diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/00/0009a621965fc195e93ba67a7d3500cbcd38b084.svn-base
--- /dev/null
+++ b/.svn/pristine/00/0009a621965fc195e93ba67a7d3500cbcd38b084.svn-base
@@ -0,0 +1,94 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class DocumentsController < ApplicationController
+  default_search_scope :documents
+  model_object Document
+  before_filter :find_project_by_project_id, :only => [:index, :new, :create]
+  before_filter :find_model_object, :except => [:index, :new, :create]
+  before_filter :find_project_from_association, :except => [:index, :new, :create]
+  before_filter :authorize
+
+  helper :attachments
+
+  def index
+    @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
+    documents = @project.documents.includes(:attachments, :category).all
+    case @sort_by
+    when 'date'
+      @grouped = documents.group_by {|d| d.updated_on.to_date }
+    when 'title'
+      @grouped = documents.group_by {|d| d.title.first.upcase}
+    when 'author'
+      @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author}
+    else
+      @grouped = documents.group_by(&:category)
+    end
+    @document = @project.documents.build
+    render :layout => false if request.xhr?
+  end
+
+  def show
+    @attachments = @document.attachments.all
+  end
+
+  def new
+    @document = @project.documents.build
+    @document.safe_attributes = params[:document]
+  end
+
+  def create
+    @document = @project.documents.build
+    @document.safe_attributes = params[:document]
+    @document.save_attachments(params[:attachments])
+    if @document.save
+      render_attachment_warning_if_needed(@document)
+      flash[:notice] = l(:notice_successful_create)
+      redirect_to project_documents_path(@project)
+    else
+      render :action => 'new'
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    @document.safe_attributes = params[:document]
+    if request.put? and @document.save
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to document_path(@document)
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def destroy
+    @document.destroy if request.delete?
+    redirect_to project_documents_path(@project)
+  end
+
+  def add_attachment
+    attachments = Attachment.attach_files(@document, params[:attachments])
+    render_attachment_warning_if_needed(@document)
+
+    if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added')
+      Mailer.attachments_added(attachments[:files]).deliver
+    end
+    redirect_to document_path(@document)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/00/002d478f30849d26745d0ec7b1c75e9c7796a254.svn-base
--- /dev/null
+++ b/.svn/pristine/00/002d478f30849d26745d0ec7b1c75e9c7796a254.svn-base
@@ -0,0 +1,614 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class MailerTest < ActiveSupport::TestCase
+  include Redmine::I18n
+  include ActionDispatch::Assertions::SelectorAssertions
+  fixtures :projects, :enabled_modules, :issues, :users, :members,
+           :member_roles, :roles, :documents, :attachments, :news,
+           :tokens, :journals, :journal_details, :changesets,
+           :trackers, :projects_trackers,
+           :issue_statuses, :enumerations, :messages, :boards, :repositories,
+           :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
+           :versions,
+           :comments
+
+  def setup
+    ActionMailer::Base.deliveries.clear
+    Setting.host_name = 'mydomain.foo'
+    Setting.protocol = 'http'
+    Setting.plain_text_mail = '0'
+  end
+
+  def test_generated_links_in_emails
+    Setting.default_language = 'en'
+    Setting.host_name = 'mydomain.foo'
+    Setting.protocol = 'https'
+
+    journal = Journal.find(3)
+    assert Mailer.issue_edit(journal).deliver
+
+    mail = last_email
+    assert_not_nil mail
+
+    assert_select_email do
+      # link to the main ticket
+      assert_select 'a[href=?]',
+                    'https://mydomain.foo/issues/2#change-3',
+                    :text => 'Feature request #2: Add ingredients categories'
+      # link to a referenced ticket
+      assert_select 'a[href=?][title=?]',
+                    'https://mydomain.foo/issues/1',
+                    'Can&#x27;t print recipes (New)',
+                    :text => '#1'
+      # link to a changeset
+      assert_select 'a[href=?][title=?]',
+                    'https://mydomain.foo/projects/ecookbook/repository/revisions/2',
+                    'This commit fixes #1, #2 and references #1 &amp; #3',
+                    :text => 'r2'
+      # link to a description diff
+      assert_select 'a[href=?][title=?]',
+                    'https://mydomain.foo/journals/diff/3?detail_id=4',
+                    'View differences',
+                    :text => 'diff'
+      # link to an attachment
+      assert_select 'a[href=?]',
+                    'https://mydomain.foo/attachments/download/4/source.rb',
+                    :text => 'source.rb'
+    end
+  end
+
+  def test_generated_links_with_prefix
+    Setting.default_language = 'en'
+    relative_url_root = Redmine::Utils.relative_url_root
+    Setting.host_name = 'mydomain.foo/rdm'
+    Setting.protocol = 'http'
+
+    journal = Journal.find(3)
+    assert Mailer.issue_edit(journal).deliver
+
+    mail = last_email
+    assert_not_nil mail
+
+    assert_select_email do
+      # link to the main ticket
+      assert_select 'a[href=?]',
+                    'http://mydomain.foo/rdm/issues/2#change-3',
+                    :text => 'Feature request #2: Add ingredients categories'
+      # link to a referenced ticket
+      assert_select 'a[href=?][title=?]',
+                    'http://mydomain.foo/rdm/issues/1',
+                    'Can&#x27;t print recipes (New)',
+                    :text => '#1'
+      # link to a changeset
+      assert_select 'a[href=?][title=?]',
+                    'http://mydomain.foo/rdm/projects/ecookbook/repository/revisions/2',
+                    'This commit fixes #1, #2 and references #1 &amp; #3',
+                    :text => 'r2'
+      # link to a description diff
+      assert_select 'a[href=?][title=?]',
+                    'http://mydomain.foo/rdm/journals/diff/3?detail_id=4',
+                    'View differences',
+                    :text => 'diff'
+      # link to an attachment
+      assert_select 'a[href=?]',
+                    'http://mydomain.foo/rdm/attachments/download/4/source.rb',
+                    :text => 'source.rb'
+    end
+  end
+
+  def test_generated_links_with_prefix_and_no_relative_url_root
+    Setting.default_language = 'en'
+    relative_url_root = Redmine::Utils.relative_url_root
+    Setting.host_name = 'mydomain.foo/rdm'
+    Setting.protocol = 'http'
+    Redmine::Utils.relative_url_root = nil
+
+    journal = Journal.find(3)
+    assert Mailer.issue_edit(journal).deliver
+
+    mail = last_email
+    assert_not_nil mail
+
+    assert_select_email do
+      # link to the main ticket
+      assert_select 'a[href=?]',
+                    'http://mydomain.foo/rdm/issues/2#change-3',
+                    :text => 'Feature request #2: Add ingredients categories'
+      # link to a referenced ticket
+      assert_select 'a[href=?][title=?]',
+                    'http://mydomain.foo/rdm/issues/1',
+                    'Can&#x27;t print recipes (New)',
+                    :text => '#1'
+      # link to a changeset
+      assert_select 'a[href=?][title=?]',
+                    'http://mydomain.foo/rdm/projects/ecookbook/repository/revisions/2',
+                    'This commit fixes #1, #2 and references #1 &amp; #3',
+                    :text => 'r2'
+      # link to a description diff
+      assert_select 'a[href=?][title=?]',
+                    'http://mydomain.foo/rdm/journals/diff/3?detail_id=4',
+                    'View differences',
+                    :text => 'diff'
+      # link to an attachment
+      assert_select 'a[href=?]',
+                    'http://mydomain.foo/rdm/attachments/download/4/source.rb',
+                    :text => 'source.rb'
+    end
+  ensure
+    # restore it
+    Redmine::Utils.relative_url_root = relative_url_root
+  end
+
+  def test_email_headers
+    issue = Issue.find(1)
+    Mailer.issue_add(issue).deliver
+    mail = last_email
+    assert_not_nil mail
+    assert_equal 'OOF', mail.header['X-Auto-Response-Suppress'].to_s
+    assert_equal 'auto-generated', mail.header['Auto-Submitted'].to_s
+    assert_equal '<redmine.example.net>', mail.header['List-Id'].to_s
+  end
+
+  def test_email_headers_should_include_sender
+    issue = Issue.find(1)
+    Mailer.issue_add(issue).deliver
+    mail = last_email
+    assert_equal issue.author.login, mail.header['X-Redmine-Sender'].to_s
+  end
+
+  def test_plain_text_mail
+    Setting.plain_text_mail = 1
+    journal = Journal.find(2)
+    Mailer.issue_edit(journal).deliver
+    mail = last_email
+    assert_equal "text/plain; charset=UTF-8", mail.content_type
+    assert_equal 0, mail.parts.size
+    assert !mail.encoded.include?('href')
+  end
+
+  def test_html_mail
+    Setting.plain_text_mail = 0
+    journal = Journal.find(2)
+    Mailer.issue_edit(journal).deliver
+    mail = last_email
+    assert_equal 2, mail.parts.size
+    assert mail.encoded.include?('href')
+  end
+
+  def test_from_header
+    with_settings :mail_from => 'redmine@example.net' do
+      Mailer.test_email(User.find(1)).deliver
+    end
+    mail = last_email
+    assert_equal 'redmine@example.net', mail.from_addrs.first
+  end
+
+  def test_from_header_with_phrase
+    with_settings :mail_from => 'Redmine app <redmine@example.net>' do
+      Mailer.test_email(User.find(1)).deliver
+    end
+    mail = last_email
+    assert_equal 'redmine@example.net', mail.from_addrs.first
+    assert_equal 'Redmine app <redmine@example.net>', mail.header['From'].to_s
+  end
+
+  def test_should_not_send_email_without_recipient
+    news = News.first
+    user = news.author
+    # Remove members except news author
+    news.project.memberships.each {|m| m.destroy unless m.user == user}
+
+    user.pref[:no_self_notified] = false
+    user.pref.save
+    User.current = user
+    Mailer.news_added(news.reload).deliver
+    assert_equal 1, last_email.bcc.size
+
+    # nobody to notify
+    user.pref[:no_self_notified] = true
+    user.pref.save
+    User.current = user
+    ActionMailer::Base.deliveries.clear
+    Mailer.news_added(news.reload).deliver
+    assert ActionMailer::Base.deliveries.empty?
+  end
+
+  def test_issue_add_message_id
+    issue = Issue.find(1)
+    Mailer.issue_add(issue).deliver
+    mail = last_email
+    assert_equal Mailer.message_id_for(issue), mail.message_id
+    assert_nil mail.references
+  end
+
+  def test_issue_edit_message_id
+    journal = Journal.find(1)
+    Mailer.issue_edit(journal).deliver
+    mail = last_email
+    assert_equal Mailer.message_id_for(journal), mail.message_id
+    assert_include Mailer.message_id_for(journal.issue), mail.references
+    assert_select_email do
+      # link to the update
+      assert_select "a[href=?]",
+                    "http://mydomain.foo/issues/#{journal.journalized_id}#change-#{journal.id}"
+    end
+  end
+
+  def test_message_posted_message_id
+    message = Message.find(1)
+    Mailer.message_posted(message).deliver
+    mail = last_email
+    assert_equal Mailer.message_id_for(message), mail.message_id
+    assert_nil mail.references
+    assert_select_email do
+      # link to the message
+      assert_select "a[href=?]",
+                    "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.id}",
+                    :text => message.subject
+    end
+  end
+
+  def test_reply_posted_message_id
+    message = Message.find(3)
+    Mailer.message_posted(message).deliver
+    mail = last_email
+    assert_equal Mailer.message_id_for(message), mail.message_id
+    assert_include Mailer.message_id_for(message.parent), mail.references
+    assert_select_email do
+      # link to the reply
+      assert_select "a[href=?]",
+                    "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.root.id}?r=#{message.id}#message-#{message.id}",
+                    :text => message.subject
+    end
+  end
+
+  test "#issue_add should notify project members" do
+    issue = Issue.find(1)
+    assert Mailer.issue_add(issue).deliver
+    assert last_email.bcc.include?('dlopper@somenet.foo')
+  end
+
+  test "#issue_add should not notify project members that are not allow to view the issue" do
+    issue = Issue.find(1)
+    Role.find(2).remove_permission!(:view_issues)
+    assert Mailer.issue_add(issue).deliver
+    assert !last_email.bcc.include?('dlopper@somenet.foo')
+  end
+
+  test "#issue_add should notify issue watchers" do
+    issue = Issue.find(1)
+    user = User.find(9)
+    # minimal email notification options
+    user.pref[:no_self_notified] = '1'
+    user.pref.save
+    user.mail_notification = false
+    user.save
+
+    Watcher.create!(:watchable => issue, :user => user)
+    assert Mailer.issue_add(issue).deliver
+    assert last_email.bcc.include?(user.mail)
+  end
+
+  test "#issue_add should not notify watchers not allowed to view the issue" do
+    issue = Issue.find(1)
+    user = User.find(9)
+    Watcher.create!(:watchable => issue, :user => user)
+    Role.non_member.remove_permission!(:view_issues)
+    assert Mailer.issue_add(issue).deliver
+    assert !last_email.bcc.include?(user.mail)
+  end
+
+  # test mailer methods for each language
+  def test_issue_add
+    issue = Issue.find(1)
+    valid_languages.each do |lang|
+      Setting.default_language = lang.to_s
+      assert Mailer.issue_add(issue).deliver
+    end
+  end
+
+  def test_issue_edit
+    journal = Journal.find(1)
+    valid_languages.each do |lang|
+      Setting.default_language = lang.to_s
+      assert Mailer.issue_edit(journal).deliver
+    end
+  end
+
+  def test_issue_edit_should_send_private_notes_to_users_with_permission_only
+    journal = Journal.find(1)
+    journal.private_notes = true
+    journal.save!
+
+    Role.find(2).add_permission! :view_private_notes
+    Mailer.issue_edit(journal).deliver
+    assert_equal %w(dlopper@somenet.foo jsmith@somenet.foo), ActionMailer::Base.deliveries.last.bcc.sort
+
+    Role.find(2).remove_permission! :view_private_notes
+    Mailer.issue_edit(journal).deliver
+    assert_equal %w(jsmith@somenet.foo), ActionMailer::Base.deliveries.last.bcc.sort
+  end
+
+  def test_issue_edit_should_send_private_notes_to_watchers_with_permission_only
+    Issue.find(1).set_watcher(User.find_by_login('someone'))
+    journal = Journal.find(1)
+    journal.private_notes = true
+    journal.save!
+
+    Role.non_member.add_permission! :view_private_notes
+    Mailer.issue_edit(journal).deliver
+    assert_include 'someone@foo.bar', ActionMailer::Base.deliveries.last.bcc.sort
+
+    Role.non_member.remove_permission! :view_private_notes
+    Mailer.issue_edit(journal).deliver
+    assert_not_include 'someone@foo.bar', ActionMailer::Base.deliveries.last.bcc.sort
+  end
+
+  def test_document_added
+    document = Document.find(1)
+    valid_languages.each do |lang|
+      Setting.default_language = lang.to_s
+      assert Mailer.document_added(document).deliver
+    end
+  end
+
+  def test_attachments_added
+    attachements = [ Attachment.find_by_container_type('Document') ]
+    valid_languages.each do |lang|
+      Setting.default_language = lang.to_s
+      assert Mailer.attachments_added(attachements).deliver
+    end
+  end
+
+  def test_version_file_added
+    attachements = [ Attachment.find_by_container_type('Version') ]
+    assert Mailer.attachments_added(attachements).deliver
+    assert_not_nil last_email.bcc
+    assert last_email.bcc.any?
+    assert_select_email do
+      assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
+    end
+  end
+
+  def test_project_file_added
+    attachements = [ Attachment.find_by_container_type('Project') ]
+    assert Mailer.attachments_added(attachements).deliver
+    assert_not_nil last_email.bcc
+    assert last_email.bcc.any?
+    assert_select_email do
+      assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
+    end
+  end
+
+  def test_news_added
+    news = News.first
+    valid_languages.each do |lang|
+      Setting.default_language = lang.to_s
+      assert Mailer.news_added(news).deliver
+    end
+  end
+
+  def test_news_comment_added
+    comment = Comment.find(2)
+    valid_languages.each do |lang|
+      Setting.default_language = lang.to_s
+      assert Mailer.news_comment_added(comment).deliver
+    end
+  end
+
+  def test_message_posted
+    message = Message.first
+    recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
+    recipients = recipients.compact.uniq
+    valid_languages.each do |lang|
+      Setting.default_language = lang.to_s
+      assert Mailer.message_posted(message).deliver
+    end
+  end
+
+  def test_wiki_content_added
+    content = WikiContent.find(1)
+    valid_languages.each do |lang|
+      Setting.default_language = lang.to_s
+      assert_difference 'ActionMailer::Base.deliveries.size' do
+        assert Mailer.wiki_content_added(content).deliver
+        assert_select_email do
+          assert_select 'a[href=?]',
+            'http://mydomain.foo/projects/ecookbook/wiki/CookBook_documentation',
+            :text => 'CookBook documentation'
+        end
+      end
+    end
+  end
+
+  def test_wiki_content_updated
+    content = WikiContent.find(1)
+    valid_languages.each do |lang|
+      Setting.default_language = lang.to_s
+      assert_difference 'ActionMailer::Base.deliveries.size' do
+        assert Mailer.wiki_content_updated(content).deliver
+        assert_select_email do
+          assert_select 'a[href=?]',
+            'http://mydomain.foo/projects/ecookbook/wiki/CookBook_documentation',
+            :text => 'CookBook documentation'
+        end
+      end
+    end
+  end
+
+  def test_account_information
+    user = User.find(2)
+    valid_languages.each do |lang|
+      user.update_attribute :language, lang.to_s
+      user.reload
+      assert Mailer.account_information(user, 'pAsswORd').deliver
+    end
+  end
+
+  def test_lost_password
+    token = Token.find(2)
+    valid_languages.each do |lang|
+      token.user.update_attribute :language, lang.to_s
+      token.reload
+      assert Mailer.lost_password(token).deliver
+    end
+  end
+
+  def test_register
+    token = Token.find(1)
+    Setting.host_name = 'redmine.foo'
+    Setting.protocol = 'https'
+
+    valid_languages.each do |lang|
+      token.user.update_attribute :language, lang.to_s
+      token.reload
+      ActionMailer::Base.deliveries.clear
+      assert Mailer.register(token).deliver
+      mail = last_email
+      assert_select_email do
+        assert_select "a[href=?]",
+                      "https://redmine.foo/account/activate?token=#{token.value}",
+                      :text => "https://redmine.foo/account/activate?token=#{token.value}"
+      end
+    end
+  end
+
+  def test_test
+    user = User.find(1)
+    valid_languages.each do |lang|
+      user.update_attribute :language, lang.to_s
+      assert Mailer.test_email(user).deliver
+    end
+  end
+
+  def test_reminders
+    Mailer.reminders(:days => 42)
+    assert_equal 1, ActionMailer::Base.deliveries.size
+    mail = last_email
+    assert mail.bcc.include?('dlopper@somenet.foo')
+    assert_mail_body_match 'Bug #3: Error 281 when updating a recipe', mail
+    assert_equal '1 issue(s) due in the next 42 days', mail.subject
+  end
+
+  def test_reminders_should_not_include_closed_issues
+    with_settings :default_language => 'en' do
+      Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 5,
+                      :subject => 'Closed issue', :assigned_to_id => 3,
+                      :due_date => 5.days.from_now,
+                      :author_id => 2)
+      ActionMailer::Base.deliveries.clear
+
+      Mailer.reminders(:days => 42)
+      assert_equal 1, ActionMailer::Base.deliveries.size
+      mail = last_email
+      assert mail.bcc.include?('dlopper@somenet.foo')
+      assert_mail_body_no_match 'Closed issue', mail
+    end
+  end
+
+  def test_reminders_for_users
+    Mailer.reminders(:days => 42, :users => ['5'])
+    assert_equal 0, ActionMailer::Base.deliveries.size # No mail for dlopper
+    Mailer.reminders(:days => 42, :users => ['3'])
+    assert_equal 1, ActionMailer::Base.deliveries.size # No mail for dlopper
+    mail = last_email
+    assert mail.bcc.include?('dlopper@somenet.foo')
+    assert_mail_body_match 'Bug #3: Error 281 when updating a recipe', mail
+  end
+
+  def test_reminder_should_include_issues_assigned_to_groups
+    with_settings :default_language => 'en' do
+      group = Group.generate!
+      group.users << User.find(2)
+      group.users << User.find(3)
+
+      Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1,
+                      :subject => 'Assigned to group', :assigned_to => group,
+                      :due_date => 5.days.from_now,
+                      :author_id => 2)
+      ActionMailer::Base.deliveries.clear
+
+      Mailer.reminders(:days => 7)
+      assert_equal 2, ActionMailer::Base.deliveries.size
+      assert_equal %w(dlopper@somenet.foo jsmith@somenet.foo), ActionMailer::Base.deliveries.map(&:bcc).flatten.sort
+      ActionMailer::Base.deliveries.each do |mail|
+        assert_mail_body_match 'Assigned to group', mail
+      end
+    end
+  end
+
+  def test_mailer_should_not_change_locale
+    Setting.default_language = 'en'
+    # Set current language to italian
+    set_language_if_valid 'it'
+    # Send an email to a french user
+    user = User.find(1)
+    user.language = 'fr'
+    Mailer.account_activated(user).deliver
+    mail = last_email
+    assert_mail_body_match 'Votre compte', mail
+
+    assert_equal :it, current_language
+  end
+
+  def test_with_deliveries_off
+    Mailer.with_deliveries false do
+      Mailer.test_email(User.find(1)).deliver
+    end
+    assert ActionMailer::Base.deliveries.empty?
+    # should restore perform_deliveries
+    assert ActionMailer::Base.perform_deliveries
+  end
+
+  def test_layout_should_include_the_emails_header
+    with_settings :emails_header => "*Header content*" do
+      assert Mailer.test_email(User.find(1)).deliver
+      assert_select_email do
+        assert_select ".header" do
+          assert_select "strong", :text => "Header content"
+        end
+      end
+    end
+  end
+
+  def test_should_escape_html_templates_only
+    Issue.generate!(:project_id => 1, :tracker_id => 1, :subject => 'Subject with a <tag>')
+    mail = last_email
+    assert_equal 2, mail.parts.size
+    assert_include '<tag>', text_part.body.encoded
+    assert_include '&lt;tag&gt;', html_part.body.encoded
+  end
+
+  private
+
+  def last_email
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    mail
+  end
+
+  def text_part
+    last_email.parts.detect {|part| part.content_type.include?('text/plain')}
+  end
+
+  def html_part
+    last_email.parts.detect {|part| part.content_type.include?('text/html')}
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/00/007e22f777adc578342260747f72f3fcfceb129d.svn-base
--- a/.svn/pristine/00/007e22f777adc578342260747f72f3fcfceb129d.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class ProjectCustomField < CustomField
-  def type_name
-    :label_project_plural
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/00/0081b5051789911922bdd0b18a28f0ad87c64e8d.svn-base
--- /dev/null
+++ b/.svn/pristine/00/0081b5051789911922bdd0b18a28f0ad87c64e8d.svn-base
@@ -0,0 +1,39 @@
+<div class="contextual">
+<%= link_to l(:label_tracker_new), new_tracker_path, :class => 'icon icon-add' %>
+<%= link_to l(:field_summary), fields_trackers_path, :class => 'icon icon-summary' %>
+</div>
+
+<h2><%=l(:label_tracker_plural)%></h2>
+
+<table class="list">
+  <thead><tr>
+  <th><%=l(:label_tracker)%></th>
+  <th></th>
+  <th><%=l(:button_sort)%></th>
+  <th></th>
+  </tr></thead>
+  <tbody>
+<% for tracker in @trackers %>
+  <tr class="<%= cycle("odd", "even") %>">
+  <td><%= link_to h(tracker.name), edit_tracker_path(tracker) %></td>
+  <td align="center">
+    <% unless tracker.workflow_rules.count > 0 %>
+      <span class="icon icon-warning">
+        <%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), workflows_edit_path(:tracker_id => tracker) %>)
+      </span>
+    <% end %>
+  </td>
+  <td align="center" style="width:15%;">
+    <%= reorder_links('tracker', {:action => 'update', :id => tracker}, :put) %>
+  </td>
+  <td class="buttons">
+    <%= delete_link tracker_path(tracker) %>
+  </td>
+  </tr>
+<% end %>
+  </tbody>
+</table>
+
+<p class="pagination"><%= pagination_links_full @tracker_pages %></p>
+
+<% html_title(l(:label_tracker_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/00/00bd76ee7194e922fe9340f2d39d910c9f79b20e.svn-base
--- /dev/null
+++ b/.svn/pristine/00/00bd76ee7194e922fe9340f2d39d910c9f79b20e.svn-base
@@ -0,0 +1,162 @@
+module ObjectHelpers
+  def User.generate!(attributes={})
+    @generated_user_login ||= 'user0'
+    @generated_user_login.succ!
+    user = User.new(attributes)
+    user.login = @generated_user_login.dup if user.login.blank?
+    user.mail = "#{@generated_user_login}@example.com" if user.mail.blank?
+    user.firstname = "Bob" if user.firstname.blank?
+    user.lastname = "Doe" if user.lastname.blank?
+    yield user if block_given?
+    user.save!
+    user
+  end
+
+  def User.add_to_project(user, project, roles=nil)
+    roles = Role.find(1) if roles.nil?
+    roles = [roles] unless roles.is_a?(Array)
+    Member.create!(:principal => user, :project => project, :roles => roles)
+  end
+
+  def Group.generate!(attributes={})
+    @generated_group_name ||= 'Group 0'
+    @generated_group_name.succ!
+    group = Group.new(attributes)
+    group.name = @generated_group_name.dup if group.name.blank?
+    yield group if block_given?
+    group.save!
+    group
+  end
+
+  def Project.generate!(attributes={})
+    @generated_project_identifier ||= 'project-0000'
+    @generated_project_identifier.succ!
+    project = Project.new(attributes)
+    project.name = @generated_project_identifier.dup if project.name.blank?
+    project.identifier = @generated_project_identifier.dup if project.identifier.blank?
+    yield project if block_given?
+    project.save!
+    project
+  end
+
+  def Project.generate_with_parent!(parent, attributes={})
+    project = Project.generate!(attributes)
+    project.set_parent!(parent)
+    project
+  end
+
+  def Tracker.generate!(attributes={})
+    @generated_tracker_name ||= 'Tracker 0'
+    @generated_tracker_name.succ!
+    tracker = Tracker.new(attributes)
+    tracker.name = @generated_tracker_name.dup if tracker.name.blank?
+    yield tracker if block_given?
+    tracker.save!
+    tracker
+  end
+
+  def Role.generate!(attributes={})
+    @generated_role_name ||= 'Role 0'
+    @generated_role_name.succ!
+    role = Role.new(attributes)
+    role.name = @generated_role_name.dup if role.name.blank?
+    yield role if block_given?
+    role.save!
+    role
+  end
+
+  def Issue.generate!(attributes={})
+    issue = Issue.new(attributes)
+    issue.project ||= Project.find(1)
+    issue.tracker ||= issue.project.trackers.first
+    issue.subject = 'Generated' if issue.subject.blank?
+    issue.author ||= User.find(2)
+    yield issue if block_given?
+    issue.save!
+    issue
+  end
+
+  # Generates an issue with 2 children and a grandchild
+  def Issue.generate_with_descendants!(attributes={})
+    issue = Issue.generate!(attributes)
+    child = Issue.generate!(:project => issue.project, :subject => 'Child1', :parent_issue_id => issue.id)
+    Issue.generate!(:project => issue.project, :subject => 'Child2', :parent_issue_id => issue.id)
+    Issue.generate!(:project => issue.project, :subject => 'Child11', :parent_issue_id => child.id)
+    issue.reload
+  end
+
+  def Journal.generate!(attributes={})
+    journal = Journal.new(attributes)
+    journal.user ||= User.first
+    journal.journalized ||= Issue.first
+    yield journal if block_given?
+    journal.save!
+    journal
+  end
+
+  def Version.generate!(attributes={})
+    @generated_version_name ||= 'Version 0'
+    @generated_version_name.succ!
+    version = Version.new(attributes)
+    version.name = @generated_version_name.dup if version.name.blank?
+    yield version if block_given?
+    version.save!
+    version
+  end
+
+  def TimeEntry.generate!(attributes={})
+    entry = TimeEntry.new(attributes)
+    entry.user ||= User.find(2)
+    entry.issue ||= Issue.find(1) unless entry.project
+    entry.project ||= entry.issue.project
+    entry.activity ||= TimeEntryActivity.first
+    entry.spent_on ||= Date.today
+    entry.hours ||= 1.0
+    entry.save!
+    entry
+  end
+
+  def AuthSource.generate!(attributes={})
+    @generated_auth_source_name ||= 'Auth 0'
+    @generated_auth_source_name.succ!
+    source = AuthSource.new(attributes)
+    source.name = @generated_auth_source_name.dup if source.name.blank?
+    yield source if block_given?
+    source.save!
+    source
+  end
+
+  def Board.generate!(attributes={})
+    @generated_board_name ||= 'Forum 0'
+    @generated_board_name.succ!
+    board = Board.new(attributes)
+    board.name = @generated_board_name.dup if board.name.blank?
+    board.description = @generated_board_name.dup if board.description.blank?
+    yield board if block_given?
+    board.save!
+    board
+  end
+
+  def Attachment.generate!(attributes={})
+    @generated_filename ||= 'testfile0'
+    @generated_filename.succ!
+    attributes = attributes.dup
+    attachment = Attachment.new(attributes)
+    attachment.container ||= Issue.find(1)
+    attachment.author ||= User.find(2)
+    attachment.filename = @generated_filename.dup if attachment.filename.blank?
+    attachment.save!
+    attachment
+  end
+
+  def CustomField.generate!(attributes={})
+    @generated_custom_field_name ||= 'Custom field 0'
+    @generated_custom_field_name.succ!
+    field = new(attributes)
+    field.name = @generated_custom_field_name.dup if field.name.blank?
+    field.field_format = 'string' if field.field_format.blank?
+    yield field if block_given?
+    field.save!
+    field
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/00/00c1a9b51dc321ecb980f25b62c13dfa7fd628ff.svn-base
--- /dev/null
+++ b/.svn/pristine/00/00c1a9b51dc321ecb980f25b62c13dfa7fd628ff.svn-base
@@ -0,0 +1,24 @@
+<%= error_messages_for 'auth_source' %>
+
+<div class="box tabular">
+  <p><%= f.text_field :name, :required => true %></p>
+  <p><%= f.text_field :host, :required => true %></p>
+  <p><%= f.text_field :port, :required => true, :size => 6 %> <%= f.check_box :tls, :no_label => true %> LDAPS</p>
+  <p><%= f.text_field :account %></p>
+  <p><%= f.password_field :account_password, :label => :field_password,
+           :name => 'dummy_password',
+           :value => ((@auth_source.new_record? || @auth_source.account_password.blank?) ? '' : ('x'*15)),
+           :onfocus => "this.value=''; this.name='auth_source[account_password]';",
+           :onchange => "this.name='auth_source[account_password]';" %></p>
+  <p><%= f.text_field :base_dn, :required => true, :size => 60 %></p>
+  <p><%= f.text_field :filter, :size => 60, :label => :field_auth_source_ldap_filter %></p>
+  <p><%= f.text_field :timeout, :size => 4 %></p>
+  <p><%= f.check_box :onthefly_register, :label => :field_onthefly %></p>
+</div>
+
+<fieldset class="box tabular"><legend><%=l(:label_attribute_plural)%></legend>
+  <p><%= f.text_field :attr_login, :required => true, :size => 20 %></p>
+  <p><%= f.text_field :attr_firstname, :size => 20 %></p>
+  <p><%= f.text_field :attr_lastname, :size => 20 %></p>
+  <p><%= f.text_field :attr_mail, :size => 20 %></p>
+</fieldset>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/00/00c4bd6691f32db8720a826db98aecc930f926d9.svn-base
--- a/.svn/pristine/00/00c4bd6691f32db8720a826db98aecc930f926d9.svn-base
+++ /dev/null
@@ -1,165 +0,0 @@
-# $Id: entry.rb 123 2006-05-18 03:52:38Z blackhedd $
-#
-# LDAP Entry (search-result) support classes
-#
-#
-#----------------------------------------------------------------------------
-#
-# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
-#
-# Gmail: garbagecat10
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#---------------------------------------------------------------------------
-#
-
-
-
-
-module Net
-class LDAP
-
-
-  # Objects of this class represent individual entries in an LDAP
-  # directory. User code generally does not instantiate this class.
-  # Net::LDAP#search provides objects of this class to user code,
-  # either as block parameters or as return values.
-  #
-  # In LDAP-land, an "entry" is a collection of attributes that are
-  # uniquely and globally identified by a DN ("Distinguished Name").
-  # Attributes are identified by short, descriptive words or phrases.
-  # Although a directory is
-  # free to implement any attribute name, most of them follow rigorous
-  # standards so that the range of commonly-encountered attribute
-  # names is not large.
-  #
-  # An attribute name is case-insensitive. Most directories also
-  # restrict the range of characters allowed in attribute names.
-  # To simplify handling attribute names, Net::LDAP::Entry
-  # internally converts them to a standard format. Therefore, the
-  # methods which take attribute names can take Strings or Symbols,
-  # and work correctly regardless of case or capitalization.
-  #
-  # An attribute consists of zero or more data items called
-  # <i>values.</i> An entry is the combination of a unique DN, a set of attribute
-  # names, and a (possibly-empty) array of values for each attribute.
-  #
-  # Class Net::LDAP::Entry provides convenience methods for dealing
-  # with LDAP entries.
-  # In addition to the methods documented below, you may access individual
-  # attributes of an entry simply by giving the attribute name as
-  # the name of a method call. For example:
-  #  ldap.search( ... ) do |entry|
-  #    puts "Common name: #{entry.cn}"
-  #    puts "Email addresses:"
-  #      entry.mail.each {|ma| puts ma}
-  #  end
-  # If you use this technique to access an attribute that is not present
-  # in a particular Entry object, a NoMethodError exception will be raised.
-  #
-  #--
-  # Ugly problem to fix someday: We key off the internal hash with
-  # a canonical form of the attribute name: convert to a string,
-  # downcase, then take the symbol. Unfortunately we do this in
-  # at least three places. Should do it in ONE place.
-  class Entry
-
-    # This constructor is not generally called by user code.
-    def initialize dn = nil # :nodoc:
-      @myhash = Hash.new {|k,v| k[v] = [] }
-      @myhash[:dn] = [dn]
-    end
-
-
-    def []= name, value # :nodoc:
-      sym = name.to_s.downcase.intern
-      @myhash[sym] = value
-    end
-
-
-    #--
-    # We have to deal with this one as we do with []=
-    # because this one and not the other one gets called
-    # in formulations like entry["CN"] << cn.
-    #
-    def [] name # :nodoc:
-      name = name.to_s.downcase.intern unless name.is_a?(Symbol)
-      @myhash[name]
-    end
-
-    # Returns the dn of the Entry as a String.
-    def dn
-      self[:dn][0]
-    end
-
-    # Returns an array of the attribute names present in the Entry.
-    def attribute_names
-      @myhash.keys
-    end
-
-    # Accesses each of the attributes present in the Entry.
-    # Calls a user-supplied block with each attribute in turn,
-    # passing two arguments to the block: a Symbol giving
-    # the name of the attribute, and a (possibly empty)
-    # Array of data values.
-    #
-    def each
-      if block_given?
-        attribute_names.each {|a|
-          attr_name,values = a,self[a]
-          yield attr_name, values
-        }
-      end
-    end
-
-    alias_method :each_attribute, :each
-
-
-    #--
-    # Convenience method to convert unknown method names
-    # to attribute references. Of course the method name
-    # comes to us as a symbol, so let's save a little time
-    # and not bother with the to_s.downcase two-step.
-    # Of course that means that a method name like mAIL
-    # won't work, but we shouldn't be encouraging that
-    # kind of bad behavior in the first place.
-    # Maybe we should thow something if the caller sends
-    # arguments or a block...
-    #
-    def method_missing *args, &block # :nodoc:
-      s = args[0].to_s.downcase.intern
-      if attribute_names.include?(s)
-        self[s]
-      elsif s.to_s[-1] == 61 and s.to_s.length > 1
-        value = args[1] or raise RuntimeError.new( "unable to set value" )
-        value = [value] unless value.is_a?(Array)
-        name = s.to_s[0..-2].intern
-        self[name] = value
-      else
-        raise NoMethodError.new( "undefined method '#{s}'" )
-      end
-    end
-
-    def write
-    end
-
-  end # class Entry
-
-
-end # class LDAP
-end # module Net
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/01/011d952bc7773843d5a8219df22dce0959479d6d.svn-base
--- a/.svn/pristine/01/011d952bc7773843d5a8219df22dce0959479d6d.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class DocumentCategoryTest < ActiveSupport::TestCase
-  fixtures :enumerations, :documents, :issues
-
-  def test_should_be_an_enumeration
-    assert DocumentCategory.ancestors.include?(Enumeration)
-  end
-
-  def test_objects_count
-    assert_equal 2, DocumentCategory.find_by_name("Uncategorized").objects_count
-    assert_equal 0, DocumentCategory.find_by_name("User documentation").objects_count
-  end
-
-  def test_option_name
-    assert_equal :enumeration_doc_categories, DocumentCategory.new.option_name
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/01/01272907f6842a5e924d61c923ee0994110ab686.svn-base
--- a/.svn/pristine/01/01272907f6842a5e924d61c923ee0994110ab686.svn-base
+++ /dev/null
@@ -1,260 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../test_helper', __FILE__)
-
-class Redmine::MenuManager::MenuHelperTest < HelperTestCase
-  include Redmine::MenuManager::MenuHelper
-  include ActionController::Assertions::SelectorAssertions
-  fixtures :users, :members, :projects, :enabled_modules
-
-  # Used by assert_select
-  def html_document
-    HTML::Document.new(@response.body)
-  end
-
-  def setup
-    super
-    @response = ActionController::TestResponse.new
-    # Stub the current menu item in the controller
-    def current_menu_item
-      :index
-    end
-  end
-
-
-  context "MenuManager#current_menu_item" do
-    should "be tested"
-  end
-
-  context "MenuManager#render_main_menu" do
-    should "be tested"
-  end
-
-  context "MenuManager#render_menu" do
-    should "be tested"
-  end
-
-  context "MenuManager#menu_item_and_children" do
-    should "be tested"
-  end
-
-  context "MenuManager#extract_node_details" do
-    should "be tested"
-  end
-
-  def test_render_single_menu_node
-    node = Redmine::MenuManager::MenuItem.new(:testing, '/test', { })
-    @response.body = render_single_menu_node(node, 'This is a test', node.url, false)
-
-    assert_select("a.testing", "This is a test")
-  end
-
-  def test_render_menu_node
-    single_node = Redmine::MenuManager::MenuItem.new(:single_node, '/test', { })
-    @response.body = render_menu_node(single_node, nil)
-
-    assert_select("li") do
-      assert_select("a.single-node", "Single node")
-    end
-  end
-
-  def test_render_menu_node_with_nested_items
-    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node, '/test', { })
-    parent_node << Redmine::MenuManager::MenuItem.new(:child_one_node, '/test', { })
-    parent_node << Redmine::MenuManager::MenuItem.new(:child_two_node, '/test', { })
-    parent_node <<
-      Redmine::MenuManager::MenuItem.new(:child_three_node, '/test', { }) <<
-      Redmine::MenuManager::MenuItem.new(:child_three_inner_node, '/test', { })
-
-    @response.body = render_menu_node(parent_node, nil)
-
-    assert_select("li") do
-      assert_select("a.parent-node", "Parent node")
-      assert_select("ul") do
-        assert_select("li a.child-one-node", "Child one node")
-        assert_select("li a.child-two-node", "Child two node")
-        assert_select("li") do
-          assert_select("a.child-three-node", "Child three node")
-          assert_select("ul") do
-            assert_select("li a.child-three-inner-node", "Child three inner node")
-          end
-        end
-      end
-    end
-
-  end
-
-  def test_render_menu_node_with_children
-    User.current = User.find(2)
-
-    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
-                                                     '/test',
-                                                     {
-                                                       :children => Proc.new {|p|
-                                                         children = []
-                                                         3.times do |time|
-                                                           children << Redmine::MenuManager::MenuItem.new("test_child_#{time}",
-                                                                                                             {:controller => 'issues', :action => 'index'},
-                                                                                                             {})
-                                                         end
-                                                         children
-                                                       }
-                                                     })
-    @response.body = render_menu_node(parent_node, Project.find(1))
-
-    assert_select("li") do
-      assert_select("a.parent-node", "Parent node")
-      assert_select("ul") do
-        assert_select("li a.test-child-0", "Test child 0")
-        assert_select("li a.test-child-1", "Test child 1")
-        assert_select("li a.test-child-2", "Test child 2")
-      end
-    end
-  end
-
-  def test_render_menu_node_with_nested_items_and_children
-    User.current = User.find(2)
-
-    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
-                                                     '/test',
-                                                     {
-                                                       :children => Proc.new {|p|
-                                                         children = []
-                                                         3.times do |time|
-                                                           children << Redmine::MenuManager::MenuItem.new("test_child_#{time}", {:controller => 'issues', :action => 'index'}, {})
-                                                         end
-                                                         children
-                                                       }
-                                                     })
-
-    parent_node << Redmine::MenuManager::MenuItem.new(:child_node,
-                                                     '/test',
-                                                     {
-                                                       :children => Proc.new {|p|
-                                                         children = []
-                                                         6.times do |time|
-                                                            children << Redmine::MenuManager::MenuItem.new("test_dynamic_child_#{time}", {:controller => 'issues', :action => 'index'}, {})
-                                                         end
-                                                         children
-                                                       }
-                                                     })
-
-    @response.body = render_menu_node(parent_node, Project.find(1))
-
-    assert_select("li") do
-      assert_select("a.parent-node", "Parent node")
-      assert_select("ul") do
-        assert_select("li a.child-node", "Child node")
-        assert_select("ul") do
-          assert_select("li a.test-dynamic-child-0", "Test dynamic child 0")
-          assert_select("li a.test-dynamic-child-1", "Test dynamic child 1")
-          assert_select("li a.test-dynamic-child-2", "Test dynamic child 2")
-          assert_select("li a.test-dynamic-child-3", "Test dynamic child 3")
-          assert_select("li a.test-dynamic-child-4", "Test dynamic child 4")
-          assert_select("li a.test-dynamic-child-5", "Test dynamic child 5")
-        end
-        assert_select("li a.test-child-0", "Test child 0")
-        assert_select("li a.test-child-1", "Test child 1")
-        assert_select("li a.test-child-2", "Test child 2")
-      end
-    end
-  end
-
-  def test_render_menu_node_with_children_without_an_array
-    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
-                                                     '/test',
-                                                     {
-                                                       :children => Proc.new {|p| Redmine::MenuManager::MenuItem.new("test_child", "/testing", {})}
-                                                     })
-
-    assert_raises Redmine::MenuManager::MenuError, ":children must be an array of MenuItems" do
-      @response.body = render_menu_node(parent_node, Project.find(1))
-    end
-  end
-
-  def test_render_menu_node_with_incorrect_children
-    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
-                                                     '/test',
-                                                     {
-                                                       :children => Proc.new {|p| ["a string"] }
-                                                     })
-
-    assert_raises Redmine::MenuManager::MenuError, ":children must be an array of MenuItems" do
-      @response.body = render_menu_node(parent_node, Project.find(1))
-    end
-
-  end
-
-  def test_menu_items_for_should_yield_all_items_if_passed_a_block
-    menu_name = :test_menu_items_for_should_yield_all_items_if_passed_a_block
-    Redmine::MenuManager.map menu_name do |menu|
-      menu.push(:a_menu, '/', { })
-      menu.push(:a_menu_2, '/', { })
-      menu.push(:a_menu_3, '/', { })
-    end
-
-    items_yielded = []
-    menu_items_for(menu_name) do |item|
-      items_yielded << item
-    end
-
-    assert_equal 3, items_yielded.size
-  end
-
-  def test_menu_items_for_should_return_all_items
-    menu_name = :test_menu_items_for_should_return_all_items
-    Redmine::MenuManager.map menu_name do |menu|
-      menu.push(:a_menu, '/', { })
-      menu.push(:a_menu_2, '/', { })
-      menu.push(:a_menu_3, '/', { })
-    end
-
-    items = menu_items_for(menu_name)
-    assert_equal 3, items.size
-  end
-
-  def test_menu_items_for_should_skip_unallowed_items_on_a_project
-    menu_name = :test_menu_items_for_should_skip_unallowed_items_on_a_project
-    Redmine::MenuManager.map menu_name do |menu|
-      menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
-      menu.push(:a_menu_2, {:controller => 'issues', :action => 'index' }, { })
-      menu.push(:unallowed, {:controller => 'issues', :action => 'unallowed' }, { })
-    end
-
-    User.current = User.find(2)
-
-    items = menu_items_for(menu_name, Project.find(1))
-    assert_equal 2, items.size
-  end
-
-  def test_menu_items_for_should_skip_items_that_fail_the_conditions
-    menu_name = :test_menu_items_for_should_skip_items_that_fail_the_conditions
-    Redmine::MenuManager.map menu_name do |menu|
-      menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
-      menu.push(:unallowed,
-                {:controller => 'issues', :action => 'index' },
-                { :if => Proc.new { false }})
-    end
-
-    User.current = User.find(2)
-
-    items = menu_items_for(menu_name, Project.find(1))
-    assert_equal 1, items.size
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/01/0154cdd03545376764b58ded20a14138238e65d0.svn-base
--- /dev/null
+++ b/.svn/pristine/01/0154cdd03545376764b58ded20a14138238e65d0.svn-base
@@ -0,0 +1,178 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::Hook::ManagerTest < ActionView::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles,
+           :groups_users,
+           :trackers, :projects_trackers,
+           :enabled_modules,
+           :versions,
+           :issue_statuses, :issue_categories, :issue_relations,
+           :enumerations,
+           :issues
+
+  # Some hooks that are manually registered in these tests
+  class TestHook < Redmine::Hook::ViewListener; end
+
+  class TestHook1 < TestHook
+    def view_layouts_base_html_head(context)
+      'Test hook 1 listener.'
+    end
+  end
+
+  class TestHook2 < TestHook
+    def view_layouts_base_html_head(context)
+      'Test hook 2 listener.'
+    end
+  end
+
+  class TestHook3 < TestHook
+    def view_layouts_base_html_head(context)
+      "Context keys: #{context.keys.collect(&:to_s).sort.join(', ')}."
+    end
+  end
+
+  class TestLinkToHook < TestHook
+    def view_layouts_base_html_head(context)
+      link_to('Issues', :controller => 'issues')
+    end
+  end
+
+  class TestHookHelperController < ActionController::Base
+    include Redmine::Hook::Helper
+  end
+
+  class TestHookHelperView < ActionView::Base
+    include Redmine::Hook::Helper
+  end
+
+  Redmine::Hook.clear_listeners
+
+  def setup
+    @hook_module = Redmine::Hook
+  end
+
+  def teardown
+    @hook_module.clear_listeners
+  end
+
+  def test_clear_listeners
+    assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
+    @hook_module.add_listener(TestHook1)
+    @hook_module.add_listener(TestHook2)
+    assert_equal 2, @hook_module.hook_listeners(:view_layouts_base_html_head).size
+
+    @hook_module.clear_listeners
+    assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
+  end
+
+  def test_add_listener
+    assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
+    @hook_module.add_listener(TestHook1)
+    assert_equal 1, @hook_module.hook_listeners(:view_layouts_base_html_head).size
+  end
+
+  def test_call_hook
+    @hook_module.add_listener(TestHook1)
+    assert_equal ['Test hook 1 listener.'], hook_helper.call_hook(:view_layouts_base_html_head)
+  end
+
+  def test_call_hook_with_context
+    @hook_module.add_listener(TestHook3)
+    assert_equal ['Context keys: bar, controller, foo, hook_caller, project, request.'],
+                 hook_helper.call_hook(:view_layouts_base_html_head, :foo => 1, :bar => 'a')
+  end
+
+  def test_call_hook_with_multiple_listeners
+    @hook_module.add_listener(TestHook1)
+    @hook_module.add_listener(TestHook2)
+    assert_equal ['Test hook 1 listener.', 'Test hook 2 listener.'], hook_helper.call_hook(:view_layouts_base_html_head)
+  end
+
+  # Context: Redmine::Hook::Helper.call_hook default_url
+  def test_call_hook_default_url_options
+    @hook_module.add_listener(TestLinkToHook)
+
+    assert_equal ['<a href="/issues">Issues</a>'], hook_helper.call_hook(:view_layouts_base_html_head)
+  end
+
+  # Context: Redmine::Hook::Helper.call_hook
+  def test_call_hook_with_project_added_to_context
+    @hook_module.add_listener(TestHook3)
+    assert_match /project/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
+  end
+
+  def test_call_hook_from_controller_with_controller_added_to_context
+    @hook_module.add_listener(TestHook3)
+    assert_match /controller/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
+  end
+
+  def test_call_hook_from_controller_with_request_added_to_context
+    @hook_module.add_listener(TestHook3)
+    assert_match /request/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
+  end
+
+  def test_call_hook_from_view_with_project_added_to_context
+    @hook_module.add_listener(TestHook3)
+    assert_match /project/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
+  end
+
+  def test_call_hook_from_view_with_controller_added_to_context
+    @hook_module.add_listener(TestHook3)
+    assert_match /controller/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
+  end
+
+  def test_call_hook_from_view_with_request_added_to_context
+    @hook_module.add_listener(TestHook3)
+    assert_match /request/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
+  end
+
+  def test_call_hook_from_view_should_join_responses_with_a_space
+    @hook_module.add_listener(TestHook1)
+    @hook_module.add_listener(TestHook2)
+    assert_equal 'Test hook 1 listener. Test hook 2 listener.',
+                 view_hook_helper.call_hook(:view_layouts_base_html_head)
+  end
+
+  def test_call_hook_should_not_change_the_default_url_for_email_notifications
+    issue = Issue.find(1)
+
+    ActionMailer::Base.deliveries.clear
+    Mailer.issue_add(issue).deliver
+    mail = ActionMailer::Base.deliveries.last
+
+    @hook_module.add_listener(TestLinkToHook)
+    hook_helper.call_hook(:view_layouts_base_html_head)
+
+    ActionMailer::Base.deliveries.clear
+    Mailer.issue_add(issue).deliver
+    mail2 = ActionMailer::Base.deliveries.last
+
+    assert_equal mail_body(mail), mail_body(mail2)
+  end
+
+  def hook_helper
+    @hook_helper ||= TestHookHelperController.new
+  end
+
+  def view_hook_helper
+    @view_hook_helper ||= TestHookHelperView.new(Rails.root.to_s + '/app/views')
+  end
+end
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/01/01a6ee1f20ebd9960efb3d88db810fb607deb030.svn-base
Binary file .svn/pristine/01/01a6ee1f20ebd9960efb3d88db810fb607deb030.svn-base has changed
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/01/01b21d04c9e912327dc0059ef282ceb1a603f54f.svn-base
--- /dev/null
+++ b/.svn/pristine/01/01b21d04c9e912327dc0059ef282ceb1a603f54f.svn-base
@@ -0,0 +1,90 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AutoCompletesControllerTest < ActionController::TestCase
+  fixtures :projects, :issues, :issue_statuses,
+           :enumerations, :users, :issue_categories,
+           :trackers,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :journals, :journal_details
+
+  def test_issues_should_not_be_case_sensitive
+    get :issues, :project_id => 'ecookbook', :q => 'ReCiPe'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert assigns(:issues).detect {|issue| issue.subject.match /recipe/}
+  end
+
+  def test_issues_should_accept_term_param
+    get :issues, :project_id => 'ecookbook', :term => 'ReCiPe'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert assigns(:issues).detect {|issue| issue.subject.match /recipe/}
+  end
+
+  def test_issues_should_return_issue_with_given_id
+    get :issues, :project_id => 'subproject1', :q => '13'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert assigns(:issues).include?(Issue.find(13))
+  end
+
+  def test_issues_should_return_issue_with_given_id_preceded_with_hash
+    get :issues, :project_id => 'subproject1', :q => '#13'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert assigns(:issues).include?(Issue.find(13))
+  end
+
+  def test_auto_complete_with_scope_all_should_search_other_projects
+    get :issues, :project_id => 'ecookbook', :q => '13', :scope => 'all'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert assigns(:issues).include?(Issue.find(13))
+  end
+
+  def test_auto_complete_without_project_should_search_all_projects
+    get :issues, :q => '13'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert assigns(:issues).include?(Issue.find(13))
+  end
+
+  def test_auto_complete_without_scope_all_should_not_search_other_projects
+    get :issues, :project_id => 'ecookbook', :q => '13'
+    assert_response :success
+    assert_equal [], assigns(:issues)
+  end
+
+  def test_issues_should_return_json
+    get :issues, :project_id => 'subproject1', :q => '13'
+    assert_response :success
+    json = ActiveSupport::JSON.decode(response.body)
+    assert_kind_of Array, json
+    issue = json.first
+    assert_kind_of Hash, issue
+    assert_equal 13, issue['id']
+    assert_equal 13, issue['value']
+    assert_equal 'Bug #13: Subproject issue two', issue['label']
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/01/01fd40d061a2be270b23a0152d0699de1966efc7.svn-base
--- a/.svn/pristine/01/01fd40d061a2be270b23a0152d0699de1966efc7.svn-base
+++ /dev/null
@@ -1,194 +0,0 @@
---- 
-roles_001: 
-  name: Manager
-  id: 1
-  builtin: 0
-  issues_visibility: all
-  permissions: |
-    --- 
-    - :add_project
-    - :edit_project
-    - :select_project_modules
-    - :manage_members
-    - :manage_versions
-    - :manage_categories
-    - :view_issues
-    - :add_issues
-    - :edit_issues
-    - :manage_issue_relations
-    - :manage_subtasks
-    - :add_issue_notes
-    - :move_issues
-    - :delete_issues
-    - :view_issue_watchers
-    - :add_issue_watchers
-    - :set_issues_private
-    - :delete_issue_watchers
-    - :manage_public_queries
-    - :save_queries
-    - :view_gantt
-    - :view_calendar
-    - :log_time
-    - :view_time_entries
-    - :edit_time_entries
-    - :delete_time_entries
-    - :manage_news
-    - :comment_news
-    - :view_documents
-    - :manage_documents
-    - :view_wiki_pages
-    - :export_wiki_pages
-    - :view_wiki_edits
-    - :edit_wiki_pages
-    - :delete_wiki_pages_attachments
-    - :protect_wiki_pages
-    - :delete_wiki_pages
-    - :rename_wiki_pages
-    - :add_messages
-    - :edit_messages
-    - :delete_messages
-    - :manage_boards
-    - :view_files
-    - :manage_files
-    - :browse_repository
-    - :manage_repository
-    - :view_changesets
-    - :manage_project_activities
-
-  position: 1
-roles_002: 
-  name: Developer
-  id: 2
-  builtin: 0
-  issues_visibility: default
-  permissions: |
-    --- 
-    - :edit_project
-    - :manage_members
-    - :manage_versions
-    - :manage_categories
-    - :view_issues
-    - :add_issues
-    - :edit_issues
-    - :manage_issue_relations
-    - :manage_subtasks
-    - :add_issue_notes
-    - :move_issues
-    - :delete_issues
-    - :view_issue_watchers
-    - :save_queries
-    - :view_gantt
-    - :view_calendar
-    - :log_time
-    - :view_time_entries
-    - :edit_own_time_entries
-    - :manage_news
-    - :comment_news
-    - :view_documents
-    - :manage_documents
-    - :view_wiki_pages
-    - :view_wiki_edits
-    - :edit_wiki_pages
-    - :protect_wiki_pages
-    - :delete_wiki_pages
-    - :add_messages
-    - :edit_own_messages
-    - :delete_own_messages
-    - :manage_boards
-    - :view_files
-    - :manage_files
-    - :browse_repository
-    - :view_changesets
-
-  position: 2
-roles_003: 
-  name: Reporter
-  id: 3
-  builtin: 0
-  issues_visibility: default
-  permissions: |
-    --- 
-    - :edit_project
-    - :manage_members
-    - :manage_versions
-    - :manage_categories
-    - :view_issues
-    - :add_issues
-    - :edit_issues
-    - :manage_issue_relations
-    - :add_issue_notes
-    - :move_issues
-    - :view_issue_watchers
-    - :save_queries
-    - :view_gantt
-    - :view_calendar
-    - :log_time
-    - :view_time_entries
-    - :manage_news
-    - :comment_news
-    - :view_documents
-    - :manage_documents
-    - :view_wiki_pages
-    - :view_wiki_edits
-    - :edit_wiki_pages
-    - :delete_wiki_pages
-    - :add_messages
-    - :manage_boards
-    - :view_files
-    - :manage_files
-    - :browse_repository
-    - :view_changesets
-
-  position: 3
-roles_004: 
-  name: Non member
-  id: 4
-  builtin: 1
-  issues_visibility: default
-  permissions: |
-    --- 
-    - :view_issues
-    - :add_issues
-    - :edit_issues
-    - :manage_issue_relations
-    - :add_issue_notes
-    - :move_issues
-    - :save_queries
-    - :view_gantt
-    - :view_calendar
-    - :log_time
-    - :view_time_entries
-    - :comment_news
-    - :view_documents
-    - :manage_documents
-    - :view_wiki_pages
-    - :view_wiki_edits
-    - :edit_wiki_pages
-    - :add_messages
-    - :view_files
-    - :manage_files
-    - :browse_repository
-    - :view_changesets
-
-  position: 4
-roles_005: 
-  name: Anonymous
-  id: 5
-  builtin: 2
-  issues_visibility: default
-  permissions: |
-    --- 
-    - :view_issues
-    - :add_issue_notes
-    - :view_gantt
-    - :view_calendar
-    - :view_time_entries
-    - :view_documents
-    - :view_wiki_pages
-    - :view_wiki_edits
-    - :view_files
-    - :browse_repository
-    - :view_changesets
-
-  position: 5
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/02/025612e4a47b7cb1c36f52b9661b0cc1f94b2a45.svn-base
--- a/.svn/pristine/02/025612e4a47b7cb1c36f52b9661b0cc1f94b2a45.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-one:
-  id: 1
-<% for attribute in attributes -%>
-  <%= attribute.name %>: <%= attribute.default %>
-<% end -%>
-two:
-  id: 2
-<% for attribute in attributes -%>
-  <%= attribute.name %>: <%= attribute.default %>
-<% end -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/02/026bb2d46eaa121e79862de3515bb99ff0827ca3.svn-base
--- /dev/null
+++ b/.svn/pristine/02/026bb2d46eaa121e79862de3515bb99ff0827ca3.svn-base
@@ -0,0 +1,943 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Helpers
+    # Simple class to handle gantt chart data
+    class Gantt
+      include ERB::Util
+      include Redmine::I18n
+      include Redmine::Utils::DateCalculation
+
+      # Relation types that are rendered
+      DRAW_TYPES = {
+        IssueRelation::TYPE_BLOCKS   => { :landscape_margin => 16, :color => '#F34F4F' },
+        IssueRelation::TYPE_PRECEDES => { :landscape_margin => 20, :color => '#628FEA' }
+      }.freeze
+
+      # :nodoc:
+      # Some utility methods for the PDF export
+      class PDF
+        MaxCharactorsForSubject = 45
+        TotalWidth = 280
+        LeftPaneWidth = 100
+
+        def self.right_pane_width
+          TotalWidth - LeftPaneWidth
+        end
+      end
+
+      attr_reader :year_from, :month_from, :date_from, :date_to, :zoom, :months, :truncated, :max_rows
+      attr_accessor :query
+      attr_accessor :project
+      attr_accessor :view
+
+      def initialize(options={})
+        options = options.dup
+        if options[:year] && options[:year].to_i >0
+          @year_from = options[:year].to_i
+          if options[:month] && options[:month].to_i >=1 && options[:month].to_i <= 12
+            @month_from = options[:month].to_i
+          else
+            @month_from = 1
+          end
+        else
+          @month_from ||= Date.today.month
+          @year_from ||= Date.today.year
+        end
+        zoom = (options[:zoom] || User.current.pref[:gantt_zoom]).to_i
+        @zoom = (zoom > 0 && zoom < 5) ? zoom : 2
+        months = (options[:months] || User.current.pref[:gantt_months]).to_i
+        @months = (months > 0 && months < 25) ? months : 6
+        # Save gantt parameters as user preference (zoom and months count)
+        if (User.current.logged? && (@zoom != User.current.pref[:gantt_zoom] ||
+              @months != User.current.pref[:gantt_months]))
+          User.current.pref[:gantt_zoom], User.current.pref[:gantt_months] = @zoom, @months
+          User.current.preference.save
+        end
+        @date_from = Date.civil(@year_from, @month_from, 1)
+        @date_to = (@date_from >> @months) - 1
+        @subjects = ''
+        @lines = ''
+        @number_of_rows = nil
+        @issue_ancestors = []
+        @truncated = false
+        if options.has_key?(:max_rows)
+          @max_rows = options[:max_rows]
+        else
+          @max_rows = Setting.gantt_items_limit.blank? ? nil : Setting.gantt_items_limit.to_i
+        end
+      end
+
+      def common_params
+        { :controller => 'gantts', :action => 'show', :project_id => @project }
+      end
+
+      def params
+        common_params.merge({:zoom => zoom, :year => year_from,
+                             :month => month_from, :months => months})
+      end
+
+      def params_previous
+        common_params.merge({:year => (date_from << months).year,
+                             :month => (date_from << months).month,
+                             :zoom => zoom, :months => months})
+      end
+
+      def params_next
+        common_params.merge({:year => (date_from >> months).year,
+                             :month => (date_from >> months).month,
+                             :zoom => zoom, :months => months})
+      end
+
+      # Returns the number of rows that will be rendered on the Gantt chart
+      def number_of_rows
+        return @number_of_rows if @number_of_rows
+        rows = projects.inject(0) {|total, p| total += number_of_rows_on_project(p)}
+        rows > @max_rows ? @max_rows : rows
+      end
+
+      # Returns the number of rows that will be used to list a project on
+      # the Gantt chart.  This will recurse for each subproject.
+      def number_of_rows_on_project(project)
+        return 0 unless projects.include?(project)
+        count = 1
+        count += project_issues(project).size
+        count += project_versions(project).size
+        count
+      end
+
+      # Renders the subjects of the Gantt chart, the left side.
+      def subjects(options={})
+        render(options.merge(:only => :subjects)) unless @subjects_rendered
+        @subjects
+      end
+
+      # Renders the lines of the Gantt chart, the right side
+      def lines(options={})
+        render(options.merge(:only => :lines)) unless @lines_rendered
+        @lines
+      end
+
+      # Returns issues that will be rendered
+      def issues
+        @issues ||= @query.issues(
+          :include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
+          :order => "#{Project.table_name}.lft ASC, #{Issue.table_name}.id ASC",
+          :limit => @max_rows
+        )
+      end
+
+      # Returns a hash of the relations between the issues that are present on the gantt
+      # and that should be displayed, grouped by issue ids.
+      def relations
+        return @relations if @relations
+        if issues.any?
+          issue_ids = issues.map(&:id)
+          @relations = IssueRelation.
+            where(:issue_from_id => issue_ids, :issue_to_id => issue_ids, :relation_type => DRAW_TYPES.keys).
+            group_by(&:issue_from_id)
+        else
+          @relations = {}
+        end
+      end
+
+      # Return all the project nodes that will be displayed
+      def projects
+        return @projects if @projects
+        ids = issues.collect(&:project).uniq.collect(&:id)
+        if ids.any?
+          # All issues projects and their visible ancestors
+          @projects = Project.visible.all(
+            :joins => "LEFT JOIN #{Project.table_name} child ON #{Project.table_name}.lft <= child.lft AND #{Project.table_name}.rgt >= child.rgt",
+            :conditions => ["child.id IN (?)", ids],
+            :order => "#{Project.table_name}.lft ASC"
+          ).uniq
+        else
+          @projects = []
+        end
+      end
+
+      # Returns the issues that belong to +project+
+      def project_issues(project)
+        @issues_by_project ||= issues.group_by(&:project)
+        @issues_by_project[project] || []
+      end
+
+      # Returns the distinct versions of the issues that belong to +project+
+      def project_versions(project)
+        project_issues(project).collect(&:fixed_version).compact.uniq
+      end
+
+      # Returns the issues that belong to +project+ and are assigned to +version+
+      def version_issues(project, version)
+        project_issues(project).select {|issue| issue.fixed_version == version}
+      end
+
+      def render(options={})
+        options = {:top => 0, :top_increment => 20,
+                   :indent_increment => 20, :render => :subject,
+                   :format => :html}.merge(options)
+        indent = options[:indent] || 4
+        @subjects = '' unless options[:only] == :lines
+        @lines = '' unless options[:only] == :subjects
+        @number_of_rows = 0
+        Project.project_tree(projects) do |project, level|
+          options[:indent] = indent + level * options[:indent_increment]
+          render_project(project, options)
+          break if abort?
+        end
+        @subjects_rendered = true unless options[:only] == :lines
+        @lines_rendered = true unless options[:only] == :subjects
+        render_end(options)
+      end
+
+      def render_project(project, options={})
+        subject_for_project(project, options) unless options[:only] == :lines
+        line_for_project(project, options) unless options[:only] == :subjects
+        options[:top] += options[:top_increment]
+        options[:indent] += options[:indent_increment]
+        @number_of_rows += 1
+        return if abort?
+        issues = project_issues(project).select {|i| i.fixed_version.nil?}
+        sort_issues!(issues)
+        if issues
+          render_issues(issues, options)
+          return if abort?
+        end
+        versions = project_versions(project)
+        versions.each do |version|
+          render_version(project, version, options)
+        end
+        # Remove indent to hit the next sibling
+        options[:indent] -= options[:indent_increment]
+      end
+
+      def render_issues(issues, options={})
+        @issue_ancestors = []
+        issues.each do |i|
+          subject_for_issue(i, options) unless options[:only] == :lines
+          line_for_issue(i, options) unless options[:only] == :subjects
+          options[:top] += options[:top_increment]
+          @number_of_rows += 1
+          break if abort?
+        end
+        options[:indent] -= (options[:indent_increment] * @issue_ancestors.size)
+      end
+
+      def render_version(project, version, options={})
+        # Version header
+        subject_for_version(version, options) unless options[:only] == :lines
+        line_for_version(version, options) unless options[:only] == :subjects
+        options[:top] += options[:top_increment]
+        @number_of_rows += 1
+        return if abort?
+        issues = version_issues(project, version)
+        if issues
+          sort_issues!(issues)
+          # Indent issues
+          options[:indent] += options[:indent_increment]
+          render_issues(issues, options)
+          options[:indent] -= options[:indent_increment]
+        end
+      end
+
+      def render_end(options={})
+        case options[:format]
+        when :pdf
+          options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top])
+        end
+      end
+
+      def subject_for_project(project, options)
+        case options[:format]
+        when :html
+          html_class = ""
+          html_class << 'icon icon-projects '
+          html_class << (project.overdue? ? 'project-overdue' : '')
+          s = view.link_to_project(project).html_safe
+          subject = view.content_tag(:span, s,
+                                     :class => html_class).html_safe
+          html_subject(options, subject, :css => "project-name")
+        when :image
+          image_subject(options, project.name)
+        when :pdf
+          pdf_new_page?(options)
+          pdf_subject(options, project.name)
+        end
+      end
+
+      def line_for_project(project, options)
+        # Skip versions that don't have a start_date or due date
+        if project.is_a?(Project) && project.start_date && project.due_date
+          options[:zoom] ||= 1
+          options[:g_width] ||= (self.date_to - self.date_from + 1) * options[:zoom]
+          coords = coordinates(project.start_date, project.due_date, nil, options[:zoom])
+          label = h(project)
+          case options[:format]
+          when :html
+            html_task(options, coords, :css => "project task", :label => label, :markers => true)
+          when :image
+            image_task(options, coords, :label => label, :markers => true, :height => 3)
+          when :pdf
+            pdf_task(options, coords, :label => label, :markers => true, :height => 0.8)
+          end
+        else
+          ''
+        end
+      end
+
+      def subject_for_version(version, options)
+        case options[:format]
+        when :html
+          html_class = ""
+          html_class << 'icon icon-package '
+          html_class << (version.behind_schedule? ? 'version-behind-schedule' : '') << " "
+          html_class << (version.overdue? ? 'version-overdue' : '')
+          html_class << ' version-closed' unless version.open?
+          if version.start_date && version.due_date && version.completed_pourcent
+            progress_date = calc_progress_date(version.start_date,
+                                               version.due_date, version.completed_pourcent)
+            html_class << ' behind-start-date' if progress_date < self.date_from
+            html_class << ' over-end-date' if progress_date > self.date_to
+          end
+          s = view.link_to_version(version).html_safe
+          subject = view.content_tag(:span, s,
+                                     :class => html_class).html_safe
+          html_subject(options, subject, :css => "version-name",
+                       :id => "version-#{version.id}")
+        when :image
+          image_subject(options, version.to_s_with_project)
+        when :pdf
+          pdf_new_page?(options)
+          pdf_subject(options, version.to_s_with_project)
+        end
+      end
+
+      def line_for_version(version, options)
+        # Skip versions that don't have a start_date
+        if version.is_a?(Version) && version.due_date && version.start_date
+          options[:zoom] ||= 1
+          options[:g_width] ||= (self.date_to - self.date_from + 1) * options[:zoom]
+          coords = coordinates(version.start_date,
+                               version.due_date, version.completed_percent,
+                               options[:zoom])
+          label = "#{h version} #{h version.completed_percent.to_i.to_s}%"
+          label = h("#{version.project} -") + label unless @project && @project == version.project
+          case options[:format]
+          when :html
+            html_task(options, coords, :css => "version task",
+                      :label => label, :markers => true, :version => version)
+          when :image
+            image_task(options, coords, :label => label, :markers => true, :height => 3)
+          when :pdf
+            pdf_task(options, coords, :label => label, :markers => true, :height => 0.8)
+          end
+        else
+          ''
+        end
+      end
+
+      def subject_for_issue(issue, options)
+        while @issue_ancestors.any? && !issue.is_descendant_of?(@issue_ancestors.last)
+          @issue_ancestors.pop
+          options[:indent] -= options[:indent_increment]
+        end
+        output = case options[:format]
+        when :html
+          css_classes = ''
+          css_classes << ' issue-overdue' if issue.overdue?
+          css_classes << ' issue-behind-schedule' if issue.behind_schedule?
+          css_classes << ' icon icon-issue' unless Setting.gravatar_enabled? && issue.assigned_to
+          css_classes << ' issue-closed' if issue.closed?
+          if issue.start_date && issue.due_before && issue.done_ratio
+            progress_date = calc_progress_date(issue.start_date,
+                                               issue.due_before, issue.done_ratio)
+            css_classes << ' behind-start-date' if progress_date < self.date_from
+            css_classes << ' over-end-date' if progress_date > self.date_to
+          end
+          s = "".html_safe
+          if issue.assigned_to.present?
+            assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name
+            s << view.avatar(issue.assigned_to,
+                             :class => 'gravatar icon-gravatar',
+                             :size => 10,
+                             :title => assigned_string).to_s.html_safe
+          end
+          s << view.link_to_issue(issue).html_safe
+          subject = view.content_tag(:span, s, :class => css_classes).html_safe
+          html_subject(options, subject, :css => "issue-subject",
+                       :title => issue.subject, :id => "issue-#{issue.id}") + "\n"
+        when :image
+          image_subject(options, issue.subject)
+        when :pdf
+          pdf_new_page?(options)
+          pdf_subject(options, issue.subject)
+        end
+        unless issue.leaf?
+          @issue_ancestors << issue
+          options[:indent] += options[:indent_increment]
+        end
+        output
+      end
+
+      def line_for_issue(issue, options)
+        # Skip issues that don't have a due_before (due_date or version's due_date)
+        if issue.is_a?(Issue) && issue.due_before
+          coords = coordinates(issue.start_date, issue.due_before, issue.done_ratio, options[:zoom])
+          label = "#{issue.status.name} #{issue.done_ratio}%"
+          case options[:format]
+          when :html
+            html_task(options, coords,
+                      :css => "task " + (issue.leaf? ? 'leaf' : 'parent'),
+                      :label => label, :issue => issue,
+                      :markers => !issue.leaf?)
+          when :image
+            image_task(options, coords, :label => label)
+          when :pdf
+            pdf_task(options, coords, :label => label)
+        end
+        else
+          ''
+        end
+      end
+
+      # Generates a gantt image
+      # Only defined if RMagick is avalaible
+      def to_image(format='PNG')
+        date_to = (@date_from >> @months) - 1
+        show_weeks = @zoom > 1
+        show_days = @zoom > 2
+        subject_width = 400
+        header_height = 18
+        # width of one day in pixels
+        zoom = @zoom * 2
+        g_width = (@date_to - @date_from + 1) * zoom
+        g_height = 20 * number_of_rows + 30
+        headers_height = (show_weeks ? 2 * header_height : header_height)
+        height = g_height + headers_height
+        imgl = Magick::ImageList.new
+        imgl.new_image(subject_width + g_width + 1, height)
+        gc = Magick::Draw.new
+        gc.font = Redmine::Configuration['rmagick_font_path'] || ""
+        # Subjects
+        gc.stroke('transparent')
+        subjects(:image => gc, :top => (headers_height + 20), :indent => 4, :format => :image)
+        # Months headers
+        month_f = @date_from
+        left = subject_width
+        @months.times do
+          width = ((month_f >> 1) - month_f) * zoom
+          gc.fill('white')
+          gc.stroke('grey')
+          gc.stroke_width(1)
+          gc.rectangle(left, 0, left + width, height)
+          gc.fill('black')
+          gc.stroke('transparent')
+          gc.stroke_width(1)
+          gc.text(left.round + 8, 14, "#{month_f.year}-#{month_f.month}")
+          left = left + width
+          month_f = month_f >> 1
+        end
+        # Weeks headers
+        if show_weeks
+          left = subject_width
+          height = header_height
+          if @date_from.cwday == 1
+            # date_from is monday
+            week_f = date_from
+          else
+            # find next monday after date_from
+            week_f = @date_from + (7 - @date_from.cwday + 1)
+            width = (7 - @date_from.cwday + 1) * zoom
+            gc.fill('white')
+            gc.stroke('grey')
+            gc.stroke_width(1)
+            gc.rectangle(left, header_height, left + width, 2 * header_height + g_height - 1)
+            left = left + width
+          end
+          while week_f <= date_to
+            width = (week_f + 6 <= date_to) ? 7 * zoom : (date_to - week_f + 1) * zoom
+            gc.fill('white')
+            gc.stroke('grey')
+            gc.stroke_width(1)
+            gc.rectangle(left.round, header_height, left.round + width, 2 * header_height + g_height - 1)
+            gc.fill('black')
+            gc.stroke('transparent')
+            gc.stroke_width(1)
+            gc.text(left.round + 2, header_height + 14, week_f.cweek.to_s)
+            left = left + width
+            week_f = week_f + 7
+          end
+        end
+        # Days details (week-end in grey)
+        if show_days
+          left = subject_width
+          height = g_height + header_height - 1
+          wday = @date_from.cwday
+          (date_to - @date_from + 1).to_i.times do
+            width =  zoom
+            gc.fill(non_working_week_days.include?(wday) ? '#eee' : 'white')
+            gc.stroke('#ddd')
+            gc.stroke_width(1)
+            gc.rectangle(left, 2 * header_height, left + width, 2 * header_height + g_height - 1)
+            left = left + width
+            wday = wday + 1
+            wday = 1 if wday > 7
+          end
+        end
+        # border
+        gc.fill('transparent')
+        gc.stroke('grey')
+        gc.stroke_width(1)
+        gc.rectangle(0, 0, subject_width + g_width, headers_height)
+        gc.stroke('black')
+        gc.rectangle(0, 0, subject_width + g_width, g_height + headers_height - 1)
+        # content
+        top = headers_height + 20
+        gc.stroke('transparent')
+        lines(:image => gc, :top => top, :zoom => zoom,
+              :subject_width => subject_width, :format => :image)
+        # today red line
+        if Date.today >= @date_from and Date.today <= date_to
+          gc.stroke('red')
+          x = (Date.today - @date_from + 1) * zoom + subject_width
+          gc.line(x, headers_height, x, headers_height + g_height - 1)
+        end
+        gc.draw(imgl)
+        imgl.format = format
+        imgl.to_blob
+      end if Object.const_defined?(:Magick)
+
+      def to_pdf
+        pdf = ::Redmine::Export::PDF::ITCPDF.new(current_language)
+        pdf.SetTitle("#{l(:label_gantt)} #{project}")
+        pdf.alias_nb_pages
+        pdf.footer_date = format_date(Date.today)
+        pdf.AddPage("L")
+        pdf.SetFontStyle('B', 12)
+        pdf.SetX(15)
+        pdf.RDMCell(PDF::LeftPaneWidth, 20, project.to_s)
+        pdf.Ln
+        pdf.SetFontStyle('B', 9)
+        subject_width = PDF::LeftPaneWidth
+        header_height = 5
+        headers_height = header_height
+        show_weeks = false
+        show_days = false
+        if self.months < 7
+          show_weeks = true
+          headers_height = 2 * header_height
+          if self.months < 3
+            show_days = true
+            headers_height = 3 * header_height
+          end
+        end
+        g_width = PDF.right_pane_width
+        zoom = (g_width) / (self.date_to - self.date_from + 1)
+        g_height = 120
+        t_height = g_height + headers_height
+        y_start = pdf.GetY
+        # Months headers
+        month_f = self.date_from
+        left = subject_width
+        height = header_height
+        self.months.times do
+          width = ((month_f >> 1) - month_f) * zoom
+          pdf.SetY(y_start)
+          pdf.SetX(left)
+          pdf.RDMCell(width, height, "#{month_f.year}-#{month_f.month}", "LTR", 0, "C")
+          left = left + width
+          month_f = month_f >> 1
+        end
+        # Weeks headers
+        if show_weeks
+          left = subject_width
+          height = header_height
+          if self.date_from.cwday == 1
+            # self.date_from is monday
+            week_f = self.date_from
+          else
+            # find next monday after self.date_from
+            week_f = self.date_from + (7 - self.date_from.cwday + 1)
+            width = (7 - self.date_from.cwday + 1) * zoom-1
+            pdf.SetY(y_start + header_height)
+            pdf.SetX(left)
+            pdf.RDMCell(width + 1, height, "", "LTR")
+            left = left + width + 1
+          end
+          while week_f <= self.date_to
+            width = (week_f + 6 <= self.date_to) ? 7 * zoom : (self.date_to - week_f + 1) * zoom
+            pdf.SetY(y_start + header_height)
+            pdf.SetX(left)
+            pdf.RDMCell(width, height, (width >= 5 ? week_f.cweek.to_s : ""), "LTR", 0, "C")
+            left = left + width
+            week_f = week_f + 7
+          end
+        end
+        # Days headers
+        if show_days
+          left = subject_width
+          height = header_height
+          wday = self.date_from.cwday
+          pdf.SetFontStyle('B', 7)
+          (self.date_to - self.date_from + 1).to_i.times do
+            width = zoom
+            pdf.SetY(y_start + 2 * header_height)
+            pdf.SetX(left)
+            pdf.RDMCell(width, height, day_name(wday).first, "LTR", 0, "C")
+            left = left + width
+            wday = wday + 1
+            wday = 1 if wday > 7
+          end
+        end
+        pdf.SetY(y_start)
+        pdf.SetX(15)
+        pdf.RDMCell(subject_width + g_width - 15, headers_height, "", 1)
+        # Tasks
+        top = headers_height + y_start
+        options = {
+          :top => top,
+          :zoom => zoom,
+          :subject_width => subject_width,
+          :g_width => g_width,
+          :indent => 0,
+          :indent_increment => 5,
+          :top_increment => 5,
+          :format => :pdf,
+          :pdf => pdf
+        }
+        render(options)
+        pdf.Output
+      end
+
+      private
+
+      def coordinates(start_date, end_date, progress, zoom=nil)
+        zoom ||= @zoom
+        coords = {}
+        if start_date && end_date && start_date < self.date_to && end_date > self.date_from
+          if start_date > self.date_from
+            coords[:start] = start_date - self.date_from
+            coords[:bar_start] = start_date - self.date_from
+          else
+            coords[:bar_start] = 0
+          end
+          if end_date < self.date_to
+            coords[:end] = end_date - self.date_from
+            coords[:bar_end] = end_date - self.date_from + 1
+          else
+            coords[:bar_end] = self.date_to - self.date_from + 1
+          end
+          if progress
+            progress_date = calc_progress_date(start_date, end_date, progress)
+            if progress_date > self.date_from && progress_date > start_date
+              if progress_date < self.date_to
+                coords[:bar_progress_end] = progress_date - self.date_from
+              else
+                coords[:bar_progress_end] = self.date_to - self.date_from + 1
+              end
+            end
+            if progress_date < Date.today
+              late_date = [Date.today, end_date].min
+              if late_date > self.date_from && late_date > start_date
+                if late_date < self.date_to
+                  coords[:bar_late_end] = late_date - self.date_from + 1
+                else
+                  coords[:bar_late_end] = self.date_to - self.date_from + 1
+                end
+              end
+            end
+          end
+        end
+        # Transforms dates into pixels witdh
+        coords.keys.each do |key|
+          coords[key] = (coords[key] * zoom).floor
+        end
+        coords
+      end
+
+      def calc_progress_date(start_date, end_date, progress)
+        start_date + (end_date - start_date + 1) * (progress / 100.0)
+      end
+
+      # TODO: Sorts a collection of issues by start_date, due_date, id for gantt rendering
+      def sort_issues!(issues)
+        issues.sort! { |a, b| gantt_issue_compare(a, b) }
+      end
+
+      # TODO: top level issues should be sorted by start date
+      def gantt_issue_compare(x, y)
+        if x.root_id == y.root_id
+          x.lft <=> y.lft
+        else
+          x.root_id <=> y.root_id
+        end
+      end
+
+      def current_limit
+        if @max_rows
+          @max_rows - @number_of_rows
+        else
+          nil
+        end
+      end
+
+      def abort?
+        if @max_rows && @number_of_rows >= @max_rows
+          @truncated = true
+        end
+      end
+
+      def pdf_new_page?(options)
+        if options[:top] > 180
+          options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top])
+          options[:pdf].AddPage("L")
+          options[:top] = 15
+          options[:pdf].Line(15, options[:top] - 0.1, PDF::TotalWidth, options[:top] - 0.1)
+        end
+      end
+
+      def html_subject(params, subject, options={})
+        style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;"
+        style << "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width]
+        output = view.content_tag(:div, subject,
+                                  :class => options[:css], :style => style,
+                                  :title => options[:title],
+                                  :id => options[:id])
+        @subjects << output
+        output
+      end
+
+      def pdf_subject(params, subject, options={})
+        params[:pdf].SetY(params[:top])
+        params[:pdf].SetX(15)
+        char_limit = PDF::MaxCharactorsForSubject - params[:indent]
+        params[:pdf].RDMCell(params[:subject_width] - 15, 5,
+                             (" " * params[:indent]) +
+                               subject.to_s.sub(/^(.{#{char_limit}}[^\s]*\s).*$/, '\1 (...)'),
+                              "LR")
+        params[:pdf].SetY(params[:top])
+        params[:pdf].SetX(params[:subject_width])
+        params[:pdf].RDMCell(params[:g_width], 5, "", "LR")
+      end
+
+      def image_subject(params, subject, options={})
+        params[:image].fill('black')
+        params[:image].stroke('transparent')
+        params[:image].stroke_width(1)
+        params[:image].text(params[:indent], params[:top] + 2, subject)
+      end
+
+      def issue_relations(issue)
+        rels = {}
+        if relations[issue.id]
+          relations[issue.id].each do |relation|
+            (rels[relation.relation_type] ||= []) << relation.issue_to_id
+          end
+        end
+        rels
+      end
+
+      def html_task(params, coords, options={})
+        output = ''
+        # Renders the task bar, with progress and late
+        if coords[:bar_start] && coords[:bar_end]
+          width = coords[:bar_end] - coords[:bar_start] - 2
+          style = ""
+          style << "top:#{params[:top]}px;"
+          style << "left:#{coords[:bar_start]}px;"
+          style << "width:#{width}px;"
+          html_id = "task-todo-issue-#{options[:issue].id}" if options[:issue]
+          html_id = "task-todo-version-#{options[:version].id}" if options[:version]
+          content_opt = {:style => style,
+                         :class => "#{options[:css]} task_todo",
+                         :id => html_id}
+          if options[:issue]
+            rels = issue_relations(options[:issue])
+            if rels.present?
+              content_opt[:data] = {"rels" => rels.to_json}
+            end
+          end
+          output << view.content_tag(:div, '&nbsp;'.html_safe, content_opt)
+          if coords[:bar_late_end]
+            width = coords[:bar_late_end] - coords[:bar_start] - 2
+            style = ""
+            style << "top:#{params[:top]}px;"
+            style << "left:#{coords[:bar_start]}px;"
+            style << "width:#{width}px;"
+            output << view.content_tag(:div, '&nbsp;'.html_safe,
+                                       :style => style,
+                                       :class => "#{options[:css]} task_late")
+          end
+          if coords[:bar_progress_end]
+            width = coords[:bar_progress_end] - coords[:bar_start] - 2
+            style = ""
+            style << "top:#{params[:top]}px;"
+            style << "left:#{coords[:bar_start]}px;"
+            style << "width:#{width}px;"
+            html_id = "task-done-issue-#{options[:issue].id}" if options[:issue]
+            html_id = "task-done-version-#{options[:version].id}" if options[:version]
+            output << view.content_tag(:div, '&nbsp;'.html_safe,
+                                       :style => style,
+                                       :class => "#{options[:css]} task_done",
+                                       :id => html_id)
+          end
+        end
+        # Renders the markers
+        if options[:markers]
+          if coords[:start]
+            style = ""
+            style << "top:#{params[:top]}px;"
+            style << "left:#{coords[:start]}px;"
+            style << "width:15px;"
+            output << view.content_tag(:div, '&nbsp;'.html_safe,
+                                       :style => style,
+                                       :class => "#{options[:css]} marker starting")
+          end
+          if coords[:end]
+            style = ""
+            style << "top:#{params[:top]}px;"
+            style << "left:#{coords[:end] + params[:zoom]}px;"
+            style << "width:15px;"
+            output << view.content_tag(:div, '&nbsp;'.html_safe,
+                                       :style => style,
+                                       :class => "#{options[:css]} marker ending")
+          end
+        end
+        # Renders the label on the right
+        if options[:label]
+          style = ""
+          style << "top:#{params[:top]}px;"
+          style << "left:#{(coords[:bar_end] || 0) + 8}px;"
+          style << "width:15px;"
+          output << view.content_tag(:div, options[:label],
+                                     :style => style,
+                                     :class => "#{options[:css]} label")
+        end
+        # Renders the tooltip
+        if options[:issue] && coords[:bar_start] && coords[:bar_end]
+          s = view.content_tag(:span,
+                               view.render_issue_tooltip(options[:issue]).html_safe,
+                               :class => "tip")
+          style = ""
+          style << "position: absolute;"
+          style << "top:#{params[:top]}px;"
+          style << "left:#{coords[:bar_start]}px;"
+          style << "width:#{coords[:bar_end] - coords[:bar_start]}px;"
+          style << "height:12px;"
+          output << view.content_tag(:div, s.html_safe,
+                                     :style => style,
+                                     :class => "tooltip")
+        end
+        @lines << output
+        output
+      end
+
+      def pdf_task(params, coords, options={})
+        height = options[:height] || 2
+        # Renders the task bar, with progress and late
+        if coords[:bar_start] && coords[:bar_end]
+          params[:pdf].SetY(params[:top] + 1.5)
+          params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
+          params[:pdf].SetFillColor(200, 200, 200)
+          params[:pdf].RDMCell(coords[:bar_end] - coords[:bar_start], height, "", 0, 0, "", 1)
+          if coords[:bar_late_end]
+            params[:pdf].SetY(params[:top] + 1.5)
+            params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
+            params[:pdf].SetFillColor(255, 100, 100)
+            params[:pdf].RDMCell(coords[:bar_late_end] - coords[:bar_start], height, "", 0, 0, "", 1)
+          end
+          if coords[:bar_progress_end]
+            params[:pdf].SetY(params[:top] + 1.5)
+            params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
+            params[:pdf].SetFillColor(90, 200, 90)
+            params[:pdf].RDMCell(coords[:bar_progress_end] - coords[:bar_start], height, "", 0, 0, "", 1)
+          end
+        end
+        # Renders the markers
+        if options[:markers]
+          if coords[:start]
+            params[:pdf].SetY(params[:top] + 1)
+            params[:pdf].SetX(params[:subject_width] + coords[:start] - 1)
+            params[:pdf].SetFillColor(50, 50, 200)
+            params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1)
+          end
+          if coords[:end]
+            params[:pdf].SetY(params[:top] + 1)
+            params[:pdf].SetX(params[:subject_width] + coords[:end] - 1)
+            params[:pdf].SetFillColor(50, 50, 200)
+            params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1)
+          end
+        end
+        # Renders the label on the right
+        if options[:label]
+          params[:pdf].SetX(params[:subject_width] + (coords[:bar_end] || 0) + 5)
+          params[:pdf].RDMCell(30, 2, options[:label])
+        end
+      end
+
+      def image_task(params, coords, options={})
+        height = options[:height] || 6
+        # Renders the task bar, with progress and late
+        if coords[:bar_start] && coords[:bar_end]
+          params[:image].fill('#aaa')
+          params[:image].rectangle(params[:subject_width] + coords[:bar_start],
+                                   params[:top],
+                                   params[:subject_width] + coords[:bar_end],
+                                   params[:top] - height)
+          if coords[:bar_late_end]
+            params[:image].fill('#f66')
+            params[:image].rectangle(params[:subject_width] + coords[:bar_start],
+                                     params[:top],
+                                     params[:subject_width] + coords[:bar_late_end],
+                                     params[:top] - height)
+          end
+          if coords[:bar_progress_end]
+            params[:image].fill('#00c600')
+            params[:image].rectangle(params[:subject_width] + coords[:bar_start],
+                                     params[:top],
+                                     params[:subject_width] + coords[:bar_progress_end],
+                                     params[:top] - height)
+          end
+        end
+        # Renders the markers
+        if options[:markers]
+          if coords[:start]
+            x = params[:subject_width] + coords[:start]
+            y = params[:top] - height / 2
+            params[:image].fill('blue')
+            params[:image].polygon(x - 4, y, x, y - 4, x + 4, y, x, y + 4)
+          end
+          if coords[:end]
+            x = params[:subject_width] + coords[:end] + params[:zoom]
+            y = params[:top] - height / 2
+            params[:image].fill('blue')
+            params[:image].polygon(x - 4, y, x, y - 4, x + 4, y, x, y + 4)
+          end
+        end
+        # Renders the label on the right
+        if options[:label]
+          params[:image].fill('black')
+          params[:image].text(params[:subject_width] + (coords[:bar_end] || 0) + 5,
+                              params[:top] + 1,
+                              options[:label])
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/02/02c68441083bdea630158440f0e7d9d62ff8f790.svn-base
--- /dev/null
+++ b/.svn/pristine/02/02c68441083bdea630158440f0e7d9d62ff8f790.svn-base
@@ -0,0 +1,822 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class MailHandlerTest < ActiveSupport::TestCase
+  fixtures :users, :projects, :enabled_modules, :roles,
+           :members, :member_roles, :users,
+           :issues, :issue_statuses,
+           :workflows, :trackers, :projects_trackers,
+           :versions, :enumerations, :issue_categories,
+           :custom_fields, :custom_fields_trackers, :custom_fields_projects,
+           :boards, :messages
+
+  FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
+
+  def setup
+    ActionMailer::Base.deliveries.clear
+    Setting.notified_events = Redmine::Notifiable.all.collect(&:name)
+  end
+
+  def teardown
+    Setting.clear_cache
+  end
+
+  def test_add_issue
+    ActionMailer::Base.deliveries.clear
+    # This email contains: 'Project: onlinestore'
+    issue = submit_email('ticket_on_given_project.eml')
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal Project.find(2), issue.project
+    assert_equal issue.project.trackers.first, issue.tracker
+    assert_equal 'New ticket on a given project', issue.subject
+    assert_equal User.find_by_login('jsmith'), issue.author
+    assert_equal IssueStatus.find_by_name('Resolved'), issue.status
+    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
+    assert_equal '2010-01-01', issue.start_date.to_s
+    assert_equal '2010-12-31', issue.due_date.to_s
+    assert_equal User.find_by_login('jsmith'), issue.assigned_to
+    assert_equal Version.find_by_name('Alpha'), issue.fixed_version
+    assert_equal 2.5, issue.estimated_hours
+    assert_equal 30, issue.done_ratio
+    assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
+    # keywords should be removed from the email body
+    assert !issue.description.match(/^Project:/i)
+    assert !issue.description.match(/^Status:/i)
+    assert !issue.description.match(/^Start Date:/i)
+    # Email notification should be sent
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert mail.subject.include?('New ticket on a given project')
+  end
+
+  def test_add_issue_with_default_tracker
+    # This email contains: 'Project: onlinestore'
+    issue = submit_email(
+              'ticket_on_given_project.eml',
+              :issue => {:tracker => 'Support request'}
+            )
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal 'Support request', issue.tracker.name
+  end
+
+  def test_add_issue_with_status
+    # This email contains: 'Project: onlinestore' and 'Status: Resolved'
+    issue = submit_email('ticket_on_given_project.eml')
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal Project.find(2), issue.project
+    assert_equal IssueStatus.find_by_name("Resolved"), issue.status
+  end
+
+  def test_add_issue_with_attributes_override
+    issue = submit_email(
+              'ticket_with_attributes.eml',
+              :allow_override => 'tracker,category,priority'
+            )
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal 'New ticket on a given project', issue.subject
+    assert_equal User.find_by_login('jsmith'), issue.author
+    assert_equal Project.find(2), issue.project
+    assert_equal 'Feature request', issue.tracker.to_s
+    assert_equal 'Stock management', issue.category.to_s
+    assert_equal 'Urgent', issue.priority.to_s
+    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
+  end
+
+  def test_add_issue_with_group_assignment
+    with_settings :issue_group_assignment => '1' do
+      issue = submit_email('ticket_on_given_project.eml') do |email|
+        email.gsub!('Assigned to: John Smith', 'Assigned to: B Team')
+      end
+      assert issue.is_a?(Issue)
+      assert !issue.new_record?
+      issue.reload
+      assert_equal Group.find(11), issue.assigned_to
+    end
+  end
+
+  def test_add_issue_with_partial_attributes_override
+    issue = submit_email(
+              'ticket_with_attributes.eml',
+              :issue => {:priority => 'High'},
+              :allow_override => ['tracker']
+            )
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal 'New ticket on a given project', issue.subject
+    assert_equal User.find_by_login('jsmith'), issue.author
+    assert_equal Project.find(2), issue.project
+    assert_equal 'Feature request', issue.tracker.to_s
+    assert_nil issue.category
+    assert_equal 'High', issue.priority.to_s
+    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
+  end
+
+  def test_add_issue_with_spaces_between_attribute_and_separator
+    issue = submit_email(
+              'ticket_with_spaces_between_attribute_and_separator.eml',
+              :allow_override => 'tracker,category,priority'
+            )
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal 'New ticket on a given project', issue.subject
+    assert_equal User.find_by_login('jsmith'), issue.author
+    assert_equal Project.find(2), issue.project
+    assert_equal 'Feature request', issue.tracker.to_s
+    assert_equal 'Stock management', issue.category.to_s
+    assert_equal 'Urgent', issue.priority.to_s
+    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
+  end
+
+  def test_add_issue_with_attachment_to_specific_project
+    issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal 'Ticket created by email with attachment', issue.subject
+    assert_equal User.find_by_login('jsmith'), issue.author
+    assert_equal Project.find(2), issue.project
+    assert_equal 'This is  a new ticket with attachments', issue.description
+    # Attachment properties
+    assert_equal 1, issue.attachments.size
+    assert_equal 'Paella.jpg', issue.attachments.first.filename
+    assert_equal 'image/jpeg', issue.attachments.first.content_type
+    assert_equal 10790, issue.attachments.first.filesize
+  end
+
+  def test_add_issue_with_custom_fields
+    issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'onlinestore'})
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal 'New ticket with custom field values', issue.subject
+    assert_equal 'PostgreSQL', issue.custom_field_value(1)
+    assert_equal 'Value for a custom field', issue.custom_field_value(2)
+    assert !issue.description.match(/^searchable field:/i)
+  end
+
+  def test_add_issue_with_version_custom_fields
+    field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3])
+
+    issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'ecookbook'}) do |email|
+      email << "Affected version: 1.0\n"
+    end
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal '2', issue.custom_field_value(field)
+  end
+
+  def test_add_issue_should_match_assignee_on_display_name
+    user = User.generate!(:firstname => 'Foo Bar', :lastname => 'Foo Baz')
+    User.add_to_project(user, Project.find(2))
+    issue = submit_email('ticket_on_given_project.eml') do |email|
+      email.sub!(/^Assigned to.*$/, 'Assigned to: Foo Bar Foo baz')
+    end
+    assert issue.is_a?(Issue)
+    assert_equal user, issue.assigned_to
+  end
+
+  def test_add_issue_with_cc
+    issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'})
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert issue.watched_by?(User.find_by_mail('dlopper@somenet.foo'))
+    assert_equal 1, issue.watcher_user_ids.size
+  end
+
+  def test_add_issue_by_unknown_user
+    assert_no_difference 'User.count' do
+      assert_equal false,
+                   submit_email(
+                     'ticket_by_unknown_user.eml',
+                     :issue => {:project => 'ecookbook'}
+                   )
+    end
+  end
+
+  def test_add_issue_by_anonymous_user
+    Role.anonymous.add_permission!(:add_issues)
+    assert_no_difference 'User.count' do
+      issue = submit_email(
+                'ticket_by_unknown_user.eml',
+                :issue => {:project => 'ecookbook'},
+                :unknown_user => 'accept'
+              )
+      assert issue.is_a?(Issue)
+      assert issue.author.anonymous?
+    end
+  end
+
+  def test_add_issue_by_anonymous_user_with_no_from_address
+    Role.anonymous.add_permission!(:add_issues)
+    assert_no_difference 'User.count' do
+      issue = submit_email(
+                'ticket_by_empty_user.eml',
+                :issue => {:project => 'ecookbook'},
+                :unknown_user => 'accept'
+              )
+      assert issue.is_a?(Issue)
+      assert issue.author.anonymous?
+    end
+  end
+
+  def test_add_issue_by_anonymous_user_on_private_project
+    Role.anonymous.add_permission!(:add_issues)
+    assert_no_difference 'User.count' do
+      assert_no_difference 'Issue.count' do
+        assert_equal false,
+                     submit_email(
+                       'ticket_by_unknown_user.eml',
+                       :issue => {:project => 'onlinestore'},
+                       :unknown_user => 'accept'
+                     )
+      end
+    end
+  end
+
+  def test_add_issue_by_anonymous_user_on_private_project_without_permission_check
+    assert_no_difference 'User.count' do
+      assert_difference 'Issue.count' do
+        issue = submit_email(
+                  'ticket_by_unknown_user.eml',
+                  :issue => {:project => 'onlinestore'},
+                  :no_permission_check => '1',
+                  :unknown_user => 'accept'
+                )
+        assert issue.is_a?(Issue)
+        assert issue.author.anonymous?
+        assert !issue.project.is_public?
+        assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
+      end
+    end
+  end
+
+  def test_add_issue_by_created_user
+    Setting.default_language = 'en'
+    assert_difference 'User.count' do
+      issue = submit_email(
+                'ticket_by_unknown_user.eml',
+                :issue => {:project => 'ecookbook'},
+                :unknown_user => 'create'
+              )
+      assert issue.is_a?(Issue)
+      assert issue.author.active?
+      assert_equal 'john.doe@somenet.foo', issue.author.mail
+      assert_equal 'John', issue.author.firstname
+      assert_equal 'Doe', issue.author.lastname
+
+      # account information
+      email = ActionMailer::Base.deliveries.first
+      assert_not_nil email
+      assert email.subject.include?('account activation')
+      login = mail_body(email).match(/\* Login: (.*)$/)[1].strip
+      password = mail_body(email).match(/\* Password: (.*)$/)[1].strip
+      assert_equal issue.author, User.try_to_login(login, password)
+    end
+  end
+
+  def test_created_user_should_be_added_to_groups
+    group1 = Group.generate!
+    group2 = Group.generate!
+
+    assert_difference 'User.count' do
+      submit_email(
+        'ticket_by_unknown_user.eml',
+        :issue => {:project => 'ecookbook'},
+        :unknown_user => 'create',
+        :default_group => "#{group1.name},#{group2.name}"
+      )
+    end
+    user = User.order('id DESC').first
+    assert_same_elements [group1, group2], user.groups
+  end
+
+  def test_created_user_should_not_receive_account_information_with_no_account_info_option
+    assert_difference 'User.count' do
+      submit_email(
+        'ticket_by_unknown_user.eml',
+        :issue => {:project => 'ecookbook'},
+        :unknown_user => 'create',
+        :no_account_notice => '1'
+      )
+    end
+
+    # only 1 email for the new issue notification
+    assert_equal 1, ActionMailer::Base.deliveries.size
+    email = ActionMailer::Base.deliveries.first
+    assert_include 'Ticket by unknown user', email.subject
+  end
+
+  def test_created_user_should_have_mail_notification_to_none_with_no_notification_option
+    assert_difference 'User.count' do
+      submit_email(
+        'ticket_by_unknown_user.eml',
+        :issue => {:project => 'ecookbook'},
+        :unknown_user => 'create',
+        :no_notification => '1'
+      )
+    end
+    user = User.order('id DESC').first
+    assert_equal 'none', user.mail_notification
+  end
+
+  def test_add_issue_without_from_header
+    Role.anonymous.add_permission!(:add_issues)
+    assert_equal false, submit_email('ticket_without_from_header.eml')
+  end
+
+  def test_add_issue_with_invalid_attributes
+    issue = submit_email(
+              'ticket_with_invalid_attributes.eml',
+              :allow_override => 'tracker,category,priority'
+            )
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_nil issue.assigned_to
+    assert_nil issue.start_date
+    assert_nil issue.due_date
+    assert_equal 0, issue.done_ratio
+    assert_equal 'Normal', issue.priority.to_s
+    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
+  end
+
+  def test_add_issue_with_localized_attributes
+    User.find_by_mail('jsmith@somenet.foo').update_attribute 'language', 'fr'
+    issue = submit_email(
+              'ticket_with_localized_attributes.eml',
+              :allow_override => 'tracker,category,priority'
+            )
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal 'New ticket on a given project', issue.subject
+    assert_equal User.find_by_login('jsmith'), issue.author
+    assert_equal Project.find(2), issue.project
+    assert_equal 'Feature request', issue.tracker.to_s
+    assert_equal 'Stock management', issue.category.to_s
+    assert_equal 'Urgent', issue.priority.to_s
+    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
+  end
+
+  def test_add_issue_with_japanese_keywords
+    ja_dev = "\xe9\x96\x8b\xe7\x99\xba"
+    ja_dev.force_encoding('UTF-8') if ja_dev.respond_to?(:force_encoding)
+    tracker = Tracker.create!(:name => ja_dev)
+    Project.find(1).trackers << tracker
+    issue = submit_email(
+              'japanese_keywords_iso_2022_jp.eml',
+              :issue => {:project => 'ecookbook'},
+              :allow_override => 'tracker'
+            )
+    assert_kind_of Issue, issue
+    assert_equal tracker, issue.tracker
+  end
+
+  def test_add_issue_from_apple_mail
+    issue = submit_email(
+              'apple_mail_with_attachment.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+    assert_kind_of Issue, issue
+    assert_equal 1, issue.attachments.size
+
+    attachment = issue.attachments.first
+    assert_equal 'paella.jpg', attachment.filename
+    assert_equal 10790, attachment.filesize
+    assert File.exist?(attachment.diskfile)
+    assert_equal 10790, File.size(attachment.diskfile)
+    assert_equal 'caaf384198bcbc9563ab5c058acd73cd', attachment.digest
+  end
+
+  def test_thunderbird_with_attachment_ja
+    issue = submit_email(
+              'thunderbird_with_attachment_ja.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+    assert_kind_of Issue, issue
+    assert_equal 1, issue.attachments.size
+    ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"
+    ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
+    attachment = issue.attachments.first
+    assert_equal ja, attachment.filename
+    assert_equal 5, attachment.filesize
+    assert File.exist?(attachment.diskfile)
+    assert_equal 5, File.size(attachment.diskfile)
+    assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
+  end
+
+  def test_gmail_with_attachment_ja
+    issue = submit_email(
+              'gmail_with_attachment_ja.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+    assert_kind_of Issue, issue
+    assert_equal 1, issue.attachments.size
+    ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"
+    ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
+    attachment = issue.attachments.first
+    assert_equal ja, attachment.filename
+    assert_equal 5, attachment.filesize
+    assert File.exist?(attachment.diskfile)
+    assert_equal 5, File.size(attachment.diskfile)
+    assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
+  end
+
+  def test_thunderbird_with_attachment_latin1
+    issue = submit_email(
+              'thunderbird_with_attachment_iso-8859-1.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+    assert_kind_of Issue, issue
+    assert_equal 1, issue.attachments.size
+    u = ""
+    u.force_encoding('UTF-8') if u.respond_to?(:force_encoding)
+    u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc"
+    u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding)
+    11.times { u << u1 }
+    attachment = issue.attachments.first
+    assert_equal "#{u}.png", attachment.filename
+    assert_equal 130, attachment.filesize
+    assert File.exist?(attachment.diskfile)
+    assert_equal 130, File.size(attachment.diskfile)
+    assert_equal '4d80e667ac37dddfe05502530f152abb', attachment.digest
+  end
+
+  def test_gmail_with_attachment_latin1
+    issue = submit_email(
+              'gmail_with_attachment_iso-8859-1.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+    assert_kind_of Issue, issue
+    assert_equal 1, issue.attachments.size
+    u = ""
+    u.force_encoding('UTF-8') if u.respond_to?(:force_encoding)
+    u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc"
+    u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding)
+    11.times { u << u1 }
+    attachment = issue.attachments.first
+    assert_equal "#{u}.txt", attachment.filename
+    assert_equal 5, attachment.filesize
+    assert File.exist?(attachment.diskfile)
+    assert_equal 5, File.size(attachment.diskfile)
+    assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
+  end
+
+  def test_add_issue_with_iso_8859_1_subject
+    issue = submit_email(
+              'subject_as_iso-8859-1.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+    str = "Testmail from Webmail: \xc3\xa4 \xc3\xb6 \xc3\xbc..."
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    assert_kind_of Issue, issue
+    assert_equal str, issue.subject
+  end
+
+  def test_add_issue_with_japanese_subject
+    issue = submit_email(
+              'subject_japanese_1.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+    assert_kind_of Issue, issue
+    ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88"
+    ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
+    assert_equal ja, issue.subject
+  end
+
+  def test_add_issue_with_no_subject_header
+    issue = submit_email(
+              'no_subject_header.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+    assert_kind_of Issue, issue
+    assert_equal '(no subject)', issue.subject
+  end
+
+  def test_add_issue_with_mixed_japanese_subject
+    issue = submit_email(
+              'subject_japanese_2.eml',
+              :issue => {:project => 'ecookbook'}
+            )
+    assert_kind_of Issue, issue
+    ja = "Re: \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88"
+    ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
+    assert_equal ja, issue.subject
+  end
+
+  def test_should_ignore_emails_from_locked_users
+    User.find(2).lock!
+
+    MailHandler.any_instance.expects(:dispatch).never
+    assert_no_difference 'Issue.count' do
+      assert_equal false, submit_email('ticket_on_given_project.eml')
+    end
+  end
+
+  def test_should_ignore_emails_from_emission_address
+    Role.anonymous.add_permission!(:add_issues)
+    assert_no_difference 'User.count' do
+      assert_equal false,
+                   submit_email(
+                     'ticket_from_emission_address.eml',
+                     :issue => {:project => 'ecookbook'},
+                     :unknown_user => 'create'
+                   )
+    end
+  end
+
+  def test_should_ignore_auto_replied_emails
+    MailHandler.any_instance.expects(:dispatch).never
+    [
+      "X-Auto-Response-Suppress: OOF",
+      "Auto-Submitted: auto-replied",
+      "Auto-Submitted: Auto-Replied",
+      "Auto-Submitted: auto-generated"
+    ].each do |header|
+      raw = IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
+      raw = header + "\n" + raw
+
+      assert_no_difference 'Issue.count' do
+        assert_equal false, MailHandler.receive(raw), "email with #{header} header was not ignored"
+      end
+    end
+  end
+
+  def test_add_issue_should_send_email_notification
+    Setting.notified_events = ['issue_added']
+    ActionMailer::Base.deliveries.clear
+    # This email contains: 'Project: onlinestore'
+    issue = submit_email('ticket_on_given_project.eml')
+    assert issue.is_a?(Issue)
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_update_issue
+    journal = submit_email('ticket_reply.eml')
+    assert journal.is_a?(Journal)
+    assert_equal User.find_by_login('jsmith'), journal.user
+    assert_equal Issue.find(2), journal.journalized
+    assert_match /This is reply/, journal.notes
+    assert_equal false, journal.private_notes
+    assert_equal 'Feature request', journal.issue.tracker.name
+  end
+
+  def test_update_issue_with_attribute_changes
+    # This email contains: 'Status: Resolved'
+    journal = submit_email('ticket_reply_with_status.eml')
+    assert journal.is_a?(Journal)
+    issue = Issue.find(journal.issue.id)
+    assert_equal User.find_by_login('jsmith'), journal.user
+    assert_equal Issue.find(2), journal.journalized
+    assert_match /This is reply/, journal.notes
+    assert_equal 'Feature request', journal.issue.tracker.name
+    assert_equal IssueStatus.find_by_name("Resolved"), issue.status
+    assert_equal '2010-01-01', issue.start_date.to_s
+    assert_equal '2010-12-31', issue.due_date.to_s
+    assert_equal User.find_by_login('jsmith'), issue.assigned_to
+    assert_equal "52.6", issue.custom_value_for(CustomField.find_by_name('Float field')).value
+    # keywords should be removed from the email body
+    assert !journal.notes.match(/^Status:/i)
+    assert !journal.notes.match(/^Start Date:/i)
+  end
+
+  def test_update_issue_with_attachment
+    assert_difference 'Journal.count' do
+      assert_difference 'JournalDetail.count' do
+        assert_difference 'Attachment.count' do
+          assert_no_difference 'Issue.count' do
+            journal = submit_email('ticket_with_attachment.eml') do |raw|
+              raw.gsub! /^Subject: .*$/, 'Subject: Re: [Cookbook - Feature #2] (New) Add ingredients categories'
+            end
+          end
+        end
+      end
+    end
+    journal = Journal.first(:order => 'id DESC')
+    assert_equal Issue.find(2), journal.journalized
+    assert_equal 1, journal.details.size
+
+    detail = journal.details.first
+    assert_equal 'attachment', detail.property
+    assert_equal 'Paella.jpg', detail.value
+  end
+
+  def test_update_issue_should_send_email_notification
+    ActionMailer::Base.deliveries.clear
+    journal = submit_email('ticket_reply.eml')
+    assert journal.is_a?(Journal)
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_update_issue_should_not_set_defaults
+    journal = submit_email(
+                'ticket_reply.eml',
+                :issue => {:tracker => 'Support request', :priority => 'High'}
+              )
+    assert journal.is_a?(Journal)
+    assert_match /This is reply/, journal.notes
+    assert_equal 'Feature request', journal.issue.tracker.name
+    assert_equal 'Normal', journal.issue.priority.name
+  end
+
+  def test_replying_to_a_private_note_should_add_reply_as_private
+    private_journal = Journal.create!(:notes => 'Private notes', :journalized => Issue.find(1), :private_notes => true, :user_id => 2)
+
+    assert_difference 'Journal.count' do
+      journal = submit_email('ticket_reply.eml') do |email|
+        email.sub! %r{^In-Reply-To:.*$}, "In-Reply-To: <redmine.journal-#{private_journal.id}.20060719210421@osiris>"
+      end
+
+      assert_kind_of Journal, journal
+      assert_match /This is reply/, journal.notes
+      assert_equal true, journal.private_notes
+    end
+  end
+
+  def test_reply_to_a_message
+    m = submit_email('message_reply.eml')
+    assert m.is_a?(Message)
+    assert !m.new_record?
+    m.reload
+    assert_equal 'Reply via email', m.subject
+    # The email replies to message #2 which is part of the thread of message #1
+    assert_equal Message.find(1), m.parent
+  end
+
+  def test_reply_to_a_message_by_subject
+    m = submit_email('message_reply_by_subject.eml')
+    assert m.is_a?(Message)
+    assert !m.new_record?
+    m.reload
+    assert_equal 'Reply to the first post', m.subject
+    assert_equal Message.find(1), m.parent
+  end
+
+  def test_should_strip_tags_of_html_only_emails
+    issue = submit_email('ticket_html_only.eml', :issue => {:project => 'ecookbook'})
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+    assert_equal 'HTML email', issue.subject
+    assert_equal 'This is a html-only email.', issue.description
+  end
+
+  test "truncate emails with no setting should add the entire email into the issue" do
+    with_settings :mail_handler_body_delimiters => '' do
+      issue = submit_email('ticket_on_given_project.eml')
+      assert_issue_created(issue)
+      assert issue.description.include?('---')
+      assert issue.description.include?('This paragraph is after the delimiter')
+    end
+  end
+
+  test "truncate emails with a single string should truncate the email at the delimiter for the issue" do
+    with_settings :mail_handler_body_delimiters => '---' do
+      issue = submit_email('ticket_on_given_project.eml')
+      assert_issue_created(issue)
+      assert issue.description.include?('This paragraph is before delimiters')
+      assert issue.description.include?('--- This line starts with a delimiter')
+      assert !issue.description.match(/^---$/)
+      assert !issue.description.include?('This paragraph is after the delimiter')
+    end
+  end
+
+  test "truncate emails with a single quoted reply should truncate the email at the delimiter with the quoted reply symbols (>)" do
+    with_settings :mail_handler_body_delimiters => '--- Reply above. Do not remove this line. ---' do
+      journal = submit_email('issue_update_with_quoted_reply_above.eml')
+      assert journal.is_a?(Journal)
+      assert journal.notes.include?('An update to the issue by the sender.')
+      assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
+      assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
+    end
+  end
+
+  test "truncate emails with multiple quoted replies should truncate the email at the delimiter with the quoted reply symbols (>)" do
+    with_settings :mail_handler_body_delimiters => '--- Reply above. Do not remove this line. ---' do
+      journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml')
+      assert journal.is_a?(Journal)
+      assert journal.notes.include?('An update to the issue by the sender.')
+      assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
+      assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
+    end
+  end
+
+  test "truncate emails with multiple strings should truncate the email at the first delimiter found (BREAK)" do
+    with_settings :mail_handler_body_delimiters => "---\nBREAK" do
+      issue = submit_email('ticket_on_given_project.eml')
+      assert_issue_created(issue)
+      assert issue.description.include?('This paragraph is before delimiters')
+      assert !issue.description.include?('BREAK')
+      assert !issue.description.include?('This paragraph is between delimiters')
+      assert !issue.description.match(/^---$/)
+      assert !issue.description.include?('This paragraph is after the delimiter')
+    end
+  end
+
+  def test_email_with_long_subject_line
+    issue = submit_email('ticket_with_long_subject.eml')
+    assert issue.is_a?(Issue)
+    assert_equal issue.subject, 'New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...'[0,255]
+  end
+
+  def test_new_user_from_attributes_should_return_valid_user
+    to_test = {
+      # [address, name] => [login, firstname, lastname]
+      ['jsmith@example.net', nil] => ['jsmith@example.net', 'jsmith', '-'],
+      ['jsmith@example.net', 'John'] => ['jsmith@example.net', 'John', '-'],
+      ['jsmith@example.net', 'John Smith'] => ['jsmith@example.net', 'John', 'Smith'],
+      ['jsmith@example.net', 'John Paul Smith'] => ['jsmith@example.net', 'John', 'Paul Smith'],
+      ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsTheMaximumLength Smith'] => ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsT', 'Smith'],
+      ['jsmith@example.net', 'John AVeryLongLastnameThatExceedsTheMaximumLength'] => ['jsmith@example.net', 'John', 'AVeryLongLastnameThatExceedsTh']
+    }
+
+    to_test.each do |attrs, expected|
+      user = MailHandler.new_user_from_attributes(attrs.first, attrs.last)
+
+      assert user.valid?, user.errors.full_messages.to_s
+      assert_equal attrs.first, user.mail
+      assert_equal expected[0], user.login
+      assert_equal expected[1], user.firstname
+      assert_equal expected[2], user.lastname
+      assert_equal 'only_my_events', user.mail_notification
+    end
+  end
+
+  def test_new_user_from_attributes_should_respect_minimum_password_length
+    with_settings :password_min_length => 15 do
+      user = MailHandler.new_user_from_attributes('jsmith@example.net')
+      assert user.valid?
+      assert user.password.length >= 15
+    end
+  end
+
+  def test_new_user_from_attributes_should_use_default_login_if_invalid
+    user = MailHandler.new_user_from_attributes('foo+bar@example.net')
+    assert user.valid?
+    assert user.login =~ /^user[a-f0-9]+$/
+    assert_equal 'foo+bar@example.net', user.mail
+  end
+
+  def test_new_user_with_utf8_encoded_fullname_should_be_decoded
+    assert_difference 'User.count' do
+      issue = submit_email(
+                'fullname_of_sender_as_utf8_encoded.eml',
+                :issue => {:project => 'ecookbook'},
+                :unknown_user => 'create'
+              )
+    end
+
+    user = User.first(:order => 'id DESC')
+    assert_equal "foo@example.org", user.mail
+    str1 = "\xc3\x84\xc3\xa4"
+    str2 = "\xc3\x96\xc3\xb6"
+    str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding)
+    str2.force_encoding('UTF-8') if str2.respond_to?(:force_encoding)
+    assert_equal str1, user.firstname
+    assert_equal str2, user.lastname
+  end
+
+  private
+
+  def submit_email(filename, options={})
+    raw = IO.read(File.join(FIXTURES_PATH, filename))
+    yield raw if block_given?
+    MailHandler.receive(raw, options)
+  end
+
+  def assert_issue_created(issue)
+    assert issue.is_a?(Issue)
+    assert !issue.new_record?
+    issue.reload
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/02/02c8aed5827fd37b4953522a150e77160bca0811.svn-base
--- a/.svn/pristine/02/02c8aed5827fd37b4953522a150e77160bca0811.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
---- 
-issue_categories_001: 
-  name: Printing
-  project_id: 1
-  assigned_to_id: 2
-  id: 1
-issue_categories_002: 
-  name: Recipes
-  project_id: 1
-  assigned_to_id: 
-  id: 2
-issue_categories_003: 
-  name: Stock management
-  project_id: 2
-  assigned_to_id: 
-  id: 3
-issue_categories_004: 
-  name: Printing
-  project_id: 2
-  assigned_to_id: 
-  id: 4
-  
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/02/02dadac204e591b101d6e3bacd9c59cdeb84b1b6.svn-base
--- a/.svn/pristine/02/02dadac204e591b101d6e3bacd9c59cdeb84b1b6.svn-base
+++ /dev/null
@@ -1,33 +0,0 @@
-<ul>
-  <% if !@time_entry.nil? -%>
-    <li><%= context_menu_link l(:button_edit), {:controller => 'timelog', :action => 'edit', :id => @time_entry},
-            :class => 'icon-edit', :disabled => !@can[:edit] %></li>
-  <% else %>
-    <li><%= context_menu_link l(:button_edit), {:controller => 'timelog', :action => 'bulk_edit', :ids => @time_entries.collect(&:id)},
-            :class => 'icon-edit', :disabled => !@can[:edit] %></li>
-  <% end %>
-
-  <%= call_hook(:view_time_entries_context_menu_start, {:time_entries => @time_entries, :can => @can, :back => @back }) %>
-
-  <% if @activities.present? -%>
-  <li class="folder">
-    <a href="#" class="submenu"><%= l(:field_activity) %></a>
-    <ul>
-    <% @activities.each do |u| -%>
-        <li><%= context_menu_link h(u.name), {:controller => 'timelog', :action => 'bulk_edit', :ids => @time_entries.collect(&:id), :time_entry => {'activity_id' => u}, :back_url => @back}, :method => :post,
-                                  :selected => (@time_entry && u == @time_entry.activity), :disabled => !@can[:edit] %></li>
-    <% end -%>
-        <li><%= context_menu_link l(:label_none), {:controller => 'timelog', :action => 'bulk_edit', :ids => @time_entries.collect(&:id), :time_entry => {'activity_id' => 'none'}, :back_url => @back}, :method => :post,
-                                  :selected => (@time_entry && @time_entry.activity.nil?), :disabled => !@can[:edit] %></li>
-    </ul>
-  </li>
-  <% end %>
-
-  <%= call_hook(:view_time_entries_context_menu_end, {:time_entries => @time_entries, :can => @can, :back => @back }) %>
-
-  <li>
-    <%= context_menu_link l(:button_delete),
-      {:controller => 'timelog', :action => 'destroy', :ids => @time_entries.collect(&:id), :back_url => @back},
-      :method => :delete, :confirm => l(:text_time_entries_destroy_confirmation), :class => 'icon-del', :disabled => !@can[:delete] %>
-  </li>
-</ul>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/02/02fe391dd14e50d29ad45f8bf8dea30be02556c5.svn-base
--- /dev/null
+++ b/.svn/pristine/02/02fe391dd14e50d29ad45f8bf8dea30be02556c5.svn-base
@@ -0,0 +1,127 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Themes
+
+    # Return an array of installed themes
+    def self.themes
+      @@installed_themes ||= scan_themes
+    end
+
+    # Rescan themes directory
+    def self.rescan
+      @@installed_themes = scan_themes
+    end
+
+    # Return theme for given id, or nil if it's not found
+    def self.theme(id, options={})
+      return nil if id.blank?
+
+      found = themes.find {|t| t.id == id}
+      if found.nil? && options[:rescan] != false
+        rescan
+        found = theme(id, :rescan => false)
+      end
+      found
+    end
+
+    # Class used to represent a theme
+    class Theme
+      attr_reader :path, :name, :dir
+
+      def initialize(path)
+        @path = path
+        @dir = File.basename(path)
+        @name = @dir.humanize
+        @stylesheets = nil
+        @javascripts = nil
+      end
+
+      # Directory name used as the theme id
+      def id; dir end
+
+      def ==(theme)
+        theme.is_a?(Theme) && theme.dir == dir
+      end
+
+      def <=>(theme)
+        name <=> theme.name
+      end
+
+      def stylesheets
+        @stylesheets ||= assets("stylesheets", "css")
+      end
+
+      def images
+        @images ||= assets("images")
+      end
+
+      def javascripts
+        @javascripts ||= assets("javascripts", "js")
+      end
+
+      def stylesheet_path(source)
+        "/themes/#{dir}/stylesheets/#{source}"
+      end
+
+      def image_path(source)
+        "/themes/#{dir}/images/#{source}"
+      end
+
+      def javascript_path(source)
+        "/themes/#{dir}/javascripts/#{source}"
+      end
+
+      private
+
+      def assets(dir, ext=nil)
+        if ext
+          Dir.glob("#{path}/#{dir}/*.#{ext}").collect {|f| File.basename(f).gsub(/\.#{ext}$/, '')}
+        else
+          Dir.glob("#{path}/#{dir}/*").collect {|f| File.basename(f)}
+        end
+      end
+    end
+
+    private
+
+    def self.scan_themes
+      dirs = Dir.glob("#{Rails.public_path}/themes/*").select do |f|
+        # A theme should at least override application.css
+        File.directory?(f) && File.exist?("#{f}/stylesheets/application.css")
+      end
+      dirs.collect {|dir| Theme.new(dir)}.sort
+    end
+  end
+end
+
+module ApplicationHelper
+  def current_theme
+    unless instance_variable_defined?(:@current_theme)
+      @current_theme = Redmine::Themes.theme(Setting.ui_theme)
+    end
+    @current_theme
+  end
+
+  # Returns the header tags for the current theme
+  def heads_for_theme
+    if current_theme && current_theme.javascripts.include?('theme')
+      javascript_include_tag current_theme.javascript_path('theme')
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/03/032e9aa73399010aaf3eb408ecd8fb8f296696b1.svn-base
--- a/.svn/pristine/03/032e9aa73399010aaf3eb408ecd8fb8f296696b1.svn-base
+++ /dev/null
@@ -1,80 +0,0 @@
-<div class="contextual">
-  <% if User.current.allowed_to?(:add_subprojects, @project) %>
-    <%= link_to l(:label_subproject_new), {:controller => 'projects', :action => 'new', :parent_id => @project}, :class => 'icon icon-add' %>
-  <% end %>
-</div>
-
-<h2><%=l(:label_overview)%></h2>
-
-<div class="splitcontentleft">
-  <div class="wiki">
-    <%= textilizable @project.description %>
-  </div>
-  <ul>
-  <% unless @project.homepage.blank? %><li><%=l(:field_homepage)%>: <%= auto_link(h(@project.homepage)) %></li><% end %>
-  <% if @subprojects.any? %>
-   <li><%=l(:label_subproject_plural)%>:
-      <%= @subprojects.collect{|p| link_to(h(p), :action => 'show', :id => p)}.join(", ").html_safe %></li>
-  <% end %>
-  <% @project.visible_custom_field_values.each do |custom_value| %>
-  <% if !custom_value.value.blank? %>
-     <li><%=h custom_value.custom_field.name %>: <%=h show_value(custom_value) %></li>
-  <% end %>
-  <% end %>
-  </ul>
-
-  <% if User.current.allowed_to?(:view_issues, @project) %>
-  <div class="issues box">
-    <h3><%=l(:label_issue_tracking)%></h3>
-    <ul>
-    <% for tracker in @trackers %>
-      <li><%= link_to h(tracker.name), :controller => 'issues', :action => 'index', :project_id => @project,
-                                                :set_filter => 1,
-                                                "tracker_id" => tracker.id %>:
-          <%= l(:label_x_open_issues_abbr_on_total, :count => @open_issues_by_tracker[tracker].to_i,
-                                                    :total => @total_issues_by_tracker[tracker].to_i) %>
-      </li>
-    <% end %>
-    </ul>
-    <p>
-      <%= link_to l(:label_issue_view_all), :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1 %>
-      <% if User.current.allowed_to?(:view_calendar, @project, :global => true) %>
-        | <%= link_to(l(:label_calendar), :controller => 'calendars', :action => 'show', :project_id => @project) %>
-      <% end %>
-      <% if User.current.allowed_to?(:view_gantt, @project, :global => true) %>
-        | <%= link_to(l(:label_gantt), :controller => 'gantts', :action => 'show', :project_id => @project) %>
-      <% end %>
-    </p>
-  </div>
-  <% end %>
-  <%= call_hook(:view_projects_show_left, :project => @project) %>
-</div>
-
-<div class="splitcontentright">
-  <%= render :partial => 'members_box' %>
-
-  <% if @news.any? && authorize_for('news', 'index') %>
-  <div class="news box">
-    <h3><%=l(:label_news_latest)%></h3>
-    <%= render :partial => 'news/news', :collection => @news %>
-    <p><%= link_to l(:label_news_view_all), :controller => 'news', :action => 'index', :project_id => @project %></p>
-  </div>
-  <% end %>
-  <%= call_hook(:view_projects_show_right, :project => @project) %>
-</div>
-
-<% content_for :sidebar do %>
-    <% if @total_hours.present? %>
-    <h3><%= l(:label_spent_time) %></h3>
-    <p><span class="icon icon-time"><%= l_hours(@total_hours) %></span></p>
-    <p><%= link_to(l(:label_details), {:controller => 'timelog', :action => 'index', :project_id => @project}) %> |
-    <%= link_to(l(:label_report), {:controller => 'time_entry_reports', :action => 'report', :project_id => @project}) %></p>
-    <% end %>
-    <%= call_hook(:view_projects_show_sidebar_bottom, :project => @project) %>
-<% end %>
-
-<% content_for :header_tags do %>
-<%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :id => @project, :format => 'atom', :key => User.current.rss_key}) %>
-<% end %>
-
-<% html_title(l(:label_overview)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/03/03389ce7c25a023f73b895dc03af8c3f1ee755e9.svn-base
--- a/.svn/pristine/03/03389ce7c25a023f73b895dc03af8c3f1ee755e9.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-<h2><%=l(:label_document)%></h2>
-
-<% form_tag({:action => 'edit', :id => @document}, :class => "tabular") do %>
-  <%= render :partial => 'form' %>
-  <%= submit_tag l(:button_save) %>
-<% end %>
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/03/033d1080f94d03c5b655f6847c2f7606bd5d5f60.svn-base
--- /dev/null
+++ b/.svn/pristine/03/033d1080f94d03c5b655f6847c2f7606bd5d5f60.svn-base
@@ -0,0 +1,54 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module UsersHelper
+  def users_status_options_for_select(selected)
+    user_count_by_status = User.count(:group => 'status').to_hash
+    options_for_select([[l(:label_all), ''],
+                        ["#{l(:status_active)} (#{user_count_by_status[1].to_i})", '1'],
+                        ["#{l(:status_registered)} (#{user_count_by_status[2].to_i})", '2'],
+                        ["#{l(:status_locked)} (#{user_count_by_status[3].to_i})", '3']], selected.to_s)
+  end
+
+  def user_mail_notification_options(user)
+    user.valid_notification_options.collect {|o| [l(o.last), o.first]}
+  end
+
+  def change_status_link(user)
+    url = {:controller => 'users', :action => 'update', :id => user, :page => params[:page], :status => params[:status], :tab => nil}
+
+    if user.locked?
+      link_to l(:button_unlock), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'icon icon-unlock'
+    elsif user.registered?
+      link_to l(:button_activate), url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'icon icon-unlock'
+    elsif user != User.current
+      link_to l(:button_lock), url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :put, :class => 'icon icon-lock'
+    end
+  end
+
+  def user_settings_tabs
+    tabs = [{:name => 'general', :partial => 'users/general', :label => :label_general},
+            {:name => 'memberships', :partial => 'users/memberships', :label => :label_project_plural}
+            ]
+    if Group.all.any?
+      tabs.insert 1, {:name => 'groups', :partial => 'users/groups', :label => :label_group_plural}
+    end
+    tabs
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/03/033e041df5add14807dd8e40c1a8ef8894cdf897.svn-base
--- a/.svn/pristine/03/033e041df5add14807dd8e40c1a8ef8894cdf897.svn-base
+++ /dev/null
@@ -1,18 +0,0 @@
-Return-Path: <john.doe@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
-Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
-From: "John Doe" <john.doe@somenet.foo>
-To: <redmine@somenet.foo>
-Subject: Ticket by unknown user
-Date: Sun, 22 Jun 2008 12:28:07 +0200
-MIME-Version: 1.0
-Content-Type: text/plain;
-	format=flowed;
-	charset="iso-8859-1";
-	reply-type=original
-Content-Transfer-Encoding: 7bit
-
-This is a ticket submitted by an unknown user.
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/03/0367c769a1dec5c6ffea095893b82d493a02e68a.svn-base
--- a/.svn/pristine/03/0367c769a1dec5c6ffea095893b82d493a02e68a.svn-base
+++ /dev/null
@@ -1,93 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/subversion_adapter'
-
-class Repository::Subversion < Repository
-  attr_protected :root_url
-  validates_presence_of :url
-  validates_format_of :url, :with => /^(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
-
-  def self.scm_adapter_class
-    Redmine::Scm::Adapters::SubversionAdapter
-  end
-
-  def self.scm_name
-    'Subversion'
-  end
-
-  def supports_directory_revisions?
-    true
-  end
-
-  def repo_log_encoding
-    'UTF-8'
-  end
-
-  def latest_changesets(path, rev, limit=10)
-    revisions = scm.revisions(path, rev, nil, :limit => limit)
-    revisions ? changesets.find_all_by_revision(revisions.collect(&:identifier), :order => "committed_on DESC", :include => :user) : []
-  end
-
-  # Returns a path relative to the url of the repository
-  def relative_path(path)
-    path.gsub(Regexp.new("^\/?#{Regexp.escape(relative_url)}"), '')
-  end
-
-  def fetch_changesets
-    scm_info = scm.info
-    if scm_info
-      # latest revision found in database
-      db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
-      # latest revision in the repository
-      scm_revision = scm_info.lastrev.identifier.to_i
-      if db_revision < scm_revision
-        logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
-        identifier_from = db_revision + 1
-        while (identifier_from <= scm_revision)
-          # loads changesets by batches of 200
-          identifier_to = [identifier_from + 199, scm_revision].min
-          revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
-          revisions.reverse_each do |revision|
-            transaction do
-              changeset = Changeset.create(:repository   => self,
-                                           :revision     => revision.identifier,
-                                           :committer    => revision.author,
-                                           :committed_on => revision.time,
-                                           :comments     => revision.message)
-
-              revision.paths.each do |change|
-                changeset.create_change(change)
-              end unless changeset.new_record?
-            end
-          end unless revisions.nil?
-          identifier_from = identifier_to + 1
-        end
-      end
-    end
-  end
-
-  private
-
-  # Returns the relative url of the repository
-  # Eg: root_url = file:///var/svn/foo
-  #     url      = file:///var/svn/foo/bar
-  #     => returns /bar
-  def relative_url
-    @relative_url ||= url.gsub(Regexp.new("^#{Regexp.escape(root_url || scm.root_url)}", Regexp::IGNORECASE), '')
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/03/03b7cab2c78e7db2be70be489d305cf0f31baf79.svn-base
--- a/.svn/pristine/03/03b7cab2c78e7db2be70be489d305cf0f31baf79.svn-base
+++ /dev/null
@@ -1,68 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Tracker < ActiveRecord::Base
-  before_destroy :check_integrity
-  has_many :issues
-  has_many :workflows, :dependent => :delete_all do
-    def copy(source_tracker)
-      Workflow.copy(source_tracker, nil, proxy_owner, nil)
-    end
-  end
-
-  has_and_belongs_to_many :projects
-  has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :association_foreign_key => 'custom_field_id'
-  acts_as_list
-
-  validates_presence_of :name
-  validates_uniqueness_of :name
-  validates_length_of :name, :maximum => 30
-
-  named_scope :named, lambda {|arg| { :conditions => ["LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip]}}
-
-  def to_s; name end
-
-  def <=>(tracker)
-    name <=> tracker.name
-  end
-
-  def self.all
-    find(:all, :order => 'position')
-  end
-
-  # Returns an array of IssueStatus that are used
-  # in the tracker's workflows
-  def issue_statuses
-    if @issue_statuses
-      return @issue_statuses
-    elsif new_record?
-      return []
-    end
-
-    ids = Workflow.
-            connection.select_rows("SELECT DISTINCT old_status_id, new_status_id FROM #{Workflow.table_name} WHERE tracker_id = #{id}").
-            flatten.
-            uniq
-
-    @issue_statuses = IssueStatus.find_all_by_id(ids).sort
-  end
-
-private
-  def check_integrity
-    raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/03/03b977fa002b4a1e6202e05fed1b5c5f4bee2ed3.svn-base
--- /dev/null
+++ b/.svn/pristine/03/03b977fa002b4a1e6202e05fed1b5c5f4bee2ed3.svn-base
@@ -0,0 +1,1029 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Project < ActiveRecord::Base
+  include Redmine::SafeAttributes
+
+  # Project statuses
+  STATUS_ACTIVE     = 1
+  STATUS_CLOSED     = 5
+  STATUS_ARCHIVED   = 9
+
+  # Maximum length for project identifiers
+  IDENTIFIER_MAX_LENGTH = 100
+
+  # Specific overidden Activities
+  has_many :time_entry_activities
+  has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}"
+  has_many :memberships, :class_name => 'Member'
+  has_many :member_principals, :class_name => 'Member',
+                               :include => :principal,
+                               :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE})"
+  has_many :users, :through => :members
+  has_many :principals, :through => :member_principals, :source => :principal
+
+  has_many :enabled_modules, :dependent => :delete_all
+  has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
+  has_many :issues, :dependent => :destroy, :include => [:status, :tracker]
+  has_many :issue_changes, :through => :issues, :source => :journals
+  has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC"
+  has_many :time_entries, :dependent => :delete_all
+  has_many :queries, :class_name => 'IssueQuery', :dependent => :delete_all
+  has_many :documents, :dependent => :destroy
+  has_many :news, :dependent => :destroy, :include => :author
+  has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name"
+  has_many :boards, :dependent => :destroy, :order => "position ASC"
+  has_one :repository, :conditions => ["is_default = ?", true]
+  has_many :repositories, :dependent => :destroy
+  has_many :changesets, :through => :repository
+  has_one :wiki, :dependent => :destroy
+  # Custom field for the project issues
+  has_and_belongs_to_many :issue_custom_fields,
+                          :class_name => 'IssueCustomField',
+                          :order => "#{CustomField.table_name}.position",
+                          :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
+                          :association_foreign_key => 'custom_field_id'
+
+  acts_as_nested_set :order => 'name', :dependent => :destroy
+  acts_as_attachable :view_permission => :view_files,
+                     :delete_permission => :manage_files
+
+  acts_as_customizable
+  acts_as_searchable :columns => ['name', 'identifier', 'description'], :project_key => 'id', :permission => nil
+  acts_as_event :title => Proc.new {|o| "#{l(:label_project)}: #{o.name}"},
+                :url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o}},
+                :author => nil
+
+  attr_protected :status
+
+  validates_presence_of :name, :identifier
+  validates_uniqueness_of :identifier
+  validates_associated :repository, :wiki
+  validates_length_of :name, :maximum => 255
+  validates_length_of :homepage, :maximum => 255
+  validates_length_of :identifier, :in => 1..IDENTIFIER_MAX_LENGTH
+  # donwcase letters, digits, dashes but not digits only
+  validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? }
+  # reserved words
+  validates_exclusion_of :identifier, :in => %w( new )
+
+  after_save :update_position_under_parent, :if => Proc.new {|project| project.name_changed?}
+  after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?}
+  before_destroy :delete_all_members
+
+  scope :has_module, lambda {|mod|
+    where("#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s)
+  }
+  scope :active, lambda { where(:status => STATUS_ACTIVE) }
+  scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) }
+  scope :all_public, lambda { where(:is_public => true) }
+  scope :visible, lambda {|*args| where(Project.visible_condition(args.shift || User.current, *args)) }
+  scope :allowed_to, lambda {|*args| 
+    user = User.current
+    permission = nil
+    if args.first.is_a?(Symbol)
+      permission = args.shift
+    else
+      user = args.shift
+      permission = args.shift
+    end
+    where(Project.allowed_to_condition(user, permission, *args))
+  }
+  scope :like, lambda {|arg|
+    if arg.blank?
+      where(nil)
+    else
+      pattern = "%#{arg.to_s.strip.downcase}%"
+      where("LOWER(identifier) LIKE :p OR LOWER(name) LIKE :p", :p => pattern)
+    end
+  }
+
+  def initialize(attributes=nil, *args)
+    super
+
+    initialized = (attributes || {}).stringify_keys
+    if !initialized.key?('identifier') && Setting.sequential_project_identifiers?
+      self.identifier = Project.next_identifier
+    end
+    if !initialized.key?('is_public')
+      self.is_public = Setting.default_projects_public?
+    end
+    if !initialized.key?('enabled_module_names')
+      self.enabled_module_names = Setting.default_projects_modules
+    end
+    if !initialized.key?('trackers') && !initialized.key?('tracker_ids')
+      default = Setting.default_projects_tracker_ids
+      if default.is_a?(Array)
+        self.trackers = Tracker.where(:id => default.map(&:to_i)).sorted.all
+      else
+        self.trackers = Tracker.sorted.all
+      end
+    end
+  end
+
+  def identifier=(identifier)
+    super unless identifier_frozen?
+  end
+
+  def identifier_frozen?
+    errors[:identifier].blank? && !(new_record? || identifier.blank?)
+  end
+
+  # returns latest created projects
+  # non public projects will be returned only if user is a member of those
+  def self.latest(user=nil, count=5)
+    visible(user).limit(count).order("created_on DESC").all
+  end
+
+  # Returns true if the project is visible to +user+ or to the current user.
+  def visible?(user=User.current)
+    user.allowed_to?(:view_project, self)
+  end
+
+  # Returns a SQL conditions string used to find all projects visible by the specified user.
+  #
+  # Examples:
+  #   Project.visible_condition(admin)        => "projects.status = 1"
+  #   Project.visible_condition(normal_user)  => "((projects.status = 1) AND (projects.is_public = 1 OR projects.id IN (1,3,4)))"
+  #   Project.visible_condition(anonymous)    => "((projects.status = 1) AND (projects.is_public = 1))"
+  def self.visible_condition(user, options={})
+    allowed_to_condition(user, :view_project, options)
+  end
+
+  # Returns a SQL conditions string used to find all projects for which +user+ has the given +permission+
+  #
+  # Valid options:
+  # * :project => limit the condition to project
+  # * :with_subprojects => limit the condition to project and its subprojects
+  # * :member => limit the condition to the user projects
+  def self.allowed_to_condition(user, permission, options={})
+    perm = Redmine::AccessControl.permission(permission)
+    base_statement = (perm && perm.read? ? "#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED}" : "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}")
+    if perm && perm.project_module
+      # If the permission belongs to a project module, make sure the module is enabled
+      base_statement << " AND #{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.project_module}')"
+    end
+    if options[:project]
+      project_statement = "#{Project.table_name}.id = #{options[:project].id}"
+      project_statement << " OR (#{Project.table_name}.lft > #{options[:project].lft} AND #{Project.table_name}.rgt < #{options[:project].rgt})" if options[:with_subprojects]
+      base_statement = "(#{project_statement}) AND (#{base_statement})"
+    end
+
+    if user.admin?
+      base_statement
+    else
+      statement_by_role = {}
+      unless options[:member]
+        role = user.logged? ? Role.non_member : Role.anonymous
+        if role.allowed_to?(permission)
+          statement_by_role[role] = "#{Project.table_name}.is_public = #{connection.quoted_true}"
+        end
+      end
+      if user.logged?
+        user.projects_by_role.each do |role, projects|
+          if role.allowed_to?(permission) && projects.any?
+            statement_by_role[role] = "#{Project.table_name}.id IN (#{projects.collect(&:id).join(',')})"
+          end
+        end
+      end
+      if statement_by_role.empty?
+        "1=0"
+      else
+        if block_given?
+          statement_by_role.each do |role, statement|
+            if s = yield(role, user)
+              statement_by_role[role] = "(#{statement} AND (#{s}))"
+            end
+          end
+        end
+        "((#{base_statement}) AND (#{statement_by_role.values.join(' OR ')}))"
+      end
+    end
+  end
+
+  # Returns the Systemwide and project specific activities
+  def activities(include_inactive=false)
+    if include_inactive
+      return all_activities
+    else
+      return active_activities
+    end
+  end
+
+  # Will create a new Project specific Activity or update an existing one
+  #
+  # This will raise a ActiveRecord::Rollback if the TimeEntryActivity
+  # does not successfully save.
+  def update_or_create_time_entry_activity(id, activity_hash)
+    if activity_hash.respond_to?(:has_key?) && activity_hash.has_key?('parent_id')
+      self.create_time_entry_activity_if_needed(activity_hash)
+    else
+      activity = project.time_entry_activities.find_by_id(id.to_i)
+      activity.update_attributes(activity_hash) if activity
+    end
+  end
+
+  # Create a new TimeEntryActivity if it overrides a system TimeEntryActivity
+  #
+  # This will raise a ActiveRecord::Rollback if the TimeEntryActivity
+  # does not successfully save.
+  def create_time_entry_activity_if_needed(activity)
+    if activity['parent_id']
+
+      parent_activity = TimeEntryActivity.find(activity['parent_id'])
+      activity['name'] = parent_activity.name
+      activity['position'] = parent_activity.position
+
+      if Enumeration.overridding_change?(activity, parent_activity)
+        project_activity = self.time_entry_activities.create(activity)
+
+        if project_activity.new_record?
+          raise ActiveRecord::Rollback, "Overridding TimeEntryActivity was not successfully saved"
+        else
+          self.time_entries.update_all("activity_id = #{project_activity.id}", ["activity_id = ?", parent_activity.id])
+        end
+      end
+    end
+  end
+
+  # Returns a :conditions SQL string that can be used to find the issues associated with this project.
+  #
+  # Examples:
+  #   project.project_condition(true)  => "(projects.id = 1 OR (projects.lft > 1 AND projects.rgt < 10))"
+  #   project.project_condition(false) => "projects.id = 1"
+  def project_condition(with_subprojects)
+    cond = "#{Project.table_name}.id = #{id}"
+    cond = "(#{cond} OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt}))" if with_subprojects
+    cond
+  end
+
+  def self.find(*args)
+    if args.first && args.first.is_a?(String) && !args.first.match(/^\d*$/)
+      project = find_by_identifier(*args)
+      raise ActiveRecord::RecordNotFound, "Couldn't find Project with identifier=#{args.first}" if project.nil?
+      project
+    else
+      super
+    end
+  end
+
+  def self.find_by_param(*args)
+    self.find(*args)
+  end
+
+  alias :base_reload :reload
+  def reload(*args)
+    @shared_versions = nil
+    @rolled_up_versions = nil
+    @rolled_up_trackers = nil
+    @all_issue_custom_fields = nil
+    @all_time_entry_custom_fields = nil
+    @to_param = nil
+    @allowed_parents = nil
+    @allowed_permissions = nil
+    @actions_allowed = nil
+    @start_date = nil
+    @due_date = nil
+    base_reload(*args)
+  end
+
+  def to_param
+    # id is used for projects with a numeric identifier (compatibility)
+    @to_param ||= (identifier.to_s =~ %r{^\d*$} ? id.to_s : identifier)
+  end
+
+  def active?
+    self.status == STATUS_ACTIVE
+  end
+
+  def archived?
+    self.status == STATUS_ARCHIVED
+  end
+
+  # Archives the project and its descendants
+  def archive
+    # Check that there is no issue of a non descendant project that is assigned
+    # to one of the project or descendant versions
+    v_ids = self_and_descendants.collect {|p| p.version_ids}.flatten
+    if v_ids.any? &&
+      Issue.
+        includes(:project).
+        where("#{Project.table_name}.lft < ? OR #{Project.table_name}.rgt > ?", lft, rgt).
+        where("#{Issue.table_name}.fixed_version_id IN (?)", v_ids).
+        exists?
+      return false
+    end
+    Project.transaction do
+      archive!
+    end
+    true
+  end
+
+  # Unarchives the project
+  # All its ancestors must be active
+  def unarchive
+    return false if ancestors.detect {|a| !a.active?}
+    update_attribute :status, STATUS_ACTIVE
+  end
+
+  def close
+    self_and_descendants.status(STATUS_ACTIVE).update_all :status => STATUS_CLOSED
+  end
+
+  def reopen
+    self_and_descendants.status(STATUS_CLOSED).update_all :status => STATUS_ACTIVE
+  end
+
+  # Returns an array of projects the project can be moved to
+  # by the current user
+  def allowed_parents
+    return @allowed_parents if @allowed_parents
+    @allowed_parents = Project.where(Project.allowed_to_condition(User.current, :add_subprojects)).all
+    @allowed_parents = @allowed_parents - self_and_descendants
+    if User.current.allowed_to?(:add_project, nil, :global => true) || (!new_record? && parent.nil?)
+      @allowed_parents << nil
+    end
+    unless parent.nil? || @allowed_parents.empty? || @allowed_parents.include?(parent)
+      @allowed_parents << parent
+    end
+    @allowed_parents
+  end
+
+  # Sets the parent of the project with authorization check
+  def set_allowed_parent!(p)
+    unless p.nil? || p.is_a?(Project)
+      if p.to_s.blank?
+        p = nil
+      else
+        p = Project.find_by_id(p)
+        return false unless p
+      end
+    end
+    if p.nil?
+      if !new_record? && allowed_parents.empty?
+        return false
+      end
+    elsif !allowed_parents.include?(p)
+      return false
+    end
+    set_parent!(p)
+  end
+
+  # Sets the parent of the project
+  # Argument can be either a Project, a String, a Fixnum or nil
+  def set_parent!(p)
+    unless p.nil? || p.is_a?(Project)
+      if p.to_s.blank?
+        p = nil
+      else
+        p = Project.find_by_id(p)
+        return false unless p
+      end
+    end
+    if p == parent && !p.nil?
+      # Nothing to do
+      true
+    elsif p.nil? || (p.active? && move_possible?(p))
+      set_or_update_position_under(p)
+      Issue.update_versions_from_hierarchy_change(self)
+      true
+    else
+      # Can not move to the given target
+      false
+    end
+  end
+
+  # Recalculates all lft and rgt values based on project names
+  # Unlike Project.rebuild!, these values are recalculated even if the tree "looks" valid
+  # Used in BuildProjectsTree migration
+  def self.rebuild_tree!
+    transaction do
+      update_all "lft = NULL, rgt = NULL"
+      rebuild!(false)
+    end
+  end
+
+  # Returns an array of the trackers used by the project and its active sub projects
+  def rolled_up_trackers
+    @rolled_up_trackers ||=
+      Tracker.
+        joins(:projects).
+        joins("JOIN #{EnabledModule.table_name} ON #{EnabledModule.table_name}.project_id = #{Project.table_name}.id AND #{EnabledModule.table_name}.name = 'issue_tracking'").
+        select("DISTINCT #{Tracker.table_name}.*").
+        where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt).
+        sorted.
+        all
+  end
+
+  # Closes open and locked project versions that are completed
+  def close_completed_versions
+    Version.transaction do
+      versions.where(:status => %w(open locked)).all.each do |version|
+        if version.completed?
+          version.update_attribute(:status, 'closed')
+        end
+      end
+    end
+  end
+
+  # Returns a scope of the Versions on subprojects
+  def rolled_up_versions
+    @rolled_up_versions ||=
+      Version.scoped(:include => :project,
+                     :conditions => ["#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt])
+  end
+
+  # Returns a scope of the Versions used by the project
+  def shared_versions
+    if new_record?
+      Version.scoped(:include => :project,
+                     :conditions => "#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED} AND #{Version.table_name}.sharing = 'system'")
+    else
+      @shared_versions ||= begin
+        r = root? ? self : root
+        Version.scoped(:include => :project,
+                       :conditions => "#{Project.table_name}.id = #{id}" +
+                                      " OR (#{Project.table_name}.status <> #{Project::STATUS_ARCHIVED} AND (" +
+                                          " #{Version.table_name}.sharing = 'system'" +
+                                          " OR (#{Project.table_name}.lft >= #{r.lft} AND #{Project.table_name}.rgt <= #{r.rgt} AND #{Version.table_name}.sharing = 'tree')" +
+                                          " OR (#{Project.table_name}.lft < #{lft} AND #{Project.table_name}.rgt > #{rgt} AND #{Version.table_name}.sharing IN ('hierarchy', 'descendants'))" +
+                                          " OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt} AND #{Version.table_name}.sharing = 'hierarchy')" +
+                                          "))")
+      end
+    end
+  end
+
+  # Returns a hash of project users grouped by role
+  def users_by_role
+    members.includes(:user, :roles).all.inject({}) do |h, m|
+      m.roles.each do |r|
+        h[r] ||= []
+        h[r] << m.user
+      end
+      h
+    end
+  end
+
+  # Deletes all project's members
+  def delete_all_members
+    me, mr = Member.table_name, MemberRole.table_name
+    connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.project_id = #{id})")
+    Member.delete_all(['project_id = ?', id])
+  end
+
+  # Users/groups issues can be assigned to
+  def assignable_users
+    assignable = Setting.issue_group_assignment? ? member_principals : members
+    assignable.select {|m| m.roles.detect {|role| role.assignable?}}.collect {|m| m.principal}.sort
+  end
+
+  # Returns the mail adresses of users that should be always notified on project events
+  def recipients
+    notified_users.collect {|user| user.mail}
+  end
+
+  # Returns the users that should be notified on project events
+  def notified_users
+    # TODO: User part should be extracted to User#notify_about?
+    members.select {|m| m.principal.present? && (m.mail_notification? || m.principal.mail_notification == 'all')}.collect {|m| m.principal}
+  end
+
+  # Returns an array of all custom fields enabled for project issues
+  # (explictly associated custom fields and custom fields enabled for all projects)
+  def all_issue_custom_fields
+    @all_issue_custom_fields ||= (IssueCustomField.for_all + issue_custom_fields).uniq.sort
+  end
+
+  # Returns an array of all custom fields enabled for project time entries
+  # (explictly associated custom fields and custom fields enabled for all projects)
+  def all_time_entry_custom_fields
+    @all_time_entry_custom_fields ||= (TimeEntryCustomField.for_all + time_entry_custom_fields).uniq.sort
+  end
+
+  def project
+    self
+  end
+
+  def <=>(project)
+    name.downcase <=> project.name.downcase
+  end
+
+  def to_s
+    name
+  end
+
+  # Returns a short description of the projects (first lines)
+  def short_description(length = 255)
+    description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description
+  end
+
+  def css_classes
+    s = 'project'
+    s << ' root' if root?
+    s << ' child' if child?
+    s << (leaf? ? ' leaf' : ' parent')
+    unless active?
+      if archived?
+        s << ' archived'
+      else
+        s << ' closed'
+      end
+    end
+    s
+  end
+
+  # The earliest start date of a project, based on it's issues and versions
+  def start_date
+    @start_date ||= [
+     issues.minimum('start_date'),
+     shared_versions.minimum('effective_date'),
+     Issue.fixed_version(shared_versions).minimum('start_date')
+    ].compact.min
+  end
+
+  # The latest due date of an issue or version
+  def due_date
+    @due_date ||= [
+     issues.maximum('due_date'),
+     shared_versions.maximum('effective_date'),
+     Issue.fixed_version(shared_versions).maximum('due_date')
+    ].compact.max
+  end
+
+  def overdue?
+    active? && !due_date.nil? && (due_date < Date.today)
+  end
+
+  # Returns the percent completed for this project, based on the
+  # progress on it's versions.
+  def completed_percent(options={:include_subprojects => false})
+    if options.delete(:include_subprojects)
+      total = self_and_descendants.collect(&:completed_percent).sum
+
+      total / self_and_descendants.count
+    else
+      if versions.count > 0
+        total = versions.collect(&:completed_percent).sum
+
+        total / versions.count
+      else
+        100
+      end
+    end
+  end
+
+  # Return true if this project allows to do the specified action.
+  # action can be:
+  # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
+  # * a permission Symbol (eg. :edit_project)
+  def allows_to?(action)
+    if archived?
+      # No action allowed on archived projects
+      return false
+    end
+    unless active? || Redmine::AccessControl.read_action?(action)
+      # No write action allowed on closed projects
+      return false
+    end
+    # No action allowed on disabled modules
+    if action.is_a? Hash
+      allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
+    else
+      allowed_permissions.include? action
+    end
+  end
+
+  def module_enabled?(module_name)
+    module_name = module_name.to_s
+    enabled_modules.detect {|m| m.name == module_name}
+  end
+
+  def enabled_module_names=(module_names)
+    if module_names && module_names.is_a?(Array)
+      module_names = module_names.collect(&:to_s).reject(&:blank?)
+      self.enabled_modules = module_names.collect {|name| enabled_modules.detect {|mod| mod.name == name} || EnabledModule.new(:name => name)}
+    else
+      enabled_modules.clear
+    end
+  end
+
+  # Returns an array of the enabled modules names
+  def enabled_module_names
+    enabled_modules.collect(&:name)
+  end
+
+  # Enable a specific module
+  #
+  # Examples:
+  #   project.enable_module!(:issue_tracking)
+  #   project.enable_module!("issue_tracking")
+  def enable_module!(name)
+    enabled_modules << EnabledModule.new(:name => name.to_s) unless module_enabled?(name)
+  end
+
+  # Disable a module if it exists
+  #
+  # Examples:
+  #   project.disable_module!(:issue_tracking)
+  #   project.disable_module!("issue_tracking")
+  #   project.disable_module!(project.enabled_modules.first)
+  def disable_module!(target)
+    target = enabled_modules.detect{|mod| target.to_s == mod.name} unless enabled_modules.include?(target)
+    target.destroy unless target.blank?
+  end
+
+  safe_attributes 'name',
+    'description',
+    'homepage',
+    'is_public',
+    'identifier',
+    'custom_field_values',
+    'custom_fields',
+    'tracker_ids',
+    'issue_custom_field_ids'
+
+  safe_attributes 'enabled_module_names',
+    :if => lambda {|project, user| project.new_record? || user.allowed_to?(:select_project_modules, project) }
+
+  safe_attributes 'inherit_members',
+    :if => lambda {|project, user| project.parent.nil? || project.parent.visible?(user)}
+
+  # Returns an array of projects that are in this project's hierarchy
+  #
+  # Example: parents, children, siblings
+  def hierarchy
+    parents = project.self_and_ancestors || []
+    descendants = project.descendants || []
+    project_hierarchy = parents | descendants # Set union
+  end
+
+  # Returns an auto-generated project identifier based on the last identifier used
+  def self.next_identifier
+    p = Project.order('id DESC').first
+    p.nil? ? nil : p.identifier.to_s.succ
+  end
+
+  # Copies and saves the Project instance based on the +project+.
+  # Duplicates the source project's:
+  # * Wiki
+  # * Versions
+  # * Categories
+  # * Issues
+  # * Members
+  # * Queries
+  #
+  # Accepts an +options+ argument to specify what to copy
+  #
+  # Examples:
+  #   project.copy(1)                                    # => copies everything
+  #   project.copy(1, :only => 'members')                # => copies members only
+  #   project.copy(1, :only => ['members', 'versions'])  # => copies members and versions
+  def copy(project, options={})
+    project = project.is_a?(Project) ? project : Project.find(project)
+
+    to_be_copied = %w(wiki versions issue_categories issues members queries boards)
+    to_be_copied = to_be_copied & options[:only].to_a unless options[:only].nil?
+
+    Project.transaction do
+      if save
+        reload
+        to_be_copied.each do |name|
+          send "copy_#{name}", project
+        end
+        Redmine::Hook.call_hook(:model_project_copy_before_save, :source_project => project, :destination_project => self)
+        save
+      end
+    end
+  end
+
+  # Returns a new unsaved Project instance with attributes copied from +project+
+  def self.copy_from(project)
+    project = project.is_a?(Project) ? project : Project.find(project)
+    # clear unique attributes
+    attributes = project.attributes.dup.except('id', 'name', 'identifier', 'status', 'parent_id', 'lft', 'rgt')
+    copy = Project.new(attributes)
+    copy.enabled_modules = project.enabled_modules
+    copy.trackers = project.trackers
+    copy.custom_values = project.custom_values.collect {|v| v.clone}
+    copy.issue_custom_fields = project.issue_custom_fields
+    copy
+  end
+
+  # Yields the given block for each project with its level in the tree
+  def self.project_tree(projects, &block)
+    ancestors = []
+    projects.sort_by(&:lft).each do |project|
+      while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
+        ancestors.pop
+      end
+      yield project, ancestors.size
+      ancestors << project
+    end
+  end
+
+  private
+
+  def after_parent_changed(parent_was)
+    remove_inherited_member_roles
+    add_inherited_member_roles
+  end
+
+  def update_inherited_members
+    if parent
+      if inherit_members? && !inherit_members_was
+        remove_inherited_member_roles
+        add_inherited_member_roles
+      elsif !inherit_members? && inherit_members_was
+        remove_inherited_member_roles
+      end
+    end
+  end
+
+  def remove_inherited_member_roles
+    member_roles = memberships.map(&:member_roles).flatten
+    member_role_ids = member_roles.map(&:id)
+    member_roles.each do |member_role|
+      if member_role.inherited_from && !member_role_ids.include?(member_role.inherited_from)
+        member_role.destroy
+      end
+    end
+  end
+
+  def add_inherited_member_roles
+    if inherit_members? && parent
+      parent.memberships.each do |parent_member|
+        member = Member.find_or_new(self.id, parent_member.user_id)
+        parent_member.member_roles.each do |parent_member_role|
+          member.member_roles << MemberRole.new(:role => parent_member_role.role, :inherited_from => parent_member_role.id)
+        end
+        member.save!
+      end
+    end
+  end
+
+  # Copies wiki from +project+
+  def copy_wiki(project)
+    # Check that the source project has a wiki first
+    unless project.wiki.nil?
+      wiki = self.wiki || Wiki.new
+      wiki.attributes = project.wiki.attributes.dup.except("id", "project_id")
+      wiki_pages_map = {}
+      project.wiki.pages.each do |page|
+        # Skip pages without content
+        next if page.content.nil?
+        new_wiki_content = WikiContent.new(page.content.attributes.dup.except("id", "page_id", "updated_on"))
+        new_wiki_page = WikiPage.new(page.attributes.dup.except("id", "wiki_id", "created_on", "parent_id"))
+        new_wiki_page.content = new_wiki_content
+        wiki.pages << new_wiki_page
+        wiki_pages_map[page.id] = new_wiki_page
+      end
+
+      self.wiki = wiki
+      wiki.save
+      # Reproduce page hierarchy
+      project.wiki.pages.each do |page|
+        if page.parent_id && wiki_pages_map[page.id]
+          wiki_pages_map[page.id].parent = wiki_pages_map[page.parent_id]
+          wiki_pages_map[page.id].save
+        end
+      end
+    end
+  end
+
+  # Copies versions from +project+
+  def copy_versions(project)
+    project.versions.each do |version|
+      new_version = Version.new
+      new_version.attributes = version.attributes.dup.except("id", "project_id", "created_on", "updated_on")
+      self.versions << new_version
+    end
+  end
+
+  # Copies issue categories from +project+
+  def copy_issue_categories(project)
+    project.issue_categories.each do |issue_category|
+      new_issue_category = IssueCategory.new
+      new_issue_category.attributes = issue_category.attributes.dup.except("id", "project_id")
+      self.issue_categories << new_issue_category
+    end
+  end
+
+  # Copies issues from +project+
+  def copy_issues(project)
+    # Stores the source issue id as a key and the copied issues as the
+    # value.  Used to map the two togeather for issue relations.
+    issues_map = {}
+
+    # Store status and reopen locked/closed versions
+    version_statuses = versions.reject(&:open?).map {|version| [version, version.status]}
+    version_statuses.each do |version, status|
+      version.update_attribute :status, 'open'
+    end
+
+    # Get issues sorted by root_id, lft so that parent issues
+    # get copied before their children
+    project.issues.reorder('root_id, lft').all.each do |issue|
+      new_issue = Issue.new
+      new_issue.copy_from(issue, :subtasks => false, :link => false)
+      new_issue.project = self
+      # Changing project resets the custom field values
+      # TODO: handle this in Issue#project=
+      new_issue.custom_field_values = issue.custom_field_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
+      # Reassign fixed_versions by name, since names are unique per project
+      if issue.fixed_version && issue.fixed_version.project == project
+        new_issue.fixed_version = self.versions.detect {|v| v.name == issue.fixed_version.name}
+      end
+      # Reassign the category by name, since names are unique per project
+      if issue.category
+        new_issue.category = self.issue_categories.detect {|c| c.name == issue.category.name}
+      end
+      # Parent issue
+      if issue.parent_id
+        if copied_parent = issues_map[issue.parent_id]
+          new_issue.parent_issue_id = copied_parent.id
+        end
+      end
+
+      self.issues << new_issue
+      if new_issue.new_record?
+        logger.info "Project#copy_issues: issue ##{issue.id} could not be copied: #{new_issue.errors.full_messages}" if logger && logger.info
+      else
+        issues_map[issue.id] = new_issue unless new_issue.new_record?
+      end
+    end
+
+    # Restore locked/closed version statuses
+    version_statuses.each do |version, status|
+      version.update_attribute :status, status
+    end
+
+    # Relations after in case issues related each other
+    project.issues.each do |issue|
+      new_issue = issues_map[issue.id]
+      unless new_issue
+        # Issue was not copied
+        next
+      end
+
+      # Relations
+      issue.relations_from.each do |source_relation|
+        new_issue_relation = IssueRelation.new
+        new_issue_relation.attributes = source_relation.attributes.dup.except("id", "issue_from_id", "issue_to_id")
+        new_issue_relation.issue_to = issues_map[source_relation.issue_to_id]
+        if new_issue_relation.issue_to.nil? && Setting.cross_project_issue_relations?
+          new_issue_relation.issue_to = source_relation.issue_to
+        end
+        new_issue.relations_from << new_issue_relation
+      end
+
+      issue.relations_to.each do |source_relation|
+        new_issue_relation = IssueRelation.new
+        new_issue_relation.attributes = source_relation.attributes.dup.except("id", "issue_from_id", "issue_to_id")
+        new_issue_relation.issue_from = issues_map[source_relation.issue_from_id]
+        if new_issue_relation.issue_from.nil? && Setting.cross_project_issue_relations?
+          new_issue_relation.issue_from = source_relation.issue_from
+        end
+        new_issue.relations_to << new_issue_relation
+      end
+    end
+  end
+
+  # Copies members from +project+
+  def copy_members(project)
+    # Copy users first, then groups to handle members with inherited and given roles
+    members_to_copy = []
+    members_to_copy += project.memberships.select {|m| m.principal.is_a?(User)}
+    members_to_copy += project.memberships.select {|m| !m.principal.is_a?(User)}
+
+    members_to_copy.each do |member|
+      new_member = Member.new
+      new_member.attributes = member.attributes.dup.except("id", "project_id", "created_on")
+      # only copy non inherited roles
+      # inherited roles will be added when copying the group membership
+      role_ids = member.member_roles.reject(&:inherited?).collect(&:role_id)
+      next if role_ids.empty?
+      new_member.role_ids = role_ids
+      new_member.project = self
+      self.members << new_member
+    end
+  end
+
+  # Copies queries from +project+
+  def copy_queries(project)
+    project.queries.each do |query|
+      new_query = IssueQuery.new
+      new_query.attributes = query.attributes.dup.except("id", "project_id", "sort_criteria")
+      new_query.sort_criteria = query.sort_criteria if query.sort_criteria
+      new_query.project = self
+      new_query.user_id = query.user_id
+      self.queries << new_query
+    end
+  end
+
+  # Copies boards from +project+
+  def copy_boards(project)
+    project.boards.each do |board|
+      new_board = Board.new
+      new_board.attributes = board.attributes.dup.except("id", "project_id", "topics_count", "messages_count", "last_message_id")
+      new_board.project = self
+      self.boards << new_board
+    end
+  end
+
+  def allowed_permissions
+    @allowed_permissions ||= begin
+      module_names = enabled_modules.all(:select => :name).collect {|m| m.name}
+      Redmine::AccessControl.modules_permissions(module_names).collect {|p| p.name}
+    end
+  end
+
+  def allowed_actions
+    @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
+  end
+
+  # Returns all the active Systemwide and project specific activities
+  def active_activities
+    overridden_activity_ids = self.time_entry_activities.collect(&:parent_id)
+
+    if overridden_activity_ids.empty?
+      return TimeEntryActivity.shared.active
+    else
+      return system_activities_and_project_overrides
+    end
+  end
+
+  # Returns all the Systemwide and project specific activities
+  # (inactive and active)
+  def all_activities
+    overridden_activity_ids = self.time_entry_activities.collect(&:parent_id)
+
+    if overridden_activity_ids.empty?
+      return TimeEntryActivity.shared
+    else
+      return system_activities_and_project_overrides(true)
+    end
+  end
+
+  # Returns the systemwide active activities merged with the project specific overrides
+  def system_activities_and_project_overrides(include_inactive=false)
+    if include_inactive
+      return TimeEntryActivity.shared.
+        where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all +
+        self.time_entry_activities
+    else
+      return TimeEntryActivity.shared.active.
+        where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all +
+        self.time_entry_activities.active
+    end
+  end
+
+  # Archives subprojects recursively
+  def archive!
+    children.each do |subproject|
+      subproject.send :archive!
+    end
+    update_attribute :status, STATUS_ARCHIVED
+  end
+
+  def update_position_under_parent
+    set_or_update_position_under(parent)
+  end
+
+  # Inserts/moves the project so that target's children or root projects stay alphabetically sorted
+  def set_or_update_position_under(target_parent)
+    parent_was = parent
+    sibs = (target_parent.nil? ? self.class.roots : target_parent.children)
+    to_be_inserted_before = sibs.sort_by {|c| c.name.to_s.downcase}.detect {|c| c.name.to_s.downcase > name.to_s.downcase }
+
+    if to_be_inserted_before
+      move_to_left_of(to_be_inserted_before)
+    elsif target_parent.nil?
+      if sibs.empty?
+        # move_to_root adds the project in first (ie. left) position
+        move_to_root
+      else
+        move_to_right_of(sibs.last) unless self == sibs.last
+      end
+    else
+      # move_to_child_of adds the project in last (ie.right) position
+      move_to_child_of(target_parent)
+    end
+    if parent_was != target_parent
+      after_parent_changed(parent_was)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/04/045b82572747e8f57f122a0ac4102b9d20ea2c04.svn-base
--- /dev/null
+++ b/.svn/pristine/04/045b82572747e8f57f122a0ac4102b9d20ea2c04.svn-base
@@ -0,0 +1,592 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ProjectsControllerTest < ActionController::TestCase
+  fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
+           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
+           :attachments, :custom_fields, :custom_values, :time_entries
+
+  def setup
+    @request.session[:user_id] = nil
+    Setting.default_language = 'en'
+  end
+
+  def test_index_by_anonymous_should_not_show_private_projects
+    get :index
+    assert_response :success
+    assert_template 'index'
+    projects = assigns(:projects)
+    assert_not_nil projects
+    assert projects.all?(&:is_public?)
+
+    assert_select 'ul' do
+      assert_select 'li' do
+        assert_select 'a', :text => 'eCookbook'
+        assert_select 'ul' do
+          assert_select 'a', :text => 'Child of private child'
+        end
+      end
+    end
+    assert_select 'a', :text => /Private child of eCookbook/, :count => 0
+  end
+
+  def test_index_atom
+    get :index, :format => 'atom'
+    assert_response :success
+    assert_template 'common/feed'
+    assert_select 'feed>title', :text => 'Redmine: Latest projects'
+    assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_condition(User.current))
+  end
+
+  test "#index by non-admin user with view_time_entries permission should show overall spent time link" do
+    @request.session[:user_id] = 3
+    get :index
+    assert_template 'index'
+    assert_select 'a[href=?]', '/time_entries'
+  end
+
+  test "#index by non-admin user without view_time_entries permission should not show overall spent time link" do
+    Role.find(2).remove_permission! :view_time_entries
+    Role.non_member.remove_permission! :view_time_entries
+    Role.anonymous.remove_permission! :view_time_entries
+    @request.session[:user_id] = 3
+
+    get :index
+    assert_template 'index'
+    assert_select 'a[href=?]', '/time_entries', 0
+  end
+
+  test "#new by admin user should accept get" do
+    @request.session[:user_id] = 1
+
+    get :new
+    assert_response :success
+    assert_template 'new'
+  end
+
+  test "#new by non-admin user with add_project permission should accept get" do
+    Role.non_member.add_permission! :add_project
+    @request.session[:user_id] = 9
+
+    get :new
+    assert_response :success
+    assert_template 'new'
+    assert_select 'select[name=?]', 'project[parent_id]', 0
+  end
+
+  test "#new by non-admin user with add_subprojects permission should accept get" do
+    Role.find(1).remove_permission! :add_project
+    Role.find(1).add_permission! :add_subprojects
+    @request.session[:user_id] = 2
+
+    get :new, :parent_id => 'ecookbook'
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'select[name=?]', 'project[parent_id]' do
+      # parent project selected
+      assert_select 'option[value=1][selected=selected]'
+      # no empty value
+      assert_select 'option[value=]', 0
+    end
+  end
+
+  test "#create by admin user should create a new project" do
+    @request.session[:user_id] = 1
+
+    post :create,
+      :project => {
+        :name => "blog",
+        :description => "weblog",
+        :homepage => 'http://weblog',
+        :identifier => "blog",
+        :is_public => 1,
+        :custom_field_values => { '3' => 'Beta' },
+        :tracker_ids => ['1', '3'],
+        # an issue custom field that is not for all project
+        :issue_custom_field_ids => ['9'],
+        :enabled_module_names => ['issue_tracking', 'news', 'repository']
+      }
+    assert_redirected_to '/projects/blog/settings'
+
+    project = Project.find_by_name('blog')
+    assert_kind_of Project, project
+    assert project.active?
+    assert_equal 'weblog', project.description
+    assert_equal 'http://weblog', project.homepage
+    assert_equal true, project.is_public?
+    assert_nil project.parent
+    assert_equal 'Beta', project.custom_value_for(3).value
+    assert_equal [1, 3], project.trackers.map(&:id).sort
+    assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
+    assert project.issue_custom_fields.include?(IssueCustomField.find(9))
+  end
+
+  test "#create by admin user should create a new subproject" do
+    @request.session[:user_id] = 1
+
+    assert_difference 'Project.count' do
+      post :create, :project => { :name => "blog",
+                               :description => "weblog",
+                               :identifier => "blog",
+                               :is_public => 1,
+                               :custom_field_values => { '3' => 'Beta' },
+                               :parent_id => 1
+                              }
+      assert_redirected_to '/projects/blog/settings'
+    end
+
+    project = Project.find_by_name('blog')
+    assert_kind_of Project, project
+    assert_equal Project.find(1), project.parent
+  end
+
+  test "#create by admin user should continue" do
+    @request.session[:user_id] = 1
+
+    assert_difference 'Project.count' do
+      post :create, :project => {:name => "blog", :identifier => "blog"}, :continue => 'Create and continue'
+    end
+    assert_redirected_to '/projects/new'
+  end
+
+  test "#create by non-admin user with add_project permission should create a new project" do
+    Role.non_member.add_permission! :add_project
+    @request.session[:user_id] = 9
+
+    post :create, :project => { :name => "blog",
+                             :description => "weblog",
+                             :identifier => "blog",
+                             :is_public => 1,
+                             :custom_field_values => { '3' => 'Beta' },
+                             :tracker_ids => ['1', '3'],
+                             :enabled_module_names => ['issue_tracking', 'news', 'repository']
+                            }
+
+    assert_redirected_to '/projects/blog/settings'
+
+    project = Project.find_by_name('blog')
+    assert_kind_of Project, project
+    assert_equal 'weblog', project.description
+    assert_equal true, project.is_public?
+    assert_equal [1, 3], project.trackers.map(&:id).sort
+    assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
+
+    # User should be added as a project member
+    assert User.find(9).member_of?(project)
+    assert_equal 1, project.members.size
+  end
+
+  test "#create by non-admin user with add_project permission should fail with parent_id" do
+    Role.non_member.add_permission! :add_project
+    @request.session[:user_id] = 9
+
+    assert_no_difference 'Project.count' do
+      post :create, :project => { :name => "blog",
+                               :description => "weblog",
+                               :identifier => "blog",
+                               :is_public => 1,
+                               :custom_field_values => { '3' => 'Beta' },
+                               :parent_id => 1
+                              }
+    end
+    assert_response :success
+    project = assigns(:project)
+    assert_kind_of Project, project
+    assert_not_nil project.errors[:parent_id]
+  end
+
+  test "#create by non-admin user with add_subprojects permission should create a project with a parent_id" do
+    Role.find(1).remove_permission! :add_project
+    Role.find(1).add_permission! :add_subprojects
+    @request.session[:user_id] = 2
+
+    post :create, :project => { :name => "blog",
+                             :description => "weblog",
+                             :identifier => "blog",
+                             :is_public => 1,
+                             :custom_field_values => { '3' => 'Beta' },
+                             :parent_id => 1
+                            }
+    assert_redirected_to '/projects/blog/settings'
+    project = Project.find_by_name('blog')
+  end
+
+  test "#create by non-admin user with add_subprojects permission should fail without parent_id" do
+    Role.find(1).remove_permission! :add_project
+    Role.find(1).add_permission! :add_subprojects
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Project.count' do
+      post :create, :project => { :name => "blog",
+                               :description => "weblog",
+                               :identifier => "blog",
+                               :is_public => 1,
+                               :custom_field_values => { '3' => 'Beta' }
+                              }
+    end
+    assert_response :success
+    project = assigns(:project)
+    assert_kind_of Project, project
+    assert_not_nil project.errors[:parent_id]
+  end
+
+  test "#create by non-admin user with add_subprojects permission should fail with unauthorized parent_id" do
+    Role.find(1).remove_permission! :add_project
+    Role.find(1).add_permission! :add_subprojects
+    @request.session[:user_id] = 2
+
+    assert !User.find(2).member_of?(Project.find(6))
+    assert_no_difference 'Project.count' do
+      post :create, :project => { :name => "blog",
+                               :description => "weblog",
+                               :identifier => "blog",
+                               :is_public => 1,
+                               :custom_field_values => { '3' => 'Beta' },
+                               :parent_id => 6
+                              }
+    end
+    assert_response :success
+    project = assigns(:project)
+    assert_kind_of Project, project
+    assert_not_nil project.errors[:parent_id]
+  end
+
+  def test_create_subproject_with_inherit_members_should_inherit_members
+    Role.find_by_name('Manager').add_permission! :add_subprojects
+    parent = Project.find(1)
+    @request.session[:user_id] = 2
+
+    assert_difference 'Project.count' do
+      post :create, :project => {
+        :name => 'inherited', :identifier => 'inherited', :parent_id => parent.id, :inherit_members => '1'
+      }
+      assert_response 302
+    end
+
+    project = Project.order('id desc').first
+    assert_equal 'inherited', project.name
+    assert_equal parent, project.parent
+    assert project.memberships.count > 0
+    assert_equal parent.memberships.count, project.memberships.count
+  end
+
+  def test_create_should_preserve_modules_on_validation_failure
+    with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
+      @request.session[:user_id] = 1
+      assert_no_difference 'Project.count' do
+        post :create, :project => {
+          :name => "blog",
+          :identifier => "",
+          :enabled_module_names => %w(issue_tracking news)
+        }
+      end
+      assert_response :success
+      project = assigns(:project)
+      assert_equal %w(issue_tracking news), project.enabled_module_names.sort
+    end
+  end
+
+  def test_show_by_id
+    get :show, :id => 1
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:project)
+  end
+
+  def test_show_by_identifier
+    get :show, :id => 'ecookbook'
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:project)
+    assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
+
+    assert_select 'li', :text => /Development status/
+  end
+
+  def test_show_should_not_display_hidden_custom_fields
+    ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
+    get :show, :id => 'ecookbook'
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:project)
+
+    assert_select 'li', :text => /Development status/, :count => 0
+  end
+
+  def test_show_should_not_fail_when_custom_values_are_nil
+    project = Project.find_by_identifier('ecookbook')
+    project.custom_values.first.update_attribute(:value, nil)
+    get :show, :id => 'ecookbook'
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:project)
+    assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
+  end
+
+  def show_archived_project_should_be_denied
+    project = Project.find_by_identifier('ecookbook')
+    project.archive!
+
+    get :show, :id => 'ecookbook'
+    assert_response 403
+    assert_nil assigns(:project)
+    assert_select 'p', :text => /archived/
+  end
+
+  def test_show_should_not_show_private_subprojects_that_are_not_visible
+    get :show, :id => 'ecookbook'
+    assert_response :success
+    assert_template 'show'
+    assert_select 'a', :text => /Private child/, :count => 0
+  end
+
+  def test_show_should_show_private_subprojects_that_are_visible
+    @request.session[:user_id] = 2 # manager who is a member of the private subproject
+    get :show, :id => 'ecookbook'
+    assert_response :success
+    assert_template 'show'
+    assert_select 'a', :text => /Private child/
+  end
+
+  def test_settings
+    @request.session[:user_id] = 2 # manager
+    get :settings, :id => 1
+    assert_response :success
+    assert_template 'settings'
+  end
+
+  def test_settings_of_subproject
+    @request.session[:user_id] = 2
+    get :settings, :id => 'private-child'
+    assert_response :success
+    assert_template 'settings'
+
+    assert_select 'input[type=checkbox][name=?]', 'project[inherit_members]'
+  end
+
+  def test_settings_should_be_denied_for_member_on_closed_project
+    Project.find(1).close
+    @request.session[:user_id] = 2 # manager
+
+    get :settings, :id => 1
+    assert_response 403
+  end
+
+  def test_settings_should_be_denied_for_anonymous_on_closed_project
+    Project.find(1).close
+
+    get :settings, :id => 1
+    assert_response 302
+  end
+
+  def test_update
+    @request.session[:user_id] = 2 # manager
+    post :update, :id => 1, :project => {:name => 'Test changed name',
+                                       :issue_custom_field_ids => ['']}
+    assert_redirected_to '/projects/ecookbook/settings'
+    project = Project.find(1)
+    assert_equal 'Test changed name', project.name
+  end
+
+  def test_update_with_failure
+    @request.session[:user_id] = 2 # manager
+    post :update, :id => 1, :project => {:name => ''}
+    assert_response :success
+    assert_template 'settings'
+    assert_error_tag :content => /name can&#x27;t be blank/i
+  end
+
+  def test_update_should_be_denied_for_member_on_closed_project
+    Project.find(1).close
+    @request.session[:user_id] = 2 # manager
+
+    post :update, :id => 1, :project => {:name => 'Closed'}
+    assert_response 403
+    assert_equal 'eCookbook', Project.find(1).name
+  end
+
+  def test_update_should_be_denied_for_anonymous_on_closed_project
+    Project.find(1).close
+
+    post :update, :id => 1, :project => {:name => 'Closed'}
+    assert_response 302
+    assert_equal 'eCookbook', Project.find(1).name
+  end
+
+  def test_modules
+    @request.session[:user_id] = 2
+    Project.find(1).enabled_module_names = ['issue_tracking', 'news']
+
+    post :modules, :id => 1, :enabled_module_names => ['issue_tracking', 'repository', 'documents']
+    assert_redirected_to '/projects/ecookbook/settings/modules'
+    assert_equal ['documents', 'issue_tracking', 'repository'], Project.find(1).enabled_module_names.sort
+  end
+
+  def test_destroy_leaf_project_without_confirmation_should_show_confirmation
+    @request.session[:user_id] = 1 # admin
+
+    assert_no_difference 'Project.count' do
+      delete :destroy, :id => 2
+      assert_response :success
+      assert_template 'destroy'
+    end
+  end
+
+  def test_destroy_without_confirmation_should_show_confirmation_with_subprojects
+    @request.session[:user_id] = 1 # admin
+
+    assert_no_difference 'Project.count' do
+      delete :destroy, :id => 1
+      assert_response :success
+      assert_template 'destroy'
+    end
+    assert_select 'strong',
+                  :text => ['Private child of eCookbook',
+                            'Child of private child, eCookbook Subproject 1',
+                            'eCookbook Subproject 2'].join(', ')
+  end
+
+  def test_destroy_with_confirmation_should_destroy_the_project_and_subprojects
+    @request.session[:user_id] = 1 # admin
+
+    assert_difference 'Project.count', -5 do
+      delete :destroy, :id => 1, :confirm => 1
+      assert_redirected_to '/admin/projects'
+    end
+    assert_nil Project.find_by_id(1)
+  end
+
+  def test_archive
+    @request.session[:user_id] = 1 # admin
+    post :archive, :id => 1
+    assert_redirected_to '/admin/projects'
+    assert !Project.find(1).active?
+  end
+
+  def test_archive_with_failure
+    @request.session[:user_id] = 1
+    Project.any_instance.stubs(:archive).returns(false)
+    post :archive, :id => 1
+    assert_redirected_to '/admin/projects'
+    assert_match /project cannot be archived/i, flash[:error]
+  end
+
+  def test_unarchive
+    @request.session[:user_id] = 1 # admin
+    Project.find(1).archive
+    post :unarchive, :id => 1
+    assert_redirected_to '/admin/projects'
+    assert Project.find(1).active?
+  end
+
+  def test_close
+    @request.session[:user_id] = 2
+    post :close, :id => 1
+    assert_redirected_to '/projects/ecookbook'
+    assert_equal Project::STATUS_CLOSED, Project.find(1).status
+  end
+
+  def test_reopen
+    Project.find(1).close
+    @request.session[:user_id] = 2
+    post :reopen, :id => 1
+    assert_redirected_to '/projects/ecookbook'
+    assert Project.find(1).active?
+  end
+
+  def test_project_breadcrumbs_should_be_limited_to_3_ancestors
+    CustomField.delete_all
+    parent = nil
+    6.times do |i|
+      p = Project.generate_with_parent!(parent)
+      get :show, :id => p
+      assert_select '#header h1' do
+        assert_select 'a', :count => [i, 3].min
+      end
+
+      parent = p
+    end
+  end
+
+  def test_get_copy
+    @request.session[:user_id] = 1 # admin
+    get :copy, :id => 1
+    assert_response :success
+    assert_template 'copy'
+    assert assigns(:project)
+    assert_equal Project.find(1).description, assigns(:project).description
+    assert_nil assigns(:project).id
+
+    assert_select 'input[name=?][value=?]', 'project[enabled_module_names][]', 'issue_tracking', 1
+  end
+
+  def test_get_copy_with_invalid_source_should_respond_with_404
+    @request.session[:user_id] = 1
+    get :copy, :id => 99
+    assert_response 404
+  end
+
+  def test_post_copy_should_copy_requested_items
+    @request.session[:user_id] = 1 # admin
+    CustomField.delete_all
+
+    assert_difference 'Project.count' do
+      post :copy, :id => 1,
+        :project => {
+          :name => 'Copy',
+          :identifier => 'unique-copy',
+          :tracker_ids => ['1', '2', '3', ''],
+          :enabled_module_names => %w(issue_tracking time_tracking)
+        },
+        :only => %w(issues versions)
+    end
+    project = Project.find('unique-copy')
+    source = Project.find(1)
+    assert_equal %w(issue_tracking time_tracking), project.enabled_module_names.sort
+
+    assert_equal source.versions.count, project.versions.count, "All versions were not copied"
+    assert_equal source.issues.count, project.issues.count, "All issues were not copied"
+    assert_equal 0, project.members.count
+  end
+
+  def test_post_copy_should_redirect_to_settings_when_successful
+    @request.session[:user_id] = 1 # admin
+    post :copy, :id => 1, :project => {:name => 'Copy', :identifier => 'unique-copy'}
+    assert_response :redirect
+    assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy'
+  end
+
+  def test_jump_should_redirect_to_active_tab
+    get :show, :id => 1, :jump => 'issues'
+    assert_redirected_to '/projects/ecookbook/issues'
+  end
+
+  def test_jump_should_not_redirect_to_inactive_tab
+    get :show, :id => 3, :jump => 'documents'
+    assert_response :success
+    assert_template 'show'
+  end
+
+  def test_jump_should_not_redirect_to_unknown_tab
+    get :show, :id => 3, :jump => 'foobar'
+    assert_response :success
+    assert_template 'show'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/04/0490719dc3185896fb07e210967a75c0f5e40a0a.svn-base
--- /dev/null
+++ b/.svn/pristine/04/0490719dc3185896fb07e210967a75c0f5e40a0a.svn-base
@@ -0,0 +1,54 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssueTransactionTest < ActiveSupport::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles,
+           :trackers, :projects_trackers,
+           :versions,
+           :issue_statuses, :issue_categories, :issue_relations, :workflows,
+           :enumerations,
+           :issues,
+           :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
+           :time_entries
+
+  self.use_transactional_fixtures = false
+
+  def test_invalid_move_to_another_project
+    parent1 = Issue.generate!
+    child =   Issue.generate!(:parent_issue_id => parent1.id)
+    grandchild = Issue.generate!(:parent_issue_id => child.id, :tracker_id => 2)
+    Project.find(2).tracker_ids = [1]
+
+    parent1.reload
+    assert_equal [1, parent1.id, 1, 6], [parent1.project_id, parent1.root_id, parent1.lft, parent1.rgt]
+
+    # child can not be moved to Project 2 because its child is on a disabled tracker
+    child = Issue.find(child.id)
+    child.project = Project.find(2)
+    assert !child.save
+    child.reload
+    grandchild.reload
+    parent1.reload
+
+    # no change
+    assert_equal [1, parent1.id, 1, 6], [parent1.project_id, parent1.root_id, parent1.lft, parent1.rgt]
+    assert_equal [1, parent1.id, 2, 5], [child.project_id, child.root_id, child.lft, child.rgt]
+    assert_equal [1, parent1.id, 3, 4], [grandchild.project_id, grandchild.root_id, grandchild.lft, grandchild.rgt]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/04/04bafe6e6b402a0f59316ed78a7582dc8951a46f.svn-base
--- a/.svn/pristine/04/04bafe6e6b402a0f59316ed78a7582dc8951a46f.svn-base
+++ /dev/null
@@ -1,26 +0,0 @@
-<% content_for :header_tags do %>
-    <%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %>
-<% end %>
-
-<div class="contextual">
-    <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %>
-    <%= link_to(l(:label_issue_view_all), { :controller => 'issues' }) + ' |' if User.current.allowed_to?(:view_issues, nil, :global => true) %>
-    <%= link_to(l(:label_overall_spent_time), { :controller => 'time_entries' }) + ' |' if User.current.allowed_to?(:view_time_entries, nil, :global => true) %>
-    <%= link_to l(:label_overall_activity), { :controller => 'activities', :action => 'index' }%>
-</div>
-
-<h2><%=l(:label_project_plural)%></h2>
-
-<%= render_project_hierarchy(@projects)%>
-
-<% if User.current.logged? %>
-<p style="text-align:right;">
-<span class="my-project"><%= l(:label_my_projects) %></span>
-</p>
-<% end %>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
-<% end %>
-
-<% html_title(l(:label_project_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/04/04bd6b422ff086dcb557f90d7ba79b9553b3ae87.svn-base
--- a/.svn/pristine/04/04bd6b422ff086dcb557f90d7ba79b9553b3ae87.svn-base
+++ /dev/null
@@ -1,71 +0,0 @@
-# encoding: utf-8
-module CodeRay
-module Scanners
-  
-  class Ruby
-    
-    class StringState < Struct.new :type, :interpreted, :delim, :heredoc,
-      :opening_paren, :paren_depth, :pattern, :next_state  # :nodoc: all
-      
-      CLOSING_PAREN = Hash[ *%w[
-        ( )
-        [ ]
-        < >
-        { }
-      ] ].each { |k,v| k.freeze; v.freeze }  # debug, if I try to change it with <<
-      
-      STRING_PATTERN = Hash.new do |h, k|
-        delim, interpreted = *k
-        # delim = delim.dup  # workaround for old Ruby
-        delim_pattern = Regexp.escape(delim)
-        if closing_paren = CLOSING_PAREN[delim]
-          delim_pattern << Regexp.escape(closing_paren)
-        end
-        delim_pattern << '\\\\' unless delim == '\\'
-        
-        # special_escapes =
-        #   case interpreted
-        #   when :regexp_symbols
-        #     '| [|?*+(){}\[\].^$]'
-        #   end
-        
-        h[k] =
-          if interpreted && delim != '#'
-            / (?= [#{delim_pattern}] | \# [{$@] ) /mx
-          else
-            / (?= [#{delim_pattern}] ) /mx
-          end
-      end
-      
-      def initialize kind, interpreted, delim, heredoc = false
-        if heredoc
-          pattern = heredoc_pattern delim, interpreted, heredoc == :indented
-          delim = nil
-        else
-          pattern = STRING_PATTERN[ [delim, interpreted] ]
-          if closing_paren = CLOSING_PAREN[delim]
-            opening_paren = delim
-            delim = closing_paren
-            paren_depth = 1
-          end
-        end
-        super kind, interpreted, delim, heredoc, opening_paren, paren_depth, pattern, :initial
-      end
-      
-      def heredoc_pattern delim, interpreted, indented
-        # delim = delim.dup  # workaround for old Ruby
-        delim_pattern = Regexp.escape(delim)
-        delim_pattern = / (?:\A|\n) #{ '(?>[ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x
-        if interpreted
-          / (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx  # $1 set == end of heredoc
-        else
-          / (?= #{delim_pattern}() | \\ ) /mx
-        end
-      end
-      
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/04/04dcbe1c1303811a184d8f2171e27c9cdde0c767.svn-base
--- /dev/null
+++ b/.svn/pristine/04/04dcbe1c1303811a184d8f2171e27c9cdde0c767.svn-base
@@ -0,0 +1,1091 @@
+fa:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: rtl
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y/%m/%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [ÛŒÚ©â€ŒØ´Ù†Ø¨Ù‡, Ø¯ÙˆØ´Ù†Ø¨Ù‡, Ø³Ù‡â€ŒØ´Ù†Ø¨Ù‡, Ú†Ù‡Ø§Ø±Ø´Ù†Ø¨Ù‡, Ù¾Ù†Ø¬â€ŒØ´Ù†Ø¨Ù‡, Ø¢Ø¯ÛŒÙ†Ù‡, Ø´Ù†Ø¨Ù‡]
+    abbr_day_names: [ÛŒÚ©, Ø¯Ùˆ, Ø³Ù‡, Ú†Ù‡Ø§Ø±, Ù¾Ù†Ø¬, Ø¢Ø¯ÛŒÙ†Ù‡, Ø´Ù†Ø¨Ù‡]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Ú˜Ø§Ù†ÙˆÛŒÙ‡, ÙÙˆØ±ÛŒÙ‡, Ù…Ø§Ø±Ø³, Ø¢ÙˆØ±ÛŒÙ„, Ù…Ù‡, Ú˜ÙˆØ¦Ù†, Ú˜ÙˆØ¦ÛŒÙ‡, Ø§ÙˆØª, Ø³Ù¾ØªØ§Ù…Ø¨Ø±, Ø§Ú©ØªØ¨Ø±, Ù†ÙˆØ§Ù…Ø¨Ø±, Ø¯Ø³Ø§Ù…Ø¨Ø±]
+    abbr_month_names: [~, Ú˜Ø§Ù†, ÙÙˆØ±, Ù…Ø§Ø±, Ø¢ÙˆØ±, Ù…Ù‡, Ú˜ÙˆØ¦Ù†, Ú˜ÙˆØ¦ÛŒÙ‡, Ø§ÙˆØª, Ø³Ù¾Øª, Ø§Ú©Øª, Ù†ÙˆØ§, Ø¯Ø³Ø§]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%Y/%m/%d - %H:%M"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%d %B %Y Ø³Ø§Ø¹Øª %H:%M"
+    am: "ØµØ¨Ø­"
+    pm: "Ø¹ØµØ±"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "Ù†ÛŒÙ… Ø¯Ù‚ÛŒÙ‚Ù‡"
+      less_than_x_seconds:
+        one:   "Ú©Ù…ØªØ± Ø§Ø² 1 Ø«Ø§Ù†ÛŒÙ‡"
+        other: "Ú©Ù…ØªØ± Ø§Ø² %{count} Ø«Ø§Ù†ÛŒÙ‡"
+      x_seconds:
+        one:   "1 Ø«Ø§Ù†ÛŒÙ‡"
+        other: "%{count} Ø«Ø§Ù†ÛŒÙ‡"
+      less_than_x_minutes:
+        one:   "Ú©Ù…ØªØ± Ø§Ø² 1 Ø¯Ù‚ÛŒÙ‚Ù‡"
+        other: "Ú©Ù…ØªØ± Ø§Ø² %{count} Ø¯Ù‚ÛŒÙ‚Ù‡"
+      x_minutes:
+        one:   "1 Ø¯Ù‚ÛŒÙ‚Ù‡"
+        other: "%{count} Ø¯Ù‚ÛŒÙ‚Ù‡"
+      about_x_hours:
+        one:   "Ù†Ø²Ø¯ÛŒÚ© 1 Ø³Ø§Ø¹Øª"
+        other: "Ù†Ø²Ø¯ÛŒÚ© %{count} Ø³Ø§Ø¹Øª"
+      x_hours:
+        one:   "1 Ø³Ø§Ø¹Øª"
+        other: "%{count} Ø³Ø§Ø¹Øª"
+      x_days:
+        one:   "1 Ø±ÙˆØ²"
+        other: "%{count} Ø±ÙˆØ²"
+      about_x_months:
+        one:   "Ù†Ø²Ø¯ÛŒÚ© 1 Ù…Ø§Ù‡"
+        other: "Ù†Ø²Ø¯ÛŒÚ© %{count} Ù…Ø§Ù‡"
+      x_months:
+        one:   "1 Ù…Ø§Ù‡"
+        other: "%{count} Ù…Ø§Ù‡"
+      about_x_years:
+        one:   "Ù†Ø²Ø¯ÛŒÚ© 1 Ø³Ø§Ù„"
+        other: "Ù†Ø²Ø¯ÛŒÚ© %{count} Ø³Ø§Ù„"
+      over_x_years:
+        one:   "Ø¨ÛŒØ´ Ø§Ø² 1 Ø³Ø§Ù„"
+        other: "Ø¨ÛŒØ´ Ø§Ø² %{count} Ø³Ø§Ù„"
+      almost_x_years:
+        one:   "Ù†Ø²Ø¯ÛŒÚ© 1 Ø³Ø§Ù„"
+        other: "Ù†Ø²Ø¯ÛŒÚ© %{count} Ø³Ø§Ù„"
+
+  number:
+    # Default format for numbers
+    format:
+      separator: "Ù«"
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Ø¨Ø§ÛŒØª"
+            other: "Ø¨Ø§ÛŒØª"
+          kb: "Ú©ÛŒÙ„ÙˆØ¨Ø§ÛŒØª"
+          mb: "Ù…Ú¯Ø§Ø¨Ø§ÛŒØª"
+          gb: "Ú¯ÛŒÚ¯Ø§Ø¨Ø§ÛŒØª"
+          tb: "ØªØ±Ø§Ø¨Ø§ÛŒØª"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "Ùˆ"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 Ø§ÛŒØ±Ø§Ø¯ Ø§Ø² Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ Ø§ÛŒÙ† %{model} Ø¬Ù„ÙˆÚ¯ÛŒØ±ÛŒ Ú©Ø±Ø¯"
+          other:  "%{count} Ø§ÛŒØ±Ø§Ø¯ Ø§Ø² Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ Ø§ÛŒÙ† %{model} Ø¬Ù„ÙˆÚ¯ÛŒØ±ÛŒ Ú©Ø±Ø¯"
+      messages:
+        inclusion: "Ø¯Ø± ÙÙ‡Ø±Ø³Øª Ù†ÛŒØ§Ù…Ø¯Ù‡ Ø§Ø³Øª"
+        exclusion: "Ø±Ø²Ø±Ùˆ Ø´Ø¯Ù‡ Ø§Ø³Øª"
+        invalid: "Ù†Ø§Ø¯Ø±Ø³Øª Ø§Ø³Øª"
+        confirmation: "Ø¨Ø§ Ø¨Ø±Ø±Ø³ÛŒ Ø³Ø§Ø²Ú¯Ø§Ø±ÛŒ Ù†Ø¯Ø§Ø±Ø¯"
+        accepted: "Ø¨Ø§ÛŒØ¯ Ù¾Ø°ÛŒØ±ÙØªÙ‡ Ø´ÙˆØ¯"
+        empty: "Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ø¯ ØªÙ‡ÛŒ Ø¨Ø§Ø´Ø¯"
+        blank: "Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ø¯ ØªÙ‡ÛŒ Ø¨Ø§Ø´Ø¯"
+        too_long: "Ø®ÛŒÙ„ÛŒ Ø¨Ù„Ù†Ø¯ Ø§Ø³Øª (Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ %{count} Ù†ÙˆÛŒØ³Ù‡ Ø§Ø³Øª)"
+        too_short: "Ø®ÛŒÙ„ÛŒ Ú©ÙˆØªØ§Ù‡ Ø§Ø³Øª (Ú©Ù…ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ %{count} Ù†ÙˆÛŒØ³Ù‡ Ø§Ø³Øª)"
+        wrong_length: "Ø§Ù†Ø¯Ø§Ø²Ù‡ Ù†Ø§Ø¯Ø±Ø³Øª Ø§Ø³Øª (Ø¨Ø§ÛŒØ¯ %{count} Ù†ÙˆÛŒØ³Ù‡ Ø¨Ø§Ø´Ø¯)"
+        taken: "Ù¾ÛŒØ´ Ø§Ø² Ø§ÛŒÙ† Ú¯Ø±ÙØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª"
+        not_a_number: "Ø´Ù…Ø§Ø±Ù‡ Ø¯Ø±Ø³ØªÛŒ Ù†ÛŒØ³Øª"
+        not_a_date: "ØªØ§Ø±ÛŒØ® Ø¯Ø±Ø³ØªÛŒ Ù†ÛŒØ³Øª"
+        greater_than: "Ø¨Ø§ÛŒØ¯ Ø¨Ø²Ø±Ú¯ØªØ± Ø§Ø² %{count} Ø¨Ø§Ø´Ø¯"
+        greater_than_or_equal_to: "Ø¨Ø§ÛŒØ¯ Ø¨Ø²Ø±Ú¯ØªØ± Ø§Ø² ÛŒØ§ Ø¨Ø±Ø§Ø¨Ø± Ø¨Ø§ %{count} Ø¨Ø§Ø´Ø¯"
+        equal_to: "Ø¨Ø§ÛŒØ¯ Ø¨Ø±Ø§Ø¨Ø± Ø¨Ø§ %{count} Ø¨Ø§Ø´Ø¯"
+        less_than: "Ø¨Ø§ÛŒØ¯ Ú©Ù…ØªØ± Ø§Ø² %{count} Ø¨Ø§Ø´Ø¯"
+        less_than_or_equal_to: "Ø¨Ø§ÛŒØ¯ Ú©Ù…ØªØ± Ø§Ø² ÛŒØ§ Ø¨Ø±Ø§Ø¨Ø± Ø¨Ø§ %{count} Ø¨Ø§Ø´Ø¯"
+        odd: "Ø¨Ø§ÛŒØ¯ ÙØ±Ø¯ Ø¨Ø§Ø´Ø¯"
+        even: "Ø¨Ø§ÛŒØ¯ Ø²ÙˆØ¬ Ø¨Ø§Ø´Ø¯"
+        greater_than_start_date: "Ø¨Ø§ÛŒØ¯ Ø§Ø² ØªØ§Ø±ÛŒØ® Ø¢ØºØ§Ø² Ø¨Ø²Ø±Ú¯ØªØ± Ø¨Ø§Ø´Ø¯"
+        not_same_project: "Ø¨Ù‡ Ù‡Ù…Ø§Ù† Ù¾Ø±ÙˆÚ˜Ù‡ ÙˆØ§Ø¨Ø³ØªÙ‡ Ù†ÛŒØ³Øª"
+        circular_dependency: "Ø§ÛŒÙ† ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ ÛŒÚ© ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ Ø¯Ø§ÛŒØ±Ù‡ ÙˆØ§Ø± Ø®ÙˆØ§Ù‡Ø¯ Ø³Ø§Ø®Øª"
+        cant_link_an_issue_with_a_descendant: "ÛŒÚ© Ù¾ÛŒØ§Ù…Ø¯ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ø¯ Ø¨Ù‡ ÛŒÚ©ÛŒ Ø§Ø² Ø²ÛŒØ± Ú©Ø§Ø±Ù‡Ø§ÛŒØ´ Ù¾ÛŒÙˆÙ†Ø¯ Ø¨Ø®ÙˆØ±Ø¯"
+
+  actionview_instancetag_blank_option: Ú¯Ø²ÛŒÙ†Ø´ Ú©Ù†ÛŒØ¯
+
+  general_text_No: 'Ø®ÛŒØ±'
+  general_text_Yes: 'Ø¢Ø±ÛŒ'
+  general_text_no: 'Ø®ÛŒØ±'
+  general_text_yes: 'Ø¢Ø±ÛŒ'
+  general_lang_name: 'Persian (Ù¾Ø§Ø±Ø³ÛŒ)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '6'
+
+  notice_account_updated: Ø­Ø³Ø§Ø¨ Ø´Ù…Ø§ Ø¨Ø±ÙˆØ² Ø´Ø¯.
+  notice_account_invalid_creditentials: Ù†Ø§Ù… Ú©Ø§Ø±Ø¨Ø±ÛŒ ÛŒØ§ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ù†Ø§Ø¯Ø±Ø³Øª Ø§Ø³Øª
+  notice_account_password_updated: Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ø¨Ø±ÙˆØ² Ø´Ø¯
+  notice_account_wrong_password: Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ù†Ø§Ø¯Ø±Ø³Øª Ø§Ø³Øª
+  notice_account_register_done: Ø­Ø³Ø§Ø¨ Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯. Ø¨Ø±Ø§ÛŒ ÙØ¹Ø§Ù„ Ù†Ù…ÙˆØ¯Ù† Ø¢Ù†ØŒ Ø±ÙˆÛŒ Ù¾ÛŒÙˆÙ†Ø¯ÛŒ Ú©Ù‡ Ø¨Ù‡ Ø´Ù…Ø§ Ø§ÛŒÙ…ÛŒÙ„ Ø´Ø¯Ù‡ Ú©Ù„ÛŒÚ© Ú©Ù†ÛŒØ¯.
+  notice_account_unknown_email: Ú©Ø§Ø±Ø¨Ø± Ø´Ù†Ø§Ø®ØªÙ‡ Ù†Ø´Ø¯.
+  notice_can_t_change_password:  Ø§ÛŒÙ† Ø­Ø³Ø§Ø¨ ÛŒÚ© Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ Ø¨ÛŒØ±ÙˆÙ†ÛŒ Ø±Ø§ Ø¨Ù‡ Ú©Ø§Ø± Ú¯Ø±ÙØªÙ‡ Ø§Ø³Øª. Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ† Ú©Ø±Ø¯.
+  notice_account_lost_email_sent: ÛŒÚ© Ø§ÛŒÙ…ÛŒÙ„ Ø¨Ø§ Ø±Ø§Ù‡Ù†Ù…Ø§ÛŒÛŒ Ø¯Ø±Ø¨Ø§Ø±Ù‡ Ú¯Ø²ÛŒÙ†Ø´ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ ØªØ§Ø²Ù‡ Ø¨Ø±Ø§ÛŒ Ø´Ù…Ø§ ÙØ±Ø³ØªØ§Ø¯Ù‡ Ø´Ø¯.
+  notice_account_activated: Ø­Ø³Ø§Ø¨ Ø´Ù…Ø§ ÙØ¹Ø§Ù„ Ø´Ø¯Ù‡ Ø§Ø³Øª. Ø§Ú©Ù†ÙˆÙ† Ù…ÛŒâ€ŒØªÙˆØ§Ù†ÛŒØ¯ ÙˆØ§Ø±Ø¯ Ø´ÙˆÛŒØ¯.
+  notice_successful_create: Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯.
+  notice_successful_update: Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ø¨Ø±ÙˆØ² Ø´Ø¯.
+  notice_successful_delete: Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ø¨Ø±Ø¯Ø§Ø´ØªÙ‡ Ø´Ø¯.
+  notice_successful_connection: Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ù…ØªØµÙ„ Ø´Ø¯.
+  notice_file_not_found: Ø¨Ø±Ú¯Ù‡ Ø¯Ø±Ø®ÙˆØ§Ø³ØªÛŒ Ø´Ù…Ø§ Ø¯Ø± Ø¯Ø³ØªØ±Ø³ Ù†ÛŒØ³Øª ÛŒØ§ Ù¾Ø§Ú© Ø´Ø¯Ù‡ Ø§Ø³Øª.
+  notice_locking_conflict: Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ Ø±Ø§ Ú©Ø§Ø±Ø¨Ø± Ø¯ÛŒÚ¯Ø±ÛŒ Ø¨Ø±ÙˆØ² Ú©Ø±Ø¯Ù‡ Ø§Ø³Øª.
+  notice_not_authorized: Ø´Ù…Ø§ Ø¨Ù‡ Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡ Ø¯Ø³ØªØ±Ø³ÛŒ Ù†Ø¯Ø§Ø±ÛŒØ¯.
+  notice_not_authorized_archived_project: Ù¾Ø±ÙˆÚ˜Ù‡ Ø¯Ø±Ø®ÙˆØ§Ø³ØªÛŒ Ø´Ù…Ø§ Ø¨Ø§ÛŒÚ¯Ø§Ù†ÛŒ Ø´Ø¯Ù‡ Ø§Ø³Øª.
+  notice_email_sent: "ÛŒÚ© Ø§ÛŒÙ…ÛŒÙ„ Ø¨Ù‡ %{value} ÙØ±Ø³ØªØ§Ø¯Ù‡ Ø´Ø¯."
+  notice_email_error: "ÛŒÚ© Ø§ÛŒØ±Ø§Ø¯ Ø¯Ø± ÙØ±Ø³ØªØ§Ø¯Ù† Ø§ÛŒÙ…ÛŒÙ„ Ù¾ÛŒØ´ Ø¢Ù…Ø¯ (%{value})."
+  notice_feeds_access_key_reseted: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ RSS Ø´Ù…Ø§ Ø¨Ø§Ø²Ù†Ø´Ø§Ù†ÛŒ Ø´Ø¯.
+  notice_api_access_key_reseted: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ API Ø´Ù…Ø§ Ø¨Ø§Ø²Ù†Ø´Ø§Ù†ÛŒ Ø´Ø¯.
+  notice_failed_to_save_issues: "Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ %{count} Ù¾ÛŒØ§Ù…Ø¯ Ø§Ø² %{total} Ù¾ÛŒØ§Ù…Ø¯ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡ Ø´Ú©Ø³Øª Ø®ÙˆØ±Ø¯: %{ids}."
+  notice_failed_to_save_members: "Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ Ø§Ø¹Ø¶Ø§ Ø´Ú©Ø³Øª Ø®ÙˆØ±Ø¯: %{errors}."
+  notice_no_issue_selected: "Ù‡ÛŒÚ† Ù¾ÛŒØ§Ù…Ø¯ÛŒ Ø¨Ø±Ú¯Ø²ÛŒØ¯Ù‡ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª! Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ ÙˆÛŒØ±Ø§ÛŒØ´ Ú©Ù†ÛŒØ¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯."
+  notice_account_pending: "Ø­Ø³Ø§Ø¨ Ø´Ù…Ø§ Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯ Ùˆ Ø§Ú©Ù†ÙˆÙ† Ú†Ø´Ù… Ø¨Ù‡ Ø±Ø§Ù‡ Ø±ÙˆØ§Ø¯ÛŒØ¯ Ø³Ø±Ù¾Ø±Ø³Øª Ø§Ø³Øª."
+  notice_default_data_loaded: Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ø¨Ø§Ø± Ø´Ø¯.
+  notice_unable_delete_version: Ù†Ú¯Ø§Ø±Ø´ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù¾Ø§Ú© Ú©Ø±Ø¯.
+  notice_unable_delete_time_entry: Ø²Ù…Ø§Ù† Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù¾Ø§Ú© Ú©Ø±Ø¯.
+  notice_issue_done_ratios_updated: Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡ Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø±ÙˆØ² Ø´Ø¯.
+  notice_gantt_chart_truncated: "Ù†Ù…ÙˆØ¯Ø§Ø± Ø¨Ø±ÛŒØ¯Ù‡ Ø´Ø¯ Ú†ÙˆÙ† Ø§Ø² Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø´Ù…Ø§Ø±ÛŒ Ú©Ù‡ Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù†Ø´Ø§Ù† Ø¯Ø§Ø¯ Ø¨Ø²Ú¯ØªØ± Ø§Ø³Øª (%{max})."
+
+  error_can_t_load_default_data: "Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ø¯ Ø¨Ø§Ø± Ø´ÙˆØ¯: %{value}"
+  error_scm_not_found: "Ø¨Ø®Ø´ ÛŒØ§ Ù†Ú¯Ø§Ø±Ø´ Ø¯Ø± Ø§Ù†Ø¨Ø§Ø±Ù‡ Ù¾ÛŒØ¯Ø§ Ù†Ø´Ø¯."
+  error_scm_command_failed: "Ø§ÛŒØ±Ø§Ø¯ÛŒ Ø¯Ø± Ø¯Ø³ØªØ±Ø³ÛŒ Ø¨Ù‡ Ø§Ù†Ø¨Ø§Ø±Ù‡ Ù¾ÛŒØ´ Ø¢Ù…Ø¯: %{value}"
+  error_scm_annotate: "Ø¨Ø®Ø´ Ù¾ÛŒØ¯Ø§ Ù†Ø´Ø¯ ÛŒØ§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¨Ø±Ø§ÛŒ Ø¢Ù† ÛŒØ§Ø¯Ø¯Ø§Ø´Øª Ù†ÙˆØ´Øª."
+  error_issue_not_found_in_project: 'Ù¾ÛŒØ§Ù…Ø¯ Ù¾ÛŒØ¯Ø§ Ù†Ø´Ø¯ ÛŒØ§ Ø¨Ù‡ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ ÙˆØ§Ø¨Ø³ØªÙ‡ Ù†ÛŒØ³Øª.'
+  error_no_tracker_in_project: 'Ù‡ÛŒÚ† Ù¾ÛŒÚ¯Ø±Ø¯ÛŒ Ø¨Ù‡ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ Ù¾ÛŒÙˆØ³ØªÙ‡ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª. Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡ Ø±Ø§ Ø¨Ø±Ø±Ø³ÛŒ Ú©Ù†ÛŒØ¯.'
+  error_no_default_issue_status: 'Ù‡ÛŒÚ† ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡â€ŒØ§ÛŒ Ù…Ø´Ø®Øµ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª. Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ø±Ø§ Ø¨Ø±Ø±Ø³ÛŒ Ú©Ù†ÛŒØ¯ (Ø¨Ù‡ Â«Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ -> ÙˆØ¶Ø¹ÛŒØªâ€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯Â» Ø¨Ø±ÙˆÛŒØ¯).'
+  error_can_not_delete_custom_field: ÙÛŒÙ„Ø¯ Ø³ÙØ§Ø±Ø´ÛŒ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù¾Ø§Ú© Ú©Ø±Ø¯.
+  error_can_not_delete_tracker: "Ø§ÛŒÙ† Ù¾ÛŒÚ¯Ø±Ø¯ Ø¯Ø§Ø±Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯ Ø§Ø³Øª Ùˆ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¢Ù† Ø±Ø§ Ù¾Ø§Ú© Ú©Ø±Ø¯."
+  error_can_not_remove_role: "Ø§ÛŒÙ† Ù†Ù‚Ø´ Ø¨Ù‡ Ú©Ø§Ø± Ú¯Ø±ÙØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª Ùˆ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¢Ù† Ø±Ø§ Ù¾Ø§Ú© Ú©Ø±Ø¯."
+  error_can_not_reopen_issue_on_closed_version: 'ÛŒÚ© Ù¾ÛŒØ§Ù…Ø¯ Ú©Ù‡ Ø¨Ù‡ ÛŒÚ© Ù†Ú¯Ø§Ø±Ø´ Ø¨Ø³ØªÙ‡ Ø´Ø¯Ù‡ ÙˆØ§Ø¨Ø³ØªÙ‡ Ø§Ø³Øª Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¨Ø§Ø² Ú©Ø±Ø¯.'
+  error_can_not_archive_project: Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¨Ø§ÛŒÚ¯Ø§Ù†ÛŒ Ú©Ø±Ø¯.
+  error_issue_done_ratios_not_updated: "Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡ Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø±ÙˆØ² Ù†Ø´Ø¯."
+  error_workflow_copy_source: 'ÛŒÚ© Ù¾ÛŒÚ¯Ø±Ø¯ ÛŒØ§ Ù†Ù‚Ø´ Ù…Ù†Ø¨Ø¹ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯.'
+  error_workflow_copy_target: 'Ù¾ÛŒÚ¯Ø±Ø¯Ù‡Ø§ ÛŒØ§ Ù†Ù‚Ø´â€ŒÙ‡Ø§ÛŒ Ù…Ù‚ØµØ¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯.'
+  error_unable_delete_issue_status: 'ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù¾Ø§Ú© Ú©Ø±Ø¯.'
+  error_unable_to_connect: "Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù…ØªØµÙ„ Ø´Ø¯ (%{value})"
+  warning_attachments_not_saved: "%{count} Ù¾Ø±ÙˆÙ†Ø¯Ù‡ Ø°Ø®ÛŒØ±Ù‡ Ù†Ø´Ø¯."
+
+  mail_subject_lost_password: "Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ø­Ø³Ø§Ø¨ %{value} Ø´Ù…Ø§"
+  mail_body_lost_password: 'Ø¨Ø±Ø§ÛŒ Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ†ÛŒ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ø®ÙˆØ¯ØŒ Ø¨Ø± Ø±ÙˆÛŒ Ù¾ÛŒÙˆÙ†Ø¯ Ø²ÛŒØ± Ú©Ù„ÛŒÚ© Ú©Ù†ÛŒØ¯:'
+  mail_subject_register: "ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ %{value} Ø´Ù…Ø§"
+  mail_body_register: 'Ø¨Ø±Ø§ÛŒ ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ Ø®ÙˆØ¯ØŒ Ø¨Ø± Ø±ÙˆÛŒ Ù¾ÛŒÙˆÙ†Ø¯ Ø²ÛŒØ± Ú©Ù„ÛŒÚ© Ú©Ù†ÛŒØ¯:'
+  mail_body_account_information_external: "Ø´Ù…Ø§ Ù…ÛŒâ€ŒØªÙˆØ§Ù†ÛŒØ¯ Ø­Ø³Ø§Ø¨ %{value} Ø®ÙˆØ¯ Ø±Ø§ Ø¨Ø±Ø§ÛŒ ÙˆØ±ÙˆØ¯ Ø¨Ù‡ Ú©Ø§Ø± Ø¨Ø±ÛŒØ¯."
+  mail_body_account_information: Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ø­Ø³Ø§Ø¨ Ø´Ù…Ø§
+  mail_subject_account_activation_request: "Ø¯Ø±Ø®ÙˆØ§Ø³Øª ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ %{value}"
+  mail_body_account_activation_request: "ÛŒÚ© Ú©Ø§Ø±Ø¨Ø± ØªØ§Ø²Ù‡ (%{value}) Ù†Ø§Ù…Ù†ÙˆÛŒØ³ÛŒ Ú©Ø±Ø¯Ù‡ Ø§Ø³Øª. Ø§ÛŒÙ† Ø­Ø³Ø§Ø¨ Ú†Ø´Ù… Ø¨Ù‡ Ø±Ø§Ù‡ Ø±ÙˆØ§Ø¯ÛŒØ¯ Ø´Ù…Ø§Ø³Øª:"
+  mail_subject_reminder: "Ø²Ù…Ø§Ù† Ø±Ø³ÛŒØ¯Ú¯ÛŒ Ø¨Ù‡ %{count} Ù¾ÛŒØ§Ù…Ø¯ Ø¯Ø± %{days} Ø±ÙˆØ² Ø¢ÛŒÙ†Ø¯Ù‡ Ø³Ø± Ù…ÛŒâ€ŒØ±Ø³Ø¯"
+  mail_body_reminder: "Ø²Ù…Ø§Ù† Ø±Ø³ÛŒØ¯Ú¯ÛŒ Ø¨Ù‡ %{count} Ù¾ÛŒØ§Ù…Ø¯ Ú©Ù‡ Ø¨Ù‡ Ø´Ù…Ø§ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡ Ø§Ø³ØªØŒ Ø¯Ø± %{days} Ø±ÙˆØ² Ø¢ÛŒÙ†Ø¯Ù‡ Ø³Ø± Ù…ÛŒâ€ŒØ±Ø³Ø¯:"
+  mail_subject_wiki_content_added: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯"
+  mail_body_wiki_content_added: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯."
+  mail_subject_wiki_content_updated: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø¨Ø±ÙˆØ² Ø´Ø¯"
+  mail_body_wiki_content_updated: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø¨Ø±ÙˆØ² Ø´Ø¯."
+
+
+  field_name: Ù†Ø§Ù…
+  field_description: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
+  field_summary: Ø®Ù„Ø§ØµÙ‡
+  field_is_required: Ø§Ù„Ø²Ø§Ù…ÛŒ
+  field_firstname: Ù†Ø§Ù… Ú©ÙˆÚ†Ú©
+  field_lastname: Ù†Ø§Ù… Ø®Ø§Ù†ÙˆØ§Ø¯Ú¯ÛŒ
+  field_mail: Ø§ÛŒÙ…ÛŒÙ„
+  field_filename: Ù¾Ø±ÙˆÙ†Ø¯Ù‡
+  field_filesize: Ø§Ù†Ø¯Ø§Ø²Ù‡
+  field_downloads: Ø¯Ø±ÛŒØ§ÙØªâ€ŒÙ‡Ø§
+  field_author: Ù†ÙˆÛŒØ³Ù†Ø¯Ù‡
+  field_created_on: Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯Ù‡ Ø¯Ø±
+  field_updated_on: Ø¨Ø±ÙˆØ² Ø´Ø¯Ù‡ Ø¯Ø±
+  field_field_format: Ù‚Ø§Ù„Ø¨
+  field_is_for_all: Ø¨Ø±Ø§ÛŒ Ù‡Ù…Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
+  field_possible_values: Ù…Ù‚Ø§Ø¯ÛŒØ± Ù…Ù…Ú©Ù†
+  field_regexp: Ø¹Ø¨Ø§Ø±Øª Ù…Ù†Ø¸Ù…
+  field_min_length: Ú©Ù…ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡
+  field_max_length: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡
+  field_value: Ù…Ù‚Ø¯Ø§Ø±
+  field_category: Ø¯Ø³ØªÙ‡
+  field_title: Ø¹Ù†ÙˆØ§Ù†
+  field_project: Ù¾Ø±ÙˆÚ˜Ù‡
+  field_issue: Ù¾ÛŒØ§Ù…Ø¯
+  field_status: ÙˆØ¶Ø¹ÛŒØª
+  field_notes: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
+  field_is_closed: Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø³ØªÙ‡ Ø´Ø¯Ù‡
+  field_is_default: Ù…Ù‚Ø¯Ø§Ø± Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
+  field_tracker: Ù¾ÛŒÚ¯Ø±Ø¯
+  field_subject: Ù…ÙˆØ¶ÙˆØ¹
+  field_due_date: Ø²Ù…Ø§Ù† Ø³Ø±Ø±Ø³ÛŒØ¯
+  field_assigned_to: ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡ Ø¨Ù‡
+  field_priority: Ø¨Ø±ØªØ±ÛŒ
+  field_fixed_version: Ù†Ú¯Ø§Ø±Ø´ Ù‡Ø¯Ù
+  field_user: Ú©Ø§Ø±Ø¨Ø±
+  field_principal: Ø¯Ø³ØªÙˆØ± Ø¯Ù‡Ù†Ø¯Ù‡
+  field_role: Ù†Ù‚Ø´
+  field_homepage: Ø¨Ø±Ú¯Ù‡ Ø®Ø§Ù†Ù‡
+  field_is_public: Ù‡Ù…Ú¯Ø§Ù†ÛŒ
+  field_parent: Ù¾Ø±ÙˆÚ˜Ù‡ Ù¾Ø¯Ø±
+  field_is_in_roadmap: Ø§ÛŒÙ† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ø¯Ø± Ú†Ø´Ù…â€ŒØ§Ù†Ø¯Ø§Ø² Ù†Ø´Ø§Ù† Ø¯Ø§Ø¯Ù‡ Ø´ÙˆÙ†Ø¯
+  field_login: ÙˆØ±ÙˆØ¯
+  field_mail_notification: Ø¢Ú¯Ø§Ù‡ Ø³Ø§Ø²ÛŒâ€ŒÙ‡Ø§ÛŒ Ø§ÛŒÙ…ÛŒÙ„ÛŒ
+  field_admin: Ø³Ø±Ù¾Ø±Ø³Øª
+  field_last_login_on: Ø¢Ø®Ø±ÛŒÙ† ÙˆØ±ÙˆØ¯
+  field_language: Ø²Ø¨Ø§Ù†
+  field_effective_date: ØªØ§Ø±ÛŒØ®
+  field_password: Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
+  field_new_password: Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ ØªØ§Ø²Ù‡
+  field_password_confirmation: Ø¨Ø±Ø±Ø³ÛŒ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
+  field_version: Ù†Ú¯Ø§Ø±Ø´
+  field_type: Ú¯ÙˆÙ†Ù‡
+  field_host: Ù…ÛŒØ²Ø¨Ø§Ù†
+  field_port: Ø¯Ø±Ú¯Ø§Ù‡
+  field_account: Ø­Ø³Ø§Ø¨
+  field_base_dn: DN Ù¾Ø§ÛŒÙ‡
+  field_attr_login: Ù†Ø´Ø§Ù†Ù‡ ÙˆØ±ÙˆØ¯
+  field_attr_firstname: Ù†Ø´Ø§Ù†Ù‡ Ù†Ø§Ù… Ú©ÙˆÚ†Ú©
+  field_attr_lastname: Ù†Ø´Ø§Ù†Ù‡ Ù†Ø§Ù… Ø®Ø§Ù†ÙˆØ§Ø¯Ú¯ÛŒ
+  field_attr_mail: Ù†Ø´Ø§Ù†Ù‡ Ø§ÛŒÙ…ÛŒÙ„
+  field_onthefly: Ø³Ø§Ø®Øª Ú©Ø§Ø±Ø¨Ø± Ø¨ÛŒØ¯Ø±Ù†Ú¯
+  field_start_date: ØªØ§Ø±ÛŒØ® Ø¢ØºØ§Ø²
+  field_done_ratio: Ùª Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡
+  field_auth_source: Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ
+  field_hide_mail: Ø§ÛŒÙ…ÛŒÙ„ Ù…Ù† Ù¾Ù†Ù‡Ø§Ù† Ø´ÙˆØ¯
+  field_comments: Ø¯ÛŒØ¯Ú¯Ø§Ù‡
+  field_url: Ù†Ø´Ø§Ù†ÛŒ
+  field_start_page: Ø¨Ø±Ú¯Ù‡ Ø¢ØºØ§Ø²
+  field_subproject: Ø²ÛŒØ± Ù¾Ø±ÙˆÚ˜Ù‡
+  field_hours: Ø³Ø§Ø¹Øªâ€Œ
+  field_activity: Ú¯Ø²Ø§Ø±Ø´
+  field_spent_on: Ø¯Ø± ØªØ§Ø±ÛŒØ®
+  field_identifier: Ø´Ù†Ø§Ø³Ù‡
+  field_is_filter: Ù¾Ø§Ù„Ø§ÛŒØ´ Ù¾Ø°ÛŒØ±
+  field_issue_to: Ù¾ÛŒØ§Ù…Ø¯ ÙˆØ§Ø¨Ø³ØªÙ‡
+  field_delay: Ø¯ÛŒØ±Ú©Ø±Ø¯
+  field_assignable: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ù†Ø¯ Ø¨Ù‡ Ø§ÛŒÙ† Ù†Ù‚Ø´ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯
+  field_redirect_existing_links: Ù¾ÛŒÙˆÙ†Ø¯Ù‡Ø§ÛŒ Ù¾ÛŒØ´ÛŒÙ†  Ø¨Ù‡ Ù¾ÛŒÙˆÙ†Ø¯ ØªØ§Ø²Ù‡ Ø±Ø§Ù‡Ù†Ù…Ø§ÛŒÛŒ Ø´ÙˆÙ†Ø¯
+  field_estimated_hours: Ø²Ù…Ø§Ù† Ø¨Ø±Ø¢ÙˆØ±Ø¯ Ø´Ø¯Ù‡
+  field_column_names: Ø³ØªÙˆÙ†â€ŒÙ‡Ø§
+  field_time_entries: Ø²Ù…Ø§Ù† Ù†ÙˆØ´ØªÙ†
+  field_time_zone: Ù¾Ù‡Ù†Ù‡ Ø²Ù…Ø§Ù†ÛŒ
+  field_searchable: Ø¬Ø³ØªØ¬Ùˆ Ù¾Ø°ÛŒØ±
+  field_default_value: Ù…Ù‚Ø¯Ø§Ø± Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
+  field_comments_sorting: Ù†Ù…Ø§ÛŒØ´ Ø¯ÛŒØ¯Ú¯Ø§Ù‡â€ŒÙ‡Ø§
+  field_parent_title: Ø¨Ø±Ú¯Ù‡ Ù¾Ø¯Ø±
+  field_editable: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾Ø°ÛŒØ±
+  field_watcher: Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†
+  field_identity_url: Ù†Ø´Ø§Ù†ÛŒ OpenID
+  field_content: Ù…Ø­ØªÙˆØ§
+  field_group_by: Ø¯Ø³ØªÙ‡ Ø¨Ù†Ø¯ÛŒ Ø¨Ø§
+  field_sharing: Ø§Ø´ØªØ±Ø§Ú© Ú¯Ø°Ø§Ø±ÛŒ
+  field_parent_issue: Ú©Ø§Ø± Ù¾Ø¯Ø±
+  field_member_of_group: "Ø¯Ø³ØªÙ‡ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯Ù‡"
+  field_assigned_to_role: "Ù†Ù‚Ø´ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯Ù‡"
+  field_text: ÙÛŒÙ„Ø¯ Ù…ØªÙ†ÛŒ
+  field_visible: Ø¢Ø´Ú©Ø§Ø±
+
+  setting_app_title: Ù†Ø§Ù… Ø¨Ø±Ù†Ø§Ù…Ù‡
+  setting_app_subtitle: Ø²ÛŒØ±Ù†Ø§Ù… Ø¨Ø±Ù†Ø§Ù…Ù‡
+  setting_welcome_text: Ù†ÙˆØ´ØªØ§Ø± Ø®ÙˆØ´â€ŒØ¢Ù…Ø¯ Ú¯ÙˆÛŒÛŒ
+  setting_default_language: Ø²Ø¨Ø§Ù† Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
+  setting_login_required: Ø§Ù„Ø²Ø§Ù…ÛŒ Ø¨ÙˆØ¯Ù† ÙˆØ±ÙˆØ¯
+  setting_self_registration: Ø®ÙˆØ¯ Ù†Ø§Ù… Ù†ÙˆÛŒØ³ÛŒ
+  setting_attachment_max_size: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ù¾ÛŒÙˆØ³Øª
+  setting_issues_export_limit: Ú©Ø±Ø§Ù†Ù‡ ØµØ¯ÙˆØ± Ù¾ÛŒÛŒØ§Ù…Ø¯Ù‡Ø§
+  setting_mail_from: Ù†Ø´Ø§Ù†ÛŒ ÙØ±Ø³ØªÙ†Ø¯Ù‡ Ø§ÛŒÙ…ÛŒÙ„
+  setting_bcc_recipients: Ú¯ÛŒØ±Ù†Ø¯Ú¯Ø§Ù† Ø§ÛŒÙ…ÛŒÙ„ Ø¯ÛŒØ¯Ù‡ Ù†Ø´ÙˆÙ†Ø¯ (bcc)
+  setting_plain_text_mail: Ø§ÛŒÙ…ÛŒÙ„ Ù†ÙˆØ´ØªÙ‡ Ø³Ø§Ø¯Ù‡ (Ø¨Ø¯ÙˆÙ† HTML)
+  setting_host_name: Ù†Ø§Ù… Ù…ÛŒØ²Ø¨Ø§Ù† Ùˆ Ù†Ø´Ø§Ù†ÛŒ
+  setting_text_formatting: Ù‚Ø§Ù„Ø¨ Ø¨Ù†Ø¯ÛŒ Ù†ÙˆØ´ØªÙ‡
+  setting_wiki_compression: ÙØ´Ø±Ø¯Ù‡â€ŒØ³Ø§Ø²ÛŒ Ù¾ÛŒØ´ÛŒÙ†Ù‡ ÙˆÛŒÚ©ÛŒ
+  setting_feeds_limit: Ú©Ø±Ø§Ù†Ù‡ Ù…Ø­ØªÙˆØ§ÛŒ Ø®ÙˆØ±Ø§Ú©
+  setting_default_projects_public: Ø­Ø§Ù„Øª Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ ØªØ§Ø²Ù‡ØŒ Ù‡Ù…Ú¯Ø§Ù†ÛŒ Ø§Ø³Øª
+  setting_autofetch_changesets: Ø¯Ø±ÛŒØ§ÙØª Ø®ÙˆØ¯Ú©Ø§Ø± ØªØºÛŒÛŒØ±Ø§Øª
+  setting_sys_api_enabled: ÙØ¹Ø§Ù„ Ø³Ø§Ø²ÛŒ ÙˆØ¨ Ø³Ø±ÙˆÛŒØ³ Ø¨Ø±Ø§ÛŒ Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡
+  setting_commit_ref_keywords: Ú©Ù„ÛŒØ¯ÙˆØ§Ú˜Ù‡â€ŒÙ‡Ø§ÛŒ Ù†Ø´Ø§Ù†Ù‡
+  setting_commit_fix_keywords: Ú©Ù„ÛŒØ¯ÙˆØ§Ú˜Ù‡â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¬Ø§Ù…
+  setting_autologin: ÙˆØ±ÙˆØ¯ Ø®ÙˆØ¯Ú©Ø§Ø±
+  setting_date_format: Ù‚Ø§Ù„Ø¨ ØªØ§Ø±ÛŒØ®
+  setting_time_format: Ù‚Ø§Ù„Ø¨ Ø²Ù…Ø§Ù†
+  setting_cross_project_issue_relations: ØªÙˆØ§Ù†Ø§ÛŒÛŒ ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ Ù…ÛŒØ§Ù† Ù¾Ø±ÙˆÚ˜Ù‡â€ŒØ§ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  setting_issue_list_default_columns: Ø³ØªÙˆÙ†â€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø± ÙÙ‡Ø±Ø³Øª Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  setting_emails_header: Ø³Ø±Ù†ÙˆÛŒØ³ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§
+  setting_emails_footer: Ù¾Ø§Ù†ÙˆÛŒØ³ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§
+  setting_protocol: Ù¾ÛŒÙˆÙ†Ø¯Ù†Ø§Ù…Ù‡
+  setting_per_page_options: Ú¯Ø²ÛŒÙ†Ù‡â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ù‡Ø± Ø¨Ø±Ú¯
+  setting_user_format: Ù‚Ø§Ù„Ø¨ Ù†Ù…Ø§ÛŒØ´ÛŒ Ú©Ø§Ø±Ø¨Ø±Ø§Ù†
+  setting_activity_days_default: Ø±ÙˆØ²Ù‡Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø± Ú¯Ø²Ø§Ø±Ø´ Ù¾Ø±ÙˆÚ˜Ù‡
+  setting_display_subprojects_issues: Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ù†Ù…Ø§ÛŒØ´ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡ Ø¯Ø± Ù¾Ø±ÙˆÚ˜Ù‡ Ù¾Ø¯Ø±
+  setting_enabled_scm: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ SCM
+  setting_mail_handler_body_delimiters: "Ø¨Ø±ÛŒØ¯Ù† Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ Ù¾Ø³ Ø§Ø² ÛŒÚ©ÛŒ Ø§Ø² Ø§ÛŒÙ† Ø±Ø¯ÛŒÙâ€ŒÙ‡Ø§"
+  setting_mail_handler_api_enabled: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ ÙˆØ¨ Ø³Ø±ÙˆÛŒØ³ Ø¨Ø±Ø§ÛŒ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ÛŒ Ø¢Ù…Ø¯Ù‡
+  setting_mail_handler_api_key: Ú©Ù„ÛŒØ¯ API
+  setting_sequential_project_identifiers: Ø³Ø§Ø®Øª Ù¾Ø´Øª Ø³Ø± Ù‡Ù… Ø´Ù†Ø§Ø³Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡
+  setting_gravatar_enabled: Ú©Ø§Ø±Ø¨Ø±Ø¯ Gravatar Ø¨Ø±Ø§ÛŒ Ø¹Ú©Ø³ Ú©Ø§Ø±Ø¨Ø±
+  setting_gravatar_default: Ø¹Ú©Ø³ Gravatar Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
+  setting_diff_max_lines_displayed: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø±Ø¯ÛŒÙâ€ŒÙ‡Ø§ÛŒ ØªÙØ§ÙˆØª Ù†Ø´Ø§Ù† Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡
+  setting_file_max_size_displayed: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø±ÙˆÙ† Ø®Ø·ÛŒ
+  setting_repository_log_display_limit: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø´Ù…Ø§Ø± Ù†Ú¯Ø§Ø±Ø´â€ŒÙ‡Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø± Ú¯Ø²Ø§Ø±Ø´ Ù¾Ø±ÙˆÙ†Ø¯Ù‡
+  setting_openid: Ù¾Ø°ÛŒØ±Ø´ ÙˆØ±ÙˆØ¯ Ùˆ Ù†Ø§Ù… Ù†ÙˆÛŒØ³ÛŒ Ø¨Ø§ OpenID
+  setting_password_min_length: Ú©Ù…ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
+  setting_new_project_user_role_id: Ù†Ù‚Ø´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¨Ù‡ Ú©Ø§Ø±Ø¨Ø±ÛŒ Ú©Ù‡ Ø³Ø±Ù¾Ø±Ø³Øª Ù†ÛŒØ³Øª Ùˆ Ù¾Ø±ÙˆÚ˜Ù‡ Ù…ÛŒâ€ŒØ³Ø§Ø²Ø¯
+  setting_default_projects_modules: Ù¾ÛŒÙ…Ø§Ù†Ù‡â€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ ÙØ¹Ø§Ù„ Ø¨Ø±Ø§ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ ØªØ§Ø²Ù‡
+  setting_issue_done_ratio: Ø¨Ø±Ø¢ÙˆØ±Ø¯ Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡ Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø§
+  setting_issue_done_ratio_issue_field: Ú©Ø§Ø±Ø¨Ø±Ø¯ ÙÛŒÙ„Ø¯ Ù¾ÛŒØ§Ù…Ø¯
+  setting_issue_done_ratio_issue_status: Ú©Ø§Ø±Ø¨Ø±Ø¯ ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯
+  setting_start_of_week: Ø¢ØºØ§Ø² Ú¯Ø§Ù‡Ø´Ù…Ø§Ø± Ø§Ø²
+  setting_rest_api_enabled: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ ÙˆØ¨ Ø³Ø±ÙˆÛŒØ³â€ŒÙ‡Ø§ÛŒ REST
+  setting_cache_formatted_text: Ù†Ù‡Ø§Ù† Ø³Ø§Ø²ÛŒ Ù†ÙˆØ´ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ù‚Ø§Ù„Ø¨ Ø¨Ù†Ø¯ÛŒ Ø´Ø¯Ù‡
+  setting_default_notification_option: Ø¢Ú¯Ø§Ù‡ Ø³Ø§Ø²ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
+  setting_commit_logtime_enabled: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
+  setting_commit_logtime_activity_id: Ú©Ø§Ø± Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
+  setting_gantt_items_limit: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø´Ù…Ø§Ø± Ø¨Ø®Ø´â€ŒÙ‡Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø± Ù†Ù…ÙˆØ¯Ø§Ø± Ú¯Ø§Ù†Øª
+
+  permission_add_project: Ø³Ø§Ø®Øª Ù¾Ø±ÙˆÚ˜Ù‡
+  permission_add_subprojects: Ø³Ø§Ø®Øª Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡
+  permission_edit_project: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾Ø±ÙˆÚ˜Ù‡
+  permission_select_project_modules: Ú¯Ø²ÛŒÙ†Ø´ Ù¾ÛŒÙ…Ø§Ù†Ù‡â€ŒÙ‡Ø§ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡
+  permission_manage_members: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø§Ø¹Ø¶Ø§
+  permission_manage_project_activities: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ú©Ø§Ø±Ù‡Ø§ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡
+  permission_manage_versions: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù†Ú¯Ø§Ø±Ø´â€ŒÙ‡Ø§
+  permission_manage_categories: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø¯Ø³ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯
+  permission_view_issues: Ø¯ÛŒØ¯Ù† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  permission_add_issues: Ø§ÙØ²ÙˆØ¯Ù† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  permission_edit_issues: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  permission_manage_issue_relations: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  permission_add_issue_notes: Ø§ÙØ²ÙˆØ¯Ù† ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
+  permission_edit_issue_notes: ÙˆÛŒØ±Ø§ÛŒØ´ ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
+  permission_edit_own_issue_notes: ÙˆÛŒØ±Ø§ÛŒØ´ ÛŒØ§Ø¯Ø¯Ø§Ø´Øª Ø®ÙˆØ¯
+  permission_move_issues: Ø¬Ø§Ø¨Ø¬Ø§ÛŒÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  permission_delete_issues: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  permission_manage_public_queries: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÙ‡Ø§ÛŒ Ù‡Ù…Ú¯Ø§Ù†ÛŒ
+  permission_save_queries: Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÙ‡Ø§
+  permission_view_gantt: Ø¯ÛŒØ¯Ù† Ù†Ù…ÙˆØ¯Ø§Ø± Ú¯Ø§Ù†Øª
+  permission_view_calendar: Ø¯ÛŒØ¯Ù† Ú¯Ø§Ù‡Ø´Ù…Ø§Ø±
+  permission_view_issue_watchers: Ø¯ÛŒØ¯Ù† ÙÙ‡Ø±Ø³Øª Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†â€ŒÙ‡Ø§
+  permission_add_issue_watchers: Ø§ÙØ²ÙˆØ¯Ù† Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†â€ŒÙ‡Ø§
+  permission_delete_issue_watchers: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†â€ŒÙ‡Ø§
+  permission_log_time: Ù†ÙˆØ´ØªÙ† Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
+  permission_view_time_entries: Ø¯ÛŒØ¯Ù† Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
+  permission_edit_time_entries: ÙˆÛŒØ±Ø§ÛŒØ´ Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
+  permission_edit_own_time_entries: ÙˆÛŒØ±Ø§ÛŒØ´ Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡ Ø®ÙˆØ¯
+  permission_manage_news: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
+  permission_comment_news: Ú¯Ø°Ø§Ø´ØªÙ† Ø¯ÛŒØ¯Ú¯Ø§Ù‡ Ø±ÙˆÛŒ Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
+  permission_view_documents: Ø¯ÛŒØ¯Ù† Ù†ÙˆØ´ØªØ§Ø±Ù‡Ø§
+  permission_manage_files: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§
+  permission_view_files: Ø¯ÛŒØ¯Ù† Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§
+  permission_manage_wiki: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ ÙˆÛŒÚ©ÛŒ
+  permission_rename_wiki_pages: Ù†Ø§Ù…Ú¯Ø°Ø§Ø±ÛŒ Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
+  permission_delete_wiki_pages: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
+  permission_view_wiki_pages: Ø¯ÛŒØ¯Ù† ÙˆÛŒÚ©ÛŒ
+  permission_view_wiki_edits: Ø¯ÛŒØ¯Ù† Ù¾ÛŒØ´ÛŒÙ†Ù‡ ÙˆÛŒÚ©ÛŒ
+  permission_edit_wiki_pages: ÙˆÛŒØ±Ø§ÛŒØ´ Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ÛŒ ÙˆÛŒÚ©ÛŒ
+  permission_delete_wiki_pages_attachments: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾ÛŒÙˆØ³Øªâ€ŒÙ‡Ø§ÛŒ Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
+  permission_protect_wiki_pages: Ù†Ú¯Ù‡â€ŒØ¯Ø§Ø±ÛŒ Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ÛŒ ÙˆÛŒÚ©ÛŒ
+  permission_manage_repository: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡
+  permission_browse_repository: Ú†Ø±ÛŒØ¯Ù† Ø¯Ø± Ø§Ù†Ø¨Ø§Ø±Ù‡
+  permission_view_changesets: Ø¯ÛŒØ¯Ù† ØªØºÛŒÛŒØ±Ø§Øª
+  permission_commit_access: Ø¯Ø³ØªØ±Ø³ÛŒ ØªØºÛŒÛŒØ± Ø§Ù†Ø¨Ø§Ø±Ù‡
+  permission_manage_boards: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø§Ù†Ø¬Ù…Ù†â€ŒÙ‡Ø§
+  permission_view_messages: Ø¯ÛŒØ¯Ù† Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§
+  permission_add_messages: ÙØ±Ø³ØªØ§Ø¯Ù† Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§
+  permission_edit_messages: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§
+  permission_edit_own_messages: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾ÛŒØ§Ù… Ø®ÙˆØ¯
+  permission_delete_messages: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§
+  permission_delete_own_messages: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾ÛŒØ§Ù… Ø®ÙˆØ¯
+  permission_export_wiki_pages: ØµØ¯ÙˆØ± Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ÛŒ ÙˆÛŒÚ©ÛŒ
+  permission_manage_subtasks: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø²ÛŒØ±Ú©Ø§Ø±Ù‡Ø§
+
+  project_module_issue_tracking: Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  project_module_time_tracking: Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ø²Ù…Ø§Ù†
+  project_module_news: Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
+  project_module_documents: Ù†ÙˆØ´ØªØ§Ø±Ù‡Ø§
+  project_module_files: Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§
+  project_module_wiki: ÙˆÛŒÚ©ÛŒ
+  project_module_repository: Ø§Ù†Ø¨Ø§Ø±Ù‡
+  project_module_boards: Ø§Ù†Ø¬Ù…Ù†â€ŒÙ‡Ø§
+  project_module_calendar: Ú¯Ø§Ù‡Ø´Ù…Ø§Ø±
+  project_module_gantt: Ú¯Ø§Ù†Øª
+
+  label_user: Ú©Ø§Ø±Ø¨Ø±
+  label_user_plural: Ú©Ø§Ø±Ø¨Ø±
+  label_user_new: Ú©Ø§Ø±Ø¨Ø± ØªØ§Ø²Ù‡
+  label_user_anonymous: Ù†Ø§Ø´Ù†Ø§Ø³
+  label_project: Ù¾Ø±ÙˆÚ˜Ù‡
+  label_project_new: Ù¾Ø±ÙˆÚ˜Ù‡ ØªØ§Ø²Ù‡
+  label_project_plural: Ù¾Ø±ÙˆÚ˜Ù‡
+  label_x_projects:
+    zero:  Ø¨Ø¯ÙˆÙ† Ù¾Ø±ÙˆÚ˜Ù‡
+    one:   "1 Ù¾Ø±ÙˆÚ˜Ù‡"
+    other: "%{count} Ù¾Ø±ÙˆÚ˜Ù‡"
+  label_project_all: Ù‡Ù…Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
+  label_project_latest: Ø¢Ø®Ø±ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
+  label_issue: Ù¾ÛŒØ§Ù…Ø¯
+  label_issue_new: Ù¾ÛŒØ§Ù…Ø¯ ØªØ§Ø²Ù‡
+  label_issue_plural: Ù¾ÛŒØ§Ù…Ø¯
+  label_issue_view_all: Ø¯ÛŒØ¯Ù† Ù‡Ù…Ù‡ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
+  label_issues_by: "Ø¯Ø³ØªÙ‡â€ŒØ¨Ù†Ø¯ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ø¨Ø§ %{value}"
+  label_issue_added: Ù¾ÛŒØ§Ù…Ø¯ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
+  label_issue_updated: Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø±ÙˆØ² Ø´Ø¯
+  label_document: Ù†ÙˆØ´ØªØ§Ø±
+  label_document_new: Ù†ÙˆØ´ØªØ§Ø± ØªØ§Ø²Ù‡
+  label_document_plural: Ù†ÙˆØ´ØªØ§Ø±
+  label_document_added: Ù†ÙˆØ´ØªØ§Ø± Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
+  label_role: Ù†Ù‚Ø´
+  label_role_plural: Ù†Ù‚Ø´
+  label_role_new: Ù†Ù‚Ø´ ØªØ§Ø²Ù‡
+  label_role_and_permissions: Ù†Ù‚Ø´â€ŒÙ‡Ø§ Ùˆ Ù¾Ø±ÙˆØ§Ù†Ù‡â€ŒÙ‡Ø§
+  label_member: Ø¹Ø¶Ùˆ
+  label_member_new: Ø¹Ø¶Ùˆ ØªØ§Ø²Ù‡
+  label_member_plural: Ø¹Ø¶Ùˆ
+  label_tracker: Ù¾ÛŒÚ¯Ø±Ø¯
+  label_tracker_plural: Ù¾ÛŒÚ¯Ø±Ø¯
+  label_tracker_new: Ù¾ÛŒÚ¯Ø±Ø¯ ØªØ§Ø²Ù‡
+  label_workflow: Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø±
+  label_issue_status: ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯
+  label_issue_status_plural: ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯
+  label_issue_status_new: ÙˆØ¶Ø¹ÛŒØª ØªØ§Ø²Ù‡
+  label_issue_category: Ø¯Ø³ØªÙ‡ Ù¾ÛŒØ§Ù…Ø¯
+  label_issue_category_plural: Ø¯Ø³ØªÙ‡ Ù¾ÛŒØ§Ù…Ø¯
+  label_issue_category_new: Ø¯Ø³ØªÙ‡ ØªØ§Ø²Ù‡
+  label_custom_field: ÙÛŒÙ„Ø¯ Ø³ÙØ§Ø±Ø´ÛŒ
+  label_custom_field_plural: ÙÛŒÙ„Ø¯ Ø³ÙØ§Ø±Ø´ÛŒ
+  label_custom_field_new: ÙÛŒÙ„Ø¯ Ø³ÙØ§Ø±Ø´ÛŒ ØªØ§Ø²Ù‡
+  label_enumerations: Ø¨Ø±Ø´Ù…Ø±Ø¯Ù†ÛŒâ€ŒÙ‡Ø§
+  label_enumeration_new: Ù…Ù‚Ø¯Ø§Ø± ØªØ§Ø²Ù‡
+  label_information: Ø¯Ø§Ø¯Ù‡
+  label_information_plural: Ø¯Ø§Ø¯Ù‡
+  label_please_login: ÙˆØ§Ø±Ø¯ Ø´ÙˆÛŒØ¯
+  label_register: Ù†Ø§Ù… Ù†ÙˆÛŒØ³ÛŒ Ú©Ù†ÛŒØ¯
+  label_login_with_open_id_option: ÛŒØ§ Ø¨Ø§ OpenID ÙˆØ§Ø±Ø¯ Ø´ÙˆÛŒØ¯
+  label_password_lost: Ø¨Ø§Ø²ÛŒØ§ÙØª Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
+  label_home: Ø³Ø±Ø¢ØºØ§Ø²
+  label_my_page: Ø¨Ø±Ú¯Ù‡ Ù…Ù†
+  label_my_account: Ø­Ø³Ø§Ø¨ Ù…Ù†
+  label_my_projects: Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ù…Ù†
+  label_my_page_block: Ø¨Ø®Ø´ Ø¨Ø±Ú¯Ù‡ Ù…Ù†
+  label_administration: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ
+  label_login: ÙˆØ±ÙˆØ¯
+  label_logout: Ø®Ø±ÙˆØ¬
+  label_help: Ø±Ø§Ù‡Ù†Ù…Ø§
+  label_reported_issues: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡
+  label_assigned_to_me_issues: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡ Ø¨Ù‡ Ù…Ù†
+  label_last_login: Ø¢Ø®Ø±ÛŒÙ† ÙˆØ±ÙˆØ¯
+  label_registered_on: Ù†Ø§Ù… Ù†ÙˆÛŒØ³ÛŒ Ø´Ø¯Ù‡ Ø¯Ø±
+  label_activity: Ú¯Ø²Ø§Ø±Ø´
+  label_overall_activity: Ú¯Ø²Ø§Ø±Ø´ Ø±ÙˆÛŒ Ù‡Ù… Ø±ÙØªÙ‡
+  label_user_activity: "Ú¯Ø²Ø§Ø±Ø´ %{value}"
+  label_new: ØªØ§Ø²Ù‡
+  label_logged_as: "Ù†Ø§Ù… Ú©Ø§Ø±Ø¨Ø±ÛŒ:"
+  label_environment: Ù…Ø­ÛŒØ·
+  label_authentication: Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ
+  label_auth_source: Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ
+  label_auth_source_new: Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ ØªØ§Ø²Ù‡
+  label_auth_source_plural: Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ
+  label_subproject_plural: Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡
+  label_subproject_new: Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡ ØªØ§Ø²Ù‡
+  label_and_its_subprojects: "%{value} Ùˆ Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒØ´"
+  label_min_max_length: Ú©Ù…ØªØ±ÛŒÙ† Ùˆ Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡
+  label_list: ÙÙ‡Ø±Ø³Øª
+  label_date: ØªØ§Ø±ÛŒØ®
+  label_integer: Ø´Ù…Ø§Ø±Ù‡ Ø¯Ø±Ø³Øª
+  label_float: Ø´Ù…Ø§Ø±Ù‡ Ø´Ù†Ø§ÙˆØ±
+  label_boolean: Ø¯Ø±Ø³Øª/Ù†Ø§Ø¯Ø±Ø³Øª
+  label_string: Ù†ÙˆØ´ØªÙ‡
+  label_text: Ù†ÙˆØ´ØªÙ‡ Ø¨Ù„Ù†Ø¯
+  label_attribute: Ù†Ø´Ø§Ù†Ù‡
+  label_attribute_plural: Ù†Ø´Ø§Ù†Ù‡
+  label_no_data: Ù‡ÛŒÚ† Ø¯Ø§Ø¯Ù‡â€ŒØ§ÛŒ Ø¨Ø±Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ù†ÛŒØ³Øª
+  label_change_status: Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ†ÛŒ ÙˆØ¶Ø¹ÛŒØª
+  label_history: Ù¾ÛŒØ´ÛŒÙ†Ù‡
+  label_attachment: Ù¾Ø±ÙˆÙ†Ø¯Ù‡
+  label_attachment_new: Ù¾Ø±ÙˆÙ†Ø¯Ù‡ ØªØ§Ø²Ù‡
+  label_attachment_delete: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾Ø±ÙˆÙ†Ø¯Ù‡
+  label_attachment_plural: Ù¾Ø±ÙˆÙ†Ø¯Ù‡
+  label_file_added: Ù¾Ø±ÙˆÙ†Ø¯Ù‡ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
+  label_report: Ú¯Ø²Ø§Ø±Ø´
+  label_report_plural: Ú¯Ø²Ø§Ø±Ø´
+  label_news: Ø±ÙˆÛŒØ¯Ø§Ø¯
+  label_news_new: Ø§ÙØ²ÙˆØ¯Ù† Ø±ÙˆÛŒØ¯Ø§Ø¯
+  label_news_plural: Ø±ÙˆÛŒØ¯Ø§Ø¯
+  label_news_latest: Ø¢Ø®Ø±ÛŒÙ† Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
+  label_news_view_all: Ø¯ÛŒØ¯Ù† Ù‡Ù…Ù‡ Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
+  label_news_added: Ø±ÙˆÛŒØ¯Ø§Ø¯ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
+  label_settings: Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ
+  label_overview: Ø¯Ø± ÛŒÚ© Ù†Ú¯Ø§Ù‡
+  label_version: Ù†Ú¯Ø§Ø±Ø´
+  label_version_new: Ù†Ú¯Ø§Ø±Ø´ ØªØ§Ø²Ù‡
+  label_version_plural: Ù†Ú¯Ø§Ø±Ø´
+  label_close_versions: Ø¨Ø³ØªÙ† Ù†Ú¯Ø§Ø±Ø´â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡
+  label_confirmation: Ø¨Ø±Ø±Ø³ÛŒ
+  label_export_to: 'Ù‚Ø§Ù„Ø¨â€ŒÙ‡Ø§ÛŒ Ø¯ÛŒÚ¯Ø±:'
+  label_read: Ø®ÙˆØ§Ù†Ø¯Ù†...
+  label_public_projects: Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ù‡Ù…Ú¯Ø§Ù†ÛŒ
+  label_open_issues: Ø¨Ø§Ø²
+  label_open_issues_plural: Ø¨Ø§Ø²
+  label_closed_issues: Ø¨Ø³ØªÙ‡
+  label_closed_issues_plural: Ø¨Ø³ØªÙ‡
+  label_x_open_issues_abbr_on_total:
+    zero:  0 Ø¨Ø§Ø² Ø§Ø² %{total}
+    one:   1 Ø¨Ø§Ø² Ø§Ø² %{total}
+    other: "%{count} Ø¨Ø§Ø² Ø§Ø² %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 Ø¨Ø§Ø²
+    one:   1 Ø¨Ø§Ø²
+    other: "%{count} Ø¨Ø§Ø²"
+  label_x_closed_issues_abbr:
+    zero:  0 Ø¨Ø³ØªÙ‡
+    one:   1 Ø¨Ø³ØªÙ‡
+    other: "%{count} Ø¨Ø³ØªÙ‡"
+  label_total: Ø¬Ù…Ù„Ù‡
+  label_permissions: Ù¾Ø±ÙˆØ§Ù†Ù‡â€ŒÙ‡Ø§
+  label_current_status: ÙˆØ¶Ø¹ÛŒØª Ú©Ù†ÙˆÙ†ÛŒ
+  label_new_statuses_allowed: ÙˆØ¶Ø¹ÛŒØªâ€ŒÙ‡Ø§ÛŒ Ù¾Ø°ÛŒØ±ÙØªÙ†ÛŒ ØªØ§Ø²Ù‡
+  label_all: Ù‡Ù…Ù‡
+  label_none: Ù‡ÛŒÚ†
+  label_nobody: Ù‡ÛŒÚ†Ú©Ø³
+  label_next: Ù¾Ø³ÛŒÙ†
+  label_previous: Ù¾ÛŒØ´ÛŒÙ†
+  label_used_by: Ø¨Ù‡ Ú©Ø§Ø± Ø±ÙØªÙ‡ Ø¯Ø±
+  label_details: Ø±ÛŒØ²Ù‡â€ŒÚ©Ø§Ø±ÛŒ
+  label_add_note: Ø§ÙØ²ÙˆØ¯Ù† ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
+  label_per_page: Ø±Ø¯ÛŒÙâ€ŒÙ‡Ø§ Ø¯Ø± Ù‡Ø± Ø¨Ø±Ú¯Ù‡
+  label_calendar: Ú¯Ø§Ù‡Ø´Ù…Ø§Ø±
+  label_months_from: Ø§Ø² Ù…Ø§Ù‡
+  label_gantt: Ú¯Ø§Ù†Øª
+  label_internal: Ø¯Ø±ÙˆÙ†ÛŒ
+  label_last_changes: "%{count} ØªØºÛŒÛŒØ± Ø¢Ø®Ø±"
+  label_change_view_all: Ø¯ÛŒØ¯Ù† Ù‡Ù…Ù‡ ØªØºÛŒÛŒØ±Ø§Øª
+  label_personalize_page: Ø³ÙØ§Ø±Ø´ÛŒ Ù†Ù…ÙˆØ¯Ù† Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡
+  label_comment: Ø¯ÛŒØ¯Ú¯Ø§Ù‡
+  label_comment_plural: Ø¯ÛŒØ¯Ú¯Ø§Ù‡
+  label_x_comments:
+    zero: Ø¨Ø¯ÙˆÙ† Ø¯ÛŒØ¯Ú¯Ø§Ù‡
+    one: 1 Ø¯ÛŒØ¯Ú¯Ø§Ù‡
+    other: "%{count} Ø¯ÛŒØ¯Ú¯Ø§Ù‡"
+  label_comment_add: Ø§ÙØ²ÙˆØ¯Ù† Ø¯ÛŒØ¯Ú¯Ø§Ù‡
+  label_comment_added: Ø¯ÛŒØ¯Ú¯Ø§Ù‡ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
+  label_comment_delete: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ø¯ÛŒØ¯Ú¯Ø§Ù‡â€ŒÙ‡Ø§
+  label_query: Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÛŒ Ø³ÙØ§Ø±Ø´ÛŒ
+  label_query_plural: Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÛŒ Ø³ÙØ§Ø±Ø´ÛŒ
+  label_query_new: Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÛŒ ØªØ§Ø²Ù‡
+  label_filter_add: Ø§ÙØ²ÙˆØ¯Ù† Ù¾Ø§Ù„Ø§ÛŒÙ‡
+  label_filter_plural: Ù¾Ø§Ù„Ø§ÛŒÙ‡
+  label_equals: Ø¨Ø±Ø§Ø¨Ø± Ø§Ø³Øª Ø¨Ø§
+  label_not_equals: Ø¨Ø±Ø§Ø¨Ø± Ù†ÛŒØ³Øª Ø¨Ø§
+  label_in_less_than: Ú©Ù…ØªØ± Ø§Ø³Øª Ø§Ø²
+  label_in_more_than: Ø¨ÛŒØ´ØªØ± Ø§Ø³Øª Ø§Ø²
+  label_greater_or_equal: Ø¨ÛŒØ´ØªØ± ÛŒØ§ Ø¨Ø±Ø§Ø¨Ø± Ø§Ø³Øª Ø¨Ø§
+  label_less_or_equal: Ú©Ù…ØªØ± ÛŒØ§ Ø¨Ø±Ø§Ø¨Ø± Ø§Ø³Øª Ø¨Ø§
+  label_in: Ø¯Ø±
+  label_today: Ø§Ù…Ø±ÙˆØ²
+  label_all_time: Ù‡Ù…ÛŒØ´Ù‡
+  label_yesterday: Ø¯ÛŒØ±ÙˆØ²
+  label_this_week: Ø§ÛŒÙ† Ù‡ÙØªÙ‡
+  label_last_week: Ù‡ÙØªÙ‡ Ù¾ÛŒØ´ÛŒÙ†
+  label_last_n_days: "%{count} Ø±ÙˆØ² Ú¯Ø°Ø´ØªÙ‡"
+  label_this_month: Ø§ÛŒÙ† Ù…Ø§Ù‡
+  label_last_month: Ù…Ø§Ù‡ Ù¾ÛŒØ´ÛŒÙ†
+  label_this_year: Ø§Ù…Ø³Ø§Ù„
+  label_date_range: Ø¨Ø§Ø²Ù‡ ØªØ§Ø±ÛŒØ®
+  label_less_than_ago: Ú©Ù…ØªØ± Ø§Ø² Ú†Ù†Ø¯ Ø±ÙˆØ² Ù¾ÛŒØ´ÛŒÙ†
+  label_more_than_ago: Ø¨ÛŒØ´ØªØ± Ø§Ø² Ú†Ù†Ø¯ Ø±ÙˆØ² Ù¾ÛŒØ´ÛŒÙ†
+  label_ago: Ø±ÙˆØ² Ù¾ÛŒØ´ÛŒÙ†
+  label_contains: Ø¯Ø§Ø±Ø¯
+  label_not_contains: Ù†Ø¯Ø§Ø±Ø¯
+  label_day_plural: Ø±ÙˆØ²
+  label_repository: Ø§Ù†Ø¨Ø§Ø±Ù‡
+  label_repository_plural: Ø§Ù†Ø¨Ø§Ø±Ù‡
+  label_browse: Ú†Ø±ÛŒØ¯Ù†
+  label_branch: Ø´Ø§Ø®Ù‡
+  label_tag: Ø¨Ø±Ú†Ø³Ø¨
+  label_revision: Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ
+  label_revision_plural: Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ
+  label_revision_id: "Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ %{value}"
+  label_associated_revisions: Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒâ€ŒÙ‡Ø§ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡
+  label_added: Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯Ù‡
+  label_modified: Ù¾ÛŒØ±Ø§Ø³ØªÙ‡ Ø´Ø¯Ù‡
+  label_copied: Ø±ÙˆÙ†ÙˆÛŒØ³ÛŒ Ø´Ø¯Ù‡
+  label_renamed: Ù†Ø§Ù…Ú¯Ø°Ø§Ø±ÛŒ Ø´Ø¯Ù‡
+  label_deleted: Ù¾Ø§Ú©Ø³Ø§Ø²ÛŒ Ø´Ø¯Ù‡
+  label_latest_revision: Ø¢Ø®Ø±ÛŒÙ† Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ
+  label_latest_revision_plural: Ø¢Ø®Ø±ÛŒÙ† Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ
+  label_view_revisions: Ø¯ÛŒØ¯Ù† Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒâ€ŒÙ‡Ø§
+  label_view_all_revisions: Ø¯ÛŒØ¯Ù† Ù‡Ù…Ù‡ Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒâ€ŒÙ‡Ø§
+  label_max_size: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡
+  label_sort_highest: Ø¨Ø±Ø¯Ù† Ø¨Ù‡ Ø¢ØºØ§Ø²
+  label_sort_higher: Ø¨Ø±Ø¯Ù† Ø¨Ù‡ Ø¨Ø§Ù„Ø§
+  label_sort_lower: Ø¨Ø±Ø¯Ù† Ø¨Ù‡ Ù¾Ø§ÛŒÛŒÙ†
+  label_sort_lowest: Ø¨Ø±Ø¯Ù† Ø¨Ù‡ Ù¾Ø§ÛŒØ§Ù†
+  label_roadmap: Ú†Ø´Ù…â€ŒØ§Ù†Ø¯Ø§Ø²
+  label_roadmap_due_in: "Ø³Ø±Ø±Ø³ÛŒØ¯ Ø¯Ø± %{value}"
+  label_roadmap_overdue: "%{value} Ø¯ÛŒØ±Ú©Ø±Ø¯"
+  label_roadmap_no_issues: Ù‡ÛŒÚ† Ù¾ÛŒØ§Ù…Ø¯ÛŒ Ø¨Ø±Ø§ÛŒ Ø§ÛŒÙ† Ù†Ú¯Ø§Ø±Ø´ Ù†ÛŒØ³Øª
+  label_search: Ø¬Ø³ØªØ¬Ùˆ
+  label_result_plural: Ø¯Ø³Øªâ€ŒØ¢ÙˆØ±Ø¯
+  label_all_words: Ù‡Ù…Ù‡ ÙˆØ§Ú˜Ù‡â€ŒÙ‡Ø§
+  label_wiki: ÙˆÛŒÚ©ÛŒ
+  label_wiki_edit: ÙˆÛŒØ±Ø§ÛŒØ´ ÙˆÛŒÚ©ÛŒ
+  label_wiki_edit_plural: ÙˆÛŒØ±Ø§ÛŒØ´ ÙˆÛŒÚ©ÛŒ
+  label_wiki_page: Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
+  label_wiki_page_plural: Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
+  label_index_by_title: Ø´Ø§Ø®Øµ Ø¨Ø± Ø§Ø³Ø§Ø³ Ù†Ø§Ù…
+  label_index_by_date: Ø´Ø§Ø®Øµ Ø¨Ø± Ø§Ø³Ø§Ø³ ØªØ§Ø±ÛŒØ®
+  label_current_version: Ù†Ú¯Ø§Ø±Ø´ Ú©Ù†ÙˆÙ†ÛŒ
+  label_preview: Ù¾ÛŒØ´â€ŒÙ†Ù…Ø§ÛŒØ´
+  label_feed_plural: Ø®ÙˆØ±Ø§Ú©
+  label_changes_details: Ø±ÛŒØ² Ù‡Ù…Ù‡ Ø¬Ø§ÛŒÚ¯Ø°Ø§Ø±ÛŒâ€ŒÙ‡Ø§
+  label_issue_tracking: Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ù¾ÛŒØ§Ù…Ø¯
+  label_spent_time: Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
+  label_overall_spent_time: Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡ Ø±ÙˆÛŒ Ù‡Ù…
+  label_f_hour: "%{value} Ø³Ø§Ø¹Øª"
+  label_f_hour_plural: "%{value} Ø³Ø§Ø¹Øª"
+  label_time_tracking: Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ø²Ù…Ø§Ù†
+  label_change_plural: Ø¬Ø§ÛŒÚ¯Ø°Ø§Ø±ÛŒ
+  label_statistics: Ø³Ø±Ø´Ù…Ø§Ø±ÛŒ
+  label_commits_per_month: ØªØºÛŒÛŒØ± Ø¯Ø± Ù‡Ø± Ù…Ø§Ù‡
+  label_commits_per_author: ØªØºÛŒÛŒØ± Ù‡Ø± Ù†ÙˆÛŒØ³Ù†Ø¯Ù‡
+  label_view_diff: Ø¯ÛŒØ¯Ù† ØªÙØ§ÙˆØªâ€ŒÙ‡Ø§
+  label_diff_inline: Ù‡Ù…Ø±Ø§Ø³ØªØ§
+  label_diff_side_by_side: Ú©Ù†Ø§Ø± Ø¨Ù‡ Ú©Ù†Ø§Ø±
+  label_options: Ú¯Ø²ÛŒÙ†Ù‡â€ŒÙ‡Ø§
+  label_copy_workflow_from: Ø±ÙˆÙ†ÙˆÛŒØ³ÛŒ Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø± Ø§Ø² Ø±ÙˆÛŒ
+  label_permissions_report: Ú¯Ø²Ø§Ø±Ø´ Ù¾Ø±ÙˆØ§Ù†Ù‡â€ŒÙ‡Ø§
+  label_watched_issues: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†ÛŒ Ø´Ø¯Ù‡
+  label_related_issues: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡
+  label_applied_status: ÙˆØ¶Ø¹ÛŒØª Ø¨Ù‡ Ú©Ø§Ø± Ø±ÙØªÙ‡
+  label_loading: Ø¨Ø§Ø± Ú¯Ø°Ø§Ø±ÛŒ...
+  label_relation_new: ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ ØªØ§Ø²Ù‡
+  label_relation_delete: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ
+  label_relates_to: ÙˆØ§Ø¨Ø³ØªÙ‡ Ø¨Ù‡
+  label_duplicates: Ù†Ú¯Ø§Ø±Ø´ Ø¯ÛŒÚ¯Ø±ÛŒ Ø§Ø²
+  label_duplicated_by: Ù†Ú¯Ø§Ø±Ø´ÛŒ Ø¯ÛŒÚ¯Ø± Ø¯Ø±
+  label_blocks: Ø¨Ø§Ø²Ø¯Ø§Ø´Øªâ€ŒÙ‡Ø§
+  label_blocked_by: Ø¨Ø§Ø²Ø¯Ø§Ø´Øª Ø¨Ù‡ Ø¯Ø³Øª
+  label_precedes: Ø¬Ù„ÙˆØªØ± Ø§Ø³Øª Ø§Ø²
+  label_follows: Ù¾Ø³ØªØ± Ø§Ø³Øª Ø§Ø²
+  label_end_to_start: Ù¾Ø§ÛŒØ§Ù† Ø¨Ù‡ Ø¢ØºØ§Ø²
+  label_end_to_end: Ù¾Ø§ÛŒØ§Ù† Ø¨Ù‡ Ù¾Ø§ÛŒØ§Ù†
+  label_start_to_start: Ø¢ØºØ§Ø² Ø¨Ù‡ Ø¢ØºØ§Ø²
+  label_start_to_end: Ø¢ØºØ§Ø² Ø¨Ù‡ Ù¾Ø§ÛŒØ§Ù†
+  label_stay_logged_in: ÙˆØ§Ø±Ø¯ Ø´Ø¯Ù‡ Ø¨Ù…Ø§Ù†ÛŒØ¯
+  label_disabled: ØºÛŒØ±ÙØ¹Ø§Ù„
+  label_show_completed_versions: Ù†Ù…Ø§ÛŒØ´ Ù†Ú¯Ø§Ø±Ø´â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡
+  label_me: Ù…Ù†
+  label_board: Ø§Ù†Ø¬Ù…Ù†
+  label_board_new: Ø§Ù†Ø¬Ù…Ù† ØªØ§Ø²Ù‡
+  label_board_plural: Ø§Ù†Ø¬Ù…Ù†
+  label_board_locked: Ù‚ÙÙ„ Ø´Ø¯Ù‡
+  label_board_sticky: Ú†Ø³Ø¨Ù†Ø§Ú©
+  label_topic_plural: Ø³Ø±ÙØµÙ„
+  label_message_plural: Ù¾ÛŒØ§Ù…
+  label_message_last: Ø¢Ø®Ø±ÛŒÙ† Ù¾ÛŒØ§Ù…
+  label_message_new: Ù¾ÛŒØ§Ù… ØªØ§Ø²Ù‡
+  label_message_posted: Ù¾ÛŒØ§Ù… Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
+  label_reply_plural: Ù¾Ø§Ø³Ø®
+  label_send_information: ÙØ±Ø³ØªØ§Ø¯Ù† Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ø­Ø³Ø§Ø¨ Ø¨Ù‡ Ú©Ø§Ø±Ø¨Ø±
+  label_year: Ø³Ø§Ù„
+  label_month: Ù…Ø§Ù‡
+  label_week: Ù‡ÙØªÙ‡
+  label_date_from: Ø§Ø²
+  label_date_to: ØªØ§
+  label_language_based: Ø¨Ø± Ø§Ø³Ø§Ø³ Ø²Ø¨Ø§Ù† Ú©Ø§Ø±Ø¨Ø±
+  label_sort_by: "Ø¬ÙˆØ± Ú©Ø±Ø¯ Ø¨Ø§ %{value}"
+  label_send_test_email: ÙØ±Ø³ØªØ§Ø¯Ù† Ø§ÛŒÙ…ÛŒÙ„ Ø¢Ø²Ù…Ø§ÛŒØ´ÛŒ
+  label_feeds_access_key: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ RSS
+  label_missing_feeds_access_key: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ RSS Ø¯Ø± Ø¯Ø³ØªØ±Ø³ Ù†ÛŒØ³Øª
+  label_feeds_access_key_created_on: "Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ RSS %{value} Ù¾ÛŒØ´ Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª"
+  label_module_plural: Ù¾ÛŒÙ…Ø§Ù†Ù‡
+  label_added_time_by: "Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯Ù‡ Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø¯Ø± %{age} Ù¾ÛŒØ´"
+  label_updated_time_by: "Ø¨Ø±ÙˆØ² Ø´Ø¯Ù‡ Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø¯Ø± %{age} Ù¾ÛŒØ´"
+  label_updated_time: "Ø¨Ø±ÙˆØ² Ø´Ø¯Ù‡ Ø¯Ø± %{value} Ù¾ÛŒØ´"
+  label_jump_to_a_project: Ù¾Ø±Ø´ Ø¨Ù‡ ÛŒÚ© Ù¾Ø±ÙˆÚ˜Ù‡...
+  label_file_plural: Ù¾Ø±ÙˆÙ†Ø¯Ù‡
+  label_changeset_plural: ØªØºÛŒÛŒØ±
+  label_default_columns: Ø³ØªÙˆÙ†â€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
+  label_no_change_option: (Ø¨Ø¯ÙˆÙ† ØªØºÛŒÛŒØ±)
+  label_bulk_edit_selected_issues: ÙˆÛŒØ±Ø§ÛŒØ´ Ø¯Ø³ØªÙ‡â€ŒØ§ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡
+  label_theme: Ù¾ÙˆØ³ØªÙ‡
+  label_default: Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
+  label_search_titles_only: ØªÙ†Ù‡Ø§ Ù†Ø§Ù…â€ŒÙ‡Ø§ Ø¬Ø³ØªØ¬Ùˆ Ø´ÙˆØ¯
+  label_user_mail_option_all: "Ø¨Ø±Ø§ÛŒ Ù‡Ø± Ø±ÙˆÛŒØ¯Ø§Ø¯ Ø¯Ø± Ù‡Ù…Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§"
+  label_user_mail_option_selected: "Ø¨Ø±Ø§ÛŒ Ù‡Ø± Ø±ÙˆÛŒØ¯Ø§Ø¯ ØªÙ†Ù‡Ø§ Ø¯Ø± Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡..."
+  label_user_mail_option_none: "Ù‡ÛŒÚ† Ø±ÙˆÛŒØ¯Ø§Ø¯ÛŒ"
+  label_user_mail_option_only_my_events: "ØªÙ†Ù‡Ø§ Ø¨Ø±Ø§ÛŒ Ú†ÛŒØ²Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù† Ù‡Ø³ØªÙ… ÛŒØ§ Ø¯Ø± Ø¢Ù†â€ŒÙ‡Ø§ Ø¯Ø±Ú¯ÛŒØ± Ù‡Ø³ØªÙ…"
+  label_user_mail_option_only_assigned: "ØªÙ†Ù‡Ø§ Ø¨Ø±Ø§ÛŒ Ú†ÛŒØ²Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¨Ù‡ Ù…Ù† ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡"
+  label_user_mail_option_only_owner: "ØªÙ†Ù‡Ø§ Ø¨Ø±Ø§ÛŒ Ú†ÛŒØ²Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ù…Ù† Ø¯Ø§Ø±Ù†Ø¯Ù‡ Ø¢Ù†â€ŒÙ‡Ø§ Ù‡Ø³ØªÙ…"
+  label_user_mail_no_self_notified: "Ù†Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡Ù… Ø§Ø² ØªØºÛŒÛŒØ±Ø§ØªÛŒ Ú©Ù‡ Ø®ÙˆØ¯Ù… Ù…ÛŒâ€ŒØ¯Ù‡Ù… Ø¢Ú¯Ø§Ù‡ Ø´ÙˆÙ…"
+  label_registration_activation_by_email: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ Ø¨Ø§ Ø§ÛŒÙ…ÛŒÙ„
+  label_registration_manual_activation: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ Ø¯Ø³ØªÛŒ
+  label_registration_automatic_activation: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ Ø®ÙˆØ¯Ú©Ø§Ø±
+  label_display_per_page: "Ø±Ø¯ÛŒÙâ€ŒÙ‡Ø§ Ø¯Ø± Ù‡Ø± Ø¨Ø±Ú¯Ù‡: %{value}"
+  label_age: Ø³Ù†
+  label_change_properties: ÙˆÛŒØ±Ø§ÛŒØ´ ÙˆÛŒÚ˜Ú¯ÛŒâ€ŒÙ‡Ø§
+  label_general: Ù‡Ù…Ú¯Ø§Ù†ÛŒ
+  label_more: Ø¨ÛŒØ´ØªØ±
+  label_scm: SCM
+  label_plugins: Ø§ÙØ²ÙˆÙ†Ù‡â€ŒÙ‡Ø§
+  label_ldap_authentication: Ø´Ù†Ø§Ø³Ø§ÛŒÛŒLDAP
+  label_downloads_abbr: Ø¯Ø±ÛŒØ§ÙØª
+  label_optional_description: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª Ø¯Ù„Ø®ÙˆØ§Ù‡
+  label_add_another_file: Ø§ÙØ²ÙˆØ¯Ù† Ù¾Ø±ÙˆÙ†Ø¯Ù‡ Ø¯ÛŒÚ¯Ø±
+  label_preferences: Ù¾Ø³Ù†Ø¯Ù‡Ø§
+  label_chronological_order: Ø¨Ù‡ ØªØ±ØªÛŒØ¨ ØªØ§Ø±ÛŒØ®
+  label_reverse_chronological_order: Ø¨Ø±Ø¹Ú©Ø³ ØªØ±ØªÛŒØ¨ ØªØ§Ø±ÛŒØ®
+  label_planning: Ø¨Ø±Ù†Ø§Ù…Ù‡ Ø±ÛŒØ²ÛŒ
+  label_incoming_emails: Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ÛŒ Ø¢Ù…Ø¯Ù‡
+  label_generate_key: Ø³Ø§Ø®Øª Ú©Ù„ÛŒØ¯
+  label_issue_watchers: Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†â€ŒÙ‡Ø§
+  label_example: Ù†Ù…ÙˆÙ†Ù‡
+  label_display: Ù†Ù…Ø§ÛŒØ´
+  label_sort: Ø¬ÙˆØ± Ú©Ø±Ø¯
+  label_ascending: Ø§ÙØ²Ø§ÛŒØ´ÛŒ
+  label_descending: Ú©Ø§Ù‡Ø´ÛŒ
+  label_date_from_to: Ø§Ø² %{start} ØªØ§ %{end}
+  label_wiki_content_added: Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
+  label_wiki_content_updated: Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Ø¨Ø±ÙˆØ² Ø´Ø¯
+  label_group: Ø¯Ø³ØªÙ‡
+  label_group_plural: Ø¯Ø³ØªÙ‡
+  label_group_new: Ø¯Ø³ØªÙ‡ ØªØ§Ø²Ù‡
+  label_time_entry_plural: Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
+  label_version_sharing_none: Ø¨Ø¯ÙˆÙ† Ø§Ø´ØªØ±Ø§Ú©
+  label_version_sharing_descendants: Ø¨Ø§ Ø²ÛŒØ± Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
+  label_version_sharing_hierarchy: Ø¨Ø§ Ø±Ø´ØªÙ‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
+  label_version_sharing_tree: Ø¨Ø§ Ø¯Ø±Ø®Øª Ù¾Ø±ÙˆÚ˜Ù‡
+  label_version_sharing_system: Ø¨Ø§ Ù‡Ù…Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
+  label_update_issue_done_ratios: Ø¨Ø±ÙˆØ² Ø±Ø³Ø§Ù†ÛŒ Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡ Ù¾ÛŒØ§Ù…Ø¯
+  label_copy_source: Ù…Ù†Ø¨Ø¹
+  label_copy_target: Ù…Ù‚ØµØ¯
+  label_copy_same_as_target: Ù…Ø§Ù†Ù†Ø¯ Ù…Ù‚ØµØ¯
+  label_display_used_statuses_only: ØªÙ†Ù‡Ø§ ÙˆØ¶Ø¹ÛŒØªâ€ŒÙ‡Ø§ÛŒÛŒ Ù†Ø´Ø§Ù† Ø¯Ø§Ø¯Ù‡ Ø´ÙˆÙ†Ø¯ Ú©Ù‡ Ø¯Ø± Ø§ÛŒÙ† Ù¾ÛŒÚ¯Ø±Ø¯ Ø¨Ù‡ Ú©Ø§Ø± Ø±ÙØªÙ‡â€ŒØ§Ù†Ø¯
+  label_api_access_key: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ API
+  label_missing_api_access_key: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ API Ø¯Ø± Ø¯Ø³ØªØ±Ø³ Ù†ÛŒØ³Øª
+  label_api_access_key_created_on: "Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ API %{value} Ù¾ÛŒØ´ Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª"
+  label_profile: Ù†Ù…Ø§ÛŒÙ‡
+  label_subtask_plural: Ø²ÛŒØ±Ú©Ø§Ø±
+  label_project_copy_notifications: Ø¯Ø± Ù‡Ù†Ú¯Ø§Ù… Ø±ÙˆÙ†ÙˆÛŒØ³ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ÛŒ Ø¢Ú¯Ø§Ù‡â€ŒØ³Ø§Ø²ÛŒ Ø±Ø§ Ø¨ÙØ±Ø³Øª
+  label_principal_search: "Ø¬Ø³ØªØ¬Ùˆ Ø¨Ø±Ø§ÛŒ Ú©Ø§Ø±Ø¨Ø± ÛŒØ§ Ø¯Ø³ØªÙ‡:"
+  label_user_search: "Ø¬Ø³ØªØ¬Ùˆ Ø¨Ø±Ø§ÛŒ Ú©Ø§Ø±Ø¨Ø±:"
+
+  button_login: ÙˆØ±ÙˆØ¯
+  button_submit: ÙˆØ§Ú¯Ø°Ø§Ø±ÛŒ
+  button_save: Ù†Ú¯Ù‡Ø¯Ø§Ø±ÛŒ
+  button_check_all: Ú¯Ø²ÛŒÙ†Ø´ Ù‡Ù…Ù‡
+  button_uncheck_all: Ú¯Ø²ÛŒÙ†Ø´ Ù‡ÛŒÚ†
+  button_delete: Ù¾Ø§Ú©
+  button_create: Ø³Ø§Ø®Øª
+  button_create_and_continue: Ø³Ø§Ø®Øª Ùˆ Ø§Ø¯Ø§Ù…Ù‡
+  button_test: Ø¢Ø²Ù…Ø§ÛŒØ´
+  button_edit: ÙˆÛŒØ±Ø§ÛŒØ´
+  button_edit_associated_wikipage: "ÙˆÛŒØ±Ø§ÛŒØ´ Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡: %{page_title}"
+  button_add: Ø§ÙØ²ÙˆØ¯Ù†
+  button_change: ÙˆÛŒØ±Ø§ÛŒØ´
+  button_apply: Ø§Ù†Ø¬Ø§Ù…
+  button_clear: Ù¾Ø§Ú©
+  button_lock: Ú¯Ø°Ø§Ø´ØªÙ† Ù‚ÙÙ„
+  button_unlock: Ø¨Ø±Ø¯Ø§Ø´ØªÙ† Ù‚ÙÙ„
+  button_download: Ø¯Ø±ÛŒØ§ÙØª
+  button_list: ÙÙ‡Ø±Ø³Øª
+  button_view: Ø¯ÛŒØ¯Ù†
+  button_move: Ø¬Ø§Ø¨Ø¬Ø§ÛŒÛŒ
+  button_move_and_follow: Ø¬Ø§Ø¨Ø¬Ø§ÛŒÛŒ Ùˆ Ø§Ø¯Ø§Ù…Ù‡
+  button_back: Ø¨Ø±Ú¯Ø´Øª
+  button_cancel: Ø¨Ø§Ø²Ú¯Ø´Øª
+  button_activate: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ
+  button_sort: Ø¬ÙˆØ± Ú©Ø±Ø¯
+  button_log_time: Ø²Ù…Ø§Ù†â€ŒÙ†ÙˆÛŒØ³ÛŒ
+  button_rollback: Ø¨Ø±Ú¯Ø±Ø¯ Ø¨Ù‡ Ø§ÛŒÙ† Ù†Ú¯Ø§Ø±Ø´
+  button_watch: Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†ÛŒ
+  button_unwatch: Ù†Ø§â€ŒØ¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†ÛŒ
+  button_reply: Ù¾Ø§Ø³Ø®
+  button_archive: Ø¨Ø§ÛŒÚ¯Ø§Ù†ÛŒ
+  button_unarchive: Ø¨Ø±Ú¯Ø´Øª Ø§Ø² Ø¨Ø§ÛŒÚ¯Ø§Ù†ÛŒ
+  button_reset: Ø¨Ø§Ø²Ù†Ø´Ø§Ù†ÛŒ
+  button_rename: Ù†Ø§Ù…Ú¯Ø°Ø§Ø±ÛŒ
+  button_change_password: Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ†ÛŒ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
+  button_copy: Ø±ÙˆÙ†ÙˆØ´Øª
+  button_copy_and_follow: Ø±ÙˆÙ†ÙˆØ´Øª Ùˆ Ø§Ø¯Ø§Ù…Ù‡
+  button_annotate: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
+  button_update: Ø¨Ø±ÙˆØ² Ø±Ø³Ø§Ù†ÛŒ
+  button_configure: Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ
+  button_quote: Ù†Ù‚Ù„ Ù‚ÙˆÙ„
+  button_duplicate: Ù†Ú¯Ø§Ø±Ø´ Ø¯ÛŒÚ¯Ø±
+  button_show: Ù†Ù…Ø§ÛŒØ´
+
+  status_active: ÙØ¹Ø§Ù„
+  status_registered: Ù†Ø§Ù…â€ŒÙ†ÙˆÛŒØ³ÛŒ Ø´Ø¯Ù‡
+  status_locked: Ù‚ÙÙ„
+
+  version_status_open: Ø¨Ø§Ø²
+  version_status_locked: Ù‚ÙÙ„
+  version_status_closed: Ø¨Ø³ØªÙ‡
+
+  field_active: ÙØ¹Ø§Ù„
+
+  text_select_mail_notifications: ÙØ±Ù…Ø§Ù†â€ŒÙ‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¨Ø±Ø§ÛŒ Ø¢Ù†â€ŒÙ‡Ø§ Ø¨Ø§ÛŒØ¯ Ø§ÛŒÙ…ÛŒÙ„ ÙØ±Ø³ØªØ§Ø¯Ù‡ Ø´ÙˆØ¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯.
+  text_regexp_info: Ø¨Ø±Ø§ÛŒ Ù†Ù…ÙˆÙ†Ù‡ ^[A-Z0-9]+$
+  text_min_max_length_info: 0 ÛŒØ¹Ù†ÛŒ Ø¨Ø¯ÙˆÙ† Ú©Ø±Ø§Ù†
+  text_project_destroy_confirmation: Ø¢ÛŒØ§ Ø¨Ø±Ø§Ø³ØªÛŒ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ Ùˆ Ù‡Ù…Ù‡ Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ø¢Ù† Ø±Ø§ Ù¾Ø§Ú© Ú©Ù†ÛŒØ¯ØŸ
+  text_subprojects_destroy_warning: "Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ø¢Ù†: %{value} Ù‡Ù… Ù¾Ø§Ú© Ø®ÙˆØ§Ù‡Ù†Ø¯ Ø´Ø¯."
+  text_workflow_edit: ÛŒÚ© Ù†Ù‚Ø´ Ùˆ ÛŒÚ© Ù¾ÛŒÚ¯Ø±Ø¯ Ø±Ø§ Ø¨Ø±Ø§ÛŒ ÙˆÛŒØ±Ø§ÛŒØ´ Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø± Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯
+  text_are_you_sure: Ø¢ÛŒØ§ Ø§ÛŒÙ† Ú©Ø§Ø± Ø§Ù†Ø¬Ø§Ù… Ø´ÙˆØ¯ØŸ
+  text_journal_changed: "Â«%{label}Â» Ø§Ø² Â«%{old}Â» Ø¨Ù‡ Â«%{new}Â» Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ† Ø´Ø¯"
+  text_journal_set_to: "Â«%{label}Â» Ø¨Ù‡ Â«%{value}Â» Ù†Ø´Ø§Ù†Ø¯Ù‡ Ø´Ø¯"
+  text_journal_deleted: "Â«%{label}Â» Ù¾Ø§Ú© Ø´Ø¯ (%{old})"
+  text_journal_added: "Â«%{label}Â»ØŒ Â«%{value}Â» Ø±Ø§ Ø§ÙØ²ÙˆØ¯"
+  text_tip_task_begin_day: Ø±ÙˆØ² Ø¢ØºØ§Ø² Ù¾ÛŒØ§Ù…Ø¯
+  text_tip_task_end_day: Ø±ÙˆØ² Ù¾Ø§ÛŒØ§Ù† Ù¾ÛŒØ§Ù…Ø¯
+  text_tip_task_begin_end_day: Ø±ÙˆØ² Ø¢ØºØ§Ø² Ùˆ Ù¾Ø§ÛŒØ§Ù† Ù¾ÛŒØ§Ù…Ø¯
+  text_caracters_maximum: "Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ %{count} Ø§Ø³Øª."
+  text_caracters_minimum: "Ú©Ù…ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ %{count} Ø§Ø³Øª."
+  text_length_between: "Ø¨Ø§ÛŒØ¯ Ù…ÛŒØ§Ù† %{min} Ùˆ %{max} Ù†ÙˆÛŒØ³Ù‡ Ø¨Ø§Ø´Ø¯."
+  text_tracker_no_workflow: Ù‡ÛŒÚ† Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø±ÛŒ Ø¨Ø±Ø§ÛŒ Ø§ÛŒÙ† Ù¾ÛŒÚ¯Ø±Ø¯ Ù…Ø´Ø®Øµ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª
+  text_unallowed_characters: Ù†ÙˆÛŒØ³Ù‡â€ŒÙ‡Ø§ÛŒ Ù†Ø§Ù¾Ø³Ù†Ø¯
+  text_comma_separated: Ú†Ù†Ø¯ Ù…Ù‚Ø¯Ø§Ø± Ù¾Ø°ÛŒØ±ÙØªÙ†ÛŒ Ø§Ø³Øª (Ø¨Ø§ Â«,Â» Ø§Ø² Ù‡Ù… Ø¬Ø¯Ø§ Ø´ÙˆÙ†Ø¯).
+  text_line_separated: Ú†Ù†Ø¯ Ù…Ù‚Ø¯Ø§Ø± Ù¾Ø°ÛŒØ±ÙØªÙ†ÛŒ Ø§Ø³Øª (Ù‡Ø± Ù…Ù‚Ø¯Ø§Ø± Ø¯Ø± ÛŒÚ© Ø®Ø·).
+  text_issues_ref_in_commit_messages: Ù†Ø´Ø§Ù†Ù‡ Ø±ÙˆÛŒ Ùˆ Ø¨Ø³ØªÙ† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ø¯Ø± Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡
+  text_issue_added: "Ù¾ÛŒØ§Ù…Ø¯ %{id} Ø¨Ù‡ Ø¯Ø³Øª %{author} Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯."
+  text_issue_updated: "Ù¾ÛŒØ§Ù…Ø¯ %{id} Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø¨Ø±ÙˆØ² Ø´Ø¯."
+  text_wiki_destroy_confirmation: Ø¢ÛŒØ§ Ø¨Ø±Ø§Ø³ØªÛŒ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ø§ÛŒÙ† ÙˆÛŒÚ©ÛŒ Ùˆ Ù‡Ù…Ù‡ Ù…Ø­ØªÙˆØ§ÛŒ Ø¢Ù† Ø±Ø§ Ù¾Ø§Ú© Ú©Ù†ÛŒØ¯ØŸ
+  text_issue_category_destroy_question: "Ø¨Ø±Ø®ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ (%{count}) Ø¨Ù‡ Ø§ÛŒÙ† Ø¯Ø³ØªÙ‡ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡â€ŒØ§Ù†Ø¯. Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ú†Ù‡ Ú©Ù†ÛŒØ¯ØŸ"
+  text_issue_category_destroy_assignments: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† ÙˆØ§Ú¯Ø°Ø§Ø±ÛŒ Ø¨Ù‡ Ø¯Ø³ØªÙ‡
+  text_issue_category_reassign_to: ÙˆØ§Ú¯Ø°Ø§Ø±ÛŒ Ø¯ÙˆØ¨Ø§Ø±Ù‡ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ø¨Ù‡ Ø§ÛŒÙ† Ø¯Ø³ØªÙ‡
+  text_user_mail_option: "Ø¨Ø±Ø§ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ú¯Ø²ÛŒÙ†Ø´ Ù†Ø´Ø¯Ù‡ØŒ ØªÙ†Ù‡Ø§ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ÛŒÛŒ Ø¯Ø±Ø¨Ø§Ø±Ù‡ Ú†ÛŒØ²Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù† ÛŒØ§ Ø¯Ø±Ú¯ÛŒØ± Ø¢Ù†â€ŒÙ‡Ø§ Ù‡Ø³ØªÛŒØ¯ Ø¯Ø±ÛŒØ§ÙØª Ø®ÙˆØ§Ù‡ÛŒØ¯ Ú©Ø±Ø¯ (Ù…Ø§Ù†Ù†Ø¯ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ù†ÙˆÛŒØ³Ù†Ø¯Ù‡ Ø¢Ù†â€ŒÙ‡Ø§ Ù‡Ø³ØªÛŒØ¯ ÛŒØ§ Ø¨Ù‡ Ø´Ù…Ø§ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡â€ŒØ§Ù†Ø¯)."
+  text_no_configuration_data: "Ù†Ù‚Ø´â€ŒÙ‡Ø§ØŒ Ù¾ÛŒÚ¯Ø±Ø¯Ù‡Ø§ØŒ ÙˆØ¶Ø¹ÛŒØªâ€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯ Ùˆ Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø± Ù‡Ù†ÙˆØ² Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù†Ø´Ø¯Ù‡â€ŒØ§Ù†Ø¯. \nØ¨Ù‡ Ø³Ø®ØªÛŒ Ù¾ÛŒØ´Ù†Ù‡Ø§Ø¯ Ù…ÛŒâ€ŒØ´ÙˆØ¯ Ú©Ù‡ Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ø±Ø§ Ø¨Ø§Ø± Ú©Ù†ÛŒØ¯. Ø³Ù¾Ø³ Ù…ÛŒâ€ŒØªÙˆØ§Ù†ÛŒØ¯ Ø¢Ù† Ø±Ø§ ÙˆÛŒØ±Ø§ÛŒØ´ Ú©Ù†ÛŒØ¯."
+  text_load_default_configuration: Ø¨Ø§Ø±Ú¯Ø°Ø§Ø±ÛŒ Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
+  text_status_changed_by_changeset: "Ø¯Ø± ØªØºÛŒÛŒØ± %{value} Ø¨Ø±ÙˆØ² Ø´Ø¯Ù‡ Ø§Ø³Øª."
+  text_time_logged_by_changeset: "Ø¯Ø± ØªØºÛŒÛŒØ± %{value} Ù†ÙˆØ´ØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª."
+  text_issues_destroy_confirmation: 'Ø¢ÛŒØ§ Ø¨Ø±Ø§Ø³ØªÛŒ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡ Ø±Ø§ Ù¾Ø§Ú© Ú©Ù†ÛŒØ¯ØŸ'
+  text_select_project_modules: 'Ù¾ÛŒÙ…Ø§Ù†Ù‡â€ŒÙ‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¨Ø§ÛŒØ¯ Ø¨Ø±Ø§ÛŒ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ ÙØ¹Ø§Ù„ Ø´ÙˆÙ†Ø¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯:'
+  text_default_administrator_account_changed: Ø­Ø³Ø§Ø¨ Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ† Ø´Ø¯
+  text_file_repository_writable: Ù¾ÙˆØ´Ù‡ Ù¾ÛŒÙˆØ³Øªâ€ŒÙ‡Ø§ Ù†ÙˆØ´ØªÙ†ÛŒ Ø§Ø³Øª
+  text_plugin_assets_writable: Ù¾ÙˆØ´Ù‡ Ø¯Ø§Ø±Ø§ÛŒÛŒâ€ŒÙ‡Ø§ÛŒ Ø§ÙØ²ÙˆÙ†Ù‡â€ŒÙ‡Ø§ Ù†ÙˆØ´ØªÙ†ÛŒ Ø§Ø³Øª
+  text_rmagick_available: RMagick Ø¯Ø± Ø¯Ø³ØªØ±Ø³ Ø§Ø³Øª (Ø§Ø®ØªÛŒØ§Ø±ÛŒ)
+  text_destroy_time_entries_question: "%{hours} Ø³Ø§Ø¹Øª Ø±ÙˆÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ù¾Ø§Ú© Ú©Ù†ÛŒØ¯ Ú©Ø§Ø± Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ø§Ø³Øª. Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ú†Ù‡ Ú©Ù†ÛŒØ¯ØŸ"
+  text_destroy_time_entries: Ø³Ø§Ø¹Øªâ€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ù¾Ø§Ú© Ø´ÙˆÙ†Ø¯
+  text_assign_time_entries_to_project: Ø³Ø§Ø¹Øªâ€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ø¨Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯
+  text_reassign_time_entries: 'Ø³Ø§Ø¹Øªâ€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ø¨Ù‡ Ø§ÛŒÙ† Ù¾ÛŒØ§Ù…Ø¯ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯:'
+  text_user_wrote: "%{value} Ù†ÙˆØ´Øª:"
+  text_enumeration_destroy_question: "%{count} Ø¯Ø§Ø¯Ù‡ Ø¨Ù‡ Ø§ÛŒÙ† Ø¨Ø±Ø´Ù…Ø±Ø¯Ù†ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡ Ø´Ø¯Ù‡â€ŒØ§Ù†Ø¯."
+  text_enumeration_category_reassign_to: 'Ø¨Ù‡ Ø§ÛŒÙ† Ø¨Ø±Ø´Ù…Ø±Ø¯Ù†ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡ Ø´ÙˆÙ†Ø¯:'
+  text_email_delivery_not_configured: "Ø¯Ø±ÛŒØ§ÙØª Ø§ÛŒÙ…ÛŒÙ„ Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª Ùˆ Ø¢Ú¯Ø§Ù‡â€ŒØ³Ø§Ø²ÛŒâ€ŒÙ‡Ø§ ØºÛŒØ± ÙØ¹Ø§Ù„ Ù‡Ø³ØªÙ†Ø¯.\nÚ©Ø§Ø±Ú¯Ø²Ø§Ø± SMTP Ø®ÙˆØ¯ Ø±Ø§ Ø¯Ø± config/configuration.yml Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ú©Ù†ÛŒØ¯ Ùˆ Ø¨Ø±Ù†Ø§Ù…Ù‡ Ø±Ø§ Ø¨Ø§Ø²Ù†Ø´Ø§Ù†ÛŒ Ú©Ù†ÛŒØ¯ ØªØ§ ÙØ¹Ø§Ù„ Ø´ÙˆÙ†Ø¯."
+  text_repository_usernames_mapping: "Ú©Ø§Ø±Ø¨Ø± Redmine Ú©Ù‡ Ø¨Ù‡ Ù‡Ø± Ù†Ø§Ù… Ú©Ø§Ø±Ø¨Ø±ÛŒ Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡ Ù†Ú¯Ø§Ø´Øª Ù…ÛŒâ€ŒØ´ÙˆØ¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯.\nÚ©Ø§Ø±Ø¨Ø±Ø§Ù†ÛŒ Ú©Ù‡ Ù†Ø§Ù… Ú©Ø§Ø±Ø¨Ø±ÛŒ ÛŒØ§ Ø§ÛŒÙ…ÛŒÙ„ Ù‡Ù…Ø³Ø§Ù† Ø¯Ø§Ø±Ù†Ø¯ØŒ Ø®ÙˆØ¯ Ø¨Ù‡ Ø®ÙˆØ¯ Ù†Ú¯Ø§Ø´Øª Ù…ÛŒâ€ŒØ´ÙˆÙ†Ø¯."
+  text_diff_truncated: '... Ø§ÛŒÙ† ØªÙØ§ÙˆØª Ø¨Ø±ÛŒØ¯Ù‡ Ø´Ø¯Ù‡ Ú†ÙˆÙ† Ø¨ÛŒØ´ØªØ± Ø§Ø² Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù†ÛŒ Ø§Ø³Øª.'
+  text_custom_field_possible_values_info: 'ÛŒÚ© Ø®Ø· Ø¨Ø±Ø§ÛŒ Ù‡Ø± Ù…Ù‚Ø¯Ø§Ø±'
+  text_wiki_page_destroy_question: "Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡ %{descendants} Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡ Ø¯Ø§Ø±Ø¯.Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ú†Ù‡ Ú©Ù†ÛŒØ¯ØŸ"
+  text_wiki_page_nullify_children: "Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ Ø¨Ø±Ú¯Ù‡ Ø±ÛŒØ´Ù‡ Ø´ÙˆÙ†Ø¯"
+  text_wiki_page_destroy_children: "Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ Ùˆ Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ÛŒ Ø¢Ù†â€ŒÙ‡Ø§ Ù¾Ø§Ú© Ø´ÙˆÙ†Ø¯"
+  text_wiki_page_reassign_children: "Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ Ø¨Ù‡ Ø²ÛŒØ± Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡ Ù¾Ø¯Ø± Ø¨Ø±ÙˆÙ†Ø¯"
+  text_own_membership_delete_confirmation: "Ø´Ù…Ø§ Ø¯Ø§Ø±ÛŒØ¯ Ø¨Ø±Ø®ÛŒ ÛŒØ§ Ù‡Ù…Ù‡ Ù¾Ø±ÙˆØ§Ù†Ù‡â€ŒÙ‡Ø§ÛŒ Ø®ÙˆØ¯ Ø±Ø§ Ø¨Ø±Ù…ÛŒâ€ŒØ¯Ø§Ø±ÛŒØ¯ Ùˆ Ø´Ø§ÛŒØ¯ Ù¾Ø³ Ø§Ø² Ø§ÛŒÙ† Ø¯ÛŒÚ¯Ø± Ù†ØªÙˆØ§Ù†ÛŒØ¯ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ Ø±Ø§ ÙˆÛŒØ±Ø§ÛŒØ´ Ú©Ù†ÛŒØ¯.\nØ¢ÛŒØ§ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ø§ÛŒÙ† Ú©Ø§Ø± Ø±Ø§ Ø¨Ú©Ù†ÛŒØ¯ØŸ"
+  text_zoom_in: Ø¯Ø±Ø´ØªÙ†Ù…Ø§ÛŒÛŒ
+  text_zoom_out: Ø±ÛŒØ²Ù†Ù…Ø§ÛŒÛŒ
+
+  default_role_manager: Ø³Ø±Ù¾Ø±Ø³Øª
+  default_role_developer: Ø¨Ø±Ù†Ø§Ù…Ù‡â€ŒÙ†ÙˆÛŒØ³
+  default_role_reporter: Ú¯Ø²Ø§Ø±Ø´â€ŒØ¯Ù‡Ù†Ø¯Ù‡
+  default_tracker_bug: Ø§ÛŒØ±Ø§Ø¯
+  default_tracker_feature: ÙˆÛŒÚ˜Ú¯ÛŒ
+  default_tracker_support: Ù¾Ø´ØªÛŒØ¨Ø§Ù†ÛŒ
+  default_issue_status_new: ØªØ§Ø²Ù‡
+  default_issue_status_in_progress: Ø¯Ø± Ú¯Ø±Ø¯Ø´
+  default_issue_status_resolved: Ø¯Ø±Ø³Øª Ø´Ø¯Ù‡
+  default_issue_status_feedback: Ø¨Ø§Ø²Ø®ÙˆØ±Ø¯
+  default_issue_status_closed: Ø¨Ø³ØªÙ‡
+  default_issue_status_rejected: Ø¨Ø±Ú¯Ø´Øª Ø®ÙˆØ±Ø¯Ù‡
+  default_doc_category_user: Ù†ÙˆØ´ØªØ§Ø± Ú©Ø§Ø±Ø¨Ø±
+  default_doc_category_tech: Ù†ÙˆØ´ØªØ§Ø± ÙÙ†ÛŒ
+  default_priority_low: Ù¾Ø§ÛŒÛŒÙ†
+  default_priority_normal: Ù…ÛŒØ§Ù†Ù‡
+  default_priority_high: Ø¨Ø§Ù„Ø§
+  default_priority_urgent: Ø²ÙˆØ¯
+  default_priority_immediate: Ø¨ÛŒØ¯Ø±Ù†Ú¯
+  default_activity_design: Ø·Ø±Ø§Ø­ÛŒ
+  default_activity_development: Ø³Ø§Ø®Øª
+
+  enumeration_issue_priorities: Ø¨Ø±ØªØ±ÛŒâ€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯
+  enumeration_doc_categories: Ø¯Ø³ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ù†ÙˆØ´ØªØ§Ø±
+  enumeration_activities: Ú©Ø§Ø±Ù‡Ø§ (Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ø²Ù…Ø§Ù†)
+  enumeration_system_activity: Ú©Ø§Ø± Ø³Ø§Ù…Ø§Ù†Ù‡
+
+  text_tip_issue_begin_day: Ù¾ÛŒØ§Ù…Ø¯ Ø¯Ø± Ø§ÛŒÙ† Ø±ÙˆØ² Ø¢ØºØ§Ø² Ù…ÛŒâ€ŒØ´ÙˆØ¯
+  field_warn_on_leaving_unsaved: Ù‡Ù†Ú¯Ø§Ù… ØªØ±Ú© Ø¨Ø±Ú¯Ù‡â€ŒØ§ÛŒ Ú©Ù‡ Ù†ÙˆØ´ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ø¢Ù† Ù†Ú¯Ù‡Ø¯Ø§Ø±ÛŒ Ù†Ø´Ø¯Ù‡ØŒ Ø¨Ù‡ Ù…Ù† Ù‡Ø´Ø¯Ø§Ø± Ø¨Ø¯Ù‡
+  text_tip_issue_begin_end_day: Ù¾ÛŒØ§Ù…Ø¯ Ø¯Ø± Ø§ÛŒÙ† Ø±ÙˆØ² Ø¢ØºØ§Ø² Ù…ÛŒâ€ŒØ´ÙˆØ¯ Ùˆ Ù¾Ø§ÛŒØ§Ù† Ù…ÛŒâ€ŒÙ¾Ø°ÛŒØ±Ø¯
+  text_tip_issue_end_day: Ù¾ÛŒØ§Ù…Ø¯ Ø¯Ø± Ø§ÛŒÙ† Ø±ÙˆØ² Ù¾Ø§ÛŒØ§Ù† Ù…ÛŒâ€ŒÙ¾Ø°ÛŒØ±Ø¯
+  text_warn_on_leaving_unsaved: Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡ Ø¯Ø§Ø±Ø§ÛŒ Ù†ÙˆØ´ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ù†Ú¯Ù‡Ø¯Ø§Ø±ÛŒ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª Ú©Ù‡ Ø§Ú¯Ø± Ø¢Ù† Ø±Ø§ ØªØ±Ú© Ú©Ù†ÛŒØ¯ØŒ Ø§Ø² Ù…ÛŒØ§Ù† Ù…ÛŒâ€ŒØ±ÙˆÙ†Ø¯.
+  label_my_queries: Ø¬Ø³ØªØ§Ø±Ù‡Ø§ÛŒ Ø³ÙØ§Ø±Ø´ÛŒ Ù…Ù†
+  text_journal_changed_no_detail: "%{label} Ø¨Ø±ÙˆØ² Ø´Ø¯"
+  label_news_comment_added: Ø¯ÛŒØ¯Ú¯Ø§Ù‡ Ø¨Ù‡ ÛŒÚ© Ø±ÙˆÛŒØ¯Ø§Ø¯ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
+  button_expand_all: Ø¨Ø§Ø² Ú©Ø±Ø¯Ù† Ù‡Ù…Ù‡
+  button_collapse_all: Ø¨Ø³ØªÙ† Ù‡Ù…Ù‡
+  label_additional_workflow_transitions_for_assignee: Ø²Ù…Ø§Ù†ÛŒ Ú©Ù‡ Ø¨Ù‡ Ú©Ø§Ø±Ø¨Ø± ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡ØŒ Ú¯Ø°Ø§Ø±Ù‡Ø§ÛŒ Ø¨ÛŒØ´ØªØ± Ù¾Ø°ÛŒØ±ÙØªÙ‡ Ù…ÛŒâ€ŒØ´ÙˆØ¯
+  label_additional_workflow_transitions_for_author: Ø²Ù…Ø§Ù†ÛŒ Ú©Ù‡ Ú©Ø§Ø±Ø¨Ø± Ù†ÙˆÛŒØ³Ù†Ø¯Ù‡ Ø§Ø³ØªØŒ Ú¯Ø°Ø§Ø±Ù‡Ø§ÛŒ Ø¨ÛŒØ´ØªØ± Ù¾Ø°ÛŒØ±ÙØªÙ‡ Ù…ÛŒâ€ŒØ´ÙˆØ¯
+  label_bulk_edit_selected_time_entries: ÙˆÛŒØ±Ø§ÛŒØ´ Ø¯Ø³ØªÙ‡â€ŒØ§ÛŒ Ø²Ù…Ø§Ù†â€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡
+  text_time_entries_destroy_confirmation: Ø¢ÛŒØ§ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ø²Ù…Ø§Ù†â€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡ Ù¾Ø§Ú© Ø´ÙˆÙ†Ø¯ØŸ
+  label_role_anonymous: Ù†Ø§Ø´Ù†Ø§Ø³
+  label_role_non_member: ØºÛŒØ± Ø¹Ø¶Ùˆ
+  label_issue_note_added: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
+  label_issue_status_updated: ÙˆØ¶Ø¹ÛŒØª Ø¨Ø±ÙˆØ² Ø´Ø¯
+  label_issue_priority_updated: Ø¨Ø±ØªØ±ÛŒ Ø¨Ø±ÙˆØ² Ø´Ø¯
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Ú©Ø¯Ú¯Ø°Ø§Ø±ÛŒ Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 Ù¾ÛŒØ§Ù…Ø¯
+    one:   1 Ù¾ÛŒØ§Ù…Ø¯
+    other: "%{count} Ù¾ÛŒØ§Ù…Ø¯"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: Ù‡Ù…Ù‡
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Ø¨Ø§ Ø²ÛŒØ± Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
+  label_cross_project_tree: Ø¨Ø§ Ø¯Ø±Ø®Øª Ù¾Ø±ÙˆÚ˜Ù‡
+  label_cross_project_hierarchy: Ø¨Ø§ Ø±Ø´ØªÙ‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
+  label_cross_project_system: Ø¨Ø§ Ù‡Ù…Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ø¬Ù…Ù„Ù‡
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/05/05366a1767d0cebdb112d7b0a839d8704040e98a.svn-base
--- a/.svn/pristine/05/05366a1767d0cebdb112d7b0a839d8704040e98a.svn-base
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env ruby
-#
-# You may specify the path to the FastCGI crash log (a log of unhandled
-# exceptions which forced the FastCGI instance to exit, great for debugging)
-# and the number of requests to process before running garbage collection.
-#
-# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
-# and the GC period is nil (turned off).  A reasonable number of requests
-# could range from 10-100 depending on the memory footprint of your app.
-#
-# Example:
-#   # Default log path, normal GC behavior.
-#   RailsFCGIHandler.process!
-#
-#   # Default log path, 50 requests between GC.
-#   RailsFCGIHandler.process! nil, 50
-#
-#   # Custom log path, normal GC behavior.
-#   RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
-#
-require File.dirname(__FILE__) + "/../config/environment"
-require 'fcgi_handler'
-
-RailsFCGIHandler.process!
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/05/05764e8ea551fb41de1ac455c66cb6f2907259b8.svn-base
--- /dev/null
+++ b/.svn/pristine/05/05764e8ea551fb41de1ac455c66cb6f2907259b8.svn-base
@@ -0,0 +1,22 @@
+/* Portuguese initialisation for the jQuery UI date picker plugin. */
+jQuery(function($){
+	$.datepicker.regional['pt'] = {
+		closeText: 'Fechar',
+		prevText: '&#x3C;Anterior',
+		nextText: 'Seguinte',
+		currentText: 'Hoje',
+		monthNames: ['Janeiro','Fevereiro','MarÃ§o','Abril','Maio','Junho',
+		'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
+		monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun',
+		'Jul','Ago','Set','Out','Nov','Dez'],
+		dayNames: ['Domingo','Segunda-feira','TerÃ§a-feira','Quarta-feira','Quinta-feira','Sexta-feira','SÃ¡bado'],
+		dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','SÃ¡b'],
+		dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','SÃ¡b'],
+		weekHeader: 'Sem',
+		dateFormat: 'dd/mm/yy',
+		firstDay: 0,
+		isRTL: false,
+		showMonthAfterYear: false,
+		yearSuffix: ''};
+	$.datepicker.setDefaults($.datepicker.regional['pt']);
+});
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/05/05d53773172688f95b7f90e6ffa69f1cbdf7504b.svn-base
--- a/.svn/pristine/05/05d53773172688f95b7f90e6ffa69f1cbdf7504b.svn-base
+++ /dev/null
@@ -1,97 +0,0 @@
-<div class="contextual">
-  &#171;
-  <% unless @changeset.previous.nil? -%>
-    <%= link_to_revision(@changeset.previous, @project, :text => l(:label_previous)) %>
-  <% else -%>
-    <%= l(:label_previous) %>
-  <% end -%>
-|
-  <% unless @changeset.next.nil? -%>
-    <%= link_to_revision(@changeset.next, @project, :text => l(:label_next)) %>
-  <% else -%>
-    <%= l(:label_next) %>
-  <% end -%>
-  &#187;&nbsp;
-
-  <% form_tag({:controller => 'repositories',
-               :action     => 'revision',
-               :id         => @project,
-               :rev        => nil},
-               :method     => :get) do %>
-    <%= text_field_tag 'rev', @rev, :size => 8 %>
-    <%= submit_tag 'OK', :name => nil %>
-  <% end %>
-</div>
-
-<h2><%= l(:label_revision) %> <%= format_revision(@changeset) %></h2>
-
-<table class="revision-info">
-  <% if @changeset.scmid %>
-    <tr>
-      <td>ID</td><td><%= h(@changeset.scmid) %></td>
-    </tr>
-  <% end %>
-  <% unless @changeset.parents.blank? %>
-    <tr>
-      <td><%= l(:label_parent_revision) %></td>
-      <td>
-        <%= @changeset.parents.collect{
-              |p| link_to_revision(p, @project, :text => format_revision(p))
-            }.join(", ") %>
-      </td>
-    </tr>
-  <% end %>
-  <% unless @changeset.children.blank? %>
-    <tr>
-      <td><%= l(:label_child_revision) %></td>
-      <td>
-       <%= @changeset.children.collect{
-              |p| link_to_revision(p, @project, :text => format_revision(p))
-             }.join(", ") %>
-      </td>
-    </tr>
-  <% end %>
-</table>
-<p>
-<span class="author">
-<%= authoring(@changeset.committed_on, @changeset.author) %>
-</span>
-</p>
-
-<%= textilizable @changeset.comments %>
-
-<% if @changeset.issues.visible.any? %>
-<h3><%= l(:label_related_issues) %></h3>
-<ul>
-<% @changeset.issues.visible.each do |issue| %>
-  <li><%= link_to_issue issue %></li>
-<% end %>
-</ul>
-<% end %>
-
-<% if User.current.allowed_to?(:browse_repository, @project) %>
-<h3><%= l(:label_attachment_plural) %></h3>
-<ul id="changes-legend">
-<li class="change change-A"><%= l(:label_added)    %></li>
-<li class="change change-M"><%= l(:label_modified) %></li>
-<li class="change change-C"><%= l(:label_copied)   %></li>
-<li class="change change-R"><%= l(:label_renamed)  %></li>
-<li class="change change-D"><%= l(:label_deleted)  %></li>
-</ul>
-
-<p><%= link_to(l(:label_view_diff),
-               :action => 'diff',
-               :id     => @project,
-               :path   => "",
-               :rev    => @changeset.identifier) if @changeset.changes.any? %></p>
-
-<div class="changeset-changes">
-<%= render_changeset_changes %>
-</div>
-<% end %>
-
-<% content_for :header_tags do %>
-<%= stylesheet_link_tag "scm" %>
-<% end %>
-
-<% html_title("#{l(:label_revision)} #{format_revision(@changeset)}") -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/05/05d8cde4a4e9772f7dcbafb481eff20153ca4409.svn-base
--- /dev/null
+++ b/.svn/pristine/05/05d8cde4a4e9772f7dcbafb481eff20153ca4409.svn-base
@@ -0,0 +1,98 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module MimeType
+
+    MIME_TYPES = {
+      'text/plain' => 'txt,tpl,properties,patch,diff,ini,readme,install,upgrade',
+      'text/css' => 'css',
+      'text/html' => 'html,htm,xhtml',
+      'text/jsp' => 'jsp',
+      'text/x-c' => 'c,cpp,cc,h,hh',
+      'text/x-csharp' => 'cs',
+      'text/x-java' => 'java',
+      'text/x-html-template' => 'rhtml',
+      'text/x-perl' => 'pl,pm',
+      'text/x-php' => 'php,php3,php4,php5',
+      'text/x-python' => 'py',
+      'text/x-ruby' => 'rb,rbw,ruby,rake,erb',
+      'text/x-csh' => 'csh',
+      'text/x-sh' => 'sh',
+      'text/xml' => 'xml,xsd,mxml',
+      'text/yaml' => 'yml,yaml',
+      'text/csv' => 'csv',
+      'text/x-po' => 'po',
+      'image/gif' => 'gif',
+      'image/jpeg' => 'jpg,jpeg,jpe',
+      'image/png' => 'png',
+      'image/tiff' => 'tiff,tif',
+      'image/x-ms-bmp' => 'bmp',
+      'image/x-xpixmap' => 'xpm',
+      'image/svg+xml'=> 'svg',
+      'application/javascript' => 'js',
+      'application/pdf' => 'pdf',
+      'application/rtf' => 'rtf',
+      'application/msword' => 'doc',
+      'application/vnd.ms-excel' => 'xls',
+      'application/vnd.ms-powerpoint' => 'ppt,pps',
+      'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
+      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
+      'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
+      'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx',
+      'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
+      'application/vnd.oasis.opendocument.text' => 'odt',
+      'application/vnd.oasis.opendocument.presentation' => 'odp',
+      'application/x-7z-compressed' => '7z',
+      'application/x-rar-compressed' => 'rar',
+      'application/x-tar' => 'tar',
+      'application/zip' => 'zip',
+      'application/x-gzip' => 'gz',
+    }.freeze
+
+    EXTENSIONS = MIME_TYPES.inject({}) do |map, (type, exts)|
+      exts.split(',').each {|ext| map[ext.strip] = type}
+      map
+    end
+
+    # returns mime type for name or nil if unknown
+    def self.of(name)
+      return nil unless name
+      m = name.to_s.match(/(^|\.)([^\.]+)$/)
+      EXTENSIONS[m[2].downcase] if m
+    end
+
+    # Returns the css class associated to
+    # the mime type of name
+    def self.css_class_of(name)
+      mime = of(name)
+      mime && mime.gsub('/', '-')
+    end
+
+    def self.main_mimetype_of(name)
+      mimetype = of(name)
+      mimetype.split('/').first if mimetype
+    end
+
+    # return true if mime-type for name is type/*
+    # otherwise false
+    def self.is_type?(type, name)
+      main_mimetype = main_mimetype_of(name)
+      type.to_s == main_mimetype
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/05/05fb4e3ebed828cf639f80e5d1d6da6095d43000.svn-base
--- /dev/null
+++ b/.svn/pristine/05/05fb4e3ebed828cf639f80e5d1d6da6095d43000.svn-base
@@ -0,0 +1,42 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class ProjectEnumerationsController < ApplicationController
+  before_filter :find_project_by_project_id
+  before_filter :authorize
+
+  def update
+    if request.put? && params[:enumerations]
+      Project.transaction do
+        params[:enumerations].each do |id, activity|
+          @project.update_or_create_time_entry_activity(id, activity)
+        end
+      end
+      flash[:notice] = l(:notice_successful_update)
+    end
+
+    redirect_to settings_project_path(@project, :tab => 'activities')
+  end
+
+  def destroy
+    @project.time_entry_activities.each do |time_entry_activity|
+      time_entry_activity.destroy(time_entry_activity.parent)
+    end
+    flash[:notice] = l(:notice_successful_update)
+    redirect_to settings_project_path(@project, :tab => 'activities')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/06/061fdfd5800e4aa71d26012579cbbe6954d78738.svn-base
--- a/.svn/pristine/06/061fdfd5800e4aa71d26012579cbbe6954d78738.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-# $Id: testem.rb 121 2006-05-15 18:36:24Z blackhedd $
-#
-#
-
-require 'test/unit'
-require 'tests/testber'
-require 'tests/testldif'
-require 'tests/testldap'
-require 'tests/testpsw'
-require 'tests/testfilter'
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/06/0661103167f6b9ecf574c505f5bd6a17eadf893e.svn-base
--- /dev/null
+++ b/.svn/pristine/06/0661103167f6b9ecf574c505f5bd6a17eadf893e.svn-base
@@ -0,0 +1,703 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require "digest/sha1"
+
+class User < Principal
+  include Redmine::SafeAttributes
+
+  # Different ways of displaying/sorting users
+  USER_FORMATS = {
+    :firstname_lastname => {
+        :string => '#{firstname} #{lastname}',
+        :order => %w(firstname lastname id),
+        :setting_order => 1
+      },
+    :firstname_lastinitial => {
+        :string => '#{firstname} #{lastname.to_s.chars.first}.',
+        :order => %w(firstname lastname id),
+        :setting_order => 2
+      },
+    :firstname => {
+        :string => '#{firstname}',
+        :order => %w(firstname id),
+        :setting_order => 3
+      },
+    :lastname_firstname => {
+        :string => '#{lastname} #{firstname}',
+        :order => %w(lastname firstname id),
+        :setting_order => 4
+      },
+    :lastname_coma_firstname => {
+        :string => '#{lastname}, #{firstname}',
+        :order => %w(lastname firstname id),
+        :setting_order => 5
+      },
+    :lastname => {
+        :string => '#{lastname}',
+        :order => %w(lastname id),
+        :setting_order => 6
+      },
+    :username => {
+        :string => '#{login}',
+        :order => %w(login id),
+        :setting_order => 7
+      },
+  }
+
+  MAIL_NOTIFICATION_OPTIONS = [
+    ['all', :label_user_mail_option_all],
+    ['selected', :label_user_mail_option_selected],
+    ['only_my_events', :label_user_mail_option_only_my_events],
+    ['only_assigned', :label_user_mail_option_only_assigned],
+    ['only_owner', :label_user_mail_option_only_owner],
+    ['none', :label_user_mail_option_none]
+  ]
+
+  has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)},
+                                   :after_remove => Proc.new {|user, group| group.user_removed(user)}
+  has_many :changesets, :dependent => :nullify
+  has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
+  has_one :rss_token, :class_name => 'Token', :conditions => "action='feeds'"
+  has_one :api_token, :class_name => 'Token', :conditions => "action='api'"
+  belongs_to :auth_source
+
+  scope :logged, lambda { where("#{User.table_name}.status <> #{STATUS_ANONYMOUS}") }
+  scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) }
+
+  acts_as_customizable
+
+  attr_accessor :password, :password_confirmation
+  attr_accessor :last_before_login_on
+  # Prevents unauthorized assignments
+  attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
+
+  LOGIN_LENGTH_LIMIT = 60
+  MAIL_LENGTH_LIMIT = 60
+
+  validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
+  validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, :case_sensitive => false
+  validates_uniqueness_of :mail, :if => Proc.new { |user| user.mail_changed? && user.mail.present? }, :case_sensitive => false
+  # Login must contain letters, numbers, underscores only
+  validates_format_of :login, :with => /\A[a-z0-9_\-@\.]*\z/i
+  validates_length_of :login, :maximum => LOGIN_LENGTH_LIMIT
+  validates_length_of :firstname, :lastname, :maximum => 30
+  validates_format_of :mail, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true
+  validates_length_of :mail, :maximum => MAIL_LENGTH_LIMIT, :allow_nil => true
+  validates_confirmation_of :password, :allow_nil => true
+  validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true
+  validate :validate_password_length
+
+  before_create :set_mail_notification
+  before_save   :update_hashed_password
+  before_destroy :remove_references_before_destroy
+
+  scope :in_group, lambda {|group|
+    group_id = group.is_a?(Group) ? group.id : group.to_i
+    where("#{User.table_name}.id IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id)
+  }
+  scope :not_in_group, lambda {|group|
+    group_id = group.is_a?(Group) ? group.id : group.to_i
+    where("#{User.table_name}.id NOT IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id)
+  }
+  scope :sorted, lambda { order(*User.fields_for_order_statement)}
+
+  def set_mail_notification
+    self.mail_notification = Setting.default_notification_option if self.mail_notification.blank?
+    true
+  end
+
+  def update_hashed_password
+    # update hashed_password if password was set
+    if self.password && self.auth_source_id.blank?
+      salt_password(password)
+    end
+  end
+
+  alias :base_reload :reload
+  def reload(*args)
+    @name = nil
+    @projects_by_role = nil
+    @membership_by_project_id = nil
+    base_reload(*args)
+  end
+
+  def mail=(arg)
+    write_attribute(:mail, arg.to_s.strip)
+  end
+
+  def identity_url=(url)
+    if url.blank?
+      write_attribute(:identity_url, '')
+    else
+      begin
+        write_attribute(:identity_url, OpenIdAuthentication.normalize_identifier(url))
+      rescue OpenIdAuthentication::InvalidOpenId
+        # Invalid url, don't save
+      end
+    end
+    self.read_attribute(:identity_url)
+  end
+
+  # Returns the user that matches provided login and password, or nil
+  def self.try_to_login(login, password)
+    login = login.to_s
+    password = password.to_s
+
+    # Make sure no one can sign in with an empty login or password
+    return nil if login.empty? || password.empty?
+    user = find_by_login(login)
+    if user
+      # user is already in local database
+      return nil unless user.active?
+      return nil unless user.check_password?(password)
+    else
+      # user is not yet registered, try to authenticate with available sources
+      attrs = AuthSource.authenticate(login, password)
+      if attrs
+        user = new(attrs)
+        user.login = login
+        user.language = Setting.default_language
+        if user.save
+          user.reload
+          logger.info("User '#{user.login}' created from external auth source: #{user.auth_source.type} - #{user.auth_source.name}") if logger && user.auth_source
+        end
+      end
+    end
+    user.update_column(:last_login_on, Time.now) if user && !user.new_record?
+    user
+  rescue => text
+    raise text
+  end
+
+  # Returns the user who matches the given autologin +key+ or nil
+  def self.try_to_autologin(key)
+    user = Token.find_active_user('autologin', key, Setting.autologin.to_i)
+    if user
+      user.update_column(:last_login_on, Time.now)
+      user
+    end
+  end
+
+  def self.name_formatter(formatter = nil)
+    USER_FORMATS[formatter || Setting.user_format] || USER_FORMATS[:firstname_lastname]
+  end
+
+  # Returns an array of fields names than can be used to make an order statement for users
+  # according to how user names are displayed
+  # Examples:
+  #
+  #   User.fields_for_order_statement              => ['users.login', 'users.id']
+  #   User.fields_for_order_statement('authors')   => ['authors.login', 'authors.id']
+  def self.fields_for_order_statement(table=nil)
+    table ||= table_name
+    name_formatter[:order].map {|field| "#{table}.#{field}"}
+  end
+
+  # Return user's full name for display
+  def name(formatter = nil)
+    f = self.class.name_formatter(formatter)
+    if formatter
+      eval('"' + f[:string] + '"')
+    else
+      @name ||= eval('"' + f[:string] + '"')
+    end
+  end
+
+  def active?
+    self.status == STATUS_ACTIVE
+  end
+
+  def registered?
+    self.status == STATUS_REGISTERED
+  end
+
+  def locked?
+    self.status == STATUS_LOCKED
+  end
+
+  def activate
+    self.status = STATUS_ACTIVE
+  end
+
+  def register
+    self.status = STATUS_REGISTERED
+  end
+
+  def lock
+    self.status = STATUS_LOCKED
+  end
+
+  def activate!
+    update_attribute(:status, STATUS_ACTIVE)
+  end
+
+  def register!
+    update_attribute(:status, STATUS_REGISTERED)
+  end
+
+  def lock!
+    update_attribute(:status, STATUS_LOCKED)
+  end
+
+  # Returns true if +clear_password+ is the correct user's password, otherwise false
+  def check_password?(clear_password)
+    if auth_source_id.present?
+      auth_source.authenticate(self.login, clear_password)
+    else
+      User.hash_password("#{salt}#{User.hash_password clear_password}") == hashed_password
+    end
+  end
+
+  # Generates a random salt and computes hashed_password for +clear_password+
+  # The hashed password is stored in the following form: SHA1(salt + SHA1(password))
+  def salt_password(clear_password)
+    self.salt = User.generate_salt
+    self.hashed_password = User.hash_password("#{salt}#{User.hash_password clear_password}")
+  end
+
+  # Does the backend storage allow this user to change their password?
+  def change_password_allowed?
+    return true if auth_source.nil?
+    return auth_source.allow_password_changes?
+  end
+
+  # Generate and set a random password.  Useful for automated user creation
+  # Based on Token#generate_token_value
+  #
+  def random_password
+    chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
+    password = ''
+    40.times { |i| password << chars[rand(chars.size-1)] }
+    self.password = password
+    self.password_confirmation = password
+    self
+  end
+
+  def pref
+    self.preference ||= UserPreference.new(:user => self)
+  end
+
+  def time_zone
+    @time_zone ||= (self.pref.time_zone.blank? ? nil : ActiveSupport::TimeZone[self.pref.time_zone])
+  end
+
+  def wants_comments_in_reverse_order?
+    self.pref[:comments_sorting] == 'desc'
+  end
+
+  # Return user's RSS key (a 40 chars long string), used to access feeds
+  def rss_key
+    if rss_token.nil?
+      create_rss_token(:action => 'feeds')
+    end
+    rss_token.value
+  end
+
+  # Return user's API key (a 40 chars long string), used to access the API
+  def api_key
+    if api_token.nil?
+      create_api_token(:action => 'api')
+    end
+    api_token.value
+  end
+
+  # Return an array of project ids for which the user has explicitly turned mail notifications on
+  def notified_projects_ids
+    @notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
+  end
+
+  def notified_project_ids=(ids)
+    Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
+    Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty?
+    @notified_projects_ids = nil
+    notified_projects_ids
+  end
+
+  def valid_notification_options
+    self.class.valid_notification_options(self)
+  end
+
+  # Only users that belong to more than 1 project can select projects for which they are notified
+  def self.valid_notification_options(user=nil)
+    # Note that @user.membership.size would fail since AR ignores
+    # :include association option when doing a count
+    if user.nil? || user.memberships.length < 1
+      MAIL_NOTIFICATION_OPTIONS.reject {|option| option.first == 'selected'}
+    else
+      MAIL_NOTIFICATION_OPTIONS
+    end
+  end
+
+  # Find a user account by matching the exact login and then a case-insensitive
+  # version.  Exact matches will be given priority.
+  def self.find_by_login(login)
+    if login.present?
+      login = login.to_s
+      # First look for an exact match
+      user = where(:login => login).all.detect {|u| u.login == login}
+      unless user
+        # Fail over to case-insensitive if none was found
+        user = where("LOWER(login) = ?", login.downcase).first
+      end
+      user
+    end
+  end
+
+  def self.find_by_rss_key(key)
+    Token.find_active_user('feeds', key)
+  end
+
+  def self.find_by_api_key(key)
+    Token.find_active_user('api', key)
+  end
+
+  # Makes find_by_mail case-insensitive
+  def self.find_by_mail(mail)
+    where("LOWER(mail) = ?", mail.to_s.downcase).first
+  end
+
+  # Returns true if the default admin account can no longer be used
+  def self.default_admin_account_changed?
+    !User.active.find_by_login("admin").try(:check_password?, "admin")
+  end
+
+  def to_s
+    name
+  end
+
+  CSS_CLASS_BY_STATUS = {
+    STATUS_ANONYMOUS  => 'anon',
+    STATUS_ACTIVE     => 'active',
+    STATUS_REGISTERED => 'registered',
+    STATUS_LOCKED     => 'locked'
+  }
+
+  def css_classes
+    "user #{CSS_CLASS_BY_STATUS[status]}"
+  end
+
+  # Returns the current day according to user's time zone
+  def today
+    if time_zone.nil?
+      Date.today
+    else
+      Time.now.in_time_zone(time_zone).to_date
+    end
+  end
+
+  # Returns the day of +time+ according to user's time zone
+  def time_to_date(time)
+    if time_zone.nil?
+      time.to_date
+    else
+      time.in_time_zone(time_zone).to_date
+    end
+  end
+
+  def logged?
+    true
+  end
+
+  def anonymous?
+    !logged?
+  end
+
+  # Returns user's membership for the given project
+  # or nil if the user is not a member of project
+  def membership(project)
+    project_id = project.is_a?(Project) ? project.id : project
+
+    @membership_by_project_id ||= Hash.new {|h, project_id|
+      h[project_id] = memberships.where(:project_id => project_id).first
+    }
+    @membership_by_project_id[project_id]
+  end
+
+  # Return user's roles for project
+  def roles_for_project(project)
+    roles = []
+    # No role on archived projects
+    return roles if project.nil? || project.archived?
+    if logged?
+      # Find project membership
+      membership = membership(project)
+      if membership
+        roles = membership.roles
+      else
+        @role_non_member ||= Role.non_member
+        roles << @role_non_member
+      end
+    else
+      @role_anonymous ||= Role.anonymous
+      roles << @role_anonymous
+    end
+    roles
+  end
+
+  # Return true if the user is a member of project
+  def member_of?(project)
+    projects.to_a.include?(project)
+  end
+
+  # Returns a hash of user's projects grouped by roles
+  def projects_by_role
+    return @projects_by_role if @projects_by_role
+
+    @projects_by_role = Hash.new([])
+    memberships.each do |membership|
+      if membership.project
+        membership.roles.each do |role|
+          @projects_by_role[role] = [] unless @projects_by_role.key?(role)
+          @projects_by_role[role] << membership.project
+        end
+      end
+    end
+    @projects_by_role.each do |role, projects|
+      projects.uniq!
+    end
+
+    @projects_by_role
+  end
+
+  # Returns true if user is arg or belongs to arg
+  def is_or_belongs_to?(arg)
+    if arg.is_a?(User)
+      self == arg
+    elsif arg.is_a?(Group)
+      arg.users.include?(self)
+    else
+      false
+    end
+  end
+
+  # Return true if the user is allowed to do the specified action on a specific context
+  # Action can be:
+  # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
+  # * a permission Symbol (eg. :edit_project)
+  # Context can be:
+  # * a project : returns true if user is allowed to do the specified action on this project
+  # * an array of projects : returns true if user is allowed on every project
+  # * nil with options[:global] set : check if user has at least one role allowed for this action,
+  #   or falls back to Non Member / Anonymous permissions depending if the user is logged
+  def allowed_to?(action, context, options={}, &block)
+    if context && context.is_a?(Project)
+      return false unless context.allows_to?(action)
+      # Admin users are authorized for anything else
+      return true if admin?
+
+      roles = roles_for_project(context)
+      return false unless roles
+      roles.any? {|role|
+        (context.is_public? || role.member?) &&
+        role.allowed_to?(action) &&
+        (block_given? ? yield(role, self) : true)
+      }
+    elsif context && context.is_a?(Array)
+      if context.empty?
+        false
+      else
+        # Authorize if user is authorized on every element of the array
+        context.map {|project| allowed_to?(action, project, options, &block)}.reduce(:&)
+      end
+    elsif options[:global]
+      # Admin users are always authorized
+      return true if admin?
+
+      # authorize if user has at least one role that has this permission
+      roles = memberships.collect {|m| m.roles}.flatten.uniq
+      roles << (self.logged? ? Role.non_member : Role.anonymous)
+      roles.any? {|role|
+        role.allowed_to?(action) &&
+        (block_given? ? yield(role, self) : true)
+      }
+    else
+      false
+    end
+  end
+
+  # Is the user allowed to do the specified action on any project?
+  # See allowed_to? for the actions and valid options.
+  def allowed_to_globally?(action, options, &block)
+    allowed_to?(action, nil, options.reverse_merge(:global => true), &block)
+  end
+
+  # Returns true if the user is allowed to delete his own account
+  def own_account_deletable?
+    Setting.unsubscribe? &&
+      (!admin? || User.active.where("admin = ? AND id <> ?", true, id).exists?)
+  end
+
+  safe_attributes 'login',
+    'firstname',
+    'lastname',
+    'mail',
+    'mail_notification',
+    'language',
+    'custom_field_values',
+    'custom_fields',
+    'identity_url'
+
+  safe_attributes 'status',
+    'auth_source_id',
+    :if => lambda {|user, current_user| current_user.admin?}
+
+  safe_attributes 'group_ids',
+    :if => lambda {|user, current_user| current_user.admin? && !user.new_record?}
+
+  # Utility method to help check if a user should be notified about an
+  # event.
+  #
+  # TODO: only supports Issue events currently
+  def notify_about?(object)
+    if mail_notification == 'all'
+      true
+    elsif mail_notification.blank? || mail_notification == 'none'
+      false
+    else
+      case object
+      when Issue
+        case mail_notification
+        when 'selected', 'only_my_events'
+          # user receives notifications for created/assigned issues on unselected projects
+          object.author == self || is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was)
+        when 'only_assigned'
+          is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was)
+        when 'only_owner'
+          object.author == self
+        end
+      when News
+        # always send to project members except when mail_notification is set to 'none'
+        true
+      end
+    end
+  end
+
+  def self.current=(user)
+    Thread.current[:current_user] = user
+  end
+
+  def self.current
+    Thread.current[:current_user] ||= User.anonymous
+  end
+
+  # Returns the anonymous user.  If the anonymous user does not exist, it is created.  There can be only
+  # one anonymous user per database.
+  def self.anonymous
+    anonymous_user = AnonymousUser.first
+    if anonymous_user.nil?
+      anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
+      raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
+    end
+    anonymous_user
+  end
+
+  # Salts all existing unsalted passwords
+  # It changes password storage scheme from SHA1(password) to SHA1(salt + SHA1(password))
+  # This method is used in the SaltPasswords migration and is to be kept as is
+  def self.salt_unsalted_passwords!
+    transaction do
+      User.where("salt IS NULL OR salt = ''").find_each do |user|
+        next if user.hashed_password.blank?
+        salt = User.generate_salt
+        hashed_password = User.hash_password("#{salt}#{user.hashed_password}")
+        User.where(:id => user.id).update_all(:salt => salt, :hashed_password => hashed_password)
+      end
+    end
+  end
+
+  protected
+
+  def validate_password_length
+    # Password length validation based on setting
+    if !password.nil? && password.size < Setting.password_min_length.to_i
+      errors.add(:password, :too_short, :count => Setting.password_min_length.to_i)
+    end
+  end
+
+  private
+
+  # Removes references that are not handled by associations
+  # Things that are not deleted are reassociated with the anonymous user
+  def remove_references_before_destroy
+    return if self.id.nil?
+
+    substitute = User.anonymous
+    Attachment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
+    Comment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
+    Issue.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
+    Issue.update_all 'assigned_to_id = NULL', ['assigned_to_id = ?', id]
+    Journal.update_all ['user_id = ?', substitute.id], ['user_id = ?', id]
+    JournalDetail.update_all ['old_value = ?', substitute.id.to_s], ["property = 'attr' AND prop_key = 'assigned_to_id' AND old_value = ?", id.to_s]
+    JournalDetail.update_all ['value = ?', substitute.id.to_s], ["property = 'attr' AND prop_key = 'assigned_to_id' AND value = ?", id.to_s]
+    Message.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
+    News.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
+    # Remove private queries and keep public ones
+    ::Query.delete_all ['user_id = ? AND is_public = ?', id, false]
+    ::Query.update_all ['user_id = ?', substitute.id], ['user_id = ?', id]
+    TimeEntry.update_all ['user_id = ?', substitute.id], ['user_id = ?', id]
+    Token.delete_all ['user_id = ?', id]
+    Watcher.delete_all ['user_id = ?', id]
+    WikiContent.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
+    WikiContent::Version.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
+  end
+
+  # Return password digest
+  def self.hash_password(clear_password)
+    Digest::SHA1.hexdigest(clear_password || "")
+  end
+
+  # Returns a 128bits random salt as a hex string (32 chars long)
+  def self.generate_salt
+    Redmine::Utils.random_hex(16)
+  end
+
+end
+
+class AnonymousUser < User
+  validate :validate_anonymous_uniqueness, :on => :create
+
+  def validate_anonymous_uniqueness
+    # There should be only one AnonymousUser in the database
+    errors.add :base, 'An anonymous user already exists.' if AnonymousUser.exists?
+  end
+
+  def available_custom_fields
+    []
+  end
+
+  # Overrides a few properties
+  def logged?; false end
+  def admin; false end
+  def name(*args); I18n.t(:label_user_anonymous) end
+  def mail; nil end
+  def time_zone; nil end
+  def rss_key; nil end
+
+  def pref
+    UserPreference.new(:user => self)
+  end
+
+  def member_of?(project)
+    false
+  end
+
+  # Anonymous user can not be destroyed
+  def destroy
+    false
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/06/066f939eced969c1eec65f1fe6ed629130668c67.svn-base
--- a/.svn/pristine/06/066f939eced969c1eec65f1fe6ed629130668c67.svn-base
+++ /dev/null
@@ -1,25 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module IssueRelationsHelper
-  def collection_for_relation_type_select
-    values = IssueRelation::TYPES
-    values.keys.sort{|x,y| values[x][:order] <=> values[y][:order]}.collect{|k| [l(values[k][:name]), k]}
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/06/067fc70eea1018fdccc706144d28aa0ea0565e34.svn-base
--- a/.svn/pristine/06/067fc70eea1018fdccc706144d28aa0ea0565e34.svn-base
+++ /dev/null
@@ -1,14 +0,0 @@
---- 
-watchers_001: 
-  watchable_type: Issue
-  watchable_id: 2
-  user_id: 3
-watchers_002: 
-  watchable_type: Message
-  watchable_id: 1
-  user_id: 1
-watchers_003: 
-  watchable_type: Issue
-  watchable_id: 2
-  user_id: 1
-  
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/06/068885f0c95ca2ed440e38b13dd95f7bb13f11dc.svn-base
--- a/.svn/pristine/06/068885f0c95ca2ed440e38b13dd95f7bb13f11dc.svn-base
+++ /dev/null
@@ -1,59 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class CustomFieldTest < ActiveSupport::TestCase
-  fixtures :custom_fields
-
-  def test_create
-    field = UserCustomField.new(:name => 'Money money money', :field_format => 'float')
-    assert field.save
-  end
-
-  def test_regexp_validation
-    field = IssueCustomField.new(:name => 'regexp', :field_format => 'text', :regexp => '[a-z0-9')
-    assert !field.save
-    assert_equal I18n.t('activerecord.errors.messages.invalid'), field.errors.on(:regexp)
-
-    field.regexp = '[a-z0-9]'
-    assert field.save
-  end
-
-  def test_possible_values_should_accept_an_array
-    field = CustomField.new
-    field.possible_values = ["One value", ""]
-    assert_equal ["One value"], field.possible_values
-  end
-
-  def test_possible_values_should_accept_a_string
-    field = CustomField.new
-    field.possible_values = "One value"
-    assert_equal ["One value"], field.possible_values
-  end
-
-  def test_possible_values_should_accept_a_multiline_string
-    field = CustomField.new
-    field.possible_values = "One value\nAnd another one  \r\n \n"
-    assert_equal ["One value", "And another one"], field.possible_values
-  end
-
-  def test_destroy
-    field = CustomField.find(1)
-    assert field.destroy
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/06/06aa9d1d0636535d93ef529aee72095eced64467.svn-base
--- a/.svn/pristine/06/06aa9d1d0636535d93ef529aee72095eced64467.svn-base
+++ /dev/null
@@ -1,18 +0,0 @@
-<%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %>
-
-<div class="contextual">
-  <%= render :partial => 'navigation' %>
-</div>
-
-<h2>
-  <%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => (@entry ? @entry.kind : nil), :revision => @rev } %>
-</h2>
-
-<p><%= render :partial => 'link_to_functions' %></p>
-
-<%= render_properties(@properties) %>
-
-<%= render(:partial => 'revisions',
-           :locals => {:project => @project, :path => @path, :revisions => @changesets, :entry => @entry }) unless @changesets.empty? %>
-
-<% html_title(l(:label_change_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/06/06b89fac956f5eaa8ae34a2daf2088c102b5cfb1.svn-base
--- a/.svn/pristine/06/06b89fac956f5eaa8ae34a2daf2088c102b5cfb1.svn-base
+++ /dev/null
@@ -1,136 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Enumeration < ActiveRecord::Base
-  default_scope :order => "#{Enumeration.table_name}.position ASC"
-
-  belongs_to :project
-
-  acts_as_list :scope => 'type = \'#{type}\''
-  acts_as_customizable
-  acts_as_tree :order => 'position ASC'
-
-  before_destroy :check_integrity
-  before_save    :check_default
-
-  validates_presence_of :name
-  validates_uniqueness_of :name, :scope => [:type, :project_id]
-  validates_length_of :name, :maximum => 30
-
-  named_scope :shared, :conditions => { :project_id => nil }
-  named_scope :active, :conditions => { :active => true }
-  named_scope :named, lambda {|arg| { :conditions => ["LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip]}}
-
-  def self.default
-    # Creates a fake default scope so Enumeration.default will check
-    # it's type.  STI subclasses will automatically add their own
-    # types to the finder.
-    if self.descends_from_active_record?
-      find(:first, :conditions => { :is_default => true, :type => 'Enumeration' })
-    else
-      # STI classes are
-      find(:first, :conditions => { :is_default => true })
-    end
-  end
-
-  # Overloaded on concrete classes
-  def option_name
-    nil
-  end
-
-  def check_default
-    if is_default? && is_default_changed?
-      Enumeration.update_all("is_default = #{connection.quoted_false}", {:type => type})
-    end
-  end
-
-  # Overloaded on concrete classes
-  def objects_count
-    0
-  end
-
-  def in_use?
-    self.objects_count != 0
-  end
-
-  # Is this enumeration overiding a system level enumeration?
-  def is_override?
-    !self.parent.nil?
-  end
-
-  alias :destroy_without_reassign :destroy
-
-  # Destroy the enumeration
-  # If a enumeration is specified, objects are reassigned
-  def destroy(reassign_to = nil)
-    if reassign_to && reassign_to.is_a?(Enumeration)
-      self.transfer_relations(reassign_to)
-    end
-    destroy_without_reassign
-  end
-
-  def <=>(enumeration)
-    position <=> enumeration.position
-  end
-
-  def to_s; name end
-
-  # Returns the Subclasses of Enumeration.  Each Subclass needs to be
-  # required in development mode.
-  #
-  # Note: subclasses is protected in ActiveRecord
-  def self.get_subclasses
-    @@subclasses[Enumeration]
-  end
-
-  # Does the +new+ Hash override the previous Enumeration?
-  def self.overridding_change?(new, previous)
-    if (same_active_state?(new['active'], previous.active)) && same_custom_values?(new,previous)
-      return false
-    else
-      return true
-    end
-  end
-
-  # Does the +new+ Hash have the same custom values as the previous Enumeration?
-  def self.same_custom_values?(new, previous)
-    previous.custom_field_values.each do |custom_value|
-      if custom_value.value != new["custom_field_values"][custom_value.custom_field_id.to_s]
-        return false
-      end
-    end
-
-    return true
-  end
-
-  # Are the new and previous fields equal?
-  def self.same_active_state?(new, previous)
-    new = (new == "1" ? true : false)
-    return new == previous
-  end
-
-private
-  def check_integrity
-    raise "Can't delete enumeration" if self.in_use?
-  end
-
-end
-
-# Force load the subclasses in development mode
-require_dependency 'time_entry_activity'
-require_dependency 'document_category'
-require_dependency 'issue_priority'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/06/06d13f36c723de5d4d11734c74881a345af8508f.svn-base
--- a/.svn/pristine/06/06d13f36c723de5d4d11734c74881a345af8508f.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= TestHelper.view_path_for __FILE__ %> (from app)
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/06/06efa9c81bf4ffa47e3211023e46fcb09d4eac0f.svn-base
--- /dev/null
+++ b/.svn/pristine/06/06efa9c81bf4ffa47e3211023e46fcb09d4eac0f.svn-base
@@ -0,0 +1,216 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RolesControllerTest < ActionController::TestCase
+  fixtures :roles, :users, :members, :member_roles, :workflows, :trackers
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 1 # admin
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+
+    assert_not_nil assigns(:roles)
+    assert_equal Role.order('builtin, position').all, assigns(:roles)
+
+    assert_tag :tag => 'a', :attributes => { :href => '/roles/1/edit' },
+                            :content => 'Manager'
+  end
+
+  def test_new
+    get :new
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_new_with_copy
+    copy_from = Role.find(2)
+
+    get :new, :copy => copy_from.id.to_s
+    assert_response :success
+    assert_template 'new'
+
+    role = assigns(:role)
+    assert_equal copy_from.permissions, role.permissions
+
+    assert_select 'form' do
+      # blank name
+      assert_select 'input[name=?][value=]', 'role[name]'
+      # edit_project permission checked
+      assert_select 'input[type=checkbox][name=?][value=edit_project][checked=checked]', 'role[permissions][]'
+      # add_project permission not checked
+      assert_select 'input[type=checkbox][name=?][value=add_project]', 'role[permissions][]'
+      assert_select 'input[type=checkbox][name=?][value=add_project][checked=checked]', 'role[permissions][]', 0
+      # workflow copy selected
+      assert_select 'select[name=?]', 'copy_workflow_from' do
+        assert_select 'option[value=2][selected=selected]'
+      end
+    end
+  end
+
+  def test_create_with_validaton_failure
+    post :create, :role => {:name => '',
+                         :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
+                         :assignable => '0'}
+
+    assert_response :success
+    assert_template 'new'
+    assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' }
+  end
+
+  def test_create_without_workflow_copy
+    post :create, :role => {:name => 'RoleWithoutWorkflowCopy',
+                         :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
+                         :assignable => '0'}
+
+    assert_redirected_to '/roles'
+    role = Role.find_by_name('RoleWithoutWorkflowCopy')
+    assert_not_nil role
+    assert_equal [:add_issues, :edit_issues, :log_time], role.permissions
+    assert !role.assignable?
+  end
+
+  def test_create_with_workflow_copy
+    post :create, :role => {:name => 'RoleWithWorkflowCopy',
+                         :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
+                         :assignable => '0'},
+               :copy_workflow_from => '1'
+
+    assert_redirected_to '/roles'
+    role = Role.find_by_name('RoleWithWorkflowCopy')
+    assert_not_nil role
+    assert_equal Role.find(1).workflow_rules.size, role.workflow_rules.size
+  end
+
+  def test_edit
+    get :edit, :id => 1
+    assert_response :success
+    assert_template 'edit'
+    assert_equal Role.find(1), assigns(:role)
+    assert_select 'select[name=?]', 'role[issues_visibility]'
+  end
+
+  def test_edit_anonymous
+    get :edit, :id => Role.anonymous.id
+    assert_response :success
+    assert_template 'edit'
+    assert_select 'select[name=?]', 'role[issues_visibility]', 0
+  end
+
+  def test_edit_invalid_should_respond_with_404
+    get :edit, :id => 999
+    assert_response 404
+  end
+
+  def test_update
+    put :update, :id => 1,
+                :role => {:name => 'Manager',
+                          :permissions => ['edit_project', ''],
+                          :assignable => '0'}
+
+    assert_redirected_to '/roles'
+    role = Role.find(1)
+    assert_equal [:edit_project], role.permissions
+  end
+
+  def test_update_with_failure
+    put :update, :id => 1, :role => {:name => ''}
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_destroy
+    r = Role.create!(:name => 'ToBeDestroyed', :permissions => [:view_wiki_pages])
+
+    delete :destroy, :id => r
+    assert_redirected_to '/roles'
+    assert_nil Role.find_by_id(r.id)
+  end
+
+  def test_destroy_role_in_use
+    delete :destroy, :id => 1
+    assert_redirected_to '/roles'
+    assert_equal 'This role is in use and cannot be deleted.', flash[:error] 
+    assert_not_nil Role.find_by_id(1)
+  end
+
+  def test_get_permissions
+    get :permissions
+    assert_response :success
+    assert_template 'permissions'
+
+    assert_not_nil assigns(:roles)
+    assert_equal Role.order('builtin, position').all, assigns(:roles)
+
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'permissions[3][]',
+                                                 :value => 'add_issues',
+                                                 :checked => 'checked' }
+
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'permissions[3][]',
+                                                 :value => 'delete_issues',
+                                                 :checked => nil }
+  end
+
+  def test_post_permissions
+    post :permissions, :permissions => { '0' => '', '1' => ['edit_issues'], '3' => ['add_issues', 'delete_issues']}
+    assert_redirected_to '/roles'
+
+    assert_equal [:edit_issues], Role.find(1).permissions
+    assert_equal [:add_issues, :delete_issues], Role.find(3).permissions
+    assert Role.find(2).permissions.empty?
+  end
+
+  def test_clear_all_permissions
+    post :permissions, :permissions => { '0' => '' }
+    assert_redirected_to '/roles'
+    assert Role.find(1).permissions.empty?
+  end
+
+  def test_move_highest
+    put :update, :id => 3, :role => {:move_to => 'highest'}
+    assert_redirected_to '/roles'
+    assert_equal 1, Role.find(3).position
+  end
+
+  def test_move_higher
+    position = Role.find(3).position
+    put :update, :id => 3, :role => {:move_to => 'higher'}
+    assert_redirected_to '/roles'
+    assert_equal position - 1, Role.find(3).position
+  end
+
+  def test_move_lower
+    position = Role.find(2).position
+    put :update, :id => 2, :role => {:move_to => 'lower'}
+    assert_redirected_to '/roles'
+    assert_equal position + 1, Role.find(2).position
+  end
+
+  def test_move_lowest
+    put :update, :id => 2, :role => {:move_to => 'lowest'}
+    assert_redirected_to '/roles'
+    assert_equal Role.count, Role.find(2).position
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/07/071c1af1d5f365dd709aaf606fafd0332e258d64.svn-base
--- /dev/null
+++ b/.svn/pristine/07/071c1af1d5f365dd709aaf606fafd0332e258d64.svn-base
@@ -0,0 +1,476 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine #:nodoc:
+
+  class PluginNotFound < StandardError; end
+  class PluginRequirementError < StandardError; end
+
+  # Base class for Redmine plugins.
+  # Plugins are registered using the <tt>register</tt> class method that acts as the public constructor.
+  #
+  #   Redmine::Plugin.register :example do
+  #     name 'Example plugin'
+  #     author 'John Smith'
+  #     description 'This is an example plugin for Redmine'
+  #     version '0.0.1'
+  #     settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'
+  #   end
+  #
+  # === Plugin attributes
+  #
+  # +settings+ is an optional attribute that let the plugin be configurable.
+  # It must be a hash with the following keys:
+  # * <tt>:default</tt>: default value for the plugin settings
+  # * <tt>:partial</tt>: path of the configuration partial view, relative to the plugin <tt>app/views</tt> directory
+  # Example:
+  #   settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'
+  # In this example, the settings partial will be found here in the plugin directory: <tt>app/views/settings/_settings.rhtml</tt>.
+  #
+  # When rendered, the plugin settings value is available as the local variable +settings+
+  class Plugin
+    cattr_accessor :directory
+    self.directory = File.join(Rails.root, 'plugins')
+
+    cattr_accessor :public_directory
+    self.public_directory = File.join(Rails.root, 'public', 'plugin_assets')
+
+    @registered_plugins = {}
+    class << self
+      attr_reader :registered_plugins
+      private :new
+
+      def def_field(*names)
+        class_eval do
+          names.each do |name|
+            define_method(name) do |*args|
+              args.empty? ? instance_variable_get("@#{name}") : instance_variable_set("@#{name}", *args)
+            end
+          end
+        end
+      end
+    end
+    def_field :name, :description, :url, :author, :author_url, :version, :settings
+    attr_reader :id
+
+    # Plugin constructor
+    def self.register(id, &block)
+      p = new(id)
+      p.instance_eval(&block)
+      # Set a default name if it was not provided during registration
+      p.name(id.to_s.humanize) if p.name.nil?
+
+      # Adds plugin locales if any
+      # YAML translation files should be found under <plugin>/config/locales/
+      ::I18n.load_path += Dir.glob(File.join(p.directory, 'config', 'locales', '*.yml'))
+
+      # Prepends the app/views directory of the plugin to the view path
+      view_path = File.join(p.directory, 'app', 'views')
+      if File.directory?(view_path)
+        ActionController::Base.prepend_view_path(view_path)
+        ActionMailer::Base.prepend_view_path(view_path)
+      end
+
+      # Adds the app/{controllers,helpers,models} directories of the plugin to the autoload path
+      Dir.glob File.expand_path(File.join(p.directory, 'app', '{controllers,helpers,models}')) do |dir|
+        ActiveSupport::Dependencies.autoload_paths += [dir]
+      end
+
+      registered_plugins[id] = p
+    end
+
+    # Returns an array of all registered plugins
+    def self.all
+      registered_plugins.values.sort
+    end
+
+    # Finds a plugin by its id
+    # Returns a PluginNotFound exception if the plugin doesn't exist
+    def self.find(id)
+      registered_plugins[id.to_sym] || raise(PluginNotFound)
+    end
+
+    # Clears the registered plugins hash
+    # It doesn't unload installed plugins
+    def self.clear
+      @registered_plugins = {}
+    end
+
+    # Checks if a plugin is installed
+    #
+    # @param [String] id name of the plugin
+    def self.installed?(id)
+      registered_plugins[id.to_sym].present?
+    end
+
+    def self.load
+      Dir.glob(File.join(self.directory, '*')).sort.each do |directory|
+        if File.directory?(directory)
+          lib = File.join(directory, "lib")
+          if File.directory?(lib)
+            $:.unshift lib
+            ActiveSupport::Dependencies.autoload_paths += [lib]
+          end
+          initializer = File.join(directory, "init.rb")
+          if File.file?(initializer)
+            require initializer
+          end
+        end
+      end
+    end
+
+    def initialize(id)
+      @id = id.to_sym
+    end
+
+    def directory
+      File.join(self.class.directory, id.to_s)
+    end
+
+    def public_directory
+      File.join(self.class.public_directory, id.to_s)
+    end
+
+    def to_param
+      id
+    end
+
+    def assets_directory
+      File.join(directory, 'assets')
+    end
+
+    def <=>(plugin)
+      self.id.to_s <=> plugin.id.to_s
+    end
+
+    # Sets a requirement on Redmine version
+    # Raises a PluginRequirementError exception if the requirement is not met
+    #
+    # Examples
+    #   # Requires Redmine 0.7.3 or higher
+    #   requires_redmine :version_or_higher => '0.7.3'
+    #   requires_redmine '0.7.3'
+    #
+    #   # Requires Redmine 0.7.x or higher
+    #   requires_redmine '0.7'
+    #
+    #   # Requires a specific Redmine version
+    #   requires_redmine :version => '0.7.3'              # 0.7.3 only
+    #   requires_redmine :version => '0.7'                # 0.7.x
+    #   requires_redmine :version => ['0.7.3', '0.8.0']   # 0.7.3 or 0.8.0
+    #
+    #   # Requires a Redmine version within a range
+    #   requires_redmine :version => '0.7.3'..'0.9.1'     # >= 0.7.3 and <= 0.9.1
+    #   requires_redmine :version => '0.7'..'0.9'         # >= 0.7.x and <= 0.9.x
+    def requires_redmine(arg)
+      arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
+      arg.assert_valid_keys(:version, :version_or_higher)
+
+      current = Redmine::VERSION.to_a
+      arg.each do |k, req|
+        case k
+        when :version_or_higher
+          raise ArgumentError.new(":version_or_higher accepts a version string only") unless req.is_a?(String)
+          unless compare_versions(req, current) <= 0
+            raise PluginRequirementError.new("#{id} plugin requires Redmine #{req} or higher but current is #{current.join('.')}")
+          end
+        when :version
+          req = [req] if req.is_a?(String)
+          if req.is_a?(Array)
+            unless req.detect {|ver| compare_versions(ver, current) == 0}
+              raise PluginRequirementError.new("#{id} plugin requires one the following Redmine versions: #{req.join(', ')} but current is #{current.join('.')}")
+            end
+          elsif req.is_a?(Range)
+            unless compare_versions(req.first, current) <= 0 && compare_versions(req.last, current) >= 0
+              raise PluginRequirementError.new("#{id} plugin requires a Redmine version between #{req.first} and #{req.last} but current is #{current.join('.')}")
+            end
+          else
+            raise ArgumentError.new(":version option accepts a version string, an array or a range of versions")
+          end
+        end
+      end
+      true
+    end
+
+    def compare_versions(requirement, current)
+      requirement = requirement.split('.').collect(&:to_i)
+      requirement <=> current.slice(0, requirement.size)
+    end
+    private :compare_versions
+
+    # Sets a requirement on a Redmine plugin version
+    # Raises a PluginRequirementError exception if the requirement is not met
+    #
+    # Examples
+    #   # Requires a plugin named :foo version 0.7.3 or higher
+    #   requires_redmine_plugin :foo, :version_or_higher => '0.7.3'
+    #   requires_redmine_plugin :foo, '0.7.3'
+    #
+    #   # Requires a specific version of a Redmine plugin
+    #   requires_redmine_plugin :foo, :version => '0.7.3'              # 0.7.3 only
+    #   requires_redmine_plugin :foo, :version => ['0.7.3', '0.8.0']   # 0.7.3 or 0.8.0
+    def requires_redmine_plugin(plugin_name, arg)
+      arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
+      arg.assert_valid_keys(:version, :version_or_higher)
+
+      plugin = Plugin.find(plugin_name)
+      current = plugin.version.split('.').collect(&:to_i)
+
+      arg.each do |k, v|
+        v = [] << v unless v.is_a?(Array)
+        versions = v.collect {|s| s.split('.').collect(&:to_i)}
+        case k
+        when :version_or_higher
+          raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
+          unless (current <=> versions.first) >= 0
+            raise PluginRequirementError.new("#{id} plugin requires the #{plugin_name} plugin #{v} or higher but current is #{current.join('.')}")
+          end
+        when :version
+          unless versions.include?(current.slice(0,3))
+            raise PluginRequirementError.new("#{id} plugin requires one the following versions of #{plugin_name}: #{v.join(', ')} but current is #{current.join('.')}")
+          end
+        end
+      end
+      true
+    end
+
+    # Adds an item to the given +menu+.
+    # The +id+ parameter (equals to the project id) is automatically added to the url.
+    #   menu :project_menu, :plugin_example, { :controller => 'example', :action => 'say_hello' }, :caption => 'Sample'
+    #
+    # +name+ parameter can be: :top_menu, :account_menu, :application_menu or :project_menu
+    #
+    def menu(menu, item, url, options={})
+      Redmine::MenuManager.map(menu).push(item, url, options)
+    end
+    alias :add_menu_item :menu
+
+    # Removes +item+ from the given +menu+.
+    def delete_menu_item(menu, item)
+      Redmine::MenuManager.map(menu).delete(item)
+    end
+
+    # Defines a permission called +name+ for the given +actions+.
+    #
+    # The +actions+ argument is a hash with controllers as keys and actions as values (a single value or an array):
+    #   permission :destroy_contacts, { :contacts => :destroy }
+    #   permission :view_contacts, { :contacts => [:index, :show] }
+    #
+    # The +options+ argument is a hash that accept the following keys:
+    # * :public => the permission is public if set to true (implicitly given to any user)
+    # * :require => can be set to one of the following values to restrict users the permission can be given to: :loggedin, :member
+    # * :read => set it to true so that the permission is still granted on closed projects
+    #
+    # Examples
+    #   # A permission that is implicitly given to any user
+    #   # This permission won't appear on the Roles & Permissions setup screen
+    #   permission :say_hello, { :example => :say_hello }, :public => true, :read => true
+    #
+    #   # A permission that can be given to any user
+    #   permission :say_hello, { :example => :say_hello }
+    #
+    #   # A permission that can be given to registered users only
+    #   permission :say_hello, { :example => :say_hello }, :require => :loggedin
+    #
+    #   # A permission that can be given to project members only
+    #   permission :say_hello, { :example => :say_hello }, :require => :member
+    def permission(name, actions, options = {})
+      if @project_module
+        Redmine::AccessControl.map {|map| map.project_module(@project_module) {|map|map.permission(name, actions, options)}}
+      else
+        Redmine::AccessControl.map {|map| map.permission(name, actions, options)}
+      end
+    end
+
+    # Defines a project module, that can be enabled/disabled for each project.
+    # Permissions defined inside +block+ will be bind to the module.
+    #
+    #   project_module :things do
+    #     permission :view_contacts, { :contacts => [:list, :show] }, :public => true
+    #     permission :destroy_contacts, { :contacts => :destroy }
+    #   end
+    def project_module(name, &block)
+      @project_module = name
+      self.instance_eval(&block)
+      @project_module = nil
+    end
+
+    # Registers an activity provider.
+    #
+    # Options:
+    # * <tt>:class_name</tt> - one or more model(s) that provide these events (inferred from event_type by default)
+    # * <tt>:default</tt> - setting this option to false will make the events not displayed by default
+    #
+    # A model can provide several activity event types.
+    #
+    # Examples:
+    #   register :news
+    #   register :scrums, :class_name => 'Meeting'
+    #   register :issues, :class_name => ['Issue', 'Journal']
+    #
+    # Retrieving events:
+    # Associated model(s) must implement the find_events class method.
+    # ActiveRecord models can use acts_as_activity_provider as a way to implement this class method.
+    #
+    # The following call should return all the scrum events visible by current user that occured in the 5 last days:
+    #   Meeting.find_events('scrums', User.current, 5.days.ago, Date.today)
+    #   Meeting.find_events('scrums', User.current, 5.days.ago, Date.today, :project => foo) # events for project foo only
+    #
+    # Note that :view_scrums permission is required to view these events in the activity view.
+    def activity_provider(*args)
+      Redmine::Activity.register(*args)
+    end
+
+    # Registers a wiki formatter.
+    #
+    # Parameters:
+    # * +name+ - human-readable name
+    # * +formatter+ - formatter class, which should have an instance method +to_html+
+    # * +helper+ - helper module, which will be included by wiki pages
+    def wiki_format_provider(name, formatter, helper)
+      Redmine::WikiFormatting.register(name, formatter, helper)
+    end
+
+    # Returns +true+ if the plugin can be configured.
+    def configurable?
+      settings && settings.is_a?(Hash) && !settings[:partial].blank?
+    end
+
+    def mirror_assets
+      source = assets_directory
+      destination = public_directory
+      return unless File.directory?(source)
+
+      source_files = Dir[source + "/**/*"]
+      source_dirs = source_files.select { |d| File.directory?(d) }
+      source_files -= source_dirs
+
+      unless source_files.empty?
+        base_target_dir = File.join(destination, File.dirname(source_files.first).gsub(source, ''))
+        begin
+          FileUtils.mkdir_p(base_target_dir)
+        rescue Exception => e
+          raise "Could not create directory #{base_target_dir}: " + e.message
+        end
+      end
+
+      source_dirs.each do |dir|
+        # strip down these paths so we have simple, relative paths we can
+        # add to the destination
+        target_dir = File.join(destination, dir.gsub(source, ''))
+        begin
+          FileUtils.mkdir_p(target_dir)
+        rescue Exception => e
+          raise "Could not create directory #{target_dir}: " + e.message
+        end
+      end
+
+      source_files.each do |file|
+        begin
+          target = File.join(destination, file.gsub(source, ''))
+          unless File.exist?(target) && FileUtils.identical?(file, target)
+            FileUtils.cp(file, target)
+          end
+        rescue Exception => e
+          raise "Could not copy #{file} to #{target}: " + e.message
+        end
+      end
+    end
+
+    # Mirrors assets from one or all plugins to public/plugin_assets
+    def self.mirror_assets(name=nil)
+      if name.present?
+        find(name).mirror_assets
+      else
+        all.each do |plugin|
+          plugin.mirror_assets
+        end
+      end
+    end
+
+    # The directory containing this plugin's migrations (<tt>plugin/db/migrate</tt>)
+    def migration_directory
+      File.join(Rails.root, 'plugins', id.to_s, 'db', 'migrate')
+    end
+
+    # Returns the version number of the latest migration for this plugin. Returns
+    # nil if this plugin has no migrations.
+    def latest_migration
+      migrations.last
+    end
+
+    # Returns the version numbers of all migrations for this plugin.
+    def migrations
+      migrations = Dir[migration_directory+"/*.rb"]
+      migrations.map { |p| File.basename(p).match(/0*(\d+)\_/)[1].to_i }.sort
+    end
+
+    # Migrate this plugin to the given version
+    def migrate(version = nil)
+      puts "Migrating #{id} (#{name})..."
+      Redmine::Plugin::Migrator.migrate_plugin(self, version)
+    end
+
+    # Migrates all plugins or a single plugin to a given version
+    # Exemples:
+    #   Plugin.migrate
+    #   Plugin.migrate('sample_plugin')
+    #   Plugin.migrate('sample_plugin', 1)
+    #
+    def self.migrate(name=nil, version=nil)
+      if name.present?
+        find(name).migrate(version)
+      else
+        all.each do |plugin|
+          plugin.migrate
+        end
+      end
+    end
+
+    class Migrator < ActiveRecord::Migrator
+      # We need to be able to set the 'current' plugin being migrated.
+      cattr_accessor :current_plugin
+    
+      class << self
+        # Runs the migrations from a plugin, up (or down) to the version given
+        def migrate_plugin(plugin, version)
+          self.current_plugin = plugin
+          return if current_version(plugin) == version
+          migrate(plugin.migration_directory, version)
+        end
+        
+        def current_version(plugin=current_plugin)
+          # Delete migrations that don't match .. to_i will work because the number comes first
+          ::ActiveRecord::Base.connection.select_values(
+            "SELECT version FROM #{schema_migrations_table_name}"
+          ).delete_if{ |v| v.match(/-#{plugin.id}/) == nil }.map(&:to_i).max || 0
+        end
+      end
+           
+      def migrated
+        sm_table = self.class.schema_migrations_table_name
+        ::ActiveRecord::Base.connection.select_values(
+          "SELECT version FROM #{sm_table}"
+        ).delete_if{ |v| v.match(/-#{current_plugin.id}/) == nil }.map(&:to_i).sort
+      end
+      
+      def record_version_state_after_migrating(version)
+        super(version.to_s + "-" + current_plugin.id.to_s)
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/07/073a34bd97c7ca9066ab7d9fa3f008e0e0da8c60.svn-base
--- /dev/null
+++ b/.svn/pristine/07/073a34bd97c7ca9066ab7d9fa3f008e0e0da8c60.svn-base
@@ -0,0 +1,172 @@
+var draw_gantt = null;
+var draw_top;
+var draw_right;
+var draw_left;
+
+var rels_stroke_width = 2;
+
+function setDrawArea() {
+  draw_top   = $("#gantt_draw_area").position().top;
+  draw_right = $("#gantt_draw_area").width();
+  draw_left  = $("#gantt_area").scrollLeft();
+}
+
+function getRelationsArray() {
+  var arr = new Array();
+  $.each($('div.task_todo[data-rels]'), function(index_div, element) {
+    var element_id = $(element).attr("id");
+    if (element_id != null) {
+      var issue_id = element_id.replace("task-todo-issue-", "");
+      var data_rels = $(element).data("rels");
+      for (rel_type_key in data_rels) {
+        $.each(data_rels[rel_type_key], function(index_issue, element_issue) {
+          arr.push({issue_from: issue_id, issue_to: element_issue,
+                    rel_type: rel_type_key});
+        });
+      }
+    }
+  });
+  return arr;
+}
+
+function drawRelations() {
+  var arr = getRelationsArray();
+  $.each(arr, function(index_issue, element_issue) {
+    var issue_from = $("#task-todo-issue-" + element_issue["issue_from"]);
+    var issue_to   = $("#task-todo-issue-" + element_issue["issue_to"]);
+    if (issue_from.size() == 0 || issue_to.size() == 0) {
+      return;
+    }
+    var issue_height = issue_from.height();
+    var issue_from_top   = issue_from.position().top  + (issue_height / 2) - draw_top;
+    var issue_from_right = issue_from.position().left + issue_from.width();
+    var issue_to_top   = issue_to.position().top  + (issue_height / 2) - draw_top;
+    var issue_to_left  = issue_to.position().left;
+    var color = issue_relation_type[element_issue["rel_type"]]["color"];
+    var landscape_margin = issue_relation_type[element_issue["rel_type"]]["landscape_margin"];
+    var issue_from_right_rel = issue_from_right + landscape_margin;
+    var issue_to_left_rel    = issue_to_left    - landscape_margin;
+    draw_gantt.path(["M", issue_from_right + draw_left,     issue_from_top,
+                     "L", issue_from_right_rel + draw_left, issue_from_top])
+                   .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+    if (issue_from_right_rel < issue_to_left_rel) {
+      draw_gantt.path(["M", issue_from_right_rel + draw_left, issue_from_top,
+                       "L", issue_from_right_rel + draw_left, issue_to_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+      draw_gantt.path(["M", issue_from_right_rel + draw_left, issue_to_top,
+                       "L", issue_to_left + draw_left,        issue_to_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+    } else {
+      var issue_middle_top = issue_to_top +
+                                (issue_height *
+                                   ((issue_from_top > issue_to_top) ? 1 : -1));
+      draw_gantt.path(["M", issue_from_right_rel + draw_left, issue_from_top,
+                       "L", issue_from_right_rel + draw_left, issue_middle_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+      draw_gantt.path(["M", issue_from_right_rel + draw_left, issue_middle_top,
+                       "L", issue_to_left_rel + draw_left,    issue_middle_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+      draw_gantt.path(["M", issue_to_left_rel + draw_left, issue_middle_top,
+                       "L", issue_to_left_rel + draw_left, issue_to_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+      draw_gantt.path(["M", issue_to_left_rel + draw_left, issue_to_top,
+                       "L", issue_to_left + draw_left,     issue_to_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+    }
+    draw_gantt.path(["M", issue_to_left + draw_left, issue_to_top,
+                     "l", -4 * rels_stroke_width, -2 * rels_stroke_width,
+                     "l", 0, 4 * rels_stroke_width, "z"])
+                   .attr({stroke: "none",
+                          fill: color,
+                          "stroke-linecap": "butt",
+                          "stroke-linejoin": "miter"
+                          });
+  });
+}
+
+function getProgressLinesArray() {
+  var arr = new Array();
+  var today_left = $('#today_line').position().left;
+  arr.push({left: today_left, top: 0});
+  $.each($('div.issue-subject, div.version-name'), function(index, element) {
+    var t = $(element).position().top - draw_top ;
+    var h = ($(element).height() / 9);
+    var element_top_upper  = t - h;
+    var element_top_center = t + (h * 3);
+    var element_top_lower  = t + (h * 8);
+    var issue_closed   = $(element).children('span').hasClass('issue-closed');
+    var version_closed = $(element).children('span').hasClass('version-closed');
+    if (issue_closed || version_closed) {
+      arr.push({left: today_left, top: element_top_center});
+    } else {
+      var issue_done = $("#task-done-" + $(element).attr("id"));
+      var is_behind_start = $(element).children('span').hasClass('behind-start-date');
+      var is_over_end     = $(element).children('span').hasClass('over-end-date');
+      if (is_over_end) {
+        arr.push({left: draw_right, top: element_top_upper, is_right_edge: true});
+        arr.push({left: draw_right, top: element_top_lower, is_right_edge: true, none_stroke: true});
+      } else if (issue_done.size() > 0) {
+        var done_left = issue_done.first().position().left +
+                           issue_done.first().width();
+        arr.push({left: done_left, top: element_top_center});
+      } else if (is_behind_start) {
+        arr.push({left: 0 , top: element_top_upper, is_left_edge: true});
+        arr.push({left: 0 , top: element_top_lower, is_left_edge: true, none_stroke: true});
+      } else {
+        var todo_left = today_left;
+        var issue_todo = $("#task-todo-" + $(element).attr("id"));
+        if (issue_todo.size() > 0){
+          todo_left = issue_todo.first().position().left;
+        }
+        arr.push({left: Math.min(today_left, todo_left), top: element_top_center});
+      }
+    }
+  });
+  return arr;
+}
+
+function drawGanttProgressLines() {
+  var arr = getProgressLinesArray();
+  var color = $("#today_line")
+                    .css("border-left-color");
+  var i;
+  for(i = 1 ; i < arr.length ; i++) {
+    if (!("none_stroke" in arr[i]) &&
+        (!("is_right_edge" in arr[i - 1] && "is_right_edge" in arr[i]) &&
+         !("is_left_edge"  in arr[i - 1] && "is_left_edge"  in arr[i]))
+        ) {
+      var x1 = (arr[i - 1].left == 0) ? 0 : arr[i - 1].left + draw_left;
+      var x2 = (arr[i].left == 0)     ? 0 : arr[i].left     + draw_left;
+      draw_gantt.path(["M", x1, arr[i - 1].top,
+                       "L", x2, arr[i].top])
+                   .attr({stroke: color, "stroke-width": 2});
+    }
+  }
+}
+
+function drawGanttHandler() {
+  var folder = document.getElementById('gantt_draw_area');
+  if(draw_gantt != null)
+    draw_gantt.clear();
+  else
+    draw_gantt = Raphael(folder);
+  setDrawArea();
+  if ($("#draw_progress_line").attr('checked'))
+    drawGanttProgressLines();
+  if ($("#draw_rels").attr('checked'))
+    drawRelations();
+}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/07/07402976102eaabe37c42cc6aab7aeb00d221891.svn-base
--- a/.svn/pristine/07/07402976102eaabe37c42cc6aab7aeb00d221891.svn-base
+++ /dev/null
@@ -1,164 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'repositories_controller'
-
-# Re-raise errors caught by the controller.
-class RepositoriesController; def rescue_action(e) raise e end; end
-
-class RepositoriesDarcsControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles,
-           :repositories, :enabled_modules
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
-  PRJ_ID = 3
-  NUM_REV = 6
-
-  def setup
-    @controller = RepositoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @project = Project.find(PRJ_ID)
-    @repository = Repository::Darcs.create(
-                        :project      => @project,
-                        :url          => REPOSITORY_PATH,
-                        :log_encoding => 'UTF-8'
-                        )
-    assert @repository
-  end
-
-  if File.directory?(REPOSITORY_PATH)
-    def test_browse_root
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal 3, assigns(:entries).size
-      assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
-    end
-
-    def test_browse_directory
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :path => ['images']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name)
-      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
-      assert_not_nil entry
-      assert_equal 'file', entry.kind
-      assert_equal 'images/edit.png', entry.path
-    end
-
-    def test_browse_at_given_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :path => ['images'], :rev => 1
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['delete.png'], assigns(:entries).collect(&:name)
-    end
-
-    def test_changes
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :changes, :id => PRJ_ID, :path => ['images', 'edit.png']
-      assert_response :success
-      assert_template 'changes'
-      assert_tag :tag => 'h2', :content => 'edit.png'
-    end
-
-    def test_diff
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      # Full diff of changeset 5
-      ['inline', 'sbs'].each do |dt|
-        get :diff, :id => PRJ_ID, :rev => 5, :type => dt
-        assert_response :success
-        assert_template 'diff'
-        # Line 22 removed
-        assert_tag :tag => 'th',
-                   :content => '22',
-                   :sibling => { :tag => 'td',
-                                 :attributes => { :class => /diff_out/ },
-                                 :content => /def remove/ }
-      end
-    end
-
-    def test_destroy_valid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-
-    def test_destroy_invalid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-
-      @repository = Repository::Darcs.create(
-                        :project      => @project,
-                        :url          => "/invalid",
-                        :log_encoding => 'UTF-8'
-                        )
-      assert @repository
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal 0, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-  else
-    puts "Darcs test repository NOT FOUND. Skipping functional tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/07/074588d42b3ac157ab70417170443c5531685d7e.svn-base
--- a/.svn/pristine/07/074588d42b3ac157ab70417170443c5531685d7e.svn-base
+++ /dev/null
@@ -1,270 +0,0 @@
-module ActiveRecord
-  module Acts #:nodoc:
-    module List #:nodoc:
-      def self.included(base)
-        base.extend(ClassMethods)
-      end
-
-      # This +acts_as+ extension provides the capabilities for sorting and reordering a number of objects in a list.
-      # The class that has this specified needs to have a +position+ column defined as an integer on
-      # the mapped database table.
-      #
-      # Todo list example:
-      #
-      #   class TodoList < ActiveRecord::Base
-      #     has_many :todo_items, :order => "position"
-      #   end
-      #
-      #   class TodoItem < ActiveRecord::Base
-      #     belongs_to :todo_list
-      #     acts_as_list :scope => :todo_list
-      #   end
-      #
-      #   todo_list.first.move_to_bottom
-      #   todo_list.last.move_higher
-      module ClassMethods
-        # Configuration options are:
-        #
-        # * +column+ - specifies the column name to use for keeping the position integer (default: +position+)
-        # * +scope+ - restricts what is to be considered a list. Given a symbol, it'll attach <tt>_id</tt> 
-        #   (if it hasn't already been added) and use that as the foreign key restriction. It's also possible 
-        #   to give it an entire string that is interpolated if you need a tighter scope than just a foreign key.
-        #   Example: <tt>acts_as_list :scope => 'todo_list_id = #{todo_list_id} AND completed = 0'</tt>
-        def acts_as_list(options = {})
-          configuration = { :column => "position", :scope => "1 = 1" }
-          configuration.update(options) if options.is_a?(Hash)
-
-          configuration[:scope] = "#{configuration[:scope]}_id".intern if configuration[:scope].is_a?(Symbol) && configuration[:scope].to_s !~ /_id$/
-
-          if configuration[:scope].is_a?(Symbol)
-            scope_condition_method = %(
-              def scope_condition
-                if #{configuration[:scope].to_s}.nil?
-                  "#{configuration[:scope].to_s} IS NULL"
-                else
-                  "#{configuration[:scope].to_s} = \#{#{configuration[:scope].to_s}}"
-                end
-              end
-            )
-          else
-            scope_condition_method = "def scope_condition() \"#{configuration[:scope]}\" end"
-          end
-
-          class_eval <<-EOV
-            include ActiveRecord::Acts::List::InstanceMethods
-
-            def acts_as_list_class
-              ::#{self.name}
-            end
-
-            def position_column
-              '#{configuration[:column]}'
-            end
-
-            #{scope_condition_method}
-
-            before_destroy :remove_from_list
-            before_create  :add_to_list_bottom
-          EOV
-        end
-      end
-
-      # All the methods available to a record that has had <tt>acts_as_list</tt> specified. Each method works
-      # by assuming the object to be the item in the list, so <tt>chapter.move_lower</tt> would move that chapter
-      # lower in the list of all chapters. Likewise, <tt>chapter.first?</tt> would return +true+ if that chapter is
-      # the first in the list of all chapters.
-      module InstanceMethods
-        # Insert the item at the given position (defaults to the top position of 1).
-        def insert_at(position = 1)
-          insert_at_position(position)
-        end
-
-        # Swap positions with the next lower item, if one exists.
-        def move_lower
-          return unless lower_item
-
-          acts_as_list_class.transaction do
-            lower_item.decrement_position
-            increment_position
-          end
-        end
-
-        # Swap positions with the next higher item, if one exists.
-        def move_higher
-          return unless higher_item
-
-          acts_as_list_class.transaction do
-            higher_item.increment_position
-            decrement_position
-          end
-        end
-
-        # Move to the bottom of the list. If the item is already in the list, the items below it have their
-        # position adjusted accordingly.
-        def move_to_bottom
-          return unless in_list?
-          acts_as_list_class.transaction do
-            decrement_positions_on_lower_items
-            assume_bottom_position
-          end
-        end
-
-        # Move to the top of the list. If the item is already in the list, the items above it have their
-        # position adjusted accordingly.
-        def move_to_top
-          return unless in_list?
-          acts_as_list_class.transaction do
-            increment_positions_on_higher_items
-            assume_top_position
-          end
-        end
-        
-        # Move to the given position
-        def move_to=(pos)
-          case pos.to_s
-          when 'highest'
-            move_to_top
-          when 'higher'
-            move_higher
-          when 'lower'
-            move_lower
-          when 'lowest'
-            move_to_bottom
-          end
-        end
-
-        # Removes the item from the list.
-        def remove_from_list
-          if in_list?
-            decrement_positions_on_lower_items
-            update_attribute position_column, nil
-          end
-        end
-
-        # Increase the position of this item without adjusting the rest of the list.
-        def increment_position
-          return unless in_list?
-          update_attribute position_column, self.send(position_column).to_i + 1
-        end
-
-        # Decrease the position of this item without adjusting the rest of the list.
-        def decrement_position
-          return unless in_list?
-          update_attribute position_column, self.send(position_column).to_i - 1
-        end
-
-        # Return +true+ if this object is the first in the list.
-        def first?
-          return false unless in_list?
-          self.send(position_column) == 1
-        end
-
-        # Return +true+ if this object is the last in the list.
-        def last?
-          return false unless in_list?
-          self.send(position_column) == bottom_position_in_list
-        end
-
-        # Return the next higher item in the list.
-        def higher_item
-          return nil unless in_list?
-          acts_as_list_class.find(:first, :conditions =>
-            "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}"
-          )
-        end
-
-        # Return the next lower item in the list.
-        def lower_item
-          return nil unless in_list?
-          acts_as_list_class.find(:first, :conditions =>
-            "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}"
-          )
-        end
-
-        # Test if this record is in a list
-        def in_list?
-          !send(position_column).nil?
-        end
-
-        private
-          def add_to_list_top
-            increment_positions_on_all_items
-          end
-
-          def add_to_list_bottom
-            self[position_column] = bottom_position_in_list.to_i + 1
-          end
-
-          # Overwrite this method to define the scope of the list changes
-          def scope_condition() "1" end
-
-          # Returns the bottom position number in the list.
-          #   bottom_position_in_list    # => 2
-          def bottom_position_in_list(except = nil)
-            item = bottom_item(except)
-            item ? item.send(position_column) : 0
-          end
-
-          # Returns the bottom item
-          def bottom_item(except = nil)
-            conditions = scope_condition
-            conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except
-            acts_as_list_class.find(:first, :conditions => conditions, :order => "#{position_column} DESC")
-          end
-
-          # Forces item to assume the bottom position in the list.
-          def assume_bottom_position
-            update_attribute(position_column, bottom_position_in_list(self).to_i + 1)
-          end
-
-          # Forces item to assume the top position in the list.
-          def assume_top_position
-            update_attribute(position_column, 1)
-          end
-
-          # This has the effect of moving all the higher items up one.
-          def decrement_positions_on_higher_items(position)
-            acts_as_list_class.update_all(
-              "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} <= #{position}"
-            )
-          end
-
-          # This has the effect of moving all the lower items up one.
-          def decrement_positions_on_lower_items
-            return unless in_list?
-            acts_as_list_class.update_all(
-              "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} > #{send(position_column).to_i}"
-            )
-          end
-
-          # This has the effect of moving all the higher items down one.
-          def increment_positions_on_higher_items
-            return unless in_list?
-            acts_as_list_class.update_all(
-              "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} < #{send(position_column).to_i}"
-            )
-          end
-
-          # This has the effect of moving all the lower items down one.
-          def increment_positions_on_lower_items(position)
-            acts_as_list_class.update_all(
-              "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} >= #{position}"
-           )
-          end
-
-          # Increments position (<tt>position_column</tt>) of all items in the list.
-          def increment_positions_on_all_items
-            acts_as_list_class.update_all(
-              "#{position_column} = (#{position_column} + 1)",  "#{scope_condition}"
-            )
-          end
-
-          def insert_at_position(position)
-            remove_from_list
-            increment_positions_on_lower_items(position)
-            self.update_attribute(position_column, position)
-          end
-      end 
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/07/07ff3aff4af2ca5266644ab7e838820cda8c8752.svn-base
--- /dev/null
+++ b/.svn/pristine/07/07ff3aff4af2ca5266644ab7e838820cda8c8752.svn-base
@@ -0,0 +1,27 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingAutoCompletesTest < ActionController::IntegrationTest
+  def test_auto_completes
+    assert_routing(
+        { :method => 'get', :path => "/issues/auto_complete" },
+        { :controller => 'auto_completes', :action => 'issues' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/08/0856b80a2e3d388f4f051bee68228eb434db38ab.svn-base
--- a/.svn/pristine/08/0856b80a2e3d388f4f051bee68228eb434db38ab.svn-base
+++ /dev/null
@@ -1,49 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::AccessControlTest < ActiveSupport::TestCase
-
-  def setup
-    @access_module = Redmine::AccessControl
-  end
-
-  def test_permissions
-    perms = @access_module.permissions
-    assert perms.is_a?(Array)
-    assert perms.first.is_a?(Redmine::AccessControl::Permission)
-  end
-
-  def test_module_permission
-    perm = @access_module.permission(:view_issues)
-    assert perm.is_a?(Redmine::AccessControl::Permission)
-    assert_equal :view_issues, perm.name
-    assert_equal :issue_tracking, perm.project_module
-    assert perm.actions.is_a?(Array)
-    assert perm.actions.include?('issues/index')
-  end
-
-  def test_no_module_permission
-    perm = @access_module.permission(:edit_project)
-    assert perm.is_a?(Redmine::AccessControl::Permission)
-    assert_equal :edit_project, perm.name
-    assert_nil perm.project_module
-    assert perm.actions.is_a?(Array)
-    assert perm.actions.include?('projects/settings')
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/08/08671dfda70fdd4f87dd0171bec11e1d6e0c22e1.svn-base
--- a/.svn/pristine/08/08671dfda70fdd4f87dd0171bec11e1d6e0c22e1.svn-base
+++ /dev/null
@@ -1,779 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../test_helper', __FILE__)
-
-class Redmine::Helpers::GanttTest < ActiveSupport::TestCase
-  # Utility methods and classes so assert_select can be used.
-  class GanttViewTest < ActionView::Base
-    include ActionView::Helpers::UrlHelper
-    include ActionView::Helpers::TextHelper
-    include ActionController::UrlWriter
-    include ApplicationHelper
-    include ProjectsHelper
-    include IssuesHelper
-
-    def self.default_url_options
-      {:only_path => true }
-    end
-
-  end
-
-  include ActionController::Assertions::SelectorAssertions
-
-  def setup
-    @response = ActionController::TestResponse.new
-    # Fixtures
-    ProjectCustomField.delete_all
-    Project.destroy_all
-
-    User.current = User.find(1)
-  end
-
-  def build_view
-    @view = GanttViewTest.new
-  end
-
-  def html_document
-    HTML::Document.new(@response.body)
-  end
-
-  # Creates a Gantt chart for a 4 week span
-  def create_gantt(project=Project.generate!, options={})
-    @project = project
-    @gantt = Redmine::Helpers::Gantt.new(options)
-    @gantt.project = @project
-    @gantt.query = Query.generate_default!(:project => @project)
-    @gantt.view = build_view
-    @gantt.instance_variable_set('@date_from', options[:date_from] || 2.weeks.ago.to_date)
-    @gantt.instance_variable_set('@date_to', options[:date_to] || 2.weeks.from_now.to_date)
-  end
-
-  context "#number_of_rows" do
-
-    context "with one project" do
-      should "return the number of rows just for that project"
-    end
-
-    context "with no project" do
-      should "return the total number of rows for all the projects, resursively"
-    end
-
-    should "not exceed max_rows option" do
-      p = Project.generate!
-      5.times do
-        Issue.generate_for_project!(p)
-      end
-
-      create_gantt(p)
-      @gantt.render
-      assert_equal 6, @gantt.number_of_rows
-      assert !@gantt.truncated
-
-      create_gantt(p, :max_rows => 3)
-      @gantt.render
-      assert_equal 3, @gantt.number_of_rows
-      assert @gantt.truncated
-    end
-  end
-
-  context "#number_of_rows_on_project" do
-    setup do
-      create_gantt
-    end
-
-    should "count 0 for an empty the project" do
-      assert_equal 0, @gantt.number_of_rows_on_project(@project)
-    end
-
-    should "count the number of issues without a version" do
-      @project.issues << Issue.generate_for_project!(@project, :fixed_version => nil)
-      assert_equal 2, @gantt.number_of_rows_on_project(@project)
-    end
-
-    should "count the number of issues on versions, including cross-project" do
-      version = Version.generate!
-      @project.versions << version
-      @project.issues << Issue.generate_for_project!(@project, :fixed_version => version)
-
-      assert_equal 3, @gantt.number_of_rows_on_project(@project)
-    end
-  end
-
-  # TODO: more of an integration test
-  context "#subjects" do
-    setup do
-      create_gantt
-      @project.enabled_module_names = [:issue_tracking]
-      @tracker = Tracker.generate!
-      @project.trackers << @tracker
-      @version = Version.generate!(:effective_date => 1.week.from_now.to_date, :sharing => 'none')
-      @project.versions << @version
-
-      @issue = Issue.generate!(:fixed_version => @version,
-                               :subject => "gantt#line_for_project",
-                               :tracker => @tracker,
-                               :project => @project,
-                               :done_ratio => 30,
-                               :start_date => Date.yesterday,
-                               :due_date => 1.week.from_now.to_date)
-      @project.issues << @issue
-    end
-
-    context "project" do
-      should "be rendered" do
-        @response.body = @gantt.subjects
-        assert_select "div.project-name a", /#{@project.name}/
-      end
-
-      should "have an indent of 4" do
-        @response.body = @gantt.subjects
-        assert_select "div.project-name[style*=left:4px]"
-      end
-    end
-
-    context "version" do
-      should "be rendered" do
-        @response.body = @gantt.subjects
-        assert_select "div.version-name a", /#{@version.name}/
-      end
-
-      should "be indented 24 (one level)" do
-        @response.body = @gantt.subjects
-        assert_select "div.version-name[style*=left:24px]"
-      end
-
-      context "without assigned issues" do
-        setup do
-          @version = Version.generate!(:effective_date => 2.week.from_now.to_date, :sharing => 'none', :name => 'empty_version')
-          @project.versions << @version
-        end
-
-        should "not be rendered" do
-          @response.body = @gantt.subjects
-          assert_select "div.version-name a", :text => /#{@version.name}/, :count => 0
-        end
-      end
-    end
-
-    context "issue" do
-      should "be rendered" do
-        @response.body = @gantt.subjects
-        assert_select "div.issue-subject", /#{@issue.subject}/
-      end
-
-      should "be indented 44 (two levels)" do
-        @response.body = @gantt.subjects
-        assert_select "div.issue-subject[style*=left:44px]"
-      end
-
-      context "assigned to a shared version of another project" do
-        setup do
-          p = Project.generate!
-          p.trackers << @tracker
-          p.enabled_module_names = [:issue_tracking]
-          @shared_version = Version.generate!(:sharing => 'system')
-          p.versions << @shared_version
-          # Reassign the issue to a shared version of another project
-
-          @issue = Issue.generate!(:fixed_version => @shared_version,
-                                   :subject => "gantt#assigned_to_shared_version",
-                                   :tracker => @tracker,
-                                   :project => @project,
-                                   :done_ratio => 30,
-                                   :start_date => Date.yesterday,
-                                   :due_date => 1.week.from_now.to_date)
-          @project.issues << @issue
-        end
-
-        should "be rendered" do
-          @response.body = @gantt.subjects
-          assert_select "div.issue-subject", /#{@issue.subject}/
-        end
-      end
-
-      context "with subtasks" do
-        setup do
-          attrs = {:project => @project, :tracker => @tracker, :fixed_version => @version}
-          @child1 = Issue.generate!(attrs.merge(:subject => 'child1', :parent_issue_id => @issue.id, :start_date => Date.yesterday, :due_date => 2.day.from_now.to_date))
-          @child2 = Issue.generate!(attrs.merge(:subject => 'child2', :parent_issue_id => @issue.id, :start_date => Date.today, :due_date => 1.week.from_now.to_date))
-          @grandchild = Issue.generate!(attrs.merge(:subject => 'grandchild', :parent_issue_id => @child1.id, :start_date => Date.yesterday, :due_date => 2.day.from_now.to_date))
-        end
-
-        should "indent subtasks" do
-          @response.body = @gantt.subjects
-          # parent task 44px
-          assert_select "div.issue-subject[style*=left:44px]", /#{@issue.subject}/
-          # children 64px
-          assert_select "div.issue-subject[style*=left:64px]", /child1/
-          assert_select "div.issue-subject[style*=left:64px]", /child2/
-          # grandchild 84px
-          assert_select "div.issue-subject[style*=left:84px]", /grandchild/, @response.body
-        end
-      end
-    end
-  end
-
-  context "#lines" do
-    setup do
-      create_gantt
-      @project.enabled_module_names = [:issue_tracking]
-      @tracker = Tracker.generate!
-      @project.trackers << @tracker
-      @version = Version.generate!(:effective_date => 1.week.from_now.to_date)
-      @project.versions << @version
-      @issue = Issue.generate!(:fixed_version => @version,
-                               :subject => "gantt#line_for_project",
-                               :tracker => @tracker,
-                               :project => @project,
-                               :done_ratio => 30,
-                               :start_date => Date.yesterday,
-                               :due_date => 1.week.from_now.to_date)
-      @project.issues << @issue
-
-      @response.body = @gantt.lines
-    end
-
-    context "project" do
-      should "be rendered" do
-        assert_select "div.project.task_todo"
-        assert_select "div.project.starting"
-        assert_select "div.project.ending"
-        assert_select "div.label.project", /#{@project.name}/
-      end
-    end
-
-    context "version" do
-      should "be rendered" do
-        assert_select "div.version.task_todo"
-        assert_select "div.version.starting"
-        assert_select "div.version.ending"
-        assert_select "div.label.version", /#{@version.name}/
-      end
-    end
-
-    context "issue" do
-      should "be rendered" do
-        assert_select "div.task_todo"
-        assert_select "div.task.label", /#{@issue.done_ratio}/
-        assert_select "div.tooltip", /#{@issue.subject}/
-      end
-    end
-  end
-
-  context "#render_project" do
-    should "be tested"
-  end
-
-  context "#render_issues" do
-    should "be tested"
-  end
-
-  context "#render_version" do
-    should "be tested"
-  end
-
-  context "#subject_for_project" do
-    setup do
-      create_gantt
-    end
-
-    context ":html format" do
-      should "add an absolute positioned div" do
-        @response.body = @gantt.subject_for_project(@project, {:format => :html})
-        assert_select "div[style*=absolute]"
-      end
-
-      should "use the indent option to move the div to the right" do
-        @response.body = @gantt.subject_for_project(@project, {:format => :html, :indent => 40})
-        assert_select "div[style*=left:40]"
-      end
-
-      should "include the project name" do
-        @response.body = @gantt.subject_for_project(@project, {:format => :html})
-        assert_select 'div', :text => /#{@project.name}/
-      end
-
-      should "include a link to the project" do
-        @response.body = @gantt.subject_for_project(@project, {:format => :html})
-        assert_select 'a[href=?]', "/projects/#{@project.identifier}", :text => /#{@project.name}/
-      end
-
-      should "style overdue projects" do
-        @project.enabled_module_names = [:issue_tracking]
-        @project.versions << Version.generate!(:effective_date => Date.yesterday)
-
-        assert @project.overdue?, "Need an overdue project for this test"
-        @response.body = @gantt.subject_for_project(@project, {:format => :html})
-
-        assert_select 'div span.project-overdue'
-      end
-
-
-    end
-
-    should "test the PNG format"
-    should "test the PDF format"
-  end
-
-  context "#line_for_project" do
-    setup do
-      create_gantt
-      @project.enabled_module_names = [:issue_tracking]
-      @tracker = Tracker.generate!
-      @project.trackers << @tracker
-      @version = Version.generate!(:effective_date => Date.yesterday)
-      @project.versions << @version
-
-      @project.issues << Issue.generate!(:fixed_version => @version,
-                                         :subject => "gantt#line_for_project",
-                                         :tracker => @tracker,
-                                         :project => @project,
-                                         :done_ratio => 30,
-                                         :start_date => 1.week.ago.to_date,
-                                         :due_date => 1.week.from_now.to_date)
-    end
-
-    context ":html format" do
-      context "todo line" do
-        should "start from the starting point on the left" do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.task_todo[style*=left:28px]", true, @response.body
-        end
-
-        should "be the total width of the project" do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.task_todo[style*=width:58px]", true, @response.body
-        end
-
-      end
-
-      context "late line" do
-        should_eventually "start from the starting point on the left" do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.task_late[style*=left:28px]", true, @response.body
-        end
-
-        should_eventually "be the total delayed width of the project" do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.task_late[style*=width:30px]", true, @response.body
-        end
-      end
-
-      context "done line" do
-        should_eventually "start from the starting point on the left" do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.task_done[style*=left:28px]", true, @response.body
-        end
-
-        should_eventually "Be the total done width of the project"  do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.task_done[style*=width:18px]", true, @response.body
-        end
-      end
-
-      context "starting marker" do
-        should "not appear if the starting point is off the gantt chart" do
-          # Shift the date range of the chart
-          @gantt.instance_variable_set('@date_from', Date.today)
-
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.starting", false, @response.body
-        end
-
-        should "appear at the starting point" do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.starting[style*=left:28px]", true, @response.body
-        end
-      end
-
-      context "ending marker" do
-        should "not appear if the starting point is off the gantt chart" do
-          # Shift the date range of the chart
-          @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
-
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.ending", false, @response.body
-
-        end
-
-        should "appear at the end of the date range" do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.ending[style*=left:88px]", true, @response.body
-        end
-      end
-
-      context "status content" do
-        should "appear at the far left, even if it's far in the past" do
-          @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
-
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.label", /#{@project.name}/
-        end
-
-        should "show the project name" do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.label", /#{@project.name}/
-        end
-
-        should_eventually "show the percent complete" do
-          @response.body = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
-          assert_select "div.project.label", /0%/
-        end
-      end
-    end
-
-    should "test the PNG format"
-    should "test the PDF format"
-  end
-
-  context "#subject_for_version" do
-    setup do
-      create_gantt
-      @project.enabled_module_names = [:issue_tracking]
-      @tracker = Tracker.generate!
-      @project.trackers << @tracker
-      @version = Version.generate!(:effective_date => Date.yesterday)
-      @project.versions << @version
-
-      @project.issues << Issue.generate!(:fixed_version => @version,
-                                         :subject => "gantt#subject_for_version",
-                                         :tracker => @tracker,
-                                         :project => @project,
-                                         :start_date => Date.today)
-
-    end
-
-    context ":html format" do
-      should "add an absolute positioned div" do
-        @response.body = @gantt.subject_for_version(@version, {:format => :html})
-        assert_select "div[style*=absolute]"
-      end
-
-      should "use the indent option to move the div to the right" do
-        @response.body = @gantt.subject_for_version(@version, {:format => :html, :indent => 40})
-        assert_select "div[style*=left:40]"
-      end
-
-      should "include the version name" do
-        @response.body = @gantt.subject_for_version(@version, {:format => :html})
-        assert_select 'div', :text => /#{@version.name}/
-      end
-
-      should "include a link to the version" do
-        @response.body = @gantt.subject_for_version(@version, {:format => :html})
-        assert_select 'a[href=?]', Regexp.escape("/versions/#{@version.to_param}"), :text => /#{@version.name}/
-      end
-
-      should "style late versions" do
-        assert @version.overdue?, "Need an overdue version for this test"
-        @response.body = @gantt.subject_for_version(@version, {:format => :html})
-
-        assert_select 'div span.version-behind-schedule'
-      end
-
-      should "style behind schedule versions" do
-        assert @version.behind_schedule?, "Need a behind schedule version for this test"
-        @response.body = @gantt.subject_for_version(@version, {:format => :html})
-
-        assert_select 'div span.version-behind-schedule'
-      end
-    end
-    should "test the PNG format"
-    should "test the PDF format"
-  end
-
-  context "#line_for_version" do
-    setup do
-      create_gantt
-      @project.enabled_module_names = [:issue_tracking]
-      @tracker = Tracker.generate!
-      @project.trackers << @tracker
-      @version = Version.generate!(:effective_date => 1.week.from_now.to_date)
-      @project.versions << @version
-
-      @project.issues << Issue.generate!(:fixed_version => @version,
-                                         :subject => "gantt#line_for_project",
-                                         :tracker => @tracker,
-                                         :project => @project,
-                                         :done_ratio => 30,
-                                         :start_date => 1.week.ago.to_date,
-                                         :due_date => 1.week.from_now.to_date)
-    end
-
-    context ":html format" do
-      context "todo line" do
-        should "start from the starting point on the left" do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.task_todo[style*=left:28px]", true, @response.body
-        end
-
-        should "be the total width of the version" do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.task_todo[style*=width:58px]", true, @response.body
-        end
-
-      end
-
-      context "late line" do
-        should "start from the starting point on the left" do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.task_late[style*=left:28px]", true, @response.body
-        end
-
-        should "be the total delayed width of the version" do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.task_late[style*=width:30px]", true, @response.body
-        end
-      end
-
-      context "done line" do
-        should "start from the starting point on the left" do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.task_done[style*=left:28px]", true, @response.body
-        end
-
-        should "be the total done width of the version"  do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.task_done[style*=width:16px]", true, @response.body
-        end
-      end
-
-      context "starting marker" do
-        should "not appear if the starting point is off the gantt chart" do
-          # Shift the date range of the chart
-          @gantt.instance_variable_set('@date_from', Date.today)
-
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.starting", false
-        end
-
-        should "appear at the starting point" do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.starting[style*=left:28px]", true, @response.body
-        end
-      end
-
-      context "ending marker" do
-        should "not appear if the starting point is off the gantt chart" do
-          # Shift the date range of the chart
-          @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
-
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.ending", false
-
-        end
-
-        should "appear at the end of the date range" do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.ending[style*=left:88px]", true, @response.body
-        end
-      end
-
-      context "status content" do
-        should "appear at the far left, even if it's far in the past" do
-          @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
-
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.label", /#{@version.name}/
-        end
-
-        should "show the version name" do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.label", /#{@version.name}/
-        end
-
-        should "show the percent complete" do
-          @response.body = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
-          assert_select "div.version.label", /30%/
-        end
-      end
-    end
-
-    should "test the PNG format"
-    should "test the PDF format"
-  end
-
-  context "#subject_for_issue" do
-    setup do
-      create_gantt
-      @project.enabled_module_names = [:issue_tracking]
-      @tracker = Tracker.generate!
-      @project.trackers << @tracker
-
-      @issue = Issue.generate!(:subject => "gantt#subject_for_issue",
-                               :tracker => @tracker,
-                               :project => @project,
-                               :start_date => 3.days.ago.to_date,
-                               :due_date => Date.yesterday)
-      @project.issues << @issue
-
-    end
-
-    context ":html format" do
-      should "add an absolute positioned div" do
-        @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
-        assert_select "div[style*=absolute]"
-      end
-
-      should "use the indent option to move the div to the right" do
-        @response.body = @gantt.subject_for_issue(@issue, {:format => :html, :indent => 40})
-        assert_select "div[style*=left:40]"
-      end
-
-      should "include the issue subject" do
-        @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
-        assert_select 'div', :text => /#{@issue.subject}/
-      end
-
-      should "include a link to the issue" do
-        @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
-        assert_select 'a[href=?]', Regexp.escape("/issues/#{@issue.to_param}"), :text => /#{@tracker.name} ##{@issue.id}/
-      end
-
-      should "style overdue issues" do
-        assert @issue.overdue?, "Need an overdue issue for this test"
-        @response.body = @gantt.subject_for_issue(@issue, {:format => :html})
-
-        assert_select 'div span.issue-overdue'
-      end
-
-    end
-    should "test the PNG format"
-    should "test the PDF format"
-  end
-
-  context "#line_for_issue" do
-    setup do
-      create_gantt
-      @project.enabled_module_names = [:issue_tracking]
-      @tracker = Tracker.generate!
-      @project.trackers << @tracker
-      @version = Version.generate!(:effective_date => 1.week.from_now.to_date)
-      @project.versions << @version
-      @issue = Issue.generate!(:fixed_version => @version,
-                               :subject => "gantt#line_for_project",
-                               :tracker => @tracker,
-                               :project => @project,
-                               :done_ratio => 30,
-                               :start_date => 1.week.ago.to_date,
-                               :due_date => 1.week.from_now.to_date)
-      @project.issues << @issue
-    end
-
-    context ":html format" do
-      context "todo line" do
-        should "start from the starting point on the left" do
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          assert_select "div.task_todo[style*=left:28px]", true, @response.body
-        end
-
-        should "be the total width of the issue" do
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          assert_select "div.task_todo[style*=width:58px]", true, @response.body
-        end
-
-      end
-
-      context "late line" do
-        should "start from the starting point on the left" do
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          assert_select "div.task_late[style*=left:28px]", true, @response.body
-        end
-
-        should "be the total delayed width of the issue" do
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          assert_select "div.task_late[style*=width:30px]", true, @response.body
-        end
-      end
-
-      context "done line" do
-        should "start from the starting point on the left" do
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          assert_select "div.task_done[style*=left:28px]", true, @response.body
-        end
-
-        should "be the total done width of the issue"  do
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          # 15 days * 4 px * 30% - 2 px for borders = 16 px
-          assert_select "div.task_done[style*=width:16px]", true, @response.body
-        end
-
-        should "not be the total done width if the chart starts after issue start date"  do
-          create_gantt(@project, :date_from => 5.days.ago.to_date)
-
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          assert_select "div.task_done[style*=left:0px]", true, @response.body
-          assert_select "div.task_done[style*=width:8px]", true, @response.body
-        end
-
-        context "for completed issue" do
-          setup do
-            @issue.done_ratio = 100
-          end
-
-          should "be the total width of the issue"  do
-            @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-            assert_select "div.task_done[style*=width:58px]", true, @response.body
-          end
-
-          should "be the total width of the issue with due_date=start_date"  do
-            @issue.due_date = @issue.start_date
-            @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-            assert_select "div.task_done[style*=width:2px]", true, @response.body
-          end
-        end
-      end
-
-      context "status content" do
-        should "appear at the far left, even if it's far in the past" do
-          @gantt.instance_variable_set('@date_to', 2.weeks.ago.to_date)
-
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          assert_select "div.task.label", true, @response.body
-        end
-
-        should "show the issue status" do
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          assert_select "div.task.label", /#{@issue.status.name}/
-        end
-
-        should "show the percent complete" do
-          @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-          assert_select "div.task.label", /30%/
-        end
-      end
-    end
-
-    should "have an issue tooltip" do
-      @response.body = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
-      assert_select "div.tooltip", /#{@issue.subject}/
-    end
-
-    should "test the PNG format"
-    should "test the PDF format"
-  end
-
-  context "#to_image" do
-    should "be tested"
-  end
-
-  context "#to_pdf" do
-    should "be tested"
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/08/086f4bbd984edf33971e918b1e5330fe445e9dd7.svn-base
--- /dev/null
+++ b/.svn/pristine/08/086f4bbd984edf33971e918b1e5330fe445e9dd7.svn-base
@@ -0,0 +1,253 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../test_helper', __FILE__)
+
+class Redmine::MenuManager::MenuHelperTest < ActionView::TestCase
+
+  include Redmine::MenuManager::MenuHelper
+  include ERB::Util
+  fixtures :users, :members, :projects, :enabled_modules, :roles, :member_roles
+
+  def setup
+    setup_with_controller
+    # Stub the current menu item in the controller
+    def current_menu_item
+      :index
+    end
+  end
+
+  context "MenuManager#current_menu_item" do
+    should "be tested"
+  end
+
+  context "MenuManager#render_main_menu" do
+    should "be tested"
+  end
+
+  context "MenuManager#render_menu" do
+    should "be tested"
+  end
+
+  context "MenuManager#menu_item_and_children" do
+    should "be tested"
+  end
+
+  context "MenuManager#extract_node_details" do
+    should "be tested"
+  end
+
+  def test_render_single_menu_node
+    node = Redmine::MenuManager::MenuItem.new(:testing, '/test', { })
+    @output_buffer = render_single_menu_node(node, 'This is a test', node.url, false)
+
+    assert_select("a.testing", "This is a test")
+  end
+
+  def test_render_menu_node
+    single_node = Redmine::MenuManager::MenuItem.new(:single_node, '/test', { })
+    @output_buffer = render_menu_node(single_node, nil)
+
+    assert_select("li") do
+      assert_select("a.single-node", "Single node")
+    end
+  end
+
+  def test_render_menu_node_with_nested_items
+    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node, '/test', { })
+    parent_node << Redmine::MenuManager::MenuItem.new(:child_one_node, '/test', { })
+    parent_node << Redmine::MenuManager::MenuItem.new(:child_two_node, '/test', { })
+    parent_node <<
+      Redmine::MenuManager::MenuItem.new(:child_three_node, '/test', { }) <<
+      Redmine::MenuManager::MenuItem.new(:child_three_inner_node, '/test', { })
+
+    @output_buffer = render_menu_node(parent_node, nil)
+
+    assert_select("li") do
+      assert_select("a.parent-node", "Parent node")
+      assert_select("ul") do
+        assert_select("li a.child-one-node", "Child one node")
+        assert_select("li a.child-two-node", "Child two node")
+        assert_select("li") do
+          assert_select("a.child-three-node", "Child three node")
+          assert_select("ul") do
+            assert_select("li a.child-three-inner-node", "Child three inner node")
+          end
+        end
+      end
+    end
+
+  end
+
+  def test_render_menu_node_with_children
+    User.current = User.find(2)
+
+    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
+                                                     '/test',
+                                                     {
+                                                       :children => Proc.new {|p|
+                                                         children = []
+                                                         3.times do |time|
+                                                           children << Redmine::MenuManager::MenuItem.new("test_child_#{time}",
+                                                                                                             {:controller => 'issues', :action => 'index'},
+                                                                                                             {})
+                                                         end
+                                                         children
+                                                       }
+                                                     })
+    @output_buffer = render_menu_node(parent_node, Project.find(1))
+
+    assert_select("li") do
+      assert_select("a.parent-node", "Parent node")
+      assert_select("ul") do
+        assert_select("li a.test-child-0", "Test child 0")
+        assert_select("li a.test-child-1", "Test child 1")
+        assert_select("li a.test-child-2", "Test child 2")
+      end
+    end
+  end
+
+  def test_render_menu_node_with_nested_items_and_children
+    User.current = User.find(2)
+
+    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
+                                                     '/test',
+                                                     {
+                                                       :children => Proc.new {|p|
+                                                         children = []
+                                                         3.times do |time|
+                                                           children << Redmine::MenuManager::MenuItem.new("test_child_#{time}", {:controller => 'issues', :action => 'index'}, {})
+                                                         end
+                                                         children
+                                                       }
+                                                     })
+
+    parent_node << Redmine::MenuManager::MenuItem.new(:child_node,
+                                                     '/test',
+                                                     {
+                                                       :children => Proc.new {|p|
+                                                         children = []
+                                                         6.times do |time|
+                                                            children << Redmine::MenuManager::MenuItem.new("test_dynamic_child_#{time}", {:controller => 'issues', :action => 'index'}, {})
+                                                         end
+                                                         children
+                                                       }
+                                                     })
+
+    @output_buffer = render_menu_node(parent_node, Project.find(1))
+
+    assert_select("li") do
+      assert_select("a.parent-node", "Parent node")
+      assert_select("ul") do
+        assert_select("li a.child-node", "Child node")
+        assert_select("ul") do
+          assert_select("li a.test-dynamic-child-0", "Test dynamic child 0")
+          assert_select("li a.test-dynamic-child-1", "Test dynamic child 1")
+          assert_select("li a.test-dynamic-child-2", "Test dynamic child 2")
+          assert_select("li a.test-dynamic-child-3", "Test dynamic child 3")
+          assert_select("li a.test-dynamic-child-4", "Test dynamic child 4")
+          assert_select("li a.test-dynamic-child-5", "Test dynamic child 5")
+        end
+        assert_select("li a.test-child-0", "Test child 0")
+        assert_select("li a.test-child-1", "Test child 1")
+        assert_select("li a.test-child-2", "Test child 2")
+      end
+    end
+  end
+
+  def test_render_menu_node_with_children_without_an_array
+    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
+                                                     '/test',
+                                                     {
+                                                       :children => Proc.new {|p| Redmine::MenuManager::MenuItem.new("test_child", "/testing", {})}
+                                                     })
+
+    assert_raises Redmine::MenuManager::MenuError, ":children must be an array of MenuItems" do
+      @output_buffer = render_menu_node(parent_node, Project.find(1))
+    end
+  end
+
+  def test_render_menu_node_with_incorrect_children
+    parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
+                                                     '/test',
+                                                     {
+                                                       :children => Proc.new {|p| ["a string"] }
+                                                     })
+
+    assert_raises Redmine::MenuManager::MenuError, ":children must be an array of MenuItems" do
+      @output_buffer = render_menu_node(parent_node, Project.find(1))
+    end
+
+  end
+
+  def test_menu_items_for_should_yield_all_items_if_passed_a_block
+    menu_name = :test_menu_items_for_should_yield_all_items_if_passed_a_block
+    Redmine::MenuManager.map menu_name do |menu|
+      menu.push(:a_menu, '/', { })
+      menu.push(:a_menu_2, '/', { })
+      menu.push(:a_menu_3, '/', { })
+    end
+
+    items_yielded = []
+    menu_items_for(menu_name) do |item|
+      items_yielded << item
+    end
+
+    assert_equal 3, items_yielded.size
+  end
+
+  def test_menu_items_for_should_return_all_items
+    menu_name = :test_menu_items_for_should_return_all_items
+    Redmine::MenuManager.map menu_name do |menu|
+      menu.push(:a_menu, '/', { })
+      menu.push(:a_menu_2, '/', { })
+      menu.push(:a_menu_3, '/', { })
+    end
+
+    items = menu_items_for(menu_name)
+    assert_equal 3, items.size
+  end
+
+  def test_menu_items_for_should_skip_unallowed_items_on_a_project
+    menu_name = :test_menu_items_for_should_skip_unallowed_items_on_a_project
+    Redmine::MenuManager.map menu_name do |menu|
+      menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
+      menu.push(:a_menu_2, {:controller => 'issues', :action => 'index' }, { })
+      menu.push(:unallowed, {:controller => 'issues', :action => 'unallowed' }, { })
+    end
+
+    User.current = User.find(2)
+
+    items = menu_items_for(menu_name, Project.find(1))
+    assert_equal 2, items.size
+  end
+
+  def test_menu_items_for_should_skip_items_that_fail_the_conditions
+    menu_name = :test_menu_items_for_should_skip_items_that_fail_the_conditions
+    Redmine::MenuManager.map menu_name do |menu|
+      menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
+      menu.push(:unallowed,
+                {:controller => 'issues', :action => 'index' },
+                { :if => Proc.new { false }})
+    end
+
+    User.current = User.find(2)
+
+    items = menu_items_for(menu_name, Project.find(1))
+    assert_equal 1, items.size
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/08/087ac3ba0dd90a493f814e49e635e06136a040ab.svn-base
--- a/.svn/pristine/08/087ac3ba0dd90a493f814e49e635e06136a040ab.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-template from plugin
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/08/088eae42f08379f3106075b388f036d1754d148c.svn-base
--- /dev/null
+++ b/.svn/pristine/08/088eae42f08379f3106075b388f036d1754d148c.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module EnumerationsHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/08/08c1f1410c30c4d18ef6cbcbd8954d1721fb044b.svn-base
--- /dev/null
+++ b/.svn/pristine/08/08c1f1410c30c4d18ef6cbcbd8954d1721fb044b.svn-base
@@ -0,0 +1,195 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WatchersControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
+           :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers
+
+  def setup
+    User.current = nil
+  end
+
+  def test_watch_a_single_object
+    @request.session[:user_id] = 3
+    assert_difference('Watcher.count') do
+      xhr :post, :watch, :object_type => 'issue', :object_id => '1'
+      assert_response :success
+      assert_include '$(".issue-1-watcher")', response.body
+    end
+    assert Issue.find(1).watched_by?(User.find(3))
+  end
+
+  def test_watch_a_collection_with_a_single_object
+    @request.session[:user_id] = 3
+    assert_difference('Watcher.count') do
+      xhr :post, :watch, :object_type => 'issue', :object_id => ['1']
+      assert_response :success
+      assert_include '$(".issue-1-watcher")', response.body
+    end
+    assert Issue.find(1).watched_by?(User.find(3))
+  end
+
+  def test_watch_a_collection_with_multiple_objects
+    @request.session[:user_id] = 3
+    assert_difference('Watcher.count', 2) do
+      xhr :post, :watch, :object_type => 'issue', :object_id => ['1', '3']
+      assert_response :success
+      assert_include '$(".issue-bulk-watcher")', response.body
+    end
+    assert Issue.find(1).watched_by?(User.find(3))
+    assert Issue.find(3).watched_by?(User.find(3))
+  end
+
+  def test_watch_should_be_denied_without_permission
+    Role.find(2).remove_permission! :view_issues
+    @request.session[:user_id] = 3
+    assert_no_difference('Watcher.count') do
+      xhr :post, :watch, :object_type => 'issue', :object_id => '1'
+      assert_response 403
+    end
+  end
+
+  def test_watch_invalid_class_should_respond_with_404
+    @request.session[:user_id] = 3
+    assert_no_difference('Watcher.count') do
+      xhr :post, :watch, :object_type => 'foo', :object_id => '1'
+      assert_response 404
+    end
+  end
+
+  def test_watch_invalid_object_should_respond_with_404
+    @request.session[:user_id] = 3
+    assert_no_difference('Watcher.count') do
+      xhr :post, :watch, :object_type => 'issue', :object_id => '999'
+      assert_response 404
+    end
+  end
+
+  def test_unwatch
+    @request.session[:user_id] = 3
+    assert_difference('Watcher.count', -1) do
+      xhr :delete, :unwatch, :object_type => 'issue', :object_id => '2'
+      assert_response :success
+      assert_include '$(".issue-2-watcher")', response.body
+    end
+    assert !Issue.find(1).watched_by?(User.find(3))
+  end
+
+  def test_unwatch_a_collection_with_multiple_objects
+    @request.session[:user_id] = 3
+    Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
+    Watcher.create!(:user_id => 3, :watchable => Issue.find(3))
+
+    assert_difference('Watcher.count', -2) do
+      xhr :delete, :unwatch, :object_type => 'issue', :object_id => ['1', '3']
+      assert_response :success
+      assert_include '$(".issue-bulk-watcher")', response.body
+    end
+    assert !Issue.find(1).watched_by?(User.find(3))
+    assert !Issue.find(3).watched_by?(User.find(3))
+  end
+
+  def test_new
+    @request.session[:user_id] = 2
+    xhr :get, :new, :object_type => 'issue', :object_id => '2'
+    assert_response :success
+    assert_match /ajax-modal/, response.body
+  end
+
+  def test_new_for_new_record_with_project_id
+    @request.session[:user_id] = 2
+    xhr :get, :new, :project_id => 1
+    assert_response :success
+    assert_equal Project.find(1), assigns(:project)
+    assert_match /ajax-modal/, response.body
+  end
+
+  def test_new_for_new_record_with_project_identifier
+    @request.session[:user_id] = 2
+    xhr :get, :new, :project_id => 'ecookbook'
+    assert_response :success
+    assert_equal Project.find(1), assigns(:project)
+    assert_match /ajax-modal/, response.body
+  end
+
+  def test_create
+    @request.session[:user_id] = 2
+    assert_difference('Watcher.count') do
+      xhr :post, :create, :object_type => 'issue', :object_id => '2', :watcher => {:user_id => '4'}
+      assert_response :success
+      assert_match /watchers/, response.body
+      assert_match /ajax-modal/, response.body
+    end
+    assert Issue.find(2).watched_by?(User.find(4))
+  end
+
+  def test_create_multiple
+    @request.session[:user_id] = 2
+    assert_difference('Watcher.count', 2) do
+      xhr :post, :create, :object_type => 'issue', :object_id => '2', :watcher => {:user_ids => ['4', '7']}
+      assert_response :success
+      assert_match /watchers/, response.body
+      assert_match /ajax-modal/, response.body
+    end
+    assert Issue.find(2).watched_by?(User.find(4))
+    assert Issue.find(2).watched_by?(User.find(7))
+  end
+
+  def test_autocomplete_on_watchable_creation
+    @request.session[:user_id] = 2
+    xhr :get, :autocomplete_for_user, :q => 'mi', :project_id => 'ecookbook'
+    assert_response :success
+    assert_select 'input', :count => 4
+    assert_select 'input[name=?][value=1]', 'watcher[user_ids][]'
+    assert_select 'input[name=?][value=2]', 'watcher[user_ids][]'
+    assert_select 'input[name=?][value=8]', 'watcher[user_ids][]'
+    assert_select 'input[name=?][value=9]', 'watcher[user_ids][]'
+  end
+
+  def test_autocomplete_on_watchable_update
+    @request.session[:user_id] = 2
+    xhr :get, :autocomplete_for_user, :q => 'mi', :object_id => '2' , :object_type => 'issue', :project_id => 'ecookbook'
+    assert_response :success
+    assert_select 'input', :count => 3
+    assert_select 'input[name=?][value=2]', 'watcher[user_ids][]'
+    assert_select 'input[name=?][value=8]', 'watcher[user_ids][]'
+    assert_select 'input[name=?][value=9]', 'watcher[user_ids][]'
+
+  end
+
+  def test_append
+    @request.session[:user_id] = 2
+    assert_no_difference 'Watcher.count' do
+      xhr :post, :append, :watcher => {:user_ids => ['4', '7']}, :project_id => 'ecookbook'
+      assert_response :success
+      assert_include 'watchers_inputs', response.body
+      assert_include 'issue[watcher_user_ids][]', response.body
+    end
+  end
+
+  def test_remove_watcher
+    @request.session[:user_id] = 2
+    assert_difference('Watcher.count', -1) do
+      xhr :delete, :destroy, :object_type => 'issue', :object_id => '2', :user_id => '3'
+      assert_response :success
+      assert_match /watchers/, response.body
+    end
+    assert !Issue.find(2).watched_by?(User.find(3))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/08/08d8c21c9156481395a983e5e0a4c9f73ad91ca9.svn-base
--- /dev/null
+++ b/.svn/pristine/08/08d8c21c9156481395a983e5e0a4c9f73ad91ca9.svn-base
@@ -0,0 +1,71 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../../test_helper', __FILE__)
+
+begin
+  require 'mocha'
+
+  class SubversionAdapterTest < ActiveSupport::TestCase
+
+    if repository_configured?('subversion')
+      def setup
+        @adapter = Redmine::Scm::Adapters::SubversionAdapter.new(self.class.subversion_repository_url)
+      end
+
+      def test_client_version
+        v = Redmine::Scm::Adapters::SubversionAdapter.client_version
+        assert v.is_a?(Array)
+      end
+
+      def test_scm_version
+        to_test = { "svn, version 1.6.13 (r1002816)\n"  => [1,6,13],
+                    "svn, versione 1.6.13 (r1002816)\n" => [1,6,13],
+                    "1.6.1\n1.7\n1.8"                   => [1,6,1],
+                    "1.6.2\r\n1.8.1\r\n1.9.1"           => [1,6,2]}
+        to_test.each do |s, v|
+          test_scm_version_for(s, v)
+        end
+      end
+
+      def test_info_not_nil
+        assert_not_nil @adapter.info
+      end
+
+      def test_info_nil
+        adpt = Redmine::Scm::Adapters::SubversionAdapter.new(
+                  "file:///invalid/invalid/"
+                  )
+        assert_nil adpt.info
+      end
+
+      private
+
+      def test_scm_version_for(scm_version, version)
+        @adapter.class.expects(:scm_version_from_command_line).returns(scm_version)
+        assert_equal version, @adapter.class.svn_binary_version
+      end
+    else
+      puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
+      def test_fake; assert true end
+    end
+  end
+rescue LoadError
+  class SubversionMochaFake < ActiveSupport::TestCase
+    def test_fake; assert(false, "Requires mocha to run those tests")  end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/09/0950951344735156104a9fd2df5df66fc9bd2194.svn-base
--- a/.svn/pristine/09/0950951344735156104a9fd2df5df66fc9bd2194.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Views
-    module Builders
-      def self.for(format, &block)
-        builder = case format
-          when 'xml',  :xml;  Builders::Xml.new
-          when 'json', :json; Builders::Json.new
-          else; raise "No builder for format #{format}"
-        end
-        if block
-          block.call(builder)
-        else
-          builder
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/09/095b395fcfe029ccbb2acac47d6cc8ef84b80f97.svn-base
--- a/.svn/pristine/09/095b395fcfe029ccbb2acac47d6cc8ef84b80f97.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-syntax: glob
-
-.project
-.loadpath
-config/additional_environment.rb
-config/configuration.yml
-config/database.yml
-config/email.yml
-config/initializers/session_store.rb
-coverage
-db/*.db
-db/*.sqlite3
-db/schema.rb
-files/*
-lib/redmine/scm/adapters/mercurial/redminehelper.pyc
-lib/redmine/scm/adapters/mercurial/redminehelper.pyo
-log/*.log*
-log/mongrel_debug
-public/dispatch.*
-public/plugin_assets
-tmp/*
-tmp/cache/*
-tmp/sessions/*
-tmp/sockets/*
-tmp/test/*
-vendor/rails
-*.rbc
-
-.svn/
-.git/
-
-.bundle
-Gemfile.lock
-Gemfile.local
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/09/09843d45a0a3ac966e4fda0bad80ec81990f71bb.svn-base
--- a/.svn/pristine/09/09843d45a0a3ac966e4fda0bad80ec81990f71bb.svn-base
+++ /dev/null
@@ -1,55 +0,0 @@
-Net::LDAP is copyrighted free software by Francis Cianfrocca
-<garbagecat10@gmail.com>. You can redistribute it and/or modify it under either
-the terms of the GPL (see the file COPYING), or the conditions below:
-
-1. You may make and give away verbatim copies of the source form of the
-   software without restriction, provided that you duplicate all of the
-   original copyright notices and associated disclaimers.
-
-2. You may modify your copy of the software in any way, provided that you do
-   at least ONE of the following:
-
-   a) place your modifications in the Public Domain or otherwise make them
-      Freely Available, such as by posting said modifications to Usenet or
-      an equivalent medium, or by allowing the author to include your
-      modifications in the software.
-
-   b) use the modified software only within your corporation or
-      organization.
-
-   c) rename any non-standard executables so the names do not conflict with
-      standard executables, which must also be provided.
-
-   d) make other distribution arrangements with the author.
-
-3. You may distribute the software in object code or executable form,
-   provided that you do at least ONE of the following:
-
-   a) distribute the executables and library files of the software, together
-      with instructions (in the manual page or equivalent) on where to get
-      the original distribution.
-
-   b) accompany the distribution with the machine-readable source of the
-      software.
-
-   c) give non-standard executables non-standard names, with instructions on
-      where to get the original software distribution.
-
-   d) make other distribution arrangements with the author.
-
-4. You may modify and include the part of the software into any other
-   software (possibly commercial).  But some files in the distribution are
-   not written by the author, so that they are not under this terms.
-
-   They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
-   files under the ./missing directory.  See each file for the copying
-   condition.
-
-5. The scripts and library files supplied as input to or produced as output
-   from the software do not automatically fall under the copyright of the
-   software, but belong to whomever generated them, and may be sold
-   commercially, and may be aggregated with this software.
-
-6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
-   WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/09/09d005add00d07aeb449a6c04ad00db8e1f72fbd.svn-base
--- /dev/null
+++ b/.svn/pristine/09/09d005add00d07aeb449a6c04ad00db8e1f72fbd.svn-base
@@ -0,0 +1,73 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingMyTest < ActionController::IntegrationTest
+  def test_my
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/my/account" },
+          { :controller => 'my', :action => 'account' }
+        )
+    end
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/my/account/destroy" },
+          { :controller => 'my', :action => 'destroy' }
+        )
+    end
+    assert_routing(
+        { :method => 'get', :path => "/my/page" },
+        { :controller => 'my', :action => 'page' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/my" },
+        { :controller => 'my', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/my/reset_rss_key" },
+        { :controller => 'my', :action => 'reset_rss_key' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/my/reset_api_key" },
+        { :controller => 'my', :action => 'reset_api_key' }
+      )
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/my/password" },
+          { :controller => 'my', :action => 'password' }
+        )
+    end
+    assert_routing(
+        { :method => 'get', :path => "/my/page_layout" },
+        { :controller => 'my', :action => 'page_layout' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/my/add_block" },
+        { :controller => 'my', :action => 'add_block' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/my/remove_block" },
+        { :controller => 'my', :action => 'remove_block' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/my/order_blocks" },
+        { :controller => 'my', :action => 'order_blocks' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/09/09e163f7a5ba48f41a7d0433361b8d9b46760493.svn-base
--- /dev/null
+++ b/.svn/pristine/09/09e163f7a5ba48f41a7d0433361b8d9b46760493.svn-base
@@ -0,0 +1,55 @@
+<%= error_messages_for 'query' %>
+
+<div class="box">
+<div class="tabular">
+<p><label for="query_name"><%=l(:field_name)%></label>
+<%= text_field 'query', 'name', :size => 80 %></p>
+
+<% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @project) %>
+<p><label for="query_is_public"><%=l(:field_is_public)%></label>
+<%= check_box 'query', 'is_public',
+      :onchange => (User.current.admin? ? nil : 'if (this.checked) {$("#query_is_for_all").removeAttr("checked"); $("#query_is_for_all").attr("disabled", true);} else {$("#query_is_for_all").removeAttr("disabled");}') %></p>
+<% end %>
+
+<p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label>
+<%= check_box_tag 'query_is_for_all', 1, @query.project.nil?,
+      :disabled => (!@query.new_record? && (@query.project.nil? || (@query.is_public? && !User.current.admin?))) %></p>
+
+<p><label for="query_default_columns"><%=l(:label_default_columns)%></label>
+<%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns',
+      :onclick => 'if (this.checked) {$("#columns").hide();} else {$("#columns").show();}' %></p>
+
+<p><label for="query_group_by"><%= l(:field_group_by) %></label>
+<%= select 'query', 'group_by', @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, :include_blank => true %></p>
+
+<p><label><%= l(:button_show) %></label>
+<%= available_block_columns_tags(@query) %></p>
+</div>
+
+<fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend>
+<%= render :partial => 'queries/filters', :locals => {:query => query}%>
+</fieldset>
+
+<fieldset><legend><%= l(:label_sort) %></legend>
+<% 3.times do |i| %>
+<%= i+1 %>: 
+<%= label_tag "query_sort_criteria_attribute_" + i.to_s,
+              l(:description_query_sort_criteria_attribute), :class => "hidden-for-sighted" %>
+<%= select_tag("query[sort_criteria][#{i}][]",
+               options_for_select([[]] + query.available_columns.select(&:sortable?).collect {|column| [column.caption, column.name.to_s]}, @query.sort_criteria_key(i)),
+               :id => "query_sort_criteria_attribute_" + i.to_s)%>
+<%= label_tag "query_sort_criteria_direction_" + i.to_s,
+              l(:description_query_sort_criteria_direction), :class => "hidden-for-sighted" %>
+<%= select_tag("query[sort_criteria][#{i}][]",
+                options_for_select([[], [l(:label_ascending), 'asc'], [l(:label_descending), 'desc']], @query.sort_criteria_order(i)),
+                :id => "query_sort_criteria_direction_" + i.to_s) %>
+<br />
+<% end %>
+</fieldset>
+
+<%= content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %>
+<legend><%= l(:field_column_names) %></legend>
+<%= render_query_columns_selection(query) %>
+<% end %>
+
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/09/09eb85d785f24ac92c1ca5060b63ab8922db4494.svn-base
--- /dev/null
+++ b/.svn/pristine/09/09eb85d785f24ac92c1ca5060b63ab8922db4494.svn-base
@@ -0,0 +1,474 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Mailer < ActionMailer::Base
+  layout 'mailer'
+  helper :application
+  helper :issues
+  helper :custom_fields
+
+  include Redmine::I18n
+
+  def self.default_url_options
+    { :host => Setting.host_name, :protocol => Setting.protocol }
+  end
+
+  # Builds a Mail::Message object used to email recipients of the added issue.
+  #
+  # Example:
+  #   issue_add(issue) => Mail::Message object
+  #   Mailer.issue_add(issue).deliver => sends an email to issue recipients
+  def issue_add(issue)
+    redmine_headers 'Project' => issue.project.identifier,
+                    'Issue-Id' => issue.id,
+                    'Issue-Author' => issue.author.login
+    redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
+    message_id issue
+    @author = issue.author
+    @issue = issue
+    @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue)
+    recipients = issue.recipients
+    cc = issue.watcher_recipients - recipients
+    mail :to => recipients,
+      :cc => cc,
+      :subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
+  end
+
+  # Builds a Mail::Message object used to email recipients of the edited issue.
+  #
+  # Example:
+  #   issue_edit(journal) => Mail::Message object
+  #   Mailer.issue_edit(journal).deliver => sends an email to issue recipients
+  def issue_edit(journal)
+    issue = journal.journalized.reload
+    redmine_headers 'Project' => issue.project.identifier,
+                    'Issue-Id' => issue.id,
+                    'Issue-Author' => issue.author.login
+    redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
+    message_id journal
+    references issue
+    @author = journal.user
+    recipients = journal.recipients
+    # Watchers in cc
+    cc = journal.watcher_recipients - recipients
+    s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
+    s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
+    s << issue.subject
+    @issue = issue
+    @journal = journal
+    @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
+    mail :to => recipients,
+      :cc => cc,
+      :subject => s
+  end
+
+  def reminder(user, issues, days)
+    set_language_if_valid user.language
+    @issues = issues
+    @days = days
+    @issues_url = url_for(:controller => 'issues', :action => 'index',
+                                :set_filter => 1, :assigned_to_id => user.id,
+                                :sort => 'due_date:asc')
+    mail :to => user.mail,
+      :subject => l(:mail_subject_reminder, :count => issues.size, :days => days)
+  end
+
+  # Builds a Mail::Message object used to email users belonging to the added document's project.
+  #
+  # Example:
+  #   document_added(document) => Mail::Message object
+  #   Mailer.document_added(document).deliver => sends an email to the document's project recipients
+  def document_added(document)
+    redmine_headers 'Project' => document.project.identifier
+    @author = User.current
+    @document = document
+    @document_url = url_for(:controller => 'documents', :action => 'show', :id => document)
+    mail :to => document.recipients,
+      :subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
+  end
+
+  # Builds a Mail::Message object used to email recipients of a project when an attachements are added.
+  #
+  # Example:
+  #   attachments_added(attachments) => Mail::Message object
+  #   Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients
+  def attachments_added(attachments)
+    container = attachments.first.container
+    added_to = ''
+    added_to_url = ''
+    @author = attachments.first.author
+    case container.class.name
+    when 'Project'
+      added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
+      added_to = "#{l(:label_project)}: #{container}"
+      recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect  {|u| u.mail}
+    when 'Version'
+      added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
+      added_to = "#{l(:label_version)}: #{container.name}"
+      recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect  {|u| u.mail}
+    when 'Document'
+      added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
+      added_to = "#{l(:label_document)}: #{container.title}"
+      recipients = container.recipients
+    end
+    redmine_headers 'Project' => container.project.identifier
+    @attachments = attachments
+    @added_to = added_to
+    @added_to_url = added_to_url
+    mail :to => recipients,
+      :subject => "[#{container.project.name}] #{l(:label_attachment_new)}"
+  end
+
+  # Builds a Mail::Message object used to email recipients of a news' project when a news item is added.
+  #
+  # Example:
+  #   news_added(news) => Mail::Message object
+  #   Mailer.news_added(news).deliver => sends an email to the news' project recipients
+  def news_added(news)
+    redmine_headers 'Project' => news.project.identifier
+    @author = news.author
+    message_id news
+    @news = news
+    @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
+    mail :to => news.recipients,
+      :subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
+  end
+
+  # Builds a Mail::Message object used to email recipients of a news' project when a news comment is added.
+  #
+  # Example:
+  #   news_comment_added(comment) => Mail::Message object
+  #   Mailer.news_comment_added(comment) => sends an email to the news' project recipients
+  def news_comment_added(comment)
+    news = comment.commented
+    redmine_headers 'Project' => news.project.identifier
+    @author = comment.author
+    message_id comment
+    @news = news
+    @comment = comment
+    @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
+    mail :to => news.recipients,
+     :cc => news.watcher_recipients,
+     :subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
+  end
+
+  # Builds a Mail::Message object used to email the recipients of the specified message that was posted.
+  #
+  # Example:
+  #   message_posted(message) => Mail::Message object
+  #   Mailer.message_posted(message).deliver => sends an email to the recipients
+  def message_posted(message)
+    redmine_headers 'Project' => message.project.identifier,
+                    'Topic-Id' => (message.parent_id || message.id)
+    @author = message.author
+    message_id message
+    references message.parent unless message.parent.nil?
+    recipients = message.recipients
+    cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients)
+    @message = message
+    @message_url = url_for(message.event_url)
+    mail :to => recipients,
+      :cc => cc,
+      :subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
+  end
+
+  # Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was added.
+  #
+  # Example:
+  #   wiki_content_added(wiki_content) => Mail::Message object
+  #   Mailer.wiki_content_added(wiki_content).deliver => sends an email to the project's recipients
+  def wiki_content_added(wiki_content)
+    redmine_headers 'Project' => wiki_content.project.identifier,
+                    'Wiki-Page-Id' => wiki_content.page.id
+    @author = wiki_content.author
+    message_id wiki_content
+    recipients = wiki_content.recipients
+    cc = wiki_content.page.wiki.watcher_recipients - recipients
+    @wiki_content = wiki_content
+    @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
+                                      :project_id => wiki_content.project,
+                                      :id => wiki_content.page.title)
+    mail :to => recipients,
+      :cc => cc,
+      :subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
+  end
+
+  # Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was updated.
+  #
+  # Example:
+  #   wiki_content_updated(wiki_content) => Mail::Message object
+  #   Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients
+  def wiki_content_updated(wiki_content)
+    redmine_headers 'Project' => wiki_content.project.identifier,
+                    'Wiki-Page-Id' => wiki_content.page.id
+    @author = wiki_content.author
+    message_id wiki_content
+    recipients = wiki_content.recipients
+    cc = wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients
+    @wiki_content = wiki_content
+    @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
+                                      :project_id => wiki_content.project,
+                                      :id => wiki_content.page.title)
+    @wiki_diff_url = url_for(:controller => 'wiki', :action => 'diff',
+                                   :project_id => wiki_content.project, :id => wiki_content.page.title,
+                                   :version => wiki_content.version)
+    mail :to => recipients,
+      :cc => cc,
+      :subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
+  end
+
+  # Builds a Mail::Message object used to email the specified user their account information.
+  #
+  # Example:
+  #   account_information(user, password) => Mail::Message object
+  #   Mailer.account_information(user, password).deliver => sends account information to the user
+  def account_information(user, password)
+    set_language_if_valid user.language
+    @user = user
+    @password = password
+    @login_url = url_for(:controller => 'account', :action => 'login')
+    mail :to => user.mail,
+      :subject => l(:mail_subject_register, Setting.app_title)
+  end
+
+  # Builds a Mail::Message object used to email all active administrators of an account activation request.
+  #
+  # Example:
+  #   account_activation_request(user) => Mail::Message object
+  #   Mailer.account_activation_request(user).deliver => sends an email to all active administrators
+  def account_activation_request(user)
+    # Send the email to all active administrators
+    recipients = User.active.where(:admin => true).all.collect { |u| u.mail }.compact
+    @user = user
+    @url = url_for(:controller => 'users', :action => 'index',
+                         :status => User::STATUS_REGISTERED,
+                         :sort_key => 'created_on', :sort_order => 'desc')
+    mail :to => recipients,
+      :subject => l(:mail_subject_account_activation_request, Setting.app_title)
+  end
+
+  # Builds a Mail::Message object used to email the specified user that their account was activated by an administrator.
+  #
+  # Example:
+  #   account_activated(user) => Mail::Message object
+  #   Mailer.account_activated(user).deliver => sends an email to the registered user
+  def account_activated(user)
+    set_language_if_valid user.language
+    @user = user
+    @login_url = url_for(:controller => 'account', :action => 'login')
+    mail :to => user.mail,
+      :subject => l(:mail_subject_register, Setting.app_title)
+  end
+
+  def lost_password(token)
+    set_language_if_valid(token.user.language)
+    @token = token
+    @url = url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
+    mail :to => token.user.mail,
+      :subject => l(:mail_subject_lost_password, Setting.app_title)
+  end
+
+  def register(token)
+    set_language_if_valid(token.user.language)
+    @token = token
+    @url = url_for(:controller => 'account', :action => 'activate', :token => token.value)
+    mail :to => token.user.mail,
+      :subject => l(:mail_subject_register, Setting.app_title)
+  end
+
+  def test_email(user)
+    set_language_if_valid(user.language)
+    @url = url_for(:controller => 'welcome')
+    mail :to => user.mail,
+      :subject => 'Redmine test'
+  end
+
+  # Overrides default deliver! method to prevent from sending an email
+  # with no recipient, cc or bcc
+  def deliver!(mail = @mail)
+    set_language_if_valid @initial_language
+    return false if (recipients.nil? || recipients.empty?) &&
+                    (cc.nil? || cc.empty?) &&
+                    (bcc.nil? || bcc.empty?)
+
+
+    # Log errors when raise_delivery_errors is set to false, Rails does not
+    raise_errors = self.class.raise_delivery_errors
+    self.class.raise_delivery_errors = true
+    begin
+      return super(mail)
+    rescue Exception => e
+      if raise_errors
+        raise e
+      elsif mylogger
+        mylogger.error "The following error occured while sending email notification: \"#{e.message}\". Check your configuration in config/configuration.yml."
+      end
+    ensure
+      self.class.raise_delivery_errors = raise_errors
+    end
+  end
+
+  # Sends reminders to issue assignees
+  # Available options:
+  # * :days     => how many days in the future to remind about (defaults to 7)
+  # * :tracker  => id of tracker for filtering issues (defaults to all trackers)
+  # * :project  => id or identifier of project to process (defaults to all projects)
+  # * :users    => array of user/group ids who should be reminded
+  def self.reminders(options={})
+    days = options[:days] || 7
+    project = options[:project] ? Project.find(options[:project]) : nil
+    tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
+    user_ids = options[:users]
+
+    scope = Issue.open.where("#{Issue.table_name}.assigned_to_id IS NOT NULL" +
+      " AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
+      " AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date
+    )
+    scope = scope.where(:assigned_to_id => user_ids) if user_ids.present?
+    scope = scope.where(:project_id => project.id) if project
+    scope = scope.where(:tracker_id => tracker.id) if tracker
+
+    issues_by_assignee = scope.includes(:status, :assigned_to, :project, :tracker).all.group_by(&:assigned_to)
+    issues_by_assignee.keys.each do |assignee|
+      if assignee.is_a?(Group)
+        assignee.users.each do |user|
+          issues_by_assignee[user] ||= []
+          issues_by_assignee[user] += issues_by_assignee[assignee]
+        end
+      end
+    end
+
+    issues_by_assignee.each do |assignee, issues|
+      reminder(assignee, issues, days).deliver if assignee.is_a?(User) && assignee.active?
+    end
+  end
+
+  # Activates/desactivates email deliveries during +block+
+  def self.with_deliveries(enabled = true, &block)
+    was_enabled = ActionMailer::Base.perform_deliveries
+    ActionMailer::Base.perform_deliveries = !!enabled
+    yield
+  ensure
+    ActionMailer::Base.perform_deliveries = was_enabled
+  end
+
+  # Sends emails synchronously in the given block
+  def self.with_synched_deliveries(&block)
+    saved_method = ActionMailer::Base.delivery_method
+    if m = saved_method.to_s.match(%r{^async_(.+)$})
+      synched_method = m[1]
+      ActionMailer::Base.delivery_method = synched_method.to_sym
+      ActionMailer::Base.send "#{synched_method}_settings=", ActionMailer::Base.send("async_#{synched_method}_settings")
+    end
+    yield
+  ensure
+    ActionMailer::Base.delivery_method = saved_method
+  end
+
+  def mail(headers={})
+    headers.merge! 'X-Mailer' => 'Redmine',
+            'X-Redmine-Host' => Setting.host_name,
+            'X-Redmine-Site' => Setting.app_title,
+            'X-Auto-Response-Suppress' => 'OOF',
+            'Auto-Submitted' => 'auto-generated',
+            'From' => Setting.mail_from,
+            'List-Id' => "<#{Setting.mail_from.to_s.gsub('@', '.')}>"
+
+    # Removes the author from the recipients and cc
+    # if he doesn't want to receive notifications about what he does
+    if @author && @author.logged? && @author.pref[:no_self_notified]
+      headers[:to].delete(@author.mail) if headers[:to].is_a?(Array)
+      headers[:cc].delete(@author.mail) if headers[:cc].is_a?(Array)
+    end
+
+    if @author && @author.logged?
+      redmine_headers 'Sender' => @author.login
+    end
+
+    # Blind carbon copy recipients
+    if Setting.bcc_recipients?
+      headers[:bcc] = [headers[:to], headers[:cc]].flatten.uniq.reject(&:blank?)
+      headers[:to] = nil
+      headers[:cc] = nil
+    end
+
+    if @message_id_object
+      headers[:message_id] = "<#{self.class.message_id_for(@message_id_object)}>"
+    end
+    if @references_objects
+      headers[:references] = @references_objects.collect {|o| "<#{self.class.message_id_for(o)}>"}.join(' ')
+    end
+
+    super headers do |format|
+      format.text
+      format.html unless Setting.plain_text_mail?
+    end
+
+    set_language_if_valid @initial_language
+  end
+
+  def initialize(*args)
+    @initial_language = current_language
+    set_language_if_valid Setting.default_language
+    super
+  end
+  
+  def self.deliver_mail(mail)
+    return false if mail.to.blank? && mail.cc.blank? && mail.bcc.blank?
+    super
+  end
+
+  def self.method_missing(method, *args, &block)
+    if m = method.to_s.match(%r{^deliver_(.+)$})
+      ActiveSupport::Deprecation.warn "Mailer.deliver_#{m[1]}(*args) is deprecated. Use Mailer.#{m[1]}(*args).deliver instead."
+      send(m[1], *args).deliver
+    else
+      super
+    end
+  end
+
+  private
+
+  # Appends a Redmine header field (name is prepended with 'X-Redmine-')
+  def redmine_headers(h)
+    h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
+  end
+
+  # Returns a predictable Message-Id for the given object
+  def self.message_id_for(object)
+    # id + timestamp should reduce the odds of a collision
+    # as far as we don't send multiple emails for the same object
+    timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
+    hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
+    host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
+    host = "#{::Socket.gethostname}.redmine" if host.empty?
+    "#{hash}@#{host}"
+  end
+
+  def message_id(object)
+    @message_id_object = object
+  end
+
+  def references(object)
+    @references_objects ||= []
+    @references_objects << object
+  end
+
+  def mylogger
+    Rails.logger
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/09/09ee2f48a5aafa2ec6da3a021e076cc86af61f01.svn-base
--- a/.svn/pristine/09/09ee2f48a5aafa2ec6da3a021e076cc86af61f01.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= l(:label_board_new) %></h2>
-
-<% labelled_tabular_form_for :board, @board, :url => {:action => 'new'} do |f| %>
-  <%= render :partial => 'form', :locals => {:f => f} %>
-  <%= submit_tag l(:button_create) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/09/09fd6db0926bf35a4db846796898a3efe70dfa6f.svn-base
--- a/.svn/pristine/09/09fd6db0926bf35a4db846796898a3efe70dfa6f.svn-base
+++ /dev/null
@@ -1,40 +0,0 @@
-<table class="list transitions-<%= name %>">
-<thead>
-  <tr>
-    <th align="left">
-      <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input')",
-                                                          :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
-      <%=l(:label_current_status)%>
-    </th>
-    <th align="center" colspan="<%= @statuses.length %>"><%=l(:label_new_statuses_allowed)%></th>
-  </tr>
-  <tr>
-    <td></td>
-    <% for new_status in @statuses %>
-    <td width="<%= 75 / @statuses.size %>%" align="center">
-      <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input.new-status-#{new_status.id}')",
-                                                      :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
-      <%=h new_status.name %>
-    </td>
-    <% end %>
-  </tr>
-</thead>
-<tbody>
-  <% for old_status in @statuses %>
-  <tr class="<%= cycle("odd", "even") %>">
-    <td>
-      <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input.old-status-#{old_status.id}')",
-                                                          :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
-
-      <%=h old_status.name %>
-    </td>
-    <% for new_status in @statuses -%>
-    <td align="center">
-      <%= check_box_tag "issue_status[#{ old_status.id }][#{new_status.id}][]", name, workflows.detect {|w| w.old_status_id == old_status.id && w.new_status_id == new_status.id},
-            :class => "old-status-#{old_status.id} new-status-#{new_status.id}" %>
-    </td>
-    <% end -%>
-  </tr>
-  <% end %>
-</tbody>
-</table>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0a/0a01ef88ba34bfc6a3c1cef8891538f7504e9b0c.svn-base
--- /dev/null
+++ b/.svn/pristine/0a/0a01ef88ba34bfc6a3c1cef8891538f7504e9b0c.svn-base
@@ -0,0 +1,184 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module I18n
+    def self.included(base)
+      base.extend Redmine::I18n
+    end
+
+    def l(*args)
+      case args.size
+      when 1
+        ::I18n.t(*args)
+      when 2
+        if args.last.is_a?(Hash)
+          ::I18n.t(*args)
+        elsif args.last.is_a?(String)
+          ::I18n.t(args.first, :value => args.last)
+        else
+          ::I18n.t(args.first, :count => args.last)
+        end
+      else
+        raise "Translation string with multiple values: #{args.first}"
+      end
+    end
+
+    def l_or_humanize(s, options={})
+      k = "#{options[:prefix]}#{s}".to_sym
+      ::I18n.t(k, :default => s.to_s.humanize)
+    end
+
+    def l_hours(hours)
+      hours = hours.to_f
+      l((hours < 2.0 ? :label_f_hour : :label_f_hour_plural), :value => ("%.2f" % hours.to_f))
+    end
+
+    def ll(lang, str, value=nil)
+      ::I18n.t(str.to_s, :value => value, :locale => lang.to_s.gsub(%r{(.+)\-(.+)$}) { "#{$1}-#{$2.upcase}" })
+    end
+
+    def format_date(date)
+      return nil unless date
+      options = {}
+      options[:format] = Setting.date_format unless Setting.date_format.blank?
+      options[:locale] = User.current.language unless User.current.language.blank?
+      ::I18n.l(date.to_date, options)
+    end
+
+    def format_time(time, include_date = true)
+      return nil unless time
+      options = {}
+      options[:format] = (Setting.time_format.blank? ? :time : Setting.time_format)
+      options[:locale] = User.current.language unless User.current.language.blank?
+      time = time.to_time if time.is_a?(String)
+      zone = User.current.time_zone
+      local = zone ? time.in_time_zone(zone) : (time.utc? ? time.localtime : time)
+      (include_date ? "#{format_date(local)} " : "") + ::I18n.l(local, options)
+    end
+
+    def day_name(day)
+      ::I18n.t('date.day_names')[day % 7]
+    end
+
+    def day_letter(day)
+      ::I18n.t('date.abbr_day_names')[day % 7].first
+    end
+
+    def month_name(month)
+      ::I18n.t('date.month_names')[month]
+    end
+
+    def valid_languages
+      ::I18n.available_locales
+    end
+
+    # Returns an array of languages names and code sorted by names, example:
+    # [["Deutsch", "de"], ["English", "en"] ...]
+    #
+    # The result is cached to prevent from loading all translations files.
+    def languages_options
+      ActionController::Base.cache_store.fetch "i18n/languages_options" do
+        valid_languages.map {|lang| [ll(lang.to_s, :general_lang_name), lang.to_s]}.sort {|x,y| x.first <=> y.first }
+      end      
+    end
+
+    def find_language(lang)
+      @@languages_lookup = valid_languages.inject({}) {|k, v| k[v.to_s.downcase] = v; k }
+      @@languages_lookup[lang.to_s.downcase]
+    end
+
+    def set_language_if_valid(lang)
+      if l = find_language(lang)
+        ::I18n.locale = l
+      end
+    end
+
+    def current_language
+      ::I18n.locale
+    end
+
+    # Custom backend based on I18n::Backend::Simple with the following changes:
+    # * lazy loading of translation files
+    # * available_locales are determined by looking at translation file names
+    class Backend
+      (class << self; self; end).class_eval { public :include }
+
+      module Implementation
+        include ::I18n::Backend::Base
+
+        # Stores translations for the given locale in memory.
+        # This uses a deep merge for the translations hash, so existing
+        # translations will be overwritten by new ones only at the deepest
+        # level of the hash.
+        def store_translations(locale, data, options = {})
+          locale = locale.to_sym
+          translations[locale] ||= {}
+          data = data.deep_symbolize_keys
+          translations[locale].deep_merge!(data)
+        end
+
+        # Get available locales from the translations filenames
+        def available_locales
+          @available_locales ||= ::I18n.load_path.map {|path| File.basename(path, '.*')}.uniq.sort.map(&:to_sym)
+        end
+
+        # Clean up translations
+        def reload!
+          @translations = nil
+          @available_locales = nil
+          super
+        end
+
+        protected
+
+        def init_translations(locale)
+          locale = locale.to_s
+          paths = ::I18n.load_path.select {|path| File.basename(path, '.*') == locale}
+          load_translations(paths)
+          translations[locale] ||= {}
+        end
+
+        def translations
+          @translations ||= {}
+        end
+
+        # Looks up a translation from the translations hash. Returns nil if
+        # eiher key is nil, or locale, scope or key do not exist as a key in the
+        # nested translations hash. Splits keys or scopes containing dots
+        # into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
+        # <tt>%w(currency format)</tt>.
+        def lookup(locale, key, scope = [], options = {})
+          init_translations(locale) unless translations.key?(locale)
+          keys = ::I18n.normalize_keys(locale, key, scope, options[:separator])
+
+          keys.inject(translations) do |result, _key|
+            _key = _key.to_sym
+            return nil unless result.is_a?(Hash) && result.has_key?(_key)
+            result = result[_key]
+            result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
+            result
+          end
+        end
+      end
+
+      include Implementation
+      # Adds fallback to default locale for untranslated strings
+      include ::I18n::Backend::Fallbacks
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0a/0a371b310545389947180083feb53371bb868f67.svn-base
--- a/.svn/pristine/0a/0a371b310545389947180083feb53371bb868f67.svn-base
+++ /dev/null
@@ -1,17 +0,0 @@
-module CodeRay
-module Encoders
-  
-  map \
-    :loc             => :lines_of_code,
-    :plain           => :text,
-    :plaintext       => :text,
-    :remove_comments => :comment_filter,
-    :stats           => :statistic,
-    :term            => :terminal,
-    :tty             => :terminal,
-    :yml             => :yaml
-  
-  # No default because Tokens#nonsense should raise NoMethodError.
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0a/0a62a3ae28a4f2df93a63c650d603c29ff087559.svn-base
--- a/.svn/pristine/0a/0a62a3ae28a4f2df93a63c650d603c29ff087559.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-<% form_tag({:action => 'edit', :tab => 'mail_handler'}) do %>
-
-<div class="box tabular settings">
-  <p>
-    <%= setting_text_area :mail_handler_body_delimiters, :rows => 5 %>
-    <br /><em><%= l(:text_line_separated) %></em>
-  </p>
-</div>
-
-<div class="box tabular settings">
-<p><%= setting_check_box :mail_handler_api_enabled,
-         :onclick => "if (this.checked) { Form.Element.enable('settings_mail_handler_api_key'); } else { Form.Element.disable('settings_mail_handler_api_key'); }"%></p>
-
-<p><%= setting_text_field :mail_handler_api_key, :size => 30,
-                                                 :id => 'settings_mail_handler_api_key',
-                                                 :disabled => !Setting.mail_handler_api_enabled? %>
-  <%= link_to_function l(:label_generate_key), "if ($('settings_mail_handler_api_key').disabled == false) { $('settings_mail_handler_api_key').value = randomKey(20) }" %>
-</p>
-</div>
-
-<%= submit_tag l(:button_save) %>
-
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0a/0a884b128ca03268f26234e1c96b240bce5a6e1b.svn-base
--- a/.svn/pristine/0a/0a884b128ca03268f26234e1c96b240bce5a6e1b.svn-base
+++ /dev/null
@@ -1,101 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class EnumerationsControllerTest < ActionController::TestCase
-  fixtures :enumerations, :issues, :users
-
-  def setup
-    @request.session[:user_id] = 1 # admin
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-  end
-
-  def test_new
-    get :new, :type => 'IssuePriority'
-    assert_response :success
-    assert_template 'new'
-    assert_kind_of IssuePriority, assigns(:enumeration)
-  end
-
-  def test_create
-    assert_difference 'IssuePriority.count' do
-      post :create, :enumeration => {:type => 'IssuePriority', :name => 'Lowest'}
-    end
-    assert_redirected_to '/enumerations?type=IssuePriority'
-    e = IssuePriority.first(:order => 'id DESC')
-    assert_equal 'Lowest', e.name
-  end
-
-  def test_create_with_failure
-    assert_no_difference 'IssuePriority.count' do
-      post :create, :enumeration => {:type => 'IssuePriority', :name => ''}
-    end
-    assert_response :success
-    assert_template 'new'
-  end
-
-  def test_edit
-    get :edit, :id => 6
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_update
-    assert_no_difference 'IssuePriority.count' do
-      post :update, :id => 6, :enumeration => {:type => 'IssuePriority', :name => 'New name'}
-    end
-    assert_redirected_to '/enumerations?type=IssuePriority'
-    e = IssuePriority.find(6)
-    assert_equal 'New name', e.name
-  end
-
-  def test_update_with_failure
-    assert_no_difference 'IssuePriority.count' do
-      post :update, :id => 6, :enumeration => {:type => 'IssuePriority', :name => ''}
-    end
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_destroy_enumeration_not_in_use
-    post :destroy, :id => 7
-    assert_redirected_to :controller => 'enumerations', :action => 'index'
-    assert_nil Enumeration.find_by_id(7)
-  end
-
-  def test_destroy_enumeration_in_use
-    post :destroy, :id => 4
-    assert_response :success
-    assert_template 'destroy'
-    assert_not_nil Enumeration.find_by_id(4)
-  end
-
-  def test_destroy_enumeration_in_use_with_reassignment
-    issue = Issue.find(:first, :conditions => {:priority_id => 4})
-    post :destroy, :id => 4, :reassign_to_id => 6
-    assert_redirected_to :controller => 'enumerations', :action => 'index'
-    assert_nil Enumeration.find_by_id(4)
-    # check that the issue was reassign
-    assert_equal 6, issue.reload.priority_id
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0a/0ab85a80b71d453bc34359193f9b3a077fde14bb.svn-base
--- /dev/null
+++ b/.svn/pristine/0a/0ab85a80b71d453bc34359193f9b3a077fde14bb.svn-base
@@ -0,0 +1,279 @@
+module ActiveRecord
+  module Acts #:nodoc:
+    module List #:nodoc:
+      def self.included(base)
+        base.extend(ClassMethods)
+      end
+
+      # This +acts_as+ extension provides the capabilities for sorting and reordering a number of objects in a list.
+      # The class that has this specified needs to have a +position+ column defined as an integer on
+      # the mapped database table.
+      #
+      # Todo list example:
+      #
+      #   class TodoList < ActiveRecord::Base
+      #     has_many :todo_items, :order => "position"
+      #   end
+      #
+      #   class TodoItem < ActiveRecord::Base
+      #     belongs_to :todo_list
+      #     acts_as_list :scope => :todo_list
+      #   end
+      #
+      #   todo_list.first.move_to_bottom
+      #   todo_list.last.move_higher
+      module ClassMethods
+        # Configuration options are:
+        #
+        # * +column+ - specifies the column name to use for keeping the position integer (default: +position+)
+        # * +scope+ - restricts what is to be considered a list. Given a symbol, it'll attach <tt>_id</tt> 
+        #   (if it hasn't already been added) and use that as the foreign key restriction. It's also possible 
+        #   to give it an entire string that is interpolated if you need a tighter scope than just a foreign key.
+        #   Example: <tt>acts_as_list :scope => 'todo_list_id = #{todo_list_id} AND completed = 0'</tt>
+        def acts_as_list(options = {})
+          configuration = { :column => "position", :scope => "1 = 1" }
+          configuration.update(options) if options.is_a?(Hash)
+
+          configuration[:scope] = "#{configuration[:scope]}_id".intern if configuration[:scope].is_a?(Symbol) && configuration[:scope].to_s !~ /_id$/
+
+          if configuration[:scope].is_a?(Symbol)
+            scope_condition_method = %(
+              def scope_condition
+                if #{configuration[:scope].to_s}.nil?
+                  "#{configuration[:scope].to_s} IS NULL"
+                else
+                  "#{configuration[:scope].to_s} = \#{#{configuration[:scope].to_s}}"
+                end
+              end
+            )
+          else
+            scope_condition_method = "def scope_condition() \"#{configuration[:scope]}\" end"
+          end
+
+          class_eval <<-EOV
+            include ActiveRecord::Acts::List::InstanceMethods
+
+            def acts_as_list_class
+              ::#{self.name}
+            end
+
+            def position_column
+              '#{configuration[:column]}'
+            end
+
+            #{scope_condition_method}
+
+            before_destroy :remove_from_list
+            before_create  :add_to_list_bottom
+          EOV
+        end
+      end
+
+      # All the methods available to a record that has had <tt>acts_as_list</tt> specified. Each method works
+      # by assuming the object to be the item in the list, so <tt>chapter.move_lower</tt> would move that chapter
+      # lower in the list of all chapters. Likewise, <tt>chapter.first?</tt> would return +true+ if that chapter is
+      # the first in the list of all chapters.
+      module InstanceMethods
+        # Insert the item at the given position (defaults to the top position of 1).
+        def insert_at(position = 1)
+          insert_at_position(position)
+        end
+
+        # Swap positions with the next lower item, if one exists.
+        def move_lower
+          return unless lower_item
+
+          acts_as_list_class.transaction do
+            lower_item.decrement_position
+            increment_position
+          end
+        end
+
+        # Swap positions with the next higher item, if one exists.
+        def move_higher
+          return unless higher_item
+
+          acts_as_list_class.transaction do
+            higher_item.increment_position
+            decrement_position
+          end
+        end
+
+        # Move to the bottom of the list. If the item is already in the list, the items below it have their
+        # position adjusted accordingly.
+        def move_to_bottom
+          return unless in_list?
+          acts_as_list_class.transaction do
+            decrement_positions_on_lower_items
+            assume_bottom_position
+          end
+        end
+
+        # Move to the top of the list. If the item is already in the list, the items above it have their
+        # position adjusted accordingly.
+        def move_to_top
+          return unless in_list?
+          acts_as_list_class.transaction do
+            increment_positions_on_higher_items
+            assume_top_position
+          end
+        end
+        
+        # Move to the given position
+        def move_to=(pos)
+          case pos.to_s
+          when 'highest'
+            move_to_top
+          when 'higher'
+            move_higher
+          when 'lower'
+            move_lower
+          when 'lowest'
+            move_to_bottom
+          end
+          reset_positions_in_list
+        end
+
+        def reset_positions_in_list
+          acts_as_list_class.where(scope_condition).reorder("#{position_column} ASC, id ASC").each_with_index do |item, i|
+            unless item.send(position_column) == (i + 1)
+              acts_as_list_class.update_all({position_column => (i + 1)}, {:id => item.id})
+            end
+          end
+        end
+
+        # Removes the item from the list.
+        def remove_from_list
+          if in_list?
+            decrement_positions_on_lower_items
+            update_attribute position_column, nil
+          end
+        end
+
+        # Increase the position of this item without adjusting the rest of the list.
+        def increment_position
+          return unless in_list?
+          update_attribute position_column, self.send(position_column).to_i + 1
+        end
+
+        # Decrease the position of this item without adjusting the rest of the list.
+        def decrement_position
+          return unless in_list?
+          update_attribute position_column, self.send(position_column).to_i - 1
+        end
+
+        # Return +true+ if this object is the first in the list.
+        def first?
+          return false unless in_list?
+          self.send(position_column) == 1
+        end
+
+        # Return +true+ if this object is the last in the list.
+        def last?
+          return false unless in_list?
+          self.send(position_column) == bottom_position_in_list
+        end
+
+        # Return the next higher item in the list.
+        def higher_item
+          return nil unless in_list?
+          acts_as_list_class.where(
+            "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}"
+          ).first
+        end
+
+        # Return the next lower item in the list.
+        def lower_item
+          return nil unless in_list?
+          acts_as_list_class.where(
+            "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}"
+          ).first
+        end
+
+        # Test if this record is in a list
+        def in_list?
+          !send(position_column).nil?
+        end
+
+        private
+          def add_to_list_top
+            increment_positions_on_all_items
+          end
+
+          def add_to_list_bottom
+            self[position_column] = bottom_position_in_list.to_i + 1
+          end
+
+          # Overwrite this method to define the scope of the list changes
+          def scope_condition() "1" end
+
+          # Returns the bottom position number in the list.
+          #   bottom_position_in_list    # => 2
+          def bottom_position_in_list(except = nil)
+            item = bottom_item(except)
+            item ? item.send(position_column) : 0
+          end
+
+          # Returns the bottom item
+          def bottom_item(except = nil)
+            conditions = scope_condition
+            conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except
+            acts_as_list_class.where(conditions).reorder("#{position_column} DESC").first
+          end
+
+          # Forces item to assume the bottom position in the list.
+          def assume_bottom_position
+            update_attribute(position_column, bottom_position_in_list(self).to_i + 1)
+          end
+
+          # Forces item to assume the top position in the list.
+          def assume_top_position
+            update_attribute(position_column, 1)
+          end
+
+          # This has the effect of moving all the higher items up one.
+          def decrement_positions_on_higher_items(position)
+            acts_as_list_class.update_all(
+              "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} <= #{position}"
+            )
+          end
+
+          # This has the effect of moving all the lower items up one.
+          def decrement_positions_on_lower_items
+            return unless in_list?
+            acts_as_list_class.update_all(
+              "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} > #{send(position_column).to_i}"
+            )
+          end
+
+          # This has the effect of moving all the higher items down one.
+          def increment_positions_on_higher_items
+            return unless in_list?
+            acts_as_list_class.update_all(
+              "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} < #{send(position_column).to_i}"
+            )
+          end
+
+          # This has the effect of moving all the lower items down one.
+          def increment_positions_on_lower_items(position)
+            acts_as_list_class.update_all(
+              "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} >= #{position}"
+           )
+          end
+
+          # Increments position (<tt>position_column</tt>) of all items in the list.
+          def increment_positions_on_all_items
+            acts_as_list_class.update_all(
+              "#{position_column} = (#{position_column} + 1)",  "#{scope_condition}"
+            )
+          end
+
+          def insert_at_position(position)
+            remove_from_list
+            increment_positions_on_lower_items(position)
+            self.update_attribute(position_column, position)
+          end
+      end 
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0b/0b7befce1d7322f245834ffc9480adf8d5c60890.svn-base
--- /dev/null
+++ b/.svn/pristine/0b/0b7befce1d7322f245834ffc9480adf8d5c60890.svn-base
@@ -0,0 +1,294 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../test_case', __FILE__)
+require 'tmpdir'
+
+class RedminePmTest::RepositorySubversionTest < RedminePmTest::TestCase
+  fixtures :projects, :users, :members, :roles, :member_roles, :auth_sources
+
+  SVN_BIN = Redmine::Configuration['scm_subversion_command'] || "svn"
+
+  def test_anonymous_read_on_public_repo_with_permission_should_succeed
+    assert_success "ls", svn_url
+  end
+
+  def test_anonymous_read_on_public_repo_without_permission_should_fail
+    Role.anonymous.remove_permission! :browse_repository
+    assert_failure "ls", svn_url
+  end
+
+  def test_anonymous_read_on_private_repo_should_fail
+    Project.find(1).update_attribute :is_public, false
+    assert_failure "ls", svn_url
+  end
+
+  def test_anonymous_commit_on_public_repo_should_fail
+    Role.anonymous.add_permission! :commit_access
+    assert_failure "mkdir --message Creating_a_directory", svn_url(random_filename)
+  end
+
+  def test_anonymous_commit_on_private_repo_should_fail
+    Role.anonymous.add_permission! :commit_access
+    Project.find(1).update_attribute :is_public, false
+    assert_failure "mkdir --message Creating_a_directory", svn_url(random_filename)
+  end
+
+  def test_non_member_read_on_public_repo_with_permission_should_succeed
+    Role.anonymous.remove_permission! :browse_repository
+    with_credentials "miscuser8", "foo" do
+      assert_success "ls", svn_url
+    end
+  end
+
+  def test_non_member_read_on_public_repo_without_permission_should_fail
+    Role.anonymous.remove_permission! :browse_repository
+    Role.non_member.remove_permission! :browse_repository
+    with_credentials "miscuser8", "foo" do
+      assert_failure "ls", svn_url
+    end
+  end
+
+  def test_non_member_read_on_private_repo_should_fail
+    Project.find(1).update_attribute :is_public, false
+    with_credentials "miscuser8", "foo" do
+      assert_failure "ls", svn_url
+    end
+  end
+
+  def test_non_member_commit_on_public_repo_should_fail
+    Role.non_member.add_permission! :commit_access
+    assert_failure "mkdir --message Creating_a_directory", svn_url(random_filename)
+  end
+
+  def test_non_member_commit_on_private_repo_should_fail
+    Role.non_member.add_permission! :commit_access
+    Project.find(1).update_attribute :is_public, false
+    assert_failure "mkdir --message Creating_a_directory", svn_url(random_filename)
+  end
+
+  def test_member_read_on_public_repo_with_permission_should_succeed
+    Role.anonymous.remove_permission! :browse_repository
+    Role.non_member.remove_permission! :browse_repository
+    with_credentials "dlopper", "foo" do
+      assert_success "ls", svn_url
+    end
+  end
+
+  def test_member_read_on_public_repo_without_permission_should_fail
+    Role.anonymous.remove_permission! :browse_repository
+    Role.non_member.remove_permission! :browse_repository
+    Role.find(2).remove_permission! :browse_repository
+    with_credentials "dlopper", "foo" do
+      assert_failure "ls", svn_url
+    end
+  end
+
+  def test_member_read_on_private_repo_with_permission_should_succeed
+    Project.find(1).update_attribute :is_public, false
+    with_credentials "dlopper", "foo" do
+      assert_success "ls", svn_url
+    end
+  end
+
+  def test_member_read_on_private_repo_without_permission_should_fail
+    Role.find(2).remove_permission! :browse_repository
+    Project.find(1).update_attribute :is_public, false
+    with_credentials "dlopper", "foo" do
+      assert_failure "ls", svn_url
+    end
+  end
+
+  def test_member_commit_on_public_repo_with_permission_should_succeed
+    Role.find(2).add_permission! :commit_access
+    with_credentials "dlopper", "foo" do
+      assert_success "mkdir --message Creating_a_directory", svn_url(random_filename)
+    end
+  end
+
+  def test_member_commit_on_public_repo_without_permission_should_fail
+    Role.find(2).remove_permission! :commit_access
+    with_credentials "dlopper", "foo" do
+      assert_failure "mkdir --message Creating_a_directory", svn_url(random_filename)
+    end
+  end
+
+  def test_member_commit_on_private_repo_with_permission_should_succeed
+    Role.find(2).add_permission! :commit_access
+    Project.find(1).update_attribute :is_public, false
+    with_credentials "dlopper", "foo" do
+      assert_success "mkdir --message Creating_a_directory", svn_url(random_filename)
+    end
+  end
+
+  def test_member_commit_on_private_repo_without_permission_should_fail
+    Role.find(2).remove_permission! :commit_access
+    Project.find(1).update_attribute :is_public, false
+    with_credentials "dlopper", "foo" do
+      assert_failure "mkdir --message Creating_a_directory", svn_url(random_filename)
+    end
+  end
+
+  def test_invalid_credentials_should_fail
+    Project.find(1).update_attribute :is_public, false
+    with_credentials "dlopper", "foo" do
+      assert_success "ls", svn_url
+    end
+    with_credentials "dlopper", "wrong" do
+      assert_failure "ls", svn_url
+    end
+  end
+
+  def test_anonymous_read_should_fail_with_login_required
+    assert_success "ls", svn_url
+    with_settings :login_required => '1' do
+      assert_failure "ls", svn_url
+    end
+  end
+
+  def test_authenticated_read_should_succeed_with_login_required
+    with_settings :login_required => '1' do
+      with_credentials "miscuser8", "foo" do
+        assert_success "ls", svn_url
+      end
+    end
+  end
+
+  def test_read_on_archived_projects_should_fail
+    Project.find(1).update_attribute :status, Project::STATUS_ARCHIVED
+    assert_failure "ls", svn_url
+  end
+
+  def test_read_on_archived_private_projects_should_fail
+    Project.find(1).update_attribute :status, Project::STATUS_ARCHIVED
+    Project.find(1).update_attribute :is_public, false
+    with_credentials "dlopper", "foo" do
+      assert_failure "ls", svn_url
+    end
+  end
+
+  def test_read_on_closed_projects_should_succeed
+    Project.find(1).update_attribute :status, Project::STATUS_CLOSED
+    assert_success "ls", svn_url
+  end
+
+  def test_read_on_closed_private_projects_should_succeed
+    Project.find(1).update_attribute :status, Project::STATUS_CLOSED
+    Project.find(1).update_attribute :is_public, false
+    with_credentials "dlopper", "foo" do
+      assert_success "ls", svn_url
+    end
+  end
+
+  def test_commit_on_closed_projects_should_fail
+    Project.find(1).update_attribute :status, Project::STATUS_CLOSED
+    Role.find(2).add_permission! :commit_access
+    with_credentials "dlopper", "foo" do
+      assert_failure "mkdir --message Creating_a_directory", svn_url(random_filename)
+    end
+  end
+
+  def test_commit_on_closed_private_projects_should_fail
+    Project.find(1).update_attribute :status, Project::STATUS_CLOSED
+    Project.find(1).update_attribute :is_public, false
+    Role.find(2).add_permission! :commit_access
+    with_credentials "dlopper", "foo" do
+      assert_failure "mkdir --message Creating_a_directory", svn_url(random_filename)
+    end
+  end
+
+  if ldap_configured?
+    def test_user_with_ldap_auth_source_should_authenticate_with_ldap_credentials
+      ldap_user = User.new(:mail => 'example1@redmine.org', :firstname => 'LDAP', :lastname => 'user', :auth_source_id => 1)
+      ldap_user.login = 'example1'
+      ldap_user.save!
+  
+      with_settings :login_required => '1' do
+        with_credentials "example1", "123456" do
+          assert_success "ls", svn_url
+        end
+      end
+  
+      with_settings :login_required => '1' do
+        with_credentials "example1", "wrong" do
+          assert_failure "ls", svn_url
+        end
+      end
+    end
+  end
+
+  def test_checkout
+    Dir.mktmpdir do |dir|
+      assert_success "checkout", svn_url, dir
+    end
+  end
+
+  def test_read_commands
+    assert_success "info", svn_url
+    assert_success "ls", svn_url
+    assert_success "log", svn_url
+  end
+
+  def test_write_commands
+    Role.find(2).add_permission! :commit_access
+    filename = random_filename
+
+    Dir.mktmpdir do |dir|
+      assert_success "checkout", svn_url, dir
+      Dir.chdir(dir) do
+        # creates a file in the working copy
+        f = File.new(File.join(dir, filename), "w")
+        f.write "test file content"
+        f.close
+
+        assert_success "add", filename
+        with_credentials "dlopper", "foo" do
+          assert_success "commit --message Committing_a_file"
+          assert_success "copy   --message Copying_a_file", svn_url(filename), svn_url("#{filename}_copy")
+          assert_success "delete --message Deleting_a_file", svn_url(filename)
+          assert_success "mkdir  --message Creating_a_directory", svn_url("#{filename}_dir")
+        end
+        assert_success "update"
+
+        # checks that the working copy was updated
+        assert File.exists?(File.join(dir, "#{filename}_copy"))
+        assert File.directory?(File.join(dir, "#{filename}_dir"))
+      end
+    end
+  end
+
+  def test_read_invalid_repo_should_fail
+    assert_failure "ls", svn_url("invalid")
+  end
+
+  protected
+
+  def execute(*args)
+    a = [SVN_BIN, "--no-auth-cache --non-interactive"]
+    a << "--username #{username}" if username
+    a << "--password #{password}" if password
+
+    super a, *args
+  end
+
+  def svn_url(path=nil)
+    host = ENV['REDMINE_TEST_DAV_SERVER'] || '127.0.0.1'
+    url = "http://#{host}/svn/ecookbook"
+    url << "/#{path}" if path
+    url
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0b/0b8467ea6271bd6bbf31748ec5f34d49b8671c8b.svn-base
--- /dev/null
+++ b/.svn/pristine/0b/0b8467ea6271bd6bbf31748ec5f34d49b8671c8b.svn-base
@@ -0,0 +1,23 @@
+/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */
+/* Written by Jamil Najafov (necefov33@gmail.com). */
+jQuery(function($) {
+	$.datepicker.regional['az'] = {
+		closeText: 'BaÄŸla',
+		prevText: '&#x3C;Geri',
+		nextText: 'Ä°rÉ™li&#x3E;',
+		currentText: 'BugÃ¼n',
+		monthNames: ['Yanvar','Fevral','Mart','Aprel','May','Ä°yun',
+		'Ä°yul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'],
+		monthNamesShort: ['Yan','Fev','Mar','Apr','May','Ä°yun',
+		'Ä°yul','Avq','Sen','Okt','Noy','Dek'],
+		dayNames: ['Bazar','Bazar ertÉ™si','Ã‡É™rÅŸÉ™nbÉ™ axÅŸamÄ±','Ã‡É™rÅŸÉ™nbÉ™','CÃ¼mÉ™ axÅŸamÄ±','CÃ¼mÉ™','ÅžÉ™nbÉ™'],
+		dayNamesShort: ['B','Be','Ã‡a','Ã‡','Ca','C','Åž'],
+		dayNamesMin: ['B','B','Ã‡','Ð¡','Ã‡','C','Åž'],
+		weekHeader: 'Hf',
+		dateFormat: 'dd.mm.yy',
+		firstDay: 1,
+		isRTL: false,
+		showMonthAfterYear: false,
+		yearSuffix: ''};
+	$.datepicker.setDefaults($.datepicker.regional['az']);
+});
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0b/0b8a142f46ed608799d7faf6016772f4b1f09f42.svn-base
--- /dev/null
+++ b/.svn/pristine/0b/0b8a142f46ed608799d7faf6016772f4b1f09f42.svn-base
@@ -0,0 +1,47 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingAdminTest < ActionController::IntegrationTest
+  def test_administration_panel
+    assert_routing(
+        { :method => 'get', :path => "/admin" },
+        { :controller => 'admin', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/admin/projects" },
+        { :controller => 'admin', :action => 'projects' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/admin/plugins" },
+        { :controller => 'admin', :action => 'plugins' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/admin/info" },
+        { :controller => 'admin', :action => 'info' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/admin/test_email" },
+        { :controller => 'admin', :action => 'test_email' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/admin/default_configuration" },
+        { :controller => 'admin', :action => 'default_configuration' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0b/0b97b483eed443a57933ffcafedb4eb971db5cf5.svn-base
--- a/.svn/pristine/0b/0b97b483eed443a57933ffcafedb4eb971db5cf5.svn-base
+++ /dev/null
@@ -1,325 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class ScmFetchError < Exception; end
-
-class Repository < ActiveRecord::Base
-  include Redmine::Ciphering
-
-  belongs_to :project
-  has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
-  has_many :changes, :through => :changesets
-
-  serialize :extra_info
-
-  # Raw SQL to delete changesets and changes in the database
-  # has_many :changesets, :dependent => :destroy is too slow for big repositories
-  before_destroy :clear_changesets
-
-  validates_length_of :password, :maximum => 255, :allow_nil => true
-  # Checks if the SCM is enabled when creating a repository
-  validate :repo_create_validation, :on => :create
-
-  def repo_create_validation
-    unless Setting.enabled_scm.include?(self.class.name.demodulize)
-      errors.add(:type, :invalid)
-    end
-  end
-
-  def self.human_attribute_name(attribute_key_name)
-    attr_name = attribute_key_name
-    if attr_name == "log_encoding"
-      attr_name = "commit_logs_encoding"
-    end
-    super(attr_name)
-  end
-
-  # Removes leading and trailing whitespace
-  def url=(arg)
-    write_attribute(:url, arg ? arg.to_s.strip : nil)
-  end
-
-  # Removes leading and trailing whitespace
-  def root_url=(arg)
-    write_attribute(:root_url, arg ? arg.to_s.strip : nil)
-  end
-
-  def password
-    read_ciphered_attribute(:password)
-  end
-
-  def password=(arg)
-    write_ciphered_attribute(:password, arg)
-  end
-
-  def scm_adapter
-    self.class.scm_adapter_class
-  end
-
-  def scm
-    @scm ||= self.scm_adapter.new(url, root_url,
-                                  login, password, path_encoding)
-    update_attribute(:root_url, @scm.root_url) if root_url.blank?
-    @scm
-  end
-
-  def scm_name
-    self.class.scm_name
-  end
-
-  def merge_extra_info(arg)
-    h = extra_info || {}
-    return h if arg.nil?
-    h.merge!(arg)
-    write_attribute(:extra_info, h)
-  end
-
-  def report_last_commit
-    true
-  end
-
-  def supports_cat?
-    scm.supports_cat?
-  end
-
-  def supports_annotate?
-    scm.supports_annotate?
-  end
-
-  def supports_all_revisions?
-    true
-  end
-
-  def supports_directory_revisions?
-    false
-  end
-
-  def supports_revision_graph?
-    false
-  end
-
-  def entry(path=nil, identifier=nil)
-    scm.entry(path, identifier)
-  end
-
-  def entries(path=nil, identifier=nil)
-    scm.entries(path, identifier)
-  end
-
-  def branches
-    scm.branches
-  end
-
-  def tags
-    scm.tags
-  end
-
-  def default_branch
-    nil
-  end
-
-  def properties(path, identifier=nil)
-    scm.properties(path, identifier)
-  end
-
-  def cat(path, identifier=nil)
-    scm.cat(path, identifier)
-  end
-
-  def diff(path, rev, rev_to)
-    scm.diff(path, rev, rev_to)
-  end
-
-  def diff_format_revisions(cs, cs_to, sep=':')
-    text = ""
-    text << cs_to.format_identifier + sep if cs_to
-    text << cs.format_identifier if cs
-    text
-  end
-
-  # Returns a path relative to the url of the repository
-  def relative_path(path)
-    path
-  end
-
-  # Finds and returns a revision with a number or the beginning of a hash
-  def find_changeset_by_name(name)
-    return nil if name.blank?
-    changesets.find(:first, :conditions => (name.match(/^\d*$/) ?
-          ["revision = ?", name.to_s] : ["revision LIKE ?", name + '%']))
-  end
-
-  def latest_changeset
-    @latest_changeset ||= changesets.find(:first)
-  end
-
-  # Returns the latest changesets for +path+
-  # Default behaviour is to search in cached changesets
-  def latest_changesets(path, rev, limit=10)
-    if path.blank?
-      changesets.find(
-         :all,
-         :include => :user,
-         :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC",
-         :limit => limit)
-    else
-      changes.find(
-         :all,
-         :include => {:changeset => :user},
-         :conditions => ["path = ?", path.with_leading_slash],
-         :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC",
-         :limit => limit
-       ).collect(&:changeset)
-    end
-  end
-
-  def scan_changesets_for_issue_ids
-    self.changesets.each(&:scan_comment_for_issue_ids)
-  end
-
-  # Returns an array of committers usernames and associated user_id
-  def committers
-    @committers ||= Changeset.connection.select_rows(
-         "SELECT DISTINCT committer, user_id FROM #{Changeset.table_name} WHERE repository_id = #{id}")
-  end
-
-  # Maps committers username to a user ids
-  def committer_ids=(h)
-    if h.is_a?(Hash)
-      committers.each do |committer, user_id|
-        new_user_id = h[committer]
-        if new_user_id && (new_user_id.to_i != user_id.to_i)
-          new_user_id = (new_user_id.to_i > 0 ? new_user_id.to_i : nil)
-          Changeset.update_all(
-               "user_id = #{ new_user_id.nil? ? 'NULL' : new_user_id }",
-               ["repository_id = ? AND committer = ?", id, committer])
-        end
-      end
-      @committers            = nil
-      @found_committer_users = nil
-      true
-    else
-      false
-    end
-  end
-
-  # Returns the Redmine User corresponding to the given +committer+
-  # It will return nil if the committer is not yet mapped and if no User
-  # with the same username or email was found
-  def find_committer_user(committer)
-    unless committer.blank?
-      @found_committer_users ||= {}
-      return @found_committer_users[committer] if @found_committer_users.has_key?(committer)
-
-      user = nil
-      c = changesets.find(:first, :conditions => {:committer => committer}, :include => :user)
-      if c && c.user
-        user = c.user
-      elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/
-        username, email = $1.strip, $3
-        u = User.find_by_login(username)
-        u ||= User.find_by_mail(email) unless email.blank?
-        user = u
-      end
-      @found_committer_users[committer] = user
-      user
-    end
-  end
-
-  def repo_log_encoding
-    encoding = log_encoding.to_s.strip
-    encoding.blank? ? 'UTF-8' : encoding
-  end
-
-  # Fetches new changesets for all repositories of active projects
-  # Can be called periodically by an external script
-  # eg. ruby script/runner "Repository.fetch_changesets"
-  def self.fetch_changesets
-    Project.active.has_module(:repository).find(:all, :include => :repository).each do |project|
-      if project.repository
-        begin
-          project.repository.fetch_changesets
-        rescue Redmine::Scm::Adapters::CommandFailed => e
-          logger.error "scm: error during fetching changesets: #{e.message}"
-        end
-      end
-    end
-  end
-
-  # scan changeset comments to find related and fixed issues for all repositories
-  def self.scan_changesets_for_issue_ids
-    find(:all).each(&:scan_changesets_for_issue_ids)
-  end
-
-  def self.scm_name
-    'Abstract'
-  end
-
-  def self.available_scm
-    subclasses.collect {|klass| [klass.scm_name, klass.name]}
-  end
-
-  def self.factory(klass_name, *args)
-    klass = "Repository::#{klass_name}".constantize
-    klass.new(*args)
-  rescue
-    nil
-  end
-
-  def self.scm_adapter_class
-    nil
-  end
-
-  def self.scm_command
-    ret = ""
-    begin
-      ret = self.scm_adapter_class.client_command if self.scm_adapter_class
-    rescue Exception => e
-      logger.error "scm: error during get command: #{e.message}"
-    end
-    ret
-  end
-
-  def self.scm_version_string
-    ret = ""
-    begin
-      ret = self.scm_adapter_class.client_version_string if self.scm_adapter_class
-    rescue Exception => e
-      logger.error "scm: error during get version string: #{e.message}"
-    end
-    ret
-  end
-
-  def self.scm_available
-    ret = false
-    begin
-      ret = self.scm_adapter_class.client_available if self.scm_adapter_class
-    rescue Exception => e
-      logger.error "scm: error during get scm available: #{e.message}"
-    end
-    ret
-  end
-
-  private
-
-  def clear_changesets
-    cs, ch, ci = Changeset.table_name, Change.table_name, "#{table_name_prefix}changesets_issues#{table_name_suffix}"
-    connection.delete("DELETE FROM #{ch} WHERE #{ch}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
-    connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
-    connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}")
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0b/0bc8b19a332c3f8ffc74fbaa182a97b748ff7feb.svn-base
--- /dev/null
+++ b/.svn/pristine/0b/0bc8b19a332c3f8ffc74fbaa182a97b748ff7feb.svn-base
@@ -0,0 +1,165 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WatcherTest < ActiveSupport::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules,
+           :issues, :issue_statuses, :enumerations, :trackers, :projects_trackers,
+           :boards, :messages,
+           :wikis, :wiki_pages,
+           :watchers
+
+  def setup
+    @user = User.find(1)
+    @issue = Issue.find(1)
+  end
+
+  def test_validate
+    user = User.find(5)
+    assert !user.active?
+    watcher = Watcher.new(:user_id => user.id)
+    assert !watcher.save
+  end
+
+  def test_watch
+    assert @issue.add_watcher(@user)
+    @issue.reload
+    assert @issue.watchers.detect { |w| w.user == @user }
+  end
+
+  def test_cant_watch_twice
+    assert @issue.add_watcher(@user)
+    assert !@issue.add_watcher(@user)
+  end
+
+  def test_watched_by
+    assert @issue.add_watcher(@user)
+    @issue.reload
+    assert @issue.watched_by?(@user)
+    assert Issue.watched_by(@user).include?(@issue)
+  end
+
+  def test_watcher_users
+    watcher_users = Issue.find(2).watcher_users
+    assert_kind_of Array, watcher_users
+    assert_kind_of User, watcher_users.first
+  end
+
+  def test_watcher_users_should_not_validate_user
+    User.update_all("firstname = ''", "id=1")
+    @user.reload
+    assert !@user.valid?
+
+    issue = Issue.new(:project => Project.find(1), :tracker_id => 1, :subject => "test", :author => User.find(2))
+    issue.watcher_users << @user
+    issue.save!
+    assert issue.watched_by?(@user)
+  end
+
+  def test_watcher_user_ids
+    assert_equal [1, 3], Issue.find(2).watcher_user_ids.sort
+  end
+
+  def test_watcher_user_ids=
+    issue = Issue.new
+    issue.watcher_user_ids = ['1', '3']
+    assert issue.watched_by?(User.find(1))
+  end
+
+  def test_watcher_user_ids_should_make_ids_uniq
+    issue = Issue.new(:project => Project.find(1), :tracker_id => 1, :subject => "test", :author => User.find(2))
+    issue.watcher_user_ids = ['1', '3', '1']
+    issue.save!
+    assert_equal 2, issue.watchers.count
+  end
+
+  def test_addable_watcher_users
+    addable_watcher_users = @issue.addable_watcher_users
+    assert_kind_of Array, addable_watcher_users
+    assert_kind_of User, addable_watcher_users.first
+  end
+
+  def test_addable_watcher_users_should_not_include_user_that_cannot_view_the_object
+    issue = Issue.new(:project => Project.find(1), :is_private => true)
+    assert_nil issue.addable_watcher_users.detect {|user| !issue.visible?(user)}
+  end
+
+  def test_recipients
+    @issue.watchers.delete_all
+    @issue.reload
+
+    assert @issue.watcher_recipients.empty?
+    assert @issue.add_watcher(@user)
+
+    @user.mail_notification = 'all'
+    @user.save!
+    @issue.reload
+    assert @issue.watcher_recipients.include?(@user.mail)
+
+    @user.mail_notification = 'none'
+    @user.save!
+    @issue.reload
+    assert !@issue.watcher_recipients.include?(@user.mail)
+  end
+
+  def test_unwatch
+    assert @issue.add_watcher(@user)
+    @issue.reload
+    assert_equal 1, @issue.remove_watcher(@user)
+  end
+
+  def test_prune
+    Watcher.delete_all("user_id = 9")
+    user = User.find(9)
+
+    # public
+    Watcher.create!(:watchable => Issue.find(1), :user => user)
+    Watcher.create!(:watchable => Issue.find(2), :user => user)
+    Watcher.create!(:watchable => Message.find(1), :user => user)
+    Watcher.create!(:watchable => Wiki.find(1), :user => user)
+    Watcher.create!(:watchable => WikiPage.find(2), :user => user)
+
+    # private project (id: 2)
+    Member.create!(:project => Project.find(2), :principal => user, :role_ids => [1])
+    Watcher.create!(:watchable => Issue.find(4), :user => user)
+    Watcher.create!(:watchable => Message.find(7), :user => user)
+    Watcher.create!(:watchable => Wiki.find(2), :user => user)
+    Watcher.create!(:watchable => WikiPage.find(3), :user => user)
+
+    assert_no_difference 'Watcher.count' do
+      Watcher.prune(:user => User.find(9))
+    end
+
+    Member.delete_all
+
+    assert_difference 'Watcher.count', -4 do
+      Watcher.prune(:user => User.find(9))
+    end
+
+    assert Issue.find(1).watched_by?(user)
+    assert !Issue.find(4).watched_by?(user)
+  end
+
+  def test_prune_all
+    user = User.find(9)
+    Watcher.new(:watchable => Issue.find(4), :user => User.find(9)).save(:validate => false)
+
+    assert Watcher.prune > 0
+    assert !Issue.find(4).watched_by?(user)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0b/0beba908a316302bd0ca691f7555fdce76127696.svn-base
--- a/.svn/pristine/0b/0beba908a316302bd0ca691f7555fdce76127696.svn-base
+++ /dev/null
@@ -1,129 +0,0 @@
---- 
-wiki_contents_001: 
-  text: |-
-    h1. CookBook documentation
-
-    {{child_pages}}
-
-    Some updated [[documentation]] here with gzipped history
-  updated_on: 2007-03-07 00:10:51 +01:00
-  page_id: 1
-  id: 1
-  version: 3
-  author_id: 1
-  comments: Gzip compression activated
-wiki_contents_002: 
-  text: |-
-    h1. Another page
-    
-    This is a link to a ticket: #2
-    And this is an included page:
-    {{include(Page with an inline image)}}
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 2
-  id: 2
-  version: 1
-  author_id: 1
-  comments: 
-wiki_contents_003: 
-  text: |-
-    h1. Start page
-    
-    E-commerce web site start page
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 3
-  id: 3
-  version: 1
-  author_id: 1
-  comments: 
-wiki_contents_004: 
-  text: |-
-    h1. Page with an inline image
-    
-    This is an inline image:
-    
-    !logo.gif!
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 4
-  id: 4
-  version: 1
-  author_id: 1
-  comments: 
-wiki_contents_005: 
-  text: |-
-    h1. Child page 1
-    
-    This is a child page
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 5
-  id: 5
-  version: 1
-  author_id: 1
-  comments: 
-wiki_contents_006: 
-  text: |-
-    h1. Child page 2
-    
-    This is a child page
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 6
-  id: 6
-  version: 1
-  author_id: 1
-  comments: 
-wiki_contents_007: 
-  text: This is a child page
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 7
-  id: 7
-  version: 1
-  author_id: 1
-  comments: 
-wiki_contents_008: 
-  text: This is a parent page
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 8
-  id: 8
-  version: 1
-  author_id: 1
-  comments: 
-wiki_contents_009: 
-  text: This is a child page
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 9
-  id: 9
-  version: 1
-  author_id: 1
-  comments: 
-wiki_contents_010: 
-  text: Page with cyrillic title
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 10
-  id: 10
-  version: 1
-  author_id: 1
-  comments: 
-wiki_contents_011: 
-  text: |-
-    h1. Title
-    
-    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
-    
-    h2. Heading 1
-    
-    @WHATEVER@
-    
-    Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in.
-
-    Cras ipsum felis, ultrices at porttitor vel, faucibus eu nunc.
-    
-    h2. Heading 2
-
-    Morbi facilisis accumsan orci non pharetra.
-  updated_on: 2007-03-08 00:18:07 +01:00
-  page_id: 11
-  id: 11
-  version: 3
-  author_id: 1
-  comments: 
-  
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0b/0bfbd6508bed6a33543df0df9a316455bb2e521a.svn-base
--- a/.svn/pristine/0b/0bfbd6508bed6a33543df0df9a316455bb2e521a.svn-base
+++ /dev/null
@@ -1,24 +0,0 @@
-<h2><%=h @attachment.filename %></h2>
-
-<div class="attachments">
-<p><%= h("#{@attachment.description} - ") unless @attachment.description.blank? %>
-   <span class="author"><%= link_to_user(@attachment.author) %>, <%= format_time(@attachment.created_on) %></span></p>
-<p><%= link_to_attachment @attachment, :text => l(:button_download), :download => true -%>
-   <span class="size">(<%= number_to_human_size @attachment.filesize %>)</span></p>
-</div>
-<p>
-<% form_tag({}, :method => 'get') do %>
-    <label><%= l(:label_view_diff) %></label>
-    <%= select_tag 'type',
-                    options_for_select(
-                      [[l(:label_diff_inline), "inline"], [l(:label_diff_side_by_side), "sbs"]], @diff_type),
-                    :onchange => "if (this.value != '') {this.form.submit()}" %>
-<% end %>
-</p>
-<%= render :partial => 'common/diff', :locals => {:diff => @diff, :diff_type => @diff_type} %>
-
-<% html_title @attachment.filename %>
-
-<% content_for :header_tags do -%>
-    <%= stylesheet_link_tag "scm" -%>
-<% end -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0c/0c07ac7fadf7713b8982de217779de9a2084825c.svn-base
--- a/.svn/pristine/0c/0c07ac7fadf7713b8982de217779de9a2084825c.svn-base
+++ /dev/null
@@ -1,70 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Group < Principal
-  has_and_belongs_to_many :users, :after_add => :user_added,
-                                  :after_remove => :user_removed
-
-  acts_as_customizable
-
-  validates_presence_of :lastname
-  validates_uniqueness_of :lastname, :case_sensitive => false
-  validates_length_of :lastname, :maximum => 30
-
-  before_destroy :remove_references_before_destroy
-
-  def to_s
-    lastname.to_s
-  end
-
-  alias :name :to_s
-
-  def user_added(user)
-    members.each do |member|
-      next if member.project.nil?
-      user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id)
-      member.member_roles.each do |member_role|
-        user_member.member_roles << MemberRole.new(:role => member_role.role, :inherited_from => member_role.id)
-      end
-      user_member.save!
-    end
-  end
-
-  def user_removed(user)
-    members.each do |member|
-      MemberRole.find(:all, :include => :member,
-                            :conditions => ["#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids]).each(&:destroy)
-    end
-  end
-
-  def self.human_attribute_name(attribute_key_name)
-    attr_name = attribute_key_name
-    if attr_name == 'lastname'
-      attr_name = "name"
-    end
-    super(attr_name)
-  end
-
-  private
-
-  # Removes references that are not handled by associations
-  def remove_references_before_destroy
-    return if self.id.nil?
-
-    Issue.update_all 'assigned_to_id = NULL', ['assigned_to_id = ?', id]
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0c/0c1341a53592418e4a2dd8783234ed2bf47a5fde.svn-base
--- /dev/null
+++ b/.svn/pristine/0c/0c1341a53592418e4a2dd8783234ed2bf47a5fde.svn-base
@@ -0,0 +1,1 @@
+$('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_members(@project)) %>');
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0c/0c3d44b905a542240e7c616a63f74580e8cbbb9d.svn-base
--- a/.svn/pristine/0c/0c3d44b905a542240e7c616a63f74580e8cbbb9d.svn-base
+++ /dev/null
@@ -1,67 +0,0 @@
-<% diff = Redmine::UnifiedDiff.new(
-            diff, :type => diff_type,
-            :max_lines => Setting.diff_max_lines_displayed.to_i) -%>
-
-<% diff.each do |table_file| -%>
-<div class="autoscroll">
-<% if diff.diff_type == 'sbs' -%>
-<table class="filecontent">
-<thead>
-<tr>
-  <th colspan="4" class="filename">
-    <%= h(Redmine::CodesetUtil.to_utf8_by_setting(table_file.file_name)) %>
-  </th>
-</tr>
-</thead>
-<tbody>
-<% table_file.each_line do |spacing, line| -%>
-<% if spacing -%>
-<tr class="spacing">
-  <th class="line-num">...</th><td></td><th class="line-num">...</th><td></td>
-</tr>
-<% end -%>
-<tr>
-  <th class="line-num"><%= line.nb_line_left %></th>
-  <td class="line-code <%= line.type_diff_left %>">
-    <pre><%= Redmine::CodesetUtil.to_utf8_by_setting(line.html_line_left) %></pre>
-  </td>
-  <th class="line-num"><%= line.nb_line_right %></th>
-  <td class="line-code <%= line.type_diff_right %>">
-    <pre><%= Redmine::CodesetUtil.to_utf8_by_setting(line.html_line_right) %></pre>
-  </td>
-</tr>
-<% end -%>
-</tbody>
-</table>
-
-<% else -%>
-<table class="filecontent">
-<thead>
-  <tr>
-    <th colspan="3" class="filename">
-      <%= h(Redmine::CodesetUtil.to_utf8_by_setting(table_file.file_name)) %>
-    </th>
-  </tr>
-</thead>
-<tbody>
-<% table_file.each_line do |spacing, line| %>
-<% if spacing -%>
-<tr class="spacing">
-  <th class="line-num">...</th><th class="line-num">...</th><td></td>
-</tr>
-<% end -%>
-<tr>
-  <th class="line-num"><%= line.nb_line_left %></th>
-  <th class="line-num"><%= line.nb_line_right %></th>
-  <td class="line-code <%= line.type_diff %>">
-    <pre><%= Redmine::CodesetUtil.to_utf8_by_setting(line.html_line) %></pre>
-  </td>
-</tr>
-<% end -%>
-</tbody>
-</table>
-<% end -%>
-</div>
-<% end -%>
-
-<%= l(:text_diff_truncated) if diff.truncated? %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0c/0c683f18d0752b5b1c900f3d3bf34e0652a0c13f.svn-base
--- /dev/null
+++ b/.svn/pristine/0c/0c683f18d0752b5b1c900f3d3bf34e0652a0c13f.svn-base
@@ -0,0 +1,290 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Version < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  after_update :update_issues_from_sharing_change
+  belongs_to :project
+  has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id', :dependent => :nullify
+  acts_as_customizable
+  acts_as_attachable :view_permission => :view_files,
+                     :delete_permission => :manage_files
+
+  VERSION_STATUSES = %w(open locked closed)
+  VERSION_SHARINGS = %w(none descendants hierarchy tree system)
+
+  validates_presence_of :name
+  validates_uniqueness_of :name, :scope => [:project_id]
+  validates_length_of :name, :maximum => 60
+  validates :effective_date, :date => true
+  validates_inclusion_of :status, :in => VERSION_STATUSES
+  validates_inclusion_of :sharing, :in => VERSION_SHARINGS
+
+  scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
+  scope :open, lambda { where(:status => 'open') }
+  scope :visible, lambda {|*args|
+    includes(:project).where(Project.allowed_to_condition(args.first || User.current, :view_issues))
+  }
+
+  safe_attributes 'name', 
+    'description',
+    'effective_date',
+    'due_date',
+    'wiki_page_title',
+    'status',
+    'sharing',
+    'custom_field_values',
+    'custom_fields'
+
+  # Returns true if +user+ or current user is allowed to view the version
+  def visible?(user=User.current)
+    user.allowed_to?(:view_issues, self.project)
+  end
+
+  # Version files have same visibility as project files
+  def attachments_visible?(*args)
+    project.present? && project.attachments_visible?(*args)
+  end
+
+  def start_date
+    @start_date ||= fixed_issues.minimum('start_date')
+  end
+
+  def due_date
+    effective_date
+  end
+
+  def due_date=(arg)
+    self.effective_date=(arg)
+  end
+
+  # Returns the total estimated time for this version
+  # (sum of leaves estimated_hours)
+  def estimated_hours
+    @estimated_hours ||= fixed_issues.leaves.sum(:estimated_hours).to_f
+  end
+
+  # Returns the total reported time for this version
+  def spent_hours
+    @spent_hours ||= TimeEntry.joins(:issue).where("#{Issue.table_name}.fixed_version_id = ?", id).sum(:hours).to_f
+  end
+
+  def closed?
+    status == 'closed'
+  end
+
+  def open?
+    status == 'open'
+  end
+
+  # Returns true if the version is completed: due date reached and no open issues
+  def completed?
+    effective_date && (effective_date < Date.today) && (open_issues_count == 0)
+  end
+
+  def behind_schedule?
+    if completed_percent == 100
+      return false
+    elsif due_date && start_date
+      done_date = start_date + ((due_date - start_date+1)* completed_percent/100).floor
+      return done_date <= Date.today
+    else
+      false # No issues so it's not late
+    end
+  end
+
+  # Returns the completion percentage of this version based on the amount of open/closed issues
+  # and the time spent on the open issues.
+  def completed_percent
+    if issues_count == 0
+      0
+    elsif open_issues_count == 0
+      100
+    else
+      issues_progress(false) + issues_progress(true)
+    end
+  end
+
+  # TODO: remove in Redmine 3.0
+  def completed_pourcent
+    ActiveSupport::Deprecation.warn "Version#completed_pourcent is deprecated and will be removed in Redmine 3.0. Please use #completed_percent instead."
+    completed_percent
+  end
+
+  # Returns the percentage of issues that have been marked as 'closed'.
+  def closed_percent
+    if issues_count == 0
+      0
+    else
+      issues_progress(false)
+    end
+  end
+
+  # TODO: remove in Redmine 3.0
+  def closed_pourcent
+    ActiveSupport::Deprecation.warn "Version#closed_pourcent is deprecated and will be removed in Redmine 3.0. Please use #closed_percent instead."
+    closed_percent
+  end
+
+  # Returns true if the version is overdue: due date reached and some open issues
+  def overdue?
+    effective_date && (effective_date < Date.today) && (open_issues_count > 0)
+  end
+
+  # Returns assigned issues count
+  def issues_count
+    load_issue_counts
+    @issue_count
+  end
+
+  # Returns the total amount of open issues for this version.
+  def open_issues_count
+    load_issue_counts
+    @open_issues_count
+  end
+
+  # Returns the total amount of closed issues for this version.
+  def closed_issues_count
+    load_issue_counts
+    @closed_issues_count
+  end
+
+  def wiki_page
+    if project.wiki && !wiki_page_title.blank?
+      @wiki_page ||= project.wiki.find_page(wiki_page_title)
+    end
+    @wiki_page
+  end
+
+  def to_s; name end
+
+  def to_s_with_project
+    "#{project} - #{name}"
+  end
+
+  # Versions are sorted by effective_date and name
+  # Those with no effective_date are at the end, sorted by name
+  def <=>(version)
+    if self.effective_date
+      if version.effective_date
+        if self.effective_date == version.effective_date
+          name == version.name ? id <=> version.id : name <=> version.name
+        else
+          self.effective_date <=> version.effective_date
+        end
+      else
+        -1
+      end
+    else
+      if version.effective_date
+        1
+      else
+        name == version.name ? id <=> version.id : name <=> version.name
+      end
+    end
+  end
+
+  def self.fields_for_order_statement(table=nil)
+    table ||= table_name
+    ["(CASE WHEN #{table}.effective_date IS NULL THEN 1 ELSE 0 END)", "#{table}.effective_date", "#{table}.name", "#{table}.id"]
+  end
+
+  scope :sorted, order(fields_for_order_statement)
+
+  # Returns the sharings that +user+ can set the version to
+  def allowed_sharings(user = User.current)
+    VERSION_SHARINGS.select do |s|
+      if sharing == s
+        true
+      else
+        case s
+        when 'system'
+          # Only admin users can set a systemwide sharing
+          user.admin?
+        when 'hierarchy', 'tree'
+          # Only users allowed to manage versions of the root project can
+          # set sharing to hierarchy or tree
+          project.nil? || user.allowed_to?(:manage_versions, project.root)
+        else
+          true
+        end
+      end
+    end
+  end
+
+  private
+
+  def load_issue_counts
+    unless @issue_count
+      @open_issues_count = 0
+      @closed_issues_count = 0
+      fixed_issues.count(:all, :group => :status).each do |status, count|
+        if status.is_closed?
+          @closed_issues_count += count
+        else
+          @open_issues_count += count
+        end
+      end
+      @issue_count = @open_issues_count + @closed_issues_count
+    end
+  end
+
+  # Update the issue's fixed versions. Used if a version's sharing changes.
+  def update_issues_from_sharing_change
+    if sharing_changed?
+      if VERSION_SHARINGS.index(sharing_was).nil? ||
+          VERSION_SHARINGS.index(sharing).nil? ||
+          VERSION_SHARINGS.index(sharing_was) > VERSION_SHARINGS.index(sharing)
+        Issue.update_versions_from_sharing_change self
+      end
+    end
+  end
+
+  # Returns the average estimated time of assigned issues
+  # or 1 if no issue has an estimated time
+  # Used to weigth unestimated issues in progress calculation
+  def estimated_average
+    if @estimated_average.nil?
+      average = fixed_issues.average(:estimated_hours).to_f
+      if average == 0
+        average = 1
+      end
+      @estimated_average = average
+    end
+    @estimated_average
+  end
+
+  # Returns the total progress of open or closed issues.  The returned percentage takes into account
+  # the amount of estimated time set for this version.
+  #
+  # Examples:
+  # issues_progress(true)   => returns the progress percentage for open issues.
+  # issues_progress(false)  => returns the progress percentage for closed issues.
+  def issues_progress(open)
+    @issues_progress ||= {}
+    @issues_progress[open] ||= begin
+      progress = 0
+      if issues_count > 0
+        ratio = open ? 'done_ratio' : 100
+
+        done = fixed_issues.open(open).sum("COALESCE(estimated_hours, #{estimated_average}) * #{ratio}").to_f
+        progress = done / (estimated_average * issues_count)
+      end
+      progress
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0c/0ca7bda81025c5f7a9ebad14d8b0c08f3a0b8176.svn-base
--- /dev/null
+++ b/.svn/pristine/0c/0ca7bda81025c5f7a9ebad14d8b0c08f3a0b8176.svn-base
@@ -0,0 +1,35 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingSysTest < ActionController::IntegrationTest
+  def test_sys
+    assert_routing(
+        { :method => 'get', :path => "/sys/projects" },
+        { :controller => 'sys', :action => 'projects' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/sys/projects/testid/repository" },
+        { :controller => 'sys', :action => 'create_project_repository', :id => 'testid' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/sys/fetch_changesets" },
+        { :controller => 'sys', :action => 'fetch_changesets' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0c/0cc9601ec1a6e3a27ab4a946d394cf4ba82254b4.svn-base
--- /dev/null
+++ b/.svn/pristine/0c/0cc9601ec1a6e3a27ab4a946d394cf4ba82254b4.svn-base
@@ -0,0 +1,22 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class TimeEntryActivityCustomField < CustomField
+  def type_name
+    :enumeration_activities
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0c/0cd8ee527e2f2ff13b3817238dc6eed2ab240c57.svn-base
--- a/.svn/pristine/0c/0cd8ee527e2f2ff13b3817238dc6eed2ab240c57.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-class <%= class_name %>Controller < ApplicationController
-  unloadable
-
-<% actions.each do |action| -%>
-
-  def <%= action %>
-  end
-<% end -%>
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0d/0d106c8ee2a99b8daf9a6d87887284bdd099fa19.svn-base
--- a/.svn/pristine/0d/0d106c8ee2a99b8daf9a6d87887284bdd099fa19.svn-base
+++ /dev/null
@@ -1,58 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class SettingTest < ActiveSupport::TestCase
-
-  def test_read_default
-    assert_equal "Redmine", Setting.app_title
-    assert Setting.self_registration?
-    assert !Setting.login_required?
-  end
-
-  def test_update
-    Setting.app_title = "My title"
-    assert_equal "My title", Setting.app_title
-    # make sure db has been updated (INSERT)
-    assert_equal "My title", Setting.find_by_name('app_title').value
-
-    Setting.app_title = "My other title"
-    assert_equal "My other title", Setting.app_title
-    # make sure db has been updated (UPDATE)
-    assert_equal "My other title", Setting.find_by_name('app_title').value
-  end
-
-  def test_serialized_setting
-    Setting.notified_events = ['issue_added', 'issue_updated', 'news_added']
-    assert_equal ['issue_added', 'issue_updated', 'news_added'], Setting.notified_events
-    assert_equal ['issue_added', 'issue_updated', 'news_added'], Setting.find_by_name('notified_events').value
-  end
-  
-  def test_setting_should_be_reloaded_after_clear_cache
-    Setting.app_title = "My title"
-    assert_equal "My title", Setting.app_title
-    
-    s = Setting.find_by_name("app_title")
-    s.value = 'New title'
-    s.save!
-    assert_equal "My title", Setting.app_title
-    
-    Setting.clear_cache
-    assert_equal "New title", Setting.app_title
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0d/0d50a39088b6bd107e54b315b0bf77a7ffa63596.svn-base
--- /dev/null
+++ b/.svn/pristine/0d/0d50a39088b6bd107e54b315b0bf77a7ffa63596.svn-base
@@ -0,0 +1,110 @@
+### From http://svn.geekdaily.org/public/rails/plugins/generally_useful/tasks/coverage_via_rcov.rake
+
+namespace :test do
+  desc 'Measures test coverage'
+  task :coverage do
+    rm_f "coverage"
+    rm_f "coverage.data"
+    rcov = "rcov --rails --aggregate coverage.data --text-summary -Ilib --html --exclude gems/"
+    files = %w(unit functional integration).map {|dir| Dir.glob("test/#{dir}/**/*_test.rb")}.flatten.join(" ")
+    system("#{rcov} #{files}")
+  end
+
+  desc 'Run unit and functional scm tests'
+  task :scm do
+    errors = %w(test:scm:units test:scm:functionals).collect do |task|
+      begin
+        Rake::Task[task].invoke
+        nil
+      rescue => e
+        task
+      end
+    end.compact
+    abort "Errors running #{errors.to_sentence(:locale => :en)}!" if errors.any?
+  end
+
+  namespace :scm do
+    namespace :setup do
+      desc "Creates directory for test repositories"
+      task :create_dir do
+        FileUtils.mkdir_p Rails.root + '/tmp/test'
+      end
+
+      supported_scms = [:subversion, :cvs, :bazaar, :mercurial, :git, :darcs, :filesystem]
+
+      desc "Creates a test subversion repository"
+      task :subversion => :create_dir do
+        repo_path = "tmp/test/subversion_repository"
+        unless File.exists?(repo_path)
+          system "svnadmin create #{repo_path}"
+          system "gunzip < test/fixtures/repositories/subversion_repository.dump.gz | svnadmin load #{repo_path}"
+        end
+      end
+
+      desc "Creates a test mercurial repository"
+      task :mercurial => :create_dir do
+        repo_path = "tmp/test/mercurial_repository"
+        unless File.exists?(repo_path)
+          bundle_path = "test/fixtures/repositories/mercurial_repository.hg"
+          system "hg init #{repo_path}"
+          system "hg -R #{repo_path} pull #{bundle_path}"
+        end
+      end
+
+      (supported_scms - [:subversion, :mercurial]).each do |scm|
+        desc "Creates a test #{scm} repository"
+        task scm => :create_dir do
+          unless File.exists?("tmp/test/#{scm}_repository")
+            # system "gunzip < test/fixtures/repositories/#{scm}_repository.tar.gz | tar -xv -C tmp/test"
+            system "tar -xvz -C tmp/test -f test/fixtures/repositories/#{scm}_repository.tar.gz"
+          end
+        end
+      end
+
+      desc "Creates all test repositories"
+      task :all => supported_scms
+    end
+
+    desc "Updates installed test repositories"
+    task :update do
+      require 'fileutils'
+      Dir.glob("tmp/test/*_repository").each do |dir|
+        next unless File.basename(dir) =~ %r{^(.+)_repository$} && File.directory?(dir)
+        scm = $1
+        next unless fixture = Dir.glob("test/fixtures/repositories/#{scm}_repository.*").first
+        next if File.stat(dir).ctime > File.stat(fixture).mtime
+
+        FileUtils.rm_rf dir
+        Rake::Task["test:scm:setup:#{scm}"].execute
+      end
+    end
+
+    Rake::TestTask.new(:units => "db:test:prepare") do |t|
+      t.libs << "test"
+      t.verbose = true
+      t.test_files = FileList['test/unit/repository*_test.rb'] + FileList['test/unit/lib/redmine/scm/**/*_test.rb']
+    end
+    Rake::Task['test:scm:units'].comment = "Run the scm unit tests"
+
+    Rake::TestTask.new(:functionals => "db:test:prepare") do |t|
+      t.libs << "test"
+      t.verbose = true
+      t.test_files = FileList['test/functional/repositories*_test.rb']
+    end
+    Rake::Task['test:scm:functionals'].comment = "Run the scm functional tests"
+  end
+
+  Rake::TestTask.new(:rdm_routing) do |t|
+    t.libs << "test"
+    t.verbose = true
+    t.test_files = FileList['test/integration/routing/*_test.rb']
+  end
+  Rake::Task['test:rdm_routing'].comment = "Run the routing tests"
+
+  Rake::TestTask.new(:ui => "db:test:prepare") do |t|
+    t.libs << "test"
+    t.verbose = true
+    t.test_files = FileList['test/ui/**/*_test.rb']
+  end
+  Rake::Task['test:ui'].comment = "Run the UI tests with Capybara (PhantomJS listening on port 4444 is required)"
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0d/0d581e597497e894acf26342b5cf129e84f325db.svn-base
--- a/.svn/pristine/0d/0d581e597497e894acf26342b5cf129e84f325db.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-module Redmine
-  module Info
-    class << self
-      def app_name; 'Redmine' end
-      def url; 'http://www.redmine.org/' end
-      def help_url; 'http://www.redmine.org/guide' end
-      def versioned_name; "#{app_name} #{Redmine::VERSION}" end
-
-      # Creates the url string to a specific Redmine issue
-      def issue(issue_id)
-        url + 'issues/' + issue_id.to_s
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0d/0d6663388ad2e1df81d9f7719fa0c144a5b76d99.svn-base
--- a/.svn/pristine/0d/0d6663388ad2e1df81d9f7719fa0c144a5b76d99.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/runner'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0d/0da01fc24e804fb2e15e93cbb542b0add78e1cbc.svn-base
--- a/.svn/pristine/0d/0da01fc24e804fb2e15e93cbb542b0add78e1cbc.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-<%= "#{issue.tracker.name} ##{issue.id}: #{issue.subject}" %>
-<%= issue_url %>
-
-<%=l(:field_author)%>: <%= issue.author %>
-<%=l(:field_status)%>: <%= issue.status %>
-<%=l(:field_priority)%>: <%= issue.priority %>
-<%=l(:field_assigned_to)%>: <%= issue.assigned_to %>
-<%=l(:field_category)%>: <%= issue.category %>
-<%=l(:field_fixed_version)%>: <%= issue.fixed_version %>
-<% issue.custom_field_values.each do |c| %><%= c.custom_field.name %>: <%= show_value(c) %>
-<% end %>
-
-<%= issue.description %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0d/0dc6f2999aebfb473b433b9a22bddd8917c60616.svn-base
--- a/.svn/pristine/0d/0dc6f2999aebfb473b433b9a22bddd8917c60616.svn-base
+++ /dev/null
@@ -1,39 +0,0 @@
-# $Id: ldif.rb 78 2006-04-26 02:57:34Z blackhedd $
-#
-# Net::LDIF for Ruby
-#
-#
-#
-# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
-#
-# Gmail: garbagecat10
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#
-
-# THIS FILE IS A STUB.
-
-module Net
-
-  class LDIF
-
-
-  end # class LDIF
-
-
-end # module Net
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0d/0de0220c6abf526fd90b0775dd5b7d3c897e479b.svn-base
--- /dev/null
+++ b/.svn/pristine/0d/0de0220c6abf526fd90b0775dd5b7d3c897e479b.svn-base
@@ -0,0 +1,10 @@
+class AddTrackerPosition < ActiveRecord::Migration
+  def self.up
+    add_column :trackers, :position, :integer, :default => 1
+    Tracker.all.each_with_index {|tracker, i| tracker.update_attribute(:position, i+1)}
+  end
+
+  def self.down
+    remove_column :trackers, :position
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0e/0e9c8f11b3db41702079f085c94dfa01133abcd9.svn-base
--- /dev/null
+++ b/.svn/pristine/0e/0e9c8f11b3db41702079f085c94dfa01133abcd9.svn-base
@@ -0,0 +1,128 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../test_helper', __FILE__)
+
+class PdfTest < ActiveSupport::TestCase
+  fixtures :users, :projects, :roles, :members, :member_roles,
+           :enabled_modules, :issues, :trackers, :attachments
+
+  def test_fix_text_encoding_nil
+    assert_equal '', Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(nil, "UTF-8")
+    assert_equal '', Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(nil, "ISO-8859-1")
+  end
+
+  def test_rdm_pdf_iconv_cannot_convert_ja_cp932
+    encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" )
+    utf8_txt_1  = "\xe7\x8b\x80\xe6\x85\x8b"
+    utf8_txt_2  = "\xe7\x8b\x80\xe6\x85\x8b\xe7\x8b\x80"
+    utf8_txt_3  = "\xe7\x8b\x80\xe7\x8b\x80\xe6\x85\x8b\xe7\x8b\x80"
+    if utf8_txt_1.respond_to?(:force_encoding)
+      txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding)
+      txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding)
+      txt_3 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding)
+      assert_equal "?\x91\xd4".force_encoding("ASCII-8BIT"), txt_1
+      assert_equal "?\x91\xd4?".force_encoding("ASCII-8BIT"), txt_2
+      assert_equal "??\x91\xd4?".force_encoding("ASCII-8BIT"), txt_3
+      assert_equal "ASCII-8BIT", txt_1.encoding.to_s
+      assert_equal "ASCII-8BIT", txt_2.encoding.to_s
+      assert_equal "ASCII-8BIT", txt_3.encoding.to_s
+    elsif RUBY_PLATFORM == 'java'
+      assert_equal "??",
+                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding)
+      assert_equal "???",
+                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding)
+      assert_equal "????",
+                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding)
+    else
+      assert_equal "???\x91\xd4",
+                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding)
+      assert_equal "???\x91\xd4???",
+                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding)
+      assert_equal "??????\x91\xd4???",
+                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding)
+    end
+  end
+
+  def test_rdm_pdf_iconv_invalid_utf8_should_be_replaced_en
+    str1 = "Texte encod\xe9 en ISO-8859-1"
+    str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test"
+    str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding)
+    str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding)
+    txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str1, 'UTF-8')
+    txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str2, 'UTF-8')
+    if txt_1.respond_to?(:force_encoding)
+      assert_equal "ASCII-8BIT", txt_1.encoding.to_s
+      assert_equal "ASCII-8BIT", txt_2.encoding.to_s
+    end
+    assert_equal "Texte encod? en ISO-8859-1", txt_1
+    assert_equal "?a?b?c?d?e test", txt_2
+  end
+
+  def test_rdm_pdf_iconv_invalid_utf8_should_be_replaced_ja
+    str1 = "Texte encod\xe9 en ISO-8859-1"
+    str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test"
+    str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding)
+    str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding)
+    encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" )
+    txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str1, encoding)
+    txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str2, encoding)
+    if txt_1.respond_to?(:force_encoding)
+      assert_equal "ASCII-8BIT", txt_1.encoding.to_s
+      assert_equal "ASCII-8BIT", txt_2.encoding.to_s
+    end
+    assert_equal "Texte encod? en ISO-8859-1", txt_1
+    assert_equal "?a?b?c?d?e test", txt_2
+  end
+
+  def test_attach
+    set_fixtures_attachments_directory
+
+    str2 = "\x83e\x83X\x83g"
+    str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding)
+    encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" )
+
+    a1 = Attachment.find(17)
+    a2 = Attachment.find(19)
+
+    User.current = User.find(1)
+    assert a1.readable?
+    assert a1.visible?
+    assert a2.readable?
+    assert a2.visible?
+
+    aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8")
+    assert_not_nil aa1
+    assert_equal 17, aa1.id
+    aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding)
+    assert_not_nil aa2
+    assert_equal 19, aa2.id
+
+    User.current = nil
+    assert a1.readable?
+    assert (! a1.visible?)
+    assert a2.readable?
+    assert (! a2.visible?)
+
+    aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8")
+    assert_equal nil, aa1
+    aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding)
+    assert_equal nil, aa2
+
+    set_tmp_attachments_directory
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0e/0e9e1072226f562ac691c9b0e43850580a4d42a6.svn-base
--- a/.svn/pristine/0e/0e9e1072226f562ac691c9b0e43850580a4d42a6.svn-base
+++ /dev/null
@@ -1,26 +0,0 @@
-<h2><%= l(:label_spent_time) %></h2>
-
-<% labelled_tabular_form_for(:time_entry, @time_entry, :url => {
-                               :action => (@time_entry.new_record? ? 'create' : 'update'),
-                               :id => @time_entry,
-                               :project_id => @time_entry.project
-                             },
-                             :html => {:method => @time_entry.new_record? ? :post : :put}) do |f| %>
-<%= error_messages_for 'time_entry' %>
-<%= back_url_hidden_field_tag %>
-
-<div class="box">
-<p><%= f.text_field :issue_id, :size => 6 %> <em><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></em></p>
-<p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
-<p><%= f.text_field :hours, :size => 6, :required => true %></p>
-<p><%= f.text_field :comments, :size => 100 %></p>
-<p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
-<% @time_entry.custom_field_values.each do |value| %>
-  <p><%= custom_field_tag_with_label :time_entry, value %></p>
-<% end %>
-<%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
-</div>
-
-<%= submit_tag l(:button_save) %>
-
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0e/0eb716c2e3251d0a363271012989e30efeb34f17.svn-base
--- /dev/null
+++ b/.svn/pristine/0e/0eb716c2e3251d0a363271012989e30efeb34f17.svn-base
@@ -0,0 +1,3 @@
+<%= form_tag(signout_path) do %>
+  <p><%= submit_tag l(:label_logout) %></p>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0e/0ee15adcf36536c48b6695748041d2c5e43cb26a.svn-base
--- a/.svn/pristine/0e/0ee15adcf36536c48b6695748041d2c5e43cb26a.svn-base
+++ /dev/null
@@ -1,255 +0,0 @@
-module CodeRay
-module Scanners
-  
-  load :java
-  
-  # Scanner for Groovy.
-  class Groovy < Java
-    
-    register_for :groovy
-    
-    # TODO: check list of keywords
-    GROOVY_KEYWORDS = %w[
-      as assert def in
-    ]  # :nodoc:
-    KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[
-      case instanceof new return throw typeof while as assert in
-    ]  # :nodoc:
-    GROOVY_MAGIC_VARIABLES = %w[ it ]  # :nodoc:
-    
-    IDENT_KIND = Java::IDENT_KIND.dup.
-      add(GROOVY_KEYWORDS, :keyword).
-      add(GROOVY_MAGIC_VARIABLES, :local_variable)  # :nodoc:
-    
-    ESCAPE = / [bfnrtv$\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x  # :nodoc:
-    UNICODE_ESCAPE =  / u[a-fA-F0-9]{4} /x  # :nodoc: no 4-byte unicode chars? U[a-fA-F0-9]{8}
-    REGEXP_ESCAPE =  / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | \d | [bBdDsSwW\/] /x  # :nodoc:
-    
-    # TODO: interpretation inside ', ", /
-    STRING_CONTENT_PATTERN = {
-      "'" => /(?>\\[^\\'\n]+|[^\\'\n]+)+/,
-      '"' => /[^\\$"\n]+/,
-      "'''" => /(?>[^\\']+|'(?!''))+/,
-      '"""' => /(?>[^\\$"]+|"(?!""))+/,
-      '/' => /[^\\$\/\n]+/,
-    }  # :nodoc:
-    
-  protected
-    
-    def scan_tokens encoder, options
-      
-      state = :initial
-      inline_block_stack = []
-      inline_block_paren_depth = nil
-      string_delimiter = nil
-      import_clause = class_name_follows = last_token = after_def = false
-      value_expected = true
-      
-      until eos?
-        
-        case state
-        
-        when :initial
-          
-          if match = scan(/ \s+ | \\\n /x)
-            encoder.text_token match, :space
-            if match.index ?\n
-              import_clause = after_def = false
-              value_expected = true unless value_expected
-            end
-            next
-          
-          elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
-            value_expected = true
-            after_def = false
-            encoder.text_token match, :comment
-          
-          elsif bol? && match = scan(/ \#!.* /x)
-            encoder.text_token match, :doctype
-          
-          elsif import_clause && match = scan(/ (?!as) #{IDENT} (?: \. #{IDENT} )* (?: \.\* )? /ox)
-            after_def = value_expected = false
-            encoder.text_token match, :include
-          
-          elsif match = scan(/ #{IDENT} | \[\] /ox)
-            kind = IDENT_KIND[match]
-            value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match]
-            if last_token == '.'
-              kind = :ident
-            elsif class_name_follows
-              kind = :class
-              class_name_follows = false
-            elsif after_def && check(/\s*[({]/)
-              kind = :method
-              after_def = false
-            elsif kind == :ident && last_token != '?' && check(/:/)
-              kind = :key
-            else
-              class_name_follows = true if match == 'class' || (import_clause && match == 'as')
-              import_clause = match == 'import'
-              after_def = true if match == 'def'
-            end
-            encoder.text_token match, kind
-          
-          elsif match = scan(/;/)
-            import_clause = after_def = false
-            value_expected = true
-            encoder.text_token match, :operator
-          
-          elsif match = scan(/\{/)
-            class_name_follows = after_def = false
-            value_expected = true
-            encoder.text_token match, :operator
-            if !inline_block_stack.empty?
-              inline_block_paren_depth += 1
-            end
-          
-          # TODO: ~'...', ~"..." and ~/.../ style regexps
-          elsif match = scan(/ \.\.<? | \*?\.(?!\d)@? | \.& | \?:? | [,?:(\[] | -[->] | \+\+ |
-              && | \|\| | \*\*=? | ==?~ | <=?>? | [-+*%^~&|>=!]=? | <<<?=? | >>>?=? /x)
-            value_expected = true
-            value_expected = :regexp if match == '~'
-            after_def = false
-            encoder.text_token match, :operator
-          
-          elsif match = scan(/ [)\]}] /x)
-            value_expected = after_def = false
-            if !inline_block_stack.empty? && match == '}'
-              inline_block_paren_depth -= 1
-              if inline_block_paren_depth == 0  # closing brace of inline block reached
-                encoder.text_token match, :inline_delimiter
-                encoder.end_group :inline
-                state, string_delimiter, inline_block_paren_depth = inline_block_stack.pop
-                next
-              end
-            end
-            encoder.text_token match, :operator
-          
-          elsif check(/[\d.]/)
-            after_def = value_expected = false
-            if match = scan(/0[xX][0-9A-Fa-f]+/)
-              encoder.text_token match, :hex
-            elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/)
-              encoder.text_token match, :octal
-            elsif match = scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/)
-              encoder.text_token match, :float
-            elsif match = scan(/\d+[lLgG]?/)
-              encoder.text_token match, :integer
-            end
-            
-          elsif match = scan(/'''|"""/)
-            after_def = value_expected = false
-            state = :multiline_string
-            encoder.begin_group :string
-            string_delimiter = match
-            encoder.text_token match, :delimiter
-            
-          # TODO: record.'name' syntax
-          elsif match = scan(/["']/)
-            after_def = value_expected = false
-            state = match == '/' ? :regexp : :string
-            encoder.begin_group state
-            string_delimiter = match
-            encoder.text_token match, :delimiter
-            
-          elsif value_expected && match = scan(/\//)
-            after_def = value_expected = false
-            encoder.begin_group :regexp
-            state = :regexp
-            string_delimiter = '/'
-            encoder.text_token match, :delimiter
-            
-          elsif match = scan(/ @ #{IDENT} /ox)
-            after_def = value_expected = false
-            encoder.text_token match, :annotation
-            
-          elsif match = scan(/\//)
-            after_def = false
-            value_expected = true
-            encoder.text_token match, :operator
-            
-          else
-            encoder.text_token getch, :error
-            
-          end
-          
-        when :string, :regexp, :multiline_string
-          if match = scan(STRING_CONTENT_PATTERN[string_delimiter])
-            encoder.text_token match, :content
-            
-          elsif match = scan(state == :multiline_string ? /'''|"""/ : /["'\/]/)
-            encoder.text_token match, :delimiter
-            if state == :regexp
-              # TODO: regexp modifiers? s, m, x, i?
-              modifiers = scan(/[ix]+/)
-              encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty?
-            end
-            state = :string if state == :multiline_string
-            encoder.end_group state
-            string_delimiter = nil
-            after_def = value_expected = false
-            state = :initial
-            next
-            
-          elsif (state == :string || state == :multiline_string) &&
-              (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
-            if string_delimiter[0] == ?' && !(match == "\\\\" || match == "\\'")
-              encoder.text_token match, :content
-            else
-              encoder.text_token match, :char
-            end
-          elsif state == :regexp && match = scan(/ \\ (?: #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
-            encoder.text_token match, :char
-            
-          elsif match = scan(/ \$ #{IDENT} /mox)
-            encoder.begin_group :inline
-            encoder.text_token '$', :inline_delimiter
-            match = match[1..-1]
-            encoder.text_token match, IDENT_KIND[match]
-            encoder.end_group :inline
-            next
-          elsif match = scan(/ \$ \{ /x)
-            encoder.begin_group :inline
-            encoder.text_token match, :inline_delimiter
-            inline_block_stack << [state, string_delimiter, inline_block_paren_depth]
-            inline_block_paren_depth = 1
-            state = :initial
-            next
-            
-          elsif match = scan(/ \$ /mx)
-            encoder.text_token match, :content
-            
-          elsif match = scan(/ \\. /mx)
-            encoder.text_token match, :content  # TODO: Shouldn't this be :error?
-            
-          elsif match = scan(/ \\ | \n /x)
-            encoder.end_group state
-            encoder.text_token match, :error
-            after_def = value_expected = false
-            state = :initial
-            
-          else
-            raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
-            
-          end
-          
-        else
-          raise_inspect 'Unknown state', encoder
-          
-        end
-        
-        last_token = match unless [:space, :comment, :doctype].include? kind
-        
-      end
-      
-      if [:multiline_string, :string, :regexp].include? state
-        encoder.end_group state
-      end
-      
-      encoder
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0e/0ee222eff2b16f026f0f817fdf32372447c6e7e8.svn-base
--- a/.svn/pristine/0e/0ee222eff2b16f026f0f817fdf32372447c6e7e8.svn-base
+++ /dev/null
@@ -1,44 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class ProjectsTest < ActionController::IntegrationTest
-  fixtures :projects, :users, :members
-
-  def test_archive_project
-    subproject = Project.find(1).children.first
-    log_user("admin", "admin")
-    get "admin/projects"
-    assert_response :success
-    assert_template "admin/projects"
-    post "projects/archive", :id => 1
-    assert_redirected_to "/admin/projects"
-    assert !Project.find(1).active?
-
-    get 'projects/1'
-    assert_response 403
-    get "projects/#{subproject.id}"
-    assert_response 403
-
-    post "projects/unarchive", :id => 1
-    assert_redirected_to "/admin/projects"
-    assert Project.find(1).active?
-    get "projects/1"
-    assert_response :success
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0f/0f05e49d9c9481ce6698da320e7a0f815ec9a184.svn-base
--- /dev/null
+++ b/.svn/pristine/0f/0f05e49d9c9481ce6698da320e7a0f815ec9a184.svn-base
@@ -0,0 +1,456 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../test_helper', __FILE__)
+require 'digest/md5'
+
+class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase
+
+  def setup
+    @formatter = Redmine::WikiFormatting::Textile::Formatter
+  end
+
+  MODIFIERS = {
+    "*" => 'strong', # bold
+    "_" => 'em',     # italic
+    "+" => 'ins',    # underline
+    "-" => 'del',    # deleted
+    "^" => 'sup',    # superscript
+    "~" => 'sub'     # subscript
+  }
+
+  def test_modifiers
+    assert_html_output(
+      '*bold*'                => '<strong>bold</strong>',
+      'before *bold*'         => 'before <strong>bold</strong>',
+      '*bold* after'          => '<strong>bold</strong> after',
+      '*two words*'           => '<strong>two words</strong>',
+      '*two*words*'           => '<strong>two*words</strong>',
+      '*two * words*'         => '<strong>two * words</strong>',
+      '*two* *words*'         => '<strong>two</strong> <strong>words</strong>',
+      '*(two)* *(words)*'     => '<strong>(two)</strong> <strong>(words)</strong>',
+      # with class
+      '*(foo)two words*'      => '<strong class="foo">two words</strong>'
+    )
+  end
+
+  def test_modifiers_combination
+    MODIFIERS.each do |m1, tag1|
+      MODIFIERS.each do |m2, tag2|
+        next if m1 == m2
+        text = "#{m2}#{m1}Phrase modifiers#{m1}#{m2}"
+        html = "<#{tag2}><#{tag1}>Phrase modifiers</#{tag1}></#{tag2}>"
+        assert_html_output text => html
+      end
+    end
+  end
+
+  def test_styles
+    # single style
+    assert_html_output({
+      'p{color:red}. text'           => '<p style="color:red;">text</p>',
+      'p{color:red;}. text'          => '<p style="color:red;">text</p>',
+      'p{color: red}. text'          => '<p style="color: red;">text</p>',
+      'p{color:#f00}. text'          => '<p style="color:#f00;">text</p>',
+      'p{color:#ff0000}. text'       => '<p style="color:#ff0000;">text</p>',
+      'p{border:10px}. text'         => '<p style="border:10px;">text</p>',
+      'p{border:10}. text'           => '<p style="border:10;">text</p>',
+      'p{border:10%}. text'          => '<p style="border:10%;">text</p>',
+      'p{border:10em}. text'         => '<p style="border:10em;">text</p>',
+      'p{border:1.5em}. text'        => '<p style="border:1.5em;">text</p>',
+      'p{border-left:1px}. text'     => '<p style="border-left:1px;">text</p>',
+      'p{border-right:1px}. text'    => '<p style="border-right:1px;">text</p>',
+      'p{border-top:1px}. text'      => '<p style="border-top:1px;">text</p>',
+      'p{border-bottom:1px}. text'   => '<p style="border-bottom:1px;">text</p>',
+      }, false)
+
+    # multiple styles
+    assert_html_output({
+      'p{color:red; border-top:1px}. text'   => '<p style="color:red;border-top:1px;">text</p>',
+      'p{color:red ; border-top:1px}. text'  => '<p style="color:red;border-top:1px;">text</p>',
+      'p{color:red;border-top:1px}. text'    => '<p style="color:red;border-top:1px;">text</p>',
+      }, false)
+
+    # styles with multiple values
+    assert_html_output({
+      'p{border:1px solid red;}. text'             => '<p style="border:1px solid red;">text</p>',
+      'p{border-top-left-radius: 10px 5px;}. text' => '<p style="border-top-left-radius: 10px 5px;">text</p>',
+      }, false)
+  end
+
+  def test_invalid_styles_should_be_filtered
+    assert_html_output({
+      'p{invalid}. text'                     => '<p>text</p>',
+      'p{invalid:red}. text'                 => '<p>text</p>',
+      'p{color:(red)}. text'                 => '<p>text</p>',
+      'p{color:red;invalid:blue}. text'      => '<p style="color:red;">text</p>',
+      'p{invalid:blue;color:red}. text'      => '<p style="color:red;">text</p>',
+      'p{color:"}. text'                     => '<p>p{color:"}. text</p>',
+      }, false)
+  end
+
+  def test_inline_code
+    assert_html_output(
+      'this is @some code@'      => 'this is <code>some code</code>',
+      '@<Location /redmine>@'    => '<code>&lt;Location /redmine&gt;</code>'
+    )
+  end
+
+  def test_nested_lists
+    raw = <<-RAW
+# Item 1
+# Item 2
+** Item 2a
+** Item 2b
+# Item 3
+** Item 3a
+RAW
+
+    expected = <<-EXPECTED
+<ol>
+  <li>Item 1</li>
+  <li>Item 2
+    <ul>
+      <li>Item 2a</li>
+      <li>Item 2b</li>
+    </ul>
+  </li>
+  <li>Item 3
+    <ul>
+      <li>Item 3a</li>
+    </ul>
+  </li>
+</ol>
+EXPECTED
+
+    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
+  end
+
+  def test_escaping
+    assert_html_output(
+      'this is a <script>'      => 'this is a &lt;script&gt;'
+    )
+  end
+
+  def test_use_of_backslashes_followed_by_numbers_in_headers
+    assert_html_output({
+      'h1. 2009\02\09'      => '<h1>2009\02\09</h1>'
+    }, false)
+  end
+
+  def test_double_dashes_should_not_strikethrough
+    assert_html_output(
+      'double -- dashes -- test'  => 'double -- dashes -- test',
+      'double -- *dashes* -- test'  => 'double -- <strong>dashes</strong> -- test'
+    )
+  end
+
+  def test_acronyms
+    assert_html_output(
+      'this is an acronym: GPL(General Public License)' => 'this is an acronym: <acronym title="General Public License">GPL</acronym>',
+      '2 letters JP(Jean-Philippe) acronym' => '2 letters <acronym title="Jean-Philippe">JP</acronym> acronym',
+      'GPL(This is a double-quoted "title")' => '<acronym title="This is a double-quoted &quot;title&quot;">GPL</acronym>'
+    )
+  end
+
+  def test_blockquote
+    # orig raw text
+    raw = <<-RAW
+John said:
+> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
+> Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
+> * Donec odio lorem,
+> * sagittis ac,
+> * malesuada in,
+> * adipiscing eu, dolor.
+>
+> >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
+> Proin a tellus. Nam vel neque.
+
+He's right.
+RAW
+
+    # expected html
+    expected = <<-EXPECTED
+<p>John said:</p>
+<blockquote>
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.<br />
+Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
+<ul>
+  <li>Donec odio lorem,</li>
+  <li>sagittis ac,</li>
+  <li>malesuada in,</li>
+  <li>adipiscing eu, dolor.</li>
+</ul>
+<blockquote>
+<p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
+</blockquote>
+<p>Proin a tellus. Nam vel neque.</p>
+</blockquote>
+<p>He's right.</p>
+EXPECTED
+
+    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
+  end
+
+  def test_table
+    raw = <<-RAW
+This is a table with empty cells:
+
+|cell11|cell12||
+|cell21||cell23|
+|cell31|cell32|cell33|
+RAW
+
+    expected = <<-EXPECTED
+<p>This is a table with empty cells:</p>
+
+<table>
+  <tr><td>cell11</td><td>cell12</td><td></td></tr>
+  <tr><td>cell21</td><td></td><td>cell23</td></tr>
+  <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
+</table>
+EXPECTED
+
+    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
+  end
+
+  def test_table_with_line_breaks
+    raw = <<-RAW
+This is a table with line breaks:
+
+|cell11
+continued|cell12||
+|-cell21-||cell23
+cell23 line2
+cell23 *line3*|
+|cell31|cell32
+cell32 line2|cell33|
+
+RAW
+
+    expected = <<-EXPECTED
+<p>This is a table with line breaks:</p>
+
+<table>
+  <tr>
+    <td>cell11<br />continued</td>
+    <td>cell12</td>
+    <td></td>
+  </tr>
+  <tr>
+    <td><del>cell21</del></td>
+    <td></td>
+    <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
+  </tr>
+  <tr>
+    <td>cell31</td>
+    <td>cell32<br/>cell32 line2</td>
+    <td>cell33</td>
+  </tr>
+</table>
+EXPECTED
+
+    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
+  end
+
+  def test_textile_should_not_mangle_brackets
+    assert_equal '<p>[msg1][msg2]</p>', to_html('[msg1][msg2]')
+  end
+
+  def test_textile_should_escape_image_urls
+    # this is onclick="alert('XSS');" in encoded form
+    raw = '!/images/comment.png"onclick=&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x27;&#x58;&#x53;&#x53;&#x27;&#x29;;&#x22;!'
+    expected = '<p><img src="/images/comment.png&quot;onclick=&amp;#x61;&amp;#x6c;&amp;#x65;&amp;#x72;&amp;#x74;&amp;#x28;&amp;#x27;&amp;#x58;&amp;#x53;&amp;#x53;&amp;#x27;&amp;#x29;;&amp;#x22;" alt="" /></p>'
+    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
+  end
+  
+  
+  STR_WITHOUT_PRE = [
+  # 0
+"h1. Title
+
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
+  # 1
+"h2. Heading 2
+
+Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in.
+
+Cras ipsum felis, ultrices at porttitor vel, faucibus eu nunc.",
+  # 2
+"h2. Heading 2
+
+Morbi facilisis accumsan orci non pharetra.
+
+h3. Heading 3
+
+Nulla nunc nisi, egestas in ornare vel, posuere ac libero.",
+  # 3
+"h3. Heading 3
+
+Praesent eget turpis nibh, a lacinia nulla.",
+  # 4
+"h2. Heading 2
+
+Ut rhoncus elementum adipiscing."]
+
+  TEXT_WITHOUT_PRE = STR_WITHOUT_PRE.join("\n\n").freeze
+  
+  def test_get_section_should_return_the_requested_section_and_its_hash
+    assert_section_with_hash STR_WITHOUT_PRE[1], TEXT_WITHOUT_PRE, 2
+    assert_section_with_hash STR_WITHOUT_PRE[2..3].join("\n\n"), TEXT_WITHOUT_PRE, 3
+    assert_section_with_hash STR_WITHOUT_PRE[3], TEXT_WITHOUT_PRE, 5
+    assert_section_with_hash STR_WITHOUT_PRE[4], TEXT_WITHOUT_PRE, 6
+    
+    assert_section_with_hash '', TEXT_WITHOUT_PRE, 0
+    assert_section_with_hash '', TEXT_WITHOUT_PRE, 10
+  end
+  
+  def test_update_section_should_update_the_requested_section
+    replacement = "New text"
+    
+    assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement)
+    assert_equal [STR_WITHOUT_PRE[0..1], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(3, replacement)
+    assert_equal [STR_WITHOUT_PRE[0..2], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(5, replacement)
+    assert_equal [STR_WITHOUT_PRE[0..3], replacement].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(6, replacement)
+    
+    assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(0, replacement)
+    assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(10, replacement)
+  end
+  
+  def test_update_section_with_hash_should_update_the_requested_section
+    replacement = "New text"
+    
+    assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"),
+      @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement, Digest::MD5.hexdigest(STR_WITHOUT_PRE[1]))
+  end
+  
+  def test_update_section_with_wrong_hash_should_raise_an_error
+    assert_raise Redmine::WikiFormatting::StaleSectionError do
+      @formatter.new(TEXT_WITHOUT_PRE).update_section(2, "New text", Digest::MD5.hexdigest("Old text"))
+    end
+  end
+
+  STR_WITH_PRE = [
+  # 0
+"h1. Title
+
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
+  # 1
+"h2. Heading 2
+
+<pre><code class=\"ruby\">
+  def foo
+  end
+</code></pre>
+
+<pre><code><pre><code class=\"ruby\">
+  Place your code here.
+</code></pre>
+</code></pre>
+
+Morbi facilisis accumsan orci non pharetra.
+
+<pre>
+Pre Content:
+
+h2. Inside pre
+
+<tag> inside pre block
+
+Morbi facilisis accumsan orci non pharetra.
+</pre>",
+  # 2
+"h3. Heading 3
+
+Nulla nunc nisi, egestas in ornare vel, posuere ac libero."]
+
+  def test_get_section_should_ignore_pre_content
+    text = STR_WITH_PRE.join("\n\n")
+
+    assert_section_with_hash STR_WITH_PRE[1..2].join("\n\n"), text, 2
+    assert_section_with_hash STR_WITH_PRE[2], text, 3
+  end
+
+  def test_update_section_should_not_escape_pre_content_outside_section
+    text = STR_WITH_PRE.join("\n\n")
+    replacement = "New text"
+    
+    assert_equal [STR_WITH_PRE[0..1], "New text"].flatten.join("\n\n"),
+      @formatter.new(text).update_section(3, replacement)
+  end
+
+  def test_get_section_should_support_lines_with_spaces_before_heading
+    # the lines after Content 2 and Heading 4 contain a space
+    text = <<-STR
+h1. Heading 1
+
+Content 1
+
+h1. Heading 2
+
+Content 2
+ 
+h1. Heading 3
+
+Content 3
+
+h1. Heading 4
+ 
+Content 4
+STR
+
+    [1, 2, 3, 4].each do |index|
+      assert_match /\Ah1. Heading #{index}.+Content #{index}/m, @formatter.new(text).get_section(index).first
+    end
+  end
+
+  def test_get_section_should_support_headings_starting_with_a_tab
+    text = <<-STR
+h1.\tHeading 1
+
+Content 1
+
+h1. Heading 2
+
+Content 2
+STR
+
+    assert_match /\Ah1.\tHeading 1\s+Content 1\z/, @formatter.new(text).get_section(1).first
+  end
+
+  private
+
+  def assert_html_output(to_test, expect_paragraph = true)
+    to_test.each do |text, expected|
+      assert_equal(( expect_paragraph ? "<p>#{expected}</p>" : expected ), @formatter.new(text).to_html, "Formatting the following text failed:\n===\n#{text}\n===\n")
+    end
+  end
+
+  def to_html(text)
+    @formatter.new(text).to_html
+  end
+  
+  def assert_section_with_hash(expected, text, index)
+    result = @formatter.new(text).get_section(index)
+    
+    assert_kind_of Array, result
+    assert_equal 2, result.size
+    assert_equal expected, result.first, "section content did not match"
+    assert_equal Digest::MD5.hexdigest(expected), result.last, "section hash did not match"
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0f/0f55ca10803bce4cf5a650e17d0e04f01a9b964d.svn-base
--- a/.svn/pristine/0f/0f55ca10803bce4cf5a650e17d0e04f01a9b964d.svn-base
+++ /dev/null
@@ -1,48 +0,0 @@
-<div class="splitcontentleft">
-<% if @group.users.any? %>
-  <table class="list users">
-    <thead><tr>
-      <th><%= l(:label_user) %></th>
-      <th style="width:15%"></th>
-    </tr></thead>
-    <tbody>
-    <% @group.users.sort.each do |user| %>
-      <tr id="user-<%= user.id %>" class="<%= cycle 'odd', 'even' %>">
-        <td class="user"><%= link_to_user user %></td>
-        <td class="buttons">
-            <%= link_to_remote l(:button_delete), { :url => group_user_path(@group, :user_id => user), :method => :delete }, :class => 'icon icon-del' %>
-        </td>
-      </tr>
-    <% end %>
-    </tbody>
-  </table>
-<% else %>
-  <p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
-</div>
-
-<div class="splitcontentright">
-<% users = User.active.not_in_group(@group).all(:limit => 100) %>
-<% if users.any? %>
-  <% remote_form_for(@group, :url => group_users_path(@group), :html => {:method => :post}) do |f| %>
-    <fieldset><legend><%=l(:label_user_new)%></legend>
-
-    <p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
-    <%= observe_field(:user_search,
-                 :frequency => 0.5,
-                 :update => :users,
-                 :url => autocomplete_for_user_group_path(@group),
-                 :method => :get,
-                 :with => 'q')
-                  %>
-
-    <div id="users">
-      <%= principals_check_box_tags 'user_ids[]', users %>
-    </div>
-
-    <p><%= submit_tag l(:button_add) %></p>
-    </fieldset>
-  <% end %>
-<% end %>
-
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0f/0f5d0b28aa88dc0b634f0aed6c20653f95af7206.svn-base
--- a/.svn/pristine/0f/0f5d0b28aa88dc0b634f0aed6c20653f95af7206.svn-base
+++ /dev/null
@@ -1,141 +0,0 @@
-module CodeRay
-  
-  # = FileType
-  #
-  # A simple filetype recognizer.
-  #
-  # == Usage
-  #
-  #  # determine the type of the given
-  #  lang = FileType[file_name]
-  #  
-  #  # return :text if the file type is unknown
-  #  lang = FileType.fetch file_name, :text
-  #  
-  #  # try the shebang line, too
-  #  lang = FileType.fetch file_name, :text, true
-  module FileType
-    
-    UnknownFileType = Class.new Exception
-    
-    class << self
-      
-      # Try to determine the file type of the file.
-      #
-      # +filename+ is a relative or absolute path to a file.
-      #
-      # The file itself is only accessed when +read_shebang+ is set to true.
-      # That means you can get filetypes from files that don't exist.
-      def [] filename, read_shebang = false
-        name = File.basename filename
-        ext = File.extname(name).sub(/^\./, '')  # from last dot, delete the leading dot
-        ext2 = filename.to_s[/\.(.*)/, 1]  # from first dot
-        
-        type =
-          TypeFromExt[ext] ||
-          TypeFromExt[ext.downcase] ||
-          (TypeFromExt[ext2] if ext2) ||
-          (TypeFromExt[ext2.downcase] if ext2) ||
-          TypeFromName[name] ||
-          TypeFromName[name.downcase]
-        type ||= shebang(filename) if read_shebang
-        
-        type
-      end
-      
-      # This works like Hash#fetch.
-      #
-      # If the filetype cannot be found, the +default+ value
-      # is returned.
-      def fetch filename, default = nil, read_shebang = false
-        if default && block_given?
-          warn 'Block supersedes default value argument; use either.'
-        end
-        
-        if type = self[filename, read_shebang]
-          type
-        else
-          return yield if block_given?
-          return default if default
-          raise UnknownFileType, 'Could not determine type of %p.' % filename
-        end
-      end
-      
-    protected
-      
-      def shebang filename
-        return unless File.exist? filename
-        File.open filename, 'r' do |f|
-          if first_line = f.gets
-            if type = first_line[TypeFromShebang]
-              type.to_sym
-            end
-          end
-        end
-      end
-      
-    end
-    
-    TypeFromExt = {
-      'c'        => :c,
-      'cfc'      => :xml,
-      'cfm'      => :xml,
-      'clj'      => :clojure,
-      'css'      => :css,
-      'diff'     => :diff,
-      'dpr'      => :delphi,
-      'gemspec'  => :ruby,
-      'groovy'   => :groovy,
-      'gvy'      => :groovy,
-      'h'        => :c,
-      'haml'     => :haml,
-      'htm'      => :page,
-      'html'     => :page,
-      'html.erb' => :erb,
-      'java'     => :java,
-      'js'       => :java_script,
-      'json'     => :json,
-      'mab'      => :ruby,
-      'pas'      => :delphi,
-      'patch'    => :diff,
-      'php'      => :php,
-      'php3'     => :php,
-      'php4'     => :php,
-      'php5'     => :php,
-      'prawn'    => :ruby,
-      'py'       => :python,
-      'py3'      => :python,
-      'pyw'      => :python,
-      'rake'     => :ruby,
-      'raydebug' => :raydebug,
-      'rb'       => :ruby,
-      'rbw'      => :ruby,
-      'rhtml'    => :erb,
-      'rjs'      => :ruby,
-      'rpdf'     => :ruby,
-      'ru'       => :ruby,
-      'rxml'     => :ruby,
-      # 'sch'      => :scheme,
-      'sql'      => :sql,
-      # 'ss'       => :scheme,
-      'xhtml'    => :page,
-      'xml'      => :xml,
-      'yaml'     => :yaml,
-      'yml'      => :yaml,
-    }
-    for cpp_alias in %w[cc cpp cp cxx c++ C hh hpp h++ cu]
-      TypeFromExt[cpp_alias] = :cpp
-    end
-    
-    TypeFromShebang = /\b(?:ruby|perl|python|sh)\b/
-    
-    TypeFromName = {
-      'Capfile'  => :ruby,
-      'Rakefile' => :ruby,
-      'Rantfile' => :ruby,
-      'Gemfile'  => :ruby,
-    }
-    
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0f/0f6a1a5f91b1625dba02a90214d3f1e2572096f8.svn-base
--- /dev/null
+++ b/.svn/pristine/0f/0f6a1a5f91b1625dba02a90214d3f1e2572096f8.svn-base
@@ -0,0 +1,7 @@
+--- a.txt	2013-04-05 14:19:39.000000000 +0900
++++ b.txt	2013-04-05 14:19:51.000000000 +0900
+@@ -1,3 +1,3 @@
+ aaaa
+-æ—¥æœ¬
++æ—¥æœ¬èªž
+ bbbb
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0f/0f78241a73ec8550e8a5f3850c895c44e2ed8e56.svn-base
--- /dev/null
+++ b/.svn/pristine/0f/0f78241a73ec8550e8a5f3850c895c44e2ed8e56.svn-base
@@ -0,0 +1,60 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'net/imap'
+
+module Redmine
+  module IMAP
+    class << self
+      def check(imap_options={}, options={})
+        host = imap_options[:host] || '127.0.0.1'
+        port = imap_options[:port] || '143'
+        ssl = !imap_options[:ssl].nil?
+        folder = imap_options[:folder] || 'INBOX'
+
+        imap = Net::IMAP.new(host, port, ssl)
+        imap.login(imap_options[:username], imap_options[:password]) unless imap_options[:username].nil?
+        imap.select(folder)
+        imap.search(['NOT', 'SEEN']).each do |message_id|
+          msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
+          logger.debug "Receiving message #{message_id}" if logger && logger.debug?
+          if MailHandler.receive(msg, options)
+            logger.debug "Message #{message_id} successfully received" if logger && logger.debug?
+            if imap_options[:move_on_success]
+              imap.copy(message_id, imap_options[:move_on_success])
+            end
+            imap.store(message_id, "+FLAGS", [:Seen, :Deleted])
+          else
+            logger.debug "Message #{message_id} can not be processed" if logger && logger.debug?
+            imap.store(message_id, "+FLAGS", [:Seen])
+            if imap_options[:move_on_failure]
+              imap.copy(message_id, imap_options[:move_on_failure])
+              imap.store(message_id, "+FLAGS", [:Deleted])
+            end
+          end
+        end
+        imap.expunge
+      end
+
+      private
+
+      def logger
+        ::Rails.logger
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0f/0f842304e58a7a419abba90bd185840b383c9907.svn-base
--- a/.svn/pristine/0f/0f842304e58a7a419abba90bd185840b383c9907.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-module Engines
-  class Plugin
-    class FileSystemLocator < Rails::Plugin::FileSystemLocator
-      def create_plugin(path)
-        plugin = Engines::Plugin.new(path)
-        plugin.valid? ? plugin : nil
-      end        
-    end
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0f/0fa8b994f508f388585e802196325aae4a4107f7.svn-base
--- a/.svn/pristine/0f/0fa8b994f508f388585e802196325aae4a4107f7.svn-base
+++ /dev/null
@@ -1,51 +0,0 @@
-<%= error_messages_for 'user' %>
-
-<div id="user_form">
-<!--[form:user]-->
-<div class="splitcontentleft">
-<fieldset class="box tabular">
-  <legend><%=l(:label_information_plural)%></legend>
-  <p><%= f.text_field :login, :required => true, :size => 25  %></p>
-  <p><%= f.text_field :firstname, :required => true %></p>
-  <p><%= f.text_field :lastname, :required => true %></p>
-  <p><%= f.text_field :mail, :required => true %></p>
-  <p><%= f.select :language, lang_options_for_select %></p>
-  <% if Setting.openid? %>
-  <p><%= f.text_field :identity_url  %></p>
-  <% end %>
-
-  <% @user.custom_field_values.each do |value| %>
-    <p><%= custom_field_tag_with_label :user, value %></p>
-  <% end %>
-
-  <p><%= f.check_box :admin, :disabled => (@user == User.current) %></p>
-  <%= call_hook(:view_users_form, :user => @user, :form => f) %>
-</fieldset>
-
-<fieldset class="box tabular">
-  <legend><%=l(:label_authentication)%></legend>
-  <% unless @auth_sources.empty? %>
-  <p><%= f.select :auth_source_id, ([[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] }), {}, :onchange => "if (this.value=='') {Element.show('password_fields');} else {Element.hide('password_fields');}" %></p>
-  <% end %>
-  <div id="password_fields" style="<%= 'display:none;' if @user.auth_source %>">
-  <p><%= f.password_field :password, :required => true, :size => 25  %><br />
-  <em><%= l(:text_caracters_minimum, :count => Setting.password_min_length) %></em></p>
-  <p><%= f.password_field :password_confirmation, :required => true, :size => 25  %></p>
-  </div>
-</fieldset>
-</div>
-
-<div class="splitcontentright">
-<fieldset class="box">
-  <legend><%=l(:field_mail_notification)%></legend>
-  <%= render :partial => 'users/mail_notifications' %>
-</fieldset>
-
-<fieldset class="box tabular">
-  <legend><%=l(:label_preferences)%></legend>
-  <%= render :partial => 'users/preferences' %>
-</fieldset>
-</div>
-</div>
-<div style="clear:left;"></div>
-<!--[eoform:user]-->
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0f/0fd45ffc205637b86a8a066d7efda723815c1464.svn-base
--- a/.svn/pristine/0f/0fd45ffc205637b86a8a066d7efda723815c1464.svn-base
+++ /dev/null
@@ -1,61 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'settings_controller'
-
-# Re-raise errors caught by the controller.
-class SettingsController; def rescue_action(e) raise e end; end
-
-class SettingsControllerTest < ActionController::TestCase
-  fixtures :users
-
-  def setup
-    @controller = SettingsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @request.session[:user_id] = 1 # admin
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_get_edit
-    get :edit
-    assert_response :success
-    assert_template 'edit'
-
-    assert_tag 'input', :attributes => {:name => 'settings[enabled_scm][]', :value => ''}
-  end
-
-  def test_post_edit_notifications
-    post :edit, :settings => {:mail_from => 'functional@test.foo',
-                              :bcc_recipients  => '0',
-                              :notified_events => %w(issue_added issue_updated news_added),
-                              :emails_footer => 'Test footer'
-                              }
-    assert_redirected_to '/settings/edit'
-    assert_equal 'functional@test.foo', Setting.mail_from
-    assert !Setting.bcc_recipients?
-    assert_equal %w(issue_added issue_updated news_added), Setting.notified_events
-    assert_equal 'Test footer', Setting.emails_footer
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/0f/0ff0bfae04ec7a8241921bdb8bb6771c6ffcd5d9.svn-base
--- a/.svn/pristine/0f/0ff0bfae04ec7a8241921bdb8bb6771c6ffcd5d9.svn-base
+++ /dev/null
@@ -1,14 +0,0 @@
-api.version do
-  api.id @version.id
-  api.project(:id => @version.project_id, :name => @version.project.name) unless @version.project.nil?
-
-  api.name        @version.name
-  api.description @version.description
-  api.status      @version.status
-  api.due_date    @version.effective_date
-
-  render_api_custom_values @version.custom_field_values, api
-
-  api.created_on @version.created_on
-  api.updated_on @version.updated_on
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/10/1048cea83e08be09288d325f5a2d1908b807f592.svn-base
--- a/.svn/pristine/10/1048cea83e08be09288d325f5a2d1908b807f592.svn-base
+++ /dev/null
@@ -1,860 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Helpers
-    # Simple class to handle gantt chart data
-    class Gantt
-      include ERB::Util
-      include Redmine::I18n
-
-      # :nodoc:
-      # Some utility methods for the PDF export
-      class PDF
-        MaxCharactorsForSubject = 45
-        TotalWidth = 280
-        LeftPaneWidth = 100
-
-        def self.right_pane_width
-          TotalWidth - LeftPaneWidth
-        end
-      end
-
-      attr_reader :year_from, :month_from, :date_from, :date_to, :zoom, :months, :truncated, :max_rows
-      attr_accessor :query
-      attr_accessor :project
-      attr_accessor :view
-
-      def initialize(options={})
-        options = options.dup
-
-        if options[:year] && options[:year].to_i >0
-          @year_from = options[:year].to_i
-          if options[:month] && options[:month].to_i >=1 && options[:month].to_i <= 12
-            @month_from = options[:month].to_i
-          else
-            @month_from = 1
-          end
-        else
-          @month_from ||= Date.today.month
-          @year_from ||= Date.today.year
-        end
-
-        zoom = (options[:zoom] || User.current.pref[:gantt_zoom]).to_i
-        @zoom = (zoom > 0 && zoom < 5) ? zoom : 2
-        months = (options[:months] || User.current.pref[:gantt_months]).to_i
-        @months = (months > 0 && months < 25) ? months : 6
-
-        # Save gantt parameters as user preference (zoom and months count)
-        if (User.current.logged? && (@zoom != User.current.pref[:gantt_zoom] || @months != User.current.pref[:gantt_months]))
-          User.current.pref[:gantt_zoom], User.current.pref[:gantt_months] = @zoom, @months
-          User.current.preference.save
-        end
-
-        @date_from = Date.civil(@year_from, @month_from, 1)
-        @date_to = (@date_from >> @months) - 1
-
-        @subjects = ''
-        @lines = ''
-        @number_of_rows = nil
-
-        @issue_ancestors = []
-
-        @truncated = false
-        if options.has_key?(:max_rows)
-          @max_rows = options[:max_rows]
-        else
-          @max_rows = Setting.gantt_items_limit.blank? ? nil : Setting.gantt_items_limit.to_i
-        end
-      end
-
-      def common_params
-        { :controller => 'gantts', :action => 'show', :project_id => @project }
-      end
-
-      def params
-        common_params.merge({  :zoom => zoom, :year => year_from, :month => month_from, :months => months })
-      end
-
-      def params_previous
-        common_params.merge({:year => (date_from << months).year, :month => (date_from << months).month, :zoom => zoom, :months => months })
-      end
-
-      def params_next
-        common_params.merge({:year => (date_from >> months).year, :month => (date_from >> months).month, :zoom => zoom, :months => months })
-      end
-
-      # Returns the number of rows that will be rendered on the Gantt chart
-      def number_of_rows
-        return @number_of_rows if @number_of_rows
-
-        rows = projects.inject(0) {|total, p| total += number_of_rows_on_project(p)}
-        rows > @max_rows ? @max_rows : rows
-      end
-
-      # Returns the number of rows that will be used to list a project on
-      # the Gantt chart.  This will recurse for each subproject.
-      def number_of_rows_on_project(project)
-        return 0 unless projects.include?(project)
-
-        count = 1
-        count += project_issues(project).size
-        count += project_versions(project).size
-        count
-      end
-
-      # Renders the subjects of the Gantt chart, the left side.
-      def subjects(options={})
-        render(options.merge(:only => :subjects)) unless @subjects_rendered
-        @subjects
-      end
-
-      # Renders the lines of the Gantt chart, the right side
-      def lines(options={})
-        render(options.merge(:only => :lines)) unless @lines_rendered
-        @lines
-      end
-
-      # Returns issues that will be rendered
-      def issues
-        @issues ||= @query.issues(
-          :include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
-          :order => "#{Project.table_name}.lft ASC, #{Issue.table_name}.id ASC",
-          :limit => @max_rows
-        )
-      end
-
-      # Return all the project nodes that will be displayed
-      def projects
-        return @projects if @projects
-
-        ids = issues.collect(&:project).uniq.collect(&:id)
-        if ids.any?
-          # All issues projects and their visible ancestors
-          @projects = Project.visible.all(
-            :joins => "LEFT JOIN #{Project.table_name} child ON #{Project.table_name}.lft <= child.lft AND #{Project.table_name}.rgt >= child.rgt",
-            :conditions => ["child.id IN (?)", ids],
-            :order => "#{Project.table_name}.lft ASC"
-          ).uniq
-        else
-          @projects = []
-        end
-      end
-
-      # Returns the issues that belong to +project+
-      def project_issues(project)
-        @issues_by_project ||= issues.group_by(&:project)
-        @issues_by_project[project] || []
-      end
-
-      # Returns the distinct versions of the issues that belong to +project+
-      def project_versions(project)
-        project_issues(project).collect(&:fixed_version).compact.uniq
-      end
-
-      # Returns the issues that belong to +project+ and are assigned to +version+
-      def version_issues(project, version)
-        project_issues(project).select {|issue| issue.fixed_version == version}
-      end
-
-      def render(options={})
-        options = {:top => 0, :top_increment => 20, :indent_increment => 20, :render => :subject, :format => :html}.merge(options)
-        indent = options[:indent] || 4
-
-        @subjects = '' unless options[:only] == :lines
-        @lines = '' unless options[:only] == :subjects
-        @number_of_rows = 0
-
-        Project.project_tree(projects) do |project, level|
-          options[:indent] = indent + level * options[:indent_increment]
-          render_project(project, options)
-          break if abort?
-        end
-
-        @subjects_rendered = true unless options[:only] == :lines
-        @lines_rendered = true unless options[:only] == :subjects
-
-        render_end(options)
-      end
-
-      def render_project(project, options={})
-        subject_for_project(project, options) unless options[:only] == :lines
-        line_for_project(project, options) unless options[:only] == :subjects
-
-        options[:top] += options[:top_increment]
-        options[:indent] += options[:indent_increment]
-        @number_of_rows += 1
-        return if abort?
-
-        issues = project_issues(project).select {|i| i.fixed_version.nil?}
-        sort_issues!(issues)
-        if issues
-          render_issues(issues, options)
-          return if abort?
-        end
-
-        versions = project_versions(project)
-        versions.each do |version|
-          render_version(project, version, options)
-        end
-
-        # Remove indent to hit the next sibling
-        options[:indent] -= options[:indent_increment]
-      end
-
-      def render_issues(issues, options={})
-        @issue_ancestors = []
-
-        issues.each do |i|
-          subject_for_issue(i, options) unless options[:only] == :lines
-          line_for_issue(i, options) unless options[:only] == :subjects
-
-          options[:top] += options[:top_increment]
-          @number_of_rows += 1
-          break if abort?
-        end
-
-        options[:indent] -= (options[:indent_increment] * @issue_ancestors.size)
-      end
-
-      def render_version(project, version, options={})
-        # Version header
-        subject_for_version(version, options) unless options[:only] == :lines
-        line_for_version(version, options) unless options[:only] == :subjects
-
-        options[:top] += options[:top_increment]
-        @number_of_rows += 1
-        return if abort?
-
-        issues = version_issues(project, version)
-        if issues
-          sort_issues!(issues)
-          # Indent issues
-          options[:indent] += options[:indent_increment]
-          render_issues(issues, options)
-          options[:indent] -= options[:indent_increment]
-        end
-      end
-
-      def render_end(options={})
-        case options[:format]
-        when :pdf
-          options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top])
-        end
-      end
-
-      def subject_for_project(project, options)
-        case options[:format]
-        when :html
-          subject = "<span class='icon icon-projects #{project.overdue? ? 'project-overdue' : ''}'>".html_safe
-          subject << view.link_to_project(project).html_safe
-          subject << '</span>'.html_safe
-          html_subject(options, subject, :css => "project-name")
-        when :image
-          image_subject(options, project.name)
-        when :pdf
-          pdf_new_page?(options)
-          pdf_subject(options, project.name)
-        end
-      end
-
-      def line_for_project(project, options)
-        # Skip versions that don't have a start_date or due date
-        if project.is_a?(Project) && project.start_date && project.due_date
-          options[:zoom] ||= 1
-          options[:g_width] ||= (self.date_to - self.date_from + 1) * options[:zoom]
-
-          coords = coordinates(project.start_date, project.due_date, nil, options[:zoom])
-          label = h(project)
-
-          case options[:format]
-          when :html
-            html_task(options, coords, :css => "project task", :label => label, :markers => true)
-          when :image
-            image_task(options, coords, :label => label, :markers => true, :height => 3)
-          when :pdf
-            pdf_task(options, coords, :label => label, :markers => true, :height => 0.8)
-          end
-        else
-          ActiveRecord::Base.logger.debug "Gantt#line_for_project was not given a project with a start_date"
-          ''
-        end
-      end
-
-      def subject_for_version(version, options)
-        case options[:format]
-        when :html
-          subject = "<span class='icon icon-package #{version.behind_schedule? ? 'version-behind-schedule' : ''} #{version.overdue? ? 'version-overdue' : ''}'>".html_safe
-          subject << view.link_to_version(version).html_safe
-          subject << '</span>'.html_safe
-          html_subject(options, subject, :css => "version-name")
-        when :image
-          image_subject(options, version.to_s_with_project)
-        when :pdf
-          pdf_new_page?(options)
-          pdf_subject(options, version.to_s_with_project)
-        end
-      end
-
-      def line_for_version(version, options)
-        # Skip versions that don't have a start_date
-        if version.is_a?(Version) && version.start_date && version.due_date
-          options[:zoom] ||= 1
-          options[:g_width] ||= (self.date_to - self.date_from + 1) * options[:zoom]
-
-          coords = coordinates(version.start_date, version.due_date, version.completed_pourcent, options[:zoom])
-          label = "#{h version } #{h version.completed_pourcent.to_i.to_s}%"
-          label = h("#{version.project} -") + label unless @project && @project == version.project
-
-          case options[:format]
-          when :html
-            html_task(options, coords, :css => "version task", :label => label, :markers => true)
-          when :image
-            image_task(options, coords, :label => label, :markers => true, :height => 3)
-          when :pdf
-            pdf_task(options, coords, :label => label, :markers => true, :height => 0.8)
-          end
-        else
-          ActiveRecord::Base.logger.debug "Gantt#line_for_version was not given a version with a start_date"
-          ''
-        end
-      end
-
-      def subject_for_issue(issue, options)
-        while @issue_ancestors.any? && !issue.is_descendant_of?(@issue_ancestors.last)
-          @issue_ancestors.pop
-          options[:indent] -= options[:indent_increment]
-        end
-
-        output = case options[:format]
-        when :html
-          css_classes = ''
-          css_classes << ' issue-overdue' if issue.overdue?
-          css_classes << ' issue-behind-schedule' if issue.behind_schedule?
-          css_classes << ' icon icon-issue' unless Setting.gravatar_enabled? && issue.assigned_to
-
-          subject = "<span class='#{css_classes}'>".html_safe
-          if issue.assigned_to.present?
-            assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name
-            subject << view.avatar(issue.assigned_to, :class => 'gravatar icon-gravatar', :size => 10, :title => assigned_string).to_s.html_safe
-          end
-          subject << view.link_to_issue(issue).html_safe
-          subject << '</span>'.html_safe
-          html_subject(options, subject, :css => "issue-subject", :title => issue.subject) + "\n"
-        when :image
-          image_subject(options, issue.subject)
-        when :pdf
-          pdf_new_page?(options)
-          pdf_subject(options, issue.subject)
-        end
-
-        unless issue.leaf?
-          @issue_ancestors << issue
-          options[:indent] += options[:indent_increment]
-        end
-
-        output
-      end
-
-      def line_for_issue(issue, options)
-        # Skip issues that don't have a due_before (due_date or version's due_date)
-        if issue.is_a?(Issue) && issue.due_before
-          coords = coordinates(issue.start_date, issue.due_before, issue.done_ratio, options[:zoom])
-          label = "#{ issue.status.name } #{ issue.done_ratio }%"
-
-          case options[:format]
-          when :html
-            html_task(options, coords, :css => "task " + (issue.leaf? ? 'leaf' : 'parent'), :label => label, :issue => issue, :markers => !issue.leaf?)
-          when :image
-            image_task(options, coords, :label => label)
-          when :pdf
-            pdf_task(options, coords, :label => label)
-        end
-        else
-          ActiveRecord::Base.logger.debug "GanttHelper#line_for_issue was not given an issue with a due_before"
-          ''
-        end
-      end
-
-      # Generates a gantt image
-      # Only defined if RMagick is avalaible
-      def to_image(format='PNG')
-        date_to = (@date_from >> @months)-1
-        show_weeks = @zoom > 1
-        show_days = @zoom > 2
-
-        subject_width = 400
-        header_height = 18
-        # width of one day in pixels
-        zoom = @zoom*2
-        g_width = (@date_to - @date_from + 1)*zoom
-        g_height = 20 * number_of_rows + 30
-        headers_height = (show_weeks ? 2*header_height : header_height)
-        height = g_height + headers_height
-
-        imgl = Magick::ImageList.new
-        imgl.new_image(subject_width+g_width+1, height)
-        gc = Magick::Draw.new
-
-        # Subjects
-        gc.stroke('transparent')
-        subjects(:image => gc, :top => (headers_height + 20), :indent => 4, :format => :image)
-
-        # Months headers
-        month_f = @date_from
-        left = subject_width
-        @months.times do
-          width = ((month_f >> 1) - month_f) * zoom
-          gc.fill('white')
-          gc.stroke('grey')
-          gc.stroke_width(1)
-          gc.rectangle(left, 0, left + width, height)
-          gc.fill('black')
-          gc.stroke('transparent')
-          gc.stroke_width(1)
-          gc.text(left.round + 8, 14, "#{month_f.year}-#{month_f.month}")
-          left = left + width
-          month_f = month_f >> 1
-        end
-
-        # Weeks headers
-        if show_weeks
-        	left = subject_width
-        	height = header_height
-        	if @date_from.cwday == 1
-        	    # date_from is monday
-                week_f = date_from
-        	else
-        	    # find next monday after date_from
-        		week_f = @date_from + (7 - @date_from.cwday + 1)
-        		width = (7 - @date_from.cwday + 1) * zoom
-                gc.fill('white')
-                gc.stroke('grey')
-                gc.stroke_width(1)
-                gc.rectangle(left, header_height, left + width, 2*header_height + g_height-1)
-        		left = left + width
-        	end
-        	while week_f <= date_to
-        		width = (week_f + 6 <= date_to) ? 7 * zoom : (date_to - week_f + 1) * zoom
-                gc.fill('white')
-                gc.stroke('grey')
-                gc.stroke_width(1)
-                gc.rectangle(left.round, header_height, left.round + width, 2*header_height + g_height-1)
-                gc.fill('black')
-                gc.stroke('transparent')
-                gc.stroke_width(1)
-                gc.text(left.round + 2, header_height + 14, week_f.cweek.to_s)
-        		left = left + width
-        		week_f = week_f+7
-        	end
-        end
-
-        # Days details (week-end in grey)
-        if show_days
-        	left = subject_width
-        	height = g_height + header_height - 1
-        	wday = @date_from.cwday
-        	(date_to - @date_from + 1).to_i.times do
-              width =  zoom
-              gc.fill(wday == 6 || wday == 7 ? '#eee' : 'white')
-              gc.stroke('#ddd')
-              gc.stroke_width(1)
-              gc.rectangle(left, 2*header_height, left + width, 2*header_height + g_height-1)
-              left = left + width
-              wday = wday + 1
-              wday = 1 if wday > 7
-        	end
-        end
-
-        # border
-        gc.fill('transparent')
-        gc.stroke('grey')
-        gc.stroke_width(1)
-        gc.rectangle(0, 0, subject_width+g_width, headers_height)
-        gc.stroke('black')
-        gc.rectangle(0, 0, subject_width+g_width, g_height+ headers_height-1)
-
-        # content
-        top = headers_height + 20
-
-        gc.stroke('transparent')
-        lines(:image => gc, :top => top, :zoom => zoom, :subject_width => subject_width, :format => :image)
-
-        # today red line
-        if Date.today >= @date_from and Date.today <= date_to
-          gc.stroke('red')
-          x = (Date.today-@date_from+1)*zoom + subject_width
-          gc.line(x, headers_height, x, headers_height + g_height-1)
-        end
-
-        gc.draw(imgl)
-        imgl.format = format
-        imgl.to_blob
-      end if Object.const_defined?(:Magick)
-
-      def to_pdf
-        pdf = ::Redmine::Export::PDF::ITCPDF.new(current_language)
-        pdf.SetTitle("#{l(:label_gantt)} #{project}")
-        pdf.alias_nb_pages
-        pdf.footer_date = format_date(Date.today)
-        pdf.AddPage("L")
-        pdf.SetFontStyle('B',12)
-        pdf.SetX(15)
-        pdf.RDMCell(PDF::LeftPaneWidth, 20, project.to_s)
-        pdf.Ln
-        pdf.SetFontStyle('B',9)
-
-        subject_width = PDF::LeftPaneWidth
-        header_height = 5
-
-        headers_height = header_height
-        show_weeks = false
-        show_days = false
-
-        if self.months < 7
-          show_weeks = true
-          headers_height = 2*header_height
-          if self.months < 3
-            show_days = true
-            headers_height = 3*header_height
-          end
-        end
-
-        g_width = PDF.right_pane_width
-        zoom = (g_width) / (self.date_to - self.date_from + 1)
-        g_height = 120
-        t_height = g_height + headers_height
-
-        y_start = pdf.GetY
-
-        # Months headers
-        month_f = self.date_from
-        left = subject_width
-        height = header_height
-        self.months.times do
-          width = ((month_f >> 1) - month_f) * zoom
-          pdf.SetY(y_start)
-          pdf.SetX(left)
-          pdf.RDMCell(width, height, "#{month_f.year}-#{month_f.month}", "LTR", 0, "C")
-          left = left + width
-          month_f = month_f >> 1
-        end
-
-        # Weeks headers
-        if show_weeks
-          left = subject_width
-          height = header_height
-          if self.date_from.cwday == 1
-            # self.date_from is monday
-            week_f = self.date_from
-          else
-            # find next monday after self.date_from
-            week_f = self.date_from + (7 - self.date_from.cwday + 1)
-            width = (7 - self.date_from.cwday + 1) * zoom-1
-            pdf.SetY(y_start + header_height)
-            pdf.SetX(left)
-            pdf.RDMCell(width + 1, height, "", "LTR")
-            left = left + width+1
-          end
-          while week_f <= self.date_to
-            width = (week_f + 6 <= self.date_to) ? 7 * zoom : (self.date_to - week_f + 1) * zoom
-            pdf.SetY(y_start + header_height)
-            pdf.SetX(left)
-            pdf.RDMCell(width, height, (width >= 5 ? week_f.cweek.to_s : ""), "LTR", 0, "C")
-            left = left + width
-            week_f = week_f+7
-          end
-        end
-
-        # Days headers
-        if show_days
-          left = subject_width
-          height = header_height
-          wday = self.date_from.cwday
-          pdf.SetFontStyle('B',7)
-          (self.date_to - self.date_from + 1).to_i.times do
-            width = zoom
-            pdf.SetY(y_start + 2 * header_height)
-            pdf.SetX(left)
-            pdf.RDMCell(width, height, day_name(wday).first, "LTR", 0, "C")
-            left = left + width
-            wday = wday + 1
-            wday = 1 if wday > 7
-          end
-        end
-
-        pdf.SetY(y_start)
-        pdf.SetX(15)
-        pdf.RDMCell(subject_width+g_width-15, headers_height, "", 1)
-
-        # Tasks
-        top = headers_height + y_start
-        options = {
-          :top => top,
-          :zoom => zoom,
-          :subject_width => subject_width,
-          :g_width => g_width,
-          :indent => 0,
-          :indent_increment => 5,
-          :top_increment => 5,
-          :format => :pdf,
-          :pdf => pdf
-        }
-        render(options)
-        pdf.Output
-      end
-
-      private
-
-      def coordinates(start_date, end_date, progress, zoom=nil)
-        zoom ||= @zoom
-
-        coords = {}
-        if start_date && end_date && start_date < self.date_to && end_date > self.date_from
-          if start_date > self.date_from
-            coords[:start] = start_date - self.date_from
-            coords[:bar_start] = start_date - self.date_from
-          else
-            coords[:bar_start] = 0
-          end
-          if end_date < self.date_to
-            coords[:end] = end_date - self.date_from
-            coords[:bar_end] = end_date - self.date_from + 1
-          else
-            coords[:bar_end] = self.date_to - self.date_from + 1
-          end
-
-          if progress
-            progress_date = start_date + (end_date - start_date + 1) * (progress / 100.0)
-            if progress_date > self.date_from && progress_date > start_date
-              if progress_date < self.date_to
-                coords[:bar_progress_end] = progress_date - self.date_from
-              else
-                coords[:bar_progress_end] = self.date_to - self.date_from + 1
-              end
-            end
-
-            if progress_date < Date.today
-              late_date = [Date.today, end_date].min
-              if late_date > self.date_from && late_date > start_date
-                if late_date < self.date_to
-                  coords[:bar_late_end] = late_date - self.date_from + 1
-                else
-                  coords[:bar_late_end] = self.date_to - self.date_from + 1
-                end
-              end
-            end
-          end
-        end
-
-        # Transforms dates into pixels witdh
-        coords.keys.each do |key|
-          coords[key] = (coords[key] * zoom).floor
-        end
-        coords
-      end
-
-      # Sorts a collection of issues by start_date, due_date, id for gantt rendering
-      def sort_issues!(issues)
-        issues.sort! { |a, b| gantt_issue_compare(a, b, issues) }
-      end
-
-      # TODO: top level issues should be sorted by start date
-      def gantt_issue_compare(x, y, issues)
-        if x.root_id == y.root_id
-          x.lft <=> y.lft
-        else
-          x.root_id <=> y.root_id
-        end
-      end
-
-      def current_limit
-        if @max_rows
-          @max_rows - @number_of_rows
-        else
-          nil
-        end
-      end
-
-      def abort?
-        if @max_rows && @number_of_rows >= @max_rows
-          @truncated = true
-        end
-      end
-
-      def pdf_new_page?(options)
-        if options[:top] > 180
-          options[:pdf].Line(15, options[:top], PDF::TotalWidth, options[:top])
-          options[:pdf].AddPage("L")
-          options[:top] = 15
-          options[:pdf].Line(15, options[:top] - 0.1, PDF::TotalWidth, options[:top] - 0.1)
-        end
-      end
-
-      def html_subject(params, subject, options={})
-        style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;"
-        style << "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width]
-
-        output = view.content_tag 'div', subject, :class => options[:css], :style => style, :title => options[:title]
-        @subjects << output
-        output
-      end
-
-      def pdf_subject(params, subject, options={})
-        params[:pdf].SetY(params[:top])
-        params[:pdf].SetX(15)
-
-        char_limit = PDF::MaxCharactorsForSubject - params[:indent]
-        params[:pdf].RDMCell(params[:subject_width]-15, 5, (" " * params[:indent]) +  subject.to_s.sub(/^(.{#{char_limit}}[^\s]*\s).*$/, '\1 (...)'), "LR")
-
-        params[:pdf].SetY(params[:top])
-        params[:pdf].SetX(params[:subject_width])
-        params[:pdf].RDMCell(params[:g_width], 5, "", "LR")
-      end
-
-      def image_subject(params, subject, options={})
-        params[:image].fill('black')
-        params[:image].stroke('transparent')
-        params[:image].stroke_width(1)
-        params[:image].text(params[:indent], params[:top] + 2, subject)
-      end
-
-      def html_task(params, coords, options={})
-        output = ''
-        # Renders the task bar, with progress and late
-        if coords[:bar_start] && coords[:bar_end]
-          output << "<div style='top:#{ params[:top] }px;left:#{ coords[:bar_start] }px;width:#{ coords[:bar_end] - coords[:bar_start] - 2}px;' class='#{options[:css]} task_todo'>&nbsp;</div>".html_safe
-
-          if coords[:bar_late_end]
-            output << "<div style='top:#{ params[:top] }px;left:#{ coords[:bar_start] }px;width:#{ coords[:bar_late_end] - coords[:bar_start] - 2}px;' class='#{options[:css]} task_late'>&nbsp;</div>".html_safe
-          end
-          if coords[:bar_progress_end]
-            output << "<div style='top:#{ params[:top] }px;left:#{ coords[:bar_start] }px;width:#{ coords[:bar_progress_end] - coords[:bar_start] - 2}px;' class='#{options[:css]} task_done'>&nbsp;</div>".html_safe
-          end
-        end
-        # Renders the markers
-        if options[:markers]
-          if coords[:start]
-            output << "<div style='top:#{ params[:top] }px;left:#{ coords[:start] }px;width:15px;' class='#{options[:css]} marker starting'>&nbsp;</div>".html_safe
-          end
-          if coords[:end]
-            output << "<div style='top:#{ params[:top] }px;left:#{ coords[:end] + params[:zoom] }px;width:15px;' class='#{options[:css]} marker ending'>&nbsp;</div>".html_safe
-          end
-        end
-        # Renders the label on the right
-        if options[:label]
-          output << "<div style='top:#{ params[:top] }px;left:#{ (coords[:bar_end] || 0) + 8 }px;' class='#{options[:css]} label'>".html_safe
-          output << options[:label]
-          output << "</div>".html_safe
-        end
-        # Renders the tooltip
-        if options[:issue] && coords[:bar_start] && coords[:bar_end]
-          output << "<div class='tooltip' style='position: absolute;top:#{ params[:top] }px;left:#{ coords[:bar_start] }px;width:#{ coords[:bar_end] - coords[:bar_start] }px;height:12px;'>".html_safe
-          output << '<span class="tip">'.html_safe
-          output << view.render_issue_tooltip(options[:issue]).html_safe
-          output << "</span></div>".html_safe
-        end
-        @lines << output
-        output
-      end
-
-      def pdf_task(params, coords, options={})
-        height = options[:height] || 2
-
-        # Renders the task bar, with progress and late
-        if coords[:bar_start] && coords[:bar_end]
-          params[:pdf].SetY(params[:top]+1.5)
-          params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
-          params[:pdf].SetFillColor(200,200,200)
-          params[:pdf].RDMCell(coords[:bar_end] - coords[:bar_start], height, "", 0, 0, "", 1)
-
-          if coords[:bar_late_end]
-            params[:pdf].SetY(params[:top]+1.5)
-            params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
-            params[:pdf].SetFillColor(255,100,100)
-            params[:pdf].RDMCell(coords[:bar_late_end] - coords[:bar_start], height, "", 0, 0, "", 1)
-          end
-          if coords[:bar_progress_end]
-            params[:pdf].SetY(params[:top]+1.5)
-            params[:pdf].SetX(params[:subject_width] + coords[:bar_start])
-            params[:pdf].SetFillColor(90,200,90)
-            params[:pdf].RDMCell(coords[:bar_progress_end] - coords[:bar_start], height, "", 0, 0, "", 1)
-          end
-        end
-        # Renders the markers
-        if options[:markers]
-          if coords[:start]
-            params[:pdf].SetY(params[:top] + 1)
-            params[:pdf].SetX(params[:subject_width] + coords[:start] - 1)
-            params[:pdf].SetFillColor(50,50,200)
-            params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1)
-          end
-          if coords[:end]
-            params[:pdf].SetY(params[:top] + 1)
-            params[:pdf].SetX(params[:subject_width] + coords[:end] - 1)
-            params[:pdf].SetFillColor(50,50,200)
-            params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1)
-          end
-        end
-        # Renders the label on the right
-        if options[:label]
-          params[:pdf].SetX(params[:subject_width] + (coords[:bar_end] || 0) + 5)
-          params[:pdf].RDMCell(30, 2, options[:label])
-        end
-      end
-
-      def image_task(params, coords, options={})
-        height = options[:height] || 6
-
-        # Renders the task bar, with progress and late
-        if coords[:bar_start] && coords[:bar_end]
-          params[:image].fill('#aaa')
-          params[:image].rectangle(params[:subject_width] + coords[:bar_start], params[:top], params[:subject_width] + coords[:bar_end], params[:top] - height)
-
-          if coords[:bar_late_end]
-            params[:image].fill('#f66')
-            params[:image].rectangle(params[:subject_width] + coords[:bar_start], params[:top], params[:subject_width] + coords[:bar_late_end], params[:top] - height)
-          end
-          if coords[:bar_progress_end]
-            params[:image].fill('#00c600')
-            params[:image].rectangle(params[:subject_width] + coords[:bar_start], params[:top], params[:subject_width] + coords[:bar_progress_end], params[:top] - height)
-          end
-        end
-        # Renders the markers
-        if options[:markers]
-          if coords[:start]
-            x = params[:subject_width] + coords[:start]
-            y = params[:top] - height / 2
-            params[:image].fill('blue')
-            params[:image].polygon(x-4, y, x, y-4, x+4, y, x, y+4)
-          end
-          if coords[:end]
-            x = params[:subject_width] + coords[:end] + params[:zoom]
-            y = params[:top] - height / 2
-            params[:image].fill('blue')
-            params[:image].polygon(x-4, y, x, y-4, x+4, y, x, y+4)
-          end
-        end
-        # Renders the label on the right
-        if options[:label]
-          params[:image].fill('black')
-          params[:image].text(params[:subject_width] + (coords[:bar_end] || 0) + 5,params[:top] + 1, options[:label])
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/10/105e4bad4371b49c4e052cc65ba6a1fae7edd15b.svn-base
--- a/.svn/pristine/10/105e4bad4371b49c4e052cc65ba6a1fae7edd15b.svn-base
+++ /dev/null
@@ -1,1009 +0,0 @@
-# Serbian translations for Redmine
-# by Vladimir MedaroviÄ‡ (vlada@medarovic.com)
-sr:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%d.%m.%Y."
-      short: "%e %b"
-      long: "%B %e, %Y"
-      
-    day_names: [Ð½ÐµÐ´ÐµÑ™Ð°, Ð¿Ð¾Ð½ÐµÐ´ÐµÑ™Ð°Ðº, ÑƒÑ‚Ð¾Ñ€Ð°Ðº, ÑÑ€ÐµÐ´Ð°, Ñ‡ÐµÑ‚Ð²Ñ€Ñ‚Ð°Ðº, Ð¿ÐµÑ‚Ð°Ðº, ÑÑƒÐ±Ð¾Ñ‚Ð°]
-    abbr_day_names: [Ð½ÐµÐ´, Ð¿Ð¾Ð½, ÑƒÑ‚Ð¾, ÑÑ€Ðµ, Ñ‡ÐµÑ‚, Ð¿ÐµÑ‚, ÑÑƒÐ±]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Ñ˜Ð°Ð½ÑƒÐ°Ñ€, Ñ„ÐµÐ±Ñ€ÑƒÐ°Ñ€, Ð¼Ð°Ñ€Ñ‚, Ð°Ð¿Ñ€Ð¸Ð», Ð¼Ð°Ñ˜, Ñ˜ÑƒÐ½, Ñ˜ÑƒÐ», Ð°Ð²Ð³ÑƒÑÑ‚, ÑÐµÐ¿Ñ‚ÐµÐ¼Ð±Ð°Ñ€, Ð¾ÐºÑ‚Ð¾Ð±Ð°Ñ€, Ð½Ð¾Ð²ÐµÐ¼Ð±Ð°Ñ€, Ð´ÐµÑ†ÐµÐ¼Ð±Ð°Ñ€]
-    abbr_month_names: [~, Ñ˜Ð°Ð½, Ñ„ÐµÐ±, Ð¼Ð°Ñ€, Ð°Ð¿Ñ€, Ð¼Ð°Ñ˜, Ñ˜ÑƒÐ½, Ñ˜ÑƒÐ», Ð°Ð²Ð³, ÑÐµÐ¿, Ð¾ÐºÑ‚, Ð½Ð¾Ð², Ð´ÐµÑ†]
-    # Used in date_select and datime_select.
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%d.%m.%Y. Ñƒ %H:%M"
-      time: "%H:%M"
-      short: "%d. %b Ñƒ %H:%M"
-      long: "%d. %B %Y Ñƒ %H:%M"
-    am: "am"
-    pm: "pm"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "Ð¿Ð¾Ð»Ð° Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
-      less_than_x_seconds:
-        one:   "Ð¼Ð°ÑšÐµ Ð¾Ð´ Ñ˜ÐµÐ´Ð½Ðµ ÑÐµÐºÑƒÐ½Ð´Ðµ"
-        other: "Ð¼Ð°ÑšÐµ Ð¾Ð´ %{count} ÑÐµÐº."
-      x_seconds:
-        one:   "Ñ˜ÐµÐ´Ð½Ð° ÑÐµÐºÑƒÐ½Ð´Ð°"
-        other: "%{count} ÑÐµÐº."
-      less_than_x_minutes:
-        one:   "Ð¼Ð°ÑšÐµ Ð¾Ð´ Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
-        other: "Ð¼Ð°ÑšÐµ Ð¾Ð´ %{count} Ð¼Ð¸Ð½."
-      x_minutes:
-        one:   "Ñ˜ÐµÐ´Ð°Ð½ Ð¼Ð¸Ð½ÑƒÑ‚"
-        other: "%{count} Ð¼Ð¸Ð½."
-      about_x_hours:
-        one:   "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ Ñ˜ÐµÐ´Ð°Ð½ ÑÐ°Ñ‚"
-        other: "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ %{count} ÑÐ°Ñ‚Ð¸"
-      x_days:
-        one:   "Ñ˜ÐµÐ´Ð°Ð½ Ð´Ð°Ð½"
-        other: "%{count} Ð´Ð°Ð½Ð°"
-      about_x_months:
-        one:   "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ Ñ˜ÐµÐ´Ð°Ð½ Ð¼ÐµÑÐµÑ†"
-        other: "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ %{count} Ð¼ÐµÑÐµÑ†Ð¸"
-      x_months:
-        one:   "Ñ˜ÐµÐ´Ð°Ð½ Ð¼ÐµÑÐµÑ†"
-        other: "%{count} Ð¼ÐµÑÐµÑ†Ð¸"
-      about_x_years:
-        one:   "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ Ð³Ð¾Ð´Ð¸Ð½Ñƒ Ð´Ð°Ð½Ð°"
-        other: "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ %{count} Ð³Ð¾Ð´."
-      over_x_years:
-        one:   "Ð¿Ñ€ÐµÐºÐ¾ Ð³Ð¾Ð´Ð¸Ð½Ñƒ Ð´Ð°Ð½Ð°"
-        other: "Ð¿Ñ€ÐµÐºÐ¾ %{count} Ð³Ð¾Ð´."
-      almost_x_years:
-        one:   "ÑÐºÐ¾Ñ€Ð¾ Ð³Ð¾Ð´Ð¸Ð½Ñƒ Ð´Ð°Ð½Ð°"
-        other: "ÑÐºÐ¾Ñ€Ð¾ %{count} Ð³Ð¾Ð´."
-
-  number:
-    format:
-      separator: ","
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "Ð¸"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "Ð½Ð¸Ñ˜Ðµ ÑƒÐºÑ™ÑƒÑ‡ÐµÐ½ Ñƒ ÑÐ¿Ð¸ÑÐ°Ðº"
-        exclusion: "Ñ˜Ðµ Ñ€ÐµÐ·ÐµÑ€Ð²Ð¸ÑÐ°Ð½"
-        invalid: "Ñ˜Ðµ Ð½ÐµÐ¸ÑÐ¿Ñ€Ð°Ð²Ð°Ð½"
-        confirmation: "Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ð° Ð½Ðµ Ð¾Ð´Ð³Ð¾Ð²Ð°Ñ€Ð°"
-        accepted: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¿Ñ€Ð¸Ñ…Ð²Ð°Ñ›ÐµÐ½"
-        empty: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
-        blank: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
-        too_long: "Ñ˜Ðµ Ð¿Ñ€ÐµÐ´ÑƒÐ³Ð°Ñ‡ÐºÐ° (Ð¼Ð°ÐºÑÐ¸Ð¼ÑƒÐ¼ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ñ˜Ðµ %{count})"
-        too_short: "Ñ˜Ðµ Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‚ÐºÐ° (Ð¼Ð¸Ð½Ð¸Ð¼ÑƒÐ¼ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ñ˜Ðµ %{count})"
-        wrong_length: "Ñ˜Ðµ Ð¿Ð¾Ð³Ñ€ÐµÑˆÐ½Ðµ Ð´ÑƒÐ¶Ð¸Ð½Ðµ (Ð±Ñ€Ð¾Ñ˜ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ %{count})"
-        taken: "Ñ˜Ðµ Ð²ÐµÑ› Ñƒ ÑƒÐ¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸"
-        not_a_number: "Ð½Ð¸Ñ˜Ðµ Ð±Ñ€Ð¾Ñ˜"
-        not_a_date: "Ð½Ð¸Ñ˜Ðµ Ð¸ÑÐ¿Ñ€Ð°Ð²Ð°Ð½ Ð´Ð°Ñ‚ÑƒÐ¼"
-        greater_than: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð²ÐµÑ›Ð¸ Ð¾Ð´ %{count}"
-        greater_than_or_equal_to: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð²ÐµÑ›Ð¸ Ð¸Ð»Ð¸ Ñ˜ÐµÐ´Ð½Ð°Ðº %{count}"
-        equal_to: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ñ˜ÐµÐ´Ð½Ð°Ðº %{count}"
-        less_than: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¼Ð°ÑšÐ¸ Ð¾Ð´ %{count}"
-        less_than_or_equal_to: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¼Ð°ÑšÐ¸ Ð¸Ð»Ð¸ Ñ˜ÐµÐ´Ð½Ð°Ðº %{count}"
-        odd: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¿Ð°Ñ€Ð°Ð½"
-        even: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð½ÐµÐ¿Ð°Ñ€Ð°Ð½"
-        greater_than_start_date: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð²ÐµÑ›Ð¸ Ð¾Ð´ Ð¿Ð¾Ñ‡ÐµÑ‚Ð½Ð¾Ð³ Ð´Ð°Ñ‚ÑƒÐ¼Ð°"
-        not_same_project: "Ð½Ðµ Ð¿Ñ€Ð¸Ð¿Ð°Ð´Ð° Ð¸ÑÑ‚Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ñƒ"
-        circular_dependency: "ÐžÐ²Ð° Ð²ÐµÐ·Ð° Ñ›Ðµ ÑÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ ÐºÑ€ÑƒÐ¶Ð½Ñƒ Ñ€ÐµÑ„ÐµÑ€ÐµÐ½Ñ†Ñƒ"
-        cant_link_an_issue_with_a_descendant: "ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½ ÑÐ° Ñ˜ÐµÐ´Ð½Ð¸Ð¼ Ð¾Ð´ ÑÐ²Ð¾Ñ˜Ð¸Ñ… Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‚Ð°ÐºÐ°"
-
-  actionview_instancetag_blank_option: ÐœÐ¾Ð»Ð¸Ð¼ Ð¾Ð´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ
-  
-  general_text_No: 'ÐÐµ'
-  general_text_Yes: 'Ð”Ð°'
-  general_text_no: 'Ð½Ðµ'
-  general_text_yes: 'Ð´Ð°'
-  general_lang_name: 'Ð¡Ñ€Ð¿ÑÐºÐ¸'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: ÐÐ°Ð»Ð¾Ð³ Ñ˜Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½.
-  notice_account_invalid_creditentials: ÐÐµÐ¸ÑÐ¿Ñ€Ð°Ð²Ð½Ð¾ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¾ Ð¸Ð¼Ðµ Ð¸Ð»Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°.
-  notice_account_password_updated: Ð›Ð¾Ð·Ð¸Ð½ÐºÐ° Ñ˜Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°.
-  notice_account_wrong_password: ÐŸÐ¾Ð³Ñ€ÐµÑˆÐ½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
-  notice_account_register_done: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³ Ñ˜Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½. ÐšÐ»Ð¸ÐºÐ½Ð¸Ñ‚Ðµ Ð½Ð° Ð»Ð¸Ð½Ðº ÐºÐ¾Ñ˜Ð¸ ÑÑ‚Ðµ Ð´Ð¾Ð±Ð¸Ð»Ð¸ Ñƒ Ðµ-Ð¿Ð¾Ñ€ÑƒÑ†Ð¸ Ð·Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ñƒ.
-  notice_account_unknown_email: ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ‚ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº.
-  notice_can_t_change_password: ÐžÐ²Ð°Ñ˜ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³ Ð·Ð° Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ñƒ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð° ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¸ ÑÐ¿Ð¾Ñ™Ð½Ð¸ Ð¸Ð·Ð²Ð¾Ñ€. ÐÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ñ˜Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸Ñ‚Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÑƒ.
-  notice_account_lost_email_sent: ÐŸÐ¾ÑÐ»Ð°Ñ‚Ð° Ð²Ð°Ð¼ Ñ˜Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐ° ÑÐ° ÑƒÐ¿ÑƒÑ‚ÑÑ‚Ð²Ð¾Ð¼ Ð·Ð° Ð¸Ð·Ð±Ð¾Ñ€ Ð½Ð¾Ð²Ðµ Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ
-  notice_account_activated: Ð’Ð°Ñˆ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³ Ñ˜Ðµ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½. Ð¡Ð°Ð´Ð° ÑÐµ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð¸Ñ‚Ð¸.
-  notice_successful_create: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ ÐºÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ.
-  notice_successful_update: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°ÑšÐµ.
-  notice_successful_delete: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð±Ñ€Ð¸ÑÐ°ÑšÐµ.
-  notice_successful_connection: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð¿Ð¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ.
-  notice_file_not_found: Ð¡Ñ‚Ñ€Ð°Ð½Ð° ÐºÐ¾Ñ˜Ð¾Ñ˜ Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð¸Ñ‚Ð¸ Ð½Ðµ Ð¿Ð¾ÑÑ‚Ð¾Ñ˜Ð¸ Ð¸Ð»Ð¸ Ñ˜Ðµ ÑƒÐºÐ»Ð¾ÑšÐµÐ½Ð°.
-  notice_locking_conflict: ÐŸÐ¾Ð´Ð°Ñ‚Ð°Ðº Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½ Ð¾Ð´ ÑÑ‚Ñ€Ð°Ð½Ðµ Ð´Ñ€ÑƒÐ³Ð¾Ð³ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ°.
-  notice_not_authorized: ÐÐ¸ÑÑ‚Ðµ Ð¾Ð²Ð»Ð°ÑˆÑ›ÐµÐ½Ð¸ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿ Ð¾Ð²Ð¾Ñ˜ ÑÑ‚Ñ€Ð°Ð½Ð¸.
-  notice_email_sent: "E-Ð¿Ð¾Ñ€ÑƒÐºÐ° Ñ˜Ðµ Ð¿Ð¾ÑÐ»Ð°Ñ‚Ð° Ð½Ð° %{value}"
-  notice_email_error: "Ð”Ð¾Ð³Ð¾Ð´Ð¸Ð»Ð° ÑÐµ Ð³Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸Ð»Ð¸ÐºÐ¾Ð¼ ÑÐ»Ð°ÑšÐ° Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ (%{value})"
-  notice_feeds_access_key_reseted: Ð’Ð°Ñˆ RSS Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ñ˜Ðµ Ð¿Ð¾Ð½Ð¸ÑˆÑ‚ÐµÐ½.
-  notice_api_access_key_reseted: Ð’Ð°Ñˆ API Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ñ˜Ðµ Ð¿Ð¾Ð½Ð¸ÑˆÑ‚ÐµÐ½.
-  notice_failed_to_save_issues: "ÐÐµÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑÐ½Ð¸Ð¼Ð°ÑšÐµ %{count} Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð¾Ð´ %{total} Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½Ð¸Ñ…: %{ids}."
-  notice_failed_to_save_members: "ÐÐµÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑÐ½Ð¸Ð¼Ð°ÑšÐµ Ñ‡Ð»Ð°Ð½Ð°(Ð¾Ð²Ð°): %{errors}."
-  notice_no_issue_selected: "ÐÐ¸ Ñ˜ÐµÐ´Ð°Ð½ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ Ð½Ð¸Ñ˜Ðµ Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½! ÐœÐ¾Ð»Ð¸Ð¼Ð¾, Ð¾Ð´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ ÐºÐ¾Ñ˜Ð¸ Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° Ð¼ÐµÑšÐ°Ñ‚Ðµ."
-  notice_account_pending: "Ð’Ð°Ñˆ Ð½Ð°Ð»Ð¾Ð³ Ñ˜Ðµ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½ Ð¸ Ñ‡ÐµÐºÐ° Ð½Ð° Ð¾Ð´Ð¾Ð±Ñ€ÐµÑšÐµ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð°."
-  notice_default_data_loaded: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ Ñ˜Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑƒÑ‡Ð¸Ñ‚Ð°Ð½Ð¾.
-  notice_unable_delete_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ñƒ Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸.
-  notice_unable_delete_time_entry: Ð¡Ñ‚Ð°Ð²ÐºÑƒ ÐµÐ²Ð¸Ð´ÐµÐ½Ñ†Ð¸Ñ˜Ðµ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð° Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸.
-  notice_issue_done_ratios_updated: ÐžÐ´Ð½Ð¾Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½.
-  
-  error_can_t_load_default_data: "ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ ÑƒÑ‡Ð¸Ñ‚Ð°Ñ‚Ð¸: %{value}"
-  error_scm_not_found: "Ð¡Ñ‚Ð°Ð²ÐºÐ° Ð¸Ð»Ð¸ Ð¸ÑÐ¿Ñ€Ð°Ð²ÐºÐ° Ð½Ð¸ÑÑƒ Ð¿Ñ€Ð¾Ð½Ð°Ñ’ÐµÐ½Ðµ Ñƒ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ñƒ."
-  error_scm_command_failed: "Ð“Ñ€ÐµÑˆÐºÐ° ÑÐµ Ñ˜Ð°Ð²Ð¸Ð»Ð° Ð¿Ñ€Ð¸Ð»Ð¸ÐºÐ¾Ð¼ Ð¿Ð¾ÐºÑƒÑˆÐ°Ñ˜Ð° Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð° ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ñƒ: %{value}"
-  error_scm_annotate: "Ð¡Ñ‚Ð°Ð²ÐºÐ° Ð½Ðµ Ð¿Ð¾ÑÑ‚Ð¾Ñ˜Ð¸ Ð¸Ð»Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð°."
-  error_issue_not_found_in_project: 'ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ð½Ð¸Ñ˜Ðµ Ð¿Ñ€Ð¾Ð½Ð°Ñ’ÐµÐ½ Ð¸Ð»Ð¸ Ð½Ðµ Ð¿Ñ€Ð¸Ð¿Ð°Ð´Ð° Ð¾Ð²Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ñƒ.'
-  error_no_tracker_in_project: 'ÐÐ¸ Ñ˜ÐµÐ´Ð½Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð½Ð¸Ñ˜Ðµ Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð¾ ÑÐ° Ð¾Ð²Ð¸Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¾Ð¼. ÐœÐ¾Ð»Ð¸Ð¼Ð¾ Ð¿Ñ€Ð¾Ð²ÐµÑ€Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´ÐµÑˆÐ°Ð²Ð°ÑšÐ° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°.'
-  error_no_default_issue_status: 'ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð½Ð¸Ñ˜Ðµ Ð´ÐµÑ„Ð¸Ð½Ð¸ÑÐ°Ð½. ÐœÐ¾Ð»Ð¸Ð¼Ð¾ Ð¿Ñ€Ð¾Ð²ÐµÑ€Ð¸Ñ‚Ðµ Ð²Ð°ÑˆÐµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ (Ð¸Ð´Ð¸Ñ‚Ðµ Ð½Ð° "ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð° -> Ð¡Ñ‚Ð°Ñ‚ÑƒÑÐ¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°").'
-  error_can_not_delete_custom_field: ÐÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ñ˜Ðµ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸ Ð¿Ñ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð¾ Ð¿Ð¾Ñ™Ðµ
-  error_can_not_delete_tracker: "ÐžÐ²Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ ÑÐ°Ð´Ñ€Ð¶Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ðµ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¾Ð±Ñ€Ð¸ÑÐ°Ð½Ð¾."
-  error_can_not_remove_role: "ÐžÐ²Ð° ÑƒÐ»Ð¾Ð³Ð° Ñ˜Ðµ Ñƒ ÑƒÐ¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¾Ð±Ñ€Ð¸ÑÐ°Ð½Ð°."
-  error_can_not_reopen_issue_on_closed_version: 'ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½ Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¾Ñ˜ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½'
-  error_can_not_archive_project: ÐžÐ²Ð°Ñ˜ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚ ÑÐµ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ñ‚Ð¸
-  error_issue_done_ratios_not_updated: "ÐžÐ´Ð½Ð¾Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð½Ð¸Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½."
-  error_workflow_copy_source: 'ÐœÐ¾Ð»Ð¸Ð¼Ð¾ Ð¾Ð´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¸Ð·Ð²Ð¾Ñ€Ð½Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð¸Ð»Ð¸ ÑƒÐ»Ð¾Ð³Ñƒ'
-  error_workflow_copy_target: 'ÐœÐ¾Ð»Ð¸Ð¼Ð¾ Ð¾Ð´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¾Ð´Ñ€ÐµÐ´Ð¸ÑˆÐ½Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð¸ ÑƒÐ»Ð¾Ð³Ñƒ'
-  error_unable_delete_issue_status: 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ð¾Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸'
-  error_unable_to_connect: "ÐŸÐ¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ ÑÐ° (%{value}) Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ"  
-  warning_attachments_not_saved: "%{count} Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ° Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ ÑÐ½Ð¸Ð¼Ñ™ÐµÐ½Ð°."
-  
-  mail_subject_lost_password: "Ð’Ð°ÑˆÐ° %{value} Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°"
-  mail_body_lost_password: 'Ð—Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñƒ Ð²Ð°ÑˆÐµ Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ, ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ‚Ðµ Ð½Ð° ÑÐ»ÐµÐ´ÐµÑ›Ð¸ Ð»Ð¸Ð½Ðº:'
-  mail_subject_register: "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð²Ð°ÑˆÐµÐ³ %{value} Ð½Ð°Ð»Ð¾Ð³Ð°"
-  mail_body_register: 'Ð—Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ñƒ Ð²Ð°ÑˆÐµÐ³ Ð½Ð°Ð»Ð¾Ð³Ð°, ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ‚Ðµ Ð½Ð° ÑÐ»ÐµÐ´ÐµÑ›Ð¸ Ð»Ð¸Ð½Ðº:'
-  mail_body_account_information_external: "Ð’Ð°Ñˆ Ð½Ð°Ð»Ð¾Ð³ %{value} Ð¼Ð¾Ð¶ÐµÑ‚Ðµ ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¸Ñ‚Ð¸ Ð·Ð° Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñƒ."
-  mail_body_account_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ðµ Ð¾ Ð²Ð°ÑˆÐµÐ¼ Ð½Ð°Ð»Ð¾Ð³Ñƒ
-  mail_subject_account_activation_request: "Ð—Ð°Ñ…Ñ‚ÐµÐ² Ð·Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ñƒ Ð½Ð°Ð»Ð¾Ð³Ð° %{value}"
-  mail_body_account_activation_request: "ÐÐ¾Ð²Ð¸ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº (%{value}) Ñ˜Ðµ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½. ÐÐ°Ð»Ð¾Ð³ Ñ‡ÐµÐºÐ° Ð½Ð° Ð²Ð°ÑˆÐµ Ð¾Ð´Ð¾Ð±Ñ€ÐµÑšÐµ:"
-  mail_subject_reminder: "%{count} Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð´Ð¾ÑÐ¿ÐµÐ²Ð° Ð½Ð°Ñ€ÐµÐ´Ð½Ð¸Ñ… %{days} Ð´Ð°Ð½Ð°"
-  mail_body_reminder: "%{count} Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ð¸Ñ… Ð²Ð°Ð¼Ð° Ð´Ð¾ÑÐ¿ÐµÐ²Ð° Ñƒ Ð½Ð°Ñ€ÐµÐ´Ð½Ð¸Ñ… %{days} Ð´Ð°Ð½Ð°:"
-  mail_subject_wiki_content_added: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° '%{id}' Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚Ð°"
-  mail_body_wiki_content_added: "%{author} Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ð¾ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ '%{id}'."
-  mail_subject_wiki_content_updated: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° '%{id}' Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°"
-  mail_body_wiki_content_updated: "%{author} Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð¾ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ '%{id}'."
-  
-  gui_validation_error: Ñ˜ÐµÐ´Ð½Ð° Ð³Ñ€ÐµÑˆÐºÐ°
-  gui_validation_error_plural: "%{count} Ð³Ñ€ÐµÑˆÐ°ÐºÐ°"
-  
-  field_name: ÐÐ°Ð·Ð¸Ð²
-  field_description: ÐžÐ¿Ð¸Ñ
-  field_summary: Ð ÐµÐ·Ð¸Ð¼Ðµ
-  field_is_required: ÐžÐ±Ð°Ð²ÐµÐ·Ð½Ð¾
-  field_firstname: Ð˜Ð¼Ðµ
-  field_lastname: ÐŸÑ€ÐµÐ·Ð¸Ð¼Ðµ
-  field_mail: Ð•-Ð°Ð´Ñ€ÐµÑÐ°
-  field_filename: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  field_filesize: Ð’ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð°
-  field_downloads: ÐŸÑ€ÐµÑƒÐ·Ð¸Ð¼Ð°ÑšÐ°
-  field_author: ÐÑƒÑ‚Ð¾Ñ€
-  field_created_on: ÐšÑ€ÐµÐ¸Ñ€Ð°Ð½Ð¾
-  field_updated_on: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾
-  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
-  field_is_for_all: Ð—Ð° ÑÐ²Ðµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ðµ
-  field_possible_values: ÐœÐ¾Ð³ÑƒÑ›Ðµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸
-  field_regexp: Ð ÐµÐ³ÑƒÐ»Ð°Ñ€Ð°Ð½ Ð¸Ð·Ñ€Ð°Ð·
-  field_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑƒÐ¶Ð¸Ð½Ð°
-  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑƒÐ¶Ð¸Ð½Ð°
-  field_value: Ð’Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
-  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
-  field_title: ÐÐ°ÑÐ»Ð¾Ð²
-  field_project: ÐŸÑ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
-  field_issue: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼
-  field_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ
-  field_notes: Ð‘ÐµÐ»ÐµÑˆÐºÐµ
-  field_is_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼
-  field_is_default: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
-  field_tracker: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ
-  field_subject: ÐŸÑ€ÐµÐ´Ð¼ÐµÑ‚
-  field_due_date: ÐšÑ€Ð°Ñ˜ÑšÐ¸ Ñ€Ð¾Ðº
-  field_assigned_to: Ð”Ð¾Ð´ÐµÑ™ÐµÐ½Ð¾
-  field_priority: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
-  field_fixed_version: ÐžÐ´Ñ€ÐµÐ´Ð¸ÑˆÐ½Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
-  field_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
-  field_principal: Ð“Ð»Ð°Ð²Ð½Ð¸
-  field_role: Ð£Ð»Ð¾Ð³Ð°
-  field_homepage: ÐŸÐ¾Ñ‡ÐµÑ‚Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  field_is_public: ÐˆÐ°Ð²Ð½Ð¾ Ð¾Ð±Ñ˜Ð°Ð²Ñ™Ð¸Ð²Ð°ÑšÐµ
-  field_parent: ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚ Ð¾Ð´
-  field_is_in_roadmap: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ð¸ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸ Ñƒ Ð¿Ð»Ð°Ð½Ñƒ Ñ€Ð°Ð´Ð°
-  field_login: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¾ Ð¸Ð¼Ðµ
-  field_mail_notification: ÐžÐ±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐ° Ð¿ÑƒÑ‚ÐµÐ¼ Ðµ-Ð¿Ð¾ÑˆÑ‚Ðµ
-  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
-  field_last_login_on: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐµ Ð¿Ð¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ
-  field_language: ÐˆÐµÐ·Ð¸Ðº
-  field_effective_date: Ð”Ð°Ñ‚ÑƒÐ¼
-  field_password: Ð›Ð¾Ð·Ð¸Ð½ÐºÐ°
-  field_new_password: ÐÐ¾Ð²Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
-  field_password_confirmation: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ
-  field_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ð°
-  field_type: Ð¢Ð¸Ð¿
-  field_host: Ð“Ð»Ð°Ð²Ð½Ð¸ Ñ€Ð°Ñ‡ÑƒÐ½Ð°Ñ€
-  field_port: ÐŸÐ¾Ñ€Ñ‚
-  field_account: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³
-  field_base_dn: Ð‘Ð°Ð·Ð½Ð¸ DN
-  field_attr_login: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™Ð¸Ð²Ð°ÑšÐ°
-  field_attr_firstname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð¸Ð¼ÐµÐ½Ð°
-  field_attr_lastname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð¿Ñ€ÐµÐ·Ð¸Ð¼ÐµÐ½Ð°
-  field_attr_mail: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ðµ-Ð°Ð´Ñ€ÐµÑÐµ
-  field_onthefly: ÐšÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ° Ñƒ Ñ‚Ð¾ÐºÑƒ Ñ€Ð°Ð´Ð°
-  field_start_date: ÐŸÐ¾Ñ‡ÐµÑ‚Ð°Ðº
-  field_done_ratio: "% ÑƒÑ€Ð°Ñ’ÐµÐ½Ð¾"
-  field_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
-  field_hide_mail: Ð¡Ð°ÐºÑ€Ð¸Ñ˜ Ð¼Ð¾Ñ˜Ñƒ Ðµ-Ð°Ð´Ñ€ÐµÑÑƒ
-  field_comments: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  field_url: URL
-  field_start_page: ÐŸÐ¾Ñ‡ÐµÑ‚Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  field_subproject: ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
-  field_hours: ÑÐ°Ñ‚Ð¸
-  field_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
-  field_spent_on: Ð”Ð°Ñ‚ÑƒÐ¼
-  field_identifier: Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€
-  field_is_filter: Ð£Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸ ÐºÐ°Ð¾ Ñ„Ð¸Ð»Ñ‚ÐµÑ€
-  field_issue_to: Ð¡Ñ€Ð¾Ð´Ð½Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
-  field_delay: ÐšÐ°ÑˆÑšÐµÑšÐµ
-  field_assignable: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½ Ð¾Ð²Ð¾Ñ˜ ÑƒÐ»Ð¾Ð·Ð¸
-  field_redirect_existing_links: ÐŸÑ€ÐµÑƒÑÐ¼ÐµÑ€Ð¸ Ð¿Ð¾ÑÑ‚Ð¾Ñ˜ÐµÑ›Ðµ Ð²ÐµÐ·Ðµ
-  field_estimated_hours: ÐŸÑ€Ð¾Ñ‚ÐµÐºÐ»Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  field_column_names: ÐšÐ¾Ð»Ð¾Ð½Ðµ
-  field_time_zone: Ð’Ñ€ÐµÐ¼ÐµÐ½ÑÐºÐ° Ð·Ð¾Ð½Ð°
-  field_searchable: ÐœÐ¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð¿Ñ€ÐµÑ‚Ñ€Ð°Ð¶ÑƒÑ˜Ðµ
-  field_default_value: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
-  field_comments_sorting: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ðµ
-  field_parent_title: ÐœÐ°Ñ‚Ð¸Ñ‡Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  field_editable: Ð˜Ð·Ð¼ÐµÐ½Ñ™Ð¸Ð²Ð¾
-  field_watcher: ÐŸÐ¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡
-  field_identity_url: OpenID URL
-  field_content: Ð¡Ð°Ð´Ñ€Ð¶Ð°Ñ˜
-  field_group_by: Ð“Ñ€ÑƒÐ¿Ð¸ÑÐ°ÑšÐµ Ñ€ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð° Ð¿Ð¾
-  field_sharing: Ð”ÐµÑ™ÐµÑšÐµ
-  field_parent_issue: ÐœÐ°Ñ‚Ð¸Ñ‡Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº
-  
-  setting_app_title: ÐÐ°ÑÐ»Ð¾Ð² Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ðµ
-  setting_app_subtitle: ÐŸÐ¾Ð´Ð½Ð°ÑÐ»Ð¾Ð² Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ðµ
-  setting_welcome_text: Ð¢ÐµÐºÑÑ‚ Ð´Ð¾Ð±Ñ€Ð¾Ð´Ð¾ÑˆÐ»Ð¸Ñ†Ðµ
-  setting_default_language: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¸ Ñ˜ÐµÐ·Ð¸Ðº
-  setting_login_required: ÐžÐ±Ð°Ð²ÐµÐ·Ð½Ð° Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ð° Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
-  setting_self_registration: Ð¡Ð°Ð¼Ð¾Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
-  setting_attachment_max_size: ÐœÐ°ÐºÑ. Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ðµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
-  setting_issues_export_limit: ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÑšÐµ Ð¸Ð·Ð²Ð¾Ð·Ð° â€žÐ¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°â€œ
-  setting_mail_from: Ð•-Ð°Ð´Ñ€ÐµÑÐ° Ð¿Ð¾ÑˆÐ¸Ñ™Ð°Ð¾Ñ†Ð°
-  setting_bcc_recipients: ÐŸÑ€Ð¸Ð¼Ð°Ð¾Ñ†Ð¸ â€žBccâ€œ ÐºÐ¾Ð¿Ð¸Ñ˜Ðµ
-  setting_plain_text_mail: ÐŸÐ¾Ñ€ÑƒÐºÐ° ÑÐ° Ñ‡Ð¸ÑÑ‚Ð¸Ð¼ Ñ‚ÐµÐºÑÑ‚Ð¾Ð¼ (Ð±ÐµÐ· HTML-Ð°)
-  setting_host_name: ÐŸÑƒÑ‚Ð°ÑšÐ° Ð¸ Ð½Ð°Ð·Ð¸Ð² Ð³Ð»Ð°Ð²Ð½Ð¾Ð³ Ñ€Ð°Ñ‡ÑƒÐ½Ð°Ñ€Ð°
-  setting_text_formatting: ÐžÐ±Ð»Ð¸ÐºÐ¾Ð²Ð°ÑšÐµ Ñ‚ÐµÐºÑÑ‚Ð°
-  setting_wiki_compression: ÐšÐ¾Ð¼Ð¿Ñ€ÐµÑÐ¸Ñ˜Ð° Wiki Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ðµ
-  setting_feeds_limit: ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÑšÐµ ÑÐ°Ð´Ñ€Ð¶Ð°Ñ˜Ð° Ð¸Ð·Ð²Ð¾Ñ€Ð° Ð²ÐµÑÑ‚Ð¸
-  setting_default_projects_public: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð° ÑÐµ Ñ˜Ð°Ð²Ð½Ð¾ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð¸Ð²Ð°ÑšÐµ Ð½Ð¾Ð²Ð¸Ñ… Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°
-  setting_autofetch_changesets: Ð˜Ð·Ð²Ñ€ÑˆÐ°Ð²Ð°ÑšÐµ Ð°ÑƒÑ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ¾Ð³ Ð¿Ñ€ÐµÑƒÐ·Ð¸Ð¼Ð°ÑšÐ°
-  setting_sys_api_enabled: ÐžÐ¼Ð¾Ð³ÑƒÑ›Ð°Ð²Ð°ÑšÐµ WS Ð·Ð° ÑƒÐ¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚ÐµÐ¼
-  setting_commit_ref_keywords: Ð ÐµÑ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ€Ð°ÑšÐµ ÐºÑ™ÑƒÑ‡Ð½Ð¸Ñ… Ñ€ÐµÑ‡Ð¸
-  setting_commit_fix_keywords: ÐŸÐ¾Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ ÐºÑ™ÑƒÑ‡Ð½Ð¸Ñ… Ñ€ÐµÑ‡Ð¸
-  setting_autologin: ÐÑƒÑ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ° Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð°
-  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð´Ð°Ñ‚ÑƒÐ¼Ð°
-  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
-  setting_cross_project_issue_relations: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸ Ð¿Ð¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð¸Ð· ÑƒÐ½Ð°ÐºÑ€ÑÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°
-  setting_issue_list_default_columns: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ðµ ÐºÐ¾Ð»Ð¾Ð½Ðµ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ðµ Ð½Ð° ÑÐ¿Ð¸ÑÐºÑƒ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  setting_emails_footer: ÐŸÐ¾Ð´Ð½Ð¾Ð¶Ñ˜Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
-  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
-  setting_per_page_options: ÐžÐ¿Ñ†Ð¸Ñ˜Ðµ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð° Ð¾Ð±Ñ˜ÐµÐºÐ°Ñ‚Ð° Ð¿Ð¾ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  setting_user_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ°
-  setting_activity_days_default: Ð‘Ñ€Ð¾Ñ˜ Ð´Ð°Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸Ñ… Ð½Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð½Ð¾Ñ˜ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð¸
-  setting_display_subprojects_issues: ÐŸÑ€Ð¸ÐºÐ°Ð·ÑƒÑ˜ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ðµ Ð¸Ð· Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð° Ð½Ð° Ð³Ð»Ð°Ð²Ð½Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ñƒ, ÑƒÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð½Ð¸Ñ˜Ðµ Ð´Ñ€ÑƒÐ³Ð°Ñ‡Ð¸Ñ˜Ðµ Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾
-  setting_enabled_scm: ÐžÐ¼Ð¾Ð³ÑƒÑ›Ð°Ð²Ð°ÑšÐµ SCM
-  setting_mail_handler_body_delimiters: "Ð¡ÐºÑ€Ð°Ñ›Ð¸Ð²Ð°ÑšÐµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ Ð½Ð°ÐºÐ¾Ð½ Ñ˜ÐµÐ´Ð½Ðµ Ð¾Ð´ Ð¾Ð²Ð¸Ñ… Ð»Ð¸Ð½Ð¸Ñ˜Ð°"
-  setting_mail_handler_api_enabled: ÐžÐ¼Ð¾Ð³ÑƒÑ›Ð°Ð²Ð°ÑšÐµ WS Ð´Ð¾Ð»Ð°Ð·Ð½Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
-  setting_mail_handler_api_key: API ÐºÑ™ÑƒÑ‡
-  setting_sequential_project_identifiers: Ð“ÐµÐ½ÐµÑ€Ð¸ÑÐ°ÑšÐµ ÑÐµÐºÐ²ÐµÐ½Ñ†Ð¸Ñ˜Ð°Ð»Ð½Ð¾Ð³ Ð¸Ð¼ÐµÐ½Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
-  setting_gravatar_enabled: ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸ Gravatar ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐµ Ð¸ÐºÐ¾Ð½Ðµ
-  setting_gravatar_default: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð° Gravatar ÑÐ»Ð¸ÐºÐ°
-  setting_diff_max_lines_displayed: ÐœÐ°ÐºÑ. Ð±Ñ€Ð¾Ñ˜ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸Ñ… Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð¸Ñ‚Ð¸Ñ… Ð»Ð¸Ð½Ð¸Ñ˜Ð°
-  setting_file_max_size_displayed: ÐœÐ°ÐºÑ. Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ñ‚ÐµÐºÑÑ‚. Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸Ñ… ÑƒÐ¼ÐµÑ‚Ð½ÑƒÑ‚Ð¾
-  setting_repository_log_display_limit: ÐœÐ°ÐºÑ. Ð±Ñ€Ð¾Ñ˜ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸Ñ… Ñƒ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÑ†Ð¸ Ð·Ð° ÐµÐ²Ð¸Ð´ÐµÐ½Ñ†Ð¸Ñ˜Ñƒ
-  setting_openid: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸ OpenID Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñƒ Ð¸ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ñƒ
-  setting_password_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑƒÐ¶Ð¸Ð½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ
-  setting_new_project_user_role_id: ÐšÑ€ÐµÐ°Ñ‚Ð¾Ñ€Ñƒ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð° (ÐºÐ¾Ñ˜Ð¸ Ð½Ð¸Ñ˜Ðµ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€) Ð´Ð¾Ð´ÐµÑ™ÑƒÑ˜Ðµ Ñ˜Ðµ ÑƒÐ»Ð¾Ð³Ð°
-  setting_default_projects_modules: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ Ð¾Ð¼Ð¾Ð³ÑƒÑ›ÐµÐ½Ð¸ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð·Ð° Ð½Ð¾Ð²Ðµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ðµ
-  setting_issue_done_ratio: Ð˜Ð·Ñ€Ð°Ñ‡ÑƒÐ½Ð°Ñ˜ Ð¾Ð´Ð½Ð¾Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  setting_issue_done_ratio_issue_field: ÐºÐ¾Ñ€Ð¸ÑÑ‚ÐµÑ›Ð¸ Ð¿Ð¾Ñ™Ðµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  setting_issue_done_ratio_issue_status: ÐºÐ¾Ñ€Ð¸ÑÑ‚ÐµÑ›Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  setting_start_of_week: ÐŸÑ€Ð²Ð¸ Ð´Ð°Ð½ Ñƒ ÑÐµÐ´Ð¼Ð¸Ñ†Ð¸
-  setting_rest_api_enabled: ÐžÐ¼Ð¾Ð³ÑƒÑ›Ð¸ REST web ÑƒÑÐ»ÑƒÐ³Ðµ
-  setting_cache_formatted_text: ÐšÐµÑˆÐ¸Ñ€Ð°ÑšÐµ Ð¾Ð±Ñ€Ð°Ñ’ÐµÐ½Ð¾Ð³ Ñ‚ÐµÐºÑÑ‚Ð°
-  
-  permission_add_project: ÐšÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
-  permission_add_subprojects: ÐšÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ Ð¿Ð¾Ñ‚Ð¿Ð¾Ñ˜ÐµÐºÑ‚Ð°
-  permission_edit_project: Ð˜Ð·Ð¼ÐµÐ½Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°
-  permission_select_project_modules: ÐžÐ´Ð°Ð±Ð¸Ñ€Ð°ÑšÐµ Ð¼Ð¾Ð´ÑƒÐ»Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
-  permission_manage_members: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ñ‡Ð»Ð°Ð½Ð¾Ð²Ð¸Ð¼Ð°
-  permission_manage_project_activities: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð½Ð¸Ð¼ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð¸Ð¼Ð°
-  permission_manage_versions: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°Ð¼Ð°
-  permission_manage_categories: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°Ð¼Ð° Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  permission_view_issues: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  permission_add_issues: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  permission_edit_issues: Ð˜Ð·Ð¼ÐµÐ½Ð° Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  permission_manage_issue_relations: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð²ÐµÐ·Ð°Ð¼Ð° Ð¸Ð·Ð¼ÐµÑ’Ñƒ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  permission_add_issue_notes: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ð±ÐµÐ»ÐµÑˆÐºÐ¸
-  permission_edit_issue_notes: Ð˜Ð·Ð¼ÐµÐ½Ð° Ð±ÐµÐ»ÐµÑˆÐºÐ¸
-  permission_edit_own_issue_notes: Ð˜Ð·Ð¼ÐµÐ½Ð° ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸Ñ… Ð±ÐµÐ»ÐµÑˆÐºÐ¸
-  permission_move_issues: ÐŸÐ¾Ð¼ÐµÑ€Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  permission_delete_issues: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  permission_manage_public_queries: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ñ˜Ð°Ð²Ð½Ð¸Ð¼ ÑƒÐ¿Ð¸Ñ‚Ð¸Ð¼Ð°
-  permission_save_queries: Ð¡Ð½Ð¸Ð¼Ð°ÑšÐµ ÑƒÐ¿Ð¸Ñ‚Ð°
-  permission_view_gantt: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð“Ð°Ð½Ñ‚Ð¾Ð²Ð¾Ð³ Ð´Ð¸Ñ˜Ð°Ð³Ñ€Ð°Ð¼Ð°
-  permission_view_calendar: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ð°
-  permission_view_issue_watchers: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÑÐ¿Ð¸ÑÐºÐ° Ð¿Ð¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡Ð°
-  permission_add_issue_watchers: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ð¿Ð¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡Ð°
-  permission_delete_issue_watchers: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð¿Ð¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡Ð°
-  permission_log_time: Ð‘ÐµÐ»ÐµÐ¶ÐµÑšÐµ ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾Ð³ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
-  permission_view_time_entries: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾Ð³ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
-  permission_edit_time_entries: Ð˜Ð·Ð¼ÐµÐ½Ð° ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾Ð³ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
-  permission_edit_own_time_entries: Ð˜Ð·Ð¼ÐµÐ½Ð° ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¾Ð³ ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾Ð³ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
-  permission_manage_news: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð²ÐµÑÑ‚Ð¸Ð¼Ð°
-  permission_comment_news: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÑÐ°ÑšÐµ Ð²ÐµÑÑ‚Ð¸
-  permission_manage_documents: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸Ð¼Ð°
-  permission_view_documents: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ð°Ñ‚Ð°
-  permission_manage_files: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°Ð¼Ð°
-  permission_view_files: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  permission_manage_wiki: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ð¼Ð°
-  permission_rename_wiki_pages: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð° Ð¸Ð¼ÐµÐ½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ð¼Ð°
-  permission_delete_wiki_pages: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  permission_view_wiki_pages: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  permission_view_wiki_edits: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ wiki Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ðµ
-  permission_edit_wiki_pages: Ð˜Ð·Ð¼ÐµÐ½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  permission_delete_wiki_pages_attachments: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ… Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  permission_protect_wiki_pages: Ð—Ð°ÑˆÑ‚Ð¸Ñ‚Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  permission_manage_repository: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚ÐµÐ¼
-  permission_browse_repository: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ð°
-  permission_view_changesets: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÑÐºÑƒÐ¿Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°
-  permission_commit_access: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð° Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð°
-  permission_manage_boards: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ñ„Ð¾Ñ€ÑƒÐ¼Ð¸Ð¼Ð°
-  permission_view_messages: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð¿Ð¾Ñ€ÑƒÐºÐ°
-  permission_add_messages: Ð¡Ð»Ð°ÑšÐµ Ð¿Ð¾Ñ€ÑƒÐºÐ°
-  permission_edit_messages: Ð˜Ð·Ð¼ÐµÐ½Ð° Ð¿Ð¾Ñ€ÑƒÐºÐ°
-  permission_edit_own_messages: Ð˜Ð·Ð¼ÐµÐ½Ð° ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸Ñ… Ð¿Ð¾Ñ€ÑƒÐºÐ°
-  permission_delete_messages: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð¿Ð¾Ñ€ÑƒÐºÐ°
-  permission_delete_own_messages: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸Ñ… Ð¿Ð¾Ñ€ÑƒÐºÐ°
-  permission_export_wiki_pages: Ð˜Ð·Ð²Ð¾Ð· wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  permission_manage_subtasks: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ†Ð¸Ð¼Ð°
-  
-  project_module_issue_tracking: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  project_module_time_tracking: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
-  project_module_news: Ð’ÐµÑÑ‚Ð¸
-  project_module_documents: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  project_module_files: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
-  project_module_wiki: Wiki
-  project_module_repository: Ð¡Ð¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ðµ
-  project_module_boards: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
-  
-  label_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
-  label_user_plural: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸
-  label_user_new: ÐÐ¾Ð²Ð¸ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
-  label_user_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼Ð°Ð½
-  label_project: ÐŸÑ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
-  label_project_new: ÐÐ¾Ð²Ð¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
-  label_project_plural: ÐŸÑ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
-  label_x_projects:
-    zero:  Ð½ÐµÐ¼Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°
-    one:   Ñ˜ÐµÐ´Ð°Ð½ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
-    other: "%{count} Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°"
-  label_project_all: Ð¡Ð²Ð¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
-  label_project_latest: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐ¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
-  label_issue: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼
-  label_issue_new: ÐÐ¾Ð²Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼
-  label_issue_plural: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
-  label_issue_view_all: ÐŸÑ€Ð¸ÐºÐ°Ð· ÑÐ²Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  label_issues_by: "ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ð¸ (%{value})"
-  label_issue_added: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚
-  label_issue_updated: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½
-  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_new: ÐÐ¾Ð²Ð¸ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  label_document_added: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚ Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚
-  label_role: Ð£Ð»Ð¾Ð³Ð°
-  label_role_plural: Ð£Ð»Ð¾Ð³Ðµ
-  label_role_new: ÐÐ¾Ð²Ð° ÑƒÐ»Ð¾Ð³Ð°
-  label_role_and_permissions: Ð£Ð»Ð¾Ð³Ðµ Ð¸ Ð´Ð¾Ð·Ð²Ð¾Ð»Ðµ
-  label_member: Ð§Ð»Ð°Ð½
-  label_member_new: ÐÐ¾Ð²Ð¸ Ñ‡Ð»Ð°Ð½
-  label_member_plural: Ð§Ð»Ð°Ð½Ð¾Ð²Ð¸
-  label_tracker: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ
-  label_tracker_plural: ÐŸÑ€Ð°Ñ›ÐµÑšÐ°
-  label_tracker_new: ÐÐ¾Ð²Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ
-  label_workflow: Ð¢Ð¾Ðº Ð¿Ð¾ÑÐ»Ð°
-  label_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  label_issue_status_plural: Ð¡Ñ‚Ð°Ñ‚ÑƒÑÐ¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  label_issue_status_new: ÐÐ¾Ð²Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð° Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ðµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  label_issue_category_new: ÐÐ¾Ð²Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
-  label_custom_field: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð¾ Ð¿Ð¾Ñ™Ðµ
-  label_custom_field_plural: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð° Ð¿Ð¾Ñ™Ð°
-  label_custom_field_new: ÐÐ¾Ð²Ð¾ Ð¿Ñ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð¾ Ð¿Ð¾Ñ™Ðµ
-  label_enumerations: ÐÐ°Ð±Ñ€Ð¾Ñ˜Ð¸Ð²Ð° Ð»Ð¸ÑÑ‚Ð°
-  label_enumeration_new: ÐÐ¾Ð²Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
-  label_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ð°
-  label_information_plural: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ðµ
-  label_please_login: ÐœÐ¾Ð»Ð¸Ð¼Ð¾, Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð¸Ñ‚Ðµ ÑÐµ
-  label_register: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
-  label_login_with_open_id_option: Ð¸Ð»Ð¸ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð° ÑÐ° OpenID
-  label_password_lost: Ð˜Ð·Ð³ÑƒÐ±Ñ™ÐµÐ½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
-  label_home: ÐŸÐ¾Ñ‡ÐµÑ‚Ð°Ðº
-  label_my_page: ÐœÐ¾Ñ˜Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  label_my_account: ÐœÐ¾Ñ˜ Ð½Ð°Ð»Ð¾Ð³
-  label_my_projects: ÐœÐ¾Ñ˜Ð¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
-  label_my_page_block: My page block
-  label_administration: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
-  label_login: ÐŸÑ€Ð¸Ñ˜Ð°Ð²Ð°
-  label_logout: ÐžÐ´Ñ˜Ð°Ð²Ð°
-  label_help: ÐŸÐ¾Ð¼Ð¾Ñ›
-  label_reported_issues: ÐŸÑ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
-  label_assigned_to_me_issues: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ð¸ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ð¸ Ð¼ÐµÐ½Ð¸
-  label_last_login: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐµ Ð¿Ð¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ
-  label_registered_on: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½
-  label_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
-  label_overall_activity: Ð¦ÐµÐ»Ð¾ÐºÑƒÐ¿Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
-  label_user_activity: "ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ° %{value}"
-  label_new: ÐÐ¾Ð²Ð¾
-  label_logged_as: ÐŸÑ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ð¸ ÑÑ‚Ðµ ÐºÐ°Ð¾
-  label_environment: ÐžÐºÑ€ÑƒÐ¶ÐµÑšÐµ
-  label_authentication: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð° Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
-  label_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
-  label_auth_source_new: ÐÐ¾Ð²Ð¸ Ñ€ÐµÐ¶Ð¸Ð¼ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
-  label_auth_source_plural: Ð ÐµÐ¶Ð¸Ð¼Ð¸ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
-  label_subproject_plural: ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
-  label_subproject_new: ÐÐ¾Ð²Ð¸ Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
-  label_and_its_subprojects: "%{value} Ð¸ ÑšÐµÐ³Ð¾Ð²Ð¸ Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸"
-  label_min_max_length: ÐœÐ¸Ð½. - ÐœÐ°ÐºÑ. Ð´ÑƒÐ¶Ð¸Ð½Ð°
-  label_list: Ð¡Ð¿Ð¸ÑÐ°Ðº
-  label_date: Ð”Ð°Ñ‚ÑƒÐ¼
-  label_integer: Ð¦ÐµÐ¾ Ð±Ñ€Ð¾Ñ˜
-  label_float: Ð¡Ð° Ð¿Ð¾ÐºÑ€ÐµÑ‚Ð½Ð¸Ð¼ Ð·Ð°Ñ€ÐµÐ·Ð¾Ð¼
-  label_boolean: Ð›Ð¾Ð³Ð¸Ñ‡ÐºÐ¸ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€
-  label_string: Ð¢ÐµÐºÑÑ‚
-  label_text: Ð”ÑƒÐ³Ð¸ Ñ‚ÐµÐºÑÑ‚
-  label_attribute: ÐžÑÐ¾Ð±Ð¸Ð½Ð°
-  label_attribute_plural: ÐžÑÐ¾Ð±Ð¸Ð½Ðµ
-  label_download: "%{count} Ð¿Ñ€ÐµÑƒÐ·Ð¸Ð¼Ð°ÑšÐµ"
-  label_download_plural: "%{count} Ð¿Ñ€ÐµÑƒÐ·Ð¸Ð¼Ð°ÑšÐ°"
-  label_no_data: ÐÐµÐ¼Ð° Ð¿Ð¾Ð´Ð°Ñ‚Ð°ÐºÐ° Ð·Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð¸Ð²Ð°ÑšÐµ
-  label_change_status: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð° ÑÑ‚Ð°Ñ‚ÑƒÑÐ°
-  label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°
-  label_attachment: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  label_attachment_new: ÐÐ¾Ð²Ð° Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  label_attachment_delete: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
-  label_attachment_plural: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
-  label_file_added: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ° Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚Ð°
-  label_report: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ˜
-  label_report_plural: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ˜Ð¸
-  label_news: Ð’ÐµÑÑ‚Ð¸
-  label_news_new: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ð²ÐµÑÑ‚Ð¸
-  label_news_plural: Ð’ÐµÑÑ‚Ð¸
-  label_news_latest: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐµ Ð²ÐµÑÑ‚Ð¸
-  label_news_view_all: ÐŸÑ€Ð¸ÐºÐ°Ð· ÑÐ²Ð¸Ñ… Ð²ÐµÑÑ‚Ð¸
-  label_news_added: Ð’ÐµÑÑ‚Ð¸ ÑÑƒ Ð´Ð¾Ð´Ð°Ñ‚Ðµ
-  label_settings: ÐŸÐ¾Ð´ÐµÑˆÐ°Ð²Ð°ÑšÐ°
-  label_overview: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
-  label_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ð°
-  label_version_new: ÐÐ¾Ð²Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
-  label_version_plural: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ðµ
-  label_close_versions: Ð—Ð°Ñ‚Ð²Ð¾Ñ€Ð¸ Ð·Ð°Ð²Ñ€ÑˆÐµÐ½Ðµ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ðµ
-  label_confirmation: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð°
-  label_export_to: 'Ð¢Ð°ÐºÐ¾Ñ’Ðµ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð½Ð¾ Ð¸ Ñƒ Ð²Ð°Ñ€Ð¸Ñ˜Ð°Ð½Ñ‚Ð¸:'
-  label_read: Ð§Ð¸Ñ‚Ð°ÑšÐµ...
-  label_public_projects: ÐˆÐ°Ð²Ð½Ð¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
-  label_open_issues: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½
-  label_open_issues_plural: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…
-  label_closed_issues: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½
-  label_closed_issues_plural: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…
-  label_x_open_issues_abbr_on_total:
-    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ… / %{total}
-    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½ / %{total}
-    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ… / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…
-    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½
-    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…"
-  label_x_closed_issues_abbr:
-    zero:  0 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…
-    one:   1 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½
-    other: "%{count} Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…"
-  label_total: Ð£ÐºÑƒÐ¿Ð½Ð¾
-  label_permissions: Ð”Ð¾Ð·Ð²Ð¾Ð»Ðµ
-  label_current_status: Ð¢Ñ€ÐµÐ½ÑƒÑ‚Ð½Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_new_statuses_allowed: ÐÐ¾Ð²Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸ Ð´Ð¾Ð·Ð²Ð¾Ñ™ÐµÐ½Ð¸
-  label_all: ÑÐ²Ð¸
-  label_none: Ð½Ð¸Ñ˜ÐµÐ´Ð°Ð½
-  label_nobody: Ð½Ð¸ÐºÐ¾Ð¼Ðµ
-  label_next: Ð¡Ð»ÐµÐ´ÐµÑ›Ðµ
-  label_previous: ÐŸÑ€ÐµÑ‚Ñ…Ð¾Ð´Ð½Ð¾
-  label_used_by: ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸Ð¾
-  label_details: Ð”ÐµÑ‚Ð°Ñ™Ð¸
-  label_add_note: Ð”Ð¾Ð´Ð°Ñ˜ Ð±ÐµÐ»ÐµÑˆÐºÑƒ
-  label_per_page: ÐŸÐ¾ ÑÑ‚Ñ€Ð°Ð½Ð¸
-  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
-  label_months_from: Ð¼ÐµÑÐµÑ†Ð¸ Ð¾Ð´
-  label_gantt: Ð“Ð°Ð½Ñ‚Ð¾Ð² Ð´Ð¸Ñ˜Ð°Ð³Ñ€Ð°Ð¼
-  label_internal: Ð£Ð½ÑƒÑ‚Ñ€Ð°ÑˆÑšÐ¸
-  label_last_changes: "Ð¿Ð¾ÑÐ»ÐµÐ´ÑšÐ¸Ñ… %{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°"
-  label_change_view_all: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸ ÑÐ²Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ðµ
-  label_personalize_page: ÐŸÐµÑ€ÑÐ¾Ð½Ð°Ð»Ð¸Ð·ÑƒÑ˜ Ð¾Ð²Ñƒ ÑÑ‚Ñ€Ð°Ð½Ñƒ
-  label_comment: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  label_comment_plural: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
-  label_x_comments:
-    zero: Ð±ÐµÐ· ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð°
-    one: Ñ˜ÐµÐ´Ð°Ð½ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-    other: "%{count} ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð°"
-  label_comment_add: Ð”Ð¾Ð´Ð°Ñ˜ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  label_comment_added: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€ Ð´Ð¾Ð´Ð°Ñ‚
-  label_comment_delete: ÐžÐ±Ñ€Ð¸ÑˆÐ¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ðµ
-  label_query: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½ ÑƒÐ¿Ð¸Ñ‚
-  label_query_plural: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð¸ ÑƒÐ¿Ð¸Ñ‚Ð¸
-  label_query_new: ÐÐ¾Ð²Ð¸ ÑƒÐ¿Ð¸Ñ‚
-  label_filter_add: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ñ„Ð¸Ð»Ñ‚ÐµÑ€Ð°
-  label_filter_plural: Ð¤Ð¸Ð»Ñ‚ÐµÑ€Ð¸
-  label_equals: Ñ˜Ðµ
-  label_not_equals: Ð½Ð¸Ñ˜Ðµ
-  label_in_less_than: Ð¼Ð°ÑšÐµ Ð¾Ð´
-  label_in_more_than: Ð²Ð¸ÑˆÐµ Ð¾Ð´
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: Ñƒ
-  label_today: Ð´Ð°Ð½Ð°Ñ
-  label_all_time: ÑÐ²Ðµ Ð²Ñ€ÐµÐ¼Ðµ
-  label_yesterday: Ñ˜ÑƒÑ‡Ðµ
-  label_this_week: Ð¾Ð²Ðµ ÑÐµÐ´Ð¼Ð¸Ñ†Ðµ
-  label_last_week: Ð¿Ð¾ÑÐ»ÐµÐ´ÑšÐµ ÑÐµÐ´Ð¼Ð¸Ñ†Ðµ
-  label_last_n_days: "Ð¿Ð¾ÑÐ»ÐµÐ´ÑšÐ¸Ñ… %{count} Ð´Ð°Ð½Ð°"
-  label_this_month: Ð¾Ð²Ð¾Ð³ Ð¼ÐµÑÐµÑ†Ð°
-  label_last_month: Ð¿Ð¾ÑÐ»ÐµÐ´ÑšÐµÐ³ Ð¼ÐµÑÐµÑ†Ð°
-  label_this_year: Ð¾Ð²Ðµ Ð³Ð¾Ð´Ð¸Ð½Ðµ
-  label_date_range: Ð’Ñ€ÐµÐ¼ÐµÐ½ÑÐºÐ¸ Ð¿ÐµÑ€Ð¸Ð¾Ð´
-  label_less_than_ago: Ð¿Ñ€Ðµ Ð¼Ð°ÑšÐµ Ð¾Ð´ Ð½ÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð´Ð°Ð½Ð°
-  label_more_than_ago: Ð¿Ñ€Ðµ Ð²Ð¸ÑˆÐµ Ð¾Ð´ Ð½ÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð´Ð°Ð½Ð°
-  label_ago: Ð¿Ñ€Ðµ Ð½ÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð´Ð°Ð½Ð°
-  label_contains: ÑÐ°Ð´Ñ€Ð¶Ð¸
-  label_not_contains: Ð½Ðµ ÑÐ°Ð´Ñ€Ð¶Ð¸
-  label_day_plural: Ð´Ð°Ð½Ð°
-  label_repository: Ð¡Ð¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ðµ
-  label_repository_plural: Ð¡Ð¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ð°
-  label_browse: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ
-  label_modification: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°"
-  label_modification_plural: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°"
-  label_branch: Ð“Ñ€Ð°Ð½Ð°
-  label_tag: ÐžÐ·Ð½Ð°ÐºÐ°
-  label_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
-  label_revision_plural: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ðµ
-  label_revision_id: "Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð° %{value}"
-  label_associated_revisions: ÐŸÑ€Ð¸Ð´Ñ€ÑƒÐ¶ÐµÐ½Ðµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ðµ
-  label_added: Ð´Ð¾Ð´Ð°Ñ‚Ð¾
-  label_modified: Ð¿Ñ€Ð¾Ð¼ÐµÑšÐµÐ½Ð¾
-  label_copied: ÐºÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ð¾
-  label_renamed: Ð¿Ñ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¾
-  label_deleted: Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ð½Ð¾
-  label_latest_revision: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐ° Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
-  label_latest_revision_plural: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ðµ
-  label_view_revisions: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
-  label_view_all_revisions: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ ÑÐ²Ð¸Ñ… Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
-  label_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð°
-  label_sort_highest: ÐŸÑ€ÐµÐ¼ÐµÑˆÑ‚Ð°ÑšÐµ Ð½Ð° Ð²Ñ€Ñ…
-  label_sort_higher: ÐŸÑ€ÐµÐ¼ÐµÑˆÑ‚Ð°ÑšÐµ Ð½Ð° Ð³Ð¾Ñ€Ðµ
-  label_sort_lower: ÐŸÑ€ÐµÐ¼ÐµÑˆÑ‚Ð°ÑšÐµ Ð½Ð° Ð´Ð¾Ð»Ðµ
-  label_sort_lowest: ÐŸÑ€ÐµÐ¼ÐµÑˆÑ‚Ð°ÑšÐµ Ð½Ð° Ð´Ð½Ð¾
-  label_roadmap: ÐŸÐ»Ð°Ð½ Ñ€Ð°Ð´Ð°
-  label_roadmap_due_in: "Ð”Ð¾ÑÐ¿ÐµÐ²Ð° %{value}"
-  label_roadmap_overdue: "%{value} Ð½Ð°Ñ˜ÐºÐ°ÑÐ½Ð¸Ñ˜Ðµ"
-  label_roadmap_no_issues: ÐÐµÐ¼Ð° Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð·Ð° Ð¾Ð²Ñƒ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ñƒ
-  label_search: ÐŸÑ€ÐµÑ‚Ñ€Ð°Ð³Ð°
-  label_result_plural: Ð ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸
-  label_all_words: Ð¡Ð²Ðµ Ñ€ÐµÑ‡Ð¸
-  label_wiki: Wiki
-  label_wiki_edit: Wiki Ð¸Ð·Ð¼ÐµÐ½Ð°
-  label_wiki_edit_plural: Wiki Ð¸Ð·Ð¼ÐµÐ½Ðµ
-  label_wiki_page: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  label_wiki_page_plural: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ
-  label_index_by_title: Ð˜Ð½Ð´ÐµÐºÑÐ¸Ñ€Ð°ÑšÐµ Ð¿Ð¾ Ð½Ð°ÑÐ»Ð¾Ð²Ñƒ
-  label_index_by_date: Ð˜Ð½Ð´ÐµÐºÑÐ¸Ñ€Ð°ÑšÐµ Ð¿Ð¾ Ð´Ð°Ñ‚ÑƒÐ¼Ñƒ
-  label_current_version: Ð¢Ñ€ÐµÐ½ÑƒÑ‚Ð½Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
-  label_preview: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
-  label_feed_plural: Ð˜Ð·Ð²Ð¾Ñ€Ð¸ Ð²ÐµÑÑ‚Ð¸
-  label_changes_details: Ð”ÐµÑ‚Ð°Ñ™Ð¸ ÑÐ²Ð¸Ñ… Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°
-  label_issue_tracking: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  label_spent_time: Ð£Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_overall_spent_time: Ð¦ÐµÐ»Ð¾ÐºÑƒÐ¿Ð½Ð¾ ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_f_hour: "%{value} ÑÐ°Ñ‚"
-  label_f_hour_plural: "%{value} ÑÐ°Ñ‚Ð¸"
-  label_time_tracking: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
-  label_change_plural: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ðµ
-  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ°
-  label_commits_per_month: Ð˜Ð·Ð²Ñ€ÑˆÐµÑšÐ° Ð¼ÐµÑÐµÑ‡Ð½Ð¾
-  label_commits_per_author: Ð˜Ð·Ð²Ñ€ÑˆÐµÑšÐ° Ð¿Ð¾ Ð°ÑƒÑ‚Ð¾Ñ€Ñƒ
-  label_view_diff: ÐŸÐ¾Ð³Ð»ÐµÐ´Ð°Ñ˜ Ñ€Ð°Ð·Ð»Ð¸ÐºÐµ
-  label_diff_inline: ÑƒÐ½ÑƒÑ‚Ñ€Ð°
-  label_diff_side_by_side: ÑƒÐ¿Ð¾Ñ€ÐµÐ´Ð¾
-  label_options: ÐžÐ¿Ñ†Ð¸Ñ˜Ðµ
-  label_copy_workflow_from: ÐšÐ¾Ð¿Ð¸Ñ€Ð°ÑšÐµ Ñ‚Ð¾ÐºÐ° Ð¿Ð¾ÑÐ»Ð° Ð¾Ð´
-  label_permissions_report: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ˜ Ð¾ Ð´Ð¾Ð·Ð²Ð¾Ð»Ð°Ð¼Ð°
-  label_watched_issues: ÐŸÐ¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ð½Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
-  label_related_issues: Ð¡Ñ€Ð¾Ð´Ð½Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
-  label_applied_status: ÐŸÑ€Ð¸Ð¼ÐµÑšÐµÐ½Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸
-  label_loading: Ð£Ñ‡Ð¸Ñ‚Ð°Ð²Ð°ÑšÐµ...
-  label_relation_new: ÐÐ¾Ð²Ð° Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ˜Ð°
-  label_relation_delete: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ˜Ðµ
-  label_relates_to: ÑÑ€Ð¾Ð´Ð½Ð¸Ñ… ÑÐ°
-  label_duplicates: Ð´ÑƒÐ¿Ð»Ð¸Ñ€Ð°Ð½Ð¸Ñ…
-  label_duplicated_by: Ð´ÑƒÐ¿Ð»Ð¸Ñ€Ð°Ð½Ð¸Ñ… Ð¾Ð´
-  label_blocks: Ð¾Ð´Ð±Ð¸Ñ˜ÐµÐ½Ð¸Ñ…
-  label_blocked_by: Ð¾Ð´Ð±Ð¸Ñ˜ÐµÐ½Ð¸Ñ… Ð¾Ð´
-  label_precedes: Ð¿Ñ€ÐµÑ‚Ñ…Ð¾Ð´Ð¸
-  label_follows: Ð¿Ñ€Ð°Ñ›ÐµÐ½Ð¸Ñ…
-  label_end_to_start: Ð¾Ð´ ÐºÑ€Ð°Ñ˜Ð° Ð´Ð¾ Ð¿Ð¾Ñ‡ÐµÑ‚ÐºÐ°
-  label_end_to_end: Ð¾Ð´ ÐºÑ€Ð°Ñ˜Ð° Ð´Ð¾ ÐºÑ€Ð°Ñ˜Ð°
-  label_start_to_start: Ð¾Ð´ Ð¿Ð¾Ñ‡ÐµÑ‚ÐºÐ° Ð´Ð¾ Ð¿Ð¾Ñ‡ÐµÑ‚ÐºÐ°
-  label_start_to_end: Ð¾Ð´ Ð¿Ð¾Ñ‡ÐµÑ‚ÐºÐ° Ð´Ð¾ ÐºÑ€Ð°Ñ˜Ð°
-  label_stay_logged_in: ÐžÑÑ‚Ð°Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ð¸
-  label_disabled: Ð¾Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›ÐµÐ½Ð¾
-  label_show_completed_versions: ÐŸÑ€Ð¸ÐºÐ°Ð·Ð¸Ð²Ð°ÑšÐµ Ð·Ð°Ð²Ñ€ÑˆÐµÐ½Ðµ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ðµ
-  label_me: Ð¼ÐµÐ½Ð¸
-  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
-  label_board_new: ÐÐ¾Ð²Ð¸ Ñ„Ð¾Ñ€ÑƒÐ¼
-  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
-  label_board_locked: Ð—Ð°ÐºÑ™ÑƒÑ‡Ð°Ð½Ð°
-  label_board_sticky: Ð›ÐµÐ¿Ñ™Ð¸Ð²Ð°
-  label_topic_plural: Ð¢ÐµÐ¼Ðµ
-  label_message_plural: ÐŸÐ¾Ñ€ÑƒÐºÐµ
-  label_message_last: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐ° Ð¿Ð¾Ñ€ÑƒÐºÐ°
-  label_message_new: ÐÐ¾Ð²Ð° Ð¿Ð¾Ñ€ÑƒÐºÐ°
-  label_message_posted: ÐŸÐ¾Ñ€ÑƒÐºÐ° Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚Ð°
-  label_reply_plural: ÐžÐ´Ð³Ð¾Ð²Ð¾Ñ€Ð¸
-  label_send_information: ÐŸÐ¾ÑˆÐ°Ñ™Ð¸ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÑƒ Ð´ÐµÑ‚Ð°Ñ™Ðµ Ð½Ð°Ð»Ð¾Ð³Ð°
-  label_year: Ð“Ð¾Ð´Ð¸Ð½Ð°
-  label_month: ÐœÐµÑÐµÑ†
-  label_week: Ð¡ÐµÐ´Ð¼Ð¸Ñ†Ð°
-  label_date_from: Ð¨Ð°Ñ™Ðµ
-  label_date_to: ÐŸÑ€Ð¸Ð¼Ð°
-  label_language_based: Ð‘Ð°Ð·Ð¸Ñ€Ð°Ð½Ð¾ Ð½Ð° Ñ˜ÐµÐ·Ð¸ÐºÑƒ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ°
-  label_sort_by: "Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ð¾ Ð¿Ð¾ %{value}"
-  label_send_test_email: Ð¡Ð»Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð½Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
-  label_feeds_access_key: RSS Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡
-  label_missing_feeds_access_key: RSS Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ˜Ðµ
-  label_feeds_access_key_created_on: "RSS Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ñ˜Ðµ Ð½Ð°Ð¿Ñ€Ð°Ð²Ñ™ÐµÐ½ Ð¿Ñ€Ðµ %{value}"
-  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ð¸
-  label_added_time_by: "Ð”Ð¾Ð´Ð°Ð¾ %{author} Ð¿Ñ€Ðµ %{age}"
-  label_updated_time_by: "ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð¾ %{author} Ð¿Ñ€Ðµ %{age}"
-  label_updated_time: "ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾ Ð¿Ñ€Ðµ %{value}"
-  label_jump_to_a_project: Ð¡ÐºÐ¾Ðº Ð½Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚...
-  label_file_plural: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
-  label_changeset_plural: Ð¡ÐºÑƒÐ¿Ð¾Ð²Ð¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°
-  label_default_columns: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ðµ ÐºÐ¾Ð»Ð¾Ð½Ðµ
-  label_no_change_option: (Ð‘ÐµÐ· Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°)
-  label_bulk_edit_selected_issues: Ð“Ñ€ÑƒÐ¿Ð½Ð° Ð¸Ð·Ð¼ÐµÐ½Ð° Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  label_theme: Ð¢ÐµÐ¼Ð°
-  label_default: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾
-  label_search_titles_only: ÐŸÑ€ÐµÑ‚Ñ€Ð°Ð¶ÑƒÑ˜ ÑÐ°Ð¼Ð¾ Ð½Ð°ÑÐ»Ð¾Ð²Ðµ
-  label_user_mail_option_all: "Ð—Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ˜Ð¸ Ð´Ð¾Ð³Ð°Ñ’Ð°Ñ˜ Ð½Ð° ÑÐ²Ð¸Ð¼ Ð¼Ð¾Ñ˜Ð¸Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°"
-  label_user_mail_option_selected: "Ð—Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ˜Ð¸ Ð´Ð¾Ð³Ð°Ñ’Ð°Ñ˜ Ð½Ð° ÑÐ°Ð¼Ð¾ Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½Ð¸Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°..."
-  label_user_mail_no_self_notified: "ÐÐµ Ð¶ÐµÐ»Ð¸Ð¼ Ð±Ð¸Ñ‚Ð¸ Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚Ð°Ð²Ð°Ð½ Ð·Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ðµ ÐºÐ¾Ñ˜Ðµ ÑÐ°Ð¼ Ð¿Ñ€Ð°Ð²Ð¸Ð¼"
-  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð°Ð»Ð¾Ð³Ð° Ð¿ÑƒÑ‚ÐµÐ¼ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
-  label_registration_manual_activation: Ñ€ÑƒÑ‡Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð°Ð»Ð¾Ð³Ð°
-  label_registration_automatic_activation: Ð°ÑƒÑ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð°Ð»Ð¾Ð³Ð°
-  label_display_per_page: "Ð‘Ñ€Ð¾Ñ˜ ÑÑ‚Ð°Ð²ÐºÐ¸ Ð¿Ð¾ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸: %{value}"
-  label_age: Ð¡Ñ‚Ð°Ñ€Ð¾ÑÑ‚
-  label_change_properties: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸ ÑÐ²Ð¾Ñ˜ÑÑ‚Ð²Ð°
-  label_general: ÐžÐ¿ÑˆÑ‚Ð¸
-  label_more: Ð’Ð¸ÑˆÐµ
-  label_scm: SCM
-  label_plugins: Ð”Ð¾Ð´Ð°Ñ‚Ð½Ðµ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ðµ
-  label_ldap_authentication: LDAP Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ð° Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
-  label_downloads_abbr: D/L
-  label_optional_description: ÐžÐ¿Ñ†Ð¸Ð¾Ð½Ð¾ Ð¾Ð¿Ð¸Ñ
-  label_add_another_file: Ð”Ð¾Ð´Ð°Ñ˜ Ñ˜Ð¾Ñˆ Ñ˜ÐµÐ´Ð½Ñƒ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÑƒ
-  label_preferences: ÐŸÐ¾Ð´ÐµÑˆÐ°Ð²Ð°ÑšÐ°
-  label_chronological_order: Ð¿Ð¾ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾ÑˆÐºÐ¾Ð¼ Ñ€ÐµÐ´Ð¾ÑÐ»ÐµÐ´Ñƒ
-  label_reverse_chronological_order: Ð¿Ð¾ Ð¾Ð±Ñ€Ð½ÑƒÑ‚Ð¾Ð¼ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾ÑˆÐºÐ¾Ð¼ Ñ€ÐµÐ´Ð¾ÑÐ»ÐµÐ´Ñƒ
-  label_planning: ÐŸÐ»Ð°Ð½Ð¸Ñ€Ð°ÑšÐµ
-  label_incoming_emails: Ð”Ð¾Ð»Ð°Ð·Ð½Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
-  label_generate_key: Ð“ÐµÐ½ÐµÑ€Ð¸ÑÐ°ÑšÐµ ÐºÑ™ÑƒÑ‡Ð°
-  label_issue_watchers: ÐŸÐ¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡Ð¸
-  label_example: ÐŸÑ€Ð¸Ð¼ÐµÑ€
-  label_display: ÐŸÑ€Ð¸ÐºÐ°Ð·
-  label_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°ÑšÐµ
-  label_ascending: Ð Ð°ÑÑ‚ÑƒÑ›Ð¸ Ð½Ð¸Ð·
-  label_descending: ÐžÐ¿Ð°Ð´Ð°Ñ˜ÑƒÑ›Ð¸ Ð½Ð¸Ð·
-  label_date_from_to: ÐžÐ´ %{start} Ð´Ð¾ %{end}
-  label_wiki_content_added: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚Ð°
-  label_wiki_content_updated: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°
-  label_group: Ð“Ñ€ÑƒÐ¿Ð°
-  label_group_plural: Ð“Ñ€ÑƒÐ¿Ðµ
-  label_group_new: ÐÐ¾Ð²Ð° Ð³Ñ€ÑƒÐ¿Ð°
-  label_time_entry_plural: Ð£Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_version_sharing_none: ÐÐ¸Ñ˜Ðµ Ð´ÐµÑ™ÐµÐ½Ð¾
-  label_version_sharing_descendants: Ð¡Ð° Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°
-  label_version_sharing_hierarchy: Ð¡Ð° Ñ…Ð¸Ñ˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ˜Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
-  label_version_sharing_tree: Ð¡Ð° ÑÑ‚Ð°Ð±Ð»Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
-  label_version_sharing_system: Ð¡Ð° ÑÐ²Ð¸Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°
-  label_update_issue_done_ratios: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ñ˜ Ð¾Ð´Ð½Ð¾Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  label_copy_source: Ð˜Ð·Ð²Ð¾Ñ€
-  label_copy_target: ÐžÐ´Ñ€ÐµÐ´Ð¸ÑˆÑ‚Ðµ
-  label_copy_same_as_target: Ð˜ÑÑ‚Ð¾ ÐºÐ°Ð¾ Ð¾Ð´Ñ€ÐµÐ´Ð¸ÑˆÑ‚Ðµ
-  label_display_used_statuses_only: ÐŸÑ€Ð¸ÐºÐ°Ð·ÑƒÑ˜ ÑÑ‚Ð°Ñ‚ÑƒÑÐµ ÐºÐ¾Ñ€Ð¸ÑˆÑ›ÐµÐ½Ðµ ÑÐ°Ð¼Ð¾ Ð¾Ð´ ÑÑ‚Ñ€Ð°Ð½Ðµ Ð¾Ð²Ð¾Ð³ Ð¿Ñ€Ð°Ñ›ÐµÑšÐ°
-  label_api_access_key: API Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡
-  label_missing_api_access_key: ÐÐµÐ´Ð¾ÑÑ‚Ð°Ñ˜Ðµ API Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡
-  label_api_access_key_created_on: "API Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ñ˜Ðµ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½ Ð¿Ñ€Ðµ %{value}"
-  label_profile: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
-  label_subtask_plural: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº
-  label_project_copy_notifications: ÐŸÐ¾ÑˆÐ°Ñ™Ð¸ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÑƒ ÑÐ° Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐµÐ¼ Ð¿Ñ€Ð¸Ð»Ð¸ÐºÐ¾Ð¼ ÐºÐ¾Ð¿Ð¸Ñ€Ð°ÑšÐ° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð° 
-  
-  button_login: ÐŸÑ€Ð¸Ñ˜Ð°Ð²Ð°
-  button_submit: ÐŸÐ¾ÑˆÐ°Ñ™Ð¸
-  button_save: Ð¡Ð½Ð¸Ð¼Ð¸
-  button_check_all: Ð£ÐºÑ™ÑƒÑ‡Ð¸ ÑÐ²Ðµ
-  button_uncheck_all: Ð˜ÑÐºÑ™ÑƒÑ‡Ð¸ ÑÐ²Ðµ
-  button_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸
-  button_create: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜
-  button_create_and_continue: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜ Ð¸ Ð½Ð°ÑÑ‚Ð°Ð²Ð¸
-  button_test: Ð¢ÐµÑÑ‚
-  button_edit: Ð˜Ð·Ð¼ÐµÐ½Ð¸
-  button_add: Ð”Ð¾Ð´Ð°Ñ˜
-  button_change: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸
-  button_apply: ÐŸÑ€Ð¸Ð¼ÐµÐ½Ð¸
-  button_clear: ÐžÐ±Ñ€Ð¸ÑˆÐ¸
-  button_lock: Ð—Ð°ÐºÑ™ÑƒÑ‡Ð°Ñ˜
-  button_unlock: ÐžÑ‚ÐºÑ™ÑƒÑ‡Ð°Ñ˜
-  button_download: ÐŸÑ€ÐµÑƒÐ·Ð¼Ð¸
-  button_list: Ð¡Ð¿Ð¸ÑÐ°Ðº
-  button_view: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸
-  button_move: ÐŸÐ¾Ð¼ÐµÑ€Ð¸
-  button_move_and_follow: ÐŸÐ¾Ð¼ÐµÑ€Ð¸ Ð¸ Ð¿Ñ€Ð°Ñ‚Ð¸
-  button_back: ÐÐ°Ð·Ð°Ð´
-  button_cancel: ÐŸÐ¾Ð½Ð¸ÑˆÑ‚Ð¸
-  button_activate: ÐÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
-  button_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ñ˜
-  button_log_time: Ð•Ð²Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ€Ð°Ñ˜ Ð²Ñ€ÐµÐ¼Ðµ
-  button_rollback: ÐŸÐ¾Ð²Ñ€Ð°Ñ‚Ð°Ðº Ð½Ð° Ð¾Ð²Ñƒ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ñƒ
-  button_watch: ÐŸÑ€Ð°Ñ‚Ð¸
-  button_unwatch: ÐÐµ Ð¿Ñ€Ð°Ñ‚Ð¸ Ð²Ð¸ÑˆÐµ
-  button_reply: ÐžÐ´Ð³Ð¾Ð²Ð¾Ñ€Ð¸
-  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
-  button_unarchive: Ð’Ñ€Ð°Ñ‚Ð¸ Ð¸Ð· Ð°Ñ€Ñ…Ð¸Ð²Ðµ
-  button_reset: ÐŸÐ¾Ð½Ð¸ÑˆÑ‚Ð¸
-  button_rename: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÑ˜
-  button_change_password: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÑƒ
-  button_copy: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜
-  button_copy_and_follow: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜ Ð¸ Ð¿Ñ€Ð°Ñ‚Ð¸
-  button_annotate: ÐŸÑ€Ð¸Ð±ÐµÐ»ÐµÐ¶Ð¸
-  button_update: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ñ˜
-  button_configure: ÐŸÐ¾Ð´ÐµÑÐ¸
-  button_quote: ÐŸÐ¾Ð´ Ð½Ð°Ð²Ð¾Ð´Ð½Ð¸Ñ†Ð¸Ð¼Ð°
-  button_duplicate: Ð”ÑƒÐ¿Ð»Ð¸Ñ€Ð°Ñ˜
-  button_show: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸
-  
-  status_active: Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¸
-  status_registered: Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½Ð¸
-  status_locked: Ð·Ð°ÐºÑ™ÑƒÑ‡Ð°Ð½Ð¸
-  
-  version_status_open: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½
-  version_status_locked: Ð·Ð°ÐºÑ™ÑƒÑ‡Ð°Ð½
-  version_status_closed: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½
-
-  field_active: ÐÐºÑ‚Ð¸Ð²Ð°Ð½
-  
-  text_select_mail_notifications: ÐžÐ´Ð°Ð±ÐµÑ€Ð¸ Ð°ÐºÑ†Ð¸Ñ˜Ðµ Ð·Ð° ÐºÐ¾Ñ˜Ðµ Ñ›Ðµ Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ð¾ÑÐ»Ð°Ñ‚Ð¾ Ð¿ÑƒÑ‚ÐµÐ¼ Ðµ-Ð¿Ð¾ÑˆÑ‚Ðµ.
-  text_regexp_info: Ð½Ð¿Ñ€. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 Ð·Ð½Ð°Ñ‡Ð¸ Ð±ÐµÐ· Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÑšÐ°
-  text_project_destroy_confirmation: ÐˆÐµÑÑ‚Ðµ Ð»Ð¸ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¾Ð²Ð°Ñ˜ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚ Ð¸ ÑÐ²Ðµ Ð¿Ñ€Ð¸Ð¿Ð°Ð´Ð°Ñ˜ÑƒÑ›Ðµ Ð¿Ð¾Ð´Ð°Ñ‚ÐºÐµ?
-  text_subprojects_destroy_warning: "ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸: %{value} Ñ›Ðµ Ñ‚Ð°ÐºÐ¾Ñ’Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ð½."
-  text_workflow_edit: ÐžÐ´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ ÑƒÐ»Ð¾Ð³Ñƒ Ð¸ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð·Ð° Ð¸Ð·Ð¼ÐµÐ½Ñƒ Ñ‚Ð¾ÐºÐ° Ð¿Ð¾ÑÐ»Ð°
-  text_are_you_sure: ÐˆÐµÑÑ‚Ðµ Ð»Ð¸ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸?
-  text_journal_changed: "%{label} Ð¿Ñ€Ð¾Ð¼ÐµÑšÐµÐ½ Ð¾Ð´ %{old} Ñƒ %{new}"
-  text_journal_set_to: "%{label} Ð¿Ð¾ÑÑ‚Ð°Ð²Ñ™ÐµÐ½ Ñƒ %{value}"
-  text_journal_deleted: "%{label} Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ð½Ð¾ (%{old})"
-  text_journal_added: "%{label} %{value} Ð´Ð¾Ð´Ð°Ñ‚Ð¾"
-  text_tip_issue_begin_day: Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº Ð¿Ð¾Ñ‡Ð¸ÑšÐµ Ð¾Ð²Ð¾Ð³ Ð´Ð°Ð½Ð°
-  text_tip_issue_end_day: Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº ÑÐµ Ð·Ð°Ð²Ñ€ÑˆÐ°Ð²Ð° Ð¾Ð²Ð¾Ð³ Ð´Ð°Ð½Ð°
-  text_tip_issue_begin_end_day: Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº Ð¿Ð¾Ñ‡Ð¸ÑšÐµ Ð¸ Ð·Ð°Ð²Ñ€ÑˆÐ°Ð²Ð° Ð¾Ð²Ð¾Ð³ Ð´Ð°Ð½Ð°
-  text_project_identifier_info: 'Ð”Ð¾Ð·Ð²Ð¾Ñ™ÐµÐ½Ð° ÑÑƒ ÑÐ°Ð¼Ð¾ Ð¼Ð°Ð»Ð° ÑÐ»Ð¾Ð²Ð° (a-Ñˆ), Ð±Ñ€Ð¾Ñ˜ÐµÐ²Ð¸ Ð¸ Ñ†Ñ€Ñ‚Ð¸Ñ†Ðµ.<br />ÐˆÐµÐ´Ð½Ð¾Ð¼ ÑÐ½Ð¸Ð¼Ñ™ÐµÐ½ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€ Ð²Ð¸ÑˆÐµ ÑÐµ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸Ñ‚Ð¸.'
-  text_caracters_maximum: "ÐÐ°Ñ˜Ð²Ð¸ÑˆÐµ %{count} Ð·Ð½Ð°Ðº(Ð¾Ð²Ð°)."
-  text_caracters_minimum: "Ð‘Ñ€Ð¾Ñ˜ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð½Ð°Ñ˜Ð¼Ð°ÑšÐµ %{count}."
-  text_length_between: "Ð‘Ñ€Ð¾Ñ˜ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¸Ð·Ð¼ÐµÑ’Ñƒ %{min} Ð¸ %{max}."
-  text_tracker_no_workflow: ÐžÐ²Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð½ÐµÐ¼Ð° Ð´ÐµÑ„Ð¸Ð½Ð¸ÑÐ°Ð½ Ñ‚Ð¾Ðº Ð¿Ð¾ÑÐ»Ð°
-  text_unallowed_characters: ÐÐµÐ´Ð¾Ð·Ð²Ð¾Ñ™ÐµÐ½Ð¸ Ð·Ð½Ð°ÐºÐ¾Ð²Ð¸
-  text_comma_separated: Ð”Ð¾Ð·Ð²Ð¾Ñ™ÐµÐ½Ðµ ÑÑƒ Ð²Ð¸ÑˆÐµÑÑ‚Ñ€ÑƒÐºÐµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸ (Ð¾Ð´Ð²Ð¾Ñ˜ÐµÐ½Ðµ Ð·Ð°Ñ€ÐµÐ·Ð¾Ð¼).
-  text_line_separated: Ð”Ð¾Ð·Ð²Ð¾Ñ™ÐµÐ½Ðµ ÑÑƒ Ð²Ð¸ÑˆÐµÑÑ‚Ñ€ÑƒÐºÐµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸ (Ñ˜ÐµÐ´Ð°Ð½ Ñ€ÐµÐ´ Ð·Ð° ÑÐ²Ð°ÐºÑƒ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚).
-  text_issues_ref_in_commit_messages: Ð ÐµÑ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ€Ð°ÑšÐµ Ð¸ Ð¿Ð¾Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ñƒ Ð¸Ð·Ð²Ñ€ÑˆÐ½Ð¸Ð¼ Ð¿Ð¾Ñ€ÑƒÐºÐ°Ð¼Ð°
-  text_issue_added: "%{author} Ñ˜Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð¸Ð¾ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ %{id}."
-  text_issue_updated: "%{author} Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð¾ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ %{id}."
-  text_wiki_destroy_confirmation: ÐˆÐµÑÑ‚Ðµ Ð»Ð¸ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° Ð¾Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ wiki Ð¸ ÑÐ°Ð² ÑÐ°Ð´Ñ€Ð¶Ð°Ñ˜?
-  text_issue_category_destroy_question: "ÐÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° (%{count}) Ñ˜Ðµ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ð¾ Ð¾Ð²Ð¾Ñ˜ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð¸. Ð¨Ñ‚Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° ÑƒÑ€Ð°Ð´Ð¸Ñ‚Ðµ?"
-  text_issue_category_destroy_assignments: Ð£ÐºÐ»Ð¾Ð½Ð¸ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ðµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ðµ
-  text_issue_category_reassign_to: Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ðµ Ð¾Ð²Ð¾Ñ˜ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð¸
-  text_user_mail_option: "Ð—Ð° Ð½ÐµÐ¸Ð·Ð°Ð±Ñ€Ð°Ð½Ðµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ðµ, Ð´Ð¾Ð±Ð¸Ñ›ÐµÑ‚Ðµ ÑÐ°Ð¼Ð¾ Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐµ Ð¾ ÑÑ‚Ð²Ð°Ñ€Ð¸Ð¼Ð° ÐºÐ¾Ñ˜Ðµ Ð¿Ñ€Ð°Ñ‚Ð¸Ñ‚Ðµ Ð¸Ð»Ð¸ ÑÑ‚Ðµ ÑƒÐºÑ™ÑƒÑ‡ÐµÐ½Ð¸ (Ð½Ð¿Ñ€. Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸ Ñ‡Ð¸Ñ˜Ð¸ ÑÑ‚Ðµ Ð²Ð¸ Ð°ÑƒÑ‚Ð¾Ñ€ Ð¸Ð»Ð¸ Ð·Ð°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ðº)."
-  text_no_configuration_data: "Ð£Ð»Ð¾Ð³Ðµ, Ð¿Ñ€Ð°Ñ›ÐµÑšÐ°, ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð¸ Ñ‚Ð¾ÐºÐ° Ð¿Ð¾ÑÐ»Ð° Ñ˜Ð¾Ñˆ ÑƒÐ²ÐµÐº Ð½Ð¸ÑÑƒ Ð¿Ð¾Ð´ÐµÑˆÐµÐ½Ð¸.\nÐŸÑ€ÐµÐ¿Ð¾Ñ€ÑƒÑ‡Ñ™Ð¸Ð²Ð¾ Ñ˜Ðµ Ð´Ð° ÑƒÑ‡Ð¸Ñ‚Ð°Ñ‚Ðµ Ð¿Ð¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ. Ð˜Ð·Ð¼ÐµÐ½Ð° Ñ˜Ðµ Ð¼Ð¾Ð³ÑƒÑ›Ð° Ð½Ð°ÐºÐ¾Ð½ Ð¿Ñ€Ð²Ð¾Ð³ ÑƒÑ‡Ð¸Ñ‚Ð°Ð²Ð°ÑšÐ°."
-  text_load_default_configuration: Ð£Ñ‡Ð¸Ñ‚Ð°Ñ˜ Ð¿Ð¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ
-  text_status_changed_by_changeset: "ÐŸÑ€Ð¸Ð¼ÐµÑšÐµÐ½Ð¾ Ñƒ ÑÐºÑƒÐ¿Ñƒ ÑÐ° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°Ð¼Ð° %{value}."
-  text_issues_destroy_confirmation: 'ÐˆÐµÑÑ‚Ðµ Ð»Ð¸ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½Ðµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ðµ?'
-  text_select_project_modules: 'ÐžÐ´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ðµ ÐºÐ¾Ñ˜Ðµ Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð¾Ð¼Ð¾Ð³ÑƒÑ›Ð¸Ñ‚Ð¸ Ð·Ð° Ð¾Ð²Ð°Ñ˜ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚:'
-  text_default_administrator_account_changed: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¸ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€ÑÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³ Ñ˜Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÑšÐµÐ½
-  text_file_repository_writable: Ð¤Ð°ÑÑ†Ð¸ÐºÐ»Ð° Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ… Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ° Ñ˜Ðµ ÑƒÐ¿Ð¸ÑÐ¸Ð²Ð°
-  text_plugin_assets_writable: Ð¤Ð°ÑÑ†Ð¸ÐºÐ»Ð° ÐµÐ»ÐµÐ¼ÐµÐ½Ð°Ñ‚Ð° Ð´Ð¾Ð´Ð°Ñ‚Ð½Ð¸Ñ… ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð¸ Ñ˜Ðµ ÑƒÐ¿Ð¸ÑÐ¸Ð²Ð°
-  text_rmagick_available: RMagick Ñ˜Ðµ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð°Ð½ (Ð¾Ð¿Ñ†Ð¸Ð¾Ð½Ð¾)
-  text_destroy_time_entries_question: "%{hours} ÑÐ°Ñ‚Ð¸ Ñ˜Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ð¾ Ð·Ð° Ð¾Ð²Ð°Ñ˜ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ ÐºÐ¾Ñ˜Ð¸ Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸. Ð¨Ñ‚Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° ÑƒÑ€Ð°Ð´Ð¸Ñ‚Ðµ?"
-  text_destroy_time_entries: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ðµ ÑÐ°Ñ‚Ðµ
-  text_assign_time_entries_to_project: Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ðµ ÑÐ°Ñ‚Ðµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ñƒ
-  text_reassign_time_entries: 'Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ðµ ÑÐ°Ñ‚Ðµ Ð¾Ð²Ð¾Ð¼ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ñƒ:'
-  text_user_wrote: "%{value} Ñ˜Ðµ Ð½Ð°Ð¿Ð¸ÑÐ°Ð¾:"
-  text_enumeration_destroy_question: "%{count} Ð¾Ð±Ñ˜ÐµÐºÐ°Ñ‚(Ð°) Ñ˜Ðµ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ð¾ Ð¾Ð²Ð¾Ñ˜ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸."
-  text_enumeration_category_reassign_to: 'Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¸Ñ… Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¾Ð²Ð¾Ñ˜ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸:'
-  text_email_delivery_not_configured: "Ð˜ÑÐ¿Ð¾Ñ€ÑƒÐºÐ° Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐ° Ð½Ð¸Ñ˜Ðµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°Ð½Ð° Ð¸ Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐ° ÑÑƒ Ð¾Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›ÐµÐ½Ð°.\nÐŸÐ¾Ð´ÐµÑÐ¸Ñ‚Ðµ Ð²Ð°Ñˆ SMTP ÑÐµÑ€Ð²ÐµÑ€ Ñƒ config/configuration.yml Ð¸ Ð¿Ð¾ÐºÑ€ÐµÐ½Ð¸Ñ‚Ðµ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ñƒ Ð·Ð° ÑšÐ¸Ñ…Ð¾Ð²Ð¾ Ð¾Ð¼Ð¾Ð³ÑƒÑ›Ð°Ð²Ð°ÑšÐµ."
-  text_repository_usernames_mapping: "ÐžÐ´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¸Ð»Ð¸ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ñ˜Ñ‚Ðµ Redmine ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐµ Ð¼Ð°Ð¿Ð¸Ñ€Ð°ÑšÐµÐ¼ ÑÐ²Ð°ÐºÐ¾Ð³ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¾Ð³ Ð¸Ð¼ÐµÐ½Ð° Ð¿Ñ€Ð¾Ð½Ð°Ñ’ÐµÐ½Ð¾Ð³ Ñƒ ÐµÐ²Ð¸Ð´ÐµÐ½Ñ†Ð¸Ñ˜Ð¸ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ð°.\nÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸ ÑÐ° Ð¸ÑÑ‚Ð¸Ð¼ Redmine Ð¸Ð¼ÐµÐ½Ð¾Ð¼ Ð¸ Ð¸Ð¼ÐµÐ½Ð¾Ð¼ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ð° Ð¸Ð»Ð¸ Ðµ-Ð°Ð´Ñ€ÐµÑÐ¾Ð¼ ÑÑƒ Ð°ÑƒÑ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ¸ Ð¼Ð°Ð¿Ð¸Ñ€Ð°Ð½Ð¸."
-  text_diff_truncated: '... ÐžÐ²Ð° Ñ€Ð°Ð·Ð»Ð¸ÐºÐ° Ñ˜Ðµ Ð¸ÑÐµÑ‡ÐµÐ½Ð° Ñ˜ÐµÑ€ Ñ˜Ðµ Ð´Ð¾ÑÑ‚Ð¸Ð³Ð½ÑƒÑ‚Ð° Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°.'
-  text_custom_field_possible_values_info: 'ÐˆÐµÐ´Ð°Ð½ Ñ€ÐµÐ´ Ð·Ð° ÑÐ²Ð°ÐºÑƒ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚'
-  text_wiki_page_destroy_question: "ÐžÐ²Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¸Ð¼Ð° %{descendants} Ð¿Ð¾Ð´Ñ€ÐµÑ’ÐµÐ½Ð¸Ñ… ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¸ Ð¿Ð¾Ð´ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°. Ð¨Ñ‚Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° ÑƒÑ€Ð°Ð´Ð¸Ñ‚Ðµ?"
-  text_wiki_page_nullify_children: "Ð—Ð°Ð´Ñ€Ð¶Ð¸ Ð¿Ð¾Ð´Ñ€ÐµÑ’ÐµÐ½Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ ÐºÐ°Ð¾ ÐºÐ¾Ñ€ÐµÐ½Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ"
-  text_wiki_page_destroy_children: "Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ Ð¿Ð¾Ð´Ñ€ÐµÑ’ÐµÐ½Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ Ð¸ ÑÐ²Ðµ ÑšÐ¸Ñ…Ð¾Ð²Ðµ Ð¿Ð¾Ð´ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ"
-  text_wiki_page_reassign_children: "Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¿Ð¾Ð´Ñ€ÐµÑ’ÐµÐ½Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ Ð¾Ð²Ð¾Ñ˜ Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾Ñ˜ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸"
-  text_own_membership_delete_confirmation: "ÐÐ°ÐºÐ¾Ð½ ÑƒÐºÐ»Ð°ÑšÐ°ÑšÐ° Ð¿Ð¾Ñ˜ÐµÐ´Ð¸Ð½Ð¸Ñ… Ð¸Ð»Ð¸ ÑÐ²Ð¸Ñ… Ð²Ð°ÑˆÐ¸Ñ… Ð´Ð¾Ð·Ð²Ð¾Ð»Ð° Ð½ÐµÑ›ÐµÑ‚Ðµ Ð²Ð¸ÑˆÐµ Ð¼Ð¾Ñ›Ð¸ Ð´Ð° ÑƒÑ€ÐµÑ’ÑƒÑ˜ÐµÑ‚Ðµ Ð¾Ð²Ð°Ñ˜ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚.\nÐ–ÐµÐ»Ð¸Ñ‚Ðµ Ð»Ð¸ Ð´Ð° Ð½Ð°ÑÑ‚Ð°Ð²Ð¸Ñ‚Ðµ?"
-  text_zoom_in: Ð£Ð²ÐµÑ›Ð°Ñ˜
-  text_zoom_out: Ð£Ð¼Ð°ÑšÐ¸
-  
-  default_role_manager: ÐœÐµÐ½Ð°ÑŸÐµÑ€
-  default_role_developer: ÐŸÑ€Ð¾Ð³Ñ€Ð°Ð¼ÐµÑ€
-  default_role_reporter: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ‡
-  default_tracker_bug: Ð“Ñ€ÐµÑˆÐºÐ°
-  default_tracker_feature: Ð¤ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð°Ð»Ð½Ð¾ÑÑ‚
-  default_tracker_support: ÐŸÐ¾Ð´Ñ€ÑˆÐºÐ°
-  default_issue_status_new: ÐÐ¾Ð²Ð¾
-  default_issue_status_in_progress: Ð£ Ñ‚Ð¾ÐºÑƒ
-  default_issue_status_resolved: Ð ÐµÑˆÐµÐ½Ð¾
-  default_issue_status_feedback: ÐŸÐ¾Ð²Ñ€Ð°Ñ‚Ð½Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ð°
-  default_issue_status_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¾
-  default_issue_status_rejected: ÐžÐ´Ð±Ð¸Ñ˜ÐµÐ½Ð¾
-  default_doc_category_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ˜Ð°
-  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸Ñ‡ÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ˜Ð°
-  default_priority_low: ÐÐ¸Ð·Ð°Ðº
-  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»Ð°Ð½
-  default_priority_high: Ð’Ð¸ÑÐ¾Ðº
-  default_priority_urgent: Ð¥Ð¸Ñ‚Ð½Ð¾
-  default_priority_immediate: ÐÐµÐ¿Ð¾ÑÑ€ÐµÐ´Ð½Ð¾
-  default_activity_design: Ð”Ð¸Ð·Ð°Ñ˜Ð½
-  default_activity_development: Ð Ð°Ð·Ð²Ð¾Ñ˜
-  
-  enumeration_issue_priorities: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
-  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ðµ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°
-  enumeration_activities: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð¸ (Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°)
-  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼ÑÐºÐ° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
-  
-  field_time_entries: Ð’Ñ€ÐµÐ¼Ðµ ÐµÐ²Ð¸Ð´ÐµÐ½Ñ†Ð¸Ñ˜Ðµ
-  project_module_gantt: Ð“Ð°Ð½Ñ‚Ð¾Ð² Ð´Ð¸Ñ˜Ð°Ð³Ñ€Ð°Ð¼
-  project_module_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
-
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: ÐšÐ¾Ð´Ð¸Ñ€Ð°ÑšÐµ Ð¸Ð·Ð²Ñ€ÑˆÐ½Ð¸Ñ… Ð¿Ð¾Ñ€ÑƒÐºÐ°
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/10/10941a48faa924ece3034ab7920a0b4ae65e5ad0.svn-base
--- a/.svn/pristine/10/10941a48faa924ece3034ab7920a0b4ae65e5ad0.svn-base
+++ /dev/null
@@ -1,41 +0,0 @@
-# redMine - project management software
-# Copyright (C) 2008  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-desc <<-END_DESC
-Send reminders about issues due in the next days.
-
-Available options:
-  * days     => number of days to remind about (defaults to 7)
-  * tracker  => id of tracker (defaults to all trackers)
-  * project  => id or identifier of project (defaults to all projects)
-  * users    => comma separated list of user ids who should be reminded
-
-Example:
-  rake redmine:send_reminders days=7 users="1,23, 56" RAILS_ENV="production"
-END_DESC
-
-namespace :redmine do
-  task :send_reminders => :environment do
-    options = {}
-    options[:days] = ENV['days'].to_i if ENV['days']
-    options[:project] = ENV['project'] if ENV['project']
-    options[:tracker] = ENV['tracker'].to_i if ENV['tracker']
-    options[:users] = (ENV['users'] || '').split(',').each(&:strip!)
-    
-    Mailer.reminders(options)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/10/10ba38f34a4375a656d65a1e3f8a1b3bc519f3f1.svn-base
--- a/.svn/pristine/10/10ba38f34a4375a656d65a1e3f8a1b3bc519f3f1.svn-base
+++ /dev/null
@@ -1,28 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class WikiContentObserver < ActiveRecord::Observer
-  def after_create(wiki_content)
-    Mailer.deliver_wiki_content_added(wiki_content) if Setting.notified_events.include?('wiki_content_added')
-  end
-
-  def after_update(wiki_content)
-    if wiki_content.text_changed?
-      Mailer.deliver_wiki_content_updated(wiki_content) if Setting.notified_events.include?('wiki_content_updated')
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/10/10c9cdd06a52f023cccd6f598c36e6c63972ac76.svn-base
--- /dev/null
+++ b/.svn/pristine/10/10c9cdd06a52f023cccd6f598c36e6c63972ac76.svn-base
@@ -0,0 +1,165 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AccountControllerOpenidTest < ActionController::TestCase
+  tests AccountController
+  fixtures :users, :roles
+
+  def setup
+    User.current = nil
+    Setting.openid = '1'
+  end
+
+  def teardown
+    Setting.openid = '0'
+  end
+
+  if Object.const_defined?(:OpenID)
+
+    def test_login_with_openid_for_existing_user
+      Setting.self_registration = '3'
+      existing_user = User.new(:firstname => 'Cool',
+                               :lastname => 'User',
+                               :mail => 'user@somedomain.com',
+                               :identity_url => 'http://openid.example.com/good_user')
+      existing_user.login = 'cool_user'
+      assert existing_user.save!
+  
+      post :login, :openid_url => existing_user.identity_url
+      assert_redirected_to '/my/page'
+    end
+  
+    def test_login_with_invalid_openid_provider
+      Setting.self_registration = '0'
+      post :login, :openid_url => 'http;//openid.example.com/good_user'
+      assert_redirected_to home_url
+    end
+  
+    def test_login_with_openid_for_existing_non_active_user
+      Setting.self_registration = '2'
+      existing_user = User.new(:firstname => 'Cool',
+                               :lastname => 'User',
+                               :mail => 'user@somedomain.com',
+                               :identity_url => 'http://openid.example.com/good_user',
+                               :status => User::STATUS_REGISTERED)
+      existing_user.login = 'cool_user'
+      assert existing_user.save!
+  
+      post :login, :openid_url => existing_user.identity_url
+      assert_redirected_to '/login'
+    end
+  
+    def test_login_with_openid_with_new_user_created
+      Setting.self_registration = '3'
+      post :login, :openid_url => 'http://openid.example.com/good_user'
+      assert_redirected_to '/my/account'
+      user = User.find_by_login('cool_user')
+      assert user
+      assert_equal 'Cool', user.firstname
+      assert_equal 'User', user.lastname
+    end
+  
+    def test_login_with_openid_with_new_user_and_self_registration_off
+      Setting.self_registration = '0'
+      post :login, :openid_url => 'http://openid.example.com/good_user'
+      assert_redirected_to home_url
+      user = User.find_by_login('cool_user')
+      assert_nil user
+    end
+  
+    def test_login_with_openid_with_new_user_created_with_email_activation_should_have_a_token
+      Setting.self_registration = '1'
+      post :login, :openid_url => 'http://openid.example.com/good_user'
+      assert_redirected_to '/login'
+      user = User.find_by_login('cool_user')
+      assert user
+  
+      token = Token.find_by_user_id_and_action(user.id, 'register')
+      assert token
+    end
+  
+    def test_login_with_openid_with_new_user_created_with_manual_activation
+      Setting.self_registration = '2'
+      post :login, :openid_url => 'http://openid.example.com/good_user'
+      assert_redirected_to '/login'
+      user = User.find_by_login('cool_user')
+      assert user
+      assert_equal User::STATUS_REGISTERED, user.status
+    end
+  
+    def test_login_with_openid_with_new_user_with_conflict_should_register
+      Setting.self_registration = '3'
+      existing_user = User.new(:firstname => 'Cool', :lastname => 'User', :mail => 'user@somedomain.com')
+      existing_user.login = 'cool_user'
+      assert existing_user.save!
+  
+      post :login, :openid_url => 'http://openid.example.com/good_user'
+      assert_response :success
+      assert_template 'register'
+      assert assigns(:user)
+      assert_equal 'http://openid.example.com/good_user', assigns(:user)[:identity_url]
+    end
+  
+    def test_login_with_openid_with_new_user_with_missing_information_should_register
+      Setting.self_registration = '3'
+  
+      post :login, :openid_url => 'http://openid.example.com/good_blank_user'
+      assert_response :success
+      assert_template 'register'
+      assert assigns(:user)
+      assert_equal 'http://openid.example.com/good_blank_user', assigns(:user)[:identity_url]
+
+      assert_select 'input[name=?]', 'user[login]'
+      assert_select 'input[name=?]', 'user[password]'
+      assert_select 'input[name=?]', 'user[password_confirmation]'
+      assert_select 'input[name=?][value=?]', 'user[identity_url]', 'http://openid.example.com/good_blank_user'
+    end
+
+    def test_register_after_login_failure_should_not_require_user_to_enter_a_password
+      Setting.self_registration = '3'
+
+      assert_difference 'User.count' do
+        post :register, :user => {
+          :login => 'good_blank_user',
+          :password => '',
+          :password_confirmation => '',
+          :firstname => 'Cool',
+          :lastname => 'User',
+          :mail => 'user@somedomain.com',
+          :identity_url => 'http://openid.example.com/good_blank_user'
+        }
+        assert_response 302
+      end
+
+      user = User.first(:order => 'id DESC')
+      assert_equal 'http://openid.example.com/good_blank_user', user.identity_url
+      assert user.hashed_password.blank?, "Hashed password was #{user.hashed_password}"
+    end
+
+    def test_setting_openid_should_return_true_when_set_to_true
+      assert_equal true, Setting.openid?
+    end
+
+  else
+    puts "Skipping openid tests."
+
+    def test_dummy
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/10/10fa798bfd4dc35b558fd0502d1cd4f15f26285c.svn-base
--- a/.svn/pristine/10/10fa798bfd4dc35b558fd0502d1cd4f15f26285c.svn-base
+++ /dev/null
@@ -1,118 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class ProjectNestedSetTest < ActiveSupport::TestCase
-
-  context "nested set" do
-    setup do
-      Project.delete_all
-
-      @a = Project.create!(:name => 'Project A', :identifier => 'projecta')
-      @a1 = Project.create!(:name => 'Project A1', :identifier => 'projecta1')
-      @a1.set_parent!(@a)
-      @a2 = Project.create!(:name => 'Project A2', :identifier => 'projecta2')
-      @a2.set_parent!(@a)
-
-      @b = Project.create!(:name => 'Project B', :identifier => 'projectb')
-      @b1 = Project.create!(:name => 'Project B1', :identifier => 'projectb1')
-      @b1.set_parent!(@b)
-      @b11 = Project.create!(:name => 'Project B11', :identifier => 'projectb11')
-      @b11.set_parent!(@b1)
-      @b2 = Project.create!(:name => 'Project B2', :identifier => 'projectb2')
-      @b2.set_parent!(@b)
-
-      @c = Project.create!(:name => 'Project C', :identifier => 'projectc')
-      @c1 = Project.create!(:name => 'Project C1', :identifier => 'projectc1')
-      @c1.set_parent!(@c)
-
-      [@a, @a1, @a2, @b, @b1, @b11, @b2, @c, @c1].each(&:reload)
-    end
-
-    context "#create" do
-      should "build valid tree" do
-        assert_nested_set_values({
-          @a   => [nil,   1,  6],
-          @a1  => [@a.id, 2,  3],
-          @a2  => [@a.id, 4,  5],
-          @b   => [nil,   7, 14],
-          @b1  => [@b.id, 8, 11],
-          @b11 => [@b1.id,9, 10],
-          @b2  => [@b.id,12, 13],
-          @c   => [nil,  15, 18],
-          @c1  => [@c.id,16, 17]
-        })
-      end
-    end
-
-    context "#set_parent!" do
-      should "keep valid tree" do
-        assert_no_difference 'Project.count' do
-          Project.find_by_name('Project B1').set_parent!(Project.find_by_name('Project A2'))
-        end
-        assert_nested_set_values({
-          @a   => [nil,   1, 10],
-          @a2  => [@a.id, 4,  9],
-          @b1  => [@a2.id,5,  8],
-          @b11 => [@b1.id,6,  7],
-          @b   => [nil,  11, 14],
-          @c   => [nil,  15, 18]
-        })
-      end
-    end
-
-    context "#destroy" do
-      context "a root with children" do
-        should "not mess up the tree" do
-          assert_difference 'Project.count', -4 do
-            Project.find_by_name('Project B').destroy
-          end
-          assert_nested_set_values({
-            @a  => [nil,   1,  6],
-            @a1 => [@a.id, 2,  3],
-            @a2 => [@a.id, 4,  5],
-            @c  => [nil,   7, 10],
-            @c1 => [@c.id, 8,  9]
-          })
-        end
-      end
-
-      context "a child with children" do
-        should "not mess up the tree" do
-          assert_difference 'Project.count', -2 do
-            Project.find_by_name('Project B1').destroy
-          end
-          assert_nested_set_values({
-            @a  => [nil,   1,  6],
-            @b  => [nil,   7, 10],
-            @b2 => [@b.id, 8,  9],
-            @c  => [nil,  11, 14]
-          })
-        end
-      end
-    end
-  end
-
-  def assert_nested_set_values(h)
-    assert Project.valid?
-    h.each do |project, expected|
-      project.reload
-      assert_equal expected, [project.parent_id, project.lft, project.rgt], "Unexpected nested set values for #{project.name}"
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/11/110c099a0d3863ceae49596e622ce49ebec0b0f7.svn-base
--- /dev/null
+++ b/.svn/pristine/11/110c099a0d3863ceae49596e622ce49ebec0b0f7.svn-base
@@ -0,0 +1,88 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Acts
+    module ActivityProvider
+      def self.included(base)
+        base.extend ClassMethods
+      end
+
+      module ClassMethods
+        def acts_as_activity_provider(options = {})
+          unless self.included_modules.include?(Redmine::Acts::ActivityProvider::InstanceMethods)
+            cattr_accessor :activity_provider_options
+            send :include, Redmine::Acts::ActivityProvider::InstanceMethods
+          end
+
+          options.assert_valid_keys(:type, :permission, :timestamp, :author_key, :find_options)
+          self.activity_provider_options ||= {}
+
+          # One model can provide different event types
+          # We store these options in activity_provider_options hash
+          event_type = options.delete(:type) || self.name.underscore.pluralize
+
+          options[:timestamp] ||= "#{table_name}.created_on"
+          options[:find_options] ||= {}
+          options[:author_key] = "#{table_name}.#{options[:author_key]}" if options[:author_key].is_a?(Symbol)
+          self.activity_provider_options[event_type] = options
+        end
+      end
+
+      module InstanceMethods
+        def self.included(base)
+          base.extend ClassMethods
+        end
+
+        module ClassMethods
+          # Returns events of type event_type visible by user that occured between from and to
+          def find_events(event_type, user, from, to, options)
+            provider_options = activity_provider_options[event_type]
+            raise "#{self.name} can not provide #{event_type} events." if provider_options.nil?
+
+            scope = self
+
+            if from && to
+              scope = scope.scoped(:conditions => ["#{provider_options[:timestamp]} BETWEEN ? AND ?", from, to])
+            end
+
+            if options[:author]
+              return [] if provider_options[:author_key].nil?
+              scope = scope.scoped(:conditions => ["#{provider_options[:author_key]} = ?", options[:author].id])
+            end
+
+            if options[:limit]
+              # id and creation time should be in same order in most cases
+              scope = scope.scoped(:order => "#{table_name}.id DESC", :limit => options[:limit])
+            end
+
+            if provider_options.has_key?(:permission)
+              scope = scope.scoped(:conditions => Project.allowed_to_condition(user, provider_options[:permission] || :view_project, options))
+            elsif respond_to?(:visible)
+              scope = scope.visible(user, options)
+            else
+              ActiveSupport::Deprecation.warn "acts_as_activity_provider with implicit :permission option is deprecated. Add a visible scope to the #{self.name} model or use explicit :permission option."
+              scope = scope.scoped(:conditions => Project.allowed_to_condition(user, "view_#{self.name.underscore.pluralize}".to_sym, options))
+            end
+
+            scope.all(provider_options[:find_options].dup)
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/11/111782291673fa0d25a1477bea1c5d346d154c35.svn-base
--- a/.svn/pristine/11/111782291673fa0d25a1477bea1c5d346d154c35.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (c) 2009 Michael Koziarski <michael@koziarski.com>
-# 
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-# 
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-require 'bigdecimal'
-
-alias BigDecimalUnsafe BigDecimal
-
-
-# This fixes CVE-2009-1904 however it removes legitimate functionality that your
-# application may depend on.  You are *strongly* advised to upgrade your ruby
-# rather than relying on this fix for an extended period of time.
-
-def BigDecimal(initial, digits=0)
-  if initial.size > 255 || initial =~ /e/i
-    raise "Invalid big Decimal Value"
-  end
-  BigDecimalUnsafe(initial, digits)
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/11/1126b71d1361e2719f05011613589ea2d0df072c.svn-base
--- a/.svn/pristine/11/1126b71d1361e2719f05011613589ea2d0df072c.svn-base
+++ /dev/null
@@ -1,564 +0,0 @@
-# Copyright (c) 2005 Rick Olson
-# 
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-# 
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-# 
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-module ActiveRecord #:nodoc:
-  module Acts #:nodoc:
-    # Specify this act if you want to save a copy of the row in a versioned table.  This assumes there is a 
-    # versioned table ready and that your model has a version field.  This works with optimistic locking if the lock_version
-    # column is present as well.
-    #
-    # The class for the versioned model is derived the first time it is seen. Therefore, if you change your database schema you have to restart
-    # your container for the changes to be reflected. In development mode this usually means restarting WEBrick.
-    #
-    #   class Page < ActiveRecord::Base
-    #     # assumes pages_versions table
-    #     acts_as_versioned
-    #   end
-    #
-    # Example:
-    #
-    #   page = Page.create(:title => 'hello world!')
-    #   page.version       # => 1
-    #
-    #   page.title = 'hello world'
-    #   page.save
-    #   page.version       # => 2
-    #   page.versions.size # => 2
-    #
-    #   page.revert_to(1)  # using version number
-    #   page.title         # => 'hello world!'
-    #
-    #   page.revert_to(page.versions.last) # using versioned instance
-    #   page.title         # => 'hello world'
-    #
-    #   page.versions.earliest # efficient query to find the first version
-    #   page.versions.latest   # efficient query to find the most recently created version
-    #
-    #
-    # Simple Queries to page between versions
-    #
-    #   page.versions.before(version) 
-    #   page.versions.after(version)
-    #
-    # Access the previous/next versions from the versioned model itself
-    #
-    #   version = page.versions.latest
-    #   version.previous # go back one version
-    #   version.next     # go forward one version
-    #
-    # See ActiveRecord::Acts::Versioned::ClassMethods#acts_as_versioned for configuration options
-    module Versioned
-      CALLBACKS = [:set_new_version, :save_version_on_create, :save_version?, :clear_altered_attributes]
-      def self.included(base) # :nodoc:
-        base.extend ClassMethods
-      end
-
-      module ClassMethods
-        # == Configuration options
-        #
-        # * <tt>class_name</tt> - versioned model class name (default: PageVersion in the above example)
-        # * <tt>table_name</tt> - versioned model table name (default: page_versions in the above example)
-        # * <tt>foreign_key</tt> - foreign key used to relate the versioned model to the original model (default: page_id in the above example)
-        # * <tt>inheritance_column</tt> - name of the column to save the model's inheritance_column value for STI.  (default: versioned_type)
-        # * <tt>version_column</tt> - name of the column in the model that keeps the version number (default: version)
-        # * <tt>sequence_name</tt> - name of the custom sequence to be used by the versioned model.
-        # * <tt>limit</tt> - number of revisions to keep, defaults to unlimited
-        # * <tt>if</tt> - symbol of method to check before saving a new version.  If this method returns false, a new version is not saved.
-        #   For finer control, pass either a Proc or modify Model#version_condition_met?
-        #
-        #     acts_as_versioned :if => Proc.new { |auction| !auction.expired? }
-        #
-        #   or...
-        #
-        #     class Auction
-        #       def version_condition_met? # totally bypasses the <tt>:if</tt> option
-        #         !expired?
-        #       end
-        #     end
-        #
-        # * <tt>if_changed</tt> - Simple way of specifying attributes that are required to be changed before saving a model.  This takes
-        #   either a symbol or array of symbols.  WARNING - This will attempt to overwrite any attribute setters you may have.
-        #   Use this instead if you want to write your own attribute setters (and ignore if_changed):
-        # 
-        #     def name=(new_name)
-        #       write_changed_attribute :name, new_name
-        #     end
-        #
-        # * <tt>extend</tt> - Lets you specify a module to be mixed in both the original and versioned models.  You can also just pass a block
-        #   to create an anonymous mixin:
-        #
-        #     class Auction
-        #       acts_as_versioned do
-        #         def started?
-        #           !started_at.nil?
-        #         end
-        #       end
-        #     end
-        #
-        #   or...
-        #
-        #     module AuctionExtension
-        #       def started?
-        #         !started_at.nil?
-        #       end
-        #     end
-        #     class Auction
-        #       acts_as_versioned :extend => AuctionExtension
-        #     end
-        #
-        #  Example code:
-        #
-        #    @auction = Auction.find(1)
-        #    @auction.started?
-        #    @auction.versions.first.started?
-        #
-        # == Database Schema
-        #
-        # The model that you're versioning needs to have a 'version' attribute. The model is versioned 
-        # into a table called #{model}_versions where the model name is singlular. The _versions table should 
-        # contain all the fields you want versioned, the same version column, and a #{model}_id foreign key field.
-        #
-        # A lock_version field is also accepted if your model uses Optimistic Locking.  If your table uses Single Table inheritance,
-        # then that field is reflected in the versioned model as 'versioned_type' by default.
-        #
-        # Acts_as_versioned comes prepared with the ActiveRecord::Acts::Versioned::ActMethods::ClassMethods#create_versioned_table 
-        # method, perfect for a migration.  It will also create the version column if the main model does not already have it.
-        #
-        #   class AddVersions < ActiveRecord::Migration
-        #     def self.up
-        #       # create_versioned_table takes the same options hash
-        #       # that create_table does
-        #       Post.create_versioned_table
-        #     end
-        # 
-        #     def self.down
-        #       Post.drop_versioned_table
-        #     end
-        #   end
-        # 
-        # == Changing What Fields Are Versioned
-        #
-        # By default, acts_as_versioned will version all but these fields: 
-        # 
-        #   [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
-        #
-        # You can add or change those by modifying #non_versioned_columns.  Note that this takes strings and not symbols.
-        #
-        #   class Post < ActiveRecord::Base
-        #     acts_as_versioned
-        #     self.non_versioned_columns << 'comments_count'
-        #   end
-        # 
-        def acts_as_versioned(options = {}, &extension)
-          # don't allow multiple calls
-          return if self.included_modules.include?(ActiveRecord::Acts::Versioned::ActMethods)
-
-          send :include, ActiveRecord::Acts::Versioned::ActMethods
-
-          cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column, 
-            :version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
-            :version_association_options
-
-          # legacy
-          alias_method :non_versioned_fields,  :non_versioned_columns
-          alias_method :non_versioned_fields=, :non_versioned_columns=
-
-          class << self
-            alias_method :non_versioned_fields,  :non_versioned_columns
-            alias_method :non_versioned_fields=, :non_versioned_columns=
-          end
-
-          send :attr_accessor, :altered_attributes
-
-          self.versioned_class_name         = options[:class_name]  || "Version"
-          self.versioned_foreign_key        = options[:foreign_key] || self.to_s.foreign_key
-          self.versioned_table_name         = options[:table_name]  || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_versions#{table_name_suffix}"
-          self.versioned_inheritance_column = options[:inheritance_column] || "versioned_#{inheritance_column}"
-          self.version_column               = options[:version_column]     || 'version'
-          self.version_sequence_name        = options[:sequence_name]
-          self.max_version_limit            = options[:limit].to_i
-          self.version_condition            = options[:if] || true
-          self.non_versioned_columns        = [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
-          self.version_association_options  = {
-                                                :class_name  => "#{self.to_s}::#{versioned_class_name}",
-                                                :foreign_key => versioned_foreign_key,
-                                                :dependent   => :delete_all
-                                              }.merge(options[:association_options] || {})
-
-          if block_given?
-            extension_module_name = "#{versioned_class_name}Extension"
-            silence_warnings do
-              self.const_set(extension_module_name, Module.new(&extension))
-            end
-
-            options[:extend] = self.const_get(extension_module_name)
-          end
-
-          class_eval do
-            has_many :versions, version_association_options do
-              # finds earliest version of this record
-              def earliest
-                @earliest ||= find(:first, :order => 'version')
-              end
-
-              # find latest version of this record
-              def latest
-                @latest ||= find(:first, :order => 'version desc')
-              end
-            end
-            before_save  :set_new_version
-            after_create :save_version_on_create
-            after_update :save_version
-            after_save   :clear_old_versions
-            after_save   :clear_altered_attributes
-
-            unless options[:if_changed].nil?
-              self.track_altered_attributes = true
-              options[:if_changed] = [options[:if_changed]] unless options[:if_changed].is_a?(Array)
-              options[:if_changed].each do |attr_name|
-                define_method("#{attr_name}=") do |value|
-                  write_changed_attribute attr_name, value
-                end
-              end
-            end
-
-            include options[:extend] if options[:extend].is_a?(Module)
-          end
-
-          # create the dynamic versioned model
-          const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
-            def self.reloadable? ; false ; end
-            # find first version before the given version
-            def self.before(version)
-              find :first, :order => 'version desc',
-                :conditions => ["#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version]
-            end
-
-            # find first version after the given version.
-            def self.after(version)
-              find :first, :order => 'version',
-                :conditions => ["#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version]
-            end
-
-            def previous
-              self.class.before(self)
-            end
-
-            def next
-              self.class.after(self)
-            end
-
-            def versions_count
-              page.version
-            end
-          end
-
-          versioned_class.cattr_accessor :original_class
-          versioned_class.original_class = self
-          versioned_class.set_table_name versioned_table_name
-          versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym, 
-            :class_name  => "::#{self.to_s}", 
-            :foreign_key => versioned_foreign_key
-          versioned_class.send :include, options[:extend]         if options[:extend].is_a?(Module)
-          versioned_class.set_sequence_name version_sequence_name if version_sequence_name
-        end
-      end
-
-      module ActMethods
-        def self.included(base) # :nodoc:
-          base.extend ClassMethods
-        end
-
-        # Finds a specific version of this record
-        def find_version(version = nil)
-          self.class.find_version(id, version)
-        end
-
-        # Saves a version of the model if applicable
-        def save_version
-          save_version_on_create if save_version?
-        end
-
-        # Saves a version of the model in the versioned table.  This is called in the after_save callback by default
-        def save_version_on_create
-          rev = self.class.versioned_class.new
-          self.clone_versioned_model(self, rev)
-          rev.version = send(self.class.version_column)
-          rev.send("#{self.class.versioned_foreign_key}=", self.id)
-          rev.save
-        end
-
-        # Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
-        # Override this method to set your own criteria for clearing old versions.
-        def clear_old_versions
-          return if self.class.max_version_limit == 0
-          excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
-          if excess_baggage > 0
-            sql = "DELETE FROM #{self.class.versioned_table_name} WHERE version <= #{excess_baggage} AND #{self.class.versioned_foreign_key} = #{self.id}"
-            self.class.versioned_class.connection.execute sql
-          end
-        end
-
-        def versions_count
-          version
-        end
-
-        # Reverts a model to a given version.  Takes either a version number or an instance of the versioned model
-        def revert_to(version)
-          if version.is_a?(self.class.versioned_class)
-            return false unless version.send(self.class.versioned_foreign_key) == self.id and !version.new_record?
-          else
-            return false unless version = versions.find_by_version(version)
-          end
-          self.clone_versioned_model(version, self)
-          self.send("#{self.class.version_column}=", version.version)
-          true
-        end
-
-        # Reverts a model to a given version and saves the model.
-        # Takes either a version number or an instance of the versioned model
-        def revert_to!(version)
-          revert_to(version) ? save_without_revision : false
-        end
-
-        # Temporarily turns off Optimistic Locking while saving.  Used when reverting so that a new version is not created.
-        def save_without_revision
-          save_without_revision!
-          true
-        rescue
-          false
-        end
-
-        def save_without_revision!
-          without_locking do
-            without_revision do
-              save!
-            end
-          end
-        end
-
-        # Returns an array of attribute keys that are versioned.  See non_versioned_columns
-        def versioned_attributes
-          self.attributes.keys.select { |k| !self.class.non_versioned_columns.include?(k) }
-        end
-
-        # If called with no parameters, gets whether the current model has changed and needs to be versioned.
-        # If called with a single parameter, gets whether the parameter has changed.
-        def changed?(attr_name = nil)
-          attr_name.nil? ?
-            (!self.class.track_altered_attributes || (altered_attributes && altered_attributes.length > 0)) :
-            (altered_attributes && altered_attributes.include?(attr_name.to_s))
-        end
-
-        # keep old dirty? method
-        alias_method :dirty?, :changed?
-
-        # Clones a model.  Used when saving a new version or reverting a model's version.
-        def clone_versioned_model(orig_model, new_model)
-          self.versioned_attributes.each do |key|
-            new_model.send("#{key}=", orig_model.send(key)) if orig_model.has_attribute?(key)
-          end
-
-          if orig_model.is_a?(self.class.versioned_class)
-            new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
-          elsif new_model.is_a?(self.class.versioned_class)
-            new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
-          end
-        end
-
-        # Checks whether a new version shall be saved or not.  Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
-        def save_version?
-          version_condition_met? && changed?
-        end
-
-        # Checks condition set in the :if option to check whether a revision should be created or not.  Override this for
-        # custom version condition checking.
-        def version_condition_met?
-          case
-          when version_condition.is_a?(Symbol)
-            send(version_condition)
-          when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
-            version_condition.call(self)
-          else
-            version_condition
-          end
-        end
-
-        # Executes the block with the versioning callbacks disabled.
-        #
-        #   @foo.without_revision do
-        #     @foo.save
-        #   end
-        #
-        def without_revision(&block)
-          self.class.without_revision(&block)
-        end
-
-        # Turns off optimistic locking for the duration of the block
-        #
-        #   @foo.without_locking do
-        #     @foo.save
-        #   end
-        #
-        def without_locking(&block)
-          self.class.without_locking(&block)
-        end
-
-        def empty_callback() end #:nodoc:
-
-        protected
-          # sets the new version before saving, unless you're using optimistic locking.  In that case, let it take care of the version.
-          def set_new_version
-            self.send("#{self.class.version_column}=", self.next_version) if new_record? || (!locking_enabled? && save_version?)
-          end
-
-          # Gets the next available version for the current record, or 1 for a new record
-          def next_version
-            return 1 if new_record?
-            (versions.calculate(:max, :version) || 0) + 1
-          end
-
-          # clears current changed attributes.  Called after save.
-          def clear_altered_attributes
-            self.altered_attributes = []
-          end
-
-          def write_changed_attribute(attr_name, attr_value)
-            # Convert to db type for comparison. Avoids failing Float<=>String comparisons.
-            attr_value_for_db = self.class.columns_hash[attr_name.to_s].type_cast(attr_value)
-            (self.altered_attributes ||= []) << attr_name.to_s unless self.changed?(attr_name) || self.send(attr_name) == attr_value_for_db
-            write_attribute(attr_name, attr_value_for_db)
-          end
-
-        module ClassMethods
-          # Finds a specific version of a specific row of this model
-          def find_version(id, version = nil)
-            return find(id) unless version
-
-            conditions = ["#{versioned_foreign_key} = ? AND version = ?", id, version]
-            options = { :conditions => conditions, :limit => 1 }
-
-            if result = find_versions(id, options).first
-              result
-            else
-              raise RecordNotFound, "Couldn't find #{name} with ID=#{id} and VERSION=#{version}"
-            end
-          end
-
-          # Finds versions of a specific model.  Takes an options hash like <tt>find</tt>
-          def find_versions(id, options = {})
-            versioned_class.find :all, {
-              :conditions => ["#{versioned_foreign_key} = ?", id],
-              :order      => 'version' }.merge(options)
-          end
-
-          # Returns an array of columns that are versioned.  See non_versioned_columns
-          def versioned_columns
-            self.columns.select { |c| !non_versioned_columns.include?(c.name) }
-          end
-
-          # Returns an instance of the dynamic versioned model
-          def versioned_class
-            const_get versioned_class_name
-          end
-
-          # Rake migration task to create the versioned table using options passed to acts_as_versioned
-          def create_versioned_table(create_table_options = {})
-            # create version column in main table if it does not exist
-            if !self.content_columns.find { |c| %w(version lock_version).include? c.name }
-              self.connection.add_column table_name, :version, :integer
-            end
-
-            self.connection.create_table(versioned_table_name, create_table_options) do |t|
-              t.column versioned_foreign_key, :integer
-              t.column :version, :integer
-            end
-
-            updated_col = nil
-            self.versioned_columns.each do |col| 
-              updated_col = col if !updated_col && %(updated_at updated_on).include?(col.name)
-              self.connection.add_column versioned_table_name, col.name, col.type, 
-                :limit => col.limit, 
-                :default => col.default,
-                :scale => col.scale,
-                :precision => col.precision
-            end
-
-            if type_col = self.columns_hash[inheritance_column]
-              self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type, 
-                :limit => type_col.limit, 
-                :default => type_col.default,
-                :scale => type_col.scale,
-                :precision => type_col.precision
-            end
-
-            if updated_col.nil?
-              self.connection.add_column versioned_table_name, :updated_at, :timestamp
-            end
-          end
-
-          # Rake migration task to drop the versioned table
-          def drop_versioned_table
-            self.connection.drop_table versioned_table_name
-          end
-
-          # Executes the block with the versioning callbacks disabled.
-          #
-          #   Foo.without_revision do
-          #     @foo.save
-          #   end
-          #
-          def without_revision(&block)
-            class_eval do 
-              CALLBACKS.each do |attr_name|
-                alias_method "orig_#{attr_name}".to_sym, attr_name
-                alias_method attr_name, :empty_callback
-              end
-            end
-            block.call
-          ensure
-            class_eval do 
-              CALLBACKS.each do |attr_name|
-                alias_method attr_name, "orig_#{attr_name}".to_sym
-              end
-            end
-          end
-
-          # Turns off optimistic locking for the duration of the block
-          #
-          #   Foo.without_locking do
-          #     @foo.save
-          #   end
-          #
-          def without_locking(&block)
-            current = ActiveRecord::Base.lock_optimistically
-            ActiveRecord::Base.lock_optimistically = false if current
-            result = block.call
-            ActiveRecord::Base.lock_optimistically = true if current
-            result
-          end
-        end
-      end
-    end
-  end
-end
-
-ActiveRecord::Base.send :include, ActiveRecord::Acts::Versioned
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/11/11276ad92ab446760ef27dc63e4ad98666e8240c.svn-base
--- /dev/null
+++ b/.svn/pristine/11/11276ad92ab446760ef27dc63e4ad98666e8240c.svn-base
@@ -0,0 +1,51 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingAccountTest < ActionController::IntegrationTest
+  def test_account
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/login" },
+          { :controller => 'account', :action => 'login' }
+        )
+    end
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/logout" },
+          { :controller => 'account', :action => 'logout' }
+        )
+    end
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/account/register" },
+          { :controller => 'account', :action => 'register' }
+        )
+    end
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/account/lost_password" },
+          { :controller => 'account', :action => 'lost_password' }
+        )
+    end
+    assert_routing(
+        { :method => 'get', :path => "/account/activate" },
+        { :controller => 'account', :action => 'activate' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/11/114393c547ad97cfcaa80a6e77c3315b6cf82431.svn-base
--- a/.svn/pristine/11/114393c547ad97cfcaa80a6e77c3315b6cf82431.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-module MailHelper
-  def do_something_helpful(var)
-    var.to_s.reverse
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/11/114804002a97fae230bf3b7bfcc60886698c2dd0.svn-base
--- a/.svn/pristine/11/114804002a97fae230bf3b7bfcc60886698c2dd0.svn-base
+++ /dev/null
@@ -1,42 +0,0 @@
-<% if @deliveries %>
-<% form_tag({:action => 'edit', :tab => 'notifications'}) do %>
-
-<div class="box tabular settings">
-<p><%= setting_text_field :mail_from, :size => 60 %></p>
-
-<p><%= setting_check_box :bcc_recipients %></p>
-
-<p><%= setting_check_box :plain_text_mail %></p>
-
-<p><%= setting_select(:default_notification_option, User.valid_notification_options.collect {|o| [l(o.last), o.first.to_s]}) %></p>
-
-</div>
-
-<fieldset class="box" id="notified_events"><legend><%=l(:text_select_mail_notifications)%></legend>
-<%= hidden_field_tag 'settings[notified_events][]', '' %>
-<% @notifiables.each do |notifiable| %>
-<%= notification_field notifiable %>
-<br />
-<% end %>
-<p><%= check_all_links('notified_events') %></p>
-</fieldset>
-
-<fieldset class="box"><legend><%= l(:setting_emails_header) %></legend>
-<%= setting_text_area :emails_header, :label => false, :class => 'wiki-edit', :rows => 5 %>
-</fieldset>
-
-<fieldset class="box"><legend><%= l(:setting_emails_footer) %></legend>
-<%= setting_text_area :emails_footer, :label => false, :class => 'wiki-edit', :rows => 5 %>
-</fieldset>
-
-<div style="float:right;">
-<%= link_to l(:label_send_test_email), :controller => 'admin', :action => 'test_email' %>
-</div>
-
-<%= submit_tag l(:button_save) %>
-<% end %>
-<% else %>
-<div class="nodata">
-<%= simple_format(l(:text_email_delivery_not_configured)) %>
-</div>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/11/114bca33e13814e69bb30791d00e3851d89cb11c.svn-base
--- a/.svn/pristine/11/114bca33e13814e69bb30791d00e3851d89cb11c.svn-base
+++ /dev/null
@@ -1,14 +0,0 @@
-documents_001: 
-  created_on: 2007-01-27 15:08:27 +01:00
-  project_id: 1
-  title: "Test document"
-  id: 1
-  description: "Document description"
-  category_id: 1
-documents_002: 
-  created_on: 2007-02-12 15:08:27 +01:00
-  project_id: 1
-  title: "An other document"
-  id: 2
-  description: ""
-  category_id: 1
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/11/119d49f6464bf67d20c576180ecf3171b1346824.svn-base
--- a/.svn/pristine/11/119d49f6464bf67d20c576180ecf3171b1346824.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Gampol Thitinilnithi, <gampolt@gmail.com>
-// Encoding: UTF-8
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("à¸­à¸²à¸—à¸´à¸•à¸¢à¹Œ",
- "à¸ˆà¸±à¸™à¸—à¸£à¹Œ",
- "à¸­à¸±à¸‡à¸„à¸²à¸£",
- "à¸žà¸¸à¸˜",
- "à¸žà¸¤à¸«à¸±à¸ªà¸šà¸”à¸µ",
- "à¸¨à¸¸à¸à¸£à¹Œ",
- "à¹€à¸ªà¸²à¸£à¹Œ",
- "à¸­à¸²à¸—à¸´à¸•à¸¢à¹Œ");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("à¸­à¸².",
- "à¸ˆ.",
- "à¸­.",
- "à¸ž.",
- "à¸žà¸¤.",
- "à¸¨.",
- "à¸ª.",
- "à¸­à¸².");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("à¸¡à¸à¸£à¸²à¸„à¸¡",
- "à¸à¸¸à¸¡à¸ à¸²à¸žà¸±à¸™à¸˜à¹Œ",
- "à¸¡à¸µà¸™à¸²à¸„à¸¡",
- "à¹€à¸¡à¸©à¸²à¸¢à¸™",
- "à¸žà¸¤à¸©à¸ à¸²à¸„à¸¡",
- "à¸¡à¸´à¸–à¸¸à¸™à¸²à¸¢à¸™",
- "à¸à¸£à¸à¸Žà¸²à¸„à¸¡",
- "à¸ªà¸´à¸‡à¸«à¸²à¸„à¸¡",
- "à¸à¸±à¸™à¸¢à¸²à¸¢à¸™",
- "à¸•à¸¸à¸¥à¸²à¸„à¸¡",
- "à¸žà¸¤à¸¨à¸ˆà¸´à¸à¸²à¸¢à¸™",
- "à¸˜à¸±à¸™à¸§à¸²à¸„à¸¡");
-
-// short month names
-Calendar._SMN = new Array
-("à¸¡.à¸„.",
- "à¸.à¸ž.",
- "à¸¡à¸µ.à¸„.",
- "à¹€à¸¡.à¸¢.",
- "à¸ž.à¸„.",
- "à¸¡à¸´.à¸¢.",
- "à¸.à¸„.",
- "à¸ª.à¸„.",
- "à¸.à¸¢.",
- "à¸•.à¸„.",
- "à¸ž.à¸¢.",
- "à¸˜.à¸„.");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "à¹€à¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸›à¸à¸´à¸—à¸´à¸™";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "à¸›à¸µà¸—à¸µà¹ˆà¹à¸¥à¹‰à¸§ (à¸–à¹‰à¸²à¸à¸”à¸„à¹‰à¸²à¸‡à¸ˆà¸°à¸¡à¸µà¹€à¸¡à¸™à¸¹)";
-Calendar._TT["PREV_MONTH"] = "à¹€à¸”à¸·à¸­à¸™à¸—à¸µà¹ˆà¹à¸¥à¹‰à¸§ (à¸–à¹‰à¸²à¸à¸”à¸„à¹‰à¸²à¸‡à¸ˆà¸°à¸¡à¸µà¹€à¸¡à¸™à¸¹)";
-Calendar._TT["GO_TODAY"] = "à¹„à¸›à¸—à¸µà¹ˆà¸§à¸±à¸™à¸™à¸µà¹‰";
-Calendar._TT["NEXT_MONTH"] = "à¹€à¸”à¸·à¸­à¸™à¸«à¸™à¹‰à¸² (à¸–à¹‰à¸²à¸à¸”à¸„à¹‰à¸²à¸‡à¸ˆà¸°à¸¡à¸µà¹€à¸¡à¸™à¸¹)";
-Calendar._TT["NEXT_YEAR"] = "à¸›à¸µà¸«à¸™à¹‰à¸² (à¸–à¹‰à¸²à¸à¸”à¸„à¹‰à¸²à¸‡à¸ˆà¸°à¸¡à¸µà¹€à¸¡à¸™à¸¹)";
-Calendar._TT["SEL_DATE"] = "à¹€à¸¥à¸·à¸­à¸à¸§à¸±à¸™";
-Calendar._TT["DRAG_TO_MOVE"] = "à¸à¸”à¹à¸¥à¹‰à¸§à¸¥à¸²à¸à¹€à¸žà¸·à¹ˆà¸­à¸¢à¹‰à¸²à¸¢";
-Calendar._TT["PART_TODAY"] = " (à¸§à¸±à¸™à¸™à¸µà¹‰)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "à¹à¸ªà¸”à¸‡ %s à¹€à¸›à¹‡à¸™à¸§à¸±à¸™à¹à¸£à¸";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "à¸›à¸´à¸”";
-Calendar._TT["TODAY"] = "à¸§à¸±à¸™à¸™à¸µà¹‰";
-Calendar._TT["TIME_PART"] = "(Shift-)à¸à¸”à¸«à¸£à¸·à¸­à¸à¸”à¹à¸¥à¹‰à¸§à¸¥à¸²à¸à¹€à¸žà¸·à¹ˆà¸­à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸„à¹ˆà¸²";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a %e %b";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "à¹€à¸§à¸¥à¸²:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/11/11caec7ba0e56486601495ed3e744468ec15f734.svn-base
--- a/.svn/pristine/11/11caec7ba0e56486601495ed3e744468ec15f734.svn-base
+++ /dev/null
@@ -1,48 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module VersionsHelper
-
-  STATUS_BY_CRITERIAS = %w(category tracker status priority author assigned_to)
-
-  def render_issue_status_by(version, criteria)
-    criteria = 'category' unless STATUS_BY_CRITERIAS.include?(criteria)
-
-    h = Hash.new {|k,v| k[v] = [0, 0]}
-    begin
-      # Total issue count
-      Issue.count(:group => criteria,
-                  :conditions => ["#{Issue.table_name}.fixed_version_id = ?", version.id]).each {|c,s| h[c][0] = s}
-      # Open issues count
-      Issue.count(:group => criteria,
-                  :include => :status,
-                  :conditions => ["#{Issue.table_name}.fixed_version_id = ? AND #{IssueStatus.table_name}.is_closed = ?", version.id, false]).each {|c,s| h[c][1] = s}
-    rescue ActiveRecord::RecordNotFound
-    # When grouping by an association, Rails throws this exception if there's no result (bug)
-    end
-    counts = h.keys.compact.sort.collect {|k| {:group => k, :total => h[k][0], :open => h[k][1], :closed => (h[k][0] - h[k][1])}}
-    max = counts.collect {|c| c[:total]}.max
-
-    render :partial => 'issue_counts', :locals => {:version => version, :criteria => criteria, :counts => counts, :max => max}
-  end
-
-  def status_by_options_for_select(value)
-    options_for_select(STATUS_BY_CRITERIAS.collect {|criteria| [l("field_#{criteria}".to_sym), criteria]}, value)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/12/120840d537ad68f417065b102e2763e8f985fe62.svn-base
--- /dev/null
+++ b/.svn/pristine/12/120840d537ad68f417065b102e2763e8f985fe62.svn-base
@@ -0,0 +1,125 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class MembersController < ApplicationController
+  model_object Member
+  before_filter :find_model_object, :except => [:index, :create, :autocomplete]
+  before_filter :find_project_from_association, :except => [:index, :create, :autocomplete]
+  before_filter :find_project_by_project_id, :only => [:index, :create, :autocomplete]
+  before_filter :authorize
+  accept_api_auth :index, :show, :create, :update, :destroy
+
+  def index
+    @offset, @limit = api_offset_and_limit
+    @member_count = @project.member_principals.count
+    @member_pages = Paginator.new @member_count, @limit, params['page']
+    @offset ||= @member_pages.offset
+    @members =  @project.member_principals.all(
+      :order => "#{Member.table_name}.id",
+      :limit  =>  @limit,
+      :offset =>  @offset
+    )
+
+    respond_to do |format|
+      format.html { head 406 }
+      format.api
+    end
+  end
+
+  def show
+    respond_to do |format|
+      format.html { head 406 }
+      format.api
+    end
+  end
+
+  def create
+    members = []
+    if params[:membership]
+      if params[:membership][:user_ids]
+        attrs = params[:membership].dup
+        user_ids = attrs.delete(:user_ids)
+        user_ids.each do |user_id|
+          members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id)
+        end
+      else
+        members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id])
+      end
+      @project.members << members
+    end
+
+    respond_to do |format|
+      format.html { redirect_to_settings_in_projects }
+      format.js { @members = members }
+      format.api {
+        @member = members.first
+        if @member.valid?
+          render :action => 'show', :status => :created, :location => membership_url(@member)
+        else
+          render_validation_errors(@member)
+        end
+      }
+    end
+  end
+
+  def update
+    if params[:membership]
+      @member.role_ids = params[:membership][:role_ids]
+    end
+    saved = @member.save
+    respond_to do |format|
+      format.html { redirect_to_settings_in_projects }
+      format.js
+      format.api {
+        if saved
+          render_api_ok
+        else
+          render_validation_errors(@member)
+        end
+      }
+    end
+  end
+
+  def destroy
+    if request.delete? && @member.deletable?
+      @member.destroy
+    end
+    respond_to do |format|
+      format.html { redirect_to_settings_in_projects }
+      format.js
+      format.api {
+        if @member.destroyed?
+          render_api_ok
+        else
+          head :unprocessable_entity
+        end
+      }
+    end
+  end
+
+  def autocomplete
+    respond_to do |format|
+      format.js
+    end
+  end
+
+  private
+
+  def redirect_to_settings_in_projects
+    redirect_to settings_project_path(@project, :tab => 'members')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/12/121eeed4fcb10e023ef41b53336708e73d10e3e6.svn-base
--- /dev/null
+++ b/.svn/pristine/12/121eeed4fcb10e023ef41b53336708e73d10e3e6.svn-base
@@ -0,0 +1,38 @@
+<%= form_tag({:action => 'edit', :tab => 'authentication'}) do %>
+
+<div class="box tabular settings">
+<p><%= setting_check_box :login_required %></p>
+
+<p><%= setting_select :autologin, [[l(:label_disabled), 0]] + [1, 7, 30, 365].collect{|days| [l('datetime.distance_in_words.x_days', :count => days), days.to_s]} %></p>
+
+<p><%= setting_select :self_registration, [[l(:label_disabled), "0"],
+                                           [l(:label_registration_activation_by_email), "1"],
+                                           [l(:label_registration_manual_activation), "2"],
+                                           [l(:label_registration_automatic_activation), "3"]] %></p>
+
+<p><%= setting_check_box :unsubscribe %></p>
+
+<p><%= setting_text_field :password_min_length, :size => 6 %></p>
+
+<p><%= setting_check_box :lost_password, :label => :label_password_lost %></p>
+
+<p><%= setting_check_box :openid, :disabled => !Object.const_defined?(:OpenID) %></p>
+
+<p><%= setting_check_box :rest_api_enabled %></p>
+
+<p><%= setting_check_box :jsonp_enabled %></p>
+</div>
+
+<fieldset class="box">
+  <legend><%= l(:label_session_expiration) %></legend>
+
+  <div class="tabular settings">
+    <p><%= setting_select :session_lifetime, [[l(:label_disabled), 0]] + [1, 7, 30, 60, 365].collect{|days| [l('datetime.distance_in_words.x_days', :count => days), (days * 60 * 24).to_s]} %></p>
+    <p><%= setting_select :session_timeout, [[l(:label_disabled), 0]] + [1, 2, 4, 8, 12, 24, 48].collect{|hours| [l('datetime.distance_in_words.x_hours', :count => hours), (hours * 60).to_s]} %></p>
+  </div>
+  
+  <p><em class="info"><%= l(:text_session_expiration_settings) %></em></p>
+</fieldset>
+
+<%= submit_tag l(:button_save) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/12/124c8ea6c27371f24076da94e97c521fc176d638.svn-base
--- a/.svn/pristine/12/124c8ea6c27371f24076da94e97c521fc176d638.svn-base
+++ /dev/null
@@ -1,77 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class FilesControllerTest < ActionController::TestCase
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :journals, :journal_details,
-           :attachments,
-           :versions
-
-  def setup
-    @controller = FilesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    @request.session[:user_id] = nil
-    Setting.default_language = 'en'
-  end
-
-  def test_index
-    get :index, :project_id => 1
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:containers)
-
-    # file attached to the project
-    assert_tag :a, :content => 'project_file.zip',
-                   :attributes => { :href => '/attachments/download/8/project_file.zip' }
-
-    # file attached to a project's version
-    assert_tag :a, :content => 'version_file.zip',
-                   :attributes => { :href => '/attachments/download/9/version_file.zip' }
-  end
-
-  def test_create_file
-    set_tmp_attachments_directory
-    @request.session[:user_id] = 2
-    Setting.notified_events = ['file_added']
-    ActionMailer::Base.deliveries.clear
-
-    assert_difference 'Attachment.count' do
-      post :create, :project_id => 1, :version_id => '',
-           :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
-      assert_response :redirect
-    end
-    assert_redirected_to '/projects/ecookbook/files'
-    a = Attachment.find(:first, :order => 'created_on DESC')
-    assert_equal 'testfile.txt', a.filename
-    assert_equal Project.find(1), a.container
-
-    mail = ActionMailer::Base.deliveries.last
-    assert_kind_of TMail::Mail, mail
-    assert_equal "[eCookbook] New file", mail.subject
-    assert mail.body.include?('testfile.txt')
-  end
-
-  def test_create_version_file
-    set_tmp_attachments_directory
-    @request.session[:user_id] = 2
-    Setting.notified_events = ['file_added']
-
-    assert_difference 'Attachment.count' do
-      post :create, :project_id => 1, :version_id => '2',
-           :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
-      assert_response :redirect
-    end
-    assert_redirected_to '/projects/ecookbook/files'
-    a = Attachment.find(:first, :order => 'created_on DESC')
-    assert_equal 'testfile.txt', a.filename
-    assert_equal Version.find(2), a.container
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/12/129a1be9ab4fb00e9e24a4a97d3003da6c507962.svn-base
--- a/.svn/pristine/12/129a1be9ab4fb00e9e24a4a97d3003da6c507962.svn-base
+++ /dev/null
@@ -1,32 +0,0 @@
-<% if @project.boards.any? %>
-<table class="list">
-  <thead><tr>
-    <th><%= l(:label_board) %></th>
-    <th><%= l(:field_description) %></th>
-    <th></th>
-    <th></th>
-  </tr></thead>
-  <tbody>
-<% @project.boards.each do |board|
-  next if board.new_record? %>
-  <tr class="<%= cycle 'odd', 'even' %>">
-    <td><%=h board.name %></td>
-    <td><%=h board.description %></td>
-    <td align="center">
-    <% if authorize_for("boards", "edit") %>
-      <%= reorder_links('board', {:controller => 'boards', :action => 'edit', :project_id => @project, :id => board}) %>
-    <% end %>
-    </td>
-    <td class="buttons">
-      <%= link_to_if_authorized l(:button_edit), {:controller => 'boards', :action => 'edit', :project_id => @project, :id => board}, :class => 'icon icon-edit' %>
-      <%= link_to_if_authorized l(:button_delete), {:controller => 'boards', :action => 'destroy', :project_id => @project, :id => board}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
-    </td>
-  </tr>
-<% end %>
-  </tbody>
-</table>
-<% else %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
-
-<p><%= link_to_if_authorized l(:label_board_new), {:controller => 'boards', :action => 'new', :project_id => @project}, :class => 'icon icon-add' %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/12/12d2aa017b97ff487eca5cc334afe4f6ec1d0dc6.svn-base
--- a/.svn/pristine/12/12d2aa017b97ff487eca5cc334afe4f6ec1d0dc6.svn-base
+++ /dev/null
@@ -1,26 +0,0 @@
-class NotifyMail < ActionMailer::Base
-
-  helper :mail
-  
-  def signup(txt)
-    body(:name => txt)
-  end
-  
-  def multipart
-    recipients 'some_address@email.com'
-    subject    'multi part email'
-    from       "another_user@email.com"
-    content_type 'multipart/alternative'
-    
-    part :content_type => "text/html", :body => render_message("multipart_html", {})
-    part "text/plain" do |p|
-      p.body = render_message("multipart_plain", {})
-    end
-  end
-  
-  def implicit_multipart
-    recipients 'some_address@email.com'
-    subject    'multi part email'
-    from       "another_user@email.com"
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/12/12e2bd6b115cd00dd763ce32dbfae0382d38cea8.svn-base
--- /dev/null
+++ b/.svn/pristine/12/12e2bd6b115cd00dd763ce32dbfae0382d38cea8.svn-base
@@ -0,0 +1,183 @@
+desc 'Updates and checks locales against en.yml'
+task :locales do
+  %w(locales:update locales:check_interpolation).collect do |task|
+    Rake::Task[task].invoke
+  end
+end
+
+namespace :locales do
+  desc 'Updates language files based on en.yml content (only works for new top level keys).'
+  task :update do
+    dir = ENV['DIR'] || './config/locales'
+
+    en_strings = YAML.load(File.read(File.join(dir,'en.yml')))['en']
+
+    files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
+    files.sort.each do |file|
+      puts "Updating file #{file}"
+      file_strings = YAML.load(File.read(file))
+      file_strings = file_strings[file_strings.keys.first]
+
+      missing_keys = en_strings.keys - file_strings.keys
+      next if missing_keys.empty?
+
+      puts "==> Missing #{missing_keys.size} keys (#{missing_keys.join(', ')})"
+      lang = File.open(file, 'a')
+
+      missing_keys.each do |key|
+        {key => en_strings[key]}.to_yaml.each_line do |line|
+          next if line =~ /^---/ || line.empty?
+          puts "  #{line}"
+          lang << "  #{line}"
+        end
+      end
+
+      lang.close
+    end
+  end
+
+  desc 'Checks interpolation arguments in locals against en.yml'
+  task :check_interpolation do
+    dir = ENV['DIR'] || './config/locales'
+    en_strings = YAML.load(File.read(File.join(dir,'en.yml')))['en']
+    files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
+    files.sort.each do |file|
+      puts "parsing #{file}..."
+      file_strings = YAML.load_file(file)
+      unless file_strings.is_a?(Hash)
+        puts "#{file}: content is not a Hash (#{file_strings.class.name})"
+        next
+      end
+      unless file_strings.keys.size == 1
+        puts "#{file}: content has multiple keys (#{file_strings.keys.size})"
+        next
+      end
+      file_strings = file_strings[file_strings.keys.first]
+
+      file_strings.each do |key, string|
+        next unless string.is_a?(String)
+        string.scan /%\{\w+\}/ do |match|
+          unless en_strings[key].nil? || en_strings[key].include?(match)
+            puts "#{file}: #{key} uses #{match} not found in en.yml"
+          end
+        end
+      end
+    end
+  end
+
+  desc <<-END_DESC
+Removes a translation string from all locale file (only works for top-level childless non-multiline keys, probably doesn\'t work on windows).
+
+This task does not work on Ruby 1.8.6.
+You need to use Ruby 1.8.7 or later.
+
+Options:
+  key=key_1,key_2    Comma-separated list of keys to delete
+  skip=en,de         Comma-separated list of locale files to ignore (filename without extension)
+END_DESC
+
+  task :remove_key do
+    dir = ENV['DIR'] || './config/locales'
+    files = Dir.glob(File.join(dir,'*.yml'))
+    skips = ENV['skip'] ? Regexp.union(ENV['skip'].split(',')) : nil
+    deletes = ENV['key'] ? Regexp.union(ENV['key'].split(',')) : nil
+    # Ignore multiline keys (begin with | or >) and keys with children (nothing meaningful after :)
+    delete_regex = /\A  #{deletes}: +[^\|>\s#].*\z/
+
+    files.each do |path|
+      # Skip certain locales
+      (puts "Skipping #{path}"; next) if File.basename(path, ".yml") =~ skips
+      puts "Deleting selected keys from #{path}"
+      orig_content = File.open(path, 'r') {|file| file.read}
+      File.open(path, 'w') {|file| orig_content.each_line {|line| file.puts line unless line.chomp =~ delete_regex}}
+    end
+  end
+
+  desc <<-END_DESC
+Adds a new top-level translation string to all locale file (only works for childless keys, probably doesn\'t work on windows, doesn't check for duplicates).
+
+Options:
+  key="some_key=foo"
+  key1="another_key=bar"
+  key_fb="foo=bar"         Keys to add in the form key=value, every option of the form key[,\\d,_*] will be recognised
+  skip=en,de               Comma-separated list of locale files to ignore (filename without extension)
+END_DESC
+
+  task :add_key do
+    dir = ENV['DIR'] || './config/locales'
+    files = Dir.glob(File.join(dir,'*.yml'))
+    skips = ENV['skip'] ? Regexp.union(ENV['skip'].split(',')) : nil
+    keys_regex = /\Akey(\d+|_.+)?\z/
+    adds = ENV.reject {|k,v| !(k =~ keys_regex)}.values.collect {|v| Array.new v.split("=",2)}
+    key_list = adds.collect {|v| v[0]}.join(", ")
+
+    files.each do |path|
+      # Skip certain locales
+      (puts "Skipping #{path}"; next) if File.basename(path, ".yml") =~ skips
+      # TODO: Check for dupliate/existing keys
+      puts "Adding #{key_list} to #{path}"
+      File.open(path, 'a') do |file|
+        adds.each do |kv|
+          Hash[*kv].to_yaml.each_line do |line|
+            file.puts "  #{line}" unless (line =~ /^---/ || line.empty?)
+          end
+        end
+      end
+    end
+  end
+
+  desc 'Duplicates a key. Exemple rake locales:dup key=foo new_key=bar'
+  task :dup do
+    dir = ENV['DIR'] || './config/locales'
+    files = Dir.glob(File.join(dir,'*.yml'))
+    skips = ENV['skip'] ? Regexp.union(ENV['skip'].split(',')) : nil
+    key = ENV['key']
+    new_key = ENV['new_key']
+    abort "Missing key argument" if key.blank?
+    abort "Missing new_key argument" if new_key.blank?
+
+    files.each do |path|
+      # Skip certain locales
+      (puts "Skipping #{path}"; next) if File.basename(path, ".yml") =~ skips
+      puts "Adding #{new_key} to #{path}"
+
+      strings = File.read(path)
+      unless strings =~ /^(  #{key}: .+)$/
+        puts "Key not found in #{path}"
+        next
+      end
+      line = $1
+
+      File.open(path, 'a') do |file|
+        file.puts(line.sub(key, new_key))
+      end
+    end
+  end
+
+  desc 'Check parsing yaml by psych library on Ruby 1.9.'
+
+  # On Fedora 12 and 13, if libyaml-devel is available,
+  # in case of installing by rvm,
+  # Ruby 1.9 default yaml library is psych.
+
+  task :check_parsing_by_psych do
+    begin
+      require 'psych'
+      parser = Psych::Parser.new
+      dir = ENV['DIR'] || './config/locales'
+      files = Dir.glob(File.join(dir,'*.yml'))
+      files.sort.each do |filename|
+        next if File.directory? filename
+        puts "parsing #{filename}..."
+        begin
+          parser.parse File.open(filename)
+        rescue Exception => e1
+          puts(e1.message)
+          puts("")
+        end
+      end
+    rescue Exception => e
+      puts(e.message)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/13/134682aa67acff21c24711968698972a9dfb0d8a.svn-base
--- a/.svn/pristine/13/134682aa67acff21c24711968698972a9dfb0d8a.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= link_to l(:label_role_plural), :controller => 'roles', :action => 'index' %> &#187; <%=l(:label_role_new)%></h2>
-
-<% labelled_tabular_form_for :role, @role, :url => { :action => 'new' }, :html => {:id => 'role_form'} do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_create) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/13/134ab6c377c7865f7eab83c298719a41c97ec009.svn-base
--- /dev/null
+++ b/.svn/pristine/13/134ab6c377c7865f7eab83c298719a41c97ec009.svn-base
@@ -0,0 +1,132 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AttachmentsTest < ActionController::IntegrationTest
+  fixtures :projects, :enabled_modules,
+           :users, :roles, :members, :member_roles,
+           :trackers, :projects_trackers,
+           :issue_statuses, :enumerations
+
+  def test_upload_as_js_and_attach_to_an_issue
+    log_user('jsmith', 'jsmith')
+
+    token = ajax_upload('myupload.txt', 'File content')
+
+    assert_difference 'Issue.count' do
+      post '/projects/ecookbook/issues', {
+          :issue => {:tracker_id => 1, :subject => 'Issue with upload'},
+          :attachments => {'1' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
+        }
+      assert_response 302
+    end
+
+    issue = Issue.order('id DESC').first
+    assert_equal 'Issue with upload', issue.subject
+    assert_equal 1, issue.attachments.count
+
+    attachment = issue.attachments.first
+    assert_equal 'myupload.txt', attachment.filename
+    assert_equal 'My uploaded file', attachment.description
+    assert_equal 'File content'.length, attachment.filesize
+  end
+
+  def test_upload_as_js_and_preview_as_inline_attachment
+    log_user('jsmith', 'jsmith')
+
+    token = ajax_upload('myupload.jpg', 'JPEG content')
+
+    post '/issues/preview/new/ecookbook', {
+        :issue => {:tracker_id => 1, :description => 'Inline upload: !myupload.jpg!'},
+        :attachments => {'1' => {:filename => 'myupload.jpg', :description => 'My uploaded file', :token => token}}
+      }
+    assert_response :success
+
+    attachment_path = response.body.match(%r{<img src="(/attachments/download/\d+/myupload.jpg)"})[1]
+    assert_not_nil token, "No attachment path found in response:\n#{response.body}"
+
+    get attachment_path
+    assert_response :success
+    assert_equal 'JPEG content', response.body
+  end
+
+  def test_upload_and_resubmit_after_validation_failure
+    log_user('jsmith', 'jsmith')
+
+    token = ajax_upload('myupload.txt', 'File content')
+
+    assert_no_difference 'Issue.count' do
+      post '/projects/ecookbook/issues', {
+          :issue => {:tracker_id => 1, :subject => ''},
+          :attachments => {'1' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
+        }
+      assert_response :success
+    end
+    assert_select 'input[type=hidden][name=?][value=?]', 'attachments[p0][token]', token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'myupload.txt'
+    assert_select 'input[name=?][value=?]', 'attachments[p0][description]', 'My uploaded file'
+
+    assert_difference 'Issue.count' do
+      post '/projects/ecookbook/issues', {
+          :issue => {:tracker_id => 1, :subject => 'Issue with upload'},
+          :attachments => {'p0' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
+        }
+      assert_response 302
+    end
+
+    issue = Issue.order('id DESC').first
+    assert_equal 'Issue with upload', issue.subject
+    assert_equal 1, issue.attachments.count
+
+    attachment = issue.attachments.first
+    assert_equal 'myupload.txt', attachment.filename
+    assert_equal 'My uploaded file', attachment.description
+    assert_equal 'File content'.length, attachment.filesize
+  end
+
+  def test_upload_as_js_and_destroy
+    log_user('jsmith', 'jsmith')
+
+    token = ajax_upload('myupload.txt', 'File content')
+
+    attachment = Attachment.order('id DESC').first
+    attachment_path = "/attachments/#{attachment.id}.js?attachment_id=1"
+    assert_include "href: '#{attachment_path}'", response.body, "Path to attachment: #{attachment_path} not found in response:\n#{response.body}"
+
+    assert_difference 'Attachment.count', -1 do
+      delete attachment_path
+      assert_response :success
+    end
+
+    assert_include "$('#attachments_1').remove();", response.body
+  end
+
+  private
+
+  def ajax_upload(filename, content, attachment_id=1)
+    assert_difference 'Attachment.count' do
+      post "/uploads.js?attachment_id=#{attachment_id}&filename=#{filename}", content, {"CONTENT_TYPE" => 'application/octet-stream'}
+      assert_response :success
+      assert_equal 'text/javascript', response.content_type
+    end
+
+    token = response.body.match(/\.val\('(\d+\.[0-9a-f]+)'\)/)[1]
+    assert_not_nil token, "No upload token found in response:\n#{response.body}"
+    token
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/13/1360db03d113fb07eff0808c5131dd75d05da3fd.svn-base
--- a/.svn/pristine/13/1360db03d113fb07eff0808c5131dd75d05da3fd.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-// ** I18N
-
-// Calendar DE language
-// Author: Jack (tR), <jack@jtr.de>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Sonntag",
- "Montag",
- "Dienstag",
- "Mittwoch",
- "Donnerstag",
- "Freitag",
- "Samstag",
- "Sonntag");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// short day names
-Calendar._SDN = new Array
-("So",
- "Mo",
- "Di",
- "Mi",
- "Do",
- "Fr",
- "Sa",
- "So");
-
-// full month names
-Calendar._MN = new Array
-("Januar",
- "Februar",
- "M\u00e4rz",
- "April",
- "Mai",
- "Juni",
- "Juli",
- "August",
- "September",
- "Oktober",
- "November",
- "Dezember");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "M\u00e4r",
- "Apr",
- "May",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Okt",
- "Nov",
- "Dez");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "\u00DCber dieses Kalendarmodul";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Datum ausw\u00e4hlen:\n" +
-"- Benutzen Sie die \xab, \xbb Buttons um das Jahr zu w\u00e4hlen\n" +
-"- Benutzen Sie die " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Buttons um den Monat zu w\u00e4hlen\n" +
-"- F\u00fcr eine Schnellauswahl halten Sie die Maustaste \u00fcber diesen Buttons fest.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Zeit ausw\u00e4hlen:\n" +
-"- Klicken Sie auf die Teile der Uhrzeit, um diese zu erh\u00F6hen\n" +
-"- oder klicken Sie mit festgehaltener Shift-Taste um diese zu verringern\n" +
-"- oder klicken und festhalten f\u00fcr Schnellauswahl.";
-
-Calendar._TT["TOGGLE"] = "Ersten Tag der Woche w\u00e4hlen";
-Calendar._TT["PREV_YEAR"] = "Voriges Jahr (Festhalten f\u00fcr Schnellauswahl)";
-Calendar._TT["PREV_MONTH"] = "Voriger Monat (Festhalten f\u00fcr Schnellauswahl)";
-Calendar._TT["GO_TODAY"] = "Heute ausw\u00e4hlen";
-Calendar._TT["NEXT_MONTH"] = "N\u00e4chst. Monat (Festhalten f\u00fcr Schnellauswahl)";
-Calendar._TT["NEXT_YEAR"] = "N\u00e4chst. Jahr (Festhalten f\u00fcr Schnellauswahl)";
-Calendar._TT["SEL_DATE"] = "Datum ausw\u00e4hlen";
-Calendar._TT["DRAG_TO_MOVE"] = "Zum Bewegen festhalten";
-Calendar._TT["PART_TODAY"] = " (Heute)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Woche beginnt mit %s ";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Schlie\u00dfen";
-Calendar._TT["TODAY"] = "Heute";
-Calendar._TT["TIME_PART"] = "(Shift-)Klick oder Festhalten und Ziehen um den Wert zu \u00e4ndern";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Zeit:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/13/137331c94a623d300b9797520d5d31b04bbcafd5.svn-base
--- a/.svn/pristine/13/137331c94a623d300b9797520d5d31b04bbcafd5.svn-base
+++ /dev/null
@@ -1,62 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class AdminTest < ActionController::IntegrationTest
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows
-
-  def test_add_user
-    log_user("admin", "admin")
-    get "/users/new"
-    assert_response :success
-    assert_template "users/new"
-    post "/users/create",
-         :user => { :login => "psmith", :firstname => "Paul",
-                    :lastname => "Smith", :mail => "psmith@somenet.foo",
-                    :language => "en", :password => "psmith09",
-                    :password_confirmation => "psmith09" }
-
-    user = User.find_by_login("psmith")
-    assert_kind_of User, user
-    assert_redirected_to "/users/#{ user.id }/edit"
-
-    logged_user = User.try_to_login("psmith", "psmith09")
-    assert_kind_of User, logged_user
-    assert_equal "Paul", logged_user.firstname
-
-    put "users/#{user.id}", :id => user.id, :user => { :status => User::STATUS_LOCKED }
-    assert_redirected_to "/users/#{ user.id }/edit"
-    locked_user = User.try_to_login("psmith", "psmith09")
-    assert_equal nil, locked_user
-  end
-
-  test "Add a user as an anonymous user should fail" do
-    post '/users/create',
-         :user => { :login => 'psmith', :firstname => 'Paul'},
-         :password => "psmith09", :password_confirmation => "psmith09"
-    assert_response :redirect
-    assert_redirected_to "/login?back_url=http%3A%2F%2Fwww.example.com%2Fusers"
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/13/1398acbd60647babc95a74c09ce2afa2acef1b0b.svn-base
--- /dev/null
+++ b/.svn/pristine/13/1398acbd60647babc95a74c09ce2afa2acef1b0b.svn-base
@@ -0,0 +1,94 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../../test_helper', __FILE__)
+
+class Redmine::Views::Builders::JsonTest < ActiveSupport::TestCase
+
+  def test_hash
+    assert_json_output({'person' => {'name' => 'Ryan', 'age' => 32}}) do |b|
+      b.person do
+        b.name 'Ryan'
+        b.age  32
+      end
+    end
+  end
+
+  def test_hash_hash
+    assert_json_output({'person' => {'name' => 'Ryan', 'birth' => {'city' => 'London', 'country' => 'UK'}}}) do |b|
+      b.person do
+        b.name 'Ryan'
+        b.birth :city => 'London', :country => 'UK'
+      end
+    end
+
+    assert_json_output({'person' => {'id' => 1, 'name' => 'Ryan', 'birth' => {'city' => 'London', 'country' => 'UK'}}}) do |b|
+      b.person :id => 1 do
+        b.name 'Ryan'
+        b.birth :city => 'London', :country => 'UK'
+      end
+    end
+  end
+
+  def test_array
+    assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
+      b.array :books do |b|
+        b.book :title => 'Book 1', :author => 'B. Smith'
+        b.book :title => 'Book 2', :author => 'G. Cooper'
+      end
+    end
+
+    assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
+      b.array :books do |b|
+        b.book :title => 'Book 1' do
+          b.author 'B. Smith'
+        end
+        b.book :title => 'Book 2' do
+          b.author 'G. Cooper'
+        end
+      end
+    end
+  end
+
+  def test_array_with_content_tags
+    assert_json_output({'books' => [{'value' => 'Book 1', 'author' => 'B. Smith'}, {'value' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
+      b.array :books do |b|
+        b.book 'Book 1', :author => 'B. Smith'
+        b.book 'Book 2', :author => 'G. Cooper'
+      end
+    end
+  end
+
+  def test_nested_arrays
+    assert_json_output({'books' => [{'authors' => ['B. Smith', 'G. Cooper']}]}) do |b|
+      b.array :books do |books|
+        books.book do |book|
+          book.array :authors do |authors|
+            authors.author 'B. Smith'
+            authors.author 'G. Cooper'
+          end
+        end
+      end
+    end
+  end
+
+  def assert_json_output(expected, &block)
+    builder = Redmine::Views::Builders::Json.new(ActionDispatch::TestRequest.new, ActionDispatch::TestResponse.new)
+    block.call(builder)
+    assert_equal(expected, ActiveSupport::JSON.decode(builder.output))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/13/13a9de4a4790249b88f8367228e59b3e03f18775.svn-base
--- a/.svn/pristine/13/13a9de4a4790249b88f8367228e59b3e03f18775.svn-base
+++ /dev/null
@@ -1,72 +0,0 @@
-<div class="contextual">
-<%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
-</div>
-
-<%= render_timelog_breadcrumb %>
-
-<h2><%= l(:label_spent_time) %></h2>
-
-<% form_tag({:controller => 'time_entry_reports', :action => 'report', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %>
-  <% @criterias.each do |criteria| %>
-    <%= hidden_field_tag 'criterias[]', criteria, :id => nil %>
-  <% end %>
-  <%= render :partial => 'timelog/date_range' %>
-
-  <p><label for='columns'><%= l(:label_details) %></label>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'],
-                                                                            [l(:label_month), 'month'],
-                                                                            [l(:label_week), 'week'],
-                                                                            [l(:label_day_plural).titleize, 'day']], @columns),
-                                                        :onchange => "this.form.onsubmit();" %>
-
-  <label for='criterias'><%= l(:button_add) %></label>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l_or_humanize(@available_criterias[k][:label]), k]}),
-                                                          :onchange => "this.form.submit();",
-                                                          :style => 'width: 200px',
-                                                          :id => nil,
-                                                          :disabled => (@criterias.length >= 3), :id => "criterias") %>
-     <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @columns}, :class => 'icon icon-reload' %></p>
-<% end %>
-
-<% unless @criterias.empty? %>
-<div class="total-hours">
-<p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
-</div>
-
-<% unless @hours.empty? %>
-<div class="autoscroll">
-<table class="list" id="time-report">
-<thead>
-<tr>
-<% @criterias.each do |criteria| %>
-  <th><%= l_or_humanize(@available_criterias[criteria][:label]) %></th>
-<% end %>
-<% columns_width = (40 / (@periods.length+1)).to_i %>
-<% @periods.each do |period| %>
-  <th class="period" width="<%= columns_width %>%"><%= period %></th>
-<% end %>
-  <th class="total" width="<%= columns_width %>%"><%= l(:label_total) %></th>
-</tr>
-</thead>
-<tbody>
-<%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
-  <tr class="total">
-  <td><%= l(:label_total) %></td>
-  <%= '<td></td>' * (@criterias.size - 1) %>
-  <% total = 0 -%>
-  <% @periods.each do |period| -%>
-    <% sum = sum_hours(select_hours(@hours, @columns, period.to_s)); total += sum -%>
-    <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
-  <% end -%>
-  <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
-  </tr>
-</tbody>
-</table>
-</div>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'CSV', :url => params %>
-<% end %>
-<% end %>
-<% end %>
-
-<% html_title l(:label_spent_time), l(:label_report) %>
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/13/13d58fac9d8f76e7061c50c043e9ceb3e590857c.svn-base
--- a/.svn/pristine/13/13d58fac9d8f76e7061c50c043e9ceb3e590857c.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class Namespace::SharedPluginController < ApplicationController
-  def an_action
-    render_class_and_action 'from beta_plugin'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/14/141194219711b0b953dd51beb008d5ce7e421ba0.svn-base
--- /dev/null
+++ b/.svn/pristine/14/141194219711b0b953dd51beb008d5ce7e421ba0.svn-base
@@ -0,0 +1,211 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * This file is part of DotClear.
+ * Copyright (c) 2005 Nicolas Martin & Olivier Meunier and contributors. All
+ * rights reserved.
+ *
+ * DotClear is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * DotClear is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with DotClear; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ***** END LICENSE BLOCK *****
+*/
+
+/* Modified by JP LANG for textile formatting */
+
+// strong
+jsToolBar.prototype.elements.strong = {
+	type: 'button',
+	title: 'Strong',
+	fn: {
+		wiki: function() { this.singleTag('*') }
+	}
+}
+
+// em
+jsToolBar.prototype.elements.em = {
+	type: 'button',
+	title: 'Italic',
+	fn: {
+		wiki: function() { this.singleTag("_") }
+	}
+}
+
+// ins
+jsToolBar.prototype.elements.ins = {
+	type: 'button',
+	title: 'Underline',
+	fn: {
+		wiki: function() { this.singleTag('+') }
+	}
+}
+
+// del
+jsToolBar.prototype.elements.del = {
+	type: 'button',
+	title: 'Deleted',
+	fn: {
+		wiki: function() { this.singleTag('-') }
+	}
+}
+
+// code
+jsToolBar.prototype.elements.code = {
+	type: 'button',
+	title: 'Code',
+	fn: {
+		wiki: function() { this.singleTag('@') }
+	}
+}
+
+// spacer
+jsToolBar.prototype.elements.space1 = {type: 'space'}
+
+// headings
+jsToolBar.prototype.elements.h1 = {
+	type: 'button',
+	title: 'Heading 1',
+	fn: {
+		wiki: function() { 
+		  this.encloseLineSelection('h1. ', '',function(str) {
+		    str = str.replace(/^h\d+\.\s+/, '')
+		    return str;
+		  });
+		}
+	}
+}
+jsToolBar.prototype.elements.h2 = {
+	type: 'button',
+	title: 'Heading 2',
+	fn: {
+		wiki: function() { 
+		  this.encloseLineSelection('h2. ', '',function(str) {
+		    str = str.replace(/^h\d+\.\s+/, '')
+		    return str;
+		  });
+		}
+	}
+}
+jsToolBar.prototype.elements.h3 = {
+	type: 'button',
+	title: 'Heading 3',
+	fn: {
+		wiki: function() { 
+		  this.encloseLineSelection('h3. ', '',function(str) {
+		    str = str.replace(/^h\d+\.\s+/, '')
+		    return str;
+		  });
+		}
+	}
+}
+
+// spacer
+jsToolBar.prototype.elements.space2 = {type: 'space'}
+
+// ul
+jsToolBar.prototype.elements.ul = {
+	type: 'button',
+	title: 'Unordered list',
+	fn: {
+		wiki: function() {
+			this.encloseLineSelection('','',function(str) {
+				str = str.replace(/\r/g,'');
+				return str.replace(/(\n|^)[#-]?\s*/g,"$1* ");
+			});
+		}
+	}
+}
+
+// ol
+jsToolBar.prototype.elements.ol = {
+	type: 'button',
+	title: 'Ordered list',
+	fn: {
+		wiki: function() {
+			this.encloseLineSelection('','',function(str) {
+				str = str.replace(/\r/g,'');
+				return str.replace(/(\n|^)[*-]?\s*/g,"$1# ");
+			});
+		}
+	}
+}
+
+// spacer
+jsToolBar.prototype.elements.space3 = {type: 'space'}
+
+// bq
+jsToolBar.prototype.elements.bq = {
+	type: 'button',
+	title: 'Quote',
+	fn: {
+		wiki: function() {
+			this.encloseLineSelection('','',function(str) {
+				str = str.replace(/\r/g,'');
+				return str.replace(/(\n|^) *([^\n]*)/g,"$1> $2");
+			});
+		}
+	}
+}
+
+// unbq
+jsToolBar.prototype.elements.unbq = {
+	type: 'button',
+	title: 'Unquote',
+	fn: {
+		wiki: function() {
+			this.encloseLineSelection('','',function(str) {
+				str = str.replace(/\r/g,'');
+				return str.replace(/(\n|^) *[>]? *([^\n]*)/g,"$1$2");
+			});
+		}
+	}
+}
+
+// pre
+jsToolBar.prototype.elements.pre = {
+	type: 'button',
+	title: 'Preformatted text',
+	fn: {
+		wiki: function() { this.encloseLineSelection('<pre>\n', '\n</pre>') }
+	}
+}
+
+// spacer
+jsToolBar.prototype.elements.space4 = {type: 'space'}
+
+// wiki page
+jsToolBar.prototype.elements.link = {
+	type: 'button',
+	title: 'Wiki link',
+	fn: {
+		wiki: function() { this.encloseSelection("[[", "]]") }
+	}
+}
+// image
+jsToolBar.prototype.elements.img = {
+	type: 'button',
+	title: 'Image',
+	fn: {
+		wiki: function() { this.encloseSelection("!", "!") }
+	}
+}
+
+// spacer
+jsToolBar.prototype.elements.space5 = {type: 'space'}
+// help
+jsToolBar.prototype.elements.help = {
+	type: 'button',
+	title: 'Help',
+	fn: {
+		wiki: function() { window.open(this.help_link, '', 'resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes') }
+	}
+}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/14/1416b352c6fb64d06513cc44f62b6e1f359f63c7.svn-base
--- a/.svn/pristine/14/1416b352c6fb64d06513cc44f62b6e1f359f63c7.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-<%= error_messages_for 'board' %>
-
-<!--[form:board]-->
-<div class="box">
-<p><%= f.text_field :name, :required => true %></p>
-<p><%= f.text_field :description, :required => true, :size => 80 %></p>
-</div>
-<!--[eoform:board]-->
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/14/14189ddfaeae5a33a107c23246aa22c4efcabc20.svn-base
--- /dev/null
+++ b/.svn/pristine/14/14189ddfaeae5a33a107c23246aa22c4efcabc20.svn-base
@@ -0,0 +1,169 @@
+--- 
+users_004: 
+  created_on: 2006-07-19 19:34:07 +02:00
+  status: 1
+  last_login_on: 
+  language: en
+  # password = foo
+  salt: 3126f764c3c5ac61cbfc103f25f934cf
+  hashed_password: 9e4dd7eeb172c12a0691a6d9d3a269f7e9fe671b
+  updated_on: 2006-07-19 19:34:07 +02:00
+  admin: false
+  mail: rhill@somenet.foo
+  lastname: Hill
+  firstname: Robert
+  id: 4
+  auth_source_id: 
+  mail_notification: all
+  login: rhill
+  type: User
+users_001: 
+  created_on: 2006-07-19 19:12:21 +02:00
+  status: 1
+  last_login_on: 2006-07-19 22:57:52 +02:00
+  language: en
+  # password = admin
+  salt: 82090c953c4a0000a7db253b0691a6b4
+  hashed_password: b5b6ff9543bf1387374cdfa27a54c96d236a7150
+  updated_on: 2006-07-19 22:57:52 +02:00
+  admin: true
+  mail: admin@somenet.foo
+  lastname: Admin
+  firstname: Redmine
+  id: 1
+  auth_source_id: 
+  mail_notification: all
+  login: admin
+  type: User
+users_002: 
+  created_on: 2006-07-19 19:32:09 +02:00
+  status: 1
+  last_login_on: 2006-07-19 22:42:15 +02:00
+  language: en
+  # password = jsmith
+  salt: 67eb4732624d5a7753dcea7ce0bb7d7d
+  hashed_password: bfbe06043353a677d0215b26a5800d128d5413bc
+  updated_on: 2006-07-19 22:42:15 +02:00
+  admin: false
+  mail: jsmith@somenet.foo
+  lastname: Smith
+  firstname: John
+  id: 2
+  auth_source_id: 
+  mail_notification: all
+  login: jsmith
+  type: User
+users_003: 
+  created_on: 2006-07-19 19:33:19 +02:00
+  status: 1
+  last_login_on: 
+  language: en
+  # password = foo
+  salt: 7599f9963ec07b5a3b55b354407120c0
+  hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
+  updated_on: 2006-07-19 19:33:19 +02:00
+  admin: false
+  mail: dlopper@somenet.foo
+  lastname: Lopper
+  firstname: Dave
+  id: 3
+  auth_source_id: 
+  mail_notification: all
+  login: dlopper
+  type: User
+users_005: 
+  id: 5
+  created_on: 2006-07-19 19:33:19 +02:00
+  # Locked
+  status: 3
+  last_login_on: 
+  language: en
+  hashed_password: 1
+  updated_on: 2006-07-19 19:33:19 +02:00
+  admin: false
+  mail: dlopper2@somenet.foo
+  lastname: Lopper2
+  firstname: Dave2
+  auth_source_id: 
+  mail_notification: all
+  login: dlopper2
+  type: User
+users_006: 
+  id: 6
+  created_on: 2006-07-19 19:33:19 +02:00
+  status: 0
+  last_login_on: 
+  language: ''
+  hashed_password: 1
+  updated_on: 2006-07-19 19:33:19 +02:00
+  admin: false
+  mail: ''
+  lastname: Anonymous
+  firstname: ''
+  auth_source_id: 
+  mail_notification: only_my_events
+  login: ''
+  type: AnonymousUser
+users_007: 
+  # A user who does not belong to any project
+  id: 7
+  created_on: 2006-07-19 19:33:19 +02:00
+  status: 1
+  last_login_on: 
+  language: 'en'
+  # password = foo
+  salt: 7599f9963ec07b5a3b55b354407120c0
+  hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
+  updated_on: 2006-07-19 19:33:19 +02:00
+  admin: false
+  mail: someone@foo.bar
+  lastname: One
+  firstname: Some
+  auth_source_id: 
+  mail_notification: only_my_events
+  login: someone
+  type: User
+users_008: 
+  id: 8
+  created_on: 2006-07-19 19:33:19 +02:00
+  status: 1
+  last_login_on: 
+  language: 'it'
+  # password = foo
+  salt: 7599f9963ec07b5a3b55b354407120c0
+  hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
+  updated_on: 2006-07-19 19:33:19 +02:00
+  admin: false
+  mail: miscuser8@foo.bar
+  lastname: Misc
+  firstname: User
+  auth_source_id: 
+  mail_notification: only_my_events
+  login: miscuser8
+  type: User
+users_009: 
+  id: 9
+  created_on: 2006-07-19 19:33:19 +02:00
+  status: 1
+  last_login_on: 
+  language: 'it'
+  hashed_password: 1
+  updated_on: 2006-07-19 19:33:19 +02:00
+  admin: false
+  mail: miscuser9@foo.bar
+  lastname: Misc
+  firstname: User
+  auth_source_id: 
+  mail_notification: only_my_events
+  login: miscuser9
+  type: User
+groups_010: 
+  id: 10
+  lastname: A Team
+  type: Group
+groups_011: 
+  id: 11
+  lastname: B Team
+  type: Group
+
+  
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/14/142eda77e7e23817ff1c9eecae08c12f33882ae4.svn-base
--- a/.svn/pristine/14/142eda77e7e23817ff1c9eecae08c12f33882ae4.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-en:
-  hello: "Hello from beta"
-  plugin: "beta"
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/14/147267197c59e4171e424ec83498747a79bcc270.svn-base
--- a/.svn/pristine/14/147267197c59e4171e424ec83498747a79bcc270.svn-base
+++ /dev/null
@@ -1,74 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class WikiRedirectTest < ActiveSupport::TestCase
-  fixtures :projects, :wikis, :wiki_pages
-
-  def setup
-    @wiki = Wiki.find(1)
-    @original = WikiPage.create(:wiki => @wiki, :title => 'Original title')
-  end
-
-  def test_create_redirect
-    @original.title = 'New title'
-    assert @original.save
-    @original.reload
-
-    assert_equal 'New_title', @original.title
-    assert @wiki.redirects.find_by_title('Original_title')
-    assert @wiki.find_page('Original title')
-    assert @wiki.find_page('ORIGINAL title')
-  end
-
-  def test_update_redirect
-    # create a redirect that point to this page
-    assert WikiRedirect.create(:wiki => @wiki, :title => 'An_old_page', :redirects_to => 'Original_title')
-
-    @original.title = 'New title'
-    @original.save
-    # make sure the old page now points to the new page
-    assert_equal 'New_title', @wiki.find_page('An old page').title
-  end
-
-  def test_reverse_rename
-    # create a redirect that point to this page
-    assert WikiRedirect.create(:wiki => @wiki, :title => 'An_old_page', :redirects_to => 'Original_title')
-
-    @original.title = 'An old page'
-    @original.save
-    assert !@wiki.redirects.find_by_title_and_redirects_to('An_old_page', 'An_old_page')
-    assert @wiki.redirects.find_by_title_and_redirects_to('Original_title', 'An_old_page')
-  end
-
-  def test_rename_to_already_redirected
-    assert WikiRedirect.create(:wiki => @wiki, :title => 'An_old_page', :redirects_to => 'Other_page')
-
-    @original.title = 'An old page'
-    @original.save
-    # this redirect have to be removed since 'An old page' page now exists
-    assert !@wiki.redirects.find_by_title_and_redirects_to('An_old_page', 'Other_page')
-  end
-
-  def test_redirects_removed_when_deleting_page
-    assert WikiRedirect.create(:wiki => @wiki, :title => 'An_old_page', :redirects_to => 'Original_title')
-
-    @original.destroy
-    assert !@wiki.redirects.find(:first)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/14/148dc94f440c0c6c1fdf948749c8c6f100698d2e.svn-base
--- a/.svn/pristine/14/148dc94f440c0c6c1fdf948749c8c6f100698d2e.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-module OpenIdAuthentication
-  class Nonce < ActiveRecord::Base
-    set_table_name :open_id_authentication_nonces
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/14/149151b89e5659b8d56fd85ed72924a5e1708683.svn-base
--- a/.svn/pristine/14/149151b89e5659b8d56fd85ed72924a5e1708683.svn-base
+++ /dev/null
@@ -1,10 +0,0 @@
-<% changesets.each do |changeset| %>
-    <div class="changeset <%= cycle('odd', 'even') %>">
-    <p><%= link_to_revision(changeset, changeset.project,
-                            :text => "#{l(:label_revision)} #{changeset.format_identifier}") %><br />
-        <span class="author"><%= authoring(changeset.committed_on, changeset.author) %></span></p>
-    <div class="wiki">
-        <%= textilizable(changeset, :comments) %>
-    </div>
-    </div>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/14/14ee5b2fb5a9f9c39e2c17ac2573da976e834e55.svn-base
--- a/.svn/pristine/14/14ee5b2fb5a9f9c39e2c17ac2573da976e834e55.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-<% fields_for :pref, @user.pref, :builder => TabularFormBuilder, :lang => current_language do |pref_fields| %>
-<p><%= pref_fields.check_box :hide_mail %></p>
-<p><%= pref_fields.select :time_zone, ActiveSupport::TimeZone.all.collect {|z| [ z.to_s, z.name ]}, :include_blank => true %></p>
-<p><%= pref_fields.select :comments_sorting, [[l(:label_chronological_order), 'asc'], [l(:label_reverse_chronological_order), 'desc']] %></p>
-<p><%= pref_fields.check_box :warn_on_leaving_unsaved %></p>
-<% end %>
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/14/14f249183ef33935d6a7aa11b5f44b945eb0da01.svn-base
--- a/.svn/pristine/14/14f249183ef33935d6a7aa11b5f44b945eb0da01.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-<%= error_messages_for 'document' %>
-<div class="box">
-<!--[form:document]-->
-<p><label for="document_category_id"><%=l(:field_category)%></label>
-<%= select('document', 'category_id', DocumentCategory.active.collect {|c| [c.name, c.id]}) %></p>
-
-<p><label for="document_title"><%=l(:field_title)%> <span class="required">*</span></label>
-<%= text_field 'document', 'title', :size => 60 %></p>
-
-<p><label for="document_description"><%=l(:field_description)%></label>
-<%= text_area 'document', 'description', :cols => 60, :rows => 15, :class => 'wiki-edit' %></p>
-<!--[eoform:document]-->
-</div>
-
-<%= wikitoolbar_for 'document_description' %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/15/150305318b29a9433291a10fc5660acea2682a2e.svn-base
--- a/.svn/pristine/15/150305318b29a9433291a10fc5660acea2682a2e.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar BG language
-// Author: Nikolay Solakov, <thoranga@gmail.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("ÐÐµÐ´ÐµÐ»Ñ",
- "ÐŸÐ¾Ð½ÐµÐ´ÐµÐ»Ð½Ð¸Ðº",
- "Ð’Ñ‚Ð¾Ñ€Ð½Ð¸Ðº",
- "Ð¡Ñ€ÑÐ´Ð°",
- "Ð§ÐµÑ‚Ð²ÑŠÑ€Ñ‚ÑŠÐº",
- "ÐŸÐµÑ‚ÑŠÐº",
- "Ð¡ÑŠÐ±Ð¾Ñ‚Ð°",
- "ÐÐµÐ´ÐµÐ»Ñ");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("ÐÐµÐ´",
- "ÐŸÐ¾Ð½",
- "Ð’Ñ‚Ð¾",
- "Ð¡Ñ€Ñ",
- "Ð§ÐµÑ‚",
- "ÐŸÐµÑ‚",
- "Ð¡ÑŠÐ±",
- "ÐÐµÐ´");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Ð¯Ð½ÑƒÐ°Ñ€Ð¸",
- "Ð¤ÐµÐ²Ñ€ÑƒÐ°Ñ€Ð¸",
- "ÐœÐ°Ñ€Ñ‚",
- "ÐÐ¿Ñ€Ð¸Ð»",
- "ÐœÐ°Ð¹",
- "Ð®Ð½Ð¸",
- "Ð®Ð»Ð¸",
- "ÐÐ²Ð³ÑƒÑÑ‚",
- "Ð¡ÐµÐ¿Ñ‚ÐµÐ¼Ð²Ñ€Ð¸",
- "ÐžÐºÑ‚Ð¾Ð¼Ð²Ñ€Ð¸",
- "ÐÐ¾ÐµÐ¼Ð²Ñ€Ð¸",
- "Ð”ÐµÐºÐµÐ¼Ð²Ñ€Ð¸");
-
-// short month names
-Calendar._SMN = new Array
-("Ð¯Ð½Ñƒ",
- "Ð¤ÐµÐ²",
- "ÐœÐ°Ñ€",
- "ÐÐ¿Ñ€",
- "ÐœÐ°Ð¹",
- "Ð®Ð½Ð¸",
- "Ð®Ð»Ð¸",
- "ÐÐ²Ð³",
- "Ð¡ÐµÐ¿",
- "ÐžÐºÑ‚",
- "ÐÐ¾Ðµ",
- "Ð”ÐµÐº");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Ð—Ð° ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ð°";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Ð˜Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð´Ð°Ñ‚Ð°:\n" +
-"- Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð¹Ñ‚Ðµ \xab, \xbb Ð·Ð° Ð¸Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð³Ð¾Ð´Ð¸Ð½Ð°\n" +
-"- Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð¹Ñ‚Ðµ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Ð·Ð° Ð¸Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð¼ÐµÑÐµÑ†\n" +
-"- Ð—Ð°Ð´Ñ€ÑŠÐ¶Ñ‚Ðµ Ð½Ð°Ñ‚Ð¸ÑÐ½Ð°Ñ‚ Ð±ÑƒÑ‚Ð¾Ð½Ð° Ð·Ð° ÑÐ¿Ð¸ÑÑŠÐº Ñ Ð³Ð¾Ð´Ð¸Ð½Ð¸/Ð¼ÐµÑÐµÑ†Ð¸.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Ð˜Ð·Ð±Ð¾Ñ€ Ð½Ð° Ñ‡Ð°Ñ:\n" +
-"- ÐšÐ»Ð¸ÐºÐ½ÐµÑ‚Ðµ Ð½Ð° Ñ‡Ð¸ÑÐ»Ð°Ñ‚Ð° Ð¾Ñ‚ Ñ‡Ð°ÑÐ° Ð·Ð° Ð´Ð° Ð³Ð¸ ÑƒÐ²ÐµÐ»Ð¸Ñ‡Ð¸Ñ‚Ðµ\n" +
-"- Ð¸Ð»Ð¸ Shift-click Ð·Ð° Ð½Ð°Ð¼Ð°Ð»ÑÐ²Ð°Ð½ÐµÑ‚Ð¾ Ð¸Ð¼\n" +
-"- Ð¸Ð»Ð¸ ÐºÐ»Ð¸ÐºÐ½ÐµÑ‚Ðµ Ð¸ Ð²Ð»Ð°Ñ‡ÐµÑ‚Ðµ Ð·Ð° Ð¿Ð¾-Ð±ÑŠÑ€Ð·Ð° Ð¿Ñ€Ð¾Ð¼ÑÐ½Ð°.";
-
-Calendar._TT["PREV_YEAR"] = "ÐŸÑ€ÐµÐ´Ð¸ÑˆÐ½Ð° Ð³Ð¾Ð´Ð¸Ð½Ð° (Ð·Ð°Ð´Ñ€ÑŠÐ¶Ñ‚Ðµ Ð·Ð° ÑÐ¿Ð¸ÑÑŠÐº)";
-Calendar._TT["PREV_MONTH"] = "ÐŸÑ€ÐµÐ´Ð¸ÑˆÐµÐ½ Ð¼ÐµÑÐµÑ† (Ð·Ð°Ð´Ñ€ÑŠÐ¶Ñ‚Ðµ Ð·Ð° ÑÐ¿Ð¸ÑÑŠÐº)";
-Calendar._TT["GO_TODAY"] = "Ð”Ð½ÐµÑˆÐ½Ð° Ð´Ð°Ñ‚Ð°";
-Calendar._TT["NEXT_MONTH"] = "Ð¡Ð»ÐµÐ´Ð²Ð°Ñ‰ Ð¼ÐµÑÐµÑ† (Ð·Ð°Ð´Ñ€ÑŠÐ¶Ñ‚Ðµ Ð·Ð° ÑÐ¿Ð¸ÑÑŠÐº)";
-Calendar._TT["NEXT_YEAR"] = "Ð¡Ð»ÐµÐ´Ð²Ð°Ñ‰Ð° Ð³Ð¾Ð´Ð¸Ð½Ð° (Ð·Ð°Ð´Ñ€ÑŠÐ¶Ñ‚Ðµ Ð·Ð° ÑÐ¿Ð¸ÑÑŠÐº)";
-Calendar._TT["SEL_DATE"] = "Ð˜Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð´Ð°Ñ‚Ð°";
-Calendar._TT["DRAG_TO_MOVE"] = "Ð”Ñ€ÑŠÐ¿Ð½ÐµÑ‚Ðµ Ð·Ð° Ð¿Ñ€ÐµÐ¼ÐµÑÑ‚Ð²Ð°Ð½Ðµ";
-Calendar._TT["PART_TODAY"] = " (Ð´Ð½ÐµÑ)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Ð¡ÐµÐ´Ð¼Ð¸Ñ†Ð°Ñ‚Ð° Ð·Ð°Ð¿Ð¾Ñ‡Ð²Ð° Ñ %s";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Ð—Ð°Ñ‚Ð²Ð¾Ñ€Ð¸";
-Calendar._TT["TODAY"] = "Ð”Ð½ÐµÑ";
-Calendar._TT["TIME_PART"] = "(Shift-)Click Ð¸Ð»Ð¸ Ð²Ð»Ð°Ñ‡ÐµÐ½Ðµ Ð·Ð° Ð¿Ñ€Ð¾Ð¼ÑÐ½Ð° Ð½Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "ÑÐµÐ´Ð¼";
-Calendar._TT["TIME"] = "Ð§Ð°Ñ:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/15/15b7222cb6b5695205873370eda995f4170a4d8e.svn-base
--- /dev/null
+++ b/.svn/pristine/15/15b7222cb6b5695205873370eda995f4170a4d8e.svn-base
@@ -0,0 +1,124 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class MemberTest < ActiveSupport::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :groups_users,
+           :watchers,
+           :journals, :journal_details,
+           :messages,
+           :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
+           :boards
+
+  include Redmine::I18n
+
+  def setup
+    @jsmith = Member.find(1)
+  end
+
+  def test_create
+    member = Member.new(:project_id => 1, :user_id => 4, :role_ids => [1, 2])
+    assert member.save
+    member.reload
+
+    assert_equal 2, member.roles.size
+    assert_equal Role.find(1), member.roles.sort.first
+  end
+
+  def test_update
+    assert_equal "eCookbook", @jsmith.project.name
+    assert_equal "Manager", @jsmith.roles.first.name
+    assert_equal "jsmith", @jsmith.user.login
+
+    @jsmith.mail_notification = !@jsmith.mail_notification
+    assert @jsmith.save
+  end
+
+  def test_update_roles
+    assert_equal 1, @jsmith.roles.size
+    @jsmith.role_ids = [1, 2]
+    assert @jsmith.save
+    assert_equal 2, @jsmith.reload.roles.size
+  end
+
+  def test_validate
+    member = Member.new(:project_id => 1, :user_id => 2, :role_ids => [2])
+    # same use can't have more than one membership for a project
+    assert !member.save
+
+    # must have one role at least
+    user = User.new(:firstname => "new1", :lastname => "user1", :mail => "test_validate@somenet.foo")
+    user.login = "test_validate"
+    user.password, user.password_confirmation = "password", "password"
+    assert user.save
+
+    set_language_if_valid 'fr'
+    member = Member.new(:project_id => 1, :user_id => user.id, :role_ids => [])
+    assert !member.save
+    assert_include I18n.translate('activerecord.errors.messages.empty'), member.errors[:role]
+    str = "R\xc3\xb4le doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    assert_equal str, [member.errors.full_messages].flatten.join
+  end
+
+  def test_validate_member_role
+    user = User.new(:firstname => "new1", :lastname => "user1", :mail => "test_validate@somenet.foo")
+    user.login = "test_validate_member_role"
+    user.password, user.password_confirmation = "password", "password"
+    assert user.save
+    member = Member.new(:project_id => 1, :user_id => user.id, :role_ids => [5])
+    assert !member.save
+  end
+
+  def test_destroy
+    category1 = IssueCategory.find(1)
+    assert_equal @jsmith.user.id, category1.assigned_to_id
+    assert_difference 'Member.count', -1 do
+      assert_difference 'MemberRole.count', -1 do
+        @jsmith.destroy
+      end
+    end
+    assert_raise(ActiveRecord::RecordNotFound) { Member.find(@jsmith.id) }
+    category1.reload
+    assert_nil category1.assigned_to_id
+  end
+
+  def test_sort_without_roles
+    a = Member.new(:roles => [Role.first])
+    b = Member.new
+
+    assert_equal -1, a <=> b
+    assert_equal 1,  b <=> a
+  end
+
+  def test_sort_without_principal
+    role = Role.first
+    a = Member.new(:roles => [role], :principal => User.first)
+    b = Member.new(:roles => [role])
+
+    assert_equal -1, a <=> b
+    assert_equal 1,  b <=> a
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/16/160ac2451e31892432ba296457c74729e5d47d98.svn-base
--- a/.svn/pristine/16/160ac2451e31892432ba296457c74729e5d47d98.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-<%= l(:text_issue_updated, :id => "##{@issue.id}", :author => @journal.user) %>
-
-<% for detail in @journal.details -%>
-<%= show_detail(detail, true) %>
-<% end -%>
-
-<%= @journal.notes if @journal.notes? %>
-----------------------------------------
-<%= render :partial => "issue.text.erb", :locals => { :issue => @issue, :issue_url => @issue_url } %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/16/1665bbb2717b49de68649a3ba32e9deb6f26e40f.svn-base
--- a/.svn/pristine/16/1665bbb2717b49de68649a3ba32e9deb6f26e40f.svn-base
+++ /dev/null
@@ -1,6082 +0,0 @@
-/*  Prototype JavaScript framework, version 1.7
- *  (c) 2005-2010 Sam Stephenson
- *
- *  Prototype is freely distributable under the terms of an MIT-style license.
- *  For details, see the Prototype web site: http://www.prototypejs.org/
- *
- *--------------------------------------------------------------------------*/
-
-var Prototype = {
-
-  Version: '1.7',
-
-  Browser: (function(){
-    var ua = navigator.userAgent;
-    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
-    return {
-      IE:             !!window.attachEvent && !isOpera,
-      Opera:          isOpera,
-      WebKit:         ua.indexOf('AppleWebKit/') > -1,
-      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
-      MobileSafari:   /Apple.*Mobile/.test(ua)
-    }
-  })(),
-
-  BrowserFeatures: {
-    XPath: !!document.evaluate,
-
-    SelectorsAPI: !!document.querySelector,
-
-    ElementExtensions: (function() {
-      var constructor = window.Element || window.HTMLElement;
-      return !!(constructor && constructor.prototype);
-    })(),
-    SpecificElementExtensions: (function() {
-      if (typeof window.HTMLDivElement !== 'undefined')
-        return true;
-
-      var div = document.createElement('div'),
-          form = document.createElement('form'),
-          isSupported = false;
-
-      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
-        isSupported = true;
-      }
-
-      div = form = null;
-
-      return isSupported;
-    })()
-  },
-
-  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
-  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
-
-  emptyFunction: function() { },
-
-  K: function(x) { return x }
-};
-
-if (Prototype.Browser.MobileSafari)
-  Prototype.BrowserFeatures.SpecificElementExtensions = false;
-
-
-var Abstract = { };
-
-
-var Try = {
-  these: function() {
-    var returnValue;
-
-    for (var i = 0, length = arguments.length; i < length; i++) {
-      var lambda = arguments[i];
-      try {
-        returnValue = lambda();
-        break;
-      } catch (e) { }
-    }
-
-    return returnValue;
-  }
-};
-
-/* Based on Alex Arnell's inheritance implementation. */
-
-var Class = (function() {
-
-  var IS_DONTENUM_BUGGY = (function(){
-    for (var p in { toString: 1 }) {
-      if (p === 'toString') return false;
-    }
-    return true;
-  })();
-
-  function subclass() {};
-  function create() {
-    var parent = null, properties = $A(arguments);
-    if (Object.isFunction(properties[0]))
-      parent = properties.shift();
-
-    function klass() {
-      this.initialize.apply(this, arguments);
-    }
-
-    Object.extend(klass, Class.Methods);
-    klass.superclass = parent;
-    klass.subclasses = [];
-
-    if (parent) {
-      subclass.prototype = parent.prototype;
-      klass.prototype = new subclass;
-      parent.subclasses.push(klass);
-    }
-
-    for (var i = 0, length = properties.length; i < length; i++)
-      klass.addMethods(properties[i]);
-
-    if (!klass.prototype.initialize)
-      klass.prototype.initialize = Prototype.emptyFunction;
-
-    klass.prototype.constructor = klass;
-    return klass;
-  }
-
-  function addMethods(source) {
-    var ancestor   = this.superclass && this.superclass.prototype,
-        properties = Object.keys(source);
-
-    if (IS_DONTENUM_BUGGY) {
-      if (source.toString != Object.prototype.toString)
-        properties.push("toString");
-      if (source.valueOf != Object.prototype.valueOf)
-        properties.push("valueOf");
-    }
-
-    for (var i = 0, length = properties.length; i < length; i++) {
-      var property = properties[i], value = source[property];
-      if (ancestor && Object.isFunction(value) &&
-          value.argumentNames()[0] == "$super") {
-        var method = value;
-        value = (function(m) {
-          return function() { return ancestor[m].apply(this, arguments); };
-        })(property).wrap(method);
-
-        value.valueOf = method.valueOf.bind(method);
-        value.toString = method.toString.bind(method);
-      }
-      this.prototype[property] = value;
-    }
-
-    return this;
-  }
-
-  return {
-    create: create,
-    Methods: {
-      addMethods: addMethods
-    }
-  };
-})();
-(function() {
-
-  var _toString = Object.prototype.toString,
-      NULL_TYPE = 'Null',
-      UNDEFINED_TYPE = 'Undefined',
-      BOOLEAN_TYPE = 'Boolean',
-      NUMBER_TYPE = 'Number',
-      STRING_TYPE = 'String',
-      OBJECT_TYPE = 'Object',
-      FUNCTION_CLASS = '[object Function]',
-      BOOLEAN_CLASS = '[object Boolean]',
-      NUMBER_CLASS = '[object Number]',
-      STRING_CLASS = '[object String]',
-      ARRAY_CLASS = '[object Array]',
-      DATE_CLASS = '[object Date]',
-      NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
-        typeof JSON.stringify === 'function' &&
-        JSON.stringify(0) === '0' &&
-        typeof JSON.stringify(Prototype.K) === 'undefined';
-
-  function Type(o) {
-    switch(o) {
-      case null: return NULL_TYPE;
-      case (void 0): return UNDEFINED_TYPE;
-    }
-    var type = typeof o;
-    switch(type) {
-      case 'boolean': return BOOLEAN_TYPE;
-      case 'number':  return NUMBER_TYPE;
-      case 'string':  return STRING_TYPE;
-    }
-    return OBJECT_TYPE;
-  }
-
-  function extend(destination, source) {
-    for (var property in source)
-      destination[property] = source[property];
-    return destination;
-  }
-
-  function inspect(object) {
-    try {
-      if (isUndefined(object)) return 'undefined';
-      if (object === null) return 'null';
-      return object.inspect ? object.inspect() : String(object);
-    } catch (e) {
-      if (e instanceof RangeError) return '...';
-      throw e;
-    }
-  }
-
-  function toJSON(value) {
-    return Str('', { '': value }, []);
-  }
-
-  function Str(key, holder, stack) {
-    var value = holder[key],
-        type = typeof value;
-
-    if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
-      value = value.toJSON(key);
-    }
-
-    var _class = _toString.call(value);
-
-    switch (_class) {
-      case NUMBER_CLASS:
-      case BOOLEAN_CLASS:
-      case STRING_CLASS:
-        value = value.valueOf();
-    }
-
-    switch (value) {
-      case null: return 'null';
-      case true: return 'true';
-      case false: return 'false';
-    }
-
-    type = typeof value;
-    switch (type) {
-      case 'string':
-        return value.inspect(true);
-      case 'number':
-        return isFinite(value) ? String(value) : 'null';
-      case 'object':
-
-        for (var i = 0, length = stack.length; i < length; i++) {
-          if (stack[i] === value) { throw new TypeError(); }
-        }
-        stack.push(value);
-
-        var partial = [];
-        if (_class === ARRAY_CLASS) {
-          for (var i = 0, length = value.length; i < length; i++) {
-            var str = Str(i, value, stack);
-            partial.push(typeof str === 'undefined' ? 'null' : str);
-          }
-          partial = '[' + partial.join(',') + ']';
-        } else {
-          var keys = Object.keys(value);
-          for (var i = 0, length = keys.length; i < length; i++) {
-            var key = keys[i], str = Str(key, value, stack);
-            if (typeof str !== "undefined") {
-               partial.push(key.inspect(true)+ ':' + str);
-             }
-          }
-          partial = '{' + partial.join(',') + '}';
-        }
-        stack.pop();
-        return partial;
-    }
-  }
-
-  function stringify(object) {
-    return JSON.stringify(object);
-  }
-
-  function toQueryString(object) {
-    return $H(object).toQueryString();
-  }
-
-  function toHTML(object) {
-    return object && object.toHTML ? object.toHTML() : String.interpret(object);
-  }
-
-  function keys(object) {
-    if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
-    var results = [];
-    for (var property in object) {
-      if (object.hasOwnProperty(property)) {
-        results.push(property);
-      }
-    }
-    return results;
-  }
-
-  function values(object) {
-    var results = [];
-    for (var property in object)
-      results.push(object[property]);
-    return results;
-  }
-
-  function clone(object) {
-    return extend({ }, object);
-  }
-
-  function isElement(object) {
-    return !!(object && object.nodeType == 1);
-  }
-
-  function isArray(object) {
-    return _toString.call(object) === ARRAY_CLASS;
-  }
-
-  var hasNativeIsArray = (typeof Array.isArray == 'function')
-    && Array.isArray([]) && !Array.isArray({});
-
-  if (hasNativeIsArray) {
-    isArray = Array.isArray;
-  }
-
-  function isHash(object) {
-    return object instanceof Hash;
-  }
-
-  function isFunction(object) {
-    return _toString.call(object) === FUNCTION_CLASS;
-  }
-
-  function isString(object) {
-    return _toString.call(object) === STRING_CLASS;
-  }
-
-  function isNumber(object) {
-    return _toString.call(object) === NUMBER_CLASS;
-  }
-
-  function isDate(object) {
-    return _toString.call(object) === DATE_CLASS;
-  }
-
-  function isUndefined(object) {
-    return typeof object === "undefined";
-  }
-
-  extend(Object, {
-    extend:        extend,
-    inspect:       inspect,
-    toJSON:        NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
-    toQueryString: toQueryString,
-    toHTML:        toHTML,
-    keys:          Object.keys || keys,
-    values:        values,
-    clone:         clone,
-    isElement:     isElement,
-    isArray:       isArray,
-    isHash:        isHash,
-    isFunction:    isFunction,
-    isString:      isString,
-    isNumber:      isNumber,
-    isDate:        isDate,
-    isUndefined:   isUndefined
-  });
-})();
-Object.extend(Function.prototype, (function() {
-  var slice = Array.prototype.slice;
-
-  function update(array, args) {
-    var arrayLength = array.length, length = args.length;
-    while (length--) array[arrayLength + length] = args[length];
-    return array;
-  }
-
-  function merge(array, args) {
-    array = slice.call(array, 0);
-    return update(array, args);
-  }
-
-  function argumentNames() {
-    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
-      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
-      .replace(/\s+/g, '').split(',');
-    return names.length == 1 && !names[0] ? [] : names;
-  }
-
-  function bind(context) {
-    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
-    var __method = this, args = slice.call(arguments, 1);
-    return function() {
-      var a = merge(args, arguments);
-      return __method.apply(context, a);
-    }
-  }
-
-  function bindAsEventListener(context) {
-    var __method = this, args = slice.call(arguments, 1);
-    return function(event) {
-      var a = update([event || window.event], args);
-      return __method.apply(context, a);
-    }
-  }
-
-  function curry() {
-    if (!arguments.length) return this;
-    var __method = this, args = slice.call(arguments, 0);
-    return function() {
-      var a = merge(args, arguments);
-      return __method.apply(this, a);
-    }
-  }
-
-  function delay(timeout) {
-    var __method = this, args = slice.call(arguments, 1);
-    timeout = timeout * 1000;
-    return window.setTimeout(function() {
-      return __method.apply(__method, args);
-    }, timeout);
-  }
-
-  function defer() {
-    var args = update([0.01], arguments);
-    return this.delay.apply(this, args);
-  }
-
-  function wrap(wrapper) {
-    var __method = this;
-    return function() {
-      var a = update([__method.bind(this)], arguments);
-      return wrapper.apply(this, a);
-    }
-  }
-
-  function methodize() {
-    if (this._methodized) return this._methodized;
-    var __method = this;
-    return this._methodized = function() {
-      var a = update([this], arguments);
-      return __method.apply(null, a);
-    };
-  }
-
-  return {
-    argumentNames:       argumentNames,
-    bind:                bind,
-    bindAsEventListener: bindAsEventListener,
-    curry:               curry,
-    delay:               delay,
-    defer:               defer,
-    wrap:                wrap,
-    methodize:           methodize
-  }
-})());
-
-
-
-(function(proto) {
-
-
-  function toISOString() {
-    return this.getUTCFullYear() + '-' +
-      (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
-      this.getUTCDate().toPaddedString(2) + 'T' +
-      this.getUTCHours().toPaddedString(2) + ':' +
-      this.getUTCMinutes().toPaddedString(2) + ':' +
-      this.getUTCSeconds().toPaddedString(2) + 'Z';
-  }
-
-
-  function toJSON() {
-    return this.toISOString();
-  }
-
-  if (!proto.toISOString) proto.toISOString = toISOString;
-  if (!proto.toJSON) proto.toJSON = toJSON;
-
-})(Date.prototype);
-
-
-RegExp.prototype.match = RegExp.prototype.test;
-
-RegExp.escape = function(str) {
-  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
-};
-var PeriodicalExecuter = Class.create({
-  initialize: function(callback, frequency) {
-    this.callback = callback;
-    this.frequency = frequency;
-    this.currentlyExecuting = false;
-
-    this.registerCallback();
-  },
-
-  registerCallback: function() {
-    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
-  },
-
-  execute: function() {
-    this.callback(this);
-  },
-
-  stop: function() {
-    if (!this.timer) return;
-    clearInterval(this.timer);
-    this.timer = null;
-  },
-
-  onTimerEvent: function() {
-    if (!this.currentlyExecuting) {
-      try {
-        this.currentlyExecuting = true;
-        this.execute();
-        this.currentlyExecuting = false;
-      } catch(e) {
-        this.currentlyExecuting = false;
-        throw e;
-      }
-    }
-  }
-});
-Object.extend(String, {
-  interpret: function(value) {
-    return value == null ? '' : String(value);
-  },
-  specialChar: {
-    '\b': '\\b',
-    '\t': '\\t',
-    '\n': '\\n',
-    '\f': '\\f',
-    '\r': '\\r',
-    '\\': '\\\\'
-  }
-});
-
-Object.extend(String.prototype, (function() {
-  var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
-    typeof JSON.parse === 'function' &&
-    JSON.parse('{"test": true}').test;
-
-  function prepareReplacement(replacement) {
-    if (Object.isFunction(replacement)) return replacement;
-    var template = new Template(replacement);
-    return function(match) { return template.evaluate(match) };
-  }
-
-  function gsub(pattern, replacement) {
-    var result = '', source = this, match;
-    replacement = prepareReplacement(replacement);
-
-    if (Object.isString(pattern))
-      pattern = RegExp.escape(pattern);
-
-    if (!(pattern.length || pattern.source)) {
-      replacement = replacement('');
-      return replacement + source.split('').join(replacement) + replacement;
-    }
-
-    while (source.length > 0) {
-      if (match = source.match(pattern)) {
-        result += source.slice(0, match.index);
-        result += String.interpret(replacement(match));
-        source  = source.slice(match.index + match[0].length);
-      } else {
-        result += source, source = '';
-      }
-    }
-    return result;
-  }
-
-  function sub(pattern, replacement, count) {
-    replacement = prepareReplacement(replacement);
-    count = Object.isUndefined(count) ? 1 : count;
-
-    return this.gsub(pattern, function(match) {
-      if (--count < 0) return match[0];
-      return replacement(match);
-    });
-  }
-
-  function scan(pattern, iterator) {
-    this.gsub(pattern, iterator);
-    return String(this);
-  }
-
-  function truncate(length, truncation) {
-    length = length || 30;
-    truncation = Object.isUndefined(truncation) ? '...' : truncation;
-    return this.length > length ?
-      this.slice(0, length - truncation.length) + truncation : String(this);
-  }
-
-  function strip() {
-    return this.replace(/^\s+/, '').replace(/\s+$/, '');
-  }
-
-  function stripTags() {
-    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
-  }
-
-  function stripScripts() {
-    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
-  }
-
-  function extractScripts() {
-    var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
-        matchOne = new RegExp(Prototype.ScriptFragment, 'im');
-    return (this.match(matchAll) || []).map(function(scriptTag) {
-      return (scriptTag.match(matchOne) || ['', ''])[1];
-    });
-  }
-
-  function evalScripts() {
-    return this.extractScripts().map(function(script) { return eval(script) });
-  }
-
-  function escapeHTML() {
-    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
-  }
-
-  function unescapeHTML() {
-    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
-  }
-
-
-  function toQueryParams(separator) {
-    var match = this.strip().match(/([^?#]*)(#.*)?$/);
-    if (!match) return { };
-
-    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
-      if ((pair = pair.split('='))[0]) {
-        var key = decodeURIComponent(pair.shift()),
-            value = pair.length > 1 ? pair.join('=') : pair[0];
-
-        if (value != undefined) value = decodeURIComponent(value);
-
-        if (key in hash) {
-          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
-          hash[key].push(value);
-        }
-        else hash[key] = value;
-      }
-      return hash;
-    });
-  }
-
-  function toArray() {
-    return this.split('');
-  }
-
-  function succ() {
-    return this.slice(0, this.length - 1) +
-      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
-  }
-
-  function times(count) {
-    return count < 1 ? '' : new Array(count + 1).join(this);
-  }
-
-  function camelize() {
-    return this.replace(/-+(.)?/g, function(match, chr) {
-      return chr ? chr.toUpperCase() : '';
-    });
-  }
-
-  function capitalize() {
-    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
-  }
-
-  function underscore() {
-    return this.replace(/::/g, '/')
-               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
-               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
-               .replace(/-/g, '_')
-               .toLowerCase();
-  }
-
-  function dasherize() {
-    return this.replace(/_/g, '-');
-  }
-
-  function inspect(useDoubleQuotes) {
-    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
-      if (character in String.specialChar) {
-        return String.specialChar[character];
-      }
-      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
-    });
-    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
-    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
-  }
-
-  function unfilterJSON(filter) {
-    return this.replace(filter || Prototype.JSONFilter, '$1');
-  }
-
-  function isJSON() {
-    var str = this;
-    if (str.blank()) return false;
-    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
-    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
-    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
-    return (/^[\],:{}\s]*$/).test(str);
-  }
-
-  function evalJSON(sanitize) {
-    var json = this.unfilterJSON(),
-        cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
-    if (cx.test(json)) {
-      json = json.replace(cx, function (a) {
-        return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
-      });
-    }
-    try {
-      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
-    } catch (e) { }
-    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
-  }
-
-  function parseJSON() {
-    var json = this.unfilterJSON();
-    return JSON.parse(json);
-  }
-
-  function include(pattern) {
-    return this.indexOf(pattern) > -1;
-  }
-
-  function startsWith(pattern) {
-    return this.lastIndexOf(pattern, 0) === 0;
-  }
-
-  function endsWith(pattern) {
-    var d = this.length - pattern.length;
-    return d >= 0 && this.indexOf(pattern, d) === d;
-  }
-
-  function empty() {
-    return this == '';
-  }
-
-  function blank() {
-    return /^\s*$/.test(this);
-  }
-
-  function interpolate(object, pattern) {
-    return new Template(this, pattern).evaluate(object);
-  }
-
-  return {
-    gsub:           gsub,
-    sub:            sub,
-    scan:           scan,
-    truncate:       truncate,
-    strip:          String.prototype.trim || strip,
-    stripTags:      stripTags,
-    stripScripts:   stripScripts,
-    extractScripts: extractScripts,
-    evalScripts:    evalScripts,
-    escapeHTML:     escapeHTML,
-    unescapeHTML:   unescapeHTML,
-    toQueryParams:  toQueryParams,
-    parseQuery:     toQueryParams,
-    toArray:        toArray,
-    succ:           succ,
-    times:          times,
-    camelize:       camelize,
-    capitalize:     capitalize,
-    underscore:     underscore,
-    dasherize:      dasherize,
-    inspect:        inspect,
-    unfilterJSON:   unfilterJSON,
-    isJSON:         isJSON,
-    evalJSON:       NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
-    include:        include,
-    startsWith:     startsWith,
-    endsWith:       endsWith,
-    empty:          empty,
-    blank:          blank,
-    interpolate:    interpolate
-  };
-})());
-
-var Template = Class.create({
-  initialize: function(template, pattern) {
-    this.template = template.toString();
-    this.pattern = pattern || Template.Pattern;
-  },
-
-  evaluate: function(object) {
-    if (object && Object.isFunction(object.toTemplateReplacements))
-      object = object.toTemplateReplacements();
-
-    return this.template.gsub(this.pattern, function(match) {
-      if (object == null) return (match[1] + '');
-
-      var before = match[1] || '';
-      if (before == '\\') return match[2];
-
-      var ctx = object, expr = match[3],
-          pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
-
-      match = pattern.exec(expr);
-      if (match == null) return before;
-
-      while (match != null) {
-        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
-        ctx = ctx[comp];
-        if (null == ctx || '' == match[3]) break;
-        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
-        match = pattern.exec(expr);
-      }
-
-      return before + String.interpret(ctx);
-    });
-  }
-});
-Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-
-var $break = { };
-
-var Enumerable = (function() {
-  function each(iterator, context) {
-    var index = 0;
-    try {
-      this._each(function(value) {
-        iterator.call(context, value, index++);
-      });
-    } catch (e) {
-      if (e != $break) throw e;
-    }
-    return this;
-  }
-
-  function eachSlice(number, iterator, context) {
-    var index = -number, slices = [], array = this.toArray();
-    if (number < 1) return array;
-    while ((index += number) < array.length)
-      slices.push(array.slice(index, index+number));
-    return slices.collect(iterator, context);
-  }
-
-  function all(iterator, context) {
-    iterator = iterator || Prototype.K;
-    var result = true;
-    this.each(function(value, index) {
-      result = result && !!iterator.call(context, value, index);
-      if (!result) throw $break;
-    });
-    return result;
-  }
-
-  function any(iterator, context) {
-    iterator = iterator || Prototype.K;
-    var result = false;
-    this.each(function(value, index) {
-      if (result = !!iterator.call(context, value, index))
-        throw $break;
-    });
-    return result;
-  }
-
-  function collect(iterator, context) {
-    iterator = iterator || Prototype.K;
-    var results = [];
-    this.each(function(value, index) {
-      results.push(iterator.call(context, value, index));
-    });
-    return results;
-  }
-
-  function detect(iterator, context) {
-    var result;
-    this.each(function(value, index) {
-      if (iterator.call(context, value, index)) {
-        result = value;
-        throw $break;
-      }
-    });
-    return result;
-  }
-
-  function findAll(iterator, context) {
-    var results = [];
-    this.each(function(value, index) {
-      if (iterator.call(context, value, index))
-        results.push(value);
-    });
-    return results;
-  }
-
-  function grep(filter, iterator, context) {
-    iterator = iterator || Prototype.K;
-    var results = [];
-
-    if (Object.isString(filter))
-      filter = new RegExp(RegExp.escape(filter));
-
-    this.each(function(value, index) {
-      if (filter.match(value))
-        results.push(iterator.call(context, value, index));
-    });
-    return results;
-  }
-
-  function include(object) {
-    if (Object.isFunction(this.indexOf))
-      if (this.indexOf(object) != -1) return true;
-
-    var found = false;
-    this.each(function(value) {
-      if (value == object) {
-        found = true;
-        throw $break;
-      }
-    });
-    return found;
-  }
-
-  function inGroupsOf(number, fillWith) {
-    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
-    return this.eachSlice(number, function(slice) {
-      while(slice.length < number) slice.push(fillWith);
-      return slice;
-    });
-  }
-
-  function inject(memo, iterator, context) {
-    this.each(function(value, index) {
-      memo = iterator.call(context, memo, value, index);
-    });
-    return memo;
-  }
-
-  function invoke(method) {
-    var args = $A(arguments).slice(1);
-    return this.map(function(value) {
-      return value[method].apply(value, args);
-    });
-  }
-
-  function max(iterator, context) {
-    iterator = iterator || Prototype.K;
-    var result;
-    this.each(function(value, index) {
-      value = iterator.call(context, value, index);
-      if (result == null || value >= result)
-        result = value;
-    });
-    return result;
-  }
-
-  function min(iterator, context) {
-    iterator = iterator || Prototype.K;
-    var result;
-    this.each(function(value, index) {
-      value = iterator.call(context, value, index);
-      if (result == null || value < result)
-        result = value;
-    });
-    return result;
-  }
-
-  function partition(iterator, context) {
-    iterator = iterator || Prototype.K;
-    var trues = [], falses = [];
-    this.each(function(value, index) {
-      (iterator.call(context, value, index) ?
-        trues : falses).push(value);
-    });
-    return [trues, falses];
-  }
-
-  function pluck(property) {
-    var results = [];
-    this.each(function(value) {
-      results.push(value[property]);
-    });
-    return results;
-  }
-
-  function reject(iterator, context) {
-    var results = [];
-    this.each(function(value, index) {
-      if (!iterator.call(context, value, index))
-        results.push(value);
-    });
-    return results;
-  }
-
-  function sortBy(iterator, context) {
-    return this.map(function(value, index) {
-      return {
-        value: value,
-        criteria: iterator.call(context, value, index)
-      };
-    }).sort(function(left, right) {
-      var a = left.criteria, b = right.criteria;
-      return a < b ? -1 : a > b ? 1 : 0;
-    }).pluck('value');
-  }
-
-  function toArray() {
-    return this.map();
-  }
-
-  function zip() {
-    var iterator = Prototype.K, args = $A(arguments);
-    if (Object.isFunction(args.last()))
-      iterator = args.pop();
-
-    var collections = [this].concat(args).map($A);
-    return this.map(function(value, index) {
-      return iterator(collections.pluck(index));
-    });
-  }
-
-  function size() {
-    return this.toArray().length;
-  }
-
-  function inspect() {
-    return '#<Enumerable:' + this.toArray().inspect() + '>';
-  }
-
-
-
-
-
-
-
-
-
-  return {
-    each:       each,
-    eachSlice:  eachSlice,
-    all:        all,
-    every:      all,
-    any:        any,
-    some:       any,
-    collect:    collect,
-    map:        collect,
-    detect:     detect,
-    findAll:    findAll,
-    select:     findAll,
-    filter:     findAll,
-    grep:       grep,
-    include:    include,
-    member:     include,
-    inGroupsOf: inGroupsOf,
-    inject:     inject,
-    invoke:     invoke,
-    max:        max,
-    min:        min,
-    partition:  partition,
-    pluck:      pluck,
-    reject:     reject,
-    sortBy:     sortBy,
-    toArray:    toArray,
-    entries:    toArray,
-    zip:        zip,
-    size:       size,
-    inspect:    inspect,
-    find:       detect
-  };
-})();
-
-function $A(iterable) {
-  if (!iterable) return [];
-  if ('toArray' in Object(iterable)) return iterable.toArray();
-  var length = iterable.length || 0, results = new Array(length);
-  while (length--) results[length] = iterable[length];
-  return results;
-}
-
-
-function $w(string) {
-  if (!Object.isString(string)) return [];
-  string = string.strip();
-  return string ? string.split(/\s+/) : [];
-}
-
-Array.from = $A;
-
-
-(function() {
-  var arrayProto = Array.prototype,
-      slice = arrayProto.slice,
-      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
-
-  function each(iterator, context) {
-    for (var i = 0, length = this.length >>> 0; i < length; i++) {
-      if (i in this) iterator.call(context, this[i], i, this);
-    }
-  }
-  if (!_each) _each = each;
-
-  function clear() {
-    this.length = 0;
-    return this;
-  }
-
-  function first() {
-    return this[0];
-  }
-
-  function last() {
-    return this[this.length - 1];
-  }
-
-  function compact() {
-    return this.select(function(value) {
-      return value != null;
-    });
-  }
-
-  function flatten() {
-    return this.inject([], function(array, value) {
-      if (Object.isArray(value))
-        return array.concat(value.flatten());
-      array.push(value);
-      return array;
-    });
-  }
-
-  function without() {
-    var values = slice.call(arguments, 0);
-    return this.select(function(value) {
-      return !values.include(value);
-    });
-  }
-
-  function reverse(inline) {
-    return (inline === false ? this.toArray() : this)._reverse();
-  }
-
-  function uniq(sorted) {
-    return this.inject([], function(array, value, index) {
-      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
-        array.push(value);
-      return array;
-    });
-  }
-
-  function intersect(array) {
-    return this.uniq().findAll(function(item) {
-      return array.detect(function(value) { return item === value });
-    });
-  }
-
-
-  function clone() {
-    return slice.call(this, 0);
-  }
-
-  function size() {
-    return this.length;
-  }
-
-  function inspect() {
-    return '[' + this.map(Object.inspect).join(', ') + ']';
-  }
-
-  function indexOf(item, i) {
-    i || (i = 0);
-    var length = this.length;
-    if (i < 0) i = length + i;
-    for (; i < length; i++)
-      if (this[i] === item) return i;
-    return -1;
-  }
-
-  function lastIndexOf(item, i) {
-    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
-    var n = this.slice(0, i).reverse().indexOf(item);
-    return (n < 0) ? n : i - n - 1;
-  }
-
-  function concat() {
-    var array = slice.call(this, 0), item;
-    for (var i = 0, length = arguments.length; i < length; i++) {
-      item = arguments[i];
-      if (Object.isArray(item) && !('callee' in item)) {
-        for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
-          array.push(item[j]);
-      } else {
-        array.push(item);
-      }
-    }
-    return array;
-  }
-
-  Object.extend(arrayProto, Enumerable);
-
-  if (!arrayProto._reverse)
-    arrayProto._reverse = arrayProto.reverse;
-
-  Object.extend(arrayProto, {
-    _each:     _each,
-    clear:     clear,
-    first:     first,
-    last:      last,
-    compact:   compact,
-    flatten:   flatten,
-    without:   without,
-    reverse:   reverse,
-    uniq:      uniq,
-    intersect: intersect,
-    clone:     clone,
-    toArray:   clone,
-    size:      size,
-    inspect:   inspect
-  });
-
-  var CONCAT_ARGUMENTS_BUGGY = (function() {
-    return [].concat(arguments)[0][0] !== 1;
-  })(1,2)
-
-  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
-
-  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
-  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
-})();
-function $H(object) {
-  return new Hash(object);
-};
-
-var Hash = Class.create(Enumerable, (function() {
-  function initialize(object) {
-    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
-  }
-
-
-  function _each(iterator) {
-    for (var key in this._object) {
-      var value = this._object[key], pair = [key, value];
-      pair.key = key;
-      pair.value = value;
-      iterator(pair);
-    }
-  }
-
-  function set(key, value) {
-    return this._object[key] = value;
-  }
-
-  function get(key) {
-    if (this._object[key] !== Object.prototype[key])
-      return this._object[key];
-  }
-
-  function unset(key) {
-    var value = this._object[key];
-    delete this._object[key];
-    return value;
-  }
-
-  function toObject() {
-    return Object.clone(this._object);
-  }
-
-
-
-  function keys() {
-    return this.pluck('key');
-  }
-
-  function values() {
-    return this.pluck('value');
-  }
-
-  function index(value) {
-    var match = this.detect(function(pair) {
-      return pair.value === value;
-    });
-    return match && match.key;
-  }
-
-  function merge(object) {
-    return this.clone().update(object);
-  }
-
-  function update(object) {
-    return new Hash(object).inject(this, function(result, pair) {
-      result.set(pair.key, pair.value);
-      return result;
-    });
-  }
-
-  function toQueryPair(key, value) {
-    if (Object.isUndefined(value)) return key;
-    return key + '=' + encodeURIComponent(String.interpret(value));
-  }
-
-  function toQueryString() {
-    return this.inject([], function(results, pair) {
-      var key = encodeURIComponent(pair.key), values = pair.value;
-
-      if (values && typeof values == 'object') {
-        if (Object.isArray(values)) {
-          var queryValues = [];
-          for (var i = 0, len = values.length, value; i < len; i++) {
-            value = values[i];
-            queryValues.push(toQueryPair(key, value));
-          }
-          return results.concat(queryValues);
-        }
-      } else results.push(toQueryPair(key, values));
-      return results;
-    }).join('&');
-  }
-
-  function inspect() {
-    return '#<Hash:{' + this.map(function(pair) {
-      return pair.map(Object.inspect).join(': ');
-    }).join(', ') + '}>';
-  }
-
-  function clone() {
-    return new Hash(this);
-  }
-
-  return {
-    initialize:             initialize,
-    _each:                  _each,
-    set:                    set,
-    get:                    get,
-    unset:                  unset,
-    toObject:               toObject,
-    toTemplateReplacements: toObject,
-    keys:                   keys,
-    values:                 values,
-    index:                  index,
-    merge:                  merge,
-    update:                 update,
-    toQueryString:          toQueryString,
-    inspect:                inspect,
-    toJSON:                 toObject,
-    clone:                  clone
-  };
-})());
-
-Hash.from = $H;
-Object.extend(Number.prototype, (function() {
-  function toColorPart() {
-    return this.toPaddedString(2, 16);
-  }
-
-  function succ() {
-    return this + 1;
-  }
-
-  function times(iterator, context) {
-    $R(0, this, true).each(iterator, context);
-    return this;
-  }
-
-  function toPaddedString(length, radix) {
-    var string = this.toString(radix || 10);
-    return '0'.times(length - string.length) + string;
-  }
-
-  function abs() {
-    return Math.abs(this);
-  }
-
-  function round() {
-    return Math.round(this);
-  }
-
-  function ceil() {
-    return Math.ceil(this);
-  }
-
-  function floor() {
-    return Math.floor(this);
-  }
-
-  return {
-    toColorPart:    toColorPart,
-    succ:           succ,
-    times:          times,
-    toPaddedString: toPaddedString,
-    abs:            abs,
-    round:          round,
-    ceil:           ceil,
-    floor:          floor
-  };
-})());
-
-function $R(start, end, exclusive) {
-  return new ObjectRange(start, end, exclusive);
-}
-
-var ObjectRange = Class.create(Enumerable, (function() {
-  function initialize(start, end, exclusive) {
-    this.start = start;
-    this.end = end;
-    this.exclusive = exclusive;
-  }
-
-  function _each(iterator) {
-    var value = this.start;
-    while (this.include(value)) {
-      iterator(value);
-      value = value.succ();
-    }
-  }
-
-  function include(value) {
-    if (value < this.start)
-      return false;
-    if (this.exclusive)
-      return value < this.end;
-    return value <= this.end;
-  }
-
-  return {
-    initialize: initialize,
-    _each:      _each,
-    include:    include
-  };
-})());
-
-
-
-var Ajax = {
-  getTransport: function() {
-    return Try.these(
-      function() {return new XMLHttpRequest()},
-      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
-      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
-    ) || false;
-  },
-
-  activeRequestCount: 0
-};
-
-Ajax.Responders = {
-  responders: [],
-
-  _each: function(iterator) {
-    this.responders._each(iterator);
-  },
-
-  register: function(responder) {
-    if (!this.include(responder))
-      this.responders.push(responder);
-  },
-
-  unregister: function(responder) {
-    this.responders = this.responders.without(responder);
-  },
-
-  dispatch: function(callback, request, transport, json) {
-    this.each(function(responder) {
-      if (Object.isFunction(responder[callback])) {
-        try {
-          responder[callback].apply(responder, [request, transport, json]);
-        } catch (e) { }
-      }
-    });
-  }
-};
-
-Object.extend(Ajax.Responders, Enumerable);
-
-Ajax.Responders.register({
-  onCreate:   function() { Ajax.activeRequestCount++ },
-  onComplete: function() { Ajax.activeRequestCount-- }
-});
-Ajax.Base = Class.create({
-  initialize: function(options) {
-    this.options = {
-      method:       'post',
-      asynchronous: true,
-      contentType:  'application/x-www-form-urlencoded',
-      encoding:     'UTF-8',
-      parameters:   '',
-      evalJSON:     true,
-      evalJS:       true
-    };
-    Object.extend(this.options, options || { });
-
-    this.options.method = this.options.method.toLowerCase();
-
-    if (Object.isHash(this.options.parameters))
-      this.options.parameters = this.options.parameters.toObject();
-  }
-});
-Ajax.Request = Class.create(Ajax.Base, {
-  _complete: false,
-
-  initialize: function($super, url, options) {
-    $super(options);
-    this.transport = Ajax.getTransport();
-    this.request(url);
-  },
-
-  request: function(url) {
-    this.url = url;
-    this.method = this.options.method;
-    var params = Object.isString(this.options.parameters) ?
-          this.options.parameters :
-          Object.toQueryString(this.options.parameters);
-
-    if (!['get', 'post'].include(this.method)) {
-      params += (params ? '&' : '') + "_method=" + this.method;
-      this.method = 'post';
-    }
-
-    if (params && this.method === 'get') {
-      this.url += (this.url.include('?') ? '&' : '?') + params;
-    }
-
-    this.parameters = params.toQueryParams();
-
-    try {
-      var response = new Ajax.Response(this);
-      if (this.options.onCreate) this.options.onCreate(response);
-      Ajax.Responders.dispatch('onCreate', this, response);
-
-      this.transport.open(this.method.toUpperCase(), this.url,
-        this.options.asynchronous);
-
-      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
-
-      this.transport.onreadystatechange = this.onStateChange.bind(this);
-      this.setRequestHeaders();
-
-      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
-      this.transport.send(this.body);
-
-      /* Force Firefox to handle ready state 4 for synchronous requests */
-      if (!this.options.asynchronous && this.transport.overrideMimeType)
-        this.onStateChange();
-
-    }
-    catch (e) {
-      this.dispatchException(e);
-    }
-  },
-
-  onStateChange: function() {
-    var readyState = this.transport.readyState;
-    if (readyState > 1 && !((readyState == 4) && this._complete))
-      this.respondToReadyState(this.transport.readyState);
-  },
-
-  setRequestHeaders: function() {
-    var headers = {
-      'X-Requested-With': 'XMLHttpRequest',
-      'X-Prototype-Version': Prototype.Version,
-      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
-    };
-
-    if (this.method == 'post') {
-      headers['Content-type'] = this.options.contentType +
-        (this.options.encoding ? '; charset=' + this.options.encoding : '');
-
-      /* Force "Connection: close" for older Mozilla browsers to work
-       * around a bug where XMLHttpRequest sends an incorrect
-       * Content-length header. See Mozilla Bugzilla #246651.
-       */
-      if (this.transport.overrideMimeType &&
-          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
-            headers['Connection'] = 'close';
-    }
-
-    if (typeof this.options.requestHeaders == 'object') {
-      var extras = this.options.requestHeaders;
-
-      if (Object.isFunction(extras.push))
-        for (var i = 0, length = extras.length; i < length; i += 2)
-          headers[extras[i]] = extras[i+1];
-      else
-        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
-    }
-
-    for (var name in headers)
-      this.transport.setRequestHeader(name, headers[name]);
-  },
-
-  success: function() {
-    var status = this.getStatus();
-    return !status || (status >= 200 && status < 300) || status == 304;
-  },
-
-  getStatus: function() {
-    try {
-      if (this.transport.status === 1223) return 204;
-      return this.transport.status || 0;
-    } catch (e) { return 0 }
-  },
-
-  respondToReadyState: function(readyState) {
-    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
-
-    if (state == 'Complete') {
-      try {
-        this._complete = true;
-        (this.options['on' + response.status]
-         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
-         || Prototype.emptyFunction)(response, response.headerJSON);
-      } catch (e) {
-        this.dispatchException(e);
-      }
-
-      var contentType = response.getHeader('Content-type');
-      if (this.options.evalJS == 'force'
-          || (this.options.evalJS && this.isSameOrigin() && contentType
-          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
-        this.evalResponse();
-    }
-
-    try {
-      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
-      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
-    } catch (e) {
-      this.dispatchException(e);
-    }
-
-    if (state == 'Complete') {
-      this.transport.onreadystatechange = Prototype.emptyFunction;
-    }
-  },
-
-  isSameOrigin: function() {
-    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
-    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
-      protocol: location.protocol,
-      domain: document.domain,
-      port: location.port ? ':' + location.port : ''
-    }));
-  },
-
-  getHeader: function(name) {
-    try {
-      return this.transport.getResponseHeader(name) || null;
-    } catch (e) { return null; }
-  },
-
-  evalResponse: function() {
-    try {
-      return eval((this.transport.responseText || '').unfilterJSON());
-    } catch (e) {
-      this.dispatchException(e);
-    }
-  },
-
-  dispatchException: function(exception) {
-    (this.options.onException || Prototype.emptyFunction)(this, exception);
-    Ajax.Responders.dispatch('onException', this, exception);
-  }
-});
-
-Ajax.Request.Events =
-  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
-
-
-
-
-
-
-
-
-Ajax.Response = Class.create({
-  initialize: function(request){
-    this.request = request;
-    var transport  = this.transport  = request.transport,
-        readyState = this.readyState = transport.readyState;
-
-    if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
-      this.status       = this.getStatus();
-      this.statusText   = this.getStatusText();
-      this.responseText = String.interpret(transport.responseText);
-      this.headerJSON   = this._getHeaderJSON();
-    }
-
-    if (readyState == 4) {
-      var xml = transport.responseXML;
-      this.responseXML  = Object.isUndefined(xml) ? null : xml;
-      this.responseJSON = this._getResponseJSON();
-    }
-  },
-
-  status:      0,
-
-  statusText: '',
-
-  getStatus: Ajax.Request.prototype.getStatus,
-
-  getStatusText: function() {
-    try {
-      return this.transport.statusText || '';
-    } catch (e) { return '' }
-  },
-
-  getHeader: Ajax.Request.prototype.getHeader,
-
-  getAllHeaders: function() {
-    try {
-      return this.getAllResponseHeaders();
-    } catch (e) { return null }
-  },
-
-  getResponseHeader: function(name) {
-    return this.transport.getResponseHeader(name);
-  },
-
-  getAllResponseHeaders: function() {
-    return this.transport.getAllResponseHeaders();
-  },
-
-  _getHeaderJSON: function() {
-    var json = this.getHeader('X-JSON');
-    if (!json) return null;
-    json = decodeURIComponent(escape(json));
-    try {
-      return json.evalJSON(this.request.options.sanitizeJSON ||
-        !this.request.isSameOrigin());
-    } catch (e) {
-      this.request.dispatchException(e);
-    }
-  },
-
-  _getResponseJSON: function() {
-    var options = this.request.options;
-    if (!options.evalJSON || (options.evalJSON != 'force' &&
-      !(this.getHeader('Content-type') || '').include('application/json')) ||
-        this.responseText.blank())
-          return null;
-    try {
-      return this.responseText.evalJSON(options.sanitizeJSON ||
-        !this.request.isSameOrigin());
-    } catch (e) {
-      this.request.dispatchException(e);
-    }
-  }
-});
-
-Ajax.Updater = Class.create(Ajax.Request, {
-  initialize: function($super, container, url, options) {
-    this.container = {
-      success: (container.success || container),
-      failure: (container.failure || (container.success ? null : container))
-    };
-
-    options = Object.clone(options);
-    var onComplete = options.onComplete;
-    options.onComplete = (function(response, json) {
-      this.updateContent(response.responseText);
-      if (Object.isFunction(onComplete)) onComplete(response, json);
-    }).bind(this);
-
-    $super(url, options);
-  },
-
-  updateContent: function(responseText) {
-    var receiver = this.container[this.success() ? 'success' : 'failure'],
-        options = this.options;
-
-    if (!options.evalScripts) responseText = responseText.stripScripts();
-
-    if (receiver = $(receiver)) {
-      if (options.insertion) {
-        if (Object.isString(options.insertion)) {
-          var insertion = { }; insertion[options.insertion] = responseText;
-          receiver.insert(insertion);
-        }
-        else options.insertion(receiver, responseText);
-      }
-      else receiver.update(responseText);
-    }
-  }
-});
-
-Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
-  initialize: function($super, container, url, options) {
-    $super(options);
-    this.onComplete = this.options.onComplete;
-
-    this.frequency = (this.options.frequency || 2);
-    this.decay = (this.options.decay || 1);
-
-    this.updater = { };
-    this.container = container;
-    this.url = url;
-
-    this.start();
-  },
-
-  start: function() {
-    this.options.onComplete = this.updateComplete.bind(this);
-    this.onTimerEvent();
-  },
-
-  stop: function() {
-    this.updater.options.onComplete = undefined;
-    clearTimeout(this.timer);
-    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
-  },
-
-  updateComplete: function(response) {
-    if (this.options.decay) {
-      this.decay = (response.responseText == this.lastText ?
-        this.decay * this.options.decay : 1);
-
-      this.lastText = response.responseText;
-    }
-    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
-  },
-
-  onTimerEvent: function() {
-    this.updater = new Ajax.Updater(this.container, this.url, this.options);
-  }
-});
-
-
-function $(element) {
-  if (arguments.length > 1) {
-    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
-      elements.push($(arguments[i]));
-    return elements;
-  }
-  if (Object.isString(element))
-    element = document.getElementById(element);
-  return Element.extend(element);
-}
-
-if (Prototype.BrowserFeatures.XPath) {
-  document._getElementsByXPath = function(expression, parentElement) {
-    var results = [];
-    var query = document.evaluate(expression, $(parentElement) || document,
-      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
-    for (var i = 0, length = query.snapshotLength; i < length; i++)
-      results.push(Element.extend(query.snapshotItem(i)));
-    return results;
-  };
-}
-
-/*--------------------------------------------------------------------------*/
-
-if (!Node) var Node = { };
-
-if (!Node.ELEMENT_NODE) {
-  Object.extend(Node, {
-    ELEMENT_NODE: 1,
-    ATTRIBUTE_NODE: 2,
-    TEXT_NODE: 3,
-    CDATA_SECTION_NODE: 4,
-    ENTITY_REFERENCE_NODE: 5,
-    ENTITY_NODE: 6,
-    PROCESSING_INSTRUCTION_NODE: 7,
-    COMMENT_NODE: 8,
-    DOCUMENT_NODE: 9,
-    DOCUMENT_TYPE_NODE: 10,
-    DOCUMENT_FRAGMENT_NODE: 11,
-    NOTATION_NODE: 12
-  });
-}
-
-
-
-(function(global) {
-  function shouldUseCache(tagName, attributes) {
-    if (tagName === 'select') return false;
-    if ('type' in attributes) return false;
-    return true;
-  }
-
-  var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
-    try {
-      var el = document.createElement('<input name="x">');
-      return el.tagName.toLowerCase() === 'input' && el.name === 'x';
-    }
-    catch(err) {
-      return false;
-    }
-  })();
-
-  var element = global.Element;
-
-  global.Element = function(tagName, attributes) {
-    attributes = attributes || { };
-    tagName = tagName.toLowerCase();
-    var cache = Element.cache;
-
-    if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
-      tagName = '<' + tagName + ' name="' + attributes.name + '">';
-      delete attributes.name;
-      return Element.writeAttribute(document.createElement(tagName), attributes);
-    }
-
-    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
-
-    var node = shouldUseCache(tagName, attributes) ?
-     cache[tagName].cloneNode(false) : document.createElement(tagName);
-
-    return Element.writeAttribute(node, attributes);
-  };
-
-  Object.extend(global.Element, element || { });
-  if (element) global.Element.prototype = element.prototype;
-
-})(this);
-
-Element.idCounter = 1;
-Element.cache = { };
-
-Element._purgeElement = function(element) {
-  var uid = element._prototypeUID;
-  if (uid) {
-    Element.stopObserving(element);
-    element._prototypeUID = void 0;
-    delete Element.Storage[uid];
-  }
-}
-
-Element.Methods = {
-  visible: function(element) {
-    return $(element).style.display != 'none';
-  },
-
-  toggle: function(element) {
-    element = $(element);
-    Element[Element.visible(element) ? 'hide' : 'show'](element);
-    return element;
-  },
-
-  hide: function(element) {
-    element = $(element);
-    element.style.display = 'none';
-    return element;
-  },
-
-  show: function(element) {
-    element = $(element);
-    element.style.display = '';
-    return element;
-  },
-
-  remove: function(element) {
-    element = $(element);
-    element.parentNode.removeChild(element);
-    return element;
-  },
-
-  update: (function(){
-
-    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
-      var el = document.createElement("select"),
-          isBuggy = true;
-      el.innerHTML = "<option value=\"test\">test</option>";
-      if (el.options && el.options[0]) {
-        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
-      }
-      el = null;
-      return isBuggy;
-    })();
-
-    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
-      try {
-        var el = document.createElement("table");
-        if (el && el.tBodies) {
-          el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
-          var isBuggy = typeof el.tBodies[0] == "undefined";
-          el = null;
-          return isBuggy;
-        }
-      } catch (e) {
-        return true;
-      }
-    })();
-
-    var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
-      try {
-        var el = document.createElement('div');
-        el.innerHTML = "<link>";
-        var isBuggy = (el.childNodes.length === 0);
-        el = null;
-        return isBuggy;
-      } catch(e) {
-        return true;
-      }
-    })();
-
-    var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
-     TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
-
-    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
-      var s = document.createElement("script"),
-          isBuggy = false;
-      try {
-        s.appendChild(document.createTextNode(""));
-        isBuggy = !s.firstChild ||
-          s.firstChild && s.firstChild.nodeType !== 3;
-      } catch (e) {
-        isBuggy = true;
-      }
-      s = null;
-      return isBuggy;
-    })();
-
-
-    function update(element, content) {
-      element = $(element);
-      var purgeElement = Element._purgeElement;
-
-      var descendants = element.getElementsByTagName('*'),
-       i = descendants.length;
-      while (i--) purgeElement(descendants[i]);
-
-      if (content && content.toElement)
-        content = content.toElement();
-
-      if (Object.isElement(content))
-        return element.update().insert(content);
-
-      content = Object.toHTML(content);
-
-      var tagName = element.tagName.toUpperCase();
-
-      if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
-        element.text = content;
-        return element;
-      }
-
-      if (ANY_INNERHTML_BUGGY) {
-        if (tagName in Element._insertionTranslations.tags) {
-          while (element.firstChild) {
-            element.removeChild(element.firstChild);
-          }
-          Element._getContentFromAnonymousElement(tagName, content.stripScripts())
-            .each(function(node) {
-              element.appendChild(node)
-            });
-        } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
-          while (element.firstChild) {
-            element.removeChild(element.firstChild);
-          }
-          var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true);
-          nodes.each(function(node) { element.appendChild(node) });
-        }
-        else {
-          element.innerHTML = content.stripScripts();
-        }
-      }
-      else {
-        element.innerHTML = content.stripScripts();
-      }
-
-      content.evalScripts.bind(content).defer();
-      return element;
-    }
-
-    return update;
-  })(),
-
-  replace: function(element, content) {
-    element = $(element);
-    if (content && content.toElement) content = content.toElement();
-    else if (!Object.isElement(content)) {
-      content = Object.toHTML(content);
-      var range = element.ownerDocument.createRange();
-      range.selectNode(element);
-      content.evalScripts.bind(content).defer();
-      content = range.createContextualFragment(content.stripScripts());
-    }
-    element.parentNode.replaceChild(content, element);
-    return element;
-  },
-
-  insert: function(element, insertions) {
-    element = $(element);
-
-    if (Object.isString(insertions) || Object.isNumber(insertions) ||
-        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
-          insertions = {bottom:insertions};
-
-    var content, insert, tagName, childNodes;
-
-    for (var position in insertions) {
-      content  = insertions[position];
-      position = position.toLowerCase();
-      insert = Element._insertionTranslations[position];
-
-      if (content && content.toElement) content = content.toElement();
-      if (Object.isElement(content)) {
-        insert(element, content);
-        continue;
-      }
-
-      content = Object.toHTML(content);
-
-      tagName = ((position == 'before' || position == 'after')
-        ? element.parentNode : element).tagName.toUpperCase();
-
-      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
-
-      if (position == 'top' || position == 'after') childNodes.reverse();
-      childNodes.each(insert.curry(element));
-
-      content.evalScripts.bind(content).defer();
-    }
-
-    return element;
-  },
-
-  wrap: function(element, wrapper, attributes) {
-    element = $(element);
-    if (Object.isElement(wrapper))
-      $(wrapper).writeAttribute(attributes || { });
-    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
-    else wrapper = new Element('div', wrapper);
-    if (element.parentNode)
-      element.parentNode.replaceChild(wrapper, element);
-    wrapper.appendChild(element);
-    return wrapper;
-  },
-
-  inspect: function(element) {
-    element = $(element);
-    var result = '<' + element.tagName.toLowerCase();
-    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
-      var property = pair.first(),
-          attribute = pair.last(),
-          value = (element[property] || '').toString();
-      if (value) result += ' ' + attribute + '=' + value.inspect(true);
-    });
-    return result + '>';
-  },
-
-  recursivelyCollect: function(element, property, maximumLength) {
-    element = $(element);
-    maximumLength = maximumLength || -1;
-    var elements = [];
-
-    while (element = element[property]) {
-      if (element.nodeType == 1)
-        elements.push(Element.extend(element));
-      if (elements.length == maximumLength)
-        break;
-    }
-
-    return elements;
-  },
-
-  ancestors: function(element) {
-    return Element.recursivelyCollect(element, 'parentNode');
-  },
-
-  descendants: function(element) {
-    return Element.select(element, "*");
-  },
-
-  firstDescendant: function(element) {
-    element = $(element).firstChild;
-    while (element && element.nodeType != 1) element = element.nextSibling;
-    return $(element);
-  },
-
-  immediateDescendants: function(element) {
-    var results = [], child = $(element).firstChild;
-    while (child) {
-      if (child.nodeType === 1) {
-        results.push(Element.extend(child));
-      }
-      child = child.nextSibling;
-    }
-    return results;
-  },
-
-  previousSiblings: function(element, maximumLength) {
-    return Element.recursivelyCollect(element, 'previousSibling');
-  },
-
-  nextSiblings: function(element) {
-    return Element.recursivelyCollect(element, 'nextSibling');
-  },
-
-  siblings: function(element) {
-    element = $(element);
-    return Element.previousSiblings(element).reverse()
-      .concat(Element.nextSiblings(element));
-  },
-
-  match: function(element, selector) {
-    element = $(element);
-    if (Object.isString(selector))
-      return Prototype.Selector.match(element, selector);
-    return selector.match(element);
-  },
-
-  up: function(element, expression, index) {
-    element = $(element);
-    if (arguments.length == 1) return $(element.parentNode);
-    var ancestors = Element.ancestors(element);
-    return Object.isNumber(expression) ? ancestors[expression] :
-      Prototype.Selector.find(ancestors, expression, index);
-  },
-
-  down: function(element, expression, index) {
-    element = $(element);
-    if (arguments.length == 1) return Element.firstDescendant(element);
-    return Object.isNumber(expression) ? Element.descendants(element)[expression] :
-      Element.select(element, expression)[index || 0];
-  },
-
-  previous: function(element, expression, index) {
-    element = $(element);
-    if (Object.isNumber(expression)) index = expression, expression = false;
-    if (!Object.isNumber(index)) index = 0;
-
-    if (expression) {
-      return Prototype.Selector.find(element.previousSiblings(), expression, index);
-    } else {
-      return element.recursivelyCollect("previousSibling", index + 1)[index];
-    }
-  },
-
-  next: function(element, expression, index) {
-    element = $(element);
-    if (Object.isNumber(expression)) index = expression, expression = false;
-    if (!Object.isNumber(index)) index = 0;
-
-    if (expression) {
-      return Prototype.Selector.find(element.nextSiblings(), expression, index);
-    } else {
-      var maximumLength = Object.isNumber(index) ? index + 1 : 1;
-      return element.recursivelyCollect("nextSibling", index + 1)[index];
-    }
-  },
-
-
-  select: function(element) {
-    element = $(element);
-    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
-    return Prototype.Selector.select(expressions, element);
-  },
-
-  adjacent: function(element) {
-    element = $(element);
-    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
-    return Prototype.Selector.select(expressions, element.parentNode).without(element);
-  },
-
-  identify: function(element) {
-    element = $(element);
-    var id = Element.readAttribute(element, 'id');
-    if (id) return id;
-    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
-    Element.writeAttribute(element, 'id', id);
-    return id;
-  },
-
-  readAttribute: function(element, name) {
-    element = $(element);
-    if (Prototype.Browser.IE) {
-      var t = Element._attributeTranslations.read;
-      if (t.values[name]) return t.values[name](element, name);
-      if (t.names[name]) name = t.names[name];
-      if (name.include(':')) {
-        return (!element.attributes || !element.attributes[name]) ? null :
-         element.attributes[name].value;
-      }
-    }
-    return element.getAttribute(name);
-  },
-
-  writeAttribute: function(element, name, value) {
-    element = $(element);
-    var attributes = { }, t = Element._attributeTranslations.write;
-
-    if (typeof name == 'object') attributes = name;
-    else attributes[name] = Object.isUndefined(value) ? true : value;
-
-    for (var attr in attributes) {
-      name = t.names[attr] || attr;
-      value = attributes[attr];
-      if (t.values[attr]) name = t.values[attr](element, value);
-      if (value === false || value === null)
-        element.removeAttribute(name);
-      else if (value === true)
-        element.setAttribute(name, name);
-      else element.setAttribute(name, value);
-    }
-    return element;
-  },
-
-  getHeight: function(element) {
-    return Element.getDimensions(element).height;
-  },
-
-  getWidth: function(element) {
-    return Element.getDimensions(element).width;
-  },
-
-  classNames: function(element) {
-    return new Element.ClassNames(element);
-  },
-
-  hasClassName: function(element, className) {
-    if (!(element = $(element))) return;
-    var elementClassName = element.className;
-    return (elementClassName.length > 0 && (elementClassName == className ||
-      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
-  },
-
-  addClassName: function(element, className) {
-    if (!(element = $(element))) return;
-    if (!Element.hasClassName(element, className))
-      element.className += (element.className ? ' ' : '') + className;
-    return element;
-  },
-
-  removeClassName: function(element, className) {
-    if (!(element = $(element))) return;
-    element.className = element.className.replace(
-      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
-    return element;
-  },
-
-  toggleClassName: function(element, className) {
-    if (!(element = $(element))) return;
-    return Element[Element.hasClassName(element, className) ?
-      'removeClassName' : 'addClassName'](element, className);
-  },
-
-  cleanWhitespace: function(element) {
-    element = $(element);
-    var node = element.firstChild;
-    while (node) {
-      var nextNode = node.nextSibling;
-      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
-        element.removeChild(node);
-      node = nextNode;
-    }
-    return element;
-  },
-
-  empty: function(element) {
-    return $(element).innerHTML.blank();
-  },
-
-  descendantOf: function(element, ancestor) {
-    element = $(element), ancestor = $(ancestor);
-
-    if (element.compareDocumentPosition)
-      return (element.compareDocumentPosition(ancestor) & 8) === 8;
-
-    if (ancestor.contains)
-      return ancestor.contains(element) && ancestor !== element;
-
-    while (element = element.parentNode)
-      if (element == ancestor) return true;
-
-    return false;
-  },
-
-  scrollTo: function(element) {
-    element = $(element);
-    var pos = Element.cumulativeOffset(element);
-    window.scrollTo(pos[0], pos[1]);
-    return element;
-  },
-
-  getStyle: function(element, style) {
-    element = $(element);
-    style = style == 'float' ? 'cssFloat' : style.camelize();
-    var value = element.style[style];
-    if (!value || value == 'auto') {
-      var css = document.defaultView.getComputedStyle(element, null);
-      value = css ? css[style] : null;
-    }
-    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
-    return value == 'auto' ? null : value;
-  },
-
-  getOpacity: function(element) {
-    return $(element).getStyle('opacity');
-  },
-
-  setStyle: function(element, styles) {
-    element = $(element);
-    var elementStyle = element.style, match;
-    if (Object.isString(styles)) {
-      element.style.cssText += ';' + styles;
-      return styles.include('opacity') ?
-        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
-    }
-    for (var property in styles)
-      if (property == 'opacity') element.setOpacity(styles[property]);
-      else
-        elementStyle[(property == 'float' || property == 'cssFloat') ?
-          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
-            property] = styles[property];
-
-    return element;
-  },
-
-  setOpacity: function(element, value) {
-    element = $(element);
-    element.style.opacity = (value == 1 || value === '') ? '' :
-      (value < 0.00001) ? 0 : value;
-    return element;
-  },
-
-  makePositioned: function(element) {
-    element = $(element);
-    var pos = Element.getStyle(element, 'position');
-    if (pos == 'static' || !pos) {
-      element._madePositioned = true;
-      element.style.position = 'relative';
-      if (Prototype.Browser.Opera) {
-        element.style.top = 0;
-        element.style.left = 0;
-      }
-    }
-    return element;
-  },
-
-  undoPositioned: function(element) {
-    element = $(element);
-    if (element._madePositioned) {
-      element._madePositioned = undefined;
-      element.style.position =
-        element.style.top =
-        element.style.left =
-        element.style.bottom =
-        element.style.right = '';
-    }
-    return element;
-  },
-
-  makeClipping: function(element) {
-    element = $(element);
-    if (element._overflow) return element;
-    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
-    if (element._overflow !== 'hidden')
-      element.style.overflow = 'hidden';
-    return element;
-  },
-
-  undoClipping: function(element) {
-    element = $(element);
-    if (!element._overflow) return element;
-    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
-    element._overflow = null;
-    return element;
-  },
-
-  clonePosition: function(element, source) {
-    var options = Object.extend({
-      setLeft:    true,
-      setTop:     true,
-      setWidth:   true,
-      setHeight:  true,
-      offsetTop:  0,
-      offsetLeft: 0
-    }, arguments[2] || { });
-
-    source = $(source);
-    var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
-
-    element = $(element);
-
-    if (Element.getStyle(element, 'position') == 'absolute') {
-      parent = Element.getOffsetParent(element);
-      delta = Element.viewportOffset(parent);
-    }
-
-    if (parent == document.body) {
-      delta[0] -= document.body.offsetLeft;
-      delta[1] -= document.body.offsetTop;
-    }
-
-    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
-    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
-    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
-    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
-    return element;
-  }
-};
-
-Object.extend(Element.Methods, {
-  getElementsBySelector: Element.Methods.select,
-
-  childElements: Element.Methods.immediateDescendants
-});
-
-Element._attributeTranslations = {
-  write: {
-    names: {
-      className: 'class',
-      htmlFor:   'for'
-    },
-    values: { }
-  }
-};
-
-if (Prototype.Browser.Opera) {
-  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
-    function(proceed, element, style) {
-      switch (style) {
-        case 'height': case 'width':
-          if (!Element.visible(element)) return null;
-
-          var dim = parseInt(proceed(element, style), 10);
-
-          if (dim !== element['offset' + style.capitalize()])
-            return dim + 'px';
-
-          var properties;
-          if (style === 'height') {
-            properties = ['border-top-width', 'padding-top',
-             'padding-bottom', 'border-bottom-width'];
-          }
-          else {
-            properties = ['border-left-width', 'padding-left',
-             'padding-right', 'border-right-width'];
-          }
-          return properties.inject(dim, function(memo, property) {
-            var val = proceed(element, property);
-            return val === null ? memo : memo - parseInt(val, 10);
-          }) + 'px';
-        default: return proceed(element, style);
-      }
-    }
-  );
-
-  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
-    function(proceed, element, attribute) {
-      if (attribute === 'title') return element.title;
-      return proceed(element, attribute);
-    }
-  );
-}
-
-else if (Prototype.Browser.IE) {
-  Element.Methods.getStyle = function(element, style) {
-    element = $(element);
-    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
-    var value = element.style[style];
-    if (!value && element.currentStyle) value = element.currentStyle[style];
-
-    if (style == 'opacity') {
-      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
-        if (value[1]) return parseFloat(value[1]) / 100;
-      return 1.0;
-    }
-
-    if (value == 'auto') {
-      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
-        return element['offset' + style.capitalize()] + 'px';
-      return null;
-    }
-    return value;
-  };
-
-  Element.Methods.setOpacity = function(element, value) {
-    function stripAlpha(filter){
-      return filter.replace(/alpha\([^\)]*\)/gi,'');
-    }
-    element = $(element);
-    var currentStyle = element.currentStyle;
-    if ((currentStyle && !currentStyle.hasLayout) ||
-      (!currentStyle && element.style.zoom == 'normal'))
-        element.style.zoom = 1;
-
-    var filter = element.getStyle('filter'), style = element.style;
-    if (value == 1 || value === '') {
-      (filter = stripAlpha(filter)) ?
-        style.filter = filter : style.removeAttribute('filter');
-      return element;
-    } else if (value < 0.00001) value = 0;
-    style.filter = stripAlpha(filter) +
-      'alpha(opacity=' + (value * 100) + ')';
-    return element;
-  };
-
-  Element._attributeTranslations = (function(){
-
-    var classProp = 'className',
-        forProp = 'for',
-        el = document.createElement('div');
-
-    el.setAttribute(classProp, 'x');
-
-    if (el.className !== 'x') {
-      el.setAttribute('class', 'x');
-      if (el.className === 'x') {
-        classProp = 'class';
-      }
-    }
-    el = null;
-
-    el = document.createElement('label');
-    el.setAttribute(forProp, 'x');
-    if (el.htmlFor !== 'x') {
-      el.setAttribute('htmlFor', 'x');
-      if (el.htmlFor === 'x') {
-        forProp = 'htmlFor';
-      }
-    }
-    el = null;
-
-    return {
-      read: {
-        names: {
-          'class':      classProp,
-          'className':  classProp,
-          'for':        forProp,
-          'htmlFor':    forProp
-        },
-        values: {
-          _getAttr: function(element, attribute) {
-            return element.getAttribute(attribute);
-          },
-          _getAttr2: function(element, attribute) {
-            return element.getAttribute(attribute, 2);
-          },
-          _getAttrNode: function(element, attribute) {
-            var node = element.getAttributeNode(attribute);
-            return node ? node.value : "";
-          },
-          _getEv: (function(){
-
-            var el = document.createElement('div'), f;
-            el.onclick = Prototype.emptyFunction;
-            var value = el.getAttribute('onclick');
-
-            if (String(value).indexOf('{') > -1) {
-              f = function(element, attribute) {
-                attribute = element.getAttribute(attribute);
-                if (!attribute) return null;
-                attribute = attribute.toString();
-                attribute = attribute.split('{')[1];
-                attribute = attribute.split('}')[0];
-                return attribute.strip();
-              };
-            }
-            else if (value === '') {
-              f = function(element, attribute) {
-                attribute = element.getAttribute(attribute);
-                if (!attribute) return null;
-                return attribute.strip();
-              };
-            }
-            el = null;
-            return f;
-          })(),
-          _flag: function(element, attribute) {
-            return $(element).hasAttribute(attribute) ? attribute : null;
-          },
-          style: function(element) {
-            return element.style.cssText.toLowerCase();
-          },
-          title: function(element) {
-            return element.title;
-          }
-        }
-      }
-    }
-  })();
-
-  Element._attributeTranslations.write = {
-    names: Object.extend({
-      cellpadding: 'cellPadding',
-      cellspacing: 'cellSpacing'
-    }, Element._attributeTranslations.read.names),
-    values: {
-      checked: function(element, value) {
-        element.checked = !!value;
-      },
-
-      style: function(element, value) {
-        element.style.cssText = value ? value : '';
-      }
-    }
-  };
-
-  Element._attributeTranslations.has = {};
-
-  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
-      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
-    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
-    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
-  });
-
-  (function(v) {
-    Object.extend(v, {
-      href:        v._getAttr2,
-      src:         v._getAttr2,
-      type:        v._getAttr,
-      action:      v._getAttrNode,
-      disabled:    v._flag,
-      checked:     v._flag,
-      readonly:    v._flag,
-      multiple:    v._flag,
-      onload:      v._getEv,
-      onunload:    v._getEv,
-      onclick:     v._getEv,
-      ondblclick:  v._getEv,
-      onmousedown: v._getEv,
-      onmouseup:   v._getEv,
-      onmouseover: v._getEv,
-      onmousemove: v._getEv,
-      onmouseout:  v._getEv,
-      onfocus:     v._getEv,
-      onblur:      v._getEv,
-      onkeypress:  v._getEv,
-      onkeydown:   v._getEv,
-      onkeyup:     v._getEv,
-      onsubmit:    v._getEv,
-      onreset:     v._getEv,
-      onselect:    v._getEv,
-      onchange:    v._getEv
-    });
-  })(Element._attributeTranslations.read.values);
-
-  if (Prototype.BrowserFeatures.ElementExtensions) {
-    (function() {
-      function _descendants(element) {
-        var nodes = element.getElementsByTagName('*'), results = [];
-        for (var i = 0, node; node = nodes[i]; i++)
-          if (node.tagName !== "!") // Filter out comment nodes.
-            results.push(node);
-        return results;
-      }
-
-      Element.Methods.down = function(element, expression, index) {
-        element = $(element);
-        if (arguments.length == 1) return element.firstDescendant();
-        return Object.isNumber(expression) ? _descendants(element)[expression] :
-          Element.select(element, expression)[index || 0];
-      }
-    })();
-  }
-
-}
-
-else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
-  Element.Methods.setOpacity = function(element, value) {
-    element = $(element);
-    element.style.opacity = (value == 1) ? 0.999999 :
-      (value === '') ? '' : (value < 0.00001) ? 0 : value;
-    return element;
-  };
-}
-
-else if (Prototype.Browser.WebKit) {
-  Element.Methods.setOpacity = function(element, value) {
-    element = $(element);
-    element.style.opacity = (value == 1 || value === '') ? '' :
-      (value < 0.00001) ? 0 : value;
-
-    if (value == 1)
-      if (element.tagName.toUpperCase() == 'IMG' && element.width) {
-        element.width++; element.width--;
-      } else try {
-        var n = document.createTextNode(' ');
-        element.appendChild(n);
-        element.removeChild(n);
-      } catch (e) { }
-
-    return element;
-  };
-}
-
-if ('outerHTML' in document.documentElement) {
-  Element.Methods.replace = function(element, content) {
-    element = $(element);
-
-    if (content && content.toElement) content = content.toElement();
-    if (Object.isElement(content)) {
-      element.parentNode.replaceChild(content, element);
-      return element;
-    }
-
-    content = Object.toHTML(content);
-    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
-
-    if (Element._insertionTranslations.tags[tagName]) {
-      var nextSibling = element.next(),
-          fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
-      parent.removeChild(element);
-      if (nextSibling)
-        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
-      else
-        fragments.each(function(node) { parent.appendChild(node) });
-    }
-    else element.outerHTML = content.stripScripts();
-
-    content.evalScripts.bind(content).defer();
-    return element;
-  };
-}
-
-Element._returnOffset = function(l, t) {
-  var result = [l, t];
-  result.left = l;
-  result.top = t;
-  return result;
-};
-
-Element._getContentFromAnonymousElement = function(tagName, html, force) {
-  var div = new Element('div'),
-      t = Element._insertionTranslations.tags[tagName];
-
-  var workaround = false;
-  if (t) workaround = true;
-  else if (force) {
-    workaround = true;
-    t = ['', '', 0];
-  }
-
-  if (workaround) {
-    div.innerHTML = '&nbsp;' + t[0] + html + t[1];
-    div.removeChild(div.firstChild);
-    for (var i = t[2]; i--; ) {
-      div = div.firstChild;
-    }
-  }
-  else {
-    div.innerHTML = html;
-  }
-  return $A(div.childNodes);
-};
-
-Element._insertionTranslations = {
-  before: function(element, node) {
-    element.parentNode.insertBefore(node, element);
-  },
-  top: function(element, node) {
-    element.insertBefore(node, element.firstChild);
-  },
-  bottom: function(element, node) {
-    element.appendChild(node);
-  },
-  after: function(element, node) {
-    element.parentNode.insertBefore(node, element.nextSibling);
-  },
-  tags: {
-    TABLE:  ['<table>',                '</table>',                   1],
-    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
-    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
-    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
-    SELECT: ['<select>',               '</select>',                  1]
-  }
-};
-
-(function() {
-  var tags = Element._insertionTranslations.tags;
-  Object.extend(tags, {
-    THEAD: tags.TBODY,
-    TFOOT: tags.TBODY,
-    TH:    tags.TD
-  });
-})();
-
-Element.Methods.Simulated = {
-  hasAttribute: function(element, attribute) {
-    attribute = Element._attributeTranslations.has[attribute] || attribute;
-    var node = $(element).getAttributeNode(attribute);
-    return !!(node && node.specified);
-  }
-};
-
-Element.Methods.ByTag = { };
-
-Object.extend(Element, Element.Methods);
-
-(function(div) {
-
-  if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
-    window.HTMLElement = { };
-    window.HTMLElement.prototype = div['__proto__'];
-    Prototype.BrowserFeatures.ElementExtensions = true;
-  }
-
-  div = null;
-
-})(document.createElement('div'));
-
-Element.extend = (function() {
-
-  function checkDeficiency(tagName) {
-    if (typeof window.Element != 'undefined') {
-      var proto = window.Element.prototype;
-      if (proto) {
-        var id = '_' + (Math.random()+'').slice(2),
-            el = document.createElement(tagName);
-        proto[id] = 'x';
-        var isBuggy = (el[id] !== 'x');
-        delete proto[id];
-        el = null;
-        return isBuggy;
-      }
-    }
-    return false;
-  }
-
-  function extendElementWith(element, methods) {
-    for (var property in methods) {
-      var value = methods[property];
-      if (Object.isFunction(value) && !(property in element))
-        element[property] = value.methodize();
-    }
-  }
-
-  var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
-
-  if (Prototype.BrowserFeatures.SpecificElementExtensions) {
-    if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
-      return function(element) {
-        if (element && typeof element._extendedByPrototype == 'undefined') {
-          var t = element.tagName;
-          if (t && (/^(?:object|applet|embed)$/i.test(t))) {
-            extendElementWith(element, Element.Methods);
-            extendElementWith(element, Element.Methods.Simulated);
-            extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
-          }
-        }
-        return element;
-      }
-    }
-    return Prototype.K;
-  }
-
-  var Methods = { }, ByTag = Element.Methods.ByTag;
-
-  var extend = Object.extend(function(element) {
-    if (!element || typeof element._extendedByPrototype != 'undefined' ||
-        element.nodeType != 1 || element == window) return element;
-
-    var methods = Object.clone(Methods),
-        tagName = element.tagName.toUpperCase();
-
-    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
-
-    extendElementWith(element, methods);
-
-    element._extendedByPrototype = Prototype.emptyFunction;
-    return element;
-
-  }, {
-    refresh: function() {
-      if (!Prototype.BrowserFeatures.ElementExtensions) {
-        Object.extend(Methods, Element.Methods);
-        Object.extend(Methods, Element.Methods.Simulated);
-      }
-    }
-  });
-
-  extend.refresh();
-  return extend;
-})();
-
-if (document.documentElement.hasAttribute) {
-  Element.hasAttribute = function(element, attribute) {
-    return element.hasAttribute(attribute);
-  };
-}
-else {
-  Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
-}
-
-Element.addMethods = function(methods) {
-  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
-
-  if (!methods) {
-    Object.extend(Form, Form.Methods);
-    Object.extend(Form.Element, Form.Element.Methods);
-    Object.extend(Element.Methods.ByTag, {
-      "FORM":     Object.clone(Form.Methods),
-      "INPUT":    Object.clone(Form.Element.Methods),
-      "SELECT":   Object.clone(Form.Element.Methods),
-      "TEXTAREA": Object.clone(Form.Element.Methods),
-      "BUTTON":   Object.clone(Form.Element.Methods)
-    });
-  }
-
-  if (arguments.length == 2) {
-    var tagName = methods;
-    methods = arguments[1];
-  }
-
-  if (!tagName) Object.extend(Element.Methods, methods || { });
-  else {
-    if (Object.isArray(tagName)) tagName.each(extend);
-    else extend(tagName);
-  }
-
-  function extend(tagName) {
-    tagName = tagName.toUpperCase();
-    if (!Element.Methods.ByTag[tagName])
-      Element.Methods.ByTag[tagName] = { };
-    Object.extend(Element.Methods.ByTag[tagName], methods);
-  }
-
-  function copy(methods, destination, onlyIfAbsent) {
-    onlyIfAbsent = onlyIfAbsent || false;
-    for (var property in methods) {
-      var value = methods[property];
-      if (!Object.isFunction(value)) continue;
-      if (!onlyIfAbsent || !(property in destination))
-        destination[property] = value.methodize();
-    }
-  }
-
-  function findDOMClass(tagName) {
-    var klass;
-    var trans = {
-      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
-      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
-      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
-      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
-      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
-      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
-      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
-      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
-      "FrameSet", "IFRAME": "IFrame"
-    };
-    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
-    if (window[klass]) return window[klass];
-    klass = 'HTML' + tagName + 'Element';
-    if (window[klass]) return window[klass];
-    klass = 'HTML' + tagName.capitalize() + 'Element';
-    if (window[klass]) return window[klass];
-
-    var element = document.createElement(tagName),
-        proto = element['__proto__'] || element.constructor.prototype;
-
-    element = null;
-    return proto;
-  }
-
-  var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
-   Element.prototype;
-
-  if (F.ElementExtensions) {
-    copy(Element.Methods, elementPrototype);
-    copy(Element.Methods.Simulated, elementPrototype, true);
-  }
-
-  if (F.SpecificElementExtensions) {
-    for (var tag in Element.Methods.ByTag) {
-      var klass = findDOMClass(tag);
-      if (Object.isUndefined(klass)) continue;
-      copy(T[tag], klass.prototype);
-    }
-  }
-
-  Object.extend(Element, Element.Methods);
-  delete Element.ByTag;
-
-  if (Element.extend.refresh) Element.extend.refresh();
-  Element.cache = { };
-};
-
-
-document.viewport = {
-
-  getDimensions: function() {
-    return { width: this.getWidth(), height: this.getHeight() };
-  },
-
-  getScrollOffsets: function() {
-    return Element._returnOffset(
-      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
-      window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop);
-  }
-};
-
-(function(viewport) {
-  var B = Prototype.Browser, doc = document, element, property = {};
-
-  function getRootElement() {
-    if (B.WebKit && !doc.evaluate)
-      return document;
-
-    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
-      return document.body;
-
-    return document.documentElement;
-  }
-
-  function define(D) {
-    if (!element) element = getRootElement();
-
-    property[D] = 'client' + D;
-
-    viewport['get' + D] = function() { return element[property[D]] };
-    return viewport['get' + D]();
-  }
-
-  viewport.getWidth  = define.curry('Width');
-
-  viewport.getHeight = define.curry('Height');
-})(document.viewport);
-
-
-Element.Storage = {
-  UID: 1
-};
-
-Element.addMethods({
-  getStorage: function(element) {
-    if (!(element = $(element))) return;
-
-    var uid;
-    if (element === window) {
-      uid = 0;
-    } else {
-      if (typeof element._prototypeUID === "undefined")
-        element._prototypeUID = Element.Storage.UID++;
-      uid = element._prototypeUID;
-    }
-
-    if (!Element.Storage[uid])
-      Element.Storage[uid] = $H();
-
-    return Element.Storage[uid];
-  },
-
-  store: function(element, key, value) {
-    if (!(element = $(element))) return;
-
-    if (arguments.length === 2) {
-      Element.getStorage(element).update(key);
-    } else {
-      Element.getStorage(element).set(key, value);
-    }
-
-    return element;
-  },
-
-  retrieve: function(element, key, defaultValue) {
-    if (!(element = $(element))) return;
-    var hash = Element.getStorage(element), value = hash.get(key);
-
-    if (Object.isUndefined(value)) {
-      hash.set(key, defaultValue);
-      value = defaultValue;
-    }
-
-    return value;
-  },
-
-  clone: function(element, deep) {
-    if (!(element = $(element))) return;
-    var clone = element.cloneNode(deep);
-    clone._prototypeUID = void 0;
-    if (deep) {
-      var descendants = Element.select(clone, '*'),
-          i = descendants.length;
-      while (i--) {
-        descendants[i]._prototypeUID = void 0;
-      }
-    }
-    return Element.extend(clone);
-  },
-
-  purge: function(element) {
-    if (!(element = $(element))) return;
-    var purgeElement = Element._purgeElement;
-
-    purgeElement(element);
-
-    var descendants = element.getElementsByTagName('*'),
-     i = descendants.length;
-
-    while (i--) purgeElement(descendants[i]);
-
-    return null;
-  }
-});
-
-(function() {
-
-  function toDecimal(pctString) {
-    var match = pctString.match(/^(\d+)%?$/i);
-    if (!match) return null;
-    return (Number(match[1]) / 100);
-  }
-
-  function getPixelValue(value, property, context) {
-    var element = null;
-    if (Object.isElement(value)) {
-      element = value;
-      value = element.getStyle(property);
-    }
-
-    if (value === null) {
-      return null;
-    }
-
-    if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
-      return window.parseFloat(value);
-    }
-
-    var isPercentage = value.include('%'), isViewport = (context === document.viewport);
-
-    if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
-      var style = element.style.left, rStyle = element.runtimeStyle.left;
-      element.runtimeStyle.left = element.currentStyle.left;
-      element.style.left = value || 0;
-      value = element.style.pixelLeft;
-      element.style.left = style;
-      element.runtimeStyle.left = rStyle;
-
-      return value;
-    }
-
-    if (element && isPercentage) {
-      context = context || element.parentNode;
-      var decimal = toDecimal(value);
-      var whole = null;
-      var position = element.getStyle('position');
-
-      var isHorizontal = property.include('left') || property.include('right') ||
-       property.include('width');
-
-      var isVertical =  property.include('top') || property.include('bottom') ||
-        property.include('height');
-
-      if (context === document.viewport) {
-        if (isHorizontal) {
-          whole = document.viewport.getWidth();
-        } else if (isVertical) {
-          whole = document.viewport.getHeight();
-        }
-      } else {
-        if (isHorizontal) {
-          whole = $(context).measure('width');
-        } else if (isVertical) {
-          whole = $(context).measure('height');
-        }
-      }
-
-      return (whole === null) ? 0 : whole * decimal;
-    }
-
-    return 0;
-  }
-
-  function toCSSPixels(number) {
-    if (Object.isString(number) && number.endsWith('px')) {
-      return number;
-    }
-    return number + 'px';
-  }
-
-  function isDisplayed(element) {
-    var originalElement = element;
-    while (element && element.parentNode) {
-      var display = element.getStyle('display');
-      if (display === 'none') {
-        return false;
-      }
-      element = $(element.parentNode);
-    }
-    return true;
-  }
-
-  var hasLayout = Prototype.K;
-  if ('currentStyle' in document.documentElement) {
-    hasLayout = function(element) {
-      if (!element.currentStyle.hasLayout) {
-        element.style.zoom = 1;
-      }
-      return element;
-    };
-  }
-
-  function cssNameFor(key) {
-    if (key.include('border')) key = key + '-width';
-    return key.camelize();
-  }
-
-  Element.Layout = Class.create(Hash, {
-    initialize: function($super, element, preCompute) {
-      $super();
-      this.element = $(element);
-
-      Element.Layout.PROPERTIES.each( function(property) {
-        this._set(property, null);
-      }, this);
-
-      if (preCompute) {
-        this._preComputing = true;
-        this._begin();
-        Element.Layout.PROPERTIES.each( this._compute, this );
-        this._end();
-        this._preComputing = false;
-      }
-    },
-
-    _set: function(property, value) {
-      return Hash.prototype.set.call(this, property, value);
-    },
-
-    set: function(property, value) {
-      throw "Properties of Element.Layout are read-only.";
-    },
-
-    get: function($super, property) {
-      var value = $super(property);
-      return value === null ? this._compute(property) : value;
-    },
-
-    _begin: function() {
-      if (this._prepared) return;
-
-      var element = this.element;
-      if (isDisplayed(element)) {
-        this._prepared = true;
-        return;
-      }
-
-      var originalStyles = {
-        position:   element.style.position   || '',
-        width:      element.style.width      || '',
-        visibility: element.style.visibility || '',
-        display:    element.style.display    || ''
-      };
-
-      element.store('prototype_original_styles', originalStyles);
-
-      var position = element.getStyle('position'),
-       width = element.getStyle('width');
-
-      if (width === "0px" || width === null) {
-        element.style.display = 'block';
-        width = element.getStyle('width');
-      }
-
-      var context = (position === 'fixed') ? document.viewport :
-       element.parentNode;
-
-      element.setStyle({
-        position:   'absolute',
-        visibility: 'hidden',
-        display:    'block'
-      });
-
-      var positionedWidth = element.getStyle('width');
-
-      var newWidth;
-      if (width && (positionedWidth === width)) {
-        newWidth = getPixelValue(element, 'width', context);
-      } else if (position === 'absolute' || position === 'fixed') {
-        newWidth = getPixelValue(element, 'width', context);
-      } else {
-        var parent = element.parentNode, pLayout = $(parent).getLayout();
-
-        newWidth = pLayout.get('width') -
-         this.get('margin-left') -
-         this.get('border-left') -
-         this.get('padding-left') -
-         this.get('padding-right') -
-         this.get('border-right') -
-         this.get('margin-right');
-      }
-
-      element.setStyle({ width: newWidth + 'px' });
-
-      this._prepared = true;
-    },
-
-    _end: function() {
-      var element = this.element;
-      var originalStyles = element.retrieve('prototype_original_styles');
-      element.store('prototype_original_styles', null);
-      element.setStyle(originalStyles);
-      this._prepared = false;
-    },
-
-    _compute: function(property) {
-      var COMPUTATIONS = Element.Layout.COMPUTATIONS;
-      if (!(property in COMPUTATIONS)) {
-        throw "Property not found.";
-      }
-
-      return this._set(property, COMPUTATIONS[property].call(this, this.element));
-    },
-
-    toObject: function() {
-      var args = $A(arguments);
-      var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
-       args.join(' ').split(' ');
-      var obj = {};
-      keys.each( function(key) {
-        if (!Element.Layout.PROPERTIES.include(key)) return;
-        var value = this.get(key);
-        if (value != null) obj[key] = value;
-      }, this);
-      return obj;
-    },
-
-    toHash: function() {
-      var obj = this.toObject.apply(this, arguments);
-      return new Hash(obj);
-    },
-
-    toCSS: function() {
-      var args = $A(arguments);
-      var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
-       args.join(' ').split(' ');
-      var css = {};
-
-      keys.each( function(key) {
-        if (!Element.Layout.PROPERTIES.include(key)) return;
-        if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
-
-        var value = this.get(key);
-        if (value != null) css[cssNameFor(key)] = value + 'px';
-      }, this);
-      return css;
-    },
-
-    inspect: function() {
-      return "#<Element.Layout>";
-    }
-  });
-
-  Object.extend(Element.Layout, {
-    PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
-
-    COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
-
-    COMPUTATIONS: {
-      'height': function(element) {
-        if (!this._preComputing) this._begin();
-
-        var bHeight = this.get('border-box-height');
-        if (bHeight <= 0) {
-          if (!this._preComputing) this._end();
-          return 0;
-        }
-
-        var bTop = this.get('border-top'),
-         bBottom = this.get('border-bottom');
-
-        var pTop = this.get('padding-top'),
-         pBottom = this.get('padding-bottom');
-
-        if (!this._preComputing) this._end();
-
-        return bHeight - bTop - bBottom - pTop - pBottom;
-      },
-
-      'width': function(element) {
-        if (!this._preComputing) this._begin();
-
-        var bWidth = this.get('border-box-width');
-        if (bWidth <= 0) {
-          if (!this._preComputing) this._end();
-          return 0;
-        }
-
-        var bLeft = this.get('border-left'),
-         bRight = this.get('border-right');
-
-        var pLeft = this.get('padding-left'),
-         pRight = this.get('padding-right');
-
-        if (!this._preComputing) this._end();
-
-        return bWidth - bLeft - bRight - pLeft - pRight;
-      },
-
-      'padding-box-height': function(element) {
-        var height = this.get('height'),
-         pTop = this.get('padding-top'),
-         pBottom = this.get('padding-bottom');
-
-        return height + pTop + pBottom;
-      },
-
-      'padding-box-width': function(element) {
-        var width = this.get('width'),
-         pLeft = this.get('padding-left'),
-         pRight = this.get('padding-right');
-
-        return width + pLeft + pRight;
-      },
-
-      'border-box-height': function(element) {
-        if (!this._preComputing) this._begin();
-        var height = element.offsetHeight;
-        if (!this._preComputing) this._end();
-        return height;
-      },
-
-      'border-box-width': function(element) {
-        if (!this._preComputing) this._begin();
-        var width = element.offsetWidth;
-        if (!this._preComputing) this._end();
-        return width;
-      },
-
-      'margin-box-height': function(element) {
-        var bHeight = this.get('border-box-height'),
-         mTop = this.get('margin-top'),
-         mBottom = this.get('margin-bottom');
-
-        if (bHeight <= 0) return 0;
-
-        return bHeight + mTop + mBottom;
-      },
-
-      'margin-box-width': function(element) {
-        var bWidth = this.get('border-box-width'),
-         mLeft = this.get('margin-left'),
-         mRight = this.get('margin-right');
-
-        if (bWidth <= 0) return 0;
-
-        return bWidth + mLeft + mRight;
-      },
-
-      'top': function(element) {
-        var offset = element.positionedOffset();
-        return offset.top;
-      },
-
-      'bottom': function(element) {
-        var offset = element.positionedOffset(),
-         parent = element.getOffsetParent(),
-         pHeight = parent.measure('height');
-
-        var mHeight = this.get('border-box-height');
-
-        return pHeight - mHeight - offset.top;
-      },
-
-      'left': function(element) {
-        var offset = element.positionedOffset();
-        return offset.left;
-      },
-
-      'right': function(element) {
-        var offset = element.positionedOffset(),
-         parent = element.getOffsetParent(),
-         pWidth = parent.measure('width');
-
-        var mWidth = this.get('border-box-width');
-
-        return pWidth - mWidth - offset.left;
-      },
-
-      'padding-top': function(element) {
-        return getPixelValue(element, 'paddingTop');
-      },
-
-      'padding-bottom': function(element) {
-        return getPixelValue(element, 'paddingBottom');
-      },
-
-      'padding-left': function(element) {
-        return getPixelValue(element, 'paddingLeft');
-      },
-
-      'padding-right': function(element) {
-        return getPixelValue(element, 'paddingRight');
-      },
-
-      'border-top': function(element) {
-        return getPixelValue(element, 'borderTopWidth');
-      },
-
-      'border-bottom': function(element) {
-        return getPixelValue(element, 'borderBottomWidth');
-      },
-
-      'border-left': function(element) {
-        return getPixelValue(element, 'borderLeftWidth');
-      },
-
-      'border-right': function(element) {
-        return getPixelValue(element, 'borderRightWidth');
-      },
-
-      'margin-top': function(element) {
-        return getPixelValue(element, 'marginTop');
-      },
-
-      'margin-bottom': function(element) {
-        return getPixelValue(element, 'marginBottom');
-      },
-
-      'margin-left': function(element) {
-        return getPixelValue(element, 'marginLeft');
-      },
-
-      'margin-right': function(element) {
-        return getPixelValue(element, 'marginRight');
-      }
-    }
-  });
-
-  if ('getBoundingClientRect' in document.documentElement) {
-    Object.extend(Element.Layout.COMPUTATIONS, {
-      'right': function(element) {
-        var parent = hasLayout(element.getOffsetParent());
-        var rect = element.getBoundingClientRect(),
-         pRect = parent.getBoundingClientRect();
-
-        return (pRect.right - rect.right).round();
-      },
-
-      'bottom': function(element) {
-        var parent = hasLayout(element.getOffsetParent());
-        var rect = element.getBoundingClientRect(),
-         pRect = parent.getBoundingClientRect();
-
-        return (pRect.bottom - rect.bottom).round();
-      }
-    });
-  }
-
-  Element.Offset = Class.create({
-    initialize: function(left, top) {
-      this.left = left.round();
-      this.top  = top.round();
-
-      this[0] = this.left;
-      this[1] = this.top;
-    },
-
-    relativeTo: function(offset) {
-      return new Element.Offset(
-        this.left - offset.left,
-        this.top  - offset.top
-      );
-    },
-
-    inspect: function() {
-      return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
-    },
-
-    toString: function() {
-      return "[#{left}, #{top}]".interpolate(this);
-    },
-
-    toArray: function() {
-      return [this.left, this.top];
-    }
-  });
-
-  function getLayout(element, preCompute) {
-    return new Element.Layout(element, preCompute);
-  }
-
-  function measure(element, property) {
-    return $(element).getLayout().get(property);
-  }
-
-  function getDimensions(element) {
-    element = $(element);
-    var display = Element.getStyle(element, 'display');
-
-    if (display && display !== 'none') {
-      return { width: element.offsetWidth, height: element.offsetHeight };
-    }
-
-    var style = element.style;
-    var originalStyles = {
-      visibility: style.visibility,
-      position:   style.position,
-      display:    style.display
-    };
-
-    var newStyles = {
-      visibility: 'hidden',
-      display:    'block'
-    };
-
-    if (originalStyles.position !== 'fixed')
-      newStyles.position = 'absolute';
-
-    Element.setStyle(element, newStyles);
-
-    var dimensions = {
-      width:  element.offsetWidth,
-      height: element.offsetHeight
-    };
-
-    Element.setStyle(element, originalStyles);
-
-    return dimensions;
-  }
-
-  function getOffsetParent(element) {
-    element = $(element);
-
-    if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
-      return $(document.body);
-
-    var isInline = (Element.getStyle(element, 'display') === 'inline');
-    if (!isInline && element.offsetParent) return $(element.offsetParent);
-
-    while ((element = element.parentNode) && element !== document.body) {
-      if (Element.getStyle(element, 'position') !== 'static') {
-        return isHtml(element) ? $(document.body) : $(element);
-      }
-    }
-
-    return $(document.body);
-  }
-
-
-  function cumulativeOffset(element) {
-    element = $(element);
-    var valueT = 0, valueL = 0;
-    if (element.parentNode) {
-      do {
-        valueT += element.offsetTop  || 0;
-        valueL += element.offsetLeft || 0;
-        element = element.offsetParent;
-      } while (element);
-    }
-    return new Element.Offset(valueL, valueT);
-  }
-
-  function positionedOffset(element) {
-    element = $(element);
-
-    var layout = element.getLayout();
-
-    var valueT = 0, valueL = 0;
-    do {
-      valueT += element.offsetTop  || 0;
-      valueL += element.offsetLeft || 0;
-      element = element.offsetParent;
-      if (element) {
-        if (isBody(element)) break;
-        var p = Element.getStyle(element, 'position');
-        if (p !== 'static') break;
-      }
-    } while (element);
-
-    valueL -= layout.get('margin-top');
-    valueT -= layout.get('margin-left');
-
-    return new Element.Offset(valueL, valueT);
-  }
-
-  function cumulativeScrollOffset(element) {
-    var valueT = 0, valueL = 0;
-    do {
-      valueT += element.scrollTop  || 0;
-      valueL += element.scrollLeft || 0;
-      element = element.parentNode;
-    } while (element);
-    return new Element.Offset(valueL, valueT);
-  }
-
-  function viewportOffset(forElement) {
-    element = $(element);
-    var valueT = 0, valueL = 0, docBody = document.body;
-
-    var element = forElement;
-    do {
-      valueT += element.offsetTop  || 0;
-      valueL += element.offsetLeft || 0;
-      if (element.offsetParent == docBody &&
-        Element.getStyle(element, 'position') == 'absolute') break;
-    } while (element = element.offsetParent);
-
-    element = forElement;
-    do {
-      if (element != docBody) {
-        valueT -= element.scrollTop  || 0;
-        valueL -= element.scrollLeft || 0;
-      }
-    } while (element = element.parentNode);
-    return new Element.Offset(valueL, valueT);
-  }
-
-  function absolutize(element) {
-    element = $(element);
-
-    if (Element.getStyle(element, 'position') === 'absolute') {
-      return element;
-    }
-
-    var offsetParent = getOffsetParent(element);
-    var eOffset = element.viewportOffset(),
-     pOffset = offsetParent.viewportOffset();
-
-    var offset = eOffset.relativeTo(pOffset);
-    var layout = element.getLayout();
-
-    element.store('prototype_absolutize_original_styles', {
-      left:   element.getStyle('left'),
-      top:    element.getStyle('top'),
-      width:  element.getStyle('width'),
-      height: element.getStyle('height')
-    });
-
-    element.setStyle({
-      position: 'absolute',
-      top:    offset.top + 'px',
-      left:   offset.left + 'px',
-      width:  layout.get('width') + 'px',
-      height: layout.get('height') + 'px'
-    });
-
-    return element;
-  }
-
-  function relativize(element) {
-    element = $(element);
-    if (Element.getStyle(element, 'position') === 'relative') {
-      return element;
-    }
-
-    var originalStyles =
-     element.retrieve('prototype_absolutize_original_styles');
-
-    if (originalStyles) element.setStyle(originalStyles);
-    return element;
-  }
-
-  if (Prototype.Browser.IE) {
-    getOffsetParent = getOffsetParent.wrap(
-      function(proceed, element) {
-        element = $(element);
-
-        if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
-          return $(document.body);
-
-        var position = element.getStyle('position');
-        if (position !== 'static') return proceed(element);
-
-        element.setStyle({ position: 'relative' });
-        var value = proceed(element);
-        element.setStyle({ position: position });
-        return value;
-      }
-    );
-
-    positionedOffset = positionedOffset.wrap(function(proceed, element) {
-      element = $(element);
-      if (!element.parentNode) return new Element.Offset(0, 0);
-      var position = element.getStyle('position');
-      if (position !== 'static') return proceed(element);
-
-      var offsetParent = element.getOffsetParent();
-      if (offsetParent && offsetParent.getStyle('position') === 'fixed')
-        hasLayout(offsetParent);
-
-      element.setStyle({ position: 'relative' });
-      var value = proceed(element);
-      element.setStyle({ position: position });
-      return value;
-    });
-  } else if (Prototype.Browser.Webkit) {
-    cumulativeOffset = function(element) {
-      element = $(element);
-      var valueT = 0, valueL = 0;
-      do {
-        valueT += element.offsetTop  || 0;
-        valueL += element.offsetLeft || 0;
-        if (element.offsetParent == document.body)
-          if (Element.getStyle(element, 'position') == 'absolute') break;
-
-        element = element.offsetParent;
-      } while (element);
-
-      return new Element.Offset(valueL, valueT);
-    };
-  }
-
-
-  Element.addMethods({
-    getLayout:              getLayout,
-    measure:                measure,
-    getDimensions:          getDimensions,
-    getOffsetParent:        getOffsetParent,
-    cumulativeOffset:       cumulativeOffset,
-    positionedOffset:       positionedOffset,
-    cumulativeScrollOffset: cumulativeScrollOffset,
-    viewportOffset:         viewportOffset,
-    absolutize:             absolutize,
-    relativize:             relativize
-  });
-
-  function isBody(element) {
-    return element.nodeName.toUpperCase() === 'BODY';
-  }
-
-  function isHtml(element) {
-    return element.nodeName.toUpperCase() === 'HTML';
-  }
-
-  function isDocument(element) {
-    return element.nodeType === Node.DOCUMENT_NODE;
-  }
-
-  function isDetached(element) {
-    return element !== document.body &&
-     !Element.descendantOf(element, document.body);
-  }
-
-  if ('getBoundingClientRect' in document.documentElement) {
-    Element.addMethods({
-      viewportOffset: function(element) {
-        element = $(element);
-        if (isDetached(element)) return new Element.Offset(0, 0);
-
-        var rect = element.getBoundingClientRect(),
-         docEl = document.documentElement;
-        return new Element.Offset(rect.left - docEl.clientLeft,
-         rect.top - docEl.clientTop);
-      }
-    });
-  }
-})();
-window.$$ = function() {
-  var expression = $A(arguments).join(', ');
-  return Prototype.Selector.select(expression, document);
-};
-
-Prototype.Selector = (function() {
-
-  function select() {
-    throw new Error('Method "Prototype.Selector.select" must be defined.');
-  }
-
-  function match() {
-    throw new Error('Method "Prototype.Selector.match" must be defined.');
-  }
-
-  function find(elements, expression, index) {
-    index = index || 0;
-    var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
-
-    for (i = 0; i < length; i++) {
-      if (match(elements[i], expression) && index == matchIndex++) {
-        return Element.extend(elements[i]);
-      }
-    }
-  }
-
-  function extendElements(elements) {
-    for (var i = 0, length = elements.length; i < length; i++) {
-      Element.extend(elements[i]);
-    }
-    return elements;
-  }
-
-
-  var K = Prototype.K;
-
-  return {
-    select: select,
-    match: match,
-    find: find,
-    extendElements: (Element.extend === K) ? K : extendElements,
-    extendElement: Element.extend
-  };
-})();
-Prototype._original_property = window.Sizzle;
-/*!
- * Sizzle CSS Selector Engine - v1.0
- *  Copyright 2009, The Dojo Foundation
- *  Released under the MIT, BSD, and GPL Licenses.
- *  More information: http://sizzlejs.com/
- */
-(function(){
-
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
-  done = 0,
-  toString = Object.prototype.toString,
-  hasDuplicate = false,
-  baseHasDuplicate = true;
-
-[0, 0].sort(function(){
-  baseHasDuplicate = false;
-  return 0;
-});
-
-var Sizzle = function(selector, context, results, seed) {
-  results = results || [];
-  var origContext = context = context || document;
-
-  if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
-    return [];
-  }
-
-  if ( !selector || typeof selector !== "string" ) {
-    return results;
-  }
-
-  var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
-    soFar = selector;
-
-  while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
-    soFar = m[3];
-
-    parts.push( m[1] );
-
-    if ( m[2] ) {
-      extra = m[3];
-      break;
-    }
-  }
-
-  if ( parts.length > 1 && origPOS.exec( selector ) ) {
-    if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
-      set = posProcess( parts[0] + parts[1], context );
-    } else {
-      set = Expr.relative[ parts[0] ] ?
-        [ context ] :
-        Sizzle( parts.shift(), context );
-
-      while ( parts.length ) {
-        selector = parts.shift();
-
-        if ( Expr.relative[ selector ] )
-          selector += parts.shift();
-
-        set = posProcess( selector, set );
-      }
-    }
-  } else {
-    if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
-        Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
-      var ret = Sizzle.find( parts.shift(), context, contextXML );
-      context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
-    }
-
-    if ( context ) {
-      var ret = seed ?
-        { expr: parts.pop(), set: makeArray(seed) } :
-        Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
-      set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
-
-      if ( parts.length > 0 ) {
-        checkSet = makeArray(set);
-      } else {
-        prune = false;
-      }
-
-      while ( parts.length ) {
-        var cur = parts.pop(), pop = cur;
-
-        if ( !Expr.relative[ cur ] ) {
-          cur = "";
-        } else {
-          pop = parts.pop();
-        }
-
-        if ( pop == null ) {
-          pop = context;
-        }
-
-        Expr.relative[ cur ]( checkSet, pop, contextXML );
-      }
-    } else {
-      checkSet = parts = [];
-    }
-  }
-
-  if ( !checkSet ) {
-    checkSet = set;
-  }
-
-  if ( !checkSet ) {
-    throw "Syntax error, unrecognized expression: " + (cur || selector);
-  }
-
-  if ( toString.call(checkSet) === "[object Array]" ) {
-    if ( !prune ) {
-      results.push.apply( results, checkSet );
-    } else if ( context && context.nodeType === 1 ) {
-      for ( var i = 0; checkSet[i] != null; i++ ) {
-        if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
-          results.push( set[i] );
-        }
-      }
-    } else {
-      for ( var i = 0; checkSet[i] != null; i++ ) {
-        if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
-          results.push( set[i] );
-        }
-      }
-    }
-  } else {
-    makeArray( checkSet, results );
-  }
-
-  if ( extra ) {
-    Sizzle( extra, origContext, results, seed );
-    Sizzle.uniqueSort( results );
-  }
-
-  return results;
-};
-
-Sizzle.uniqueSort = function(results){
-  if ( sortOrder ) {
-    hasDuplicate = baseHasDuplicate;
-    results.sort(sortOrder);
-
-    if ( hasDuplicate ) {
-      for ( var i = 1; i < results.length; i++ ) {
-        if ( results[i] === results[i-1] ) {
-          results.splice(i--, 1);
-        }
-      }
-    }
-  }
-
-  return results;
-};
-
-Sizzle.matches = function(expr, set){
-  return Sizzle(expr, null, null, set);
-};
-
-Sizzle.find = function(expr, context, isXML){
-  var set, match;
-
-  if ( !expr ) {
-    return [];
-  }
-
-  for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
-    var type = Expr.order[i], match;
-
-    if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
-      var left = match[1];
-      match.splice(1,1);
-
-      if ( left.substr( left.length - 1 ) !== "\\" ) {
-        match[1] = (match[1] || "").replace(/\\/g, "");
-        set = Expr.find[ type ]( match, context, isXML );
-        if ( set != null ) {
-          expr = expr.replace( Expr.match[ type ], "" );
-          break;
-        }
-      }
-    }
-  }
-
-  if ( !set ) {
-    set = context.getElementsByTagName("*");
-  }
-
-  return {set: set, expr: expr};
-};
-
-Sizzle.filter = function(expr, set, inplace, not){
-  var old = expr, result = [], curLoop = set, match, anyFound,
-    isXMLFilter = set && set[0] && isXML(set[0]);
-
-  while ( expr && set.length ) {
-    for ( var type in Expr.filter ) {
-      if ( (match = Expr.match[ type ].exec( expr )) != null ) {
-        var filter = Expr.filter[ type ], found, item;
-        anyFound = false;
-
-        if ( curLoop == result ) {
-          result = [];
-        }
-
-        if ( Expr.preFilter[ type ] ) {
-          match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
-
-          if ( !match ) {
-            anyFound = found = true;
-          } else if ( match === true ) {
-            continue;
-          }
-        }
-
-        if ( match ) {
-          for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
-            if ( item ) {
-              found = filter( item, match, i, curLoop );
-              var pass = not ^ !!found;
-
-              if ( inplace && found != null ) {
-                if ( pass ) {
-                  anyFound = true;
-                } else {
-                  curLoop[i] = false;
-                }
-              } else if ( pass ) {
-                result.push( item );
-                anyFound = true;
-              }
-            }
-          }
-        }
-
-        if ( found !== undefined ) {
-          if ( !inplace ) {
-            curLoop = result;
-          }
-
-          expr = expr.replace( Expr.match[ type ], "" );
-
-          if ( !anyFound ) {
-            return [];
-          }
-
-          break;
-        }
-      }
-    }
-
-    if ( expr == old ) {
-      if ( anyFound == null ) {
-        throw "Syntax error, unrecognized expression: " + expr;
-      } else {
-        break;
-      }
-    }
-
-    old = expr;
-  }
-
-  return curLoop;
-};
-
-var Expr = Sizzle.selectors = {
-  order: [ "ID", "NAME", "TAG" ],
-  match: {
-    ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
-    CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
-    NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
-    ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
-    TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
-    CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
-    POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
-    PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
-  },
-  leftMatch: {},
-  attrMap: {
-    "class": "className",
-    "for": "htmlFor"
-  },
-  attrHandle: {
-    href: function(elem){
-      return elem.getAttribute("href");
-    }
-  },
-  relative: {
-    "+": function(checkSet, part, isXML){
-      var isPartStr = typeof part === "string",
-        isTag = isPartStr && !/\W/.test(part),
-        isPartStrNotTag = isPartStr && !isTag;
-
-      if ( isTag && !isXML ) {
-        part = part.toUpperCase();
-      }
-
-      for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
-        if ( (elem = checkSet[i]) ) {
-          while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
-
-          checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
-            elem || false :
-            elem === part;
-        }
-      }
-
-      if ( isPartStrNotTag ) {
-        Sizzle.filter( part, checkSet, true );
-      }
-    },
-    ">": function(checkSet, part, isXML){
-      var isPartStr = typeof part === "string";
-
-      if ( isPartStr && !/\W/.test(part) ) {
-        part = isXML ? part : part.toUpperCase();
-
-        for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-          var elem = checkSet[i];
-          if ( elem ) {
-            var parent = elem.parentNode;
-            checkSet[i] = parent.nodeName === part ? parent : false;
-          }
-        }
-      } else {
-        for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-          var elem = checkSet[i];
-          if ( elem ) {
-            checkSet[i] = isPartStr ?
-              elem.parentNode :
-              elem.parentNode === part;
-          }
-        }
-
-        if ( isPartStr ) {
-          Sizzle.filter( part, checkSet, true );
-        }
-      }
-    },
-    "": function(checkSet, part, isXML){
-      var doneName = done++, checkFn = dirCheck;
-
-      if ( !/\W/.test(part) ) {
-        var nodeCheck = part = isXML ? part : part.toUpperCase();
-        checkFn = dirNodeCheck;
-      }
-
-      checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
-    },
-    "~": function(checkSet, part, isXML){
-      var doneName = done++, checkFn = dirCheck;
-
-      if ( typeof part === "string" && !/\W/.test(part) ) {
-        var nodeCheck = part = isXML ? part : part.toUpperCase();
-        checkFn = dirNodeCheck;
-      }
-
-      checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
-    }
-  },
-  find: {
-    ID: function(match, context, isXML){
-      if ( typeof context.getElementById !== "undefined" && !isXML ) {
-        var m = context.getElementById(match[1]);
-        return m ? [m] : [];
-      }
-    },
-    NAME: function(match, context, isXML){
-      if ( typeof context.getElementsByName !== "undefined" ) {
-        var ret = [], results = context.getElementsByName(match[1]);
-
-        for ( var i = 0, l = results.length; i < l; i++ ) {
-          if ( results[i].getAttribute("name") === match[1] ) {
-            ret.push( results[i] );
-          }
-        }
-
-        return ret.length === 0 ? null : ret;
-      }
-    },
-    TAG: function(match, context){
-      return context.getElementsByTagName(match[1]);
-    }
-  },
-  preFilter: {
-    CLASS: function(match, curLoop, inplace, result, not, isXML){
-      match = " " + match[1].replace(/\\/g, "") + " ";
-
-      if ( isXML ) {
-        return match;
-      }
-
-      for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
-        if ( elem ) {
-          if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
-            if ( !inplace )
-              result.push( elem );
-          } else if ( inplace ) {
-            curLoop[i] = false;
-          }
-        }
-      }
-
-      return false;
-    },
-    ID: function(match){
-      return match[1].replace(/\\/g, "");
-    },
-    TAG: function(match, curLoop){
-      for ( var i = 0; curLoop[i] === false; i++ ){}
-      return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
-    },
-    CHILD: function(match){
-      if ( match[1] == "nth" ) {
-        var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
-          match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
-          !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
-
-        match[2] = (test[1] + (test[2] || 1)) - 0;
-        match[3] = test[3] - 0;
-      }
-
-      match[0] = done++;
-
-      return match;
-    },
-    ATTR: function(match, curLoop, inplace, result, not, isXML){
-      var name = match[1].replace(/\\/g, "");
-
-      if ( !isXML && Expr.attrMap[name] ) {
-        match[1] = Expr.attrMap[name];
-      }
-
-      if ( match[2] === "~=" ) {
-        match[4] = " " + match[4] + " ";
-      }
-
-      return match;
-    },
-    PSEUDO: function(match, curLoop, inplace, result, not){
-      if ( match[1] === "not" ) {
-        if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
-          match[3] = Sizzle(match[3], null, null, curLoop);
-        } else {
-          var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
-          if ( !inplace ) {
-            result.push.apply( result, ret );
-          }
-          return false;
-        }
-      } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
-        return true;
-      }
-
-      return match;
-    },
-    POS: function(match){
-      match.unshift( true );
-      return match;
-    }
-  },
-  filters: {
-    enabled: function(elem){
-      return elem.disabled === false && elem.type !== "hidden";
-    },
-    disabled: function(elem){
-      return elem.disabled === true;
-    },
-    checked: function(elem){
-      return elem.checked === true;
-    },
-    selected: function(elem){
-      elem.parentNode.selectedIndex;
-      return elem.selected === true;
-    },
-    parent: function(elem){
-      return !!elem.firstChild;
-    },
-    empty: function(elem){
-      return !elem.firstChild;
-    },
-    has: function(elem, i, match){
-      return !!Sizzle( match[3], elem ).length;
-    },
-    header: function(elem){
-      return /h\d/i.test( elem.nodeName );
-    },
-    text: function(elem){
-      return "text" === elem.type;
-    },
-    radio: function(elem){
-      return "radio" === elem.type;
-    },
-    checkbox: function(elem){
-      return "checkbox" === elem.type;
-    },
-    file: function(elem){
-      return "file" === elem.type;
-    },
-    password: function(elem){
-      return "password" === elem.type;
-    },
-    submit: function(elem){
-      return "submit" === elem.type;
-    },
-    image: function(elem){
-      return "image" === elem.type;
-    },
-    reset: function(elem){
-      return "reset" === elem.type;
-    },
-    button: function(elem){
-      return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
-    },
-    input: function(elem){
-      return /input|select|textarea|button/i.test(elem.nodeName);
-    }
-  },
-  setFilters: {
-    first: function(elem, i){
-      return i === 0;
-    },
-    last: function(elem, i, match, array){
-      return i === array.length - 1;
-    },
-    even: function(elem, i){
-      return i % 2 === 0;
-    },
-    odd: function(elem, i){
-      return i % 2 === 1;
-    },
-    lt: function(elem, i, match){
-      return i < match[3] - 0;
-    },
-    gt: function(elem, i, match){
-      return i > match[3] - 0;
-    },
-    nth: function(elem, i, match){
-      return match[3] - 0 == i;
-    },
-    eq: function(elem, i, match){
-      return match[3] - 0 == i;
-    }
-  },
-  filter: {
-    PSEUDO: function(elem, match, i, array){
-      var name = match[1], filter = Expr.filters[ name ];
-
-      if ( filter ) {
-        return filter( elem, i, match, array );
-      } else if ( name === "contains" ) {
-        return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
-      } else if ( name === "not" ) {
-        var not = match[3];
-
-        for ( var i = 0, l = not.length; i < l; i++ ) {
-          if ( not[i] === elem ) {
-            return false;
-          }
-        }
-
-        return true;
-      }
-    },
-    CHILD: function(elem, match){
-      var type = match[1], node = elem;
-      switch (type) {
-        case 'only':
-        case 'first':
-          while ( (node = node.previousSibling) )  {
-            if ( node.nodeType === 1 ) return false;
-          }
-          if ( type == 'first') return true;
-          node = elem;
-        case 'last':
-          while ( (node = node.nextSibling) )  {
-            if ( node.nodeType === 1 ) return false;
-          }
-          return true;
-        case 'nth':
-          var first = match[2], last = match[3];
-
-          if ( first == 1 && last == 0 ) {
-            return true;
-          }
-
-          var doneName = match[0],
-            parent = elem.parentNode;
-
-          if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
-            var count = 0;
-            for ( node = parent.firstChild; node; node = node.nextSibling ) {
-              if ( node.nodeType === 1 ) {
-                node.nodeIndex = ++count;
-              }
-            }
-            parent.sizcache = doneName;
-          }
-
-          var diff = elem.nodeIndex - last;
-          if ( first == 0 ) {
-            return diff == 0;
-          } else {
-            return ( diff % first == 0 && diff / first >= 0 );
-          }
-      }
-    },
-    ID: function(elem, match){
-      return elem.nodeType === 1 && elem.getAttribute("id") === match;
-    },
-    TAG: function(elem, match){
-      return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
-    },
-    CLASS: function(elem, match){
-      return (" " + (elem.className || elem.getAttribute("class")) + " ")
-        .indexOf( match ) > -1;
-    },
-    ATTR: function(elem, match){
-      var name = match[1],
-        result = Expr.attrHandle[ name ] ?
-          Expr.attrHandle[ name ]( elem ) :
-          elem[ name ] != null ?
-            elem[ name ] :
-            elem.getAttribute( name ),
-        value = result + "",
-        type = match[2],
-        check = match[4];
-
-      return result == null ?
-        type === "!=" :
-        type === "=" ?
-        value === check :
-        type === "*=" ?
-        value.indexOf(check) >= 0 :
-        type === "~=" ?
-        (" " + value + " ").indexOf(check) >= 0 :
-        !check ?
-        value && result !== false :
-        type === "!=" ?
-        value != check :
-        type === "^=" ?
-        value.indexOf(check) === 0 :
-        type === "$=" ?
-        value.substr(value.length - check.length) === check :
-        type === "|=" ?
-        value === check || value.substr(0, check.length + 1) === check + "-" :
-        false;
-    },
-    POS: function(elem, match, i, array){
-      var name = match[2], filter = Expr.setFilters[ name ];
-
-      if ( filter ) {
-        return filter( elem, i, match, array );
-      }
-    }
-  }
-};
-
-var origPOS = Expr.match.POS;
-
-for ( var type in Expr.match ) {
-  Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
-  Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
-}
-
-var makeArray = function(array, results) {
-  array = Array.prototype.slice.call( array, 0 );
-
-  if ( results ) {
-    results.push.apply( results, array );
-    return results;
-  }
-
-  return array;
-};
-
-try {
-  Array.prototype.slice.call( document.documentElement.childNodes, 0 );
-
-} catch(e){
-  makeArray = function(array, results) {
-    var ret = results || [];
-
-    if ( toString.call(array) === "[object Array]" ) {
-      Array.prototype.push.apply( ret, array );
-    } else {
-      if ( typeof array.length === "number" ) {
-        for ( var i = 0, l = array.length; i < l; i++ ) {
-          ret.push( array[i] );
-        }
-      } else {
-        for ( var i = 0; array[i]; i++ ) {
-          ret.push( array[i] );
-        }
-      }
-    }
-
-    return ret;
-  };
-}
-
-var sortOrder;
-
-if ( document.documentElement.compareDocumentPosition ) {
-  sortOrder = function( a, b ) {
-    if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
-      if ( a == b ) {
-        hasDuplicate = true;
-      }
-      return 0;
-    }
-
-    var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
-    if ( ret === 0 ) {
-      hasDuplicate = true;
-    }
-    return ret;
-  };
-} else if ( "sourceIndex" in document.documentElement ) {
-  sortOrder = function( a, b ) {
-    if ( !a.sourceIndex || !b.sourceIndex ) {
-      if ( a == b ) {
-        hasDuplicate = true;
-      }
-      return 0;
-    }
-
-    var ret = a.sourceIndex - b.sourceIndex;
-    if ( ret === 0 ) {
-      hasDuplicate = true;
-    }
-    return ret;
-  };
-} else if ( document.createRange ) {
-  sortOrder = function( a, b ) {
-    if ( !a.ownerDocument || !b.ownerDocument ) {
-      if ( a == b ) {
-        hasDuplicate = true;
-      }
-      return 0;
-    }
-
-    var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
-    aRange.setStart(a, 0);
-    aRange.setEnd(a, 0);
-    bRange.setStart(b, 0);
-    bRange.setEnd(b, 0);
-    var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
-    if ( ret === 0 ) {
-      hasDuplicate = true;
-    }
-    return ret;
-  };
-}
-
-(function(){
-  var form = document.createElement("div"),
-    id = "script" + (new Date).getTime();
-  form.innerHTML = "<a name='" + id + "'/>";
-
-  var root = document.documentElement;
-  root.insertBefore( form, root.firstChild );
-
-  if ( !!document.getElementById( id ) ) {
-    Expr.find.ID = function(match, context, isXML){
-      if ( typeof context.getElementById !== "undefined" && !isXML ) {
-        var m = context.getElementById(match[1]);
-        return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
-      }
-    };
-
-    Expr.filter.ID = function(elem, match){
-      var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
-      return elem.nodeType === 1 && node && node.nodeValue === match;
-    };
-  }
-
-  root.removeChild( form );
-  root = form = null; // release memory in IE
-})();
-
-(function(){
-
-  var div = document.createElement("div");
-  div.appendChild( document.createComment("") );
-
-  if ( div.getElementsByTagName("*").length > 0 ) {
-    Expr.find.TAG = function(match, context){
-      var results = context.getElementsByTagName(match[1]);
-
-      if ( match[1] === "*" ) {
-        var tmp = [];
-
-        for ( var i = 0; results[i]; i++ ) {
-          if ( results[i].nodeType === 1 ) {
-            tmp.push( results[i] );
-          }
-        }
-
-        results = tmp;
-      }
-
-      return results;
-    };
-  }
-
-  div.innerHTML = "<a href='#'></a>";
-  if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
-      div.firstChild.getAttribute("href") !== "#" ) {
-    Expr.attrHandle.href = function(elem){
-      return elem.getAttribute("href", 2);
-    };
-  }
-
-  div = null; // release memory in IE
-})();
-
-if ( document.querySelectorAll ) (function(){
-  var oldSizzle = Sizzle, div = document.createElement("div");
-  div.innerHTML = "<p class='TEST'></p>";
-
-  if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
-    return;
-  }
-
-  Sizzle = function(query, context, extra, seed){
-    context = context || document;
-
-    if ( !seed && context.nodeType === 9 && !isXML(context) ) {
-      try {
-        return makeArray( context.querySelectorAll(query), extra );
-      } catch(e){}
-    }
-
-    return oldSizzle(query, context, extra, seed);
-  };
-
-  for ( var prop in oldSizzle ) {
-    Sizzle[ prop ] = oldSizzle[ prop ];
-  }
-
-  div = null; // release memory in IE
-})();
-
-if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
-  var div = document.createElement("div");
-  div.innerHTML = "<div class='test e'></div><div class='test'></div>";
-
-  if ( div.getElementsByClassName("e").length === 0 )
-    return;
-
-  div.lastChild.className = "e";
-
-  if ( div.getElementsByClassName("e").length === 1 )
-    return;
-
-  Expr.order.splice(1, 0, "CLASS");
-  Expr.find.CLASS = function(match, context, isXML) {
-    if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
-      return context.getElementsByClassName(match[1]);
-    }
-  };
-
-  div = null; // release memory in IE
-})();
-
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
-  var sibDir = dir == "previousSibling" && !isXML;
-  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-    var elem = checkSet[i];
-    if ( elem ) {
-      if ( sibDir && elem.nodeType === 1 ){
-        elem.sizcache = doneName;
-        elem.sizset = i;
-      }
-      elem = elem[dir];
-      var match = false;
-
-      while ( elem ) {
-        if ( elem.sizcache === doneName ) {
-          match = checkSet[elem.sizset];
-          break;
-        }
-
-        if ( elem.nodeType === 1 && !isXML ){
-          elem.sizcache = doneName;
-          elem.sizset = i;
-        }
-
-        if ( elem.nodeName === cur ) {
-          match = elem;
-          break;
-        }
-
-        elem = elem[dir];
-      }
-
-      checkSet[i] = match;
-    }
-  }
-}
-
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
-  var sibDir = dir == "previousSibling" && !isXML;
-  for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-    var elem = checkSet[i];
-    if ( elem ) {
-      if ( sibDir && elem.nodeType === 1 ) {
-        elem.sizcache = doneName;
-        elem.sizset = i;
-      }
-      elem = elem[dir];
-      var match = false;
-
-      while ( elem ) {
-        if ( elem.sizcache === doneName ) {
-          match = checkSet[elem.sizset];
-          break;
-        }
-
-        if ( elem.nodeType === 1 ) {
-          if ( !isXML ) {
-            elem.sizcache = doneName;
-            elem.sizset = i;
-          }
-          if ( typeof cur !== "string" ) {
-            if ( elem === cur ) {
-              match = true;
-              break;
-            }
-
-          } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
-            match = elem;
-            break;
-          }
-        }
-
-        elem = elem[dir];
-      }
-
-      checkSet[i] = match;
-    }
-  }
-}
-
-var contains = document.compareDocumentPosition ?  function(a, b){
-  return a.compareDocumentPosition(b) & 16;
-} : function(a, b){
-  return a !== b && (a.contains ? a.contains(b) : true);
-};
-
-var isXML = function(elem){
-  return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
-    !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
-};
-
-var posProcess = function(selector, context){
-  var tmpSet = [], later = "", match,
-    root = context.nodeType ? [context] : context;
-
-  while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
-    later += match[0];
-    selector = selector.replace( Expr.match.PSEUDO, "" );
-  }
-
-  selector = Expr.relative[selector] ? selector + "*" : selector;
-
-  for ( var i = 0, l = root.length; i < l; i++ ) {
-    Sizzle( selector, root[i], tmpSet );
-  }
-
-  return Sizzle.filter( later, tmpSet );
-};
-
-
-window.Sizzle = Sizzle;
-
-})();
-
-;(function(engine) {
-  var extendElements = Prototype.Selector.extendElements;
-
-  function select(selector, scope) {
-    return extendElements(engine(selector, scope || document));
-  }
-
-  function match(element, selector) {
-    return engine.matches(selector, [element]).length == 1;
-  }
-
-  Prototype.Selector.engine = engine;
-  Prototype.Selector.select = select;
-  Prototype.Selector.match = match;
-})(Sizzle);
-
-window.Sizzle = Prototype._original_property;
-delete Prototype._original_property;
-
-var Form = {
-  reset: function(form) {
-    form = $(form);
-    form.reset();
-    return form;
-  },
-
-  serializeElements: function(elements, options) {
-    if (typeof options != 'object') options = { hash: !!options };
-    else if (Object.isUndefined(options.hash)) options.hash = true;
-    var key, value, submitted = false, submit = options.submit, accumulator, initial;
-
-    if (options.hash) {
-      initial = {};
-      accumulator = function(result, key, value) {
-        if (key in result) {
-          if (!Object.isArray(result[key])) result[key] = [result[key]];
-          result[key].push(value);
-        } else result[key] = value;
-        return result;
-      };
-    } else {
-      initial = '';
-      accumulator = function(result, key, value) {
-        return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value);
-      }
-    }
-
-    return elements.inject(initial, function(result, element) {
-      if (!element.disabled && element.name) {
-        key = element.name; value = $(element).getValue();
-        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
-            submit !== false && (!submit || key == submit) && (submitted = true)))) {
-          result = accumulator(result, key, value);
-        }
-      }
-      return result;
-    });
-  }
-};
-
-Form.Methods = {
-  serialize: function(form, options) {
-    return Form.serializeElements(Form.getElements(form), options);
-  },
-
-  getElements: function(form) {
-    var elements = $(form).getElementsByTagName('*'),
-        element,
-        arr = [ ],
-        serializers = Form.Element.Serializers;
-    for (var i = 0; element = elements[i]; i++) {
-      arr.push(element);
-    }
-    return arr.inject([], function(elements, child) {
-      if (serializers[child.tagName.toLowerCase()])
-        elements.push(Element.extend(child));
-      return elements;
-    })
-  },
-
-  getInputs: function(form, typeName, name) {
-    form = $(form);
-    var inputs = form.getElementsByTagName('input');
-
-    if (!typeName && !name) return $A(inputs).map(Element.extend);
-
-    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
-      var input = inputs[i];
-      if ((typeName && input.type != typeName) || (name && input.name != name))
-        continue;
-      matchingInputs.push(Element.extend(input));
-    }
-
-    return matchingInputs;
-  },
-
-  disable: function(form) {
-    form = $(form);
-    Form.getElements(form).invoke('disable');
-    return form;
-  },
-
-  enable: function(form) {
-    form = $(form);
-    Form.getElements(form).invoke('enable');
-    return form;
-  },
-
-  findFirstElement: function(form) {
-    var elements = $(form).getElements().findAll(function(element) {
-      return 'hidden' != element.type && !element.disabled;
-    });
-    var firstByIndex = elements.findAll(function(element) {
-      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
-    }).sortBy(function(element) { return element.tabIndex }).first();
-
-    return firstByIndex ? firstByIndex : elements.find(function(element) {
-      return /^(?:input|select|textarea)$/i.test(element.tagName);
-    });
-  },
-
-  focusFirstElement: function(form) {
-    form = $(form);
-    var element = form.findFirstElement();
-    if (element) element.activate();
-    return form;
-  },
-
-  request: function(form, options) {
-    form = $(form), options = Object.clone(options || { });
-
-    var params = options.parameters, action = form.readAttribute('action') || '';
-    if (action.blank()) action = window.location.href;
-    options.parameters = form.serialize(true);
-
-    if (params) {
-      if (Object.isString(params)) params = params.toQueryParams();
-      Object.extend(options.parameters, params);
-    }
-
-    if (form.hasAttribute('method') && !options.method)
-      options.method = form.method;
-
-    return new Ajax.Request(action, options);
-  }
-};
-
-/*--------------------------------------------------------------------------*/
-
-
-Form.Element = {
-  focus: function(element) {
-    $(element).focus();
-    return element;
-  },
-
-  select: function(element) {
-    $(element).select();
-    return element;
-  }
-};
-
-Form.Element.Methods = {
-
-  serialize: function(element) {
-    element = $(element);
-    if (!element.disabled && element.name) {
-      var value = element.getValue();
-      if (value != undefined) {
-        var pair = { };
-        pair[element.name] = value;
-        return Object.toQueryString(pair);
-      }
-    }
-    return '';
-  },
-
-  getValue: function(element) {
-    element = $(element);
-    var method = element.tagName.toLowerCase();
-    return Form.Element.Serializers[method](element);
-  },
-
-  setValue: function(element, value) {
-    element = $(element);
-    var method = element.tagName.toLowerCase();
-    Form.Element.Serializers[method](element, value);
-    return element;
-  },
-
-  clear: function(element) {
-    $(element).value = '';
-    return element;
-  },
-
-  present: function(element) {
-    return $(element).value != '';
-  },
-
-  activate: function(element) {
-    element = $(element);
-    try {
-      element.focus();
-      if (element.select && (element.tagName.toLowerCase() != 'input' ||
-          !(/^(?:button|reset|submit)$/i.test(element.type))))
-        element.select();
-    } catch (e) { }
-    return element;
-  },
-
-  disable: function(element) {
-    element = $(element);
-    element.disabled = true;
-    return element;
-  },
-
-  enable: function(element) {
-    element = $(element);
-    element.disabled = false;
-    return element;
-  }
-};
-
-/*--------------------------------------------------------------------------*/
-
-var Field = Form.Element;
-
-var $F = Form.Element.Methods.getValue;
-
-/*--------------------------------------------------------------------------*/
-
-Form.Element.Serializers = (function() {
-  function input(element, value) {
-    switch (element.type.toLowerCase()) {
-      case 'checkbox':
-      case 'radio':
-        return inputSelector(element, value);
-      default:
-        return valueSelector(element, value);
-    }
-  }
-
-  function inputSelector(element, value) {
-    if (Object.isUndefined(value))
-      return element.checked ? element.value : null;
-    else element.checked = !!value;
-  }
-
-  function valueSelector(element, value) {
-    if (Object.isUndefined(value)) return element.value;
-    else element.value = value;
-  }
-
-  function select(element, value) {
-    if (Object.isUndefined(value))
-      return (element.type === 'select-one' ? selectOne : selectMany)(element);
-
-    var opt, currentValue, single = !Object.isArray(value);
-    for (var i = 0, length = element.length; i < length; i++) {
-      opt = element.options[i];
-      currentValue = this.optionValue(opt);
-      if (single) {
-        if (currentValue == value) {
-          opt.selected = true;
-          return;
-        }
-      }
-      else opt.selected = value.include(currentValue);
-    }
-  }
-
-  function selectOne(element) {
-    var index = element.selectedIndex;
-    return index >= 0 ? optionValue(element.options[index]) : null;
-  }
-
-  function selectMany(element) {
-    var values, length = element.length;
-    if (!length) return null;
-
-    for (var i = 0, values = []; i < length; i++) {
-      var opt = element.options[i];
-      if (opt.selected) values.push(optionValue(opt));
-    }
-    return values;
-  }
-
-  function optionValue(opt) {
-    return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
-  }
-
-  return {
-    input:         input,
-    inputSelector: inputSelector,
-    textarea:      valueSelector,
-    select:        select,
-    selectOne:     selectOne,
-    selectMany:    selectMany,
-    optionValue:   optionValue,
-    button:        valueSelector
-  };
-})();
-
-/*--------------------------------------------------------------------------*/
-
-
-Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
-  initialize: function($super, element, frequency, callback) {
-    $super(callback, frequency);
-    this.element   = $(element);
-    this.lastValue = this.getValue();
-  },
-
-  execute: function() {
-    var value = this.getValue();
-    if (Object.isString(this.lastValue) && Object.isString(value) ?
-        this.lastValue != value : String(this.lastValue) != String(value)) {
-      this.callback(this.element, value);
-      this.lastValue = value;
-    }
-  }
-});
-
-Form.Element.Observer = Class.create(Abstract.TimedObserver, {
-  getValue: function() {
-    return Form.Element.getValue(this.element);
-  }
-});
-
-Form.Observer = Class.create(Abstract.TimedObserver, {
-  getValue: function() {
-    return Form.serialize(this.element);
-  }
-});
-
-/*--------------------------------------------------------------------------*/
-
-Abstract.EventObserver = Class.create({
-  initialize: function(element, callback) {
-    this.element  = $(element);
-    this.callback = callback;
-
-    this.lastValue = this.getValue();
-    if (this.element.tagName.toLowerCase() == 'form')
-      this.registerFormCallbacks();
-    else
-      this.registerCallback(this.element);
-  },
-
-  onElementEvent: function() {
-    var value = this.getValue();
-    if (this.lastValue != value) {
-      this.callback(this.element, value);
-      this.lastValue = value;
-    }
-  },
-
-  registerFormCallbacks: function() {
-    Form.getElements(this.element).each(this.registerCallback, this);
-  },
-
-  registerCallback: function(element) {
-    if (element.type) {
-      switch (element.type.toLowerCase()) {
-        case 'checkbox':
-        case 'radio':
-          Event.observe(element, 'click', this.onElementEvent.bind(this));
-          break;
-        default:
-          Event.observe(element, 'change', this.onElementEvent.bind(this));
-          break;
-      }
-    }
-  }
-});
-
-Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
-  getValue: function() {
-    return Form.Element.getValue(this.element);
-  }
-});
-
-Form.EventObserver = Class.create(Abstract.EventObserver, {
-  getValue: function() {
-    return Form.serialize(this.element);
-  }
-});
-(function() {
-
-  var Event = {
-    KEY_BACKSPACE: 8,
-    KEY_TAB:       9,
-    KEY_RETURN:   13,
-    KEY_ESC:      27,
-    KEY_LEFT:     37,
-    KEY_UP:       38,
-    KEY_RIGHT:    39,
-    KEY_DOWN:     40,
-    KEY_DELETE:   46,
-    KEY_HOME:     36,
-    KEY_END:      35,
-    KEY_PAGEUP:   33,
-    KEY_PAGEDOWN: 34,
-    KEY_INSERT:   45,
-
-    cache: {}
-  };
-
-  var docEl = document.documentElement;
-  var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
-    && 'onmouseleave' in docEl;
-
-
-
-  var isIELegacyEvent = function(event) { return false; };
-
-  if (window.attachEvent) {
-    if (window.addEventListener) {
-      isIELegacyEvent = function(event) {
-        return !(event instanceof window.Event);
-      };
-    } else {
-      isIELegacyEvent = function(event) { return true; };
-    }
-  }
-
-  var _isButton;
-
-  function _isButtonForDOMEvents(event, code) {
-    return event.which ? (event.which === code + 1) : (event.button === code);
-  }
-
-  var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
-  function _isButtonForLegacyEvents(event, code) {
-    return event.button === legacyButtonMap[code];
-  }
-
-  function _isButtonForWebKit(event, code) {
-    switch (code) {
-      case 0: return event.which == 1 && !event.metaKey;
-      case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
-      case 2: return event.which == 3;
-      default: return false;
-    }
-  }
-
-  if (window.attachEvent) {
-    if (!window.addEventListener) {
-      _isButton = _isButtonForLegacyEvents;
-    } else {
-      _isButton = function(event, code) {
-        return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
-         _isButtonForDOMEvents(event, code);
-      }
-    }
-  } else if (Prototype.Browser.WebKit) {
-    _isButton = _isButtonForWebKit;
-  } else {
-    _isButton = _isButtonForDOMEvents;
-  }
-
-  function isLeftClick(event)   { return _isButton(event, 0) }
-
-  function isMiddleClick(event) { return _isButton(event, 1) }
-
-  function isRightClick(event)  { return _isButton(event, 2) }
-
-  function element(event) {
-    event = Event.extend(event);
-
-    var node = event.target, type = event.type,
-     currentTarget = event.currentTarget;
-
-    if (currentTarget && currentTarget.tagName) {
-      if (type === 'load' || type === 'error' ||
-        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
-          && currentTarget.type === 'radio'))
-            node = currentTarget;
-    }
-
-    if (node.nodeType == Node.TEXT_NODE)
-      node = node.parentNode;
-
-    return Element.extend(node);
-  }
-
-  function findElement(event, expression) {
-    var element = Event.element(event);
-
-    if (!expression) return element;
-    while (element) {
-      if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
-        return Element.extend(element);
-      }
-      element = element.parentNode;
-    }
-  }
-
-  function pointer(event) {
-    return { x: pointerX(event), y: pointerY(event) };
-  }
-
-  function pointerX(event) {
-    var docElement = document.documentElement,
-     body = document.body || { scrollLeft: 0 };
-
-    return event.pageX || (event.clientX +
-      (docElement.scrollLeft || body.scrollLeft) -
-      (docElement.clientLeft || 0));
-  }
-
-  function pointerY(event) {
-    var docElement = document.documentElement,
-     body = document.body || { scrollTop: 0 };
-
-    return  event.pageY || (event.clientY +
-       (docElement.scrollTop || body.scrollTop) -
-       (docElement.clientTop || 0));
-  }
-
-
-  function stop(event) {
-    Event.extend(event);
-    event.preventDefault();
-    event.stopPropagation();
-
-    event.stopped = true;
-  }
-
-
-  Event.Methods = {
-    isLeftClick:   isLeftClick,
-    isMiddleClick: isMiddleClick,
-    isRightClick:  isRightClick,
-
-    element:     element,
-    findElement: findElement,
-
-    pointer:  pointer,
-    pointerX: pointerX,
-    pointerY: pointerY,
-
-    stop: stop
-  };
-
-  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
-    m[name] = Event.Methods[name].methodize();
-    return m;
-  });
-
-  if (window.attachEvent) {
-    function _relatedTarget(event) {
-      var element;
-      switch (event.type) {
-        case 'mouseover':
-        case 'mouseenter':
-          element = event.fromElement;
-          break;
-        case 'mouseout':
-        case 'mouseleave':
-          element = event.toElement;
-          break;
-        default:
-          return null;
-      }
-      return Element.extend(element);
-    }
-
-    var additionalMethods = {
-      stopPropagation: function() { this.cancelBubble = true },
-      preventDefault:  function() { this.returnValue = false },
-      inspect: function() { return '[object Event]' }
-    };
-
-    Event.extend = function(event, element) {
-      if (!event) return false;
-
-      if (!isIELegacyEvent(event)) return event;
-
-      if (event._extendedByPrototype) return event;
-      event._extendedByPrototype = Prototype.emptyFunction;
-
-      var pointer = Event.pointer(event);
-
-      Object.extend(event, {
-        target: event.srcElement || element,
-        relatedTarget: _relatedTarget(event),
-        pageX:  pointer.x,
-        pageY:  pointer.y
-      });
-
-      Object.extend(event, methods);
-      Object.extend(event, additionalMethods);
-
-      return event;
-    };
-  } else {
-    Event.extend = Prototype.K;
-  }
-
-  if (window.addEventListener) {
-    Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
-    Object.extend(Event.prototype, methods);
-  }
-
-  function _createResponder(element, eventName, handler) {
-    var registry = Element.retrieve(element, 'prototype_event_registry');
-
-    if (Object.isUndefined(registry)) {
-      CACHE.push(element);
-      registry = Element.retrieve(element, 'prototype_event_registry', $H());
-    }
-
-    var respondersForEvent = registry.get(eventName);
-    if (Object.isUndefined(respondersForEvent)) {
-      respondersForEvent = [];
-      registry.set(eventName, respondersForEvent);
-    }
-
-    if (respondersForEvent.pluck('handler').include(handler)) return false;
-
-    var responder;
-    if (eventName.include(":")) {
-      responder = function(event) {
-        if (Object.isUndefined(event.eventName))
-          return false;
-
-        if (event.eventName !== eventName)
-          return false;
-
-        Event.extend(event, element);
-        handler.call(element, event);
-      };
-    } else {
-      if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
-       (eventName === "mouseenter" || eventName === "mouseleave")) {
-        if (eventName === "mouseenter" || eventName === "mouseleave") {
-          responder = function(event) {
-            Event.extend(event, element);
-
-            var parent = event.relatedTarget;
-            while (parent && parent !== element) {
-              try { parent = parent.parentNode; }
-              catch(e) { parent = element; }
-            }
-
-            if (parent === element) return;
-
-            handler.call(element, event);
-          };
-        }
-      } else {
-        responder = function(event) {
-          Event.extend(event, element);
-          handler.call(element, event);
-        };
-      }
-    }
-
-    responder.handler = handler;
-    respondersForEvent.push(responder);
-    return responder;
-  }
-
-  function _destroyCache() {
-    for (var i = 0, length = CACHE.length; i < length; i++) {
-      Event.stopObserving(CACHE[i]);
-      CACHE[i] = null;
-    }
-  }
-
-  var CACHE = [];
-
-  if (Prototype.Browser.IE)
-    window.attachEvent('onunload', _destroyCache);
-
-  if (Prototype.Browser.WebKit)
-    window.addEventListener('unload', Prototype.emptyFunction, false);
-
-
-  var _getDOMEventName = Prototype.K,
-      translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
-
-  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
-    _getDOMEventName = function(eventName) {
-      return (translations[eventName] || eventName);
-    };
-  }
-
-  function observe(element, eventName, handler) {
-    element = $(element);
-
-    var responder = _createResponder(element, eventName, handler);
-
-    if (!responder) return element;
-
-    if (eventName.include(':')) {
-      if (element.addEventListener)
-        element.addEventListener("dataavailable", responder, false);
-      else {
-        element.attachEvent("ondataavailable", responder);
-        element.attachEvent("onlosecapture", responder);
-      }
-    } else {
-      var actualEventName = _getDOMEventName(eventName);
-
-      if (element.addEventListener)
-        element.addEventListener(actualEventName, responder, false);
-      else
-        element.attachEvent("on" + actualEventName, responder);
-    }
-
-    return element;
-  }
-
-  function stopObserving(element, eventName, handler) {
-    element = $(element);
-
-    var registry = Element.retrieve(element, 'prototype_event_registry');
-    if (!registry) return element;
-
-    if (!eventName) {
-      registry.each( function(pair) {
-        var eventName = pair.key;
-        stopObserving(element, eventName);
-      });
-      return element;
-    }
-
-    var responders = registry.get(eventName);
-    if (!responders) return element;
-
-    if (!handler) {
-      responders.each(function(r) {
-        stopObserving(element, eventName, r.handler);
-      });
-      return element;
-    }
-
-    var i = responders.length, responder;
-    while (i--) {
-      if (responders[i].handler === handler) {
-        responder = responders[i];
-        break;
-      }
-    }
-    if (!responder) return element;
-
-    if (eventName.include(':')) {
-      if (element.removeEventListener)
-        element.removeEventListener("dataavailable", responder, false);
-      else {
-        element.detachEvent("ondataavailable", responder);
-        element.detachEvent("onlosecapture", responder);
-      }
-    } else {
-      var actualEventName = _getDOMEventName(eventName);
-      if (element.removeEventListener)
-        element.removeEventListener(actualEventName, responder, false);
-      else
-        element.detachEvent('on' + actualEventName, responder);
-    }
-
-    registry.set(eventName, responders.without(responder));
-
-    return element;
-  }
-
-  function fire(element, eventName, memo, bubble) {
-    element = $(element);
-
-    if (Object.isUndefined(bubble))
-      bubble = true;
-
-    if (element == document && document.createEvent && !element.dispatchEvent)
-      element = document.documentElement;
-
-    var event;
-    if (document.createEvent) {
-      event = document.createEvent('HTMLEvents');
-      event.initEvent('dataavailable', bubble, true);
-    } else {
-      event = document.createEventObject();
-      event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
-    }
-
-    event.eventName = eventName;
-    event.memo = memo || { };
-
-    if (document.createEvent)
-      element.dispatchEvent(event);
-    else
-      element.fireEvent(event.eventType, event);
-
-    return Event.extend(event);
-  }
-
-  Event.Handler = Class.create({
-    initialize: function(element, eventName, selector, callback) {
-      this.element   = $(element);
-      this.eventName = eventName;
-      this.selector  = selector;
-      this.callback  = callback;
-      this.handler   = this.handleEvent.bind(this);
-    },
-
-    start: function() {
-      Event.observe(this.element, this.eventName, this.handler);
-      return this;
-    },
-
-    stop: function() {
-      Event.stopObserving(this.element, this.eventName, this.handler);
-      return this;
-    },
-
-    handleEvent: function(event) {
-      var element = Event.findElement(event, this.selector);
-      if (element) this.callback.call(this.element, event, element);
-    }
-  });
-
-  function on(element, eventName, selector, callback) {
-    element = $(element);
-    if (Object.isFunction(selector) && Object.isUndefined(callback)) {
-      callback = selector, selector = null;
-    }
-
-    return new Event.Handler(element, eventName, selector, callback).start();
-  }
-
-  Object.extend(Event, Event.Methods);
-
-  Object.extend(Event, {
-    fire:          fire,
-    observe:       observe,
-    stopObserving: stopObserving,
-    on:            on
-  });
-
-  Element.addMethods({
-    fire:          fire,
-
-    observe:       observe,
-
-    stopObserving: stopObserving,
-
-    on:            on
-  });
-
-  Object.extend(document, {
-    fire:          fire.methodize(),
-
-    observe:       observe.methodize(),
-
-    stopObserving: stopObserving.methodize(),
-
-    on:            on.methodize(),
-
-    loaded:        false
-  });
-
-  if (window.Event) Object.extend(window.Event, Event);
-  else window.Event = Event;
-})();
-
-(function() {
-  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
-     Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
-
-  var timer;
-
-  function fireContentLoadedEvent() {
-    if (document.loaded) return;
-    if (timer) window.clearTimeout(timer);
-    document.loaded = true;
-    document.fire('dom:loaded');
-  }
-
-  function checkReadyState() {
-    if (document.readyState === 'complete') {
-      document.stopObserving('readystatechange', checkReadyState);
-      fireContentLoadedEvent();
-    }
-  }
-
-  function pollDoScroll() {
-    try { document.documentElement.doScroll('left'); }
-    catch(e) {
-      timer = pollDoScroll.defer();
-      return;
-    }
-    fireContentLoadedEvent();
-  }
-
-  if (document.addEventListener) {
-    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
-  } else {
-    document.observe('readystatechange', checkReadyState);
-    if (window == top)
-      timer = pollDoScroll.defer();
-  }
-
-  Event.observe(window, 'load', fireContentLoadedEvent);
-})();
-
-Element.addMethods();
-
-/*------------------------------- DEPRECATED -------------------------------*/
-
-Hash.toQueryString = Object.toQueryString;
-
-var Toggle = { display: Element.toggle };
-
-Element.Methods.childOf = Element.Methods.descendantOf;
-
-var Insertion = {
-  Before: function(element, content) {
-    return Element.insert(element, {before:content});
-  },
-
-  Top: function(element, content) {
-    return Element.insert(element, {top:content});
-  },
-
-  Bottom: function(element, content) {
-    return Element.insert(element, {bottom:content});
-  },
-
-  After: function(element, content) {
-    return Element.insert(element, {after:content});
-  }
-};
-
-var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
-
-var Position = {
-  includeScrollOffsets: false,
-
-  prepare: function() {
-    this.deltaX =  window.pageXOffset
-                || document.documentElement.scrollLeft
-                || document.body.scrollLeft
-                || 0;
-    this.deltaY =  window.pageYOffset
-                || document.documentElement.scrollTop
-                || document.body.scrollTop
-                || 0;
-  },
-
-  within: function(element, x, y) {
-    if (this.includeScrollOffsets)
-      return this.withinIncludingScrolloffsets(element, x, y);
-    this.xcomp = x;
-    this.ycomp = y;
-    this.offset = Element.cumulativeOffset(element);
-
-    return (y >= this.offset[1] &&
-            y <  this.offset[1] + element.offsetHeight &&
-            x >= this.offset[0] &&
-            x <  this.offset[0] + element.offsetWidth);
-  },
-
-  withinIncludingScrolloffsets: function(element, x, y) {
-    var offsetcache = Element.cumulativeScrollOffset(element);
-
-    this.xcomp = x + offsetcache[0] - this.deltaX;
-    this.ycomp = y + offsetcache[1] - this.deltaY;
-    this.offset = Element.cumulativeOffset(element);
-
-    return (this.ycomp >= this.offset[1] &&
-            this.ycomp <  this.offset[1] + element.offsetHeight &&
-            this.xcomp >= this.offset[0] &&
-            this.xcomp <  this.offset[0] + element.offsetWidth);
-  },
-
-  overlap: function(mode, element) {
-    if (!mode) return 0;
-    if (mode == 'vertical')
-      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
-        element.offsetHeight;
-    if (mode == 'horizontal')
-      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
-        element.offsetWidth;
-  },
-
-
-  cumulativeOffset: Element.Methods.cumulativeOffset,
-
-  positionedOffset: Element.Methods.positionedOffset,
-
-  absolutize: function(element) {
-    Position.prepare();
-    return Element.absolutize(element);
-  },
-
-  relativize: function(element) {
-    Position.prepare();
-    return Element.relativize(element);
-  },
-
-  realOffset: Element.Methods.cumulativeScrollOffset,
-
-  offsetParent: Element.Methods.getOffsetParent,
-
-  page: Element.Methods.viewportOffset,
-
-  clone: function(source, target, options) {
-    options = options || { };
-    return Element.clonePosition(target, source, options);
-  }
-};
-
-/*--------------------------------------------------------------------------*/
-
-if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
-  function iter(name) {
-    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
-  }
-
-  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
-  function(element, className) {
-    className = className.toString().strip();
-    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
-    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
-  } : function(element, className) {
-    className = className.toString().strip();
-    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
-    if (!classNames && !className) return elements;
-
-    var nodes = $(element).getElementsByTagName('*');
-    className = ' ' + className + ' ';
-
-    for (var i = 0, child, cn; child = nodes[i]; i++) {
-      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
-          (classNames && classNames.all(function(name) {
-            return !name.toString().blank() && cn.include(' ' + name + ' ');
-          }))))
-        elements.push(Element.extend(child));
-    }
-    return elements;
-  };
-
-  return function(className, parentElement) {
-    return $(parentElement || document.body).getElementsByClassName(className);
-  };
-}(Element.Methods);
-
-/*--------------------------------------------------------------------------*/
-
-Element.ClassNames = Class.create();
-Element.ClassNames.prototype = {
-  initialize: function(element) {
-    this.element = $(element);
-  },
-
-  _each: function(iterator) {
-    this.element.className.split(/\s+/).select(function(name) {
-      return name.length > 0;
-    })._each(iterator);
-  },
-
-  set: function(className) {
-    this.element.className = className;
-  },
-
-  add: function(classNameToAdd) {
-    if (this.include(classNameToAdd)) return;
-    this.set($A(this).concat(classNameToAdd).join(' '));
-  },
-
-  remove: function(classNameToRemove) {
-    if (!this.include(classNameToRemove)) return;
-    this.set($A(this).without(classNameToRemove).join(' '));
-  },
-
-  toString: function() {
-    return $A(this).join(' ');
-  }
-};
-
-Object.extend(Element.ClassNames.prototype, Enumerable);
-
-/*--------------------------------------------------------------------------*/
-
-(function() {
-  window.Selector = Class.create({
-    initialize: function(expression) {
-      this.expression = expression.strip();
-    },
-
-    findElements: function(rootElement) {
-      return Prototype.Selector.select(this.expression, rootElement);
-    },
-
-    match: function(element) {
-      return Prototype.Selector.match(element, this.expression);
-    },
-
-    toString: function() {
-      return this.expression;
-    },
-
-    inspect: function() {
-      return "#<Selector: " + this.expression + ">";
-    }
-  });
-
-  Object.extend(Selector, {
-    matchElements: function(elements, expression) {
-      var match = Prototype.Selector.match,
-          results = [];
-
-      for (var i = 0, length = elements.length; i < length; i++) {
-        var element = elements[i];
-        if (match(element, expression)) {
-          results.push(Element.extend(element));
-        }
-      }
-      return results;
-    },
-
-    findElement: function(elements, expression, index) {
-      index = index || 0;
-      var matchIndex = 0, element;
-      for (var i = 0, length = elements.length; i < length; i++) {
-        element = elements[i];
-        if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
-          return Element.extend(element);
-        }
-      }
-    },
-
-    findChildElements: function(element, expressions) {
-      var selector = expressions.toArray().join(', ');
-      return Prototype.Selector.select(selector, element || document);
-    }
-  });
-})();
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/16/167c2e3f1c69c031a7eed67f30145680f52df6a1.svn-base
--- /dev/null
+++ b/.svn/pristine/16/167c2e3f1c69c031a7eed67f30145680f52df6a1.svn-base
@@ -0,0 +1,1094 @@
+# Hebrew translation for Redmine
+# Initiated by Dotan Nahum (dipidi@gmail.com)
+# Jul 2010 - Updated by Orgad Shaneh (orgads@gmail.com)
+
+he:
+  direction: rtl
+  date:
+    formats:
+      default: "%d/%m/%Y"
+      short: "%d/%m"
+      long: "%d/%m/%Y"
+      only_day: "%e"
+
+    day_names: [×¨××©×•×Ÿ, ×©× ×™, ×©×œ×™×©×™, ×¨×‘×™×¢×™, ×—×ž×™×©×™, ×©×™×©×™, ×©×‘×ª]
+    abbr_day_names: ["×'", "×‘'", "×’'", "×“'", "×”'", "×•'", "×©'"]
+    month_names: [~, ×™× ×•××¨, ×¤×‘×¨×•××¨, ×ž×¨×¥, ××¤×¨×™×œ, ×ž××™, ×™×•× ×™, ×™×•×œ×™, ××•×’×•×¡×˜, ×¡×¤×˜×ž×‘×¨, ××•×§×˜×•×‘×¨, × ×•×‘×ž×‘×¨, ×“×¦×ž×‘×¨]
+    abbr_month_names: [~, ×™×× , ×¤×‘×¨, ×ž×¨×¥, ××¤×¨, ×ž××™, ×™×•× , ×™×•×œ, ××•×’, ×¡×¤×˜, ××•×§, × ×•×‘, ×“×¦×ž]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a %d/%m/%Y %H:%M:%S"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+      only_second: "%S"
+
+      datetime:
+        formats:
+          default: "%d-%m-%YT%H:%M:%S%Z"
+
+    am: 'am'
+    pm: 'pm'
+
+  datetime:
+    distance_in_words:
+      half_a_minute: '×—×¦×™ ×“×§×”'
+      less_than_x_seconds:
+        zero: '×¤×—×•×ª ×ž×©× ×™×”'
+        one: '×¤×—×•×ª ×ž×©× ×™×”'
+        other: '×¤×—×•×ª ×žÖ¾%{count} ×©× ×™×•×ª'
+      x_seconds:
+        one: '×©× ×™×” ××—×ª'
+        other: '%{count} ×©× ×™×•×ª'
+      less_than_x_minutes:
+        zero: '×¤×—×•×ª ×ž×“×§×” ××—×ª'
+        one: '×¤×—×•×ª ×ž×“×§×” ××—×ª'
+        other: '×¤×—×•×ª ×žÖ¾%{count} ×“×§×•×ª'
+      x_minutes:
+        one: '×“×§×” ××—×ª'
+        other: '%{count} ×“×§×•×ª'
+      about_x_hours:
+        one: '×‘×¢×¨×š ×©×¢×” ××—×ª'
+        other: '×‘×¢×¨×š %{count} ×©×¢×•×ª'
+      x_hours:
+        one:   "1 ×©×¢×”"
+        other: "%{count} ×©×¢×•×ª"
+      x_days:
+        one: '×™×•× ××—×“'
+        other: '%{count} ×™×ž×™×'
+      about_x_months:
+        one: '×‘×¢×¨×š ×—×•×“×© ××—×“'
+        other: '×‘×¢×¨×š %{count} ×—×•×“×©×™×'
+      x_months:
+        one: '×—×•×“×© ××—×“'
+        other: '%{count} ×—×•×“×©×™×'
+      about_x_years:
+        one: '×‘×¢×¨×š ×©× ×” ××—×ª'
+        other: '×‘×¢×¨×š %{count} ×©× ×™×'
+      over_x_years:
+        one: '×ž×¢×œ ×©× ×” ××—×ª'
+        other: '×ž×¢×œ %{count} ×©× ×™×'
+      almost_x_years:
+        one:   "×›×ž×¢×˜ ×©× ×”"
+        other: "×›×ž×¢×˜ %{count} ×©× ×™×"
+
+  number:
+    format:
+      precision: 3
+      separator: '.'
+      delimiter: ','
+    currency:
+      format:
+        unit: '×©"×—'
+        precision: 2
+        format: '%u %n'
+    human:
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "×‘×™×™×˜"
+            other: "×‘×ª×™×"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  support:
+    array:
+      sentence_connector: "×•×’×"
+      skip_last_comma: true
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "×œ× × ×›×œ×œ ×‘×¨×©×™×ž×”"
+        exclusion: "×œ× ×–×ž×™×Ÿ"
+        invalid: "×œ× ×•×œ×™×“×™"
+        confirmation: "×œ× ×ª×•×× ×œ××™×©×•×¨"
+        accepted: "×—×™×™×‘ ×‘××™×©×•×¨"
+        empty: "×—×™×™×‘ ×œ×”×›×œ×œ"
+        blank: "×—×™×™×‘ ×œ×”×›×œ×œ"
+        too_long: "××¨×•×š ×ž×“×™ (×œ× ×™×•×ª×¨ ×žÖ¾%{count} ×ª×•×™×)"
+        too_short: "×§×¦×¨ ×ž×“×™ (×œ× ×™×•×ª×¨ ×žÖ¾%{count} ×ª×•×™×)"
+        wrong_length: "×œ× ×‘××•×¨×š ×”× ×›×•×Ÿ (×—×™×™×‘ ×œ×”×™×•×ª %{count} ×ª×•×™×)"
+        taken: "×œ× ×–×ž×™×Ÿ"
+        not_a_number: "×”×•× ×œ× ×ž×¡×¤×¨"
+        greater_than: "×—×™×™×‘ ×œ×”×™×•×ª ×’×“×•×œ ×žÖ¾%{count}"
+        greater_than_or_equal_to: "×—×™×™×‘ ×œ×”×™×•×ª ×’×“×•×œ ××• ×©×•×•×” ×œÖ¾%{count}"
+        equal_to: "×—×™×™×‘ ×œ×”×™×•×ª ×©×•×•×” ×œÖ¾%{count}"
+        less_than: "×—×™×™×‘ ×œ×”×™×•×ª ×§×˜×Ÿ ×žÖ¾%{count}"
+        less_than_or_equal_to: "×—×™×™×‘ ×œ×”×™×•×ª ×§×˜×Ÿ ××• ×©×•×•×” ×œÖ¾%{count}"
+        odd: "×—×™×™×‘ ×œ×”×™×•×ª ××™ ×–×•×’×™"
+        even: "×—×™×™×‘ ×œ×”×™×•×ª ×–×•×’×™"
+        greater_than_start_date: "×—×™×™×‘ ×œ×”×™×•×ª ×ž××•×—×¨ ×™×•×ª×¨ ×ž×ª××¨×™×š ×”×”×ª×—×œ×”"
+        not_same_project: "×œ× ×©×™×™×š ×œ××•×ª×• ×”×¤×¨×•×™×§×˜"
+        circular_dependency: "×§×©×¨ ×–×” ×™×¦×•×¨ ×ª×œ×•×ª ×ž×¢×’×œ×™×ª"
+        cant_link_an_issue_with_a_descendant: "×œ× × ×™×ª×Ÿ ×œ×§×©×¨ × ×•×©× ×œ×ª×ªÖ¾×ž×©×™×ž×” ×©×œ×•"
+
+  actionview_instancetag_blank_option: ×‘×—×¨ ×‘×‘×§×©×”
+
+  general_text_No: '×œ×'
+  general_text_Yes: '×›×Ÿ'
+  general_text_no: '×œ×'
+  general_text_yes: '×›×Ÿ'
+  general_lang_name: 'Hebrew (×¢×‘×¨×™×ª)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_updated: ×”×—×©×‘×•×Ÿ ×¢×•×“×›×Ÿ ×‘×”×¦×œ×—×”!
+  notice_account_invalid_creditentials: ×©× ×ž×©×ª×ž×© ××• ×¡×™×¡×ž×” ×©×’×•×™×™×
+  notice_account_password_updated: ×”×¡×™×¡×ž×” ×¢×•×“×›× ×” ×‘×”×¦×œ×—×”!
+  notice_account_wrong_password: ×¡×™×¡×ž×” ×©×’×•×™×”
+  notice_account_register_done: ×”×—×©×‘×•×Ÿ × ×•×¦×¨ ×‘×”×¦×œ×—×”. ×œ×”×¤×¢×œ×ª ×”×—×©×‘×•×Ÿ ×œ×—×¥ ×¢×œ ×”×§×™×©×•×¨ ×©× ×©×œ×— ×œ×“×•×"×œ ×©×œ×š.
+  notice_account_unknown_email: ×ž×©×ª×ž×© ×œ× ×ž×•×›×¨.
+  notice_can_t_change_password: ×”×—×©×‘×•×Ÿ ×”×–×” ×ž×©×ª×ž×© ×‘×ž×§×•×¨ ×”×–×“×”×•×ª ×—×™×¦×•× ×™. ×©×™× ×•×™ ×¡×™×¡×ž×” ×”×™× ×• ×‘×™×œ×ª×™ ××¤×©×¨
+  notice_account_lost_email_sent: ×“×•×"×œ ×¢× ×”×•×¨××•×ª ×œ×‘×—×™×¨×ª ×¡×™×¡×ž×” ×—×“×©×” × ×©×œ×— ××œ×™×š.
+  notice_account_activated: ×—×©×‘×•× ×š ×”×•×¤×¢×œ. ××ª×” ×™×›×•×œ ×œ×”×ª×—×‘×¨ ×›×¢×ª.
+  notice_successful_create: ×™×¦×™×¨×” ×ž×•×¦×œ×—×ª.
+  notice_successful_update: ×¢×™×“×›×•×Ÿ ×ž×•×¦×œ×—.
+  notice_successful_delete: ×ž×—×™×§×” ×ž×•×¦×œ×—×ª.
+  notice_successful_connection: ×—×™×‘×•×¨ ×ž×•×¦×œ×—.
+  notice_file_not_found: ×”×“×£ ×©××ª×” ×ž× ×¡×” ×œ×’×©×ª ××œ×™×• ××™× ×• ×§×™×™× ××• ×©×”×•×¡×¨.
+  notice_locking_conflict: ×”×ž×™×“×¢ ×¢×•×“×›×Ÿ ×¢×œ ×™×“×™ ×ž×©×ª×ž×© ××—×¨.
+  notice_not_authorized: ××™× ×š ×ž×•×¨×©×” ×œ×¨××•×ª ×“×£ ×–×”.
+  notice_not_authorized_archived_project: ×”×¤×¨×•×™×§×˜ ×©××ª×” ×ž× ×¡×” ×œ×’×©×ª ××œ×™×• × ×ž×¦× ×‘××¨×›×™×•×Ÿ.
+  notice_email_sent: "×“×•××œ × ×©×œ×— ×œ×›×ª×•×‘×ª %{value}"
+  notice_email_error: "××¨×¢×” ×©×’×™××” ×‘×¢×ª ×©×œ×™×—×ª ×”×“×•××œ (%{value})"
+  notice_feeds_access_key_reseted: ×ž×¤×ª×— ×”Ö¾RSS ×©×œ×š ××•×¤×¡.
+  notice_api_access_key_reseted: ×ž×¤×ª×— ×”×’×™×©×” ×©×œ×š ×œÖ¾API ××•×¤×¡.
+  notice_failed_to_save_issues: "× ×›×©×¨×ª ×‘×©×ž×™×¨×ª %{count} × ×•×©××™× ×‘ %{total} × ×‘×—×¨×•: %{ids}."
+  notice_failed_to_save_members: "×›×©×œ×•×Ÿ ×‘×©×ž×™×¨×ª ×—×‘×¨(×™×): %{errors}."
+  notice_no_issue_selected: "×œ× × ×‘×—×¨ ××£ × ×•×©×! ×‘×—×¨ ×‘×‘×§×©×” ××ª ×”× ×•×©××™× ×©×‘×¨×¦×•× ×š ×œ×¢×¨×•×š."
+  notice_account_pending: "×”×—×©×‘×•×Ÿ ×©×œ×š × ×•×¦×¨ ×•×¢×ª×” ×ž×—×›×” ×œ××™×©×•×¨ ×ž× ×”×œ ×”×ž×¢×¨×›×ª."
+  notice_default_data_loaded: ××¤×©×¨×•×™×•×ª ×‘×¨×™×¨×ª ×ž×—×“×œ ×ž×•×¤×¢×œ×•×ª.
+  notice_unable_delete_version: ×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ×’×™×¨×¡×”
+  notice_unable_delete_time_entry: ×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ×¨×©×•×ž×ª ×–×ž×Ÿ.
+  notice_issue_done_ratios_updated: ××—×•×–×™ ×”×ª×§×“×ž×•×ª ×œ× ×•×©× ×¢×•×“×›× ×•.
+
+  error_can_t_load_default_data: "××¤×©×¨×•×™×•×ª ×‘×¨×™×¨×ª ×”×ž×—×“×œ ×œ× ×”×¦×œ×™×—×• ×œ×”×™×˜×¢×Ÿ: %{value}"
+  error_scm_not_found: ×›× ×™×¡×” ×•\××• ×ž×”×“×•×¨×” ××™× × ×§×™×™×ž×™× ×‘×ž××’×¨.
+  error_scm_command_failed: "××¨×¢×” ×©×’×™××” ×‘×¢×ª × ×™×¡×•×Ÿ ×’×™×©×” ×œ×ž××’×¨: %{value}"
+  error_scm_annotate: "×”×›× ×™×¡×” ×œ× ×§×™×™×ž×ª ××• ×©×œ× × ×™×ª×Ÿ ×œ×ª××¨ ××•×ª×”."
+  error_issue_not_found_in_project: '×”× ×•×©××™× ×œ× × ×ž×¦××• ××• ××™× × ×©×™×›×™× ×œ×¤×¨×•×™×§×˜'
+  error_no_tracker_in_project: ×œ× ×”×•×’×“×¨ ×¡×™×•×•×’ ×œ×¤×¨×•×™×§×˜ ×–×”. × × ×‘×“×•×§ ××ª ×”×’×“×¨×•×ª ×”×¤×¨×•×™×§×˜.
+  error_no_default_issue_status: ×œ× ×ž×•×’×“×¨ ×ž×¦×‘ ×‘×¨×™×¨×ª ×ž×—×“×œ ×œ× ×•×©××™×. × × ×‘×“×•×§ ××ª ×”×ª×¦×•×¨×” ("× ×™×”×•×œ -> ×ž×¦×‘×™ × ×•×©×").
+  error_can_not_delete_custom_field: ×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ×©×“×” ×ž×•×ª×× ××™×©×™×ª
+  error_can_not_delete_tracker: ×§×™×™×ž×™× × ×•×©××™× ×‘×¡×™×•×•×’ ×–×”, ×•×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ××•×ª×•.
+  error_can_not_remove_role: ×ª×¤×§×™×“ ×–×” × ×ž×¦× ×‘×©×™×ž×•×©, ×•×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ××•×ª×•.
+  error_can_not_reopen_issue_on_closed_version: ×œ× × ×™×ª×Ÿ ×œ×¤×ª×•×— ×ž×—×“×© × ×•×©× ×©×ž×©×•×™×š ×œ×’×™×¨×¡×” ×¡×’×•×¨×”
+  error_can_not_archive_project: ×œ× × ×™×ª×Ÿ ×œ××¨×›×‘ ×¤×¨×•×™×§×˜ ×–×”
+  error_issue_done_ratios_not_updated: ××—×•×– ×”×ª×§×“×ž×•×ª ×œ× ×•×©× ×œ× ×¢×•×“×›×Ÿ.
+  error_workflow_copy_source: × × ×‘×—×¨ ×¡×™×•×•×’ ××• ×ª×¤×§×™×“ ×ž×§×•×¨
+  error_workflow_copy_target: × × ×‘×—×¨ ×ª×¤×§×™×“(×™×) ×•×¡×™×•×•×’(×™×)
+  error_unable_delete_issue_status: ×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ×ž×¦×‘ × ×•×©×
+  error_unable_to_connect: ×œ× × ×™×ª×Ÿ ×œ×”×ª×—×‘×¨ (%{value})
+  warning_attachments_not_saved: "×›×©×œ×•×Ÿ ×‘×©×ž×™×¨×ª %{count} ×§×‘×¦×™×."
+
+  mail_subject_lost_password: "×¡×™×¡×ž×ª ×”Ö¾%{value} ×©×œ×š"
+  mail_body_lost_password: '×œ×©×™× ×• ×¡×™×¡×ž×ª ×”Ö¾Redmine ×©×œ×š, ×œ×—×¥ ×¢×œ ×”×§×™×©×•×¨ ×”×‘×:'
+  mail_subject_register: "×”×¤×¢×œ×ª ×—×©×‘×•×Ÿ %{value}"
+  mail_body_register: '×œ×”×¤×¢×œ×ª ×—×©×‘×•×Ÿ ×”Ö¾Redmine ×©×œ×š, ×œ×—×¥ ×¢×œ ×”×§×™×©×•×¨ ×”×‘×:'
+  mail_body_account_information_external: "××ª×” ×™×›×•×œ ×œ×”×©×ª×ž×© ×‘×—×©×‘×•×Ÿ %{value} ×›×“×™ ×œ×”×ª×—×‘×¨"
+  mail_body_account_information: ×¤×¨×˜×™ ×”×—×©×‘×•×Ÿ ×©×œ×š
+  mail_subject_account_activation_request: "×‘×§×©×ª ×”×¤×¢×œ×” ×œ×—×©×‘×•×Ÿ %{value}"
+  mail_body_account_activation_request: "×ž×©×ª×ž×© ×—×“×© (%{value}) × ×¨×©×. ×”×—×©×‘×•×Ÿ ×©×œ×• ×ž×—×›×” ×œ××™×©×•×¨ ×©×œ×š:"
+  mail_subject_reminder: "%{count} × ×•×©××™× ×ž×™×•×¢×“×™× ×œ×”×’×©×” ×‘×™×ž×™× ×”×§×¨×•×‘×™× (%{days})"
+  mail_body_reminder: "%{count} × ×•×©××™× ×©×ž×™×•×¢×“×™× ××œ×™×š ×ž×™×•×¢×“×™× ×œ×”×’×©×” ×‘×ª×•×š %{days} ×™×ž×™×:"
+  mail_subject_wiki_content_added: "×“×£ ×”Ö¾wiki â€'%{id}' × ×•×¡×£"
+  mail_body_wiki_content_added: ×“×£ ×”Ö¾wiki â€'%{id}' × ×•×¡×£ ×¢"×™ %{author}.
+  mail_subject_wiki_content_updated: "×“×£ ×”Ö¾wiki â€'%{id}' ×¢×•×“×›×Ÿ"
+  mail_body_wiki_content_updated: ×“×£ ×”Ö¾wiki â€'%{id}' ×¢×•×“×›×Ÿ ×¢"×™ %{author}.
+
+
+  field_name: ×©×
+  field_description: ×ª×™××•×¨
+  field_summary: ×ª×§×¦×™×¨
+  field_is_required: × ×“×¨×©
+  field_firstname: ×©× ×¤×¨×˜×™
+  field_lastname: ×©× ×ž×©×¤×—×”
+  field_mail: ×“×•×"×œ
+  field_filename: ×§×•×‘×¥
+  field_filesize: ×’×•×“×œ
+  field_downloads: ×”×•×¨×“×•×ª
+  field_author: ×›×•×ª×‘
+  field_created_on: × ×•×¦×¨
+  field_updated_on: ×¢×•×“×›×Ÿ
+  field_field_format: ×¤×•×¨×ž×˜
+  field_is_for_all: ×œ×›×œ ×”×¤×¨×•×™×§×˜×™×
+  field_possible_values: ×¢×¨×›×™× ××¤×©×¨×™×™×
+  field_regexp: ×‘×™×˜×•×™ ×¨×’×™×œ
+  field_min_length: ××•×¨×š ×ž×™× ×™×ž××œ×™
+  field_max_length: ××•×¨×š ×ž×§×¡×™×ž××œ×™
+  field_value: ×¢×¨×š
+  field_category: ×§×˜×’×•×¨×™×”
+  field_title: ×›×•×ª×¨×ª
+  field_project: ×¤×¨×•×™×§×˜
+  field_issue: × ×•×©×
+  field_status: ×ž×¦×‘
+  field_notes: ×”×¢×¨×•×ª
+  field_is_closed: × ×•×©× ×¡×’×•×¨
+  field_is_default: ×¢×¨×š ×‘×¨×™×¨×ª ×ž×—×“×œ
+  field_tracker: ×¡×™×•×•×’
+  field_subject: ×©× × ×•×©×
+  field_due_date: ×ª××¨×™×š ×¡×™×•×
+  field_assigned_to: ××—×¨××™
+  field_priority: ×¢×“×™×¤×•×ª
+  field_fixed_version: ×’×™×¨×¡×ª ×™×¢×“
+  field_user: ×ž×ª×©×ž×©
+  field_principal: ×ž× ×”×œ
+  field_role: ×ª×¤×§×™×“
+  field_homepage: ×“×£ ×”×‘×™×ª
+  field_is_public: ×¤×•×ž×‘×™
+  field_parent: ×ª×ª ×¤×¨×•×™×§×˜ ×©×œ
+  field_is_in_roadmap: × ×•×©××™× ×”×ž×•×¦×’×™× ×‘×ž×¤×ª ×”×“×¨×›×™×
+  field_login: ×©× ×ž×©×ª×ž×©
+  field_mail_notification: ×”×•×“×¢×•×ª ×“×•×"×œ
+  field_admin: × ×™×”×•×œ
+  field_last_login_on: ×”×ª×—×‘×¨×•×ª ××—×¨×•× ×”
+  field_language: ×©×¤×”
+  field_effective_date: ×ª××¨×™×š
+  field_password: ×¡×™×¡×ž×”
+  field_new_password: ×¡×™×¡×ž×” ×—×“×©×”
+  field_password_confirmation: ××™×©×•×¨
+  field_version: ×’×™×¨×¡×”
+  field_type: ×¡×•×’
+  field_host: ×©×¨×ª
+  field_port: ×¤×•×¨×˜
+  field_account: ×—×©×‘×•×Ÿ
+  field_base_dn: ×‘×¡×™×¡ DN
+  field_attr_login: ×ª×›×•× ×ª ×”×ª×—×‘×¨×•×ª
+  field_attr_firstname: ×ª×›×•× ×ª ×©× ×¤×¨×˜×™×
+  field_attr_lastname: ×ª×›×•× ×ª ×©× ×ž×©×¤×—×”
+  field_attr_mail: ×ª×›×•× ×ª ×“×•×"×œ
+  field_onthefly: ×™×¦×™×¨×ª ×ž×©×ª×ž×©×™× ×–×¨×™×–×”
+  field_start_date: ×ª××¨×™×š ×”×ª×—×œ×”
+  field_done_ratio: "% ×’×ž×•×¨"
+  field_auth_source: ×ž×§×•×¨ ×”×–×“×”×•×ª
+  field_hide_mail: ×”×—×‘× ××ª ×›×ª×•×‘×ª ×”×“×•×"×œ ×©×œ×™
+  field_comments: ×”×¢×¨×•×ª
+  field_url: URL
+  field_start_page: ×“×£ ×”×ª×—×œ×ª×™
+  field_subproject: ×ª×ªÖ¾×¤×¨×•×™×§×˜
+  field_hours: ×©×¢×•×ª
+  field_activity: ×¤×¢×™×œ×•×ª
+  field_spent_on: ×ª××¨×™×š
+  field_identifier: ×ž×–×”×”
+  field_is_filter: ×ž×©×ž×© ×›×ž×¡× ×Ÿ
+  field_issue_to: × ×•×©××™× ×§×©×•×¨×™×
+  field_delay: ×¢×™×§×•×‘
+  field_assignable: × ×™×ª×Ÿ ×œ×”×§×¦×•×ª × ×•×©××™× ×œ×ª×¤×§×™×“ ×–×”
+  field_redirect_existing_links: ×”×¢×‘×¨ ×§×™×©×•×¨×™× ×§×™×™×ž×™×
+  field_estimated_hours: ×–×ž×Ÿ ×ž×©×•×¢×¨
+  field_column_names: ×¢×ž×•×“×•×ª
+  field_time_entries: ×¨×™×©×•× ×–×ž× ×™×
+  field_time_zone: ××™×–×•×¨ ×–×ž×Ÿ
+  field_searchable: × ×™×ª×Ÿ ×œ×—×™×¤×•×©
+  field_default_value: ×¢×¨×š ×‘×¨×™×¨×ª ×ž×—×“×œ
+  field_comments_sorting: ×”×¦×’ ×”×¢×¨×•×ª
+  field_parent_title: ×“×£ ××‘
+  field_editable: × ×™×ª×Ÿ ×œ×¢×¨×™×›×”
+  field_watcher: ×¦×•×¤×”
+  field_identity_url: ×›×ª×•×‘×ª OpenID
+  field_content: ×ª×•×›×Ÿ
+  field_group_by: ×§×‘×¥ ××ª ×”×ª×•×¦××•×ª ×œ×¤×™
+  field_sharing: ×©×™×ª×•×£
+  field_parent_issue: ×ž×©×™×ž×ª ××‘
+  field_text: ×©×“×” ×˜×§×¡×˜
+
+  setting_app_title: ×›×•×ª×¨×ª ×™×©×•×
+  setting_app_subtitle: ×ª×ªÖ¾×›×•×ª×¨×ª ×™×©×•×
+  setting_welcome_text: ×˜×§×¡×˜ "×‘×¨×•×š ×”×‘×"
+  setting_default_language: ×©×¤×ª ×‘×¨×™×¨×ª ×ž×—×“×œ
+  setting_login_required: ×“×¨×•×©×” ×”×–×“×”×•×ª
+  setting_self_registration: ××¤×©×¨ ×”×¨×©×ž×” ×¢×¦×ž×™×ª
+  setting_attachment_max_size: ×’×•×“×œ ×“×‘×•×§×” ×ž×§×¡×™×ž××œ×™
+  setting_issues_export_limit: ×’×‘×•×œ ×™×¦×•× × ×•×©××™×
+  setting_mail_from: ×›×ª×•×‘×ª ×©×œ×™×—×ª ×“×•×"×œ
+  setting_bcc_recipients: ×ž×•×¡×ª×¨ (bcc)
+  setting_plain_text_mail: ×˜×§×¡×˜ ×¤×©×•×˜ ×‘×œ×‘×“ (×œ×œ× HTML)
+  setting_host_name: ×©× ×©×¨×ª
+  setting_text_formatting: ×¢×™×¦×•×‘ ×˜×§×¡×˜
+  setting_wiki_compression: ×›×™×•×•×¥ ×”×™×¡×˜×•×¨×™×ª wiki
+  setting_feeds_limit: ×’×‘×•×œ ×ª×•×›×Ÿ ×”×–× ×•×ª
+  setting_default_projects_public: ×¤×¨×•×™×§×˜×™× ×—×“×©×™× ×”×™× × ×¤×•×ž×‘×™×™× ×›×‘×¨×™×¨×ª ×ž×—×“×œ
+  setting_autofetch_changesets: ×ž×©×™×›×” ××•×˜×•×ž×˜×™×ª ×©×œ ×©×™× ×•×™×™×
+  setting_sys_api_enabled: ××¤×©×¨ ×©×™×¨×•×ª ×¨×©×ª ×œ× ×™×”×•×œ ×”×ž××’×¨
+  setting_commit_ref_keywords: ×ž×™×œ×•×ª ×ž×¤×ª×— ×ž×§×©×¨×•×ª
+  setting_commit_fix_keywords: ×ž×™×œ×•×ª ×ž×¤×ª×— ×ž×ª×§× ×•×ª
+  setting_autologin: ×”×ª×—×‘×¨×•×ª ××•×˜×•×ž×˜×™×ª
+  setting_date_format: ×¤×•×¨×ž×˜ ×ª××¨×™×š
+  setting_time_format: ×¤×•×¨×ž×˜ ×–×ž×Ÿ
+  setting_cross_project_issue_relations: ×”×¨×©×” ×§×™×©×•×¨ × ×•×©××™× ×‘×™×Ÿ ×¤×¨×•×™×§×˜×™×
+  setting_issue_list_default_columns: ×¢×ž×•×“×•×ª ×‘×¨×™×¨×ª ×ž×—×“×œ ×”×ž×•×¦×’×•×ª ×‘×¨×©×™×ž×ª ×”× ×•×©××™×
+  setting_emails_footer: ×ª×—×ª×™×ª ×“×•×"×œ
+  setting_protocol: ×¤×¨×•×˜×•×§×•×œ
+  setting_per_page_options: ××¤×©×¨×•×™×•×ª ××•×‘×™×§×˜×™× ×œ×¤×™ ×“×£
+  setting_user_format: ×¤×•×¨×ž×˜ ×”×¦×’×ª ×ž×©×ª×ž×©×™×
+  setting_activity_days_default: ×™×ž×™× ×”×ž×•×¦×’×™× ×¢×œ ×¤×¢×™×œ×•×ª ×”×¤×¨×•×™×§×˜
+  setting_display_subprojects_issues: ×”×¦×’ × ×•×©××™× ×©×œ ×ª×ª×™Ö¾×¤×¨×•×™×§×˜×™× ×›×‘×¨×™×¨×ª ×ž×—×“×œ
+  setting_enabled_scm: ××¤×©×¨ × ×™×”×•×œ ×ª×¦×•×¨×”
+  setting_mail_handler_body_delimiters: ×—×ª×•×š ×›×ª×•×‘×•×ª ×“×•××¨ ××—×¨×™ ××—×ª ×ž×©×•×¨×•×ª ××œ×”
+  setting_mail_handler_api_enabled: ××¤×©×¨ ×©×™×¨×•×ª ×¨×©×ª ×œ×“×•××¨ × ×›× ×¡
+  setting_mail_handler_api_key: ×ž×¤×ª×— API
+  setting_sequential_project_identifiers: ×”×©×ª×ž×© ×‘×ž×¡×¤×¨×™× ×¢×•×§×‘×™× ×œ×ž×–×”×™ ×¤×¨×•×™×§×˜
+  setting_gravatar_enabled: ×©×™×ž×•×© ×‘×¦×œ×ž×™×•×ª ×ž×©×ª×ž×©×™× ×žÖ¾Gravatar
+  setting_gravatar_default: ×ª×ž×•× ×ª Gravatar ×‘×¨×™×¨×ª ×ž×—×“×œ
+  setting_diff_max_lines_displayed: ×ž×¡×¤×¨ ×ž×™×¨×‘×™ ×©×œ ×©×•×¨×•×ª ×‘×ª×¦×•×’×ª ×©×™× ×•×™×™×
+  setting_file_max_size_displayed: ×’×•×“×œ ×ž×™×¨×‘×™ ×©×œ ×ž×œ×œ ×”×ž×•×¦×’ ×‘×ª×•×š ×”×©×•×¨×”
+  setting_repository_log_display_limit: ×ž×¡×¤×¨ ×ž×™×¨×‘×™ ×©×œ ×ž×”×“×•×¨×•×ª ×”×ž×•×¦×’×•×ª ×‘×™×•×ž×Ÿ ×§×•×‘×¥
+  setting_openid: ××¤×©×¨ ×”×ª×—×‘×¨×•×ª ×•×¨×™×©×•× ×‘××ž×¦×¢×•×ª OpenID
+  setting_password_min_length: ××•×¨×š ×¡×™×¡×ž×” ×ž×™× ×™×ž××œ×™
+  setting_new_project_user_role_id: ×”×ª×¤×§×™×“ ×©×ž×•×’×“×¨ ×œ×ž×©×ª×ž×© ×¤×©×•×˜ ××©×¨ ×™×•×¦×¨ ×¤×¨×•×™×§×˜
+  setting_default_projects_modules: ×ž×•×“×•×œ×™× ×ž××•×¤×©×¨×™× ×‘×‘×¨×™×¨×ª ×ž×—×“×œ ×¢×‘×•×¨ ×¤×¨×•×™×§×˜×™× ×—×“×©×™×
+  setting_issue_done_ratio: ×—×©×‘ ××—×•×– ×”×ª×§×“×ž×•×ª ×‘× ×•×©× ×¢×
+  setting_issue_done_ratio_issue_field: ×”×©×ª×ž×© ×‘×©×“×” ×”× ×•×©×
+  setting_issue_done_ratio_issue_status: ×”×©×ª×ž×© ×‘×ž×¦×‘ ×”× ×•×©×
+  setting_start_of_week: ×”×©×‘×•×¢ ×ž×ª×—×™×œ ×‘×™×•×
+  setting_rest_api_enabled: ××¤×©×¨ ×©×™×¨×•×ª ×¨×©×ª REST
+  setting_cache_formatted_text: ×©×ž×•×¨ ×˜×§×¡×˜ ×ž×¢×•×¦×‘ ×‘×ž×˜×ž×•×Ÿ
+  setting_default_notification_option: ××¤×©×¨×•×ª ×”×ª×¨××” ×‘×¨×™×¨×ªÖ¾×ž×—×“×œ
+
+  permission_add_project: ×™×¦×™×¨×ª ×¤×¨×•×™×§×˜
+  permission_add_subprojects: ×™×¦×™×¨×ª ×ª×ª×™Ö¾×¤×¨×•×™×§×˜
+  permission_edit_project: ×¢×¨×™×›×ª ×¤×¨×•×™×§×˜
+  permission_select_project_modules: ×‘×—×™×¨×ª ×ž×•×“×•×œ×™ ×¤×¨×•×™×§×˜
+  permission_manage_members: × ×™×”×•×œ ×—×‘×¨×™×
+  permission_manage_project_activities: × ×”×œ ×¤×¢×™×œ×•×™×•×ª ×¤×¨×•×™×§×˜
+  permission_manage_versions: × ×™×”×•×œ ×’×™×¨×¡××•×ª
+  permission_manage_categories: × ×™×”×•×œ ×§×˜×’×•×¨×™×•×ª × ×•×©××™×
+  permission_view_issues: ×¦×¤×™×” ×‘× ×•×©××™×
+  permission_add_issues: ×”×•×¡×¤×ª × ×•×©×
+  permission_edit_issues: ×¢×¨×™×›×ª × ×•×©××™×
+  permission_manage_issue_relations: × ×™×”×•×œ ×§×©×¨×™× ×‘×™×Ÿ × ×•×©××™×
+  permission_add_issue_notes: ×”×•×¡×¤×ª ×”×¢×¨×•×ª ×œ× ×•×©××™×
+  permission_edit_issue_notes: ×¢×¨×™×›×ª ×¨×©×™×ž×•×ª
+  permission_edit_own_issue_notes: ×¢×¨×™×›×ª ×”×¢×¨×•×ª ×©×œ ×¢×¦×ž×•
+  permission_move_issues: ×”×–×–×ª × ×•×©××™×
+  permission_delete_issues: ×ž×—×™×§×ª × ×•×©××™×
+  permission_manage_public_queries: × ×™×”×•×œ ×©××™×œ×ª×•×ª ×¤×•×ž×‘×™×•×ª
+  permission_save_queries: ×©×ž×™×¨×ª ×©××™×œ×ª×•×ª
+  permission_view_gantt: ×¦×¤×™×” ×‘×’×× ×˜
+  permission_view_calendar: ×¦×¤×™×” ×‘×œ×•×— ×”×©× ×”
+  permission_view_issue_watchers: ×¦×¤×™×” ×‘×¨×©×™×ž×ª ×¦×•×¤×™×
+  permission_add_issue_watchers: ×”×•×¡×¤×ª ×¦×•×¤×™×
+  permission_delete_issue_watchers: ×”×¡×¨×ª ×¦×•×¤×™×
+  permission_log_time: ×ª×™×¢×•×“ ×–×ž×Ÿ ×©×”×•×©×§×¢
+  permission_view_time_entries: ×¦×¤×™×” ×‘×¨×™×©×•× ×–×ž× ×™×
+  permission_edit_time_entries: ×¢×¨×™×›×ª ×¨×™×©×•× ×–×ž× ×™×
+  permission_edit_own_time_entries: ×¢×¨×™×›×ª ×¨×™×©×•× ×”×–×ž× ×™× ×©×œ ×¢×¦×ž×•
+  permission_manage_news: × ×™×”×•×œ ×—×“×©×•×ª
+  permission_comment_news: ×ª×’×•×‘×” ×œ×—×“×©×•×ª
+  permission_view_documents: ×¦×¤×™×” ×‘×ž×¡×ž×›×™×
+  permission_manage_files: × ×™×”×•×œ ×§×‘×¦×™×
+  permission_view_files: ×¦×¤×™×” ×‘×§×‘×¦×™×
+  permission_manage_wiki: × ×™×”×•×œ wiki
+  permission_rename_wiki_pages: ×©×™× ×•×™ ×©× ×©×œ ×“×¤×™ wiki
+  permission_delete_wiki_pages: ×ž×—×™×§×ª ×“×¤×™ wiki
+  permission_view_wiki_pages: ×¦×¤×™×” ×‘Ö¾wiki
+  permission_view_wiki_edits: ×¦×¤×™×” ×‘×”×™×¡×˜×•×¨×™×ª wiki
+  permission_edit_wiki_pages: ×¢×¨×™×›×ª ×“×¤×™ wiki
+  permission_delete_wiki_pages_attachments: ×ž×—×™×§×ª ×“×‘×•×§×•×ª
+  permission_protect_wiki_pages: ×”×’× ×” ×¢×œ ×›×œ ×“×¤×™ wiki
+  permission_manage_repository: × ×™×”×•×œ ×ž××’×¨
+  permission_browse_repository: ×¡×™×•×¨ ×‘×ž××’×¨
+  permission_view_changesets: ×¦×¤×™×” ×‘×¡×“×¨×•×ª ×©×™× ×•×™×™×
+  permission_commit_access: ××™×©×•×¨ ×”×¤×§×“×•×ª
+  permission_manage_boards: × ×™×”×•×œ ×œ×•×—×•×ª
+  permission_view_messages: ×¦×¤×™×” ×‘×”×•×“×¢×•×ª
+  permission_add_messages: ×”×¦×‘×ª ×”×•×“×¢×•×ª
+  permission_edit_messages: ×¢×¨×™×›×ª ×”×•×“×¢×•×ª
+  permission_edit_own_messages: ×¢×¨×™×›×ª ×”×•×“×¢×•×ª ×©×œ ×¢×¦×ž×•
+  permission_delete_messages: ×ž×—×™×§×ª ×”×•×“×¢×•×ª
+  permission_delete_own_messages: ×ž×—×™×§×ª ×”×•×“×¢×•×ª ×©×œ ×¢×¦×ž×•
+  permission_export_wiki_pages: ×™×¦× ×“×¤×™ wiki
+  permission_manage_subtasks: × ×”×œ ×ª×ª×™Ö¾×ž×©×™×ž×•×ª
+
+  project_module_issue_tracking: ×ž×¢×§×‘ × ×•×©××™×
+  project_module_time_tracking: ×ž×¢×§×‘ ××—×¨ ×–×ž× ×™×
+  project_module_news: ×—×“×©×•×ª
+  project_module_documents: ×ž×¡×ž×›×™×
+  project_module_files: ×§×‘×¦×™×
+  project_module_wiki: Wiki
+  project_module_repository: ×ž××’×¨
+  project_module_boards: ×œ×•×—×•×ª
+  project_module_calendar: ×œ×•×— ×©× ×”
+  project_module_gantt: ×’×× ×˜
+
+  label_user: ×ž×©×ª×ž×©
+  label_user_plural: ×ž×©×ª×ž×©×™×
+  label_user_new: ×ž×©×ª×ž×© ×—×“×©
+  label_user_anonymous: ××œ×ž×•× ×™
+  label_project: ×¤×¨×•×™×§×˜
+  label_project_new: ×¤×¨×•×™×§×˜ ×—×“×©
+  label_project_plural: ×¤×¨×•×™×§×˜×™×
+  label_x_projects:
+    zero:  ×œ×œ× ×¤×¨×•×™×§×˜×™×
+    one:   ×¤×¨×•×™×§×˜ ××—×“
+    other: "%{count} ×¤×¨×•×™×§×˜×™×"
+  label_project_all: ×›×œ ×”×¤×¨×•×™×§×˜×™×
+  label_project_latest: ×”×¤×¨×•×™×§×˜×™× ×”×—×“×©×™× ×‘×™×•×ª×¨
+  label_issue: × ×•×©×
+  label_issue_new: × ×•×©× ×—×“×©
+  label_issue_plural: × ×•×©××™×
+  label_issue_view_all: ×¦×¤×” ×‘×›×œ ×”× ×•×©××™×
+  label_issues_by: "× ×•×©××™× ×œ×¤×™ %{value}"
+  label_issue_added: × ×•×©× × ×•×¡×£
+  label_issue_updated: × ×•×©× ×¢×•×“×›×Ÿ
+  label_document: ×ž×¡×ž×š
+  label_document_new: ×ž×¡×ž×š ×—×“×©
+  label_document_plural: ×ž×¡×ž×›×™×
+  label_document_added: ×ž×¡×ž×š × ×•×¡×£
+  label_role: ×ª×¤×§×™×“
+  label_role_plural: ×ª×¤×§×™×“×™×
+  label_role_new: ×ª×¤×§×™×“ ×—×“×©
+  label_role_and_permissions: ×ª×¤×§×™×“×™× ×•×”×¨×©××•×ª
+  label_member: ×—×‘×¨
+  label_member_new: ×—×‘×¨ ×—×“×©
+  label_member_plural: ×—×‘×¨×™×
+  label_tracker: ×¡×™×•×•×’
+  label_tracker_plural: ×¡×™×•×•×’×™×
+  label_tracker_new: ×¡×™×•×•×’ ×—×“×©
+  label_workflow: ×–×¨×™×ž×ª ×¢×‘×•×“×”
+  label_issue_status: ×ž×¦×‘ × ×•×©×
+  label_issue_status_plural: ×ž×¦×‘×™ × ×•×©×
+  label_issue_status_new: ×ž×¦×‘ ×—×“×©
+  label_issue_category: ×§×˜×’×•×¨×™×ª × ×•×©×
+  label_issue_category_plural: ×§×˜×’×•×¨×™×•×ª × ×•×©×
+  label_issue_category_new: ×§×˜×’×•×¨×™×” ×—×“×©×”
+  label_custom_field: ×©×“×” ××™×©×™
+  label_custom_field_plural: ×©×“×•×ª ××™×©×™×™×
+  label_custom_field_new: ×©×“×” ××™×©×™ ×—×“×©
+  label_enumerations: ××™× ×•×ž×¨×¦×™×•×ª
+  label_enumeration_new: ×¢×¨×š ×—×“×©
+  label_information: ×ž×™×“×¢
+  label_information_plural: ×ž×™×“×¢
+  label_please_login: × × ×”×ª×—×‘×¨
+  label_register: ×”×¨×©×ž×”
+  label_login_with_open_id_option: ××• ×”×ª×—×‘×¨ ×‘××ž×¦×¢×•×ª OpenID
+  label_password_lost: ××‘×“×” ×”×¡×™×¡×ž×”?
+  label_home: ×“×£ ×”×‘×™×ª
+  label_my_page: ×”×“×£ ×©×œ×™
+  label_my_account: ×”×—×©×‘×•×Ÿ ×©×œ×™
+  label_my_projects: ×”×¤×¨×•×™×§×˜×™× ×©×œ×™
+  label_my_page_block: ×‘×œ×•×§ ×”×“×£ ×©×œ×™
+  label_administration: × ×™×”×•×œ
+  label_login: ×”×ª×—×‘×¨
+  label_logout: ×”×ª× ×ª×§
+  label_help: ×¢×–×¨×”
+  label_reported_issues: × ×•×©××™× ×©×“×•×•×—×•
+  label_assigned_to_me_issues: × ×•×©××™× ×©×”×•×¦×‘×• ×œ×™
+  label_last_login: ×”×ª×—×‘×¨×•×ª ××—×¨×•× ×”
+  label_registered_on: × ×¨×©× ×‘×ª××¨×™×š
+  label_activity: ×¤×¢×™×œ×•×ª
+  label_overall_activity: ×¤×¢×™×œ×•×ª ×›×•×œ×œ×ª
+  label_user_activity: "×”×¤×¢×™×œ×•×ª ×©×œ %{value}"
+  label_new: ×—×“×©
+  label_logged_as: ×ž×—×•×‘×¨ ×›
+  label_environment: ×¡×‘×™×‘×”
+  label_authentication: ×”×–×“×”×•×ª
+  label_auth_source: ×ž×§×•×¨ ×”×–×“×”×•×ª
+  label_auth_source_new: ×ž×§×•×¨ ×”×–×“×”×•×ª ×—×“×©
+  label_auth_source_plural: ×ž×§×•×¨×•×ª ×”×–×“×”×•×ª
+  label_subproject_plural: ×ª×ªÖ¾×¤×¨×•×™×§×˜×™×
+  label_subproject_new: ×ª×ªÖ¾×¤×¨×•×™×§×˜ ×—×“×©
+  label_and_its_subprojects: "%{value} ×•×›×œ ×ª×ª×™Ö¾×”×¤×¨×•×™×§×˜×™× ×©×œ×•"
+  label_min_max_length: ××•×¨×š ×ž×™× ×™×ž××œ×™ - ×ž×§×¡×™×ž××œ×™
+  label_list: ×¨×©×™×ž×”
+  label_date: ×ª××¨×™×š
+  label_integer: ×ž×¡×¤×¨ ×©×œ×
+  label_float: ×¦×£
+  label_boolean: ×¢×¨×š ×‘×•×œ×™×× ×™
+  label_string: ×˜×§×¡×˜
+  label_text: ×˜×§×¡×˜ ××¨×•×š
+  label_attribute: ×ª×›×•× ×”
+  label_attribute_plural: ×ª×›×•× ×•×ª
+  label_no_data: ××™×Ÿ ×ž×™×“×¢ ×œ×”×¦×™×’
+  label_change_status: ×©× ×” ×ž×¦×‘
+  label_history: ×”×™×¡×˜×•×¨×™×”
+  label_attachment: ×§×•×‘×¥
+  label_attachment_new: ×§×•×‘×¥ ×—×“×©
+  label_attachment_delete: ×ž×—×§ ×§×•×‘×¥
+  label_attachment_plural: ×§×‘×¦×™×
+  label_file_added: ×§×•×‘×¥ × ×•×¡×£
+  label_report: ×“×•"×—
+  label_report_plural: ×“×•"×—×•×ª
+  label_news: ×—×“×©×•×ª
+  label_news_new: ×”×•×¡×£ ×—×“×©×•×ª
+  label_news_plural: ×—×“×©×•×ª
+  label_news_latest: ×—×“×©×•×ª ××—×¨×•× ×•×ª
+  label_news_view_all: ×¦×¤×” ×‘×›×œ ×”×—×“×©×•×ª
+  label_news_added: ×—×“×©×•×ª × ×•×¡×¤×•
+  label_settings: ×”×’×“×¨×•×ª
+  label_overview: ×ž×‘×˜ ×¨×—×‘
+  label_version: ×’×™×¨×¡×”
+  label_version_new: ×’×™×¨×¡×” ×—×“×©×”
+  label_version_plural: ×’×™×¨×¡××•×ª
+  label_close_versions: ×¡×’×•×¨ ×’×™×¨×¡××•×ª ×©×”×•×©×œ×ž×•
+  label_confirmation: ××™×©×•×¨
+  label_export_to: ×™×¦× ×œ
+  label_read: ×§×¨×...
+  label_public_projects: ×¤×¨×•×™×§×˜×™× ×¤×•×ž×‘×™×™×
+  label_open_issues: ×¤×ª×•×—
+  label_open_issues_plural: ×¤×ª×•×—×™×
+  label_closed_issues: ×¡×’×•×¨
+  label_closed_issues_plural: ×¡×’×•×¨×™×
+  label_x_open_issues_abbr_on_total:
+    zero:  0 ×¤×ª×•×—×™× / %{total}
+    one:   1 ×¤×ª×•×— / %{total}
+    other: "%{count} ×¤×ª×•×—×™× / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 ×¤×ª×•×—×™×
+    one:   1 ×¤×ª×•×—
+    other: "%{count} ×¤×ª×•×—×™×"
+  label_x_closed_issues_abbr:
+    zero:  0 ×¡×’×•×¨×™×
+    one:   1 ×¡×’×•×¨
+    other: "%{count} ×¡×’×•×¨×™×"
+  label_total: ×¡×”"×›
+  label_permissions: ×”×¨×©××•×ª
+  label_current_status: ×ž×¦×‘ × ×•×›×—×™
+  label_new_statuses_allowed: ×ž×¦×‘×™× ×—×“×©×™× ××¤×©×¨×™×™×
+  label_all: ×”×›×œ
+  label_none: ×›×œ×•×
+  label_nobody: ××£ ××—×“
+  label_next: ×”×‘×
+  label_previous: ×”×§×•×“×
+  label_used_by: ×‘×©×™×ž×•×© ×¢"×™
+  label_details: ×¤×¨×˜×™×
+  label_add_note: ×”×•×¡×£ ×”×¢×¨×”
+  label_per_page: ×œ×›×œ ×“×£
+  label_calendar: ×œ×•×— ×©× ×”
+  label_months_from: ×—×•×“×©×™× ×ž
+  label_gantt: ×’×× ×˜
+  label_internal: ×¤× ×™×ž×™
+  label_last_changes: "%{count} ×©×™× ×•×™× ××—×¨×•× ×™×"
+  label_change_view_all: ×¦×¤×” ×‘×›×œ ×”×©×™× ×•×™×
+  label_personalize_page: ×”×ª×× ××™×©×™×ª ×“×£ ×–×”
+  label_comment: ×ª×’×•×‘×”
+  label_comment_plural: ×ª×’×•×‘×•×ª
+  label_x_comments:
+    zero: ××™×Ÿ ×”×¢×¨×•×ª
+    one: ×”×¢×¨×” ××—×ª
+    other: "%{count} ×”×¢×¨×•×ª"
+  label_comment_add: ×”×•×¡×£ ×ª×’×•×‘×”
+  label_comment_added: ×ª×’×•×‘×” × ×•×¡×¤×”
+  label_comment_delete: ×ž×—×§ ×ª×’×•×‘×•×ª
+  label_query: ×©××™×œ×ª×” ××™×©×™×ª
+  label_query_plural: ×©××™×œ×ª×•×ª ××™×©×™×•×ª
+  label_query_new: ×©××™×œ×ª×” ×—×“×©×”
+  label_filter_add: ×”×•×¡×£ ×ž×¡× ×Ÿ
+  label_filter_plural: ×ž×¡× × ×™×
+  label_equals: ×”×•×
+  label_not_equals: ×”×•× ×œ×
+  label_in_less_than: ×‘×¤×—×•×ª ×ž
+  label_in_more_than: ×‘×™×•×ª×¨ ×ž
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  label_in: ×‘
+  label_today: ×”×™×•×
+  label_all_time: ×ª×ž×™×“
+  label_yesterday: ××ª×ž×•×œ
+  label_this_week: ×”×©×‘×•×¢
+  label_last_week: ×”×©×‘×•×¢ ×©×¢×‘×¨
+  label_last_n_days: "×‘Ö¾%{count} ×™×ž×™× ××—×¨×•× ×™×"
+  label_this_month: ×”×—×•×“×©
+  label_last_month: ×—×•×“×© ×©×¢×‘×¨
+  label_this_year: ×”×©× ×”
+  label_date_range: ×˜×•×•×— ×ª××¨×™×›×™×
+  label_less_than_ago: ×¤×—×•×ª ×ž
+  label_more_than_ago: ×™×•×ª×¨ ×ž
+  label_ago: ×œ×¤× ×™
+  label_contains: ×ž×›×™×œ
+  label_not_contains: ×œ× ×ž×›×™×œ
+  label_day_plural: ×™×ž×™×
+  label_repository: ×ž××’×¨
+  label_repository_plural: ×ž××’×¨×™×
+  label_browse: ×¡×™×™×¨
+  label_branch: ×¢× ×£
+  label_tag: ×¡×™×ž×•×Ÿ
+  label_revision: ×ž×”×“×•×¨×”
+  label_revision_plural: ×ž×”×“×•×¨×•×ª
+  label_revision_id: ×ž×”×“×•×¨×” %{value}
+  label_associated_revisions: ×ž×”×“×•×¨×•×ª ×§×©×•×¨×•×ª
+  label_added: × ×•×¡×£
+  label_modified: ×©×•× ×”
+  label_copied: ×”×•×¢×ª×§
+  label_renamed: ×”×©× ×©×•× ×”
+  label_deleted: × ×ž×—×§
+  label_latest_revision: ×ž×”×“×•×¨×” ××—×¨×•× ×”
+  label_latest_revision_plural: ×ž×”×“×•×¨×•×ª ××—×¨×•× ×•×ª
+  label_view_revisions: ×¦×¤×” ×‘×ž×”×“×•×¨×•×ª
+  label_view_all_revisions: ×¦×¤×” ×‘×›×œ ×”×ž×”×“×•×¨×•×ª
+  label_max_size: ×’×•×“×œ ×ž×§×¡×™×ž××œ×™
+  label_sort_highest: ×”×–×– ×œ×¨××©×™×ª
+  label_sort_higher: ×”×–×– ×œ×ž×¢×œ×”
+  label_sort_lower: ×”×–×– ×œ×ž×˜×”
+  label_sort_lowest: ×”×–×– ×œ×ª×—×ª×™×ª
+  label_roadmap: ×ž×¤×ª ×”×“×¨×›×™×
+  label_roadmap_due_in: "× ×’×ž×¨ ×‘×¢×•×“ %{value}"
+  label_roadmap_overdue: "%{value} ×ž××—×¨"
+  label_roadmap_no_issues: ××™×Ÿ × ×•×©××™× ×œ×’×™×¨×¡×” ×–×•
+  label_search: ×—×¤×©
+  label_result_plural: ×ª×•×¦××•×ª
+  label_all_words: ×›×œ ×”×ž×™×œ×™×
+  label_wiki: Wiki
+  label_wiki_edit: ×¢×¨×•×š wiki
+  label_wiki_edit_plural: ×¢×¨×™×›×•×ª wiki
+  label_wiki_page: ×“×£ Wiki
+  label_wiki_page_plural: ×“×¤×™ wiki
+  label_index_by_title: ×¡×“×¨ ×¢×œ ×¤×™ ×›×•×ª×¨×ª
+  label_index_by_date: ×¡×“×¨ ×¢×œ ×¤×™ ×ª××¨×™×š
+  label_current_version: ×’×™×¨×¡×” × ×•×›×—×™×ª
+  label_preview: ×ª×¦×•×’×” ×ž×§×“×™×ž×”
+  label_feed_plural: ×”×–× ×•×ª
+  label_changes_details: ×¤×™×¨×•×˜ ×›×œ ×”×©×™× ×•×™×™×
+  label_issue_tracking: ×ž×¢×§×‘ ××—×¨ × ×•×©××™×
+  label_spent_time: ×–×ž×Ÿ ×©×”×•×©×§×¢
+  label_overall_spent_time: ×–×ž×Ÿ ×©×”×•×©×§×¢ ×¡×”"×›
+  label_f_hour: "%{value} ×©×¢×”"
+  label_f_hour_plural: "%{value} ×©×¢×•×ª"
+  label_time_tracking: ×ž×¢×§×‘ ×–×ž× ×™×
+  label_change_plural: ×©×™× ×•×™×™×
+  label_statistics: ×¡×˜×˜×™×¡×˜×™×§×•×ª
+  label_commits_per_month: ×”×¤×§×“×•×ª ×œ×¤×™ ×—×•×“×©
+  label_commits_per_author: ×”×¤×§×“×•×ª ×œ×¤×™ ×›×•×ª×‘
+  label_view_diff: ×¦×¤×” ×‘×©×™× ×•×™×™×
+  label_diff_inline: ×‘×ª×•×š ×”×©×•×¨×”
+  label_diff_side_by_side: ×¦×“ ×œ×¦×“
+  label_options: ××¤×©×¨×•×™×•×ª
+  label_copy_workflow_from: ×”×¢×ª×§ ×–×™×¨×ž×ª ×¢×‘×•×“×” ×ž
+  label_permissions_report: ×“×•"×— ×”×¨×©××•×ª
+  label_watched_issues: × ×•×©××™× ×©× ×¦×¤×•
+  label_related_issues: × ×•×©××™× ×§×©×•×¨×™×
+  label_applied_status: ×ž×¦×‘ ×ž×•×—×œ
+  label_loading: ×˜×•×¢×Ÿ...
+  label_relation_new: ×§×©×¨ ×—×“×©
+  label_relation_delete: ×ž×—×§ ×§×©×¨
+  label_relates_to: ×§×©×•×¨ ×œ
+  label_duplicates: ×ž×›×¤×™×œ ××ª
+  label_duplicated_by: ×©×•×›×¤×œ ×¢"×™
+  label_blocks: ×—×•×¡× ××ª
+  label_blocked_by: ×—×¡×•× ×¢"×™
+  label_precedes: ×ž×§×“×™× ××ª
+  label_follows: ×¢×•×§×‘ ××—×¨×™
+  label_end_to_start: ×ž×”×ª×—×œ×” ×œ×¡×•×£
+  label_end_to_end: ×ž×”×¡×•×£ ×œ×¡×•×£
+  label_start_to_start: ×ž×”×ª×—×œ×” ×œ×”×ª×—×œ×”
+  label_start_to_end: ×ž×”×ª×—×œ×” ×œ×¡×•×£
+  label_stay_logged_in: ×”×©××¨ ×ž×—×•×‘×¨
+  label_disabled: ×ž×‘×•×˜×œ
+  label_show_completed_versions: ×”×¦×’ ×’×™×¨×¡××•×ª ×’×ž×•×¨×•×ª
+  label_me: ×× ×™
+  label_board: ×¤×•×¨×•×
+  label_board_new: ×¤×•×¨×•× ×—×“×©
+  label_board_plural: ×¤×•×¨×•×ž×™×
+  label_board_locked: × ×¢×•×œ
+  label_board_sticky: ×“×‘×™×§
+  label_topic_plural: × ×•×©××™×
+  label_message_plural: ×”×•×“×¢×•×ª
+  label_message_last: ×”×•×“×¢×” ××—×¨×•× ×”
+  label_message_new: ×”×•×“×¢×” ×—×“×©×”
+  label_message_posted: ×”×•×“×¢×” × ×•×¡×¤×”
+  label_reply_plural: ×”×©×‘×•×ª
+  label_send_information: ×©×œ×— ×ž×™×“×¢ ×¢×œ ×—×©×‘×•×Ÿ ×œ×ž×©×ª×ž×©
+  label_year: ×©× ×”
+  label_month: ×—×•×“×©
+  label_week: ×©×‘×•×¢
+  label_date_from: ×ž×ª××¨×™×š
+  label_date_to: ×¢×“
+  label_language_based: ×ž×‘×•×¡×¡ ×©×¤×”
+  label_sort_by: "×ž×™×™×Ÿ ×œ×¤×™ %{value}"
+  label_send_test_email: ×©×œ×— ×“×•×"×œ ×‘×“×™×§×”
+  label_feeds_access_key: ×ž×¤×ª×— ×’×™×©×” ×œÖ¾RSS
+  label_missing_feeds_access_key: ×—×¡×¨ ×ž×¤×ª×— ×’×™×©×” ×œÖ¾RSS
+  label_feeds_access_key_created_on: "×ž×¤×ª×— ×”×–× ×ª RSS × ×•×¦×¨ ×œ×¤× ×™%{value}"
+  label_module_plural: ×ž×•×“×•×œ×™×
+  label_added_time_by: '× ×•×¡×£ ×¢"×™ %{author} ×œ×¤× ×™ %{age}'
+  label_updated_time_by: '×¢×•×“×›×Ÿ ×¢"×™ %{author} ×œ×¤× ×™ %{age}'
+  label_updated_time: "×¢×•×“×›×Ÿ ×œ×¤× ×™ %{value} "
+  label_jump_to_a_project: ×§×¤×•×¥ ×œ×¤×¨×•×™×§×˜...
+  label_file_plural: ×§×‘×¦×™×
+  label_changeset_plural: ×¡×“×¨×•×ª ×©×™× ×•×™×™×
+  label_default_columns: ×¢×ž×•×“×ª ×‘×¨×™×¨×ª ×ž×—×“×œ
+  label_no_change_option: (××™×Ÿ ×©×™× ×•×™×)
+  label_bulk_edit_selected_issues: ×¢×¨×•×š ××ª ×”× ×•×©××™× ×”×ž×¡×•×ž× ×™×
+  label_theme: ×¢×¨×›×ª × ×•×©×
+  label_default: ×‘×¨×™×¨×ª ×ž×—×“×œ
+  label_search_titles_only: ×—×¤×© ×‘×›×•×ª×¨×•×ª ×‘×œ×‘×“
+  label_user_mail_option_all: "×œ×›×œ ××™×¨×•×¢ ×‘×›×œ ×”×¤×¨×•×™×§×˜×™× ×©×œ×™"
+  label_user_mail_option_selected: "×œ×›×œ ××™×¨×•×¢ ×‘×¤×¨×•×™×§×˜×™× ×©×‘×—×¨×ª×™ ×‘×œ×‘×“..."
+  label_user_mail_option_only_my_events: ×¢×‘×•×¨ ×“×‘×¨×™× ×©×× ×™ ×¦×•×¤×” ××• ×ž×¢×•×¨×‘ ×‘×”× ×‘×œ×‘×“
+  label_user_mail_option_only_assigned: ×¢×‘×•×¨ ×“×‘×¨×™× ×©×× ×™ ××—×¨××™ ×¢×œ×™×”× ×‘×œ×‘×“
+  label_user_mail_option_only_owner: ×¢×‘×•×¨ ×“×‘×¨×™× ×©×× ×™ ×”×‘×¢×œ×™× ×©×œ×”× ×‘×œ×‘×“
+  label_user_mail_no_self_notified: "×× ×™ ×œ× ×¨×•×¦×” ×©×™×•×“×™×¢×• ×œ×™ ×¢×œ ×©×™× ×•×™×™× ×©×× ×™ ×ž×‘×¦×¢"
+  label_registration_activation_by_email: ×”×¤×¢×œ ×—×©×‘×•×Ÿ ×‘××ž×¦×¢×•×ª ×“×•×"×œ
+  label_registration_manual_activation: ×”×¤×¢×œ×ª ×—×©×‘×•×Ÿ ×™×“× ×™×ª
+  label_registration_automatic_activation: ×”×¤×¢×œ×ª ×—×©×‘×•×Ÿ ××•×˜×•×ž×˜×™×ª
+  label_display_per_page: "×‘×›×œ ×“×£: %{value} ×ª×•×¦××•×ª"
+  label_age: ×’×™×œ
+  label_change_properties: ×©× ×” ×ž××¤×™×™× ×™×
+  label_general: ×›×œ×œ×™
+  label_more: ×¢×•×“
+  label_scm: ×ž×¢×¨×›×ª × ×™×”×•×œ ×ª×¦×•×¨×”
+  label_plugins: ×ª×•×¡×¤×™×
+  label_ldap_authentication: ×”×–×“×”×•×ª LDAP
+  label_downloads_abbr: D/L
+  label_optional_description: ×ª×™××•×¨ ×¨×©×•×ª
+  label_add_another_file: ×”×•×¡×£ ×¢×•×“ ×§×•×‘×¥
+  label_preferences: ×”×¢×“×¤×•×ª
+  label_chronological_order: ×‘×¡×“×¨ ×›×¨×•× ×•×œ×•×’×™
+  label_reverse_chronological_order: ×‘×¡×“×¨ ×›×¨×•× ×•×œ×•×’×™ ×”×¤×•×š
+  label_planning: ×ª×›× ×•×Ÿ
+  label_incoming_emails: ×“×•×"×œ × ×›× ×¡
+  label_generate_key: ×¦×•×¨ ×ž×¤×ª×—
+  label_issue_watchers: ×¦×•×¤×™×
+  label_example: ×“×•×’×ž×
+  label_display: ×ª×¦×•×’×”
+  label_sort: ×ž×™×•×Ÿ
+  label_ascending: ×‘×¡×“×¨ ×¢×•×œ×”
+  label_descending: ×‘×¡×“×¨ ×™×•×¨×“
+  label_date_from_to: '×ž×ª××¨×™×š %{start} ×•×¢×“ ×ª××¨×™×š %{end}'
+  label_wiki_content_added: × ×•×¡×£ ×“×£ ×œÖ¾wiki
+  label_wiki_content_updated: ×“×£ wiki ×¢×•×“×›×Ÿ
+  label_group: ×§×‘×•×¦×”
+  label_group_plural: ×§×‘×•×¦×•×ª
+  label_group_new: ×§×‘×•×¦×” ×—×“×©×”
+  label_time_entry_plural: ×–×ž×Ÿ ×©×”×•×©×§×¢
+  label_version_sharing_none: ×œ× ×ž×©×•×ª×£
+  label_version_sharing_descendants: ×¢× ×¤×¨×•×™×§×˜×™× ×‘× ×™×
+  label_version_sharing_hierarchy: ×¢× ×”×™×¨×¨×›×™×ª ×”×¤×¨×•×™×§×˜×™×
+  label_version_sharing_tree: ×¢× ×¢×¥ ×”×¤×¨×•×™×§×˜
+  label_version_sharing_system: ×¢× ×›×œ ×”×¤×¨×•×™×§×˜×™×
+  label_update_issue_done_ratios: ×¢×“×›×Ÿ ××—×•×– ×”×ª×§×“×ž×•×ª ×œ× ×•×©×
+  label_copy_source: ×ž×§×•×¨
+  label_copy_target: ×™×¢×“
+  label_copy_same_as_target: ×–×”×” ×œ×™×¢×“
+  label_display_used_statuses_only: ×”×¦×’ ×¨×§ ××ª ×”×ž×¦×‘×™× ×‘×©×™×ž×•×© ×œ×¡×™×•×•×’ ×–×”
+  label_api_access_key: ×ž×¤×ª×— ×’×™×©×” ×œÖ¾API
+  label_missing_api_access_key: ×—×¡×¨ ×ž×¤×ª×— ×’×™×©×” ×œÖ¾API
+  label_api_access_key_created_on: '×ž×¤×ª×— ×’×™×©×” ×œÖ¾API × ×•×¦×¨ ×œ×¤× ×™ %{value}'
+  label_profile: ×¤×¨×•×¤×™×œ
+  label_subtask_plural: ×ª×ª×™Ö¾×ž×©×™×ž×•×ª
+  label_project_copy_notifications: ×©×œ×— ×”×ª×¨××•×ª ×“×•××¨ ×‘×ž×”×œ×š ×”×¢×ª×§×ª ×”×¤×¨×•×™×§×˜
+
+  button_login: ×”×ª×—×‘×¨
+  button_submit: ××©×¨
+  button_save: ×©×ž×•×¨
+  button_check_all: ×‘×—×¨ ×”×›×œ
+  button_uncheck_all: ×‘×—×¨ ×›×œ×•×
+  button_delete: ×ž×—×§
+  button_create: ×¦×•×¨
+  button_create_and_continue: ×¦×•×¨ ×•×¤×ª×— ×—×“×©
+  button_test: ×‘×“×•×§
+  button_edit: ×¢×¨×•×š
+  button_edit_associated_wikipage: "×¢×¨×•×š ×“×£ wiki ×ž×§×•×©×¨: %{page_title}"
+  button_add: ×”×•×¡×£
+  button_change: ×©× ×”
+  button_apply: ×”×—×œ
+  button_clear: × ×§×”
+  button_lock: × ×¢×œ
+  button_unlock: ×‘×˜×œ × ×¢×™×œ×”
+  button_download: ×”×•×¨×“
+  button_list: ×¨×©×™×ž×”
+  button_view: ×¦×¤×”
+  button_move: ×”×–×–
+  button_move_and_follow: ×”×¢×‘×¨ ×•×¢×§×•×‘
+  button_back: ×”×§×•×“×
+  button_cancel: ×‘×˜×œ
+  button_activate: ×”×¤×¢×œ
+  button_sort: ×ž×™×™×Ÿ
+  button_log_time: ×¨×™×©×•× ×–×ž× ×™×
+  button_rollback: ×—×–×•×¨ ×œ×ž×”×“×•×¨×” ×–×•
+  button_watch: ×¦×¤×”
+  button_unwatch: ×‘×˜×œ ×¦×¤×™×”
+  button_reply: ×”×©×‘
+  button_archive: ××¨×›×™×•×Ÿ
+  button_unarchive: ×”×•×¦× ×ž×”××¨×›×™×•×Ÿ
+  button_reset: ××¤×¡
+  button_rename: ×©× ×” ×©×
+  button_change_password: ×©× ×” ×¡×™×¡×ž×”
+  button_copy: ×”×¢×ª×§
+  button_copy_and_follow: ×”×¢×ª×§ ×•×¢×§×•×‘
+  button_annotate: ×”×•×¡×£ ×ª×™××•×¨ ×ž×¡×’×¨×ª
+  button_update: ×¢×“×›×Ÿ
+  button_configure: ××¤×©×¨×•×™×•×ª
+  button_quote: ×¦×˜×˜
+  button_duplicate: ×©×›×¤×œ
+  button_show: ×”×¦×’
+
+  status_active: ×¤×¢×™×œ
+  status_registered: ×¨×©×•×
+  status_locked: × ×¢×•×œ
+
+  version_status_open: ×¤×ª×•×—
+  version_status_locked: × ×¢×•×œ
+  version_status_closed: ×¡×’×•×¨
+
+  field_active: ×¤×¢×™×œ
+
+  text_select_mail_notifications: ×‘×—×¨ ×¤×¢×•×œ×ª ×©×‘×’×œ×œ×Ÿ ×™×©×œ×— ×“×•×"×œ.
+  text_regexp_info: ×›×’×•×Ÿ. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 ×ž×©×ž×¢×• ×œ×œ× ×”×’×‘×œ×•×ª
+  text_project_destroy_confirmation: ×”×× ××ª×” ×‘×˜×•×— ×©×‘×¨×¦×•× ×š ×œ×ž×—×•×§ ××ª ×”×¤×¨×•×™×§×˜ ×•××ª ×›×œ ×”×ž×™×“×¢ ×”×§×©×•×¨ ××œ×™×•?
+  text_subprojects_destroy_warning: "×ª×ªÖ¾×”×¤×¨×•×™×§×˜×™×: %{value} ×™×ž×—×§×• ×’× ×›×Ÿ."
+  text_workflow_edit: ×‘×—×¨ ×ª×¤×§×™×“ ×•×¡×™×•×•×’ ×›×“×™ ×œ×¢×¨×•×š ××ª ×–×¨×™×ž×ª ×”×¢×‘×•×“×”
+  text_are_you_sure: ×”×× ××ª×” ×‘×˜×•×—?
+  text_journal_changed: "%{label} ×”×©×ª× ×” ×ž%{old} ×œ%{new}"
+  text_journal_set_to: "%{label} × ×§×‘×¢ ×œ%{value}"
+  text_journal_deleted: "%{label} × ×ž×—×§ (%{old})"
+  text_journal_added: "%{label} %{value} × ×•×¡×£"
+  text_tip_issue_begin_day: ×ž×˜×œ×” ×”×ž×ª×—×™×œ×” ×”×™×•×
+  text_tip_issue_end_day: ×ž×˜×œ×” ×”×ž×¡×ª×™×™×ž×ª ×”×™×•×
+  text_tip_issue_begin_end_day: ×ž×˜×œ×” ×”×ž×ª×—×™×œ×” ×•×ž×¡×ª×™×™×ž×ª ×”×™×•×
+  text_caracters_maximum: "×ž×§×¡×™×ž×•× %{count} ×ª×•×•×™×."
+  text_caracters_minimum: "×—×™×™×‘ ×œ×”×™×•×ª ×œ×¤×—×•×ª ×‘××•×¨×š ×©×œ %{count} ×ª×•×•×™×."
+  text_length_between: "××•×¨×š ×‘×™×Ÿ %{min} ×œ %{max} ×ª×•×•×™×."
+  text_tracker_no_workflow: ×–×¨×™×ž×ª ×¢×‘×•×“×” ×œ× ×”×•×’×“×¨×” ×¢×‘×•×¨ ×¡×™×•×•×’ ×–×”
+  text_unallowed_characters: ×ª×•×•×™× ×œ× ×ž×•×¨×©×™×
+  text_comma_separated: ×”×›× ×¡×ª ×¢×¨×›×™× ×ž×¨×•×‘×™× ×ž×•×ª×¨×ª (×ž×•×¤×¨×“×™× ×‘×¤×¡×™×§×™×).
+  text_line_separated: × ×™×ª×Ÿ ×œ×”×–×™×Ÿ ×ž×¡×¤×¨ ×¢×¨×›×™× (×©×•×¨×” ××—×ª ×œ×›×œ ×¢×¨×š).
+  text_issues_ref_in_commit_messages: ×§×™×©×•×¨ ×•×ª×™×§×•× × ×•×©××™× ×‘×”×•×“×¢×•×ª ×”×¤×§×“×”
+  text_issue_added: "×”× ×•×©× %{id} ×“×•×•×— (×‘×™×“×™ %{author})."
+  text_issue_updated: "×”× ×•×©× %{id} ×¢×•×“×›×Ÿ (×‘×™×“×™ %{author})."
+  text_wiki_destroy_confirmation: ×”×× ××ª×” ×‘×˜×•×— ×©×‘×¨×¦×•× ×š ×œ×ž×—×•×§ ××ª ×”WIKI ×”×–×” ×•××ª ×›×œ ×ª×•×›× ×•?
+  text_issue_category_destroy_question: "×›×ž×” × ×•×©××™× (%{count}) ×ž×•×¦×‘×™× ×œ×§×˜×’×•×¨×™×” ×”×–×•. ×ž×” ×‘×¨×¦×•× ×š ×œ×¢×©×•×ª?"
+  text_issue_category_destroy_assignments: ×”×¡×¨ ×”×¦×‘×ª ×§×˜×’×•×¨×™×”
+  text_issue_category_reassign_to: ×”×¦×‘ ×ž×—×“×© ××ª ×”×§×˜×’×•×¨×™×” ×œ× ×•×©××™×
+  text_user_mail_option: "×‘×¤×¨×•×™×§×˜×™× ×©×œ× ×‘×—×¨×ª, ××ª×” ×¨×§ ×ª×§×‘×œ ×”×ª×¨×¢×•×ª ×¢×œ ×©××ª×” ×¦×•×¤×” ××• ×§×©×•×¨ ××œ×™×”× (×œ×“×•×’×ž×:× ×•×©××™× ×©××ª×” ×”×™×•×¦×¨ ×©×œ×”× ××• ××—×¨××™ ×¢×œ×™×”×)."
+  text_no_configuration_data: "×œ× ×”×•×’×“×¨×” ×ª×¦×•×¨×” ×¢×‘×•×¨ ×ª×¤×§×™×“×™×, ×¡×™×•×•×’×™×, ×ž×¦×‘×™ × ×•×©× ×•×–×¨×™×ž×ª ×¢×‘×•×“×”.\n×ž×•×ž×œ×¥ ×ž××“ ×œ×˜×¢×•×Ÿ ××ª ×ª×¦×•×¨×ª ×‘×¨×™×¨×ª ×”×ž×—×“×œ. ×ª×•×›×œ ×œ×©× ×•×ª×” ×ž××•×—×¨ ×™×•×ª×¨."
+  text_load_default_configuration: ×˜×¢×Ÿ ××ª ××¤×©×¨×•×™×•×ª ×‘×¨×™×¨×ª ×”×ž×—×“×œ
+  text_status_changed_by_changeset: "×”×•×—×œ ×‘×¡×“×¨×ª ×”×©×™× ×•×™×™× %{value}."
+  text_issues_destroy_confirmation: '×”×× ××ª×” ×‘×˜×•×— ×©×‘×¨×¦×•× ×š ×œ×ž×—×•×§ ××ª ×”× ×•×©××™×?'
+  text_select_project_modules: '×‘×—×¨ ×ž×•×“×•×œ×™× ×œ×”×—×™×œ ×¢×œ ×¤×¨×•×™×§×˜ ×–×”:'
+  text_default_administrator_account_changed: ×ž× ×”×œ ×”×ž×¢×¨×›×ª ×‘×¨×™×¨×ª ×”×ž×—×“×œ ×©×•× ×”
+  text_file_repository_writable: ×ž××’×¨ ×”×§×‘×¦×™× × ×™×ª×Ÿ ×œ×›×ª×™×‘×”
+  text_plugin_assets_writable: ×¡×¤×¨×™×ª × ×›×¡×™ ×ª×•×¡×¤×™× × ×™×ª× ×ª ×œ×›×ª×™×‘×”
+  text_rmagick_available: RMagick ×–×ž×™×Ÿ (×¨×©×•×ª)
+  text_destroy_time_entries_question: "%{hours} ×©×¢×•×ª ×“×•×•×—×• ×¢×œ ×”× ×•×©××™× ×©××ª×” ×¢×•×ž×“ ×œ×ž×—×•×§. ×ž×” ×‘×¨×¦×•× ×š ×œ×¢×©×•×ª?"
+  text_destroy_time_entries: ×ž×—×§ ×©×¢×•×ª ×©×“×•×•×—×•
+  text_assign_time_entries_to_project: ×”×¦×‘ ×©×¢×•×ª ×©×“×•×•×—×• ×œ×¤×¨×•×™×§×˜ ×”×–×”
+  text_reassign_time_entries: '×”×¦×‘ ×ž×—×“×© ×©×¢×•×ª ×©×“×•×•×—×• ×œ×¤×¨×•×™×§×˜ ×”×–×”:'
+  text_user_wrote: "%{value} ×›×ª×‘:"
+  text_enumeration_destroy_question: "%{count} ××•×‘×™×§×˜×™× ×ž×•×¦×‘×™× ×œ×¢×¨×š ×–×”."
+  text_enumeration_category_reassign_to: '×”×¦×‘ ×ž×—×“×© ×œ×¢×¨×š ×”×–×”:'
+  text_email_delivery_not_configured: '×œ× × ×§×‘×¢×” ×ª×¦×•×¨×” ×œ×©×œ×™×—×ª ×“×•××¨, ×•×”×”×ª×¨××•×ª ×›×‘×•×™×•×ª.\n×§×‘×¢ ××ª ×ª×¦×•×¨×ª ×©×¨×ª ×”Ö¾SMTP ×‘×§×•×‘×¥ /etc/redmine/&lt;instance&gt;/configuration.yml ×•×”×ª×—×œ ××ª ×”××¤×œ×™×§×¦×™×” ×ž×—×“×© ×¢"×ž ×œ××¤×©×¨ ××•×ª×.'
+  text_repository_usernames_mapping: "×‘×—×¨ ××• ×¢×“×›×Ÿ ××ª ×ž×©×ª×ž×© Redmine ×”×ž×ž×•×¤×” ×œ×›×œ ×©× ×ž×©×ª×ž×© ×‘×™×•×ž×Ÿ ×”×ž××’×¨.\n×ž×©×ª×ž×©×™× ×‘×¢×œ×™ ×©× ××• ×›×ª×•×‘×ª ×“×•××¨ ×–×”×” ×‘Ö¾Redmine ×•×‘×ž××’×¨ ×ž×ž×•×¤×™× ×‘××•×¤×Ÿ ××•×˜×•×ž×˜×™."
+  text_diff_truncated: '... ×”×©×™× ×•×™×™× ×¢×•×‘×¨×™× ××ª ×ž×¡×¤×¨ ×”×©×•×¨×•×ª ×”×ž×™×¨×‘×™ ×œ×ª×¦×•×’×”, ×•×œ×›×Ÿ ×”× ×§×•×¦×¦×•.'
+  text_custom_field_possible_values_info: ×©×•×¨×” ××—×ª ×œ×›×œ ×¢×¨×š
+  text_wiki_page_destroy_question: ×œ×“×£ ×–×” ×™×© %{descendants} ×“×¤×™× ×‘× ×™× ×•×ª×œ×•×™×™×. ×ž×” ×‘×¨×¦×•× ×š ×œ×¢×©×•×ª?
+  text_wiki_page_nullify_children: ×”×©××¨ ×“×¤×™× ×‘× ×™× ×›×“×¤×™× ×¨××©×™×™×
+  text_wiki_page_destroy_children: ×ž×—×§ ××ª ×”×“×¤×™× ×”×‘× ×™× ×•××ª ×›×œ ×”×ª×œ×•×™×™× ×‘×”×
+  text_wiki_page_reassign_children: ×”×¦×‘ ×ž×—×“×© ×“×¤×™× ×‘× ×™× ×œ×“×£ ×”××‘ ×”× ×•×›×—×™
+  text_own_membership_delete_confirmation: |-
+    ×‘×›×•×•× ×ª×š ×œ×ž×—×•×§ ×—×œ×§ ××• ××ª ×›×œ ×”×”×¨×©××•×ª ×©×œ×š. ×œ××—×¨ ×ž×›×Ÿ ×œ× ×ª×•×›×œ ×™×•×ª×¨ ×œ×¢×¨×•×š ×¤×¨×•×™×§×˜ ×–×”.
+    ×”×× ××ª×” ×‘×˜×•×— ×©×‘×¨×¦×•× ×š ×œ×”×ž×©×™×š?
+  text_zoom_in: ×”×ª×§×¨×‘
+  text_zoom_out: ×”×ª×¨×—×§
+
+  default_role_manager: ×ž× ×”×œ
+  default_role_developer: ×ž×¤×ª×—
+  default_role_reporter: ×ž×“×•×•×—
+  default_tracker_bug: ×ª×§×œ×”
+  default_tracker_feature: ×™×›×•×œ×ª
+  default_tracker_support: ×ª×ž×™×›×”
+  default_issue_status_new: ×—×“×©
+  default_issue_status_in_progress: ×‘×¢×‘×•×“×”
+  default_issue_status_resolved: × ×¤×ª×¨
+  default_issue_status_feedback: ×ž×©×•×‘
+  default_issue_status_closed: ×¡×’×•×¨
+  default_issue_status_rejected: × ×“×—×”
+  default_doc_category_user: ×ª×™×¢×•×“ ×ž×©×ª×ž×©
+  default_doc_category_tech: ×ª×™×¢×•×“ ×˜×›× ×™
+  default_priority_low: × ×ž×•×›×”
+  default_priority_normal: ×¨×’×™×œ×”
+  default_priority_high: ×’×‘×•×”×”
+  default_priority_urgent: ×“×—×•×¤×”
+  default_priority_immediate: ×ž×™×“×™×ª
+  default_activity_design: ×¢×™×¦×•×‘
+  default_activity_development: ×¤×™×ª×•×—
+
+  enumeration_issue_priorities: ×¢×“×™×¤×•×ª × ×•×©××™×
+  enumeration_doc_categories: ×§×˜×’×•×¨×™×•×ª ×ž×¡×ž×›×™×
+  enumeration_activities: ×¤×¢×™×œ×•×™×•×ª (×ž×¢×§×‘ ××—×¨ ×–×ž× ×™×)
+  enumeration_system_activity: ×¤×¢×™×œ×•×ª ×ž×¢×¨×›×ª
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: ×§×™×“×•×“ ×”×•×“×¢×•×ª ×”×¤×§×“×”
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 × ×•×©×
+    one:   1 × ×•×©×
+    other: "%{count} × ×•×©××™×"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: ×”×›×œ
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: ×¢× ×¤×¨×•×™×§×˜×™× ×‘× ×™×
+  label_cross_project_tree: ×¢× ×¢×¥ ×”×¤×¨×•×™×§×˜
+  label_cross_project_hierarchy: ×¢× ×”×™×¨×¨×›×™×ª ×”×¤×¨×•×™×§×˜×™×
+  label_cross_project_system: ×¢× ×›×œ ×”×¤×¨×•×™×§×˜×™×
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: ×¡×”"×›
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/17/175ce98d0f45b612d93a4554fb4f76c1be18c0ff.svn-base
--- a/.svn/pristine/17/175ce98d0f45b612d93a4554fb4f76c1be18c0ff.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../../config/boot',  __FILE__)
-require 'commands/performance/benchmarker'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/17/176d1dc144c5bd598057e3a7c94346dee9aedc08.svn-base
--- /dev/null
+++ b/.svn/pristine/17/176d1dc144c5bd598057e3a7c94346dee9aedc08.svn-base
@@ -0,0 +1,13 @@
+class AddViewIssuesPermission < ActiveRecord::Migration
+  def self.up
+    Role.all.each do |r|
+      r.add_permission!(:view_issues)
+    end
+  end
+
+  def self.down
+    Role.all.each do |r|
+      r.remove_permission!(:view_issues)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/17/1786faee3d0cf0b377ade4249d7c22ac019c3500.svn-base
--- /dev/null
+++ b/.svn/pristine/17/1786faee3d0cf0b377ade4249d7c22ac019c3500.svn-base
@@ -0,0 +1,356 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'diff'
+
+# The WikiController follows the Rails REST controller pattern but with
+# a few differences
+#
+# * index - shows a list of WikiPages grouped by page or date
+# * new - not used
+# * create - not used
+# * show - will also show the form for creating a new wiki page
+# * edit - used to edit an existing or new page
+# * update - used to save a wiki page update to the database, including new pages
+# * destroy - normal
+#
+# Other member and collection methods are also used
+#
+# TODO: still being worked on
+class WikiController < ApplicationController
+  default_search_scope :wiki_pages
+  before_filter :find_wiki, :authorize
+  before_filter :find_existing_or_new_page, :only => [:show, :edit, :update]
+  before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version]
+  accept_api_auth :index, :show, :update, :destroy
+  before_filter :find_attachments, :only => [:preview]
+
+  helper :attachments
+  include AttachmentsHelper
+  helper :watchers
+  include Redmine::Export::PDF
+
+  # List of pages, sorted alphabetically and by parent (hierarchy)
+  def index
+    load_pages_for_index
+
+    respond_to do |format|
+      format.html {
+        @pages_by_parent_id = @pages.group_by(&:parent_id)
+      }
+      format.api
+    end
+  end
+
+  # List of page, by last update
+  def date_index
+    load_pages_for_index
+    @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
+  end
+
+  # display a page (in editing mode if it doesn't exist)
+  def show
+    if @page.new_record?
+      if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? && !api_request?
+        edit
+        render :action => 'edit'
+      else
+        render_404
+      end
+      return
+    end
+    if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
+      deny_access
+      return
+    end
+    @content = @page.content_for_version(params[:version])
+    if User.current.allowed_to?(:export_wiki_pages, @project)
+      if params[:format] == 'pdf'
+        send_data(wiki_page_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf")
+        return
+      elsif params[:format] == 'html'
+        export = render_to_string :action => 'export', :layout => false
+        send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
+        return
+      elsif params[:format] == 'txt'
+        send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
+        return
+      end
+    end
+    @editable = editable?
+    @sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) &&
+      @content.current_version? &&
+      Redmine::WikiFormatting.supports_section_edit?
+
+    respond_to do |format|
+      format.html
+      format.api
+    end
+  end
+
+  # edit an existing page or a new one
+  def edit
+    return render_403 unless editable?
+    if @page.new_record?
+      @page.content = WikiContent.new(:page => @page)
+      if params[:parent].present?
+        @page.parent = @page.wiki.find_page(params[:parent].to_s)
+      end
+    end
+
+    @content = @page.content_for_version(params[:version])
+    @content.text = initial_page_content(@page) if @content.text.blank?
+    # don't keep previous comment
+    @content.comments = nil
+
+    # To prevent StaleObjectError exception when reverting to a previous version
+    @content.version = @page.content.version
+
+    @text = @content.text
+    if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
+      @section = params[:section].to_i
+      @text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section)
+      render_404 if @text.blank?
+    end
+  end
+
+  # Creates a new page or updates an existing one
+  def update
+    return render_403 unless editable?
+    was_new_page = @page.new_record?
+    @page.content = WikiContent.new(:page => @page) if @page.new_record?
+    @page.safe_attributes = params[:wiki_page]
+
+    @content = @page.content
+    content_params = params[:content]
+    if content_params.nil? && params[:wiki_page].is_a?(Hash)
+      content_params = params[:wiki_page].slice(:text, :comments, :version)
+    end
+    content_params ||= {}
+
+    @content.comments = content_params[:comments]
+    @text = content_params[:text]
+    if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
+      @section = params[:section].to_i
+      @section_hash = params[:section_hash]
+      @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash)
+    else
+      @content.version = content_params[:version] if content_params[:version]
+      @content.text = @text
+    end
+    @content.author = User.current
+
+    if @page.save_with_content
+      attachments = Attachment.attach_files(@page, params[:attachments])
+      render_attachment_warning_if_needed(@page)
+      call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
+
+      respond_to do |format|
+        format.html { redirect_to project_wiki_page_path(@project, @page.title) }
+        format.api {
+          if was_new_page
+            render :action => 'show', :status => :created, :location => project_wiki_page_path(@project, @page.title)
+          else
+            render_api_ok
+          end
+        }
+      end
+    else
+      respond_to do |format|
+        format.html { render :action => 'edit' }
+        format.api { render_validation_errors(@content) }
+      end
+    end
+
+  rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError
+    # Optimistic locking exception
+    respond_to do |format|
+      format.html {
+        flash.now[:error] = l(:notice_locking_conflict)
+        render :action => 'edit'
+      }
+      format.api { render_api_head :conflict }
+    end
+  rescue ActiveRecord::RecordNotSaved
+    respond_to do |format|
+      format.html { render :action => 'edit' }
+      format.api { render_validation_errors(@content) }
+    end
+  end
+
+  # rename a page
+  def rename
+    return render_403 unless editable?
+    @page.redirect_existing_links = true
+    # used to display the *original* title if some AR validation errors occur
+    @original_title = @page.pretty_title
+    if request.post? && @page.update_attributes(params[:wiki_page])
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to project_wiki_page_path(@project, @page.title)
+    end
+  end
+
+  def protect
+    @page.update_attribute :protected, params[:protected]
+    redirect_to project_wiki_page_path(@project, @page.title)
+  end
+
+  # show page history
+  def history
+    @version_count = @page.content.versions.count
+    @version_pages = Paginator.new @version_count, per_page_option, params['page']
+    # don't load text
+    @versions = @page.content.versions.
+      select("id, author_id, comments, updated_on, version").
+      reorder('version DESC').
+      limit(@version_pages.per_page + 1).
+      offset(@version_pages.offset).
+      all
+
+    render :layout => false if request.xhr?
+  end
+
+  def diff
+    @diff = @page.diff(params[:version], params[:version_from])
+    render_404 unless @diff
+  end
+
+  def annotate
+    @annotate = @page.annotate(params[:version])
+    render_404 unless @annotate
+  end
+
+  # Removes a wiki page and its history
+  # Children can be either set as root pages, removed or reassigned to another parent page
+  def destroy
+    return render_403 unless editable?
+
+    @descendants_count = @page.descendants.size
+    if @descendants_count > 0
+      case params[:todo]
+      when 'nullify'
+        # Nothing to do
+      when 'destroy'
+        # Removes all its descendants
+        @page.descendants.each(&:destroy)
+      when 'reassign'
+        # Reassign children to another parent page
+        reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
+        return unless reassign_to
+        @page.children.each do |child|
+          child.update_attribute(:parent, reassign_to)
+        end
+      else
+        @reassignable_to = @wiki.pages - @page.self_and_descendants
+        # display the destroy form if it's a user request
+        return unless api_request?
+      end
+    end
+    @page.destroy
+    respond_to do |format|
+      format.html { redirect_to project_wiki_index_path(@project) }
+      format.api { render_api_ok }
+    end
+  end
+
+  def destroy_version
+    return render_403 unless editable?
+
+    @content = @page.content_for_version(params[:version])
+    @content.destroy
+    redirect_to_referer_or history_project_wiki_page_path(@project, @page.title)
+  end
+
+  # Export wiki to a single pdf or html file
+  def export
+    @pages = @wiki.pages.all(:order => 'title', :include => [:content, {:attachments => :author}])
+    respond_to do |format|
+      format.html {
+        export = render_to_string :action => 'export_multiple', :layout => false
+        send_data(export, :type => 'text/html', :filename => "wiki.html")
+      }
+      format.pdf {
+        send_data(wiki_pages_to_pdf(@pages, @project), :type => 'application/pdf', :filename => "#{@project.identifier}.pdf")
+      }
+    end
+  end
+
+  def preview
+    page = @wiki.find_page(params[:id])
+    # page is nil when previewing a new page
+    return render_403 unless page.nil? || editable?(page)
+    if page
+      @attachments += page.attachments
+      @previewed = page.content
+    end
+    @text = params[:content][:text]
+    render :partial => 'common/preview'
+  end
+
+  def add_attachment
+    return render_403 unless editable?
+    attachments = Attachment.attach_files(@page, params[:attachments])
+    render_attachment_warning_if_needed(@page)
+    redirect_to :action => 'show', :id => @page.title, :project_id => @project
+  end
+
+private
+
+  def find_wiki
+    @project = Project.find(params[:project_id])
+    @wiki = @project.wiki
+    render_404 unless @wiki
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  # Finds the requested page or a new page if it doesn't exist
+  def find_existing_or_new_page
+    @page = @wiki.find_or_new_page(params[:id])
+    if @wiki.page_found_with_redirect?
+      redirect_to params.update(:id => @page.title)
+    end
+  end
+
+  # Finds the requested page and returns a 404 error if it doesn't exist
+  def find_existing_page
+    @page = @wiki.find_page(params[:id])
+    if @page.nil?
+      render_404
+      return
+    end
+    if @wiki.page_found_with_redirect?
+      redirect_to params.update(:id => @page.title)
+    end
+  end
+
+  # Returns true if the current user is allowed to edit the page, otherwise false
+  def editable?(page = @page)
+    page.editable_by?(User.current)
+  end
+
+  # Returns the default content of a new wiki page
+  def initial_page_content(page)
+    helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
+    extend helper unless self.instance_of?(helper)
+    helper.instance_method(:initial_page_content).bind(self).call(page)
+  end
+
+  def load_pages_for_index
+    @pages = @wiki.pages.with_updated_on.reorder("#{WikiPage.table_name}.title").includes(:wiki => :project).includes(:parent).all
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/17/17d43ea055a7a8001dad09ba9decc118c095d5fe.svn-base
--- a/.svn/pristine/17/17d43ea055a7a8001dad09ba9decc118c095d5fe.svn-base
+++ /dev/null
@@ -1,55 +0,0 @@
-<% labelled_tabular_form_for :issue, @issue,
-                             :url => {:action => 'update', :id => @issue},
-                             :html => {:id => 'issue-form',
-                                       :class => nil,
-                                       :method => :put,
-                                       :multipart => true} do |f| %>
-    <%= error_messages_for 'issue', 'time_entry' %>
-    <div class="box">
-    <% if @edit_allowed || !@allowed_statuses.empty? %>
-        <fieldset class="tabular"><legend><%= l(:label_change_properties) %>
-        <% if !@issue.new_record? && !@issue.errors.any? && @edit_allowed %>
-        <small>(<%= link_to l(:label_more), {}, :onclick => 'Effect.toggle("issue_descr_fields", "appear", {duration:0.3}); return false;' %>)</small>
-        <% end %>
-        </legend>
-        <%= render :partial => (@edit_allowed ? 'form' : 'form_update'), :locals => {:f => f} %>
-        </fieldset>
-    <% end %>
-    <% if User.current.allowed_to?(:log_time, @project) %>
-        <fieldset class="tabular"><legend><%= l(:button_log_time) %></legend>
-        <% fields_for :time_entry, @time_entry, { :builder => TabularFormBuilder, :lang => current_language} do |time_entry| %>
-        <div class="splitcontentleft">
-        <p><%= time_entry.text_field :hours, :size => 6, :label => :label_spent_time %> <%= l(:field_hours) %></p>
-        </div>
-        <div class="splitcontentright">
-        <p><%= time_entry.select :activity_id, activity_collection_for_select_options %></p>
-        </div>
-        <p><%= time_entry.text_field :comments, :size => 60 %></p>
-        <% @time_entry.custom_field_values.each do |value| %>
-          <p><%= custom_field_tag_with_label :time_entry, value %></p>
-        <% end %>
-        <% end %>
-    </fieldset>
-    <% end %>
-
-    <fieldset><legend><%= l(:field_notes) %></legend>
-    <%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %>
-    <%= wikitoolbar_for 'notes' %>
-    <%= call_hook(:view_issues_edit_notes_bottom, { :issue => @issue, :notes => @notes, :form => f }) %>
-
-    <p><%=l(:label_attachment_plural)%><br /><%= render :partial => 'attachments/form' %></p>
-    </fieldset>
-    </div>
-
-    <%= f.hidden_field :lock_version %>
-    <%= submit_tag l(:button_submit) %>
-    <%= link_to_remote l(:label_preview),
-                       { :url => preview_issue_path(:project_id => @project, :id => @issue),
-                         :method => 'post',
-                         :update => 'preview',
-                         :with => 'Form.serialize("issue-form")',
-                         :complete => "Element.scrollTo('preview')"
-                       }, :accesskey => accesskey(:preview) %>
-<% end %>
-
-<div id="preview" class="wiki"></div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/17/17e6519b50da04ce88ce18f460d2215c425cc034.svn-base
--- a/.svn/pristine/17/17e6519b50da04ce88ce18f460d2215c425cc034.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-<div id="assets_layout">
-	<%= yield %>
-</div>
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/17/17eeb63ea895552f87458a07894df799f570d379.svn-base
--- /dev/null
+++ b/.svn/pristine/17/17eeb63ea895552f87458a07894df799f570d379.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module RolesHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/183c141a2e88b4caf280dddca622ea780ebfd282.svn-base
--- /dev/null
+++ b/.svn/pristine/18/183c141a2e88b4caf280dddca622ea780ebfd282.svn-base
@@ -0,0 +1,1171 @@
+# Chinese (Taiwan) translations for Ruby on Rails
+# by tsechingho (http://github.com/tsechingho)
+# See http://github.com/svenfuchs/rails-i18n/ for details.
+
+"zh-TW":
+  direction: ltr
+  jquery:
+    locale: "zh-TW"
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%b%dæ—¥"
+      long: "%Yå¹´%b%dæ—¥"
+
+    day_names: [æ˜ŸæœŸæ—¥, æ˜ŸæœŸä¸€, æ˜ŸæœŸäºŒ, æ˜ŸæœŸä¸‰, æ˜ŸæœŸå››, æ˜ŸæœŸäº”, æ˜ŸæœŸå…­]
+    abbr_day_names: [æ—¥, ä¸€, äºŒ, ä¸‰, å››, äº”, å…­]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, ä¸€æœˆ, äºŒæœˆ, ä¸‰æœˆ, å››æœˆ, äº”æœˆ, å…­æœˆ, ä¸ƒæœˆ, å…«æœˆ, ä¹æœˆ, åæœˆ, åä¸€æœˆ, åäºŒæœˆ]
+    abbr_month_names: [~, 1æœˆ, 2æœˆ, 3æœˆ, 4æœˆ, 5æœˆ, 6æœˆ, 7æœˆ, 8æœˆ, 9æœˆ, 10æœˆ, 11æœˆ, 12æœˆ]
+    # ä½¿ç”¨æ–¼ date_select èˆ‡ datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%Yå¹´%b%dæ—¥ %A %H:%M:%S %Z"
+      time: "%H:%M"
+      short: "%b%dæ—¥ %H:%M"
+      long: "%Yå¹´%b%dæ—¥ %H:%M"
+    am: "AM"
+    pm: "PM"
+
+# ä½¿ç”¨æ–¼ array.to_sentence.
+  support:
+    array:
+      words_connector: ", "
+      two_words_connector: " å’Œ "
+      last_word_connector: ", å’Œ "
+      sentence_connector: "ä¸”"
+      skip_last_comma: false
+
+  number:
+    # ä½¿ç”¨æ–¼ number_with_delimiter()
+    # åŒæ™‚ä¹Ÿæ˜¯ 'currency', 'percentage', 'precision', èˆ‡ 'human' çš„é è¨­å€¼
+    format:
+      # è¨­å®šå°æ•¸é»žåˆ†éš”å­—å…ƒï¼Œä»¥ä½¿ç”¨æ›´é«˜çš„æº–ç¢ºåº¦ (ä¾‹å¦‚ï¼š 1.0 / 2.0 == 0.5)
+      separator: "."
+      # åƒåˆ†ä½ç¬¦è™Ÿ (ä¾‹å¦‚ï¼šä¸€ç™¾è¬æ˜¯ 1,000,000) (å‡ä»¥ä¸‰å€‹ä½æ•¸ä¾†åˆ†çµ„)
+      delimiter: ","
+      # å°æ•¸é»žåˆ†éš”å­—å…ƒå¾Œä¹‹ç²¾ç¢ºä½æ•¸ (æ•¸å­— 1 æ­é… 2 ä½ç²¾ç¢ºä½æ•¸ç‚ºï¼š 1.00)
+      precision: 3
+
+    # ä½¿ç”¨æ–¼ number_to_currency()
+    currency:
+      format:
+        # è²¨å¹£ç¬¦è™Ÿçš„ä½ç½®? %u æ˜¯è²¨å¹£ç¬¦è™Ÿ, %n æ˜¯æ•¸å€¼ (é è¨­å€¼ï¼š $5.00)
+        format: "%u%n"
+        unit: "NT$"
+        # ä¸‹åˆ—ä¸‰å€‹é¸é …è¨­å®š, è‹¥æœ‰è¨­å®šå€¼å°‡æœƒå–ä»£ number.format æˆç‚ºé è¨­å€¼
+        separator: "."
+        delimiter: ","
+        precision: 2
+
+    # ä½¿ç”¨æ–¼ number_to_percentage()
+    percentage:
+      format:
+        # ä¸‹åˆ—ä¸‰å€‹é¸é …è¨­å®š, è‹¥æœ‰è¨­å®šå€¼å°‡æœƒå–ä»£ number.format æˆç‚ºé è¨­å€¼
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # ä½¿ç”¨æ–¼ number_to_precision()
+    precision:
+      format:
+        # ä¸‹åˆ—ä¸‰å€‹é¸é …è¨­å®š, è‹¥æœ‰è¨­å®šå€¼å°‡æœƒå–ä»£ number.format æˆç‚ºé è¨­å€¼
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # ä½¿ç”¨æ–¼ number_to_human_size()
+    human:
+      format:
+        # ä¸‹åˆ—ä¸‰å€‹é¸é …è¨­å®š, è‹¥æœ‰è¨­å®šå€¼å°‡æœƒå–ä»£ number.format æˆç‚ºé è¨­å€¼
+        # separator:
+        delimiter: ""
+        precision: 3
+        # å„²å­˜å–®ä½è¼¸å‡ºæ ¼å¼.
+        # %u æ˜¯å„²å­˜å–®ä½, %n æ˜¯æ•¸å€¼ (é è¨­å€¼: 2 MB)
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "ä½å…ƒçµ„ (B)"
+            other: "ä½å…ƒçµ„ (B)"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  # ä½¿ç”¨æ–¼ distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+  datetime:
+    distance_in_words:
+      half_a_minute: "åŠåˆ†é˜"
+      less_than_x_seconds:
+        one: "å°æ–¼ 1 ç§’"
+        other: "å°æ–¼ %{count} ç§’"
+      x_seconds:
+        one: "1 ç§’"
+        other: "%{count} ç§’"
+      less_than_x_minutes:
+        one: "å°æ–¼ 1 åˆ†é˜"
+        other: "å°æ–¼ %{count} åˆ†é˜"
+      x_minutes:
+        one: "1 åˆ†é˜"
+        other: "%{count} åˆ†é˜"
+      about_x_hours:
+        one: "ç´„ 1 å°æ™‚"
+        other: "ç´„ %{count} å°æ™‚"
+      x_hours:
+        one:   "1 å°æ™‚"
+        other: "%{count} å°æ™‚"
+      x_days:
+        one: "1 å¤©"
+        other: "%{count} å¤©"
+      about_x_months:
+        one: "ç´„ 1 å€‹æœˆ"
+        other: "ç´„ %{count} å€‹æœˆ"
+      x_months:
+        one: "1 å€‹æœˆ"
+        other: "%{count} å€‹æœˆ"
+      about_x_years:
+        one: "ç´„ 1 å¹´"
+        other: "ç´„ %{count} å¹´"
+      over_x_years:
+        one: "è¶…éŽ 1 å¹´"
+        other: "è¶…éŽ %{count} å¹´"
+      almost_x_years:
+        one:   "å°‡è¿‘ 1 å¹´"
+        other: "å°‡è¿‘ %{count} å¹´"
+    prompts:
+      year:   "å¹´"
+      month:  "æœˆ"
+      day:    "æ—¥"
+      hour:   "æ™‚"
+      minute: "åˆ†"
+      second: "ç§’"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:   "æœ‰ 1 å€‹éŒ¯èª¤ç™¼ç”Ÿä½¿å¾—ã€Œ%{model}ã€ç„¡æ³•è¢«å„²å­˜ã€‚"
+          other: "æœ‰ %{count} å€‹éŒ¯èª¤ç™¼ç”Ÿä½¿å¾—ã€Œ%{model}ã€ç„¡æ³•è¢«å„²å­˜ã€‚"
+        # The variable :count is also available
+        body: "ä¸‹é¢æ‰€åˆ—æ¬„ä½æœ‰å•é¡Œï¼š"
+      # The values :model, :attribute and :value are always available for interpolation
+      # The value :count is available when applicable. Can be used for pluralization.
+      messages:
+        inclusion: "æ²’æœ‰åŒ…å«åœ¨åˆ—è¡¨ä¸­"
+        exclusion: "æ˜¯è¢«ä¿ç•™çš„"
+        invalid: "æ˜¯ç„¡æ•ˆçš„"
+        confirmation: "ä¸ç¬¦åˆç¢ºèªå€¼"
+        accepted: "å¿…é¡»æ˜¯å¯è¢«æŽ¥å—çš„"
+        empty: "ä¸èƒ½ç•™ç©º"
+        blank: "ä¸èƒ½æ˜¯ç©ºç™½å­—å…ƒ"
+        too_long: "éŽé•·ï¼ˆæœ€é•·æ˜¯ %{count} å€‹å­—ï¼‰"
+        too_short: "éŽçŸ­ï¼ˆæœ€çŸ­æ˜¯ %{count} å€‹å­—ï¼‰"
+        wrong_length: "å­—æ•¸éŒ¯èª¤ï¼ˆå¿…é ˆæ˜¯ %{count} å€‹å­—ï¼‰"
+        taken: "å·²ç¶“è¢«ä½¿ç”¨"
+        not_a_number: "ä¸æ˜¯æ•¸å­—"
+        greater_than: "å¿…é ˆå¤§æ–¼ %{count}"
+        greater_than_or_equal_to: "å¿…é ˆå¤§æ–¼æˆ–ç­‰æ–¼ %{count}"
+        equal_to: "å¿…é ˆç­‰æ–¼ %{count}"
+        less_than: "å¿…é ˆå°æ–¼ %{count}"
+        less_than_or_equal_to: "å¿…é ˆå°æ–¼æˆ–ç­‰æ–¼ %{count}"
+        odd: "å¿…é ˆæ˜¯å¥‡æ•¸"
+        even: "å¿…é ˆæ˜¯å¶æ•¸"
+        # Append your own errors here or at the model/attributes scope.
+        greater_than_start_date: "å¿…é ˆåœ¨é–‹å§‹æ—¥æœŸä¹‹å¾Œ"
+        not_same_project: "ä¸å±¬æ–¼åŒä¸€å€‹å°ˆæ¡ˆ"
+        circular_dependency: "é€™å€‹é—œè¯æœƒå°Žè‡´ç’°ç‹€ç›¸ä¾"
+        cant_link_an_issue_with_a_descendant: "å•é¡Œç„¡æ³•è¢«é€£çµè‡³è‡ªå·±çš„å­ä»»å‹™"
+
+      # You can define own errors for models or model attributes.
+      # The values :model, :attribute and :value are always available for interpolation.
+      #
+      # For example,
+      #   models:
+      #     user:
+      #       blank: "This is a custom blank message for %{model}: %{attribute}"
+      #       attributes:
+      #         login:
+      #           blank: "This is a custom blank message for User login"
+      # Will define custom blank validation message for User model and
+      # custom blank validation message for login attribute of User model.
+      #models:
+
+    # Translate model names. Used in Model.human_name().
+    #models:
+      # For example,
+      #   user: "Dude"
+      # will translate User model name to "Dude"
+
+    # Translate model attribute names. Used in Model.human_attribute_name(attribute).
+    #attributes:
+      # For example,
+      #   user:
+      #     login: "Handle"
+      # will translate User attribute "login" as "Handle"
+
+  actionview_instancetag_blank_option: è«‹é¸æ“‡
+
+  general_text_No: 'å¦'
+  general_text_Yes: 'æ˜¯'
+  general_text_no: 'å¦'
+  general_text_yes: 'æ˜¯'
+  general_lang_name: 'Traditional Chinese (ç¹é«”ä¸­æ–‡)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: Big5
+  general_pdf_encoding: Big5
+  general_first_day_of_week: '7'
+
+  notice_account_updated: å¸³æˆ¶æ›´æ–°è³‡è¨Šå·²å„²å­˜
+  notice_account_invalid_creditentials: å¸³æˆ¶æˆ–å¯†ç¢¼ä¸æ­£ç¢º
+  notice_account_password_updated: å¸³æˆ¶æ–°å¯†ç¢¼å·²å„²å­˜
+  notice_account_wrong_password: å¯†ç¢¼ä¸æ­£ç¢º
+  notice_account_register_done: å¸³è™Ÿå·²å»ºç«‹æˆåŠŸã€‚æ¬²å•Ÿç”¨æ‚¨çš„å¸³è™Ÿï¼Œè«‹é»žæ“Šç³»çµ±ç¢ºèªä¿¡å‡½ä¸­çš„å•Ÿç”¨é€£çµã€‚
+  notice_account_unknown_email: æœªçŸ¥çš„ä½¿ç”¨è€…
+  notice_can_t_change_password: é€™å€‹å¸³è™Ÿä½¿ç”¨å¤–éƒ¨èªè­‰æ–¹å¼ï¼Œç„¡æ³•è®Šæ›´å…¶å¯†ç¢¼ã€‚
+  notice_account_lost_email_sent: åŒ…å«é¸æ“‡æ–°å¯†ç¢¼æŒ‡ç¤ºçš„é›»å­éƒµä»¶ï¼Œå·²ç¶“å¯„å‡ºçµ¦æ‚¨ã€‚
+  notice_account_activated: æ‚¨çš„å¸³è™Ÿå·²ç¶“å•Ÿç”¨ï¼Œå¯ç”¨å®ƒç™»å…¥ç³»çµ±ã€‚
+  notice_successful_create: å»ºç«‹æˆåŠŸ
+  notice_successful_update: æ›´æ–°æˆåŠŸ
+  notice_successful_delete: åˆªé™¤æˆåŠŸ
+  notice_successful_connection: é€£ç·šæˆåŠŸ
+  notice_file_not_found: æ‚¨æƒ³è¦å­˜å–çš„é é¢å·²ç¶“ä¸å­˜åœ¨æˆ–è¢«æ¬ç§»è‡³å…¶ä»–ä½ç½®ã€‚
+  notice_locking_conflict: è³‡æ–™å·²è¢«å…¶ä»–ä½¿ç”¨è€…æ›´æ–°ã€‚
+  notice_not_authorized: ä½ æœªè¢«æŽˆæ¬Šå­˜å–æ­¤é é¢ã€‚
+  notice_not_authorized_archived_project: æ‚¨æ¬²å­˜å–çš„å°ˆæ¡ˆå·²ç¶“è¢«å°å­˜ã€‚
+  notice_email_sent: "éƒµä»¶å·²ç¶“æˆåŠŸå¯„é€è‡³ä»¥ä¸‹æ”¶ä»¶è€…ï¼š %{value}"
+  notice_email_error: "å¯„é€éƒµä»¶çš„éŽç¨‹ä¸­ç™¼ç”ŸéŒ¯èª¤ (%{value})"
+  notice_feeds_access_key_reseted: æ‚¨çš„ RSS å­˜å–é‡‘é‘°å·²è¢«é‡æ–°è¨­å®šã€‚
+  notice_api_access_key_reseted: æ‚¨çš„ API å­˜å–é‡‘é‘°å·²è¢«é‡æ–°è¨­å®šã€‚
+  notice_failed_to_save_issues: "ç„¡æ³•å„²å­˜ %{count} å•é¡Œåˆ°ä¸‹åˆ—æ‰€é¸å–çš„ %{total} å€‹é …ç›®ä¸­ï¼š %{ids}ã€‚"
+  notice_failed_to_save_time_entries: "ç„¡æ³•å„²å­˜ %{count} å€‹å·¥æ™‚åˆ°ä¸‹åˆ—æ‰€é¸å–çš„ %{total} å€‹é …ç›®ä¸­ï¼š %{ids}ã€‚"
+  notice_failed_to_save_members: "æˆå“¡å„²å­˜å¤±æ•—: %{errors}."
+  notice_no_issue_selected: "æœªé¸æ“‡ä»»ä½•å•é¡Œï¼è«‹å‹¾é¸æ‚¨æƒ³è¦ç·¨è¼¯çš„å•é¡Œã€‚"
+  notice_account_pending: "æ‚¨çš„å¸³è™Ÿå·²ç¶“å»ºç«‹ï¼Œæ­£åœ¨ç­‰å¾…ç®¡ç†å“¡çš„å¯©æ ¸ã€‚"
+  notice_default_data_loaded: é è¨­çµ„æ…‹å·²è¼‰å…¥æˆåŠŸã€‚
+  notice_unable_delete_version: ç„¡æ³•åˆªé™¤ç‰ˆæœ¬ã€‚
+  notice_unable_delete_time_entry: ç„¡æ³•åˆªé™¤å·¥æ™‚è¨˜éŒ„é …ç›®ã€‚
+  notice_issue_done_ratios_updated: å•é¡Œå®Œæˆç™¾åˆ†æ¯”å·²æ›´æ–°ã€‚
+  notice_gantt_chart_truncated: "ç”±æ–¼é …ç›®æ•¸é‡è¶…éŽå¯é¡¯ç¤ºæ•¸é‡çš„æœ€å¤§å€¼ (%{max})ï¼Œæ•…æ­¤ç”˜ç‰¹åœ–å°¾éƒ¨å·²è¢«æˆªæ–·"
+  notice_issue_successful_create: "å•é¡Œ %{id} å·²å»ºç«‹ã€‚"
+  notice_issue_update_conflict: "ç•¶æ‚¨æ­£åœ¨ç·¨è¼¯é€™å€‹å•é¡Œçš„æ™‚å€™ï¼Œå®ƒå·²ç¶“è¢«å…¶ä»–äººæ¶å…ˆä¸€æ­¥æ›´æ–°éŽã€‚"
+  notice_account_deleted: "æ‚¨çš„å¸³æˆ¶å·²è¢«æ°¸ä¹…åˆªé™¤ã€‚"
+  notice_user_successful_create: "å·²å»ºç«‹ç”¨æˆ¶ %{id}ã€‚"
+
+  error_can_t_load_default_data: "ç„¡æ³•è¼‰å…¥é è¨­çµ„æ…‹ï¼š %{value}"
+  error_scm_not_found: "åœ¨å„²å­˜æ©Ÿåˆ¶ä¸­æ‰¾ä¸åˆ°é€™å€‹é …ç›®æˆ–ä¿®è¨‚ç‰ˆã€‚"
+  error_scm_command_failed: "å˜—è©¦å­˜å–å„²å­˜æ©Ÿåˆ¶æ™‚ç™¼ç”ŸéŒ¯èª¤ï¼š %{value}"
+  error_scm_annotate: "é …ç›®ä¸å­˜åœ¨æˆ–é …ç›®ç„¡æ³•è¢«åŠ ä¸Šé™„è¨»ã€‚"
+  error_scm_annotate_big_text_file: æ­¤é …ç›®ç„¡æ³•è¢«æ¨™è¨»ï¼Œå› ç‚ºå®ƒå·²ç¶“è¶…éŽæœ€å¤§çš„æ–‡å­—æª”å¤§å°ã€‚
+  error_issue_not_found_in_project: 'è©²å•é¡Œä¸å­˜åœ¨æˆ–ä¸å±¬æ–¼æ­¤å°ˆæ¡ˆ'
+  error_no_tracker_in_project: 'æ­¤å°ˆæ¡ˆå°šæœªæŒ‡å®šè¿½è¹¤æ¨™ç±¤ã€‚è«‹æª¢æŸ¥å°ˆæ¡ˆçš„è¨­å®šè³‡è¨Šã€‚'
+  error_no_default_issue_status: 'å°šæœªå®šç¾©å•é¡Œç‹€æ…‹çš„é è¨­å€¼ã€‚è«‹æ‚¨å‰å¾€ã€Œç¶²ç«™ç®¡ç†ã€->ã€Œå•é¡Œç‹€æ…‹æ¸…å–®ã€é é¢ï¼Œæª¢æŸ¥ç›¸é—œçµ„æ…‹è¨­å®šã€‚'
+  error_can_not_delete_custom_field: ç„¡æ³•åˆªé™¤è‡ªè¨‚æ¬„ä½
+  error_can_not_delete_tracker: "æ­¤è¿½è¹¤æ¨™ç±¤å·²åŒ…å«å•é¡Œï¼Œç„¡æ³•è¢«åˆªé™¤ã€‚"
+  error_can_not_remove_role: "æ­¤è§’è‰²å·²è¢«ä½¿ç”¨ï¼Œç„¡æ³•å°‡å…¶åˆªé™¤ã€‚"
+  error_can_not_reopen_issue_on_closed_version: 'æŒ‡æ´¾çµ¦ã€Œå·²çµæŸã€ç‰ˆæœ¬çš„å•é¡Œï¼Œç„¡æ³•å†å°‡å…¶ç‹€æ…‹è®Šæ›´ç‚ºã€Œé€²è¡Œä¸­ã€'
+  error_can_not_archive_project: æ­¤å°ˆæ¡ˆç„¡æ³•è¢«å°å­˜
+  error_issue_done_ratios_not_updated: "å•é¡Œå®Œæˆç™¾åˆ†æ¯”æœªæ›´æ–°ã€‚"
+  error_workflow_copy_source: 'è«‹é¸æ“‡ä¸€å€‹ä¾†æºå•é¡Œè¿½è¹¤æ¨™ç±¤æˆ–è§’è‰²'
+  error_workflow_copy_target: 'è«‹é¸æ“‡ä¸€å€‹ï¼ˆæˆ–å¤šå€‹ï¼‰ç›®çš„å•é¡Œè¿½è¹¤æ¨™ç±¤æˆ–è§’è‰²'
+  error_unable_delete_issue_status: 'ç„¡æ³•åˆªé™¤å•é¡Œç‹€æ…‹'
+  error_unable_to_connect: "ç„¡æ³•é€£ç·šè‡³ï¼ˆ%{value}ï¼‰"
+  error_attachment_too_big: "é€™å€‹æª”æ¡ˆç„¡æ³•è¢«ä¸Šå‚³ï¼Œå› ç‚ºå®ƒå·²ç¶“è¶…éŽæœ€å¤§çš„æª”æ¡ˆå¤§å° (%{max_size})"
+  error_session_expired: "æ‚¨çš„å·¥ä½œéšŽæ®µå·²ç¶“éŽæœŸã€‚è«‹é‡æ–°ç™»å…¥ã€‚"
+  warning_attachments_not_saved: "%{count} å€‹é™„åŠ æª”æ¡ˆç„¡æ³•è¢«å„²å­˜ã€‚"
+
+  mail_subject_lost_password: æ‚¨çš„ Redmine ç¶²ç«™å¯†ç¢¼
+  mail_body_lost_password: 'æ¬²è®Šæ›´æ‚¨çš„ Redmine ç¶²ç«™å¯†ç¢¼, è«‹é»žé¸ä»¥ä¸‹éˆçµ:'
+  mail_subject_register: å•Ÿç”¨æ‚¨çš„ Redmine å¸³è™Ÿ
+  mail_body_register: 'æ¬²å•Ÿç”¨æ‚¨çš„ Redmine å¸³è™Ÿ, è«‹é»žé¸ä»¥ä¸‹éˆçµ:'
+  mail_body_account_information_external: "æ‚¨å¯ä»¥ä½¿ç”¨ %{value} å¸³è™Ÿç™»å…¥ Redmine ç¶²ç«™ã€‚"
+  mail_body_account_information: æ‚¨çš„ Redmine å¸³è™Ÿè³‡è¨Š
+  mail_subject_account_activation_request: Redmine å¸³è™Ÿå•Ÿç”¨éœ€æ±‚é€šçŸ¥
+  mail_body_account_activation_request: "æœ‰ä½æ–°ç”¨æˆ¶ (%{value}) å·²ç¶“å®Œæˆè¨»å†Šï¼Œæ­£ç­‰å€™æ‚¨çš„å¯©æ ¸ï¼š"
+  mail_subject_reminder: "æ‚¨æœ‰ %{count} å€‹å•é¡Œå³å°‡åˆ°æœŸ (%{days})"
+  mail_body_reminder: "%{count} å€‹æŒ‡æ´¾çµ¦æ‚¨çš„å•é¡Œï¼Œå°‡æ–¼ %{days} å¤©ä¹‹å…§åˆ°æœŸï¼š"
+  mail_subject_wiki_content_added: "'%{id}' wiki é é¢å·²è¢«æ–°å¢ž"
+  mail_body_wiki_content_added: "æ­¤ '%{id}' wiki é é¢å·²è¢« %{author} æ–°å¢žã€‚"
+  mail_subject_wiki_content_updated: "'%{id}' wiki é é¢å·²è¢«æ›´æ–°"
+  mail_body_wiki_content_updated: "æ­¤ '%{id}' wiki é é¢å·²è¢« %{author} æ›´æ–°ã€‚"
+
+
+  field_name: åç¨±
+  field_description: æ¦‚è¿°
+  field_summary: æ‘˜è¦
+  field_is_required: å¿…å¡«
+  field_firstname: åå­—
+  field_lastname: å§“æ°
+  field_mail: é›»å­éƒµä»¶
+  field_filename: æª”æ¡ˆåç¨±
+  field_filesize: å¤§å°
+  field_downloads: ä¸‹è¼‰æ¬¡æ•¸
+  field_author: ä½œè€…
+  field_created_on: å»ºç«‹æ—¥æœŸ
+  field_updated_on: æ›´æ–°æ—¥æœŸ
+  field_closed_on: çµæŸæ—¥æœŸ
+  field_field_format: æ ¼å¼
+  field_is_for_all: çµ¦å…¨éƒ¨çš„å°ˆæ¡ˆ
+  field_possible_values: å¯èƒ½å€¼
+  field_regexp: æ­£è¦è¡¨ç¤ºå¼
+  field_min_length: æœ€å°é•·åº¦
+  field_max_length: æœ€å¤§é•·åº¦
+  field_value: å€¼
+  field_category: åˆ†é¡ž
+  field_title: æ¨™é¡Œ
+  field_project: å°ˆæ¡ˆ
+  field_issue: å•é¡Œ
+  field_status: ç‹€æ…‹
+  field_notes: ç­†è¨˜
+  field_is_closed: å•é¡Œå·²çµæŸ
+  field_is_default: é è¨­å€¼
+  field_tracker: è¿½è¹¤æ¨™ç±¤
+  field_subject: ä¸»æ—¨
+  field_due_date: å®Œæˆæ—¥æœŸ
+  field_assigned_to: åˆ†æ´¾çµ¦
+  field_priority: å„ªå…ˆæ¬Š
+  field_fixed_version: ç‰ˆæœ¬
+  field_user: ç”¨æˆ¶
+  field_principal: åŽŸå‰‡
+  field_role: è§’è‰²
+  field_homepage: ç¶²ç«™é¦–é 
+  field_is_public: å…¬é–‹
+  field_parent: çˆ¶å°ˆæ¡ˆ
+  field_is_in_roadmap: å•é¡Œé¡¯ç¤ºæ–¼ç‰ˆæœ¬è—åœ–ä¸­
+  field_login: å¸³æˆ¶åç¨±
+  field_mail_notification: é›»å­éƒµä»¶æé†’é¸é …
+  field_admin: ç®¡ç†è€…
+  field_last_login_on: æœ€è¿‘é€£ç·šæ—¥æœŸ
+  field_language: èªžç³»
+  field_effective_date: æ—¥æœŸ
+  field_password: ç›®å‰å¯†ç¢¼
+  field_new_password: æ–°å¯†ç¢¼
+  field_password_confirmation: ç¢ºèªæ–°å¯†ç¢¼
+  field_version: ç‰ˆæœ¬
+  field_type: Type
+  field_host: Host
+  field_port: é€£æŽ¥åŸ 
+  field_account: å¸³æˆ¶
+  field_base_dn: Base DN
+  field_attr_login: ç™»å…¥å±¬æ€§
+  field_attr_firstname: åå­—å±¬æ€§
+  field_attr_lastname: å§“æ°å±¬æ€§
+  field_attr_mail: é›»å­éƒµä»¶ä¿¡ç®±å±¬æ€§
+  field_onthefly: å³æ™‚å»ºç«‹ä½¿ç”¨è€…
+  field_start_date: é–‹å§‹æ—¥æœŸ
+  field_done_ratio: å®Œæˆç™¾åˆ†æ¯”
+  field_auth_source: èªè­‰æ¨¡å¼
+  field_hide_mail: éš±è—æˆ‘çš„é›»å­éƒµä»¶
+  field_comments: å›žæ‡‰
+  field_url: ç¶²å€
+  field_start_page: é¦–é 
+  field_subproject: å­å°ˆæ¡ˆ
+  field_hours: å°æ™‚
+  field_activity: æ´»å‹•
+  field_spent_on: æ—¥æœŸ
+  field_identifier: ä»£ç¢¼
+  field_is_filter: ç”¨ä¾†ä½œç‚ºéŽæ¿¾å™¨
+  field_issue_to: ç›¸é—œå•é¡Œ
+  field_delay: é€¾æœŸ
+  field_assignable: å•é¡Œå¯è¢«åˆ†æ´¾è‡³æ­¤è§’è‰²
+  field_redirect_existing_links: é‡æ–°å°Žå‘ç¾æœ‰é€£çµ
+  field_estimated_hours: é ä¼°å·¥æ™‚
+  field_column_names: æ¬„ä½
+  field_time_entries: è€—ç”¨å·¥æ™‚
+  field_time_zone: æ™‚å€
+  field_searchable: å¯ç”¨åšæœå°‹æ¢ä»¶
+  field_default_value: é è¨­å€¼
+  field_comments_sorting: å›žæ‡‰æŽ’åº
+  field_parent_title: çˆ¶é é¢
+  field_editable: å¯ç·¨è¼¯
+  field_watcher: è§€å¯Ÿè€…
+  field_identity_url: OpenID ç¶²å€
+  field_content: å…§å®¹
+  field_group_by: çµæžœåˆ†çµ„æ–¹å¼
+  field_sharing: å…±ç”¨
+  field_parent_issue: çˆ¶å•é¡Œ
+  field_member_of_group: "è¢«æŒ‡æ´¾è€…çš„ç¾¤çµ„"
+  field_assigned_to_role: "è¢«æŒ‡æ´¾è€…çš„è§’è‰²"
+  field_text: å…§å®¹æ–‡å­—
+  field_visible: å¯è¢«çœ‹è¦‹
+  field_warn_on_leaving_unsaved: "æé†’æˆ‘å°‡è¦é›¢é–‹çš„é é¢ä¸­å°šæœ‰æœªå„²å­˜çš„è³‡æ–™"
+  field_issues_visibility: å•é¡Œå¯è¦‹åº¦
+  field_is_private: ç§äºº
+  field_commit_logs_encoding: èªå¯è¨Šæ¯ç·¨ç¢¼
+  field_scm_path_encoding: è·¯å¾‘ç·¨ç¢¼
+  field_path_to_repository: å„²å­˜æ©Ÿåˆ¶è·¯å¾‘
+  field_root_directory: æ ¹è³‡æ–™å¤¾
+  field_cvsroot: CVSROOT
+  field_cvs_module: æ¨¡çµ„
+  field_repository_is_default: ä¸»è¦å„²å­˜æ©Ÿåˆ¶
+  field_multiple: å¤šé‡å€¼
+  field_auth_source_ldap_filter: LDAP ç¯©é¸å™¨
+  field_core_fields: æ¨™æº–æ¬„ä½
+  field_timeout: "é€¾æ™‚ (å–®ä½: ç§’)"
+  field_board_parent: çˆ¶è«–å£‡
+  field_private_notes: ç§äººç­†è¨˜
+  field_inherit_members: ç¹¼æ‰¿çˆ¶å°ˆæ¡ˆæˆå“¡
+
+  setting_app_title: æ¨™é¡Œ
+  setting_app_subtitle: å‰¯æ¨™é¡Œ
+  setting_welcome_text: æ­¡è¿Žè©ž
+  setting_default_language: é è¨­èªžç³»
+  setting_login_required: éœ€è¦é©—è­‰
+  setting_self_registration: è¨»å†Šé¸é …
+  setting_attachment_max_size: é™„ä»¶å¤§å°é™åˆ¶
+  setting_issues_export_limit: å•é¡ŒåŒ¯å‡ºé™åˆ¶
+  setting_mail_from: å¯„ä»¶è€…é›»å­éƒµä»¶
+  setting_bcc_recipients: ä½¿ç”¨å¯†ä»¶å‰¯æœ¬ (BCC)
+  setting_plain_text_mail: ç´”æ–‡å­—éƒµä»¶ (ä¸å« HTML)
+  setting_host_name: ä¸»æ©Ÿåç¨±
+  setting_text_formatting: æ–‡å­—æ ¼å¼
+  setting_wiki_compression: å£“ç¸® Wiki æ­·å²æ–‡ç« 
+  setting_feeds_limit: RSS æ–°èžé™åˆ¶
+  setting_autofetch_changesets: è‡ªå‹•æ“·å–èªå¯
+  setting_default_projects_public: æ–°å»ºç«‹ä¹‹å°ˆæ¡ˆé è¨­ç‚ºã€Œå…¬é–‹ã€
+  setting_sys_api_enabled: å•Ÿç”¨ç®¡ç†å„²å­˜æ©Ÿåˆ¶çš„ç¶²é æœå‹™ (Web Service)
+  setting_commit_ref_keywords: èªå¯ç”¨æ–¼åƒç…§ä¹‹é—œéµå­—
+  setting_commit_fix_keywords: èªå¯ç”¨æ–¼ä¿®æ­£ä¹‹é—œéµå­—
+  setting_autologin: è‡ªå‹•ç™»å…¥
+  setting_date_format: æ—¥æœŸæ ¼å¼
+  setting_time_format: æ™‚é–“æ ¼å¼
+  setting_cross_project_issue_relations: å…è¨±é—œè¯è‡³å…¶å®ƒå°ˆæ¡ˆçš„å•é¡Œ
+  setting_cross_project_subtasks: å…è¨±è·¨å°ˆæ¡ˆçš„å­ä»»å‹™
+  setting_issue_list_default_columns: é è¨­é¡¯ç¤ºæ–¼å•é¡Œæ¸…å–®çš„æ¬„ä½
+  setting_repositories_encodings: é™„åŠ æª”æ¡ˆèˆ‡å„²å­˜æ©Ÿåˆ¶çš„ç·¨ç¢¼
+  setting_emails_header: é›»å­éƒµä»¶å‰é ­èªªæ˜Ž
+  setting_emails_footer: é›»å­éƒµä»¶é™„å¸¶èªªæ˜Ž
+  setting_protocol: å”å®š
+  setting_per_page_options: æ¯é é¡¯ç¤ºå€‹æ•¸é¸é …
+  setting_user_format: ä½¿ç”¨è€…é¡¯ç¤ºæ ¼å¼
+  setting_activity_days_default: å°ˆæ¡ˆæ´»å‹•é¡¯ç¤ºå¤©æ•¸
+  setting_display_subprojects_issues: é è¨­æ–¼çˆ¶å°ˆæ¡ˆä¸­é¡¯ç¤ºå­å°ˆæ¡ˆçš„å•é¡Œ
+  setting_enabled_scm: å•Ÿç”¨çš„ SCM
+  setting_mail_handler_body_delimiters: "æˆªåŽ»éƒµä»¶ä¸­åŒ…å«ä¸‹åˆ—å€¼ä¹‹å¾Œçš„å…§å®¹"
+  setting_mail_handler_api_enabled: å•Ÿç”¨è™•ç†å‚³å…¥é›»å­éƒµä»¶çš„æœå‹™
+  setting_mail_handler_api_key: API é‡‘é‘°
+  setting_sequential_project_identifiers: å¾ªåºç”¢ç”Ÿå°ˆæ¡ˆè­˜åˆ¥ç¢¼
+  setting_gravatar_enabled: å•Ÿç”¨ Gravatar å…¨çƒèªè­‰å¤§é ­åƒ
+  setting_gravatar_default: é è¨­å…¨çƒèªè­‰å¤§é ­åƒåœ–ç‰‡
+  setting_diff_max_lines_displayed: å·®ç•°é¡¯ç¤ºè¡Œæ•¸ä¹‹æœ€å¤§å€¼
+  setting_file_max_size_displayed: æª”æ¡ˆå…§å®¹é¡¯ç¤ºå¤§å°ä¹‹æœ€å¤§å€¼
+  setting_repository_log_display_limit: ä¿®è¨‚ç‰ˆé¡¯ç¤ºæ•¸ç›®ä¹‹æœ€å¤§å€¼
+  setting_openid: å…è¨±ä½¿ç”¨ OpenID ç™»å…¥èˆ‡è¨»å†Š
+  setting_password_min_length: å¯†ç¢¼æœ€å°é•·åº¦
+  setting_new_project_user_role_id: ç®¡ç†è€…ä»¥å¤–ä¹‹ç”¨æˆ¶å»ºç«‹æ–°å°ˆæ¡ˆæ™‚ï¼Œå°‡è¢«æŒ‡æ´¾çš„è§’è‰²
+  setting_default_projects_modules: æ–°å°ˆæ¡ˆé è¨­å•Ÿç”¨çš„æ¨¡çµ„
+  setting_issue_done_ratio: è¨ˆç®—å•é¡Œå®Œæˆç™¾åˆ†æ¯”ä¹‹æ–¹å¼
+  setting_issue_done_ratio_issue_field: ä¾æ“šå•é¡Œå®Œæˆç™¾åˆ†æ¯”æ¬„ä½
+  setting_issue_done_ratio_issue_status: ä¾æ“šå•é¡Œç‹€æ…‹
+  setting_start_of_week: é€±çš„ç¬¬ä¸€å¤©
+  setting_rest_api_enabled: å•Ÿç”¨ REST ç¶²è·¯æœå‹™æŠ€è¡“ï¼ˆWeb Serviceï¼‰
+  setting_cache_formatted_text: å¿«å–å·²æ ¼å¼åŒ–æ–‡å­—
+  setting_default_notification_option: é è¨­é€šçŸ¥é¸é …
+  setting_commit_logtime_enabled: å•Ÿç”¨èªå¯ä¸­çš„æ™‚é–“è¨˜éŒ„
+  setting_commit_logtime_activity_id: æ™‚é–“è¨˜éŒ„å°æ‡‰çš„æ´»å‹•
+  setting_gantt_items_limit: ç”˜ç‰¹åœ–ä¸­é …ç›®é¡¯ç¤ºæ•¸é‡çš„æœ€å¤§å€¼
+  setting_issue_group_assignment: å…è¨±å•é¡Œè¢«æŒ‡æ´¾è‡³ç¾¤çµ„
+  setting_default_issue_start_date_to_creation_date: è¨­å®šæ–°å•é¡Œçš„èµ·å§‹æ—¥æœŸç‚ºä»Šå¤©çš„æ—¥æœŸ
+  setting_commit_cross_project_ref: å…è¨±é—œè¯ä¸¦ä¿®æ­£å…¶ä»–å°ˆæ¡ˆçš„å•é¡Œ
+  setting_unsubscribe: å…è¨±ç”¨æˆ¶å–æ¶ˆè¨»å†Šï¼ˆåˆªé™¤å¸³æˆ¶ï¼‰
+  setting_session_lifetime: å·¥ä½œéšŽæ®µå­˜ç•™æ™‚é–“æœ€å¤§å€¼
+  setting_session_timeout: å·¥ä½œéšŽæ®µç„¡æ´»å‹•é€¾æ™‚æ™‚é–“
+  setting_thumbnails_enabled: é¡¯ç¤ºé™„åŠ æª”æ¡ˆçš„ç¸®åœ–
+  setting_thumbnails_size: "ç¸®åœ–å¤§å° (å–®ä½: åƒç´  pixels)"
+  setting_non_working_week_days: éžå·¥ä½œæ—¥
+  setting_jsonp_enabled: å•Ÿç”¨ JSONP æ”¯æ´
+  setting_default_projects_tracker_ids: æ–°å°ˆæ¡ˆé è¨­ä½¿ç”¨çš„è¿½è¹¤æ¨™ç±¤
+
+  permission_add_project: å»ºç«‹å°ˆæ¡ˆ
+  permission_add_subprojects: å»ºç«‹å­å°ˆæ¡ˆ
+  permission_edit_project: ç·¨è¼¯å°ˆæ¡ˆ
+  permission_close_project: é—œé–‰ / é‡æ–°é–‹å•Ÿå°ˆæ¡ˆ
+  permission_select_project_modules: é¸æ“‡å°ˆæ¡ˆæ¨¡çµ„
+  permission_manage_members: ç®¡ç†æˆå“¡
+  permission_manage_project_activities: ç®¡ç†å°ˆæ¡ˆæ´»å‹•
+  permission_manage_versions: ç®¡ç†ç‰ˆæœ¬
+  permission_manage_categories: ç®¡ç†å•é¡Œåˆ†é¡ž
+  permission_view_issues: æª¢è¦–å•é¡Œ
+  permission_add_issues: æ–°å¢žå•é¡Œ
+  permission_edit_issues: ç·¨è¼¯å•é¡Œ
+  permission_manage_issue_relations: ç®¡ç†å•é¡Œé—œè¯
+  permission_set_issues_private: è¨­å®šå•é¡Œç‚ºå…¬é–‹æˆ–ç§äºº
+  permission_set_own_issues_private: è¨­å®šè‡ªå·±çš„å•é¡Œç‚ºå…¬é–‹æˆ–ç§äºº
+  permission_add_issue_notes: æ–°å¢žç­†è¨˜
+  permission_edit_issue_notes: ç·¨è¼¯ç­†è¨˜
+  permission_edit_own_issue_notes: ç·¨è¼¯è‡ªå·±çš„ç­†è¨˜
+  permission_view_private_notes: æª¢è¦–ç§äººç­†è¨˜
+  permission_set_notes_private: è¨­å®šç­†è¨˜ç‚ºç§äººç­†è¨˜
+  permission_move_issues: æ¬ç§»å•é¡Œ
+  permission_delete_issues: åˆªé™¤å•é¡Œ
+  permission_manage_public_queries: ç®¡ç†å…¬é–‹æŸ¥è©¢
+  permission_save_queries: å„²å­˜æŸ¥è©¢
+  permission_view_gantt: æª¢è¦–ç”˜ç‰¹åœ–
+  permission_view_calendar: æª¢è¦–æ—¥æ›†
+  permission_view_issue_watchers: æª¢è¦–ç›£çœ‹è€…æ¸…å–®
+  permission_add_issue_watchers: æ–°å¢žç›£çœ‹è€…
+  permission_delete_issue_watchers: åˆªé™¤ç›£çœ‹è€…
+  permission_log_time: ç´€éŒ„è€—ç”¨å·¥æ™‚
+  permission_view_time_entries: æª¢è¦–è€—ç”¨å·¥æ™‚
+  permission_edit_time_entries: ç·¨è¼¯å·¥æ™‚ç´€éŒ„
+  permission_edit_own_time_entries: ç·¨è¼¯è‡ªå·±çš„å·¥æ™‚è¨˜éŒ„
+  permission_manage_news: ç®¡ç†æ–°èž
+  permission_comment_news: å›žæ‡‰æ–°èž
+  permission_view_documents: æª¢è¦–æ–‡ä»¶
+  permission_add_documents: æ–°å¢žæ–‡ä»¶
+  permission_edit_documents: ç·¨è¼¯æ–‡ä»¶
+  permission_delete_documents: åˆªé™¤æ–‡ä»¶
+  permission_manage_files: ç®¡ç†æª”æ¡ˆ
+  permission_view_files: æª¢è¦–æª”æ¡ˆ
+  permission_manage_wiki: ç®¡ç† wiki
+  permission_rename_wiki_pages: é‡æ–°å‘½å wiki é é¢
+  permission_delete_wiki_pages: åˆªé™¤ wiki é é¢
+  permission_view_wiki_pages: æª¢è¦– wiki
+  permission_view_wiki_edits: æª¢è¦– wiki æ­·å²
+  permission_edit_wiki_pages: ç·¨è¼¯ wiki é é¢
+  permission_delete_wiki_pages_attachments: åˆªé™¤é™„ä»¶
+  permission_protect_wiki_pages: å°ˆæ¡ˆ wiki é é¢
+  permission_manage_repository: ç®¡ç†å„²å­˜æ©Ÿåˆ¶
+  permission_browse_repository: ç€è¦½å„²å­˜æ©Ÿåˆ¶
+  permission_view_changesets: æª¢è¦–è®Šæ›´é›†
+  permission_commit_access: å­˜å–èªå¯
+  permission_manage_boards: ç®¡ç†è¨Žè«–ç‰ˆ
+  permission_view_messages: æª¢è¦–è¨Šæ¯
+  permission_add_messages: æ–°å¢žè¨Šæ¯
+  permission_edit_messages: ç·¨è¼¯è¨Šæ¯
+  permission_edit_own_messages: ç·¨è¼¯è‡ªå·±çš„è¨Šæ¯
+  permission_delete_messages: åˆªé™¤è¨Šæ¯
+  permission_delete_own_messages: åˆªé™¤è‡ªå·±çš„è¨Šæ¯
+  permission_export_wiki_pages: åŒ¯å‡º wiki é é¢
+  permission_manage_subtasks: ç®¡ç†å­ä»»å‹™
+  permission_manage_related_issues: ç®¡ç†ç›¸é—œå•é¡Œ
+
+  project_module_issue_tracking: å•é¡Œè¿½è¹¤
+  project_module_time_tracking: å·¥æ™‚è¿½è¹¤
+  project_module_news: æ–°èž
+  project_module_documents: æ–‡ä»¶
+  project_module_files: æª”æ¡ˆ
+  project_module_wiki: Wiki
+  project_module_repository: ç‰ˆæœ¬æŽ§ç®¡
+  project_module_boards: è¨Žè«–å€
+  project_module_calendar: æ—¥æ›†
+  project_module_gantt: ç”˜ç‰¹åœ–
+
+  label_user: ç”¨æˆ¶
+  label_user_plural: ç”¨æˆ¶æ¸…å–®
+  label_user_new: å»ºç«‹æ–°ç”¨æˆ¶
+  label_user_anonymous: åŒ¿åç”¨æˆ¶
+  label_project: å°ˆæ¡ˆ
+  label_project_new: å»ºç«‹æ–°å°ˆæ¡ˆ
+  label_project_plural: å°ˆæ¡ˆæ¸…å–®
+  label_x_projects:
+    zero:  ç„¡å°ˆæ¡ˆ
+    one:   1 å€‹å°ˆæ¡ˆ
+    other: "%{count} å€‹å°ˆæ¡ˆ"
+  label_project_all: å…¨éƒ¨çš„å°ˆæ¡ˆ
+  label_project_latest: æœ€è¿‘çš„å°ˆæ¡ˆ
+  label_issue: å•é¡Œ
+  label_issue_new: å»ºç«‹æ–°å•é¡Œ
+  label_issue_plural: å•é¡Œæ¸…å–®
+  label_issue_view_all: æª¢è¦–æ‰€æœ‰å•é¡Œ
+  label_issues_by: "å•é¡ŒæŒ‰ %{value} åˆ†çµ„é¡¯ç¤º"
+  label_issue_added: å•é¡Œå·²æ–°å¢ž
+  label_issue_updated: å•é¡Œå·²æ›´æ–°
+  label_issue_note_added: ç­†è¨˜å·²æ–°å¢ž
+  label_issue_status_updated: ç‹€æ…‹å·²æ›´æ–°
+  label_issue_priority_updated: å„ªå…ˆæ¬Šå·²æ›´æ–°
+  label_document: æ–‡ä»¶
+  label_document_new: å»ºç«‹æ–°æ–‡ä»¶
+  label_document_plural: æ–‡ä»¶
+  label_document_added: æ–‡ä»¶å·²æ–°å¢ž
+  label_role: è§’è‰²
+  label_role_plural: è§’è‰²
+  label_role_new: å»ºç«‹æ–°è§’è‰²
+  label_role_and_permissions: è§’è‰²èˆ‡æ¬Šé™
+  label_role_anonymous: åŒ¿åè€…
+  label_role_non_member: éžæœƒå“¡
+  label_member: æˆå“¡
+  label_member_new: å»ºç«‹æ–°æˆå“¡
+  label_member_plural: æˆå“¡
+  label_tracker: è¿½è¹¤æ¨™ç±¤
+  label_tracker_plural: è¿½è¹¤æ¨™ç±¤æ¸…å–®
+  label_tracker_new: å»ºç«‹æ–°çš„è¿½è¹¤æ¨™ç±¤
+  label_workflow: æµç¨‹
+  label_issue_status: å•é¡Œç‹€æ…‹
+  label_issue_status_plural: å•é¡Œç‹€æ…‹æ¸…å–®
+  label_issue_status_new: å»ºç«‹æ–°ç‹€æ…‹
+  label_issue_category: å•é¡Œåˆ†é¡ž
+  label_issue_category_plural: å•é¡Œåˆ†é¡žæ¸…å–®
+  label_issue_category_new: å»ºç«‹æ–°åˆ†é¡ž
+  label_custom_field: è‡ªè¨‚æ¬„ä½
+  label_custom_field_plural: è‡ªè¨‚æ¬„ä½æ¸…å–®
+  label_custom_field_new: å»ºç«‹æ–°è‡ªè¨‚æ¬„ä½
+  label_enumerations: åˆ—èˆ‰å€¼æ¸…å–®
+  label_enumeration_new: å»ºç«‹æ–°åˆ—èˆ‰å€¼
+  label_information: è³‡è¨Š
+  label_information_plural: è³‡è¨Š
+  label_please_login: è«‹å…ˆç™»å…¥
+  label_register: è¨»å†Š
+  label_login_with_open_id_option: æˆ–ä½¿ç”¨ OpenID ç™»å…¥
+  label_password_lost: éºå¤±å¯†ç¢¼
+  label_home: ç¶²ç«™é¦–é 
+  label_my_page: å¸³æˆ¶é¦–é 
+  label_my_account: æˆ‘çš„å¸³æˆ¶
+  label_my_projects: æˆ‘çš„å°ˆæ¡ˆ
+  label_my_page_block: å¸³æˆ¶é¦–é å€å¡Š
+  label_administration: ç¶²ç«™ç®¡ç†
+  label_login: ç™»å…¥
+  label_logout: ç™»å‡º
+  label_help: èªªæ˜Ž
+  label_reported_issues: æˆ‘é€šå ±çš„å•é¡Œ
+  label_assigned_to_me_issues: åˆ†æ´¾çµ¦æˆ‘çš„å•é¡Œ
+  label_last_login: æœ€è¿‘ä¸€æ¬¡é€£ç·š
+  label_registered_on: è¨»å†Šæ–¼
+  label_activity: æ´»å‹•
+  label_overall_activity: æ•´é«”æ´»å‹•
+  label_user_activity: "%{value} çš„æ´»å‹•"
+  label_new: å»ºç«‹æ–°çš„...
+  label_logged_as: ç›®å‰ç™»å…¥
+  label_environment: ç’°å¢ƒ
+  label_authentication: èªè­‰
+  label_auth_source: èªè­‰æ¨¡å¼
+  label_auth_source_new: å»ºç«‹æ–°èªè­‰æ¨¡å¼
+  label_auth_source_plural: èªè­‰æ¨¡å¼æ¸…å–®
+  label_subproject_plural: å­å°ˆæ¡ˆ
+  label_subproject_new: å»ºç«‹å­å°ˆæ¡ˆ
+  label_and_its_subprojects: "%{value} èˆ‡å…¶å­å°ˆæ¡ˆ"
+  label_min_max_length: æœ€å° - æœ€å¤§ é•·åº¦
+  label_list: æ¸…å–®
+  label_date: æ—¥æœŸ
+  label_integer: æ•´æ•¸
+  label_float: æµ®é»žæ•¸
+  label_boolean: å¸ƒæž—
+  label_string: æ–‡å­—
+  label_text: é•·æ–‡å­—
+  label_attribute: å±¬æ€§
+  label_attribute_plural: å±¬æ€§
+  label_no_data: æ²’æœ‰ä»»ä½•è³‡æ–™å¯ä¾›é¡¯ç¤º
+  label_change_status: è®Šæ›´ç‹€æ…‹
+  label_history: æ­·å²
+  label_attachment: æª”æ¡ˆ
+  label_attachment_new: å»ºç«‹æ–°æª”æ¡ˆ
+  label_attachment_delete: åˆªé™¤æª”æ¡ˆ
+  label_attachment_plural: æª”æ¡ˆ
+  label_file_added: æª”æ¡ˆå·²æ–°å¢ž
+  label_report: å ±å‘Š
+  label_report_plural: å ±å‘Š
+  label_news: æ–°èž
+  label_news_new: å»ºç«‹æ–°èž
+  label_news_plural: æ–°èž
+  label_news_latest: æœ€è¿‘æ–°èž
+  label_news_view_all: æª¢è¦–å…¨éƒ¨çš„æ–°èž
+  label_news_added: æ–°èžå·²æ–°å¢ž
+  label_news_comment_added: å›žæ‡‰å·²åŠ å…¥æ–°èž
+  label_settings: è¨­å®š
+  label_overview: æ¦‚è§€
+  label_version: ç‰ˆæœ¬
+  label_version_new: å»ºç«‹æ–°ç‰ˆæœ¬
+  label_version_plural: ç‰ˆæœ¬
+  label_close_versions: çµæŸå·²å®Œæˆçš„ç‰ˆæœ¬
+  label_confirmation: ç¢ºèª
+  label_export_to: åŒ¯å‡ºè‡³
+  label_read: è®€å–...
+  label_public_projects: å…¬é–‹å°ˆæ¡ˆ
+  label_open_issues: é€²è¡Œä¸­
+  label_open_issues_plural: é€²è¡Œä¸­
+  label_closed_issues: å·²çµæŸ
+  label_closed_issues_plural: å·²çµæŸ
+  label_x_open_issues_abbr_on_total:
+    zero:  0 é€²è¡Œä¸­ / å…± %{total}
+    one:   1 é€²è¡Œä¸­ / å…± %{total}
+    other: "%{count} é€²è¡Œä¸­ / å…± %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 é€²è¡Œä¸­
+    one:   1 é€²è¡Œä¸­
+    other: "%{count} é€²è¡Œä¸­"
+  label_x_closed_issues_abbr:
+    zero:  0 å·²çµæŸ
+    one:   1 å·²çµæŸ
+    other: "%{count} å·²çµæŸ"
+  label_x_issues:
+    zero:  0 å€‹å•é¡Œ
+    one:   1 å€‹å•é¡Œ
+    other: "%{count} å€‹å•é¡Œ"
+  label_total: ç¸½è¨ˆ
+  label_permissions: æ¬Šé™
+  label_current_status: ç›®å‰ç‹€æ…‹
+  label_new_statuses_allowed: å¯è®Šæ›´è‡³ä»¥ä¸‹ç‹€æ…‹
+  label_all: å…¨éƒ¨
+  label_any: ä»»æ„ä¸€å€‹
+  label_none: ç©ºå€¼
+  label_nobody: ç„¡å
+  label_next: ä¸‹ä¸€é 
+  label_previous: ä¸Šä¸€é 
+  label_used_by: Used by
+  label_details: æ˜Žç´°
+  label_add_note: åŠ å…¥ä¸€å€‹æ–°ç­†è¨˜
+  label_per_page: æ¯é 
+  label_calendar: æ—¥æ›†
+  label_months_from: å€‹æœˆ, é–‹å§‹æœˆä»½
+  label_gantt: ç”˜ç‰¹åœ–
+  label_internal: å…§éƒ¨
+  label_last_changes: "æœ€è¿‘ %{count} å€‹è®Šæ›´"
+  label_change_view_all: æª¢è¦–å…¨éƒ¨çš„è®Šæ›´
+  label_personalize_page: è‡ªè¨‚ç‰ˆé¢
+  label_comment: å›žæ‡‰
+  label_comment_plural: å›žæ‡‰
+  label_x_comments:
+    zero: ç„¡å›žæ‡‰
+    one: 1 å€‹å›žæ‡‰
+    other: "%{count} å€‹å›žæ‡‰"
+  label_comment_add: åŠ å…¥æ–°å›žæ‡‰
+  label_comment_added: æ–°å›žæ‡‰å·²åŠ å…¥
+  label_comment_delete: åˆªé™¤å›žæ‡‰
+  label_query: è‡ªè¨‚æŸ¥è©¢
+  label_query_plural: è‡ªè¨‚æŸ¥è©¢
+  label_query_new: å»ºç«‹æ–°æŸ¥è©¢
+  label_my_queries: æˆ‘çš„è‡ªè¨‚æŸ¥è©¢
+  label_filter_add: åŠ å…¥æ–°ç¯©é¸æ¢ä»¶
+  label_filter_plural: ç¯©é¸æ¢ä»¶
+  label_equals: ç­‰æ–¼
+  label_not_equals: ä¸ç­‰æ–¼
+  label_in_less_than: åœ¨å°æ–¼
+  label_in_more_than: åœ¨å¤§æ–¼
+  label_in_the_next_days: åœ¨æœªä¾†å¹¾å¤©ä¹‹å…§
+  label_in_the_past_days: åœ¨éŽåŽ»å¹¾å¤©ä¹‹å…§
+  label_greater_or_equal: "å¤§æ–¼ç­‰æ–¼ (>=)"
+  label_less_or_equal: "å°æ–¼ç­‰æ–¼ (<=)"
+  label_between: å€é–“
+  label_in: åœ¨
+  label_today: ä»Šå¤©
+  label_all_time: å…¨éƒ¨
+  label_yesterday: æ˜¨å¤©
+  label_this_week: æœ¬é€±
+  label_last_week: ä¸Šé€±
+  label_last_n_weeks: "éŽåŽ» %{count} é€±"
+  label_last_n_days: "éŽåŽ» %{count} å¤©"
+  label_this_month: é€™å€‹æœˆ
+  label_last_month: ä¸Šå€‹æœˆ
+  label_this_year: ä»Šå¹´
+  label_date_range: æ—¥æœŸå€é–“
+  label_less_than_ago: å°æ–¼å¹¾å¤©ä¹‹å‰
+  label_more_than_ago: å¤§æ–¼å¹¾å¤©ä¹‹å‰
+  label_ago: å¤©ä»¥å‰
+  label_contains: åŒ…å«
+  label_not_contains: ä¸åŒ…å«
+  label_any_issues_in_project: åœ¨å°ˆæ¡ˆä¸­çš„ä»»æ„å•é¡Œ
+  label_any_issues_not_in_project: ä¸åœ¨å°ˆæ¡ˆä¸­çš„ä»»æ„å•é¡Œ
+  label_no_issues_in_project: æ²’æœ‰å•é¡Œåœ¨å°ˆæ¡ˆä¸­
+  label_day_plural: å¤©
+  label_repository: å„²å­˜æ©Ÿåˆ¶
+  label_repository_new: å»ºç«‹æ–°å„²å­˜æ©Ÿåˆ¶
+  label_repository_plural: å„²å­˜æ©Ÿåˆ¶æ¸…å–®
+  label_browse: ç€è¦½
+  label_branch: åˆ†æ”¯
+  label_tag: æ¨™ç±¤
+  label_revision: ä¿®è¨‚ç‰ˆ
+  label_revision_plural: ä¿®è¨‚ç‰ˆæ¸…å–®
+  label_revision_id: "ä¿®è¨‚ç‰ˆ %{value}"
+  label_associated_revisions: é—œè¯çš„ä¿®è¨‚ç‰ˆ
+  label_added: å·²æ–°å¢ž
+  label_modified: å·²ä¿®æ”¹
+  label_copied: å·²è¤‡è£½
+  label_renamed: å·²é‡æ–°å‘½å
+  label_deleted: å·²åˆªé™¤
+  label_latest_revision: æœ€æ–°çš„ä¿®è¨‚ç‰ˆ
+  label_latest_revision_plural: æœ€æ–°çš„ä¿®è¨‚ç‰ˆæ¸…å–®
+  label_view_revisions: æª¢è¦–ä¿®è¨‚ç‰ˆæ¸…å–®
+  label_view_all_revisions: æª¢è¦–æ‰€æœ‰çš„çš„ä¿®è¨‚ç‰ˆæ¸…å–®
+  label_max_size: æœ€å¤§é•·åº¦
+  label_sort_highest: ç§»å‹•è‡³é–‹é ­
+  label_sort_higher: å¾€ä¸Šç§»å‹•
+  label_sort_lower: å¾€ä¸‹ç§»å‹•
+  label_sort_lowest: ç§»å‹•è‡³çµå°¾
+  label_roadmap: ç‰ˆæœ¬è—åœ–
+  label_roadmap_due_in: "å‰©é¤˜ %{value}"
+  label_roadmap_overdue: "é€¾æœŸ %{value}"
+  label_roadmap_no_issues: æ­¤ç‰ˆæœ¬å°šæœªåŒ…å«ä»»ä½•å•é¡Œ
+  label_search: æœå°‹
+  label_result_plural: çµæžœ
+  label_all_words: åŒ…å«å…¨éƒ¨çš„å­—è©ž
+  label_wiki: Wiki
+  label_wiki_edit: Wiki ç·¨è¼¯
+  label_wiki_edit_plural: Wiki ç·¨è¼¯
+  label_wiki_page: Wiki ç¶²é 
+  label_wiki_page_plural: Wiki ç¶²é 
+  label_index_by_title: ä¾æ¨™é¡Œç´¢å¼•
+  label_index_by_date: ä¾æ—¥æœŸç´¢å¼•
+  label_current_version: ç¾è¡Œç‰ˆæœ¬
+  label_preview: é è¦½
+  label_feed_plural: Feeds
+  label_changes_details: æ‰€æœ‰è®Šæ›´çš„æ˜Žç´°
+  label_issue_tracking: å•é¡Œè¿½è¹¤
+  label_spent_time: è€—ç”¨å·¥æ™‚
+  label_overall_spent_time: æ•´é«”è€—ç”¨å·¥æ™‚
+  label_f_hour: "%{value} å°æ™‚"
+  label_f_hour_plural: "%{value} å°æ™‚"
+  label_time_tracking: å·¥æ™‚è¿½è¹¤
+  label_change_plural: è®Šæ›´
+  label_statistics: çµ±è¨ˆè³‡è¨Š
+  label_commits_per_month: ä¾æœˆä»½çµ±è¨ˆèªå¯
+  label_commits_per_author: ä¾ä½œè€…çµ±è¨ˆèªå¯
+  label_view_diff: æª¢è¦–å·®ç•°
+  label_diff: å·®ç•°
+  label_diff_inline: ç›´åˆ—
+  label_diff_side_by_side: ä¸¦æŽ’
+  label_options: é¸é …æ¸…å–®
+  label_copy_workflow_from: å¾žä»¥ä¸‹è¿½è¹¤æ¨™ç±¤è¤‡è£½å·¥ä½œæµç¨‹
+  label_permissions_report: æ¬Šé™å ±è¡¨
+  label_watched_issues: ç›£çœ‹ä¸­çš„å•é¡Œæ¸…å–®
+  label_related_issues: ç›¸é—œçš„å•é¡Œæ¸…å–®
+  label_applied_status: å·²å¥—ç”¨ç‹€æ…‹
+  label_loading: è¼‰å…¥ä¸­...
+  label_relation_new: å»ºç«‹æ–°é—œè¯
+  label_relation_delete: åˆªé™¤é—œè¯
+  label_relates_to: é—œè¯è‡³
+  label_duplicates: å·²é‡è¤‡
+  label_duplicated_by: èˆ‡å¾Œé¢æ‰€åˆ—å•é¡Œé‡è¤‡
+  label_blocks: é˜»æ“‹
+  label_blocked_by: è¢«é˜»æ“‹
+  label_precedes: å„ªå…ˆæ–¼
+  label_follows: è·Ÿéš¨æ–¼
+  label_copied_to: è¤‡è£½åˆ°
+  label_copied_from: è¤‡è£½æ–¼
+  label_end_to_start: çµæŸâ”€é–‹å§‹
+  label_end_to_end: çµæŸâ”€çµæŸ
+  label_start_to_start: é–‹å§‹â”€é–‹å§‹
+  label_start_to_end: é–‹å§‹â”€çµæŸ
+  label_stay_logged_in: ç¶­æŒå·²ç™»å…¥ç‹€æ…‹
+  label_disabled: é—œé–‰
+  label_show_completed_versions: é¡¯ç¤ºå·²å®Œæˆçš„ç‰ˆæœ¬
+  label_me: æˆ‘è‡ªå·±
+  label_board: è«–å£‡
+  label_board_new: å»ºç«‹æ–°è«–å£‡
+  label_board_plural: è«–å£‡
+  label_board_locked: éŽ–å®š
+  label_board_sticky: ç½®é ‚
+  label_topic_plural: è¨Žè«–ä¸»é¡Œ
+  label_message_plural: è¨Šæ¯
+  label_message_last: ä¸Šä¸€å°è¨Šæ¯
+  label_message_new: å»ºç«‹æ–°è¨Šæ¯
+  label_message_posted: è¨Šæ¯å·²æ–°å¢ž
+  label_reply_plural: å›žæ‡‰
+  label_send_information: å¯„é€å¸³æˆ¶è³‡è¨Šé›»å­éƒµä»¶çµ¦ç”¨æˆ¶
+  label_year: å¹´
+  label_month: æœˆ
+  label_week: é€±
+  label_date_from: é–‹å§‹
+  label_date_to: çµæŸ
+  label_language_based: ä¾ç”¨æˆ¶ä¹‹èªžç³»æ±ºå®š
+  label_sort_by: "æŒ‰ %{value} æŽ’åº"
+  label_send_test_email: å¯„é€æ¸¬è©¦éƒµä»¶
+  label_feeds_access_key: RSS å­˜å–é‡‘é‘°
+  label_missing_feeds_access_key: æ‰¾ä¸åˆ° RSS å­˜å–é‡‘é‘°
+  label_feeds_access_key_created_on: "RSS å­˜å–éµå»ºç«‹æ–¼ %{value} ä¹‹å‰"
+  label_module_plural: æ¨¡çµ„
+  label_added_time_by: "æ˜¯ç”± %{author} æ–¼ %{age} å‰åŠ å…¥"
+  label_updated_time_by: "æ˜¯ç”± %{author} æ–¼ %{age} å‰æ›´æ–°"
+  label_updated_time: "æ–¼ %{value} å‰æ›´æ–°"
+  label_jump_to_a_project: é¸æ“‡æ¬²å‰å¾€çš„å°ˆæ¡ˆ...
+  label_file_plural: æª”æ¡ˆæ¸…å–®
+  label_changeset_plural: è®Šæ›´é›†æ¸…å–®
+  label_default_columns: é è¨­æ¬„ä½æ¸…å–®
+  label_no_change_option: (ç¶­æŒä¸è®Š)
+  label_bulk_edit_selected_issues: å¤§é‡ç·¨è¼¯é¸å–çš„å•é¡Œ
+  label_bulk_edit_selected_time_entries: å¤§é‡ç·¨è¼¯é¸å–çš„å·¥æ™‚é …ç›®
+  label_theme: ç•«é¢ä¸»é¡Œ
+  label_default: é è¨­
+  label_search_titles_only: åƒ…æœå°‹æ¨™é¡Œ
+  label_user_mail_option_all: "æé†’èˆ‡æˆ‘çš„å°ˆæ¡ˆæœ‰é—œçš„å…¨éƒ¨äº‹ä»¶"
+  label_user_mail_option_selected: "åªæé†’æˆ‘æ‰€é¸æ“‡å°ˆæ¡ˆä¸­çš„äº‹ä»¶..."
+  label_user_mail_option_none: "å–æ¶ˆæé†’"
+  label_user_mail_option_only_my_events: "åªæé†’æˆ‘è§€å¯Ÿä¸­æˆ–åƒèˆ‡ä¸­çš„äº‹ç‰©"
+  label_user_mail_option_only_assigned: "åªæé†’æˆ‘è¢«æŒ‡æ´¾çš„äº‹ç‰©"
+  label_user_mail_option_only_owner: "åªæé†’æˆ‘ä½œç‚ºæ“æœ‰è€…çš„äº‹ç‰©"
+  label_user_mail_no_self_notified: "ä¸æé†’æˆ‘è‡ªå·±æ‰€åšçš„è®Šæ›´"
+  label_registration_activation_by_email: é€éŽé›»å­éƒµä»¶å•Ÿç”¨å¸³æˆ¶
+  label_registration_manual_activation: æ‰‹å‹•å•Ÿç”¨å¸³æˆ¶
+  label_registration_automatic_activation: è‡ªå‹•å•Ÿç”¨å¸³æˆ¶
+  label_display_per_page: "æ¯é é¡¯ç¤º: %{value} å€‹"
+  label_age: å¹´é½¡
+  label_change_properties: è®Šæ›´å±¬æ€§
+  label_general: ä¸€èˆ¬
+  label_more: æ›´å¤š Â»
+  label_scm: ç‰ˆæœ¬æŽ§ç®¡
+  label_plugins: é™„åŠ å…ƒä»¶
+  label_ldap_authentication: LDAP èªè­‰
+  label_downloads_abbr: ä¸‹è¼‰
+  label_optional_description: é¡å¤–çš„èªªæ˜Ž
+  label_add_another_file: å¢žåŠ å…¶ä»–æª”æ¡ˆ
+  label_preferences: åå¥½é¸é …
+  label_chronological_order: ä»¥æ™‚é–“ç”±é è‡³è¿‘æŽ’åº
+  label_reverse_chronological_order: ä»¥æ™‚é–“ç”±è¿‘è‡³é æŽ’åº
+  label_planning: è¨ˆåŠƒè¡¨
+  label_incoming_emails: å‚³å…¥çš„é›»å­éƒµä»¶
+  label_generate_key: ç”¢ç”Ÿé‡‘é‘°
+  label_issue_watchers: ç›£çœ‹è€…
+  label_example: ç¯„ä¾‹
+  label_display: é¡¯ç¤º
+  label_sort: æŽ’åº
+  label_ascending: éžå¢žæŽ’åº
+  label_descending: éžæ¸›æŽ’åº
+  label_date_from_to: èµ· %{start} è¿„ %{end}
+  label_wiki_content_added: Wiki é é¢å·²æ–°å¢ž
+  label_wiki_content_updated: Wiki é é¢å·²æ›´æ–°
+  label_group: ç¾¤çµ„
+  label_group_plural: ç¾¤çµ„æ¸…å–®
+  label_group_new: å»ºç«‹æ–°ç¾¤çµ„
+  label_time_entry_plural: è€—ç”¨å·¥æ™‚
+  label_version_sharing_none: ä¸å…±ç”¨
+  label_version_sharing_descendants: èˆ‡å­å°ˆæ¡ˆå…±ç”¨
+  label_version_sharing_hierarchy: èˆ‡å°ˆæ¡ˆéšŽå±¤æž¶æ§‹å…±ç”¨
+  label_version_sharing_tree: èˆ‡å°ˆæ¡ˆæ¨¹å…±ç”¨
+  label_version_sharing_system: èˆ‡å…¨éƒ¨çš„å°ˆæ¡ˆå…±ç”¨
+  label_update_issue_done_ratios: æ›´æ–°å•é¡Œå®Œæˆç™¾åˆ†æ¯”
+  label_copy_source: ä¾†æº
+  label_copy_target: ç›®çš„åœ°
+  label_copy_same_as_target: èˆ‡ç›®çš„åœ°ç›¸åŒ
+  label_display_used_statuses_only: åƒ…é¡¯ç¤ºæ­¤è¿½è¹¤æ¨™ç±¤æ‰€ä½¿ç”¨ä¹‹ç‹€æ…‹
+  label_api_access_key: API å­˜å–é‡‘é‘°
+  label_missing_api_access_key: æ‰¾ä¸åˆ° API å­˜å–é‡‘é‘°
+  label_api_access_key_created_on: "API å­˜å–é‡‘é‘°å»ºç«‹æ–¼ %{value} ä¹‹å‰"
+  label_profile: é…ç½®æ¦‚æ³
+  label_subtask_plural: å­ä»»å‹™
+  label_project_copy_notifications: åœ¨è¤‡è£½å°ˆæ¡ˆçš„éŽç¨‹ä¸­ï¼Œå‚³é€é€šçŸ¥éƒµä»¶
+  label_principal_search: "æœå°‹ç”¨æˆ¶æˆ–ç¾¤çµ„ï¼š"
+  label_user_search: "æœå°‹ç”¨æˆ¶ï¼š"
+  label_additional_workflow_transitions_for_author: ç”¨æˆ¶ç‚ºä½œè€…æ™‚é¡å¤–å…è¨±çš„æµç¨‹è½‰æ›
+  label_additional_workflow_transitions_for_assignee: ç”¨æˆ¶ç‚ºè¢«æŒ‡å®šè€…æ™‚é¡å¤–å…è¨±çš„æµç¨‹è½‰æ›
+  label_issues_visibility_all: æ‰€æœ‰å•é¡Œ
+  label_issues_visibility_public: æ‰€æœ‰éžç§äººå•é¡Œ
+  label_issues_visibility_own: ä½¿ç”¨è€…æ‰€å»ºç«‹çš„æˆ–è¢«æŒ‡æ´¾çš„å•é¡Œ
+  label_git_report_last_commit: å ±å‘Šæœ€å¾Œèªå¯çš„æ–‡ä»¶å’Œç›®éŒ„
+  label_parent_revision: çˆ¶é …
+  label_child_revision: å­é …
+  label_export_options: "%{export_format} åŒ¯å‡ºé¸é …"
+  label_copy_attachments: è¤‡è£½é™„ä»¶
+  label_copy_subtasks: è¤‡è£½å­ä»»å‹™
+  label_item_position: "%{position} / %{count}"
+  label_completed_versions: å·²å®Œæˆç‰ˆæœ¬
+  label_search_for_watchers: æœå°‹å¯ä¾›åŠ å…¥çš„ç›£çœ‹è€…
+  label_session_expiration: å·¥ä½œéšŽæ®µé€¾æœŸ
+  label_show_closed_projects: æª¢è¦–å·²é—œé–‰çš„å°ˆæ¡ˆ
+  label_status_transitions: ç‹€æ…‹è½‰æ›
+  label_fields_permissions: æ¬„ä½æ¬Šé™
+  label_readonly: å”¯è®€
+  label_required: å¿…å¡«
+  label_attribute_of_project: "å°ˆæ¡ˆæ˜¯ %{name}"
+  label_attribute_of_issue: "å•é¡Œæ˜¯ %{name}"
+  label_attribute_of_author: "ä½œè€…æ˜¯ %{name}"
+  label_attribute_of_assigned_to: "è¢«æŒ‡æ´¾è€…æ˜¯ %{name}"
+  label_attribute_of_user: "ç”¨æˆ¶æ˜¯ %{name}"
+  label_attribute_of_fixed_version: "ç‰ˆæœ¬æ˜¯ %{name}"
+  label_cross_project_descendants: èˆ‡å­å°ˆæ¡ˆå…±ç”¨
+  label_cross_project_tree: èˆ‡å°ˆæ¡ˆæ¨¹å…±ç”¨
+  label_cross_project_hierarchy: èˆ‡å°ˆæ¡ˆéšŽå±¤æž¶æ§‹å…±ç”¨
+  label_cross_project_system: èˆ‡å…¨éƒ¨çš„å°ˆæ¡ˆå…±ç”¨
+  label_gantt_progress_line: é€²åº¦ç·š
+
+  button_login: ç™»å…¥
+  button_submit: é€å‡º
+  button_save: å„²å­˜
+  button_check_all: å…¨é¸
+  button_uncheck_all: å…¨ä¸é¸
+  button_collapse_all: å…¨éƒ¨æ‘ºç–Š
+  button_expand_all: å…¨éƒ¨å±•é–‹
+  button_delete: åˆªé™¤
+  button_create: å»ºç«‹
+  button_create_and_continue: ç¹¼çºŒå»ºç«‹
+  button_test: æ¸¬è©¦
+  button_edit: ç·¨è¼¯
+  button_edit_associated_wikipage: "ç·¨è¼¯ç›¸é—œ Wiki é é¢: %{page_title}"
+  button_add: æ–°å¢ž
+  button_change: ä¿®æ”¹
+  button_apply: å¥—ç”¨
+  button_clear: æ¸…é™¤
+  button_lock: éŽ–å®š
+  button_unlock: è§£é™¤éŽ–å®š
+  button_download: ä¸‹è¼‰
+  button_list: æ¸…å–®
+  button_view: æª¢è¦–
+  button_move: ç§»å‹•
+  button_move_and_follow: ç§»å‹•å¾Œè·Ÿéš¨
+  button_back: è¿”å›ž
+  button_cancel: å–æ¶ˆ
+  button_activate: å•Ÿç”¨
+  button_sort: æŽ’åº
+  button_log_time: è¨˜éŒ„æ™‚é–“
+  button_rollback: é‚„åŽŸè‡³æ­¤ç‰ˆæœ¬
+  button_watch: è§€å¯Ÿ
+  button_unwatch: å–æ¶ˆè§€å¯Ÿ
+  button_reply: å›žæ‡‰
+  button_archive: å°å­˜
+  button_unarchive: å–æ¶ˆå°å­˜
+  button_reset: å›žå¾©
+  button_rename: é‡æ–°å‘½å
+  button_change_password: è®Šæ›´å¯†ç¢¼
+  button_copy: è¤‡è£½
+  button_copy_and_follow: è¤‡è£½å¾Œè·Ÿéš¨
+  button_annotate: è¨»è§£
+  button_update: æ›´æ–°
+  button_configure: è¨­å®š
+  button_quote: å¼•ç”¨
+  button_duplicate: é‡è£½
+  button_show: é¡¯ç¤º
+  button_hide: éš±è—
+  button_edit_section: ç·¨è¼¯æ­¤å€å¡Š
+  button_export: åŒ¯å‡º
+  button_delete_my_account: åˆªé™¤æˆ‘çš„å¸³æˆ¶
+  button_close: é—œé–‰
+  button_reopen: é‡æ–°é–‹å•Ÿ
+
+  status_active: æ´»å‹•ä¸­
+  status_registered: è¨»å†Šå®Œæˆ
+  status_locked: éŽ–å®šä¸­
+
+  project_status_active: ä½¿ç”¨ä¸­
+  project_status_closed: å·²é—œé–‰
+  project_status_archived: å·²å°å­˜
+
+  version_status_open: é€²è¡Œä¸­
+  version_status_locked: å·²éŽ–å®š
+  version_status_closed: å·²çµæŸ
+
+  field_active: æ´»å‹•ä¸­
+
+  text_select_mail_notifications: é¸æ“‡æ¬²å¯„é€æé†’é€šçŸ¥éƒµä»¶ä¹‹å‹•ä½œ
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 ä»£è¡¨ã€Œä¸é™åˆ¶ã€
+  text_project_destroy_confirmation: æ‚¨ç¢ºå®šè¦åˆªé™¤é€™å€‹å°ˆæ¡ˆå’Œå…¶ä»–ç›¸é—œè³‡æ–™ï¼Ÿ
+  text_subprojects_destroy_warning: "ä¸‹åˆ—å­å°ˆæ¡ˆï¼š %{value} å°‡ä¸€ä½µè¢«åˆªé™¤ã€‚"
+  text_workflow_edit: é¸æ“‡è§’è‰²èˆ‡è¿½è¹¤æ¨™ç±¤ä»¥è¨­å®šå…¶å·¥ä½œæµç¨‹
+  text_are_you_sure: ç¢ºå®šåŸ·è¡Œï¼Ÿ
+  text_journal_changed: "%{label} å¾ž %{old} è®Šæ›´ç‚º %{new}"
+  text_journal_changed_no_detail: "%{label} å·²æ›´æ–°"
+  text_journal_set_to: "%{label} è¨­å®šç‚º %{value}"
+  text_journal_deleted: "%{label} å·²åˆªé™¤ (%{old})"
+  text_journal_added: "%{label} %{value} å·²æ–°å¢ž"
+  text_tip_issue_begin_day: ä»Šå¤©èµ·å§‹çš„å•é¡Œ
+  text_tip_issue_end_day: ä»Šå¤©æˆªæ­¢çš„çš„å•é¡Œ
+  text_tip_issue_begin_end_day: ä»Šå¤©èµ·å§‹èˆ‡æˆªæ­¢çš„å•é¡Œ
+  text_project_identifier_info: 'åƒ…å…è¨±ä½¿ç”¨å°å¯«è‹±æ–‡å­—æ¯ (a-z), é˜¿æ‹‰ä¼¯æ•¸å­—, è™›ç·šèˆ‡åº•ç·šã€‚<br />ä¸€æ—¦å„²å­˜ä¹‹å¾Œ, ä»£ç¢¼ä¾¿ç„¡æ³•å†æ¬¡è¢«æ›´æ”¹ã€‚'
+  text_caracters_maximum: "æœ€å¤š %{count} å€‹å­—å…ƒ."
+  text_caracters_minimum: "é•·åº¦å¿…é ˆå¤§æ–¼ %{count} å€‹å­—å…ƒ."
+  text_length_between: "é•·åº¦å¿…é ˆä»‹æ–¼ %{min} è‡³ %{max} å€‹å­—å…ƒä¹‹é–“."
+  text_tracker_no_workflow: æ­¤è¿½è¹¤æ¨™ç±¤å°šæœªå®šç¾©å·¥ä½œæµç¨‹
+  text_unallowed_characters: ä¸å…è¨±çš„å­—å…ƒ
+  text_comma_separated: å¯è¼¸å…¥å¤šå€‹å€¼ï¼ˆé ˆä»¥é€—è™Ÿåˆ†éš”ï¼‰ã€‚
+  text_line_separated: å¯è¼¸å…¥å¤šå€‹å€¼ï¼ˆé ˆä»¥æ›è¡Œç¬¦è™Ÿåˆ†éš”ï¼Œå³æ¯åˆ—åªèƒ½è¼¸å…¥ä¸€å€‹å€¼ï¼‰ã€‚
+  text_issues_ref_in_commit_messages: èªå¯è¨Šæ¯ä¸­åƒç…§(æˆ–ä¿®æ­£)å•é¡Œä¹‹é—œéµå­—
+  text_issue_added: "å•é¡Œ %{id} å·²è¢« %{author} é€šå ±ã€‚"
+  text_issue_updated: "å•é¡Œ %{id} å·²è¢« %{author} æ›´æ–°ã€‚"
+  text_wiki_destroy_confirmation: æ‚¨ç¢ºå®šè¦åˆªé™¤é€™å€‹ wiki å’Œå…¶ä¸­çš„æ‰€æœ‰å…§å®¹ï¼Ÿ
+  text_issue_category_destroy_question: "æœ‰ (%{count}) å€‹å•é¡Œè¢«æŒ‡æ´¾åˆ°æ­¤åˆ†é¡ž. è«‹é¸æ“‡æ‚¨æƒ³è¦çš„å‹•ä½œï¼Ÿ"
+  text_issue_category_destroy_assignments: ç§»é™¤é€™äº›å•é¡Œçš„åˆ†é¡ž
+  text_issue_category_reassign_to: é‡æ–°æŒ‡æ´¾é€™äº›å•é¡Œè‡³å…¶å®ƒåˆ†é¡ž
+  text_user_mail_option: "å°æ–¼é‚£äº›æœªè¢«é¸æ“‡çš„å°ˆæ¡ˆï¼Œå°‡åªæœƒæŽ¥æ”¶åˆ°æ‚¨æ­£åœ¨è§€å¯Ÿä¸­ï¼Œæˆ–æ˜¯åƒèˆ‡ä¸­çš„å•é¡Œé€šçŸ¥ã€‚ï¼ˆã€Œåƒèˆ‡ä¸­çš„å•é¡Œã€åŒ…å«æ‚¨å»ºç«‹çš„æˆ–æ˜¯æŒ‡æ´¾çµ¦æ‚¨çš„å•é¡Œï¼‰"
+  text_no_configuration_data: "è§’è‰²ã€è¿½è¹¤æ¨™ç±¤ã€å•é¡Œç‹€æ…‹èˆ‡æµç¨‹å°šæœªè¢«è¨­å®šå®Œæˆã€‚\nå¼·çƒˆå»ºè­°æ‚¨å…ˆè¼‰å…¥é è¨­çš„çµ„æ…‹ã€‚å°‡é è¨­çµ„æ…‹è¼‰å…¥ä¹‹å¾Œï¼Œæ‚¨å¯å†è®Šæ›´å…¶ä¸­ä¹‹å€¼ã€‚"
+  text_load_default_configuration: è¼‰å…¥é è¨­çµ„æ…‹
+  text_status_changed_by_changeset: "å·²å¥—ç”¨è‡³è®Šæ›´é›† %{value}."
+  text_time_logged_by_changeset: "ç´€éŒ„æ–¼è®Šæ›´é›† %{value}."
+  text_issues_destroy_confirmation: 'ç¢ºå®šåˆªé™¤å·²é¸æ“‡çš„å•é¡Œï¼Ÿ'
+  text_issues_destroy_descendants_confirmation: "é€™éº¼åšå°‡æœƒä¸€ä½µåˆªé™¤ %{count} å­ä»»å‹™ã€‚"
+  text_time_entries_destroy_confirmation: æ‚¨ç¢ºå®šè¦åˆªé™¤æ‰€é¸æ“‡çš„å·¥æ™‚ç´€éŒ„ï¼Ÿ
+  text_select_project_modules: 'é¸æ“‡æ­¤å°ˆæ¡ˆå¯ä½¿ç”¨ä¹‹æ¨¡çµ„ï¼š'
+  text_default_administrator_account_changed: å·²è®Šæ›´é è¨­ç®¡ç†å“¡å¸³è™Ÿå…§å®¹
+  text_file_repository_writable: å¯å¯«å…¥é™„åŠ æª”æ¡ˆç›®éŒ„
+  text_plugin_assets_writable: å¯å¯«å…¥é™„åŠ å…ƒä»¶ç›®éŒ„
+  text_rmagick_available: å¯ä½¿ç”¨ RMagick (é¸é…)
+  text_destroy_time_entries_question: æ‚¨å³å°‡åˆªé™¤çš„å•é¡Œå·²å ±å·¥ %{hours} å°æ™‚. æ‚¨çš„é¸æ“‡æ˜¯ï¼Ÿ
+  text_destroy_time_entries: åˆªé™¤å·²å ±å·¥çš„æ™‚æ•¸
+  text_assign_time_entries_to_project: æŒ‡å®šå·²å ±å·¥çš„æ™‚æ•¸è‡³å°ˆæ¡ˆä¸­
+  text_reassign_time_entries: 'é‡æ–°æŒ‡å®šå·²å ±å·¥çš„æ™‚æ•¸è‡³æ­¤å•é¡Œï¼š'
+  text_user_wrote: "%{value} å…ˆå‰æåˆ°:"
+  text_enumeration_destroy_question: "ç›®å‰æœ‰ %{count} å€‹ç‰©ä»¶ä½¿ç”¨æ­¤åˆ—èˆ‰å€¼ã€‚"
+  text_enumeration_category_reassign_to: 'é‡æ–°è¨­å®šå…¶åˆ—èˆ‰å€¼ç‚ºï¼š'
+  text_email_delivery_not_configured: "æ‚¨å°šæœªè¨­å®šé›»å­éƒµä»¶å‚³é€æ–¹å¼ï¼Œå› æ­¤æé†’é¸é …å·²è¢«åœç”¨ã€‚\nè«‹åœ¨ config/configuration.yml ä¸­è¨­å®š SMTP ä¹‹å¾Œï¼Œé‡æ–°å•Ÿå‹• Redmineï¼Œä»¥å•Ÿç”¨é›»å­éƒµä»¶æé†’é¸é …ã€‚"
+  text_repository_usernames_mapping: "é¸æ“‡æˆ–æ›´æ–° Redmine ä½¿ç”¨è€…èˆ‡å„²å­˜æ©Ÿåˆ¶ç´€éŒ„ä½¿ç”¨è€…ä¹‹å°æ‡‰é—œä¿‚ã€‚\nå„²å­˜æ©Ÿåˆ¶ä¸­ä¹‹ä½¿ç”¨è€…å¸³è™Ÿæˆ–é›»å­éƒµä»¶ä¿¡ç®±ï¼Œèˆ‡ Redmine è¨­å®šç›¸åŒè€…ï¼Œå°‡è‡ªå‹•ç”¢ç”Ÿå°æ‡‰é—œä¿‚ã€‚"
+  text_diff_truncated: '... é€™ä»½å·®ç•°å·²è¢«æˆªçŸ­ä»¥ç¬¦åˆé¡¯ç¤ºè¡Œæ•¸ä¹‹æœ€å¤§å€¼'
+  text_custom_field_possible_values_info: 'ä¸€åˆ—è¼¸å…¥ä¸€å€‹å€¼'
+  text_wiki_page_destroy_question: "æ­¤é é¢åŒ…å« %{descendants} å€‹å­é é¢åŠå»¶ä¼¸é é¢ã€‚ è«‹é¸æ“‡æ‚¨æƒ³è¦çš„å‹•ä½œ?"
+  text_wiki_page_nullify_children: "ä¿ç•™æ‰€æœ‰å­é é¢ç•¶ä½œæ ¹é é¢"
+  text_wiki_page_destroy_children: "åˆªé™¤æ‰€æœ‰å­é é¢åŠå…¶å»¶ä¼¸é é¢"
+  text_wiki_page_reassign_children: "é‡æ–°æŒ‡å®šæ‰€æœ‰çš„å­é é¢ä¹‹çˆ¶é é¢è‡³æ­¤é é¢"
+  text_own_membership_delete_confirmation: "æ‚¨åœ¨å°ˆæ¡ˆä¸­ï¼Œæ‰€æ“æœ‰çš„éƒ¨åˆ†æˆ–å…¨éƒ¨æ¬Šé™å³å°‡è¢«ç§»é™¤ï¼Œåœ¨é€™ä¹‹å¾Œå¯èƒ½ç„¡æ³•å†æ¬¡ç·¨è¼¯æ­¤å°ˆæ¡ˆã€‚\næ‚¨ç¢ºå®šè¦ç¹¼çºŒåŸ·è¡Œé€™å€‹å‹•ä½œï¼Ÿ"
+  text_zoom_in: æ”¾å¤§
+  text_zoom_out: ç¸®å°
+  text_warn_on_leaving_unsaved: "è‹¥æ‚¨é›¢é–‹é€™å€‹é é¢ï¼Œæ­¤é é¢æ‰€åŒ…å«çš„æœªå„²å­˜è³‡æ–™å°‡æœƒéºå¤±ã€‚"
+  text_scm_path_encoding_note: "é è¨­: UTF-8"
+  text_git_repository_note: å„²å­˜æ©Ÿåˆ¶æ˜¯æœ¬æ©Ÿçš„ç©º(bare)ç›®éŒ„ (å³ï¼š /gitrepo, c:\gitrepo)
+  text_mercurial_repository_note: æœ¬æ©Ÿå„²å­˜æ©Ÿåˆ¶ (å³ï¼š /hgrepo, c:\hgrepo)
+  text_scm_command: å‘½ä»¤
+  text_scm_command_version: ç‰ˆæœ¬
+  text_scm_config: æ‚¨å¯ä»¥åœ¨ config/configuration.yml ä¸­è¨­å®š SCM å‘½ä»¤ã€‚è«‹åœ¨ç·¨è¼¯è©²æª”æ¡ˆä¹‹å¾Œé‡æ–°å•Ÿå‹• Redmine æ‡‰ç”¨ç¨‹å¼ã€‚
+  text_scm_command_not_available: SCM å‘½ä»¤ç„¡æ³•ä½¿ç”¨ã€‚è«‹æª¢æŸ¥ç®¡ç†é¢æ¿ä¸­çš„è¨­å®šã€‚
+  text_issue_conflict_resolution_overwrite: "ç›´æŽ¥å¥—ç”¨æˆ‘çš„è®Šæ›´ (å…ˆå‰çš„ç­†è¨˜å°‡æœƒè¢«ä¿ç•™ï¼Œä½†æ˜¯æŸäº›è®Šæ›´å¯èƒ½æœƒè¢«è¤‡å¯«)"
+  text_issue_conflict_resolution_add_notes: "æ–°å¢žæˆ‘çš„ç­†è¨˜ä¸¦æ¨æ£„æˆ‘å…¶ä»–çš„è®Šæ›´"
+  text_issue_conflict_resolution_cancel: "æ¨æ£„æˆ‘å…¨éƒ¨çš„è®Šæ›´ä¸¦é‡æ–°é¡¯ç¤º %{link}"
+  text_account_destroy_confirmation: |-
+    æ‚¨ç¢ºå®šè¦ç¹¼çºŒé€™å€‹å‹•ä½œå—Žï¼Ÿ
+    æ‚¨çš„å¸³æˆ¶å°‡æœƒè¢«æ°¸ä¹…åˆªé™¤ï¼Œä¸”ç„¡æ³•è¢«é‡æ–°å•Ÿç”¨ã€‚
+  text_session_expiration_settings: "è­¦å‘Šï¼šè®Šæ›´é€™äº›è¨­å®šå°‡æœƒå°Žè‡´åŒ…å«æ‚¨åœ¨å…§çš„æ‰€æœ‰å·¥ä½œéšŽæ®µéŽæœŸã€‚"
+  text_project_closed: æ­¤å°ˆæ¡ˆå·²è¢«é—œé–‰ï¼Œåƒ…ä¾›å”¯è®€ä½¿ç”¨ã€‚
+  text_turning_multiple_off: "è‹¥æ‚¨åœç”¨å¤šé‡å€¼è¨­å®šï¼Œé‡è¤‡çš„å€¼å°‡æœƒè¢«ç§»é™¤ï¼Œä»¥ä½¿æ¯å€‹é …ç›®åƒ…ä¿ç•™ä¸€å€‹å€¼ã€‚"
+
+  default_role_manager: ç®¡ç†äººå“¡
+  default_role_developer: é–‹ç™¼äººå“¡
+  default_role_reporter: å ±å‘Šäººå“¡
+  default_tracker_bug: è‡­èŸ²
+  default_tracker_feature: åŠŸèƒ½
+  default_tracker_support: æ”¯æ´
+  default_issue_status_new: æ–°å»ºç«‹
+  default_issue_status_in_progress: å¯¦ä½œä¸­
+  default_issue_status_resolved: å·²è§£æ±º
+  default_issue_status_feedback: å·²å›žæ‡‰
+  default_issue_status_closed: å·²çµæŸ
+  default_issue_status_rejected: å·²æ‹’çµ•
+  default_doc_category_user: ä½¿ç”¨æ‰‹å†Š
+  default_doc_category_tech: æŠ€è¡“æ–‡ä»¶
+  default_priority_low: ä½Ž
+  default_priority_normal: æ­£å¸¸
+  default_priority_high: é«˜
+  default_priority_urgent: é€Ÿ
+  default_priority_immediate: æ€¥
+  default_activity_design: è¨­è¨ˆ
+  default_activity_development: é–‹ç™¼
+
+  enumeration_issue_priorities: å•é¡Œå„ªå…ˆæ¬Š
+  enumeration_doc_categories: æ–‡ä»¶åˆ†é¡ž
+  enumeration_activities: æ´»å‹• (æ™‚é–“è¿½è¹¤)
+  enumeration_system_activity: ç³»çµ±æ´»å‹•
+  description_filter: ç¯©é¸æ¢ä»¶
+  description_search: æœå°‹æ¬„ä½
+  description_choose_project: å°ˆæ¡ˆæ¸…å–®
+  description_project_scope: æœå°‹ç¯„åœ
+  description_notes: ç­†è¨˜
+  description_message_content: è¨Šæ¯å…§å®¹
+  description_query_sort_criteria_attribute: æŽ’åºå±¬æ€§
+  description_query_sort_criteria_direction: æŽ’åˆ—é †åº
+  description_user_mail_notification: éƒµä»¶é€šçŸ¥è¨­å®š
+  description_available_columns: å¯ç”¨æ¬„ä½
+  description_selected_columns: å·²é¸å–çš„æ¬„ä½
+  description_all_columns: æ‰€æœ‰æ¬„ä½
+  description_issue_category_reassign: é¸æ“‡å•é¡Œåˆ†é¡ž
+  description_wiki_subpages_reassign: é¸æ“‡æ–°çš„çˆ¶é é¢
+  description_date_range_list: å¾žæ¸…å–®ä¸­é¸å–ç¯„åœ
+  description_date_range_interval: é¸æ“‡èµ·å§‹èˆ‡çµæŸæ—¥æœŸä»¥è¨­å®šç¯„åœå€é–“
+  description_date_from: è¼¸å…¥èµ·å§‹æ—¥æœŸ
+  description_date_to: è¼¸å…¥çµæŸæ—¥æœŸ
+  text_repository_identifier_info: 'åƒ…å…è¨±ä½¿ç”¨å°å¯«è‹±æ–‡å­—æ¯ (a-z), é˜¿æ‹‰ä¼¯æ•¸å­—, è™›ç·šèˆ‡åº•ç·šã€‚<br />ä¸€æ—¦å„²å­˜ä¹‹å¾Œ, ä»£ç¢¼ä¾¿ç„¡æ³•å†æ¬¡è¢«æ›´æ”¹ã€‚'
+  label_total_time: ç¸½è¨ˆ
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/183dca49dc870131da0c794df1c3f5f569d0e6e5.svn-base
--- /dev/null
+++ b/.svn/pristine/18/183dca49dc870131da0c794df1c3f5f569d0e6e5.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module IssueStatusesHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/185ae4625d7d985009b3be79f0d708b104a00d0b.svn-base
--- a/.svn/pristine/18/185ae4625d7d985009b3be79f0d708b104a00d0b.svn-base
+++ /dev/null
@@ -1,51 +0,0 @@
-<div class="contextual">
-<%= link_to(l(:label_news_new),
-            new_project_news_path(@project),
-            :class => 'icon icon-add',
-            :onclick => 'Element.show("add-news"); Form.Element.focus("news_title"); return false;') if @project && User.current.allowed_to?(:manage_news, @project) %>
-</div>
-
-<div id="add-news" style="display:none;">
-<h2><%=l(:label_news_new)%></h2>
-<% labelled_tabular_form_for @news, :url => project_news_index_path(@project),
-                                           :html => { :id => 'news-form' } do |f| %>
-<%= render :partial => 'news/form', :locals => { :f => f } %>
-<%= submit_tag l(:button_create) %>
-<%= link_to_remote l(:label_preview),
-                   { :url => preview_news_path(:project_id => @project),
-                     :method => 'get',
-                     :update => 'preview',
-                     :with => "Form.serialize('news-form')"
-                   }, :accesskey => accesskey(:preview) %> |
-<%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("add-news")' %>
-<% end if @project %>
-<div id="preview" class="wiki"></div>
-</div>
-
-<h2><%=l(:label_news_plural)%></h2>
-
-<% if @newss.empty? %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% else %>
-<% @newss.each do |news| %>
-    <h3><%= avatar(news.author, :size => "24") %><%= link_to_project(news.project) + ': ' unless news.project == @project %>
-    <%= link_to h(news.title), news_path(news) %>
-    <%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count > 0 %></h3>
-    <p class="author"><%= authoring news.created_on, news.author %></p>
-    <div class="wiki">
-    <%= textilizable(news.description) %>
-    </div>
-<% end %>
-<% end %>
-<p class="pagination"><%= pagination_links_full @news_pages %></p>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:project_id => @project, :key => User.current.rss_key} %>
-<% end %>
-
-<% content_for :header_tags do %>
-  <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %>
-  <%= stylesheet_link_tag 'scm' %>
-<% end %>
-
-<% html_title(l(:label_news_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/18852f098b25cd84eb6339e96750fe88239d356c.svn-base
--- a/.svn/pristine/18/18852f098b25cd84eb6339e96750fe88239d356c.svn-base
+++ /dev/null
@@ -1,178 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'pp'
-class RepositoryCvsTest < ActiveSupport::TestCase
-  fixtures :projects
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s
-  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
-  # CVS module
-  MODULE_NAME    = 'test'
-  CHANGESETS_NUM = 7
-
-  def setup
-    @project = Project.find(3)
-    @repository = Repository::Cvs.create(:project  => @project,
-                                         :root_url => REPOSITORY_PATH,
-                                         :url      => MODULE_NAME,
-                                         :log_encoding => 'UTF-8')
-    assert @repository
-  end
-
-  if File.directory?(REPOSITORY_PATH)
-    def test_fetch_changesets_from_scratch
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-
-      assert_equal CHANGESETS_NUM, @repository.changesets.count
-      assert_equal 16, @repository.changes.count
-      assert_not_nil @repository.changesets.find_by_comments('Two files changed')
-
-      r2 = @repository.changesets.find_by_revision('2')
-      assert_equal 'v1-20071213-162510', r2.scmid
-    end
-
-    def test_fetch_changesets_incremental
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      # Remove changesets with revision > 3
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 3}
-      @repository.reload
-      assert_equal 3, @repository.changesets.count
-      assert_equal %w|3 2 1|, @repository.changesets.collect(&:revision)
-
-      rev3_commit = @repository.changesets.find(:first, :order => 'committed_on DESC')
-      assert_equal '3', rev3_commit.revision
-       # 2007-12-14 01:27:22 +0900
-      rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
-      assert_equal 'HEAD-20071213-162722', rev3_commit.scmid
-      assert_equal rev3_committed_on, rev3_commit.committed_on
-      latest_rev = @repository.latest_changeset
-      assert_equal rev3_committed_on, latest_rev.committed_on
-
-      @repository.fetch_changesets
-      @repository.reload
-      assert_equal CHANGESETS_NUM, @repository.changesets.count
-
-      assert_equal %w|7 6 5 4 3 2 1|, @repository.changesets.collect(&:revision)
-      rev5_commit = @repository.changesets.find_by_revision('5')
-      assert_equal 'HEAD-20071213-163001', rev5_commit.scmid
-       # 2007-12-14 01:30:01 +0900
-      rev5_committed_on = Time.gm(2007, 12, 13, 16, 30, 1)
-      assert_equal rev5_committed_on, rev5_commit.committed_on
-    end
-
-    def test_deleted_files_should_not_be_listed
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal CHANGESETS_NUM, @repository.changesets.count
-
-      entries = @repository.entries('sources')
-      assert entries.detect {|e| e.name == 'watchers_controller.rb'}
-      assert_nil entries.detect {|e| e.name == 'welcome_controller.rb'}
-    end
-
-    def test_entries_rev3
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal CHANGESETS_NUM, @repository.changesets.count
-      entries = @repository.entries('', '3')
-      assert_equal 3, entries.size
-      assert_equal entries[2].name, "README"
-      assert_equal entries[2].lastrev.time, Time.gm(2007, 12, 13, 16, 27, 22)
-      assert_equal entries[2].lastrev.identifier, '3'
-      assert_equal entries[2].lastrev.revision, '3'
-      assert_equal entries[2].lastrev.author, 'LANG'
-    end
-
-    def test_entries_invalid_path
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal CHANGESETS_NUM, @repository.changesets.count
-      assert_nil @repository.entries('missing')
-      assert_nil @repository.entries('missing', '3')
-    end
-
-    def test_entries_invalid_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal CHANGESETS_NUM, @repository.changesets.count
-      assert_nil @repository.entries('', '123')
-    end
-
-    def test_cat
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal CHANGESETS_NUM, @repository.changesets.count
-      buf = @repository.cat('README')
-      assert buf
-      lines = buf.split("\n")
-      assert_equal 3, lines.length
-      buf = lines[1].gsub(/\r$/, "")
-      assert_equal 'with one change', buf
-      buf = @repository.cat('README', '1')
-      assert buf
-      lines = buf.split("\n")
-      assert_equal 1, lines.length
-      buf = lines[0].gsub(/\r$/, "")
-      assert_equal 'CVS test repository', buf
-      assert_nil @repository.cat('missing.rb')
-
-      # sources/welcome_controller.rb is removed at revision 5.
-      assert @repository.cat('sources/welcome_controller.rb', '4')
-      assert @repository.cat('sources/welcome_controller.rb', '5').blank?
-
-      # invalid revision
-      assert @repository.cat('README', '123').blank?
-    end
-
-    def test_annotate
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal CHANGESETS_NUM, @repository.changesets.count
-      ann = @repository.annotate('README')
-      assert ann
-      assert_equal 3, ann.revisions.length
-      assert_equal '1.2', ann.revisions[1].revision
-      assert_equal 'LANG', ann.revisions[1].author
-      assert_equal 'with one change', ann.lines[1]
-
-      ann = @repository.annotate('README', '1')
-      assert ann
-      assert_equal 1, ann.revisions.length
-      assert_equal '1.1', ann.revisions[0].revision
-      assert_equal 'LANG', ann.revisions[0].author
-      assert_equal 'CVS test repository', ann.lines[0]
-
-     # invalid revision
-     assert_nil @repository.annotate('README', '123')
-   end
-
-  else
-    puts "CVS test repository NOT FOUND. Skipping unit tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/1885ce921d043d16f90840164f06199bb85e23a9.svn-base
--- a/.svn/pristine/18/1885ce921d043d16f90840164f06199bb85e23a9.svn-base
+++ /dev/null
@@ -1,114 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class ActivitiesControllerTest < ActionController::TestCase
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :groups_users,
-           :enabled_modules,
-           :workflows,
-           :auth_sources,
-           :journals, :journal_details
-
-
-  def test_project_index
-    get :index, :id => 1, :with_subprojects => 0
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:events_by_day)
-
-    assert_tag :tag => "h3",
-               :content => /#{2.days.ago.to_date.day}/,
-               :sibling => { :tag => "dl",
-                 :child => { :tag => "dt",
-                   :attributes => { :class => /issue-edit/ },
-                   :child => { :tag => "a",
-                     :content => /(#{IssueStatus.find(2).name})/,
-                   }
-                 }
-               }
-  end
-
-  def test_project_index_with_invalid_project_id_should_respond_404
-    get :index, :id => 299
-    assert_response 404
-  end
-
-  def test_previous_project_index
-    get :index, :id => 1, :from => 3.days.ago.to_date
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:events_by_day)
-
-    assert_tag :tag => "h3",
-               :content => /#{3.day.ago.to_date.day}/,
-               :sibling => { :tag => "dl",
-                 :child => { :tag => "dt",
-                   :attributes => { :class => /issue/ },
-                   :child => { :tag => "a",
-                     :content => /#{Issue.find(1).subject}/,
-                   }
-                 }
-               }
-  end
-
-  def test_global_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:events_by_day)
-
-    assert_tag :tag => "h3",
-               :content => /#{5.day.ago.to_date.day}/,
-               :sibling => { :tag => "dl",
-                 :child => { :tag => "dt",
-                   :attributes => { :class => /issue/ },
-                   :child => { :tag => "a",
-                     :content => /#{Issue.find(5).subject}/,
-                   }
-                 }
-               }
-  end
-
-  def test_user_index
-    get :index, :user_id => 2
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:events_by_day)
-
-    assert_tag :tag => "h3",
-               :content => /#{3.day.ago.to_date.day}/,
-               :sibling => { :tag => "dl",
-                 :child => { :tag => "dt",
-                   :attributes => { :class => /issue/ },
-                   :child => { :tag => "a",
-                     :content => /#{Issue.find(1).subject}/,
-                   }
-                 }
-               }
-  end
-
-  def test_user_index_with_invalid_user_id_should_respond_404
-    get :index, :user_id => 299
-    assert_response 404
-  end
-
-  def test_index_atom_feed
-    get :index, :format => 'atom'
-    assert_response :success
-    assert_template 'common/feed.atom'
-    assert_tag :tag => 'entry', :child => {
-      :tag => 'link',
-      :attributes => {:href => 'http://test.host/issues/11'}}
-  end
-
-  def test_index_atom_feed_with_one_item_type
-    get :index, :format => 'atom', :show_issues => '1'
-    assert_response :success
-    assert_template 'common/feed.atom'
-    assert_tag :tag => 'title', :content => /Issues/
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/189265ed49969ae038f71c1289b8d78b6d40e378.svn-base
--- /dev/null
+++ b/.svn/pristine/18/189265ed49969ae038f71c1289b8d78b6d40e378.svn-base
@@ -0,0 +1,198 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+namespace :redmine do
+  namespace :email do
+
+    desc <<-END_DESC
+Read an email from standard input.
+
+General options:
+  unknown_user=ACTION      how to handle emails from an unknown user
+                           ACTION can be one of the following values:
+                           ignore: email is ignored (default)
+                           accept: accept as anonymous user
+                           create: create a user account
+  no_permission_check=1    disable permission checking when receiving
+                           the email
+  no_account_notice=1      disable new user account notification
+  default_group=foo,bar    adds created user to foo and bar groups
+
+Issue attributes control options:
+  project=PROJECT          identifier of the target project
+  status=STATUS            name of the target status
+  tracker=TRACKER          name of the target tracker
+  category=CATEGORY        name of the target category
+  priority=PRIORITY        name of the target priority
+  allow_override=ATTRS     allow email content to override attributes
+                           specified by previous options
+                           ATTRS is a comma separated list of attributes
+
+Examples:
+  # No project specified. Emails MUST contain the 'Project' keyword:
+  rake redmine:email:read RAILS_ENV="production" < raw_email
+
+  # Fixed project and default tracker specified, but emails can override
+  # both tracker and priority attributes:
+  rake redmine:email:read RAILS_ENV="production" \\
+                  project=foo \\
+                  tracker=bug \\
+                  allow_override=tracker,priority < raw_email
+END_DESC
+
+    task :read => :environment do
+      options = { :issue => {} }
+      %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
+      options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
+      options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
+      options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
+      options[:no_account_notice] = ENV['no_account_notice'] if ENV['no_account_notice']
+      options[:default_group] = ENV['default_group'] if ENV['default_group']
+
+      MailHandler.receive(STDIN.read, options)
+    end
+
+    desc <<-END_DESC
+Read emails from an IMAP server.
+
+General options:
+  unknown_user=ACTION      how to handle emails from an unknown user
+                           ACTION can be one of the following values:
+                           ignore: email is ignored (default)
+                           accept: accept as anonymous user
+                           create: create a user account
+  no_permission_check=1    disable permission checking when receiving
+                           the email
+  no_account_notice=1      disable new user account notification
+  default_group=foo,bar    adds created user to foo and bar groups
+
+Available IMAP options:
+  host=HOST                IMAP server host (default: 127.0.0.1)
+  port=PORT                IMAP server port (default: 143)
+  ssl=SSL                  Use SSL? (default: false)
+  username=USERNAME        IMAP account
+  password=PASSWORD        IMAP password
+  folder=FOLDER            IMAP folder to read (default: INBOX)
+
+Issue attributes control options:
+  project=PROJECT          identifier of the target project
+  status=STATUS            name of the target status
+  tracker=TRACKER          name of the target tracker
+  category=CATEGORY        name of the target category
+  priority=PRIORITY        name of the target priority
+  allow_override=ATTRS     allow email content to override attributes
+                           specified by previous options
+                           ATTRS is a comma separated list of attributes
+
+Processed emails control options:
+  move_on_success=MAILBOX  move emails that were successfully received
+                           to MAILBOX instead of deleting them
+  move_on_failure=MAILBOX  move emails that were ignored to MAILBOX
+
+Examples:
+  # No project specified. Emails MUST contain the 'Project' keyword:
+
+  rake redmine:email:receive_imap RAILS_ENV="production" \\
+    host=imap.foo.bar username=redmine@example.net password=xxx
+
+
+  # Fixed project and default tracker specified, but emails can override
+  # both tracker and priority attributes:
+
+  rake redmine:email:receive_imap RAILS_ENV="production" \\
+    host=imap.foo.bar username=redmine@example.net password=xxx ssl=1 \\
+    project=foo \\
+    tracker=bug \\
+    allow_override=tracker,priority
+END_DESC
+
+    task :receive_imap => :environment do
+      imap_options = {:host => ENV['host'],
+                      :port => ENV['port'],
+                      :ssl => ENV['ssl'],
+                      :username => ENV['username'],
+                      :password => ENV['password'],
+                      :folder => ENV['folder'],
+                      :move_on_success => ENV['move_on_success'],
+                      :move_on_failure => ENV['move_on_failure']}
+
+      options = { :issue => {} }
+      %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
+      options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
+      options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
+      options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
+      options[:no_account_notice] = ENV['no_account_notice'] if ENV['no_account_notice']
+      options[:default_group] = ENV['default_group'] if ENV['default_group']
+
+      Redmine::IMAP.check(imap_options, options)
+    end
+
+    desc <<-END_DESC
+Read emails from an POP3 server.
+
+Available POP3 options:
+  host=HOST                POP3 server host (default: 127.0.0.1)
+  port=PORT                POP3 server port (default: 110)
+  username=USERNAME        POP3 account
+  password=PASSWORD        POP3 password
+  apop=1                   use APOP authentication (default: false)
+  delete_unprocessed=1     delete messages that could not be processed
+                           successfully from the server (default
+                           behaviour is to leave them on the server)
+
+See redmine:email:receive_imap for more options and examples.
+END_DESC
+
+    task :receive_pop3 => :environment do
+      pop_options  = {:host => ENV['host'],
+                      :port => ENV['port'],
+                      :apop => ENV['apop'],
+                      :username => ENV['username'],
+                      :password => ENV['password'],
+                      :delete_unprocessed => ENV['delete_unprocessed']}
+
+      options = { :issue => {} }
+      %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
+      options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
+      options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
+      options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
+      options[:no_account_notice] = ENV['no_account_notice'] if ENV['no_account_notice']
+      options[:default_group] = ENV['default_group'] if ENV['default_group']
+
+      Redmine::POP3.check(pop_options, options)
+    end
+
+    desc "Send a test email to the user with the provided login name"
+    task :test, [:login] => :environment do |task, args|
+      include Redmine::I18n
+      abort l(:notice_email_error, "Please include the user login to test with. Example: rake redmine:email:test[login]") if args[:login].blank?
+
+      user = User.find_by_login(args[:login])
+      abort l(:notice_email_error, "User #{args[:login]} not found") unless user && user.logged?
+
+      ActionMailer::Base.raise_delivery_errors = true
+      begin
+        Mailer.with_synched_deliveries do
+          Mailer.test_email(user).deliver
+        end
+        puts l(:notice_email_sent, user.mail)
+      rescue Exception => e
+        abort l(:notice_email_error, e.message)
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/189e42fe562dc8e6777fdc048ca3ef1e55e522e9.svn-base
--- a/.svn/pristine/18/189e42fe562dc8e6777fdc048ca3ef1e55e522e9.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-the implicit html part of the email <%= do_something_helpful("semaj") %>
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/18a09954a05a5ec15a7caae7ea49a3f1f212aec3.svn-base
--- a/.svn/pristine/18/18a09954a05a5ec15a7caae7ea49a3f1f212aec3.svn-base
+++ /dev/null
@@ -1,81 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../../test_helper', __FILE__)
-
-class Redmine::Views::Builders::JsonTest < ActiveSupport::TestCase
-
-  def test_hash
-    assert_json_output({'person' => {'name' => 'Ryan', 'age' => 32}}) do |b|
-      b.person do
-        b.name 'Ryan'
-        b.age  32
-      end
-    end
-  end
-
-  def test_hash_hash
-    assert_json_output({'person' => {'name' => 'Ryan', 'birth' => {'city' => 'London', 'country' => 'UK'}}}) do |b|
-      b.person do
-        b.name 'Ryan'
-        b.birth :city => 'London', :country => 'UK'
-      end
-    end
-
-    assert_json_output({'person' => {'id' => 1, 'name' => 'Ryan', 'birth' => {'city' => 'London', 'country' => 'UK'}}}) do |b|
-      b.person :id => 1 do
-        b.name 'Ryan'
-        b.birth :city => 'London', :country => 'UK'
-      end
-    end
-  end
-
-  def test_array
-    assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
-      b.array :books do |b|
-        b.book :title => 'Book 1', :author => 'B. Smith'
-        b.book :title => 'Book 2', :author => 'G. Cooper'
-      end
-    end
-
-    assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
-      b.array :books do |b|
-        b.book :title => 'Book 1' do
-          b.author 'B. Smith'
-        end
-        b.book :title => 'Book 2' do
-          b.author 'G. Cooper'
-        end
-      end
-    end
-  end
-
-  def test_array_with_content_tags
-    assert_json_output({'books' => [{'value' => 'Book 1', 'author' => 'B. Smith'}, {'value' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
-      b.array :books do |b|
-        b.book 'Book 1', :author => 'B. Smith'
-        b.book 'Book 2', :author => 'G. Cooper'
-      end
-    end
-  end
-
-  def assert_json_output(expected, &block)
-    builder = Redmine::Views::Builders::Json.new
-    block.call(builder)
-    assert_equal(expected, ActiveSupport::JSON.decode(builder.output))
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/18aaa55b2d77150962ade434e4a8c39b73c97814.svn-base
--- /dev/null
+++ b/.svn/pristine/18/18aaa55b2d77150962ade434e4a8c39b73c97814.svn-base
@@ -0,0 +1,164 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoriesFilesystemControllerTest < ActionController::TestCase
+  tests RepositoriesController
+
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :repositories, :enabled_modules
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/filesystem_repository').to_s
+  PRJ_ID = 3
+
+  def setup
+    @ruby19_non_utf8_pass =
+        (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8')
+    User.current = nil
+    Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
+    @project = Project.find(PRJ_ID)
+    @repository = Repository::Filesystem.create(
+                      :project       => @project,
+                      :url           => REPOSITORY_PATH,
+                      :path_encoding => ''
+                      )
+    assert @repository
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    def test_get_new
+      @request.session[:user_id] = 1
+      @project.repository.destroy
+      get :new, :project_id => 'subproject1', :repository_scm => 'Filesystem'
+      assert_response :success
+      assert_template 'new'
+      assert_kind_of Repository::Filesystem, assigns(:repository)
+      assert assigns(:repository).new_record?
+    end
+
+    def test_browse_root
+      @repository.fetch_changesets
+      @repository.reload
+      get :show, :id => PRJ_ID
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert assigns(:entries).size > 0
+      assert_not_nil assigns(:changesets)
+      assert assigns(:changesets).size == 0
+
+      assert_no_tag 'input', :attributes => {:name => 'rev'}
+      assert_no_tag 'a', :content => 'Statistics'
+      assert_no_tag 'a', :content => 'Atom'
+    end
+
+    def test_show_no_extension
+      get :entry, :id => PRJ_ID, :path => repository_path_hash(['test'])[:param]
+      assert_response :success
+      assert_template 'entry'
+      assert_tag :tag => 'th',
+                 :content => '1',
+                 :attributes => { :class => 'line-num' },
+                 :sibling => { :tag => 'td', :content => /TEST CAT/ }
+    end
+
+    def test_entry_download_no_extension
+      get :raw, :id => PRJ_ID, :path => repository_path_hash(['test'])[:param]
+      assert_response :success
+      assert_equal 'application/octet-stream', @response.content_type
+    end
+
+    def test_show_non_ascii_contents
+      with_settings :repositories_encodings => 'UTF-8,EUC-JP' do
+        get :entry, :id => PRJ_ID,
+            :path => repository_path_hash(['japanese', 'euc-jp.txt'])[:param]
+        assert_response :success
+        assert_template 'entry'
+        assert_tag :tag => 'th',
+                   :content => '2',
+                   :attributes => { :class => 'line-num' },
+                   :sibling => { :tag => 'td', :content => /japanese/ }
+        if @ruby19_non_utf8_pass
+          puts "TODO: show repository file contents test fails in Ruby 1.9 " +
+               "and Encoding.default_external is not UTF-8. " +
+               "Current value is '#{Encoding.default_external.to_s}'"
+        else
+          str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
+          str_japanese.force_encoding('UTF-8') if str_japanese.respond_to?(:force_encoding)
+          assert_tag :tag => 'th',
+                     :content => '3',
+                     :attributes => { :class => 'line-num' },
+                     :sibling => { :tag => 'td', :content => /#{str_japanese}/ }
+        end
+      end
+    end
+
+    def test_show_utf16
+      enc = (RUBY_VERSION == "1.9.2" ? 'UTF-16LE' : 'UTF-16')
+      with_settings :repositories_encodings => enc do
+        get :entry, :id => PRJ_ID,
+            :path => repository_path_hash(['japanese', 'utf-16.txt'])[:param]
+        assert_response :success
+        assert_tag :tag => 'th',
+                   :content => '2',
+                   :attributes => { :class => 'line-num' },
+                   :sibling => { :tag => 'td', :content => /japanese/ }
+      end
+    end
+
+    def test_show_text_file_should_send_if_too_big
+      with_settings :file_max_size_displayed => 1 do
+        get :entry, :id => PRJ_ID,
+            :path => repository_path_hash(['japanese', 'big-file.txt'])[:param]
+        assert_response :success
+        assert_equal 'text/plain', @response.content_type
+      end
+    end
+
+    def test_destroy_valid_repository
+      @request.session[:user_id] = 1 # admin
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+
+    def test_destroy_invalid_repository
+      @request.session[:user_id] = 1 # admin
+      @project.repository.destroy
+      @repository = Repository::Filesystem.create!(
+                      :project       => @project,
+                      :url           => "/invalid",
+                      :path_encoding => ''
+                      )
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+  else
+    puts "Filesystem test repository NOT FOUND. Skipping functional tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/18af7ca4dac0c217561ab69b8406264b81adb03a.svn-base
--- /dev/null
+++ b/.svn/pristine/18/18af7ca4dac0c217561ab69b8406264b81adb03a.svn-base
@@ -0,0 +1,23 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class UserCustomField < CustomField
+  def type_name
+    :label_user_plural
+  end
+end
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/18cc4e49160ae0034ae73ed153f32f0bc91339cb.svn-base
--- a/.svn/pristine/18/18cc4e49160ae0034ae73ed153f32f0bc91339cb.svn-base
+++ /dev/null
@@ -1,4 +0,0 @@
-<%= image_tag 'image.png', :plugin => 'test_assets' %>
-<%= javascript_include_tag 'file.1.js', 'file2', :plugin => "test_assets" %>
-<%= stylesheet_link_tag 'file.1.css', 'file2', :plugin => "test_assets" %>
-<%= image_submit_tag 'image.png', :plugin => "test_assets" %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/18d3632a00930fda235a1df851a99c522ae0e846.svn-base
--- a/.svn/pristine/18/18d3632a00930fda235a1df851a99c522ae0e846.svn-base
+++ /dev/null
@@ -1,45 +0,0 @@
-require 'rails_generator/base'
-require 'rails_generator/generators/components/model/model_generator'
-
-class RedminePluginModelGenerator < ModelGenerator
-  attr_accessor :plugin_path, :plugin_name, :plugin_pretty_name
-  
-  def initialize(runtime_args, runtime_options = {})
-    runtime_args = runtime_args.dup
-    usage if runtime_args.empty?
-    @plugin_name = "redmine_" + runtime_args.shift.underscore
-    @plugin_pretty_name = plugin_name.titleize
-    @plugin_path = "vendor/plugins/#{plugin_name}"
-    super(runtime_args, runtime_options)
-  end
-  
-  def destination_root
-    File.join(Rails.root, plugin_path)
-  end
-  
-  def manifest
-    record do |m|
-      # Check for class naming collisions.
-      m.class_collisions class_path, class_name, "#{class_name}Test"
-
-      # Model, test, and fixture directories.
-      m.directory File.join('app/models', class_path)
-      m.directory File.join('test/unit', class_path)
-      m.directory File.join('test/fixtures', class_path)
-
-      # Model class, unit test, and fixtures.
-      m.template 'model.rb.erb',      File.join('app/models', class_path, "#{file_name}.rb")
-      m.template 'unit_test.rb.erb',  File.join('test/unit', class_path, "#{file_name}_test.rb")
-
-      unless options[:skip_fixture] 
-       	m.template 'fixtures.yml',  File.join('test/fixtures', "#{table_name}.yml")
-      end
-
-      unless options[:skip_migration]
-        m.migration_template 'migration.rb.erb', 'db/migrate', :assigns => {
-          :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
-        }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/18/18f24048551fce41db8feba1bc192158d946b808.svn-base
--- /dev/null
+++ b/.svn/pristine/18/18f24048551fce41db8feba1bc192158d946b808.svn-base
@@ -0,0 +1,98 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class EnumerationsController < ApplicationController
+  layout 'admin'
+
+  before_filter :require_admin, :except => :index
+  before_filter :require_admin_or_api_request, :only => :index
+  before_filter :build_new_enumeration, :only => [:new, :create]
+  before_filter :find_enumeration, :only => [:edit, :update, :destroy]
+  accept_api_auth :index
+
+  helper :custom_fields
+
+  def index
+    respond_to do |format|
+      format.html
+      format.api {
+        @klass = Enumeration.get_subclass(params[:type])
+        if @klass
+          @enumerations = @klass.shared.sorted.all
+        else
+          render_404
+        end
+      }
+    end
+  end
+
+  def new
+  end
+
+  def create
+    if request.post? && @enumeration.save
+      flash[:notice] = l(:notice_successful_create)
+      redirect_to enumerations_path
+    else
+      render :action => 'new'
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    if request.put? && @enumeration.update_attributes(params[:enumeration])
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to enumerations_path
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def destroy
+    if !@enumeration.in_use?
+      # No associated objects
+      @enumeration.destroy
+      redirect_to enumerations_path
+      return
+    elsif params[:reassign_to_id]
+      if reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id])
+        @enumeration.destroy(reassign_to)
+        redirect_to enumerations_path
+        return
+      end
+    end
+    @enumerations = @enumeration.class.system.all - [@enumeration]
+  end
+
+  private
+
+  def build_new_enumeration
+    class_name = params[:enumeration] && params[:enumeration][:type] || params[:type]
+    @enumeration = Enumeration.new_subclass_instance(class_name, params[:enumeration])
+    if @enumeration.nil?
+      render_404
+    end
+  end
+
+  def find_enumeration
+    @enumeration = Enumeration.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/19/190e5bea2d5dc9984a86fa22ae8cc4dd749898ab.svn-base
--- /dev/null
+++ b/.svn/pristine/19/190e5bea2d5dc9984a86fa22ae8cc4dd749898ab.svn-base
@@ -0,0 +1,72 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Search
+
+    mattr_accessor :available_search_types
+
+    @@available_search_types = []
+
+    class << self
+      def map(&block)
+        yield self
+      end
+
+      # Registers a search provider
+      def register(search_type, options={})
+        search_type = search_type.to_s
+        @@available_search_types << search_type unless @@available_search_types.include?(search_type)
+      end
+    end
+
+    module Controller
+      def self.included(base)
+        base.extend(ClassMethods)
+      end
+
+      module ClassMethods
+        @@default_search_scopes = Hash.new {|hash, key| hash[key] = {:default => nil, :actions => {}}}
+        mattr_accessor :default_search_scopes
+
+        # Set the default search scope for a controller or specific actions
+        # Examples:
+        #   * search_scope :issues # => sets the search scope to :issues for the whole controller
+        #   * search_scope :issues, :only => :index
+        #   * search_scope :issues, :only => [:index, :show]
+        def default_search_scope(id, options = {})
+          if actions = options[:only]
+            actions = [] << actions unless actions.is_a?(Array)
+            actions.each {|a| default_search_scopes[controller_name.to_sym][:actions][a.to_sym] = id.to_s}
+          else
+            default_search_scopes[controller_name.to_sym][:default] = id.to_s
+          end
+        end
+      end
+
+      def default_search_scopes
+        self.class.default_search_scopes
+      end
+
+      # Returns the default search scope according to the current action
+      def default_search_scope
+        @default_search_scope ||= default_search_scopes[controller_name.to_sym][:actions][action_name.to_sym] ||
+                                  default_search_scopes[controller_name.to_sym][:default]
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/19/190f7780ebda85c20bf409af3fa0689d0dd1bde4.svn-base
--- /dev/null
+++ b/.svn/pristine/19/190f7780ebda85c20bf409af3fa0689d0dd1bde4.svn-base
@@ -0,0 +1,30 @@
+<h2><%= link_to l(:label_user_plural), users_path %> &#187; <%=l(:label_user_new)%></h2>
+
+<%= labelled_form_for @user do |f| %>
+  <%= render :partial => 'form', :locals => { :f => f } %>
+  <% if email_delivery_enabled? %>
+  <p><label><%= check_box_tag 'send_information', 1, true %> <%= l(:label_send_information) %></label></p>
+  <% end %>
+  <p>
+    <%= submit_tag l(:button_create) %>
+    <%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
+  </p>
+<% end %>
+
+<% if @auth_sources.present? && @auth_sources.any?(&:searchable?) %>
+  <%= javascript_tag do %>
+    observeAutocompleteField('user_login', '<%= escape_javascript autocomplete_for_new_user_auth_sources_path %>', {
+      select: function(event, ui) {
+        $('input#user_firstname').val(ui.item.firstname);
+        $('input#user_lastname').val(ui.item.lastname);
+        $('input#user_mail').val(ui.item.mail);
+        $('select#user_auth_source_id option').each(function(){
+          if ($(this).attr('value') == ui.item.auth_source_id) {
+            $(this).attr('selected', true);
+            $('select#user_auth_source_id').trigger('change');
+          }
+        });
+      }
+    });
+  <% end %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/19/191c54aa364bc303830fb03453b541edfd9e5945.svn-base
--- /dev/null
+++ b/.svn/pristine/19/191c54aa364bc303830fb03453b541edfd9e5945.svn-base
@@ -0,0 +1,114 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Configuration
+
+    # Configuration default values
+    @defaults = {
+      'email_delivery' => nil,
+      'max_concurrent_ajax_uploads' => 2
+    }
+
+    @config = nil
+
+    class << self
+      # Loads the Redmine configuration file
+      # Valid options:
+      # * <tt>:file</tt>: the configuration file to load (default: config/configuration.yml)
+      # * <tt>:env</tt>: the environment to load the configuration for (default: Rails.env)
+      def load(options={})
+        filename = options[:file] || File.join(Rails.root, 'config', 'configuration.yml')
+        env = options[:env] || Rails.env
+
+        @config = @defaults.dup
+
+        load_deprecated_email_configuration(env)
+        if File.file?(filename)
+          @config.merge!(load_from_yaml(filename, env))
+        end
+
+        # Compatibility mode for those who copy email.yml over configuration.yml
+        %w(delivery_method smtp_settings sendmail_settings).each do |key|
+          if value = @config.delete(key)
+            @config['email_delivery'] ||= {}
+            @config['email_delivery'][key] = value
+          end
+        end
+
+        if @config['email_delivery']
+          ActionMailer::Base.perform_deliveries = true
+          @config['email_delivery'].each do |k, v|
+            v.symbolize_keys! if v.respond_to?(:symbolize_keys!)
+            ActionMailer::Base.send("#{k}=", v)
+          end
+        end
+
+        @config
+      end
+
+      # Returns a configuration setting
+      def [](name)
+        load unless @config
+        @config[name]
+      end
+
+      # Yields a block with the specified hash configuration settings
+      def with(settings)
+        settings.stringify_keys!
+        load unless @config
+        was = settings.keys.inject({}) {|h,v| h[v] = @config[v]; h}
+        @config.merge! settings
+        yield if block_given?
+        @config.merge! was
+      end
+
+      private
+
+      def load_from_yaml(filename, env)
+        yaml = nil
+        begin
+          yaml = YAML::load_file(filename)
+        rescue ArgumentError
+          $stderr.puts "Your Redmine configuration file located at #{filename} is not a valid YAML file and could not be loaded."
+          exit 1
+        end
+        conf = {}
+        if yaml.is_a?(Hash)
+          if yaml['default']
+            conf.merge!(yaml['default'])
+          end
+          if yaml[env]
+            conf.merge!(yaml[env])
+          end
+        else
+          $stderr.puts "Your Redmine configuration file located at #{filename} is not a valid Redmine configuration file."
+          exit 1
+        end
+        conf
+      end
+
+      def load_deprecated_email_configuration(env)
+        deprecated_email_conf = File.join(Rails.root, 'config', 'email.yml')
+        if File.file?(deprecated_email_conf)
+          warn "Storing outgoing emails configuration in config/email.yml is deprecated. You should now store it in config/configuration.yml using the email_delivery setting."
+          @config.merge!({'email_delivery' => load_from_yaml(deprecated_email_conf, env)})
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/19/191deb72582c6d402b1e52197865840391314c7f.svn-base
--- /dev/null
+++ b/.svn/pristine/19/191deb72582c6d402b1e52197865840391314c7f.svn-base
@@ -0,0 +1,2451 @@
+== Redmine changelog
+
+Redmine - project management software
+Copyright (C) 2006-2013  Jean-Philippe Lang
+http://www.redmine.org/
+
+== 2013-05-01 v2.3.1
+
+* Defect #12650: Lost text after selection in issue list with IE
+* Defect #12684: Hotkey for Issue-Edit doesn't work as expected
+* Defect #13405: Commit link title is escaped twice when using "commit:" prefix
+* Defect #13541: Can't access SCM when log/production.scm.stderr.log is not writable
+* Defect #13579: Datepicker uses Simplified Chinese in Traditional Chinese locale
+* Defect #13584: Missing Portuguese jQuery UI date picker
+* Defect #13586: Circular loop testing prevents precedes/follows relation between subtasks
+* Defect #13618: CSV export of spent time ignores filters and columns selection
+* Defect #13630: PDF export generates the issue id twice
+* Defect #13644: Diff - Internal Error
+* Defect #13712: Fix email rake tasks to also support no_account_notice and default_group options
+* Defect #13811: Broken javascript in IE7 ; recurrence of #12195
+* Defect #13823: Trailing comma in javascript files
+* Patch #13531: Traditional Chinese translation for 2.3-stable
+* Patch #13552: Dutch translations for 2.3-stable
+* Patch #13678: Lithuanian translation for 2.3-stable
+
+== 2013-03-19 v2.3.0
+
+* Defect #3107: Issue with two digit year on Logtime
+* Defect #3371: Autologin does not work when using openid
+* Defect #3676: www. generates broken link in formatted text
+* Defect #4700: Adding news does not send notification to all project members
+* Defect #5329: Time entries report broken on first week of year
+* Defect #8794: Circular loop when using relations and subtasks
+* Defect #9475: German Translation "My custom queries" and "Custom queries"
+* Defect #9549: Only 100 users are displayed when adding new project members
+* Defect #10277: Redmine wikitext URL-into-link creation with hyphen is wrong
+* Defect #10364: Custom field float separator in CSV export
+* Defect #10930: rake redmine:load_default_data error in 2.0 with SQLServer
+* Defect #10977: Redmine shouldn't require all database gems
+* Defect #12528: Handle temporary failures gracefully in the external mail handler script
+* Defect #12629: Wrong German "label_issues_by" translation
+* Defect #12641: Diff outputs become ??? in some non ASCII words.
+* Defect #12707: Typo in app/models/tracker.rb
+* Defect #12716: Attachment description lost when issue validation fails
+* Defect #12735: Negative duration allowed
+* Defect #12736: Negative start/due dates allowed
+* Defect #12968: Subtasks don't resepect following/precedes
+* Defect #13006: Filter "Assignee's group" doesn't work with group assignments
+* Defect #13022: Image pointing towards /logout signs out user
+* Defect #13059: Custom fields are listed two times in workflow/Fields permission
+* Defect #13076: Project overview page shows trackers from subprojects with disabled issue module
+* Defect #13119: custom_field_values are not reloaded on #reload
+* Defect #13154: After upgrade to 2.2.2 ticket list on some projects fails
+* Defect #13188: Forms are not updated after changing the status field without "Add issues" permission
+* Defect #13251: Adding a "follows" relation may not refresh relations list
+* Defect #13272: translation missing: setting_default_projects_tracker_ids
+* Defect #13328: Copying an issue as a child of itself creates an extra issue
+* Defect #13335: Autologin does not work with custom autologin cookie name
+* Defect #13350: Japanese mistranslation fix
+* Feature #824: Add "closed_on" issue field (storing time of last closing) & add it as a column and filter on the issue list.
+* Feature #1766: Custom fields should become addable to Spent Time list/report
+* Feature #3436: Show relations in Gantt diagram
+* Feature #3957: Ajax file upload with progress bar
+* Feature #5298: Store attachments in sub directories
+* Feature #5605: Subprojects should (optionally) inherit Members from their parent
+* Feature #6727: Add/remove issue watchers via REST API
+* Feature #7159: Bulk watch/unwatch issues from the context menu
+* Feature #8529: Get the API key of the user through REST API
+* Feature #8579: Multiple file upload with HTML5 / Drag-and-Drop
+* Feature #10191: Add Filters For Spent time's Details and Report
+* Feature #10286: Auto-populate fields while creating a new user with LDAP
+* Feature #10352: Preview should already display the freshly attached images
+* Feature #11498: Add --no-account-notice option for the mail handler script
+* Feature #12122: Gantt progress lines (html only)
+* Feature #12228: JRuby 1.7.2 support
+* Feature #12251: Custom fields: 'Multiple values' should be able to be checked and then unchecked
+* Feature #12401: Split "Manage documents" permission into create, edit and delete permissions
+* Feature #12542: Group events in the activity view
+* Feature #12665: Link to a file in a repository branch
+* Feature #12713: Microsoft SQLServer support
+* Feature #12787: Remove "Warning - iconv will be deprecated in the future, use String#encode instead."
+* Feature #12843: Add links to projects in Group projects list
+* Feature #12898: Handle GET /issues/context_menu parameters nicely to prevent returning error 500 to crawlers
+* Feature #12992: Make JSONP support optional and disabled by default
+* Feature #13174: Raise group name maximum length to 255 characters
+* Feature #13175: Possibility to define the default enable trackers when creating a project
+* Feature #13329: Ruby 2.0 support
+* Feature #13337: Split translation "label_total"
+* Feature #13340: Mail handler: option to add created user to default group
+* Feature #13341: Mail handler: --no-notification option to disable notifications to the created user
+* Patch #7202: Polish translation for v1.0.4
+* Patch #7851: Italian translation for 'issue'
+* Patch #9225: Generate project identifier automatically with JavaScript
+* Patch #10916: Optimisation in issues relations display
+* Patch #12485: Don't force english language for default admin account
+* Patch #12499: Use lambda in model scopes
+* Patch #12611: Login link unexpected logs you out
+* Patch #12626: Updated Japanese translations for button_view and permission_commit_access
+* Patch #12640: Russian "about_x_hours" translation change
+* Patch #12645: Russian numeric translation
+* Patch #12660: Consistent German translation for my page
+* Patch #12708: Restructured german translation (Cleanup)
+* Patch #12721: Optimize MenuManager a bit
+* Patch #12725: Change pourcent to percent (#12724)
+* Patch #12754: Updated Japanese translation for notice_account_register_done
+* Patch #12788: Copyright for 2013
+* Patch #12806: Serbian translation change
+* Patch #12810: Swedish Translation change
+* Patch #12910: Plugin settings div should perhaps have 'settings' CSS class
+* Patch #12911: Fix 500 error for requests to the settings path for non-configurable plugins
+* Patch #12926: Bulgarian translation (r11218)
+* Patch #12927: Swedish Translation for r11244
+* Patch #12967: Change Spanish login/logout translations
+* Patch #12988: Russian translation for trunk
+* Patch #13080: German translation of label_in
+* Patch #13098: Small datepicker improvements
+* Patch #13152: Locale file for Azerbaijanian language
+* Patch #13155: Add login to /users/:id API for current user
+* Patch #13173: Put source :rubygems url HTTP secure
+* Patch #13190: Bulgarian translation (r11404)
+* Patch #13198: Traditional Chinese language file (to r11426)
+* Patch #13203: German translation change for follow and precedes is inconsitent
+* Patch #13206: Portuguese translation file
+* Patch #13246: Some german translation patches
+* Patch #13280: German translation (r11478)
+* Patch #13301: Performance: avoid querying all memberships in User#roles_for_project
+* Patch #13309: Add "tracker-[id]" CSS class to issues
+* Patch #13324: fixing some pt-br locales
+* Patch #13339: Complete language Vietnamese file
+* Patch #13391: Czech translation update
+* Patch #13399: Fixed some wrong or confusing translation in Korean locale
+* Patch #13414: Bulgarian translation (r11567)
+* Patch #13420: Korean translation for 2.3 (r11583)
+* Patch #13437: German translation of setting_emails_header
+* Patch #13438: English translation
+* Patch #13447: German translation - some patches
+* Patch #13450: Czech translation
+* Patch #13475: fixing some pt-br locales
+* Patch #13514: fixing some pt-br locales
+
+== 2013-03-19 v2.2.4
+
+* Upgrade to Rails 3.2.13
+* Defect #12243: Ordering forum replies by last reply date is broken
+* Defect #13127: h1 multiple lined titles breaks into main menu
+* Defect #13138: Generating PDF of issue causes UndefinedConversionError with htmlentities gem
+* Defect #13165: rdm-mailhandler.rb: initialize_http_header override basic auth
+* Defect #13232: Link to topic in nonexistent forum causes error 500
+* Patch #13181: Bulgarian translation of jstoolbar-bg.js
+* Patch #13207: Portuguese translation for 2.2-stable
+* Patch #13310: pt-BR label_last_n_weeks translation
+* Patch #13325: pt-BR translation for 2.2-stable
+* Patch #13343: Vietnamese translation for 2.2-stable
+* Patch #13398: Czech translation for 2.2-stable
+
+== 2013-02-12 v2.2.3
+
+* Upgrade to Rails 3.2.12
+* Defect #11987: pdf: Broken new line in table
+* Defect #12930: 404 Error when referencing different project source files in the wiki syntax
+* Defect #12979: Wiki link syntax commit:repo_a:abcd doesn't work
+* Defect #13075: Can't clear custom field value through context menu in the issue list
+* Defect #13097: Project copy fails when wiki module is disabled
+* Defect #13126: Issue view: estimated time vs. spent time
+* Patch #12922: Update Spanish translation
+* Patch #12928: Bulgarian translation for 2.2-stable
+* Patch #12987: Russian translation for 2.2-stable
+
+== 2013-01-20 v2.2.2
+
+* Defect #7510: Link to attachment should return latest attachment
+* Defect #9842: {{toc}} is not replaced by table of content when exporting wiki page to pdf
+* Defect #12749: Plugins cannot route wiki page sub-path
+* Defect #12799: Cannot edit a wiki section which title starts with a tab
+* Defect #12801: Viewing the history of a wiki page with attachments raises an error
+* Defect #12833: Input fields restricted on length should have maxlength parameter set
+* Defect #12838: Blank page when clicking Add with no block selected on my page layout
+* Defect #12851: "Parent task is invalid" while editing child issues by Role with restricted Issues Visibility
+* Patch #12800: Serbian Latin translation patch (sr-YU.yml)
+* Patch #12809: Swedish Translation for r11162
+* Patch #12818: Minor swedish translation fix
+
+== 2013-01-09 v2.2.1
+
+* Upgrade to Rails 3.2.11
+* Defect #12652: "Copy ticket" selects "new ticket"
+* Defect #12691: Textile Homepage Dead?
+* Defect #12711: incorrect fix of lib/SVG/Graph/TimeSeries.rb
+* Defect #12744: Unable to call a macro with a name that contains uppercase letters
+* Defect #12776: Security vulnerability in Rails 3.2.10 (CVE-2013-0156)
+* Patch #12630: Russian "x_hours" translation
+
+== 2012-12-18 v2.2.0
+
+* Defect #4787: Gannt to PNG - CJK (Chinese, Japanese and Korean) characters appear as ?
+* Defect #8106: Issues by Category should show tasks without category
+* Defect #8373: i18n string text_are_you_sure_with_children no longer used
+* Defect #11426: Filtering with Due Date in less than N days should show overdue issues
+* Defect #11834: Bazaar: "???" instead of non ASCII character in paths on non UTF-8 locale
+* Defect #11868: Git and Mercurial diff displays deleted files as /dev/null
+* Defect #11979: No validation errors when entering an invalid "Parent task"
+* Defect #12012: Redmine::VERSION.revision method does not work on Subversion 1.7 working copy
+* Defect #12018: Issue filter select box order changes randomly
+* Defect #12090: email recipients not written to action_mailer log if BCC recipients setting is checked
+* Defect #12092: Issue "start date" validation does not work correctly
+* Defect #12285: Some unit and functional tests miss fixtures and break when run alone
+* Defect #12286: Emails of private notes are sent to watcher users regardless of viewing permissions
+* Defect #12310: Attachments may not be displayed in the order they were selected
+* Defect #12356: Issue "Update" link broken focus
+* Defect #12397: Error in Textile conversion of HTTP links, containing russian letters
+* Defect #12434: Respond with 404 instead of 500 when requesting a wiki diff with invalid versions
+* Feature #1554: Private comments in tickets
+* Feature #2161: Time tracking code should respect weekends as "no work" days
+* Feature #3239: Show related issues on the Issues Listing
+* Feature #3265: Filter on issue relations
+* Feature #3447: Option to display the issue descriptions on the issues list
+* Feature #3511: Ability to sort issues by grouped column
+* Feature #4590: Precede-Follow relation should move following issues when rescheduling issue earlier
+* Feature #5487: Allow subtasks to cross projects
+* Feature #6899: Add a relation between the original and copied issue
+* Feature #7082: Rest API for wiki
+* Feature #9835: REST API - List priorities
+* Feature #10789: Macros {{child_pages}} with depth parameter
+* Feature #10852: Ability to delete a version from a wiki page history
+* Feature #10937: new user format #{lastname}
+* Feature #11502: Expose roles details via REST API
+* Feature #11755: Impersonate user through REST API auth
+* Feature #12085: New user name format: firstname + first letter of lastname
+* Feature #12125: Set filename used to store attachment updloaded via the REST API
+* Feature #12167: Macro for inserting collapsible block of text
+* Feature #12211: Wrap issue description and its contextual menu in a div
+* Feature #12216: Textual CSS class for priorities
+* Feature #12299: Redmine version requirement improvements (in plugins)
+* Feature #12393: Upgrade to Rails 3.2.9
+* Feature #12475: Lazy loading of translation files for faster startup
+* Patch #11846: Fill username when authentification failed
+* Patch #11862: Add "last 2 weeks" preset to time entries reporting
+* Patch #11992: Japanese translation about issue relations improved
+* Patch #12027: Incorrect Spanish "September" month name
+* Patch #12061: Japanese translation improvement (permission names)
+* Patch #12078: User#allowed_to? should return true or false
+* Patch #12117: Change Japanese translation of "admin"
+* Patch #12142: Updated translation in Lithuanian
+* Patch #12232: German translation enhancements
+* Patch #12316: Fix Lithuanian numeral translation
+* Patch #12494: Bulgarian "button_submit" translation change
+* Patch #12514: Updated translation in Lithuanian
+* Patch #12602: Korean translation update for 2.2-stable
+* Patch #12608: Norwegian translation changed
+* Patch #12619: Russian translation change
+
+== 2012-12-18 v2.1.5
+
+* Defect #12400: Validation fails when receiving an email with list custom fields
+* Defect #12451: Macros.rb extract_macro_options should use lazy search
+* Defect #12513: Grouping of issues by custom fields not correct in PDF export
+* Defect #12566: Issue history notes previews are broken
+* Defect #12568: Clicking "edit" on a journal multiple times shows multiple forms
+* Patch #12605: Norwegian translation for 1.4-stable update
+* Patch #12614: Dutch translation
+* Patch #12615: Russian translation
+
+== 2012-11-24 v2.1.4
+
+* Defect #12274: Wiki export from Index by title is truncated
+* Defect #12298: Right-click context menu unable to batch/bulk update (IE8)
+* Defect #12332: Repository identifier does not display on Project/Settings/Repositories
+* Defect #12396: Error when receiving an email without subject header
+* Defect #12399: Non ASCII attachment filename encoding broken (MOJIBAKE) in receiving mail on Ruby 1.8
+* Defect #12409: Git: changesets aren't read after clear_changesets call
+* Defect #12431: Project.rebuild! sorts root projects by id instead of name
+
+== 2012-11-17 v2.1.3
+
+* Defect #12050: :export links to repository files lead to a 404 error
+* Defect #12189: Missing tmp/pdf directory
+* Defect #12195: Javascript error with IE7 / IE8 on new issue form
+* Defect #12196: "Page not found" on OK button in SCM "View all revisions" page
+* Defect #12199: Confirmation message displayed when clicking a disabled delete link in the context menu
+* Defect #12231: Hardcoded "Back" in Repository
+* Defect #12294: Incorrect german translation for "registered" users filter
+* Defect #12349: Watchers auto-complete search on non-latin chars
+* Defect #12358: 'None' grouped issue list section should be translated
+* Defect #12359: Version date field regex validation accepts invalid date
+* Defect #12375: Receiving mail subject encoding broken (MOJIBAKE) in some cases on Ruby 1.8
+* Patch #9732: German translations
+* Patch #12021: Russian locale translations
+* Patch #12188: Simplified Chinese translation with zh.yml file based on Rev:10681
+* Patch #12235: German translation for 2.1-stable
+* Patch #12237: Added German Translation
+
+== 2012-09-30 v2.1.2
+
+* Defect #11929: XSS vulnerability in Redmine 2.1.x
+
+== 2012-09-30 v2.1.1
+
+* Defect #11290: ParseDate missing in Ruby 1.9x
+* Defect #11844: "load_default_data" rake task fails to print the error message if one occurs
+* Defect #11850: Can't create a user from ldap by on-the-fly on the redmine server using URI prefix
+* Defect #11872: Private issue visible to anonymous users after its author is deleted
+* Defect #11885: Filter misses Selectionfield on IE8
+* Defect #11893: New relation form Cancel link is broken with Chrome 21
+* Defect #11905: Potential "can't dup NilClass" error in UserPreference
+* Defect #11909: Autocomplete results not reset after clearing search field
+* Defect #11922: bs.yml and de.yml lead to error by number_to_currency()
+* Defect #11945: rake task prints "can't convert Errno::EACCES into String" in case of no permission of public/plugin_assets
+* Defect #11975: Undefined status transitions allowed in workflow (author of issue changes when selecting a new status)
+* Defect #11982: SCM diff view generates extra parameter for switching mode
+* Patch #11897: Traditional Chinese language file (to r10433)
+
+== 2012-09-16 v2.1.0
+
+* Defect #2071: Reordering priority-enumerations breaks alternate-theme's issue-colouring
+* Defect #2190: Month names not translated to german
+* Defect #8978: LDAP timeout if an LDAP auth provider is unreachable
+* Defect #9839: Gantt abbr of weekday should not be necessarily the first letter of the long day name
+* Defect #10928: Documentation about generating a plugin is not up-to-date
+* Defect #11034: TLS configuration documentation for Rails 3
+* Defect #11073: UserCustomField order_statement returns wrong output
+* Defect #11153: Default sorting for target version is DESC instead of ASC
+* Defect #11207: Issues associated with a locked version are not copied when copying a project
+* Defect #11304: Issue-class: status-1, status-2 etc. refer to status position instead of status id
+* Defect #11331: Openid registration form should not require user to enter password
+* Defect #11345: Context menu should show shared versions when editing issues from different projects
+* Defect #11355: Plain text notification emails content is HTML escaped
+* Defect #11388: Updating a version through rest API returns invalid JSON
+* Defect #11389: Warning in awesome_nested_set.rb
+* Defect #11503: Accessing /projects/:project/wiki/something.png fails with error 500
+* Defect #11506: Versions that are not shared should not be assignable when selecting another project
+* Defect #11508: Projects not ordered alphabetically after renaming project
+* Defect #11540: Roadmap anchor links can be ambigous
+* Defect #11545: Overwriting existing method Issue.open
+* Defect #11552: MailHandler does not match assignee name with spaces
+* Defect #11571: Custom fields of type version not proper handled in receiving e-mails
+* Defect #11577: Can't use non-latin anchor in wiki
+* Defect #11612: Revision graph sometimes broken due to raphael.js error
+* Defect #11621: Redmine MIME Detection Of Javascript Files Non-Standard
+* Defect #11633: Macro arguments should not be parsed by text formatters
+* Defect #11662: Invalid query returned from Issues.visible scope after accessing User#projects_by_role with a role that is not present
+* Defect #11691: 404 response when deleting a user from the edit page
+* Defect #11723: redmine:send_reminders notification misses if assignee is a group
+* Defect #11738: Batch update of issues clears project path
+* Defect #11749: Redmine.pm: HEAD is not considered as a read-only method
+* Defect #11814: Date picker does not respect week start setting
+* Feature #703: Configurable required fields per tracker/status/role
+* Feature #1006: Display thumbnails of attached images
+* Feature #1091: Disabling default ticket fields per tracker
+* Feature #1360: Permission for adding an issue to a version.
+* Feature #3061: Let macros optionally match over multiple lines and ignore single curly braces
+* Feature #3510: Inserting image thumbnails inside the wiki
+* Feature #3521: Permissions for roles to change fields per tracker/status
+* Feature #3640: Freeze / Close Projects
+* Feature #3831: Support for subforums
+* Feature #6597: Configurable session lifetime and timeout
+* Feature #6965: Option to Copy Subtasks when copying an issue
+* Feature #8161: Ability to filter issues on project custom fields
+* Feature #8577: "Private" column and filter on the issue list
+* Feature #8981: REST Api for Groups
+* Feature #9258: Create role by copy
+* Feature #9419: Group/sort the issue list by user/version-format custom fields
+* Feature #10362: Show images in repositories inline when clicking the 'View' link
+* Feature #10419: Upgrade raphael.js (2.1.0)
+* Feature #11068: Ability to set default column order in issue list
+* Feature #11102: Add autocomplete to "Related issue" field on revision
+* Feature #11109: Repository Identifier should be frozen
+* Feature #11181: Additional "Log time" link on project overview
+* Feature #11205: Reversed order of priorities on the issue summary page
+* Feature #11445: Switch from Prototype to JQuery
+* Feature #11469: JSONP support
+* Feature #11475: Redmine.pm: Allow fallback to other Apache auth providers
+* Feature #11494: Don't turn #nnn with leading zeros into links
+* Feature #11539: Display a projects tree instead of a flat list in notification preferences
+* Feature #11578: Option to pass whole arguments to a macro without splitting them
+* Feature #11595: Missing mime type for svg files
+* Feature #11758: Upgrade to Rails 3.2.8
+* Patch #4905: Redmine.pm: add support for Git's smart HTTP protocol
+* Patch #10988: New Korean translation patch
+* Patch #11201: Korean translation special update
+* Patch #11401: Fix Japanese mistranslation for "button_submit"
+* Patch #11402: Japanese translation added for default role names
+* Patch #11411: Fix disordered use of long sound in Japanese "user" translation
+* Patch #11412: Unnatural Japanese message when users failed to login
+* Patch #11419: Fix wrong Japanese "label_attachment" translation
+* Patch #11496: Make labels clickable in Adminstration/Settings
+* Patch #11704: Avoid the use of tag("...", "...", true) in layout
+* Patch #11818: Redmine.pm fails when permissions are NULL
+
+== 2012-09-16 v2.0.4
+
+* Defect #10818: Running rake in test environment causes exception
+* Defect #11209: Wiki diff may generate broken HTML
+* Defect #11217: Project names in drop-down are escaped twice
+* Defect #11262: Link is escaped in wiki added/updated notification email
+* Defect #11307: Can't filter for negative numeric custom fields
+* Defect #11325: Unified diff link broken on specific file/revision diff view
+* Defect #11341: Escaped link in conflict resolution form
+* Defect #11365: Attachment description length is not validated
+* Defect #11511: Confirmation page has broken HTML when a project folding sub project is deleted
+* Defect #11533: rake redmine:plugins:test doesn't run tests in subdirectories
+* Defect #11541: Version sharing is missing in the REST API
+* Defect #11550: Issue reminder doesn't work when using asynchronous delivery
+* Defect #11776: Can't override mailer views inside redmine plugin.
+* Defect #11789: Edit section links broken with h5/h6 headings
+* Feature #11338: Exclude emails with auto-submitted => auto-generated
+* Patch #11299: redmine:plugins:migrate should update db/schema.rb
+* Patch #11328: Fix Japanese mistranslation for 'label_language_based'
+* Patch #11448: Russian translation for 1.4-stable and 2.0-stable
+* Patch #11600: Fix plural form of the abbreviation for hours in Brazilian Portuguese
+
+== 2012-06-18 v2.0.3
+
+* Defect #10688: PDF export from Wiki - Problems with tables
+* Defect #11061: Cannot choose commit versions to view differences in Git/Mercurial repository view
+* Defect #11065: E-Mail submitted tickets: German umlauts in 'Subject' get malformed (ruby 1.8)
+* Defect #11098: Default priorities have the same position and can't be reordered
+* Defect #11105: <% content_for :header_tags do %> doesn't work inside hook
+* Defect #11112: REST API - custom fields in POST/PUT ignored for time_entries
+* Defect #11118: "Maximum file size" displayed on upload forms is incorrect
+* Defect #11124: Link to user is escaped in activity title
+* Defect #11133: Wiki-page section edit link can point to incorrect section
+* Defect #11160: SQL Error on time report if a custom field has multiple values for an entry
+* Defect #11170: Topics sort order is broken in Redmine 2.x
+* Defect #11178: Spent time sorted by date-descending order lists same-date entries in physical order (not-reverse)
+* Defect #11185: Redmine fails to delete a project with parent/child task
+* Feature #11162: Upgrade to Rails 3.2.6
+* Patch #11113: Small glitch in German localization
+
+== 2012-06-05 v2.0.2
+
+* Defect #11032: Project list is not shown when "For any event on the selected projects only..." is selected on user edit panel
+* Defect #11038: "Create and continue" should preserve project, issue and activity when logging time
+* Defect #11046: Redmine.pm does not support "bind as user" ldap authentication
+* Defect #11051: reposman.rb fails in 1.4.2 because of missing require for rubygems
+* Defect #11085: Wiki start page can't be changed
+* Feature #11084: Update Rails to 3.2.5
+
+== 2012-05-28 v2.0.1
+
+* Defect #10923: After creating a new Version Redmine jumps back to "Information"
+* Defect #10932: Links to delete watchers are escaped when gravatars are enabled
+* Defect #10964: Updated column doesn't get updated on issues
+* Defect #10965: rake yard does not work for generating documentation.
+* Defect #10972: Columns selection not displayed on the custom query form
+* Defect #10991: My page > Spent time 'project' column is html-encoded
+* Defect #10996: Time zones lost when upgrading from Redmine 1.4 to 2.0
+* Defect #11013: Fetching Email from IMAP/POP3 - uninitialized constant RAILS_DEFAULT_LOGGER error
+* Defect #11024: redmine_plugin_model generator does not create the migration
+* Defect #11027: Saving new query without name causes escaping of input field
+* Defect #11028: Project identifier can be updated
+
+== 2012-05-15 v2.0.0
+
+* Feature #4796: Rails 3 support
+* Feature #7720: Limit the pagination-limit when max-results is fewer than max-pagination-limit
+* Feature #9034: Add an id to the flash messages
+* Patch #10782: Better translation for Estonian language
+
+== 2012-05-13 v1.4.2
+
+* Defect #10744: rake task redmine:email:test broken
+* Defect #10787: "Allow users to unsubscribe" option is confusing
+* Defect #10827: Cannot access Repositories page and Settings in a Project - Error 500
+* Defect #10829: db:migrate fails 0.8.2 -> 1.4.1
+* Defect #10832: REST Uploads fail with fastcgi
+* Defect #10837: reposman and rdm-mailhandler not working with ruby 1.9.x
+* Defect #10856: can not load translations from hr.yml with ruby1.9.3-p194
+* Defect #10865: Filter reset when deleting locked user
+* Feature #9790: Allow filtering text custom fields on "is null" and "is not null"
+* Feature #10778: svn:ignore for config/additional_environment.rb
+* Feature #10875: Partial Albanian Translations
+* Feature #10888: Bring back List-Id to help aid Gmail filtering
+* Patch #10733: Traditional Chinese language file (to r9502)
+* Patch #10745: Japanese translation update (r9519)
+* Patch #10750: Swedish Translation for r9522
+* Patch #10785: Bulgarian translation (jstoolbar)
+* Patch #10800: Simplified Chinese translation
+
+== 2012-04-20 v1.4.1
+
+* Defect #8574: Time report: date range fields not enabled when using the calendar popup
+* Defect #10642: Nested textile ol/ul lists generate invalid HTML
+* Defect #10668: RSS key is generated twice when user is not reloaded
+* Defect #10669: Token.destroy_expired should not delete API tokens
+* Defect #10675: "Submit and continue" is broken
+* Defect #10711: User cannot change account details with "Login has already been taken" error
+* Feature #10664: Unsubscribe Own User Account
+* Patch #10693: German Translation Update
+
+== 2012-04-14 v1.4.0
+
+* Defect #2719: Increase username length limit from 30 to 60
+* Defect #3087: Revision referring to issues across all projects
+* Defect #4824: Unable to connect (can't convert Net::LDAP::LdapError into String)
+* Defect #5058: reminder mails are not sent when delivery_method is :async_smtp
+* Defect #6859: Moving issues to a tracker with different custom fields should let fill these fields
+* Defect #7398: Error when trying to quick create a version with required custom field
+* Defect #7495: Python multiline comments highlighting problem in Repository browser
+* Defect #7826: bigdecimal-segfault-fix.rb must be removed for Oracle
+* Defect #7920: Attempted to update a stale object when copying a project
+* Defect #8857: Git: Too long in fetching repositories after upgrade from 1.1 or new branch at first time
+* Defect #9472: The git scm module causes an excess amount of DB traffic.
+* Defect #9685: Adding multiple times the same related issue relation is possible
+* Defect #9798: Release 1.3.0 does not detect rubytree under ruby 1.9.3p0 / rails 2.3.14
+* Defect #9978: Japanese "permission_add_issue_watchers" is wrong
+* Defect #10006: Email reminders are sent for closed issues
+* Defect #10150: CSV export and spent time: rounding issue
+* Defect #10168: CSV export breaks custom columns
+* Defect #10181: Issue context menu and bulk edit form show irrelevant statuses
+* Defect #10198: message_id regex in pop3.rb only recognizes Message-ID header (not Message-Id)
+* Defect #10251: Description diff link in note details is relative when received by email
+* Defect #10272: Ruby 1.9.3: "incompatible character encoding" with LDAP auth
+* Defect #10275: Message object not passed to wiki macros for head topic and in preview edit mode
+* Defect #10334: Full name is not unquoted when creating users from emails
+* Defect #10410: [Localization] Grammar issue of Simplified Chinese in zh.yml
+* Defect #10442: Ruby 1.9.3 Time Zone setting Internal error.
+* Defect #10467: Confusing behavior while moving issue to a project with disabled Issues module
+* Defect #10575: Uploading of attachments which filename contains non-ASCII chars fails with Ruby 1.9
+* Defect #10590: WikiContent::Version#text return string with #<Encoding:ASCII-8BIT> when uncompressed
+* Defect #10593: Error: 'incompatible character encodings: UTF-8 and ASCII-8BIT' (old annoing issue) on ruby-1.9.3
+* Defect #10600: Watchers search generates an Internal error
+* Defect #10605: Bulk edit selected issues does not allow selection of blank values for custom fields
+* Defect #10619: When changing status before tracker, it shows improper status
+* Feature #779: Multiple SCM per project
+* Feature #971: Add "Spent time" column to query
+* Feature #1060: Add a LDAP-filter using external auth sources
+* Feature #1102: Shortcut for assigning an issue to me
+* Feature #1189: Multiselect custom fields
+* Feature #1363: Allow underscores in project identifiers
+* Feature #1913: LDAP - authenticate as user
+* Feature #1972: Attachments for News
+* Feature #2009: Manually add related revisions
+* Feature #2323: Workflow permissions for administrators
+* Feature #2416: {background:color} doesn't work in text formatting
+* Feature #2694: Notification on loosing assignment
+* Feature #2715: "Magic links" to notes
+* Feature #2850: Add next/previous navigation to issue
+* Feature #3055: Option to copy attachments when copying an issue
+* Feature #3108: set parent automatically for new pages
+* Feature #3463: Export all wiki pages to PDF
+* Feature #4050: Ruby 1.9 support
+* Feature #4769: Ability to move an issue to a different project from the update form
+* Feature #4774: Change the hyperlink for file attachment to view and download
+* Feature #5159: Ability to add Non-Member watchers to the watch list
+* Feature #5638: Use Bundler (Gemfile) for gem management
+* Feature #5643: Add X-Redmine-Sender header to email notifications
+* Feature #6296: Bulk-edit custom fields through context menu
+* Feature #6386: Issue mail should render the HTML version of the issue details
+* Feature #6449: Edit a wiki page's parent on the edit page
+* Feature #6555: Double-click on "Submit" and "Save" buttons should not send two requests to server
+* Feature #7361: Highlight active query in the side bar
+* Feature #7420: Rest API for projects members
+* Feature #7603: Please make editing issues more obvious than "Change properties (More)"
+* Feature #8171: Adding attachments through the REST API
+* Feature #8691: Better handling of issue update conflict
+* Feature #9803: Change project through REST API issue update
+* Feature #9923: User type custom fields should be filterable by "Me".
+* Feature #9985: Group time report by the Status field
+* Feature #9995: Time entries insertion, "Create and continue" button
+* Feature #10020: Enable global time logging at /time_entries/new
+* Feature #10042: Bulk change private flag
+* Feature #10126: Add members of subprojects in the assignee and author filters
+* Feature #10131: Include custom fiels in time entries API responses
+* Feature #10207: Git: use default branch from HEAD
+* Feature #10208: Estonian translation
+* Feature #10253: Better handling of attachments when validation fails
+* Feature #10350: Bulk copy should allow for changing the target version
+* Feature #10607: Ignore out-of-office incoming emails
+* Feature #10635: Adding time like "123 Min" is invalid
+* Patch #9998: Make attachement "Optional Description" less wide
+* Patch #10066: i18n not working with russian gem
+* Patch #10128: Disable IE 8 compatibility mode to fix wrong div.autoscroll scroll bar behaviour 
+* Patch #10155: Russian translation changed
+* Patch #10464: Enhanced PDF output for Issues list
+* Patch #10470: Efficiently process new git revisions in a single batch
+* Patch #10513: Dutch translation improvement
+
+== 2012-04-14 v1.3.3
+
+* Defect #10505: Error when exporting to PDF with NoMethodError (undefined method `downcase' for nil:NilClass)
+* Defect #10554: Defect symbols when exporting tasks in pdf
+* Defect #10564: Unable to change locked, sticky flags and board when editing a message
+* Defect #10591: Dutch "label_file_added" translation is wrong
+* Defect #10622: "Default administrator account changed" is always true
+* Patch #10555: rake redmine:send_reminders aborted if issue assigned to group
+* Patch #10611: Simplified Chinese translations for 1.3-stable
+
+== 2012-03-11 v1.3.2
+
+* Defect #8194: {{toc}} uses identical anchors for subsections with the same name
+* Defect #9143: Partial diff comparison should be done on actual code, not on html
+* Defect #9523: {{toc}} does not display headers with @ code markup
+* Defect #9815: Release 1.3.0 does not detect rubytree with rubgems 1.8
+* Defect #10053: undefined method `<=>' for nil:NilClass when accessing the settings of a project
+* Defect #10135: ActionView::TemplateError (can't convert Fixnum into String)
+* Defect #10193: Unappropriate icons in highlighted code block
+* Defect #10199: No wiki section edit when title contains code
+* Defect #10218: Error when creating a project with a version custom field
+* Defect #10241: "get version by ID" fails with "401 not authorized" error when using API access key
+* Defect #10284: Note added by commit from a subproject does not contain project identifier
+* Defect #10374: User list is empty when adding users to project / group if remaining users are added late
+* Defect #10390: Mass assignment security vulnerability
+* Patch #8413: Confirmation message before deleting a relationship
+* Patch #10160: Bulgarian translation (r8777)
+* Patch #10242: Migrate Redmine.pm from Digest::Sha1 to Digest::Sha
+* Patch #10258: Italian translation for 1.3-stable
+
+== 2012-02-06 v1.3.1
+
+* Defect #9775: app/views/repository/_revision_graph.html.erb sets window.onload directly..
+* Defect #9792: Ruby 1.9: [v1.3.0] Error: incompatible character encodings for it translation on Calendar page
+* Defect #9793: Bad spacing between numbered list and heading (recently broken).
+* Defect #9795: Unrelated error message when creating a group with an invalid name
+* Defect #9832: Revision graph height should depend on height of rows in revisions table
+* Defect #9937: Repository settings are not saved when all SCM are disabled
+* Defect #9961: Ukrainian "default_tracker_bug" is wrong
+* Defect #10013: Rest API - Create Version -> Internal server error 500
+* Defect #10115: Javascript error - Can't attach more than 1 file on IE 6 and 7
+* Defect #10130: Broken italic text style in edited comment preview
+* Defect #10152: Attachment diff type is not saved in user preference
+* Feature #9943: Arabic translation
+* Patch #9874: pt-BR translation updates
+* Patch #9922: Spanish translation updated
+* Patch #10137: Korean language file ko.yml updated to Redmine 1.3.0
+
+== 2011-12-10 v1.3.0
+
+* Defect #2109: Context menu is being submitted twice per right click
+* Defect #7717: MailHandler user creation for unknown_user impossible due to diverging length-limits of login and email fields
+* Defect #7917: Creating users via email fails if user real name containes special chars
+* Defect #7966: MailHandler does not include JournalDetail for attached files
+* Defect #8368: Bad decimal separator in time entry CSV
+* Defect #8371: MySQL error when filtering a custom field using the REST api
+* Defect #8549: Export CSV has character encoding error
+* Defect #8573: Do not show inactive Enumerations where not needed
+* Defect #8611: rake/rdoctask is deprecated
+* Defect #8751: Email notification: bug, when number of recipients more then 8
+* Defect #8894: Private issues - make it more obvious in the UI?
+* Defect #8994: Hardcoded French string "anonyme"
+* Defect #9043: Hardcoded string "diff" in Wiki#show and Repositories_Helper
+* Defect #9051: wrong "text_issue_added" in russian translation.
+* Defect #9108: Custom query not saving status filter
+* Defect #9252: Regression: application title escaped 2 times
+* Defect #9264: Bad Portuguese translation
+* Defect #9470: News list is missing Avatars
+* Defect #9471: Inline markup broken in Wiki link labels
+* Defect #9489: Label all input field and control tags
+* Defect #9534: Precedence: bulk email header is non standard and discouraged
+* Defect #9540: Issue filter by assigned_to_role is not project specific
+* Defect #9619: Time zone ignored when logging time while editing ticket
+* Defect #9638: Inconsistent image filename extensions
+* Defect #9669: Issue list doesn't sort assignees/authors regarding user display format
+* Defect #9672: Message-quoting in forums module broken
+* Defect #9719: Filtering by numeric custom field types broken after update to master
+* Defect #9724: Can't remote add new categories
+* Defect #9738: Setting of cross-project custom query is not remembered inside project
+* Defect #9748: Error about configuration.yml validness should mention file path
+* Feature #69: Textilized description in PDF
+* Feature #401: Add pdf export for WIKI page
+* Feature #1567: Make author column sortable and groupable
+* Feature #2222: Single section edit.
+* Feature #2269: Default issue start date should become configurable.
+* Feature #2371: character encoding for attachment file
+* Feature #2964: Ability to assign issues to groups
+* Feature #3033: Bug Reporting: Using "Create and continue" should show bug id of saved bug
+* Feature #3261: support attachment images in PDF export
+* Feature #4264: Update CodeRay to 1.0 final
+* Feature #4324: Redmine renames my files, it shouldn't.
+* Feature #4729: Add Date-Based Filters for Issues List
+* Feature #4742: CSV export: option to export selected or all columns
+* Feature #4976: Allow rdm-mailhandler to read the API key from a file
+* Feature #5501: Git: Mercurial: Adding visual merge/branch history to repository view
+* Feature #5634: Export issue to PDF does not include Subtasks and Related Issues
+* Feature #5670: Cancel option for file upload
+* Feature #5737: Custom Queries available through the REST Api
+* Feature #6180: Searchable custom fields do not provide adequate operators
+* Feature #6954: Filter from date to date
+* Feature #7180: List of statuses in REST API
+* Feature #7181: List of trackers in REST API
+* Feature #7366: REST API for Issue Relations
+* Feature #7403: REST API for Versions
+* Feature #7671: REST API for reading attachments
+* Feature #7832: Ability to assign issue categories to groups
+* Feature #8420: Consider removing #7013 workaround
+* Feature #9196: Improve logging in MailHandler when user creation fails
+* Feature #9496: Adds an option in mailhandler to disable server certificate verification
+* Feature #9553: CRUD operations for "Issue categories" in REST API
+* Feature #9593: HTML title should be reordered
+* Feature #9600: Wiki links for news and forums
+* Feature #9607: Filter for issues without start date (or any another field based on date type)
+* Feature #9609: Upgrade to Rails 2.3.14
+* Feature #9612: "side by side" and "inline" patch view for attachments
+* Feature #9667: Check attachment size before upload
+* Feature #9690: Link in notification pointing to the actual update
+* Feature #9720: Add note number for single issue's PDF
+* Patch #8617: Indent subject of subtask ticket in exported issues PDF
+* Patch #8778: Traditional Chinese 'issue' translation change
+* Patch #9053: Fix up Russian translation
+* Patch #9129: Improve wording of Git repository note at project setting
+* Patch #9148: Better handling of field_due_date italian translation
+* Patch #9273: Fix typos in russian localization
+* Patch #9484: Limit SCM annotate to text files under the maximum file size for viewing
+* Patch #9659: Indexing rows in auth_sources/index view
+* Patch #9692: Fix Textilized description in PDF for CodeRay
+
+== 2011-12-10 v1.2.3
+
+* Defect #8707: Reposman: wrong constant name
+* Defect #8809: Table in timelog report overflows
+* Defect #9055: Version files in Files module cannot be downloaded if issue tracking is disabled
+* Defect #9137: db:encrypt fails to handle repositories with blank password
+* Defect #9394: Custom date field only validating on regex and not a valid date
+* Defect #9405: Any user with :log_time permission can edit time entries via context menu
+* Defect #9448: The attached images are not shown in documents
+* Defect #9520: Copied private query not visible after project copy
+* Defect #9552: Error when reading ciphered text from the database without cipher key configured
+* Defect #9566: Redmine.pm considers all projects private when login_required is enabled
+* Defect #9567: Redmine.pm potential security issue with cache credential enabled and subversion
+* Defect #9577: Deleting a subtasks doesn't update parent's rgt & lft values
+* Defect #9597: Broken version links in wiki annotate history
+* Defect #9682: Wiki HTML Export only useful when Access history is accessible
+* Defect #9737: Custom values deleted before issue submit
+* Defect #9741: calendar-hr.js (Croatian) is not UTF-8
+* Patch #9558: Simplified Chinese translation for 1.2.2 updated
+* Patch #9695: Bulgarian translation (r7942)
+
+== 2011-11-11 v1.2.2
+
+* Defect #3276: Incorrect handling of anchors in Wiki to HTML export
+* Defect #7215: Wiki formatting mangles links to internal headers
+* Defect #7613: Generated test instances may share the same attribute value object
+* Defect #8411: Can't remove "Project" column on custom query
+* Defect #8615: Custom 'version' fields don't show shared versions
+* Defect #8633: Pagination counts non visible issues
+* Defect #8651: Email attachments are not added to issues any more in v1.2
+* Defect #8825: JRuby + Windows: SCMs do not work on Redmine 1.2
+* Defect #8836: Additional workflow transitions not available when set to both author and assignee
+* Defect #8865: Custom field regular expression is not validated
+* Defect #8880: Error deleting issue with grandchild
+* Defect #8884: Assignee is cleared when updating issue with locked assignee
+* Defect #8892: Unused fonts in rfpdf plugin folder
+* Defect #9161: pt-BR field_warn_on_leaving_unsaved has a small gramatical error
+* Defect #9308: Search fails when a role haven't "view wiki" permission
+* Defect #9465: Mercurial: can't browse named branch below Mercurial 1.5
+
+== 2011-07-11 v1.2.1
+
+* Defect #5089: i18N error on truncated revision diff view
+* Defect #7501: Search options get lost after clicking on a specific result type
+* Defect #8229: "project.xml" response does not include the parent ID
+* Defect #8449: Wiki annotated page does not display author of version 1
+* Defect #8467: Missing german translation - Warn me when leaving a page with unsaved text
+* Defect #8468: No warning when leaving page with unsaved text that has not lost focus
+* Defect #8472: Private checkbox ignored on issue creation with "Set own issues public or private" permission
+* Defect #8510: JRuby: Can't open administrator panel if scm command is not available
+* Defect #8512: Syntax highlighter on Welcome page
+* Defect #8554: Translation missing error on custom field validation
+* Defect #8565: JRuby: Japanese PDF export error
+* Defect #8566: Exported PDF UTF-8 Vietnamese not correct
+* Defect #8569: JRuby: PDF export error with TypeError
+* Defect #8576: Missing german translation - different things
+* Defect #8616: Circular relations
+* Defect #8646: Russian translation "label_follows" and "label_follows" are wrong
+* Defect #8712: False 'Description updated' journal details messages
+* Defect #8729: Not-public queries are not private
+* Defect #8737: Broken line of long issue description on issue PDF.
+* Defect #8738: Missing revision number/id of associated revisions on issue PDF
+* Defect #8739: Workflow copy does not copy advanced workflow settings
+* Defect #8759: Setting issue attributes from mail should be case-insensitive
+* Defect #8777: Mercurial: Not able to Resetting Redmine project respository
+
+== 2011-05-30 v1.2.0
+
+* Defect #61: Broken character encoding in pdf export
+* Defect #1965: Redmine is not Tab Safe
+* Defect #2274: Filesystem Repository path encoding of non UTF-8 characters
+* Defect #2664: Mercurial: Repository path encoding of non UTF-8 characters
+* Defect #3421: Mercurial reads files from working dir instead of changesets
+* Defect #3462: CVS: Repository path encoding of non UTF-8 characters
+* Defect #3715: Login page should not show projects link and search box if authentication is required
+* Defect #3724: Mercurial repositories display revision ID instead of changeset ID
+* Defect #3761: Most recent CVS revisions are missing in "revisions" view
+* Defect #4270: CVS Repository view in Project doesn't show Author, Revision, Comment
+* Defect #5138: Don't use Ajax for pagination
+* Defect #5152: Cannot use certain characters for user and role names.
+* Defect #5251: Git: Repository path encoding of non UTF-8 characters
+* Defect #5373: Translation missing when adding invalid watchers
+* Defect #5817: Shared versions not shown in subproject's gantt chart
+* Defect #6013: git tab,browsing, very slow -- even after first time
+* Defect #6148: Quoting, newlines, and nightmares...
+* Defect #6256: Redmine considers non ASCII and UTF-16 text files as binary in SCM
+* Defect #6476: Subproject's issues are not shown in the subproject's gantt
+* Defect #6496: Remove i18n 0.3.x/0.4.x hack for Rails 2.3.5
+* Defect #6562: Context-menu deletion of issues deletes all subtasks too without explicit prompt
+* Defect #6604: Issues targeted at parent project versions' are not shown on gantt chart
+* Defect #6706: Resolving issues with the commit message produces the wrong comment with CVS
+* Defect #6901: Copy/Move an issue does not give any history of who actually did the action.
+* Defect #6905: Specific heading-content breaks CSS
+* Defect #7000: Project filter not applied on versions in Gantt chart
+* Defect #7097: Starting day of week cannot be set to Saturday
+* Defect #7114: New gantt doesn't display some projects
+* Defect #7146: Git adapter lost commits before 7 days from database latest changeset
+* Defect #7218: Date range error on issue query
+* Defect #7257: "Issues by" version links bad criterias
+* Defect #7279: CSS class ".icon-home" is not used.
+* Defect #7320: circular dependency >2 issues
+* Defect #7352: Filters not working in Gantt charts
+* Defect #7367: Receiving pop3 email should not output debug messages
+* Defect #7373: Error with PDF output and ruby 1.9.2
+* Defect #7379: Remove extraneous hidden_field on wiki history
+* Defect #7516: Redmine does not work with RubyGems 1.5.0
+* Defect #7518: Mercurial diff can be wrong if the previous changeset isn't the parent
+* Defect #7581: Not including a spent time value on the main issue update screen causes silent data loss
+* Defect #7582: hiding form pages from search engines
+* Defect #7597: Subversion and Mercurial log have the possibility to miss encoding
+* Defect #7604: ActionView::TemplateError (undefined method `name' for nil:NilClass)
+* Defect #7605: Using custom queries always redirects to "Issues" tab
+* Defect #7615: CVS diffs do not handle new files properly
+* Defect #7618: SCM diffs do not handle one line new files properly
+* Defect #7639: Some date fields do not have requested format.
+* Defect #7657: Wrong commit range in git log command on Windows
+* Defect #7818: Wiki pages don't use the local timezone to display the "Updated ? hours ago" mouseover
+* Defect #7821: Git "previous" and "next" revisions are incorrect
+* Defect #7827: CVS: Age column on repository view is off by timezone delta
+* Defect #7843: Add a relation between issues = explicit login window ! (basic authentication popup is prompted on AJAX request)
+* Defect #8011: {{toc}} does not display headlines with inline code markup
+* Defect #8029: List of users for adding to a group may be empty if 100 first users have been added
+* Defect #8064: Text custom fields do not wrap on the issue list
+* Defect #8071: Watching a subtask from the context menu updates main issue watch link
+* Defect #8072: Two untranslatable default role names
+* Defect #8075: Some "notifiable" names are not i18n-enabled
+* Defect #8081: GIT: Commits missing when user has the "decorate" git option enabled
+* Defect #8088: Colorful indentation of subprojects must be on right in RTL locales
+* Defect #8239: notes field is not propagated during issue copy
+* Defect #8356: GET /time_entries.xml ignores limit/offset parameters
+* Defect #8432: Private issues information shows up on Activity page for unauthorized users
+* Feature #746: Versioned issue descriptions
+* Feature #1067: Differentiate public/private saved queries in the sidebar
+* Feature #1236: Make destination folder for attachment uploads configurable
+* Feature #1735: Per project repository log encoding setting
+* Feature #1763: Autologin-cookie should be configurable
+* Feature #1981: display mercurial tags
+* Feature #2074: Sending email notifications when comments are added in the news section
+* Feature #2096: Custom fields referencing system tables (users and versions)
+* Feature #2732: Allow additional workflow transitions for author and assignee
+* Feature #2910: Warning on leaving edited issue/wiki page without saving
+* Feature #3396: Git: use --encoding=UTF-8 in "git log"
+* Feature #4273: SCM command availability automatic check in administration panel
+* Feature #4477: Use mime types in downloading from repository
+* Feature #5518: Graceful fallback for "missing translation" needed
+* Feature #5520: Text format buttons and preview link missing when editing comment
+* Feature #5831: Parent Task to Issue Bulk Edit
+* Feature #6887: Upgrade to Rails 2.3.11
+* Feature #7139: Highlight changes inside diff lines
+* Feature #7236: Collapse All for Groups
+* Feature #7246: Handle "named branch" for mercurial
+* Feature #7296: Ability for admin to delete users
+* Feature #7318: Add user agent to Redmine Mailhandler
+* Feature #7408: Add an application configuration file
+* Feature #7409: Cross project Redmine links
+* Feature #7410: Add salt to user passwords
+* Feature #7411: Option to cipher LDAP ans SCM passwords stored in the database
+* Feature #7412: Add an issue visibility level to each role
+* Feature #7414: Private issues
+* Feature #7517: Configurable path of executable for scm adapters
+* Feature #7640: Add "mystery man" gravatar to options
+* Feature #7858: RubyGems 1.6 support
+* Feature #7893: Group filter on the users list
+* Feature #7899: Box for editing comments should open with the formatting toolbar
+* Feature #7921: issues by pulldown should have 'status' option
+* Feature #7996: Bulk edit and context menu for time entries
+* Feature #8006: Right click context menu for Related Issues
+* Feature #8209: I18n YAML files not parsable with psych yaml library
+* Feature #8345: Link to user profile from account page
+* Feature #8365: Git: per project setting to report last commit or not in repository tree
+* Patch #5148: metaKey not handled in issues selection
+* Patch #5629: Wrap text fields properly in PDF
+* Patch #7418: Redmine Persian Translation
+* Patch #8295: Wrap title fields properly in PDF
+* Patch #8310: fixes automatic line break problem with TCPDF
+* Patch #8312: Switch to TCPDF from FPDF for PDF export
+
+== 2011-04-29 v1.1.3
+
+* Defect #5773: Email reminders are sent to locked users
+* Defect #6590: Wrong file list link in email notification on new file upload
+* Defect #7589: Wiki page with backslash in title can not be found
+* Defect #7785: Mailhandler keywords are not removed when updating issues
+* Defect #7794: Internal server error on formatting an issue as a PDF in Japanese
+* Defect #7838: Gantt- Issues does not show up in green when start and end date are the same
+* Defect #7846: Headers (h1, etc.) containing backslash followed by a digit are not displayed correctly
+* Defect #7875: CSV export separators in polish locale (pl.yml)
+* Defect #7890: Internal server error when referencing an issue without project in commit message
+* Defect #7904: Subprojects not properly deleted when deleting a parent project
+* Defect #7939: Simultaneous Wiki Updates Cause Internal Error
+* Defect #7951: Atom links broken on wiki index
+* Defect #7954: IE 9 can not select issues, does not display context menu
+* Defect #7985: Trying to do a bulk edit results in "Internal Error"
+* Defect #8003: Error raised by reposman.rb under Windows server 2003
+* Defect #8012: Wrong selection of modules when adding new project after validation error
+* Defect #8038: Associated Revisions OL/LI items are not styled properly in issue view
+* Defect #8067: CSV exporting in Italian locale
+* Defect #8235: bulk edit issues and copy issues error in es, gl and ca locales
+* Defect #8244: selected modules are not activated when copying a project
+* Patch #7278: Update Simplified Chinese translation to 1.1
+* Patch #7390: Fixes in Czech localization
+* Patch #7963: Reminder email: Link for show all issues does not sort
+
+== 2011-03-07 v1.1.2
+
+* Defect #3132: Bulk editing menu non-functional in Opera browser
+* Defect #6090: Most binary files become corrupted when downloading from CVS repository browser when Redmine is running on a Windows server
+* Defect #7280: Issues subjects wrap in Gantt
+* Defect #7288: Non ASCII filename downloaded from repo is broken on Internet Explorer.
+* Defect #7317: Gantt tab gives internal error due to nil avatar icon
+* Defect #7497: Aptana Studio .project file added to version 1.1.1-stable
+* Defect #7611: Workflow summary shows X icon for workflow with exactly 1 status transition
+* Defect #7625: Syntax highlighting unavailable from board new topic or topic edit preview
+* Defect #7630: Spent time in commits not recognized
+* Defect #7656: MySQL SQL Syntax Error when filtering issues by Assignee's Group
+* Defect #7718: Minutes logged in commit message are converted to hours
+* Defect #7763: Email notification are sent to watchers even if 'No events' setting is chosen
+* Feature #7608: Add "retro" gravatars
+* Patch #7598: Extensible MailHandler
+* Patch #7795: Internal server error at journals#index with custom fields
+
+== 2011-01-30 v1.1.1
+
+* Defect #4899: Redmine fails to list files for darcs repository
+* Defect #7245: Wiki fails to find pages with cyrillic characters using postgresql
+* Defect #7256: redmine/public/.htaccess must be moved for non-fastcgi installs/upgrades
+* Defect #7258: Automatic spent time logging does not work properly with SQLite3
+* Defect #7259: Released 1.1.0 uses "devel" label inside admin information
+* Defect #7265: "Loading..." icon does not disappear after add project member
+* Defect #7266: Test test_due_date_distance_in_words fail due to undefined locale
+* Defect #7274: CSV value separator in dutch locale
+* Defect #7277: Enabling gravatas causes usernames to overlap first name field in user list
+* Defect #7294: "Notifiy for only project I select" is not available anymore in 1.1.0
+* Defect #7307: HTTP 500 error on query for empty revision
+* Defect #7313: Label not translated in french in Settings/Email Notification tab
+* Defect #7329: <code class="javascript"> with long strings may hang server
+* Defect #7337: My page french translation
+* Defect #7348: French Translation of "Connection"
+* Defect #7385: Error when viewing an issue which was related to a deleted subtask
+* Defect #7386: NoMethodError on pdf export
+* Defect #7415: Darcs adapter recognizes new files as modified files above Darcs 2.4
+* Defect #7421: no email sent with 'Notifiy for any event on the selected projects only'
+* Feature #5344: Update to latest CodeRay 0.9.x
+
+== 2011-01-09 v1.1.0
+
+* Defect #2038: Italics in wiki headers show-up wrong in the toc
+* Defect #3449: Redmine Takes Too Long On Large Mercurial Repository
+* Defect #3567: Sorting for changesets might go wrong on Mercurial repos
+* Defect #3707: {{toc}} doesn't work with {{include}}
+* Defect #5096: Redmine hangs up while browsing Git repository
+* Defect #6000: Safe Attributes prevents plugin extension of Issue model...
+* Defect #6064: Modules not assigned to projects created via API
+* Defect #6110: MailHandler should allow updating Issue Priority and Custom fields
+* Defect #6136: JSON API holds less information than XML API
+* Defect #6345: xml used by rest API is invalid
+* Defect #6348: Gantt chart PDF rendering errors
+* Defect #6403: Updating an issue with custom fields fails
+* Defect #6467: "Member of role", "Member of group" filter not work correctly
+* Defect #6473: New gantt broken after clearing issue filters
+* Defect #6541: Email notifications send to everybody
+* Defect #6549: Notification settings not migrated properly
+* Defect #6591: Acronyms must have a minimum of three characters
+* Defect #6674: Delete time log broken after changes to REST
+* Defect #6681: Mercurial, Bazaar and Darcs auto close issue text should be commit id instead of revision number
+* Defect #6724: Wiki uploads does not work anymore (SVN 4266)
+* Defect #6746: Wiki links are broken on Activity page
+* Defect #6747: Wiki diff does not work since r4265
+* Defect #6763: New gantt charts: subject displayed twice on issues
+* Defect #6826: Clicking "Add" twice creates duplicate member record
+* Defect #6844: Unchecking status filter on the issue list has no effect
+* Defect #6895: Wrong Polish translation of "blocks"
+* Defect #6943: Migration from boolean to varchar fails on PostgreSQL 8.1
+* Defect #7064: Mercurial adapter does not recognize non alphabetic nor numeric in UTF-8 copied files
+* Defect #7128: New gantt chart does not render subtasks under parent task
+* Defect #7135: paging mechanism returns the same last page forever
+* Defect #7188: Activity page not refreshed when changing language
+* Defect #7195: Apply CLI-supplied defaults for incoming mail only to new issues not replies
+* Defect #7197: Tracker reset to default when replying to an issue email
+* Defect #7213: Copy project does not copy all roles and permissions
+* Defect #7225: Project settings: Trackers & Custom fields only relevant if module Issue tracking is active
+* Feature #630: Allow non-unique names for projects
+* Feature #1738: Add a "Visible" flag to project/user custom fields
+* Feature #2803: Support for Javascript in Themes
+* Feature #2852: Clean Incoming Email of quoted text "----- Reply above this line ------"
+* Feature #2995: Improve error message when trying to access an archived project
+* Feature #3170: Autocomplete issue relations on subject
+* Feature #3503: Administrator Be Able To Modify Email settings Of Users
+* Feature #4155: Automatic spent time logging from commit messages
+* Feature #5136: Parent select on Wiki rename page
+* Feature #5338: Descendants (subtasks) should be available via REST API
+* Feature #5494: Wiki TOC should display heading from level 4
+* Feature #5594: Improve MailHandler's keyword handling
+* Feature #5622: Allow version to be set via incoming email
+* Feature #5712: Reload themes
+* Feature #5869: Issue filters by Group and Role
+* Feature #6092: Truncate Git revision labels in Activity page/feed and allow configurable length
+* Feature #6112: Accept localized keywords when receiving emails
+* Feature #6140: REST issues response with issue count limit and offset
+* Feature #6260: REST API for Users
+* Feature #6276: Gantt Chart rewrite
+* Feature #6446: Remove length limits on project identifier and name
+* Feature #6628: Improvements in truncate email
+* Feature #6779: Project JSON API
+* Feature #6823: REST API for time tracker.
+* Feature #7072: REST API for news
+* Feature #7111: Expose more detail on journal entries
+* Feature #7141: REST API: get information about current user
+* Patch #4807: Allow to set the done_ratio field with the incoming mail system
+* Patch #5441: Initialize TimeEntry attributes with params[:time_entry]
+* Patch #6762: Use GET instead of POST to retrieve context_menu
+* Patch #7160: French translation ofr "not_a_date" is missing
+* Patch #7212: Missing remove_index in AddUniqueIndexOnMembers down migration
+
+
+== 2010-12-23 v1.0.5
+
+* #6656: Mercurial adapter loses seconds of commit times
+* #6996: Migration trac(sqlite3) -> redmine(postgresql) doesnt escape ' char
+* #7013: v-1.0.4 trunk - see {{count}} in page display rather than value
+* #7016: redundant 'field_start_date' in ja.yml
+* #7018: 'undefined method `reschedule_after' for nil:NilClass' on new issues
+* #7024: E-mail notifications about Wiki changes.
+* #7033: 'class' attribute of <pre> tag shouldn't be truncate
+* #7035: CSV value separator in russian
+* #7122: Issue-description Quote-button missing
+* #7144: custom queries making use of deleted custom fields cause a 500 error
+* #7162: Multiply defined label in french translation
+
+== 2010-11-28 v1.0.4
+
+* #5324: Git not working if color.ui is enabled
+* #6447: Issues API doesn't allow full key auth for all actions
+* #6457: Edit User group problem
+* #6575: start date being filled with current date even when blank value is submitted
+* #6740: Max attachment size, incorrect usage of 'KB'
+* #6760: Select box sorted by ID instead of name in Issue Category
+* #6766: Changing target version name can cause an internal error
+* #6784: Redmine not working with i18n gem 0.4.2
+* #6839: Hardcoded absolute links in my/page_layout
+* #6841: Projects API doesn't allow full key auth for all actions
+* #6860: svn: Write error: Broken pipe when browsing repository
+* #6874: API should return XML description when creating a project
+* #6932: submitting wrong parent task input creates a 500 error
+* #6966: Records of Forums are remained, deleting project
+* #6990: Layout problem in workflow overview
+* #5117: mercurial_adapter should ensure the right LANG environment variable
+* #6782: Traditional Chinese language file (to r4352)
+* #6783: Swedish Translation for r4352
+* #6804: Bugfix: spelling fixes
+* #6814: Japanese Translation for r4362
+* #6948: Bulgarian translation
+* #6973: Update es.yml
+
+== 2010-10-31 v1.0.3
+
+* #4065: Redmine.pm doesn't work with LDAPS and a non-standard port
+* #4416: Link from version details page to edit the wiki.
+* #5484: Add new issue as subtask to an existing ticket
+* #5948: Update help/wiki_syntax_detailed.html with more link options
+* #6494: Typo in pt_BR translation for 1.0.2
+* #6508: Japanese translation update
+* #6509: Localization pt-PT (new strings)
+* #6511: Rake task to test email
+* #6525: Traditional Chinese language file (to r4225)
+* #6536: Patch for swedish translation
+* #6548: Rake tasks to add/remove i18n strings
+* #6569: Updated Hebrew translation
+* #6570: Japanese Translation for r4231
+* #6596: pt-BR translation updates
+* #6629: Change field-name of issues start date
+* #6669: Bulgarian translation
+* #6731: Macedonian translation fix
+* #6732: Japanese Translation for r4287
+* #6735: Add user-agent to reposman
+* #6736: Traditional Chinese language file (to r4288)
+* #6739: Swedish Translation for r4288
+* #6765: Traditional Chinese language file (to r4302)
+* Fixed #5324: Git not working if color.ui is enabled
+* Fixed #5652: Bad URL parsing in the wiki when it ends with right-angle-bracket(greater-than mark).
+* Fixed #5803: Precedes/Follows Relationships Broke
+* Fixed #6435: Links to wikipages bound to versions do not respect version-sharing in Settings -> Versions
+* Fixed #6438: Autologin cannot be disabled again once it's enabled
+* Fixed #6513: "Move" and "Copy" are not displayed when deployed in subdirectory
+* Fixed #6521: Tooltip/label for user "search-refinment" field on group/project member list
+* Fixed #6563: i18n-issues on calendar view
+* Fixed #6598: Wrong caption for button_create_and_continue in German language file
+* Fixed #6607: Unclear caption for german button_update
+* Fixed #6612: SortHelper missing from CalendarsController
+* Fixed #6740: Max attachment size, incorrect usage of 'KB'
+* Fixed #6750: ActionView::TemplateError (undefined method `empty?' for nil:NilClass) on line #12 of app/views/context_menus/issues.html.erb:
+
+== 2010-09-26 v1.0.2
+
+* #2285: issue-refinement: pressing enter should result to an "apply"
+* #3411: Allow mass status update trough context menu
+* #5929: https-enabled gravatars when called over https
+* #6189: Japanese Translation for r4011
+* #6197: Traditional Chinese language file (to r4036)
+* #6198: Updated german translation
+* #6208: Macedonian translation
+* #6210: Swedish Translation for r4039
+* #6248: nl translation update for r4050
+* #6263: Catalan translation update
+* #6275: After submitting a related issue, the Issue field should be re-focused
+* #6289: Checkboxes in issues list shouldn't be displayed when printing
+* #6290: Make journals theming easier
+* #6291: User#allowed_to? is not tested
+* #6306: Traditional Chinese language file (to r4061)
+* #6307: Korean translation update for 4066(4061)
+* #6316: pt_BR update
+* #6339: SERBIAN Updated
+* #6358: Updated Polish translation
+* #6363: Japanese Translation for r4080
+* #6365: Traditional Chinese language file (to r4081)
+* #6382: Issue PDF export variable usage
+* #6428: Interim solution for i18n >= 0.4
+* #6441: Japanese Translation for r4162
+* #6451: Traditional Chinese language file (to r4167)
+* #6465: Japanese Translation for r4171
+* #6466: Traditional Chinese language file (to r4171)
+* #6490: pt-BR translation for 1.0.2
+* Fixed #3935: stylesheet_link_tag with plugin doesn't take into account relative_url_root
+* Fixed #4998: Global issue list's context menu has enabled options for parent menus but there are no valid selections
+* Fixed #5170: Done ratio can not revert to 0% if status is used for done ratio
+* Fixed #5608: broken with i18n 0.4.0
+* Fixed #6054: Error 500 on filenames with whitespace in git reposities
+* Fixed #6135: Default logger configuration grows without bound.
+* Fixed #6191: Deletion of a main task deletes all subtasks
+* Fixed #6195: Missing move issues between projects
+* Fixed #6242: can't switch between inline and side-by-side diff
+* Fixed #6249: Create and continue returns 404
+* Fixed #6267: changing the authentication mode from ldap to internal with setting the password
+* Fixed #6270: diff coderay malformed in the "news" page
+* Fixed #6278: missing "cant_link_an_issue_with_a_descendant"from locale files
+* Fixed #6333: Create and continue results in a 404 Error
+* Fixed #6346: Age column on repository view is skewed for git, probably CVS too
+* Fixed #6351: Context menu on roadmap broken
+* Fixed #6388: New Subproject leads to a 404
+* Fixed #6392: Updated/Created links to activity broken
+* Fixed #6413: Error in SQL
+* Fixed #6443: Redirect to project settings after Copying a Project
+* Fixed #6448: Saving a wiki page with no content has a translation missing
+* Fixed #6452: Unhandled exception on creating File
+* Fixed #6471: Typo in label_report in Czech translation
+* Fixed #6479: Changing tracker type will lose watchers
+* Fixed #6499: Files with leading or trailing whitespace are not shown in git.
+
+== 2010-08-22 v1.0.1
+
+* #819: Add a body ID and class to all pages
+* #871: Commit new CSS styles!
+* #3301: Add favicon to base layout
+* #4656: On Issue#show page, clicking on Ã¢â‚¬Å“Add related issueÃ¢â‚¬ï¿½ should focus on the input
+* #4896: Project identifier should be a limited field
+* #5084: Filter all isssues by projects
+* #5477: Replace Test::Unit::TestCase with ActiveSupport::TestCase
+* #5591: 'calendar' action is used with 'issue' controller in issue/sidebar
+* #5735: Traditional Chinese language file (to r3810)
+* #5740: Swedish Translation for r3810
+* #5785: pt-BR translation update
+* #5898: Projects should be displayed as links in users/memberships
+* #5910: Chinese translation to redmine-1.0.0
+* #5912: Translation update for french locale
+* #5962: Hungarian translation update to r3892
+* #5971: Remove falsly applied chrome on revision links
+* #5972: Updated Hebrew translation for 1.0.0
+* #5982: Updated german translation
+* #6008: Move admin_menu to Redmine::MenuManager
+* #6012: RTL layout
+* #6021: Spanish translation 1.0.0-RC
+* #6025: nl translation updated for r3905
+* #6030: Japanese Translation for r3907
+* #6074: sr-CY.yml contains DOS-type newlines (\r\n)
+* #6087: SERBIAN translation updated
+* #6093: Updated italian translation
+* #6142: Swedish Translation for r3940
+* #6153: Move view_calendar and view_gantt to own modules
+* #6169: Add issue status to issue tooltip
+* Fixed #3834: Add a warning when not choosing a member role
+* Fixed #3922: Bad english arround "Assigned to" text in journal entries
+* Fixed #5158: Simplified Chinese language file zh.yml updated to r3608
+* Fixed #5162: translation missing: zh-TW, field_time_entrie
+* Fixed #5297: openid not validated correctly
+* Fixed #5628: Wrong commit range in git log command
+* Fixed #5760: Assigned_to and author filters in "Projects>View all issues" should be based on user's project visibility
+* Fixed #5771: Problem when importing git repository
+* Fixed #5775: ldap authentication in admin menu should have an icon
+* Fixed #5811: deleting statuses doesnt delete workflow entries
+* Fixed #5834: Emails with trailing spaces incorrectly detected as invalid
+* Fixed #5846: ChangeChangesPathLengthLimit does not remove default for MySQL
+* Fixed #5861: Vertical scrollbar always visible in Wiki "code" blocks in Chrome.
+* Fixed #5883: correct label_project_latest Chinese translation
+* Fixed #5892: Changing status from contextual menu opens the ticket instead
+* Fixed #5904: Global gantt PDF and PNG should display project names
+* Fixed #5925: parent task's priority edit should be disabled through shortcut menu in issues list page
+* Fixed #5935: Add Another file to ticket doesn't work in IE Internet Explorer
+* Fixed #5937: Harmonize french locale "zero" translation with other locales
+* Fixed #5945: Forum message permalinks don't take pagination into account
+* Fixed #5978: Debug code still remains
+* Fixed #6009: When using "English (British)", the repository browser (svn) shows files over 1000 bytes as floating point (2.334355)
+* Fixed #6045: Repository file Diff view sometimes shows more than selected file
+* Fixed #6079: German Translation error in TimeEntryActivity
+* Fixed #6100: User's profile should display all visible projects
+* Fixed #6132: Allow Key based authentication in the Boards atom feed
+* Fixed #6163: Bad CSS class for calendar project menu_item
+* Fixed #6172: Browsing to a missing user's page shows the admin sidebar
+
+== 2010-07-18 v1.0.0 (Release candidate)
+
+* #443: Adds context menu to the roadmap issue lists
+* #443: Subtasking
+* #741: Description preview while editing an issue
+* #1131: Add support for alternate (non-LDAP) authentication
+* #1214: REST API for Issues
+* #1223: File upload on wiki edit form
+* #1755: add "blocked by" as a related issues option
+* #2420: Fetching emails from an POP server
+* #2482: Named scopes in Issue and ActsAsWatchable plus some view refactoring (logic extraction).
+* #2924: Make the right click menu more discoverable using a cursor property
+* #2985: Make syntax highlighting pluggable
+* #3201: Workflow Check/Uncheck All Rows/Columns
+* #3359: Update CodeRay 0.9
+* #3706: Allow assigned_to field configuration on Issue creation by email
+* #3936: configurable list of models to include in search
+* #4480: Create a link to the user profile from the administration interface
+* #4482: Cache textile rendering
+* #4572: Make it harder to ruin your database
+* #4573: Move github gems to Gemcutter
+* #4664: Add pagination to forum threads
+* #4732: Make login case-insensitive also for PostgreSQL
+* #4812: Create links to other projects
+* #4819: Replace images with smushed ones for speed
+* #4945: Allow custom fields attached to project to be searchable
+* #5121: Fix issues list layout overflow
+* #5169: Issue list view hook request
+* #5208: Aibility to edit wiki sidebar
+* #5281: Remove empty ul tags in the issue history
+* #5291: Updated basque translations
+* #5328: Automatically add "Repository" menu_item after repository creation
+* #5415: Fewer SQL statements generated for watcher_recipients
+* #5416: Exclude "fields_for" from overridden methods in TabularFormBuilder
+* #5573: Allow issue assignment in email
+* #5595: Allow start date and due dates to be set via incoming email
+* #5752: The projects view (/projects) renders ul's wrong
+* #5781: Allow to use more macros on the welcome page and project list
+* Fixed #1288: Unable to past escaped wiki syntax in an issue description
+* Fixed #1334: Wiki formatting character *_ and _*
+* Fixed #1416: Inline code with less-then/greater-than produces @lt; and @gt; respectively
+* Fixed #2473: Login and mail should not be case sensitive
+* Fixed #2990: Ruby 1.9 - wrong number of arguments (1 for 0) on rake db:migrate
+* Fixed #3089: Text formatting sometimes breaks when combined
+* Fixed #3690: Status change info duplicates on the issue screen
+* Fixed #3691: Redmine allows two files with the same file name to be uploaded to the same issue
+* Fixed #3764: ApplicationHelperTest fails with JRuby
+* Fixed #4265: Unclosed code tags in issue descriptions affects main UI
+* Fixed #4745: Bug in index.xml.builder (issues)
+* Fixed #4852: changing user/roles of project member not possible without javascript
+* Fixed #4857: Week number calculation in date picker is wrong if a week starts with Sunday
+* Fixed #4883: Bottom "contextual" placement in issue with associated changeset
+* Fixed #4918: Revisions r3453 and r3454 broke On-the-fly user creation with LDAP
+* Fixed #4935: Navigation to the Master Timesheet page (time_entries)
+* Fixed #5043: Flash messages are not displayed after the project settings[module/activity] saved
+* Fixed #5081: Broken links on public/help/wiki_syntax_detailed.html
+* Fixed #5104: Description of document not wikified on documents index
+* Fixed #5108: Issue linking fails inside of []s
+* Fixed #5199: diff code coloring using coderay
+* Fixed #5233: Add a hook to the issue report (Summary) view
+* Fixed #5265: timetracking: subtasks time is added to the main task
+* Fixed #5343: acts_as_event Doesn't Accept Outside URLs
+* Fixed #5440: UI Inconsistency : Administration > Enumerations table row headers should be enclosed in <thead>
+* Fixed #5463: 0.9.4 INSTALL and/or UPGRADE, missing session_store.rb
+* Fixed #5524: Update_parent_attributes doesn't work for the old parent issue when reparenting
+* Fixed #5548: SVN Repository: Can not list content of a folder which includes square brackets.
+* Fixed #5589: "with subproject" malfunction
+* Fixed #5676: Search for Numeric Value
+* Fixed #5696: Redmine + PostgreSQL 8.4.4 fails on _dir_list_content.rhtml
+* Fixed #5698: redmine:email:receive_imap fails silently for mails with subject longer than 255 characters
+* Fixed #5700: TimelogController#destroy assumes success
+* Fixed #5751: developer role is mispelled
+* Fixed #5769: Popup Calendar doesn't Advance in Chrome
+* Fixed #5771: Problem when importing git repository
+* Fixed #5823: Error in comments in plugin.rb
+
+
+== 2010-07-07 v0.9.6
+
+* Fixed: Redmine.pm access by unauthorized users
+
+== 2010-06-24 v0.9.5
+
+* Linkify folder names on revision view
+* "fiters" and "options" should be hidden in print view via css
+* Fixed: NoMethodError when no issue params are submitted
+* Fixed: projects.atom with required authentication
+* Fixed: External links not correctly displayed in Wiki TOC
+* Fixed: Member role forms in project settings are not hidden after member added
+* Fixed: pre can't be inside p
+* Fixed: session cookie path does not respect RAILS_RELATIVE_URL_ROOT
+* Fixed: mail handler fails when the from address is empty
+
+
+== 2010-05-01 v0.9.4
+
+* Filters collapsed by default on issues index page for a saved query
+* Fixed: When categories list is too big the popup menu doesn't adjust (ex. in the issue list)
+* Fixed: remove "main-menu" div when the menu is empty
+* Fixed: Code syntax highlighting not working in Document page
+* Fixed: Git blame/annotate fails on moved files
+* Fixed: Failing test in test_show_atom
+* Fixed: Migrate from trac - not displayed Wikis
+* Fixed: Email notifications on file upload sent to empty recipient list
+* Fixed: Migrating from trac is not possible, fails to allocate memory
+* Fixed: Lost password no longer flashes a confirmation message
+* Fixed: Crash while deleting in-use enumeration
+* Fixed: Hard coded English string at the selection of issue watchers
+* Fixed: Bazaar v2.1.0 changed behaviour
+* Fixed: Roadmap display can raise an exception if no trackers are selected
+* Fixed: Gravatar breaks layout of "logged in" page
+* Fixed: Reposman.rb on Windows
+* Fixed: Possible error 500 while moving an issue to another project with SQLite
+* Fixed: backslashes in issue description/note should be escaped when quoted
+* Fixed: Long text in <pre> disrupts Associated revisions
+* Fixed: Links to missing wiki pages not red on project overview page
+* Fixed: Cannot delete a project with subprojects that shares versions
+* Fixed: Update of Subversion changesets broken under Solaris
+* Fixed: "Move issues" permission not working for Non member
+* Fixed: Sidebar overlap on Users tab of Group editor
+* Fixed: Error on db:migrate with table prefix set (hardcoded name in principal.rb)
+* Fixed: Report shows sub-projects for non-members
+* Fixed: 500 internal error when browsing any Redmine page in epiphany
+* Fixed: Watchers selection lost when issue creation fails
+* Fixed: When copying projects, redmine should not generate an email to people who created issues
+* Fixed: Issue "#" table cells should have a class attribute to enable fine-grained CSS theme
+* Fixed: Plugin generators should display help if no parameter is given
+
+
+== 2010-02-28 v0.9.3
+
+* Adds filter for system shared versions on the cross project issue list
+* Makes project identifiers searchable
+* Remove invalid utf8 sequences from commit comments and author name
+* Fixed: Wrong link when "http" not included in project "Homepage" link
+* Fixed: Escaping in html email templates
+* Fixed: Pound (#) followed by number with leading zero (0) removes leading zero when rendered in wiki
+* Fixed: Deselecting textile text formatting causes interning empty string errors
+* Fixed: error with postgres when entering a non-numeric id for an issue relation
+* Fixed: div.task incorrectly wrapping on Gantt Chart
+* Fixed: Project copy loses wiki pages hierarchy
+* Fixed: parent project field doesn't include blank value when a member with 'add subproject' permission edits a child project
+* Fixed: Repository.fetch_changesets tries to fetch changesets for archived projects
+* Fixed: Duplicated project name for subproject version on gantt chart
+* Fixed: roadmap shows subprojects issues even if subprojects is unchecked
+* Fixed: IndexError if all the :last menu items are deleted from a menu
+* Fixed: Very high CPU usage for a long time when fetching commits from a large Git repository
+
+
+== 2010-02-07 v0.9.2
+
+* Fixed: Sub-project repository commits not displayed on parent project issues
+* Fixed: Potential security leak on my page calendar
+* Fixed: Project tree structure is broken by deleting the project with the subproject
+* Fixed: Error message shown duplicated when creating a new group
+* Fixed: Firefox cuts off large pages
+* Fixed: Invalid format parameter returns a DoubleRenderError on issues index
+* Fixed: Unnecessary Quote button on locked forum message
+* Fixed: Error raised when trying to view the gantt or calendar with a grouped query
+* Fixed: PDF support for Korean locale
+* Fixed: Deprecation warning in extra/svn/reposman.rb
+
+
+== 2010-01-30 v0.9.1
+
+* Vertical alignment for inline images in formatted text set to 'middle'
+* Fixed: Redmine.pm error "closing dbh with active statement handles at /usr/lib/perl5/Apache/Redmine.pm"
+* Fixed: copyright year in footer set to 2010
+* Fixed: Trac migration script may not output query lines
+* Fixed: Email notifications may affect language of notice messages on the UI
+* Fixed: Can not search for 2 letters word
+* Fixed: Attachments get saved on issue update even if validation fails
+* Fixed: Tab's 'border-bottom' not absent when selected
+* Fixed: Issue summary tables that list by user are not sorted
+* Fixed: Issue pdf export fails if target version is set
+* Fixed: Issue list export to PDF breaks when issues are sorted by a custom field
+* Fixed: SQL error when adding a group
+* Fixes: Min password length during password reset always displays as 4 chars
+
+
+== 2010-01-09 v0.9.0 (Release candidate)
+
+* Unlimited subproject nesting
+* Multiple roles per user per project
+* User groups
+* Inheritence of versions
+* OpenID login
+* "Watched by me" issue filter
+* Project copy
+* Project creation by non admin users
+* Accept emails from anyone on a private project
+* Add email notification on Wiki changes
+* Make issue description non-required field
+* Custom fields for Versions
+* Being able to sort the issue list by custom fields
+* Ability to close versions
+* User display/editing of custom fields attached to their user profile
+* Add "follows" issue relation
+* Copy workflows between trackers and roles
+* Defaults enabled modules list for project creation
+* Weighted version completion percentage on the roadmap
+* Autocreate user account when user submits email that creates new issue
+* CSS class on overdue issues on the issue list
+* Enable tracker update on issue edit form
+* Remove issue watchers
+* Ability to move threads between project forums
+* Changed custom field "Possible values" to a textarea
+* Adds projects association on tracker form
+* Set session store to cookie store by default
+* Set a default wiki page on project creation
+* Roadmap for main project should see Roadmaps for sub projects
+* Ticket grouping on the issue list
+* Hierarchical Project links in the page header
+* Allow My Page blocks to be added to from a plugin
+* Sort issues by multiple columns
+* Filters of saved query are now visible and be adjusted without editing the query
+* Saving "sort order" in custom queries
+* Url to fetch changesets for a repository
+* Managers able to create subprojects
+* Issue Totals on My Page Modules
+* Convert Enumerations to single table inheritance (STI)
+* Allow custom my_page blocks to define drop-down names
+* "View Issues" user permission added
+* Ask user what to do with child pages when deleting a parent wiki page
+* Contextual quick search
+* Allow resending of password by email
+* Change reply subject to be a link to the reply itself
+* Include Logged Time as part of the project's Activity history
+* REST API for authentication
+* Browse through Git branches
+* Setup Object Daddy to replace test fixtures
+* Setup shoulda to make it easier to test
+* Custom fields and overrides on Enumerations
+* Add or remove columns from the issue list
+* Ability to add new version from issues screen
+* Setting to choose which day calendars start
+* Asynchronous email delivery method
+* RESTful URLs for (almost) everything
+* Include issue status in search results and activity pages
+* Add email to admin user search filter
+* Proper content type for plain text mails
+* Default value of project jump box
+* Tree based menus
+* Ability to use issue status to update percent done
+* Second set of issue "Action Links" at the bottom of an issue page
+* Proper exist status code for rdm-mailhandler.rb
+* Remove incoming email body via a delimiter
+* Fixed: Custom querry 'Export to PDF' ignores field selection
+* Fixed: Related e-mail notifications aren't threaded
+* Fixed: No warning when the creation of a categories from the issue form fails
+* Fixed: Actually block issues from closing when relation 'blocked by' isn't closed
+* Fixed: Include both first and last name when sorting by users
+* Fixed: Table cell with multiple line text
+* Fixed: Project overview page shows disabled trackers
+* Fixed: Cross project issue relations and user permissions
+* Fixed: My page shows tickets the user doesn't have access to
+* Fixed: TOC does not parse wiki page reference links with description
+* Fixed: Target version-list on bulk edit form is incorrectly sorted
+* Fixed: Cannot modify/delete project named "Documents"
+* Fixed: Email address in brackets breaks html
+* Fixed: Timelog detail loose issue filter passing to report tab
+* Fixed: Inform about custom field's name maximum length
+* Fixed: Activity page and Atom feed links contain project id instead of identifier
+* Fixed: no Atom key for forums with only 1 forum
+* Fixed: When reading RSS feed in MS Outlook, the inline links are broken.
+* Fixed: Sometimes new posts don't show up in the topic list of a forum.
+* Fixed: The all/active filter selection in the project view does not stick.
+* Fixed: Login box has Different width
+* Fixed: User removed from project - still getting project update emails
+* Fixed: Project with the identifier of 'new' cannot be viewed
+* Fixed: Artefacts in search view (Cyrillic)
+* Fixed: Allow [#id] as subject to reply by email
+* Fixed: Wrong language used when closing an issue via a commit message
+* Fixed: email handler drops emails for new issues with no subject
+* Fixed: Calendar misspelled under Roles/Permissions
+* Fixed: Emails from no-reply redmine's address hell cycle
+* Fixed: child_pages macro fails on wiki page history
+* Fixed: Pre-filled time tracking date ignores timezone
+* Fixed: Links on locked users lead to 404 page
+* Fixed: Page changes in issue-list when using context menu
+* Fixed: diff parser removes lines starting with multiple dashes
+* Fixed: Quoting in forums resets message subject
+* Fixed: Editing issue comment removes quote link
+* Fixed: Redmine.pm ignore browse_repository permission
+* Fixed: text formatting breaks on [msg1][msg2]
+* Fixed: Spent Time Default Value of 0.0
+* Fixed: Wiki pages in search results are referenced by project number, not by project identifier.
+* Fixed: When logging in via an autologin cookie the user's last_login_on should be updated
+* Fixed: 50k users cause problems in project->settings->members screen
+* Fixed: Document timestamp needs to show updated timestamps
+* Fixed: Users getting notifications for issues they are no longer allowed to view
+* Fixed: issue summary counts should link to the issue list without subprojects
+* Fixed: 'Delete' link on LDAP list has no effect
+
+
+== 2009-11-15 v0.8.7
+
+* Fixed: Hide paragraph terminator at the end of headings on html export
+* Fixed: pre tags containing "<pre*"
+* Fixed: First date of the date range not included in the time report with SQLite
+* Fixed: Password field not styled correctly on alternative stylesheet
+* Fixed: Error when sumbitting a POST request that requires a login
+* Fixed: CSRF vulnerabilities
+
+
+== 2009-11-04 v0.8.6
+
+* Change links to closed issues to be a grey color
+* Change subversion adapter to not cache authentication and run non interactively
+* Fixed: Custom Values with a nil value cause HTTP error 500
+* Fixed: Failure to convert HTML entities when editing an Issue reply
+* Fixed: Error trying to show repository when there are no comments in a changeset
+* Fixed: account/show/:user_id should not be accessible for other users not in your projects
+* Fixed: XSS vulnerabilities
+* Fixed: IssuesController#destroy should accept POST only
+* Fixed: Inline images in wiki headings
+
+
+== 2009-09-13 v0.8.5
+
+* Incoming mail handler : Allow spaces between keywords and colon
+* Do not require a non-word character after a comma in Redmine links
+* Include issue hyperlinks in reminder emails
+* Prevent nil error when retrieving svn version
+* Various plugin hooks added
+* Add plugins information to script/about
+* Fixed: 500 Internal Server Error is raised if add an empty comment to the news
+* Fixed: Atom links for wiki pages are not correct
+* Fixed: Atom feeds leak email address
+* Fixed: Case sensitivity in Issue filtering
+* Fixed: When reading RSS feed, the inline-embedded images are not properly shown
+
+
+== 2009-05-17 v0.8.4
+
+* Allow textile mailto links
+* Fixed: memory consumption when uploading file
+* Fixed: Mercurial integration doesn't work if Redmine is installed in folder path containing space
+* Fixed: an error is raised when no tab is available on project settings
+* Fixed: insert image macro corrupts urls with excalamation marks
+* Fixed: error on cross-project gantt PNG export
+* Fixed: self and alternate links in atom feeds do not respect Atom specs
+* Fixed: accept any svn tunnel scheme in repository URL
+* Fixed: issues/show should accept user's rss key
+* Fixed: consistency of custom fields display on the issue detail view
+* Fixed: wiki comments length validation is missing
+* Fixed: weak autologin token generation algorithm causes duplicate tokens
+
+
+== 2009-04-05 v0.8.3
+
+* Separate project field and subject in cross-project issue view
+* Ability to set language for redmine:load_default_data task using REDMINE_LANG environment variable
+* Rescue Redmine::DefaultData::DataAlreadyLoaded in redmine:load_default_data task
+* CSS classes to highlight own and assigned issues
+* Hide "New file" link on wiki pages from printing
+* Flush buffer when asking for language in redmine:load_default_data task
+* Minimum project identifier length set to 1
+* Include headers so that emails don't trigger vacation auto-responders
+* Fixed: Time entries csv export links for all projects are malformed
+* Fixed: Files without Version aren't visible in the Activity page
+* Fixed: Commit logs are centered in the repo browser
+* Fixed: News summary field content is not searchable
+* Fixed: Journal#save has a wrong signature
+* Fixed: Email footer signature convention
+* Fixed: Timelog report do not show time for non-versioned issues
+
+
+== 2009-03-07 v0.8.2
+
+* Send an email to the user when an administrator activates a registered user
+* Strip keywords from received email body
+* Footer updated to 2009
+* Show RSS-link even when no issues is found
+* One click filter action in activity view
+* Clickable/linkable line #'s while browsing the repo or viewing a file
+* Links to versions on files list
+* Added request and controller objects to the hooks by default
+* Fixed: exporting an issue with attachments to PDF raises an error
+* Fixed: "too few arguments" error may occur on activerecord error translation
+* Fixed: "Default columns Displayed on the Issues list" setting is not easy to read
+* Fixed: visited links to closed tickets are not striked through with IE6
+* Fixed: MailHandler#plain_text_body returns nil if there was nothing to strip
+* Fixed: MailHandler raises an error when processing an email without From header
+
+
+== 2009-02-15 v0.8.1
+
+* Select watchers on new issue form
+* Issue description is no longer a required field
+* Files module: ability to add files without version
+* Jump to the current tab when using the project quick-jump combo
+* Display a warning if some attachments were not saved
+* Import custom fields values from emails on issue creation
+* Show view/annotate/download links on entry and annotate views
+* Admin Info Screen: Display if plugin assets directory is writable
+* Adds a 'Create and continue' button on the new issue form
+* IMAP: add options to move received emails
+* Do not show Category field when categories are not defined
+* Lower the project identifier limit to a minimum of two characters
+* Add "closed" html class to closed entries in issue list
+* Fixed: broken redirect URL on login failure
+* Fixed: Deleted files are shown when using Darcs
+* Fixed: Darcs adapter works on Win32 only
+* Fixed: syntax highlight doesn't appear in new ticket preview
+* Fixed: email notification for changes I make still occurs when running Repository.fetch_changesets
+* Fixed: no error is raised when entering invalid hours on the issue update form
+* Fixed: Details time log report CSV export doesn't honour date format from settings
+* Fixed: invalid css classes on issue details
+* Fixed: Trac importer creates duplicate custom values
+* Fixed: inline attached image should not match partial filename
+
+
+== 2008-12-30 v0.8.0
+
+* Setting added in order to limit the number of diff lines that should be displayed
+* Makes logged-in username in topbar linking to
+* Mail handler: strip tags when receiving a html-only email
+* Mail handler: add watchers before sending notification
+* Adds a css class (overdue) to overdue issues on issue lists and detail views
+* Fixed: project activity truncated after viewing user's activity
+* Fixed: email address entered for password recovery shouldn't be case-sensitive
+* Fixed: default flag removed when editing a default enumeration
+* Fixed: default category ignored when adding a document
+* Fixed: error on repository user mapping when a repository username is blank
+* Fixed: Firefox cuts off large diffs
+* Fixed: CVS browser should not show dead revisions (deleted files)
+* Fixed: escape double-quotes in image titles
+* Fixed: escape textarea content when editing a issue note
+* Fixed: JS error on context menu with IE
+* Fixed: bold syntax around single character in series doesn't work
+* Fixed several XSS vulnerabilities
+* Fixed a SQL injection vulnerability
+
+
+== 2008-12-07 v0.8.0-rc1
+
+* Wiki page protection
+* Wiki page hierarchy. Parent page can be assigned on the Rename screen
+* Adds support for issue creation via email
+* Adds support for free ticket filtering and custom queries on Gantt chart and calendar
+* Cross-project search
+* Ability to search a project and its subprojects
+* Ability to search the projects the user belongs to
+* Adds custom fields on time entries
+* Adds boolean and list custom fields for time entries as criteria on time report
+* Cross-project time reports
+* Display latest user's activity on account/show view
+* Show last connexion time on user's page
+* Obfuscates email address on user's account page using javascript
+* wiki TOC rendered as an unordered list
+* Adds the ability to search for a user on the administration users list
+* Adds the ability to search for a project name or identifier on the administration projects list
+* Redirect user to the previous page after logging in
+* Adds a permission 'view wiki edits' so that wiki history can be hidden to certain users
+* Adds permissions for viewing the watcher list and adding new watchers on the issue detail view
+* Adds permissions to let users edit and/or delete their messages
+* Link to activity view when displaying dates
+* Hide Redmine version in atom feeds and pdf properties
+* Maps repository users to Redmine users. Users with same username or email are automatically mapped. Mapping can be manually adjusted in repository settings. Multiple usernames can be mapped to the same Redmine user.
+* Sort users by their display names so that user dropdown lists are sorted alphabetically
+* Adds estimated hours to issue filters
+* Switch order of current and previous revisions in side-by-side diff
+* Render the commit changes list as a tree
+* Adds watch/unwatch functionality at forum topic level
+* When moving an issue to another project, reassign it to the category with same name if any
+* Adds child_pages macro for wiki pages
+* Use GET instead of POST on roadmap (#718), gantt and calendar forms
+* Search engine: display total results count and count by result type
+* Email delivery configuration moved to an unversioned YAML file (config/email.yml, see the sample file)
+* Adds icons on search results
+* Adds 'Edit' link on account/show for admin users
+* Adds Lock/Unlock/Activate link on user edit screen
+* Adds user count in status drop down on admin user list
+* Adds multi-levels blockquotes support by using > at the beginning of lines
+* Adds a Reply link to each issue note
+* Adds plain text only option for mail notifications
+* Gravatar support for issue detail, user grid, and activity stream (disabled by default)
+* Adds 'Delete wiki pages attachments' permission
+* Show the most recent file when displaying an inline image
+* Makes permission screens localized
+* AuthSource list: display associated users count and disable 'Delete' buton if any
+* Make the 'duplicates of' relation asymmetric
+* Adds username to the password reminder email
+* Adds links to forum messages using message#id syntax
+* Allow same name for custom fields on different object types
+* One-click bulk edition using the issue list context menu within the same project
+* Adds support for commit logs reencoding to UTF-8 before insertion in the database. Source encoding of commit logs can be selected in Application settings -> Repositories.
+* Adds checkboxes toggle links on permissions report
+* Adds Trac-Like anchors on wiki headings
+* Adds support for wiki links with anchor
+* Adds category to the issue context menu
+* Adds a workflow overview screen
+* Appends the filename to the attachment url so that clients that ignore content-disposition http header get the real filename
+* Dots allowed in custom field name
+* Adds posts quoting functionality
+* Adds an option to generate sequential project identifiers
+* Adds mailto link on the user administration list
+* Ability to remove enumerations (activities, priorities, document categories) that are in use. Associated objects can be reassigned to another value
+* Gantt chart: display issues that don't have a due date if they are assigned to a version with a date
+* Change projects homepage limit to 255 chars
+* Improved on-the-fly account creation. If some attributes are missing (eg. not present in the LDAP) or are invalid, the registration form is displayed so that the user is able to fill or fix these attributes
+* Adds "please select" to activity select box if no activity is set as default
+* Do not silently ignore timelog validation failure on issue edit
+* Adds a rake task to send reminder emails
+* Allow empty cells in wiki tables
+* Makes wiki text formatter pluggable
+* Adds back textile acronyms support
+* Remove pre tag attributes
+* Plugin hooks
+* Pluggable admin menu
+* Plugins can provide activity content
+* Moves plugin list to its own administration menu item
+* Adds url and author_url plugin attributes
+* Adds Plugin#requires_redmine method so that plugin compatibility can be checked against current Redmine version
+* Adds atom feed on time entries details
+* Adds project name to issues feed title
+* Adds a css class on menu items in order to apply item specific styles (eg. icons)
+* Adds a Redmine plugin generators
+* Adds timelog link to the issue context menu
+* Adds links to the user page on various views
+* Turkish translation by Ismail Sezen
+* Catalan translation
+* Vietnamese translation
+* Slovak translation
+* Better naming of activity feed if only one kind of event is displayed
+* Enable syntax highlight on issues, messages and news
+* Add target version to the issue list context menu
+* Hide 'Target version' filter if no version is defined
+* Add filters on cross-project issue list for custom fields marked as 'For all projects'
+* Turn ftp urls into links
+* Hiding the View Differences button when a wiki page's history only has one version
+* Messages on a Board can now be sorted by the number of replies
+* Adds a class ('me') to events of the activity view created by current user
+* Strip pre/code tags content from activity view events
+* Display issue notes in the activity view
+* Adds links to changesets atom feed on repository browser
+* Track project and tracker changes in issue history
+* Adds anchor to atom feed messages links
+* Adds a key in lang files to set the decimal separator (point or comma) in csv exports
+* Makes importer work with Trac 0.8.x
+* Upgraded to Prototype 1.6.0.1
+* File viewer for attached text files
+* Menu mapper: add support for :before, :after and :last options to #push method and add #delete method
+* Removed inconsistent revision numbers on diff view
+* CVS: add support for modules names with spaces
+* Log the user in after registration if account activation is not needed
+* Mercurial adapter improvements
+* Trac importer: read session_attribute table to find user's email and real name
+* Ability to disable unused SCM adapters in application settings
+* Adds Filesystem adapter
+* Clear changesets and changes with raw sql when deleting a repository for performance
+* Redmine.pm now uses the 'commit access' permission defined in Redmine
+* Reposman can create any type of scm (--scm option)
+* Reposman creates a repository if the 'repository' module is enabled at project level only
+* Display svn properties in the browser, svn >= 1.5.0 only
+* Reduces memory usage when importing large git repositories
+* Wider SVG graphs in repository stats
+* SubversionAdapter#entries performance improvement
+* SCM browser: ability to download raw unified diffs
+* More detailed error message in log when scm command fails
+* Adds support for file viewing with Darcs 2.0+
+* Check that git changeset is not in the database before creating it
+* Unified diff viewer for attached files with .patch or .diff extension
+* File size display with Bazaar repositories
+* Git adapter: use commit time instead of author time
+* Prettier url for changesets
+* Makes changes link to entries on the revision view
+* Adds a field on the repository view to browse at specific revision
+* Adds new projects atom feed
+* Added rake tasks to generate rcov code coverage reports
+* Add Redcloth's :block_markdown_rule to allow horizontal rules in wiki
+* Show the project hierarchy in the drop down list for new membership on user administration screen
+* Split user edit screen into tabs
+* Renames bundled RedCloth to RedCloth3 to avoid RedCloth 4 to be loaded instead
+* Fixed: Roadmap crashes when a version has a due date > 2037
+* Fixed: invalid effective date (eg. 99999-01-01) causes an error on version edition screen
+* Fixed: login filter providing incorrect back_url for Redmine installed in sub-directory
+* Fixed: logtime entry duplicated when edited from parent project
+* Fixed: wrong digest for text files under Windows
+* Fixed: associated revisions are displayed in wrong order on issue view
+* Fixed: Git Adapter date parsing ignores timezone
+* Fixed: Printing long roadmap doesn't split across pages
+* Fixes custom fields display order at several places
+* Fixed: urls containing @ are parsed as email adress by the wiki formatter
+* Fixed date filters accuracy with SQLite
+* Fixed: tokens not escaped in highlight_tokens regexp
+* Fixed Bazaar shared repository browsing
+* Fixes platform determination under JRuby
+* Fixed: Estimated time in issue's journal should be rounded to two decimals
+* Fixed: 'search titles only' box ignored after one search is done on titles only
+* Fixed: non-ASCII subversion path can't be displayed
+* Fixed: Inline images don't work if file name has upper case letters or if image is in BMP format
+* Fixed: document listing shows on "my page" when viewing documents is disabled for the role
+* Fixed: Latest news appear on the homepage for projects with the News module disabled
+* Fixed: cross-project issue list should not show issues of projects for which the issue tracking module was disabled
+* Fixed: the default status is lost when reordering issue statuses
+* Fixes error with Postgresql and non-UTF8 commit logs
+* Fixed: textile footnotes no longer work
+* Fixed: http links containing parentheses fail to reder correctly
+* Fixed: GitAdapter#get_rev should use current branch instead of hardwiring master
+
+
+== 2008-07-06 v0.7.3
+
+* Allow dot in firstnames and lastnames
+* Add project name to cross-project Atom feeds
+* Encoding set to utf8 in example database.yml
+* HTML titles on forums related views
+* Fixed: various XSS vulnerabilities
+* Fixed: Entourage (and some old client) fails to correctly render notification styles
+* Fixed: Fixed: timelog redirects inappropriately when :back_url is blank
+* Fixed: wrong relative paths to images in wiki_syntax.html
+
+
+== 2008-06-15 v0.7.2
+
+* "New Project" link on Projects page
+* Links to repository directories on the repo browser
+* Move status to front in Activity View
+* Remove edit step from Status context menu
+* Fixed: No way to do textile horizontal rule
+* Fixed: Repository: View differences doesn't work
+* Fixed: attachement's name maybe invalid.
+* Fixed: Error when creating a new issue
+* Fixed: NoMethodError on @available_filters.has_key?
+* Fixed: Check All / Uncheck All in Email Settings
+* Fixed: "View differences" of one file at /repositories/revision/ fails
+* Fixed: Column width in "my page"
+* Fixed: private subprojects are listed on Issues view
+* Fixed: Textile: bold, italics, underline, etc... not working after parentheses
+* Fixed: Update issue form: comment field from log time end out of screen
+* Fixed: Editing role: "issue can be assigned to this role" out of box
+* Fixed: Unable use angular braces after include word
+* Fixed: Using '*' as keyword for repository referencing keywords doesn't work
+* Fixed: Subversion repository "View differences" on each file rise ERROR
+* Fixed: View differences for individual file of a changeset fails if the repository URL doesn't point to the repository root
+* Fixed: It is possible to lock out the last admin account
+* Fixed: Wikis are viewable for anonymous users on public projects, despite not granting access
+* Fixed: Issue number display clipped on 'my issues'
+* Fixed: Roadmap version list links not carrying state
+* Fixed: Log Time fieldset in IssueController#edit doesn't set default Activity as default
+* Fixed: git's "get_rev" API should use repo's current branch instead of hardwiring "master"
+* Fixed: browser's language subcodes ignored
+* Fixed: Error on project selection with numeric (only) identifier.
+* Fixed: Link to PDF doesn't work after creating new issue
+* Fixed: "Replies" should not be shown on forum threads that are locked
+* Fixed: SVN errors lead to svn username/password being displayed to end users (security issue)
+* Fixed: http links containing hashes don't display correct
+* Fixed: Allow ampersands in Enumeration names
+* Fixed: Atom link on saved query does not include query_id
+* Fixed: Logtime info lost when there's an error updating an issue
+* Fixed: TOC does not parse colorization markups
+* Fixed: CVS: add support for modules names with spaces
+* Fixed: Bad rendering on projects/add
+* Fixed: exception when viewing differences on cvs
+* Fixed: export issue to pdf will messup when use Chinese language
+* Fixed: Redmine::Scm::Adapters::GitAdapter#get_rev ignored GIT_BIN constant
+* Fixed: Adding non-ASCII new issue type in the New Issue page have encoding error using IE
+* Fixed: Importing from trac : some wiki links are messed
+* Fixed: Incorrect weekend definition in Hebrew calendar locale
+* Fixed: Atom feeds don't provide author section for repository revisions
+* Fixed: In Activity views, changesets titles can be multiline while they should not
+* Fixed: Ignore unreadable subversion directories (read disabled using authz)
+* Fixed: lib/SVG/Graph/Graph.rb can't externalize stylesheets
+* Fixed: Close statement handler in Redmine.pm
+
+
+== 2008-05-04 v0.7.1
+
+* Thai translation added (Gampol Thitinilnithi)
+* Translations updates
+* Escape HTML comment tags
+* Prevent "can't convert nil into String" error when :sort_order param is not present
+* Fixed: Updating tickets add a time log with zero hours
+* Fixed: private subprojects names are revealed on the project overview
+* Fixed: Search for target version of "none" fails with postgres 8.3
+* Fixed: Home, Logout, Login links shouldn't be absolute links
+* Fixed: 'Latest projects' box on the welcome screen should be hidden if there are no projects
+* Fixed: error when using upcase language name in coderay
+* Fixed: error on Trac import when :due attribute is nil
+
+
+== 2008-04-28 v0.7.0
+
+* Forces Redmine to use rails 2.0.2 gem when vendor/rails is not present
+* Queries can be marked as 'For all projects'. Such queries will be available on all projects and on the global issue list.
+* Add predefined date ranges to the time report
+* Time report can be done at issue level
+* Various timelog report enhancements
+* Accept the following formats for "hours" field: 1h, 1 h, 1 hour, 2 hours, 30m, 30min, 1h30, 1h30m, 1:30
+* Display the context menu above and/or to the left of the click if needed
+* Make the admin project files list sortable
+* Mercurial: display working directory files sizes unless browsing a specific revision
+* Preserve status filter and page number when using lock/unlock/activate links on the users list
+* Redmine.pm support for LDAP authentication
+* Better error message and AR errors in log for failed LDAP on-the-fly user creation
+* Redirected user to where he is coming from after logging hours
+* Warn user that subprojects are also deleted when deleting a project
+* Include subprojects versions on calendar and gantt
+* Notify project members when a message is posted if they want to receive notifications
+* Fixed: Feed content limit setting has no effect
+* Fixed: Priorities not ordered when displayed as a filter in issue list
+* Fixed: can not display attached images inline in message replies
+* Fixed: Boards are not deleted when project is deleted
+* Fixed: trying to preview a new issue raises an exception with postgresql
+* Fixed: single file 'View difference' links do not work because of duplicate slashes in url
+* Fixed: inline image not displayed when including a wiki page
+* Fixed: CVS duplicate key violation
+* Fixed: ActiveRecord::StaleObjectError exception on closing a set of circular duplicate issues
+* Fixed: custom field filters behaviour
+* Fixed: Postgresql 8.3 compatibility
+* Fixed: Links to repository directories don't work
+
+
+== 2008-03-29 v0.7.0-rc1
+
+* Overall activity view and feed added, link is available on the project list
+* Git VCS support
+* Rails 2.0 sessions cookie store compatibility
+* Use project identifiers in urls instead of ids
+* Default configuration data can now be loaded from the administration screen
+* Administration settings screen split to tabs (email notifications options moved to 'Settings')
+* Project description is now unlimited and optional
+* Wiki annotate view
+* Escape HTML tag in textile content
+* Add Redmine links to documents, versions, attachments and repository files
+* New setting to specify how many objects should be displayed on paginated lists. There are 2 ways to select a set of issues on the issue list:
+    * by using checkbox and/or the little pencil that will select/unselect all issues
+    * by clicking on the rows (but not on the links), Ctrl and Shift keys can be used to select multiple issues
+* Context menu disabled on links so that the default context menu of the browser is displayed when right-clicking on a link (click anywhere else on the row to display the context menu)
+* User display format is now configurable in administration settings
+* Issue list now supports bulk edit/move/delete (for a set of issues that belong to the same project)
+* Merged 'change status', 'edit issue' and 'add note' actions:
+    * Users with 'edit issues' permission can now update any property including custom fields when adding a note or changing the status
+    * 'Change issue status' permission removed. To change an issue status, a user just needs to have either 'Edit' or 'Add note' permissions and some workflow transitions allowed
+* Details by assignees on issue summary view
+* 'New issue' link in the main menu (accesskey 7). The drop-down lists to add an issue on the project overview and the issue list are removed
+* Change status select box default to current status
+* Preview for issue notes, news and messages
+* Optional description for attachments
+* 'Fixed version' label changed to 'Target version'
+* Let the user choose when deleting issues with reported hours to:
+    * delete the hours
+    * assign the hours to the project
+    * reassign the hours to another issue
+* Date range filter and pagination on time entries detail view
+* Propagate time tracking to the parent project
+* Switch added on the project activity view to include subprojects
+* Display total estimated and spent hours on the version detail view
+* Weekly time tracking block for 'My page'
+* Permissions to edit time entries
+* Include subprojects on the issue list, calendar, gantt and timelog by default (can be turned off is administration settings)
+* Roadmap enhancements (separate related issues from wiki contents, leading h1 in version wiki pages is hidden, smaller wiki headings)
+* Make versions with same date sorted by name
+* Allow issue list to be sorted by target version
+* Related changesets messages displayed on the issue details view
+* Create a journal and send an email when an issue is closed by commit
+* Add 'Author' to the available columns for the issue list
+* More appropriate default sort order on sortable columns
+* Add issue subject to the time entries view and issue subject, description and tracker to the csv export
+* Permissions to edit issue notes
+* Display date/time instead of date on files list
+* Do not show Roadmap menu item if the project doesn't define any versions
+* Allow longer version names (60 chars)
+* Ability to copy an existing workflow when creating a new role
+* Display custom fields in two columns on the issue form
+* Added 'estimated time' in the csv export of the issue list
+* Display the last 30 days on the activity view rather than the current month (number of days can be configured in the application settings)
+* Setting for whether new projects should be public by default
+* User preference to choose how comments/replies are displayed: in chronological or reverse chronological order
+* Added default value for custom fields
+* Added tabindex property on wiki toolbar buttons (to easily move from field to field using the tab key)
+* Redirect to issue page after creating a new issue
+* Wiki toolbar improvements (mainly for Firefox)
+* Display wiki syntax quick ref link on all wiki textareas
+* Display links to Atom feeds
+* Breadcrumb nav for the forums
+* Show replies when choosing to display messages in the activity
+* Added 'include' macro to include another wiki page
+* RedmineWikiFormatting page available as a static HTML file locally
+* Wrap diff content
+* Strip out email address from authors in repository screens
+* Highlight the current item of the main menu
+* Added simple syntax highlighters for php and java languages
+* Do not show empty diffs
+* Show explicit error message when the scm command failed (eg. when svn binary is not available)
+* Lithuanian translation added (Sergej Jegorov)
+* Ukrainan translation added (Natalia Konovka & Mykhaylo Sorochan)
+* Danish translation added (Mads Vestergaard)
+* Added i18n support to the jstoolbar and various settings screen
+* RedCloth's glyphs no longer user
+* New icons for the wiki toolbar (from http://www.famfamfam.com/lab/icons/silk/)
+* The following menus can now be extended by plugins: top_menu, account_menu, application_menu
+* Added a simple rake task to fetch changesets from the repositories: rake redmine:fetch_changesets
+* Remove hardcoded "Redmine" strings in account related emails and use application title instead
+* Mantis importer preserve bug ids
+* Trac importer: Trac guide wiki pages skipped
+* Trac importer: wiki attachments migration added
+* Trac importer: support database schema for Trac migration
+* Trac importer: support CamelCase links
+* Removes the Redmine version from the footer (can be viewed on admin -> info)
+* Rescue and display an error message when trying to delete a role that is in use
+* Add various 'X-Redmine' headers to email notifications: X-Redmine-Host, X-Redmine-Site, X-Redmine-Project, X-Redmine-Issue-Id, -Author, -Assignee, X-Redmine-Topic-Id
+* Add "--encoding utf8" option to the Mercurial "hg log" command in order to get utf8 encoded commit logs
+* Fixed: Gantt and calendar not properly refreshed (fragment caching removed)
+* Fixed: Textile image with style attribute cause internal server error
+* Fixed: wiki TOC not rendered properly when used in an issue or document description
+* Fixed: 'has already been taken' error message on username and email fields if left empty
+* Fixed: non-ascii attachement filename with IE
+* Fixed: wrong url for wiki syntax pop-up when Redmine urls are prefixed
+* Fixed: search for all words doesn't work
+* Fixed: Do not show sticky and locked checkboxes when replying to a message
+* Fixed: Mantis importer: do not duplicate Mantis username in firstname and lastname if realname is blank
+* Fixed: Date custom fields not displayed as specified in application settings
+* Fixed: titles not escaped in the activity view
+* Fixed: issue queries can not use custom fields marked as 'for all projects' in a project context
+* Fixed: on calendar, gantt and in the tracker filter on the issue list, only active trackers of the project (and its sub projects) should be available
+* Fixed: locked users should not receive email notifications
+* Fixed: custom field selection is not saved when unchecking them all on project settings
+* Fixed: can not lock a topic when creating it
+* Fixed: Incorrect filtering for unset values when using 'is not' filter
+* Fixed: PostgreSQL issues_seq_id not updated when using Trac importer
+* Fixed: ajax pagination does not scroll up
+* Fixed: error when uploading a file with no content-type specified by the browser
+* Fixed: wiki and changeset links not displayed when previewing issue description or notes
+* Fixed: 'LdapError: no bind result' error when authenticating
+* Fixed: 'LdapError: invalid binding information' when no username/password are set on the LDAP account
+* Fixed: CVS repository doesn't work if port is used in the url
+* Fixed: Email notifications: host name is missing in generated links
+* Fixed: Email notifications: referenced changesets, wiki pages, attachments... are not turned into links
+* Fixed: Do not clear issue relations when moving an issue to another project if cross-project issue relations are allowed
+* Fixed: "undefined method 'textilizable'" error on email notification when running Repository#fetch_changesets from the console
+* Fixed: Do not send an email with no recipient, cc or bcc
+* Fixed: fetch_changesets fails on commit comments that close 2 duplicates issues.
+* Fixed: Mercurial browsing under unix-like os and for directory depth > 2
+* Fixed: Wiki links with pipe can not be used in wiki tables
+* Fixed: migrate_from_trac doesn't import timestamps of wiki and tickets
+* Fixed: when bulk editing, setting "Assigned to" to "nobody" causes an sql error with Postgresql
+
+
+== 2008-03-12 v0.6.4
+
+* Fixed: private projects name are displayed on account/show even if the current user doesn't have access to these private projects
+* Fixed: potential LDAP authentication security flaw
+* Fixed: context submenus on the issue list don't show up with IE6.
+* Fixed: Themes are not applied with Rails 2.0
+* Fixed: crash when fetching Mercurial changesets if changeset[:files] is nil
+* Fixed: Mercurial repository browsing
+* Fixed: undefined local variable or method 'log' in CvsAdapter when a cvs command fails
+* Fixed: not null constraints not removed with Postgresql
+* Doctype set to transitional
+
+
+== 2007-12-18 v0.6.3
+
+* Fixed: upload doesn't work in 'Files' section
+
+
+== 2007-12-16 v0.6.2
+
+* Search engine: issue custom fields can now be searched
+* News comments are now textilized
+* Updated Japanese translation (Satoru Kurashiki)
+* Updated Chinese translation (Shortie Lo)
+* Fixed Rails 2.0 compatibility bugs:
+  * Unable to create a wiki
+  * Gantt and calendar error
+  * Trac importer error (readonly? is defined by ActiveRecord)
+* Fixed: 'assigned to me' filter broken
+* Fixed: crash when validation fails on issue edition with no custom fields
+* Fixed: reposman "can't find group" error
+* Fixed: 'LDAP account password is too long' error when leaving the field empty on creation
+* Fixed: empty lines when displaying repository files with Windows style eol
+* Fixed: missing body closing tag in repository annotate and entry views
+
+
+== 2007-12-10 v0.6.1
+
+* Rails 2.0 compatibility
+* Custom fields can now be displayed as columns on the issue list
+* Added version details view (accessible from the roadmap)
+* Roadmap: more accurate completion percentage calculation (done ratio of open issues is now taken into account)
+* Added per-project tracker selection. Trackers can be selected on project settings
+* Anonymous users can now be allowed to create, edit, comment issues, comment news and post messages in the forums
+* Forums: messages can now be edited/deleted (explicit permissions need to be given)
+* Forums: topics can be locked so that no reply can be added
+* Forums: topics can be marked as sticky so that they always appear at the top of the list
+* Forums: attachments can now be added to replies
+* Added time zone support
+* Added a setting to choose the account activation strategy (available in application settings)
+* Added 'Classic' theme (inspired from the v0.51 design)
+* Added an alternate theme which provides issue list colorization based on issues priority
+* Added Bazaar SCM adapter
+* Added Annotate/Blame view in the repository browser (except for Darcs SCM)
+* Diff style (inline or side by side) automatically saved as a user preference
+* Added issues status changes on the activity view (by Cyril Mougel)
+* Added forums topics on the activity view (disabled by default)
+* Added an option on 'My account' for users who don't want to be notified of changes that they make
+* Trac importer now supports mysql and postgresql databases
+* Trac importer improvements (by Mat Trudel)
+* 'fixed version' field can now be displayed on the issue list
+* Added a couple of new formats for the 'date format' setting
+* Added Traditional Chinese translation (by Shortie Lo)
+* Added Russian translation (iGor kMeta)
+* Project name format limitation removed (name can now contain any character)
+* Project identifier maximum length changed from 12 to 20
+* Changed the maximum length of LDAP account to 255 characters
+* Removed the 12 characters limit on passwords
+* Added wiki macros support
+* Performance improvement on workflow setup screen
+* More detailed html title on several views
+* Custom fields can now be reordered
+* Search engine: search can be restricted to an exact phrase by using quotation marks
+* Added custom fields marked as 'For all projects' to the csv export of the cross project issue list
+* Email notifications are now sent as Blind carbon copy by default
+* Fixed: all members (including non active) should be deleted when deleting a project
+* Fixed: Error on wiki syntax link (accessible from wiki/edit)
+* Fixed: 'quick jump to a revision' form on the revisions list
+* Fixed: error on admin/info if there's more than 1 plugin installed
+* Fixed: svn or ldap password can be found in clear text in the html source in editing mode
+* Fixed: 'Assigned to' drop down list is not sorted
+* Fixed: 'View all issues' link doesn't work on issues/show
+* Fixed: error on account/register when validation fails
+* Fixed: Error when displaying the issue list if a float custom field is marked as 'used as filter'
+* Fixed: Mercurial adapter breaks on missing :files entry in changeset hash (James Britt)
+* Fixed: Wrong feed URLs on the home page
+* Fixed: Update of time entry fails when the issue has been moved to an other project
+* Fixed: Error when moving an issue without changing its tracker (Postgresql)
+* Fixed: Changes not recorded when using :pserver string (CVS adapter)
+* Fixed: admin should be able to move issues to any project
+* Fixed: adding an attachment is not possible when changing the status of an issue
+* Fixed: No mime-types in documents/files downloading
+* Fixed: error when sorting the messages if there's only one board for the project
+* Fixed: 'me' doesn't appear in the drop down filters on a project issue list.
+
+== 2007-11-04 v0.6.0
+
+* Permission model refactoring.
+* Permissions: there are now 2 builtin roles that can be used to specify permissions given to other users than members of projects
+* Permissions: some permissions (eg. browse the repository) can be removed for certain roles
+* Permissions: modules (eg. issue tracking, news, documents...) can be enabled/disabled at project level
+* Added Mantis and Trac importers
+* New application layout
+* Added "Bulk edit" functionality on the issue list
+* More flexible mail notifications settings at user level
+* Added AJAX based context menu on the project issue list that provide shortcuts for editing, re-assigning, changing the status or the priority, moving or deleting an issue
+* Added the hability to copy an issue. It can be done from the "issue/show" view or from the context menu on the issue list
+* Added the ability to customize issue list columns (at application level or for each saved query)
+* Overdue versions (date reached and open issues > 0) are now always displayed on the roadmap
+* Added the ability to rename wiki pages (specific permission required)
+* Search engines now supports pagination. Results are sorted in reverse chronological order
+* Added "Estimated hours" attribute on issues
+* A category with assigned issue can now be deleted. 2 options are proposed: remove assignments or reassign issues to another category
+* Forum notifications are now also sent to the authors of the thread, even if they donÃ¯Â¿Â½t watch the board
+* Added an application setting to specify the application protocol (http or https) used to generate urls in emails
+* Gantt chart: now starts at the current month by default
+* Gantt chart: month count and zoom factor are automatically saved as user preferences
+* Wiki links can now refer to other project wikis
+* Added wiki index by date
+* Added preview on add/edit issue form
+* Emails footer can now be customized from the admin interface (Admin -> Email notifications)
+* Default encodings for repository files can now be set in application settings (used to convert files content and diff to UTF-8 so that theyÃ¯Â¿Â½re properly displayed)
+* Calendar: first day of week can now be set in lang files
+* Automatic closing of duplicate issues
+* Added a cross-project issue list
+* AJAXified the SCM browser (tree view)
+* Pretty URL for the repository browser (Cyril Mougel)
+* Search engine: added a checkbox to search titles only
+* Added "% done" in the filter list
+* Enumerations: values can now be reordered and a default value can be specified (eg. default issue priority)
+* Added some accesskeys
+* Added "Float" as a custom field format
+* Added basic Theme support
+* Added the ability to set the Ã¯Â¿Â½done ratioÃ¯Â¿Â½ of issues fixed by commit (Nikolay Solakov)
+* Added custom fields in issue related mail notifications
+* Email notifications are now sent in plain text and html
+* Gantt chart can now be exported to a graphic file (png). This functionality is only available if RMagick is installed.
+* Added syntax highlightment for repository files and wiki
+* Improved automatic Redmine links
+* Added automatic table of content support on wiki pages
+* Added radio buttons on the documents list to sort documents by category, date, title or author
+* Added basic plugin support, with a sample plugin
+* Added a link to add a new category when creating or editing an issue
+* Added a "Assignable" boolean on the Role model. If unchecked, issues can not be assigned to users having this role.
+* Added an option to be able to relate issues in different projects
+* Added the ability to move issues (to another project) without changing their trackers.
+* Atom feeds added on project activity, news and changesets
+* Added the ability to reset its own RSS access key
+* Main project list now displays root projects with their subprojects
+* Added anchor links to issue notes
+* Added reposman Ruby version. This script can now register created repositories in Redmine (Nicolas Chuche)
+* Issue notes are now included in search
+* Added email sending test functionality
+* Added LDAPS support for LDAP authentication
+* Removed hard-coded URLs in mail templates
+* Subprojects are now grouped by projects in the navigation drop-down menu
+* Added a new value for date filters: this week
+* Added cache for application settings
+* Added Polish translation (Tomasz Gawryl)
+* Added Czech translation (Jan Kadlecek)
+* Added Romanian translation (Csongor Bartus)
+* Added Hebrew translation (Bob Builder)
+* Added Serbian translation (Dragan Matic)
+* Added Korean translation (Choi Jong Yoon)
+* Fixed: the link to delete issue relations is displayed even if the user is not authorized to delete relations
+* Performance improvement on calendar and gantt
+* Fixed: wiki preview doesnÃ¯Â¿Â½t work on long entries
+* Fixed: queries with multiple custom fields return no result
+* Fixed: Can not authenticate user against LDAP if its DN contains non-ascii characters
+* Fixed: URL with ~ broken in wiki formatting
+* Fixed: some quotation marks are rendered as strange characters in pdf
+
+
+== 2007-07-15 v0.5.1
+
+* per project forums added
+* added the ability to archive projects
+* added Ã¯Â¿Â½WatchÃ¯Â¿Â½ functionality on issues. It allows users to receive notifications about issue changes
+* custom fields for issues can now be used as filters on issue list
+* added per user custom queries
+* commit messages are now scanned for referenced or fixed issue IDs (keywords defined in Admin -> Settings)
+* projects list now shows the list of public projects and private projects for which the user is a member
+* versions can now be created with no date
+* added issue count details for versions on Reports view
+* added time report, by member/activity/tracker/version and year/month/week for the selected period
+* each category can now be associated to a user, so that new issues in that category are automatically assigned to that user
+* added autologin feature (disabled by default)
+* optimistic locking added for wiki edits
+* added wiki diff
+* added the ability to destroy wiki pages (requires permission)
+* a wiki page can now be attached to each version, and displayed on the roadmap
+* attachments can now be added to wiki pages (original patch by Pavol Murin) and displayed online
+* added an option to see all versions in the roadmap view (including completed ones)
+* added basic issue relations
+* added the ability to log time when changing an issue status
+* account information can now be sent to the user when creating an account
+* author and assignee of an issue always receive notifications (even if they turned of mail notifications)
+* added a quick search form in page header
+* added 'me' value for 'assigned to' and 'author' query filters
+* added a link on revision screen to see the entire diff for the revision
+* added last commit message for each entry in repository browser
+* added the ability to view a file diff with free to/from revision selection.
+* text files can now be viewed online when browsing the repository
+* added basic support for other SCM: CVS (Ralph Vater), Mercurial and Darcs
+* added fragment caching for svn diffs
+* added fragment caching for calendar and gantt views
+* login field automatically focused on login form
+* subproject name displayed on issue list, calendar and gantt
+* added an option to choose the date format: language based or ISO 8601
+* added a simple mail handler. It lets users add notes to an existing issue by replying to the initial notification email.
+* a 403 error page is now displayed (instead of a blank page) when trying to access a protected page
+* added portuguese translation (Joao Carlos Clementoni)
+* added partial online help japanese translation (Ken Date)
+* added bulgarian translation (Nikolay Solakov)
+* added dutch translation (Linda van den Brink)
+* added swedish translation (Thomas Habets)
+* italian translation update (Alessio Spadaro)
+* japanese translation update (Satoru Kurashiki)
+* fixed: error on history atom feed when thereÃ¯Â¿Â½s no notes on an issue change
+* fixed: error in journalizing an issue with longtext custom fields (Postgresql)
+* fixed: creation of Oracle schema
+* fixed: last day of the month not included in project activity
+* fixed: files with an apostrophe in their names can't be accessed in SVN repository
+* fixed: performance issue on RepositoriesController#revisions when a changeset has a great number of changes (eg. 100,000)
+* fixed: open/closed issue counts are always 0 on reports view (postgresql)
+* fixed: date query filters (wrong results and sql error with postgresql)
+* fixed: confidentiality issue on account/show (private project names displayed to anyone)
+* fixed: Long text custom fields displayed without line breaks
+* fixed: Error when editing the wokflow after deleting a status
+* fixed: SVN commit dates are now stored as local time
+
+
+== 2007-04-11 v0.5.0
+
+* added per project Wiki
+* added rss/atom feeds at project level (custom queries can be used as feeds)
+* added search engine (search in issues, news, commits, wiki pages, documents)
+* simple time tracking functionality added
+* added version due dates on calendar and gantt
+* added subprojects issue count on project Reports page
+* added the ability to copy an existing workflow when creating a new tracker
+* added the ability to include subprojects on calendar and gantt
+* added the ability to select trackers to display on calendar and gantt (Jeffrey Jones)
+* added side by side svn diff view (Cyril Mougel)
+* added back subproject filter on issue list
+* added permissions report in admin area
+* added a status filter on users list
+* support for password-protected SVN repositories
+* SVN commits are now stored in the database
+* added simple svn statistics SVG graphs
+* progress bars for roadmap versions (Nick Read)
+* issue history now shows file uploads and deletions
+* #id patterns are turned into links to issues in descriptions and commit messages
+* japanese translation added (Satoru Kurashiki)
+* chinese simplified translation added (Andy Wu)
+* italian translation added (Alessio Spadaro)
+* added scripts to manage SVN repositories creation and user access control using ssh+svn (Nicolas Chuche)
+* better calendar rendering time
+* fixed migration scripts to work with mysql 5 running in strict mode
+* fixed: error when clicking "add" with no block selected on my/page_layout
+* fixed: hard coded links in navigation bar
+* fixed: table_name pre/suffix support
+
+
+== 2007-02-18 v0.4.2
+
+* Rails 1.2 is now required
+* settings are now stored in the database and editable through the application in: Admin -> Settings (config_custom.rb is no longer used)
+* added project roadmap view
+* mail notifications added when a document, a file or an attachment is added
+* tooltips added on Gantt chart and calender to view the details of the issues
+* ability to set the sort order for roles, trackers, issue statuses
+* added missing fields to csv export: priority, start date, due date, done ratio
+* added total number of issues per tracker on project overview
+* all icons replaced (new icons are based on GPL icon set: "KDE Crystal Diamond 2.5" -by paolino- and "kNeu! Alpha v0.1" -by Pablo Fabregat-)
+* added back "fixed version" field on issue screen and in filters
+* project settings screen split in 4 tabs
+* custom fields screen split in 3 tabs (one for each kind of custom field)
+* multiple issues pdf export now rendered as a table
+* added a button on users/list to manually activate an account
+* added a setting option to disable "password lost" functionality
+* added a setting option to set max number of issues in csv/pdf exports
+* fixed: subprojects count is always 0 on projects list
+* fixed: locked users are proposed when adding a member to a project
+* fixed: setting an issue status as default status leads to an sql error with SQLite
+* fixed: unable to delete an issue status even if it's not used yet
+* fixed: filters ignored when exporting a predefined query to csv/pdf
+* fixed: crash when french "issue_edit" email notification is sent
+* fixed: hide mail preference not saved (my/account)
+* fixed: crash when a new user try to edit its "my page" layout
+
+
+== 2007-01-03 v0.4.1
+
+* fixed: emails have no recipient when one of the project members has notifications disabled
+
+
+== 2007-01-02 v0.4.0
+
+* simple SVN browser added (just needs svn binaries in PATH)
+* comments can now be added on news
+* "my page" is now customizable 
+* more powerfull and savable filters for issues lists
+* improved issues change history
+* new functionality: move an issue to another project or tracker
+* new functionality: add a note to an issue
+* new report: project activity
+* "start date" and "% done" fields added on issues
+* project calendar added
+* gantt chart added (exportable to pdf)
+* single/multiple issues pdf export added
+* issues reports improvements
+* multiple file upload for issues, documents and files
+* option to set maximum size of uploaded files
+* textile formating of issue and news descritions (RedCloth required)
+* integration of DotClear jstoolbar for textile formatting
+* calendar date picker for date fields (LGPL DHTML Calendar http://sourceforge.net/projects/jscalendar)
+* new filter in issues list: Author
+* ajaxified paginators
+* news rss feed added
+* option to set number of results per page on issues list
+* localized csv separator (comma/semicolon)
+* csv output encoded to ISO-8859-1
+* user custom field displayed on account/show
+* default configuration improved (default roles, trackers, status, permissions and workflows)
+* language for default configuration data can now be chosen when running 'load_default_data' task
+* javascript added on custom field form to show/hide fields according to the format of custom field
+* fixed: custom fields not in csv exports
+* fixed: project settings now displayed according to user's permissions
+* fixed: application error when no version is selected on projects/add_file
+* fixed: public actions not authorized for members of non public projects
+* fixed: non public projects were shown on welcome screen even if current user is not a member
+
+
+== 2006-10-08 v0.3.0
+
+* user authentication against multiple LDAP (optional)
+* token based "lost password" functionality
+* user self-registration functionality (optional)
+* custom fields now available for issues, users and projects
+* new custom field format "text" (displayed as a textarea field) 
+* project & administration drop down menus in navigation bar for quicker access
+* text formatting is preserved for long text fields (issues, projects and news descriptions)
+* urls and emails are turned into clickable links in long text fields
+* "due date" field added on issues
+* tracker selection filter added on change log
+* Localization plugin replaced with GLoc 1.1.0 (iconv required)
+* error messages internationalization
+* german translation added (thanks to Karim Trott)
+* data locking for issues to prevent update conflicts (using ActiveRecord builtin optimistic locking)
+* new filter in issues list: "Fixed version"
+* active filters are displayed with colored background on issues list
+* custom configuration is now defined in config/config_custom.rb
+* user object no more stored in session (only user_id)
+* news summary field is no longer required
+* tables and forms redesign
+* Fixed: boolean custom field not working
+* Fixed: error messages for custom fields are not displayed
+* Fixed: invalid custom fields should have a red border
+* Fixed: custom fields values are not validated on issue update
+* Fixed: unable to choose an empty value for 'List' custom fields
+* Fixed: no issue categories sorting
+* Fixed: incorrect versions sorting
+
+
+== 2006-07-12 - v0.2.2
+
+* Fixed: bug in "issues list"
+
+
+== 2006-07-09 - v0.2.1
+
+* new databases supported: Oracle, PostgreSQL, SQL Server
+* projects/subprojects hierarchy (1 level of subprojects only)
+* environment information display in admin/info
+* more filter options in issues list (rev6)
+* default language based on browser settings (Accept-Language HTTP header)
+* issues list exportable to CSV (rev6)
+* simple_format and auto_link on long text fields
+* more data validations
+* Fixed: error when all mail notifications are unchecked in admin/mail_options
+* Fixed: all project news are displayed on project summary
+* Fixed: Can't change user password in users/edit
+* Fixed: Error on tables creation with PostgreSQL (rev5)
+* Fixed: SQL error in "issue reports" view with PostgreSQL (rev5)
+
+
+== 2006-06-25 - v0.1.0
+
+* multiple users/multiple projects
+* role based access control
+* issue tracking system
+* fully customizable workflow
+* documents/files repository
+* email notifications on issue creation and update
+* multilanguage support (except for error messages):english, french, spanish
+* online manual in french (unfinished)
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/19/1933646523012d974bcce0affad6dacd2e7a9322.svn-base
--- a/.svn/pristine/19/1933646523012d974bcce0affad6dacd2e7a9322.svn-base
+++ /dev/null
@@ -1,182 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module DefaultData
-    class DataAlreadyLoaded < Exception; end
-
-    module Loader
-      include Redmine::I18n
-
-      class << self
-        # Returns true if no data is already loaded in the database
-        # otherwise false
-        def no_data?
-          !Role.find(:first, :conditions => {:builtin => 0}) &&
-            !Tracker.find(:first) &&
-            !IssueStatus.find(:first) &&
-            !Enumeration.find(:first)
-        end
-
-        # Loads the default data
-        # Raises a RecordNotSaved exception if something goes wrong
-        def load(lang=nil)
-          raise DataAlreadyLoaded.new("Some configuration data is already loaded.") unless no_data?
-          set_language_if_valid(lang)
-
-          Role.transaction do
-            # Roles
-            manager = Role.create! :name => l(:default_role_manager),
-                                   :issues_visibility => 'all',
-                                   :position => 1
-            manager.permissions = manager.setable_permissions.collect {|p| p.name}
-            manager.save!
-
-            developer = Role.create!  :name => l(:default_role_developer),
-                                      :position => 2,
-                                      :permissions => [:manage_versions,
-                                                      :manage_categories,
-                                                      :view_issues,
-                                                      :add_issues,
-                                                      :edit_issues,
-                                                      :manage_issue_relations,
-                                                      :manage_subtasks,
-                                                      :add_issue_notes,
-                                                      :save_queries,
-                                                      :view_gantt,
-                                                      :view_calendar,
-                                                      :log_time,
-                                                      :view_time_entries,
-                                                      :comment_news,
-                                                      :view_documents,
-                                                      :view_wiki_pages,
-                                                      :view_wiki_edits,
-                                                      :edit_wiki_pages,
-                                                      :delete_wiki_pages,
-                                                      :add_messages,
-                                                      :edit_own_messages,
-                                                      :view_files,
-                                                      :manage_files,
-                                                      :browse_repository,
-                                                      :view_changesets,
-                                                      :commit_access]
-
-            reporter = Role.create! :name => l(:default_role_reporter),
-                                    :position => 3,
-                                    :permissions => [:view_issues,
-                                                    :add_issues,
-                                                    :add_issue_notes,
-                                                    :save_queries,
-                                                    :view_gantt,
-                                                    :view_calendar,
-                                                    :log_time,
-                                                    :view_time_entries,
-                                                    :comment_news,
-                                                    :view_documents,
-                                                    :view_wiki_pages,
-                                                    :view_wiki_edits,
-                                                    :add_messages,
-                                                    :edit_own_messages,
-                                                    :view_files,
-                                                    :browse_repository,
-                                                    :view_changesets]
-
-            Role.non_member.update_attribute :permissions, [:view_issues,
-                                                            :add_issues,
-                                                            :add_issue_notes,
-                                                            :save_queries,
-                                                            :view_gantt,
-                                                            :view_calendar,
-                                                            :view_time_entries,
-                                                            :comment_news,
-                                                            :view_documents,
-                                                            :view_wiki_pages,
-                                                            :view_wiki_edits,
-                                                            :add_messages,
-                                                            :view_files,
-                                                            :browse_repository,
-                                                            :view_changesets]
-
-            Role.anonymous.update_attribute :permissions, [:view_issues,
-                                                           :view_gantt,
-                                                           :view_calendar,
-                                                           :view_time_entries,
-                                                           :view_documents,
-                                                           :view_wiki_pages,
-                                                           :view_wiki_edits,
-                                                           :view_files,
-                                                           :browse_repository,
-                                                           :view_changesets]
-
-            # Trackers
-            Tracker.create!(:name => l(:default_tracker_bug),     :is_in_chlog => true,  :is_in_roadmap => false, :position => 1)
-            Tracker.create!(:name => l(:default_tracker_feature), :is_in_chlog => true,  :is_in_roadmap => true,  :position => 2)
-            Tracker.create!(:name => l(:default_tracker_support), :is_in_chlog => false, :is_in_roadmap => false, :position => 3)
-
-            # Issue statuses
-            new       = IssueStatus.create!(:name => l(:default_issue_status_new), :is_closed => false, :is_default => true, :position => 1)
-            in_progress  = IssueStatus.create!(:name => l(:default_issue_status_in_progress), :is_closed => false, :is_default => false, :position => 2)
-            resolved  = IssueStatus.create!(:name => l(:default_issue_status_resolved), :is_closed => false, :is_default => false, :position => 3)
-            feedback  = IssueStatus.create!(:name => l(:default_issue_status_feedback), :is_closed => false, :is_default => false, :position => 4)
-            closed    = IssueStatus.create!(:name => l(:default_issue_status_closed), :is_closed => true, :is_default => false, :position => 5)
-            rejected  = IssueStatus.create!(:name => l(:default_issue_status_rejected), :is_closed => true, :is_default => false, :position => 6)
-
-            # Workflow
-            Tracker.find(:all).each { |t|
-              IssueStatus.find(:all).each { |os|
-                IssueStatus.find(:all).each { |ns|
-                  Workflow.create!(:tracker_id => t.id, :role_id => manager.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
-                }
-              }
-            }
-
-            Tracker.find(:all).each { |t|
-              [new, in_progress, resolved, feedback].each { |os|
-                [in_progress, resolved, feedback, closed].each { |ns|
-                  Workflow.create!(:tracker_id => t.id, :role_id => developer.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
-                }
-              }
-            }
-
-            Tracker.find(:all).each { |t|
-              [new, in_progress, resolved, feedback].each { |os|
-                [closed].each { |ns|
-                  Workflow.create!(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
-                }
-              }
-              Workflow.create!(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => resolved.id, :new_status_id => feedback.id)
-            }
-
-            # Enumerations
-            DocumentCategory.create!(:name => l(:default_doc_category_user), :position => 1)
-            DocumentCategory.create!(:name => l(:default_doc_category_tech), :position => 2)
-
-            IssuePriority.create!(:name => l(:default_priority_low), :position => 1)
-            IssuePriority.create!(:name => l(:default_priority_normal), :position => 2, :is_default => true)
-            IssuePriority.create!(:name => l(:default_priority_high), :position => 3)
-            IssuePriority.create!(:name => l(:default_priority_urgent), :position => 4)
-            IssuePriority.create!(:name => l(:default_priority_immediate), :position => 5)
-
-            TimeEntryActivity.create!(:name => l(:default_activity_design), :position => 1)
-            TimeEntryActivity.create!(:name => l(:default_activity_development), :position => 2)
-          end
-          true
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/19/19b6be5d688e189fd6e317c5eb9f45e401793fef.svn-base
--- a/.svn/pristine/19/19b6be5d688e189fd6e317c5eb9f45e401793fef.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-Fixtures are only copied from plugins with an +app+ directory, but git needs this directory to be non-empty
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1a57484f351c2899093aa4b926665fc8327667ab.svn-base
--- /dev/null
+++ b/.svn/pristine/1a/1a57484f351c2899093aa4b926665fc8327667ab.svn-base
@@ -0,0 +1,119 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class LayoutTest < ActionController::IntegrationTest
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  test "browsing to a missing page should render the base layout" do
+    get "/users/100000000"
+
+    assert_response :not_found
+
+    # UsersController uses the admin layout by default
+    assert_select "#admin-menu", :count => 0
+  end
+
+  test "browsing to an unauthorized page should render the base layout" do
+    change_user_password('miscuser9', 'test1234')
+
+    log_user('miscuser9','test1234')
+
+    get "/admin"
+    assert_response :forbidden
+    assert_select "#admin-menu", :count => 0
+  end
+
+  def test_top_menu_and_search_not_visible_when_login_required
+    with_settings :login_required => '1' do
+      get '/'
+      assert_select "#top-menu > ul", 0
+      assert_select "#quick-search", 0
+    end
+  end
+
+  def test_top_menu_and_search_visible_when_login_not_required
+    with_settings :login_required => '0' do
+      get '/'
+      assert_select "#top-menu > ul"
+      assert_select "#quick-search"
+    end
+  end
+
+  def test_wiki_formatter_header_tags
+    Role.anonymous.add_permission! :add_issues
+
+    get '/projects/ecookbook/issues/new'
+    assert_tag :script,
+      :attributes => {:src => %r{^/javascripts/jstoolbar/jstoolbar-textile.min.js}},
+      :parent => {:tag => 'head'}
+  end
+
+  def test_calendar_header_tags
+    with_settings :default_language => 'fr' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-fr.js", response.body
+    end
+
+    with_settings :default_language => 'en-GB' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-en-GB.js", response.body
+    end
+
+    with_settings :default_language => 'en' do
+      get '/issues'
+      assert_not_include "/javascripts/i18n/jquery.ui.datepicker", response.body
+    end
+
+    with_settings :default_language => 'zh' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-zh-CN.js", response.body
+    end
+
+    with_settings :default_language => 'zh-TW' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-zh-TW.js", response.body
+    end
+
+    with_settings :default_language => 'pt' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-pt.js", response.body
+    end
+
+    with_settings :default_language => 'pt-BR' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-pt-BR.js", response.body
+    end
+  end
+
+  def test_search_field_outside_project_should_link_to_global_search
+    get '/'
+    assert_select 'div#quick-search form[action=/search]'
+  end
+
+  def test_search_field_inside_project_should_link_to_project_search
+    get '/projects/ecookbook'
+    assert_select 'div#quick-search form[action=/projects/ecookbook/search]'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1a5ac9a1d7cbc1a58738649fabccca79dc7633e5.svn-base
--- /dev/null
+++ b/.svn/pristine/1a/1a5ac9a1d7cbc1a58738649fabccca79dc7633e5.svn-base
@@ -0,0 +1,33 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingWikisTest < ActionController::IntegrationTest
+  def test_wikis_plural_admin_setup
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/projects/ladida/wiki/destroy" },
+          { :controller => 'wikis', :action => 'destroy', :id => 'ladida' }
+        )
+    end
+    assert_routing(
+        { :method => 'post', :path => "/projects/ladida/wiki" },
+        { :controller => 'wikis', :action => 'edit', :id => 'ladida' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1a762326747d7b8c686840a8d5c0aaf794f1453e.svn-base
--- /dev/null
+++ b/.svn/pristine/1a/1a762326747d7b8c686840a8d5c0aaf794f1453e.svn-base
@@ -0,0 +1,47 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingCustomFieldsTest < ActionController::IntegrationTest
+  def test_custom_fields
+    assert_routing(
+        { :method => 'get', :path => "/custom_fields" },
+        { :controller => 'custom_fields', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/custom_fields/new" },
+        { :controller => 'custom_fields', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/custom_fields" },
+        { :controller => 'custom_fields', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/custom_fields/2/edit" },
+        { :controller => 'custom_fields', :action => 'edit', :id => '2' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/custom_fields/2" },
+        { :controller => 'custom_fields', :action => 'update', :id => '2' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/custom_fields/2" },
+        { :controller => 'custom_fields', :action => 'destroy', :id => '2' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1a82d923d734db1f664f7d362dd31d181914982f.svn-base
--- a/.svn/pristine/1a/1a82d923d734db1f664f7d362dd31d181914982f.svn-base
+++ /dev/null
@@ -1,26 +0,0 @@
-<div class="contextual">
-<%= link_to_remote l(:button_add),
-                   :url => {:controller => 'watchers',
-                            :action => 'new',
-                            :object_type => watched.class.name.underscore,
-                            :object_id => watched} if User.current.allowed_to?(:add_issue_watchers, @project) %>
-</div>
-
-<h3><%= l(:label_issue_watchers) %> (<%= watched.watcher_users.size %>)</h3>
-
-<% unless @watcher.nil? %>
-  <% remote_form_for(:watcher, @watcher,
-                     :url => {:controller => 'watchers',
-                              :action => 'new',
-                              :object_type => watched.class.name.underscore,
-                              :object_id => watched},
-                      :method => :post,
-                     :html => {:id => 'new-watcher-form'}) do |f| %>
-    <p><%= f.select :user_id, (watched.addable_watcher_users.collect {|m| [m.name, m.id]}), :prompt => "--- #{l(:actionview_instancetag_blank_option)} ---" %>
-
-    <%= submit_tag l(:button_add) %>
-    <%= toggle_link l(:button_cancel), 'new-watcher-form'%></p>
-  <% end %>
-<% end %>
-
-<%= watchers_list(watched) %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1a8a501f625f400265586ffe68a1c06c8affc4fc.svn-base
--- a/.svn/pristine/1a/1a8a501f625f400265586ffe68a1c06c8affc4fc.svn-base
+++ /dev/null
@@ -1,63 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../test_helper', __FILE__)
-
-class CalendarTest < ActiveSupport::TestCase
-
-  def test_monthly
-    c = Redmine::Helpers::Calendar.new(Date.today, :fr, :month)
-    assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday]
-
-    c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :month)
-    assert_equal ['2007-06-25'.to_date, '2007-08-05'.to_date], [c.startdt, c.enddt]
-
-    c = Redmine::Helpers::Calendar.new(Date.today, :en, :month)
-    assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday]
-  end
-
-  def test_weekly
-    c = Redmine::Helpers::Calendar.new(Date.today, :fr, :week)
-    assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday]
-
-    c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :week)
-    assert_equal ['2007-07-09'.to_date, '2007-07-15'.to_date], [c.startdt, c.enddt]
-
-    c = Redmine::Helpers::Calendar.new(Date.today, :en, :week)
-    assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday]
-  end
-
-  def test_monthly_start_day
-    [1, 6, 7].each do |day|
-      with_settings :start_of_week => day do
-        c = Redmine::Helpers::Calendar.new(Date.today, :en, :month)
-        assert_equal day , c.startdt.cwday
-        assert_equal (day + 5) % 7 + 1, c.enddt.cwday
-      end
-    end
-  end
-
-  def test_weekly_start_day
-    [1, 6, 7].each do |day|
-      with_settings :start_of_week => day do
-        c = Redmine::Helpers::Calendar.new(Date.today, :en, :week)
-        assert_equal day, c.startdt.cwday
-        assert_equal (day + 5) % 7 + 1, c.enddt.cwday
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1ab88c9db51ca0f94d552b61bcc13c4bd5d1f921.svn-base
--- /dev/null
+++ b/.svn/pristine/1a/1ab88c9db51ca0f94d552b61bcc13c4bd5d1f921.svn-base
@@ -0,0 +1,30 @@
+<% if @statuses.empty? or rows.empty? %>
+    <p><i><%=l(:label_no_data)%></i></p>
+<% else %>
+<% col_width = 70 / (@statuses.length+3) %>
+<table class="list">
+<thead><tr>
+<th style="width:25%"></th>
+<% for status in @statuses %>
+<th style="width:<%= col_width %>%"><%=h status.name %></th>
+<% end %>
+<th align="center" style="width:<%= col_width %>%"><strong><%=l(:label_open_issues_plural)%></strong></th>
+<th align="center" style="width:<%= col_width %>%"><strong><%=l(:label_closed_issues_plural)%></strong></th>
+<th align="center" style="width:<%= col_width %>%"><strong><%=l(:label_total)%></strong></th>
+</tr></thead>
+<tbody>
+<% for row in rows %>
+<tr class="<%= cycle("odd", "even") %>">
+  <td><%= link_to h(row.name), aggregate_path(@project, field_name, row) %></td>
+  <% for status in @statuses %>
+    <td align="center"><%= aggregate_link data, { field_name => row.id, "status_id" => status.id }, aggregate_path(@project, field_name, row, :status_id => status.id) %></td>
+  <% end %>
+  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o") %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c") %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*") %></td>
+</tr>
+<% end %>
+</tbody>
+</table>
+<% end
+  reset_cycle %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1ac4dbb6341375ce31f3dc814df9fd5800c3148d.svn-base
--- a/.svn/pristine/1a/1ac4dbb6341375ce31f3dc814df9fd5800c3148d.svn-base
+++ /dev/null
@@ -1,45 +0,0 @@
-# Mocks out OpenID
-#
-# http://www.northpub.com/articles/2007/04/02/testing-openid-support
-module OpenIdAuthentication
-
-  EXTENSION_FIELDS = {'email'    => 'user@somedomain.com',
-                      'nickname' => 'cool_user',
-                      'country'  => 'US',
-                      'postcode' => '12345',
-                      'fullname' => 'Cool User',
-                      'dob'      => '1970-04-01',
-                      'language' => 'en',
-                      'timezone' => 'America/New_York'}
-
-  protected
-
-    def authenticate_with_open_id(identity_url = params[:openid_url], options = {}) #:doc:
-      if User.find_by_identity_url(identity_url) || identity_url.include?('good')
-        # Don't process registration fields unless it is requested.
-        unless identity_url.include?('blank') || (options[:required].nil? && options[:optional].nil?)
-          extension_response_fields = {}
-
-          options[:required].each do |field|
-            extension_response_fields[field.to_s] = EXTENSION_FIELDS[field.to_s]
-          end unless options[:required].nil?
-
-          options[:optional].each do |field|
-            extension_response_fields[field.to_s] = EXTENSION_FIELDS[field.to_s]
-          end unless options[:optional].nil?
-        end
-
-        yield Result[:successful], identity_url , extension_response_fields
-      else
-        logger.info "OpenID authentication failed: #{identity_url}"
-        yield Result[:failed], identity_url, nil
-      end
-    end
-
-  private
-
-    def add_simple_registration_fields(open_id_response, fields)
-      open_id_response.add_extension_arg('sreg', 'required', [ fields[:required] ].flatten * ',') if fields[:required]
-      open_id_response.add_extension_arg('sreg', 'optional', [ fields[:optional] ].flatten * ',') if fields[:optional]
-    end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1ad12962c58a76f3a2222abf367e284e64a3d8e1.svn-base
--- /dev/null
+++ b/.svn/pristine/1a/1ad12962c58a76f3a2222abf367e284e64a3d8e1.svn-base
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8" />
+<title><%=h html_title %></title>
+<meta name="description" content="<%= Redmine::Info.app_name %>" />
+<meta name="keywords" content="issue,bug,tracker" />
+<%= csrf_meta_tag %>
+<%= favicon %>
+<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', :media => 'all' %>
+<%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
+<%= javascript_heads %>
+<%= heads_for_theme %>
+<%= call_hook :view_layouts_base_html_head %>
+<!-- page specific tags -->
+<%= yield :header_tags -%>
+</head>
+<body class="<%=h body_css_classes %>">
+<div id="wrapper">
+<div id="wrapper2">
+<div id="wrapper3">
+<div id="top-menu">
+    <div id="account">
+        <%= render_menu :account_menu -%>
+    </div>
+    <%= content_tag('div', "#{l(:label_logged_as)} #{link_to_user(User.current, :format => :username)}".html_safe, :id => 'loggedas') if User.current.logged? %>
+    <%= render_menu :top_menu if User.current.logged? || !Setting.login_required? -%>
+</div>
+
+<div id="header">
+    <% if User.current.logged? || !Setting.login_required? %>
+    <div id="quick-search">
+        <%= form_tag({:controller => 'search', :action => 'index', :id => @project}, :method => :get ) do %>
+        <%= hidden_field_tag(controller.default_search_scope, 1, :id => nil) if controller.default_search_scope %>
+        <label for='q'>
+          <%= link_to l(:label_search), {:controller => 'search', :action => 'index', :id => @project}, :accesskey => accesskey(:search) %>:
+        </label>
+        <%= text_field_tag 'q', @question, :size => 20, :class => 'small', :accesskey => accesskey(:quick_search) %>
+        <% end %>
+        <%= render_project_jump_box %>
+    </div>
+    <% end %>
+
+    <h1><%= page_header_title %></h1>
+
+    <% if display_main_menu?(@project) %>
+    <div id="main-menu">
+        <%= render_main_menu(@project) %>
+    </div>
+    <% end %>
+</div>
+
+<div id="main" class="<%= sidebar_content? ? '' : 'nosidebar' %>">
+    <div id="sidebar">
+        <%= yield :sidebar %>
+        <%= view_layouts_base_sidebar_hook_response %>
+    </div>
+
+    <div id="content">
+        <%= render_flash_messages %>
+        <%= yield %>
+        <%= call_hook :view_layouts_base_content %>
+        <div style="clear:both;"></div>
+    </div>
+</div>
+</div>
+
+<div id="ajax-indicator" style="display:none;"><span><%= l(:label_loading) %></span></div>
+<div id="ajax-modal" style="display:none;"></div>
+
+<div id="footer">
+  <div class="bgl"><div class="bgr">
+    Powered by <%= link_to Redmine::Info.app_name, Redmine::Info.url %> &copy; 2006-2013 Jean-Philippe Lang
+  </div></div>
+</div>
+</div>
+</div>
+<%= call_hook :view_layouts_base_body_bottom %>
+</body>
+</html>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1ae20ea87464b5769eed93f455558d2b0e19460e.svn-base
--- /dev/null
+++ b/.svn/pristine/1a/1ae20ea87464b5769eed93f455558d2b0e19460e.svn-base
@@ -0,0 +1,24 @@
+class AddUniqueIndexOnCustomFieldsProjects < ActiveRecord::Migration
+  def up
+    table_name = "#{CustomField.table_name_prefix}custom_fields_projects#{CustomField.table_name_suffix}"
+    duplicates = CustomField.connection.select_rows("SELECT custom_field_id, project_id FROM #{table_name} GROUP BY custom_field_id, project_id HAVING COUNT(*) > 1")
+    duplicates.each do |custom_field_id, project_id|
+      # Removes duplicate rows
+      CustomField.connection.execute("DELETE FROM #{table_name} WHERE custom_field_id=#{custom_field_id} AND project_id=#{project_id}")
+      # And insert one
+      CustomField.connection.execute("INSERT INTO #{table_name} (custom_field_id, project_id) VALUES (#{custom_field_id}, #{project_id})")
+    end
+
+    if index_exists? :custom_fields_projects, [:custom_field_id, :project_id]
+      remove_index :custom_fields_projects, [:custom_field_id, :project_id]
+    end
+    add_index :custom_fields_projects, [:custom_field_id, :project_id], :unique => true
+  end
+
+  def down
+    if index_exists? :custom_fields_projects, [:custom_field_id, :project_id]
+      remove_index :custom_fields_projects, [:custom_field_id, :project_id]
+    end
+    add_index :custom_fields_projects, [:custom_field_id, :project_id]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1a/1ae3258fdcdf6aa143d4aa4fdfd79484152c6554.svn-base
--- /dev/null
+++ b/.svn/pristine/1a/1ae3258fdcdf6aa143d4aa4fdfd79484152c6554.svn-base
@@ -0,0 +1,35 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module MembersHelper
+  def render_principals_for_new_members(project)
+    scope = Principal.active.sorted.not_member_of(project).like(params[:q])
+    principal_count = scope.count
+    principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
+    principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
+
+    s = content_tag('div', principals_check_box_tags('membership[user_ids][]', principals), :id => 'principals')
+
+    links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
+      link_to text, autocomplete_project_memberships_path(project, parameters.merge(:q => params[:q], :format => 'js')), :remote => true
+    }
+
+    s + content_tag('p', links, :class => 'pagination')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1b/1b0ed23201303f160d7d4495d1661d066db9d987.svn-base
--- a/.svn/pristine/1b/1b0ed23201303f160d7d4495d1661d066db9d987.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-<form id="status_by_form">
-<fieldset>
-<legend>
-<%= l(:label_issues_by,
-       select_tag('status_by',
-                   status_by_options_for_select(criteria),
-                   :id => 'status_by_select',
-                   :onchange => remote_function(:url => status_by_version_path(version),
-                                                :with => "Form.serialize('status_by_form')"))) %>
-</legend>
-<% if counts.empty? %>
-    <p><em><%= l(:label_no_data) %></em></p>
-<% else %>
-    <table>
-    <% counts.each do |count| %>
-    <tr>
-        <td width="130px" align="right" >
-            <%= link_to h(count[:group]), {:controller => 'issues',
-                                        :action => 'index',
-                                        :project_id => version.project,
-                                        :set_filter => 1,
-                                        :status_id => '*',
-                                        :fixed_version_id => version}.merge("#{criteria}_id".to_sym => count[:group]) %>
-        </td>
-        <td width="240px">
-            <%= progress_bar((count[:closed].to_f / count[:total])*100,
-                  :legend => "#{count[:closed]}/#{count[:total]}",
-                  :width => "#{(count[:total].to_f / max * 200).floor}px;") %>
-        </td>
-    </tr>
-    <% end %>
-    </table>
-<% end %>
-</fieldset>
-</form>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1b/1b578055102e356a87f5f77cb58bb01b760471f9.svn-base
--- a/.svn/pristine/1b/1b578055102e356a87f5f77cb58bb01b760471f9.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-plain template
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1b/1bf322e40d14051308bb92bbfb41fdba8ea03c74.svn-base
--- a/.svn/pristine/1b/1bf322e40d14051308bb92bbfb41fdba8ea03c74.svn-base
+++ /dev/null
@@ -1,21 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module BoardsHelper
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1c/1c133f685ba1e7aa677a1a8d5d646e268fcc08fc.svn-base
--- a/.svn/pristine/1c/1c133f685ba1e7aa677a1a8d5d646e268fcc08fc.svn-base
+++ /dev/null
@@ -1,206 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-begin
-  require 'mocha'
-rescue
-  # Won't run some tests
-end
-
-class AccountTest < ActionController::IntegrationTest
-  fixtures :users, :roles
-
-  # Replace this with your real tests.
-  def test_login
-    get "my/page"
-    assert_redirected_to "/login?back_url=http%3A%2F%2Fwww.example.com%2Fmy%2Fpage"
-    log_user('jsmith', 'jsmith')
-
-    get "my/account"
-    assert_response :success
-    assert_template "my/account"
-  end
-
-  def test_autologin
-    user = User.find(1)
-    Setting.autologin = "7"
-    Token.delete_all
-
-    # User logs in with 'autologin' checked
-    post '/login', :username => user.login, :password => 'admin', :autologin => 1
-    assert_redirected_to '/my/page'
-    token = Token.find :first
-    assert_not_nil token
-    assert_equal user, token.user
-    assert_equal 'autologin', token.action
-    assert_equal user.id, session[:user_id]
-    assert_equal token.value, cookies['autologin']
-
-    # Session is cleared
-    reset!
-    User.current = nil
-    # Clears user's last login timestamp
-    user.update_attribute :last_login_on, nil
-    assert_nil user.reload.last_login_on
-
-    # User comes back with his autologin cookie
-    cookies[:autologin] = token.value
-    get '/my/page'
-    assert_response :success
-    assert_template 'my/page'
-    assert_equal user.id, session[:user_id]
-    assert_not_nil user.reload.last_login_on
-    assert user.last_login_on.utc > 10.second.ago.utc
-  end
-
-  def test_lost_password
-    Token.delete_all
-
-    get "account/lost_password"
-    assert_response :success
-    assert_template "account/lost_password"
-
-    post "account/lost_password", :mail => 'jSmith@somenet.foo'
-    assert_redirected_to "/login"
-
-    token = Token.find(:first)
-    assert_equal 'recovery', token.action
-    assert_equal 'jsmith@somenet.foo', token.user.mail
-    assert !token.expired?
-
-    get "account/lost_password", :token => token.value
-    assert_response :success
-    assert_template "account/password_recovery"
-
-    post "account/lost_password", :token => token.value, :new_password => 'newpass', :new_password_confirmation => 'newpass'
-    assert_redirected_to "/login"
-    assert_equal 'Password was successfully updated.', flash[:notice]
-
-    log_user('jsmith', 'newpass')
-    assert_equal 0, Token.count
-  end
-
-  def test_register_with_automatic_activation
-    Setting.self_registration = '3'
-
-    get 'account/register'
-    assert_response :success
-    assert_template 'account/register'
-
-    post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar"},
-                             :password => "newpass", :password_confirmation => "newpass"
-    assert_redirected_to '/my/account'
-    follow_redirect!
-    assert_response :success
-    assert_template 'my/account'
-
-    user = User.find_by_login('newuser')
-    assert_not_nil user
-    assert user.active?
-    assert_not_nil user.last_login_on
-  end
-
-  def test_register_with_manual_activation
-    Setting.self_registration = '2'
-
-    post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar"},
-                             :password => "newpass", :password_confirmation => "newpass"
-    assert_redirected_to '/login'
-    assert !User.find_by_login('newuser').active?
-  end
-
-  def test_register_with_email_activation
-    Setting.self_registration = '1'
-    Token.delete_all
-
-    post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar"},
-                             :password => "newpass", :password_confirmation => "newpass"
-    assert_redirected_to '/login'
-    assert !User.find_by_login('newuser').active?
-
-    token = Token.find(:first)
-    assert_equal 'register', token.action
-    assert_equal 'newuser@foo.bar', token.user.mail
-    assert !token.expired?
-
-    get 'account/activate', :token => token.value
-    assert_redirected_to '/login'
-    log_user('newuser', 'newpass')
-  end
-
-  if Object.const_defined?(:Mocha)
-
-  def test_onthefly_registration
-    # disable registration
-    Setting.self_registration = '0'
-    AuthSource.expects(:authenticate).returns({:login => 'foo', :firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com', :auth_source_id => 66})
-
-    post 'account/login', :username => 'foo', :password => 'bar'
-    assert_redirected_to '/my/page'
-
-    user = User.find_by_login('foo')
-    assert user.is_a?(User)
-    assert_equal 66, user.auth_source_id
-    assert user.hashed_password.blank?
-  end
-
-  def test_onthefly_registration_with_invalid_attributes
-    # disable registration
-    Setting.self_registration = '0'
-    AuthSource.expects(:authenticate).returns({:login => 'foo', :lastname => 'Smith', :auth_source_id => 66})
-
-    post 'account/login', :username => 'foo', :password => 'bar'
-    assert_response :success
-    assert_template 'account/register'
-    assert_tag :input, :attributes => { :name => 'user[firstname]', :value => '' }
-    assert_tag :input, :attributes => { :name => 'user[lastname]', :value => 'Smith' }
-    assert_no_tag :input, :attributes => { :name => 'user[login]' }
-    assert_no_tag :input, :attributes => { :name => 'user[password]' }
-
-    post 'account/register', :user => {:firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com'}
-    assert_redirected_to '/my/account'
-
-    user = User.find_by_login('foo')
-    assert user.is_a?(User)
-    assert_equal 66, user.auth_source_id
-    assert user.hashed_password.blank?
-  end
-
-  def test_login_and_logout_should_clear_session
-    get '/login'
-    sid = session[:session_id]
-
-    post '/login', :username => 'admin', :password => 'admin'
-    assert_redirected_to '/my/page'
-    assert_not_equal sid, session[:session_id], "login should reset session"
-    assert_equal 1, session[:user_id]
-    sid = session[:session_id]
-
-    get '/'
-    assert_equal sid, session[:session_id]
-
-    get '/logout'
-    assert_not_equal sid, session[:session_id], "logout should reset session"
-    assert_nil session[:user_id]
-  end
-
-  else
-    puts 'Mocha is missing. Skipping tests.'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1c/1c27182fa8ab48906fb7a4d556796242f651644e.svn-base
--- /dev/null
+++ b/.svn/pristine/1c/1c27182fa8ab48906fb7a4d556796242f651644e.svn-base
@@ -0,0 +1,244 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Pagination
+    class Paginator
+      attr_reader :item_count, :per_page, :page, :page_param
+
+      def initialize(*args)
+        if args.first.is_a?(ActionController::Base)
+          args.shift
+          ActiveSupport::Deprecation.warn "Paginator no longer takes a controller instance as the first argument. Remove it from #new arguments."
+        end
+        item_count, per_page, page, page_param = *args
+
+        @item_count = item_count
+        @per_page = per_page
+        page = (page || 1).to_i
+        if page < 1
+          page = 1
+        end
+        @page = page
+        @page_param = page_param || :page
+      end
+
+      def offset
+        (page - 1) * per_page
+      end
+
+      def first_page
+        if item_count > 0
+          1
+        end
+      end
+
+      def previous_page
+        if page > 1
+          page - 1
+        end
+      end
+
+      def next_page
+        if last_item < item_count
+          page + 1
+        end
+      end
+
+      def last_page
+        if item_count > 0
+          (item_count - 1) / per_page + 1
+        end
+      end
+
+      def first_item
+        item_count == 0 ? 0 : (offset + 1)
+      end
+
+      def last_item
+        l = first_item + per_page - 1
+        l > item_count ? item_count : l
+      end
+
+      def linked_pages
+        pages = []
+        if item_count > 0
+          pages += [first_page, page, last_page]
+          pages += ((page-2)..(page+2)).to_a.select {|p| p > first_page && p < last_page}
+        end
+        pages = pages.compact.uniq.sort
+        if pages.size > 1
+          pages
+        else
+          []
+        end
+      end
+
+      def items_per_page
+        ActiveSupport::Deprecation.warn "Paginator#items_per_page will be removed. Use #per_page instead."
+        per_page
+      end
+
+      def current
+        ActiveSupport::Deprecation.warn "Paginator#current will be removed. Use .offset instead of .current.offset."
+        self
+      end
+    end
+
+    # Paginates the given scope or model. Returns a Paginator instance and
+    # the collection of objects for the current page.
+    #
+    # Options:
+    #   :parameter     name of the page parameter
+    #
+    # Examples:
+    #   @user_pages, @users = paginate User.where(:status => 1)
+    #
+    def paginate(scope, options={})
+      options = options.dup
+      finder_options = options.extract!(
+        :conditions,
+        :order,
+        :joins,
+        :include,
+        :select
+      )
+      if scope.is_a?(Symbol) || finder_options.values.compact.any?
+        return deprecated_paginate(scope, finder_options, options)
+      end
+
+      paginator = paginator(scope.count, options)
+      collection = scope.limit(paginator.per_page).offset(paginator.offset).to_a
+
+      return paginator, collection
+    end
+
+    def deprecated_paginate(arg, finder_options, options={})
+      ActiveSupport::Deprecation.warn "#paginate with a Symbol and/or find options is depreceted and will be removed. Use a scope instead."
+      klass = arg.is_a?(Symbol) ? arg.to_s.classify.constantize : arg
+      scope = klass.scoped(finder_options)
+      paginate(scope, options)
+    end
+
+    def paginator(item_count, options={})
+      options.assert_valid_keys :parameter, :per_page
+
+      page_param = options[:parameter] || :page
+      page = (params[page_param] || 1).to_i
+      per_page = options[:per_page] || per_page_option
+      Paginator.new(item_count, per_page, page, page_param)
+    end
+
+    module Helper
+      include Redmine::I18n
+
+      # Renders the pagination links for the given paginator.
+      #
+      # Options:
+      #   :per_page_links    if set to false, the "Per page" links are not rendered
+      #
+      def pagination_links_full(*args)
+        pagination_links_each(*args) do |text, parameters, options|
+          if block_given?
+            yield text, parameters, options
+          else
+            link_to text, params.merge(parameters), options
+          end
+        end
+      end
+
+      # Yields the given block with the text and parameters
+      # for each pagination link and returns a string that represents the links
+      def pagination_links_each(paginator, count=nil, options={}, &block)
+        options.assert_valid_keys :per_page_links
+
+        per_page_links = options.delete(:per_page_links)
+        per_page_links = false if count.nil?
+        page_param = paginator.page_param
+
+        html = ''
+        if paginator.previous_page
+          # \xc2\xab(utf-8) = &#171;
+          text = "\xc2\xab " + l(:label_previous)
+          html << yield(text, {page_param => paginator.previous_page}, :class => 'previous') + ' '
+        end
+
+        previous = nil
+        paginator.linked_pages.each do |page|
+          if previous && previous != page - 1
+            html << content_tag('span', '...', :class => 'spacer') + ' '
+          end
+          if page == paginator.page
+            html << content_tag('span', page.to_s, :class => 'current page')
+          else
+            html << yield(page.to_s, {page_param => page}, :class => 'page')
+          end
+          html << ' '
+          previous = page
+        end
+
+        if paginator.next_page
+          # \xc2\xbb(utf-8) = &#187;
+          text = l(:label_next) + " \xc2\xbb"
+          html << yield(text, {page_param => paginator.next_page}, :class => 'next') + ' '
+        end
+
+        html << content_tag('span', "(#{paginator.first_item}-#{paginator.last_item}/#{paginator.item_count})", :class => 'items') + ' '
+
+        if per_page_links != false && links = per_page_links(paginator, &block)
+          html << content_tag('span', links.to_s, :class => 'per-page')
+        end
+
+        html.html_safe
+      end
+
+      # Renders the "Per page" links.
+      def per_page_links(paginator, &block)
+        values = per_page_options(paginator.per_page, paginator.item_count)
+        if values.any?
+          links = values.collect do |n|
+            if n == paginator.per_page
+              content_tag('span', n.to_s)
+            else
+              yield(n, :per_page => n, paginator.page_param => nil)
+            end
+          end
+          l(:label_display_per_page, links.join(', ')).html_safe
+        end
+      end
+
+      def per_page_options(selected=nil, item_count=nil)
+        options = Setting.per_page_options_array
+        if item_count && options.any?
+          if item_count > options.first
+            max = options.detect {|value| value >= item_count} || item_count
+          else
+            max = item_count
+          end
+          options = options.select {|value| value <= max || value == selected}
+        end
+        if options.empty? || (options.size == 1 && options.first == selected)
+          []
+        else
+          options
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1c/1c5257cafbf7d7508949bf6ef73182b08b1fa87d.svn-base
--- a/.svn/pristine/1c/1c5257cafbf7d7508949bf6ef73182b08b1fa87d.svn-base
+++ /dev/null
@@ -1,1585 +0,0 @@
-#
-# setup.rb
-#
-# Copyright (c) 2000-2005 Minero Aoki
-#
-# This program is free software.
-# You can distribute/modify this program under the terms of
-# the GNU LGPL, Lesser General Public License version 2.1.
-#
-
-unless Enumerable.method_defined?(:map)   # Ruby 1.4.6
-  module Enumerable
-    alias map collect
-  end
-end
-
-unless File.respond_to?(:read)   # Ruby 1.6
-  def File.read(fname)
-    open(fname) {|f|
-      return f.read
-    }
-  end
-end
-
-unless Errno.const_defined?(:ENOTEMPTY)   # Windows?
-  module Errno
-    class ENOTEMPTY
-      # We do not raise this exception, implementation is not needed.
-    end
-  end
-end
-
-def File.binread(fname)
-  open(fname, 'rb') {|f|
-    return f.read
-  }
-end
-
-# for corrupted Windows' stat(2)
-def File.dir?(path)
-  File.directory?((path[-1,1] == '/') ? path : path + '/')
-end
-
-
-class ConfigTable
-
-  include Enumerable
-
-  def initialize(rbconfig)
-    @rbconfig = rbconfig
-    @items = []
-    @table = {}
-    # options
-    @install_prefix = nil
-    @config_opt = nil
-    @verbose = true
-    @no_harm = false
-  end
-
-  attr_accessor :install_prefix
-  attr_accessor :config_opt
-
-  attr_writer :verbose
-
-  def verbose?
-    @verbose
-  end
-
-  attr_writer :no_harm
-
-  def no_harm?
-    @no_harm
-  end
-
-  def [](key)
-    lookup(key).resolve(self)
-  end
-
-  def []=(key, val)
-    lookup(key).set val
-  end
-
-  def names
-    @items.map {|i| i.name }
-  end
-
-  def each(&block)
-    @items.each(&block)
-  end
-
-  def key?(name)
-    @table.key?(name)
-  end
-
-  def lookup(name)
-    @table[name] or setup_rb_error "no such config item: #{name}"
-  end
-
-  def add(item)
-    @items.push item
-    @table[item.name] = item
-  end
-
-  def remove(name)
-    item = lookup(name)
-    @items.delete_if {|i| i.name == name }
-    @table.delete_if {|name, i| i.name == name }
-    item
-  end
-
-  def load_script(path, inst = nil)
-    if File.file?(path)
-      MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
-    end
-  end
-
-  def savefile
-    '.config'
-  end
-
-  def load_savefile
-    begin
-      File.foreach(savefile()) do |line|
-        k, v = *line.split(/=/, 2)
-        self[k] = v.strip
-      end
-    rescue Errno::ENOENT
-      setup_rb_error $!.message + "\n#{File.basename($0)} config first"
-    end
-  end
-
-  def save
-    @items.each {|i| i.value }
-    File.open(savefile(), 'w') {|f|
-      @items.each do |i|
-        f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
-      end
-    }
-  end
-
-  def load_standard_entries
-    standard_entries(@rbconfig).each do |ent|
-      add ent
-    end
-  end
-
-  def standard_entries(rbconfig)
-    c = rbconfig
-
-    rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
-
-    major = c['MAJOR'].to_i
-    minor = c['MINOR'].to_i
-    teeny = c['TEENY'].to_i
-    version = "#{major}.#{minor}"
-
-    # ruby ver. >= 1.4.4?
-    newpath_p = ((major >= 2) or
-                 ((major == 1) and
-                  ((minor >= 5) or
-                   ((minor == 4) and (teeny >= 4)))))
-
-    if c['rubylibdir']
-      # V > 1.6.3
-      libruby         = "#{c['prefix']}/lib/ruby"
-      librubyver      = c['rubylibdir']
-      librubyverarch  = c['archdir']
-      siteruby        = c['sitedir']
-      siterubyver     = c['sitelibdir']
-      siterubyverarch = c['sitearchdir']
-    elsif newpath_p
-      # 1.4.4 <= V <= 1.6.3
-      libruby         = "#{c['prefix']}/lib/ruby"
-      librubyver      = "#{c['prefix']}/lib/ruby/#{version}"
-      librubyverarch  = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
-      siteruby        = c['sitedir']
-      siterubyver     = "$siteruby/#{version}"
-      siterubyverarch = "$siterubyver/#{c['arch']}"
-    else
-      # V < 1.4.4
-      libruby         = "#{c['prefix']}/lib/ruby"
-      librubyver      = "#{c['prefix']}/lib/ruby/#{version}"
-      librubyverarch  = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
-      siteruby        = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
-      siterubyver     = siteruby
-      siterubyverarch = "$siterubyver/#{c['arch']}"
-    end
-    parameterize = lambda {|path|
-      path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
-    }
-
-    if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
-      makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
-    else
-      makeprog = 'make'
-    end
-
-    [
-      ExecItem.new('installdirs', 'std/site/home',
-                   'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
-          {|val, table|
-            case val
-            when 'std'
-              table['rbdir'] = '$librubyver'
-              table['sodir'] = '$librubyverarch'
-            when 'site'
-              table['rbdir'] = '$siterubyver'
-              table['sodir'] = '$siterubyverarch'
-            when 'home'
-              setup_rb_error '$HOME was not set' unless ENV['HOME']
-              table['prefix'] = ENV['HOME']
-              table['rbdir'] = '$libdir/ruby'
-              table['sodir'] = '$libdir/ruby'
-            end
-          },
-      PathItem.new('prefix', 'path', c['prefix'],
-                   'path prefix of target environment'),
-      PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
-                   'the directory for commands'),
-      PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
-                   'the directory for libraries'),
-      PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
-                   'the directory for shared data'),
-      PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
-                   'the directory for man pages'),
-      PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
-                   'the directory for system configuration files'),
-      PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
-                   'the directory for local state data'),
-      PathItem.new('libruby', 'path', libruby,
-                   'the directory for ruby libraries'),
-      PathItem.new('librubyver', 'path', librubyver,
-                   'the directory for standard ruby libraries'),
-      PathItem.new('librubyverarch', 'path', librubyverarch,
-                   'the directory for standard ruby extensions'),
-      PathItem.new('siteruby', 'path', siteruby,
-          'the directory for version-independent aux ruby libraries'),
-      PathItem.new('siterubyver', 'path', siterubyver,
-                   'the directory for aux ruby libraries'),
-      PathItem.new('siterubyverarch', 'path', siterubyverarch,
-                   'the directory for aux ruby binaries'),
-      PathItem.new('rbdir', 'path', '$siterubyver',
-                   'the directory for ruby scripts'),
-      PathItem.new('sodir', 'path', '$siterubyverarch',
-                   'the directory for ruby extentions'),
-      PathItem.new('rubypath', 'path', rubypath,
-                   'the path to set to #! line'),
-      ProgramItem.new('rubyprog', 'name', rubypath,
-                      'the ruby program using for installation'),
-      ProgramItem.new('makeprog', 'name', makeprog,
-                      'the make program to compile ruby extentions'),
-      SelectItem.new('shebang', 'all/ruby/never', 'ruby',
-                     'shebang line (#!) editing mode'),
-      BoolItem.new('without-ext', 'yes/no', 'no',
-                   'does not compile/install ruby extentions')
-    ]
-  end
-  private :standard_entries
-
-  def load_multipackage_entries
-    multipackage_entries().each do |ent|
-      add ent
-    end
-  end
-
-  def multipackage_entries
-    [
-      PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
-                               'package names that you want to install'),
-      PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
-                               'package names that you do not want to install')
-    ]
-  end
-  private :multipackage_entries
-
-  ALIASES = {
-    'std-ruby'         => 'librubyver',
-    'stdruby'          => 'librubyver',
-    'rubylibdir'       => 'librubyver',
-    'archdir'          => 'librubyverarch',
-    'site-ruby-common' => 'siteruby',     # For backward compatibility
-    'site-ruby'        => 'siterubyver',  # For backward compatibility
-    'bin-dir'          => 'bindir',
-    'bin-dir'          => 'bindir',
-    'rb-dir'           => 'rbdir',
-    'so-dir'           => 'sodir',
-    'data-dir'         => 'datadir',
-    'ruby-path'        => 'rubypath',
-    'ruby-prog'        => 'rubyprog',
-    'ruby'             => 'rubyprog',
-    'make-prog'        => 'makeprog',
-    'make'             => 'makeprog'
-  }
-
-  def fixup
-    ALIASES.each do |ali, name|
-      @table[ali] = @table[name]
-    end
-    @items.freeze
-    @table.freeze
-    @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
-  end
-
-  def parse_opt(opt)
-    m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
-    m.to_a[1,2]
-  end
-
-  def dllext
-    @rbconfig['DLEXT']
-  end
-
-  def value_config?(name)
-    lookup(name).value?
-  end
-
-  class Item
-    def initialize(name, template, default, desc)
-      @name = name.freeze
-      @template = template
-      @value = default
-      @default = default
-      @description = desc
-    end
-
-    attr_reader :name
-    attr_reader :description
-
-    attr_accessor :default
-    alias help_default default
-
-    def help_opt
-      "--#{@name}=#{@template}"
-    end
-
-    def value?
-      true
-    end
-
-    def value
-      @value
-    end
-
-    def resolve(table)
-      @value.gsub(%r<\$([^/]+)>) { table[$1] }
-    end
-
-    def set(val)
-      @value = check(val)
-    end
-
-    private
-
-    def check(val)
-      setup_rb_error "config: --#{name} requires argument" unless val
-      val
-    end
-  end
-
-  class BoolItem < Item
-    def config_type
-      'bool'
-    end
-
-    def help_opt
-      "--#{@name}"
-    end
-
-    private
-
-    def check(val)
-      return 'yes' unless val
-      case val
-      when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
-      when /\An(o)?\z/i, /\Af(alse)\z/i  then 'no'
-      else
-        setup_rb_error "config: --#{@name} accepts only yes/no for argument"
-      end
-    end
-  end
-
-  class PathItem < Item
-    def config_type
-      'path'
-    end
-
-    private
-
-    def check(path)
-      setup_rb_error "config: --#{@name} requires argument"  unless path
-      path[0,1] == '$' ? path : File.expand_path(path)
-    end
-  end
-
-  class ProgramItem < Item
-    def config_type
-      'program'
-    end
-  end
-
-  class SelectItem < Item
-    def initialize(name, selection, default, desc)
-      super
-      @ok = selection.split('/')
-    end
-
-    def config_type
-      'select'
-    end
-
-    private
-
-    def check(val)
-      unless @ok.include?(val.strip)
-        setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
-      end
-      val.strip
-    end
-  end
-
-  class ExecItem < Item
-    def initialize(name, selection, desc, &block)
-      super name, selection, nil, desc
-      @ok = selection.split('/')
-      @action = block
-    end
-
-    def config_type
-      'exec'
-    end
-
-    def value?
-      false
-    end
-
-    def resolve(table)
-      setup_rb_error "$#{name()} wrongly used as option value"
-    end
-
-    undef set
-
-    def evaluate(val, table)
-      v = val.strip.downcase
-      unless @ok.include?(v)
-        setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
-      end
-      @action.call v, table
-    end
-  end
-
-  class PackageSelectionItem < Item
-    def initialize(name, template, default, help_default, desc)
-      super name, template, default, desc
-      @help_default = help_default
-    end
-
-    attr_reader :help_default
-
-    def config_type
-      'package'
-    end
-
-    private
-
-    def check(val)
-      unless File.dir?("packages/#{val}")
-        setup_rb_error "config: no such package: #{val}"
-      end
-      val
-    end
-  end
-
-  class MetaConfigEnvironment
-    def initialize(config, installer)
-      @config = config
-      @installer = installer
-    end
-
-    def config_names
-      @config.names
-    end
-
-    def config?(name)
-      @config.key?(name)
-    end
-
-    def bool_config?(name)
-      @config.lookup(name).config_type == 'bool'
-    end
-
-    def path_config?(name)
-      @config.lookup(name).config_type == 'path'
-    end
-
-    def value_config?(name)
-      @config.lookup(name).config_type != 'exec'
-    end
-
-    def add_config(item)
-      @config.add item
-    end
-
-    def add_bool_config(name, default, desc)
-      @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
-    end
-
-    def add_path_config(name, default, desc)
-      @config.add PathItem.new(name, 'path', default, desc)
-    end
-
-    def set_config_default(name, default)
-      @config.lookup(name).default = default
-    end
-
-    def remove_config(name)
-      @config.remove(name)
-    end
-
-    # For only multipackage
-    def packages
-      raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
-      @installer.packages
-    end
-
-    # For only multipackage
-    def declare_packages(list)
-      raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
-      @installer.packages = list
-    end
-  end
-
-end   # class ConfigTable
-
-
-# This module requires: #verbose?, #no_harm?
-module FileOperations
-
-  def mkdir_p(dirname, prefix = nil)
-    dirname = prefix + File.expand_path(dirname) if prefix
-    $stderr.puts "mkdir -p #{dirname}" if verbose?
-    return if no_harm?
-
-    # Does not check '/', it's too abnormal.
-    dirs = File.expand_path(dirname).split(%r<(?=/)>)
-    if /\A[a-z]:\z/i =~ dirs[0]
-      disk = dirs.shift
-      dirs[0] = disk + dirs[0]
-    end
-    dirs.each_index do |idx|
-      path = dirs[0..idx].join('')
-      Dir.mkdir path unless File.dir?(path)
-    end
-  end
-
-  def rm_f(path)
-    $stderr.puts "rm -f #{path}" if verbose?
-    return if no_harm?
-    force_remove_file path
-  end
-
-  def rm_rf(path)
-    $stderr.puts "rm -rf #{path}" if verbose?
-    return if no_harm?
-    remove_tree path
-  end
-
-  def remove_tree(path)
-    if File.symlink?(path)
-      remove_file path
-    elsif File.dir?(path)
-      remove_tree0 path
-    else
-      force_remove_file path
-    end
-  end
-
-  def remove_tree0(path)
-    Dir.foreach(path) do |ent|
-      next if ent == '.'
-      next if ent == '..'
-      entpath = "#{path}/#{ent}"
-      if File.symlink?(entpath)
-        remove_file entpath
-      elsif File.dir?(entpath)
-        remove_tree0 entpath
-      else
-        force_remove_file entpath
-      end
-    end
-    begin
-      Dir.rmdir path
-    rescue Errno::ENOTEMPTY
-      # directory may not be empty
-    end
-  end
-
-  def move_file(src, dest)
-    force_remove_file dest
-    begin
-      File.rename src, dest
-    rescue
-      File.open(dest, 'wb') {|f|
-        f.write File.binread(src)
-      }
-      File.chmod File.stat(src).mode, dest
-      File.unlink src
-    end
-  end
-
-  def force_remove_file(path)
-    begin
-      remove_file path
-    rescue
-    end
-  end
-
-  def remove_file(path)
-    File.chmod 0777, path
-    File.unlink path
-  end
-
-  def install(from, dest, mode, prefix = nil)
-    $stderr.puts "install #{from} #{dest}" if verbose?
-    return if no_harm?
-
-    realdest = prefix ? prefix + File.expand_path(dest) : dest
-    realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
-    str = File.binread(from)
-    if diff?(str, realdest)
-      verbose_off {
-        rm_f realdest if File.exist?(realdest)
-      }
-      File.open(realdest, 'wb') {|f|
-        f.write str
-      }
-      File.chmod mode, realdest
-
-      File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
-        if prefix
-          f.puts realdest.sub(prefix, '')
-        else
-          f.puts realdest
-        end
-      }
-    end
-  end
-
-  def diff?(new_content, path)
-    return true unless File.exist?(path)
-    new_content != File.binread(path)
-  end
-
-  def command(*args)
-    $stderr.puts args.join(' ') if verbose?
-    system(*args) or raise RuntimeError,
-        "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
-  end
-
-  def ruby(*args)
-    command config('rubyprog'), *args
-  end
-  
-  def make(task = nil)
-    command(*[config('makeprog'), task].compact)
-  end
-
-  def extdir?(dir)
-    File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
-  end
-
-  def files_of(dir)
-    Dir.open(dir) {|d|
-      return d.select {|ent| File.file?("#{dir}/#{ent}") }
-    }
-  end
-
-  DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
-
-  def directories_of(dir)
-    Dir.open(dir) {|d|
-      return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
-    }
-  end
-
-end
-
-
-# This module requires: #srcdir_root, #objdir_root, #relpath
-module HookScriptAPI
-
-  def get_config(key)
-    @config[key]
-  end
-
-  alias config get_config
-
-  # obsolete: use metaconfig to change configuration
-  def set_config(key, val)
-    @config[key] = val
-  end
-
-  #
-  # srcdir/objdir (works only in the package directory)
-  #
-
-  def curr_srcdir
-    "#{srcdir_root()}/#{relpath()}"
-  end
-
-  def curr_objdir
-    "#{objdir_root()}/#{relpath()}"
-  end
-
-  def srcfile(path)
-    "#{curr_srcdir()}/#{path}"
-  end
-
-  def srcexist?(path)
-    File.exist?(srcfile(path))
-  end
-
-  def srcdirectory?(path)
-    File.dir?(srcfile(path))
-  end
-  
-  def srcfile?(path)
-    File.file?(srcfile(path))
-  end
-
-  def srcentries(path = '.')
-    Dir.open("#{curr_srcdir()}/#{path}") {|d|
-      return d.to_a - %w(. ..)
-    }
-  end
-
-  def srcfiles(path = '.')
-    srcentries(path).select {|fname|
-      File.file?(File.join(curr_srcdir(), path, fname))
-    }
-  end
-
-  def srcdirectories(path = '.')
-    srcentries(path).select {|fname|
-      File.dir?(File.join(curr_srcdir(), path, fname))
-    }
-  end
-
-end
-
-
-class ToplevelInstaller
-
-  Version   = '3.4.1'
-  Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
-
-  TASKS = [
-    [ 'all',      'do config, setup, then install' ],
-    [ 'config',   'saves your configurations' ],
-    [ 'show',     'shows current configuration' ],
-    [ 'setup',    'compiles ruby extentions and others' ],
-    [ 'install',  'installs files' ],
-    [ 'test',     'run all tests in test/' ],
-    [ 'clean',    "does `make clean' for each extention" ],
-    [ 'distclean',"does `make distclean' for each extention" ]
-  ]
-
-  def ToplevelInstaller.invoke
-    config = ConfigTable.new(load_rbconfig())
-    config.load_standard_entries
-    config.load_multipackage_entries if multipackage?
-    config.fixup
-    klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
-    klass.new(File.dirname($0), config).invoke
-  end
-
-  def ToplevelInstaller.multipackage?
-    File.dir?(File.dirname($0) + '/packages')
-  end
-
-  def ToplevelInstaller.load_rbconfig
-    if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
-      ARGV.delete(arg)
-      load File.expand_path(arg.split(/=/, 2)[1])
-      $".push 'rbconfig.rb'
-    else
-      require 'rbconfig'
-    end
-    ::Config::CONFIG
-  end
-
-  def initialize(ardir_root, config)
-    @ardir = File.expand_path(ardir_root)
-    @config = config
-    # cache
-    @valid_task_re = nil
-  end
-
-  def config(key)
-    @config[key]
-  end
-
-  def inspect
-    "#<#{self.class} #{__id__()}>"
-  end
-
-  def invoke
-    run_metaconfigs
-    case task = parsearg_global()
-    when nil, 'all'
-      parsearg_config
-      init_installers
-      exec_config
-      exec_setup
-      exec_install
-    else
-      case task
-      when 'config', 'test'
-        ;
-      when 'clean', 'distclean'
-        @config.load_savefile if File.exist?(@config.savefile)
-      else
-        @config.load_savefile
-      end
-      __send__ "parsearg_#{task}"
-      init_installers
-      __send__ "exec_#{task}"
-    end
-  end
-  
-  def run_metaconfigs
-    @config.load_script "#{@ardir}/metaconfig"
-  end
-
-  def init_installers
-    @installer = Installer.new(@config, @ardir, File.expand_path('.'))
-  end
-
-  #
-  # Hook Script API bases
-  #
-
-  def srcdir_root
-    @ardir
-  end
-
-  def objdir_root
-    '.'
-  end
-
-  def relpath
-    '.'
-  end
-
-  #
-  # Option Parsing
-  #
-
-  def parsearg_global
-    while arg = ARGV.shift
-      case arg
-      when /\A\w+\z/
-        setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
-        return arg
-      when '-q', '--quiet'
-        @config.verbose = false
-      when '--verbose'
-        @config.verbose = true
-      when '--help'
-        print_usage $stdout
-        exit 0
-      when '--version'
-        puts "#{File.basename($0)} version #{Version}"
-        exit 0
-      when '--copyright'
-        puts Copyright
-        exit 0
-      else
-        setup_rb_error "unknown global option '#{arg}'"
-      end
-    end
-    nil
-  end
-
-  def valid_task?(t)
-    valid_task_re() =~ t
-  end
-
-  def valid_task_re
-    @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
-  end
-
-  def parsearg_no_options
-    unless ARGV.empty?
-      task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
-      setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
-    end
-  end
-
-  alias parsearg_show       parsearg_no_options
-  alias parsearg_setup      parsearg_no_options
-  alias parsearg_test       parsearg_no_options
-  alias parsearg_clean      parsearg_no_options
-  alias parsearg_distclean  parsearg_no_options
-
-  def parsearg_config
-    evalopt = []
-    set = []
-    @config.config_opt = []
-    while i = ARGV.shift
-      if /\A--?\z/ =~ i
-        @config.config_opt = ARGV.dup
-        break
-      end
-      name, value = *@config.parse_opt(i)
-      if @config.value_config?(name)
-        @config[name] = value
-      else
-        evalopt.push [name, value]
-      end
-      set.push name
-    end
-    evalopt.each do |name, value|
-      @config.lookup(name).evaluate value, @config
-    end
-    # Check if configuration is valid
-    set.each do |n|
-      @config[n] if @config.value_config?(n)
-    end
-  end
-
-  def parsearg_install
-    @config.no_harm = false
-    @config.install_prefix = ''
-    while a = ARGV.shift
-      case a
-      when '--no-harm'
-        @config.no_harm = true
-      when /\A--prefix=/
-        path = a.split(/=/, 2)[1]
-        path = File.expand_path(path) unless path[0,1] == '/'
-        @config.install_prefix = path
-      else
-        setup_rb_error "install: unknown option #{a}"
-      end
-    end
-  end
-
-  def print_usage(out)
-    out.puts 'Typical Installation Procedure:'
-    out.puts "  $ ruby #{File.basename $0} config"
-    out.puts "  $ ruby #{File.basename $0} setup"
-    out.puts "  # ruby #{File.basename $0} install (may require root privilege)"
-    out.puts
-    out.puts 'Detailed Usage:'
-    out.puts "  ruby #{File.basename $0} <global option>"
-    out.puts "  ruby #{File.basename $0} [<global options>] <task> [<task options>]"
-
-    fmt = "  %-24s %s\n"
-    out.puts
-    out.puts 'Global options:'
-    out.printf fmt, '-q,--quiet',   'suppress message outputs'
-    out.printf fmt, '   --verbose', 'output messages verbosely'
-    out.printf fmt, '   --help',    'print this message'
-    out.printf fmt, '   --version', 'print version and quit'
-    out.printf fmt, '   --copyright',  'print copyright and quit'
-    out.puts
-    out.puts 'Tasks:'
-    TASKS.each do |name, desc|
-      out.printf fmt, name, desc
-    end
-
-    fmt = "  %-24s %s [%s]\n"
-    out.puts
-    out.puts 'Options for CONFIG or ALL:'
-    @config.each do |item|
-      out.printf fmt, item.help_opt, item.description, item.help_default
-    end
-    out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
-    out.puts
-    out.puts 'Options for INSTALL:'
-    out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
-    out.printf fmt, '--prefix=path',  'install path prefix', ''
-    out.puts
-  end
-
-  #
-  # Task Handlers
-  #
-
-  def exec_config
-    @installer.exec_config
-    @config.save   # must be final
-  end
-
-  def exec_setup
-    @installer.exec_setup
-  end
-
-  def exec_install
-    @installer.exec_install
-  end
-
-  def exec_test
-    @installer.exec_test
-  end
-
-  def exec_show
-    @config.each do |i|
-      printf "%-20s %s\n", i.name, i.value if i.value?
-    end
-  end
-
-  def exec_clean
-    @installer.exec_clean
-  end
-
-  def exec_distclean
-    @installer.exec_distclean
-  end
-
-end   # class ToplevelInstaller
-
-
-class ToplevelInstallerMulti < ToplevelInstaller
-
-  include FileOperations
-
-  def initialize(ardir_root, config)
-    super
-    @packages = directories_of("#{@ardir}/packages")
-    raise 'no package exists' if @packages.empty?
-    @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
-  end
-
-  def run_metaconfigs
-    @config.load_script "#{@ardir}/metaconfig", self
-    @packages.each do |name|
-      @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
-    end
-  end
-
-  attr_reader :packages
-
-  def packages=(list)
-    raise 'package list is empty' if list.empty?
-    list.each do |name|
-      raise "directory packages/#{name} does not exist"\
-              unless File.dir?("#{@ardir}/packages/#{name}")
-    end
-    @packages = list
-  end
-
-  def init_installers
-    @installers = {}
-    @packages.each do |pack|
-      @installers[pack] = Installer.new(@config,
-                                       "#{@ardir}/packages/#{pack}",
-                                       "packages/#{pack}")
-    end
-    with    = extract_selection(config('with'))
-    without = extract_selection(config('without'))
-    @selected = @installers.keys.select {|name|
-                  (with.empty? or with.include?(name)) \
-                      and not without.include?(name)
-                }
-  end
-
-  def extract_selection(list)
-    a = list.split(/,/)
-    a.each do |name|
-      setup_rb_error "no such package: #{name}"  unless @installers.key?(name)
-    end
-    a
-  end
-
-  def print_usage(f)
-    super
-    f.puts 'Inluded packages:'
-    f.puts '  ' + @packages.sort.join(' ')
-    f.puts
-  end
-
-  #
-  # Task Handlers
-  #
-
-  def exec_config
-    run_hook 'pre-config'
-    each_selected_installers {|inst| inst.exec_config }
-    run_hook 'post-config'
-    @config.save   # must be final
-  end
-
-  def exec_setup
-    run_hook 'pre-setup'
-    each_selected_installers {|inst| inst.exec_setup }
-    run_hook 'post-setup'
-  end
-
-  def exec_install
-    run_hook 'pre-install'
-    each_selected_installers {|inst| inst.exec_install }
-    run_hook 'post-install'
-  end
-
-  def exec_test
-    run_hook 'pre-test'
-    each_selected_installers {|inst| inst.exec_test }
-    run_hook 'post-test'
-  end
-
-  def exec_clean
-    rm_f @config.savefile
-    run_hook 'pre-clean'
-    each_selected_installers {|inst| inst.exec_clean }
-    run_hook 'post-clean'
-  end
-
-  def exec_distclean
-    rm_f @config.savefile
-    run_hook 'pre-distclean'
-    each_selected_installers {|inst| inst.exec_distclean }
-    run_hook 'post-distclean'
-  end
-
-  #
-  # lib
-  #
-
-  def each_selected_installers
-    Dir.mkdir 'packages' unless File.dir?('packages')
-    @selected.each do |pack|
-      $stderr.puts "Processing the package `#{pack}' ..." if verbose?
-      Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
-      Dir.chdir "packages/#{pack}"
-      yield @installers[pack]
-      Dir.chdir '../..'
-    end
-  end
-
-  def run_hook(id)
-    @root_installer.run_hook id
-  end
-
-  # module FileOperations requires this
-  def verbose?
-    @config.verbose?
-  end
-
-  # module FileOperations requires this
-  def no_harm?
-    @config.no_harm?
-  end
-
-end   # class ToplevelInstallerMulti
-
-
-class Installer
-
-  FILETYPES = %w( bin lib ext data conf man )
-
-  include FileOperations
-  include HookScriptAPI
-
-  def initialize(config, srcroot, objroot)
-    @config = config
-    @srcdir = File.expand_path(srcroot)
-    @objdir = File.expand_path(objroot)
-    @currdir = '.'
-  end
-
-  def inspect
-    "#<#{self.class} #{File.basename(@srcdir)}>"
-  end
-
-  def noop(rel)
-  end
-
-  #
-  # Hook Script API base methods
-  #
-
-  def srcdir_root
-    @srcdir
-  end
-
-  def objdir_root
-    @objdir
-  end
-
-  def relpath
-    @currdir
-  end
-
-  #
-  # Config Access
-  #
-
-  # module FileOperations requires this
-  def verbose?
-    @config.verbose?
-  end
-
-  # module FileOperations requires this
-  def no_harm?
-    @config.no_harm?
-  end
-
-  def verbose_off
-    begin
-      save, @config.verbose = @config.verbose?, false
-      yield
-    ensure
-      @config.verbose = save
-    end
-  end
-
-  #
-  # TASK config
-  #
-
-  def exec_config
-    exec_task_traverse 'config'
-  end
-
-  alias config_dir_bin noop
-  alias config_dir_lib noop
-
-  def config_dir_ext(rel)
-    extconf if extdir?(curr_srcdir())
-  end
-
-  alias config_dir_data noop
-  alias config_dir_conf noop
-  alias config_dir_man noop
-
-  def extconf
-    ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
-  end
-
-  #
-  # TASK setup
-  #
-
-  def exec_setup
-    exec_task_traverse 'setup'
-  end
-
-  def setup_dir_bin(rel)
-    files_of(curr_srcdir()).each do |fname|
-      update_shebang_line "#{curr_srcdir()}/#{fname}"
-    end
-  end
-
-  alias setup_dir_lib noop
-
-  def setup_dir_ext(rel)
-    make if extdir?(curr_srcdir())
-  end
-
-  alias setup_dir_data noop
-  alias setup_dir_conf noop
-  alias setup_dir_man noop
-
-  def update_shebang_line(path)
-    return if no_harm?
-    return if config('shebang') == 'never'
-    old = Shebang.load(path)
-    if old
-      $stderr.puts "warning: #{path}: Shebang line includes too many args.  It is not portable and your program may not work." if old.args.size > 1
-      new = new_shebang(old)
-      return if new.to_s == old.to_s
-    else
-      return unless config('shebang') == 'all'
-      new = Shebang.new(config('rubypath'))
-    end
-    $stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
-    open_atomic_writer(path) {|output|
-      File.open(path, 'rb') {|f|
-        f.gets if old   # discard
-        output.puts new.to_s
-        output.print f.read
-      }
-    }
-  end
-
-  def new_shebang(old)
-    if /\Aruby/ =~ File.basename(old.cmd)
-      Shebang.new(config('rubypath'), old.args)
-    elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
-      Shebang.new(config('rubypath'), old.args[1..-1])
-    else
-      return old unless config('shebang') == 'all'
-      Shebang.new(config('rubypath'))
-    end
-  end
-
-  def open_atomic_writer(path, &block)
-    tmpfile = File.basename(path) + '.tmp'
-    begin
-      File.open(tmpfile, 'wb', &block)
-      File.rename tmpfile, File.basename(path)
-    ensure
-      File.unlink tmpfile if File.exist?(tmpfile)
-    end
-  end
-
-  class Shebang
-    def Shebang.load(path)
-      line = nil
-      File.open(path) {|f|
-        line = f.gets
-      }
-      return nil unless /\A#!/ =~ line
-      parse(line)
-    end
-
-    def Shebang.parse(line)
-      cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
-      new(cmd, args)
-    end
-
-    def initialize(cmd, args = [])
-      @cmd = cmd
-      @args = args
-    end
-
-    attr_reader :cmd
-    attr_reader :args
-
-    def to_s
-      "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
-    end
-  end
-
-  #
-  # TASK install
-  #
-
-  def exec_install
-    rm_f 'InstalledFiles'
-    exec_task_traverse 'install'
-  end
-
-  def install_dir_bin(rel)
-    install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
-  end
-
-  def install_dir_lib(rel)
-    install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
-  end
-
-  def install_dir_ext(rel)
-    return unless extdir?(curr_srcdir())
-    install_files rubyextentions('.'),
-                  "#{config('sodir')}/#{File.dirname(rel)}",
-                  0555
-  end
-
-  def install_dir_data(rel)
-    install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
-  end
-
-  def install_dir_conf(rel)
-    # FIXME: should not remove current config files
-    # (rename previous file to .old/.org)
-    install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
-  end
-
-  def install_dir_man(rel)
-    install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
-  end
-
-  def install_files(list, dest, mode)
-    mkdir_p dest, @config.install_prefix
-    list.each do |fname|
-      install fname, dest, mode, @config.install_prefix
-    end
-  end
-
-  def libfiles
-    glob_reject(%w(*.y *.output), targetfiles())
-  end
-
-  def rubyextentions(dir)
-    ents = glob_select("*.#{@config.dllext}", targetfiles())
-    if ents.empty?
-      setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
-    end
-    ents
-  end
-
-  def targetfiles
-    mapdir(existfiles() - hookfiles())
-  end
-
-  def mapdir(ents)
-    ents.map {|ent|
-      if File.exist?(ent)
-      then ent                         # objdir
-      else "#{curr_srcdir()}/#{ent}"   # srcdir
-      end
-    }
-  end
-
-  # picked up many entries from cvs-1.11.1/src/ignore.c
-  JUNK_FILES = %w( 
-    core RCSLOG tags TAGS .make.state
-    .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
-    *~ *.old *.bak *.BAK *.orig *.rej _$* *$
-
-    *.org *.in .*
-  )
-
-  def existfiles
-    glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
-  end
-
-  def hookfiles
-    %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
-      %w( config setup install clean ).map {|t| sprintf(fmt, t) }
-    }.flatten
-  end
-
-  def glob_select(pat, ents)
-    re = globs2re([pat])
-    ents.select {|ent| re =~ ent }
-  end
-
-  def glob_reject(pats, ents)
-    re = globs2re(pats)
-    ents.reject {|ent| re =~ ent }
-  end
-
-  GLOB2REGEX = {
-    '.' => '\.',
-    '$' => '\$',
-    '#' => '\#',
-    '*' => '.*'
-  }
-
-  def globs2re(pats)
-    /\A(?:#{
-      pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
-    })\z/
-  end
-
-  #
-  # TASK test
-  #
-
-  TESTDIR = 'test'
-
-  def exec_test
-    unless File.directory?('test')
-      $stderr.puts 'no test in this package' if verbose?
-      return
-    end
-    $stderr.puts 'Running tests...' if verbose?
-    begin
-      require 'test/unit'
-    rescue LoadError
-      setup_rb_error 'test/unit cannot loaded.  You need Ruby 1.8 or later to invoke this task.'
-    end
-    runner = Test::Unit::AutoRunner.new(true)
-    runner.to_run << TESTDIR
-    runner.run
-  end
-
-  #
-  # TASK clean
-  #
-
-  def exec_clean
-    exec_task_traverse 'clean'
-    rm_f @config.savefile
-    rm_f 'InstalledFiles'
-  end
-
-  alias clean_dir_bin noop
-  alias clean_dir_lib noop
-  alias clean_dir_data noop
-  alias clean_dir_conf noop
-  alias clean_dir_man noop
-
-  def clean_dir_ext(rel)
-    return unless extdir?(curr_srcdir())
-    make 'clean' if File.file?('Makefile')
-  end
-
-  #
-  # TASK distclean
-  #
-
-  def exec_distclean
-    exec_task_traverse 'distclean'
-    rm_f @config.savefile
-    rm_f 'InstalledFiles'
-  end
-
-  alias distclean_dir_bin noop
-  alias distclean_dir_lib noop
-
-  def distclean_dir_ext(rel)
-    return unless extdir?(curr_srcdir())
-    make 'distclean' if File.file?('Makefile')
-  end
-
-  alias distclean_dir_data noop
-  alias distclean_dir_conf noop
-  alias distclean_dir_man noop
-
-  #
-  # Traversing
-  #
-
-  def exec_task_traverse(task)
-    run_hook "pre-#{task}"
-    FILETYPES.each do |type|
-      if type == 'ext' and config('without-ext') == 'yes'
-        $stderr.puts 'skipping ext/* by user option' if verbose?
-        next
-      end
-      traverse task, type, "#{task}_dir_#{type}"
-    end
-    run_hook "post-#{task}"
-  end
-
-  def traverse(task, rel, mid)
-    dive_into(rel) {
-      run_hook "pre-#{task}"
-      __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
-      directories_of(curr_srcdir()).each do |d|
-        traverse task, "#{rel}/#{d}", mid
-      end
-      run_hook "post-#{task}"
-    }
-  end
-
-  def dive_into(rel)
-    return unless File.dir?("#{@srcdir}/#{rel}")
-
-    dir = File.basename(rel)
-    Dir.mkdir dir unless File.dir?(dir)
-    prevdir = Dir.pwd
-    Dir.chdir dir
-    $stderr.puts '---> ' + rel if verbose?
-    @currdir = rel
-    yield
-    Dir.chdir prevdir
-    $stderr.puts '<--- ' + rel if verbose?
-    @currdir = File.dirname(rel)
-  end
-
-  def run_hook(id)
-    path = [ "#{curr_srcdir()}/#{id}",
-             "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
-    return unless path
-    begin
-      instance_eval File.read(path), path, 1
-    rescue
-      raise if $DEBUG
-      setup_rb_error "hook #{path} failed:\n" + $!.message
-    end
-  end
-
-end   # class Installer
-
-
-class SetupError < StandardError; end
-
-def setup_rb_error(msg)
-  raise SetupError, msg
-end
-
-if $0 == __FILE__
-  begin
-    ToplevelInstaller.invoke
-  rescue SetupError
-    raise if $DEBUG
-    $stderr.puts $!.message
-    $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
-    exit 1
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1d/1d1a40d68d66d098f38161f4b90f0e887e1b73d9.svn-base
--- /dev/null
+++ b/.svn/pristine/1d/1d1a40d68d66d098f38161f4b90f0e887e1b73d9.svn-base
@@ -0,0 +1,15 @@
+class AddUniqueIndexOnTokensValue < ActiveRecord::Migration
+  def up
+    say_with_time "Adding unique index on tokens, this may take some time..." do
+      # Just in case
+      duplicates = Token.connection.select_values("SELECT value FROM #{Token.table_name} GROUP BY value HAVING COUNT(id) > 1")
+      Token.where(:value => duplicates).delete_all
+  
+      add_index :tokens, :value, :unique => true, :name => 'tokens_value'
+    end
+  end
+
+  def down
+    remove_index :tokens, :name => 'tokens_value'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1d/1d27e55302983310e1f42ffc59d4c81eba90edc6.svn-base
--- a/.svn/pristine/1d/1d27e55302983310e1f42ffc59d4c81eba90edc6.svn-base
+++ /dev/null
@@ -1,129 +0,0 @@
-// ** I18N
-
-// Calendar ES (spanish) language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Updater: Servilio Afre Puentes <servilios@yahoo.com>
-// Updated: 2004-06-03
-// Encoding: utf-8
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Domingo",
- "Lunes",
- "Martes",
- "MiÃ©rcoles",
- "Jueves",
- "Viernes",
- "SÃ¡bado",
- "Domingo");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Dom",
- "Lun",
- "Mar",
- "MiÃ©",
- "Jue",
- "Vie",
- "SÃ¡b",
- "Dom");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Enero",
- "Febrero",
- "Marzo",
- "Abril",
- "Mayo",
- "Junio",
- "Julio",
- "Agosto",
- "Septiembre",
- "Octubre",
- "Noviembre",
- "Diciembre");
-
-// short month names
-Calendar._SMN = new Array
-("Ene",
- "Feb",
- "Mar",
- "Abr",
- "May",
- "Jun",
- "Jul",
- "Ago",
- "Sep",
- "Oct",
- "Nov",
- "Dic");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Acerca del calendario";
-
-Calendar._TT["ABOUT"] =
-"Selector DHTML de Fecha/Hora\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"Para conseguir la Ãºltima versiÃ³n visite: http://www.dynarch.com/projects/calendar/\n" +
-"Distribuido bajo licencia GNU LGPL. Visite http://gnu.org/licenses/lgpl.html para mÃ¡s detalles." +
-"\n\n" +
-"SelecciÃ³n de fecha:\n" +
-"- Use los botones \xab, \xbb para seleccionar el aÃ±o\n" +
-"- Use los botones " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para seleccionar el mes\n" +
-"- Mantenga pulsado el ratÃ³n en cualquiera de estos botones para una selecciÃ³n rÃ¡pida.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"SelecciÃ³n de hora:\n" +
-"- Pulse en cualquiera de las partes de la hora para incrementarla\n" +
-"- o pulse las mayÃºsculas mientras hace clic para decrementarla\n" +
-"- o haga clic y arrastre el ratÃ³n para una selecciÃ³n mÃ¡s rÃ¡pida.";
-
-Calendar._TT["PREV_YEAR"] = "AÃ±o anterior (mantener para menÃº)";
-Calendar._TT["PREV_MONTH"] = "Mes anterior (mantener para menÃº)";
-Calendar._TT["GO_TODAY"] = "Ir a hoy";
-Calendar._TT["NEXT_MONTH"] = "Mes siguiente (mantener para menÃº)";
-Calendar._TT["NEXT_YEAR"] = "AÃ±o siguiente (mantener para menÃº)";
-Calendar._TT["SEL_DATE"] = "Seleccionar fecha";
-Calendar._TT["DRAG_TO_MOVE"] = "Arrastrar para mover";
-Calendar._TT["PART_TODAY"] = " (hoy)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Hacer %s primer dÃ­a de la semana";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Cerrar";
-Calendar._TT["TODAY"] = "Hoy";
-Calendar._TT["TIME_PART"] = "(MayÃºscula-)Clic o arrastre para cambiar valor";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%A, %e de %B de %Y";
-
-Calendar._TT["WK"] = "sem";
-Calendar._TT["TIME"] = "Hora:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1d/1d511a07201f732ef6d8b4edd5fe52d3844b42ce.svn-base
--- a/.svn/pristine/1d/1d511a07201f732ef6d8b4edd5fe52d3844b42ce.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/destroy'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1d/1d53493a3b6f86fc88f7ad446a14e1fb98681f83.svn-base
--- a/.svn/pristine/1d/1d53493a3b6f86fc88f7ad446a14e1fb98681f83.svn-base
+++ /dev/null
@@ -1,58 +0,0 @@
-= Net::LDAP Changelog
-
-== Net::LDAP 0.0.4: August 15, 2006
-* Undeprecated Net::LDAP#modify. Thanks to Justin Forder for
-  providing the rationale for this.
-* Added a much-expanded set of special characters to the parser
-  for RFC-2254 filters. Thanks to Andre Nathan.
-* Changed Net::LDAP#search so you can pass it a filter in string form.
-  The conversion to a Net::LDAP::Filter now happens automatically.
-* Implemented Net::LDAP#bind_as (preliminary and subject to change).
-  Thanks for Simon Claret for valuable suggestions and for helping test.
-* Fixed bug in Net::LDAP#open that was preventing #open from being
-  called more than one on a given Net::LDAP object.
-
-== Net::LDAP 0.0.3: July 26, 2006
-* Added simple TLS encryption.
-  Thanks to Garett Shulman for suggestions and for helping test.
-
-== Net::LDAP 0.0.2: July 12, 2006
-* Fixed malformation in distro tarball and gem.
-* Improved documentation.
-* Supported "paged search control."
-* Added a range of API improvements.
-* Thanks to Andre Nathan, andre@digirati.com.br, for valuable
-  suggestions.
-* Added support for LE and GE search filters.
-* Added support for Search referrals.
-* Fixed a regression with openldap 2.2.x and higher caused
-  by the introduction of RFC-2696 controls. Thanks to Andre
-  Nathan for reporting the problem.
-* Added support for RFC-2254 filter syntax.
-
-== Net::LDAP 0.0.1: May 1, 2006
-* Initial release.
-* Client functionality is near-complete, although the APIs
-  are not guaranteed and may change depending on feedback
-  from the community.
-* We're internally working on a Ruby-based implementation
-  of a full-featured, production-quality LDAP server,
-  which will leverage the underlying LDAP and BER functionality
-  in Net::LDAP.
-* Please tell us if you would be interested in seeing a public
-  release of the LDAP server.
-* Grateful acknowledgement to Austin Ziegler, who reviewed
-  this code and provided the release framework, including
-  minitar.
-
-#--
-# Net::LDAP for Ruby.
-#   http://rubyforge.org/projects/net-ldap/
-#   Copyright (C) 2006 by Francis Cianfrocca
-#
-#   Available under the same terms as Ruby. See LICENCE in the main
-#   distribution for full licensing information.
-#
-# $Id: ChangeLog,v 1.17.2.4 2005/09/09 12:36:42 austin Exp $
-#++
-# vim: sts=2 sw=2 ts=4 et ai tw=77
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1d/1d5de2a1ef017a12eb407c0c43e77ba879705fe3.svn-base
--- a/.svn/pristine/1d/1d5de2a1ef017a12eb407c0c43e77ba879705fe3.svn-base
+++ /dev/null
@@ -1,509 +0,0 @@
-module CodeRay
-module Scanners
-  
-  load :html
-  
-  # Scanner for PHP.
-  # 
-  # Original by Stefan Walk.
-  class PHP < Scanner
-    
-    register_for :php
-    file_extension 'php'
-    encoding 'BINARY'
-    
-    KINDS_NOT_LOC = HTML::KINDS_NOT_LOC
-    
-  protected
-    
-    def setup
-      @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true, :keep_state => true
-    end
-    
-    def reset_instance
-      super
-      @html_scanner.reset
-    end
-    
-    module Words  # :nodoc:
-      
-      # according to http://www.php.net/manual/en/reserved.keywords.php
-      KEYWORDS = %w[
-        abstract and array as break case catch class clone const continue declare default do else elseif
-        enddeclare endfor endforeach endif endswitch endwhile extends final for foreach function global
-        goto if implements interface instanceof namespace new or private protected public static switch
-        throw try use var while xor
-        cfunction old_function
-      ]
-      
-      TYPES = %w[ int integer float double bool boolean string array object resource ]
-      
-      LANGUAGE_CONSTRUCTS = %w[
-        die echo empty exit eval include include_once isset list
-        require require_once return print unset
-      ]
-      
-      CLASSES = %w[ Directory stdClass __PHP_Incomplete_Class exception php_user_filter Closure ]
-      
-      # according to http://php.net/quickref.php on 2009-04-21;
-      # all functions with _ excluded (module functions) and selected additional functions
-      BUILTIN_FUNCTIONS = %w[
-        abs acos acosh addcslashes addslashes aggregate array arsort ascii2ebcdic asin asinh asort assert atan atan2
-        atanh basename bcadd bccomp bcdiv bcmod bcmul bcpow bcpowmod bcscale bcsqrt bcsub bin2hex bindec
-        bindtextdomain bzclose bzcompress bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite
-        calculhmac ceil chdir checkdate checkdnsrr chgrp chmod chop chown chr chroot clearstatcache closedir closelog
-        compact constant copy cos cosh count crc32 crypt current date dcgettext dcngettext deaggregate decbin dechex
-        decoct define defined deg2rad delete dgettext die dirname diskfreespace dl dngettext doubleval each
-        ebcdic2ascii echo empty end ereg eregi escapeshellarg escapeshellcmd eval exec exit exp explode expm1 extract
-        fclose feof fflush fgetc fgetcsv fgets fgetss file fileatime filectime filegroup fileinode filemtime fileowner
-        fileperms filepro filesize filetype floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv
-        fputs fread frenchtojd fscanf fseek fsockopen fstat ftell ftok ftruncate fwrite getallheaders getcwd getdate
-        getenv gethostbyaddr gethostbyname gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid
-        getmyuid getopt getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext
-        gettimeofday gettype glob gmdate gmmktime gmstrftime gregoriantojd gzclose gzcompress gzdecode gzdeflate
-        gzencode gzeof gzfile gzgetc gzgets gzgetss gzinflate gzopen gzpassthru gzputs gzread gzrewind gzseek gztell
-        gzuncompress gzwrite hash header hebrev hebrevc hexdec htmlentities htmlspecialchars hypot iconv idate
-        implode include intval ip2long iptcembed iptcparse isset
-        jddayofweek jdmonthname jdtofrench jdtogregorian jdtojewish jdtojulian jdtounix jewishtojd join jpeg2wbmp
-        juliantojd key krsort ksort lcfirst lchgrp lchown levenshtein link linkinfo list localeconv localtime log
-        log10 log1p long2ip lstat ltrim mail main max md5 metaphone mhash microtime min mkdir mktime msql natcasesort
-        natsort next ngettext nl2br nthmac octdec opendir openlog
-        ord overload pack passthru pathinfo pclose pfsockopen phpcredits phpinfo phpversion pi png2wbmp popen pos pow
-        prev print printf putenv quotemeta rad2deg rand range rawurldecode rawurlencode readdir readfile readgzfile
-        readline readlink realpath recode rename require reset rewind rewinddir rmdir round rsort rtrim scandir
-        serialize setcookie setlocale setrawcookie settype sha1 shuffle signeurlpaiement sin sinh sizeof sleep snmpget
-        snmpgetnext snmprealwalk snmpset snmpwalk snmpwalkoid sort soundex split spliti sprintf sqrt srand sscanf stat
-        strcasecmp strchr strcmp strcoll strcspn strftime stripcslashes stripos stripslashes stristr strlen
-        strnatcasecmp strnatcmp strncasecmp strncmp strpbrk strpos strptime strrchr strrev strripos strrpos strspn
-        strstr strtok strtolower strtotime strtoupper strtr strval substr symlink syslog system tan tanh tempnam
-        textdomain time tmpfile touch trim uasort ucfirst ucwords uksort umask uniqid unixtojd unlink unpack
-        unserialize unset urldecode urlencode usleep usort vfprintf virtual vprintf vsprintf wordwrap
-        array_change_key_case array_chunk array_combine array_count_values array_diff array_diff_assoc
-        array_diff_key array_diff_uassoc array_diff_ukey array_fill array_fill_keys array_filter array_flip
-        array_intersect array_intersect_assoc array_intersect_key array_intersect_uassoc array_intersect_ukey
-        array_key_exists array_keys array_map array_merge array_merge_recursive array_multisort array_pad
-        array_pop array_product array_push array_rand array_reduce array_reverse array_search array_shift
-        array_slice array_splice array_sum array_udiff array_udiff_assoc array_udiff_uassoc array_uintersect
-        array_uintersect_assoc array_uintersect_uassoc array_unique array_unshift array_values array_walk
-        array_walk_recursive
-        assert_options base_convert base64_decode base64_encode
-        chunk_split class_exists class_implements class_parents
-        count_chars debug_backtrace debug_print_backtrace debug_zval_dump
-        error_get_last error_log error_reporting extension_loaded
-        file_exists file_get_contents file_put_contents load_file
-        func_get_arg func_get_args func_num_args function_exists
-        get_browser get_called_class get_cfg_var get_class get_class_methods get_class_vars
-        get_current_user get_declared_classes get_declared_interfaces get_defined_constants
-        get_defined_functions get_defined_vars get_extension_funcs get_headers get_html_translation_table
-        get_include_path get_included_files get_loaded_extensions get_magic_quotes_gpc get_magic_quotes_runtime
-        get_meta_tags get_object_vars get_parent_class get_required_filesget_resource_type
-        gc_collect_cycles gc_disable gc_enable gc_enabled
-        halt_compiler headers_list headers_sent highlight_file highlight_string
-        html_entity_decode htmlspecialchars_decode
-        in_array include_once inclued_get_data
-        is_a is_array is_binary is_bool is_buffer is_callable is_dir is_double is_executable is_file is_finite
-        is_float is_infinite is_int is_integer is_link is_long is_nan is_null is_numeric is_object is_readable
-        is_real is_resource is_scalar is_soap_fault is_string is_subclass_of is_unicode is_uploaded_file
-        is_writable is_writeable
-        locale_get_default locale_set_default
-        number_format override_function parse_str parse_url
-        php_check_syntax php_ini_loaded_file php_ini_scanned_files php_logo_guid php_sapi_name
-        php_strip_whitespace php_uname
-        preg_filter preg_grep preg_last_error preg_match preg_match_all preg_quote preg_replace
-        preg_replace_callback preg_split print_r
-        require_once register_shutdown_function register_tick_function
-        set_error_handler set_exception_handler set_file_buffer set_include_path
-        set_magic_quotes_runtime set_time_limit shell_exec
-        str_getcsv str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split str_word_count
-        strip_tags substr_compare substr_count substr_replace
-        time_nanosleep time_sleep_until
-        token_get_all token_name trigger_error
-        unregister_tick_function use_soap_error_handler user_error
-        utf8_decode utf8_encode var_dump var_export
-        version_compare
-        zend_logo_guid zend_thread_id zend_version
-        create_function call_user_func_array
-        posix_access posix_ctermid posix_get_last_error posix_getcwd posix_getegid
-        posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups
-        posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid
-        posix_getpwnam posix_getpwuid posix_getrlimit posix_getsid posix_getuid
-        posix_initgroups posix_isatty posix_kill posix_mkfifo posix_mknod
-        posix_setegid posix_seteuid posix_setgid posix_setpgid posix_setsid
-        posix_setuid posix_strerror posix_times posix_ttyname posix_uname
-        pcntl_alarm pcntl_exec pcntl_fork pcntl_getpriority pcntl_setpriority
-        pcntl_signal pcntl_signal_dispatch pcntl_sigprocmask pcntl_sigtimedwait
-        pcntl_sigwaitinfo pcntl_wait pcntl_waitpid pcntl_wexitstatus pcntl_wifexited
-        pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig
-      ]
-      # TODO: more built-in PHP functions?
-      
-      EXCEPTIONS = %w[
-        E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING
-        E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_DEPRECATED E_USER_DEPRECATED E_ALL E_STRICT
-      ]
-      
-      CONSTANTS = %w[
-        null true false self parent
-        __LINE__ __DIR__ __FILE__ __LINE__
-        __CLASS__ __NAMESPACE__ __METHOD__ __FUNCTION__
-        PHP_VERSION PHP_MAJOR_VERSION PHP_MINOR_VERSION PHP_RELEASE_VERSION PHP_VERSION_ID PHP_EXTRA_VERSION PHP_ZTS
-        PHP_DEBUG PHP_MAXPATHLEN PHP_OS PHP_SAPI PHP_EOL PHP_INT_MAX PHP_INT_SIZE DEFAULT_INCLUDE_PATH
-        PEAR_INSTALL_DIR PEAR_EXTENSION_DIR PHP_EXTENSION_DIR PHP_PREFIX PHP_BINDIR PHP_LIBDIR PHP_DATADIR
-        PHP_SYSCONFDIR PHP_LOCALSTATEDIR PHP_CONFIG_FILE_PATH PHP_CONFIG_FILE_SCAN_DIR PHP_SHLIB_SUFFIX
-        PHP_OUTPUT_HANDLER_START PHP_OUTPUT_HANDLER_CONT PHP_OUTPUT_HANDLER_END
-        __COMPILER_HALT_OFFSET__
-        EXTR_OVERWRITE EXTR_SKIP EXTR_PREFIX_SAME EXTR_PREFIX_ALL EXTR_PREFIX_INVALID EXTR_PREFIX_IF_EXISTS
-        EXTR_IF_EXISTS SORT_ASC SORT_DESC SORT_REGULAR SORT_NUMERIC SORT_STRING CASE_LOWER CASE_UPPER COUNT_NORMAL
-        COUNT_RECURSIVE ASSERT_ACTIVE ASSERT_CALLBACK ASSERT_BAIL ASSERT_WARNING ASSERT_QUIET_EVAL CONNECTION_ABORTED
-        CONNECTION_NORMAL CONNECTION_TIMEOUT INI_USER INI_PERDIR INI_SYSTEM INI_ALL M_E M_LOG2E M_LOG10E M_LN2 M_LN10
-        M_PI M_PI_2 M_PI_4 M_1_PI M_2_PI M_2_SQRTPI M_SQRT2 M_SQRT1_2 CRYPT_SALT_LENGTH CRYPT_STD_DES CRYPT_EXT_DES
-        CRYPT_MD5 CRYPT_BLOWFISH DIRECTORY_SEPARATOR SEEK_SET SEEK_CUR SEEK_END LOCK_SH LOCK_EX LOCK_UN LOCK_NB
-        HTML_SPECIALCHARS HTML_ENTITIES ENT_COMPAT ENT_QUOTES ENT_NOQUOTES INFO_GENERAL INFO_CREDITS
-        INFO_CONFIGURATION INFO_MODULES INFO_ENVIRONMENT INFO_VARIABLES INFO_LICENSE INFO_ALL CREDITS_GROUP
-        CREDITS_GENERAL CREDITS_SAPI CREDITS_MODULES CREDITS_DOCS CREDITS_FULLPAGE CREDITS_QA CREDITS_ALL STR_PAD_LEFT
-        STR_PAD_RIGHT STR_PAD_BOTH PATHINFO_DIRNAME PATHINFO_BASENAME PATHINFO_EXTENSION PATH_SEPARATOR CHAR_MAX
-        LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_ALL LC_MESSAGES ABDAY_1 ABDAY_2 ABDAY_3 ABDAY_4 ABDAY_5
-        ABDAY_6 ABDAY_7 DAY_1 DAY_2 DAY_3 DAY_4 DAY_5 DAY_6 DAY_7 ABMON_1 ABMON_2 ABMON_3 ABMON_4 ABMON_5 ABMON_6
-        ABMON_7 ABMON_8 ABMON_9 ABMON_10 ABMON_11 ABMON_12 MON_1 MON_2 MON_3 MON_4 MON_5 MON_6 MON_7 MON_8 MON_9
-        MON_10 MON_11 MON_12 AM_STR PM_STR D_T_FMT D_FMT T_FMT T_FMT_AMPM ERA ERA_YEAR ERA_D_T_FMT ERA_D_FMT ERA_T_FMT
-        ALT_DIGITS INT_CURR_SYMBOL CURRENCY_SYMBOL CRNCYSTR MON_DECIMAL_POINT MON_THOUSANDS_SEP MON_GROUPING
-        POSITIVE_SIGN NEGATIVE_SIGN INT_FRAC_DIGITS FRAC_DIGITS P_CS_PRECEDES P_SEP_BY_SPACE N_CS_PRECEDES
-        N_SEP_BY_SPACE P_SIGN_POSN N_SIGN_POSN DECIMAL_POINT RADIXCHAR THOUSANDS_SEP THOUSEP GROUPING YESEXPR NOEXPR
-        YESSTR NOSTR CODESET LOG_EMERG LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG LOG_KERN
-        LOG_USER LOG_MAIL LOG_DAEMON LOG_AUTH LOG_SYSLOG LOG_LPR LOG_NEWS LOG_UUCP LOG_CRON LOG_AUTHPRIV LOG_LOCAL0
-        LOG_LOCAL1 LOG_LOCAL2 LOG_LOCAL3 LOG_LOCAL4 LOG_LOCAL5 LOG_LOCAL6 LOG_LOCAL7 LOG_PID LOG_CONS LOG_ODELAY
-        LOG_NDELAY LOG_NOWAIT LOG_PERROR
-      ]
-      
-      PREDEFINED = %w[
-        $GLOBALS $_SERVER $_GET $_POST $_FILES $_REQUEST $_SESSION $_ENV
-        $_COOKIE $php_errormsg $HTTP_RAW_POST_DATA $http_response_header
-        $argc $argv
-      ]
-      
-      IDENT_KIND = WordList::CaseIgnoring.new(:ident).
-        add(KEYWORDS, :keyword).
-        add(TYPES, :predefined_type).
-        add(LANGUAGE_CONSTRUCTS, :keyword).
-        add(BUILTIN_FUNCTIONS, :predefined).
-        add(CLASSES, :predefined_constant).
-        add(EXCEPTIONS, :exception).
-        add(CONSTANTS, :predefined_constant)
-      
-      VARIABLE_KIND = WordList.new(:local_variable).
-        add(PREDEFINED, :predefined)
-    end
-    
-    module RE  # :nodoc:
-      
-      PHP_START = /
-        <script\s+[^>]*?language\s*=\s*"php"[^>]*?> |
-        <script\s+[^>]*?language\s*=\s*'php'[^>]*?> |
-        <\?php\d? |
-        <\?(?!xml)
-      /xi
-      
-      PHP_END = %r!
-        </script> |
-        \?>
-      !xi
-      
-      HTML_INDICATOR = /<!DOCTYPE html|<(?:html|body|div|p)[> ]/i
-      
-      IDENTIFIER = /[a-z_\x7f-\xFF][a-z0-9_\x7f-\xFF]*/i
-      VARIABLE = /\$#{IDENTIFIER}/
-      
-      OPERATOR = /
-        \.(?!\d)=? |      # dot that is not decimal point, string concatenation
-        && | \|\| |       # logic
-        :: | -> | => |    # scope, member, dictionary
-        \\(?!\n) |        # namespace
-        \+\+ | -- |       # increment, decrement
-        [,;?:()\[\]{}] |  # simple delimiters
-        [-+*\/%&|^]=? |   # ordinary math, binary logic, assignment shortcuts
-        [~$] |            # whatever
-        =& |              # reference assignment
-        [=!]=?=? | <> |   # comparison and assignment
-        <<=? | >>=? | [<>]=?  # comparison and shift
-      /x
-      
-    end
-    
-  protected
-    
-    def scan_tokens encoder, options
-      
-      if check(RE::PHP_START) ||  # starts with <?
-       (match?(/\s*<\S/) && check(/.{1,1000}#{RE::PHP_START}/om)) || # starts with tag and contains <?
-       check(/.{0,1000}#{RE::HTML_INDICATOR}/om) ||
-       check(/.{1,100}#{RE::PHP_START}/om)  # PHP start after max 100 chars
-        # is HTML with embedded PHP, so start with HTML
-        states = [:initial]
-      else
-        # is just PHP, so start with PHP surrounded by HTML
-        states = [:initial, :php]
-      end
-      
-      label_expected = true
-      case_expected = false
-      
-      heredoc_delimiter = nil
-      delimiter = nil
-      modifier = nil
-      
-      until eos?
-        
-        case states.last
-        
-        when :initial  # HTML
-          if match = scan(RE::PHP_START)
-            encoder.text_token match, :inline_delimiter
-            label_expected = true
-            states << :php
-          else
-            match = scan_until(/(?=#{RE::PHP_START})/o) || scan_rest
-            @html_scanner.tokenize match unless match.empty?
-          end
-        
-        when :php
-          if match = scan(/\s+/)
-            encoder.text_token match, :space
-          
-          elsif match = scan(%r! (?m: \/\* (?: .*? \*\/ | .* ) ) | (?://|\#) .*? (?=#{RE::PHP_END}|$) !xo)
-            encoder.text_token match, :comment
-          
-          elsif match = scan(RE::IDENTIFIER)
-            kind = Words::IDENT_KIND[match]
-            if kind == :ident && label_expected && check(/:(?!:)/)
-              kind = :label
-              label_expected = true
-            else
-              label_expected = false
-              if kind == :ident && match =~ /^[A-Z]/
-                kind = :constant
-              elsif kind == :keyword
-                case match
-                when 'class'
-                  states << :class_expected
-                when 'function'
-                  states << :function_expected
-                when 'case', 'default'
-                  case_expected = true
-                end
-              elsif match == 'b' && check(/['"]/)  # binary string literal
-                modifier = match
-                next
-              end
-            end
-            encoder.text_token match, kind
-          
-          elsif match = scan(/(?:\d+\.\d*|\d*\.\d+)(?:e[-+]?\d+)?|\d+e[-+]?\d+/i)
-            label_expected = false
-            encoder.text_token match, :float
-          
-          elsif match = scan(/0x[0-9a-fA-F]+/)
-            label_expected = false
-            encoder.text_token match, :hex
-          
-          elsif match = scan(/\d+/)
-            label_expected = false
-            encoder.text_token match, :integer
-          
-          elsif match = scan(/['"`]/)
-            encoder.begin_group :string
-            if modifier
-              encoder.text_token modifier, :modifier
-              modifier = nil
-            end
-            delimiter = match
-            encoder.text_token match, :delimiter
-            states.push match == "'" ? :sqstring : :dqstring
-          
-          elsif match = scan(RE::VARIABLE)
-            label_expected = false
-            encoder.text_token match, Words::VARIABLE_KIND[match]
-          
-          elsif match = scan(/\{/)
-            encoder.text_token match, :operator
-            label_expected = true
-            states.push :php
-          
-          elsif match = scan(/\}/)
-            if states.size == 1
-              encoder.text_token match, :error
-            else
-              states.pop
-              if states.last.is_a?(::Array)
-                delimiter = states.last[1]
-                states[-1] = states.last[0]
-                encoder.text_token match, :delimiter
-                encoder.end_group :inline
-              else
-                encoder.text_token match, :operator
-                label_expected = true
-              end
-            end
-          
-          elsif match = scan(/@/)
-            label_expected = false
-            encoder.text_token match, :exception
-          
-          elsif match = scan(RE::PHP_END)
-            encoder.text_token match, :inline_delimiter
-            states = [:initial]
-          
-          elsif match = scan(/<<<(?:(#{RE::IDENTIFIER})|"(#{RE::IDENTIFIER})"|'(#{RE::IDENTIFIER})')/o)
-            encoder.begin_group :string
-            # warn 'heredoc in heredoc?' if heredoc_delimiter
-            heredoc_delimiter = Regexp.escape(self[1] || self[2] || self[3])
-            encoder.text_token match, :delimiter
-            states.push self[3] ? :sqstring : :dqstring
-            heredoc_delimiter = /#{heredoc_delimiter}(?=;?$)/
-          
-          elsif match = scan(/#{RE::OPERATOR}/o)
-            label_expected = match == ';'
-            if case_expected
-              label_expected = true if match == ':'
-              case_expected = false
-            end
-            encoder.text_token match, :operator
-          
-          else
-            encoder.text_token getch, :error
-          
-          end
-        
-        when :sqstring
-          if match = scan(heredoc_delimiter ? /[^\\\n]+/ : /[^'\\]+/)
-            encoder.text_token match, :content
-          elsif !heredoc_delimiter && match = scan(/'/)
-            encoder.text_token match, :delimiter
-            encoder.end_group :string
-            delimiter = nil
-            label_expected = false
-            states.pop
-          elsif heredoc_delimiter && match = scan(/\n/)
-            if scan heredoc_delimiter
-              encoder.text_token "\n", :content
-              encoder.text_token matched, :delimiter
-              encoder.end_group :string
-              heredoc_delimiter = nil
-              label_expected = false
-              states.pop
-            else
-              encoder.text_token match, :content
-            end
-          elsif match = scan(heredoc_delimiter ? /\\\\/ : /\\[\\'\n]/)
-            encoder.text_token match, :char
-          elsif match = scan(/\\./m)
-            encoder.text_token match, :content
-          elsif match = scan(/\\/)
-            encoder.text_token match, :error
-          else
-            states.pop
-          end
-        
-        when :dqstring
-          if match = scan(heredoc_delimiter ? /[^${\\\n]+/ : (delimiter == '"' ? /[^"${\\]+/ : /[^`${\\]+/))
-            encoder.text_token match, :content
-          elsif !heredoc_delimiter && match = scan(delimiter == '"' ? /"/ : /`/)
-            encoder.text_token match, :delimiter
-            encoder.end_group :string
-            delimiter = nil
-            label_expected = false
-            states.pop
-          elsif heredoc_delimiter && match = scan(/\n/)
-            if scan heredoc_delimiter
-              encoder.text_token "\n", :content
-              encoder.text_token matched, :delimiter
-              encoder.end_group :string
-              heredoc_delimiter = nil
-              label_expected = false
-              states.pop
-            else
-              encoder.text_token match, :content
-            end
-          elsif match = scan(/\\(?:x[0-9A-Fa-f]{1,2}|[0-7]{1,3})/)
-            encoder.text_token match, :char
-          elsif match = scan(heredoc_delimiter ? /\\[nrtvf\\$]/ : (delimiter == '"' ? /\\[nrtvf\\$"]/ : /\\[nrtvf\\$`]/))
-            encoder.text_token match, :char
-          elsif match = scan(/\\./m)
-            encoder.text_token match, :content
-          elsif match = scan(/\\/)
-            encoder.text_token match, :error
-          elsif match = scan(/#{RE::VARIABLE}/o)
-            if check(/\[#{RE::IDENTIFIER}\]/o)
-              encoder.begin_group :inline
-              encoder.text_token match, :local_variable
-              encoder.text_token scan(/\[/), :operator
-              encoder.text_token scan(/#{RE::IDENTIFIER}/o), :ident
-              encoder.text_token scan(/\]/), :operator
-              encoder.end_group :inline
-            elsif check(/\[/)
-              match << scan(/\[['"]?#{RE::IDENTIFIER}?['"]?\]?/o)
-              encoder.text_token match, :error
-            elsif check(/->#{RE::IDENTIFIER}/o)
-              encoder.begin_group :inline
-              encoder.text_token match, :local_variable
-              encoder.text_token scan(/->/), :operator
-              encoder.text_token scan(/#{RE::IDENTIFIER}/o), :ident
-              encoder.end_group :inline
-            elsif check(/->/)
-              match << scan(/->/)
-              encoder.text_token match, :error
-            else
-              encoder.text_token match, :local_variable
-            end
-          elsif match = scan(/\{/)
-            if check(/\$/)
-              encoder.begin_group :inline
-              states[-1] = [states.last, delimiter]
-              delimiter = nil
-              states.push :php
-              encoder.text_token match, :delimiter
-            else
-              encoder.text_token match, :content
-            end
-          elsif match = scan(/\$\{#{RE::IDENTIFIER}\}/o)
-            encoder.text_token match, :local_variable
-          elsif match = scan(/\$/)
-            encoder.text_token match, :content
-          else
-            states.pop
-          end
-        
-        when :class_expected
-          if match = scan(/\s+/)
-            encoder.text_token match, :space
-          elsif match = scan(/#{RE::IDENTIFIER}/o)
-            encoder.text_token match, :class
-            states.pop
-          else
-            states.pop
-          end
-        
-        when :function_expected
-          if match = scan(/\s+/)
-            encoder.text_token match, :space
-          elsif match = scan(/&/)
-            encoder.text_token match, :operator
-          elsif match = scan(/#{RE::IDENTIFIER}/o)
-            encoder.text_token match, :function
-            states.pop
-          else
-            states.pop
-          end
-        
-        else
-          raise_inspect 'Unknown state!', encoder, states
-        end
-        
-      end
-      
-      encoder
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1d/1d8c43c17d3233bffb7ec0f72aeb2fc2a1c616a9.svn-base
--- /dev/null
+++ b/.svn/pristine/1d/1d8c43c17d3233bffb7ec0f72aeb2fc2a1c616a9.svn-base
@@ -0,0 +1,39 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class CustomValueTest < ActiveSupport::TestCase
+  fixtures :custom_fields, :custom_values, :users
+
+  def test_default_value
+    field = CustomField.find_by_default_value('Default string')
+    assert_not_nil field
+
+    v = CustomValue.new(:custom_field => field)
+    assert_equal 'Default string', v.value
+
+    v = CustomValue.new(:custom_field => field, :value => 'Not empty')
+    assert_equal 'Not empty', v.value
+  end
+
+  def test_sti_polymorphic_association
+    # Rails uses top level sti class for polymorphic association. See #3978.
+    assert !User.find(4).custom_values.empty?
+    assert !CustomValue.find(2).customized.nil?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1e/1e249c4fe7dcd1453c3738c60c059927f1f93080.svn-base
--- /dev/null
+++ b/.svn/pristine/1e/1e249c4fe7dcd1453c3738c60c059927f1f93080.svn-base
@@ -0,0 +1,96 @@
+source 'https://rubygems.org'
+
+gem "rails", "3.2.13"
+gem "jquery-rails", "~> 2.0.2"
+gem "i18n", "~> 0.6.0"
+gem "coderay", "~> 1.0.9"
+gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
+gem "builder", "3.0.0"
+
+# Optional gem for LDAP authentication
+group :ldap do
+  gem "net-ldap", "~> 0.3.1"
+end
+
+# Optional gem for OpenID authentication
+group :openid do
+  gem "ruby-openid", "~> 2.1.4", :require => "openid"
+  gem "rack-openid"
+end
+
+# Optional gem for exporting the gantt to a PNG file, not supported with jruby
+platforms :mri, :mingw do
+  group :rmagick do
+    # RMagick 2 supports ruby 1.9
+    # RMagick 1 would be fine for ruby 1.8 but Bundler does not support
+    # different requirements for the same gem on different platforms
+    gem "rmagick", ">= 2.0.0"
+  end
+end
+
+platforms :jruby do
+  # jruby-openssl is bundled with JRuby 1.7.0
+  gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
+  gem "activerecord-jdbc-adapter", "1.2.5"
+end
+
+# Include database gems for the adapters found in the database
+# configuration file
+require 'erb'
+require 'yaml'
+database_file = File.join(File.dirname(__FILE__), "config/database.yml")
+if File.exist?(database_file)
+  database_config = YAML::load(ERB.new(IO.read(database_file)).result)
+  adapters = database_config.values.map {|c| c['adapter']}.compact.uniq
+  if adapters.any?
+    adapters.each do |adapter|
+      case adapter
+      when 'mysql2'
+        gem "mysql2", "~> 0.3.11", :platforms => [:mri, :mingw]
+        gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
+      when 'mysql'
+        gem "mysql", "~> 2.8.1", :platforms => [:mri, :mingw]
+        gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
+      when /postgresql/
+        gem "pg", ">= 0.11.0", :platforms => [:mri, :mingw]
+        gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
+      when /sqlite3/
+        gem "sqlite3", :platforms => [:mri, :mingw]
+        gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
+      when /sqlserver/
+        gem "tiny_tds", "~> 0.5.1", :platforms => [:mri, :mingw]
+        gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
+      else
+        warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems")
+      end
+    end
+  else
+    warn("No adapter found in config/database.yml, please configure it first")
+  end
+else
+  warn("Please configure your config/database.yml first")
+end
+
+group :development do
+  gem "rdoc", ">= 2.4.2"
+  gem "yard"
+end
+
+group :test do
+  gem "shoulda", "~> 3.3.2"
+  gem "mocha", "~> 0.13.3"
+  gem 'capybara', '~> 2.0.0'
+  gem 'nokogiri', '< 1.6.0'
+end
+
+local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
+if File.exists?(local_gemfile)
+  puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v`
+  instance_eval File.read(local_gemfile)
+end
+
+# Load plugins' Gemfiles
+Dir.glob File.expand_path("../plugins/*/Gemfile", __FILE__) do |file|
+  puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
+  instance_eval File.read(file)
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1e/1e483084ac442168a4ba45984a0f145a415a7cad.svn-base
--- a/.svn/pristine/1e/1e483084ac442168a4ba45984a0f145a415a7cad.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class DocumentObserver < ActiveRecord::Observer
-  def after_create(document)
-    Mailer.deliver_document_added(document) if Setting.notified_events.include?('document_added')
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1e/1e54d19d4970142ec949fe4202f5ffe30b1f8dbf.svn-base
--- /dev/null
+++ b/.svn/pristine/1e/1e54d19d4970142ec949fe4202f5ffe30b1f8dbf.svn-base
@@ -0,0 +1,78 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::DisabledRestApiTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  def setup
+    Setting.rest_api_enabled = '0'
+    Setting.login_required = '1'
+  end
+
+  def teardown
+    Setting.rest_api_enabled = '1'
+    Setting.login_required = '0'
+  end
+
+  def test_with_a_valid_api_token
+    @user = User.generate!
+    @token = Token.create!(:user => @user, :action => 'api')
+
+    get "/news.xml?key=#{@token.value}"
+    assert_response :unauthorized
+    assert_equal User.anonymous, User.current
+
+    get "/news.json?key=#{@token.value}"
+    assert_response :unauthorized
+    assert_equal User.anonymous, User.current
+  end
+
+  def test_with_valid_username_password_http_authentication
+    @user = User.generate! do |user|
+      user.password = 'my_password'
+    end
+
+    get "/news.xml", nil, credentials(@user.login, 'my_password')
+    assert_response :unauthorized
+    assert_equal User.anonymous, User.current
+
+    get "/news.json", nil, credentials(@user.login, 'my_password')
+    assert_response :unauthorized
+    assert_equal User.anonymous, User.current
+  end
+
+  def test_with_valid_token_http_authentication
+    @user = User.generate!
+    @token = Token.create!(:user => @user, :action => 'api')
+
+    get "/news.xml", nil, credentials(@token.value, 'X')
+    assert_response :unauthorized
+    assert_equal User.anonymous, User.current
+
+    get "/news.json", nil, credentials(@token.value, 'X')
+    assert_response :unauthorized
+    assert_equal User.anonymous, User.current
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1e/1e6be947d792b95e6881bfbd4ea45738a1aaae9e.svn-base
--- a/.svn/pristine/1e/1e6be947d792b95e6881bfbd4ea45738a1aaae9e.svn-base
+++ /dev/null
@@ -1,58 +0,0 @@
-# Tests in this file ensure that:
-#
-# * the application /app/[controllers|helpers|models] and /lib 
-#   paths preceed the corresponding plugin paths
-# * the plugin paths are added to $LOAD_PATH in the order in which plugins are 
-#   loaded
-
-require File.dirname(__FILE__) + '/../test_helper'
-
-class LoadPathTest < Test::Unit::TestCase
-  def setup
-    @load_path = expand_paths($LOAD_PATH)
-  end
-  
-  # Not sure if these test actually make sense as this now essentially tests
-  # Rails core functionality. On the other hand Engines relies on this to some
-  # extend so this will choke if something important changes in Rails.
-  
-  # the application app/... and lib/ directories should appear
-  # before any plugin directories
-  
-  def test_application_app_libs_should_precede_all_plugin_app_libs
-    types = %w(app/controllers app/helpers app/models lib)
-    types.each do |t|
-      app_index = load_path_index(File.join(RAILS_ROOT, t))
-      assert_not_nil app_index, "#{t} is missing in $LOAD_PATH"
-      Engines.plugins.each do |plugin|
-        first_plugin_index = load_path_index(File.join(plugin.directory, t))
-        assert(app_index < first_plugin_index) unless first_plugin_index.nil?
-      end
-    end
-  end
-  
-  # the engine directories should appear in the proper order based on
-  # the order they were started  
-  
-  def test_plugin_dirs_should_appear_in_reverse_plugin_loading_order
-    app_paths = %w(app/controllers/ app app/models app/helpers lib)
-    app_paths.map { |p| File.join(RAILS_ROOT, p)}
-    plugin_paths = Engines.plugins.reverse.collect { |plugin| plugin.load_paths.reverse }.flatten    
-    
-    expected_paths = expand_paths(app_paths + plugin_paths)    
-    # only look at those paths that are also present in expected_paths so
-    # the only difference would be in the order of the paths
-    actual_paths = @load_path & expected_paths 
-    
-    assert_equal expected_paths, actual_paths
-  end
-  
-  protected    
-    def expand_paths(paths)
-      paths.collect { |p| File.expand_path(p) }
-    end
-    
-    def load_path_index(dir)
-      @load_path.index(File.expand_path(dir))
-    end  
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1e/1ee7b5168bf92e876c9f4c10698beed4d4ba3f9d.svn-base
--- a/.svn/pristine/1e/1ee7b5168bf92e876c9f4c10698beed4d4ba3f9d.svn-base
+++ /dev/null
@@ -1,1011 +0,0 @@
-fa:
-  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
-  direction: rtl
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y/%m/%d"
-      short: "%b %d"
-      long: "%B %d, %Y"
-      
-    day_names: [ÛŒÚ©â€ŒØ´Ù†Ø¨Ù‡, Ø¯ÙˆØ´Ù†Ø¨Ù‡, Ø³Ù‡â€ŒØ´Ù†Ø¨Ù‡, Ú†Ù‡Ø§Ø±Ø´Ù†Ø¨Ù‡, Ù¾Ù†Ø¬â€ŒØ´Ù†Ø¨Ù‡, Ø¢Ø¯ÛŒÙ†Ù‡, Ø´Ù†Ø¨Ù‡]
-    abbr_day_names: [ÛŒÚ©, Ø¯Ùˆ, Ø³Ù‡, Ú†Ù‡Ø§Ø±, Ù¾Ù†Ø¬, Ø¢Ø¯ÛŒÙ†Ù‡, Ø´Ù†Ø¨Ù‡]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Ú˜Ø§Ù†ÙˆÛŒÙ‡, ÙÙˆØ±ÛŒÙ‡, Ù…Ø§Ø±Ø³, Ø¢ÙˆØ±ÛŒÙ„, Ù…Ù‡, Ú˜ÙˆØ¦Ù†, Ú˜ÙˆØ¦ÛŒÙ‡, Ø§ÙˆØª, Ø³Ù¾ØªØ§Ù…Ø¨Ø±, Ø§Ú©ØªØ¨Ø±, Ù†ÙˆØ§Ù…Ø¨Ø±, Ø¯Ø³Ø§Ù…Ø¨Ø±]
-    abbr_month_names: [~, Ú˜Ø§Ù†, ÙÙˆØ±, Ù…Ø§Ø±, Ø¢ÙˆØ±, Ù…Ù‡, Ú˜ÙˆØ¦Ù†, Ú˜ÙˆØ¦ÛŒÙ‡, Ø§ÙˆØª, Ø³Ù¾Øª, Ø§Ú©Øª, Ù†ÙˆØ§, Ø¯Ø³Ø§]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%Y/%m/%d - %H:%M"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%d %B %Y Ø³Ø§Ø¹Øª %H:%M"
-    am: "ØµØ¨Ø­"
-    pm: "Ø¹ØµØ±"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "Ù†ÛŒÙ… Ø¯Ù‚ÛŒÙ‚Ù‡"
-      less_than_x_seconds:
-        one:   "Ú©Ù…ØªØ± Ø§Ø² 1 Ø«Ø§Ù†ÛŒÙ‡"
-        other: "Ú©Ù…ØªØ± Ø§Ø² %{count} Ø«Ø§Ù†ÛŒÙ‡"
-      x_seconds:
-        one:   "1 Ø«Ø§Ù†ÛŒÙ‡"
-        other: "%{count} Ø«Ø§Ù†ÛŒÙ‡"
-      less_than_x_minutes:
-        one:   "Ú©Ù…ØªØ± Ø§Ø² 1 Ø¯Ù‚ÛŒÙ‚Ù‡"
-        other: "Ú©Ù…ØªØ± Ø§Ø² %{count} Ø¯Ù‚ÛŒÙ‚Ù‡"
-      x_minutes:
-        one:   "1 Ø¯Ù‚ÛŒÙ‚Ù‡"
-        other: "%{count} Ø¯Ù‚ÛŒÙ‚Ù‡"
-      about_x_hours:
-        one:   "Ù†Ø²Ø¯ÛŒÚ© 1 Ø³Ø§Ø¹Øª"
-        other: "Ù†Ø²Ø¯ÛŒÚ© %{count} Ø³Ø§Ø¹Øª"
-      x_days:
-        one:   "1 Ø±ÙˆØ²"
-        other: "%{count} Ø±ÙˆØ²"
-      about_x_months:
-        one:   "Ù†Ø²Ø¯ÛŒÚ© 1 Ù…Ø§Ù‡"
-        other: "Ù†Ø²Ø¯ÛŒÚ© %{count} Ù…Ø§Ù‡"
-      x_months:
-        one:   "1 Ù…Ø§Ù‡"
-        other: "%{count} Ù…Ø§Ù‡"
-      about_x_years:
-        one:   "Ù†Ø²Ø¯ÛŒÚ© 1 Ø³Ø§Ù„"
-        other: "Ù†Ø²Ø¯ÛŒÚ© %{count} Ø³Ø§Ù„"
-      over_x_years:
-        one:   "Ø¨ÛŒØ´ Ø§Ø² 1 Ø³Ø§Ù„"
-        other: "Ø¨ÛŒØ´ Ø§Ø² %{count} Ø³Ø§Ù„"
-      almost_x_years:
-        one:   "Ù†Ø²Ø¯ÛŒÚ© 1 Ø³Ø§Ù„"
-        other: "Ù†Ø²Ø¯ÛŒÚ© %{count} Ø³Ø§Ù„"
-
-  number:
-    # Default format for numbers
-    format:
-      separator: "Ù«" 
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Ø¨Ø§ÛŒØª"
-            other: "Ø¨Ø§ÛŒØª"
-          kb: "Ú©ÛŒÙ„ÙˆØ¨Ø§ÛŒØª"
-          mb: "Ù…Ú¯Ø§Ø¨Ø§ÛŒØª"
-          gb: "Ú¯ÛŒÚ¯Ø§Ø¨Ø§ÛŒØª"
-          tb: "ØªØ±Ø§Ø¨Ø§ÛŒØª"
-
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "Ùˆ"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 Ø§ÛŒØ±Ø§Ø¯ Ø§Ø² Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ Ø§ÛŒÙ† %{model} Ø¬Ù„ÙˆÚ¯ÛŒØ±ÛŒ Ú©Ø±Ø¯"
-          other:  "%{count} Ø§ÛŒØ±Ø§Ø¯ Ø§Ø² Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ Ø§ÛŒÙ† %{model} Ø¬Ù„ÙˆÚ¯ÛŒØ±ÛŒ Ú©Ø±Ø¯"
-      messages:
-        inclusion: "Ø¯Ø± ÙÙ‡Ø±Ø³Øª Ù†ÛŒØ§Ù…Ø¯Ù‡ Ø§Ø³Øª"
-        exclusion: "Ø±Ø²Ø±Ùˆ Ø´Ø¯Ù‡ Ø§Ø³Øª"
-        invalid: "Ù†Ø§Ø¯Ø±Ø³Øª Ø§Ø³Øª"
-        confirmation: "Ø¨Ø§ Ø¨Ø±Ø±Ø³ÛŒ Ø³Ø§Ø²Ú¯Ø§Ø±ÛŒ Ù†Ø¯Ø§Ø±Ø¯"
-        accepted: "Ø¨Ø§ÛŒØ¯ Ù¾Ø°ÛŒØ±ÙØªÙ‡ Ø´ÙˆØ¯"
-        empty: "Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ø¯ ØªÙ‡ÛŒ Ø¨Ø§Ø´Ø¯"
-        blank: "Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ø¯ ØªÙ‡ÛŒ Ø¨Ø§Ø´Ø¯"
-        too_long: "Ø®ÛŒÙ„ÛŒ Ø¨Ù„Ù†Ø¯ Ø§Ø³Øª (Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ %{count} Ù†ÙˆÛŒØ³Ù‡ Ø§Ø³Øª)"
-        too_short: "Ø®ÛŒÙ„ÛŒ Ú©ÙˆØªØ§Ù‡ Ø§Ø³Øª (Ú©Ù…ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ %{count} Ù†ÙˆÛŒØ³Ù‡ Ø§Ø³Øª)"
-        wrong_length: "Ø§Ù†Ø¯Ø§Ø²Ù‡ Ù†Ø§Ø¯Ø±Ø³Øª Ø§Ø³Øª (Ø¨Ø§ÛŒØ¯ %{count} Ù†ÙˆÛŒØ³Ù‡ Ø¨Ø§Ø´Ø¯)"
-        taken: "Ù¾ÛŒØ´ Ø§Ø² Ø§ÛŒÙ† Ú¯Ø±ÙØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª"
-        not_a_number: "Ø´Ù…Ø§Ø±Ù‡ Ø¯Ø±Ø³ØªÛŒ Ù†ÛŒØ³Øª"
-        not_a_date: "ØªØ§Ø±ÛŒØ® Ø¯Ø±Ø³ØªÛŒ Ù†ÛŒØ³Øª"
-        greater_than: "Ø¨Ø§ÛŒØ¯ Ø¨Ø²Ø±Ú¯ØªØ± Ø§Ø² %{count} Ø¨Ø§Ø´Ø¯"
-        greater_than_or_equal_to: "Ø¨Ø§ÛŒØ¯ Ø¨Ø²Ø±Ú¯ØªØ± Ø§Ø² ÛŒØ§ Ø¨Ø±Ø§Ø¨Ø± Ø¨Ø§ %{count} Ø¨Ø§Ø´Ø¯"
-        equal_to: "Ø¨Ø§ÛŒØ¯ Ø¨Ø±Ø§Ø¨Ø± Ø¨Ø§ %{count} Ø¨Ø§Ø´Ø¯"
-        less_than: "Ø¨Ø§ÛŒØ¯ Ú©Ù…ØªØ± Ø§Ø² %{count} Ø¨Ø§Ø´Ø¯"
-        less_than_or_equal_to: "Ø¨Ø§ÛŒØ¯ Ú©Ù…ØªØ± Ø§Ø² ÛŒØ§ Ø¨Ø±Ø§Ø¨Ø± Ø¨Ø§ %{count} Ø¨Ø§Ø´Ø¯"
-        odd: "Ø¨Ø§ÛŒØ¯ ÙØ±Ø¯ Ø¨Ø§Ø´Ø¯"
-        even: "Ø¨Ø§ÛŒØ¯ Ø²ÙˆØ¬ Ø¨Ø§Ø´Ø¯"
-        greater_than_start_date: "Ø¨Ø§ÛŒØ¯ Ø§Ø² ØªØ§Ø±ÛŒØ® Ø¢ØºØ§Ø² Ø¨Ø²Ø±Ú¯ØªØ± Ø¨Ø§Ø´Ø¯"
-        not_same_project: "Ø¨Ù‡ Ù‡Ù…Ø§Ù† Ù¾Ø±ÙˆÚ˜Ù‡ ÙˆØ§Ø¨Ø³ØªÙ‡ Ù†ÛŒØ³Øª"
-        circular_dependency: "Ø§ÛŒÙ† ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ ÛŒÚ© ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ Ø¯Ø§ÛŒØ±Ù‡ ÙˆØ§Ø± Ø®ÙˆØ§Ù‡Ø¯ Ø³Ø§Ø®Øª"
-        cant_link_an_issue_with_a_descendant: "ÛŒÚ© Ù¾ÛŒØ§Ù…Ø¯ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ø¯ Ø¨Ù‡ ÛŒÚ©ÛŒ Ø§Ø² Ø²ÛŒØ± Ú©Ø§Ø±Ù‡Ø§ÛŒØ´ Ù¾ÛŒÙˆÙ†Ø¯ Ø¨Ø®ÙˆØ±Ø¯"
-
-  actionview_instancetag_blank_option: Ú¯Ø²ÛŒÙ†Ø´ Ú©Ù†ÛŒØ¯
-  
-  general_text_No: 'Ø®ÛŒØ±'
-  general_text_Yes: 'Ø¢Ø±ÛŒ'
-  general_text_no: 'Ø®ÛŒØ±'
-  general_text_yes: 'Ø¢Ø±ÛŒ'
-  general_lang_name: 'Persian (Ù¾Ø§Ø±Ø³ÛŒ)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '6'
-  
-  notice_account_updated: Ø­Ø³Ø§Ø¨ Ø´Ù…Ø§ Ø¨Ø±ÙˆØ² Ø´Ø¯.
-  notice_account_invalid_creditentials: Ù†Ø§Ù… Ú©Ø§Ø±Ø¨Ø±ÛŒ ÛŒØ§ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ù†Ø§Ø¯Ø±Ø³Øª Ø§Ø³Øª
-  notice_account_password_updated: Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ø¨Ø±ÙˆØ² Ø´Ø¯
-  notice_account_wrong_password: Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ù†Ø§Ø¯Ø±Ø³Øª Ø§Ø³Øª
-  notice_account_register_done: Ø­Ø³Ø§Ø¨ Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯. Ø¨Ø±Ø§ÛŒ ÙØ¹Ø§Ù„ Ù†Ù…ÙˆØ¯Ù† Ø¢Ù†ØŒ Ø±ÙˆÛŒ Ù¾ÛŒÙˆÙ†Ø¯ÛŒ Ú©Ù‡ Ø¨Ù‡ Ø´Ù…Ø§ Ø§ÛŒÙ…ÛŒÙ„ Ø´Ø¯Ù‡ Ú©Ù„ÛŒÚ© Ú©Ù†ÛŒØ¯.
-  notice_account_unknown_email: Ú©Ø§Ø±Ø¨Ø± Ø´Ù†Ø§Ø®ØªÙ‡ Ù†Ø´Ø¯.
-  notice_can_t_change_password:  Ø§ÛŒÙ† Ø­Ø³Ø§Ø¨ ÛŒÚ© Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ Ø¨ÛŒØ±ÙˆÙ†ÛŒ Ø±Ø§ Ø¨Ù‡ Ú©Ø§Ø± Ú¯Ø±ÙØªÙ‡ Ø§Ø³Øª. Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ† Ú©Ø±Ø¯.
-  notice_account_lost_email_sent: ÛŒÚ© Ø§ÛŒÙ…ÛŒÙ„ Ø¨Ø§ Ø±Ø§Ù‡Ù†Ù…Ø§ÛŒÛŒ Ø¯Ø±Ø¨Ø§Ø±Ù‡ Ú¯Ø²ÛŒÙ†Ø´ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ ØªØ§Ø²Ù‡ Ø¨Ø±Ø§ÛŒ Ø´Ù…Ø§ ÙØ±Ø³ØªØ§Ø¯Ù‡ Ø´Ø¯.
-  notice_account_activated: Ø­Ø³Ø§Ø¨ Ø´Ù…Ø§ ÙØ¹Ø§Ù„ Ø´Ø¯Ù‡ Ø§Ø³Øª. Ø§Ú©Ù†ÙˆÙ† Ù…ÛŒâ€ŒØªÙˆØ§Ù†ÛŒØ¯ ÙˆØ§Ø±Ø¯ Ø´ÙˆÛŒØ¯.
-  notice_successful_create: Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯.
-  notice_successful_update: Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ø¨Ø±ÙˆØ² Ø´Ø¯.
-  notice_successful_delete: Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ø¨Ø±Ø¯Ø§Ø´ØªÙ‡ Ø´Ø¯.
-  notice_successful_connection: Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ù…ØªØµÙ„ Ø´Ø¯.
-  notice_file_not_found: Ø¨Ø±Ú¯Ù‡ Ø¯Ø±Ø®ÙˆØ§Ø³ØªÛŒ Ø´Ù…Ø§ Ø¯Ø± Ø¯Ø³ØªØ±Ø³ Ù†ÛŒØ³Øª ÛŒØ§ Ù¾Ø§Ú© Ø´Ø¯Ù‡ Ø§Ø³Øª.
-  notice_locking_conflict: Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ Ø±Ø§ Ú©Ø§Ø±Ø¨Ø± Ø¯ÛŒÚ¯Ø±ÛŒ Ø¨Ø±ÙˆØ² Ú©Ø±Ø¯Ù‡ Ø§Ø³Øª.
-  notice_not_authorized: Ø´Ù…Ø§ Ø¨Ù‡ Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡ Ø¯Ø³ØªØ±Ø³ÛŒ Ù†Ø¯Ø§Ø±ÛŒØ¯.
-  notice_not_authorized_archived_project: Ù¾Ø±ÙˆÚ˜Ù‡ Ø¯Ø±Ø®ÙˆØ§Ø³ØªÛŒ Ø´Ù…Ø§ Ø¨Ø§ÛŒÚ¯Ø§Ù†ÛŒ Ø´Ø¯Ù‡ Ø§Ø³Øª.
-  notice_email_sent: "ÛŒÚ© Ø§ÛŒÙ…ÛŒÙ„ Ø¨Ù‡ %{value} ÙØ±Ø³ØªØ§Ø¯Ù‡ Ø´Ø¯."
-  notice_email_error: "ÛŒÚ© Ø§ÛŒØ±Ø§Ø¯ Ø¯Ø± ÙØ±Ø³ØªØ§Ø¯Ù† Ø§ÛŒÙ…ÛŒÙ„ Ù¾ÛŒØ´ Ø¢Ù…Ø¯ (%{value})."
-  notice_feeds_access_key_reseted: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ RSS Ø´Ù…Ø§ Ø¨Ø§Ø²Ù†Ø´Ø§Ù†ÛŒ Ø´Ø¯.
-  notice_api_access_key_reseted: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ API Ø´Ù…Ø§ Ø¨Ø§Ø²Ù†Ø´Ø§Ù†ÛŒ Ø´Ø¯.
-  notice_failed_to_save_issues: "Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ %{count} Ù¾ÛŒØ§Ù…Ø¯ Ø§Ø² %{total} Ù¾ÛŒØ§Ù…Ø¯ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡ Ø´Ú©Ø³Øª Ø®ÙˆØ±Ø¯: %{ids}."
-  notice_failed_to_save_members: "Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ Ø§Ø¹Ø¶Ø§ Ø´Ú©Ø³Øª Ø®ÙˆØ±Ø¯: %{errors}."
-  notice_no_issue_selected: "Ù‡ÛŒÚ† Ù¾ÛŒØ§Ù…Ø¯ÛŒ Ø¨Ø±Ú¯Ø²ÛŒØ¯Ù‡ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª! Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ ÙˆÛŒØ±Ø§ÛŒØ´ Ú©Ù†ÛŒØ¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯."
-  notice_account_pending: "Ø­Ø³Ø§Ø¨ Ø´Ù…Ø§ Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯ Ùˆ Ø§Ú©Ù†ÙˆÙ† Ú†Ø´Ù… Ø¨Ù‡ Ø±Ø§Ù‡ Ø±ÙˆØ§Ø¯ÛŒØ¯ Ø³Ø±Ù¾Ø±Ø³Øª Ø§Ø³Øª."
-  notice_default_data_loaded: Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ø¨Ø§ Ù…ÙˆÙÙ‚ÛŒØª Ø¨Ø§Ø± Ø´Ø¯.
-  notice_unable_delete_version: Ù†Ú¯Ø§Ø±Ø´ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù¾Ø§Ú© Ú©Ø±Ø¯.
-  notice_unable_delete_time_entry: Ø²Ù…Ø§Ù† Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù¾Ø§Ú© Ú©Ø±Ø¯.
-  notice_issue_done_ratios_updated: Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡ Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø±ÙˆØ² Ø´Ø¯.
-  notice_gantt_chart_truncated: "Ù†Ù…ÙˆØ¯Ø§Ø± Ø¨Ø±ÛŒØ¯Ù‡ Ø´Ø¯ Ú†ÙˆÙ† Ø§Ø² Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø´Ù…Ø§Ø±ÛŒ Ú©Ù‡ Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù†Ø´Ø§Ù† Ø¯Ø§Ø¯ Ø¨Ø²Ú¯ØªØ± Ø§Ø³Øª (%{max})."
-  
-  error_can_t_load_default_data: "Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ø¯ Ø¨Ø§Ø± Ø´ÙˆØ¯: %{value}"
-  error_scm_not_found: "Ø¨Ø®Ø´ ÛŒØ§ Ù†Ú¯Ø§Ø±Ø´ Ø¯Ø± Ø§Ù†Ø¨Ø§Ø±Ù‡ Ù¾ÛŒØ¯Ø§ Ù†Ø´Ø¯."
-  error_scm_command_failed: "Ø§ÛŒØ±Ø§Ø¯ÛŒ Ø¯Ø± Ø¯Ø³ØªØ±Ø³ÛŒ Ø¨Ù‡ Ø§Ù†Ø¨Ø§Ø±Ù‡ Ù¾ÛŒØ´ Ø¢Ù…Ø¯: %{value}"
-  error_scm_annotate: "Ø¨Ø®Ø´ Ù¾ÛŒØ¯Ø§ Ù†Ø´Ø¯ ÛŒØ§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¨Ø±Ø§ÛŒ Ø¢Ù† ÛŒØ§Ø¯Ø¯Ø§Ø´Øª Ù†ÙˆØ´Øª."
-  error_issue_not_found_in_project: 'Ù¾ÛŒØ§Ù…Ø¯ Ù¾ÛŒØ¯Ø§ Ù†Ø´Ø¯ ÛŒØ§ Ø¨Ù‡ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ ÙˆØ§Ø¨Ø³ØªÙ‡ Ù†ÛŒØ³Øª.'
-  error_no_tracker_in_project: 'Ù‡ÛŒÚ† Ù¾ÛŒÚ¯Ø±Ø¯ÛŒ Ø¨Ù‡ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ Ù¾ÛŒÙˆØ³ØªÙ‡ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª. Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡ Ø±Ø§ Ø¨Ø±Ø±Ø³ÛŒ Ú©Ù†ÛŒØ¯.'
-  error_no_default_issue_status: 'Ù‡ÛŒÚ† ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡â€ŒØ§ÛŒ Ù…Ø´Ø®Øµ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª. Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ø±Ø§ Ø¨Ø±Ø±Ø³ÛŒ Ú©Ù†ÛŒØ¯ (Ø¨Ù‡ Â«Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ -> ÙˆØ¶Ø¹ÛŒØªâ€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯Â» Ø¨Ø±ÙˆÛŒØ¯).'
-  error_can_not_delete_custom_field: ÙÛŒÙ„Ø¯ Ø³ÙØ§Ø±Ø´ÛŒ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù¾Ø§Ú© Ú©Ø±Ø¯.
-  error_can_not_delete_tracker: "Ø§ÛŒÙ† Ù¾ÛŒÚ¯Ø±Ø¯ Ø¯Ø§Ø±Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯ Ø§Ø³Øª Ùˆ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¢Ù† Ø±Ø§ Ù¾Ø§Ú© Ú©Ø±Ø¯."
-  error_can_not_remove_role: "Ø§ÛŒÙ† Ù†Ù‚Ø´ Ø¨Ù‡ Ú©Ø§Ø± Ú¯Ø±ÙØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª Ùˆ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¢Ù† Ø±Ø§ Ù¾Ø§Ú© Ú©Ø±Ø¯."
-  error_can_not_reopen_issue_on_closed_version: 'ÛŒÚ© Ù¾ÛŒØ§Ù…Ø¯ Ú©Ù‡ Ø¨Ù‡ ÛŒÚ© Ù†Ú¯Ø§Ø±Ø´ Ø¨Ø³ØªÙ‡ Ø´Ø¯Ù‡ ÙˆØ§Ø¨Ø³ØªÙ‡ Ø§Ø³Øª Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¨Ø§Ø² Ú©Ø±Ø¯.'
-  error_can_not_archive_project: Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ø¨Ø§ÛŒÚ¯Ø§Ù†ÛŒ Ú©Ø±Ø¯.
-  error_issue_done_ratios_not_updated: "Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡ Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø±ÙˆØ² Ù†Ø´Ø¯."
-  error_workflow_copy_source: 'ÛŒÚ© Ù¾ÛŒÚ¯Ø±Ø¯ ÛŒØ§ Ù†Ù‚Ø´ Ù…Ù†Ø¨Ø¹ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯.'
-  error_workflow_copy_target: 'Ù¾ÛŒÚ¯Ø±Ø¯Ù‡Ø§ ÛŒØ§ Ù†Ù‚Ø´â€ŒÙ‡Ø§ÛŒ Ù…Ù‚ØµØ¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯.'
-  error_unable_delete_issue_status: 'ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯ Ø±Ø§ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù¾Ø§Ú© Ú©Ø±Ø¯.'
-  error_unable_to_connect: "Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù† Ù…ØªØµÙ„ Ø´Ø¯ (%{value})"
-  warning_attachments_not_saved: "%{count} Ù¾Ø±ÙˆÙ†Ø¯Ù‡ Ø°Ø®ÛŒØ±Ù‡ Ù†Ø´Ø¯."
-  
-  mail_subject_lost_password: "Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ø­Ø³Ø§Ø¨ %{value} Ø´Ù…Ø§"
-  mail_body_lost_password: 'Ø¨Ø±Ø§ÛŒ Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ†ÛŒ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ Ø®ÙˆØ¯ØŒ Ø¨Ø± Ø±ÙˆÛŒ Ù¾ÛŒÙˆÙ†Ø¯ Ø²ÛŒØ± Ú©Ù„ÛŒÚ© Ú©Ù†ÛŒØ¯:'
-  mail_subject_register: "ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ %{value} Ø´Ù…Ø§"
-  mail_body_register: 'Ø¨Ø±Ø§ÛŒ ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ Ø®ÙˆØ¯ØŒ Ø¨Ø± Ø±ÙˆÛŒ Ù¾ÛŒÙˆÙ†Ø¯ Ø²ÛŒØ± Ú©Ù„ÛŒÚ© Ú©Ù†ÛŒØ¯:'
-  mail_body_account_information_external: "Ø´Ù…Ø§ Ù…ÛŒâ€ŒØªÙˆØ§Ù†ÛŒØ¯ Ø­Ø³Ø§Ø¨ %{value} Ø®ÙˆØ¯ Ø±Ø§ Ø¨Ø±Ø§ÛŒ ÙˆØ±ÙˆØ¯ Ø¨Ù‡ Ú©Ø§Ø± Ø¨Ø±ÛŒØ¯."
-  mail_body_account_information: Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ø­Ø³Ø§Ø¨ Ø´Ù…Ø§
-  mail_subject_account_activation_request: "Ø¯Ø±Ø®ÙˆØ§Ø³Øª ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ %{value}"
-  mail_body_account_activation_request: "ÛŒÚ© Ú©Ø§Ø±Ø¨Ø± ØªØ§Ø²Ù‡ (%{value}) Ù†Ø§Ù…Ù†ÙˆÛŒØ³ÛŒ Ú©Ø±Ø¯Ù‡ Ø§Ø³Øª. Ø§ÛŒÙ† Ø­Ø³Ø§Ø¨ Ú†Ø´Ù… Ø¨Ù‡ Ø±Ø§Ù‡ Ø±ÙˆØ§Ø¯ÛŒØ¯ Ø´Ù…Ø§Ø³Øª:"
-  mail_subject_reminder: "Ø²Ù…Ø§Ù† Ø±Ø³ÛŒØ¯Ú¯ÛŒ Ø¨Ù‡ %{count} Ù¾ÛŒØ§Ù…Ø¯ Ø¯Ø± %{days} Ø±ÙˆØ² Ø¢ÛŒÙ†Ø¯Ù‡ Ø³Ø± Ù…ÛŒâ€ŒØ±Ø³Ø¯"
-  mail_body_reminder: "Ø²Ù…Ø§Ù† Ø±Ø³ÛŒØ¯Ú¯ÛŒ Ø¨Ù‡ %{count} Ù¾ÛŒØ§Ù…Ø¯ Ú©Ù‡ Ø¨Ù‡ Ø´Ù…Ø§ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡ Ø§Ø³ØªØŒ Ø¯Ø± %{days} Ø±ÙˆØ² Ø¢ÛŒÙ†Ø¯Ù‡ Ø³Ø± Ù…ÛŒâ€ŒØ±Ø³Ø¯:"
-  mail_subject_wiki_content_added: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯"
-  mail_body_wiki_content_added: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯."
-  mail_subject_wiki_content_updated: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø¨Ø±ÙˆØ² Ø´Ø¯"
-  mail_body_wiki_content_updated: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø¨Ø±ÙˆØ² Ø´Ø¯."
-  
-  gui_validation_error: 1 Ø§ÛŒØ±Ø§Ø¯
-  gui_validation_error_plural: "%{count} Ø§ÛŒØ±Ø§Ø¯"
-  
-  field_name: Ù†Ø§Ù…
-  field_description: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
-  field_summary: Ø®Ù„Ø§ØµÙ‡
-  field_is_required: Ø§Ù„Ø²Ø§Ù…ÛŒ
-  field_firstname: Ù†Ø§Ù… Ú©ÙˆÚ†Ú©
-  field_lastname: Ù†Ø§Ù… Ø®Ø§Ù†ÙˆØ§Ø¯Ú¯ÛŒ
-  field_mail: Ø§ÛŒÙ…ÛŒÙ„
-  field_filename: Ù¾Ø±ÙˆÙ†Ø¯Ù‡
-  field_filesize: Ø§Ù†Ø¯Ø§Ø²Ù‡
-  field_downloads: Ø¯Ø±ÛŒØ§ÙØªâ€ŒÙ‡Ø§
-  field_author: Ù†ÙˆÛŒØ³Ù†Ø¯Ù‡
-  field_created_on: Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯Ù‡ Ø¯Ø±
-  field_updated_on: Ø¨Ø±ÙˆØ² Ø´Ø¯Ù‡ Ø¯Ø±
-  field_field_format: Ù‚Ø§Ù„Ø¨
-  field_is_for_all: Ø¨Ø±Ø§ÛŒ Ù‡Ù…Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
-  field_possible_values: Ù…Ù‚Ø§Ø¯ÛŒØ± Ù…Ù…Ú©Ù†
-  field_regexp: Ø¹Ø¨Ø§Ø±Øª Ù…Ù†Ø¸Ù…
-  field_min_length: Ú©Ù…ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡
-  field_max_length: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡
-  field_value: Ù…Ù‚Ø¯Ø§Ø±
-  field_category: Ø¯Ø³ØªÙ‡
-  field_title: Ø¹Ù†ÙˆØ§Ù†
-  field_project: Ù¾Ø±ÙˆÚ˜Ù‡
-  field_issue: Ù¾ÛŒØ§Ù…Ø¯
-  field_status: ÙˆØ¶Ø¹ÛŒØª
-  field_notes: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
-  field_is_closed: Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø³ØªÙ‡ Ø´Ø¯Ù‡
-  field_is_default: Ù…Ù‚Ø¯Ø§Ø± Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
-  field_tracker: Ù¾ÛŒÚ¯Ø±Ø¯
-  field_subject: Ù…ÙˆØ¶ÙˆØ¹
-  field_due_date: Ø²Ù…Ø§Ù† Ø³Ø±Ø±Ø³ÛŒØ¯
-  field_assigned_to: ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡ Ø¨Ù‡
-  field_priority: Ø¨Ø±ØªØ±ÛŒ
-  field_fixed_version: Ù†Ú¯Ø§Ø±Ø´ Ù‡Ø¯Ù
-  field_user: Ú©Ø§Ø±Ø¨Ø±
-  field_principal: Ø¯Ø³ØªÙˆØ± Ø¯Ù‡Ù†Ø¯Ù‡
-  field_role: Ù†Ù‚Ø´
-  field_homepage: Ø¨Ø±Ú¯Ù‡ Ø®Ø§Ù†Ù‡
-  field_is_public: Ù‡Ù…Ú¯Ø§Ù†ÛŒ
-  field_parent: Ù¾Ø±ÙˆÚ˜Ù‡ Ù¾Ø¯Ø±
-  field_is_in_roadmap: Ø§ÛŒÙ† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ø¯Ø± Ú†Ø´Ù…â€ŒØ§Ù†Ø¯Ø§Ø² Ù†Ø´Ø§Ù† Ø¯Ø§Ø¯Ù‡ Ø´ÙˆÙ†Ø¯
-  field_login: ÙˆØ±ÙˆØ¯
-  field_mail_notification: Ø¢Ú¯Ø§Ù‡ Ø³Ø§Ø²ÛŒâ€ŒÙ‡Ø§ÛŒ Ø§ÛŒÙ…ÛŒÙ„ÛŒ
-  field_admin: Ø³Ø±Ù¾Ø±Ø³Øª
-  field_last_login_on: Ø¢Ø®Ø±ÛŒÙ† ÙˆØ±ÙˆØ¯
-  field_language: Ø²Ø¨Ø§Ù†
-  field_effective_date: ØªØ§Ø±ÛŒØ®
-  field_password: Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
-  field_new_password: Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡ ØªØ§Ø²Ù‡
-  field_password_confirmation: Ø¨Ø±Ø±Ø³ÛŒ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
-  field_version: Ù†Ú¯Ø§Ø±Ø´
-  field_type: Ú¯ÙˆÙ†Ù‡
-  field_host: Ù…ÛŒØ²Ø¨Ø§Ù†
-  field_port: Ø¯Ø±Ú¯Ø§Ù‡
-  field_account: Ø­Ø³Ø§Ø¨
-  field_base_dn: DN Ù¾Ø§ÛŒÙ‡
-  field_attr_login: Ù†Ø´Ø§Ù†Ù‡ ÙˆØ±ÙˆØ¯
-  field_attr_firstname: Ù†Ø´Ø§Ù†Ù‡ Ù†Ø§Ù… Ú©ÙˆÚ†Ú©
-  field_attr_lastname: Ù†Ø´Ø§Ù†Ù‡ Ù†Ø§Ù… Ø®Ø§Ù†ÙˆØ§Ø¯Ú¯ÛŒ
-  field_attr_mail: Ù†Ø´Ø§Ù†Ù‡ Ø§ÛŒÙ…ÛŒÙ„
-  field_onthefly: Ø³Ø§Ø®Øª Ú©Ø§Ø±Ø¨Ø± Ø¨ÛŒØ¯Ø±Ù†Ú¯
-  field_start_date: ØªØ§Ø±ÛŒØ® Ø¢ØºØ§Ø²
-  field_done_ratio: Ùª Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡
-  field_auth_source: Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ
-  field_hide_mail: Ø§ÛŒÙ…ÛŒÙ„ Ù…Ù† Ù¾Ù†Ù‡Ø§Ù† Ø´ÙˆØ¯
-  field_comments: Ø¯ÛŒØ¯Ú¯Ø§Ù‡
-  field_url: Ù†Ø´Ø§Ù†ÛŒ
-  field_start_page: Ø¨Ø±Ú¯Ù‡ Ø¢ØºØ§Ø²
-  field_subproject: Ø²ÛŒØ± Ù¾Ø±ÙˆÚ˜Ù‡
-  field_hours: Ø³Ø§Ø¹Øªâ€Œ
-  field_activity: Ú¯Ø²Ø§Ø±Ø´
-  field_spent_on: Ø¯Ø± ØªØ§Ø±ÛŒØ®
-  field_identifier: Ø´Ù†Ø§Ø³Ù‡
-  field_is_filter: Ù¾Ø§Ù„Ø§ÛŒØ´ Ù¾Ø°ÛŒØ±
-  field_issue_to: Ù¾ÛŒØ§Ù…Ø¯ ÙˆØ§Ø¨Ø³ØªÙ‡
-  field_delay: Ø¯ÛŒØ±Ú©Ø±Ø¯
-  field_assignable: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ù†Ø¯ Ø¨Ù‡ Ø§ÛŒÙ† Ù†Ù‚Ø´ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯
-  field_redirect_existing_links: Ù¾ÛŒÙˆÙ†Ø¯Ù‡Ø§ÛŒ Ù¾ÛŒØ´ÛŒÙ†  Ø¨Ù‡ Ù¾ÛŒÙˆÙ†Ø¯ ØªØ§Ø²Ù‡ Ø±Ø§Ù‡Ù†Ù…Ø§ÛŒÛŒ Ø´ÙˆÙ†Ø¯
-  field_estimated_hours: Ø²Ù…Ø§Ù† Ø¨Ø±Ø¢ÙˆØ±Ø¯ Ø´Ø¯Ù‡
-  field_column_names: Ø³ØªÙˆÙ†â€ŒÙ‡Ø§
-  field_time_entries: Ø²Ù…Ø§Ù† Ù†ÙˆØ´ØªÙ†
-  field_time_zone: Ù¾Ù‡Ù†Ù‡ Ø²Ù…Ø§Ù†ÛŒ
-  field_searchable: Ø¬Ø³ØªØ¬Ùˆ Ù¾Ø°ÛŒØ±
-  field_default_value: Ù…Ù‚Ø¯Ø§Ø± Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
-  field_comments_sorting: Ù†Ù…Ø§ÛŒØ´ Ø¯ÛŒØ¯Ú¯Ø§Ù‡â€ŒÙ‡Ø§
-  field_parent_title: Ø¨Ø±Ú¯Ù‡ Ù¾Ø¯Ø±
-  field_editable: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾Ø°ÛŒØ±
-  field_watcher: Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†
-  field_identity_url: Ù†Ø´Ø§Ù†ÛŒ OpenID
-  field_content: Ù…Ø­ØªÙˆØ§
-  field_group_by: Ø¯Ø³ØªÙ‡ Ø¨Ù†Ø¯ÛŒ Ø¨Ø§
-  field_sharing: Ø§Ø´ØªØ±Ø§Ú© Ú¯Ø°Ø§Ø±ÛŒ
-  field_parent_issue: Ú©Ø§Ø± Ù¾Ø¯Ø±
-  field_member_of_group: "Ø¯Ø³ØªÙ‡ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯Ù‡"
-  field_assigned_to_role: "Ù†Ù‚Ø´ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯Ù‡"
-  field_text: ÙÛŒÙ„Ø¯ Ù…ØªÙ†ÛŒ
-  field_visible: Ø¢Ø´Ú©Ø§Ø±
-  
-  setting_app_title: Ù†Ø§Ù… Ø¨Ø±Ù†Ø§Ù…Ù‡
-  setting_app_subtitle: Ø²ÛŒØ±Ù†Ø§Ù… Ø¨Ø±Ù†Ø§Ù…Ù‡
-  setting_welcome_text: Ù†ÙˆØ´ØªØ§Ø± Ø®ÙˆØ´â€ŒØ¢Ù…Ø¯ Ú¯ÙˆÛŒÛŒ
-  setting_default_language: Ø²Ø¨Ø§Ù† Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
-  setting_login_required: Ø§Ù„Ø²Ø§Ù…ÛŒ Ø¨ÙˆØ¯Ù† ÙˆØ±ÙˆØ¯
-  setting_self_registration: Ø®ÙˆØ¯ Ù†Ø§Ù… Ù†ÙˆÛŒØ³ÛŒ
-  setting_attachment_max_size: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ù¾ÛŒÙˆØ³Øª
-  setting_issues_export_limit: Ú©Ø±Ø§Ù†Ù‡ ØµØ¯ÙˆØ± Ù¾ÛŒÛŒØ§Ù…Ø¯Ù‡Ø§
-  setting_mail_from: Ù†Ø´Ø§Ù†ÛŒ ÙØ±Ø³ØªÙ†Ø¯Ù‡ Ø§ÛŒÙ…ÛŒÙ„
-  setting_bcc_recipients: Ú¯ÛŒØ±Ù†Ø¯Ú¯Ø§Ù† Ø§ÛŒÙ…ÛŒÙ„ Ø¯ÛŒØ¯Ù‡ Ù†Ø´ÙˆÙ†Ø¯ (bcc)
-  setting_plain_text_mail: Ø§ÛŒÙ…ÛŒÙ„ Ù†ÙˆØ´ØªÙ‡ Ø³Ø§Ø¯Ù‡ (Ø¨Ø¯ÙˆÙ† HTML)
-  setting_host_name: Ù†Ø§Ù… Ù…ÛŒØ²Ø¨Ø§Ù† Ùˆ Ù†Ø´Ø§Ù†ÛŒ
-  setting_text_formatting: Ù‚Ø§Ù„Ø¨ Ø¨Ù†Ø¯ÛŒ Ù†ÙˆØ´ØªÙ‡
-  setting_wiki_compression: ÙØ´Ø±Ø¯Ù‡â€ŒØ³Ø§Ø²ÛŒ Ù¾ÛŒØ´ÛŒÙ†Ù‡ ÙˆÛŒÚ©ÛŒ
-  setting_feeds_limit: Ú©Ø±Ø§Ù†Ù‡ Ù…Ø­ØªÙˆØ§ÛŒ Ø®ÙˆØ±Ø§Ú©
-  setting_default_projects_public: Ø­Ø§Ù„Øª Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ ØªØ§Ø²Ù‡ØŒ Ù‡Ù…Ú¯Ø§Ù†ÛŒ Ø§Ø³Øª
-  setting_autofetch_changesets: Ø¯Ø±ÛŒØ§ÙØª Ø®ÙˆØ¯Ú©Ø§Ø± ØªØºÛŒÛŒØ±Ø§Øª
-  setting_sys_api_enabled: ÙØ¹Ø§Ù„ Ø³Ø§Ø²ÛŒ ÙˆØ¨ Ø³Ø±ÙˆÛŒØ³ Ø¨Ø±Ø§ÛŒ Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡
-  setting_commit_ref_keywords: Ú©Ù„ÛŒØ¯ÙˆØ§Ú˜Ù‡â€ŒÙ‡Ø§ÛŒ Ù†Ø´Ø§Ù†Ù‡
-  setting_commit_fix_keywords: Ú©Ù„ÛŒØ¯ÙˆØ§Ú˜Ù‡â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¬Ø§Ù…
-  setting_autologin: ÙˆØ±ÙˆØ¯ Ø®ÙˆØ¯Ú©Ø§Ø±
-  setting_date_format: Ù‚Ø§Ù„Ø¨ ØªØ§Ø±ÛŒØ®
-  setting_time_format: Ù‚Ø§Ù„Ø¨ Ø²Ù…Ø§Ù†
-  setting_cross_project_issue_relations: ØªÙˆØ§Ù†Ø§ÛŒÛŒ ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ Ù…ÛŒØ§Ù† Ù¾Ø±ÙˆÚ˜Ù‡â€ŒØ§ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  setting_issue_list_default_columns: Ø³ØªÙˆÙ†â€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø± ÙÙ‡Ø±Ø³Øª Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  setting_emails_header: Ø³Ø±Ù†ÙˆÛŒØ³ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§
-  setting_emails_footer: Ù¾Ø§Ù†ÙˆÛŒØ³ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§
-  setting_protocol: Ù¾ÛŒÙˆÙ†Ø¯Ù†Ø§Ù…Ù‡
-  setting_per_page_options: Ú¯Ø²ÛŒÙ†Ù‡â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ù‡Ø± Ø¨Ø±Ú¯
-  setting_user_format: Ù‚Ø§Ù„Ø¨ Ù†Ù…Ø§ÛŒØ´ÛŒ Ú©Ø§Ø±Ø¨Ø±Ø§Ù†
-  setting_activity_days_default: Ø±ÙˆØ²Ù‡Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø± Ú¯Ø²Ø§Ø±Ø´ Ù¾Ø±ÙˆÚ˜Ù‡
-  setting_display_subprojects_issues: Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ù†Ù…Ø§ÛŒØ´ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡ Ø¯Ø± Ù¾Ø±ÙˆÚ˜Ù‡ Ù¾Ø¯Ø±
-  setting_enabled_scm: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ SCM
-  setting_mail_handler_body_delimiters: "Ø¨Ø±ÛŒØ¯Ù† Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ Ù¾Ø³ Ø§Ø² ÛŒÚ©ÛŒ Ø§Ø² Ø§ÛŒÙ† Ø±Ø¯ÛŒÙâ€ŒÙ‡Ø§"
-  setting_mail_handler_api_enabled: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ ÙˆØ¨ Ø³Ø±ÙˆÛŒØ³ Ø¨Ø±Ø§ÛŒ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ÛŒ Ø¢Ù…Ø¯Ù‡
-  setting_mail_handler_api_key: Ú©Ù„ÛŒØ¯ API
-  setting_sequential_project_identifiers: Ø³Ø§Ø®Øª Ù¾Ø´Øª Ø³Ø± Ù‡Ù… Ø´Ù†Ø§Ø³Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡
-  setting_gravatar_enabled: Ú©Ø§Ø±Ø¨Ø±Ø¯ Gravatar Ø¨Ø±Ø§ÛŒ Ø¹Ú©Ø³ Ú©Ø§Ø±Ø¨Ø±
-  setting_gravatar_default: Ø¹Ú©Ø³ Gravatar Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
-  setting_diff_max_lines_displayed: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø±Ø¯ÛŒÙâ€ŒÙ‡Ø§ÛŒ ØªÙØ§ÙˆØª Ù†Ø´Ø§Ù† Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡
-  setting_file_max_size_displayed: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø±ÙˆÙ† Ø®Ø·ÛŒ
-  setting_repository_log_display_limit: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø´Ù…Ø§Ø± Ù†Ú¯Ø§Ø±Ø´â€ŒÙ‡Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø± Ú¯Ø²Ø§Ø±Ø´ Ù¾Ø±ÙˆÙ†Ø¯Ù‡
-  setting_openid: Ù¾Ø°ÛŒØ±Ø´ ÙˆØ±ÙˆØ¯ Ùˆ Ù†Ø§Ù… Ù†ÙˆÛŒØ³ÛŒ Ø¨Ø§ OpenID
-  setting_password_min_length: Ú©Ù…ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
-  setting_new_project_user_role_id: Ù†Ù‚Ø´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¨Ù‡ Ú©Ø§Ø±Ø¨Ø±ÛŒ Ú©Ù‡ Ø³Ø±Ù¾Ø±Ø³Øª Ù†ÛŒØ³Øª Ùˆ Ù¾Ø±ÙˆÚ˜Ù‡ Ù…ÛŒâ€ŒØ³Ø§Ø²Ø¯
-  setting_default_projects_modules: Ù¾ÛŒÙ…Ø§Ù†Ù‡â€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ ÙØ¹Ø§Ù„ Ø¨Ø±Ø§ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ ØªØ§Ø²Ù‡
-  setting_issue_done_ratio: Ø¨Ø±Ø¢ÙˆØ±Ø¯ Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡ Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø§
-  setting_issue_done_ratio_issue_field: Ú©Ø§Ø±Ø¨Ø±Ø¯ ÙÛŒÙ„Ø¯ Ù¾ÛŒØ§Ù…Ø¯
-  setting_issue_done_ratio_issue_status: Ú©Ø§Ø±Ø¨Ø±Ø¯ ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯
-  setting_start_of_week: Ø¢ØºØ§Ø² Ú¯Ø§Ù‡Ø´Ù…Ø§Ø± Ø§Ø²
-  setting_rest_api_enabled: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ ÙˆØ¨ Ø³Ø±ÙˆÛŒØ³â€ŒÙ‡Ø§ÛŒ REST
-  setting_cache_formatted_text: Ù†Ù‡Ø§Ù† Ø³Ø§Ø²ÛŒ Ù†ÙˆØ´ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ù‚Ø§Ù„Ø¨ Ø¨Ù†Ø¯ÛŒ Ø´Ø¯Ù‡
-  setting_default_notification_option: Ø¢Ú¯Ø§Ù‡ Ø³Ø§Ø²ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
-  setting_commit_logtime_enabled: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
-  setting_commit_logtime_activity_id: Ú©Ø§Ø± Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
-  setting_gantt_items_limit: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø´Ù…Ø§Ø± Ø¨Ø®Ø´â€ŒÙ‡Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù‡ Ø´Ø¯Ù‡ Ø¯Ø± Ù†Ù…ÙˆØ¯Ø§Ø± Ú¯Ø§Ù†Øª
-  
-  permission_add_project: Ø³Ø§Ø®Øª Ù¾Ø±ÙˆÚ˜Ù‡
-  permission_add_subprojects: Ø³Ø§Ø®Øª Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡
-  permission_edit_project: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾Ø±ÙˆÚ˜Ù‡
-  permission_select_project_modules: Ú¯Ø²ÛŒÙ†Ø´ Ù¾ÛŒÙ…Ø§Ù†Ù‡â€ŒÙ‡Ø§ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡
-  permission_manage_members: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø§Ø¹Ø¶Ø§
-  permission_manage_project_activities: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ú©Ø§Ø±Ù‡Ø§ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡
-  permission_manage_versions: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù†Ú¯Ø§Ø±Ø´â€ŒÙ‡Ø§
-  permission_manage_categories: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø¯Ø³ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯
-  permission_view_issues: Ø¯ÛŒØ¯Ù† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  permission_add_issues: Ø§ÙØ²ÙˆØ¯Ù† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  permission_edit_issues: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  permission_manage_issue_relations: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  permission_add_issue_notes: Ø§ÙØ²ÙˆØ¯Ù† ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
-  permission_edit_issue_notes: ÙˆÛŒØ±Ø§ÛŒØ´ ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
-  permission_edit_own_issue_notes: ÙˆÛŒØ±Ø§ÛŒØ´ ÛŒØ§Ø¯Ø¯Ø§Ø´Øª Ø®ÙˆØ¯
-  permission_move_issues: Ø¬Ø§Ø¨Ø¬Ø§ÛŒÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  permission_delete_issues: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  permission_manage_public_queries: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÙ‡Ø§ÛŒ Ù‡Ù…Ú¯Ø§Ù†ÛŒ
-  permission_save_queries: Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒ Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÙ‡Ø§
-  permission_view_gantt: Ø¯ÛŒØ¯Ù† Ù†Ù…ÙˆØ¯Ø§Ø± Ú¯Ø§Ù†Øª
-  permission_view_calendar: Ø¯ÛŒØ¯Ù† Ú¯Ø§Ù‡Ø´Ù…Ø§Ø±
-  permission_view_issue_watchers: Ø¯ÛŒØ¯Ù† ÙÙ‡Ø±Ø³Øª Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†â€ŒÙ‡Ø§
-  permission_add_issue_watchers: Ø§ÙØ²ÙˆØ¯Ù† Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†â€ŒÙ‡Ø§
-  permission_delete_issue_watchers: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†â€ŒÙ‡Ø§
-  permission_log_time: Ù†ÙˆØ´ØªÙ† Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
-  permission_view_time_entries: Ø¯ÛŒØ¯Ù† Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
-  permission_edit_time_entries: ÙˆÛŒØ±Ø§ÛŒØ´ Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
-  permission_edit_own_time_entries: ÙˆÛŒØ±Ø§ÛŒØ´ Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡ Ø®ÙˆØ¯
-  permission_manage_news: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
-  permission_comment_news: Ú¯Ø°Ø§Ø´ØªÙ† Ø¯ÛŒØ¯Ú¯Ø§Ù‡ Ø±ÙˆÛŒ Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
-  permission_manage_documents: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù†ÙˆØ´ØªØ§Ø±Ù‡Ø§
-  permission_view_documents: Ø¯ÛŒØ¯Ù† Ù†ÙˆØ´ØªØ§Ø±Ù‡Ø§
-  permission_manage_files: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§
-  permission_view_files: Ø¯ÛŒØ¯Ù† Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§
-  permission_manage_wiki: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ ÙˆÛŒÚ©ÛŒ
-  permission_rename_wiki_pages: Ù†Ø§Ù…Ú¯Ø°Ø§Ø±ÛŒ Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
-  permission_delete_wiki_pages: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
-  permission_view_wiki_pages: Ø¯ÛŒØ¯Ù† ÙˆÛŒÚ©ÛŒ
-  permission_view_wiki_edits: Ø¯ÛŒØ¯Ù† Ù¾ÛŒØ´ÛŒÙ†Ù‡ ÙˆÛŒÚ©ÛŒ
-  permission_edit_wiki_pages: ÙˆÛŒØ±Ø§ÛŒØ´ Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ÛŒ ÙˆÛŒÚ©ÛŒ
-  permission_delete_wiki_pages_attachments: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾ÛŒÙˆØ³Øªâ€ŒÙ‡Ø§ÛŒ Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
-  permission_protect_wiki_pages: Ù†Ú¯Ù‡â€ŒØ¯Ø§Ø±ÛŒ Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ÛŒ ÙˆÛŒÚ©ÛŒ
-  permission_manage_repository: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡
-  permission_browse_repository: Ú†Ø±ÛŒØ¯Ù† Ø¯Ø± Ø§Ù†Ø¨Ø§Ø±Ù‡
-  permission_view_changesets: Ø¯ÛŒØ¯Ù† ØªØºÛŒÛŒØ±Ø§Øª
-  permission_commit_access: Ø¯Ø³ØªØ±Ø³ÛŒ ØªØºÛŒÛŒØ± Ø§Ù†Ø¨Ø§Ø±Ù‡
-  permission_manage_boards: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø§Ù†Ø¬Ù…Ù†â€ŒÙ‡Ø§
-  permission_view_messages: Ø¯ÛŒØ¯Ù† Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§
-  permission_add_messages: ÙØ±Ø³ØªØ§Ø¯Ù† Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§
-  permission_edit_messages: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§
-  permission_edit_own_messages: ÙˆÛŒØ±Ø§ÛŒØ´ Ù¾ÛŒØ§Ù… Ø®ÙˆØ¯
-  permission_delete_messages: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§
-  permission_delete_own_messages: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾ÛŒØ§Ù… Ø®ÙˆØ¯
-  permission_export_wiki_pages: ØµØ¯ÙˆØ± Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ÛŒ ÙˆÛŒÚ©ÛŒ
-  permission_manage_subtasks: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø²ÛŒØ±Ú©Ø§Ø±Ù‡Ø§
-  
-  project_module_issue_tracking: Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  project_module_time_tracking: Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ø²Ù…Ø§Ù†
-  project_module_news: Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
-  project_module_documents: Ù†ÙˆØ´ØªØ§Ø±Ù‡Ø§
-  project_module_files: Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§
-  project_module_wiki: ÙˆÛŒÚ©ÛŒ
-  project_module_repository: Ø§Ù†Ø¨Ø§Ø±Ù‡
-  project_module_boards: Ø§Ù†Ø¬Ù…Ù†â€ŒÙ‡Ø§
-  project_module_calendar: Ú¯Ø§Ù‡Ø´Ù…Ø§Ø±
-  project_module_gantt: Ú¯Ø§Ù†Øª
-  
-  label_user: Ú©Ø§Ø±Ø¨Ø±
-  label_user_plural: Ú©Ø§Ø±Ø¨Ø±
-  label_user_new: Ú©Ø§Ø±Ø¨Ø± ØªØ§Ø²Ù‡
-  label_user_anonymous: Ù†Ø§Ø´Ù†Ø§Ø³
-  label_project: Ù¾Ø±ÙˆÚ˜Ù‡
-  label_project_new: Ù¾Ø±ÙˆÚ˜Ù‡ ØªØ§Ø²Ù‡
-  label_project_plural: Ù¾Ø±ÙˆÚ˜Ù‡
-  label_x_projects:
-    zero:  Ø¨Ø¯ÙˆÙ† Ù¾Ø±ÙˆÚ˜Ù‡
-    one:   "1 Ù¾Ø±ÙˆÚ˜Ù‡"
-    other: "%{count} Ù¾Ø±ÙˆÚ˜Ù‡"
-  label_project_all: Ù‡Ù…Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
-  label_project_latest: Ø¢Ø®Ø±ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
-  label_issue: Ù¾ÛŒØ§Ù…Ø¯
-  label_issue_new: Ù¾ÛŒØ§Ù…Ø¯ ØªØ§Ø²Ù‡
-  label_issue_plural: Ù¾ÛŒØ§Ù…Ø¯
-  label_issue_view_all: Ø¯ÛŒØ¯Ù† Ù‡Ù…Ù‡ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§
-  label_issues_by: "Ø¯Ø³ØªÙ‡â€ŒØ¨Ù†Ø¯ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ø¨Ø§ %{value}"
-  label_issue_added: Ù¾ÛŒØ§Ù…Ø¯ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
-  label_issue_updated: Ù¾ÛŒØ§Ù…Ø¯ Ø¨Ø±ÙˆØ² Ø´Ø¯
-  label_document: Ù†ÙˆØ´ØªØ§Ø±
-  label_document_new: Ù†ÙˆØ´ØªØ§Ø± ØªØ§Ø²Ù‡
-  label_document_plural: Ù†ÙˆØ´ØªØ§Ø±
-  label_document_added: Ù†ÙˆØ´ØªØ§Ø± Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
-  label_role: Ù†Ù‚Ø´
-  label_role_plural: Ù†Ù‚Ø´
-  label_role_new: Ù†Ù‚Ø´ ØªØ§Ø²Ù‡
-  label_role_and_permissions: Ù†Ù‚Ø´â€ŒÙ‡Ø§ Ùˆ Ù¾Ø±ÙˆØ§Ù†Ù‡â€ŒÙ‡Ø§
-  label_member: Ø¹Ø¶Ùˆ
-  label_member_new: Ø¹Ø¶Ùˆ ØªØ§Ø²Ù‡
-  label_member_plural: Ø¹Ø¶Ùˆ
-  label_tracker: Ù¾ÛŒÚ¯Ø±Ø¯
-  label_tracker_plural: Ù¾ÛŒÚ¯Ø±Ø¯
-  label_tracker_new: Ù¾ÛŒÚ¯Ø±Ø¯ ØªØ§Ø²Ù‡
-  label_workflow: Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø±
-  label_issue_status: ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯
-  label_issue_status_plural: ÙˆØ¶Ø¹ÛŒØª Ù¾ÛŒØ§Ù…Ø¯
-  label_issue_status_new: ÙˆØ¶Ø¹ÛŒØª ØªØ§Ø²Ù‡
-  label_issue_category: Ø¯Ø³ØªÙ‡ Ù¾ÛŒØ§Ù…Ø¯
-  label_issue_category_plural: Ø¯Ø³ØªÙ‡ Ù¾ÛŒØ§Ù…Ø¯
-  label_issue_category_new: Ø¯Ø³ØªÙ‡ ØªØ§Ø²Ù‡
-  label_custom_field: ÙÛŒÙ„Ø¯ Ø³ÙØ§Ø±Ø´ÛŒ
-  label_custom_field_plural: ÙÛŒÙ„Ø¯ Ø³ÙØ§Ø±Ø´ÛŒ
-  label_custom_field_new: ÙÛŒÙ„Ø¯ Ø³ÙØ§Ø±Ø´ÛŒ ØªØ§Ø²Ù‡
-  label_enumerations: Ø¨Ø±Ø´Ù…Ø±Ø¯Ù†ÛŒâ€ŒÙ‡Ø§
-  label_enumeration_new: Ù…Ù‚Ø¯Ø§Ø± ØªØ§Ø²Ù‡
-  label_information: Ø¯Ø§Ø¯Ù‡
-  label_information_plural: Ø¯Ø§Ø¯Ù‡
-  label_please_login: ÙˆØ§Ø±Ø¯ Ø´ÙˆÛŒØ¯
-  label_register: Ù†Ø§Ù… Ù†ÙˆÛŒØ³ÛŒ Ú©Ù†ÛŒØ¯
-  label_login_with_open_id_option: ÛŒØ§ Ø¨Ø§ OpenID ÙˆØ§Ø±Ø¯ Ø´ÙˆÛŒØ¯
-  label_password_lost: Ø¨Ø§Ø²ÛŒØ§ÙØª Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
-  label_home: Ø³Ø±Ø¢ØºØ§Ø²
-  label_my_page: Ø¨Ø±Ú¯Ù‡ Ù…Ù†
-  label_my_account: Ø­Ø³Ø§Ø¨ Ù…Ù†
-  label_my_projects: Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ù…Ù†
-  label_my_page_block: Ø¨Ø®Ø´ Ø¨Ø±Ú¯Ù‡ Ù…Ù†
-  label_administration: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ
-  label_login: ÙˆØ±ÙˆØ¯
-  label_logout: Ø®Ø±ÙˆØ¬
-  label_help: Ø±Ø§Ù‡Ù†Ù…Ø§
-  label_reported_issues: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡
-  label_assigned_to_me_issues: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡ Ø¨Ù‡ Ù…Ù†
-  label_last_login: Ø¢Ø®Ø±ÛŒÙ† ÙˆØ±ÙˆØ¯
-  label_registered_on: Ù†Ø§Ù… Ù†ÙˆÛŒØ³ÛŒ Ø´Ø¯Ù‡ Ø¯Ø±
-  label_activity: Ú¯Ø²Ø§Ø±Ø´
-  label_overall_activity: Ú¯Ø²Ø§Ø±Ø´ Ø±ÙˆÛŒ Ù‡Ù… Ø±ÙØªÙ‡
-  label_user_activity: "Ú¯Ø²Ø§Ø±Ø´ %{value}"
-  label_new: ØªØ§Ø²Ù‡
-  label_logged_as: "Ù†Ø§Ù… Ú©Ø§Ø±Ø¨Ø±ÛŒ:"
-  label_environment: Ù…Ø­ÛŒØ·
-  label_authentication: Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ
-  label_auth_source: Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ
-  label_auth_source_new: Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ ØªØ§Ø²Ù‡
-  label_auth_source_plural: Ø±ÙˆØ´ Ø´Ù†Ø§Ø³Ø§ÛŒÛŒ
-  label_subproject_plural: Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡
-  label_subproject_new: Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡ ØªØ§Ø²Ù‡
-  label_and_its_subprojects: "%{value} Ùˆ Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒØ´"
-  label_min_max_length: Ú©Ù…ØªØ±ÛŒÙ† Ùˆ Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡
-  label_list: ÙÙ‡Ø±Ø³Øª
-  label_date: ØªØ§Ø±ÛŒØ®
-  label_integer: Ø´Ù…Ø§Ø±Ù‡ Ø¯Ø±Ø³Øª
-  label_float: Ø´Ù…Ø§Ø±Ù‡ Ø´Ù†Ø§ÙˆØ±
-  label_boolean: Ø¯Ø±Ø³Øª/Ù†Ø§Ø¯Ø±Ø³Øª
-  label_string: Ù†ÙˆØ´ØªÙ‡
-  label_text: Ù†ÙˆØ´ØªÙ‡ Ø¨Ù„Ù†Ø¯
-  label_attribute: Ù†Ø´Ø§Ù†Ù‡
-  label_attribute_plural: Ù†Ø´Ø§Ù†Ù‡
-  label_download: "%{count} Ø¨Ø§Ø± Ø¯Ø±ÛŒØ§ÙØª Ø´Ø¯Ù‡"
-  label_download_plural: "%{count} Ø¨Ø§Ø± Ø¯Ø±ÛŒØ§ÙØª Ø´Ø¯Ù‡"
-  label_no_data: Ù‡ÛŒÚ† Ø¯Ø§Ø¯Ù‡â€ŒØ§ÛŒ Ø¨Ø±Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ù†ÛŒØ³Øª
-  label_change_status: Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ†ÛŒ ÙˆØ¶Ø¹ÛŒØª
-  label_history: Ù¾ÛŒØ´ÛŒÙ†Ù‡
-  label_attachment: Ù¾Ø±ÙˆÙ†Ø¯Ù‡
-  label_attachment_new: Ù¾Ø±ÙˆÙ†Ø¯Ù‡ ØªØ§Ø²Ù‡
-  label_attachment_delete: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ù¾Ø±ÙˆÙ†Ø¯Ù‡
-  label_attachment_plural: Ù¾Ø±ÙˆÙ†Ø¯Ù‡
-  label_file_added: Ù¾Ø±ÙˆÙ†Ø¯Ù‡ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
-  label_report: Ú¯Ø²Ø§Ø±Ø´
-  label_report_plural: Ú¯Ø²Ø§Ø±Ø´
-  label_news: Ø±ÙˆÛŒØ¯Ø§Ø¯
-  label_news_new: Ø§ÙØ²ÙˆØ¯Ù† Ø±ÙˆÛŒØ¯Ø§Ø¯
-  label_news_plural: Ø±ÙˆÛŒØ¯Ø§Ø¯
-  label_news_latest: Ø¢Ø®Ø±ÛŒÙ† Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
-  label_news_view_all: Ø¯ÛŒØ¯Ù† Ù‡Ù…Ù‡ Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
-  label_news_added: Ø±ÙˆÛŒØ¯Ø§Ø¯ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
-  label_settings: Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ
-  label_overview: Ø¯Ø± ÛŒÚ© Ù†Ú¯Ø§Ù‡
-  label_version: Ù†Ú¯Ø§Ø±Ø´
-  label_version_new: Ù†Ú¯Ø§Ø±Ø´ ØªØ§Ø²Ù‡
-  label_version_plural: Ù†Ú¯Ø§Ø±Ø´
-  label_close_versions: Ø¨Ø³ØªÙ† Ù†Ú¯Ø§Ø±Ø´â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡
-  label_confirmation: Ø¨Ø±Ø±Ø³ÛŒ
-  label_export_to: 'Ù‚Ø§Ù„Ø¨â€ŒÙ‡Ø§ÛŒ Ø¯ÛŒÚ¯Ø±:'
-  label_read: Ø®ÙˆØ§Ù†Ø¯Ù†...
-  label_public_projects: Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ù‡Ù…Ú¯Ø§Ù†ÛŒ
-  label_open_issues: Ø¨Ø§Ø²
-  label_open_issues_plural: Ø¨Ø§Ø²
-  label_closed_issues: Ø¨Ø³ØªÙ‡
-  label_closed_issues_plural: Ø¨Ø³ØªÙ‡
-  label_x_open_issues_abbr_on_total:
-    zero:  0 Ø¨Ø§Ø² Ø§Ø² %{total}
-    one:   1 Ø¨Ø§Ø² Ø§Ø² %{total}
-    other: "%{count} Ø¨Ø§Ø² Ø§Ø² %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 Ø¨Ø§Ø²
-    one:   1 Ø¨Ø§Ø²
-    other: "%{count} Ø¨Ø§Ø²"
-  label_x_closed_issues_abbr:
-    zero:  0 Ø¨Ø³ØªÙ‡
-    one:   1 Ø¨Ø³ØªÙ‡
-    other: "%{count} Ø¨Ø³ØªÙ‡"
-  label_total: Ø¬Ù…Ù„Ù‡
-  label_permissions: Ù¾Ø±ÙˆØ§Ù†Ù‡â€ŒÙ‡Ø§
-  label_current_status: ÙˆØ¶Ø¹ÛŒØª Ú©Ù†ÙˆÙ†ÛŒ
-  label_new_statuses_allowed: ÙˆØ¶Ø¹ÛŒØªâ€ŒÙ‡Ø§ÛŒ Ù¾Ø°ÛŒØ±ÙØªÙ†ÛŒ ØªØ§Ø²Ù‡
-  label_all: Ù‡Ù…Ù‡
-  label_none: Ù‡ÛŒÚ†
-  label_nobody: Ù‡ÛŒÚ†Ú©Ø³
-  label_next: Ù¾Ø³ÛŒÙ†
-  label_previous: Ù¾ÛŒØ´ÛŒÙ†
-  label_used_by: Ø¨Ù‡ Ú©Ø§Ø± Ø±ÙØªÙ‡ Ø¯Ø±
-  label_details: Ø±ÛŒØ²Ù‡â€ŒÚ©Ø§Ø±ÛŒ
-  label_add_note: Ø§ÙØ²ÙˆØ¯Ù† ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
-  label_per_page: Ø±Ø¯ÛŒÙâ€ŒÙ‡Ø§ Ø¯Ø± Ù‡Ø± Ø¨Ø±Ú¯Ù‡
-  label_calendar: Ú¯Ø§Ù‡Ø´Ù…Ø§Ø±
-  label_months_from: Ø§Ø² Ù…Ø§Ù‡
-  label_gantt: Ú¯Ø§Ù†Øª
-  label_internal: Ø¯Ø±ÙˆÙ†ÛŒ
-  label_last_changes: "%{count} ØªØºÛŒÛŒØ± Ø¢Ø®Ø±"
-  label_change_view_all: Ø¯ÛŒØ¯Ù† Ù‡Ù…Ù‡ ØªØºÛŒÛŒØ±Ø§Øª
-  label_personalize_page: Ø³ÙØ§Ø±Ø´ÛŒ Ù†Ù…ÙˆØ¯Ù† Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡
-  label_comment: Ø¯ÛŒØ¯Ú¯Ø§Ù‡
-  label_comment_plural: Ø¯ÛŒØ¯Ú¯Ø§Ù‡
-  label_x_comments:
-    zero: Ø¨Ø¯ÙˆÙ† Ø¯ÛŒØ¯Ú¯Ø§Ù‡
-    one: 1 Ø¯ÛŒØ¯Ú¯Ø§Ù‡
-    other: "%{count} Ø¯ÛŒØ¯Ú¯Ø§Ù‡"
-  label_comment_add: Ø§ÙØ²ÙˆØ¯Ù† Ø¯ÛŒØ¯Ú¯Ø§Ù‡
-  label_comment_added: Ø¯ÛŒØ¯Ú¯Ø§Ù‡ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
-  label_comment_delete: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† Ø¯ÛŒØ¯Ú¯Ø§Ù‡â€ŒÙ‡Ø§
-  label_query: Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÛŒ Ø³ÙØ§Ø±Ø´ÛŒ
-  label_query_plural: Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÛŒ Ø³ÙØ§Ø±Ø´ÛŒ
-  label_query_new: Ù¾Ø±Ø³â€ŒÙˆØ¬ÙˆÛŒ ØªØ§Ø²Ù‡
-  label_filter_add: Ø§ÙØ²ÙˆØ¯Ù† Ù¾Ø§Ù„Ø§ÛŒÙ‡
-  label_filter_plural: Ù¾Ø§Ù„Ø§ÛŒÙ‡
-  label_equals: Ø¨Ø±Ø§Ø¨Ø± Ø§Ø³Øª Ø¨Ø§
-  label_not_equals: Ø¨Ø±Ø§Ø¨Ø± Ù†ÛŒØ³Øª Ø¨Ø§
-  label_in_less_than: Ú©Ù…ØªØ± Ø§Ø³Øª Ø§Ø²
-  label_in_more_than: Ø¨ÛŒØ´ØªØ± Ø§Ø³Øª Ø§Ø²
-  label_greater_or_equal: Ø¨ÛŒØ´ØªØ± ÛŒØ§ Ø¨Ø±Ø§Ø¨Ø± Ø§Ø³Øª Ø¨Ø§
-  label_less_or_equal: Ú©Ù…ØªØ± ÛŒØ§ Ø¨Ø±Ø§Ø¨Ø± Ø§Ø³Øª Ø¨Ø§
-  label_in: Ø¯Ø±
-  label_today: Ø§Ù…Ø±ÙˆØ²
-  label_all_time: Ù‡Ù…ÛŒØ´Ù‡
-  label_yesterday: Ø¯ÛŒØ±ÙˆØ²
-  label_this_week: Ø§ÛŒÙ† Ù‡ÙØªÙ‡
-  label_last_week: Ù‡ÙØªÙ‡ Ù¾ÛŒØ´ÛŒÙ†
-  label_last_n_days: "%{count} Ø±ÙˆØ² Ú¯Ø°Ø´ØªÙ‡"
-  label_this_month: Ø§ÛŒÙ† Ù…Ø§Ù‡
-  label_last_month: Ù…Ø§Ù‡ Ù¾ÛŒØ´ÛŒÙ†
-  label_this_year: Ø§Ù…Ø³Ø§Ù„
-  label_date_range: Ø¨Ø§Ø²Ù‡ ØªØ§Ø±ÛŒØ®
-  label_less_than_ago: Ú©Ù…ØªØ± Ø§Ø² Ú†Ù†Ø¯ Ø±ÙˆØ² Ù¾ÛŒØ´ÛŒÙ†
-  label_more_than_ago: Ø¨ÛŒØ´ØªØ± Ø§Ø² Ú†Ù†Ø¯ Ø±ÙˆØ² Ù¾ÛŒØ´ÛŒÙ†
-  label_ago: Ø±ÙˆØ² Ù¾ÛŒØ´ÛŒÙ†
-  label_contains: Ø¯Ø§Ø±Ø¯
-  label_not_contains: Ù†Ø¯Ø§Ø±Ø¯
-  label_day_plural: Ø±ÙˆØ²
-  label_repository: Ø§Ù†Ø¨Ø§Ø±Ù‡
-  label_repository_plural: Ø§Ù†Ø¨Ø§Ø±Ù‡
-  label_browse: Ú†Ø±ÛŒØ¯Ù†
-  label_modification: "%{count} Ø¬Ø§ÛŒÚ¯Ø°Ø§Ø±ÛŒ"
-  label_modification_plural: "%{count} Ø¬Ø§ÛŒÚ¯Ø°Ø§Ø±ÛŒ"
-  label_branch: Ø´Ø§Ø®Ù‡
-  label_tag: Ø¨Ø±Ú†Ø³Ø¨
-  label_revision: Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ
-  label_revision_plural: Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ
-  label_revision_id: "Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ %{value}"
-  label_associated_revisions: Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒâ€ŒÙ‡Ø§ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡
-  label_added: Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯Ù‡
-  label_modified: Ù¾ÛŒØ±Ø§Ø³ØªÙ‡ Ø´Ø¯Ù‡
-  label_copied: Ø±ÙˆÙ†ÙˆÛŒØ³ÛŒ Ø´Ø¯Ù‡
-  label_renamed: Ù†Ø§Ù…Ú¯Ø°Ø§Ø±ÛŒ Ø´Ø¯Ù‡
-  label_deleted: Ù¾Ø§Ú©Ø³Ø§Ø²ÛŒ Ø´Ø¯Ù‡
-  label_latest_revision: Ø¢Ø®Ø±ÛŒÙ† Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ
-  label_latest_revision_plural: Ø¢Ø®Ø±ÛŒÙ† Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ
-  label_view_revisions: Ø¯ÛŒØ¯Ù† Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒâ€ŒÙ‡Ø§
-  label_view_all_revisions: Ø¯ÛŒØ¯Ù† Ù‡Ù…Ù‡ Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒâ€ŒÙ‡Ø§
-  label_max_size: Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡
-  label_sort_highest: Ø¨Ø±Ø¯Ù† Ø¨Ù‡ Ø¢ØºØ§Ø²
-  label_sort_higher: Ø¨Ø±Ø¯Ù† Ø¨Ù‡ Ø¨Ø§Ù„Ø§
-  label_sort_lower: Ø¨Ø±Ø¯Ù† Ø¨Ù‡ Ù¾Ø§ÛŒÛŒÙ†
-  label_sort_lowest: Ø¨Ø±Ø¯Ù† Ø¨Ù‡ Ù¾Ø§ÛŒØ§Ù†
-  label_roadmap: Ú†Ø´Ù…â€ŒØ§Ù†Ø¯Ø§Ø²
-  label_roadmap_due_in: "Ø³Ø±Ø±Ø³ÛŒØ¯ Ø¯Ø± %{value}"
-  label_roadmap_overdue: "%{value} Ø¯ÛŒØ±Ú©Ø±Ø¯"
-  label_roadmap_no_issues: Ù‡ÛŒÚ† Ù¾ÛŒØ§Ù…Ø¯ÛŒ Ø¨Ø±Ø§ÛŒ Ø§ÛŒÙ† Ù†Ú¯Ø§Ø±Ø´ Ù†ÛŒØ³Øª
-  label_search: Ø¬Ø³ØªØ¬Ùˆ
-  label_result_plural: Ø¯Ø³Øªâ€ŒØ¢ÙˆØ±Ø¯
-  label_all_words: Ù‡Ù…Ù‡ ÙˆØ§Ú˜Ù‡â€ŒÙ‡Ø§
-  label_wiki: ÙˆÛŒÚ©ÛŒ
-  label_wiki_edit: ÙˆÛŒØ±Ø§ÛŒØ´ ÙˆÛŒÚ©ÛŒ
-  label_wiki_edit_plural: ÙˆÛŒØ±Ø§ÛŒØ´ ÙˆÛŒÚ©ÛŒ
-  label_wiki_page: Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
-  label_wiki_page_plural: Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ
-  label_index_by_title: Ø´Ø§Ø®Øµ Ø¨Ø± Ø§Ø³Ø§Ø³ Ù†Ø§Ù…
-  label_index_by_date: Ø´Ø§Ø®Øµ Ø¨Ø± Ø§Ø³Ø§Ø³ ØªØ§Ø±ÛŒØ®
-  label_current_version: Ù†Ú¯Ø§Ø±Ø´ Ú©Ù†ÙˆÙ†ÛŒ
-  label_preview: Ù¾ÛŒØ´â€ŒÙ†Ù…Ø§ÛŒØ´
-  label_feed_plural: Ø®ÙˆØ±Ø§Ú©
-  label_changes_details: Ø±ÛŒØ² Ù‡Ù…Ù‡ Ø¬Ø§ÛŒÚ¯Ø°Ø§Ø±ÛŒâ€ŒÙ‡Ø§
-  label_issue_tracking: Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ù¾ÛŒØ§Ù…Ø¯
-  label_spent_time: Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
-  label_overall_spent_time: Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡ Ø±ÙˆÛŒ Ù‡Ù…
-  label_f_hour: "%{value} Ø³Ø§Ø¹Øª"
-  label_f_hour_plural: "%{value} Ø³Ø§Ø¹Øª"
-  label_time_tracking: Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ø²Ù…Ø§Ù†
-  label_change_plural: Ø¬Ø§ÛŒÚ¯Ø°Ø§Ø±ÛŒ
-  label_statistics: Ø³Ø±Ø´Ù…Ø§Ø±ÛŒ
-  label_commits_per_month: ØªØºÛŒÛŒØ± Ø¯Ø± Ù‡Ø± Ù…Ø§Ù‡
-  label_commits_per_author: ØªØºÛŒÛŒØ± Ù‡Ø± Ù†ÙˆÛŒØ³Ù†Ø¯Ù‡
-  label_view_diff: Ø¯ÛŒØ¯Ù† ØªÙØ§ÙˆØªâ€ŒÙ‡Ø§
-  label_diff_inline: Ù‡Ù…Ø±Ø§Ø³ØªØ§
-  label_diff_side_by_side: Ú©Ù†Ø§Ø± Ø¨Ù‡ Ú©Ù†Ø§Ø±
-  label_options: Ú¯Ø²ÛŒÙ†Ù‡â€ŒÙ‡Ø§
-  label_copy_workflow_from: Ø±ÙˆÙ†ÙˆÛŒØ³ÛŒ Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø± Ø§Ø² Ø±ÙˆÛŒ
-  label_permissions_report: Ú¯Ø²Ø§Ø±Ø´ Ù¾Ø±ÙˆØ§Ù†Ù‡â€ŒÙ‡Ø§
-  label_watched_issues: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†ÛŒ Ø´Ø¯Ù‡
-  label_related_issues: Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡
-  label_applied_status: ÙˆØ¶Ø¹ÛŒØª Ø¨Ù‡ Ú©Ø§Ø± Ø±ÙØªÙ‡
-  label_loading: Ø¨Ø§Ø± Ú¯Ø°Ø§Ø±ÛŒ...
-  label_relation_new: ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ ØªØ§Ø²Ù‡
-  label_relation_delete: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† ÙˆØ§Ø¨Ø³ØªÚ¯ÛŒ
-  label_relates_to: ÙˆØ§Ø¨Ø³ØªÙ‡ Ø¨Ù‡
-  label_duplicates: Ù†Ú¯Ø§Ø±Ø´ Ø¯ÛŒÚ¯Ø±ÛŒ Ø§Ø²
-  label_duplicated_by: Ù†Ú¯Ø§Ø±Ø´ÛŒ Ø¯ÛŒÚ¯Ø± Ø¯Ø±
-  label_blocks: Ø¨Ø§Ø²Ø¯Ø§Ø´Øªâ€ŒÙ‡Ø§
-  label_blocked_by: Ø¨Ø§Ø²Ø¯Ø§Ø´Øª Ø¨Ù‡ Ø¯Ø³Øª
-  label_precedes: Ø¬Ù„ÙˆØªØ± Ø§Ø³Øª Ø§Ø²
-  label_follows: Ù¾Ø³ØªØ± Ø§Ø³Øª Ø§Ø²
-  label_end_to_start: Ù¾Ø§ÛŒØ§Ù† Ø¨Ù‡ Ø¢ØºØ§Ø²
-  label_end_to_end: Ù¾Ø§ÛŒØ§Ù† Ø¨Ù‡ Ù¾Ø§ÛŒØ§Ù†
-  label_start_to_start: Ø¢ØºØ§Ø² Ø¨Ù‡ Ø¢ØºØ§Ø²
-  label_start_to_end: Ø¢ØºØ§Ø² Ø¨Ù‡ Ù¾Ø§ÛŒØ§Ù†
-  label_stay_logged_in: ÙˆØ§Ø±Ø¯ Ø´Ø¯Ù‡ Ø¨Ù…Ø§Ù†ÛŒØ¯
-  label_disabled: ØºÛŒØ±ÙØ¹Ø§Ù„
-  label_show_completed_versions: Ù†Ù…Ø§ÛŒØ´ Ù†Ú¯Ø§Ø±Ø´â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡
-  label_me: Ù…Ù†
-  label_board: Ø§Ù†Ø¬Ù…Ù†
-  label_board_new: Ø§Ù†Ø¬Ù…Ù† ØªØ§Ø²Ù‡
-  label_board_plural: Ø§Ù†Ø¬Ù…Ù†
-  label_board_locked: Ù‚ÙÙ„ Ø´Ø¯Ù‡
-  label_board_sticky: Ú†Ø³Ø¨Ù†Ø§Ú©
-  label_topic_plural: Ø³Ø±ÙØµÙ„
-  label_message_plural: Ù¾ÛŒØ§Ù…
-  label_message_last: Ø¢Ø®Ø±ÛŒÙ† Ù¾ÛŒØ§Ù…
-  label_message_new: Ù¾ÛŒØ§Ù… ØªØ§Ø²Ù‡
-  label_message_posted: Ù¾ÛŒØ§Ù… Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
-  label_reply_plural: Ù¾Ø§Ø³Ø®
-  label_send_information: ÙØ±Ø³ØªØ§Ø¯Ù† Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ø­Ø³Ø§Ø¨ Ø¨Ù‡ Ú©Ø§Ø±Ø¨Ø±
-  label_year: Ø³Ø§Ù„
-  label_month: Ù…Ø§Ù‡
-  label_week: Ù‡ÙØªÙ‡
-  label_date_from: Ø§Ø²
-  label_date_to: ØªØ§
-  label_language_based: Ø¨Ø± Ø§Ø³Ø§Ø³ Ø²Ø¨Ø§Ù† Ú©Ø§Ø±Ø¨Ø±
-  label_sort_by: "Ø¬ÙˆØ± Ú©Ø±Ø¯ Ø¨Ø§ %{value}"
-  label_send_test_email: ÙØ±Ø³ØªØ§Ø¯Ù† Ø§ÛŒÙ…ÛŒÙ„ Ø¢Ø²Ù…Ø§ÛŒØ´ÛŒ
-  label_feeds_access_key: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ RSS
-  label_missing_feeds_access_key: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ RSS Ø¯Ø± Ø¯Ø³ØªØ±Ø³ Ù†ÛŒØ³Øª
-  label_feeds_access_key_created_on: "Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ RSS %{value} Ù¾ÛŒØ´ Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª"
-  label_module_plural: Ù¾ÛŒÙ…Ø§Ù†Ù‡
-  label_added_time_by: "Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯Ù‡ Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø¯Ø± %{age} Ù¾ÛŒØ´"
-  label_updated_time_by: "Ø¨Ø±ÙˆØ² Ø´Ø¯Ù‡ Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø¯Ø± %{age} Ù¾ÛŒØ´"
-  label_updated_time: "Ø¨Ø±ÙˆØ² Ø´Ø¯Ù‡ Ø¯Ø± %{value} Ù¾ÛŒØ´"
-  label_jump_to_a_project: Ù¾Ø±Ø´ Ø¨Ù‡ ÛŒÚ© Ù¾Ø±ÙˆÚ˜Ù‡...
-  label_file_plural: Ù¾Ø±ÙˆÙ†Ø¯Ù‡
-  label_changeset_plural: ØªØºÛŒÛŒØ±
-  label_default_columns: Ø³ØªÙˆÙ†â€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
-  label_no_change_option: (Ø¨Ø¯ÙˆÙ† ØªØºÛŒÛŒØ±)
-  label_bulk_edit_selected_issues: ÙˆÛŒØ±Ø§ÛŒØ´ Ø¯Ø³ØªÙ‡â€ŒØ§ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡
-  label_theme: Ù¾ÙˆØ³ØªÙ‡
-  label_default: Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
-  label_search_titles_only: ØªÙ†Ù‡Ø§ Ù†Ø§Ù…â€ŒÙ‡Ø§ Ø¬Ø³ØªØ¬Ùˆ Ø´ÙˆØ¯
-  label_user_mail_option_all: "Ø¨Ø±Ø§ÛŒ Ù‡Ø± Ø±ÙˆÛŒØ¯Ø§Ø¯ Ø¯Ø± Ù‡Ù…Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§"
-  label_user_mail_option_selected: "Ø¨Ø±Ø§ÛŒ Ù‡Ø± Ø±ÙˆÛŒØ¯Ø§Ø¯ ØªÙ†Ù‡Ø§ Ø¯Ø± Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡..."
-  label_user_mail_option_none: "Ù‡ÛŒÚ† Ø±ÙˆÛŒØ¯Ø§Ø¯ÛŒ"
-  label_user_mail_option_only_my_events: "ØªÙ†Ù‡Ø§ Ø¨Ø±Ø§ÛŒ Ú†ÛŒØ²Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù† Ù‡Ø³ØªÙ… ÛŒØ§ Ø¯Ø± Ø¢Ù†â€ŒÙ‡Ø§ Ø¯Ø±Ú¯ÛŒØ± Ù‡Ø³ØªÙ…"
-  label_user_mail_option_only_assigned: "ØªÙ†Ù‡Ø§ Ø¨Ø±Ø§ÛŒ Ú†ÛŒØ²Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¨Ù‡ Ù…Ù† ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡"
-  label_user_mail_option_only_owner: "ØªÙ†Ù‡Ø§ Ø¨Ø±Ø§ÛŒ Ú†ÛŒØ²Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ù…Ù† Ø¯Ø§Ø±Ù†Ø¯Ù‡ Ø¢Ù†â€ŒÙ‡Ø§ Ù‡Ø³ØªÙ…"
-  label_user_mail_no_self_notified: "Ù†Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡Ù… Ø§Ø² ØªØºÛŒÛŒØ±Ø§ØªÛŒ Ú©Ù‡ Ø®ÙˆØ¯Ù… Ù…ÛŒâ€ŒØ¯Ù‡Ù… Ø¢Ú¯Ø§Ù‡ Ø´ÙˆÙ…"
-  label_registration_activation_by_email: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ Ø¨Ø§ Ø§ÛŒÙ…ÛŒÙ„
-  label_registration_manual_activation: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ Ø¯Ø³ØªÛŒ
-  label_registration_automatic_activation: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ Ø­Ø³Ø§Ø¨ Ø®ÙˆØ¯Ú©Ø§Ø±
-  label_display_per_page: "Ø±Ø¯ÛŒÙâ€ŒÙ‡Ø§ Ø¯Ø± Ù‡Ø± Ø¨Ø±Ú¯Ù‡: %{value}"
-  label_age: Ø³Ù†
-  label_change_properties: ÙˆÛŒØ±Ø§ÛŒØ´ ÙˆÛŒÚ˜Ú¯ÛŒâ€ŒÙ‡Ø§
-  label_general: Ù‡Ù…Ú¯Ø§Ù†ÛŒ
-  label_more: Ø¨ÛŒØ´ØªØ±
-  label_scm: SCM
-  label_plugins: Ø§ÙØ²ÙˆÙ†Ù‡â€ŒÙ‡Ø§
-  label_ldap_authentication: Ø´Ù†Ø§Ø³Ø§ÛŒÛŒLDAP
-  label_downloads_abbr: Ø¯Ø±ÛŒØ§ÙØª
-  label_optional_description: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª Ø¯Ù„Ø®ÙˆØ§Ù‡
-  label_add_another_file: Ø§ÙØ²ÙˆØ¯Ù† Ù¾Ø±ÙˆÙ†Ø¯Ù‡ Ø¯ÛŒÚ¯Ø±
-  label_preferences: Ù¾Ø³Ù†Ø¯Ù‡Ø§
-  label_chronological_order: Ø¨Ù‡ ØªØ±ØªÛŒØ¨ ØªØ§Ø±ÛŒØ®
-  label_reverse_chronological_order: Ø¨Ø±Ø¹Ú©Ø³ ØªØ±ØªÛŒØ¨ ØªØ§Ø±ÛŒØ®
-  label_planning: Ø¨Ø±Ù†Ø§Ù…Ù‡ Ø±ÛŒØ²ÛŒ
-  label_incoming_emails: Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ÛŒ Ø¢Ù…Ø¯Ù‡
-  label_generate_key: Ø³Ø§Ø®Øª Ú©Ù„ÛŒØ¯
-  label_issue_watchers: Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†â€ŒÙ‡Ø§
-  label_example: Ù†Ù…ÙˆÙ†Ù‡
-  label_display: Ù†Ù…Ø§ÛŒØ´
-  label_sort: Ø¬ÙˆØ± Ú©Ø±Ø¯
-  label_ascending: Ø§ÙØ²Ø§ÛŒØ´ÛŒ
-  label_descending: Ú©Ø§Ù‡Ø´ÛŒ
-  label_date_from_to: Ø§Ø² %{start} ØªØ§ %{end}
-  label_wiki_content_added: Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
-  label_wiki_content_updated: Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Ø¨Ø±ÙˆØ² Ø´Ø¯
-  label_group: Ø¯Ø³ØªÙ‡
-  label_group_plural: Ø¯Ø³ØªÙ‡
-  label_group_new: Ø¯Ø³ØªÙ‡ ØªØ§Ø²Ù‡
-  label_time_entry_plural: Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡
-  label_version_sharing_none: Ø¨Ø¯ÙˆÙ† Ø§Ø´ØªØ±Ø§Ú©
-  label_version_sharing_descendants: Ø¨Ø§ Ø²ÛŒØ± Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
-  label_version_sharing_hierarchy: Ø¨Ø§ Ø±Ø´ØªÙ‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
-  label_version_sharing_tree: Ø¨Ø§ Ø¯Ø±Ø®Øª Ù¾Ø±ÙˆÚ˜Ù‡
-  label_version_sharing_system: Ø¨Ø§ Ù‡Ù…Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§
-  label_update_issue_done_ratios: Ø¨Ø±ÙˆØ² Ø±Ø³Ø§Ù†ÛŒ Ø§Ù†Ø¯Ø§Ø²Ù‡ Ø§Ù†Ø¬Ø§Ù… Ø´Ø¯Ù‡ Ù¾ÛŒØ§Ù…Ø¯
-  label_copy_source: Ù…Ù†Ø¨Ø¹
-  label_copy_target: Ù…Ù‚ØµØ¯
-  label_copy_same_as_target: Ù…Ø§Ù†Ù†Ø¯ Ù…Ù‚ØµØ¯
-  label_display_used_statuses_only: ØªÙ†Ù‡Ø§ ÙˆØ¶Ø¹ÛŒØªâ€ŒÙ‡Ø§ÛŒÛŒ Ù†Ø´Ø§Ù† Ø¯Ø§Ø¯Ù‡ Ø´ÙˆÙ†Ø¯ Ú©Ù‡ Ø¯Ø± Ø§ÛŒÙ† Ù¾ÛŒÚ¯Ø±Ø¯ Ø¨Ù‡ Ú©Ø§Ø± Ø±ÙØªÙ‡â€ŒØ§Ù†Ø¯
-  label_api_access_key: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ API
-  label_missing_api_access_key: Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ API Ø¯Ø± Ø¯Ø³ØªØ±Ø³ Ù†ÛŒØ³Øª
-  label_api_access_key_created_on: "Ú©Ù„ÛŒØ¯ Ø¯Ø³ØªØ±Ø³ÛŒ API %{value} Ù¾ÛŒØ´ Ø³Ø§Ø®ØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª"
-  label_profile: Ù†Ù…Ø§ÛŒÙ‡
-  label_subtask_plural: Ø²ÛŒØ±Ú©Ø§Ø±
-  label_project_copy_notifications: Ø¯Ø± Ù‡Ù†Ú¯Ø§Ù… Ø±ÙˆÙ†ÙˆÛŒØ³ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ÛŒ Ø¢Ú¯Ø§Ù‡â€ŒØ³Ø§Ø²ÛŒ Ø±Ø§ Ø¨ÙØ±Ø³Øª
-  label_principal_search: "Ø¬Ø³ØªØ¬Ùˆ Ø¨Ø±Ø§ÛŒ Ú©Ø§Ø±Ø¨Ø± ÛŒØ§ Ø¯Ø³ØªÙ‡:"
-  label_user_search: "Ø¬Ø³ØªØ¬Ùˆ Ø¨Ø±Ø§ÛŒ Ú©Ø§Ø±Ø¨Ø±:"
-  
-  button_login: ÙˆØ±ÙˆØ¯
-  button_submit: ÙˆØ§Ú¯Ø°Ø§Ø±ÛŒ
-  button_save: Ù†Ú¯Ù‡Ø¯Ø§Ø±ÛŒ
-  button_check_all: Ú¯Ø²ÛŒÙ†Ø´ Ù‡Ù…Ù‡
-  button_uncheck_all: Ú¯Ø²ÛŒÙ†Ø´ Ù‡ÛŒÚ†
-  button_delete: Ù¾Ø§Ú©
-  button_create: Ø³Ø§Ø®Øª
-  button_create_and_continue: Ø³Ø§Ø®Øª Ùˆ Ø§Ø¯Ø§Ù…Ù‡
-  button_test: Ø¢Ø²Ù…Ø§ÛŒØ´
-  button_edit: ÙˆÛŒØ±Ø§ÛŒØ´
-  button_edit_associated_wikipage: "ÙˆÛŒØ±Ø§ÛŒØ´ Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡: %{page_title}"
-  button_add: Ø§ÙØ²ÙˆØ¯Ù†
-  button_change: ÙˆÛŒØ±Ø§ÛŒØ´
-  button_apply: Ø§Ù†Ø¬Ø§Ù…
-  button_clear: Ù¾Ø§Ú©
-  button_lock: Ú¯Ø°Ø§Ø´ØªÙ† Ù‚ÙÙ„
-  button_unlock: Ø¨Ø±Ø¯Ø§Ø´ØªÙ† Ù‚ÙÙ„
-  button_download: Ø¯Ø±ÛŒØ§ÙØª
-  button_list: ÙÙ‡Ø±Ø³Øª
-  button_view: Ø¯ÛŒØ¯Ù†
-  button_move: Ø¬Ø§Ø¨Ø¬Ø§ÛŒÛŒ
-  button_move_and_follow: Ø¬Ø§Ø¨Ø¬Ø§ÛŒÛŒ Ùˆ Ø§Ø¯Ø§Ù…Ù‡
-  button_back: Ø¨Ø±Ú¯Ø´Øª
-  button_cancel: Ø¨Ø§Ø²Ú¯Ø´Øª
-  button_activate: ÙØ¹Ø§Ù„Ø³Ø§Ø²ÛŒ
-  button_sort: Ø¬ÙˆØ± Ú©Ø±Ø¯
-  button_log_time: Ø²Ù…Ø§Ù†â€ŒÙ†ÙˆÛŒØ³ÛŒ
-  button_rollback: Ø¨Ø±Ú¯Ø±Ø¯ Ø¨Ù‡ Ø§ÛŒÙ† Ù†Ú¯Ø§Ø±Ø´
-  button_watch: Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†ÛŒ
-  button_unwatch: Ù†Ø§â€ŒØ¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù†ÛŒ
-  button_reply: Ù¾Ø§Ø³Ø®
-  button_archive: Ø¨Ø§ÛŒÚ¯Ø§Ù†ÛŒ
-  button_unarchive: Ø¨Ø±Ú¯Ø´Øª Ø§Ø² Ø¨Ø§ÛŒÚ¯Ø§Ù†ÛŒ
-  button_reset: Ø¨Ø§Ø²Ù†Ø´Ø§Ù†ÛŒ
-  button_rename: Ù†Ø§Ù…Ú¯Ø°Ø§Ø±ÛŒ
-  button_change_password: Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ†ÛŒ Ú¯Ø°Ø±ÙˆØ§Ú˜Ù‡
-  button_copy: Ø±ÙˆÙ†ÙˆØ´Øª
-  button_copy_and_follow: Ø±ÙˆÙ†ÙˆØ´Øª Ùˆ Ø§Ø¯Ø§Ù…Ù‡
-  button_annotate: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
-  button_update: Ø¨Ø±ÙˆØ² Ø±Ø³Ø§Ù†ÛŒ
-  button_configure: Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ
-  button_quote: Ù†Ù‚Ù„ Ù‚ÙˆÙ„
-  button_duplicate: Ù†Ú¯Ø§Ø±Ø´ Ø¯ÛŒÚ¯Ø±
-  button_show: Ù†Ù…Ø§ÛŒØ´
-  
-  status_active: ÙØ¹Ø§Ù„
-  status_registered: Ù†Ø§Ù…â€ŒÙ†ÙˆÛŒØ³ÛŒ Ø´Ø¯Ù‡
-  status_locked: Ù‚ÙÙ„
-  
-  version_status_open: Ø¨Ø§Ø²
-  version_status_locked: Ù‚ÙÙ„
-  version_status_closed: Ø¨Ø³ØªÙ‡
-
-  field_active: ÙØ¹Ø§Ù„
-  
-  text_select_mail_notifications: ÙØ±Ù…Ø§Ù†â€ŒÙ‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¨Ø±Ø§ÛŒ Ø¢Ù†â€ŒÙ‡Ø§ Ø¨Ø§ÛŒØ¯ Ø§ÛŒÙ…ÛŒÙ„ ÙØ±Ø³ØªØ§Ø¯Ù‡ Ø´ÙˆØ¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯.
-  text_regexp_info: Ø¨Ø±Ø§ÛŒ Ù†Ù…ÙˆÙ†Ù‡ ^[A-Z0-9]+$
-  text_min_max_length_info: 0 ÛŒØ¹Ù†ÛŒ Ø¨Ø¯ÙˆÙ† Ú©Ø±Ø§Ù†
-  text_project_destroy_confirmation: Ø¢ÛŒØ§ Ø¨Ø±Ø§Ø³ØªÛŒ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ Ùˆ Ù‡Ù…Ù‡ Ø¯Ø§Ø¯Ù‡â€ŒÙ‡Ø§ÛŒ Ø¢Ù† Ø±Ø§ Ù¾Ø§Ú© Ú©Ù†ÛŒØ¯ØŸ
-  text_subprojects_destroy_warning: "Ø²ÛŒØ±Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ø¢Ù†: %{value} Ù‡Ù… Ù¾Ø§Ú© Ø®ÙˆØ§Ù‡Ù†Ø¯ Ø´Ø¯."
-  text_workflow_edit: ÛŒÚ© Ù†Ù‚Ø´ Ùˆ ÛŒÚ© Ù¾ÛŒÚ¯Ø±Ø¯ Ø±Ø§ Ø¨Ø±Ø§ÛŒ ÙˆÛŒØ±Ø§ÛŒØ´ Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø± Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯
-  text_are_you_sure: Ø¢ÛŒØ§ Ø§ÛŒÙ† Ú©Ø§Ø± Ø§Ù†Ø¬Ø§Ù… Ø´ÙˆØ¯ØŸ
-  text_are_you_sure_with_children: "Ø¢ÛŒØ§ Ù¾ÛŒØ§Ù…Ø¯ Ùˆ Ù‡Ù…Ù‡ Ø²ÛŒØ±Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ø¢Ù† Ù¾Ø§Ú© Ø´ÙˆÙ†Ø¯ØŸ"
-  text_journal_changed: "Â«%{label}Â» Ø§Ø² Â«%{old}Â» Ø¨Ù‡ Â«%{new}Â» Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ† Ø´Ø¯"
-  text_journal_set_to: "Â«%{label}Â» Ø¨Ù‡ Â«%{value}Â» Ù†Ø´Ø§Ù†Ø¯Ù‡ Ø´Ø¯"
-  text_journal_deleted: "Â«%{label}Â» Ù¾Ø§Ú© Ø´Ø¯ (%{old})"
-  text_journal_added: "Â«%{label}Â»ØŒ Â«%{value}Â» Ø±Ø§ Ø§ÙØ²ÙˆØ¯"
-  text_tip_task_begin_day: Ø±ÙˆØ² Ø¢ØºØ§Ø² Ù¾ÛŒØ§Ù…Ø¯
-  text_tip_task_end_day: Ø±ÙˆØ² Ù¾Ø§ÛŒØ§Ù† Ù¾ÛŒØ§Ù…Ø¯
-  text_tip_task_begin_end_day: Ø±ÙˆØ² Ø¢ØºØ§Ø² Ùˆ Ù¾Ø§ÛŒØ§Ù† Ù¾ÛŒØ§Ù…Ø¯
-  text_project_identifier_info: 'ØªÙ†Ù‡Ø§ Ù†ÙˆÛŒØ³Ù‡â€ŒÙ‡Ø§ÛŒ Ú©ÙˆÚ†Ú© (a-z)ØŒ Ø´Ù…Ø§Ø±Ù‡â€ŒÙ‡Ø§ Ùˆ Ø®Ø· ØªÛŒØ±Ù‡ Ù¾Ø°ÛŒØ±ÙØªÙ†ÛŒ Ø§Ø³Øª.<br />Ù¾Ø³ Ø§Ø² Ø°Ø®ÛŒØ±Ù‡ Ø³Ø§Ø²ÛŒØŒ Ø´Ù†Ø§Ø³Ù‡ Ù†Ù…ÛŒâ€ŒØªÙˆØ§Ù†Ø¯ Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ† Ø´ÙˆØ¯.'
-  text_caracters_maximum: "Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ %{count} Ø§Ø³Øª."
-  text_caracters_minimum: "Ú©Ù…ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ %{count} Ø§Ø³Øª."
-  text_length_between: "Ø¨Ø§ÛŒØ¯ Ù…ÛŒØ§Ù† %{min} Ùˆ %{max} Ù†ÙˆÛŒØ³Ù‡ Ø¨Ø§Ø´Ø¯."
-  text_tracker_no_workflow: Ù‡ÛŒÚ† Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø±ÛŒ Ø¨Ø±Ø§ÛŒ Ø§ÛŒÙ† Ù¾ÛŒÚ¯Ø±Ø¯ Ù…Ø´Ø®Øµ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª
-  text_unallowed_characters: Ù†ÙˆÛŒØ³Ù‡â€ŒÙ‡Ø§ÛŒ Ù†Ø§Ù¾Ø³Ù†Ø¯
-  text_comma_separated: Ú†Ù†Ø¯ Ù…Ù‚Ø¯Ø§Ø± Ù¾Ø°ÛŒØ±ÙØªÙ†ÛŒ Ø§Ø³Øª (Ø¨Ø§ Â«,Â» Ø§Ø² Ù‡Ù… Ø¬Ø¯Ø§ Ø´ÙˆÙ†Ø¯).
-  text_line_separated: Ú†Ù†Ø¯ Ù…Ù‚Ø¯Ø§Ø± Ù¾Ø°ÛŒØ±ÙØªÙ†ÛŒ Ø§Ø³Øª (Ù‡Ø± Ù…Ù‚Ø¯Ø§Ø± Ø¯Ø± ÛŒÚ© Ø®Ø·).
-  text_issues_ref_in_commit_messages: Ù†Ø´Ø§Ù†Ù‡ Ø±ÙˆÛŒ Ùˆ Ø¨Ø³ØªÙ† Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ø¯Ø± Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡
-  text_issue_added: "Ù¾ÛŒØ§Ù…Ø¯ %{id} Ø¨Ù‡ Ø¯Ø³Øª %{author} Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯."
-  text_issue_updated: "Ù¾ÛŒØ§Ù…Ø¯ %{id} Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø¨Ø±ÙˆØ² Ø´Ø¯."
-  text_wiki_destroy_confirmation: Ø¢ÛŒØ§ Ø¨Ø±Ø§Ø³ØªÛŒ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ø§ÛŒÙ† ÙˆÛŒÚ©ÛŒ Ùˆ Ù‡Ù…Ù‡ Ù…Ø­ØªÙˆØ§ÛŒ Ø¢Ù† Ø±Ø§ Ù¾Ø§Ú© Ú©Ù†ÛŒØ¯ØŸ
-  text_issue_category_destroy_question: "Ø¨Ø±Ø®ÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ (%{count}) Ø¨Ù‡ Ø§ÛŒÙ† Ø¯Ø³ØªÙ‡ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡â€ŒØ§Ù†Ø¯. Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ú†Ù‡ Ú©Ù†ÛŒØ¯ØŸ"
-  text_issue_category_destroy_assignments: Ù¾Ø§Ú© Ú©Ø±Ø¯Ù† ÙˆØ§Ú¯Ø°Ø§Ø±ÛŒ Ø¨Ù‡ Ø¯Ø³ØªÙ‡
-  text_issue_category_reassign_to: ÙˆØ§Ú¯Ø°Ø§Ø±ÛŒ Ø¯ÙˆØ¨Ø§Ø±Ù‡ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ Ø¨Ù‡ Ø§ÛŒÙ† Ø¯Ø³ØªÙ‡
-  text_user_mail_option: "Ø¨Ø±Ø§ÛŒ Ù¾Ø±ÙˆÚ˜Ù‡â€ŒÙ‡Ø§ÛŒ Ú¯Ø²ÛŒÙ†Ø´ Ù†Ø´Ø¯Ù‡ØŒ ØªÙ†Ù‡Ø§ Ø§ÛŒÙ…ÛŒÙ„â€ŒÙ‡Ø§ÛŒÛŒ Ø¯Ø±Ø¨Ø§Ø±Ù‡ Ú†ÛŒØ²Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¯ÛŒØ¯Ù‡â€ŒØ¨Ø§Ù† ÛŒØ§ Ø¯Ø±Ú¯ÛŒØ± Ø¢Ù†â€ŒÙ‡Ø§ Ù‡Ø³ØªÛŒØ¯ Ø¯Ø±ÛŒØ§ÙØª Ø®ÙˆØ§Ù‡ÛŒØ¯ Ú©Ø±Ø¯ (Ù…Ø§Ù†Ù†Ø¯ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ù†ÙˆÛŒØ³Ù†Ø¯Ù‡ Ø¢Ù†â€ŒÙ‡Ø§ Ù‡Ø³ØªÛŒØ¯ ÛŒØ§ Ø¨Ù‡ Ø´Ù…Ø§ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡â€ŒØ§Ù†Ø¯)."
-  text_no_configuration_data: "Ù†Ù‚Ø´â€ŒÙ‡Ø§ØŒ Ù¾ÛŒÚ¯Ø±Ø¯Ù‡Ø§ØŒ ÙˆØ¶Ø¹ÛŒØªâ€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯ Ùˆ Ú¯Ø±Ø¯Ø´ Ú©Ø§Ø± Ù‡Ù†ÙˆØ² Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù†Ø´Ø¯Ù‡â€ŒØ§Ù†Ø¯. \nØ¨Ù‡ Ø³Ø®ØªÛŒ Ù¾ÛŒØ´Ù†Ù‡Ø§Ø¯ Ù…ÛŒâ€ŒØ´ÙˆØ¯ Ú©Ù‡ Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ø±Ø§ Ø¨Ø§Ø± Ú©Ù†ÛŒØ¯. Ø³Ù¾Ø³ Ù…ÛŒâ€ŒØªÙˆØ§Ù†ÛŒØ¯ Ø¢Ù† Ø±Ø§ ÙˆÛŒØ±Ø§ÛŒØ´ Ú©Ù†ÛŒØ¯."
-  text_load_default_configuration: Ø¨Ø§Ø±Ú¯Ø°Ø§Ø±ÛŒ Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡
-  text_status_changed_by_changeset: "Ø¯Ø± ØªØºÛŒÛŒØ± %{value} Ø¨Ø±ÙˆØ² Ø´Ø¯Ù‡ Ø§Ø³Øª."
-  text_time_logged_by_changeset: "Ø¯Ø± ØªØºÛŒÛŒØ± %{value} Ù†ÙˆØ´ØªÙ‡ Ø´Ø¯Ù‡ Ø§Ø³Øª."
-  text_issues_destroy_confirmation: 'Ø¢ÛŒØ§ Ø¨Ø±Ø§Ø³ØªÛŒ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡ Ø±Ø§ Ù¾Ø§Ú© Ú©Ù†ÛŒØ¯ØŸ'
-  text_select_project_modules: 'Ù¾ÛŒÙ…Ø§Ù†Ù‡â€ŒÙ‡Ø§ÛŒÛŒ Ú©Ù‡ Ø¨Ø§ÛŒØ¯ Ø¨Ø±Ø§ÛŒ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ ÙØ¹Ø§Ù„ Ø´ÙˆÙ†Ø¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯:'
-  text_default_administrator_account_changed: Ø­Ø³Ø§Ø¨ Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù¾ÛŒØ´â€ŒÚ¯Ø²ÛŒØ¯Ù‡ Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ† Ø´Ø¯
-  text_file_repository_writable: Ù¾ÙˆØ´Ù‡ Ù¾ÛŒÙˆØ³Øªâ€ŒÙ‡Ø§ Ù†ÙˆØ´ØªÙ†ÛŒ Ø§Ø³Øª
-  text_plugin_assets_writable: Ù¾ÙˆØ´Ù‡ Ø¯Ø§Ø±Ø§ÛŒÛŒâ€ŒÙ‡Ø§ÛŒ Ø§ÙØ²ÙˆÙ†Ù‡â€ŒÙ‡Ø§ Ù†ÙˆØ´ØªÙ†ÛŒ Ø§Ø³Øª
-  text_rmagick_available: RMagick Ø¯Ø± Ø¯Ø³ØªØ±Ø³ Ø§Ø³Øª (Ø§Ø®ØªÛŒØ§Ø±ÛŒ)
-  text_destroy_time_entries_question: "%{hours} Ø³Ø§Ø¹Øª Ø±ÙˆÛŒ Ù¾ÛŒØ§Ù…Ø¯Ù‡Ø§ÛŒÛŒ Ú©Ù‡ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ù¾Ø§Ú© Ú©Ù†ÛŒØ¯ Ú©Ø§Ø± Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ø§Ø³Øª. Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ú†Ù‡ Ú©Ù†ÛŒØ¯ØŸ"
-  text_destroy_time_entries: Ø³Ø§Ø¹Øªâ€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ù¾Ø§Ú© Ø´ÙˆÙ†Ø¯
-  text_assign_time_entries_to_project: Ø³Ø§Ø¹Øªâ€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ø¨Ù‡ Ù¾Ø±ÙˆÚ˜Ù‡ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯
-  text_reassign_time_entries: 'Ø³Ø§Ø¹Øªâ€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ø¨Ù‡ Ø§ÛŒÙ† Ù¾ÛŒØ§Ù…Ø¯ ÙˆØ§Ú¯Ø°Ø§Ø± Ø´ÙˆÙ†Ø¯:'
-  text_user_wrote: "%{value} Ù†ÙˆØ´Øª:"
-  text_enumeration_destroy_question: "%{count} Ø¯Ø§Ø¯Ù‡ Ø¨Ù‡ Ø§ÛŒÙ† Ø¨Ø±Ø´Ù…Ø±Ø¯Ù†ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡ Ø´Ø¯Ù‡â€ŒØ§Ù†Ø¯."
-  text_enumeration_category_reassign_to: 'Ø¨Ù‡ Ø§ÛŒÙ† Ø¨Ø±Ø´Ù…Ø±Ø¯Ù†ÛŒ ÙˆØ§Ø¨Ø³ØªÙ‡ Ø´ÙˆÙ†Ø¯:'
-  text_email_delivery_not_configured: "Ø¯Ø±ÛŒØ§ÙØª Ø§ÛŒÙ…ÛŒÙ„ Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª Ùˆ Ø¢Ú¯Ø§Ù‡â€ŒØ³Ø§Ø²ÛŒâ€ŒÙ‡Ø§ ØºÛŒØ± ÙØ¹Ø§Ù„ Ù‡Ø³ØªÙ†Ø¯.\nÚ©Ø§Ø±Ú¯Ø²Ø§Ø± SMTP Ø®ÙˆØ¯ Ø±Ø§ Ø¯Ø± config/configuration.yml Ù¾ÛŒÚ©Ø±Ø¨Ù†Ø¯ÛŒ Ú©Ù†ÛŒØ¯ Ùˆ Ø¨Ø±Ù†Ø§Ù…Ù‡ Ø±Ø§ Ø¨Ø§Ø²Ù†Ø´Ø§Ù†ÛŒ Ú©Ù†ÛŒØ¯ ØªØ§ ÙØ¹Ø§Ù„ Ø´ÙˆÙ†Ø¯."
-  text_repository_usernames_mapping: "Ú©Ø§Ø±Ø¨Ø± Redmine Ú©Ù‡ Ø¨Ù‡ Ù‡Ø± Ù†Ø§Ù… Ú©Ø§Ø±Ø¨Ø±ÛŒ Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡ Ù†Ú¯Ø§Ø´Øª Ù…ÛŒâ€ŒØ´ÙˆØ¯ Ø±Ø§ Ø¨Ø±Ú¯Ø²ÛŒÙ†ÛŒØ¯.\nÚ©Ø§Ø±Ø¨Ø±Ø§Ù†ÛŒ Ú©Ù‡ Ù†Ø§Ù… Ú©Ø§Ø±Ø¨Ø±ÛŒ ÛŒØ§ Ø§ÛŒÙ…ÛŒÙ„ Ù‡Ù…Ø³Ø§Ù† Ø¯Ø§Ø±Ù†Ø¯ØŒ Ø®ÙˆØ¯ Ø¨Ù‡ Ø®ÙˆØ¯ Ù†Ú¯Ø§Ø´Øª Ù…ÛŒâ€ŒØ´ÙˆÙ†Ø¯."
-  text_diff_truncated: '... Ø§ÛŒÙ† ØªÙØ§ÙˆØª Ø¨Ø±ÛŒØ¯Ù‡ Ø´Ø¯Ù‡ Ú†ÙˆÙ† Ø¨ÛŒØ´ØªØ± Ø§Ø² Ø¨ÛŒØ´ØªØ±ÛŒÙ† Ø§Ù†Ø¯Ø§Ø²Ù‡ Ù†Ù…Ø§ÛŒØ´ Ø¯Ø§Ø¯Ù†ÛŒ Ø§Ø³Øª.'
-  text_custom_field_possible_values_info: 'ÛŒÚ© Ø®Ø· Ø¨Ø±Ø§ÛŒ Ù‡Ø± Ù…Ù‚Ø¯Ø§Ø±'
-  text_wiki_page_destroy_question: "Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡ %{descendants} Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡ Ø¯Ø§Ø±Ø¯.Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ú†Ù‡ Ú©Ù†ÛŒØ¯ØŸ"
-  text_wiki_page_nullify_children: "Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ Ø¨Ø±Ú¯Ù‡ Ø±ÛŒØ´Ù‡ Ø´ÙˆÙ†Ø¯"
-  text_wiki_page_destroy_children: "Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ Ùˆ Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ÛŒ Ø¢Ù†â€ŒÙ‡Ø§ Ù¾Ø§Ú© Ø´ÙˆÙ†Ø¯"
-  text_wiki_page_reassign_children: "Ø²ÛŒØ±Ø¨Ø±Ú¯Ù‡â€ŒÙ‡Ø§ Ø¨Ù‡ Ø²ÛŒØ± Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡ Ù¾Ø¯Ø± Ø¨Ø±ÙˆÙ†Ø¯"
-  text_own_membership_delete_confirmation: "Ø´Ù…Ø§ Ø¯Ø§Ø±ÛŒØ¯ Ø¨Ø±Ø®ÛŒ ÛŒØ§ Ù‡Ù…Ù‡ Ù¾Ø±ÙˆØ§Ù†Ù‡â€ŒÙ‡Ø§ÛŒ Ø®ÙˆØ¯ Ø±Ø§ Ø¨Ø±Ù…ÛŒâ€ŒØ¯Ø§Ø±ÛŒØ¯ Ùˆ Ø´Ø§ÛŒØ¯ Ù¾Ø³ Ø§Ø² Ø§ÛŒÙ† Ø¯ÛŒÚ¯Ø± Ù†ØªÙˆØ§Ù†ÛŒØ¯ Ø§ÛŒÙ† Ù¾Ø±ÙˆÚ˜Ù‡ Ø±Ø§ ÙˆÛŒØ±Ø§ÛŒØ´ Ú©Ù†ÛŒØ¯.\nØ¢ÛŒØ§ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ø§ÛŒÙ† Ú©Ø§Ø± Ø±Ø§ Ø¨Ú©Ù†ÛŒØ¯ØŸ"
-  text_zoom_in: Ø¯Ø±Ø´ØªÙ†Ù…Ø§ÛŒÛŒ
-  text_zoom_out: Ø±ÛŒØ²Ù†Ù…Ø§ÛŒÛŒ
-  
-  default_role_manager: Ø³Ø±Ù¾Ø±Ø³Øª
-  default_role_developer: Ø¨Ø±Ù†Ø§Ù…Ù‡â€ŒÙ†ÙˆÛŒØ³
-  default_role_reporter: Ú¯Ø²Ø§Ø±Ø´â€ŒØ¯Ù‡Ù†Ø¯Ù‡
-  default_tracker_bug: Ø§ÛŒØ±Ø§Ø¯
-  default_tracker_feature: ÙˆÛŒÚ˜Ú¯ÛŒ
-  default_tracker_support: Ù¾Ø´ØªÛŒØ¨Ø§Ù†ÛŒ
-  default_issue_status_new: ØªØ§Ø²Ù‡
-  default_issue_status_in_progress: Ø¯Ø± Ú¯Ø±Ø¯Ø´
-  default_issue_status_resolved: Ø¯Ø±Ø³Øª Ø´Ø¯Ù‡
-  default_issue_status_feedback: Ø¨Ø§Ø²Ø®ÙˆØ±Ø¯
-  default_issue_status_closed: Ø¨Ø³ØªÙ‡
-  default_issue_status_rejected: Ø¨Ø±Ú¯Ø´Øª Ø®ÙˆØ±Ø¯Ù‡
-  default_doc_category_user: Ù†ÙˆØ´ØªØ§Ø± Ú©Ø§Ø±Ø¨Ø±
-  default_doc_category_tech: Ù†ÙˆØ´ØªØ§Ø± ÙÙ†ÛŒ
-  default_priority_low: Ù¾Ø§ÛŒÛŒÙ†
-  default_priority_normal: Ù…ÛŒØ§Ù†Ù‡
-  default_priority_high: Ø¨Ø§Ù„Ø§
-  default_priority_urgent: Ø²ÙˆØ¯
-  default_priority_immediate: Ø¨ÛŒØ¯Ø±Ù†Ú¯
-  default_activity_design: Ø·Ø±Ø§Ø­ÛŒ
-  default_activity_development: Ø³Ø§Ø®Øª
-  
-  enumeration_issue_priorities: Ø¨Ø±ØªØ±ÛŒâ€ŒÙ‡Ø§ÛŒ Ù¾ÛŒØ§Ù…Ø¯
-  enumeration_doc_categories: Ø¯Ø³ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ù†ÙˆØ´ØªØ§Ø±
-  enumeration_activities: Ú©Ø§Ø±Ù‡Ø§ (Ù¾ÛŒÚ¯ÛŒØ±ÛŒ Ø²Ù…Ø§Ù†)
-  enumeration_system_activity: Ú©Ø§Ø± Ø³Ø§Ù…Ø§Ù†Ù‡
-
-  text_tip_issue_begin_day: Ù¾ÛŒØ§Ù…Ø¯ Ø¯Ø± Ø§ÛŒÙ† Ø±ÙˆØ² Ø¢ØºØ§Ø² Ù…ÛŒâ€ŒØ´ÙˆØ¯
-  field_warn_on_leaving_unsaved: Ù‡Ù†Ú¯Ø§Ù… ØªØ±Ú© Ø¨Ø±Ú¯Ù‡â€ŒØ§ÛŒ Ú©Ù‡ Ù†ÙˆØ´ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ø¢Ù† Ù†Ú¯Ù‡Ø¯Ø§Ø±ÛŒ Ù†Ø´Ø¯Ù‡ØŒ Ø¨Ù‡ Ù…Ù† Ù‡Ø´Ø¯Ø§Ø± Ø¨Ø¯Ù‡
-  text_tip_issue_begin_end_day: Ù¾ÛŒØ§Ù…Ø¯ Ø¯Ø± Ø§ÛŒÙ† Ø±ÙˆØ² Ø¢ØºØ§Ø² Ù…ÛŒâ€ŒØ´ÙˆØ¯ Ùˆ Ù¾Ø§ÛŒØ§Ù† Ù…ÛŒâ€ŒÙ¾Ø°ÛŒØ±Ø¯
-  text_tip_issue_end_day: Ù¾ÛŒØ§Ù…Ø¯ Ø¯Ø± Ø§ÛŒÙ† Ø±ÙˆØ² Ù¾Ø§ÛŒØ§Ù† Ù…ÛŒâ€ŒÙ¾Ø°ÛŒØ±Ø¯
-  text_warn_on_leaving_unsaved: Ø§ÛŒÙ† Ø¨Ø±Ú¯Ù‡ Ø¯Ø§Ø±Ø§ÛŒ Ù†ÙˆØ´ØªÙ‡â€ŒÙ‡Ø§ÛŒ Ù†Ú¯Ù‡Ø¯Ø§Ø±ÛŒ Ù†Ø´Ø¯Ù‡ Ø§Ø³Øª Ú©Ù‡ Ø§Ú¯Ø± Ø¢Ù† Ø±Ø§ ØªØ±Ú© Ú©Ù†ÛŒØ¯ØŒ Ø§Ø² Ù…ÛŒØ§Ù† Ù…ÛŒâ€ŒØ±ÙˆÙ†Ø¯.
-  label_my_queries: Ø¬Ø³ØªØ§Ø±Ù‡Ø§ÛŒ Ø³ÙØ§Ø±Ø´ÛŒ Ù…Ù†
-  text_journal_changed_no_detail: "%{label} Ø¨Ø±ÙˆØ² Ø´Ø¯"
-  label_news_comment_added: Ø¯ÛŒØ¯Ú¯Ø§Ù‡ Ø¨Ù‡ ÛŒÚ© Ø±ÙˆÛŒØ¯Ø§Ø¯ Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
-  button_expand_all: Ø¨Ø§Ø² Ú©Ø±Ø¯Ù† Ù‡Ù…Ù‡
-  button_collapse_all: Ø¨Ø³ØªÙ† Ù‡Ù…Ù‡
-  label_additional_workflow_transitions_for_assignee: Ø²Ù…Ø§Ù†ÛŒ Ú©Ù‡ Ø¨Ù‡ Ú©Ø§Ø±Ø¨Ø± ÙˆØ§Ú¯Ø°Ø§Ø± Ø´Ø¯Ù‡ØŒ Ú¯Ø°Ø§Ø±Ù‡Ø§ÛŒ Ø¨ÛŒØ´ØªØ± Ù¾Ø°ÛŒØ±ÙØªÙ‡ Ù…ÛŒâ€ŒØ´ÙˆØ¯
-  label_additional_workflow_transitions_for_author: Ø²Ù…Ø§Ù†ÛŒ Ú©Ù‡ Ú©Ø§Ø±Ø¨Ø± Ù†ÙˆÛŒØ³Ù†Ø¯Ù‡ Ø§Ø³ØªØŒ Ú¯Ø°Ø§Ø±Ù‡Ø§ÛŒ Ø¨ÛŒØ´ØªØ± Ù¾Ø°ÛŒØ±ÙØªÙ‡ Ù…ÛŒâ€ŒØ´ÙˆØ¯
-  label_bulk_edit_selected_time_entries: ÙˆÛŒØ±Ø§ÛŒØ´ Ø¯Ø³ØªÙ‡â€ŒØ§ÛŒ Ø²Ù…Ø§Ù†â€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡
-  text_time_entries_destroy_confirmation: Ø¢ÛŒØ§ Ù…ÛŒâ€ŒØ®ÙˆØ§Ù‡ÛŒØ¯ Ø²Ù…Ø§Ù†â€ŒÙ‡Ø§ÛŒ Ú¯Ø²Ø§Ø±Ø´ Ø´Ø¯Ù‡ Ú¯Ø²ÛŒÙ†Ø´ Ø´Ø¯Ù‡ Ù¾Ø§Ú© Ø´ÙˆÙ†Ø¯ØŸ
-  label_role_anonymous: Ù†Ø§Ø´Ù†Ø§Ø³
-  label_role_non_member: ØºÛŒØ± Ø¹Ø¶Ùˆ
-  label_issue_note_added: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª Ø§ÙØ²ÙˆØ¯Ù‡ Ø´Ø¯
-  label_issue_status_updated: ÙˆØ¶Ø¹ÛŒØª Ø¨Ø±ÙˆØ² Ø´Ø¯
-  label_issue_priority_updated: Ø¨Ø±ØªØ±ÛŒ Ø¨Ø±ÙˆØ² Ø´Ø¯
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Ú©Ø¯Ú¯Ø°Ø§Ø±ÛŒ Ù¾ÛŒØ§Ù…â€ŒÙ‡Ø§ÛŒ Ø§Ù†Ø¨Ø§Ø±Ù‡
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1e/1eeb2d3cf254cdaa3fced154da1af384e6d301db.svn-base
--- a/.svn/pristine/1e/1eeb2d3cf254cdaa3fced154da1af384e6d301db.svn-base
+++ /dev/null
@@ -1,186 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'workflows_controller'
-
-# Re-raise errors caught by the controller.
-class WorkflowsController; def rescue_action(e) raise e end; end
-
-class WorkflowsControllerTest < ActionController::TestCase
-  fixtures :roles, :trackers, :workflows, :users, :issue_statuses
-
-  def setup
-    @controller = WorkflowsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @request.session[:user_id] = 1 # admin
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-
-    count = Workflow.count(:all, :conditions => 'role_id = 1 AND tracker_id = 2')
-    assert_tag :tag => 'a', :content => count.to_s,
-                            :attributes => { :href => '/workflows/edit?role_id=1&amp;tracker_id=2' }
-  end
-
-  def test_get_edit
-    get :edit
-    assert_response :success
-    assert_template 'edit'
-    assert_not_nil assigns(:roles)
-    assert_not_nil assigns(:trackers)
-  end
-
-  def test_get_edit_with_role_and_tracker
-    Workflow.delete_all
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
-    Workflow.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
-
-    get :edit, :role_id => 2, :tracker_id => 1
-    assert_response :success
-    assert_template 'edit'
-
-    # used status only
-    assert_not_nil assigns(:statuses)
-    assert_equal [2, 3, 5], assigns(:statuses).collect(&:id)
-
-    # allowed transitions
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'issue_status[3][5][]',
-                                                 :value => 'always',
-                                                 :checked => 'checked' }
-    # not allowed
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'issue_status[3][2][]',
-                                                 :value => 'always',
-                                                 :checked => nil }
-    # unused
-    assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                    :name => 'issue_status[1][1][]' }
-  end
-
-  def test_get_edit_with_role_and_tracker_and_all_statuses
-    Workflow.delete_all
-
-    get :edit, :role_id => 2, :tracker_id => 1, :used_statuses_only => '0'
-    assert_response :success
-    assert_template 'edit'
-
-    assert_not_nil assigns(:statuses)
-    assert_equal IssueStatus.count, assigns(:statuses).size
-
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'issue_status[1][1][]',
-                                                 :value => 'always',
-                                                 :checked => nil }
-  end
-
-  def test_post_edit
-    post :edit, :role_id => 2, :tracker_id => 1,
-      :issue_status => {
-        '4' => {'5' => ['always']},
-        '3' => {'1' => ['always'], '2' => ['always']}
-      }
-    assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
-
-    assert_equal 3, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
-    assert_not_nil  Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
-    assert_nil      Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4})
-  end
-
-  def test_post_edit_with_additional_transitions
-    post :edit, :role_id => 2, :tracker_id => 1,
-      :issue_status => {
-        '4' => {'5' => ['always']},
-        '3' => {'1' => ['author'], '2' => ['assignee'], '4' => ['author', 'assignee']}
-      }
-    assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
-
-    assert_equal 4, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
-
-    w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5})
-    assert ! w.author
-    assert ! w.assignee
-    w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1})
-    assert w.author
-    assert ! w.assignee
-    w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
-    assert ! w.author
-    assert w.assignee
-    w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4})
-    assert w.author
-    assert w.assignee
-  end
-
-  def test_clear_workflow
-    assert Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2}) > 0
-
-    post :edit, :role_id => 2, :tracker_id => 1
-    assert_equal 0, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
-  end
-
-  def test_get_copy
-    get :copy
-    assert_response :success
-    assert_template 'copy'
-  end
-
-  def test_post_copy_one_to_one
-    source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
-
-    post :copy, :source_tracker_id => '1', :source_role_id => '2',
-                :target_tracker_ids => ['3'], :target_role_ids => ['1']
-    assert_response 302
-    assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
-  end
-
-  def test_post_copy_one_to_many
-    source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
-
-    post :copy, :source_tracker_id => '1', :source_role_id => '2',
-                :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
-    assert_response 302
-    assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 1)
-    assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
-    assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 3)
-    assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 3)
-  end
-
-  def test_post_copy_many_to_many
-    source_t2 = status_transitions(:tracker_id => 2, :role_id => 2)
-    source_t3 = status_transitions(:tracker_id => 3, :role_id => 2)
-
-    post :copy, :source_tracker_id => 'any', :source_role_id => '2',
-                :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
-    assert_response 302
-    assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 1)
-    assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 1)
-    assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 3)
-    assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 3)
-  end
-
-  # Returns an array of status transitions that can be compared
-  def status_transitions(conditions)
-    Workflow.find(:all, :conditions => conditions,
-                        :order => 'tracker_id, role_id, old_status_id, new_status_id').collect {|w| [w.old_status, w.new_status_id]}
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1e/1ef1c1b3db8e0ec86373a9f847e88d0b2afb5d10.svn-base
--- a/.svn/pristine/1e/1ef1c1b3db8e0ec86373a9f847e88d0b2afb5d10.svn-base
+++ /dev/null
@@ -1,2 +0,0 @@
-class AssetsController < ApplicationController
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1f/1f0cbd778ac799db40d158f816d90f939c73e314.svn-base
--- /dev/null
+++ b/.svn/pristine/1f/1f0cbd778ac799db40d158f816d90f939c73e314.svn-base
@@ -0,0 +1,73 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Helpers
+    class Diff
+      include ERB::Util
+      include ActionView::Helpers::TagHelper
+      include ActionView::Helpers::TextHelper
+      attr_reader :diff, :words
+
+      def initialize(content_to, content_from)
+        @words = content_to.to_s.split(/(\s+)/)
+        @words = @words.select {|word| word != ' '}
+        words_from = content_from.to_s.split(/(\s+)/)
+        words_from = words_from.select {|word| word != ' '}
+        @diff = words_from.diff @words
+      end
+
+      def to_html
+        words = self.words.collect{|word| h(word)}
+        words_add = 0
+        words_del = 0
+        dels = 0
+        del_off = 0
+        diff.diffs.each do |diff|
+          add_at = nil
+          add_to = nil
+          del_at = nil
+          deleted = ""
+          diff.each do |change|
+            pos = change[1]
+            if change[0] == "+"
+              add_at = pos + dels unless add_at
+              add_to = pos + dels
+              words_add += 1
+            else
+              del_at = pos unless del_at
+              deleted << ' ' unless deleted.empty?
+              deleted << h(change[2])
+              words_del  += 1
+            end
+          end
+          if add_at
+            words[add_at] = '<span class="diff_in">'.html_safe + words[add_at]
+            words[add_to] = words[add_to] + '</span>'.html_safe
+          end
+          if del_at
+            words.insert del_at - del_off + dels + words_add, '<span class="diff_out">'.html_safe + deleted + '</span>'.html_safe
+            dels += 1
+            del_off += words_del
+            words_del = 0
+          end
+        end
+        words.join(' ').html_safe
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1f/1f46b0be9dff718da9b5754753e6d89331b5e22e.svn-base
--- /dev/null
+++ b/.svn/pristine/1f/1f46b0be9dff718da9b5754753e6d89331b5e22e.svn-base
@@ -0,0 +1,24 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module AuthSourcesHelper
+  def auth_source_partial_name(auth_source)
+    "form_#{auth_source.class.name.underscore}"
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1f/1f572940b49da993424874b4b9bed1d524fcea35.svn-base
--- a/.svn/pristine/1f/1f572940b49da993424874b4b9bed1d524fcea35.svn-base
+++ /dev/null
@@ -1,95 +0,0 @@
-module CodeRay
-  
-  # A little hack to enable CodeRay highlighting in RedCloth.
-  # 
-  # Usage:
-  #  require 'coderay'
-  #  require 'coderay/for_redcloth'
-  #  RedCloth.new('@[ruby]puts "Hello, World!"@').to_html
-  # 
-  # Make sure you have RedCloth 4.0.3 activated, for example by calling
-  #  require 'rubygems'
-  # before RedCloth is loaded and before calling CodeRay.for_redcloth.
-  module ForRedCloth
-    
-    def self.install
-      gem 'RedCloth', '>= 4.0.3' if defined? gem
-      require 'redcloth'
-      unless RedCloth::VERSION.to_s >= '4.0.3'
-        if defined? gem
-          raise 'CodeRay.for_redcloth needs RedCloth version 4.0.3 or later. ' +
-            "You have #{RedCloth::VERSION}. Please gem install RedCloth."
-        else
-          $".delete 'redcloth.rb'  # sorry, but it works
-          require 'rubygems'
-          return install  # retry
-        end
-      end
-      unless RedCloth::VERSION.to_s >= '4.2.2'
-        warn 'CodeRay.for_redcloth works best with RedCloth version 4.2.2 or later.'
-      end
-      RedCloth::TextileDoc.send :include, ForRedCloth::TextileDoc
-      RedCloth::Formatters::HTML.module_eval do
-        def unescape(html)  # :nodoc:
-          replacements = {
-            '&amp;' => '&',
-            '&quot;' => '"',
-            '&gt;' => '>',
-            '&lt;' => '<',
-          }
-          html.gsub(/&(?:amp|quot|[gl]t);/) { |entity| replacements[entity] }
-        end
-        undef code, bc_open, bc_close, escape_pre
-        def code(opts)  # :nodoc:
-          opts[:block] = true
-          if !opts[:lang] && RedCloth::VERSION.to_s >= '4.2.0'
-            # simulating pre-4.2 behavior
-            if opts[:text].sub!(/\A\[(\w+)\]/, '')
-              if CodeRay::Scanners[$1].lang == :text
-                opts[:text] = $& + opts[:text]
-              else
-                opts[:lang] = $1
-              end
-            end
-          end
-          if opts[:lang] && !filter_coderay
-            require 'coderay'
-            @in_bc ||= nil
-            format = @in_bc ? :div : :span
-            opts[:text] = unescape(opts[:text]) unless @in_bc
-            highlighted_code = CodeRay.encode opts[:text], opts[:lang], format
-            highlighted_code.sub!(/\A<(span|div)/) { |m| m + pba(@in_bc || opts) }
-            highlighted_code
-          else
-            "<code#{pba(opts)}>#{opts[:text]}</code>"
-          end
-        end
-        def bc_open(opts)  # :nodoc:
-          opts[:block] = true
-          @in_bc = opts
-          opts[:lang] ? '' : "<pre#{pba(opts)}>"
-        end
-        def bc_close(opts)  # :nodoc:
-          opts = @in_bc
-          @in_bc = nil
-          opts[:lang] ? '' : "</pre>\n"
-        end
-        def escape_pre(text)  # :nodoc:
-          if @in_bc ||= nil
-            text
-          else
-            html_esc(text, :html_escape_preformatted)
-          end
-        end
-      end
-    end
-
-    module TextileDoc  # :nodoc:
-      attr_accessor :filter_coderay
-    end
-    
-  end
-  
-end
-
-CodeRay::ForRedCloth.install
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1f/1f78c9cd9879f6fcb3d4c7ae2bf80de5b578d42c.svn-base
--- a/.svn/pristine/1f/1f78c9cd9879f6fcb3d4c7ae2bf80de5b578d42c.svn-base
+++ /dev/null
@@ -1,56 +0,0 @@
-<% show_revision_graph = ( @repository.supports_revision_graph? && path.blank? ) %>
-<% form_tag({:controller => 'repositories', :action => 'diff', :id => @project, :path => to_path_param(path)}, :method => :get) do %>
-<table class="list changesets">
-<thead><tr>
-<% if show_revision_graph %>
-  <th></th>
-<% end %>
-<th>#</th>
-<th></th>
-<th></th>
-<th><%= l(:label_date) %></th>
-<th><%= l(:field_author) %></th>
-<th><%= l(:field_comments) %></th>
-</tr></thead>
-<tbody>
-<% show_diff = revisions.size > 1 %>
-<% line_num = 1 %>
-<% revisions.each do |changeset| %>
-<tr class="changeset <%= cycle 'odd', 'even' %>">
-<% if show_revision_graph %>
-  <% if line_num == 1 %>
-    <td class="revision_graph" rowspan="<%= revisions.size %>">
-      <% href_base = Proc.new {|x| url_for(:controller => 'repositories',
-                                           :action => 'revision',
-                                           :id => project,
-                                           :rev => x) } %>
-      <%= render :partial => 'revision_graph',
-                 :locals => {
-                    :commits => index_commits(
-                                         revisions,
-                                         @repository.branches,
-                                         href_base
-                                            )
-                    } %>
-    </td>
-  <% end %>
-<% end %>
-<td class="id"><%= link_to_revision(changeset, project) %></td>
-<td class="checkbox"><%= radio_button_tag('rev', changeset.identifier, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < revisions.size) %></td>
-<td class="checkbox"><%= radio_button_tag('rev_to', changeset.identifier, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('cb-#{line_num}').checked==true) {$('cb-#{line_num-1}').checked=true;}") if show_diff && (line_num > 1) %></td>
-<td class="committed_on"><%= format_time(changeset.committed_on) %></td>
-<td class="author"><%= h truncate(changeset.author.to_s, :length => 30) %></td>
-<% if show_revision_graph %>
-  <td class="comments_nowrap">
-    <%= textilizable(truncate(truncate_at_line_break(changeset.comments, 0), :length => 90)) %>
-  </td>
-<% else %>
-  <td class="comments"><%= textilizable(truncate_at_line_break(changeset.comments)) %></td>
-<% end %>
-</tr>
-<% line_num += 1 %>
-<% end %>
-</tbody>
-</table>
-<%= submit_tag(l(:label_view_diff), :name => nil) if show_diff %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1f/1fa67dac1aa9c162206c0f56eb10970df326cd79.svn-base
--- a/.svn/pristine/1f/1fa67dac1aa9c162206c0f56eb10970df326cd79.svn-base
+++ /dev/null
@@ -1,26 +0,0 @@
-<div class="contextual">
-<%= watcher_tag(@wiki, User.current) %>
-</div>
-
-<h2><%= l(:label_index_by_title) %></h2>
-
-<% if @pages.empty? %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
-
-<%= render_page_hierarchy(@pages_by_parent_id, nil, :timestamp => true) %>
-
-<% content_for :sidebar do %>
-  <%= render :partial => 'sidebar' %>
-<% end %>
-
-<% unless @pages.empty? %>
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :key => User.current.rss_key} %>
-  <%= f.link_to('HTML', :url => {:action => 'export'}) if User.current.allowed_to?(:export_wiki_pages, @project) %>
-<% end %>
-<% end %>
-
-<% content_for :header_tags do %>
-<%= auto_discovery_link_tag(:atom, :controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :format => 'atom', :key => User.current.rss_key) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1f/1fb867d43b925bd44b6fa06a149ecabad4787c36.svn-base
--- a/.svn/pristine/1f/1fb867d43b925bd44b6fa06a149ecabad4787c36.svn-base
+++ /dev/null
@@ -1,141 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'admin_controller'
-
-# Re-raise errors caught by the controller.
-class AdminController; def rescue_action(e) raise e end; end
-
-class AdminControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles
-
-  def setup
-    @controller = AdminController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @request.session[:user_id] = 1 # admin
-  end
-
-  def test_index
-    get :index
-    assert_no_tag :tag => 'div',
-                  :attributes => { :class => /nodata/ }
-  end
-
-  def test_index_with_no_configuration_data
-    delete_configuration_data
-    get :index
-    assert_tag :tag => 'div',
-               :attributes => { :class => /nodata/ }
-  end
-
-  def test_projects
-    get :projects
-    assert_response :success
-    assert_template 'projects'
-    assert_not_nil assigns(:projects)
-    # active projects only
-    assert_nil assigns(:projects).detect {|u| !u.active?}
-  end
-
-  def test_projects_with_name_filter
-    get :projects, :name => 'store', :status => ''
-    assert_response :success
-    assert_template 'projects'
-    projects = assigns(:projects)
-    assert_not_nil projects
-    assert_equal 1, projects.size
-    assert_equal 'OnlineStore', projects.first.name
-  end
-
-  def test_load_default_configuration_data
-    delete_configuration_data
-    post :default_configuration, :lang => 'fr'
-    assert_response :redirect
-    assert_nil flash[:error]
-    assert IssueStatus.find_by_name('Nouveau')
-  end
-
-  def test_test_email
-    get :test_email
-    assert_redirected_to '/settings/edit?tab=notifications'
-    mail = ActionMailer::Base.deliveries.last
-    assert_kind_of TMail::Mail, mail
-    user = User.find(1)
-    assert_equal [user.mail], mail.bcc
-  end
-
-  def test_no_plugins
-    Redmine::Plugin.clear
-
-    get :plugins
-    assert_response :success
-    assert_template 'plugins'
-  end
-
-  def test_plugins
-    # Register a few plugins
-    Redmine::Plugin.register :foo do
-      name 'Foo plugin'
-      author 'John Smith'
-      description 'This is a test plugin'
-      version '0.0.1'
-      settings :default => {'sample_setting' => 'value', 'foo'=>'bar'}, :partial => 'foo/settings'
-    end
-    Redmine::Plugin.register :bar do
-    end
-
-    get :plugins
-    assert_response :success
-    assert_template 'plugins'
-
-    assert_tag :td, :child => { :tag => 'span', :content => 'Foo plugin' }
-    assert_tag :td, :child => { :tag => 'span', :content => 'Bar' }
-  end
-
-  def test_info
-    get :info
-    assert_response :success
-    assert_template 'info'
-  end
-
-  def test_admin_menu_plugin_extension
-    Redmine::MenuManager.map :admin_menu do |menu|
-      menu.push :test_admin_menu_plugin_extension, '/foo/bar', :caption => 'Test'
-    end
-
-    get :index
-    assert_response :success
-    assert_tag :a, :attributes => { :href => '/foo/bar' },
-                   :content => 'Test'
-
-    Redmine::MenuManager.map :admin_menu do |menu|
-      menu.delete :test_admin_menu_plugin_extension
-    end
-  end
-
-  private
-
-  def delete_configuration_data
-    Role.delete_all('builtin = 0')
-    Tracker.delete_all
-    IssueStatus.delete_all
-    Enumeration.delete_all
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1f/1fc4113fdbf747b80464d17633b16c0ed0796efd.svn-base
--- /dev/null
+++ b/.svn/pristine/1f/1fc4113fdbf747b80464d17633b16c0ed0796efd.svn-base
@@ -0,0 +1,7 @@
+<h2><%=l(:label_report_plural)%></h2>
+
+<h3><%=@report_title%></h3>
+<%= render :partial => 'details', :locals => { :data => @data, :field_name => @field, :rows => @rows } %>
+<br />
+<%= link_to l(:button_back), project_issues_report_path(@project) %>
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/1f/1fcb69836707f0f2797567ced5c5da34d64949eb.svn-base
--- a/.svn/pristine/1f/1fcb69836707f0f2797567ced5c5da34d64949eb.svn-base
+++ /dev/null
@@ -1,58 +0,0 @@
-<div class="contextual">
-  <%= link_to l(:label_version_new), new_project_version_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_versions, @project) %>
-</div>
-
-<h2><%=l(:label_roadmap)%></h2>
-
-<% if @versions.empty? %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% else %>
-<div id="roadmap">
-<% @versions.each do |version| %>
-    <h3 class="version"><%= tag 'a', :name => h(version.name) %><%= link_to_version version %></h3>
-    <%= render :partial => 'versions/overview', :locals => {:version => version} %>
-    <%= render(:partial => "wiki/content", :locals => {:content => version.wiki_page.content}) if version.wiki_page %>
-
-    <% if (issues = @issues_by_version[version]) && issues.size > 0 %>
-    <% form_tag({}) do -%>
-    <table class="list related-issues">
-    <caption><%= l(:label_related_issues) %></caption>
-    <% issues.each do |issue| -%>
-      <tr class="hascontextmenu">
-        <td class="checkbox"><%= check_box_tag 'ids[]', issue.id %></td>
-        <td><%= link_to_issue(issue, :project => (@project != issue.project)) %></td>
-      </tr>
-    <% end -%>
-    </table>
-    <% end %>
-    <% end %>
-    <%= call_hook :view_projects_roadmap_version_bottom, :version => version %>
-<% end %>
-</div>
-<% end %>
-
-<% content_for :sidebar do %>
-<% form_tag({}, :method => :get) do %>
-<h3><%= l(:label_roadmap) %></h3>
-<% @trackers.each do |tracker| %>
-  <label><%= check_box_tag "tracker_ids[]", tracker.id, (@selected_tracker_ids.include? tracker.id.to_s), :id => nil %>
-  <%=h tracker.name %></label><br />
-<% end %>
-<br />
-<label for="completed"><%= check_box_tag "completed", 1, params[:completed] %> <%= l(:label_show_completed_versions) %></label>
-<% if @project.descendants.active.any? %>
-  <%= hidden_field_tag 'with_subprojects', 0 %>
-  <br /><label><%= check_box_tag 'with_subprojects', 1, @with_subprojects %> <%=l(:label_subproject_plural)%></label>
-<% end %>
-<p><%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %></p>
-<% end %>
-
-<h3><%= l(:label_version_plural) %></h3>
-<% @versions.each do |version| %>
-<%= link_to format_version_name(version), "##{version.name}" %><br />
-<% end %>
-<% end %>
-
-<% html_title(l(:label_roadmap)) %>
-
-<%= context_menu issues_context_menu_path %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/20/202b3d81f943caf51ec23281dde3cf26313ba319.svn-base
--- a/.svn/pristine/20/202b3d81f943caf51ec23281dde3cf26313ba319.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= link_to l(@enumeration.option_name), :controller => 'enumerations', :action => 'index' %> &#187; <%=l(:label_enumeration_new)%></h2>
-
-<% form_tag({:action => 'create'}, :class => "tabular") do %>
-  <%= render :partial => 'form' %>
-  <%= submit_tag l(:button_create) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/20/2087b528196b7332c8234e9ab56b21a9c4114103.svn-base
--- /dev/null
+++ b/.svn/pristine/20/2087b528196b7332c8234e9ab56b21a9c4114103.svn-base
@@ -0,0 +1,49 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class DefaultDataTest < ActiveSupport::TestCase
+  include Redmine::I18n
+  fixtures :roles
+
+  def test_no_data
+    assert !Redmine::DefaultData::Loader::no_data?
+    Role.delete_all("builtin = 0")
+    Tracker.delete_all
+    IssueStatus.delete_all
+    Enumeration.delete_all
+    assert Redmine::DefaultData::Loader::no_data?
+  end
+
+  def test_load
+    valid_languages.each do |lang|
+      begin
+        Role.delete_all("builtin = 0")
+        Tracker.delete_all
+        IssueStatus.delete_all
+        Enumeration.delete_all
+        assert Redmine::DefaultData::Loader::load(lang)
+        assert_not_nil DocumentCategory.first
+        assert_not_nil IssuePriority.first
+        assert_not_nil TimeEntryActivity.first
+      rescue ActiveRecord::RecordInvalid => e
+        assert false, ":#{lang} default data is invalid (#{e.message})."
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/20/2098d41250dd6484652b4b39b955e37f96aa4bb6.svn-base
--- a/.svn/pristine/20/2098d41250dd6484652b4b39b955e37f96aa4bb6.svn-base
+++ /dev/null
@@ -1,114 +0,0 @@
-
-require 'active_record'
-
-module ActiveRecord
-  class Base
-    include Redmine::I18n
-
-    # Translate attribute names for validation errors display
-    def self.human_attribute_name(attr)
-      l("field_#{attr.to_s.gsub(/_id$/, '')}", :default => attr)
-    end
-  end
-end
-
-module ActiveRecord
-  class Errors
-    def full_messages(options = {})
-      full_messages = []
-
-      @errors.each_key do |attr|
-        @errors[attr].each do |message|
-          next unless message
-
-          if attr == "base"
-            full_messages << message
-          elsif attr == "custom_values"
-            # Replace the generic "custom values is invalid"
-            # with the errors on custom values
-            @base.custom_values.each do |value|
-              value.errors.each do |attr, msg|
-                full_messages << value.custom_field.name + ' ' + msg
-              end
-            end
-          else
-            attr_name = @base.class.human_attribute_name(attr)
-            full_messages << attr_name + ' ' + message.to_s
-          end
-        end
-      end
-      full_messages
-    end
-  end
-end
-
-module ActionView
-  module Helpers
-    module DateHelper
-      # distance_of_time_in_words breaks when difference is greater than 30 years
-      def distance_of_date_in_words(from_date, to_date = 0, options = {})
-        from_date = from_date.to_date if from_date.respond_to?(:to_date)
-        to_date = to_date.to_date if to_date.respond_to?(:to_date)
-        distance_in_days = (to_date - from_date).abs
-
-        I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale|
-          case distance_in_days
-            when 0..60     then locale.t :x_days,             :count => distance_in_days.round
-            when 61..720   then locale.t :about_x_months,     :count => (distance_in_days / 30).round
-            else                locale.t :over_x_years,       :count => (distance_in_days / 365).floor
-          end
-        end
-      end
-    end
-  end
-end
-
-ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
-
-module AsynchronousMailer
-  # Adds :async_smtp and :async_sendmail delivery methods
-  # to perform email deliveries asynchronously
-  %w(smtp sendmail).each do |type|
-    define_method("perform_delivery_async_#{type}") do |mail|
-      Thread.start do
-        send "perform_delivery_#{type}", mail
-      end
-    end
-  end
-
-  # Adds a delivery method that writes emails in tmp/emails for testing purpose
-  def perform_delivery_tmp_file(mail)
-    dest_dir = File.join(Rails.root, 'tmp', 'emails')
-    Dir.mkdir(dest_dir) unless File.directory?(dest_dir)
-    File.open(File.join(dest_dir, mail.message_id.gsub(/[<>]/, '') + '.eml'), 'wb') {|f| f.write(mail.encoded) }
-  end
-end
-
-ActionMailer::Base.send :include, AsynchronousMailer
-
-module TMail
-  # TMail::Unquoter.convert_to_with_fallback_on_iso_8859_1 introduced in TMail 1.2.7
-  # triggers a test failure in test_add_issue_with_japanese_keywords(MailHandlerTest)
-  class Unquoter
-    class << self
-      alias_method :convert_to, :convert_to_without_fallback_on_iso_8859_1
-    end
-  end
-
-  # Patch for TMail 1.2.7. See http://www.redmine.org/issues/8751
-  class Encoder
-    def puts_meta(str)
-      add_text str
-    end
-  end
-end
-
-module ActionController
-  module MimeResponds
-    class Responder
-      def api(&block)
-        any(:xml, :json, &block)
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/20/20aee30a3886ed67fbcf2637dc7c9a63361c83fd.svn-base
--- /dev/null
+++ b/.svn/pristine/20/20aee30a3886ed67fbcf2637dc7c9a63361c83fd.svn-base
@@ -0,0 +1,90 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Group < Principal
+  include Redmine::SafeAttributes
+
+  has_and_belongs_to_many :users, :after_add => :user_added,
+                                  :after_remove => :user_removed
+
+  acts_as_customizable
+
+  validates_presence_of :lastname
+  validates_uniqueness_of :lastname, :case_sensitive => false
+  validates_length_of :lastname, :maximum => 255
+
+  before_destroy :remove_references_before_destroy
+
+  scope :sorted, lambda { order("#{table_name}.lastname ASC") }
+  scope :named, lambda {|arg| where("LOWER(#{table_name}.lastname) = LOWER(?)", arg.to_s.strip)}
+
+  safe_attributes 'name',
+    'user_ids',
+    'custom_field_values',
+    'custom_fields',
+    :if => lambda {|group, user| user.admin?}
+
+  def to_s
+    lastname.to_s
+  end
+
+  def name
+    lastname
+  end
+
+  def name=(arg)
+    self.lastname = arg
+  end
+
+  def user_added(user)
+    members.each do |member|
+      next if member.project.nil?
+      user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id)
+      member.member_roles.each do |member_role|
+        user_member.member_roles << MemberRole.new(:role => member_role.role, :inherited_from => member_role.id)
+      end
+      user_member.save!
+    end
+  end
+
+  def user_removed(user)
+    members.each do |member|
+      MemberRole.
+        includes(:member).
+        where("#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids).
+        all.
+        each(&:destroy)
+    end
+  end
+
+  def self.human_attribute_name(attribute_key_name, *args)
+    attr_name = attribute_key_name.to_s
+    if attr_name == 'lastname'
+      attr_name = "name"
+    end
+    super(attr_name, *args)
+  end
+
+  private
+
+  # Removes references that are not handled by associations
+  def remove_references_before_destroy
+    return if self.id.nil?
+
+    Issue.update_all 'assigned_to_id = NULL', ['assigned_to_id = ?', id]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/20/20bbceb95e51f40dbb36d0ff4569d0437a37f449.svn-base
--- a/.svn/pristine/20/20bbceb95e51f40dbb36d0ff4569d0437a37f449.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar SL language
-// Author: Jernej Vidmar, <jernej.vidmar@vidmarboehm.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Nedelja",
- "Ponedeljek",
- "Torek",
- "Sreda",
- "ÄŒetrtek",
- "Petek",
- "Sobota",
- "Nedelja");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Ned",
- "Pon",
- "Tor",
- "Sre",
- "ÄŒet",
- "Pet",
- "Sob",
- "Ned");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("Januar",
- "Februar",
- "Marec",
- "April",
- "Maj",
- "Junij",
- "Julij",
- "Avgust",
- "September",
- "Oktober",
- "November",
- "December");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "Mar",
- "Apr",
- "Maj",
- "Jun",
- "Jul",
- "Avg",
- "Sep",
- "Okt",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "O koledarju";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Izbira datuma:\n" +
-"- Uporabite \xab, \xbb gumbe za izbiro leta\n" +
-"- Uporabite " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " gumbe za izbiro meseca\n" +
-"- Za hitrejÅ¡o izbiro drÅ¾ite miÅ¡kin gumb nad enim od zgornjih gumbov.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Izbira Äasa:\n" +
-"- Kliknite na katerikoli del Äasa da ga poveÄate\n" +
-"- oziroma kliknite s Shiftom za zniÅ¾anje\n" +
-"- ali kliknite in vlecite za hitrejÅ¡o izbiro.";
-
-Calendar._TT["PREV_YEAR"] = "PrejÅ¡nje leto (drÅ¾ite za meni)";
-Calendar._TT["PREV_MONTH"] = "PrejÅ¡nji mesec (drÅ¾ite za meni)";
-Calendar._TT["GO_TODAY"] = "Pojdi na danes";
-Calendar._TT["NEXT_MONTH"] = "Naslednji mesec (drÅ¾ite za meni)";
-Calendar._TT["NEXT_YEAR"] = "Naslednje leto (drÅ¾ite za meni)";
-Calendar._TT["SEL_DATE"] = "Izberite datum";
-Calendar._TT["DRAG_TO_MOVE"] = "Povlecite za premik";
-Calendar._TT["PART_TODAY"] = " (danes)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Najprej prikaÅ¾i %s";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Zapri";
-Calendar._TT["TODAY"] = "Danes";
-Calendar._TT["TIME_PART"] = "(Shift-)klik ali povleÄi, da spremeniÅ¡ vrednost";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Time:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/20/20cfc1def6cf64da0d22e9f4697140fef8698ede.svn-base
--- /dev/null
+++ b/.svn/pristine/20/20cfc1def6cf64da0d22e9f4697140fef8698ede.svn-base
@@ -0,0 +1,24 @@
+class AddUniqueIndexOnCustomFieldsTrackers < ActiveRecord::Migration
+  def up
+    table_name = "#{CustomField.table_name_prefix}custom_fields_trackers#{CustomField.table_name_suffix}"
+    duplicates = CustomField.connection.select_rows("SELECT custom_field_id, tracker_id FROM #{table_name} GROUP BY custom_field_id, tracker_id HAVING COUNT(*) > 1")
+    duplicates.each do |custom_field_id, tracker_id|
+      # Removes duplicate rows
+      CustomField.connection.execute("DELETE FROM #{table_name} WHERE custom_field_id=#{custom_field_id} AND tracker_id=#{tracker_id}")
+      # And insert one
+      CustomField.connection.execute("INSERT INTO #{table_name} (custom_field_id, tracker_id) VALUES (#{custom_field_id}, #{tracker_id})")
+    end
+
+    if index_exists? :custom_fields_trackers, [:custom_field_id, :tracker_id]
+      remove_index :custom_fields_trackers, [:custom_field_id, :tracker_id]
+    end
+    add_index :custom_fields_trackers, [:custom_field_id, :tracker_id], :unique => true
+  end
+
+  def down
+    if index_exists? :custom_fields_trackers, [:custom_field_id, :tracker_id]
+      remove_index :custom_fields_trackers, [:custom_field_id, :tracker_id]
+    end
+    add_index :custom_fields_trackers, [:custom_field_id, :tracker_id]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/21/210ed78bd5324335e5f6bf0efa5404a9438fd74c.svn-base
--- a/.svn/pristine/21/210ed78bd5324335e5f6bf0efa5404a9438fd74c.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-<div class="splitcontentleft">
-<% i = 0 %>
-<% split_on = (@issue.custom_field_values.size / 2.0).ceil - 1 %>
-<% @issue.custom_field_values.each do |value| %>
-  <p><%= custom_field_tag_with_label :issue, value %></p>
-<% if i == split_on -%>
-</div><div class="splitcontentright">
-<% end -%>
-<% i += 1 -%>
-<% end -%>
-</div>
-<div style="clear:both;"> </div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/21/21220872c05ed094a0e17dfec9147a1d8f235a7a.svn-base
--- a/.svn/pristine/21/21220872c05ed094a0e17dfec9147a1d8f235a7a.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-class Meeting < ActiveRecord::Base
-  belongs_to :project
-
-  acts_as_event :title => Proc.new {|o| "#{o.scheduled_on} Meeting"},
-                :datetime => :scheduled_on,
-                :author => nil,
-                :url => Proc.new {|o| {:controller => 'meetings', :action => 'show', :id => o.id}}                
-  
-  acts_as_activity_provider :timestamp => 'scheduled_on',
-                            :find_options => { :include => :project }
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/21/213cd47b5ee47b691425e1fcb6dffb207c707d8c.svn-base
--- /dev/null
+++ b/.svn/pristine/21/213cd47b5ee47b691425e1fcb6dffb207c707d8c.svn-base
@@ -0,0 +1,5 @@
+/*! jQuery UI - v1.9.2 - 2012-12-26
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2C%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=759fcf&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=628db6&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=628db6&iconColorDefault=759fcf&bgColorHover=eef5fd&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=628db6&fcHover=628db6&iconColorHover=759fcf&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=628db6&fcActive=628db6&iconColorActive=759fcf&bgColorHighlight=759fcf&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=628db6&fcHighlight=363636&iconColorHighlight=759fcf&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
+* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;zoom:1}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto;zoom:1}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}* html .ui-autocomplete{width:1px}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:1.4}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0em}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current{float:right}.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;width:300px;overflow:hidden}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto;zoom:1}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em;zoom:1}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}* html .ui-tooltip{background-image:none}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #628db6;background:#759fcf url(images/ui-bg_gloss-wave_35_759fcf_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;background:#f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#628db6}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#628db6;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #628db6;background:#eef5fd url(images/ui-bg_glass_100_eef5fd_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#628db6}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#628db6;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #628db6;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#628db6}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#628db6;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #628db6;background:#759fcf url(images/ui-bg_highlight-soft_75_759fcf_1x100.png) 50% top repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_ffd27a_256x240.png)}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/21/217d8edc342d8c96ea1e479a7157b0c862da5448.svn-base
--- a/.svn/pristine/21/217d8edc342d8c96ea1e479a7157b0c862da5448.svn-base
+++ /dev/null
@@ -1,110 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'members_controller'
-
-# Re-raise errors caught by the controller.
-class MembersController; def rescue_action(e) raise e end; end
-
-
-class MembersControllerTest < ActionController::TestCase
-  fixtures :projects, :members, :member_roles, :roles, :users
-
-  def setup
-    @controller = MembersController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @request.session[:user_id] = 2
-  end
-
-  def test_create
-    assert_difference 'Member.count' do
-      post :new, :id => 1, :member => {:role_ids => [1], :user_id => 7}
-    end
-    assert_redirected_to '/projects/ecookbook/settings/members'
-    assert User.find(7).member_of?(Project.find(1))
-  end
-
-  def test_create_multiple
-    assert_difference 'Member.count', 3 do
-      post :new, :id => 1, :member => {:role_ids => [1], :user_ids => [7, 8, 9]}
-    end
-    assert_redirected_to '/projects/ecookbook/settings/members'
-    assert User.find(7).member_of?(Project.find(1))
-  end
-
-  def test_xhr_create
-    assert_difference 'Member.count', 3 do
-      post :new, :format => "js", :id => 1, :member => {:role_ids => [1], :user_ids => [7, 8, 9]}
-    end
-    assert_select_rjs :replace_html, 'tab-content-members'
-    assert User.find(7).member_of?(Project.find(1))
-    assert User.find(8).member_of?(Project.find(1))
-    assert User.find(9).member_of?(Project.find(1))
-  end
-
-  def test_xhr_create_with_failure
-    assert_no_difference 'Member.count' do
-      post :new, :format => "js", :id => 1, :member => {:role_ids => [], :user_ids => [7, 8, 9]}
-    end
-    assert_select '#tab-content-members', 0
-    assert @response.body.match(/alert/i), "Alert message not sent"
-  end
-
-  def test_edit
-    assert_no_difference 'Member.count' do
-      post :edit, :id => 2, :member => {:role_ids => [1], :user_id => 3}
-    end
-    assert_redirected_to '/projects/ecookbook/settings/members'
-  end
-
-  def test_xhr_edit
-    assert_no_difference 'Member.count' do
-      xhr :post, :edit, :id => 2, :member => {:role_ids => [1], :user_id => 3}
-    end
-    assert_select_rjs :replace_html, 'tab-content-members'
-    member = Member.find(2)
-    assert_equal [1], member.role_ids
-    assert_equal 3, member.user_id
-  end
-
-  def test_destroy
-    assert_difference 'Member.count', -1 do
-      post :destroy, :id => 2
-    end
-    assert_redirected_to '/projects/ecookbook/settings/members'
-    assert !User.find(3).member_of?(Project.find(1))
-  end
-
-  def test_xhr_destroy
-    assert_difference 'Member.count', -1 do
-      xhr :post, :destroy, :id => 2
-    end
-    assert_select_rjs :replace_html, 'tab-content-members'
-  end
-
-  def test_autocomplete_for_member
-    get :autocomplete_for_member, :id => 1, :q => 'mis'
-    assert_response :success
-    assert_template 'autocomplete_for_member'
-
-    assert_tag :label, :content => /User Misc/,
-                       :child => { :tag => 'input', :attributes => { :name => 'member[user_ids][]', :value => '8' } }
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/21/21b08aea1ac3dbc27c974e37d3d3c4f6952cdffd.svn-base
--- /dev/null
+++ b/.svn/pristine/21/21b08aea1ac3dbc27c974e37d3d3c4f6952cdffd.svn-base
@@ -0,0 +1,83 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'blankslate'
+
+module Redmine
+  module Views
+    module Builders
+      class Structure < BlankSlate
+        attr_accessor :request, :response
+
+        def initialize(request, response)
+          @struct = [{}]
+          self.request = request
+          self.response = response
+        end
+
+        def array(tag, options={}, &block)
+          @struct << []
+          block.call(self)
+          ret = @struct.pop
+          @struct.last[tag] = ret
+          @struct.last.merge!(options) if options
+        end
+
+        def method_missing(sym, *args, &block)
+          if args.any?
+            if args.first.is_a?(Hash)
+              if @struct.last.is_a?(Array)
+                @struct.last << args.first unless block
+              else
+                @struct.last[sym] = args.first
+              end
+            else
+              if @struct.last.is_a?(Array)
+                if args.size == 1 && !block_given?
+                  @struct.last << args.first
+                else
+                  @struct.last << (args.last || {}).merge(:value => args.first)
+                end
+              else
+                @struct.last[sym] = args.first
+              end
+            end
+          end
+
+          if block
+            @struct << (args.first.is_a?(Hash) ? args.first : {})
+            block.call(self)
+            ret = @struct.pop
+            if @struct.last.is_a?(Array)
+              @struct.last << ret
+            else
+              if @struct.last.has_key?(sym) && @struct.last[sym].is_a?(Hash)
+                @struct.last[sym].merge! ret
+              else
+                @struct.last[sym] = ret
+              end
+            end
+          end
+        end
+
+        def output
+          raise "Need to implement #{self.class.name}#output"
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/21/21bb59308736cf64ef50e8df95a55241d5b3beeb.svn-base
--- a/.svn/pristine/21/21bb59308736cf64ef50e8df95a55241d5b3beeb.svn-base
+++ /dev/null
@@ -1,58 +0,0 @@
-<div class="contextual">
-<%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %>
-</div>
-
-<h2><%=l(:label_user_plural)%></h2>
-
-<% form_tag({}, :method => :get) do %>
-<fieldset><legend><%= l(:label_filter_plural) %></legend>
-<label for='status'><%= l(:field_status) %>:</label>
-<%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;"  %>
-
-<% if @groups.present? %>
-<label for='group_id'><%= l(:label_group) %>:</label>
-<%= select_tag 'group_id', '<option></option>' + options_from_collection_for_select(@groups, :id, :name, params[:group_id].to_i), :onchange => "this.form.submit(); return false;"  %>
-<% end %>
-
-<label for='name'><%= l(:label_user) %>:</label>
-<%= text_field_tag 'name', params[:name], :size => 30 %>
-<%= submit_tag l(:button_apply), :class => "small", :name => nil %>
-<%= link_to l(:button_clear), users_path, :class => 'icon icon-reload' %>
-</fieldset>
-<% end %>
-&nbsp;
-
-<div class="autoscroll">
-<table class="list">
-  <thead><tr>
-  <%= sort_header_tag('login', :caption => l(:field_login)) %>
-  <%= sort_header_tag('firstname', :caption => l(:field_firstname)) %>
-  <%= sort_header_tag('lastname', :caption => l(:field_lastname)) %>
-  <%= sort_header_tag('mail', :caption => l(:field_mail)) %>
-  <%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %>
-  <%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %>
-  <%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %>
-    <th></th>
-  </tr></thead>
-  <tbody>
-<% for user in @users -%>
-  <tr class="user <%= cycle("odd", "even") %> <%= %w(anon active registered locked)[user.status] %>">
-  <td class="username"><%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %></td>
-  <td class="firstname"><%= h(user.firstname) %></td>
-  <td class="lastname"><%= h(user.lastname) %></td>
-  <td class="email"><%= mail_to(h(user.mail)) %></td>
-  <td align="center"><%= checked_image user.admin? %></td>
-  <td class="created_on" align="center"><%= format_time(user.created_on) %></td>
-  <td class="last_login_on" align="center"><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>
-    <td class="buttons">
-      <%= change_status_link(user) %>
-      <%= link_to(l(:button_delete), user, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') unless User.current == user %>
-    </td>
-  </tr>
-<% end -%>
-  </tbody>
-</table>
-</div>
-<p class="pagination"><%= pagination_links_full @user_pages, @user_count %></p>
-
-<% html_title(l(:label_user_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/21/21e12c0e1e71e0c4f94a4c58d91a04399075123a.svn-base
--- a/.svn/pristine/21/21e12c0e1e71e0c4f94a4c58d91a04399075123a.svn-base
+++ /dev/null
@@ -1,21 +0,0 @@
-# Settings specified here will take precedence over those in config/environment.rb
-
-# The production environment is meant for finished, "live" apps.
-# Code is not reloaded between requests
-config.cache_classes = true
-
-# Use a different logger for distributed setups
-# config.logger        = SyslogLogger.new
-config.log_level = :info
-
-# Full error reports are disabled and caching is turned on
-config.action_controller.consider_all_requests_local = false
-config.action_controller.perform_caching             = true
-
-# Enable serving of images, stylesheets, and javascripts from an asset server
-# config.action_controller.asset_host                  = "http://assets.example.com"
-
-# Disable mail delivery
-config.action_mailer.perform_deliveries = false
-config.action_mailer.raise_delivery_errors = false
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/21/21f67f445a6c5a2512b4712ac66209391d37efdc.svn-base
--- a/.svn/pristine/21/21f67f445a6c5a2512b4712ac66209391d37efdc.svn-base
+++ /dev/null
@@ -1,241 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/abstract_adapter'
-require 'rexml/document'
-
-module Redmine
-  module Scm
-    module Adapters
-      class DarcsAdapter < AbstractAdapter
-        # Darcs executable name
-        DARCS_BIN = Redmine::Configuration['scm_darcs_command'] || "darcs"
-
-        class << self
-          def client_command
-            @@bin    ||= DARCS_BIN
-          end
-
-          def sq_bin
-            @@sq_bin ||= shell_quote_command
-          end
-
-          def client_version
-            @@client_version ||= (darcs_binary_version || [])
-          end
-
-          def client_available
-            !client_version.empty?
-          end
-
-          def darcs_binary_version
-            darcsversion = darcs_binary_version_from_command_line.dup
-            if darcsversion.respond_to?(:force_encoding)
-              darcsversion.force_encoding('ASCII-8BIT')
-            end
-            if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)})
-              m[2].scan(%r{\d+}).collect(&:to_i)
-            end
-          end
-
-          def darcs_binary_version_from_command_line
-            shellout("#{sq_bin} --version") { |io| io.read }.to_s
-          end
-        end
-
-        def initialize(url, root_url=nil, login=nil, password=nil,
-                       path_encoding=nil)
-          @url = url
-          @root_url = url
-        end
-
-        def supports_cat?
-          # cat supported in darcs 2.0.0 and higher
-          self.class.client_version_above?([2, 0, 0])
-        end
-
-        # Get info about the darcs repository
-        def info
-          rev = revisions(nil,nil,nil,{:limit => 1})
-          rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil
-        end
-
-        # Returns an Entries collection
-        # or nil if the given path doesn't exist in the repository
-        def entries(path=nil, identifier=nil, options={})
-          path_prefix = (path.blank? ? '' : "#{path}/")
-          if path.blank?
-            path = ( self.class.client_version_above?([2, 2, 0]) ? @url : '.' )
-          end
-          entries = Entries.new
-          cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --xml-output"
-          cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
-          cmd << " #{shell_quote path}"
-          shellout(cmd) do |io|
-            begin
-              doc = REXML::Document.new(io)
-              if doc.root.name == 'directory'
-                doc.elements.each('directory/*') do |element|
-                  next unless ['file', 'directory'].include? element.name
-                  entries << entry_from_xml(element, path_prefix)
-                end
-              elsif doc.root.name == 'file'
-                entries << entry_from_xml(doc.root, path_prefix)
-              end
-            rescue
-            end
-          end
-          return nil if $? && $?.exitstatus != 0
-          entries.compact.sort_by_name
-        end
-
-        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
-          path = '.' if path.blank?
-          revisions = Revisions.new
-          cmd = "#{self.class.sq_bin} changes --repodir #{shell_quote @url} --xml-output"
-          cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from
-          cmd << " --last #{options[:limit].to_i}" if options[:limit]
-          shellout(cmd) do |io|
-            begin
-              doc = REXML::Document.new(io)
-              doc.elements.each("changelog/patch") do |patch|
-                message = patch.elements['name'].text
-                message << "\n" + patch.elements['comment'].text.gsub(/\*\*\*END OF DESCRIPTION\*\*\*.*\z/m, '') if patch.elements['comment']
-                revisions << Revision.new({:identifier => nil,
-                              :author => patch.attributes['author'],
-                              :scmid => patch.attributes['hash'],
-                              :time => Time.parse(patch.attributes['local_date']),
-                              :message => message,
-                              :paths => (options[:with_path] ? get_paths_for_patch(patch.attributes['hash']) : nil)
-                            })
-              end
-            rescue
-            end
-          end
-          return nil if $? && $?.exitstatus != 0
-          revisions
-        end
-
-        def diff(path, identifier_from, identifier_to=nil)
-          path = '*' if path.blank?
-          cmd = "#{self.class.sq_bin} diff --repodir #{shell_quote @url}"
-          if identifier_to.nil?
-            cmd << " --match #{shell_quote("hash #{identifier_from}")}"
-          else
-            cmd << " --to-match #{shell_quote("hash #{identifier_from}")}"
-            cmd << " --from-match #{shell_quote("hash #{identifier_to}")}"
-          end
-          cmd << " -u #{shell_quote path}"
-          diff = []
-          shellout(cmd) do |io|
-            io.each_line do |line|
-              diff << line
-            end
-          end
-          return nil if $? && $?.exitstatus != 0
-          diff
-        end
-
-        def cat(path, identifier=nil)
-          cmd = "#{self.class.sq_bin} show content --repodir #{shell_quote @url}"
-          cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
-          cmd << " #{shell_quote path}"
-          cat = nil
-          shellout(cmd) do |io|
-            io.binmode
-            cat = io.read
-          end
-          return nil if $? && $?.exitstatus != 0
-          cat
-        end
-
-        private
-
-        # Returns an Entry from the given XML element
-        # or nil if the entry was deleted
-        def entry_from_xml(element, path_prefix)
-          modified_element = element.elements['modified']
-          if modified_element.elements['modified_how'].text.match(/removed/)
-            return nil
-          end
-
-          Entry.new({:name => element.attributes['name'],
-                     :path => path_prefix + element.attributes['name'],
-                     :kind => element.name == 'file' ? 'file' : 'dir',
-                     :size => nil,
-                     :lastrev => Revision.new({
-                       :identifier => nil,
-                       :scmid => modified_element.elements['patch'].attributes['hash']
-                       })
-                     })
-        end
-
-        def get_paths_for_patch(hash)
-          paths = get_paths_for_patch_raw(hash)
-          if self.class.client_version_above?([2, 4])
-            orig_paths = paths
-            paths = []
-            add_paths = []
-            add_paths_name = []
-            mod_paths = []
-            other_paths = []
-            orig_paths.each do |path|
-              if path[:action] == 'A'
-                add_paths << path
-                add_paths_name << path[:path]
-              elsif path[:action] == 'M'
-                mod_paths << path
-              else
-                other_paths << path
-              end
-            end
-            add_paths_name.each do |add_path|
-              mod_paths.delete_if { |m| m[:path] == add_path }
-            end
-            paths.concat add_paths
-            paths.concat mod_paths
-            paths.concat other_paths
-          end
-          paths
-        end
-
-        # Retrieve changed paths for a single patch
-        def get_paths_for_patch_raw(hash)
-          cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --summary --xml-output"
-          cmd << " --match #{shell_quote("hash #{hash}")} "
-          paths = []
-          shellout(cmd) do |io|
-            begin
-              # Darcs xml output has multiple root elements in this case (tested with darcs 1.0.7)
-              # A root element is added so that REXML doesn't raise an error
-              doc = REXML::Document.new("<fake_root>" + io.read + "</fake_root>")
-              doc.elements.each('fake_root/summary/*') do |modif|
-                paths << {:action => modif.name[0,1].upcase,
-                          :path => "/" + modif.text.chomp.gsub(/^\s*/, '')
-                         }
-              end
-            rescue
-            end
-          end
-          paths
-        rescue CommandFailed
-          paths
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/22/2231a90d74735e9a796f1508f0e2f1bfd1774f24.svn-base
--- /dev/null
+++ b/.svn/pristine/22/2231a90d74735e9a796f1508f0e2f1bfd1774f24.svn-base
@@ -0,0 +1,113 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Member < ActiveRecord::Base
+  belongs_to :user
+  belongs_to :principal, :foreign_key => 'user_id'
+  has_many :member_roles, :dependent => :destroy
+  has_many :roles, :through => :member_roles
+  belongs_to :project
+
+  validates_presence_of :principal, :project
+  validates_uniqueness_of :user_id, :scope => :project_id
+  validate :validate_role
+
+  before_destroy :set_issue_category_nil
+
+  def role
+  end
+
+  def role=
+  end
+
+  def name
+    self.user.name
+  end
+
+  alias :base_role_ids= :role_ids=
+  def role_ids=(arg)
+    ids = (arg || []).collect(&:to_i) - [0]
+    # Keep inherited roles
+    ids += member_roles.select {|mr| !mr.inherited_from.nil?}.collect(&:role_id)
+
+    new_role_ids = ids - role_ids
+    # Add new roles
+    new_role_ids.each {|id| member_roles << MemberRole.new(:role_id => id) }
+    # Remove roles (Rails' #role_ids= will not trigger MemberRole#on_destroy)
+    member_roles_to_destroy = member_roles.select {|mr| !ids.include?(mr.role_id)}
+    if member_roles_to_destroy.any?
+      member_roles_to_destroy.each(&:destroy)
+    end
+  end
+
+  def <=>(member)
+    a, b = roles.sort.first, member.roles.sort.first
+    if a == b
+      if principal
+        principal <=> member.principal
+      else
+        1
+      end
+    elsif a
+      a <=> b
+    else
+      1
+    end
+  end
+
+  def deletable?
+    member_roles.detect {|mr| mr.inherited_from}.nil?
+  end
+
+  def include?(user)
+    if principal.is_a?(Group)
+      !user.nil? && user.groups.include?(principal)
+    else
+      self.user == user
+    end
+  end
+
+  def set_issue_category_nil
+    if user
+      # remove category based auto assignments for this member
+      IssueCategory.update_all "assigned_to_id = NULL", ["project_id = ? AND assigned_to_id = ?", project.id, user.id]
+    end
+  end
+
+  # Find or initilize a Member with an id, attributes, and for a Principal
+  def self.edit_membership(id, new_attributes, principal=nil)
+    @membership = id.present? ? Member.find(id) : Member.new(:principal => principal)
+    @membership.attributes = new_attributes
+    @membership
+  end
+
+  # Finds or initilizes a Member for the given project and principal
+  def self.find_or_new(project, principal)
+    project_id = project.is_a?(Project) ? project.id : project
+    principal_id = principal.is_a?(Principal) ? principal.id : principal
+
+    member = Member.find_by_project_id_and_user_id(project_id, principal_id)
+    member ||= Member.new(:project_id => project_id, :user_id => principal_id)
+    member
+  end
+
+  protected
+
+  def validate_role
+    errors.add_on_empty :role if member_roles.empty? && roles.empty?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/22/2254c6ada14f9698b9a4320070c88983213e381b.svn-base
--- /dev/null
+++ b/.svn/pristine/22/2254c6ada14f9698b9a4320070c88983213e381b.svn-base
@@ -0,0 +1,32 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingCalendarsTest < ActionController::IntegrationTest
+  def test_calendars
+    assert_routing(
+        { :method => 'get', :path => "/issues/calendar" },
+        { :controller => 'calendars', :action => 'show' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/project-name/issues/calendar" },
+        { :controller => 'calendars', :action => 'show',
+          :project_id => 'project-name' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/22/22629c3ce001e5a68327c24a4b23675476508e16.svn-base
--- /dev/null
+++ b/.svn/pristine/22/22629c3ce001e5a68327c24a4b23675476508e16.svn-base
@@ -0,0 +1,32 @@
+<%= error_messages_for 'time_entry' %>
+<%= back_url_hidden_field_tag %>
+
+<div class="box tabular">
+  <% if @time_entry.new_record? %>
+    <% if params[:project_id] || @time_entry.issue %>
+      <%= f.hidden_field :project_id %>
+    <% else %>
+      <p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project), :required => true %></p>
+    <% end %>
+  <% end %>
+  <p>
+    <%= f.text_field :issue_id, :size => 6 %>
+    <span id="time_entry_issue"><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></span>
+  </p>
+  <p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
+  <p><%= f.text_field :hours, :size => 6, :required => true %></p>
+  <p><%= f.text_field :comments, :size => 100, :maxlength => 255 %></p>
+  <p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
+  <% @time_entry.custom_field_values.each do |value| %>
+    <p><%= custom_field_tag_with_label :time_entry, value %></p>
+  <% end %>
+  <%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
+</div>
+
+<%= javascript_tag do %>
+  observeAutocompleteField('time_entry_issue_id', '<%= escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (@project ? nil : 'all'))%>', {
+    select: function(event, ui) {
+      $('#time_entry_issue').text(ui.item.label);
+    }
+  });
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/22/2271decb00153f4ca80ae30e23c680b8a941ca9b.svn-base
--- /dev/null
+++ b/.svn/pristine/22/2271decb00153f4ca80ae30e23c680b8a941ca9b.svn-base
@@ -0,0 +1,94 @@
+<%= form_tag({:action => 'edit', :tab => 'repositories'}) do %>
+
+<fieldset class="box settings enabled_scm">
+<legend><%= l(:setting_enabled_scm) %></legend>
+<%= hidden_field_tag 'settings[enabled_scm][]', '' %>
+<table>
+  <tr>
+    <th></th>
+    <th><%= l(:text_scm_command)         %></th>
+    <th><%= l(:text_scm_command_version) %></th>
+  </tr>
+  <% Redmine::Scm::Base.all.collect do |choice| %>
+    <% scm_class = "Repository::#{choice}".constantize %>
+    <% text, value = (choice.is_a?(Array) ? choice : [choice, choice]) %>
+    <% setting = :enabled_scm %>
+		<% enabled = Setting.send(setting).include?(value) %>
+    <tr>
+      <td class="scm_name">
+        <label>
+        <%= check_box_tag("settings[#{setting}][]", value, enabled, :id => nil) %>
+        <%= text.to_s %>
+        </label>
+      </td>
+      <td>
+         <% if enabled %>
+         <%=
+           image_tag(
+              (scm_class.scm_available ? 'true.png' : 'exclamation.png'),
+              :style => "vertical-align:bottom;"
+           )
+           %>
+          <%= scm_class.scm_command %>
+					<% end %>
+       </td>
+       <td>
+          <%= scm_class.scm_version_string if enabled %>
+       </td>
+     </tr>
+  <% end %>
+</table>
+<p><em class="info"><%= l(:text_scm_config) %></em></p>
+</fieldset>
+
+<div class="box tabular settings">
+<p><%= setting_check_box :autofetch_changesets %></p>
+
+<p><%= setting_check_box :sys_api_enabled,
+                         :onclick =>
+                             "if (this.checked) { $('#settings_sys_api_key').removeAttr('disabled'); } else { $('#settings_sys_api_key').attr('disabled', true); }" %></p>
+
+<p><%= setting_text_field :sys_api_key,
+                          :size     => 30,
+                          :id       => 'settings_sys_api_key',
+                          :disabled => !Setting.sys_api_enabled?,
+                          :label    => :setting_mail_handler_api_key %>
+  <%= link_to_function l(:label_generate_key),
+                       "if (!$('#settings_sys_api_key').attr('disabled')) { $('#settings_sys_api_key').val(randomKey(20)) }" %>
+</p>
+
+<p><%= setting_text_field :repository_log_display_limit, :size => 6 %></p>
+</div>
+
+<fieldset class="box tabular settings">
+<legend><%= l(:text_issues_ref_in_commit_messages) %></legend>
+<p><%= setting_text_field :commit_ref_keywords, :size => 30 %>
+<em class="info"><%= l(:text_comma_separated) %></em></p>
+
+<p><%= setting_text_field :commit_fix_keywords, :size => 30 %>
+&nbsp;<%= l(:label_applied_status) %>: <%= setting_select :commit_fix_status_id,
+                                                          [["", 0]] +
+                                                              IssueStatus.sorted.all.collect{
+                                                                 |status| [status.name, status.id.to_s]
+                                                              },
+                                                          :label => false %>
+&nbsp;<%= l(:field_done_ratio) %>: <%= setting_select :commit_fix_done_ratio,
+                                                       (0..10).to_a.collect {|r| ["#{r*10} %", "#{r*10}"] },
+                                                       :blank => :label_no_change_option,
+                                                       :label => false %>
+<em class="info"><%= l(:text_comma_separated) %></em></p>
+
+<p><%= setting_check_box :commit_cross_project_ref %></p>
+
+<p><%= setting_check_box :commit_logtime_enabled,
+                         :onclick =>
+                            "if (this.checked) { $('#settings_commit_logtime_activity_id').removeAttr('disabled'); } else { $('#settings_commit_logtime_activity_id').attr('disabled', true); }"%></p>
+
+<p><%= setting_select :commit_logtime_activity_id,
+                      [[l(:label_default), 0]] +
+                          TimeEntryActivity.shared.active.collect{|activity| [activity.name, activity.id.to_s]},
+                      :disabled => !Setting.commit_logtime_enabled?%></p>
+</fieldset>
+
+<%= submit_tag l(:button_save) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/22/229053adf4d0f0cdc30b283c6478a18c47c6fe1d.svn-base
--- /dev/null
+++ b/.svn/pristine/22/229053adf4d0f0cdc30b283c6478a18c47c6fe1d.svn-base
@@ -0,0 +1,161 @@
+if RUBY_VERSION < '1.9'
+  require 'iconv'
+end
+
+module Redmine
+  module CodesetUtil
+
+    def self.replace_invalid_utf8(str)
+      return str if str.nil?
+      if str.respond_to?(:force_encoding)
+        str.force_encoding('UTF-8')
+        if ! str.valid_encoding?
+          str = str.encode("US-ASCII", :invalid => :replace,
+                :undef => :replace, :replace => '?').encode("UTF-8")
+        end
+      elsif RUBY_PLATFORM == 'java'
+        begin
+          ic = Iconv.new('UTF-8', 'UTF-8')
+          str = ic.iconv(str)
+        rescue
+          str = str.gsub(%r{[^\r\n\t\x20-\x7e]}, '?')
+        end
+      else
+        ic = Iconv.new('UTF-8', 'UTF-8')
+        txtar = ""
+        begin
+          txtar += ic.iconv(str)
+        rescue Iconv::IllegalSequence
+          txtar += $!.success
+          str = '?' + $!.failed[1,$!.failed.length]
+          retry
+        rescue
+          txtar += $!.success
+        end
+        str = txtar
+      end
+      str
+    end
+
+    def self.to_utf8(str, encoding)
+      return str if str.nil?
+      str.force_encoding("ASCII-8BIT") if str.respond_to?(:force_encoding)
+      if str.empty?
+        str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
+        return str
+      end
+      enc = encoding.blank? ? "UTF-8" : encoding
+      if str.respond_to?(:force_encoding)
+        if enc.upcase != "UTF-8"
+          str.force_encoding(enc)
+          str = str.encode("UTF-8", :invalid => :replace,
+                :undef => :replace, :replace => '?')
+        else
+          str.force_encoding("UTF-8")
+          if ! str.valid_encoding?
+            str = str.encode("US-ASCII", :invalid => :replace,
+                  :undef => :replace, :replace => '?').encode("UTF-8")
+          end
+        end
+      elsif RUBY_PLATFORM == 'java'
+        begin
+          ic = Iconv.new('UTF-8', enc)
+          str = ic.iconv(str)
+        rescue
+          str = str.gsub(%r{[^\r\n\t\x20-\x7e]}, '?')
+        end
+      else
+        ic = Iconv.new('UTF-8', enc)
+        txtar = ""
+        begin
+          txtar += ic.iconv(str)
+        rescue Iconv::IllegalSequence
+          txtar += $!.success
+          str = '?' + $!.failed[1,$!.failed.length]
+          retry
+        rescue
+          txtar += $!.success
+        end
+        str = txtar
+      end
+      str
+    end
+
+    def self.to_utf8_by_setting(str)
+      return str if str.nil?
+      str = self.to_utf8_by_setting_internal(str)
+      if str.respond_to?(:force_encoding)
+        str.force_encoding('UTF-8')
+      end
+      str
+    end
+
+    def self.to_utf8_by_setting_internal(str)
+      return str if str.nil?
+      if str.respond_to?(:force_encoding)
+        str.force_encoding('ASCII-8BIT')
+      end
+      return str if str.empty?
+      return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii
+      if str.respond_to?(:force_encoding)
+        str.force_encoding('UTF-8')
+      end
+      encodings = Setting.repositories_encodings.split(',').collect(&:strip)
+      encodings.each do |encoding|
+        if str.respond_to?(:force_encoding)
+          begin
+            str.force_encoding(encoding)
+            utf8 = str.encode('UTF-8')
+            return utf8 if utf8.valid_encoding?
+          rescue
+            # do nothing here and try the next encoding
+          end
+        else
+          begin
+            return Iconv.conv('UTF-8', encoding, str)
+          rescue Iconv::Failure
+            # do nothing here and try the next encoding
+          end
+        end
+      end
+      str = self.replace_invalid_utf8(str)
+      if str.respond_to?(:force_encoding)
+        str.force_encoding('UTF-8')
+      end
+      str
+    end
+
+    def self.from_utf8(str, encoding)
+      str ||= ''
+      if str.respond_to?(:force_encoding)
+        str.force_encoding('UTF-8')
+        if encoding.upcase != 'UTF-8'
+          str = str.encode(encoding, :invalid => :replace,
+                           :undef => :replace, :replace => '?')
+        else
+          str = self.replace_invalid_utf8(str)
+        end
+      elsif RUBY_PLATFORM == 'java'
+        begin
+          ic = Iconv.new(encoding, 'UTF-8')
+          str = ic.iconv(str)
+        rescue
+          str = str.gsub(%r{[^\r\n\t\x20-\x7e]}, '?')
+        end
+      else
+        ic = Iconv.new(encoding, 'UTF-8')
+        txtar = ""
+        begin
+          txtar += ic.iconv(str)
+        rescue Iconv::IllegalSequence
+          txtar += $!.success
+          str = '?' + $!.failed[1, $!.failed.length]
+          retry
+        rescue
+          txtar += $!.success
+        end
+        str = txtar
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/22/22a7851f8ede366924cba144fbbe8879121ee70d.svn-base
--- /dev/null
+++ b/.svn/pristine/22/22a7851f8ede366924cba144fbbe8879121ee70d.svn-base
@@ -0,0 +1,31 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingWelcomeTest < ActionController::IntegrationTest
+  def test_welcome
+    assert_routing(
+        { :method => 'get', :path => "/" },
+        { :controller => 'welcome', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/robots.txt" },
+        { :controller => 'welcome', :action => 'robots' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/23/2330bc88f1bd2ce1c1b2bfa4d60a6eb823530bd2.svn-base
--- a/.svn/pristine/23/2330bc88f1bd2ce1c1b2bfa4d60a6eb823530bd2.svn-base
+++ /dev/null
@@ -1,182 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../test_helper', __FILE__)
-
-class Redmine::MenuManager::MapperTest < ActiveSupport::TestCase
-  context "Mapper#initialize" do
-    should "be tested"
-  end
-
-  def test_push_onto_root
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
-
-    menu_mapper.exists?(:test_overview)
-  end
-
-  def test_push_onto_parent
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
-
-    assert menu_mapper.exists?(:test_child)
-    assert_equal :test_child, menu_mapper.find(:test_child).name
-  end
-
-  def test_push_onto_grandparent
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
-    menu_mapper.push :test_grandchild, { :controller => 'projects', :action => 'show'}, {:parent => :test_child}
-
-    assert menu_mapper.exists?(:test_grandchild)
-    grandchild = menu_mapper.find(:test_grandchild)
-    assert_equal :test_grandchild, grandchild.name
-    assert_equal :test_child, grandchild.parent.name
-  end
-
-  def test_push_first
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {:first => true}
-
-    root = menu_mapper.find(:root)
-    assert_equal 5, root.children.size
-    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
-      assert_not_nil root.children[position]
-      assert_equal name, root.children[position].name
-    end
-
-  end
-
-  def test_push_before
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {:before => :test_fourth}
-
-    root = menu_mapper.find(:root)
-    assert_equal 5, root.children.size
-    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
-      assert_not_nil root.children[position]
-      assert_equal name, root.children[position].name
-    end
-
-  end
-
-  def test_push_after
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {:after => :test_third}
-
-    root = menu_mapper.find(:root)
-    assert_equal 5, root.children.size
-    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
-      assert_not_nil root.children[position]
-      assert_equal name, root.children[position].name
-    end
-
-  end
-
-  def test_push_last
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {:last => true}
-    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
-
-    root = menu_mapper.find(:root)
-    assert_equal 5, root.children.size
-    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
-      assert_not_nil root.children[position]
-      assert_equal name, root.children[position].name
-    end
-
-  end
-
-  def test_exists_for_child_node
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
-    menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview }
-
-    assert menu_mapper.exists?(:test_child)
-  end
-
-  def test_exists_for_invalid_node
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
-
-    assert !menu_mapper.exists?(:nothing)
-  end
-
-  def test_find
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
-
-    item = menu_mapper.find(:test_overview)
-    assert_equal :test_overview, item.name
-    assert_equal({:controller => 'projects', :action => 'show'}, item.url)
-  end
-
-  def test_find_missing
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
-
-    item = menu_mapper.find(:nothing)
-    assert_equal nil, item
-  end
-
-  def test_delete
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
-    assert_not_nil menu_mapper.delete(:test_overview)
-
-    assert_nil menu_mapper.find(:test_overview)
-  end
-
-  def test_delete_missing
-    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
-    assert_nil menu_mapper.delete(:test_missing)
-  end
-
-  test 'deleting all items' do
-    # Exposed by deleting :last items
-    Redmine::MenuManager.map :test_menu do |menu|
-      menu.push :not_last, Redmine::Info.help_url
-      menu.push :administration, { :controller => 'projects', :action => 'show'}, {:last => true}
-      menu.push :help, Redmine::Info.help_url, :last => true
-    end
-
-    assert_nothing_raised do
-      Redmine::MenuManager.map :test_menu do |menu|
-        menu.delete(:administration)
-        menu.delete(:help)
-        menu.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
-     end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/23/239f83d29fc7b11e5679dea8261085d9a0c7a621.svn-base
--- a/.svn/pristine/23/239f83d29fc7b11e5679dea8261085d9a0c7a621.svn-base
+++ /dev/null
@@ -1,49 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine #:nodoc:
-  module CoreExtensions #:nodoc:
-    module String #:nodoc:
-      # Custom string conversions
-      module Conversions
-        # Parses hours format and returns a float
-        def to_hours
-          s = self.dup
-          s.strip!
-          if s =~ %r{^(\d+([.,]\d+)?)h?$}
-            s = $1
-          else
-            # 2:30 => 2.5
-            s.gsub!(%r{^(\d+):(\d+)$}) { $1.to_i + $2.to_i / 60.0 }
-            # 2h30, 2h, 30m => 2.5, 2, 0.5
-            s.gsub!(%r{^((\d+)\s*(h|hours?))?\s*((\d+)\s*(m|min)?)?$}) { |m| ($1 || $4) ? ($2.to_i + $5.to_i / 60.0) : m[0] }
-          end
-          # 2,5 => 2.5
-          s.gsub!(',', '.')
-          begin; Kernel.Float(s); rescue; nil; end
-        end
-
-        # Object#to_a removed in ruby1.9
-        if RUBY_VERSION > '1.9'
-          def to_a
-            [self.dup]
-          end
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/23/23b009231ec6aa90fecfe01522aea6ff2ac84fb3.svn-base
--- a/.svn/pristine/23/23b009231ec6aa90fecfe01522aea6ff2ac84fb3.svn-base
+++ /dev/null
@@ -1,40 +0,0 @@
-<h2><%= l(:label_home) %></h2>
-
-<div class="splitcontentleft">
-  <%= textilizable Setting.welcome_text %>
-  <% if @news.any? %>
-  <div class="news box">
-  <h3><%=l(:label_news_latest)%></h3>
-    <%= render :partial => 'news/news', :collection => @news %>
-    <%= link_to l(:label_news_view_all), :controller => 'news' %>
-  </div>
-  <% end %>
-  <%= call_hook(:view_welcome_index_left, :projects => @projects) %>
-</div>
-
-<div class="splitcontentright">
-    <% if @projects.any? %>
-  <div class="projects box">
-  <h3><%=l(:label_project_latest)%></h3>
-    <ul>
-    <% for project in @projects %>
-      <% @project = project %>
-      <li>
-      <%= link_to_project project %> (<%= format_time(project.created_on) %>)
-      <%= textilizable project.short_description, :project => project %>
-      </li>
-    <% end %>
-    <% @project = nil %>
-    </ul>
-  </div>
-  <% end %>
-    <%= call_hook(:view_welcome_index_right, :projects => @projects) %>
-</div>
-
-<% content_for :header_tags do %>
-<%= stylesheet_link_tag 'scm' %>
-<%= auto_discovery_link_tag(:atom, {:controller => 'news', :action => 'index', :key => User.current.rss_key, :format => 'atom'},
-                                   :title => "#{Setting.app_title}: #{l(:label_news_latest)}") %>
-<%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :key => User.current.rss_key, :format => 'atom'},
-                                   :title => "#{Setting.app_title}: #{l(:label_activity)}") %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/23/23ef48c3079c4ad7ff9c6850f3a7bce6b2c94752.svn-base
--- a/.svn/pristine/23/23ef48c3079c4ad7ff9c6850f3a7bce6b2c94752.svn-base
+++ /dev/null
@@ -1,55 +0,0 @@
-<% form_tag({}) do -%>
-<%= hidden_field_tag 'back_url', url_for(params) %>
-<div class="autoscroll">
-<table class="list time-entries">
-<thead>
-<tr>
-<th class="checkbox hide-when-print">
-  <%= link_to image_tag('toggle_check.png'),
-    {},
-    :onclick => 'toggleIssuesSelection(Element.up(this, "form")); return false;',
-    :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
-</th>
-<%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %>
-<%= sort_header_tag('user', :caption => l(:label_member)) %>
-<%= sort_header_tag('activity', :caption => l(:label_activity)) %>
-<%= sort_header_tag('project', :caption => l(:label_project)) %>
-<%= sort_header_tag('issue', :caption => l(:label_issue), :default_order => 'desc') %>
-<th><%= l(:field_comments) %></th>
-<%= sort_header_tag('hours', :caption => l(:field_hours)) %>
-<th></th>
-</tr>
-</thead>
-<tbody>
-<% entries.each do |entry| -%>
-<tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
-<td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
-<td class="spent_on"><%= format_date(entry.spent_on) %></td>
-<td class="user"><%= link_to_user(entry.user) %></td>
-<td class="activity"><%=h entry.activity %></td>
-<td class="project"><%= link_to_project(entry.project) %></td>
-<td class="subject">
-<% if entry.issue -%>
-<%= entry.issue.visible? ? link_to_issue(entry.issue, :truncate => 50) : "##{entry.issue.id}" -%>
-<% end -%>
-</td>
-<td class="comments"><%=h entry.comments %></td>
-<td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
-<td align="center">
-<% if entry.editable_by?(User.current) -%>
-    <%= link_to image_tag('edit.png'), {:controller => 'timelog', :action => 'edit', :id => entry, :project_id => nil},
-                                       :title => l(:button_edit) %>
-    <%= link_to image_tag('delete.png'), {:controller => 'timelog', :action => 'destroy', :id => entry, :project_id => nil},
-                                         :confirm => l(:text_are_you_sure),
-                                         :method => :delete,
-                                         :title => l(:button_delete) %>
-<% end -%>
-</td>
-</tr>
-<% end -%>
-</tbody>
-</table>
-</div>
-<% end -%>
-
-<%= context_menu time_entries_context_menu_path %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/23/23f046e7217770bca11bfe9989b755a158f48868.svn-base
--- /dev/null
+++ b/.svn/pristine/23/23f046e7217770bca11bfe9989b755a158f48868.svn-base
@@ -0,0 +1,83 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Token < ActiveRecord::Base
+  belongs_to :user
+  validates_uniqueness_of :value
+
+  before_create :delete_previous_tokens, :generate_new_token
+
+  @@validity_time = 1.day
+
+  def generate_new_token
+    self.value = Token.generate_token_value
+  end
+
+  # Return true if token has expired
+  def expired?
+    return Time.now > self.created_on + @@validity_time
+  end
+
+  # Delete all expired tokens
+  def self.destroy_expired
+    Token.delete_all ["action NOT IN (?) AND created_on < ?", ['feeds', 'api'], Time.now - @@validity_time]
+  end
+
+  # Returns the active user who owns the key for the given action
+  def self.find_active_user(action, key, validity_days=nil)
+    user = find_user(action, key, validity_days)
+    if user && user.active?
+      user
+    end
+  end
+
+  # Returns the user who owns the key for the given action
+  def self.find_user(action, key, validity_days=nil)
+    token = find_token(action, key, validity_days)
+    if token
+      token.user
+    end
+  end
+
+  # Returns the token for action and key with an optional
+  # validity duration (in number of days)
+  def self.find_token(action, key, validity_days=nil)
+    action = action.to_s
+    key = key.to_s
+    return nil unless action.present? && key =~ /\A[a-z0-9]+\z/i
+
+    token = Token.where(:action => action, :value => key).first
+    if token && (token.action == action) && (token.value == key) && token.user
+      if validity_days.nil? || (token.created_on > validity_days.days.ago)
+        token
+      end
+    end
+  end
+
+  def self.generate_token_value
+    Redmine::Utils.random_hex(20)
+  end
+
+  private
+
+  # Removes obsolete tokens (same user and action)
+  def delete_previous_tokens
+    if user
+      Token.delete_all(['user_id = ? AND action = ?', user.id, action])
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/23/23f71ac728c941d3ffe5e3105dc856980b211079.svn-base
--- a/.svn/pristine/23/23f71ac728c941d3ffe5e3105dc856980b211079.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-plugin mail template loaded from application
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/23/23ff873f0bf0f2e45a3709caf12bc84dab7be570.svn-base
--- /dev/null
+++ b/.svn/pristine/23/23ff873f0bf0f2e45a3709caf12bc84dab7be570.svn-base
@@ -0,0 +1,106 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module SettingsHelper
+  def administration_settings_tabs
+    tabs = [{:name => 'general', :partial => 'settings/general', :label => :label_general},
+            {:name => 'display', :partial => 'settings/display', :label => :label_display},
+            {:name => 'authentication', :partial => 'settings/authentication', :label => :label_authentication},
+            {:name => 'projects', :partial => 'settings/projects', :label => :label_project_plural},
+            {:name => 'issues', :partial => 'settings/issues', :label => :label_issue_tracking},
+            {:name => 'notifications', :partial => 'settings/notifications', :label => :field_mail_notification},
+            {:name => 'mail_handler', :partial => 'settings/mail_handler', :label => :label_incoming_emails},
+            {:name => 'repositories', :partial => 'settings/repositories', :label => :label_repository_plural}
+            ]
+  end
+
+  def setting_select(setting, choices, options={})
+    if blank_text = options.delete(:blank)
+      choices = [[blank_text.is_a?(Symbol) ? l(blank_text) : blank_text, '']] + choices
+    end
+    setting_label(setting, options).html_safe +
+      select_tag("settings[#{setting}]",
+                 options_for_select(choices, Setting.send(setting).to_s),
+                 options).html_safe
+  end
+
+  def setting_multiselect(setting, choices, options={})
+    setting_values = Setting.send(setting)
+    setting_values = [] unless setting_values.is_a?(Array)
+
+    content_tag("label", l(options[:label] || "setting_#{setting}")) +
+      hidden_field_tag("settings[#{setting}][]", '').html_safe +
+      choices.collect do |choice|
+        text, value = (choice.is_a?(Array) ? choice : [choice, choice])
+        content_tag(
+          'label',
+          check_box_tag(
+             "settings[#{setting}][]",
+             value,
+             setting_values.include?(value),
+             :id => nil
+           ) + text.to_s,
+          :class => (options[:inline] ? 'inline' : 'block')
+         )
+      end.join.html_safe
+  end
+
+  def setting_text_field(setting, options={})
+    setting_label(setting, options).html_safe +
+      text_field_tag("settings[#{setting}]", Setting.send(setting), options).html_safe
+  end
+
+  def setting_text_area(setting, options={})
+    setting_label(setting, options).html_safe +
+      text_area_tag("settings[#{setting}]", Setting.send(setting), options).html_safe
+  end
+
+  def setting_check_box(setting, options={})
+    setting_label(setting, options).html_safe +
+      hidden_field_tag("settings[#{setting}]", 0, :id => nil).html_safe +
+        check_box_tag("settings[#{setting}]", 1, Setting.send("#{setting}?"), options).html_safe
+  end
+
+  def setting_label(setting, options={})
+    label = options.delete(:label)
+    label != false ? label_tag("settings_#{setting}", l(label || "setting_#{setting}")).html_safe : ''
+  end
+
+  # Renders a notification field for a Redmine::Notifiable option
+  def notification_field(notifiable)
+    return content_tag(:label,
+                       check_box_tag('settings[notified_events][]',
+                                     notifiable.name,
+                                     Setting.notified_events.include?(notifiable.name), :id => nil).html_safe +
+                         l_or_humanize(notifiable.name, :prefix => 'label_').html_safe,
+                       :class => notifiable.parent.present? ? "parent" : '').html_safe
+  end
+
+  def cross_project_subtasks_options
+    options = [
+      [:label_disabled, ''],
+      [:label_cross_project_system, 'system'],
+      [:label_cross_project_tree, 'tree'],
+      [:label_cross_project_hierarchy, 'hierarchy'],
+      [:label_cross_project_descendants, 'descendants']
+    ]
+
+    options.map {|label, value| [l(label), value.to_s]}
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/244393349ccf9a5e6e3ea60c976d07e62fd15de2.svn-base
--- a/.svn/pristine/24/244393349ccf9a5e6e3ea60c976d07e62fd15de2.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-<p><%= l(:mail_body_wiki_content_added, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url),
-                                        :author => h(@wiki_content.author)) %><br />
-<em><%=h @wiki_content.comments %></em></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/244c888e0b10e75677f5d843ff3bbb49ca914d36.svn-base
--- a/.svn/pristine/24/244c888e0b10e75677f5d843ff3bbb49ca914d36.svn-base
+++ /dev/null
@@ -1,1013 +0,0 @@
-# Hebrew translation for Redmine
-# Initiated by Dotan Nahum (dipidi@gmail.com)
-# Jul 2010 - Updated by Orgad Shaneh (orgads@gmail.com)
-
-he:
-  direction: rtl
-  date:
-    formats:
-      default: "%d/%m/%Y"
-      short: "%d/%m"
-      long: "%d/%m/%Y"
-      only_day: "%e"
-
-    day_names: [×¨××©×•×Ÿ, ×©× ×™, ×©×œ×™×©×™, ×¨×‘×™×¢×™, ×—×ž×™×©×™, ×©×™×©×™, ×©×‘×ª]
-    abbr_day_names: ["×'", "×‘'", "×’'", "×“'", "×”'", "×•'", "×©'"]
-    month_names: [~, ×™× ×•××¨, ×¤×‘×¨×•××¨, ×ž×¨×¥, ××¤×¨×™×œ, ×ž××™, ×™×•× ×™, ×™×•×œ×™, ××•×’×•×¡×˜, ×¡×¤×˜×ž×‘×¨, ××•×§×˜×•×‘×¨, × ×•×‘×ž×‘×¨, ×“×¦×ž×‘×¨]
-    abbr_month_names: [~, ×™×× , ×¤×‘×¨, ×ž×¨×¥, ××¤×¨, ×ž××™, ×™×•× , ×™×•×œ, ××•×’, ×¡×¤×˜, ××•×§, × ×•×‘, ×“×¦×ž]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%a %d/%m/%Y %H:%M:%S"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-      only_second: "%S"
-
-      datetime:
-        formats:
-          default: "%d-%m-%YT%H:%M:%S%Z"
-
-    am: 'am'
-    pm: 'pm'
-
-  datetime:
-    distance_in_words:
-      half_a_minute: '×—×¦×™ ×“×§×”'
-      less_than_x_seconds:
-        zero: '×¤×—×•×ª ×ž×©× ×™×”'
-        one: '×¤×—×•×ª ×ž×©× ×™×”'
-        other: '×¤×—×•×ª ×žÖ¾%{count} ×©× ×™×•×ª'
-      x_seconds:
-        one: '×©× ×™×” ××—×ª'
-        other: '%{count} ×©× ×™×•×ª'
-      less_than_x_minutes:
-        zero: '×¤×—×•×ª ×ž×“×§×” ××—×ª'
-        one: '×¤×—×•×ª ×ž×“×§×” ××—×ª'
-        other: '×¤×—×•×ª ×žÖ¾%{count} ×“×§×•×ª'
-      x_minutes:
-        one: '×“×§×” ××—×ª'
-        other: '%{count} ×“×§×•×ª'
-      about_x_hours:
-        one: '×‘×¢×¨×š ×©×¢×” ××—×ª'
-        other: '×‘×¢×¨×š %{count} ×©×¢×•×ª'
-      x_days:
-        one: '×™×•× ××—×“'
-        other: '%{count} ×™×ž×™×'
-      about_x_months:
-        one: '×‘×¢×¨×š ×—×•×“×© ××—×“'
-        other: '×‘×¢×¨×š %{count} ×—×•×“×©×™×'
-      x_months:
-        one: '×—×•×“×© ××—×“'
-        other: '%{count} ×—×•×“×©×™×'
-      about_x_years:
-        one: '×‘×¢×¨×š ×©× ×” ××—×ª'
-        other: '×‘×¢×¨×š %{count} ×©× ×™×'
-      over_x_years:
-        one: '×ž×¢×œ ×©× ×” ××—×ª'
-        other: '×ž×¢×œ %{count} ×©× ×™×'
-      almost_x_years:
-        one:   "×›×ž×¢×˜ ×©× ×”"
-        other: "×›×ž×¢×˜ %{count} ×©× ×™×"
-
-  number:
-    format:
-      precision: 3
-      separator: '.'
-      delimiter: ','
-    currency:
-      format:
-        unit: '×©"×—'
-        precision: 2
-        format: '%u %n'
-    human:
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "×‘×™×™×˜"
-            other: "×‘×ª×™×"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  support:
-    array:
-      sentence_connector: "×•×’×"
-      skip_last_comma: true
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "×œ× × ×›×œ×œ ×‘×¨×©×™×ž×”"
-        exclusion: "×œ× ×–×ž×™×Ÿ"
-        invalid: "×œ× ×•×œ×™×“×™"
-        confirmation: "×œ× ×ª×•×× ×œ××™×©×•×¨"
-        accepted: "×—×™×™×‘ ×‘××™×©×•×¨"
-        empty: "×—×™×™×‘ ×œ×”×›×œ×œ"
-        blank: "×—×™×™×‘ ×œ×”×›×œ×œ"
-        too_long: "××¨×•×š ×ž×“×™ (×œ× ×™×•×ª×¨ ×žÖ¾%{count} ×ª×•×™×)"
-        too_short: "×§×¦×¨ ×ž×“×™ (×œ× ×™×•×ª×¨ ×žÖ¾%{count} ×ª×•×™×)"
-        wrong_length: "×œ× ×‘××•×¨×š ×”× ×›×•×Ÿ (×—×™×™×‘ ×œ×”×™×•×ª %{count} ×ª×•×™×)"
-        taken: "×œ× ×–×ž×™×Ÿ"
-        not_a_number: "×”×•× ×œ× ×ž×¡×¤×¨"
-        greater_than: "×—×™×™×‘ ×œ×”×™×•×ª ×’×“×•×œ ×žÖ¾%{count}"
-        greater_than_or_equal_to: "×—×™×™×‘ ×œ×”×™×•×ª ×’×“×•×œ ××• ×©×•×•×” ×œÖ¾%{count}"
-        equal_to: "×—×™×™×‘ ×œ×”×™×•×ª ×©×•×•×” ×œÖ¾%{count}"
-        less_than: "×—×™×™×‘ ×œ×”×™×•×ª ×§×˜×Ÿ ×žÖ¾%{count}"
-        less_than_or_equal_to: "×—×™×™×‘ ×œ×”×™×•×ª ×§×˜×Ÿ ××• ×©×•×•×” ×œÖ¾%{count}"
-        odd: "×—×™×™×‘ ×œ×”×™×•×ª ××™ ×–×•×’×™"
-        even: "×—×™×™×‘ ×œ×”×™×•×ª ×–×•×’×™"
-        greater_than_start_date: "×—×™×™×‘ ×œ×”×™×•×ª ×ž××•×—×¨ ×™×•×ª×¨ ×ž×ª××¨×™×š ×”×”×ª×—×œ×”"
-        not_same_project: "×œ× ×©×™×™×š ×œ××•×ª×• ×”×¤×¨×•×™×§×˜"
-        circular_dependency: "×§×©×¨ ×–×” ×™×¦×•×¨ ×ª×œ×•×ª ×ž×¢×’×œ×™×ª"
-        cant_link_an_issue_with_a_descendant: "×œ× × ×™×ª×Ÿ ×œ×§×©×¨ × ×•×©× ×œ×ª×ªÖ¾×ž×©×™×ž×” ×©×œ×•"
-
-  actionview_instancetag_blank_option: ×‘×—×¨ ×‘×‘×§×©×”
-
-  general_text_No: '×œ×'
-  general_text_Yes: '×›×Ÿ'
-  general_text_no: '×œ×'
-  general_text_yes: '×›×Ÿ'
-  general_lang_name: 'Hebrew (×¢×‘×¨×™×ª)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: ISO-8859-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '7'
-
-  notice_account_updated: ×”×—×©×‘×•×Ÿ ×¢×•×“×›×Ÿ ×‘×”×¦×œ×—×”!
-  notice_account_invalid_creditentials: ×©× ×ž×©×ª×ž×© ××• ×¡×™×¡×ž×” ×©×’×•×™×™×
-  notice_account_password_updated: ×”×¡×™×¡×ž×” ×¢×•×“×›× ×” ×‘×”×¦×œ×—×”!
-  notice_account_wrong_password: ×¡×™×¡×ž×” ×©×’×•×™×”
-  notice_account_register_done: ×”×—×©×‘×•×Ÿ × ×•×¦×¨ ×‘×”×¦×œ×—×”. ×œ×”×¤×¢×œ×ª ×”×—×©×‘×•×Ÿ ×œ×—×¥ ×¢×œ ×”×§×™×©×•×¨ ×©× ×©×œ×— ×œ×“×•×"×œ ×©×œ×š.
-  notice_account_unknown_email: ×ž×©×ª×ž×© ×œ× ×ž×•×›×¨.
-  notice_can_t_change_password: ×”×—×©×‘×•×Ÿ ×”×–×” ×ž×©×ª×ž×© ×‘×ž×§×•×¨ ×”×–×“×”×•×ª ×—×™×¦×•× ×™. ×©×™× ×•×™ ×¡×™×¡×ž×” ×”×™× ×• ×‘×™×œ×ª×™ ××¤×©×¨
-  notice_account_lost_email_sent: ×“×•×"×œ ×¢× ×”×•×¨××•×ª ×œ×‘×—×™×¨×ª ×¡×™×¡×ž×” ×—×“×©×” × ×©×œ×— ××œ×™×š.
-  notice_account_activated: ×—×©×‘×•× ×š ×”×•×¤×¢×œ. ××ª×” ×™×›×•×œ ×œ×”×ª×—×‘×¨ ×›×¢×ª.
-  notice_successful_create: ×™×¦×™×¨×” ×ž×•×¦×œ×—×ª.
-  notice_successful_update: ×¢×™×“×›×•×Ÿ ×ž×•×¦×œ×—.
-  notice_successful_delete: ×ž×—×™×§×” ×ž×•×¦×œ×—×ª.
-  notice_successful_connection: ×—×™×‘×•×¨ ×ž×•×¦×œ×—.
-  notice_file_not_found: ×”×“×£ ×©××ª×” ×ž× ×¡×” ×œ×’×©×ª ××œ×™×• ××™× ×• ×§×™×™× ××• ×©×”×•×¡×¨.
-  notice_locking_conflict: ×”×ž×™×“×¢ ×¢×•×“×›×Ÿ ×¢×œ ×™×“×™ ×ž×©×ª×ž×© ××—×¨.
-  notice_not_authorized: ××™× ×š ×ž×•×¨×©×” ×œ×¨××•×ª ×“×£ ×–×”.
-  notice_not_authorized_archived_project: ×”×¤×¨×•×™×§×˜ ×©××ª×” ×ž× ×¡×” ×œ×’×©×ª ××œ×™×• × ×ž×¦× ×‘××¨×›×™×•×Ÿ.
-  notice_email_sent: "×“×•××œ × ×©×œ×— ×œ×›×ª×•×‘×ª %{value}"
-  notice_email_error: "××¨×¢×” ×©×’×™××” ×‘×¢×ª ×©×œ×™×—×ª ×”×“×•××œ (%{value})"
-  notice_feeds_access_key_reseted: ×ž×¤×ª×— ×”Ö¾RSS ×©×œ×š ××•×¤×¡.
-  notice_api_access_key_reseted: ×ž×¤×ª×— ×”×’×™×©×” ×©×œ×š ×œÖ¾API ××•×¤×¡.
-  notice_failed_to_save_issues: "× ×›×©×¨×ª ×‘×©×ž×™×¨×ª %{count} × ×•×©××™× ×‘ %{total} × ×‘×—×¨×•: %{ids}."
-  notice_failed_to_save_members: "×›×©×œ×•×Ÿ ×‘×©×ž×™×¨×ª ×—×‘×¨(×™×): %{errors}."
-  notice_no_issue_selected: "×œ× × ×‘×—×¨ ××£ × ×•×©×! ×‘×—×¨ ×‘×‘×§×©×” ××ª ×”× ×•×©××™× ×©×‘×¨×¦×•× ×š ×œ×¢×¨×•×š."
-  notice_account_pending: "×”×—×©×‘×•×Ÿ ×©×œ×š × ×•×¦×¨ ×•×¢×ª×” ×ž×—×›×” ×œ××™×©×•×¨ ×ž× ×”×œ ×”×ž×¢×¨×›×ª."
-  notice_default_data_loaded: ××¤×©×¨×•×™×•×ª ×‘×¨×™×¨×ª ×ž×—×“×œ ×ž×•×¤×¢×œ×•×ª.
-  notice_unable_delete_version: ×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ×’×™×¨×¡×”
-  notice_unable_delete_time_entry: ×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ×¨×©×•×ž×ª ×–×ž×Ÿ.
-  notice_issue_done_ratios_updated: ××—×•×–×™ ×”×ª×§×“×ž×•×ª ×œ× ×•×©× ×¢×•×“×›× ×•.
-
-  error_can_t_load_default_data: "××¤×©×¨×•×™×•×ª ×‘×¨×™×¨×ª ×”×ž×—×“×œ ×œ× ×”×¦×œ×™×—×• ×œ×”×™×˜×¢×Ÿ: %{value}"
-  error_scm_not_found: ×›× ×™×¡×” ×•\××• ×ž×”×“×•×¨×” ××™× × ×§×™×™×ž×™× ×‘×ž××’×¨.
-  error_scm_command_failed: "××¨×¢×” ×©×’×™××” ×‘×¢×ª × ×™×¡×•×Ÿ ×’×™×©×” ×œ×ž××’×¨: %{value}"
-  error_scm_annotate: "×”×›× ×™×¡×” ×œ× ×§×™×™×ž×ª ××• ×©×œ× × ×™×ª×Ÿ ×œ×ª××¨ ××•×ª×”."
-  error_issue_not_found_in_project: '×”× ×•×©××™× ×œ× × ×ž×¦××• ××• ××™× × ×©×™×›×™× ×œ×¤×¨×•×™×§×˜'
-  error_no_tracker_in_project: ×œ× ×”×•×’×“×¨ ×¡×™×•×•×’ ×œ×¤×¨×•×™×§×˜ ×–×”. × × ×‘×“×•×§ ××ª ×”×’×“×¨×•×ª ×”×¤×¨×•×™×§×˜.
-  error_no_default_issue_status: ×œ× ×ž×•×’×“×¨ ×ž×¦×‘ ×‘×¨×™×¨×ª ×ž×—×“×œ ×œ× ×•×©××™×. × × ×‘×“×•×§ ××ª ×”×ª×¦×•×¨×” ("× ×™×”×•×œ -> ×ž×¦×‘×™ × ×•×©×").
-  error_can_not_delete_custom_field: ×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ×©×“×” ×ž×•×ª×× ××™×©×™×ª
-  error_can_not_delete_tracker: ×§×™×™×ž×™× × ×•×©××™× ×‘×¡×™×•×•×’ ×–×”, ×•×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ××•×ª×•.
-  error_can_not_remove_role: ×ª×¤×§×™×“ ×–×” × ×ž×¦× ×‘×©×™×ž×•×©, ×•×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ××•×ª×•.
-  error_can_not_reopen_issue_on_closed_version: ×œ× × ×™×ª×Ÿ ×œ×¤×ª×•×— ×ž×—×“×© × ×•×©× ×©×ž×©×•×™×š ×œ×’×™×¨×¡×” ×¡×’×•×¨×”
-  error_can_not_archive_project: ×œ× × ×™×ª×Ÿ ×œ××¨×›×‘ ×¤×¨×•×™×§×˜ ×–×”
-  error_issue_done_ratios_not_updated: ××—×•×– ×”×ª×§×“×ž×•×ª ×œ× ×•×©× ×œ× ×¢×•×“×›×Ÿ.
-  error_workflow_copy_source: × × ×‘×—×¨ ×¡×™×•×•×’ ××• ×ª×¤×§×™×“ ×ž×§×•×¨
-  error_workflow_copy_target: × × ×‘×—×¨ ×ª×¤×§×™×“(×™×) ×•×¡×™×•×•×’(×™×)
-  error_unable_delete_issue_status: ×œ× × ×™×ª×Ÿ ×œ×ž×—×•×§ ×ž×¦×‘ × ×•×©×
-  error_unable_to_connect: ×œ× × ×™×ª×Ÿ ×œ×”×ª×—×‘×¨ (%{value})
-  warning_attachments_not_saved: "×›×©×œ×•×Ÿ ×‘×©×ž×™×¨×ª %{count} ×§×‘×¦×™×."
-
-  mail_subject_lost_password: "×¡×™×¡×ž×ª ×”Ö¾%{value} ×©×œ×š"
-  mail_body_lost_password: '×œ×©×™× ×• ×¡×™×¡×ž×ª ×”Ö¾Redmine ×©×œ×š, ×œ×—×¥ ×¢×œ ×”×§×™×©×•×¨ ×”×‘×:'
-  mail_subject_register: "×”×¤×¢×œ×ª ×—×©×‘×•×Ÿ %{value}"
-  mail_body_register: '×œ×”×¤×¢×œ×ª ×—×©×‘×•×Ÿ ×”Ö¾Redmine ×©×œ×š, ×œ×—×¥ ×¢×œ ×”×§×™×©×•×¨ ×”×‘×:'
-  mail_body_account_information_external: "××ª×” ×™×›×•×œ ×œ×”×©×ª×ž×© ×‘×—×©×‘×•×Ÿ %{value} ×›×“×™ ×œ×”×ª×—×‘×¨"
-  mail_body_account_information: ×¤×¨×˜×™ ×”×—×©×‘×•×Ÿ ×©×œ×š
-  mail_subject_account_activation_request: "×‘×§×©×ª ×”×¤×¢×œ×” ×œ×—×©×‘×•×Ÿ %{value}"
-  mail_body_account_activation_request: "×ž×©×ª×ž×© ×—×“×© (%{value}) × ×¨×©×. ×”×—×©×‘×•×Ÿ ×©×œ×• ×ž×—×›×” ×œ××™×©×•×¨ ×©×œ×š:"
-  mail_subject_reminder: "%{count} × ×•×©××™× ×ž×™×•×¢×“×™× ×œ×”×’×©×” ×‘×™×ž×™× ×”×§×¨×•×‘×™× (%{days})"
-  mail_body_reminder: "%{count} × ×•×©××™× ×©×ž×™×•×¢×“×™× ××œ×™×š ×ž×™×•×¢×“×™× ×œ×”×’×©×” ×‘×ª×•×š %{days} ×™×ž×™×:"
-  mail_subject_wiki_content_added: "×“×£ ×”Ö¾wiki â€'%{id}' × ×•×¡×£"
-  mail_body_wiki_content_added: ×“×£ ×”Ö¾wiki â€'%{id}' × ×•×¡×£ ×¢"×™ %{author}.
-  mail_subject_wiki_content_updated: "×“×£ ×”Ö¾wiki â€'%{id}' ×¢×•×“×›×Ÿ"
-  mail_body_wiki_content_updated: ×“×£ ×”Ö¾wiki â€'%{id}' ×¢×•×“×›×Ÿ ×¢"×™ %{author}.
-
-  gui_validation_error: ×©×’×™××” 1
-  gui_validation_error_plural: "%{count} ×©×’×™××•×ª"
-
-  field_name: ×©×
-  field_description: ×ª×™××•×¨
-  field_summary: ×ª×§×¦×™×¨
-  field_is_required: × ×“×¨×©
-  field_firstname: ×©× ×¤×¨×˜×™
-  field_lastname: ×©× ×ž×©×¤×—×”
-  field_mail: ×“×•×"×œ
-  field_filename: ×§×•×‘×¥
-  field_filesize: ×’×•×“×œ
-  field_downloads: ×”×•×¨×“×•×ª
-  field_author: ×›×•×ª×‘
-  field_created_on: × ×•×¦×¨
-  field_updated_on: ×¢×•×“×›×Ÿ
-  field_field_format: ×¤×•×¨×ž×˜
-  field_is_for_all: ×œ×›×œ ×”×¤×¨×•×™×§×˜×™×
-  field_possible_values: ×¢×¨×›×™× ××¤×©×¨×™×™×
-  field_regexp: ×‘×™×˜×•×™ ×¨×’×™×œ
-  field_min_length: ××•×¨×š ×ž×™× ×™×ž××œ×™
-  field_max_length: ××•×¨×š ×ž×§×¡×™×ž××œ×™
-  field_value: ×¢×¨×š
-  field_category: ×§×˜×’×•×¨×™×”
-  field_title: ×›×•×ª×¨×ª
-  field_project: ×¤×¨×•×™×§×˜
-  field_issue: × ×•×©×
-  field_status: ×ž×¦×‘
-  field_notes: ×”×¢×¨×•×ª
-  field_is_closed: × ×•×©× ×¡×’×•×¨
-  field_is_default: ×¢×¨×š ×‘×¨×™×¨×ª ×ž×—×“×œ
-  field_tracker: ×¡×™×•×•×’
-  field_subject: ×©× × ×•×©×
-  field_due_date: ×ª××¨×™×š ×¡×™×•×
-  field_assigned_to: ××—×¨××™
-  field_priority: ×¢×“×™×¤×•×ª
-  field_fixed_version: ×’×™×¨×¡×ª ×™×¢×“
-  field_user: ×ž×ª×©×ž×©
-  field_principal: ×ž× ×”×œ
-  field_role: ×ª×¤×§×™×“
-  field_homepage: ×“×£ ×”×‘×™×ª
-  field_is_public: ×¤×•×ž×‘×™
-  field_parent: ×ª×ª ×¤×¨×•×™×§×˜ ×©×œ
-  field_is_in_roadmap: × ×•×©××™× ×”×ž×•×¦×’×™× ×‘×ž×¤×ª ×”×“×¨×›×™×
-  field_login: ×©× ×ž×©×ª×ž×©
-  field_mail_notification: ×”×•×“×¢×•×ª ×“×•×"×œ
-  field_admin: × ×™×”×•×œ
-  field_last_login_on: ×”×ª×—×‘×¨×•×ª ××—×¨×•× ×”
-  field_language: ×©×¤×”
-  field_effective_date: ×ª××¨×™×š
-  field_password: ×¡×™×¡×ž×”
-  field_new_password: ×¡×™×¡×ž×” ×—×“×©×”
-  field_password_confirmation: ××™×©×•×¨
-  field_version: ×’×™×¨×¡×”
-  field_type: ×¡×•×’
-  field_host: ×©×¨×ª
-  field_port: ×¤×•×¨×˜
-  field_account: ×—×©×‘×•×Ÿ
-  field_base_dn: ×‘×¡×™×¡ DN
-  field_attr_login: ×ª×›×•× ×ª ×”×ª×—×‘×¨×•×ª
-  field_attr_firstname: ×ª×›×•× ×ª ×©× ×¤×¨×˜×™×
-  field_attr_lastname: ×ª×›×•× ×ª ×©× ×ž×©×¤×—×”
-  field_attr_mail: ×ª×›×•× ×ª ×“×•×"×œ
-  field_onthefly: ×™×¦×™×¨×ª ×ž×©×ª×ž×©×™× ×–×¨×™×–×”
-  field_start_date: ×ª××¨×™×š ×”×ª×—×œ×”
-  field_done_ratio: "% ×’×ž×•×¨"
-  field_auth_source: ×ž×§×•×¨ ×”×–×“×”×•×ª
-  field_hide_mail: ×”×—×‘× ××ª ×›×ª×•×‘×ª ×”×“×•×"×œ ×©×œ×™
-  field_comments: ×”×¢×¨×•×ª
-  field_url: URL
-  field_start_page: ×“×£ ×”×ª×—×œ×ª×™
-  field_subproject: ×ª×ªÖ¾×¤×¨×•×™×§×˜
-  field_hours: ×©×¢×•×ª
-  field_activity: ×¤×¢×™×œ×•×ª
-  field_spent_on: ×ª××¨×™×š
-  field_identifier: ×ž×–×”×”
-  field_is_filter: ×ž×©×ž×© ×›×ž×¡× ×Ÿ
-  field_issue_to: × ×•×©××™× ×§×©×•×¨×™×
-  field_delay: ×¢×™×§×•×‘
-  field_assignable: × ×™×ª×Ÿ ×œ×”×§×¦×•×ª × ×•×©××™× ×œ×ª×¤×§×™×“ ×–×”
-  field_redirect_existing_links: ×”×¢×‘×¨ ×§×™×©×•×¨×™× ×§×™×™×ž×™×
-  field_estimated_hours: ×–×ž×Ÿ ×ž×©×•×¢×¨
-  field_column_names: ×¢×ž×•×“×•×ª
-  field_time_entries: ×¨×™×©×•× ×–×ž× ×™×
-  field_time_zone: ××™×–×•×¨ ×–×ž×Ÿ
-  field_searchable: × ×™×ª×Ÿ ×œ×—×™×¤×•×©
-  field_default_value: ×¢×¨×š ×‘×¨×™×¨×ª ×ž×—×“×œ
-  field_comments_sorting: ×”×¦×’ ×”×¢×¨×•×ª
-  field_parent_title: ×“×£ ××‘
-  field_editable: × ×™×ª×Ÿ ×œ×¢×¨×™×›×”
-  field_watcher: ×¦×•×¤×”
-  field_identity_url: ×›×ª×•×‘×ª OpenID
-  field_content: ×ª×•×›×Ÿ
-  field_group_by: ×§×‘×¥ ××ª ×”×ª×•×¦××•×ª ×œ×¤×™
-  field_sharing: ×©×™×ª×•×£
-  field_parent_issue: ×ž×©×™×ž×ª ××‘
-  field_text: ×©×“×” ×˜×§×¡×˜
-
-  setting_app_title: ×›×•×ª×¨×ª ×™×©×•×
-  setting_app_subtitle: ×ª×ªÖ¾×›×•×ª×¨×ª ×™×©×•×
-  setting_welcome_text: ×˜×§×¡×˜ "×‘×¨×•×š ×”×‘×"
-  setting_default_language: ×©×¤×ª ×‘×¨×™×¨×ª ×ž×—×“×œ
-  setting_login_required: ×“×¨×•×©×” ×”×–×“×”×•×ª
-  setting_self_registration: ××¤×©×¨ ×”×¨×©×ž×” ×¢×¦×ž×™×ª
-  setting_attachment_max_size: ×’×•×“×œ ×“×‘×•×§×” ×ž×§×¡×™×ž××œ×™
-  setting_issues_export_limit: ×’×‘×•×œ ×™×¦×•× × ×•×©××™×
-  setting_mail_from: ×›×ª×•×‘×ª ×©×œ×™×—×ª ×“×•×"×œ
-  setting_bcc_recipients: ×ž×•×¡×ª×¨ (bcc)
-  setting_plain_text_mail: ×˜×§×¡×˜ ×¤×©×•×˜ ×‘×œ×‘×“ (×œ×œ× HTML)
-  setting_host_name: ×©× ×©×¨×ª
-  setting_text_formatting: ×¢×™×¦×•×‘ ×˜×§×¡×˜
-  setting_wiki_compression: ×›×™×•×•×¥ ×”×™×¡×˜×•×¨×™×ª wiki
-  setting_feeds_limit: ×’×‘×•×œ ×ª×•×›×Ÿ ×”×–× ×•×ª
-  setting_default_projects_public: ×¤×¨×•×™×§×˜×™× ×—×“×©×™× ×”×™× × ×¤×•×ž×‘×™×™× ×›×‘×¨×™×¨×ª ×ž×—×“×œ
-  setting_autofetch_changesets: ×ž×©×™×›×” ××•×˜×•×ž×˜×™×ª ×©×œ ×©×™× ×•×™×™×
-  setting_sys_api_enabled: ××¤×©×¨ ×©×™×¨×•×ª ×¨×©×ª ×œ× ×™×”×•×œ ×”×ž××’×¨
-  setting_commit_ref_keywords: ×ž×™×œ×•×ª ×ž×¤×ª×— ×ž×§×©×¨×•×ª
-  setting_commit_fix_keywords: ×ž×™×œ×•×ª ×ž×¤×ª×— ×ž×ª×§× ×•×ª
-  setting_autologin: ×”×ª×—×‘×¨×•×ª ××•×˜×•×ž×˜×™×ª
-  setting_date_format: ×¤×•×¨×ž×˜ ×ª××¨×™×š
-  setting_time_format: ×¤×•×¨×ž×˜ ×–×ž×Ÿ
-  setting_cross_project_issue_relations: ×”×¨×©×” ×§×™×©×•×¨ × ×•×©××™× ×‘×™×Ÿ ×¤×¨×•×™×§×˜×™×
-  setting_issue_list_default_columns: ×¢×ž×•×“×•×ª ×‘×¨×™×¨×ª ×ž×—×“×œ ×”×ž×•×¦×’×•×ª ×‘×¨×©×™×ž×ª ×”× ×•×©××™×
-  setting_emails_footer: ×ª×—×ª×™×ª ×“×•×"×œ
-  setting_protocol: ×¤×¨×•×˜×•×§×•×œ
-  setting_per_page_options: ××¤×©×¨×•×™×•×ª ××•×‘×™×§×˜×™× ×œ×¤×™ ×“×£
-  setting_user_format: ×¤×•×¨×ž×˜ ×”×¦×’×ª ×ž×©×ª×ž×©×™×
-  setting_activity_days_default: ×™×ž×™× ×”×ž×•×¦×’×™× ×¢×œ ×¤×¢×™×œ×•×ª ×”×¤×¨×•×™×§×˜
-  setting_display_subprojects_issues: ×”×¦×’ × ×•×©××™× ×©×œ ×ª×ª×™Ö¾×¤×¨×•×™×§×˜×™× ×›×‘×¨×™×¨×ª ×ž×—×“×œ
-  setting_enabled_scm: ××¤×©×¨ × ×™×”×•×œ ×ª×¦×•×¨×”
-  setting_mail_handler_body_delimiters: ×—×ª×•×š ×›×ª×•×‘×•×ª ×“×•××¨ ××—×¨×™ ××—×ª ×ž×©×•×¨×•×ª ××œ×”
-  setting_mail_handler_api_enabled: ××¤×©×¨ ×©×™×¨×•×ª ×¨×©×ª ×œ×“×•××¨ × ×›× ×¡
-  setting_mail_handler_api_key: ×ž×¤×ª×— API
-  setting_sequential_project_identifiers: ×”×©×ª×ž×© ×‘×ž×¡×¤×¨×™× ×¢×•×§×‘×™× ×œ×ž×–×”×™ ×¤×¨×•×™×§×˜
-  setting_gravatar_enabled: ×©×™×ž×•×© ×‘×¦×œ×ž×™×•×ª ×ž×©×ª×ž×©×™× ×žÖ¾Gravatar
-  setting_gravatar_default: ×ª×ž×•× ×ª Gravatar ×‘×¨×™×¨×ª ×ž×—×“×œ
-  setting_diff_max_lines_displayed: ×ž×¡×¤×¨ ×ž×™×¨×‘×™ ×©×œ ×©×•×¨×•×ª ×‘×ª×¦×•×’×ª ×©×™× ×•×™×™×
-  setting_file_max_size_displayed: ×’×•×“×œ ×ž×™×¨×‘×™ ×©×œ ×ž×œ×œ ×”×ž×•×¦×’ ×‘×ª×•×š ×”×©×•×¨×”
-  setting_repository_log_display_limit: ×ž×¡×¤×¨ ×ž×™×¨×‘×™ ×©×œ ×ž×”×“×•×¨×•×ª ×”×ž×•×¦×’×•×ª ×‘×™×•×ž×Ÿ ×§×•×‘×¥
-  setting_openid: ××¤×©×¨ ×”×ª×—×‘×¨×•×ª ×•×¨×™×©×•× ×‘××ž×¦×¢×•×ª OpenID
-  setting_password_min_length: ××•×¨×š ×¡×™×¡×ž×” ×ž×™× ×™×ž××œ×™
-  setting_new_project_user_role_id: ×”×ª×¤×§×™×“ ×©×ž×•×’×“×¨ ×œ×ž×©×ª×ž×© ×¤×©×•×˜ ××©×¨ ×™×•×¦×¨ ×¤×¨×•×™×§×˜
-  setting_default_projects_modules: ×ž×•×“×•×œ×™× ×ž××•×¤×©×¨×™× ×‘×‘×¨×™×¨×ª ×ž×—×“×œ ×¢×‘×•×¨ ×¤×¨×•×™×§×˜×™× ×—×“×©×™×
-  setting_issue_done_ratio: ×—×©×‘ ××—×•×– ×”×ª×§×“×ž×•×ª ×‘× ×•×©× ×¢×
-  setting_issue_done_ratio_issue_field: ×”×©×ª×ž×© ×‘×©×“×” ×”× ×•×©×
-  setting_issue_done_ratio_issue_status: ×”×©×ª×ž×© ×‘×ž×¦×‘ ×”× ×•×©×
-  setting_start_of_week: ×”×©×‘×•×¢ ×ž×ª×—×™×œ ×‘×™×•×
-  setting_rest_api_enabled: ××¤×©×¨ ×©×™×¨×•×ª ×¨×©×ª REST
-  setting_cache_formatted_text: ×©×ž×•×¨ ×˜×§×¡×˜ ×ž×¢×•×¦×‘ ×‘×ž×˜×ž×•×Ÿ
-  setting_default_notification_option: ××¤×©×¨×•×ª ×”×ª×¨××” ×‘×¨×™×¨×ªÖ¾×ž×—×“×œ
-
-  permission_add_project: ×™×¦×™×¨×ª ×¤×¨×•×™×§×˜
-  permission_add_subprojects: ×™×¦×™×¨×ª ×ª×ª×™Ö¾×¤×¨×•×™×§×˜
-  permission_edit_project: ×¢×¨×™×›×ª ×¤×¨×•×™×§×˜
-  permission_select_project_modules: ×‘×—×™×¨×ª ×ž×•×“×•×œ×™ ×¤×¨×•×™×§×˜
-  permission_manage_members: × ×™×”×•×œ ×—×‘×¨×™×
-  permission_manage_project_activities: × ×”×œ ×¤×¢×™×œ×•×™×•×ª ×¤×¨×•×™×§×˜
-  permission_manage_versions: × ×™×”×•×œ ×’×™×¨×¡××•×ª
-  permission_manage_categories: × ×™×”×•×œ ×§×˜×’×•×¨×™×•×ª × ×•×©××™×
-  permission_view_issues: ×¦×¤×™×” ×‘× ×•×©××™×
-  permission_add_issues: ×”×•×¡×¤×ª × ×•×©×
-  permission_edit_issues: ×¢×¨×™×›×ª × ×•×©××™×
-  permission_manage_issue_relations: × ×™×”×•×œ ×§×©×¨×™× ×‘×™×Ÿ × ×•×©××™×
-  permission_add_issue_notes: ×”×•×¡×¤×ª ×”×¢×¨×•×ª ×œ× ×•×©××™×
-  permission_edit_issue_notes: ×¢×¨×™×›×ª ×¨×©×™×ž×•×ª
-  permission_edit_own_issue_notes: ×¢×¨×™×›×ª ×”×¢×¨×•×ª ×©×œ ×¢×¦×ž×•
-  permission_move_issues: ×”×–×–×ª × ×•×©××™×
-  permission_delete_issues: ×ž×—×™×§×ª × ×•×©××™×
-  permission_manage_public_queries: × ×™×”×•×œ ×©××™×œ×ª×•×ª ×¤×•×ž×‘×™×•×ª
-  permission_save_queries: ×©×ž×™×¨×ª ×©××™×œ×ª×•×ª
-  permission_view_gantt: ×¦×¤×™×” ×‘×’×× ×˜
-  permission_view_calendar: ×¦×¤×™×” ×‘×œ×•×— ×”×©× ×”
-  permission_view_issue_watchers: ×¦×¤×™×” ×‘×¨×©×™×ž×ª ×¦×•×¤×™×
-  permission_add_issue_watchers: ×”×•×¡×¤×ª ×¦×•×¤×™×
-  permission_delete_issue_watchers: ×”×¡×¨×ª ×¦×•×¤×™×
-  permission_log_time: ×ª×™×¢×•×“ ×–×ž×Ÿ ×©×”×•×©×§×¢
-  permission_view_time_entries: ×¦×¤×™×” ×‘×¨×™×©×•× ×–×ž× ×™×
-  permission_edit_time_entries: ×¢×¨×™×›×ª ×¨×™×©×•× ×–×ž× ×™×
-  permission_edit_own_time_entries: ×¢×¨×™×›×ª ×¨×™×©×•× ×”×–×ž× ×™× ×©×œ ×¢×¦×ž×•
-  permission_manage_news: × ×™×”×•×œ ×—×“×©×•×ª
-  permission_comment_news: ×ª×’×•×‘×” ×œ×—×“×©×•×ª
-  permission_manage_documents: × ×™×”×•×œ ×ž×¡×ž×›×™×
-  permission_view_documents: ×¦×¤×™×” ×‘×ž×¡×ž×›×™×
-  permission_manage_files: × ×™×”×•×œ ×§×‘×¦×™×
-  permission_view_files: ×¦×¤×™×” ×‘×§×‘×¦×™×
-  permission_manage_wiki: × ×™×”×•×œ wiki
-  permission_rename_wiki_pages: ×©×™× ×•×™ ×©× ×©×œ ×“×¤×™ wiki
-  permission_delete_wiki_pages: ×ž×—×™×§×ª ×“×¤×™ wiki
-  permission_view_wiki_pages: ×¦×¤×™×” ×‘Ö¾wiki
-  permission_view_wiki_edits: ×¦×¤×™×” ×‘×”×™×¡×˜×•×¨×™×ª wiki
-  permission_edit_wiki_pages: ×¢×¨×™×›×ª ×“×¤×™ wiki
-  permission_delete_wiki_pages_attachments: ×ž×—×™×§×ª ×“×‘×•×§×•×ª
-  permission_protect_wiki_pages: ×”×’× ×” ×¢×œ ×›×œ ×“×¤×™ wiki
-  permission_manage_repository: × ×™×”×•×œ ×ž××’×¨
-  permission_browse_repository: ×¡×™×•×¨ ×‘×ž××’×¨
-  permission_view_changesets: ×¦×¤×™×” ×‘×¡×“×¨×•×ª ×©×™× ×•×™×™×
-  permission_commit_access: ××™×©×•×¨ ×”×¤×§×“×•×ª
-  permission_manage_boards: × ×™×”×•×œ ×œ×•×—×•×ª
-  permission_view_messages: ×¦×¤×™×” ×‘×”×•×“×¢×•×ª
-  permission_add_messages: ×”×¦×‘×ª ×”×•×“×¢×•×ª
-  permission_edit_messages: ×¢×¨×™×›×ª ×”×•×“×¢×•×ª
-  permission_edit_own_messages: ×¢×¨×™×›×ª ×”×•×“×¢×•×ª ×©×œ ×¢×¦×ž×•
-  permission_delete_messages: ×ž×—×™×§×ª ×”×•×“×¢×•×ª
-  permission_delete_own_messages: ×ž×—×™×§×ª ×”×•×“×¢×•×ª ×©×œ ×¢×¦×ž×•
-  permission_export_wiki_pages: ×™×¦× ×“×¤×™ wiki
-  permission_manage_subtasks: × ×”×œ ×ª×ª×™Ö¾×ž×©×™×ž×•×ª
-
-  project_module_issue_tracking: ×ž×¢×§×‘ × ×•×©××™×
-  project_module_time_tracking: ×ž×¢×§×‘ ××—×¨ ×–×ž× ×™×
-  project_module_news: ×—×“×©×•×ª
-  project_module_documents: ×ž×¡×ž×›×™×
-  project_module_files: ×§×‘×¦×™×
-  project_module_wiki: Wiki
-  project_module_repository: ×ž××’×¨
-  project_module_boards: ×œ×•×—×•×ª
-  project_module_calendar: ×œ×•×— ×©× ×”
-  project_module_gantt: ×’×× ×˜
-
-  label_user: ×ž×©×ª×ž×©
-  label_user_plural: ×ž×©×ª×ž×©×™×
-  label_user_new: ×ž×©×ª×ž×© ×—×“×©
-  label_user_anonymous: ××œ×ž×•× ×™
-  label_project: ×¤×¨×•×™×§×˜
-  label_project_new: ×¤×¨×•×™×§×˜ ×—×“×©
-  label_project_plural: ×¤×¨×•×™×§×˜×™×
-  label_x_projects:
-    zero:  ×œ×œ× ×¤×¨×•×™×§×˜×™×
-    one:   ×¤×¨×•×™×§×˜ ××—×“
-    other: "%{count} ×¤×¨×•×™×§×˜×™×"
-  label_project_all: ×›×œ ×”×¤×¨×•×™×§×˜×™×
-  label_project_latest: ×”×¤×¨×•×™×§×˜×™× ×”×—×“×©×™× ×‘×™×•×ª×¨
-  label_issue: × ×•×©×
-  label_issue_new: × ×•×©× ×—×“×©
-  label_issue_plural: × ×•×©××™×
-  label_issue_view_all: ×¦×¤×” ×‘×›×œ ×”× ×•×©××™×
-  label_issues_by: "× ×•×©××™× ×œ×¤×™ %{value}"
-  label_issue_added: × ×•×©× × ×•×¡×£
-  label_issue_updated: × ×•×©× ×¢×•×“×›×Ÿ
-  label_document: ×ž×¡×ž×š
-  label_document_new: ×ž×¡×ž×š ×—×“×©
-  label_document_plural: ×ž×¡×ž×›×™×
-  label_document_added: ×ž×¡×ž×š × ×•×¡×£
-  label_role: ×ª×¤×§×™×“
-  label_role_plural: ×ª×¤×§×™×“×™×
-  label_role_new: ×ª×¤×§×™×“ ×—×“×©
-  label_role_and_permissions: ×ª×¤×§×™×“×™× ×•×”×¨×©××•×ª
-  label_member: ×—×‘×¨
-  label_member_new: ×—×‘×¨ ×—×“×©
-  label_member_plural: ×—×‘×¨×™×
-  label_tracker: ×¡×™×•×•×’
-  label_tracker_plural: ×¡×™×•×•×’×™×
-  label_tracker_new: ×¡×™×•×•×’ ×—×“×©
-  label_workflow: ×–×¨×™×ž×ª ×¢×‘×•×“×”
-  label_issue_status: ×ž×¦×‘ × ×•×©×
-  label_issue_status_plural: ×ž×¦×‘×™ × ×•×©×
-  label_issue_status_new: ×ž×¦×‘ ×—×“×©
-  label_issue_category: ×§×˜×’×•×¨×™×ª × ×•×©×
-  label_issue_category_plural: ×§×˜×’×•×¨×™×•×ª × ×•×©×
-  label_issue_category_new: ×§×˜×’×•×¨×™×” ×—×“×©×”
-  label_custom_field: ×©×“×” ××™×©×™
-  label_custom_field_plural: ×©×“×•×ª ××™×©×™×™×
-  label_custom_field_new: ×©×“×” ××™×©×™ ×—×“×©
-  label_enumerations: ××™× ×•×ž×¨×¦×™×•×ª
-  label_enumeration_new: ×¢×¨×š ×—×“×©
-  label_information: ×ž×™×“×¢
-  label_information_plural: ×ž×™×“×¢
-  label_please_login: × × ×”×ª×—×‘×¨
-  label_register: ×”×¨×©×ž×”
-  label_login_with_open_id_option: ××• ×”×ª×—×‘×¨ ×‘××ž×¦×¢×•×ª OpenID
-  label_password_lost: ××‘×“×” ×”×¡×™×¡×ž×”?
-  label_home: ×“×£ ×”×‘×™×ª
-  label_my_page: ×”×“×£ ×©×œ×™
-  label_my_account: ×”×—×©×‘×•×Ÿ ×©×œ×™
-  label_my_projects: ×”×¤×¨×•×™×§×˜×™× ×©×œ×™
-  label_my_page_block: ×‘×œ×•×§ ×”×“×£ ×©×œ×™
-  label_administration: × ×™×”×•×œ
-  label_login: ×”×ª×—×‘×¨
-  label_logout: ×”×ª× ×ª×§
-  label_help: ×¢×–×¨×”
-  label_reported_issues: × ×•×©××™× ×©×“×•×•×—×•
-  label_assigned_to_me_issues: × ×•×©××™× ×©×”×•×¦×‘×• ×œ×™
-  label_last_login: ×”×ª×—×‘×¨×•×ª ××—×¨×•× ×”
-  label_registered_on: × ×¨×©× ×‘×ª××¨×™×š
-  label_activity: ×¤×¢×™×œ×•×ª
-  label_overall_activity: ×¤×¢×™×œ×•×ª ×›×•×œ×œ×ª
-  label_user_activity: "×”×¤×¢×™×œ×•×ª ×©×œ %{value}"
-  label_new: ×—×“×©
-  label_logged_as: ×ž×—×•×‘×¨ ×›
-  label_environment: ×¡×‘×™×‘×”
-  label_authentication: ×”×–×“×”×•×ª
-  label_auth_source: ×ž×§×•×¨ ×”×–×“×”×•×ª
-  label_auth_source_new: ×ž×§×•×¨ ×”×–×“×”×•×ª ×—×“×©
-  label_auth_source_plural: ×ž×§×•×¨×•×ª ×”×–×“×”×•×ª
-  label_subproject_plural: ×ª×ªÖ¾×¤×¨×•×™×§×˜×™×
-  label_subproject_new: ×ª×ªÖ¾×¤×¨×•×™×§×˜ ×—×“×©
-  label_and_its_subprojects: "%{value} ×•×›×œ ×ª×ª×™Ö¾×”×¤×¨×•×™×§×˜×™× ×©×œ×•"
-  label_min_max_length: ××•×¨×š ×ž×™× ×™×ž××œ×™ - ×ž×§×¡×™×ž××œ×™
-  label_list: ×¨×©×™×ž×”
-  label_date: ×ª××¨×™×š
-  label_integer: ×ž×¡×¤×¨ ×©×œ×
-  label_float: ×¦×£
-  label_boolean: ×¢×¨×š ×‘×•×œ×™×× ×™
-  label_string: ×˜×§×¡×˜
-  label_text: ×˜×§×¡×˜ ××¨×•×š
-  label_attribute: ×ª×›×•× ×”
-  label_attribute_plural: ×ª×›×•× ×•×ª
-  label_download: "×”×•×¨×“×” %{count}"
-  label_download_plural: "%{count} ×”×•×¨×“×•×ª"
-  label_no_data: ××™×Ÿ ×ž×™×“×¢ ×œ×”×¦×™×’
-  label_change_status: ×©× ×” ×ž×¦×‘
-  label_history: ×”×™×¡×˜×•×¨×™×”
-  label_attachment: ×§×•×‘×¥
-  label_attachment_new: ×§×•×‘×¥ ×—×“×©
-  label_attachment_delete: ×ž×—×§ ×§×•×‘×¥
-  label_attachment_plural: ×§×‘×¦×™×
-  label_file_added: ×§×•×‘×¥ × ×•×¡×£
-  label_report: ×“×•"×—
-  label_report_plural: ×“×•"×—×•×ª
-  label_news: ×—×“×©×•×ª
-  label_news_new: ×”×•×¡×£ ×—×“×©×•×ª
-  label_news_plural: ×—×“×©×•×ª
-  label_news_latest: ×—×“×©×•×ª ××—×¨×•× ×•×ª
-  label_news_view_all: ×¦×¤×” ×‘×›×œ ×”×—×“×©×•×ª
-  label_news_added: ×—×“×©×•×ª × ×•×¡×¤×•
-  label_settings: ×”×’×“×¨×•×ª
-  label_overview: ×ž×‘×˜ ×¨×—×‘
-  label_version: ×’×™×¨×¡×”
-  label_version_new: ×’×™×¨×¡×” ×—×“×©×”
-  label_version_plural: ×’×™×¨×¡××•×ª
-  label_close_versions: ×¡×’×•×¨ ×’×™×¨×¡××•×ª ×©×”×•×©×œ×ž×•
-  label_confirmation: ××™×©×•×¨
-  label_export_to: ×™×¦× ×œ
-  label_read: ×§×¨×...
-  label_public_projects: ×¤×¨×•×™×§×˜×™× ×¤×•×ž×‘×™×™×
-  label_open_issues: ×¤×ª×•×—
-  label_open_issues_plural: ×¤×ª×•×—×™×
-  label_closed_issues: ×¡×’×•×¨
-  label_closed_issues_plural: ×¡×’×•×¨×™×
-  label_x_open_issues_abbr_on_total:
-    zero:  0 ×¤×ª×•×—×™× / %{total}
-    one:   1 ×¤×ª×•×— / %{total}
-    other: "%{count} ×¤×ª×•×—×™× / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 ×¤×ª×•×—×™×
-    one:   1 ×¤×ª×•×—
-    other: "%{count} ×¤×ª×•×—×™×"
-  label_x_closed_issues_abbr:
-    zero:  0 ×¡×’×•×¨×™×
-    one:   1 ×¡×’×•×¨
-    other: "%{count} ×¡×’×•×¨×™×"
-  label_total: ×¡×”"×›
-  label_permissions: ×”×¨×©××•×ª
-  label_current_status: ×ž×¦×‘ × ×•×›×—×™
-  label_new_statuses_allowed: ×ž×¦×‘×™× ×—×“×©×™× ××¤×©×¨×™×™×
-  label_all: ×”×›×œ
-  label_none: ×›×œ×•×
-  label_nobody: ××£ ××—×“
-  label_next: ×”×‘×
-  label_previous: ×”×§×•×“×
-  label_used_by: ×‘×©×™×ž×•×© ×¢"×™
-  label_details: ×¤×¨×˜×™×
-  label_add_note: ×”×•×¡×£ ×”×¢×¨×”
-  label_per_page: ×œ×›×œ ×“×£
-  label_calendar: ×œ×•×— ×©× ×”
-  label_months_from: ×—×•×“×©×™× ×ž
-  label_gantt: ×’×× ×˜
-  label_internal: ×¤× ×™×ž×™
-  label_last_changes: "%{count} ×©×™× ×•×™× ××—×¨×•× ×™×"
-  label_change_view_all: ×¦×¤×” ×‘×›×œ ×”×©×™× ×•×™×
-  label_personalize_page: ×”×ª×× ××™×©×™×ª ×“×£ ×–×”
-  label_comment: ×ª×’×•×‘×”
-  label_comment_plural: ×ª×’×•×‘×•×ª
-  label_x_comments:
-    zero: ××™×Ÿ ×”×¢×¨×•×ª
-    one: ×”×¢×¨×” ××—×ª
-    other: "%{count} ×”×¢×¨×•×ª"
-  label_comment_add: ×”×•×¡×£ ×ª×’×•×‘×”
-  label_comment_added: ×ª×’×•×‘×” × ×•×¡×¤×”
-  label_comment_delete: ×ž×—×§ ×ª×’×•×‘×•×ª
-  label_query: ×©××™×œ×ª×” ××™×©×™×ª
-  label_query_plural: ×©××™×œ×ª×•×ª ××™×©×™×•×ª
-  label_query_new: ×©××™×œ×ª×” ×—×“×©×”
-  label_filter_add: ×”×•×¡×£ ×ž×¡× ×Ÿ
-  label_filter_plural: ×ž×¡× × ×™×
-  label_equals: ×”×•×
-  label_not_equals: ×”×•× ×œ×
-  label_in_less_than: ×‘×¤×—×•×ª ×ž
-  label_in_more_than: ×‘×™×•×ª×¨ ×ž
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  label_in: ×‘
-  label_today: ×”×™×•×
-  label_all_time: ×ª×ž×™×“
-  label_yesterday: ××ª×ž×•×œ
-  label_this_week: ×”×©×‘×•×¢
-  label_last_week: ×”×©×‘×•×¢ ×©×¢×‘×¨
-  label_last_n_days: "×‘Ö¾%{count} ×™×ž×™× ××—×¨×•× ×™×"
-  label_this_month: ×”×—×•×“×©
-  label_last_month: ×—×•×“×© ×©×¢×‘×¨
-  label_this_year: ×”×©× ×”
-  label_date_range: ×˜×•×•×— ×ª××¨×™×›×™×
-  label_less_than_ago: ×¤×—×•×ª ×ž
-  label_more_than_ago: ×™×•×ª×¨ ×ž
-  label_ago: ×œ×¤× ×™
-  label_contains: ×ž×›×™×œ
-  label_not_contains: ×œ× ×ž×›×™×œ
-  label_day_plural: ×™×ž×™×
-  label_repository: ×ž××’×¨
-  label_repository_plural: ×ž××’×¨×™×
-  label_browse: ×¡×™×™×¨
-  label_modification: "×©×™× ×•×™ %{count}"
-  label_modification_plural: "%{count} ×©×™× ×•×™×™×"
-  label_branch: ×¢× ×£
-  label_tag: ×¡×™×ž×•×Ÿ
-  label_revision: ×ž×”×“×•×¨×”
-  label_revision_plural: ×ž×”×“×•×¨×•×ª
-  label_revision_id: ×ž×”×“×•×¨×” %{value}
-  label_associated_revisions: ×ž×”×“×•×¨×•×ª ×§×©×•×¨×•×ª
-  label_added: × ×•×¡×£
-  label_modified: ×©×•× ×”
-  label_copied: ×”×•×¢×ª×§
-  label_renamed: ×”×©× ×©×•× ×”
-  label_deleted: × ×ž×—×§
-  label_latest_revision: ×ž×”×“×•×¨×” ××—×¨×•× ×”
-  label_latest_revision_plural: ×ž×”×“×•×¨×•×ª ××—×¨×•× ×•×ª
-  label_view_revisions: ×¦×¤×” ×‘×ž×”×“×•×¨×•×ª
-  label_view_all_revisions: ×¦×¤×” ×‘×›×œ ×”×ž×”×“×•×¨×•×ª
-  label_max_size: ×’×•×“×œ ×ž×§×¡×™×ž××œ×™
-  label_sort_highest: ×”×–×– ×œ×¨××©×™×ª
-  label_sort_higher: ×”×–×– ×œ×ž×¢×œ×”
-  label_sort_lower: ×”×–×– ×œ×ž×˜×”
-  label_sort_lowest: ×”×–×– ×œ×ª×—×ª×™×ª
-  label_roadmap: ×ž×¤×ª ×”×“×¨×›×™×
-  label_roadmap_due_in: "× ×’×ž×¨ ×‘×¢×•×“ %{value}"
-  label_roadmap_overdue: "%{value} ×ž××—×¨"
-  label_roadmap_no_issues: ××™×Ÿ × ×•×©××™× ×œ×’×™×¨×¡×” ×–×•
-  label_search: ×—×¤×©
-  label_result_plural: ×ª×•×¦××•×ª
-  label_all_words: ×›×œ ×”×ž×™×œ×™×
-  label_wiki: Wiki
-  label_wiki_edit: ×¢×¨×•×š wiki
-  label_wiki_edit_plural: ×¢×¨×™×›×•×ª wiki
-  label_wiki_page: ×“×£ Wiki
-  label_wiki_page_plural: ×“×¤×™ wiki
-  label_index_by_title: ×¡×“×¨ ×¢×œ ×¤×™ ×›×•×ª×¨×ª
-  label_index_by_date: ×¡×“×¨ ×¢×œ ×¤×™ ×ª××¨×™×š
-  label_current_version: ×’×™×¨×¡×” × ×•×›×—×™×ª
-  label_preview: ×ª×¦×•×’×” ×ž×§×“×™×ž×”
-  label_feed_plural: ×”×–× ×•×ª
-  label_changes_details: ×¤×™×¨×•×˜ ×›×œ ×”×©×™× ×•×™×™×
-  label_issue_tracking: ×ž×¢×§×‘ ××—×¨ × ×•×©××™×
-  label_spent_time: ×–×ž×Ÿ ×©×”×•×©×§×¢
-  label_overall_spent_time: ×–×ž×Ÿ ×©×”×•×©×§×¢ ×¡×”"×›
-  label_f_hour: "%{value} ×©×¢×”"
-  label_f_hour_plural: "%{value} ×©×¢×•×ª"
-  label_time_tracking: ×ž×¢×§×‘ ×–×ž× ×™×
-  label_change_plural: ×©×™× ×•×™×™×
-  label_statistics: ×¡×˜×˜×™×¡×˜×™×§×•×ª
-  label_commits_per_month: ×”×¤×§×“×•×ª ×œ×¤×™ ×—×•×“×©
-  label_commits_per_author: ×”×¤×§×“×•×ª ×œ×¤×™ ×›×•×ª×‘
-  label_view_diff: ×¦×¤×” ×‘×©×™× ×•×™×™×
-  label_diff_inline: ×‘×ª×•×š ×”×©×•×¨×”
-  label_diff_side_by_side: ×¦×“ ×œ×¦×“
-  label_options: ××¤×©×¨×•×™×•×ª
-  label_copy_workflow_from: ×”×¢×ª×§ ×–×™×¨×ž×ª ×¢×‘×•×“×” ×ž
-  label_permissions_report: ×“×•"×— ×”×¨×©××•×ª
-  label_watched_issues: × ×•×©××™× ×©× ×¦×¤×•
-  label_related_issues: × ×•×©××™× ×§×©×•×¨×™×
-  label_applied_status: ×ž×¦×‘ ×ž×•×—×œ
-  label_loading: ×˜×•×¢×Ÿ...
-  label_relation_new: ×§×©×¨ ×—×“×©
-  label_relation_delete: ×ž×—×§ ×§×©×¨
-  label_relates_to: ×§×©×•×¨ ×œ
-  label_duplicates: ×ž×›×¤×™×œ ××ª
-  label_duplicated_by: ×©×•×›×¤×œ ×¢"×™
-  label_blocks: ×—×•×¡× ××ª
-  label_blocked_by: ×—×¡×•× ×¢"×™
-  label_precedes: ×ž×§×“×™× ××ª
-  label_follows: ×¢×•×§×‘ ××—×¨×™
-  label_end_to_start: ×ž×”×ª×—×œ×” ×œ×¡×•×£
-  label_end_to_end: ×ž×”×¡×•×£ ×œ×¡×•×£
-  label_start_to_start: ×ž×”×ª×—×œ×” ×œ×”×ª×—×œ×”
-  label_start_to_end: ×ž×”×ª×—×œ×” ×œ×¡×•×£
-  label_stay_logged_in: ×”×©××¨ ×ž×—×•×‘×¨
-  label_disabled: ×ž×‘×•×˜×œ
-  label_show_completed_versions: ×”×¦×’ ×’×™×¨×¡××•×ª ×’×ž×•×¨×•×ª
-  label_me: ×× ×™
-  label_board: ×¤×•×¨×•×
-  label_board_new: ×¤×•×¨×•× ×—×“×©
-  label_board_plural: ×¤×•×¨×•×ž×™×
-  label_board_locked: × ×¢×•×œ
-  label_board_sticky: ×“×‘×™×§
-  label_topic_plural: × ×•×©××™×
-  label_message_plural: ×”×•×“×¢×•×ª
-  label_message_last: ×”×•×“×¢×” ××—×¨×•× ×”
-  label_message_new: ×”×•×“×¢×” ×—×“×©×”
-  label_message_posted: ×”×•×“×¢×” × ×•×¡×¤×”
-  label_reply_plural: ×”×©×‘×•×ª
-  label_send_information: ×©×œ×— ×ž×™×“×¢ ×¢×œ ×—×©×‘×•×Ÿ ×œ×ž×©×ª×ž×©
-  label_year: ×©× ×”
-  label_month: ×—×•×“×©
-  label_week: ×©×‘×•×¢
-  label_date_from: ×ž×ª××¨×™×š
-  label_date_to: ×¢×“
-  label_language_based: ×ž×‘×•×¡×¡ ×©×¤×”
-  label_sort_by: "×ž×™×™×Ÿ ×œ×¤×™ %{value}"
-  label_send_test_email: ×©×œ×— ×“×•×"×œ ×‘×“×™×§×”
-  label_feeds_access_key: ×ž×¤×ª×— ×’×™×©×” ×œÖ¾RSS
-  label_missing_feeds_access_key: ×—×¡×¨ ×ž×¤×ª×— ×’×™×©×” ×œÖ¾RSS
-  label_feeds_access_key_created_on: "×ž×¤×ª×— ×”×–× ×ª RSS × ×•×¦×¨ ×œ×¤× ×™%{value}"
-  label_module_plural: ×ž×•×“×•×œ×™×
-  label_added_time_by: '× ×•×¡×£ ×¢"×™ %{author} ×œ×¤× ×™ %{age}'
-  label_updated_time_by: '×¢×•×“×›×Ÿ ×¢"×™ %{author} ×œ×¤× ×™ %{age}'
-  label_updated_time: "×¢×•×“×›×Ÿ ×œ×¤× ×™ %{value} "
-  label_jump_to_a_project: ×§×¤×•×¥ ×œ×¤×¨×•×™×§×˜...
-  label_file_plural: ×§×‘×¦×™×
-  label_changeset_plural: ×¡×“×¨×•×ª ×©×™× ×•×™×™×
-  label_default_columns: ×¢×ž×•×“×ª ×‘×¨×™×¨×ª ×ž×—×“×œ
-  label_no_change_option: (××™×Ÿ ×©×™× ×•×™×)
-  label_bulk_edit_selected_issues: ×¢×¨×•×š ××ª ×”× ×•×©××™× ×”×ž×¡×•×ž× ×™×
-  label_theme: ×¢×¨×›×ª × ×•×©×
-  label_default: ×‘×¨×™×¨×ª ×ž×—×“×œ
-  label_search_titles_only: ×—×¤×© ×‘×›×•×ª×¨×•×ª ×‘×œ×‘×“
-  label_user_mail_option_all: "×œ×›×œ ××™×¨×•×¢ ×‘×›×œ ×”×¤×¨×•×™×§×˜×™× ×©×œ×™"
-  label_user_mail_option_selected: "×œ×›×œ ××™×¨×•×¢ ×‘×¤×¨×•×™×§×˜×™× ×©×‘×—×¨×ª×™ ×‘×œ×‘×“..."
-  label_user_mail_option_only_my_events: ×¢×‘×•×¨ ×“×‘×¨×™× ×©×× ×™ ×¦×•×¤×” ××• ×ž×¢×•×¨×‘ ×‘×”× ×‘×œ×‘×“
-  label_user_mail_option_only_assigned: ×¢×‘×•×¨ ×“×‘×¨×™× ×©×× ×™ ××—×¨××™ ×¢×œ×™×”× ×‘×œ×‘×“
-  label_user_mail_option_only_owner: ×¢×‘×•×¨ ×“×‘×¨×™× ×©×× ×™ ×”×‘×¢×œ×™× ×©×œ×”× ×‘×œ×‘×“
-  label_user_mail_no_self_notified: "×× ×™ ×œ× ×¨×•×¦×” ×©×™×•×“×™×¢×• ×œ×™ ×¢×œ ×©×™× ×•×™×™× ×©×× ×™ ×ž×‘×¦×¢"
-  label_registration_activation_by_email: ×”×¤×¢×œ ×—×©×‘×•×Ÿ ×‘××ž×¦×¢×•×ª ×“×•×"×œ
-  label_registration_manual_activation: ×”×¤×¢×œ×ª ×—×©×‘×•×Ÿ ×™×“× ×™×ª
-  label_registration_automatic_activation: ×”×¤×¢×œ×ª ×—×©×‘×•×Ÿ ××•×˜×•×ž×˜×™×ª
-  label_display_per_page: "×‘×›×œ ×“×£: %{value} ×ª×•×¦××•×ª"
-  label_age: ×’×™×œ
-  label_change_properties: ×©× ×” ×ž××¤×™×™× ×™×
-  label_general: ×›×œ×œ×™
-  label_more: ×¢×•×“
-  label_scm: ×ž×¢×¨×›×ª × ×™×”×•×œ ×ª×¦×•×¨×”
-  label_plugins: ×ª×•×¡×¤×™×
-  label_ldap_authentication: ×”×–×“×”×•×ª LDAP
-  label_downloads_abbr: D/L
-  label_optional_description: ×ª×™××•×¨ ×¨×©×•×ª
-  label_add_another_file: ×”×•×¡×£ ×¢×•×“ ×§×•×‘×¥
-  label_preferences: ×”×¢×“×¤×•×ª
-  label_chronological_order: ×‘×¡×“×¨ ×›×¨×•× ×•×œ×•×’×™
-  label_reverse_chronological_order: ×‘×¡×“×¨ ×›×¨×•× ×•×œ×•×’×™ ×”×¤×•×š
-  label_planning: ×ª×›× ×•×Ÿ
-  label_incoming_emails: ×“×•×"×œ × ×›× ×¡
-  label_generate_key: ×¦×•×¨ ×ž×¤×ª×—
-  label_issue_watchers: ×¦×•×¤×™×
-  label_example: ×“×•×’×ž×
-  label_display: ×ª×¦×•×’×”
-  label_sort: ×ž×™×•×Ÿ
-  label_ascending: ×‘×¡×“×¨ ×¢×•×œ×”
-  label_descending: ×‘×¡×“×¨ ×™×•×¨×“
-  label_date_from_to: '×ž×ª××¨×™×š %{start} ×•×¢×“ ×ª××¨×™×š %{end}'
-  label_wiki_content_added: × ×•×¡×£ ×“×£ ×œÖ¾wiki
-  label_wiki_content_updated: ×“×£ wiki ×¢×•×“×›×Ÿ
-  label_group: ×§×‘×•×¦×”
-  label_group_plural: ×§×‘×•×¦×•×ª
-  label_group_new: ×§×‘×•×¦×” ×—×“×©×”
-  label_time_entry_plural: ×–×ž×Ÿ ×©×”×•×©×§×¢
-  label_version_sharing_none: ×œ× ×ž×©×•×ª×£
-  label_version_sharing_descendants: ×¢× ×¤×¨×•×™×§×˜×™× ×‘× ×™×
-  label_version_sharing_hierarchy: ×¢× ×”×™×¨×¨×›×™×ª ×”×¤×¨×•×™×§×˜×™×
-  label_version_sharing_tree: ×¢× ×¢×¥ ×”×¤×¨×•×™×§×˜
-  label_version_sharing_system: ×¢× ×›×œ ×”×¤×¨×•×™×§×˜×™×
-  label_update_issue_done_ratios: ×¢×“×›×Ÿ ××—×•×– ×”×ª×§×“×ž×•×ª ×œ× ×•×©×
-  label_copy_source: ×ž×§×•×¨
-  label_copy_target: ×™×¢×“
-  label_copy_same_as_target: ×–×”×” ×œ×™×¢×“
-  label_display_used_statuses_only: ×”×¦×’ ×¨×§ ××ª ×”×ž×¦×‘×™× ×‘×©×™×ž×•×© ×œ×¡×™×•×•×’ ×–×”
-  label_api_access_key: ×ž×¤×ª×— ×’×™×©×” ×œÖ¾API
-  label_missing_api_access_key: ×—×¡×¨ ×ž×¤×ª×— ×’×™×©×” ×œÖ¾API
-  label_api_access_key_created_on: '×ž×¤×ª×— ×’×™×©×” ×œÖ¾API × ×•×¦×¨ ×œ×¤× ×™ %{value}'
-  label_profile: ×¤×¨×•×¤×™×œ
-  label_subtask_plural: ×ª×ª×™Ö¾×ž×©×™×ž×•×ª
-  label_project_copy_notifications: ×©×œ×— ×”×ª×¨××•×ª ×“×•××¨ ×‘×ž×”×œ×š ×”×¢×ª×§×ª ×”×¤×¨×•×™×§×˜
-
-  button_login: ×”×ª×—×‘×¨
-  button_submit: ××©×¨
-  button_save: ×©×ž×•×¨
-  button_check_all: ×‘×—×¨ ×”×›×œ
-  button_uncheck_all: ×‘×—×¨ ×›×œ×•×
-  button_delete: ×ž×—×§
-  button_create: ×¦×•×¨
-  button_create_and_continue: ×¦×•×¨ ×•×¤×ª×— ×—×“×©
-  button_test: ×‘×“×•×§
-  button_edit: ×¢×¨×•×š
-  button_edit_associated_wikipage: "×¢×¨×•×š ×“×£ wiki ×ž×§×•×©×¨: %{page_title}"
-  button_add: ×”×•×¡×£
-  button_change: ×©× ×”
-  button_apply: ×”×—×œ
-  button_clear: × ×§×”
-  button_lock: × ×¢×œ
-  button_unlock: ×‘×˜×œ × ×¢×™×œ×”
-  button_download: ×”×•×¨×“
-  button_list: ×¨×©×™×ž×”
-  button_view: ×¦×¤×”
-  button_move: ×”×–×–
-  button_move_and_follow: ×”×¢×‘×¨ ×•×¢×§×•×‘
-  button_back: ×”×§×•×“×
-  button_cancel: ×‘×˜×œ
-  button_activate: ×”×¤×¢×œ
-  button_sort: ×ž×™×™×Ÿ
-  button_log_time: ×¨×™×©×•× ×–×ž× ×™×
-  button_rollback: ×—×–×•×¨ ×œ×ž×”×“×•×¨×” ×–×•
-  button_watch: ×¦×¤×”
-  button_unwatch: ×‘×˜×œ ×¦×¤×™×”
-  button_reply: ×”×©×‘
-  button_archive: ××¨×›×™×•×Ÿ
-  button_unarchive: ×”×•×¦× ×ž×”××¨×›×™×•×Ÿ
-  button_reset: ××¤×¡
-  button_rename: ×©× ×” ×©×
-  button_change_password: ×©× ×” ×¡×™×¡×ž×”
-  button_copy: ×”×¢×ª×§
-  button_copy_and_follow: ×”×¢×ª×§ ×•×¢×§×•×‘
-  button_annotate: ×”×•×¡×£ ×ª×™××•×¨ ×ž×¡×’×¨×ª
-  button_update: ×¢×“×›×Ÿ
-  button_configure: ××¤×©×¨×•×™×•×ª
-  button_quote: ×¦×˜×˜
-  button_duplicate: ×©×›×¤×œ
-  button_show: ×”×¦×’
-
-  status_active: ×¤×¢×™×œ
-  status_registered: ×¨×©×•×
-  status_locked: × ×¢×•×œ
-
-  version_status_open: ×¤×ª×•×—
-  version_status_locked: × ×¢×•×œ
-  version_status_closed: ×¡×’×•×¨
-
-  field_active: ×¤×¢×™×œ
-
-  text_select_mail_notifications: ×‘×—×¨ ×¤×¢×•×œ×ª ×©×‘×’×œ×œ×Ÿ ×™×©×œ×— ×“×•×"×œ.
-  text_regexp_info: ×›×’×•×Ÿ. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 ×ž×©×ž×¢×• ×œ×œ× ×”×’×‘×œ×•×ª
-  text_project_destroy_confirmation: ×”×× ××ª×” ×‘×˜×•×— ×©×‘×¨×¦×•× ×š ×œ×ž×—×•×§ ××ª ×”×¤×¨×•×™×§×˜ ×•××ª ×›×œ ×”×ž×™×“×¢ ×”×§×©×•×¨ ××œ×™×•?
-  text_subprojects_destroy_warning: "×ª×ªÖ¾×”×¤×¨×•×™×§×˜×™×: %{value} ×™×ž×—×§×• ×’× ×›×Ÿ."
-  text_workflow_edit: ×‘×—×¨ ×ª×¤×§×™×“ ×•×¡×™×•×•×’ ×›×“×™ ×œ×¢×¨×•×š ××ª ×–×¨×™×ž×ª ×”×¢×‘×•×“×”
-  text_are_you_sure: ×”×× ××ª×” ×‘×˜×•×—?
-  text_are_you_sure_with_children: ×”×× ×œ×ž×—×•×§ ××ª ×”× ×•×©× ×•××ª ×›×œ ×‘× ×™×•?
-  text_journal_changed: "%{label} ×”×©×ª× ×” ×ž%{old} ×œ%{new}"
-  text_journal_set_to: "%{label} × ×§×‘×¢ ×œ%{value}"
-  text_journal_deleted: "%{label} × ×ž×—×§ (%{old})"
-  text_journal_added: "%{label} %{value} × ×•×¡×£"
-  text_tip_issue_begin_day: ×ž×˜×œ×” ×”×ž×ª×—×™×œ×” ×”×™×•×
-  text_tip_issue_end_day: ×ž×˜×œ×” ×”×ž×¡×ª×™×™×ž×ª ×”×™×•×
-  text_tip_issue_begin_end_day: ×ž×˜×œ×” ×”×ž×ª×—×™×œ×” ×•×ž×¡×ª×™×™×ž×ª ×”×™×•×
-  text_project_identifier_info: '××•×ª×™×•×ª ×œ×˜×™× ×™×•×ª (a-z), ×ž×¡×¤×¨×™× ×•×ž×§×¤×™×.<br />×‘×¨×’×¢ ×©× ×©×ž×¨, ×œ× × ×™×ª×Ÿ ×œ×©× ×•×ª ××ª ×”×ž×–×”×”.'
-  text_caracters_maximum: "×ž×§×¡×™×ž×•× %{count} ×ª×•×•×™×."
-  text_caracters_minimum: "×—×™×™×‘ ×œ×”×™×•×ª ×œ×¤×—×•×ª ×‘××•×¨×š ×©×œ %{count} ×ª×•×•×™×."
-  text_length_between: "××•×¨×š ×‘×™×Ÿ %{min} ×œ %{max} ×ª×•×•×™×."
-  text_tracker_no_workflow: ×–×¨×™×ž×ª ×¢×‘×•×“×” ×œ× ×”×•×’×“×¨×” ×¢×‘×•×¨ ×¡×™×•×•×’ ×–×”
-  text_unallowed_characters: ×ª×•×•×™× ×œ× ×ž×•×¨×©×™×
-  text_comma_separated: ×”×›× ×¡×ª ×¢×¨×›×™× ×ž×¨×•×‘×™× ×ž×•×ª×¨×ª (×ž×•×¤×¨×“×™× ×‘×¤×¡×™×§×™×).
-  text_line_separated: × ×™×ª×Ÿ ×œ×”×–×™×Ÿ ×ž×¡×¤×¨ ×¢×¨×›×™× (×©×•×¨×” ××—×ª ×œ×›×œ ×¢×¨×š).
-  text_issues_ref_in_commit_messages: ×§×™×©×•×¨ ×•×ª×™×§×•× × ×•×©××™× ×‘×”×•×“×¢×•×ª ×”×¤×§×“×”
-  text_issue_added: "×”× ×•×©× %{id} ×“×•×•×— (×‘×™×“×™ %{author})."
-  text_issue_updated: "×”× ×•×©× %{id} ×¢×•×“×›×Ÿ (×‘×™×“×™ %{author})."
-  text_wiki_destroy_confirmation: ×”×× ××ª×” ×‘×˜×•×— ×©×‘×¨×¦×•× ×š ×œ×ž×—×•×§ ××ª ×”WIKI ×”×–×” ×•××ª ×›×œ ×ª×•×›× ×•?
-  text_issue_category_destroy_question: "×›×ž×” × ×•×©××™× (%{count}) ×ž×•×¦×‘×™× ×œ×§×˜×’×•×¨×™×” ×”×–×•. ×ž×” ×‘×¨×¦×•× ×š ×œ×¢×©×•×ª?"
-  text_issue_category_destroy_assignments: ×”×¡×¨ ×”×¦×‘×ª ×§×˜×’×•×¨×™×”
-  text_issue_category_reassign_to: ×”×¦×‘ ×ž×—×“×© ××ª ×”×§×˜×’×•×¨×™×” ×œ× ×•×©××™×
-  text_user_mail_option: "×‘×¤×¨×•×™×§×˜×™× ×©×œ× ×‘×—×¨×ª, ××ª×” ×¨×§ ×ª×§×‘×œ ×”×ª×¨×¢×•×ª ×¢×œ ×©××ª×” ×¦×•×¤×” ××• ×§×©×•×¨ ××œ×™×”× (×œ×“×•×’×ž×:× ×•×©××™× ×©××ª×” ×”×™×•×¦×¨ ×©×œ×”× ××• ××—×¨××™ ×¢×œ×™×”×)."
-  text_no_configuration_data: "×œ× ×”×•×’×“×¨×” ×ª×¦×•×¨×” ×¢×‘×•×¨ ×ª×¤×§×™×“×™×, ×¡×™×•×•×’×™×, ×ž×¦×‘×™ × ×•×©× ×•×–×¨×™×ž×ª ×¢×‘×•×“×”.\n×ž×•×ž×œ×¥ ×ž××“ ×œ×˜×¢×•×Ÿ ××ª ×ª×¦×•×¨×ª ×‘×¨×™×¨×ª ×”×ž×—×“×œ. ×ª×•×›×œ ×œ×©× ×•×ª×” ×ž××•×—×¨ ×™×•×ª×¨."
-  text_load_default_configuration: ×˜×¢×Ÿ ××ª ××¤×©×¨×•×™×•×ª ×‘×¨×™×¨×ª ×”×ž×—×“×œ
-  text_status_changed_by_changeset: "×”×•×—×œ ×‘×¡×“×¨×ª ×”×©×™× ×•×™×™× %{value}."
-  text_issues_destroy_confirmation: '×”×× ××ª×” ×‘×˜×•×— ×©×‘×¨×¦×•× ×š ×œ×ž×—×•×§ ××ª ×”× ×•×©××™×?'
-  text_select_project_modules: '×‘×—×¨ ×ž×•×“×•×œ×™× ×œ×”×—×™×œ ×¢×œ ×¤×¨×•×™×§×˜ ×–×”:'
-  text_default_administrator_account_changed: ×ž× ×”×œ ×”×ž×¢×¨×›×ª ×‘×¨×™×¨×ª ×”×ž×—×“×œ ×©×•× ×”
-  text_file_repository_writable: ×ž××’×¨ ×”×§×‘×¦×™× × ×™×ª×Ÿ ×œ×›×ª×™×‘×”
-  text_plugin_assets_writable: ×¡×¤×¨×™×ª × ×›×¡×™ ×ª×•×¡×¤×™× × ×™×ª× ×ª ×œ×›×ª×™×‘×”
-  text_rmagick_available: RMagick ×–×ž×™×Ÿ (×¨×©×•×ª)
-  text_destroy_time_entries_question: "%{hours} ×©×¢×•×ª ×“×•×•×—×• ×¢×œ ×”× ×•×©××™× ×©××ª×” ×¢×•×ž×“ ×œ×ž×—×•×§. ×ž×” ×‘×¨×¦×•× ×š ×œ×¢×©×•×ª?"
-  text_destroy_time_entries: ×ž×—×§ ×©×¢×•×ª ×©×“×•×•×—×•
-  text_assign_time_entries_to_project: ×”×¦×‘ ×©×¢×•×ª ×©×“×•×•×—×• ×œ×¤×¨×•×™×§×˜ ×”×–×”
-  text_reassign_time_entries: '×”×¦×‘ ×ž×—×“×© ×©×¢×•×ª ×©×“×•×•×—×• ×œ×¤×¨×•×™×§×˜ ×”×–×”:'
-  text_user_wrote: "%{value} ×›×ª×‘:"
-  text_enumeration_destroy_question: "%{count} ××•×‘×™×§×˜×™× ×ž×•×¦×‘×™× ×œ×¢×¨×š ×–×”."
-  text_enumeration_category_reassign_to: '×”×¦×‘ ×ž×—×“×© ×œ×¢×¨×š ×”×–×”:'
-  text_email_delivery_not_configured: '×œ× × ×§×‘×¢×” ×ª×¦×•×¨×” ×œ×©×œ×™×—×ª ×“×•××¨, ×•×”×”×ª×¨××•×ª ×›×‘×•×™×•×ª.\n×§×‘×¢ ××ª ×ª×¦×•×¨×ª ×©×¨×ª ×”Ö¾SMTP ×‘×§×•×‘×¥ /etc/redmine/&lt;instance&gt;/configuration.yml ×•×”×ª×—×œ ××ª ×”××¤×œ×™×§×¦×™×” ×ž×—×“×© ×¢"×ž ×œ××¤×©×¨ ××•×ª×.'
-  text_repository_usernames_mapping: "×‘×—×¨ ××• ×¢×“×›×Ÿ ××ª ×ž×©×ª×ž×© Redmine ×”×ž×ž×•×¤×” ×œ×›×œ ×©× ×ž×©×ª×ž×© ×‘×™×•×ž×Ÿ ×”×ž××’×¨.\n×ž×©×ª×ž×©×™× ×‘×¢×œ×™ ×©× ××• ×›×ª×•×‘×ª ×“×•××¨ ×–×”×” ×‘Ö¾Redmine ×•×‘×ž××’×¨ ×ž×ž×•×¤×™× ×‘××•×¤×Ÿ ××•×˜×•×ž×˜×™."
-  text_diff_truncated: '... ×”×©×™× ×•×™×™× ×¢×•×‘×¨×™× ××ª ×ž×¡×¤×¨ ×”×©×•×¨×•×ª ×”×ž×™×¨×‘×™ ×œ×ª×¦×•×’×”, ×•×œ×›×Ÿ ×”× ×§×•×¦×¦×•.'
-  text_custom_field_possible_values_info: ×©×•×¨×” ××—×ª ×œ×›×œ ×¢×¨×š
-  text_wiki_page_destroy_question: ×œ×“×£ ×–×” ×™×© %{descendants} ×“×¤×™× ×‘× ×™× ×•×ª×œ×•×™×™×. ×ž×” ×‘×¨×¦×•× ×š ×œ×¢×©×•×ª?
-  text_wiki_page_nullify_children: ×”×©××¨ ×“×¤×™× ×‘× ×™× ×›×“×¤×™× ×¨××©×™×™×
-  text_wiki_page_destroy_children: ×ž×—×§ ××ª ×”×“×¤×™× ×”×‘× ×™× ×•××ª ×›×œ ×”×ª×œ×•×™×™× ×‘×”×
-  text_wiki_page_reassign_children: ×”×¦×‘ ×ž×—×“×© ×“×¤×™× ×‘× ×™× ×œ×“×£ ×”××‘ ×”× ×•×›×—×™
-  text_own_membership_delete_confirmation: |-
-    ×‘×›×•×•× ×ª×š ×œ×ž×—×•×§ ×—×œ×§ ××• ××ª ×›×œ ×”×”×¨×©××•×ª ×©×œ×š. ×œ××—×¨ ×ž×›×Ÿ ×œ× ×ª×•×›×œ ×™×•×ª×¨ ×œ×¢×¨×•×š ×¤×¨×•×™×§×˜ ×–×”.
-    ×”×× ××ª×” ×‘×˜×•×— ×©×‘×¨×¦×•× ×š ×œ×”×ž×©×™×š?
-  text_zoom_in: ×”×ª×§×¨×‘
-  text_zoom_out: ×”×ª×¨×—×§
-
-  default_role_manager: ×ž× ×”×œ
-  default_role_developer: ×ž×¤×ª×—
-  default_role_reporter: ×ž×“×•×•×—
-  default_tracker_bug: ×ª×§×œ×”
-  default_tracker_feature: ×™×›×•×œ×ª
-  default_tracker_support: ×ª×ž×™×›×”
-  default_issue_status_new: ×—×“×©
-  default_issue_status_in_progress: ×‘×¢×‘×•×“×”
-  default_issue_status_resolved: × ×¤×ª×¨
-  default_issue_status_feedback: ×ž×©×•×‘
-  default_issue_status_closed: ×¡×’×•×¨
-  default_issue_status_rejected: × ×“×—×”
-  default_doc_category_user: ×ª×™×¢×•×“ ×ž×©×ª×ž×©
-  default_doc_category_tech: ×ª×™×¢×•×“ ×˜×›× ×™
-  default_priority_low: × ×ž×•×›×”
-  default_priority_normal: ×¨×’×™×œ×”
-  default_priority_high: ×’×‘×•×”×”
-  default_priority_urgent: ×“×—×•×¤×”
-  default_priority_immediate: ×ž×™×“×™×ª
-  default_activity_design: ×¢×™×¦×•×‘
-  default_activity_development: ×¤×™×ª×•×—
-
-  enumeration_issue_priorities: ×¢×“×™×¤×•×ª × ×•×©××™×
-  enumeration_doc_categories: ×§×˜×’×•×¨×™×•×ª ×ž×¡×ž×›×™×
-  enumeration_activities: ×¤×¢×™×œ×•×™×•×ª (×ž×¢×§×‘ ××—×¨ ×–×ž× ×™×)
-  enumeration_system_activity: ×¤×¢×™×œ×•×ª ×ž×¢×¨×›×ª
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: ×§×™×“×•×“ ×”×•×“×¢×•×ª ×”×¤×§×“×”
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/246272ecf77e9e146775d6173c7c910bea9ac736.svn-base
--- a/.svn/pristine/24/246272ecf77e9e146775d6173c7c910bea9ac736.svn-base
+++ /dev/null
@@ -1,95 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class ReportsController < ApplicationController
-  menu_item :issues
-  before_filter :find_project, :authorize, :find_issue_statuses
-
-  def issue_report
-    @trackers = @project.trackers
-    @versions = @project.shared_versions.sort
-    @priorities = IssuePriority.all
-    @categories = @project.issue_categories
-    @assignees = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
-    @authors = @project.users.sort
-    @subprojects = @project.descendants.visible
-
-    @issues_by_tracker = Issue.by_tracker(@project)
-    @issues_by_version = Issue.by_version(@project)
-    @issues_by_priority = Issue.by_priority(@project)
-    @issues_by_category = Issue.by_category(@project)
-    @issues_by_assigned_to = Issue.by_assigned_to(@project)
-    @issues_by_author = Issue.by_author(@project)
-    @issues_by_subproject = Issue.by_subproject(@project) || []
-
-    render :template => "reports/issue_report"
-  end
-
-  def issue_report_details
-    case params[:detail]
-    when "tracker"
-      @field = "tracker_id"
-      @rows = @project.trackers
-      @data = Issue.by_tracker(@project)
-      @report_title = l(:field_tracker)
-    when "version"
-      @field = "fixed_version_id"
-      @rows = @project.shared_versions.sort
-      @data = Issue.by_version(@project)
-      @report_title = l(:field_version)
-    when "priority"
-      @field = "priority_id"
-      @rows = IssuePriority.all
-      @data = Issue.by_priority(@project)
-      @report_title = l(:field_priority)
-    when "category"
-      @field = "category_id"
-      @rows = @project.issue_categories
-      @data = Issue.by_category(@project)
-      @report_title = l(:field_category)
-    when "assigned_to"
-      @field = "assigned_to_id"
-      @rows = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
-      @data = Issue.by_assigned_to(@project)
-      @report_title = l(:field_assigned_to)
-    when "author"
-      @field = "author_id"
-      @rows = @project.users.sort
-      @data = Issue.by_author(@project)
-      @report_title = l(:field_author)
-    when "subproject"
-      @field = "project_id"
-      @rows = @project.descendants.visible
-      @data = Issue.by_subproject(@project) || []
-      @report_title = l(:field_subproject)
-    end
-
-    respond_to do |format|
-      if @field
-        format.html {}
-      else
-        format.html { redirect_to :action => 'issue_report', :id => @project }
-      end
-    end
-  end
-
-  private
-
-  def find_issue_statuses
-    @statuses = IssueStatus.find(:all, :order => 'position')
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/246874006236597325557c0bf816ad53110aa1a7.svn-base
--- a/.svn/pristine/24/246874006236597325557c0bf816ad53110aa1a7.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class DocumentCategoryCustomField < CustomField
-  def type_name
-    :enumeration_doc_categories
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/2471e93efea942bf9d4041debddb77820f273e27.svn-base
--- a/.svn/pristine/24/2471e93efea942bf9d4041debddb77820f273e27.svn-base
+++ /dev/null
@@ -1,36 +0,0 @@
---- 
-journal_details_001: 
-  old_value: "1"
-  property: attr
-  id: 1
-  value: "2"
-  prop_key: status_id
-  journal_id: 1
-journal_details_002: 
-  old_value: "40"
-  property: attr
-  id: 2
-  value: "30"
-  prop_key: done_ratio
-  journal_id: 1
-journal_details_003:
-  old_value: nil
-  property: attr
-  id: 3
-  value: "6"
-  prop_key: fixed_version_id
-  journal_id: 4
-journal_details_004:
-  old_value: "This word was removed and an other was"
-  property: attr
-  id: 4
-  value: "This word was and an other was added"
-  prop_key: description
-  journal_id: 3
-journal_details_005:
-  old_value: Old value
-  property: cf
-  id: 5
-  value: New value
-  prop_key: 2
-  journal_id: 3
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/247b283cdc31d8c730597eba0ebe99d82df6440a.svn-base
--- /dev/null
+++ b/.svn/pristine/24/247b283cdc31d8c730597eba0ebe99d82df6440a.svn-base
@@ -0,0 +1,122 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class GanttsControllerTest < ActionController::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :versions
+
+  def test_gantt_should_work
+    i2 = Issue.find(2)
+    i2.update_attribute(:due_date, 1.month.from_now)
+    get :show, :project_id => 1
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_not_nil assigns(:gantt)
+    # Issue with start and due dates
+    i = Issue.find(1)
+    assert_not_nil i.due_date
+    assert_select "div a.issue", /##{i.id}/
+    # Issue with on a targeted version should not be in the events but loaded in the html
+    i = Issue.find(2)
+    assert_select "div a.issue", /##{i.id}/
+  end
+
+  def test_gantt_should_work_without_issue_due_dates
+    Issue.update_all("due_date = NULL")
+    get :show, :project_id => 1
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_not_nil assigns(:gantt)
+  end
+
+  def test_gantt_should_work_without_issue_and_version_due_dates
+    Issue.update_all("due_date = NULL")
+    Version.update_all("effective_date = NULL")
+    get :show, :project_id => 1
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_not_nil assigns(:gantt)
+  end
+
+  def test_gantt_should_work_cross_project
+    get :show
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_not_nil assigns(:gantt)
+    assert_not_nil assigns(:gantt).query
+    assert_nil assigns(:gantt).project
+  end
+
+  def test_gantt_should_not_disclose_private_projects
+    get :show
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_tag 'a', :content => /eCookbook/
+    # Root private project
+    assert_no_tag 'a', {:content => /OnlineStore/}
+    # Private children of a public project
+    assert_no_tag 'a', :content => /Private child of eCookbook/
+  end
+
+  def test_gantt_should_display_relations
+    IssueRelation.delete_all
+    issue1 = Issue.generate!(:start_date => 1.day.from_now, :due_date => 3.day.from_now)
+    issue2 = Issue.generate!(:start_date => 1.day.from_now, :due_date => 3.day.from_now)
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => 'precedes')
+
+    get :show
+    assert_response :success
+
+    relations = assigns(:gantt).relations
+    assert_kind_of Hash, relations
+    assert relations.present?
+    assert_select 'div.task_todo[id=?][data-rels*=?]', "task-todo-issue-#{issue1.id}", issue2.id.to_s
+    assert_select 'div.task_todo[id=?]:not([data-rels])', "task-todo-issue-#{issue2.id}"
+  end
+
+  def test_gantt_should_export_to_pdf
+    get :show, :project_id => 1, :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', @response.content_type
+    assert @response.body.starts_with?('%PDF')
+    assert_not_nil assigns(:gantt)
+  end
+
+  def test_gantt_should_export_to_pdf_cross_project
+    get :show, :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', @response.content_type
+    assert @response.body.starts_with?('%PDF')
+    assert_not_nil assigns(:gantt)
+  end
+
+  if Object.const_defined?(:Magick)
+    def test_gantt_should_export_to_png
+      get :show, :project_id => 1, :format => 'png'
+      assert_response :success
+      assert_equal 'image/png', @response.content_type
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/24b4bc532dbfbdbadb24d22bdcba74f2493b0b5a.svn-base
--- /dev/null
+++ b/.svn/pristine/24/24b4bc532dbfbdbadb24d22bdcba74f2493b0b5a.svn-base
@@ -0,0 +1,119 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingVersionsTest < ActionController::IntegrationTest
+  def test_roadmap
+    # /projects/foo/versions is /projects/foo/roadmap
+    assert_routing(
+        { :method => 'get', :path => "/projects/33/roadmap" },
+        { :controller => 'versions', :action => 'index', :project_id => '33' }
+      )
+  end
+
+  def test_versions_scoped_under_project
+    assert_routing(
+        { :method => 'put', :path => "/projects/foo/versions/close_completed" },
+        { :controller => 'versions', :action => 'close_completed',
+          :project_id => 'foo' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/foo/versions.xml" },
+        { :controller => 'versions', :action => 'index',
+          :project_id => 'foo', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/foo/versions.json" },
+        { :controller => 'versions', :action => 'index',
+          :project_id => 'foo', :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/foo/versions/new" },
+        { :controller => 'versions', :action => 'new',
+          :project_id => 'foo' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/foo/versions" },
+        { :controller => 'versions', :action => 'create',
+          :project_id => 'foo' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/foo/versions.xml" },
+        { :controller => 'versions', :action => 'create',
+          :project_id => 'foo', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/foo/versions.json" },
+        { :controller => 'versions', :action => 'create',
+          :project_id => 'foo', :format => 'json' }
+      )
+  end
+
+  def test_versions
+    assert_routing(
+        { :method => 'get', :path => "/versions/1" },
+        { :controller => 'versions', :action => 'show', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/versions/1.xml" },
+        { :controller => 'versions', :action => 'show', :id => '1',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/versions/1.json" },
+        { :controller => 'versions', :action => 'show', :id => '1',
+          :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/versions/1/edit" },
+        { :controller => 'versions', :action => 'edit', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/versions/1" },
+        { :controller => 'versions', :action => 'update', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/versions/1.xml" },
+        { :controller => 'versions', :action => 'update', :id => '1',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/versions/1.json" },
+        { :controller => 'versions', :action => 'update', :id => '1',
+          :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/versions/1" },
+        { :controller => 'versions', :action => 'destroy', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/versions/1.xml" },
+        { :controller => 'versions', :action => 'destroy', :id => '1',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/versions/1.json" },
+        { :controller => 'versions', :action => 'destroy', :id => '1',
+          :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/versions/1/status_by" },
+        { :controller => 'versions', :action => 'status_by', :id => '1' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/24c62162ea3371ca1be4a955c3f0b6fc0dac2c81.svn-base
--- /dev/null
+++ b/.svn/pristine/24/24c62162ea3371ca1be4a955c3f0b6fc0dac2c81.svn-base
@@ -0,0 +1,167 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AdminControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :roles
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 1 # admin
+  end
+
+  def test_index
+    get :index
+    assert_select 'div.nodata', 0
+  end
+
+  def test_index_with_no_configuration_data
+    delete_configuration_data
+    get :index
+    assert_select 'div.nodata'
+  end
+
+  def test_projects
+    get :projects
+    assert_response :success
+    assert_template 'projects'
+    assert_not_nil assigns(:projects)
+    # active projects only
+    assert_nil assigns(:projects).detect {|u| !u.active?}
+  end
+
+  def test_projects_with_status_filter
+    get :projects, :status => 1
+    assert_response :success
+    assert_template 'projects'
+    assert_not_nil assigns(:projects)
+    # active projects only
+    assert_nil assigns(:projects).detect {|u| !u.active?}
+  end
+
+  def test_projects_with_name_filter
+    get :projects, :name => 'store', :status => ''
+    assert_response :success
+    assert_template 'projects'
+    projects = assigns(:projects)
+    assert_not_nil projects
+    assert_equal 1, projects.size
+    assert_equal 'OnlineStore', projects.first.name
+  end
+
+  def test_load_default_configuration_data
+    delete_configuration_data
+    post :default_configuration, :lang => 'fr'
+    assert_response :redirect
+    assert_nil flash[:error]
+    assert IssueStatus.find_by_name('Nouveau')
+  end
+
+  def test_load_default_configuration_data_should_rescue_error
+    delete_configuration_data
+    Redmine::DefaultData::Loader.stubs(:load).raises(Exception.new("Something went wrong"))
+    post :default_configuration, :lang => 'fr'
+    assert_response :redirect
+    assert_not_nil flash[:error]
+    assert_match /Something went wrong/, flash[:error]
+  end
+
+  def test_test_email
+    user = User.find(1)
+    user.pref[:no_self_notified] = '1'
+    user.pref.save!
+    ActionMailer::Base.deliveries.clear
+
+    get :test_email
+    assert_redirected_to '/settings?tab=notifications'
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    user = User.find(1)
+    assert_equal [user.mail], mail.bcc
+  end
+
+  def test_test_email_failure_should_display_the_error
+    Mailer.stubs(:test_email).raises(Exception, 'Some error message')
+    get :test_email
+    assert_redirected_to '/settings?tab=notifications'
+    assert_match /Some error message/, flash[:error]
+  end
+
+  def test_no_plugins
+    Redmine::Plugin.clear
+
+    get :plugins
+    assert_response :success
+    assert_template 'plugins'
+  end
+
+  def test_plugins
+    # Register a few plugins
+    Redmine::Plugin.register :foo do
+      name 'Foo plugin'
+      author 'John Smith'
+      description 'This is a test plugin'
+      version '0.0.1'
+      settings :default => {'sample_setting' => 'value', 'foo'=>'bar'}, :partial => 'foo/settings'
+    end
+    Redmine::Plugin.register :bar do
+    end
+
+    get :plugins
+    assert_response :success
+    assert_template 'plugins'
+
+    assert_select 'tr#plugin-foo' do
+      assert_select 'td span.name', :text => 'Foo plugin'
+      assert_select 'td.configure a[href=/settings/plugin/foo]'
+    end
+    assert_select 'tr#plugin-bar' do
+      assert_select 'td span.name', :text => 'Bar'
+      assert_select 'td.configure a', 0
+    end
+  end
+
+  def test_info
+    get :info
+    assert_response :success
+    assert_template 'info'
+  end
+
+  def test_admin_menu_plugin_extension
+    Redmine::MenuManager.map :admin_menu do |menu|
+      menu.push :test_admin_menu_plugin_extension, '/foo/bar', :caption => 'Test'
+    end
+
+    get :index
+    assert_response :success
+    assert_select 'div#admin-menu a[href=/foo/bar]', :text => 'Test'
+
+    Redmine::MenuManager.map :admin_menu do |menu|
+      menu.delete :test_admin_menu_plugin_extension
+    end
+  end
+
+  private
+
+  def delete_configuration_data
+    Role.delete_all('builtin = 0')
+    Tracker.delete_all
+    IssueStatus.delete_all
+    Enumeration.delete_all
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/24ebd90070f1307a8f6d2f2f35671e06e60bb2b7.svn-base
--- /dev/null
+++ b/.svn/pristine/24/24ebd90070f1307a8f6d2f2f35671e06e60bb2b7.svn-base
@@ -0,0 +1,184 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class MessageTest < ActiveSupport::TestCase
+  fixtures :projects, :roles, :members, :member_roles, :boards, :messages,
+           :users, :watchers, :enabled_modules
+
+  def setup
+    @board = Board.find(1)
+    @user = User.find(1)
+  end
+
+  def test_create
+    topics_count = @board.topics_count
+    messages_count = @board.messages_count
+
+    message = Message.new(:board => @board, :subject => 'Test message',
+                          :content => 'Test message content',
+                          :author => @user)
+    assert message.save
+    @board.reload
+    # topics count incremented
+    assert_equal topics_count + 1, @board[:topics_count]
+    # messages count incremented
+    assert_equal messages_count + 1, @board[:messages_count]
+    assert_equal message, @board.last_message
+    # author should be watching the message
+    assert message.watched_by?(@user)
+  end
+
+  def test_reply
+    topics_count = @board.topics_count
+    messages_count = @board.messages_count
+    message = Message.find(1)
+    replies_count = message.replies_count
+
+    reply_author = User.find(2)
+    reply = Message.new(:board => @board, :subject => 'Test reply',
+                        :content => 'Test reply content',
+                        :parent => message, :author => reply_author)
+    assert reply.save
+    @board.reload
+    # same topics count
+    assert_equal topics_count, @board[:topics_count]
+    # messages count incremented
+    assert_equal messages_count+1, @board[:messages_count]
+    assert_equal reply, @board.last_message
+    message.reload
+    # replies count incremented
+    assert_equal replies_count+1, message[:replies_count]
+    assert_equal reply, message.last_reply
+    # author should be watching the message
+    assert message.watched_by?(reply_author)
+  end
+
+  def test_cannot_reply_to_locked_topic
+    topics_count = @board.topics_count
+    messages_count = @board.messages_count
+    message = Message.find(1)
+    replies_count = message.replies_count
+    assert_equal false, message.locked
+    message.locked = true
+    assert message.save
+    assert_equal true, message.locked
+
+    reply_author = User.find(2)
+    reply = Message.new(:board => @board, :subject => 'Test reply',
+                        :content => 'Test reply content',
+                        :parent => message, :author => reply_author)
+    reply.save
+    assert_equal 1, reply.errors.count
+  end
+
+  def test_moving_message_should_update_counters
+    message = Message.find(1)
+    assert_no_difference 'Message.count' do
+      # Previous board
+      assert_difference 'Board.find(1).topics_count', -1 do
+        assert_difference 'Board.find(1).messages_count', -(1 + message.replies_count) do
+          # New board
+          assert_difference 'Board.find(2).topics_count' do
+            assert_difference 'Board.find(2).messages_count', (1 + message.replies_count) do
+              message.update_attributes(:board_id => 2)
+            end
+          end
+        end
+      end
+    end
+  end
+
+  def test_destroy_topic
+    message = Message.find(1)
+    board = message.board
+    topics_count, messages_count = board.topics_count, board.messages_count
+
+    assert_difference('Watcher.count', -1) do
+      assert message.destroy
+    end
+    board.reload
+
+    # Replies deleted
+    assert Message.find_all_by_parent_id(1).empty?
+    # Checks counters
+    assert_equal topics_count - 1, board.topics_count
+    assert_equal messages_count - 3, board.messages_count
+    # Watchers removed
+  end
+
+  def test_destroy_reply
+    message = Message.find(5)
+    board = message.board
+    topics_count, messages_count = board.topics_count, board.messages_count
+    assert message.destroy
+    board.reload
+
+    # Checks counters
+    assert_equal topics_count, board.topics_count
+    assert_equal messages_count - 1, board.messages_count
+  end
+
+  def test_destroying_last_reply_should_update_topic_last_reply_id
+    topic = Message.find(4)
+    assert_equal 6, topic.last_reply_id
+
+    assert_difference 'Message.count', -1 do
+      Message.find(6).destroy
+    end
+    assert_equal 5, topic.reload.last_reply_id
+
+    assert_difference 'Message.count', -1 do
+      Message.find(5).destroy
+    end
+    assert_nil topic.reload.last_reply_id
+  end
+
+  def test_editable_by
+    message = Message.find(6)
+    author = message.author
+    assert message.editable_by?(author)
+
+    author.roles_for_project(message.project).first.remove_permission!(:edit_own_messages)
+    assert !message.reload.editable_by?(author.reload)
+  end
+
+  def test_destroyable_by
+    message = Message.find(6)
+    author = message.author
+    assert message.destroyable_by?(author)
+
+    author.roles_for_project(message.project).first.remove_permission!(:delete_own_messages)
+    assert !message.reload.destroyable_by?(author.reload)
+  end
+
+  def test_set_sticky
+    message = Message.new
+    assert_equal 0, message.sticky
+    message.sticky = nil
+    assert_equal 0, message.sticky
+    message.sticky = false
+    assert_equal 0, message.sticky
+    message.sticky = true
+    assert_equal 1, message.sticky
+    message.sticky = '0'
+    assert_equal 0, message.sticky
+    message.sticky = '1'
+    assert_equal 1, message.sticky
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/24/24f7f0414301f421feaefeee3ae3bf564c315361.svn-base
--- a/.svn/pristine/24/24f7f0414301f421feaefeee3ae3bf564c315361.svn-base
+++ /dev/null
@@ -1,217 +0,0 @@
-# encoding: utf-8
-module CodeRay
-  module Scanners
-    
-    # Clojure scanner by Licenser.
-    class Clojure < Scanner
-      
-      register_for :clojure
-      file_extension 'clj'
-      
-      SPECIAL_FORMS = %w[
-        def if do let quote var fn loop recur throw try catch monitor-enter monitor-exit .
-        new 
-      ]  # :nodoc:
-      
-      CORE_FORMS = %w[
-        + - -> ->> .. / * <= < = == >= > accessor aclone add-classpath add-watch
-        agent agent-error agent-errors aget alength alias all-ns alter alter-meta!
-        alter-var-root amap ancestors and apply areduce array-map aset aset-boolean
-        aset-byte aset-char aset-double aset-float aset-int aset-long aset-short
-        assert assoc assoc! assoc-in associative? atom await await-for bases bean
-        bigdec bigint binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or
-        bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array
-        booleans bound-fn bound-fn* bound? butlast byte byte-array bytes case cast char
-        char-array char-escape-string char-name-string char? chars class class?
-        clear-agent-errors clojure-version coll? comment commute comp comparator
-        compare compare-and-set! compile complement concat cond condp conj conj!
-        cons constantly construct-proxy contains? count counted? create-ns
-        create-struct cycle dec decimal? declare definline defmacro defmethod defmulti
-        defn defn- defonce defprotocol defrecord defstruct deftype delay delay?
-        deliver denominator deref derive descendants disj disj! dissoc dissoc!
-        distinct distinct? doall doc dorun doseq dosync dotimes doto double
-        double-array doubles drop drop-last drop-while empty empty? ensure
-        enumeration-seq error-handler error-mode eval even? every? extend
-        extend-protocol extend-type extenders extends? false? ffirst file-seq
-        filter find find-doc find-ns find-var first float float-array float?
-        floats flush fn fn? fnext for force format future future-call future-cancel
-        future-cancelled? future-done? future? gen-class gen-interface gensym get
-        get-in get-method get-proxy-class get-thread-bindings get-validator hash
-        hash-map hash-set identical? identity if-let if-not ifn? import in-ns
-        inc init-proxy instance? int int-array integer? interleave intern
-        interpose into into-array ints io! isa? iterate iterator-seq juxt key
-        keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list*
-        list? load load-file load-reader load-string loaded-libs locking long
-        long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy
-        map map? mapcat max max-key memfn memoize merge merge-with meta methods
-        min min-key mod name namespace neg? newline next nfirst nil? nnext not
-        not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns
-        ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth
-        nthnext num number? numerator object-array odd? or parents partial
-        partition pcalls peek persistent! pmap pop pop! pop-thread-bindings
-        pos? pr pr-str prefer-method prefers print print-namespace-doc
-        print-str printf println println-str prn prn-str promise proxy
-        proxy-mappings proxy-super push-thread-bindings pvalues quot rand
-        rand-int range ratio? rationalize re-find re-groups re-matcher
-        re-matches re-pattern re-seq read read-line read-string reduce ref
-        ref-history-count ref-max-history ref-min-history ref-set refer
-        refer-clojure reify release-pending-sends rem remove remove-all-methods
-        remove-method remove-ns remove-watch repeat repeatedly replace replicate
-        require reset! reset-meta! resolve rest restart-agent resultset-seq
-        reverse reversible? rseq rsubseq satisfies? second select-keys send
-        send-off seq seq? seque sequence sequential? set set-error-handler!
-        set-error-mode! set-validator! set? short short-array shorts
-        shutdown-agents slurp some sort sort-by sorted-map sorted-map-by
-        sorted-set sorted-set-by sorted? special-form-anchor special-symbol?
-        split-at split-with str string? struct struct-map subs subseq subvec
-        supers swap! symbol symbol? sync syntax-symbol-anchor take take-last
-        take-nth take-while test the-ns thread-bound? time to-array to-array-2d
-        trampoline transient tree-seq true? type unchecked-add unchecked-dec
-        unchecked-divide unchecked-inc unchecked-multiply unchecked-negate
-        unchecked-remainder unchecked-subtract underive update-in update-proxy
-        use val vals var-get var-set var? vary-meta vec vector vector-of vector?
-        when when-first when-let when-not while with-bindings with-bindings*
-        with-in-str with-local-vars with-meta with-open with-out-str
-        with-precision xml-seq zero? zipmap 
-      ]  # :nodoc:
-      
-      PREDEFINED_CONSTANTS = %w[
-        true false nil *1 *2 *3 *agent* *clojure-version* *command-line-args*
-        *compile-files* *compile-path* *e *err* *file* *flush-on-newline*
-        *in* *ns* *out* *print-dup* *print-length* *print-level* *print-meta*
-        *print-readably* *read-eval* *warn-on-reflection*
-      ]  # :nodoc:
-      
-      IDENT_KIND = WordList.new(:ident).
-        add(SPECIAL_FORMS, :keyword).
-        add(CORE_FORMS, :keyword).
-        add(PREDEFINED_CONSTANTS, :predefined_constant)
-      
-      KEYWORD_NEXT_TOKEN_KIND = WordList.new(nil).
-        add(%w[ def defn defn- definline defmacro defmulti defmethod defstruct defonce declare ], :function).
-        add(%w[ ns ], :namespace).
-        add(%w[ defprotocol defrecord ], :class)
-      
-      BASIC_IDENTIFIER = /[a-zA-Z$%*\/_+!?&<>\-=]=?[a-zA-Z0-9$&*+!\/_?<>\-\#]*/
-      IDENTIFIER = /(?!-\d)(?:(?:#{BASIC_IDENTIFIER}\.)*#{BASIC_IDENTIFIER}(?:\/#{BASIC_IDENTIFIER})?\.?)|\.\.?/
-      SYMBOL = /::?#{IDENTIFIER}/o
-      DIGIT = /\d/
-      DIGIT10 = DIGIT
-      DIGIT16 = /[0-9a-f]/i
-      DIGIT8 = /[0-7]/
-      DIGIT2 = /[01]/
-      RADIX16 = /\#x/i
-      RADIX8 = /\#o/i
-      RADIX2 = /\#b/i
-      RADIX10 = /\#d/i
-      EXACTNESS = /#i|#e/i
-      SIGN = /[\+-]?/
-      EXP_MARK = /[esfdl]/i
-      EXP = /#{EXP_MARK}#{SIGN}#{DIGIT}+/
-      SUFFIX = /#{EXP}?/
-      PREFIX10 = /#{RADIX10}?#{EXACTNESS}?|#{EXACTNESS}?#{RADIX10}?/
-      PREFIX16 = /#{RADIX16}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX16}/
-      PREFIX8 = /#{RADIX8}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX8}/
-      PREFIX2 = /#{RADIX2}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX2}/
-      UINT10 = /#{DIGIT10}+#*/
-      UINT16 = /#{DIGIT16}+#*/
-      UINT8 = /#{DIGIT8}+#*/
-      UINT2 = /#{DIGIT2}+#*/
-      DECIMAL = /#{DIGIT10}+#+\.#*#{SUFFIX}|#{DIGIT10}+\.#{DIGIT10}*#*#{SUFFIX}|\.#{DIGIT10}+#*#{SUFFIX}|#{UINT10}#{EXP}/
-      UREAL10 = /#{UINT10}\/#{UINT10}|#{DECIMAL}|#{UINT10}/
-      UREAL16 = /#{UINT16}\/#{UINT16}|#{UINT16}/
-      UREAL8 = /#{UINT8}\/#{UINT8}|#{UINT8}/
-      UREAL2 = /#{UINT2}\/#{UINT2}|#{UINT2}/
-      REAL10 = /#{SIGN}#{UREAL10}/
-      REAL16 = /#{SIGN}#{UREAL16}/
-      REAL8 = /#{SIGN}#{UREAL8}/
-      REAL2 = /#{SIGN}#{UREAL2}/
-      IMAG10 = /i|#{UREAL10}i/
-      IMAG16 = /i|#{UREAL16}i/
-      IMAG8 = /i|#{UREAL8}i/
-      IMAG2 = /i|#{UREAL2}i/
-      COMPLEX10 = /#{REAL10}@#{REAL10}|#{REAL10}\+#{IMAG10}|#{REAL10}-#{IMAG10}|\+#{IMAG10}|-#{IMAG10}|#{REAL10}/
-      COMPLEX16 = /#{REAL16}@#{REAL16}|#{REAL16}\+#{IMAG16}|#{REAL16}-#{IMAG16}|\+#{IMAG16}|-#{IMAG16}|#{REAL16}/
-      COMPLEX8 = /#{REAL8}@#{REAL8}|#{REAL8}\+#{IMAG8}|#{REAL8}-#{IMAG8}|\+#{IMAG8}|-#{IMAG8}|#{REAL8}/
-      COMPLEX2 = /#{REAL2}@#{REAL2}|#{REAL2}\+#{IMAG2}|#{REAL2}-#{IMAG2}|\+#{IMAG2}|-#{IMAG2}|#{REAL2}/
-      NUM10 = /#{PREFIX10}?#{COMPLEX10}/
-      NUM16 = /#{PREFIX16}#{COMPLEX16}/
-      NUM8 = /#{PREFIX8}#{COMPLEX8}/
-      NUM2 = /#{PREFIX2}#{COMPLEX2}/
-      NUM = /#{NUM10}|#{NUM16}|#{NUM8}|#{NUM2}/
-      
-    protected
-      
-      def scan_tokens encoder, options
-        
-        state = :initial
-        kind = nil
-        
-        until eos?
-          
-          case state
-          when :initial
-            if match = scan(/ \s+ | \\\n | , /x)
-              encoder.text_token match, :space
-            elsif match = scan(/['`\(\[\)\]\{\}]|\#[({]|~@?|[@\^]/)
-              encoder.text_token match, :operator
-            elsif match = scan(/;.*/)
-              encoder.text_token match, :comment  # TODO: recognize (comment ...) too
-            elsif match = scan(/\#?\\(?:newline|space|.?)/)
-              encoder.text_token match, :char
-            elsif match = scan(/\#[ft]/)
-              encoder.text_token match, :predefined_constant
-            elsif match = scan(/#{IDENTIFIER}/o)
-              kind = IDENT_KIND[match]
-              encoder.text_token match, kind
-              if rest? && kind == :keyword
-                if kind = KEYWORD_NEXT_TOKEN_KIND[match]
-                  encoder.text_token match, :space if match = scan(/\s+/o)
-                  encoder.text_token match, kind if match = scan(/#{IDENTIFIER}/o)
-                end
-              end
-            elsif match = scan(/#{SYMBOL}/o)
-              encoder.text_token match, :symbol
-            elsif match = scan(/\./)
-              encoder.text_token match, :operator
-            elsif match = scan(/ \# \^ #{IDENTIFIER} /ox)
-              encoder.text_token match, :type
-            elsif match = scan(/ (\#)? " /x)
-              state = self[1] ? :regexp : :string
-              encoder.begin_group state
-              encoder.text_token match, :delimiter
-            elsif match = scan(/#{NUM}/o) and not matched.empty?
-              encoder.text_token match, match[/[.e\/]/i] ? :float : :integer
-            else
-              encoder.text_token getch, :error
-            end
-            
-          when :string, :regexp
-            if match = scan(/[^"\\]+|\\.?/)
-              encoder.text_token match, :content
-            elsif match = scan(/"/)
-              encoder.text_token match, :delimiter
-              encoder.end_group state
-              state = :initial
-            else
-              raise_inspect "else case \" reached; %p not handled." % peek(1),
-                encoder, state
-            end
-            
-          else
-            raise 'else case reached'
-            
-          end
-          
-        end
-        
-        if [:string, :regexp].include? state
-          encoder.end_group state
-        end
-        
-        encoder
-        
-      end
-    end
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/25/25113ec5e4b14337a78af5200fc4c9451ad1548e.svn-base
--- a/.svn/pristine/25/25113ec5e4b14337a78af5200fc4c9451ad1548e.svn-base
+++ /dev/null
@@ -1,39 +0,0 @@
-<% @entries.each do |entry| %>
-<% tr_id = Digest::MD5.hexdigest(entry.path)
-   depth = params[:depth].to_i %>
-<%  ent_path = Redmine::CodesetUtil.replace_invalid_utf8(entry.path)   %>
-<%  ent_name = Redmine::CodesetUtil.replace_invalid_utf8(entry.name)   %>
-<tr id="<%= tr_id %>" class="<%= h params[:parent_id] %> entry <%= entry.kind %>">
-<td style="padding-left: <%=18 * depth%>px;" class="<%=
-           @repository.report_last_commit ? "filename" : "filename_no_report" %>";>
-<% if entry.is_dir? %>
-<span class="expander" onclick="<%= remote_function(
-                  :url => {
-                       :action => 'show',
-                       :id     => @project,
-                       :path   => to_path_param(ent_path),
-                       :rev    => @rev,
-                       :depth  => (depth + 1),
-                       :parent_id => tr_id
-                         },
-                  :method => :get,
-                  :update => { :success => tr_id },
-                  :position => :after,
-                  :success => "scmEntryLoaded('#{tr_id}')",
-                  :condition => "scmEntryClick('#{tr_id}')"
-                ) %>">&nbsp</span>
-<% end %>
-<%=  link_to h(ent_name),
-          {:action => (entry.is_dir? ? 'show' : 'changes'), :id => @project, :path => to_path_param(ent_path), :rev => @rev},
-          :class => (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%>
-</td>
-<td class="size"><%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>
-<% changeset = @project.repository.find_changeset_by_name(entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %>
-<% if @repository.report_last_commit %>
-<td class="revision"><%= link_to_revision(changeset, @project) if changeset %></td>
-<td class="age"><%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %></td>
-<td class="author"><%= changeset.nil? ? h(Redmine::CodesetUtil.replace_invalid_utf8(entry.lastrev.author.to_s.split('<').first)) : h(changeset.author) if entry.lastrev %></td>
-<td class="comments"><%=h truncate(changeset.comments, :length => 50) unless changeset.nil? %></td>
-<% end %>
-</tr>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/25/252339adc97bdbe7fac1c5b16dba024f1d817a65.svn-base
--- /dev/null
+++ b/.svn/pristine/25/252339adc97bdbe7fac1c5b16dba024f1d817a65.svn-base
@@ -0,0 +1,290 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class QueriesControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :queries, :enabled_modules
+
+  def setup
+    User.current = nil
+  end
+
+  def test_index
+    get :index
+    # HTML response not implemented
+    assert_response 406
+  end
+
+  def test_new_project_query
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'query[is_public]',
+                                                 :checked => nil }
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'query_is_for_all',
+                                                 :checked => nil,
+                                                 :disabled => nil }
+    assert_select 'select[name=?]', 'c[]' do
+      assert_select 'option[value=tracker]'
+      assert_select 'option[value=subject]'
+    end
+  end
+
+  def test_new_global_query
+    @request.session[:user_id] = 2
+    get :new
+    assert_response :success
+    assert_template 'new'
+    assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                    :name => 'query[is_public]' }
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'query_is_for_all',
+                                                 :checked => 'checked',
+                                                 :disabled => nil }
+  end
+
+  def test_new_on_invalid_project
+    @request.session[:user_id] = 2
+    get :new, :project_id => 'invalid'
+    assert_response 404
+  end
+
+  def test_create_project_public_query
+    @request.session[:user_id] = 2
+    post :create,
+         :project_id => 'ecookbook',
+         :default_columns => '1',
+         :f => ["status_id", "assigned_to_id"],
+         :op => {"assigned_to_id" => "=", "status_id" => "o"},
+         :v => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
+         :query => {"name" => "test_new_project_public_query", "is_public" => "1"}
+
+    q = Query.find_by_name('test_new_project_public_query')
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
+    assert q.is_public?
+    assert q.has_default_columns?
+    assert q.valid?
+  end
+
+  def test_create_project_private_query
+    @request.session[:user_id] = 3
+    post :create,
+         :project_id => 'ecookbook',
+         :default_columns => '1',
+         :fields => ["status_id", "assigned_to_id"],
+         :operators => {"assigned_to_id" => "=", "status_id" => "o"},
+         :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
+         :query => {"name" => "test_new_project_private_query", "is_public" => "1"}
+
+    q = Query.find_by_name('test_new_project_private_query')
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
+    assert !q.is_public?
+    assert q.has_default_columns?
+    assert q.valid?
+  end
+
+  def test_create_global_private_query_with_custom_columns
+    @request.session[:user_id] = 3
+    post :create,
+         :fields => ["status_id", "assigned_to_id"],
+         :operators => {"assigned_to_id" => "=", "status_id" => "o"},
+         :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
+         :query => {"name" => "test_new_global_private_query", "is_public" => "1"},
+         :c => ["", "tracker", "subject", "priority", "category"]
+
+    q = Query.find_by_name('test_new_global_private_query')
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
+    assert !q.is_public?
+    assert !q.has_default_columns?
+    assert_equal [:id, :tracker, :subject, :priority, :category], q.columns.collect {|c| c.name}
+    assert q.valid?
+  end
+
+  def test_create_global_query_with_custom_filters
+    @request.session[:user_id] = 3
+    post :create,
+         :fields => ["assigned_to_id"],
+         :operators => {"assigned_to_id" => "="},
+         :values => { "assigned_to_id" => ["me"]},
+         :query => {"name" => "test_new_global_query"}
+
+    q = Query.find_by_name('test_new_global_query')
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
+    assert !q.has_filter?(:status_id)
+    assert_equal ['assigned_to_id'], q.filters.keys
+    assert q.valid?
+  end
+
+  def test_create_with_sort
+    @request.session[:user_id] = 1
+    post :create,
+         :default_columns => '1',
+         :operators => {"status_id" => "o"},
+         :values => {"status_id" => ["1"]},
+         :query => {:name => "test_new_with_sort",
+                    :is_public => "1",
+                    :sort_criteria => {"0" => ["due_date", "desc"], "1" => ["tracker", ""]}}
+
+    query = Query.find_by_name("test_new_with_sort")
+    assert_not_nil query
+    assert_equal [['due_date', 'desc'], ['tracker', 'asc']], query.sort_criteria
+  end
+
+  def test_create_with_failure
+    @request.session[:user_id] = 2
+    assert_no_difference '::Query.count' do
+      post :create, :project_id => 'ecookbook', :query => {:name => ''}
+    end
+    assert_response :success
+    assert_template 'new'
+    assert_select 'input[name=?]', 'query[name]'
+  end
+
+  def test_edit_global_public_query
+    @request.session[:user_id] = 1
+    get :edit, :id => 4
+    assert_response :success
+    assert_template 'edit'
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'query[is_public]',
+                                                 :checked => 'checked' }
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'query_is_for_all',
+                                                 :checked => 'checked',
+                                                 :disabled => 'disabled' }
+  end
+
+  def test_edit_global_private_query
+    @request.session[:user_id] = 3
+    get :edit, :id => 3
+    assert_response :success
+    assert_template 'edit'
+    assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                    :name => 'query[is_public]' }
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'query_is_for_all',
+                                                 :checked => 'checked',
+                                                 :disabled => 'disabled' }
+  end
+
+  def test_edit_project_private_query
+    @request.session[:user_id] = 3
+    get :edit, :id => 2
+    assert_response :success
+    assert_template 'edit'
+    assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                    :name => 'query[is_public]' }
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'query_is_for_all',
+                                                 :checked => nil,
+                                                 :disabled => nil }
+  end
+
+  def test_edit_project_public_query
+    @request.session[:user_id] = 2
+    get :edit, :id => 1
+    assert_response :success
+    assert_template 'edit'
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'query[is_public]',
+                                                 :checked => 'checked'
+                                                  }
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'query_is_for_all',
+                                                 :checked => nil,
+                                                 :disabled => 'disabled' }
+  end
+
+  def test_edit_sort_criteria
+    @request.session[:user_id] = 1
+    get :edit, :id => 5
+    assert_response :success
+    assert_template 'edit'
+    assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' },
+                                 :child => { :tag => 'option', :attributes => { :value => 'priority',
+                                                                                :selected => 'selected' } }
+    assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' },
+                                 :child => { :tag => 'option', :attributes => { :value => 'desc',
+                                                                                :selected => 'selected' } }
+  end
+
+  def test_edit_invalid_query
+    @request.session[:user_id] = 2
+    get :edit, :id => 99
+    assert_response 404
+  end
+
+  def test_udpate_global_private_query
+    @request.session[:user_id] = 3
+    put :update,
+         :id => 3,
+         :default_columns => '1',
+         :fields => ["status_id", "assigned_to_id"],
+         :operators => {"assigned_to_id" => "=", "status_id" => "o"},
+         :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
+         :query => {"name" => "test_edit_global_private_query", "is_public" => "1"}
+
+    assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 3
+    q = Query.find_by_name('test_edit_global_private_query')
+    assert !q.is_public?
+    assert q.has_default_columns?
+    assert q.valid?
+  end
+
+  def test_update_global_public_query
+    @request.session[:user_id] = 1
+    put :update,
+         :id => 4,
+         :default_columns => '1',
+         :fields => ["status_id", "assigned_to_id"],
+         :operators => {"assigned_to_id" => "=", "status_id" => "o"},
+         :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
+         :query => {"name" => "test_edit_global_public_query", "is_public" => "1"}
+
+    assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 4
+    q = Query.find_by_name('test_edit_global_public_query')
+    assert q.is_public?
+    assert q.has_default_columns?
+    assert q.valid?
+  end
+
+  def test_update_with_failure
+    @request.session[:user_id] = 1
+    put :update, :id => 4, :query => {:name => ''}
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_destroy
+    @request.session[:user_id] = 2
+    delete :destroy, :id => 1
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :set_filter => 1, :query_id => nil
+    assert_nil Query.find_by_id(1)
+  end
+
+  def test_backslash_should_be_escaped_in_filters
+    @request.session[:user_id] = 2
+    get :new, :subject => 'foo/bar'
+    assert_response :success
+    assert_template 'new'
+    assert_include 'addFilter("subject", "=", ["foo\/bar"]);', response.body
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/25/25a75439387b5e7c9157d74c8baba2d41c8319c0.svn-base
--- /dev/null
+++ b/.svn/pristine/25/25a75439387b5e7c9157d74c8baba2d41c8319c0.svn-base
@@ -0,0 +1,48 @@
+<div class="contextual">
+<%= link_to l(:button_log_time), 
+            {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue},
+            :class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project, :global => true) %>
+</div>
+
+<%= render_timelog_breadcrumb %>
+
+<h2><%= l(:label_spent_time) %></h2>
+
+<%= form_tag({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %>
+<%= render :partial => 'date_range' %>
+<% end %>
+
+<div class="total-hours">
+<p><%= l(:label_total_time) %>: <%= html_hours(l_hours(@total_hours)) %></p>
+</div>
+
+<% unless @entries.empty? %>
+<%= render :partial => 'list', :locals => { :entries => @entries }%>
+<p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
+
+<% other_formats_links do |f| %>
+  <%= f.link_to 'Atom', :url => params.merge({:issue_id => @issue, :key => User.current.rss_key}) %>
+  <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
+<% end %>
+
+<div id="csv-export-options" style="display:none;">
+  <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
+  <%= form_tag(params.slice(:project_id, :issue_id).merge(:format => 'csv', :page=>nil), :method => :get, :id => 'csv-export-form') do %>
+  <%= query_hidden_tags @query %>
+  <p>
+    <label><%= radio_button_tag 'columns', '', true %> <%= l(:description_selected_columns) %></label><br />
+    <label><%= radio_button_tag 'columns', 'all' %> <%= l(:description_all_columns) %></label>
+  </p>
+  <p class="buttons">
+    <%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);" %>
+    <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
+  </p>
+  <% end %>
+</div>
+<% end %>
+
+<% html_title l(:label_spent_time), l(:label_details) %>
+
+<% content_for :header_tags do %>
+    <%= auto_discovery_link_tag(:atom, {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :title => l(:label_spent_time)) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/25/25e20e75adcb2337c7b7589449cc334604a57456.svn-base
--- a/.svn/pristine/25/25e20e75adcb2337c7b7589449cc334604a57456.svn-base
+++ /dev/null
@@ -1,64 +0,0 @@
-# $Id: psw.rb 73 2006-04-24 21:59:35Z blackhedd $
-#
-#
-#----------------------------------------------------------------------------
-#
-# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
-#
-# Gmail: garbagecat10
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#---------------------------------------------------------------------------
-#
-#
-
-
-module Net
-class LDAP
-
-
-class Password
-  class << self
-
-  # Generate a password-hash suitable for inclusion in an LDAP attribute.
-  # Pass a hash type (currently supported: :md5 and :sha) and a plaintext
-  # password. This function will return a hashed representation.
-  # STUB: This is here to fulfill the requirements of an RFC, which one?
-  # TODO, gotta do salted-sha and (maybe) salted-md5.
-  # Should we provide sha1 as a synonym for sha1? I vote no because then
-  # should you also provide ssha1 for symmetry?
-  def generate( type, str )
-    case type
-    when :md5
-      require 'md5'
-      "{MD5}#{ [MD5.new( str.to_s ).digest].pack("m").chomp }"
-    when :sha
-      require 'sha1'
-      "{SHA}#{ [SHA1.new( str.to_s ).digest].pack("m").chomp }"
-    # when ssha
-    else
-      raise Net::LDAP::LdapError.new( "unsupported password-hash type (#{type})" )
-    end
-  end
-
-  end
-end
-
-
-end # class LDAP
-end # module Net
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/25/25e2b9b227cb6f18e371c2b9f54071b5c31827f3.svn-base
--- a/.svn/pristine/25/25e2b9b227cb6f18e371c2b9f54071b5c31827f3.svn-base
+++ /dev/null
@@ -1,106 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::CipheringTest < ActiveSupport::TestCase
-
-  def test_password_should_be_encrypted
-    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
-      r = Repository::Subversion.generate!(:password => 'foo')
-      assert_equal 'foo', r.password
-      assert r.read_attribute(:password).match(/\Aaes-256-cbc:.+\Z/)
-    end
-  end
-
-  def test_password_should_be_clear_with_blank_key
-    Redmine::Configuration.with 'database_cipher_key' => '' do
-      r = Repository::Subversion.generate!(:password => 'foo')
-      assert_equal 'foo', r.password
-      assert_equal 'foo', r.read_attribute(:password)
-    end
-  end
-
-  def test_password_should_be_clear_with_nil_key
-    Redmine::Configuration.with 'database_cipher_key' => nil do
-      r = Repository::Subversion.generate!(:password => 'foo')
-      assert_equal 'foo', r.password
-      assert_equal 'foo', r.read_attribute(:password)
-    end
-  end
-
-  def test_blank_password_should_be_clear
-    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
-      r = Repository::Subversion.generate!(:password => '')
-      assert_equal '', r.password
-      assert_equal '', r.read_attribute(:password)
-    end
-  end
-
-  def test_unciphered_password_should_be_readable
-    Redmine::Configuration.with 'database_cipher_key' => nil do
-      r = Repository::Subversion.generate!(:password => 'clear')
-    end
-
-    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
-      r = Repository.first(:order => 'id DESC')
-      assert_equal 'clear', r.password
-    end
-  end
-  
-  def test_ciphered_password_with_no_cipher_key_configured_should_be_returned_ciphered
-    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
-      r = Repository::Subversion.generate!(:password => 'clear')
-    end
-
-    Redmine::Configuration.with 'database_cipher_key' => '' do
-      r = Repository.first(:order => 'id DESC')
-      # password can not be deciphered
-      assert_nothing_raised do
-        assert r.password.match(/\Aaes-256-cbc:.+\Z/)
-      end
-    end
-  end
-
-  def test_encrypt_all
-    Repository.delete_all
-    Redmine::Configuration.with 'database_cipher_key' => nil do
-      Repository::Subversion.generate!(:password => 'foo')
-      Repository::Subversion.generate!(:password => 'bar')
-    end
-
-    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
-      assert Repository.encrypt_all(:password)
-      r = Repository.first(:order => 'id DESC')
-      assert_equal 'bar', r.password
-      assert r.read_attribute(:password).match(/\Aaes-256-cbc:.+\Z/)
-    end
-  end
-
-  def test_decrypt_all
-    Repository.delete_all
-    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
-      Repository::Subversion.generate!(:password => 'foo')
-      Repository::Subversion.generate!(:password => 'bar')
-
-      assert Repository.decrypt_all(:password)
-      r = Repository.first(:order => 'id DESC')
-      assert_equal 'bar', r.password
-      assert_equal 'bar', r.read_attribute(:password)
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/25/25f1da6f66db9d07326385e2039be298e7f220f8.svn-base
--- /dev/null
+++ b/.svn/pristine/25/25f1da6f66db9d07326385e2039be298e7f220f8.svn-base
@@ -0,0 +1,61 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::ConfigurationTest < ActiveSupport::TestCase
+  def setup
+    @conf = Redmine::Configuration
+  end
+
+  def test_empty
+    assert_kind_of Hash, load_conf('empty.yml', 'test')
+  end
+
+  def test_default
+    assert_kind_of Hash, load_conf('default.yml', 'test')
+    assert_equal 'foo', @conf['somesetting']
+  end
+
+  def test_no_default
+    assert_kind_of Hash, load_conf('no_default.yml', 'test')
+    assert_equal 'foo', @conf['somesetting']
+  end
+
+  def test_overrides
+    assert_kind_of Hash, load_conf('overrides.yml', 'test')
+    assert_equal 'bar', @conf['somesetting']
+  end
+
+  def test_with
+    load_conf('default.yml', 'test')
+    assert_equal 'foo', @conf['somesetting']
+    @conf.with 'somesetting' => 'bar' do
+      assert_equal 'bar', @conf['somesetting']
+    end
+    assert_equal 'foo', @conf['somesetting']
+  end
+
+  private
+
+  def load_conf(file, env)
+    @conf.load(
+      :file => File.join(Rails.root, 'test', 'fixtures', 'configuration', file),
+      :env => env
+    )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/26/2671f6e5821e0f33ebda94781641aa4c51e44a69.svn-base
--- a/.svn/pristine/26/2671f6e5821e0f33ebda94781641aa4c51e44a69.svn-base
+++ /dev/null
@@ -1,14 +0,0 @@
-<%= wiki_page_breadcrumb(@page) %>
-
-<h2><%=h @original_title %></h2>
-
-<%= error_messages_for 'page' %>
-
-<% labelled_tabular_form_for :wiki_page, @page, :url => { :action => 'rename' } do |f| %>
-<div class="box">
-<p><%= f.text_field :title, :required => true, :size => 100  %></p>
-<p><%= f.check_box :redirect_existing_links %></p>
-<p><%= f.select :parent_id, "<option value=''></option>" + wiki_page_options_for_select(@wiki.pages.all(:include => :parent) - @page.self_and_descendants, @page.parent), :label => :field_parent_title %></p>
-</div>
-<%= submit_tag l(:button_rename) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/26/2675c54fd1e1031cc73ed11da9cb75c92aebe12b.svn-base
--- /dev/null
+++ b/.svn/pristine/26/2675c54fd1e1031cc73ed11da9cb75c92aebe12b.svn-base
@@ -0,0 +1,1089 @@
+sl:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [Nedelja, Ponedeljek, Torek, Sreda, ÄŒetrtek, Petek, Sobota]
+    abbr_day_names: [Ned, Pon, To, Sr, ÄŒet, Pet, Sob]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Januar, Februar, Marec, April, Maj, Junij, Julij, Avgust, September, Oktober, November, December]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, Maj, Jun, Jul, Aug, Sep, Okt, Nov, Dec]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pol minute"
+      less_than_x_seconds:
+        one:   "manj kot 1. sekundo"
+        other: "manj kot %{count} sekund"
+      x_seconds:
+        one:   "1. sekunda"
+        other: "%{count} sekund"
+      less_than_x_minutes:
+        one:   "manj kot minuto"
+        other: "manj kot %{count} minut"
+      x_minutes:
+        one:   "1 minuta"
+        other: "%{count} minut"
+      about_x_hours:
+        one:   "okrog 1. ure"
+        other: "okrog %{count} ur"
+      x_hours:
+        one:   "1 ura"
+        other: "%{count} ur"
+      x_days:
+        one:   "1 dan"
+        other: "%{count} dni"
+      about_x_months:
+        one:   "okrog 1. mesec"
+        other: "okrog %{count} mesecev"
+      x_months:
+        one:   "1 mesec"
+        other: "%{count} mesecev"
+      about_x_years:
+        one:   "okrog 1. leto"
+        other: "okrog %{count} let"
+      over_x_years:
+        one:   "veÄ kot 1. leto"
+        other: "veÄ kot %{count} let"
+      almost_x_years:
+        one:   "skoraj 1. leto"
+        other: "skoraj %{count} let"
+
+  number:
+    format:
+      separator: ","
+      delimiter: "."
+      precision: 3
+    human:
+      format:
+        precision: 3
+        delimiter: ""
+      storage_units:
+        format: "%n %u"
+        units:
+          kb: KB
+          tb: TB
+          gb: GB
+          byte:
+            one: Byte
+            other: Bytes
+          mb: MB
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "in"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1. napaka je prepreÄila temu %{model} da bi se shranil"
+          other:  "%{count} napak je prepreÄilo temu %{model} da bi se shranil"
+      messages:
+        inclusion: "ni vkljuÄen na seznamu"
+        exclusion: "je rezerviran"
+        invalid: "je napaÄen"
+        confirmation: "ne ustreza potrdilu"
+        accepted: "mora biti sprejet"
+        empty: "ne sme biti prazen"
+        blank: "ne sme biti neizpolnjen"
+        too_long: "je predolg"
+        too_short: "je prekratek"
+        wrong_length: "je napaÄne dolÅ¾ine"
+        taken: "je Å¾e zaseden"
+        not_a_number: "ni Å¡tevilo"
+        not_a_date: "ni veljaven datum"
+        greater_than: "mora biti veÄji kot %{count}"
+        greater_than_or_equal_to: "mora biti veÄji ali enak kot %{count}"
+        equal_to: "mora biti enak kot %{count}"
+        less_than: "mora biti manjÅ¡i kot %{count}"
+        less_than_or_equal_to: "mora biti manjÅ¡i ali enak kot %{count}"
+        odd: "mora biti sodo"
+        even: "mora biti liho"
+        greater_than_start_date: "mora biti kasnejÅ¡i kot zaÄetni datum"
+        not_same_project: "ne pripada istemu projektu"
+        circular_dependency: "Ta odnos bi povzroÄil kroÅ¾no odvisnost"
+        cant_link_an_issue_with_a_descendant: "Zahtevek ne more biti povezan s svojo podnalogo"
+
+  actionview_instancetag_blank_option: Prosimo izberite
+
+  general_text_No: 'Ne'
+  general_text_Yes: 'Da'
+  general_text_no: 'ne'
+  general_text_yes: 'da'
+  general_lang_name: 'SlovenÅ¡Äina'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: RaÄun je bil uspeÅ¡no posodobljen.
+  notice_account_invalid_creditentials: NapaÄno uporabniÅ¡ko ime ali geslo
+  notice_account_password_updated: Geslo je bilo uspeÅ¡no posodobljeno.
+  notice_account_wrong_password: NapaÄno geslo
+  notice_account_register_done: RaÄun je bil uspeÅ¡no ustvarjen. Za aktivacijo potrdite povezavo, ki vam je bila poslana v e-nabiralnik.
+  notice_account_unknown_email: Neznan uporabnik.
+  notice_can_t_change_password: Ta raÄun za overovljanje uporablja zunanji. Gesla ni mogoÄe spremeniti.
+  notice_account_lost_email_sent: Poslano vam je bilo e-pismo z navodili za izbiro novega gesla.
+  notice_account_activated: VaÅ¡ raÄun je bil aktiviran. Sedaj se lahko prijavite.
+  notice_successful_create: Ustvarjanje uspelo.
+  notice_successful_update: Posodobitev uspela.
+  notice_successful_delete: Izbris uspel.
+  notice_successful_connection: Povezava uspela.
+  notice_file_not_found: Stran na katero se Å¾elite povezati ne obstaja ali pa je bila umaknjena.
+  notice_locking_conflict: Drug uporabnik je posodobil podatke.
+  notice_not_authorized: Nimate privilegijev za dostop do te strani.
+  notice_email_sent: "E-poÅ¡tno sporoÄilo je bilo poslano %{value}"
+  notice_email_error: "Ob poÅ¡iljanju e-sporoÄila je priÅ¡lo do napake (%{value})"
+  notice_feeds_access_key_reseted: VaÅ¡ RSS dostopni kljuÄ je bil ponastavljen.
+  notice_failed_to_save_issues: "Neuspelo shranjevanje %{count} zahtevka na %{total} izbranem: %{ids}."
+  notice_no_issue_selected: "Izbran ni noben zahtevek! Prosimo preverite zahtevke, ki jih Å¾elite urediti."
+  notice_account_pending: "VaÅ¡ raÄun je bil ustvarjen in Äaka na potrditev s strani administratorja."
+  notice_default_data_loaded: Privzete nastavitve so bile uspeÅ¡no naloÅ¾ene.
+  notice_unable_delete_version: Verzije ni bilo mogoÄe izbrisati.
+
+  error_can_t_load_default_data: "Privzetih nastavitev ni bilo mogoÄe naloÅ¾iti: %{value}"
+  error_scm_not_found: "Vnos ali revizija v shrambi ni bila najdena ."
+  error_scm_command_failed: "Med vzpostavljem povezave s shrambo je priÅ¡lo do napake: %{value}"
+  error_scm_annotate: "Vnos ne obstaja ali pa ga ni mogoÄe komentirati."
+  error_issue_not_found_in_project: 'Zahtevek ni bil najden ali pa ne pripada temu projektu'
+
+  mail_subject_lost_password: "VaÅ¡e %{value} geslo"
+  mail_body_lost_password: 'Za spremembo glesla kliknite na naslednjo povezavo:'
+  mail_subject_register: "Aktivacija %{value} vaÅ¡ega raÄuna"
+  mail_body_register: 'Za aktivacijo vaÅ¡ega raÄuna kliknite na naslednjo povezavo:'
+  mail_body_account_information_external: "Za prijavo lahko uporabite vaÅ¡ %{value} raÄun."
+  mail_body_account_information: Informacije o vaÅ¡em raÄunu
+  mail_subject_account_activation_request: "%{value} zahtevek za aktivacijo raÄuna"
+  mail_body_account_activation_request: "Registriral se je nov uporabnik (%{value}). RaÄun Äaka na vaÅ¡o odobritev:"
+  mail_subject_reminder: "%{count} zahtevek(zahtevki) zapadejo v naslednjih %{days} dneh"
+  mail_body_reminder: "%{count} zahtevek(zahtevki), ki so vam dodeljeni bodo zapadli v naslednjih %{days} dneh:"
+
+
+  field_name: Ime
+  field_description: Opis
+  field_summary: Povzetek
+  field_is_required: Zahtevano
+  field_firstname: Ime
+  field_lastname: Priimek
+  field_mail: E-naslov
+  field_filename: Datoteka
+  field_filesize: Velikost
+  field_downloads: Prenosi
+  field_author: Avtor
+  field_created_on: Ustvarjen
+  field_updated_on: Posodobljeno
+  field_field_format: Format
+  field_is_for_all: Za vse projekte
+  field_possible_values: MoÅ¾ne vrednosti
+  field_regexp: Regularni izraz
+  field_min_length: Minimalna dolÅ¾ina
+  field_max_length: Maksimalna dolÅ¾ina
+  field_value: Vrednost
+  field_category: Kategorija
+  field_title: Naslov
+  field_project: Projekt
+  field_issue: Zahtevek
+  field_status: Status
+  field_notes: ZabeleÅ¾ka
+  field_is_closed: Zahtevek zaprt
+  field_is_default: Privzeta vrednost
+  field_tracker: Vrsta zahtevka
+  field_subject: Tema
+  field_due_date: Do datuma
+  field_assigned_to: Dodeljen
+  field_priority: Prioriteta
+  field_fixed_version: Ciljna verzija
+  field_user: Uporabnik
+  field_role: Vloga
+  field_homepage: DomaÄa stran
+  field_is_public: Javno
+  field_parent: Podprojekt projekta
+  field_is_in_roadmap: Zahtevki prikazani na zemljevidu
+  field_login: Prijava
+  field_mail_notification: E-poÅ¡tna oznanila
+  field_admin: Administrator
+  field_last_login_on: ZadnjiÄ povezan(a)
+  field_language: Jezik
+  field_effective_date: Datum
+  field_password: Geslo
+  field_new_password: Novo geslo
+  field_password_confirmation: Potrditev
+  field_version: Verzija
+  field_type: Tip
+  field_host: Gostitelj
+  field_port: Vrata
+  field_account: RaÄun
+  field_base_dn: Bazni DN
+  field_attr_login: Oznaka za prijavo
+  field_attr_firstname: Oznaka za ime
+  field_attr_lastname: Oznaka za priimek
+  field_attr_mail: Oznaka za e-naslov
+  field_onthefly: Sprotna izdelava uporabnikov
+  field_start_date: ZaÄetek
+  field_done_ratio: "% Narejeno"
+  field_auth_source: NaÄin overovljanja
+  field_hide_mail: Skrij moj e-naslov
+  field_comments: Komentar
+  field_url: URL
+  field_start_page: ZaÄetna stran
+  field_subproject: Podprojekt
+  field_hours: Ur
+  field_activity: Aktivnost
+  field_spent_on: Datum
+  field_identifier: Identifikator
+  field_is_filter: Uporabljen kot filter
+  field_issue_to: Povezan zahtevek
+  field_delay: Zamik
+  field_assignable: Zahtevki so lahko dodeljeni tej vlogi
+  field_redirect_existing_links: Preusmeri obstojeÄe povezave
+  field_estimated_hours: Ocenjen Äas
+  field_column_names: Stolpci
+  field_time_zone: ÄŒasovni pas
+  field_searchable: ZmoÅ¾en iskanja
+  field_default_value: Privzeta vrednost
+  field_comments_sorting: PrikaÅ¾i komentarje
+  field_parent_title: MatiÄna stran
+
+  setting_app_title: Naslov aplikacije
+  setting_app_subtitle: Podnaslov aplikacije
+  setting_welcome_text: Pozdravno besedilo
+  setting_default_language: Privzeti jezik
+  setting_login_required: Zahtevano overovljanje
+  setting_self_registration: Samostojna registracija
+  setting_attachment_max_size: Maksimalna velikost priponk
+  setting_issues_export_limit: Skrajna meja za izvoz zahtevkov
+  setting_mail_from: E-naslov za emisijo
+  setting_bcc_recipients: Prejemniki slepih kopij (bcc)
+  setting_plain_text_mail: navadno e-sporoÄilo (ne HTML)
+  setting_host_name: Ime gostitelja in pot
+  setting_text_formatting: Oblikovanje besedila
+  setting_wiki_compression: Stiskanje Wiki zgodovine
+  setting_feeds_limit: Meja obsega RSS virov
+  setting_default_projects_public: Novi projekti so privzeto javni
+  setting_autofetch_changesets: Samodejni izvleÄek zapisa sprememb
+  setting_sys_api_enabled: OmogoÄi WS za upravljanje shrambe
+  setting_commit_ref_keywords: Sklicne kljuÄne besede
+  setting_commit_fix_keywords: Urejanje kljuÄne besede
+  setting_autologin: Avtomatska prijava
+  setting_date_format: Oblika datuma
+  setting_time_format: Oblika Äasa
+  setting_cross_project_issue_relations: Dovoli povezave zahtevkov med razliÄnimi projekti
+  setting_issue_list_default_columns: Privzeti stolpci prikazani na seznamu zahtevkov
+  setting_emails_footer: Noga e-sporoÄil
+  setting_protocol: Protokol
+  setting_per_page_options: Å tevilo elementov na stran
+  setting_user_format: Oblika prikaza uporabnikov
+  setting_activity_days_default: Prikaz dni na aktivnost projekta
+  setting_display_subprojects_issues: Privzeti prikaz zahtevkov podprojektov v glavnem projektu
+  setting_enabled_scm: OmogoÄen SCM
+  setting_mail_handler_api_enabled: OmogoÄi WS za prihajajoÄo e-poÅ¡to
+  setting_mail_handler_api_key: API kljuÄ
+  setting_sequential_project_identifiers: Generiraj projektne identifikatorje sekvenÄno
+  setting_gravatar_enabled: Uporabljaj Gravatar ikone
+  setting_diff_max_lines_displayed: Maksimalno Å¡tevilo prikazanih vrstic razliÄnosti
+
+  permission_edit_project: Uredi projekt
+  permission_select_project_modules: Izberi module projekta
+  permission_manage_members: Uredi Älane
+  permission_manage_versions: Uredi verzije
+  permission_manage_categories: Urejanje kategorij zahtevkov
+  permission_add_issues: Dodaj zahtevke
+  permission_edit_issues: Uredi zahtevke
+  permission_manage_issue_relations: Uredi odnose med zahtevki
+  permission_add_issue_notes: Dodaj zabeleÅ¾ke
+  permission_edit_issue_notes: Uredi zabeleÅ¾ke
+  permission_edit_own_issue_notes: Uredi lastne zabeleÅ¾ke
+  permission_move_issues: Premakni zahtevke
+  permission_delete_issues: IzbriÅ¡i zahtevke
+  permission_manage_public_queries: Uredi javna povpraÅ¡evanja
+  permission_save_queries: Shrani povpraÅ¡evanje
+  permission_view_gantt: Poglej gantogram
+  permission_view_calendar: Poglej koledar
+  permission_view_issue_watchers: Oglej si listo spremeljevalcev
+  permission_add_issue_watchers: Dodaj spremljevalce
+  permission_log_time: BeleÅ¾i porabljen Äas
+  permission_view_time_entries: Poglej porabljen Äas
+  permission_edit_time_entries: Uredi beleÅ¾ko Äasa
+  permission_edit_own_time_entries: Uredi beleÅ¾ko lastnega Äasa
+  permission_manage_news: Uredi novice
+  permission_comment_news: Komentiraj novice
+  permission_view_documents: Poglej dokumente
+  permission_manage_files: Uredi datoteke
+  permission_view_files: Poglej datoteke
+  permission_manage_wiki: Uredi wiki
+  permission_rename_wiki_pages: Preimenuj wiki strani
+  permission_delete_wiki_pages: IzbriÅ¡i wiki strani
+  permission_view_wiki_pages: Poglej wiki
+  permission_view_wiki_edits: Poglej wiki zgodovino
+  permission_edit_wiki_pages: Uredi wiki strani
+  permission_delete_wiki_pages_attachments: IzbriÅ¡i priponke
+  permission_protect_wiki_pages: ZaÅ¡Äiti wiki strani
+  permission_manage_repository: Uredi shrambo
+  permission_browse_repository: Prebrskaj shrambo
+  permission_view_changesets: Poglej zapis sprememb
+  permission_commit_access: Dostop za predajo
+  permission_manage_boards: Uredi table
+  permission_view_messages: Poglej sporoÄila
+  permission_add_messages: Objavi sporoÄila
+  permission_edit_messages: Uredi sporoÄila
+  permission_edit_own_messages: Uredi lastna sporoÄila
+  permission_delete_messages: IzbriÅ¡i sporoÄila
+  permission_delete_own_messages: IzbriÅ¡i lastna sporoÄila
+
+  project_module_issue_tracking: Sledenje zahtevkom
+  project_module_time_tracking: Sledenje Äasa
+  project_module_news: Novice
+  project_module_documents: Dokumenti
+  project_module_files: Datoteke
+  project_module_wiki: Wiki
+  project_module_repository: Shramba
+  project_module_boards: Table
+
+  label_user: Uporabnik
+  label_user_plural: Uporabniki
+  label_user_new: Nov uporabnik
+  label_project: Projekt
+  label_project_new: Nov projekt
+  label_project_plural: Projekti
+  label_x_projects:
+    zero:  ni projektov
+    one:   1 projekt
+    other: "%{count} projektov"
+  label_project_all: Vsi projekti
+  label_project_latest: Zadnji projekti
+  label_issue: Zahtevek
+  label_issue_new: Nov zahtevek
+  label_issue_plural: Zahtevki
+  label_issue_view_all: Poglej vse zahtevke
+  label_issues_by: "Zahtevki od %{value}"
+  label_issue_added: Zahtevek dodan
+  label_issue_updated: Zahtevek posodobljen
+  label_document: Dokument
+  label_document_new: Nov dokument
+  label_document_plural: Dokumenti
+  label_document_added: Dokument dodan
+  label_role: Vloga
+  label_role_plural: Vloge
+  label_role_new: Nova vloga
+  label_role_and_permissions: Vloge in dovoljenja
+  label_member: ÄŒlan
+  label_member_new: Nov Älan
+  label_member_plural: ÄŒlani
+  label_tracker: Vrsta zahtevka
+  label_tracker_plural: Vrste zahtevkov
+  label_tracker_new: Nova vrsta zahtevka
+  label_workflow: Potek dela
+  label_issue_status: Stanje zahtevka
+  label_issue_status_plural: Stanje zahtevkov
+  label_issue_status_new: Novo stanje
+  label_issue_category: Kategorija zahtevka
+  label_issue_category_plural: Kategorije zahtevkov
+  label_issue_category_new: Nova kategorija
+  label_custom_field: Polje po meri
+  label_custom_field_plural: Polja po meri
+  label_custom_field_new: Novo polje po meri
+  label_enumerations: Seznami
+  label_enumeration_new: Nova vrednost
+  label_information: Informacija
+  label_information_plural: Informacije
+  label_please_login: Prosimo prijavite se
+  label_register: Registracija
+  label_password_lost: Izgubljeno geslo
+  label_home: Domov
+  label_my_page: Moja stran
+  label_my_account: Moj raÄun
+  label_my_projects: Moji projekti
+  label_administration: Upravljanje
+  label_login: Prijavi se
+  label_logout: Odjavi se
+  label_help: PomoÄ
+  label_reported_issues: Prijavljeni zahtevki
+  label_assigned_to_me_issues: Zahtevki dodeljeni meni
+  label_last_login: Zadnja povezava
+  label_registered_on: Registriran
+  label_activity: Aktivnost
+  label_overall_activity: Celotna aktivnost
+  label_user_activity: "Aktivnost %{value}"
+  label_new: Nov
+  label_logged_as: Prijavljen(a) kot
+  label_environment: Okolje
+  label_authentication: Overovitev
+  label_auth_source: NaÄin overovitve
+  label_auth_source_new: Nov naÄin overovitve
+  label_auth_source_plural: NaÄini overovitve
+  label_subproject_plural: Podprojekti
+  label_and_its_subprojects: "%{value} in njegovi podprojekti"
+  label_min_max_length: Min - Max dolÅ¾ina
+  label_list: Seznam
+  label_date: Datum
+  label_integer: Celo Å¡tevilo
+  label_float: Decimalno Å¡tevilo
+  label_boolean: Boolean
+  label_string: Besedilo
+  label_text: Dolgo besedilo
+  label_attribute: Lastnost
+  label_attribute_plural: Lastnosti
+  label_no_data: Ni podatkov za prikaz
+  label_change_status: Spremeni stanje
+  label_history: Zgodovina
+  label_attachment: Datoteka
+  label_attachment_new: Nova datoteka
+  label_attachment_delete: IzbriÅ¡i datoteko
+  label_attachment_plural: Datoteke
+  label_file_added: Datoteka dodana
+  label_report: PoroÄilo
+  label_report_plural: PoroÄila
+  label_news: Novica
+  label_news_new: Dodaj novico
+  label_news_plural: Novice
+  label_news_latest: Zadnje novice
+  label_news_view_all: Poglej vse novice
+  label_news_added: Dodane novice
+  label_settings: Nastavitve
+  label_overview: Pregled
+  label_version: Verzija
+  label_version_new: Nova verzija
+  label_version_plural: Verzije
+  label_confirmation: Potrditev
+  label_export_to: 'Na razpolago tudi v:'
+  label_read: Preberi...
+  label_public_projects: Javni projekti
+  label_open_issues: odprt zahtevek
+  label_open_issues_plural: odprti zahtevki
+  label_closed_issues: zaprt zahtevek
+  label_closed_issues_plural: zaprti zahtevki
+  label_x_open_issues_abbr_on_total:
+    zero:  0 odprtih / %{total}
+    one:   1 odprt / %{total}
+    other: "%{count} odprtih / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 odprtih
+    one:   1 odprt
+    other: "%{count} odprtih"
+  label_x_closed_issues_abbr:
+    zero:  0 zaprtih
+    one:   1 zaprt
+    other: "%{count} zaprtih"
+  label_total: Skupaj
+  label_permissions: Dovoljenja
+  label_current_status: Trenutno stanje
+  label_new_statuses_allowed: Novi zahtevki dovoljeni
+  label_all: vsi
+  label_none: noben
+  label_nobody: nihÄe
+  label_next: Naslednji
+  label_previous: PrejÅ¡nji
+  label_used_by: V uporabi od
+  label_details: Podrobnosti
+  label_add_note: Dodaj zabeleÅ¾ko
+  label_per_page: Na stran
+  label_calendar: Koledar
+  label_months_from: mesecev od
+  label_gantt: Gantogram
+  label_internal: Notranji
+  label_last_changes: "zadnjih %{count} sprememb"
+  label_change_view_all: Poglej vse spremembe
+  label_personalize_page: Individualiziraj to stran
+  label_comment: Komentar
+  label_comment_plural: Komentarji
+  label_x_comments:
+    zero: ni komentarjev
+    one: 1 komentar
+    other: "%{count} komentarjev"
+  label_comment_add: Dodaj komentar
+  label_comment_added: Komentar dodan
+  label_comment_delete: IzbriÅ¡i komentarje
+  label_query: Iskanje po meri
+  label_query_plural: Iskanja po meri
+  label_query_new: Novo iskanje
+  label_filter_add: Dodaj filter
+  label_filter_plural: Filtri
+  label_equals: je enako
+  label_not_equals: ni enako
+  label_in_less_than: v manj kot
+  label_in_more_than: v veÄ kot
+  label_in: v
+  label_today: danes
+  label_all_time: v vsem Äasu
+  label_yesterday: vÄeraj
+  label_this_week: ta teden
+  label_last_week: pretekli teden
+  label_last_n_days: "zadnjih %{count} dni"
+  label_this_month: ta mesec
+  label_last_month: zadnji mesec
+  label_this_year: to leto
+  label_date_range: Razpon datumov
+  label_less_than_ago: manj kot dni nazaj
+  label_more_than_ago: veÄ kot dni nazaj
+  label_ago: dni nazaj
+  label_contains: vsebuje
+  label_not_contains: ne vsebuje
+  label_day_plural: dni
+  label_repository: Shramba
+  label_repository_plural: Shrambe
+  label_browse: Prebrskaj
+  label_revision: Revizija
+  label_revision_plural: Revizije
+  label_associated_revisions: Povezane revizije
+  label_added: dodano
+  label_modified: spremenjeno
+  label_copied: kopirano
+  label_renamed: preimenovano
+  label_deleted: izbrisano
+  label_latest_revision: Zadnja revizija
+  label_latest_revision_plural: Zadnje revizije
+  label_view_revisions: Poglej revizije
+  label_max_size: NajveÄja velikost
+  label_sort_highest: Premakni na vrh
+  label_sort_higher: Premakni gor
+  label_sort_lower: Premakni dol
+  label_sort_lowest: Premakni na dno
+  label_roadmap: NaÄrt
+  label_roadmap_due_in: "Do %{value}"
+  label_roadmap_overdue: "%{value} zakasnel"
+  label_roadmap_no_issues: Ni zahtevkov za to verzijo
+  label_search: IÅ¡Äi
+  label_result_plural: Rezultati
+  label_all_words: Vse besede
+  label_wiki: Wiki
+  label_wiki_edit: Wiki urejanje
+  label_wiki_edit_plural: Wiki urejanja
+  label_wiki_page: Wiki stran
+  label_wiki_page_plural: Wiki strani
+  label_index_by_title: Razvrsti po naslovu
+  label_index_by_date: Razvrsti po datumu
+  label_current_version: Trenutna verzija
+  label_preview: Predogled
+  label_feed_plural: RSS viri
+  label_changes_details: Podrobnosti o vseh spremembah
+  label_issue_tracking: Sledenje zahtevkom
+  label_spent_time: Porabljen Äas
+  label_f_hour: "%{value} ura"
+  label_f_hour_plural: "%{value} ur"
+  label_time_tracking: Sledenje Äasu
+  label_change_plural: Spremembe
+  label_statistics: Statistika
+  label_commits_per_month: Predaj na mesec
+  label_commits_per_author: Predaj na avtorja
+  label_view_diff: Preglej razlike
+  label_diff_inline: znotraj
+  label_diff_side_by_side: vzporedno
+  label_options: MoÅ¾nosti
+  label_copy_workflow_from: Kopiraj potek dela od
+  label_permissions_report: PoroÄilo o dovoljenjih
+  label_watched_issues: Spremljani zahtevki
+  label_related_issues: Povezani zahtevki
+  label_applied_status: Uveljavljeno stanje
+  label_loading: Nalaganje...
+  label_relation_new: Nova povezava
+  label_relation_delete: IzbriÅ¡i povezavo
+  label_relates_to: povezan z
+  label_duplicates: duplikati
+  label_duplicated_by: dupliciral
+  label_blocks: blok
+  label_blocked_by: blokiral
+  label_precedes: ima prednost pred
+  label_follows: sledi
+  label_end_to_start: konec na zaÄetek
+  label_end_to_end: konec na konec
+  label_start_to_start: zaÄetek na zaÄetek
+  label_start_to_end: zaÄetek na konec
+  label_stay_logged_in: Ostani prijavljen(a)
+  label_disabled: onemogoÄi
+  label_show_completed_versions: PrikaÅ¾i zakljuÄene verzije
+  label_me: jaz
+  label_board: Forum
+  label_board_new: Nov forum
+  label_board_plural: Forumi
+  label_topic_plural: Teme
+  label_message_plural: SporoÄila
+  label_message_last: Zadnje sporoÄilo
+  label_message_new: Novo sporoÄilo
+  label_message_posted: SporoÄilo dodano
+  label_reply_plural: Odgovori
+  label_send_information: PoÅ¡lji informacijo o raÄunu uporabniku
+  label_year: Leto
+  label_month: Mesec
+  label_week: Teden
+  label_date_from: Do
+  label_date_to: Do
+  label_language_based: Glede na uporabnikov jezik
+  label_sort_by: "Razporedi po %{value}"
+  label_send_test_email: PoÅ¡lji testno e-pismo
+  label_feeds_access_key_created_on: "RSS dostopni kljuÄ narejen %{value} nazaj"
+  label_module_plural: Moduli
+  label_added_time_by: "Dodan %{author} %{age} nazaj"
+  label_updated_time_by: "Posodobljen od %{author} %{age} nazaj"
+  label_updated_time: "Posodobljen %{value} nazaj"
+  label_jump_to_a_project: SkoÄi na projekt...
+  label_file_plural: Datoteke
+  label_changeset_plural: Zapisi sprememb
+  label_default_columns: Privzeti stolpci
+  label_no_change_option: (Ni spremembe)
+  label_bulk_edit_selected_issues: Uredi izbrane zahtevke skupaj
+  label_theme: Tema
+  label_default: Privzeto
+  label_search_titles_only: PreiÅ¡Äi samo naslove
+  label_user_mail_option_all: "Za vsak dogodek v vseh mojih projektih"
+  label_user_mail_option_selected: "Za vsak dogodek samo na izbranih projektih..."
+  label_user_mail_no_self_notified: "Ne Å¾elim biti opozorjen(a) na spremembe, ki jih naredim sam(a)"
+  label_registration_activation_by_email: aktivacija raÄuna po e-poÅ¡ti
+  label_registration_manual_activation: roÄna aktivacija raÄuna
+  label_registration_automatic_activation: samodejna aktivacija raÄuna
+  label_display_per_page: "Na stran: %{value}"
+  label_age: Starost
+  label_change_properties: Sprememba lastnosti
+  label_general: SploÅ¡no
+  label_more: VeÄ
+  label_scm: SCM
+  label_plugins: VtiÄniki
+  label_ldap_authentication: LDAP overovljanje
+  label_downloads_abbr: D/L
+  label_optional_description: Neobvezen opis
+  label_add_another_file: Dodaj Å¡e eno datoteko
+  label_preferences: Preference
+  label_chronological_order: KronoloÅ¡ko
+  label_reverse_chronological_order: Obrnjeno kronoloÅ¡ko
+  label_planning: NaÄrtovanje
+  label_incoming_emails: PrihajajoÄa e-poÅ¡ta
+  label_generate_key: Ustvari kljuÄ
+  label_issue_watchers: Spremljevalci
+  label_example: Vzorec
+
+  button_login: Prijavi se
+  button_submit: PoÅ¡lji
+  button_save: Shrani
+  button_check_all: OznaÄi vse
+  button_uncheck_all: OdznaÄi vse
+  button_delete: IzbriÅ¡i
+  button_create: Ustvari
+  button_test: Testiraj
+  button_edit: Uredi
+  button_add: Dodaj
+  button_change: Spremeni
+  button_apply: Uporabi
+  button_clear: PoÄisti
+  button_lock: Zakleni
+  button_unlock: Odkleni
+  button_download: Prenesi
+  button_list: Seznam
+  button_view: Pogled
+  button_move: Premakni
+  button_back: Nazaj
+  button_cancel: PrekliÄi
+  button_activate: Aktiviraj
+  button_sort: Razvrsti
+  button_log_time: BeleÅ¾i Äas
+  button_rollback: Povrni na to verzijo
+  button_watch: Spremljaj
+  button_unwatch: Ne spremljaj
+  button_reply: Odgovori
+  button_archive: Arhiviraj
+  button_unarchive: Odarhiviraj
+  button_reset: Ponastavi
+  button_rename: Preimenuj
+  button_change_password: Spremeni geslo
+  button_copy: Kopiraj
+  button_annotate: ZapiÅ¡i pripombo
+  button_update: Posodobi
+  button_configure: Konfiguriraj
+  button_quote: Citiraj
+
+  status_active: aktivni
+  status_registered: registriran
+  status_locked: zaklenjen
+
+  text_select_mail_notifications: Izberi dejanja za katera naj bodo poslana oznanila preko e-poÅ¡to.
+  text_regexp_info: npr. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 pomeni brez omejitev
+  text_project_destroy_confirmation: Ali ste prepriÄani da Å¾elite izbrisati izbrani projekt in vse z njim povezane podatke?
+  text_subprojects_destroy_warning: "Njegov(i) podprojekt(i): %{value} bodo prav tako izbrisani."
+  text_workflow_edit: Izberite vlogo in zahtevek za urejanje poteka dela
+  text_are_you_sure: Ali ste prepriÄani?
+  text_tip_issue_begin_day: naloga z zaÄetkom na ta dan
+  text_tip_issue_end_day: naloga z zakljuÄkom na ta dan
+  text_tip_issue_begin_end_day: naloga ki se zaÄne in konÄa ta dan
+  text_caracters_maximum: "najveÄ %{count} znakov."
+  text_caracters_minimum: "Mora biti vsaj dolg vsaj %{count} znakov."
+  text_length_between: "DolÅ¾ina med %{min} in %{max} znakov."
+  text_tracker_no_workflow: Potek dela za to vrsto zahtevka ni doloÄen
+  text_unallowed_characters: Nedovoljeni znaki
+  text_comma_separated: Dovoljenih je veÄ vrednosti (loÄenih z vejico).
+  text_issues_ref_in_commit_messages: Zahtevki sklicev in popravkov v sporoÄilu predaje
+  text_issue_added: "Zahtevek %{id} je sporoÄil(a) %{author}."
+  text_issue_updated: "Zahtevek %{id} je posodobil(a) %{author}."
+  text_wiki_destroy_confirmation: Ali ste prepriÄani da Å¾elite izbrisati ta wiki in vso njegovo vsebino?
+  text_issue_category_destroy_question: "Nekateri zahtevki (%{count}) so dodeljeni tej kategoriji. Kaj Å¾elite storiti?"
+  text_issue_category_destroy_assignments: Odstrani naloge v kategoriji
+  text_issue_category_reassign_to: Ponovno dodeli zahtevke tej kategoriji
+  text_user_mail_option: "Na neizbrane projekte boste prejemali le obvestila o zadevah ki jih spremljate ali v katere ste vkljuÄeni (npr. zahtevki katerih avtor(ica) ste)"
+  text_no_configuration_data: "Vloge, vrste zahtevkov, statusi zahtevkov in potek dela Å¡e niso bili doloÄeni. \nZelo priporoÄljivo je, da naloÅ¾ite privzeto  konfiguracijo, ki jo lahko kasneje tudi prilagodite."
+  text_load_default_configuration: NaloÅ¾i privzeto konfiguracijo
+  text_status_changed_by_changeset: "Dodano v zapis sprememb %{value}."
+  text_issues_destroy_confirmation: 'Ali ste prepriÄani, da Å¾elite izbrisati izbrani(e) zahtevek(ke)?'
+  text_select_project_modules: 'Izberite module, ki jih Å¾elite omogoÄiti za ta projekt:'
+  text_default_administrator_account_changed: Spremenjen privzeti administratorski raÄun
+  text_file_repository_writable: OmogoÄeno pisanje v shrambo datotek
+  text_rmagick_available: RMagick je na voljo(neobvezno)
+  text_destroy_time_entries_question: "%{hours} ur je bilo opravljenih na zahtevku, ki ga Å¾elite izbrisati. Kaj Å¾elite storiti?"
+  text_destroy_time_entries: IzbriÅ¡i opravljene ure
+  text_assign_time_entries_to_project: Predaj opravljene ure projektu
+  text_reassign_time_entries: 'Prenesi opravljene ure na ta zahtevek:'
+  text_user_wrote: "%{value} je napisal(a):"
+  text_enumeration_destroy_question: "%{count} objektov je doloÄenih tej vrednosti."
+  text_enumeration_category_reassign_to: 'Ponastavi jih na to vrednost:'
+  text_email_delivery_not_configured: "E-poÅ¡tna dostava ni nastavljena in oznanila so onemogoÄena.\nNastavite vaÅ¡ SMTP streÅ¾nik v config/configuration.yml in ponovno zaÅ¾enite aplikacijo da ga omogoÄite.\n"
+  text_repository_usernames_mapping: "Izberite ali posodobite Redmine uporabnika dodeljenega vsakemu uporabniÅ¡kemu imenu najdenemu v zapisniku shrambe.\n Uporabniki z enakim Redmine ali shrambinem uporabniÅ¡kem imenu ali e-poÅ¡tnem naslovu so samodejno dodeljeni."
+  text_diff_truncated: '... Ta sprememba je bila odsekana ker presega najveÄjo velikost ki je lahko prikazana.'
+
+  default_role_manager: Upravnik
+  default_role_developer: Razvijalec
+  default_role_reporter: PoroÄevalec
+  default_tracker_bug: HroÅ¡Ä
+  default_tracker_feature: Funkcija
+  default_tracker_support: Podpora
+  default_issue_status_new: Nov
+  default_issue_status_in_progress: V teku
+  default_issue_status_resolved: ReÅ¡en
+  default_issue_status_feedback: Povratna informacija
+  default_issue_status_closed: ZakljuÄen
+  default_issue_status_rejected: Zavrnjen
+  default_doc_category_user: UporabniÅ¡ka dokumentacija
+  default_doc_category_tech: TehniÄna dokumentacija
+  default_priority_low: Nizka
+  default_priority_normal: ObiÄajna
+  default_priority_high: Visoka
+  default_priority_urgent: Urgentna
+  default_priority_immediate: TakojÅ¡nje ukrepanje
+  default_activity_design: Oblikovanje
+  default_activity_development: Razvoj
+
+  enumeration_issue_priorities: Prioritete zahtevkov
+  enumeration_doc_categories: Kategorije dokumentov
+  enumeration_activities: Aktivnosti (sledenje Äasa)
+  warning_attachments_not_saved: "%{count} datotek(e) ni bilo mogoÄe shraniti."
+  field_editable: Uredljivo
+  text_plugin_assets_writable: Zapisljiva mapa za vtiÄnike
+  label_display: Prikaz
+  button_create_and_continue: Ustvari in nadaljuj
+  text_custom_field_possible_values_info: 'Ena vrstica za vsako vrednost'
+  setting_repository_log_display_limit: NajveÄje Å¡tevilo prikazanih revizij v log datoteki
+  setting_file_max_size_displayed: NajveÄja velikost besedilnih datotek v vkljuÄenem prikazu
+  field_watcher: Opazovalec
+  setting_openid: Dovoli OpenID prijavo in registracijo
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: ali se prijavi z OpenID
+  field_content: Vsebina
+  label_descending: PadajoÄe
+  label_sort: Razvrsti
+  label_ascending: NaraÅ¡ÄajoÄe
+  label_date_from_to: Od %{start} do %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Ta stran ima %{descendants} podstran(i) in naslednik(ov). Kaj Å¾elite storiti?
+  text_wiki_page_reassign_children: Znova dodeli podstrani tej glavni strani
+  text_wiki_page_nullify_children: ObdrÅ¾i podstrani kot glavne strani
+  text_wiki_page_destroy_children: IzbriÅ¡i podstrani in vse njihove naslednike
+  setting_password_min_length: Minimalna dolÅ¾ina gesla
+  field_group_by: ZdruÅ¾i rezultate po
+  mail_subject_wiki_content_updated: "'%{id}' wiki stran je bila posodobljena"
+  label_wiki_content_added: Wiki stran dodana
+  mail_subject_wiki_content_added: "'%{id}' wiki stran je bila dodana"
+  mail_body_wiki_content_added: "%{author} je dodal '%{id}' wiki stran"
+  label_wiki_content_updated: Wiki stran posodobljena
+  mail_body_wiki_content_updated: "%{author} je posodobil '%{id}' wiki stran."
+  permission_add_project: Ustvari projekt
+  setting_new_project_user_role_id: Vloga, dodeljena neadministratorskemu uporabniku, ki je ustvaril projekt
+  label_view_all_revisions: Poglej vse revizije
+  label_tag: Oznaka
+  label_branch: Veja
+  error_no_tracker_in_project: Noben sledilnik ni povezan s tem projektom. Prosimo preverite nastavitve projekta.
+  error_no_default_issue_status: Privzeti zahtevek ni definiran. Prosimo preverite svoje nastavitve (Pojdite na "Administracija -> Stanje zahtevkov").
+  text_journal_changed: "%{label} se je spremenilo iz %{old} v %{new}"
+  text_journal_set_to: "%{label} nastavljeno na %{value}"
+  text_journal_deleted: "%{label} izbrisan (%{old})"
+  label_group_plural: Skupine
+  label_group: Skupina
+  label_group_new: Nova skupina
+  label_time_entry_plural: Porabljen Äas
+  text_journal_added: "%{label} %{value} dodan"
+  field_active: Aktiven
+  enumeration_system_activity: Sistemska aktivnost
+  permission_delete_issue_watchers: IzbriÅ¡i opazovalce
+  version_status_closed: zaprt
+  version_status_locked: zaklenjen
+  version_status_open: odprt
+  error_can_not_reopen_issue_on_closed_version: Zahtevek dodeljen zaprti verziji ne more biti ponovno odprt
+  label_user_anonymous: Anonimni
+  button_move_and_follow: Premakni in sledi
+  setting_default_projects_modules: Privzeti moduli za nove projekte
+  setting_gravatar_default: Privzeta Gravatar slika
+  field_sharing: Deljenje
+  label_version_sharing_hierarchy: S projektno hierarhijo
+  label_version_sharing_system: Z vsemi projekti
+  label_version_sharing_descendants: S podprojekti
+  label_version_sharing_tree: Z drevesom projekta
+  label_version_sharing_none: Ni deljeno
+  error_can_not_archive_project: Ta projekt ne more biti arhiviran
+  button_duplicate: Podvoji
+  button_copy_and_follow: Kopiraj in sledi
+  label_copy_source: Vir
+  setting_issue_done_ratio: IzraÄunaj razmerje opravljenega zahtevka z
+  setting_issue_done_ratio_issue_status: Uporabi stanje zahtevka
+  error_issue_done_ratios_not_updated: Razmerje opravljenega zahtevka ni bilo posodobljeno.
+  error_workflow_copy_target: Prosimo izberite ciljni(e) sledilnik(e) in vlogo(e)
+  setting_issue_done_ratio_issue_field: Uporabi polje zahtevka
+  label_copy_same_as_target: Enako kot cilj
+  label_copy_target: Cilj
+  notice_issue_done_ratios_updated: Razmerje opravljenega zahtevka posodobljeno.
+  error_workflow_copy_source: Prosimo izberite vir zahtevka ali vlogo
+  label_update_issue_done_ratios: Posodobi razmerje opravljenega zahtevka
+  setting_start_of_week: ZaÄni koledarje z
+  permission_view_issues: Poglej zahtevke
+  label_display_used_statuses_only: PrikaÅ¾i samo stanja ki uporabljajo ta sledilnik
+  label_revision_id: Revizija %{value}
+  label_api_access_key: API dostopni kljuÄ
+  label_api_access_key_created_on: API dostopni kljuÄ ustvarjen pred %{value}
+  label_feeds_access_key: RSS dostopni kljuÄ
+  notice_api_access_key_reseted: VaÅ¡ API dostopni kljuÄ je bil ponastavljen.
+  setting_rest_api_enabled: OmogoÄi REST spletni servis
+  label_missing_api_access_key: ManjkajoÄ API dostopni kljuÄ
+  label_missing_feeds_access_key: ManjkajoÄ RSS dostopni kljuÄ
+  button_show: PrikaÅ¾i
+  text_line_separated: Dovoljenih veÄ vrednosti (ena vrstica za vsako vrednost).
+  setting_mail_handler_body_delimiters: OdreÅ¾i e-poÅ¡to po eni od teh vrstic
+  permission_add_subprojects: Ustvari podprojekte
+  label_subproject_new: Nov podprojekt
+  text_own_membership_delete_confirmation: |-
+    Odstranili boste nekatere ali vse od dovoljenj zaradi Äesar morda ne boste mogli veÄ urejati tega projekta.
+    Ali ste prepriÄani, da Å¾elite nadaljevati?
+  label_close_versions: Zapri dokonÄane verzije
+  label_board_sticky: Lepljivo
+  label_board_locked: Zaklenjeno
+  permission_export_wiki_pages: Izvozi wiki strani
+  setting_cache_formatted_text: Predpomni oblikovano besedilo
+  permission_manage_project_activities: Uredi aktivnosti projekta
+  error_unable_delete_issue_status: Stanja zahtevka ni bilo moÅ¾no spremeniti
+  label_profile: Profil
+  permission_manage_subtasks: Uredi podnaloge
+  field_parent_issue: Nadrejena naloga
+  label_subtask_plural: Podnaloge
+  label_project_copy_notifications: Med kopiranjem projekta poÅ¡lji e-poÅ¡tno sporoÄilo
+  error_can_not_delete_custom_field: Polja po meri ni mogoÄe izbrisati
+  error_unable_to_connect: Povezava ni mogoÄa (%{value})
+  error_can_not_remove_role: Ta vloga je v uporabi in je ni mogoÄe izbrisati.
+  error_can_not_delete_tracker: Ta sledilnik vsebuje zahtevke in se ga ne more izbrisati.
+  field_principal: Upravnik varnosti
+  label_my_page_block: Moj gradnik strani
+  notice_failed_to_save_members: "Shranjevanje uporabnika(ov) ni uspelo: %{errors}."
+  text_zoom_out: PribliÅ¾aj
+  text_zoom_in: Oddalji
+  notice_unable_delete_time_entry: Brisanje dnevnika porabljenaga Äasa ni mogoÄe.
+  label_overall_spent_time: Skupni porabljeni Äas
+  field_time_entries: BeleÅ¾i porabljeni Äas
+  project_module_gantt: Gantogram
+  project_module_calendar: Koledear
+  button_edit_associated_wikipage: "Uredi povezano Wiki stran: %{page_title}"
+  field_text: Besedilno polje
+  label_user_mail_option_only_owner: Samo za stvari katerih lastnik sem
+  setting_default_notification_option: Privzeta moÅ¾nost obveÅ¡Äanja
+  label_user_mail_option_only_my_events: Samo za stvari, ki jih opazujem ali sem v njih vpleten
+  label_user_mail_option_only_assigned: Samo za stvari, ki smo mi dodeljene
+  label_user_mail_option_none: Noben dogodek
+  field_member_of_group: PooblaÅ¡ÄenÄeva skupina
+  field_assigned_to_role: PooblaÅ¡ÄenÄeva vloga
+  notice_not_authorized_archived_project: Projekt, do katerega poskuÅ¡ate dostopati, je bil arhiviran.
+  label_principal_search: "PoiÅ¡Äi uporabnika ali skupino:"
+  label_user_search: "PoiÅ¡Äi uporabnikia:"
+  field_visible: Viden
+  setting_emails_header: Glava e-poÅ¡te
+  setting_commit_logtime_activity_id: Aktivnost zabeleÅ¾enega Äasa
+  text_time_logged_by_changeset: Uporabljeno v spremembi %{value}.
+  setting_commit_logtime_enabled: OmogoÄi beleÅ¾enje Äasa
+  notice_gantt_chart_truncated: Graf je bil odrezan, ker je prekoraÄil najveÄje dovoljeno Å¡tevilo elementov, ki se jih lahko prikaÅ¾e (%{max})
+  setting_gantt_items_limit: NajveÄje Å¡tevilo elementov prikazano na gantogramu
+  field_warn_on_leaving_unsaved: Opozori me, kadar zapuÅ¡Äam stran z neshranjenim besedilom
+  text_warn_on_leaving_unsaved: Trenutna stran vsebuje neshranjeno besedilo ki bo izgubljeno, Äe zapustite to stran.
+  label_my_queries: Moje poizvedbe po meri
+  text_journal_changed_no_detail: "%{label} posodobljen"
+  label_news_comment_added: Komentar dodan novici
+  button_expand_all: RazÅ¡iri vse
+  button_collapse_all: SkrÄi vse
+  label_additional_workflow_transitions_for_assignee: Dovoljeni dodatni prehodi kadar je uporabnik pooblaÅ¡Äenec
+  label_additional_workflow_transitions_for_author: Dovoljeni dodatni prehodi kadar je uporabnik avtor
+  label_bulk_edit_selected_time_entries: Skupinsko urejanje izbranih Äasovnih zapisov
+  text_time_entries_destroy_confirmation: Ali ste prepriÄani, da Å¾elite izbristai izbran(e) Äasovn(i/e) zapis(e)?
+  label_role_anonymous: Anonimni
+  label_role_non_member: NeÄlan
+  label_issue_note_added: Dodan zaznamek
+  label_issue_status_updated: Status posodobljen
+  label_issue_priority_updated: Prioriteta posodobljena
+  label_issues_visibility_own: Zahtevek ustvarjen s strani uporabnika ali dodeljen uporabniku
+  field_issues_visibility: Vidljivost zahtevkov
+  label_issues_visibility_all: Vsi zahtevki
+  permission_set_own_issues_private: Nastavi lastne zahtevke kot javne ali zasebne
+  field_is_private: Zaseben
+  permission_set_issues_private: Nastavi zahtevke kot javne ali zasebne
+  label_issues_visibility_public: Vsi nezasebni zahtevki
+  text_issues_destroy_descendants_confirmation: To bo izbrisalo tudi  %{count} podnalog(o).
+  field_commit_logs_encoding: Kodiranje sporoÄil ob predaji
+  field_scm_path_encoding: Pot do kodiranja
+  text_scm_path_encoding_note: "Privzeto: UTF-8"
+  field_path_to_repository: Pot do shrambe
+  field_root_directory: Korenska mapa
+  field_cvs_module: Modul
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Lokalna shramba (npr. /hgrepo, c:\hgrepo)
+  text_scm_command: Ukaz
+  text_scm_command_version: Verzija
+  label_git_report_last_commit: SporoÄi zadnje uveljavljanje datotek in map
+  text_scm_config: Svoje SCM ukaze lahko nastavite v datoteki config/configuration.yml. Po urejanju prosimo ponovno zaÅ¾enite aplikacijo.
+  text_scm_command_not_available: SCM ukaz ni na voljo. Prosimo preverite nastavitve v upravljalskem podoknu.
+
+  text_git_repository_note: Shramba je prazna in lokalna (npr. /gitrepo, c:\gitrepo)
+
+  notice_issue_successful_create: Ustvarjen zahtevek %{id}.
+  label_between: med
+  setting_issue_group_assignment: Dovoli dodeljevanje zahtevka skupinam
+  label_diff: diff
+
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 zahtevek
+    one:   1 zahtevek
+    other: "%{count} zahtevki"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: vsi
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: S podprojekti
+  label_cross_project_tree: Z drevesom projekta
+  label_cross_project_hierarchy: S projektno hierarhijo
+  label_cross_project_system: Z vsemi projekti
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Skupaj
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/26/269ba2765067adff083d346c53c1c4aac3a7ed83.svn-base
--- a/.svn/pristine/26/269ba2765067adff083d346c53c1c4aac3a7ed83.svn-base
+++ /dev/null
@@ -1,90 +0,0 @@
-module CodeRay
-  
-  # A Hash of all known token kinds and their associated CSS classes.
-  TokenKinds = Hash.new do |h, k|
-    warn 'Undefined Token kind: %p' % [k] if $CODERAY_DEBUG
-    false
-  end
-  
-  # speedup
-  TokenKinds.compare_by_identity if TokenKinds.respond_to? :compare_by_identity
-  
-  TokenKinds.update(  # :nodoc:
-    :annotation          => 'annotation',
-    :attribute_name      => 'attribute-name',
-    :attribute_value     => 'attribute-value',
-    :binary              => 'bin',
-    :char                => 'char',
-    :class               => 'class',
-    :class_variable      => 'class-variable',
-    :color               => 'color',
-    :comment             => 'comment',
-    :complex             => 'complex',
-    :constant            => 'constant',
-    :content             => 'content',
-    :debug               => 'debug',
-    :decorator           => 'decorator',
-    :definition          => 'definition',
-    :delimiter           => 'delimiter',
-    :directive           => 'directive',
-    :doc                 => 'doc',
-    :doctype             => 'doctype',
-    :doc_string          => 'doc-string',
-    :entity              => 'entity',
-    :error               => 'error',
-    :escape              => 'escape',
-    :exception           => 'exception',
-    :filename            => 'filename',
-    :float               => 'float',
-    :function            => 'function',
-    :global_variable     => 'global-variable',
-    :hex                 => 'hex',
-    :imaginary           => 'imaginary',
-    :important           => 'important',
-    :include             => 'include',
-    :inline              => 'inline',
-    :inline_delimiter    => 'inline-delimiter',
-    :instance_variable   => 'instance-variable',
-    :integer             => 'integer',
-    :key                 => 'key',
-    :keyword             => 'keyword',
-    :label               => 'label',
-    :local_variable      => 'local-variable',
-    :modifier            => 'modifier',
-    :namespace           => 'namespace',
-    :octal               => 'octal',
-    :predefined          => 'predefined',
-    :predefined_constant => 'predefined-constant',
-    :predefined_type     => 'predefined-type',
-    :preprocessor        => 'preprocessor',
-    :pseudo_class        => 'pseudo-class',
-    :regexp              => 'regexp',
-    :reserved            => 'reserved',
-    :shell               => 'shell',
-    :string              => 'string',
-    :symbol              => 'symbol',
-    :tag                 => 'tag',
-    :type                => 'type',
-    :value               => 'value',
-    :variable            => 'variable',
-    
-    :change              => 'change',
-    :delete              => 'delete',
-    :head                => 'head',
-    :insert              => 'insert',
-    
-    :eyecatcher          => 'eyecatcher',
-    
-    :ident               => false,
-    :operator            => false,
-    
-    :space               => false,
-    :plain               => false
-  )
-  
-  TokenKinds[:method]    = TokenKinds[:function]
-  TokenKinds[:escape]    = TokenKinds[:delimiter]
-  TokenKinds[:docstring] = TokenKinds[:comment]
-  
-  TokenKinds.freeze
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/26/26d9747ae706cea5f68ea0007e9fb7e1bf0c8d18.svn-base
--- /dev/null
+++ b/.svn/pristine/26/26d9747ae706cea5f68ea0007e9fb7e1bf0c8d18.svn-base
@@ -0,0 +1,76 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class CustomFieldVersionFormatTest < ActiveSupport::TestCase
+  fixtures :custom_fields, :projects, :members, :users, :member_roles, :trackers, :issues, :versions
+
+  def setup
+    @field = IssueCustomField.create!(:name => 'Tester', :field_format => 'version')
+  end
+
+  def test_possible_values_with_no_arguments
+    assert_equal [], @field.possible_values
+    assert_equal [], @field.possible_values(nil)
+  end
+
+  def test_possible_values_with_project_resource
+    project = Project.find(1)
+    possible_values = @field.possible_values(project.issues.first)
+    assert possible_values.any?
+    assert_equal project.shared_versions.sort.collect(&:id).map(&:to_s), possible_values
+  end
+
+  def test_possible_values_with_nil_project_resource
+    assert_equal [], @field.possible_values(Issue.new)
+  end
+
+  def test_possible_values_options_with_no_arguments
+    assert_equal [], @field.possible_values_options
+    assert_equal [], @field.possible_values_options(nil)
+  end
+
+  def test_possible_values_options_with_project_resource
+    project = Project.find(1)
+    possible_values_options = @field.possible_values_options(project.issues.first)
+    assert possible_values_options.any?
+    assert_equal project.shared_versions.sort.map {|u| [u.name, u.id.to_s]}, possible_values_options
+  end
+
+  def test_possible_values_options_with_array
+    projects = Project.find([1, 2])
+    possible_values_options = @field.possible_values_options(projects)
+    assert possible_values_options.any?
+    assert_equal (projects.first.shared_versions & projects.last.shared_versions).sort.map {|u| [u.name, u.id.to_s]}, possible_values_options
+  end
+
+  def test_cast_blank_value
+    assert_equal nil, @field.cast_value(nil)
+    assert_equal nil, @field.cast_value("")
+  end
+
+  def test_cast_valid_value
+    version = @field.cast_value("2")
+    assert_kind_of Version, version
+    assert_equal Version.find(2), version
+  end
+
+  def test_cast_invalid_value
+    assert_equal nil, @field.cast_value("187")
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/26/26f2b8dec33ec3e8eb2d5b55094ac09d33160993.svn-base
--- a/.svn/pristine/26/26f2b8dec33ec3e8eb2d5b55094ac09d33160993.svn-base
+++ /dev/null
@@ -1,603 +0,0 @@
-require File.dirname(__FILE__) + '/test_helper'
-
-class Note < ActiveRecord::Base
-  acts_as_nested_set :scope => [:notable_id, :notable_type]
-end
-
-class AwesomeNestedSetTest < Test::Unit::TestCase
-
-  class Default < ActiveRecord::Base
-    acts_as_nested_set
-    set_table_name 'categories'
-  end
-  class Scoped < ActiveRecord::Base
-    acts_as_nested_set :scope => :organization
-    set_table_name 'categories'
-  end
-
-  def test_left_column_default
-    assert_equal 'lft', Default.acts_as_nested_set_options[:left_column]
-  end
-
-  def test_right_column_default
-    assert_equal 'rgt', Default.acts_as_nested_set_options[:right_column]
-  end
-
-  def test_parent_column_default
-    assert_equal 'parent_id', Default.acts_as_nested_set_options[:parent_column]
-  end
-
-  def test_scope_default
-    assert_nil Default.acts_as_nested_set_options[:scope]
-  end
-  
-  def test_left_column_name
-    assert_equal 'lft', Default.left_column_name
-    assert_equal 'lft', Default.new.left_column_name
-  end
-
-  def test_right_column_name
-    assert_equal 'rgt', Default.right_column_name
-    assert_equal 'rgt', Default.new.right_column_name
-  end
-
-  def test_parent_column_name
-    assert_equal 'parent_id', Default.parent_column_name
-    assert_equal 'parent_id', Default.new.parent_column_name
-  end
-  
-  def test_quoted_left_column_name
-    quoted = Default.connection.quote_column_name('lft')
-    assert_equal quoted, Default.quoted_left_column_name
-    assert_equal quoted, Default.new.quoted_left_column_name
-  end
-
-  def test_quoted_right_column_name
-    quoted = Default.connection.quote_column_name('rgt')
-    assert_equal quoted, Default.quoted_right_column_name
-    assert_equal quoted, Default.new.quoted_right_column_name
-  end
-
-  def test_left_column_protected_from_assignment
-    assert_raises(ActiveRecord::ActiveRecordError) { Category.new.lft = 1 }
-  end
-  
-  def test_right_column_protected_from_assignment
-    assert_raises(ActiveRecord::ActiveRecordError) { Category.new.rgt = 1 }
-  end
-  
-  def test_parent_column_protected_from_assignment
-    assert_raises(ActiveRecord::ActiveRecordError) { Category.new.parent_id = 1 }
-  end
-  
-  def test_colums_protected_on_initialize
-    c = Category.new(:lft => 1, :rgt => 2, :parent_id => 3)
-    assert_nil c.lft
-    assert_nil c.rgt
-    assert_nil c.parent_id
-  end
-  
-  def test_scoped_appends_id
-    assert_equal :organization_id, Scoped.acts_as_nested_set_options[:scope]
-  end
-  
-  def test_roots_class_method
-    assert_equal Category.find_all_by_parent_id(nil), Category.roots
-  end
-    
-  def test_root_class_method
-    assert_equal categories(:top_level), Category.root
-  end
-  
-  def test_root
-    assert_equal categories(:top_level), categories(:child_3).root
-  end
-  
-  def test_root?
-    assert categories(:top_level).root?
-    assert categories(:top_level_2).root?
-  end
-  
-  def test_leaves_class_method
-    assert_equal Category.find(:all, :conditions => "#{Category.right_column_name} - #{Category.left_column_name} = 1"), Category.leaves
-    assert_equal Category.leaves.count, 4
-    assert (Category.leaves.include? categories(:child_1))
-    assert (Category.leaves.include? categories(:child_2_1))
-    assert (Category.leaves.include? categories(:child_3))
-    assert (Category.leaves.include? categories(:top_level_2))
-  end
-  
-  def test_leaf
-    assert categories(:child_1).leaf?
-    assert categories(:child_2_1).leaf?
-    assert categories(:child_3).leaf?
-    assert categories(:top_level_2).leaf?
-    
-    assert !categories(:top_level).leaf?
-    assert !categories(:child_2).leaf?
-  end
-    
-  def test_parent
-    assert_equal categories(:child_2), categories(:child_2_1).parent
-  end
-  
-  def test_self_and_ancestors
-    child = categories(:child_2_1)
-    self_and_ancestors = [categories(:top_level), categories(:child_2), child]
-    assert_equal self_and_ancestors, child.self_and_ancestors
-  end
-
-  def test_ancestors
-    child = categories(:child_2_1)
-    ancestors = [categories(:top_level), categories(:child_2)]
-    assert_equal ancestors, child.ancestors
-  end
-  
-  def test_self_and_siblings
-    child = categories(:child_2)
-    self_and_siblings = [categories(:child_1), child, categories(:child_3)]
-    assert_equal self_and_siblings, child.self_and_siblings
-    assert_nothing_raised do
-      tops = [categories(:top_level), categories(:top_level_2)]
-      assert_equal tops, categories(:top_level).self_and_siblings
-    end
-  end
-
-  def test_siblings
-    child = categories(:child_2)
-    siblings = [categories(:child_1), categories(:child_3)]
-    assert_equal siblings, child.siblings
-  end
-  
-  def test_leaves
-    leaves = [categories(:child_1), categories(:child_2_1), categories(:child_3), categories(:top_level_2)]
-    assert categories(:top_level).leaves, leaves
-  end
-  
-  def test_level
-    assert_equal 0, categories(:top_level).level
-    assert_equal 1, categories(:child_1).level
-    assert_equal 2, categories(:child_2_1).level
-  end
-  
-  def test_has_children?
-    assert categories(:child_2_1).children.empty?
-    assert !categories(:child_2).children.empty?
-    assert !categories(:top_level).children.empty?
-  end
-  
-  def test_self_and_descendents
-    parent = categories(:top_level)
-    self_and_descendants = [parent, categories(:child_1), categories(:child_2),
-      categories(:child_2_1), categories(:child_3)]
-    assert_equal self_and_descendants, parent.self_and_descendants
-    assert_equal self_and_descendants, parent.self_and_descendants.count
-  end
-  
-  def test_descendents
-    lawyers = Category.create!(:name => "lawyers")
-    us = Category.create!(:name => "United States")
-    us.move_to_child_of(lawyers)
-    patent = Category.create!(:name => "Patent Law")
-    patent.move_to_child_of(us)
-    lawyers.reload
-
-    assert_equal 1, lawyers.children.size
-    assert_equal 1, us.children.size
-    assert_equal 2, lawyers.descendants.size
-  end
-  
-  def test_self_and_descendents
-    parent = categories(:top_level)
-    descendants = [categories(:child_1), categories(:child_2),
-      categories(:child_2_1), categories(:child_3)]
-    assert_equal descendants, parent.descendants
-  end
-  
-  def test_children
-    category = categories(:top_level)
-    category.children.each {|c| assert_equal category.id, c.parent_id }
-  end
-  
-  def test_is_or_is_ancestor_of?
-    assert categories(:top_level).is_or_is_ancestor_of?(categories(:child_1))
-    assert categories(:top_level).is_or_is_ancestor_of?(categories(:child_2_1))
-    assert categories(:child_2).is_or_is_ancestor_of?(categories(:child_2_1))
-    assert !categories(:child_2_1).is_or_is_ancestor_of?(categories(:child_2))
-    assert !categories(:child_1).is_or_is_ancestor_of?(categories(:child_2))
-    assert categories(:child_1).is_or_is_ancestor_of?(categories(:child_1))
-  end
-  
-  def test_is_ancestor_of?
-    assert categories(:top_level).is_ancestor_of?(categories(:child_1))
-    assert categories(:top_level).is_ancestor_of?(categories(:child_2_1))
-    assert categories(:child_2).is_ancestor_of?(categories(:child_2_1))
-    assert !categories(:child_2_1).is_ancestor_of?(categories(:child_2))
-    assert !categories(:child_1).is_ancestor_of?(categories(:child_2))
-    assert !categories(:child_1).is_ancestor_of?(categories(:child_1))
-  end
-
-  def test_is_or_is_ancestor_of_with_scope
-    root = Scoped.root
-    child = root.children.first
-    assert root.is_or_is_ancestor_of?(child)
-    child.update_attribute :organization_id, 'different'
-    assert !root.is_or_is_ancestor_of?(child)
-  end
-
-  def test_is_or_is_descendant_of?
-    assert categories(:child_1).is_or_is_descendant_of?(categories(:top_level))
-    assert categories(:child_2_1).is_or_is_descendant_of?(categories(:top_level))
-    assert categories(:child_2_1).is_or_is_descendant_of?(categories(:child_2))
-    assert !categories(:child_2).is_or_is_descendant_of?(categories(:child_2_1))
-    assert !categories(:child_2).is_or_is_descendant_of?(categories(:child_1))
-    assert categories(:child_1).is_or_is_descendant_of?(categories(:child_1))
-  end
-  
-  def test_is_descendant_of?
-    assert categories(:child_1).is_descendant_of?(categories(:top_level))
-    assert categories(:child_2_1).is_descendant_of?(categories(:top_level))
-    assert categories(:child_2_1).is_descendant_of?(categories(:child_2))
-    assert !categories(:child_2).is_descendant_of?(categories(:child_2_1))
-    assert !categories(:child_2).is_descendant_of?(categories(:child_1))
-    assert !categories(:child_1).is_descendant_of?(categories(:child_1))
-  end
-  
-  def test_is_or_is_descendant_of_with_scope
-    root = Scoped.root
-    child = root.children.first
-    assert child.is_or_is_descendant_of?(root)
-    child.update_attribute :organization_id, 'different'
-    assert !child.is_or_is_descendant_of?(root)
-  end
-  
-  def test_same_scope?
-    root = Scoped.root
-    child = root.children.first
-    assert child.same_scope?(root)
-    child.update_attribute :organization_id, 'different'
-    assert !child.same_scope?(root)
-  end
-  
-  def test_left_sibling
-    assert_equal categories(:child_1), categories(:child_2).left_sibling
-    assert_equal categories(:child_2), categories(:child_3).left_sibling
-  end
-
-  def test_left_sibling_of_root
-    assert_nil categories(:top_level).left_sibling
-  end
-
-  def test_left_sibling_without_siblings
-    assert_nil categories(:child_2_1).left_sibling
-  end
-
-  def test_left_sibling_of_leftmost_node
-    assert_nil categories(:child_1).left_sibling
-  end
-
-  def test_right_sibling
-    assert_equal categories(:child_3), categories(:child_2).right_sibling
-    assert_equal categories(:child_2), categories(:child_1).right_sibling
-  end
-
-  def test_right_sibling_of_root
-    assert_equal categories(:top_level_2), categories(:top_level).right_sibling
-    assert_nil categories(:top_level_2).right_sibling
-  end
-
-  def test_right_sibling_without_siblings
-    assert_nil categories(:child_2_1).right_sibling
-  end
-
-  def test_right_sibling_of_rightmost_node
-    assert_nil categories(:child_3).right_sibling
-  end
-  
-  def test_move_left
-    categories(:child_2).move_left
-    assert_nil categories(:child_2).left_sibling
-    assert_equal categories(:child_1), categories(:child_2).right_sibling
-    assert Category.valid?
-  end
-
-  def test_move_right
-    categories(:child_2).move_right
-    assert_nil categories(:child_2).right_sibling
-    assert_equal categories(:child_3), categories(:child_2).left_sibling
-    assert Category.valid?
-  end
-
-  def test_move_to_left_of
-    categories(:child_3).move_to_left_of(categories(:child_1))
-    assert_nil categories(:child_3).left_sibling
-    assert_equal categories(:child_1), categories(:child_3).right_sibling
-    assert Category.valid?
-  end
-
-  def test_move_to_right_of
-    categories(:child_1).move_to_right_of(categories(:child_3))
-    assert_nil categories(:child_1).right_sibling
-    assert_equal categories(:child_3), categories(:child_1).left_sibling
-    assert Category.valid?
-  end
-  
-  def test_move_to_root
-    categories(:child_2).move_to_root
-    assert_nil categories(:child_2).parent
-    assert_equal 0, categories(:child_2).level
-    assert_equal 1, categories(:child_2_1).level
-    assert_equal 1, categories(:child_2).left
-    assert_equal 4, categories(:child_2).right
-    assert Category.valid?
-  end
-
-  def test_move_to_child_of
-    categories(:child_1).move_to_child_of(categories(:child_3))
-    assert_equal categories(:child_3).id, categories(:child_1).parent_id
-    assert Category.valid?
-  end
-  
-  def test_move_to_child_of_appends_to_end
-    child = Category.create! :name => 'New Child'
-    child.move_to_child_of categories(:top_level)
-    assert_equal child, categories(:top_level).children.last
-  end
-  
-  def test_subtree_move_to_child_of
-    assert_equal 4, categories(:child_2).left
-    assert_equal 7, categories(:child_2).right
-    
-    assert_equal 2, categories(:child_1).left
-    assert_equal 3, categories(:child_1).right
-    
-    categories(:child_2).move_to_child_of(categories(:child_1))
-    assert Category.valid?
-    assert_equal categories(:child_1).id, categories(:child_2).parent_id
-    
-    assert_equal 3, categories(:child_2).left
-    assert_equal 6, categories(:child_2).right
-    assert_equal 2, categories(:child_1).left
-    assert_equal 7, categories(:child_1).right    
-  end
-  
-  def test_slightly_difficult_move_to_child_of
-    assert_equal 11, categories(:top_level_2).left
-    assert_equal 12, categories(:top_level_2).right
-    
-    # create a new top-level node and move single-node top-level tree inside it.
-    new_top = Category.create(:name => 'New Top')
-    assert_equal 13, new_top.left
-    assert_equal 14, new_top.right
-    
-    categories(:top_level_2).move_to_child_of(new_top)
-    
-    assert Category.valid?
-    assert_equal new_top.id, categories(:top_level_2).parent_id
-    
-    assert_equal 12, categories(:top_level_2).left
-    assert_equal 13, categories(:top_level_2).right
-    assert_equal 11, new_top.left
-    assert_equal 14, new_top.right    
-  end
-  
-  def test_difficult_move_to_child_of
-    assert_equal 1, categories(:top_level).left
-    assert_equal 10, categories(:top_level).right
-    assert_equal 5, categories(:child_2_1).left
-    assert_equal 6, categories(:child_2_1).right
-    
-    # create a new top-level node and move an entire top-level tree inside it.
-    new_top = Category.create(:name => 'New Top')
-    categories(:top_level).move_to_child_of(new_top)
-    categories(:child_2_1).reload
-    assert Category.valid?  
-    assert_equal new_top.id, categories(:top_level).parent_id
-    
-    assert_equal 4, categories(:top_level).left
-    assert_equal 13, categories(:top_level).right
-    assert_equal 8, categories(:child_2_1).left
-    assert_equal 9, categories(:child_2_1).right    
-  end
-
-  #rebuild swaps the position of the 2 children when added using move_to_child twice onto same parent
-  def test_move_to_child_more_than_once_per_parent_rebuild
-    root1 = Category.create(:name => 'Root1')
-    root2 = Category.create(:name => 'Root2')
-    root3 = Category.create(:name => 'Root3')
-    
-    root2.move_to_child_of root1
-    root3.move_to_child_of root1
-      
-    output = Category.roots.last.to_text
-    Category.update_all('lft = null, rgt = null')
-    Category.rebuild!
-    
-    assert_equal Category.roots.last.to_text, output
-  end
-  
-  # doing move_to_child twice onto same parent from the furthest right first
-  def test_move_to_child_more_than_once_per_parent_outside_in
-    node1 = Category.create(:name => 'Node-1')
-    node2 = Category.create(:name => 'Node-2')
-    node3 = Category.create(:name => 'Node-3')
-    
-    node2.move_to_child_of node1
-    node3.move_to_child_of node1
-      
-    output = Category.roots.last.to_text
-    Category.update_all('lft = null, rgt = null')
-    Category.rebuild!
-    
-    assert_equal Category.roots.last.to_text, output
-  end
-
-
-  def test_valid_with_null_lefts
-    assert Category.valid?
-    Category.update_all('lft = null')
-    assert !Category.valid?
-  end
-
-  def test_valid_with_null_rights
-    assert Category.valid?
-    Category.update_all('rgt = null')
-    assert !Category.valid?
-  end
-  
-  def test_valid_with_missing_intermediate_node
-    # Even though child_2_1 will still exist, it is a sign of a sloppy delete, not an invalid tree.
-    assert Category.valid?
-    Category.delete(categories(:child_2).id)
-    assert Category.valid?
-  end
-  
-  def test_valid_with_overlapping_and_rights
-    assert Category.valid?
-    categories(:top_level_2)['lft'] = 0
-    categories(:top_level_2).save
-    assert !Category.valid?
-  end
-  
-  def test_rebuild
-    assert Category.valid?
-    before_text = Category.root.to_text
-    Category.update_all('lft = null, rgt = null')
-    Category.rebuild!
-    assert Category.valid?
-    assert_equal before_text, Category.root.to_text
-  end
-  
-  def test_move_possible_for_sibling
-    assert categories(:child_2).move_possible?(categories(:child_1))
-  end
-  
-  def test_move_not_possible_to_self
-    assert !categories(:top_level).move_possible?(categories(:top_level))
-  end
-  
-  def test_move_not_possible_to_parent
-    categories(:top_level).descendants.each do |descendant|
-      assert !categories(:top_level).move_possible?(descendant)
-      assert descendant.move_possible?(categories(:top_level))
-    end
-  end
-  
-  def test_is_or_is_ancestor_of?
-    [:child_1, :child_2, :child_2_1, :child_3].each do |c|
-      assert categories(:top_level).is_or_is_ancestor_of?(categories(c))
-    end
-    assert !categories(:top_level).is_or_is_ancestor_of?(categories(:top_level_2))
-  end
-  
-  def test_left_and_rights_valid_with_blank_left
-    assert Category.left_and_rights_valid?
-    categories(:child_2)[:lft] = nil
-    categories(:child_2).save(false)
-    assert !Category.left_and_rights_valid?
-  end
-
-  def test_left_and_rights_valid_with_blank_right
-    assert Category.left_and_rights_valid?
-    categories(:child_2)[:rgt] = nil
-    categories(:child_2).save(false)
-    assert !Category.left_and_rights_valid?
-  end
-
-  def test_left_and_rights_valid_with_equal
-    assert Category.left_and_rights_valid?
-    categories(:top_level_2)[:lft] = categories(:top_level_2)[:rgt]
-    categories(:top_level_2).save(false)
-    assert !Category.left_and_rights_valid?
-  end
-
-  def test_left_and_rights_valid_with_left_equal_to_parent
-    assert Category.left_and_rights_valid?
-    categories(:child_2)[:lft] = categories(:top_level)[:lft]
-    categories(:child_2).save(false)
-    assert !Category.left_and_rights_valid?
-  end
-
-  def test_left_and_rights_valid_with_right_equal_to_parent
-    assert Category.left_and_rights_valid?
-    categories(:child_2)[:rgt] = categories(:top_level)[:rgt]
-    categories(:child_2).save(false)
-    assert !Category.left_and_rights_valid?
-  end
-  
-  def test_moving_dirty_objects_doesnt_invalidate_tree
-    r1 = Category.create
-    r2 = Category.create
-    r3 = Category.create
-    r4 = Category.create
-    nodes = [r1, r2, r3, r4]
-    
-    r2.move_to_child_of(r1)
-    assert Category.valid?
-    
-    r3.move_to_child_of(r1)
-    assert Category.valid?
-    
-    r4.move_to_child_of(r2)
-    assert Category.valid?
-  end
-  
-  def test_multi_scoped_no_duplicates_for_columns?
-    assert_nothing_raised do
-      Note.no_duplicates_for_columns?
-    end
-  end
-
-  def test_multi_scoped_all_roots_valid?
-    assert_nothing_raised do
-      Note.all_roots_valid?
-    end
-  end
-
-  def test_multi_scoped
-    note1 = Note.create!(:body => "A", :notable_id => 2, :notable_type => 'Category')
-    note2 = Note.create!(:body => "B", :notable_id => 2, :notable_type => 'Category')
-    note3 = Note.create!(:body => "C", :notable_id => 2, :notable_type => 'Default')
-    
-    assert_equal [note1, note2], note1.self_and_siblings
-    assert_equal [note3], note3.self_and_siblings
-  end
-  
-  def test_multi_scoped_rebuild
-    root = Note.create!(:body => "A", :notable_id => 3, :notable_type => 'Category')
-    child1 = Note.create!(:body => "B", :notable_id => 3, :notable_type => 'Category')
-    child2 = Note.create!(:body => "C", :notable_id => 3, :notable_type => 'Category')
-    
-    child1.move_to_child_of root
-    child2.move_to_child_of root
-          
-    Note.update_all('lft = null, rgt = null')
-    Note.rebuild!
-    
-    assert_equal Note.roots.find_by_body('A'), root
-    assert_equal [child1, child2], Note.roots.find_by_body('A').children
-  end
-  
-  def test_same_scope_with_multi_scopes
-    assert_nothing_raised do
-      notes(:scope1).same_scope?(notes(:child_1))
-    end
-    assert notes(:scope1).same_scope?(notes(:child_1))
-    assert notes(:child_1).same_scope?(notes(:scope1))
-    assert !notes(:scope1).same_scope?(notes(:scope2))
-  end
-  
-  def test_quoting_of_multi_scope_column_names
-    assert_equal ["\"notable_id\"", "\"notable_type\""], Note.quoted_scope_column_names
-  end
-  
-  def test_equal_in_same_scope
-    assert_equal notes(:scope1), notes(:scope1)
-    assert_not_equal notes(:scope1), notes(:child_1)
-  end
-  
-  def test_equal_in_different_scopes
-    assert_not_equal notes(:scope1), notes(:scope2)
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/270c9debef33419abbdab93ac142c4646e6e19cf.svn-base
--- /dev/null
+++ b/.svn/pristine/27/270c9debef33419abbdab93ac142c4646e6e19cf.svn-base
@@ -0,0 +1,67 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ReportsControllerTest < ActionController::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :versions
+
+  def test_get_issue_report
+    get :issue_report, :id => 1
+
+    assert_response :success
+    assert_template 'issue_report'
+
+    [:issues_by_tracker, :issues_by_version, :issues_by_category, :issues_by_assigned_to,
+     :issues_by_author, :issues_by_subproject, :issues_by_priority].each do |ivar|
+      assert_not_nil assigns(ivar)
+    end
+
+    assert_equal IssuePriority.all.reverse, assigns(:priorities)
+  end
+
+  def test_get_issue_report_details
+    %w(tracker version priority category assigned_to author subproject).each do |detail|
+      get :issue_report_details, :id => 1, :detail => detail
+
+      assert_response :success
+      assert_template 'issue_report_details'
+      assert_not_nil assigns(:field)
+      assert_not_nil assigns(:rows)
+      assert_not_nil assigns(:data)
+      assert_not_nil assigns(:report_title)
+    end
+  end
+
+  def test_get_issue_report_details_by_priority
+    get :issue_report_details, :id => 1, :detail => 'priority'
+    assert_equal IssuePriority.all.reverse, assigns(:rows)
+  end
+
+  def test_get_issue_report_details_with_an_invalid_detail
+    get :issue_report_details, :id => 1, :detail => 'invalid'
+
+    assert_redirected_to '/projects/ecookbook/issues/report'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/273ac825eb891aaec6af1c5e2e94f14d0663c303.svn-base
--- a/.svn/pristine/27/273ac825eb891aaec6af1c5e2e94f14d0663c303.svn-base
+++ /dev/null
@@ -1,61 +0,0 @@
-module CodeRay
-module Encoders
-  
-  # = Debug Encoder
-  #
-  # Fast encoder producing simple debug output.
-  #
-  # It is readable and diff-able and is used for testing.
-  #
-  # You cannot fully restore the tokens information from the
-  # output, because consecutive :space tokens are merged.
-  # Use Tokens#dump for caching purposes.
-  # 
-  # See also: Scanners::Debug
-  class Debug < Encoder
-    
-    register_for :debug
-    
-    FILE_EXTENSION = 'raydebug'
-    
-    def initialize options = {}
-      super
-      @opened = []
-    end
-    
-    def text_token text, kind
-      if kind == :space
-        @out << text
-      else
-        # TODO: Escape (
-        text = text.gsub(/[)\\]/, '\\\\\0')  # escape ) and \
-        @out << kind.to_s << '(' << text << ')'
-      end
-    end
-    
-    def begin_group kind
-      @opened << kind
-      @out << kind.to_s << '<'
-    end
-    
-    def end_group kind
-      if @opened.last != kind
-        puts @out
-        raise "we are inside #{@opened.inspect}, not #{kind}"
-      end
-      @opened.pop
-      @out << '>'
-    end
-    
-    def begin_line kind
-      @out << kind.to_s << '['
-    end
-    
-    def end_line kind
-      @out << ']'
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/2745a50d7301c30263d5450e181481b6eeb6b406.svn-base
--- /dev/null
+++ b/.svn/pristine/27/2745a50d7301c30263d5450e181481b6eeb6b406.svn-base
@@ -0,0 +1,106 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::CipheringTest < ActiveSupport::TestCase
+
+  def test_password_should_be_encrypted
+    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
+      r = Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'svn')
+      assert_equal 'foo', r.password
+      assert r.read_attribute(:password).match(/\Aaes-256-cbc:.+\Z/)
+    end
+  end
+
+  def test_password_should_be_clear_with_blank_key
+    Redmine::Configuration.with 'database_cipher_key' => '' do
+      r = Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'svn')
+      assert_equal 'foo', r.password
+      assert_equal 'foo', r.read_attribute(:password)
+    end
+  end
+
+  def test_password_should_be_clear_with_nil_key
+    Redmine::Configuration.with 'database_cipher_key' => nil do
+      r = Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'svn')
+      assert_equal 'foo', r.password
+      assert_equal 'foo', r.read_attribute(:password)
+    end
+  end
+
+  def test_blank_password_should_be_clear
+    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
+      r = Repository::Subversion.create!(:password => '', :url => 'file:///tmp', :identifier => 'svn')
+      assert_equal '', r.password
+      assert_equal '', r.read_attribute(:password)
+    end
+  end
+
+  def test_unciphered_password_should_be_readable
+    Redmine::Configuration.with 'database_cipher_key' => nil do
+      r = Repository::Subversion.create!(:password => 'clear', :url => 'file:///tmp', :identifier => 'svn')
+    end
+
+    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
+      r = Repository.first(:order => 'id DESC')
+      assert_equal 'clear', r.password
+    end
+  end
+  
+  def test_ciphered_password_with_no_cipher_key_configured_should_be_returned_ciphered
+    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
+      r = Repository::Subversion.create!(:password => 'clear', :url => 'file:///tmp', :identifier => 'svn')
+    end
+
+    Redmine::Configuration.with 'database_cipher_key' => '' do
+      r = Repository.first(:order => 'id DESC')
+      # password can not be deciphered
+      assert_nothing_raised do
+        assert r.password.match(/\Aaes-256-cbc:.+\Z/)
+      end
+    end
+  end
+
+  def test_encrypt_all
+    Repository.delete_all
+    Redmine::Configuration.with 'database_cipher_key' => nil do
+      Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'foo')
+      Repository::Subversion.create!(:password => 'bar', :url => 'file:///tmp', :identifier => 'bar')
+    end
+
+    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
+      assert Repository.encrypt_all(:password)
+      r = Repository.first(:order => 'id DESC')
+      assert_equal 'bar', r.password
+      assert r.read_attribute(:password).match(/\Aaes-256-cbc:.+\Z/)
+    end
+  end
+
+  def test_decrypt_all
+    Repository.delete_all
+    Redmine::Configuration.with 'database_cipher_key' => 'secret' do
+      Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'foo')
+      Repository::Subversion.create!(:password => 'bar', :url => 'file:///tmp', :identifier => 'bar')
+
+      assert Repository.decrypt_all(:password)
+      r = Repository.first(:order => 'id DESC')
+      assert_equal 'bar', r.password
+      assert_equal 'bar', r.read_attribute(:password)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/274f3b80c3fec339ad5a9fd2fdcdbd871a6ae2d1.svn-base
--- /dev/null
+++ b/.svn/pristine/27/274f3b80c3fec339ad5a9fd2fdcdbd871a6ae2d1.svn-base
@@ -0,0 +1,69 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../../test_helper', __FILE__)
+begin
+  require 'mocha'
+
+  class DarcsAdapterTest < ActiveSupport::TestCase
+    REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
+
+    if File.directory?(REPOSITORY_PATH)
+      def setup
+        @adapter = Redmine::Scm::Adapters::DarcsAdapter.new(REPOSITORY_PATH)
+      end
+
+      def test_darcsversion
+        to_test = { "1.0.9 (release)\n"  => [1,0,9] ,
+                    "2.2.0 (release)\n"  => [2,2,0] }
+        to_test.each do |s, v|
+          test_darcsversion_for(s, v)
+        end
+      end
+
+      def test_revisions
+        id1 = '20080308225258-98289-761f654d669045eabee90b91b53a21ce5593cadf.gz'
+        revs = @adapter.revisions('', nil, nil, {:with_path => true})
+        assert_equal 6, revs.size
+        assert_equal id1, revs[5].scmid
+        paths = revs[5].paths
+        assert_equal 5, paths.size
+        assert_equal 'A', paths[0][:action]
+        assert_equal '/README', paths[0][:path]
+        assert_equal 'A', paths[1][:action]
+        assert_equal '/images', paths[1][:path]
+      end
+
+      private
+
+      def test_darcsversion_for(darcsversion, version)
+        @adapter.class.expects(:darcs_binary_version_from_command_line).returns(darcsversion)
+        assert_equal version, @adapter.class.darcs_binary_version
+      end
+
+    else
+      puts "Darcs test repository NOT FOUND. Skipping unit tests !!!"
+      def test_fake; assert true end
+    end
+  end
+
+rescue LoadError
+  class DarcsMochaFake < ActiveSupport::TestCase
+    def test_fake; assert(false, "Requires mocha to run those tests")  end
+  end
+end
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/275a63d95374044297ed252103e82089ce4c9a74.svn-base
--- a/.svn/pristine/27/275a63d95374044297ed252103e82089ce4c9a74.svn-base
+++ /dev/null
@@ -1,86 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::AttachmentsTest < ActionController::IntegrationTest
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :attachments
-
-  def setup
-    Setting.rest_api_enabled = '1'
-    Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
-  end
-
-  context "/attachments/:id" do
-    context "GET" do
-      should "return the attachment" do
-        get '/attachments/7.xml', {}, :authorization => credentials('jsmith')
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-        assert_tag :tag => 'attachment',
-          :child => {
-            :tag => 'id',
-            :content => '7',
-            :sibling => {
-              :tag => 'filename',
-              :content => 'archive.zip',
-              :sibling => {
-                :tag => 'content_url',
-                :content => 'http://www.example.com/attachments/download/7/archive.zip'
-              }
-            }
-          }
-      end
-
-      should "deny access without credentials" do
-        get '/attachments/7.xml'
-        assert_response 401
-        set_tmp_attachments_directory
-      end
-    end
-  end
-
-  context "/attachments/download/:id/:filename" do
-    context "GET" do
-      should "return the attachment content" do
-        get '/attachments/download/7/archive.zip',
-            {}, :authorization => credentials('jsmith')
-        assert_response :success
-        assert_equal 'application/octet-stream', @response.content_type
-        set_tmp_attachments_directory
-      end
-
-      should "deny access without credentials" do
-        get '/attachments/download/7/archive.zip'
-        assert_response 302
-        set_tmp_attachments_directory
-      end
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/27952988c7b2ad95ea1ef729436ace0c3896dd74.svn-base
--- a/.svn/pristine/27/27952988c7b2ad95ea1ef729436ace0c3896dd74.svn-base
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
-
-# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
-# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
-require "dispatcher"
-
-ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/2798cf8bdb60e5a48dc833a97dea5cc70e29382c.svn-base
--- a/.svn/pristine/27/2798cf8bdb60e5a48dc833a97dea5cc70e29382c.svn-base
+++ /dev/null
@@ -1,76 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ProjectsHelperTest < ActionView::TestCase
-  include ApplicationHelper
-  include ProjectsHelper
-
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :versions,
-           :projects_trackers,
-           :member_roles,
-           :members,
-           :groups_users,
-           :enabled_modules,
-           :workflows
-
-  def setup
-    super
-    set_language_if_valid('en')
-    User.current = nil
-  end
-
-  def test_link_to_version_within_project
-    @project = Project.find(2)
-    User.current = User.find(1)
-    assert_equal '<a href="/versions/5">Alpha</a>', link_to_version(Version.find(5))
-  end
-
-  def test_link_to_version
-    User.current = User.find(1)
-    assert_equal '<a href="/versions/5">OnlineStore - Alpha</a>', link_to_version(Version.find(5))
-  end
-
-  def test_link_to_private_version
-    assert_equal 'OnlineStore - Alpha', link_to_version(Version.find(5))
-  end
-
-  def test_link_to_version_invalid_version
-    assert_equal '', link_to_version(Object)
-  end
-
-  def test_format_version_name_within_project
-    @project = Project.find(1)
-    assert_equal "0.1", format_version_name(Version.find(1))
-  end
-
-  def test_format_version_name
-    assert_equal "eCookbook - 0.1", format_version_name(Version.find(1))
-  end
-
-  def test_format_version_name_for_system_version
-    assert_equal "OnlineStore - Systemwide visible version", format_version_name(Version.find(7))
-  end
-
-  def test_version_options_for_select_with_no_versions
-    assert_equal '', version_options_for_select([])
-    assert_equal '<option value="1" selected="selected">0.1</option>', version_options_for_select([], Version.find(1))
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/27ca0e4d3dcbae405bcd6b8ff364b70b5542b197.svn-base
--- a/.svn/pristine/27/27ca0e4d3dcbae405bcd6b8ff364b70b5542b197.svn-base
+++ /dev/null
@@ -1,46 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class CustomFieldsHelperTest < ActionView::TestCase
-  include CustomFieldsHelper
-  include Redmine::I18n
-
-  def test_format_boolean_value
-    I18n.locale = 'en'
-    assert_equal 'Yes', format_value('1', 'bool')
-    assert_equal 'No', format_value('0', 'bool')
-  end
-
-  def test_unknow_field_format_should_be_edited_as_string
-    field = CustomField.new(:field_format => 'foo')
-    value = CustomValue.new(:value => 'bar', :custom_field => field)
-    field.id = 52
-
-    assert_equal '<input id="object_custom_field_values_52" name="object[custom_field_values][52]" type="text" value="bar" />',
-      custom_field_tag('object', value)
-  end
-
-  def test_unknow_field_format_should_be_bulk_edited_as_string
-    field = CustomField.new(:field_format => 'foo')
-    field.id = 52
-
-    assert_equal '<input id="object_custom_field_values_52" name="object[custom_field_values][52]" type="text" value="" />',
-      custom_field_tag_for_bulk_edit('object', field)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/27ce56818e709e285d3d63b2d5d116ba119243bf.svn-base
--- /dev/null
+++ b/.svn/pristine/27/27ce56818e709e285d3d63b2d5d116ba119243bf.svn-base
@@ -0,0 +1,32 @@
+class ChangeChangesetsRevisionToString < ActiveRecord::Migration
+  def self.up
+    # Some backends (eg. SQLServer 2012) do not support changing the type
+    # of an indexed column so the index needs to be dropped first
+    # BUT this index is renamed with some backends (at least SQLite3) for
+    # some (unknown) reasons, thus we check for the other name as well
+    # so we don't end up with 2 identical indexes
+    if index_exists? :changesets, [:repository_id, :revision], :name => :changesets_repos_rev
+      remove_index  :changesets, :name => :changesets_repos_rev
+    end
+    if index_exists? :changesets, [:repository_id, :revision], :name => :altered_changesets_repos_rev
+      remove_index  :changesets, :name => :altered_changesets_repos_rev
+    end
+
+    change_column :changesets, :revision, :string, :null => false
+
+    add_index :changesets, [:repository_id, :revision], :unique => true, :name => :changesets_repos_rev
+  end
+
+  def self.down
+    if index_exists? :changesets, :changesets_repos_rev
+      remove_index  :changesets, :name => :changesets_repos_rev
+    end
+    if index_exists? :changesets, [:repository_id, :revision], :name => :altered_changesets_repos_rev
+      remove_index  :changesets, :name => :altered_changesets_repos_rev
+    end
+
+    change_column :changesets, :revision, :integer, :null => false
+
+    add_index :changesets, [:repository_id, :revision], :unique => true, :name => :changesets_repos_rev
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/27/27ff0c8aa6059bb3d3244c9053898a1f8e9c2b1e.svn-base
--- /dev/null
+++ b/.svn/pristine/27/27ff0c8aa6059bb3d3244c9053898a1f8e9c2b1e.svn-base
@@ -0,0 +1,32 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Views
+    module MyPage
+      module Block
+        def self.additional_blocks
+          @@additional_blocks ||= Dir.glob("#{Redmine::Plugin.directory}/*/app/views/my/blocks/_*.{rhtml,erb}").inject({}) do |h,file|
+            name = File.basename(file).split('.').first.gsub(/^_/, '')
+            h[name] = name.to_sym
+            h
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/28/2804d830457d070d543c18e9bbae7cbb0206aa55.svn-base
--- /dev/null
+++ b/.svn/pristine/28/2804d830457d070d543c18e9bbae7cbb0206aa55.svn-base
@@ -0,0 +1,188 @@
+/* Redmine - project management software
+   Copyright (C) 2006-2013  Jean-Philippe Lang */
+
+function addFile(inputEl, file, eagerUpload) {
+
+  if ($('#attachments_fields').children().length < 10) {
+
+    var attachmentId = addFile.nextAttachmentId++;
+
+    var fileSpan = $('<span>', { id: 'attachments_' + attachmentId });
+
+    fileSpan.append(
+        $('<input>', { type: 'text', 'class': 'filename readonly', name: 'attachments[' + attachmentId + '][filename]', readonly: 'readonly'} ).val(file.name),
+        $('<input>', { type: 'text', 'class': 'description', name: 'attachments[' + attachmentId + '][description]', maxlength: 255, placeholder: $(inputEl).data('description-placeholder') } ).toggle(!eagerUpload),
+        $('<a>&nbsp</a>').attr({ href: "#", 'class': 'remove-upload' }).click(removeFile).toggle(!eagerUpload)
+    ).appendTo('#attachments_fields');
+
+    if(eagerUpload) {
+      ajaxUpload(file, attachmentId, fileSpan, inputEl);
+    }
+
+    return attachmentId;
+  }
+  return null;
+}
+
+addFile.nextAttachmentId = 1;
+
+function ajaxUpload(file, attachmentId, fileSpan, inputEl) {
+
+  function onLoadstart(e) {
+    fileSpan.removeClass('ajax-waiting');
+    fileSpan.addClass('ajax-loading');
+    $('input:submit', $(this).parents('form')).attr('disabled', 'disabled');
+  }
+
+  function onProgress(e) {
+    if(e.lengthComputable) {
+      this.progressbar( 'value', e.loaded * 100 / e.total );
+    }
+  }
+
+  function actualUpload(file, attachmentId, fileSpan, inputEl) {
+
+    ajaxUpload.uploading++;
+
+    uploadBlob(file, $(inputEl).data('upload-path'), attachmentId, {
+        loadstartEventHandler: onLoadstart.bind(progressSpan),
+        progressEventHandler: onProgress.bind(progressSpan)
+      })
+      .done(function(result) {
+        progressSpan.progressbar( 'value', 100 ).remove();
+        fileSpan.find('input.description, a').css('display', 'inline-block');
+      })
+      .fail(function(result) {
+        progressSpan.text(result.statusText);
+      }).always(function() {
+        ajaxUpload.uploading--;
+        fileSpan.removeClass('ajax-loading');
+        var form = fileSpan.parents('form');
+        if (form.queue('upload').length == 0 && ajaxUpload.uploading == 0) {
+          $('input:submit', form).removeAttr('disabled');
+        }
+        form.dequeue('upload');
+      });
+  }
+
+  var progressSpan = $('<div>').insertAfter(fileSpan.find('input.filename'));
+  progressSpan.progressbar();
+  fileSpan.addClass('ajax-waiting');
+
+  var maxSyncUpload = $(inputEl).data('max-concurrent-uploads');
+
+  if(maxSyncUpload == null || maxSyncUpload <= 0 || ajaxUpload.uploading < maxSyncUpload)
+    actualUpload(file, attachmentId, fileSpan, inputEl);
+  else
+    $(inputEl).parents('form').queue('upload', actualUpload.bind(this, file, attachmentId, fileSpan, inputEl));
+}
+
+ajaxUpload.uploading = 0;
+
+function removeFile() {
+  $(this).parent('span').remove();
+  return false;
+}
+
+function uploadBlob(blob, uploadUrl, attachmentId, options) {
+
+  var actualOptions = $.extend({
+    loadstartEventHandler: $.noop,
+    progressEventHandler: $.noop
+  }, options);
+
+  uploadUrl = uploadUrl + '?attachment_id=' + attachmentId;
+  if (blob instanceof window.File) {
+    uploadUrl += '&filename=' + encodeURIComponent(blob.name);
+  }
+
+  return $.ajax(uploadUrl, {
+    type: 'POST',
+    contentType: 'application/octet-stream',
+    beforeSend: function(jqXhr) {
+      jqXhr.setRequestHeader('Accept', 'application/js');
+    },
+    xhr: function() {
+      var xhr = $.ajaxSettings.xhr();
+      xhr.upload.onloadstart = actualOptions.loadstartEventHandler;
+      xhr.upload.onprogress = actualOptions.progressEventHandler;
+      return xhr;
+    },
+    data: blob,
+    cache: false,
+    processData: false
+  });
+}
+
+function addInputFiles(inputEl) {
+  var clearedFileInput = $(inputEl).clone().val('');
+
+  if (inputEl.files) {
+    // upload files using ajax
+    uploadAndAttachFiles(inputEl.files, inputEl);
+    $(inputEl).remove();
+  } else {
+    // browser not supporting the file API, upload on form submission
+    var attachmentId;
+    var aFilename = inputEl.value.split(/\/|\\/);
+    attachmentId = addFile(inputEl, { name: aFilename[ aFilename.length - 1 ] }, false);
+    if (attachmentId) {
+      $(inputEl).attr({ name: 'attachments[' + attachmentId + '][file]', style: 'display:none;' }).appendTo('#attachments_' + attachmentId);
+    }
+  }
+
+  clearedFileInput.insertAfter('#attachments_fields');
+}
+
+function uploadAndAttachFiles(files, inputEl) {
+
+  var maxFileSize = $(inputEl).data('max-file-size');
+  var maxFileSizeExceeded = $(inputEl).data('max-file-size-message');
+
+  var sizeExceeded = false;
+  $.each(files, function() {
+    if (this.size && maxFileSize && this.size > parseInt(maxFileSize)) {sizeExceeded=true;}
+  });
+  if (sizeExceeded) {
+    window.alert(maxFileSizeExceeded);
+  } else {
+    $.each(files, function() {addFile(inputEl, this, true);});
+  }
+}
+
+function handleFileDropEvent(e) {
+
+  $(this).removeClass('fileover');
+  blockEventPropagation(e);
+
+  if ($.inArray('Files', e.dataTransfer.types) > -1) {
+    uploadAndAttachFiles(e.dataTransfer.files, $('input:file.file_selector'));
+  }
+}
+
+function dragOverHandler(e) {
+  $(this).addClass('fileover');
+  blockEventPropagation(e);
+}
+
+function dragOutHandler(e) {
+  $(this).removeClass('fileover');
+  blockEventPropagation(e);
+}
+
+function setupFileDrop() {
+  if (window.File && window.FileList && window.ProgressEvent && window.FormData) {
+
+    $.event.fixHooks.drop = { props: [ 'dataTransfer' ] };
+
+    $('form div.box').has('input:file').each(function() {
+      $(this).on({
+          dragover: dragOverHandler,
+          dragleave: dragOutHandler,
+          drop: handleFileDropEvent
+      });
+    });
+  }
+}
+
+$(document).ready(setupFileDrop);
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/28/2806c2e1c64e92f9ca9d69815ab933298ecbeb25.svn-base
--- a/.svn/pristine/28/2806c2e1c64e92f9ca9d69815ab933298ecbeb25.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-module OpenIdAuthentication
-  class Association < ActiveRecord::Base
-    set_table_name :open_id_authentication_associations
-
-    def from_record
-      OpenID::Association.new(handle, secret, issued, lifetime, assoc_type)
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/28/2840fb98174d2a4d326c6f441324c06bb7ec4f82.svn-base
--- /dev/null
+++ b/.svn/pristine/28/2840fb98174d2a4d326c6f441324c06bb7ec4f82.svn-base
@@ -0,0 +1,326 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require "digest/md5"
+require "fileutils"
+
+class Attachment < ActiveRecord::Base
+  belongs_to :container, :polymorphic => true
+  belongs_to :author, :class_name => "User", :foreign_key => "author_id"
+
+  validates_presence_of :filename, :author
+  validates_length_of :filename, :maximum => 255
+  validates_length_of :disk_filename, :maximum => 255
+  validates_length_of :description, :maximum => 255
+  validate :validate_max_file_size
+
+  acts_as_event :title => :filename,
+                :url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}}
+
+  acts_as_activity_provider :type => 'files',
+                            :permission => :view_files,
+                            :author_key => :author_id,
+                            :find_options => {:select => "#{Attachment.table_name}.*",
+                                              :joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " +
+                                                        "LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id OR ( #{Attachment.table_name}.container_type='Project' AND #{Attachment.table_name}.container_id = #{Project.table_name}.id )"}
+
+  acts_as_activity_provider :type => 'documents',
+                            :permission => :view_documents,
+                            :author_key => :author_id,
+                            :find_options => {:select => "#{Attachment.table_name}.*",
+                                              :joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " +
+                                                        "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"}
+
+  cattr_accessor :storage_path
+  @@storage_path = Redmine::Configuration['attachments_storage_path'] || File.join(Rails.root, "files")
+
+  cattr_accessor :thumbnails_storage_path
+  @@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails")
+
+  before_save :files_to_final_location
+  after_destroy :delete_from_disk
+
+  # Returns an unsaved copy of the attachment
+  def copy(attributes=nil)
+    copy = self.class.new
+    copy.attributes = self.attributes.dup.except("id", "downloads")
+    copy.attributes = attributes if attributes
+    copy
+  end
+
+  def validate_max_file_size
+    if @temp_file && self.filesize > Setting.attachment_max_size.to_i.kilobytes
+      errors.add(:base, l(:error_attachment_too_big, :max_size => Setting.attachment_max_size.to_i.kilobytes))
+    end
+  end
+
+  def file=(incoming_file)
+    unless incoming_file.nil?
+      @temp_file = incoming_file
+      if @temp_file.size > 0
+        if @temp_file.respond_to?(:original_filename)
+          self.filename = @temp_file.original_filename
+          self.filename.force_encoding("UTF-8") if filename.respond_to?(:force_encoding)
+        end
+        if @temp_file.respond_to?(:content_type)
+          self.content_type = @temp_file.content_type.to_s.chomp
+        end
+        if content_type.blank? && filename.present?
+          self.content_type = Redmine::MimeType.of(filename)
+        end
+        self.filesize = @temp_file.size
+      end
+    end
+  end
+
+  def file
+    nil
+  end
+
+  def filename=(arg)
+    write_attribute :filename, sanitize_filename(arg.to_s)
+    filename
+  end
+
+  # Copies the temporary file to its final location
+  # and computes its MD5 hash
+  def files_to_final_location
+    if @temp_file && (@temp_file.size > 0)
+      self.disk_directory = target_directory
+      self.disk_filename = Attachment.disk_filename(filename, disk_directory)
+      logger.info("Saving attachment '#{self.diskfile}' (#{@temp_file.size} bytes)")
+      path = File.dirname(diskfile)
+      unless File.directory?(path)
+        FileUtils.mkdir_p(path)
+      end
+      md5 = Digest::MD5.new
+      File.open(diskfile, "wb") do |f|
+        if @temp_file.respond_to?(:read)
+          buffer = ""
+          while (buffer = @temp_file.read(8192))
+            f.write(buffer)
+            md5.update(buffer)
+          end
+        else
+          f.write(@temp_file)
+          md5.update(@temp_file)
+        end
+      end
+      self.digest = md5.hexdigest
+    end
+    @temp_file = nil
+    # Don't save the content type if it's longer than the authorized length
+    if self.content_type && self.content_type.length > 255
+      self.content_type = nil
+    end
+  end
+
+  # Deletes the file from the file system if it's not referenced by other attachments
+  def delete_from_disk
+    if Attachment.where("disk_filename = ? AND id <> ?", disk_filename, id).empty?
+      delete_from_disk!
+    end
+  end
+
+  # Returns file's location on disk
+  def diskfile
+    File.join(self.class.storage_path, disk_directory.to_s, disk_filename.to_s)
+  end
+
+  def title
+    title = filename.to_s
+    if description.present?
+      title << " (#{description})"
+    end
+    title
+  end
+
+  def increment_download
+    increment!(:downloads)
+  end
+
+  def project
+    container.try(:project)
+  end
+
+  def visible?(user=User.current)
+    if container_id
+      container && container.attachments_visible?(user)
+    else
+      author == user
+    end
+  end
+
+  def deletable?(user=User.current)
+    if container_id
+      container && container.attachments_deletable?(user)
+    else
+      author == user
+    end
+  end
+
+  def image?
+    !!(self.filename =~ /\.(bmp|gif|jpg|jpe|jpeg|png)$/i)
+  end
+
+  def thumbnailable?
+    image?
+  end
+
+  # Returns the full path the attachment thumbnail, or nil
+  # if the thumbnail cannot be generated.
+  def thumbnail(options={})
+    if thumbnailable? && readable?
+      size = options[:size].to_i
+      if size > 0
+        # Limit the number of thumbnails per image
+        size = (size / 50) * 50
+        # Maximum thumbnail size
+        size = 800 if size > 800
+      else
+        size = Setting.thumbnails_size.to_i
+      end
+      size = 100 unless size > 0
+      target = File.join(self.class.thumbnails_storage_path, "#{id}_#{digest}_#{size}.thumb")
+
+      begin
+        Redmine::Thumbnail.generate(self.diskfile, target, size)
+      rescue => e
+        logger.error "An error occured while generating thumbnail for #{disk_filename} to #{target}\nException was: #{e.message}" if logger
+        return nil
+      end
+    end
+  end
+
+  # Deletes all thumbnails
+  def self.clear_thumbnails
+    Dir.glob(File.join(thumbnails_storage_path, "*.thumb")).each do |file|
+      File.delete file
+    end
+  end
+
+  def is_text?
+    Redmine::MimeType.is_type?('text', filename)
+  end
+
+  def is_diff?
+    self.filename =~ /\.(patch|diff)$/i
+  end
+
+  # Returns true if the file is readable
+  def readable?
+    File.readable?(diskfile)
+  end
+
+  # Returns the attachment token
+  def token
+    "#{id}.#{digest}"
+  end
+
+  # Finds an attachment that matches the given token and that has no container
+  def self.find_by_token(token)
+    if token.to_s =~ /^(\d+)\.([0-9a-f]+)$/
+      attachment_id, attachment_digest = $1, $2
+      attachment = Attachment.where(:id => attachment_id, :digest => attachment_digest).first
+      if attachment && attachment.container.nil?
+        attachment
+      end
+    end
+  end
+
+  # Bulk attaches a set of files to an object
+  #
+  # Returns a Hash of the results:
+  # :files => array of the attached files
+  # :unsaved => array of the files that could not be attached
+  def self.attach_files(obj, attachments)
+    result = obj.save_attachments(attachments, User.current)
+    obj.attach_saved_attachments
+    result
+  end
+
+  def self.latest_attach(attachments, filename)
+    attachments.sort_by(&:created_on).reverse.detect {
+      |att| att.filename.downcase == filename.downcase
+     }
+  end
+
+  def self.prune(age=1.day)
+    Attachment.where("created_on < ? AND (container_type IS NULL OR container_type = '')", Time.now - age).destroy_all
+  end
+
+  # Moves an existing attachment to its target directory
+  def move_to_target_directory!
+    if !new_record? & readable?
+      src = diskfile
+      self.disk_directory = target_directory
+      dest = diskfile
+      if src != dest && FileUtils.mkdir_p(File.dirname(dest)) && FileUtils.mv(src, dest)
+        update_column :disk_directory, disk_directory
+      end
+    end
+  end
+
+  # Moves existing attachments that are stored at the root of the files
+  # directory (ie. created before Redmine 2.3) to their target subdirectories
+  def self.move_from_root_to_target_directory
+    Attachment.where("disk_directory IS NULL OR disk_directory = ''").find_each do |attachment|
+      attachment.move_to_target_directory!
+    end
+  end
+
+  private
+
+  # Physically deletes the file from the file system
+  def delete_from_disk!
+    if disk_filename.present? && File.exist?(diskfile)
+      File.delete(diskfile)
+    end
+  end
+
+  def sanitize_filename(value)
+    # get only the filename, not the whole path
+    just_filename = value.gsub(/^.*(\\|\/)/, '')
+
+    # Finally, replace invalid characters with underscore
+    @filename = just_filename.gsub(/[\/\?\%\*\:\|\"\'<>]+/, '_')
+  end
+
+  # Returns the subdirectory in which the attachment will be saved
+  def target_directory
+    time = created_on || DateTime.now
+    time.strftime("%Y/%m")
+  end
+
+  # Returns an ASCII or hashed filename that do not
+  # exists yet in the given subdirectory
+  def self.disk_filename(filename, directory=nil)
+    timestamp = DateTime.now.strftime("%y%m%d%H%M%S")
+    ascii = ''
+    if filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
+      ascii = filename
+    else
+      ascii = Digest::MD5.hexdigest(filename)
+      # keep the extension if any
+      ascii << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$}
+    end
+    while File.exist?(File.join(storage_path, directory.to_s, "#{timestamp}_#{ascii}"))
+      timestamp.succ!
+    end
+    "#{timestamp}_#{ascii}"
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/28/28420e6f2a289bd07da6ea940b845a9449d5bc41.svn-base
--- /dev/null
+++ b/.svn/pristine/28/28420e6f2a289bd07da6ea940b845a9449d5bc41.svn-base
@@ -0,0 +1,35 @@
+api.array :issues, api_meta(:total_count => @issue_count, :offset => @offset, :limit => @limit) do
+  @issues.each do |issue|
+    api.issue do
+      api.id issue.id
+      api.project(:id => issue.project_id, :name => issue.project.name) unless issue.project.nil?
+      api.tracker(:id => issue.tracker_id, :name => issue.tracker.name) unless issue.tracker.nil?
+      api.status(:id => issue.status_id, :name => issue.status.name) unless issue.status.nil?
+      api.priority(:id => issue.priority_id, :name => issue.priority.name) unless issue.priority.nil?
+      api.author(:id => issue.author_id, :name => issue.author.name) unless issue.author.nil?
+      api.assigned_to(:id => issue.assigned_to_id, :name => issue.assigned_to.name) unless issue.assigned_to.nil?
+      api.category(:id => issue.category_id, :name => issue.category.name) unless issue.category.nil?
+      api.fixed_version(:id => issue.fixed_version_id, :name => issue.fixed_version.name) unless issue.fixed_version.nil?
+      api.parent(:id => issue.parent_id) unless issue.parent.nil?
+
+      api.subject     issue.subject
+      api.description issue.description
+      api.start_date  issue.start_date
+      api.due_date    issue.due_date
+      api.done_ratio  issue.done_ratio
+      api.estimated_hours issue.estimated_hours
+
+      render_api_custom_values issue.custom_field_values, api
+
+      api.created_on issue.created_on
+      api.updated_on issue.updated_on
+      api.closed_on  issue.closed_on
+
+      api.array :relations do
+        issue.relations.each do |relation|
+          api.relation(:id => relation.id, :issue_id => relation.issue_from_id, :issue_to_id => relation.issue_to_id, :relation_type => relation.relation_type, :delay => relation.delay)
+        end
+      end if include_in_api_response?('relations')
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/28/2864783005a4ba0460d387fef08dd617a059d205.svn-base
--- a/.svn/pristine/28/2864783005a4ba0460d387fef08dd617a059d205.svn-base
+++ /dev/null
@@ -1,61 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::ConfigurationTest < ActiveSupport::TestCase
-  def setup
-    @conf = Redmine::Configuration
-  end
-
-  def test_empty
-    assert_kind_of Hash, load_conf('empty.yml', 'test')
-  end
-
-  def test_default
-    assert_kind_of Hash, load_conf('default.yml', 'test')
-    assert_equal 'foo', @conf['somesetting']
-  end
-
-  def test_no_default
-    assert_kind_of Hash, load_conf('no_default.yml', 'test')
-    assert_equal 'foo', @conf['somesetting']
-  end
-
-  def test_overrides
-    assert_kind_of Hash, load_conf('overrides.yml', 'test')
-    assert_equal 'bar', @conf['somesetting']
-  end
-
-  def test_with
-    load_conf('default.yml', 'test')
-    assert_equal 'foo', @conf['somesetting']
-    @conf.with 'somesetting' => 'bar' do
-      assert_equal 'bar', @conf['somesetting']
-    end
-    assert_equal 'foo', @conf['somesetting']
-  end
-
-  private
-
-  def load_conf(file, env)
-    @conf.load(
-      :file => File.join(Rails.root, 'test', 'fixtures', 'configuration', file),
-      :env => env
-    )
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/28/28ac0f519eb9b5a961e5bcb8825c18def371a932.svn-base
--- a/.svn/pristine/28/28ac0f519eb9b5a961e5bcb8825c18def371a932.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= @note %> (from application)
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/28/28e4e2427d2a8e8bd98db1e2c7317b6c662eb82a.svn-base
--- a/.svn/pristine/28/28e4e2427d2a8e8bd98db1e2c7317b6c662eb82a.svn-base
+++ /dev/null
@@ -1,17 +0,0 @@
-<h2><%=l(:label_news)%></h2>
-
-<% labelled_tabular_form_for @news, :html => { :id => 'news-form', :method => :put } do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_save) %>
-<%= link_to_remote l(:label_preview),
-                   { :url => preview_news_path(:project_id => @project),
-                     :method => 'get',
-                     :update => 'preview',
-                     :with => "Form.serialize('news-form')"
-                   }, :accesskey => accesskey(:preview) %>
-<% end %>
-<div id="preview" class="wiki"></div>
-
-<% content_for :header_tags do %>
-  <%= stylesheet_link_tag 'scm' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/28/28f61d6f82da16a79bf305217d0869e0a3170794.svn-base
--- a/.svn/pristine/28/28f61d6f82da16a79bf305217d0869e0a3170794.svn-base
+++ /dev/null
@@ -1,39 +0,0 @@
-<div class="contextual">
-<%= link_to_if_authorized l(:label_document_new),
-                          {:controller => 'documents', :action => 'new', :project_id => @project},
-                          :class => 'icon icon-add',
-                          :onclick => 'Element.show("add-document"); Form.Element.focus("document_title"); return false;' %>
-</div>
-
-<div id="add-document" style="display:none;">
-<h2><%=l(:label_document_new)%></h2>
-<% form_tag({:controller => 'documents', :action => 'new', :project_id => @project}, :class => "tabular", :multipart => true) do %>
-<%= render :partial => 'documents/form' %>
-<div class="box">
-<p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
-</div>
-<%= submit_tag l(:button_create) %>
-<%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("add-document")' %>
-<% end %>
-</div>
-
-<h2><%=l(:label_document_plural)%></h2>
-
-<% if @grouped.empty? %><p class="nodata"><%= l(:label_no_data) %></p><% end %>
-
-<% @grouped.keys.sort.each do |group| %>
-    <h3><%= group %></h3>
-    <%= render :partial => 'documents/document', :collection => @grouped[group] %>
-<% end %>
-
-<% content_for :sidebar do %>
-    <h3><%= l(:label_sort_by, '') %></h3>
-    <% form_tag({}, :method => :get) do %>
-    <label><%= radio_button_tag 'sort_by', 'category', (@sort_by == 'category'), :onclick => 'this.form.submit();' %> <%= l(:field_category) %></label><br />
-    <label><%= radio_button_tag 'sort_by', 'date', (@sort_by == 'date'), :onclick => 'this.form.submit();' %> <%= l(:label_date) %></label><br />
-    <label><%= radio_button_tag 'sort_by', 'title', (@sort_by == 'title'), :onclick => 'this.form.submit();' %> <%= l(:field_title) %></label><br />
-    <label><%= radio_button_tag 'sort_by', 'author', (@sort_by == 'author'), :onclick => 'this.form.submit();' %> <%= l(:field_author) %></label>
-    <% end %>
-<% end %>
-
-<% html_title(l(:label_document_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/29/2916f748eef73ff691bcfc74e7c1ac23960d090b.svn-base
--- a/.svn/pristine/29/2916f748eef73ff691bcfc74e7c1ac23960d090b.svn-base
+++ /dev/null
@@ -1,294 +0,0 @@
-# $Id: ber.rb 142 2006-07-26 12:20:33Z blackhedd $
-#
-# NET::BER
-# Mixes ASN.1/BER convenience methods into several standard classes.
-# Also provides BER parsing functionality.
-#
-#----------------------------------------------------------------------------
-#
-# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
-#
-# Gmail: garbagecat10
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#---------------------------------------------------------------------------
-#
-#
-
-
-
-
-module Net
-
-  module BER
-
-  class BerError < Exception; end
-
-
-  # This module is for mixing into IO and IO-like objects.
-  module BERParser
-
-    # The order of these follows the class-codes in BER.
-    # Maybe this should have been a hash.
-    TagClasses = [:universal, :application, :context_specific, :private]
-
-    BuiltinSyntax = {
-      :universal => {
-        :primitive => {
-          1 => :boolean,
-          2 => :integer,
-          4 => :string,
-          10 => :integer,
-        },
-        :constructed => {
-          16 => :array,
-          17 => :array
-        }
-      }
-    }
-
-    #
-    # read_ber
-    # TODO: clean this up so it works properly with partial
-    # packets coming from streams that don't block when
-    # we ask for more data (like StringIOs). At it is,
-    # this can throw TypeErrors and other nasties.
-    #
-    def read_ber syntax=nil
-      return nil if (StringIO == self.class) and  eof?
-
-      id = getc  # don't trash this value, we'll use it later
-      tag = id & 31
-      tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
-      tagclass = TagClasses[ id >> 6 ]
-      encoding = (id & 0x20 != 0) ? :constructed : :primitive
-
-      n = getc
-      lengthlength,contentlength = if n <= 127
-        [1,n]
-      else
-        j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
-        [1 + (n & 127), j]
-      end
-
-      newobj = read contentlength
-
-      objtype = nil
-      [syntax, BuiltinSyntax].each {|syn|
-        if syn && (ot = syn[tagclass]) && (ot = ot[encoding]) && ot[tag]
-          objtype = ot[tag]
-          break
-        end
-      }
-      
-      obj = case objtype
-      when :boolean
-        newobj != "\000"
-      when :string
-        (newobj || "").dup
-      when :integer
-        j = 0
-        newobj.each_byte {|b| j = (j << 8) + b}
-        j
-      when :array
-        seq = []
-        sio = StringIO.new( newobj || "" )
-        # Interpret the subobject, but note how the loop
-        # is built: nil ends the loop, but false (a valid
-        # BER value) does not!
-        while (e = sio.read_ber(syntax)) != nil
-          seq << e
-        end
-        seq
-      else
-        raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
-      end
-
-      # Add the identifier bits into the object if it's a String or an Array.
-      # We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway.
-      obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end"
-      obj
-
-    end
-
-  end # module BERParser
-  end # module BER
-
-end # module Net
-
-
-class IO
-  include Net::BER::BERParser
-end
-
-require "stringio"
-class StringIO
-  include Net::BER::BERParser
-end
-
-begin
-  require 'openssl'
-  class OpenSSL::SSL::SSLSocket
-    include Net::BER::BERParser
-  end
-rescue LoadError
-# Ignore LoadError.
-# DON'T ignore NameError, which means the SSLSocket class
-# is somehow unavailable on this implementation of Ruby's openssl.
-# This may be WRONG, however, because we don't yet know how Ruby's
-# openssl behaves on machines with no OpenSSL library. I suppose
-# it's possible they do not fail to require 'openssl' but do not
-# create the classes. So this code is provisional.
-# Also, you might think that OpenSSL::SSL::SSLSocket inherits from
-# IO so we'd pick it up above. But you'd be wrong.
-end
-
-class String
-  def read_ber syntax=nil
-    StringIO.new(self).read_ber(syntax)
-  end
-end
-
-
-
-#----------------------------------------------
-
-
-class FalseClass
-  #
-  # to_ber
-  #
-  def to_ber
-    "\001\001\000"
-  end
-end
-
-
-class TrueClass
-  #
-  # to_ber
-  #
-  def to_ber
-    "\001\001\001"
-  end
-end
-
-
-
-class Fixnum
-  #
-  # to_ber
-  #
-  def to_ber
-    i = [self].pack('w')
-    [2, i.length].pack("CC") + i
-  end
-
-  #
-  # to_ber_enumerated
-  #
-  def to_ber_enumerated
-    i = [self].pack('w')
-    [10, i.length].pack("CC") + i
-  end
-
-  #
-  # to_ber_length_encoding
-  #
-  def to_ber_length_encoding
-    if self <= 127
-      [self].pack('C')
-    else
-      i = [self].pack('N').sub(/^[\0]+/,"")
-      [0x80 + i.length].pack('C') + i
-    end
-  end
-
-end # class Fixnum
-
-
-class Bignum
-
-  def to_ber
-    i = [self].pack('w')
-    i.length > 126 and raise Net::BER::BerError.new( "range error in bignum" )
-    [2, i.length].pack("CC") + i
-  end
-
-end
-
-
-
-class String
-  #
-  # to_ber
-  # A universal octet-string is tag number 4,
-  # but others are possible depending on the context, so we
-  # let the caller give us one.
-  # The preferred way to do this in user code is via to_ber_application_sring
-  # and to_ber_contextspecific.
-  #
-  def to_ber code = 4
-    [code].pack('C') + length.to_ber_length_encoding + self
-  end
-
-  #
-  # to_ber_application_string
-  #
-  def to_ber_application_string code
-    to_ber( 0x40 + code )
-  end
-
-  #
-  # to_ber_contextspecific
-  #
-  def to_ber_contextspecific code
-    to_ber( 0x80 + code )
-  end
-
-end # class String
-
-
-
-class Array
-  #
-  # to_ber_appsequence
-  # An application-specific sequence usually gets assigned
-  # a tag that is meaningful to the particular protocol being used.
-  # This is different from the universal sequence, which usually
-  # gets a tag value of 16.
-  # Now here's an interesting thing: We're adding the X.690
-  # "application constructed" code at the top of the tag byte (0x60),
-  # but some clients, notably ldapsearch, send "context-specific
-  # constructed" (0xA0). The latter would appear to violate RFC-1777,
-  # but what do I know? We may need to change this.
-  #
-
-  def to_ber                 id = 0; to_ber_seq_internal( 0x30 + id ); end
-  def to_ber_set             id = 0; to_ber_seq_internal( 0x31 + id ); end
-  def to_ber_sequence        id = 0; to_ber_seq_internal( 0x30 + id ); end
-  def to_ber_appsequence     id = 0; to_ber_seq_internal( 0x60 + id ); end
-  def to_ber_contextspecific id = 0; to_ber_seq_internal( 0xA0 + id ); end
-
-  private
-  def to_ber_seq_internal code
-    s = self.to_s
-    [code].pack('C') + s.length.to_ber_length_encoding + s
-  end
-
-end # class Array
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/29/299dc6b637e0f5b3775b92631d240971508c0684.svn-base
--- a/.svn/pristine/29/299dc6b637e0f5b3775b92631d240971508c0684.svn-base
+++ /dev/null
@@ -1,61 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::MimeTypeTest < ActiveSupport::TestCase
-
-  def test_of
-    to_test = {'test.unk' => nil,
-               'test.txt' => 'text/plain',
-               'test.c' => 'text/x-c',
-               }
-    to_test.each do |name, expected|
-      assert_equal expected, Redmine::MimeType.of(name)
-    end
-  end
-
-  def test_css_class_of
-    to_test = {'test.unk' => nil,
-               'test.txt' => 'text-plain',
-               'test.c' => 'text-x-c',
-               }
-    to_test.each do |name, expected|
-      assert_equal expected, Redmine::MimeType.css_class_of(name)
-    end
-  end
-
-  def test_main_mimetype_of
-    to_test = {'test.unk' => nil,
-               'test.txt' => 'text',
-               'test.c' => 'text',
-               }
-    to_test.each do |name, expected|
-      assert_equal expected, Redmine::MimeType.main_mimetype_of(name)
-    end
-  end
-
-  def test_is_type
-    to_test = {['text', 'test.unk'] => false,
-               ['text', 'test.txt'] => true,
-               ['text', 'test.c'] => true,
-               }
-    to_test.each do |args, expected|
-      assert_equal expected, Redmine::MimeType.is_type?(*args)
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/29/29d1b7a44a44f4040dd2b8d4fe4b9b40b3383592.svn-base
--- a/.svn/pristine/29/29d1b7a44a44f4040dd2b8d4fe4b9b40b3383592.svn-base
+++ /dev/null
@@ -1,84 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class TrackersController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin, :except => :index
-  before_filter :require_admin_or_api_request, :only => :index
-  accept_api_auth :index
-
-  def index
-    respond_to do |format|
-      format.html {
-        @tracker_pages, @trackers = paginate :trackers, :per_page => 10, :order => 'position'
-        render :action => "index", :layout => false if request.xhr?
-      }
-      format.api {
-        @trackers = Tracker.all
-      }
-    end
-  end
-
-  def new
-    @tracker ||= Tracker.new(params[:tracker])
-    @trackers = Tracker.find :all, :order => 'position'
-    @projects = Project.find(:all)
-  end
-
-  def create
-    @tracker = Tracker.new(params[:tracker])
-    if request.post? and @tracker.save
-      # workflow copy
-      if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from]))
-        @tracker.workflows.copy(copy_from)
-      end
-      flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index'
-      return
-    end
-    new
-    render :action => 'new'
-  end
-
-  def edit
-    @tracker ||= Tracker.find(params[:id])
-    @projects = Project.find(:all)
-  end
-  
-  def update
-    @tracker = Tracker.find(params[:id])
-    if request.put? and @tracker.update_attributes(params[:tracker])
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
-      return
-    end
-    edit
-    render :action => 'edit'
-  end
-
-  verify :method => :delete, :only => :destroy, :redirect_to => { :action => :index }
-  def destroy
-    @tracker = Tracker.find(params[:id])
-    unless @tracker.issues.empty?
-      flash[:error] = l(:error_can_not_delete_tracker)
-    else
-      @tracker.destroy
-    end
-    redirect_to :action => 'index'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/29/29e480c531a7477e290d81b189c3105531d0d4db.svn-base
--- /dev/null
+++ b/.svn/pristine/29/29e480c531a7477e290d81b189c3105531d0d4db.svn-base
@@ -0,0 +1,217 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../base', __FILE__)
+
+class Redmine::UiTest::IssuesTest < Redmine::UiTest::Base
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :trackers, :projects_trackers, :enabled_modules, :issue_statuses, :issues,
+           :enumerations, :custom_fields, :custom_values, :custom_fields_trackers,
+           :watchers
+
+  def test_create_issue
+    log_user('jsmith', 'jsmith')
+    visit '/projects/ecookbook/issues/new'
+    within('form#issue-form') do
+      select 'Bug', :from => 'Tracker'
+      select 'Low', :from => 'Priority'
+      fill_in 'Subject', :with => 'new test issue'
+      fill_in 'Description', :with => 'new issue'
+      select '0 %', :from => 'Done'
+      fill_in 'Due date', :with => ''
+      select '', :from => 'Assignee'
+      fill_in 'Searchable field', :with => 'Value for field 2'
+      # click_button 'Create' would match both 'Create' and 'Create and continue' buttons
+      find('input[name=commit]').click
+    end
+
+    # find created issue
+    issue = Issue.find_by_subject("new test issue")
+    assert_kind_of Issue, issue
+
+    # check redirection
+    find 'div#flash_notice', :visible => true, :text => "Issue \##{issue.id} created."
+    assert_equal issue_path(:id => issue), current_path
+
+    # check issue attributes
+    assert_equal 'jsmith', issue.author.login
+    assert_equal 1, issue.project.id
+    assert_equal IssueStatus.find_by_name('New'), issue.status 
+    assert_equal Tracker.find_by_name('Bug'), issue.tracker
+    assert_equal IssuePriority.find_by_name('Low'), issue.priority
+    assert_equal 'Value for field 2', issue.custom_field_value(CustomField.find_by_name('Searchable field'))
+  end
+
+  def test_create_issue_with_form_update
+    field1 = IssueCustomField.create!(
+      :field_format => 'string',
+      :name => 'Field1',
+      :is_for_all => true,
+      :trackers => Tracker.find_all_by_id([1, 2])
+    )
+    field2 = IssueCustomField.create!(
+      :field_format => 'string',
+      :name => 'Field2',
+      :is_for_all => true,
+      :trackers => Tracker.find_all_by_id(2)
+    )
+
+    Role.non_member.add_permission! :add_issues
+    Role.non_member.remove_permission! :edit_issues, :add_issue_notes
+
+    log_user('someone', 'foo')
+    visit '/projects/ecookbook/issues/new'
+    assert page.has_no_content?(field2.name)
+    assert page.has_content?(field1.name)
+
+    fill_in 'Subject', :with => 'New test issue'
+    fill_in 'Description', :with => 'New test issue description'
+    fill_in field1.name, :with => 'CF1 value'
+    select 'Low', :from => 'Priority'
+
+    # field2 should show up when changing tracker
+    select 'Feature request', :from => 'Tracker'
+    assert page.has_content?(field2.name)
+    assert page.has_content?(field1.name)
+
+    fill_in field2.name, :with => 'CF2 value'
+    assert_difference 'Issue.count' do
+      page.first(:button, 'Create').click
+    end
+
+    issue = Issue.order('id desc').first
+    assert_equal 'New test issue', issue.subject
+    assert_equal 'New test issue description', issue.description
+    assert_equal 'Low', issue.priority.name
+    assert_equal 'CF1 value', issue.custom_field_value(field1)
+    assert_equal 'CF2 value', issue.custom_field_value(field2)
+  end
+
+  def test_create_issue_with_watchers
+    User.generate!(:firstname => 'Some', :lastname => 'Watcher')
+
+    log_user('jsmith', 'jsmith')
+    visit '/projects/ecookbook/issues/new'
+    fill_in 'Subject', :with => 'Issue with watchers'
+    # Add a project member as watcher
+    check 'Dave Lopper'
+    # Search for another user
+    click_link 'Search for watchers to add'
+    within('form#new-watcher-form') do
+      assert page.has_content?('Some One')
+      fill_in 'user_search', :with => 'watch'
+      assert page.has_no_content?('Some One')
+      check 'Some Watcher'
+      click_button 'Add'
+    end
+    assert_difference 'Issue.count' do
+      find('input[name=commit]').click
+    end
+
+    issue = Issue.order('id desc').first
+    assert_equal ['Dave Lopper', 'Some Watcher'], issue.watcher_users.map(&:name).sort
+  end
+
+  def test_preview_issue_description
+    log_user('jsmith', 'jsmith')
+    visit '/projects/ecookbook/issues/new'
+    within('form#issue-form') do
+      fill_in 'Subject', :with => 'new issue subject'
+      fill_in 'Description', :with => 'new issue description'
+      click_link 'Preview'
+    end
+    find 'div#preview fieldset', :visible => true, :text => 'new issue description'
+    assert_difference 'Issue.count' do
+      find('input[name=commit]').click
+    end
+
+    issue = Issue.order('id desc').first
+    assert_equal 'new issue description', issue.description
+  end
+
+  def test_update_issue_with_form_update
+    field = IssueCustomField.create!(
+      :field_format => 'string',
+      :name => 'Form update CF',
+      :is_for_all => true,
+      :trackers => Tracker.find_all_by_name('Feature request')
+    )
+
+    Role.non_member.add_permission! :edit_issues
+    Role.non_member.remove_permission! :add_issues, :add_issue_notes
+
+    log_user('someone', 'foo')
+    visit '/issues/1'
+    assert page.has_no_content?('Form update CF')
+
+    page.first(:link, 'Update').click
+    # the custom field should show up when changing tracker
+    select 'Feature request', :from => 'Tracker'
+    assert page.has_content?('Form update CF')
+
+    fill_in 'Form update', :with => 'CF value'
+    assert_no_difference 'Issue.count' do
+      page.first(:button, 'Submit').click
+    end
+
+    issue = Issue.find(1)
+    assert_equal 'CF value', issue.custom_field_value(field)
+  end
+
+  def test_remove_issue_watcher_from_sidebar
+    user = User.find(3)
+    Watcher.create!(:watchable => Issue.find(1), :user => user)
+
+    log_user('jsmith', 'jsmith')
+    visit '/issues/1'
+    assert page.first('#sidebar').has_content?('Watchers (1)')
+    assert page.first('#sidebar').has_content?(user.name)
+    assert_difference 'Watcher.count', -1 do
+      page.first('ul.watchers .user-3 a.delete').click
+    end
+    assert page.first('#sidebar').has_content?('Watchers (0)')
+    assert page.first('#sidebar').has_no_content?(user.name)
+  end
+
+  def test_watch_issue_via_context_menu
+    log_user('jsmith', 'jsmith')
+    visit '/issues'
+    find('tr#issue-1 td.updated_on').click
+    page.execute_script "$('tr#issue-1 td.updated_on').trigger('contextmenu');"
+    assert_difference 'Watcher.count' do
+      within('#context-menu') do
+        click_link 'Watch'
+      end
+    end
+    assert Issue.find(1).watched_by?(User.find_by_login('jsmith'))
+  end
+
+  def test_bulk_watch_issues_via_context_menu
+    log_user('jsmith', 'jsmith')
+    visit '/issues'
+    find('tr#issue-1 input[type=checkbox]').click
+    find('tr#issue-4 input[type=checkbox]').click
+    page.execute_script "$('tr#issue-1 td.updated_on').trigger('contextmenu');"
+    assert_difference 'Watcher.count', 2 do
+      within('#context-menu') do
+        click_link 'Watch'
+      end
+    end
+    assert Issue.find(1).watched_by?(User.find_by_login('jsmith'))
+    assert Issue.find(4).watched_by?(User.find_by_login('jsmith'))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2a/2a26987d3e76c57b6a5ef62d32f7ea30699c2a7e.svn-base
--- a/.svn/pristine/2a/2a26987d3e76c57b6a5ef62d32f7ea30699c2a7e.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-class AlphaPluginLibModel < ActiveRecord::Base
-  def self.report_location; TestHelper::report_location(__FILE__); end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2a/2a729c60b4face5ae26610fc483b9a2b1f7c2f71.svn-base
--- a/.svn/pristine/2a/2a729c60b4face5ae26610fc483b9a2b1f7c2f71.svn-base
+++ /dev/null
@@ -1,102 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class WorkflowsController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin
-  before_filter :find_roles
-  before_filter :find_trackers
-
-  def index
-    @workflow_counts = Workflow.count_by_tracker_and_role
-  end
-
-  def edit
-    @role = Role.find_by_id(params[:role_id])
-    @tracker = Tracker.find_by_id(params[:tracker_id])
-
-    if request.post?
-      Workflow.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
-      (params[:issue_status] || []).each { |status_id, transitions|
-        transitions.each { |new_status_id, options|
-          author = options.is_a?(Array) && options.include?('author') && !options.include?('always')
-          assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always')
-          @role.workflows.build(:tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee)
-        }
-      }
-      if @role.save
-        flash[:notice] = l(:notice_successful_update)
-        redirect_to :action => 'edit', :role_id => @role, :tracker_id => @tracker
-        return
-      end
-    end
-
-    @used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
-    if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
-      @statuses = @tracker.issue_statuses
-    end
-    @statuses ||= IssueStatus.find(:all, :order => 'position')
-
-    if @tracker && @role && @statuses.any?
-      workflows = Workflow.all(:conditions => {:role_id => @role.id, :tracker_id => @tracker.id})
-      @workflows = {}
-      @workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
-      @workflows['author'] = workflows.select {|w| w.author}
-      @workflows['assignee'] = workflows.select {|w| w.assignee}
-    end
-  end
-
-  def copy
-
-    if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any'
-      @source_tracker = nil
-    else
-      @source_tracker = Tracker.find_by_id(params[:source_tracker_id].to_i)
-    end
-    if params[:source_role_id].blank? || params[:source_role_id] == 'any'
-      @source_role = nil
-    else
-      @source_role = Role.find_by_id(params[:source_role_id].to_i)
-    end
-
-    @target_trackers = params[:target_tracker_ids].blank? ? nil : Tracker.find_all_by_id(params[:target_tracker_ids])
-    @target_roles = params[:target_role_ids].blank? ? nil : Role.find_all_by_id(params[:target_role_ids])
-
-    if request.post?
-      if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?)
-        flash.now[:error] = l(:error_workflow_copy_source)
-      elsif @target_trackers.nil? || @target_roles.nil?
-        flash.now[:error] = l(:error_workflow_copy_target)
-      else
-        Workflow.copy(@source_tracker, @source_role, @target_trackers, @target_roles)
-        flash[:notice] = l(:notice_successful_update)
-        redirect_to :action => 'copy', :source_tracker_id => @source_tracker, :source_role_id => @source_role
-      end
-    end
-  end
-
-  private
-
-  def find_roles
-    @roles = Role.find(:all, :order => 'builtin, position')
-  end
-
-  def find_trackers
-    @trackers = Tracker.find(:all, :order => 'position')
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2a/2a8a6f95df9c9b5ea1480ac33b5f365836080244.svn-base
--- a/.svn/pristine/2a/2a8a6f95df9c9b5ea1480ac33b5f365836080244.svn-base
+++ /dev/null
@@ -1,178 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Setting < ActiveRecord::Base
-
-  DATE_FORMATS = [
-	'%Y-%m-%d',
-	'%d/%m/%Y',
-	'%d.%m.%Y',
-	'%d-%m-%Y',
-	'%m/%d/%Y',
-	'%d %b %Y',
-	'%d %B %Y',
-	'%b %d, %Y',
-	'%B %d, %Y'
-    ]
-
-  TIME_FORMATS = [
-    '%H:%M',
-    '%I:%M %p'
-    ]
-
-  ENCODINGS = %w(US-ASCII
-                  windows-1250
-                  windows-1251
-                  windows-1252
-                  windows-1253
-                  windows-1254
-                  windows-1255
-                  windows-1256
-                  windows-1257
-                  windows-1258
-                  windows-31j
-                  ISO-2022-JP
-                  ISO-2022-KR
-                  ISO-8859-1
-                  ISO-8859-2
-                  ISO-8859-3
-                  ISO-8859-4
-                  ISO-8859-5
-                  ISO-8859-6
-                  ISO-8859-7
-                  ISO-8859-8
-                  ISO-8859-9
-                  ISO-8859-13
-                  ISO-8859-15
-                  KOI8-R
-                  UTF-8
-                  UTF-16
-                  UTF-16BE
-                  UTF-16LE
-                  EUC-JP
-                  Shift_JIS
-                  CP932
-                  GB18030
-                  GBK
-                  ISCII91
-                  EUC-KR
-                  Big5
-                  Big5-HKSCS
-                  TIS-620)
-
-  cattr_accessor :available_settings
-  @@available_settings = YAML::load(File.open("#{Rails.root}/config/settings.yml"))
-  Redmine::Plugin.all.each do |plugin|
-    next unless plugin.settings
-    @@available_settings["plugin_#{plugin.id}"] = {'default' => plugin.settings[:default], 'serialized' => true}
-  end
-
-  validates_uniqueness_of :name
-  validates_inclusion_of :name, :in => @@available_settings.keys
-  validates_numericality_of :value, :only_integer => true, :if => Proc.new { |setting| @@available_settings[setting.name]['format'] == 'int' }
-
-  # Hash used to cache setting values
-  @cached_settings = {}
-  @cached_cleared_on = Time.now
-
-  def value
-    v = read_attribute(:value)
-    # Unserialize serialized settings
-    v = YAML::load(v) if @@available_settings[name]['serialized'] && v.is_a?(String)
-    v = v.to_sym if @@available_settings[name]['format'] == 'symbol' && !v.blank?
-    v
-  end
-
-  def value=(v)
-    v = v.to_yaml if v && @@available_settings[name] && @@available_settings[name]['serialized']
-    write_attribute(:value, v.to_s)
-  end
-
-  # Returns the value of the setting named name
-  def self.[](name)
-    v = @cached_settings[name]
-    v ? v : (@cached_settings[name] = find_or_default(name).value)
-  end
-
-  def self.[]=(name, v)
-    setting = find_or_default(name)
-    setting.value = (v ? v : "")
-    @cached_settings[name] = nil
-    setting.save
-    setting.value
-  end
-
-  # Defines getter and setter for each setting
-  # Then setting values can be read using: Setting.some_setting_name
-  # or set using Setting.some_setting_name = "some value"
-  @@available_settings.each do |name, params|
-    src = <<-END_SRC
-    def self.#{name}
-      self[:#{name}]
-    end
-
-    def self.#{name}?
-      self[:#{name}].to_i > 0
-    end
-
-    def self.#{name}=(value)
-      self[:#{name}] = value
-    end
-    END_SRC
-    class_eval src, __FILE__, __LINE__
-  end
-
-  # Helper that returns an array based on per_page_options setting
-  def self.per_page_options_array
-    per_page_options.split(%r{[\s,]}).collect(&:to_i).select {|n| n > 0}.sort
-  end
-
-  def self.openid?
-    Object.const_defined?(:OpenID) && self[:openid].to_i > 0
-  end
-
-  # Checks if settings have changed since the values were read
-  # and clears the cache hash if it's the case
-  # Called once per request
-  def self.check_cache
-    settings_updated_on = Setting.maximum(:updated_on)
-    if settings_updated_on && @cached_cleared_on <= settings_updated_on
-      clear_cache
-    end
-  end
-  
-  # Clears the settings cache
-  def self.clear_cache
-    @cached_settings.clear
-    @cached_cleared_on = Time.now
-    logger.info "Settings cache cleared." if logger
-  end
-
-private
-  # Returns the Setting instance for the setting named name
-  # (record found in database or new record with default value)
-  def self.find_or_default(name)
-    name = name.to_s
-    raise "There's no setting named #{name}" unless @@available_settings.has_key?(name)
-    setting = find_by_name(name)
-    unless setting
-      setting = new(:name => name)
-      setting.value = @@available_settings[name]['default']
-    end
-    setting
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2b/2b0a9f999f6063790f2925cfcbf5bec32cb0108e.svn-base
--- a/.svn/pristine/2b/2b0a9f999f6063790f2925cfcbf5bec32cb0108e.svn-base
+++ /dev/null
@@ -1,583 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::IssuesTest < ActionController::IntegrationTest
-  fixtures :projects,
-    :users,
-    :roles,
-    :members,
-    :member_roles,
-    :issues,
-    :issue_statuses,
-    :versions,
-    :trackers,
-    :projects_trackers,
-    :issue_categories,
-    :enabled_modules,
-    :enumerations,
-    :attachments,
-    :workflows,
-    :custom_fields,
-    :custom_values,
-    :custom_fields_projects,
-    :custom_fields_trackers,
-    :time_entries,
-    :journals,
-    :journal_details,
-    :queries,
-    :attachments
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "/issues" do
-    # Use a private project to make sure auth is really working and not just
-    # only showing public issues.
-    should_allow_api_authentication(:get, "/projects/private-child/issues.xml")
-
-    should "contain metadata" do
-      get '/issues.xml'
-
-      assert_tag :tag => 'issues',
-        :attributes => {
-          :type => 'array',
-          :total_count => assigns(:issue_count),
-          :limit => 25,
-          :offset => 0
-        }
-    end
-
-    context "with offset and limit" do
-      should "use the params" do
-        get '/issues.xml?offset=2&limit=3'
-
-        assert_equal 3, assigns(:limit)
-        assert_equal 2, assigns(:offset)
-        assert_tag :tag => 'issues', :children => {:count => 3, :only => {:tag => 'issue'}}
-      end
-    end
-
-    context "with nometa param" do
-      should "not contain metadata" do
-        get '/issues.xml?nometa=1'
-
-        assert_tag :tag => 'issues',
-          :attributes => {
-            :type => 'array',
-            :total_count => nil,
-            :limit => nil,
-            :offset => nil
-          }
-      end
-    end
-
-    context "with nometa header" do
-      should "not contain metadata" do
-        get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'}
-
-        assert_tag :tag => 'issues',
-          :attributes => {
-            :type => 'array',
-            :total_count => nil,
-            :limit => nil,
-            :offset => nil
-          }
-      end
-    end
-
-    context "with relations" do
-      should "display relations" do
-        get '/issues.xml?include=relations'
-
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-        assert_tag 'relations',
-          :parent => {:tag => 'issue', :child => {:tag => 'id', :content => '3'}},
-          :children => {:count => 1},
-          :child => {
-            :tag => 'relation',
-            :attributes => {:id => '2', :issue_id => '2', :issue_to_id => '3', :relation_type => 'relates'}
-          }
-        assert_tag 'relations',
-          :parent => {:tag => 'issue', :child => {:tag => 'id', :content => '1'}},
-          :children => {:count => 0}
-      end
-    end
-
-    context "with invalid query params" do
-      should "return errors" do
-        get '/issues.xml', {:f => ['start_date'], :op => {:start_date => '='}}
-
-        assert_response :unprocessable_entity
-        assert_equal 'application/xml', @response.content_type
-        assert_tag 'errors', :child => {:tag => 'error', :content => "Start date can't be blank"}
-      end
-    end
-
-    context "with custom field filter" do
-      should "show only issues with the custom field value" do
-        get '/issues.xml', { :set_filter => 1, :f => ['cf_1'], :op => {:cf_1 => '='}, :v => {:cf_1 => ['MySQL']}}
-
-        expected_ids = Issue.visible.all(
-            :include => :custom_values,
-            :conditions => {:custom_values => {:custom_field_id => 1, :value => 'MySQL'}}).map(&:id)
-
-        assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
-           ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
-        end
-      end
-    end
-
-    context "with custom field filter (shorthand method)" do
-      should "show only issues with the custom field value" do
-        get '/issues.xml', { :cf_1 => 'MySQL' }
-
-        expected_ids = Issue.visible.all(
-            :include => :custom_values,
-            :conditions => {:custom_values => {:custom_field_id => 1, :value => 'MySQL'}}).map(&:id)
-
-        assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
-          ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
-        end
-      end
-    end
-  end
-
-  context "/index.json" do
-    should_allow_api_authentication(:get, "/projects/private-child/issues.json")
-  end
-
-  context "/index.xml with filter" do
-    should "show only issues with the status_id" do
-      get '/issues.xml?status_id=5'
-
-      expected_ids = Issue.visible.all(:conditions => {:status_id => 5}).map(&:id)
-
-      assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
-         ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
-      end
-    end
-  end
-
-  context "/index.json with filter" do
-    should "show only issues with the status_id" do
-      get '/issues.json?status_id=5'
-
-      json = ActiveSupport::JSON.decode(response.body)
-      status_ids_used = json['issues'].collect {|j| j['status']['id'] }
-      assert_equal 3, status_ids_used.length
-      assert status_ids_used.all? {|id| id == 5 }
-    end
-
-  end
-
-  # Issue 6 is on a private project
-  context "/issues/6.xml" do
-    should_allow_api_authentication(:get, "/issues/6.xml")
-  end
-
-  context "/issues/6.json" do
-    should_allow_api_authentication(:get, "/issues/6.json")
-  end
-
-  context "GET /issues/:id" do
-    context "with journals" do
-      context ".xml" do
-        should "display journals" do
-          get '/issues/1.xml?include=journals'
-
-          assert_tag :tag => 'issue',
-            :child => {
-              :tag => 'journals',
-              :attributes => { :type => 'array' },
-              :child => {
-                :tag => 'journal',
-                :attributes => { :id => '1'},
-                :child => {
-                  :tag => 'details',
-                  :attributes => { :type => 'array' },
-                  :child => {
-                    :tag => 'detail',
-                    :attributes => { :name => 'status_id' },
-                    :child => {
-                      :tag => 'old_value',
-                      :content => '1',
-                      :sibling => {
-                        :tag => 'new_value',
-                        :content => '2'
-                      }
-                    }
-                  }
-                }
-              }
-            }
-        end
-      end
-    end
-
-    context "with custom fields" do
-      context ".xml" do
-        should "display custom fields" do
-          get '/issues/3.xml'
-
-          assert_tag :tag => 'issue',
-            :child => {
-              :tag => 'custom_fields',
-              :attributes => { :type => 'array' },
-              :child => {
-                :tag => 'custom_field',
-                :attributes => { :id => '1'},
-                :child => {
-                  :tag => 'value',
-                  :content => 'MySQL'
-                }
-              }
-            }
-
-          assert_nothing_raised do
-            Hash.from_xml(response.body).to_xml
-          end
-        end
-      end
-    end
-
-    context "with attachments" do
-      context ".xml" do
-        should "display attachments" do
-          get '/issues/3.xml?include=attachments'
-
-          assert_tag :tag => 'issue',
-            :child => {
-              :tag => 'attachments',
-              :children => {:count => 5},
-              :child => {
-                :tag => 'attachment',
-                :child => {
-                  :tag => 'filename',
-                  :content => 'source.rb',
-                  :sibling => {
-                    :tag => 'content_url',
-                    :content => 'http://www.example.com/attachments/download/4/source.rb'
-                  }
-                }
-              }
-            }
-        end
-      end
-    end
-
-    context "with subtasks" do
-      setup do
-        @c1 = Issue.generate!(:status_id => 1, :subject => "child c1", :tracker_id => 1, :project_id => 1, :parent_issue_id => 1)
-        @c2 = Issue.generate!(:status_id => 1, :subject => "child c2", :tracker_id => 1, :project_id => 1, :parent_issue_id => 1)
-        @c3 = Issue.generate!(:status_id => 1, :subject => "child c3", :tracker_id => 1, :project_id => 1, :parent_issue_id => @c1.id)
-      end
-
-      context ".xml" do
-        should "display children" do
-          get '/issues/1.xml?include=children'
-
-          assert_tag :tag => 'issue',
-            :child => {
-              :tag => 'children',
-              :children => {:count => 2},
-              :child => {
-                :tag => 'issue',
-                :attributes => {:id => @c1.id.to_s},
-                :child => {
-                  :tag => 'subject',
-                  :content => 'child c1',
-                  :sibling => {
-                    :tag => 'children',
-                    :children => {:count => 1},
-                    :child => {
-                      :tag => 'issue',
-                      :attributes => {:id => @c3.id.to_s}
-                    }
-                  }
-                }
-              }
-            }
-        end
-
-        context ".json" do
-          should "display children" do
-            get '/issues/1.json?include=children'
-
-            json = ActiveSupport::JSON.decode(response.body)
-            assert_equal([
-              {
-                'id' => @c1.id, 'subject' => 'child c1', 'tracker' => {'id' => 1, 'name' => 'Bug'},
-                'children' => [{ 'id' => @c3.id, 'subject' => 'child c3', 'tracker' => {'id' => 1, 'name' => 'Bug'} }]
-              },
-              { 'id' => @c2.id, 'subject' => 'child c2', 'tracker' => {'id' => 1, 'name' => 'Bug'} }
-              ],
-              json['issue']['children'])
-          end
-        end
-      end
-    end
-  end
-
-  context "POST /issues.xml" do
-    should_allow_api_authentication(:post,
-                                    '/issues.xml',
-                                    {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}},
-                                    {:success_code => :created})
-
-    should "create an issue with the attributes" do
-      assert_difference('Issue.count') do
-        post '/issues.xml', {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}}, :authorization => credentials('jsmith')
-      end
-
-      issue = Issue.first(:order => 'id DESC')
-      assert_equal 1, issue.project_id
-      assert_equal 2, issue.tracker_id
-      assert_equal 3, issue.status_id
-      assert_equal 'API test', issue.subject
-
-      assert_response :created
-      assert_equal 'application/xml', @response.content_type
-      assert_tag 'issue', :child => {:tag => 'id', :content => issue.id.to_s}
-    end
-  end
-
-  context "POST /issues.xml with failure" do
-    should "have an errors tag" do
-      assert_no_difference('Issue.count') do
-        post '/issues.xml', {:issue => {:project_id => 1}}, :authorization => credentials('jsmith')
-      end
-
-      assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
-    end
-  end
-
-  context "POST /issues.json" do
-    should_allow_api_authentication(:post,
-                                    '/issues.json',
-                                    {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}},
-                                    {:success_code => :created})
-
-    should "create an issue with the attributes" do
-      assert_difference('Issue.count') do
-        post '/issues.json', {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}}, :authorization => credentials('jsmith')
-      end
-
-      issue = Issue.first(:order => 'id DESC')
-      assert_equal 1, issue.project_id
-      assert_equal 2, issue.tracker_id
-      assert_equal 3, issue.status_id
-      assert_equal 'API test', issue.subject
-    end
-
-  end
-
-  context "POST /issues.json with failure" do
-    should "have an errors element" do
-      assert_no_difference('Issue.count') do
-        post '/issues.json', {:issue => {:project_id => 1}}, :authorization => credentials('jsmith')
-      end
-
-      json = ActiveSupport::JSON.decode(response.body)
-      assert json['errors'].include?(['subject', "can't be blank"])
-    end
-  end
-
-  # Issue 6 is on a private project
-  context "PUT /issues/6.xml" do
-    setup do
-      @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
-      @headers = { :authorization => credentials('jsmith') }
-    end
-
-    should_allow_api_authentication(:put,
-                                    '/issues/6.xml',
-                                    {:issue => {:subject => 'API update', :notes => 'A new note'}},
-                                    {:success_code => :ok})
-
-    should "not create a new issue" do
-      assert_no_difference('Issue.count') do
-        put '/issues/6.xml', @parameters, @headers
-      end
-    end
-
-    should "create a new journal" do
-      assert_difference('Journal.count') do
-        put '/issues/6.xml', @parameters, @headers
-      end
-    end
-
-    should "add the note to the journal" do
-      put '/issues/6.xml', @parameters, @headers
-
-      journal = Journal.last
-      assert_equal "A new note", journal.notes
-    end
-
-    should "update the issue" do
-      put '/issues/6.xml', @parameters, @headers
-
-      issue = Issue.find(6)
-      assert_equal "API update", issue.subject
-    end
-
-  end
-
-  context "PUT /issues/3.xml with custom fields" do
-    setup do
-      @parameters = {:issue => {:custom_fields => [{'id' => '1', 'value' => 'PostgreSQL' }, {'id' => '2', 'value' => '150'}]}}
-      @headers = { :authorization => credentials('jsmith') }
-    end
-
-    should "update custom fields" do
-      assert_no_difference('Issue.count') do
-        put '/issues/3.xml', @parameters, @headers
-      end
-
-      issue = Issue.find(3)
-      assert_equal '150', issue.custom_value_for(2).value
-      assert_equal 'PostgreSQL', issue.custom_value_for(1).value
-    end
-  end
-
-  context "PUT /issues/6.xml with failed update" do
-    setup do
-      @parameters = {:issue => {:subject => ''}}
-      @headers = { :authorization => credentials('jsmith') }
-    end
-
-    should "not create a new issue" do
-      assert_no_difference('Issue.count') do
-        put '/issues/6.xml', @parameters, @headers
-      end
-    end
-
-    should "not create a new journal" do
-      assert_no_difference('Journal.count') do
-        put '/issues/6.xml', @parameters, @headers
-      end
-    end
-
-    should "have an errors tag" do
-      put '/issues/6.xml', @parameters, @headers
-
-      assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
-    end
-  end
-
-  context "PUT /issues/6.json" do
-    setup do
-      @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
-      @headers = { :authorization => credentials('jsmith') }
-    end
-
-    should_allow_api_authentication(:put,
-                                    '/issues/6.json',
-                                    {:issue => {:subject => 'API update', :notes => 'A new note'}},
-                                    {:success_code => :ok})
-
-    should "not create a new issue" do
-      assert_no_difference('Issue.count') do
-        put '/issues/6.json', @parameters, @headers
-      end
-    end
-
-    should "create a new journal" do
-      assert_difference('Journal.count') do
-        put '/issues/6.json', @parameters, @headers
-      end
-    end
-
-    should "add the note to the journal" do
-      put '/issues/6.json', @parameters, @headers
-
-      journal = Journal.last
-      assert_equal "A new note", journal.notes
-    end
-
-    should "update the issue" do
-      put '/issues/6.json', @parameters, @headers
-
-      issue = Issue.find(6)
-      assert_equal "API update", issue.subject
-    end
-
-  end
-
-  context "PUT /issues/6.json with failed update" do
-    setup do
-      @parameters = {:issue => {:subject => ''}}
-      @headers = { :authorization => credentials('jsmith') }
-    end
-
-    should "not create a new issue" do
-      assert_no_difference('Issue.count') do
-        put '/issues/6.json', @parameters, @headers
-      end
-    end
-
-    should "not create a new journal" do
-      assert_no_difference('Journal.count') do
-        put '/issues/6.json', @parameters, @headers
-      end
-    end
-
-    should "have an errors attribute" do
-      put '/issues/6.json', @parameters, @headers
-
-      json = ActiveSupport::JSON.decode(response.body)
-      assert json['errors'].include?(['subject', "can't be blank"])
-    end
-  end
-
-  context "DELETE /issues/1.xml" do
-    should_allow_api_authentication(:delete,
-                                    '/issues/6.xml',
-                                    {},
-                                    {:success_code => :ok})
-
-    should "delete the issue" do
-      assert_difference('Issue.count',-1) do
-        delete '/issues/6.xml', {}, :authorization => credentials('jsmith')
-      end
-
-      assert_nil Issue.find_by_id(6)
-    end
-  end
-
-  context "DELETE /issues/1.json" do
-    should_allow_api_authentication(:delete,
-                                    '/issues/6.json',
-                                    {},
-                                    {:success_code => :ok})
-
-    should "delete the issue" do
-      assert_difference('Issue.count',-1) do
-        delete '/issues/6.json', {}, :authorization => credentials('jsmith')
-      end
-
-      assert_nil Issue.find_by_id(6)
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2b/2b22d90c6bc0187f71e0f86b9bffc12dccfc3f03.svn-base
--- /dev/null
+++ b/.svn/pristine/2b/2b22d90c6bc0187f71e0f86b9bffc12dccfc3f03.svn-base
@@ -0,0 +1,337 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ProjectCopyTest < ActiveSupport::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :journals, :journal_details,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :custom_fields,
+           :custom_fields_projects,
+           :custom_fields_trackers,
+           :custom_values,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :versions,
+           :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
+           :groups_users,
+           :boards, :messages,
+           :repositories,
+           :news, :comments,
+           :documents
+
+  def setup
+    ProjectCustomField.destroy_all
+    @source_project = Project.find(2)
+    @project = Project.new(:name => 'Copy Test', :identifier => 'copy-test')
+    @project.trackers = @source_project.trackers
+    @project.enabled_module_names = @source_project.enabled_modules.collect(&:name)
+  end
+
+  test "#copy should copy issues" do
+    @source_project.issues << Issue.generate!(:status => IssueStatus.find_by_name('Closed'),
+                                              :subject => "copy issue status",
+                                              :tracker_id => 1,
+                                              :assigned_to_id => 2,
+                                              :project_id => @source_project.id)
+    assert @project.valid?
+    assert @project.issues.empty?
+    assert @project.copy(@source_project)
+
+    assert_equal @source_project.issues.size, @project.issues.size
+    @project.issues.each do |issue|
+      assert issue.valid?
+      assert ! issue.assigned_to.blank?
+      assert_equal @project, issue.project
+    end
+
+    copied_issue = @project.issues.first(:conditions => {:subject => "copy issue status"})
+    assert copied_issue
+    assert copied_issue.status
+    assert_equal "Closed", copied_issue.status.name
+  end
+
+  test "#copy should copy issues custom values" do
+    field = IssueCustomField.generate!(:is_for_all => true, :trackers => Tracker.all)
+    issue = Issue.generate!(:project => @source_project, :subject => 'Custom field copy')
+    issue.custom_field_values = {field.id => 'custom'}
+    issue.save!
+    assert_equal 'custom', issue.reload.custom_field_value(field)
+
+    assert @project.copy(@source_project)
+    copy = @project.issues.find_by_subject('Custom field copy')
+    assert copy
+    assert_equal 'custom', copy.reload.custom_field_value(field)
+  end
+
+  test "#copy should copy issues assigned to a locked version" do
+    User.current = User.find(1)
+    assigned_version = Version.generate!(:name => "Assigned Issues")
+    @source_project.versions << assigned_version
+    Issue.generate!(:project => @source_project,
+                    :fixed_version_id => assigned_version.id,
+                    :subject => "copy issues assigned to a locked version")
+    assigned_version.update_attribute :status, 'locked'
+
+    assert @project.copy(@source_project)
+    @project.reload
+    copied_issue = @project.issues.first(:conditions => {:subject => "copy issues assigned to a locked version"})
+
+    assert copied_issue
+    assert copied_issue.fixed_version
+    assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
+    assert_equal 'locked', copied_issue.fixed_version.status
+  end
+
+  test "#copy should change the new issues to use the copied version" do
+    User.current = User.find(1)
+    assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open')
+    @source_project.versions << assigned_version
+    assert_equal 3, @source_project.versions.size
+    Issue.generate!(:project => @source_project,
+                    :fixed_version_id => assigned_version.id,
+                    :subject => "change the new issues to use the copied version")
+
+    assert @project.copy(@source_project)
+    @project.reload
+    copied_issue = @project.issues.first(:conditions => {:subject => "change the new issues to use the copied version"})
+
+    assert copied_issue
+    assert copied_issue.fixed_version
+    assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
+    assert_not_equal assigned_version.id, copied_issue.fixed_version.id # Different record
+  end
+
+  test "#copy should keep target shared versions from other project" do
+    assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open', :project_id => 1, :sharing => 'system')
+    issue = Issue.generate!(:project => @source_project,
+                            :fixed_version => assigned_version,
+                            :subject => "keep target shared versions")
+
+    assert @project.copy(@source_project)
+    @project.reload
+    copied_issue = @project.issues.first(:conditions => {:subject => "keep target shared versions"})
+
+    assert copied_issue
+    assert_equal assigned_version, copied_issue.fixed_version
+  end
+
+  test "#copy should copy issue relations" do
+    Setting.cross_project_issue_relations = '1'
+
+    second_issue = Issue.generate!(:status_id => 5,
+                                   :subject => "copy issue relation",
+                                   :tracker_id => 1,
+                                   :assigned_to_id => 2,
+                                   :project_id => @source_project.id)
+    source_relation = IssueRelation.create!(:issue_from => Issue.find(4),
+                                              :issue_to => second_issue,
+                                              :relation_type => "relates")
+    source_relation_cross_project = IssueRelation.create!(:issue_from => Issue.find(1),
+                                                            :issue_to => second_issue,
+                                                            :relation_type => "duplicates")
+
+    assert @project.copy(@source_project)
+    assert_equal @source_project.issues.count, @project.issues.count
+    copied_issue = @project.issues.find_by_subject("Issue on project 2") # Was #4
+    copied_second_issue = @project.issues.find_by_subject("copy issue relation")
+
+    # First issue with a relation on project
+    assert_equal 1, copied_issue.relations.size, "Relation not copied"
+    copied_relation = copied_issue.relations.first
+    assert_equal "relates", copied_relation.relation_type
+    assert_equal copied_second_issue.id, copied_relation.issue_to_id
+    assert_not_equal source_relation.id, copied_relation.id
+
+    # Second issue with a cross project relation
+    assert_equal 2, copied_second_issue.relations.size, "Relation not copied"
+    copied_relation = copied_second_issue.relations.select {|r| r.relation_type == 'duplicates'}.first
+    assert_equal "duplicates", copied_relation.relation_type
+    assert_equal 1, copied_relation.issue_from_id, "Cross project relation not kept"
+    assert_not_equal source_relation_cross_project.id, copied_relation.id
+  end
+
+  test "#copy should copy issue attachments" do
+    issue = Issue.generate!(:subject => "copy with attachment", :tracker_id => 1, :project_id => @source_project.id)
+    Attachment.create!(:container => issue, :file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 1)
+    @source_project.issues << issue
+    assert @project.copy(@source_project)
+
+    copied_issue = @project.issues.first(:conditions => {:subject => "copy with attachment"})
+    assert_not_nil copied_issue
+    assert_equal 1, copied_issue.attachments.count, "Attachment not copied"
+    assert_equal "testfile.txt", copied_issue.attachments.first.filename
+  end
+
+  test "#copy should copy memberships" do
+    assert @project.valid?
+    assert @project.members.empty?
+    assert @project.copy(@source_project)
+
+    assert_equal @source_project.memberships.size, @project.memberships.size
+    @project.memberships.each do |membership|
+      assert membership
+      assert_equal @project, membership.project
+    end
+  end
+
+  test "#copy should copy memberships with groups and additional roles" do
+    group = Group.create!(:lastname => "Copy group")
+    user = User.find(7)
+    group.users << user
+    # group role
+    Member.create!(:project_id => @source_project.id, :principal => group, :role_ids => [2])
+    member = Member.find_by_user_id_and_project_id(user.id, @source_project.id)
+    # additional role
+    member.role_ids = [1]
+
+    assert @project.copy(@source_project)
+    member = Member.find_by_user_id_and_project_id(user.id, @project.id)
+    assert_not_nil member
+    assert_equal [1, 2], member.role_ids.sort
+  end
+
+  test "#copy should copy project specific queries" do
+    assert @project.valid?
+    assert @project.queries.empty?
+    assert @project.copy(@source_project)
+
+    assert_equal @source_project.queries.size, @project.queries.size
+    @project.queries.each do |query|
+      assert query
+      assert_equal @project, query.project
+    end
+    assert_equal @source_project.queries.map(&:user_id).sort, @project.queries.map(&:user_id).sort
+  end
+
+  test "#copy should copy versions" do
+    @source_project.versions << Version.generate!
+    @source_project.versions << Version.generate!
+
+    assert @project.versions.empty?
+    assert @project.copy(@source_project)
+
+    assert_equal @source_project.versions.size, @project.versions.size
+    @project.versions.each do |version|
+      assert version
+      assert_equal @project, version.project
+    end
+  end
+
+  test "#copy should copy wiki" do
+    assert_difference 'Wiki.count' do
+      assert @project.copy(@source_project)
+    end
+
+    assert @project.wiki
+    assert_not_equal @source_project.wiki, @project.wiki
+    assert_equal "Start page", @project.wiki.start_page
+  end
+
+  test "#copy should copy wiki without wiki module" do
+    project = Project.new(:name => 'Copy Test', :identifier => 'copy-test', :enabled_module_names => [])
+    assert_difference 'Wiki.count' do
+      assert project.copy(@source_project)
+    end
+
+    assert project.wiki
+  end
+
+  test "#copy should copy wiki pages and content with hierarchy" do
+    assert_difference 'WikiPage.count', @source_project.wiki.pages.size do
+      assert @project.copy(@source_project)
+    end
+
+    assert @project.wiki
+    assert_equal @source_project.wiki.pages.size, @project.wiki.pages.size
+
+    @project.wiki.pages.each do |wiki_page|
+      assert wiki_page.content
+      assert !@source_project.wiki.pages.include?(wiki_page)
+    end
+
+    parent = @project.wiki.find_page('Parent_page')
+    child1 = @project.wiki.find_page('Child_page_1')
+    child2 = @project.wiki.find_page('Child_page_2')
+    assert_equal parent, child1.parent
+    assert_equal parent, child2.parent
+  end
+
+  test "#copy should copy issue categories" do
+    assert @project.copy(@source_project)
+
+    assert_equal 2, @project.issue_categories.size
+    @project.issue_categories.each do |issue_category|
+      assert !@source_project.issue_categories.include?(issue_category)
+    end
+  end
+
+  test "#copy should copy boards" do
+    assert @project.copy(@source_project)
+
+    assert_equal 1, @project.boards.size
+    @project.boards.each do |board|
+      assert !@source_project.boards.include?(board)
+    end
+  end
+
+  test "#copy should change the new issues to use the copied issue categories" do
+    issue = Issue.find(4)
+    issue.update_attribute(:category_id, 3)
+
+    assert @project.copy(@source_project)
+
+    @project.issues.each do |issue|
+      assert issue.category
+      assert_equal "Stock management", issue.category.name # Same name
+      assert_not_equal IssueCategory.find(3), issue.category # Different record
+    end
+  end
+
+  test "#copy should limit copy with :only option" do
+    assert @project.members.empty?
+    assert @project.issue_categories.empty?
+    assert @source_project.issues.any?
+
+    assert @project.copy(@source_project, :only => ['members', 'issue_categories'])
+
+    assert @project.members.any?
+    assert @project.issue_categories.any?
+    assert @project.issues.empty?
+  end
+
+  test "#copy should copy subtasks" do
+    source = Project.generate!(:tracker_ids => [1])
+    issue = Issue.generate_with_descendants!(:project => source)
+    project = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1])
+
+    assert_difference 'Project.count' do
+      assert_difference 'Issue.count', 1+issue.descendants.count do
+        assert project.copy(source.reload)
+      end
+    end
+    copy = Issue.where(:parent_id => nil).order("id DESC").first
+    assert_equal project, copy.project
+    assert_equal issue.descendants.count, copy.descendants.count
+    child_copy = copy.children.detect {|c| c.subject == 'Child1'}
+    assert child_copy.descendants.any?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2b/2b52b333ebdd9a328bfca27bab6d9bb1f5c45425.svn-base
--- /dev/null
+++ b/.svn/pristine/2b/2b52b333ebdd9a328bfca27bab6d9bb1f5c45425.svn-base
@@ -0,0 +1,75 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class ActivitiesController < ApplicationController
+  menu_item :activity
+  before_filter :find_optional_project
+  accept_rss_auth :index
+
+  def index
+    @days = Setting.activity_days_default.to_i
+
+    if params[:from]
+      begin; @date_to = params[:from].to_date + 1; rescue; end
+    end
+
+    @date_to ||= Date.today + 1
+    @date_from = @date_to - @days
+    @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
+    @author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id]))
+
+    @activity = Redmine::Activity::Fetcher.new(User.current, :project => @project,
+                                                             :with_subprojects => @with_subprojects,
+                                                             :author => @author)
+    @activity.scope_select {|t| !params["show_#{t}"].nil?}
+    @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty?
+
+    events = @activity.events(@date_from, @date_to)
+
+    if events.empty? || stale?(:etag => [@activity.scope, @date_to, @date_from, @with_subprojects, @author, events.first, events.size, User.current, current_language])
+      respond_to do |format|
+        format.html {
+          @events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)}
+          render :layout => false if request.xhr?
+        }
+        format.atom {
+          title = l(:label_activity)
+          if @author
+            title = @author.name
+          elsif @activity.scope.size == 1
+            title = l("label_#{@activity.scope.first.singularize}_plural")
+          end
+          render_feed(events, :title => "#{@project || Setting.app_title}: #{title}")
+        }
+      end
+    end
+
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  private
+
+  # TODO: refactor, duplicated in projects_controller
+  def find_optional_project
+    return true unless params[:id]
+    @project = Project.find(params[:id])
+    authorize
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2b/2b8d3c9c3c263ae7cd6f97cc6dd5f192b92ebd2b.svn-base
--- a/.svn/pristine/2b/2b8d3c9c3c263ae7cd6f97cc6dd5f192b92ebd2b.svn-base
+++ /dev/null
@@ -1,69 +0,0 @@
-# The MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-# This implements native php methods used by tcpdf, which have had to be
-# reimplemented within Ruby.
-
-module RFPDF
-
-  # http://uk2.php.net/getimagesize
-  def getimagesize(filename)
-    image = Magick::ImageList.new(filename)
-    
-    out = Hash.new
-    out[0] = image.columns
-    out[1] = image.rows
-    
-    # These are actually meant to return integer values But I couldn't seem to find anything saying what those values are.
-    # So for now they return strings. The only place that uses this at the moment is the parsejpeg method, so I've changed that too.
-    case image.mime_type
-    when "image/gif"
-      out[2] = "GIF"
-    when "image/jpeg"
-      out[2] = "JPEG"
-    when "image/png"
-      out[2] = "PNG"
-    when " 	image/vnd.wap.wbmp"
-      out[2] = "WBMP"
-    when "image/x-xpixmap"
-      out[2] = "XPM"
-    end
-    out[3] = "height=\"#{image.rows}\" width=\"#{image.columns}\""
-    out['mime'] = image.mime_type
-    
-    # This needs work to cover more situations
-    # I can't see how to just list the number of channels with ImageMagick / rmagick
-    if image.colorspace.to_s == "CMYKColorspace"
-        out['channels'] = 4
-    elsif image.colorspace.to_s == "RGBColorspace"
-      out['channels'] = 3
-    end
-
-    out['bits'] = image.channel_depth
-    File.open( TCPDF.k_path_cache + File::basename(filename), 'w'){|f|
-      f.binmode
-      f.print image.to_blob
-      f.close
-    }
-    
-    out
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2b/2b9b5932a0933b4096addb68309527dfbf45da2c.svn-base
--- /dev/null
+++ b/.svn/pristine/2b/2b9b5932a0933b4096addb68309527dfbf45da2c.svn-base
@@ -0,0 +1,32 @@
+<% if version.completed? %>
+  <p><%= format_date(version.effective_date) %></p>
+<% elsif version.effective_date %>
+  <p><strong><%= due_date_distance_in_words(version.effective_date) %></strong> (<%= format_date(version.effective_date) %>)</p>
+<% end %>
+
+<p><%=h version.description %></p>
+<% if version.custom_field_values.any? %>
+<ul>
+  <% version.custom_field_values.each do |custom_value| %>
+    <% if custom_value.value.present? %>
+       <li><%=h custom_value.custom_field.name %>: <%=h show_value(custom_value) %></li>
+    <% end %>
+  <% end %>
+</ul>
+<% end %>
+
+<% if version.issues_count > 0 %>
+    <%= progress_bar([version.closed_percent, version.completed_percent], :width => '40em', :legend => ('%0.0f%' % version.completed_percent)) %>
+    <p class="progress-info">
+    	  <%= link_to(l(:label_x_issues, :count => version.issues_count), 
+              project_issues_path(version.project, :status_id => '*', :fixed_version_id => version, :set_filter => 1)) %>
+				&nbsp;
+        (<%= link_to_if(version.closed_issues_count > 0, l(:label_x_closed_issues_abbr, :count => version.closed_issues_count), 
+               project_issues_path(version.project, :status_id => 'c', :fixed_version_id => version, :set_filter => 1)) %>
+        &#8212;
+        <%= link_to_if(version.open_issues_count > 0, l(:label_x_open_issues_abbr, :count => version.open_issues_count), 
+              project_issues_path(version.project, :status_id => 'o', :fixed_version_id => version, :set_filter => 1)) %>)
+    </p>
+<% else %>
+    <p class="progress-info"><%= l(:label_roadmap_no_issues) %></p>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2c/2cde7dc8fe86b1b79ab2ee40c054579ef58ee63c.svn-base
--- a/.svn/pristine/2c/2cde7dc8fe86b1b79ab2ee40c054579ef58ee63c.svn-base
+++ /dev/null
@@ -1,1015 +0,0 @@
-# Croatian translations for Ruby on Rails 
-# by Helix d.o.o. (info@helix.hr)
-
-hr:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%m/%d/%Y"
-      short: "%b %d"
-      long: "%B %d, %Y"
-      
-    day_names: [Ponedjeljak, Utorak, Srijeda, ÄŒetvrtak, Petak, Subota, Nedjelja]
-    abbr_day_names: [Ned, Pon, Uto, Sri, ÄŒet, Pet, Sub]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Sijecanj, Veljaca, OÅ¾ujak, Travanj, Svibanj, Lipanj, Srpanj, Kolovoz, Rujan, Listopad, Studeni, Prosinac]
-    abbr_month_names: [~, Sij, Velj, OÅ¾u, Tra, Svi, Lip, Srp, Kol, Ruj, List, Stu, Pro]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%m/%d/%Y %I:%M %p"
-      time: "%I:%M %p"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "am"
-    pm: "pm"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "pola minute"
-      less_than_x_seconds:
-        one:   "manje od sekunde"
-        other: "manje od %{count} sekundi"
-      x_seconds:
-        one:   "1 sekunda"
-        other: "%{count} sekundi"
-      less_than_x_minutes:
-        one:   "manje od minute"
-        other: "manje od %{count} minuta"
-      x_minutes:
-        one:   "1 minuta"
-        other: "%{count} minuta"
-      about_x_hours:
-        one:   "oko sat vremena"
-        other: "oko %{count} sati"
-      x_days:
-        one:   "1 dan"
-        other: "%{count} dana"
-      about_x_months:
-        one:   "oko 1 mjesec"
-        other: "oko %{count} mjeseci"
-      x_months:
-        one:   "mjesec"
-        other: "%{count} mjeseci"
-      about_x_years:
-        one:   "1 godina"
-        other: "%{count} godina"
-      over_x_years:
-        one:   "preko 1 godine"
-        other: "preko %{count} godina"
-
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-  
-     
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "i"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "nije ukljuceno u listu"
-        exclusion: "je rezervirano"
-        invalid: "nije ispravno"
-        confirmation: "ne odgovara za potvrdu"
-        accepted: "mora biti prihvaÄ‡en"
-        empty: "ne moÅ¾e biti prazno"
-        blank: "ne moÅ¾e biti razmaka"
-        too_long: "je predug (maximum is %{count} characters)"
-        too_short: "je prekratak (minimum is %{count} characters)"
-        wrong_length: "je pogreÅ¡ne duÅ¾ine (should be %{count} characters)"
-        taken: "veÄ‡ je zauzeto"
-        not_a_number: "nije broj"
-        not_a_date: "nije ispravan datum"
-        greater_than: "mora biti veÄ‡i od %{count}"
-        greater_than_or_equal_to: "mora biti veÄ‡i ili jednak %{count}"
-        equal_to: "mora biti jednak %{count}"
-        less_than: "mora biti manji od %{count}"
-        less_than_or_equal_to: "mora bit manji ili jednak%{count}"
-        odd: "mora biti neparan"
-        even: "mora biti paran"
-        greater_than_start_date: "mora biti veci nego pocetni datum"
-        not_same_project: "ne pripada istom projektu"
-        circular_dependency: "Ovaj relacija stvara kruÅ¾nu ovisnost"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: Molimo odaberite
-  
-  general_text_No: 'Ne'
-  general_text_Yes: 'Da'
-  general_text_no: 'ne'
-  general_text_yes: 'da'
-  general_lang_name: 'Hrvatski'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '7'
-  
-  notice_account_updated: VaÅ¡ profil je uspjeÅ¡no promijenjen.
-  notice_account_invalid_creditentials: Neispravno korisniÄko ime ili zaporka.
-  notice_account_password_updated: Zaporka je uspjeÅ¡no promijenjena.
-  notice_account_wrong_password: PogreÅ¡na zaporka
-  notice_account_register_done: Racun je uspjeÅ¡no napravljen. Da biste aktivirali svoj raÄun, kliknite na link koji vam je poslan na e-mail.
-  notice_account_unknown_email: Nepoznati korisnik.
-  notice_can_t_change_password: Ovaj raÄun koristi eksterni izvor prijavljivanja. NemoguÄ‡e je promijeniti zaporku.
-  notice_account_lost_email_sent: E-mail s uputama kako bi odabrali novu zaporku je poslan na na vaÅ¡u e-mail adresu.
-  notice_account_activated: VaÅ¡ racun je aktiviran. MoÅ¾ete se prijaviti.
-  notice_successful_create: UspjeÅ¡no napravljeno.
-  notice_successful_update: UspjeÅ¡na promjena.
-  notice_successful_delete: UspjeÅ¡no brisanje.
-  notice_successful_connection: UspjeÅ¡na veza.
-  notice_file_not_found: Stranica kojoj ste pokuÅ¡ali pristupiti ne postoji ili je uklonjena.
-  notice_locking_conflict: Podataci su aÅ¾urirani od strane drugog korisnika.
-  notice_not_authorized: Niste ovlaÅ¡teni za pristup ovoj stranici. 
-  notice_email_sent: E-mail je poslan %{value}"
-  notice_email_error: Dogodila se pogreÅ¡ka tijekom slanja E-maila (%{value})"
-  notice_feeds_access_key_reseted: VaÅ¡ RSS pristup je resetovan.
-  notice_api_access_key_reseted: VaÅ¡ API pristup je resetovan.
-  notice_failed_to_save_issues: "Neuspjelo spremanje %{count} predmeta na %{total} odabrane: %{ids}."
-  notice_no_issue_selected: "Niti jedan predmet nije odabran! Molim, odaberite predmete koje Å¾elite urediti."
-  notice_account_pending: "VaÅ¡ korisnicki raÄun je otvoren, Äeka odobrenje administratora."
-  notice_default_data_loaded: Konfiguracija je uspjeÅ¡no uÄitana.
-  notice_unable_delete_version: Nije moguÄ‡e izbrisati verziju.
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  
-  error_can_t_load_default_data: "Zadanu konfiguracija nije uÄitana: %{value}"
-  error_scm_not_found: "Unos i/ili revizija nije pronaÄ‘en."
-  error_scm_command_failed: "Dogodila se pogreÅ¡ka prilikom pokuÅ¡aja pristupa: %{value}"
-  error_scm_annotate: "Ne postoji ili ne moÅ¾e biti obiljeÅ¾en."
-  error_issue_not_found_in_project: 'Nije pronaÄ‘en ili ne pripada u ovaj projekt'
-  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
-  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
-  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version can not be reopened'
-  error_can_not_archive_project: This project can not be archived
-  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
-  error_workflow_copy_source: 'Please select a source tracker or role'
-  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
-    
-  warning_attachments_not_saved: "%{count} Datoteka/e nije mogla biti spremljena."
-  
-  mail_subject_lost_password: "VaÅ¡a %{value} zaporka"
-  mail_body_lost_password: 'Kako biste promijenili VaÅ¡u zaporku slijedite poveznicu:'
-  mail_subject_register: "Aktivacija korisniÄog raÄuna %{value}"
-  mail_body_register: 'Da biste aktivirali svoj raÄun, kliknite na sljedeci link:'
-  mail_body_account_information_external: "MoÅ¾ete koristiti vaÅ¡ raÄun %{value} za prijavu."
-  mail_body_account_information: VaÅ¡i korisniÄki podaci
-  mail_subject_account_activation_request: "%{value} predmet za aktivaciju korisniÄkog raÄuna"
-  mail_body_account_activation_request: "Novi korisnik (%{value}) je registriran. Njegov korisniÄki raÄun Äeka vaÅ¡e odobrenje:"
-  mail_subject_reminder: "%{count} predmet(a) dospijeva sljedeÄ‡ih %{days} dana"
-  mail_body_reminder: "%{count} vama dodijeljen(ih) predmet(a) dospijeva u sljedeÄ‡ih %{days} dana:"
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
-  
-  gui_validation_error: 1 pogreÅ¡ka
-  gui_validation_error_plural: "%{count} pogreÅ¡aka"
-   
-  field_name: Ime
-  field_description: Opis
-  field_summary: SaÅ¾etak
-  field_is_required: Obavezno
-  field_firstname: Ime
-  field_lastname: Prezime
-  field_mail: E-poÅ¡ta
-  field_filename: Datoteka
-  field_filesize: VeliÄina
-  field_downloads: Preuzimanja
-  field_author: Autor
-  field_created_on: Napravljen
-  field_updated_on: Promijenjen
-  field_field_format: Format
-  field_is_for_all: Za sve projekte
-  field_possible_values: MoguÄ‡e vrijednosti
-  field_regexp: Regularni izraz
-  field_min_length: Minimalna duÅ¾ina
-  field_max_length: Maksimalna duÅ¾ina
-  field_value: Vrijednost
-  field_category: Kategorija
-  field_title: Naslov
-  field_project: Projekt
-  field_issue: Predmet
-  field_status: Status
-  field_notes: Napomene
-  field_is_closed: Predmet je zatvoren
-  field_is_default: Zadana vrijednost
-  field_tracker: Tracker
-  field_subject: Predmet
-  field_due_date: Do datuma
-  field_assigned_to: Dodijeljeno
-  field_priority: Prioritet
-  field_fixed_version: Verzija
-  field_user: Korisnik
-  field_role: Uloga
-  field_homepage: Naslovnica
-  field_is_public: Javni projekt
-  field_parent: Potprojekt od
-  field_is_in_chlog: Predmeti se prikazuju u dnevniku promjena
-  field_is_in_roadmap: Predmeti se prikazuju u Putokazu
-  field_login: KorisniÄko ime
-  field_mail_notification: Obavijest putem e-poÅ¡te
-  field_admin: Administrator
-  field_last_login_on: Zadnja prijava
-  field_language: Primarni jezik
-  field_effective_date: Datum
-  field_password: Zaporka
-  field_new_password: Nova zaporka
-  field_password_confirmation: Potvrda zaporke
-  field_version: Verzija
-  field_type: Tip
-  field_host: Host
-  field_port: Port
-  field_account: Racun
-  field_base_dn: Osnovni DN
-  field_attr_login: Login atribut
-  field_attr_firstname: Atribut imena
-  field_attr_lastname: Atribut prezimena
-  field_attr_mail: Atribut e-poÅ¡te
-  field_onthefly: "Izrada korisnika \"u hodu\""
-  field_start_date: Pocetak
-  field_done_ratio: "% UÄinjeno"
-  field_auth_source: Vrsta prijavljivanja
-  field_hide_mail: Sakrij moju adresu e-poÅ¡te
-  field_comments: Komentar
-  field_url: URL
-  field_start_page: PoÄetna stranica
-  field_subproject: Potprojekt
-  field_hours: Sati
-  field_activity: Aktivnost
-  field_spent_on: Datum
-  field_identifier: Identifikator
-  field_is_filter: KoriÅ¡teno kao filtar
-  field_issue_to_id: Povezano s predmetom
-  field_delay: Odgodeno
-  field_assignable: Predmeti mogu biti dodijeljeni ovoj ulozi
-  field_redirect_existing_links: Preusmjeravanje postojeÄ‡ih linkova
-  field_estimated_hours: Procijenjeno vrijeme
-  field_column_names: Stupci
-  field_time_zone: Vremenska zona
-  field_searchable: PretraÅ¾ivo
-  field_default_value: Zadana vrijednost
-  field_comments_sorting: Prikaz komentara
-  field_parent_title: Parent page
-  field_editable: Editable
-  field_watcher: Watcher
-  field_identity_url: OpenID URL
-  field_content: Content
-  field_group_by: Group results by
-  
-  setting_app_title: Naziv aplikacije
-  setting_app_subtitle: Podnaslov aplikacije
-  setting_welcome_text: Tekst dobrodoÅ¡lice
-  setting_default_language: Zadani jezik
-  setting_login_required: Potrebna je prijava
-  setting_self_registration: Samoregistracija je dozvoljena
-  setting_attachment_max_size: Maksimalna veliÄina privitka
-  setting_issues_export_limit: OgraniÄenje izvoza predmeta
-  setting_mail_from: Izvorna adresa e-poÅ¡te
-  setting_bcc_recipients: Blind carbon copy primatelja (bcc)
-  setting_plain_text_mail: obiÄni tekst poÅ¡te (bez HTML-a)
-  setting_host_name: Naziv domaÄ‡ina (host)
-  setting_text_formatting: Oblikovanje teksta
-  setting_wiki_compression: SaÅ¾imanje
-  setting_feeds_limit: Ogranicenje unosa sadrÅ¾aja
-  setting_default_projects_public: Novi projekti su javni po defaultu
-  setting_autofetch_changesets: Autofetch commits
-  setting_sys_api_enabled: OmoguÄ‡i WS za upravljanje skladiÅ¡tem
-  setting_commit_ref_keywords: Referentne kljuÄne rijeÄi
-  setting_commit_fix_keywords: Fiksne kljuÄne rijeÄi
-  setting_autologin: Automatska prijava
-  setting_date_format: Format datuma
-  setting_time_format: Format vremena
-  setting_cross_project_issue_relations: Dozvoli povezivanje predmeta izmedu razliÄitih projekata
-  setting_issue_list_default_columns: Stupci prikazani na listi predmeta
-  setting_emails_footer: Zaglavlje e-poÅ¡te
-  setting_protocol: Protokol
-  setting_per_page_options: Objekata po stranici opcija
-  setting_user_format: Oblik prikaza korisnika
-  setting_activity_days_default: Dani prikazane aktivnosti na projektu
-  setting_display_subprojects_issues: Prikaz predmeta potprojekta na glavnom projektu po defaultu
-  setting_enabled_scm: OmoguÄ‡en SCM
-  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
-  setting_mail_handler_api_enabled: Omoguci WS za dolaznu e-poÅ¡tu
-  setting_mail_handler_api_key: API kljuÄ
-  setting_sequential_project_identifiers: Generiraj slijedne identifikatore projekta
-  setting_gravatar_enabled: Koristi Gravatar korisniÄke ikone
-  setting_gravatar_default: Default Gravatar image
-  setting_diff_max_lines_displayed: Maksimalni broj diff linija za prikazati
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_openid: Allow OpenID login and registration
-  setting_password_min_length: Minimum password length
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  setting_default_projects_modules: Default enabled modules for new projects 
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_field: Use the issue field
-  setting_issue_done_ratio_issue_status: Use the issue status
-  setting_start_of_week: Start calendars on
-  setting_rest_api_enabled: Enable REST web service
-   
-  permission_add_project: Dodaj projekt
-  permission_add_subprojects: Dodaj potprojekt 
-  permission_edit_project: Uredi projekt
-  permission_select_project_modules: Odaberi projektne module
-  permission_manage_members: Upravljaj Älanovima
-  permission_manage_versions: Upravljaj verzijama
-  permission_manage_categories: Upravljaj kategorijama predmeta
-  permission_view_issues: Pregledaj zahtjeve
-  permission_add_issues: Dodaj predmete 
-  permission_edit_issues: Uredi predmete
-  permission_manage_issue_relations: Upravljaj relacijama predmeta
-  permission_add_issue_notes: Dodaj biljeÅ¡ke 
-  permission_edit_issue_notes: Uredi biljeÅ¡ke 
-  permission_edit_own_issue_notes: Uredi vlastite biljeÅ¡ke
-  permission_move_issues: Premjesti predmete 
-  permission_delete_issues: Brisanje predmeta
-  permission_manage_public_queries: Upravljaj javnim upitima
-  permission_save_queries: Spremi upite 
-  permission_view_gantt: Pregledaj gantt grafikon
-  permission_view_calendar: Pregledaj kalendar
-  permission_view_issue_watchers: Pregledaj listu promatraca
-  permission_add_issue_watchers: Dodaj promatraÄa
-  permission_delete_issue_watchers: Delete watchers
-  permission_log_time: Dnevnik utroÅ¡enog vremena 
-  permission_view_time_entries: Pregledaj utroÅ¡eno vrijeme
-  permission_edit_time_entries: Uredi vremenske dnevnike
-  permission_edit_own_time_entries: Edit own time logs
-  permission_manage_news: Upravljaj novostima
-  permission_comment_news: Komentiraj novosti
-  permission_manage_documents: Upravljaj dokumentima
-  permission_view_documents: Pregledaj dokumente
-  permission_manage_files: Upravljaj datotekama
-  permission_view_files: Pregledaj datoteke
-  permission_manage_wiki: Upravljaj wikijem
-  permission_rename_wiki_pages: Promijeni ime wiki stranicama
-  permission_delete_wiki_pages: ObriÅ¡i wiki stranice
-  permission_view_wiki_pages: Pregledaj wiki
-  permission_view_wiki_edits: Pregledaj povijest wikija
-  permission_edit_wiki_pages: Uredi wiki stranice
-  permission_delete_wiki_pages_attachments: ObriÅ¡i privitke
-  permission_protect_wiki_pages: ZaÅ¡titi wiki stranice
-  permission_manage_repository: Upravljaj skladiÅ¡tem
-  permission_browse_repository: Browse repository
-  permission_view_changesets: View changesets
-  permission_commit_access: MoguÄ‡nost pohranjivanja
-  permission_manage_boards: Manage boards
-  permission_view_messages: Pregledaj poruke
-  permission_add_messages: Objavi poruke
-  permission_edit_messages: Uredi poruke
-  permission_edit_own_messages: Uredi vlastite poruke 
-  permission_delete_messages: ObriÅ¡i poruke
-  permission_delete_own_messages: ObriÅ¡i vlastite poruke
-    
-  project_module_issue_tracking: PraÄ‡enje predmeta
-  project_module_time_tracking: PraÄ‡enje vremena
-  project_module_news: Novosti
-  project_module_documents: Dokumenti
-  project_module_files: Datoteke
-  project_module_wiki: Wiki
-  project_module_repository: SkladiÅ¡te
-  project_module_boards: Boards
-  
-  label_user: Korisnik
-  label_user_plural: Korisnici
-  label_user_new: Novi korisnik
-  label_user_anonymous: Anonymous
-  label_project: Projekt
-  label_project_new: Novi projekt
-  label_project_plural: Projekti
-  label_x_projects:
-    zero:  no projects
-    one:   1 project
-    other: "%{count} projects"
-  label_project_all: Svi Projekti
-  label_project_latest: Najnoviji projekt
-  label_issue: Predmet
-  label_issue_new: Novi predmet
-  label_issue_plural: Predmeti
-  label_issue_view_all: Pregled svih predmeta
-  label_issues_by: "Predmeti od %{value}"
-  label_issue_added: Predmet dodan
-  label_issue_updated: Predmet promijenjen
-  label_document: Dokument
-  label_document_new: Novi dokument
-  label_document_plural: Dokumenti
-  label_document_added: Dokument dodan
-  label_role: Uloga
-  label_role_plural: Uloge
-  label_role_new: Nova uloga
-  label_role_and_permissions: Uloge i ovlasti
-  label_member: ÄŒlan
-  label_member_new: Novi Älan
-  label_member_plural: ÄŒlanovi
-  label_tracker: Vrsta
-  label_tracker_plural: Vrste predmeta
-  label_tracker_new: Nova vrsta
-  label_workflow: Tijek rada
-  label_issue_status: Status predmeta
-  label_issue_status_plural: Status predmeta
-  label_issue_status_new: Novi status
-  label_issue_category: Kategorija predmeta
-  label_issue_category_plural: Kategorije predmeta
-  label_issue_category_new: Nova kategorija
-  label_custom_field: KorisniÄki definirano polje
-  label_custom_field_plural: KorisniÄki definirana polja
-  label_custom_field_new: Novo korisniÄki definirano polje
-  label_enumerations: Pobrojenice
-  label_enumeration_new: Nova vrijednost
-  label_information: Informacija
-  label_information_plural: Informacije
-  label_please_login: Molim prijavite se
-  label_register: Registracija
-  label_login_with_open_id_option: or login with OpenID
-  label_password_lost: Izgubljena zaporka
-  label_home: PoÄetna stranica
-  label_my_page: Moja stranica
-  label_my_account: Moj profil
-  label_my_projects: Moji projekti
-  label_administration: Administracija
-  label_login: Korisnik
-  label_logout: Odjava
-  label_help: PomoÄ‡
-  label_reported_issues: Prijavljeni predmeti
-  label_assigned_to_me_issues: Moji predmeti
-  label_last_login: Last connection
-  label_registered_on: Registrirano
-  label_activity: Aktivnosti
-  label_overall_activity: Aktivnosti
-  label_user_activity: "%{value} ova/ina aktivnost"
-  label_new: Novi
-  label_logged_as: Prijavljeni ste kao
-  label_environment: Okolina
-  label_authentication: Autentikacija
-  label_auth_source: NaÄin prijavljivanja
-  label_auth_source_new: Novi naÄin prijavljivanja
-  label_auth_source_plural: NaÄini prijavljivanja
-  label_subproject_plural: Potprojekti
-  label_subproject_new: Novi potprojekt
-  label_and_its_subprojects: "%{value} i njegovi potprojekti"
-  label_min_max_length: Min - Maks  veliÄina
-  label_list: Liste
-  label_date: Datum
-  label_integer: Integer
-  label_float: Float
-  label_boolean: Boolean
-  label_string: Text
-  label_text: Long text
-  label_attribute: Atribut
-  label_attribute_plural: Atributi
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
-  label_no_data: Nema podataka za prikaz
-  label_change_status: Promjena statusa
-  label_history: Povijest
-  label_attachment: Datoteka
-  label_attachment_new: Nova datoteka
-  label_attachment_delete: Brisanje datoteke
-  label_attachment_plural: Datoteke
-  label_file_added: Datoteka dodana
-  label_report: IzvjeÅ¡Ä‡e
-  label_report_plural: IzvjeÅ¡Ä‡a
-  label_news: Novosti
-  label_news_new: Dodaj novost
-  label_news_plural: Novosti
-  label_news_latest: Novosti
-  label_news_view_all: Pregled svih novosti
-  label_news_added: Novosti dodane
-  label_change_log: Dnevnik promjena
-  label_settings: Postavke
-  label_overview: Pregled
-  label_version: Verzija
-  label_version_new: Nova verzija
-  label_version_plural: Verzije
-  label_confirmation: Potvrda
-  label_export_to: 'Izvoz u:'
-  label_read: ÄŒitaj...
-  label_public_projects: Javni projekti
-  label_open_issues: Otvoren
-  label_open_issues_plural: Otvoreno
-  label_closed_issues: Zatvoren
-  label_closed_issues_plural: Zatvoreno
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_total: Ukupno
-  label_permissions: Dozvole
-  label_current_status: Trenutni status
-  label_new_statuses_allowed: Novi status je dozvoljen
-  label_all: Svi
-  label_none: nema
-  label_nobody: nitko
-  label_next: Naredni
-  label_previous: Prethodni
-  label_used_by: KoriÅ¡ten od 
-  label_details: Detalji
-  label_add_note: Dodaj napomenu
-  label_per_page: Po stranici
-  label_calendar: Kalendar
-  label_months_from: Mjeseci od
-  label_gantt: Gantt
-  label_internal: Interno
-  label_last_changes: "Posljednjih %{count} promjena"
-  label_change_view_all: Prikaz svih promjena
-  label_personalize_page: Prilagodite ovu stranicu
-  label_comment: Komentar
-  label_comment_plural: Komentari
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_comment_add: Dodaj komentar
-  label_comment_added: Komentar dodan
-  label_comment_delete: Brisanje komentara
-  label_query: KorisniÄki upit
-  label_query_plural: KorisniÄki upiti
-  label_query_new: Novi upit
-  label_filter_add: Dodaj filtar
-  label_filter_plural: Filtri
-  label_equals: je
-  label_not_equals: nije
-  label_in_less_than: za manje od
-  label_in_more_than: za viÅ¡e od
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: za toÄno
-  label_today: danas
-  label_all_time: sva vremena
-  label_yesterday: juÄer
-  label_this_week: ovog tjedna
-  label_last_week: proÅ¡log tjedna
-  label_last_n_days: "zadnjih %{count} dana"
-  label_this_month: ovog mjeseca
-  label_last_month: proÅ¡log mjeseca
-  label_this_year: ove godine
-  label_date_range: vremenski raspon
-  label_less_than_ago: manje od
-  label_more_than_ago: viÅ¡e od
-  label_ago: prije
-  label_contains: SadrÅ¾i
-  label_not_contains: ne sadrÅ¾i
-  label_day_plural: dana
-  label_repository: SkladiÅ¡te
-  label_repository_plural: SkladiÅ¡ta
-  label_browse: Pregled
-  label_modification: "%{count} promjena"
-  label_modification_plural: "%{count} promjena"
-  label_branch: Branch
-  label_tag: Tag 
-  label_revision: Revizija
-  label_revision_plural: Revizije
-  label_revision_id: "Revision %{value}" 
-  label_associated_revisions: Dodijeljene revizije
-  label_added: dodano
-  label_modified: promijenjen
-  label_copied: kopirano
-  label_renamed: preimenovano
-  label_deleted: obrisano
-  label_latest_revision: Posljednja revizija
-  label_latest_revision_plural: Posljednje revizije
-  label_view_revisions: Pregled revizija
-  label_view_all_revisions: View all revisions
-  label_max_size: Maksimalna veliÄina
-  label_sort_highest: Premjesti na vrh
-  label_sort_higher: Premjesti prema gore
-  label_sort_lower: Premjesti prema dolje
-  label_sort_lowest: Premjesti na dno
-  label_roadmap: Putokaz
-  label_roadmap_due_in: "ZavrÅ¡ava se za %{value}"
-  label_roadmap_overdue: "%{value} kasni"
-  label_roadmap_no_issues: Nema predmeta za ovu verziju
-  label_search: TraÅ¾i
-  label_result_plural: Rezultati
-  label_all_words: Sve rijeÄi
-  label_wiki: Wiki
-  label_wiki_edit: Wiki promjena
-  label_wiki_edit_plural: Wiki promjene
-  label_wiki_page: Wiki stranica
-  label_wiki_page_plural: Wiki stranice
-  label_index_by_title: Indeks po naslovima
-  label_index_by_date: Indeks po datumu
-  label_current_version: Trenutna verzija
-  label_preview: Brzi pregled
-  label_feed_plural: Feeds
-  label_changes_details: Detalji svih promjena
-  label_issue_tracking: PraÄ‡enje predmeta
-  label_spent_time: UtroÅ¡eno vrijeme
-  label_f_hour: "%{value} sata"
-  label_f_hour_plural: "%{value} sati"
-  label_time_tracking: PraÄ‡enje vremena
-  label_change_plural: Promjene
-  label_statistics: Statistika
-  label_commits_per_month: Pohrana po mjesecu
-  label_commits_per_author: Pohrana po autoru
-  label_view_diff: Pregled razlika
-  label_diff_inline: uvuÄeno
-  label_diff_side_by_side: paralelno
-  label_options: Opcije
-  label_copy_workflow_from: Kopiraj tijek rada od
-  label_permissions_report: IzvjeÅ¡Ä‡e o dozvolama
-  label_watched_issues: PraÄ‡eni predmeti
-  label_related_issues: Povezani predmeti
-  label_applied_status: Primijenjen status
-  label_loading: UÄitavam...
-  label_relation_new: Nova relacija
-  label_relation_delete: Brisanje relacije
-  label_relates_to: u relaciji sa
-  label_duplicates: Duplira
-  label_duplicated_by: ponovljen kao
-  label_blocks: blokira
-  label_blocked_by: blokiran od strane
-  label_precedes: prethodi
-  label_follows: slijedi
-  label_end_to_start: od kraja do poÄetka
-  label_end_to_end: od kraja do kraja
-  label_end_to_start: od kraja do poÄetka
-  label_end_to_end: od kraja do kraja
-  label_stay_logged_in: Ostanite prijavljeni
-  label_disabled: IskljuÄen
-  label_show_completed_versions: PrikaÅ¾i zavrÅ¡ene verzije
-  label_me: ja
-  label_board: Forum
-  label_board_new: Novi forum
-  label_board_plural: Forumi
-  label_topic_plural: Teme
-  label_message_plural: Poruke
-  label_message_last: Posljednja poruka
-  label_message_new: Nova poruka
-  label_message_posted: Poruka dodana
-  label_reply_plural: Odgovori
-  label_send_information: PoÅ¡alji korisniku informaciju o profilu 
-  label_year: Godina
-  label_month: Mjesec
-  label_week: Tjedan
-  label_date_from: Od
-  label_date_to: Do
-  label_language_based: Zasnovano na jeziku
-  label_sort_by: "Uredi po %{value}"
-  label_send_test_email: PoÅ¡alji testno E-pismo
-  label_feeds_access_key: RSS access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  label_feeds_access_key_created_on: "RSS kljuc za pristup je napravljen prije %{value}"  
-  label_module_plural: Moduli
-  label_added_time_by: "Promijenio %{author} prije %{age}"
-  label_updated_time_by: "Dodao/la %{author} prije %{age}"
-  label_updated_time: "Promijenjeno prije %{value}"
-  label_jump_to_a_project: Prebaci se na projekt...
-  label_file_plural: Datoteke
-  label_changeset_plural: Promjene
-  label_default_columns: Zadani stupci
-  label_no_change_option: (Bez promjene)
-  label_bulk_edit_selected_issues: ZajedniÄka promjena izabranih predmeta
-  label_theme: Tema
-  label_default: Zadana
-  label_search_titles_only: PretraÅ¾ivanje samo naslova
-  label_user_mail_option_all: "Za bilo koji dogaÄ‘aj na svim mojim projektima"
-  label_user_mail_option_selected: "Za bilo koji dogaÄ‘aj samo za izabrane projekte..."
-  label_user_mail_no_self_notified: "Ne Å¾elim primati obavijesti o promjenama koje sam napravim"
-  label_registration_activation_by_email: aktivacija putem e-poÅ¡te
-  label_registration_manual_activation: ruÄna aktivacija
-  label_registration_automatic_activation: automatska aktivacija
-  label_display_per_page: "Po stranici: %{value}"
-  label_age: Starost
-  label_change_properties: Promijeni svojstva
-  label_general: OpÄ‡enito
-  label_more: JoÅ¡
-  label_scm: SCM
-  label_plugins: Plugins
-  label_ldap_authentication: LDAP autentikacija
-  label_downloads_abbr: D/L
-  label_optional_description: Opcije
-  label_add_another_file: Dodaj joÅ¡ jednu datoteku
-  label_preferences: Preferences
-  label_chronological_order: U kronoloÅ¡kom redoslijedu
-  label_reverse_chronological_order: U obrnutom kronoloÅ¡kom redoslijedu
-  label_planning: Planiranje
-  label_incoming_emails: Dolazne poruke e-poÅ¡te
-  label_generate_key: Generiraj kljuÄ
-  label_issue_watchers: PromatraÄi
-  label_example: Primjer
-  label_display: Display
-  label_sort: Sort
-  label_ascending: Ascending
-  label_descending: Descending
-  label_date_from_to: From %{start} to %{end}
-  label_wiki_content_added: Wiki page added
-  label_wiki_content_updated: Wiki page updated
-  label_group: Group
-  label_group_plural: Grupe
-  label_group_new: Nova grupa
-  label_time_entry_plural: Spent time
-  label_version_sharing_none: Not shared
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_tree: With project tree
-  label_version_sharing_system: With all projects
-  label_update_issue_done_ratios: Update issue done ratios
-  label_copy_source: Source
-  label_copy_target: Target
-  label_copy_same_as_target: Same as target
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_api_access_key: API access key
-  label_missing_api_access_key: Missing an API access key
-  label_api_access_key_created_on: "API access key created %{value} ago"
-  
-  button_login: Prijavi
-  button_submit: PoÅ¡alji
-  button_save: Spremi
-  button_check_all: OznaÄi sve
-  button_uncheck_all: IskljuÄi sve
-  button_delete: ObriÅ¡i
-  button_create: Napravi
-  button_create_and_continue: Napravi i nastavi
-  button_test: Test
-  button_edit: Uredi
-  button_add: Dodaj
-  button_change: Promijeni
-  button_apply: Primijeni
-  button_clear: Ukloni
-  button_lock: ZakljuÄaj
-  button_unlock: OtkljuÄaj
-  button_download: Preuzmi
-  button_list: Spisak
-  button_view: Pregled
-  button_move: Premjesti
-  button_move_and_follow: Move and follow
-  button_back: Nazad
-  button_cancel: Odustani
-  button_activate: Aktiviraj
-  button_sort: Redoslijed
-  button_log_time: ZapiÅ¡i vrijeme
-  button_rollback: IzvrÅ¡i rollback na ovu verziju
-  button_watch: Prati
-  button_unwatch: Prekini pracenje
-  button_reply: Odgovori
-  button_archive: Arhiviraj
-  button_rollback: Dearhiviraj
-  button_reset: PoniÅ¡ti
-  button_rename: Promijeni ime
-  button_change_password: Promjena zaporke
-  button_copy: Kopiraj
-  button_copy_and_follow: Copy and follow
-  button_annotate: Annotate
-  button_update: Promijeni
-  button_configure: Konfiguracija
-  button_quote: Navod
-  button_duplicate: Duplicate
-  button_show: Show  
-  
-  status_active: aktivan
-  status_registered: Registriran
-  status_locked: zakljuÄan
-  
-  version_status_open: open
-  version_status_locked: locked
-  version_status_closed: closed
-
-  field_active: Active
-  
-  text_select_mail_notifications: Izbor akcija za koje Ä‡e biti poslana obavijest e-poÅ¡tom.
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 znaÄi bez ograniÄenja
-  text_project_destroy_confirmation: Da li ste sigurni da Å¾elite izbrisati ovaj projekt i sve njegove podatke?
-  text_subprojects_destroy_warning: "Njegov(i) potprojekt(i): %{value} Ä‡e takoÄ‘er biti obrisan."
-  text_workflow_edit: Select a role and a tracker to edit the workflow
-  text_are_you_sure: Da li ste sigurni?
-  text_journal_changed: "%{label} promijenjen iz %{old} u %{new}"
-  text_journal_set_to: "%{label} postavi na %{value}"
-  text_journal_deleted: "%{label} izbrisano (%{old})"
-  text_journal_added: "%{label} %{value} added"  
-  text_tip_issue_begin_day: Zadaci koji poÄinju ovog dana
-  text_tip_issue_end_day: zadaci koji se zavrÅ¡avaju ovog dana
-  text_tip_issue_begin_end_day: Zadaci koji poÄinju i zavrÅ¡avaju se ovog dana
-  text_project_identifier_info: 'mala slova (a-z), brojevi i crtice su dozvoljeni.<br />Jednom snimljen identifikator se ne moÅ¾e mijenjati!'
-  text_caracters_maximum: "NajviÅ¡e %{count} znakova."
-  text_caracters_minimum: "Mora biti dugaÄko najmanje %{count} znakova."
-  text_length_between: "DuÅ¾ina izmedu %{min} i %{max} znakova."
-  text_tracker_no_workflow: Tijek rada nije definiran za ovaj tracker
-  text_unallowed_characters: Nedozvoljeni znakovi
-  text_comma_separated: ViÅ¡estruke vrijednosti su dozvoljene (razdvojene zarezom).
-  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
-  text_tracker_no_workflow: No workflow defined for this tracker
-  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
-  text_issue_added: "Predmet %{id} je prijavljen (prijavio %{author})."
-  text_issue_updated: "Predmet %{id} je promijenjen %{author})."
-  text_wiki_destroy_confirmation: Da li ste sigurni da Å¾elite izbrisati ovaj wiki i njegov sadrÅ¾aj?
-  text_issue_category_destroy_question: "Neke predmeti (%{count}) su dodijeljeni ovoj kategoriji. Å to Å¾elite uraditi?"
-  text_issue_category_destroy_assignments: Ukloni dodjeljivanje kategorija
-  text_issue_category_reassign_to: Ponovo dodijeli predmete ovoj kategoriji
-  text_user_mail_option: "Za neizabrane projekte, primit Ä‡ete obavjesti samo o stvarima koje pratite ili u kojima sudjelujete (npr. predmete koje ste vi napravili ili koje su vama dodjeljeni)."
-  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded." 
-  text_load_default_configuration: UÄitaj poÄetnu konfiguraciju
-  text_status_changed_by_changeset: "Applied in changeset %{value}."
-  text_issues_destroy_confirmation: 'Jeste li sigurni da Å¾elite obrisati izabrani/e predmet(e)?'
-  text_select_project_modules: 'Odaberite module koji Ä‡e biti omoguÄ‡eni za ovaj projekt:'
-  text_default_administrator_account_changed: Default administrator account changed
-  text_file_repository_writable: Dozvoljeno pisanje u direktorij za privitke
-  text_plugin_assets_writable: Plugin assets directory writable
-  text_rmagick_available: RMagick dostupan (nije obavezno)
-  text_destroy_time_entries_question: "%{hours} sati je prijavljeno za predmete koje Å¾elite obrisati. Å to Ä‡ete uÄiniti?"
-  text_destroy_time_entries: ObriÅ¡i prijavljene sate
-  text_assign_time_entries_to_project: PridruÅ¾i prijavljene sate projektu
-  text_reassign_time_entries: 'Premjesti prijavljene sate ovom predmetu:'
-  text_user_wrote: "%{value} je napisao/la:"
-  text_enumeration_destroy_question: "%{count} objekata je pridruÅ¾eno toj vrijednosti."
-  text_enumeration_category_reassign_to: 'Premjesti ih ovoj vrijednosti:'
-  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
-  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
-  text_diff_truncated: '... Ovaj diff je odrezan zato Å¡to prelazi maksimalnu veliÄinu koja moÅ¾e biti prikazana.'
-  text_custom_field_possible_values_info: 'One line for each value'
-  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
-  text_wiki_page_nullify_children: "Keep child pages as root pages"
-  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
-  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
-  default_role_manager: Upravitelj
-  default_role_developer: Razvojni inÅ¾enjer
-  default_role_reporter: Korisnik
-  default_tracker_bug: PogreÅ¡ka
-  default_tracker_feature: Funkcionalnost
-  default_tracker_support: PodrÅ¡ka
-  default_issue_status_new: Novo
-  default_issue_status_assigned: Dodijeljeno
-  default_issue_status_resolved: RijeÅ¡eno
-  default_issue_status_feedback: Povratna informacija
-  default_issue_status_closed: Zatvoreno
-  default_issue_status_rejected: Odbaceno
-  default_doc_category_user: KorisniÄka dokumentacija
-  default_doc_category_tech: TehniÄka dokumentacija
-  default_priority_low: Nizak
-  default_priority_normal: Redovan
-  default_priority_high: Visok
-  default_priority_urgent: Hitan
-  default_priority_immediate: Odmah
-  default_activity_design: Dizajn
-  default_activity_development: Razvoj
-  enumeration_issue_priorities: Prioriteti predmeta
-  enumeration_doc_categories: Kategorija dokumenata
-  enumeration_activities: Aktivnosti (po vremenu)  
-  enumeration_system_activity: System Activity
-  field_sharing: Sharing
-  text_line_separated: Multiple values allowed (one line for each value).
-  label_close_versions: Close completed versions
-  button_unarchive: Unarchive
-  label_start_to_end: start to end
-  label_start_to_start: start to start
-  field_issue_to: Related issue
-  default_issue_status_in_progress: In Progress
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Commit messages encoding
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2c/2cfeab9b9366f48fd720b77fb1dc5f6f878ef869.svn-base
--- /dev/null
+++ b/.svn/pristine/2c/2cfeab9b9366f48fd720b77fb1dc5f6f878ef869.svn-base
@@ -0,0 +1,284 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/core_ext'
+
+begin
+  require 'RMagick' unless Object.const_defined?(:Magick)
+rescue LoadError
+  # RMagick is not available
+end
+
+require 'redmine/scm/base'
+require 'redmine/access_control'
+require 'redmine/access_keys'
+require 'redmine/activity'
+require 'redmine/activity/fetcher'
+require 'redmine/ciphering'
+require 'redmine/codeset_util'
+require 'redmine/custom_field_format'
+require 'redmine/i18n'
+require 'redmine/menu_manager'
+require 'redmine/notifiable'
+require 'redmine/platform'
+require 'redmine/mime_type'
+require 'redmine/notifiable'
+require 'redmine/search'
+require 'redmine/syntax_highlighting'
+require 'redmine/thumbnail'
+require 'redmine/unified_diff'
+require 'redmine/utils'
+require 'redmine/version'
+require 'redmine/wiki_formatting'
+
+require 'redmine/default_data/loader'
+require 'redmine/helpers/calendar'
+require 'redmine/helpers/diff'
+require 'redmine/helpers/gantt'
+require 'redmine/helpers/time_report'
+require 'redmine/views/other_formats_builder'
+require 'redmine/views/labelled_form_builder'
+require 'redmine/views/builders'
+
+require 'redmine/themes'
+require 'redmine/hook'
+require 'redmine/plugin'
+
+if RUBY_VERSION < '1.9'
+  require 'fastercsv'
+else
+  require 'csv'
+  FCSV = CSV
+end
+
+Redmine::Scm::Base.add "Subversion"
+Redmine::Scm::Base.add "Darcs"
+Redmine::Scm::Base.add "Mercurial"
+Redmine::Scm::Base.add "Cvs"
+Redmine::Scm::Base.add "Bazaar"
+Redmine::Scm::Base.add "Git"
+Redmine::Scm::Base.add "Filesystem"
+
+Redmine::CustomFieldFormat.map do |fields|
+  fields.register 'string'
+  fields.register 'text'
+  fields.register 'int', :label => :label_integer
+  fields.register 'float'
+  fields.register 'list'
+  fields.register 'date'
+  fields.register 'bool', :label => :label_boolean
+  fields.register 'user', :only => %w(Issue TimeEntry Version Project), :edit_as => 'list'
+  fields.register 'version', :only => %w(Issue TimeEntry Version Project), :edit_as => 'list'
+end
+
+# Permissions
+Redmine::AccessControl.map do |map|
+  map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true, :read => true
+  map.permission :search_project, {:search => :index}, :public => true, :read => true
+  map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
+  map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
+  map.permission :close_project, {:projects => [:close, :reopen]}, :require => :member, :read => true
+  map.permission :select_project_modules, {:projects => :modules}, :require => :member
+  map.permission :manage_members, {:projects => :settings, :members => [:index, :show, :create, :update, :destroy, :autocomplete]}, :require => :member
+  map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
+  map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
+
+  map.project_module :issue_tracking do |map|
+    # Issue categories
+    map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
+    # Issues
+    map.permission :view_issues, {:issues => [:index, :show],
+                                  :auto_complete => [:issues],
+                                  :context_menus => [:issues],
+                                  :versions => [:index, :show, :status_by],
+                                  :journals => [:index, :diff],
+                                  :queries => :index,
+                                  :reports => [:issue_report, :issue_report_details]},
+                                  :read => true
+    map.permission :add_issues, {:issues => [:new, :create, :update_form], :attachments => :upload}
+    map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new], :attachments => :upload}
+    map.permission :manage_issue_relations, {:issue_relations => [:index, :show, :create, :destroy]}
+    map.permission :manage_subtasks, {}
+    map.permission :set_issues_private, {}
+    map.permission :set_own_issues_private, {}, :require => :loggedin
+    map.permission :add_issue_notes, {:issues => [:edit, :update, :update_form], :journals => [:new], :attachments => :upload}
+    map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
+    map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
+    map.permission :view_private_notes, {}, :read => true, :require => :member
+    map.permission :set_notes_private, {}, :require => :member
+    map.permission :move_issues, {:issues => [:bulk_edit, :bulk_update]}, :require => :loggedin
+    map.permission :delete_issues, {:issues => :destroy}, :require => :member
+    # Queries
+    map.permission :manage_public_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :member
+    map.permission :save_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
+    # Watchers
+    map.permission :view_issue_watchers, {}, :read => true
+    map.permission :add_issue_watchers, {:watchers => [:new, :create, :append, :autocomplete_for_user]}
+    map.permission :delete_issue_watchers, {:watchers => :destroy}
+  end
+
+  map.project_module :time_tracking do |map|
+    map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
+    map.permission :view_time_entries, {:timelog => [:index, :report, :show]}, :read => true
+    map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
+    map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
+    map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
+  end
+
+  map.project_module :news do |map|
+    map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
+    map.permission :view_news, {:news => [:index, :show]}, :public => true, :read => true
+    map.permission :comment_news, {:comments => :create}
+  end
+
+  map.project_module :documents do |map|
+    map.permission :add_documents, {:documents => [:new, :create, :add_attachment]}, :require => :loggedin
+    map.permission :edit_documents, {:documents => [:edit, :update, :add_attachment]}, :require => :loggedin
+    map.permission :delete_documents, {:documents => [:destroy]}, :require => :loggedin
+    map.permission :view_documents, {:documents => [:index, :show, :download]}, :read => true
+  end
+
+  map.project_module :files do |map|
+    map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
+    map.permission :view_files, {:files => :index, :versions => :download}, :read => true
+  end
+
+  map.project_module :wiki do |map|
+    map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
+    map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
+    map.permission :delete_wiki_pages, {:wiki => [:destroy, :destroy_version]}, :require => :member
+    map.permission :view_wiki_pages, {:wiki => [:index, :show, :special, :date_index]}, :read => true
+    map.permission :export_wiki_pages, {:wiki => [:export]}, :read => true
+    map.permission :view_wiki_edits, {:wiki => [:history, :diff, :annotate]}, :read => true
+    map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
+    map.permission :delete_wiki_pages_attachments, {}
+    map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
+  end
+
+  map.project_module :repository do |map|
+    map.permission :manage_repository, {:repositories => [:new, :create, :edit, :update, :committers, :destroy]}, :require => :member
+    map.permission :browse_repository, {:repositories => [:show, :browse, :entry, :raw, :annotate, :changes, :diff, :stats, :graph]}, :read => true
+    map.permission :view_changesets, {:repositories => [:show, :revisions, :revision]}, :read => true
+    map.permission :commit_access, {}
+    map.permission :manage_related_issues, {:repositories => [:add_related_issue, :remove_related_issue]}
+  end
+
+  map.project_module :boards do |map|
+    map.permission :manage_boards, {:boards => [:new, :create, :edit, :update, :destroy]}, :require => :member
+    map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true, :read => true
+    map.permission :add_messages, {:messages => [:new, :reply, :quote]}
+    map.permission :edit_messages, {:messages => :edit}, :require => :member
+    map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
+    map.permission :delete_messages, {:messages => :destroy}, :require => :member
+    map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
+  end
+
+  map.project_module :calendar do |map|
+    map.permission :view_calendar, {:calendars => [:show, :update]}, :read => true
+  end
+
+  map.project_module :gantt do |map|
+    map.permission :view_gantt, {:gantts => [:show, :update]}, :read => true
+  end
+end
+
+Redmine::MenuManager.map :top_menu do |menu|
+  menu.push :home, :home_path
+  menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
+  menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
+  menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
+  menu.push :help, Redmine::Info.help_url, :last => true
+end
+
+Redmine::MenuManager.map :account_menu do |menu|
+  menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
+  menu.push :register, :register_path, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
+  menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
+  menu.push :logout, :signout_path, :html => {:method => 'post'}, :if => Proc.new { User.current.logged? }
+end
+
+Redmine::MenuManager.map :application_menu do |menu|
+  # Empty
+end
+
+Redmine::MenuManager.map :admin_menu do |menu|
+  menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
+  menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
+  menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
+  menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
+  menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
+  menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
+            :html => {:class => 'issue_statuses'}
+  menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
+  menu.push :custom_fields, {:controller => 'custom_fields'},  :caption => :label_custom_field_plural,
+            :html => {:class => 'custom_fields'}
+  menu.push :enumerations, {:controller => 'enumerations'}
+  menu.push :settings, {:controller => 'settings'}
+  menu.push :ldap_authentication, {:controller => 'auth_sources', :action => 'index'},
+            :html => {:class => 'server_authentication'}
+  menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
+  menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
+end
+
+Redmine::MenuManager.map :project_menu do |menu|
+  menu.push :overview, { :controller => 'projects', :action => 'show' }
+  menu.push :activity, { :controller => 'activities', :action => 'index' }
+  menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
+              :if => Proc.new { |p| p.shared_versions.any? }
+  menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
+  menu.push :new_issue, { :controller => 'issues', :action => 'new', :copy_from => nil }, :param => :project_id, :caption => :label_issue_new,
+              :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
+  menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
+  menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
+  menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
+  menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
+  menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
+              :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
+  menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
+              :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
+  menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
+  menu.push :repository, { :controller => 'repositories', :action => 'show', :repository_id => nil, :path => nil, :rev => nil },
+              :if => Proc.new { |p| p.repository && !p.repository.new_record? }
+  menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
+end
+
+Redmine::Activity.map do |activity|
+  activity.register :issues, :class_name => %w(Issue Journal)
+  activity.register :changesets
+  activity.register :news
+  activity.register :documents, :class_name => %w(Document Attachment)
+  activity.register :files, :class_name => 'Attachment'
+  activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
+  activity.register :messages, :default => false
+  activity.register :time_entries, :default => false
+end
+
+Redmine::Search.map do |search|
+  search.register :issues
+  search.register :news
+  search.register :documents
+  search.register :changesets
+  search.register :wiki_pages
+  search.register :messages
+  search.register :projects
+end
+
+Redmine::WikiFormatting.map do |format|
+  format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
+end
+
+ActionView::Template.register_template_handler :rsb, Redmine::Views::ApiTemplateHandler
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2d/2d1b6f7772fdd853c88983e5f12b084f72e3159d.svn-base
--- /dev/null
+++ b/.svn/pristine/2d/2d1b6f7772fdd853c88983e5f12b084f72e3159d.svn-base
@@ -0,0 +1,13 @@
+class AddCommitAccessPermission < ActiveRecord::Migration
+  def self.up
+    Role.all.select { |r| not r.builtin? }.each do |r|
+      r.add_permission!(:commit_access)
+    end
+  end
+
+  def self.down
+    Role.all.select { |r| not r.builtin? }.each do |r|
+      r.remove_permission!(:commit_access)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2d/2d2fc73f05e5360a853859d4a6d6261e16112400.svn-base
--- a/.svn/pristine/2d/2d2fc73f05e5360a853859d4a6d6261e16112400.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-<div class="contextual">
-<%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %>
-<%= change_status_link(@user) %>
-<%= link_to(l(:button_delete), @user, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') if User.current != @user %>
-</div>
-
-<h2><%= link_to l(:label_user_plural), users_path %> &#187; <%=h @user.login %></h2>
-
-<%= render_tabs user_settings_tabs %>
-
-<% html_title(l(:label_user), @user.login, l(:label_administration)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2d/2d3d652686003e0e75f2451ee9050de946a60dda.svn-base
--- /dev/null
+++ b/.svn/pristine/2d/2d3d652686003e0e75f2451ee9050de946a60dda.svn-base
@@ -0,0 +1,92 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+# Generic exception for when the AuthSource can not be reached
+# (eg. can not connect to the LDAP)
+class AuthSourceException < Exception; end
+class AuthSourceTimeoutException < AuthSourceException; end
+
+class AuthSource < ActiveRecord::Base
+  include Redmine::SubclassFactory
+  include Redmine::Ciphering
+
+  has_many :users
+
+  validates_presence_of :name
+  validates_uniqueness_of :name
+  validates_length_of :name, :maximum => 60
+
+  def authenticate(login, password)
+  end
+
+  def test_connection
+  end
+
+  def auth_method_name
+    "Abstract"
+  end
+
+  def account_password
+    read_ciphered_attribute(:account_password)
+  end
+
+  def account_password=(arg)
+    write_ciphered_attribute(:account_password, arg)
+  end
+
+  def searchable?
+    false
+  end
+
+  def self.search(q)
+    results = []
+    AuthSource.all.each do |source|
+      begin
+        if source.searchable?
+          results += source.search(q)
+        end
+      rescue AuthSourceException => e
+        logger.error "Error while searching users in #{source.name}: #{e.message}"
+      end
+    end
+    results
+  end
+
+  def allow_password_changes?
+    self.class.allow_password_changes?
+  end
+
+  # Does this auth source backend allow password changes?
+  def self.allow_password_changes?
+    false
+  end
+
+  # Try to authenticate a user not yet registered against available sources
+  def self.authenticate(login, password)
+    AuthSource.where(:onthefly_register => true).all.each do |source|
+      begin
+        logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
+        attrs = source.authenticate(login, password)
+      rescue => e
+        logger.error "Error during authentication: #{e.message}"
+        attrs = nil
+      end
+      return attrs if attrs
+    end
+    return nil
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2d/2d611b348b4b0790a149102dbbb27f7bf647e472.svn-base
--- /dev/null
+++ b/.svn/pristine/2d/2d611b348b4b0790a149102dbbb27f7bf647e472.svn-base
@@ -0,0 +1,176 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::PluginTest < ActiveSupport::TestCase
+
+  def setup
+    @klass = Redmine::Plugin
+    # In case some real plugins are installed
+    @klass.clear
+  end
+
+  def teardown
+    @klass.clear
+  end
+
+  def test_register
+    @klass.register :foo do
+      name 'Foo plugin'
+      url 'http://example.net/plugins/foo'
+      author 'John Smith'
+      author_url 'http://example.net/jsmith'
+      description 'This is a test plugin'
+      version '0.0.1'
+      settings :default => {'sample_setting' => 'value', 'foo'=>'bar'}, :partial => 'foo/settings'
+    end
+
+    assert_equal 1, @klass.all.size
+
+    plugin = @klass.find('foo')
+    assert plugin.is_a?(Redmine::Plugin)
+    assert_equal :foo, plugin.id
+    assert_equal 'Foo plugin', plugin.name
+    assert_equal 'http://example.net/plugins/foo', plugin.url
+    assert_equal 'John Smith', plugin.author
+    assert_equal 'http://example.net/jsmith', plugin.author_url
+    assert_equal 'This is a test plugin', plugin.description
+    assert_equal '0.0.1', plugin.version
+  end
+
+  def test_installed
+    @klass.register(:foo) {}
+
+    assert_equal true, @klass.installed?(:foo)
+    assert_equal false, @klass.installed?(:bar)
+  end
+
+  def test_menu
+    assert_difference 'Redmine::MenuManager.items(:project_menu).size' do
+      @klass.register :foo do
+        menu :project_menu, :foo_menu_item, '/foo', :caption => 'Foo'
+      end
+    end
+    menu_item = Redmine::MenuManager.items(:project_menu).detect {|i| i.name == :foo_menu_item}
+    assert_not_nil menu_item
+    assert_equal 'Foo', menu_item.caption
+    assert_equal '/foo', menu_item.url
+  end
+
+  def test_delete_menu_item
+    Redmine::MenuManager.map(:project_menu).push(:foo_menu_item, '/foo', :caption => 'Foo')
+
+    assert_difference 'Redmine::MenuManager.items(:project_menu).size', -1 do
+      @klass.register :foo do
+        delete_menu_item :project_menu, :foo_menu_item
+      end
+    end
+    assert_nil Redmine::MenuManager.items(:project_menu).detect {|i| i.name == :foo_menu_item}
+  end
+
+  def test_requires_redmine
+    plugin = Redmine::Plugin.register(:foo) {}
+    Redmine::VERSION.stubs(:to_a).returns([2, 1, 3, "stable", 10817])
+
+    # Specific version without hash
+    assert plugin.requires_redmine('2.1.3')
+    assert plugin.requires_redmine('2.1')
+    assert_raise Redmine::PluginRequirementError do
+      plugin.requires_redmine('2.1.4')
+    end
+    assert_raise Redmine::PluginRequirementError do
+      plugin.requires_redmine('2.2')
+    end
+
+    # Specific version
+    assert plugin.requires_redmine(:version => '2.1.3')
+    assert plugin.requires_redmine(:version => ['2.1.3', '2.2.0'])
+    assert plugin.requires_redmine(:version => '2.1')
+    assert_raise Redmine::PluginRequirementError do
+      plugin.requires_redmine(:version => '2.2.0')
+    end
+    assert_raise Redmine::PluginRequirementError do
+      plugin.requires_redmine(:version => ['2.1.4', '2.2.0'])
+    end
+    assert_raise Redmine::PluginRequirementError do
+      plugin.requires_redmine(:version => '2.2')
+    end
+
+    # Version range
+    assert plugin.requires_redmine(:version => '2.0.0'..'2.2.4')
+    assert plugin.requires_redmine(:version => '2.1.3'..'2.2.4')
+    assert plugin.requires_redmine(:version => '2.0.0'..'2.1.3')
+    assert plugin.requires_redmine(:version => '2.0'..'2.2')
+    assert plugin.requires_redmine(:version => '2.1'..'2.2')
+    assert plugin.requires_redmine(:version => '2.0'..'2.1')
+    assert_raise Redmine::PluginRequirementError do
+      plugin.requires_redmine(:version => '2.1.4'..'2.2.4')
+    end
+
+
+    # Version or higher
+    assert plugin.requires_redmine(:version_or_higher => '0.1.0')
+    assert plugin.requires_redmine(:version_or_higher => '2.1.3')
+    assert plugin.requires_redmine(:version_or_higher => '2.1')
+    assert_raise Redmine::PluginRequirementError do
+      plugin.requires_redmine(:version_or_higher => '2.2.0')
+    end
+    assert_raise Redmine::PluginRequirementError do
+      plugin.requires_redmine(:version_or_higher => '2.2')
+    end
+  end
+
+  def test_requires_redmine_plugin
+    test = self
+    other_version = '0.5.0'
+
+    @klass.register :other do
+      name 'Other'
+      version other_version
+    end
+
+    @klass.register :foo do
+      test.assert requires_redmine_plugin(:other, :version_or_higher => '0.1.0')
+      test.assert requires_redmine_plugin(:other, :version_or_higher => other_version)
+      test.assert requires_redmine_plugin(:other, other_version)
+      test.assert_raise Redmine::PluginRequirementError do
+        requires_redmine_plugin(:other, :version_or_higher => '99.0.0')
+      end
+
+      test.assert requires_redmine_plugin(:other, :version => other_version)
+      test.assert requires_redmine_plugin(:other, :version => [other_version, '99.0.0'])
+      test.assert_raise Redmine::PluginRequirementError do
+        requires_redmine_plugin(:other, :version => '99.0.0')
+      end
+      test.assert_raise Redmine::PluginRequirementError do
+        requires_redmine_plugin(:other, :version => ['98.0.0', '99.0.0'])
+      end
+      # Missing plugin
+      test.assert_raise Redmine::PluginNotFound do
+        requires_redmine_plugin(:missing, :version_or_higher => '0.1.0')
+      end
+      test.assert_raise Redmine::PluginNotFound do
+        requires_redmine_plugin(:missing, '0.1.0')
+      end
+      test.assert_raise Redmine::PluginNotFound do
+        requires_redmine_plugin(:missing, :version => '0.1.0')
+      end
+
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2d/2d85d0783f59c365e1251c736bcbc44da38bc043.svn-base
--- /dev/null
+++ b/.svn/pristine/2d/2d85d0783f59c365e1251c736bcbc44da38bc043.svn-base
@@ -0,0 +1,163 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WikiPageTest < ActiveSupport::TestCase
+  fixtures :projects, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
+
+  def setup
+    @wiki = Wiki.find(1)
+    @page = @wiki.pages.first
+  end
+
+  def test_create
+    page = WikiPage.new(:wiki => @wiki)
+    assert !page.save
+    assert_equal 1, page.errors.count
+
+    page.title = "Page"
+    assert page.save
+    page.reload
+    assert !page.protected?
+
+    @wiki.reload
+    assert @wiki.pages.include?(page)
+  end
+
+  def test_sidebar_should_be_protected_by_default
+    page = @wiki.find_or_new_page('sidebar')
+    assert page.new_record?
+    assert page.protected?
+  end
+
+  def test_find_or_new_page
+    page = @wiki.find_or_new_page("CookBook documentation")
+    assert_kind_of WikiPage, page
+    assert !page.new_record?
+
+    page = @wiki.find_or_new_page("Non existing page")
+    assert_kind_of WikiPage, page
+    assert page.new_record?
+  end
+
+  def test_parent_title
+    page = WikiPage.find_by_title('Another_page')
+    assert_nil page.parent_title
+
+    page = WikiPage.find_by_title('Page_with_an_inline_image')
+    assert_equal 'CookBook documentation', page.parent_title
+  end
+
+  def test_assign_parent
+    page = WikiPage.find_by_title('Another_page')
+    page.parent_title = 'CookBook documentation'
+    assert page.save
+    page.reload
+    assert_equal WikiPage.find_by_title('CookBook_documentation'), page.parent
+  end
+
+  def test_unassign_parent
+    page = WikiPage.find_by_title('Page_with_an_inline_image')
+    page.parent_title = ''
+    assert page.save
+    page.reload
+    assert_nil page.parent
+  end
+
+  def test_parent_validation
+    page = WikiPage.find_by_title('CookBook_documentation')
+
+    # A page that doesn't exist
+    page.parent_title = 'Unknown title'
+    assert !page.save
+    assert_include I18n.translate('activerecord.errors.messages.invalid'),
+                   page.errors[:parent_title]
+    # A child page
+    page.parent_title = 'Page_with_an_inline_image'
+    assert !page.save
+    assert_include I18n.translate('activerecord.errors.messages.circular_dependency'),
+                   page.errors[:parent_title]
+    # The page itself
+    page.parent_title = 'CookBook_documentation'
+    assert !page.save
+    assert_include I18n.translate('activerecord.errors.messages.circular_dependency'),
+                   page.errors[:parent_title]
+    page.parent_title = 'Another_page'
+    assert page.save
+  end
+
+  def test_destroy
+    page = WikiPage.find(1)
+    page.destroy
+    assert_nil WikiPage.find_by_id(1)
+    # make sure that page content and its history are deleted
+    assert WikiContent.find_all_by_page_id(1).empty?
+    assert WikiContent.versioned_class.find_all_by_page_id(1).empty?
+  end
+
+  def test_destroy_should_not_nullify_children
+    page = WikiPage.find(2)
+    child_ids = page.child_ids
+    assert child_ids.any?
+    page.destroy
+    assert_nil WikiPage.find_by_id(2)
+
+    children = WikiPage.find_all_by_id(child_ids)
+    assert_equal child_ids.size, children.size
+    children.each do |child|
+      assert_nil child.parent_id
+    end
+  end
+
+  def test_updated_on_eager_load
+    page = WikiPage.with_updated_on.first(:order => 'id')
+    assert page.is_a?(WikiPage)
+    assert_not_nil page.read_attribute(:updated_on)
+    assert_equal Time.gm(2007, 3, 6, 23, 10, 51), page.content.updated_on
+    assert_equal page.content.updated_on, page.updated_on
+    assert_not_nil page.read_attribute(:version)
+  end
+
+  def test_descendants
+    page = WikiPage.create!(:wiki => @wiki, :title => 'Parent')
+    child1 = WikiPage.create!(:wiki => @wiki, :title => 'Child1', :parent => page)
+    child11 = WikiPage.create!(:wiki => @wiki, :title => 'Child11', :parent => child1)
+    child111 = WikiPage.create!(:wiki => @wiki, :title => 'Child111', :parent => child11)
+    child2 = WikiPage.create!(:wiki => @wiki, :title => 'Child2', :parent => page)
+
+    assert_equal %w(Child1 Child11 Child111 Child2), page.descendants.map(&:title).sort
+    assert_equal %w(Child1 Child11 Child111 Child2), page.descendants(nil).map(&:title).sort
+    assert_equal %w(Child1 Child11 Child2), page.descendants(2).map(&:title).sort
+    assert_equal %w(Child1 Child2), page.descendants(1).map(&:title).sort
+
+    assert_equal %w(Child1 Child11 Child111 Child2 Parent), page.self_and_descendants.map(&:title).sort
+    assert_equal %w(Child1 Child11 Child111 Child2 Parent), page.self_and_descendants(nil).map(&:title).sort
+    assert_equal %w(Child1 Child11 Child2 Parent), page.self_and_descendants(2).map(&:title).sort
+    assert_equal %w(Child1 Child2 Parent), page.self_and_descendants(1).map(&:title).sort
+  end
+
+  def test_diff_for_page_with_deleted_version_should_pick_the_previous_available_version
+    WikiContent::Version.find_by_page_id_and_version(1, 2).destroy
+
+    page = WikiPage.find(1)
+    diff = page.diff(3)
+    assert_not_nil diff
+    assert_equal 3, diff.content_to.version
+    assert_equal 1, diff.content_from.version
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2d/2dbd0564d495b47bea2303b32f1609a8bf5c4b1a.svn-base
--- /dev/null
+++ b/.svn/pristine/2d/2dbd0564d495b47bea2303b32f1609a8bf5c4b1a.svn-base
@@ -0,0 +1,41 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingJournalsTest < ActionController::IntegrationTest
+  def test_journals
+    assert_routing(
+        { :method => 'post', :path => "/issues/1/quoted" },
+        { :controller => 'journals', :action => 'new', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/changes" },
+        { :controller => 'journals', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/journals/diff/1" },
+        { :controller => 'journals', :action => 'diff', :id => '1' }
+      )
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/journals/edit/1" },
+          { :controller => 'journals', :action => 'edit', :id => '1' }
+        )
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2d/2dbde491b7a799c190d49fd409652b2fbab77ca3.svn-base
--- /dev/null
+++ b/.svn/pristine/2d/2dbde491b7a799c190d49fd409652b2fbab77ca3.svn-base
@@ -0,0 +1,66 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class News < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  belongs_to :project
+  belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+  has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
+
+  validates_presence_of :title, :description
+  validates_length_of :title, :maximum => 60
+  validates_length_of :summary, :maximum => 255
+
+  acts_as_attachable :delete_permission => :manage_news
+  acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"], :include => :project
+  acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}}
+  acts_as_activity_provider :find_options => {:include => [:project, :author]},
+                            :author_key => :author_id
+  acts_as_watchable
+
+  after_create :add_author_as_watcher
+
+  scope :visible, lambda {|*args|
+    includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args))
+  }
+
+  safe_attributes 'title', 'summary', 'description'
+
+  def visible?(user=User.current)
+    !user.nil? && user.allowed_to?(:view_news, project)
+  end
+
+  # Returns true if the news can be commented by user
+  def commentable?(user=User.current)
+    user.allowed_to?(:comment_news, project)
+  end
+
+  def recipients
+    project.users.select {|user| user.notify_about?(self)}.map(&:mail)
+  end
+
+  # returns latest news for projects visible by user
+  def self.latest(user = User.current, count = 5)
+    visible(user).includes([:author, :project]).order("#{News.table_name}.created_on DESC").limit(count).all
+  end
+
+  private
+
+  def add_author_as_watcher
+    Watcher.create(:watchable => self, :user => author)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2d/2ddfd454c5c1fbd92838296a3b268aeb1e87e384.svn-base
--- /dev/null
+++ b/.svn/pristine/2d/2ddfd454c5c1fbd92838296a3b268aeb1e87e384.svn-base
@@ -0,0 +1,212 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::GroupsTest < Redmine::ApiTest::Base
+  fixtures :users, :groups_users
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "GET /groups" do
+    context ".xml" do
+      should "require authentication" do
+        get '/groups.xml'
+        assert_response 401
+      end
+
+      should "return groups" do
+        get '/groups.xml', {}, credentials('admin')
+        assert_response :success
+        assert_equal 'application/xml', response.content_type
+
+        assert_select 'groups' do
+          assert_select 'group' do
+            assert_select 'name', :text => 'A Team'
+            assert_select 'id', :text => '10'
+          end
+        end
+      end
+    end
+
+    context ".json" do
+      should "require authentication" do
+        get '/groups.json'
+        assert_response 401
+      end
+
+      should "return groups" do
+        get '/groups.json', {}, credentials('admin')
+        assert_response :success
+        assert_equal 'application/json', response.content_type
+
+        json = MultiJson.load(response.body)
+        groups = json['groups']
+        assert_kind_of Array, groups
+        group = groups.detect {|g| g['name'] == 'A Team'}
+        assert_not_nil group
+        assert_equal({'id' => 10, 'name' => 'A Team'}, group)
+      end
+    end
+  end
+
+  context "GET /groups/:id" do
+    context ".xml" do
+      should "return the group with its users" do
+        get '/groups/10.xml', {}, credentials('admin')
+        assert_response :success
+        assert_equal 'application/xml', response.content_type
+
+        assert_select 'group' do
+          assert_select 'name', :text => 'A Team'
+          assert_select 'id', :text => '10'
+        end
+      end
+
+      should "include users if requested" do
+        get '/groups/10.xml?include=users', {}, credentials('admin')
+        assert_response :success
+        assert_equal 'application/xml', response.content_type
+
+        assert_select 'group' do
+          assert_select 'users' do
+            assert_select 'user', Group.find(10).users.count
+            assert_select 'user[id=8]'
+          end
+        end
+      end
+
+      should "include memberships if requested" do
+        get '/groups/10.xml?include=memberships', {}, credentials('admin')
+        assert_response :success
+        assert_equal 'application/xml', response.content_type
+
+        assert_select 'group' do
+          assert_select 'memberships'
+        end
+      end
+    end
+  end
+
+  context "POST /groups" do
+    context "with valid parameters" do
+      context ".xml" do
+        should "create groups" do
+          assert_difference('Group.count') do
+            post '/groups.xml', {:group => {:name => 'Test', :user_ids => [2, 3]}}, credentials('admin')
+            assert_response :created
+            assert_equal 'application/xml', response.content_type
+          end
+  
+          group = Group.order('id DESC').first
+          assert_equal 'Test', group.name
+          assert_equal [2, 3], group.users.map(&:id).sort
+
+          assert_select 'group' do
+            assert_select 'name', :text => 'Test'
+          end
+        end
+      end
+    end
+
+    context "with invalid parameters" do
+      context ".xml" do
+        should "return errors" do
+          assert_no_difference('Group.count') do
+            post '/groups.xml', {:group => {:name => ''}}, credentials('admin')
+          end
+          assert_response :unprocessable_entity
+          assert_equal 'application/xml', response.content_type
+
+          assert_select 'errors' do
+            assert_select 'error', :text => /Name can't be blank/
+          end
+        end
+      end
+    end
+  end
+
+  context "PUT /groups/:id" do
+    context "with valid parameters" do
+      context ".xml" do
+        should "update the group" do
+          put '/groups/10.xml', {:group => {:name => 'New name', :user_ids => [2, 3]}}, credentials('admin')
+          assert_response :ok
+          assert_equal '', @response.body
+  
+          group = Group.find(10)
+          assert_equal 'New name', group.name
+          assert_equal [2, 3], group.users.map(&:id).sort
+        end
+      end
+    end
+
+    context "with invalid parameters" do
+      context ".xml" do
+        should "return errors" do
+          put '/groups/10.xml', {:group => {:name => ''}}, credentials('admin')
+          assert_response :unprocessable_entity
+          assert_equal 'application/xml', response.content_type
+
+          assert_select 'errors' do
+            assert_select 'error', :text => /Name can't be blank/
+          end
+        end
+      end
+    end
+  end
+
+  context "DELETE /groups/:id" do
+    context ".xml" do
+      should "delete the group" do
+        assert_difference 'Group.count', -1 do
+          delete '/groups/10.xml', {}, credentials('admin')
+          assert_response :ok
+          assert_equal '', @response.body
+        end
+      end
+    end
+  end
+
+  context "POST /groups/:id/users" do
+    context ".xml" do
+      should "add user to the group" do
+        assert_difference 'Group.find(10).users.count' do
+          post '/groups/10/users.xml', {:user_id => 5}, credentials('admin')
+          assert_response :ok
+          assert_equal '', @response.body
+        end
+        assert_include User.find(5), Group.find(10).users
+      end
+    end
+  end
+
+  context "DELETE /groups/:id/users/:user_id" do
+    context ".xml" do
+      should "remove user from the group" do
+        assert_difference 'Group.find(10).users.count', -1 do
+          delete '/groups/10/users/8.xml', {}, credentials('admin')
+          assert_response :ok
+          assert_equal '', @response.body
+        end
+        assert_not_include User.find(8), Group.find(10).users
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2d/2de3a87e3fe026c2ba56948a00c54c7c54909e85.svn-base
--- a/.svn/pristine/2d/2de3a87e3fe026c2ba56948a00c54c7c54909e85.svn-base
+++ /dev/null
@@ -1,417 +0,0 @@
-/* redMine - project management software
-   Copyright (C) 2006-2008  Jean-Philippe Lang */
-
-function checkAll (id, checked) {
-	var els = Element.descendants(id);
-	for (var i = 0; i < els.length; i++) {
-    if (els[i].disabled==false) {
-      els[i].checked = checked;
-    }
-	}
-}
-
-function toggleCheckboxesBySelector(selector) {
-	boxes = $$(selector);
-	var all_checked = true;
-	for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
-	for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
-}
-
-function setCheckboxesBySelector(checked, selector) {
-  var boxes = $$(selector);
-  boxes.each(function(ele) {
-    ele.checked = checked;
-  });
-}
-
-function showAndScrollTo(id, focus) {
-	Element.show(id);
-	if (focus!=null) { Form.Element.focus(focus); }
-	Element.scrollTo(id);
-}
-
-function toggleRowGroup(el) {
-	var tr = Element.up(el, 'tr');
-	var n = Element.next(tr);
-	tr.toggleClassName('open');
-	while (n != undefined && !n.hasClassName('group')) {
-		Element.toggle(n);
-		n = Element.next(n);
-	}
-}
-
-function collapseAllRowGroups(el) {
-  var tbody = Element.up(el, 'tbody');
-  tbody.childElements('tr').each(function(tr) {
-    if (tr.hasClassName('group')) {
-      tr.removeClassName('open');
-    } else {
-      tr.hide();
-    }
-  })
-}
-
-function expandAllRowGroups(el) {
-  var tbody = Element.up(el, 'tbody');
-  tbody.childElements('tr').each(function(tr) {
-    if (tr.hasClassName('group')) {
-      tr.addClassName('open');
-    } else {
-      tr.show();
-    }
-  })
-}
-
-function toggleAllRowGroups(el) {
-	var tr = Element.up(el, 'tr');
-  if (tr.hasClassName('open')) {
-    collapseAllRowGroups(el);
-  } else {
-    expandAllRowGroups(el);
-  }
-}
-
-function toggleFieldset(el) {
-	var fieldset = Element.up(el, 'fieldset');
-	fieldset.toggleClassName('collapsed');
-	Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
-}
-
-function hideFieldset(el) {
-	var fieldset = Element.up(el, 'fieldset');
-	fieldset.toggleClassName('collapsed');
-	fieldset.down('div').hide();
-}
-
-var fileFieldCount = 1;
-
-function addFileField() {
-  var fields = $('attachments_fields');
-  if (fields.childElements().length >= 10) return false;
-  fileFieldCount++;
-  var s = new Element('span');
-  s.update(fields.down('span').innerHTML);
-  s.down('input.file').name = "attachments[" + fileFieldCount + "][file]";
-  s.down('input.description').name = "attachments[" + fileFieldCount + "][description]";
-  fields.appendChild(s);
-}
-
-function removeFileField(el) {
-  var fields = $('attachments_fields');
-	var s = Element.up(el, 'span');
-	if (fields.childElements().length > 1) {
-		s.remove();
-	} else {
-		s.update(s.innerHTML);
-	}
-}
-
-function checkFileSize(el, maxSize, message) {
-  var files = el.files;
-  if (files) {
-    for (var i=0; i<files.length; i++) {
-      if (files[i].size > maxSize) {
-        alert(message);
-        el.value = "";
-      }
-    }
-  }
-}
-
-function showTab(name) {
-    var f = $$('div#content .tab-content');
-	for(var i=0; i<f.length; i++){
-		Element.hide(f[i]);
-	}
-    var f = $$('div.tabs a');
-	for(var i=0; i<f.length; i++){
-		Element.removeClassName(f[i], "selected");
-	}
-	Element.show('tab-content-' + name);
-	Element.addClassName('tab-' + name, "selected");
-	return false;
-}
-
-function moveTabRight(el) {
-	var lis = Element.up(el, 'div.tabs').down('ul').childElements();
-	var tabsWidth = 0;
-	var i;
-	for (i=0; i<lis.length; i++) {
-		if (lis[i].visible()) {
-			tabsWidth += lis[i].getWidth() + 6;
-		}
-	}
-	if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
-		return;
-	}
-	i=0;
-	while (i<lis.length && !lis[i].visible()) {
-		i++;
-	}
-	lis[i].hide();
-}
-
-function moveTabLeft(el) {
-	var lis = Element.up(el, 'div.tabs').down('ul').childElements();
-	var i = 0;
-	while (i<lis.length && !lis[i].visible()) {
-		i++;
-	}
-	if (i>0) {
-		lis[i-1].show();
-	}
-}
-
-function displayTabsButtons() {
-	var lis;
-	var tabsWidth = 0;
-	var i;
-	$$('div.tabs').each(function(el) {
-		lis = el.down('ul').childElements();
-		for (i=0; i<lis.length; i++) {
-			if (lis[i].visible()) {
-				tabsWidth += lis[i].getWidth() + 6;
-			}
-		}
-		if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
-			el.down('div.tabs-buttons').hide();
-		} else {
-			el.down('div.tabs-buttons').show();
-		}
-	});
-}
-
-function setPredecessorFieldsVisibility() {
-    relationType = $('relation_relation_type');
-    if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
-        Element.show('predecessor_fields');
-    } else {
-        Element.hide('predecessor_fields');
-    }
-}
-
-function promptToRemote(text, param, url) {
-    value = prompt(text + ':');
-    if (value) {
-        new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
-        return false;
-    }
-}
-
-function showModal(id, width) {
-  el = $(id);
-	if (el == undefined || el.visible()) {return;}
-  var h = $$('body')[0].getHeight();
-  var d = document.createElement("div");
-  d.id = 'modalbg';
-  $('main').appendChild(d);
-  $('modalbg').setStyle({ width: '100%', height: h + 'px' });
-  $('modalbg').show();
-
-  var pageWidth = document.viewport.getWidth();
-	el.setStyle({'width': width});
-	el.setStyle({'left': (((pageWidth - el.getWidth())/2  *100) / pageWidth) + '%'});
-  el.addClassName('modal');
-	el.show();
-
-  var submit = el.down("input[type=submit]");
-	if (submit) {
-  	submit.focus();
-  }
-}
-
-function hideModal(el) {
-  var modal = Element.up(el, 'div.modal');
-	if (modal) {
-		modal.hide();
-	}
-	var bg = $('modalbg');
-	if (bg) {
-  	bg.remove();
-  }
-}
-
-function collapseScmEntry(id) {
-    var els = document.getElementsByClassName(id, 'browser');
-	for (var i = 0; i < els.length; i++) {
-	   if (els[i].hasClassName('open')) {
-	       collapseScmEntry(els[i].id);
-	   }
-       Element.hide(els[i]);
-    }
-    $(id).removeClassName('open');
-}
-
-function expandScmEntry(id) {
-    var els = document.getElementsByClassName(id, 'browser');
-	for (var i = 0; i < els.length; i++) {
-       Element.show(els[i]);
-       if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
-            expandScmEntry(els[i].id);
-       }
-    }
-    $(id).addClassName('open');
-}
-
-function scmEntryClick(id) {
-    el = $(id);
-    if (el.hasClassName('open')) {
-        collapseScmEntry(id);
-        el.addClassName('collapsed');
-        return false;
-    } else if (el.hasClassName('loaded')) {
-        expandScmEntry(id);
-        el.removeClassName('collapsed');
-        return false;
-    }
-    if (el.hasClassName('loading')) {
-        return false;
-    }
-    el.addClassName('loading');
-    return true;
-}
-
-function scmEntryLoaded(id) {
-    Element.addClassName(id, 'open');
-    Element.addClassName(id, 'loaded');
-    Element.removeClassName(id, 'loading');
-}
-
-function randomKey(size) {
-	var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
-	var key = '';
-	for (i = 0; i < size; i++) {
-  	key += chars[Math.floor(Math.random() * chars.length)];
-	}
-	return key;
-}
-
-function observeParentIssueField(url) {
-  new Ajax.Autocompleter('issue_parent_issue_id',
-                         'parent_issue_candidates',
-                         url,
-                         { minChars: 3,
-                           frequency: 0.5,
-                           paramName: 'q',
-                           method: 'get',
-                           updateElement: function(value) {
-                             document.getElementById('issue_parent_issue_id').value = value.id;
-                           }});
-}
-
-function observeRelatedIssueField(url) {
-  new Ajax.Autocompleter('relation_issue_to_id',
-                         'related_issue_candidates',
-                         url,
-                         { minChars: 3,
-                           frequency: 0.5,
-                           paramName: 'q',
-                           method: 'get',
-                           updateElement: function(value) {
-                             document.getElementById('relation_issue_to_id').value = value.id;
-                           },
-                           parameters: 'scope=all'
-                           });
-}
-
-function setVisible(id, visible) {
-  var el = $(id);
-  if (el) {if (visible) {el.show();} else {el.hide();}}
-}
-
-function observeProjectModules() {
-  var f = function() {
-    /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
-    var c = ($('project_enabled_module_names_issue_tracking').checked == true);
-    setVisible('project_trackers', c);
-    setVisible('project_issue_custom_fields', c);
-  };
-  
-  Event.observe(window, 'load', f);
-  Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
-}
-
-/*
- * Class used to warn user when leaving a page with unsaved textarea
- * Author: mathias.fischer@berlinonline.de
-*/
-
-var WarnLeavingUnsaved = Class.create({
-	observedForms: false,
-	observedElements: false,
-	changedForms: false,
-	message: null,
-	
-	initialize: function(message){
-		this.observedForms = $$('form');
-		this.observedElements =  $$('textarea');
-		this.message = message;
-		
-		this.observedElements.each(this.observeChange.bind(this));
-		this.observedForms.each(this.submitAction.bind(this));
-		
-		window.onbeforeunload = this.unload.bind(this);
-	},
-	
-	unload: function(){
-		this.observedElements.each(function(el) {el.blur();})
-		if(this.changedForms)
-      return this.message;
-	},
-	
-	setChanged: function(){
-    this.changedForms = true;
-	},
-	
-	setUnchanged: function(){
-    this.changedForms = false;
-	},
-	
-	observeChange: function(element){
-    element.observe('change',this.setChanged.bindAsEventListener(this));
-	},
-	
-	submitAction: function(element){
-    element.observe('submit',this.setUnchanged.bindAsEventListener(this));
-	}
-});
-
-/* 
- * 1 - registers a callback which copies the csrf token into the
- * X-CSRF-Token header with each ajax request.  Necessary to 
- * work with rails applications which have fixed
- * CVE-2011-0447
- * 2 - shows and hides ajax indicator
- */
-Ajax.Responders.register({
-    onCreate: function(request){
-        var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
-
-        if (csrf_meta_tag) {
-            var header = 'X-CSRF-Token',
-                token = csrf_meta_tag.readAttribute('content');
-
-            if (!request.options.requestHeaders) {
-              request.options.requestHeaders = {};
-            }
-            request.options.requestHeaders[header] = token;
-          }
-
-        if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
-            Element.show('ajax-indicator');
-        }
-    },
-    onComplete: function(){
-        if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
-            Element.hide('ajax-indicator');
-        }
-    }
-});
-
-function hideOnLoad() {
-  $$('.hol').each(function(el) {
-  	el.hide();
-	});
-}
-
-Event.observe(window, 'load', hideOnLoad);
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2e/2e1157d3f81f3880c0395bb75f0b975ce97e7bd4.svn-base
--- /dev/null
+++ b/.svn/pristine/2e/2e1157d3f81f3880c0395bb75f0b975ce97e7bd4.svn-base
@@ -0,0 +1,8 @@
+<%= error_messages_for @group %>
+
+<div class="box tabular">
+  <p><%= f.text_field :name, :required => true, :size => 60 %></p>
+  <% @group.custom_field_values.each do |value| %>
+    <p><%= custom_field_tag_with_label :group, value %></p>
+  <% end %>
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2e/2e26af3877bdd2fe792449a4fd743a6ba7463f7e.svn-base
--- /dev/null
+++ b/.svn/pristine/2e/2e26af3877bdd2fe792449a4fd743a6ba7463f7e.svn-base
@@ -0,0 +1,53 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class PreviewsController < ApplicationController
+  before_filter :find_project, :find_attachments
+
+  def issue
+    @issue = @project.issues.find_by_id(params[:id]) unless params[:id].blank?
+    if @issue
+      @description = params[:issue] && params[:issue][:description]
+      if @description && @description.gsub(/(\r?\n|\n\r?)/, "\n") == @issue.description.to_s.gsub(/(\r?\n|\n\r?)/, "\n")
+        @description = nil
+      end
+      # params[:notes] is useful for preview of notes in issue history
+      @notes = params[:notes] || (params[:issue] ? params[:issue][:notes] : nil)
+    else
+      @description = (params[:issue] ? params[:issue][:description] : nil)
+    end
+    render :layout => false
+  end
+
+  def news
+    if params[:id].present? && news = News.visible.find_by_id(params[:id])
+      @previewed = news
+    end
+    @text = (params[:news] ? params[:news][:description] : nil)
+    render :partial => 'common/preview'
+  end
+
+  private
+
+  def find_project
+    project_id = (params[:issue] && params[:issue][:project_id]) || params[:project_id]
+    @project = Project.find(project_id)
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2e/2e2d614b9e64145af9606e9c3e56e58eb315056d.svn-base
--- /dev/null
+++ b/.svn/pristine/2e/2e2d614b9e64145af9606e9c3e56e58eb315056d.svn-base
@@ -0,0 +1,34 @@
+<div id="query_form_content" class="hide-when-print">
+  <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
+    <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
+    <div style="<%= @query.new_record? ? "" : "display: none;" %>">
+      <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
+    </div>
+  </fieldset>
+  <fieldset class="collapsible collapsed">
+    <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
+    <div style="display: none;">
+      <table>
+        <tr>
+          <td><%= l(:field_column_names) %></td>
+          <td><%= render_query_columns_selection(@query) %></td>
+        </tr>
+      </table>
+    </div>
+  </fieldset>
+</div>
+
+<p class="buttons hide-when-print">
+  <%= link_to_function l(:button_apply), 'submit_query_form("query_form")', :class => 'icon icon-checked' %>
+  <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue}, :class => 'icon icon-reload'  %>
+</p>
+
+<div class="tabs">
+<% query_params = params.slice(:f, :op, :v, :sort) %>
+<ul>
+    <li><%= link_to(l(:label_details), query_params.merge({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue }),
+                                       :class => (action_name == 'index' ? 'selected' : nil)) %></li>
+    <li><%= link_to(l(:label_report), query_params.merge({:controller => 'timelog', :action => 'report', :project_id => @project, :issue_id => @issue}),
+                                       :class => (action_name == 'report' ? 'selected' : nil)) %></li>
+</ul>
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2e/2e4d7c7eff8f75e07fa65599f46a1983efb8afeb.svn-base
--- /dev/null
+++ b/.svn/pristine/2e/2e4d7c7eff8f75e07fa65599f46a1983efb8afeb.svn-base
@@ -0,0 +1,150 @@
+<h2><%= @copy ? l(:button_copy) : l(:label_bulk_edit_selected_issues) %></h2>
+
+<ul id="bulk-selection">
+<% @issues.each do |issue| %>
+  <%= content_tag 'li', link_to_issue(issue) %>
+<% end %>
+</ul>
+
+<%= form_tag(bulk_update_issues_path, :id => 'bulk_edit_form') do %>
+<%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join("\n").html_safe %>
+<div class="box tabular">
+<fieldset class="attributes">
+<legend><%= l(:label_change_properties) %></legend>
+
+<div class="splitcontentleft">
+<% if @allowed_projects.present? %>
+<p>
+  <label for="issue_project_id"><%= l(:field_project) %></label>
+  <%= select_tag('issue[project_id]', content_tag('option', l(:label_no_change_option), :value => '') + project_tree_options_for_select(@allowed_projects, :selected => @target_project),
+                 :onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')") %>
+</p>
+<% end %>
+<p>
+  <label for="issue_tracker_id"><%= l(:field_tracker) %></label>
+  <%= select_tag('issue[tracker_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@trackers, :id, :name)) %>
+</p>
+<% if @available_statuses.any? %>
+<p>
+  <label for='issue_status_id'><%= l(:field_status) %></label>
+  <%= select_tag('issue[status_id]',content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_statuses, :id, :name)) %>
+</p>
+<% end %>
+
+<% if @safe_attributes.include?('priority_id') -%>
+<p>
+  <label for='issue_priority_id'><%= l(:field_priority) %></label>
+  <%= select_tag('issue[priority_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(IssuePriority.active, :id, :name)) %>
+</p>
+<% end %>
+
+<% if @safe_attributes.include?('assigned_to_id') -%>
+<p>
+  <label for='issue_assigned_to_id'><%= l(:field_assigned_to) %></label>
+  <%= select_tag('issue[assigned_to_id]', content_tag('option', l(:label_no_change_option), :value => '') +
+                                 content_tag('option', l(:label_nobody), :value => 'none') +
+                                 principals_options_for_select(@assignables)) %>
+</p>
+<% end %>
+
+<% if @safe_attributes.include?('category_id') -%>
+<p>
+  <label for='issue_category_id'><%= l(:field_category) %></label>
+  <%= select_tag('issue[category_id]', content_tag('option', l(:label_no_change_option), :value => '') +
+                                content_tag('option', l(:label_none), :value => 'none') +
+                                options_from_collection_for_select(@categories, :id, :name)) %>
+</p>
+<% end %>
+
+<% if @safe_attributes.include?('fixed_version_id') -%>
+<p>
+  <label for='issue_fixed_version_id'><%= l(:field_fixed_version) %></label>
+  <%= select_tag('issue[fixed_version_id]', content_tag('option', l(:label_no_change_option), :value => '') +
+                                   content_tag('option', l(:label_none), :value => 'none') +
+                                   version_options_for_select(@versions.sort)) %>
+</p>
+<% end %>
+
+<% @custom_fields.each do |custom_field| %>
+  <p><label><%= h(custom_field.name) %></label> <%= custom_field_tag_for_bulk_edit('issue', custom_field, @projects) %></p>
+<% end %>
+
+<% if @copy && @attachments_present %>
+<p>
+  <label for='copy_attachments'><%= l(:label_copy_attachments) %></label>
+  <%= check_box_tag 'copy_attachments', '1', true %>
+</p>
+<% end %>
+
+<% if @copy && @subtasks_present %>
+<p>
+  <label for='copy_subtasks'><%= l(:label_copy_subtasks) %></label>
+  <%= check_box_tag 'copy_subtasks', '1', true %>
+</p>
+<% end %>
+
+<%= call_hook(:view_issues_bulk_edit_details_bottom, { :issues => @issues }) %>
+</div>
+
+<div class="splitcontentright">
+<% if @safe_attributes.include?('is_private') %>
+<p>
+  <label for='issue_is_private'><%= l(:field_is_private) %></label>
+  <%= select_tag('issue[is_private]', content_tag('option', l(:label_no_change_option), :value => '') +
+                                content_tag('option', l(:general_text_Yes), :value => '1') +
+                                content_tag('option', l(:general_text_No), :value => '0')) %>
+</p>
+<% end %>
+
+<% if @safe_attributes.include?('parent_issue_id') && @project %>
+<p>
+  <label for='issue_parent_issue_id'><%= l(:field_parent_issue) %></label>
+  <%= text_field_tag 'issue[parent_issue_id]', '', :size => 10 %>
+</p>
+<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project)}')" %>
+<% end %>
+
+<% if @safe_attributes.include?('start_date') %>
+<p>
+  <label for='issue_start_date'><%= l(:field_start_date) %></label>
+  <%= text_field_tag 'issue[start_date]', '', :size => 10 %><%= calendar_for('issue_start_date') %>
+</p>
+<% end %>
+
+<% if @safe_attributes.include?('due_date') %>
+<p>
+  <label for='issue_due_date'><%= l(:field_due_date) %></label>
+  <%= text_field_tag 'issue[due_date]', '', :size => 10 %><%= calendar_for('issue_due_date') %>
+</p>
+<% end %>
+
+<% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %>
+<p>
+  <label for='issue_done_ratio'><%= l(:field_done_ratio) %></label>
+  <%= select_tag 'issue[done_ratio]', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %>
+</p>
+<% end %>
+</div>
+
+</fieldset>
+
+<fieldset><legend><%= l(:field_notes) %></legend>
+<%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %>
+<%= wikitoolbar_for 'notes' %>
+</fieldset>
+</div>
+
+<p>
+	<% if @copy %>
+	  <%= hidden_field_tag 'copy', '1' %>
+	  <%= submit_tag l(:button_copy) %>
+	  <%= submit_tag l(:button_copy_and_follow), :name => 'follow' %>
+	<% elsif @target_project %>
+	  <%= submit_tag l(:button_move) %>
+	  <%= submit_tag l(:button_move_and_follow), :name => 'follow' %>
+	<% else %>
+	  <%= submit_tag l(:button_submit) %>
+	<% end %>
+</p>
+
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2e/2e9778d3950cea9aad42938a07deac546bf3beda.svn-base
--- /dev/null
+++ b/.svn/pristine/2e/2e9778d3950cea9aad42938a07deac546bf3beda.svn-base
@@ -0,0 +1,74 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class ThemesTest < ActionController::IntegrationTest
+
+  def setup
+    @theme = Redmine::Themes.themes.last
+    Setting.ui_theme = @theme.id
+  end
+
+  def teardown
+    Setting.ui_theme = ''
+  end
+
+  def test_application_css
+    get '/'
+
+    assert_response :success
+    assert_tag :tag => 'link',
+      :attributes => {:href => %r{^/themes/#{@theme.dir}/stylesheets/application.css}}
+  end
+
+  def test_without_theme_js
+    get '/'
+
+    assert_response :success
+    assert_no_tag :tag => 'script',
+      :attributes => {:src => %r{^/themes/#{@theme.dir}/javascripts/theme.js}}
+  end
+
+  def test_with_theme_js
+    # Simulates a theme.js
+    @theme.javascripts << 'theme'
+    get '/'
+
+    assert_response :success
+    assert_tag :tag => 'script',
+      :attributes => {:src => %r{^/themes/#{@theme.dir}/javascripts/theme.js}}
+
+  ensure
+    @theme.javascripts.delete 'theme'
+  end
+
+  def test_with_sub_uri
+    Redmine::Utils.relative_url_root = '/foo'
+    @theme.javascripts << 'theme'
+    get '/'
+
+    assert_response :success
+    assert_tag :tag => 'link',
+      :attributes => {:href => %r{^/foo/themes/#{@theme.dir}/stylesheets/application.css}}
+    assert_tag :tag => 'script',
+      :attributes => {:src => %r{^/foo/themes/#{@theme.dir}/javascripts/theme.js}}
+
+  ensure
+    Redmine::Utils.relative_url_root = ''
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2e/2ee21f20a298f9183bcf6da4115281a958daccfb.svn-base
--- a/.svn/pristine/2e/2ee21f20a298f9183bcf6da4115281a958daccfb.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= link_to l(:label_issue_status_plural), issue_statuses_path %> &#187; <%=h @issue_status %></h2>
-
-<% form_for @issue_status, :builder => TabularFormBuilder do |f| %>
-  <%= render :partial => 'form', :locals => {:f => f} %>
-  <%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2f/2f133168a880fffbd35ca248f3d226a5ea263cb4.svn-base
--- /dev/null
+++ b/.svn/pristine/2f/2f133168a880fffbd35ca248f3d226a5ea263cb4.svn-base
@@ -0,0 +1,90 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class NewsTest < ActiveSupport::TestCase
+  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news
+
+  def valid_news
+    { :title => 'Test news', :description => 'Lorem ipsum etc', :author => User.first }
+  end
+
+  def setup
+  end
+
+  def test_create_should_send_email_notification
+    ActionMailer::Base.deliveries.clear
+    news = Project.find(1).news.new(valid_news)
+
+    with_settings :notified_events => %w(news_added) do
+      assert news.save
+    end
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_should_include_news_for_projects_with_news_enabled
+    project = projects(:projects_001)
+    assert project.enabled_modules.any?{ |em| em.name == 'news' }
+
+    # News.latest should return news from projects_001
+    assert News.latest.any? { |news| news.project == project }
+  end
+
+  def test_should_not_include_news_for_projects_with_news_disabled
+    EnabledModule.delete_all(["project_id = ? AND name = ?", 2, 'news'])
+    project = Project.find(2)
+
+    # Add a piece of news to the project
+    news = project.news.create(valid_news)
+
+    # News.latest should not return that new piece of news
+    assert News.latest.include?(news) == false
+  end
+
+  def test_should_only_include_news_from_projects_visibly_to_the_user
+    assert News.latest(User.anonymous).all? { |news| news.project.is_public? }
+  end
+
+  def test_should_limit_the_amount_of_returned_news
+    # Make sure we have a bunch of news stories
+    10.times { projects(:projects_001).news.create(valid_news) }
+    assert_equal 2, News.latest(users(:users_002), 2).size
+    assert_equal 6, News.latest(users(:users_002), 6).size
+  end
+
+  def test_should_return_5_news_stories_by_default
+    # Make sure we have a bunch of news stories
+    10.times { projects(:projects_001).news.create(valid_news) }
+    assert_equal 5, News.latest(users(:users_004)).size
+  end
+
+  def test_attachments_should_be_visible
+    assert News.find(1).attachments_visible?(User.anonymous)
+  end
+
+  def test_attachments_should_be_deletable_with_manage_news_permission
+    manager = User.find(2)
+    assert News.find(1).attachments_deletable?(manager)
+  end
+
+  def test_attachments_should_not_be_deletable_without_manage_news_permission
+    manager = User.find(2)
+    Role.find_by_name('Manager').remove_permission!(:manage_news)
+    assert !News.find(1).attachments_deletable?(manager)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2f/2f1f6f8262e47819e2d086a5c6cc0817e0e7d2b5.svn-base
--- a/.svn/pristine/2f/2f1f6f8262e47819e2d086a5c6cc0817e0e7d2b5.svn-base
+++ /dev/null
@@ -1,526 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'uri'
-require 'cgi'
-
-class Unauthorized < Exception; end
-
-class ApplicationController < ActionController::Base
-  include Redmine::I18n
-
-  layout 'base'
-  exempt_from_layout 'builder', 'rsb'
-
-  protect_from_forgery
-  def handle_unverified_request
-    super
-    cookies.delete(:autologin)
-  end
-  # Remove broken cookie after upgrade from 0.8.x (#4292)
-  # See https://rails.lighthouseapp.com/projects/8994/tickets/3360
-  # TODO: remove it when Rails is fixed
-  before_filter :delete_broken_cookies
-  def delete_broken_cookies
-    if cookies['_redmine_session'] && cookies['_redmine_session'] !~ /--/
-      cookies.delete '_redmine_session'
-      redirect_to home_path
-      return false
-    end
-  end
-
-  before_filter :user_setup, :check_if_login_required, :set_localization
-  filter_parameter_logging :password
-
-  rescue_from ActionController::InvalidAuthenticityToken, :with => :invalid_authenticity_token
-  rescue_from ::Unauthorized, :with => :deny_access
-
-  include Redmine::Search::Controller
-  include Redmine::MenuManager::MenuController
-  helper Redmine::MenuManager::MenuHelper
-
-  Redmine::Scm::Base.all.each do |scm|
-    require_dependency "repository/#{scm.underscore}"
-  end
-
-  def user_setup
-    # Check the settings cache for each request
-    Setting.check_cache
-    # Find the current user
-    User.current = find_current_user
-  end
-
-  # Returns the current user or nil if no user is logged in
-  # and starts a session if needed
-  def find_current_user
-    if session[:user_id]
-      # existing session
-      (User.active.find(session[:user_id]) rescue nil)
-    elsif cookies[:autologin] && Setting.autologin?
-      # auto-login feature starts a new session
-      user = User.try_to_autologin(cookies[:autologin])
-      session[:user_id] = user.id if user
-      user
-    elsif params[:format] == 'atom' && params[:key] && request.get? && accept_rss_auth?
-      # RSS key authentication does not start a session
-      User.find_by_rss_key(params[:key])
-    elsif Setting.rest_api_enabled? && accept_api_auth?
-      if (key = api_key_from_request)
-        # Use API key
-        User.find_by_api_key(key)
-      else
-        # HTTP Basic, either username/password or API key/random
-        authenticate_with_http_basic do |username, password|
-          User.try_to_login(username, password) || User.find_by_api_key(username)
-        end
-      end
-    end
-  end
-
-  # Sets the logged in user
-  def logged_user=(user)
-    reset_session
-    if user && user.is_a?(User)
-      User.current = user
-      session[:user_id] = user.id
-    else
-      User.current = User.anonymous
-    end
-  end
-
-  # check if login is globally required to access the application
-  def check_if_login_required
-    # no check needed if user is already logged in
-    return true if User.current.logged?
-    require_login if Setting.login_required?
-  end
-
-  def set_localization
-    lang = nil
-    if User.current.logged?
-      lang = find_language(User.current.language)
-    end
-    if lang.nil? && request.env['HTTP_ACCEPT_LANGUAGE']
-      accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first
-      if !accept_lang.blank?
-        accept_lang = accept_lang.downcase
-        lang = find_language(accept_lang) || find_language(accept_lang.split('-').first)
-      end
-    end
-    lang ||= Setting.default_language
-    set_language_if_valid(lang)
-  end
-
-  def require_login
-    if !User.current.logged?
-      # Extract only the basic url parameters on non-GET requests
-      if request.get?
-        url = url_for(params)
-      else
-        url = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id], :project_id => params[:project_id])
-      end
-      respond_to do |format|
-        format.html { redirect_to :controller => "account", :action => "login", :back_url => url }
-        format.atom { redirect_to :controller => "account", :action => "login", :back_url => url }
-        format.xml  { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
-        format.js   { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
-        format.json { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
-      end
-      return false
-    end
-    true
-  end
-
-  def require_admin
-    return unless require_login
-    if !User.current.admin?
-      render_403
-      return false
-    end
-    true
-  end
-
-  def deny_access
-    User.current.logged? ? render_403 : require_login
-  end
-
-  # Authorize the user for the requested action
-  def authorize(ctrl = params[:controller], action = params[:action], global = false)
-    allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project || @projects, :global => global)
-    if allowed
-      true
-    else
-      if @project && @project.archived?
-        render_403 :message => :notice_not_authorized_archived_project
-      else
-        deny_access
-      end
-    end
-  end
-
-  # Authorize the user for the requested action outside a project
-  def authorize_global(ctrl = params[:controller], action = params[:action], global = true)
-    authorize(ctrl, action, global)
-  end
-
-  # Find project of id params[:id]
-  def find_project
-    @project = Project.find(params[:id])
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  # Find project of id params[:project_id]
-  def find_project_by_project_id
-    @project = Project.find(params[:project_id])
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  # Find a project based on params[:project_id]
-  # TODO: some subclasses override this, see about merging their logic
-  def find_optional_project
-    @project = Project.find(params[:project_id]) unless params[:project_id].blank?
-    allowed = User.current.allowed_to?({:controller => params[:controller], :action => params[:action]}, @project, :global => true)
-    allowed ? true : deny_access
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  # Finds and sets @project based on @object.project
-  def find_project_from_association
-    render_404 unless @object.present?
-
-    @project = @object.project
-  end
-
-  def find_model_object
-    model = self.class.read_inheritable_attribute('model_object')
-    if model
-      @object = model.find(params[:id])
-      self.instance_variable_set('@' + controller_name.singularize, @object) if @object
-    end
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  def self.model_object(model)
-    write_inheritable_attribute('model_object', model)
-  end
-
-  # Filter for bulk issue operations
-  def find_issues
-    @issues = Issue.find_all_by_id(params[:id] || params[:ids])
-    raise ActiveRecord::RecordNotFound if @issues.empty?
-    if @issues.detect {|issue| !issue.visible?}
-      deny_access
-      return
-    end
-    @projects = @issues.collect(&:project).compact.uniq
-    @project = @projects.first if @projects.size == 1
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  # Check if project is unique before bulk operations
-  def check_project_uniqueness
-    unless @project
-      # TODO: let users bulk edit/move/destroy issues from different projects
-      render_error 'Can not bulk edit/move/destroy issues from different projects'
-      return false
-    end
-  end
-
-  # make sure that the user is a member of the project (or admin) if project is private
-  # used as a before_filter for actions that do not require any particular permission on the project
-  def check_project_privacy
-    if @project && @project.active?
-      if @project.is_public? || User.current.member_of?(@project) || User.current.admin?
-        true
-      else
-        deny_access
-      end
-    else
-      @project = nil
-      render_404
-      false
-    end
-  end
-
-  def back_url
-    params[:back_url] || request.env['HTTP_REFERER']
-  end
-
-  def redirect_back_or_default(default)
-    back_url = CGI.unescape(params[:back_url].to_s)
-    if !back_url.blank?
-      begin
-        uri = URI.parse(back_url)
-        # do not redirect user to another host or to the login or register page
-        if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
-          redirect_to(back_url)
-          return
-        end
-      rescue URI::InvalidURIError
-        # redirect to default
-      end
-    end
-    redirect_to default
-    false
-  end
-
-  def render_403(options={})
-    @project = nil
-    render_error({:message => :notice_not_authorized, :status => 403}.merge(options))
-    return false
-  end
-
-  def render_404(options={})
-    render_error({:message => :notice_file_not_found, :status => 404}.merge(options))
-    return false
-  end
-
-  # Renders an error response
-  def render_error(arg)
-    arg = {:message => arg} unless arg.is_a?(Hash)
-
-    @message = arg[:message]
-    @message = l(@message) if @message.is_a?(Symbol)
-    @status = arg[:status] || 500
-
-    respond_to do |format|
-      format.html {
-        render :template => 'common/error', :layout => use_layout, :status => @status
-      }
-      format.atom { head @status }
-      format.xml { head @status }
-      format.js { head @status }
-      format.json { head @status }
-    end
-  end
-  
-  # Filter for actions that provide an API response
-  # but have no HTML representation for non admin users
-  def require_admin_or_api_request
-    return true if api_request?
-    if User.current.admin?
-      true
-    elsif User.current.logged?
-      render_error(:status => 406)
-    else
-      deny_access
-    end
-  end
-
-  # Picks which layout to use based on the request
-  #
-  # @return [boolean, string] name of the layout to use or false for no layout
-  def use_layout
-    request.xhr? ? false : 'base'
-  end
-
-  def invalid_authenticity_token
-    if api_request?
-      logger.error "Form authenticity token is missing or is invalid. API calls must include a proper Content-type header (text/xml or text/json)."
-    end
-    render_error "Invalid form authenticity token."
-  end
-
-  def render_feed(items, options={})
-    @items = items || []
-    @items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
-    @items = @items.slice(0, Setting.feeds_limit.to_i)
-    @title = options[:title] || Setting.app_title
-    render :template => "common/feed.atom", :layout => false,
-           :content_type => 'application/atom+xml'
-  end
-
-  # TODO: remove in Redmine 1.4
-  def self.accept_key_auth(*actions)
-    ActiveSupport::Deprecation.warn "ApplicationController.accept_key_auth is deprecated and will be removed in Redmine 1.4. Use accept_rss_auth (or accept_api_auth) instead."
-    accept_rss_auth(*actions)
-  end
-
-  # TODO: remove in Redmine 1.4
-  def accept_key_auth_actions
-    ActiveSupport::Deprecation.warn "ApplicationController.accept_key_auth_actions is deprecated and will be removed in Redmine 1.4. Use accept_rss_auth (or accept_api_auth) instead."
-    self.class.accept_rss_auth
-  end
-
-  def self.accept_rss_auth(*actions)
-    if actions.any?
-      write_inheritable_attribute('accept_rss_auth_actions', actions)
-    else
-      read_inheritable_attribute('accept_rss_auth_actions') || []
-    end
-  end
-
-  def accept_rss_auth?(action=action_name)
-    self.class.accept_rss_auth.include?(action.to_sym)
-  end
-
-  def self.accept_api_auth(*actions)
-    if actions.any?
-      write_inheritable_attribute('accept_api_auth_actions', actions)
-    else
-      read_inheritable_attribute('accept_api_auth_actions') || []
-    end
-  end
-
-  def accept_api_auth?(action=action_name)
-    self.class.accept_api_auth.include?(action.to_sym)
-  end
-
-  # Returns the number of objects that should be displayed
-  # on the paginated list
-  def per_page_option
-    per_page = nil
-    if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
-      per_page = params[:per_page].to_s.to_i
-      session[:per_page] = per_page
-    elsif session[:per_page]
-      per_page = session[:per_page]
-    else
-      per_page = Setting.per_page_options_array.first || 25
-    end
-    per_page
-  end
-
-  # Returns offset and limit used to retrieve objects
-  # for an API response based on offset, limit and page parameters
-  def api_offset_and_limit(options=params)
-    if options[:offset].present?
-      offset = options[:offset].to_i
-      if offset < 0
-        offset = 0
-      end
-    end
-    limit = options[:limit].to_i
-    if limit < 1
-      limit = 25
-    elsif limit > 100
-      limit = 100
-    end
-    if offset.nil? && options[:page].present?
-      offset = (options[:page].to_i - 1) * limit
-      offset = 0 if offset < 0
-    end
-    offset ||= 0
-
-    [offset, limit]
-  end
-
-  # qvalues http header parser
-  # code taken from webrick
-  def parse_qvalues(value)
-    tmp = []
-    if value
-      parts = value.split(/,\s*/)
-      parts.each {|part|
-        if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
-          val = m[1]
-          q = (m[2] or 1).to_f
-          tmp.push([val, q])
-        end
-      }
-      tmp = tmp.sort_by{|val, q| -q}
-      tmp.collect!{|val, q| val}
-    end
-    return tmp
-  rescue
-    nil
-  end
-
-  # Returns a string that can be used as filename value in Content-Disposition header
-  def filename_for_content_disposition(name)
-    request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
-  end
-
-  def api_request?
-    %w(xml json).include? params[:format]
-  end
-
-  # Returns the API key present in the request
-  def api_key_from_request
-    if params[:key].present?
-      params[:key]
-    elsif request.headers["X-Redmine-API-Key"].present?
-      request.headers["X-Redmine-API-Key"]
-    end
-  end
-
-  # Renders a warning flash if obj has unsaved attachments
-  def render_attachment_warning_if_needed(obj)
-    flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present?
-  end
-
-  # Sets the `flash` notice or error based the number of issues that did not save
-  #
-  # @param [Array, Issue] issues all of the saved and unsaved Issues
-  # @param [Array, Integer] unsaved_issue_ids the issue ids that were not saved
-  def set_flash_from_bulk_issue_save(issues, unsaved_issue_ids)
-    if unsaved_issue_ids.empty?
-      flash[:notice] = l(:notice_successful_update) unless issues.empty?
-    else
-      flash[:error] = l(:notice_failed_to_save_issues,
-                        :count => unsaved_issue_ids.size,
-                        :total => issues.size,
-                        :ids => '#' + unsaved_issue_ids.join(', #'))
-    end
-  end
-
-  # Rescues an invalid query statement. Just in case...
-  def query_statement_invalid(exception)
-    logger.error "Query::StatementInvalid: #{exception.message}" if logger
-    session.delete(:query)
-    sort_clear if respond_to?(:sort_clear)
-    render_error "An error occurred while executing the query and has been logged. Please report this error to your Redmine administrator."
-  end
-
-  # Renders API response on validation failure
-  def render_validation_errors(object)
-    options = { :status => :unprocessable_entity, :layout => false }
-    options.merge!(case params[:format]
-      when 'xml';  { :xml =>  object.errors }
-      when 'json'; { :json => {'errors' => object.errors} } # ActiveResource client compliance
-      else
-        raise "Unknown format #{params[:format]} in #render_validation_errors"
-      end
-    )
-    render options
-  end
-
-  # Overrides #default_template so that the api template
-  # is used automatically if it exists
-  def default_template(action_name = self.action_name)
-    if api_request?
-      begin
-        return self.view_paths.find_template(default_template_name(action_name), 'api')
-      rescue ::ActionView::MissingTemplate
-        # the api template was not found
-        # fallback to the default behaviour
-      end
-    end
-    super
-  end
-
-  # Overrides #pick_layout so that #render with no arguments
-  # doesn't use the layout for api requests
-  def pick_layout(*args)
-    api_request? ? nil : super
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2f/2f2c80ebd6e33d1fd4e81ae48e2384cbacf46e18.svn-base
--- a/.svn/pristine/2f/2f2c80ebd6e33d1fd4e81ae48e2384cbacf46e18.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class MessageObserver < ActiveRecord::Observer
-  def after_create(message)
-    Mailer.deliver_message_posted(message) if Setting.notified_events.include?('message_posted')
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2f/2f3ef4ed7d4fcc37d2d5c06ce61c1093cb75fa73.svn-base
--- a/.svn/pristine/2f/2f3ef4ed7d4fcc37d2d5c06ce61c1093cb75fa73.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-class AlphaPluginController < ApplicationController
-  def an_action
-    render_class_and_action
-  end
-  def action_with_layout
-    render_class_and_action(nil, :layout => "plugin_layout")
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/2f/2ff7c4a24ae3be5225189f1a6fd5fd0c91104ce3.svn-base
--- /dev/null
+++ b/.svn/pristine/2f/2ff7c4a24ae3be5225189f1a6fd5fd0c91104ce3.svn-base
@@ -0,0 +1,34 @@
+<div class="contextual">
+<%= link_to l(:label_document_new), new_project_document_path(@project), :class => 'icon icon-add',
+      :onclick => 'showAndScrollTo("add-document", "document_title"); return false;' if User.current.allowed_to?(:add_documents, @project) %>
+</div>
+
+<div id="add-document" style="display:none;">
+<h2><%=l(:label_document_new)%></h2>
+<%= labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
+<%= render :partial => 'form', :locals => {:f => f} %>
+<p>
+	<%= submit_tag l(:button_create) %>
+  <%= link_to l(:button_cancel), "#", :onclick => '$("#add-document").hide(); return false;' %>
+</p>
+<% end %>
+</div>
+
+<h2><%=l(:label_document_plural)%></h2>
+
+<% if @grouped.empty? %><p class="nodata"><%= l(:label_no_data) %></p><% end %>
+
+<% @grouped.keys.sort.each do |group| %>
+    <h3><%= group %></h3>
+    <%= render :partial => 'documents/document', :collection => @grouped[group] %>
+<% end %>
+
+<% content_for :sidebar do %>
+  <h3><%= l(:label_sort_by, '') %></h3>
+  <%= link_to l(:field_category), {:sort_by => 'category'}, :class => (@sort_by == 'category' ? 'selected' :nil) %><br />
+  <%= link_to l(:label_date), {:sort_by => 'date'}, :class => (@sort_by == 'date' ? 'selected' :nil) %><br />
+  <%= link_to l(:field_title), {:sort_by => 'title'}, :class => (@sort_by == 'title' ? 'selected' :nil) %><br />
+  <%= link_to l(:field_author), {:sort_by => 'author'}, :class => (@sort_by == 'author' ? 'selected' :nil) %>
+<% end %>
+
+<% html_title(l(:label_document_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/30/301185c13f555c3833de6896f8f45895314d605b.svn-base
--- /dev/null
+++ b/.svn/pristine/30/301185c13f555c3833de6896f8f45895314d605b.svn-base
@@ -0,0 +1,32 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingCommentsTest < ActionController::IntegrationTest
+  def test_comments
+    assert_routing(
+        { :method => 'post', :path => "/news/567/comments" },
+        { :controller => 'comments', :action => 'create', :id => '567' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/news/567/comments/15" },
+        { :controller => 'comments', :action => 'destroy', :id => '567',
+          :comment_id => '15' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/30/304b68e7e7a6cf907c51306f2e95b29f2a8946e9.svn-base
--- a/.svn/pristine/30/304b68e7e7a6cf907c51306f2e95b29f2a8946e9.svn-base
+++ /dev/null
@@ -1,256 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class RepositoryTest < ActiveSupport::TestCase
-  fixtures :projects,
-           :trackers,
-           :projects_trackers,
-           :enabled_modules,
-           :repositories,
-           :issues,
-           :issue_statuses,
-           :issue_categories,
-           :changesets,
-           :changes,
-           :users,
-           :members,
-           :member_roles,
-           :roles,
-           :enumerations
-
-  def setup
-    @repository = Project.find(1).repository
-  end
-
-  def test_create
-    repository = Repository::Subversion.new(:project => Project.find(3))
-    assert !repository.save
-
-    repository.url = "svn://localhost"
-    assert repository.save
-    repository.reload
-
-    project = Project.find(3)
-    assert_equal repository, project.repository
-  end
-
-  def test_destroy
-    changesets = Changeset.count(:all, :conditions => "repository_id = 10")
-    changes = Change.count(:all, :conditions => "repository_id = 10",
-                           :include => :changeset)
-    assert_difference 'Changeset.count', -changesets do
-      assert_difference 'Change.count', -changes do
-        Repository.find(10).destroy
-      end
-    end
-  end
-
-  def test_should_not_create_with_disabled_scm
-    # disable Subversion
-    with_settings :enabled_scm => ['Darcs', 'Git'] do
-      repository = Repository::Subversion.new(
-                      :project => Project.find(3), :url => "svn://localhost")
-      assert !repository.save
-      assert_equal I18n.translate('activerecord.errors.messages.invalid'),
-                                  repository.errors.on(:type)
-    end
-  end
-
-  def test_scan_changesets_for_issue_ids
-    Setting.default_language = 'en'
-    Setting.notified_events = ['issue_added','issue_updated']
-
-    # choosing a status to apply to fix issues
-    Setting.commit_fix_status_id = IssueStatus.find(
-                                     :first,
-                                     :conditions => ["is_closed = ?", true]).id
-    Setting.commit_fix_done_ratio = "90"
-    Setting.commit_ref_keywords = 'refs , references, IssueID'
-    Setting.commit_fix_keywords = 'fixes , closes'
-    Setting.default_language = 'en'
-    ActionMailer::Base.deliveries.clear
-
-    # make sure issue 1 is not already closed
-    fixed_issue = Issue.find(1)
-    assert !fixed_issue.status.is_closed?
-    old_status = fixed_issue.status
-
-    Repository.scan_changesets_for_issue_ids
-    assert_equal [101, 102], Issue.find(3).changeset_ids
-
-    # fixed issues
-    fixed_issue.reload
-    assert fixed_issue.status.is_closed?
-    assert_equal 90, fixed_issue.done_ratio
-    assert_equal [101], fixed_issue.changeset_ids
-
-    # issue change
-    journal = fixed_issue.journals.find(:first, :order => 'created_on desc')
-    assert_equal User.find_by_login('dlopper'), journal.user
-    assert_equal 'Applied in changeset r2.', journal.notes
-
-    # 2 email notifications
-    assert_equal 2, ActionMailer::Base.deliveries.size
-    mail = ActionMailer::Base.deliveries.first
-    assert_kind_of TMail::Mail, mail
-    assert mail.subject.starts_with?(
-        "[#{fixed_issue.project.name} - #{fixed_issue.tracker.name} ##{fixed_issue.id}]")
-    assert mail.body.include?(
-        "Status changed from #{old_status} to #{fixed_issue.status}")
-
-    # ignoring commits referencing an issue of another project
-    assert_equal [], Issue.find(4).changesets
-  end
-
-  def test_for_changeset_comments_strip
-    repository = Repository::Mercurial.create(
-                    :project => Project.find( 4 ),
-                    :url => '/foo/bar/baz' )
-    comment = <<-COMMENT
-    This is a loooooooooooooooooooooooooooong comment                                                   
-                                                                                                       
-                                                                                            
-    COMMENT
-    changeset = Changeset.new(
-      :comments => comment, :commit_date => Time.now,
-      :revision => 0, :scmid => 'f39b7922fb3c',
-      :committer => 'foo <foo@example.com>',
-      :committed_on => Time.now, :repository => repository )
-    assert( changeset.save )
-    assert_not_equal( comment, changeset.comments )
-    assert_equal( 'This is a loooooooooooooooooooooooooooong comment',
-                  changeset.comments )
-  end
-
-  def test_for_urls_strip_cvs
-    repository = Repository::Cvs.create(
-        :project => Project.find(4),
-        :url => ' :pserver:login:password@host:/path/to/the/repository',
-        :root_url => 'foo  ',
-        :log_encoding => 'UTF-8')
-    assert repository.save
-    repository.reload
-    assert_equal ':pserver:login:password@host:/path/to/the/repository',
-                  repository.url
-    assert_equal 'foo', repository.root_url
-  end
-
-  def test_for_urls_strip_subversion
-    repository = Repository::Subversion.create(
-        :project => Project.find(4),
-        :url => ' file:///dummy   ')
-    assert repository.save
-    repository.reload
-    assert_equal 'file:///dummy', repository.url
-  end
-
-  def test_for_urls_strip_git
-    repository = Repository::Git.create(
-        :project => Project.find(4),
-        :url => ' c:\dummy   ')
-    assert repository.save
-    repository.reload
-    assert_equal 'c:\dummy', repository.url
-  end
-
-  def test_manual_user_mapping
-    assert_no_difference "Changeset.count(:conditions => 'user_id <> 2')" do
-      c = Changeset.create!(
-              :repository => @repository,
-              :committer => 'foo',
-              :committed_on => Time.now,
-              :revision => 100,
-              :comments => 'Committed by foo.'
-            )
-      assert_nil c.user
-      @repository.committer_ids = {'foo' => '2'}
-      assert_equal User.find(2), c.reload.user
-      # committer is now mapped
-      c = Changeset.create!(
-              :repository => @repository,
-              :committer => 'foo',
-              :committed_on => Time.now,
-              :revision => 101,
-              :comments => 'Another commit by foo.'
-            )
-      assert_equal User.find(2), c.user
-    end
-  end
-
-  def test_auto_user_mapping_by_username
-    c = Changeset.create!(
-          :repository   => @repository,
-          :committer    => 'jsmith',
-          :committed_on => Time.now,
-          :revision     => 100,
-          :comments     => 'Committed by john.'
-        )
-    assert_equal User.find(2), c.user
-  end
-
-  def test_auto_user_mapping_by_email
-    c = Changeset.create!(
-          :repository   => @repository,
-          :committer    => 'john <jsmith@somenet.foo>',
-          :committed_on => Time.now,
-          :revision     => 100,
-          :comments     => 'Committed by john.'
-        )
-    assert_equal User.find(2), c.user
-  end
-
-  def test_filesystem_avaialbe
-    klass = Repository::Filesystem
-    assert klass.scm_adapter_class
-    assert_equal true, klass.scm_available
-  end
-
-  def test_merge_extra_info
-    repo = Repository::Subversion.new(:project => Project.find(3))
-    assert !repo.save
-    repo.url = "svn://localhost"
-    assert repo.save
-    repo.reload
-    project = Project.find(3)
-    assert_equal repo, project.repository
-    assert_nil repo.extra_info
-    h1 = {"test_1" => {"test_11" => "test_value_11"}}
-    repo.merge_extra_info(h1)
-    assert_equal h1, repo.extra_info
-    h2 = {"test_2" => {
-                   "test_21" => "test_value_21",
-                   "test_22" => "test_value_22",
-                  }}
-    repo.merge_extra_info(h2)
-    assert_equal (h = {"test_11" => "test_value_11"}),
-                 repo.extra_info["test_1"]
-    assert_equal "test_value_21",
-                 repo.extra_info["test_2"]["test_21"]
-    h3 = {"test_2" => {
-                   "test_23" => "test_value_23",
-                   "test_24" => "test_value_24",
-                  }}
-    repo.merge_extra_info(h3)
-    assert_equal (h = {"test_11" => "test_value_11"}),
-                 repo.extra_info["test_1"]
-    assert_nil repo.extra_info["test_2"]["test_21"]
-    assert_equal "test_value_23",
-                 repo.extra_info["test_2"]["test_23"]
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/30/30787e3d5bfe04d8411e5332a384d8a1a749f767.svn-base
--- /dev/null
+++ b/.svn/pristine/30/30787e3d5bfe04d8411e5332a384d8a1a749f767.svn-base
@@ -0,0 +1,38 @@
+<h2><%= l(:label_board_plural) %></h2>
+
+<table class="list boards">
+  <thead><tr>
+    <th><%= l(:label_board) %></th>
+    <th><%= l(:label_topic_plural) %></th>
+    <th><%= l(:label_message_plural) %></th>
+    <th><%= l(:label_message_last) %></th>
+  </tr></thead>
+  <tbody>
+<% Board.board_tree(@boards) do |board, level| %>
+  <tr class="<%= cycle 'odd', 'even' %>">
+    <td style="padding-left: <%= level * 18 %>px;">
+      <%= link_to h(board.name), project_board_path(board.project, board), :class => "board" %><br />
+      <%=h board.description %>
+    </td>
+    <td class="topic-count"><%= board.topics_count %></td>
+    <td class="message-count"><%= board.messages_count %></td>
+    <td class="last-message">
+      <% if board.last_message %>
+      <%= authoring board.last_message.created_on, board.last_message.author %><br />
+      <%= link_to_message board.last_message %>
+      <% end %>
+    </td>
+  </tr>
+<% end %>
+  </tbody>
+</table>
+
+<% other_formats_links do |f| %>
+  <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => @project, :show_messages => 1, :key => User.current.rss_key} %>
+<% end %>
+
+<% content_for :header_tags do %>
+  <%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :id => @project, :format => 'atom', :show_messages => 1, :key => User.current.rss_key}) %>
+<% end %>
+
+<% html_title l(:label_board_plural) %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/30/30881f171a667b3a44449e71bb74b80be13859b2.svn-base
--- a/.svn/pristine/30/30881f171a667b3a44449e71bb74b80be13859b2.svn-base
+++ /dev/null
@@ -1,95 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # Scanner for JSON (JavaScript Object Notation).
-  class JSON < Scanner
-    
-    register_for :json
-    file_extension 'json'
-    
-    KINDS_NOT_LOC = [
-      :float, :char, :content, :delimiter,
-      :error, :integer, :operator, :value,
-    ]  # :nodoc:
-    
-    ESCAPE = / [bfnrt\\"\/] /x  # :nodoc:
-    UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x  # :nodoc:
-    
-  protected
-    
-    # See http://json.org/ for a definition of the JSON lexic/grammar.
-    def scan_tokens encoder, options
-      
-      state = :initial
-      stack = []
-      key_expected = false
-      
-      until eos?
-        
-        case state
-        
-        when :initial
-          if match = scan(/ \s+ /x)
-            encoder.text_token match, :space
-          elsif match = scan(/"/)
-            state = key_expected ? :key : :string
-            encoder.begin_group state
-            encoder.text_token match, :delimiter
-          elsif match = scan(/ [:,\[{\]}] /x)
-            encoder.text_token match, :operator
-            case match
-            when ':' then key_expected = false
-            when ',' then key_expected = true if stack.last == :object
-            when '{' then stack << :object; key_expected = true
-            when '[' then stack << :array
-            when '}', ']' then stack.pop  # no error recovery, but works for valid JSON
-            end
-          elsif match = scan(/ true | false | null /x)
-            encoder.text_token match, :value
-          elsif match = scan(/ -? (?: 0 | [1-9]\d* ) /x)
-            if scan(/ \.\d+ (?:[eE][-+]?\d+)? | [eE][-+]? \d+ /x)
-              match << matched
-              encoder.text_token match, :float
-            else
-              encoder.text_token match, :integer
-            end
-          else
-            encoder.text_token getch, :error
-          end
-          
-        when :string, :key
-          if match = scan(/[^\\"]+/)
-            encoder.text_token match, :content
-          elsif match = scan(/"/)
-            encoder.text_token match, :delimiter
-            encoder.end_group state
-            state = :initial
-          elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
-            encoder.text_token match, :char
-          elsif match = scan(/\\./m)
-            encoder.text_token match, :content
-          elsif match = scan(/ \\ | $ /x)
-            encoder.end_group state
-            encoder.text_token match, :error
-            state = :initial
-          else
-            raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
-          end
-          
-        else
-          raise_inspect 'Unknown state: %p' % [state], encoder
-          
-        end
-      end
-      
-      if [:string, :key].include? state
-        encoder.end_group state
-      end
-      
-      encoder
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/30/308a50990fe7138ee80b066400a54a3b1b066faf.svn-base
--- a/.svn/pristine/30/308a50990fe7138ee80b066400a54a3b1b066faf.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= TestHelper.view_path_for __FILE__ %>
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/30/308f688f7ea9b63ad1f36c2cfc3b151507bfbaea.svn-base
--- a/.svn/pristine/30/308f688f7ea9b63ad1f36c2cfc3b151507bfbaea.svn-base
+++ /dev/null
@@ -1,16 +0,0 @@
-api.array :time_entries, api_meta(:total_count => @entry_count, :offset => @offset, :limit => @limit) do
-  @entries.each do |time_entry|
-    api.time_entry do
-      api.id time_entry.id
-      api.project(:id => time_entry.project_id, :name => time_entry.project.name) unless time_entry.project.nil?
-      api.issue(:id => time_entry.issue_id) unless time_entry.issue.nil?
-      api.user(:id => time_entry.user_id, :name => time_entry.user.name) unless time_entry.user.nil?
-      api.activity(:id => time_entry.activity_id, :name => time_entry.activity.name) unless time_entry.activity.nil?
-      api.hours time_entry.hours
-      api.comments time_entry.comments
-      api.spent_on time_entry.spent_on
-      api.created_on time_entry.created_on
-      api.updated_on time_entry.updated_on
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/31/3111f66f2205d5a3793f8baff324b532853a4a60.svn-base
--- a/.svn/pristine/31/3111f66f2205d5a3793f8baff324b532853a4a60.svn-base
+++ /dev/null
@@ -1,1023 +0,0 @@
-# French translations for Ruby on Rails
-# by Christian Lescuyer (christian@flyingcoders.com)
-# contributor: Sebastien Grosjean - ZenCocoon.com
-# contributor: Thibaut Cuvelier - Developpez.com
-
-fr:
-  direction: ltr
-  date:
-    formats:
-      default: "%d/%m/%Y"
-      short: "%e %b"
-      long: "%e %B %Y"
-      long_ordinal: "%e %B %Y"
-      only_day: "%e"
-
-    day_names: [dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi]
-    abbr_day_names: [dim, lun, mar, mer, jeu, ven, sam]
-    month_names: [~, janvier, fÃ©vrier, mars, avril, mai, juin, juillet, aoÃ»t, septembre, octobre, novembre, dÃ©cembre]
-    abbr_month_names: [~, jan., fÃ©v., mar., avr., mai, juin, juil., aoÃ»t, sept., oct., nov., dÃ©c.]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%d/%m/%Y %H:%M"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%A %d %B %Y %H:%M:%S %Z"
-      long_ordinal: "%A %d %B %Y %H:%M:%S %Z"
-      only_second: "%S"
-    am: 'am'
-    pm: 'pm'
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "30 secondes"
-      less_than_x_seconds:
-        zero:  "moins d'une seconde"
-        one:   "moins d'uneÂ seconde"
-        other: "moins de %{count}Â secondes"
-      x_seconds:
-        one:   "1Â seconde"
-        other: "%{count}Â secondes"
-      less_than_x_minutes:
-        zero:  "moins d'une minute"
-        one:   "moins d'uneÂ minute"
-        other: "moins de %{count}Â minutes"
-      x_minutes:
-        one:   "1Â minute"
-        other: "%{count}Â minutes"
-      about_x_hours:
-        one:   "environ une heure"
-        other: "environ %{count}Â heures"
-      x_days:
-        one:   "unÂ jour"
-        other: "%{count}Â jours"
-      about_x_months:
-        one:   "environ un mois"
-        other: "environ %{count}Â mois"
-      x_months:
-        one:   "unÂ mois"
-        other: "%{count}Â mois"
-      about_x_years:
-        one:   "environ un an"
-        other: "environ %{count}Â ans"
-      over_x_years:
-        one:   "plus d'un an"
-        other: "plus de %{count}Â ans"
-      almost_x_years:
-        one:   "presqu'un an"
-        other: "presque %{count} ans"
-    prompts:
-      year:   "AnnÃ©e"
-      month:  "Mois"
-      day:    "Jour"
-      hour:   "Heure"
-      minute: "Minute"
-      second: "Seconde"
-
-  number:
-    format:
-      precision: 3
-      separator: ','
-      delimiter: 'Â '
-    currency:
-      format:
-        unit: 'â‚¬'
-        precision: 2
-        format: '%nÂ %u'
-    human:
-      format:
-        precision: 2
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "octet"
-            other: "octet"
-          kb: "ko"
-          mb: "Mo"
-          gb: "Go"
-          tb: "To"
-
-  support:
-    array:
-      sentence_connector: 'et'
-      skip_last_comma: true
-      word_connector: ", "
-      two_words_connector: " et "
-      last_word_connector: " et "
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one: "Impossible d'enregistrer %{model} : une erreur"
-          other: "Impossible d'enregistrer %{model} : %{count} erreurs."
-        body: "Veuillez vÃ©rifier les champs suivantsÂ :"
-      messages:
-        inclusion: "n'est pas inclus(e) dans la liste"
-        exclusion: "n'est pas disponible"
-        invalid: "n'est pas valide"
-        confirmation: "ne concorde pas avec la confirmation"
-        accepted: "doit Ãªtre acceptÃ©(e)"
-        empty: "doit Ãªtre renseignÃ©(e)"
-        blank: "doit Ãªtre renseignÃ©(e)"
-        too_long: "est trop long (pas plus de %{count} caractÃ¨res)"
-        too_short: "est trop court (au moins %{count} caractÃ¨res)"
-        wrong_length: "ne fait pas la bonne longueur (doit comporter %{count} caractÃ¨res)"
-        taken: "est dÃ©jÃ  utilisÃ©"
-        not_a_number: "n'est pas un nombre"
-        not_a_date: "n'est pas une date valide"
-        greater_than: "doit Ãªtre supÃ©rieur Ã  %{count}"
-        greater_than_or_equal_to: "doit Ãªtre supÃ©rieur ou Ã©gal Ã  %{count}"
-        equal_to: "doit Ãªtre Ã©gal Ã  %{count}"
-        less_than: "doit Ãªtre infÃ©rieur Ã  %{count}"
-        less_than_or_equal_to: "doit Ãªtre infÃ©rieur ou Ã©gal Ã  %{count}"
-        odd: "doit Ãªtre impair"
-        even: "doit Ãªtre pair"
-        greater_than_start_date: "doit Ãªtre postÃ©rieure Ã  la date de dÃ©but"
-        not_same_project: "n'appartient pas au mÃªme projet"
-        circular_dependency: "Cette relation crÃ©erait une dÃ©pendance circulaire"
-        cant_link_an_issue_with_a_descendant: "Une demande ne peut pas Ãªtre liÃ©e Ã  l'une de ses sous-tÃ¢ches"
-
-  actionview_instancetag_blank_option: Choisir
-
-  general_text_No: 'Non'
-  general_text_Yes: 'Oui'
-  general_text_no: 'non'
-  general_text_yes: 'oui'
-  general_lang_name: 'FranÃ§ais'
-  general_csv_separator: ';'
-  general_csv_decimal_separator: ','
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: Le compte a Ã©tÃ© mis Ã  jour avec succÃ¨s.
-  notice_account_invalid_creditentials: Identifiant ou mot de passe invalide.
-  notice_account_password_updated: Mot de passe mis Ã  jour avec succÃ¨s.
-  notice_account_wrong_password: Mot de passe incorrect
-  notice_account_register_done: Un message contenant les instructions pour activer votre compte vous a Ã©tÃ© envoyÃ©.
-  notice_account_unknown_email: Aucun compte ne correspond Ã  cette adresse.
-  notice_can_t_change_password: Ce compte utilise une authentification externe. Impossible de changer le mot de passe.
-  notice_account_lost_email_sent: Un message contenant les instructions pour choisir un nouveau mot de passe vous a Ã©tÃ© envoyÃ©.
-  notice_account_activated: Votre compte a Ã©tÃ© activÃ©. Vous pouvez Ã  prÃ©sent vous connecter.
-  notice_successful_create: CrÃ©ation effectuÃ©e avec succÃ¨s.
-  notice_successful_update: Mise Ã  jour effectuÃ©e avec succÃ¨s.
-  notice_successful_delete: Suppression effectuÃ©e avec succÃ¨s.
-  notice_successful_connection: Connexion rÃ©ussie.
-  notice_file_not_found: "La page Ã  laquelle vous souhaitez accÃ©der n'existe pas ou a Ã©tÃ© supprimÃ©e."
-  notice_locking_conflict: Les donnÃ©es ont Ã©tÃ© mises Ã  jour par un autre utilisateur. Mise Ã  jour impossible.
-  notice_not_authorized: "Vous n'Ãªtes pas autorisÃ© Ã  accÃ©der Ã  cette page."
-  notice_not_authorized_archived_project: Le projet auquel vous tentez d'accÃ©der a Ã©tÃ© archivÃ©.
-  notice_email_sent: "Un email a Ã©tÃ© envoyÃ© Ã  %{value}"
-  notice_email_error: "Erreur lors de l'envoi de l'email (%{value})"
-  notice_feeds_access_key_reseted: "Votre clÃ© d'accÃ¨s aux flux RSS a Ã©tÃ© rÃ©initialisÃ©e."
-  notice_failed_to_save_issues: "%{count} demande(s) sur les %{total} sÃ©lectionnÃ©es n'ont pas pu Ãªtre mise(s) Ã  jour : %{ids}."
-  notice_no_issue_selected: "Aucune demande sÃ©lectionnÃ©e ! Cochez les demandes que vous voulez mettre Ã  jour."
-  notice_account_pending: "Votre compte a Ã©tÃ© crÃ©Ã© et attend l'approbation de l'administrateur."
-  notice_default_data_loaded: ParamÃ©trage par dÃ©faut chargÃ© avec succÃ¨s.
-  notice_unable_delete_version: Impossible de supprimer cette version.
-  notice_issue_done_ratios_updated: L'avancement des demandes a Ã©tÃ© mis Ã  jour.
-  notice_api_access_key_reseted: Votre clÃ© d'accÃ¨s API a Ã©tÃ© rÃ©initialisÃ©e.
-  notice_gantt_chart_truncated: "Le diagramme a Ã©tÃ© tronquÃ© car il excÃ¨de le nombre maximal d'Ã©lÃ©ments pouvant Ãªtre affichÃ©s (%{max})"
-  notice_issue_successful_create: "La demande %{id} a Ã©tÃ© crÃ©Ã©e."
-
-  error_can_t_load_default_data: "Une erreur s'est produite lors du chargement du paramÃ©trage : %{value}"
-  error_scm_not_found: "L'entrÃ©e et/ou la rÃ©vision demandÃ©e n'existe pas dans le dÃ©pÃ´t."
-  error_scm_command_failed: "Une erreur s'est produite lors de l'accÃ¨s au dÃ©pÃ´t : %{value}"
-  error_scm_annotate: "L'entrÃ©e n'existe pas ou ne peut pas Ãªtre annotÃ©e."
-  error_issue_not_found_in_project: "La demande n'existe pas ou n'appartient pas Ã  ce projet"
-  error_can_not_reopen_issue_on_closed_version: 'Une demande assignÃ©e Ã  une version fermÃ©e ne peut pas Ãªtre rÃ©ouverte'
-  error_can_not_archive_project: "Ce projet ne peut pas Ãªtre archivÃ©"
-  error_workflow_copy_source: 'Veuillez sÃ©lectionner un tracker et/ou un rÃ´le source'
-  error_workflow_copy_target: 'Veuillez sÃ©lectionner les trackers et rÃ´les cibles'
-  error_issue_done_ratios_not_updated: L'avancement des demandes n'a pas pu Ãªtre mis Ã  jour.
-  error_attachment_too_big: Ce fichier ne peut pas Ãªtre attachÃ© car il excÃ¨de la taille maximale autorisÃ©e (%{max_size})
-
-  warning_attachments_not_saved: "%{count} fichier(s) n'ont pas pu Ãªtre sauvegardÃ©s."
-
-  mail_subject_lost_password: "Votre mot de passe %{value}"
-  mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :'
-  mail_subject_register: "Activation de votre compte %{value}"
-  mail_body_register: 'Pour activer votre compte, cliquez sur le lien suivant :'
-  mail_body_account_information_external: "Vous pouvez utiliser votre compte %{value} pour vous connecter."
-  mail_body_account_information: ParamÃ¨tres de connexion de votre compte
-  mail_subject_account_activation_request: "Demande d'activation d'un compte %{value}"
-  mail_body_account_activation_request: "Un nouvel utilisateur (%{value}) s'est inscrit. Son compte nÃ©cessite votre approbation :"
-  mail_subject_reminder: "%{count} demande(s) arrivent Ã  Ã©chÃ©ance (%{days})"
-  mail_body_reminder: "%{count} demande(s) qui vous sont assignÃ©es arrivent Ã  Ã©chÃ©ance dans les %{days} prochains jours :"
-  mail_subject_wiki_content_added: "Page wiki '%{id}' ajoutÃ©e"
-  mail_body_wiki_content_added: "La page wiki '%{id}' a Ã©tÃ© ajoutÃ©e par %{author}."
-  mail_subject_wiki_content_updated: "Page wiki '%{id}' mise Ã  jour"
-  mail_body_wiki_content_updated: "La page wiki '%{id}' a Ã©tÃ© mise Ã  jour par %{author}."
-
-  gui_validation_error: 1 erreur
-  gui_validation_error_plural: "%{count} erreurs"
-
-  field_name: Nom
-  field_description: Description
-  field_summary: RÃ©sumÃ©
-  field_is_required: Obligatoire
-  field_firstname: PrÃ©nom
-  field_lastname: Nom
-  field_mail: "Email "
-  field_filename: Fichier
-  field_filesize: Taille
-  field_downloads: TÃ©lÃ©chargements
-  field_author: Auteur
-  field_created_on: "CrÃ©Ã© "
-  field_updated_on: "Mis-Ã -jour "
-  field_field_format: Format
-  field_is_for_all: Pour tous les projets
-  field_possible_values: Valeurs possibles
-  field_regexp: Expression rÃ©guliÃ¨re
-  field_min_length: Longueur minimum
-  field_max_length: Longueur maximum
-  field_value: Valeur
-  field_category: CatÃ©gorie
-  field_title: Titre
-  field_project: Projet
-  field_issue: Demande
-  field_status: Statut
-  field_notes: Notes
-  field_is_closed: Demande fermÃ©e
-  field_is_default: Valeur par dÃ©faut
-  field_tracker: Tracker
-  field_subject: Sujet
-  field_due_date: EchÃ©ance
-  field_assigned_to: AssignÃ© Ã 
-  field_priority: PrioritÃ©
-  field_fixed_version: Version cible
-  field_user: Utilisateur
-  field_role: RÃ´le
-  field_homepage: "Site web "
-  field_is_public: Public
-  field_parent: Sous-projet de
-  field_is_in_roadmap: Demandes affichÃ©es dans la roadmap
-  field_login: "Identifiant "
-  field_mail_notification: Notifications par mail
-  field_admin: Administrateur
-  field_last_login_on: "DerniÃ¨re connexion "
-  field_language: Langue
-  field_effective_date: Date
-  field_password: Mot de passe
-  field_new_password: Nouveau mot de passe
-  field_password_confirmation: Confirmation
-  field_version: Version
-  field_type: Type
-  field_host: HÃ´te
-  field_port: Port
-  field_account: Compte
-  field_base_dn: Base DN
-  field_attr_login: Attribut Identifiant
-  field_attr_firstname: Attribut PrÃ©nom
-  field_attr_lastname: Attribut Nom
-  field_attr_mail: Attribut Email
-  field_onthefly: CrÃ©ation des utilisateurs Ã  la volÃ©e
-  field_start_date: DÃ©but
-  field_done_ratio: "% rÃ©alisÃ©"
-  field_auth_source: Mode d'authentification
-  field_hide_mail: Cacher mon adresse mail
-  field_comments: Commentaire
-  field_url: URL
-  field_start_page: Page de dÃ©marrage
-  field_subproject: Sous-projet
-  field_hours: Heures
-  field_activity: ActivitÃ©
-  field_spent_on: Date
-  field_identifier: Identifiant
-  field_is_filter: UtilisÃ© comme filtre
-  field_issue_to: Demande liÃ©e
-  field_delay: Retard
-  field_assignable: Demandes assignables Ã  ce rÃ´le
-  field_redirect_existing_links: Rediriger les liens existants
-  field_estimated_hours: Temps estimÃ©
-  field_column_names: Colonnes
-  field_time_zone: Fuseau horaire
-  field_searchable: UtilisÃ© pour les recherches
-  field_default_value: Valeur par dÃ©faut
-  field_comments_sorting: Afficher les commentaires
-  field_parent_title: Page parent
-  field_editable: Modifiable
-  field_watcher: Observateur
-  field_identity_url: URL OpenID
-  field_content: Contenu
-  field_group_by: Grouper par
-  field_sharing: Partage
-  field_active: Actif
-  field_parent_issue: TÃ¢che parente
-  field_visible: Visible
-  field_warn_on_leaving_unsaved: "M'avertir lorsque je quitte une page contenant du texte non sauvegardÃ©"
-  field_issues_visibility: VisibilitÃ© des demandes
-  field_is_private: PrivÃ©e
-  field_commit_logs_encoding: Encodage des messages de commit
-
-  setting_app_title: Titre de l'application
-  setting_app_subtitle: Sous-titre de l'application
-  setting_welcome_text: Texte d'accueil
-  setting_default_language: Langue par dÃ©faut
-  setting_login_required: Authentification obligatoire
-  setting_self_registration: Inscription des nouveaux utilisateurs
-  setting_attachment_max_size: Taille maximale des fichiers
-  setting_issues_export_limit: Limite d'exportation des demandes
-  setting_mail_from: Adresse d'Ã©mission
-  setting_bcc_recipients: Destinataires en copie cachÃ©e (cci)
-  setting_plain_text_mail: Mail en texte brut (non HTML)
-  setting_host_name: Nom d'hÃ´te et chemin
-  setting_text_formatting: Formatage du texte
-  setting_wiki_compression: Compression de l'historique des pages wiki
-  setting_feeds_limit: Nombre maximal d'Ã©lÃ©ments dans les flux Atom
-  setting_default_projects_public: DÃ©finir les nouveaux projets comme publics par dÃ©faut
-  setting_autofetch_changesets: RÃ©cupÃ©ration automatique des commits
-  setting_sys_api_enabled: Activer les WS pour la gestion des dÃ©pÃ´ts
-  setting_commit_ref_keywords: Mots-clÃ©s de rÃ©fÃ©rencement
-  setting_commit_fix_keywords: Mots-clÃ©s de rÃ©solution
-  setting_autologin: DurÃ©e maximale de connexion automatique
-  setting_date_format: Format de date
-  setting_time_format: Format d'heure
-  setting_cross_project_issue_relations: Autoriser les relations entre demandes de diffÃ©rents projets
-  setting_issue_list_default_columns: Colonnes affichÃ©es par dÃ©faut sur la liste des demandes
-  setting_emails_footer: Pied-de-page des emails
-  setting_protocol: Protocole
-  setting_per_page_options: Options d'objets affichÃ©s par page
-  setting_user_format: Format d'affichage des utilisateurs
-  setting_activity_days_default: Nombre de jours affichÃ©s sur l'activitÃ© des projets
-  setting_display_subprojects_issues: Afficher par dÃ©faut les demandes des sous-projets sur les projets principaux
-  setting_enabled_scm: SCM activÃ©s
-  setting_mail_handler_body_delimiters: "Tronquer les emails aprÃ¨s l'une de ces lignes"
-  setting_mail_handler_api_enabled: "Activer le WS pour la rÃ©ception d'emails"
-  setting_mail_handler_api_key: ClÃ© de protection de l'API
-  setting_sequential_project_identifiers: GÃ©nÃ©rer des identifiants de projet sÃ©quentiels
-  setting_gravatar_enabled: Afficher les Gravatar des utilisateurs
-  setting_diff_max_lines_displayed: Nombre maximum de lignes de diff affichÃ©es
-  setting_file_max_size_displayed: Taille maximum des fichiers texte affichÃ©s en ligne
-  setting_repository_log_display_limit: "Nombre maximum de rÃ©visions affichÃ©es sur l'historique d'un fichier"
-  setting_openid: "Autoriser l'authentification et l'enregistrement OpenID"
-  setting_password_min_length: Longueur minimum des mots de passe
-  setting_new_project_user_role_id: RÃ´le donnÃ© Ã  un utilisateur non-administrateur qui crÃ©e un projet
-  setting_default_projects_modules: Modules activÃ©s par dÃ©faut pour les nouveaux projets
-  setting_issue_done_ratio: Calcul de l'avancement des demandes
-  setting_issue_done_ratio_issue_status: Utiliser le statut
-  setting_issue_done_ratio_issue_field: 'Utiliser le champ % effectuÃ©'
-  setting_rest_api_enabled: Activer l'API REST
-  setting_gravatar_default: Image Gravatar par dÃ©faut
-  setting_start_of_week: Jour de dÃ©but des calendriers
-  setting_cache_formatted_text: Mettre en cache le texte formatÃ©
-  setting_commit_logtime_enabled: Permettre la saisie de temps
-  setting_commit_logtime_activity_id: ActivitÃ© pour le temps saisi
-  setting_gantt_items_limit: Nombre maximum d'Ã©lÃ©ments affichÃ©s sur le gantt
-  setting_issue_group_assignment: Permettre l'assignement des demandes aux groupes
-  setting_default_issue_start_date_to_creation_date: Donner Ã  la date de dÃ©but d'une nouvelle demande la valeur de la date du jour
-
-  permission_add_project: CrÃ©er un projet
-  permission_add_subprojects: CrÃ©er des sous-projets
-  permission_edit_project: Modifier le projet
-  permission_select_project_modules: Choisir les modules
-  permission_manage_members: GÃ©rer les membres
-  permission_manage_versions: GÃ©rer les versions
-  permission_manage_categories: GÃ©rer les catÃ©gories de demandes
-  permission_view_issues: Voir les demandes
-  permission_add_issues: CrÃ©er des demandes
-  permission_edit_issues: Modifier les demandes
-  permission_manage_issue_relations: GÃ©rer les relations
-  permission_set_issues_private: Rendre les demandes publiques ou privÃ©es
-  permission_set_own_issues_private: Rendre ses propres demandes publiques ou privÃ©es
-  permission_add_issue_notes: Ajouter des notes
-  permission_edit_issue_notes: Modifier les notes
-  permission_edit_own_issue_notes: Modifier ses propres notes
-  permission_move_issues: DÃ©placer les demandes
-  permission_delete_issues: Supprimer les demandes
-  permission_manage_public_queries: GÃ©rer les requÃªtes publiques
-  permission_save_queries: Sauvegarder les requÃªtes
-  permission_view_gantt: Voir le gantt
-  permission_view_calendar: Voir le calendrier
-  permission_view_issue_watchers: Voir la liste des observateurs
-  permission_add_issue_watchers: Ajouter des observateurs
-  permission_delete_issue_watchers: Supprimer des observateurs
-  permission_log_time: Saisir le temps passÃ©
-  permission_view_time_entries: Voir le temps passÃ©
-  permission_edit_time_entries: Modifier les temps passÃ©s
-  permission_edit_own_time_entries: Modifier son propre temps passÃ©
-  permission_manage_news: GÃ©rer les annonces
-  permission_comment_news: Commenter les annonces
-  permission_manage_documents: GÃ©rer les documents
-  permission_view_documents: Voir les documents
-  permission_manage_files: GÃ©rer les fichiers
-  permission_view_files: Voir les fichiers
-  permission_manage_wiki: GÃ©rer le wiki
-  permission_rename_wiki_pages: Renommer les pages
-  permission_delete_wiki_pages: Supprimer les pages
-  permission_view_wiki_pages: Voir le wiki
-  permission_view_wiki_edits: "Voir l'historique des modifications"
-  permission_edit_wiki_pages: Modifier les pages
-  permission_delete_wiki_pages_attachments: Supprimer les fichiers joints
-  permission_protect_wiki_pages: ProtÃ©ger les pages
-  permission_manage_repository: GÃ©rer le dÃ©pÃ´t de sources
-  permission_browse_repository: Parcourir les sources
-  permission_view_changesets: Voir les rÃ©visions
-  permission_commit_access: Droit de commit
-  permission_manage_boards: GÃ©rer les forums
-  permission_view_messages: Voir les messages
-  permission_add_messages: Poster un message
-  permission_edit_messages: Modifier les messages
-  permission_edit_own_messages: Modifier ses propres messages
-  permission_delete_messages: Supprimer les messages
-  permission_delete_own_messages: Supprimer ses propres messages
-  permission_export_wiki_pages: Exporter les pages
-  permission_manage_project_activities: GÃ©rer les activitÃ©s
-  permission_manage_subtasks: GÃ©rer les sous-tÃ¢ches
-
-  project_module_issue_tracking: Suivi des demandes
-  project_module_time_tracking: Suivi du temps passÃ©
-  project_module_news: Publication d'annonces
-  project_module_documents: Publication de documents
-  project_module_files: Publication de fichiers
-  project_module_wiki: Wiki
-  project_module_repository: DÃ©pÃ´t de sources
-  project_module_boards: Forums de discussion
-
-  label_user: Utilisateur
-  label_user_plural: Utilisateurs
-  label_user_new: Nouvel utilisateur
-  label_user_anonymous: Anonyme
-  label_project: Projet
-  label_project_new: Nouveau projet
-  label_project_plural: Projets
-  label_x_projects:
-    zero:  aucun projet
-    one:   un projet
-    other: "%{count} projets"
-  label_project_all: Tous les projets
-  label_project_latest: Derniers projets
-  label_issue: Demande
-  label_issue_new: Nouvelle demande
-  label_issue_plural: Demandes
-  label_issue_view_all: Voir toutes les demandes
-  label_issue_added: Demande ajoutÃ©e
-  label_issue_updated: Demande mise Ã  jour
-  label_issue_note_added: Note ajoutÃ©e
-  label_issue_status_updated: Statut changÃ©
-  label_issue_priority_updated: PrioritÃ© changÃ©e
-  label_issues_by: "Demandes par %{value}"
-  label_document: Document
-  label_document_new: Nouveau document
-  label_document_plural: Documents
-  label_document_added: Document ajoutÃ©
-  label_role: RÃ´le
-  label_role_plural: RÃ´les
-  label_role_new: Nouveau rÃ´le
-  label_role_and_permissions: RÃ´les et permissions
-  label_role_anonymous: Anonyme
-  label_role_non_member: Non membre
-  label_member: Membre
-  label_member_new: Nouveau membre
-  label_member_plural: Membres
-  label_tracker: Tracker
-  label_tracker_plural: Trackers
-  label_tracker_new: Nouveau tracker
-  label_workflow: Workflow
-  label_issue_status: Statut de demandes
-  label_issue_status_plural: Statuts de demandes
-  label_issue_status_new: Nouveau statut
-  label_issue_category: CatÃ©gorie de demandes
-  label_issue_category_plural: CatÃ©gories de demandes
-  label_issue_category_new: Nouvelle catÃ©gorie
-  label_custom_field: Champ personnalisÃ©
-  label_custom_field_plural: Champs personnalisÃ©s
-  label_custom_field_new: Nouveau champ personnalisÃ©
-  label_enumerations: Listes de valeurs
-  label_enumeration_new: Nouvelle valeur
-  label_information: Information
-  label_information_plural: Informations
-  label_please_login: Identification
-  label_register: S'enregistrer
-  label_login_with_open_id_option: S'authentifier avec OpenID
-  label_password_lost: Mot de passe perdu
-  label_home: Accueil
-  label_my_page: Ma page
-  label_my_account: Mon compte
-  label_my_projects: Mes projets
-  label_my_page_block: Blocs disponibles
-  label_administration: Administration
-  label_login: Connexion
-  label_logout: DÃ©connexion
-  label_help: Aide
-  label_reported_issues: "Demandes soumises "
-  label_assigned_to_me_issues: Demandes qui me sont assignÃ©es
-  label_last_login: "DerniÃ¨re connexion "
-  label_registered_on: "Inscrit le "
-  label_activity: ActivitÃ©
-  label_overall_activity: ActivitÃ© globale
-  label_user_activity: "ActivitÃ© de %{value}"
-  label_new: Nouveau
-  label_logged_as: ConnectÃ© en tant que
-  label_environment: Environnement
-  label_authentication: Authentification
-  label_auth_source: Mode d'authentification
-  label_auth_source_new: Nouveau mode d'authentification
-  label_auth_source_plural: Modes d'authentification
-  label_subproject_plural: Sous-projets
-  label_subproject_new: Nouveau sous-projet
-  label_and_its_subprojects: "%{value} et ses sous-projets"
-  label_min_max_length: Longueurs mini - maxi
-  label_list: Liste
-  label_date: Date
-  label_integer: Entier
-  label_float: Nombre dÃ©cimal
-  label_boolean: BoolÃ©en
-  label_string: Texte
-  label_text: Texte long
-  label_attribute: Attribut
-  label_attribute_plural: Attributs
-  label_download: "%{count} tÃ©lÃ©chargement"
-  label_download_plural: "%{count} tÃ©lÃ©chargements"
-  label_no_data: Aucune donnÃ©e Ã  afficher
-  label_change_status: Changer le statut
-  label_history: Historique
-  label_attachment: Fichier
-  label_attachment_new: Nouveau fichier
-  label_attachment_delete: Supprimer le fichier
-  label_attachment_plural: Fichiers
-  label_file_added: Fichier ajoutÃ©
-  label_report: Rapport
-  label_report_plural: Rapports
-  label_news: Annonce
-  label_news_new: Nouvelle annonce
-  label_news_plural: Annonces
-  label_news_latest: DerniÃ¨res annonces
-  label_news_view_all: Voir toutes les annonces
-  label_news_added: Annonce ajoutÃ©e
-  label_news_comment_added: Commentaire ajoutÃ© Ã  une annonce
-  label_settings: Configuration
-  label_overview: AperÃ§u
-  label_version: Version
-  label_version_new: Nouvelle version
-  label_version_plural: Versions
-  label_confirmation: Confirmation
-  label_export_to: 'Formats disponibles :'
-  label_read: Lire...
-  label_public_projects: Projets publics
-  label_open_issues: ouvert
-  label_open_issues_plural: ouverts
-  label_closed_issues: fermÃ©
-  label_closed_issues_plural: fermÃ©s
-  label_x_open_issues_abbr_on_total:
-    zero:  0 ouvert sur %{total}
-    one:   1 ouvert sur %{total}
-    other: "%{count} ouverts sur %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 ouvert
-    one:   1 ouvert
-    other: "%{count} ouverts"
-  label_x_closed_issues_abbr:
-    zero:  0 fermÃ©
-    one:   1 fermÃ©
-    other: "%{count} fermÃ©s"
-  label_total: Total
-  label_permissions: Permissions
-  label_current_status: Statut actuel
-  label_new_statuses_allowed: Nouveaux statuts autorisÃ©s
-  label_all: tous
-  label_none: aucun
-  label_nobody: personne
-  label_next: Suivant
-  label_previous: PrÃ©cÃ©dent
-  label_used_by: UtilisÃ© par
-  label_details: DÃ©tails
-  label_add_note: Ajouter une note
-  label_per_page: Par page
-  label_calendar: Calendrier
-  label_months_from: mois depuis
-  label_gantt: Gantt
-  label_internal: Interne
-  label_last_changes: "%{count} derniers changements"
-  label_change_view_all: Voir tous les changements
-  label_personalize_page: Personnaliser cette page
-  label_comment: Commentaire
-  label_comment_plural: Commentaires
-  label_x_comments:
-    zero: aucun commentaire
-    one: un commentaire
-    other: "%{count} commentaires"
-  label_comment_add: Ajouter un commentaire
-  label_comment_added: Commentaire ajoutÃ©
-  label_comment_delete: Supprimer les commentaires
-  label_query: Rapport personnalisÃ©
-  label_query_plural: Rapports personnalisÃ©s
-  label_query_new: Nouveau rapport
-  label_my_queries: Mes rapports personnalisÃ©s
-  label_filter_add: "Ajouter le filtre "
-  label_filter_plural: Filtres
-  label_equals: Ã©gal
-  label_not_equals: diffÃ©rent
-  label_in_less_than: dans moins de
-  label_in_more_than: dans plus de
-  label_in: dans
-  label_today: aujourd'hui
-  label_all_time: toute la pÃ©riode
-  label_yesterday: hier
-  label_this_week: cette semaine
-  label_last_week: la semaine derniÃ¨re
-  label_last_n_days: "les %{count} derniers jours"
-  label_this_month: ce mois-ci
-  label_last_month: le mois dernier
-  label_this_year: cette annÃ©e
-  label_date_range: PÃ©riode
-  label_less_than_ago: il y a moins de
-  label_more_than_ago: il y a plus de
-  label_ago: il y a
-  label_contains: contient
-  label_not_contains: ne contient pas
-  label_day_plural: jours
-  label_repository: DÃ©pÃ´t
-  label_repository_plural: DÃ©pÃ´ts
-  label_browse: Parcourir
-  label_modification: "%{count} modification"
-  label_modification_plural: "%{count} modifications"
-  label_revision: "RÃ©vision "
-  label_revision_plural: RÃ©visions
-  label_associated_revisions: RÃ©visions associÃ©es
-  label_added: ajoutÃ©
-  label_modified: modifiÃ©
-  label_copied: copiÃ©
-  label_renamed: renommÃ©
-  label_deleted: supprimÃ©
-  label_latest_revision: DerniÃ¨re rÃ©vision
-  label_latest_revision_plural: DerniÃ¨res rÃ©visions
-  label_view_revisions: Voir les rÃ©visions
-  label_max_size: Taille maximale
-  label_sort_highest: Remonter en premier
-  label_sort_higher: Remonter
-  label_sort_lower: Descendre
-  label_sort_lowest: Descendre en dernier
-  label_roadmap: Roadmap
-  label_roadmap_due_in: "Ã‰chÃ©ance dans %{value}"
-  label_roadmap_overdue: "En retard de %{value}"
-  label_roadmap_no_issues: Aucune demande pour cette version
-  label_search: "Recherche "
-  label_result_plural: RÃ©sultats
-  label_all_words: Tous les mots
-  label_wiki: Wiki
-  label_wiki_edit: RÃ©vision wiki
-  label_wiki_edit_plural: RÃ©visions wiki
-  label_wiki_page: Page wiki
-  label_wiki_page_plural: Pages wiki
-  label_index_by_title: Index par titre
-  label_index_by_date: Index par date
-  label_current_version: Version actuelle
-  label_preview: PrÃ©visualisation
-  label_feed_plural: Flux RSS
-  label_changes_details: DÃ©tails de tous les changements
-  label_issue_tracking: Suivi des demandes
-  label_spent_time: Temps passÃ©
-  label_f_hour: "%{value} heure"
-  label_f_hour_plural: "%{value} heures"
-  label_time_tracking: Suivi du temps
-  label_change_plural: Changements
-  label_statistics: Statistiques
-  label_commits_per_month: Commits par mois
-  label_commits_per_author: Commits par auteur
-  label_view_diff: Voir les diffÃ©rences
-  label_diff_inline: en ligne
-  label_diff_side_by_side: cÃ´te Ã  cÃ´te
-  label_options: Options
-  label_copy_workflow_from: Copier le workflow de
-  label_permissions_report: SynthÃ¨se des permissions
-  label_watched_issues: Demandes surveillÃ©es
-  label_related_issues: Demandes liÃ©es
-  label_applied_status: Statut appliquÃ©
-  label_loading: Chargement...
-  label_relation_new: Nouvelle relation
-  label_relation_delete: Supprimer la relation
-  label_relates_to: liÃ© Ã 
-  label_duplicates: duplique
-  label_duplicated_by: dupliquÃ© par
-  label_blocks: bloque
-  label_blocked_by: bloquÃ© par
-  label_precedes: prÃ©cÃ¨de
-  label_follows: suit
-  label_end_to_start: fin Ã  dÃ©but
-  label_end_to_end: fin Ã  fin
-  label_start_to_start: dÃ©but Ã  dÃ©but
-  label_start_to_end: dÃ©but Ã  fin
-  label_stay_logged_in: Rester connectÃ©
-  label_disabled: dÃ©sactivÃ©
-  label_show_completed_versions: Voir les versions passÃ©es
-  label_me: moi
-  label_board: Forum
-  label_board_new: Nouveau forum
-  label_board_plural: Forums
-  label_topic_plural: Discussions
-  label_message_plural: Messages
-  label_message_last: Dernier message
-  label_message_new: Nouveau message
-  label_message_posted: Message ajoutÃ©
-  label_reply_plural: RÃ©ponses
-  label_send_information: Envoyer les informations Ã  l'utilisateur
-  label_year: AnnÃ©e
-  label_month: Mois
-  label_week: Semaine
-  label_date_from: Du
-  label_date_to: Au
-  label_language_based: BasÃ© sur la langue de l'utilisateur
-  label_sort_by: "Trier par %{value}"
-  label_send_test_email: Envoyer un email de test
-  label_feeds_access_key_created_on: "ClÃ© d'accÃ¨s RSS crÃ©Ã©e il y a %{value}"
-  label_module_plural: Modules
-  label_added_time_by: "AjoutÃ© par %{author} il y a %{age}"
-  label_updated_time_by: "Mis Ã  jour par %{author} il y a %{age}"
-  label_updated_time: "Mis Ã  jour il y a %{value}"
-  label_jump_to_a_project: Aller Ã  un projet...
-  label_file_plural: Fichiers
-  label_changeset_plural: RÃ©visions
-  label_default_columns: Colonnes par dÃ©faut
-  label_no_change_option: (Pas de changement)
-  label_bulk_edit_selected_issues: Modifier les demandes sÃ©lectionnÃ©es
-  label_theme: ThÃ¨me
-  label_default: DÃ©faut
-  label_search_titles_only: Uniquement dans les titres
-  label_user_mail_option_all: "Pour tous les Ã©vÃ©nements de tous mes projets"
-  label_user_mail_option_selected: "Pour tous les Ã©vÃ©nements des projets sÃ©lectionnÃ©s..."
-  label_user_mail_no_self_notified: "Je ne veux pas Ãªtre notifiÃ© des changements que j'effectue"
-  label_registration_activation_by_email: activation du compte par email
-  label_registration_manual_activation: activation manuelle du compte
-  label_registration_automatic_activation: activation automatique du compte
-  label_display_per_page: "Par page : %{value}"
-  label_age: Ã‚ge
-  label_change_properties: Changer les propriÃ©tÃ©s
-  label_general: GÃ©nÃ©ral
-  label_more: Plus
-  label_scm: SCM
-  label_plugins: Plugins
-  label_ldap_authentication: Authentification LDAP
-  label_downloads_abbr: D/L
-  label_optional_description: Description facultative
-  label_add_another_file: Ajouter un autre fichier
-  label_preferences: PrÃ©fÃ©rences
-  label_chronological_order: Dans l'ordre chronologique
-  label_reverse_chronological_order: Dans l'ordre chronologique inverse
-  label_planning: Planning
-  label_incoming_emails: Emails entrants
-  label_generate_key: GÃ©nÃ©rer une clÃ©
-  label_issue_watchers: Observateurs
-  label_example: Exemple
-  label_display: Affichage
-  label_sort: Tri
-  label_ascending: Croissant
-  label_descending: DÃ©croissant
-  label_date_from_to: Du %{start} au %{end}
-  label_wiki_content_added: Page wiki ajoutÃ©e
-  label_wiki_content_updated: Page wiki mise Ã  jour
-  label_group_plural: Groupes
-  label_group: Groupe
-  label_group_new: Nouveau groupe
-  label_time_entry_plural: Temps passÃ©
-  label_version_sharing_none: Non partagÃ©
-  label_version_sharing_descendants: Avec les sous-projets
-  label_version_sharing_hierarchy: Avec toute la hiÃ©rarchie
-  label_version_sharing_tree: Avec tout l'arbre
-  label_version_sharing_system: Avec tous les projets
-  label_copy_source: Source
-  label_copy_target: Cible
-  label_copy_same_as_target: Comme la cible
-  label_update_issue_done_ratios: Mettre Ã  jour l'avancement des demandes
-  label_display_used_statuses_only: N'afficher que les statuts utilisÃ©s dans ce tracker
-  label_api_access_key: ClÃ© d'accÃ¨s API
-  label_api_access_key_created_on: ClÃ© d'accÃ¨s API crÃ©Ã©e il y a %{value}
-  label_feeds_access_key: ClÃ© d'accÃ¨s RSS
-  label_missing_api_access_key: ClÃ© d'accÃ¨s API manquante
-  label_missing_feeds_access_key: ClÃ© d'accÃ¨s RSS manquante
-  label_close_versions: Fermer les versions terminÃ©es
-  label_revision_id: Revision %{value}
-  label_profile: Profil
-  label_subtask_plural: Sous-tÃ¢ches
-  label_project_copy_notifications: Envoyer les notifications durant la copie du projet
-  label_principal_search: "Rechercher un utilisateur ou un groupe :"
-  label_user_search: "Rechercher un utilisateur :"
-  label_additional_workflow_transitions_for_author: Autorisations supplÃ©mentaires lorsque l'utilisateur a crÃ©Ã© la demande
-  label_additional_workflow_transitions_for_assignee: Autorisations supplÃ©mentaires lorsque la demande est assignÃ©e Ã  l'utilisateur
-  label_issues_visibility_all: Toutes les demandes
-  label_issues_visibility_public: Toutes les demandes non privÃ©es
-  label_issues_visibility_own: Demandes crÃ©Ã©es par ou assignÃ©es Ã  l'utilisateur
-  label_export_options: Options d'exportation %{export_format}
-
-  button_login: Connexion
-  button_submit: Soumettre
-  button_save: Sauvegarder
-  button_check_all: Tout cocher
-  button_uncheck_all: Tout dÃ©cocher
-  button_collapse_all: Plier tout
-  button_expand_all: DÃ©plier tout
-  button_delete: Supprimer
-  button_create: CrÃ©er
-  button_create_and_continue: CrÃ©er et continuer
-  button_test: Tester
-  button_edit: Modifier
-  button_add: Ajouter
-  button_change: Changer
-  button_apply: Appliquer
-  button_clear: Effacer
-  button_lock: Verrouiller
-  button_unlock: DÃ©verrouiller
-  button_download: TÃ©lÃ©charger
-  button_list: Lister
-  button_view: Voir
-  button_move: DÃ©placer
-  button_move_and_follow: DÃ©placer et suivre
-  button_back: Retour
-  button_cancel: Annuler
-  button_activate: Activer
-  button_sort: Trier
-  button_log_time: Saisir temps
-  button_rollback: Revenir Ã  cette version
-  button_watch: Surveiller
-  button_unwatch: Ne plus surveiller
-  button_reply: RÃ©pondre
-  button_archive: Archiver
-  button_unarchive: DÃ©sarchiver
-  button_reset: RÃ©initialiser
-  button_rename: Renommer
-  button_change_password: Changer de mot de passe
-  button_copy: Copier
-  button_copy_and_follow: Copier et suivre
-  button_annotate: Annoter
-  button_update: Mettre Ã  jour
-  button_configure: Configurer
-  button_quote: Citer
-  button_duplicate: Dupliquer
-  button_show: Afficher
-  button_edit_section: Modifier cette section
-  button_export: Exporter
-
-  status_active: actif
-  status_registered: enregistrÃ©
-  status_locked: verrouillÃ©
-
-  version_status_open: ouvert
-  version_status_locked: verrouillÃ©
-  version_status_closed: fermÃ©
-
-  text_select_mail_notifications: Actions pour lesquelles une notification par e-mail est envoyÃ©e
-  text_regexp_info: ex. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 pour aucune restriction
-  text_project_destroy_confirmation: ÃŠtes-vous sÃ»r de vouloir supprimer ce projet et toutes ses donnÃ©es ?
-  text_subprojects_destroy_warning: "Ses sous-projets : %{value} seront Ã©galement supprimÃ©s."
-  text_workflow_edit: SÃ©lectionner un tracker et un rÃ´le pour Ã©diter le workflow
-  text_are_you_sure: ÃŠtes-vous sÃ»r ?
-  text_tip_issue_begin_day: tÃ¢che commenÃ§ant ce jour
-  text_tip_issue_end_day: tÃ¢che finissant ce jour
-  text_tip_issue_begin_end_day: tÃ¢che commenÃ§ant et finissant ce jour
-  text_project_identifier_info: 'Seuls les lettres minuscules (a-z), chiffres et tirets sont autorisÃ©s.<br />Un fois sauvegardÃ©, l''identifiant ne pourra plus Ãªtre modifiÃ©.'
-  text_caracters_maximum: "%{count} caractÃ¨res maximum."
-  text_caracters_minimum: "%{count} caractÃ¨res minimum."
-  text_length_between: "Longueur comprise entre %{min} et %{max} caractÃ¨res."
-  text_tracker_no_workflow: Aucun worflow n'est dÃ©fini pour ce tracker
-  text_unallowed_characters: CaractÃ¨res non autorisÃ©s
-  text_comma_separated: Plusieurs valeurs possibles (sÃ©parÃ©es par des virgules).
-  text_line_separated: Plusieurs valeurs possibles (une valeur par ligne).
-  text_issues_ref_in_commit_messages: RÃ©fÃ©rencement et rÃ©solution des demandes dans les commentaires de commits
-  text_issue_added: "La demande %{id} a Ã©tÃ© soumise par %{author}."
-  text_issue_updated: "La demande %{id} a Ã©tÃ© mise Ã  jour par %{author}."
-  text_wiki_destroy_confirmation: Etes-vous sÃ»r de vouloir supprimer ce wiki et tout son contenu ?
-  text_issue_category_destroy_question: "%{count} demandes sont affectÃ©es Ã  cette catÃ©gorie. Que voulez-vous faire ?"
-  text_issue_category_destroy_assignments: N'affecter les demandes Ã  aucune autre catÃ©gorie
-  text_issue_category_reassign_to: RÃ©affecter les demandes Ã  cette catÃ©gorie
-  text_user_mail_option: "Pour les projets non sÃ©lectionnÃ©s, vous recevrez seulement des notifications pour ce que vous surveillez ou Ã  quoi vous participez (exemple: demandes dont vous Ãªtes l'auteur ou la personne assignÃ©e)."
-  text_no_configuration_data: "Les rÃ´les, trackers, statuts et le workflow ne sont pas encore paramÃ©trÃ©s.\nIl est vivement recommandÃ© de charger le paramÃ©trage par defaut. Vous pourrez le modifier une fois chargÃ©."
-  text_load_default_configuration: Charger le paramÃ©trage par dÃ©faut
-  text_status_changed_by_changeset: "AppliquÃ© par commit %{value}."
-  text_time_logged_by_changeset: "AppliquÃ© par commit %{value}"
-  text_issues_destroy_confirmation: 'ÃŠtes-vous sÃ»r de vouloir supprimer la ou les demandes(s) selectionnÃ©e(s) ?'
-  text_issues_destroy_descendants_confirmation: "Cela entrainera Ã©galement la suppression de %{count} sous-tÃ¢che(s)."
-  text_select_project_modules: 'SÃ©lectionner les modules Ã  activer pour ce projet :'
-  text_default_administrator_account_changed: Compte administrateur par dÃ©faut changÃ©
-  text_file_repository_writable: RÃ©pertoire de stockage des fichiers accessible en Ã©criture
-  text_plugin_assets_writable: RÃ©pertoire public des plugins accessible en Ã©criture
-  text_rmagick_available: BibliothÃ¨que RMagick prÃ©sente (optionnelle)
-  text_destroy_time_entries_question: "%{hours} heures ont Ã©tÃ© enregistrÃ©es sur les demandes Ã  supprimer. Que voulez-vous faire ?"
-  text_destroy_time_entries: Supprimer les heures
-  text_assign_time_entries_to_project: Reporter les heures sur le projet
-  text_reassign_time_entries: 'Reporter les heures sur cette demande:'
-  text_user_wrote: "%{value} a Ã©crit :"
-  text_enumeration_destroy_question: "Cette valeur est affectÃ©e Ã  %{count} objets."
-  text_enumeration_category_reassign_to: 'RÃ©affecter les objets Ã  cette valeur:'
-  text_email_delivery_not_configured: "L'envoi de mail n'est pas configurÃ©, les notifications sont dÃ©sactivÃ©es.\nConfigurez votre serveur SMTP dans config/configuration.yml et redÃ©marrez l'application pour les activer."
-  text_repository_usernames_mapping: "Vous pouvez sÃ©lectionner ou modifier l'utilisateur Redmine associÃ© Ã  chaque nom d'utilisateur figurant dans l'historique du dÃ©pÃ´t.\nLes utilisateurs avec le mÃªme identifiant ou la mÃªme adresse mail seront automatiquement associÃ©s."
-  text_diff_truncated: '... Ce diffÃ©rentiel a Ã©tÃ© tronquÃ© car il excÃ¨de la taille maximale pouvant Ãªtre affichÃ©e.'
-  text_custom_field_possible_values_info: 'Une ligne par valeur'
-  text_wiki_page_destroy_question: "Cette page possÃ¨de %{descendants} sous-page(s) et descendante(s). Que voulez-vous faire ?"
-  text_wiki_page_nullify_children: "Conserver les sous-pages en tant que pages racines"
-  text_wiki_page_destroy_children: "Supprimer les sous-pages et toutes leurs descedantes"
-  text_wiki_page_reassign_children: "RÃ©affecter les sous-pages Ã  cette page"
-  text_own_membership_delete_confirmation: "Vous allez supprimer tout ou partie de vos permissions sur ce projet et ne serez peut-Ãªtre plus autorisÃ© Ã  modifier ce projet.\nEtes-vous sÃ»r de vouloir continuer ?"
-  text_warn_on_leaving_unsaved: "Cette page contient du texte non sauvegardÃ© qui sera perdu si vous quittez la page."
-
-  default_role_manager: "Manager "
-  default_role_developer: "DÃ©veloppeur "
-  default_role_reporter: "Rapporteur "
-  default_tracker_bug: Anomalie
-  default_tracker_feature: Evolution
-  default_tracker_support: Assistance
-  default_issue_status_new: Nouveau
-  default_issue_status_in_progress: En cours
-  default_issue_status_resolved: RÃ©solu
-  default_issue_status_feedback: Commentaire
-  default_issue_status_closed: FermÃ©
-  default_issue_status_rejected: RejetÃ©
-  default_doc_category_user: Documentation utilisateur
-  default_doc_category_tech: Documentation technique
-  default_priority_low: Bas
-  default_priority_normal: Normal
-  default_priority_high: Haut
-  default_priority_urgent: Urgent
-  default_priority_immediate: ImmÃ©diat
-  default_activity_design: Conception
-  default_activity_development: DÃ©veloppement
-
-  enumeration_issue_priorities: PrioritÃ©s des demandes
-  enumeration_doc_categories: CatÃ©gories des documents
-  enumeration_activities: ActivitÃ©s (suivi du temps)
-  label_greater_or_equal: ">="
-  label_less_or_equal: "<="
-  label_between: entre
-  label_view_all_revisions: Voir toutes les rÃ©visions
-  label_tag: Tag
-  label_branch: Branche
-  error_no_tracker_in_project: "Aucun tracker n'est associÃ© Ã  ce projet. VÃ©rifier la configuration du projet."
-  error_no_default_issue_status: "Aucun statut de demande n'est dÃ©fini par dÃ©faut. VÃ©rifier votre configuration (Administration -> Statuts de demandes)."
-  text_journal_changed: "%{label} changÃ© de %{old} Ã  %{new}"
-  text_journal_changed_no_detail: "%{label} mis Ã  jour"
-  text_journal_set_to: "%{label} mis Ã  %{value}"
-  text_journal_deleted: "%{label} %{old} supprimÃ©"
-  text_journal_added: "%{label} %{value} ajoutÃ©"
-  enumeration_system_activity: ActivitÃ© systÃ¨me
-  label_board_sticky: Sticky
-  label_board_locked: VerrouillÃ©
-  error_unable_delete_issue_status: Impossible de supprimer le statut de demande
-  error_can_not_delete_custom_field: Impossible de supprimer le champ personnalisÃ©
-  error_unable_to_connect: Connexion impossible (%{value})
-  error_can_not_remove_role: Ce rÃ´le est utilisÃ© et ne peut pas Ãªtre supprimÃ©.
-  error_can_not_delete_tracker: Ce tracker contient des demandes et ne peut pas Ãªtre supprimÃ©.
-  field_principal: Principal
-  notice_failed_to_save_members: "Erreur lors de la sauvegarde des membres: %{errors}."
-  text_zoom_out: Zoom arriÃ¨re
-  text_zoom_in: Zoom avant
-  notice_unable_delete_time_entry: Impossible de supprimer le temps passÃ©.
-  label_overall_spent_time: Temps passÃ© global
-  field_time_entries: Temps passÃ©
-  project_module_gantt: Gantt
-  project_module_calendar: Calendrier
-  button_edit_associated_wikipage: "Modifier la page wiki associÃ©e: %{page_title}"
-  text_are_you_sure_with_children: Supprimer la demande et toutes ses sous-demandes ?
-  field_text: Champ texte
-  label_user_mail_option_only_owner: Seulement pour ce que j'ai crÃ©Ã©
-  setting_default_notification_option: Option de notification par dÃ©faut
-  label_user_mail_option_only_my_events: Seulement pour ce que je surveille
-  label_user_mail_option_only_assigned: Seulement pour ce qui m'est assignÃ©
-  label_user_mail_option_none: Aucune notification
-  field_member_of_group: Groupe de l'assignÃ©
-  field_assigned_to_role: RÃ´le de l'assignÃ©
-  setting_emails_header: En-tÃªte des emails
-  label_bulk_edit_selected_time_entries: Modifier les temps passÃ©s sÃ©lectionnÃ©es
-  text_time_entries_destroy_confirmation: "Etes-vous sÃ»r de vouloir supprimer les temps passÃ©s sÃ©lectionnÃ©s ?"
-  field_scm_path_encoding: Encodage des chemins
-  text_scm_path_encoding_note: "DÃ©faut : UTF-8"
-  field_path_to_repository: Chemin du dÃ©pÃ´t
-  field_root_directory: RÃ©pertoire racine
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: "DÃ©pÃ´t local (exemples : /hgrepo, c:\\hgrepo)"
-  text_scm_command: Commande
-  text_scm_command_version: Version
-  label_git_report_last_commit: Afficher le dernier commit des fichiers et rÃ©pertoires
-  text_scm_config: Vous pouvez configurer les commandes des SCM dans config/configuration.yml. RedÃ©marrer l'application aprÃ¨s modification.
-  text_scm_command_not_available: Ce SCM n'est pas disponible. VÃ©rifier les paramÃ¨tres dans la section administration.
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Ordre de tri
-  description_project_scope: PÃ©rimÃ¨tre de recherche
-  description_filter: Filtre
-  description_user_mail_notification: Option de notification
-  description_date_from: Date de dÃ©but
-  description_message_content: Contenu du message
-  description_available_columns: Colonnes disponibles
-  description_all_columns: Toutes les colonnes
-  description_date_range_interval: Choisir une pÃ©riode
-  description_issue_category_reassign: Choisir une catÃ©gorie
-  description_search: Champ de recherche
-  description_notes: Notes
-  description_date_range_list: Choisir une pÃ©riode prÃ©dÃ©finie
-  description_choose_project: Projets
-  description_date_to: Date de fin
-  description_query_sort_criteria_attribute: CritÃ¨re de tri
-  description_wiki_subpages_reassign: Choisir une nouvelle page parent
-  description_selected_columns: Colonnes sÃ©lectionnÃ©es
-  label_parent_revision: Parent
-  label_child_revision: Enfant
-  error_scm_annotate_big_text_file: Cette entrÃ©e ne peut pas Ãªtre annotÃ©e car elle excÃ¨de la taille maximale.
-  setting_repositories_encodings: Encodages des fichiers et des dÃ©pÃ´ts
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/31/31192143eb1c52ad53b2edf56c4ab09d186df056.svn-base
--- a/.svn/pristine/31/31192143eb1c52ad53b2edf56c4ab09d186df056.svn-base
+++ /dev/null
@@ -1,54 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class IssueCategoryTest < ActiveSupport::TestCase
-  fixtures :issue_categories, :issues
-
-  def setup
-    @category = IssueCategory.find(1)
-  end
-
-  def test_create
-    assert IssueCategory.new(:project_id => 2, :name => 'New category').save
-    category = IssueCategory.first(:order => 'id DESC')
-    assert_equal 'New category', category.name
-  end
-
-  def test_create_with_group_assignment
-    assert IssueCategory.new(:project_id => 2, :name => 'Group assignment', :assigned_to_id => 11).save
-    category = IssueCategory.first(:order => 'id DESC')
-    assert_kind_of Group, category.assigned_to
-    assert_equal Group.find(11), category.assigned_to
-  end
-
-  def test_destroy
-    issue = @category.issues.first
-    @category.destroy
-    # Make sure the category was nullified on the issue
-    assert_nil issue.reload.category
-  end
-
-  def test_destroy_with_reassign
-    issue = @category.issues.first
-    reassign_to = IssueCategory.find(2)
-    @category.destroy(reassign_to)
-    # Make sure the issue was reassigned
-    assert_equal reassign_to, issue.reload.category
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/31/3185cbd184bff678cc310485aae2abf79881c171.svn-base
--- /dev/null
+++ b/.svn/pristine/31/3185cbd184bff678cc310485aae2abf79881c171.svn-base
@@ -0,0 +1,22 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class NewsObserver < ActiveRecord::Observer
+  def after_create(news)
+    Mailer.news_added(news).deliver if Setting.notified_events.include?('news_added')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/31/31fa227633ea6c4259f0d7dd6d5668da6f1d4647.svn-base
--- a/.svn/pristine/31/31fa227633ea6c4259f0d7dd6d5668da6f1d4647.svn-base
+++ /dev/null
@@ -1,237 +0,0 @@
-/* The main calendar widget.  DIV containing a table. */
-
-img.calendar-trigger {
-    cursor: pointer;
-    vertical-align: middle;
-    margin-left: 4px;
-}
-
-div.calendar { position: relative; z-index: 30;}
-
-div.calendar, div.calendar table {
-  border: 1px solid #556;
-  font-size: 11px;
-  color: #000;
-  cursor: default;
-  background: #fafbfc;
-  font-family: tahoma,verdana,sans-serif;
-}
-
-/* Header part -- contains navigation buttons and day names. */
-
-div.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
-  text-align: center;    /* They are the navigation buttons */
-  padding: 2px;          /* Make the buttons seem like they're pressing */
-}
-
-div.calendar .nav {
-  background: #467aa7;
-}
-
-div.calendar thead .title { /* This holds the current "month, year" */
-  font-weight: bold;      /* Pressing it will take you to the current date */
-  text-align: center;
-  background: #fff;
-  color: #000;
-  padding: 2px;
-}
-
-div.calendar thead .headrow { /* Row <TR> containing navigation buttons */
-  background: #467aa7;
-  color: #fff;
-}
-
-div.calendar thead .daynames { /* Row <TR> containing the day names */
-  background: #bdf;
-}
-
-div.calendar thead .name { /* Cells <TD> containing the day names */
-  border-bottom: 1px solid #556;
-  padding: 2px;
-  text-align: center;
-  color: #000;
-}
-
-div.calendar thead .weekend { /* How a weekend day name shows in header */
-  color: #a66;
-}
-
-div.calendar thead .hilite { /* How do the buttons in header appear when hover */
-  background-color: #80b0da;
-  color: #000;
-  padding: 1px;
-}
-
-div.calendar thead .active { /* Active (pressed) buttons in header */
-  background-color: #77c;
-  padding: 2px 0px 0px 2px;
-}
-
-/* The body part -- contains all the days in month. */
-
-div.calendar tbody .day { /* Cells <TD> containing month days dates */
-  width: 2em;
-  color: #456;
-  text-align: right;
-  padding: 2px 4px 2px 2px;
-}
-div.calendar tbody .day.othermonth {
-  font-size: 80%;
-  color: #bbb;
-}
-div.calendar tbody .day.othermonth.oweekend {
-  color: #fbb;
-}
-
-div.calendar table .wn {
-  padding: 2px 3px 2px 2px;
-  border-right: 1px solid #000;
-  background: #bdf;
-}
-
-div.calendar tbody .rowhilite td {
-  background: #def;
-}
-
-div.calendar tbody .rowhilite td.wn {
-  background: #80b0da;
-}
-
-div.calendar tbody td.hilite { /* Hovered cells <TD> */
-  background: #80b0da;
-  padding: 1px 3px 1px 1px;
-  border: 1px solid #bbb;
-}
-
-div.calendar tbody td.active { /* Active (pressed) cells <TD> */
-  background: #cde;
-  padding: 2px 2px 0px 2px;
-}
-
-div.calendar tbody td.selected { /* Cell showing today date */
-  font-weight: bold;
-  border: 1px solid #000;
-  padding: 1px 3px 1px 1px;
-  background: #fff;
-  color: #000;
-}
-
-div.calendar tbody td.weekend { /* Cells showing weekend days */
-  color: #a66;
-}
-
-div.calendar tbody td.today { /* Cell showing selected date */
-  font-weight: bold;
-  color: #f00;
-}
-
-div.calendar tbody .disabled { color: #999; }
-
-div.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
-  visibility: hidden;
-}
-
-div.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
-  display: none;
-}
-
-/* The footer part -- status bar and "Close" button */
-
-div.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
-  text-align: center;
-  background: #556;
-  color: #fff;
-}
-
-div.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
-  background: #fff;
-  color: #445;
-  border-top: 1px solid #556;
-  padding: 1px;
-}
-
-div.calendar tfoot .hilite { /* Hover style for buttons in footer */
-  background: #aaf;
-  border: 1px solid #04f;
-  color: #000;
-  padding: 1px;
-}
-
-div.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
-  background: #77c;
-  padding: 2px 0px 0px 2px;
-}
-
-/* Combo boxes (menus that display months/years for direct selection) */
-
-div.calendar .combo {
-  position: absolute;
-  display: none;
-  top: 0px;
-  left: 0px;
-  width: 4em;
-  cursor: default;
-  border: 1px solid #655;
-  background: #def;
-  color: #000;
-  font-size: 90%;
-  z-index: 100;
-}
-
-div.calendar .combo .label,
-div.calendar .combo .label-IEfix {
-  text-align: center;
-  padding: 1px;
-}
-
-div.calendar .combo .label-IEfix {
-  width: 4em;
-}
-
-div.calendar .combo .hilite {
-  background: #acf;
-}
-
-div.calendar .combo .active {
-  border-top: 1px solid #46a;
-  border-bottom: 1px solid #46a;
-  background: #eef;
-  font-weight: bold;
-}
-
-div.calendar td.time {
-  border-top: 1px solid #000;
-  padding: 1px 0px;
-  text-align: center;
-  background-color: #f4f0e8;
-}
-
-div.calendar td.time .hour,
-div.calendar td.time .minute,
-div.calendar td.time .ampm {
-  padding: 0px 3px 0px 4px;
-  border: 1px solid #889;
-  font-weight: bold;
-  background-color: #fff;
-}
-
-div.calendar td.time .ampm {
-  text-align: center;
-}
-
-div.calendar td.time .colon {
-  padding: 0px 2px 0px 3px;
-  font-weight: bold;
-}
-
-div.calendar td.time span.hilite {
-  border-color: #000;
-  background-color: #667;
-  color: #fff;
-}
-
-div.calendar td.time span.active {
-  border-color: #f00;
-  background-color: #000;
-  color: #0f0;
-}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/32/326a62adc02ab48e12d9e9d717fea2e84b8c44cf.svn-base
--- /dev/null
+++ b/.svn/pristine/32/326a62adc02ab48e12d9e9d717fea2e84b8c44cf.svn-base
@@ -0,0 +1,601 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoryGitTest < ActiveSupport::TestCase
+  fixtures :projects, :repositories, :enabled_modules, :users, :roles
+
+  include Redmine::I18n
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
+  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
+
+  NUM_REV = 28
+  NUM_HEAD = 6
+
+  FELIX_HEX  = "Felix Sch\xC3\xA4fer"
+  CHAR_1_HEX = "\xc3\x9c"
+
+  ## Git, Mercurial and CVS path encodings are binary.
+  ## Subversion supports URL encoding for path.
+  ## Redmine Mercurial adapter and extension use URL encoding.
+  ## Git accepts only binary path in command line parameter.
+  ## So, there is no way to use binary command line parameter in JRuby.
+  JRUBY_SKIP     = (RUBY_PLATFORM == 'java')
+  JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
+
+  def setup
+    @project = Project.find(3)
+    @repository = Repository::Git.create(
+                        :project       => @project,
+                        :url           => REPOSITORY_PATH,
+                        :path_encoding => 'ISO-8859-1'
+                        )
+    assert @repository
+    @char_1        = CHAR_1_HEX.dup
+    if @char_1.respond_to?(:force_encoding)
+      @char_1.force_encoding('UTF-8')
+    end
+  end
+
+  def test_blank_path_to_repository_error_message
+    set_language_if_valid 'en'
+    repo = Repository::Git.new(
+                          :project      => @project,
+                          :identifier   => 'test'
+                        )
+    assert !repo.save
+    assert_include "Path to repository can't be blank",
+                   repo.errors.full_messages
+  end
+
+  def test_blank_path_to_repository_error_message_fr
+    set_language_if_valid 'fr'
+    str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    repo = Repository::Git.new(
+                          :project      => @project,
+                          :url          => "",
+                          :identifier   => 'test',
+                          :path_encoding => ''
+                        )
+    assert !repo.save
+    assert_include str, repo.errors.full_messages
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    ## Ruby uses ANSI api to fork a process on Windows.
+    ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
+    ## and these are incompatible with ASCII.
+    ## Git for Windows (msysGit) changed internal API from ANSI to Unicode in 1.7.10
+    ## http://code.google.com/p/msysgit/issues/detail?id=80
+    ## So, Latin-1 path tests fail on Japanese Windows
+    WINDOWS_PASS = (Redmine::Platform.mswin? &&
+                         Redmine::Scm::Adapters::GitAdapter.client_version_above?([1, 7, 10]))
+    WINDOWS_SKIP_STR = "TODO: This test fails in Git for Windows above 1.7.10"
+
+    def test_scm_available
+      klass = Repository::Git
+      assert_equal "Git", klass.scm_name
+      assert klass.scm_adapter_class
+      assert_not_equal "", klass.scm_command
+      assert_equal true, klass.scm_available
+    end
+
+    def test_entries
+      entries = @repository.entries
+      assert_kind_of Redmine::Scm::Adapters::Entries, entries
+    end
+
+    def test_fetch_changesets_from_scratch
+      assert_nil @repository.extra_info
+
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_equal 39, @repository.filechanges.count
+
+      commit = @repository.changesets.find_by_revision("7234cb2750b63f47bff735edc50a1c0a433c2518")
+      assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", commit.scmid
+      assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments
+      assert_equal "jsmith <jsmith@foo.bar>", commit.committer
+      assert_equal User.find_by_login('jsmith'), commit.user
+      # TODO: add a commit with commit time <> author time to the test repository
+      assert_equal "2007-12-14 09:22:52".to_time, commit.committed_on
+      assert_equal "2007-12-14".to_date, commit.commit_date
+      assert_equal 3, commit.filechanges.count
+      change = commit.filechanges.sort_by(&:path).first
+      assert_equal "README", change.path
+      assert_equal nil, change.from_path
+      assert_equal "A", change.action
+
+      assert_equal NUM_HEAD, @repository.extra_info["heads"].size
+    end
+
+    def test_fetch_changesets_incremental
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      extra_info_heads = @repository.extra_info["heads"].dup
+      assert_equal NUM_HEAD, extra_info_heads.size
+      extra_info_heads.delete_if { |x| x == "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c" }
+      assert_equal 4, extra_info_heads.size
+
+      del_revs = [
+          "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
+          "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
+          "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
+          "deff712f05a90d96edbd70facc47d944be5897e3",
+          "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
+          "7e61ac704deecde634b51e59daa8110435dcb3da",
+         ]
+      @repository.changesets.each do |rev|
+        rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
+      end
+      @project.reload
+      cs1 = @repository.changesets
+      assert_equal NUM_REV - 6, cs1.count
+      extra_info_heads << "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
+      h = {}
+      h["heads"] = extra_info_heads
+      @repository.merge_extra_info(h)
+      @repository.save
+      @project.reload
+      assert @repository.extra_info["heads"].index("4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8")
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_equal NUM_HEAD, @repository.extra_info["heads"].size
+      assert @repository.extra_info["heads"].index("83ca5fd546063a3c7dc2e568ba3355661a9e2b2c")
+    end
+
+    def test_fetch_changesets_history_editing
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      extra_info_heads = @repository.extra_info["heads"].dup
+      assert_equal NUM_HEAD, extra_info_heads.size
+      extra_info_heads.delete_if { |x| x == "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c" }
+      assert_equal 4, extra_info_heads.size
+
+      del_revs = [
+          "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
+          "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
+          "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
+          "deff712f05a90d96edbd70facc47d944be5897e3",
+          "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
+          "7e61ac704deecde634b51e59daa8110435dcb3da",
+         ]
+      @repository.changesets.each do |rev|
+        rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
+      end
+      @project.reload
+      assert_equal NUM_REV - 6, @repository.changesets.count
+
+      c = Changeset.new(:repository   => @repository,
+                        :committed_on => Time.now,
+                        :revision     => "abcd1234efgh",
+                        :scmid        => "abcd1234efgh",
+                        :comments     => 'test')
+      assert c.save
+      @project.reload
+      assert_equal NUM_REV - 5, @repository.changesets.count
+
+      extra_info_heads << "1234abcd5678"
+      h = {}
+      h["heads"] = extra_info_heads
+      @repository.merge_extra_info(h)
+      @repository.save
+      @project.reload
+      h1 = @repository.extra_info["heads"].dup
+      assert h1.index("1234abcd5678")
+      assert_equal 5, h1.size
+
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV - 5, @repository.changesets.count
+      h2 = @repository.extra_info["heads"].dup
+      assert_equal h1, h2
+    end
+
+    def test_keep_extra_report_last_commit_in_clear_changesets
+      assert_nil @repository.extra_info
+      h = {}
+      h["extra_report_last_commit"] = "1"
+      @repository.merge_extra_info(h)
+      @repository.save
+      @project.reload
+
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+
+      assert_equal NUM_REV, @repository.changesets.count
+      @repository.send(:clear_changesets)
+      assert_equal 1, @repository.extra_info.size
+      assert_equal "1", @repository.extra_info["extra_report_last_commit"]
+    end
+
+    def test_refetch_after_clear_changesets
+      assert_nil @repository.extra_info
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      @repository.send(:clear_changesets)
+      @project.reload
+      assert_equal 0, @repository.changesets.count
+
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+    end
+
+    def test_parents
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      r1 = @repository.find_changeset_by_name("7234cb2750b63")
+      assert_equal [], r1.parents
+      r2 = @repository.find_changeset_by_name("899a15dba03a3")
+      assert_equal 1, r2.parents.length
+      assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
+                   r2.parents[0].identifier
+      r3 = @repository.find_changeset_by_name("32ae898b720c2")
+      assert_equal 2, r3.parents.length
+      r4 = [r3.parents[0].identifier, r3.parents[1].identifier].sort
+      assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", r4[0]
+      assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da", r4[1]
+    end
+
+    def test_db_consistent_ordering_init
+      assert_nil @repository.extra_info
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal 1, @repository.extra_info["db_consistent"]["ordering"]
+    end
+
+    def test_db_consistent_ordering_before_1_2
+      assert_nil @repository.extra_info
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_not_nil @repository.extra_info
+      h = {}
+      h["heads"] = []
+      h["branches"] = {}
+      h["db_consistent"] = {}
+      @repository.merge_extra_info(h)
+      @repository.save
+      assert_equal NUM_REV, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
+
+      extra_info_heads = @repository.extra_info["heads"].dup
+      extra_info_heads.delete_if { |x| x == "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c" }
+      del_revs = [
+          "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
+          "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
+          "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
+          "deff712f05a90d96edbd70facc47d944be5897e3",
+          "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
+          "7e61ac704deecde634b51e59daa8110435dcb3da",
+         ]
+      @repository.changesets.each do |rev|
+        rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
+      end
+      @project.reload
+      cs1 = @repository.changesets
+      assert_equal NUM_REV - 6, cs1.count
+      assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
+
+      extra_info_heads << "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
+      h = {}
+      h["heads"] = extra_info_heads
+      @repository.merge_extra_info(h)
+      @repository.save
+      @project.reload
+      assert @repository.extra_info["heads"].index("4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8")
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_equal NUM_HEAD, @repository.extra_info["heads"].size
+
+      assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
+    end
+
+    def test_heads_from_branches_hash
+      assert_nil @repository.extra_info
+      assert_equal 0, @repository.changesets.count
+      assert_equal [], @repository.heads_from_branches_hash
+      h = {}
+      h["branches"] = {}
+      h["branches"]["test1"] = {}
+      h["branches"]["test1"]["last_scmid"] = "1234abcd"
+      h["branches"]["test2"] = {}
+      h["branches"]["test2"]["last_scmid"] = "abcd1234"
+      @repository.merge_extra_info(h)
+      @repository.save
+      @project.reload
+      assert_equal ["1234abcd", "abcd1234"], @repository.heads_from_branches_hash.sort
+    end
+
+    def test_latest_changesets
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      # with limit
+      changesets = @repository.latest_changesets('', 'master', 2)
+      assert_equal 2, changesets.size
+
+      # with path
+      changesets = @repository.latest_changesets('images', 'master')
+      assert_equal [
+              'deff712f05a90d96edbd70facc47d944be5897e3',
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+              '7234cb2750b63f47bff735edc50a1c0a433c2518',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README', nil)
+      assert_equal [
+              '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf',
+              '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8',
+              '713f4944648826f558cf548222f813dabe7cbb04',
+              '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+              '7234cb2750b63f47bff735edc50a1c0a433c2518',
+          ], changesets.collect(&:revision)
+
+      # with path, revision and limit
+      changesets = @repository.latest_changesets('images', '899a15dba')
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+              '7234cb2750b63f47bff735edc50a1c0a433c2518',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('images', '899a15dba', 1)
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README', '899a15dba')
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+              '7234cb2750b63f47bff735edc50a1c0a433c2518',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README', '899a15dba', 1)
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+          ], changesets.collect(&:revision)
+
+      # with path, tag and limit
+      changesets = @repository.latest_changesets('images', 'tag01.annotated')
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+              '7234cb2750b63f47bff735edc50a1c0a433c2518',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('images', 'tag01.annotated', 1)
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README', 'tag01.annotated')
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+              '7234cb2750b63f47bff735edc50a1c0a433c2518',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README', 'tag01.annotated', 1)
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+          ], changesets.collect(&:revision)
+
+      # with path, branch and limit
+      changesets = @repository.latest_changesets('images', 'test_branch')
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+              '7234cb2750b63f47bff735edc50a1c0a433c2518',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('images', 'test_branch', 1)
+      assert_equal [
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README', 'test_branch')
+      assert_equal [
+              '713f4944648826f558cf548222f813dabe7cbb04',
+              '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
+              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
+              '7234cb2750b63f47bff735edc50a1c0a433c2518',
+          ], changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README', 'test_branch', 2)
+      assert_equal [
+              '713f4944648826f558cf548222f813dabe7cbb04',
+              '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
+          ], changesets.collect(&:revision)
+
+      if WINDOWS_PASS
+        puts WINDOWS_SKIP_STR
+      elsif JRUBY_SKIP
+        puts JRUBY_SKIP_STR
+      else
+        # latin-1 encoding path
+        changesets = @repository.latest_changesets(
+                      "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89')
+        assert_equal [
+              '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
+              '4fc55c43bf3d3dc2efb66145365ddc17639ce81e',
+          ], changesets.collect(&:revision)
+
+        changesets = @repository.latest_changesets(
+                    "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89', 1)
+        assert_equal [
+              '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
+          ], changesets.collect(&:revision)
+      end
+    end
+
+    def test_latest_changesets_latin_1_dir
+      if WINDOWS_PASS
+        puts WINDOWS_SKIP_STR
+      elsif JRUBY_SKIP
+        puts JRUBY_SKIP_STR
+      else
+        assert_equal 0, @repository.changesets.count
+        @repository.fetch_changesets
+        @project.reload
+        assert_equal NUM_REV, @repository.changesets.count
+        changesets = @repository.latest_changesets(
+                    "latin-1-dir/test-#{@char_1}-subdir", '1ca7f5ed')
+        assert_equal [
+              '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127',
+          ], changesets.collect(&:revision)
+      end
+    end
+
+    def test_find_changeset_by_name
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['7234cb2750b63f47bff735edc50a1c0a433c2518', '7234cb2750b'].each do |r|
+        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518',
+                     @repository.find_changeset_by_name(r).revision
+      end
+    end
+
+    def test_find_changeset_by_empty_name
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['', ' ', nil].each do |r|
+        assert_nil @repository.find_changeset_by_name(r)
+      end
+    end
+
+    def test_identifier
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      c = @repository.changesets.find_by_revision(
+                          '7234cb2750b63f47bff735edc50a1c0a433c2518')
+      assert_equal c.scmid, c.identifier
+    end
+
+    def test_format_identifier
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      c = @repository.changesets.find_by_revision(
+                          '7234cb2750b63f47bff735edc50a1c0a433c2518')
+      assert_equal '7234cb27', c.format_identifier
+    end
+
+    def test_activities
+      c = Changeset.new(:repository => @repository,
+                        :committed_on => Time.now,
+                        :revision => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
+                        :scmid    => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
+                        :comments => 'test')
+      assert c.event_title.include?('abc7234c:')
+      assert_equal 'abc7234cb2750b63f47bff735edc50a1c0a433c2', c.event_url[:rev]
+    end
+
+    def test_log_utf8
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      str_felix_hex  = FELIX_HEX.dup
+      if str_felix_hex.respond_to?(:force_encoding)
+          str_felix_hex.force_encoding('UTF-8')
+      end
+      c = @repository.changesets.find_by_revision(
+                        'ed5bb786bbda2dee66a2d50faf51429dbc043a7b')
+      assert_equal "#{str_felix_hex} <felix@fachschaften.org>", c.committer
+    end
+
+    def test_previous
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
+        changeset = @repository.find_changeset_by_name(r1)
+        %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
+          assert_equal @repository.find_changeset_by_name(r2), changeset.previous
+        end
+      end
+    end
+
+    def test_previous_nil
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      %w|7234cb2750b63f47bff735edc50a1c0a433c2518 7234cb275|.each do |r1|
+        changeset = @repository.find_changeset_by_name(r1)
+        assert_nil changeset.previous
+      end
+    end
+
+    def test_next
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
+        changeset = @repository.find_changeset_by_name(r2)
+        %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
+        assert_equal @repository.find_changeset_by_name(r1), changeset.next
+        end
+      end
+    end
+
+    def test_next_nil
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      %w|2a682156a3b6e77a8bf9cd4590e8db757f3c6c78 2a682156a3b6e77a|.each do |r1|
+        changeset = @repository.find_changeset_by_name(r1)
+        assert_nil changeset.next
+      end
+    end
+  else
+    puts "Git test repository NOT FOUND. Skipping unit tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/32/326ec63d3dde535244f38884da87eca7ff6e8ba3.svn-base
--- /dev/null
+++ b/.svn/pristine/32/326ec63d3dde535244f38884da87eca7ff6e8ba3.svn-base
@@ -0,0 +1,1101 @@
+# German translations for Ruby on Rails
+# by Clemens Kofler (clemens@railway.at)
+# additions for Redmine 1.2 by Jens Martsch (jmartsch@gmail.com)
+
+de:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d.%m.%Y"
+      short: "%e. %b"
+      long: "%e. %B %Y"
+
+    day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag]
+    abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Januar, Februar, MÃ¤rz, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember]
+    abbr_month_names: [~, Jan, Feb, MÃ¤r, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez]
+    # Used in date_select and datime_select.
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%d.%m.%Y %H:%M"
+      time: "%H:%M"
+      short: "%e. %b %H:%M"
+      long: "%A, %e. %B %Y, %H:%M Uhr"
+    am: "vormittags"
+    pm: "nachmittags"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: 'eine halbe Minute'
+      less_than_x_seconds:
+        one: 'weniger als 1 Sekunde'
+        other: 'weniger als %{count} Sekunden'
+      x_seconds:
+        one: '1 Sekunde'
+        other: '%{count} Sekunden'
+      less_than_x_minutes:
+        one: 'weniger als 1 Minute'
+        other: 'weniger als %{count} Minuten'
+      x_minutes:
+        one: '1 Minute'
+        other: '%{count} Minuten'
+      about_x_hours:
+        one: 'etwa 1 Stunde'
+        other: 'etwa %{count} Stunden'
+      x_hours:
+        one:   "1 Stunde"
+        other: "%{count} Stunden"
+      x_days:
+        one: '1 Tag'
+        other: '%{count} Tagen'
+      about_x_months:
+        one: 'etwa 1 Monat'
+        other: 'etwa %{count} Monaten'
+      x_months:
+        one: '1 Monat'
+        other: '%{count} Monaten'
+      about_x_years:
+        one: 'etwa 1 Jahr'
+        other: 'etwa %{count} Jahren'
+      over_x_years:
+        one: 'mehr als 1 Jahr'
+        other: 'mehr als %{count} Jahren'
+      almost_x_years:
+        one:   "fast 1 Jahr"
+        other: "fast %{count} Jahren"
+
+  number:
+    # Default format for numbers
+    format:
+      separator: ','
+      delimiter: '.'
+      precision: 2
+    currency:
+      format:
+        unit: 'â‚¬'
+        format: '%n %u'
+        delimiter: ''
+    percentage:
+      format:
+        delimiter: ""
+    precision:
+      format:
+        delimiter: ""
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "und"
+      skip_last_comma: true
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "Dieses %{model}-Objekt konnte nicht gespeichert werden: %{count} Fehler."
+          other:  "Dieses %{model}-Objekt konnte nicht gespeichert werden: %{count} Fehler."
+        body: "Bitte Ã¼berprÃ¼fen Sie die folgenden Felder:"
+
+      messages:
+        inclusion: "ist kein gÃ¼ltiger Wert"
+        exclusion: "ist nicht verfÃ¼gbar"
+        invalid: "ist nicht gÃ¼ltig"
+        confirmation: "stimmt nicht mit der BestÃ¤tigung Ã¼berein"
+        accepted: "muss akzeptiert werden"
+        empty: "muss ausgefÃ¼llt werden"
+        blank: "muss ausgefÃ¼llt werden"
+        too_long: "ist zu lang (nicht mehr als %{count} Zeichen)"
+        too_short: "ist zu kurz (nicht weniger als %{count} Zeichen)"
+        wrong_length: "hat die falsche LÃ¤nge (muss genau %{count} Zeichen haben)"
+        taken: "ist bereits vergeben"
+        not_a_number: "ist keine Zahl"
+        not_a_date: "is kein gÃ¼ltiges Datum"
+        greater_than: "muss grÃ¶ÃŸer als %{count} sein"
+        greater_than_or_equal_to: "muss grÃ¶ÃŸer oder gleich %{count} sein"
+        equal_to: "muss genau %{count} sein"
+        less_than: "muss kleiner als %{count} sein"
+        less_than_or_equal_to: "muss kleiner oder gleich %{count} sein"
+        odd: "muss ungerade sein"
+        even: "muss gerade sein"
+        greater_than_start_date: "muss grÃ¶ÃŸer als Anfangsdatum sein"
+        not_same_project: "gehÃ¶rt nicht zum selben Projekt"
+        circular_dependency: "Diese Beziehung wÃ¼rde eine zyklische AbhÃ¤ngigkeit erzeugen"
+        cant_link_an_issue_with_a_descendant: "Ein Ticket kann nicht mit einer Ihrer Unteraufgaben verlinkt werden"
+
+  actionview_instancetag_blank_option: Bitte auswÃ¤hlen
+
+  button_activate: Aktivieren
+  button_add: HinzufÃ¼gen
+  button_annotate: Annotieren
+  button_apply: Anwenden
+  button_archive: Archivieren
+  button_back: ZurÃ¼ck
+  button_cancel: Abbrechen
+  button_change: Wechseln
+  button_change_password: Kennwort Ã¤ndern
+  button_check_all: Alles auswÃ¤hlen
+  button_clear: ZurÃ¼cksetzen
+  button_close: SchlieÃŸen
+  button_collapse_all: Alle einklappen
+  button_configure: Konfigurieren
+  button_copy: Kopieren
+  button_copy_and_follow: Kopieren und Ticket anzeigen
+  button_create: Anlegen
+  button_create_and_continue: Anlegen und weiter
+  button_delete: LÃ¶schen
+  button_delete_my_account: Mein Benutzerkonto lÃ¶schen 
+  button_download: Download
+  button_duplicate: Duplizieren
+  button_edit: Bearbeiten
+  button_edit_associated_wikipage: "ZugehÃ¶rige Wikiseite bearbeiten: %{page_title}"
+  button_edit_section: Diesen Bereich bearbeiten
+  button_expand_all: Alle ausklappen
+  button_export: Exportieren
+  button_hide: Verstecken
+  button_list: Liste
+  button_lock: Sperren
+  button_log_time: Aufwand buchen
+  button_login: Anmelden
+  button_move: Verschieben
+  button_move_and_follow: Verschieben und Ticket anzeigen
+  button_quote: Zitieren
+  button_rename: Umbenennen
+  button_reopen: Ã–ffnen
+  button_reply: Antworten
+  button_reset: ZurÃ¼cksetzen
+  button_rollback: Auf diese Version zurÃ¼cksetzen
+  button_save: Speichern
+  button_show: Anzeigen
+  button_sort: Sortieren
+  button_submit: OK
+  button_test: Testen
+  button_unarchive: Entarchivieren
+  button_uncheck_all: Alles abwÃ¤hlen
+  button_unlock: Entsperren
+  button_unwatch: Nicht beobachten
+  button_update: Bearbeiten
+  button_view: Anzeigen
+  button_watch: Beobachten
+
+  default_activity_design: Design
+  default_activity_development: Entwicklung
+  default_doc_category_tech: Technische Dokumentation
+  default_doc_category_user: Benutzerdokumentation
+  default_issue_status_closed: Erledigt
+  default_issue_status_feedback: Feedback
+  default_issue_status_in_progress: In Bearbeitung
+  default_issue_status_new: Neu
+  default_issue_status_rejected: Abgewiesen
+  default_issue_status_resolved: GelÃ¶st
+  default_priority_high: Hoch
+  default_priority_immediate: Sofort
+  default_priority_low: Niedrig
+  default_priority_normal: Normal
+  default_priority_urgent: Dringend
+  default_role_developer: Entwickler
+  default_role_manager: Manager
+  default_role_reporter: Reporter
+  default_tracker_bug: Fehler
+  default_tracker_feature: Feature
+  default_tracker_support: UnterstÃ¼tzung
+
+  description_all_columns: Alle Spalten
+  description_available_columns: VerfÃ¼gbare Spalten
+  description_choose_project: Projekte
+  description_date_from: Startdatum eintragen
+  description_date_range_interval: Zeitraum durch Start- und Enddatum festlegen
+  description_date_range_list: Zeitraum aus einer Liste wÃ¤hlen
+  description_date_to: Enddatum eintragen
+  description_filter: Filter
+  description_issue_category_reassign: Neue Kategorie wÃ¤hlen
+  description_message_content: Nachrichteninhalt
+  description_notes: Kommentare
+  description_project_scope: Suchbereich
+  description_query_sort_criteria_attribute: Sortierattribut
+  description_query_sort_criteria_direction: Sortierrichtung
+  description_search: Suchfeld
+  description_selected_columns: AusgewÃ¤hlte Spalten
+  description_user_mail_notification: Mailbenachrichtigungseinstellung
+  description_wiki_subpages_reassign: Neue Elternseite wÃ¤hlen
+
+  enumeration_activities: AktivitÃ¤ten (Zeiterfassung)
+  enumeration_doc_categories: Dokumentenkategorien
+  enumeration_issue_priorities: Ticket-PrioritÃ¤ten
+  enumeration_system_activity: System-AktivitÃ¤t
+
+  error_attachment_too_big: Diese Datei kann nicht hochgeladen werden, da sie die maximale DateigrÃ¶ÃŸe von (%{max_size}) Ã¼berschreitet.
+  error_can_not_archive_project: Dieses Projekt kann nicht archiviert werden.
+  error_can_not_delete_custom_field: Kann das benutzerdefinierte Feld nicht lÃ¶schen.
+  error_can_not_delete_tracker: Dieser Tracker enthÃ¤lt Tickets und kann nicht gelÃ¶scht werden.
+  error_can_not_remove_role: Diese Rolle wird verwendet und kann nicht gelÃ¶scht werden.
+  error_can_not_reopen_issue_on_closed_version: Das Ticket ist einer abgeschlossenen Version zugeordnet und kann daher nicht wieder geÃ¶ffnet werden.
+  error_can_t_load_default_data: "Die Standard-Konfiguration konnte nicht geladen werden: %{value}"
+  error_issue_done_ratios_not_updated: Der Ticket-Fortschritt wurde nicht aktualisiert.
+  error_issue_not_found_in_project: 'Das Ticket wurde nicht gefunden oder gehÃ¶rt nicht zu diesem Projekt.'
+  error_no_default_issue_status: Es ist kein Status als Standard definiert. Bitte Ã¼berprÃ¼fen Sie Ihre Konfiguration (unter "Administration -> Ticket-Status").
+  error_no_tracker_in_project: Diesem Projekt ist kein Tracker zugeordnet. Bitte Ã¼berprÃ¼fen Sie die Projekteinstellungen.
+  error_scm_annotate: "Der Eintrag existiert nicht oder kann nicht annotiert werden."
+  error_scm_annotate_big_text_file: Der Eintrag kann nicht umgesetzt werden, da er die maximale TextlÃ¤nge Ã¼berschreitet.
+  error_scm_command_failed: "Beim Zugriff auf das Projektarchiv ist ein Fehler aufgetreten: %{value}"
+  error_scm_not_found: Eintrag und/oder Revision existiert nicht im Projektarchiv.
+  error_session_expired: Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.
+  error_unable_delete_issue_status: "Der Ticket-Status konnte nicht gelÃ¶scht werden."
+  error_unable_to_connect: Fehler beim Verbinden (%{value})
+  error_workflow_copy_source: Bitte wÃ¤hlen Sie einen Quell-Tracker und eine Quell-Rolle.
+  error_workflow_copy_target: Bitte wÃ¤hlen Sie die Ziel-Tracker und -Rollen.
+
+  field_account: Konto
+  field_active: Aktiv
+  field_activity: AktivitÃ¤t
+  field_admin: Administrator
+  field_assignable: Tickets kÃ¶nnen dieser Rolle zugewiesen werden
+  field_assigned_to: Zugewiesen an
+  field_assigned_to_role: ZustÃ¤ndigkeitsrolle
+  field_attr_firstname: Vorname-Attribut
+  field_attr_lastname: Name-Attribut
+  field_attr_login: Mitgliedsname-Attribut
+  field_attr_mail: E-Mail-Attribut
+  field_auth_source: Authentifizierungs-Modus
+  field_auth_source_ldap_filter: LDAP-Filter
+  field_author: Autor
+  field_base_dn: Base DN
+  field_board_parent: Ãœbergeordnetes Forum
+  field_category: Kategorie
+  field_column_names: Spalten
+  field_closed_on: Geschlossen am
+  field_comments: Kommentar
+  field_comments_sorting: Kommentare anzeigen
+  field_commit_logs_encoding: Kodierung der Commit-Log-Meldungen
+  field_content: Inhalt
+  field_core_fields: Standardwerte
+  field_created_on: Angelegt
+  field_cvs_module: Modul
+  field_cvsroot: CVSROOT
+  field_default_value: Standardwert
+  field_delay: Pufferzeit
+  field_description: Beschreibung
+  field_done_ratio: "% erledigt"
+  field_downloads: Downloads
+  field_due_date: Abgabedatum
+  field_editable: Bearbeitbar
+  field_effective_date: Datum
+  field_estimated_hours: GeschÃ¤tzter Aufwand
+  field_field_format: Format
+  field_filename: Datei
+  field_filesize: GrÃ¶ÃŸe
+  field_firstname: Vorname
+  field_fixed_version: Zielversion
+  field_group_by: Gruppiere Ergebnisse nach
+  field_hide_mail: E-Mail-Adresse nicht anzeigen
+  field_homepage: Projekt-Homepage
+  field_host: Host
+  field_hours: Stunden
+  field_identifier: Kennung
+  field_identity_url: OpenID-URL
+  field_inherit_members: Benutzer vererben
+  field_is_closed: Ticket geschlossen
+  field_is_default: Standardeinstellung
+  field_is_filter: Als Filter benutzen
+  field_is_for_all: FÃ¼r alle Projekte
+  field_is_in_roadmap: In der Roadmap anzeigen
+  field_is_private: Privat
+  field_is_public: Ã–ffentlich
+  field_is_required: Erforderlich
+  field_issue: Ticket
+  field_issue_to: ZugehÃ¶riges Ticket
+  field_issues_visibility: Ticket Sichtbarkeit
+  field_language: Sprache
+  field_last_login_on: Letzte Anmeldung
+  field_lastname: Nachname
+  field_login: Mitgliedsname
+  field_mail: E-Mail
+  field_mail_notification: Mailbenachrichtigung
+  field_max_length: Maximale LÃ¤nge
+  field_member_of_group: ZustÃ¤ndigkeitsgruppe
+  field_min_length: Minimale LÃ¤nge
+  field_multiple: Mehrere Werte
+  field_name: Name
+  field_new_password: Neues Kennwort
+  field_notes: Kommentare
+  field_onthefly: On-the-fly-Benutzererstellung
+  field_parent: Unterprojekt von
+  field_parent_issue: Ãœbergeordnete Aufgabe
+  field_parent_title: Ãœbergeordnete Seite
+  field_password: Kennwort
+  field_password_confirmation: BestÃ¤tigung
+  field_path_to_repository: Pfad zum Repository
+  field_port: Port
+  field_possible_values: MÃ¶gliche Werte
+  field_principal: Auftraggeber
+  field_priority: PrioritÃ¤t
+  field_private_notes: Privater Kommentar
+  field_project: Projekt
+  field_redirect_existing_links: Existierende Links umleiten
+  field_regexp: RegulÃ¤rer Ausdruck
+  field_repository_is_default: Haupt-Repository
+  field_role: Rolle
+  field_root_directory: Wurzelverzeichnis
+  field_scm_path_encoding: Pfad-Kodierung
+  field_searchable: Durchsuchbar
+  field_sharing: Gemeinsame Verwendung
+  field_spent_on: Datum
+  field_start_date: Beginn
+  field_start_page: Hauptseite
+  field_status: Status
+  field_subject: Thema
+  field_subproject: Unterprojekt von
+  field_summary: Zusammenfassung
+  field_text: Textfeld
+  field_time_entries: Logzeit
+  field_time_zone: Zeitzone
+  field_timeout: Auszeit (in Sekunden)
+  field_title: Titel
+  field_tracker: Tracker
+  field_type: Typ
+  field_updated_on: Aktualisiert
+  field_url: URL
+  field_user: Benutzer
+  field_value: Wert
+  field_version: Version
+  field_visible: Sichtbar
+  field_warn_on_leaving_unsaved: Vor dem Verlassen einer Seite mit ungesichertem Text im Editor warnen
+  field_watcher: Beobachter
+
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-1
+  general_csv_separator: ';'
+  general_first_day_of_week: '1'
+  general_lang_name: 'Deutsch'
+  general_pdf_encoding: UTF-8
+  general_text_No: 'Nein'
+  general_text_Yes: 'Ja'
+  general_text_no: 'nein'
+  general_text_yes: 'ja'
+
+  label_activity: AktivitÃ¤t
+  label_add_another_file: Eine weitere Datei hinzufÃ¼gen
+  label_add_note: Kommentar hinzufÃ¼gen
+  label_added: hinzugefÃ¼gt
+  label_added_time_by: "Von %{author} vor %{age} hinzugefÃ¼gt"
+  label_additional_workflow_transitions_for_assignee: ZusÃ¤tzliche Berechtigungen wenn der Benutzer der Zugewiesene ist
+  label_additional_workflow_transitions_for_author: ZusÃ¤tzliche Berechtigungen wenn der Benutzer der Autor ist
+  label_administration: Administration
+  label_age: GeÃ¤ndert vor
+  label_ago: vor
+  label_all: alle
+  label_all_time: gesamter Zeitraum
+  label_all_words: Alle WÃ¶rter
+  label_and_its_subprojects: "%{value} und dessen Unterprojekte"
+  label_any: alle
+  label_any_issues_in_project: irgendein Ticket im Projekt
+  label_any_issues_not_in_project: irgendein Ticket nicht im Projekt
+  label_api_access_key: API-ZugriffsschlÃ¼ssel
+  label_api_access_key_created_on: Der API-ZugriffsschlÃ¼ssel wurde vor %{value} erstellt
+  label_applied_status: Zugewiesener Status
+  label_ascending: Aufsteigend
+  label_assigned_to_me_issues: Mir zugewiesene Tickets
+  label_associated_revisions: ZugehÃ¶rige Revisionen
+  label_attachment: Datei
+  label_attachment_delete: Anhang lÃ¶schen
+  label_attachment_new: Neue Datei
+  label_attachment_plural: Dateien
+  label_attribute: Attribut
+  label_attribute_of_assigned_to: "%{name} des Bearbeiters"
+  label_attribute_of_author: "%{name} des Autors"
+  label_attribute_of_fixed_version: "%{name} der Zielversion"
+  label_attribute_of_issue: "%{name} des Tickets"
+  label_attribute_of_project: "%{name} des Projekts"
+  label_attribute_of_user: "%{name} des Benutzers"
+  label_attribute_plural: Attribute
+  label_auth_source: Authentifizierungs-Modus
+  label_auth_source_new: Neuer Authentifizierungs-Modus
+  label_auth_source_plural: Authentifizierungs-Arten
+  label_authentication: Authentifizierung
+  label_between: zwischen
+  label_blocked_by: Blockiert durch
+  label_blocks: Blockiert
+  label_board: Forum
+  label_board_locked: Gesperrt
+  label_board_new: Neues Forum
+  label_board_plural: Foren
+  label_board_sticky: Wichtig (immer oben)
+  label_boolean: Boolean
+  label_branch: Zweig
+  label_browse: Codebrowser
+  label_bulk_edit_selected_issues: Alle ausgewÃ¤hlten Tickets bearbeiten
+  label_bulk_edit_selected_time_entries: AusgewÃ¤hlte ZeitaufwÃ¤nde bearbeiten
+  label_calendar: Kalender
+  label_change_plural: Ã„nderungen
+  label_change_properties: Eigenschaften Ã¤ndern
+  label_change_status: Statuswechsel
+  label_change_view_all: Alle Ã„nderungen anzeigen
+  label_changes_details: Details aller Ã„nderungen
+  label_changeset_plural: Changesets
+  label_child_revision: Nachfolger
+  label_chronological_order: in zeitlicher Reihenfolge
+  label_close_versions: VollstÃ¤ndige Versionen schlieÃŸen
+  label_closed_issues: geschlossen
+  label_closed_issues_plural: geschlossen
+  label_comment: Kommentar
+  label_comment_add: Kommentar hinzufÃ¼gen
+  label_comment_added: Kommentar hinzugefÃ¼gt
+  label_comment_delete: Kommentar lÃ¶schen
+  label_comment_plural: Kommentare
+  label_commits_per_author: Ãœbertragungen pro Autor
+  label_commits_per_month: Ãœbertragungen pro Monat
+  label_completed_versions: Abgeschlossene Versionen
+  label_confirmation: BestÃ¤tigung
+  label_contains: enthÃ¤lt
+  label_copied: kopiert
+  label_copied_from: Kopiert von
+  label_copied_to: Kopiert nach
+  label_copy_attachments: AnhÃ¤nge kopieren
+  label_copy_same_as_target: So wie das Ziel
+  label_copy_source: Quelle
+  label_copy_subtasks: Unteraufgaben kopieren
+  label_copy_target: Ziel
+  label_copy_workflow_from: Workflow kopieren von
+  label_cross_project_descendants: Mit Unterprojekten
+  label_cross_project_hierarchy: Mit Projekthierarchie
+  label_cross_project_system: Mit allen Projekten
+  label_cross_project_tree: Mit Projektbaum
+  label_current_status: GegenwÃ¤rtiger Status
+  label_current_version: GegenwÃ¤rtige Version
+  label_custom_field: Benutzerdefiniertes Feld
+  label_custom_field_new: Neues Feld
+  label_custom_field_plural: Benutzerdefinierte Felder
+  label_date: Datum
+  label_date_from: Von
+  label_date_from_to: von %{start} bis %{end}
+  label_date_range: Zeitraum
+  label_date_to: Bis
+  label_day_plural: Tage
+  label_default: Standard
+  label_default_columns: Standard-Spalten
+  label_deleted: gelÃ¶scht
+  label_descending: Absteigend
+  label_details: Details
+  label_diff: diff
+  label_diff_inline: einspaltig
+  label_diff_side_by_side: nebeneinander
+  label_disabled: gesperrt
+  label_display: Anzeige
+  label_display_per_page: "Pro Seite: %{value}"
+  label_display_used_statuses_only: Zeige nur Status an, die von diesem Tracker verwendet werden
+  label_document: Dokument
+  label_document_added: Dokument hinzugefÃ¼gt
+  label_document_new: Neues Dokument
+  label_document_plural: Dokumente
+  label_downloads_abbr: D/L
+  label_duplicated_by: Dupliziert durch
+  label_duplicates: Duplikat von
+  label_end_to_end: Ende - Ende
+  label_end_to_start: Ende - Anfang
+  label_enumeration_new: Neuer Wert
+  label_enumerations: AufzÃ¤hlungen
+  label_environment: Umgebung
+  label_equals: ist
+  label_example: Beispiel
+  label_export_options: "%{export_format} Export-Eigenschaften"
+  label_export_to: "Auch abrufbar als:"
+  label_f_hour: "%{value} Stunde"
+  label_f_hour_plural: "%{value} Stunden"
+  label_feed_plural: Feeds
+  label_feeds_access_key: Atom-ZugriffsschlÃ¼ssel
+  label_feeds_access_key_created_on: "Atom-ZugriffsschlÃ¼ssel vor %{value} erstellt"
+  label_fields_permissions: Feldberechtigungen
+  label_file_added: Datei hinzugefÃ¼gt
+  label_file_plural: Dateien
+  label_filter_add: Filter hinzufÃ¼gen
+  label_filter_plural: Filter
+  label_float: FlieÃŸkommazahl
+  label_follows: Nachfolger von
+  label_gantt: Gantt-Diagramm
+  label_gantt_progress_line: Fortschrittslinie
+  label_general: Allgemein
+  label_generate_key: Generieren
+  label_git_report_last_commit: Bericht des letzten Commits fÃ¼r Dateien und Verzeichnisse
+  label_greater_or_equal: ">="
+  label_group: Gruppe
+  label_group_new: Neue Gruppe
+  label_group_plural: Gruppen
+  label_help: Hilfe
+  label_history: Historie
+  label_home: Hauptseite
+  label_in: in
+  label_in_less_than: in weniger als
+  label_in_more_than: in mehr als
+  label_in_the_next_days: in den nÃ¤chsten
+  label_in_the_past_days: in den letzten
+  label_incoming_emails: Eingehende E-Mails
+  label_index_by_date: Seiten nach Datum sortiert
+  label_index_by_title: Seiten nach Titel sortiert
+  label_information: Information
+  label_information_plural: Informationen
+  label_integer: Zahl
+  label_internal: Intern
+  label_issue: Ticket
+  label_issue_added: Ticket hinzugefÃ¼gt
+  label_issue_category: Ticket-Kategorie
+  label_issue_category_new: Neue Kategorie
+  label_issue_category_plural: Ticket-Kategorien
+  label_issue_new: Neues Ticket
+  label_issue_note_added: Notiz hinzugefÃ¼gt
+  label_issue_plural: Tickets
+  label_issue_priority_updated: PrioritÃ¤t aktualisiert
+  label_issue_status: Ticket-Status
+  label_issue_status_new: Neuer Status
+  label_issue_status_plural: Ticket-Status
+  label_issue_status_updated: Status aktualisiert
+  label_issue_tracking: Tickets
+  label_issue_updated: Ticket aktualisiert
+  label_issue_view_all: Alle Tickets anzeigen
+  label_issue_watchers: Beobachter
+  label_issues_by: "Tickets pro %{value}"
+  label_issues_visibility_all: Alle Tickets
+  label_issues_visibility_own: Tickets die folgender Benutzer erstellt hat oder die ihm zugewiesen sind
+  label_issues_visibility_public: Alle Ã¶ffentlichen Tickets
+  label_item_position: "%{position}/%{count}"
+  label_jump_to_a_project: Zu einem Projekt springen...
+  label_language_based: SprachabhÃ¤ngig
+  label_last_changes: "%{count} letzte Ã„nderungen"
+  label_last_login: Letzte Anmeldung
+  label_last_month: voriger Monat
+  label_last_n_days: "die letzten %{count} Tage"
+  label_last_n_weeks: letzte %{count} Wochen
+  label_last_week: vorige Woche
+  label_latest_revision: Aktuellste Revision
+  label_latest_revision_plural: Aktuellste Revisionen
+  label_ldap_authentication: LDAP-Authentifizierung
+  label_less_or_equal: "<="
+  label_less_than_ago: vor weniger als
+  label_list: Liste
+  label_loading: Lade...
+  label_logged_as: Angemeldet als
+  label_login: Anmelden
+  label_login_with_open_id_option: oder mit OpenID anmelden
+  label_logout: Abmelden
+  label_max_size: Maximale GrÃ¶ÃŸe
+  label_me: ich
+  label_member: Mitglied
+  label_member_new: Neues Mitglied
+  label_member_plural: Mitglieder
+  label_message_last: Letzter Forenbeitrag
+  label_message_new: Neues Thema
+  label_message_plural: ForenbeitrÃ¤ge
+  label_message_posted: Forenbeitrag hinzugefÃ¼gt
+  label_min_max_length: LÃ¤nge (Min. - Max.)
+  label_missing_api_access_key: Der API-ZugriffsschlÃ¼ssel fehlt.
+  label_missing_feeds_access_key: Der Atom-ZugriffsschlÃ¼ssel fehlt.
+  label_modified: geÃ¤ndert
+  label_module_plural: Module
+  label_month: Monat
+  label_months_from: Monate ab
+  label_more: Mehr
+  label_more_than_ago: vor mehr als
+  label_my_account: Mein Konto
+  label_my_page: Meine Seite
+  label_my_page_block: VerfÃ¼gbare Widgets
+  label_my_projects: Meine Projekte
+  label_my_queries: Meine eigenen Abfragen
+  label_new: Neu
+  label_new_statuses_allowed: Neue Berechtigungen
+  label_news: News
+  label_news_added: News hinzugefÃ¼gt
+  label_news_comment_added: Kommentar zu einer News hinzugefÃ¼gt
+  label_news_latest: Letzte News
+  label_news_new: News hinzufÃ¼gen
+  label_news_plural: News
+  label_news_view_all: Alle News anzeigen
+  label_next: Weiter
+  label_no_change_option: (Keine Ã„nderung)
+  label_no_data: Nichts anzuzeigen
+  label_no_issues_in_project: keine Tickets im Projekt
+  label_nobody: Niemand
+  label_none: kein
+  label_not_contains: enthÃ¤lt nicht
+  label_not_equals: ist nicht
+  label_open_issues: offen
+  label_open_issues_plural: offen
+  label_optional_description: Beschreibung (optional)
+  label_options: Optionen
+  label_overall_activity: AktivitÃ¤ten aller Projekte anzeigen
+  label_overall_spent_time: Aufgewendete Zeit aller Projekte anzeigen
+  label_overview: Ãœbersicht
+  label_parent_revision: VorgÃ¤nger
+  label_password_lost: Kennwort vergessen
+  label_per_page: Pro Seite
+  label_permissions: Berechtigungen
+  label_permissions_report: BerechtigungsÃ¼bersicht
+  label_personalize_page: Diese Seite anpassen
+  label_planning: Terminplanung
+  label_please_login: Anmelden
+  label_plugins: Plugins
+  label_precedes: VorgÃ¤nger von
+  label_preferences: PrÃ¤ferenzen
+  label_preview: Vorschau
+  label_previous: ZurÃ¼ck
+  label_principal_search: "Nach Benutzer oder Gruppe suchen:"
+  label_profile: Profil
+  label_project: Projekt
+  label_project_all: Alle Projekte
+  label_project_copy_notifications: Sende Mailbenachrichtigungen beim Kopieren des Projekts.
+  label_project_latest: Neueste Projekte
+  label_project_new: Neues Projekt
+  label_project_plural: Projekte
+  label_public_projects: Ã–ffentliche Projekte
+  label_query: Benutzerdefinierte Abfrage
+  label_query_new: Neue Abfrage
+  label_query_plural: Benutzerdefinierte Abfragen
+  label_read: Lesen...
+  label_readonly: Nur-Lese-Zugriff
+  label_register: Registrieren
+  label_registered_on: Angemeldet am
+  label_registration_activation_by_email: Kontoaktivierung durch E-Mail
+  label_registration_automatic_activation: Automatische Kontoaktivierung
+  label_registration_manual_activation: Manuelle Kontoaktivierung
+  label_related_issues: ZugehÃ¶rige Tickets
+  label_relates_to: Beziehung mit
+  label_relation_delete: Beziehung lÃ¶schen
+  label_relation_new: Neue Beziehung
+  label_renamed: umbenannt
+  label_reply_plural: Antworten
+  label_report: Bericht
+  label_report_plural: Berichte
+  label_reported_issues: Erstellte Tickets
+  label_repository: Projektarchiv
+  label_repository_new: Neues Repository
+  label_repository_plural: Projektarchive
+  label_required: Erforderlich
+  label_result_plural: Resultate
+  label_reverse_chronological_order: in umgekehrter zeitlicher Reihenfolge
+  label_revision: Revision
+  label_revision_id: Revision %{value}
+  label_revision_plural: Revisionen
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "FÃ¤llig in %{value}"
+  label_roadmap_no_issues: Keine Tickets fÃ¼r diese Version
+  label_roadmap_overdue: "%{value} verspÃ¤tet"
+  label_role: Rolle
+  label_role_and_permissions: Rollen und Rechte
+  label_role_anonymous: Anonymous
+  label_role_new: Neue Rolle
+  label_role_non_member: Nichtmitglied
+  label_role_plural: Rollen
+  label_scm: Versionskontrollsystem
+  label_search: Suche
+  label_search_for_watchers: Nach hinzufÃ¼gbaren Beobachtern suchen
+  label_search_titles_only: Nur Titel durchsuchen
+  label_send_information: Sende Kontoinformationen an Benutzer
+  label_send_test_email: Test-E-Mail senden
+  label_session_expiration: Ende einer Sitzung
+  label_settings: Konfiguration
+  label_show_closed_projects: Geschlossene Projekte anzeigen
+  label_show_completed_versions: Abgeschlossene Versionen anzeigen
+  label_sort: Sortierung
+  label_sort_by: "Sortiert nach %{value}"
+  label_sort_higher: Eins hÃ¶her
+  label_sort_highest: An den Anfang
+  label_sort_lower: Eins tiefer
+  label_sort_lowest: Ans Ende
+  label_spent_time: Aufgewendete Zeit
+  label_start_to_end: Anfang - Ende
+  label_start_to_start: Anfang - Anfang
+  label_statistics: Statistiken
+  label_status_transitions: StatusÃ¤nderungen
+  label_stay_logged_in: Angemeldet bleiben
+  label_string: Text
+  label_subproject_new: Neues Unterprojekt
+  label_subproject_plural: Unterprojekte
+  label_subtask_plural: Unteraufgaben
+  label_tag: Markierung
+  label_text: Langer Text
+  label_theme: Stil
+  label_this_month: aktueller Monat
+  label_this_week: aktuelle Woche
+  label_this_year: aktuelles Jahr
+  label_time_entry_plural: BenÃ¶tigte Zeit
+  label_time_tracking: Zeiterfassung
+  label_today: heute
+  label_topic_plural: Themen
+  label_total: Gesamtzahl
+  label_tracker: Tracker
+  label_tracker_new: Neuer Tracker
+  label_tracker_plural: Tracker
+  label_update_issue_done_ratios: Ticket-Fortschritt aktualisieren
+  label_updated_time: "Vor %{value} aktualisiert"
+  label_updated_time_by: "Von %{author} vor %{age} aktualisiert"
+  label_used_by: Benutzt von
+  label_user: Benutzer
+  label_user_activity: "AktivitÃ¤t von %{value}"
+  label_user_anonymous: Anonym
+  label_user_mail_no_self_notified: "Ich mÃ¶chte nicht Ã¼ber Ã„nderungen benachrichtigt werden, die ich selbst durchfÃ¼hre."
+  label_user_mail_option_all: "FÃ¼r alle Ereignisse in all meinen Projekten"
+  label_user_mail_option_none: Keine Ereignisse
+  label_user_mail_option_only_assigned: Nur fÃ¼r Aufgaben fÃ¼r die ich zustÃ¤ndig bin
+  label_user_mail_option_only_my_events: Nur fÃ¼r Aufgaben die ich beobachte oder an welchen ich mitarbeite
+  label_user_mail_option_only_owner: Nur fÃ¼r Aufgaben die ich angelegt habe
+  label_user_mail_option_selected: "FÃ¼r alle Ereignisse in den ausgewÃ¤hlten Projekten..."
+  label_user_new: Neuer Benutzer
+  label_user_plural: Benutzer
+  label_user_search: "Nach Benutzer suchen:"
+  label_version: Version
+  label_version_new: Neue Version
+  label_version_plural: Versionen
+  label_version_sharing_descendants: Mit Unterprojekten
+  label_version_sharing_hierarchy: Mit Projekthierarchie
+  label_version_sharing_none: Nicht gemeinsam verwenden
+  label_version_sharing_system: Mit allen Projekten
+  label_version_sharing_tree: Mit Projektbaum
+  label_view_all_revisions: Alle Revisionen anzeigen
+  label_view_diff: Unterschiede anzeigen
+  label_view_revisions: Revisionen anzeigen
+  label_watched_issues: Beobachtete Tickets
+  label_week: Woche
+  label_wiki: Wiki
+  label_wiki_content_added: Wiki-Seite hinzugefÃ¼gt
+  label_wiki_content_updated: Wiki-Seite aktualisiert
+  label_wiki_edit: Wiki-Bearbeitung
+  label_wiki_edit_plural: Wiki-Bearbeitungen
+  label_wiki_page: Wiki-Seite
+  label_wiki_page_plural: Wiki-Seiten
+  label_workflow: Workflow
+  label_x_closed_issues_abbr:
+    zero:  0 geschlossen
+    one:   1 geschlossen
+    other: "%{count} geschlossen"
+  label_x_comments:
+    zero: keine Kommentare
+    one: 1 Kommentar
+    other: "%{count} Kommentare"
+  label_x_issues:
+    zero:  0 Tickets
+    one:   1 Ticket
+    other: "%{count} Tickets"
+  label_x_open_issues_abbr:
+    zero:  0 offen
+    one:   1 offen
+    other: "%{count} offen"
+  label_x_open_issues_abbr_on_total:
+    zero:  0 offen / %{total}
+    one:   1 offen / %{total}
+    other: "%{count} offen / %{total}"
+  label_x_projects:
+    zero:  keine Projekte
+    one:   1 Projekt
+    other: "%{count} Projekte"
+  label_year: Jahr
+  label_yesterday: gestern
+
+  mail_body_account_activation_request: "Ein neuer Benutzer (%{value}) hat sich registriert. Sein Konto wartet auf Ihre Genehmigung:"
+  mail_body_account_information: Ihre Konto-Informationen
+  mail_body_account_information_external: "Sie kÃ¶nnen sich mit Ihrem Konto %{value} anmelden."
+  mail_body_lost_password: 'Benutzen Sie den folgenden Link, um Ihr Kennwort zu Ã¤ndern:'
+  mail_body_register: 'Um Ihr Konto zu aktivieren, benutzen Sie folgenden Link:'
+  mail_body_reminder: "%{count} Tickets, die Ihnen zugewiesen sind, mÃ¼ssen in den nÃ¤chsten %{days} Tagen abgegeben werden:"
+  mail_body_wiki_content_added: "Die Wiki-Seite '%{id}' wurde von %{author} hinzugefÃ¼gt."
+  mail_body_wiki_content_updated: "Die Wiki-Seite '%{id}' wurde von %{author} aktualisiert."
+  mail_subject_account_activation_request: "Antrag auf %{value} Kontoaktivierung"
+  mail_subject_lost_password: "Ihr %{value} Kennwort"
+  mail_subject_register: "%{value} Kontoaktivierung"
+  mail_subject_reminder: "%{count} Tickets mÃ¼ssen in den nÃ¤chsten %{days} Tagen abgegeben werden"
+  mail_subject_wiki_content_added: "Wiki-Seite '%{id}' hinzugefÃ¼gt"
+  mail_subject_wiki_content_updated: "Wiki-Seite '%{id}' erfolgreich aktualisiert"
+
+  notice_account_activated: Ihr Konto ist aktiviert. Sie kÃ¶nnen sich jetzt anmelden.
+  notice_account_deleted: Ihr Benutzerkonto wurde unwiderruflich gelÃ¶scht.
+  notice_account_invalid_creditentials: Benutzer oder Kennwort ist ungÃ¼ltig.
+  notice_account_lost_email_sent: Eine E-Mail mit Anweisungen, ein neues Kennwort zu wÃ¤hlen, wurde Ihnen geschickt.
+  notice_account_password_updated: Kennwort wurde erfolgreich aktualisiert.
+  notice_account_pending: "Ihr Konto wurde erstellt und wartet jetzt auf die Genehmigung des Administrators."
+  notice_account_register_done: Konto wurde erfolgreich angelegt.
+  notice_account_unknown_email: Unbekannter Benutzer.
+  notice_account_updated: Konto wurde erfolgreich aktualisiert.
+  notice_account_wrong_password: Falsches Kennwort.
+  notice_api_access_key_reseted: Ihr API-ZugriffsschlÃ¼ssel wurde zurÃ¼ckgesetzt.
+  notice_can_t_change_password: Dieses Konto verwendet eine externe Authentifizierungs-Quelle. UnmÃ¶glich, das Kennwort zu Ã¤ndern.
+  notice_default_data_loaded: Die Standard-Konfiguration wurde erfolgreich geladen.
+  notice_email_error: "Beim Senden einer E-Mail ist ein Fehler aufgetreten (%{value})."
+  notice_email_sent: "Eine E-Mail wurde an %{value} gesendet."
+  notice_failed_to_save_issues: "%{count} von %{total} ausgewÃ¤hlten Tickets konnte(n) nicht gespeichert werden: %{ids}."
+  notice_failed_to_save_members: "Benutzer konnte nicht gespeichert werden: %{errors}."
+  notice_failed_to_save_time_entries: "Gescheitert %{count} ZeiteintrÃ¤ge fÃ¼r %{total} von ausgewÃ¤hlten: %{ids} zu speichern." 
+  notice_feeds_access_key_reseted: Ihr Atom-ZugriffsschlÃ¼ssel wurde zurÃ¼ckgesetzt.
+  notice_file_not_found: Anhang existiert nicht oder ist gelÃ¶scht worden.
+  notice_gantt_chart_truncated: Die Grafik ist unvollstÃ¤ndig, da das Maximum der anzeigbaren Aufgaben Ã¼berschritten wurde (%{max})
+  notice_issue_done_ratios_updated: Der Ticket-Fortschritt wurde aktualisiert.
+  notice_issue_successful_create: Ticket %{id} erstellt.
+  notice_issue_update_conflict: Das Ticket wurde von einem anderen Nutzer Ã¼berarbeitet wÃ¤hrend Ihrer Bearbeitung.
+  notice_locking_conflict: Datum wurde von einem anderen Benutzer geÃ¤ndert.
+  notice_no_issue_selected: "Kein Ticket ausgewÃ¤hlt! Bitte wÃ¤hlen Sie die Tickets, die Sie bearbeiten mÃ¶chten."
+  notice_not_authorized: Sie sind nicht berechtigt, auf diese Seite zuzugreifen.
+  notice_not_authorized_archived_project: Das Projekt wurde archiviert und ist daher nicht nicht verfÃ¼gbar.
+  notice_successful_connection: Verbindung erfolgreich.
+  notice_successful_create: Erfolgreich angelegt
+  notice_successful_delete: Erfolgreich gelÃ¶scht.
+  notice_successful_update: Erfolgreich aktualisiert.
+  notice_unable_delete_time_entry: Der Zeiterfassungseintrag konnte nicht gelÃ¶scht werden.
+  notice_unable_delete_version: Die Version konnte nicht gelÃ¶scht werden.
+  notice_user_successful_create: Benutzer %{id} angelegt.
+
+  permission_add_issue_notes: Kommentare hinzufÃ¼gen
+  permission_add_issue_watchers: Beobachter hinzufÃ¼gen
+  permission_add_issues: Tickets hinzufÃ¼gen
+  permission_add_messages: ForenbeitrÃ¤ge hinzufÃ¼gen
+  permission_add_project: Projekt erstellen
+  permission_add_subprojects: Unterprojekte erstellen
+  permission_add_documents: Dokumente hinzufÃ¼gen
+  permission_browse_repository: Projektarchiv ansehen
+  permission_close_project: SchlieÃŸen / erneutes Ã–ffnen eines Projekts
+  permission_comment_news: News kommentieren
+  permission_commit_access: Commit-Zugriff
+  permission_delete_issue_watchers: Beobachter lÃ¶schen
+  permission_delete_issues: Tickets lÃ¶schen
+  permission_delete_messages: ForenbeitrÃ¤ge lÃ¶schen
+  permission_delete_own_messages: Eigene ForenbeitrÃ¤ge lÃ¶schen
+  permission_delete_wiki_pages: Wiki-Seiten lÃ¶schen
+  permission_delete_wiki_pages_attachments: AnhÃ¤nge lÃ¶schen
+  permission_delete_documents: Dokumente lÃ¶schen
+  permission_edit_issue_notes: Kommentare bearbeiten
+  permission_edit_issues: Tickets bearbeiten
+  permission_edit_messages: ForenbeitrÃ¤ge bearbeiten
+  permission_edit_own_issue_notes: Eigene Kommentare bearbeiten
+  permission_edit_own_messages: Eigene ForenbeitrÃ¤ge bearbeiten
+  permission_edit_own_time_entries: Selbst gebuchte AufwÃ¤nde bearbeiten
+  permission_edit_project: Projekt bearbeiten
+  permission_edit_time_entries: Gebuchte AufwÃ¤nde bearbeiten
+  permission_edit_wiki_pages: Wiki-Seiten bearbeiten
+  permission_edit_documents: Dokumente bearbeiten
+  permission_export_wiki_pages: Wiki-Seiten exportieren
+  permission_log_time: AufwÃ¤nde buchen
+  permission_manage_boards: Foren verwalten
+  permission_manage_categories: Ticket-Kategorien verwalten
+  permission_manage_files: Dateien verwalten
+  permission_manage_issue_relations: Ticket-Beziehungen verwalten
+  permission_manage_members: Mitglieder verwalten
+  permission_manage_news: News verwalten
+  permission_manage_project_activities: AktivitÃ¤ten (Zeiterfassung) verwalten
+  permission_manage_public_queries: Ã–ffentliche Filter verwalten
+  permission_manage_related_issues: ZugehÃ¶rige Tickets verwalten
+  permission_manage_repository: Projektarchiv verwalten
+  permission_manage_subtasks: Unteraufgaben verwalten
+  permission_manage_versions: Versionen verwalten
+  permission_manage_wiki: Wiki verwalten
+  permission_move_issues: Tickets verschieben
+  permission_protect_wiki_pages: Wiki-Seiten schÃ¼tzen
+  permission_rename_wiki_pages: Wiki-Seiten umbenennen
+  permission_save_queries: Filter speichern
+  permission_select_project_modules: Projektmodule auswÃ¤hlen
+  permission_set_issues_private: Tickets privat oder Ã¶ffentlich markieren
+  permission_set_notes_private: Kommentar als privat markieren
+  permission_set_own_issues_private: Eigene Tickets privat oder Ã¶ffentlich markieren
+  permission_view_calendar: Kalender ansehen
+  permission_view_changesets: Changesets ansehen
+  permission_view_documents: Dokumente ansehen
+  permission_view_files: Dateien ansehen
+  permission_view_gantt: Gantt-Diagramm ansehen
+  permission_view_issue_watchers: Liste der Beobachter ansehen
+  permission_view_issues: Tickets anzeigen
+  permission_view_messages: ForenbeitrÃ¤ge ansehen
+  permission_view_private_notes: Private Kommentare sehen
+  permission_view_time_entries: Gebuchte AufwÃ¤nde ansehen
+  permission_view_wiki_edits: Wiki-Versionsgeschichte ansehen
+  permission_view_wiki_pages: Wiki ansehen
+
+  project_module_boards: Foren
+  project_module_calendar: Kalender
+  project_module_documents: Dokumente
+  project_module_files: Dateien
+  project_module_gantt: Gantt
+  project_module_issue_tracking: Ticket-Verfolgung
+  project_module_news: News
+  project_module_repository: Projektarchiv
+  project_module_time_tracking: Zeiterfassung
+  project_module_wiki: Wiki
+  project_status_active: aktiv
+  project_status_archived: archiviert
+  project_status_closed: geschlossen
+
+  setting_activity_days_default: Anzahl Tage pro Seite der Projekt-AktivitÃ¤t
+  setting_app_subtitle: Applikations-Untertitel
+  setting_app_title: Applikations-Titel
+  setting_attachment_max_size: Max. DateigrÃ¶ÃŸe
+  setting_autofetch_changesets: Changesets automatisch abrufen
+  setting_autologin: Automatische Anmeldung
+  setting_bcc_recipients: E-Mails als Blindkopie (BCC) senden
+  setting_cache_formatted_text: Formatierten Text im Cache speichern
+  setting_commit_cross_project_ref: Erlauben auf Tickets aller anderen Projekte zu referenzieren
+  setting_commit_fix_keywords: SchlÃ¼sselwÃ¶rter (Status)
+  setting_commit_logtime_activity_id: AktivitÃ¤t fÃ¼r die Zeiterfassung
+  setting_commit_logtime_enabled: Aktiviere Zeitlogging
+  setting_commit_ref_keywords: SchlÃ¼sselwÃ¶rter (Beziehungen)
+  setting_cross_project_issue_relations: Ticket-Beziehungen zwischen Projekten erlauben
+  setting_cross_project_subtasks: ProjektÃ¼bergreifende Unteraufgaben erlauben
+  setting_date_format: Datumsformat
+  setting_default_issue_start_date_to_creation_date: Aktuelles Datum als Beginn fÃ¼r neue Tickets verwenden
+  setting_default_language: Standardsprache
+  setting_default_notification_option: Standard Benachrichtigungsoptionen
+  setting_default_projects_modules: StandardmÃ¤ÃŸig aktivierte Module fÃ¼r neue Projekte
+  setting_default_projects_public: Neue Projekte sind standardmÃ¤ÃŸig Ã¶ffentlich
+  setting_diff_max_lines_displayed: Maximale Anzahl anzuzeigender Diff-Zeilen
+  setting_display_subprojects_issues: Tickets von Unterprojekten im Hauptprojekt anzeigen
+  setting_emails_footer: E-Mail-FuÃŸzeile
+  setting_emails_header: E-Mail-Kopfzeile
+  setting_enabled_scm: Aktivierte Versionskontrollsysteme
+  setting_feeds_limit: Max. Anzahl EintrÃ¤ge pro Atom-Feed
+  setting_file_max_size_displayed: Maximale GrÃ¶ÃŸe inline angezeigter Textdateien
+  setting_gantt_items_limit: Maximale Anzahl von Aufgaben die im Gantt-Chart angezeigt werden
+  setting_gravatar_default: Standard-Gravatar-Bild
+  setting_gravatar_enabled: Gravatar-Benutzerbilder benutzen
+  setting_host_name: Hostname
+  setting_issue_done_ratio: Berechne den Ticket-Fortschritt mittels
+  setting_issue_done_ratio_issue_field: Ticket-Feld %-erledigt
+  setting_issue_done_ratio_issue_status: Ticket-Status
+  setting_issue_group_assignment: Ticketzuweisung an Gruppen erlauben
+  setting_issue_list_default_columns: Standard-Spalten in der Ticket-Auflistung
+  setting_issues_export_limit: Max. Anzahl Tickets bei CSV/PDF-Export
+  setting_jsonp_enabled: JSONP UnterstÃ¼tzung aktivieren
+  setting_login_required: Authentifizierung erforderlich
+  setting_mail_from: E-Mail-Absender
+  setting_mail_handler_api_enabled: Abruf eingehender E-Mails aktivieren
+  setting_mail_handler_api_key: API-SchlÃ¼ssel
+  setting_mail_handler_body_delimiters: "Schneide E-Mails nach einer dieser Zeilen ab"
+  setting_new_project_user_role_id: Rolle, die einem Nicht-Administrator zugeordnet wird, der ein Projekt erstellt
+  setting_non_working_week_days: Arbeitsfreie Tage
+  setting_openid: Erlaube OpenID-Anmeldung und -Registrierung
+  setting_password_min_length: MindestlÃ¤nge des Kennworts
+  setting_per_page_options: Objekte pro Seite
+  setting_plain_text_mail: Nur reinen Text (kein HTML) senden
+  setting_protocol: Protokoll
+  setting_repositories_encodings: Enkodierung von AnhÃ¤ngen und Repositories
+  setting_repository_log_display_limit: Maximale Anzahl anzuzeigender Revisionen in der Historie einer Datei
+  setting_rest_api_enabled: REST-Schnittstelle aktivieren
+  setting_self_registration: Anmeldung ermÃ¶glicht
+  setting_sequential_project_identifiers: Fortlaufende Projektkennungen generieren
+  setting_session_lifetime: LÃ¤ngste Dauer einer Sitzung
+  setting_session_timeout: ZeitÃ¼berschreitung bei InaktivitÃ¤t
+  setting_start_of_week: Wochenanfang
+  setting_sys_api_enabled: Webservice zur Verwaltung der Projektarchive benutzen
+  setting_text_formatting: Textformatierung
+  setting_thumbnails_enabled: Vorschaubilder von DateianhÃ¤ngen anzeigen
+  setting_thumbnails_size: GrÃ¶ÃŸe der Vorschaubilder (in Pixel)
+  setting_time_format: Zeitformat
+  setting_unsubscribe: Erlaubt Benutzern das eigene Benutzerkonto zu lÃ¶schen
+  setting_user_format: Benutzer-Anzeigeformat
+  setting_welcome_text: Willkommenstext
+  setting_wiki_compression: Wiki-Historie komprimieren
+  setting_default_projects_tracker_ids: StandardmÃ¤ÃŸig aktivierte Tracker fÃ¼r neue Projekte
+
+  status_active: aktiv
+  status_locked: gesperrt
+  status_registered: nicht aktivierte
+
+  text_account_destroy_confirmation: MÃ¶chten Sie wirklich fortfahren?\nIhr Benutzerkonto wird fÃ¼r immer gelÃ¶scht und kann nicht wiederhergestellt werden.
+  text_are_you_sure: Sind Sie sicher?
+  text_assign_time_entries_to_project: Gebuchte AufwÃ¤nde dem Projekt zuweisen
+  text_caracters_maximum: "Max. %{count} Zeichen."
+  text_caracters_minimum: "Muss mindestens %{count} Zeichen lang sein."
+  text_comma_separated: Mehrere Werte erlaubt (durch Komma getrennt).
+  text_custom_field_possible_values_info: 'Eine Zeile pro Wert'
+  text_default_administrator_account_changed: Administrator-Kennwort geÃ¤ndert
+  text_destroy_time_entries: Gebuchte AufwÃ¤nde lÃ¶schen
+  text_destroy_time_entries_question: Es wurden bereits %{hours} Stunden auf dieses Ticket gebucht. Was soll mit den AufwÃ¤nden geschehen?
+  text_diff_truncated: '... Dieser Diff wurde abgeschnitten, weil er die maximale Anzahl anzuzeigender Zeilen Ã¼berschreitet.'
+  text_email_delivery_not_configured: "Der SMTP-Server ist nicht konfiguriert und Mailbenachrichtigungen sind ausgeschaltet.\nNehmen Sie die Einstellungen fÃ¼r Ihren SMTP-Server in config/configuration.yml vor und starten Sie die Applikation neu."
+  text_enumeration_category_reassign_to: 'Die Objekte stattdessen diesem Wert zuordnen:'
+  text_enumeration_destroy_question: "%{count} Objekt(e) sind diesem Wert zugeordnet."
+  text_file_repository_writable: Verzeichnis fÃ¼r Dateien beschreibbar
+  text_git_repository_note: Repository steht fÃ¼r sich alleine (bare) und liegt lokal (z.B. /gitrepo, c:\gitrepo)
+  text_issue_added: "Ticket %{id} wurde erstellt von %{author}."
+  text_issue_category_destroy_assignments: Kategorie-Zuordnung entfernen
+  text_issue_category_destroy_question: "Einige Tickets (%{count}) sind dieser Kategorie zugeodnet. Was mÃ¶chten Sie tun?"
+  text_issue_category_reassign_to: Tickets dieser Kategorie zuordnen
+  text_issue_conflict_resolution_add_notes: Meine Ã„nderungen Ã¼bernehmen und alle anderen Ã„nderungen verwerfen
+  text_issue_conflict_resolution_cancel: Meine Ã„nderungen verwerfen und %{link} neu anzeigen
+  text_issue_conflict_resolution_overwrite: Meine Ã„nderungen trotzdem Ã¼bernehmen (vorherige Notizen bleiben erhalten aber manche kÃ¶nnen Ã¼berschrieben werden)
+  text_issue_updated: "Ticket %{id} wurde aktualisiert von %{author}."
+  text_issues_destroy_confirmation: 'Sind Sie sicher, dass Sie die ausgewÃ¤hlten Tickets lÃ¶schen mÃ¶chten?'
+  text_issues_destroy_descendants_confirmation: Dies wird auch %{count} Unteraufgabe/n lÃ¶schen.
+  text_issues_ref_in_commit_messages: Ticket-Beziehungen und -Status in Commit-Log-Meldungen
+  text_journal_added: "%{label} %{value} wurde hinzugefÃ¼gt"
+  text_journal_changed: "%{label} wurde von %{old} zu %{new} geÃ¤ndert"
+  text_journal_changed_no_detail: "%{label} aktualisiert"
+  text_journal_deleted: "%{label} %{old} wurde gelÃ¶scht"
+  text_journal_set_to: "%{label} wurde auf %{value} gesetzt"
+  text_length_between: "LÃ¤nge zwischen %{min} und %{max} Zeichen."
+  text_line_separated: Mehrere Werte sind erlaubt (eine Zeile pro Wert).
+  text_load_default_configuration: Standard-Konfiguration laden
+  text_mercurial_repository_note: Lokales repository (e.g. /hgrepo, c:\hgrepo)
+  text_min_max_length_info: 0 heiÃŸt keine BeschrÃ¤nkung
+  text_no_configuration_data: "Rollen, Tracker, Ticket-Status und Workflows wurden noch nicht konfiguriert.\nEs ist sehr zu empfehlen, die Standard-Konfiguration zu laden. Sobald sie geladen ist, kÃ¶nnen Sie sie abÃ¤ndern."
+  text_own_membership_delete_confirmation: "Sie sind dabei, einige oder alle Ihre Berechtigungen zu entfernen. Es ist mÃ¶glich, dass Sie danach das Projekt nicht mehr ansehen oder bearbeiten dÃ¼rfen.\nSind Sie sicher, dass Sie dies tun mÃ¶chten?"
+  text_plugin_assets_writable: Verzeichnis fÃ¼r Plugin-Assets beschreibbar
+  text_project_closed: Dieses Projekt ist geschlossen und kann nicht bearbeitet werden.
+  text_project_destroy_confirmation: Sind Sie sicher, dass Sie das Projekt lÃ¶schen wollen?
+  text_project_identifier_info: 'Kleinbuchstaben (a-z), Ziffern, Binde- und Unterstriche erlaubt, muss mit einem Kleinbuchstaben beginnen.<br />Einmal gespeichert, kann die Kennung nicht mehr geÃ¤ndert werden.'
+  text_reassign_time_entries: 'Gebuchte AufwÃ¤nde diesem Ticket zuweisen:'
+  text_regexp_info: z. B. ^[A-Z0-9]+$
+  text_repository_identifier_info: 'Kleinbuchstaben (a-z), Ziffern, Binde- und Unterstriche erlaubt.<br />Einmal gespeichert, kann die Kennung nicht mehr geÃ¤ndert werden.'
+  text_repository_usernames_mapping: "Bitte legen Sie die Zuordnung der Redmine-Benutzer zu den Benutzernamen der Commit-Log-Meldungen des Projektarchivs fest.\nBenutzer mit identischen Redmine- und Projektarchiv-Benutzernamen oder -E-Mail-Adressen werden automatisch zugeordnet."
+  text_rmagick_available: RMagick verfÃ¼gbar (optional)
+  text_scm_command: Kommando
+  text_scm_command_not_available: SCM-Kommando ist nicht verfÃ¼gbar. Bitte prÃ¼fen Sie die Einstellungen im Administrationspanel.
+  text_scm_command_version: Version
+  text_scm_config: Die SCM-Kommandos kÃ¶nnen in der in config/configuration.yml konfiguriert werden. Redmine muss anschlieÃŸend neu gestartet werden.
+  text_scm_path_encoding_note: "Standard: UTF-8"
+  text_select_mail_notifications: Bitte wÃ¤hlen Sie die Aktionen aus, fÃ¼r die eine Mailbenachrichtigung gesendet werden soll.
+  text_select_project_modules: 'Bitte wÃ¤hlen Sie die Module aus, die in diesem Projekt aktiviert sein sollen:'
+  text_session_expiration_settings: "Achtung: Ã„nderungen kÃ¶nnen aktuelle Sitzungen beenden, Ihre eingeschlossen!" 
+  text_status_changed_by_changeset: "Status geÃ¤ndert durch Changeset %{value}."
+  text_subprojects_destroy_warning: "Dessen Unterprojekte (%{value}) werden ebenfalls gelÃ¶scht."
+  text_time_entries_destroy_confirmation: Sind Sie sicher, dass Sie die ausgewÃ¤hlten ZeitaufwÃ¤nde lÃ¶schen mÃ¶chten?
+  text_time_logged_by_changeset: Angewendet in Changeset %{value}.
+  text_tip_issue_begin_day: Aufgabe, die an diesem Tag beginnt
+  text_tip_issue_begin_end_day: Aufgabe, die an diesem Tag beginnt und endet
+  text_tip_issue_end_day: Aufgabe, die an diesem Tag endet
+  text_tracker_no_workflow: Kein Workflow fÃ¼r diesen Tracker definiert.
+  text_turning_multiple_off: Wenn Sie die Mehrfachauswahl deaktivieren, werden Felder mit Mehrfachauswahl bereinigt.
+    Dadurch wird sichergestellt, dass lediglich ein Wert pro Feld ausgewÃ¤hlt ist.
+  text_unallowed_characters: Nicht erlaubte Zeichen
+  text_user_mail_option: "FÃ¼r nicht ausgewÃ¤hlte Projekte werden Sie nur Benachrichtigungen fÃ¼r Dinge erhalten, die Sie beobachten oder an denen Sie beteiligt sind (z. B. Tickets, deren Autor Sie sind oder die Ihnen zugewiesen sind)."
+  text_user_wrote: "%{value} schrieb:"
+  text_warn_on_leaving_unsaved: Die aktuellen Ã„nderungen gehen verloren, wenn Sie diese Seite verlassen.
+  text_wiki_destroy_confirmation: Sind Sie sicher, dass Sie dieses Wiki mit sÃ¤mtlichem Inhalt lÃ¶schen mÃ¶chten?
+  text_wiki_page_destroy_children: LÃ¶sche alle Unterseiten
+  text_wiki_page_destroy_question: "Diese Seite hat %{descendants} Unterseite(n). Was mÃ¶chten Sie tun?"
+  text_wiki_page_nullify_children: Verschiebe die Unterseiten auf die oberste Ebene
+  text_wiki_page_reassign_children: Ordne die Unterseiten dieser Seite zu
+  text_workflow_edit: Workflow zum Bearbeiten auswÃ¤hlen
+  text_zoom_in: Ansicht vergrÃ¶ÃŸern
+  text_zoom_out: Ansicht verkleinern
+
+  version_status_closed: abgeschlossen
+  version_status_locked: gesperrt
+  version_status_open: offen
+
+  warning_attachments_not_saved: "%{count} Datei(en) konnten nicht gespeichert werden."
+  label_total_time: Gesamtzeit
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/32/3298e1c1ddf5d23eff798c7cd5979f9e2dc8ea9f.svn-base
--- /dev/null
+++ b/.svn/pristine/32/3298e1c1ddf5d23eff798c7cd5979f9e2dc8ea9f.svn-base
@@ -0,0 +1,212 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+begin
+  require 'mocha'
+rescue
+  # Won't run some tests
+end
+
+class AccountTest < ActionController::IntegrationTest
+  fixtures :users, :roles
+
+  # Replace this with your real tests.
+  def test_login
+    get "my/page"
+    assert_redirected_to "/login?back_url=http%3A%2F%2Fwww.example.com%2Fmy%2Fpage"
+    log_user('jsmith', 'jsmith')
+
+    get "my/account"
+    assert_response :success
+    assert_template "my/account"
+  end
+
+  def test_autologin
+    user = User.find(1)
+    Setting.autologin = "7"
+    Token.delete_all
+
+    # User logs in with 'autologin' checked
+    post '/login', :username => user.login, :password => 'admin', :autologin => 1
+    assert_redirected_to '/my/page'
+    token = Token.first
+    assert_not_nil token
+    assert_equal user, token.user
+    assert_equal 'autologin', token.action
+    assert_equal user.id, session[:user_id]
+    assert_equal token.value, cookies['autologin']
+
+    # Session is cleared
+    reset!
+    User.current = nil
+    # Clears user's last login timestamp
+    user.update_attribute :last_login_on, nil
+    assert_nil user.reload.last_login_on
+
+    # User comes back with his autologin cookie
+    cookies[:autologin] = token.value
+    get '/my/page'
+    assert_response :success
+    assert_template 'my/page'
+    assert_equal user.id, session[:user_id]
+    assert_not_nil user.reload.last_login_on
+  end
+
+  def test_autologin_should_use_autologin_cookie_name
+    Token.delete_all
+    Redmine::Configuration.stubs(:[]).with('autologin_cookie_name').returns('custom_autologin')
+    Redmine::Configuration.stubs(:[]).with('autologin_cookie_path').returns('/')
+    Redmine::Configuration.stubs(:[]).with('autologin_cookie_secure').returns(false)
+
+    with_settings :autologin => '7' do
+      assert_difference 'Token.count' do
+        post '/login', :username => 'admin', :password => 'admin', :autologin => 1
+      end
+      assert_response 302
+      assert cookies['custom_autologin'].present?
+      token = cookies['custom_autologin']
+  
+      # Session is cleared
+      reset!
+      cookies['custom_autologin'] = token
+      get '/my/page'
+      assert_response :success
+
+      assert_difference 'Token.count', -1 do
+        post '/logout'
+      end
+      assert cookies['custom_autologin'].blank?
+    end
+  end
+
+  def test_lost_password
+    Token.delete_all
+
+    get "account/lost_password"
+    assert_response :success
+    assert_template "account/lost_password"
+    assert_select 'input[name=mail]'
+
+    post "account/lost_password", :mail => 'jSmith@somenet.foo'
+    assert_redirected_to "/login"
+
+    token = Token.first
+    assert_equal 'recovery', token.action
+    assert_equal 'jsmith@somenet.foo', token.user.mail
+    assert !token.expired?
+
+    get "account/lost_password", :token => token.value
+    assert_response :success
+    assert_template "account/password_recovery"
+    assert_select 'input[type=hidden][name=token][value=?]', token.value
+    assert_select 'input[name=new_password]'
+    assert_select 'input[name=new_password_confirmation]'
+
+    post "account/lost_password", :token => token.value, :new_password => 'newpass123', :new_password_confirmation => 'newpass123'
+    assert_redirected_to "/login"
+    assert_equal 'Password was successfully updated.', flash[:notice]
+
+    log_user('jsmith', 'newpass123')
+    assert_equal 0, Token.count
+  end
+
+  def test_register_with_automatic_activation
+    Setting.self_registration = '3'
+
+    get 'account/register'
+    assert_response :success
+    assert_template 'account/register'
+
+    post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar",
+                             :password => "newpass123", :password_confirmation => "newpass123"}
+    assert_redirected_to '/my/account'
+    follow_redirect!
+    assert_response :success
+    assert_template 'my/account'
+
+    user = User.find_by_login('newuser')
+    assert_not_nil user
+    assert user.active?
+    assert_not_nil user.last_login_on
+  end
+
+  def test_register_with_manual_activation
+    Setting.self_registration = '2'
+
+    post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar",
+                             :password => "newpass123", :password_confirmation => "newpass123"}
+    assert_redirected_to '/login'
+    assert !User.find_by_login('newuser').active?
+  end
+
+  def test_register_with_email_activation
+    Setting.self_registration = '1'
+    Token.delete_all
+
+    post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar",
+                             :password => "newpass123", :password_confirmation => "newpass123"}
+    assert_redirected_to '/login'
+    assert !User.find_by_login('newuser').active?
+
+    token = Token.first
+    assert_equal 'register', token.action
+    assert_equal 'newuser@foo.bar', token.user.mail
+    assert !token.expired?
+
+    get 'account/activate', :token => token.value
+    assert_redirected_to '/login'
+    log_user('newuser', 'newpass123')
+  end
+
+  def test_onthefly_registration
+    # disable registration
+    Setting.self_registration = '0'
+    AuthSource.expects(:authenticate).returns({:login => 'foo', :firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com', :auth_source_id => 66})
+
+    post '/login', :username => 'foo', :password => 'bar'
+    assert_redirected_to '/my/page'
+
+    user = User.find_by_login('foo')
+    assert user.is_a?(User)
+    assert_equal 66, user.auth_source_id
+    assert user.hashed_password.blank?
+  end
+
+  def test_onthefly_registration_with_invalid_attributes
+    # disable registration
+    Setting.self_registration = '0'
+    AuthSource.expects(:authenticate).returns({:login => 'foo', :lastname => 'Smith', :auth_source_id => 66})
+
+    post '/login', :username => 'foo', :password => 'bar'
+    assert_response :success
+    assert_template 'account/register'
+    assert_tag :input, :attributes => { :name => 'user[firstname]', :value => '' }
+    assert_tag :input, :attributes => { :name => 'user[lastname]', :value => 'Smith' }
+    assert_no_tag :input, :attributes => { :name => 'user[login]' }
+    assert_no_tag :input, :attributes => { :name => 'user[password]' }
+
+    post 'account/register', :user => {:firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com'}
+    assert_redirected_to '/my/account'
+
+    user = User.find_by_login('foo')
+    assert user.is_a?(User)
+    assert_equal 66, user.auth_source_id
+    assert user.hashed_password.blank?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/32/32f548872e7dda9a87d4e449afcdf5184ca9059d.svn-base
--- a/.svn/pristine/32/32f548872e7dda9a87d4e449afcdf5184ca9059d.svn-base
+++ /dev/null
@@ -1,87 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array ("æ—¥æ›œæ—¥", "æœˆæ›œæ—¥", "ç«æ›œæ—¥", "æ°´æ›œæ—¥", "æœ¨æ›œæ—¥", "é‡‘æ›œæ—¥", "åœŸæ›œæ—¥");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array ("æ—¥", "æœˆ", "ç«", "æ°´", "æœ¨", "é‡‘", "åœŸ");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array ("1æœˆ", "2æœˆ", "3æœˆ", "4æœˆ", "5æœˆ", "6æœˆ", "7æœˆ", "8æœˆ", "9æœˆ", "10æœˆ", "11æœˆ", "12æœˆ");
-
-// short month names
-Calendar._SMN = new Array ("1æœˆ", "2æœˆ", "3æœˆ", "4æœˆ", "5æœˆ", "6æœˆ", "7æœˆ", "8æœˆ", "9æœˆ", "10æœˆ", "11æœˆ", "12æœˆ");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "ã“ã®ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼ã«ã¤ã„ã¦";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"æ—¥ä»˜ã®é¸æŠžæ–¹æ³•:\n" +
-"- \xab, \xbb ãƒœã‚¿ãƒ³ã§å¹´ã‚’é¸æŠžã€‚\n" +
-"- " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ãƒœã‚¿ãƒ³ã§å¹´ã‚’é¸æŠžã€‚\n" +
-"- ä¸Šè¨˜ãƒœã‚¿ãƒ³ã®é•·æŠ¼ã—ã§ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰é¸æŠžã€‚";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "å‰å¹´ (é•·æŠ¼ã—ã§ãƒ¡ãƒ‹ãƒ¥ãƒ¼è¡¨ç¤º)";
-Calendar._TT["PREV_MONTH"] = "å‰æœˆ (é•·æŠ¼ã—ã§ãƒ¡ãƒ‹ãƒ¥ãƒ¼è¡¨ç¤º)";
-Calendar._TT["GO_TODAY"] = "ä»Šæ—¥ã®æ—¥ä»˜ã‚’é¸æŠž";
-Calendar._TT["NEXT_MONTH"] = "ç¿Œæœˆ (é•·æŠ¼ã—ã§ãƒ¡ãƒ‹ãƒ¥ãƒ¼è¡¨ç¤º)";
-Calendar._TT["NEXT_YEAR"] = "ç¿Œå¹´ (é•·æŠ¼ã—ã§ãƒ¡ãƒ‹ãƒ¥ãƒ¼è¡¨ç¤º)";
-Calendar._TT["SEL_DATE"] = "æ—¥ä»˜ã‚’é¸æŠžã—ã¦ãã ã•ã„";
-Calendar._TT["DRAG_TO_MOVE"] = "ãƒ‰ãƒ©ãƒƒã‚°ã§ç§»å‹•";
-Calendar._TT["PART_TODAY"] = " (ä»Šæ—¥)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "%så§‹ã¾ã‚Šã§è¡¨ç¤º";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "é–‰ã˜ã‚‹";
-Calendar._TT["TODAY"] = "ä»Šæ—¥";
-Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%b%eæ—¥(%a)";
-
-Calendar._TT["WK"] = "é€±";
-Calendar._TT["TIME"] = "Time:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/33/3310ce8725bdb75d262ab89bf521469eb429b588.svn-base
--- /dev/null
+++ b/.svn/pristine/33/3310ce8725bdb75d262ab89bf521469eb429b588.svn-base
@@ -0,0 +1,771 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'active_record'
+require 'iconv' if RUBY_VERSION < '1.9'
+require 'pp'
+
+namespace :redmine do
+  desc 'Trac migration script'
+  task :migrate_from_trac => :environment do
+
+    module TracMigrate
+        TICKET_MAP = []
+
+        DEFAULT_STATUS = IssueStatus.default
+        assigned_status = IssueStatus.find_by_position(2)
+        resolved_status = IssueStatus.find_by_position(3)
+        feedback_status = IssueStatus.find_by_position(4)
+        closed_status = IssueStatus.where(:is_closed => true).first
+        STATUS_MAPPING = {'new' => DEFAULT_STATUS,
+                          'reopened' => feedback_status,
+                          'assigned' => assigned_status,
+                          'closed' => closed_status
+                          }
+
+        priorities = IssuePriority.all
+        DEFAULT_PRIORITY = priorities[0]
+        PRIORITY_MAPPING = {'lowest' => priorities[0],
+                            'low' => priorities[0],
+                            'normal' => priorities[1],
+                            'high' => priorities[2],
+                            'highest' => priorities[3],
+                            # ---
+                            'trivial' => priorities[0],
+                            'minor' => priorities[1],
+                            'major' => priorities[2],
+                            'critical' => priorities[3],
+                            'blocker' => priorities[4]
+                            }
+
+        TRACKER_BUG = Tracker.find_by_position(1)
+        TRACKER_FEATURE = Tracker.find_by_position(2)
+        DEFAULT_TRACKER = TRACKER_BUG
+        TRACKER_MAPPING = {'defect' => TRACKER_BUG,
+                           'enhancement' => TRACKER_FEATURE,
+                           'task' => TRACKER_FEATURE,
+                           'patch' =>TRACKER_FEATURE
+                           }
+
+        roles = Role.where(:builtin => 0).order('position ASC').all
+        manager_role = roles[0]
+        developer_role = roles[1]
+        DEFAULT_ROLE = roles.last
+        ROLE_MAPPING = {'admin' => manager_role,
+                        'developer' => developer_role
+                        }
+
+      class ::Time
+        class << self
+          alias :real_now :now
+          def now
+            real_now - @fake_diff.to_i
+          end
+          def fake(time)
+            @fake_diff = real_now - time
+            res = yield
+            @fake_diff = 0
+           res
+          end
+        end
+      end
+
+      class TracComponent < ActiveRecord::Base
+        self.table_name = :component
+      end
+
+      class TracMilestone < ActiveRecord::Base
+        self.table_name = :milestone
+        # If this attribute is set a milestone has a defined target timepoint
+        def due
+          if read_attribute(:due) && read_attribute(:due) > 0
+            Time.at(read_attribute(:due)).to_date
+          else
+            nil
+          end
+        end
+        # This is the real timepoint at which the milestone has finished.
+        def completed
+          if read_attribute(:completed) && read_attribute(:completed) > 0
+            Time.at(read_attribute(:completed)).to_date
+          else
+            nil
+          end
+        end
+
+        def description
+          # Attribute is named descr in Trac v0.8.x
+          has_attribute?(:descr) ? read_attribute(:descr) : read_attribute(:description)
+        end
+      end
+
+      class TracTicketCustom < ActiveRecord::Base
+        self.table_name = :ticket_custom
+      end
+
+      class TracAttachment < ActiveRecord::Base
+        self.table_name = :attachment
+        set_inheritance_column :none
+
+        def time; Time.at(read_attribute(:time)) end
+
+        def original_filename
+          filename
+        end
+
+        def content_type
+          ''
+        end
+
+        def exist?
+          File.file? trac_fullpath
+        end
+
+        def open
+          File.open("#{trac_fullpath}", 'rb') {|f|
+            @file = f
+            yield self
+          }
+        end
+
+        def read(*args)
+          @file.read(*args)
+        end
+
+        def description
+          read_attribute(:description).to_s.slice(0,255)
+        end
+
+      private
+        def trac_fullpath
+          attachment_type = read_attribute(:type)
+          trac_file = filename.gsub( /[^a-zA-Z0-9\-_\.!~*']/n ) {|x| sprintf('%%%02x', x[0]) }
+          "#{TracMigrate.trac_attachments_directory}/#{attachment_type}/#{id}/#{trac_file}"
+        end
+      end
+
+      class TracTicket < ActiveRecord::Base
+        self.table_name = :ticket
+        set_inheritance_column :none
+
+        # ticket changes: only migrate status changes and comments
+        has_many :ticket_changes, :class_name => "TracTicketChange", :foreign_key => :ticket
+        has_many :customs, :class_name => "TracTicketCustom", :foreign_key => :ticket
+
+        def attachments
+          TracMigrate::TracAttachment.all(:conditions => ["type = 'ticket' AND id = ?", self.id.to_s])
+        end
+
+        def ticket_type
+          read_attribute(:type)
+        end
+
+        def summary
+          read_attribute(:summary).blank? ? "(no subject)" : read_attribute(:summary)
+        end
+
+        def description
+          read_attribute(:description).blank? ? summary : read_attribute(:description)
+        end
+
+        def time; Time.at(read_attribute(:time)) end
+        def changetime; Time.at(read_attribute(:changetime)) end
+      end
+
+      class TracTicketChange < ActiveRecord::Base
+        self.table_name = :ticket_change
+
+        def self.columns
+          # Hides Trac field 'field' to prevent clash with AR field_changed? method (Rails 3.0)
+          super.select {|column| column.name.to_s != 'field'}
+        end
+
+        def time; Time.at(read_attribute(:time)) end
+      end
+
+      TRAC_WIKI_PAGES = %w(InterMapTxt InterTrac InterWiki RecentChanges SandBox TracAccessibility TracAdmin TracBackup TracBrowser TracCgi TracChangeset \
+                           TracEnvironment TracFastCgi TracGuide TracImport TracIni TracInstall TracInterfaceCustomization \
+                           TracLinks TracLogging TracModPython TracNotification TracPermissions TracPlugins TracQuery \
+                           TracReports TracRevisionLog TracRoadmap TracRss TracSearch TracStandalone TracSupport TracSyntaxColoring TracTickets \
+                           TracTicketsCustomFields TracTimeline TracUnicode TracUpgrade TracWiki WikiDeletePage WikiFormatting \
+                           WikiHtml WikiMacros WikiNewPage WikiPageNames WikiProcessors WikiRestructuredText WikiRestructuredTextLinks \
+                           CamelCase TitleIndex)
+
+      class TracWikiPage < ActiveRecord::Base
+        self.table_name = :wiki
+        set_primary_key :name
+
+        def self.columns
+          # Hides readonly Trac field to prevent clash with AR readonly? method (Rails 2.0)
+          super.select {|column| column.name.to_s != 'readonly'}
+        end
+
+        def attachments
+          TracMigrate::TracAttachment.all(:conditions => ["type = 'wiki' AND id = ?", self.id.to_s])
+        end
+
+        def time; Time.at(read_attribute(:time)) end
+      end
+
+      class TracPermission < ActiveRecord::Base
+        self.table_name = :permission
+      end
+
+      class TracSessionAttribute < ActiveRecord::Base
+        self.table_name = :session_attribute
+      end
+
+      def self.find_or_create_user(username, project_member = false)
+        return User.anonymous if username.blank?
+
+        u = User.find_by_login(username)
+        if !u
+          # Create a new user if not found
+          mail = username[0, User::MAIL_LENGTH_LIMIT]
+          if mail_attr = TracSessionAttribute.find_by_sid_and_name(username, 'email')
+            mail = mail_attr.value
+          end
+          mail = "#{mail}@foo.bar" unless mail.include?("@")
+
+          name = username
+          if name_attr = TracSessionAttribute.find_by_sid_and_name(username, 'name')
+            name = name_attr.value
+          end
+          name =~ (/(.*)(\s+\w+)?/)
+          fn = $1.strip
+          ln = ($2 || '-').strip
+
+          u = User.new :mail => mail.gsub(/[^-@a-z0-9\.]/i, '-'),
+                       :firstname => fn[0, limit_for(User, 'firstname')],
+                       :lastname => ln[0, limit_for(User, 'lastname')]
+
+          u.login = username[0, User::LOGIN_LENGTH_LIMIT].gsub(/[^a-z0-9_\-@\.]/i, '-')
+          u.password = 'trac'
+          u.admin = true if TracPermission.find_by_username_and_action(username, 'admin')
+          # finally, a default user is used if the new user is not valid
+          u = User.first unless u.save
+        end
+        # Make sure he is a member of the project
+        if project_member && !u.member_of?(@target_project)
+          role = DEFAULT_ROLE
+          if u.admin
+            role = ROLE_MAPPING['admin']
+          elsif TracPermission.find_by_username_and_action(username, 'developer')
+            role = ROLE_MAPPING['developer']
+          end
+          Member.create(:user => u, :project => @target_project, :roles => [role])
+          u.reload
+        end
+        u
+      end
+
+      # Basic wiki syntax conversion
+      def self.convert_wiki_text(text)
+        # Titles
+        text = text.gsub(/^(\=+)\s(.+)\s(\=+)/) {|s| "\nh#{$1.length}. #{$2}\n"}
+        # External Links
+        text = text.gsub(/\[(http[^\s]+)\s+([^\]]+)\]/) {|s| "\"#{$2}\":#{$1}"}
+        # Ticket links:
+        #      [ticket:234 Text],[ticket:234 This is a test]
+        text = text.gsub(/\[ticket\:([^\ ]+)\ (.+?)\]/, '"\2":/issues/show/\1')
+        #      ticket:1234
+        #      #1 is working cause Redmine uses the same syntax.
+        text = text.gsub(/ticket\:([^\ ]+)/, '#\1')
+        # Milestone links:
+        #      [milestone:"0.1.0 Mercury" Milestone 0.1.0 (Mercury)]
+        #      The text "Milestone 0.1.0 (Mercury)" is not converted,
+        #      cause Redmine's wiki does not support this.
+        text = text.gsub(/\[milestone\:\"([^\"]+)\"\ (.+?)\]/, 'version:"\1"')
+        #      [milestone:"0.1.0 Mercury"]
+        text = text.gsub(/\[milestone\:\"([^\"]+)\"\]/, 'version:"\1"')
+        text = text.gsub(/milestone\:\"([^\"]+)\"/, 'version:"\1"')
+        #      milestone:0.1.0
+        text = text.gsub(/\[milestone\:([^\ ]+)\]/, 'version:\1')
+        text = text.gsub(/milestone\:([^\ ]+)/, 'version:\1')
+        # Internal Links
+        text = text.gsub(/\[\[BR\]\]/, "\n") # This has to go before the rules below
+        text = text.gsub(/\[\"(.+)\".*\]/) {|s| "[[#{$1.delete(',./?;|:')}]]"}
+        text = text.gsub(/\[wiki:\"(.+)\".*\]/) {|s| "[[#{$1.delete(',./?;|:')}]]"}
+        text = text.gsub(/\[wiki:\"(.+)\".*\]/) {|s| "[[#{$1.delete(',./?;|:')}]]"}
+        text = text.gsub(/\[wiki:([^\s\]]+)\]/) {|s| "[[#{$1.delete(',./?;|:')}]]"}
+        text = text.gsub(/\[wiki:([^\s\]]+)\s(.*)\]/) {|s| "[[#{$1.delete(',./?;|:')}|#{$2.delete(',./?;|:')}]]"}
+
+  # Links to pages UsingJustWikiCaps
+  text = text.gsub(/([^!]|^)(^| )([A-Z][a-z]+[A-Z][a-zA-Z]+)/, '\\1\\2[[\3]]')
+  # Normalize things that were supposed to not be links
+  # like !NotALink
+  text = text.gsub(/(^| )!([A-Z][A-Za-z]+)/, '\1\2')
+        # Revisions links
+        text = text.gsub(/\[(\d+)\]/, 'r\1')
+        # Ticket number re-writing
+        text = text.gsub(/#(\d+)/) do |s|
+          if $1.length < 10
+#            TICKET_MAP[$1.to_i] ||= $1
+            "\##{TICKET_MAP[$1.to_i] || $1}"
+          else
+            s
+          end
+        end
+        # We would like to convert the Code highlighting too
+        # This will go into the next line.
+        shebang_line = false
+        # Reguar expression for start of code
+        pre_re = /\{\{\{/
+        # Code hightlighing...
+        shebang_re = /^\#\!([a-z]+)/
+        # Regular expression for end of code
+        pre_end_re = /\}\}\}/
+
+        # Go through the whole text..extract it line by line
+        text = text.gsub(/^(.*)$/) do |line|
+          m_pre = pre_re.match(line)
+          if m_pre
+            line = '<pre>'
+          else
+            m_sl = shebang_re.match(line)
+            if m_sl
+              shebang_line = true
+              line = '<code class="' + m_sl[1] + '">'
+            end
+            m_pre_end = pre_end_re.match(line)
+            if m_pre_end
+              line = '</pre>'
+              if shebang_line
+                line = '</code>' + line
+              end
+            end
+          end
+          line
+        end
+
+        # Highlighting
+        text = text.gsub(/'''''([^\s])/, '_*\1')
+        text = text.gsub(/([^\s])'''''/, '\1*_')
+        text = text.gsub(/'''/, '*')
+        text = text.gsub(/''/, '_')
+        text = text.gsub(/__/, '+')
+        text = text.gsub(/~~/, '-')
+        text = text.gsub(/`/, '@')
+        text = text.gsub(/,,/, '~')
+        # Lists
+        text = text.gsub(/^([ ]+)\* /) {|s| '*' * $1.length + " "}
+
+        text
+      end
+
+      def self.migrate
+        establish_connection
+
+        # Quick database test
+        TracComponent.count
+
+        migrated_components = 0
+        migrated_milestones = 0
+        migrated_tickets = 0
+        migrated_custom_values = 0
+        migrated_ticket_attachments = 0
+        migrated_wiki_edits = 0
+        migrated_wiki_attachments = 0
+
+        #Wiki system initializing...
+        @target_project.wiki.destroy if @target_project.wiki
+        @target_project.reload
+        wiki = Wiki.new(:project => @target_project, :start_page => 'WikiStart')
+        wiki_edit_count = 0
+
+        # Components
+        print "Migrating components"
+        issues_category_map = {}
+        TracComponent.all.each do |component|
+        print '.'
+        STDOUT.flush
+          c = IssueCategory.new :project => @target_project,
+                                :name => encode(component.name[0, limit_for(IssueCategory, 'name')])
+        next unless c.save
+        issues_category_map[component.name] = c
+        migrated_components += 1
+        end
+        puts
+
+        # Milestones
+        print "Migrating milestones"
+        version_map = {}
+        TracMilestone.all.each do |milestone|
+          print '.'
+          STDOUT.flush
+          # First we try to find the wiki page...
+          p = wiki.find_or_new_page(milestone.name.to_s)
+          p.content = WikiContent.new(:page => p) if p.new_record?
+          p.content.text = milestone.description.to_s
+          p.content.author = find_or_create_user('trac')
+          p.content.comments = 'Milestone'
+          p.save
+
+          v = Version.new :project => @target_project,
+                          :name => encode(milestone.name[0, limit_for(Version, 'name')]),
+                          :description => nil,
+                          :wiki_page_title => milestone.name.to_s,
+                          :effective_date => milestone.completed
+
+          next unless v.save
+          version_map[milestone.name] = v
+          migrated_milestones += 1
+        end
+        puts
+
+        # Custom fields
+        # TODO: read trac.ini instead
+        print "Migrating custom fields"
+        custom_field_map = {}
+        TracTicketCustom.find_by_sql("SELECT DISTINCT name FROM #{TracTicketCustom.table_name}").each do |field|
+          print '.'
+          STDOUT.flush
+          # Redmine custom field name
+          field_name = encode(field.name[0, limit_for(IssueCustomField, 'name')]).humanize
+          # Find if the custom already exists in Redmine
+          f = IssueCustomField.find_by_name(field_name)
+          # Or create a new one
+          f ||= IssueCustomField.create(:name => encode(field.name[0, limit_for(IssueCustomField, 'name')]).humanize,
+                                        :field_format => 'string')
+
+          next if f.new_record?
+          f.trackers = Tracker.all
+          f.projects << @target_project
+          custom_field_map[field.name] = f
+        end
+        puts
+
+        # Trac 'resolution' field as a Redmine custom field
+        r = IssueCustomField.where(:name => "Resolution").first
+        r = IssueCustomField.new(:name => 'Resolution',
+                                 :field_format => 'list',
+                                 :is_filter => true) if r.nil?
+        r.trackers = Tracker.all
+        r.projects << @target_project
+        r.possible_values = (r.possible_values + %w(fixed invalid wontfix duplicate worksforme)).flatten.compact.uniq
+        r.save!
+        custom_field_map['resolution'] = r
+
+        # Tickets
+        print "Migrating tickets"
+          TracTicket.find_each(:batch_size => 200) do |ticket|
+          print '.'
+          STDOUT.flush
+          i = Issue.new :project => @target_project,
+                          :subject => encode(ticket.summary[0, limit_for(Issue, 'subject')]),
+                          :description => convert_wiki_text(encode(ticket.description)),
+                          :priority => PRIORITY_MAPPING[ticket.priority] || DEFAULT_PRIORITY,
+                          :created_on => ticket.time
+          i.author = find_or_create_user(ticket.reporter)
+          i.category = issues_category_map[ticket.component] unless ticket.component.blank?
+          i.fixed_version = version_map[ticket.milestone] unless ticket.milestone.blank?
+          i.status = STATUS_MAPPING[ticket.status] || DEFAULT_STATUS
+          i.tracker = TRACKER_MAPPING[ticket.ticket_type] || DEFAULT_TRACKER
+          i.id = ticket.id unless Issue.exists?(ticket.id)
+          next unless Time.fake(ticket.changetime) { i.save }
+          TICKET_MAP[ticket.id] = i.id
+          migrated_tickets += 1
+
+          # Owner
+            unless ticket.owner.blank?
+              i.assigned_to = find_or_create_user(ticket.owner, true)
+              Time.fake(ticket.changetime) { i.save }
+            end
+
+          # Comments and status/resolution changes
+          ticket.ticket_changes.group_by(&:time).each do |time, changeset|
+              status_change = changeset.select {|change| change.field == 'status'}.first
+              resolution_change = changeset.select {|change| change.field == 'resolution'}.first
+              comment_change = changeset.select {|change| change.field == 'comment'}.first
+
+              n = Journal.new :notes => (comment_change ? convert_wiki_text(encode(comment_change.newvalue)) : ''),
+                              :created_on => time
+              n.user = find_or_create_user(changeset.first.author)
+              n.journalized = i
+              if status_change &&
+                   STATUS_MAPPING[status_change.oldvalue] &&
+                   STATUS_MAPPING[status_change.newvalue] &&
+                   (STATUS_MAPPING[status_change.oldvalue] != STATUS_MAPPING[status_change.newvalue])
+                n.details << JournalDetail.new(:property => 'attr',
+                                               :prop_key => 'status_id',
+                                               :old_value => STATUS_MAPPING[status_change.oldvalue].id,
+                                               :value => STATUS_MAPPING[status_change.newvalue].id)
+              end
+              if resolution_change
+                n.details << JournalDetail.new(:property => 'cf',
+                                               :prop_key => custom_field_map['resolution'].id,
+                                               :old_value => resolution_change.oldvalue,
+                                               :value => resolution_change.newvalue)
+              end
+              n.save unless n.details.empty? && n.notes.blank?
+          end
+
+          # Attachments
+          ticket.attachments.each do |attachment|
+            next unless attachment.exist?
+              attachment.open {
+                a = Attachment.new :created_on => attachment.time
+                a.file = attachment
+                a.author = find_or_create_user(attachment.author)
+                a.container = i
+                a.description = attachment.description
+                migrated_ticket_attachments += 1 if a.save
+              }
+          end
+
+          # Custom fields
+          custom_values = ticket.customs.inject({}) do |h, custom|
+            if custom_field = custom_field_map[custom.name]
+              h[custom_field.id] = custom.value
+              migrated_custom_values += 1
+            end
+            h
+          end
+          if custom_field_map['resolution'] && !ticket.resolution.blank?
+            custom_values[custom_field_map['resolution'].id] = ticket.resolution
+          end
+          i.custom_field_values = custom_values
+          i.save_custom_field_values
+        end
+
+        # update issue id sequence if needed (postgresql)
+        Issue.connection.reset_pk_sequence!(Issue.table_name) if Issue.connection.respond_to?('reset_pk_sequence!')
+        puts
+
+        # Wiki
+        print "Migrating wiki"
+        if wiki.save
+          TracWikiPage.order('name, version').all.each do |page|
+            # Do not migrate Trac manual wiki pages
+            next if TRAC_WIKI_PAGES.include?(page.name)
+            wiki_edit_count += 1
+            print '.'
+            STDOUT.flush
+            p = wiki.find_or_new_page(page.name)
+            p.content = WikiContent.new(:page => p) if p.new_record?
+            p.content.text = page.text
+            p.content.author = find_or_create_user(page.author) unless page.author.blank? || page.author == 'trac'
+            p.content.comments = page.comment
+            Time.fake(page.time) { p.new_record? ? p.save : p.content.save }
+
+            next if p.content.new_record?
+            migrated_wiki_edits += 1
+
+            # Attachments
+            page.attachments.each do |attachment|
+              next unless attachment.exist?
+              next if p.attachments.find_by_filename(attachment.filename.gsub(/^.*(\\|\/)/, '').gsub(/[^\w\.\-]/,'_')) #add only once per page
+              attachment.open {
+                a = Attachment.new :created_on => attachment.time
+                a.file = attachment
+                a.author = find_or_create_user(attachment.author)
+                a.description = attachment.description
+                a.container = p
+                migrated_wiki_attachments += 1 if a.save
+              }
+            end
+          end
+
+          wiki.reload
+          wiki.pages.each do |page|
+            page.content.text = convert_wiki_text(page.content.text)
+            Time.fake(page.content.updated_on) { page.content.save }
+          end
+        end
+        puts
+
+        puts
+        puts "Components:      #{migrated_components}/#{TracComponent.count}"
+        puts "Milestones:      #{migrated_milestones}/#{TracMilestone.count}"
+        puts "Tickets:         #{migrated_tickets}/#{TracTicket.count}"
+        puts "Ticket files:    #{migrated_ticket_attachments}/" + TracAttachment.count(:conditions => {:type => 'ticket'}).to_s
+        puts "Custom values:   #{migrated_custom_values}/#{TracTicketCustom.count}"
+        puts "Wiki edits:      #{migrated_wiki_edits}/#{wiki_edit_count}"
+        puts "Wiki files:      #{migrated_wiki_attachments}/" + TracAttachment.count(:conditions => {:type => 'wiki'}).to_s
+      end
+
+      def self.limit_for(klass, attribute)
+        klass.columns_hash[attribute.to_s].limit
+      end
+
+      def self.encoding(charset)
+        @charset = charset
+      end
+
+      def self.set_trac_directory(path)
+        @@trac_directory = path
+        raise "This directory doesn't exist!" unless File.directory?(path)
+        raise "#{trac_attachments_directory} doesn't exist!" unless File.directory?(trac_attachments_directory)
+        @@trac_directory
+      rescue Exception => e
+        puts e
+        return false
+      end
+
+      def self.trac_directory
+        @@trac_directory
+      end
+
+      def self.set_trac_adapter(adapter)
+        return false if adapter.blank?
+        raise "Unknown adapter: #{adapter}!" unless %w(sqlite3 mysql postgresql).include?(adapter)
+        # If adapter is sqlite or sqlite3, make sure that trac.db exists
+        raise "#{trac_db_path} doesn't exist!" if %w(sqlite3).include?(adapter) && !File.exist?(trac_db_path)
+        @@trac_adapter = adapter
+      rescue Exception => e
+        puts e
+        return false
+      end
+
+      def self.set_trac_db_host(host)
+        return nil if host.blank?
+        @@trac_db_host = host
+      end
+
+      def self.set_trac_db_port(port)
+        return nil if port.to_i == 0
+        @@trac_db_port = port.to_i
+      end
+
+      def self.set_trac_db_name(name)
+        return nil if name.blank?
+        @@trac_db_name = name
+      end
+
+      def self.set_trac_db_username(username)
+        @@trac_db_username = username
+      end
+
+      def self.set_trac_db_password(password)
+        @@trac_db_password = password
+      end
+
+      def self.set_trac_db_schema(schema)
+        @@trac_db_schema = schema
+      end
+
+      mattr_reader :trac_directory, :trac_adapter, :trac_db_host, :trac_db_port, :trac_db_name, :trac_db_schema, :trac_db_username, :trac_db_password
+
+      def self.trac_db_path; "#{trac_directory}/db/trac.db" end
+      def self.trac_attachments_directory; "#{trac_directory}/attachments" end
+
+      def self.target_project_identifier(identifier)
+        project = Project.find_by_identifier(identifier)
+        if !project
+          # create the target project
+          project = Project.new :name => identifier.humanize,
+                                :description => ''
+          project.identifier = identifier
+          puts "Unable to create a project with identifier '#{identifier}'!" unless project.save
+          # enable issues and wiki for the created project
+          project.enabled_module_names = ['issue_tracking', 'wiki']
+        else
+          puts
+          puts "This project already exists in your Redmine database."
+          print "Are you sure you want to append data to this project ? [Y/n] "
+          STDOUT.flush
+          exit if STDIN.gets.match(/^n$/i)
+        end
+        project.trackers << TRACKER_BUG unless project.trackers.include?(TRACKER_BUG)
+        project.trackers << TRACKER_FEATURE unless project.trackers.include?(TRACKER_FEATURE)
+        @target_project = project.new_record? ? nil : project
+        @target_project.reload
+      end
+
+      def self.connection_params
+        if trac_adapter == 'sqlite3'
+          {:adapter => 'sqlite3',
+           :database => trac_db_path}
+        else
+          {:adapter => trac_adapter,
+           :database => trac_db_name,
+           :host => trac_db_host,
+           :port => trac_db_port,
+           :username => trac_db_username,
+           :password => trac_db_password,
+           :schema_search_path => trac_db_schema
+          }
+        end
+      end
+
+      def self.establish_connection
+        constants.each do |const|
+          klass = const_get(const)
+          next unless klass.respond_to? 'establish_connection'
+          klass.establish_connection connection_params
+        end
+      end
+
+      def self.encode(text)
+        if RUBY_VERSION < '1.9'
+          @ic ||= Iconv.new('UTF-8', @charset)
+          @ic.iconv text
+        else
+          text.to_s.force_encoding(@charset).encode('UTF-8')
+        end
+      end
+    end
+
+    puts
+    if Redmine::DefaultData::Loader.no_data?
+      puts "Redmine configuration need to be loaded before importing data."
+      puts "Please, run this first:"
+      puts
+      puts "  rake redmine:load_default_data RAILS_ENV=\"#{ENV['RAILS_ENV']}\""
+      exit
+    end
+
+    puts "WARNING: a new project will be added to Redmine during this process."
+    print "Are you sure you want to continue ? [y/N] "
+    STDOUT.flush
+    break unless STDIN.gets.match(/^y$/i)
+    puts
+
+    def prompt(text, options = {}, &block)
+      default = options[:default] || ''
+      while true
+        print "#{text} [#{default}]: "
+        STDOUT.flush
+        value = STDIN.gets.chomp!
+        value = default if value.blank?
+        break if yield value
+      end
+    end
+
+    DEFAULT_PORTS = {'mysql' => 3306, 'postgresql' => 5432}
+
+    prompt('Trac directory') {|directory| TracMigrate.set_trac_directory directory.strip}
+    prompt('Trac database adapter (sqlite3, mysql2, postgresql)', :default => 'sqlite3') {|adapter| TracMigrate.set_trac_adapter adapter}
+    unless %w(sqlite3).include?(TracMigrate.trac_adapter)
+      prompt('Trac database host', :default => 'localhost') {|host| TracMigrate.set_trac_db_host host}
+      prompt('Trac database port', :default => DEFAULT_PORTS[TracMigrate.trac_adapter]) {|port| TracMigrate.set_trac_db_port port}
+      prompt('Trac database name') {|name| TracMigrate.set_trac_db_name name}
+      prompt('Trac database schema', :default => 'public') {|schema| TracMigrate.set_trac_db_schema schema}
+      prompt('Trac database username') {|username| TracMigrate.set_trac_db_username username}
+      prompt('Trac database password') {|password| TracMigrate.set_trac_db_password password}
+    end
+    prompt('Trac database encoding', :default => 'UTF-8') {|encoding| TracMigrate.encoding encoding}
+    prompt('Target project identifier') {|identifier| TracMigrate.target_project_identifier identifier}
+    puts
+
+    # Turn off email notifications
+    Setting.notified_events = []
+
+    TracMigrate.migrate
+  end
+end
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/33/332beac4e5a854120b53b926beb38dfe9376b34a.svn-base
--- a/.svn/pristine/33/332beac4e5a854120b53b926beb38dfe9376b34a.svn-base
+++ /dev/null
@@ -1,72 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Search
-
-    mattr_accessor :available_search_types
-
-    @@available_search_types = []
-
-    class << self
-      def map(&block)
-        yield self
-      end
-
-      # Registers a search provider
-      def register(search_type, options={})
-        search_type = search_type.to_s
-        @@available_search_types << search_type unless @@available_search_types.include?(search_type)
-      end
-    end
-
-    module Controller
-      def self.included(base)
-        base.extend(ClassMethods)
-      end
-
-      module ClassMethods
-        @@default_search_scopes = Hash.new {|hash, key| hash[key] = {:default => nil, :actions => {}}}
-        mattr_accessor :default_search_scopes
-
-        # Set the default search scope for a controller or specific actions
-        # Examples:
-        #   * search_scope :issues # => sets the search scope to :issues for the whole controller
-        #   * search_scope :issues, :only => :index
-        #   * search_scope :issues, :only => [:index, :show]
-        def default_search_scope(id, options = {})
-          if actions = options[:only]
-            actions = [] << actions unless actions.is_a?(Array)
-            actions.each {|a| default_search_scopes[controller_name.to_sym][:actions][a.to_sym] = id.to_s}
-          else
-            default_search_scopes[controller_name.to_sym][:default] = id.to_s
-          end
-        end
-      end
-
-      def default_search_scopes
-        self.class.default_search_scopes
-      end
-
-      # Returns the default search scope according to the current action
-      def default_search_scope
-        @default_search_scope ||= default_search_scopes[controller_name.to_sym][:actions][action_name.to_sym] ||
-                                  default_search_scopes[controller_name.to_sym][:default]
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/33/3349206fec5e88c2e11146378e031801f405150d.svn-base
--- a/.svn/pristine/33/3349206fec5e88c2e11146378e031801f405150d.svn-base
+++ /dev/null
@@ -1,28 +0,0 @@
-<%= link_to 'root', :action => 'show', :id => @project, :path => '', :rev => @rev %>
-<%
-dirs = path.split('/')
-if 'file' == kind
-    filename = dirs.pop
-end
-link_path = ''
-dirs.each do |dir|
-    next if dir.blank?
-    link_path << '/' unless link_path.empty?
-    link_path << "#{dir}"
-    %>
-    / <%= link_to h(dir), :action => 'show', :id => @project,
-                :path => to_path_param(link_path), :rev => @rev %>
-<% end %>
-<% if filename %>
-    / <%= link_to h(filename),
-                   :action => 'changes', :id => @project,
-                   :path => to_path_param("#{link_path}/#{filename}"), :rev => @rev %>
-<% end %>
-<%
-  # @rev is revsion or Git and Mercurial branch or tag.
-  # For Mercurial *tip*, @rev and @changeset are nil.
-  rev_text = @changeset.nil? ? @rev : format_revision(@changeset)
-%>
-<%= "@ #{h rev_text}" unless rev_text.blank? %>
-
-<% html_title(with_leading_slash(path)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/33/3357225f79b9b7908f02d51c4dcc557f0e92041e.svn-base
--- a/.svn/pristine/33/3357225f79b9b7908f02d51c4dcc557f0e92041e.svn-base
+++ /dev/null
@@ -1,388 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/abstract_adapter'
-
-module Redmine
-  module Scm
-    module Adapters
-      class GitAdapter < AbstractAdapter
-
-        # Git executable name
-        GIT_BIN = Redmine::Configuration['scm_git_command'] || "git"
-
-        class << self
-          def client_command
-            @@bin    ||= GIT_BIN
-          end
-
-          def sq_bin
-            @@sq_bin ||= shell_quote_command
-          end
-
-          def client_version
-            @@client_version ||= (scm_command_version || [])
-          end
-
-          def client_available
-            !client_version.empty?
-          end
-
-          def scm_command_version
-            scm_version = scm_version_from_command_line.dup
-            if scm_version.respond_to?(:force_encoding)
-              scm_version.force_encoding('ASCII-8BIT')
-            end
-            if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
-              m[2].scan(%r{\d+}).collect(&:to_i)
-            end
-          end
-
-          def scm_version_from_command_line
-            shellout("#{sq_bin} --version --no-color") { |io| io.read }.to_s
-          end
-        end
-
-        def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil)
-          super
-          @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
-        end
-
-        def path_encoding
-          @path_encoding
-        end
-
-        def info
-          begin
-            Info.new(:root_url => url, :lastrev => lastrev('',nil))
-          rescue
-            nil
-          end
-        end
-
-        def branches
-          return @branches if @branches
-          @branches = []
-          cmd_args = %w|branch --no-color --verbose --no-abbrev|
-          scm_cmd(*cmd_args) do |io|
-            io.each_line do |line|
-              branch_rev = line.match('\s*\*?\s*(.*?)\s*([0-9a-f]{40}).*$')
-              bran = Branch.new(branch_rev[1])
-              bran.revision =  branch_rev[2]
-              bran.scmid    =  branch_rev[2]
-              @branches << bran
-            end
-          end
-          @branches.sort!
-        rescue ScmCommandAborted
-          nil
-        end
-
-        def tags
-          return @tags if @tags
-          cmd_args = %w|tag|
-          scm_cmd(*cmd_args) do |io|
-            @tags = io.readlines.sort!.map{|t| t.strip}
-          end
-        rescue ScmCommandAborted
-          nil
-        end
-
-        def default_branch
-          bras = self.branches
-          return nil if bras.nil?
-          bras.include?('master') ? 'master' : bras.first
-        end
-
-        def entry(path=nil, identifier=nil)
-          parts = path.to_s.split(%r{[\/\\]}).select {|n| !n.blank?}
-          search_path = parts[0..-2].join('/')
-          search_name = parts[-1]
-          if search_path.blank? && search_name.blank?
-            # Root entry
-            Entry.new(:path => '', :kind => 'dir')
-          else
-            # Search for the entry in the parent directory
-            es = entries(search_path, identifier,
-                         options = {:report_last_commit => false})
-            es ? es.detect {|e| e.name == search_name} : nil
-          end
-        end
-
-        def entries(path=nil, identifier=nil, options={})
-          path ||= ''
-          p = scm_iconv(@path_encoding, 'UTF-8', path)
-          entries = Entries.new
-          cmd_args = %w|ls-tree -l|
-          cmd_args << "HEAD:#{p}"          if identifier.nil?
-          cmd_args << "#{identifier}:#{p}" if identifier
-          scm_cmd(*cmd_args) do |io|
-            io.each_line do |line|
-              e = line.chomp.to_s
-              if e =~ /^\d+\s+(\w+)\s+([0-9a-f]{40})\s+([0-9-]+)\t(.+)$/
-                type = $1
-                sha  = $2
-                size = $3
-                name = $4
-                if name.respond_to?(:force_encoding)
-                  name.force_encoding(@path_encoding)
-                end
-                full_path = p.empty? ? name : "#{p}/#{name}"
-                n      = scm_iconv('UTF-8', @path_encoding, name)
-                full_p = scm_iconv('UTF-8', @path_encoding, full_path)
-                entries << Entry.new({:name => n,
-                 :path => full_p,
-                 :kind => (type == "tree") ? 'dir' : 'file',
-                 :size => (type == "tree") ? nil : size,
-                 :lastrev => options[:report_last_commit] ?
-                                 lastrev(full_path, identifier) : Revision.new
-                }) unless entries.detect{|entry| entry.name == name}
-              end
-            end
-          end
-          entries.sort_by_name
-        rescue ScmCommandAborted
-          nil
-        end
-
-        def lastrev(path, rev)
-          return nil if path.nil?
-          cmd_args = %w|log --no-color --encoding=UTF-8 --date=iso --pretty=fuller --no-merges -n 1|
-          cmd_args << rev if rev
-          cmd_args << "--" << path unless path.empty?
-          lines = []
-          scm_cmd(*cmd_args) { |io| lines = io.readlines }
-          begin
-              id = lines[0].split[1]
-              author = lines[1].match('Author:\s+(.*)$')[1]
-              time = Time.parse(lines[4].match('CommitDate:\s+(.*)$')[1])
-
-              Revision.new({
-                :identifier => id,
-                :scmid      => id,
-                :author     => author,
-                :time       => time,
-                :message    => nil,
-                :paths      => nil
-                })
-          rescue NoMethodError => e
-              logger.error("The revision '#{path}' has a wrong format")
-              return nil
-          end
-        rescue ScmCommandAborted
-          nil
-        end
-
-        def revisions(path, identifier_from, identifier_to, options={})
-          revs = Revisions.new
-          cmd_args = %w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller --parents|
-          cmd_args << "--reverse" if options[:reverse]
-          cmd_args << "--all" if options[:all]
-          cmd_args << "-n" << "#{options[:limit].to_i}" if options[:limit]
-          from_to = ""
-          from_to << "#{identifier_from}.." if identifier_from
-          from_to << "#{identifier_to}" if identifier_to
-          cmd_args << from_to if !from_to.empty?
-          cmd_args << "--since=#{options[:since].strftime("%Y-%m-%d %H:%M:%S")}" if options[:since]
-          cmd_args << "--" << scm_iconv(@path_encoding, 'UTF-8', path) if path && !path.empty?
-
-          scm_cmd *cmd_args do |io|
-            files=[]
-            changeset = {}
-            parsing_descr = 0  #0: not parsing desc or files, 1: parsing desc, 2: parsing files
-
-            io.each_line do |line|
-              if line =~ /^commit ([0-9a-f]{40})(( [0-9a-f]{40})*)$/
-                key = "commit"
-                value = $1
-                parents_str = $2
-                if (parsing_descr == 1 || parsing_descr == 2)
-                  parsing_descr = 0
-                  revision = Revision.new({
-                    :identifier => changeset[:commit],
-                    :scmid      => changeset[:commit],
-                    :author     => changeset[:author],
-                    :time       => Time.parse(changeset[:date]),
-                    :message    => changeset[:description],
-                    :paths      => files,
-                    :parents    => changeset[:parents]
-                  })
-                  if block_given?
-                    yield revision
-                  else
-                    revs << revision
-                  end
-                  changeset = {}
-                  files = []
-                end
-                changeset[:commit] = $1
-                unless parents_str.nil? or parents_str == ""
-                  changeset[:parents] = parents_str.strip.split(' ')
-                end
-              elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/
-                key = $1
-                value = $2
-                if key == "Author"
-                  changeset[:author] = value
-                elsif key == "CommitDate"
-                  changeset[:date] = value
-                end
-              elsif (parsing_descr == 0) && line.chomp.to_s == ""
-                parsing_descr = 1
-                changeset[:description] = ""
-              elsif (parsing_descr == 1 || parsing_descr == 2) \
-                  && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\t(.+)$/
-                parsing_descr = 2
-                fileaction    = $1
-                filepath      = $2
-                p = scm_iconv('UTF-8', @path_encoding, filepath)
-                files << {:action => fileaction, :path => p}
-              elsif (parsing_descr == 1 || parsing_descr == 2) \
-                  && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\d+\s+(\S+)\t(.+)$/
-                parsing_descr = 2
-                fileaction    = $1
-                filepath      = $3
-                p = scm_iconv('UTF-8', @path_encoding, filepath)
-                files << {:action => fileaction, :path => p}
-              elsif (parsing_descr == 1) && line.chomp.to_s == ""
-                parsing_descr = 2
-              elsif (parsing_descr == 1)
-                changeset[:description] << line[4..-1]
-              end
-            end
-
-            if changeset[:commit]
-              revision = Revision.new({
-                :identifier => changeset[:commit],
-                :scmid      => changeset[:commit],
-                :author     => changeset[:author],
-                :time       => Time.parse(changeset[:date]),
-                :message    => changeset[:description],
-                :paths      => files,
-                :parents    => changeset[:parents]
-                 })
-              if block_given?
-                yield revision
-              else
-                revs << revision
-              end
-            end
-          end
-          revs
-        rescue ScmCommandAborted => e
-          logger.error("git log #{from_to.to_s} error: #{e.message}")
-          revs
-        end
-
-        def diff(path, identifier_from, identifier_to=nil)
-          path ||= ''
-          cmd_args = []
-          if identifier_to
-            cmd_args << "diff" << "--no-color" <<  identifier_to << identifier_from
-          else
-            cmd_args << "show" << "--no-color" << identifier_from
-          end
-          cmd_args << "--" <<  scm_iconv(@path_encoding, 'UTF-8', path) unless path.empty?
-          diff = []
-          scm_cmd *cmd_args do |io|
-            io.each_line do |line|
-              diff << line
-            end
-          end
-          diff
-        rescue ScmCommandAborted
-          nil
-        end
-
-        def annotate(path, identifier=nil)
-          identifier = 'HEAD' if identifier.blank?
-          cmd_args = %w|blame|
-          cmd_args << "-p" << identifier << "--" <<  scm_iconv(@path_encoding, 'UTF-8', path)
-          blame = Annotate.new
-          content = nil
-          scm_cmd(*cmd_args) { |io| io.binmode; content = io.read }
-          # git annotates binary files
-          return nil if content.is_binary_data?
-          identifier = ''
-          # git shows commit author on the first occurrence only
-          authors_by_commit = {}
-          content.split("\n").each do |line|
-            if line =~ /^([0-9a-f]{39,40})\s.*/
-              identifier = $1
-            elsif line =~ /^author (.+)/
-              authors_by_commit[identifier] = $1.strip
-            elsif line =~ /^\t(.*)/
-              blame.add_line($1, Revision.new(
-                                    :identifier => identifier,
-                                    :revision   => identifier,
-                                    :scmid      => identifier,
-                                    :author     => authors_by_commit[identifier]
-                                    ))
-              identifier = ''
-              author = ''
-            end
-          end
-          blame
-        rescue ScmCommandAborted
-          nil
-        end
-
-        def cat(path, identifier=nil)
-          if identifier.nil?
-            identifier = 'HEAD'
-          end
-          cmd_args = %w|show --no-color|
-          cmd_args << "#{identifier}:#{scm_iconv(@path_encoding, 'UTF-8', path)}"
-          cat = nil
-          scm_cmd(*cmd_args) do |io|
-            io.binmode
-            cat = io.read
-          end
-          cat
-        rescue ScmCommandAborted
-          nil
-        end
-
-        class Revision < Redmine::Scm::Adapters::Revision
-          # Returns the readable identifier
-          def format_identifier
-            identifier[0,8]
-          end
-        end
-
-        def scm_cmd(*args, &block)
-          repo_path = root_url || url
-          full_args = ['--git-dir', repo_path]
-          if self.class.client_version_above?([1, 7, 2])
-            full_args << '-c' << 'core.quotepath=false'
-            full_args << '-c' << 'log.decorate=no'
-          end
-          full_args += args
-          ret = shellout(
-                   self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
-                   &block
-                   )
-          if $? && $?.exitstatus != 0
-            raise ScmCommandAborted, "git exited with non-zero status: #{$?.exitstatus}"
-          end
-          ret
-        end
-        private :scm_cmd
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/33/3396ee85e7860d58bce2840b1f00fae7a535409f.svn-base
--- a/.svn/pristine/33/3396ee85e7860d58bce2840b1f00fae7a535409f.svn-base
+++ /dev/null
@@ -1,42 +0,0 @@
-module TestHelper
-  def self.report_location(path)
-    [RAILS_ROOT + '/', 'vendor/plugins/'].each { |part| path.sub! part, ''}
-    path = path.split('/')
-    location, subject = path.first, path.last
-    if subject.sub! '.rb', ''
-      subject = subject.classify
-    else 
-      subject.sub! '.html.erb', ''
-    end
-    "#{subject} (from #{location})"
-  end
-  
-  def self.view_path_for path
-    [RAILS_ROOT + '/', 'vendor/plugins/', '.html.erb'].each { |part| path.sub! part, ''}
-    parts = path.split('/')
-    parts[(parts.index('views')+1)..-1].join('/')
-  end
-end
-
-class Test::Unit::TestCase
-  # Add more helper methods to be used by all tests here...  
-  def get_action_on_controller(*args)
-    action = args.shift
-    with_controller *args
-    get action
-  end
-  
-  def with_controller(controller, namespace = nil)
-    classname = controller.to_s.classify + 'Controller'
-    classname = namespace.to_s.classify + '::' + classname unless namespace.nil?
-    @controller = classname.constantize.new
-  end
-  
-  def assert_response_body(expected)
-    assert_equal expected, @response.body
-  end
-end
-
-# Because we're testing this behaviour, we actually want these features on!
-Engines.disable_application_view_loading = false
-Engines.disable_application_code_loading = false
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/33/339df18b16b4ab05fedfba76e31080e6dda3b82a.svn-base
--- /dev/null
+++ b/.svn/pristine/33/339df18b16b4ab05fedfba76e31080e6dda3b82a.svn-base
@@ -0,0 +1,27 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingMailHandlerTest < ActionController::IntegrationTest
+  def test_mail_handler
+    assert_routing(
+        { :method => "post", :path => "/mail_handler" },
+        { :controller => 'mail_handler', :action => 'index' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/33/33a69333d665b6d06e88fdb324d960ab74dff338.svn-base
--- a/.svn/pristine/33/33a69333d665b6d06e88fdb324d960ab74dff338.svn-base
+++ /dev/null
@@ -1,55 +0,0 @@
-module CodeRay
-  
-  # The result of a scan operation is a TokensProxy, but should act like Tokens.
-  # 
-  # This proxy makes it possible to use the classic CodeRay.scan.encode API
-  # while still providing the benefits of direct streaming.
-  class TokensProxy
-    
-    attr_accessor :input, :lang, :options, :block
-    
-    # Create a new TokensProxy with the arguments of CodeRay.scan.
-    def initialize input, lang, options = {}, block = nil
-      @input   = input
-      @lang    = lang
-      @options = options
-      @block   = block
-    end
-    
-    # Call CodeRay.encode if +encoder+ is a Symbol;
-    # otherwise, convert the receiver to tokens and call encoder.encode_tokens.
-    def encode encoder, options = {}
-      if encoder.respond_to? :to_sym
-        CodeRay.encode(input, lang, encoder, options)
-      else
-        encoder.encode_tokens tokens, options
-      end
-    end
-    
-    # Tries to call encode;
-    # delegates to tokens otherwise.
-    def method_missing method, *args, &blk
-      encode method.to_sym, *args
-    rescue PluginHost::PluginNotFound
-      tokens.send(method, *args, &blk)
-    end
-    
-    # The (cached) result of the tokenized input; a Tokens instance.
-    def tokens
-      @tokens ||= scanner.tokenize(input)
-    end
-    
-    # A (cached) scanner instance to use for the scan task.
-    def scanner
-      @scanner ||= CodeRay.scanner(lang, options, &block)
-    end
-    
-    # Overwrite Struct#each.
-    def each *args, &blk
-      tokens.each(*args, &blk)
-      self
-    end
-    
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/34/3426569be9b65b6dce3f0afa56586bb79fc07741.svn-base
--- a/.svn/pristine/34/3426569be9b65b6dce3f0afa56586bb79fc07741.svn-base
+++ /dev/null
@@ -1,112 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Acts
-    module Customizable
-      def self.included(base)
-        base.extend ClassMethods
-      end
-
-      module ClassMethods
-        def acts_as_customizable(options = {})
-          return if self.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
-          cattr_accessor :customizable_options
-          self.customizable_options = options
-          has_many :custom_values, :as => :customized,
-                                   :include => :custom_field,
-                                   :order => "#{CustomField.table_name}.position",
-                                   :dependent => :delete_all
-          before_validation { |customized| customized.custom_field_values if customized.new_record? }
-          # Trigger validation only if custom values were changed
-          validates_associated :custom_values, :on => :update, :if => Proc.new { |customized| customized.custom_field_values_changed? }
-          send :include, Redmine::Acts::Customizable::InstanceMethods
-          # Save custom values when saving the customized object
-          after_save :save_custom_field_values
-        end
-      end
-
-      module InstanceMethods
-        def self.included(base)
-          base.extend ClassMethods
-        end
-        
-        def available_custom_fields
-          CustomField.find(:all, :conditions => "type = '#{self.class.name}CustomField'",
-                                 :order => 'position')
-        end
-        
-        # Sets the values of the object's custom fields
-        # values is an array like [{'id' => 1, 'value' => 'foo'}, {'id' => 2, 'value' => 'bar'}]
-        def custom_fields=(values)
-          values_to_hash = values.inject({}) do |hash, v|
-            v = v.stringify_keys
-            if v['id'] && v.has_key?('value')
-              hash[v['id']] = v['value']
-            end
-            hash
-          end
-          self.custom_field_values = values_to_hash
-        end
-
-        # Sets the values of the object's custom fields
-        # values is a hash like {'1' => 'foo', 2 => 'bar'}
-        def custom_field_values=(values)
-          @custom_field_values_changed = true
-          values = values.stringify_keys
-          custom_field_values.each do |custom_value|
-            custom_value.value = values[custom_value.custom_field_id.to_s] if values.has_key?(custom_value.custom_field_id.to_s)
-          end if values.is_a?(Hash)
-        end
-        
-        def custom_field_values
-          @custom_field_values ||= available_custom_fields.collect { |x| custom_values.detect { |v| v.custom_field == x } || custom_values.build(:customized => self, :custom_field => x, :value => nil) }
-        end
-        
-        def visible_custom_field_values
-          custom_field_values.select(&:visible?)
-        end
-        
-        def custom_field_values_changed?
-          @custom_field_values_changed == true
-        end
-        
-        def custom_value_for(c)
-          field_id = (c.is_a?(CustomField) ? c.id : c.to_i)
-          custom_values.detect {|v| v.custom_field_id == field_id }
-        end
-        
-        def save_custom_field_values
-          self.custom_values = custom_field_values
-          custom_field_values.each(&:save)
-          @custom_field_values_changed = false
-          @custom_field_values = nil
-        end
-        
-        def reset_custom_values!
-          @custom_field_values = nil
-          @custom_field_values_changed = true
-          values = custom_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
-          custom_values.each {|cv| cv.destroy unless custom_field_values.include?(cv)}
-        end
-        
-        module ClassMethods
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/34/342bfb95b19c2d2bc64485e9d4d12de5afbbc42e.svn-base
--- a/.svn/pristine/34/342bfb95b19c2d2bc64485e9d4d12de5afbbc42e.svn-base
+++ /dev/null
@@ -1,57 +0,0 @@
-Return-Path: <JSmith@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
-Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
-From: "John Smith" <JSmith@somenet.foo>
-To: <redmine@somenet.foo>
-Subject: New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...
-Date: Sun, 22 Jun 2008 12:28:07 +0200
-MIME-Version: 1.0
-Content-Type: text/plain;
-	format=flowed;
-	charset="iso-8859-1";
-	reply-type=original
-Content-Transfer-Encoding: 7bit
-X-Priority: 3
-X-MSMail-Priority: Normal
-X-Mailer: Microsoft Outlook Express 6.00.2900.2869
-X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet 
-turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus 
-blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti 
-sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In 
-in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras 
-sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum 
-id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus 
-eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique 
-sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et 
-malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
-platea dictumst.
-
---- This line starts with a delimiter and should not be stripped
-
-This paragraph is before delimiters.
-
-BREAK
-
-This paragraph is between delimiters.
-
----
-
-This paragraph is after the delimiter so it shouldn't appear.
-
-Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque 
-sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. 
-Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, 
-dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed, 
-massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo 
-pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
-
-Project: onlinestore
-Status: Resolved
-due date: 2010-12-31
-Start Date:2010-01-01
-Assigned to: John Smith
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/34/345b699f46121e103fdce4587bf3ec87db1cc445.svn-base
--- /dev/null
+++ b/.svn/pristine/34/345b699f46121e103fdce4587bf3ec87db1cc445.svn-base
@@ -0,0 +1,107 @@
+module ActiveRecord
+  module Acts
+    module Tree
+      def self.included(base)
+        base.extend(ClassMethods)
+      end
+
+      # Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children
+      # association. This requires that you have a foreign key column, which by default is called +parent_id+.
+      #
+      #   class Category < ActiveRecord::Base
+      #     acts_as_tree :order => "name"
+      #   end
+      #
+      #   Example:
+      #   root
+      #    \_ child1
+      #         \_ subchild1
+      #         \_ subchild2
+      #
+      #   root      = Category.create("name" => "root")
+      #   child1    = root.children.create("name" => "child1")
+      #   subchild1 = child1.children.create("name" => "subchild1")
+      #
+      #   root.parent   # => nil
+      #   child1.parent # => root
+      #   root.children # => [child1]
+      #   root.children.first.children.first # => subchild1
+      #
+      # In addition to the parent and children associations, the following instance methods are added to the class
+      # after calling <tt>acts_as_tree</tt>:
+      # * <tt>siblings</tt> - Returns all the children of the parent, excluding the current node (<tt>[subchild2]</tt> when called on <tt>subchild1</tt>)
+      # * <tt>self_and_siblings</tt> - Returns all the children of the parent, including the current node (<tt>[subchild1, subchild2]</tt> when called on <tt>subchild1</tt>)
+      # * <tt>ancestors</tt> - Returns all the ancestors of the current node (<tt>[child1, root]</tt> when called on <tt>subchild2</tt>)
+      # * <tt>root</tt> - Returns the root of the current node (<tt>root</tt> when called on <tt>subchild2</tt>)
+      module ClassMethods
+        # Configuration options are:
+        #
+        # * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
+        # * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
+        # * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
+        def acts_as_tree(options = {})
+          configuration = { :foreign_key => "parent_id", :dependent => :destroy, :order => nil, :counter_cache => nil }
+          configuration.update(options) if options.is_a?(Hash)
+
+          belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
+          has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => configuration[:dependent]
+
+          scope :roots, where("#{configuration[:foreign_key]} IS NULL").order(configuration[:order])
+
+          send :include, ActiveRecord::Acts::Tree::InstanceMethods
+        end
+      end
+
+      module InstanceMethods
+        # Returns list of ancestors, starting from parent until root.
+        #
+        #   subchild1.ancestors # => [child1, root]
+        def ancestors
+          node, nodes = self, []
+          nodes << node = node.parent while node.parent
+          nodes
+        end
+
+        # Returns list of descendants.
+        #
+        #   root.descendants # => [child1, subchild1, subchild2]
+        def descendants(depth=nil)
+          depth ||= 0
+          result = children.dup
+          unless depth == 1
+            result += children.collect {|child| child.descendants(depth-1)}.flatten
+          end
+          result
+        end
+
+        # Returns list of descendants and a reference to the current node.
+        #
+        #   root.self_and_descendants # => [root, child1, subchild1, subchild2]
+        def self_and_descendants(depth=nil)
+          [self] + descendants(depth)
+        end
+
+        # Returns the root node of the tree.
+        def root
+          node = self
+          node = node.parent while node.parent
+          node
+        end
+
+        # Returns all siblings of the current node.
+        #
+        #   subchild1.siblings # => [subchild2]
+        def siblings
+          self_and_siblings - [self]
+        end
+
+        # Returns all siblings and a reference to the current node.
+        #
+        #   subchild1.self_and_siblings # => [subchild1, subchild2]
+        def self_and_siblings
+          parent ? parent.children : self.class.roots
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/34/34e888bcdeab7ab62509c340e12806f908468391.svn-base
--- a/.svn/pristine/34/34e888bcdeab7ab62509c340e12806f908468391.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-author: James Adam
-email: james.adam@gmail.com
-homepage: http://www.rails-engines.org
-summary: Enhances the plugin mechanism to perform more flexible sharing
-description: The Rails Engines plugin allows the sharing of almost any type of code or asset that you could use in a Rails application, including controllers, models, stylesheets, and views.
-license: MIT
-version: 2.3.2
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/35/3512f0a7e8a0b7dd8c33b6309137ca6b0f893a68.svn-base
--- a/.svn/pristine/35/3512f0a7e8a0b7dd8c33b6309137ca6b0f893a68.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= TestHelper.view_path_for __FILE__ %> (from a_view)
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/35/35159d7789b8fbcfc57c58eacb8fb9632b6c69c9.svn-base
--- a/.svn/pristine/35/35159d7789b8fbcfc57c58eacb8fb9632b6c69c9.svn-base
+++ /dev/null
@@ -1,67 +0,0 @@
-api.issue do
-  api.id @issue.id
-  api.project(:id => @issue.project_id, :name => @issue.project.name) unless @issue.project.nil?
-  api.tracker(:id => @issue.tracker_id, :name => @issue.tracker.name) unless @issue.tracker.nil?
-  api.status(:id => @issue.status_id, :name => @issue.status.name) unless @issue.status.nil?
-  api.priority(:id => @issue.priority_id, :name => @issue.priority.name) unless @issue.priority.nil?
-  api.author(:id => @issue.author_id, :name => @issue.author.name) unless @issue.author.nil?
-  api.assigned_to(:id => @issue.assigned_to_id, :name => @issue.assigned_to.name) unless @issue.assigned_to.nil?
-  api.category(:id => @issue.category_id, :name => @issue.category.name) unless @issue.category.nil?
-  api.fixed_version(:id => @issue.fixed_version_id, :name => @issue.fixed_version.name) unless @issue.fixed_version.nil?
-  api.parent(:id => @issue.parent_id) unless @issue.parent.nil?
-
-  api.subject @issue.subject
-  api.description @issue.description
-  api.start_date @issue.start_date
-  api.due_date @issue.due_date
-  api.done_ratio @issue.done_ratio
-  api.estimated_hours @issue.estimated_hours
-  api.spent_hours(@issue.spent_hours) if User.current.allowed_to?(:view_time_entries, @project)
-
-  render_api_custom_values @issue.custom_field_values, api
-
-  api.created_on @issue.created_on
-  api.updated_on @issue.updated_on
-
-  render_api_issue_children(@issue, api) if include_in_api_response?('children')
-
-  api.array :attachments do
-    @issue.attachments.each do |attachment|
-      render_api_attachment(attachment, api)
-    end
-  end if include_in_api_response?('attachments')
-
-  api.array :relations do
-    @relations.each do |relation|
-      api.relation(:id => relation.id, :issue_id => relation.issue_from_id, :issue_to_id => relation.issue_to_id, :relation_type => relation.relation_type, :delay => relation.delay)
-    end
-  end if include_in_api_response?('relations') && @relations.present?
-
-  api.array :changesets do
-    @issue.changesets.each do |changeset|
-      api.changeset :revision => changeset.revision do
-        api.user(:id => changeset.user_id, :name => changeset.user.name) unless changeset.user.nil?
-        api.comments changeset.comments
-        api.committed_on changeset.committed_on
-      end
-    end
-  end if include_in_api_response?('changesets') && User.current.allowed_to?(:view_changesets, @project)
-
-  api.array :journals do
-    @issue.journals.each do |journal|
-      api.journal :id => journal.id do
-        api.user(:id => journal.user_id, :name => journal.user.name) unless journal.user.nil?
-        api.notes journal.notes
-        api.created_on journal.created_on
-        api.array :details do
-          journal.details.each do |detail|
-            api.detail :property => detail.property, :name => detail.prop_key do
-              api.old_value detail.old_value
-              api.new_value detail.value
-            end
-          end
-        end
-      end
-    end
-  end if include_in_api_response?('journals')
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/35/35a0a9f6553f729051c01dc102ed98a7a0151c3f.svn-base
--- /dev/null
+++ b/.svn/pristine/35/35a0a9f6553f729051c01dc102ed98a7a0151c3f.svn-base
@@ -0,0 +1,243 @@
+# encoding: utf-8
+#
+# Helpers to sort tables using clickable column headers.
+#
+# Author:  Stuart Rackham <srackham@methods.co.nz>, March 2005.
+#          Jean-Philippe Lang, 2009
+# License: This source code is released under the MIT license.
+#
+# - Consecutive clicks toggle the column's sort order.
+# - Sort state is maintained by a session hash entry.
+# - CSS classes identify sort column and state.
+# - Typically used in conjunction with the Pagination module.
+#
+# Example code snippets:
+#
+# Controller:
+#
+#   helper :sort
+#   include SortHelper
+#
+#   def list
+#     sort_init 'last_name'
+#     sort_update %w(first_name last_name)
+#     @items = Contact.find_all nil, sort_clause
+#   end
+#
+# Controller (using Pagination module):
+#
+#   helper :sort
+#   include SortHelper
+#
+#   def list
+#     sort_init 'last_name'
+#     sort_update %w(first_name last_name)
+#     @contact_pages, @items = paginate :contacts,
+#       :order_by => sort_clause,
+#       :per_page => 10
+#   end
+#
+# View (table header in list.rhtml):
+#
+#   <thead>
+#     <tr>
+#       <%= sort_header_tag('id', :title => 'Sort by contact ID') %>
+#       <%= sort_header_tag('last_name', :caption => 'Name') %>
+#       <%= sort_header_tag('phone') %>
+#       <%= sort_header_tag('address', :width => 200) %>
+#     </tr>
+#   </thead>
+#
+# - Introduces instance variables: @sort_default, @sort_criteria
+# - Introduces param :sort
+#
+
+module SortHelper
+  class SortCriteria
+
+    def initialize
+      @criteria = []
+    end
+
+    def available_criteria=(criteria)
+      unless criteria.is_a?(Hash)
+        criteria = criteria.inject({}) {|h,k| h[k] = k; h}
+      end
+      @available_criteria = criteria
+    end
+
+    def from_param(param)
+      @criteria = param.to_s.split(',').collect {|s| s.split(':')[0..1]}
+      normalize!
+    end
+
+    def criteria=(arg)
+      @criteria = arg
+      normalize!
+    end
+
+    def to_param
+      @criteria.collect {|k,o| k + (o ? '' : ':desc')}.join(',')
+    end
+
+    # Returns an array of SQL fragments used to sort the list
+    def to_sql
+      sql = @criteria.collect do |k,o|
+        if s = @available_criteria[k]
+          (o ? s.to_a : s.to_a.collect {|c| append_desc(c)})
+        end
+      end.flatten.compact
+      sql.blank? ? nil : sql
+    end
+
+    def to_a
+      @criteria.dup
+    end
+
+    def add!(key, asc)
+      @criteria.delete_if {|k,o| k == key}
+      @criteria = [[key, asc]] + @criteria
+      normalize!
+    end
+
+    def add(*args)
+      r = self.class.new.from_param(to_param)
+      r.add!(*args)
+      r
+    end
+
+    def first_key
+      @criteria.first && @criteria.first.first
+    end
+
+    def first_asc?
+      @criteria.first && @criteria.first.last
+    end
+
+    def empty?
+      @criteria.empty?
+    end
+
+    private
+
+    def normalize!
+      @criteria ||= []
+      @criteria = @criteria.collect {|s| s = s.to_a; [s.first, (s.last == false || s.last == 'desc') ? false : true]}
+      @criteria = @criteria.select {|k,o| @available_criteria.has_key?(k)} if @available_criteria
+      @criteria.slice!(3)
+      self
+    end
+
+    # Appends DESC to the sort criterion unless it has a fixed order
+    def append_desc(criterion)
+      if criterion =~ / (asc|desc)$/i
+        criterion
+      else
+        "#{criterion} DESC"
+      end
+    end
+  end
+
+  def sort_name
+    controller_name + '_' + action_name + '_sort'
+  end
+
+  # Initializes the default sort.
+  # Examples:
+  #
+  #   sort_init 'name'
+  #   sort_init 'id', 'desc'
+  #   sort_init ['name', ['id', 'desc']]
+  #   sort_init [['name', 'desc'], ['id', 'desc']]
+  #
+  def sort_init(*args)
+    case args.size
+    when 1
+      @sort_default = args.first.is_a?(Array) ? args.first : [[args.first]]
+    when 2
+      @sort_default = [[args.first, args.last]]
+    else
+      raise ArgumentError
+    end
+  end
+
+  # Updates the sort state. Call this in the controller prior to calling
+  # sort_clause.
+  # - criteria can be either an array or a hash of allowed keys
+  #
+  def sort_update(criteria, sort_name=nil)
+    sort_name ||= self.sort_name
+    @sort_criteria = SortCriteria.new
+    @sort_criteria.available_criteria = criteria
+    @sort_criteria.from_param(params[:sort] || session[sort_name])
+    @sort_criteria.criteria = @sort_default if @sort_criteria.empty?
+    session[sort_name] = @sort_criteria.to_param
+  end
+
+  # Clears the sort criteria session data
+  #
+  def sort_clear
+    session[sort_name] = nil
+  end
+
+  # Returns an SQL sort clause corresponding to the current sort state.
+  # Use this to sort the controller's table items collection.
+  #
+  def sort_clause()
+    @sort_criteria.to_sql
+  end
+
+  def sort_criteria
+    @sort_criteria
+  end
+
+  # Returns a link which sorts by the named column.
+  #
+  # - column is the name of an attribute in the sorted record collection.
+  # - the optional caption explicitly specifies the displayed link text.
+  # - 2 CSS classes reflect the state of the link: sort and asc or desc
+  #
+  def sort_link(column, caption, default_order)
+    css, order = nil, default_order
+
+    if column.to_s == @sort_criteria.first_key
+      if @sort_criteria.first_asc?
+        css = 'sort asc'
+        order = 'desc'
+      else
+        css = 'sort desc'
+        order = 'asc'
+      end
+    end
+    caption = column.to_s.humanize unless caption
+
+    sort_options = { :sort => @sort_criteria.add(column.to_s, order).to_param }
+    url_options = params.merge(sort_options)
+
+     # Add project_id to url_options
+    url_options = url_options.merge(:project_id => params[:project_id]) if params.has_key?(:project_id)
+
+    link_to_content_update(h(caption), url_options, :class => css)
+  end
+
+  # Returns a table header <th> tag with a sort link for the named column
+  # attribute.
+  #
+  # Options:
+  #   :caption     The displayed link name (defaults to titleized column name).
+  #   :title       The tag's 'title' attribute (defaults to 'Sort by :caption').
+  #
+  # Other options hash entries generate additional table header tag attributes.
+  #
+  # Example:
+  #
+  #   <%= sort_header_tag('id', :title => 'Sort by contact ID', :width => 40) %>
+  #
+  def sort_header_tag(column, options = {})
+    caption = options.delete(:caption) || column.to_s.humanize
+    default_order = options.delete(:default_order) || 'asc'
+    options[:title] = l(:label_sort_by, "\"#{caption}\"") unless options[:title]
+    content_tag('th', sort_link(column, caption, default_order), options)
+  end
+end
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/35/35c1cd09fb09a0095fc148484431ad643d188dd6.svn-base
--- /dev/null
+++ b/.svn/pristine/35/35c1cd09fb09a0095fc148484431ad643d188dd6.svn-base
@@ -0,0 +1,24 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class CommentObserver < ActiveRecord::Observer
+  def after_create(comment)
+    if comment.commented.is_a?(News) && Setting.notified_events.include?('news_comment_added')
+      Mailer.news_comment_added(comment).deliver
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/35/35d2a8dc4a5a8983e7bc3e63a00a706b7e3bfb4c.svn-base
--- /dev/null
+++ b/.svn/pristine/35/35d2a8dc4a5a8983e7bc3e63a00a706b7e3bfb4c.svn-base
@@ -0,0 +1,223 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module QueriesHelper
+  def filters_options_for_select(query)
+    options_for_select(filters_options(query))
+  end
+
+  def filters_options(query)
+    options = [[]]
+    options += query.available_filters.map do |field, field_options|
+      [field_options[:name], field]
+    end
+  end
+
+  def query_filters_hidden_tags(query)
+    tags = ''.html_safe
+    query.filters.each do |field, options|
+      tags << hidden_field_tag("f[]", field, :id => nil)
+      tags << hidden_field_tag("op[#{field}]", options[:operator], :id => nil)
+      options[:values].each do |value|
+        tags << hidden_field_tag("v[#{field}][]", value, :id => nil)
+      end
+    end
+    tags
+  end
+
+  def query_columns_hidden_tags(query)
+    tags = ''.html_safe
+    query.columns.each do |column|
+      tags << hidden_field_tag("c[]", column.name, :id => nil)
+    end
+    tags
+  end
+
+  def query_hidden_tags(query)
+    query_filters_hidden_tags(query) + query_columns_hidden_tags(query)
+  end
+
+  def available_block_columns_tags(query)
+    tags = ''.html_safe
+    query.available_block_columns.each do |column|
+      tags << content_tag('label', check_box_tag('c[]', column.name.to_s, query.has_column?(column)) + " #{column.caption}", :class => 'inline')
+    end
+    tags
+  end
+
+  def query_available_inline_columns_options(query)
+    (query.available_inline_columns - query.columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
+  end
+
+  def query_selected_inline_columns_options(query)
+    (query.inline_columns & query.available_inline_columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
+  end
+
+  def render_query_columns_selection(query, options={})
+    tag_name = (options[:name] || 'c') + '[]'
+    render :partial => 'queries/columns', :locals => {:query => query, :tag_name => tag_name}
+  end
+
+  def column_header(column)
+    column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption,
+                                                        :default_order => column.default_order) :
+                      content_tag('th', h(column.caption))
+  end
+
+  def column_content(column, issue)
+    value = column.value(issue)
+    if value.is_a?(Array)
+      value.collect {|v| column_value(column, issue, v)}.compact.join(', ').html_safe
+    else
+      column_value(column, issue, value)
+    end
+  end
+  
+  def column_value(column, issue, value)
+    case value.class.name
+    when 'String'
+      if column.name == :subject
+        link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
+      elsif column.name == :description
+        issue.description? ? content_tag('div', textilizable(issue, :description), :class => "wiki") : ''
+      else
+        h(value)
+      end
+    when 'Time'
+      format_time(value)
+    when 'Date'
+      format_date(value)
+    when 'Fixnum'
+      if column.name == :id
+        link_to value, issue_path(issue)
+      elsif column.name == :done_ratio
+        progress_bar(value, :width => '80px')
+      else
+        value.to_s
+      end
+    when 'Float'
+      sprintf "%.2f", value
+    when 'User'
+      link_to_user value
+    when 'Project'
+      link_to_project value
+    when 'Version'
+      link_to(h(value), :controller => 'versions', :action => 'show', :id => value)
+    when 'TrueClass'
+      l(:general_text_Yes)
+    when 'FalseClass'
+      l(:general_text_No)
+    when 'Issue'
+      value.visible? ? link_to_issue(value) : "##{value.id}"
+    when 'IssueRelation'
+      other = value.other_issue(issue)
+      content_tag('span',
+        (l(value.label_for(issue)) + " " + link_to_issue(other, :subject => false, :tracker => false)).html_safe,
+        :class => value.css_classes_for(issue))
+    else
+      h(value)
+    end
+  end
+
+  def csv_content(column, issue)
+    value = column.value(issue)
+    if value.is_a?(Array)
+      value.collect {|v| csv_value(column, issue, v)}.compact.join(', ')
+    else
+      csv_value(column, issue, value)
+    end
+  end
+
+  def csv_value(column, issue, value)
+    case value.class.name
+    when 'Time'
+      format_time(value)
+    when 'Date'
+      format_date(value)
+    when 'Float'
+      sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator))
+    when 'IssueRelation'
+      other = value.other_issue(issue)
+      l(value.label_for(issue)) + " ##{other.id}"
+    else
+      value.to_s
+    end
+  end
+
+  def query_to_csv(items, query, options={})
+    encoding = l(:general_csv_encoding)
+    columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns)
+    query.available_block_columns.each do |column|
+      if options[column.name].present?
+        columns << column
+      end
+    end
+
+    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
+      # csv header fields
+      csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
+      # csv lines
+      items.each do |item|
+        csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(csv_content(c, item), encoding) }
+      end
+    end
+    export
+  end
+
+  # Retrieve query from session or build a new query
+  def retrieve_query
+    if !params[:query_id].blank?
+      cond = "project_id IS NULL"
+      cond << " OR project_id = #{@project.id}" if @project
+      @query = IssueQuery.find(params[:query_id], :conditions => cond)
+      raise ::Unauthorized unless @query.visible?
+      @query.project = @project
+      session[:query] = {:id => @query.id, :project_id => @query.project_id}
+      sort_clear
+    elsif api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
+      # Give it a name, required to be valid
+      @query = IssueQuery.new(:name => "_")
+      @query.project = @project
+      @query.build_from_params(params)
+      session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
+    else
+      # retrieve from session
+      @query = IssueQuery.find_by_id(session[:query][:id]) if session[:query][:id]
+      @query ||= IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
+      @query.project = @project
+    end
+  end
+
+  def retrieve_query_from_session
+    if session[:query]
+      if session[:query][:id]
+        @query = IssueQuery.find_by_id(session[:query][:id])
+        return unless @query
+      else
+        @query = IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
+      end
+      if session[:query].has_key?(:project_id)
+        @query.project_id = session[:query][:project_id]
+      else
+        @query.project = @project
+      end
+      @query
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/35/35f7ce114c4047a04259024e5c563af98880d0e2.svn-base
--- a/.svn/pristine/35/35f7ce114c4047a04259024e5c563af98880d0e2.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-# Add new mime types for use in respond_to blocks:
-
-Mime::SET << Mime::CSV unless Mime::SET.include?(Mime::CSV)
-Mime::Type.register 'application/pdf', :pdf
-Mime::Type.register 'image/png', :png
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/36/36167ee499dcc4b045fdbe86a18299795ead7b8c.svn-base
--- a/.svn/pristine/36/36167ee499dcc4b045fdbe86a18299795ead7b8c.svn-base
+++ /dev/null
@@ -1,33 +0,0 @@
-<h3><%=l(:label_my_account)%></h3>
-
-<p><%=l(:field_login)%>: <strong><%= link_to_user(@user, :format => :username) %></strong><br />
-<%=l(:field_created_on)%>: <%= format_time(@user.created_on) %></p>
-
-
-<h4><%= l(:label_feeds_access_key) %></h4>
-
-<p>
-<% if @user.rss_token %>
-<%= l(:label_feeds_access_key_created_on, distance_of_time_in_words(Time.now, @user.rss_token.created_on)) %>
-<% else %>
-<%= l(:label_missing_feeds_access_key) %>
-<% end %>
-(<%= link_to l(:button_reset), {:action => 'reset_rss_key'}, :method => :post %>)
-</p>
-
-<% if Setting.rest_api_enabled? %>
-<h4><%= l(:label_api_access_key) %></h4>
-<div>
-  <%= link_to_function(l(:button_show), "$('api-access-key').toggle();")%>
-  <pre id='api-access-key' class='autoscroll'><%= h(@user.api_key) %></pre>
-</div>
-<%= javascript_tag("$('api-access-key').hide();") %>
-<p>
-<% if @user.api_token %>
-<%= l(:label_api_access_key_created_on, distance_of_time_in_words(Time.now, @user.api_token.created_on)) %>
-<% else %>
-<%= l(:label_missing_api_access_key) %>
-<% end %>
-(<%= link_to l(:button_reset), {:action => 'reset_api_key'}, :method => :post %>)
-</p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/36/362876bd65a226af3b36d0e31a3e589d5fcd9d1f.svn-base
--- a/.svn/pristine/36/362876bd65a226af3b36d0e31a3e589d5fcd9d1f.svn-base
+++ /dev/null
@@ -1,75 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module SafeAttributes
-    def self.included(base)
-      base.extend(ClassMethods)
-    end
-
-    module ClassMethods
-      # Declares safe attributes
-      # An optional Proc can be given for conditional inclusion
-      #
-      # Example:
-      #   safe_attributes 'title', 'pages'
-      #   safe_attributes 'isbn', :if => {|book, user| book.author == user}
-      def safe_attributes(*args)
-        @safe_attributes ||= []
-        if args.empty?
-          @safe_attributes
-        else
-          options = args.last.is_a?(Hash) ? args.pop : {}
-          @safe_attributes << [args, options]
-        end
-      end
-    end
-
-    # Returns an array that can be safely set by user or current user
-    #
-    # Example:
-    #   book.safe_attributes # => ['title', 'pages']
-    #   book.safe_attributes(book.author) # => ['title', 'pages', 'isbn']
-    def safe_attribute_names(user=User.current)
-      names = []
-      self.class.safe_attributes.collect do |attrs, options|
-        if options[:if].nil? || options[:if].call(self, user)
-          names += attrs.collect(&:to_s)
-        end
-      end
-      names.uniq
-    end
-
-    # Returns a hash with unsafe attributes removed
-    # from the given attrs hash
-    #
-    # Example:
-    #   book.delete_unsafe_attributes({'title' => 'My book', 'foo' => 'bar'})
-    #   # => {'title' => 'My book'}
-    def delete_unsafe_attributes(attrs, user=User.current)
-      safe = safe_attribute_names(user)
-      attrs.dup.delete_if {|k,v| !safe.include?(k)}
-    end
-
-    # Sets attributes from attrs that are safe
-    # attrs is a Hash with string keys
-    def safe_attributes=(attrs, user=User.current)
-      return unless attrs.is_a?(Hash)
-      self.attributes = delete_unsafe_attributes(attrs, user)
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/36/3661c33de673c9465c49c9836851558b3db7deb2.svn-base
--- /dev/null
+++ b/.svn/pristine/36/3661c33de673c9465c49c9836851558b3db7deb2.svn-base
@@ -0,0 +1,69 @@
+Installing gems for testing
+===========================
+
+Remove your .bundle/config if you've already installed Redmine without
+the test dependencies. Then, run `bundle install`.
+
+Running Tests
+=============
+
+Run `rake --tasks test` to see available tests.
+Run `rake test` to run the entire test suite (except the tests for the
+Apache perl module Redmine.pm and Capybara tests, see below).
+
+You can run `ruby test/unit/issue_test.rb` for running a single test case.
+
+Before running tests, you need to configure both development
+and test databases.
+
+Creating test repositories
+==========================
+
+Redmine supports a wide array of different version control systems.
+To test the support, a test repository needs to be created for each of those.
+
+Run `rake --tasks test:scm:setup` for a list of available test-repositories or
+run `rake test:scm:setup:all` to set up all of them. The repositories are
+unpacked into {redmine_root}/tmp/test.
+
+If the test repositories are not present, the tests that need them will be
+skipped.
+
+Creating a test ldap database
+=============================
+
+Redmine supports using LDAP for user authentications.  To test LDAP
+with Redmine, load the LDAP export from test/fixtures/ldap/test-ldap.ldif
+into a testing LDAP server. Make sure that the LDAP server can be accessed
+at 127.0.0.1 on port 389.
+
+Setting up the test LDAP server is beyond the scope of this documentation.
+The OpenLDAP project provides a simple LDAP implementation that should work
+good as a test server.
+
+If the LDAP is not available, the tests that need it will be skipped.
+
+Running Redmine.pm tests
+========================
+
+(work in progress)
+
+Running the tests for the Redmine.pm perl module needs a bit more setup.
+You need an Apache server with mod_perl, mod_dav_svn and Redmine.pm configured.
+See: http://www.redmine.org/projects/redmine/wiki/Repositories_access_control_with_apache_mod_dav_svn_and_mod_perl
+
+You need an empty repository accessible at http://127.0.0.1/svn/ecookbook
+Then, you can run the tests with:
+`ruby test\extra\redmine_pm\repository_subversion_test.rb`
+
+If you svn server is not running on localhost, you can use the REDMINE_TEST_DAV_SERVER
+environment variable to specify another host.
+
+Running Capybara tests
+======================
+
+You need to have PhantomJS WebDriver listening on port 4444:
+`phantomjs --webdriver 4444`
+
+Capybara tests can be run with:
+`rake test:ui`
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/36/36e4e7ac1d9860e3b7d32ae92975617939624a06.svn-base
--- /dev/null
+++ b/.svn/pristine/36/36e4e7ac1d9860e3b7d32ae92975617939624a06.svn-base
@@ -0,0 +1,1084 @@
+en:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%m/%d/%Y"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
+    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%m/%d/%Y %I:%M %p"
+      time: "%I:%M %p"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "half a minute"
+      less_than_x_seconds:
+        one:   "less than 1 second"
+        other: "less than %{count} seconds"
+      x_seconds:
+        one:   "1 second"
+        other: "%{count} seconds"
+      less_than_x_minutes:
+        one:   "less than a minute"
+        other: "less than %{count} minutes"
+      x_minutes:
+        one:   "1 minute"
+        other: "%{count} minutes"
+      about_x_hours:
+        one:   "about 1 hour"
+        other: "about %{count} hours"
+      x_hours:
+        one:   "1 hour"
+        other: "%{count} hours"
+      x_days:
+        one:   "1 day"
+        other: "%{count} days"
+      about_x_months:
+        one:   "about 1 month"
+        other: "about %{count} months"
+      x_months:
+        one:   "1 month"
+        other: "%{count} months"
+      about_x_years:
+        one:   "about 1 year"
+        other: "about %{count} years"
+      over_x_years:
+        one:   "over 1 year"
+        other: "over %{count} years"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "and"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "is not included in the list"
+        exclusion: "is reserved"
+        invalid: "is invalid"
+        confirmation: "doesn't match confirmation"
+        accepted: "must be accepted"
+        empty: "can't be empty"
+        blank: "can't be blank"
+        too_long: "is too long (maximum is %{count} characters)"
+        too_short: "is too short (minimum is %{count} characters)"
+        wrong_length: "is the wrong length (should be %{count} characters)"
+        taken: "has already been taken"
+        not_a_number: "is not a number"
+        not_a_date: "is not a valid date"
+        greater_than: "must be greater than %{count}"
+        greater_than_or_equal_to: "must be greater than or equal to %{count}"
+        equal_to: "must be equal to %{count}"
+        less_than: "must be less than %{count}"
+        less_than_or_equal_to: "must be less than or equal to %{count}"
+        odd: "must be odd"
+        even: "must be even"
+        greater_than_start_date: "must be greater than start date"
+        not_same_project: "doesn't belong to the same project"
+        circular_dependency: "This relation would create a circular dependency"
+        cant_link_an_issue_with_a_descendant: "An issue cannot be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: Please select
+
+  general_text_No: 'No'
+  general_text_Yes: 'Yes'
+  general_text_no: 'no'
+  general_text_yes: 'yes'
+  general_lang_name: 'English'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_updated: Account was successfully updated.
+  notice_account_invalid_creditentials: Invalid user or password
+  notice_account_password_updated: Password was successfully updated.
+  notice_account_wrong_password: Wrong password
+  notice_account_register_done: Account was successfully created. To activate your account, click on the link that was emailed to you.
+  notice_account_unknown_email: Unknown user.
+  notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
+  notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
+  notice_account_activated: Your account has been activated. You can now log in.
+  notice_successful_create: Successful creation.
+  notice_successful_update: Successful update.
+  notice_successful_delete: Successful deletion.
+  notice_successful_connection: Successful connection.
+  notice_file_not_found: The page you were trying to access doesn't exist or has been removed.
+  notice_locking_conflict: Data has been updated by another user.
+  notice_not_authorized: You are not authorized to access this page.
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  notice_email_sent: "An email was sent to %{value}"
+  notice_email_error: "An error occurred while sending mail (%{value})"
+  notice_feeds_access_key_reseted: Your RSS access key was reset.
+  notice_api_access_key_reseted: Your API access key was reset.
+  notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+  notice_account_pending: "Your account was created and is now pending administrator approval."
+  notice_default_data_loaded: Default configuration successfully loaded.
+  notice_unable_delete_version: Unable to delete version.
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})"
+  notice_issue_successful_create: "Issue %{id} created."
+  notice_issue_update_conflict: "The issue has been updated by an other user while you were editing it."
+  notice_account_deleted: "Your account has been permanently deleted."
+  notice_user_successful_create: "User %{id} created."
+
+  error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
+  error_scm_not_found: "The entry or revision was not found in the repository."
+  error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
+  error_scm_annotate: "The entry does not exist or cannot be annotated."
+  error_scm_annotate_big_text_file: "The entry cannot be annotated, as it exceeds the maximum text file size."
+  error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
+  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
+  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_can_not_delete_tracker: "This tracker contains issues and cannot be deleted."
+  error_can_not_remove_role: "This role is in use and cannot be deleted."
+  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version cannot be reopened'
+  error_can_not_archive_project: This project cannot be archived
+  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
+  error_workflow_copy_source: 'Please select a source tracker or role'
+  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
+  error_unable_delete_issue_status: 'Unable to delete issue status'
+  error_unable_to_connect: "Unable to connect (%{value})"
+  error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})"
+  error_session_expired: "Your session has expired. Please login again."
+  warning_attachments_not_saved: "%{count} file(s) could not be saved."
+
+  mail_subject_lost_password: "Your %{value} password"
+  mail_body_lost_password: 'To change your password, click on the following link:'
+  mail_subject_register: "Your %{value} account activation"
+  mail_body_register: 'To activate your account, click on the following link:'
+  mail_body_account_information_external: "You can use your %{value} account to log in."
+  mail_body_account_information: Your account information
+  mail_subject_account_activation_request: "%{value} account activation request"
+  mail_body_account_activation_request: "A new user (%{value}) has registered. The account is pending your approval:"
+  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
+  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
+
+  field_name: Name
+  field_description: Description
+  field_summary: Summary
+  field_is_required: Required
+  field_firstname: First name
+  field_lastname: Last name
+  field_mail: Email
+  field_filename: File
+  field_filesize: Size
+  field_downloads: Downloads
+  field_author: Author
+  field_created_on: Created
+  field_updated_on: Updated
+  field_closed_on: Closed
+  field_field_format: Format
+  field_is_for_all: For all projects
+  field_possible_values: Possible values
+  field_regexp: Regular expression
+  field_min_length: Minimum length
+  field_max_length: Maximum length
+  field_value: Value
+  field_category: Category
+  field_title: Title
+  field_project: Project
+  field_issue: Issue
+  field_status: Status
+  field_notes: Notes
+  field_is_closed: Issue closed
+  field_is_default: Default value
+  field_tracker: Tracker
+  field_subject: Subject
+  field_due_date: Due date
+  field_assigned_to: Assignee
+  field_priority: Priority
+  field_fixed_version: Target version
+  field_user: User
+  field_principal: Principal
+  field_role: Role
+  field_homepage: Homepage
+  field_is_public: Public
+  field_parent: Subproject of
+  field_is_in_roadmap: Issues displayed in roadmap
+  field_login: Login
+  field_mail_notification: Email notifications
+  field_admin: Administrator
+  field_last_login_on: Last connection
+  field_language: Language
+  field_effective_date: Date
+  field_password: Password
+  field_new_password: New password
+  field_password_confirmation: Confirmation
+  field_version: Version
+  field_type: Type
+  field_host: Host
+  field_port: Port
+  field_account: Account
+  field_base_dn: Base DN
+  field_attr_login: Login attribute
+  field_attr_firstname: Firstname attribute
+  field_attr_lastname: Lastname attribute
+  field_attr_mail: Email attribute
+  field_onthefly: On-the-fly user creation
+  field_start_date: Start date
+  field_done_ratio: "% Done"
+  field_auth_source: Authentication mode
+  field_hide_mail: Hide my email address
+  field_comments: Comment
+  field_url: URL
+  field_start_page: Start page
+  field_subproject: Subproject
+  field_hours: Hours
+  field_activity: Activity
+  field_spent_on: Date
+  field_identifier: Identifier
+  field_is_filter: Used as a filter
+  field_issue_to: Related issue
+  field_delay: Delay
+  field_assignable: Issues can be assigned to this role
+  field_redirect_existing_links: Redirect existing links
+  field_estimated_hours: Estimated time
+  field_column_names: Columns
+  field_time_entries: Log time
+  field_time_zone: Time zone
+  field_searchable: Searchable
+  field_default_value: Default value
+  field_comments_sorting: Display comments
+  field_parent_title: Parent page
+  field_editable: Editable
+  field_watcher: Watcher
+  field_identity_url: OpenID URL
+  field_content: Content
+  field_group_by: Group results by
+  field_sharing: Sharing
+  field_parent_issue: Parent task
+  field_member_of_group: "Assignee's group"
+  field_assigned_to_role: "Assignee's role"
+  field_text: Text field
+  field_visible: Visible
+  field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text"
+  field_issues_visibility: Issues visibility
+  field_is_private: Private
+  field_commit_logs_encoding: Commit messages encoding
+  field_scm_path_encoding: Path encoding
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvsroot: CVSROOT
+  field_cvs_module: Module
+  field_repository_is_default: Main repository
+  field_multiple: Multiple values
+  field_auth_source_ldap_filter: LDAP filter
+  field_core_fields: Standard fields
+  field_timeout: "Timeout (in seconds)"
+  field_board_parent: Parent forum
+  field_private_notes: Private notes
+  field_inherit_members: Inherit members
+
+  setting_app_title: Application title
+  setting_app_subtitle: Application subtitle
+  setting_welcome_text: Welcome text
+  setting_default_language: Default language
+  setting_login_required: Authentication required
+  setting_self_registration: Self-registration
+  setting_attachment_max_size: Maximum attachment size
+  setting_issues_export_limit: Issues export limit
+  setting_mail_from: Emission email address
+  setting_bcc_recipients: Blind carbon copy recipients (bcc)
+  setting_plain_text_mail: Plain text mail (no HTML)
+  setting_host_name: Host name and path
+  setting_text_formatting: Text formatting
+  setting_wiki_compression: Wiki history compression
+  setting_feeds_limit: Maximum number of items in Atom feeds
+  setting_default_projects_public: New projects are public by default
+  setting_autofetch_changesets: Fetch commits automatically
+  setting_sys_api_enabled: Enable WS for repository management
+  setting_commit_ref_keywords: Referencing keywords
+  setting_commit_fix_keywords: Fixing keywords
+  setting_autologin: Autologin
+  setting_date_format: Date format
+  setting_time_format: Time format
+  setting_cross_project_issue_relations: Allow cross-project issue relations
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  setting_issue_list_default_columns: Default columns displayed on the issue list
+  setting_repositories_encodings: Attachments and repositories encodings
+  setting_emails_header: Email header
+  setting_emails_footer: Email footer
+  setting_protocol: Protocol
+  setting_per_page_options: Objects per page options
+  setting_user_format: Users display format
+  setting_activity_days_default: Days displayed on project activity
+  setting_display_subprojects_issues: Display subprojects issues on main projects by default
+  setting_enabled_scm: Enabled SCM
+  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
+  setting_mail_handler_api_enabled: Enable WS for incoming emails
+  setting_mail_handler_api_key: API key
+  setting_sequential_project_identifiers: Generate sequential project identifiers
+  setting_gravatar_enabled: Use Gravatar user icons
+  setting_gravatar_default: Default Gravatar image
+  setting_diff_max_lines_displayed: Maximum number of diff lines displayed
+  setting_file_max_size_displayed: Maximum size of text files displayed inline
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_openid: Allow OpenID login and registration
+  setting_password_min_length: Minimum password length
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_field: Use the issue field
+  setting_issue_done_ratio_issue_status: Use the issue status
+  setting_start_of_week: Start calendars on
+  setting_rest_api_enabled: Enable REST web service
+  setting_cache_formatted_text: Cache formatted text
+  setting_default_notification_option: Default notification option
+  setting_commit_logtime_enabled: Enable time logging
+  setting_commit_logtime_activity_id: Activity for logged time
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  setting_issue_group_assignment: Allow issue assignment to groups
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  setting_unsubscribe: Allow users to delete their own account
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  setting_non_working_week_days: Non-working days
+  setting_jsonp_enabled: Enable JSONP support
+  setting_default_projects_tracker_ids: Default trackers for new projects
+
+  permission_add_project: Create project
+  permission_add_subprojects: Create subprojects
+  permission_edit_project: Edit project
+  permission_close_project: Close / reopen the project
+  permission_select_project_modules: Select project modules
+  permission_manage_members: Manage members
+  permission_manage_project_activities: Manage project activities
+  permission_manage_versions: Manage versions
+  permission_manage_categories: Manage issue categories
+  permission_view_issues: View Issues
+  permission_add_issues: Add issues
+  permission_edit_issues: Edit issues
+  permission_manage_issue_relations: Manage issue relations
+  permission_set_issues_private: Set issues public or private
+  permission_set_own_issues_private: Set own issues public or private
+  permission_add_issue_notes: Add notes
+  permission_edit_issue_notes: Edit notes
+  permission_edit_own_issue_notes: Edit own notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  permission_move_issues: Move issues
+  permission_delete_issues: Delete issues
+  permission_manage_public_queries: Manage public queries
+  permission_save_queries: Save queries
+  permission_view_gantt: View gantt chart
+  permission_view_calendar: View calendar
+  permission_view_issue_watchers: View watchers list
+  permission_add_issue_watchers: Add watchers
+  permission_delete_issue_watchers: Delete watchers
+  permission_log_time: Log spent time
+  permission_view_time_entries: View spent time
+  permission_edit_time_entries: Edit time logs
+  permission_edit_own_time_entries: Edit own time logs
+  permission_manage_news: Manage news
+  permission_comment_news: Comment news
+  permission_view_documents: View documents
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  permission_manage_files: Manage files
+  permission_view_files: View files
+  permission_manage_wiki: Manage wiki
+  permission_rename_wiki_pages: Rename wiki pages
+  permission_delete_wiki_pages: Delete wiki pages
+  permission_view_wiki_pages: View wiki
+  permission_view_wiki_edits: View wiki history
+  permission_edit_wiki_pages: Edit wiki pages
+  permission_delete_wiki_pages_attachments: Delete attachments
+  permission_protect_wiki_pages: Protect wiki pages
+  permission_manage_repository: Manage repository
+  permission_browse_repository: Browse repository
+  permission_view_changesets: View changesets
+  permission_commit_access: Commit access
+  permission_manage_boards: Manage forums
+  permission_view_messages: View messages
+  permission_add_messages: Post messages
+  permission_edit_messages: Edit messages
+  permission_edit_own_messages: Edit own messages
+  permission_delete_messages: Delete messages
+  permission_delete_own_messages: Delete own messages
+  permission_export_wiki_pages: Export wiki pages
+  permission_manage_subtasks: Manage subtasks
+  permission_manage_related_issues: Manage related issues
+
+  project_module_issue_tracking: Issue tracking
+  project_module_time_tracking: Time tracking
+  project_module_news: News
+  project_module_documents: Documents
+  project_module_files: Files
+  project_module_wiki: Wiki
+  project_module_repository: Repository
+  project_module_boards: Forums
+  project_module_calendar: Calendar
+  project_module_gantt: Gantt
+
+  label_user: User
+  label_user_plural: Users
+  label_user_new: New user
+  label_user_anonymous: Anonymous
+  label_project: Project
+  label_project_new: New project
+  label_project_plural: Projects
+  label_x_projects:
+    zero:  no projects
+    one:   1 project
+    other: "%{count} projects"
+  label_project_all: All Projects
+  label_project_latest: Latest projects
+  label_issue: Issue
+  label_issue_new: New issue
+  label_issue_plural: Issues
+  label_issue_view_all: View all issues
+  label_issues_by: "Issues by %{value}"
+  label_issue_added: Issue added
+  label_issue_updated: Issue updated
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_document: Document
+  label_document_new: New document
+  label_document_plural: Documents
+  label_document_added: Document added
+  label_role: Role
+  label_role_plural: Roles
+  label_role_new: New role
+  label_role_and_permissions: Roles and permissions
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_member: Member
+  label_member_new: New member
+  label_member_plural: Members
+  label_tracker: Tracker
+  label_tracker_plural: Trackers
+  label_tracker_new: New tracker
+  label_workflow: Workflow
+  label_issue_status: Issue status
+  label_issue_status_plural: Issue statuses
+  label_issue_status_new: New status
+  label_issue_category: Issue category
+  label_issue_category_plural: Issue categories
+  label_issue_category_new: New category
+  label_custom_field: Custom field
+  label_custom_field_plural: Custom fields
+  label_custom_field_new: New custom field
+  label_enumerations: Enumerations
+  label_enumeration_new: New value
+  label_information: Information
+  label_information_plural: Information
+  label_please_login: Please log in
+  label_register: Register
+  label_login_with_open_id_option: or login with OpenID
+  label_password_lost: Lost password
+  label_home: Home
+  label_my_page: My page
+  label_my_account: My account
+  label_my_projects: My projects
+  label_my_page_block: My page block
+  label_administration: Administration
+  label_login: Sign in
+  label_logout: Sign out
+  label_help: Help
+  label_reported_issues: Reported issues
+  label_assigned_to_me_issues: Issues assigned to me
+  label_last_login: Last connection
+  label_registered_on: Registered on
+  label_activity: Activity
+  label_overall_activity: Overall activity
+  label_user_activity: "%{value}'s activity"
+  label_new: New
+  label_logged_as: Logged in as
+  label_environment: Environment
+  label_authentication: Authentication
+  label_auth_source: Authentication mode
+  label_auth_source_new: New authentication mode
+  label_auth_source_plural: Authentication modes
+  label_subproject_plural: Subprojects
+  label_subproject_new: New subproject
+  label_and_its_subprojects: "%{value} and its subprojects"
+  label_min_max_length: Min - Max length
+  label_list: List
+  label_date: Date
+  label_integer: Integer
+  label_float: Float
+  label_boolean: Boolean
+  label_string: Text
+  label_text: Long text
+  label_attribute: Attribute
+  label_attribute_plural: Attributes
+  label_no_data: No data to display
+  label_change_status: Change status
+  label_history: History
+  label_attachment: File
+  label_attachment_new: New file
+  label_attachment_delete: Delete file
+  label_attachment_plural: Files
+  label_file_added: File added
+  label_report: Report
+  label_report_plural: Reports
+  label_news: News
+  label_news_new: Add news
+  label_news_plural: News
+  label_news_latest: Latest news
+  label_news_view_all: View all news
+  label_news_added: News added
+  label_news_comment_added: Comment added to a news
+  label_settings: Settings
+  label_overview: Overview
+  label_version: Version
+  label_version_new: New version
+  label_version_plural: Versions
+  label_close_versions: Close completed versions
+  label_confirmation: Confirmation
+  label_export_to: 'Also available in:'
+  label_read: Read...
+  label_public_projects: Public projects
+  label_open_issues: open
+  label_open_issues_plural: open
+  label_closed_issues: closed
+  label_closed_issues_plural: closed
+  label_x_open_issues_abbr_on_total:
+    zero:  0 open / %{total}
+    one:   1 open / %{total}
+    other: "%{count} open / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 open
+    one:   1 open
+    other: "%{count} open"
+  label_x_closed_issues_abbr:
+    zero:  0 closed
+    one:   1 closed
+    other: "%{count} closed"
+  label_x_issues:
+    zero:  0 issues
+    one:   1 issue
+    other: "%{count} issues"
+  label_total: Total
+  label_total_time: Total time
+  label_permissions: Permissions
+  label_current_status: Current status
+  label_new_statuses_allowed: New statuses allowed
+  label_all: all
+  label_any: any
+  label_none: none
+  label_nobody: nobody
+  label_next: Next
+  label_previous: Previous
+  label_used_by: Used by
+  label_details: Details
+  label_add_note: Add a note
+  label_per_page: Per page
+  label_calendar: Calendar
+  label_months_from: months from
+  label_gantt: Gantt
+  label_internal: Internal
+  label_last_changes: "last %{count} changes"
+  label_change_view_all: View all changes
+  label_personalize_page: Personalize this page
+  label_comment: Comment
+  label_comment_plural: Comments
+  label_x_comments:
+    zero: no comments
+    one: 1 comment
+    other: "%{count} comments"
+  label_comment_add: Add a comment
+  label_comment_added: Comment added
+  label_comment_delete: Delete comments
+  label_query: Custom query
+  label_query_plural: Custom queries
+  label_query_new: New query
+  label_my_queries: My custom queries
+  label_filter_add: Add filter
+  label_filter_plural: Filters
+  label_equals: is
+  label_not_equals: is not
+  label_in_less_than: in less than
+  label_in_more_than: in more than
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_between: between
+  label_in: in
+  label_today: today
+  label_all_time: all time
+  label_yesterday: yesterday
+  label_this_week: this week
+  label_last_week: last week
+  label_last_n_weeks: "last %{count} weeks"
+  label_last_n_days: "last %{count} days"
+  label_this_month: this month
+  label_last_month: last month
+  label_this_year: this year
+  label_date_range: Date range
+  label_less_than_ago: less than days ago
+  label_more_than_ago: more than days ago
+  label_ago: days ago
+  label_contains: contains
+  label_not_contains: doesn't contain
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  label_no_issues_in_project: no issues in project
+  label_day_plural: days
+  label_repository: Repository
+  label_repository_new: New repository
+  label_repository_plural: Repositories
+  label_browse: Browse
+  label_branch: Branch
+  label_tag: Tag
+  label_revision: Revision
+  label_revision_plural: Revisions
+  label_revision_id: "Revision %{value}"
+  label_associated_revisions: Associated revisions
+  label_added: added
+  label_modified: modified
+  label_copied: copied
+  label_renamed: renamed
+  label_deleted: deleted
+  label_latest_revision: Latest revision
+  label_latest_revision_plural: Latest revisions
+  label_view_revisions: View revisions
+  label_view_all_revisions: View all revisions
+  label_max_size: Maximum size
+  label_sort_highest: Move to top
+  label_sort_higher: Move up
+  label_sort_lower: Move down
+  label_sort_lowest: Move to bottom
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "Due in %{value}"
+  label_roadmap_overdue: "%{value} late"
+  label_roadmap_no_issues: No issues for this version
+  label_search: Search
+  label_result_plural: Results
+  label_all_words: All words
+  label_wiki: Wiki
+  label_wiki_edit: Wiki edit
+  label_wiki_edit_plural: Wiki edits
+  label_wiki_page: Wiki page
+  label_wiki_page_plural: Wiki pages
+  label_index_by_title: Index by title
+  label_index_by_date: Index by date
+  label_current_version: Current version
+  label_preview: Preview
+  label_feed_plural: Feeds
+  label_changes_details: Details of all changes
+  label_issue_tracking: Issue tracking
+  label_spent_time: Spent time
+  label_overall_spent_time: Overall spent time
+  label_f_hour: "%{value} hour"
+  label_f_hour_plural: "%{value} hours"
+  label_time_tracking: Time tracking
+  label_change_plural: Changes
+  label_statistics: Statistics
+  label_commits_per_month: Commits per month
+  label_commits_per_author: Commits per author
+  label_diff: diff
+  label_view_diff: View differences
+  label_diff_inline: inline
+  label_diff_side_by_side: side by side
+  label_options: Options
+  label_copy_workflow_from: Copy workflow from
+  label_permissions_report: Permissions report
+  label_watched_issues: Watched issues
+  label_related_issues: Related issues
+  label_applied_status: Applied status
+  label_loading: Loading...
+  label_relation_new: New relation
+  label_relation_delete: Delete relation
+  label_relates_to: Related to
+  label_duplicates: Duplicates
+  label_duplicated_by: Duplicated by
+  label_blocks: Blocks
+  label_blocked_by: Blocked by
+  label_precedes: Precedes
+  label_follows: Follows
+  label_copied_to: Copied to
+  label_copied_from: Copied from
+  label_end_to_start: end to start
+  label_end_to_end: end to end
+  label_start_to_start: start to start
+  label_start_to_end: start to end
+  label_stay_logged_in: Stay logged in
+  label_disabled: disabled
+  label_show_completed_versions: Show completed versions
+  label_me: me
+  label_board: Forum
+  label_board_new: New forum
+  label_board_plural: Forums
+  label_board_locked: Locked
+  label_board_sticky: Sticky
+  label_topic_plural: Topics
+  label_message_plural: Messages
+  label_message_last: Last message
+  label_message_new: New message
+  label_message_posted: Message added
+  label_reply_plural: Replies
+  label_send_information: Send account information to the user
+  label_year: Year
+  label_month: Month
+  label_week: Week
+  label_date_from: From
+  label_date_to: To
+  label_language_based: Based on user's language
+  label_sort_by: "Sort by %{value}"
+  label_send_test_email: Send a test email
+  label_feeds_access_key: RSS access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  label_feeds_access_key_created_on: "RSS access key created %{value} ago"
+  label_module_plural: Modules
+  label_added_time_by: "Added by %{author} %{age} ago"
+  label_updated_time_by: "Updated by %{author} %{age} ago"
+  label_updated_time: "Updated %{value} ago"
+  label_jump_to_a_project: Jump to a project...
+  label_file_plural: Files
+  label_changeset_plural: Changesets
+  label_default_columns: Default columns
+  label_no_change_option: (No change)
+  label_bulk_edit_selected_issues: Bulk edit selected issues
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  label_theme: Theme
+  label_default: Default
+  label_search_titles_only: Search titles only
+  label_user_mail_option_all: "For any event on all my projects"
+  label_user_mail_option_selected: "For any event on the selected projects only..."
+  label_user_mail_option_none: "No events"
+  label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
+  label_user_mail_option_only_assigned: "Only for things I am assigned to"
+  label_user_mail_option_only_owner: "Only for things I am the owner of"
+  label_user_mail_no_self_notified: "I don't want to be notified of changes that I make myself"
+  label_registration_activation_by_email: account activation by email
+  label_registration_manual_activation: manual account activation
+  label_registration_automatic_activation: automatic account activation
+  label_display_per_page: "Per page: %{value}"
+  label_age: Age
+  label_change_properties: Change properties
+  label_general: General
+  label_more: More
+  label_scm: SCM
+  label_plugins: Plugins
+  label_ldap_authentication: LDAP authentication
+  label_downloads_abbr: D/L
+  label_optional_description: Optional description
+  label_add_another_file: Add another file
+  label_preferences: Preferences
+  label_chronological_order: In chronological order
+  label_reverse_chronological_order: In reverse chronological order
+  label_planning: Planning
+  label_incoming_emails: Incoming emails
+  label_generate_key: Generate a key
+  label_issue_watchers: Watchers
+  label_example: Example
+  label_display: Display
+  label_sort: Sort
+  label_ascending: Ascending
+  label_descending: Descending
+  label_date_from_to: From %{start} to %{end}
+  label_wiki_content_added: Wiki page added
+  label_wiki_content_updated: Wiki page updated
+  label_group: Group
+  label_group_plural: Groups
+  label_group_new: New group
+  label_time_entry_plural: Spent time
+  label_version_sharing_none: Not shared
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_tree: With project tree
+  label_version_sharing_system: With all projects
+  label_update_issue_done_ratios: Update issue done ratios
+  label_copy_source: Source
+  label_copy_target: Target
+  label_copy_same_as_target: Same as target
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_api_access_key: API access key
+  label_missing_api_access_key: Missing an API access key
+  label_api_access_key_created_on: "API access key created %{value} ago"
+  label_profile: Profile
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_issues_visibility_all: All issues
+  label_issues_visibility_public: All non private issues
+  label_issues_visibility_own: Issues created by or assigned to the user
+  label_git_report_last_commit: Report last commit for files and directories
+  label_parent_revision: Parent
+  label_child_revision: Child
+  label_export_options: "%{export_format} export options"
+  label_copy_attachments: Copy attachments
+  label_copy_subtasks: Copy subtasks
+  label_item_position: "%{position} of %{count}"
+  label_completed_versions: Completed versions
+  label_search_for_watchers: Search for watchers to add
+  label_session_expiration: Session expiration
+  label_show_closed_projects: View closed projects
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  label_attribute_of_project: "Project's %{name}"
+  label_attribute_of_issue: "Issue's %{name}"
+  label_attribute_of_author: "Author's %{name}"
+  label_attribute_of_assigned_to: "Assignee's %{name}"
+  label_attribute_of_user: "User's %{name}"
+  label_attribute_of_fixed_version: "Target version's %{name}"
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  label_gantt_progress_line: Progress line
+
+  button_login: Login
+  button_submit: Submit
+  button_save: Save
+  button_check_all: Check all
+  button_uncheck_all: Uncheck all
+  button_collapse_all: Collapse all
+  button_expand_all: Expand all
+  button_delete: Delete
+  button_create: Create
+  button_create_and_continue: Create and continue
+  button_test: Test
+  button_edit: Edit
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  button_add: Add
+  button_change: Change
+  button_apply: Apply
+  button_clear: Clear
+  button_lock: Lock
+  button_unlock: Unlock
+  button_download: Download
+  button_list: List
+  button_view: View
+  button_move: Move
+  button_move_and_follow: Move and follow
+  button_back: Back
+  button_cancel: Cancel
+  button_activate: Activate
+  button_sort: Sort
+  button_log_time: Log time
+  button_rollback: Rollback to this version
+  button_watch: Watch
+  button_unwatch: Unwatch
+  button_reply: Reply
+  button_archive: Archive
+  button_unarchive: Unarchive
+  button_reset: Reset
+  button_rename: Rename
+  button_change_password: Change password
+  button_copy: Copy
+  button_copy_and_follow: Copy and follow
+  button_annotate: Annotate
+  button_update: Update
+  button_configure: Configure
+  button_quote: Quote
+  button_duplicate: Duplicate
+  button_show: Show
+  button_hide: Hide
+  button_edit_section: Edit this section
+  button_export: Export
+  button_delete_my_account: Delete my account
+  button_close: Close
+  button_reopen: Reopen
+
+  status_active: active
+  status_registered: registered
+  status_locked: locked
+
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+
+  version_status_open: open
+  version_status_locked: locked
+  version_status_closed: closed
+
+  field_active: Active
+
+  text_select_mail_notifications: Select actions for which email notifications should be sent.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 means no restriction
+  text_project_destroy_confirmation: Are you sure you want to delete this project and related data?
+  text_subprojects_destroy_warning: "Its subproject(s): %{value} will be also deleted."
+  text_workflow_edit: Select a role and a tracker to edit the workflow
+  text_are_you_sure: Are you sure?
+  text_journal_changed: "%{label} changed from %{old} to %{new}"
+  text_journal_changed_no_detail: "%{label} updated"
+  text_journal_set_to: "%{label} set to %{value}"
+  text_journal_deleted: "%{label} deleted (%{old})"
+  text_journal_added: "%{label} %{value} added"
+  text_tip_issue_begin_day: issue beginning this day
+  text_tip_issue_end_day: issue ending this day
+  text_tip_issue_begin_end_day: issue beginning and ending this day
+  text_project_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed, must start with a lower case letter.<br />Once saved, the identifier cannot be changed.'
+  text_caracters_maximum: "%{count} characters maximum."
+  text_caracters_minimum: "Must be at least %{count} characters long."
+  text_length_between: "Length between %{min} and %{max} characters."
+  text_tracker_no_workflow: No workflow defined for this tracker
+  text_unallowed_characters: Unallowed characters
+  text_comma_separated: Multiple values allowed (comma separated).
+  text_line_separated: Multiple values allowed (one line for each value).
+  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
+  text_issue_added: "Issue %{id} has been reported by %{author}."
+  text_issue_updated: "Issue %{id} has been updated by %{author}."
+  text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content?
+  text_issue_category_destroy_question: "Some issues (%{count}) are assigned to this category. What do you want to do?"
+  text_issue_category_destroy_assignments: Remove category assignments
+  text_issue_category_reassign_to: Reassign issues to this category
+  text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
+  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
+  text_load_default_configuration: Load the default configuration
+  text_status_changed_by_changeset: "Applied in changeset %{value}."
+  text_time_logged_by_changeset: "Applied in changeset %{value}."
+  text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?'
+  text_issues_destroy_descendants_confirmation: "This will also delete %{count} subtask(s)."
+  text_time_entries_destroy_confirmation: 'Are you sure you want to delete the selected time entr(y/ies)?'
+  text_select_project_modules: 'Select modules to enable for this project:'
+  text_default_administrator_account_changed: Default administrator account changed
+  text_file_repository_writable: Attachments directory writable
+  text_plugin_assets_writable: Plugin assets directory writable
+  text_rmagick_available: RMagick available (optional)
+  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do?"
+  text_destroy_time_entries: Delete reported hours
+  text_assign_time_entries_to_project: Assign reported hours to the project
+  text_reassign_time_entries: 'Reassign reported hours to this issue:'
+  text_user_wrote: "%{value} wrote:"
+  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
+  text_enumeration_category_reassign_to: 'Reassign them to this value:'
+  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
+  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
+  text_custom_field_possible_values_info: 'One line for each value'
+  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
+  text_wiki_page_nullify_children: "Keep child pages as root pages"
+  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
+  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
+  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
+  text_zoom_in: Zoom in
+  text_zoom_out: Zoom out
+  text_warn_on_leaving_unsaved: "The current page contains unsaved text that will be lost if you leave this page."
+  text_scm_path_encoding_note: "Default: UTF-8"
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  text_issue_conflict_resolution_overwrite: "Apply my changes anyway (previous notes will be kept but some changes may be overwritten)"
+  text_issue_conflict_resolution_add_notes: "Add my notes and discard my other changes"
+  text_issue_conflict_resolution_cancel: "Discard all my changes and redisplay %{link}"
+  text_account_destroy_confirmation: "Are you sure you want to proceed?\nYour account will be permanently deleted, with no way to reactivate it."
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  text_project_closed: This project is closed and read-only.
+  text_turning_multiple_off: "If you disable multiple values, multiple values will be removed in order to preserve only one value per item."
+
+  default_role_manager: Manager
+  default_role_developer: Developer
+  default_role_reporter: Reporter
+  default_tracker_bug: Bug
+  default_tracker_feature: Feature
+  default_tracker_support: Support
+  default_issue_status_new: New
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: Resolved
+  default_issue_status_feedback: Feedback
+  default_issue_status_closed: Closed
+  default_issue_status_rejected: Rejected
+  default_doc_category_user: User documentation
+  default_doc_category_tech: Technical documentation
+  default_priority_low: Low
+  default_priority_normal: Normal
+  default_priority_high: High
+  default_priority_urgent: Urgent
+  default_priority_immediate: Immediate
+  default_activity_design: Design
+  default_activity_development: Development
+
+  enumeration_issue_priorities: Issue priorities
+  enumeration_doc_categories: Document categories
+  enumeration_activities: Activities (time tracking)
+  enumeration_system_activity: System Activity
+  description_filter: Filter
+  description_search: Searchfield
+  description_choose_project: Projects
+  description_project_scope: Search scope
+  description_notes: Notes
+  description_message_content: Message content
+  description_query_sort_criteria_attribute: Sort attribute
+  description_query_sort_criteria_direction: Sort direction
+  description_user_mail_notification: Mail notification settings
+  description_available_columns: Available Columns
+  description_selected_columns: Selected Columns
+  description_all_columns: All Columns
+  description_issue_category_reassign: Choose issue category
+  description_wiki_subpages_reassign: Choose new parent page
+  description_date_range_list: Choose range from list
+  description_date_range_interval: Choose range by selecting start and end date
+  description_date_from: Enter start date
+  description_date_to: Enter end date
+  text_repository_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/37/3708cf8f04cafb1d769bb5ceca8ecd5dd9ef264d.svn-base
--- a/.svn/pristine/37/3708cf8f04cafb1d769bb5ceca8ecd5dd9ef264d.svn-base
+++ /dev/null
@@ -1,21 +0,0 @@
-<% reply_links = authorize_for('issues', 'edit') -%>
-<% for journal in journals %>
-  <div id="change-<%= journal.id %>" class="<%= journal.css_classes %>">
-    <h4><div class="journal-link"><%= link_to "##{journal.indice}", :anchor => "note-#{journal.indice}" %></div>
-    <%= avatar(journal.user, :size => "24") %>
-    <%= content_tag('a', '', :name => "note-#{journal.indice}")%>
-    <%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %></h4>
-
-    <% if journal.details.any? %>
-    <ul class="details">
-      <% for detail in journal.details %>
-       <li><%= show_detail(detail) %></li>
-      <% end %>
-    </ul>
-    <% end %>
-    <%= render_notes(issue, journal, :reply_links => reply_links) unless journal.notes.blank? %>
-  </div>
-  <%= call_hook(:view_issues_history_journal_bottom, { :journal => journal }) %>
-<% end %>
-
-<% heads_for_wiki_formatter if User.current.allowed_to?(:edit_issue_notes, issue.project) || User.current.allowed_to?(:edit_own_issue_notes, issue.project) %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/37/3761b0e47a324667f29e56ceb9695ed94f68fe4d.svn-base
--- /dev/null
+++ b/.svn/pristine/37/3761b0e47a324667f29e56ceb9695ed94f68fe4d.svn-base
@@ -0,0 +1,44 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class AutoCompletesController < ApplicationController
+  before_filter :find_project
+
+  def issues
+    @issues = []
+    q = (params[:q] || params[:term]).to_s.strip
+    if q.present?
+      scope = (params[:scope] == "all" || @project.nil? ? Issue : @project.issues).visible
+      if q.match(/\A#?(\d+)\z/)
+        @issues << scope.find_by_id($1.to_i)
+      end
+      @issues += scope.where("LOWER(#{Issue.table_name}.subject) LIKE LOWER(?)", "%#{q}%").order("#{Issue.table_name}.id DESC").limit(10).all
+      @issues.compact!
+    end
+    render :layout => false
+  end
+
+  private
+
+  def find_project
+    if params[:project_id].present?
+      @project = Project.find(params[:project_id])
+    end
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/37/376d8c99e588cd6ce8e1e869de342e76d55623d6.svn-base
--- a/.svn/pristine/37/376d8c99e588cd6ce8e1e869de342e76d55623d6.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-class AppAndPluginModel < ActiveRecord::Base
-  def self.report_location; TestHelper::report_location(__FILE__); end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/37/379e1dce88d814d8a7bcf79ecfe42aa08a6ba5f8.svn-base
--- a/.svn/pristine/37/379e1dce88d814d8a7bcf79ecfe42aa08a6ba5f8.svn-base
+++ /dev/null
@@ -1,19 +0,0 @@
-<%= error_messages_for 'enumeration' %>
-<div class="box">
-<!--[form:optvalue]-->
-<%= hidden_field 'enumeration', 'type'  %>
-
-<p><label for="enumeration_name"><%=l(:field_name)%></label>
-<%= text_field 'enumeration', 'name'  %></p>
-
-<p><label for="enumeration_active"><%=l(:field_active)%></label>
-<%= check_box 'enumeration', 'active'  %></p>
-
-<p><label for="enumeration_is_default"><%=l(:field_is_default)%></label>
-<%= check_box 'enumeration', 'is_default'  %></p>
-<!--[eoform:optvalue]-->
-
-<% @enumeration.custom_field_values.each do |value| %>
-  <p><%= custom_field_tag_with_label :enumeration, value %></p>
-<% end %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/37/37ab6adb38ec399dce62202cc442ace6462d7703.svn-base
--- a/.svn/pristine/37/37ab6adb38ec399dce62202cc442ace6462d7703.svn-base
+++ /dev/null
@@ -1,45 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module AttachmentsHelper
-  # Displays view/delete links to the attachments of the given object
-  # Options:
-  #   :author -- author names are not displayed if set to false
-  def link_to_attachments(container, options = {})
-    options.assert_valid_keys(:author)
-
-    if container.attachments.any?
-      options = {:deletable => container.attachments_deletable?, :author => true}.merge(options)
-      render :partial => 'attachments/links', :locals => {:attachments => container.attachments, :options => options}
-    end
-  end
-
-  def render_api_attachment(attachment, api)
-    api.attachment do
-      api.id attachment.id
-      api.filename attachment.filename
-      api.filesize attachment.filesize
-      api.content_type attachment.content_type
-      api.description attachment.description
-      api.content_url url_for(:controller => 'attachments', :action => 'download', :id => attachment, :filename => attachment.filename, :only_path => false)
-      api.author(:id => attachment.author.id, :name => attachment.author.name) if attachment.author
-      api.created_on attachment.created_on
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/37/37b31d80a7477985b5820b70128b01d1053a8cec.svn-base
--- a/.svn/pristine/37/37b31d80a7477985b5820b70128b01d1053a8cec.svn-base
+++ /dev/null
@@ -1,89 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class AuthSourceLdapTest < ActiveSupport::TestCase
-  fixtures :auth_sources
-
-  def setup
-  end
-
-  def test_create
-    a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName')
-    assert a.save
-  end
-
-  def test_should_strip_ldap_attributes
-    a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName',
-                           :attr_firstname => 'givenName ')
-    assert a.save
-    assert_equal 'givenName', a.reload.attr_firstname
-  end
-
-  def test_replace_port_zero_to_389
-    a = AuthSourceLdap.new(
-           :name => 'My LDAP', :host => 'ldap.example.net', :port => 0,
-           :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName',
-           :attr_firstname => 'givenName ')
-    assert a.save
-    assert_equal 389, a.port
-  end
-
-  if ldap_configured?
-    context '#authenticate' do
-      setup do
-        @auth = AuthSourceLdap.find(1)
-      end
-
-      context 'with a valid LDAP user' do
-        should 'return the user attributes' do
-          attributes =  @auth.authenticate('example1','123456')
-          assert attributes.is_a?(Hash), "An hash was not returned"
-          assert_equal 'Example', attributes[:firstname]
-          assert_equal 'One', attributes[:lastname]
-          assert_equal 'example1@redmine.org', attributes[:mail]
-          assert_equal @auth.id, attributes[:auth_source_id]
-          attributes.keys.each do |attribute|
-            assert User.new.respond_to?("#{attribute}="), "Unexpected :#{attribute} attribute returned"
-          end
-        end
-      end
-
-      context 'with an invalid LDAP user' do
-        should 'return nil' do
-          assert_equal nil, @auth.authenticate('nouser','123456')
-        end
-      end
-
-      context 'without a login' do
-        should 'return nil' do
-          assert_equal nil, @auth.authenticate('','123456')
-        end
-      end
-
-      context 'without a password' do
-        should 'return nil' do
-          assert_equal nil, @auth.authenticate('edavis','')
-        end
-      end
-
-    end
-  else
-    puts '(Test LDAP server not configured)'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/37/37c265b21c0c5ae4d4c2ec8cfe9dabe532a90dd1.svn-base
--- a/.svn/pristine/37/37c265b21c0c5ae4d4c2ec8cfe9dabe532a90dd1.svn-base
+++ /dev/null
@@ -1,32 +0,0 @@
-<div class="contextual">
-<%= link_to_if_authorized l(:button_edit), {:controller => 'documents', :action => 'edit', :id => @document}, :class => 'icon icon-edit', :accesskey => accesskey(:edit) %>
-<%= link_to_if_authorized l(:button_delete), {:controller => 'documents', :action => 'destroy', :id => @document}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
-</div>
-
-<h2><%=h @document.title %></h2>
-
-<p><em><%=h @document.category.name %><br />
-<%= format_date @document.created_on %></em></p>
-<div class="wiki">
-<%= textilizable @document.description, :attachments => @document.attachments %>
-</div>
-
-<h3><%= l(:label_attachment_plural) %></h3>
-<%= link_to_attachments @document %>
-
-<% if authorize_for('documents', 'add_attachment') %>
-<p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
-                                             :id => 'attach_files_link' %></p>
-  <% form_tag({ :controller => 'documents', :action => 'add_attachment', :id => @document }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
-  <div class="box">
-  <p><%= render :partial => 'attachments/form' %></p>
-  </div>
-  <%= submit_tag l(:button_add) %>
-  <% end %>
-<% end %>
-
-<% html_title @document.title -%>
-
-<% content_for :header_tags do %>
-    <%= stylesheet_link_tag 'scm' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/37/37f5b9c7485d4f52f7798b9d54c2aab8e937964a.svn-base
--- a/.svn/pristine/37/37f5b9c7485d4f52f7798b9d54c2aab8e937964a.svn-base
+++ /dev/null
@@ -1,38 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class TokenTest < ActiveSupport::TestCase
-  fixtures :tokens
-
-  def test_create
-    token = Token.new
-    token.save
-    assert_equal 40, token.value.length
-    assert !token.expired?
-  end
-
-  def test_create_should_remove_existing_tokens
-    user = User.find(1)
-    t1 = Token.create(:user => user, :action => 'autologin')
-    t2 = Token.create(:user => user, :action => 'autologin')
-    assert_not_equal t1.value, t2.value
-    assert !Token.exists?(t1.id)
-    assert  Token.exists?(t2.id)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/38/3813f5e1b5a3dcfe71214c111cf9817ac22039cc.svn-base
--- a/.svn/pristine/38/3813f5e1b5a3dcfe71214c111cf9817ac22039cc.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class GroupCustomField < CustomField
-  def type_name
-    :label_group_plural
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/38/383b53ea01b1aa0055dd414210668c6694327465.svn-base
--- /dev/null
+++ b/.svn/pristine/38/383b53ea01b1aa0055dd414210668c6694327465.svn-base
@@ -0,0 +1,77 @@
+<h2><%= link_to l(:label_tracker_plural), trackers_path %> &#187; <%= l(:field_summary) %></h2>
+
+<% if @trackers.any? %>
+  <%= form_tag fields_trackers_path do %>
+    <div class="autoscroll">
+    <table class="list">
+    <thead>
+      <tr>
+        <th></th>
+        <% @trackers.each do |tracker| %>
+        <th>
+          <%= tracker.name %>
+          <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('input.tracker-#{tracker.id}')",
+                                                              :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
+        </th>
+        <% end %>
+      </tr>
+    </thead>
+    <tbody>
+      <tr class="group open">
+        <td colspan="<%= @trackers.size + 1 %>">
+          <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
+          <%= l(:field_core_fields) %>
+        </td>
+      </tr>
+      <% Tracker::CORE_FIELDS.each do |field| %>
+      <tr class="<%= cycle("odd", "even") %>">
+        <td>
+          <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('input.core-field-#{field}')",
+                                                              :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
+          <%= l("field_#{field}".sub(/_id$/, '')) %>
+        </td>
+        <% @trackers.each do |tracker| %>
+        <td align="center">
+          <%= check_box_tag "trackers[#{tracker.id}][core_fields][]", field, tracker.core_fields.include?(field),
+                            :class => "tracker-#{tracker.id} core-field-#{field}" %>
+        </td>
+        <% end %>
+      </tr>
+      <% end %>
+      <% if @custom_fields.any? %>
+        <tr class="group open">
+          <td colspan="<%= @trackers.size + 1 %>">
+            <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
+            <%= l(:label_custom_field_plural) %>
+          </td>
+        </tr>
+        <% @custom_fields.each do |field| %>
+        <tr class="<%= cycle("odd", "even") %>">
+          <td>
+            <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('input.custom-field-#{field.id}')",
+                                                                :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
+            <%= field.name %>
+          </td>
+          <% @trackers.each do |tracker| %>
+          <td align="center">
+            <%= check_box_tag "trackers[#{tracker.id}][custom_field_ids][]", field.id, tracker.custom_fields.include?(field),
+                              :class => "tracker-#{tracker.id} custom-field-#{field.id}" %>
+          </td>
+          <% end %>
+        </tr>
+        <% end %>
+      <% end %>
+    </tbody>
+    </table>
+    </div>
+    <p><%= submit_tag l(:button_save) %></p>
+    <% @trackers.each do |tracker| %>
+      <%= hidden_field_tag "trackers[#{tracker.id}][core_fields][]", '' %>
+      <%= hidden_field_tag "trackers[#{tracker.id}][custom_field_ids][]", '' %>
+    <% end %>
+  <% end %>
+<% else %>
+  <p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
+
+<% html_title l(:field_summary) %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/38/387d439159b4d0ddd79c12022e45def5fc069c4f.svn-base
--- a/.svn/pristine/38/387d439159b4d0ddd79c12022e45def5fc069c4f.svn-base
+++ /dev/null
@@ -1,38 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class EnabledModule < ActiveRecord::Base
-  belongs_to :project
-
-  validates_presence_of :name
-  validates_uniqueness_of :name, :scope => :project_id
-
-  after_create :module_enabled
-
-  private
-
-  # after_create callback used to do things when a module is enabled
-  def module_enabled
-    case name
-    when 'wiki'
-      # Create a wiki with a default start page
-      if project && project.wiki.nil?
-        Wiki.create(:project => project, :start_page => 'Wiki')
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/38/389e9dcc20c4e06169902989d099cd6ec772aa7a.svn-base
--- a/.svn/pristine/38/389e9dcc20c4e06169902989d099cd6ec772aa7a.svn-base
+++ /dev/null
@@ -1,274 +0,0 @@
-= EDGE
-
-* Samuel Williams (http://www.oriontransfer.co.nz/):
-	Thanks to Tekin for his patches.
-	Updated migrations system to tie in more closely with the current rails mechanism.
-	Rake task for updating database schema info
-		rake db:migrate:upgrade_plugin_migrations
-	Please see http://engines.lighthouseapp.com/projects/10178-engines-plugin/tickets/17 for more information.
-
-* Refactored the view loading to work with changes in Edge Rails
-
-* Fixed integration of plugin migrations with the new, default timestamped migrations in Edge Rails
-
-* Refactored tests into the plugin itself - the plugin can now generate its own test_app harness and run tests within it.
-
-
-= 2.0.0 - (ANOTHER) MASSIVE INTERNAL REFACTORING
-
-* Engines now conforms to the new plugin loading mechanism, delegating plugin load order and lots of other things to Rails itself.
-
-
-
-= 1.2.2
-
-* Added the ability to code mix different types of files, cleaning up the existing code-mixing implementation slightly (Ticket #271)
-
-
-= 1.2.1
-
-* Added documentation to clarify some of the issues with Rails unloading classes that aren't required using "require_dependency" (Ticket #266)
-
-* Fixed a bug where test_help was being loaded when it wasn't needed, and was actually causing problems (Ticket #265)
-
-
-= 1.2.0 - MASSIVE INTERNAL REFACTORING
-
-* !!!Support for Rails < 1.2 has been dropped!!!; if you are using Rails =< 1.1.6, please use Engines 1.1.6, available from http://svn.rails-engines.org/engines/tags/rel_1.1.6
-
-* Engines are dead! Long live plugins! There is now no meaningful notion of an engine - all plugins can take advantage of the more powerful features that the engines plugin provides by including app directories, etc.
-
-* Init_engine.rb is no longer used; please use the plugin-standard init.rb instead.
-
-* Engines.start is no longer required; please use the config.plugins array provided by Rails instead
-
-* To get the most benefit from Engines, set config.plugins to ["engines", "*"] to load the engines plugin first, and then all other plugins in their normal order after.
-
-* Access all loaded plugins via the new Rails.plugins array, and by name using Rails.plugins[:plugin_name].
-
-* Access plugin metadata loaded automatically from about.yml: Rails.plugins[:name].about. Plugin#version is provided directly, for easy access.
-
-* Module.config is has been removed - use mattr_accessor instead, and initialize your default values via the init.rb mechanism.
-
-* Public asset helpers have been rewritten; instead of engine_stylesheet, now use stylesheet_link_tag :name, :plugin => "plugin_name"
-
-* Plugin migrations have been reworked to integrate into the main migration stream. Please run script/generate plugin_migration to create plugin migrations in your main application.
-
-* The fixture method for loading fixtures against any class has been removed; instead, engines will now provide a mechanism for loading fixtures from all plugins, by mirroring fixtures into a common location.
-
-* All references to engines have been removed; For example, any rake tasks which applied to engines now apply to all plugins. The default Rails rake tasks for plugins are overridden where necessary.
-
-* Layouts can now be shared via plugins - inspiration gratefully taken from PluginAWeek's plugin_routing :)
-
-* Actual routing from plugins is now possible, by including routes.rb in your plugin directory and using the from_plugin method in config/routes.rb (Ticket #182)
-
-* Controllers are no longer loaded twice if they're not present in the normal app/ directory (Ticket #177)
-
-* The preferred location for javascripts/stylesheets/etc is now 'assets' rather than 'public'
-
-* Ensure that plugins started before routing have their controllers appropriately added to config.controller_paths (Ticket #258)
-
-* Removed Engines.version - it's not longer relevant, now we're loading version information from about.yml files.
-
-* Added a huge amount of documentation to all new modules.
-
-* Added new warning message if installation of engines 1.2.x is attempted in a Rails 1.1.x application
-
-* Added details of the removal of the config method to UPGRADING
-
-* Removed the plugins:info rake task in favour of adding information to script/about via the Rails::Info module (Ticket #261)
-
-* Improved handling of testing and documentation tasks for plugins
-
-
-
-= 1.1.4
-
-* Fixed creation of multipart emails (Ticket #190)
-
-* Added a temporary fix to the code-mixing issue. In your engine's test/test_helper.rb, please add the following lines:
-
-   # Ensure that the code mixing and view loading from the application is disabled
-   Engines.disable_app_views_loading = true
-   Engines.disable_app_code_mixing = true
-
-  which will prevent code mixing for controllers and helpers, and loading views from the application. One thing to remember is to load any controllers/helpers using 'require_or_load' in your tests, to ensure that the engine behaviour is respected (Ticket #135)
-
-* Added tasks to easily test engines individually (Ticket #120)
-
-* Fixture extensions will now fail with an exception if the corresponding class cannot be loaded (Ticket #138)
-
-* Patch for new routing/controller loading in Rails 1.1.6. The routing code is now replaced with the contents of config.controller_paths, along with controller paths from any started engines (Ticket #196)
-
-* Rails' Configuration instance is now stored, and available from all engines and plugins.
-
-
-
-= 1.1.3
-
-* Fixed README to show 'models' rather than 'model' class (Ticket #167)
-* Fixed dependency loading to work with Rails 1.1.4 (Ticket #180)
-
-
-
-= 1.1.2
-
-* Added better fix to version checking (Ticket #130, jdell@gbdev.com).
-
-* Fixed generated init_engine.rb so that VERSION module doesn't cause probems (Ticket #131, japgolly@gmail.com)
-
-* Fixed error with Rails 1.0 when trying to ignore the engine_schema_info table (Ticket #132, snowblink@gmail.com)
-
-* Re-added old style rake tasks (Ticket #133)
-
-* No longer adding all subdirectories of <engine>/app or <engine>/lib, as this can cause issues when files are grouped in modules (Ticket #149, kasatani@gmail.com)
-
-* Fixed engine precidence ordering for Rails 1.1 (Ticket #146)
-
-* Added new Engines.each method to assist in processing the engines in the desired order (Ticket #146)
-
-* Fixed annoying error message at appears when starting the console in development mode (Ticket #134)
-
-* Engines is now super-careful about loading the correct version of Rails from vendor (Ticket #154)
-
-
-
-= 1.1.1
-
-* Fixed migration rake task failing when given a specific version (Ticket #115)
-
-* Added new rake task "test:engines" which will test engines (and other plugins) but ensure that the test database is cloned from development beforehand (Ticket #125)
-
-* Fixed issue where 'engine_schema_info' table was included in schema dumps (Ticket #87)
-
-* Fixed multi-part emails (Ticket #121)
-
-* Added an 'install.rb' file to new engines created by the bundled generator, which installs the engines plugin automatically if it doesn't already exist (Ticket #122)
-
-* Added a default VERSION module to generated engines (Ticket #123)
-
-* Refactored copying of engine's public files to a method of an Engine instance. You can now call Engines.get(:engine_name).copy_public_files (Ticket #108)
-
-* Changed engine generator templates from .rb files to .erb files (Ticket #106)
-
-* Fixed the test_helper.erb file to use the correct testing extensions and not load any schema - the schema will be cloned automatically via rake test:engines
-
-* Fixed problem when running with Rails 1.1.1 where version wasn't determined correctly (Ticket #129)
-
-* Fixed bug preventing engines from loading when both Rails 1.1.0 and 1.1.1 gems are installed and in use.
-
-* Updated version (d'oh!)
-
-
-
-= 1.1.0
-
-* Improved regexp matching for Rails 1.0 engines with peculiar paths
-
-* Engine instance objects can be accessed via Engines[:name], an alias for Engines.get(:name) (Ticket #99)
-
-* init_engine.rb is now processed as the final step in the Engine.start process, so it can access files within the lib directory, which is now in the $LOAD_PATH at that point. (Ticket #99)
-
-* Clarified MIT license (Ticket #98)
-
-* Updated Rake tasks to integrate smoothly with Rails 1.1 namespaces
-
-* Changed the version to "1.1.0 (svn)"
-
-* Added more information about using the plugin with Edge Rails to the README
-
-* moved extensions into lib/engines/ directory to enable use of Engines module in extension code.
-
-* Added conditional require_or_load method which attempts to detect the current Rails version. To use the Edge Rails version of the loading mechanism, add the line:
-
-*   Engines.config :edge, true
-
-* to your environment.rb file.
-
-* Merged changes from /branches/edge and /branches/rb_1.0 into /trunk
-
-* engine_schema_info now respects the prefix/suffixes set for ActiveRecord::Base (Ticket #67)
-
-* added ActiveRecord::Base.wrapped_table_name(name) method to assist in determining the correct table name
-
-
-
-= 1.0.6
-
-* Added ability to determine version information for engines: rake engine_info
-
-* Added a custom logger for the Engines module, to stop pollution of the Rails logs.
-
-* Added some more tests (in particular, see rails_engines/applications/engines_test).
-
-* Another attempt at solving Ticket #53 - controllers and helpers should now be loadable from modules, and if a full path (including RAILS_ROOT/ENGINES_ROOT) is given, it should be safely stripped from the require filename such that corresponding files can be located in any active engines. In other words, controller/helper overloading should now completely work, even if the controllers/helpers are in modules.
-
-* Added (finally) patch from Ticket #22 - ActionMailer helpers should now load
-
-* Removed support for Engines.start :engine, :engine_name => 'whatever'. It was pointless.
-
-* Fixed engine name referencing; engine_stylesheet/engine_javascript can now happily use shorthand engine names (i.e. :test == :test_engine) (Ticket #45)
-
-* Fixed minor documentation error ('Engine.start' ==> 'Engines.start') (Ticket #57)
-
-* Fixed double inclusion of RAILS_ROOT in engine_migrate rake task (Ticket #61)
-
-* Added ability to force config values even if given as a hash (Ticket #62)
-
-
-
-= 1.0.5
-
-* Fixed bug stopping fixtures from loading with PostgreSQL
-
-
-
-= 1.0.4
-
-* Another attempt at loading controllers within modules (Ticket #56)
-
-
-
-= 1.0.3
-
-* Fixed serious dependency bug stopping controllers being loaded (Ticket #56)
-
-
-
-= 1.0.2
-
-* Fixed bug with overloading controllers in modules from /app directory
-
-* Fixed exception thrown when public files couldn't be created; exception is now logged (Ticket #52)
-
-* Fixed problem with generated test_helper.rb file via File.expand_path (Ticket #50)
-
-
-
-= 1.0.1
-
-* Added engine generator for creation of new engines
-
-* Fixed 'Engine' typo in README
-
-* Fixed bug in fixtures extensions
-
-* Fixed /lib path management bug
-
-* Added method to determine public directory location from Engine object
-
-* Fixed bug in the error message in get_engine_dir()
-
-* Added proper component loading
-
-* Added preliminary tests for the config() methods module
-
-
-
-= pre-v170
-
-* Fixed copyright notices to point to DHH, rather than me.
-
-* Moved extension require statements into lib/engines.rb, so the will be loaded if another module/file calls require 'engines
-
-* Added a CHANGELOG file (this file)
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/38/38ca6dda2ba6a1320c43393fa70400cd1996e3e9.svn-base
--- a/.svn/pristine/38/38ca6dda2ba6a1320c43393fa70400cd1996e3e9.svn-base
+++ /dev/null
@@ -1,130 +0,0 @@
-require 'test/unit'
-
-$:.unshift File.expand_path('../../../lib', __FILE__)
-require 'coderay'
-
-class ExamplesTest < Test::Unit::TestCase
-  
-  def test_examples
-    # output as HTML div (using inline CSS styles)
-    div = CodeRay.scan('puts "Hello, world!"', :ruby).div
-    assert_equal <<-DIV, div
-<div class="CodeRay">
-  <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Hello, world!</span><span style="color:#710">&quot;</span></span></pre></div>
-</div>
-    DIV
-    
-    # ...with line numbers
-    div = CodeRay.scan(<<-CODE.chomp, :ruby).div(:line_numbers => :table)
-5.times do
-  puts 'Hello, world!'
-end
-    CODE
-    assert_equal <<-DIV, div
-<table class="CodeRay"><tr>
-  <td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
-<a href="#n2" name="n2">2</a>
-<a href="#n3" name="n3">3</a>
-</pre></td>
-  <td class="code"><pre><span style="color:#00D">5</span>.times <span style="color:#080;font-weight:bold">do</span>
-  puts <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">'</span><span style="color:#D20">Hello, world!</span><span style="color:#710">'</span></span>
-<span style="color:#080;font-weight:bold">end</span></pre></td>
-</tr></table>
-    DIV
-    
-    # output as standalone HTML page (using CSS classes)
-    page = CodeRay.scan('puts "Hello, world!"', :ruby).page
-    assert page[<<-PAGE]
-<body style="background-color: white;">
-
-<table class="CodeRay"><tr>
-  <td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>
-</pre></td>
-  <td class="code"><pre>puts <span class="string"><span class="delimiter">&quot;</span><span class="content">Hello, world!</span><span class="delimiter">&quot;</span></span></pre></td>
-</tr></table>
-
-</body>
-    PAGE
-    
-    # keep scanned tokens for later use
-    tokens = CodeRay.scan('{ "just": "an", "example": 42 }', :json)
-    assert_kind_of CodeRay::TokensProxy, tokens
-    
-    assert_equal ["{", :operator, " ", :space, :begin_group, :key,
-      "\"", :delimiter, "just", :content, "\"", :delimiter,
-      :end_group, :key, ":", :operator, " ", :space,
-      :begin_group, :string, "\"", :delimiter, "an", :content,
-      "\"", :delimiter, :end_group, :string, ",", :operator,
-      " ", :space, :begin_group, :key, "\"", :delimiter,
-      "example", :content, "\"", :delimiter, :end_group, :key,
-      ":", :operator, " ", :space, "42", :integer,
-      " ", :space, "}", :operator], tokens.tokens
-    
-    # produce a token statistic
-    assert_equal <<-STATISTIC, tokens.statistic
-
-Code Statistics
-
-Tokens                  26
-  Non-Whitespace        15
-Bytes Total             31
-
-Token Types (7):
-  type                     count     ratio    size (average)
--------------------------------------------------------------
-  TOTAL                       26  100.00 %     1.2
-  delimiter                    6   23.08 %     1.0
-  operator                     5   19.23 %     1.0
-  space                        5   19.23 %     1.0
-  key                          4   15.38 %     0.0
-  :begin_group                 3   11.54 %     0.0
-  :end_group                   3   11.54 %     0.0
-  content                      3   11.54 %     4.3
-  string                       2    7.69 %     0.0
-  integer                      1    3.85 %     2.0
-
-    STATISTIC
-    
-    # count the tokens
-    assert_equal 26, tokens.count
-    
-    # produce a HTML div, but with CSS classes
-    div = tokens.div(:css => :class)
-    assert_equal <<-DIV, div
-<div class="CodeRay">
-  <div class="code"><pre>{ <span class="key"><span class="delimiter">&quot;</span><span class="content">just</span><span class="delimiter">&quot;</span></span>: <span class="string"><span class="delimiter">&quot;</span><span class="content">an</span><span class="delimiter">&quot;</span></span>, <span class="key"><span class="delimiter">&quot;</span><span class="content">example</span><span class="delimiter">&quot;</span></span>: <span class="integer">42</span> }</pre></div>
-</div>
-    DIV
-    
-    # highlight a file (HTML div); guess the file type base on the extension
-    require 'coderay/helpers/file_type'
-    assert_equal :ruby, CodeRay::FileType[__FILE__]
-    
-    # get a new scanner for Python
-    python_scanner = CodeRay.scanner :python
-    assert_kind_of CodeRay::Scanners::Python, python_scanner
-    
-    # get a new encoder for terminal
-    terminal_encoder = CodeRay.encoder :term
-    assert_kind_of CodeRay::Encoders::Terminal, terminal_encoder
-    
-    # scanning into tokens
-    tokens = python_scanner.tokenize 'import this;  # The Zen of Python'
-    assert_equal ["import", :keyword, " ", :space, "this", :include,
-      ";", :operator, "  ", :space, "# The Zen of Python", :comment], tokens
-    
-    # format the tokens
-    term = terminal_encoder.encode_tokens(tokens)
-    assert_equal "\e[1;31mimport\e[0m \e[33mthis\e[0m;  \e[37m# The Zen of Python\e[0m", term
-    
-    # re-using scanner and encoder
-    ruby_highlighter = CodeRay::Duo[:ruby, :div]
-    div = ruby_highlighter.encode('puts "Hello, world!"')
-    assert_equal <<-DIV, div
-<div class="CodeRay">
-  <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Hello, world!</span><span style="color:#710">&quot;</span></span></pre></div>
-</div>
-    DIV
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/39/390e71b002ea8073c16b9d8e33ea8c3450b2266a.svn-base
--- a/.svn/pristine/39/390e71b002ea8073c16b9d8e33ea8c3450b2266a.svn-base
+++ /dev/null
@@ -1,117 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::PluginTest < ActiveSupport::TestCase
-
-  def setup
-    @klass = Redmine::Plugin
-    # In case some real plugins are installed
-    @klass.clear
-  end
-
-  def teardown
-    @klass.clear
-  end
-
-  def test_register
-    @klass.register :foo do
-      name 'Foo plugin'
-      url 'http://example.net/plugins/foo'
-      author 'John Smith'
-      author_url 'http://example.net/jsmith'
-      description 'This is a test plugin'
-      version '0.0.1'
-      settings :default => {'sample_setting' => 'value', 'foo'=>'bar'}, :partial => 'foo/settings'
-    end
-
-    assert_equal 1, @klass.all.size
-
-    plugin = @klass.find('foo')
-    assert plugin.is_a?(Redmine::Plugin)
-    assert_equal :foo, plugin.id
-    assert_equal 'Foo plugin', plugin.name
-    assert_equal 'http://example.net/plugins/foo', plugin.url
-    assert_equal 'John Smith', plugin.author
-    assert_equal 'http://example.net/jsmith', plugin.author_url
-    assert_equal 'This is a test plugin', plugin.description
-    assert_equal '0.0.1', plugin.version
-  end
-
-  def test_requires_redmine
-    test = self
-    version = Redmine::VERSION.to_a.slice(0,3).join('.')
-
-    @klass.register :foo do
-      test.assert requires_redmine(:version_or_higher => '0.1.0')
-      test.assert requires_redmine(:version_or_higher => version)
-      test.assert requires_redmine(version)
-      test.assert_raise Redmine::PluginRequirementError do
-        requires_redmine(:version_or_higher => '99.0.0')
-      end
-
-      test.assert requires_redmine(:version => version)
-      test.assert requires_redmine(:version => [version, '99.0.0'])
-      test.assert_raise Redmine::PluginRequirementError do
-        requires_redmine(:version => '99.0.0')
-      end
-      test.assert_raise Redmine::PluginRequirementError do
-        requires_redmine(:version => ['98.0.0', '99.0.0'])
-      end
-    end
-  end
-
-  def test_requires_redmine_plugin
-    test = self
-    other_version = '0.5.0'
-
-    @klass.register :other do
-      name 'Other'
-      version other_version
-    end
-
-    @klass.register :foo do
-      test.assert requires_redmine_plugin(:other, :version_or_higher => '0.1.0')
-      test.assert requires_redmine_plugin(:other, :version_or_higher => other_version)
-      test.assert requires_redmine_plugin(:other, other_version)
-      test.assert_raise Redmine::PluginRequirementError do
-        requires_redmine_plugin(:other, :version_or_higher => '99.0.0')
-      end
-
-      test.assert requires_redmine_plugin(:other, :version => other_version)
-      test.assert requires_redmine_plugin(:other, :version => [other_version, '99.0.0'])
-      test.assert_raise Redmine::PluginRequirementError do
-        requires_redmine_plugin(:other, :version => '99.0.0')
-      end
-      test.assert_raise Redmine::PluginRequirementError do
-        requires_redmine_plugin(:other, :version => ['98.0.0', '99.0.0'])
-      end
-      # Missing plugin
-      test.assert_raise Redmine::PluginNotFound do
-        requires_redmine_plugin(:missing, :version_or_higher => '0.1.0')
-      end
-      test.assert_raise Redmine::PluginNotFound do
-        requires_redmine_plugin(:missing, '0.1.0')
-      end
-      test.assert_raise Redmine::PluginNotFound do
-        requires_redmine_plugin(:missing, :version => '0.1.0')
-      end
-
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/39/391b1c790687d518fea17dcd03fc5883b7da327b.svn-base
--- /dev/null
+++ b/.svn/pristine/39/391b1c790687d518fea17dcd03fc5883b7da327b.svn-base
@@ -0,0 +1,23 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssuePriorityCustomField < CustomField
+  def type_name
+    :enumeration_issue_priorities
+  end
+end
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/39/3989df463d71da05bed8c7a24a4bb085b8755d7f.svn-base
--- a/.svn/pristine/39/3989df463d71da05bed8c7a24a4bb085b8755d7f.svn-base
+++ /dev/null
@@ -1,17 +0,0 @@
-Return-Path: <john.doe@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
-Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
-To: <redmine@somenet.foo>
-Subject: Ticket by unknown user
-Date: Sun, 22 Jun 2008 12:28:07 +0200
-MIME-Version: 1.0
-Content-Type: text/plain;
-	format=flowed;
-	charset="iso-8859-1";
-	reply-type=original
-Content-Transfer-Encoding: 7bit
-
-This is a ticket submitted by an unknown user.
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/39/399f2a5d4375067a1c2f5abc78f9f28143ca9321.svn-base
--- /dev/null
+++ b/.svn/pristine/39/399f2a5d4375067a1c2f5abc78f9f28143ca9321.svn-base
@@ -0,0 +1,95 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class ReportsController < ApplicationController
+  menu_item :issues
+  before_filter :find_project, :authorize, :find_issue_statuses
+
+  def issue_report
+    @trackers = @project.trackers
+    @versions = @project.shared_versions.sort
+    @priorities = IssuePriority.all.reverse
+    @categories = @project.issue_categories
+    @assignees = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
+    @authors = @project.users.sort
+    @subprojects = @project.descendants.visible
+
+    @issues_by_tracker = Issue.by_tracker(@project)
+    @issues_by_version = Issue.by_version(@project)
+    @issues_by_priority = Issue.by_priority(@project)
+    @issues_by_category = Issue.by_category(@project)
+    @issues_by_assigned_to = Issue.by_assigned_to(@project)
+    @issues_by_author = Issue.by_author(@project)
+    @issues_by_subproject = Issue.by_subproject(@project) || []
+
+    render :template => "reports/issue_report"
+  end
+
+  def issue_report_details
+    case params[:detail]
+    when "tracker"
+      @field = "tracker_id"
+      @rows = @project.trackers
+      @data = Issue.by_tracker(@project)
+      @report_title = l(:field_tracker)
+    when "version"
+      @field = "fixed_version_id"
+      @rows = @project.shared_versions.sort
+      @data = Issue.by_version(@project)
+      @report_title = l(:field_version)
+    when "priority"
+      @field = "priority_id"
+      @rows = IssuePriority.all.reverse
+      @data = Issue.by_priority(@project)
+      @report_title = l(:field_priority)
+    when "category"
+      @field = "category_id"
+      @rows = @project.issue_categories
+      @data = Issue.by_category(@project)
+      @report_title = l(:field_category)
+    when "assigned_to"
+      @field = "assigned_to_id"
+      @rows = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
+      @data = Issue.by_assigned_to(@project)
+      @report_title = l(:field_assigned_to)
+    when "author"
+      @field = "author_id"
+      @rows = @project.users.sort
+      @data = Issue.by_author(@project)
+      @report_title = l(:field_author)
+    when "subproject"
+      @field = "project_id"
+      @rows = @project.descendants.visible
+      @data = Issue.by_subproject(@project) || []
+      @report_title = l(:field_subproject)
+    end
+
+    respond_to do |format|
+      if @field
+        format.html {}
+      else
+        format.html { redirect_to :action => 'issue_report', :id => @project }
+      end
+    end
+  end
+
+  private
+
+  def find_issue_statuses
+    @statuses = IssueStatus.sorted.all
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/39/39a608089a590c01af61f645951f37bfe827c689.svn-base
--- /dev/null
+++ b/.svn/pristine/39/39a608089a590c01af61f645951f37bfe827c689.svn-base
@@ -0,0 +1,61 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AdminTest < ActionController::IntegrationTest
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  def test_add_user
+    log_user("admin", "admin")
+    get "/users/new"
+    assert_response :success
+    assert_template "users/new"
+    post "/users",
+         :user => { :login => "psmith", :firstname => "Paul",
+                    :lastname => "Smith", :mail => "psmith@somenet.foo",
+                    :language => "en", :password => "psmith09",
+                    :password_confirmation => "psmith09" }
+
+    user = User.find_by_login("psmith")
+    assert_kind_of User, user
+    assert_redirected_to "/users/#{ user.id }/edit"
+
+    logged_user = User.try_to_login("psmith", "psmith09")
+    assert_kind_of User, logged_user
+    assert_equal "Paul", logged_user.firstname
+
+    put "users/#{user.id}", :id => user.id, :user => { :status => User::STATUS_LOCKED }
+    assert_redirected_to "/users/#{ user.id }/edit"
+    locked_user = User.try_to_login("psmith", "psmith09")
+    assert_equal nil, locked_user
+  end
+
+  test "Add a user as an anonymous user should fail" do
+    post '/users',
+         :user => { :login => 'psmith', :firstname => 'Paul'},
+         :password => "psmith09", :password_confirmation => "psmith09"
+    assert_response :redirect
+    assert_redirected_to "/login?back_url=http%3A%2F%2Fwww.example.com%2Fusers"
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/39/39e07ef2d5632f8e7ca245cda7735bd6e7674f6d.svn-base
--- /dev/null
+++ b/.svn/pristine/39/39e07ef2d5632f8e7ca245cda7735bd6e7674f6d.svn-base
@@ -0,0 +1,341 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/abstract_adapter'
+
+module Redmine
+  module Scm
+    module Adapters
+      class BazaarAdapter < AbstractAdapter
+
+        # Bazaar executable name
+        BZR_BIN = Redmine::Configuration['scm_bazaar_command'] || "bzr"
+
+        class << self
+          def client_command
+            @@bin    ||= BZR_BIN
+          end
+
+          def sq_bin
+            @@sq_bin ||= shell_quote_command
+          end
+
+          def client_version
+            @@client_version ||= (scm_command_version || [])
+          end
+
+          def client_available
+            !client_version.empty?
+          end
+
+          def scm_command_version
+            scm_version = scm_version_from_command_line.dup
+            if scm_version.respond_to?(:force_encoding)
+              scm_version.force_encoding('ASCII-8BIT')
+            end
+            if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
+              m[2].scan(%r{\d+}).collect(&:to_i)
+            end
+          end
+
+          def scm_version_from_command_line
+            shellout("#{sq_bin} --version") { |io| io.read }.to_s
+          end
+        end
+
+        def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil)
+          @url = url
+          @root_url = url
+          @path_encoding = 'UTF-8'
+          # do not call *super* for non ASCII repository path
+        end
+
+        def bzr_path_encodig=(encoding)
+          @path_encoding = encoding
+        end
+
+        # Get info about the repository
+        def info
+          cmd_args = %w|revno|
+          cmd_args << bzr_target('')
+          info = nil
+          scm_cmd(*cmd_args) do |io|
+            if io.read =~ %r{^(\d+)\r?$}
+              info = Info.new({:root_url => url,
+                               :lastrev => Revision.new({
+                                 :identifier => $1
+                               })
+                             })
+            end
+          end
+          info
+        rescue ScmCommandAborted
+          return nil
+        end
+
+        # Returns an Entries collection
+        # or nil if the given path doesn't exist in the repository
+        def entries(path=nil, identifier=nil, options={})
+          path ||= ''
+          entries = Entries.new
+          identifier = -1 unless identifier && identifier.to_i > 0
+          cmd_args = %w|ls -v --show-ids|
+          cmd_args << "-r#{identifier.to_i}"
+          cmd_args << bzr_target(path)
+          scm_cmd(*cmd_args) do |io|
+            prefix_utf8 = "#{url}/#{path}".gsub('\\', '/')
+            logger.debug "PREFIX: #{prefix_utf8}"
+            prefix = scm_iconv(@path_encoding, 'UTF-8', prefix_utf8)
+            prefix.force_encoding('ASCII-8BIT') if prefix.respond_to?(:force_encoding)
+            re = %r{^V\s+(#{Regexp.escape(prefix)})?(\/?)([^\/]+)(\/?)\s+(\S+)\r?$}
+            io.each_line do |line|
+              next unless line =~ re
+              name_locale, slash, revision = $3.strip, $4, $5.strip
+              name = scm_iconv('UTF-8', @path_encoding, name_locale)
+              entries << Entry.new({:name => name,
+                                    :path => ((path.empty? ? "" : "#{path}/") + name),
+                                    :kind => (slash.blank? ? 'file' : 'dir'),
+                                    :size => nil,
+                                    :lastrev => Revision.new(:revision => revision)
+                                  })
+            end
+          end
+          if logger && logger.debug?
+            logger.debug("Found #{entries.size} entries in the repository for #{target(path)}")
+          end
+          entries.sort_by_name
+        rescue ScmCommandAborted
+          return nil
+        end
+
+        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
+          path ||= ''
+          identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : 'last:1'
+          identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1
+          revisions = Revisions.new
+          cmd_args = %w|log -v --show-ids|
+          cmd_args << "-r#{identifier_to}..#{identifier_from}"
+          cmd_args << bzr_target(path)
+          scm_cmd(*cmd_args) do |io|
+            revision = nil
+            parsing  = nil
+            io.each_line do |line|
+              if line =~ /^----/
+                revisions << revision if revision
+                revision = Revision.new(:paths => [], :message => '')
+                parsing = nil
+              else
+                next unless revision
+                if line =~ /^revno: (\d+)($|\s\[merge\]$)/
+                  revision.identifier = $1.to_i
+                elsif line =~ /^committer: (.+)$/
+                  revision.author = $1.strip
+                elsif line =~ /^revision-id:(.+)$/
+                  revision.scmid = $1.strip
+                elsif line =~ /^timestamp: (.+)$/
+                  revision.time = Time.parse($1).localtime
+                elsif line =~ /^    -----/
+                  # partial revisions
+                  parsing = nil unless parsing == 'message'
+                elsif line =~ /^(message|added|modified|removed|renamed):/
+                  parsing = $1
+                elsif line =~ /^  (.*)$/
+                  if parsing == 'message'
+                    revision.message << "#{$1}\n"
+                  else
+                    if $1 =~ /^(.*)\s+(\S+)$/
+                      path_locale = $1.strip
+                      path = scm_iconv('UTF-8', @path_encoding, path_locale)
+                      revid = $2
+                      case parsing
+                      when 'added'
+                        revision.paths << {:action => 'A', :path => "/#{path}", :revision => revid}
+                      when 'modified'
+                        revision.paths << {:action => 'M', :path => "/#{path}", :revision => revid}
+                      when 'removed'
+                        revision.paths << {:action => 'D', :path => "/#{path}", :revision => revid}
+                      when 'renamed'
+                        new_path = path.split('=>').last
+                        if new_path
+                          revision.paths << {:action => 'M', :path => "/#{new_path.strip}",
+                                             :revision => revid}
+                        end
+                      end
+                    end
+                  end
+                else
+                  parsing = nil
+                end
+              end
+            end
+            revisions << revision if revision
+          end
+          revisions
+        rescue ScmCommandAborted
+          return nil
+        end
+
+        def diff(path, identifier_from, identifier_to=nil)
+          path ||= ''
+          if identifier_to
+            identifier_to = identifier_to.to_i
+          else
+            identifier_to = identifier_from.to_i - 1
+          end
+          if identifier_from
+            identifier_from = identifier_from.to_i
+          end
+          diff = []
+          cmd_args = %w|diff|
+          cmd_args << "-r#{identifier_to}..#{identifier_from}"
+          cmd_args << bzr_target(path)
+          scm_cmd_no_raise(*cmd_args) do |io|
+            io.each_line do |line|
+              diff << line
+            end
+          end
+          diff
+        end
+
+        def cat(path, identifier=nil)
+          cat = nil
+          cmd_args = %w|cat|
+          cmd_args << "-r#{identifier.to_i}" if identifier && identifier.to_i > 0
+          cmd_args << bzr_target(path)
+          scm_cmd(*cmd_args) do |io|
+            io.binmode
+            cat = io.read
+          end
+          cat
+        rescue ScmCommandAborted
+          return nil
+        end
+
+        def annotate(path, identifier=nil)
+          blame = Annotate.new
+          cmd_args = %w|annotate -q --all|
+          cmd_args << "-r#{identifier.to_i}" if identifier && identifier.to_i > 0
+          cmd_args << bzr_target(path)
+          scm_cmd(*cmd_args) do |io|
+            author     = nil
+            identifier = nil
+            io.each_line do |line|
+              next unless line =~ %r{^(\d+) ([^|]+)\| (.*)$}
+              rev = $1
+              blame.add_line($3.rstrip,
+                 Revision.new(
+                  :identifier => rev,
+                  :revision   => rev,
+                  :author     => $2.strip
+                  ))
+            end
+          end
+          blame
+        rescue ScmCommandAborted
+          return nil
+        end
+
+        def self.branch_conf_path(path)
+          bcp = nil
+          m = path.match(%r{^(.*[/\\])\.bzr.*$})
+          if m
+            bcp = m[1]
+          else
+            bcp = path
+          end
+          bcp.gsub!(%r{[\/\\]$}, "")
+          if bcp
+            bcp = File.join(bcp, ".bzr", "branch", "branch.conf")
+          end
+          bcp
+        end
+
+        def append_revisions_only
+          return @aro if ! @aro.nil?
+          @aro = false
+          bcp = self.class.branch_conf_path(url)
+          if bcp && File.exist?(bcp)
+            begin
+              f = File::open(bcp, "r")
+              cnt = 0
+              f.each_line do |line|
+                l = line.chomp.to_s
+                if l =~ /^\s*append_revisions_only\s*=\s*(\w+)\s*$/
+                  str_aro = $1
+                  if str_aro.upcase == "TRUE"
+                    @aro = true
+                    cnt += 1
+                  elsif str_aro.upcase == "FALSE"
+                    @aro = false
+                    cnt += 1
+                  end
+                  if cnt > 1
+                    @aro = false
+                    break
+                  end
+                end
+              end
+            ensure
+              f.close
+            end
+          end
+          @aro
+        end
+
+        def scm_cmd(*args, &block)
+          full_args = []
+          full_args += args
+          full_args_locale = []
+          full_args.map do |e|
+            full_args_locale << scm_iconv(@path_encoding, 'UTF-8', e)
+          end
+          ret = shellout(
+                   self.class.sq_bin + ' ' + 
+                     full_args_locale.map { |e| shell_quote e.to_s }.join(' '),
+                   &block
+                   )
+          if $? && $?.exitstatus != 0
+            raise ScmCommandAborted, "bzr exited with non-zero status: #{$?.exitstatus}"
+          end
+          ret
+        end
+        private :scm_cmd
+
+        def scm_cmd_no_raise(*args, &block)
+          full_args = []
+          full_args += args
+          full_args_locale = []
+          full_args.map do |e|
+            full_args_locale << scm_iconv(@path_encoding, 'UTF-8', e)
+          end
+          ret = shellout(
+                   self.class.sq_bin + ' ' + 
+                     full_args_locale.map { |e| shell_quote e.to_s }.join(' '),
+                   &block
+                   )
+          ret
+        end
+        private :scm_cmd_no_raise
+
+        def bzr_target(path)
+          target(path, false)
+        end
+        private :bzr_target
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/39/39e52a0654ea7d5e49b76b29ba4c1190481acad6.svn-base
--- a/.svn/pristine/39/39e52a0654ea7d5e49b76b29ba4c1190481acad6.svn-base
+++ /dev/null
@@ -1,118 +0,0 @@
-# RedMine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# FileSystem adapter
-# File written by Paul Rivier, at Demotera.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/abstract_adapter'
-require 'find'
-
-module Redmine
-  module Scm
-    module Adapters
-      class FilesystemAdapter < AbstractAdapter
-
-        class << self
-          def client_available
-            true
-          end
-        end
-
-        def initialize(url, root_url=nil, login=nil, password=nil,
-                       path_encoding=nil)
-          @url = with_trailling_slash(url)
-          @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
-        end
-
-        def path_encoding
-          @path_encoding
-        end
-
-        def format_path_ends(path, leading=true, trailling=true)
-          path = leading ? with_leading_slash(path) :
-            without_leading_slash(path)
-          trailling ? with_trailling_slash(path) :
-            without_trailling_slash(path)
-        end
-
-        def info
-          info = Info.new({:root_url => target(),
-                            :lastrev => nil
-                          })
-          info
-        rescue CommandFailed
-          return nil
-        end
-
-        def entries(path="", identifier=nil, options={})
-          entries = Entries.new
-          trgt_utf8 = target(path)
-          trgt = scm_iconv(@path_encoding, 'UTF-8', trgt_utf8)
-          Dir.new(trgt).each do |e1|
-            e_utf8 = scm_iconv('UTF-8', @path_encoding, e1)
-            next if e_utf8.blank?
-            relative_path_utf8 = format_path_ends(
-                (format_path_ends(path,false,true) + e_utf8),false,false)
-            t1_utf8 = target(relative_path_utf8)
-            t1 = scm_iconv(@path_encoding, 'UTF-8', t1_utf8)
-            relative_path = scm_iconv(@path_encoding, 'UTF-8', relative_path_utf8)
-            e1 = scm_iconv(@path_encoding, 'UTF-8', e_utf8)
-            if File.exist?(t1) and # paranoid test
-                  %w{file directory}.include?(File.ftype(t1)) and # avoid special types
-                  not File.basename(e1).match(/^\.+$/) # avoid . and ..
-              p1         = File.readable?(t1) ? relative_path : ""
-              utf_8_path = scm_iconv('UTF-8', @path_encoding, p1)
-              entries <<
-                Entry.new({ :name => scm_iconv('UTF-8', @path_encoding, File.basename(e1)),
-                          # below : list unreadable files, but dont link them.
-                          :path => utf_8_path,
-                          :kind => (File.directory?(t1) ? 'dir' : 'file'),
-                          :size => (File.directory?(t1) ? nil : [File.size(t1)].pack('l').unpack('L').first),
-                          :lastrev =>
-                              Revision.new({:time => (File.mtime(t1)) })
-                        })
-            end
-          end
-          entries.sort_by_name
-        rescue  => err
-          logger.error "scm: filesystem: error: #{err.message}"
-          raise CommandFailed.new(err.message)
-        end
-
-        def cat(path, identifier=nil)
-          p = scm_iconv(@path_encoding, 'UTF-8', target(path))
-          File.new(p, "rb").read
-        rescue  => err
-          logger.error "scm: filesystem: error: #{err.message}"
-          raise CommandFailed.new(err.message)
-        end
-
-        private
-
-        # AbstractAdapter::target is implicitly made to quote paths.
-        # Here we do not shell-out, so we do not want quotes.
-        def target(path=nil)
-          # Prevent the use of ..
-          if path and !path.match(/(^|\/)\.\.(\/|$)/)
-            return "#{self.url}#{without_leading_slash(path)}"
-          end
-          return self.url
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/39/39faeb0151b407d013fa291b6fe7a94c6860c63f.svn-base
--- a/.svn/pristine/39/39faeb0151b407d013fa291b6fe7a94c6860c63f.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class AppAndPluginController < ApplicationController
-  def an_action
-    render_class_and_action 'from app'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3a/3a0e01441fbdb0f5b1aa103fddb2a58126ec7f0e.svn-base
--- /dev/null
+++ b/.svn/pristine/3a/3a0e01441fbdb0f5b1aa103fddb2a58126ec7f0e.svn-base
@@ -0,0 +1,33 @@
+<h2><%=l(:label_report_plural)%></h2>
+
+<div class="splitcontentleft">
+<h3><%=l(:field_tracker)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'tracker') %></h3>
+<%= render :partial => 'simple', :locals => { :data => @issues_by_tracker, :field_name => "tracker_id", :rows => @trackers } %>
+<br />
+<h3><%=l(:field_priority)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'priority') %></h3>
+<%= render :partial => 'simple', :locals => { :data => @issues_by_priority, :field_name => "priority_id", :rows => @priorities } %>
+<br />
+<h3><%=l(:field_assigned_to)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'assigned_to') %></h3>
+<%= render :partial => 'simple', :locals => { :data => @issues_by_assigned_to, :field_name => "assigned_to_id", :rows => @assignees } %>
+<br />
+<h3><%=l(:field_author)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'author') %></h3>
+<%= render :partial => 'simple', :locals => { :data => @issues_by_author, :field_name => "author_id", :rows => @authors } %>
+<br />
+<%= call_hook(:view_reports_issue_report_split_content_left, :project => @project) %>
+</div>
+
+<div class="splitcontentright">
+<h3><%=l(:field_version)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'version') %></h3>
+<%= render :partial => 'simple', :locals => { :data => @issues_by_version, :field_name => "fixed_version_id", :rows => @versions } %>
+<br />
+<% if @project.children.any? %>
+<h3><%=l(:field_subproject)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'subproject') %></h3>
+<%= render :partial => 'simple', :locals => { :data => @issues_by_subproject, :field_name => "project_id", :rows => @subprojects } %>
+<br />
+<% end %>
+<h3><%=l(:field_category)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'category') %></h3>
+<%= render :partial => 'simple', :locals => { :data => @issues_by_category, :field_name => "category_id", :rows => @categories } %>
+<br />
+<%= call_hook(:view_reports_issue_report_split_content_right, :project => @project) %>
+</div>
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3a/3abba0780c56be34f089a5b70681173c4f0cb4c0.svn-base
--- a/.svn/pristine/3a/3abba0780c56be34f089a5b70681173c4f0cb4c0.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-api.time_entry do
-  api.id @time_entry.id
-  api.project(:id => @time_entry.project_id, :name => @time_entry.project.name) unless @time_entry.project.nil?
-  api.issue(:id => @time_entry.issue_id) unless @time_entry.issue.nil?
-  api.user(:id => @time_entry.user_id, :name => @time_entry.user.name) unless @time_entry.user.nil?
-  api.activity(:id => @time_entry.activity_id, :name => @time_entry.activity.name) unless @time_entry.activity.nil?
-  api.hours @time_entry.hours
-  api.comments @time_entry.comments
-  api.spent_on @time_entry.spent_on
-  api.created_on @time_entry.created_on
-  api.updated_on @time_entry.updated_on
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3b/3b0a04b81b3503971b4e570669380aa1831579cc.svn-base
--- a/.svn/pristine/3b/3b0a04b81b3503971b4e570669380aa1831579cc.svn-base
+++ /dev/null
@@ -1,162 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-require 'search_controller'
-
-# Re-raise errors caught by the controller.
-class SearchController; def rescue_action(e) raise e end; end
-
-class SearchControllerTest < ActionController::TestCase
-  fixtures :projects, :enabled_modules, :roles, :users, :members, :member_roles,
-           :issues, :trackers, :issue_statuses,
-           :custom_fields, :custom_values,
-           :repositories, :changesets
-
-  def setup
-    @controller = SearchController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_search_for_projects
-    get :index
-    assert_response :success
-    assert_template 'index'
-
-    get :index, :q => "cook"
-    assert_response :success
-    assert_template 'index'
-    assert assigns(:results).include?(Project.find(1))
-  end
-
-  def test_search_all_projects
-    get :index, :q => 'recipe subproject commit', :all_words => ''
-    assert_response :success
-    assert_template 'index'
-
-    assert assigns(:results).include?(Issue.find(2))
-    assert assigns(:results).include?(Issue.find(5))
-    assert assigns(:results).include?(Changeset.find(101))
-    assert_tag :dt, :attributes => { :class => /issue/ },
-                    :child => { :tag => 'a',  :content => /Add ingredients categories/ },
-                    :sibling => { :tag => 'dd', :content => /should be classified by categories/ }
-
-    assert assigns(:results_by_type).is_a?(Hash)
-    assert_equal 5, assigns(:results_by_type)['changesets']
-    assert_tag :a, :content => 'Changesets (5)'
-  end
-
-  def test_search_issues
-    get :index, :q => 'issue', :issues => 1
-    assert_response :success
-    assert_template 'index'
-
-    assert_equal true, assigns(:all_words)
-    assert_equal false, assigns(:titles_only)
-    assert assigns(:results).include?(Issue.find(8))
-    assert assigns(:results).include?(Issue.find(5))
-    assert_tag :dt, :attributes => { :class => /issue closed/ },
-                    :child => { :tag => 'a',  :content => /Closed/ }
-  end
-
-  def test_search_project_and_subprojects
-    get :index, :id => 1, :q => 'recipe subproject', :scope => 'subprojects', :all_words => ''
-    assert_response :success
-    assert_template 'index'
-    assert assigns(:results).include?(Issue.find(1))
-    assert assigns(:results).include?(Issue.find(5))
-  end
-
-  def test_search_without_searchable_custom_fields
-    CustomField.update_all "searchable = #{ActiveRecord::Base.connection.quoted_false}"
-
-    get :index, :id => 1
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:project)
-
-    get :index, :id => 1, :q => "can"
-    assert_response :success
-    assert_template 'index'
-  end
-
-  def test_search_with_searchable_custom_fields
-    get :index, :id => 1, :q => "stringforcustomfield"
-    assert_response :success
-    results = assigns(:results)
-    assert_not_nil results
-    assert_equal 1, results.size
-    assert results.include?(Issue.find(7))
-  end
-
-  def test_search_all_words
-    # 'all words' is on by default
-    get :index, :id => 1, :q => 'recipe updating saving', :all_words => '1'
-    assert_equal true, assigns(:all_words)
-    results = assigns(:results)
-    assert_not_nil results
-    assert_equal 1, results.size
-    assert results.include?(Issue.find(3))
-  end
-
-  def test_search_one_of_the_words
-    get :index, :id => 1, :q => 'recipe updating saving', :all_words => ''
-    assert_equal false, assigns(:all_words)
-    results = assigns(:results)
-    assert_not_nil results
-    assert_equal 3, results.size
-    assert results.include?(Issue.find(3))
-  end
-
-  def test_search_titles_only_without_result
-    get :index, :id => 1, :q => 'recipe updating saving', :titles_only => '1'
-    results = assigns(:results)
-    assert_not_nil results
-    assert_equal 0, results.size
-  end
-
-  def test_search_titles_only
-    get :index, :id => 1, :q => 'recipe', :titles_only => '1'
-    assert_equal true, assigns(:titles_only)
-    results = assigns(:results)
-    assert_not_nil results
-    assert_equal 2, results.size
-  end
-
-  def test_search_content
-    Issue.update_all("description = 'This is a searchkeywordinthecontent'", "id=1")
-
-    get :index, :id => 1, :q => 'searchkeywordinthecontent', :titles_only => ''
-    assert_equal false, assigns(:titles_only)
-    results = assigns(:results)
-    assert_not_nil results
-    assert_equal 1, results.size
-  end
-
-  def test_search_with_invalid_project_id
-    get :index, :id => 195, :q => 'recipe'
-    assert_response 404
-    assert_nil assigns(:results)
-  end
-
-  def test_quick_jump_to_issue
-    # issue of a public project
-    get :index, :q => "3"
-    assert_redirected_to '/issues/3'
-
-    # issue of a private project
-    get :index, :q => "4"
-    assert_response :success
-    assert_template 'index'
-  end
-
-  def test_large_integer
-    get :index, :q => '4615713488'
-    assert_response :success
-    assert_template 'index'
-  end
-
-  def test_tokens_with_quotes
-    get :index, :id => 1, :q => '"good bye" hello "bye bye"'
-    assert_equal ["good bye", "hello", "bye bye"], assigns(:tokens)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3b/3b1b10ce6290c2ed3a8ab7a0cbea04c53b0b08e9.svn-base
--- a/.svn/pristine/3b/3b1b10ce6290c2ed3a8ab7a0cbea04c53b0b08e9.svn-base
+++ /dev/null
@@ -1,232 +0,0 @@
-/* redMine - project management software
-   Copyright (C) 2006-2008  Jean-Philippe Lang */
-
-var observingContextMenuClick;
-
-ContextMenu = Class.create();
-ContextMenu.prototype = {
-	initialize: function (url) {
-	this.url = url;
-	this.createMenu();
-
-	if (!observingContextMenuClick) {
-		Event.observe(document, 'click', this.Click.bindAsEventListener(this));
-		Event.observe(document, 'contextmenu', this.RightClick.bindAsEventListener(this));
-		observingContextMenuClick = true;
-	}
-	
-	this.unselectAll();
-	this.lastSelected = null;
-	},
-  
-	RightClick: function(e) {
-		this.hideMenu();
-		// do not show the context menu on links
-		if (Event.element(e).tagName == 'A') { return; }
-		var tr = Event.findElement(e, 'tr');
-		if (tr == document || tr == undefined  || !tr.hasClassName('hascontextmenu')) { return; }
-		Event.stop(e);
-		if (!this.isSelected(tr)) {
-			this.unselectAll();
-			this.addSelection(tr);
-			this.lastSelected = tr;
-		}
-		this.showMenu(e);
-	},
-
-  Click: function(e) {
-  	this.hideMenu();
-  	if (Event.element(e).tagName == 'A' || Event.element(e).tagName == 'IMG') { return; }
-    if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) {      
-      var tr = Event.findElement(e, 'tr');
-      if (tr!=null && tr!=document && tr.hasClassName('hascontextmenu')) {
-        // a row was clicked, check if the click was on checkbox
-        var box = Event.findElement(e, 'input');
-        if (box!=document && box!=undefined) {
-          // a checkbox may be clicked
-          if (box.checked) {
-            tr.addClassName('context-menu-selection');
-          } else {
-            tr.removeClassName('context-menu-selection');
-          }
-        } else {
-          if (e.ctrlKey || e.metaKey) {
-            this.toggleSelection(tr);
-          } else if (e.shiftKey) {
-            if (this.lastSelected != null) {
-              var toggling = false;
-              var rows = $$('.hascontextmenu');
-              for (i=0; i<rows.length; i++) {
-                if (toggling || rows[i]==tr) {
-                  this.addSelection(rows[i]);
-                }
-                if (rows[i]==tr || rows[i]==this.lastSelected) {
-                  toggling = !toggling;
-                }
-              }
-            } else {
-              this.addSelection(tr);
-            }
-          } else {
-            this.unselectAll();
-            this.addSelection(tr);
-          }
-          this.lastSelected = tr;
-        }
-      } else {
-        // click is outside the rows
-        var t = Event.findElement(e, 'a');
-        if (t == document || t == undefined) {
-          this.unselectAll();
-        } else {
-          if (Element.hasClassName(t, 'disabled') || Element.hasClassName(t, 'submenu')) {
-            Event.stop(e);
-          }
-        }
-      }
-    }
-  },
-  
-  createMenu: function() {
-    if (!$('context-menu')) {
-      var menu = document.createElement("div");
-      menu.setAttribute("id", "context-menu");
-      menu.setAttribute("style", "display:none;");
-      document.getElementById("content").appendChild(menu);
-    }
-  },
-  
-  showMenu: function(e) {
-    var mouse_x = Event.pointerX(e);
-    var mouse_y = Event.pointerY(e);
-    var render_x = mouse_x;
-    var render_y = mouse_y;
-    var dims;
-    var menu_width;
-    var menu_height;
-    var window_width;
-    var window_height;
-    var max_width;
-    var max_height;
-
-    $('context-menu').style['left'] = (render_x + 'px');
-    $('context-menu').style['top'] = (render_y + 'px');		
-    Element.update('context-menu', '');
-
-    new Ajax.Updater({success:'context-menu'}, this.url, 
-      {asynchronous:true,
-       method: 'get',
-       evalScripts:true,
-       parameters:Form.serialize(Event.findElement(e, 'form')),
-       onComplete:function(request){
-				 dims = $('context-menu').getDimensions();
-				 menu_width = dims.width;
-				 menu_height = dims.height;
-				 max_width = mouse_x + 2*menu_width;
-				 max_height = mouse_y + menu_height;
-			
-				 var ws = window_size();
-				 window_width = ws.width;
-				 window_height = ws.height;
-			
-				 /* display the menu above and/or to the left of the click if needed */
-				 if (max_width > window_width) {
-				   render_x -= menu_width;
-				   $('context-menu').addClassName('reverse-x');
-				 } else {
-					 $('context-menu').removeClassName('reverse-x');
-				 }
-				 if (max_height > window_height) {
-				   render_y -= menu_height;
-				   $('context-menu').addClassName('reverse-y');
-				 } else {
-					 $('context-menu').removeClassName('reverse-y');
-				 }
-				 if (render_x <= 0) render_x = 1;
-				 if (render_y <= 0) render_y = 1;
-				 $('context-menu').style['left'] = (render_x + 'px');
-				 $('context-menu').style['top'] = (render_y + 'px');
-				 
-         Effect.Appear('context-menu', {duration: 0.20});
-         if (window.parseStylesheets) { window.parseStylesheets(); } // IE
-      }})
-  },
-  
-  hideMenu: function() {
-    Element.hide('context-menu');
-  },
-  
-  addSelection: function(tr) {
-    tr.addClassName('context-menu-selection');
-    this.checkSelectionBox(tr, true);
-    this.clearDocumentSelection();
-  },
-  
-  toggleSelection: function(tr) {
-    if (this.isSelected(tr)) {
-      this.removeSelection(tr);
-    } else {
-      this.addSelection(tr);
-    }
-  },
-  
-  removeSelection: function(tr) {
-    tr.removeClassName('context-menu-selection');
-    this.checkSelectionBox(tr, false);
-  },
-  
-  unselectAll: function() {
-    var rows = $$('.hascontextmenu');
-    for (i=0; i<rows.length; i++) {
-      this.removeSelection(rows[i]);
-    }
-  },
-  
-  checkSelectionBox: function(tr, checked) {
-  	var inputs = Element.getElementsBySelector(tr, 'input');
-  	if (inputs.length > 0) { inputs[0].checked = checked; }
-  },
-  
-  isSelected: function(tr) {
-    return Element.hasClassName(tr, 'context-menu-selection');
-  },
-  
-  clearDocumentSelection: function() {
-    if (document.selection) {
-      document.selection.clear(); // IE
-    } else {
-      window.getSelection().removeAllRanges();
-    }
-  }
-}
-
-function toggleIssuesSelection(el) {
-	var boxes = el.getElementsBySelector('input[type=checkbox]');
-	var all_checked = true;
-	for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
-	for (i = 0; i < boxes.length; i++) {
-		if (all_checked) {
-			boxes[i].checked = false;
-			boxes[i].up('tr').removeClassName('context-menu-selection');
-		} else if (boxes[i].checked == false) {
-			boxes[i].checked = true;
-			boxes[i].up('tr').addClassName('context-menu-selection');
-		}
-	}
-}
-
-function window_size() {
-    var w;
-    var h;
-    if (window.innerWidth) {
-	w = window.innerWidth;
-	h = window.innerHeight;
-    } else if (document.documentElement) {
-	w = document.documentElement.clientWidth;
-	h = document.documentElement.clientHeight;
-    } else {
-	w = document.body.clientWidth;
-	h = document.body.clientHeight;
-    }
-    return {width: w, height: h};
-}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3b/3b35aa3e53757a7316cb173ab97cf120044ce7fe.svn-base
--- a/.svn/pristine/3b/3b35aa3e53757a7316cb173ab97cf120044ce7fe.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= yield %> (with plugin layout)
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3b/3b77726a8efda3938653233bf84d8e02401c4bc3.svn-base
--- /dev/null
+++ b/.svn/pristine/3b/3b77726a8efda3938653233bf84d8e02401c4bc3.svn-base
@@ -0,0 +1,30 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class WelcomeController < ApplicationController
+  caches_action :robots
+
+  def index
+    @news = News.latest User.current
+    @projects = Project.latest User.current
+  end
+
+  def robots
+    @projects = Project.all_public.active
+    render :layout => false, :content_type => 'text/plain'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3b/3bdc9be57907c77b3244c04ca134e43fe57a10c8.svn-base
--- a/.svn/pristine/3b/3bdc9be57907c77b3244c04ca134e43fe57a10c8.svn-base
+++ /dev/null
@@ -1,40 +0,0 @@
-<%= call_hook(:view_issues_form_details_top, { :issue => @issue, :form => f }) %>
-
-<div id="issue_descr_fields" <%= 'style="display:none"' unless @issue.new_record? || @issue.errors.any? %>>
-<% if @issue.safe_attribute_names.include?('is_private') %>
-<p style="float:right; margin-right:1em;">
-  <label class="inline" for="issue_is_private" id="issue_is_private_label"><%= f.check_box :is_private, :no_label => true %> <%= l(:field_is_private) %></label>
-</p>
-<% end %>
-<p><%= f.select :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %></p>
-<%= observe_field :issue_tracker_id, :url => { :action => :new, :project_id => @project, :id => @issue },
-                                     :update => :attributes,
-                                     :with => "Form.serialize('issue-form')" %>
-
-<p><%= f.text_field :subject, :size => 80, :required => true %></p>
-<p><%= f.text_area :description,
-                   :cols => 60,
-                   :rows => (@issue.description.blank? ? 10 : [[10, @issue.description.length / 50].max, 100].min),
-                   :accesskey => accesskey(:edit),
-                   :class => 'wiki-edit' %></p>
-</div>
-
-<div id="attributes" class="attributes">
-  <%= render :partial => 'issues/attributes' %>
-</div>
-
-<% if @issue.new_record? %>
-<p id="attachments_form"><%= label_tag('attachments[1][file]', l(:label_attachment_plural))%><%= render :partial => 'attachments/form' %></p>
-<% end %>
-
-<% if @issue.new_record? && User.current.allowed_to?(:add_issue_watchers, @project) -%>
-<p id="watchers_form"><label><%= l(:label_issue_watchers) %></label>
-<% @issue.project.users.sort.each do |user| -%>
-<label class="floating"><%= check_box_tag 'issue[watcher_user_ids][]', user.id, @issue.watched_by?(user) %> <%=h user %></label>
-<% end -%>
-</p>
-<% end %>
-
-<%= call_hook(:view_issues_form_details_bottom, { :issue => @issue, :form => f }) %>
-
-<%= wikitoolbar_for 'issue_description' %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3c16dbd6e7c58f730f5ff1711301f6b5ab6045e0.svn-base
--- a/.svn/pristine/3c/3c16dbd6e7c58f730f5ff1711301f6b5ab6045e0.svn-base
+++ /dev/null
@@ -1,16 +0,0 @@
-# Settings specified here will take precedence over those in config/environment.rb
-
-# In the development environment your application's code is reloaded on
-# every request.  This slows down response time but is perfect for development
-# since you don't have to restart the webserver when you make code changes.
-config.cache_classes     = false
-
-# Log error messages when you accidentally call methods on nil.
-config.whiny_nils        = true
-
-# Show full error reports and disable caching
-config.action_controller.consider_all_requests_local = true
-config.action_controller.perform_caching             = false
-
-# Don't care if the mailer can't send
-config.action_mailer.raise_delivery_errors = false
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3c376c5f92040d674ff0d9660198f1ddf43a3782.svn-base
--- a/.svn/pristine/3c/3c376c5f92040d674ff0d9660198f1ddf43a3782.svn-base
+++ /dev/null
@@ -1,264 +0,0 @@
---- 
-issues_001: 
-  created_on: <%= 3.days.ago.to_date.to_s(:db) %>
-  project_id: 1
-  updated_on: <%= 1.day.ago.to_date.to_s(:db) %>
-  priority_id: 4
-  subject: Can't print recipes
-  id: 1
-  fixed_version_id: 
-  category_id: 1
-  description: Unable to print recipes
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 1
-  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
-  due_date: <%= 10.day.from_now.to_date.to_s(:db) %>
-  root_id: 1
-  lft: 1
-  rgt: 2
-issues_002: 
-  created_on: 2006-07-19 21:04:21 +02:00
-  project_id: 1
-  updated_on: 2006-07-19 21:09:50 +02:00
-  priority_id: 5
-  subject: Add ingredients categories
-  id: 2
-  fixed_version_id: 2
-  category_id: 
-  description: Ingredients of the recipe should be classified by categories
-  tracker_id: 2
-  assigned_to_id: 3
-  author_id: 2
-  status_id: 2
-  start_date: <%= 2.day.ago.to_date.to_s(:db) %>
-  due_date: 
-  root_id: 2
-  lft: 1
-  rgt: 2
-  lock_version: 3
-  done_ratio: 30
-issues_003: 
-  created_on: 2006-07-19 21:07:27 +02:00
-  project_id: 1
-  updated_on: 2006-07-19 21:07:27 +02:00
-  priority_id: 4
-  subject: Error 281 when updating a recipe
-  id: 3
-  fixed_version_id: 
-  category_id: 
-  description: Error 281 is encountered when saving a recipe
-  tracker_id: 1
-  assigned_to_id: 3
-  author_id: 2
-  status_id: 1
-  start_date: <%= 15.day.ago.to_date.to_s(:db) %>
-  due_date: <%= 5.day.ago.to_date.to_s(:db) %>
-  root_id: 3
-  lft: 1
-  rgt: 2
-issues_004: 
-  created_on: <%= 5.days.ago.to_date.to_s(:db) %>
-  project_id: 2
-  updated_on: <%= 2.days.ago.to_date.to_s(:db) %>
-  priority_id: 4
-  subject: Issue on project 2
-  id: 4
-  fixed_version_id: 
-  category_id: 
-  description: Issue on project 2
-  tracker_id: 1
-  assigned_to_id: 2
-  author_id: 2
-  status_id: 1
-  root_id: 4
-  lft: 1
-  rgt: 2
-issues_005: 
-  created_on: <%= 5.days.ago.to_date.to_s(:db) %>
-  project_id: 3
-  updated_on: <%= 2.days.ago.to_date.to_s(:db) %>
-  priority_id: 4
-  subject: Subproject issue
-  id: 5
-  fixed_version_id: 
-  category_id: 
-  description: This is an issue on a cookbook subproject
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 1
-  root_id: 5
-  lft: 1
-  rgt: 2
-issues_006: 
-  created_on: <%= 1.minute.ago.to_date.to_s(:db) %>
-  project_id: 5
-  updated_on: <%= 1.minute.ago.to_date.to_s(:db) %>
-  priority_id: 4
-  subject: Issue of a private subproject
-  id: 6
-  fixed_version_id: 
-  category_id: 
-  description: This is an issue of a private subproject of cookbook
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 1
-  start_date: <%= Date.today.to_s(:db) %>
-  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
-  root_id: 6
-  lft: 1
-  rgt: 2
-issues_007: 
-  created_on: <%= 10.days.ago.to_date.to_s(:db) %>
-  project_id: 1
-  updated_on: <%= 10.days.ago.to_date.to_s(:db) %>
-  priority_id: 5
-  subject: Issue due today
-  id: 7
-  fixed_version_id: 
-  category_id: 
-  description: This is an issue that is due today
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 1
-  start_date: <%= 10.days.ago.to_s(:db) %>
-  due_date: <%= Date.today.to_s(:db) %>
-  lock_version: 0
-  root_id: 7
-  lft: 1
-  rgt: 2
-issues_008: 
-  created_on: <%= 10.days.ago.to_date.to_s(:db) %>
-  project_id: 1
-  updated_on: <%= 10.days.ago.to_date.to_s(:db) %>
-  priority_id: 5
-  subject: Closed issue
-  id: 8
-  fixed_version_id: 
-  category_id: 
-  description: This is a closed issue.
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 5
-  start_date: 
-  due_date: 
-  lock_version: 0
-  root_id: 8
-  lft: 1
-  rgt: 2
-issues_009: 
-  created_on: <%= 1.minute.ago.to_date.to_s(:db) %>
-  project_id: 5
-  updated_on: <%= 1.minute.ago.to_date.to_s(:db) %>
-  priority_id: 5
-  subject: Blocked Issue
-  id: 9
-  fixed_version_id: 
-  category_id: 
-  description: This is an issue that is blocked by issue #10
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 1
-  start_date: <%= Date.today.to_s(:db) %>
-  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
-  root_id: 9
-  lft: 1
-  rgt: 2
-issues_010: 
-  created_on: <%= 1.minute.ago.to_date.to_s(:db) %>
-  project_id: 5
-  updated_on: <%= 1.minute.ago.to_date.to_s(:db) %>
-  priority_id: 5
-  subject: Issue Doing the Blocking
-  id: 10
-  fixed_version_id: 
-  category_id: 
-  description: This is an issue that blocks issue #9
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 1
-  start_date: <%= Date.today.to_s(:db) %>
-  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
-  root_id: 10
-  lft: 1
-  rgt: 2
-issues_011: 
-  created_on: <%= 3.days.ago.to_date.to_s(:db) %>
-  project_id: 1
-  updated_on: <%= 1.day.ago.to_date.to_s(:db) %>
-  priority_id: 5
-  subject: Closed issue on a closed version
-  id: 11
-  fixed_version_id: 1 
-  category_id: 1
-  description:
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 5
-  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
-  due_date:
-  root_id: 11
-  lft: 1
-  rgt: 2
-issues_012: 
-  created_on: <%= 3.days.ago.to_date.to_s(:db) %>
-  project_id: 1
-  updated_on: <%= 1.day.ago.to_date.to_s(:db) %>
-  priority_id: 5
-  subject: Closed issue on a locked version
-  id: 12
-  fixed_version_id: 2 
-  category_id: 1
-  description:
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 3
-  status_id: 5
-  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
-  due_date:
-  root_id: 12
-  lft: 1
-  rgt: 2
-issues_013:
-  created_on: <%= 5.days.ago.to_date.to_s(:db) %>
-  project_id: 3
-  updated_on: <%= 2.days.ago.to_date.to_s(:db) %>
-  priority_id: 4
-  subject: Subproject issue two
-  id: 13
-  fixed_version_id: 
-  category_id: 
-  description: This is a second issue on a cookbook subproject
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 1
-  root_id: 13
-  lft: 1
-  rgt: 2
-issues_014:
-  id: 14
-  created_on: <%= 15.days.ago.to_date.to_s(:db) %>
-  project_id: 3
-  updated_on: <%= 15.days.ago.to_date.to_s(:db) %>
-  priority_id: 5
-  subject: Private issue on public project
-  fixed_version_id: 
-  category_id: 
-  description: This is a private issue
-  tracker_id: 1
-  assigned_to_id: 
-  author_id: 2
-  status_id: 1
-  is_private: true
-  root_id: 14
-  lft: 1
-  rgt: 2
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3c57aa09eea8e28ae469dce0482885ac576762ef.svn-base
--- /dev/null
+++ b/.svn/pristine/3c/3c57aa09eea8e28ae469dce0482885ac576762ef.svn-base
@@ -0,0 +1,47 @@
+<%= form_tag({}) do -%>
+<%= hidden_field_tag 'back_url', url_for(params), :id => nil %>
+<div class="autoscroll">
+<table class="list issues">
+  <thead>
+    <tr>
+      <th class="checkbox hide-when-print">
+        <%= link_to image_tag('toggle_check.png'), {},
+                              :onclick => 'toggleIssuesSelection(this); return false;',
+                              :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
+      </th>
+      <% query.inline_columns.each do |column| %>
+        <%= column_header(column) %>
+      <% end %>
+    </tr>
+  </thead>
+  <% previous_group = false %>
+  <tbody>
+  <% issue_list(issues) do |issue, level| -%>
+  <% if @query.grouped? && (group = @query.group_by_column.value(issue)) != previous_group %>
+    <% reset_cycle %>
+    <tr class="group open">
+      <td colspan="<%= query.inline_columns.size + 2 %>">
+        <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
+        <%= group.blank? ? l(:label_none) : column_content(@query.group_by_column, issue) %> <span class="count"><%= @issue_count_by_group[group] %></span>
+        <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}",
+                             "toggleAllRowGroups(this)", :class => 'toggle-all') %>
+      </td>
+    </tr>
+    <% previous_group = group %>
+  <% end %>
+  <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
+    <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
+    <%= raw query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, issue)}</td>"}.join %>
+  </tr>
+  <% @query.block_columns.each do |column|
+       if (text = column_content(column, issue)) && text.present? -%>
+  <tr class="<%= current_cycle %>">
+    <td colspan="<%= @query.inline_columns.size + 1 %>" class="<%= column.css_classes %>"><%= text %></td>
+  </tr>
+  <% end -%>
+  <% end -%>
+  <% end -%>
+  </tbody>
+</table>
+</div>
+<% end -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3c7ff621c4b3a329adfd7d06c0fa2ae1d92c4a27.svn-base
--- a/.svn/pristine/3c/3c7ff621c4b3a329adfd7d06c0fa2ae1d92c4a27.svn-base
+++ /dev/null
@@ -1,142 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssueRelation < ActiveRecord::Base
-  belongs_to :issue_from, :class_name => 'Issue', :foreign_key => 'issue_from_id'
-  belongs_to :issue_to, :class_name => 'Issue', :foreign_key => 'issue_to_id'
-
-  TYPE_RELATES      = "relates"
-  TYPE_DUPLICATES   = "duplicates"
-  TYPE_DUPLICATED   = "duplicated"
-  TYPE_BLOCKS       = "blocks"
-  TYPE_BLOCKED      = "blocked"
-  TYPE_PRECEDES     = "precedes"
-  TYPE_FOLLOWS      = "follows"
-
-  TYPES = { TYPE_RELATES =>     { :name => :label_relates_to, :sym_name => :label_relates_to, :order => 1, :sym => TYPE_RELATES },
-            TYPE_DUPLICATES =>  { :name => :label_duplicates, :sym_name => :label_duplicated_by, :order => 2, :sym => TYPE_DUPLICATED },
-            TYPE_DUPLICATED =>  { :name => :label_duplicated_by, :sym_name => :label_duplicates, :order => 3, :sym => TYPE_DUPLICATES, :reverse => TYPE_DUPLICATES },
-            TYPE_BLOCKS =>      { :name => :label_blocks, :sym_name => :label_blocked_by, :order => 4, :sym => TYPE_BLOCKED },
-            TYPE_BLOCKED =>     { :name => :label_blocked_by, :sym_name => :label_blocks, :order => 5, :sym => TYPE_BLOCKS, :reverse => TYPE_BLOCKS },
-            TYPE_PRECEDES =>    { :name => :label_precedes, :sym_name => :label_follows, :order => 6, :sym => TYPE_FOLLOWS },
-            TYPE_FOLLOWS =>     { :name => :label_follows, :sym_name => :label_precedes, :order => 7, :sym => TYPE_PRECEDES, :reverse => TYPE_PRECEDES }
-          }.freeze
-
-  validates_presence_of :issue_from, :issue_to, :relation_type
-  validates_inclusion_of :relation_type, :in => TYPES.keys
-  validates_numericality_of :delay, :allow_nil => true
-  validates_uniqueness_of :issue_to_id, :scope => :issue_from_id
-
-  validate :validate_issue_relation
-
-  attr_protected :issue_from_id, :issue_to_id
-
-  before_save :handle_issue_order
-
-  def visible?(user=User.current)
-    (issue_from.nil? || issue_from.visible?(user)) && (issue_to.nil? || issue_to.visible?(user))
-  end
-
-  def deletable?(user=User.current)
-    visible?(user) &&
-      ((issue_from.nil? || user.allowed_to?(:manage_issue_relations, issue_from.project)) ||
-        (issue_to.nil? || user.allowed_to?(:manage_issue_relations, issue_to.project)))
-  end
-
-  def after_initialize
-    if new_record?
-      if relation_type.blank?
-        self.relation_type = IssueRelation::TYPE_RELATES
-      end
-    end
-  end
-
-  def validate_issue_relation
-    if issue_from && issue_to
-      errors.add :issue_to_id, :invalid if issue_from_id == issue_to_id
-      errors.add :issue_to_id, :not_same_project unless issue_from.project_id == issue_to.project_id || Setting.cross_project_issue_relations?
-      #detect circular dependencies depending wether the relation should be reversed
-      if TYPES.has_key?(relation_type) && TYPES[relation_type][:reverse]
-        errors.add :base, :circular_dependency if issue_from.all_dependent_issues.include? issue_to
-      else
-        errors.add :base, :circular_dependency if issue_to.all_dependent_issues.include? issue_from
-      end
-      errors.add :base, :cant_link_an_issue_with_a_descendant if issue_from.is_descendant_of?(issue_to) || issue_from.is_ancestor_of?(issue_to)
-    end
-  end
-
-  def other_issue(issue)
-    (self.issue_from_id == issue.id) ? issue_to : issue_from
-  end
-
-  # Returns the relation type for +issue+
-  def relation_type_for(issue)
-    if TYPES[relation_type]
-      if self.issue_from_id == issue.id
-        relation_type
-      else
-        TYPES[relation_type][:sym]
-      end
-    end
-  end
-
-  def label_for(issue)
-    TYPES[relation_type] ? TYPES[relation_type][(self.issue_from_id == issue.id) ? :name : :sym_name] : :unknow
-  end
-
-  def handle_issue_order
-    reverse_if_needed
-
-    if TYPE_PRECEDES == relation_type
-      self.delay ||= 0
-    else
-      self.delay = nil
-    end
-    set_issue_to_dates
-  end
-
-  def set_issue_to_dates
-    soonest_start = self.successor_soonest_start
-    if soonest_start && issue_to
-      issue_to.reschedule_after(soonest_start)
-    end
-  end
-
-  def successor_soonest_start
-    if (TYPE_PRECEDES == self.relation_type) && delay && issue_from && (issue_from.start_date || issue_from.due_date)
-      (issue_from.due_date || issue_from.start_date) + 1 + delay
-    end
-  end
-
-  def <=>(relation)
-    TYPES[self.relation_type][:order] <=> TYPES[relation.relation_type][:order]
-  end
-
-  private
-
-  # Reverses the relation if needed so that it gets stored in the proper way
-  # Should not be reversed before validation so that it can be displayed back
-  # as entered on new relation form
-  def reverse_if_needed
-    if TYPES.has_key?(relation_type) && TYPES[relation_type][:reverse]
-      issue_tmp = issue_to
-      self.issue_to = issue_from
-      self.issue_from = issue_tmp
-      self.relation_type = TYPES[relation_type][:reverse]
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3c9db866c7acbdda129e19ec3d3a7067e2b8c96c.svn-base
--- /dev/null
+++ b/.svn/pristine/3c/3c9db866c7acbdda129e19ec3d3a7067e2b8c96c.svn-base
@@ -0,0 +1,1102 @@
+# French translations for Ruby on Rails
+# by Christian Lescuyer (christian@flyingcoders.com)
+# contributor: Sebastien Grosjean - ZenCocoon.com
+# contributor: Thibaut Cuvelier - Developpez.com
+
+fr:
+  direction: ltr
+  date:
+    formats:
+      default: "%d/%m/%Y"
+      short: "%e %b"
+      long: "%e %B %Y"
+      long_ordinal: "%e %B %Y"
+      only_day: "%e"
+
+    day_names: [dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi]
+    abbr_day_names: [dim, lun, mar, mer, jeu, ven, sam]
+    month_names: [~, janvier, fÃ©vrier, mars, avril, mai, juin, juillet, aoÃ»t, septembre, octobre, novembre, dÃ©cembre]
+    abbr_month_names: [~, jan., fÃ©v., mar., avr., mai, juin, juil., aoÃ»t, sept., oct., nov., dÃ©c.]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%d/%m/%Y %H:%M"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%A %d %B %Y %H:%M:%S %Z"
+      long_ordinal: "%A %d %B %Y %H:%M:%S %Z"
+      only_second: "%S"
+    am: 'am'
+    pm: 'pm'
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "30 secondes"
+      less_than_x_seconds:
+        zero:  "moins d'une seconde"
+        one:   "moins d'uneÂ seconde"
+        other: "moins de %{count}Â secondes"
+      x_seconds:
+        one:   "1Â seconde"
+        other: "%{count}Â secondes"
+      less_than_x_minutes:
+        zero:  "moins d'une minute"
+        one:   "moins d'uneÂ minute"
+        other: "moins de %{count}Â minutes"
+      x_minutes:
+        one:   "1Â minute"
+        other: "%{count}Â minutes"
+      about_x_hours:
+        one:   "environ une heure"
+        other: "environ %{count}Â heures"
+      x_hours:
+        one:   "une heure"
+        other: "%{count}Â heures"
+      x_days:
+        one:   "unÂ jour"
+        other: "%{count}Â jours"
+      about_x_months:
+        one:   "environ un mois"
+        other: "environ %{count}Â mois"
+      x_months:
+        one:   "unÂ mois"
+        other: "%{count}Â mois"
+      about_x_years:
+        one:   "environ un an"
+        other: "environ %{count}Â ans"
+      over_x_years:
+        one:   "plus d'un an"
+        other: "plus de %{count}Â ans"
+      almost_x_years:
+        one:   "presqu'un an"
+        other: "presque %{count} ans"
+    prompts:
+      year:   "AnnÃ©e"
+      month:  "Mois"
+      day:    "Jour"
+      hour:   "Heure"
+      minute: "Minute"
+      second: "Seconde"
+
+  number:
+    format:
+      precision: 3
+      separator: ','
+      delimiter: 'Â '
+    currency:
+      format:
+        unit: 'â‚¬'
+        precision: 2
+        format: '%nÂ %u'
+    human:
+      format:
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "octet"
+            other: "octet"
+          kb: "ko"
+          mb: "Mo"
+          gb: "Go"
+          tb: "To"
+
+  support:
+    array:
+      sentence_connector: 'et'
+      skip_last_comma: true
+      word_connector: ", "
+      two_words_connector: " et "
+      last_word_connector: " et "
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one: "Impossible d'enregistrer %{model} : une erreur"
+          other: "Impossible d'enregistrer %{model} : %{count} erreurs."
+        body: "Veuillez vÃ©rifier les champs suivantsÂ :"
+      messages:
+        inclusion: "n'est pas inclus(e) dans la liste"
+        exclusion: "n'est pas disponible"
+        invalid: "n'est pas valide"
+        confirmation: "ne concorde pas avec la confirmation"
+        accepted: "doit Ãªtre acceptÃ©(e)"
+        empty: "doit Ãªtre renseignÃ©(e)"
+        blank: "doit Ãªtre renseignÃ©(e)"
+        too_long: "est trop long (pas plus de %{count} caractÃ¨res)"
+        too_short: "est trop court (au moins %{count} caractÃ¨res)"
+        wrong_length: "ne fait pas la bonne longueur (doit comporter %{count} caractÃ¨res)"
+        taken: "est dÃ©jÃ  utilisÃ©"
+        not_a_number: "n'est pas un nombre"
+        not_a_date: "n'est pas une date valide"
+        greater_than: "doit Ãªtre supÃ©rieur Ã  %{count}"
+        greater_than_or_equal_to: "doit Ãªtre supÃ©rieur ou Ã©gal Ã  %{count}"
+        equal_to: "doit Ãªtre Ã©gal Ã  %{count}"
+        less_than: "doit Ãªtre infÃ©rieur Ã  %{count}"
+        less_than_or_equal_to: "doit Ãªtre infÃ©rieur ou Ã©gal Ã  %{count}"
+        odd: "doit Ãªtre impair"
+        even: "doit Ãªtre pair"
+        greater_than_start_date: "doit Ãªtre postÃ©rieure Ã  la date de dÃ©but"
+        not_same_project: "n'appartient pas au mÃªme projet"
+        circular_dependency: "Cette relation crÃ©erait une dÃ©pendance circulaire"
+        cant_link_an_issue_with_a_descendant: "Une demande ne peut pas Ãªtre liÃ©e Ã  l'une de ses sous-tÃ¢ches"
+
+  actionview_instancetag_blank_option: Choisir
+
+  general_text_No: 'Non'
+  general_text_Yes: 'Oui'
+  general_text_no: 'non'
+  general_text_yes: 'oui'
+  general_lang_name: 'FranÃ§ais'
+  general_csv_separator: ';'
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Le compte a Ã©tÃ© mis Ã  jour avec succÃ¨s.
+  notice_account_invalid_creditentials: Identifiant ou mot de passe invalide.
+  notice_account_password_updated: Mot de passe mis Ã  jour avec succÃ¨s.
+  notice_account_wrong_password: Mot de passe incorrect
+  notice_account_register_done: Un message contenant les instructions pour activer votre compte vous a Ã©tÃ© envoyÃ©.
+  notice_account_unknown_email: Aucun compte ne correspond Ã  cette adresse.
+  notice_can_t_change_password: Ce compte utilise une authentification externe. Impossible de changer le mot de passe.
+  notice_account_lost_email_sent: Un message contenant les instructions pour choisir un nouveau mot de passe vous a Ã©tÃ© envoyÃ©.
+  notice_account_activated: Votre compte a Ã©tÃ© activÃ©. Vous pouvez Ã  prÃ©sent vous connecter.
+  notice_successful_create: CrÃ©ation effectuÃ©e avec succÃ¨s.
+  notice_successful_update: Mise Ã  jour effectuÃ©e avec succÃ¨s.
+  notice_successful_delete: Suppression effectuÃ©e avec succÃ¨s.
+  notice_successful_connection: Connexion rÃ©ussie.
+  notice_file_not_found: "La page Ã  laquelle vous souhaitez accÃ©der n'existe pas ou a Ã©tÃ© supprimÃ©e."
+  notice_locking_conflict: Les donnÃ©es ont Ã©tÃ© mises Ã  jour par un autre utilisateur. Mise Ã  jour impossible.
+  notice_not_authorized: "Vous n'Ãªtes pas autorisÃ© Ã  accÃ©der Ã  cette page."
+  notice_not_authorized_archived_project: Le projet auquel vous tentez d'accÃ©der a Ã©tÃ© archivÃ©.
+  notice_email_sent: "Un email a Ã©tÃ© envoyÃ© Ã  %{value}"
+  notice_email_error: "Erreur lors de l'envoi de l'email (%{value})"
+  notice_feeds_access_key_reseted: "Votre clÃ© d'accÃ¨s aux flux RSS a Ã©tÃ© rÃ©initialisÃ©e."
+  notice_failed_to_save_issues: "%{count} demande(s) sur les %{total} sÃ©lectionnÃ©es n'ont pas pu Ãªtre mise(s) Ã  jour : %{ids}."
+  notice_failed_to_save_time_entries: "%{count} temps passÃ©(s) sur les %{total} sÃ©lectionnÃ©s n'ont pas pu Ãªtre mis Ã  jour: %{ids}."
+  notice_no_issue_selected: "Aucune demande sÃ©lectionnÃ©e ! Cochez les demandes que vous voulez mettre Ã  jour."
+  notice_account_pending: "Votre compte a Ã©tÃ© crÃ©Ã© et attend l'approbation de l'administrateur."
+  notice_default_data_loaded: ParamÃ©trage par dÃ©faut chargÃ© avec succÃ¨s.
+  notice_unable_delete_version: Impossible de supprimer cette version.
+  notice_issue_done_ratios_updated: L'avancement des demandes a Ã©tÃ© mis Ã  jour.
+  notice_api_access_key_reseted: Votre clÃ© d'accÃ¨s API a Ã©tÃ© rÃ©initialisÃ©e.
+  notice_gantt_chart_truncated: "Le diagramme a Ã©tÃ© tronquÃ© car il excÃ¨de le nombre maximal d'Ã©lÃ©ments pouvant Ãªtre affichÃ©s (%{max})"
+  notice_issue_successful_create: "Demande %{id} crÃ©Ã©e."
+  notice_issue_update_conflict: "La demande a Ã©tÃ© mise Ã  jour par un autre utilisateur pendant que vous la modifiez."
+  notice_account_deleted: "Votre compte a Ã©tÃ© dÃ©finitivement supprimÃ©."
+  notice_user_successful_create: "Utilisateur %{id} crÃ©Ã©."
+
+  error_can_t_load_default_data: "Une erreur s'est produite lors du chargement du paramÃ©trage : %{value}"
+  error_scm_not_found: "L'entrÃ©e et/ou la rÃ©vision demandÃ©e n'existe pas dans le dÃ©pÃ´t."
+  error_scm_command_failed: "Une erreur s'est produite lors de l'accÃ¨s au dÃ©pÃ´t : %{value}"
+  error_scm_annotate: "L'entrÃ©e n'existe pas ou ne peut pas Ãªtre annotÃ©e."
+  error_issue_not_found_in_project: "La demande n'existe pas ou n'appartient pas Ã  ce projet"
+  error_can_not_reopen_issue_on_closed_version: 'Une demande assignÃ©e Ã  une version fermÃ©e ne peut pas Ãªtre rÃ©ouverte'
+  error_can_not_archive_project: "Ce projet ne peut pas Ãªtre archivÃ©"
+  error_workflow_copy_source: 'Veuillez sÃ©lectionner un tracker et/ou un rÃ´le source'
+  error_workflow_copy_target: 'Veuillez sÃ©lectionner les trackers et rÃ´les cibles'
+  error_issue_done_ratios_not_updated: L'avancement des demandes n'a pas pu Ãªtre mis Ã  jour.
+  error_attachment_too_big: Ce fichier ne peut pas Ãªtre attachÃ© car il excÃ¨de la taille maximale autorisÃ©e (%{max_size})
+  error_session_expired: "Votre session a expirÃ©. Veuillez vous reconnecter."
+
+  warning_attachments_not_saved: "%{count} fichier(s) n'ont pas pu Ãªtre sauvegardÃ©s."
+
+  mail_subject_lost_password: "Votre mot de passe %{value}"
+  mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :'
+  mail_subject_register: "Activation de votre compte %{value}"
+  mail_body_register: 'Pour activer votre compte, cliquez sur le lien suivant :'
+  mail_body_account_information_external: "Vous pouvez utiliser votre compte %{value} pour vous connecter."
+  mail_body_account_information: ParamÃ¨tres de connexion de votre compte
+  mail_subject_account_activation_request: "Demande d'activation d'un compte %{value}"
+  mail_body_account_activation_request: "Un nouvel utilisateur (%{value}) s'est inscrit. Son compte nÃ©cessite votre approbation :"
+  mail_subject_reminder: "%{count} demande(s) arrivent Ã  Ã©chÃ©ance (%{days})"
+  mail_body_reminder: "%{count} demande(s) qui vous sont assignÃ©es arrivent Ã  Ã©chÃ©ance dans les %{days} prochains jours :"
+  mail_subject_wiki_content_added: "Page wiki '%{id}' ajoutÃ©e"
+  mail_body_wiki_content_added: "La page wiki '%{id}' a Ã©tÃ© ajoutÃ©e par %{author}."
+  mail_subject_wiki_content_updated: "Page wiki '%{id}' mise Ã  jour"
+  mail_body_wiki_content_updated: "La page wiki '%{id}' a Ã©tÃ© mise Ã  jour par %{author}."
+
+
+  field_name: Nom
+  field_description: Description
+  field_summary: RÃ©sumÃ©
+  field_is_required: Obligatoire
+  field_firstname: PrÃ©nom
+  field_lastname: Nom
+  field_mail: "Email "
+  field_filename: Fichier
+  field_filesize: Taille
+  field_downloads: TÃ©lÃ©chargements
+  field_author: Auteur
+  field_created_on: "CrÃ©Ã© "
+  field_updated_on: "Mis-Ã -jour "
+  field_closed_on: FermÃ©
+  field_field_format: Format
+  field_is_for_all: Pour tous les projets
+  field_possible_values: Valeurs possibles
+  field_regexp: Expression rÃ©guliÃ¨re
+  field_min_length: Longueur minimum
+  field_max_length: Longueur maximum
+  field_value: Valeur
+  field_category: CatÃ©gorie
+  field_title: Titre
+  field_project: Projet
+  field_issue: Demande
+  field_status: Statut
+  field_notes: Notes
+  field_is_closed: Demande fermÃ©e
+  field_is_default: Valeur par dÃ©faut
+  field_tracker: Tracker
+  field_subject: Sujet
+  field_due_date: EchÃ©ance
+  field_assigned_to: AssignÃ© Ã 
+  field_priority: PrioritÃ©
+  field_fixed_version: Version cible
+  field_user: Utilisateur
+  field_role: RÃ´le
+  field_homepage: "Site web "
+  field_is_public: Public
+  field_parent: Sous-projet de
+  field_is_in_roadmap: Demandes affichÃ©es dans la roadmap
+  field_login: "Identifiant "
+  field_mail_notification: Notifications par mail
+  field_admin: Administrateur
+  field_last_login_on: "DerniÃ¨re connexion "
+  field_language: Langue
+  field_effective_date: Date
+  field_password: Mot de passe
+  field_new_password: Nouveau mot de passe
+  field_password_confirmation: Confirmation
+  field_version: Version
+  field_type: Type
+  field_host: HÃ´te
+  field_port: Port
+  field_account: Compte
+  field_base_dn: Base DN
+  field_attr_login: Attribut Identifiant
+  field_attr_firstname: Attribut PrÃ©nom
+  field_attr_lastname: Attribut Nom
+  field_attr_mail: Attribut Email
+  field_onthefly: CrÃ©ation des utilisateurs Ã  la volÃ©e
+  field_start_date: DÃ©but
+  field_done_ratio: "% rÃ©alisÃ©"
+  field_auth_source: Mode d'authentification
+  field_hide_mail: Cacher mon adresse mail
+  field_comments: Commentaire
+  field_url: URL
+  field_start_page: Page de dÃ©marrage
+  field_subproject: Sous-projet
+  field_hours: Heures
+  field_activity: ActivitÃ©
+  field_spent_on: Date
+  field_identifier: Identifiant
+  field_is_filter: UtilisÃ© comme filtre
+  field_issue_to: Demande liÃ©e
+  field_delay: Retard
+  field_assignable: Demandes assignables Ã  ce rÃ´le
+  field_redirect_existing_links: Rediriger les liens existants
+  field_estimated_hours: Temps estimÃ©
+  field_column_names: Colonnes
+  field_time_zone: Fuseau horaire
+  field_searchable: UtilisÃ© pour les recherches
+  field_default_value: Valeur par dÃ©faut
+  field_comments_sorting: Afficher les commentaires
+  field_parent_title: Page parent
+  field_editable: Modifiable
+  field_watcher: Observateur
+  field_identity_url: URL OpenID
+  field_content: Contenu
+  field_group_by: Grouper par
+  field_sharing: Partage
+  field_active: Actif
+  field_parent_issue: TÃ¢che parente
+  field_visible: Visible
+  field_warn_on_leaving_unsaved: "M'avertir lorsque je quitte une page contenant du texte non sauvegardÃ©"
+  field_issues_visibility: VisibilitÃ© des demandes
+  field_is_private: PrivÃ©e
+  field_commit_logs_encoding: Encodage des messages de commit
+  field_repository_is_default: DÃ©pÃ´t principal
+  field_multiple: Valeurs multiples
+  field_auth_source_ldap_filter: Filtre LDAP
+  field_core_fields: Champs standards
+  field_timeout: "Timeout (en secondes)"
+  field_board_parent: Forum parent
+  field_private_notes: Notes privÃ©es
+  field_inherit_members: HÃ©riter les membres
+
+  setting_app_title: Titre de l'application
+  setting_app_subtitle: Sous-titre de l'application
+  setting_welcome_text: Texte d'accueil
+  setting_default_language: Langue par dÃ©faut
+  setting_login_required: Authentification obligatoire
+  setting_self_registration: Inscription des nouveaux utilisateurs
+  setting_attachment_max_size: Taille maximale des fichiers
+  setting_issues_export_limit: Limite d'exportation des demandes
+  setting_mail_from: Adresse d'Ã©mission
+  setting_bcc_recipients: Destinataires en copie cachÃ©e (cci)
+  setting_plain_text_mail: Mail en texte brut (non HTML)
+  setting_host_name: Nom d'hÃ´te et chemin
+  setting_text_formatting: Formatage du texte
+  setting_wiki_compression: Compression de l'historique des pages wiki
+  setting_feeds_limit: Nombre maximal d'Ã©lÃ©ments dans les flux Atom
+  setting_default_projects_public: DÃ©finir les nouveaux projets comme publics par dÃ©faut
+  setting_autofetch_changesets: RÃ©cupÃ©ration automatique des commits
+  setting_sys_api_enabled: Activer les WS pour la gestion des dÃ©pÃ´ts
+  setting_commit_ref_keywords: Mots-clÃ©s de rÃ©fÃ©rencement
+  setting_commit_fix_keywords: Mots-clÃ©s de rÃ©solution
+  setting_autologin: DurÃ©e maximale de connexion automatique
+  setting_date_format: Format de date
+  setting_time_format: Format d'heure
+  setting_cross_project_issue_relations: Autoriser les relations entre demandes de diffÃ©rents projets
+  setting_cross_project_subtasks: Autoriser les sous-tÃ¢ches dans des projets diffÃ©rents
+  setting_issue_list_default_columns: Colonnes affichÃ©es par dÃ©faut sur la liste des demandes
+  setting_emails_footer: Pied-de-page des emails
+  setting_protocol: Protocole
+  setting_per_page_options: Options d'objets affichÃ©s par page
+  setting_user_format: Format d'affichage des utilisateurs
+  setting_activity_days_default: Nombre de jours affichÃ©s sur l'activitÃ© des projets
+  setting_display_subprojects_issues: Afficher par dÃ©faut les demandes des sous-projets sur les projets principaux
+  setting_enabled_scm: SCM activÃ©s
+  setting_mail_handler_body_delimiters: "Tronquer les emails aprÃ¨s l'une de ces lignes"
+  setting_mail_handler_api_enabled: "Activer le WS pour la rÃ©ception d'emails"
+  setting_mail_handler_api_key: ClÃ© de protection de l'API
+  setting_sequential_project_identifiers: GÃ©nÃ©rer des identifiants de projet sÃ©quentiels
+  setting_gravatar_enabled: Afficher les Gravatar des utilisateurs
+  setting_diff_max_lines_displayed: Nombre maximum de lignes de diff affichÃ©es
+  setting_file_max_size_displayed: Taille maximum des fichiers texte affichÃ©s en ligne
+  setting_repository_log_display_limit: "Nombre maximum de rÃ©visions affichÃ©es sur l'historique d'un fichier"
+  setting_openid: "Autoriser l'authentification et l'enregistrement OpenID"
+  setting_password_min_length: Longueur minimum des mots de passe
+  setting_new_project_user_role_id: RÃ´le donnÃ© Ã  un utilisateur non-administrateur qui crÃ©e un projet
+  setting_default_projects_modules: Modules activÃ©s par dÃ©faut pour les nouveaux projets
+  setting_issue_done_ratio: Calcul de l'avancement des demandes
+  setting_issue_done_ratio_issue_status: Utiliser le statut
+  setting_issue_done_ratio_issue_field: 'Utiliser le champ % effectuÃ©'
+  setting_rest_api_enabled: Activer l'API REST
+  setting_gravatar_default: Image Gravatar par dÃ©faut
+  setting_start_of_week: Jour de dÃ©but des calendriers
+  setting_cache_formatted_text: Mettre en cache le texte formatÃ©
+  setting_commit_logtime_enabled: Permettre la saisie de temps
+  setting_commit_logtime_activity_id: ActivitÃ© pour le temps saisi
+  setting_gantt_items_limit: Nombre maximum d'Ã©lÃ©ments affichÃ©s sur le gantt
+  setting_issue_group_assignment: Permettre l'assignement des demandes aux groupes
+  setting_default_issue_start_date_to_creation_date: Donner Ã  la date de dÃ©but d'une nouvelle demande la valeur de la date du jour
+  setting_commit_cross_project_ref: Permettre le rÃ©fÃ©rencement et la rÃ©solution des demandes de tous les autres projets
+  setting_unsubscribe: Permettre aux utilisateurs de supprimer leur propre compte
+  setting_session_lifetime: DurÃ©e de vie maximale des sessions
+  setting_session_timeout: DurÃ©e maximale d'inactivitÃ©
+  setting_thumbnails_enabled: Afficher les vignettes des images
+  setting_thumbnails_size: Taille des vignettes (en pixels)
+  setting_non_working_week_days: Jours non travaillÃ©s
+  setting_jsonp_enabled: Activer le support JSONP
+  setting_default_projects_tracker_ids: Trackers par dÃ©faut pour les nouveaux projets
+
+  permission_add_project: CrÃ©er un projet
+  permission_add_subprojects: CrÃ©er des sous-projets
+  permission_edit_project: Modifier le projet
+  permission_close_project: Fermer / rÃ©ouvrir le projet
+  permission_select_project_modules: Choisir les modules
+  permission_manage_members: GÃ©rer les membres
+  permission_manage_versions: GÃ©rer les versions
+  permission_manage_categories: GÃ©rer les catÃ©gories de demandes
+  permission_view_issues: Voir les demandes
+  permission_add_issues: CrÃ©er des demandes
+  permission_edit_issues: Modifier les demandes
+  permission_manage_issue_relations: GÃ©rer les relations
+  permission_set_issues_private: Rendre les demandes publiques ou privÃ©es
+  permission_set_own_issues_private: Rendre ses propres demandes publiques ou privÃ©es
+  permission_add_issue_notes: Ajouter des notes
+  permission_edit_issue_notes: Modifier les notes
+  permission_edit_own_issue_notes: Modifier ses propres notes
+  permission_view_private_notes: Voir les notes privÃ©es
+  permission_set_notes_private: Rendre les notes privÃ©es
+  permission_move_issues: DÃ©placer les demandes
+  permission_delete_issues: Supprimer les demandes
+  permission_manage_public_queries: GÃ©rer les requÃªtes publiques
+  permission_save_queries: Sauvegarder les requÃªtes
+  permission_view_gantt: Voir le gantt
+  permission_view_calendar: Voir le calendrier
+  permission_view_issue_watchers: Voir la liste des observateurs
+  permission_add_issue_watchers: Ajouter des observateurs
+  permission_delete_issue_watchers: Supprimer des observateurs
+  permission_log_time: Saisir le temps passÃ©
+  permission_view_time_entries: Voir le temps passÃ©
+  permission_edit_time_entries: Modifier les temps passÃ©s
+  permission_edit_own_time_entries: Modifier son propre temps passÃ©
+  permission_manage_news: GÃ©rer les annonces
+  permission_comment_news: Commenter les annonces
+  permission_view_documents: Voir les documents
+  permission_add_documents: Ajouter des documents
+  permission_edit_documents: Modifier les documents
+  permission_delete_documents: Supprimer les documents
+  permission_manage_files: GÃ©rer les fichiers
+  permission_view_files: Voir les fichiers
+  permission_manage_wiki: GÃ©rer le wiki
+  permission_rename_wiki_pages: Renommer les pages
+  permission_delete_wiki_pages: Supprimer les pages
+  permission_view_wiki_pages: Voir le wiki
+  permission_view_wiki_edits: "Voir l'historique des modifications"
+  permission_edit_wiki_pages: Modifier les pages
+  permission_delete_wiki_pages_attachments: Supprimer les fichiers joints
+  permission_protect_wiki_pages: ProtÃ©ger les pages
+  permission_manage_repository: GÃ©rer le dÃ©pÃ´t de sources
+  permission_browse_repository: Parcourir les sources
+  permission_view_changesets: Voir les rÃ©visions
+  permission_commit_access: Droit de commit
+  permission_manage_boards: GÃ©rer les forums
+  permission_view_messages: Voir les messages
+  permission_add_messages: Poster un message
+  permission_edit_messages: Modifier les messages
+  permission_edit_own_messages: Modifier ses propres messages
+  permission_delete_messages: Supprimer les messages
+  permission_delete_own_messages: Supprimer ses propres messages
+  permission_export_wiki_pages: Exporter les pages
+  permission_manage_project_activities: GÃ©rer les activitÃ©s
+  permission_manage_subtasks: GÃ©rer les sous-tÃ¢ches
+  permission_manage_related_issues: GÃ©rer les demandes associÃ©es
+
+  project_module_issue_tracking: Suivi des demandes
+  project_module_time_tracking: Suivi du temps passÃ©
+  project_module_news: Publication d'annonces
+  project_module_documents: Publication de documents
+  project_module_files: Publication de fichiers
+  project_module_wiki: Wiki
+  project_module_repository: DÃ©pÃ´t de sources
+  project_module_boards: Forums de discussion
+
+  label_user: Utilisateur
+  label_user_plural: Utilisateurs
+  label_user_new: Nouvel utilisateur
+  label_user_anonymous: Anonyme
+  label_project: Projet
+  label_project_new: Nouveau projet
+  label_project_plural: Projets
+  label_x_projects:
+    zero:  aucun projet
+    one:   un projet
+    other: "%{count} projets"
+  label_project_all: Tous les projets
+  label_project_latest: Derniers projets
+  label_issue: Demande
+  label_issue_new: Nouvelle demande
+  label_issue_plural: Demandes
+  label_issue_view_all: Voir toutes les demandes
+  label_issue_added: Demande ajoutÃ©e
+  label_issue_updated: Demande mise Ã  jour
+  label_issue_note_added: Note ajoutÃ©e
+  label_issue_status_updated: Statut changÃ©
+  label_issue_priority_updated: PrioritÃ© changÃ©e
+  label_issues_by: "Demandes par %{value}"
+  label_document: Document
+  label_document_new: Nouveau document
+  label_document_plural: Documents
+  label_document_added: Document ajoutÃ©
+  label_role: RÃ´le
+  label_role_plural: RÃ´les
+  label_role_new: Nouveau rÃ´le
+  label_role_and_permissions: RÃ´les et permissions
+  label_role_anonymous: Anonyme
+  label_role_non_member: Non membre
+  label_member: Membre
+  label_member_new: Nouveau membre
+  label_member_plural: Membres
+  label_tracker: Tracker
+  label_tracker_plural: Trackers
+  label_tracker_new: Nouveau tracker
+  label_workflow: Workflow
+  label_issue_status: Statut de demandes
+  label_issue_status_plural: Statuts de demandes
+  label_issue_status_new: Nouveau statut
+  label_issue_category: CatÃ©gorie de demandes
+  label_issue_category_plural: CatÃ©gories de demandes
+  label_issue_category_new: Nouvelle catÃ©gorie
+  label_custom_field: Champ personnalisÃ©
+  label_custom_field_plural: Champs personnalisÃ©s
+  label_custom_field_new: Nouveau champ personnalisÃ©
+  label_enumerations: Listes de valeurs
+  label_enumeration_new: Nouvelle valeur
+  label_information: Information
+  label_information_plural: Informations
+  label_please_login: Identification
+  label_register: S'enregistrer
+  label_login_with_open_id_option: S'authentifier avec OpenID
+  label_password_lost: Mot de passe perdu
+  label_home: Accueil
+  label_my_page: Ma page
+  label_my_account: Mon compte
+  label_my_projects: Mes projets
+  label_my_page_block: Blocs disponibles
+  label_administration: Administration
+  label_login: Connexion
+  label_logout: DÃ©connexion
+  label_help: Aide
+  label_reported_issues: "Demandes soumises "
+  label_assigned_to_me_issues: Demandes qui me sont assignÃ©es
+  label_last_login: "DerniÃ¨re connexion "
+  label_registered_on: "Inscrit le "
+  label_activity: ActivitÃ©
+  label_overall_activity: ActivitÃ© globale
+  label_user_activity: "ActivitÃ© de %{value}"
+  label_new: Nouveau
+  label_logged_as: ConnectÃ© en tant que
+  label_environment: Environnement
+  label_authentication: Authentification
+  label_auth_source: Mode d'authentification
+  label_auth_source_new: Nouveau mode d'authentification
+  label_auth_source_plural: Modes d'authentification
+  label_subproject_plural: Sous-projets
+  label_subproject_new: Nouveau sous-projet
+  label_and_its_subprojects: "%{value} et ses sous-projets"
+  label_min_max_length: Longueurs mini - maxi
+  label_list: Liste
+  label_date: Date
+  label_integer: Entier
+  label_float: Nombre dÃ©cimal
+  label_boolean: BoolÃ©en
+  label_string: Texte
+  label_text: Texte long
+  label_attribute: Attribut
+  label_attribute_plural: Attributs
+  label_no_data: Aucune donnÃ©e Ã  afficher
+  label_change_status: Changer le statut
+  label_history: Historique
+  label_attachment: Fichier
+  label_attachment_new: Nouveau fichier
+  label_attachment_delete: Supprimer le fichier
+  label_attachment_plural: Fichiers
+  label_file_added: Fichier ajoutÃ©
+  label_report: Rapport
+  label_report_plural: Rapports
+  label_news: Annonce
+  label_news_new: Nouvelle annonce
+  label_news_plural: Annonces
+  label_news_latest: DerniÃ¨res annonces
+  label_news_view_all: Voir toutes les annonces
+  label_news_added: Annonce ajoutÃ©e
+  label_news_comment_added: Commentaire ajoutÃ© Ã  une annonce
+  label_settings: Configuration
+  label_overview: AperÃ§u
+  label_version: Version
+  label_version_new: Nouvelle version
+  label_version_plural: Versions
+  label_confirmation: Confirmation
+  label_export_to: 'Formats disponibles :'
+  label_read: Lire...
+  label_public_projects: Projets publics
+  label_open_issues: ouvert
+  label_open_issues_plural: ouverts
+  label_closed_issues: fermÃ©
+  label_closed_issues_plural: fermÃ©s
+  label_x_open_issues_abbr_on_total:
+    zero:  0 ouverte sur %{total}
+    one:   1 ouverte sur %{total}
+    other: "%{count} ouvertes sur %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 ouverte
+    one:   1 ouverte
+    other: "%{count} ouvertes"
+  label_x_closed_issues_abbr:
+    zero:  0 fermÃ©e
+    one:   1 fermÃ©e
+    other: "%{count} fermÃ©es"
+  label_x_issues:
+    zero:  0 demande
+    one:   1 demande
+    other: "%{count} demandes"
+  label_total: Total
+  label_total_time: Temps total
+  label_permissions: Permissions
+  label_current_status: Statut actuel
+  label_new_statuses_allowed: Nouveaux statuts autorisÃ©s
+  label_all: tous
+  label_any: tous
+  label_none: aucun
+  label_nobody: personne
+  label_next: Suivant
+  label_previous: PrÃ©cÃ©dent
+  label_used_by: UtilisÃ© par
+  label_details: DÃ©tails
+  label_add_note: Ajouter une note
+  label_per_page: Par page
+  label_calendar: Calendrier
+  label_months_from: mois depuis
+  label_gantt: Gantt
+  label_internal: Interne
+  label_last_changes: "%{count} derniers changements"
+  label_change_view_all: Voir tous les changements
+  label_personalize_page: Personnaliser cette page
+  label_comment: Commentaire
+  label_comment_plural: Commentaires
+  label_x_comments:
+    zero: aucun commentaire
+    one: un commentaire
+    other: "%{count} commentaires"
+  label_comment_add: Ajouter un commentaire
+  label_comment_added: Commentaire ajoutÃ©
+  label_comment_delete: Supprimer les commentaires
+  label_query: Rapport personnalisÃ©
+  label_query_plural: Rapports personnalisÃ©s
+  label_query_new: Nouveau rapport
+  label_my_queries: Mes rapports personnalisÃ©s
+  label_filter_add: "Ajouter le filtre "
+  label_filter_plural: Filtres
+  label_equals: Ã©gal
+  label_not_equals: diffÃ©rent
+  label_in_less_than: dans moins de
+  label_in_more_than: dans plus de
+  label_in_the_next_days: dans les prochains jours
+  label_in_the_past_days: dans les derniers jours
+  label_in: dans
+  label_today: aujourd'hui
+  label_all_time: toute la pÃ©riode
+  label_yesterday: hier
+  label_this_week: cette semaine
+  label_last_week: la semaine derniÃ¨re
+  label_last_n_weeks: "les %{count} derniÃ¨res semaines"
+  label_last_n_days: "les %{count} derniers jours"
+  label_this_month: ce mois-ci
+  label_last_month: le mois dernier
+  label_this_year: cette annÃ©e
+  label_date_range: PÃ©riode
+  label_less_than_ago: il y a moins de
+  label_more_than_ago: il y a plus de
+  label_ago: il y a
+  label_contains: contient
+  label_not_contains: ne contient pas
+  label_any_issues_in_project: une demande du projet
+  label_any_issues_not_in_project: une demande hors du projet
+  label_no_issues_in_project: aucune demande du projet
+  label_day_plural: jours
+  label_repository: DÃ©pÃ´t
+  label_repository_new: Nouveau dÃ©pÃ´t
+  label_repository_plural: DÃ©pÃ´ts
+  label_browse: Parcourir
+  label_revision: "RÃ©vision "
+  label_revision_plural: RÃ©visions
+  label_associated_revisions: RÃ©visions associÃ©es
+  label_added: ajoutÃ©
+  label_modified: modifiÃ©
+  label_copied: copiÃ©
+  label_renamed: renommÃ©
+  label_deleted: supprimÃ©
+  label_latest_revision: DerniÃ¨re rÃ©vision
+  label_latest_revision_plural: DerniÃ¨res rÃ©visions
+  label_view_revisions: Voir les rÃ©visions
+  label_max_size: Taille maximale
+  label_sort_highest: Remonter en premier
+  label_sort_higher: Remonter
+  label_sort_lower: Descendre
+  label_sort_lowest: Descendre en dernier
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "Ã‰chÃ©ance dans %{value}"
+  label_roadmap_overdue: "En retard de %{value}"
+  label_roadmap_no_issues: Aucune demande pour cette version
+  label_search: "Recherche "
+  label_result_plural: RÃ©sultats
+  label_all_words: Tous les mots
+  label_wiki: Wiki
+  label_wiki_edit: RÃ©vision wiki
+  label_wiki_edit_plural: RÃ©visions wiki
+  label_wiki_page: Page wiki
+  label_wiki_page_plural: Pages wiki
+  label_index_by_title: Index par titre
+  label_index_by_date: Index par date
+  label_current_version: Version actuelle
+  label_preview: PrÃ©visualisation
+  label_feed_plural: Flux RSS
+  label_changes_details: DÃ©tails de tous les changements
+  label_issue_tracking: Suivi des demandes
+  label_spent_time: Temps passÃ©
+  label_f_hour: "%{value} heure"
+  label_f_hour_plural: "%{value} heures"
+  label_time_tracking: Suivi du temps
+  label_change_plural: Changements
+  label_statistics: Statistiques
+  label_commits_per_month: Commits par mois
+  label_commits_per_author: Commits par auteur
+  label_view_diff: Voir les diffÃ©rences
+  label_diff_inline: en ligne
+  label_diff_side_by_side: cÃ´te Ã  cÃ´te
+  label_options: Options
+  label_copy_workflow_from: Copier le workflow de
+  label_permissions_report: SynthÃ¨se des permissions
+  label_watched_issues: Demandes surveillÃ©es
+  label_related_issues: Demandes liÃ©es
+  label_applied_status: Statut appliquÃ©
+  label_loading: Chargement...
+  label_relation_new: Nouvelle relation
+  label_relation_delete: Supprimer la relation
+  label_relates_to: LiÃ© Ã 
+  label_duplicates: Duplique
+  label_duplicated_by: DupliquÃ© par
+  label_blocks: Bloque
+  label_blocked_by: BloquÃ© par
+  label_precedes: PrÃ©cÃ¨de
+  label_follows: Suit
+  label_copied_to: CopiÃ© vers
+  label_copied_from: CopiÃ© depuis
+  label_end_to_start: fin Ã  dÃ©but
+  label_end_to_end: fin Ã  fin
+  label_start_to_start: dÃ©but Ã  dÃ©but
+  label_start_to_end: dÃ©but Ã  fin
+  label_stay_logged_in: Rester connectÃ©
+  label_disabled: dÃ©sactivÃ©
+  label_show_completed_versions: Voir les versions passÃ©es
+  label_me: moi
+  label_board: Forum
+  label_board_new: Nouveau forum
+  label_board_plural: Forums
+  label_topic_plural: Discussions
+  label_message_plural: Messages
+  label_message_last: Dernier message
+  label_message_new: Nouveau message
+  label_message_posted: Message ajoutÃ©
+  label_reply_plural: RÃ©ponses
+  label_send_information: Envoyer les informations Ã  l'utilisateur
+  label_year: AnnÃ©e
+  label_month: Mois
+  label_week: Semaine
+  label_date_from: Du
+  label_date_to: Au
+  label_language_based: BasÃ© sur la langue de l'utilisateur
+  label_sort_by: "Trier par %{value}"
+  label_send_test_email: Envoyer un email de test
+  label_feeds_access_key_created_on: "ClÃ© d'accÃ¨s RSS crÃ©Ã©e il y a %{value}"
+  label_module_plural: Modules
+  label_added_time_by: "AjoutÃ© par %{author} il y a %{age}"
+  label_updated_time_by: "Mis Ã  jour par %{author} il y a %{age}"
+  label_updated_time: "Mis Ã  jour il y a %{value}"
+  label_jump_to_a_project: Aller Ã  un projet...
+  label_file_plural: Fichiers
+  label_changeset_plural: RÃ©visions
+  label_default_columns: Colonnes par dÃ©faut
+  label_no_change_option: (Pas de changement)
+  label_bulk_edit_selected_issues: Modifier les demandes sÃ©lectionnÃ©es
+  label_theme: ThÃ¨me
+  label_default: DÃ©faut
+  label_search_titles_only: Uniquement dans les titres
+  label_user_mail_option_all: "Pour tous les Ã©vÃ©nements de tous mes projets"
+  label_user_mail_option_selected: "Pour tous les Ã©vÃ©nements des projets sÃ©lectionnÃ©s..."
+  label_user_mail_no_self_notified: "Je ne veux pas Ãªtre notifiÃ© des changements que j'effectue"
+  label_registration_activation_by_email: activation du compte par email
+  label_registration_manual_activation: activation manuelle du compte
+  label_registration_automatic_activation: activation automatique du compte
+  label_display_per_page: "Par page : %{value}"
+  label_age: Ã‚ge
+  label_change_properties: Changer les propriÃ©tÃ©s
+  label_general: GÃ©nÃ©ral
+  label_more: Plus
+  label_scm: SCM
+  label_plugins: Plugins
+  label_ldap_authentication: Authentification LDAP
+  label_downloads_abbr: D/L
+  label_optional_description: Description facultative
+  label_add_another_file: Ajouter un autre fichier
+  label_preferences: PrÃ©fÃ©rences
+  label_chronological_order: Dans l'ordre chronologique
+  label_reverse_chronological_order: Dans l'ordre chronologique inverse
+  label_planning: Planning
+  label_incoming_emails: Emails entrants
+  label_generate_key: GÃ©nÃ©rer une clÃ©
+  label_issue_watchers: Observateurs
+  label_example: Exemple
+  label_display: Affichage
+  label_sort: Tri
+  label_ascending: Croissant
+  label_descending: DÃ©croissant
+  label_date_from_to: Du %{start} au %{end}
+  label_wiki_content_added: Page wiki ajoutÃ©e
+  label_wiki_content_updated: Page wiki mise Ã  jour
+  label_group_plural: Groupes
+  label_group: Groupe
+  label_group_new: Nouveau groupe
+  label_time_entry_plural: Temps passÃ©
+  label_version_sharing_none: Non partagÃ©
+  label_version_sharing_descendants: Avec les sous-projets
+  label_version_sharing_hierarchy: Avec toute la hiÃ©rarchie
+  label_version_sharing_tree: Avec tout l'arbre
+  label_version_sharing_system: Avec tous les projets
+  label_copy_source: Source
+  label_copy_target: Cible
+  label_copy_same_as_target: Comme la cible
+  label_update_issue_done_ratios: Mettre Ã  jour l'avancement des demandes
+  label_display_used_statuses_only: N'afficher que les statuts utilisÃ©s dans ce tracker
+  label_api_access_key: ClÃ© d'accÃ¨s API
+  label_api_access_key_created_on: ClÃ© d'accÃ¨s API crÃ©Ã©e il y a %{value}
+  label_feeds_access_key: ClÃ© d'accÃ¨s RSS
+  label_missing_api_access_key: ClÃ© d'accÃ¨s API manquante
+  label_missing_feeds_access_key: ClÃ© d'accÃ¨s RSS manquante
+  label_close_versions: Fermer les versions terminÃ©es
+  label_revision_id: RÃ©vision %{value}
+  label_profile: Profil
+  label_subtask_plural: Sous-tÃ¢ches
+  label_project_copy_notifications: Envoyer les notifications durant la copie du projet
+  label_principal_search: "Rechercher un utilisateur ou un groupe :"
+  label_user_search: "Rechercher un utilisateur :"
+  label_additional_workflow_transitions_for_author: Autorisations supplÃ©mentaires lorsque l'utilisateur a crÃ©Ã© la demande
+  label_additional_workflow_transitions_for_assignee: Autorisations supplÃ©mentaires lorsque la demande est assignÃ©e Ã  l'utilisateur
+  label_issues_visibility_all: Toutes les demandes
+  label_issues_visibility_public: Toutes les demandes non privÃ©es
+  label_issues_visibility_own: Demandes crÃ©Ã©es par ou assignÃ©es Ã  l'utilisateur
+  label_export_options: Options d'exportation %{export_format}
+  label_copy_attachments: Copier les fichiers
+  label_copy_subtasks: Copier les sous-tÃ¢ches
+  label_item_position: "%{position} sur %{count}"
+  label_completed_versions: Versions passÃ©es
+  label_session_expiration: Expiration des sessions
+  label_show_closed_projects: Voir les projets fermÃ©s
+  label_status_transitions: Changements de statut
+  label_fields_permissions: Permissions sur les champs
+  label_readonly: Lecture
+  label_required: Obligatoire
+  label_attribute_of_project: "%{name} du projet"
+  label_attribute_of_issue: "%{name} de la demande"
+  label_attribute_of_author: "%{name} de l'auteur"
+  label_attribute_of_assigned_to: "%{name} de l'assignÃ©"
+  label_attribute_of_user: "%{name} de l'utilisateur"
+  label_attribute_of_fixed_version: "%{name} de la version cible"
+  label_cross_project_descendants: Avec les sous-projets
+  label_cross_project_tree: Avec tout l'arbre
+  label_cross_project_hierarchy: Avec toute la hiÃ©rarchie
+  label_cross_project_system: Avec tous les projets
+  label_gantt_progress_line: Ligne de progression
+
+  button_login: Connexion
+  button_submit: Soumettre
+  button_save: Sauvegarder
+  button_check_all: Tout cocher
+  button_uncheck_all: Tout dÃ©cocher
+  button_collapse_all: Plier tout
+  button_expand_all: DÃ©plier tout
+  button_delete: Supprimer
+  button_create: CrÃ©er
+  button_create_and_continue: CrÃ©er et continuer
+  button_test: Tester
+  button_edit: Modifier
+  button_add: Ajouter
+  button_change: Changer
+  button_apply: Appliquer
+  button_clear: Effacer
+  button_lock: Verrouiller
+  button_unlock: DÃ©verrouiller
+  button_download: TÃ©lÃ©charger
+  button_list: Lister
+  button_view: Voir
+  button_move: DÃ©placer
+  button_move_and_follow: DÃ©placer et suivre
+  button_back: Retour
+  button_cancel: Annuler
+  button_activate: Activer
+  button_sort: Trier
+  button_log_time: Saisir temps
+  button_rollback: Revenir Ã  cette version
+  button_watch: Surveiller
+  button_unwatch: Ne plus surveiller
+  button_reply: RÃ©pondre
+  button_archive: Archiver
+  button_unarchive: DÃ©sarchiver
+  button_reset: RÃ©initialiser
+  button_rename: Renommer
+  button_change_password: Changer de mot de passe
+  button_copy: Copier
+  button_copy_and_follow: Copier et suivre
+  button_annotate: Annoter
+  button_update: Mettre Ã  jour
+  button_configure: Configurer
+  button_quote: Citer
+  button_duplicate: Dupliquer
+  button_show: Afficher
+  button_hide: Cacher
+  button_edit_section: Modifier cette section
+  button_export: Exporter
+  button_delete_my_account: Supprimer mon compte
+  button_close: Fermer
+  button_reopen: RÃ©ouvrir
+
+  status_active: actif
+  status_registered: enregistrÃ©
+  status_locked: verrouillÃ©
+
+  project_status_active: actif
+  project_status_closed: fermÃ©
+  project_status_archived: archivÃ©
+
+  version_status_open: ouvert
+  version_status_locked: verrouillÃ©
+  version_status_closed: fermÃ©
+
+  text_select_mail_notifications: Actions pour lesquelles une notification par e-mail est envoyÃ©e
+  text_regexp_info: ex. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 pour aucune restriction
+  text_project_destroy_confirmation: ÃŠtes-vous sÃ»r de vouloir supprimer ce projet et toutes ses donnÃ©es ?
+  text_subprojects_destroy_warning: "Ses sous-projets : %{value} seront Ã©galement supprimÃ©s."
+  text_workflow_edit: SÃ©lectionner un tracker et un rÃ´le pour Ã©diter le workflow
+  text_are_you_sure: ÃŠtes-vous sÃ»r ?
+  text_tip_issue_begin_day: tÃ¢che commenÃ§ant ce jour
+  text_tip_issue_end_day: tÃ¢che finissant ce jour
+  text_tip_issue_begin_end_day: tÃ¢che commenÃ§ant et finissant ce jour
+  text_project_identifier_info: 'Seuls les lettres minuscules (a-z), chiffres, tirets et underscore sont autorisÃ©s, doit commencer par une minuscule.<br />Un fois sauvegardÃ©, l''identifiant ne pourra plus Ãªtre modifiÃ©.'
+  text_caracters_maximum: "%{count} caractÃ¨res maximum."
+  text_caracters_minimum: "%{count} caractÃ¨res minimum."
+  text_length_between: "Longueur comprise entre %{min} et %{max} caractÃ¨res."
+  text_tracker_no_workflow: Aucun worflow n'est dÃ©fini pour ce tracker
+  text_unallowed_characters: CaractÃ¨res non autorisÃ©s
+  text_comma_separated: Plusieurs valeurs possibles (sÃ©parÃ©es par des virgules).
+  text_line_separated: Plusieurs valeurs possibles (une valeur par ligne).
+  text_issues_ref_in_commit_messages: RÃ©fÃ©rencement et rÃ©solution des demandes dans les commentaires de commits
+  text_issue_added: "La demande %{id} a Ã©tÃ© soumise par %{author}."
+  text_issue_updated: "La demande %{id} a Ã©tÃ© mise Ã  jour par %{author}."
+  text_wiki_destroy_confirmation: Etes-vous sÃ»r de vouloir supprimer ce wiki et tout son contenu ?
+  text_issue_category_destroy_question: "%{count} demandes sont affectÃ©es Ã  cette catÃ©gorie. Que voulez-vous faire ?"
+  text_issue_category_destroy_assignments: N'affecter les demandes Ã  aucune autre catÃ©gorie
+  text_issue_category_reassign_to: RÃ©affecter les demandes Ã  cette catÃ©gorie
+  text_user_mail_option: "Pour les projets non sÃ©lectionnÃ©s, vous recevrez seulement des notifications pour ce que vous surveillez ou Ã  quoi vous participez (exemple: demandes dont vous Ãªtes l'auteur ou la personne assignÃ©e)."
+  text_no_configuration_data: "Les rÃ´les, trackers, statuts et le workflow ne sont pas encore paramÃ©trÃ©s.\nIl est vivement recommandÃ© de charger le paramÃ©trage par defaut. Vous pourrez le modifier une fois chargÃ©."
+  text_load_default_configuration: Charger le paramÃ©trage par dÃ©faut
+  text_status_changed_by_changeset: "AppliquÃ© par commit %{value}."
+  text_time_logged_by_changeset: "AppliquÃ© par commit %{value}"
+  text_issues_destroy_confirmation: 'ÃŠtes-vous sÃ»r de vouloir supprimer la ou les demandes(s) selectionnÃ©e(s) ?'
+  text_issues_destroy_descendants_confirmation: "Cela entrainera Ã©galement la suppression de %{count} sous-tÃ¢che(s)."
+  text_select_project_modules: 'SÃ©lectionner les modules Ã  activer pour ce projet :'
+  text_default_administrator_account_changed: Compte administrateur par dÃ©faut changÃ©
+  text_file_repository_writable: RÃ©pertoire de stockage des fichiers accessible en Ã©criture
+  text_plugin_assets_writable: RÃ©pertoire public des plugins accessible en Ã©criture
+  text_rmagick_available: BibliothÃ¨que RMagick prÃ©sente (optionnelle)
+  text_destroy_time_entries_question: "%{hours} heures ont Ã©tÃ© enregistrÃ©es sur les demandes Ã  supprimer. Que voulez-vous faire ?"
+  text_destroy_time_entries: Supprimer les heures
+  text_assign_time_entries_to_project: Reporter les heures sur le projet
+  text_reassign_time_entries: 'Reporter les heures sur cette demande:'
+  text_user_wrote: "%{value} a Ã©crit :"
+  text_enumeration_destroy_question: "Cette valeur est affectÃ©e Ã  %{count} objets."
+  text_enumeration_category_reassign_to: 'RÃ©affecter les objets Ã  cette valeur:'
+  text_email_delivery_not_configured: "L'envoi de mail n'est pas configurÃ©, les notifications sont dÃ©sactivÃ©es.\nConfigurez votre serveur SMTP dans config/configuration.yml et redÃ©marrez l'application pour les activer."
+  text_repository_usernames_mapping: "Vous pouvez sÃ©lectionner ou modifier l'utilisateur Redmine associÃ© Ã  chaque nom d'utilisateur figurant dans l'historique du dÃ©pÃ´t.\nLes utilisateurs avec le mÃªme identifiant ou la mÃªme adresse mail seront automatiquement associÃ©s."
+  text_diff_truncated: '... Ce diffÃ©rentiel a Ã©tÃ© tronquÃ© car il excÃ¨de la taille maximale pouvant Ãªtre affichÃ©e.'
+  text_custom_field_possible_values_info: 'Une ligne par valeur'
+  text_wiki_page_destroy_question: "Cette page possÃ¨de %{descendants} sous-page(s) et descendante(s). Que voulez-vous faire ?"
+  text_wiki_page_nullify_children: "Conserver les sous-pages en tant que pages racines"
+  text_wiki_page_destroy_children: "Supprimer les sous-pages et toutes leurs descedantes"
+  text_wiki_page_reassign_children: "RÃ©affecter les sous-pages Ã  cette page"
+  text_own_membership_delete_confirmation: "Vous allez supprimer tout ou partie de vos permissions sur ce projet et ne serez peut-Ãªtre plus autorisÃ© Ã  modifier ce projet.\nEtes-vous sÃ»r de vouloir continuer ?"
+  text_warn_on_leaving_unsaved: "Cette page contient du texte non sauvegardÃ© qui sera perdu si vous quittez la page."
+  text_issue_conflict_resolution_overwrite: "Appliquer quand mÃªme ma mise Ã  jour (les notes prÃ©cÃ©dentes seront conservÃ©es mais des changements pourront Ãªtre Ã©crasÃ©s)"
+  text_issue_conflict_resolution_add_notes: "Ajouter mes notes et ignorer mes autres changements"
+  text_issue_conflict_resolution_cancel: "Annuler ma mise Ã  jour et rÃ©afficher %{link}"
+  text_account_destroy_confirmation: "ÃŠtes-vous sÃ»r de vouloir continuer ?\nVotre compte sera dÃ©finitivement supprimÃ©, sans aucune possibilitÃ© de le rÃ©activer."
+  text_session_expiration_settings: "Attention : le changement de ces paramÃ¨tres peut entrainer l'expiration des sessions utilisateurs en cours, y compris la vÃ´tre."
+  text_project_closed: Ce projet est fermÃ© et accessible en lecture seule.
+  text_turning_multiple_off: "Si vous dÃ©sactivez les valeurs multiples, les valeurs multiples seront supprimÃ©es pour n'en conserver qu'une par objet."
+
+  default_role_manager: "Manager "
+  default_role_developer: "DÃ©veloppeur "
+  default_role_reporter: "Rapporteur "
+  default_tracker_bug: Anomalie
+  default_tracker_feature: Evolution
+  default_tracker_support: Assistance
+  default_issue_status_new: Nouveau
+  default_issue_status_in_progress: En cours
+  default_issue_status_resolved: RÃ©solu
+  default_issue_status_feedback: Commentaire
+  default_issue_status_closed: FermÃ©
+  default_issue_status_rejected: RejetÃ©
+  default_doc_category_user: Documentation utilisateur
+  default_doc_category_tech: Documentation technique
+  default_priority_low: Bas
+  default_priority_normal: Normal
+  default_priority_high: Haut
+  default_priority_urgent: Urgent
+  default_priority_immediate: ImmÃ©diat
+  default_activity_design: Conception
+  default_activity_development: DÃ©veloppement
+
+  enumeration_issue_priorities: PrioritÃ©s des demandes
+  enumeration_doc_categories: CatÃ©gories des documents
+  enumeration_activities: ActivitÃ©s (suivi du temps)
+  label_greater_or_equal: ">="
+  label_less_or_equal: "<="
+  label_between: entre
+  label_view_all_revisions: Voir toutes les rÃ©visions
+  label_tag: Tag
+  label_branch: Branche
+  error_no_tracker_in_project: "Aucun tracker n'est associÃ© Ã  ce projet. VÃ©rifier la configuration du projet."
+  error_no_default_issue_status: "Aucun statut de demande n'est dÃ©fini par dÃ©faut. VÃ©rifier votre configuration (Administration -> Statuts de demandes)."
+  text_journal_changed: "%{label} changÃ© de %{old} Ã  %{new}"
+  text_journal_changed_no_detail: "%{label} mis Ã  jour"
+  text_journal_set_to: "%{label} mis Ã  %{value}"
+  text_journal_deleted: "%{label} %{old} supprimÃ©"
+  text_journal_added: "%{label} %{value} ajoutÃ©"
+  enumeration_system_activity: ActivitÃ© systÃ¨me
+  label_board_sticky: Sticky
+  label_board_locked: VerrouillÃ©
+  error_unable_delete_issue_status: Impossible de supprimer le statut de demande
+  error_can_not_delete_custom_field: Impossible de supprimer le champ personnalisÃ©
+  error_unable_to_connect: Connexion impossible (%{value})
+  error_can_not_remove_role: Ce rÃ´le est utilisÃ© et ne peut pas Ãªtre supprimÃ©.
+  error_can_not_delete_tracker: Ce tracker contient des demandes et ne peut pas Ãªtre supprimÃ©.
+  field_principal: Principal
+  notice_failed_to_save_members: "Erreur lors de la sauvegarde des membres: %{errors}."
+  text_zoom_out: Zoom arriÃ¨re
+  text_zoom_in: Zoom avant
+  notice_unable_delete_time_entry: Impossible de supprimer le temps passÃ©.
+  label_overall_spent_time: Temps passÃ© global
+  field_time_entries: Temps passÃ©
+  project_module_gantt: Gantt
+  project_module_calendar: Calendrier
+  button_edit_associated_wikipage: "Modifier la page wiki associÃ©e: %{page_title}"
+  field_text: Champ texte
+  label_user_mail_option_only_owner: Seulement pour ce que j'ai crÃ©Ã©
+  setting_default_notification_option: Option de notification par dÃ©faut
+  label_user_mail_option_only_my_events: Seulement pour ce que je surveille
+  label_user_mail_option_only_assigned: Seulement pour ce qui m'est assignÃ©
+  label_user_mail_option_none: Aucune notification
+  field_member_of_group: Groupe de l'assignÃ©
+  field_assigned_to_role: RÃ´le de l'assignÃ©
+  setting_emails_header: En-tÃªte des emails
+  label_bulk_edit_selected_time_entries: Modifier les temps passÃ©s sÃ©lectionnÃ©s
+  text_time_entries_destroy_confirmation: "Etes-vous sÃ»r de vouloir supprimer les temps passÃ©s sÃ©lectionnÃ©s ?"
+  field_scm_path_encoding: Encodage des chemins
+  text_scm_path_encoding_note: "DÃ©faut : UTF-8"
+  field_path_to_repository: Chemin du dÃ©pÃ´t
+  field_root_directory: RÃ©pertoire racine
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: "DÃ©pÃ´t local (exemples : /hgrepo, c:\\hgrepo)"
+  text_scm_command: Commande
+  text_scm_command_version: Version
+  label_git_report_last_commit: Afficher le dernier commit des fichiers et rÃ©pertoires
+  text_scm_config: Vous pouvez configurer les commandes des SCM dans config/configuration.yml. RedÃ©marrer l'application aprÃ¨s modification.
+  text_scm_command_not_available: Ce SCM n'est pas disponible. VÃ©rifier les paramÃ¨tres dans la section administration.
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Ordre de tri
+  description_project_scope: PÃ©rimÃ¨tre de recherche
+  description_filter: Filtre
+  description_user_mail_notification: Option de notification
+  description_date_from: Date de dÃ©but
+  description_message_content: Contenu du message
+  description_available_columns: Colonnes disponibles
+  description_all_columns: Toutes les colonnes
+  description_date_range_interval: Choisir une pÃ©riode
+  description_issue_category_reassign: Choisir une catÃ©gorie
+  description_search: Champ de recherche
+  description_notes: Notes
+  description_date_range_list: Choisir une pÃ©riode prÃ©dÃ©finie
+  description_choose_project: Projets
+  description_date_to: Date de fin
+  description_query_sort_criteria_attribute: CritÃ¨re de tri
+  description_wiki_subpages_reassign: Choisir une nouvelle page parent
+  description_selected_columns: Colonnes sÃ©lectionnÃ©es
+  label_parent_revision: Parent
+  label_child_revision: Enfant
+  error_scm_annotate_big_text_file: Cette entrÃ©e ne peut pas Ãªtre annotÃ©e car elle excÃ¨de la taille maximale.
+  setting_repositories_encodings: Encodages des fichiers et des dÃ©pÃ´ts
+  label_search_for_watchers: Rechercher des observateurs
+  text_repository_identifier_info: 'Seuls les lettres minuscules (a-z), chiffres, tirets et underscore sont autorisÃ©s.<br />Un fois sauvegardÃ©, l''identifiant ne pourra plus Ãªtre modifiÃ©.'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3cb3c42447393d4203d371cda0ccf19d942248be.svn-base
--- /dev/null
+++ b/.svn/pristine/3c/3cb3c42447393d4203d371cda0ccf19d942248be.svn-base
@@ -0,0 +1,99 @@
+<%= error_messages_for 'custom_field' %>
+
+<div class="box tabular">
+<p><%= f.text_field :name, :required => true %></p>
+<p><%= f.select :field_format, custom_field_formats_for_select(@custom_field), {}, :disabled => !@custom_field.new_record? %></p>
+
+<% if @custom_field.format_in? 'list', 'user', 'version' %>
+<p>
+  <%= f.check_box :multiple %>
+  <% if !@custom_field.new_record? && @custom_field.multiple %>
+  <em class="info"><%= l(:text_turning_multiple_off) %></em>
+  <% end %>
+</p>
+<% end %>
+
+<% unless @custom_field.format_in? 'list', 'bool', 'date', 'user', 'version' %>
+<p><label for="custom_field_min_length"><%=l(:label_min_max_length)%></label>
+   <%= f.text_field :min_length, :size => 5, :no_label => true %> - 
+   <%= f.text_field :max_length, :size => 5, :no_label => true %><br />(<%=l(:text_min_max_length_info)%>)</p>
+<p><%= f.text_field :regexp, :size => 50 %><br />(<%=l(:text_regexp_info)%>)</p>
+<% end %>
+
+<% if @custom_field.format_in? 'list' %>
+<p>
+  <%= f.text_area :possible_values, :value => @custom_field.possible_values.to_a.join("\n"), :rows => 15 %>
+  <em class="info"><%= l(:text_custom_field_possible_values_info) %></em>
+</p>
+<% end %>
+
+<% case @custom_field.field_format %>
+<% when 'bool' %>
+  <p><%= f.check_box(:default_value) %></p>
+<% when 'text' %>
+  <p><%= f.text_area(:default_value, :rows => 8) %></p>
+<% when 'date' %>
+  <p><%= f.text_field(:default_value, :size => 10) %></p>
+  <%= calendar_for('custom_field_default_value') %>
+<% when 'user', 'version' %>
+<% else %>
+  <p><%= f.text_field(:default_value) %></p>
+<% end %>
+
+<%= call_hook(:view_custom_fields_form_upper_box, :custom_field => @custom_field, :form => f) %>
+</div>
+
+<div class="box tabular">
+<% case @custom_field.class.name
+when "IssueCustomField" %>
+
+    <fieldset><legend><%=l(:label_tracker_plural)%></legend>
+    <% Tracker.sorted.all.each do |tracker| %>
+      <%= check_box_tag "custom_field[tracker_ids][]",
+                        tracker.id,
+                        (@custom_field.trackers.include? tracker),
+                        :id => "custom_field_tracker_ids_#{tracker.id}" %>
+      <label class="no-css" for="custom_field_tracker_ids_<%=tracker.id%>">
+        <%= h(tracker.name) %>
+      </label>
+    <% end %>
+    <%= hidden_field_tag "custom_field[tracker_ids][]", '' %>
+    </fieldset>
+    &nbsp;
+    <p><%= f.check_box :is_required %></p>
+    <p><%= f.check_box :is_for_all %></p>
+    <p><%= f.check_box :is_filter %></p>
+    <p><%= f.check_box :searchable %></p>
+
+<% when "UserCustomField" %>
+    <p><%= f.check_box :is_required %></p>
+    <p><%= f.check_box :visible %></p>
+    <p><%= f.check_box :editable %></p>
+    <p><%= f.check_box :is_filter %></p>
+
+<% when "ProjectCustomField" %>
+    <p><%= f.check_box :is_required %></p>
+    <p><%= f.check_box :visible %></p>
+    <p><%= f.check_box :searchable %></p>
+    <p><%= f.check_box :is_filter %></p>
+
+<% when "VersionCustomField" %>
+    <p><%= f.check_box :is_required %></p>
+    <p><%= f.check_box :is_filter %></p>
+
+<% when "GroupCustomField" %>
+    <p><%= f.check_box :is_required %></p>
+    <p><%= f.check_box :is_filter %></p>
+
+<% when "TimeEntryCustomField" %>
+    <p><%= f.check_box :is_required %></p>
+    <p><%= f.check_box :is_filter %></p>
+
+<% else %>
+    <p><%= f.check_box :is_required %></p>
+
+<% end %>
+<%= call_hook(:"view_custom_fields_form_#{@custom_field.type.to_s.underscore}", :custom_field => @custom_field, :form => f) %>
+</div>
+
+<% include_calendar_headers_tags %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3cbf045871f4a74462d238faefdda2d93e946bc2.svn-base
--- a/.svn/pristine/3c/3cbf045871f4a74462d238faefdda2d93e946bc2.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-<h2><%=l(:label_project_new)%></h2>
-
-<% labelled_tabular_form_for @project do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_create) %>
-<%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
-<%= javascript_tag "Form.Element.focus('project_name');" %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3cc2762940ee93762d4d782147803b7d0198ed51.svn-base
--- a/.svn/pristine/3c/3cc2762940ee93762d4d782147803b7d0198ed51.svn-base
+++ /dev/null
@@ -1,4 +0,0 @@
-ActionController::Routing::Routes.draw do |map|
-  map.connect 'routes/:action', :controller => "test_routing"
-  map.plugin_route 'somespace/routes/:action', :controller => "namespace/test_routing"
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3cd8e88573cd0b42429f6ee4864dcc592f6b54a1.svn-base
--- a/.svn/pristine/3c/3cd8e88573cd0b42429f6ee4864dcc592f6b54a1.svn-base
+++ /dev/null
@@ -1,29 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine #:nodoc:
-  module CoreExtensions #:nodoc:
-    module String #:nodoc:
-      # Custom string inflections
-      module Inflections
-        def with_leading_slash
-          starts_with?('/') ? self : "/#{ self }"
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3c/3cdf10eb8093cfc847c369901c8cec7bae62db8a.svn-base
--- a/.svn/pristine/3c/3cdf10eb8093cfc847c369901c8cec7bae62db8a.svn-base
+++ /dev/null
@@ -1,125 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class CustomValueTest < ActiveSupport::TestCase
-  fixtures :custom_fields, :custom_values, :users
-
-  def test_string_field_validation_with_blank_value
-    f = CustomField.new(:field_format => 'string')
-    v = CustomValue.new(:custom_field => f)
-
-    v.value = nil
-    assert v.valid?
-    v.value = ''
-    assert v.valid?
-
-    f.is_required = true
-    v.value = nil
-    assert !v.valid?
-    v.value = ''
-    assert !v.valid?
-  end
-
-  def test_string_field_validation_with_min_and_max_lengths
-    f = CustomField.new(:field_format => 'string', :min_length => 2, :max_length => 5)
-    v = CustomValue.new(:custom_field => f, :value => '')
-    assert v.valid?
-    v.value = 'a'
-    assert !v.valid?
-    v.value = 'a' * 2
-    assert v.valid?
-    v.value = 'a' * 6
-    assert !v.valid?
-  end
-
-  def test_string_field_validation_with_regexp
-    f = CustomField.new(:field_format => 'string', :regexp => '^[A-Z0-9]*$')
-    v = CustomValue.new(:custom_field => f, :value => '')
-    assert v.valid?
-    v.value = 'abc'
-    assert !v.valid?
-    v.value = 'ABC'
-    assert v.valid?
-  end
-
-  def test_date_field_validation
-    f = CustomField.new(:field_format => 'date')
-    v = CustomValue.new(:custom_field => f, :value => '')
-    assert v.valid?
-    v.value = 'abc'
-    assert !v.valid?
-    v.value = '1975-07-33'
-    assert !v.valid?
-    v.value = '1975-07-14'
-    assert v.valid?
-  end
-
-  def test_list_field_validation
-    f = CustomField.new(:field_format => 'list', :possible_values => ['value1', 'value2'])
-    v = CustomValue.new(:custom_field => f, :value => '')
-    assert v.valid?
-    v.value = 'abc'
-    assert !v.valid?
-    v.value = 'value2'
-    assert v.valid?
-  end
-
-  def test_int_field_validation
-    f = CustomField.new(:field_format => 'int')
-    v = CustomValue.new(:custom_field => f, :value => '')
-    assert v.valid?
-    v.value = 'abc'
-    assert !v.valid?
-    v.value = '123'
-    assert v.valid?
-    v.value = '+123'
-    assert v.valid?
-    v.value = '-123'
-    assert v.valid?
-  end
-
-  def test_float_field_validation
-    v = CustomValue.new(:customized => User.find(:first), :custom_field => UserCustomField.find_by_name('Money'))
-    v.value = '11.2'
-    assert v.save
-    v.value = ''
-    assert v.save
-    v.value = '-6.250'
-    assert v.save
-    v.value = '6a'
-    assert !v.save
-  end
-
-  def test_default_value
-    field = CustomField.find_by_default_value('Default string')
-    assert_not_nil field
-
-    v = CustomValue.new(:custom_field => field)
-    assert_equal 'Default string', v.value
-
-    v = CustomValue.new(:custom_field => field, :value => 'Not empty')
-    assert_equal 'Not empty', v.value
-  end
-
-  def test_sti_polymorphic_association
-    # Rails uses top level sti class for polymorphic association. See #3978.
-    assert !User.find(4).custom_values.empty?
-    assert !CustomValue.find(2).customized.nil?
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3d/3d264827557eaf8b65d3068714787c51e68d02b2.svn-base
--- /dev/null
+++ b/.svn/pristine/3d/3d264827557eaf8b65d3068714787c51e68d02b2.svn-base
@@ -0,0 +1,22 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class DocumentCategoryCustomField < CustomField
+  def type_name
+    :enumeration_doc_categories
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3d/3d3b405886b53d97a18acfbd6ee1f68a9fd0e1c4.svn-base
--- a/.svn/pristine/3d/3d3b405886b53d97a18acfbd6ee1f68a9fd0e1c4.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-<h2><%=l(:button_change_password)%></h2>
-
-<%= error_messages_for 'user' %>
-
-<% form_tag({}, :class => "tabular") do %>
-<div class="box">
-<p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label>
-<%= password_field_tag 'password', nil, :size => 25 %></p>
-
-<p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label>
-<%= password_field_tag 'new_password', nil, :size => 25 %><br />
-<em><%= l(:text_caracters_minimum, :count => Setting.password_min_length) %></em></p>
-
-<p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
-<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
-</div>
-<%= submit_tag l(:button_apply) %>
-<% end %>
-
-<% content_for :sidebar do %>
-<%= render :partial => 'sidebar' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3d/3d503edadd13a313e0e3661d47e1156ded0be542.svn-base
--- a/.svn/pristine/3d/3d503edadd13a313e0e3661d47e1156ded0be542.svn-base
+++ /dev/null
@@ -1,65 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Watcher < ActiveRecord::Base
-  belongs_to :watchable, :polymorphic => true
-  belongs_to :user
-
-  validates_presence_of :user
-  validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id]
-
-  # Unwatch things that users are no longer allowed to view
-  def self.prune(options={})
-    if options.has_key?(:user)
-      prune_single_user(options[:user], options)
-    else
-      pruned = 0
-      User.find(:all, :conditions => "id IN (SELECT DISTINCT user_id FROM #{table_name})").each do |user|
-        pruned += prune_single_user(user, options)
-      end
-      pruned
-    end
-  end
-
-  protected
-
-  def validate
-    errors.add :user_id, :invalid unless user.nil? || user.active?
-  end
-
-  private
-
-  def self.prune_single_user(user, options={})
-    return unless user.is_a?(User)
-    pruned = 0
-    find(:all, :conditions => {:user_id => user.id}).each do |watcher|
-      next if watcher.watchable.nil?
-
-      if options.has_key?(:project)
-        next unless watcher.watchable.respond_to?(:project) && watcher.watchable.project == options[:project]
-      end
-
-      if watcher.watchable.respond_to?(:visible?)
-        unless watcher.watchable.visible?(user)
-          watcher.destroy
-          pruned += 1
-        end
-      end
-    end
-    pruned
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3d/3d6522340e1723225cb18ddbafc5c9dc0b5f8799.svn-base
--- /dev/null
+++ b/.svn/pristine/3d/3d6522340e1723225cb18ddbafc5c9dc0b5f8799.svn-base
@@ -0,0 +1,48 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueCategory < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  belongs_to :project
+  belongs_to :assigned_to, :class_name => 'Principal', :foreign_key => 'assigned_to_id'
+  has_many :issues, :foreign_key => 'category_id', :dependent => :nullify
+
+  validates_presence_of :name
+  validates_uniqueness_of :name, :scope => [:project_id]
+  validates_length_of :name, :maximum => 30
+
+  safe_attributes 'name', 'assigned_to_id'
+
+  scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
+
+  alias :destroy_without_reassign :destroy
+
+  # Destroy the category
+  # If a category is specified, issues are reassigned to this category
+  def destroy(reassign_to = nil)
+    if reassign_to && reassign_to.is_a?(IssueCategory) && reassign_to.project == self.project
+      Issue.update_all({:category_id => reassign_to.id}, {:category_id => id})
+    end
+    destroy_without_reassign
+  end
+
+  def <=>(category)
+    name <=> category.name
+  end
+
+  def to_s; name end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3d/3d7003238eceffbbaba3bf34003b59ea441ffc00.svn-base
--- /dev/null
+++ b/.svn/pristine/3d/3d7003238eceffbbaba3bf34003b59ea441ffc00.svn-base
@@ -0,0 +1,46 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Activity
+
+    mattr_accessor :available_event_types, :default_event_types, :providers
+
+    @@available_event_types = []
+    @@default_event_types = []
+    @@providers = Hash.new {|h,k| h[k]=[] }
+
+    class << self
+      def map(&block)
+        yield self
+      end
+
+      # Registers an activity provider
+      def register(event_type, options={})
+        options.assert_valid_keys(:class_name, :default)
+
+        event_type = event_type.to_s
+        providers = options[:class_name] || event_type.classify
+        providers = ([] << providers) unless providers.is_a?(Array)
+
+        @@available_event_types << event_type unless @@available_event_types.include?(event_type)
+        @@default_event_types << event_type unless options[:default] == false
+        @@providers[event_type] += providers
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3e/3e17a1388b20cd76503961d40ea60716108de247.svn-base
--- /dev/null
+++ b/.svn/pristine/3e/3e17a1388b20cd76503961d40ea60716108de247.svn-base
@@ -0,0 +1,147 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssueRelationsControllerTest < ActionController::TestCase
+  fixtures :projects,
+           :users,
+           :roles,
+           :members,
+           :member_roles,
+           :issues,
+           :issue_statuses,
+           :issue_relations,
+           :enabled_modules,
+           :enumerations,
+           :trackers,
+           :projects_trackers
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 3
+  end
+
+  def test_create
+    assert_difference 'IssueRelation.count' do
+      post :create, :issue_id => 1,
+                 :relation => {:issue_to_id => '2', :relation_type => 'relates', :delay => ''}
+    end
+    relation = IssueRelation.first(:order => 'id DESC')
+    assert_equal 1, relation.issue_from_id
+    assert_equal 2, relation.issue_to_id
+    assert_equal 'relates', relation.relation_type
+  end
+
+  def test_create_xhr
+    assert_difference 'IssueRelation.count' do
+      xhr :post, :create, :issue_id => 3, :relation => {:issue_to_id => '1', :relation_type => 'relates', :delay => ''}
+      assert_response :success
+      assert_template 'create'
+      assert_equal 'text/javascript', response.content_type
+    end
+    relation = IssueRelation.first(:order => 'id DESC')
+    assert_equal 3, relation.issue_from_id
+    assert_equal 1, relation.issue_to_id
+
+    assert_match /Bug #1/, response.body
+  end
+
+  def test_create_should_accept_id_with_hash
+    assert_difference 'IssueRelation.count' do
+      post :create, :issue_id => 1,
+                 :relation => {:issue_to_id => '#2', :relation_type => 'relates', :delay => ''}
+    end
+    relation = IssueRelation.first(:order => 'id DESC')
+    assert_equal 2, relation.issue_to_id
+  end
+
+  def test_create_should_strip_id
+    assert_difference 'IssueRelation.count' do
+      post :create, :issue_id => 1,
+                 :relation => {:issue_to_id => ' 2  ', :relation_type => 'relates', :delay => ''}
+    end
+    relation = IssueRelation.first(:order => 'id DESC')
+    assert_equal 2, relation.issue_to_id
+  end
+
+  def test_create_should_not_break_with_non_numerical_id
+    assert_no_difference 'IssueRelation.count' do
+      assert_nothing_raised do
+        post :create, :issue_id => 1,
+                   :relation => {:issue_to_id => 'foo', :relation_type => 'relates', :delay => ''}
+      end
+    end
+  end
+
+  def test_create_follows_relation_should_update_relations_list
+    issue1 = Issue.generate!(:subject => 'Followed issue', :start_date => Date.yesterday, :due_date => Date.today)
+    issue2 = Issue.generate!
+
+    assert_difference 'IssueRelation.count' do
+      xhr :post, :create, :issue_id => issue2.id,
+                 :relation => {:issue_to_id => issue1.id, :relation_type => 'follows', :delay => ''}
+    end
+    assert_match /Followed issue/, response.body
+  end
+
+  def test_should_create_relations_with_visible_issues_only
+    Setting.cross_project_issue_relations = '1'
+    assert_nil Issue.visible(User.find(3)).find_by_id(4)
+
+    assert_no_difference 'IssueRelation.count' do
+      post :create, :issue_id => 1,
+                 :relation => {:issue_to_id => '4', :relation_type => 'relates', :delay => ''}
+    end
+  end
+
+  should "prevent relation creation when there's a circular dependency"
+
+  def test_create_xhr_with_failure
+    assert_no_difference 'IssueRelation.count' do
+      xhr :post, :create, :issue_id => 3, :relation => {:issue_to_id => '999', :relation_type => 'relates', :delay => ''}
+
+      assert_response :success
+      assert_template 'create'
+      assert_equal 'text/javascript', response.content_type
+    end
+
+    assert_match /errorExplanation/, response.body
+  end
+
+  def test_destroy
+    assert_difference 'IssueRelation.count', -1 do
+      delete :destroy, :id => '2'
+    end
+  end
+
+  def test_destroy_xhr
+    IssueRelation.create!(:relation_type => IssueRelation::TYPE_RELATES) do |r|
+      r.issue_from_id = 3
+      r.issue_to_id = 1
+    end
+
+    assert_difference 'IssueRelation.count', -1 do
+      xhr :delete, :destroy, :id => '2'
+
+      assert_response :success
+      assert_template 'destroy'
+      assert_equal 'text/javascript', response.content_type
+      assert_match /relation-2/, response.body
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3e/3e2401296aa57bb537864ac16aaa5ce36ba06138.svn-base
--- /dev/null
+++ b/.svn/pristine/3e/3e2401296aa57bb537864ac16aaa5ce36ba06138.svn-base
@@ -0,0 +1,200 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::MembershipsTest < Redmine::ApiTest::Base
+  fixtures :projects, :users, :roles, :members, :member_roles
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "/projects/:project_id/memberships" do
+    context "GET" do
+      context "xml" do
+        should "return memberships" do
+          get '/projects/1/memberships.xml', {}, credentials('jsmith')
+
+          assert_response :success
+          assert_equal 'application/xml', @response.content_type
+          assert_tag :tag => 'memberships',
+            :attributes => {:type => 'array'},
+            :child => {
+              :tag => 'membership',
+              :child => {
+                :tag => 'id',
+                :content => '2',
+                :sibling => {
+                  :tag => 'user',
+                  :attributes => {:id => '3', :name => 'Dave Lopper'},
+                  :sibling => {
+                    :tag => 'roles',
+                    :child => {
+                      :tag => 'role',
+                      :attributes => {:id => '2', :name => 'Developer'}
+                    }
+                  }
+                }
+              }
+            }
+        end
+      end
+
+      context "json" do
+        should "return memberships" do
+          get '/projects/1/memberships.json', {}, credentials('jsmith')
+
+          assert_response :success
+          assert_equal 'application/json', @response.content_type
+          json = ActiveSupport::JSON.decode(response.body)
+          assert_equal({
+            "memberships" =>
+              [{"id"=>1,
+                "project" => {"name"=>"eCookbook", "id"=>1},
+                "roles" => [{"name"=>"Manager", "id"=>1}],
+                "user" => {"name"=>"John Smith", "id"=>2}},
+               {"id"=>2,
+                "project" => {"name"=>"eCookbook", "id"=>1},
+                "roles" => [{"name"=>"Developer", "id"=>2}],
+                "user" => {"name"=>"Dave Lopper", "id"=>3}}],
+           "limit" => 25,
+           "total_count" => 2,
+           "offset" => 0},
+           json)
+        end
+      end
+    end
+
+    context "POST" do
+      context "xml" do
+        should "create membership" do
+          assert_difference 'Member.count' do
+            post '/projects/1/memberships.xml', {:membership => {:user_id => 7, :role_ids => [2,3]}}, credentials('jsmith')
+
+            assert_response :created
+          end
+        end
+
+        should "return errors on failure" do
+          assert_no_difference 'Member.count' do
+            post '/projects/1/memberships.xml', {:membership => {:role_ids => [2,3]}}, credentials('jsmith')
+
+            assert_response :unprocessable_entity
+            assert_equal 'application/xml', @response.content_type
+            assert_tag 'errors', :child => {:tag => 'error', :content => "Principal can't be blank"}
+          end
+        end
+      end
+    end
+  end
+
+  context "/memberships/:id" do
+    context "GET" do
+      context "xml" do
+        should "return the membership" do
+          get '/memberships/2.xml', {}, credentials('jsmith')
+
+          assert_response :success
+          assert_equal 'application/xml', @response.content_type
+          assert_tag :tag => 'membership',
+            :child => {
+              :tag => 'id',
+              :content => '2',
+              :sibling => {
+                :tag => 'user',
+                :attributes => {:id => '3', :name => 'Dave Lopper'},
+                :sibling => {
+                  :tag => 'roles',
+                  :child => {
+                    :tag => 'role',
+                    :attributes => {:id => '2', :name => 'Developer'}
+                  }
+                }
+              }
+            }
+        end
+      end
+
+      context "json" do
+        should "return the membership" do
+          get '/memberships/2.json', {}, credentials('jsmith')
+
+          assert_response :success
+          assert_equal 'application/json', @response.content_type
+          json = ActiveSupport::JSON.decode(response.body)
+          assert_equal(
+            {"membership" => {
+              "id" => 2,
+              "project" => {"name"=>"eCookbook", "id"=>1},
+              "roles" => [{"name"=>"Developer", "id"=>2}],
+              "user" => {"name"=>"Dave Lopper", "id"=>3}}
+            },
+            json)
+        end
+      end
+    end
+
+    context "PUT" do
+      context "xml" do
+        should "update membership" do
+          assert_not_equal [1,2], Member.find(2).role_ids.sort
+          assert_no_difference 'Member.count' do
+            put '/memberships/2.xml', {:membership => {:user_id => 3, :role_ids => [1,2]}}, credentials('jsmith')
+
+            assert_response :ok
+            assert_equal '', @response.body
+          end
+          member = Member.find(2)
+          assert_equal [1,2], member.role_ids.sort
+        end
+
+        should "return errors on failure" do
+          put '/memberships/2.xml', {:membership => {:user_id => 3, :role_ids => [99]}}, credentials('jsmith')
+
+          assert_response :unprocessable_entity
+          assert_equal 'application/xml', @response.content_type
+          assert_tag 'errors', :child => {:tag => 'error', :content => /member_roles is invalid/}
+        end
+      end
+    end
+
+    context "DELETE" do
+      context "xml" do
+        should "destroy membership" do
+          assert_difference 'Member.count', -1 do
+            delete '/memberships/2.xml', {}, credentials('jsmith')
+
+            assert_response :ok
+            assert_equal '', @response.body
+          end
+          assert_nil Member.find_by_id(2)
+        end
+
+        should "respond with 422 on failure" do
+          assert_no_difference 'Member.count' do
+            # A membership with an inherited role can't be deleted
+            Member.find(2).member_roles.first.update_attribute :inherited_from, 99
+            delete '/memberships/2.xml', {}, credentials('jsmith')
+
+            assert_response :unprocessable_entity
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3e/3e2856705bc7c004aa221bf2a7acea9b1ba0b99e.svn-base
--- a/.svn/pristine/3e/3e2856705bc7c004aa221bf2a7acea9b1ba0b99e.svn-base
+++ /dev/null
@@ -1,554 +0,0 @@
-module CollectiveIdea #:nodoc:
-  module Acts #:nodoc:
-    module NestedSet #:nodoc:
-      def self.included(base)
-        base.extend(SingletonMethods)
-      end
-
-      # This acts provides Nested Set functionality. Nested Set is a smart way to implement
-      # an _ordered_ tree, with the added feature that you can select the children and all of their
-      # descendants with a single query. The drawback is that insertion or move need some complex
-      # sql queries. But everything is done here by this module!
-      #
-      # Nested sets are appropriate each time you want either an orderd tree (menus,
-      # commercial categories) or an efficient way of querying big trees (threaded posts).
-      #
-      # == API
-      #
-      # Methods names are aligned with acts_as_tree as much as possible, to make replacment from one
-      # by another easier, except for the creation:
-      #
-      # in acts_as_tree:
-      #   item.children.create(:name => "child1")
-      #
-      # in acts_as_nested_set:
-      #   # adds a new item at the "end" of the tree, i.e. with child.left = max(tree.right)+1
-      #   child = MyClass.new(:name => "child1")
-      #   child.save
-      #   # now move the item to its right place
-      #   child.move_to_child_of my_item
-      #
-      # You can pass an id or an object to:
-      # * <tt>#move_to_child_of</tt>
-      # * <tt>#move_to_right_of</tt>
-      # * <tt>#move_to_left_of</tt>
-      #
-      module SingletonMethods
-        # Configuration options are:
-        #
-        # * +:parent_column+ - specifies the column name to use for keeping the position integer (default: parent_id)
-        # * +:left_column+ - column name for left boundry data, default "lft"
-        # * +:right_column+ - column name for right boundry data, default "rgt"
-        # * +:scope+ - restricts what is to be considered a list. Given a symbol, it'll attach "_id"
-        #   (if it hasn't been already) and use that as the foreign key restriction. You
-        #   can also pass an array to scope by multiple attributes.
-        #   Example: <tt>acts_as_nested_set :scope => [:notable_id, :notable_type]</tt>
-        # * +:dependent+ - behavior for cascading destroy. If set to :destroy, all the
-        #   child objects are destroyed alongside this object by calling their destroy
-        #   method. If set to :delete_all (default), all the child objects are deleted
-        #   without calling their destroy method.
-        #
-        # See CollectiveIdea::Acts::NestedSet::ClassMethods for a list of class methods and
-        # CollectiveIdea::Acts::NestedSet::InstanceMethods for a list of instance methods added 
-        # to acts_as_nested_set models
-        def acts_as_nested_set(options = {})
-          options = {
-            :parent_column => 'parent_id',
-            :left_column => 'lft',
-            :right_column => 'rgt',
-            :order => 'id',
-            :dependent => :delete_all, # or :destroy
-          }.merge(options)
-          
-          if options[:scope].is_a?(Symbol) && options[:scope].to_s !~ /_id$/
-            options[:scope] = "#{options[:scope]}_id".intern
-          end
-
-          write_inheritable_attribute :acts_as_nested_set_options, options
-          class_inheritable_reader :acts_as_nested_set_options
-          
-          include Comparable
-          include Columns
-          include InstanceMethods
-          extend Columns
-          extend ClassMethods
-
-          # no bulk assignment
-          attr_protected  left_column_name.intern,
-                          right_column_name.intern, 
-                          parent_column_name.intern
-                          
-          before_create :set_default_left_and_right
-          before_destroy :prune_from_tree
-                          
-          # no assignment to structure fields
-          [left_column_name, right_column_name, parent_column_name].each do |column|
-            module_eval <<-"end_eval", __FILE__, __LINE__
-              def #{column}=(x)
-                raise ActiveRecord::ActiveRecordError, "Unauthorized assignment to #{column}: it's an internal field handled by acts_as_nested_set code, use move_to_* methods instead."
-              end
-            end_eval
-          end
-          
-          named_scope :roots, :conditions => {parent_column_name => nil}, :order => quoted_left_column_name
-          named_scope :leaves, :conditions => "#{quoted_right_column_name} - #{quoted_left_column_name} = 1", :order => quoted_left_column_name
-          if self.respond_to?(:define_callbacks)
-            define_callbacks("before_move", "after_move")              
-          end
-
-          
-        end
-        
-      end
-      
-      module ClassMethods
-        
-        # Returns the first root
-        def root
-          roots.find(:first)
-        end
-        
-        def valid?
-          left_and_rights_valid? && no_duplicates_for_columns? && all_roots_valid?
-        end
-        
-        def left_and_rights_valid?
-          count(
-            :joins => "LEFT OUTER JOIN #{quoted_table_name} AS parent ON " +
-              "#{quoted_table_name}.#{quoted_parent_column_name} = parent.#{primary_key}",
-            :conditions =>
-              "#{quoted_table_name}.#{quoted_left_column_name} IS NULL OR " +
-              "#{quoted_table_name}.#{quoted_right_column_name} IS NULL OR " +
-              "#{quoted_table_name}.#{quoted_left_column_name} >= " +
-                "#{quoted_table_name}.#{quoted_right_column_name} OR " +
-              "(#{quoted_table_name}.#{quoted_parent_column_name} IS NOT NULL AND " +
-                "(#{quoted_table_name}.#{quoted_left_column_name} <= parent.#{quoted_left_column_name} OR " +
-                "#{quoted_table_name}.#{quoted_right_column_name} >= parent.#{quoted_right_column_name}))"
-          ) == 0
-        end
-        
-        def no_duplicates_for_columns?
-          scope_string = Array(acts_as_nested_set_options[:scope]).map do |c|
-            connection.quote_column_name(c)
-          end.push(nil).join(", ")
-          [quoted_left_column_name, quoted_right_column_name].all? do |column|
-            # No duplicates
-            find(:first, 
-              :select => "#{scope_string}#{column}, COUNT(#{column})", 
-              :group => "#{scope_string}#{column} 
-                HAVING COUNT(#{column}) > 1").nil?
-          end
-        end
-        
-        # Wrapper for each_root_valid? that can deal with scope.
-        def all_roots_valid?
-          if acts_as_nested_set_options[:scope]
-            roots(:group => scope_column_names).group_by{|record| scope_column_names.collect{|col| record.send(col.to_sym)}}.all? do |scope, grouped_roots|
-              each_root_valid?(grouped_roots)
-            end
-          else
-            each_root_valid?(roots)
-          end
-        end
-        
-        def each_root_valid?(roots_to_validate)
-          left = right = 0
-          roots_to_validate.all? do |root|
-            (root.left > left && root.right > right).tap do
-              left = root.left
-              right = root.right
-            end
-          end
-        end
-                
-        # Rebuilds the left & rights if unset or invalid.  Also very useful for converting from acts_as_tree.
-        def rebuild!(force=false)
-          # Don't rebuild a valid tree.
-          # valid? doesn't strictly validate the tree
-          return true if !force && valid?
-          
-          scope = lambda{|node|}
-          if acts_as_nested_set_options[:scope]
-            scope = lambda{|node| 
-              scope_column_names.inject(""){|str, column_name|
-                str << "AND #{connection.quote_column_name(column_name)} = #{connection.quote(node.send(column_name.to_sym))} "
-              }
-            }
-          end
-          indices = {}
-          
-          set_left_and_rights = lambda do |node|
-            # set left
-            node[left_column_name] = indices[scope.call(node)] += 1
-            # find
-            find(:all, :conditions => ["#{quoted_parent_column_name} = ? #{scope.call(node)}", node], :order => "#{quoted_left_column_name}, #{quoted_right_column_name}, #{acts_as_nested_set_options[:order]}").each{|n| set_left_and_rights.call(n) }
-            # set right
-            node[right_column_name] = indices[scope.call(node)] += 1    
-            node.save!    
-          end
-                              
-          # Find root node(s)
-          root_nodes = find(:all, :conditions => "#{quoted_parent_column_name} IS NULL", :order => "#{quoted_left_column_name}, #{quoted_right_column_name}, #{acts_as_nested_set_options[:order]}").each do |root_node|
-            # setup index for this scope
-            indices[scope.call(root_node)] ||= 0
-            set_left_and_rights.call(root_node)
-          end
-        end
-      end
-      
-      # Mixed into both classes and instances to provide easy access to the column names
-      module Columns
-        def left_column_name
-          acts_as_nested_set_options[:left_column]
-        end
-        
-        def right_column_name
-          acts_as_nested_set_options[:right_column]
-        end
-        
-        def parent_column_name
-          acts_as_nested_set_options[:parent_column]
-        end
-        
-        def scope_column_names
-          Array(acts_as_nested_set_options[:scope])
-        end
-        
-        def quoted_left_column_name
-          connection.quote_column_name(left_column_name)
-        end
-        
-        def quoted_right_column_name
-          connection.quote_column_name(right_column_name)
-        end
-        
-        def quoted_parent_column_name
-          connection.quote_column_name(parent_column_name)
-        end
-        
-        def quoted_scope_column_names
-          scope_column_names.collect {|column_name| connection.quote_column_name(column_name) }
-        end
-      end
-
-      # Any instance method that returns a collection makes use of Rails 2.1's named_scope (which is bundled for Rails 2.0), so it can be treated as a finder.
-      #
-      #   category.self_and_descendants.count
-      #   category.ancestors.find(:all, :conditions => "name like '%foo%'")
-      module InstanceMethods
-        # Value of the parent column
-        def parent_id
-          self[parent_column_name]
-        end
-        
-        # Value of the left column
-        def left
-          self[left_column_name]
-        end
-        
-        # Value of the right column
-        def right
-          self[right_column_name]
-        end
-
-        # Returns true if this is a root node.
-        def root?
-          parent_id.nil?
-        end
-        
-        def leaf?
-          new_record? || (right - left == 1)
-        end
-
-        # Returns true is this is a child node
-        def child?
-          !parent_id.nil?
-        end
-
-        # order by left column
-        def <=>(x)
-          left <=> x.left
-        end
-        
-        # Redefine to act like active record
-        def ==(comparison_object)
-          comparison_object.equal?(self) ||
-            (comparison_object.instance_of?(self.class) &&
-              comparison_object.id == id &&
-              !comparison_object.new_record?)
-        end
-
-        # Returns root
-        def root
-          self_and_ancestors.find(:first)
-        end
-
-        # Returns the immediate parent
-        def parent
-          nested_set_scope.find_by_id(parent_id) if parent_id
-        end
-
-        # Returns the array of all parents and self
-        def self_and_ancestors
-          nested_set_scope.scoped :conditions => [
-            "#{self.class.table_name}.#{quoted_left_column_name} <= ? AND #{self.class.table_name}.#{quoted_right_column_name} >= ?", left, right
-          ]
-        end
-
-        # Returns an array of all parents
-        def ancestors
-          without_self self_and_ancestors
-        end
-
-        # Returns the array of all children of the parent, including self
-        def self_and_siblings
-          nested_set_scope.scoped :conditions => {parent_column_name => parent_id}
-        end
-
-        # Returns the array of all children of the parent, except self
-        def siblings
-          without_self self_and_siblings
-        end
-
-        # Returns a set of all of its nested children which do not have children  
-        def leaves
-          descendants.scoped :conditions => "#{self.class.table_name}.#{quoted_right_column_name} - #{self.class.table_name}.#{quoted_left_column_name} = 1"
-        end    
-
-        # Returns the level of this object in the tree
-        # root level is 0
-        def level
-          parent_id.nil? ? 0 : ancestors.count
-        end
-
-        # Returns a set of itself and all of its nested children
-        def self_and_descendants
-          nested_set_scope.scoped :conditions => [
-            "#{self.class.table_name}.#{quoted_left_column_name} >= ? AND #{self.class.table_name}.#{quoted_right_column_name} <= ?", left, right
-          ]
-        end
-
-        # Returns a set of all of its children and nested children
-        def descendants
-          without_self self_and_descendants
-        end
-
-        # Returns a set of only this entry's immediate children
-        def children
-          nested_set_scope.scoped :conditions => {parent_column_name => self}
-        end
-
-        def is_descendant_of?(other)
-          other.left < self.left && self.left < other.right && same_scope?(other)
-        end
-        
-        def is_or_is_descendant_of?(other)
-          other.left <= self.left && self.left < other.right && same_scope?(other)
-        end
-
-        def is_ancestor_of?(other)
-          self.left < other.left && other.left < self.right && same_scope?(other)
-        end
-        
-        def is_or_is_ancestor_of?(other)
-          self.left <= other.left && other.left < self.right && same_scope?(other)
-        end
-        
-        # Check if other model is in the same scope
-        def same_scope?(other)
-          Array(acts_as_nested_set_options[:scope]).all? do |attr|
-            self.send(attr) == other.send(attr)
-          end
-        end
-
-        # Find the first sibling to the left
-        def left_sibling
-          siblings.find(:first, :conditions => ["#{self.class.table_name}.#{quoted_left_column_name} < ?", left],
-            :order => "#{self.class.table_name}.#{quoted_left_column_name} DESC")
-        end
-
-        # Find the first sibling to the right
-        def right_sibling
-          siblings.find(:first, :conditions => ["#{self.class.table_name}.#{quoted_left_column_name} > ?", left])
-        end
-
-        # Shorthand method for finding the left sibling and moving to the left of it.
-        def move_left
-          move_to_left_of left_sibling
-        end
-
-        # Shorthand method for finding the right sibling and moving to the right of it.
-        def move_right
-          move_to_right_of right_sibling
-        end
-
-        # Move the node to the left of another node (you can pass id only)
-        def move_to_left_of(node)
-          move_to node, :left
-        end
-
-        # Move the node to the left of another node (you can pass id only)
-        def move_to_right_of(node)
-          move_to node, :right
-        end
-
-        # Move the node to the child of another node (you can pass id only)
-        def move_to_child_of(node)
-          move_to node, :child
-        end
-        
-        # Move the node to root nodes
-        def move_to_root
-          move_to nil, :root
-        end
-        
-        def move_possible?(target)
-          self != target && # Can't target self
-          same_scope?(target) && # can't be in different scopes
-          # !(left..right).include?(target.left..target.right) # this needs tested more
-          # detect impossible move
-          !((left <= target.left && right >= target.left) or (left <= target.right && right >= target.right))
-        end
-        
-        def to_text
-          self_and_descendants.map do |node|
-            "#{'*'*(node.level+1)} #{node.id} #{node.to_s} (#{node.parent_id}, #{node.left}, #{node.right})"
-          end.join("\n")
-        end
-        
-      protected
-      
-        def without_self(scope)
-          scope.scoped :conditions => ["#{self.class.table_name}.#{self.class.primary_key} != ?", self]
-        end
-        
-        # All nested set queries should use this nested_set_scope, which performs finds on
-        # the base ActiveRecord class, using the :scope declared in the acts_as_nested_set
-        # declaration.
-        def nested_set_scope
-          options = {:order => "#{self.class.table_name}.#{quoted_left_column_name}"}
-          scopes = Array(acts_as_nested_set_options[:scope])
-          options[:conditions] = scopes.inject({}) do |conditions,attr|
-            conditions.merge attr => self[attr]
-          end unless scopes.empty?
-          self.class.base_class.scoped options
-        end
-        
-        # on creation, set automatically lft and rgt to the end of the tree
-        def set_default_left_and_right
-          maxright = nested_set_scope.maximum(right_column_name) || 0
-          # adds the new node to the right of all existing nodes
-          self[left_column_name] = maxright + 1
-          self[right_column_name] = maxright + 2
-        end
-      
-        # Prunes a branch off of the tree, shifting all of the elements on the right
-        # back to the left so the counts still work.
-        def prune_from_tree
-          return if right.nil? || left.nil? || !self.class.exists?(id)
-
-          self.class.base_class.transaction do
-            reload_nested_set
-            if acts_as_nested_set_options[:dependent] == :destroy
-              children.each(&:destroy)
-            else
-              nested_set_scope.send(:delete_all,
-                ["#{quoted_left_column_name} > ? AND #{quoted_right_column_name} < ?",
-                  left, right]
-              )
-            end
-            reload_nested_set
-            diff = right - left + 1
-            nested_set_scope.update_all(
-              ["#{quoted_left_column_name} = (#{quoted_left_column_name} - ?)", diff],
-              ["#{quoted_left_column_name} >= ?", right]
-            )
-            nested_set_scope.update_all(
-              ["#{quoted_right_column_name} = (#{quoted_right_column_name} - ?)", diff],
-              ["#{quoted_right_column_name} >= ?", right]
-            )
-          end
-          
-          # Reload is needed because children may have updated their parent (self) during deletion.
-          reload
-        end
-
-        # reload left, right, and parent
-        def reload_nested_set
-          reload(:select => "#{quoted_left_column_name}, " +
-            "#{quoted_right_column_name}, #{quoted_parent_column_name}")
-        end
-        
-        def move_to(target, position)
-          raise ActiveRecord::ActiveRecordError, "You cannot move a new node" if self.new_record?
-          return if callback(:before_move) == false
-          transaction do
-            if target.is_a? self.class.base_class
-              target.reload_nested_set
-            elsif position != :root
-              # load object if node is not an object
-              target = nested_set_scope.find(target)
-            end
-            self.reload_nested_set
-          
-            unless position == :root || move_possible?(target)
-              raise ActiveRecord::ActiveRecordError, "Impossible move, target node cannot be inside moved tree."
-            end
-            
-            bound = case position
-              when :child;  target[right_column_name]
-              when :left;   target[left_column_name]
-              when :right;  target[right_column_name] + 1
-              when :root;   1
-              else raise ActiveRecord::ActiveRecordError, "Position should be :child, :left, :right or :root ('#{position}' received)."
-            end
-          
-            if bound > self[right_column_name]
-              bound = bound - 1
-              other_bound = self[right_column_name] + 1
-            else
-              other_bound = self[left_column_name] - 1
-            end
-
-            # there would be no change
-            return if bound == self[right_column_name] || bound == self[left_column_name]
-          
-            # we have defined the boundaries of two non-overlapping intervals, 
-            # so sorting puts both the intervals and their boundaries in order
-            a, b, c, d = [self[left_column_name], self[right_column_name], bound, other_bound].sort
-
-            new_parent = case position
-              when :child;  target.id
-              when :root;   nil
-              else          target[parent_column_name]
-            end
-
-            self.class.base_class.update_all([
-              "#{quoted_left_column_name} = CASE " +
-                "WHEN #{quoted_left_column_name} BETWEEN :a AND :b " +
-                  "THEN #{quoted_left_column_name} + :d - :b " +
-                "WHEN #{quoted_left_column_name} BETWEEN :c AND :d " +
-                  "THEN #{quoted_left_column_name} + :a - :c " +
-                "ELSE #{quoted_left_column_name} END, " +
-              "#{quoted_right_column_name} = CASE " +
-                "WHEN #{quoted_right_column_name} BETWEEN :a AND :b " +
-                  "THEN #{quoted_right_column_name} + :d - :b " +
-                "WHEN #{quoted_right_column_name} BETWEEN :c AND :d " +
-                  "THEN #{quoted_right_column_name} + :a - :c " +
-                "ELSE #{quoted_right_column_name} END, " +
-              "#{quoted_parent_column_name} = CASE " +
-                "WHEN #{self.class.base_class.primary_key} = :id THEN :new_parent " +
-                "ELSE #{quoted_parent_column_name} END",
-              {:a => a, :b => b, :c => c, :d => d, :id => self.id, :new_parent => new_parent}
-            ], nested_set_scope.proxy_options[:conditions])
-          end
-          target.reload_nested_set if target
-          self.reload_nested_set
-          callback(:after_move)
-        end
-
-      end
-      
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3e/3e497523d528dce449385801e7d571e2b8c31896.svn-base
--- a/.svn/pristine/3e/3e497523d528dce449385801e7d571e2b8c31896.svn-base
+++ /dev/null
@@ -1,1006 +0,0 @@
-bg:
-  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%d-%m-%Y"
-      short: "%b %d"
-      long: "%B %d, %Y"
-
-    day_names: [ÐÐµÐ´ÐµÐ»Ñ, ÐŸÐ¾Ð½ÐµÐ´ÐµÐ»Ð½Ð¸Ðº, Ð’Ñ‚Ð¾Ñ€Ð½Ð¸Ðº, Ð¡Ñ€ÑÐ´Ð°, Ð§ÐµÑ‚Ð²ÑŠÑ€Ñ‚ÑŠÐº, ÐŸÐµÑ‚ÑŠÐº, Ð¡ÑŠÐ±Ð¾Ñ‚Ð°]
-    abbr_day_names: [ÐÐµÐ´, ÐŸÐ¾Ð½, Ð’Ñ‚Ð¾, Ð¡Ñ€Ñ, Ð§ÐµÑ‚, ÐŸÐµÑ‚, Ð¡ÑŠÐ±]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Ð¯Ð½ÑƒÐ°Ñ€Ð¸, Ð¤ÐµÐ²Ñ€ÑƒÐ°Ñ€Ð¸, ÐœÐ°Ñ€Ñ‚, ÐÐ¿Ñ€Ð¸Ð», ÐœÐ°Ð¹, Ð®Ð½Ð¸, Ð®Ð»Ð¸, ÐÐ²Ð³ÑƒÑÑ‚, Ð¡ÐµÐ¿Ñ‚ÐµÐ¼Ð²Ñ€Ð¸, ÐžÐºÑ‚Ð¾Ð¼Ð²Ñ€Ð¸, ÐÐ¾ÐµÐ¼Ð²Ñ€Ð¸, Ð”ÐµÐºÐµÐ¼Ð²Ñ€Ð¸]
-    abbr_month_names: [~, Ð¯Ð½Ñƒ, Ð¤ÐµÐ², ÐœÐ°Ñ€, ÐÐ¿Ñ€, ÐœÐ°Ð¹, Ð®Ð½Ð¸, Ð®Ð»Ð¸, ÐÐ²Ð³, Ð¡ÐµÐ¿, ÐžÐºÑ‚, ÐÐ¾Ðµ, Ð”ÐµÐº]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%a, %d %b %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "am"
-    pm: "pm"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "half a minute"
-      less_than_x_seconds:
-        one:   "Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚ 1 ÑÐµÐºÑƒÐ½Ð´Ð°"
-        other: "Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚ %{count} ÑÐµÐºÑƒÐ½Ð´Ð¸"
-      x_seconds:
-        one:   "1 ÑÐµÐºÑƒÐ½Ð´Ð°"
-        other: "%{count} ÑÐµÐºÑƒÐ½Ð´Ð¸"
-      less_than_x_minutes:
-        one:   "Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚ 1 Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
-        other: "Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚ %{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð¸"
-      x_minutes:
-        one:   "1 Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
-        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð¸"
-      about_x_hours:
-        one:   "Ð¾ÐºÐ¾Ð»Ð¾ 1 Ñ‡Ð°Ñ"
-        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
-      x_days:
-        one:   "1 Ð´ÐµÐ½"
-        other: "%{count} Ð´ÐµÐ½Ð°"
-      about_x_months:
-        one:   "Ð¾ÐºÐ¾Ð»Ð¾ 1 Ð¼ÐµÑÐµÑ†"
-        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÐµÑ†Ð°"
-      x_months:
-        one:   "1 Ð¼ÐµÑÐµÑ†"
-        other: "%{count} Ð¼ÐµÑÐµÑ†Ð°"
-      about_x_years:
-        one:   "Ð¾ÐºÐ¾Ð»Ð¾ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
-        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
-      over_x_years:
-        one:   "Ð½Ð°Ð´ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
-        other: "Ð½Ð°Ð´ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
-      almost_x_years:
-        one:   "Ð¿Ð¾Ñ‡Ñ‚Ð¸ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
-        other: "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
-
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-
-    human:
-      format:
-        precision: 1
-        delimiter: ""
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: Byte
-            other: Bytes
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "Ð¸"
-      skip_last_comma: false
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 Ð³Ñ€ÐµÑˆÐºÐ° Ð¿Ð¾Ð¿Ñ€ÐµÑ‡Ð¸ Ñ‚Ð¾Ð·Ð¸ %{model} Ð´Ð° Ð±ÑŠÐ´Ðµ Ð·Ð°Ð¿Ð¸ÑÐ°Ð½"
-          other:  "%{count} Ð³Ñ€ÐµÑˆÐºÐ¸ Ð¿Ð¾Ð¿Ñ€ÐµÑ‡Ð¸Ñ…Ð° Ñ‚Ð¾Ð·Ð¸ %{model} Ð´Ð° Ð±ÑŠÐ´Ðµ Ð·Ð°Ð¿Ð¸ÑÐ°Ð½"
-      messages:
-        inclusion: "Ð½Ðµ ÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð° Ð² ÑÐ¿Ð¸ÑÑŠÐºÐ°"
-        exclusion: "Ðµ Ð·Ð°Ð¿Ð°Ð·ÐµÐ½Ð¾"
-        invalid: "Ðµ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð¾"
-        confirmation: "Ð»Ð¸Ð¿ÑÐ²Ð° Ð¾Ð´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ðµ"
-        accepted: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° ÑÐµ Ð¿Ñ€Ð¸ÐµÐ¼Ðµ"
-        empty: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
-        blank: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
-        too_long: "Ðµ Ð¿Ñ€ÐµÐºÐ°Ð»ÐµÐ½Ð¾ Ð´ÑŠÐ»Ð³Ð¾"
-        too_short: "Ðµ Ð¿Ñ€ÐµÐºÐ°Ð»ÐµÐ½Ð¾ ÐºÑŠÑÐ¾"
-        wrong_length: "Ðµ Ñ Ð³Ñ€ÐµÑˆÐ½Ð° Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð°"
-        taken: "Ð²ÐµÑ‡Ðµ ÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð°"
-        not_a_number: "Ð½Ðµ Ðµ Ñ‡Ð¸ÑÐ»Ð¾"
-        not_a_date: "Ðµ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð° Ð´Ð°Ñ‚Ð°"
-        greater_than: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾-Ð³Ð¾Ð»ÑÐ¼[a/Ð¾] Ð¾Ñ‚ %{count}"
-        greater_than_or_equal_to: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾-Ð³Ð¾Ð»ÑÐ¼[a/Ð¾] Ð¾Ñ‚ Ð¸Ð»Ð¸ Ñ€Ð°Ð²ÐµÐ½[a/o] Ð½Ð° %{count}"
-        equal_to: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ñ€Ð°Ð²ÐµÐ½[a/o] Ð½Ð° %{count}"
-        less_than: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾-Ð¼Ð°Ð»ÑŠÐº[a/o] Ð¾Ñ‚ %{count}"
-        less_than_or_equal_to: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾-Ð¼Ð°Ð»ÑŠÐº[a/o] Ð¾Ñ‚ Ð¸Ð»Ð¸ Ñ€Ð°Ð²ÐµÐ½[a/o] Ð½Ð° %{count}"
-        odd: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð½ÐµÑ‡ÐµÑ‚ÐµÐ½[a/o]"
-        even: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ñ‡ÐµÑ‚ÐµÐ½[a/o]"
-        greater_than_start_date: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ðµ ÑÐ»ÐµÐ´ Ð½Ð°Ñ‡Ð°Ð»Ð½Ð°Ñ‚Ð° Ð´Ð°Ñ‚Ð°"
-        not_same_project: "Ð½Ðµ Ðµ Ð¾Ñ‚ ÑÑŠÑ‰Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚"
-        circular_dependency: "Ð¢Ð°Ð·Ð¸ Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ Ñ‰Ðµ Ð´Ð¾Ð²ÐµÐ´Ðµ Ð´Ð¾ Ð±ÐµÐ·ÐºÑ€Ð°Ð¹Ð½Ð° Ð·Ð°Ð²Ð¸ÑÐ¸Ð¼Ð¾ÑÑ‚"
-        cant_link_an_issue_with_a_descendant: "Ð•Ð´Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð° Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ð° ÐºÑŠÐ¼ ÑÐ²Ð¾Ñ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð°"
-
-  actionview_instancetag_blank_option: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ
-
-  general_text_No: 'ÐÐµ'
-  general_text_Yes: 'Ð”Ð°'
-  general_text_no: 'Ð½Ðµ'
-  general_text_yes: 'Ð´Ð°'
-  general_lang_name: 'Bulgarian (Ð‘ÑŠÐ»Ð³Ð°Ñ€ÑÐºÐ¸)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŠÑ‚ Ðµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
-  notice_account_invalid_creditentials: ÐÐµÐ²Ð°Ð»Ð¸Ð´ÐµÐ½ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» Ð¸Ð»Ð¸ Ð¿Ð°Ñ€Ð¾Ð»Ð°.
-  notice_account_password_updated: ÐŸÐ°Ñ€Ð¾Ð»Ð°Ñ‚Ð° Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½Ð°.
-  notice_account_wrong_password: Ð“Ñ€ÐµÑˆÐ½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
-  notice_account_register_done: ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŠÑ‚ Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
-  notice_account_unknown_email: ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ‚ e-mail.
-  notice_can_t_change_password: Ð¢Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ðµ Ñ Ð²ÑŠÐ½ÑˆÐµÐ½ Ð¼ÐµÑ‚Ð¾Ð´ Ð·Ð° Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ. ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð° ÑÐ¼ÑÐ½Ð° Ð½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°Ñ‚Ð°.
-  notice_account_lost_email_sent: Ð˜Ð·Ð¿Ñ€Ð°Ñ‚ÐµÐ½ Ð²Ð¸ Ðµ e-mail Ñ Ð¸Ð½ÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ð¸ Ð·Ð° Ð¸Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð½Ð¾Ð²Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°.
-  notice_account_activated: ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŠÑ‚ Ð²Ð¸ Ðµ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½. Ð’ÐµÑ‡Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð²Ð»ÐµÐ·ÐµÑ‚Ðµ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ð°Ñ‚Ð°.
-  notice_successful_create: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ ÑÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ.
-  notice_successful_update: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð¾Ð±Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ.
-  notice_successful_delete: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ.
-  notice_successful_connection: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ.
-  notice_file_not_found: ÐÐµÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð°Ñ‰Ð° Ð¸Ð»Ð¸ Ð¿Ñ€ÐµÐ¼ÐµÑÑ‚ÐµÐ½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°.
-  notice_locking_conflict: Ð”Ñ€ÑƒÐ³ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ Ñ‚ÐµÐ·Ð¸ Ð´Ð°Ð½Ð½Ð¸ Ð² Ð¼Ð¾Ð¼ÐµÐ½Ñ‚Ð°.
-  notice_not_authorized: ÐÑÐ¼Ð°Ñ‚Ðµ Ð¿Ñ€Ð°Ð²Ð¾ Ð½Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿ Ð´Ð¾ Ñ‚Ð°Ð·Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°.
-  notice_not_authorized_archived_project: ÐŸÑ€Ð¾ÐµÐºÑ‚ÑŠÑ‚, ÐºÐ¾Ð¹Ñ‚Ð¾ ÑÐµ Ð¾Ð¿Ð¸Ñ‚Ð²Ð°Ñ‚Ðµ Ð´Ð° Ð²Ð¸Ð´Ð¸Ñ‚Ðµ Ðµ Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½. ÐÐºÐ¾ ÑÐ¼ÑÑ‚Ð°Ñ‚Ðµ, Ñ‡Ðµ Ñ‚Ð¾Ð²Ð° Ð½Ðµ Ðµ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð½Ð¾, Ð¾Ð±ÑŠÑ€Ð½ÐµÑ‚Ðµ ÑÐµ ÐºÑŠÐ¼ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð° Ð·Ð° Ñ€Ð°Ð·Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ.
-  notice_email_sent: "Ð˜Ð·Ð¿Ñ€Ð°Ñ‚ÐµÐ½ e-mail Ð½Ð° %{value}"
-  notice_email_error: "Ð“Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð¸Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° e-mail (%{value})"
-  notice_feeds_access_key_reseted: Ð’Ð°ÑˆÐ¸Ñ ÐºÐ»ÑŽÑ‡ Ð·Ð° RSS Ð´Ð¾ÑÑ‚ÑŠÐ¿ Ð±ÐµÑˆÐµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½.
-  notice_api_access_key_reseted: Ð’Ð°ÑˆÐ¸ÑÑ‚ API ÐºÐ»ÑŽÑ‡ Ð·Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿ Ð±ÐµÑˆÐµ Ð¸Ð·Ñ‡Ð¸ÑÑ‚ÐµÐ½.
-  notice_failed_to_save_issues: "ÐÐµÑƒÑÐ¿ÐµÑˆÐµÐ½ Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° %{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¾Ñ‚ %{total} Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸: %{ids}."
-  notice_failed_to_save_members: "ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° Ñ‡Ð»ÐµÐ½(Ð¾Ð²Ðµ): %{errors}."
-  notice_no_issue_selected: "ÐÑÐ¼Ð° Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸."
-  notice_account_pending: "ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŠÑ‚ Ð’Ð¸ Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½ Ð¸ Ð¾Ñ‡Ð°ÐºÐ²Ð° Ð¾Ð´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ðµ Ð¾Ñ‚ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€."
-  notice_default_data_loaded: ÐŸÑ€Ð¸Ð¼ÐµÑ€Ð½Ð°Ñ‚Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ðµ Ð·Ð°Ñ€ÐµÐ´ÐµÐ½Ð° ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
-  notice_unable_delete_version: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð²ÐµÑ€ÑÐ¸Ñ
-  notice_unable_delete_time_entry: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° time log.
-  notice_issue_done_ratios_updated: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½ Ð¿Ñ€Ð¾Ñ†ÐµÐ½Ñ‚ Ð½Ð° Ð·Ð°Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸.
-  notice_gantt_chart_truncated: ÐœÑ€ÐµÐ¶Ð¾Ð²Ð¸ÑÑ‚ Ð³Ñ€Ð°Ñ„Ð¸Ðº Ðµ ÑÑŠÐºÑ€Ð°Ñ‚ÐµÐ½, Ð¿Ð¾Ð½ÐµÐ¶Ðµ Ð±Ñ€Ð¾ÑÑ‚ Ð½Ð° Ð¾Ð±ÐµÐºÑ‚Ð¸Ñ‚Ðµ, ÐºÐ¾Ð¸Ñ‚Ð¾ Ð¼Ð¾Ð³Ð°Ñ‚ Ð´Ð° Ð±ÑŠÐ´Ð°Ñ‚ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ð¸ Ðµ Ñ‚Ð²ÑŠÑ€Ð´Ðµ Ð³Ð¾Ð»ÑÐ¼ (%{max})
-  notice_issue_successful_create: Ð—Ð°Ð´Ð°Ñ‡Ð° %{id} Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½Ð°.
-
-  error_can_t_load_default_data: "Ð“Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð·Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð½Ð°Ñ‚Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ: %{value}"
-  error_scm_not_found: ÐÐµÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð°Ñ‰ Ð¾Ð±ÐµÐºÑ‚ Ð² Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÑ‚Ð¾.
-  error_scm_command_failed: "Ð“Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð¾Ð¿Ð¸Ñ‚ Ð·Ð° ÐºÐ¾Ð¼ÑƒÐ½Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ: %{value}"
-  error_scm_annotate: "ÐžÐ±ÐµÐºÑ‚ÑŠÑ‚ Ð½Ðµ ÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð° Ð¸Ð»Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð°Ð½Ð¾Ñ‚Ð¸Ñ€Ð°Ð½."
-  error_scm_annotate_big_text_file: "Ð¤Ð°Ð¹Ð»ÑŠÑ‚ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð°Ð½Ð¾Ñ‚Ð¸Ñ€Ð°Ð½, Ð¿Ð¾Ð½ÐµÐ¶Ðµ Ð½Ð°Ð´Ñ…Ð²ÑŠÑ€Ð»Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ð·Ð° Ñ‚ÐµÐºÑÑ‚Ð¾Ð²Ð¸ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ."
-  error_issue_not_found_in_project: 'Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ð½Ðµ Ðµ Ð½Ð°Ð¼ÐµÑ€ÐµÐ½Ð° Ð¸Ð»Ð¸ Ð½Ðµ Ð¿Ñ€Ð¸Ð½Ð°Ð´Ð»ÐµÐ¶Ð¸ Ð½Ð° Ñ‚Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚'
-  error_no_tracker_in_project: ÐÑÐ¼Ð° Ð°ÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð°Ð½Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€Ð¸ Ñ Ñ‚Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚. ÐŸÑ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸Ñ‚Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°.
-  error_no_default_issue_status: ÐÑÐ¼Ð° ÑƒÑÑ‚Ð°Ð½Ð¾Ð²ÐµÐ½Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ñ‰Ð¾ ÑÐµ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ Ð·Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ. ÐœÐ¾Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ Ð²Ð°ÑˆÐ°Ñ‚Ð° ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ (Ð’Ð¸Ð¶Ñ‚Ðµ "ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ -> Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ñ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸").
-  error_can_not_delete_custom_field: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¾ Ð¿Ð¾Ð»Ðµ
-  error_can_not_delete_tracker: Ð¢Ð¾Ð·Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€ ÑÑŠÐ´ÑŠÑ€Ð¶Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚.
-  error_can_not_remove_role: Ð¢Ð°Ð·Ð¸ Ñ€Ð¾Ð»Ñ ÑÐµ Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚Ð°.
-  error_can_not_reopen_issue_on_closed_version: Ð—Ð°Ð´Ð°Ñ‡Ð°, Ð°ÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð°Ð½Ð° ÑÑŠÑ Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° Ð²ÐµÑ€ÑÐ¸Ñ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° Ð¾Ñ‚Ð½Ð¾Ð²Ð¾
-  error_can_not_archive_project: Ð¢Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½
-  error_issue_done_ratios_not_updated: ÐŸÑ€Ð¾Ñ†ÐµÐ½Ñ‚ÑŠÑ‚ Ð½Ð° Ð·Ð°Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð½Ðµ Ðµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½.
-  error_workflow_copy_source: ÐœÐ¾Ð»Ñ Ð¸Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ source Ñ‚Ñ€Ð°ÐºÐµÑ€ Ð¸Ð»Ð¸ Ñ€Ð¾Ð»Ñ
-  error_workflow_copy_target: ÐœÐ¾Ð»Ñ Ð¸Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ñ‚Ñ€Ð°ÐºÐµÑ€(Ð¸) Ð¸ Ñ€Ð¾Ð»Ñ (Ñ€Ð¾Ð»Ð¸).
-  error_unable_delete_issue_status: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  error_unable_to_connect: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ Ñ (%{value})
-  error_attachment_too_big: Ð¢Ð¾Ð·Ð¸ Ñ„Ð°Ð¹Ð» Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ ÐºÐ°Ñ‡ÐµÐ½, Ð¿Ð¾Ð½ÐµÐ¶Ðµ Ð½Ð°Ð´Ñ…Ð²ÑŠÑ€Ð»Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð°Ñ‚Ð° Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð° Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð° (%{max_size})
-  warning_attachments_not_saved: "%{count} Ñ„Ð°Ð¹Ð»Ð° Ð½Ðµ Ð±ÑÑ…Ð° Ð·Ð°Ð¿Ð¸ÑÐ°Ð½Ð¸."
-
-  mail_subject_lost_password: "Ð’Ð°ÑˆÐ°Ñ‚Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð° (%{value})"
-  mail_body_lost_password: 'Ð—Ð° Ð´Ð° ÑÐ¼ÐµÐ½Ð¸Ñ‚Ðµ Ð¿Ð°Ñ€Ð¾Ð»Ð°Ñ‚Ð° ÑÐ¸, Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð¹Ñ‚Ðµ ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð»Ð¸Ð½Ðº:'
-  mail_subject_register: "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð» (%{value})"
-  mail_body_register: 'Ð—Ð° Ð´Ð° Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ñ‚Ðµ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð° ÑÐ¸ Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð¹Ñ‚Ðµ ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð»Ð¸Ð½Ðº:'
-  mail_body_account_information_external: "ÐœÐ¾Ð¶ÐµÑ‚Ðµ Ð´Ð° Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ñ‚Ðµ Ð²Ð°ÑˆÐ¸Ñ %{value} Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ð·Ð° Ð²Ñ…Ð¾Ð´."
-  mail_body_account_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÑÑ‚Ð° Ð·Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð° Ð²Ð¸
-  mail_subject_account_activation_request: "Ð—Ð°ÑÐ²ÐºÐ° Ð·Ð° Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ð² %{value}"
-  mail_body_account_activation_request: "Ð˜Ð¼Ð° Ð½Ð¾Ð²Ð¾Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» (%{value}), Ð¾Ñ‡Ð°ÐºÐ²Ð°Ñ‰ Ð²Ð°ÑˆÐµÑ‚Ð¾ Ð¾Ð´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ðµ:"
-  mail_subject_reminder: "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ñ ÐºÑ€Ð°ÐµÐ½ ÑÑ€Ð¾Ðº Ñ ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ‚Ðµ %{days} Ð´Ð½Ð¸"
-  mail_body_reminder: "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸, Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð²Ð°Ñ ÑÐ° Ñ ÐºÑ€Ð°ÐµÐ½ ÑÑ€Ð¾Ðº Ð² ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ‚Ðµ %{days} Ð´Ð½Ð¸:"
-  mail_subject_wiki_content_added: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð°"
-  mail_body_wiki_content_added: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð° Ð¾Ñ‚ %{author}.
-  mail_subject_wiki_content_updated: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð°"
-  mail_body_wiki_content_updated: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð° Ð¾Ñ‚ %{author}.
-
-  gui_validation_error: 1 Ð³Ñ€ÐµÑˆÐºÐ°
-  gui_validation_error_plural: "%{count} Ð³Ñ€ÐµÑˆÐºÐ¸"
-
-  field_name: Ð˜Ð¼Ðµ
-  field_description: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ
-  field_summary: ÐÐ½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ
-  field_is_required: Ð—Ð°Ð´ÑŠÐ»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾
-  field_firstname: Ð˜Ð¼Ðµ
-  field_lastname: Ð¤Ð°Ð¼Ð¸Ð»Ð¸Ñ
-  field_mail: Email
-  field_filename: Ð¤Ð°Ð¹Ð»
-  field_filesize: Ð“Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð°
-  field_downloads: Ð˜Ð·Ñ‚ÐµÐ³Ð»ÐµÐ½Ð¸ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
-  field_author: ÐÐ²Ñ‚Ð¾Ñ€
-  field_created_on: ÐžÑ‚ Ð´Ð°Ñ‚Ð°
-  field_updated_on: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð°
-  field_field_format: Ð¢Ð¸Ð¿
-  field_is_for_all: Ð—Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  field_possible_values: Ð’ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¸ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚Ð¸
-  field_regexp: Ð ÐµÐ³ÑƒÐ»ÑÑ€ÐµÐ½ Ð¸Ð·Ñ€Ð°Ð·
-  field_min_length: ÐœÐ¸Ð½. Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð°
-  field_max_length: ÐœÐ°ÐºÑ. Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð°
-  field_value: Ð¡Ñ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚
-  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
-  field_title: Ð—Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ
-  field_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
-  field_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
-  field_status: Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
-  field_notes: Ð‘ÐµÐ»ÐµÐ¶ÐºÐ°
-  field_is_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  field_is_default: Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
-  field_tracker: Ð¢Ñ€Ð°ÐºÐµÑ€
-  field_subject: ÐžÑ‚Ð½Ð¾ÑÐ½Ð¾
-  field_due_date: ÐšÑ€Ð°Ð¹Ð½Ð° Ð´Ð°Ñ‚Ð°
-  field_assigned_to: Ð’ÑŠÐ·Ð»Ð¾Ð¶ÐµÐ½Ð° Ð½Ð°
-  field_priority: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
-  field_fixed_version: ÐŸÐ»Ð°Ð½ÑƒÐ²Ð°Ð½Ð° Ð²ÐµÑ€ÑÐ¸Ñ
-  field_user: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
-  field_principal: Principal
-  field_role: Ð Ð¾Ð»Ñ
-  field_homepage: ÐÐ°Ñ‡Ð°Ð»Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  field_is_public: ÐŸÑƒÐ±Ð»Ð¸Ñ‡ÐµÐ½
-  field_parent: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð½Ð°
-  field_is_in_roadmap: Ð”Ð° ÑÐµ Ð²Ð¸Ð¶Ð´Ð° Ð»Ð¸ Ð² ÐŸÑŠÑ‚Ð½Ð° ÐºÐ°Ñ€Ñ‚Ð°
-  field_login: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
-  field_mail_notification: Ð˜Ð·Ð²ÐµÑÑ‚Ð¸Ñ Ð¿Ð¾ Ð¿Ð¾Ñ‰Ð°Ñ‚Ð°
-  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
-  field_last_login_on: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¾ ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ
-  field_language: Ð•Ð·Ð¸Ðº
-  field_effective_date: Ð”Ð°Ñ‚Ð°
-  field_password: ÐŸÐ°Ñ€Ð¾Ð»Ð°
-  field_new_password: ÐÐ¾Ð²Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
-  field_password_confirmation: ÐŸÐ¾Ñ‚Ð²ÑŠÑ€Ð¶Ð´ÐµÐ½Ð¸Ðµ
-  field_version: Ð’ÐµÑ€ÑÐ¸Ñ
-  field_type: Ð¢Ð¸Ð¿
-  field_host: Ð¥Ð¾ÑÑ‚
-  field_port: ÐŸÐ¾Ñ€Ñ‚
-  field_account: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
-  field_base_dn: Base DN
-  field_attr_login: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Login
-  field_attr_firstname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ ÐŸÑŠÑ€Ð²Ð¾ Ð¸Ð¼Ðµ (Firstname)
-  field_attr_lastname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð¤Ð°Ð¼Ð¸Ð»Ð¸Ñ (Lastname)
-  field_attr_mail: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Email
-  field_onthefly: Ð”Ð¸Ð½Ð°Ð¼Ð¸Ñ‡Ð½Ð¾ ÑÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
-  field_start_date: ÐÐ°Ñ‡Ð°Ð»Ð½Ð° Ð´Ð°Ñ‚Ð°
-  field_done_ratio: "% ÐŸÑ€Ð¾Ð³Ñ€ÐµÑ"
-  field_auth_source: ÐÐ°Ñ‡Ð¸Ð½ Ð½Ð° Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
-  field_hide_mail: Ð¡ÐºÑ€Ð¸Ð¹ e-mail Ð°Ð´Ñ€ÐµÑÐ° Ð¼Ð¸
-  field_comments: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  field_url: ÐÐ´Ñ€ÐµÑ
-  field_start_page: ÐÐ°Ñ‡Ð°Ð»Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  field_subproject: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  field_hours: Ð§Ð°ÑÐ¾Ð²Ðµ
-  field_activity: Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚
-  field_spent_on: Ð”Ð°Ñ‚Ð°
-  field_identifier: Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€
-  field_is_filter: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° ÑÐµ Ð·Ð° Ñ„Ð¸Ð»Ñ‚ÑŠÑ€
-  field_issue_to: Ð¡Ð²ÑŠÑ€Ð·Ð°Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  field_delay: ÐžÑ‚Ð¼ÐµÑÑ‚Ð²Ð°Ð½Ðµ
-  field_assignable: Ð’ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ Ðµ Ð²ÑŠÐ·Ð»Ð°Ð³Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð·Ð° Ñ‚Ð°Ð·Ð¸ Ñ€Ð¾Ð»Ñ
-  field_redirect_existing_links: ÐŸÑ€ÐµÐ½Ð°ÑÐ¾Ñ‡Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð°Ñ‰Ð¸ Ð»Ð¸Ð½ÐºÐ¾Ð²Ðµ
-  field_estimated_hours: Ð˜Ð·Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  field_column_names: ÐšÐ¾Ð»Ð¾Ð½Ð¸
-  field_time_entries: Log time
-  field_time_zone: Ð§Ð°ÑÐ¾Ð²Ð° Ð·Ð¾Ð½Ð°
-  field_searchable: Ð¡ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ñ‚ÑŠÑ€ÑÐµÐ½Ðµ
-  field_default_value: Ð¡Ñ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
-  field_comments_sorting: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ‚Ðµ
-  field_parent_title: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  field_editable: Editable
-  field_watcher: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»
-  field_identity_url: OpenID URL
-  field_content: Ð¡ÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ
-  field_group_by: Ð“Ñ€ÑƒÐ¿Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ñ€ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸Ñ‚Ðµ Ð¿Ð¾
-  field_sharing: Sharing
-  field_parent_issue: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  field_member_of_group: Ð§Ð»ÐµÐ½ Ð½Ð° Ð³Ñ€ÑƒÐ¿Ð°
-  field_assigned_to_role: Assignee's role
-  field_text: Ð¢ÐµÐºÑÑ‚Ð¾Ð²Ð¾ Ð¿Ð¾Ð»Ðµ
-  field_visible: Ð’Ð¸Ð´Ð¸Ð¼
-  field_warn_on_leaving_unsaved: ÐŸÑ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ´Ð¸ Ð¼Ðµ, ÐºÐ¾Ð³Ð°Ñ‚Ð¾ Ð½Ð°Ð¿ÑƒÑÐºÐ°Ð¼ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ñ Ð½ÐµÐ·Ð°Ð¿Ð¸ÑÐ°Ð½Ð¾ ÑÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ
-  field_issues_visibility: Ð’Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
-  field_is_private: Ð›Ð¸Ñ‡Ð½Ð°
-  field_commit_logs_encoding: ÐšÐ¾Ð´Ð¾Ð²Ð° Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸ÑÑ‚Ð° Ð¿Ñ€Ð¸ Ð¿Ð¾Ð²ÐµÑ€ÑÐ²Ð°Ð½Ðµ
-  field_scm_path_encoding: ÐšÐ¾Ð´Ð¾Ð²Ð° Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ð½Ð° Ð¿ÑŠÑ‚Ð¸Ñ‰Ð°Ñ‚Ð° (path)
-  field_path_to_repository: ÐŸÑŠÑ‚ Ð´Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÑ‚Ð¾
-  field_root_directory: ÐšÐ¾Ñ€ÐµÐ½Ð½Ð° Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ (Ð¿Ð°Ð¿ÐºÐ°)
-  field_cvsroot: CVSROOT
-  field_cvs_module: ÐœÐ¾Ð´ÑƒÐ»
-
-  setting_app_title: Ð—Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ
-  setting_app_subtitle: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ
-  setting_welcome_text: Ð”Ð¾Ð¿ÑŠÐ»Ð½Ð¸Ñ‚ÐµÐ»ÐµÐ½ Ñ‚ÐµÐºÑÑ‚
-  setting_default_language: Ð•Ð·Ð¸Ðº Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
-  setting_login_required: Ð˜Ð·Ð¸ÑÐºÐ²Ð°Ð½Ðµ Ð·Ð° Ð²Ñ…Ð¾Ð´ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ð°Ñ‚Ð°
-  setting_self_registration: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸
-  setting_attachment_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð° Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½ Ñ„Ð°Ð¹Ð»
-  setting_issues_export_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð·Ð° ÐµÐºÑÐ¿Ð¾Ñ€Ñ‚
-  setting_mail_from: E-mail Ð°Ð´Ñ€ÐµÑ Ð·Ð° ÐµÐ¼Ð¸ÑÐ¸Ð¸
-  setting_bcc_recipients: ÐŸÐ¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ð¸ Ð½Ð° ÑÐºÑ€Ð¸Ñ‚Ð¾ ÐºÐ¾Ð¿Ð¸Ðµ (bcc)
-  setting_plain_text_mail: ÑÐ°Ð¼Ð¾ Ñ‡Ð¸ÑÑ‚ Ñ‚ÐµÐºÑÑ‚ (Ð±ÐµÐ· HTML)
-  setting_host_name: Ð¥Ð¾ÑÑ‚
-  setting_text_formatting: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ñ‚ÐµÐºÑÑ‚Ð°
-  setting_wiki_compression: ÐšÐ¾Ð¼Ð¿Ñ€ÐµÑÐ¸Ñ€Ð°Ð½Ðµ Ð½Ð° Wiki Ð¸ÑÑ‚Ð¾Ñ€Ð¸ÑÑ‚Ð°
-  setting_feeds_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð² ATOM ÐµÐ¼Ð¸ÑÐ¸Ð¸
-  setting_default_projects_public: ÐÐ¾Ð²Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸ ÑÐ° Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
-  setting_autofetch_changesets: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾ Ð¸Ð·Ð²Ð»Ð¸Ñ‡Ð°Ð½Ðµ Ð½Ð° Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸Ñ‚Ðµ
-  setting_sys_api_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° WS Ð·Ð° ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ
-  setting_commit_ref_keywords: ÐžÑ‚Ð±ÐµÐ»ÑÐ·Ð²Ð°Ñ‰Ð¸ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¸ Ð´ÑƒÐ¼Ð¸
-  setting_commit_fix_keywords: ÐŸÑ€Ð¸ÐºÐ»ÑŽÑ‡Ð²Ð°Ñ‰Ð¸ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¸ Ð´ÑƒÐ¼Ð¸
-  setting_autologin: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÐ½ Ð²Ñ…Ð¾Ð´
-  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð½Ð° Ð´Ð°Ñ‚Ð°Ñ‚Ð°
-  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð½Ð° Ñ‡Ð°ÑÐ°
-  setting_cross_project_issue_relations: Ð ÐµÐ»Ð°Ñ†Ð¸Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¼ÐµÐ¶Ð´Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  setting_issue_list_default_columns: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ð¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
-  setting_repositories_encodings: ÐšÐ¾Ð´Ð¾Ð²Ð° Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½Ð¸Ñ‚Ðµ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°Ñ‚Ð°
-  setting_emails_header: Emails header
-  setting_emails_footer: ÐŸÐ¾Ð´Ñ‚ÐµÐºÑÑ‚ Ð·Ð° e-mail
-  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
-  setting_per_page_options: ÐžÐ¿Ñ†Ð¸Ð¸ Ð·Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ€Ð°Ð½Ðµ
-  setting_user_format: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚
-  setting_activity_days_default: Ð‘Ñ€Ð¾Ð¹ Ð´Ð½Ð¸ Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ð½Ð¸ Ð½Ð° Ñ‚Ð°Ð± Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚
-  setting_display_subprojects_issues: Ð—Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ Ð¾Ñ‚ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ ÑÐµ Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ñ‚ Ð² Ð³Ð»Ð°Ð²Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  setting_enabled_scm: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð° SCM
-  setting_mail_handler_body_delimiters: ÐžÑ‚Ñ€ÑÐ·Ð²Ð°Ð½Ðµ Ð½Ð° e-mail-Ð¸Ñ‚Ðµ ÑÐ»ÐµÐ´ ÐµÐ´Ð¸Ð½ Ð¾Ñ‚ Ñ‚ÐµÐ·Ð¸ Ñ€ÐµÐ´Ð¾Ð²Ðµ
-  setting_mail_handler_api_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° WS Ð·Ð° Ð²Ñ…Ð¾Ð´ÑÑ‰Ð¸ e-mail-Ð¸
-  setting_mail_handler_api_key: API ÐºÐ»ÑŽÑ‡
-  setting_sequential_project_identifiers: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»Ð½Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ð¸ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¸
-  setting_gravatar_enabled: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ñ€Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ Ð¸ÐºÐ¾Ð½Ð¸ Ð¾Ñ‚ Gravatar
-  setting_gravatar_default: ÐŸÐ¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ñ‰Ð¾ ÑÐµ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ Ð¾Ñ‚ Gravatar
-  setting_diff_max_lines_displayed: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ð½Ð¸ diff Ñ€ÐµÐ´Ð¾Ð²Ðµ
-  setting_file_max_size_displayed: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ð½Ð° Ñ‚ÐµÐºÑÑ‚Ð¾Ð²Ð¸Ñ‚Ðµ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ, Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ð½Ð¸ inline
-  setting_repository_log_display_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð½Ð° Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ð½ÐµÑ‚Ðµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸ Ð² Ð»Ð¾Ð³ Ñ„Ð°Ð¹Ð»Ð°
-  setting_openid: Ð Ð°Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° OpenID Ð²Ñ…Ð¾Ð´ Ð¸ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
-  setting_password_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð° Ð½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
-  setting_new_project_user_role_id: Ð Ð¾Ð»Ñ, Ð´Ð°Ð²Ð°Ð½Ð° Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ», ÑÑŠÐ·Ð´Ð°Ð²Ð°Ñ‰ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸, ÐºÐ¾Ð¹Ñ‚Ð¾ Ð½Ðµ Ðµ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
-  setting_default_projects_modules: ÐÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ð¸ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ Ð·Ð° Ð½Ð¾Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  setting_issue_done_ratio: Ð˜Ð·Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð¿Ñ€Ð¾Ñ†ÐµÐ½Ñ‚Ð° Ð½Ð° Ð³Ð¾Ñ‚Ð¾Ð²Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ñ
-  setting_issue_done_ratio_issue_field: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ð»Ðµ '% ÐŸÑ€Ð¾Ð³Ñ€ÐµÑ'
-  setting_issue_done_ratio_issue_status: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸ÐµÑ‚Ð¾ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
-  setting_start_of_week: ÐŸÑŠÑ€Ð²Ð¸ Ð´ÐµÐ½ Ð½Ð° ÑÐµÐ´Ð¼Ð¸Ñ†Ð°Ñ‚Ð°
-  setting_rest_api_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° REST web ÑÑŠÑ€Ð²Ð¸Ñ
-  setting_cache_formatted_text: ÐšÐµÑˆÐ¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ñ‚ÐµÐºÑÑ‚Ð¾Ð²Ðµ
-  setting_default_notification_option: ÐŸÐ¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ñ‰ ÑÐµ Ð½Ð°Ñ‡Ð¸Ð½ Ð·Ð° Ð¸Ð·Ð²ÐµÑÑ‚ÑÐ²Ð°Ð½Ðµ
-  setting_commit_logtime_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¾Ñ‚Ñ‡Ð¸Ñ‚Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  setting_commit_logtime_activity_id: Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚ Ð¿Ñ€Ð¸ Ð¾Ñ‚Ñ‡Ð¸Ñ‚Ð°Ð½Ðµ Ð½Ð° Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  setting_gantt_items_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð¾Ð±ÐµÐºÑ‚Ð¸, ÐºÐ¾Ð¸Ñ‚Ð¾ Ð´Ð° ÑÐµ Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ñ‚ Ð² Ð¼Ñ€ÐµÐ¶Ð¾Ð² Ð³Ñ€Ð°Ñ„Ð¸Ðº
-  setting_issue_group_assignment: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¾ Ð½Ð°Ð·Ð½Ð°Ñ‡Ð°Ð²Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð½Ð° Ð³Ñ€ÑƒÐ¿Ð¸
-  setting_default_issue_start_date_to_creation_date: ÐÐ°Ñ‡Ð°Ð»Ð½Ð° Ð´Ð°Ñ‚Ð° Ð½Ð° Ð½Ð¾Ð²Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð´Ð½ÐµÑˆÐ½Ð°Ñ‚Ð° Ð´Ð°Ñ‚Ð°
-
-  permission_add_project: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  permission_add_subprojects: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  permission_edit_project: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  permission_select_project_modules: Ð˜Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ð¸ Ð¼Ð¾Ð´ÑƒÐ»Ð¸
-  permission_manage_members: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ñ‡Ð»ÐµÐ½Ð¾Ð²ÐµÑ‚Ðµ (Ð½Ð° ÐµÐºÐ¸Ð¿)
-  permission_manage_project_activities: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð´ÐµÐ¹Ð½Ð¾ÑÑ‚Ð¸Ñ‚Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
-  permission_manage_versions: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð²ÐµÑ€ÑÐ¸Ð¸Ñ‚Ðµ
-  permission_manage_categories: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸Ñ‚Ðµ
-  permission_view_issues: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
-  permission_add_issues: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_edit_issues: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_manage_issue_relations: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð²Ñ€ÑŠÐ·ÐºÐ¸Ñ‚Ðµ Ð¼ÐµÐ¶Ð´Ñƒ Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
-  permission_set_own_issues_private: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸ Ð¸Ð»Ð¸ Ð»Ð¸Ñ‡Ð½Ð¸
-  permission_set_issues_private: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸ Ð¸Ð»Ð¸ Ð»Ð¸Ñ‡Ð½Ð¸
-  permission_add_issue_notes: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸
-  permission_edit_issue_notes: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸
-  permission_edit_own_issue_notes: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸ Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸
-  permission_move_issues: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_delete_issues: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_manage_public_queries: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸Ñ‚Ðµ Ð·Ð°ÑÐ²ÐºÐ¸
-  permission_save_queries: Ð—Ð°Ð¿Ð¸Ñ Ð½Ð° Ð·Ð°Ð¿Ð¸Ñ‚Ð²Ð°Ð½Ð¸Ñ (queries)
-  permission_view_gantt: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¼Ñ€ÐµÐ¶Ð¾Ð² Ð³Ñ€Ð°Ñ„Ð¸Ðº
-  permission_view_calendar: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ð¸
-  permission_view_issue_watchers: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° ÑÐ¿Ð¸ÑÑŠÐº Ñ Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
-  permission_add_issue_watchers: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
-  permission_delete_issue_watchers: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
-  permission_log_time: Log spent time
-  permission_view_time_entries: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¸Ð·Ñ€Ð°Ð·Ñ…Ð¾Ð´Ð²Ð°Ð½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  permission_edit_time_entries: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° time logs
-  permission_edit_own_time_entries: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸Ñ‚Ðµ time logs
-  permission_manage_news: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð½Ð¾Ð²Ð¸Ð½Ð¸
-  permission_comment_news: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð½Ð¾Ð²Ð¸Ð½Ð¸
-  permission_manage_documents: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  permission_view_documents: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  permission_manage_files: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
-  permission_view_files: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
-  permission_manage_wiki: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° wiki
-  permission_rename_wiki_pages: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ðµ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_delete_wiki_pages: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_view_wiki_pages: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° wiki
-  permission_view_wiki_edits: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° wiki Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ
-  permission_edit_wiki_pages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_delete_wiki_pages_attachments: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½Ð¸ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ ÐºÑŠÐ¼ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_protect_wiki_pages: Ð—Ð°ÐºÐ»ÑŽÑ‡Ð²Ð°Ð½Ðµ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_manage_repository: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
-  permission_browse_repository: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
-  permission_view_changesets: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° changesets
-  permission_commit_access: ÐŸÐ¾Ð²ÐµÑ€ÑÐ²Ð°Ð½Ðµ
-  permission_manage_boards: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° boards
-  permission_view_messages: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
-  permission_add_messages: ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
-  permission_edit_messages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
-  permission_edit_own_messages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸ ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
-  permission_delete_messages: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
-  permission_delete_own_messages: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸ ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
-  permission_export_wiki_pages: Ð•ÐºÑÐ¿Ð¾Ñ€Ñ‚ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_manage_subtasks: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
-
-  project_module_issue_tracking: Ð¢Ñ€Ð°ÐºÐ¸Ð½Ð³
-  project_module_time_tracking: ÐžÑ‚Ð´ÐµÐ»ÑÐ½Ðµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
-  project_module_news: ÐÐ¾Ð²Ð¸Ð½Ð¸
-  project_module_documents: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  project_module_files: Ð¤Ð°Ð¹Ð»Ð¾Ð²Ðµ
-  project_module_wiki: Wiki
-  project_module_repository: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
-  project_module_boards: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
-  project_module_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
-  project_module_gantt: ÐœÑ€ÐµÐ¶Ð¾Ð² Ð³Ñ€Ð°Ñ„Ð¸Ðº
-
-  label_user: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
-  label_user_plural: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸
-  label_user_new: ÐÐ¾Ð² Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
-  label_user_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼ÐµÐ½
-  label_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
-  label_project_new: ÐÐ¾Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  label_project_plural: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸
-  label_x_projects:
-    zero:  0 Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
-    one:   1 Ð¿Ñ€Ð¾ÐµÐºÑ‚
-    other: "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°"
-  label_project_all: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_project_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_new: ÐÐ¾Ð²Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_plural: Ð—Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_view_all: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issues_by: "Ð—Ð°Ð´Ð°Ñ‡Ð¸ Ð¿Ð¾ %{value}"
-  label_issue_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_updated: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_note_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð° Ð±ÐµÐ»ÐµÐ¶ÐºÐ°
-  label_issue_status_updated: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð¾ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
-  label_issue_priority_updated: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
-  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_new: ÐÐ¾Ð² Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  label_document_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_role: Ð Ð¾Ð»Ñ
-  label_role_plural: Ð Ð¾Ð»Ð¸
-  label_role_new: ÐÐ¾Ð²Ð° Ñ€Ð¾Ð»Ñ
-  label_role_and_permissions: Ð Ð¾Ð»Ð¸ Ð¸ Ð¿Ñ€Ð°Ð²Ð°
-  label_role_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼ÐµÐ½
-  label_role_non_member: ÐÐµ Ñ‡Ð»ÐµÐ½
-  label_member: Ð§Ð»ÐµÐ½
-  label_member_new: ÐÐ¾Ð² Ñ‡Ð»ÐµÐ½
-  label_member_plural: Ð§Ð»ÐµÐ½Ð¾Ð²Ðµ
-  label_tracker: Ð¢Ñ€Ð°ÐºÐµÑ€
-  label_tracker_plural: Ð¢Ñ€Ð°ÐºÐµÑ€Ð¸
-  label_tracker_new: ÐÐ¾Ð² Ñ‚Ñ€Ð°ÐºÐµÑ€
-  label_workflow: Ð Ð°Ð±Ð¾Ñ‚ÐµÐ½ Ð¿Ñ€Ð¾Ñ†ÐµÑ
-  label_issue_status: Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_status_plural: Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ñ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_status_new: ÐÐ¾Ð²Ð¾ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
-  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_category_new: ÐÐ¾Ð²Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
-  label_custom_field: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¾ Ð¿Ð¾Ð»Ðµ
-  label_custom_field_plural: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ Ð¿Ð¾Ð»ÐµÑ‚Ð°
-  label_custom_field_new: ÐÐ¾Ð²Ð¾ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¾ Ð¿Ð¾Ð»Ðµ
-  label_enumerations: Ð¡Ð¿Ð¸ÑÑŠÑ†Ð¸
-  label_enumeration_new: ÐÐ¾Ð²Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚
-  label_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
-  label_information_plural: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
-  label_please_login: Ð’Ñ…Ð¾Ð´
-  label_register: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
-  label_login_with_open_id_option: Ð¸Ð»Ð¸ Ð²Ñ…Ð¾Ð´ Ñ‡Ñ€ÐµÐ· OpenID
-  label_password_lost: Ð—Ð°Ð±Ñ€Ð°Ð²ÐµÐ½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
-  label_home: ÐÐ°Ñ‡Ð°Ð»Ð¾
-  label_my_page: Ð›Ð¸Ñ‡Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  label_my_account: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
-  label_my_projects: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸, Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑƒÑ‡Ð°ÑÑ‚Ð²Ð°Ð¼
-  label_my_page_block: Ð‘Ð»Ð¾ÐºÐ¾Ð²Ðµ Ð² Ð»Ð¸Ñ‡Ð½Ð°Ñ‚Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  label_administration: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
-  label_login: Ð’Ñ…Ð¾Ð´
-  label_logout: Ð˜Ð·Ñ…Ð¾Ð´
-  label_help: ÐŸÐ¾Ð¼Ð¾Ñ‰
-  label_reported_issues: ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_assigned_to_me_issues: Ð’ÑŠÐ·Ð»Ð¾Ð¶ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½
-  label_last_login: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¾ ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ
-  label_registered_on: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
-  label_activity: Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚
-  label_overall_activity: Ð¦ÑÐ»Ð¾ÑÑ‚Ð½Ð° Ð´ÐµÐ¹Ð½Ð¾ÑÑ‚
-  label_user_activity: "ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚ Ð½Ð° %{value}"
-  label_new: ÐÐ¾Ð²
-  label_logged_as: Ð—Ð´Ñ€Ð°Ð²ÐµÐ¹Ñ‚Ðµ,
-  label_environment: Ð¡Ñ€ÐµÐ´Ð°
-  label_authentication: ÐžÑ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
-  label_auth_source: ÐÐ°Ñ‡Ð¸Ð½ Ð½Ð° Ð¾Ñ‚Ð¾Ñ€Ð¾Ð·Ð°Ñ†Ð¸Ñ
-  label_auth_source_new: ÐÐ¾Ð² Ð½Ð°Ñ‡Ð¸Ð½ Ð½Ð° Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
-  label_auth_source_plural: ÐÐ°Ñ‡Ð¸Ð½Ð¸ Ð½Ð° Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
-  label_subproject_plural: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_subproject_new: ÐÐ¾Ð² Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  label_and_its_subprojects: "%{value} Ð¸ Ð½ÐµÐ³Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
-  label_min_max_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° - Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð°
-  label_list: Ð¡Ð¿Ð¸ÑÑŠÐº
-  label_date: Ð”Ð°Ñ‚Ð°
-  label_integer: Ð¦ÐµÐ»Ð¾Ñ‡Ð¸ÑÐ»ÐµÐ½
-  label_float: Ð”Ñ€Ð¾Ð±Ð½Ð¾
-  label_boolean: Ð§ÐµÐºÐ±Ð¾ÐºÑ
-  label_string: Ð¢ÐµÐºÑÑ‚
-  label_text: Ð”ÑŠÐ»ÑŠÐ³ Ñ‚ÐµÐºÑÑ‚
-  label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
-  label_attribute_plural: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸
-  label_download: "%{count} Ð¸Ð·Ñ‚ÐµÐ³Ð»ÑÐ½Ðµ"
-  label_download_plural: "%{count} Ð¸Ð·Ñ‚ÐµÐ³Ð»ÑÐ½Ð¸Ñ"
-  label_no_data: ÐÑÐ¼Ð° Ð¸Ð·Ñ…Ð¾Ð´Ð½Ð¸ Ð´Ð°Ð½Ð½Ð¸
-  label_change_status: ÐŸÑ€Ð¾Ð¼ÑÐ½Ð° Ð½Ð° ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸ÐµÑ‚Ð¾
-  label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ
-  label_attachment: Ð¤Ð°Ð¹Ð»
-  label_attachment_new: ÐÐ¾Ð² Ñ„Ð°Ð¹Ð»
-  label_attachment_delete: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ
-  label_attachment_plural: Ð¤Ð°Ð¹Ð»Ð¾Ð²Ðµ
-  label_file_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½ Ñ„Ð°Ð¹Ð»
-  label_report: Ð¡Ð¿Ñ€Ð°Ð²ÐºÐ°
-  label_report_plural: Ð¡Ð¿Ñ€Ð°Ð²ÐºÐ¸
-  label_news: ÐÐ¾Ð²Ð¸Ð½Ð¸
-  label_news_new: Ð”Ð¾Ð±Ð°Ð²Ð¸
-  label_news_plural: ÐÐ¾Ð²Ð¸Ð½Ð¸
-  label_news_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ð½Ð¾Ð²Ð¸Ð½Ð¸
-  label_news_view_all: Ð’Ð¸Ð¶ Ð²ÑÐ¸Ñ‡ÐºÐ¸
-  label_news_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð° Ð½Ð¾Ð²Ð¸Ð½Ð°
-  label_news_comment_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€ ÐºÑŠÐ¼ Ð½Ð¾Ð²Ð¸Ð½Ð°
-  label_settings: ÐÐ°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸
-  label_overview: ÐžÐ±Ñ‰ Ð¸Ð·Ð³Ð»ÐµÐ´
-  label_version: Ð’ÐµÑ€ÑÐ¸Ñ
-  label_version_new: ÐÐ¾Ð²Ð° Ð²ÐµÑ€ÑÐ¸Ñ
-  label_version_plural: Ð’ÐµÑ€ÑÐ¸Ð¸
-  label_close_versions: Ð—Ð°Ñ‚Ð²Ð°Ñ€ÑÐ½Ðµ Ð½Ð° Ð·Ð°Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð²ÐµÑ€ÑÐ¸Ð¸
-  label_confirmation: ÐžÐ´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ðµ
-  label_export_to: Ð•ÐºÑÐ¿Ð¾Ñ€Ñ‚ ÐºÑŠÐ¼
-  label_read: Read...
-  label_public_projects: ÐŸÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_open_issues: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-  label_open_issues_plural: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-  label_closed_issues: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-  label_closed_issues_plural: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-  label_x_open_issues_abbr_on_total:
-    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸ / %{total}
-    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° / %{total}
-    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸ / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸"
-  label_x_closed_issues_abbr:
-    zero:  0 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-    one:   1 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-    other: "%{count} Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸"
-  label_total: ÐžÐ±Ñ‰Ð¾
-  label_permissions: ÐŸÑ€Ð°Ð²Ð°
-  label_current_status: Ð¢ÐµÐºÑƒÑ‰Ð¾ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
-  label_new_statuses_allowed: ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ñ
-  label_all: Ð²ÑÐ¸Ñ‡ÐºÐ¸
-  label_none: Ð½Ð¸ÐºÐ°ÐºÐ²Ð¸
-  label_nobody: Ð½Ð¸ÐºÐ¾Ð¹
-  label_next: Ð¡Ð»ÐµÐ´Ð²Ð°Ñ‰
-  label_previous: ÐŸÑ€ÐµÐ´Ð¸ÑˆÐµÐ½
-  label_used_by: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° ÑÐµ Ð¾Ñ‚
-  label_details: Ð”ÐµÑ‚Ð°Ð¹Ð»Ð¸
-  label_add_note: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð±ÐµÐ»ÐµÐ¶ÐºÐ°
-  label_per_page: ÐÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
-  label_months_from: Ð¼ÐµÑÐµÑ†Ð° Ð¾Ñ‚
-  label_gantt: ÐœÑ€ÐµÐ¶Ð¾Ð² Ð³Ñ€Ð°Ñ„Ð¸Ðº
-  label_internal: Ð’ÑŠÑ‚Ñ€ÐµÑˆÐµÐ½
-  label_last_changes: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸ %{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
-  label_change_view_all: Ð’Ð¸Ð¶ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸
-  label_personalize_page: ÐŸÐµÑ€ÑÐ¾Ð½Ð°Ð»Ð¸Ð·Ð¸Ñ€Ð°Ð½Ðµ
-  label_comment: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  label_comment_plural: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
-  label_x_comments:
-    zero: 0 ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
-    one: 1 ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-    other: "%{count} ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸"
-  label_comment_add: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  label_comment_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  label_comment_delete: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
-  label_query: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ° ÑÐ¿Ñ€Ð°Ð²ÐºÐ°
-  label_query_plural: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ ÑÐ¿Ñ€Ð°Ð²ÐºÐ¸
-  label_query_new: ÐÐ¾Ð²Ð° Ð·Ð°ÑÐ²ÐºÐ°
-  label_my_queries: ÐœÐ¾Ð¸Ñ‚Ðµ Ð·Ð°ÑÐ²ÐºÐ¸
-  label_filter_add: Ð”Ð¾Ð±Ð°Ð²Ð¸ Ñ„Ð¸Ð»Ñ‚ÑŠÑ€
-  label_filter_plural: Ð¤Ð¸Ð»Ñ‚Ñ€Ð¸
-  label_equals: Ðµ
-  label_not_equals: Ð½Ðµ Ðµ
-  label_in_less_than: ÑÐ»ÐµÐ´ Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚
-  label_in_more_than: ÑÐ»ÐµÐ´ Ð¿Ð¾Ð²ÐµÑ‡Ðµ Ð¾Ñ‚
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  label_between: Ð¼ÐµÐ¶Ð´Ñƒ
-  label_in: Ð² ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ‚Ðµ
-  label_today: Ð´Ð½ÐµÑ
-  label_all_time: Ð²ÑÐ¸Ñ‡ÐºÐ¸
-  label_yesterday: Ð²Ñ‡ÐµÑ€Ð°
-  label_this_week: Ñ‚Ð°Ð·Ð¸ ÑÐµÐ´Ð¼Ð¸Ñ†Ð°
-  label_last_week: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð°Ñ‚Ð° ÑÐµÐ´Ð¼Ð¸Ñ†Ð°
-  label_last_n_days: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ‚Ðµ %{count} Ð´Ð½Ð¸"
-  label_this_month: Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð¼ÐµÑÐµÑ†
-  label_last_month: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð¼ÐµÑÐµÑ†
-  label_this_year: Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ‚Ð° Ð³Ð¾Ð´Ð¸Ð½Ð°
-  label_date_range: ÐŸÐµÑ€Ð¸Ð¾Ð´
-  label_less_than_ago: Ð¿Ñ€ÐµÐ´Ð¸ Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚
-  label_more_than_ago: Ð¿Ñ€ÐµÐ´Ð¸ Ð¿Ð¾Ð²ÐµÑ‡Ðµ Ð¾Ñ‚
-  label_ago: Ð¿Ñ€ÐµÐ´Ð¸
-  label_contains: ÑÑŠÐ´ÑŠÑ€Ð¶Ð°
-  label_not_contains: Ð½Ðµ ÑÑŠÐ´ÑŠÑ€Ð¶Ð°
-  label_day_plural: Ð´Ð½Ð¸
-  label_repository: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
-  label_repository_plural: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
-  label_browse: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ
-  label_modification: "%{count} Ð¿Ñ€Ð¾Ð¼ÑÐ½Ð°"
-  label_modification_plural: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
-  label_branch: Ñ€Ð°Ð±Ð¾Ñ‚ÐµÐ½ Ð²Ð°Ñ€Ð¸Ð°Ð½Ñ‚
-  label_tag: Ð’ÐµÑ€ÑÐ¸Ñ
-  label_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ
-  label_revision_plural: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  label_revision_id: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ %{value}
-  label_associated_revisions: ÐÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð°Ð½Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  label_added: Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð¾
-  label_modified: Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½Ð¾
-  label_copied: ÐºÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ð¾
-  label_renamed: Ð¿Ñ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð¾
-  label_deleted: Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚Ð¾
-  label_latest_revision: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ
-  label_latest_revision_plural: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  label_view_revisions: Ð’Ð¸Ð¶ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸Ñ‚Ðµ
-  label_view_all_revisions: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  label_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð°
-  label_sort_highest: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ð¹-Ð³Ð¾Ñ€Ðµ
-  label_sort_higher: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð¿Ð¾-Ð³Ð¾Ñ€Ðµ
-  label_sort_lower: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð¿Ð¾-Ð´Ð¾Ð»Ñƒ
-  label_sort_lowest: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ð¹-Ð´Ð¾Ð»Ñƒ
-  label_roadmap: ÐŸÑŠÑ‚Ð½Ð° ÐºÐ°Ñ€Ñ‚Ð°
-  label_roadmap_due_in: "Ð˜Ð·Ð»Ð¸Ð·Ð° ÑÐ»ÐµÐ´ %{value}"
-  label_roadmap_overdue: "%{value} Ð·Ð°ÐºÑŠÑÐ½ÐµÐ½Ð¸Ðµ"
-  label_roadmap_no_issues: ÐÑÐ¼Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð·Ð° Ñ‚Ð°Ð·Ð¸ Ð²ÐµÑ€ÑÐ¸Ñ
-  label_search: Ð¢ÑŠÑ€ÑÐµÐ½Ðµ
-  label_result_plural: PÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸
-  label_all_words: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð´ÑƒÐ¼Ð¸
-  label_wiki: Wiki
-  label_wiki_edit: Wiki Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ñ
-  label_wiki_edit_plural: Wiki Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
-  label_wiki_page: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  label_wiki_page_plural: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  label_index_by_title: Ð˜Ð½Ð´ÐµÐºÑ
-  label_index_by_date: Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Ð´Ð°Ñ‚Ð°
-  label_current_version: Ð¢ÐµÐºÑƒÑ‰Ð° Ð²ÐµÑ€ÑÐ¸Ñ
-  label_preview: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
-  label_feed_plural: Ð•Ð¼Ð¸ÑÐ¸Ð¸
-  label_changes_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸
-  label_issue_tracking: Ð¢Ñ€Ð°ÐºÐ¸Ð½Ð³
-  label_spent_time: ÐžÑ‚Ð´ÐµÐ»ÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_overall_spent_time: ÐžÐ±Ñ‰Ð¾ ÑƒÐ¿Ð¾Ñ‚Ñ€ÐµÐ±ÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_f_hour: "%{value} Ñ‡Ð°Ñ"
-  label_f_hour_plural: "%{value} Ñ‡Ð°ÑÐ°"
-  label_time_tracking: ÐžÑ‚Ð´ÐµÐ»ÑÐ½Ðµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
-  label_change_plural: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸
-  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ¸
-  label_commits_per_month: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸ Ð¿Ð¾ Ð¼ÐµÑÐµÑ†Ð¸
-  label_commits_per_author: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸ Ð¿Ð¾ Ð°Ð²Ñ‚Ð¾Ñ€
-  label_diff: diff
-  label_view_diff: Ð’Ð¸Ð¶ Ñ€Ð°Ð·Ð»Ð¸ÐºÐ¸Ñ‚Ðµ
-  label_diff_inline: Ñ…Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»Ð½Ð¾
-  label_diff_side_by_side: Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»Ð½Ð¾
-  label_options: ÐžÐ¿Ñ†Ð¸Ð¸
-  label_copy_workflow_from: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ð¹ Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð¾Ñ‚
-  label_permissions_report: Ð¡Ð¿Ñ€Ð°Ð²ÐºÐ° Ð·Ð° Ð¿Ñ€Ð°Ð²Ð°
-  label_watched_issues: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ð²Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_related_issues: Ð¡Ð²ÑŠÑ€Ð·Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_applied_status: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²ÐµÐ½Ð¾ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
-  label_loading: Ð—Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½Ðµ...
-  label_relation_new: ÐÐ¾Ð²Ð° Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ
-  label_relation_delete: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ
-  label_relates_to: ÑÐ²ÑŠÑ€Ð·Ð°Ð½Ð° ÑÑŠÑ
-  label_duplicates: Ð´ÑƒÐ±Ð»Ð¸Ñ€Ð°
-  label_duplicated_by: Ð´ÑƒÐ±Ð»Ð¸Ñ€Ð°Ð½Ð° Ð¾Ñ‚
-  label_blocks: Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð°
-  label_blocked_by: Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð°Ð½Ð° Ð¾Ñ‚
-  label_precedes: Ð¿Ñ€ÐµÐ´ÑˆÐµÑÑ‚Ð²Ð°
-  label_follows: Ð¸Ð·Ð¿ÑŠÐ»Ð½ÑÐ²Ð° ÑÐµ ÑÐ»ÐµÐ´
-  label_end_to_start: ÐºÑ€Ð°Ð¹ ÐºÑŠÐ¼ Ð½Ð°Ñ‡Ð°Ð»Ð¾
-  label_end_to_end: ÐºÑ€Ð°Ð¹ ÐºÑŠÐ¼ ÐºÑ€Ð°Ð¹
-  label_start_to_start: Ð½Ð°Ñ‡Ð°Ð»Ð¾ ÐºÑŠÐ¼ Ð½Ð°Ñ‡Ð°Ð»Ð¾
-  label_start_to_end: Ð½Ð°Ñ‡Ð°Ð»Ð¾ ÐºÑŠÐ¼ ÐºÑ€Ð°Ð¹
-  label_stay_logged_in: Ð—Ð°Ð¿Ð¾Ð¼Ð½Ð¸ Ð¼Ðµ
-  label_disabled: Ð·Ð°Ð±Ñ€Ð°Ð½ÐµÐ½Ð¾
-  label_show_completed_versions: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ñ€ÐµÐ°Ð»Ð¸Ð·Ð¸Ñ€Ð°Ð½Ð¸ Ð²ÐµÑ€ÑÐ¸Ð¸
-  label_me: Ð°Ð·
-  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
-  label_board_new: ÐÐ¾Ð² Ñ„Ð¾Ñ€ÑƒÐ¼
-  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
-  label_board_locked: Ð—Ð°ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°
-  label_board_sticky: Sticky
-  label_topic_plural: Ð¢ÐµÐ¼Ð¸
-  label_message_plural: Ð¡ÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
-  label_message_last: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¾ ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
-  label_message_new: ÐÐ¾Ð²Ð° Ñ‚ÐµÐ¼Ð°
-  label_message_posted: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð¾ ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
-  label_reply_plural: ÐžÑ‚Ð³Ð¾Ð²Ð¾Ñ€Ð¸
-  label_send_information: Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÑÑ‚Ð° Ð´Ð¾ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ
-  label_year: Ð“Ð¾Ð´Ð¸Ð½Ð°
-  label_month: ÐœÐµÑÐµÑ†
-  label_week: Ð¡ÐµÐ´Ð¼Ð¸Ñ†Ð°
-  label_date_from: ÐžÑ‚
-  label_date_to: Ð”Ð¾
-  label_language_based: Ð’ Ð·Ð°Ð²Ð¸ÑÐ¸Ð¼Ð¾ÑÑ‚ Ð¾Ñ‚ ÐµÐ·Ð¸ÐºÐ°
-  label_sort_by: "Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ Ð¿Ð¾ %{value}"
-  label_send_test_email: Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° Ñ‚ÐµÑÑ‚Ð¾Ð² e-mail
-  label_feeds_access_key: RSS access ÐºÐ»ÑŽÑ‡
-  label_missing_feeds_access_key: Ð›Ð¸Ð¿ÑÐ²Ð°Ñ‰ RSS ÐºÐ»ÑŽÑ‡ Ð·Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿
-  label_feeds_access_key_created_on: "%{value} Ð¾Ñ‚ ÑÑŠÐ·Ð´Ð°Ð²Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° RSS ÐºÐ»ÑŽÑ‡Ð°"
-  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ð¸
-  label_added_time_by: "ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ð½Ð° Ð¾Ñ‚ %{author} Ð¿Ñ€ÐµÐ´Ð¸ %{age}"
-  label_updated_time_by: "ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð° Ð¾Ñ‚ %{author} Ð¿Ñ€ÐµÐ´Ð¸ %{age}"
-  label_updated_time: "ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð° Ð¿Ñ€ÐµÐ´Ð¸ %{value}"
-  label_jump_to_a_project: ÐŸÑ€Ð¾ÐµÐºÑ‚...
-  label_file_plural: Ð¤Ð°Ð¹Ð»Ð¾Ð²Ðµ
-  label_changeset_plural: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  label_default_columns: ÐŸÐ¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
-  label_no_change_option: (Ð‘ÐµÐ· Ð¿Ñ€Ð¾Ð¼ÑÐ½Ð°)
-  label_bulk_edit_selected_issues: Ð“Ñ€ÑƒÐ¿Ð¾Ð²Ð¾ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_bulk_edit_selected_time_entries: Ð“Ñ€ÑƒÐ¿Ð¾Ð²Ð¾ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð·Ð° Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_theme: Ð¢ÐµÐ¼Ð°
-  label_default: ÐŸÐ¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
-  label_search_titles_only: Ð¡Ð°Ð¼Ð¾ Ð² Ð·Ð°Ð³Ð»Ð°Ð²Ð¸ÑÑ‚Ð°
-  label_user_mail_option_all: "Ð—Ð° Ð²ÑÑÐºÐ¾ ÑÑŠÐ±Ð¸Ñ‚Ð¸Ðµ Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ, Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑƒÑ‡Ð°ÑÑ‚Ð²Ð°Ð¼"
-  label_user_mail_option_selected: "Ð—Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸ ÑÑŠÐ±Ð¸Ñ‚Ð¸Ñ ÑÐ°Ð¼Ð¾ Ð² Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸..."
-  label_user_mail_option_none: "Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ð²Ð°Ð½Ð¸ Ð¸Ð»Ð¸ Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑƒÑ‡Ð°ÑÑ‚Ð²Ð°Ð¼ (Ð°Ð²Ñ‚Ð¾Ñ€ Ð¸Ð»Ð¸ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½)"
-  label_user_mail_option_only_my_events: Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ð½ÐµÑ‰Ð°, Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑÑŠÐ¼ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½/Ð°
-  label_user_mail_option_only_assigned: Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ð½ÐµÑ‰Ð°, Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½
-  label_user_mail_option_only_owner: Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ð½ÐµÑ‰Ð°, Ð½Ð° ÐºÐ¾Ð¸Ñ‚Ð¾ Ð°Ð· ÑÑŠÐ¼ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸Ðº
-  label_user_mail_no_self_notified: "ÐÐµ Ð¸ÑÐºÐ°Ð¼ Ð¸Ð·Ð²ÐµÑÑ‚Ð¸Ñ Ð·Ð° Ð¸Ð·Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸ Ð¾Ñ‚ Ð¼ÐµÐ½ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
-  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð° Ð¿Ð¾ email
-  label_registration_manual_activation: Ñ€ÑŠÑ‡Ð½Ð¾ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ
-  label_registration_automatic_activation: Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ
-  label_display_per_page: "ÐÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¿Ð¾: %{value}"
-  label_age: Ð’ÑŠÐ·Ñ€Ð°ÑÑ‚
-  label_change_properties: ÐŸÑ€Ð¾Ð¼ÑÐ½Ð° Ð½Ð° Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸
-  label_general: ÐžÑÐ½Ð¾Ð²Ð½Ð¸
-  label_more: ÐžÑ‰Ðµ
-  label_scm: SCM (Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð° Ð·Ð° ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð» Ð½Ð° Ð²ÐµÑ€ÑÐ¸Ð¸Ñ‚Ðµ)
-  label_plugins: ÐŸÐ»ÑŠÐ³Ð¸Ð½Ð¸
-  label_ldap_authentication: LDAP Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
-  label_downloads_abbr: D/L
-  label_optional_description: ÐÐµÐ·Ð°Ð´ÑŠÐ»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾ Ð¾Ð¿Ð¸ÑÐ°Ð½Ð¸Ðµ
-  label_add_another_file: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð´Ñ€ÑƒÐ³ Ñ„Ð°Ð¹Ð»
-  label_preferences: ÐŸÑ€ÐµÐ´Ð¿Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð¸Ñ
-  label_chronological_order: Ð¥Ñ€Ð¾Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ‡ÐµÐ½ Ñ€ÐµÐ´
-  label_reverse_chronological_order: ÐžÐ±Ñ€Ð°Ñ‚ÐµÐ½ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ‡ÐµÐ½ Ñ€ÐµÐ´
-  label_planning: ÐŸÐ»Ð°Ð½Ð¸Ñ€Ð°Ð½Ðµ
-  label_incoming_emails: Ð’Ñ…Ð¾Ð´ÑÑ‰Ð¸ e-mail-Ð¸
-  label_generate_key: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÐºÐ»ÑŽÑ‡
-  label_issue_watchers: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
-  label_example: ÐŸÑ€Ð¸Ð¼ÐµÑ€
-  label_display: Display
-  label_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ
-  label_ascending: ÐÐ°Ñ€Ð°ÑÑ‚Ð²Ð°Ñ‰
-  label_descending: ÐÐ°Ð¼Ð°Ð»ÑÐ²Ð°Ñ‰
-  label_date_from_to: ÐžÑ‚ %{start} Ð´Ð¾ %{end}
-  label_wiki_content_added: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð±ÐµÑˆÐµ Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð°
-  label_wiki_content_updated: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð±ÐµÑˆÐµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð°
-  label_group: Ð“Ñ€ÑƒÐ¿Ð°
-  label_group_plural: Ð“Ñ€ÑƒÐ¿Ð¸
-  label_group_new: ÐÐ¾Ð²Ð° Ð³Ñ€ÑƒÐ¿Ð°
-  label_time_entry_plural: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_version_sharing_none: ÐÐµ ÑÐ¿Ð¾Ð´ÐµÐ»ÐµÐ½
-  label_version_sharing_descendants: Ð¡ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_version_sharing_hierarchy: Ð¡ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ð° Ð¹ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ
-  label_version_sharing_tree: Ð¡ Ð´ÑŠÑ€Ð²Ð¾ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ
-  label_version_sharing_system: Ð¡ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_update_issue_done_ratios: ÐžÐ±Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾Ñ†ÐµÐ½Ñ‚Ð° Ð½Ð° Ð·Ð°Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_copy_source: Ð˜Ð·Ñ‚Ð¾Ñ‡Ð½Ð¸Ðº
-  label_copy_target: Ð¦ÐµÐ»
-  label_copy_same_as_target: Ð¡ÑŠÑ‰Ð¾ ÐºÐ°Ñ‚Ð¾ Ñ†ÐµÐ»Ñ‚Ð°
-  label_display_used_statuses_only: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ðµ ÑÐ°Ð¼Ð¾ Ð½Ð° ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸ÑÑ‚Ð°, Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ð¸ Ð¾Ñ‚ Ñ‚Ð¾Ð·Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€
-  label_api_access_key: API ÐºÐ»ÑŽÑ‡ Ð·Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿
-  label_missing_api_access_key: Ð›Ð¸Ð¿ÑÐ²Ð°Ñ‰ API ÐºÐ»ÑŽÑ‡
-  label_api_access_key_created_on: API ÐºÐ»ÑŽÑ‡ Ð·Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿ Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½ Ð¿Ñ€ÐµÐ´Ð¸ %{value}
-  label_profile: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
-  label_subtask_plural: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_project_copy_notifications: Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° Send e-mail Ð¸Ð·Ð²ÐµÑÑ‚Ð¸Ñ Ð¿Ð¾ Ð²Ñ€ÐµÐ¼Ðµ Ð½Ð° ÐºÐ¾Ð¿Ð¸Ñ€Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
-  label_principal_search: "Ð¢ÑŠÑ€ÑÐµÐ½Ðµ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» Ð¸Ð»Ð¸ Ð³Ñ€ÑƒÐ¿Ð°:"
-  label_user_search: "Ð¢ÑŠÑ€ÑÐµÐ½Ðµ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»:"
-  label_additional_workflow_transitions_for_author: ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ° Ð´Ð¾Ð¿ÑŠÐ»Ð½Ð¸Ñ‚ÐµÐ»Ð½Ð¸ Ð¿Ñ€ÐµÑ…Ð¾Ð´Ð¸, ÐºÐ¾Ð³Ð°Ñ‚Ð¾ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÑ‚ Ðµ Ð°Ð²Ñ‚Ð¾Ñ€ÑŠÑ‚
-  label_additional_workflow_transitions_for_assignee:  ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ° Ð´Ð¾Ð¿ÑŠÐ»Ð½Ð¸Ñ‚ÐµÐ»Ð½Ð¸ Ð¿Ñ€ÐµÑ…Ð¾Ð´Ð¸, ÐºÐ¾Ð³Ð°Ñ‚Ð¾ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÑ‚ Ðµ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÑÑ‚ ÐºÑŠÐ¼ Ð·Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð°
-  label_issues_visibility_all: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issues_visibility_public: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð½Ðµ-Ð»Ð¸Ñ‡Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issues_visibility_own: Ð—Ð°Ð´Ð°Ñ‡Ð¸, ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½Ð¸ Ð¾Ñ‚ Ð¸Ð»Ð¸ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ
-  label_git_report_last_commit: Ð˜Ð·Ð²ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¾Ñ‚Ð¾ Ð¿Ð¾Ð²ÐµÑ€ÑÐ²Ð°Ð½Ðµ Ð·Ð° Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ Ð¸ Ð¿Ð°Ð¿ÐºÐ¸
-  label_parent_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»
-  label_child_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ Ð½Ð°ÑÐ»ÐµÐ´Ð½Ð¸Ðº
-  label_export_options: "%{export_format} Ð¾Ð¿Ñ†Ð¸Ð¸ Ð·Ð° ÐµÐºÑÐ¿Ð¾Ñ€Ñ‚"
-
-  button_login: Ð’Ñ…Ð¾Ð´
-  button_submit: ÐŸÑ€Ð¸ÐºÐ°Ñ‡Ð²Ð°Ð½Ðµ
-  button_save: Ð—Ð°Ð¿Ð¸Ñ
-  button_check_all: Ð˜Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸
-  button_uncheck_all: Ð˜Ð·Ñ‡Ð¸ÑÑ‚Ð²Ð°Ð½Ðµ Ð½Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸
-  button_collapse_all: Ð¡ÐºÑ€Ð¸Ð²Ð°Ð½Ðµ Ð²ÑÐ¸Ñ‡ÐºÐ¸
-  button_expand_all: Ð Ð°Ð·Ð³ÑŠÐ²Ð°Ð½Ðµ Ð²ÑÐ¸Ñ‡ÐºÐ¸
-  button_delete: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ
-  button_create: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ
-  button_create_and_continue: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð¸ Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð°Ð²Ð°Ð½Ðµ
-  button_test: Ð¢ÐµÑÑ‚
-  button_edit: Ð ÐµÐ´Ð°ÐºÑ†Ð¸Ñ
-  button_edit_associated_wikipage: "Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð°ÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð°Ð½Ð°Ñ‚Ð° Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°: %{page_title}"
-  button_add: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ
-  button_change: ÐŸÑ€Ð¾Ð¼ÑÐ½Ð°
-  button_apply: ÐŸÑ€Ð¸Ð»Ð¾Ð¶Ð¸
-  button_clear: Ð˜Ð·Ñ‡Ð¸ÑÑ‚Ð¸
-  button_lock: Ð—Ð°ÐºÐ»ÑŽÑ‡Ð²Ð°Ð½Ðµ
-  button_unlock: ÐžÑ‚ÐºÐ»ÑŽÑ‡Ð²Ð°Ð½Ðµ
-  button_download: Ð˜Ð·Ñ‚ÐµÐ³Ð»ÑÐ½Ðµ
-  button_list: Ð¡Ð¿Ð¸ÑÑŠÐº
-  button_view: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
-  button_move: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð²Ð°Ð½Ðµ
-  button_move_and_follow: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð²Ð°Ð½Ðµ Ð¸ Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð°Ð²Ð°Ð½Ðµ
-  button_back: ÐÐ°Ð·Ð°Ð´
-  button_cancel: ÐžÑ‚ÐºÐ°Ð·
-  button_activate: ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ
-  button_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ
-  button_log_time: ÐžÑ‚Ð´ÐµÐ»ÑÐ½Ðµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
-  button_rollback: Ð’ÑŠÑ€Ð½Ð¸ ÑÐµ ÐºÑŠÐ¼ Ñ‚Ð°Ð·Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ
-  button_watch: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ð²Ð°Ð½Ðµ
-  button_unwatch: ÐšÑ€Ð°Ð¹ Ð½Ð° Ð½Ð°Ð±Ð»ÑŽÐ´ÐµÐ½Ð¸ÐµÑ‚Ð¾
-  button_reply: ÐžÑ‚Ð³Ð¾Ð²Ð¾Ñ€
-  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ
-  button_unarchive: Ð Ð°Ð·Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ
-  button_reset: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð°Ð½Ð¾Ð²Ð¾
-  button_rename: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ðµ
-  button_change_password: ÐŸÑ€Ð¾Ð¼ÑÐ½Ð° Ð½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
-  button_copy: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ðµ
-  button_copy_and_follow: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ðµ Ð¸ Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð°Ð²Ð°Ð½Ðµ
-  button_annotate: ÐÐ½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ
-  button_update: ÐžÐ±Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ
-  button_configure: ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð½Ðµ
-  button_quote: Ð¦Ð¸Ñ‚Ð°Ñ‚
-  button_duplicate: Ð”ÑƒÐ±Ð»Ð¸Ñ€Ð°Ð½Ðµ
-  button_show: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ðµ
-  button_edit_section: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ñ‚Ð°Ð·Ð¸ ÑÐµÐºÑ†Ð¸Ñ
-  button_export: Ð•ÐºÑÐ¿Ð¾Ñ€Ñ‚
-
-  status_active: Ð°ÐºÑ‚Ð¸Ð²ÐµÐ½
-  status_registered: Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½
-  status_locked: Ð·Ð°ÐºÐ»ÑŽÑ‡ÐµÐ½
-
-  version_status_open: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-  version_status_locked: Ð·Ð°ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°
-  version_status_closed: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-
-  field_active: ÐÐºÑ‚Ð¸Ð²ÐµÐ½
-
-  text_select_mail_notifications: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ ÑÑŠÐ±Ð¸Ñ‚Ð¸Ñ Ð·Ð° Ð¸Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° e-mail.
-  text_regexp_info: Ð¿Ñ€. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 - Ð±ÐµÐ· Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ
-  text_project_destroy_confirmation: Ð¡Ð¸Ð³ÑƒÑ€Ð½Ð¸ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð° Ð¸ Ð´Ð°Ð½Ð½Ð¸Ñ‚Ðµ Ð² Ð½ÐµÐ³Ð¾?
-  text_subprojects_destroy_warning: "ÐÐµÐ³Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸: %{value} ÑÑŠÑ‰Ð¾ Ñ‰Ðµ Ð±ÑŠÐ´Ð°Ñ‚ Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚Ð¸."
-  text_workflow_edit: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ñ€Ð¾Ð»Ñ Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€ Ð·Ð° Ð´Ð° Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ñ‚Ðµ Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑ
-  text_are_you_sure: Ð¡Ð¸Ð³ÑƒÑ€Ð½Ð¸ Ð»Ð¸ ÑÑ‚Ðµ?
-  text_are_you_sure_with_children: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ð¸ Ð½ÐµÐ¹Ð½Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸?
-  text_journal_changed: "%{label} Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½ Ð¾Ñ‚ %{old} Ð½Ð° %{new}"
-  text_journal_changed_no_detail: "%{label} Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½"
-  text_journal_set_to: "%{label} ÑƒÑÑ‚Ð°Ð½Ð¾Ð²ÐµÐ½ Ð½Ð° %{value}"
-  text_journal_deleted: "%{label} Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚ (%{old})"
-  text_journal_added: "Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð¾ %{label} %{value}"
-  text_tip_issue_begin_day: Ð·Ð°Ð´Ð°Ñ‡Ð°, Ð·Ð°Ð¿Ð¾Ñ‡Ð²Ð°Ñ‰Ð° Ñ‚Ð¾Ð·Ð¸ Ð´ÐµÐ½
-  text_tip_issue_end_day: Ð·Ð°Ð´Ð°Ñ‡Ð°, Ð·Ð°Ð²ÑŠÑ€ÑˆÐ²Ð°Ñ‰Ð° Ñ‚Ð¾Ð·Ð¸ Ð´ÐµÐ½
-  text_tip_issue_begin_end_day: Ð·Ð°Ð´Ð°Ñ‡Ð°, Ð·Ð°Ð¿Ð¾Ñ‡Ð²Ð°Ñ‰Ð° Ð¸ Ð·Ð°Ð²ÑŠÑ€ÑˆÐ²Ð°Ñ‰Ð° Ñ‚Ð¾Ð·Ð¸ Ð´ÐµÐ½
-  text_project_identifier_info: 'ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ° Ð¼Ð°Ð»ÐºÐ¸ Ð±ÑƒÐºÐ²Ð¸ (a-z), Ñ†Ð¸Ñ„Ñ€Ð¸ Ð¸ Ñ‚Ð¸Ñ€ÐµÑ‚Ð°.<br />ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð° Ð¿Ñ€Ð¾Ð¼ÑÐ½Ð° ÑÐ»ÐµÐ´ Ð·Ð°Ð¿Ð¸Ñ.'
-  text_caracters_maximum: "Ð”Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°."
-  text_caracters_minimum: "ÐœÐ¸Ð½Ð¸Ð¼ÑƒÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°."
-  text_length_between: "ÐžÑ‚ %{min} Ð´Ð¾ %{max} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°."
-  text_tracker_no_workflow: ÐÑÐ¼Ð° Ð´ÐµÑ„Ð¸Ð½Ð¸Ñ€Ð°Ð½ Ñ€Ð°Ð±Ð¾Ñ‚ÐµÐ½ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð·Ð° Ñ‚Ð¾Ð·Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€
-  text_unallowed_characters: ÐÐµÐ¿Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¸
-  text_comma_separated: ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¾ Ðµ Ð¸Ð·Ð±Ñ€Ð¾ÑÐ²Ð°Ð½Ðµ (Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ» Ð·Ð°Ð¿ÐµÑ‚Ð°Ñ).
-  text_line_separated: ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ° Ð¼Ð½Ð¾Ð³Ð¾ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚Ð¸ (Ð¿Ð¾ ÐµÐ´Ð½Ð¾ Ð½Ð° Ñ€ÐµÐ´).
-  text_issues_ref_in_commit_messages: ÐžÑ‚Ð±ÐµÐ»ÑÐ·Ð²Ð°Ð½Ðµ Ð¸ Ð¿Ñ€Ð¸ÐºÐ»ÑŽÑ‡Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¾Ñ‚ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  text_issue_added: "ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ð½Ð° Ðµ Ð½Ð¾Ð²Ð° Ð·Ð°Ð´Ð°Ñ‡Ð° Ñ Ð½Ð¾Ð¼ÐµÑ€ %{id} (Ð¾Ñ‚ %{author})."
-  text_issue_updated: "Ð—Ð°Ð´Ð°Ñ‡Ð° %{id} Ðµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð° (Ð¾Ñ‚ %{author})."
-  text_wiki_destroy_confirmation: Ð¡Ð¸Ð³ÑƒÑ€Ð½Ð¸ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ Ñ‚Ð¾Ð²Ð° Wiki Ð¸ Ñ†ÑÐ»Ð¾Ñ‚Ð¾ Ð¼Ñƒ ÑÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ?
-  text_issue_category_destroy_question: "Ð˜Ð¼Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ (%{count}) Ð¾Ð±Ð²ÑŠÑ€Ð·Ð°Ð½Ð¸ Ñ Ñ‚Ð°Ð·Ð¸ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ. ÐšÐ°ÐºÐ²Ð¾ Ñ‰Ðµ Ð¸Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ?"
-  text_issue_category_destroy_assignments: ÐŸÑ€ÐµÐ¼Ð°Ñ…Ð²Ð°Ð½Ðµ Ð½Ð° Ð²Ñ€ÑŠÐ·ÐºÐ¸Ñ‚Ðµ Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸ÑÑ‚Ð°
-  text_issue_category_reassign_to: ÐŸÑ€ÐµÐ¾Ð±Ð²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
-  text_user_mail_option: "Ð—Ð° Ð½ÐµÐ¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸, Ñ‰Ðµ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ð²Ð°Ñ‚Ðµ Ð¸Ð·Ð²ÐµÑÑ‚Ð¸Ñ ÑÐ°Ð¼Ð¾ Ð·Ð° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ð²Ð°Ð½Ð¸ Ð´ÐµÐ¹Ð½Ð¾ÑÑ‚Ð¸ Ð¸Ð»Ð¸ Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑƒÑ‡Ð°ÑÑ‚Ð²Ð°Ñ‚Ðµ (Ñ‚.Ðµ. Ð°Ð²Ñ‚Ð¾Ñ€ Ð¸Ð»Ð¸ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½)."
-  text_no_configuration_data: "Ð’ÑÐµ Ð¾Ñ‰Ðµ Ð½Ðµ ÑÐ° ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¸ Ð Ð¾Ð»Ð¸, Ñ‚Ñ€Ð°ÐºÐµÑ€Ð¸, ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ñ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¸ Ñ€Ð°Ð±Ð¾Ñ‚ÐµÐ½ Ð¿Ñ€Ð¾Ñ†ÐµÑ.\nÐ¡Ñ‚Ñ€Ð¾Ð³Ð¾ ÑÐµ Ð¿Ñ€ÐµÐ¿Ð¾Ñ€ÑŠÑ‡Ð²Ð° Ð·Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð½Ð°Ñ‚Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ. Ð’ÐµÐ´Ð½ÑŠÐ¶ Ð·Ð°Ñ€ÐµÐ´ÐµÐ½Ð° Ñ‰Ðµ Ð¸Ð¼Ð°Ñ‚Ðµ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð´Ð° Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ñ‚Ðµ."
-  text_load_default_configuration: Ð—Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð½Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
-  text_status_changed_by_changeset: "ÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¾ Ñ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ %{value}."
-  text_time_logged_by_changeset: ÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¾ Ð² Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ %{value}.
-  text_issues_destroy_confirmation: 'Ð¡Ð¸Ð³ÑƒÑ€Ð½Ð¸ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸?'
-  text_issues_destroy_descendants_confirmation: Ð¢Ð°Ð·Ð¸ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ‰Ðµ Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½Ðµ Ð¸ %{count} Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð°(Ð¸).
-  text_time_entries_destroy_confirmation: Ð¡Ð¸Ð³ÑƒÑ€ÐµÐ½ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð·Ð° Ð¸Ð·Ñ€Ð°Ð·Ñ…Ð¾Ð´Ð²Ð°Ð½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ?
-  text_select_project_modules: 'Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¸Ñ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð·Ð° Ñ‚Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚:'
-  text_default_administrator_account_changed: Ð¡Ð¼ÐµÐ½ÐµÐ½ Ñ„Ð°Ð±Ñ€Ð¸Ñ‡Ð½Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€ÑÐºÐ¸ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»
-  text_file_repository_writable: Ð’ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¿Ð¸ÑÐ°Ð½Ðµ Ð² Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÑ‚Ð¾ Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
-  text_plugin_assets_writable: ÐŸÐ°Ð¿ÐºÐ°Ñ‚Ð° Ð½Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð²ÐºÐ¸Ñ‚Ðµ Ðµ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð° Ð·Ð° Ð·Ð°Ð¿Ð¸Ñ
-  text_rmagick_available: ÐÐ°Ð»Ð¸Ñ‡ÐµÐ½ RMagick (Ð¿Ð¾ Ð¸Ð·Ð±Ð¾Ñ€)
-  text_destroy_time_entries_question: "%{hours} Ñ‡Ð°ÑÐ° ÑÐ° Ð¾Ñ‚Ð´ÐµÐ»ÐµÐ½Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ, ÐºÐ¾Ð¸Ñ‚Ð¾ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ. ÐšÐ°ÐºÐ²Ð¾ Ð¸Ð·Ð±Ð¸Ñ€Ð°Ñ‚Ðµ?"
-  text_destroy_time_entries: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð¾Ñ‚Ð´ÐµÐ»ÐµÐ½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  text_assign_time_entries_to_project: ÐŸÑ€ÐµÑ…Ð²ÑŠÑ€Ð»ÑÐ½Ðµ Ð½Ð° Ð¾Ñ‚Ð´ÐµÐ»ÐµÐ½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ ÐºÑŠÐ¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  text_reassign_time_entries: 'ÐŸÑ€ÐµÑ…Ð²ÑŠÑ€Ð»ÑÐ½Ðµ Ð½Ð° Ð¾Ñ‚Ð´ÐµÐ»ÐµÐ½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ ÐºÑŠÐ¼ Ð·Ð°Ð´Ð°Ñ‡Ð°:'
-  text_user_wrote: "%{value} Ð½Ð°Ð¿Ð¸ÑÐ°:"
-  text_enumeration_destroy_question: "%{count} Ð¾Ð±ÐµÐºÑ‚Ð° ÑÐ° ÑÐ²ÑŠÑ€Ð·Ð°Ð½Ð¸ Ñ Ñ‚Ð°Ð·Ð¸ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚."
-  text_enumeration_category_reassign_to: 'ÐŸÑ€ÐµÑÐ²ÑŠÑ€Ð¶ÐµÑ‚Ðµ Ð³Ð¸ ÐºÑŠÐ¼ Ñ‚Ð°Ð·Ð¸ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚:'
-  text_email_delivery_not_configured: "Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° e-mail-Ð¸ Ð½Ðµ Ðµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾ Ð¸ Ð¸Ð·Ð²ÐµÑÑ‚Ð¸ÑÑ‚Ð° Ð½Ðµ ÑÐ° Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸.\nÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð¹Ñ‚Ðµ Ð²Ð°ÑˆÐ¸Ñ SMTP ÑÑŠÑ€Ð²ÑŠÑ€ Ð² config/configuration.yml Ð¸ Ñ€ÐµÑÑ‚Ð°Ñ€Ñ‚Ð¸Ñ€Ð°Ð¹Ñ‚Ðµ Redmine, Ð·Ð° Ð´Ð° Ð³Ð¸ Ñ€Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚Ðµ."
-  text_repository_usernames_mapping: "Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð¸Ð»Ð¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÑ‚Ðµ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸Ñ‚Ðµ Ð² Redmine, ÑÑŠÐ¾Ñ‚Ð²ÐµÑ‚ÑÑ‚Ð²Ð°Ñ‰Ð¸ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸Ñ‚Ðµ Ð² Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÐ° Ð½Ð° Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÑ‚Ð¾ (repository).\nÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸Ñ‚Ðµ Ñ ÐµÐ´Ð½Ð°ÐºÐ²Ð¸ Ð¸Ð¼ÐµÐ½Ð° Ð² Redmine Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°Ñ‚Ð° ÑÐµ ÑÑŠÐ²Ð¼ÐµÑÑ‚ÑÐ²Ð°Ñ‚ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾."
-  text_diff_truncated: '... Ð¢Ð¾Ð·Ð¸ diff Ð½Ðµ Ðµ Ð¿ÑŠÐ»ÐµÐ½, Ð¿Ð¾Ð½ÐµÐ¶Ðµ Ðµ Ð½Ð°Ð´Ñ…Ð²ÑŠÑ€Ð»Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€, ÐºÐ¾Ð¹Ñ‚Ð¾ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½.'
-  text_custom_field_possible_values_info: 'Ð•Ð´Ð½Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚ Ð½Ð° Ñ€ÐµÐ´'
-  text_wiki_page_destroy_question: Ð¢Ð°Ð·Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¸Ð¼Ð° %{descendants} ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸ Ð´ÐµÑ†Ð° Ð¸ descendant(s). ÐšÐ°ÐºÐ²Ð¾ Ð¶ÐµÐ»Ð°ÐµÑ‚Ðµ Ð´Ð° Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ðµ?
-  text_wiki_page_nullify_children: Ð—Ð°Ð¿Ð°Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ñ‚ÐµÐ·Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸ ÐºÐ°Ñ‚Ð¾ ÐºÐ¾Ñ€ÐµÐ½Ð½Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  text_wiki_page_destroy_children: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸Ñ‚Ðµ Ð´ÐµÑ†Ð° Ð¸ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ñ‚ÐµÑ…Ð½Ð¸ descendants
-  text_wiki_page_reassign_children: ÐŸÑ€ÐµÐ½Ð°Ð·Ð½Ð°Ñ‡Ð°Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸Ñ‚Ðµ Ð´ÐµÑ†Ð° Ð½Ð° Ñ‚Ð°Ð·Ð¸ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  text_own_membership_delete_confirmation: "Ð’Ð¸Ðµ ÑÑ‚Ðµ Ð½Ð° Ð¿ÑŠÑ‚ Ð´Ð° Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½ÐµÑ‚Ðµ Ð½ÑÐºÐ¾Ð¸ Ð¸Ð»Ð¸ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð²Ð°ÑˆÐ¸ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¸ Ðµ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ ÑÐ»ÐµÐ´ Ñ‚Ð¾Ð²Ð° Ð´Ð° Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð´Ð° Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ñ‚Ðµ Ñ‚Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚.\nÐ¡Ð¸Ð³ÑƒÑ€ÐµÐ½ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð¸Ñ‚Ðµ?"
-  text_zoom_in: Ð£Ð²ÐµÐ»Ð¸Ñ‡Ð°Ð²Ð°Ð½Ðµ
-  text_zoom_out: ÐÐ°Ð¼Ð°Ð»ÑÐ²Ð°Ð½Ðµ
-  text_warn_on_leaving_unsaved: Ð¡Ñ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° ÑÑŠÐ´ÑŠÑ€Ð¶Ð° Ð½ÐµÐ·Ð°Ð¿Ð¸ÑÐ°Ð½Ð¾ ÑÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ, ÐºÐ¾ÐµÑ‚Ð¾ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð·Ð°Ð³ÑƒÐ±ÐµÐ½Ð¾, Ð°ÐºÐ¾ Ñ Ð½Ð°Ð¿ÑƒÑÐ½ÐµÑ‚Ðµ.
-  text_scm_path_encoding_note: "ÐŸÐ¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ: UTF-8"
-  text_git_repository_note: ÐŸÑ€Ð°Ð·Ð½Ð¾ Ð¸ Ð»Ð¾ÐºÐ°Ð»Ð½Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ (Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€ /gitrepo, c:\gitrepo)
-  text_mercurial_repository_note: Ð›Ð¾ÐºÐ°Ð»Ð½Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ (Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€ /hgrepo, c:\hgrepo)
-  text_scm_command: SCM ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°
-  text_scm_command_version: Ð’ÐµÑ€ÑÐ¸Ñ
-  text_scm_config: ÐœÐ¾Ð¶ÐµÑ‚Ðµ Ð´Ð° ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ñ‚Ðµ SCM ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸Ñ‚Ðµ Ð² config/configuration.yml. Ð—Ð° Ð´Ð° Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ñ‚Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸Ñ‚Ðµ, Ñ€ÐµÑÑ‚Ð°Ñ€Ñ‚Ð¸Ñ€Ð°Ð¹Ñ‚Ðµ Redmine.
-  text_scm_command_not_available: SCM ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð° Ð½Ðµ Ðµ Ð½Ð°Ð»Ð¸Ñ‡Ð½Ð° Ð¸Ð»Ð¸ Ð´Ð¾ÑÑ‚ÑŠÐ¿Ð½Ð°. ÐŸÑ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸ÑÑ‚Ð° Ð² Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¸Ð²Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ».
-
-  default_role_manager: ÐœÐµÐ½Ð¸Ð´Ð¶ÑŠÑ€
-  default_role_developer: Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸Ðº
-  default_role_reporter: ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ñ‰
-  default_tracker_bug: Ð“Ñ€ÐµÑˆÐºÐ°
-  default_tracker_feature: Ð¤ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð°Ð»Ð½Ð¾ÑÑ‚
-  default_tracker_support: ÐŸÐ¾Ð´Ð´Ñ€ÑŠÐ¶ÐºÐ°
-  default_issue_status_new: ÐÐ¾Ð²Ð°
-  default_issue_status_in_progress: Ð˜Ð·Ð¿ÑŠÐ»Ð½ÐµÐ½Ð¸Ðµ
-  default_issue_status_resolved: ÐŸÑ€Ð¸ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°
-  default_issue_status_feedback: ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð° Ð²Ñ€ÑŠÐ·ÐºÐ°
-  default_issue_status_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-  default_issue_status_rejected: ÐžÑ‚Ñ…Ð²ÑŠÑ€Ð»ÐµÐ½Ð°
-  default_doc_category_user: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð·Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ
-  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸Ñ‡ÐµÑÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ
-  default_priority_low: ÐÐ¸ÑÑŠÐº
-  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»ÐµÐ½
-  default_priority_high: Ð’Ð¸ÑÐ¾Ðº
-  default_priority_urgent: Ð¡Ð¿ÐµÑˆÐµÐ½
-  default_priority_immediate: Ð’ÐµÐ´Ð½Ð°Ð³Ð°
-  default_activity_design: Ð”Ð¸Ð·Ð°Ð¹Ð½
-  default_activity_development: Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ°
-
-  enumeration_issue_priorities: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  enumeration_activities: Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚Ð¸ (time tracking)
-  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
-  description_filter: Ð¤Ð¸Ð»Ñ‚ÑŠÑ€
-  description_search: Ð¢ÑŠÑ€ÑÐµÐ½Ðµ
-  description_choose_project: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸
-  description_project_scope: ÐžÐ±Ñ…Ð²Ð°Ñ‚ Ð½Ð° Ñ‚ÑŠÑ€ÑÐµÐ½ÐµÑ‚Ð¾
-  description_notes: Ð‘ÐµÐ»ÐµÐ¶ÐºÐ¸
-  description_message_content: Ð¡ÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸ÐµÑ‚Ð¾
-  description_query_sort_criteria_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð½Ð° ÑÐ¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ
-  description_query_sort_criteria_direction: ÐŸÐ¾ÑÐ¾ÐºÐ° Ð½Ð° ÑÐ¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ
-  description_user_mail_notification: ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¸Ð·Ð²ÐµÑÑ‚Ð¸ÑÑ‚Ð° Ð¿Ð¾ Ð¿Ð¾Ñ‰Ð°Ñ‚Ð°
-  description_available_columns: ÐÐ°Ð»Ð¸Ñ‡Ð½Ð¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸
-  description_selected_columns: Ð˜Ð·Ð±Ñ€Ð°Ð½Ð¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸
-  description_issue_category_reassign: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
-  description_wiki_subpages_reassign: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð½Ð¾Ð²Ð° Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  description_all_columns: Ð’ÑÐ¸Ñ‡ÐºÐ¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸
-  description_date_range_list: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ð¾Ñ‚ ÑÐ¿Ð¸ÑÑŠÐºÐ°
-  description_date_range_interval: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ñ‡Ñ€ÐµÐ· Ð·Ð°Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð½Ð°Ñ‡Ð°Ð»Ð½Ð° Ð¸ ÐºÑ€Ð°Ð¹Ð½Ð° Ð´Ð°Ñ‚Ð¸
-  description_date_from: Ð’ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ Ð½Ð°Ñ‡Ð°Ð»Ð½Ð° Ð´Ð°Ñ‚Ð°
-  description_date_to: Ð’ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ ÐºÑ€Ð°Ð¹Ð½Ð° Ð´Ð°Ñ‚Ð°
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3e/3e69b6e2154a117c66e42d50dd35e274a3a35611.svn-base
--- a/.svn/pristine/3e/3e69b6e2154a117c66e42d50dd35e274a3a35611.svn-base
+++ /dev/null
@@ -1,16 +0,0 @@
-<h2><%=l(:label_confirmation)%></h2>
-<div class="warning">
-<p><strong><%=h @project_to_destroy %></strong><br />
-<%=l(:text_project_destroy_confirmation)%>
-
-<% if @project_to_destroy.descendants.any? %>
-<br /><%= l(:text_subprojects_destroy_warning, content_tag('strong', h(@project_to_destroy.descendants.collect{|p| p.to_s}.join(', ')))) %>
-<% end %>
-</p>
-<p>
-    <% form_tag(project_path(@project_to_destroy), :method => :delete) do %>
-    <label><%= check_box_tag 'confirm', 1 %> <%= l(:general_text_Yes) %></label>
-    <%= submit_tag l(:button_delete) %>
-    <% end %>
-</p>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3e/3ecbdf2b380b8b58c6f31309dfb99930076f3961.svn-base
--- /dev/null
+++ b/.svn/pristine/3e/3ecbdf2b380b8b58c6f31309dfb99930076f3961.svn-base
@@ -0,0 +1,374 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * This file is part of DotClear.
+ * Copyright (c) 2005 Nicolas Martin & Olivier Meunier and contributors. All
+ * rights reserved.
+ *
+ * DotClear is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * DotClear is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with DotClear; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ***** END LICENSE BLOCK *****
+*/
+
+/* Modified by JP LANG for textile formatting */
+
+function jsToolBar(textarea) {
+	if (!document.createElement) { return; }
+	
+	if (!textarea) { return; }
+	
+	if ((typeof(document["selection"]) == "undefined")
+	&& (typeof(textarea["setSelectionRange"]) == "undefined")) {
+		return;
+	}
+	
+	this.textarea = textarea;
+	
+	this.editor = document.createElement('div');
+	this.editor.className = 'jstEditor';
+	
+	this.textarea.parentNode.insertBefore(this.editor,this.textarea);
+	this.editor.appendChild(this.textarea);
+	
+	this.toolbar = document.createElement("div");
+	this.toolbar.className = 'jstElements';
+	this.editor.parentNode.insertBefore(this.toolbar,this.editor);
+	
+	// Dragable resizing
+	if (this.editor.addEventListener && navigator.appVersion.match(/\bMSIE\b/))
+	{
+		this.handle = document.createElement('div');
+		this.handle.className = 'jstHandle';
+		var dragStart = this.resizeDragStart;
+		var This = this;
+		this.handle.addEventListener('mousedown',function(event) { dragStart.call(This,event); },false);
+		// fix memory leak in Firefox (bug #241518)
+		window.addEventListener('unload',function() { 
+				var del = This.handle.parentNode.removeChild(This.handle);
+				delete(This.handle);
+		},false);
+		
+		this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling);
+	}
+	
+	this.context = null;
+	this.toolNodes = {}; // lorsque la toolbar est dessinÃ©e , cet objet est garni 
+					// de raccourcis vers les Ã©lÃ©ments DOM correspondants aux outils.
+}
+
+function jsButton(title, fn, scope, className) {
+    if(typeof jsToolBar.strings == 'undefined') {
+      this.title = title || null;
+    } else {
+      this.title = jsToolBar.strings[title] || title || null;
+    }
+	this.fn = fn || function(){};
+	this.scope = scope || null;
+	this.className = className || null;
+}
+jsButton.prototype.draw = function() {
+	if (!this.scope) return null;
+	
+	var button = document.createElement('button');
+	button.setAttribute('type','button');
+	button.tabIndex = 200;
+	if (this.className) button.className = this.className;
+	button.title = this.title;
+	var span = document.createElement('span');
+	span.appendChild(document.createTextNode(this.title));
+	button.appendChild(span);
+	
+	if (this.icon != undefined) {
+		button.style.backgroundImage = 'url('+this.icon+')';
+	}
+	if (typeof(this.fn) == 'function') {
+		var This = this;
+		button.onclick = function() { try { This.fn.apply(This.scope, arguments) } catch (e) {} return false; };
+	}
+	return button;
+}
+
+function jsSpace(id) {
+	this.id = id || null;
+	this.width = null;
+}
+jsSpace.prototype.draw = function() {
+	var span = document.createElement('span');
+	if (this.id) span.id = this.id;
+	span.appendChild(document.createTextNode(String.fromCharCode(160)));
+	span.className = 'jstSpacer';
+	if (this.width) span.style.marginRight = this.width+'px';
+	
+	return span;
+} 
+
+function jsCombo(title, options, scope, fn, className) {
+	this.title = title || null;
+	this.options = options || null;
+	this.scope = scope || null;
+	this.fn = fn || function(){};
+	this.className = className || null;
+}
+jsCombo.prototype.draw = function() {
+	if (!this.scope || !this.options) return null;
+
+	var select = document.createElement('select');
+	if (this.className) select.className = className;
+	select.title = this.title;
+	
+	for (var o in this.options) {
+		//var opt = this.options[o];
+		var option = document.createElement('option');
+		option.value = o;
+		option.appendChild(document.createTextNode(this.options[o]));
+		select.appendChild(option);
+	}
+
+	var This = this;
+	select.onchange = function() {
+		try { 
+			This.fn.call(This.scope, this.value);
+		} catch (e) { alert(e); }
+
+		return false;
+	}
+
+	return select;
+}
+
+
+jsToolBar.prototype = {
+	base_url: '',
+	mode: 'wiki',
+	elements: {},
+	help_link: '',
+	
+	getMode: function() {
+		return this.mode;
+	},
+	
+	setMode: function(mode) {
+		this.mode = mode || 'wiki';
+	},
+	
+	switchMode: function(mode) {
+		mode = mode || 'wiki';
+		this.draw(mode);
+	},
+	
+	setHelpLink: function(link) {
+		this.help_link = link;
+	},
+	
+	button: function(toolName) {
+		var tool = this.elements[toolName];
+		if (typeof tool.fn[this.mode] != 'function') return null;
+		var b = new jsButton(tool.title, tool.fn[this.mode], this, 'jstb_'+toolName);
+		if (tool.icon != undefined) b.icon = tool.icon;
+		return b;
+	},
+	space: function(toolName) {
+		var tool = new jsSpace(toolName)
+		if (this.elements[toolName].width !== undefined)
+			tool.width = this.elements[toolName].width;
+		return tool;
+	},
+	combo: function(toolName) {
+		var tool = this.elements[toolName];
+		var length = tool[this.mode].list.length;
+
+		if (typeof tool[this.mode].fn != 'function' || length == 0) {
+			return null;
+		} else {
+			var options = {};
+			for (var i=0; i < length; i++) {
+				var opt = tool[this.mode].list[i];
+				options[opt] = tool.options[opt];
+			}
+			return new jsCombo(tool.title, options, this, tool[this.mode].fn);
+		}
+	},
+	draw: function(mode) {
+		this.setMode(mode);
+		
+		// Empty toolbar
+		while (this.toolbar.hasChildNodes()) {
+			this.toolbar.removeChild(this.toolbar.firstChild)
+		}
+		this.toolNodes = {}; // vide les raccourcis DOM/**/
+
+		// Draw toolbar elements
+		var b, tool, newTool;
+		
+		for (var i in this.elements) {
+			b = this.elements[i];
+
+			var disabled =
+			b.type == undefined || b.type == ''
+			|| (b.disabled != undefined && b.disabled)
+			|| (b.context != undefined && b.context != null && b.context != this.context);
+			
+			if (!disabled && typeof this[b.type] == 'function') {
+				tool = this[b.type](i);
+				if (tool) newTool = tool.draw();
+				if (newTool) {
+					this.toolNodes[i] = newTool; //mÃ©morise l'accÃ¨s DOM pour usage Ã©ventuel ultÃ©rieur
+					this.toolbar.appendChild(newTool);
+				}
+			}
+		}
+	},
+	
+	singleTag: function(stag,etag) {
+		stag = stag || null;
+		etag = etag || stag;
+		
+		if (!stag || !etag) { return; }
+		
+		this.encloseSelection(stag,etag);
+	},
+	
+	encloseLineSelection: function(prefix, suffix, fn) {
+		this.textarea.focus();
+		
+		prefix = prefix || '';
+		suffix = suffix || '';
+		
+		var start, end, sel, scrollPos, subst, res;
+		
+		if (typeof(document["selection"]) != "undefined") {
+			sel = document.selection.createRange().text;
+		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
+			start = this.textarea.selectionStart;
+			end = this.textarea.selectionEnd;
+			scrollPos = this.textarea.scrollTop;
+			// go to the start of the line
+			start = this.textarea.value.substring(0, start).replace(/[^\r\n]*$/g,'').length;
+			// go to the end of the line
+            end = this.textarea.value.length - this.textarea.value.substring(end, this.textarea.value.length).replace(/^[^\r\n]*/, '').length;
+			sel = this.textarea.value.substring(start, end);
+		}
+		
+		if (sel.match(/ $/)) { // exclude ending space char, if any
+			sel = sel.substring(0, sel.length - 1);
+			suffix = suffix + " ";
+		}
+		
+		if (typeof(fn) == 'function') {
+			res = (sel) ? fn.call(this,sel) : fn('');
+		} else {
+			res = (sel) ? sel : '';
+		}
+		
+		subst = prefix + res + suffix;
+		
+		if (typeof(document["selection"]) != "undefined") {
+			document.selection.createRange().text = subst;
+			var range = this.textarea.createTextRange();
+			range.collapse(false);
+			range.move('character', -suffix.length);
+			range.select();
+		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
+			this.textarea.value = this.textarea.value.substring(0, start) + subst +
+			this.textarea.value.substring(end);
+			if (sel) {
+				this.textarea.setSelectionRange(start + subst.length, start + subst.length);
+			} else {
+				this.textarea.setSelectionRange(start + prefix.length, start + prefix.length);
+			}
+			this.textarea.scrollTop = scrollPos;
+		}
+	},
+	
+	encloseSelection: function(prefix, suffix, fn) {
+		this.textarea.focus();
+		
+		prefix = prefix || '';
+		suffix = suffix || '';
+		
+		var start, end, sel, scrollPos, subst, res;
+		
+		if (typeof(document["selection"]) != "undefined") {
+			sel = document.selection.createRange().text;
+		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
+			start = this.textarea.selectionStart;
+			end = this.textarea.selectionEnd;
+			scrollPos = this.textarea.scrollTop;
+			sel = this.textarea.value.substring(start, end);
+		}
+		
+		if (sel.match(/ $/)) { // exclude ending space char, if any
+			sel = sel.substring(0, sel.length - 1);
+			suffix = suffix + " ";
+		}
+		
+		if (typeof(fn) == 'function') {
+			res = (sel) ? fn.call(this,sel) : fn('');
+		} else {
+			res = (sel) ? sel : '';
+		}
+		
+		subst = prefix + res + suffix;
+		
+		if (typeof(document["selection"]) != "undefined") {
+			document.selection.createRange().text = subst;
+			var range = this.textarea.createTextRange();
+			range.collapse(false);
+			range.move('character', -suffix.length);
+			range.select();
+//			this.textarea.caretPos -= suffix.length;
+		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
+			this.textarea.value = this.textarea.value.substring(0, start) + subst +
+			this.textarea.value.substring(end);
+			if (sel) {
+				this.textarea.setSelectionRange(start + subst.length, start + subst.length);
+			} else {
+				this.textarea.setSelectionRange(start + prefix.length, start + prefix.length);
+			}
+			this.textarea.scrollTop = scrollPos;
+		}
+	},
+	
+	stripBaseURL: function(url) {
+		if (this.base_url != '') {
+			var pos = url.indexOf(this.base_url);
+			if (pos == 0) {
+				url = url.substr(this.base_url.length);
+			}
+		}
+		
+		return url;
+	}
+};
+
+/** Resizer
+-------------------------------------------------------- */
+jsToolBar.prototype.resizeSetStartH = function() {
+	this.dragStartH = this.textarea.offsetHeight + 0;
+};
+jsToolBar.prototype.resizeDragStart = function(event) {
+	var This = this;
+	this.dragStartY = event.clientY;
+	this.resizeSetStartH();
+	document.addEventListener('mousemove', this.dragMoveHdlr=function(event){This.resizeDragMove(event);}, false);
+	document.addEventListener('mouseup', this.dragStopHdlr=function(event){This.resizeDragStop(event);}, false);
+};
+
+jsToolBar.prototype.resizeDragMove = function(event) {
+	this.textarea.style.height = (this.dragStartH+event.clientY-this.dragStartY)+'px';
+};
+
+jsToolBar.prototype.resizeDragStop = function(event) {
+	document.removeEventListener('mousemove', this.dragMoveHdlr, false);
+	document.removeEventListener('mouseup', this.dragStopHdlr, false);
+};
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3e/3ee3c9a35a260aa80f2513c5c9353b2283428f2c.svn-base
--- /dev/null
+++ b/.svn/pristine/3e/3ee3c9a35a260aa80f2513c5c9353b2283428f2c.svn-base
@@ -0,0 +1,40 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class PatchesTest < ActiveSupport::TestCase
+  include Redmine::I18n
+
+  context "ActiveRecord::Base.human_attribute_name" do
+    setup do
+      Setting.default_language = 'en'
+    end
+
+    should "transform name to field_name" do
+      assert_equal l('field_last_login_on'), ActiveRecord::Base.human_attribute_name('last_login_on')
+    end
+
+    should "cut extra _id suffix for better validation" do
+      assert_equal l('field_last_login_on'), ActiveRecord::Base.human_attribute_name('last_login_on_id')
+    end
+
+    should "default to humanized value if no translation has been found (useful for custom fields)" do
+      assert_equal 'Patch name', ActiveRecord::Base.human_attribute_name('Patch name')
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3e/3efd26febde35f053259781a6842c32aa0085eb7.svn-base
--- a/.svn/pristine/3e/3efd26febde35f053259781a6842c32aa0085eb7.svn-base
+++ /dev/null
@@ -1,144 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class SearchTest < ActiveSupport::TestCase
-  fixtures :users,
-           :members,
-           :member_roles,
-           :projects,
-           :roles,
-           :enabled_modules,
-           :issues,
-           :trackers,
-           :journals,
-           :journal_details,
-           :repositories,
-           :changesets
-
-  def setup
-    @project = Project.find(1)
-    @issue_keyword = '%unable to print recipes%'
-    @issue = Issue.find(1)
-    @changeset_keyword = '%very first commit%'
-    @changeset = Changeset.find(100)
-  end
-
-  def test_search_by_anonymous
-    User.current = nil
-
-    r = Issue.search(@issue_keyword).first
-    assert r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert r.include?(@changeset)
-
-    # Removes the :view_changesets permission from Anonymous role
-    remove_permission Role.anonymous, :view_changesets
-
-    r = Issue.search(@issue_keyword).first
-    assert r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert !r.include?(@changeset)
-
-    # Make the project private
-    @project.update_attribute :is_public, false
-    r = Issue.search(@issue_keyword).first
-    assert !r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert !r.include?(@changeset)
-  end
-
-  def test_search_by_user
-    User.current = User.find_by_login('rhill')
-    assert User.current.memberships.empty?
-
-    r = Issue.search(@issue_keyword).first
-    assert r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert r.include?(@changeset)
-
-    # Removes the :view_changesets permission from Non member role
-    remove_permission Role.non_member, :view_changesets
-
-    r = Issue.search(@issue_keyword).first
-    assert r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert !r.include?(@changeset)
-
-    # Make the project private
-    @project.update_attribute :is_public, false
-    r = Issue.search(@issue_keyword).first
-    assert !r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert !r.include?(@changeset)
-  end
-
-  def test_search_by_allowed_member
-    User.current = User.find_by_login('jsmith')
-    assert User.current.projects.include?(@project)
-
-    r = Issue.search(@issue_keyword).first
-    assert r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert r.include?(@changeset)
-
-    # Make the project private
-    @project.update_attribute :is_public, false
-    r = Issue.search(@issue_keyword).first
-    assert r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert r.include?(@changeset)
-  end
-
-  def test_search_by_unallowed_member
-    # Removes the :view_changesets permission from user's and non member role
-    remove_permission Role.find(1), :view_changesets
-    remove_permission Role.non_member, :view_changesets
-
-    User.current = User.find_by_login('jsmith')
-    assert User.current.projects.include?(@project)
-
-    r = Issue.search(@issue_keyword).first
-    assert r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert !r.include?(@changeset)
-
-    # Make the project private
-    @project.update_attribute :is_public, false
-    r = Issue.search(@issue_keyword).first
-    assert r.include?(@issue)
-    r = Changeset.search(@changeset_keyword).first
-    assert !r.include?(@changeset)
-  end
-
-  def test_search_issue_with_multiple_hits_in_journals
-    i = Issue.find(1)
-    assert_equal 2, i.journals.count(:all, :conditions => "notes LIKE '%notes%'")
-
-    r = Issue.search('%notes%').first
-    assert_equal 1, r.size
-    assert_equal i, r.first
-  end
-
-  private
-
-  def remove_permission(role, permission)
-    role.permissions = role.permissions - [ permission ]
-    role.save
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3f/3f0e8212628d5f669e97d1ba675898fce5586337.svn-base
--- a/.svn/pristine/3f/3f0e8212628d5f669e97d1ba675898fce5586337.svn-base
+++ /dev/null
@@ -1,25 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class LdapAuthSourcesController < AuthSourcesController
-
-  protected
-
-  def auth_source_class
-    AuthSourceLdap
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3f/3f1432f5ae9fdc8b43bfc5b1f1592ae627706799.svn-base
--- a/.svn/pristine/3f/3f1432f5ae9fdc8b43bfc5b1f1592ae627706799.svn-base
+++ /dev/null
@@ -1,48 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class GanttsController < ApplicationController
-  menu_item :gantt
-  before_filter :find_optional_project
-
-  rescue_from Query::StatementInvalid, :with => :query_statement_invalid
-
-  helper :gantt
-  helper :issues
-  helper :projects
-  helper :queries
-  include QueriesHelper
-  helper :sort
-  include SortHelper
-  include Redmine::Export::PDF
-
-  def show
-    @gantt = Redmine::Helpers::Gantt.new(params)
-    @gantt.project = @project
-    retrieve_query
-    @query.group_by = nil
-    @gantt.query = @query if @query.valid?
-
-    basename = (@project ? "#{@project.identifier}-" : '') + 'gantt'
-
-    respond_to do |format|
-      format.html { render :action => "show", :layout => !request.xhr? }
-      format.png  { send_data(@gantt.to_image, :disposition => 'inline', :type => 'image/png', :filename => "#{basename}.png") } if @gantt.respond_to?('to_image')
-      format.pdf  { send_data(@gantt.to_pdf, :type => 'application/pdf', :filename => "#{basename}.pdf") }
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3f/3f7e33eb719b73cf1721b389cca78ecdef336acd.svn-base
--- /dev/null
+++ b/.svn/pristine/3f/3f7e33eb719b73cf1721b389cca78ecdef336acd.svn-base
@@ -0,0 +1,46 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module JournalsHelper
+  def render_notes(issue, journal, options={})
+    content = ''
+    editable = User.current.logged? && (User.current.allowed_to?(:edit_issue_notes, issue.project) || (journal.user == User.current && User.current.allowed_to?(:edit_own_issue_notes, issue.project)))
+    links = []
+    if !journal.notes.blank?
+      links << link_to(image_tag('comment.png'),
+                       {:controller => 'journals', :action => 'new', :id => issue, :journal_id => journal},
+                       :remote => true,
+                       :method => 'post',
+                       :title => l(:button_quote)) if options[:reply_links]
+      links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
+                                             { :controller => 'journals', :action => 'edit', :id => journal, :format => 'js' },
+                                                :title => l(:button_edit)) if editable
+    end
+    content << content_tag('div', links.join(' ').html_safe, :class => 'contextual') unless links.empty?
+    content << textilizable(journal, :notes)
+    css_classes = "wiki"
+    css_classes << " editable" if editable
+    content_tag('div', content.html_safe, :id => "journal-#{journal.id}-notes", :class => css_classes)
+  end
+
+  def link_to_in_place_notes_editor(text, field_id, url, options={})
+    onclick = "$.ajax({url: '#{url_for(url)}', type: 'get'}); return false;"
+    link_to text, '#', options.merge(:onclick => onclick)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3f/3fac3fc235a53c2e2d4d021dffb9a965b1506411.svn-base
--- /dev/null
+++ b/.svn/pristine/3f/3fac3fc235a53c2e2d4d021dffb9a965b1506411.svn-base
@@ -0,0 +1,9 @@
+class AddQueriesType < ActiveRecord::Migration
+  def up
+    add_column :queries, :type, :string
+  end
+
+  def down
+    remove_column :queries, :type
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/3f/3ff64c6f7b8c7d1560b577e6e864916cca4fbd1d.svn-base
--- a/.svn/pristine/3f/3ff64c6f7b8c7d1560b577e6e864916cca4fbd1d.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/process/inspector'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/40/4020a77b0d5d691da1ac32e725f8f600aff372b8.svn-base
--- a/.svn/pristine/40/4020a77b0d5d691da1ac32e725f8f600aff372b8.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<h2><%= class_name %>#<%= action %></h2>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/40/4038e83eefe53cf4e2ba6b2f10fddf413b1d2edb.svn-base
--- a/.svn/pristine/40/4038e83eefe53cf4e2ba6b2f10fddf413b1d2edb.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-// ** I18N
-
-// Calendar GL (galician) language
-// Author: MartÃ­n VÃ¡zquez Cabanas, <eu@martinvazquez.net>
-// Updated: 2009-01-23
-// Encoding: utf-8
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Domingo",
- "Luns",
- "Martes",
- "MÃ©rcores",
- "Xoves",
- "Venres",
- "SÃ¡bado",
- "Domingo");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Dom",
- "Lun",
- "Mar",
- "MÃ©r",
- "Xov",
- "Ven",
- "SÃ¡b",
- "Dom");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Xaneiro",
- "Febreiro",
- "Marzo",
- "Abril",
- "Maio",
- "XuÃ±o",
- "Xullo",
- "Agosto",
- "Setembro",
- "Outubro",
- "Novembro",
- "Decembro");
-
-// short month names
-Calendar._SMN = new Array
-("Xan",
- "Feb",
- "Mar",
- "Abr",
- "Mai",
- "Xun",
- "Xull",
- "Ago",
- "Set",
- "Out",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Acerca do calendario";
-
-Calendar._TT["ABOUT"] =
-"Selector DHTML de Data/Hora\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"Para conseguila Ãºltima versiÃ³n visite: http://www.dynarch.com/projects/calendar/\n" +
-"DistribuÃ­do baixo licenza GNU LGPL. Visite http://gnu.org/licenses/lgpl.html para mÃ¡is detalles." +
-"\n\n" +
-"SelecciÃ³n de data:\n" +
-"- Use os botÃ³ns \xab, \xbb para seleccionalo ano\n" +
-"- Use os botÃ³ns " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para seleccionalo mes\n" +
-"- ManteÃ±a pulsado o rato en calquera destes botÃ³ns para unha selecciÃ³n rÃ¡pida.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"SelecciÃ³n de hora:\n" +
-"- Pulse en calquera das partes da hora para incrementala\n" +
-"- ou pulse maiÃºsculas mentres fai clic para decrementala\n" +
-"- ou faga clic e arrastre o rato para unha selecciÃ³n mÃ¡is rÃ¡pida.";
-
-Calendar._TT["PREV_YEAR"] = "Ano anterior (manter para menÃº)";
-Calendar._TT["PREV_MONTH"] = "Mes anterior (manter para menÃº)";
-Calendar._TT["GO_TODAY"] = "Ir a hoxe";
-Calendar._TT["NEXT_MONTH"] = "Mes seguinte (manter para menÃº)";
-Calendar._TT["NEXT_YEAR"] = "Ano seguinte (manter para menÃº)";
-Calendar._TT["SEL_DATE"] = "Seleccionar data";
-Calendar._TT["DRAG_TO_MOVE"] = "Arrastrar para mover";
-Calendar._TT["PART_TODAY"] = " (hoxe)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Facer %s primeiro dÃ­a da semana";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Pechar";
-Calendar._TT["TODAY"] = "Hoxe";
-Calendar._TT["TIME_PART"] = "(MaiÃºscula-)Clic ou arrastre para cambiar valor";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%A, %e de %B de %Y";
-
-Calendar._TT["WK"] = "sem";
-Calendar._TT["TIME"] = "Hora:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/40/40689c0c3542244c3df167e6c12a7f9af9376e9b.svn-base
--- /dev/null
+++ b/.svn/pristine/40/40689c0c3542244c3df167e6c12a7f9af9376e9b.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module DocumentsHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/40/406f7b24c26c10e7c0b7a7dfc884f38ff3b10cd2.svn-base
--- a/.svn/pristine/40/406f7b24c26c10e7c0b7a7dfc884f38ff3b10cd2.svn-base
+++ /dev/null
@@ -1,383 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'SVG/Graph/Bar'
-require 'SVG/Graph/BarHorizontal'
-require 'digest/sha1'
-
-class ChangesetNotFound < Exception; end
-class InvalidRevisionParam < Exception; end
-
-class RepositoriesController < ApplicationController
-  menu_item :repository
-  menu_item :settings, :only => :edit
-  default_search_scope :changesets
-
-  before_filter :find_repository, :except => :edit
-  before_filter :find_project, :only => :edit
-  before_filter :authorize
-  accept_rss_auth :revisions
-
-  rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed
-
-  def edit
-    @repository = @project.repository
-    if !@repository && !params[:repository_scm].blank?
-      @repository = Repository.factory(params[:repository_scm])
-      @repository.project = @project if @repository
-    end
-    if request.post? && @repository
-      p1 = params[:repository]
-      p       = {}
-      p_extra = {}
-      p1.each do |k, v|
-        if k =~ /^extra_/
-          p_extra[k] = v
-        else
-          p[k] = v
-        end
-      end
-      @repository.attributes = p
-      @repository.merge_extra_info(p_extra)
-      @repository.save
-    end
-    render(:update) do |page|
-      page.replace_html "tab-content-repository",
-                        :partial => 'projects/settings/repository'
-      if @repository && !@project.repository
-        @project.reload # needed to reload association
-        page.replace_html "main-menu", render_main_menu(@project)
-      end
-    end
-  end
-
-  def committers
-    @committers = @repository.committers
-    @users = @project.users
-    additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
-    @users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty?
-    @users.compact!
-    @users.sort!
-    if request.post? && params[:committers].is_a?(Hash)
-      # Build a hash with repository usernames as keys and corresponding user ids as values
-      @repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h}
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'committers', :id => @project
-    end
-  end
-
-  def destroy
-    @repository.destroy
-    redirect_to :controller => 'projects',
-                :action     => 'settings',
-                :id         => @project,
-                :tab        => 'repository'
-  end
-
-  def show
-    @repository.fetch_changesets if Setting.autofetch_changesets? && @path.empty?
-
-    @entries = @repository.entries(@path, @rev)
-    @changeset = @repository.find_changeset_by_name(@rev)
-    if request.xhr?
-      @entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
-    else
-      (show_error_not_found; return) unless @entries
-      @changesets = @repository.latest_changesets(@path, @rev)
-      @properties = @repository.properties(@path, @rev)
-      render :action => 'show'
-    end
-  end
-
-  alias_method :browse, :show
-
-  def changes
-    @entry = @repository.entry(@path, @rev)
-    (show_error_not_found; return) unless @entry
-    @changesets = @repository.latest_changesets(@path, @rev, Setting.repository_log_display_limit.to_i)
-    @properties = @repository.properties(@path, @rev)
-    @changeset = @repository.find_changeset_by_name(@rev)
-  end
-
-  def revisions
-    @changeset_count = @repository.changesets.count
-    @changeset_pages = Paginator.new self, @changeset_count,
-                                     per_page_option,
-                                     params['page']
-    @changesets = @repository.changesets.find(:all,
-                       :limit  =>  @changeset_pages.items_per_page,
-                       :offset =>  @changeset_pages.current.offset,
-                       :include => [:user, :repository, :parents])
-
-    respond_to do |format|
-      format.html { render :layout => false if request.xhr? }
-      format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
-    end
-  end
-
-  def entry
-    @entry = @repository.entry(@path, @rev)
-    (show_error_not_found; return) unless @entry
-
-    # If the entry is a dir, show the browser
-    (show; return) if @entry.is_dir?
-
-    @content = @repository.cat(@path, @rev)
-    (show_error_not_found; return) unless @content
-    if 'raw' == params[:format] ||
-         (@content.size && @content.size > Setting.file_max_size_displayed.to_i.kilobyte) ||
-         ! is_entry_text_data?(@content, @path)
-      # Force the download
-      send_opt = { :filename => filename_for_content_disposition(@path.split('/').last) }
-      send_type = Redmine::MimeType.of(@path)
-      send_opt[:type] = send_type.to_s if send_type
-      send_data @content, send_opt
-    else
-      # Prevent empty lines when displaying a file with Windows style eol
-      # TODO: UTF-16
-      # Is this needs? AttachmentsController reads file simply.
-      @content.gsub!("\r\n", "\n")
-      @changeset = @repository.find_changeset_by_name(@rev)
-    end
-  end
-
-  def is_entry_text_data?(ent, path)
-    # UTF-16 contains "\x00".
-    # It is very strict that file contains less than 30% of ascii symbols
-    # in non Western Europe.
-    return true if Redmine::MimeType.is_type?('text', path)
-    # Ruby 1.8.6 has a bug of integer divisions.
-    # http://apidock.com/ruby/v1_8_6_287/String/is_binary_data%3F
-    return false if ent.is_binary_data?
-    true
-  end
-  private :is_entry_text_data?
-
-  def annotate
-    @entry = @repository.entry(@path, @rev)
-    (show_error_not_found; return) unless @entry
-
-    @annotate = @repository.scm.annotate(@path, @rev)
-    if @annotate.nil? || @annotate.empty?
-      (render_error l(:error_scm_annotate); return)
-    end
-    ann_buf_size = 0
-    @annotate.lines.each do |buf|
-      ann_buf_size += buf.size
-    end
-    if ann_buf_size > Setting.file_max_size_displayed.to_i.kilobyte
-      (render_error l(:error_scm_annotate_big_text_file); return)
-    end
-    @changeset = @repository.find_changeset_by_name(@rev)
-  end
-
-  def revision
-    raise ChangesetNotFound if @rev.blank?
-    @changeset = @repository.find_changeset_by_name(@rev)
-    raise ChangesetNotFound unless @changeset
-
-    respond_to do |format|
-      format.html
-      format.js {render :layout => false}
-    end
-  rescue ChangesetNotFound
-    show_error_not_found
-  end
-
-  def diff
-    if params[:format] == 'diff'
-      @diff = @repository.diff(@path, @rev, @rev_to)
-      (show_error_not_found; return) unless @diff
-      filename = "changeset_r#{@rev}"
-      filename << "_r#{@rev_to}" if @rev_to
-      send_data @diff.join, :filename => "#{filename}.diff",
-                            :type => 'text/x-patch',
-                            :disposition => 'attachment'
-    else
-      @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
-      @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
-
-      # Save diff type as user preference
-      if User.current.logged? && @diff_type != User.current.pref[:diff_type]
-        User.current.pref[:diff_type] = @diff_type
-        User.current.preference.save
-      end
-      @cache_key = "repositories/diff/#{@repository.id}/" +
-                      Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}-#{current_language}")
-      unless read_fragment(@cache_key)
-        @diff = @repository.diff(@path, @rev, @rev_to)
-        show_error_not_found unless @diff
-      end
-
-      @changeset = @repository.find_changeset_by_name(@rev)
-      @changeset_to = @rev_to ? @repository.find_changeset_by_name(@rev_to) : nil
-      @diff_format_revisions = @repository.diff_format_revisions(@changeset, @changeset_to)
-    end
-  end
-
-  def stats
-  end
-
-  def graph
-    data = nil
-    case params[:graph]
-    when "commits_per_month"
-      data = graph_commits_per_month(@repository)
-    when "commits_per_author"
-      data = graph_commits_per_author(@repository)
-    end
-    if data
-      headers["Content-Type"] = "image/svg+xml"
-      send_data(data, :type => "image/svg+xml", :disposition => "inline")
-    else
-      render_404
-    end
-  end
-
-  private
-
-  REV_PARAM_RE = %r{\A[a-f0-9]*\Z}i
-
-  def find_repository
-    @project = Project.find(params[:id])
-    @repository = @project.repository
-    (render_404; return false) unless @repository
-    @path = params[:path].join('/') unless params[:path].nil?
-    @path ||= ''
-    @rev = params[:rev].blank? ? @repository.default_branch : params[:rev].to_s.strip
-    @rev_to = params[:rev_to]
-
-    unless @rev.to_s.match(REV_PARAM_RE) && @rev_to.to_s.match(REV_PARAM_RE)
-      if @repository.branches.blank?
-        raise InvalidRevisionParam
-      end
-    end
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  rescue InvalidRevisionParam
-    show_error_not_found
-  end
-
-  def show_error_not_found
-    render_error :message => l(:error_scm_not_found), :status => 404
-  end
-
-  # Handler for Redmine::Scm::Adapters::CommandFailed exception
-  def show_error_command_failed(exception)
-    render_error l(:error_scm_command_failed, exception.message)
-  end
-
-  def graph_commits_per_month(repository)
-    @date_to = Date.today
-    @date_from = @date_to << 11
-    @date_from = Date.civil(@date_from.year, @date_from.month, 1)
-    commits_by_day = repository.changesets.count(
-                          :all, :group => :commit_date,
-                          :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
-    commits_by_month = [0] * 12
-    commits_by_day.each {|c| commits_by_month[c.first.to_date.months_ago] += c.last }
-
-    changes_by_day = repository.changes.count(
-                          :all, :group => :commit_date,
-                          :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
-    changes_by_month = [0] * 12
-    changes_by_day.each {|c| changes_by_month[c.first.to_date.months_ago] += c.last }
-
-    fields = []
-    12.times {|m| fields << month_name(((Date.today.month - 1 - m) % 12) + 1)}
-
-    graph = SVG::Graph::Bar.new(
-      :height => 300,
-      :width => 800,
-      :fields => fields.reverse,
-      :stack => :side,
-      :scale_integers => true,
-      :step_x_labels => 2,
-      :show_data_values => false,
-      :graph_title => l(:label_commits_per_month),
-      :show_graph_title => true
-    )
-
-    graph.add_data(
-      :data => commits_by_month[0..11].reverse,
-      :title => l(:label_revision_plural)
-    )
-
-    graph.add_data(
-      :data => changes_by_month[0..11].reverse,
-      :title => l(:label_change_plural)
-    )
-
-    graph.burn
-  end
-
-  def graph_commits_per_author(repository)
-    commits_by_author = repository.changesets.count(:all, :group => :committer)
-    commits_by_author.to_a.sort! {|x, y| x.last <=> y.last}
-
-    changes_by_author = repository.changes.count(:all, :group => :committer)
-    h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o}
-
-    fields = commits_by_author.collect {|r| r.first}
-    commits_data = commits_by_author.collect {|r| r.last}
-    changes_data = commits_by_author.collect {|r| h[r.first] || 0}
-
-    fields = fields + [""]*(10 - fields.length) if fields.length<10
-    commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10
-    changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10
-
-    # Remove email adress in usernames
-    fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
-
-    graph = SVG::Graph::BarHorizontal.new(
-      :height => 400,
-      :width => 800,
-      :fields => fields,
-      :stack => :side,
-      :scale_integers => true,
-      :show_data_values => false,
-      :rotate_y_labels => false,
-      :graph_title => l(:label_commits_per_author),
-      :show_graph_title => true
-    )
-    graph.add_data(
-      :data => commits_data,
-      :title => l(:label_revision_plural)
-    )
-    graph.add_data(
-      :data => changes_data,
-      :title => l(:label_change_plural)
-    )
-    graph.burn
-  end
-end
-
-class Date
-  def months_ago(date = Date.today)
-    (date.year - self.year)*12 + (date.month - self.month)
-  end
-
-  def weeks_ago(date = Date.today)
-    (date.year - self.year)*52 + (date.cweek - self.cweek)
-  end
-end
-
-class String
-  def with_leading_slash
-    starts_with?('/') ? self : "/#{self}"
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/40/407f7e2d4e08a32e78ca65cbc6b2ee007be59736.svn-base
--- /dev/null
+++ b/.svn/pristine/40/407f7e2d4e08a32e78ca65cbc6b2ee007be59736.svn-base
@@ -0,0 +1,73 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class WorkflowRule < ActiveRecord::Base
+  self.table_name = "#{table_name_prefix}workflows#{table_name_suffix}"
+
+  belongs_to :role
+  belongs_to :tracker
+  belongs_to :old_status, :class_name => 'IssueStatus', :foreign_key => 'old_status_id'
+  belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
+
+  validates_presence_of :role, :tracker, :old_status
+
+  # Copies workflows from source to targets
+  def self.copy(source_tracker, source_role, target_trackers, target_roles)
+    unless source_tracker.is_a?(Tracker) || source_role.is_a?(Role)
+      raise ArgumentError.new("source_tracker or source_role must be specified")
+    end
+
+    target_trackers = [target_trackers].flatten.compact
+    target_roles = [target_roles].flatten.compact
+
+    target_trackers = Tracker.sorted.all if target_trackers.empty?
+    target_roles = Role.all if target_roles.empty?
+
+    target_trackers.each do |target_tracker|
+      target_roles.each do |target_role|
+        copy_one(source_tracker || target_tracker,
+                   source_role || target_role,
+                   target_tracker,
+                   target_role)
+      end
+    end
+  end
+
+  # Copies a single set of workflows from source to target
+  def self.copy_one(source_tracker, source_role, target_tracker, target_role)
+    unless source_tracker.is_a?(Tracker) && !source_tracker.new_record? &&
+      source_role.is_a?(Role) && !source_role.new_record? &&
+      target_tracker.is_a?(Tracker) && !target_tracker.new_record? &&
+      target_role.is_a?(Role) && !target_role.new_record?
+
+      raise ArgumentError.new("arguments can not be nil or unsaved objects")
+    end
+
+    if source_tracker == target_tracker && source_role == target_role
+      false
+    else
+      transaction do
+        delete_all :tracker_id => target_tracker.id, :role_id => target_role.id
+        connection.insert "INSERT INTO #{WorkflowRule.table_name} (tracker_id, role_id, old_status_id, new_status_id, author, assignee, field_name, #{connection.quote_column_name 'rule'}, type)" +
+                          " SELECT #{target_tracker.id}, #{target_role.id}, old_status_id, new_status_id, author, assignee, field_name, #{connection.quote_column_name 'rule'}, type" +
+                          " FROM #{WorkflowRule.table_name}" +
+                          " WHERE tracker_id = #{source_tracker.id} AND role_id = #{source_role.id}"
+      end
+      true
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/40/40d857531cd6b4668cb1e019211d87ead6d54850.svn-base
--- a/.svn/pristine/40/40d857531cd6b4668cb1e019211d87ead6d54850.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-require 'test/unit'
-
-$VERBOSE = $CODERAY_DEBUG = true
-$:.unshift File.expand_path('../../../lib', __FILE__)
-require 'coderay'
-
-mydir = File.dirname(__FILE__)
-suite = Dir[File.join(mydir, '*.rb')].
-  map { |tc| File.basename(tc).sub(/\.rb$/, '') } - %w'suite for_redcloth'
-
-puts "Running basic CodeRay #{CodeRay::VERSION} tests: #{suite.join(', ')}"
-
-for test_case in suite
-  load File.join(mydir, test_case + '.rb')
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/40/40fb7c915312a0bec722da5f4b2c6582d58a02b9.svn-base
--- a/.svn/pristine/40/40fb7c915312a0bec722da5f4b2c6582d58a02b9.svn-base
+++ /dev/null
@@ -1,174 +0,0 @@
-require 'active_support'
-require File.join(File.dirname(__FILE__), 'engines/plugin')
-require File.join(File.dirname(__FILE__), 'engines/plugin/list')
-require File.join(File.dirname(__FILE__), 'engines/plugin/loader')
-require File.join(File.dirname(__FILE__), 'engines/plugin/locator')
-require File.join(File.dirname(__FILE__), 'engines/assets')
-require File.join(File.dirname(__FILE__), 'engines/rails_extensions/rails')
-
-# == Parameters
-#
-# The Engines module has a number of public configuration parameters:
-#
-# [+public_directory+]  The directory into which plugin assets should be
-#                       mirrored. Defaults to <tt>RAILS_ROOT/public/plugin_assets</tt>.
-# [+schema_info_table+] The table to use when storing plugin migration 
-#                       version information. Defaults to +plugin_schema_info+.
-#
-# Additionally, there are a few flags which control the behaviour of
-# some of the features the engines plugin adds to Rails:
-#
-# [+disable_application_view_loading+] A boolean flag determining whether
-#                                      or not views should be loaded from 
-#                                      the main <tt>app/views</tt> directory.
-#                                      Defaults to false; probably only 
-#                                      useful when testing your plugin.
-# [+disable_application_code_loading+] A boolean flag determining whether
-#                                      or not to load controllers/helpers 
-#                                      from the main +app+ directory,
-#                                      if corresponding code exists within 
-#                                      a plugin. Defaults to false; again, 
-#                                      probably only useful when testing 
-#                                      your plugin.
-# [+disable_code_mixing+] A boolean flag indicating whether all plugin
-#                         copies of a particular controller/helper should 
-#                         be loaded and allowed to override each other, 
-#                         or if the first matching file should be loaded 
-#                         instead. Defaults to false.
-#
-module Engines
-  # The set of all loaded plugins
-  mattr_accessor :plugins
-  self.plugins = Engines::Plugin::List.new  
-  
-  # List of extensions to load, can be changed in init.rb before calling Engines.init
-  mattr_accessor :rails_extensions
-  self.rails_extensions = %w(asset_helpers form_tag_helpers migrations dependencies)
-  
-  # The name of the public directory to mirror public engine assets into.
-  # Defaults to <tt>RAILS_ROOT/public/plugin_assets</tt>.
-  mattr_accessor :public_directory
-  self.public_directory = File.join(RAILS_ROOT, 'public', 'plugin_assets')
-
-  # The table in which to store plugin schema information. Defaults to
-  # "plugin_schema_info".
-  mattr_accessor :schema_info_table
-  self.schema_info_table = "plugin_schema_info"
-
-  #--
-  # These attributes control the behaviour of the engines extensions
-  #++
-  
-  # Set this to true if views should *only* be loaded from plugins
-  mattr_accessor :disable_application_view_loading
-  self.disable_application_view_loading = false
-  
-  # Set this to true if controller/helper code shouldn't be loaded 
-  # from the application
-  mattr_accessor :disable_application_code_loading
-  self.disable_application_code_loading = false
-  
-  # Set this to true if code should not be mixed (i.e. it will be loaded
-  # from the first valid path on $LOAD_PATH)
-  mattr_accessor :disable_code_mixing
-  self.disable_code_mixing = false
-  
-  # This is used to determine which files are candidates for the "code
-  # mixing" feature that the engines plugin provides, where classes from
-  # plugins can be loaded, and then code from the application loaded
-  # on top of that code to override certain methods.
-  mattr_accessor :code_mixing_file_types
-  self.code_mixing_file_types = %w(controller helper)
-  
-  class << self
-    def init(initializer)
-      load_extensions
-      Engines::Assets.initialize_base_public_directory
-    end
-    
-    def logger
-      RAILS_DEFAULT_LOGGER
-    end
-    
-    def load_extensions
-      rails_extensions.each { |name| require "engines/rails_extensions/#{name}" }
-      # load the testing extensions, if we are in the test environment.
-      require "engines/testing" if RAILS_ENV == "test"
-    end
-    
-    def select_existing_paths(paths)
-      paths.select { |path| File.directory?(path) }
-    end  
-  
-    # The engines plugin will, by default, mix code from controllers and helpers,
-    # allowing application code to override specific methods in the corresponding
-    # controller or helper classes and modules. However, if other file types should
-    # also be mixed like this, they can be added by calling this method. For example,
-    # if you want to include "things" within your plugin and override them from
-    # your applications, you should use the following layout:
-    #
-    #   app/
-    #    +-- things/
-    #    |       +-- one_thing.rb
-    #    |       +-- another_thing.rb
-    #   ...
-    #   vendor/
-    #       +-- plugins/
-    #                +-- my_plugin/
-    #                           +-- app/
-    #                                +-- things/
-    #                                        +-- one_thing.rb
-    #                                        +-- another_thing.rb
-    #
-    # The important point here is that your "things" are named <whatever>_thing.rb,
-    # and that they are placed within plugin/app/things (the pluralized form of 'thing').
-    # 
-    # It's important to note that you'll also want to ensure that the "things" are
-    # on your load path by including them in Rails load path mechanism, e.g. in init.rb:
-    #
-    #  ActiveSupport::Dependencies.load_paths << File.join(File.dirname(__FILE__), 'app', 'things'))
-    #
-    def mix_code_from(*types)
-      self.code_mixing_file_types += types.map { |x| x.to_s.singularize }
-    end
-    
-    # A general purpose method to mirror a directory (+source+) into a destination
-    # directory, including all files and subdirectories. Files will not be mirrored
-    # if they are identical already (checked via FileUtils#identical?).
-    def mirror_files_from(source, destination)
-      return unless File.directory?(source)
-      
-      # TODO: use Rake::FileList#pathmap?    
-      source_files = Dir[source + "/**/*"]
-      source_dirs = source_files.select { |d| File.directory?(d) }
-      source_files -= source_dirs
-      
-      unless source_files.empty?
-        base_target_dir = File.join(destination, File.dirname(source_files.first).gsub(source, ''))
-        FileUtils.mkdir_p(base_target_dir)
-      end
-      
-      source_dirs.each do |dir|
-        # strip down these paths so we have simple, relative paths we can
-        # add to the destination
-        target_dir = File.join(destination, dir.gsub(source, ''))
-        begin        
-          FileUtils.mkdir_p(target_dir)
-        rescue Exception => e
-          raise "Could not create directory #{target_dir}: \n" + e
-        end
-      end
-      
-      source_files.each do |file|
-        begin
-          target = File.join(destination, file.gsub(source, ''))
-          unless File.exist?(target) && FileUtils.identical?(file, target)
-            FileUtils.cp(file, target)
-          end 
-        rescue Exception => e
-          raise "Could not copy #{file} to #{target}: \n" + e 
-        end
-      end  
-    end   
-  end  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/41/413080d862dfb1417751d3ce6800014b0d3f9e36.svn-base
--- a/.svn/pristine/41/413080d862dfb1417751d3ce6800014b0d3f9e36.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class JournalObserverTest < ActiveSupport::TestCase
-  fixtures :issues, :issue_statuses, :journals, :journal_details
-
-  def setup
-    ActionMailer::Base.deliveries.clear
-    @journal = Journal.find 1
-  end
-
-  # context: issue_updated notified_events
-  def test_create_should_send_email_notification_with_issue_updated
-    Setting.notified_events = ['issue_updated']
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    journal = issue.init_journal(user, issue)
-
-    assert journal.save
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_create_should_not_send_email_notification_with_notify_set_to_false
-    Setting.notified_events = ['issue_updated']
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    journal = issue.init_journal(user, issue)
-    journal.notify = false
-
-    assert journal.save
-    assert_equal 0, ActionMailer::Base.deliveries.size
-  end
-
-  def test_create_should_not_send_email_notification_without_issue_updated
-    Setting.notified_events = []
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    journal = issue.init_journal(user, issue)
-
-    assert journal.save
-    assert_equal 0, ActionMailer::Base.deliveries.size
-  end
-
-  # context: issue_note_added notified_events
-  def test_create_should_send_email_notification_with_issue_note_added
-    Setting.notified_events = ['issue_note_added']
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    journal = issue.init_journal(user, issue)
-    journal.notes = 'This update has a note'
-
-    assert journal.save
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_create_should_not_send_email_notification_without_issue_note_added
-    Setting.notified_events = []
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    journal = issue.init_journal(user, issue)
-    journal.notes = 'This update has a note'
-
-    assert journal.save
-    assert_equal 0, ActionMailer::Base.deliveries.size
-  end
-
-  # context: issue_status_updated notified_events
-  def test_create_should_send_email_notification_with_issue_status_updated
-    Setting.notified_events = ['issue_status_updated']
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    issue.init_journal(user, issue)
-    issue.status = IssueStatus.last
-
-    assert issue.save
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_create_should_not_send_email_notification_without_issue_status_updated
-    Setting.notified_events = []
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    issue.init_journal(user, issue)
-    issue.status = IssueStatus.last
-
-    assert issue.save
-    assert_equal 0, ActionMailer::Base.deliveries.size
-  end
-
-  # context: issue_priority_updated notified_events
-  def test_create_should_send_email_notification_with_issue_priority_updated
-    Setting.notified_events = ['issue_priority_updated']
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    issue.init_journal(user, issue)
-    issue.priority = IssuePriority.last
-
-    assert issue.save
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_create_should_not_send_email_notification_without_issue_priority_updated
-    Setting.notified_events = []
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    issue.init_journal(user, issue)
-    issue.priority = IssuePriority.last
-
-    assert issue.save
-    assert_equal 0, ActionMailer::Base.deliveries.size
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/41/414d847bcbb5d1b481c5b6e074d2d95ff30c291d.svn-base
--- /dev/null
+++ b/.svn/pristine/41/414d847bcbb5d1b481c5b6e074d2d95ff30c291d.svn-base
@@ -0,0 +1,29 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class UsersTest < ActionController::IntegrationTest
+  fixtures :users
+
+  def test_destroy_should_not_accept_get_requests
+    assert_no_difference 'User.count' do
+      get '/users/destroy/2', {}, credentials('admin')
+      assert_response 404
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/41/41666c76b3a63b119e23476dd87dae257e309108.svn-base
--- /dev/null
+++ b/.svn/pristine/41/41666c76b3a63b119e23476dd87dae257e309108.svn-base
@@ -0,0 +1,111 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class NewsController < ApplicationController
+  default_search_scope :news
+  model_object News
+  before_filter :find_model_object, :except => [:new, :create, :index]
+  before_filter :find_project_from_association, :except => [:new, :create, :index]
+  before_filter :find_project_by_project_id, :only => [:new, :create]
+  before_filter :authorize, :except => [:index]
+  before_filter :find_optional_project, :only => :index
+  accept_rss_auth :index
+  accept_api_auth :index
+
+  helper :watchers
+  helper :attachments
+
+  def index
+    case params[:format]
+    when 'xml', 'json'
+      @offset, @limit = api_offset_and_limit
+    else
+      @limit =  10
+    end
+
+    scope = @project ? @project.news.visible : News.visible
+
+    @news_count = scope.count
+    @news_pages = Paginator.new @news_count, @limit, params['page']
+    @offset ||= @news_pages.offset
+    @newss = scope.all(:include => [:author, :project],
+                                       :order => "#{News.table_name}.created_on DESC",
+                                       :offset => @offset,
+                                       :limit => @limit)
+
+    respond_to do |format|
+      format.html {
+        @news = News.new # for adding news inline
+        render :layout => false if request.xhr?
+      }
+      format.api
+      format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") }
+    end
+  end
+
+  def show
+    @comments = @news.comments
+    @comments.reverse! if User.current.wants_comments_in_reverse_order?
+  end
+
+  def new
+    @news = News.new(:project => @project, :author => User.current)
+  end
+
+  def create
+    @news = News.new(:project => @project, :author => User.current)
+    @news.safe_attributes = params[:news]
+    @news.save_attachments(params[:attachments])
+    if @news.save
+      render_attachment_warning_if_needed(@news)
+      flash[:notice] = l(:notice_successful_create)
+      redirect_to project_news_index_path(@project)
+    else
+      render :action => 'new'
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    @news.safe_attributes = params[:news]
+    @news.save_attachments(params[:attachments])
+    if @news.save
+      render_attachment_warning_if_needed(@news)
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to news_path(@news)
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def destroy
+    @news.destroy
+    redirect_to project_news_index_path(@project)
+  end
+
+  private
+
+  def find_optional_project
+    return true unless params[:project_id]
+    @project = Project.find(params[:project_id])
+    authorize
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/41/4171661e14f170beefe360373ffc236afc3efe66.svn-base
--- /dev/null
+++ b/.svn/pristine/41/4171661e14f170beefe360373ffc236afc3efe66.svn-base
@@ -0,0 +1,101 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class ActivitiesHelperTest < ActionView::TestCase
+  include ActivitiesHelper
+
+  class MockEvent
+    attr_reader :event_datetime, :event_group, :name
+
+    def initialize(group=nil)
+      @@count ||= 0
+      @name = "e#{@@count}"
+      @event_datetime = Time.now + @@count.hours
+      @event_group = group || self
+      @@count += 1
+    end
+
+    def self.clear
+      @@count = 0
+    end
+  end
+
+  def setup
+    MockEvent.clear
+  end
+
+  def test_sort_activity_events_should_sort_by_datetime
+    events = []
+    events << MockEvent.new
+    events << MockEvent.new
+    events << MockEvent.new
+
+    assert_equal [
+        ['e2', false],
+        ['e1', false],
+        ['e0', false]
+      ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
+  end
+
+  def test_sort_activity_events_should_group_events
+    events = []
+    events << MockEvent.new
+    events << MockEvent.new(events[0])
+    events << MockEvent.new(events[0])
+
+    assert_equal [
+        ['e2', false],
+        ['e1', true],
+        ['e0', true]
+      ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
+  end
+
+  def test_sort_activity_events_with_group_not_in_set_should_group_events
+    e = MockEvent.new
+    events = []
+    events << MockEvent.new(e)
+    events << MockEvent.new(e)
+
+    assert_equal [
+        ['e2', false],
+        ['e1', true]
+      ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
+  end
+
+  def test_sort_activity_events_should_sort_by_datetime_and_group
+    events = []
+    events << MockEvent.new
+    events << MockEvent.new
+    events << MockEvent.new
+    events << MockEvent.new(events[1])
+    events << MockEvent.new(events[2])
+    events << MockEvent.new
+    events << MockEvent.new(events[2])
+
+    assert_equal [
+        ['e6', false],
+        ['e4', true],
+        ['e2', true],
+        ['e5', false],
+        ['e3', false],
+        ['e1', true],
+        ['e0', false]
+      ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/41/41bb9cc50bdf02df6fa0e55ba5d0a45d87f52436.svn-base
--- /dev/null
+++ b/.svn/pristine/41/41bb9cc50bdf02df6fa0e55ba5d0a45d87f52436.svn-base
@@ -0,0 +1,182 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueRelation < ActiveRecord::Base
+  # Class used to represent the relations of an issue
+  class Relations < Array
+    include Redmine::I18n
+
+    def initialize(issue, *args)
+      @issue = issue
+      super(*args)
+    end
+
+    def to_s(*args)
+      map {|relation| "#{l(relation.label_for(@issue))} ##{relation.other_issue(@issue).id}"}.join(', ')
+    end
+  end
+
+  belongs_to :issue_from, :class_name => 'Issue', :foreign_key => 'issue_from_id'
+  belongs_to :issue_to, :class_name => 'Issue', :foreign_key => 'issue_to_id'
+
+  TYPE_RELATES      = "relates"
+  TYPE_DUPLICATES   = "duplicates"
+  TYPE_DUPLICATED   = "duplicated"
+  TYPE_BLOCKS       = "blocks"
+  TYPE_BLOCKED      = "blocked"
+  TYPE_PRECEDES     = "precedes"
+  TYPE_FOLLOWS      = "follows"
+  TYPE_COPIED_TO    = "copied_to"
+  TYPE_COPIED_FROM  = "copied_from"
+
+  TYPES = {
+    TYPE_RELATES =>     { :name => :label_relates_to, :sym_name => :label_relates_to,
+                          :order => 1, :sym => TYPE_RELATES },
+    TYPE_DUPLICATES =>  { :name => :label_duplicates, :sym_name => :label_duplicated_by,
+                          :order => 2, :sym => TYPE_DUPLICATED },
+    TYPE_DUPLICATED =>  { :name => :label_duplicated_by, :sym_name => :label_duplicates,
+                          :order => 3, :sym => TYPE_DUPLICATES, :reverse => TYPE_DUPLICATES },
+    TYPE_BLOCKS =>      { :name => :label_blocks, :sym_name => :label_blocked_by,
+                          :order => 4, :sym => TYPE_BLOCKED },
+    TYPE_BLOCKED =>     { :name => :label_blocked_by, :sym_name => :label_blocks,
+                          :order => 5, :sym => TYPE_BLOCKS, :reverse => TYPE_BLOCKS },
+    TYPE_PRECEDES =>    { :name => :label_precedes, :sym_name => :label_follows,
+                          :order => 6, :sym => TYPE_FOLLOWS },
+    TYPE_FOLLOWS =>     { :name => :label_follows, :sym_name => :label_precedes,
+                          :order => 7, :sym => TYPE_PRECEDES, :reverse => TYPE_PRECEDES },
+    TYPE_COPIED_TO =>   { :name => :label_copied_to, :sym_name => :label_copied_from,
+                          :order => 8, :sym => TYPE_COPIED_FROM },
+    TYPE_COPIED_FROM => { :name => :label_copied_from, :sym_name => :label_copied_to,
+                          :order => 9, :sym => TYPE_COPIED_TO, :reverse => TYPE_COPIED_TO }
+  }.freeze
+
+  validates_presence_of :issue_from, :issue_to, :relation_type
+  validates_inclusion_of :relation_type, :in => TYPES.keys
+  validates_numericality_of :delay, :allow_nil => true
+  validates_uniqueness_of :issue_to_id, :scope => :issue_from_id
+  validate :validate_issue_relation
+
+  attr_protected :issue_from_id, :issue_to_id
+  before_save :handle_issue_order
+
+  def visible?(user=User.current)
+    (issue_from.nil? || issue_from.visible?(user)) && (issue_to.nil? || issue_to.visible?(user))
+  end
+
+  def deletable?(user=User.current)
+    visible?(user) &&
+      ((issue_from.nil? || user.allowed_to?(:manage_issue_relations, issue_from.project)) ||
+        (issue_to.nil? || user.allowed_to?(:manage_issue_relations, issue_to.project)))
+  end
+
+  def initialize(attributes=nil, *args)
+    super
+    if new_record?
+      if relation_type.blank?
+        self.relation_type = IssueRelation::TYPE_RELATES
+      end
+    end
+  end
+
+  def validate_issue_relation
+    if issue_from && issue_to
+      errors.add :issue_to_id, :invalid if issue_from_id == issue_to_id
+      unless issue_from.project_id == issue_to.project_id ||
+                Setting.cross_project_issue_relations?
+        errors.add :issue_to_id, :not_same_project
+      end
+      # detect circular dependencies depending wether the relation should be reversed
+      if TYPES.has_key?(relation_type) && TYPES[relation_type][:reverse]
+        errors.add :base, :circular_dependency if issue_from.all_dependent_issues.include? issue_to
+      else
+        errors.add :base, :circular_dependency if issue_to.all_dependent_issues.include? issue_from
+      end
+      if issue_from.is_descendant_of?(issue_to) || issue_from.is_ancestor_of?(issue_to)
+        errors.add :base, :cant_link_an_issue_with_a_descendant
+      end
+    end
+  end
+
+  def other_issue(issue)
+    (self.issue_from_id == issue.id) ? issue_to : issue_from
+  end
+
+  # Returns the relation type for +issue+
+  def relation_type_for(issue)
+    if TYPES[relation_type]
+      if self.issue_from_id == issue.id
+        relation_type
+      else
+        TYPES[relation_type][:sym]
+      end
+    end
+  end
+
+  def label_for(issue)
+    TYPES[relation_type] ?
+        TYPES[relation_type][(self.issue_from_id == issue.id) ? :name : :sym_name] :
+        :unknow
+  end
+
+  def css_classes_for(issue)
+    "rel-#{relation_type_for(issue)}"
+  end
+
+  def handle_issue_order
+    reverse_if_needed
+
+    if TYPE_PRECEDES == relation_type
+      self.delay ||= 0
+    else
+      self.delay = nil
+    end
+    set_issue_to_dates
+  end
+
+  def set_issue_to_dates
+    soonest_start = self.successor_soonest_start
+    if soonest_start && issue_to
+      issue_to.reschedule_on!(soonest_start)
+    end
+  end
+
+  def successor_soonest_start
+    if (TYPE_PRECEDES == self.relation_type) && delay && issue_from &&
+           (issue_from.start_date || issue_from.due_date)
+      (issue_from.due_date || issue_from.start_date) + 1 + delay
+    end
+  end
+
+  def <=>(relation)
+    r = TYPES[self.relation_type][:order] <=> TYPES[relation.relation_type][:order]
+    r == 0 ? id <=> relation.id : r
+  end
+
+  private
+
+  # Reverses the relation if needed so that it gets stored in the proper way
+  # Should not be reversed before validation so that it can be displayed back
+  # as entered on new relation form
+  def reverse_if_needed
+    if TYPES.has_key?(relation_type) && TYPES[relation_type][:reverse]
+      issue_tmp = issue_to
+      self.issue_to = issue_from
+      self.issue_from = issue_tmp
+      self.relation_type = TYPES[relation_type][:reverse]
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/42/42065d6686eb12e9679c9132fc4c1d7b2537270b.svn-base
--- a/.svn/pristine/42/42065d6686eb12e9679c9132fc4c1d7b2537270b.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-xml.instruct!
-xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
-  xml.title   @title
-  xml.link    "rel" => "self", "href" => url_for(:format => 'atom', :key => User.current.rss_key, :only_path => false)
-  xml.link    "rel" => "alternate", "href" => home_url(:only_path => false)
-  xml.id      url_for(:controller => 'welcome', :only_path => false)
-  xml.updated((@journals.first ? @journals.first.event_datetime : Time.now).xmlschema)
-  xml.author  { xml.name "#{Setting.app_title}" }
-  @journals.each do |change|
-    issue = change.issue
-    xml.entry do
-      xml.title   "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
-      xml.link    "rel" => "alternate", "href" => url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
-      xml.id      url_for(:controller => 'issues' , :action => 'show', :id => issue, :journal_id => change, :only_path => false)
-      xml.updated change.created_on.xmlschema
-      xml.author do
-        xml.name change.user.name
-        xml.email(change.user.mail) if change.user.is_a?(User) && !change.user.mail.blank? && !change.user.pref.hide_mail
-      end
-      xml.content "type" => "html" do
-        xml.text! '<ul>'
-        change.details.each do |detail|
-          xml.text! '<li>' + show_detail(detail, false) + '</li>'
-        end
-        xml.text! '</ul>'
-        xml.text! textilizable(change, :notes, :only_path => false) unless change.notes.blank?
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/42/4222efb8f989394cbc29df18dfb204374b8d5e79.svn-base
--- /dev/null
+++ b/.svn/pristine/42/4222efb8f989394cbc29df18dfb204374b8d5e79.svn-base
@@ -0,0 +1,97 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::NewsTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :news
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "GET /news" do
+    context ".xml" do
+      should "return news" do
+        get '/news.xml'
+
+        assert_tag :tag => 'news',
+          :attributes => {:type => 'array'},
+          :child => {
+            :tag => 'news',
+            :child => {
+              :tag => 'id',
+              :content => '2'
+            }
+          }
+      end
+    end
+
+    context ".json" do
+      should "return news" do
+        get '/news.json'
+
+        json = ActiveSupport::JSON.decode(response.body)
+        assert_kind_of Hash, json
+        assert_kind_of Array, json['news']
+        assert_kind_of Hash, json['news'].first
+        assert_equal 2, json['news'].first['id']
+      end
+    end
+  end
+
+  context "GET /projects/:project_id/news" do
+    context ".xml" do
+      should_allow_api_authentication(:get, "/projects/onlinestore/news.xml")
+
+      should "return news" do
+        get '/projects/ecookbook/news.xml'
+
+        assert_tag :tag => 'news',
+          :attributes => {:type => 'array'},
+          :child => {
+            :tag => 'news',
+            :child => {
+              :tag => 'id',
+              :content => '2'
+            }
+          }
+      end
+    end
+
+    context ".json" do
+      should_allow_api_authentication(:get, "/projects/onlinestore/news.json")
+
+      should "return news" do
+        get '/projects/ecookbook/news.json'
+
+        json = ActiveSupport::JSON.decode(response.body)
+        assert_kind_of Hash, json
+        assert_kind_of Array, json['news']
+        assert_kind_of Hash, json['news'].first
+        assert_equal 2, json['news'].first['id']
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/42/427b264a64a6d9342fb25880cb15db8377d4ab62.svn-base
--- a/.svn/pristine/42/427b264a64a6d9342fb25880cb15db8377d4ab62.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-<%= l(:text_issue_added, :id => "##{@issue.id}", :author => h(@issue.author)) %>
-<hr />
-<%= render :partial => "issue.html.erb", :locals => { :issue => @issue, :issue_url => @issue_url } %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/42/427c435973b09320d012f4a307265921e2e2fd84.svn-base
--- a/.svn/pristine/42/427c435973b09320d012f4a307265921e2e2fd84.svn-base
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/perl
-#
-# redMine is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-# modify to suit your repository base
-my $repos_base = '/var/svn';
-
-my $path = '/usr/bin/';
-my %kwown_commands = map { $_ => 1 } qw/svnserve/;
-
-umask 0002;
-
-exec ('/usr/bin/svnserve', '-r', $repos_base, '-t');
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/42/428612395d9016270f63f32ed9dffa1b755e4922.svn-base
--- a/.svn/pristine/42/428612395d9016270f63f32ed9dffa1b755e4922.svn-base
+++ /dev/null
@@ -1,960 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Issue < ActiveRecord::Base
-  include Redmine::SafeAttributes
-
-  belongs_to :project
-  belongs_to :tracker
-  belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
-  belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
-  belongs_to :assigned_to, :class_name => 'Principal', :foreign_key => 'assigned_to_id'
-  belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
-  belongs_to :priority, :class_name => 'IssuePriority', :foreign_key => 'priority_id'
-  belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
-
-  has_many :journals, :as => :journalized, :dependent => :destroy
-  has_many :time_entries, :dependent => :delete_all
-  has_and_belongs_to_many :changesets, :order => "#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC"
-
-  has_many :relations_from, :class_name => 'IssueRelation', :foreign_key => 'issue_from_id', :dependent => :delete_all
-  has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all
-
-  acts_as_nested_set :scope => 'root_id', :dependent => :destroy
-  acts_as_attachable :after_add => :attachment_added, :after_remove => :attachment_removed
-  acts_as_customizable
-  acts_as_watchable
-  acts_as_searchable :columns => ['subject', "#{table_name}.description", "#{Journal.table_name}.notes"],
-                     :include => [:project, :journals],
-                     # sort by id so that limited eager loading doesn't break with postgresql
-                     :order_column => "#{table_name}.id"
-  acts_as_event :title => Proc.new {|o| "#{o.tracker.name} ##{o.id} (#{o.status}): #{o.subject}"},
-                :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.id}},
-                :type => Proc.new {|o| 'issue' + (o.closed? ? ' closed' : '') }
-
-  acts_as_activity_provider :find_options => {:include => [:project, :author, :tracker]},
-                            :author_key => :author_id
-
-  DONE_RATIO_OPTIONS = %w(issue_field issue_status)
-
-  attr_reader :current_journal
-
-  validates_presence_of :subject, :priority, :project, :tracker, :author, :status
-
-  validates_length_of :subject, :maximum => 255
-  validates_inclusion_of :done_ratio, :in => 0..100
-  validates_numericality_of :estimated_hours, :allow_nil => true
-  validate :validate_issue
-
-  named_scope :visible, lambda {|*args| { :include => :project,
-                                          :conditions => Issue.visible_condition(args.shift || User.current, *args) } }
-
-  named_scope :open, :conditions => ["#{IssueStatus.table_name}.is_closed = ?", false], :include => :status
-
-  named_scope :recently_updated, :order => "#{Issue.table_name}.updated_on DESC"
-  named_scope :with_limit, lambda { |limit| { :limit => limit} }
-  named_scope :on_active_project, :include => [:status, :project, :tracker],
-                                  :conditions => ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"]
-
-  named_scope :without_version, lambda {
-    {
-      :conditions => { :fixed_version_id => nil}
-    }
-  }
-
-  named_scope :with_query, lambda {|query|
-    {
-      :conditions => Query.merge_conditions(query.statement)
-    }
-  }
-
-  before_create :default_assign
-  before_save :close_duplicates, :update_done_ratio_from_issue_status
-  after_save :reschedule_following_issues, :update_nested_set_attributes, :update_parent_attributes, :create_journal
-  after_destroy :update_parent_attributes
-
-  # Returns a SQL conditions string used to find all issues visible by the specified user
-  def self.visible_condition(user, options={})
-    Project.allowed_to_condition(user, :view_issues, options) do |role, user|
-      case role.issues_visibility
-      when 'all'
-        nil
-      when 'default'
-        user_ids = [user.id] + user.groups.map(&:id)
-        "(#{table_name}.is_private = #{connection.quoted_false} OR #{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))"
-      when 'own'
-        user_ids = [user.id] + user.groups.map(&:id)
-        "(#{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))"
-      else
-        '1=0'
-      end
-    end
-  end
-
-  # Returns true if usr or current user is allowed to view the issue
-  def visible?(usr=nil)
-    (usr || User.current).allowed_to?(:view_issues, self.project) do |role, user|
-      case role.issues_visibility
-      when 'all'
-        true
-      when 'default'
-        !self.is_private? || self.author == user || user.is_or_belongs_to?(assigned_to)
-      when 'own'
-        self.author == user || user.is_or_belongs_to?(assigned_to)
-      else
-        false
-      end
-    end
-  end
-
-  def after_initialize
-    if new_record?
-      # set default values for new records only
-      self.status ||= IssueStatus.default
-      self.priority ||= IssuePriority.default
-    end
-  end
-
-  # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
-  def available_custom_fields
-    (project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : []
-  end
-
-  def copy_from(arg)
-    issue = arg.is_a?(Issue) ? arg : Issue.visible.find(arg)
-    self.attributes = issue.attributes.dup.except("id", "root_id", "parent_id", "lft", "rgt", "created_on", "updated_on")
-    self.custom_field_values = issue.custom_field_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
-    self.status = issue.status
-    self
-  end
-
-  # Moves/copies an issue to a new project and tracker
-  # Returns the moved/copied issue on success, false on failure
-  def move_to_project(*args)
-    ret = Issue.transaction do
-      move_to_project_without_transaction(*args) || raise(ActiveRecord::Rollback)
-    end || false
-  end
-
-  def move_to_project_without_transaction(new_project, new_tracker = nil, options = {})
-    options ||= {}
-    issue = options[:copy] ? self.class.new.copy_from(self) : self
-
-    if new_project && issue.project_id != new_project.id
-      # delete issue relations
-      unless Setting.cross_project_issue_relations?
-        issue.relations_from.clear
-        issue.relations_to.clear
-      end
-      # issue is moved to another project
-      # reassign to the category with same name if any
-      new_category = issue.category.nil? ? nil : new_project.issue_categories.find_by_name(issue.category.name)
-      issue.category = new_category
-      # Keep the fixed_version if it's still valid in the new_project
-      unless new_project.shared_versions.include?(issue.fixed_version)
-        issue.fixed_version = nil
-      end
-      issue.project = new_project
-      if issue.parent && issue.parent.project_id != issue.project_id
-        issue.parent_issue_id = nil
-      end
-    end
-    if new_tracker
-      issue.tracker = new_tracker
-      issue.reset_custom_values!
-    end
-    if options[:copy]
-      issue.author = User.current
-      issue.custom_field_values = self.custom_field_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
-      issue.status = if options[:attributes] && options[:attributes][:status_id]
-                       IssueStatus.find_by_id(options[:attributes][:status_id])
-                     else
-                       self.status
-                     end
-    end
-    # Allow bulk setting of attributes on the issue
-    if options[:attributes]
-      issue.attributes = options[:attributes]
-    end
-    if issue.save
-      if options[:copy]
-        if current_journal && current_journal.notes.present?
-          issue.init_journal(current_journal.user, current_journal.notes)
-          issue.current_journal.notify = false
-          issue.save
-        end
-      else
-        # Manually update project_id on related time entries
-        TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id})
-
-        issue.children.each do |child|
-          unless child.move_to_project_without_transaction(new_project)
-            # Move failed and transaction was rollback'd
-            return false
-          end
-        end
-      end
-    else
-      return false
-    end
-    issue
-  end
-
-  def status_id=(sid)
-    self.status = nil
-    write_attribute(:status_id, sid)
-  end
-
-  def priority_id=(pid)
-    self.priority = nil
-    write_attribute(:priority_id, pid)
-  end
-
-  def tracker_id=(tid)
-    self.tracker = nil
-    result = write_attribute(:tracker_id, tid)
-    @custom_field_values = nil
-    result
-  end
-
-  def description=(arg)
-    if arg.is_a?(String)
-      arg = arg.gsub(/(\r\n|\n|\r)/, "\r\n")
-    end
-    write_attribute(:description, arg)
-  end
-
-  # Overrides attributes= so that tracker_id gets assigned first
-  def attributes_with_tracker_first=(new_attributes, *args)
-    return if new_attributes.nil?
-    new_tracker_id = new_attributes['tracker_id'] || new_attributes[:tracker_id]
-    if new_tracker_id
-      self.tracker_id = new_tracker_id
-    end
-    send :attributes_without_tracker_first=, new_attributes, *args
-  end
-  # Do not redefine alias chain on reload (see #4838)
-  alias_method_chain(:attributes=, :tracker_first) unless method_defined?(:attributes_without_tracker_first=)
-
-  def estimated_hours=(h)
-    write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
-  end
-
-  safe_attributes 'tracker_id',
-    'status_id',
-    'parent_issue_id',
-    'category_id',
-    'assigned_to_id',
-    'priority_id',
-    'fixed_version_id',
-    'subject',
-    'description',
-    'start_date',
-    'due_date',
-    'done_ratio',
-    'estimated_hours',
-    'custom_field_values',
-    'custom_fields',
-    'lock_version',
-    :if => lambda {|issue, user| issue.new_record? || user.allowed_to?(:edit_issues, issue.project) }
-
-  safe_attributes 'status_id',
-    'assigned_to_id',
-    'fixed_version_id',
-    'done_ratio',
-    :if => lambda {|issue, user| issue.new_statuses_allowed_to(user).any? }
-
-  safe_attributes 'is_private',
-    :if => lambda {|issue, user|
-      user.allowed_to?(:set_issues_private, issue.project) ||
-        (issue.author == user && user.allowed_to?(:set_own_issues_private, issue.project))
-    }
-
-  # Safely sets attributes
-  # Should be called from controllers instead of #attributes=
-  # attr_accessible is too rough because we still want things like
-  # Issue.new(:project => foo) to work
-  # TODO: move workflow/permission checks from controllers to here
-  def safe_attributes=(attrs, user=User.current)
-    return unless attrs.is_a?(Hash)
-
-    # User can change issue attributes only if he has :edit permission or if a workflow transition is allowed
-    attrs = delete_unsafe_attributes(attrs, user)
-    return if attrs.empty?
-
-    # Tracker must be set before since new_statuses_allowed_to depends on it.
-    if t = attrs.delete('tracker_id')
-      self.tracker_id = t
-    end
-
-    if attrs['status_id']
-      unless new_statuses_allowed_to(user).collect(&:id).include?(attrs['status_id'].to_i)
-        attrs.delete('status_id')
-      end
-    end
-
-    unless leaf?
-      attrs.reject! {|k,v| %w(priority_id done_ratio start_date due_date estimated_hours).include?(k)}
-    end
-
-    if attrs.has_key?('parent_issue_id')
-      if !user.allowed_to?(:manage_subtasks, project)
-        attrs.delete('parent_issue_id')
-      elsif !attrs['parent_issue_id'].blank?
-        attrs.delete('parent_issue_id') unless Issue.visible(user).exists?(attrs['parent_issue_id'].to_i)
-      end
-    end
-
-    self.attributes = attrs
-  end
-
-  def done_ratio
-    if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
-      status.default_done_ratio
-    else
-      read_attribute(:done_ratio)
-    end
-  end
-
-  def self.use_status_for_done_ratio?
-    Setting.issue_done_ratio == 'issue_status'
-  end
-
-  def self.use_field_for_done_ratio?
-    Setting.issue_done_ratio == 'issue_field'
-  end
-
-  def validate_issue
-    if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
-      errors.add :due_date, :not_a_date
-    end
-
-    if self.due_date and self.start_date and self.due_date < self.start_date
-      errors.add :due_date, :greater_than_start_date
-    end
-
-    if start_date && soonest_start && start_date < soonest_start
-      errors.add :start_date, :invalid
-    end
-
-    if fixed_version
-      if !assignable_versions.include?(fixed_version)
-        errors.add :fixed_version_id, :inclusion
-      elsif reopened? && fixed_version.closed?
-        errors.add :base, I18n.t(:error_can_not_reopen_issue_on_closed_version)
-      end
-    end
-
-    # Checks that the issue can not be added/moved to a disabled tracker
-    if project && (tracker_id_changed? || project_id_changed?)
-      unless project.trackers.include?(tracker)
-        errors.add :tracker_id, :inclusion
-      end
-    end
-
-    # Checks parent issue assignment
-    if @parent_issue
-      if @parent_issue.project_id != project_id
-        errors.add :parent_issue_id, :not_same_project
-      elsif !new_record?
-        # moving an existing issue
-        if @parent_issue.root_id != root_id
-          # we can always move to another tree
-        elsif move_possible?(@parent_issue)
-          # move accepted inside tree
-        else
-          errors.add :parent_issue_id, :not_a_valid_parent
-        end
-      end
-    end
-  end
-
-  # Set the done_ratio using the status if that setting is set.  This will keep the done_ratios
-  # even if the user turns off the setting later
-  def update_done_ratio_from_issue_status
-    if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
-      self.done_ratio = status.default_done_ratio
-    end
-  end
-
-  def init_journal(user, notes = "")
-    @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
-    @issue_before_change = self.clone
-    @issue_before_change.status = self.status
-    @custom_values_before_change = {}
-    self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
-    # Make sure updated_on is updated when adding a note.
-    updated_on_will_change!
-    @current_journal
-  end
-
-  # Return true if the issue is closed, otherwise false
-  def closed?
-    self.status.is_closed?
-  end
-
-  # Return true if the issue is being reopened
-  def reopened?
-    if !new_record? && status_id_changed?
-      status_was = IssueStatus.find_by_id(status_id_was)
-      status_new = IssueStatus.find_by_id(status_id)
-      if status_was && status_new && status_was.is_closed? && !status_new.is_closed?
-        return true
-      end
-    end
-    false
-  end
-
-  # Return true if the issue is being closed
-  def closing?
-    if !new_record? && status_id_changed?
-      status_was = IssueStatus.find_by_id(status_id_was)
-      status_new = IssueStatus.find_by_id(status_id)
-      if status_was && status_new && !status_was.is_closed? && status_new.is_closed?
-        return true
-      end
-    end
-    false
-  end
-
-  # Returns true if the issue is overdue
-  def overdue?
-    !due_date.nil? && (due_date < Date.today) && !status.is_closed?
-  end
-
-  # Is the amount of work done less than it should for the due date
-  def behind_schedule?
-    return false if start_date.nil? || due_date.nil?
-    done_date = start_date + ((due_date - start_date+1)* done_ratio/100).floor
-    return done_date <= Date.today
-  end
-
-  # Does this issue have children?
-  def children?
-    !leaf?
-  end
-
-  # Users the issue can be assigned to
-  def assignable_users
-    users = project.assignable_users
-    users << author if author
-    users << assigned_to if assigned_to
-    users.uniq.sort
-  end
-
-  # Versions that the issue can be assigned to
-  def assignable_versions
-    @assignable_versions ||= (project.shared_versions.open + [Version.find_by_id(fixed_version_id_was)]).compact.uniq.sort
-  end
-
-  # Returns true if this issue is blocked by another issue that is still open
-  def blocked?
-    !relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil?
-  end
-
-  # Returns an array of status that user is able to apply
-  def new_statuses_allowed_to(user, include_default=false)
-    statuses = status.find_new_statuses_allowed_to(
-      user.roles_for_project(project),
-      tracker,
-      author == user,
-      assigned_to_id_changed? ? assigned_to_id_was == user.id : assigned_to_id == user.id
-      )
-    statuses << status unless statuses.empty?
-    statuses << IssueStatus.default if include_default
-    statuses = statuses.uniq.sort
-    blocked? ? statuses.reject {|s| s.is_closed?} : statuses
-  end
-
-  # Returns the mail adresses of users that should be notified
-  def recipients
-    notified = project.notified_users
-    # Author and assignee are always notified unless they have been
-    # locked or don't want to be notified
-    notified << author if author && author.active? && author.notify_about?(self)
-    if assigned_to
-      if assigned_to.is_a?(Group)
-        notified += assigned_to.users.select {|u| u.active? && u.notify_about?(self)}
-      else
-        notified << assigned_to if assigned_to.active? && assigned_to.notify_about?(self)
-      end
-    end
-    notified.uniq!
-    # Remove users that can not view the issue
-    notified.reject! {|user| !visible?(user)}
-    notified.collect(&:mail)
-  end
-
-  # Returns the total number of hours spent on this issue and its descendants
-  #
-  # Example:
-  #   spent_hours => 0.0
-  #   spent_hours => 50.2
-  def spent_hours
-    @spent_hours ||= self_and_descendants.sum("#{TimeEntry.table_name}.hours", :include => :time_entries).to_f || 0.0
-  end
-
-  def relations
-    @relations ||= (relations_from + relations_to).sort
-  end
-
-  # Preloads relations for a collection of issues
-  def self.load_relations(issues)
-    if issues.any?
-      relations = IssueRelation.all(:conditions => ["issue_from_id IN (:ids) OR issue_to_id IN (:ids)", {:ids => issues.map(&:id)}])
-      issues.each do |issue|
-        issue.instance_variable_set "@relations", relations.select {|r| r.issue_from_id == issue.id || r.issue_to_id == issue.id}
-      end
-    end
-  end
-
-  # Finds an issue relation given its id.
-  def find_relation(relation_id)
-    IssueRelation.find(relation_id, :conditions => ["issue_to_id = ? OR issue_from_id = ?", id, id])
-  end
-
-  def all_dependent_issues(except=[])
-    except << self
-    dependencies = []
-    relations_from.each do |relation|
-      if relation.issue_to && !except.include?(relation.issue_to)
-        dependencies << relation.issue_to
-        dependencies += relation.issue_to.all_dependent_issues(except)
-      end
-    end
-    dependencies
-  end
-
-  # Returns an array of issues that duplicate this one
-  def duplicates
-    relations_to.select {|r| r.relation_type == IssueRelation::TYPE_DUPLICATES}.collect {|r| r.issue_from}
-  end
-
-  # Returns the due date or the target due date if any
-  # Used on gantt chart
-  def due_before
-    due_date || (fixed_version ? fixed_version.effective_date : nil)
-  end
-
-  # Returns the time scheduled for this issue.
-  #
-  # Example:
-  #   Start Date: 2/26/09, End Date: 3/04/09
-  #   duration => 6
-  def duration
-    (start_date && due_date) ? due_date - start_date : 0
-  end
-
-  def soonest_start
-    @soonest_start ||= (
-        relations_to.collect{|relation| relation.successor_soonest_start} +
-        ancestors.collect(&:soonest_start)
-      ).compact.max
-  end
-
-  def reschedule_after(date)
-    return if date.nil?
-    if leaf?
-      if start_date.nil? || start_date < date
-        self.start_date, self.due_date = date, date + duration
-        save
-      end
-    else
-      leaves.each do |leaf|
-        leaf.reschedule_after(date)
-      end
-    end
-  end
-
-  def <=>(issue)
-    if issue.nil?
-      -1
-    elsif root_id != issue.root_id
-      (root_id || 0) <=> (issue.root_id || 0)
-    else
-      (lft || 0) <=> (issue.lft || 0)
-    end
-  end
-
-  def to_s
-    "#{tracker} ##{id}: #{subject}"
-  end
-
-  # Returns a string of css classes that apply to the issue
-  def css_classes
-    s = "issue status-#{status.position} priority-#{priority.position}"
-    s << ' closed' if closed?
-    s << ' overdue' if overdue?
-    s << ' child' if child?
-    s << ' parent' unless leaf?
-    s << ' private' if is_private?
-    s << ' created-by-me' if User.current.logged? && author_id == User.current.id
-    s << ' assigned-to-me' if User.current.logged? && assigned_to_id == User.current.id
-    s
-  end
-
-  # Saves an issue, time_entry, attachments, and a journal from the parameters
-  # Returns false if save fails
-  def save_issue_with_child_records(params, existing_time_entry=nil)
-    Issue.transaction do
-      if params[:time_entry] && (params[:time_entry][:hours].present? || params[:time_entry][:comments].present?) && User.current.allowed_to?(:log_time, project)
-        @time_entry = existing_time_entry || TimeEntry.new
-        @time_entry.project = project
-        @time_entry.issue = self
-        @time_entry.user = User.current
-        @time_entry.spent_on = User.current.today
-        @time_entry.attributes = params[:time_entry]
-        self.time_entries << @time_entry
-      end
-
-      if valid?
-        attachments = Attachment.attach_files(self, params[:attachments])
-        # TODO: Rename hook
-        Redmine::Hook.call_hook(:controller_issues_edit_before_save, { :params => params, :issue => self, :time_entry => @time_entry, :journal => @current_journal})
-        begin
-          if save
-            # TODO: Rename hook
-            Redmine::Hook.call_hook(:controller_issues_edit_after_save, { :params => params, :issue => self, :time_entry => @time_entry, :journal => @current_journal})
-          else
-            raise ActiveRecord::Rollback
-          end
-        rescue ActiveRecord::StaleObjectError
-          attachments[:files].each(&:destroy)
-          errors.add :base, l(:notice_locking_conflict)
-          raise ActiveRecord::Rollback
-        end
-      end
-    end
-  end
-
-  # Unassigns issues from +version+ if it's no longer shared with issue's project
-  def self.update_versions_from_sharing_change(version)
-    # Update issues assigned to the version
-    update_versions(["#{Issue.table_name}.fixed_version_id = ?", version.id])
-  end
-
-  # Unassigns issues from versions that are no longer shared
-  # after +project+ was moved
-  def self.update_versions_from_hierarchy_change(project)
-    moved_project_ids = project.self_and_descendants.reload.collect(&:id)
-    # Update issues of the moved projects and issues assigned to a version of a moved project
-    Issue.update_versions(["#{Version.table_name}.project_id IN (?) OR #{Issue.table_name}.project_id IN (?)", moved_project_ids, moved_project_ids])
-  end
-
-  def parent_issue_id=(arg)
-    parent_issue_id = arg.blank? ? nil : arg.to_i
-    if parent_issue_id && @parent_issue = Issue.find_by_id(parent_issue_id)
-      @parent_issue.id
-    else
-      @parent_issue = nil
-      nil
-    end
-  end
-
-  def parent_issue_id
-    if instance_variable_defined? :@parent_issue
-      @parent_issue.nil? ? nil : @parent_issue.id
-    else
-      parent_id
-    end
-  end
-
-  # Extracted from the ReportsController.
-  def self.by_tracker(project)
-    count_and_group_by(:project => project,
-                       :field => 'tracker_id',
-                       :joins => Tracker.table_name)
-  end
-
-  def self.by_version(project)
-    count_and_group_by(:project => project,
-                       :field => 'fixed_version_id',
-                       :joins => Version.table_name)
-  end
-
-  def self.by_priority(project)
-    count_and_group_by(:project => project,
-                       :field => 'priority_id',
-                       :joins => IssuePriority.table_name)
-  end
-
-  def self.by_category(project)
-    count_and_group_by(:project => project,
-                       :field => 'category_id',
-                       :joins => IssueCategory.table_name)
-  end
-
-  def self.by_assigned_to(project)
-    count_and_group_by(:project => project,
-                       :field => 'assigned_to_id',
-                       :joins => User.table_name)
-  end
-
-  def self.by_author(project)
-    count_and_group_by(:project => project,
-                       :field => 'author_id',
-                       :joins => User.table_name)
-  end
-
-  def self.by_subproject(project)
-    ActiveRecord::Base.connection.select_all("select    s.id as status_id, 
-                                                s.is_closed as closed, 
-                                                #{Issue.table_name}.project_id as project_id,
-                                                count(#{Issue.table_name}.id) as total 
-                                              from 
-                                                #{Issue.table_name}, #{Project.table_name}, #{IssueStatus.table_name} s
-                                              where 
-                                                #{Issue.table_name}.status_id=s.id
-                                                and #{Issue.table_name}.project_id = #{Project.table_name}.id
-                                                and #{visible_condition(User.current, :project => project, :with_subprojects => true)}
-                                                and #{Issue.table_name}.project_id <> #{project.id}
-                                              group by s.id, s.is_closed, #{Issue.table_name}.project_id") if project.descendants.active.any?
-  end
-  # End ReportsController extraction
-
-  # Returns an array of projects that current user can move issues to
-  def self.allowed_target_projects_on_move
-    projects = []
-    if User.current.admin?
-      # admin is allowed to move issues to any active (visible) project
-      projects = Project.visible.all
-    elsif User.current.logged?
-      if Role.non_member.allowed_to?(:move_issues)
-        projects = Project.visible.all
-      else
-        User.current.memberships.each {|m| projects << m.project if m.roles.detect {|r| r.allowed_to?(:move_issues)}}
-      end
-    end
-    projects
-  end
-
-  private
-
-  def update_nested_set_attributes
-    if root_id.nil?
-      # issue was just created
-      self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id)
-      set_default_left_and_right
-      Issue.update_all("root_id = #{root_id}, lft = #{lft}, rgt = #{rgt}", ["id = ?", id])
-      if @parent_issue
-        move_to_child_of(@parent_issue)
-      end
-      reload
-    elsif parent_issue_id != parent_id
-      former_parent_id = parent_id
-      # moving an existing issue
-      if @parent_issue && @parent_issue.root_id == root_id
-        # inside the same tree
-        move_to_child_of(@parent_issue)
-      else
-        # to another tree
-        unless root?
-          move_to_right_of(root)
-          reload
-        end
-        old_root_id = root_id
-        self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id )
-        target_maxright = nested_set_scope.maximum(right_column_name) || 0
-        offset = target_maxright + 1 - lft
-        Issue.update_all("root_id = #{root_id}, lft = lft + #{offset}, rgt = rgt + #{offset}",
-                          ["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt])
-        self[left_column_name] = lft + offset
-        self[right_column_name] = rgt + offset
-        if @parent_issue
-          move_to_child_of(@parent_issue)
-        end
-      end
-      reload
-      # delete invalid relations of all descendants
-      self_and_descendants.each do |issue|
-        issue.relations.each do |relation|
-          relation.destroy unless relation.valid?
-        end
-      end
-      # update former parent
-      recalculate_attributes_for(former_parent_id) if former_parent_id
-    end
-    remove_instance_variable(:@parent_issue) if instance_variable_defined?(:@parent_issue)
-  end
-
-  def update_parent_attributes
-    recalculate_attributes_for(parent_id) if parent_id
-  end
-
-  def recalculate_attributes_for(issue_id)
-    if issue_id && p = Issue.find_by_id(issue_id)
-      # priority = highest priority of children
-      if priority_position = p.children.maximum("#{IssuePriority.table_name}.position", :include => :priority)
-        p.priority = IssuePriority.find_by_position(priority_position)
-      end
-
-      # start/due dates = lowest/highest dates of children
-      p.start_date = p.children.minimum(:start_date)
-      p.due_date = p.children.maximum(:due_date)
-      if p.start_date && p.due_date && p.due_date < p.start_date
-        p.start_date, p.due_date = p.due_date, p.start_date
-      end
-
-      # done ratio = weighted average ratio of leaves
-      unless Issue.use_status_for_done_ratio? && p.status && p.status.default_done_ratio
-        leaves_count = p.leaves.count
-        if leaves_count > 0
-          average = p.leaves.average(:estimated_hours).to_f
-          if average == 0
-            average = 1
-          end
-          done = p.leaves.sum("COALESCE(estimated_hours, #{average}) * (CASE WHEN is_closed = #{connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)", :include => :status).to_f
-          progress = done / (average * leaves_count)
-          p.done_ratio = progress.round
-        end
-      end
-
-      # estimate = sum of leaves estimates
-      p.estimated_hours = p.leaves.sum(:estimated_hours).to_f
-      p.estimated_hours = nil if p.estimated_hours == 0.0
-
-      # ancestors will be recursively updated
-      p.save(false)
-    end
-  end
-
-  # Update issues so their versions are not pointing to a
-  # fixed_version that is not shared with the issue's project
-  def self.update_versions(conditions=nil)
-    # Only need to update issues with a fixed_version from
-    # a different project and that is not systemwide shared
-    Issue.all(:conditions => merge_conditions("#{Issue.table_name}.fixed_version_id IS NOT NULL" +
-                                                " AND #{Issue.table_name}.project_id <> #{Version.table_name}.project_id" +
-                                                " AND #{Version.table_name}.sharing <> 'system'",
-                                                conditions),
-              :include => [:project, :fixed_version]
-              ).each do |issue|
-      next if issue.project.nil? || issue.fixed_version.nil?
-      unless issue.project.shared_versions.include?(issue.fixed_version)
-        issue.init_journal(User.current)
-        issue.fixed_version = nil
-        issue.save
-      end
-    end
-  end
-
-  # Callback on attachment deletion
-  def attachment_added(obj)
-    if @current_journal && !obj.new_record?
-      @current_journal.details << JournalDetail.new(:property => 'attachment', :prop_key => obj.id, :value => obj.filename)
-    end
-  end
-
-  # Callback on attachment deletion
-  def attachment_removed(obj)
-    journal = init_journal(User.current)
-    journal.details << JournalDetail.new(:property => 'attachment',
-                                         :prop_key => obj.id,
-                                         :old_value => obj.filename)
-    journal.save
-  end
-
-  # Default assignment based on category
-  def default_assign
-    if assigned_to.nil? && category && category.assigned_to
-      self.assigned_to = category.assigned_to
-    end
-  end
-
-  # Updates start/due dates of following issues
-  def reschedule_following_issues
-    if start_date_changed? || due_date_changed?
-      relations_from.each do |relation|
-        relation.set_issue_to_dates
-      end
-    end
-  end
-
-  # Closes duplicates if the issue is being closed
-  def close_duplicates
-    if closing?
-      duplicates.each do |duplicate|
-        # Reload is need in case the duplicate was updated by a previous duplicate
-        duplicate.reload
-        # Don't re-close it if it's already closed
-        next if duplicate.closed?
-        # Same user and notes
-        if @current_journal
-          duplicate.init_journal(@current_journal.user, @current_journal.notes)
-        end
-        duplicate.update_attribute :status, self.status
-      end
-    end
-  end
-
-  # Saves the changes in a Journal
-  # Called after_save
-  def create_journal
-    if @current_journal
-      # attributes changes
-      (Issue.column_names - %w(id root_id lft rgt lock_version created_on updated_on)).each {|c|
-        before = @issue_before_change.send(c)
-        after = send(c)
-        next if before == after || (before.blank? && after.blank?)
-        @current_journal.details << JournalDetail.new(:property => 'attr',
-                                                      :prop_key => c,
-                                                      :old_value => @issue_before_change.send(c),
-                                                      :value => send(c))
-      }
-      # custom fields changes
-      custom_values.each {|c|
-        next if (@custom_values_before_change[c.custom_field_id]==c.value ||
-                  (@custom_values_before_change[c.custom_field_id].blank? && c.value.blank?))
-        @current_journal.details << JournalDetail.new(:property => 'cf',
-                                                      :prop_key => c.custom_field_id,
-                                                      :old_value => @custom_values_before_change[c.custom_field_id],
-                                                      :value => c.value)
-      }
-      @current_journal.save
-      # reset current journal
-      init_journal @current_journal.user, @current_journal.notes
-    end
-  end
-
-  # Query generator for selecting groups of issue counts for a project
-  # based on specific criteria
-  #
-  # Options
-  # * project - Project to search in.
-  # * field - String. Issue field to key off of in the grouping.
-  # * joins - String. The table name to join against.
-  def self.count_and_group_by(options)
-    project = options.delete(:project)
-    select_field = options.delete(:field)
-    joins = options.delete(:joins)
-
-    where = "#{Issue.table_name}.#{select_field}=j.id"
-
-    ActiveRecord::Base.connection.select_all("select    s.id as status_id, 
-                                                s.is_closed as closed, 
-                                                j.id as #{select_field},
-                                                count(#{Issue.table_name}.id) as total 
-                                              from 
-                                                  #{Issue.table_name}, #{Project.table_name}, #{IssueStatus.table_name} s, #{joins} j
-                                              where 
-                                                #{Issue.table_name}.status_id=s.id 
-                                                and #{where}
-                                                and #{Issue.table_name}.project_id=#{Project.table_name}.id
-                                                and #{visible_condition(User.current, :project => project)}
-                                              group by s.id, s.is_closed, j.id")
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/42/428ba80948c53d51011877b4e85f463b9e15c19b.svn-base
--- /dev/null
+++ b/.svn/pristine/42/428ba80948c53d51011877b4e85f463b9e15c19b.svn-base
@@ -0,0 +1,1 @@
+$('#users').html('<%= escape_javascript(render_principals_for_new_group_users(@group)) %>');
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/42/428bfa93a4c970791698a943e257eddabf08b22f.svn-base
--- a/.svn/pristine/42/428bfa93a4c970791698a943e257eddabf08b22f.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h4><%= link_to h(document.title), :controller => 'documents', :action => 'show', :id => document %></h4>
-<p><em><%= format_time(document.updated_on) %></em></p>
-
-<div class="wiki">
-  <%= textilizable(truncate_lines(document.description), :object => document) %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/42/42cbd8a4f24d085f0d8c0a431c99b911f57d4034.svn-base
--- /dev/null
+++ b/.svn/pristine/42/42cbd8a4f24d085f0d8c0a431c99b911f57d4034.svn-base
@@ -0,0 +1,638 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoriesGitControllerTest < ActionController::TestCase
+  tests RepositoriesController
+
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :repositories, :enabled_modules
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
+  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
+  PRJ_ID     = 3
+  CHAR_1_HEX = "\xc3\x9c"
+  NUM_REV = 28
+
+  ## Git, Mercurial and CVS path encodings are binary.
+  ## Subversion supports URL encoding for path.
+  ## Redmine Mercurial adapter and extension use URL encoding.
+  ## Git accepts only binary path in command line parameter.
+  ## So, there is no way to use binary command line parameter in JRuby.
+  JRUBY_SKIP     = (RUBY_PLATFORM == 'java')
+  JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
+
+  def setup
+    @ruby19_non_utf8_pass =
+      (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8')
+
+    User.current = nil
+    @project    = Project.find(PRJ_ID)
+    @repository = Repository::Git.create(
+                      :project       => @project,
+                      :url           => REPOSITORY_PATH,
+                      :path_encoding => 'ISO-8859-1'
+                      )
+    assert @repository
+    @char_1        = CHAR_1_HEX.dup
+    if @char_1.respond_to?(:force_encoding)
+      @char_1.force_encoding('UTF-8')
+    end
+  end
+
+  def test_create_and_update
+    @request.session[:user_id] = 1
+    assert_difference 'Repository.count' do
+      post :create, :project_id => 'subproject1',
+                    :repository_scm => 'Git',
+                    :repository => {
+                       :url => '/test',
+                       :is_default => '0',
+                       :identifier => 'test-create',
+                       :extra_report_last_commit => '1',
+                     }
+    end
+    assert_response 302
+    repository = Repository.first(:order => 'id DESC')
+    assert_kind_of Repository::Git, repository
+    assert_equal '/test', repository.url
+    assert_equal true, repository.extra_report_last_commit
+
+    put :update, :id => repository.id,
+                 :repository => {
+                     :extra_report_last_commit => '0'
+                 }
+    assert_response 302
+    repo2 = Repository.find(repository.id)
+    assert_equal false, repo2.extra_report_last_commit
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    ## Ruby uses ANSI api to fork a process on Windows.
+    ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
+    ## and these are incompatible with ASCII.
+    ## Git for Windows (msysGit) changed internal API from ANSI to Unicode in 1.7.10
+    ## http://code.google.com/p/msysgit/issues/detail?id=80
+    ## So, Latin-1 path tests fail on Japanese Windows
+    WINDOWS_PASS = (Redmine::Platform.mswin? &&
+                         Redmine::Scm::Adapters::GitAdapter.client_version_above?([1, 7, 10]))
+    WINDOWS_SKIP_STR = "TODO: This test fails in Git for Windows above 1.7.10"
+
+    def test_get_new
+      @request.session[:user_id] = 1
+      @project.repository.destroy
+      get :new, :project_id => 'subproject1', :repository_scm => 'Git'
+      assert_response :success
+      assert_template 'new'
+      assert_kind_of Repository::Git, assigns(:repository)
+      assert assigns(:repository).new_record?
+    end
+
+    def test_browse_root
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      get :show, :id => PRJ_ID
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal 9, assigns(:entries).size
+      assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'this_is_a_really_long_and_verbose_directory_name' && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
+      assert assigns(:entries).detect {|e| e.name == 'copied_README' && e.kind == 'file'}
+      assert assigns(:entries).detect {|e| e.name == 'new_file.txt' && e.kind == 'file'}
+      assert assigns(:entries).detect {|e| e.name == 'renamed_test.txt' && e.kind == 'file'}
+      assert assigns(:entries).detect {|e| e.name == 'filemane with spaces.txt' && e.kind == 'file'}
+      assert assigns(:entries).detect {|e| e.name == ' filename with a leading space.txt ' && e.kind == 'file'}
+      assert_not_nil assigns(:changesets)
+      assert assigns(:changesets).size > 0
+    end
+
+    def test_browse_branch
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :rev => 'test_branch'
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal 4, assigns(:entries).size
+      assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
+      assert assigns(:entries).detect {|e| e.name == 'test.txt' && e.kind == 'file'}
+      assert_not_nil assigns(:changesets)
+      assert assigns(:changesets).size > 0
+    end
+
+    def test_browse_tag
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+       [
+        "tag00.lightweight",
+        "tag01.annotated",
+       ].each do |t1|
+        get :show, :id => PRJ_ID, :rev => t1
+        assert_response :success
+        assert_template 'show'
+        assert_not_nil assigns(:entries)
+        assert assigns(:entries).size > 0
+        assert_not_nil assigns(:changesets)
+        assert assigns(:changesets).size > 0
+      end
+    end
+
+    def test_browse_directory
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['images'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['edit.png'], assigns(:entries).collect(&:name)
+      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
+      assert_not_nil entry
+      assert_equal 'file', entry.kind
+      assert_equal 'images/edit.png', entry.path
+      assert_not_nil assigns(:changesets)
+      assert assigns(:changesets).size > 0
+    end
+
+    def test_browse_at_given_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['images'])[:param],
+          :rev => '7234cb2750b63f47bff735edc50a1c0a433c2518'
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['delete.png'], assigns(:entries).collect(&:name)
+      assert_not_nil assigns(:changesets)
+      assert assigns(:changesets).size > 0
+    end
+
+    def test_changes
+      get :changes, :id => PRJ_ID,
+          :path => repository_path_hash(['images', 'edit.png'])[:param]
+      assert_response :success
+      assert_template 'changes'
+      assert_tag :tag => 'h2', :content => 'edit.png'
+    end
+
+    def test_entry_show
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param]
+      assert_response :success
+      assert_template 'entry'
+      # Line 19
+      assert_tag :tag => 'th',
+                 :content => '11',
+                 :attributes => { :class => 'line-num' },
+                 :sibling => { :tag => 'td', :content => /WITHOUT ANY WARRANTY/ }
+    end
+
+    def test_entry_show_latin_1
+      if @ruby19_non_utf8_pass
+        puts_ruby19_non_utf8_pass()
+      elsif WINDOWS_PASS
+        puts WINDOWS_SKIP_STR
+      elsif JRUBY_SKIP
+        puts JRUBY_SKIP_STR
+      else
+        with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
+          ['57ca437c', '57ca437c0acbbcb749821fdf3726a1367056d364'].each do |r1|
+            get :entry, :id => PRJ_ID,
+                :path => repository_path_hash(['latin-1-dir', "test-#{@char_1}.txt"])[:param],
+                :rev => r1
+            assert_response :success
+            assert_template 'entry'
+            assert_tag :tag => 'th',
+                   :content => '1',
+                   :attributes => { :class => 'line-num' },
+                   :sibling => { :tag => 'td',
+                                 :content => /test-#{@char_1}.txt/ }
+          end
+        end
+      end
+    end
+
+    def test_entry_download
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param],
+          :format => 'raw'
+      assert_response :success
+      # File content
+      assert @response.body.include?('WITHOUT ANY WARRANTY')
+    end
+
+    def test_directory_entry
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entry)
+      assert_equal 'sources', assigns(:entry).name
+    end
+
+    def test_diff
+      assert_equal true, @repository.is_default
+      assert_nil @repository.identifier
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      # Full diff of changeset 2f9c0091
+      ['inline', 'sbs'].each do |dt|
+        get :diff,
+            :id   => PRJ_ID,
+            :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7',
+            :type => dt
+        assert_response :success
+        assert_template 'diff'
+        # Line 22 removed
+        assert_tag :tag => 'th',
+                   :content => /22/,
+                   :sibling => { :tag => 'td',
+                                 :attributes => { :class => /diff_out/ },
+                                 :content => /def remove/ }
+        assert_tag :tag => 'h2', :content => /2f9c0091/
+      end
+    end
+
+    def test_diff_with_rev_and_path
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      with_settings :diff_max_lines_displayed => 1000 do
+        # Full diff of changeset 2f9c0091
+        ['inline', 'sbs'].each do |dt|
+          get :diff,
+              :id   => PRJ_ID,
+              :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7',
+              :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param],
+              :type => dt
+          assert_response :success
+          assert_template 'diff'
+          # Line 22 removed
+          assert_tag :tag => 'th',
+                     :content => '22',
+                     :sibling => { :tag => 'td',
+                                   :attributes => { :class => /diff_out/ },
+                                   :content => /def remove/ }
+          assert_tag :tag => 'h2', :content => /2f9c0091/
+        end
+      end
+    end
+
+    def test_diff_truncated
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      with_settings :diff_max_lines_displayed => 5 do
+        # Truncated diff of changeset 2f9c0091
+        with_cache do
+          with_settings :default_language => 'en' do
+            get :diff, :id   => PRJ_ID, :type => 'inline',
+                :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
+            assert_response :success
+            assert @response.body.include?("... This diff was truncated")
+          end
+          with_settings :default_language => 'fr' do
+            get :diff, :id   => PRJ_ID, :type => 'inline',
+                :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
+            assert_response :success
+            assert ! @response.body.include?("... This diff was truncated")
+            assert @response.body.include?("... Ce diff")
+          end
+        end
+      end
+    end
+
+    def test_diff_two_revs
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['inline', 'sbs'].each do |dt|
+        get :diff,
+            :id     => PRJ_ID,
+            :rev    => '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
+            :rev_to => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7',
+            :type   => dt
+        assert_response :success
+        assert_template 'diff'
+        diff = assigns(:diff)
+        assert_not_nil diff
+        assert_tag :tag => 'h2', :content => /2f9c0091:61b685fb/
+        assert_tag :tag => "form",
+                   :attributes => {
+                     :action => "/projects/subproject1/repository/revisions/" +
+                                   "61b685fbe55ab05b5ac68402d5720c1a6ac973d1/diff"
+                   }
+        assert_tag :tag => 'input',
+                   :attributes => {
+                     :id => "rev_to",
+                     :name => "rev_to",
+                     :type => "hidden",
+                     :value => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
+                   }
+      end
+    end
+
+    def test_diff_path_in_subrepo
+      repo = Repository::Git.create(
+                      :project       => @project,
+                      :url           => REPOSITORY_PATH,
+                      :identifier => 'test-diff-path',
+                      :path_encoding => 'ISO-8859-1'
+                      );
+      assert repo
+      assert_equal false, repo.is_default
+      assert_equal 'test-diff-path', repo.identifier
+      get :diff,
+          :id     => PRJ_ID,
+          :repository_id => 'test-diff-path',
+          :rev    => '61b685fbe55ab05b',
+          :rev_to => '2f9c0091c754a91a',
+          :type   => 'inline'
+      assert_response :success
+      assert_template 'diff'
+      diff = assigns(:diff)
+      assert_not_nil diff
+      assert_tag :tag => "form",
+                 :attributes => {
+                   :action => "/projects/subproject1/repository/test-diff-path/" + 
+                                "revisions/61b685fbe55ab05b/diff"
+                 }
+      assert_tag :tag => 'input',
+                 :attributes => {
+                   :id => "rev_to",
+                   :name => "rev_to",
+                   :type => "hidden",
+                   :value => '2f9c0091c754a91a'
+                 }
+    end
+
+    def test_diff_latin_1
+      if @ruby19_non_utf8_pass
+        puts_ruby19_non_utf8_pass()
+      else
+        with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
+          ['57ca437c', '57ca437c0acbbcb749821fdf3726a1367056d364'].each do |r1|
+            ['inline', 'sbs'].each do |dt|
+              get :diff, :id => PRJ_ID, :rev => r1, :type => dt
+              assert_response :success
+              assert_template 'diff'
+              assert_tag :tag => 'thead',
+                         :descendant => {
+                           :tag => 'th',
+                           :attributes => { :class => 'filename' } ,
+                           :content => /latin-1-dir\/test-#{@char_1}.txt/ ,
+                          },
+                         :sibling => {
+                           :tag => 'tbody',
+                           :descendant => {
+                              :tag => 'td',
+                              :attributes => { :class => /diff_in/ },
+                              :content => /test-#{@char_1}.txt/
+                           }
+                         }
+            end
+          end
+        end
+      end
+    end
+
+    def test_diff_should_show_filenames
+      get :diff, :id => PRJ_ID, :rev => 'deff712f05a90d96edbd70facc47d944be5897e3', :type => 'inline'
+      assert_response :success
+      assert_template 'diff'
+      # modified file
+      assert_select 'th.filename', :text => 'sources/watchers_controller.rb'
+      # deleted file
+      assert_select 'th.filename', :text => 'test.txt'
+    end
+
+    def test_save_diff_type
+      user1 = User.find(1)
+      user1.pref[:diff_type] = nil
+      user1.preference.save
+      user = User.find(1)
+      assert_nil user.pref[:diff_type]
+
+      @request.session[:user_id] = 1 # admin
+      get :diff,
+          :id   => PRJ_ID,
+          :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
+      assert_response :success
+      assert_template 'diff'
+      user.reload
+      assert_equal "inline", user.pref[:diff_type]
+      get :diff,
+          :id   => PRJ_ID,
+          :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7',
+          :type => 'sbs'
+      assert_response :success
+      assert_template 'diff'
+      user.reload
+      assert_equal "sbs", user.pref[:diff_type]
+    end
+
+    def test_annotate
+      get :annotate, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param]
+      assert_response :success
+      assert_template 'annotate'
+
+      # Line 23, changeset 2f9c0091
+      assert_select 'tr' do
+        assert_select 'th.line-num', :text => '23'
+        assert_select 'td.revision', :text => /2f9c0091/
+        assert_select 'td.author', :text => 'jsmith'
+        assert_select 'td', :text => /remove_watcher/
+      end
+    end
+
+    def test_annotate_at_given_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :annotate, :id => PRJ_ID, :rev => 'deff7',
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param]
+      assert_response :success
+      assert_template 'annotate'
+      assert_tag :tag => 'h2', :content => /@ deff712f/
+    end
+
+    def test_annotate_binary_file
+      get :annotate, :id => PRJ_ID,
+          :path => repository_path_hash(['images', 'edit.png'])[:param]
+      assert_response 500
+      assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ },
+                              :content => /cannot be annotated/
+    end
+
+    def test_annotate_error_when_too_big
+      with_settings :file_max_size_displayed => 1 do
+        get :annotate, :id => PRJ_ID,
+            :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param],
+            :rev => 'deff712f'
+        assert_response 500
+        assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ },
+                                :content => /exceeds the maximum text file size/
+
+        get :annotate, :id => PRJ_ID,
+            :path => repository_path_hash(['README'])[:param],
+            :rev => '7234cb2'
+        assert_response :success
+        assert_template 'annotate'
+      end
+    end
+
+    def test_annotate_latin_1
+      if @ruby19_non_utf8_pass
+        puts_ruby19_non_utf8_pass()
+      elsif WINDOWS_PASS
+        puts WINDOWS_SKIP_STR
+      elsif JRUBY_SKIP
+        puts JRUBY_SKIP_STR
+      else
+        with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
+          ['57ca437c', '57ca437c0acbbcb749821fdf3726a1367056d364'].each do |r1|
+            get :annotate, :id => PRJ_ID,
+                :path => repository_path_hash(['latin-1-dir', "test-#{@char_1}.txt"])[:param],
+                :rev => r1
+            assert_tag :tag => 'th',
+                       :content => '1',
+                       :attributes => { :class => 'line-num' },
+                       :sibling => { :tag => 'td',
+                                     :content => /test-#{@char_1}.txt/ }
+          end
+        end
+      end
+    end
+
+    def test_revisions
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :revisions, :id => PRJ_ID
+      assert_response :success
+      assert_template 'revisions'
+      assert_tag :tag => 'form',
+                 :attributes => {
+                   :method => 'get',
+                   :action => '/projects/subproject1/repository/revision'
+                 }
+    end
+
+    def test_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['61b685fbe55ab05b5ac68402d5720c1a6ac973d1', '61b685f'].each do |r|
+        get :revision, :id => PRJ_ID, :rev => r
+        assert_response :success
+        assert_template 'revision'
+      end
+    end
+
+    def test_empty_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['', ' ', nil].each do |r|
+        get :revision, :id => PRJ_ID, :rev => r
+        assert_response 404
+        assert_error_tag :content => /was not found/
+      end
+    end
+
+    def test_destroy_valid_repository
+      @request.session[:user_id] = 1 # admin
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+
+    def test_destroy_invalid_repository
+      @request.session[:user_id] = 1 # admin
+      @project.repository.destroy
+      @repository = Repository::Git.create!(
+                      :project       => @project,
+                      :url           => "/invalid",
+                      :path_encoding => 'ISO-8859-1'
+                      )
+      @repository.fetch_changesets
+      @repository.reload
+      assert_equal 0, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+
+    private
+
+    def puts_ruby19_non_utf8_pass
+      puts "TODO: This test fails in Ruby 1.9 " +
+           "and Encoding.default_external is not UTF-8. " +
+           "Current value is '#{Encoding.default_external.to_s}'"
+    end
+  else
+    puts "Git test repository NOT FOUND. Skipping functional tests !!!"
+    def test_fake; assert true end
+  end
+
+  private
+  def with_cache(&block)
+    before = ActionController::Base.perform_caching
+    ActionController::Base.perform_caching = true
+    block.call
+    ActionController::Base.perform_caching = before
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/43/4319c6d41e87c8e5f7a1d9a565f8d9f540e96297.svn-base
--- /dev/null
+++ b/.svn/pristine/43/4319c6d41e87c8e5f7a1d9a565f8d9f540e96297.svn-base
@@ -0,0 +1,19 @@
+<h2><%= l(:label_plugins) %></h2>
+
+<% if @plugins.any? %>
+<table class="list plugins">
+    <% @plugins.each do |plugin| %>
+        <tr id="plugin-<%= plugin.id %>" class="<%= cycle('odd', 'even') %>">
+        <td><span class="name"><%=h plugin.name %></span>
+            <%= content_tag('span', h(plugin.description), :class => 'description') unless plugin.description.blank? %>
+            <%= content_tag('span', link_to(h(plugin.url), plugin.url), :class => 'url') unless plugin.url.blank? %>
+        </td>
+        <td class="author"><%= plugin.author_url.blank? ? h(plugin.author) : link_to(h(plugin.author), plugin.author_url) %></td>
+        <td class="version"><%=h plugin.version %></td>
+        <td class="configure"><%= link_to(l(:button_configure), plugin_settings_path(plugin)) if plugin.configurable? %></td>
+        </tr>
+    <% end %>
+</table>
+<% else %>
+<p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/43/431e564a1e03f4cc7d0102d7d18816df7d2cc0e3.svn-base
--- a/.svn/pristine/43/431e564a1e03f4cc7d0102d7d18816df7d2cc0e3.svn-base
+++ /dev/null
@@ -1,117 +0,0 @@
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::DisabledRestApiTest < ActionController::IntegrationTest
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows
-
-  def setup
-    Setting.rest_api_enabled = '0'
-    Setting.login_required = '1'
-  end
-
-  def teardown
-    Setting.rest_api_enabled = '1'
-    Setting.login_required = '0'
-  end
-
-  # Using the NewsController because it's a simple API.
-  context "get /news with the API disabled" do
-
-    context "in :xml format" do
-      context "with a valid api token" do
-        setup do
-          @user = User.generate_with_protected!
-          @token = Token.generate!(:user => @user, :action => 'api')
-          get "/news.xml?key=#{@token.value}"
-        end
-
-        should_respond_with :unauthorized
-        should_respond_with_content_type :xml
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-
-      context "with a valid HTTP authentication" do
-        setup do
-          @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
-          @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
-          get "/news.xml", nil, :authorization => @authorization
-        end
-
-        should_respond_with :unauthorized
-        should_respond_with_content_type :xml
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-
-      context "with a valid HTTP authentication using the API token" do
-        setup do
-          @user = User.generate_with_protected!
-          @token = Token.generate!(:user => @user, :action => 'api')
-          @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
-          get "/news.xml", nil, :authorization => @authorization
-        end
-
-        should_respond_with :unauthorized
-        should_respond_with_content_type :xml
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-    end
-
-    context "in :json format" do
-      context "with a valid api token" do
-        setup do
-          @user = User.generate_with_protected!
-          @token = Token.generate!(:user => @user, :action => 'api')
-          get "/news.json?key=#{@token.value}"
-        end
-
-        should_respond_with :unauthorized
-        should_respond_with_content_type :json
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-
-      context "with a valid HTTP authentication" do
-        setup do
-          @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
-          @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
-          get "/news.json", nil, :authorization => @authorization
-        end
-
-        should_respond_with :unauthorized
-        should_respond_with_content_type :json
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-
-      context "with a valid HTTP authentication using the API token" do
-        setup do
-          @user = User.generate_with_protected!
-          @token = Token.generate!(:user => @user, :action => 'api')
-          @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
-          get "/news.json", nil, :authorization => @authorization
-        end
-
-        should_respond_with :unauthorized
-        should_respond_with_content_type :json
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/43/43272555ea477da0c1b59cf98e2f63d68056c98b.svn-base
--- a/.svn/pristine/43/43272555ea477da0c1b59cf98e2f63d68056c98b.svn-base
+++ /dev/null
@@ -1,113 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/darcs_adapter'
-
-class Repository::Darcs < Repository
-  validates_presence_of :url, :log_encoding
-
-  def self.human_attribute_name(attribute_key_name)
-    attr_name = attribute_key_name
-    if attr_name == "url"
-      attr_name = "path_to_repository"
-    end
-    super(attr_name)
-  end
-
-  def self.scm_adapter_class
-    Redmine::Scm::Adapters::DarcsAdapter
-  end
-
-  def self.scm_name
-    'Darcs'
-  end
-
-  def supports_directory_revisions?
-    true
-  end
-
-  def entry(path=nil, identifier=nil)
-    patch = identifier.nil? ? nil : changesets.find_by_revision(identifier)
-    scm.entry(path, patch.nil? ? nil : patch.scmid)
-  end
-
-  def entries(path=nil, identifier=nil)
-    patch = nil
-    if ! identifier.nil?
-      patch = changesets.find_by_revision(identifier)
-      return nil if patch.nil?
-    end
-    entries = scm.entries(path, patch.nil? ? nil : patch.scmid)
-    if entries
-      entries.each do |entry|
-        # Search the DB for the entry's last change
-        if entry.lastrev && !entry.lastrev.scmid.blank?
-          changeset = changesets.find_by_scmid(entry.lastrev.scmid)
-        end
-        if changeset
-          entry.lastrev.identifier = changeset.revision
-          entry.lastrev.name       = changeset.revision
-          entry.lastrev.time       = changeset.committed_on
-          entry.lastrev.author     = changeset.committer
-        end
-      end
-    end
-    entries
-  end
-
-  def cat(path, identifier=nil)
-    patch = identifier.nil? ? nil : changesets.find_by_revision(identifier.to_s)
-    scm.cat(path, patch.nil? ? nil : patch.scmid)
-  end
-
-  def diff(path, rev, rev_to)
-    patch_from = changesets.find_by_revision(rev)
-    return nil if patch_from.nil?
-    patch_to = changesets.find_by_revision(rev_to) if rev_to
-    if path.blank?
-      path = patch_from.changes.collect{|change| change.path}.join(' ')
-    end
-    patch_from ? scm.diff(path, patch_from.scmid, patch_to ? patch_to.scmid : nil) : nil
-  end
-
-  def fetch_changesets
-    scm_info = scm.info
-    if scm_info
-      db_last_id = latest_changeset ? latest_changeset.scmid : nil
-      next_rev   = latest_changeset ? latest_changeset.revision.to_i + 1 : 1
-      # latest revision in the repository
-      scm_revision = scm_info.lastrev.scmid
-      unless changesets.find_by_scmid(scm_revision)
-        revisions = scm.revisions('', db_last_id, nil, :with_path => true)
-        transaction do
-          revisions.reverse_each do |revision|
-            changeset = Changeset.create(:repository   => self,
-                                         :revision     => next_rev,
-                                         :scmid        => revision.scmid,
-                                         :committer    => revision.author,
-                                         :committed_on => revision.time,
-                                         :comments     => revision.message)
-            revision.paths.each do |change|
-              changeset.create_change(change)
-            end
-            next_rev += 1
-          end if revisions
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/43/4333e2faed9865820292b92a3a8ebf203749d50e.svn-base
--- /dev/null
+++ b/.svn/pristine/43/4333e2faed9865820292b92a3a8ebf203749d50e.svn-base
@@ -0,0 +1,43 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module WikiHelper
+
+  def wiki_page_options_for_select(pages, selected = nil, parent = nil, level = 0)
+    pages = pages.group_by(&:parent) unless pages.is_a?(Hash)
+    s = ''.html_safe
+    if pages.has_key?(parent)
+      pages[parent].each do |page|
+        attrs = "value='#{page.id}'"
+        attrs << " selected='selected'" if selected == page
+        indent = (level > 0) ? ('&nbsp;' * level * 2 + '&#187; ') : ''
+
+        s << content_tag('option', (indent + h(page.pretty_title)).html_safe, :value => page.id.to_s, :selected => selected == page) +
+               wiki_page_options_for_select(pages, selected, page, level + 1)
+      end
+    end
+    s
+  end
+
+  def wiki_page_breadcrumb(page)
+    breadcrumb(page.ancestors.reverse.collect {|parent|
+      link_to(h(parent.pretty_title), {:controller => 'wiki', :action => 'show', :id => parent.title, :project_id => parent.project, :version => nil})
+    })
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/43/435d200d5b8e7f06b0e465d23cb053a76fc8f49e.svn-base
--- /dev/null
+++ b/.svn/pristine/43/435d200d5b8e7f06b0e465d23cb053a76fc8f49e.svn-base
@@ -0,0 +1,62 @@
+<div class="contextual">
+<%= watcher_link(@news, User.current) %>
+<%= link_to(l(:button_edit),
+      edit_news_path(@news),
+      :class => 'icon icon-edit',
+      :accesskey => accesskey(:edit),
+      :onclick => '$("#edit-news").show(); return false;') if User.current.allowed_to?(:manage_news, @project) %>
+<%= delete_link news_path(@news) if User.current.allowed_to?(:manage_news, @project) %>
+</div>
+
+<h2><%= avatar(@news.author, :size => "24") %><%=h @news.title %></h2>
+
+<% if authorize_for('news', 'edit') %>
+<div id="edit-news" style="display:none;">
+<%= labelled_form_for :news, @news, :url => news_path(@news),
+                                           :html => { :id => 'news-form', :multipart => true, :method => :put } do |f| %>
+<%= render :partial => 'form', :locals => { :f => f } %>
+<%= submit_tag l(:button_save) %>
+<%= preview_link preview_news_path(:project_id => @project, :id => @news), 'news-form' %> |
+<%= link_to l(:button_cancel), "#", :onclick => '$("#edit-news").hide(); return false;' %>
+<% end %>
+<div id="preview" class="wiki"></div>
+</div>
+<% end %>
+
+<p><% unless @news.summary.blank? %><em><%=h @news.summary %></em><br /><% end %>
+<span class="author"><%= authoring @news.created_on, @news.author %></span></p>
+<div class="wiki">
+<%= textilizable(@news, :description) %>
+</div>
+<%= link_to_attachments @news %>
+<br />
+
+<div id="comments" style="margin-bottom:16px;">
+<h3 class="comments"><%= l(:label_comment_plural) %></h3>
+<% @comments.each do |comment| %>
+    <% next if comment.new_record? %>
+    <div class="contextual">
+    <%= link_to_if_authorized image_tag('delete.png'), {:controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment},
+                                                       :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, :title => l(:button_delete) %>
+    </div>
+    <h4><%= avatar(comment.author, :size => "24") %><%= authoring comment.created_on, comment.author %></h4>
+    <%= textilizable(comment.comments) %>
+<% end if @comments.any? %>
+</div>
+
+<% if @news.commentable? %>
+<p><%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %></p>
+<%= form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %>
+<div class="box">
+    <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %>
+    <%= wikitoolbar_for 'comment_comments' %>
+</div>
+<p><%= submit_tag l(:button_add) %></p>
+<% end %>
+<% end %>
+
+<% html_title @news.title -%>
+
+<% content_for :header_tags do %>
+  <%= stylesheet_link_tag 'scm' %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/43/437c58e98b2bf838355e6ccb0adcad2c75761185.svn-base
--- a/.svn/pristine/43/437c58e98b2bf838355e6ccb0adcad2c75761185.svn-base
+++ /dev/null
@@ -1,52 +0,0 @@
-<h2><%= l(:label_search) %></h2>
-
-<div class="box">
-<% form_tag({}, :method => :get) do %>
-<%= label_tag "search-input", l(:description_search), :class => "hidden-for-sighted" %>
-<p><%= text_field_tag 'q', @question, :size => 60, :id => 'search-input' %>
-<%= javascript_tag "Field.focus('search-input')" %>
-<%= project_select_tag %>
-<%= hidden_field_tag 'all_words', '', :id => nil %>
-<label><%= check_box_tag 'all_words', 1, @all_words %> <%= l(:label_all_words) %></label>
-<%= hidden_field_tag 'titles_only', '', :id => nil %>
-<label><%= check_box_tag 'titles_only', 1, @titles_only %> <%= l(:label_search_titles_only) %></label>
-</p>
-<p>
-<% @object_types.each do |t| %>
-<label><%= check_box_tag t, 1, @scope.include?(t) %> <%= type_label(t) %></label>
-<% end %>
-</p>
-
-<p><%= submit_tag l(:button_submit), :name => 'submit' %></p>
-<% end %>
-</div>
-
-<% if @results %>
-    <div id="search-results-counts">
-    <%= render_results_by_type(@results_by_type) unless @scope.size == 1 %>
-    </div>
-
-    <h3><%= l(:label_result_plural) %> (<%= @results_by_type.values.sum %>)</h3>
-    <dl id="search-results">
-      <% @results.each do |e| %>
-        <dt class="<%= e.event_type %>"><%= content_tag('span', h(e.project), :class => 'project') unless @project == e.project %> <%= link_to highlight_tokens(truncate(h(e.event_title), :length => 255), @tokens), e.event_url %></dt>
-        <dd><span class="description"><%= highlight_tokens(h(e.event_description), @tokens) %></span>
-        <span class="author"><%= format_time(e.event_datetime) %></span></dd>
-      <% end %>
-    </dl>
-<% end %>
-
-<p><center>
-<% if @pagination_previous_date %>
-<%= link_to_content_update("\xc2\xab " + l(:label_previous),
-      params.merge(:previous => 1,
-                   :offset => @pagination_previous_date.strftime("%Y%m%d%H%M%S"))) %>&nbsp;
-<% end %>
-<% if @pagination_next_date %>
-<%= link_to_content_update(l(:label_next) + " \xc2\xbb",
-      params.merge(:previous => nil,
-                   :offset => @pagination_next_date.strftime("%Y%m%d%H%M%S"))) %>
-<% end %>
-</center></p>
-
-<% html_title(l(:label_search)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/43/43815b2797ad5e2c1f98a876a3c98a313e459bdb.svn-base
--- a/.svn/pristine/43/43815b2797ad5e2c1f98a876a3c98a313e459bdb.svn-base
+++ /dev/null
@@ -1,31 +0,0 @@
-RUBYTREE - http://rubytree.rubyforge.org
-========================================
-
-Copyright (c) 2006, 2007 Anupam Sengupta
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-- Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-- Redistributions in binary form must reproduce the above copyright notice, this
-  list of conditions and the following disclaimer in the documentation and/or
-  other materials provided with the distribution.
-
-- Neither the name of the organization nor the names of its contributors may
-  be used to endorse or promote products derived from this software without
-  specific prior written permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/43/4384f149ba601f6c60fa67ac6f918ddfc90dc0b6.svn-base
--- a/.svn/pristine/43/4384f149ba601f6c60fa67ac6f918ddfc90dc0b6.svn-base
+++ /dev/null
@@ -1,281 +0,0 @@
-# This code lets us redefine existing Rake tasks, which is extremely
-# handy for modifying existing Rails rake tasks.
-# Credit for the original snippet of code goes to Jeremy Kemper
-# http://pastie.caboo.se/9620
-unless Rake::TaskManager.methods.include?('redefine_task')
-  module Rake
-    module TaskManager
-      def redefine_task(task_class, args, &block)
-        task_name, arg_names, deps = resolve_args([args])
-        task_name = task_class.scope_name(@scope, task_name)
-        deps = [deps] unless deps.respond_to?(:to_ary)
-        deps = deps.collect {|d| d.to_s }
-        task = @tasks[task_name.to_s] = task_class.new(task_name, self)
-        task.application = self
-        task.add_description(@last_description)
-        @last_description = nil
-        task.enhance(deps, &block)
-        task
-      end
-      
-    end
-    class Task
-      class << self
-        def redefine_task(args, &block)
-          Rake.application.redefine_task(self, [args], &block)
-        end
-      end
-    end
-  end
-end
-
-namespace :db do
-  namespace :migrate do
-    desc 'Migrate database and plugins to current status.'
-    task :all => [ 'db:migrate', 'db:migrate:plugins' ]
-    
-    desc 'Migrate plugins to current status.'
-    task :plugins => :environment do
-      Engines.plugins.each do |plugin|
-        next unless plugin.respond_to?(:migration_directory)
-        next unless File.exists? plugin.migration_directory
-        puts "Migrating plugin #{plugin.name} ..."
-        plugin.migrate
-      end
-    end
-
-    desc 'For engines coming from Rails version < 2.0 or for those previously updated to work with Sven Fuch\'s fork of engines, you need to upgrade the schema info table'
-    task :upgrade_plugin_migrations => :environment do
-      svens_fork_table_name = 'plugin_schema_migrations'
-      
-      # Check if app was previously using Sven's fork
-      if ActiveRecord::Base.connection.table_exists?(svens_fork_table_name)
-        old_sm_table = svens_fork_table_name
-      else
-        old_sm_table = ActiveRecord::Migrator.proper_table_name(Engines.schema_info_table)
-      end
-      
-      unless ActiveRecord::Base.connection.table_exists?(old_sm_table)
-        abort "Cannot find old migration table - assuming nothing needs to be done"
-      end
-      
-      # There are two forms of the engines schema info - pre-fix_plugin_migrations and post
-      # We need to figure this out before we continue.
-      
-      results = ActiveRecord::Base.connection.select_rows(
-        "SELECT version, plugin_name FROM #{old_sm_table}"
-      ).uniq
-      
-      def insert_new_version(plugin_name, version)
-        version_string = "#{version}-#{plugin_name}"
-        new_sm_table = ActiveRecord::Migrator.schema_migrations_table_name
-        
-        # Check if the row already exists for some reason - maybe run this task more than once.
-        return if ActiveRecord::Base.connection.select_rows("SELECT * FROM #{new_sm_table} WHERE version = #{version_string.dump.gsub("\"", "'")}").size > 0
-        
-        puts "Inserting new version #{version} for plugin #{plugin_name}.."
-        ActiveRecord::Base.connection.insert("INSERT INTO #{new_sm_table} (version) VALUES (#{version_string.dump.gsub("\"", "'")})")
-      end
-      
-      # We need to figure out if they already used "fix_plugin_migrations"
-      versions = {}
-      results.each do |r|
-        versions[r[1]] ||= []
-        versions[r[1]] << r[0].to_i
-      end
-      
-      if versions.values.find{ |v| v.size > 1 } == nil
-        puts "Fixing migration info"
-        # We only have one listed migration per plugin - this is pre-fix_plugin_migrations,
-        # so we build all versions required. In this case, all migrations should 
-        versions.each do |plugin_name, version|
-          version = version[0] # There is only one version
-          
-          # We have to make an assumption that numeric migrations won't get this long..
-          # I'm not sure if there is a better assumption, it should work in all
-          # current cases.. (touch wood..)
-          if version.to_s.size < "YYYYMMDDHHMMSS".size
-            # Insert version records for each migration
-            (1..version).each do |v|
-             insert_new_version(plugin_name, v)
-            end
-          else
-            # If the plugin is new-format "YYYYMMDDHHMMSS", we just copy it across... 
-            # The case in which this occurs is very rare..
-            insert_new_version(plugin_name, version)
-          end
-        end
-      else
-        puts "Moving migration info"
-        # We have multiple migrations listed per plugin - thus we can assume they have
-        # already applied fix_plugin_migrations - we just copy it across verbatim
-        versions.each do |plugin_name, version|
-          version.each { |v| insert_new_version(plugin_name, v) }
-        end
-      end
-      
-      puts "Migration info successfully migrated - removing old schema info table"
-      ActiveRecord::Base.connection.drop_table(old_sm_table)
-    end
-    
-    desc 'Migrate a specified plugin.'
-    task(:plugin => :environment) do
-      name = ENV['NAME']
-      if plugin = Engines.plugins[name]
-        version = ENV['VERSION']
-        puts "Migrating #{plugin.name} to " + (version ? "version #{version}" : 'latest version') + " ..."
-        plugin.migrate(version ? version.to_i : nil)
-      else
-        puts "Plugin #{name} does not exist."
-      end
-    end
-  end
-end
-
-
-namespace :db do  
-  namespace :fixtures do
-    namespace :plugins do
-      
-      desc "Load plugin fixtures into the current environment's database."
-      task :load => :environment do
-        require 'active_record/fixtures'
-        ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
-        Dir.glob(File.join(RAILS_ROOT, 'vendor', 'plugins', ENV['PLUGIN'] || '**', 
-                 'test', 'fixtures', '*.yml')).each do |fixture_file|
-          Fixtures.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*'))
-        end
-      end
-      
-    end
-  end
-end
-
-# this is just a modification of the original task in railties/lib/tasks/documentation.rake, 
-# because the default task doesn't support subdirectories like <plugin>/app or
-# <plugin>/component. These tasks now include every file under a plugin's load paths (see
-# Plugin#load_paths).
-namespace :doc do
-
-  plugins = FileList['vendor/plugins/**'].collect { |plugin| File.basename(plugin) }
-
-  namespace :plugins do
-
-    # Define doc tasks for each plugin
-    plugins.each do |plugin|
-      desc "Create plugin documentation for '#{plugin}'"
-      Rake::Task.redefine_task(plugin => :environment) do
-        plugin_base   = RAILS_ROOT + "/vendor/plugins/#{plugin}"
-        options       = []
-        files         = Rake::FileList.new
-        options << "-o doc/plugins/#{plugin}"
-        options << "--title '#{plugin.titlecase} Plugin Documentation'"
-        options << '--line-numbers' << '--inline-source'
-        options << '-T html'
-
-        # Include every file in the plugin's load_paths (see Plugin#load_paths)
-        if Engines.plugins[plugin]
-          files.include("#{plugin_base}/{#{Engines.plugins[plugin].load_paths.join(",")}}/**/*.rb")
-        end
-        if File.exists?("#{plugin_base}/README")
-          files.include("#{plugin_base}/README")    
-          options << "--main '#{plugin_base}/README'"
-        end
-        files.include("#{plugin_base}/CHANGELOG") if File.exists?("#{plugin_base}/CHANGELOG")
-
-        if files.empty?
-          puts "No source files found in #{plugin_base}. No documentation will be generated."
-        else
-          options << files.to_s
-          sh %(rdoc #{options * ' '})
-        end
-      end
-    end
-  end
-end
-
-
-
-namespace :test do
-  task :warn_about_multiple_plugin_testing_with_engines do
-    puts %{-~============== A Moste Polite Warninge ===========================~-
-
-You may experience issues testing multiple plugins at once when using
-the code-mixing features that the engines plugin provides. If you do
-experience any problems, please test plugins individually, i.e.
-
-  $ rake test:plugins PLUGIN=my_plugin
-
-or use the per-type plugin test tasks:
-
-  $ rake test:plugins:units
-  $ rake test:plugins:functionals
-  $ rake test:plugins:integration
-  $ rake test:plugins:all
-
-Report any issues on http://dev.rails-engines.org. Thanks!
-
--~===============( ... as you were ... )============================~-}
-  end
-  
-  namespace :engines do
-    
-    def engine_plugins
-      Dir["vendor/plugins/*"].select { |f| File.directory?(File.join(f, "app")) }.map { |f| File.basename(f) }.join(",")
-    end
-    
-    desc "Run tests from within engines plugins (plugins with an 'app' directory)"
-    task :all => [:units, :functionals, :integration]
-    
-    desc "Run unit tests from within engines plugins (plugins with an 'app' directory)"
-    Rake::TestTask.new(:units => "test:plugins:setup_plugin_fixtures") do |t|
-      t.pattern = "vendor/plugins/{#{ENV['PLUGIN'] || engine_plugins}}/test/unit/**/*_test.rb"
-      t.verbose = true
-    end
-
-    desc "Run functional tests from within engines plugins (plugins with an 'app' directory)"
-    Rake::TestTask.new(:functionals => "test:plugins:setup_plugin_fixtures") do |t|
-      t.pattern = "vendor/plugins/{#{ENV['PLUGIN'] || engine_plugins}}/test/functional/**/*_test.rb"
-      t.verbose = true
-    end
-
-    desc "Run integration tests from within engines plugins (plugins with an 'app' directory)"
-    Rake::TestTask.new(:integration => "test:plugins:setup_plugin_fixtures") do |t|
-      t.pattern = "vendor/plugins/{#{ENV['PLUGIN'] || engine_plugins}}/test/integration/**/*_test.rb"
-      t.verbose = true
-    end
-  end
-  
-  namespace :plugins do
-
-    desc "Run the plugin tests in vendor/plugins/**/test (or specify with PLUGIN=name)"
-    task :all => [:warn_about_multiple_plugin_testing_with_engines, 
-                  :units, :functionals, :integration]
-    
-    desc "Run all plugin unit tests"
-    Rake::TestTask.new(:units => :setup_plugin_fixtures) do |t|
-      t.pattern = "vendor/plugins/#{ENV['PLUGIN'] || "**"}/test/unit/**/*_test.rb"
-      t.verbose = true
-    end
-    
-    desc "Run all plugin functional tests"
-    Rake::TestTask.new(:functionals => :setup_plugin_fixtures) do |t|
-      t.pattern = "vendor/plugins/#{ENV['PLUGIN'] || "**"}/test/functional/**/*_test.rb"
-      t.verbose = true
-    end
-    
-    desc "Integration test engines"
-    Rake::TestTask.new(:integration => :setup_plugin_fixtures) do |t|
-      t.pattern = "vendor/plugins/#{ENV['PLUGIN'] || "**"}/test/integration/**/*_test.rb"
-      t.verbose = true
-    end
-
-    desc "Mirrors plugin fixtures into a single location to help plugin tests"
-    task :setup_plugin_fixtures => :environment do
-      Engines::Testing.setup_plugin_fixtures
-    end
-    
-    # Patch the default plugin testing task to have setup_plugin_fixtures as a prerequisite
-    Rake::Task["test:plugins"].prerequisites << "test:plugins:setup_plugin_fixtures"
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/44/4427f53bdbb62ef1eca701cca69cda8b76215c5d.svn-base
--- /dev/null
+++ b/.svn/pristine/44/4427f53bdbb62ef1eca701cca69cda8b76215c5d.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module MessagesHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/44/4439ef733d46df57772e77a997ac371196818a57.svn-base
--- a/.svn/pristine/44/4439ef733d46df57772e77a997ac371196818a57.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-# Load the normal Rails helper
-require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
-
-# Ensure that we are using the temporary fixture path
-Engines::Testing.set_fixture_path
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/44/44669c27372c172ef04555f4bb81865f6ca83884.svn-base
--- a/.svn/pristine/44/44669c27372c172ef04555f4bb81865f6ca83884.svn-base
+++ /dev/null
@@ -1,95 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class GanttsControllerTest < ActionController::TestCase
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :versions
-
-  context "#gantt" do
-    should "work" do
-      i2 = Issue.find(2)
-      i2.update_attribute(:due_date, 1.month.from_now)
-
-      get :show, :project_id => 1
-      assert_response :success
-      assert_template 'gantts/show'
-      assert_not_nil assigns(:gantt)
-      # Issue with start and due dates
-      i = Issue.find(1)
-      assert_not_nil i.due_date
-      assert_select "div a.issue", /##{i.id}/
-      # Issue with on a targeted version should not be in the events but loaded in the html
-      i = Issue.find(2)
-      assert_select "div a.issue", /##{i.id}/
-    end
-
-    should "work without issue due dates" do
-      Issue.update_all("due_date = NULL")
-
-      get :show, :project_id => 1
-      assert_response :success
-      assert_template 'gantts/show'
-      assert_not_nil assigns(:gantt)
-    end
-
-    should "work without issue and version due dates" do
-      Issue.update_all("due_date = NULL")
-      Version.update_all("effective_date = NULL")
-
-      get :show, :project_id => 1
-      assert_response :success
-      assert_template 'gantts/show'
-      assert_not_nil assigns(:gantt)
-    end
-
-    should "work cross project" do
-      get :show
-      assert_response :success
-      assert_template 'gantts/show'
-      assert_not_nil assigns(:gantt)
-      assert_not_nil assigns(:gantt).query
-      assert_nil assigns(:gantt).project
-    end
-
-    should "not disclose private projects" do
-      get :show
-      assert_response :success
-      assert_template 'gantts/show'
-
-      assert_tag 'a', :content => /eCookbook/
-      # Root private project
-      assert_no_tag 'a', {:content => /OnlineStore/}
-      # Private children of a public project
-      assert_no_tag 'a', :content => /Private child of eCookbook/
-    end
-
-    should "export to pdf" do
-      get :show, :project_id => 1, :format => 'pdf'
-      assert_response :success
-      assert_equal 'application/pdf', @response.content_type
-      assert @response.body.starts_with?('%PDF')
-      assert_not_nil assigns(:gantt)
-    end
-
-    should "export to pdf cross project" do
-      get :show, :format => 'pdf'
-      assert_response :success
-      assert_equal 'application/pdf', @response.content_type
-      assert @response.body.starts_with?('%PDF')
-      assert_not_nil assigns(:gantt)
-    end
-
-    should "export to png" do
-      get :show, :project_id => 1, :format => 'png'
-      assert_response :success
-      assert_equal 'image/png', @response.content_type
-    end if Object.const_defined?(:Magick)
-
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/44/448dc5ae56acac81ffaeeeb288586a6544fe08b0.svn-base
--- a/.svn/pristine/44/448dc5ae56acac81ffaeeeb288586a6544fe08b0.svn-base
+++ /dev/null
@@ -1,545 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'projects_controller'
-
-# Re-raise errors caught by the controller.
-class ProjectsController; def rescue_action(e) raise e end; end
-
-class ProjectsControllerTest < ActionController::TestCase
-  fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
-           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
-           :attachments, :custom_fields, :custom_values, :time_entries
-
-  def setup
-    @controller = ProjectsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    @request.session[:user_id] = nil
-    Setting.default_language = 'en'
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:projects)
-
-    assert_tag :ul, :child => {:tag => 'li',
-                               :descendant => {:tag => 'a', :content => 'eCookbook'},
-                               :child => { :tag => 'ul',
-                                           :descendant => { :tag => 'a',
-                                                            :content => 'Child of private child'
-                                                           }
-                                          }
-                               }
-
-    assert_no_tag :a, :content => /Private child of eCookbook/
-  end
-
-  def test_index_atom
-    get :index, :format => 'atom'
-    assert_response :success
-    assert_template 'common/feed.atom'
-    assert_select 'feed>title', :text => 'Redmine: Latest projects'
-    assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_condition(User.current))
-  end
-
-  context "#index" do
-    context "by non-admin user with view_time_entries permission" do
-      setup do
-        @request.session[:user_id] = 3
-      end
-      should "show overall spent time link" do
-        get :index
-        assert_template 'index'
-        assert_tag :a, :attributes => {:href => '/time_entries'}
-      end
-    end
-
-    context "by non-admin user without view_time_entries permission" do
-      setup do
-        Role.find(2).remove_permission! :view_time_entries
-        Role.non_member.remove_permission! :view_time_entries
-        Role.anonymous.remove_permission! :view_time_entries
-        @request.session[:user_id] = 3
-      end
-      should "not show overall spent time link" do
-        get :index
-        assert_template 'index'
-        assert_no_tag :a, :attributes => {:href => '/time_entries'}
-      end
-    end
-  end
-
-  context "#new" do
-    context "by admin user" do
-      setup do
-        @request.session[:user_id] = 1
-      end
-
-      should "accept get" do
-        get :new
-        assert_response :success
-        assert_template 'new'
-      end
-
-    end
-
-    context "by non-admin user with add_project permission" do
-      setup do
-        Role.non_member.add_permission! :add_project
-        @request.session[:user_id] = 9
-      end
-
-      should "accept get" do
-        get :new
-        assert_response :success
-        assert_template 'new'
-        assert_no_tag :select, :attributes => {:name => 'project[parent_id]'}
-      end
-    end
-
-    context "by non-admin user with add_subprojects permission" do
-      setup do
-        Role.find(1).remove_permission! :add_project
-        Role.find(1).add_permission! :add_subprojects
-        @request.session[:user_id] = 2
-      end
-
-      should "accept get" do
-        get :new, :parent_id => 'ecookbook'
-        assert_response :success
-        assert_template 'new'
-        # parent project selected
-        assert_tag :select, :attributes => {:name => 'project[parent_id]'},
-                            :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}}
-        # no empty value
-        assert_no_tag :select, :attributes => {:name => 'project[parent_id]'},
-                               :child => {:tag => 'option', :attributes => {:value => ''}}
-      end
-    end
-
-  end
-
-  context "POST :create" do
-    context "by admin user" do
-      setup do
-        @request.session[:user_id] = 1
-      end
-
-      should "create a new project" do
-        post :create,
-          :project => {
-            :name => "blog",
-            :description => "weblog",
-            :homepage => 'http://weblog',
-            :identifier => "blog",
-            :is_public => 1,
-            :custom_field_values => { '3' => 'Beta' },
-            :tracker_ids => ['1', '3'],
-            # an issue custom field that is not for all project
-            :issue_custom_field_ids => ['9'],
-            :enabled_module_names => ['issue_tracking', 'news', 'repository']
-          }
-        assert_redirected_to '/projects/blog/settings'
-
-        project = Project.find_by_name('blog')
-        assert_kind_of Project, project
-        assert project.active?
-        assert_equal 'weblog', project.description
-        assert_equal 'http://weblog', project.homepage
-        assert_equal true, project.is_public?
-        assert_nil project.parent
-        assert_equal 'Beta', project.custom_value_for(3).value
-        assert_equal [1, 3], project.trackers.map(&:id).sort
-        assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
-        assert project.issue_custom_fields.include?(IssueCustomField.find(9))
-      end
-
-      should "create a new subproject" do
-        post :create, :project => { :name => "blog",
-                                 :description => "weblog",
-                                 :identifier => "blog",
-                                 :is_public => 1,
-                                 :custom_field_values => { '3' => 'Beta' },
-                                 :parent_id => 1
-                                }
-        assert_redirected_to '/projects/blog/settings'
-
-        project = Project.find_by_name('blog')
-        assert_kind_of Project, project
-        assert_equal Project.find(1), project.parent
-      end
-
-      should "continue" do
-        assert_difference 'Project.count' do
-          post :create, :project => {:name => "blog", :identifier => "blog"}, :continue => 'Create and continue'
-        end
-        assert_redirected_to '/projects/new?'
-      end
-    end
-
-    context "by non-admin user with add_project permission" do
-      setup do
-        Role.non_member.add_permission! :add_project
-        @request.session[:user_id] = 9
-      end
-
-      should "accept create a Project" do
-        post :create, :project => { :name => "blog",
-                                 :description => "weblog",
-                                 :identifier => "blog",
-                                 :is_public => 1,
-                                 :custom_field_values => { '3' => 'Beta' },
-                                 :tracker_ids => ['1', '3'],
-                                 :enabled_module_names => ['issue_tracking', 'news', 'repository']
-                                }
-
-        assert_redirected_to '/projects/blog/settings'
-
-        project = Project.find_by_name('blog')
-        assert_kind_of Project, project
-        assert_equal 'weblog', project.description
-        assert_equal true, project.is_public?
-        assert_equal [1, 3], project.trackers.map(&:id).sort
-        assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
-
-        # User should be added as a project member
-        assert User.find(9).member_of?(project)
-        assert_equal 1, project.members.size
-      end
-
-      should "fail with parent_id" do
-        assert_no_difference 'Project.count' do
-          post :create, :project => { :name => "blog",
-                                   :description => "weblog",
-                                   :identifier => "blog",
-                                   :is_public => 1,
-                                   :custom_field_values => { '3' => 'Beta' },
-                                   :parent_id => 1
-                                  }
-        end
-        assert_response :success
-        project = assigns(:project)
-        assert_kind_of Project, project
-        assert_not_nil project.errors[:parent_id]
-      end
-    end
-
-    context "by non-admin user with add_subprojects permission" do
-      setup do
-        Role.find(1).remove_permission! :add_project
-        Role.find(1).add_permission! :add_subprojects
-        @request.session[:user_id] = 2
-      end
-
-      should "create a project with a parent_id" do
-        post :create, :project => { :name => "blog",
-                                 :description => "weblog",
-                                 :identifier => "blog",
-                                 :is_public => 1,
-                                 :custom_field_values => { '3' => 'Beta' },
-                                 :parent_id => 1
-                                }
-        assert_redirected_to '/projects/blog/settings'
-        project = Project.find_by_name('blog')
-      end
-
-      should "fail without parent_id" do
-        assert_no_difference 'Project.count' do
-          post :create, :project => { :name => "blog",
-                                   :description => "weblog",
-                                   :identifier => "blog",
-                                   :is_public => 1,
-                                   :custom_field_values => { '3' => 'Beta' }
-                                  }
-        end
-        assert_response :success
-        project = assigns(:project)
-        assert_kind_of Project, project
-        assert_not_nil project.errors[:parent_id]
-      end
-
-      should "fail with unauthorized parent_id" do
-        assert !User.find(2).member_of?(Project.find(6))
-        assert_no_difference 'Project.count' do
-          post :create, :project => { :name => "blog",
-                                   :description => "weblog",
-                                   :identifier => "blog",
-                                   :is_public => 1,
-                                   :custom_field_values => { '3' => 'Beta' },
-                                   :parent_id => 6
-                                  }
-        end
-        assert_response :success
-        project = assigns(:project)
-        assert_kind_of Project, project
-        assert_not_nil project.errors[:parent_id]
-      end
-    end
-  end
-
-  def test_create_should_preserve_modules_on_validation_failure
-    with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
-      @request.session[:user_id] = 1
-      assert_no_difference 'Project.count' do
-        post :create, :project => {
-          :name => "blog",
-          :identifier => "",
-          :enabled_module_names => %w(issue_tracking news)
-        }
-      end
-      assert_response :success
-      project = assigns(:project)
-      assert_equal %w(issue_tracking news), project.enabled_module_names.sort
-    end
-  end
-
-  def test_create_should_not_accept_get
-    @request.session[:user_id] = 1
-    get :create
-    assert_response :method_not_allowed
-  end
-
-  def test_show_by_id
-    get :show, :id => 1
-    assert_response :success
-    assert_template 'show'
-    assert_not_nil assigns(:project)
-  end
-
-  def test_show_by_identifier
-    get :show, :id => 'ecookbook'
-    assert_response :success
-    assert_template 'show'
-    assert_not_nil assigns(:project)
-    assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
-
-    assert_tag 'li', :content => /Development status/
-  end
-
-  def test_show_should_not_display_hidden_custom_fields
-    ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
-    get :show, :id => 'ecookbook'
-    assert_response :success
-    assert_template 'show'
-    assert_not_nil assigns(:project)
-
-    assert_no_tag 'li', :content => /Development status/
-  end
-
-  def test_show_should_not_fail_when_custom_values_are_nil
-    project = Project.find_by_identifier('ecookbook')
-    project.custom_values.first.update_attribute(:value, nil)
-    get :show, :id => 'ecookbook'
-    assert_response :success
-    assert_template 'show'
-    assert_not_nil assigns(:project)
-    assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
-  end
-
-  def show_archived_project_should_be_denied
-    project = Project.find_by_identifier('ecookbook')
-    project.archive!
-
-    get :show, :id => 'ecookbook'
-    assert_response 403
-    assert_nil assigns(:project)
-    assert_tag :tag => 'p', :content => /archived/
-  end
-
-  def test_private_subprojects_hidden
-    get :show, :id => 'ecookbook'
-    assert_response :success
-    assert_template 'show'
-    assert_no_tag :tag => 'a', :content => /Private child/
-  end
-
-  def test_private_subprojects_visible
-    @request.session[:user_id] = 2 # manager who is a member of the private subproject
-    get :show, :id => 'ecookbook'
-    assert_response :success
-    assert_template 'show'
-    assert_tag :tag => 'a', :content => /Private child/
-  end
-
-  def test_settings
-    @request.session[:user_id] = 2 # manager
-    get :settings, :id => 1
-    assert_response :success
-    assert_template 'settings'
-  end
-
-  def test_update
-    @request.session[:user_id] = 2 # manager
-    post :update, :id => 1, :project => {:name => 'Test changed name',
-                                       :issue_custom_field_ids => ['']}
-    assert_redirected_to '/projects/ecookbook/settings'
-    project = Project.find(1)
-    assert_equal 'Test changed name', project.name
-  end
-
-  def test_modules
-    @request.session[:user_id] = 2
-    Project.find(1).enabled_module_names = ['issue_tracking', 'news']
-
-    post :modules, :id => 1, :enabled_module_names => ['issue_tracking', 'repository', 'documents']
-    assert_redirected_to '/projects/ecookbook/settings/modules'
-    assert_equal ['documents', 'issue_tracking', 'repository'], Project.find(1).enabled_module_names.sort
-  end
-
-  def test_modules_should_not_allow_get
-    @request.session[:user_id] = 1
-    get :modules, :id => 1
-    assert_response :method_not_allowed
-  end
-
-  def test_get_destroy
-    @request.session[:user_id] = 1 # admin
-    get :destroy, :id => 1
-    assert_response :success
-    assert_template 'destroy'
-    assert_not_nil Project.find_by_id(1)
-  end
-
-  def test_post_destroy
-    @request.session[:user_id] = 1 # admin
-    post :destroy, :id => 1, :confirm => 1
-    assert_redirected_to '/admin/projects'
-    assert_nil Project.find_by_id(1)
-  end
-
-  def test_archive
-    @request.session[:user_id] = 1 # admin
-    post :archive, :id => 1
-    assert_redirected_to '/admin/projects'
-    assert !Project.find(1).active?
-  end
-
-  def test_unarchive
-    @request.session[:user_id] = 1 # admin
-    Project.find(1).archive
-    post :unarchive, :id => 1
-    assert_redirected_to '/admin/projects'
-    assert Project.find(1).active?
-  end
-
-  def test_project_breadcrumbs_should_be_limited_to_3_ancestors
-    CustomField.delete_all
-    parent = nil
-    6.times do |i|
-      p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")
-      p.set_parent!(parent)
-      get :show, :id => p
-      assert_tag :h1, :parent => { :attributes => {:id => 'header'}},
-                      :children => { :count => [i, 3].min,
-                                     :only => { :tag => 'a' } }
-
-      parent = p
-    end
-  end
-
-  def test_get_copy
-    @request.session[:user_id] = 1 # admin
-    get :copy, :id => 1
-    assert_response :success
-    assert_template 'copy'
-    assert assigns(:project)
-    assert_equal Project.find(1).description, assigns(:project).description
-    assert_nil assigns(:project).id
-
-    assert_tag :tag => 'input',
-      :attributes => {:name => 'project[enabled_module_names][]', :value => 'issue_tracking'}
-  end
-
-  def test_get_copy_without_project
-    @request.session[:user_id] = 1 # admin
-    get :copy
-    assert_response :redirect
-    assert_redirected_to :controller => 'admin', :action => 'projects'
-  end
-
-  def test_post_copy_should_copy_requested_items
-    @request.session[:user_id] = 1 # admin
-    CustomField.delete_all
-
-    assert_difference 'Project.count' do
-      post :copy, :id => 1,
-        :project => {
-          :name => 'Copy',
-          :identifier => 'unique-copy',
-          :tracker_ids => ['1', '2', '3', ''],
-          :enabled_module_names => %w(issue_tracking time_tracking)
-        },
-        :only => %w(issues versions)
-    end
-    project = Project.find('unique-copy')
-    source = Project.find(1)
-    assert_equal %w(issue_tracking time_tracking), project.enabled_module_names.sort
-
-    assert_equal source.versions.count, project.versions.count, "All versions were not copied"
-    # issues assigned to a closed version won't be copied
-    assert_equal source.issues.select {|i| i.fixed_version.nil? || i.fixed_version.open?}.size,
-                 project.issues.count, "All issues were not copied"
-    assert_equal 0, project.members.count
-  end
-
-  def test_post_copy_should_redirect_to_settings_when_successful
-    @request.session[:user_id] = 1 # admin
-    post :copy, :id => 1, :project => {:name => 'Copy', :identifier => 'unique-copy'}
-    assert_response :redirect
-    assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy'
-  end
-
-  def test_jump_should_redirect_to_active_tab
-    get :show, :id => 1, :jump => 'issues'
-    assert_redirected_to '/projects/ecookbook/issues'
-  end
-
-  def test_jump_should_not_redirect_to_inactive_tab
-    get :show, :id => 3, :jump => 'documents'
-    assert_response :success
-    assert_template 'show'
-  end
-
-  def test_jump_should_not_redirect_to_unknown_tab
-    get :show, :id => 3, :jump => 'foobar'
-    assert_response :success
-    assert_template 'show'
-  end
-
-  # A hook that is manually registered later
-  class ProjectBasedTemplate < Redmine::Hook::ViewListener
-    def view_layouts_base_html_head(context)
-      # Adds a project stylesheet
-      stylesheet_link_tag(context[:project].identifier) if context[:project]
-    end
-  end
-  # Don't use this hook now
-  Redmine::Hook.clear_listeners
-
-  def test_hook_response
-    Redmine::Hook.add_listener(ProjectBasedTemplate)
-    get :show, :id => 1
-    assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},
-                               :parent => {:tag => 'head'}
-
-    Redmine::Hook.clear_listeners
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/44/44d79a17ffe7c2b64a23af9018ae26f5e13961e3.svn-base
--- a/.svn/pristine/44/44d79a17ffe7c2b64a23af9018ae26f5e13961e3.svn-base
+++ /dev/null
@@ -1,25 +0,0 @@
-<% form_tag({:action => 'edit', :tab => 'issues'}) do %>
-
-<div class="box tabular settings">
-<p><%= setting_check_box :cross_project_issue_relations %></p>
-
-<p><%= setting_check_box :issue_group_assignment %></p>
-
-<p><%= setting_check_box :default_issue_start_date_to_creation_date %></p>
-
-<p><%= setting_check_box :display_subprojects_issues %></p>
-
-<p><%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %></p>
-
-<p><%= setting_text_field :issues_export_limit, :size => 6 %></p>
-
-<p><%= setting_text_field :gantt_items_limit, :size => 6 %></p>
-</div>
-
-<fieldset class="box settings"><legend><%= l(:setting_issue_list_default_columns) %></legend>
-<%= setting_multiselect(:issue_list_default_columns,
-        Query.new.available_columns.collect {|c| [c.caption, c.name.to_s]}, :label => false) %>
-</fieldset>
-
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/4537efe545b75bf585f6f1b2f82d7cbf9d1195c2.svn-base
--- /dev/null
+++ b/.svn/pristine/45/4537efe545b75bf585f6f1b2f82d7cbf9d1195c2.svn-base
@@ -0,0 +1,166 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Hook
+    @@listener_classes = []
+    @@listeners = nil
+    @@hook_listeners = {}
+
+    class << self
+      # Adds a listener class.
+      # Automatically called when a class inherits from Redmine::Hook::Listener.
+      def add_listener(klass)
+        raise "Hooks must include Singleton module." unless klass.included_modules.include?(Singleton)
+        @@listener_classes << klass
+        clear_listeners_instances
+      end
+
+      # Returns all the listerners instances.
+      def listeners
+        @@listeners ||= @@listener_classes.collect {|listener| listener.instance}
+      end
+
+      # Returns the listeners instances for the given hook.
+      def hook_listeners(hook)
+        @@hook_listeners[hook] ||= listeners.select {|listener| listener.respond_to?(hook)}
+      end
+
+      # Clears all the listeners.
+      def clear_listeners
+        @@listener_classes = []
+        clear_listeners_instances
+      end
+
+      # Clears all the listeners instances.
+      def clear_listeners_instances
+        @@listeners = nil
+        @@hook_listeners = {}
+      end
+
+      # Calls a hook.
+      # Returns the listeners response.
+      def call_hook(hook, context={})
+        [].tap do |response|
+          hls = hook_listeners(hook)
+          if hls.any?
+            hls.each {|listener| response << listener.send(hook, context)}
+          end
+        end
+      end
+    end
+
+    # Base class for hook listeners.
+    class Listener
+      include Singleton
+      include Redmine::I18n
+
+      # Registers the listener
+      def self.inherited(child)
+        Redmine::Hook.add_listener(child)
+        super
+      end
+
+    end
+
+    # Listener class used for views hooks.
+    # Listeners that inherit this class will include various helpers by default.
+    class ViewListener < Listener
+      include ERB::Util
+      include ActionView::Helpers::TagHelper
+      include ActionView::Helpers::FormHelper
+      include ActionView::Helpers::FormTagHelper
+      include ActionView::Helpers::FormOptionsHelper
+      include ActionView::Helpers::JavaScriptHelper
+      include ActionView::Helpers::NumberHelper
+      include ActionView::Helpers::UrlHelper
+      include ActionView::Helpers::AssetTagHelper
+      include ActionView::Helpers::TextHelper
+      include Rails.application.routes.url_helpers
+      include ApplicationHelper
+
+      # Default to creating links using only the path.  Subclasses can
+      # change this default as needed
+      def self.default_url_options
+        {:only_path => true }
+      end
+
+      # Helper method to directly render a partial using the context:
+      #
+      #   class MyHook < Redmine::Hook::ViewListener
+      #     render_on :view_issues_show_details_bottom, :partial => "show_more_data"
+      #   end
+      #
+      def self.render_on(hook, options={})
+        define_method hook do |context|
+          if context[:hook_caller].respond_to?(:render)
+            context[:hook_caller].send(:render, {:locals => context}.merge(options))
+          elsif context[:controller].is_a?(ActionController::Base)
+            context[:controller].send(:render_to_string, {:locals => context}.merge(options))
+          else
+            raise "Cannot render #{self.name} hook from #{context[:hook_caller].class.name}"
+          end
+        end
+      end
+      
+      def controller
+        nil
+      end
+      
+      def config
+        ActionController::Base.config
+      end
+    end
+
+    # Helper module included in ApplicationHelper and ActionController so that
+    # hooks can be called in views like this:
+    #
+    #   <%= call_hook(:some_hook) %>
+    #   <%= call_hook(:another_hook, :foo => 'bar') %>
+    #
+    # Or in controllers like:
+    #   call_hook(:some_hook)
+    #   call_hook(:another_hook, :foo => 'bar')
+    #
+    # Hooks added to views will be concatenated into a string. Hooks added to
+    # controllers will return an array of results.
+    #
+    # Several objects are automatically added to the call context:
+    #
+    # * project => current project
+    # * request => Request instance
+    # * controller => current Controller instance
+    # * hook_caller => object that called the hook
+    #
+    module Helper
+      def call_hook(hook, context={})
+        if is_a?(ActionController::Base)
+          default_context = {:controller => self, :project => @project, :request => request, :hook_caller => self}
+          Redmine::Hook.call_hook(hook, default_context.merge(context))
+        else
+          default_context = { :project => @project, :hook_caller => self }
+          default_context[:controller] = controller if respond_to?(:controller)
+          default_context[:request] = request if respond_to?(:request)
+          Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ').html_safe
+        end
+      end
+    end
+  end
+end
+
+ApplicationHelper.send(:include, Redmine::Hook::Helper)
+ActionController::Base.send(:include, Redmine::Hook::Helper)
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/4541853cf8b57a89416ab78d9c5650a0f0ed5774.svn-base
--- a/.svn/pristine/45/4541853cf8b57a89416ab78d9c5650a0f0ed5774.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class AppAndPluginController < ApplicationController
-  def an_action
-    render_class_and_action 'from beta_plugin'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/45481eeadf5fe7268354b5aabc0c5767470f2390.svn-base
--- /dev/null
+++ b/.svn/pristine/45/45481eeadf5fe7268354b5aabc0c5767470f2390.svn-base
@@ -0,0 +1,97 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Wiki < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  belongs_to :project
+  has_many :pages, :class_name => 'WikiPage', :dependent => :destroy, :order => 'title'
+  has_many :redirects, :class_name => 'WikiRedirect', :dependent => :delete_all
+
+  acts_as_watchable
+
+  validates_presence_of :start_page
+  validates_format_of :start_page, :with => /\A[^,\.\/\?\;\|\:]*\z/
+
+  safe_attributes 'start_page'
+
+  def visible?(user=User.current)
+    !user.nil? && user.allowed_to?(:view_wiki_pages, project)
+  end
+
+  # Returns the wiki page that acts as the sidebar content
+  # or nil if no such page exists
+  def sidebar
+    @sidebar ||= find_page('Sidebar', :with_redirect => false)
+  end
+
+  # find the page with the given title
+  # if page doesn't exist, return a new page
+  def find_or_new_page(title)
+    title = start_page if title.blank?
+    find_page(title) || WikiPage.new(:wiki => self, :title => Wiki.titleize(title))
+  end
+
+  # find the page with the given title
+  def find_page(title, options = {})
+    @page_found_with_redirect = false
+    title = start_page if title.blank?
+    title = Wiki.titleize(title)
+    page = pages.first(:conditions => ["LOWER(title) = LOWER(?)", title])
+    if !page && !(options[:with_redirect] == false)
+      # search for a redirect
+      redirect = redirects.first(:conditions => ["LOWER(title) = LOWER(?)", title])
+      if redirect
+        page = find_page(redirect.redirects_to, :with_redirect => false)
+        @page_found_with_redirect = true
+      end
+    end
+    page
+  end
+
+  # Returns true if the last page was found with a redirect
+  def page_found_with_redirect?
+    @page_found_with_redirect
+  end
+
+  # Finds a page by title
+  # The given string can be of one of the forms: "title" or "project:title"
+  # Examples:
+  #   Wiki.find_page("bar", project => foo)
+  #   Wiki.find_page("foo:bar")
+  def self.find_page(title, options = {})
+    project = options[:project]
+    if title.to_s =~ %r{^([^\:]+)\:(.*)$}
+      project_identifier, title = $1, $2
+      project = Project.find_by_identifier(project_identifier) || Project.find_by_name(project_identifier)
+    end
+    if project && project.wiki
+      page = project.wiki.find_page(title)
+      if page && page.content
+        page
+      end
+    end
+  end
+
+  # turn a string into a valid page title
+  def self.titleize(title)
+    # replace spaces with _ and remove unwanted caracters
+    title = title.gsub(/\s+/, '_').delete(',./?;|:') if title
+    # upcase the first letter
+    title = (title.slice(0..0).upcase + (title.slice(1..-1) || '')) if title
+    title
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/456ef3443ff7df8c5dc761c97f3f05ad3eb5ac25.svn-base
--- a/.svn/pristine/45/456ef3443ff7df8c5dc761c97f3f05ad3eb5ac25.svn-base
+++ /dev/null
@@ -1,101 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../test_helper', __FILE__)
-
-class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
-  include ApplicationHelper
-  include ActionView::Helpers::TextHelper
-  include ActionView::Helpers::SanitizeHelper
-  extend ActionView::Helpers::SanitizeHelper::ClassMethods
-
-  fixtures :projects, :roles, :enabled_modules, :users,
-                      :repositories, :changesets,
-                      :trackers, :issue_statuses, :issues,
-                      :versions, :documents,
-                      :wikis, :wiki_pages, :wiki_contents,
-                      :boards, :messages,
-                      :attachments
-
-  def setup
-    super
-    @project = nil
-  end
-
-  def teardown
-  end
-
-  def test_macro_hello_world
-    text = "{{hello_world}}"
-    assert textilizable(text).match(/Hello world!/)
-    # escaping
-    text = "!{{hello_world}}"
-    assert_equal '<p>{{hello_world}}</p>', textilizable(text)
-  end
-
-  def test_macro_include
-    @project = Project.find(1)
-    # include a page of the current project wiki
-    text = "{{include(Another page)}}"
-    assert textilizable(text).match(/This is a link to a ticket/)
-
-    @project = nil
-    # include a page of a specific project wiki
-    text = "{{include(ecookbook:Another page)}}"
-    assert textilizable(text).match(/This is a link to a ticket/)
-
-    text = "{{include(ecookbook:)}}"
-    assert textilizable(text).match(/CookBook documentation/)
-
-    text = "{{include(unknowidentifier:somepage)}}"
-    assert textilizable(text).match(/Page not found/)
-  end
-
-  def test_macro_child_pages
-    expected =  "<p><ul class=\"pages-hierarchy\">\n" +
-                 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a></li>\n" +
-                 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
-                 "</ul>\n</p>"
-
-    @project = Project.find(1)
-    # child pages of the current wiki page
-    assert_equal expected, textilizable("{{child_pages}}", :object => WikiPage.find(2).content)
-    # child pages of another page
-    assert_equal expected, textilizable("{{child_pages(Another_page)}}", :object => WikiPage.find(1).content)
-
-    @project = Project.find(2)
-    assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page)}}", :object => WikiPage.find(1).content)
-  end
-
-  def test_macro_child_pages_with_option
-    expected =  "<p><ul class=\"pages-hierarchy\">\n" +
-                 "<li><a href=\"/projects/ecookbook/wiki/Another_page\">Another page</a>\n" +
-                 "<ul class=\"pages-hierarchy\">\n" +
-                 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a></li>\n" +
-                 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
-                 "</ul>\n</li>\n</ul>\n</p>"
-
-    @project = Project.find(1)
-    # child pages of the current wiki page
-    assert_equal expected, textilizable("{{child_pages(parent=1)}}", :object => WikiPage.find(2).content)
-    # child pages of another page
-    assert_equal expected, textilizable("{{child_pages(Another_page, parent=1)}}", :object => WikiPage.find(1).content)
-
-    @project = Project.find(2)
-    assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page, parent=1)}}", :object => WikiPage.find(1).content)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/457635320d7cf0fe410b58dcbd4445d01bddd1f8.svn-base
--- a/.svn/pristine/45/457635320d7cf0fe410b58dcbd4445d01bddd1f8.svn-base
+++ /dev/null
@@ -1,285 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-require 'pp'
-class ApiTest::UsersTest < ActionController::IntegrationTest
-  fixtures :users
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "GET /users" do
-    should_allow_api_authentication(:get, "/users.xml")
-    should_allow_api_authentication(:get, "/users.json")
-  end
-
-  context "GET /users/2" do
-    context ".xml" do
-      should "return requested user" do
-        get '/users/2.xml'
-
-        assert_tag :tag => 'user',
-          :child => {:tag => 'id', :content => '2'}
-      end
-    end
-
-    context ".json" do
-      should "return requested user" do
-        get '/users/2.json'
-
-        json = ActiveSupport::JSON.decode(response.body)
-        assert_kind_of Hash, json
-        assert_kind_of Hash, json['user']
-        assert_equal 2, json['user']['id']
-      end
-    end
-  end
-
-  context "GET /users/current" do
-    context ".xml" do
-      should "require authentication" do
-        get '/users/current.xml'
-
-        assert_response 401
-      end
-
-      should "return current user" do
-        get '/users/current.xml', {}, :authorization => credentials('jsmith')
-
-        assert_tag :tag => 'user',
-          :child => {:tag => 'id', :content => '2'}
-      end
-    end
-  end
-
-  context "POST /users" do
-    context "with valid parameters" do
-      setup do
-        @parameters = {:user => {:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname', :mail => 'foo@example.net', :password => 'secret', :mail_notification => 'only_assigned'}}
-      end
-
-      context ".xml" do
-        should_allow_api_authentication(:post,
-          '/users.xml',
-          {:user => {:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname', :mail => 'foo@example.net', :password => 'secret'}},
-          {:success_code => :created})
-
-        should "create a user with the attributes" do
-          assert_difference('User.count') do
-            post '/users.xml', @parameters, :authorization => credentials('admin')
-          end
-
-          user = User.first(:order => 'id DESC')
-          assert_equal 'foo', user.login
-          assert_equal 'Firstname', user.firstname
-          assert_equal 'Lastname', user.lastname
-          assert_equal 'foo@example.net', user.mail
-          assert_equal 'only_assigned', user.mail_notification
-          assert !user.admin?
-          assert user.check_password?('secret')
-
-          assert_response :created
-          assert_equal 'application/xml', @response.content_type
-          assert_tag 'user', :child => {:tag => 'id', :content => user.id.to_s}
-        end
-      end
-
-      context ".json" do
-        should_allow_api_authentication(:post,
-          '/users.json',
-          {:user => {:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname', :mail => 'foo@example.net'}},
-          {:success_code => :created})
-
-        should "create a user with the attributes" do
-          assert_difference('User.count') do
-            post '/users.json', @parameters, :authorization => credentials('admin')
-          end
-
-          user = User.first(:order => 'id DESC')
-          assert_equal 'foo', user.login
-          assert_equal 'Firstname', user.firstname
-          assert_equal 'Lastname', user.lastname
-          assert_equal 'foo@example.net', user.mail
-          assert !user.admin?
-
-          assert_response :created
-          assert_equal 'application/json', @response.content_type
-          json = ActiveSupport::JSON.decode(response.body)
-          assert_kind_of Hash, json
-          assert_kind_of Hash, json['user']
-          assert_equal user.id, json['user']['id']
-        end
-      end
-    end
-
-    context "with invalid parameters" do
-      setup do
-        @parameters = {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}
-      end
-
-      context ".xml" do
-        should "return errors" do
-          assert_no_difference('User.count') do
-            post '/users.xml', @parameters, :authorization => credentials('admin')
-          end
-
-          assert_response :unprocessable_entity
-          assert_equal 'application/xml', @response.content_type
-          assert_tag 'errors', :child => {:tag => 'error', :content => "First name can't be blank"}
-        end
-      end
-
-      context ".json" do
-        should "return errors" do
-          assert_no_difference('User.count') do
-            post '/users.json', @parameters, :authorization => credentials('admin')
-          end
-
-          assert_response :unprocessable_entity
-          assert_equal 'application/json', @response.content_type
-          json = ActiveSupport::JSON.decode(response.body)
-          assert_kind_of Hash, json
-          assert json.has_key?('errors')
-          assert_kind_of Array, json['errors']
-        end
-      end
-    end
-  end
-
-  context "PUT /users/2" do
-    context "with valid parameters" do
-      setup do
-        @parameters = {:user => {:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed', :mail => 'jsmith@somenet.foo'}}
-      end
-
-      context ".xml" do
-        should_allow_api_authentication(:put,
-          '/users/2.xml',
-          {:user => {:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed', :mail => 'jsmith@somenet.foo'}},
-          {:success_code => :ok})
-
-        should "update user with the attributes" do
-          assert_no_difference('User.count') do
-            put '/users/2.xml', @parameters, :authorization => credentials('admin')
-          end
-
-          user = User.find(2)
-          assert_equal 'jsmith', user.login
-          assert_equal 'John', user.firstname
-          assert_equal 'Renamed', user.lastname
-          assert_equal 'jsmith@somenet.foo', user.mail
-          assert !user.admin?
-
-          assert_response :ok
-        end
-      end
-
-      context ".json" do
-        should_allow_api_authentication(:put,
-          '/users/2.json',
-          {:user => {:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed', :mail => 'jsmith@somenet.foo'}},
-          {:success_code => :ok})
-
-        should "update user with the attributes" do
-          assert_no_difference('User.count') do
-            put '/users/2.json', @parameters, :authorization => credentials('admin')
-          end
-
-          user = User.find(2)
-          assert_equal 'jsmith', user.login
-          assert_equal 'John', user.firstname
-          assert_equal 'Renamed', user.lastname
-          assert_equal 'jsmith@somenet.foo', user.mail
-          assert !user.admin?
-
-          assert_response :ok
-        end
-      end
-    end
-
-    context "with invalid parameters" do
-      setup do
-        @parameters = {:user => {:login => 'jsmith', :firstname => '', :lastname => 'Lastname', :mail => 'foo'}}
-      end
-
-      context ".xml" do
-        should "return errors" do
-          assert_no_difference('User.count') do
-            put '/users/2.xml', @parameters, :authorization => credentials('admin')
-          end
-
-          assert_response :unprocessable_entity
-          assert_equal 'application/xml', @response.content_type
-          assert_tag 'errors', :child => {:tag => 'error', :content => "First name can't be blank"}
-        end
-      end
-
-      context ".json" do
-        should "return errors" do
-          assert_no_difference('User.count') do
-            put '/users/2.json', @parameters, :authorization => credentials('admin')
-          end
-
-          assert_response :unprocessable_entity
-          assert_equal 'application/json', @response.content_type
-          json = ActiveSupport::JSON.decode(response.body)
-          assert_kind_of Hash, json
-          assert json.has_key?('errors')
-          assert_kind_of Array, json['errors']
-        end
-      end
-    end
-  end
-
-  context "DELETE /users/2" do
-    context ".xml" do
-      should_allow_api_authentication(:delete,
-        '/users/2.xml',
-        {},
-        {:success_code => :ok})
-
-      should "delete user" do
-        assert_difference('User.count', -1) do
-          delete '/users/2.xml', {}, :authorization => credentials('admin')
-        end
-
-        assert_response :ok
-      end
-    end
-
-    context ".json" do
-      should_allow_api_authentication(:delete,
-        '/users/2.xml',
-        {},
-        {:success_code => :ok})
-
-      should "delete user" do
-        assert_difference('User.count', -1) do
-          delete '/users/2.json', {}, :authorization => credentials('admin')
-        end
-
-        assert_response :ok
-      end
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/4589164e770ce01b12657f2cebf30982504c9054.svn-base
--- /dev/null
+++ b/.svn/pristine/45/4589164e770ce01b12657f2cebf30982504c9054.svn-base
@@ -0,0 +1,1248 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class QueryTest < ActiveSupport::TestCase
+  include Redmine::I18n
+
+  fixtures :projects, :enabled_modules, :users, :members,
+           :member_roles, :roles, :trackers, :issue_statuses,
+           :issue_categories, :enumerations, :issues,
+           :watchers, :custom_fields, :custom_values, :versions,
+           :queries,
+           :projects_trackers,
+           :custom_fields_trackers
+
+  def test_available_filters_should_be_ordered
+    query = IssueQuery.new
+    assert_equal 0, query.available_filters.keys.index('status_id')
+  end
+
+  def test_custom_fields_for_all_projects_should_be_available_in_global_queries
+    query = IssueQuery.new(:project => nil, :name => '_')
+    assert query.available_filters.has_key?('cf_1')
+    assert !query.available_filters.has_key?('cf_3')
+  end
+
+  def test_system_shared_versions_should_be_available_in_global_queries
+    Version.find(2).update_attribute :sharing, 'system'
+    query = IssueQuery.new(:project => nil, :name => '_')
+    assert query.available_filters.has_key?('fixed_version_id')
+    assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'}
+  end
+
+  def test_project_filter_in_global_queries
+    query = IssueQuery.new(:project => nil, :name => '_')
+    project_filter = query.available_filters["project_id"]
+    assert_not_nil project_filter
+    project_ids = project_filter[:values].map{|p| p[1]}
+    assert project_ids.include?("1")  #public project
+    assert !project_ids.include?("2") #private project user cannot see
+  end
+
+  def find_issues_with_query(query)
+    Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where(
+         query.statement
+       ).all
+  end
+
+  def assert_find_issues_with_query_is_successful(query)
+    assert_nothing_raised do
+      find_issues_with_query(query)
+    end
+  end
+
+  def assert_query_statement_includes(query, condition)
+    assert_include condition, query.statement
+  end
+  
+  def assert_query_result(expected, query)
+    assert_nothing_raised do
+      assert_equal expected.map(&:id).sort, query.issues.map(&:id).sort
+      assert_equal expected.size, query.issue_count
+    end
+  end
+
+  def test_query_should_allow_shared_versions_for_a_project_query
+    subproject_version = Version.find(4)
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
+
+    assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
+  end
+
+  def test_query_with_multiple_custom_fields
+    query = IssueQuery.find(1)
+    assert query.valid?
+    assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
+    issues = find_issues_with_query(query)
+    assert_equal 1, issues.length
+    assert_equal Issue.find(3), issues.first
+  end
+
+  def test_operator_none
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('fixed_version_id', '!*', [''])
+    query.add_filter('cf_1', '!*', [''])
+    assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
+    assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
+    find_issues_with_query(query)
+  end
+
+  def test_operator_none_for_integer
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('estimated_hours', '!*', [''])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    assert issues.all? {|i| !i.estimated_hours}
+  end
+
+  def test_operator_none_for_date
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('start_date', '!*', [''])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    assert issues.all? {|i| i.start_date.nil?}
+  end
+
+  def test_operator_none_for_string_custom_field
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('cf_2', '!*', [''])
+    assert query.has_filter?('cf_2')
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    assert issues.all? {|i| i.custom_field_value(2).blank?}
+  end
+
+  def test_operator_all
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('fixed_version_id', '*', [''])
+    query.add_filter('cf_1', '*', [''])
+    assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
+    assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
+    find_issues_with_query(query)
+  end
+
+  def test_operator_all_for_date
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('start_date', '*', [''])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    assert issues.all? {|i| i.start_date.present?}
+  end
+
+  def test_operator_all_for_string_custom_field
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('cf_2', '*', [''])
+    assert query.has_filter?('cf_2')
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    assert issues.all? {|i| i.custom_field_value(2).present?}
+  end
+
+  def test_numeric_filter_should_not_accept_non_numeric_values
+    query = IssueQuery.new(:name => '_')
+    query.add_filter('estimated_hours', '=', ['a'])
+
+    assert query.has_filter?('estimated_hours')
+    assert !query.valid?
+  end
+
+  def test_operator_is_on_float
+    Issue.update_all("estimated_hours = 171.2", "id=2")
+
+    query = IssueQuery.new(:name => '_')
+    query.add_filter('estimated_hours', '=', ['171.20'])
+    issues = find_issues_with_query(query)
+    assert_equal 1, issues.size
+    assert_equal 2, issues.first.id
+  end
+
+  def test_operator_is_on_integer_custom_field
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true)
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
+
+    query = IssueQuery.new(:name => '_')
+    query.add_filter("cf_#{f.id}", '=', ['12'])
+    issues = find_issues_with_query(query)
+    assert_equal 1, issues.size
+    assert_equal 2, issues.first.id
+  end
+
+  def test_operator_is_on_integer_custom_field_should_accept_negative_value
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true)
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
+
+    query = IssueQuery.new(:name => '_')
+    query.add_filter("cf_#{f.id}", '=', ['-12'])
+    assert query.valid?
+    issues = find_issues_with_query(query)
+    assert_equal 1, issues.size
+    assert_equal 2, issues.first.id
+  end
+
+  def test_operator_is_on_float_custom_field
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true)
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12.7')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
+
+    query = IssueQuery.new(:name => '_')
+    query.add_filter("cf_#{f.id}", '=', ['12.7'])
+    issues = find_issues_with_query(query)
+    assert_equal 1, issues.size
+    assert_equal 2, issues.first.id
+  end
+
+  def test_operator_is_on_float_custom_field_should_accept_negative_value
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true)
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12.7')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
+
+    query = IssueQuery.new(:name => '_')
+    query.add_filter("cf_#{f.id}", '=', ['-12.7'])
+    assert query.valid?
+    issues = find_issues_with_query(query)
+    assert_equal 1, issues.size
+    assert_equal 2, issues.first.id
+  end
+
+  def test_operator_is_on_multi_list_custom_field
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
+      :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
+
+    query = IssueQuery.new(:name => '_')
+    query.add_filter("cf_#{f.id}", '=', ['value1'])
+    issues = find_issues_with_query(query)
+    assert_equal [1, 3], issues.map(&:id).sort
+
+    query = IssueQuery.new(:name => '_')
+    query.add_filter("cf_#{f.id}", '=', ['value2'])
+    issues = find_issues_with_query(query)
+    assert_equal [1], issues.map(&:id).sort
+  end
+
+  def test_operator_is_not_on_multi_list_custom_field
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
+      :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
+
+    query = IssueQuery.new(:name => '_')
+    query.add_filter("cf_#{f.id}", '!', ['value1'])
+    issues = find_issues_with_query(query)
+    assert !issues.map(&:id).include?(1)
+    assert !issues.map(&:id).include?(3)
+
+    query = IssueQuery.new(:name => '_')
+    query.add_filter("cf_#{f.id}", '!', ['value2'])
+    issues = find_issues_with_query(query)
+    assert !issues.map(&:id).include?(1)
+    assert issues.map(&:id).include?(3)
+  end
+
+  def test_operator_is_on_is_private_field
+    # is_private filter only available for those who can set issues private
+    User.current = User.find(2)
+
+    query = IssueQuery.new(:name => '_')
+    assert query.available_filters.key?('is_private')
+
+    query.add_filter("is_private", '=', ['1'])
+    issues = find_issues_with_query(query)
+    assert issues.any?
+    assert_nil issues.detect {|issue| !issue.is_private?}
+  ensure
+    User.current = nil
+  end
+
+  def test_operator_is_not_on_is_private_field
+    # is_private filter only available for those who can set issues private
+    User.current = User.find(2)
+
+    query = IssueQuery.new(:name => '_')
+    assert query.available_filters.key?('is_private')
+
+    query.add_filter("is_private", '!', ['1'])
+    issues = find_issues_with_query(query)
+    assert issues.any?
+    assert_nil issues.detect {|issue| issue.is_private?}
+  ensure
+    User.current = nil
+  end
+
+  def test_operator_greater_than
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('done_ratio', '>=', ['40'])
+    assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
+    find_issues_with_query(query)
+  end
+
+  def test_operator_greater_than_a_float
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('estimated_hours', '>=', ['40.5'])
+    assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
+    find_issues_with_query(query)
+  end
+
+  def test_operator_greater_than_on_int_custom_field
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
+
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter("cf_#{f.id}", '>=', ['8'])
+    issues = find_issues_with_query(query)
+    assert_equal 1, issues.size
+    assert_equal 2, issues.first.id
+  end
+
+  def test_operator_lesser_than
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('done_ratio', '<=', ['30'])
+    assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
+    find_issues_with_query(query)
+  end
+
+  def test_operator_lesser_than_on_custom_field
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter("cf_#{f.id}", '<=', ['30'])
+    assert_match /CAST.+ <= 30\.0/, query.statement
+    find_issues_with_query(query)
+  end
+
+  def test_operator_lesser_than_on_date_custom_field
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'date', :is_filter => true, :is_for_all => true)
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '2013-04-11')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '2013-05-14')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
+
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter("cf_#{f.id}", '<=', ['2013-05-01'])
+    issue_ids = find_issues_with_query(query).map(&:id)
+    assert_include 1, issue_ids
+    assert_not_include 2, issue_ids
+    assert_not_include 3, issue_ids
+  end
+
+  def test_operator_between
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('done_ratio', '><', ['30', '40'])
+    assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
+    find_issues_with_query(query)
+  end
+
+  def test_operator_between_on_custom_field
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter("cf_#{f.id}", '><', ['30', '40'])
+    assert_match /CAST.+ BETWEEN 30.0 AND 40.0/, query.statement
+    find_issues_with_query(query)
+  end
+
+  def test_date_filter_should_not_accept_non_date_values
+    query = IssueQuery.new(:name => '_')
+    query.add_filter('created_on', '=', ['a'])
+
+    assert query.has_filter?('created_on')
+    assert !query.valid?
+  end
+
+  def test_date_filter_should_not_accept_invalid_date_values
+    query = IssueQuery.new(:name => '_')
+    query.add_filter('created_on', '=', ['2011-01-34'])
+
+    assert query.has_filter?('created_on')
+    assert !query.valid?
+  end
+
+  def test_relative_date_filter_should_not_accept_non_integer_values
+    query = IssueQuery.new(:name => '_')
+    query.add_filter('created_on', '>t-', ['a'])
+
+    assert query.has_filter?('created_on')
+    assert !query.valid?
+  end
+
+  def test_operator_date_equals
+    query = IssueQuery.new(:name => '_')
+    query.add_filter('due_date', '=', ['2011-07-10'])
+    assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
+    find_issues_with_query(query)
+  end
+
+  def test_operator_date_lesser_than
+    query = IssueQuery.new(:name => '_')
+    query.add_filter('due_date', '<=', ['2011-07-10'])
+    assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
+    find_issues_with_query(query)
+  end
+
+  def test_operator_date_greater_than
+    query = IssueQuery.new(:name => '_')
+    query.add_filter('due_date', '>=', ['2011-07-10'])
+    assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
+    find_issues_with_query(query)
+  end
+
+  def test_operator_date_between
+    query = IssueQuery.new(:name => '_')
+    query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
+    assert_match /issues\.due_date > '2011-06-22 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
+    find_issues_with_query(query)
+  end
+
+  def test_operator_in_more_than
+    Issue.find(7).update_attribute(:due_date, (Date.today + 15))
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', '>t+', ['15'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
+  end
+
+  def test_operator_in_less_than
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', '<t+', ['15'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date <= (Date.today + 15))}
+  end
+
+  def test_operator_in_the_next_days
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', '><t+', ['15'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
+  end
+
+  def test_operator_less_than_ago
+    Issue.find(7).update_attribute(:due_date, (Date.today - 3))
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', '>t-', ['3'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date >= (Date.today - 3))}
+  end
+
+  def test_operator_in_the_past_days
+    Issue.find(7).update_attribute(:due_date, (Date.today - 3))
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', '><t-', ['3'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
+  end
+
+  def test_operator_more_than_ago
+    Issue.find(7).update_attribute(:due_date, (Date.today - 10))
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', '<t-', ['10'])
+    assert query.statement.include?("#{Issue.table_name}.due_date <=")
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
+  end
+
+  def test_operator_in
+    Issue.find(7).update_attribute(:due_date, (Date.today + 2))
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', 't+', ['2'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
+  end
+
+  def test_operator_ago
+    Issue.find(7).update_attribute(:due_date, (Date.today - 3))
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', 't-', ['3'])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
+  end
+
+  def test_operator_today
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', 't', [''])
+    issues = find_issues_with_query(query)
+    assert !issues.empty?
+    issues.each {|issue| assert_equal Date.today, issue.due_date}
+  end
+
+  def test_operator_this_week_on_date
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', 'w', [''])
+    find_issues_with_query(query)
+  end
+
+  def test_operator_this_week_on_datetime
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('created_on', 'w', [''])
+    find_issues_with_query(query)
+  end
+
+  def test_operator_contains
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('subject', '~', ['uNable'])
+    assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
+    result = find_issues_with_query(query)
+    assert result.empty?
+    result.each {|issue| assert issue.subject.downcase.include?('unable') }
+  end
+
+  def test_range_for_this_week_with_week_starting_on_monday
+    I18n.locale = :fr
+    assert_equal '1', I18n.t(:general_first_day_of_week)
+
+    Date.stubs(:today).returns(Date.parse('2011-04-29'))
+
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', 'w', [''])
+    assert query.statement.match(/issues\.due_date > '2011-04-24 23:59:59(\.9+)?' AND issues\.due_date <= '2011-05-01 23:59:59(\.9+)?/), "range not found in #{query.statement}"
+    I18n.locale = :en
+  end
+
+  def test_range_for_this_week_with_week_starting_on_sunday
+    I18n.locale = :en
+    assert_equal '7', I18n.t(:general_first_day_of_week)
+
+    Date.stubs(:today).returns(Date.parse('2011-04-29'))
+
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('due_date', 'w', [''])
+    assert query.statement.match(/issues\.due_date > '2011-04-23 23:59:59(\.9+)?' AND issues\.due_date <= '2011-04-30 23:59:59(\.9+)?/), "range not found in #{query.statement}"
+  end
+
+  def test_operator_does_not_contains
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter('subject', '!~', ['uNable'])
+    assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
+    find_issues_with_query(query)
+  end
+
+  def test_filter_assigned_to_me
+    user = User.find(2)
+    group = Group.find(10)
+    User.current = user
+    i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user)
+    i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group)
+    i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
+    group.users << user
+
+    query = IssueQuery.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
+    result = query.issues
+    assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id)
+
+    assert result.include?(i1)
+    assert result.include?(i2)
+    assert !result.include?(i3)
+  end
+
+  def test_user_custom_field_filtered_on_me
+    User.current = User.find(2)
+    cf = IssueCustomField.create!(:field_format => 'user', :is_for_all => true, :is_filter => true, :name => 'User custom field', :tracker_ids => [1])
+    issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '2'}, :subject => 'Test', :author_id => 1)
+    issue2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '3'})
+
+    query = IssueQuery.new(:name => '_', :project => Project.find(1))
+    filter = query.available_filters["cf_#{cf.id}"]
+    assert_not_nil filter
+    assert_include 'me', filter[:values].map{|v| v[1]}
+
+    query.filters = { "cf_#{cf.id}" => {:operator => '=', :values => ['me']}}
+    result = query.issues
+    assert_equal 1, result.size
+    assert_equal issue1, result.first
+  end
+
+  def test_filter_my_projects
+    User.current = User.find(2)
+    query = IssueQuery.new(:name => '_')
+    filter = query.available_filters['project_id']
+    assert_not_nil filter
+    assert_include 'mine', filter[:values].map{|v| v[1]}
+
+    query.filters = { 'project_id' => {:operator => '=', :values => ['mine']}}
+    result = query.issues
+    assert_nil result.detect {|issue| !User.current.member_of?(issue.project)}
+  end
+
+  def test_filter_watched_issues
+    User.current = User.find(1)
+    query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
+    result = find_issues_with_query(query)
+    assert_not_nil result
+    assert !result.empty?
+    assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
+    User.current = nil
+  end
+
+  def test_filter_unwatched_issues
+    User.current = User.find(1)
+    query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
+    result = find_issues_with_query(query)
+    assert_not_nil result
+    assert !result.empty?
+    assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
+    User.current = nil
+  end
+
+  def test_filter_on_project_custom_field
+    field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
+    CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
+    CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
+
+    query = IssueQuery.new(:name => '_')
+    filter_name = "project.cf_#{field.id}"
+    assert_include filter_name, query.available_filters.keys
+    query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
+    assert_equal [3, 5], find_issues_with_query(query).map(&:project_id).uniq.sort
+  end
+
+  def test_filter_on_author_custom_field
+    field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
+    CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
+
+    query = IssueQuery.new(:name => '_')
+    filter_name = "author.cf_#{field.id}"
+    assert_include filter_name, query.available_filters.keys
+    query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
+    assert_equal [3], find_issues_with_query(query).map(&:author_id).uniq.sort
+  end
+
+  def test_filter_on_assigned_to_custom_field
+    field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
+    CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
+
+    query = IssueQuery.new(:name => '_')
+    filter_name = "assigned_to.cf_#{field.id}"
+    assert_include filter_name, query.available_filters.keys
+    query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
+    assert_equal [3], find_issues_with_query(query).map(&:assigned_to_id).uniq.sort
+  end
+
+  def test_filter_on_fixed_version_custom_field
+    field = VersionCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
+    CustomValue.create!(:custom_field => field, :customized => Version.find(2), :value => 'Foo')
+
+    query = IssueQuery.new(:name => '_')
+    filter_name = "fixed_version.cf_#{field.id}"
+    assert_include filter_name, query.available_filters.keys
+    query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
+    assert_equal [2], find_issues_with_query(query).map(&:fixed_version_id).uniq.sort
+  end
+
+  def test_filter_on_relations_with_a_specific_issue
+    IssueRelation.delete_all
+    IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
+    IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
+
+    query = IssueQuery.new(:name => '_')
+    query.filters = {"relates" => {:operator => '=', :values => ['1']}}
+    assert_equal [2, 3], find_issues_with_query(query).map(&:id).sort
+
+    query = IssueQuery.new(:name => '_')
+    query.filters = {"relates" => {:operator => '=', :values => ['2']}}
+    assert_equal [1], find_issues_with_query(query).map(&:id).sort
+  end
+
+  def test_filter_on_relations_with_any_issues_in_a_project
+    IssueRelation.delete_all
+    with_settings :cross_project_issue_relations => '1' do
+      IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
+      IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(2).issues.first)
+      IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
+    end
+
+    query = IssueQuery.new(:name => '_')
+    query.filters = {"relates" => {:operator => '=p', :values => ['2']}}
+    assert_equal [1, 2], find_issues_with_query(query).map(&:id).sort
+
+    query = IssueQuery.new(:name => '_')
+    query.filters = {"relates" => {:operator => '=p', :values => ['3']}}
+    assert_equal [1], find_issues_with_query(query).map(&:id).sort
+
+    query = IssueQuery.new(:name => '_')
+    query.filters = {"relates" => {:operator => '=p', :values => ['4']}}
+    assert_equal [], find_issues_with_query(query).map(&:id).sort
+  end
+
+  def test_filter_on_relations_with_any_issues_not_in_a_project
+    IssueRelation.delete_all
+    with_settings :cross_project_issue_relations => '1' do
+      IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
+      #IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(1).issues.first)
+      IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
+    end
+
+    query = IssueQuery.new(:name => '_')
+    query.filters = {"relates" => {:operator => '=!p', :values => ['1']}}
+    assert_equal [1], find_issues_with_query(query).map(&:id).sort
+  end
+
+  def test_filter_on_relations_with_no_issues_in_a_project
+    IssueRelation.delete_all
+    with_settings :cross_project_issue_relations => '1' do
+      IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
+      IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(3).issues.first)
+      IssueRelation.create!(:relation_type => "relates", :issue_to => Project.find(2).issues.first, :issue_from => Issue.find(3))
+    end
+
+    query = IssueQuery.new(:name => '_')
+    query.filters = {"relates" => {:operator => '!p', :values => ['2']}}
+    ids = find_issues_with_query(query).map(&:id).sort
+    assert_include 2, ids
+    assert_not_include 1, ids
+    assert_not_include 3, ids
+  end
+
+  def test_filter_on_relations_with_no_issues
+    IssueRelation.delete_all
+    IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
+    IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
+
+    query = IssueQuery.new(:name => '_')
+    query.filters = {"relates" => {:operator => '!*', :values => ['']}}
+    ids = find_issues_with_query(query).map(&:id)
+    assert_equal [], ids & [1, 2, 3]
+    assert_include 4, ids
+  end
+
+  def test_filter_on_relations_with_any_issues
+    IssueRelation.delete_all
+    IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
+    IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
+
+    query = IssueQuery.new(:name => '_')
+    query.filters = {"relates" => {:operator => '*', :values => ['']}}
+    assert_equal [1, 2, 3], find_issues_with_query(query).map(&:id).sort
+  end
+
+  def test_statement_should_be_nil_with_no_filters
+    q = IssueQuery.new(:name => '_')
+    q.filters = {}
+
+    assert q.valid?
+    assert_nil q.statement
+  end
+
+  def test_default_columns
+    q = IssueQuery.new
+    assert q.columns.any?
+    assert q.inline_columns.any?
+    assert q.block_columns.empty?
+  end
+
+  def test_set_column_names
+    q = IssueQuery.new
+    q.column_names = ['tracker', :subject, '', 'unknonw_column']
+    assert_equal [:id, :tracker, :subject], q.columns.collect {|c| c.name}
+  end
+
+  def test_has_column_should_accept_a_column_name
+    q = IssueQuery.new
+    q.column_names = ['tracker', :subject]
+    assert q.has_column?(:tracker)
+    assert !q.has_column?(:category)
+  end
+
+  def test_has_column_should_accept_a_column
+    q = IssueQuery.new
+    q.column_names = ['tracker', :subject]
+
+    tracker_column = q.available_columns.detect {|c| c.name==:tracker}
+    assert_kind_of QueryColumn, tracker_column
+    category_column = q.available_columns.detect {|c| c.name==:category}
+    assert_kind_of QueryColumn, category_column
+
+    assert q.has_column?(tracker_column)
+    assert !q.has_column?(category_column)
+  end
+
+  def test_inline_and_block_columns
+    q = IssueQuery.new
+    q.column_names = ['subject', 'description', 'tracker']
+
+    assert_equal [:id, :subject, :tracker], q.inline_columns.map(&:name)
+    assert_equal [:description], q.block_columns.map(&:name)
+  end
+
+  def test_custom_field_columns_should_be_inline
+    q = IssueQuery.new
+    columns = q.available_columns.select {|column| column.is_a? QueryCustomFieldColumn}
+    assert columns.any?
+    assert_nil columns.detect {|column| !column.inline?}
+  end
+
+  def test_query_should_preload_spent_hours
+    q = IssueQuery.new(:name => '_', :column_names => [:subject, :spent_hours])
+    assert q.has_column?(:spent_hours)
+    issues = q.issues
+    assert_not_nil issues.first.instance_variable_get("@spent_hours")
+  end
+
+  def test_groupable_columns_should_include_custom_fields
+    q = IssueQuery.new
+    column = q.groupable_columns.detect {|c| c.name == :cf_1}
+    assert_not_nil column
+    assert_kind_of QueryCustomFieldColumn, column
+  end
+
+  def test_groupable_columns_should_not_include_multi_custom_fields
+    field = CustomField.find(1)
+    field.update_attribute :multiple, true
+
+    q = IssueQuery.new
+    column = q.groupable_columns.detect {|c| c.name == :cf_1}
+    assert_nil column
+  end
+
+  def test_groupable_columns_should_include_user_custom_fields
+    cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'user')
+
+    q = IssueQuery.new
+    assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
+  end
+
+  def test_groupable_columns_should_include_version_custom_fields
+    cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'version')
+
+    q = IssueQuery.new
+    assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
+  end
+
+  def test_grouped_with_valid_column
+    q = IssueQuery.new(:group_by => 'status')
+    assert q.grouped?
+    assert_not_nil q.group_by_column
+    assert_equal :status, q.group_by_column.name
+    assert_not_nil q.group_by_statement
+    assert_equal 'status', q.group_by_statement
+  end
+
+  def test_grouped_with_invalid_column
+    q = IssueQuery.new(:group_by => 'foo')
+    assert !q.grouped?
+    assert_nil q.group_by_column
+    assert_nil q.group_by_statement
+  end
+  
+  def test_sortable_columns_should_sort_assignees_according_to_user_format_setting
+    with_settings :user_format => 'lastname_coma_firstname' do
+      q = IssueQuery.new
+      assert q.sortable_columns.has_key?('assigned_to')
+      assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to']
+    end
+  end
+  
+  def test_sortable_columns_should_sort_authors_according_to_user_format_setting
+    with_settings :user_format => 'lastname_coma_firstname' do
+      q = IssueQuery.new
+      assert q.sortable_columns.has_key?('author')
+      assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author']
+    end
+  end
+
+  def test_sortable_columns_should_include_custom_field
+    q = IssueQuery.new
+    assert q.sortable_columns['cf_1']
+  end
+
+  def test_sortable_columns_should_not_include_multi_custom_field
+    field = CustomField.find(1)
+    field.update_attribute :multiple, true
+
+    q = IssueQuery.new
+    assert !q.sortable_columns['cf_1']
+  end
+
+  def test_default_sort
+    q = IssueQuery.new
+    assert_equal [], q.sort_criteria
+  end
+
+  def test_set_sort_criteria_with_hash
+    q = IssueQuery.new
+    q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
+    assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
+  end
+
+  def test_set_sort_criteria_with_array
+    q = IssueQuery.new
+    q.sort_criteria = [['priority', 'desc'], 'tracker']
+    assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
+  end
+
+  def test_create_query_with_sort
+    q = IssueQuery.new(:name => 'Sorted')
+    q.sort_criteria = [['priority', 'desc'], 'tracker']
+    assert q.save
+    q.reload
+    assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
+  end
+
+  def test_sort_by_string_custom_field_asc
+    q = IssueQuery.new
+    c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
+    assert c
+    assert c.sortable
+    issues = q.issues(:order => "#{c.sortable} ASC")
+    values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
+    assert !values.empty?
+    assert_equal values.sort, values
+  end
+
+  def test_sort_by_string_custom_field_desc
+    q = IssueQuery.new
+    c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
+    assert c
+    assert c.sortable
+    issues = q.issues(:order => "#{c.sortable} DESC")
+    values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
+    assert !values.empty?
+    assert_equal values.sort.reverse, values
+  end
+
+  def test_sort_by_float_custom_field_asc
+    q = IssueQuery.new
+    c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
+    assert c
+    assert c.sortable
+    issues = q.issues(:order => "#{c.sortable} ASC")
+    values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
+    assert !values.empty?
+    assert_equal values.sort, values
+  end
+
+  def test_invalid_query_should_raise_query_statement_invalid_error
+    q = IssueQuery.new
+    assert_raise Query::StatementInvalid do
+      q.issues(:conditions => "foo = 1")
+    end
+  end
+
+  def test_issue_count
+    q = IssueQuery.new(:name => '_')
+    issue_count = q.issue_count
+    assert_equal q.issues.size, issue_count
+  end
+
+  def test_issue_count_with_archived_issues
+    p = Project.generate! do |project|
+      project.status = Project::STATUS_ARCHIVED
+    end
+    i = Issue.generate!( :project => p, :tracker => p.trackers.first )
+    assert !i.visible?
+
+    test_issue_count
+  end
+
+  def test_issue_count_by_association_group
+    q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
+    count_by_group = q.issue_count_by_group
+    assert_kind_of Hash, count_by_group
+    assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
+    assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
+    assert count_by_group.has_key?(User.find(3))
+  end
+
+  def test_issue_count_by_list_custom_field_group
+    q = IssueQuery.new(:name => '_', :group_by => 'cf_1')
+    count_by_group = q.issue_count_by_group
+    assert_kind_of Hash, count_by_group
+    assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
+    assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
+    assert count_by_group.has_key?('MySQL')
+  end
+
+  def test_issue_count_by_date_custom_field_group
+    q = IssueQuery.new(:name => '_', :group_by => 'cf_8')
+    count_by_group = q.issue_count_by_group
+    assert_kind_of Hash, count_by_group
+    assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
+    assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
+  end
+
+  def test_issue_count_with_nil_group_only
+    Issue.update_all("assigned_to_id = NULL")
+
+    q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
+    count_by_group = q.issue_count_by_group
+    assert_kind_of Hash, count_by_group
+    assert_equal 1, count_by_group.keys.size
+    assert_nil count_by_group.keys.first
+  end
+
+  def test_issue_ids
+    q = IssueQuery.new(:name => '_')
+    order = "issues.subject, issues.id"
+    issues = q.issues(:order => order)
+    assert_equal issues.map(&:id), q.issue_ids(:order => order)
+  end
+
+  def test_label_for
+    set_language_if_valid 'en'
+    q = IssueQuery.new
+    assert_equal 'Assignee', q.label_for('assigned_to_id')
+  end
+
+  def test_label_for_fr
+    set_language_if_valid 'fr'
+    q = IssueQuery.new
+    s = "Assign\xc3\xa9 \xc3\xa0"
+    s.force_encoding('UTF-8') if s.respond_to?(:force_encoding)
+    assert_equal s, q.label_for('assigned_to_id')
+  end
+
+  def test_editable_by
+    admin = User.find(1)
+    manager = User.find(2)
+    developer = User.find(3)
+
+    # Public query on project 1
+    q = IssueQuery.find(1)
+    assert q.editable_by?(admin)
+    assert q.editable_by?(manager)
+    assert !q.editable_by?(developer)
+
+    # Private query on project 1
+    q = IssueQuery.find(2)
+    assert q.editable_by?(admin)
+    assert !q.editable_by?(manager)
+    assert q.editable_by?(developer)
+
+    # Private query for all projects
+    q = IssueQuery.find(3)
+    assert q.editable_by?(admin)
+    assert !q.editable_by?(manager)
+    assert q.editable_by?(developer)
+
+    # Public query for all projects
+    q = IssueQuery.find(4)
+    assert q.editable_by?(admin)
+    assert !q.editable_by?(manager)
+    assert !q.editable_by?(developer)
+  end
+
+  def test_visible_scope
+    query_ids = IssueQuery.visible(User.anonymous).map(&:id)
+
+    assert query_ids.include?(1), 'public query on public project was not visible'
+    assert query_ids.include?(4), 'public query for all projects was not visible'
+    assert !query_ids.include?(2), 'private query on public project was visible'
+    assert !query_ids.include?(3), 'private query for all projects was visible'
+    assert !query_ids.include?(7), 'public query on private project was visible'
+  end
+
+  test "#available_filters should include users of visible projects in cross-project view" do
+    users = IssueQuery.new.available_filters["assigned_to_id"]
+    assert_not_nil users
+    assert users[:values].map{|u|u[1]}.include?("3")
+  end
+
+  test "#available_filters should include users of subprojects" do
+    user1 = User.generate!
+    user2 = User.generate!
+    project = Project.find(1)
+    Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1])
+
+    users = IssueQuery.new(:project => project).available_filters["assigned_to_id"]
+    assert_not_nil users
+    assert users[:values].map{|u|u[1]}.include?(user1.id.to_s)
+    assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s)
+  end
+
+  test "#available_filters should include visible projects in cross-project view" do
+    projects = IssueQuery.new.available_filters["project_id"]
+    assert_not_nil projects
+    assert projects[:values].map{|u|u[1]}.include?("1")
+  end
+
+  test "#available_filters should include 'member_of_group' filter" do
+    query = IssueQuery.new
+    assert query.available_filters.keys.include?("member_of_group")
+    assert_equal :list_optional, query.available_filters["member_of_group"][:type]
+    assert query.available_filters["member_of_group"][:values].present?
+    assert_equal Group.all.sort.map {|g| [g.name, g.id.to_s]},
+      query.available_filters["member_of_group"][:values].sort
+  end
+
+  test "#available_filters should include 'assigned_to_role' filter" do
+    query = IssueQuery.new
+    assert query.available_filters.keys.include?("assigned_to_role")
+    assert_equal :list_optional, query.available_filters["assigned_to_role"][:type]
+
+    assert query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
+    assert query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
+    assert query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
+
+    assert ! query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
+    assert ! query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
+  end
+
+  context "#statement" do
+    context "with 'member_of_group' filter" do
+      setup do
+        Group.destroy_all # No fixtures
+        @user_in_group = User.generate!
+        @second_user_in_group = User.generate!
+        @user_in_group2 = User.generate!
+        @user_not_in_group = User.generate!
+
+        @group = Group.generate!.reload
+        @group.users << @user_in_group
+        @group.users << @second_user_in_group
+
+        @group2 = Group.generate!.reload
+        @group2.users << @user_in_group2
+
+      end
+
+      should "search assigned to for users in the group" do
+        @query = IssueQuery.new(:name => '_')
+        @query.add_filter('member_of_group', '=', [@group.id.to_s])
+
+        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@group.id}')"
+        assert_find_issues_with_query_is_successful @query
+      end
+
+      should "search not assigned to any group member (none)" do
+        @query = IssueQuery.new(:name => '_')
+        @query.add_filter('member_of_group', '!*', [''])
+
+        # Users not in a group
+        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}','#{@group.id}','#{@group2.id}')"
+        assert_find_issues_with_query_is_successful @query
+      end
+
+      should "search assigned to any group member (all)" do
+        @query = IssueQuery.new(:name => '_')
+        @query.add_filter('member_of_group', '*', [''])
+
+        # Only users in a group
+        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}','#{@group.id}','#{@group2.id}')"
+        assert_find_issues_with_query_is_successful @query
+      end
+
+      should "return an empty set with = empty group" do
+        @empty_group = Group.generate!
+        @query = IssueQuery.new(:name => '_')
+        @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
+
+        assert_equal [], find_issues_with_query(@query)
+      end
+
+      should "return issues with ! empty group" do
+        @empty_group = Group.generate!
+        @query = IssueQuery.new(:name => '_')
+        @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
+
+        assert_find_issues_with_query_is_successful @query
+      end
+    end
+
+    context "with 'assigned_to_role' filter" do
+      setup do
+        @manager_role = Role.find_by_name('Manager')
+        @developer_role = Role.find_by_name('Developer')
+
+        @project = Project.generate!
+        @manager = User.generate!
+        @developer = User.generate!
+        @boss = User.generate!
+        @guest = User.generate!
+        User.add_to_project(@manager, @project, @manager_role)
+        User.add_to_project(@developer, @project, @developer_role)
+        User.add_to_project(@boss, @project, [@manager_role, @developer_role])
+        
+        @issue1 = Issue.generate!(:project => @project, :assigned_to_id => @manager.id)
+        @issue2 = Issue.generate!(:project => @project, :assigned_to_id => @developer.id)
+        @issue3 = Issue.generate!(:project => @project, :assigned_to_id => @boss.id)
+        @issue4 = Issue.generate!(:project => @project, :assigned_to_id => @guest.id)
+        @issue5 = Issue.generate!(:project => @project)
+      end
+
+      should "search assigned to for users with the Role" do
+        @query = IssueQuery.new(:name => '_', :project => @project)
+        @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
+
+        assert_query_result [@issue1, @issue3], @query
+      end
+
+      should "search assigned to for users with the Role on the issue project" do
+        other_project = Project.generate!
+        User.add_to_project(@developer, other_project, @manager_role)
+        
+        @query = IssueQuery.new(:name => '_', :project => @project)
+        @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
+
+        assert_query_result [@issue1, @issue3], @query
+      end
+
+      should "return an empty set with empty role" do
+        @empty_role = Role.generate!
+        @query = IssueQuery.new(:name => '_', :project => @project)
+        @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
+
+        assert_query_result [], @query
+      end
+
+      should "search assigned to for users without the Role" do
+        @query = IssueQuery.new(:name => '_', :project => @project)
+        @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s])
+
+        assert_query_result [@issue2, @issue4, @issue5], @query
+      end
+
+      should "search assigned to for users not assigned to any Role (none)" do
+        @query = IssueQuery.new(:name => '_', :project => @project)
+        @query.add_filter('assigned_to_role', '!*', [''])
+
+        assert_query_result [@issue4, @issue5], @query
+      end
+
+      should "search assigned to for users assigned to any Role (all)" do
+        @query = IssueQuery.new(:name => '_', :project => @project)
+        @query.add_filter('assigned_to_role', '*', [''])
+
+        assert_query_result [@issue1, @issue2, @issue3], @query
+      end
+
+      should "return issues with ! empty role" do
+        @empty_role = Role.generate!
+        @query = IssueQuery.new(:name => '_', :project => @project)
+        @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s])
+
+        assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/45b8269cf1731acb2f145d6ea43cdd52da6f4d4a.svn-base
--- /dev/null
+++ b/.svn/pristine/45/45b8269cf1731acb2f145d6ea43cdd52da6f4d4a.svn-base
@@ -0,0 +1,101 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class TrackersController < ApplicationController
+  layout 'admin'
+
+  before_filter :require_admin, :except => :index
+  before_filter :require_admin_or_api_request, :only => :index
+  accept_api_auth :index
+
+  def index
+    respond_to do |format|
+      format.html {
+        @tracker_pages, @trackers = paginate Tracker.sorted, :per_page => 25
+        render :action => "index", :layout => false if request.xhr?
+      }
+      format.api {
+        @trackers = Tracker.sorted.all
+      }
+    end
+  end
+
+  def new
+    @tracker ||= Tracker.new(params[:tracker])
+    @trackers = Tracker.sorted.all
+    @projects = Project.all
+  end
+
+  def create
+    @tracker = Tracker.new(params[:tracker])
+    if @tracker.save
+      # workflow copy
+      if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from]))
+        @tracker.workflow_rules.copy(copy_from)
+      end
+      flash[:notice] = l(:notice_successful_create)
+      redirect_to trackers_path
+      return
+    end
+    new
+    render :action => 'new'
+  end
+
+  def edit
+    @tracker ||= Tracker.find(params[:id])
+    @projects = Project.all
+  end
+
+  def update
+    @tracker = Tracker.find(params[:id])
+    if @tracker.update_attributes(params[:tracker])
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to trackers_path
+      return
+    end
+    edit
+    render :action => 'edit'
+  end
+
+  def destroy
+    @tracker = Tracker.find(params[:id])
+    unless @tracker.issues.empty?
+      flash[:error] = l(:error_can_not_delete_tracker)
+    else
+      @tracker.destroy
+    end
+    redirect_to trackers_path
+  end
+
+  def fields
+    if request.post? && params[:trackers]
+      params[:trackers].each do |tracker_id, tracker_params|
+        tracker = Tracker.find_by_id(tracker_id)
+        if tracker
+          tracker.core_fields = tracker_params[:core_fields]
+          tracker.custom_field_ids = tracker_params[:custom_field_ids]
+          tracker.save
+        end
+      end
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to fields_trackers_path
+      return
+    end
+    @trackers = Tracker.sorted.all
+    @custom_fields = IssueCustomField.all.sort
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/45ba0113063b6030bb97f2bd03aad9a662b0bfbf.svn-base
--- a/.svn/pristine/45/45ba0113063b6030bb97f2bd03aad9a662b0bfbf.svn-base
+++ /dev/null
@@ -1,74 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class ThemesTest < ActionController::IntegrationTest
-
-  def setup
-    @theme = Redmine::Themes.themes.last
-    Setting.ui_theme = @theme.id
-  end
-
-  def teardown
-    Setting.ui_theme = ''
-  end
-
-  def test_application_css
-    get '/'
-
-    assert_response :success
-    assert_tag :tag => 'link',
-      :attributes => {:href => %r{^/themes/#{@theme.dir}/stylesheets/application.css}}
-  end
-
-  def test_without_theme_js
-    get '/'
-
-    assert_response :success
-    assert_no_tag :tag => 'script',
-      :attributes => {:src => %r{^/themes/#{@theme.dir}/javascripts/theme.js}}
-  end
-
-  def test_with_theme_js
-    # Simulates a theme.js
-    @theme.javascripts << 'theme'
-    get '/'
-
-    assert_response :success
-    assert_tag :tag => 'script',
-      :attributes => {:src => %r{^/themes/#{@theme.dir}/javascripts/theme.js}}
-
-  ensure
-    @theme.javascripts.delete 'theme'
-  end
-
-  def test_with_sub_uri
-    Redmine::Utils.relative_url_root = '/foo'
-    @theme.javascripts << 'theme'
-    get '/'
-
-    assert_response :success
-    assert_tag :tag => 'link',
-      :attributes => {:href => %r{^/foo/themes/#{@theme.dir}/stylesheets/application.css}}
-    assert_tag :tag => 'script',
-      :attributes => {:src => %r{^/foo/themes/#{@theme.dir}/javascripts/theme.js}}
-
-  ensure
-    Redmine::Utils.relative_url_root = ''
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/45daf4d07a686bd1866f0fdb820fe646d660b21c.svn-base
--- /dev/null
+++ b/.svn/pristine/45/45daf4d07a686bd1866f0fdb820fe646d660b21c.svn-base
@@ -0,0 +1,316 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::UnifiedDiffTest < ActiveSupport::TestCase
+  def test_subversion_diff
+    diff = Redmine::UnifiedDiff.new(read_diff_fixture('subversion.diff'))
+    # number of files
+    assert_equal 4, diff.size
+    assert diff.detect {|file| file.file_name =~ %r{^config/settings.yml}}
+  end
+
+  def test_truncate_diff
+    diff = Redmine::UnifiedDiff.new(read_diff_fixture('subversion.diff'), :max_lines => 20)
+    assert_equal 2, diff.size
+  end
+
+  def test_inline_partials
+    diff = Redmine::UnifiedDiff.new(read_diff_fixture('partials.diff'))
+    assert_equal 1, diff.size
+    diff = diff.first
+    assert_equal 43, diff.size
+
+    assert_equal [51, -1], diff[0].offsets
+    assert_equal [51, -1], diff[1].offsets
+    assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>elit</span>', diff[0].html_line
+    assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>xx</span>', diff[1].html_line
+
+    assert_nil diff[2].offsets
+    assert_equal 'Praesent et sagittis dui. Vivamus ac diam diam', diff[2].html_line
+
+    assert_equal [0, -14], diff[3].offsets
+    assert_equal [0, -14], diff[4].offsets
+    assert_equal '<span>Ut sed</span> auctor justo', diff[3].html_line
+    assert_equal '<span>xxx</span> auctor justo', diff[4].html_line
+
+    assert_equal [13, -19], diff[6].offsets
+    assert_equal [13, -19], diff[7].offsets
+
+    assert_equal [24, -8], diff[9].offsets
+    assert_equal [24, -8], diff[10].offsets
+
+    assert_equal [37, -1], diff[12].offsets
+    assert_equal [37, -1], diff[13].offsets
+
+    assert_equal [0, -38], diff[15].offsets
+    assert_equal [0, -38], diff[16].offsets
+  end
+
+  def test_side_by_side_partials
+    diff = Redmine::UnifiedDiff.new(read_diff_fixture('partials.diff'), :type => 'sbs')
+    assert_equal 1, diff.size
+    diff = diff.first
+    assert_equal 32, diff.size
+
+    assert_equal [51, -1], diff[0].offsets
+    assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>elit</span>', diff[0].html_line_left
+    assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>xx</span>', diff[0].html_line_right
+
+    assert_nil diff[1].offsets
+    assert_equal 'Praesent et sagittis dui. Vivamus ac diam diam', diff[1].html_line_left
+    assert_equal 'Praesent et sagittis dui. Vivamus ac diam diam', diff[1].html_line_right
+
+    assert_equal [0, -14], diff[2].offsets
+    assert_equal '<span>Ut sed</span> auctor justo', diff[2].html_line_left
+    assert_equal '<span>xxx</span> auctor justo', diff[2].html_line_right
+
+    assert_equal [13, -19], diff[4].offsets
+    assert_equal [24, -8], diff[6].offsets
+    assert_equal [37, -1], diff[8].offsets
+    assert_equal [0, -38], diff[10].offsets
+
+  end
+
+  def test_partials_with_html_entities
+    raw = <<-DIFF
+--- test.orig.txt Wed Feb 15 16:10:39 2012
++++ test.new.txt  Wed Feb 15 16:11:25 2012
+@@ -1,5 +1,5 @@
+ Semicolons were mysteriously appearing in code diffs in the repository
+ 
+-void DoSomething(std::auto_ptr<MyClass> myObj)
++void DoSomething(const MyClass& myObj)
+ 
+DIFF
+
+    diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs')
+    assert_equal 1, diff.size
+    assert_equal 'void DoSomething(<span>std::auto_ptr&lt;MyClass&gt;</span> myObj)', diff.first[2].html_line_left
+    assert_equal 'void DoSomething(<span>const MyClass&amp;</span> myObj)', diff.first[2].html_line_right
+
+    diff = Redmine::UnifiedDiff.new(raw, :type => 'inline')
+    assert_equal 1, diff.size
+    assert_equal 'void DoSomething(<span>std::auto_ptr&lt;MyClass&gt;</span> myObj)', diff.first[2].html_line
+    assert_equal 'void DoSomething(<span>const MyClass&amp;</span> myObj)', diff.first[3].html_line
+  end
+
+  def test_line_starting_with_dashes
+    diff = Redmine::UnifiedDiff.new(<<-DIFF
+--- old.txt Wed Nov 11 14:24:58 2009
++++ new.txt Wed Nov 11 14:25:02 2009
+@@ -1,8 +1,4 @@
+-Lines that starts with dashes:
+-
+-------------------------
+--- file.c
+-------------------------
++A line that starts with dashes:
+ 
+ and removed.
+ 
+@@ -23,4 +19,4 @@
+ 
+ 
+ 
+-Another chunk of change
++Another chunk of changes
+
+DIFF
+    )
+    assert_equal 1, diff.size
+  end
+
+  def test_one_line_new_files
+    diff = Redmine::UnifiedDiff.new(<<-DIFF
+diff -r 000000000000 -r ea98b14f75f0 README1
+--- /dev/null
++++ b/README1
+@@ -0,0 +1,1 @@
++test1
+diff -r 000000000000 -r ea98b14f75f0 README2
+--- /dev/null
++++ b/README2
+@@ -0,0 +1,1 @@
++test2
+diff -r 000000000000 -r ea98b14f75f0 README3
+--- /dev/null
++++ b/README3
+@@ -0,0 +1,3 @@
++test4
++test5
++test6
+diff -r 000000000000 -r ea98b14f75f0 README4
+--- /dev/null
++++ b/README4
+@@ -0,0 +1,3 @@
++test4
++test5
++test6
+DIFF
+    )
+    assert_equal 4, diff.size
+    assert_equal "README1", diff[0].file_name
+  end
+
+  def test_both_git_diff
+    diff = Redmine::UnifiedDiff.new(<<-DIFF
+# HG changeset patch
+# User test
+# Date 1348014182 -32400
+# Node ID d1c871b8ef113df7f1c56d41e6e3bfbaff976e1f
+# Parent  180b6605936cdc7909c5f08b59746ec1a7c99b3e
+modify test1.txt
+
+diff -r 180b6605936c -r d1c871b8ef11 test1.txt
+--- a/test1.txt
++++ b/test1.txt
+@@ -1,1 +1,1 @@
+-test1
++modify test1
+DIFF
+    )
+    assert_equal 1, diff.size
+    assert_equal "test1.txt", diff[0].file_name
+  end
+
+  def test_include_a_b_slash
+    diff = Redmine::UnifiedDiff.new(<<-DIFF
+--- test1.txt
++++ b/test02.txt
+@@ -1 +0,0 @@
+-modify test1
+DIFF
+    )
+    assert_equal 1, diff.size
+    assert_equal "b/test02.txt", diff[0].file_name
+
+    diff = Redmine::UnifiedDiff.new(<<-DIFF
+--- a/test1.txt
++++ a/test02.txt
+@@ -1 +0,0 @@
+-modify test1
+DIFF
+    )
+    assert_equal 1, diff.size
+    assert_equal "a/test02.txt", diff[0].file_name
+
+    diff = Redmine::UnifiedDiff.new(<<-DIFF
+--- a/test1.txt
++++ test02.txt
+@@ -1 +0,0 @@
+-modify test1
+DIFF
+    )
+    assert_equal 1, diff.size
+    assert_equal "test02.txt", diff[0].file_name
+  end
+
+  def test_utf8_ja
+    ja = "  text_tip_issue_end_day: "
+    ja += "\xe3\x81\x93\xe3\x81\xae\xe6\x97\xa5\xe3\x81\xab\xe7\xb5\x82\xe4\xba\x86\xe3\x81\x99\xe3\x82\x8b<span>\xe3\x82\xbf\xe3\x82\xb9\xe3\x82\xaf</span>"
+    ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
+    with_settings :repositories_encodings => '' do
+      diff = Redmine::UnifiedDiff.new(read_diff_fixture('issue-12641-ja.diff'), :type => 'inline')
+      assert_equal 1, diff.size
+      assert_equal 12, diff.first.size
+      assert_equal ja, diff.first[4].html_line_left
+    end
+  end
+
+  def test_utf8_ru
+    ru = "        other: &quot;\xd0\xbe\xd0\xba\xd0\xbe\xd0\xbb\xd0\xbe %{count} \xd1\x87\xd0\xb0\xd1\x81<span>\xd0\xb0</span>&quot;"
+    ru.force_encoding('UTF-8') if ru.respond_to?(:force_encoding)
+    with_settings :repositories_encodings => '' do
+      diff = Redmine::UnifiedDiff.new(read_diff_fixture('issue-12641-ru.diff'), :type => 'inline')
+      assert_equal 1, diff.size
+      assert_equal 8, diff.first.size
+      assert_equal ru, diff.first[3].html_line_left
+    end
+  end
+
+  def test_offset_range_ascii_1
+    raw = <<-DIFF
+--- a.txt	2013-04-05 14:19:39.000000000 +0900
++++ b.txt	2013-04-05 14:19:51.000000000 +0900
+@@ -1,3 +1,3 @@
+ aaaa
+-abc
++abcd
+ bbbb
+DIFF
+    diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs')
+    assert_equal 1, diff.size
+    assert_equal 3, diff.first.size
+    assert_equal "abc<span></span>", diff.first[1].html_line_left
+    assert_equal "abc<span>d</span>", diff.first[1].html_line_right
+  end
+
+  def test_offset_range_ascii_2
+    raw = <<-DIFF
+--- a.txt	2013-04-05 14:19:39.000000000 +0900
++++ b.txt	2013-04-05 14:19:51.000000000 +0900
+@@ -1,3 +1,3 @@
+ aaaa
+-abc
++zabc
+ bbbb
+DIFF
+    diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs')
+    assert_equal 1, diff.size
+    assert_equal 3, diff.first.size
+    assert_equal "<span></span>abc", diff.first[1].html_line_left
+    assert_equal "<span>z</span>abc", diff.first[1].html_line_right
+  end
+
+  def test_offset_range_japanese_1
+    ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span></span>"
+    ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding)
+    ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x9e</span>"
+    ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding)
+    with_settings :repositories_encodings => '' do
+      diff = Redmine::UnifiedDiff.new(
+               read_diff_fixture('issue-13644-1.diff'), :type => 'sbs')
+      assert_equal 1, diff.size
+      assert_equal 3, diff.first.size
+      assert_equal ja1, diff.first[1].html_line_left
+      assert_equal ja2, diff.first[1].html_line_right
+    end
+  end
+
+  def test_offset_range_japanese_2
+    ja1 = "<span></span>\xe6\x97\xa5\xe6\x9c\xac"
+    ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding)
+    ja2 = "<span>\xe3\x81\xab\xe3\x81\xa3\xe3\x81\xbd\xe3\x82\x93</span>\xe6\x97\xa5\xe6\x9c\xac"
+    ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding)
+    with_settings :repositories_encodings => '' do
+      diff = Redmine::UnifiedDiff.new(
+               read_diff_fixture('issue-13644-2.diff'), :type => 'sbs')
+      assert_equal 1, diff.size
+      assert_equal 3, diff.first.size
+      assert_equal ja1, diff.first[1].html_line_left
+      assert_equal ja2, diff.first[1].html_line_right
+    end
+  end
+
+  private
+
+  def read_diff_fixture(filename)
+    File.new(File.join(File.dirname(__FILE__), '/../../../fixtures/diffs', filename)).read
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/45/45fedacb83fa4bf0b530842cc4c9e44d1242cd73.svn-base
--- /dev/null
+++ b/.svn/pristine/45/45fedacb83fa4bf0b530842cc4c9e44d1242cd73.svn-base
@@ -0,0 +1,47 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module AttachmentsHelper
+  # Displays view/delete links to the attachments of the given object
+  # Options:
+  #   :author -- author names are not displayed if set to false
+  #   :thumbails -- display thumbnails if enabled in settings
+  def link_to_attachments(container, options = {})
+    options.assert_valid_keys(:author, :thumbnails)
+
+    if container.attachments.any?
+      options = {:deletable => container.attachments_deletable?, :author => true}.merge(options)
+      render :partial => 'attachments/links',
+        :locals => {:attachments => container.attachments, :options => options, :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)}
+    end
+  end
+
+  def render_api_attachment(attachment, api)
+    api.attachment do
+      api.id attachment.id
+      api.filename attachment.filename
+      api.filesize attachment.filesize
+      api.content_type attachment.content_type
+      api.description attachment.description
+      api.content_url url_for(:controller => 'attachments', :action => 'download', :id => attachment, :filename => attachment.filename, :only_path => false)
+      api.author(:id => attachment.author.id, :name => attachment.author.name) if attachment.author
+      api.created_on attachment.created_on
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/46/460154f7f38123fe1c4a30970945d9f47767461e.svn-base
--- a/.svn/pristine/46/460154f7f38123fe1c4a30970945d9f47767461e.svn-base
+++ /dev/null
@@ -1,50 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module WikiFormatting
-    module Textile
-      module Helper
-        def wikitoolbar_for(field_id)
-          heads_for_wiki_formatter
-          # Is there a simple way to link to a public resource?
-          url = "#{Redmine::Utils.relative_url_root}/help/wiki_syntax.html"
-          help_link = link_to(l(:setting_text_formatting), url,
-            :onclick => "window.open(\"#{ url }\", \"\", \"resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\"); return false;")
-
-          javascript_tag("var wikiToolbar = new jsToolBar($('#{field_id}')); wikiToolbar.setHelpLink('#{escape_javascript help_link}'); wikiToolbar.draw();")
-        end
-
-        def initial_page_content(page)
-          "h1. #{@page.pretty_title}"
-        end
-
-        def heads_for_wiki_formatter
-          unless @heads_for_wiki_formatter_included
-            content_for :header_tags do
-              javascript_include_tag('jstoolbar/jstoolbar') +
-              javascript_include_tag('jstoolbar/textile') +
-              javascript_include_tag("jstoolbar/lang/jstoolbar-#{current_language.to_s.downcase}") +
-              stylesheet_link_tag('jstoolbar')
-            end
-            @heads_for_wiki_formatter_included = true
-          end
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/46/4604849a86c8bbf40b2a1eb833e2c3ff6fe87f8f.svn-base
--- a/.svn/pristine/46/4604849a86c8bbf40b2a1eb833e2c3ff6fe87f8f.svn-base
+++ /dev/null
@@ -1,33 +0,0 @@
-<div class="contextual">
-<%= watcher_tag(@wiki, User.current) %>
-</div>
-
-<h2><%= l(:label_index_by_date) %></h2>
-
-<% if @pages.empty? %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
-
-<% @pages_by_date.keys.sort.reverse.each do |date| %>
-<h3><%= format_date(date) %></h3>
-<ul>
-<% @pages_by_date[date].each do |page| %>
-    <li><%= link_to h(page.pretty_title), :action => 'show', :id => page.title, :project_id => page.project %></li>
-<% end %>
-</ul>
-<% end %>
-
-<% content_for :sidebar do %>
-  <%= render :partial => 'sidebar' %>
-<% end %>
-
-<% unless @pages.empty? %>
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :key => User.current.rss_key} %>
-  <%= f.link_to('HTML', :url => {:action => 'export'}) if User.current.allowed_to?(:export_wiki_pages, @project) %>
-<% end %>
-<% end %>
-
-<% content_for :header_tags do %>
-<%= auto_discovery_link_tag(:atom, :controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :format => 'atom', :key => User.current.rss_key) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/46/460823ad942a6dbaf3986f763002fe9ab659fb36.svn-base
--- /dev/null
+++ b/.svn/pristine/46/460823ad942a6dbaf3986f763002fe9ab659fb36.svn-base
@@ -0,0 +1,45 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class WorkflowPermission < WorkflowRule
+  validates_inclusion_of :rule, :in => %w(readonly required)
+  validate :validate_field_name
+
+  # Replaces the workflow permissions for the given tracker and role
+  #
+  # Example:
+  #   WorkflowPermission.replace_permissions role, tracker, {'due_date' => {'1' => 'readonly', '2' => 'required'}}
+  def self.replace_permissions(tracker, role, permissions)
+    destroy_all(:tracker_id => tracker.id, :role_id => role.id)
+
+    permissions.each { |field, rule_by_status_id|
+      rule_by_status_id.each { |status_id, rule|
+        if rule.present?
+          WorkflowPermission.create(:role_id => role.id, :tracker_id => tracker.id, :old_status_id => status_id, :field_name => field, :rule => rule)
+        end
+      }
+    }
+  end
+
+  protected
+
+  def validate_field_name
+    unless Tracker::CORE_FIELDS_ALL.include?(field_name) || field_name.to_s.match(/^\d+$/)
+      errors.add :field_name, :invalid
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/46/46d08e5d685f85ea6b371254e247586c06beb87e.svn-base
--- a/.svn/pristine/46/46d08e5d685f85ea6b371254e247586c06beb87e.svn-base
+++ /dev/null
@@ -1,107 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'sys_controller'
-require 'mocha'
-
-# Re-raise errors caught by the controller.
-class SysController; def rescue_action(e) raise e end; end
-
-class SysControllerTest < ActionController::TestCase
-  fixtures :projects, :repositories, :enabled_modules
-
-  def setup
-    @controller = SysController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    Setting.sys_api_enabled = '1'
-    Setting.enabled_scm = %w(Subversion Git)
-  end
-
-  def test_projects_with_repository_enabled
-    get :projects
-    assert_response :success
-    assert_equal 'application/xml', @response.content_type
-    with_options :tag => 'projects' do |test|
-      test.assert_tag :children => { :count  => Project.active.has_module(:repository).count }
-      test.assert_tag 'project', :child => {:tag => 'identifier', :sibling => {:tag => 'is-public'}}
-    end
-    assert_no_tag 'extra-info'
-    assert_no_tag 'extra_info'
-  end
-
-  def test_create_project_repository
-    assert_nil Project.find(4).repository
-
-    post :create_project_repository, :id => 4,
-                                     :vendor => 'Subversion',
-                                     :repository => { :url => 'file:///create/project/repository/subproject2'}
-    assert_response :created
-    assert_equal 'application/xml', @response.content_type
-
-    r = Project.find(4).repository
-    assert r.is_a?(Repository::Subversion)
-    assert_equal 'file:///create/project/repository/subproject2', r.url
-    
-    assert_tag 'repository-subversion',
-      :child => {
-        :tag => 'id', :content => r.id.to_s,
-        :sibling => {:tag => 'url', :content => r.url}
-      }
-    assert_no_tag 'extra-info'
-    assert_no_tag 'extra_info'
-  end
-
-  def test_fetch_changesets
-    Repository::Subversion.any_instance.expects(:fetch_changesets).returns(true)
-    get :fetch_changesets
-    assert_response :success
-  end
-
-  def test_fetch_changesets_one_project
-    Repository::Subversion.any_instance.expects(:fetch_changesets).returns(true)
-    get :fetch_changesets, :id => 'ecookbook'
-    assert_response :success
-  end
-
-  def test_fetch_changesets_unknown_project
-    get :fetch_changesets, :id => 'unknown'
-    assert_response 404
-  end
-
-  def test_disabled_ws_should_respond_with_403_error
-    with_settings :sys_api_enabled => '0' do
-      get :projects
-      assert_response 403
-    end
-  end
-
-  def test_api_key
-    with_settings :sys_api_key => 'my_secret_key' do
-      get :projects, :key => 'my_secret_key'
-      assert_response :success
-    end
-  end
-
-  def test_wrong_key_should_respond_with_403_error
-    with_settings :sys_api_enabled => 'my_secret_key' do
-      get :projects, :key => 'wrong_key'
-      assert_response 403
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/47/4715b8761d3d616a6e3ff8f7139429ffdd309875.svn-base
--- a/.svn/pristine/47/4715b8761d3d616a6e3ff8f7139429ffdd309875.svn-base
+++ /dev/null
@@ -1,1008 +0,0 @@
-sl:
-  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y-%m-%d"
-      short: "%b %d"
-      long: "%B %d, %Y"
-
-    day_names: [Nedelja, Ponedeljek, Torek, Sreda, ÄŒetrtek, Petek, Sobota]
-    abbr_day_names: [Ned, Pon, To, Sr, ÄŒet, Pet, Sob]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Januar, Februar, Marec, April, Maj, Junij, Julij, Avgust, September, Oktober, November, December]
-    abbr_month_names: [~, Jan, Feb, Mar, Apr, Maj, Jun, Jul, Aug, Sep, Okt, Nov, Dec]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%a, %d %b %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "am"
-    pm: "pm"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "pol minute"
-      less_than_x_seconds:
-        one:   "manj kot 1. sekundo"
-        other: "manj kot %{count} sekund"
-      x_seconds:
-        one:   "1. sekunda"
-        other: "%{count} sekund"
-      less_than_x_minutes:
-        one:   "manj kot minuto"
-        other: "manj kot %{count} minut"
-      x_minutes:
-        one:   "1 minuta"
-        other: "%{count} minut"
-      about_x_hours:
-        one:   "okrog 1. ure"
-        other: "okrog %{count} ur"
-      x_days:
-        one:   "1 dan"
-        other: "%{count} dni"
-      about_x_months:
-        one:   "okrog 1. mesec"
-        other: "okrog %{count} mesecev"
-      x_months:
-        one:   "1 mesec"
-        other: "%{count} mesecev"
-      about_x_years:
-        one:   "okrog 1. leto"
-        other: "okrog %{count} let"
-      over_x_years:
-        one:   "veÄ kot 1. leto"
-        other: "veÄ kot %{count} let"
-      almost_x_years:
-        one:   "skoraj 1. leto"
-        other: "skoraj %{count} let"
-
-  number:
-    format:
-      separator: ","
-      delimiter: "."
-      precision: 3
-    human:
-      format:
-        precision: 1
-        delimiter: ""
-      storage_units:
-        format: "%n %u"
-        units:
-          kb: KB
-          tb: TB
-          gb: GB
-          byte:
-            one: Byte
-            other: Bytes
-          mb: MB
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "in"
-      skip_last_comma: false
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1. napaka je prepreÄila temu %{model} da bi se shranil"
-          other:  "%{count} napak je prepreÄilo temu %{model} da bi se shranil"
-      messages:
-        inclusion: "ni vkljuÄen na seznamu"
-        exclusion: "je rezerviran"
-        invalid: "je napaÄen"
-        confirmation: "ne ustreza potrdilu"
-        accepted: "mora biti sprejet"
-        empty: "ne sme biti prazen"
-        blank: "ne sme biti neizpolnjen"
-        too_long: "je predolg"
-        too_short: "je prekratek"
-        wrong_length: "je napaÄne dolÅ¾ine"
-        taken: "je Å¾e zaseden"
-        not_a_number: "ni Å¡tevilo"
-        not_a_date: "ni veljaven datum"
-        greater_than: "mora biti veÄji kot %{count}"
-        greater_than_or_equal_to: "mora biti veÄji ali enak kot %{count}"
-        equal_to: "mora biti enak kot %{count}"
-        less_than: "mora biti manjÅ¡i kot %{count}"
-        less_than_or_equal_to: "mora biti manjÅ¡i ali enak kot %{count}"
-        odd: "mora biti sodo"
-        even: "mora biti liho"
-        greater_than_start_date: "mora biti kasnejÅ¡i kot zaÄetni datum"
-        not_same_project: "ne pripada istemu projektu"
-        circular_dependency: "Ta odnos bi povzroÄil kroÅ¾no odvisnost"
-        cant_link_an_issue_with_a_descendant: "Zahtevek ne more biti povezan s svojo podnalogo"
-
-  actionview_instancetag_blank_option: Prosimo izberite
-
-  general_text_No: 'Ne'
-  general_text_Yes: 'Da'
-  general_text_no: 'ne'
-  general_text_yes: 'da'
-  general_lang_name: 'SlovenÅ¡Äina'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: RaÄun je bil uspeÅ¡no posodobljen.
-  notice_account_invalid_creditentials: NapaÄno uporabniÅ¡ko ime ali geslo
-  notice_account_password_updated: Geslo je bilo uspeÅ¡no posodobljeno.
-  notice_account_wrong_password: NapaÄno geslo
-  notice_account_register_done: RaÄun je bil uspeÅ¡no ustvarjen. Za aktivacijo potrdite povezavo, ki vam je bila poslana v e-nabiralnik.
-  notice_account_unknown_email: Neznan uporabnik.
-  notice_can_t_change_password: Ta raÄun za overovljanje uporablja zunanji. Gesla ni mogoÄe spremeniti.
-  notice_account_lost_email_sent: Poslano vam je bilo e-pismo z navodili za izbiro novega gesla.
-  notice_account_activated: VaÅ¡ raÄun je bil aktiviran. Sedaj se lahko prijavite.
-  notice_successful_create: Ustvarjanje uspelo.
-  notice_successful_update: Posodobitev uspela.
-  notice_successful_delete: Izbris uspel.
-  notice_successful_connection: Povezava uspela.
-  notice_file_not_found: Stran na katero se Å¾elite povezati ne obstaja ali pa je bila umaknjena.
-  notice_locking_conflict: Drug uporabnik je posodobil podatke.
-  notice_not_authorized: Nimate privilegijev za dostop do te strani.
-  notice_email_sent: "E-poÅ¡tno sporoÄilo je bilo poslano %{value}"
-  notice_email_error: "Ob poÅ¡iljanju e-sporoÄila je priÅ¡lo do napake (%{value})"
-  notice_feeds_access_key_reseted: VaÅ¡ RSS dostopni kljuÄ je bil ponastavljen.
-  notice_failed_to_save_issues: "Neuspelo shranjevanje %{count} zahtevka na %{total} izbranem: %{ids}."
-  notice_no_issue_selected: "Izbran ni noben zahtevek! Prosimo preverite zahtevke, ki jih Å¾elite urediti."
-  notice_account_pending: "VaÅ¡ raÄun je bil ustvarjen in Äaka na potrditev s strani administratorja."
-  notice_default_data_loaded: Privzete nastavitve so bile uspeÅ¡no naloÅ¾ene.
-  notice_unable_delete_version: Verzije ni bilo mogoÄe izbrisati.
-
-  error_can_t_load_default_data: "Privzetih nastavitev ni bilo mogoÄe naloÅ¾iti: %{value}"
-  error_scm_not_found: "Vnos ali revizija v shrambi ni bila najdena ."
-  error_scm_command_failed: "Med vzpostavljem povezave s shrambo je priÅ¡lo do napake: %{value}"
-  error_scm_annotate: "Vnos ne obstaja ali pa ga ni mogoÄe komentirati."
-  error_issue_not_found_in_project: 'Zahtevek ni bil najden ali pa ne pripada temu projektu'
-
-  mail_subject_lost_password: "VaÅ¡e %{value} geslo"
-  mail_body_lost_password: 'Za spremembo glesla kliknite na naslednjo povezavo:'
-  mail_subject_register: "Aktivacija %{value} vaÅ¡ega raÄuna"
-  mail_body_register: 'Za aktivacijo vaÅ¡ega raÄuna kliknite na naslednjo povezavo:'
-  mail_body_account_information_external: "Za prijavo lahko uporabite vaÅ¡ %{value} raÄun."
-  mail_body_account_information: Informacije o vaÅ¡em raÄunu
-  mail_subject_account_activation_request: "%{value} zahtevek za aktivacijo raÄuna"
-  mail_body_account_activation_request: "Registriral se je nov uporabnik (%{value}). RaÄun Äaka na vaÅ¡o odobritev:"
-  mail_subject_reminder: "%{count} zahtevek(zahtevki) zapadejo v naslednjih %{days} dneh"
-  mail_body_reminder: "%{count} zahtevek(zahtevki), ki so vam dodeljeni bodo zapadli v naslednjih %{days} dneh:"
-
-  gui_validation_error: 1 napaka
-  gui_validation_error_plural: "%{count} napak"
-
-  field_name: Ime
-  field_description: Opis
-  field_summary: Povzetek
-  field_is_required: Zahtevano
-  field_firstname: Ime
-  field_lastname: Priimek
-  field_mail: E-naslov
-  field_filename: Datoteka
-  field_filesize: Velikost
-  field_downloads: Prenosi
-  field_author: Avtor
-  field_created_on: Ustvarjen
-  field_updated_on: Posodobljeno
-  field_field_format: Format
-  field_is_for_all: Za vse projekte
-  field_possible_values: MoÅ¾ne vrednosti
-  field_regexp: Regularni izraz
-  field_min_length: Minimalna dolÅ¾ina
-  field_max_length: Maksimalna dolÅ¾ina
-  field_value: Vrednost
-  field_category: Kategorija
-  field_title: Naslov
-  field_project: Projekt
-  field_issue: Zahtevek
-  field_status: Status
-  field_notes: ZabeleÅ¾ka
-  field_is_closed: Zahtevek zaprt
-  field_is_default: Privzeta vrednost
-  field_tracker: Vrsta zahtevka
-  field_subject: Tema
-  field_due_date: Do datuma
-  field_assigned_to: Dodeljen
-  field_priority: Prioriteta
-  field_fixed_version: Ciljna verzija
-  field_user: Uporabnik
-  field_role: Vloga
-  field_homepage: DomaÄa stran
-  field_is_public: Javno
-  field_parent: Podprojekt projekta
-  field_is_in_roadmap: Zahtevki prikazani na zemljevidu
-  field_login: Prijava
-  field_mail_notification: E-poÅ¡tna oznanila
-  field_admin: Administrator
-  field_last_login_on: ZadnjiÄ povezan(a)
-  field_language: Jezik
-  field_effective_date: Datum
-  field_password: Geslo
-  field_new_password: Novo geslo
-  field_password_confirmation: Potrditev
-  field_version: Verzija
-  field_type: Tip
-  field_host: Gostitelj
-  field_port: Vrata
-  field_account: RaÄun
-  field_base_dn: Bazni DN
-  field_attr_login: Oznaka za prijavo
-  field_attr_firstname: Oznaka za ime
-  field_attr_lastname: Oznaka za priimek
-  field_attr_mail: Oznaka za e-naslov
-  field_onthefly: Sprotna izdelava uporabnikov
-  field_start_date: ZaÄetek
-  field_done_ratio: "% Narejeno"
-  field_auth_source: NaÄin overovljanja
-  field_hide_mail: Skrij moj e-naslov
-  field_comments: Komentar
-  field_url: URL
-  field_start_page: ZaÄetna stran
-  field_subproject: Podprojekt
-  field_hours: Ur
-  field_activity: Aktivnost
-  field_spent_on: Datum
-  field_identifier: Identifikator
-  field_is_filter: Uporabljen kot filter
-  field_issue_to: Povezan zahtevek
-  field_delay: Zamik
-  field_assignable: Zahtevki so lahko dodeljeni tej vlogi
-  field_redirect_existing_links: Preusmeri obstojeÄe povezave
-  field_estimated_hours: Ocenjen Äas
-  field_column_names: Stolpci
-  field_time_zone: ÄŒasovni pas
-  field_searchable: ZmoÅ¾en iskanja
-  field_default_value: Privzeta vrednost
-  field_comments_sorting: PrikaÅ¾i komentarje
-  field_parent_title: MatiÄna stran
-
-  setting_app_title: Naslov aplikacije
-  setting_app_subtitle: Podnaslov aplikacije
-  setting_welcome_text: Pozdravno besedilo
-  setting_default_language: Privzeti jezik
-  setting_login_required: Zahtevano overovljanje
-  setting_self_registration: Samostojna registracija
-  setting_attachment_max_size: Maksimalna velikost priponk
-  setting_issues_export_limit: Skrajna meja za izvoz zahtevkov
-  setting_mail_from: E-naslov za emisijo
-  setting_bcc_recipients: Prejemniki slepih kopij (bcc)
-  setting_plain_text_mail: navadno e-sporoÄilo (ne HTML)
-  setting_host_name: Ime gostitelja in pot
-  setting_text_formatting: Oblikovanje besedila
-  setting_wiki_compression: Stiskanje Wiki zgodovine
-  setting_feeds_limit: Meja obsega RSS virov
-  setting_default_projects_public: Novi projekti so privzeto javni
-  setting_autofetch_changesets: Samodejni izvleÄek zapisa sprememb
-  setting_sys_api_enabled: OmogoÄi WS za upravljanje shrambe
-  setting_commit_ref_keywords: Sklicne kljuÄne besede
-  setting_commit_fix_keywords: Urejanje kljuÄne besede
-  setting_autologin: Avtomatska prijava
-  setting_date_format: Oblika datuma
-  setting_time_format: Oblika Äasa
-  setting_cross_project_issue_relations: Dovoli povezave zahtevkov med razliÄnimi projekti
-  setting_issue_list_default_columns: Privzeti stolpci prikazani na seznamu zahtevkov
-  setting_emails_footer: Noga e-sporoÄil
-  setting_protocol: Protokol
-  setting_per_page_options: Å tevilo elementov na stran
-  setting_user_format: Oblika prikaza uporabnikov
-  setting_activity_days_default: Prikaz dni na aktivnost projekta
-  setting_display_subprojects_issues: Privzeti prikaz zahtevkov podprojektov v glavnem projektu
-  setting_enabled_scm: OmogoÄen SCM
-  setting_mail_handler_api_enabled: OmogoÄi WS za prihajajoÄo e-poÅ¡to
-  setting_mail_handler_api_key: API kljuÄ
-  setting_sequential_project_identifiers: Generiraj projektne identifikatorje sekvenÄno
-  setting_gravatar_enabled: Uporabljaj Gravatar ikone
-  setting_diff_max_lines_displayed: Maksimalno Å¡tevilo prikazanih vrstic razliÄnosti
-
-  permission_edit_project: Uredi projekt
-  permission_select_project_modules: Izberi module projekta
-  permission_manage_members: Uredi Älane
-  permission_manage_versions: Uredi verzije
-  permission_manage_categories: Urejanje kategorij zahtevkov
-  permission_add_issues: Dodaj zahtevke
-  permission_edit_issues: Uredi zahtevke
-  permission_manage_issue_relations: Uredi odnose med zahtevki
-  permission_add_issue_notes: Dodaj zabeleÅ¾ke
-  permission_edit_issue_notes: Uredi zabeleÅ¾ke
-  permission_edit_own_issue_notes: Uredi lastne zabeleÅ¾ke
-  permission_move_issues: Premakni zahtevke
-  permission_delete_issues: IzbriÅ¡i zahtevke
-  permission_manage_public_queries: Uredi javna povpraÅ¡evanja
-  permission_save_queries: Shrani povpraÅ¡evanje
-  permission_view_gantt: Poglej gantogram
-  permission_view_calendar: Poglej koledar
-  permission_view_issue_watchers: Oglej si listo spremeljevalcev
-  permission_add_issue_watchers: Dodaj spremljevalce
-  permission_log_time: BeleÅ¾i porabljen Äas
-  permission_view_time_entries: Poglej porabljen Äas
-  permission_edit_time_entries: Uredi beleÅ¾ko Äasa
-  permission_edit_own_time_entries: Uredi beleÅ¾ko lastnega Äasa
-  permission_manage_news: Uredi novice
-  permission_comment_news: Komentiraj novice
-  permission_manage_documents: Uredi dokumente
-  permission_view_documents: Poglej dokumente
-  permission_manage_files: Uredi datoteke
-  permission_view_files: Poglej datoteke
-  permission_manage_wiki: Uredi wiki
-  permission_rename_wiki_pages: Preimenuj wiki strani
-  permission_delete_wiki_pages: IzbriÅ¡i wiki strani
-  permission_view_wiki_pages: Poglej wiki
-  permission_view_wiki_edits: Poglej wiki zgodovino
-  permission_edit_wiki_pages: Uredi wiki strani
-  permission_delete_wiki_pages_attachments: IzbriÅ¡i priponke
-  permission_protect_wiki_pages: ZaÅ¡Äiti wiki strani
-  permission_manage_repository: Uredi shrambo
-  permission_browse_repository: Prebrskaj shrambo
-  permission_view_changesets: Poglej zapis sprememb
-  permission_commit_access: Dostop za predajo
-  permission_manage_boards: Uredi table
-  permission_view_messages: Poglej sporoÄila
-  permission_add_messages: Objavi sporoÄila
-  permission_edit_messages: Uredi sporoÄila
-  permission_edit_own_messages: Uredi lastna sporoÄila
-  permission_delete_messages: IzbriÅ¡i sporoÄila
-  permission_delete_own_messages: IzbriÅ¡i lastna sporoÄila
-
-  project_module_issue_tracking: Sledenje zahtevkom
-  project_module_time_tracking: Sledenje Äasa
-  project_module_news: Novice
-  project_module_documents: Dokumenti
-  project_module_files: Datoteke
-  project_module_wiki: Wiki
-  project_module_repository: Shramba
-  project_module_boards: Table
-
-  label_user: Uporabnik
-  label_user_plural: Uporabniki
-  label_user_new: Nov uporabnik
-  label_project: Projekt
-  label_project_new: Nov projekt
-  label_project_plural: Projekti
-  label_x_projects:
-    zero:  ni projektov
-    one:   1 projekt
-    other: "%{count} projektov"
-  label_project_all: Vsi projekti
-  label_project_latest: Zadnji projekti
-  label_issue: Zahtevek
-  label_issue_new: Nov zahtevek
-  label_issue_plural: Zahtevki
-  label_issue_view_all: Poglej vse zahtevke
-  label_issues_by: "Zahtevki od %{value}"
-  label_issue_added: Zahtevek dodan
-  label_issue_updated: Zahtevek posodobljen
-  label_document: Dokument
-  label_document_new: Nov dokument
-  label_document_plural: Dokumenti
-  label_document_added: Dokument dodan
-  label_role: Vloga
-  label_role_plural: Vloge
-  label_role_new: Nova vloga
-  label_role_and_permissions: Vloge in dovoljenja
-  label_member: ÄŒlan
-  label_member_new: Nov Älan
-  label_member_plural: ÄŒlani
-  label_tracker: Vrsta zahtevka
-  label_tracker_plural: Vrste zahtevkov
-  label_tracker_new: Nova vrsta zahtevka
-  label_workflow: Potek dela
-  label_issue_status: Stanje zahtevka
-  label_issue_status_plural: Stanje zahtevkov
-  label_issue_status_new: Novo stanje
-  label_issue_category: Kategorija zahtevka
-  label_issue_category_plural: Kategorije zahtevkov
-  label_issue_category_new: Nova kategorija
-  label_custom_field: Polje po meri
-  label_custom_field_plural: Polja po meri
-  label_custom_field_new: Novo polje po meri
-  label_enumerations: Seznami
-  label_enumeration_new: Nova vrednost
-  label_information: Informacija
-  label_information_plural: Informacije
-  label_please_login: Prosimo prijavite se
-  label_register: Registracija
-  label_password_lost: Izgubljeno geslo
-  label_home: Domov
-  label_my_page: Moja stran
-  label_my_account: Moj raÄun
-  label_my_projects: Moji projekti
-  label_administration: Upravljanje
-  label_login: Prijavi se
-  label_logout: Odjavi se
-  label_help: PomoÄ
-  label_reported_issues: Prijavljeni zahtevki
-  label_assigned_to_me_issues: Zahtevki dodeljeni meni
-  label_last_login: Zadnja povezava
-  label_registered_on: Registriran
-  label_activity: Aktivnost
-  label_overall_activity: Celotna aktivnost
-  label_user_activity: "Aktivnost %{value}"
-  label_new: Nov
-  label_logged_as: Prijavljen(a) kot
-  label_environment: Okolje
-  label_authentication: Overovitev
-  label_auth_source: NaÄin overovitve
-  label_auth_source_new: Nov naÄin overovitve
-  label_auth_source_plural: NaÄini overovitve
-  label_subproject_plural: Podprojekti
-  label_and_its_subprojects: "%{value} in njegovi podprojekti"
-  label_min_max_length: Min - Max dolÅ¾ina
-  label_list: Seznam
-  label_date: Datum
-  label_integer: Celo Å¡tevilo
-  label_float: Decimalno Å¡tevilo
-  label_boolean: Boolean
-  label_string: Besedilo
-  label_text: Dolgo besedilo
-  label_attribute: Lastnost
-  label_attribute_plural: Lastnosti
-  label_download: "%{count} Prenos"
-  label_download_plural: "%{count} Prenosi"
-  label_no_data: Ni podatkov za prikaz
-  label_change_status: Spremeni stanje
-  label_history: Zgodovina
-  label_attachment: Datoteka
-  label_attachment_new: Nova datoteka
-  label_attachment_delete: IzbriÅ¡i datoteko
-  label_attachment_plural: Datoteke
-  label_file_added: Datoteka dodana
-  label_report: PoroÄilo
-  label_report_plural: PoroÄila
-  label_news: Novica
-  label_news_new: Dodaj novico
-  label_news_plural: Novice
-  label_news_latest: Zadnje novice
-  label_news_view_all: Poglej vse novice
-  label_news_added: Dodane novice
-  label_settings: Nastavitve
-  label_overview: Pregled
-  label_version: Verzija
-  label_version_new: Nova verzija
-  label_version_plural: Verzije
-  label_confirmation: Potrditev
-  label_export_to: 'Na razpolago tudi v:'
-  label_read: Preberi...
-  label_public_projects: Javni projekti
-  label_open_issues: odprt zahtevek
-  label_open_issues_plural: odprti zahtevki
-  label_closed_issues: zaprt zahtevek
-  label_closed_issues_plural: zaprti zahtevki
-  label_x_open_issues_abbr_on_total:
-    zero:  0 odprtih / %{total}
-    one:   1 odprt / %{total}
-    other: "%{count} odprtih / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 odprtih
-    one:   1 odprt
-    other: "%{count} odprtih"
-  label_x_closed_issues_abbr:
-    zero:  0 zaprtih
-    one:   1 zaprt
-    other: "%{count} zaprtih"
-  label_total: Skupaj
-  label_permissions: Dovoljenja
-  label_current_status: Trenutno stanje
-  label_new_statuses_allowed: Novi zahtevki dovoljeni
-  label_all: vsi
-  label_none: noben
-  label_nobody: nihÄe
-  label_next: Naslednji
-  label_previous: PrejÅ¡nji
-  label_used_by: V uporabi od
-  label_details: Podrobnosti
-  label_add_note: Dodaj zabeleÅ¾ko
-  label_per_page: Na stran
-  label_calendar: Koledar
-  label_months_from: mesecev od
-  label_gantt: Gantogram
-  label_internal: Notranji
-  label_last_changes: "zadnjih %{count} sprememb"
-  label_change_view_all: Poglej vse spremembe
-  label_personalize_page: Individualiziraj to stran
-  label_comment: Komentar
-  label_comment_plural: Komentarji
-  label_x_comments:
-    zero: ni komentarjev
-    one: 1 komentar
-    other: "%{count} komentarjev"
-  label_comment_add: Dodaj komentar
-  label_comment_added: Komentar dodan
-  label_comment_delete: IzbriÅ¡i komentarje
-  label_query: Iskanje po meri
-  label_query_plural: Iskanja po meri
-  label_query_new: Novo iskanje
-  label_filter_add: Dodaj filter
-  label_filter_plural: Filtri
-  label_equals: je enako
-  label_not_equals: ni enako
-  label_in_less_than: v manj kot
-  label_in_more_than: v veÄ kot
-  label_in: v
-  label_today: danes
-  label_all_time: v vsem Äasu
-  label_yesterday: vÄeraj
-  label_this_week: ta teden
-  label_last_week: pretekli teden
-  label_last_n_days: "zadnjih %{count} dni"
-  label_this_month: ta mesec
-  label_last_month: zadnji mesec
-  label_this_year: to leto
-  label_date_range: Razpon datumov
-  label_less_than_ago: manj kot dni nazaj
-  label_more_than_ago: veÄ kot dni nazaj
-  label_ago: dni nazaj
-  label_contains: vsebuje
-  label_not_contains: ne vsebuje
-  label_day_plural: dni
-  label_repository: Shramba
-  label_repository_plural: Shrambe
-  label_browse: Prebrskaj
-  label_modification: "%{count} sprememba"
-  label_modification_plural: "%{count} spremembe"
-  label_revision: Revizija
-  label_revision_plural: Revizije
-  label_associated_revisions: Povezane revizije
-  label_added: dodano
-  label_modified: spremenjeno
-  label_copied: kopirano
-  label_renamed: preimenovano
-  label_deleted: izbrisano
-  label_latest_revision: Zadnja revizija
-  label_latest_revision_plural: Zadnje revizije
-  label_view_revisions: Poglej revizije
-  label_max_size: NajveÄja velikost
-  label_sort_highest: Premakni na vrh
-  label_sort_higher: Premakni gor
-  label_sort_lower: Premakni dol
-  label_sort_lowest: Premakni na dno
-  label_roadmap: NaÄrt
-  label_roadmap_due_in: "Do %{value}"
-  label_roadmap_overdue: "%{value} zakasnel"
-  label_roadmap_no_issues: Ni zahtevkov za to verzijo
-  label_search: IÅ¡Äi
-  label_result_plural: Rezultati
-  label_all_words: Vse besede
-  label_wiki: Wiki
-  label_wiki_edit: Wiki urejanje
-  label_wiki_edit_plural: Wiki urejanja
-  label_wiki_page: Wiki stran
-  label_wiki_page_plural: Wiki strani
-  label_index_by_title: Razvrsti po naslovu
-  label_index_by_date: Razvrsti po datumu
-  label_current_version: Trenutna verzija
-  label_preview: Predogled
-  label_feed_plural: RSS viri
-  label_changes_details: Podrobnosti o vseh spremembah
-  label_issue_tracking: Sledenje zahtevkom
-  label_spent_time: Porabljen Äas
-  label_f_hour: "%{value} ura"
-  label_f_hour_plural: "%{value} ur"
-  label_time_tracking: Sledenje Äasu
-  label_change_plural: Spremembe
-  label_statistics: Statistika
-  label_commits_per_month: Predaj na mesec
-  label_commits_per_author: Predaj na avtorja
-  label_view_diff: Preglej razlike
-  label_diff_inline: znotraj
-  label_diff_side_by_side: vzporedno
-  label_options: MoÅ¾nosti
-  label_copy_workflow_from: Kopiraj potek dela od
-  label_permissions_report: PoroÄilo o dovoljenjih
-  label_watched_issues: Spremljani zahtevki
-  label_related_issues: Povezani zahtevki
-  label_applied_status: Uveljavljeno stanje
-  label_loading: Nalaganje...
-  label_relation_new: Nova povezava
-  label_relation_delete: IzbriÅ¡i povezavo
-  label_relates_to: povezan z
-  label_duplicates: duplikati
-  label_duplicated_by: dupliciral
-  label_blocks: blok
-  label_blocked_by: blokiral
-  label_precedes: ima prednost pred
-  label_follows: sledi
-  label_end_to_start: konec na zaÄetek
-  label_end_to_end: konec na konec
-  label_start_to_start: zaÄetek na zaÄetek
-  label_start_to_end: zaÄetek na konec
-  label_stay_logged_in: Ostani prijavljen(a)
-  label_disabled: onemogoÄi
-  label_show_completed_versions: PrikaÅ¾i zakljuÄene verzije
-  label_me: jaz
-  label_board: Forum
-  label_board_new: Nov forum
-  label_board_plural: Forumi
-  label_topic_plural: Teme
-  label_message_plural: SporoÄila
-  label_message_last: Zadnje sporoÄilo
-  label_message_new: Novo sporoÄilo
-  label_message_posted: SporoÄilo dodano
-  label_reply_plural: Odgovori
-  label_send_information: PoÅ¡lji informacijo o raÄunu uporabniku
-  label_year: Leto
-  label_month: Mesec
-  label_week: Teden
-  label_date_from: Do
-  label_date_to: Do
-  label_language_based: Glede na uporabnikov jezik
-  label_sort_by: "Razporedi po %{value}"
-  label_send_test_email: PoÅ¡lji testno e-pismo
-  label_feeds_access_key_created_on: "RSS dostopni kljuÄ narejen %{value} nazaj"
-  label_module_plural: Moduli
-  label_added_time_by: "Dodan %{author} %{age} nazaj"
-  label_updated_time_by: "Posodobljen od %{author} %{age} nazaj"
-  label_updated_time: "Posodobljen %{value} nazaj"
-  label_jump_to_a_project: SkoÄi na projekt...
-  label_file_plural: Datoteke
-  label_changeset_plural: Zapisi sprememb
-  label_default_columns: Privzeti stolpci
-  label_no_change_option: (Ni spremembe)
-  label_bulk_edit_selected_issues: Uredi izbrane zahtevke skupaj
-  label_theme: Tema
-  label_default: Privzeto
-  label_search_titles_only: PreiÅ¡Äi samo naslove
-  label_user_mail_option_all: "Za vsak dogodek v vseh mojih projektih"
-  label_user_mail_option_selected: "Za vsak dogodek samo na izbranih projektih..."
-  label_user_mail_no_self_notified: "Ne Å¾elim biti opozorjen(a) na spremembe, ki jih naredim sam(a)"
-  label_registration_activation_by_email: aktivacija raÄuna po e-poÅ¡ti
-  label_registration_manual_activation: roÄna aktivacija raÄuna
-  label_registration_automatic_activation: samodejna aktivacija raÄuna
-  label_display_per_page: "Na stran: %{value}"
-  label_age: Starost
-  label_change_properties: Sprememba lastnosti
-  label_general: SploÅ¡no
-  label_more: VeÄ
-  label_scm: SCM
-  label_plugins: VtiÄniki
-  label_ldap_authentication: LDAP overovljanje
-  label_downloads_abbr: D/L
-  label_optional_description: Neobvezen opis
-  label_add_another_file: Dodaj Å¡e eno datoteko
-  label_preferences: Preference
-  label_chronological_order: KronoloÅ¡ko
-  label_reverse_chronological_order: Obrnjeno kronoloÅ¡ko
-  label_planning: NaÄrtovanje
-  label_incoming_emails: PrihajajoÄa e-poÅ¡ta
-  label_generate_key: Ustvari kljuÄ
-  label_issue_watchers: Spremljevalci
-  label_example: Vzorec
-
-  button_login: Prijavi se
-  button_submit: PoÅ¡lji
-  button_save: Shrani
-  button_check_all: OznaÄi vse
-  button_uncheck_all: OdznaÄi vse
-  button_delete: IzbriÅ¡i
-  button_create: Ustvari
-  button_test: Testiraj
-  button_edit: Uredi
-  button_add: Dodaj
-  button_change: Spremeni
-  button_apply: Uporabi
-  button_clear: PoÄisti
-  button_lock: Zakleni
-  button_unlock: Odkleni
-  button_download: Prenesi
-  button_list: Seznam
-  button_view: Pogled
-  button_move: Premakni
-  button_back: Nazaj
-  button_cancel: PrekliÄi
-  button_activate: Aktiviraj
-  button_sort: Razvrsti
-  button_log_time: BeleÅ¾i Äas
-  button_rollback: Povrni na to verzijo
-  button_watch: Spremljaj
-  button_unwatch: Ne spremljaj
-  button_reply: Odgovori
-  button_archive: Arhiviraj
-  button_unarchive: Odarhiviraj
-  button_reset: Ponastavi
-  button_rename: Preimenuj
-  button_change_password: Spremeni geslo
-  button_copy: Kopiraj
-  button_annotate: ZapiÅ¡i pripombo
-  button_update: Posodobi
-  button_configure: Konfiguriraj
-  button_quote: Citiraj
-
-  status_active: aktivni
-  status_registered: registriran
-  status_locked: zaklenjen
-
-  text_select_mail_notifications: Izberi dejanja za katera naj bodo poslana oznanila preko e-poÅ¡to.
-  text_regexp_info: npr. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 pomeni brez omejitev
-  text_project_destroy_confirmation: Ali ste prepriÄani da Å¾elite izbrisati izbrani projekt in vse z njim povezane podatke?
-  text_subprojects_destroy_warning: "Njegov(i) podprojekt(i): %{value} bodo prav tako izbrisani."
-  text_workflow_edit: Izberite vlogo in zahtevek za urejanje poteka dela
-  text_are_you_sure: Ali ste prepriÄani?
-  text_tip_issue_begin_day: naloga z zaÄetkom na ta dan
-  text_tip_issue_end_day: naloga z zakljuÄkom na ta dan
-  text_tip_issue_begin_end_day: naloga ki se zaÄne in konÄa ta dan
-  text_project_identifier_info: 'Dovoljene so samo male Ärke (a-z), Å¡tevilke in vezaji.<br />Enkrat shranjen identifikator ne more biti spremenjen.'
-  text_caracters_maximum: "najveÄ %{count} znakov."
-  text_caracters_minimum: "Mora biti vsaj dolg vsaj %{count} znakov."
-  text_length_between: "DolÅ¾ina med %{min} in %{max} znakov."
-  text_tracker_no_workflow: Potek dela za to vrsto zahtevka ni doloÄen
-  text_unallowed_characters: Nedovoljeni znaki
-  text_comma_separated: Dovoljenih je veÄ vrednosti (loÄenih z vejico).
-  text_issues_ref_in_commit_messages: Zahtevki sklicev in popravkov v sporoÄilu predaje
-  text_issue_added: "Zahtevek %{id} je sporoÄil(a) %{author}."
-  text_issue_updated: "Zahtevek %{id} je posodobil(a) %{author}."
-  text_wiki_destroy_confirmation: Ali ste prepriÄani da Å¾elite izbrisati ta wiki in vso njegovo vsebino?
-  text_issue_category_destroy_question: "Nekateri zahtevki (%{count}) so dodeljeni tej kategoriji. Kaj Å¾elite storiti?"
-  text_issue_category_destroy_assignments: Odstrani naloge v kategoriji
-  text_issue_category_reassign_to: Ponovno dodeli zahtevke tej kategoriji
-  text_user_mail_option: "Na neizbrane projekte boste prejemali le obvestila o zadevah ki jih spremljate ali v katere ste vkljuÄeni (npr. zahtevki katerih avtor(ica) ste)"
-  text_no_configuration_data: "Vloge, vrste zahtevkov, statusi zahtevkov in potek dela Å¡e niso bili doloÄeni. \nZelo priporoÄljivo je, da naloÅ¾ite privzeto  konfiguracijo, ki jo lahko kasneje tudi prilagodite."
-  text_load_default_configuration: NaloÅ¾i privzeto konfiguracijo
-  text_status_changed_by_changeset: "Dodano v zapis sprememb %{value}."
-  text_issues_destroy_confirmation: 'Ali ste prepriÄani, da Å¾elite izbrisati izbrani(e) zahtevek(ke)?'
-  text_select_project_modules: 'Izberite module, ki jih Å¾elite omogoÄiti za ta projekt:'
-  text_default_administrator_account_changed: Spremenjen privzeti administratorski raÄun
-  text_file_repository_writable: OmogoÄeno pisanje v shrambo datotek
-  text_rmagick_available: RMagick je na voljo(neobvezno)
-  text_destroy_time_entries_question: "%{hours} ur je bilo opravljenih na zahtevku, ki ga Å¾elite izbrisati. Kaj Å¾elite storiti?"
-  text_destroy_time_entries: IzbriÅ¡i opravljene ure
-  text_assign_time_entries_to_project: Predaj opravljene ure projektu
-  text_reassign_time_entries: 'Prenesi opravljene ure na ta zahtevek:'
-  text_user_wrote: "%{value} je napisal(a):"
-  text_enumeration_destroy_question: "%{count} objektov je doloÄenih tej vrednosti."
-  text_enumeration_category_reassign_to: 'Ponastavi jih na to vrednost:'
-  text_email_delivery_not_configured: "E-poÅ¡tna dostava ni nastavljena in oznanila so onemogoÄena.\nNastavite vaÅ¡ SMTP streÅ¾nik v config/configuration.yml in ponovno zaÅ¾enite aplikacijo da ga omogoÄite.\n"
-  text_repository_usernames_mapping: "Izberite ali posodobite Redmine uporabnika dodeljenega vsakemu uporabniÅ¡kemu imenu najdenemu v zapisniku shrambe.\n Uporabniki z enakim Redmine ali shrambinem uporabniÅ¡kem imenu ali e-poÅ¡tnem naslovu so samodejno dodeljeni."
-  text_diff_truncated: '... Ta sprememba je bila odsekana ker presega najveÄjo velikost ki je lahko prikazana.'
-
-  default_role_manager: Upravnik
-  default_role_developer: Razvijalec
-  default_role_reporter: PoroÄevalec
-  default_tracker_bug: HroÅ¡Ä
-  default_tracker_feature: Funkcija
-  default_tracker_support: Podpora
-  default_issue_status_new: Nov
-  default_issue_status_in_progress: V teku
-  default_issue_status_resolved: ReÅ¡en
-  default_issue_status_feedback: Povratna informacija
-  default_issue_status_closed: ZakljuÄen
-  default_issue_status_rejected: Zavrnjen
-  default_doc_category_user: UporabniÅ¡ka dokumentacija
-  default_doc_category_tech: TehniÄna dokumentacija
-  default_priority_low: Nizka
-  default_priority_normal: ObiÄajna
-  default_priority_high: Visoka
-  default_priority_urgent: Urgentna
-  default_priority_immediate: TakojÅ¡nje ukrepanje
-  default_activity_design: Oblikovanje
-  default_activity_development: Razvoj
-
-  enumeration_issue_priorities: Prioritete zahtevkov
-  enumeration_doc_categories: Kategorije dokumentov
-  enumeration_activities: Aktivnosti (sledenje Äasa)
-  warning_attachments_not_saved: "%{count} datotek(e) ni bilo mogoÄe shraniti."
-  field_editable: Uredljivo
-  text_plugin_assets_writable: Zapisljiva mapa za vtiÄnike
-  label_display: Prikaz
-  button_create_and_continue: Ustvari in nadaljuj
-  text_custom_field_possible_values_info: 'Ena vrstica za vsako vrednost'
-  setting_repository_log_display_limit: NajveÄje Å¡tevilo prikazanih revizij v log datoteki
-  setting_file_max_size_displayed: NajveÄja velikost besedilnih datotek v vkljuÄenem prikazu
-  field_watcher: Opazovalec
-  setting_openid: Dovoli OpenID prijavo in registracijo
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: ali se prijavi z OpenID
-  field_content: Vsebina
-  label_descending: PadajoÄe
-  label_sort: Razvrsti
-  label_ascending: NaraÅ¡ÄajoÄe
-  label_date_from_to: Od %{start} do %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: Ta stran ima %{descendants} podstran(i) in naslednik(ov). Kaj Å¾elite storiti?
-  text_wiki_page_reassign_children: Znova dodeli podstrani tej glavni strani
-  text_wiki_page_nullify_children: ObdrÅ¾i podstrani kot glavne strani
-  text_wiki_page_destroy_children: IzbriÅ¡i podstrani in vse njihove naslednike
-  setting_password_min_length: Minimalna dolÅ¾ina gesla
-  field_group_by: ZdruÅ¾i rezultate po
-  mail_subject_wiki_content_updated: "'%{id}' wiki stran je bila posodobljena"
-  label_wiki_content_added: Wiki stran dodana
-  mail_subject_wiki_content_added: "'%{id}' wiki stran je bila dodana"
-  mail_body_wiki_content_added: "%{author} je dodal '%{id}' wiki stran"
-  label_wiki_content_updated: Wiki stran posodobljena
-  mail_body_wiki_content_updated: "%{author} je posodobil '%{id}' wiki stran."
-  permission_add_project: Ustvari projekt
-  setting_new_project_user_role_id: Vloga, dodeljena neadministratorskemu uporabniku, ki je ustvaril projekt
-  label_view_all_revisions: Poglej vse revizije
-  label_tag: Oznaka
-  label_branch: Veja
-  error_no_tracker_in_project: Noben sledilnik ni povezan s tem projektom. Prosimo preverite nastavitve projekta.
-  error_no_default_issue_status: Privzeti zahtevek ni definiran. Prosimo preverite svoje nastavitve (Pojdite na "Administracija -> Stanje zahtevkov").
-  text_journal_changed: "%{label} se je spremenilo iz %{old} v %{new}"
-  text_journal_set_to: "%{label} nastavljeno na %{value}"
-  text_journal_deleted: "%{label} izbrisan (%{old})"
-  label_group_plural: Skupine
-  label_group: Skupina
-  label_group_new: Nova skupina
-  label_time_entry_plural: Porabljen Äas
-  text_journal_added: "%{label} %{value} dodan"
-  field_active: Aktiven
-  enumeration_system_activity: Sistemska aktivnost
-  permission_delete_issue_watchers: IzbriÅ¡i opazovalce
-  version_status_closed: zaprt
-  version_status_locked: zaklenjen
-  version_status_open: odprt
-  error_can_not_reopen_issue_on_closed_version: Zahtevek dodeljen zaprti verziji ne more biti ponovno odprt
-  label_user_anonymous: Anonimni
-  button_move_and_follow: Premakni in sledi
-  setting_default_projects_modules: Privzeti moduli za nove projekte
-  setting_gravatar_default: Privzeta Gravatar slika
-  field_sharing: Deljenje
-  label_version_sharing_hierarchy: S projektno hierarhijo
-  label_version_sharing_system: Z vsemi projekti
-  label_version_sharing_descendants: S podprojekti
-  label_version_sharing_tree: Z drevesom projekta
-  label_version_sharing_none: Ni deljeno
-  error_can_not_archive_project: Ta projekt ne more biti arhiviran
-  button_duplicate: Podvoji
-  button_copy_and_follow: Kopiraj in sledi
-  label_copy_source: Vir
-  setting_issue_done_ratio: IzraÄunaj razmerje opravljenega zahtevka z
-  setting_issue_done_ratio_issue_status: Uporabi stanje zahtevka
-  error_issue_done_ratios_not_updated: Razmerje opravljenega zahtevka ni bilo posodobljeno.
-  error_workflow_copy_target: Prosimo izberite ciljni(e) sledilnik(e) in vlogo(e)
-  setting_issue_done_ratio_issue_field: Uporabi polje zahtevka
-  label_copy_same_as_target: Enako kot cilj
-  label_copy_target: Cilj
-  notice_issue_done_ratios_updated: Razmerje opravljenega zahtevka posodobljeno.
-  error_workflow_copy_source: Prosimo izberite vir zahtevka ali vlogo
-  label_update_issue_done_ratios: Posodobi razmerje opravljenega zahtevka
-  setting_start_of_week: ZaÄni koledarje z
-  permission_view_issues: Poglej zahtevke
-  label_display_used_statuses_only: PrikaÅ¾i samo stanja ki uporabljajo ta sledilnik
-  label_revision_id: Revizija %{value}
-  label_api_access_key: API dostopni kljuÄ
-  label_api_access_key_created_on: API dostopni kljuÄ ustvarjen pred %{value}
-  label_feeds_access_key: RSS dostopni kljuÄ
-  notice_api_access_key_reseted: VaÅ¡ API dostopni kljuÄ je bil ponastavljen.
-  setting_rest_api_enabled: OmogoÄi REST spletni servis
-  label_missing_api_access_key: ManjkajoÄ API dostopni kljuÄ
-  label_missing_feeds_access_key: ManjkajoÄ RSS dostopni kljuÄ
-  button_show: PrikaÅ¾i
-  text_line_separated: Dovoljenih veÄ vrednosti (ena vrstica za vsako vrednost).
-  setting_mail_handler_body_delimiters: OdreÅ¾i e-poÅ¡to po eni od teh vrstic
-  permission_add_subprojects: Ustvari podprojekte
-  label_subproject_new: Nov podprojekt
-  text_own_membership_delete_confirmation: |-
-    Odstranili boste nekatere ali vse od dovoljenj zaradi Äesar morda ne boste mogli veÄ urejati tega projekta.
-    Ali ste prepriÄani, da Å¾elite nadaljevati?
-  label_close_versions: Zapri dokonÄane verzije
-  label_board_sticky: Lepljivo
-  label_board_locked: Zaklenjeno
-  permission_export_wiki_pages: Izvozi wiki strani
-  setting_cache_formatted_text: Predpomni oblikovano besedilo
-  permission_manage_project_activities: Uredi aktivnosti projekta
-  error_unable_delete_issue_status: Stanja zahtevka ni bilo moÅ¾no spremeniti
-  label_profile: Profil
-  permission_manage_subtasks: Uredi podnaloge
-  field_parent_issue: Nadrejena naloga
-  label_subtask_plural: Podnaloge
-  label_project_copy_notifications: Med kopiranjem projekta poÅ¡lji e-poÅ¡tno sporoÄilo
-  error_can_not_delete_custom_field: Polja po meri ni mogoÄe izbrisati
-  error_unable_to_connect: Povezava ni mogoÄa (%{value})
-  error_can_not_remove_role: Ta vloga je v uporabi in je ni mogoÄe izbrisati.
-  error_can_not_delete_tracker: Ta sledilnik vsebuje zahtevke in se ga ne more izbrisati.
-  field_principal: Upravnik varnosti
-  label_my_page_block: Moj gradnik strani
-  notice_failed_to_save_members: "Shranjevanje uporabnika(ov) ni uspelo: %{errors}."
-  text_zoom_out: PribliÅ¾aj
-  text_zoom_in: Oddalji
-  notice_unable_delete_time_entry: Brisanje dnevnika porabljenaga Äasa ni mogoÄe.
-  label_overall_spent_time: Skupni porabljeni Äas
-  field_time_entries: BeleÅ¾i porabljeni Äas
-  project_module_gantt: Gantogram
-  project_module_calendar: Koledear
-  button_edit_associated_wikipage: "Uredi povezano Wiki stran: %{page_title}"
-  text_are_you_sure_with_children: IzbriÅ¡i zahtevek in vse podazahtevke?
-  field_text: Besedilno polje
-  label_user_mail_option_only_owner: Samo za stvari katerih lastnik sem
-  setting_default_notification_option: Privzeta moÅ¾nost obveÅ¡Äanja
-  label_user_mail_option_only_my_events: Samo za stvari, ki jih opazujem ali sem v njih vpleten
-  label_user_mail_option_only_assigned: Samo za stvari, ki smo mi dodeljene
-  label_user_mail_option_none: Noben dogodek
-  field_member_of_group: PooblaÅ¡ÄenÄeva skupina
-  field_assigned_to_role: PooblaÅ¡ÄenÄeva vloga
-  notice_not_authorized_archived_project: Projekt, do katerega poskuÅ¡ate dostopati, je bil arhiviran.
-  label_principal_search: "PoiÅ¡Äi uporabnika ali skupino:"
-  label_user_search: "PoiÅ¡Äi uporabnikia:"
-  field_visible: Viden
-  setting_emails_header: Glava e-poÅ¡te
-  setting_commit_logtime_activity_id: Aktivnost zabeleÅ¾enega Äasa
-  text_time_logged_by_changeset: Uporabljeno v spremembi %{value}.
-  setting_commit_logtime_enabled: OmogoÄi beleÅ¾enje Äasa
-  notice_gantt_chart_truncated: Graf je bil odrezan, ker je prekoraÄil najveÄje dovoljeno Å¡tevilo elementov, ki se jih lahko prikaÅ¾e (%{max})
-  setting_gantt_items_limit: NajveÄje Å¡tevilo elementov prikazano na gantogramu
-  field_warn_on_leaving_unsaved: Opozori me, kadar zapuÅ¡Äam stran z neshranjenim besedilom
-  text_warn_on_leaving_unsaved: Trenutna stran vsebuje neshranjeno besedilo ki bo izgubljeno, Äe zapustite to stran.
-  label_my_queries: Moje poizvedbe po meri
-  text_journal_changed_no_detail: "%{label} posodobljen"
-  label_news_comment_added: Komentar dodan novici
-  button_expand_all: RazÅ¡iri vse
-  button_collapse_all: SkrÄi vse
-  label_additional_workflow_transitions_for_assignee: Dovoljeni dodatni prehodi kadar je uporabnik pooblaÅ¡Äenec
-  label_additional_workflow_transitions_for_author: Dovoljeni dodatni prehodi kadar je uporabnik avtor
-  label_bulk_edit_selected_time_entries: Skupinsko urejanje izbranih Äasovnih zapisov
-  text_time_entries_destroy_confirmation: Ali ste prepriÄani, da Å¾elite izbristai izbran(e) Äasovn(i/e) zapis(e)?
-  label_role_anonymous: Anonimni
-  label_role_non_member: NeÄlan
-  label_issue_note_added: Dodan zaznamek
-  label_issue_status_updated: Status posodobljen
-  label_issue_priority_updated: Prioriteta posodobljena
-  label_issues_visibility_own: Zahtevek ustvarjen s strani uporabnika ali dodeljen uporabniku
-  field_issues_visibility: Vidljivost zahtevkov
-  label_issues_visibility_all: Vsi zahtevki
-  permission_set_own_issues_private: Nastavi lastne zahtevke kot javne ali zasebne
-  field_is_private: Zaseben
-  permission_set_issues_private: Nastavi zahtevke kot javne ali zasebne
-  label_issues_visibility_public: Vsi nezasebni zahtevki
-  text_issues_destroy_descendants_confirmation: To bo izbrisalo tudi  %{count} podnalog(o).
-  field_commit_logs_encoding: Kodiranje sporoÄil ob predaji
-  field_scm_path_encoding: Pot do kodiranja
-  text_scm_path_encoding_note: "Privzeto: UTF-8"
-  field_path_to_repository: Pot do shrambe
-  field_root_directory: Korenska mapa
-  field_cvs_module: Modul
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Lokalna shramba (npr. /hgrepo, c:\hgrepo)
-  text_scm_command: Ukaz
-  text_scm_command_version: Verzija
-  label_git_report_last_commit: SporoÄi zadnje uveljavljanje datotek in map
-  text_scm_config: Svoje SCM ukaze lahko nastavite v datoteki config/configuration.yml. Po urejanju prosimo ponovno zaÅ¾enite aplikacijo.
-  text_scm_command_not_available: SCM ukaz ni na voljo. Prosimo preverite nastavitve v upravljalskem podoknu.
-
-  text_git_repository_note: Shramba je prazna in lokalna (npr. /gitrepo, c:\gitrepo)
-
-  notice_issue_successful_create: Ustvarjen zahtevek %{id}.
-  label_between: med
-  setting_issue_group_assignment: Dovoli dodeljevanje zahtevka skupinam
-  label_diff: diff
-
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/47/47226d5a01dc8a69470963b9e6191a0eef3e2f87.svn-base
--- a/.svn/pristine/47/47226d5a01dc8a69470963b9e6191a0eef3e2f87.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-<h3><%=l(:label_watched_issues)%> (<%= Issue.visible.watched_by(user.id).count %>)</h3>
-<% watched_issues = Issue.visible.on_active_project.watched_by(user.id).recently_updated.with_limit(10) %>
-
-<%= render :partial => 'issues/list_simple', :locals => { :issues => watched_issues } %>
-<% if watched_issues.length > 0 %>
-<p class="small"><%= link_to l(:label_issue_view_all), :controller => 'issues',
-                                                       :action => 'index',
-                                                       :set_filter => 1,
-                                                       :watcher_id => 'me',
-                                                       :sort => 'updated_on:desc' %></p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/47/479ac14fe82d486e34532603c24b409ad8800748.svn-base
--- /dev/null
+++ b/.svn/pristine/47/479ac14fe82d486e34532603c24b409ad8800748.svn-base
@@ -0,0 +1,405 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueQuery < Query
+
+  self.queried_class = Issue
+
+  self.available_columns = [
+    QueryColumn.new(:id, :sortable => "#{Issue.table_name}.id", :default_order => 'desc', :caption => '#', :frozen => true),
+    QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
+    QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position", :groupable => true),
+    QueryColumn.new(:parent, :sortable => ["#{Issue.table_name}.root_id", "#{Issue.table_name}.lft ASC"], :default_order => 'desc', :caption => :field_parent_issue),
+    QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true),
+    QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc', :groupable => true),
+    QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
+    QueryColumn.new(:author, :sortable => lambda {User.fields_for_order_statement("authors")}, :groupable => true),
+    QueryColumn.new(:assigned_to, :sortable => lambda {User.fields_for_order_statement}, :groupable => true),
+    QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'),
+    QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true),
+    QueryColumn.new(:fixed_version, :sortable => lambda {Version.fields_for_order_statement}, :groupable => true),
+    QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date"),
+    QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date"),
+    QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours"),
+    QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true),
+    QueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc'),
+    QueryColumn.new(:closed_on, :sortable => "#{Issue.table_name}.closed_on", :default_order => 'desc'),
+    QueryColumn.new(:relations, :caption => :label_related_issues),
+    QueryColumn.new(:description, :inline => false)
+  ]
+
+  scope :visible, lambda {|*args|
+    user = args.shift || User.current
+    base = Project.allowed_to_condition(user, :view_issues, *args)
+    user_id = user.logged? ? user.id : 0
+
+    includes(:project).where("(#{table_name}.project_id IS NULL OR (#{base})) AND (#{table_name}.is_public = ? OR #{table_name}.user_id = ?)", true, user_id)
+  }
+
+  def initialize(attributes=nil, *args)
+    super attributes
+    self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} }
+  end
+
+  # Returns true if the query is visible to +user+ or the current user.
+  def visible?(user=User.current)
+    (project.nil? || user.allowed_to?(:view_issues, project)) && (self.is_public? || self.user_id == user.id)
+  end
+
+  def initialize_available_filters
+    principals = []
+    subprojects = []
+    versions = []
+    categories = []
+    issue_custom_fields = []
+    
+    if project
+      principals += project.principals.sort
+      unless project.leaf?
+        subprojects = project.descendants.visible.all
+        principals += Principal.member_of(subprojects)
+      end
+      versions = project.shared_versions.all
+      categories = project.issue_categories.all
+      issue_custom_fields = project.all_issue_custom_fields
+    else
+      if all_projects.any?
+        principals += Principal.member_of(all_projects)
+      end
+      versions = Version.visible.find_all_by_sharing('system')
+      issue_custom_fields = IssueCustomField.where(:is_filter => true, :is_for_all => true).all
+    end
+    principals.uniq!
+    principals.sort!
+    users = principals.select {|p| p.is_a?(User)}
+
+
+    add_available_filter "status_id",
+      :type => :list_status, :values => IssueStatus.sorted.all.collect{|s| [s.name, s.id.to_s] }
+
+    if project.nil?
+      project_values = []
+      if User.current.logged? && User.current.memberships.any?
+        project_values << ["<< #{l(:label_my_projects).downcase} >>", "mine"]
+      end
+      project_values += all_projects_values
+      add_available_filter("project_id",
+        :type => :list, :values => project_values
+      ) unless project_values.empty?
+    end
+
+    add_available_filter "tracker_id",
+      :type => :list, :values => trackers.collect{|s| [s.name, s.id.to_s] }
+    add_available_filter "priority_id",
+      :type => :list, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s] }
+
+    author_values = []
+    author_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
+    author_values += users.collect{|s| [s.name, s.id.to_s] }
+    add_available_filter("author_id",
+      :type => :list, :values => author_values
+    ) unless author_values.empty?
+
+    assigned_to_values = []
+    assigned_to_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
+    assigned_to_values += (Setting.issue_group_assignment? ?
+                              principals : users).collect{|s| [s.name, s.id.to_s] }
+    add_available_filter("assigned_to_id",
+      :type => :list_optional, :values => assigned_to_values
+    ) unless assigned_to_values.empty?
+
+    group_values = Group.all.collect {|g| [g.name, g.id.to_s] }
+    add_available_filter("member_of_group",
+      :type => :list_optional, :values => group_values
+    ) unless group_values.empty?
+
+    role_values = Role.givable.collect {|r| [r.name, r.id.to_s] }
+    add_available_filter("assigned_to_role",
+      :type => :list_optional, :values => role_values
+    ) unless role_values.empty?
+
+    if versions.any?
+      add_available_filter "fixed_version_id",
+        :type => :list_optional,
+        :values => versions.sort.collect{|s| ["#{s.project.name} - #{s.name}", s.id.to_s] }
+    end
+
+    if categories.any?
+      add_available_filter "category_id",
+        :type => :list_optional,
+        :values => categories.collect{|s| [s.name, s.id.to_s] }
+    end
+
+    add_available_filter "subject", :type => :text
+    add_available_filter "created_on", :type => :date_past
+    add_available_filter "updated_on", :type => :date_past
+    add_available_filter "closed_on", :type => :date_past
+    add_available_filter "start_date", :type => :date
+    add_available_filter "due_date", :type => :date
+    add_available_filter "estimated_hours", :type => :float
+    add_available_filter "done_ratio", :type => :integer
+
+    if User.current.allowed_to?(:set_issues_private, nil, :global => true) ||
+      User.current.allowed_to?(:set_own_issues_private, nil, :global => true)
+      add_available_filter "is_private",
+        :type => :list,
+        :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]]
+    end
+
+    if User.current.logged?
+      add_available_filter "watcher_id",
+        :type => :list, :values => [["<< #{l(:label_me)} >>", "me"]]
+    end
+
+    if subprojects.any?
+      add_available_filter "subproject_id",
+        :type => :list_subprojects,
+        :values => subprojects.collect{|s| [s.name, s.id.to_s] }
+    end
+
+    add_custom_fields_filters(issue_custom_fields)
+
+    add_associations_custom_fields_filters :project, :author, :assigned_to, :fixed_version
+
+    IssueRelation::TYPES.each do |relation_type, options|
+      add_available_filter relation_type, :type => :relation, :label => options[:name]
+    end
+
+    Tracker.disabled_core_fields(trackers).each {|field|
+      delete_available_filter field
+    }
+  end
+
+  def available_columns
+    return @available_columns if @available_columns
+    @available_columns = self.class.available_columns.dup
+    @available_columns += (project ?
+                            project.all_issue_custom_fields :
+                            IssueCustomField.all
+                           ).collect {|cf| QueryCustomFieldColumn.new(cf) }
+
+    if User.current.allowed_to?(:view_time_entries, project, :global => true)
+      index = nil
+      @available_columns.each_with_index {|column, i| index = i if column.name == :estimated_hours}
+      index = (index ? index + 1 : -1)
+      # insert the column after estimated_hours or at the end
+      @available_columns.insert index, QueryColumn.new(:spent_hours,
+        :sortable => "COALESCE((SELECT SUM(hours) FROM #{TimeEntry.table_name} WHERE #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id), 0)",
+        :default_order => 'desc',
+        :caption => :label_spent_time
+      )
+    end
+
+    if User.current.allowed_to?(:set_issues_private, nil, :global => true) ||
+      User.current.allowed_to?(:set_own_issues_private, nil, :global => true)
+      @available_columns << QueryColumn.new(:is_private, :sortable => "#{Issue.table_name}.is_private")
+    end
+
+    disabled_fields = Tracker.disabled_core_fields(trackers).map {|field| field.sub(/_id$/, '')}
+    @available_columns.reject! {|column|
+      disabled_fields.include?(column.name.to_s)
+    }
+
+    @available_columns
+  end
+
+  def default_columns_names
+    @default_columns_names ||= begin
+      default_columns = Setting.issue_list_default_columns.map(&:to_sym)
+
+      project.present? ? default_columns : [:project] | default_columns
+    end
+  end
+
+  # Returns the issue count
+  def issue_count
+    Issue.visible.count(:include => [:status, :project], :conditions => statement)
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the issue count by group or nil if query is not grouped
+  def issue_count_by_group
+    r = nil
+    if grouped?
+      begin
+        # Rails3 will raise an (unexpected) RecordNotFound if there's only a nil group value
+        r = Issue.visible.count(:joins => joins_for_order_statement(group_by_statement), :group => group_by_statement, :include => [:status, :project], :conditions => statement)
+      rescue ActiveRecord::RecordNotFound
+        r = {nil => issue_count}
+      end
+      c = group_by_column
+      if c.is_a?(QueryCustomFieldColumn)
+        r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h}
+      end
+    end
+    r
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the issues
+  # Valid options are :order, :offset, :limit, :include, :conditions
+  def issues(options={})
+    order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?)
+
+    issues = Issue.visible.where(options[:conditions]).all(
+      :include => ([:status, :project] + (options[:include] || [])).uniq,
+      :conditions => statement,
+      :order => order_option,
+      :joins => joins_for_order_statement(order_option.join(',')),
+      :limit  => options[:limit],
+      :offset => options[:offset]
+    )
+
+    if has_column?(:spent_hours)
+      Issue.load_visible_spent_hours(issues)
+    end
+    if has_column?(:relations)
+      Issue.load_visible_relations(issues)
+    end
+    issues
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the issues ids
+  def issue_ids(options={})
+    order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?)
+
+    Issue.visible.scoped(:conditions => options[:conditions]).scoped(:include => ([:status, :project] + (options[:include] || [])).uniq,
+                     :conditions => statement,
+                     :order => order_option,
+                     :joins => joins_for_order_statement(order_option.join(',')),
+                     :limit  => options[:limit],
+                     :offset => options[:offset]).find_ids
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the journals
+  # Valid options are :order, :offset, :limit
+  def journals(options={})
+    Journal.visible.all(
+      :include => [:details, :user, {:issue => [:project, :author, :tracker, :status]}],
+      :conditions => statement,
+      :order => options[:order],
+      :limit => options[:limit],
+      :offset => options[:offset]
+    )
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the versions
+  # Valid options are :conditions
+  def versions(options={})
+    Version.visible.where(options[:conditions]).all(
+      :include => :project,
+      :conditions => project_statement
+    )
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  def sql_for_watcher_id_field(field, operator, value)
+    db_table = Watcher.table_name
+    "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND " +
+      sql_for_field(field, '=', value, db_table, 'user_id') + ')'
+  end
+
+  def sql_for_member_of_group_field(field, operator, value)
+    if operator == '*' # Any group
+      groups = Group.all
+      operator = '=' # Override the operator since we want to find by assigned_to
+    elsif operator == "!*"
+      groups = Group.all
+      operator = '!' # Override the operator since we want to find by assigned_to
+    else
+      groups = Group.find_all_by_id(value)
+    end
+    groups ||= []
+
+    members_of_groups = groups.inject([]) {|user_ids, group|
+      user_ids + group.user_ids + [group.id]
+    }.uniq.compact.sort.collect(&:to_s)
+
+    '(' + sql_for_field("assigned_to_id", operator, members_of_groups, Issue.table_name, "assigned_to_id", false) + ')'
+  end
+
+  def sql_for_assigned_to_role_field(field, operator, value)
+    case operator
+    when "*", "!*" # Member / Not member
+      sw = operator == "!*" ? 'NOT' : ''
+      nl = operator == "!*" ? "#{Issue.table_name}.assigned_to_id IS NULL OR" : ''
+      "(#{nl} #{Issue.table_name}.assigned_to_id #{sw} IN (SELECT DISTINCT #{Member.table_name}.user_id FROM #{Member.table_name}" +
+        " WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id))"
+    when "=", "!"
+      role_cond = value.any? ?
+        "#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")" :
+        "1=0"
+
+      sw = operator == "!" ? 'NOT' : ''
+      nl = operator == "!" ? "#{Issue.table_name}.assigned_to_id IS NULL OR" : ''
+      "(#{nl} #{Issue.table_name}.assigned_to_id #{sw} IN (SELECT DISTINCT #{Member.table_name}.user_id FROM #{Member.table_name}, #{MemberRole.table_name}" +
+        " WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id AND #{Member.table_name}.id = #{MemberRole.table_name}.member_id AND #{role_cond}))"
+    end
+  end
+
+  def sql_for_is_private_field(field, operator, value)
+    op = (operator == "=" ? 'IN' : 'NOT IN')
+    va = value.map {|v| v == '0' ? connection.quoted_false : connection.quoted_true}.uniq.join(',')
+
+    "#{Issue.table_name}.is_private #{op} (#{va})"
+  end
+
+  def sql_for_relations(field, operator, value, options={})
+    relation_options = IssueRelation::TYPES[field]
+    return relation_options unless relation_options
+
+    relation_type = field
+    join_column, target_join_column = "issue_from_id", "issue_to_id"
+    if relation_options[:reverse] || options[:reverse]
+      relation_type = relation_options[:reverse] || relation_type
+      join_column, target_join_column = target_join_column, join_column
+    end
+
+    sql = case operator
+      when "*", "!*"
+        op = (operator == "*" ? 'IN' : 'NOT IN')
+        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}')"
+      when "=", "!"
+        op = (operator == "=" ? 'IN' : 'NOT IN')
+        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = #{value.first.to_i})"
+      when "=p", "=!p", "!p"
+        op = (operator == "!p" ? 'NOT IN' : 'IN')
+        comp = (operator == "=!p" ? '<>' : '=')
+        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})"
+      end
+
+    if relation_options[:sym] == field && !options[:reverse]
+      sqls = [sql, sql_for_relations(field, operator, value, :reverse => true)]
+      sqls.join(["!", "!*", "!p"].include?(operator) ? " AND " : " OR ")
+    else
+      sql
+    end
+  end
+
+  IssueRelation::TYPES.keys.each do |relation_type|
+    alias_method "sql_for_#{relation_type}_field".to_sym, :sql_for_relations
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/47/47cd8b345d1020290ba00f3aec67bf352663d44c.svn-base
--- a/.svn/pristine/47/47cd8b345d1020290ba00f3aec67bf352663d44c.svn-base
+++ /dev/null
@@ -1,72 +0,0 @@
-module CodeRay
-module Encoders
-  
-  # = XML Encoder
-  #
-  # Uses REXML. Very slow.
-  class XML < Encoder
-    
-    register_for :xml
-    
-    FILE_EXTENSION = 'xml'
-    
-    autoload :REXML, 'rexml/document'
-    
-    DEFAULT_OPTIONS = {
-      :tab_width => 8,
-      :pretty => -1,
-      :transitive => false,
-    }
-    
-  protected
-    def setup options
-      super
-      
-      @doc = REXML::Document.new
-      @doc << REXML::XMLDecl.new
-      @tab_width = options[:tab_width]
-      @root = @node = @doc.add_element('coderay-tokens')
-    end
-    
-    def finish options
-      @doc.write @out, options[:pretty], options[:transitive], true
-      
-      super
-    end
-    
-  public
-    def text_token text, kind
-      if kind == :space
-        token = @node
-      else
-        token = @node.add_element kind.to_s
-      end
-      text.scan(/(\x20+)|(\t+)|(\n)|[^\x20\t\n]+/) do |space, tab, nl|
-        case
-        when space
-          token << REXML::Text.new(space, true)
-        when tab
-          token << REXML::Text.new(tab, true)
-        when nl
-          token << REXML::Text.new(nl, true)
-        else
-          token << REXML::Text.new($&)
-        end
-      end
-    end
-    
-    def begin_group kind
-      @node = @node.add_element kind.to_s
-    end
-    
-    def end_group kind
-      if @node == @root
-        raise 'no token to close!'
-      end
-      @node = @node.parent
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/48/4829d2fe162c5f9c318c8ff9b05ff5fc25513144.svn-base
--- /dev/null
+++ b/.svn/pristine/48/4829d2fe162c5f9c318c8ff9b05ff5fc25513144.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module WelcomeHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/48/482dc54fc612e4f812361911050f6c949928488f.svn-base
--- /dev/null
+++ b/.svn/pristine/48/482dc54fc612e4f812361911050f6c949928488f.svn-base
@@ -0,0 +1,50 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class CustomFieldValue
+  attr_accessor :custom_field, :customized, :value
+
+  def custom_field_id
+    custom_field.id
+  end
+
+  def true?
+    self.value == '1'
+  end
+
+  def editable?
+    custom_field.editable?
+  end
+
+  def visible?
+    custom_field.visible?
+  end
+
+  def required?
+    custom_field.is_required?
+  end
+
+  def to_s
+    value.to_s
+  end
+
+  def validate_value
+    custom_field.validate_field_value(value).each do |message|
+      customized.errors.add(:base, custom_field.name + ' ' + message)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/48/4852f1cf9dc40b28e85de8175f26734a857d7d04.svn-base
--- a/.svn/pristine/48/4852f1cf9dc40b28e85de8175f26734a857d7d04.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class SharedEngineController < ApplicationController
-  def an_action
-    render_class_and_action 'from alpha_engine'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/48/4881b5ad6e4efa4165188246776dbe492c56e6df.svn-base
--- /dev/null
+++ b/.svn/pristine/48/4881b5ad6e4efa4165188246776dbe492c56e6df.svn-base
@@ -0,0 +1,112 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Principal < ActiveRecord::Base
+  self.table_name = "#{table_name_prefix}users#{table_name_suffix}"
+
+  # Account statuses
+  STATUS_ANONYMOUS  = 0
+  STATUS_ACTIVE     = 1
+  STATUS_REGISTERED = 2
+  STATUS_LOCKED     = 3
+
+  has_many :members, :foreign_key => 'user_id', :dependent => :destroy
+  has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}", :order => "#{Project.table_name}.name"
+  has_many :projects, :through => :memberships
+  has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
+
+  # Groups and active users
+  scope :active, lambda { where(:status => STATUS_ACTIVE) }
+
+  scope :like, lambda {|q|
+    q = q.to_s
+    if q.blank?
+      where({})
+    else
+      pattern = "%#{q}%"
+      sql = %w(login firstname lastname mail).map {|column| "LOWER(#{table_name}.#{column}) LIKE LOWER(:p)"}.join(" OR ")
+      params = {:p => pattern}
+      if q =~ /^(.+)\s+(.+)$/
+        a, b = "#{$1}%", "#{$2}%"
+        sql << " OR (LOWER(#{table_name}.firstname) LIKE LOWER(:a) AND LOWER(#{table_name}.lastname) LIKE LOWER(:b))"
+        sql << " OR (LOWER(#{table_name}.firstname) LIKE LOWER(:b) AND LOWER(#{table_name}.lastname) LIKE LOWER(:a))"
+        params.merge!(:a => a, :b => b)
+      end
+      where(sql, params)
+    end
+  }
+
+  # Principals that are members of a collection of projects
+  scope :member_of, lambda {|projects|
+    projects = [projects] unless projects.is_a?(Array)
+    if projects.empty?
+      where("1=0")
+    else
+      ids = projects.map(&:id)
+      active.uniq.joins(:members).where("#{Member.table_name}.project_id IN (?)", ids)
+    end
+  }
+  # Principals that are not members of projects
+  scope :not_member_of, lambda {|projects|
+    projects = [projects] unless projects.is_a?(Array)
+    if projects.empty?
+      where("1=0")
+    else
+      ids = projects.map(&:id)
+      where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE project_id IN (?))", ids)
+    end
+  }
+  scope :sorted, lambda { order(*Principal.fields_for_order_statement)}
+
+  before_create :set_default_empty_values
+
+  def name(formatter = nil)
+    to_s
+  end
+
+  def <=>(principal)
+    if principal.nil?
+      -1
+    elsif self.class.name == principal.class.name
+      self.to_s.downcase <=> principal.to_s.downcase
+    else
+      # groups after users
+      principal.class.name <=> self.class.name
+    end
+  end
+
+  # Returns an array of fields names than can be used to make an order statement for principals.
+  # Users are sorted before Groups.
+  # Examples:
+  def self.fields_for_order_statement(table=nil)
+    table ||= table_name
+    columns = ['type DESC'] + (User.name_formatter[:order] - ['id']) + ['lastname', 'id']
+    columns.uniq.map {|field| "#{table}.#{field}"}
+  end
+
+  protected
+
+  # Make sure we don't try to insert NULL values (see #4632)
+  def set_default_empty_values
+    self.login ||= ''
+    self.hashed_password ||= ''
+    self.firstname ||= ''
+    self.lastname ||= ''
+    self.mail ||= ''
+    true
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/48/48978cef54e6b0d716c9ba5b5c6c5a3e24326336.svn-base
--- /dev/null
+++ b/.svn/pristine/48/48978cef54e6b0d716c9ba5b5c6c5a3e24326336.svn-base
@@ -0,0 +1,154 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module TimelogHelper
+  include ApplicationHelper
+
+  def render_timelog_breadcrumb
+    links = []
+    links << link_to(l(:label_project_all), {:project_id => nil, :issue_id => nil})
+    links << link_to(h(@project), {:project_id => @project, :issue_id => nil}) if @project
+    if @issue
+      if @issue.visible?
+        links << link_to_issue(@issue, :subject => false)
+      else
+        links << "##{@issue.id}"
+      end
+    end
+    breadcrumb links
+  end
+
+  # Returns a collection of activities for a select field.  time_entry
+  # is optional and will be used to check if the selected TimeEntryActivity
+  # is active.
+  def activity_collection_for_select_options(time_entry=nil, project=nil)
+    project ||= @project
+    if project.nil?
+      activities = TimeEntryActivity.shared.active
+    else
+      activities = project.activities
+    end
+
+    collection = []
+    if time_entry && time_entry.activity && !time_entry.activity.active?
+      collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ]
+    else
+      collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
+    end
+    activities.each { |a| collection << [a.name, a.id] }
+    collection
+  end
+
+  def select_hours(data, criteria, value)
+    if value.to_s.empty?
+      data.select {|row| row[criteria].blank? }
+    else
+      data.select {|row| row[criteria].to_s == value.to_s}
+    end
+  end
+
+  def sum_hours(data)
+    sum = 0
+    data.each do |row|
+      sum += row['hours'].to_f
+    end
+    sum
+  end
+
+  def options_for_period_select(value)
+    options_for_select([[l(:label_all_time), 'all'],
+                        [l(:label_today), 'today'],
+                        [l(:label_yesterday), 'yesterday'],
+                        [l(:label_this_week), 'current_week'],
+                        [l(:label_last_week), 'last_week'],
+                        [l(:label_last_n_weeks, 2), 'last_2_weeks'],
+                        [l(:label_last_n_days, 7), '7_days'],
+                        [l(:label_this_month), 'current_month'],
+                        [l(:label_last_month), 'last_month'],
+                        [l(:label_last_n_days, 30), '30_days'],
+                        [l(:label_this_year), 'current_year']],
+                        value)
+  end
+
+  def format_criteria_value(criteria_options, value)
+    if value.blank?
+      "[#{l(:label_none)}]"
+    elsif k = criteria_options[:klass]
+      obj = k.find_by_id(value.to_i)
+      if obj.is_a?(Issue)
+        obj.visible? ? "#{obj.tracker} ##{obj.id}: #{obj.subject}" : "##{obj.id}"
+      else
+        obj
+      end
+    else
+      format_value(value, criteria_options[:format])
+    end
+  end
+
+  def report_to_csv(report)
+    decimal_separator = l(:general_csv_decimal_separator)
+    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
+      # Column headers
+      headers = report.criteria.collect {|criteria| l(report.available_criteria[criteria][:label]) }
+      headers += report.periods
+      headers << l(:label_total_time)
+      csv << headers.collect {|c| Redmine::CodesetUtil.from_utf8(
+                                    c.to_s,
+                                    l(:general_csv_encoding) ) }
+      # Content
+      report_criteria_to_csv(csv, report.available_criteria, report.columns, report.criteria, report.periods, report.hours)
+      # Total row
+      str_total = Redmine::CodesetUtil.from_utf8(l(:label_total_time), l(:general_csv_encoding))
+      row = [ str_total ] + [''] * (report.criteria.size - 1)
+      total = 0
+      report.periods.each do |period|
+        sum = sum_hours(select_hours(report.hours, report.columns, period.to_s))
+        total += sum
+        row << (sum > 0 ? ("%.2f" % sum).gsub('.',decimal_separator) : '')
+      end
+      row << ("%.2f" % total).gsub('.',decimal_separator)
+      csv << row
+    end
+    export
+  end
+
+  def report_criteria_to_csv(csv, available_criteria, columns, criteria, periods, hours, level=0)
+    decimal_separator = l(:general_csv_decimal_separator)
+    hours.collect {|h| h[criteria[level]].to_s}.uniq.each do |value|
+      hours_for_value = select_hours(hours, criteria[level], value)
+      next if hours_for_value.empty?
+      row = [''] * level
+      row << Redmine::CodesetUtil.from_utf8(
+                        format_criteria_value(available_criteria[criteria[level]], value).to_s,
+                        l(:general_csv_encoding) )
+      row += [''] * (criteria.length - level - 1)
+      total = 0
+      periods.each do |period|
+        sum = sum_hours(select_hours(hours_for_value, columns, period.to_s))
+        total += sum
+        row << (sum > 0 ? ("%.2f" % sum).gsub('.',decimal_separator) : '')
+      end
+      row << ("%.2f" % total).gsub('.',decimal_separator)
+      csv << row
+      if criteria.length > level + 1
+        report_criteria_to_csv(csv, available_criteria, columns, criteria, periods, hours_for_value, level + 1)
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/48/48b2840db60b271c593d21c38917c44a5158b68b.svn-base
--- a/.svn/pristine/48/48b2840db60b271c593d21c38917c44a5158b68b.svn-base
+++ /dev/null
@@ -1,29 +0,0 @@
-# Rails <2.x doesn't define #except
-class Hash #:nodoc:
-  # Returns a new hash without the given keys.
-  def except(*keys)
-    clone.except!(*keys)
-  end unless method_defined?(:except)
-
-  # Replaces the hash without the given keys.
-  def except!(*keys)
-    keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
-    keys.each { |key| delete(key) }
-    self
-  end unless method_defined?(:except!)
-end
-
-# NamedScope is new to Rails 2.1
-unless defined? ActiveRecord::NamedScope
-  require 'awesome_nested_set/named_scope'
-  ActiveRecord::Base.class_eval do
-    include CollectiveIdea::NamedScope
-  end
-end
-
-# Rails 1.2.x doesn't define #quoted_table_name
-class ActiveRecord::Base  #:nodoc:
-  def self.quoted_table_name
-    self.connection.quote_column_name(self.table_name)
-  end unless methods.include?('quoted_table_name')
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/48/48b4396c87b793f88c5ab4bc586ea45f81977244.svn-base
--- a/.svn/pristine/48/48b4396c87b793f88c5ab4bc586ea45f81977244.svn-base
+++ /dev/null
@@ -1,28 +0,0 @@
-<%= error_messages_for 'message' %>
-<% replying ||= false %>
-
-<div class="box">
-<!--[form:message]-->
-<p><label for="message_subject"><%= l(:field_subject) %></label><br />
-<%= f.text_field :subject, :size => 120, :id => "message_subject" %>
-
-<% if !replying && User.current.allowed_to?(:edit_messages, @project) %>
-    <label><%= f.check_box :sticky %><%= l(:label_board_sticky) %></label>
-    <label><%= f.check_box :locked %><%= l(:label_board_locked) %></label>
-<% end %>
-</p>
-
-<% if !replying && !@message.new_record? && User.current.allowed_to?(:edit_messages, @project) %>
-  <p><label><%= l(:label_board) %></label><br />
-  <%= f.select :board_id, @project.boards.collect {|b| [b.name, b.id]} %></p>
-<% end %>
-
-<p>
-<%= label_tag "message_content", l(:description_message_content), :class => "hidden-for-sighted" %>
-<%= f.text_area :content, :cols => 80, :rows => 15, :class => 'wiki-edit', :id => 'message_content' %></p>
-<%= wikitoolbar_for 'message_content' %>
-<!--[eoform:message]-->
-
-<p><%= l(:label_attachment_plural) %><br />
-<%= render :partial => 'attachments/form' %></p>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/49/493a8cd26b7fa714fe78dd4274ecdc966ff8a00e.svn-base
--- /dev/null
+++ b/.svn/pristine/49/493a8cd26b7fa714fe78dd4274ecdc966ff8a00e.svn-base
@@ -0,0 +1,47 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module SubclassFactory
+    def self.included(base) 
+      base.extend ClassMethods
+    end 
+
+    module ClassMethods
+      def get_subclass(class_name)
+        klass = nil
+        begin
+          klass = class_name.to_s.classify.constantize
+        rescue
+          # invalid class name
+        end
+        unless subclasses.include? klass
+          klass = nil
+        end
+        klass
+      end
+
+      # Returns an instance of the given subclass name
+      def new_subclass_instance(class_name, *args)
+        klass = get_subclass(class_name)
+        if klass
+          klass.new(*args)
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/49/49a09daa149b6d9350cac1817bdfb249c5164fda.svn-base
--- a/.svn/pristine/49/49a09daa149b6d9350cac1817bdfb249c5164fda.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-<h2><%= link_to l(:label_tracker_plural), trackers_path %> &#187; <%=h @tracker %></h2>
-
-<% form_for @tracker, :builder => TabularFormBuilder do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/49/49af1b38eba0e08163a526b80740e126cc5034c1.svn-base
--- /dev/null
+++ b/.svn/pristine/49/49af1b38eba0e08163a526b80740e126cc5034c1.svn-base
@@ -0,0 +1,1148 @@
+# Lithuanian translations for Ruby on Rails
+# by Laurynas Butkus (laurynas.butkus@gmail.com)
+# Redmine translation by Gediminas MuiÅ¾is gediminas.muizis@gmail.com
+# and Sergej Jegorov sergej.jegorov@gmail.com
+# and Gytis Gurklys gytis.gurklys@gmail.com
+# and Andrius KriuÄkovas andrius.kriuckovas@gmail.com
+
+lt:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [sekmadienis, pirmadienis, antradienis, treÄiadienis, ketvirtadienis, penktadienis, Å¡eÅ¡tadienis]
+#    standalone_day_names: [Sekmadienis, Pirmadienis, Antradienis, TreÄiadienis, Ketvirtadienis, Penktadienis, Å eÅ¡tadienis]
+    abbr_day_names: [Sek, Pir, Ant, Tre, Ket, Pen, Å eÅ¡]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, sausio, vasario, kovo, balandÅ¾io, geguÅ¾Ä—s, birÅ¾elio, liepos, rugpjÅ«Äio, rugsÄ—jo, spalio, lapkriÄio, gruodÅ¾io]
+    abbr_month_names: [~, Sau, Vas, Kov, Bal, Geg, Bir, Lie, Rgp, Rgs, Spa, Lap, Grd]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "ryto"
+    pm: "vakaro"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pusÄ— minutÄ—s"
+      less_than_x_seconds:
+        one:   "maÅ¾iau nei %{count} sekundÄ™"
+        few:   "maÅ¾iau nei %{count} sekundes"
+        many:  "maÅ¾iau nei %{count} sekundÅ¾iÅ³"
+        other: "maÅ¾iau nei %{count} sekundÅ¾iÅ³"
+      x_seconds:
+        one:   "%{count} sekundÄ—"
+        few:   "%{count} sekundÄ—s"
+        many:  "%{count} sekundÅ¾iÅ³"
+        other: "%{count} sekundÅ¾iÅ³"
+      less_than_x_minutes:
+        one:   "maÅ¾iau nei minutÄ™"
+        other: "maÅ¾iau nei %{count} minutes(ÄiÅ³)"
+      x_minutes:
+        one:   "1 minutÄ™"
+        other: "%{count} minutes(ÄiÅ³)"
+      about_x_hours:
+        one:   "apie 1 valandÄ…"
+        other: "apie %{count} valandas(Å³)"
+      x_hours:
+        one:   "1 valandÄ…"
+        other: "%{count} valandas(Å³)"
+      x_days:
+        one:   "1 dienÄ…"
+        other: "%{count} dienas(Å³)"
+      about_x_months:
+        one:   "apie 1 mÄ—nuo"
+        other: "apie %{count} mÄ—n."
+      x_months:
+        one:   "1 mÄ—nuo"
+        other: "%{count} mÄ—n."
+      about_x_years:
+        one:   "apie 1 metus"
+        other: "apie %{count} metÅ³"
+      over_x_years:
+        one:   "virÅ¡ 1 metÅ³"
+        other: "virÅ¡ %{count} metÅ³"
+      almost_x_years:
+        one:   "beveik 1 metus"
+        other: "beveik %{count} metai(us)"
+    prompts:
+      year:   "Metai"
+      month:  "MÄ—nuo"
+      day:    "Diena"
+      hour:   "Valanda"
+      minute: "MinutÄ—"
+      second: "SekundÄ—s"
+
+  number:
+    format:
+      separator: ","
+      delimiter: " "
+      precision: 3
+
+    currency:
+      format:
+        format: "%n %u"
+        unit: "Lt"
+        separator: ","
+        delimiter: " "
+        precision: 2
+
+    percentage:
+      format:
+        delimiter: ""
+
+    precision:
+      format:
+        delimiter: ""
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        # Storage units output formatting.
+        # %u is the storage unit, %n is the number (default: 2 MB)
+        format: "%n %u"
+        units:
+          byte:
+            one:   "baitas"
+            few:   "baitÅ³(ai)"
+            many:  "baitÅ³(ai)"
+            other: "baitÅ³(ai)"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      # Rails 2.2
+      sentence_connector: "ir"
+      skip_last_comma: true
+      # Rails 2.3
+      words_connector: ", "
+      two_words_connector: " ir "
+      last_word_connector: " ir "
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "IÅ¡saugant objektÄ… %{model} rasta %{count} klaida"
+          few:    "IÅ¡saugant objektÄ… %{model} rasta %{count} klaidÅ³"
+          many:   "IÅ¡saugant objektÄ… %{model} rastos %{count} klaidos"
+          other:  "IÅ¡saugant objektÄ… %{model} rastos %{count} klaidos"
+        body: "Å iuose laukuose yra klaidÅ³:"
+
+      messages:
+        inclusion: "nenumatyta reikÅ¡mÄ—"
+        exclusion: "uÅ¾imtas"
+        invalid: "neteisingas"
+        confirmation: "neteisingai pakartotas"
+        accepted: "turi bÅ«ti patvirtintas"
+        empty: "negali bÅ«ti tuÅ¡Äias"
+        blank: "negali bÅ«ti tuÅ¡Äias"
+        too_long:
+          one:   "per ilgas (daugiausiai %{count} simbolius)"
+          few:   "per ilgas (daugiausiai %{count} simboliu)"
+          many:  "per ilgas (daugiausiai %{count} simboliu)"
+          other: "per ilgas (daugiausiai %{count} simboliai)"
+        too_short:
+          one:   "per trumpas (maÅ¾iausiai %{count} simbolius)"
+          few:   "per trumpas (maÅ¾iausiai %{count} simboliu)"
+          many:  "per trumpas (maÅ¾iausiai %{count} simboliu)"
+          other: "per trumpas (maÅ¾iausiai %{count} simboliai)"
+        wrong_length:
+          one:   "neteisingo ilgio (turi bÅ«ti lygiai %{count} simbolius)"
+          few:   "neteisingo ilgio (turi bÅ«ti lygiai %{count} simboliu)"
+          many:  "neteisingo ilgio (turi bÅ«ti lygiai %{count} simboliu)"
+          other: "neteisingo ilgio (turi bÅ«ti lygiai %{count} simboliai)"
+        taken: "jau uÅ¾imtas"
+        not_a_number: "ne skaiÄius"
+        not_a_date: "is not a valid date"
+        greater_than: "turi bÅ«ti didesnis uÅ¾ %{count}"
+        greater_than_or_equal_to: "turi bÅ«ti didesnis arba lygus %{count}"
+        equal_to: "turi bÅ«ti lygus %{count}"
+        less_than: "turi bÅ«ti maÅ¾esnis uÅ¾ %{count}"
+        less_than_or_equal_to: "turi bÅ«ti maÅ¾esnis arba lygus %{count}"
+        odd: "turi bÅ«ti nelyginis"
+        even: "turi bÅ«ti lyginis"
+        greater_than_start_date: "turi bÅ«ti didesnÄ— negu pradÅ¾ios data"
+        not_same_project: "nepriklauso tam paÄiam projektui"
+        circular_dependency: "Å is ryÅ¡ys sukurtÅ³ ciklinÄ™ priklausomybÄ™"
+        cant_link_an_issue_with_a_descendant: "Darbas negali bÅ«ti susietas su viena iÅ¡ savo darbo daliÅ³"
+
+  actionview_instancetag_blank_option: PraÅ¡om parinkti
+
+  general_text_No: 'Ne'
+  general_text_Yes: 'Taip'
+  general_text_no: 'ne'
+  general_text_yes: 'taip'
+  general_lang_name: 'Lithuanian (lietuviÅ³)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Paskyra buvo sÄ—kmingai atnaujinta.
+  notice_account_invalid_creditentials: Negaliojantis vartotojo vardas ar slaptaÅ¾odis
+  notice_account_password_updated: SlaptaÅ¾odis buvo sÄ—kmingai atnaujintas.
+  notice_account_wrong_password: Neteisingas slaptaÅ¾odis
+  notice_account_register_done: Paskyra buvo sÄ—kmingai sukurta. Kad aktyvintumÄ—te savo paskyrÄ…, paspauskite nuorodÄ…, kuri jums buvo siÅ³sta elektroniniu paÅ¡tu.
+  notice_account_unknown_email: NeÅ¾inomas vartotojas.
+  notice_can_t_change_password: Å is praneÅ¡imas naudoja iÅ¡orinÄ¯ autentiÅ¡kumo nustatymo Å¡altinÄ¯. NeÄ¯manoma pakeisti slaptaÅ¾odÄ¯.
+  notice_account_lost_email_sent: Ä® JÅ«sÅ³ paÅ¡tÄ… iÅ¡siÅ³stas laiÅ¡kas su naujo slaptaÅ¾odÅ¾io pasirinkimo instrukcija.
+  notice_account_activated: JÅ«sÅ³ paskyra aktyvuota. Galite prisijungti.
+  notice_successful_create: SÄ—kmingas sukÅ«rimas.
+  notice_successful_update: SÄ—kmingas atnaujinimas.
+  notice_successful_delete: SÄ—kmingas panaikinimas.
+  notice_successful_connection: SÄ—kmingas susijungimas.
+  notice_file_not_found: Puslapis, Ä¯ kurÄ¯ ketinate Ä¯eiti, neegzistuoja arba yra paÅ¡alintas.
+  notice_locking_conflict: Duomenys atnaujinti kito vartotojo.
+  notice_not_authorized: JÅ«s neturite teisiÅ³ gauti prieigÄ… prie Å¡io puslapio.
+  notice_not_authorized_archived_project: Projektas, kurÄ¯ bandote atidaryti, buvo suarchyvuotas.
+  notice_email_sent: "LaiÅ¡kas iÅ¡siÅ³stas %{value}"
+  notice_email_error: "LaiÅ¡ko siuntimo metu Ä¯vyko klaida (%{value})"
+  notice_feeds_access_key_reseted: JÅ«sÅ³ RSS raktas buvo atnaujintas.
+  notice_api_access_key_reseted: JÅ«sÅ³ API prieigos raktas buvo atnaujintas.
+  notice_failed_to_save_issues: "Nepavyko iÅ¡saugoti %{count} problemos(Å³) iÅ¡ %{total} pasirinkto: %{ids}."
+  notice_failed_to_save_members: "Nepavyko iÅ¡saugoti nario(iÅ³): %{errors}."
+  notice_no_issue_selected: "Nepasirinkta nÄ— viena problema! PraÅ¡om paÅ¾ymÄ—ti problemÄ…, kuriÄ… norite redaguoti."
+  notice_account_pending: "JÅ«sÅ³ paskyra buvo sukurta ir dabar laukiama administratoriaus patvirtinimo."
+  notice_default_data_loaded: Numatytoji konfiguracija sÄ—kmingai uÅ¾krauta.
+  notice_unable_delete_version: NeÄ¯manoma panaikinti versijÄ….
+  notice_unable_delete_time_entry: NeÄ¯mano iÅ¡trinti laiko Å¾urnalo Ä¯raÅ¡Ä….
+  notice_issue_done_ratios_updated: Problemos baigtumo rodikliai atnaujinti.
+  notice_gantt_chart_truncated: Grafikas buvo sutrumpintas, kadangi jis virÅ¡ija maksimalÅ³ (%{max}) leistinÅ³ atvaizduoti elementÅ³ kiekÄ¯
+  notice_issue_successful_create: Darbas %{id} sukurtas.
+
+  error_can_t_load_default_data: "Numatytoji konfiguracija negali bÅ«ti uÅ¾krauta: %{value}"
+  error_scm_not_found: "Duomenys ir/ar pakeitimai saugykloje(repozitorojoje) neegzistuoja."
+  error_scm_command_failed: "Ä®vyko klaida jungiantis prie saugyklos: %{value}"
+  error_scm_annotate: "Ä®raÅ¡as neegzistuoja arba negalima jo atvaizduoti."
+  error_scm_annotate_big_text_file: "Ä®raÅ¡o negalima atvaizduoti, nes jis virÅ¡ija maksimalÅ³ tekstinio failo dydÄ¯."
+  error_issue_not_found_in_project: 'Darbas nerastas arba nesuriÅ¡tas su Å¡iuo projektu'
+  error_no_tracker_in_project: 'Joks pÄ—dsekys nesusietas su Å¡iuo projektu. PraÅ¡om patikrinti Projekto nustatymus.'
+  error_no_default_issue_status: Nenustatyta numatytoji darbÅ³ bÅ«sena. PraÅ¡ome patikrinti konfigÅ«ravimÄ… ("Administravimas -> DarbÅ³ bÅ«senos").
+  error_can_not_delete_custom_field: Negalima iÅ¡trinti kliento lauko
+  error_can_not_delete_tracker: "Å is pÄ—dsekys turi Ä¯raÅ¡us ir todÄ—l negali bÅ«ti iÅ¡trintas."
+  error_can_not_remove_role: "Å i rolÄ— yra naudojama ir negali bÅ«ti iÅ¡trinta."
+  error_can_not_reopen_issue_on_closed_version: UÅ¾darytai versijai priskirtas darbas negali bÅ«ti atnaujintas.
+  error_can_not_archive_project: Å io projekto negalima suarchyvuoti
+  error_issue_done_ratios_not_updated: "Ä®raÅ¡o baigtumo rodikliai nebuvo atnaujinti. "
+  error_workflow_copy_source: 'PraÅ¡ome pasirinkti pirminÄ¯ Å¡altinio seklÄ¯ arba rolÄ™'
+  error_workflow_copy_target: 'PraÅ¡ome pasirinkti galutinÄ¯ paskirties seklÄ¯(-ius) arba rolÄ™(-s)'
+  error_unable_delete_issue_status: 'Negalima iÅ¡trinti darbo statuso'
+  error_unable_to_connect: Negalima prisijungti (%{value})
+  error_attachment_too_big: "Å i byla negali bÅ«ti Ä¯kelta, nes virÅ¡ija maksimaliÄ… (%{max_size}) leistinÄ… bylos apimtÄ¯"
+  warning_attachments_not_saved: "%{count} byla(Å³) negali bÅ«ti iÅ¡saugota."
+
+  mail_subject_lost_password: "JÅ«sÅ³ %{value} slaptaÅ¾odis"
+  mail_body_lost_password: 'NorÄ—dami pakeisti slaptaÅ¾odÄ¯, spauskite nuorodÄ…:'
+  mail_subject_register: "JÅ«sÅ³ %{value} paskyros aktyvavimas"
+  mail_body_register: 'NorÄ—dami aktyvuoti paskyrÄ…, spauskite nuorodÄ…:'
+  mail_body_account_information_external: "JÅ«s galite naudoti JÅ«sÅ³ %{value} paskyrÄ…, norÄ—dami prisijungti."
+  mail_body_account_information: Informacija apie JÅ«sÅ³ paskyrÄ…
+  mail_subject_account_activation_request: "%{value} paskyros aktyvavimo praÅ¡ymas"
+  mail_body_account_activation_request: "UÅ¾siregistravo naujas vartotojas (%{value}). Jo paskyra laukia jÅ«sÅ³ patvirtinimo:"
+  mail_subject_reminder: "%{count} jums priskirti darbai per artimiausias %{days} dienÅ³(as)"
+  mail_body_reminder: "%{count} darbas(ai), kurie yra jums priskirti, baigiasi per artimiausias %{days} dienÅ³(as):"
+  mail_subject_wiki_content_added: "'%{id}' pridÄ—tas wiki puslapis"
+  mail_body_wiki_content_added: "'%{id}' wiki puslapÄ¯ pridÄ—jo %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' atnaujintas wiki puslapis"
+  mail_body_wiki_content_updated: "'%{id}' wiki puslapÄ¯ atnaujino %{author}."
+
+
+  field_name: Pavadinimas
+  field_description: ApraÅ¡as
+  field_summary: Santrauka
+  field_is_required: Reikalaujama
+  field_firstname: Vardas
+  field_lastname: PavardÄ—
+  field_mail: El. paÅ¡tas
+  field_filename: Failas
+  field_filesize: Dydis
+  field_downloads: Atsiuntimai
+  field_author: Autorius
+  field_created_on: Sukurta
+  field_updated_on: Atnaujintas(a)
+  field_field_format: Formatas
+  field_is_for_all: Visiems projektams
+  field_possible_values: Galimos reikÅ¡mÄ—s
+  field_regexp: Pastovi iÅ¡raiÅ¡ka
+  field_min_length: Minimalus ilgis
+  field_max_length: Maksimalus ilgis
+  field_value: VertÄ—
+  field_category: Kategorija
+  field_title: Pavadinimas
+  field_project: Projektas
+  field_issue: Darbas
+  field_status: BÅ«sena
+  field_notes: Pastabos
+  field_is_closed: Darbas uÅ¾darytas
+  field_is_default: Numatytoji vertÄ—
+  field_tracker: PÄ—dsekys
+  field_subject: Tema
+  field_due_date: UÅ¾baigimo data
+  field_assigned_to: Paskirtas
+  field_priority: Prioritetas
+  field_fixed_version: TikslinÄ— versija
+  field_user: Vartotojas
+  field_principal: Vardas
+  field_role: Vaidmuo
+  field_homepage: Pagrindinis puslapis
+  field_is_public: VieÅ¡as
+  field_parent: Priklauso projektui
+  field_is_in_roadmap: Darbai rodomi veiklos grafike
+  field_login: Registracijos vardas
+  field_mail_notification: Elektroninio paÅ¡to praneÅ¡imai
+  field_admin: Administratorius
+  field_last_login_on: Paskutinis prisijungimas
+  field_language: Kalba
+  field_effective_date: Data
+  field_password: SlaptaÅ¾odis
+  field_new_password: Naujas slaptaÅ¾odis
+  field_password_confirmation: Patvirtinimas
+  field_version: Versija
+  field_type: Tipas
+  field_host: Pagrindinis kompiuteris
+  field_port: Prievadas
+  field_account: Paskyra
+  field_base_dn: Bazinis skiriamasis vardas (base DN)
+  field_attr_login: Registracijos vardo poÅ¾ymis (login)
+  field_attr_firstname: Vardo poÅ¾ymis
+  field_attr_lastname: PavardÄ—s poÅ¾ymis
+  field_attr_mail: Elektroninio paÅ¡to poÅ¾ymis
+  field_onthefly: Automatinis vartotojÅ³ registravimas
+  field_start_date: PradÄ—ti
+  field_done_ratio: "% atlikta"
+  field_auth_source: AutentiÅ¡kumo nustatymo bÅ«das
+  field_hide_mail: SlÄ—pti mano elektroninio paÅ¡to adresÄ…
+  field_comments: Komentaras
+  field_url: URL
+  field_start_page: PradÅ¾ios puslapis
+  field_subproject: Subprojektas
+  field_hours: valandos
+  field_activity: Veikla
+  field_spent_on: Data
+  field_identifier: Identifikuotojas
+  field_is_filter: Panaudotas kaip filtras
+  field_issue_to: SusijÄ™s darbas
+  field_delay: UÅ¾laikymas
+  field_assignable: Darbai gali bÅ«ti paskirti Å¡iam vaidmeniui
+  field_redirect_existing_links: Peradresuokite egzistuojanÄias sÄ…sajas
+  field_estimated_hours: Numatyta trukmÄ—
+  field_column_names: Skiltys
+  field_time_entries: Praleistas laikas
+  field_time_zone: Laiko juosta
+  field_searchable: Randamas
+  field_default_value: Numatytoji vertÄ—
+  field_comments_sorting: Rodyti komentarus
+  field_parent_title: AukÅ¡tesnio lygio puslapis
+  field_editable: Redaguojamas
+  field_watcher: StebÄ—tojas
+  field_identity_url: OpenID URL
+  field_content: Turinys
+  field_group_by: Sugrupuoti pagal
+  field_sharing: Dalijimasis
+  field_parent_issue: PagrindinÄ— uÅ¾duotis
+  field_member_of_group: "Priskirtojo grupÄ—"
+  field_assigned_to_role: "Priskirtojo rolÄ—"
+  field_text: Teksto laukas
+  field_visible: Matomas
+  field_warn_on_leaving_unsaved: "Ä®spÄ—ti mane, kai paliekamas puslapis su neiÅ¡saugotu tekstu"
+  field_issues_visibility: DarbÅ³ matomumas
+  field_is_private: Privatus
+  field_commit_logs_encoding: Commit praneÅ¡imÅ³ koduotÄ—
+  field_scm_path_encoding: Kelio koduotÄ—
+  field_path_to_repository: Saugyklos kelias
+  field_root_directory: Root directorija
+  field_cvsroot: CVSROOT
+  field_cvs_module: Modulis
+
+  setting_app_title: Programos pavadinimas
+  setting_app_subtitle: Programos paantraÅ¡tÄ—
+  setting_welcome_text: Pasveikinimas
+  setting_default_language: Numatytoji kalba
+  setting_login_required: Reikalingas autentiÅ¡kumo nustatymas
+  setting_self_registration: Saviregistracija
+  setting_attachment_max_size: Priedo maks. dydis
+  setting_issues_export_limit: DarbÅ³ eksportavimo riba
+  setting_mail_from: IÅ¡leidimo elektroninio paÅ¡to adresas
+  setting_bcc_recipients: Akli tikslios kopijos gavÄ—jai (bcc)
+  setting_plain_text_mail: Tik tekstas (be HTML)
+  setting_host_name: Pagrindinio kompiuterio vardas
+  setting_text_formatting: Teksto formatavimas
+  setting_wiki_compression: Wiki istorijos suspaudimas
+  setting_feeds_limit: Perdavimo turinio maksimali riba
+  setting_default_projects_public: Nauji projektai vieÅ¡i pagal nutylÄ—jimÄ…
+  setting_autofetch_changesets: Automatinis pakeitimÅ³ siuntimas
+  setting_sys_api_enabled: Ä®galinti WS sandÄ—lio valdymui
+  setting_commit_ref_keywords: Nurodymo reikÅ¡miniai Å¾odÅ¾iai
+  setting_commit_fix_keywords: Fiksavimo reikÅ¡miniai Å¾odÅ¾iai
+  setting_autologin: Automatinis prisijungimas
+  setting_date_format: Datos formatas
+  setting_time_format: Laiko formatas
+  setting_cross_project_issue_relations: Leisti tarprojektinius darbÅ³ ryÅ¡ius
+  setting_issue_list_default_columns: Numatytosios skiltys darbÅ³ sÄ…raÅ¡e
+  setting_repositories_encodings: PridÄ—tÅ³ failÅ³ ir saugyklÅ³ Å¡ifravimas
+  setting_emails_header: LaiÅ¡ko antraÅ¡tÄ—
+  setting_emails_footer: LaiÅ¡ko poraÅ¡tÄ—
+  setting_protocol: Protokolas
+  setting_per_page_options: Ä®raÅ¡Å³ puslapyje nustatymas  
+  setting_user_format: Vartotojo atvaizdavimo formatas
+  setting_activity_days_default: Atvaizduojamos dienos projekto veikloje
+  setting_display_subprojects_issues: Pagal nutylÄ—jimÄ… rodyti subprojektÅ³ darbus pagrindiniame projekte
+  setting_enabled_scm: Ä®galinti SCM
+  setting_mail_handler_body_delimiters: "Trumpinti laiÅ¡kus po vienos iÅ¡ Å¡iÅ³ eiluÄiÅ³"
+  setting_mail_handler_api_enabled: Ä®galinti WS Ä¯einantiems laiÅ¡kams
+  setting_mail_handler_api_key: API raktas
+  setting_sequential_project_identifiers: Generuoti nuoseklius projekto identifikatorius
+  setting_gravatar_enabled: Naudoti Gravatar vartotojo paveiksliukus
+  setting_gravatar_default: Gravatar paveiksliukas pagal nutylÄ—jimÄ…
+  setting_diff_max_lines_displayed: Maksimalus rodomas pakeitimÅ³ eiluÄiÅ³ skaiÄius
+  setting_file_max_size_displayed: Maksimalus testiniÅ³ failÅ³ dydis rodomas vienoje eilutÄ—je
+  setting_repository_log_display_limit: Maksimalus revizijÅ³ skaiÄius rodomas failo loge
+  setting_openid: Leisti OpenID prisijungimÄ… ir registracijÄ…
+  setting_password_min_length: Minimalus slaptaÅ¾odÅ¾io ilgis
+  setting_new_project_user_role_id: Vartotojo vaidmuo, suteikiamas ne administratoriui, kuris sukuria projektÄ…
+  setting_default_projects_modules: Pagal nutylÄ—jimÄ… naujam projektui priskirti moduliai
+  setting_issue_done_ratio: DArbo Ä¯vykdymo progresÄ… skaiÄiuoti su
+  setting_issue_done_ratio_issue_field: Naudoti darbo laukÄ…
+  setting_issue_done_ratio_issue_status: Naudoti darbo statusÄ…
+  setting_start_of_week: SavaitÄ—s pradÅ¾ios diena
+  setting_rest_api_enabled: Ä®jungti REST web service
+  setting_cache_formatted_text: PaslÄ—pti formatuotÄ… tekstÄ…
+  setting_default_notification_option: Numatytosios praneÅ¡imÅ³ nuostatos
+  setting_commit_logtime_enabled: Ä®jungti laiko registravimÄ…
+  setting_commit_logtime_activity_id: Laiko Ä¯raÅ¡Å³ veikla
+  setting_gantt_items_limit: Maksimalus rodmenÅ³ skaiÄius rodomas Gantt'o grafike
+  setting_issue_group_assignment: Leisti darbo priskirimÄ… grupÄ—ms
+  setting_default_issue_start_date_to_creation_date: Naudoti dabartinÄ™ datÄ… kaip naujÅ³ darbÅ³ pradÅ¾ios datÄ…
+
+  permission_add_project: Sukurti projektÄ…
+  permission_add_subprojects: Kurti subprojektus
+  permission_edit_project: Taisyti projektÄ…
+  permission_select_project_modules: Parinkti projekto modulius
+  permission_manage_members: Valdyti narius
+  permission_manage_project_activities: Valdyti projekto veiklas
+  permission_manage_versions: Valdyti versijas
+  permission_manage_categories: Valdyti darbÅ³ kategorijas
+  permission_view_issues: UÅ¾duoÄiÅ³ perÅ¾iÅ«ra
+  permission_add_issues: Sukurti darbus
+  permission_edit_issues: Redaguoti darbus
+  permission_manage_issue_relations: Valdyti darbÅ³ ryÅ¡ius
+  permission_set_issues_private: Nustatyti darbÄ… vieÅ¡u ar privaÄiu
+  permission_set_own_issues_private: Nustatyti savo darbus vieÅ¡ais ar privaÄiais
+  permission_add_issue_notes: Sukurti pastabas
+  permission_edit_issue_notes: Redaguoti pastabas
+  permission_edit_own_issue_notes: Redaguoti savo pastabas
+  permission_move_issues: Perkelti darbus
+  permission_delete_issues: PaÅ¡alinti darbus
+  permission_manage_public_queries: Valdyti vieÅ¡as uÅ¾klausas
+  permission_save_queries: IÅ¡saugoti uÅ¾klausas
+  permission_view_gantt: Matyti Gantt grafikÄ…
+  permission_view_calendar: Matyti kalendoriÅ³
+  permission_view_issue_watchers: Matyti stebÄ—tojÅ³ sÄ…raÅ¡Ä…
+  permission_add_issue_watchers: PridÄ—ti stebÄ—tojus
+  permission_delete_issue_watchers: PaÅ¡alinti stebÄ—tojus
+  permission_log_time: Regsitruoti dirbtÄ… laikÄ…
+  permission_view_time_entries: Matyti dirbtÄ… laikÄ…
+  permission_edit_time_entries: Redaguoti laiko Ä¯raÅ¡us
+  permission_edit_own_time_entries: Redguoti savo laiko Ä¯raÅ¡us
+  permission_manage_news: Valdyti naujienas
+  permission_comment_news: Komentuoti naujienas
+  permission_view_documents: Matyti dokumentus
+  permission_manage_files: Valdyti failus
+  permission_view_files: Matyti failus
+  permission_manage_wiki: Valdyti wiki
+  permission_rename_wiki_pages: Pervadinti wiki puslapius
+  permission_delete_wiki_pages: PaÅ¡alinti wiki puslapius
+  permission_view_wiki_pages: Matyti wiki
+  permission_view_wiki_edits: Matyti wiki istorijÄ…
+  permission_edit_wiki_pages: Redaguoti wiki puslapius
+  permission_delete_wiki_pages_attachments: PaÅ¡alinti priedus
+  permission_protect_wiki_pages: Apsaugoti wiki puslapius
+  permission_manage_repository: Valdyti saugyklÄ…
+  permission_browse_repository: PerÅ¾iÅ«rÄ—ti saugyklÄ…
+  permission_view_changesets: Matyti pakeitimus
+  permission_commit_access: Prieiga prie pakeitimÅ³
+  permission_manage_boards: Valdyti forumus
+  permission_view_messages: Matyti praneÅ¡imus
+  permission_add_messages: Skelbti praneÅ¡imus
+  permission_edit_messages: Redaguoti praneÅ¡imus
+  permission_edit_own_messages: Redaguoti savo praneÅ¡imus
+  permission_delete_messages: PaÅ¡alinti praneÅ¡imus
+  permission_delete_own_messages: PaÅ¡alinti savo praneÅ¡imus
+  permission_export_wiki_pages: Eksportuoti wiki puslapius
+  permission_manage_subtasks: Valdyti darbo dalis
+
+  project_module_issue_tracking: DarbÅ³ pÄ—dsekys
+  project_module_time_tracking: Laiko pÄ—dsekys
+  project_module_news: Naujienos
+  project_module_documents: Dokumentai
+  project_module_files: Failai
+  project_module_wiki: Wiki
+  project_module_repository: Saugykla
+  project_module_boards: Forumai
+  project_module_calendar: Kalendorius
+  project_module_gantt: Gantt
+
+  label_user: Vartotojas
+  label_user_plural: Vartotojai
+  label_user_new: Naujas vartotojas
+  label_user_anonymous: Anonimas
+  label_project: Projektas
+  label_project_new: Naujas projektas
+  label_project_plural: Projektai
+  label_x_projects:
+    zero:  nÄ—ra projektÅ³
+    one:   1 projektas
+    other: "%{count} projektÅ³"
+  label_project_all: Visi Projektai
+  label_project_latest: Naujausi projektai
+  label_issue: Darbas
+  label_issue_new: Naujas darbas
+  label_issue_plural: Darbai
+  label_issue_view_all: PerÅ¾iÅ«rÄ—ti visus darbus
+  label_issues_by: "Darbai pagal %{value}"
+  label_issue_added: Darbas pridÄ—tas
+  label_issue_updated: Darbas atnaujintas
+  label_issue_note_added: Pastaba pridÄ—ta 
+  label_issue_status_updated: Statusas atnaujintas
+  label_issue_priority_updated: Prioritetas atnaujintas
+  label_document: Dokumentas
+  label_document_new: Naujas dokumentas
+  label_document_plural: Dokumentai
+  label_document_added: Dokumentas pridÄ—tas
+  label_role: Vaidmuo
+  label_role_plural: Vaidmenys
+  label_role_new: Naujas vaidmuo
+  label_role_and_permissions: Vaidmenys ir leidimai
+  label_role_anonymous: Anonimas
+  label_role_non_member: NÄ—ra narys
+  label_member: Narys
+  label_member_new: Naujas narys
+  label_member_plural: Nariai
+  label_tracker: PÄ—dsekys
+  label_tracker_plural: PÄ—dsekiai
+  label_tracker_new: Naujas pÄ—dsekys
+  label_workflow: DarbÅ³ eiga
+  label_issue_status: Darbo bÅ«sena
+  label_issue_status_plural: DarbÅ³ bÅ«senos
+  label_issue_status_new: Nauja bÅ«sena
+  label_issue_category: Darbo kategorija
+  label_issue_category_plural: Darbo kategorijos
+  label_issue_category_new: Nauja kategorija
+  label_custom_field: Kliento laukas
+  label_custom_field_plural: Kliento laukai
+  label_custom_field_new: Naujas kliento laukas
+  label_enumerations: IÅ¡vardinimai
+  label_enumeration_new: Nauja vertÄ—
+  label_information: Informacija
+  label_information_plural: Informacija
+  label_please_login: PraÅ¡om prisijungti
+  label_register: UÅ¾siregistruoti
+  label_login_with_open_id_option: arba prisijunkite su OpenID
+  label_password_lost: Prarastas slaptaÅ¾odis
+  label_home: Pagrindinis
+  label_my_page: Mano puslapis
+  label_my_account: Mano paskyra
+  label_my_projects: Mano projektai
+  label_my_page_block: Mano puslapio blokas
+  label_administration: Administravimas
+  label_login: Prisijungti
+  label_logout: Atsijungti
+  label_help: Pagalba
+  label_reported_issues: PraneÅ¡ti darbai
+  label_assigned_to_me_issues: Darbai, priskirti man
+  label_last_login: Paskutinis prisijungimas
+  label_registered_on: UÅ¾registruota
+  label_activity: Veikla
+  label_overall_activity: Visa veikla
+  label_user_activity: "%{value} veikla"
+  label_new: Naujas
+  label_logged_as: PrisijungÄ™s kaip
+  label_environment: Aplinka
+  label_authentication: AutentiÅ¡kumo nustatymas
+  label_auth_source: AutentiÅ¡kumo nustatymo bÅ«das
+  label_auth_source_new: Naujas autentiÅ¡kumo nustatymo bÅ«das
+  label_auth_source_plural: AutentiÅ¡kumo nustatymo bÅ«dai
+  label_subproject_plural: Subprojektai
+  label_subproject_new: Naujas subprojektas
+  label_and_its_subprojects: "%{value} projektas ir jo subprojektai"
+  label_min_max_length: Min - Maks ilgis
+  label_list: SÄ…raÅ¡as
+  label_date: Data
+  label_integer: Sveikasis skaiÄius
+  label_float: Slankiojo kablelio skaiÄius
+  label_boolean: Loginis
+  label_string: Tekstas
+  label_text: Ilgas tekstas
+  label_attribute: PoÅ¾ymis
+  label_attribute_plural: PoÅ¾ymiai
+  label_no_data: NÄ—ra kÄ… atvaizduoti
+  label_change_status: Pakeitimo bÅ«sena
+  label_history: Istorija
+  label_attachment: Filas
+  label_attachment_new: Naujas failas
+  label_attachment_delete: PaÅ¡alinkite failÄ…
+  label_attachment_plural: Failai
+  label_file_added: Failas pridÄ—tas
+  label_report: Ataskaita
+  label_report_plural: Ataskaitos
+  label_news: Naujiena
+  label_news_new: PridÄ—ti naujienas
+  label_news_plural: Naujienos
+  label_news_latest: PaskutinÄ—s naujienos
+  label_news_view_all: PerÅ¾iÅ«rÄ—ti visas naujienas
+  label_news_added: Naujiena pridÄ—ta
+  label_news_comment_added: Prie naujienos pridÄ—tas komentaras
+  label_settings: Nustatymai
+  label_overview: ApÅ¾valga
+  label_version: Versija
+  label_version_new: Nauja versija
+  label_version_plural: Versijos
+  label_close_versions: UÅ¾daryti uÅ¾baigtas versijas
+  label_confirmation: Patvirtinimas
+  label_export_to: 'Eksportuoti Ä¯:'
+  label_read: Skaitykite...
+  label_public_projects: VieÅ¡i projektai
+  label_open_issues: atidaryta
+  label_open_issues_plural: atidaryti
+  label_closed_issues: uÅ¾daryta
+  label_closed_issues_plural: uÅ¾daryti
+  label_x_open_issues_abbr_on_total:
+    zero:  0 atvirÅ³ / %{total}
+    one:   1 atviras / %{total}
+    other: "%{count} atviri / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 atvirÅ³
+    one:   1 atviras
+    other: "%{count} atviri"
+  label_x_closed_issues_abbr:
+    zero:  0 uÅ¾darytÅ³
+    one:   1 uÅ¾darytas
+    other: "%{count} uÅ¾darytÅ³"
+  label_total: IÅ¡ viso
+  label_permissions: Leidimai
+  label_current_status: DabartinÄ— bÅ«sena
+  label_new_statuses_allowed: Naujos bÅ«senos galimos
+  label_all: visi(os)
+  label_none: joks
+  label_nobody: niekas
+  label_next: Kitas
+  label_previous: Ankstesnis
+  label_used_by: Naudotas
+  label_details: DetalÄ—s
+  label_add_note: PridÄ—kite pastabÄ…
+  label_per_page: Puslapyje
+  label_calendar: Kalendorius
+  label_months_from: mÄ—nesiai nuo
+  label_gantt: Gantt
+  label_internal: Vidinis
+  label_last_changes: "paskutiniai %{count} pokyÄiai(iÅ³)"
+  label_change_view_all: PerÅ¾iÅ«rÄ—ti visus pakeitimus
+  label_personalize_page: Suasmeninti Å¡Ä¯ puslapÄ¯
+  label_comment: Komentaras
+  label_comment_plural: Komentarai
+  label_x_comments:
+    zero: nÄ—ra komentarÅ³
+    one: 1 komentaras
+    other: "%{count} komentarÅ³"
+  label_comment_add: PridÄ—kite komentarÄ…
+  label_comment_added: Komentaras pridÄ—tas
+  label_comment_delete: PaÅ¡alinti komentarus
+  label_query: UÅ¾klausa
+  label_query_plural: UÅ¾klausos
+  label_query_new: Nauja uÅ¾klausa
+  label_my_queries: Mano sukurtos uÅ¾klausos
+  label_filter_add: PridÄ—ti filtrÄ…
+  label_filter_plural: Filtrai
+  label_equals: yra
+  label_not_equals: nÄ—ra
+  label_in_less_than: anksÄiau nei po
+  label_in_more_than: vÄ—liau nei po
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_between: tarp
+  label_in: per
+  label_today: Å¡iandien
+  label_all_time: visas laikas
+  label_yesterday: vakar
+  label_this_week: Å¡iÄ… savaitÄ™
+  label_last_week: praeita savaitÄ—
+  label_last_n_days: "paskutiniÅ³ %{count} dienÅ³"
+  label_this_month: Å¡is menuo
+  label_last_month: praeitas mÄ—nuo
+  label_this_year: Å¡iemet
+  label_date_range: DienÅ³ diapazonas
+  label_less_than_ago: vÄ—liau nei prieÅ¡
+  label_more_than_ago: anksÄiau nei prieÅ¡
+  label_ago: prieÅ¡
+  label_contains: turi
+  label_not_contains: neturi
+  label_day_plural: dienÅ³(os)
+  label_repository: Saugykla
+  label_repository_plural: Saugyklos
+  label_browse: NarÅ¡yti
+  label_branch: Å aka
+  label_tag: Tag
+  label_revision: Revizija
+  label_revision_plural: Revizijos
+  label_revision_id: Revizija %{value}
+  label_associated_revisions: Susijusios revizijos
+  label_added: pridÄ—tas
+  label_modified: pakeistas
+  label_copied: nukopijuotas
+  label_renamed: pervardintas
+  label_deleted: paÅ¡alintas
+  label_latest_revision: PaskutinÄ— revizija
+  label_latest_revision_plural: PaskutinÄ—s revizijos
+  label_view_revisions: PeÅ¾iÅ«rÄ—ti revizijas
+  label_view_all_revisions: PeÅ¾iÅ«rÄ—ti visas revizijas
+  label_max_size: Maksimalus dydis
+  label_sort_highest: Perkelti Ä¯ virÅ¡Å«nÄ™
+  label_sort_higher: Perkelti Ä¯ virÅ¡Å³
+  label_sort_lower: Perkelti Å¾emyn
+  label_sort_lowest: Perkelti Ä¯ apaÄiÄ…
+  label_roadmap: Veiklos grafikas
+  label_roadmap_due_in: "Baigiasi po %{value}"
+  label_roadmap_overdue: "%{value} vÄ—luojama"
+  label_roadmap_no_issues:  Å iai versijai nepriskirtas koks darbas
+  label_search: IeÅ¡koti
+  label_result_plural: Rezultatai
+  label_all_words: Visi Å¾odÅ¾iai
+  label_wiki: Wiki
+  label_wiki_edit: Wiki redakcija
+  label_wiki_edit_plural: Wiki redakcijos
+  label_wiki_page: Wiki puslapis
+  label_wiki_page_plural: Wiki puslapiai
+  label_index_by_title: Indeksuoti pagal pavadinimÄ…
+  label_index_by_date: Indeksuoti pagal datÄ…
+  label_current_version: Einamoji versija
+  label_preview: PerÅ¾iÅ«ra
+  label_feed_plural: Kanalai
+  label_changes_details: VisÅ³ pakeitimÅ³ detalÄ—s
+  label_issue_tracking: DarbÅ³ sekimas
+  label_spent_time: Dirbtas laikas
+  label_overall_spent_time: Visas dirbtas laikas
+  label_f_hour: "%{value} valanda"
+  label_f_hour_plural: "%{value} valandÅ³(os)"
+  label_time_tracking: Laiko sekimas
+  label_change_plural: Pakeitimai
+  label_statistics: Statistika
+  label_commits_per_month: Ä®kÄ—limai per mÄ—nesÄ¯
+  label_commits_per_author: Ä®kÄ—limai pagal autoriÅ³
+  label_diff: skirt
+  label_view_diff: SkirtumÅ³ perÅ¾iÅ«ra
+  label_diff_inline: Ä¯terptas
+  label_diff_side_by_side: Å¡alia
+  label_options: Pasirinkimai
+  label_copy_workflow_from: Kopijuoti darbÅ³ eiga iÅ¡
+  label_permissions_report: LeidimÅ³ praneÅ¡imas
+  label_watched_issues: Stebimi darbai
+  label_related_issues: SusijÄ™ darbai
+  label_applied_status: Taikomoji bÅ«sena
+  label_loading: Kraunama...
+  label_relation_new: Naujas ryÅ¡ys
+  label_relation_delete: PaÅ¡alinti ryÅ¡Ä¯
+  label_relates_to: susietas su
+  label_duplicates: dubliuoja
+  label_duplicated_by: dubliuojasi su
+  label_blocks: blokuoja
+  label_blocked_by: blokuojamas
+  label_precedes: ankstesnÄ—(is)
+  label_follows: seka
+  label_end_to_start: uÅ¾baigti, kad pradÄ—ti
+  label_end_to_end: uÅ¾baigti, kad pabaigti
+  label_start_to_start: pradÄ—kite pradÄ—ti
+  label_start_to_end: pradÄ—kite uÅ¾baigti
+  label_stay_logged_in: Likti prisijungus
+  label_disabled: iÅ¡jungta(as)
+  label_show_completed_versions: Rodyti uÅ¾baigtas versijas
+  label_me: aÅ¡
+  label_board: Forumas
+  label_board_new: Naujas forumas
+  label_board_plural: Forumai
+  label_board_locked: UÅ¾rakinta
+  label_board_sticky: Lipnus
+  label_topic_plural: Temos
+  label_message_plural: PraneÅ¡imai
+  label_message_last: Paskutinis praneÅ¡imas
+  label_message_new: Naujas praneÅ¡imas
+  label_message_posted: PraneÅ¡imas pridÄ—tas
+  label_reply_plural: Atsakymai
+  label_send_information: NusiÅ³sti paskyros informacijÄ… vartotojui
+  label_year: Metai
+  label_month: MÄ—nuo
+  label_week: SavaitÄ—
+  label_date_from: Nuo
+  label_date_to: Iki
+  label_language_based: PagrÄ¯sta vartotojo kalba
+  label_sort_by: "RÅ«Å¡iuoti pagal %{value}"
+  label_send_test_email: NusiÅ³sti bandomÄ…jÄ¯ laiÅ¡kÄ…
+  label_feeds_access_key: RSS prieigos raktas 
+  label_missing_feeds_access_key: TRÅ«ksta RSS prieigos rakto
+  label_feeds_access_key_created_on: "RSS prieigos raktas sukurtas prieÅ¡ %{value}"
+  label_module_plural: Moduliai
+  label_added_time_by: "PridÄ—jo %{author} prieÅ¡ %{age}"
+  label_updated_time_by: "Atnaujino %{author} prieÅ¡ %{age}"
+  label_updated_time: "Atnaujinta prieÅ¡ %{value}"
+  label_jump_to_a_project: Å uolis Ä¯ projektÄ…...
+  label_file_plural: Failai
+  label_changeset_plural: PakeitimÅ³ rinkiniai
+  label_default_columns: Numatytieji stulpeliai
+  label_no_change_option: (Jokio pakeitimo)
+  label_bulk_edit_selected_issues: MasiÅ¡kai readguoti pasirinktus darbus
+  label_bulk_edit_selected_time_entries: MasiÅ¡kai redaguotumÄ—te pasirinktus laiko Ä¯raÅ¡us
+  label_theme: Tema
+  label_default: Numatyta(as)
+  label_search_titles_only: IeÅ¡koti tiktai pavadinimÅ³ 
+  label_user_mail_option_all: "Bet kokiam Ä¯vykiui visuose mano projektuose"
+  label_user_mail_option_selected: "Bet kokiam Ä¯vykiui tiktai pasirinktuose projektuose ..."
+  label_user_mail_option_none: "NÄ—ra Ä¯vykiÅ³"
+  label_user_mail_option_only_my_events: "Tiktai Ä¯vikiai, kuriuos stebiu arba esu Ä¯trauktas"
+  label_user_mail_option_only_assigned: "Tiktai Ä¯vykiai, kuriems esu priskirtas"
+  label_user_mail_option_only_owner: "Tiktai Ä¯vikiai, kuriÅ³ Å¡eikininkas esu"
+  label_user_mail_no_self_notified: "Nenoriu bÅ«ti informuotas apie pakeitimus, kuriuos pats atlieku"
+  label_registration_activation_by_email: paskyros aktyvacija per e-paÅ¡tÄ…
+  label_registration_manual_activation: rankinÄ— paskyros aktyvacija
+  label_registration_automatic_activation: automatinÄ— paskyros aktyvacija
+  label_display_per_page: "%{value} Ä¯raÅ¡Å³ puslapyje"
+  label_age: AmÅ¾ius
+  label_change_properties: Pakeisti nustatymus
+  label_general: Bendri(as)
+  label_more: Daugiau
+  label_scm: SCM
+  label_plugins: Ä®skiepiai
+  label_ldap_authentication: LDAP autentifikacija
+  label_downloads_abbr: siunt.
+  label_optional_description: ApibÅ«dinimas (laisvai pasirenkamas)
+  label_add_another_file: PridÄ—ti kitÄ… failÄ…
+  label_preferences: SavybÄ—s
+  label_chronological_order: Chronologine tvarka
+  label_reverse_chronological_order: Atbuline chronologine tvarka
+  label_planning: Planavimas
+  label_incoming_emails: Ä®einantys laiÅ¡kai
+  label_generate_key: Generuoti raktÄ…
+  label_issue_watchers: StebÄ—tojai
+  label_example: Pavyzdys
+  label_display: Demonstruoti
+  label_sort: RÅ«Å¡iuoti
+  label_ascending: DidÄ—jantis
+  label_descending: MaÅ¾Ä—jantis
+  label_date_from_to: Nuo %{start} iki %{end}
+  label_wiki_content_added: Wiki puslapis pridÄ—tas
+  label_wiki_content_updated: Wiki puslapis atnaujintas
+  label_group: GrupÄ—
+  label_group_plural: GrupÄ—s
+  label_group_new: Nauja grupÄ—
+  label_time_entry_plural: Sprendimo laikas
+  label_version_sharing_none: Nesidalinama
+  label_version_sharing_descendants: Su subprojektais
+  label_version_sharing_hierarchy: Su projekto hierarchija
+  label_version_sharing_tree: Su projekto medÅ¾iu
+  label_version_sharing_system: Su visais projektais
+  label_update_issue_done_ratios: Atnaujinti darbo atlikimo progresÄ…
+  label_copy_source: Å altinis
+  label_copy_target: Tikslas
+  label_copy_same_as_target: Toks pat kaip tikslas
+  label_display_used_statuses_only: Rodyti tik tuos statusus, kurie naudojami Å¡io pÄ—dsekio
+  label_api_access_key: API prieigos raktas
+  label_missing_api_access_key: TrÅ«ksta API prieigos rakto
+  label_api_access_key_created_on: "API prieigos raktas sukurtas prieÅ¡ %{value}"
+  label_profile: Profilis
+  label_subtask_plural: Darbo dalys
+  label_project_copy_notifications: SiÅ³sti paÅ¡to praneÅ¡imus kopijuojant projektÄ…
+  label_principal_search: "IeÅ¡koti vartotojo arba grupÄ—s:"
+  label_user_search: "IeÅ¡koti vartotojo:"
+  label_issues_visibility_all: Visi darbai
+  label_issues_visibility_public: Visi vieÅ¡i darbai
+  label_issues_visibility_own: Darbai, sukurti vartotojo arba jam priskirti
+  label_git_report_last_commit: Nurodyti paskutinÄ¯ failÅ³ ir katalogÅ³ pakeitimÄ…
+  label_parent_revision: PirminÄ— revizija
+  label_child_revision: Sekanti revizija
+  label_export_options: "%{export_format} eksportavimo nustatymai"
+
+  button_login: Registruotis
+  button_submit: Pateikti
+  button_save: IÅ¡saugoti
+  button_check_all: Å½ymÄ—ti visus
+  button_uncheck_all: AtÅ¾ymÄ—ti visus
+  button_collapse_all: Sutraukti visus
+  button_expand_all: IÅ¡skleisti visus
+  button_delete: PaÅ¡alinti
+  button_create: Sukurti
+  button_create_and_continue: Sukurti ir tÄ™sti
+  button_test: Testas
+  button_edit: Redaguoti
+  button_edit_associated_wikipage: "Redaguoti susijusÄ¯ Wiki puslapÄ¯: %{page_title}"
+  button_add: PridÄ—ti
+  button_change: Keisti
+  button_apply: Pritaikyti
+  button_clear: IÅ¡valyti
+  button_lock: Rakinti
+  button_unlock: Atrakinti
+  button_download: AtsisiÅ³sti
+  button_list: SÄ…raÅ¡as
+  button_view: Å½iÅ«rÄ—ti
+  button_move: Perkelti
+  button_move_and_follow: Perkelti ir sekti
+  button_back: Atgal
+  button_cancel: AtÅ¡aukti
+  button_activate: Aktyvinti
+  button_sort: RÅ«Å¡iuoti
+  button_log_time: Registruoti laikÄ…
+  button_rollback: GrÄ¯Å¾ti Ä¯ Å¡iÄ… versijÄ…
+  button_watch: StebÄ—ti
+  button_unwatch: NestebÄ—ti
+  button_reply: Atsakyti
+  button_archive: Archyvuoti
+  button_unarchive: IÅ¡pakuoti
+  button_reset: Atstatyti
+  button_rename: Pervadinti
+  button_change_password: Pakeisti slaptaÅ¾odÄ¯
+  button_copy: Kopijuoti
+  button_copy_and_follow: Kopijuoti ir laikytis
+  button_annotate: RaÅ¡yti pastabÄ…
+  button_update: Atnaujinti
+  button_configure: KonfigÅ«ruoti
+  button_quote: Cituoti
+  button_duplicate: Dubliuoti
+  button_show: Rodyti
+  button_edit_section: Redaguoti Å¡Ä¯ skirsnÄ¯
+  button_export: Eksportuoti
+
+  status_active: aktyvus
+  status_registered: uÅ¾registruotas
+  status_locked: uÅ¾rakintas
+
+  version_status_open: atidaryta
+  version_status_locked: uÅ¾rakinta
+  version_status_closed: uÅ¾daryta
+
+  field_active: Aktyvus
+
+  text_select_mail_notifications: IÅ¡rinkite veiksmus, apie kuriuos bÅ«tÅ³ praneÅ¡ta elektroniniu paÅ¡tu.
+  text_regexp_info: pvz. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 reiÅ¡kia jokiÅ³ apribojimÅ³
+  text_project_destroy_confirmation: Ar esate Ä¯sitikinÄ™s, kad norite paÅ¡alinti Å¡Ä¯ projektÄ… ir visus susijusius duomenis?
+  text_subprojects_destroy_warning: "Å is(ie) subprojektas(ai): %{value} taip pat bus iÅ¡trintas(i)."
+  text_workflow_edit: IÅ¡rinkite vaidmenÄ¯ ir pÄ—dsekÄ¯, kad redaguotumÄ—te darbÅ³ eigÄ…
+  text_are_you_sure: Ar esate Ä¯sitikinÄ™s?
+  text_journal_changed: "%{label} pakeistas(a) iÅ¡ %{old} Ä¯ %{new}"
+  text_journal_changed_no_detail: "%{label} atnaujintas(a)"
+  text_journal_set_to: "%{label} nustatytas(a) Ä¯ %{value}"
+  text_journal_deleted: "%{label} iÅ¡trintas(a) (%{old})"
+  text_journal_added: "%{label} pridÄ—tas(a) %{value}"
+  text_tip_issue_begin_day: uÅ¾duotis, prasidedanti Å¡iÄ… dienÄ…
+  text_tip_issue_end_day: uÅ¾duotis, pasibaigianti Å¡iÄ… dienÄ…
+  text_tip_issue_begin_end_day: uÅ¾duotis, prasidedanti ir pasibaigianti Å¡iÄ… dienÄ…
+  text_project_identifier_info: 'MaÅ¾osios raidÄ—s (a-z), skaiÄiai ir brÅ«kÅ¡niai galimi.<br/>IÅ¡saugojus, identifikatorius negali bÅ«ti keiÄiamas.'
+  text_caracters_maximum: "%{count} simboliÅ³ maksimumas."
+  text_caracters_minimum: "Turi bÅ«ti maÅ¾iausiai %{count} simboliÅ³ ilgio."
+  text_length_between: "Ilgis tarp %{min} ir %{max} simboliÅ³."
+  text_tracker_no_workflow: Jokia darbÅ³ eiga neapibrÄ—Å¾ta Å¡iam pÄ—dsekiui
+  text_unallowed_characters: Neleistini simboliai
+  text_comma_separated: Leistinos kelios reikÅ¡mÄ—s (atskirtos kableliu).
+  text_line_separated: Galimos kelios reikÅ¡mÄ—s (viena linija vienai vertei).
+  text_issues_ref_in_commit_messages: DarbÅ³ susiejimas ir fiksavimas  pavedimÅ³ Å¾inutÄ—se
+  text_issue_added: "Darbas %{id} buvo praneÅ¡tas (by %{author})."
+  text_issue_updated: "Darbas %{id} buvo atnaujintas (by %{author})."
+  text_wiki_destroy_confirmation: Ar esate Ä¯sitikinÄ™s, kad norite paÅ¡alinti Å¡Ä¯ wiki puslapÄ¯ ir visÄ… jo turinÄ¯?
+  text_issue_category_destroy_question: "Kai kurie darbai (%{count}) yra paskirti Å¡iai kategorijai. KÄ… jÅ«s norite daryti?"
+  text_issue_category_destroy_assignments: PaÅ¡alinti kategorijos uÅ¾duotis
+  text_issue_category_reassign_to: IÅ¡ naujo priskirti darbus Å¡iai kategorijai
+  text_user_mail_option: "NeiÅ¡rinktiems projektams, jÅ«s gausite tiktai praneÅ¡imus apie tuos Ä¯vykius, kuriuos jÅ«s stebite, arba Ä¯ kuriuos esate Ä¯trauktas (pvz. darbai, kuriÅ³ autorius jÅ«s esate  ar esate priskirtas)."
+  text_no_configuration_data: "Vaidmenys, pÄ—dsekiai, darbÅ³ bÅ«senos ir darbÅ³ eiga dar nebuvo konfigÅ«ruoti.\nGrieÅ¾tai rekomenduojam uÅ¾krauti numatytÄ…jÄ… (default) konfiguracijÄ…. UÅ¾krovus, galÄ—site jÄ… modifikuoti."
+  text_load_default_configuration: UÅ¾krauti numatytÄ…j konfiguracijÄ…
+  text_status_changed_by_changeset: "Pakeista %{value} revizijoje."
+  text_time_logged_by_changeset: "Applied in changeset %{value}."
+  text_issues_destroy_confirmation: 'Ar jÅ«s tikrai norite sunaikinti paÅ¾ymÄ—tÄ…(us) darbÄ…(us)?'
+  text_issues_destroy_descendants_confirmation: Taip pat bus iÅ¡trinta(os) %{count} darbo dalis(ys).
+  text_time_entries_destroy_confirmation: 'Ar jÅ«s tikrai norite iÅ¡trinti pasirinktÄ…(us) laiko Ä¯raÅ¡Ä…(us)?'
+  text_select_project_modules: 'Parinkite modulius, kuriuos norite naudoti Å¡iame projekte:'
+  text_default_administrator_account_changed: Administratoriaus numatytoji paskyra pakeista
+  text_file_repository_writable: Ä® failÅ³ saugyklÄ… saugoti galima (RW)
+  text_plugin_assets_writable: Ä® Ä¯skiepiÅ³ apraÅ¡o punktÅ³ katalogÄ… Ä¯raÅ¡yti galima
+  text_rmagick_available: RMagick pasiekiamas (pasirinktinai)
+  text_destroy_time_entries_question: "Naikinamam darbui priskirta %{hours} valandÅ³. KÄ… norite su jomis daryti?"
+  text_destroy_time_entries: IÅ¡trinti Ä¯raÅ¡ytas valandas
+  text_assign_time_entries_to_project: Priskirti Ä¯raÅ¡ytas valandas prie projekto
+  text_reassign_time_entries: 'Priskirti Ä¯raÅ¡ytas valandas Å¡iam darbui:'
+  text_user_wrote: "%{value} paraÅ¡Ä—:"
+  text_enumeration_destroy_question: "%{count} objektai(Å³) priskirti Å¡iai reikÅ¡mei."
+  text_enumeration_category_reassign_to: 'Priskirti juos Å¡iai reikÅ¡mei:'
+  text_email_delivery_not_configured: "El.paÅ¡to siuntimas nesukonfigÅ«ruotas, ir perspÄ—jimai neaktyvus.\nSukonfigÅ«ruokite savo SMTP serverÄ¯ byloje config/configuration.yml ir perleiskite programÄ… norÄ—dami pritaikyti pakeitimus."
+  text_repository_usernames_mapping: "Parinkite ar atnaujinkite Redmine vartotojÄ…, kuris paminÄ—tas saugyklos log'e.\nVartotojai, turintys tÄ… patÄ¯ Redmine ir saugyklos vardÄ… ar el.paÅ¡tÄ… yra automatiÅ¡kai suriÅ¡ti."
+  text_diff_truncated: "... Å is diff'as nukarpytas, nes jis virÅ¡ijo maksimalÅ³ rodomÅ³ eiluÄiÅ³ skaiÄiÅ³."
+  text_custom_field_possible_values_info: 'Po vienÄ… eilutÄ™ kiekvienai reikÅ¡mei'
+  text_wiki_page_destroy_question: "Å is puslapis turi %{descendants} susijusiÅ³ arba iÅ¡vestiniÅ³ puslapiÅ³. KÄ… norÄ—tumÄ—te daryti?"
+  text_wiki_page_nullify_children: Laikyti child puslapius kaip pagrindinius puslapius
+  text_wiki_page_destroy_children: "PaÅ¡alinti child puslapius ir jÅ³ palikuonis"
+  text_wiki_page_reassign_children: "Priskirkite iÅ¡ naujo 'child' puslapius Å¡iam pagrindiniam puslapiui"
+  text_own_membership_delete_confirmation: "JÅ«s esate pasiruoÅ¡Ä™s panaikinti dalÄ¯ arba visus leidimus ir po Å¡io pakeitimo galite prarasti Å¡io projekto redagavimo galimybÄ™. \n Ar jÅ«s esate Ä¯sitikinÄ™s ir tÄ™sti?"
+  text_zoom_in: Priartinti
+  text_zoom_out: Nutolinti
+  text_warn_on_leaving_unsaved: "Dabartinis puslapis turi neiÅ¡saugoto teksto, kuris bus prarastas, jeigu paliksite Å¡Ä¯ puslapÄ¯."
+  text_scm_path_encoding_note: "Numatytasis: UTF-8"
+  text_git_repository_note: Saugykla (repository) yra plika ir vietinÄ— (pvz. /gitrepo, c:\gitrepo)
+  text_mercurial_repository_note: VietinÄ— saugykla (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Komanda
+  text_scm_command_version: Versija
+
+  default_role_manager: Vadovas
+  default_role_developer: Projektuotojas
+  default_role_reporter: PraneÅ¡Ä—jas
+  default_tracker_bug: Klaida
+  default_tracker_feature: YpatybÄ—
+  default_tracker_support: Palaikymas
+  default_issue_status_new: Naujas
+  default_issue_status_in_progress: Vykdomas
+  default_issue_status_resolved: IÅ¡sprÄ™stas
+  default_issue_status_feedback: GrÄ¯Å¾tamasis ryÅ¡ys
+  default_issue_status_closed: UÅ¾darytas
+  default_issue_status_rejected: Atmestas
+  default_doc_category_user: Vartotojo dokumentacija
+  default_doc_category_tech: TechninÄ— dokumentacija
+  default_priority_low: Å½emas
+  default_priority_normal: Normalus
+  default_priority_high: AukÅ¡tas
+  default_priority_urgent: Skubus
+  default_priority_immediate: NeatidÄ—liotinas
+  default_activity_design: Projektavimas
+  default_activity_development: Vystymas
+
+  enumeration_issue_priorities: Darbo prioritetai
+  enumeration_doc_categories: Dokumento kategorijos
+  enumeration_activities: Veiklos (laiko sekimas)
+  enumeration_system_activity: Sistemos veikla
+
+  description_filter: Filtras
+  description_search: PaieÅ¡kos laukas
+  description_choose_project: Projektai
+  description_project_scope: PaieÅ¡kos sritis
+  description_notes: Pastabos
+  description_message_content: Å½inutÄ—s turinys
+  description_query_sort_criteria_attribute: RÅ«Å¡iuoti atributÄ…
+  description_query_sort_criteria_direction: RÅ«Å¡iuoti kryptÄ¯
+  description_user_mail_notification: PaÅ¡to praneÅ¡imÅ³ nustatymai
+  description_available_columns: Galimi Stulpeliai
+  description_selected_columns: Pasirinkti Stulpeliai
+  description_all_columns: Visi stulpeliai
+  description_issue_category_reassign: Pasirinkti darbo kategorijÄ…
+  description_wiki_subpages_reassign: Pasirinkti naujÄ… pagrindinÄ¯ puslapÄ¯
+  description_date_range_list: PasirinkitÄ™ diapazonÄ… iÅ¡ sÄ…raÅ¡o
+  description_date_range_interval: Pasirinkite diapazonÄ… pasirinkdami pradÅ¾ios ir pabaigos datas
+  description_date_from: Ä®vesti pradÅ¾ios datÄ…
+  description_date_to: Ä®vesti pabaigos datÄ…
+
+  label_additional_workflow_transitions_for_assignee: Papildomi darbÅ³ eigos variantai kai darbas paskirtas vartotojui
+  label_additional_workflow_transitions_for_author: Papildomi darbÅ³ eigos variantai kai vartotojas yra darbo autorius
+  notice_failed_to_save_time_entries: "Nepavyko iÅ¡saugoti %{count} laiko Å¾urnalo Ä¯raÅ¡Å³ iÅ¡ %{total} parinktÅ³: %{ids}."
+  label_x_issues:
+    zero:  0 darbas
+    one:   1 darbas
+    other: "%{count} darbai(Å³)"
+  label_repository_new: Nauja saugykla
+  field_repository_is_default: PagrindinÄ— saugykla
+  label_copy_attachments: Kopijuoti priedus
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: UÅ¾baigtos versijos
+  text_project_identifier_info: LeidÅ¾iamos tik maÅ¾osios raidÄ—s (a-z), skaitmenys, brÅ«kÅ¡neliai ir pabraukimo simboliai.<br />KartÄ… iÅ¡saugojus pakeitimai negalimi
+  field_multiple: Keletas reikÅ¡miÅ³
+  setting_commit_cross_project_ref: Leisti visÅ³ kitÅ³ projektÅ³ Ä¯raÅ¡us susieti nuorodomis ir sutaisyti
+  text_issue_conflict_resolution_add_notes: IÅ¡saugoti mano Å¾inutÄ™ ir atmesti likusius mano pataisymus
+  text_issue_conflict_resolution_overwrite: IÅ¡saugoti mano pakeitimus (ankstesniÅ³ pakeitimÅ³ Å¾inutÄ—s bus iÅ¡saugotos, taÄiau kai kurie pakeitimai bus perraÅ¡yti)
+  notice_issue_update_conflict: Darbas buvo pakoreguotas kito vartotojo kol jÅ«s atlikote pakeitimus.
+  text_issue_conflict_resolution_cancel: Atmesti visus mano pakeitimus ir iÅ¡ naujo rodyti %{link}
+  permission_manage_related_issues: Tvarkyti susietus darbus
+  field_auth_source_ldap_filter: LDAP filtras
+  label_search_for_watchers: IeÅ¡koti vartotojÅ³ kuriuos Ä¯traukti kaip stebÄ—tojus
+  notice_account_deleted: JÅ«sÅ³ paskyra panaikinta.
+  setting_unsubscribe: Leisti vartotojams panaikinti savo paskyrÄ…
+  button_delete_my_account: Panaikinti savo paskyrÄ…
+  text_account_destroy_confirmation: |-
+    Ar tikrai norite tÄ™sti?
+    JÅ«sÅ³ paskyra bus panaikinta ir nebus galimybÄ—s jos atkurti.
+  error_session_expired: JÅ«sÅ³ sesija pasibaigÄ—. PraÅ¡ome prisijunti iÅ¡ naujo.
+  text_session_expiration_settings: "Ä®spÄ—jimas: atlikus Å¡iuos pakeitimus visos aktyvios sesijos gali nustoti galiojusios (Ä¯skaitant jÅ«sÅ³ sesijÄ…)."
+  setting_session_lifetime: Sesijos maksimalus galiojimas
+  setting_session_timeout: Sesijos neveiklumo laiko tarpas
+  label_session_expiration: BaigÄ—si sujungimo sesija
+  permission_close_project: UÅ¾daryti / atnaujinti projektÄ…
+  label_show_closed_projects: Matyti uÅ¾darytus projektus
+  button_close: UÅ¾daryti
+  button_reopen: Atnaujinti
+  project_status_active: aktyvus
+  project_status_closed: uÅ¾darytas
+  project_status_archived: archyvuotas
+  text_project_closed: Å is projektas yra uÅ¾darytas, prieinamas tik perÅ¾iÅ«rai.
+  notice_user_successful_create: Vartotojas %{id} sukurtas.
+  field_core_fields: Standartiniai laukai
+  field_timeout: Timeout (po sek.)
+  setting_thumbnails_enabled: Rodyti sumaÅ¾intus priedÅ³ atvaizdus
+  setting_thumbnails_size: SumaÅ¾into atvaizdo dydis (taÅ¡keliais)
+  label_status_transitions: DarbÅ³ eiga
+  label_fields_permissions: Leidimai
+  label_readonly: Tik perÅ¾iÅ«ra
+  label_required: Privaloma(s)
+  text_repository_identifier_info: LeidÅ¾iamos tik maÅ¾osios raidÄ—s (a-z), skaitmenys, brÅ«kÅ¡neliai ir pabraukimo simboliai.<br />KartÄ… iÅ¡saugojus pakeitimai negalimi
+  field_board_parent: Pagrindinis forumas
+  label_attribute_of_project: Projekto pavadinimas %{name}
+  label_attribute_of_author: Autorius %{name}
+  label_attribute_of_assigned_to: Paskirtas %{name}
+  label_attribute_of_fixed_version: Versijos %{name}
+  label_copy_subtasks: Kopijuoti darbo dalis
+  label_copied_to: kopijuota Ä¯
+  label_copied_from: kopijuota iÅ¡
+  label_any_issues_in_project: bet kurie projekto darbai
+  label_any_issues_not_in_project: bet kurie ne Å¡io projekto darbai
+  field_private_notes: PrivaÄios Å¾inutÄ—s
+  permission_view_private_notes: Matyti privaÄias Å¾inutes
+  permission_set_notes_private: Pakeisti Å¾inutÄ™ privaÄia
+  label_no_issues_in_project: projekte nÄ—ra darbÅ³
+  label_any: visi
+  label_last_n_weeks: prieÅ¡ %{count} sav.
+  setting_cross_project_subtasks: Leisti susieti skirtingÅ³ projektÅ³ uÅ¾duoÄiÅ³ dalis
+  label_cross_project_descendants: Su subprojektais
+  label_cross_project_tree: Su projekto medÅ¾iu
+  label_cross_project_hierarchy: Su projekto hierarchija
+  label_cross_project_system: Su visais projektais
+  button_hide: SlÄ—pti
+  setting_non_working_week_days: Nedarbo dienos
+  label_in_the_next_days: per ateinanÄias
+  label_in_the_past_days: per paskutines
+  label_attribute_of_user: Vartotojo %{name}
+  text_turning_multiple_off: Jei jÅ«s iÅ¡jungsite keliÅ³ reikÅ¡miÅ³ pasirinkimÄ…, visos iÅ¡vardintos reikÅ¡mÄ—s bus paÅ¡alintos ir palikta tik viena reikÅ¡mÄ— kiekvienam laukui.
+  label_attribute_of_issue: Ä®raÅ¡ai %{name}
+  permission_add_documents: PridÄ—ti dokumentus
+  permission_edit_documents: Redaguoti dokumentus
+  permission_delete_documents: Trinti dokumentus
+  label_gantt_progress_line: Progreso linija
+  setting_jsonp_enabled: Ä®galinti JSONP palaikymÄ…
+  field_inherit_members: PaveldÄ—ti narius
+  field_closed_on: UÅ¾darytas
+  setting_default_projects_tracker_ids: Sekliai pagal nutylÄ—jimÄ… naujiems projektams
+  label_total_time: IÅ¡ viso
+  text_scm_config: JÅ«s galite pakeisti SCM komandas byloje config/configuration.yml. PraÅ¡ome perkrauti programÄ… po redagavimo, idant Ä¯galinti pakeitimus.
+  text_scm_command_not_available: SCM komanda nepasiekiama. Patikrinkite administravimo skydelio nustatymus.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/49/49c759950bed453cc0da75c2904a201b6bf1a7c4.svn-base
--- a/.svn/pristine/49/49c759950bed453cc0da75c2904a201b6bf1a7c4.svn-base
+++ /dev/null
@@ -1,83 +0,0 @@
-module CodeRay
-module Encoders
-  
-  # A simple JSON Encoder.
-  # 
-  # Example:
-  #  CodeRay.scan('puts "Hello world!"', :ruby).json
-  # yields
-  #  [
-  #    {"type"=>"text", "text"=>"puts", "kind"=>"ident"},
-  #    {"type"=>"text", "text"=>" ", "kind"=>"space"},
-  #    {"type"=>"block", "action"=>"open", "kind"=>"string"},
-  #    {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
-  #    {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"},
-  #    {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
-  #    {"type"=>"block", "action"=>"close", "kind"=>"string"},
-  #  ]
-  class JSON < Encoder
-    
-    begin
-      require 'json'
-    rescue LoadError
-      begin
-        require 'rubygems' unless defined? Gem
-        gem 'json'
-        require 'json'
-      rescue LoadError
-        $stderr.puts "The JSON encoder needs the JSON library.\n" \
-          "Please gem install json."
-        raise
-      end
-    end
-    
-    register_for :json
-    FILE_EXTENSION = 'json'
-    
-  protected
-    def setup options
-      super
-      
-      @first = true
-      @out << '['
-    end
-    
-    def finish options
-      @out << ']'
-    end
-    
-    def append data
-      if @first
-        @first = false
-      else
-        @out << ','
-      end
-      
-      @out << data.to_json
-    end
-    
-  public
-    def text_token text, kind
-      append :type => 'text', :text => text, :kind => kind
-    end
-    
-    def begin_group kind
-      append :type => 'block', :action => 'open', :kind => kind
-    end
-    
-    def end_group kind
-      append :type => 'block', :action => 'close', :kind => kind
-    end
-    
-    def begin_line kind
-      append :type => 'block', :action => 'begin_line', :kind => kind
-    end
-    
-    def end_line kind
-      append :type => 'block', :action => 'end_line', :kind => kind
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/49/49ce90be0c149fe7cbdb78cf85bb09564b042b23.svn-base
--- a/.svn/pristine/49/49ce90be0c149fe7cbdb78cf85bb09564b042b23.svn-base
+++ /dev/null
@@ -1,43 +0,0 @@
-Return-Path: <jsmith@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
-Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
-From: "John Smith" <jsmith@somenet.foo>
-To: <redmine@somenet.foo>
-Subject: New ticket on a given project
-Date: Sun, 22 Jun 2008 12:28:07 +0200
-MIME-Version: 1.0
-Content-Type: text/plain;
-	format=flowed;
-	charset="iso-8859-1";
-	reply-type=original
-Content-Transfer-Encoding: 7bit
-X-Priority: 3
-X-MSMail-Priority: Normal
-X-Mailer: Microsoft Outlook Express 6.00.2900.2869
-X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet 
-turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus 
-blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti 
-sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In 
-in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras 
-sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum 
-id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus 
-eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique 
-sed, mauris. Pellentesque habitant morbi tristique senectus et netus et 
-malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
-platea dictumst.
-
-Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque 
-sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. 
-Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, 
-dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed, 
-massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo 
-pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
-
-Projet: onlinestore
-Tracker: Feature request
-catégorie: Stock management
-priorité: Urgent
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/49/49e241388e4f3f4216ec7154a82eaad6c0c8e9f4.svn-base
--- a/.svn/pristine/49/49e241388e4f3f4216ec7154a82eaad6c0c8e9f4.svn-base
+++ /dev/null
@@ -1,38 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class JournalDetail < ActiveRecord::Base
-  belongs_to :journal
-  before_save :normalize_values
-
-  private
-
-  def normalize_values
-    self.value = normalize(value)
-    self.old_value = normalize(old_value)
-  end
-
-  def normalize(v)
-    if v == true
-      "1"
-    elsif v == false
-      "0"
-    else
-      v
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4a/4a0639ca12562188292e323bfd92d9487f71fda7.svn-base
--- a/.svn/pristine/4a/4a0639ca12562188292e323bfd92d9487f71fda7.svn-base
+++ /dev/null
@@ -1,78 +0,0 @@
---- 
-wiki_pages_001: 
-  created_on: 2007-03-07 00:08:07 +01:00
-  title: CookBook_documentation
-  id: 1
-  wiki_id: 1
-  protected: true
-  parent_id: 
-wiki_pages_002: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Another_page
-  id: 2
-  wiki_id: 1
-  protected: false
-  parent_id: 
-wiki_pages_003: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Start_page
-  id: 3
-  wiki_id: 2
-  protected: false
-  parent_id: 
-wiki_pages_004: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Page_with_an_inline_image
-  id: 4
-  wiki_id: 1
-  protected: false
-  parent_id: 1
-wiki_pages_005: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Child_1
-  id: 5
-  wiki_id: 1
-  protected: false
-  parent_id: 2
-wiki_pages_006: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Child_2
-  id: 6
-  wiki_id: 1
-  protected: false
-  parent_id: 2
-wiki_pages_007: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Child_page_1
-  id: 7
-  wiki_id: 2
-  protected: false
-  parent_id: 8
-wiki_pages_008: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Parent_page
-  id: 8
-  wiki_id: 2
-  protected: false
-  parent_id: 
-wiki_pages_009: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Child_page_2
-  id: 9
-  wiki_id: 2
-  protected: false
-  parent_id: 8
-wiki_pages_010: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Ð­Ñ‚Ð¸ÐºÐ°_Ð¼ÐµÐ½ÐµÐ´Ð¶Ð¼ÐµÐ½Ñ‚Ð°
-  id: 10
-  wiki_id: 1
-  protected: false
-  parent_id: 
-wiki_pages_011: 
-  created_on: 2007-03-08 00:18:07 +01:00
-  title: Page_with_sections
-  id: 11
-  wiki_id: 1
-  protected: false
-  parent_id: 
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4a/4a23cff6d2e8f3f4391d3ef5634965a5324bf60d.svn-base
--- a/.svn/pristine/4a/4a23cff6d2e8f3f4391d3ef5634965a5324bf60d.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-module RFPDF
-  module TemplateHandlers
-    class Base < ::ActionView::TemplateHandlers::ERB
-      
-      def compile(template)
-        src = "_rfpdf_compile_setup;" + super
-      end
-    end
-  end
-end
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4a/4a4cc530e16fc15272849a68536d70a8eaa8b683.svn-base
--- a/.svn/pristine/4a/4a4cc530e16fc15272849a68536d70a8eaa8b683.svn-base
+++ /dev/null
@@ -1,56 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class CommentTest < ActiveSupport::TestCase
-  fixtures :users, :news, :comments
-
-  def setup
-    @jsmith = User.find(2)
-    @news = News.find(1)
-  end
-
-  def test_create
-    comment = Comment.new(:commented => @news, :author => @jsmith, :comments => "my comment")
-    assert comment.save
-    @news.reload
-    assert_equal 2, @news.comments_count
-  end
-
-  def test_create_should_send_notification
-    Setting.notified_events << 'news_comment_added'
-    Watcher.create!(:watchable => @news, :user => @jsmith)
-
-    assert_difference 'ActionMailer::Base.deliveries.size' do
-      Comment.create!(:commented => @news, :author => @jsmith, :comments => "my comment")
-    end
-  end
-
-  def test_validate
-    comment = Comment.new(:commented => @news)
-    assert !comment.save
-    assert_equal 2, comment.errors.length
-  end
-
-  def test_destroy
-    comment = Comment.find(1)
-    assert comment.destroy
-    @news.reload
-    assert_equal 0, @news.comments_count
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4a/4a7aa8e524e7ffcb9d61a2f01e83b69a07ba112b.svn-base
--- a/.svn/pristine/4a/4a7aa8e524e7ffcb9d61a2f01e83b69a07ba112b.svn-base
+++ /dev/null
@@ -1,27 +0,0 @@
-<% if version.completed? %>
-  <p><%= format_date(version.effective_date) %></p>
-<% elsif version.effective_date %>
-  <p><strong><%= due_date_distance_in_words(version.effective_date) %></strong> (<%= format_date(version.effective_date) %>)</p>
-<% end %>
-
-<p><%=h version.description %></p>
-<ul>
-  <% version.custom_values.each do |custom_value| %>
-    <% if !custom_value.value.blank? %>
-       <li><%=h custom_value.custom_field.name %>: <%=h show_value(custom_value) %></li>
-    <% end %>
-  <% end %>
-</ul>
-
-<% if version.fixed_issues.count > 0 %>
-    <%= progress_bar([version.closed_pourcent, version.completed_pourcent], :width => '40em', :legend => ('%0.0f%' % version.completed_pourcent)) %>
-    <p class="progress-info">
-        <%= link_to_if(version.closed_issues_count > 0, l(:label_x_closed_issues_abbr, :count => version.closed_issues_count), :controller => 'issues', :action => 'index', :project_id => version.project, :status_id => 'c', :fixed_version_id => version, :set_filter => 1) %>
-        (<%= '%0.0f' % (version.closed_issues_count.to_f / version.fixed_issues.count * 100) %>%)
-        &#160;
-        <%= link_to_if(version.open_issues_count > 0, l(:label_x_open_issues_abbr, :count => version.open_issues_count), :controller => 'issues', :action => 'index', :project_id => version.project, :status_id => 'o', :fixed_version_id => version, :set_filter => 1) %>
-        (<%= '%0.0f' % (version.open_issues_count.to_f / version.fixed_issues.count * 100) %>%)
-    </p>
-<% else %>
-    <p><em><%= l(:label_roadmap_no_issues) %></em></p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4a/4a905b256f6edbbe772142f865f00ae63e6aa5e8.svn-base
--- /dev/null
+++ b/.svn/pristine/4a/4a905b256f6edbbe772142f865f00ae63e6aa5e8.svn-base
@@ -0,0 +1,31 @@
+<span id="attachments_fields">
+<% if defined?(container) && container && container.saved_attachments %>
+  <% container.saved_attachments.each_with_index do |attachment, i| %>
+    <span id="attachments_p<%= i %>">
+      <%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename') +
+          text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description') +
+          link_to('&nbsp;'.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %>
+      <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %>
+    </span>
+  <% end %>
+<% end %>
+</span>
+<span class="add_attachment">
+<%= file_field_tag 'attachments[dummy][file]',
+      :id => nil,
+      :class => 'file_selector',
+      :multiple => true,
+      :onchange => 'addInputFiles(this);',
+      :data => {
+        :max_file_size => Setting.attachment_max_size.to_i.kilobytes,
+        :max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)),
+        :max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i,
+        :upload_path => uploads_path(:format => 'js'),
+        :description_placeholder => l(:label_optional_description)
+      } %>
+(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
+</span>
+
+<% content_for :header_tags do %>
+  <%= javascript_include_tag 'attachments' %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4a/4ab02a244084d766659b315d2b404e1d4afb8313.svn-base
--- /dev/null
+++ b/.svn/pristine/4a/4ab02a244084d766659b315d2b404e1d4afb8313.svn-base
@@ -0,0 +1,89 @@
+<%= error_messages_for 'project' %>
+
+<div class="box tabular">
+<!--[form:project]-->
+<p><%= f.text_field :name, :required => true, :size => 60 %></p>
+
+<p><%= f.text_area :description, :rows => 8, :class => 'wiki-edit' %></p>
+<p><%= f.text_field :identifier, :required => true, :size => 60, :disabled => @project.identifier_frozen?, :maxlength => Project::IDENTIFIER_MAX_LENGTH %>
+<% unless @project.identifier_frozen? %>
+  <em class="info"><%= l(:text_length_between, :min => 1, :max => Project::IDENTIFIER_MAX_LENGTH) %> <%= l(:text_project_identifier_info).html_safe %></em>
+<% end %></p>
+<p><%= f.text_field :homepage, :size => 60 %></p>
+<p><%= f.check_box :is_public %></p>
+
+<% unless @project.allowed_parents.compact.empty? %>
+    <p><%= label(:project, :parent_id, l(:field_parent)) %><%= parent_project_select_tag(@project) %></p>
+<% end %>
+
+<% if @project.safe_attribute? 'inherit_members' %>
+<p><%= f.check_box :inherit_members %></p>
+<% end %>
+
+<%= wikitoolbar_for 'project_description' %>
+
+<% @project.custom_field_values.each do |value| %>
+  <p><%= custom_field_tag_with_label :project, value %></p>
+<% end %>
+<%= call_hook(:view_projects_form, :project => @project, :form => f) %>
+</div>
+
+<% if @project.new_record? %>
+<fieldset class="box tabular"><legend><%= l(:label_module_plural) %></legend>
+<% Redmine::AccessControl.available_project_modules.each do |m| %>
+    <label class="floating">
+    <%= check_box_tag 'project[enabled_module_names][]', m, @project.module_enabled?(m), :id => "project_enabled_module_names_#{m}" %>
+    <%= l_or_humanize(m, :prefix => "project_module_") %>
+    </label>
+<% end %>
+<%= hidden_field_tag 'project[enabled_module_names][]', '' %>
+<%= javascript_tag 'observeProjectModules()' %>
+</fieldset>
+<% end %>
+
+<% if @project.new_record? || @project.module_enabled?('issue_tracking') %>
+<% unless @trackers.empty? %>
+<fieldset class="box tabular" id="project_trackers"><legend><%=l(:label_tracker_plural)%></legend>
+<% @trackers.each do |tracker| %>
+    <label class="floating">
+    <%= check_box_tag 'project[tracker_ids][]', tracker.id, @project.trackers.include?(tracker) %>
+    <%=h tracker %>
+    </label>
+<% end %>
+<%= hidden_field_tag 'project[tracker_ids][]', '' %>
+</fieldset>
+<% end %>
+
+<% unless @issue_custom_fields.empty? %>
+<fieldset class="box tabular" id="project_issue_custom_fields"><legend><%=l(:label_custom_field_plural)%></legend>
+<% @issue_custom_fields.each do |custom_field| %>
+    <label class="floating">
+  <%= check_box_tag 'project[issue_custom_field_ids][]', custom_field.id, (@project.all_issue_custom_fields.include? custom_field), (custom_field.is_for_all? ? {:disabled => "disabled"} : {}) %>
+  <%=h custom_field.name %>
+  </label>
+<% end %>
+<%= hidden_field_tag 'project[issue_custom_field_ids][]', '' %>
+</fieldset>
+<% end %>
+<% end %>
+<!--[eoform:project]-->
+
+<% unless @project.identifier_frozen? %>
+  <% content_for :header_tags do %>
+    <%= javascript_include_tag 'project_identifier' %>
+  <% end %>
+<% end %>
+
+<% if !User.current.admin? && @project.inherit_members? && @project.parent && User.current.member_of?(@project.parent) %>
+  <%= javascript_tag do %>
+    $(document).ready(function() {
+      $("#project_inherit_members").change(function(){
+        if (!$(this).is(':checked')) {
+          if (!confirm("<%= escape_javascript(l(:text_own_membership_delete_confirmation)) %>")) {
+            $("#project_inherit_members").attr("checked", true);
+          }
+        }
+      });
+    });
+  <% end %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4a/4ab9278cce0785883057ff4ba259f3d5b17b6fd7.svn-base
--- a/.svn/pristine/4a/4ab9278cce0785883057ff4ba259f3d5b17b6fd7.svn-base
+++ /dev/null
@@ -1,53 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'mail_handler_controller'
-
-# Re-raise errors caught by the controller.
-class MailHandlerController; def rescue_action(e) raise e end; end
-
-class MailHandlerControllerTest < ActionController::TestCase
-  fixtures :users, :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :issue_statuses, :trackers, :enumerations
-
-  FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
-
-  def setup
-    @controller = MailHandlerController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_should_create_issue
-    # Enable API and set a key
-    Setting.mail_handler_api_enabled = 1
-    Setting.mail_handler_api_key = 'secret'
-
-    post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
-    assert_response 201
-  end
-
-  def test_should_not_allow
-    # Disable API
-    Setting.mail_handler_api_enabled = 0
-    Setting.mail_handler_api_key = 'secret'
-
-    post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
-    assert_response 403
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4a/4af7d6561304237ee0f7ba68af0460300a5a3233.svn-base
--- /dev/null
+++ b/.svn/pristine/4a/4af7d6561304237ee0f7ba68af0460300a5a3233.svn-base
@@ -0,0 +1,1089 @@
+ar:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: rtl
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%m/%d/%Y"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [Ø§Ù„Ø§Ø­Ø¯, Ø§Ù„Ø§Ø«Ù†ÙŠÙ†, Ø§Ù„Ø«Ù„Ø§Ø«Ø§Ø¡, Ø§Ù„Ø§Ø±Ø¨Ø¹Ø§Ø¡, Ø§Ù„Ø®Ù…ÙŠØ³, Ø§Ù„Ø¬Ù…Ø¹Ø©, Ø§Ù„Ø³Ø¨Øª]
+    abbr_day_names: [Ø£Ø­, Ø§Ø«, Ø«, Ø§Ø±, Ø®, Ø¬, Ø³]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ, Ø´Ø¨Ø§Ø·, Ø¢Ø°Ø§Ø±, Ù†ÙŠØ³Ø§Ù†, Ø£ÙŠØ§Ø±, Ø­Ø²ÙŠØ±Ø§Ù†, ØªÙ…ÙˆØ², Ø¢Ø¨, Ø£ÙŠÙ„ÙˆÙ„, ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø£ÙˆÙ„, ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ, ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø£ÙˆÙ„]
+    abbr_month_names: [~, ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ, Ø´Ø¨Ø§Ø·, Ø¢Ø°Ø§Ø±, Ù†ÙŠØ³Ø§Ù†, Ø£ÙŠØ§Ø±, Ø­Ø²ÙŠØ±Ø§Ù†, ØªÙ…ÙˆØ², Ø¢Ø¨, Ø£ÙŠÙ„ÙˆÙ„, ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø£ÙˆÙ„, ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ, ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø£ÙˆÙ„]
+    # Used in date_select and datime_select.
+    order:
+      - :Ø§Ù„Ø³Ù†Ø©
+      - :Ø§Ù„Ø´Ù‡Ø±
+      - :Ø§Ù„ÙŠÙˆÙ…
+
+  time:
+    formats:
+      default: "%m/%d/%Y %I:%M %p"
+      time: "%I:%M %p"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "ØµØ¨Ø§Ø­Ø§"
+    pm: "Ù…Ø³Ø§Ø¡Ø§"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "Ù†ØµÙ Ø¯Ù‚ÙŠÙ‚Ø©"
+      less_than_x_seconds:
+        one:   "Ø£Ù‚Ù„ Ù…Ù† Ø«Ø§Ù†ÙŠØ©"
+        other: "Ø«ÙˆØ§Ù†ÙŠ %{count}Ø£Ù‚Ù„ Ù…Ù† "
+      x_seconds:
+        one:   "Ø«Ø§Ù†ÙŠØ©"
+        other: "%{count}Ø«ÙˆØ§Ù†ÙŠ "
+      less_than_x_minutes:
+        one:   "Ø£Ù‚Ù„ Ù…Ù† Ø¯Ù‚ÙŠÙ‚Ø©"
+        other: "Ø¯Ù‚Ø§Ø¦Ù‚%{count}Ø£Ù‚Ù„ Ù…Ù† "
+      x_minutes:
+        one:   "Ø¯Ù‚ÙŠÙ‚Ø©"
+        other: "%{count} Ø¯Ù‚Ø§Ø¦Ù‚"
+      about_x_hours:
+        one:   "Ø­ÙˆØ§Ù„ÙŠ Ø³Ø§Ø¹Ø©"
+        other: "Ø³Ø§Ø¹Ø§Øª %{count}Ø­ÙˆØ§Ù„ÙŠ "
+      x_hours:
+        one:   "%{count} Ø³Ø§Ø¹Ø©"
+        other: "%{count} Ø³Ø§Ø¹Ø§Øª"
+      x_days:
+        one:   "ÙŠÙˆÙ…"
+        other: "%{count} Ø£ÙŠØ§Ù…"
+      about_x_months:
+        one:   "Ø­ÙˆØ§Ù„ÙŠ Ø´Ù‡Ø±"
+        other: "Ø£Ø´Ù‡Ø±  %{count} Ø­ÙˆØ§Ù„ÙŠ"
+      x_months:
+        one:   "Ø´Ù‡Ø±"
+        other: "%{count} Ø£Ø´Ù‡Ø±"
+      about_x_years:
+        one:   "Ø­ÙˆØ§Ù„ÙŠ Ø³Ù†Ø©"
+        other: "Ø³Ù†ÙˆØ§Øª  %{count}Ø­ÙˆØ§Ù„ÙŠ "
+      over_x_years:
+        one:   "Ø§ÙƒØ«Ø± Ù…Ù† Ø³Ù†Ø©"
+        other: "Ø³Ù†ÙˆØ§Øª  %{count}Ø£ÙƒØ«Ø± Ù…Ù† "
+      almost_x_years:
+        one:   "ØªÙ‚Ø±ÙŠØ¨Ø§ Ø³Ù†Ø©"
+        other: "Ø³Ù†ÙˆØ§Øª %{count} Ù†Ù‚Ø±ÙŠØ¨Ø§"
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "Ùˆ"
+      skip_last_comma: Ø®Ø·Ø£
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    " %{model} Ø®Ø·Ø£ ÙŠÙ…Ù†Ø¹ ØªØ®Ø²ÙŠÙ†"
+          other:  " %{model} ÙŠÙ…Ù†Ø¹ ØªØ®Ø²ÙŠÙ†%{count}Ø®Ø·Ø£ Ø±Ù‚Ù…  "
+      messages:
+        inclusion: "ØºÙŠØ± Ù…Ø¯Ø±Ø¬Ø© Ø¹Ù„Ù‰ Ø§Ù„Ù‚Ø§Ø¦Ù…Ø©"
+        exclusion: "Ù…Ø­Ø¬ÙˆØ²"
+        invalid: "ØºÙŠØ± ØµØ§Ù„Ø­"
+        confirmation: "ØºÙŠØ± Ù…ØªØ·Ø§Ø¨Ù‚"
+        accepted: "Ù…Ù‚Ø¨ÙˆÙ„Ø©"
+        empty: "Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø§Ù† ØªÙƒÙˆÙ† ÙØ§Ø±ØºØ©"
+        blank: "Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø§Ù† ØªÙƒÙˆÙ† ÙØ§Ø±ØºØ©"
+        too_long: " %{count}Ø·ÙˆÙŠÙ„Ø© Ø¬Ø¯Ø§ØŒ Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù‡Ùˆ )"
+        too_short: " %{count}Ù‚ØµÙŠØ±Ø© Ø¬Ø¯Ø§ØŒ Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¯Ù†Ù‰ Ù‡Ùˆ)"
+        wrong_length: " %{count}Ø®Ø·Ø£ ÙÙŠ Ø§Ù„Ø·ÙˆÙ„ØŒ ÙŠØ¬Ø¨ Ø§Ù† ÙŠÙƒÙˆÙ† )"
+        taken: "Ù„Ù‚Ø¯ Ø§ØªØ®Ø°Øª Ø³Ø§Ø¨Ù‚Ø§"
+        not_a_number: "Ù„ÙŠØ³ Ø±Ù‚Ù…Ø§"
+        not_a_date: "Ù„ÙŠØ³ ØªØ§Ø±ÙŠØ®Ø§ ØµØ§Ù„Ø­Ø§"
+        greater_than: "%{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§ÙƒØ«Ø± Ù…Ù† "
+        greater_than_or_equal_to: "%{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§ÙƒØ«Ø± Ù…Ù† Ø§Ùˆ ØªØ³Ø§ÙˆÙŠ"
+        equal_to: "%{count}ÙŠØ¬Ø¨ Ø§Ù† ØªØ³Ø§ÙˆÙŠ"
+        less_than: " %{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§Ù‚Ù„ Ù…Ù†"
+        less_than_or_equal_to: " %{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§Ù‚Ù„ Ù…Ù† Ø§Ùˆ ØªØ³Ø§ÙˆÙŠ"
+        odd: "must be odd"
+        even: "must be even"
+        greater_than_start_date: "ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§ÙƒØ«Ø± Ù…Ù† ØªØ§Ø±ÙŠØ® Ø§Ù„Ø¨Ø¯Ø§ÙŠØ©"
+        not_same_project: "Ù„Ø§ ÙŠÙ†ØªÙ…ÙŠ Ø§Ù„Ù‰ Ù†ÙØ³ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹"
+        circular_dependency: "Ù‡Ø°Ù‡ Ø§Ù„Ø¹Ù„Ø§Ù‚Ø© Ø³ÙˆÙ ØªØ®Ù„Ù‚ Ø¹Ù„Ø§Ù‚Ø© ØªØ¨Ø¹ÙŠØ© Ø¯Ø§Ø¦Ø±ÙŠØ©"
+        cant_link_an_issue_with_a_descendant: "Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø§Ù† ØªÙƒÙˆÙ† Ø§Ù„Ù…Ø´ÙƒÙ„Ø© Ù…Ø±ØªØ¨Ø·Ø© Ø¨ÙˆØ§Ø­Ø¯Ø© Ù…Ù† Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ÙØ±Ø¹ÙŠØ©"
+
+  actionview_instancetag_blank_option: Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ø¯ÙŠØ¯
+
+  general_text_No: 'Ù„Ø§'
+  general_text_Yes: 'Ù†Ø¹Ù…'
+  general_text_no: 'Ù„Ø§'
+  general_text_yes: 'Ù†Ø¹Ù…'
+  general_lang_name: 'Arabic (Ø¹Ø±Ø¨ÙŠ)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_updated: Ù„Ù‚Ø¯ ØªÙ… ØªØ¬Ø¯ÙŠØ¯ Ø§Ù„Ø­Ø³Ø§Ø¨ Ø¨Ù†Ø¬Ø§Ø­.
+  notice_account_invalid_creditentials: Ø§Ø³Ù… Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… Ø§Ùˆ ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± ØºÙŠØ± ØµØ­ÙŠØ­Ø©
+  notice_account_password_updated: Ù„Ù‚Ø¯ ØªÙ… ØªØ¬Ø¯ÙŠØ¯ ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± Ø¨Ù†Ø¬Ø§Ø­.
+  notice_account_wrong_password: ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± ØºÙŠØ± ØµØ­ÙŠØ­Ø©
+  notice_account_register_done: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù†Ø´Ø§Ø¡ Ø­Ø³Ø§Ø¨Ùƒ Ø¨Ù†Ø¬Ø§Ø­ØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ ØªØ£ÙƒÙŠØ¯ Ø§Ù„Ø·Ù„Ø¨ Ù…Ù† Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  notice_account_unknown_email: Ù…Ø³ØªØ®Ø¯Ù… ØºÙŠØ± Ù…Ø¹Ø±ÙˆÙ.
+  notice_can_t_change_password: Ù‡Ø°Ø§ Ø§Ù„Ø­Ø³Ø§Ø¨ ÙŠØ³ØªØ®Ø¯Ù… Ø¬Ù‡Ø§Ø² Ø®Ø§Ø±Ø¬ÙŠ ØºÙŠØ± Ù…ØµØ±Ø­ Ø¨Ù‡ Ù„Ø§ ÙŠÙ…ÙƒÙ† ØªØºÙŠØ± ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
+  notice_account_lost_email_sent: Ù„Ù‚Ø¯ ØªÙ… Ø§Ø±Ø³Ø§Ù„ Ø±Ø³Ø§Ù„Ø© Ø¹Ù„Ù‰ Ø¨Ø±ÙŠØ¯Ùƒ Ø¨Ø§Ù„ØªØ¹Ù„ÙŠÙ…Ø§Øª Ø§Ù„Ù„Ø§Ø²Ù…Ø© Ù„ØªØºÙŠØ± ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
+  notice_account_activated: Ù„Ù‚Ø¯ ØªÙ… ØªÙØ¹ÙŠÙ„ Ø­Ø³Ø§Ø¨ÙƒØŒ ÙŠÙ…ÙƒÙ†Ùƒ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„Ø§Ù†
+  notice_successful_create: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù„Ø§Ù†Ø´Ø§Ø¡ Ø¨Ù†Ø¬Ø§Ø­
+  notice_successful_update: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù„ØªØ­Ø¯ÙŠØ« Ø¨Ù†Ø¬Ø§Ø­
+  notice_successful_delete: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù„Ø­Ø°Ù Ø¨Ù†Ø¬Ø§Ø­
+  notice_successful_connection: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù„Ø±Ø¨Ø· Ø¨Ù†Ø¬Ø§Ø­
+  notice_file_not_found: Ø§Ù„ØµÙØ­Ø© Ø§Ù„ØªÙŠ ØªØ­Ø§ÙˆÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„ÙŠÙ‡Ø§ ØºÙŠØ± Ù…ÙˆØ¬ÙˆØ¯Ù‡ Ø§Ùˆ ØªÙ… Ø­Ø°ÙÙ‡Ø§
+  notice_locking_conflict: ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ø¨ÙŠØ§Ù†Ø§Øª Ø¹Ù† Ø·Ø±ÙŠÙ‚ Ù…Ø³ØªØ®Ø¯Ù… Ø¢Ø®Ø±.
+  notice_not_authorized: ØºÙŠØ± Ù…ØµØ±Ø­ Ù„Ùƒ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„Ù‰ Ù‡Ø°Ù‡ Ø§Ù„Ù…Ù†Ø·Ù‚Ø©.
+  notice_not_authorized_archived_project: Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ Ø§Ù„Ø°ÙŠ ØªØ­Ø§ÙˆÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„ÙŠÙ‡ ØªÙ… Ø§Ø±Ø´ÙØªÙ‡
+  notice_email_sent: "%{value}ØªÙ… Ø§Ø±Ø³Ø§Ù„ Ø±Ø³Ø§Ù„Ø© Ø§Ù„Ù‰ "
+  notice_email_error: " (%{value})Ù„Ù‚Ø¯ Ø­Ø¯Ø« Ø®Ø·Ø£ Ù…Ø§ Ø§Ø«Ù†Ø§Ø¡ Ø§Ø±Ø³Ø§Ù„ Ø§Ù„Ø±Ø³Ø§Ù„Ø© Ø§Ù„Ù‰ "
+  notice_feeds_access_key_reseted: ÙƒÙ„Ù…Ø© Ø§Ù„Ø¯Ø®ÙˆÙ„  RSSÙ„Ù‚Ø¯ ØªÙ… ØªØ¹Ø¯ÙŠÙ„ .
+  notice_api_access_key_reseted:  ÙƒÙ„Ù…Ø© Ø§Ù„Ø¯Ø®ÙˆÙ„APIÙ„Ù‚Ø¯ ØªÙ… ØªØ¹Ø¯ÙŠÙ„ .
+  notice_failed_to_save_issues: "ÙØ´Ù„ ÙÙŠ Ø­ÙØ¸ Ø§Ù„Ù…Ù„Ù"
+  notice_failed_to_save_members: "ÙØ´Ù„ ÙÙŠ Ø­ÙØ¸ Ø§Ù„Ø§Ø¹Ø¶Ø§Ø¡: %{errors}."
+  notice_no_issue_selected: "Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ¯ Ø´ÙŠØ¡ØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ ØªØ­Ø¯ÙŠØ¯ Ø§Ù„Ù…Ø³Ø£Ù„Ø© Ø§Ù„ØªÙŠ ØªØ±ÙŠØ¯"
+  notice_account_pending: "Ù„Ù‚Ø¯ ØªÙ… Ø§Ù†Ø´Ø§Ø¡ Ø­Ø³Ø§Ø¨ÙƒØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„Ø§Ù†ØªØ¸Ø§Ø± Ø­ØªÙ‰ ØªØªÙ… Ø§Ù„Ù…ÙˆØ§ÙÙ‚Ø©"
+  notice_default_data_loaded: ØªÙ… ØªØ­Ù…ÙŠÙ„ Ø§Ù„ØªÙƒÙˆÙŠÙ† Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ Ø¨Ù†Ø¬Ø§Ø­
+  notice_unable_delete_version: ØºÙŠØ± Ù‚Ø§Ø¯Ø± Ø¹Ù„Ù‰ Ù…Ø³Ø­ Ø§Ù„Ù†Ø³Ø®Ø©.
+  notice_unable_delete_time_entry: ØºÙŠØ± Ù‚Ø§Ø¯Ø± Ø¹Ù„Ù‰ Ù…Ø³Ø­ ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„.
+  notice_issue_done_ratios_updated: Ù„Ù‚Ø¯ ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ù†Ø³Ø¨.
+  notice_gantt_chart_truncated: " (%{max})Ù„Ù‚Ø¯ ØªÙ… Ø§Ù‚ØªØ·Ø§Ø¹ Ø§Ù„Ø±Ø³Ù… Ø§Ù„Ø¨ÙŠØ§Ù†ÙŠ Ù„Ø§Ù†Ù‡ ØªØ¬Ø§ÙˆØ² Ø§Ù„Ø§Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„Ø¹Ù†Ø§ØµØ± Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¹Ø±Ø¶Ù‡Ø§ "
+  notice_issue_successful_create: "%{id}Ù„Ù‚Ø¯ ØªÙ… Ø§Ù†Ø´Ø§Ø¡ "
+
+
+  error_can_t_load_default_data: "Ù„Ù… ÙŠØªÙ… ØªØ­Ù…ÙŠÙ„ Ø§Ù„ØªÙƒÙˆÙŠÙ† Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ ÙƒØ§Ù…Ù„Ø§ %{value}"
+  error_scm_not_found: "Ù„Ù… ÙŠØªÙ… Ø§Ù„Ø¹Ø«ÙˆØ± Ø¹Ù„Ù‰ Ø§Ø¯Ø®Ø§Ù„ ÙÙŠ Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹"
+  error_scm_command_failed: "Ø­Ø¯Ø« Ø®Ø·Ø£ Ø¹Ù†Ø¯ Ù…Ø­Ø§ÙˆÙ„Ø© Ø§Ù„ÙˆØµÙˆÙ„ Ø§Ù„Ù‰ Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹: %{value}"
+  error_scm_annotate: "Ø§Ù„Ø§Ø¯Ø®Ø§Ù„ ØºÙŠØ± Ù…ÙˆØ¬ÙˆØ¯."
+  error_scm_annotate_big_text_file: "Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø­ÙØ¸ Ø§Ù„Ø§Ø¯Ø®Ø§Ù„ Ù„Ø§Ù†Ù‡ ØªØ¬Ø§ÙˆØ² Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø­Ø¬Ù… Ø§Ù„Ù…Ù„Ù."
+  error_issue_not_found_in_project: 'Ù„Ù… ÙŠØªÙ… Ø§Ù„Ø¹Ø«ÙˆØ± Ø¹Ù„Ù‰ Ø§Ù„Ù…Ø®Ø±Ø¬ Ø§Ùˆ Ø§Ù†Ù‡ ÙŠÙ†ØªÙ…ÙŠ Ø§Ù„Ù‰ Ù…Ø´Ø±ÙˆØ¹ Ø§Ø®Ø±'
+  error_no_tracker_in_project: 'Ù„Ø§ ÙŠÙˆØ¬Ø¯ Ù…ØªØªØ¨Ø¹ Ù„Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ù‚Ù‚ Ù…Ù† Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„Ù…Ø´Ø±ÙˆØ¹. '
+  error_no_default_issue_status: 'Ù„Ù… ÙŠØªÙ… Ø§Ù„ØªØ¹Ø±Ù Ø¹Ù„Ù‰ Ø§ÙŠ ÙˆØ¶Ø¹ Ø§ÙØªØ±Ø§Ø¶ÙŠØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ù‚Ù‚ Ù…Ù† Ø§Ù„ØªÙƒÙˆÙŠÙ† Ø§Ù„Ø®Ø§Øµ Ø¨Ùƒ (Ø§Ø°Ù‡Ø¨ Ø§Ù„Ù‰ Ø¥Ø¯Ø§Ø±Ø©-Ø¥ØµØ¯Ø§Ø± Ø§Ù„Ø­Ø§Ù„Ø§Øª)'
+  error_can_not_delete_custom_field: ØºÙŠØ± Ù‚Ø§Ø¯Ø± Ø¹Ù„Ù‰ Ø­Ø°Ù Ø§Ù„Ø­Ù‚Ù„ Ø§Ù„Ù…Ø¸Ù„Ù„
+  error_can_not_delete_tracker: "Ù‡Ø°Ø§ Ø§Ù„Ù…ØªØªØ¨Ø¹ ÙŠØ­ØªÙˆÙŠ Ø¹Ù„Ù‰ Ù…Ø³Ø§Ø¦Ù„ Ù†Ø´Ø·Ø© ÙˆÙ„Ø§ ÙŠÙ…ÙƒÙ† Ø­Ø°ÙÙ‡"
+  error_can_not_remove_role: "Ù‡Ø°Ø§ Ø§Ù„Ø¯ÙˆØ± Ù‚ÙŠØ¯ Ø§Ù„Ø§Ø³ØªØ®Ø¯Ø§Ù…ØŒ Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø­Ø°ÙÙ‡"
+  error_can_not_reopen_issue_on_closed_version: 'Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø¥Ø¹Ø§Ø¯Ø© ÙØªØ­ Ù‚Ø¶ÙŠØ© Ù…Ø¹ÙŠÙ†Ù‡ Ù„Ø§ØµØ¯Ø§Ø± Ù…Ù‚ÙÙ„'
+  error_can_not_archive_project: Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø§Ø±Ø´ÙØ© Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  error_issue_done_ratios_not_updated: "Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ù†Ø³Ø¨"
+  error_workflow_copy_source: 'Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ø®ØªÙŠØ§Ø± Ø§Ù„Ù…ØªØªØ¨Ø¹ Ø§Ùˆ Ø§Ù„Ø§Ø¯ÙˆØ§Ø±'
+  error_workflow_copy_target: 'Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ø®ØªÙŠØ§Ø± Ù‡Ø¯Ù Ø§Ù„Ù…ØªØªØ¨Ø¹ Ø§Ùˆ Ù‡Ø¯Ù Ø§Ù„Ø§Ø¯ÙˆØ§Ø±'
+  error_unable_delete_issue_status: 'ØºÙŠØ± Ù‚Ø§Ø¯Ø± Ø¹Ù„Ù‰ Ø­Ø°Ù Ø­Ø§Ù„Ø© Ø§Ù„Ù‚Ø¶ÙŠØ©'
+  error_unable_to_connect: "ØªØ¹Ø°Ø± Ø§Ù„Ø§ØªØµØ§Ù„(%{value})"
+  error_attachment_too_big: " (%{max_size})Ù„Ø§ ÙŠÙ…ÙƒÙ† ØªØ­Ù…ÙŠÙ„ Ù‡Ø°Ø§ Ø§Ù„Ù…Ù„ÙØŒ Ù„Ù‚Ø¯ ØªØ¬Ø§ÙˆØ² Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¨Ù‡ "
+  warning_attachments_not_saved: "%{count}ØªØ¹Ø°Ø± Ø­ÙØ¸ Ø§Ù„Ù…Ù„Ù"
+
+  mail_subject_lost_password: " %{value}ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± Ø§Ù„Ø®Ø§ØµØ© Ø¨Ùƒ "
+  mail_body_lost_password: 'Ù„ØªØºÙŠØ± ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±ØŒ Ø§Ù†Ù‚Ø± Ø¹Ù„Ù‰ Ø§Ù„Ø±ÙˆØ§Ø¨Ø· Ø§Ù„ØªØ§Ù„ÙŠØ©:'
+  mail_subject_register: " %{value}ØªÙØ¹ÙŠÙ„ Ø­Ø³Ø§Ø¨Ùƒ "
+  mail_body_register: 'Ù„ØªÙØ¹ÙŠÙ„ Ø­Ø³Ø§Ø¨ÙƒØŒ Ø§Ù†Ù‚Ø± Ø¹Ù„Ù‰ Ø§Ù„Ø±ÙˆØ§Ø¨Ø· Ø§Ù„ØªØ§Ù„ÙŠØ©:'
+  mail_body_account_information_external: " %{value}Ø§ØµØ¨Ø­ Ø¨Ø§Ù…ÙƒØ§Ù†Ùƒ Ø§Ø³ØªØ®Ø¯Ø§Ù… Ø­Ø³Ø§Ø¨Ùƒ Ù„Ù„Ø¯Ø®ÙˆÙ„"
+  mail_body_account_information: Ù…Ø¹Ù„ÙˆÙ…Ø§Øª Ø­Ø³Ø§Ø¨Ùƒ
+  mail_subject_account_activation_request: "%{value}Ø·Ù„Ø¨ ØªÙØ¹ÙŠÙ„ Ø§Ù„Ø­Ø³Ø§Ø¨ "
+  mail_body_account_activation_request: " (%{value})ØªÙ… ØªØ³Ø¬ÙŠÙ„ Ø­Ø³Ø§Ø¨ Ø¬Ø¯ÙŠØ¯ØŒ Ø¨Ø§Ù†ØªØ¸Ø§Ø± Ø§Ù„Ù…ÙˆØ§ÙÙ‚Ø©:"
+  mail_subject_reminder: "%{count}ØªÙ… ØªØ£Ø¬ÙŠÙ„ Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ØªØ§Ù„ÙŠØ©  "
+  mail_body_reminder: "%{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙ‚ÙˆÙ… Ø¨ØªØ³Ù„ÙŠÙ… Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ØªØ§Ù„ÙŠØ© :"
+  mail_subject_wiki_content_added: "'%{id}' ØªÙ… Ø§Ø¶Ø§ÙØ© ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ"
+  mail_body_wiki_content_added: "The '%{id}' ØªÙ… Ø§Ø¶Ø§ÙØ© ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ Ù…Ù† Ù‚Ø¨Ù„ %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' ØªÙ… ØªØ­Ø¯ÙŠØ« ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ"
+  mail_body_wiki_content_updated: "The '%{id}'ØªÙ… ØªØ­Ø¯ÙŠØ« ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ Ù…Ù† Ù‚Ø¨Ù„ %{author}."
+
+
+  field_name: Ø§Ù„Ø§Ø³Ù…
+  field_description: Ø§Ù„ÙˆØµÙ
+  field_summary: Ø§Ù„Ù…Ù„Ø®Øµ
+  field_is_required: Ù…Ø·Ù„ÙˆØ¨
+  field_firstname: Ø§Ù„Ø§Ø³Ù… Ø§Ù„Ø§ÙˆÙ„
+  field_lastname: Ø§Ù„Ø§Ø³Ù… Ø§Ù„Ø§Ø®ÙŠØ±
+  field_mail: Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  field_filename: Ø§Ø³Ù… Ø§Ù„Ù…Ù„Ù
+  field_filesize: Ø­Ø¬Ù… Ø§Ù„Ù…Ù„Ù
+  field_downloads: Ø§Ù„ØªÙ†Ø²ÙŠÙ„
+  field_author: Ø§Ù„Ù…Ø¤Ù„Ù
+  field_created_on: ØªÙ… Ø§Ù„Ø§Ù†Ø´Ø§Ø¡ ÙÙŠ
+  field_updated_on: ØªÙ… Ø§Ù„ØªØ­Ø¯ÙŠØ«
+  field_field_format: ØªÙ†Ø³ÙŠÙ‚ Ø§Ù„Ø­Ù‚Ù„
+  field_is_for_all: Ù„ÙƒÙ„ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹Ø§Øª
+  field_possible_values: Ù‚ÙŠÙ… Ù…Ø­ØªÙ…Ù„Ø©
+  field_regexp: Ø§Ù„ØªØ¹Ø¨ÙŠØ± Ø§Ù„Ø¹Ø§Ø¯ÙŠ
+  field_min_length: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¯Ù†Ù‰ Ù„Ù„Ø·ÙˆÙ„
+  field_max_length: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¹Ù„Ù‰ Ù„Ù„Ø·ÙˆÙ„
+  field_value: Ø§Ù„Ù‚ÙŠÙ…Ø©
+  field_category: Ø§Ù„ÙØ¦Ø©
+  field_title: Ø§Ù„Ø¹Ù†ÙˆØ§Ù†
+  field_project: Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  field_issue: Ø§Ù„Ù‚Ø¶ÙŠØ©
+  field_status: Ø§Ù„Ø­Ø§Ù„Ø©
+  field_notes: Ù…Ù„Ø§Ø­Ø¸Ø§Øª
+  field_is_closed: Ø§Ù„Ù‚Ø¶ÙŠØ© Ù…ØºÙ„Ù‚Ø©
+  field_is_default: Ø§Ù„Ù‚ÙŠÙ…Ø© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
+  field_tracker: Ø§Ù„Ù…ØªØªØ¨Ø¹
+  field_subject: Ø§Ù„Ù…ÙˆØ¶ÙˆØ¹
+  field_due_date: ØªØ§Ø±ÙŠØ® Ø§Ù„Ø§Ø³ØªØ­Ù‚Ø§Ù‚
+  field_assigned_to: Ø§Ù„Ù…Ø­Ø§Ù„ Ø§Ù„ÙŠÙ‡
+  field_priority: Ø§Ù„Ø£ÙˆÙ„ÙˆÙŠØ©
+  field_fixed_version: Ø§Ù„Ø§ØµØ¯Ø§Ø± Ø§Ù„Ù…Ø³ØªÙ‡Ø¯Ù
+  field_user: Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
+  field_principal: Ø§Ù„Ø±Ø¦ÙŠØ³ÙŠ
+  field_role: Ø¯ÙˆØ±
+  field_homepage: Ø§Ù„ØµÙØ­Ø© Ø§Ù„Ø±Ø¦ÙŠØ³ÙŠØ©
+  field_is_public: Ø¹Ø§Ù…
+  field_parent: Ù…Ø´Ø±ÙˆØ¹ ÙØ±Ø¹ÙŠ Ù…Ù†
+  field_is_in_roadmap: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© ÙÙŠ Ø®Ø§Ø±Ø·Ø© Ø§Ù„Ø·Ø±ÙŠÙ‚
+  field_login: ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„
+  field_mail_notification: Ù…Ù„Ø§Ø­Ø¸Ø§Øª Ø¹Ù„Ù‰ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  field_admin: Ø§Ù„Ù…Ø¯ÙŠØ±
+  field_last_login_on: Ø§Ø®Ø± Ø§ØªØµØ§Ù„
+  field_language: Ù„ØºØ©
+  field_effective_date: ØªØ§Ø±ÙŠØ®
+  field_password: ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
+  field_new_password: ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± Ø§Ù„Ø¬Ø¯ÙŠØ¯Ø©
+  field_password_confirmation: ØªØ£ÙƒÙŠØ¯
+  field_version: Ø¥ØµØ¯Ø§Ø±
+  field_type: Ù†ÙˆØ¹
+  field_host: Ø§Ù„Ù…Ø¶ÙŠÙ
+  field_port: Ø§Ù„Ù…Ù†ÙØ°
+  field_account: Ø§Ù„Ø­Ø³Ø§Ø¨
+  field_base_dn: DN Ù‚Ø§Ø¹Ø¯Ø©
+  field_attr_login: Ø³Ù…Ø© Ø§Ù„Ø¯Ø®ÙˆÙ„
+  field_attr_firstname: Ø³Ù…Ø© Ø§Ù„Ø§Ø³Ù… Ø§Ù„Ø§ÙˆÙ„
+  field_attr_lastname: Ø³Ù…Ø© Ø§Ù„Ø§Ø³Ù… Ø§Ù„Ø§Ø®ÙŠØ±
+  field_attr_mail: Ø³Ù…Ø© Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  field_onthefly: Ø¥Ù†Ø´Ø§Ø¡ Ø­Ø³Ø§Ø¨ Ù…Ø³ØªØ®Ø¯Ù… Ø¹Ù„Ù‰ ØªØ­Ø±Ùƒ
+  field_start_date: ØªØ§Ø±ÙŠØ® Ø§Ù„Ø¨Ø¯ÙŠØ©
+  field_done_ratio: "% ØªÙ…"
+  field_auth_source: ÙˆØ¶Ø¹ Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
+  field_hide_mail: Ø¥Ø®ÙØ§Ø¡ Ø¨Ø±ÙŠØ¯ÙŠ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  field_comments: ØªØ¹Ù„ÙŠÙ‚
+  field_url: Ø±Ø§Ø¨Ø·
+  field_start_page: ØµÙØ­Ø© Ø§Ù„Ø¨Ø¯Ø§ÙŠØ©
+  field_subproject: Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ Ø§Ù„ÙØ±Ø¹ÙŠ
+  field_hours: Ø³Ø§Ø¹Ø§Øª
+  field_activity: Ø§Ù„Ù†Ø´Ø§Ø·
+  field_spent_on: ØªØ§Ø±ÙŠØ®
+  field_identifier: Ø§Ù„Ù…Ø¹Ø±Ù
+  field_is_filter: Ø§Ø³ØªØ®Ø¯Ù… ÙƒØªØµÙÙŠØ©
+  field_issue_to: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù…ØªØµÙ„Ø©
+  field_delay: ØªØ£Ø®ÙŠØ±
+  field_assignable: ÙŠÙ…ÙƒÙ† Ø§Ù† ØªØ³ØªÙ†Ø¯ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù‰ Ù‡Ø°Ø§ Ø§Ù„Ø¯ÙˆØ±
+  field_redirect_existing_links: Ø¥Ø¹Ø§Ø¯Ø© ØªÙˆØ¬ÙŠÙ‡ Ø§Ù„Ø±ÙˆØ§Ø¨Ø· Ø§Ù„Ù…ÙˆØ¬ÙˆØ¯Ø©
+  field_estimated_hours: Ø§Ù„ÙˆÙ‚Øª Ø§Ù„Ù…ØªÙˆÙ‚Ø¹
+  field_column_names: Ø£Ø¹Ù…Ø¯Ø©
+  field_time_entries: ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„
+  field_time_zone: Ø§Ù„Ù…Ù†Ø·Ù‚Ø© Ø§Ù„Ø²Ù…Ù†ÙŠØ©
+  field_searchable: ÙŠÙ…ÙƒÙ† Ø§Ù„Ø¨Ø­Ø« ÙÙŠÙ‡
+  field_default_value: Ø§Ù„Ù‚ÙŠÙ…Ø© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
+  field_comments_sorting: Ø§Ø¹Ø±Ø¶ Ø§Ù„ØªØ¹Ù„ÙŠÙ‚Ø§Øª
+  field_parent_title: ØµÙØ­Ø© Ø§Ù„ÙˆØ§Ù„Ø¯ÙŠÙ†
+  field_editable: ÙŠÙ…ÙƒÙ† Ø§Ø¹Ø§Ø¯Ø© ØªØ­Ø±ÙŠØ±Ù‡
+  field_watcher: Ù…Ø±Ø§Ù‚Ø¨
+  field_identity_url: Ø§ÙØªØ­ Ø§Ù„Ø±Ø§Ø¨Ø· Ø§Ù„Ø®Ø§Øµ Ø¨Ø§Ù„Ù‡ÙˆÙŠØ© Ø§Ù„Ø´Ø®ØµÙŠØ©
+  field_content: Ø§Ù„Ù…Ø­ØªÙˆÙŠØ§Øª
+  field_group_by: Ù…Ø¬Ù…ÙˆØ¹Ø© Ø§Ù„Ù†ØªØ§Ø¦Ø¬ Ø¹Ù† Ø·Ø±ÙŠÙ‚
+  field_sharing: Ù…Ø´Ø§Ø±ÙƒØ©
+  field_parent_issue: Ù…Ù‡Ù…Ø© Ø§Ù„ÙˆØ§Ù„Ø¯ÙŠÙ†
+  field_member_of_group: "Ù…Ø¬Ù…ÙˆØ¹Ø© Ø§Ù„Ù…Ø­Ø§Ù„"
+  field_assigned_to_role: "Ø¯ÙˆØ± Ø§Ù„Ù…Ø­Ø§Ù„"
+  field_text: Ø­Ù‚Ù„ Ù†ØµÙŠ
+  field_visible: ØºÙŠØ± Ù…Ø±Ø¦ÙŠ
+  field_warn_on_leaving_unsaved: "Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ø°ÙŠØ± Ø¹Ù†Ø¯ Ù…ØºØ§Ø¯Ø±Ø© ØµÙØ­Ø© ÙˆØ§Ù„Ù†Øµ ØºÙŠØ± Ù…Ø­ÙÙˆØ¸"
+  field_issues_visibility: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù…Ø±Ø¦ÙŠØ©
+  field_is_private: Ø®Ø§Øµ
+  field_commit_logs_encoding: Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„ØªØ±Ù…ÙŠØ²
+  field_scm_path_encoding: ØªØ±Ù…ÙŠØ² Ø§Ù„Ù…Ø³Ø§Ø±
+  field_path_to_repository: Ù…Ø³Ø§Ø± Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹
+  field_root_directory: Ø¯Ù„ÙŠÙ„ Ø§Ù„Ø¬Ø°Ø±
+  field_cvsroot: CVSØ¬Ø°Ø±
+  field_cvs_module: ÙˆØ­Ø¯Ø©
+
+  setting_app_title: Ø¹Ù†ÙˆØ§Ù† Ø§Ù„ØªØ·Ø¨ÙŠÙ‚
+  setting_app_subtitle: Ø§Ù„Ø¹Ù†ÙˆØ§Ù† Ø§Ù„ÙØ±Ø¹ÙŠ Ù„Ù„ØªØ·Ø¨ÙŠÙ‚
+  setting_welcome_text: Ù†Øµ Ø§Ù„ØªØ±Ø­ÙŠØ¨
+  setting_default_language: Ø§Ù„Ù„ØºØ© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
+  setting_login_required: Ù…Ø·Ù„ÙˆØ¨ Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
+  setting_self_registration: Ø§Ù„ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø°Ø§ØªÙŠ
+  setting_attachment_max_size: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ù„Ù…Ù„ÙØ§Øª Ø§Ù„Ù…Ø±ÙÙ‚Ø©
+  setting_issues_export_limit: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„ØªØµØ¯ÙŠØ±
+  setting_mail_from: Ø§Ù†Ø¨Ø¹Ø§Ø«Ø§Øª Ø¹Ù†ÙˆØ§Ù† Ø¨Ø±ÙŠØ¯Ùƒ
+  setting_bcc_recipients: Ù…Ø³ØªÙ„Ù…ÙŠÙ† Ø§Ù„Ù†Ø³Ø® Ø§Ù„Ù…Ø®ÙÙŠØ© (bcc)
+  setting_plain_text_mail: Ù†Øµ Ø¹Ø§Ø¯ÙŠ (no HTML)
+  setting_host_name: Ø§Ø³Ù… ÙˆÙ…Ø³Ø§Ø± Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
+  setting_text_formatting: ØªÙ†Ø³ÙŠÙ‚ Ø§Ù„Ù†Øµ
+  setting_wiki_compression: Ø¶ØºØ· ØªØ§Ø±ÙŠØ® Ø§Ù„ÙˆÙŠÙƒÙŠ
+  setting_feeds_limit: Atom feeds Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„Ø¨Ù†ÙˆØ¯ ÙÙŠ
+  setting_default_projects_public: Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„Ø¬Ø¯ÙŠØ¯Ù‡ Ù…ØªØ§Ø­Ø© Ù„Ù„Ø¬Ù…ÙŠØ¹ Ø§ÙØªØ±Ø§Ø¶ÙŠØ§
+  setting_autofetch_changesets: Ø§Ù„Ø¥Ø­Ø¶Ø§Ø± Ø§Ù„ØªÙ„Ù‚Ø§Ø¦ÙŠ
+  setting_sys_api_enabled: Ù…Ù† Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹ WS ØªÙ…ÙƒÙŠÙ†
+  setting_commit_ref_keywords: Ù…Ø±Ø¬Ø¹ÙŠØ© Ø§Ù„ÙƒÙ„Ù…Ø§Øª Ø§Ù„Ù…ÙØªØ§Ø­ÙŠØ©
+  setting_commit_fix_keywords: ØªØµØ­ÙŠØ­ Ø§Ù„ÙƒÙ„Ù…Ø§Øª Ø§Ù„Ù…ÙØªØ§Ø­ÙŠØ©
+  setting_autologin: Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„ØªÙ„Ù‚Ø§Ø¦ÙŠ
+  setting_date_format: ØªÙ†Ø³ÙŠÙ‚ Ø§Ù„ØªØ§Ø±ÙŠØ®
+  setting_time_format: ØªÙ†Ø³ÙŠÙ‚ Ø§Ù„ÙˆÙ‚Øª
+  setting_cross_project_issue_relations: Ø§Ù„Ø³Ù…Ø§Ø­ Ø¨Ø§Ø¯Ø§Ø±Ø¬ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ ÙÙŠ Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  setting_issue_list_default_columns: Ø§Ù„Ø§Ø¹Ù…Ø¯Ø© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ© Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© ÙÙŠ Ù‚Ø§Ø¦Ù…Ø© Ø§Ù„Ù‚Ø¶ÙŠØ©
+  setting_repositories_encodings: ØªØ±Ù…ÙŠØ² Ø§Ù„Ù…Ø±ÙÙ‚Ø§Øª ÙˆØ§Ù„Ù…Ø³ØªÙˆØ¯Ø¹Ø§Øª
+  setting_emails_header: Ø±Ø£Ø³ Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  setting_emails_footer: Ø°ÙŠÙ„ Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  setting_protocol: Ø¨Ø±ÙˆØªÙˆÙƒÙˆÙ„
+  setting_per_page_options: Ø§Ù„ÙƒØ§Ø¦Ù†Ø§Øª Ù„ÙƒÙ„ Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„ØµÙØ­Ø©
+  setting_user_format: ØªÙ†Ø³ÙŠÙ‚ Ø¹Ø±Ø¶ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
+  setting_activity_days_default: Ø§Ù„Ø§ÙŠØ§Ù… Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© Ø¹Ù„Ù‰ Ù†Ø´Ø§Ø· Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  setting_display_subprojects_issues: Ø¹Ø±Ø¶ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„ÙØ±Ø¹ÙŠØ© Ù„Ù„Ù…Ø´Ø§Ø±Ø¹ Ø§Ù„Ø±Ø¦ÙŠØ³ÙŠØ© Ø¨Ø´ÙƒÙ„ Ø§ÙØªØ±Ø§Ø¶ÙŠ
+  setting_enabled_scm: SCM ØªÙ…ÙƒÙŠÙ†
+  setting_mail_handler_body_delimiters: "Ø§Ù‚ØªØ·Ø§Ø¹ Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ Ø¨Ø¹Ø¯ Ù‡Ø°Ù‡ Ø§Ù„Ø®Ø·ÙˆØ·"
+  setting_mail_handler_api_enabled: Ù„Ù„Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„ÙˆØ§Ø±Ø¯Ø©WS ØªÙ…ÙƒÙŠÙ†
+  setting_mail_handler_api_key: API Ù…ÙØªØ§Ø­
+  setting_sequential_project_identifiers: Ø§Ù†Ø´Ø§Ø¡ Ù…Ø¹Ø±ÙØ§Øª Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ Ø§Ù„Ù…ØªØ³Ù„Ø³Ù„Ø©
+  setting_gravatar_enabled: ÙƒØ£ÙŠÙ‚ÙˆÙ†Ø© Ù…Ø³ØªØ®Ø¯Ù…Gravatar Ø§Ø³ØªØ®Ø¯Ø§Ù…
+  setting_gravatar_default: Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©Gravatar ØµÙˆØ±Ø©
+  setting_diff_max_lines_displayed: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„Ø®Ø·ÙˆØ·
+  setting_file_max_size_displayed: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø£Ù‚ØµÙ‰ Ù„Ø­Ø¬Ù… Ø§Ù„Ù†Øµ Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶ Ø¹Ù„Ù‰ Ø§Ù„Ù…Ù„ÙØ§Øª Ø§Ù„Ù…Ø±ÙÙ‚Ø©
+  setting_repository_log_display_limit: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„ØªÙ†Ù‚ÙŠØ­Ø§Øª Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© Ø¹Ù„Ù‰ Ù…Ù„Ù Ø§Ù„Ø³Ø¬Ù„
+  setting_openid: Ø§Ù„Ø³Ù…Ø§Ø­ Ø¨Ø¯Ø®ÙˆÙ„ Ø§Ø³Ù… Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… Ø§Ù„Ù…ÙØªÙˆØ­ ÙˆØ§Ù„ØªØ³Ø¬ÙŠÙ„
+  setting_password_min_length: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¯Ù†ÙŠ Ù„Ø·ÙˆÙ„ ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
+  setting_new_project_user_role_id: Ø§Ù„Ø¯ÙˆØ± Ø§Ù„Ù…Ø³Ù†Ø¯ Ø§Ù„Ù‰ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… ØºÙŠØ± Ø§Ù„Ù…Ø³Ø¤ÙˆÙ„ Ø§Ù„Ø°ÙŠ ÙŠÙ‚ÙˆÙ… Ø¨Ø¥Ù†Ø´Ø§Ø¡ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  setting_default_projects_modules: ØªÙ…ÙƒÙŠÙ† Ø§Ù„ÙˆØ­Ø¯Ø§Øª Ø§Ù„Ù†Ù…Ø·ÙŠØ© Ù„Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„Ø¬Ø¯ÙŠØ¯Ø© Ø¨Ø´ÙƒÙ„ Ø§ÙØªØ±Ø§Ø¶ÙŠ
+  setting_issue_done_ratio: Ø­Ø³Ø§Ø¨ Ù†Ø³Ø¨Ø© Ø§Ù„Ù‚Ø¶ÙŠØ© Ø§Ù„Ù…Ù†ØªÙ‡ÙŠØ©
+  setting_issue_done_ratio_issue_field: Ø§Ø³ØªØ®Ø¯Ù… Ø­Ù‚Ù„ Ø§Ù„Ù‚Ø¶ÙŠØ©
+  setting_issue_done_ratio_issue_status: Ø§Ø³ØªØ®Ø¯Ù… ÙˆØ¶Ø¹ Ø§Ù„Ù‚Ø¶ÙŠØ©
+  setting_start_of_week: Ø¨Ø¯Ø£ Ø§Ù„ØªÙ‚ÙˆÙŠÙ…
+  setting_rest_api_enabled: ØªÙ…ÙƒÙŠÙ† Ø¨Ø§Ù‚ÙŠ Ø®Ø¯Ù…Ø§Øª Ø§Ù„ÙˆÙŠØ¨
+  setting_cache_formatted_text: Ø§Ù„Ù†Øµ Ø§Ù„Ù…Ø³Ø¨Ù‚ ØªÙ†Ø³ÙŠÙ‚Ù‡ ÙÙŠ Ø°Ø§ÙƒØ±Ø© Ø§Ù„ØªØ®Ø²ÙŠÙ† Ø§Ù„Ù…Ø¤Ù‚Øª
+  setting_default_notification_option: Ø®ÙŠØ§Ø± Ø§Ù„Ø§Ø¹Ù„Ø§Ù… Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ
+  setting_commit_logtime_enabled: ØªÙ…ÙŠÙƒÙ† ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„
+  setting_commit_logtime_activity_id: Ø§Ù„Ù†Ø´Ø§Ø· ÙÙŠ ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„
+  setting_gantt_items_limit: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„Ø¹Ù†Ø§ØµØ± Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© Ø¹Ù„Ù‰ Ø§Ù„Ù…Ø®Ø·Ø·
+  setting_issue_group_assignment: Ø§Ù„Ø³Ù…Ø§Ø­ Ù„Ù„Ø¥Ø­Ø§Ù„Ø© Ø§Ù„Ù‰ Ø§Ù„Ù…Ø¬Ù…ÙˆØ¹Ø§Øª
+  setting_default_issue_start_date_to_creation_date: Ø§Ø³ØªØ®Ø¯Ø§Ù… Ø§Ù„ØªØ§Ø±ÙŠØ® Ø§Ù„Ø­Ø§Ù„ÙŠ ÙƒØªØ§Ø±ÙŠØ® Ø¨Ø¯Ø£ Ù„Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ø¬Ø¯ÙŠØ¯Ø©
+
+  permission_add_project: Ø¥Ù†Ø´Ø§Ø¡ Ù…Ø´Ø±ÙˆØ¹
+  permission_add_subprojects: Ø¥Ù†Ø´Ø§Ø¡ Ù…Ø´Ø§Ø±ÙŠØ¹ ÙØ±Ø¹ÙŠØ©
+  permission_edit_project: ØªØ¹Ø¯ÙŠÙ„ Ù…Ø´Ø±ÙˆØ¹
+  permission_select_project_modules: ØªØ­Ø¯ÙŠØ¯ Ø´ÙƒÙ„ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  permission_manage_members: Ø¥Ø¯Ø§Ø±Ø© Ø§Ù„Ø§Ø¹Ø¶Ø§Ø¡
+  permission_manage_project_activities: Ø§Ø¯Ø§Ø±Ø© Ø§ØµØ¯Ø§Ø±Ø§Øª Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  permission_manage_versions: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ø§ØµØ¯Ø§Ø±Ø§Øª
+  permission_manage_categories: Ø§Ø¯Ø§Ø±Ø© Ø§Ù†ÙˆØ§Ø¹ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  permission_view_issues: Ø¹Ø±Ø¶ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  permission_add_issues: Ø§Ø¶Ø§ÙØ© Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  permission_edit_issues: ØªØ¹Ø¯ÙŠÙ„ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  permission_manage_issue_relations: Ø§Ø¯Ø§Ø±Ø© Ø¹Ù„Ø§Ù‚Ø§Øª Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  permission_set_issues_private: ØªØ¹ÙŠÙ† Ù‚Ø¶Ø§ÙŠØ§ Ø¹Ø§Ù…Ø© Ø§Ùˆ Ø®Ø§ØµØ©
+  permission_set_own_issues_private: ØªØ¹ÙŠÙ† Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ø®Ø§ØµØ© Ø¨Ùƒ ÙƒÙ‚Ø¶Ø§ÙŠØ§ Ø¹Ø§Ù…Ø© Ø§Ùˆ Ø®Ø§ØµØ©
+  permission_add_issue_notes: Ø§Ø¶Ø§ÙØ© Ù…Ù„Ø§Ø­Ø¸Ø§Øª
+  permission_edit_issue_notes: ØªØ¹Ø¯ÙŠÙ„ Ù…Ù„Ø§Ø­Ø¸Ø§Øª
+  permission_edit_own_issue_notes: ØªØ¹Ø¯ÙŠÙ„ Ù…Ù„Ø§Ø­Ø¸Ø§ØªÙƒ
+  permission_move_issues: ØªØ­Ø±ÙŠÙƒ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  permission_delete_issues: Ø­Ø°Ù Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  permission_manage_public_queries: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ø§Ø³ØªØ¹Ù„Ø§Ù…Ø§Øª Ø§Ù„Ø¹Ø§Ù…Ø©
+  permission_save_queries: Ø­ÙØ¸ Ø§Ù„Ø§Ø³ØªØ¹Ù„Ø§Ù…Ø§Øª
+  permission_view_gantt: Ø¹Ø±Ø¶ Ø·Ø±ÙŠÙ‚Ø©"Ø¬Ø§Ù†Øª"
+  permission_view_calendar: Ø¹Ø±Ø¶ Ø§Ù„ØªÙ‚ÙˆÙŠÙ…
+  permission_view_issue_watchers: Ø¹Ø±Ø¶ Ù‚Ø§Ø¦Ù…Ø© Ø§Ù„Ù…Ø±Ø§Ù‚Ø¨ÙŠÙ†
+  permission_add_issue_watchers: Ø§Ø¶Ø§ÙØ© Ù…Ø±Ø§Ù‚Ø¨ÙŠÙ†
+  permission_delete_issue_watchers: Ø­Ø°Ù Ù…Ø±Ø§Ù‚Ø¨ÙŠÙ†
+  permission_log_time: Ø§Ù„ÙˆÙ‚Øª Ø§Ù„Ù…Ø³ØªØºØ±Ù‚ Ø¨Ø§Ù„Ø¯Ø®ÙˆÙ„
+  permission_view_time_entries: Ø¹Ø±Ø¶ Ø§Ù„ÙˆÙ‚Øª Ø§Ù„Ù…Ø³ØªØºØ±Ù‚
+  permission_edit_time_entries: ØªØ¹Ø¯ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„Ø§Øª Ø§Ù„Ø²Ù…Ù†ÙŠØ©
+  permission_edit_own_time_entries: ØªØ¹Ø¯ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„Ø§Øª Ø§Ù„Ø´Ø®ØµÙŠØ©
+  permission_manage_news: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ø§Ø®Ø¨Ø§Ø±
+  permission_comment_news: Ø§Ø®Ø¨Ø§Ø± Ø§Ù„ØªØ¹Ù„ÙŠÙ‚Ø§Øª
+  permission_view_documents: Ø¹Ø±Ø¶ Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª
+  permission_manage_files: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ù„ÙØ§Øª
+  permission_view_files: Ø¹Ø±Ø¶ Ø§Ù„Ù…Ù„ÙØ§Øª
+  permission_manage_wiki: Ø§Ø¯Ø§Ø±Ø© ÙˆÙŠÙƒÙŠ
+  permission_rename_wiki_pages: Ø§Ø¹Ø§Ø¯Ø© ØªØ³Ù…ÙŠØ© ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
+  permission_delete_wiki_pages: Ø­Ø°Ù‚ ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
+  permission_view_wiki_pages: Ø¹Ø±Ø¶ ÙˆÙŠÙƒÙŠ
+  permission_view_wiki_edits: Ø¹Ø±Ø¶ ØªØ§Ø±ÙŠØ® ÙˆÙŠÙƒÙŠ
+  permission_edit_wiki_pages: ØªØ¹Ø¯ÙŠÙ„ ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
+  permission_delete_wiki_pages_attachments: Ø­Ø°Ù Ø§Ù„Ù…Ø±ÙÙ‚Ø§Øª
+  permission_protect_wiki_pages: Ø­Ù…Ø§ÙŠØ© ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
+  permission_manage_repository: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹Ø§Øª
+  permission_browse_repository: Ø§Ø³ØªØ¹Ø±Ø§Ø¶ Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹Ø§Øª
+  permission_view_changesets: Ø¹Ø±Ø¶ Ø·Ø§Ù‚Ù… Ø§Ù„ØªØºÙŠÙŠØ±
+  permission_commit_access: Ø§Ù„ÙˆØµÙˆÙ„
+  permission_manage_boards: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ù†ØªØ¯ÙŠØ§Øª
+  permission_view_messages: Ø¹Ø±Ø¶ Ø§Ù„Ø±Ø³Ø§Ø¦Ù„
+  permission_add_messages: Ù†Ø´Ø± Ø§Ù„Ø±Ø³Ø§Ø¦Ù„
+  permission_edit_messages: ØªØ­Ø±ÙŠØ± Ø§Ù„Ø±Ø³Ø§Ø¦Ù„
+  permission_edit_own_messages: ØªØ­Ø±ÙŠØ± Ø§Ù„Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø®Ø§ØµØ©
+  permission_delete_messages: Ø­Ø°Ù Ø§Ù„Ø±Ø³Ø§Ø¦Ù„
+  permission_delete_own_messages: Ø­Ø°Ù Ø§Ù„Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø®Ø§ØµØ©
+  permission_export_wiki_pages: ØªØµØ¯ÙŠØ± ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
+  permission_manage_subtasks: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ÙØ±Ø¹ÙŠØ©
+
+  project_module_issue_tracking: ØªØ¹Ù‚Ø¨ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  project_module_time_tracking: Ø§Ù„ØªØ¹Ù‚Ø¨ Ø§Ù„Ø²Ù…Ù†ÙŠ
+  project_module_news: Ø§Ù„Ø§Ø®Ø¨Ø§Ø±
+  project_module_documents: Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª
+  project_module_files: Ø§Ù„Ù…Ù„ÙØ§Øª
+  project_module_wiki: ÙˆÙŠÙƒÙŠ
+  project_module_repository: Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹
+  project_module_boards: Ø§Ù„Ù…Ù†ØªØ¯ÙŠØ§Øª
+  project_module_calendar: Ø§Ù„ØªÙ‚ÙˆÙŠÙ…
+  project_module_gantt: Ø¬Ø§Ù†Øª
+
+  label_user: Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
+  label_user_plural: Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…ÙŠÙ†
+  label_user_new: Ù…Ø³ØªØ®Ø¯Ù… Ø¬Ø¯ÙŠØ¯
+  label_user_anonymous: Ù…Ø¬Ù‡ÙˆÙ„ Ø§Ù„Ù‡ÙˆÙŠØ©
+  label_project: Ù…Ø´Ø±ÙˆØ¹
+  label_project_new: Ù…Ø´Ø±ÙˆØ¹ Ø¬Ø¯ÙŠØ¯
+  label_project_plural: Ù…Ø´Ø§Ø±ÙŠØ¹
+  label_x_projects:
+    zero: Ù„Ø§ ÙŠÙˆØ¬Ø¯ Ù…Ø´Ø§Ø±ÙŠØ¹
+    one: Ù…Ø´Ø±ÙˆØ¹ ÙˆØ§Ø­Ø¯
+    other: "%{count} Ù…Ø´Ø§Ø±ÙŠØ¹"
+  label_project_all: ÙƒÙ„ Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹
+  label_project_latest: Ø§Ø­Ø¯Ø« Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹
+  label_issue: Ù‚Ø¶ÙŠØ©
+  label_issue_new: Ù‚Ø¶ÙŠØ© Ø¬Ø¯ÙŠØ¯Ø©
+  label_issue_plural: Ù‚Ø¶Ø§ÙŠØ§
+  label_issue_view_all: Ø¹Ø±Ø¶ ÙƒÙ„ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  label_issues_by: " %{value}Ø§Ù„Ù‚Ø¶ÙŠØ© Ù„ØµØ­Ø§Ø¨Ù‡Ø§"
+  label_issue_added: ØªÙ… Ø§Ø¶Ø§ÙØ© Ø§Ù„Ù‚Ø¶ÙŠØ©
+  label_issue_updated: ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ù‚Ø¶ÙŠØ©
+  label_issue_note_added: ØªÙ… Ø§Ø¶Ø§ÙØ© Ø§Ù„Ù…Ù„Ø§Ø­Ø¸Ø©
+  label_issue_status_updated: ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ø­Ø§Ù„Ø©
+  label_issue_priority_updated: ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ø§ÙˆÙ„ÙˆÙŠØ§Øª
+  label_document: Ù…Ø³ØªÙ†Ø¯
+  label_document_new: Ù…Ø³ØªÙ†Ø¯ Ø¬Ø¯ÙŠØ¯
+  label_document_plural: Ù…Ø³ØªÙ†Ø¯Ø§Øª
+  label_document_added: ØªÙ… Ø§Ø¶Ø§ÙØ© Ù…Ø³ØªÙ†Ø¯
+  label_role: Ø¯ÙˆØ±
+  label_role_plural: Ø§Ø¯ÙˆØ§Ø±
+  label_role_new: Ø¯ÙˆØ± Ø¬Ø¯ÙŠØ¯
+  label_role_and_permissions: Ø§Ù„Ø§Ø¯ÙˆØ§Ø± ÙˆØ§Ù„Ø§Ø°Ù†
+  label_role_anonymous: Ù…Ø¬Ù‡ÙˆÙ„ Ø§Ù„Ù‡ÙˆÙŠØ©
+  label_role_non_member: Ù„ÙŠØ³ Ø¹Ø¶Ùˆ
+  label_member: Ø¹Ø¶Ùˆ
+  label_member_new: Ø¹Ø¶Ùˆ Ø¬Ø¯ÙŠØ¯
+  label_member_plural: Ø§Ø¹Ø¶Ø§Ø¡
+  label_tracker: Ø§Ù„Ù…ØªØªØ¨Ø¹
+  label_tracker_plural: Ø§Ù„Ù…ØªØªØ¨Ø¹ÙŠÙ†
+  label_tracker_new: Ù…ØªØªØ¨Ø¹ Ø¬Ø¯ÙŠØ¯
+  label_workflow: Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„
+  label_issue_status: ÙˆØ¶Ø¹ Ø§Ù„Ù‚Ø¶ÙŠØ©
+  label_issue_status_plural: Ø§ÙˆØ¶Ø§Ø¹ Ø§Ù„Ù‚Ø¶ÙŠØ©
+  label_issue_status_new: ÙˆØ¶Ø¹ Ø¬Ø¯ÙŠØ¯
+  label_issue_category: Ù†ÙˆØ¹ Ø§Ù„Ù‚Ø¶ÙŠØ©
+  label_issue_category_plural: Ø§Ù†ÙˆØ§Ø¹ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  label_issue_category_new: Ù†ÙˆØ¹ Ø¬Ø¯ÙŠØ¯
+  label_custom_field: ØªØ®ØµÙŠØµ Ø­Ù‚Ù„
+  label_custom_field_plural: ØªØ®ØµÙŠØµ Ø­Ù‚ÙˆÙ„
+  label_custom_field_new: Ø­Ù‚Ù„ Ù…Ø®ØµØµ Ø¬Ø¯ÙŠØ¯
+  label_enumerations: Ø§Ù„ØªØ¹Ø¯Ø§Ø¯Ø§Øª
+  label_enumeration_new: Ù‚ÙŠÙ…Ø© Ø¬Ø¯ÙŠØ¯Ø©
+  label_information: Ù…Ø¹Ù„ÙˆÙ…Ø©
+  label_information_plural: Ù…Ø¹Ù„ÙˆÙ…Ø§Øª
+  label_please_login: Ø¨Ø±Ø¬Ù‰ ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„
+  label_register: ØªØ³Ø¬ÙŠÙ„
+  label_login_with_open_id_option: Ø§Ùˆ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø¨Ù‡ÙˆÙŠØ© Ù…ÙØªÙˆØ­Ø©
+  label_password_lost: ÙÙ‚Ø¯Øª ÙƒÙ„Ù…Ø© Ø§Ù„Ø³Ø±
+  label_home: Ø§Ù„ØµÙØ­Ø© Ø§Ù„Ø±Ø¦ÙŠØ³ÙŠØ©
+  label_my_page: Ø§Ù„ØµÙØ­Ø© Ø§Ù„Ø®Ø§ØµØ© Ø¨ÙŠ
+  label_my_account: Ø­Ø³Ø§Ø¨ÙŠ
+  label_my_projects: Ù…Ø´Ø§Ø±ÙŠØ¹ÙŠ Ø§Ù„Ø®Ø§ØµØ©
+  label_my_page_block: Ø­Ø¬Ø¨ ØµÙØ­ØªÙŠ Ø§Ù„Ø®Ø§ØµØ©
+  label_administration: Ø§Ù„Ø¥Ø¯Ø§Ø±Ø©
+  label_login: ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„
+  label_logout: ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø®Ø±ÙˆØ¬
+  label_help: Ù…Ø³Ø§Ø¹Ø¯Ø©
+  label_reported_issues: Ø£Ø¨Ù„Øº Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  label_assigned_to_me_issues: Ø§Ù„Ù…Ø³Ø§Ø¦Ù„ Ø§Ù„Ù…Ø¹Ù†ÙŠØ© Ø¥Ù„Ù‰
+  label_last_login: Ø¢Ø®Ø± Ø§ØªØµØ§Ù„
+  label_registered_on: Ù…Ø³Ø¬Ù„ Ø¹Ù„Ù‰
+  label_activity: Ø§Ù„Ù†Ø´Ø§Ø·
+  label_overall_activity: Ø§Ù„Ù†Ø´Ø§Ø· Ø§Ù„Ø¹Ø§Ù…
+  label_user_activity: "Ù‚ÙŠÙ…Ø© Ø§Ù„Ù†Ø´Ø§Ø·"
+  label_new: Ø¬Ø¯ÙŠØ¯Ø©
+  label_logged_as: ØªÙ… ØªØ³Ø¬ÙŠÙ„ Ø¯Ø®ÙˆÙ„Ùƒ
+  label_environment: Ø§Ù„Ø¨ÙŠØ¦Ø©
+  label_authentication: Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
+  label_auth_source: ÙˆØ¶Ø¹ Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
+  label_auth_source_new: ÙˆØ¶Ø¹ Ù…ØµØ§Ø¯Ù‚Ø© Ø¬Ø¯ÙŠØ¯Ø©
+  label_auth_source_plural: Ø£ÙˆØ¶Ø§Ø¹ Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
+  label_subproject_plural: Ù…Ø´Ø§Ø±ÙŠØ¹ ÙØ±Ø¹ÙŠØ©
+  label_subproject_new: Ù…Ø´Ø±ÙˆØ¹ ÙØ±Ø¹ÙŠ Ø¬Ø¯ÙŠØ¯
+  label_and_its_subprojects: "Ù‚ÙŠÙ…Ø©Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„ÙØ±Ø¹ÙŠØ© Ø§Ù„Ø®Ø§ØµØ© Ø¨Ùƒ"
+  label_min_max_length: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ ÙˆØ§Ù„Ø§Ø¯Ù†Ù‰ Ù„Ù„Ø·ÙˆÙ„
+  label_list: Ù‚Ø§Ø¦Ù…Ø©
+  label_date: ØªØ§Ø±ÙŠØ®
+  label_integer: Ø¹Ø¯Ø¯ ØµØ­ÙŠØ­
+  label_float: ØªØ¹ÙˆÙŠÙ…
+  label_boolean: Ù…Ù†Ø·Ù‚ÙŠØ©
+  label_string: Ø§Ù„Ù†Øµ
+  label_text: Ù†Øµ Ø·ÙˆÙŠÙ„
+  label_attribute: Ø³Ù…Ø©
+  label_attribute_plural: Ø§Ù„Ø³Ù…Ø§Øª
+  label_no_data: Ù„Ø§ ØªÙˆØ¬Ø¯ Ø¨ÙŠØ§Ù†Ø§Øª Ù„Ù„Ø¹Ø±Ø¶
+  label_change_status: ØªØºÙŠÙŠØ± Ø§Ù„ÙˆØ¶Ø¹
+  label_history: Ø§Ù„ØªØ§Ø±ÙŠØ®
+  label_attachment: Ø§Ù„Ù…Ù„Ù
+  label_attachment_new: Ù…Ù„Ù Ø¬Ø¯ÙŠØ¯
+  label_attachment_delete: Ø­Ø°Ù Ø§Ù„Ù…Ù„Ù
+  label_attachment_plural: Ø§Ù„Ù…Ù„ÙØ§Øª
+  label_file_added: Ø§Ù„Ù…Ù„Ù Ø§Ù„Ù…Ø¶Ø§Ù
+  label_report: ØªÙ‚Ø±ÙŠØ±
+  label_report_plural: Ø§Ù„ØªÙ‚Ø§Ø±ÙŠØ±
+  label_news: Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
+  label_news_new: Ø¥Ø¶Ø§ÙØ© Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
+  label_news_plural: Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
+  label_news_latest: Ø¢Ø®Ø± Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
+  label_news_view_all: Ø¹Ø±Ø¶ ÙƒÙ„ Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
+  label_news_added: Ø§Ù„Ø£Ø®Ø¨Ø§Ø± Ø§Ù„Ù…Ø¶Ø§ÙØ©
+  label_news_comment_added: Ø¥Ø¶Ø§ÙØ© Ø§Ù„ØªØ¹Ù„ÙŠÙ‚Ø§Øª Ø¹Ù„Ù‰ Ø£Ø®Ø¨Ø§Ø±
+  label_settings: Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª
+  label_overview: Ù„Ù…Ø­Ø© Ø¹Ø§Ù…Ø©
+  label_version: Ø§Ù„Ø¥ØµØ¯Ø§Ø±
+  label_version_new: Ø§Ù„Ø¥ØµØ¯Ø§Ø± Ø§Ù„Ø¬Ø¯ÙŠØ¯
+  label_version_plural: Ø§Ù„Ø¥ØµØ¯Ø§Ø±Ø§Øª
+  label_close_versions: Ø£ÙƒÙ…Ù„Øª Ø¥ØºÙ„Ø§Ù‚ Ø§Ù„Ø¥ØµØ¯Ø§Ø±Ø§Øª
+  label_confirmation: ØªØ£ÙƒÙŠØ¯
+  label_export_to: 'Ù…ØªÙˆÙØ±Ø© Ø£ÙŠØ¶Ø§ ÙÙŠ:'
+  label_read: Ø§Ù„Ù‚Ø±Ø§Ø¡Ø©...
+  label_public_projects: Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„Ø¹Ø§Ù…Ø©
+  label_open_issues: ÙØªØ­ Ù‚Ø¶ÙŠØ©
+  label_open_issues_plural:  ÙØªØ­ Ù‚Ø¶Ø§ÙŠØ§
+  label_closed_issues: Ù‚Ø¶ÙŠØ© Ù…ØºÙ„Ù‚Ø©
+  label_closed_issues_plural: Ù‚Ø¶Ø§ÙŠØ§ Ù…ØºÙ„Ù‚Ø©
+  label_x_open_issues_abbr_on_total:
+    zero: 0 Ù…ÙØªÙˆØ­ / %{total}
+    one: 1 Ù…ÙØªÙˆØ­ / %{total}
+    other: "%{count} Ù…ÙØªÙˆØ­ / %{total}"
+  label_x_open_issues_abbr:
+    zero: 0 Ù…ÙØªÙˆØ­
+    one: 1 Ù…Ù‚ØªÙˆØ­
+    other: "%{count} Ù…ÙØªÙˆØ­"
+  label_x_closed_issues_abbr:
+    zero: 0 Ù…ØºÙ„Ù‚
+    one: 1 Ù…ØºÙ„Ù‚
+    other: "%{count} Ù…ØºÙ„Ù‚"
+  label_total: Ø§Ù„Ø¥Ø¬Ù…Ø§Ù„ÙŠ
+  label_permissions: Ø£Ø°ÙˆÙ†Ø§Øª
+  label_current_status: Ø§Ù„ÙˆØ¶Ø¹ Ø§Ù„Ø­Ø§Ù„ÙŠ
+  label_new_statuses_allowed: ÙŠØ³Ù…Ø­ Ø¨Ø§Ø¯Ø±Ø§Ø¬ Ø­Ø§Ù„Ø§Øª Ø¬Ø¯ÙŠØ¯Ø©
+  label_all: Ø¬Ù…ÙŠØ¹
+  label_none: Ù„Ø§ Ø´ÙŠØ¡
+  label_nobody: Ù„Ø§ Ø£Ø­Ø¯
+  label_next: Ø§Ù„Ù‚Ø§Ø¯Ù…
+  label_previous: Ø§Ù„Ø³Ø§Ø¨Ù‚
+  label_used_by: Ø§Ù„ØªÙŠ ÙŠØ³ØªØ®Ø¯Ù…Ù‡Ø§
+  label_details: Ø§Ù„ØªÙØ§ØµÙŠÙ„
+  label_add_note: Ø¥Ø¶Ø§ÙØ© Ù…Ù„Ø§Ø­Ø¸Ø©
+  label_per_page: ÙƒÙ„ ØµÙØ­Ø©
+  label_calendar: Ø§Ù„ØªÙ‚ÙˆÙŠÙ…
+  label_months_from: Ø¨Ø¹Ø¯ Ø£Ø´Ù‡Ø± Ù…Ù†
+  label_gantt: Ø¬Ø§Ù†Øª
+  label_internal: Ø§Ù„Ø¯Ø§Ø®Ù„ÙŠØ©
+  label_last_changes: "Ø¢Ø®Ø± Ø§Ù„ØªØºÙŠÙŠØ±Ø§Øª %{count}"
+  label_change_view_all: Ø¹Ø±Ø¶ ÙƒØ§ÙØ© Ø§Ù„ØªØºÙŠÙŠØ±Ø§Øª
+  label_personalize_page: ØªØ®ØµÙŠØµ Ù‡Ø°Ù‡ Ø§Ù„ØµÙØ­Ø©
+  label_comment: ØªØ¹Ù„ÙŠÙ‚
+  label_comment_plural: ØªØ¹Ù„ÙŠÙ‚Ø§Øª
+  label_x_comments:
+    zero: Ù„Ø§ ÙŠÙˆØ¬Ø¯ ØªØ¹Ù„ÙŠÙ‚Ø§Øª
+    one: ØªØ¹Ù„ÙŠÙ‚ ÙˆØ§Ø­Ø¯
+    other: "%{count} ØªØ¹Ù„ÙŠÙ‚Ø§Øª"
+  label_comment_add: Ø¥Ø¶Ø§ÙØ© ØªØ¹Ù„ÙŠÙ‚
+  label_comment_added: ØªÙ… Ø¥Ø¶Ø§ÙØ© Ø§Ù„ØªØ¹Ù„ÙŠÙ‚
+  label_comment_delete: Ø­Ø°Ù Ø§Ù„ØªØ¹Ù„ÙŠÙ‚Ø§Øª
+  label_query: Ø§Ø³ØªØ¹Ù„Ø§Ù… Ù…Ø®ØµØµ
+  label_query_plural: Ø§Ø³ØªØ¹Ù„Ø§Ù…Ø§Øª Ù…Ø®ØµØµØ©
+  label_query_new: Ø§Ø³ØªØ¹Ù„Ø§Ù… Ø¬Ø¯ÙŠØ¯
+  label_my_queries: Ø§Ø³ØªØ¹Ù„Ø§Ù…Ø§ØªÙŠ Ø§Ù„Ù…Ø®ØµØµØ©
+  label_filter_add: Ø¥Ø¶Ø§ÙØ© Ø¹Ø§Ù…Ù„ ØªØµÙÙŠØ©
+  label_filter_plural: Ø¹ÙˆØ§Ù…Ù„ Ø§Ù„ØªØµÙÙŠØ©
+  label_equals: ÙŠØ³Ø§ÙˆÙŠ
+  label_not_equals: Ù„Ø§ ÙŠØ³Ø§ÙˆÙŠ
+  label_in_less_than: ÙÙŠ Ø£Ù‚Ù„ Ù…Ù†
+  label_in_more_than: ÙÙŠ Ø£ÙƒØ«Ø± Ù…Ù†
+  label_greater_or_equal: '>='
+  label_less_or_equal: '< ='
+  label_between: Ø¨ÙŠÙ†
+  label_in: ÙÙŠ
+  label_today: Ø§Ù„ÙŠÙˆÙ…
+  label_all_time: ÙƒÙ„ Ø§Ù„ÙˆÙ‚Øª
+  label_yesterday: Ø¨Ø§Ù„Ø£Ù…Ø³
+  label_this_week: Ù‡Ø°Ø§ Ø§Ù„Ø£Ø³Ø¨ÙˆØ¹
+  label_last_week: Ø§Ù„Ø£Ø³Ø¨ÙˆØ¹ Ø§Ù„Ù…Ø§Ø¶ÙŠ
+  label_last_n_days: "Ø§ÙŠØ§Ù… %{count} Ø§Ø®Ø±"
+  label_this_month: Ù‡Ø°Ø§ Ø§Ù„Ø´Ù‡Ø±
+  label_last_month: Ø§Ù„Ø´Ù‡Ø± Ø§Ù„Ù…Ø§Ø¶ÙŠ
+  label_this_year: Ù‡Ø°Ø§ Ø§Ù„Ø¹Ø§Ù…
+  label_date_range: Ù†Ø·Ø§Ù‚ Ø§Ù„ØªØ§Ø±ÙŠØ®
+  label_less_than_ago: Ø£Ù‚Ù„ Ù…Ù† Ù‚Ø¨Ù„ Ø£ÙŠØ§Ù…
+  label_more_than_ago: Ø£ÙƒØ«Ø± Ù…Ù† Ù‚Ø¨Ù„ Ø£ÙŠØ§Ù…
+  label_ago: Ù…Ù†Ø° Ø£ÙŠØ§Ù…
+  label_contains: ÙŠØ­ØªÙˆÙŠ Ø¹Ù„Ù‰
+  label_not_contains: Ù„Ø§ ÙŠØ­ØªÙˆÙŠ Ø¹Ù„Ù‰
+  label_day_plural: Ø£ÙŠØ§Ù…
+  label_repository: Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹
+  label_repository_plural: Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹Ø§Øª
+  label_browse: ØªØµÙØ­
+  label_branch: ÙØ±Ø¹
+  label_tag: Ø±Ø¨Ø·
+  label_revision: Ù…Ø±Ø§Ø¬Ø¹Ø©
+  label_revision_plural: ØªÙ†Ù‚ÙŠØ­Ø§Øª
+  label_revision_id: " %{value}Ù…Ø±Ø§Ø¬Ø¹Ø©"
+  label_associated_revisions: Ø§Ù„ØªÙ†Ù‚ÙŠØ­Ø§Øª Ø§Ù„Ù…Ø±ØªØ¨Ø·Ø©
+  label_added: Ø¥Ø¶Ø§ÙØ©
+  label_modified: ØªØ¹Ø¯ÙŠÙ„
+  label_copied: Ù†Ø³Ø®
+  label_renamed: Ø¥Ø¹Ø§Ø¯Ø© ØªØ³Ù…ÙŠØ©
+  label_deleted: Ø­Ø°Ù
+  label_latest_revision: Ø¢Ø®Ø± ØªÙ†Ù‚ÙŠØ­
+  label_latest_revision_plural: Ø£Ø­Ø¯Ø« Ø§Ù„Ù…Ø±Ø§Ø¬Ø¹Ø§Øª
+  label_view_revisions: Ø¹Ø±Ø¶ Ø§Ù„ØªÙ†Ù‚ÙŠØ­Ø§Øª
+  label_view_all_revisions: Ø¹Ø±Ø¶ ÙƒØ§ÙØ© Ø§Ù„Ù…Ø±Ø§Ø¬Ø¹Ø§Øª
+  label_max_size: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø£Ù‚ØµÙ‰ Ù„Ù„Ø­Ø¬Ù…
+  label_sort_highest: Ø§Ù„ØªØ­Ø±Ùƒ Ø¥Ù„Ù‰ Ø£Ø¹Ù„Ù‰
+  label_sort_higher: ØªØ­Ø±ÙŠÙƒ Ù„Ø£Ø¹Ù„Ù‰
+  label_sort_lower: ØªØ­Ø±ÙŠÙƒ Ù„Ø£Ø³ÙÙ„
+  label_sort_lowest: Ø§Ù„Ø§Ù†ØªÙ‚Ø§Ù„ Ø¥Ù„Ù‰ Ø£Ø³ÙÙ„
+  label_roadmap: Ø®Ø§Ø±Ø·Ø© Ø§Ù„Ø·Ø±ÙŠÙ‚
+  label_roadmap_due_in: " %{value}ØªØ³ØªØ­Ù‚ ÙÙŠ "
+  label_roadmap_overdue: "%{value}ØªØ£Ø®ÙŠØ±"
+  label_roadmap_no_issues: Ù„Ø§ ÙŠÙˆØ¬Ø¯ Ù‚Ø¶Ø§ÙŠØ§ Ù„Ù‡Ø°Ø§ Ø§Ù„Ø¥ØµØ¯Ø§Ø±
+  label_search: Ø§Ù„Ø¨Ø­Ø«
+  label_result_plural: Ø§Ù„Ù†ØªØ§Ø¦Ø¬
+  label_all_words: ÙƒÙ„ Ø§Ù„ÙƒÙ„Ù…Ø§Øª
+  label_wiki: ÙˆÙŠÙƒÙŠ
+  label_wiki_edit: ØªØ­Ø±ÙŠØ± ÙˆÙŠÙƒÙŠ
+  label_wiki_edit_plural: Ø¹Ù…Ù„ÙŠØ§Øª ØªØ­Ø±ÙŠØ± ÙˆÙŠÙƒÙŠ
+  label_wiki_page: ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ
+  label_wiki_page_plural: ÙˆÙŠÙƒÙŠ ØµÙØ­Ø§Øª
+  label_index_by_title: Ø§Ù„ÙÙ‡Ø±Ø³ Ø­Ø³Ø¨ Ø§Ù„Ø¹Ù†ÙˆØ§Ù†
+  label_index_by_date: Ø§Ù„ÙÙ‡Ø±Ø³ Ø­Ø³Ø¨ Ø§Ù„ØªØ§Ø±ÙŠØ®
+  label_current_version: Ø§Ù„Ø¥ØµØ¯Ø§Ø± Ø§Ù„Ø­Ø§Ù„ÙŠ
+  label_preview: Ù…Ø¹Ø§ÙŠÙ†Ø©
+  label_feed_plural: Ù…ÙˆØ¬Ø² ÙˆÙŠØ¨
+  label_changes_details: ØªÙØ§ØµÙŠÙ„ Ø¬Ù…ÙŠØ¹ Ø§Ù„ØªØºÙŠÙŠØ±Ø§Øª
+  label_issue_tracking: ØªØ¹Ù‚Ø¨ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  label_spent_time: Ø£Ù…Ø¶Ù‰ Ø¨Ø¹Ø¶ Ø§Ù„ÙˆÙ‚Øª
+  label_overall_spent_time: Ø§Ù„ÙˆÙ‚Øª Ø§Ù„Ø°ÙŠ ØªÙ… Ø§Ù†ÙØ§Ù‚Ù‡ ÙƒØ§Ù…Ù„Ø§
+  label_f_hour: "%{value} Ø³Ø§Ø¹Ø©"
+  label_f_hour_plural: "%{value} Ø³Ø§Ø¹Ø§Øª"
+  label_time_tracking: ØªØ¹Ù‚Ø¨ Ø§Ù„ÙˆÙ‚Øª
+  label_change_plural: Ø§Ù„ØªØºÙŠÙŠØ±Ø§Øª
+  label_statistics: Ø¥Ø­ØµØ§Ø¡Ø§Øª
+  label_commits_per_month: ÙŠØ«Ø¨Øª ÙÙŠ Ø§Ù„Ø´Ù‡Ø±
+  label_commits_per_author: ÙŠØ«Ø¨Øª Ù„ÙƒÙ„ Ù…Ø¤Ù„Ù
+  label_diff: Ø§Ù„Ø§Ø®ØªÙ„Ø§ÙØ§Øª
+  label_view_diff: Ø¹Ø±Ø¶ Ø§Ù„Ø§Ø®ØªÙ„Ø§ÙØ§Øª
+  label_diff_inline: Ù…Ø¶Ù…Ù†Ø©
+  label_diff_side_by_side: Ø¬Ù†Ø¨Ø§ Ø¥Ù„Ù‰ Ø¬Ù†Ø¨
+  label_options: Ø®ÙŠØ§Ø±Ø§Øª
+  label_copy_workflow_from: Ù†Ø³Ø® Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„ Ù…Ù†
+  label_permissions_report: ØªÙ‚Ø±ÙŠØ± Ø£Ø°ÙˆÙ†Ø§Øª
+  label_watched_issues: Ø´Ø§Ù‡Ø¯ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  label_related_issues: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø°Ø§Øª Ø§Ù„ØµÙ„Ø©
+  label_applied_status: ØªØ·Ø¨ÙŠÙ‚ Ù…Ø±ÙƒØ²
+  label_loading: ØªØ­Ù…ÙŠÙ„...
+  label_relation_new: Ø¹Ù„Ø§Ù‚Ø© Ø¬Ø¯ÙŠØ¯Ø©
+  label_relation_delete: Ø­Ø°Ù Ø§Ù„Ø¹Ù„Ø§Ù‚Ø©
+  label_relates_to: Ø°Ø§Øª Ø§Ù„ØµÙ„Ø© Ø¥Ù„Ù‰
+  label_duplicates: Ø§Ù„ØªÙƒØ±Ø§Ø±Ø§Øª
+  label_duplicated_by: Ø§Ø²Ø¯ÙˆØ§Ø¬
+  label_blocks: Ø­Ø¸Ø±
+  label_blocked_by: Ø­Ø¸Ø± Ø¨ÙˆØ§Ø³Ø·Ø©
+  label_precedes: ÙŠØ³Ø¨Ù‚
+  label_follows: ÙŠØªØ¨Ø¹
+  label_end_to_start: Ù†Ù‡Ø§ÙŠØ© Ù„Ø¨Ø¯Ø¡
+  label_end_to_end: Ù†Ù‡Ø§ÙŠØ© Ø¥Ù„Ù‰ Ù†Ù‡Ø§ÙŠØ©
+  label_start_to_start: Ø¨Ø¯Ø¡ Ø¥Ù„Ù‰ Ø¨Ø¯Ø¡
+  label_start_to_end: Ø¨Ø¯Ø§ÙŠØ© Ù„Ù†Ù‡Ø§ÙŠØ©
+  label_stay_logged_in: ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„ ÙÙŠ
+  label_disabled: ØªØ¹Ø·ÙŠÙ„
+  label_show_completed_versions: Ø£ÙƒÙ…Ù„Øª Ø¥Ø¸Ù‡Ø§Ø± Ø¥ØµØ¯Ø§Ø±Ø§Øª
+  label_me: Ù„ÙŠ
+  label_board: Ø§Ù„Ù…Ù†ØªØ¯Ù‰
+  label_board_new: Ù…Ù†ØªØ¯Ù‰ Ø¬Ø¯ÙŠØ¯
+  label_board_plural: Ø§Ù„Ù…Ù†ØªØ¯ÙŠØ§Øª
+  label_board_locked: ØªØ£Ù…ÙŠÙ†
+  label_board_sticky: Ù„Ø²Ø¬Ø©
+  label_topic_plural: Ø§Ù„Ù…ÙˆØ§Ø¶ÙŠØ¹
+  label_message_plural: Ø±Ø³Ø§Ø¦Ù„
+  label_message_last: Ø¢Ø®Ø± Ø±Ø³Ø§Ù„Ø©
+  label_message_new: Ø±Ø³Ø§Ù„Ø© Ø¬Ø¯ÙŠØ¯Ø©
+  label_message_posted: ØªÙ… Ø§Ø¶Ø§ÙØ© Ø§Ù„Ø±Ø³Ø§Ù„Ø©
+  label_reply_plural: Ø§Ù„Ø±Ø¯ÙˆØ¯
+  label_send_information: Ø¥Ø±Ø³Ø§Ù„ Ù…Ø¹Ù„ÙˆÙ…Ø§Øª Ø§Ù„Ø­Ø³Ø§Ø¨ Ù„Ù„Ù…Ø³ØªØ®Ø¯Ù…
+  label_year: Ø³Ù†Ø©
+  label_month: Ø´Ù‡Ø±
+  label_week: Ø£Ø³Ø¨ÙˆØ¹
+  label_date_from: Ù…Ù†
+  label_date_to: Ø¥Ù„Ù‰
+  label_language_based: Ø§Ø³ØªÙ†Ø§Ø¯Ø§Ù‹ Ø¥Ù„Ù‰ Ù„ØºØ© Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
+  label_sort_by: " %{value}Ø§Ù„ØªØ±ØªÙŠØ¨ Ø­Ø³Ø¨ "
+  label_send_test_email: Ø§Ø±Ø³Ù„ Ø±Ø³Ø§Ù„Ø© Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠØ© ÙƒØ§Ø®ØªØ¨Ø§Ø±
+  label_feeds_access_key: RSS Ù…ÙØªØ§Ø­ Ø¯Ø®ÙˆÙ„
+  label_missing_feeds_access_key: Ù…ÙÙ‚ÙˆØ¯RSS Ù…ÙØªØ§Ø­ Ø¯Ø®ÙˆÙ„
+  label_feeds_access_key_created_on: "RSS ØªÙ… Ø§Ù†Ø´Ø§Ø¡ Ù…ÙØªØ§Ø­ %{value} Ù…Ù†Ø°"
+  label_module_plural: Ø§Ù„ÙˆØ­Ø¯Ø§Øª Ø§Ù„Ù†Ù…Ø·ÙŠØ©
+  label_added_time_by: " ØªÙ… Ø§Ø¶Ø§ÙØªÙ‡ Ù…Ù† Ù‚Ø¨Ù„%{author} %{age} Ù…Ù†Ø°"
+  label_updated_time_by: " ØªÙ… ØªØ­Ø¯ÙŠØ«Ù‡ Ù…Ù† Ù‚Ø¨Ù„%{author} %{age} Ù…Ù†Ø°"
+  label_updated_time: "ØªÙ… Ø§Ù„ØªØ­Ø¯ÙŠØ«  %{value} Ù…Ù†Ø°"
+  label_jump_to_a_project: Ø§Ù„Ø§Ù†ØªÙ‚Ø§Ù„ Ø¥Ù„Ù‰ Ù…Ø´Ø±ÙˆØ¹...
+  label_file_plural: Ø§Ù„Ù…Ù„ÙØ§Øª
+  label_changeset_plural: Ø§Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„ØªØºÙŠØ±
+  label_default_columns: Ø§Ù„Ø§Ø¹Ù…Ø¯Ø© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
+  label_no_change_option: (Ø£ÙŠ ØªØºÙŠÙŠØ±)
+  label_bulk_edit_selected_issues: ØªØ­Ø±ÙŠØ± Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù…Ø¸Ù„Ù„Ø©
+  label_bulk_edit_selected_time_entries: ØªØ¹Ø¯ÙŠÙ„ ÙƒÙ„ Ø§Ù„Ø¥Ø¯Ø®Ø§Ù„Ø§Øª ÙÙŠ ÙƒÙ„ Ø§Ù„Ø§ÙˆÙ‚Ø§Øª
+  label_theme: Ø§Ù„Ù…ÙˆØ¶ÙˆØ¹
+  label_default: Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ
+  label_search_titles_only: Ø§Ù„Ø¨Ø­Ø« ÙÙŠ Ø§Ù„Ø¹Ù†Ø§ÙˆÙŠÙ† ÙÙ‚Ø·
+  label_user_mail_option_all: "Ø¬Ù…ÙŠØ¹ Ø§Ù„Ø®ÙŠØ§Ø±Ø§Øª"
+  label_user_mail_option_selected: "Ø§Ù„Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„Ù…Ø¸Ù„Ù„Ø© ÙÙ‚Ø·"
+  label_user_mail_option_none: "Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ¯ Ø§ÙŠ Ø®ÙŠØ§Ø±Ø§Øª"
+  label_user_mail_option_only_my_events: "Ø§Ù„Ø³Ù…Ø§Ø­ Ù„ÙŠ ÙÙ‚Ø· Ø¨Ù…Ø´Ø§Ù‡Ø¯Ø© Ø§Ù„Ø§Ø­Ø¯Ø§Ø« Ø§Ù„Ø®Ø§ØµØ©"
+  label_user_mail_option_only_assigned: "ÙÙ‚Ø· Ø§Ù„Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„ØªÙŠ ØªÙ… ØªØ¹ÙŠÙŠÙ†Ù‡Ø§"
+  label_user_mail_option_only_owner: "ÙÙ‚Ø· Ù„Ù„Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„ØªÙŠ Ø§Ù…Ù„ÙƒÙ‡Ø§"
+  label_user_mail_no_self_notified: "Ù„Ø§ ØªØ±ÙŠØ¯ Ø§Ø¹Ù„Ø§Ù…Ùƒ Ø¨Ø§Ù„ØªØºÙŠØ±Ø§Øª Ø§Ù„ØªÙŠ ØªØ¬Ø±ÙŠÙ‡Ø§ Ø¨Ù†ÙØ³Ùƒ"
+  label_registration_activation_by_email: Ø­Ø³Ø§Ø¨ Ø§Ù„ØªÙ†Ø´ÙŠØ· Ø¹Ø¨Ø± Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  label_registration_manual_activation: ØªÙ†Ø´ÙŠØ· Ø§Ù„Ø­Ø³Ø§Ø¨ Ø§Ù„ÙŠØ¯ÙˆÙŠ
+  label_registration_automatic_activation: ØªÙ†Ø´ÙŠØ· Ø§Ù„Ø­Ø³Ø§Ø¨ Ø§Ù„ØªÙ„Ù‚Ø§Ø¦ÙŠ
+  label_display_per_page: "Ù„ÙƒÙ„ ØµÙØ­Ø©: %{value}"
+  label_age: Ø§Ù„Ø¹Ù…Ø±
+  label_change_properties: ØªØºÙŠÙŠØ± Ø§Ù„Ø®ØµØ§Ø¦Øµ
+  label_general: Ø¹Ø§Ù…Ø©
+  label_more: Ø£ÙƒØ«Ø±
+  label_scm: scm
+  label_plugins: Ø§Ù„Ø¥Ø¶Ø§ÙØ§Øª
+  label_ldap_authentication: Ù…ØµØ§Ø¯Ù‚Ø© LDAP
+  label_downloads_abbr: D/L
+  label_optional_description: ÙˆØµÙ Ø§Ø®ØªÙŠØ§Ø±ÙŠ
+  label_add_another_file: Ø¥Ø¶Ø§ÙØ© Ù…Ù„Ù Ø¢Ø®Ø±
+  label_preferences: ØªÙØ¶ÙŠÙ„Ø§Øª
+  label_chronological_order: ÙÙŠ ØªØ±ØªÙŠØ¨ Ø²Ù…Ù†ÙŠ
+  label_reverse_chronological_order: ÙÙŠ ØªØ±ØªÙŠØ¨ Ø²Ù…Ù†ÙŠ Ø¹ÙƒØ³ÙŠ
+  label_planning: Ø§Ù„ØªØ®Ø·ÙŠØ·
+  label_incoming_emails: Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ Ø§Ù„ÙˆØ§Ø±Ø¯
+  label_generate_key: Ø¥Ù†Ø´Ø§Ø¡ Ù…ÙØªØ§Ø­
+  label_issue_watchers: Ø§Ù„Ù…Ø±Ø§Ù‚Ø¨ÙˆÙ†
+  label_example: Ù…Ø«Ø§Ù„
+  label_display: Ø§Ù„Ø¹Ø±Ø¶
+  label_sort: ÙØ±Ø²
+  label_ascending: ØªØµØ§Ø¹Ø¯ÙŠ
+  label_descending: ØªÙ†Ø§Ø²Ù„ÙŠ
+  label_date_from_to: Ù…Ù† %{start} Ø§Ù„Ù‰ %{end}
+  label_wiki_content_added: Ø¥Ø¶Ø§ÙØ© ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ
+  label_wiki_content_updated: ØªØ­Ø¯ÙŠØ« ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ
+  label_group: Ù…Ø¬Ù…ÙˆØ¹Ø©
+  label_group_plural: Ø§Ù„Ù…Ø¬Ù…ÙˆØ¹Ø§Øª
+  label_group_new: Ù…Ø¬Ù…ÙˆØ¹Ø© Ø¬Ø¯ÙŠØ¯Ø©
+  label_time_entry_plural: Ø£Ù…Ø¶Ù‰ Ø¨Ø¹Ø¶ Ø§Ù„ÙˆÙ‚Øª
+  label_version_sharing_none: Ù„Ù… ÙŠØ´Ø§Ø±Ùƒ
+  label_version_sharing_descendants: ÙŠØ´Ø§Ø±Ùƒ
+  label_version_sharing_hierarchy: Ù…Ø¹ Ø§Ù„ØªØ³Ù„Ø³Ù„ Ø§Ù„Ù‡Ø±Ù…ÙŠ Ù„Ù„Ù…Ø´Ø±ÙˆØ¹
+  label_version_sharing_tree: Ù…Ø¹ Ø´Ø¬Ø±Ø© Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  label_version_sharing_system: Ù…Ø¹ Ø¬Ù…ÙŠØ¹ Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹
+  label_update_issue_done_ratios: ØªØ­Ø¯ÙŠØ« Ù‚Ø¶ÙŠØ©Ø§Ù„Ù†Ø³Ø¨
+  label_copy_source: Ù…ØµØ¯Ø±
+  label_copy_target: Ø§Ù„Ù‡Ø¯Ù
+  label_copy_same_as_target: Ù†ÙØ³ Ø§Ù„Ù‡Ø¯Ù
+  label_display_used_statuses_only: Ø¹Ø±Ø¶ Ø§Ù„Ø­Ø§Ù„Ø§Øª Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…Ø© Ù…Ù† Ù‚Ø¨Ù„ Ù‡Ø°Ø§ "ØªØ¹Ù‚Ø¨" ÙÙ‚Ø·
+  label_api_access_key: Ù…ÙØªØ§Ø­ Ø§Ù„ÙˆØµÙˆÙ„ Ø¥Ù„Ù‰ API
+  label_missing_api_access_key: API Ù„Ù… ÙŠØªÙ… Ø§Ù„Ø­ØµÙˆÙ„ Ø¹Ù„Ù‰ Ù…ÙØªØ§Ø­ Ø§Ù„ÙˆØµÙˆÙ„
+  label_api_access_key_created_on: " API  Ø¥Ù†Ø´Ø§Ø¡ Ù…ÙØªØ§Ø­ Ø§Ù„ÙˆØµÙˆÙ„ Ø¥Ù„Ù‰"
+  label_profile: Ø§Ù„Ù…Ù„Ù Ø§Ù„Ø´Ø®ØµÙŠ
+  label_subtask_plural: Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ÙØ±Ø¹ÙŠØ©
+  label_project_copy_notifications: Ø¥Ø±Ø³Ø§Ù„ Ø¥Ø´Ø¹Ø§Ø± Ø§Ù„Ù‰ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ Ø¹Ù†Ø¯ Ù†Ø³Ø® Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  label_principal_search: "Ø§Ù„Ø¨Ø­Ø« Ø¹Ù† Ù…Ø³ØªØ®Ø¯Ù… Ø£Ùˆ Ù…Ø¬Ù…ÙˆØ¹Ø©:"
+  label_user_search: "Ø§Ù„Ø¨Ø­Ø« Ø¹Ù† Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…:"
+  label_additional_workflow_transitions_for_author: Ø§Ù„Ø§Ù†ØªÙ‚Ø§Ù„Ø§Øª Ø§Ù„Ø¥Ø¶Ø§ÙÙŠØ© Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¨Ù‡Ø§ Ø¹Ù†Ø¯ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… ØµØ§Ø­Ø¨ Ø§Ù„Ø¨Ù„Ø§Øº
+  label_additional_workflow_transitions_for_assignee: Ø§Ù„Ø§Ù†ØªÙ‚Ø§Ù„Ø§Øª Ø§Ù„Ø¥Ø¶Ø§ÙÙŠØ© Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¨Ù‡Ø§ Ø¹Ù†Ø¯ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… Ø§Ù„Ù…Ø­Ø§Ù„ Ø¥Ù„ÙŠÙ‡
+  label_issues_visibility_all: Ø¬Ù…ÙŠØ¹ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
+  label_issues_visibility_public: Ø¬Ù…ÙŠØ¹ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ø®Ø§ØµØ©
+  label_issues_visibility_own: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„ØªÙŠ Ø£Ù†Ø´Ø£Ù‡Ø§ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
+  label_git_report_last_commit: Ø§Ø¹ØªÙ…Ø§Ø¯ Ø§Ù„ØªÙ‚Ø±ÙŠØ± Ø§Ù„Ø£Ø®ÙŠØ± Ù„Ù„Ù…Ù„ÙØ§Øª ÙˆØ§Ù„Ø¯Ù„Ø§Ø¦Ù„
+  label_parent_revision: Ø§Ù„ÙˆØ§Ù„Ø¯ÙŠÙ†
+  label_child_revision: Ø§Ù„Ø·ÙÙ„
+  label_export_options: "%{export_format} Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„ØªØµØ¯ÙŠØ±"
+
+  button_login: Ø¯Ø®ÙˆÙ„
+  button_submit: ØªØ«Ø¨ÙŠØª
+  button_save: Ø­ÙØ¸
+  button_check_all: Ù†Ø­Ø¯ÙŠØ¯ Ø§Ù„ÙƒÙ„
+  button_uncheck_all: Ø¹Ø¯Ù… ØªØ­Ø¯ÙŠØ¯ Ø§Ù„ÙƒÙ„
+  button_collapse_all:  ØªÙ‚Ù„ÙŠØµ Ø§Ù„ÙƒÙ„
+  button_expand_all: Ø¹Ø±Ø¶ Ø§Ù„ÙƒÙ„
+  button_delete: Ø­Ø°Ù
+  button_create: Ø§Ù†Ø´Ø§Ø¡
+  button_create_and_continue: Ø§Ù†Ø´Ø§Ø¡ ÙˆØ§Ø³ØªÙ…Ø±Ø§Ø±
+  button_test: Ø§Ø®ØªØ¨Ø§Ø±
+  button_edit: ØªØ¹Ø¯ÙŠÙ„
+  button_edit_associated_wikipage: "ØªØºÙŠØ± ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ: %{page_title}"
+  button_add: Ø§Ø¶Ø§ÙØ©
+  button_change: ØªØºÙŠØ±
+  button_apply: ØªØ·Ø¨ÙŠÙ‚
+  button_clear: ÙˆØ§Ø¶Ø­
+  button_lock: Ù‚ÙÙ„
+  button_unlock: Ø§Ù„ØºØ§Ø¡ Ø§Ù„Ù‚ÙÙ„
+  button_download: ØªÙ†Ø²ÙŠÙ„
+  button_list: Ù‚Ø§Ø¦Ù…Ø©
+  button_view: Ø¹Ø±Ø¶
+  button_move: ØªØ­Ø±Ùƒ
+  button_move_and_follow: ØªØ­Ø±Ùƒ ÙˆØ§ØªØ¨Ø¹
+  button_back: Ø±Ø¬ÙˆØ¹
+  button_cancel: Ø¥Ù„ØºØ§Ø¡
+  button_activate: ØªÙ†Ø´ÙŠØ·
+  button_sort: ØªØ±ØªÙŠØ¨
+  button_log_time: ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„
+  button_rollback: Ø§Ù„Ø±Ø¬ÙˆØ¹ Ø§Ù„Ù‰ Ù‡Ø°Ø§ Ø§Ù„Ø§ØµØ¯Ø§Ø±
+  button_watch: ÙŠØ´Ø§Ù‡Ø¯
+  button_unwatch: Ø¥Ù„ØºØ§Ø¡ Ø§Ù„Ù…Ø´Ø§Ù‡Ø¯Ø©
+  button_reply: Ø±Ø¯
+  button_archive: Ø§Ù„Ø§Ø±Ø´ÙŠÙ
+  button_unarchive: Ø¥Ù„ØºØ§Ø¡ Ø§Ù„Ø§Ø±Ø´ÙØ©
+  button_reset: Ø¥Ø¹Ø§Ø¯Ø©
+  button_rename: Ø¥Ø¹Ø§Ø¯Ø© Ø§Ù„ØªØ³Ù…ÙŠØ©
+  button_change_password: ØªØºÙŠØ± ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
+  button_copy: Ù†Ø³Ø®
+  button_copy_and_follow: Ù†Ø³Ø® ÙˆØ§ØªØ¨Ø§Ø¹
+  button_annotate: ØªØ¹Ù„ÙŠÙ‚
+  button_update: ØªØ­Ø¯ÙŠØ«
+  button_configure: ØªÙƒÙˆÙŠÙ†
+  button_quote: ÙŠÙ‚ØªØ¨Ø³
+  button_duplicate: ÙŠØ¶Ø§Ø¹Ù
+  button_show: ÙŠØ¸Ù‡Ø±
+  button_edit_section: ÙŠØ¹Ø¯Ù„ Ù‡Ø°Ø§ Ø§Ù„Ø¬Ø²Ø¡
+  button_export: ÙŠØ³ØªÙˆØ±Ø¯
+
+  status_active: Ù†Ø´ÙŠØ·
+  status_registered: Ù…Ø³Ø¬Ù„
+  status_locked: Ù…Ù‚ÙÙ„
+
+  version_status_open: Ù…ÙØªÙˆØ­
+  version_status_locked: Ù…Ù‚ÙÙ„
+  version_status_closed: Ù…ØºÙ„Ù‚
+
+  field_active: ÙØ¹Ø§Ù„
+
+  text_select_mail_notifications: Ø­Ø¯Ø¯ Ø§Ù„Ø§Ù…ÙˆØ± Ø§Ù„ØªÙŠ ÙŠØ¬Ø¨ Ø§Ø¨Ù„Ø§ØºÙƒ Ø¨Ù‡Ø§ Ø¹Ù† Ø·Ø±ÙŠÙ‚ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  text_regexp_info: Ù…Ø«Ø§Ù„. ^[A-Z0-9]+$
+  text_min_max_length_info: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ ÙˆØ§Ù„Ø§Ø¯Ù†ÙŠ Ù„Ø·ÙˆÙ„ Ø§Ù„Ù…Ø¹Ù„ÙˆÙ…Ø§Øª
+  text_project_destroy_confirmation: Ù‡Ù„ Ø£Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø£Ù†Ùƒ ØªØ±ÙŠØ¯ Ø­Ø°Ù Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ ÙˆØ§Ù„Ø¨ÙŠØ§Ù†Ø§Øª Ø°Ø§Øª Ø§Ù„ØµÙ„Ø©ØŸ
+  text_subprojects_destroy_warning: "subproject(s): Ø³ÙŠØªÙ… Ø­Ø°Ù Ø£ÙŠØ¶Ø§."
+  text_workflow_edit: Ø­Ø¯Ø¯ Ø¯ÙˆØ±Ø§Ù‹ ÙˆØªØ¹Ù‚Ø¨ Ù„ØªØ­Ø±ÙŠØ± Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„
+  text_are_you_sure: Ù‡Ù„ Ø£Ù†Øª Ù…ØªØ£ÙƒØ¯ØŸ
+  text_journal_changed: "%{label} ØªØºÙŠØ± %{old} Ø§Ù„Ù‰ %{new}"
+  text_journal_changed_no_detail: "%{label} ØªÙ… Ø§Ù„ØªØ­Ø¯ÙŠØ«"
+  text_journal_set_to: "%{label} ØªØºÙŠØ± Ø§Ù„Ù‰ %{value}"
+  text_journal_deleted: "%{label} ØªÙ… Ø§Ù„Ø­Ø°Ù (%{old})"
+  text_journal_added: "%{label} %{value} ØªÙ… Ø§Ù„Ø§Ø¶Ø§ÙØ©"
+  text_tip_issue_begin_day: Ù‚Ø¶ÙŠØ© Ø¨Ø¯Ø£Øª Ø§Ù„ÙŠÙˆÙ…
+  text_tip_issue_end_day: Ù‚Ø¶ÙŠØ© Ø§Ù†ØªÙ‡Øª Ø§Ù„ÙŠÙˆÙ…
+  text_tip_issue_begin_end_day: Ù‚Ø¶ÙŠØ© Ø¨Ø¯Ø£Øª ÙˆØ§Ù†ØªÙ‡Øª Ø§Ù„ÙŠÙˆÙ…
+  text_caracters_maximum: "%{count} Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰."
+  text_caracters_minimum: "Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¯Ù†Ù‰  %{count}"
+  text_length_between: "Ø§Ù„Ø·ÙˆÙ„ %{min} Ø¨ÙŠÙ† %{max} Ø±Ù…Ø²"
+  text_tracker_no_workflow: Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ¯ Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„ Ù„Ù‡Ø°Ø§ Ø§Ù„Ù…ØªØªØ¨Ø¹
+  text_unallowed_characters: Ø±Ù…ÙˆØ² ØºÙŠØ± Ù…Ø³Ù…ÙˆØ­Ø©
+  text_comma_separated: Ù…Ø³Ù…ÙˆØ­ Ø±Ù…ÙˆØ² Ù…ØªÙ†ÙˆØ¹Ø© ÙŠÙØµÙ„Ù‡Ø§ ÙØ§ØµÙ„Ø© .
+  text_line_separated: Ù…Ø³Ù…ÙˆØ­ Ø±Ù…ÙˆØ² Ù…ØªÙ†ÙˆØ¹Ø© ÙŠÙØµÙ„Ù‡Ø§ Ø³Ø·ÙˆØ±
+  text_issues_ref_in_commit_messages: Ø§Ù„Ø±Ø¬ÙˆØ¹ ÙˆØ§ØµÙ„Ø§Ø­ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ ÙÙŠ Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ù…Ø´ØªÙƒÙŠÙ†
+  text_issue_added: "Ø§Ù„Ù‚Ø¶ÙŠØ© %{id} ØªÙ… Ø§Ø¨Ù„Ø§ØºÙ‡Ø§ Ø¹Ù† Ø·Ø±ÙŠÙ‚ %{author}."
+  text_issue_updated: "Ø§Ù„Ù‚Ø¶ÙŠØ© %{id} ØªÙ… ØªØ­Ø¯ÙŠØ«Ù‡Ø§ Ø¹Ù† Ø·Ø±ÙŠÙ‚ %{author}."
+  text_wiki_destroy_confirmation: Ù‡Ù„ Ø§Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø±ØºØ¨ØªÙƒ ÙÙŠ Ø­Ø°Ù Ù‡Ø°Ø§ Ø§Ù„ÙˆÙŠÙƒÙŠ ÙˆÙ…Ø­ØªÙˆÙŠØ§ØªÙ‡ØŸ
+  text_issue_category_destroy_question: "Ø¨Ø¹Ø¶ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§  (%{count}) Ù…Ø±ØªØ¨Ø·Ø© Ø¨Ù‡Ø°Ù‡ Ø§Ù„ÙØ¦Ø©ØŒ Ù…Ø§Ø°Ø§ ØªØ±ÙŠØ¯ Ø§Ù† ØªÙØ¹Ù„ Ø¨Ù‡Ø§ØŸ"
+  text_issue_category_destroy_assignments: Ø­Ø°Ù Ø§Ù„ÙØ¦Ø©
+  text_issue_category_reassign_to: Ø§Ø¹Ø§Ø¯Ø© ØªØ«Ø¨ÙŠØª Ø§Ù„Ø¨Ù†ÙˆØ¯ ÙÙŠ Ø§Ù„ÙØ¦Ø©
+  text_user_mail_option: "Ø¨Ø§Ù„Ù†Ø³Ø¨Ø© Ù„Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ ØºÙŠØ± Ø§Ù„Ù…Ø­Ø¯Ø¯Ø©ØŒ Ø³ÙˆÙ ÙŠØªÙ… Ø§Ø¨Ù„Ø§ØºÙƒ Ø¹Ù† Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„ØªÙŠ ØªØ´Ø§Ù‡Ø¯Ù‡Ø§ Ø§Ùˆ ØªØ´Ø§Ø±Ùƒ Ø¨Ù‡Ø§ ÙÙ‚Ø·!"
+  text_no_configuration_data: "Ø§Ù„Ø§Ø¯ÙˆØ§Ø± ÙˆØ§Ù„Ù…ØªØªØ¨Ø¹ ÙˆØ­Ø§Ù„Ø§Øª Ø§Ù„Ù‚Ø¶ÙŠØ© ÙˆÙ…Ø®Ø·Ø· Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„ Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ¯ ÙˆØ¶Ø¹Ù‡Ø§ Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ Ø¨Ø¹Ø¯. "
+  text_load_default_configuration: Ø§Ø­Ù…Ù„ Ø§Ù„Ø§Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
+  text_status_changed_by_changeset: " Ø·Ø¨Ù‚ Ø§Ù„ØªØºÙŠØ±Ø§Øª Ø§Ù„Ù…Ø¹ÙŠÙ†Ø© Ø¹Ù„Ù‰ %{value}."
+  text_time_logged_by_changeset: "ØªÙ… ØªØ·Ø¨ÙŠÙ‚ Ø§Ù„ØªØºÙŠØ±Ø§Øª Ø§Ù„Ù…Ø¹ÙŠÙ†Ø© Ø¹Ù„Ù‰  %{value}."
+  text_issues_destroy_confirmation: Ù‡Ù„ Ø§Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø­Ø°Ù Ø§Ù„Ø¨Ù†ÙˆØ¯ Ø§Ù„Ù…Ø¸Ù„Ù„Ø©ØŸ'
+  text_issues_destroy_descendants_confirmation: "Ø³ÙˆÙ ÙŠØ¤Ø¯ÙŠ Ù‡Ø°Ø§ Ø§Ù„Ù‰ Ø­Ø°Ù  %{count} Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ÙØ±Ø¹ÙŠØ© Ø§ÙŠØ¶Ø§."
+  text_time_entries_destroy_confirmation: "Ù‡Ù„ Ø§Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø±ØºØ¨ØªÙƒ ÙÙŠ Ø­Ø°Ù Ø§Ù„Ø§Ø¯Ø®Ø§Ù„Ø§Øª Ø§Ù„Ø²Ù…Ù†ÙŠØ© Ø§Ù„Ù…Ø­Ø¯Ø¯Ø©ØŸ"
+  text_select_project_modules: Ù‚Ù… Ø¨ØªØ­Ø¯ÙŠØ¯ Ø§Ù„ÙˆØ¶Ø¹ Ø§Ù„Ù…Ù†Ø§Ø³Ø¨ Ù„Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹:'
+  text_default_administrator_account_changed: ØªÙ… ØªØ¹Ø¯ÙŠÙ„ Ø§Ù„Ø§Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ© Ù„Ø­Ø³Ø§Ø¨ Ø§Ù„Ù…Ø¯ÙŠØ±
+  text_file_repository_writable: Ø§Ù„Ù…Ø±ÙÙ‚Ø§Øª Ù‚Ø§Ø¨Ù„Ø© Ù„Ù„ÙƒØªØ§Ø¨Ø©
+  text_plugin_assets_writable: Ø§Ù„Ø¯Ù„ÙŠÙ„ Ø§Ù„Ù…Ø³Ø§Ø¹Ø¯ Ù‚Ø§Ø¨Ù„ Ù„Ù„ÙƒØªØ§Ø¨Ø©
+  text_destroy_time_entries_question: " Ø³Ø§Ø¹Ø© Ø¹Ù„Ù‰ Ø§Ù„Ù‚Ø¶ÙŠØ© Ø§Ù„ØªÙŠ ØªÙˆØ¯ Ø­Ø°ÙÙ‡Ø§ØŒ Ù…Ø§Ø°Ø§ ØªØ±ÙŠØ¯ Ø§Ù† ØªÙØ¹Ù„ØŸ %{hours} ØªÙ… ØªØ«Ø¨ÙŠØª"
+  text_destroy_time_entries: Ù‚Ù… Ø¨Ø­Ø°Ù Ø§Ù„Ø³Ø§Ø¹Ø§Øª Ø§Ù„Ù…Ø³Ø¬Ù„Ø©
+  text_assign_time_entries_to_project: Ø«Ø¨Øª Ø§Ù„Ø³Ø§Ø¹Ø§Øª Ø§Ù„Ù…Ø³Ø¬Ù„Ø© Ø¹Ù„Ù‰ Ø§Ù„ØªÙ‚Ø±ÙŠØ±
+  text_reassign_time_entries: 'Ø§Ø¹Ø§Ø¯Ø© ØªØ«Ø¨ÙŠØª Ø§Ù„Ø³Ø§Ø¹Ø§Øª Ø§Ù„Ù…Ø³Ø¬Ù„Ø© Ù„Ù‡Ø°Ù‡ Ø§Ù„Ù‚Ø¶ÙŠØ©:'
+  text_user_wrote: "%{value} ÙƒØªØ¨:"
+  text_enumeration_destroy_question: "%{count} Ø§Ù„ÙƒØ§Ø¦Ù†Ø§Øª Ø§Ù„Ù…Ø¹Ù†ÙŠØ© Ù„Ù‡Ø°Ù‡ Ø§Ù„Ù‚ÙŠÙ…Ø©"
+  text_enumeration_category_reassign_to: Ø§Ø¹Ø§Ø¯Ø© ØªØ«Ø¨ÙŠØª Ø§Ù„ÙƒØ§Ø¦Ù†Ø§Øª Ø§Ù„ØªØ§Ù„ÙŠØ© Ù„Ù‡Ø°Ù‡ Ø§Ù„Ù‚ÙŠÙ…Ø©:'
+  text_email_delivery_not_configured: "Ù„Ù… ÙŠØªÙ… ØªØ³Ù„ÙŠÙ… Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ"
+  text_diff_truncated: '... Ù„Ù‚Ø¯ ØªÙ… Ø§Ù‚ØªØ·Ù„Ø¹ Ù‡Ø°Ø§ Ø§Ù„Ø¬Ø²Ø¡ Ù„Ø§Ù†Ù‡ ØªØ¬Ø§ÙˆØ² Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¨Ø¹Ø±Ø¶Ù‡'
+  text_custom_field_possible_values_info: 'Ø³Ø·Ø± Ù„ÙƒÙ„ Ù‚ÙŠÙ…Ø©'
+  text_wiki_page_nullify_children: "Ø§Ù„Ø§Ø­ØªÙØ§Ø¸ Ø¨ØµÙØ­Ø§Øª Ø§Ù„Ø·ÙÙ„ ÙƒØµÙØ­Ø§Øª Ø¬Ø°Ø±"
+  text_wiki_page_destroy_children: "Ø­Ø°Ù ØµÙØ­Ø§Øª Ø§Ù„Ø·ÙÙ„ ÙˆØ¬Ù…ÙŠØ¹ Ø£ÙˆÙ„Ø§Ø¯Ù‡Ù…"
+  text_wiki_page_reassign_children: "Ø¥Ø¹Ø§Ø¯Ø© ØªØ¹ÙŠÙŠÙ† ØµÙØ­Ø§Øª ØªØ§Ø¨Ø¹Ø© Ù„Ù‡Ø°Ù‡ Ø§Ù„ØµÙØ­Ø© Ø§Ù„Ø£ØµÙ„ÙŠØ©"
+  text_own_membership_delete_confirmation: "Ø§Ù†Øª Ø¹Ù„Ù‰ ÙˆØ´Ùƒ Ø¥Ø²Ø§Ù„Ø© Ø¨Ø¹Ø¶ Ø£Ùˆ ÙƒØ§ÙØ© Ø§Ù„Ø£Ø°ÙˆÙ†Ø§Øª Ø§Ù„Ø®Ø§ØµØ© Ø¨ÙƒØŒ Ù„Ù† ØªÙƒÙˆÙ† Ù‚Ø§Ø¯Ø±Ø§Ù‹ Ø¹Ù„Ù‰ ØªØ­Ø±ÙŠØ± Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ Ø¨Ø¹Ø¯ Ø°Ù„Ùƒ. Ù‡Ù„ Ø£Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø£Ù†Ùƒ ØªØ±ÙŠØ¯ Ø§Ù„Ù…ØªØ§Ø¨Ø¹Ø©ØŸ"
+  text_zoom_in: ØªØµØºÙŠØ±
+  text_zoom_out: ØªÙƒØ¨ÙŠØ±
+  text_warn_on_leaving_unsaved: "Ø§Ù„ØµÙØ­Ø© ØªØ­ØªÙˆÙŠ Ø¹Ù„Ù‰ Ù†Øµ ØºÙŠØ± Ù…Ø®Ø²Ù†ØŒ Ø³ÙˆÙ ÙŠÙÙ‚Ø¯ Ø§Ù„Ù†Øµ Ø§Ø°Ø§ ØªÙ… Ø§Ù„Ø®Ø±ÙˆØ¬ Ù…Ù† Ø§Ù„ØµÙØ­Ø©."
+  text_scm_path_encoding_note: "Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ: UTF-8"
+  text_git_repository_note: Ù…Ø³ØªÙˆØ¯Ø¹ ÙØ§Ø±Øº ÙˆÙ…Ø­Ù„ÙŠ
+  text_mercurial_repository_note: Ù…Ø³ØªÙˆØ¯Ø¹ Ù…Ø­Ù„ÙŠ
+  text_scm_command: Ø§Ù…Ø±
+  text_scm_command_version: Ø§ØµØ¯Ø§Ø±
+  text_scm_config: Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ø¹Ø§Ø¯Ø© ØªØ´ØºÙŠÙ„ Ø§Ù„ØªØ·Ø¨ÙŠÙ‚
+  text_scm_command_not_available: Ø§Ù„Ø§Ù…Ø± ØºÙŠØ± Ù…ØªÙˆÙØ±ØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ù‚Ù‚ Ù…Ù† Ù„ÙˆØ­Ø© Ø§Ù„ØªØ­ÙƒÙ…
+
+  default_role_manager: Ù…Ø¯ÙŠØ±
+  default_role_developer: Ù…Ø·ÙˆØ±
+  default_role_reporter: Ù…Ø±Ø§Ø³Ù„
+  default_tracker_bug: Ø§Ù„Ø´ÙˆØ§Ø¦Ø¨
+  default_tracker_feature: Ø®Ø§ØµÙŠØ©
+  default_tracker_support: Ø¯Ø¹Ù…
+  default_issue_status_new: Ø¬Ø¯ÙŠØ¯
+  default_issue_status_in_progress: Ø¬Ø§Ø±ÙŠ Ø§Ù„ØªØ­Ù…ÙŠÙ„
+  default_issue_status_resolved: Ø§Ù„Ø­Ù„
+  default_issue_status_feedback: Ø§Ù„ØªØºØ°ÙŠØ© Ø§Ù„Ø±Ø§Ø¬Ø¹Ø©
+  default_issue_status_closed: Ù…ØºÙ„Ù‚
+  default_issue_status_rejected: Ù…Ø±ÙÙˆØ¶
+  default_doc_category_user: Ù…Ø³ØªÙ†Ø¯Ø§Øª Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
+  default_doc_category_tech: Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª Ø§Ù„ØªÙ‚Ù†ÙŠØ©
+  default_priority_low: Ù‚Ù„ÙŠÙ„
+  default_priority_normal: Ø¹Ø§Ø¯ÙŠ
+  default_priority_high: Ø¹Ø§Ù„ÙŠ
+  default_priority_urgent: Ø·Ø§Ø±Ø¦
+  default_priority_immediate: Ù…Ø¨Ø§Ø´Ø±Ø©
+  default_activity_design: ØªØµÙ…ÙŠÙ…
+  default_activity_development: ØªØ·ÙˆÙŠØ±
+
+  enumeration_issue_priorities: Ø§Ù„Ø§ÙˆÙ„ÙˆÙŠØ§Øª
+  enumeration_doc_categories: ØªØµÙ†ÙŠÙ Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª
+  enumeration_activities: Ø§Ù„Ø§Ù†Ø´Ø·Ø©
+  enumeration_system_activity: Ù†Ø´Ø§Ø· Ø§Ù„Ù†Ø¸Ø§Ù…
+  description_filter: ÙÙ„ØªØ±Ø©
+  description_search: Ø­Ù‚Ù„ Ø§Ù„Ø¨Ø­Ø«
+  description_choose_project: Ù…Ø´Ø§Ø±ÙŠØ¹
+  description_project_scope: Ù…Ø¬Ø§Ù„ Ø§Ù„Ø¨Ø­Ø«
+  description_notes: Ù…Ù„Ø§Ø­Ø¸Ø§Øª
+  description_message_content: Ù…Ø­ØªÙˆÙŠØ§Øª Ø§Ù„Ø±Ø³Ø§Ù„Ø©
+  description_query_sort_criteria_attribute: Ù†ÙˆØ¹ Ø§Ù„ØªØ±ØªÙŠØ¨
+  description_query_sort_criteria_direction: Ø§ØªØ¬Ø§Ù‡ Ø§Ù„ØªØ±ØªÙŠØ¨
+  description_user_mail_notification: Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
+  description_available_columns: Ø§Ù„Ø§Ø¹Ù…Ø¯Ø© Ø§Ù„Ù…ØªÙˆÙØ±Ø©
+  description_selected_columns: Ø§Ù„Ø§Ø¹Ù…Ø¯Ø© Ø§Ù„Ù…Ø­Ø¯Ø¯Ø©
+  description_all_columns: ÙƒÙ„ Ø§Ù„Ø§Ø¹Ù…Ø¯Ø©
+  description_issue_category_reassign: Ø§Ø®ØªØ± Ø§Ù„ØªØµÙ†ÙŠÙ
+  description_wiki_subpages_reassign: Ø§Ø®ØªØ± ØµÙØ­Ø© Ø¬Ø¯ÙŠØ¯Ø©
+  description_date_range_list: Ø§Ø®ØªØ± Ø§Ù„Ù…Ø¬Ø§Ù„ Ù…Ù† Ø§Ù„Ù‚Ø§Ø¦Ù…Ø©
+  description_date_range_interval: Ø§Ø®ØªØ± Ø§Ù„Ù…Ø¯Ø© Ø¹Ù† Ø·Ø±ÙŠÙ‚ Ø§Ø®ØªÙŠØ§Ø± ØªØ§Ø±ÙŠØ® Ø§Ù„Ø¨Ø¯Ø§ÙŠØ© ÙˆØ§Ù„Ù†Ù‡Ø§ÙŠØ©
+  description_date_from: Ø§Ø¯Ø®Ù„ ØªØ§Ø±ÙŠØ® Ø§Ù„Ø¨Ø¯Ø§ÙŠØ©
+  description_date_to: Ø§Ø¯Ø®Ù„ ØªØ§Ø±ÙŠØ® Ø§Ù„Ø§Ù†ØªÙ‡Ø§Ø¡
+  text_rmagick_available: RMagick available (optional)
+  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
+  text_repository_usernames_mapping: |-
+    Select or update the Redmine user mapped to each username found in the repository log.
+    Users with the same Redmine and repository username or email are automatically mapped.
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 Ù‚Ø¶ÙŠØ©
+    one:   1 Ù‚Ø¶ÙŠØ©
+    other: "%{count} Ù‚Ø¶Ø§ÙŠØ§"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: Ø¬Ù…ÙŠØ¹
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: ÙŠØ´Ø§Ø±Ùƒ
+  label_cross_project_tree: Ù…Ø¹ Ø´Ø¬Ø±Ø© Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
+  label_cross_project_hierarchy: Ù…Ø¹ Ø§Ù„ØªØ³Ù„Ø³Ù„ Ø§Ù„Ù‡Ø±Ù…ÙŠ Ù„Ù„Ù…Ø´Ø±ÙˆØ¹
+  label_cross_project_system: Ù…Ø¹ Ø¬Ù…ÙŠØ¹ Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ø§Ù„Ø¥Ø¬Ù…Ø§Ù„ÙŠ
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4b/4b8ff24938a4dd7deed4f9307f87afc0e6c1ff11.svn-base
--- /dev/null
+++ b/.svn/pristine/4b/4b8ff24938a4dd7deed4f9307f87afc0e6c1ff11.svn-base
@@ -0,0 +1,31 @@
+<div class="contextual">
+<%= link_to l(:label_auth_source_new), {:action => 'new'}, :class => 'icon icon-add' %>
+</div>
+
+<h2><%=l(:label_auth_source_plural)%></h2>
+
+<table class="list">
+  <thead><tr>
+    <th><%=l(:field_name)%></th>
+    <th><%=l(:field_type)%></th>
+    <th><%=l(:field_host)%></th>
+    <th><%=l(:label_user_plural)%></th>
+    <th></th>
+  </tr></thead>
+  <tbody>
+<% for source in @auth_sources %>
+  <tr id="auth-source-<%= source.id %>" class="<%= cycle("odd", "even") %>">
+    <td><%= link_to(h(source.name), :action => 'edit', :id => source)%></td>
+    <td align="center"><%= h source.auth_method_name %></td>
+    <td align="center"><%= h source.host %></td>
+    <td align="center"><%= h source.users.count %></td>
+    <td class="buttons">
+      <%= link_to l(:button_test), try_connection_auth_source_path(source), :class => 'icon icon-test' %>
+      <%= delete_link auth_source_path(source) %>
+    </td>
+  </tr>
+<% end %>
+  </tbody>
+</table>
+
+<p class="pagination"><%= pagination_links_full @auth_source_pages %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4b/4b9d105a6ddf9e2913feb748f35b6ced3a593557.svn-base
--- a/.svn/pristine/4b/4b9d105a6ddf9e2913feb748f35b6ced3a593557.svn-base
+++ /dev/null
@@ -1,1045 +0,0 @@
-# Spanish translations for Rails
-# by Francisco Fernando GarcÃ­a Nieto (ffgarcianieto@gmail.com)
-# Redmine spanish translation: 
-# by J. Cayetano Delgado (Cayetano _dot_ Delgado _at_ ioko _dot_ com)
-
-es:
-  number:
-    # Used in number_with_delimiter()
-    # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
-    format:
-      # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
-      separator: "," 
-      # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
-      delimiter: "." 
-      # Number of decimals, behind the separator (1 with a precision of 2 gives: 1.00)
-      precision: 3
-
-    # Used in number_to_currency()
-    currency:
-      format:
-        # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
-        format: "%n %u" 
-        unit: "â‚¬" 
-        # These three are to override number.format and are optional
-        separator: "," 
-        delimiter: "." 
-        precision: 2
-
-    # Used in number_to_percentage()
-    percentage:
-      format:
-        # These three are to override number.format and are optional
-        # separator: 
-        delimiter: "" 
-        # precision: 
-
-    # Used in number_to_precision()
-    precision:
-      format:
-        # These three are to override number.format and are optional
-        # separator:
-        delimiter: "" 
-        # precision:
-
-    # Used in number_to_human_size()
-    human:
-      format:
-        # These three are to override number.format and are optional
-        # separator: 
-        delimiter: "" 
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
-  datetime:
-    distance_in_words:
-      half_a_minute: "medio minuto" 
-      less_than_x_seconds:
-        one:  "menos de 1 segundo" 
-        other: "menos de %{count} segundos"
-      x_seconds:
-        one:  "1 segundo" 
-        other: "%{count} segundos" 
-      less_than_x_minutes:
-        one:  "menos de 1 minuto" 
-        other: "menos de %{count} minutos" 
-      x_minutes:
-        one:  "1 minuto" 
-        other: "%{count} minutos" 
-      about_x_hours:
-        one:  "alrededor de 1 hora" 
-        other: "alrededor de %{count} horas" 
-      x_days:
-        one:  "1 dÃ­a" 
-        other: "%{count} dÃ­as" 
-      about_x_months:
-        one:  "alrededor de 1 mes" 
-        other: "alrededor de %{count} meses" 
-      x_months:
-        one:  "1 mes" 
-        other: "%{count} meses" 
-      about_x_years:
-        one:  "alrededor de 1 aÃ±o" 
-        other: "alrededor de %{count} aÃ±os" 
-      over_x_years:
-        one:  "mÃ¡s de 1 aÃ±o" 
-        other: "mÃ¡s de %{count} aÃ±os" 
-      almost_x_years:
-        one:   "casi 1 aÃ±o"
-        other: "casi %{count} aÃ±os"
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:   "no se pudo guardar este %{model} porque se encontrÃ³ 1 error" 
-          other:  "no se pudo guardar este %{model} porque se encontraron %{count} errores" 
-        # The variable :count is also available
-        body: "Se encontraron problemas con los siguientes campos:" 
-
-      # The values :model, :attribute and :value are always available for interpolation
-      # The value :count is available when applicable. Can be used for pluralization.
-      messages:
-        inclusion: "no estÃ¡ incluido en la lista" 
-        exclusion: "estÃ¡ reservado" 
-        invalid: "no es vÃ¡lido" 
-        confirmation: "no coincide con la confirmaciÃ³n"
-        accepted: "debe ser aceptado"
-        empty: "no puede estar vacÃ­o"
-        blank: "no puede estar en blanco"
-        too_long: "es demasiado largo (%{count} caracteres mÃ¡ximo)"
-        too_short: "es demasiado corto (%{count} caracteres mÃ­nimo)"
-        wrong_length: "no tiene la longitud correcta (%{count} caracteres exactos)"
-        taken: "ya estÃ¡ en uso"
-        not_a_number: "no es un nÃºmero"
-        greater_than: "debe ser mayor que %{count}"
-        greater_than_or_equal_to: "debe ser mayor que o igual a %{count}"
-        equal_to: "debe ser igual a %{count}"
-        less_than: "debe ser menor que %{count}"
-        less_than_or_equal_to: "debe ser menor que o igual a %{count}"
-        odd: "debe ser impar"
-        even: "debe ser par"
-        greater_than_start_date: "debe ser posterior a la fecha de comienzo"
-        not_same_project: "no pertenece al mismo proyecto"
-        circular_dependency: "Esta relaciÃ³n podrÃ­a crear una dependencia circular"
-        cant_link_an_issue_with_a_descendant: "Esta peticiÃ³n no puede ser ligada a una de estas tareas"
-
-        # Append your own errors here or at the model/attributes scope.
-
-      models:
-        # Overrides default messages
-
-      attributes:
-        # Overrides model and default messages.
-
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y-%m-%d" 
-      short: "%d de %b" 
-      long: "%d de %B de %Y" 
-
-    day_names: [Domingo, Lunes, Martes, MiÃ©rcoles, Jueves, Viernes, SÃ¡bado]
-    abbr_day_names: [Dom, Lun, Mar, Mie, Jue, Vie, Sab]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Setiembre, Octubre, Noviembre, Diciembre]
-    abbr_month_names: [~, Ene, Feb, Mar, Abr, May, Jun, Jul, Ago, Set, Oct, Nov, Dic]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%A, %d de %B de %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d de %b %H:%M" 
-      long: "%d de %B de %Y %H:%M" 
-    am: "am" 
-    pm: "pm" 
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "y"
-
-  actionview_instancetag_blank_option: Por favor seleccione
-  
-  button_activate: Activar
-  button_add: AÃ±adir
-  button_annotate: Anotar
-  button_apply: Aceptar
-  button_archive: Archivar
-  button_back: AtrÃ¡s
-  button_cancel: Cancelar
-  button_change: Cambiar
-  button_change_password: Cambiar contraseÃ±a
-  button_check_all: Seleccionar todo
-  button_clear: Anular
-  button_configure: Configurar
-  button_copy: Copiar
-  button_create: Crear
-  button_delete: Borrar
-  button_download: Descargar
-  button_edit: Modificar
-  button_list: Listar
-  button_lock: Bloquear
-  button_log_time: Tiempo dedicado
-  button_login: ConexiÃ³n
-  button_move: Mover
-  button_quote: Citar
-  button_rename: Renombrar
-  button_reply: Responder
-  button_reset: Reestablecer
-  button_rollback: Volver a esta versiÃ³n
-  button_save: Guardar
-  button_sort: Ordenar
-  button_submit: Aceptar
-  button_test: Probar
-  button_unarchive: Desarchivar
-  button_uncheck_all: No seleccionar nada
-  button_unlock: Desbloquear
-  button_unwatch: No monitorizar
-  button_update: Actualizar
-  button_view: Ver
-  button_watch: Monitorizar
-  default_activity_design: DiseÃ±o
-  default_activity_development: Desarrollo
-  default_doc_category_tech: DocumentaciÃ³n tÃ©cnica
-  default_doc_category_user: DocumentaciÃ³n de usuario
-  default_issue_status_in_progress: En curso
-  default_issue_status_closed: Cerrada
-  default_issue_status_feedback: Comentarios
-  default_issue_status_new: Nueva
-  default_issue_status_rejected: Rechazada
-  default_issue_status_resolved: Resuelta
-  default_priority_high: Alta
-  default_priority_immediate: Inmediata
-  default_priority_low: Baja
-  default_priority_normal: Normal
-  default_priority_urgent: Urgente
-  default_role_developer: Desarrollador
-  default_role_manager: Jefe de proyecto
-  default_role_reporter: Informador
-  default_tracker_bug: Errores
-  default_tracker_feature: Tareas
-  default_tracker_support: Soporte
-  enumeration_activities: Actividades (tiempo dedicado)
-  enumeration_doc_categories: CategorÃ­as del documento
-  enumeration_issue_priorities: Prioridad de las peticiones
-  error_can_t_load_default_data: "No se ha podido cargar la configuraciÃ³n por defecto: %{value}"
-  error_issue_not_found_in_project: 'La peticiÃ³n no se encuentra o no estÃ¡ asociada a este proyecto'
-  error_scm_annotate: "No existe la entrada o no ha podido ser anotada"
-  error_scm_annotate_big_text_file: "La entrada no puede anotarse, al superar el tamaÃ±o mÃ¡ximo para ficheros de texto."
-  error_scm_command_failed: "Se produjo un error al acceder al repositorio: %{value}"
-  error_scm_not_found: "La entrada y/o la revisiÃ³n no existe en el repositorio."
-  field_account: Cuenta
-  field_activity: Actividad
-  field_admin: Administrador
-  field_assignable: Se pueden asignar peticiones a este perfil
-  field_assigned_to: Asignado a
-  field_attr_firstname: Cualidad del nombre
-  field_attr_lastname: Cualidad del apellido
-  field_attr_login: Cualidad del identificador
-  field_attr_mail: Cualidad del Email
-  field_auth_source: Modo de identificaciÃ³n
-  field_author: Autor
-  field_base_dn: DN base
-  field_category: CategorÃ­a
-  field_column_names: Columnas
-  field_comments: Comentario
-  field_comments_sorting: Mostrar comentarios
-  field_created_on: Creado
-  field_default_value: Estado por defecto
-  field_delay: Retraso
-  field_description: DescripciÃ³n
-  field_done_ratio: "% Realizado"
-  field_downloads: Descargas
-  field_due_date: Fecha fin
-  field_effective_date: Fecha
-  field_estimated_hours: Tiempo estimado
-  field_field_format: Formato
-  field_filename: Fichero
-  field_filesize: TamaÃ±o
-  field_firstname: Nombre
-  field_fixed_version: VersiÃ³n prevista
-  field_hide_mail: Ocultar mi direcciÃ³n de correo
-  field_homepage: Sitio web
-  field_host: AnfitriÃ³n
-  field_hours: Horas
-  field_identifier: Identificador
-  field_is_closed: PeticiÃ³n resuelta
-  field_is_default: Estado por defecto
-  field_is_filter: Usado como filtro
-  field_is_for_all: Para todos los proyectos
-  field_is_in_roadmap: Consultar las peticiones en la planificaciÃ³n
-  field_is_public: PÃºblico
-  field_is_required: Obligatorio
-  field_issue: PeticiÃ³n
-  field_issue_to: PeticiÃ³n relacionada
-  field_language: Idioma
-  field_last_login_on: Ãšltima conexiÃ³n
-  field_lastname: Apellido
-  field_login: Identificador
-  field_mail: Correo electrÃ³nico
-  field_mail_notification: Notificaciones por correo
-  field_max_length: Longitud mÃ¡xima
-  field_min_length: Longitud mÃ­nima
-  field_name: Nombre
-  field_new_password: Nueva contraseÃ±a
-  field_notes: Notas
-  field_onthefly: CreaciÃ³n del usuario "al vuelo"
-  field_parent: Proyecto padre
-  field_parent_title: PÃ¡gina padre
-  field_password: ContraseÃ±a
-  field_password_confirmation: ConfirmaciÃ³n
-  field_port: Puerto
-  field_possible_values: Valores posibles
-  field_priority: Prioridad
-  field_project: Proyecto
-  field_redirect_existing_links: Redireccionar enlaces existentes
-  field_regexp: ExpresiÃ³n regular
-  field_role: Perfil
-  field_searchable: Incluir en las bÃºsquedas
-  field_spent_on: Fecha
-  field_start_date: Fecha de inicio
-  field_start_page: PÃ¡gina principal
-  field_status: Estado
-  field_subject: Asunto
-  field_subproject: Proyecto secundario
-  field_summary: Resumen
-  field_time_zone: Zona horaria
-  field_title: TÃ­tulo
-  field_tracker: Tipo
-  field_type: Tipo
-  field_updated_on: Actualizado
-  field_url: URL
-  field_user: Usuario
-  field_value: Valor
-  field_version: VersiÃ³n
-  general_csv_decimal_separator: ','
-  general_csv_encoding: ISO-8859-15
-  general_csv_separator: ';'
-  general_first_day_of_week: '1'
-  general_lang_name: 'EspaÃ±ol'
-  general_pdf_encoding: UTF-8
-  general_text_No: 'No'
-  general_text_Yes: 'SÃ­'
-  general_text_no: 'no'
-  general_text_yes: 'sÃ­'
-  gui_validation_error: 1 error
-  gui_validation_error_plural: "%{count} errores"
-  label_activity: Actividad
-  label_add_another_file: AÃ±adir otro fichero
-  label_add_note: AÃ±adir una nota
-  label_added: aÃ±adido
-  label_added_time_by: "AÃ±adido por %{author} hace %{age}"
-  label_administration: AdministraciÃ³n
-  label_age: Edad
-  label_ago: hace
-  label_all: todos
-  label_all_time: todo el tiempo
-  label_all_words: Todas las palabras
-  label_and_its_subprojects: "%{value} y proyectos secundarios"
-  label_applied_status: Aplicar estado
-  label_assigned_to_me_issues: Peticiones que me estÃ¡n asignadas
-  label_associated_revisions: Revisiones asociadas
-  label_attachment: Fichero
-  label_attachment_delete: Borrar el fichero
-  label_attachment_new: Nuevo fichero
-  label_attachment_plural: Ficheros
-  label_attribute: Cualidad
-  label_attribute_plural: Cualidades
-  label_auth_source: Modo de autenticaciÃ³n
-  label_auth_source_new: Nuevo modo de autenticaciÃ³n
-  label_auth_source_plural: Modos de autenticaciÃ³n
-  label_authentication: AutenticaciÃ³n
-  label_blocked_by: bloqueado por
-  label_blocks: bloquea a
-  label_board: Foro
-  label_board_new: Nuevo foro
-  label_board_plural: Foros
-  label_boolean: Booleano
-  label_browse: Hojear
-  label_bulk_edit_selected_issues: Editar las peticiones seleccionadas
-  label_calendar: Calendario
-  label_change_plural: Cambios
-  label_change_properties: Cambiar propiedades
-  label_change_status: Cambiar el estado
-  label_change_view_all: Ver todos los cambios
-  label_changes_details: Detalles de todos los cambios
-  label_changeset_plural: Cambios
-  label_chronological_order: En orden cronolÃ³gico
-  label_closed_issues: cerrada
-  label_closed_issues_plural: cerradas
-  label_x_open_issues_abbr_on_total:
-    zero:  0 abiertas / %{total}
-    one:   1 abierta / %{total}
-    other: "%{count} abiertas / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 abiertas
-    one:   1 abierta
-    other: "%{count} abiertas"
-  label_x_closed_issues_abbr:
-    zero:  0 cerradas
-    one:   1 cerrada
-    other: "%{count} cerradas"
-  label_comment: Comentario
-  label_comment_add: AÃ±adir un comentario
-  label_comment_added: Comentario aÃ±adido
-  label_comment_delete: Borrar comentarios
-  label_comment_plural: Comentarios
-  label_x_comments:
-    zero: sin comentarios
-    one: 1 comentario
-    other: "%{count} comentarios"
-  label_commits_per_author: Commits por autor
-  label_commits_per_month: Commits por mes
-  label_confirmation: ConfirmaciÃ³n
-  label_contains: contiene
-  label_copied: copiado
-  label_copy_workflow_from: Copiar flujo de trabajo desde
-  label_current_status: Estado actual
-  label_current_version: VersiÃ³n actual
-  label_custom_field: Campo personalizado
-  label_custom_field_new: Nuevo campo personalizado
-  label_custom_field_plural: Campos personalizados
-  label_date: Fecha
-  label_date_from: Desde
-  label_date_range: Rango de fechas
-  label_date_to: Hasta
-  label_day_plural: dÃ­as
-  label_default: Por defecto
-  label_default_columns: Columnas por defecto
-  label_deleted: suprimido
-  label_details: Detalles
-  label_diff_inline: en lÃ­nea
-  label_diff_side_by_side: cara a cara
-  label_disabled: deshabilitado
-  label_display_per_page: "Por pÃ¡gina: %{value}"
-  label_document: Documento
-  label_document_added: Documento aÃ±adido
-  label_document_new: Nuevo documento
-  label_document_plural: Documentos
-  label_download: "%{count} Descarga"
-  label_download_plural: "%{count} Descargas"
-  label_downloads_abbr: D/L
-  label_duplicated_by: duplicada por
-  label_duplicates: duplicada de
-  label_end_to_end: fin a fin
-  label_end_to_start: fin a principio
-  label_enumeration_new: Nuevo valor
-  label_enumerations: Listas de valores
-  label_environment: Entorno
-  label_equals: igual
-  label_example: Ejemplo
-  label_export_to: 'Exportar a:'
-  label_f_hour: "%{value} hora"
-  label_f_hour_plural: "%{value} horas"
-  label_feed_plural: Feeds
-  label_feeds_access_key_created_on: "Clave de acceso por RSS creada hace %{value}"
-  label_file_added: Fichero aÃ±adido
-  label_file_plural: Archivos
-  label_filter_add: AÃ±adir el filtro
-  label_filter_plural: Filtros
-  label_float: Flotante
-  label_follows: posterior a
-  label_gantt: Gantt
-  label_general: General
-  label_generate_key: Generar clave
-  label_help: Ayuda
-  label_history: HistÃ³rico
-  label_home: Inicio
-  label_in: en
-  label_in_less_than: en menos que
-  label_in_more_than: en mÃ¡s que
-  label_incoming_emails: Correos entrantes
-  label_index_by_date: Ãndice por fecha
-  label_index_by_title: Ãndice por tÃ­tulo
-  label_information: InformaciÃ³n
-  label_information_plural: InformaciÃ³n
-  label_integer: NÃºmero
-  label_internal: Interno
-  label_issue: PeticiÃ³n
-  label_issue_added: PeticiÃ³n aÃ±adida
-  label_issue_category: CategorÃ­a de las peticiones
-  label_issue_category_new: Nueva categorÃ­a
-  label_issue_category_plural: CategorÃ­as de las peticiones
-  label_issue_new: Nueva peticiÃ³n
-  label_issue_plural: Peticiones
-  label_issue_status: Estado de la peticiÃ³n
-  label_issue_status_new: Nuevo estado
-  label_issue_status_plural: Estados de las peticiones
-  label_issue_tracking: Peticiones
-  label_issue_updated: PeticiÃ³n actualizada
-  label_issue_view_all: Ver todas las peticiones
-  label_issue_watchers: Seguidores
-  label_issues_by: "Peticiones por %{value}"
-  label_jump_to_a_project: Ir al proyecto...
-  label_language_based: Basado en el idioma
-  label_last_changes: "Ãºltimos %{count} cambios"
-  label_last_login: Ãšltima conexiÃ³n
-  label_last_month: Ãºltimo mes
-  label_last_n_days: "Ãºltimos %{count} dÃ­as"
-  label_last_week: Ãºltima semana
-  label_latest_revision: Ãšltima revisiÃ³n
-  label_latest_revision_plural: Ãšltimas revisiones
-  label_ldap_authentication: AutenticaciÃ³n LDAP
-  label_less_than_ago: hace menos de
-  label_list: Lista
-  label_loading: Cargando...
-  label_logged_as: Conectado como
-  label_login: ConexiÃ³n
-  label_logout: DesconexiÃ³n
-  label_max_size: TamaÃ±o mÃ¡ximo
-  label_me: yo mismo
-  label_member: Miembro
-  label_member_new: Nuevo miembro
-  label_member_plural: Miembros
-  label_message_last: Ãšltimo mensaje
-  label_message_new: Nuevo mensaje
-  label_message_plural: Mensajes
-  label_message_posted: Mensaje aÃ±adido
-  label_min_max_length: Longitud mÃ­n - mÃ¡x
-  label_modification: "%{count} modificaciÃ³n"
-  label_modification_plural: "%{count} modificaciones"
-  label_modified: modificado
-  label_module_plural: MÃ³dulos
-  label_month: Mes
-  label_months_from: meses de
-  label_more: MÃ¡s
-  label_more_than_ago: hace mÃ¡s de
-  label_my_account: Mi cuenta
-  label_my_page: Mi pÃ¡gina
-  label_my_projects: Mis proyectos
-  label_new: Nuevo
-  label_new_statuses_allowed: Nuevos estados autorizados
-  label_news: Noticia
-  label_news_added: Noticia aÃ±adida
-  label_news_latest: Ãšltimas noticias
-  label_news_new: Nueva noticia
-  label_news_plural: Noticias
-  label_news_view_all: Ver todas las noticias
-  label_next: Siguiente
-  label_no_change_option: (Sin cambios)
-  label_no_data: NingÃºn dato disponible
-  label_nobody: nadie
-  label_none: ninguno
-  label_not_contains: no contiene
-  label_not_equals: no igual
-  label_open_issues: abierta
-  label_open_issues_plural: abiertas
-  label_optional_description: DescripciÃ³n opcional
-  label_options: Opciones
-  label_overall_activity: Actividad global
-  label_overview: Vistazo
-  label_password_lost: Â¿Olvidaste la contraseÃ±a?
-  label_per_page: Por pÃ¡gina
-  label_permissions: Permisos
-  label_permissions_report: Informe de permisos
-  label_personalize_page: Personalizar esta pÃ¡gina
-  label_planning: PlanificaciÃ³n
-  label_please_login: ConexiÃ³n
-  label_plugins: Extensiones
-  label_precedes: anterior a
-  label_preferences: Preferencias
-  label_preview: Previsualizar
-  label_previous: Anterior
-  label_project: Proyecto
-  label_project_all: Todos los proyectos
-  label_project_latest: Ãšltimos proyectos
-  label_project_new: Nuevo proyecto
-  label_project_plural: Proyectos
-  label_x_projects:
-    zero:  sin proyectos
-    one:   1 proyecto
-    other: "%{count} proyectos"
-  label_public_projects: Proyectos pÃºblicos
-  label_query: Consulta personalizada
-  label_query_new: Nueva consulta
-  label_query_plural: Consultas personalizadas
-  label_read: Leer...
-  label_register: Registrar
-  label_registered_on: Inscrito el
-  label_registration_activation_by_email: activaciÃ³n de cuenta por correo
-  label_registration_automatic_activation: activaciÃ³n automÃ¡tica de cuenta
-  label_registration_manual_activation: activaciÃ³n manual de cuenta
-  label_related_issues: Peticiones relacionadas
-  label_relates_to: relacionada con
-  label_relation_delete: Eliminar relaciÃ³n
-  label_relation_new: Nueva relaciÃ³n
-  label_renamed: renombrado
-  label_reply_plural: Respuestas
-  label_report: Informe
-  label_report_plural: Informes
-  label_reported_issues: Peticiones registradas por mÃ­
-  label_repository: Repositorio
-  label_repository_plural: Repositorios
-  label_result_plural: Resultados
-  label_reverse_chronological_order: En orden cronolÃ³gico inverso
-  label_revision: RevisiÃ³n
-  label_revision_plural: Revisiones
-  label_roadmap: PlanificaciÃ³n
-  label_roadmap_due_in: "Finaliza en %{value}"
-  label_roadmap_no_issues: No hay peticiones para esta versiÃ³n
-  label_roadmap_overdue: "%{value} tarde"
-  label_role: Perfil
-  label_role_and_permissions: Perfiles y permisos
-  label_role_new: Nuevo perfil
-  label_role_plural: Perfiles
-  label_scm: SCM
-  label_search: BÃºsqueda
-  label_search_titles_only: Buscar sÃ³lo en tÃ­tulos
-  label_send_information: Enviar informaciÃ³n de la cuenta al usuario
-  label_send_test_email: Enviar un correo de prueba
-  label_settings: ConfiguraciÃ³n
-  label_show_completed_versions: Muestra las versiones terminadas
-  label_sort_by: "Ordenar por %{value}"
-  label_sort_higher: Subir
-  label_sort_highest: Primero
-  label_sort_lower: Bajar
-  label_sort_lowest: Ãšltimo
-  label_spent_time: Tiempo dedicado
-  label_start_to_end: principio a fin
-  label_start_to_start: principio a principio
-  label_statistics: EstadÃ­sticas
-  label_stay_logged_in: Recordar conexiÃ³n
-  label_string: Texto
-  label_subproject_plural: Proyectos secundarios
-  label_text: Texto largo
-  label_theme: Tema
-  label_this_month: este mes
-  label_this_week: esta semana
-  label_this_year: este aÃ±o
-  label_time_tracking: Control de tiempo
-  label_today: hoy
-  label_topic_plural: Temas
-  label_total: Total
-  label_tracker: Tipo
-  label_tracker_new: Nuevo tipo
-  label_tracker_plural: Tipos de peticiones
-  label_updated_time: "Actualizado hace %{value}"
-  label_updated_time_by: "Actualizado por %{author} hace %{age}"
-  label_used_by: Utilizado por
-  label_user: Usuario
-  label_user_activity: "Actividad de %{value}"
-  label_user_mail_no_self_notified: "No quiero ser avisado de cambios hechos por mÃ­"
-  label_user_mail_option_all: "Para cualquier evento en todos mis proyectos"
-  label_user_mail_option_selected: "Para cualquier evento de los proyectos seleccionados..."
-  label_user_new: Nuevo usuario
-  label_user_plural: Usuarios
-  label_version: VersiÃ³n
-  label_version_new: Nueva versiÃ³n
-  label_version_plural: Versiones
-  label_view_diff: Ver diferencias
-  label_view_revisions: Ver las revisiones
-  label_watched_issues: Peticiones monitorizadas
-  label_week: Semana
-  label_wiki: Wiki
-  label_wiki_edit: ModificaciÃ³n Wiki
-  label_wiki_edit_plural: Modificaciones Wiki
-  label_wiki_page: PÃ¡gina Wiki
-  label_wiki_page_plural: PÃ¡ginas Wiki
-  label_workflow: Flujo de trabajo
-  label_year: AÃ±o
-  label_yesterday: ayer
-  mail_body_account_activation_request: "Se ha inscrito un nuevo usuario (%{value}). La cuenta estÃ¡ pendiende de aprobaciÃ³n:"
-  mail_body_account_information: InformaciÃ³n sobre su cuenta
-  mail_body_account_information_external: "Puede usar su cuenta %{value} para conectarse."
-  mail_body_lost_password: 'Para cambiar su contraseÃ±a, haga clic en el siguiente enlace:'
-  mail_body_register: 'Para activar su cuenta, haga clic en el siguiente enlace:'
-  mail_body_reminder: "%{count} peticion(es) asignadas a tÃ­ finalizan en los prÃ³ximos %{days} dÃ­as:"
-  mail_subject_account_activation_request: "PeticiÃ³n de activaciÃ³n de cuenta %{value}"
-  mail_subject_lost_password: "Tu contraseÃ±a del %{value}"
-  mail_subject_register: "ActivaciÃ³n de la cuenta del %{value}"
-  mail_subject_reminder: "%{count} peticion(es) finalizan en los prÃ³ximos %{days} dÃ­as"
-  notice_account_activated: Su cuenta ha sido activada. Ya puede conectarse.
-  notice_account_invalid_creditentials: Usuario o contraseÃ±a invÃ¡lido.
-  notice_account_lost_email_sent: Se le ha enviado un correo con instrucciones para elegir una nueva contraseÃ±a.
-  notice_account_password_updated: ContraseÃ±a modificada correctamente.
-  notice_account_pending: "Su cuenta ha sido creada y estÃ¡ pendiende de la aprobaciÃ³n por parte del administrador."
-  notice_account_register_done: Cuenta creada correctamente. Para activarla, haga clic sobre el enlace que le ha sido enviado por correo.
-  notice_account_unknown_email: Usuario desconocido.
-  notice_account_updated: Cuenta actualizada correctamente.
-  notice_account_wrong_password: ContraseÃ±a incorrecta.
-  notice_can_t_change_password: Esta cuenta utiliza una fuente de autenticaciÃ³n externa. No es posible cambiar la contraseÃ±a.
-  notice_default_data_loaded: ConfiguraciÃ³n por defecto cargada correctamente.
-  notice_email_error: "Ha ocurrido un error mientras enviando el correo (%{value})"
-  notice_email_sent: "Se ha enviado un correo a %{value}"
-  notice_failed_to_save_issues: "Imposible grabar %{count} peticion(es) de %{total} seleccionada(s): %{ids}."
-  notice_feeds_access_key_reseted: Su clave de acceso para RSS ha sido reiniciada.
-  notice_file_not_found: La pÃ¡gina a la que intenta acceder no existe.
-  notice_locking_conflict: Los datos han sido modificados por otro usuario.
-  notice_no_issue_selected: "Ninguna peticiÃ³n seleccionada. Por favor, compruebe la peticiÃ³n que quiere modificar"
-  notice_not_authorized: No tiene autorizaciÃ³n para acceder a esta pÃ¡gina.
-  notice_successful_connection: ConexiÃ³n correcta.
-  notice_successful_create: CreaciÃ³n correcta.
-  notice_successful_delete: Borrado correcto.
-  notice_successful_update: ModificaciÃ³n correcta.
-  notice_unable_delete_version: No se puede borrar la versiÃ³n
-  permission_add_issue_notes: AÃ±adir notas
-  permission_add_issue_watchers: AÃ±adir seguidores
-  permission_add_issues: AÃ±adir peticiones
-  permission_add_messages: Enviar mensajes
-  permission_browse_repository: Hojear repositiorio
-  permission_comment_news: Comentar noticias
-  permission_commit_access: Acceso de escritura
-  permission_delete_issues: Borrar peticiones
-  permission_delete_messages: Borrar mensajes
-  permission_delete_own_messages: Borrar mensajes propios
-  permission_delete_wiki_pages: Borrar pÃ¡ginas wiki
-  permission_delete_wiki_pages_attachments: Borrar ficheros
-  permission_edit_issue_notes: Modificar notas
-  permission_edit_issues: Modificar peticiones
-  permission_edit_messages: Modificar mensajes
-  permission_edit_own_issue_notes: Modificar notas propias
-  permission_edit_own_messages: Editar mensajes propios
-  permission_edit_own_time_entries: Modificar tiempos dedicados propios
-  permission_edit_project: Modificar proyecto
-  permission_edit_time_entries: Modificar tiempos dedicados
-  permission_edit_wiki_pages: Modificar pÃ¡ginas wiki
-  permission_log_time: Anotar tiempo dedicado
-  permission_manage_boards: Administrar foros
-  permission_manage_categories: Administrar categorÃ­as de peticiones
-  permission_manage_documents: Administrar documentos
-  permission_manage_files: Administrar ficheros
-  permission_manage_issue_relations: Administrar relaciÃ³n con otras peticiones
-  permission_manage_members: Administrar miembros
-  permission_manage_news: Administrar noticias
-  permission_manage_public_queries: Administrar consultas pÃºblicas
-  permission_manage_repository: Administrar repositorio
-  permission_manage_versions: Administrar versiones
-  permission_manage_wiki: Administrar wiki
-  permission_move_issues: Mover peticiones
-  permission_protect_wiki_pages: Proteger pÃ¡ginas wiki
-  permission_rename_wiki_pages: Renombrar pÃ¡ginas wiki
-  permission_save_queries: Grabar consultas
-  permission_select_project_modules: Seleccionar mÃ³dulos del proyecto
-  permission_view_calendar: Ver calendario
-  permission_view_changesets: Ver cambios
-  permission_view_documents: Ver documentos
-  permission_view_files: Ver ficheros
-  permission_view_gantt: Ver diagrama de Gantt
-  permission_view_issue_watchers: Ver lista de seguidores
-  permission_view_messages: Ver mensajes
-  permission_view_time_entries: Ver tiempo dedicado
-  permission_view_wiki_edits: Ver histÃ³rico del wiki
-  permission_view_wiki_pages: Ver wiki
-  project_module_boards: Foros
-  project_module_documents: Documentos
-  project_module_files: Ficheros
-  project_module_issue_tracking: Peticiones
-  project_module_news: Noticias
-  project_module_repository: Repositorio
-  project_module_time_tracking: Control de tiempo
-  project_module_wiki: Wiki
-  setting_activity_days_default: DÃ­as a mostrar en la actividad de proyecto
-  setting_app_subtitle: SubtÃ­tulo de la aplicaciÃ³n
-  setting_app_title: TÃ­tulo de la aplicaciÃ³n
-  setting_attachment_max_size: TamaÃ±o mÃ¡ximo del fichero
-  setting_autofetch_changesets: Autorellenar los commits del repositorio
-  setting_autologin: ConexiÃ³n automÃ¡tica
-  setting_bcc_recipients: Ocultar las copias de carbÃ³n (bcc)
-  setting_commit_fix_keywords: Palabras clave para la correcciÃ³n
-  setting_commit_ref_keywords: Palabras clave para la referencia
-  setting_cross_project_issue_relations: Permitir relacionar peticiones de distintos proyectos
-  setting_date_format: Formato de fecha
-  setting_default_language: Idioma por defecto
-  setting_default_projects_public: Los proyectos nuevos son pÃºblicos por defecto
-  setting_diff_max_lines_displayed: NÃºmero mÃ¡ximo de diferencias mostradas
-  setting_display_subprojects_issues: Mostrar por defecto peticiones de proy. secundarios en el principal
-  setting_emails_footer: Pie de mensajes
-  setting_enabled_scm: Activar SCM
-  setting_feeds_limit: LÃ­mite de contenido para sindicaciÃ³n
-  setting_gravatar_enabled: Usar iconos de usuario (Gravatar)
-  setting_host_name: Nombre y ruta del servidor
-  setting_issue_list_default_columns: Columnas por defecto para la lista de peticiones
-  setting_issues_export_limit: LÃ­mite de exportaciÃ³n de peticiones
-  setting_login_required: Se requiere identificaciÃ³n
-  setting_mail_from: Correo desde el que enviar mensajes
-  setting_mail_handler_api_enabled: Activar SW para mensajes entrantes
-  setting_mail_handler_api_key: Clave de la API
-  setting_per_page_options: Objetos por pÃ¡gina
-  setting_plain_text_mail: sÃ³lo texto plano (no HTML)
-  setting_protocol: Protocolo
-  setting_self_registration: Registro permitido
-  setting_sequential_project_identifiers: Generar identificadores de proyecto
-  setting_sys_api_enabled: Habilitar SW para la gestiÃ³n del repositorio
-  setting_text_formatting: Formato de texto
-  setting_time_format: Formato de hora
-  setting_user_format: Formato de nombre de usuario
-  setting_welcome_text: Texto de bienvenida
-  setting_wiki_compression: CompresiÃ³n del historial del Wiki
-  status_active: activo
-  status_locked: bloqueado
-  status_registered: registrado
-  text_are_you_sure: Â¿EstÃ¡ seguro?
-  text_assign_time_entries_to_project: Asignar las horas al proyecto
-  text_caracters_maximum: "%{count} caracteres como mÃ¡ximo."
-  text_caracters_minimum: "%{count} caracteres como mÃ­nimo."
-  text_comma_separated: MÃºltiples valores permitidos (separados por coma).
-  text_default_administrator_account_changed: Cuenta de administrador por defecto modificada
-  text_destroy_time_entries: Borrar las horas
-  text_destroy_time_entries_question: Existen %{hours} horas asignadas a la peticiÃ³n que quiere borrar. Â¿QuÃ© quiere hacer?
-  text_diff_truncated: '... Diferencia truncada por exceder el mÃ¡ximo tamaÃ±o visualizable.'
-  text_email_delivery_not_configured: "Las notificaciones estÃ¡n desactivadas porque el servidor de correo no estÃ¡ configurado.\nConfigure el servidor de SMTP en config/configuration.yml y reinicie la aplicaciÃ³n para activar los cambios."
-  text_enumeration_category_reassign_to: 'Reasignar al siguiente valor:'
-  text_enumeration_destroy_question: "%{count} objetos con este valor asignado."
-  text_file_repository_writable: Se puede escribir en el repositorio
-  text_issue_added: "PeticiÃ³n %{id} aÃ±adida por %{author}."
-  text_issue_category_destroy_assignments: Dejar las peticiones sin categorÃ­a
-  text_issue_category_destroy_question: "Algunas peticiones (%{count}) estÃ¡n asignadas a esta categorÃ­a. Â¿QuÃ© desea hacer?"
-  text_issue_category_reassign_to: Reasignar las peticiones a la categorÃ­a
-  text_issue_updated: "La peticiÃ³n %{id} ha sido actualizada por %{author}."
-  text_issues_destroy_confirmation: 'Â¿Seguro que quiere borrar las peticiones seleccionadas?'
-  text_issues_ref_in_commit_messages: Referencia y peticiÃ³n de correcciÃ³n en los mensajes
-  text_length_between: "Longitud entre %{min} y %{max} caracteres."
-  text_load_default_configuration: Cargar la configuraciÃ³n por defecto
-  text_min_max_length_info: 0 para ninguna restricciÃ³n
-  text_no_configuration_data: "TodavÃ­a no se han configurado perfiles, ni tipos, estados y flujo de trabajo asociado a peticiones. Se recomiendo encarecidamente cargar la configuraciÃ³n por defecto. Una vez cargada, podrÃ¡ modificarla."
-  text_project_destroy_confirmation: Â¿EstÃ¡s seguro de querer eliminar el proyecto?
-  text_project_identifier_info: 'Letras minÃºsculas (a-z), nÃºmeros y signos de puntuaciÃ³n permitidos.<br />Una vez guardado, el identificador no puede modificarse.'
-  text_reassign_time_entries: 'Reasignar las horas a esta peticiÃ³n:'
-  text_regexp_info: ej. ^[A-Z0-9]+$
-  text_repository_usernames_mapping: "Establezca la correspondencia entre los usuarios de Redmine y los presentes en el log del repositorio.\nLos usuarios con el mismo nombre o correo en Redmine y en el repositorio serÃ¡n asociados automÃ¡ticamente."
-  text_rmagick_available: RMagick disponible (opcional)
-  text_select_mail_notifications: Seleccionar los eventos a notificar
-  text_select_project_modules: 'Seleccione los mÃ³dulos a activar para este proyecto:'
-  text_status_changed_by_changeset: "Aplicado en los cambios %{value}"
-  text_subprojects_destroy_warning: "Los proyectos secundarios: %{value} tambiÃ©n se eliminarÃ¡n"
-  text_tip_issue_begin_day: tarea que comienza este dÃ­a
-  text_tip_issue_begin_end_day: tarea que comienza y termina este dÃ­a
-  text_tip_issue_end_day: tarea que termina este dÃ­a
-  text_tracker_no_workflow: No hay ningÃºn flujo de trabajo definido para este tipo de peticiÃ³n
-  text_unallowed_characters: Caracteres no permitidos
-  text_user_mail_option: "De los proyectos no seleccionados, sÃ³lo recibirÃ¡ notificaciones sobre elementos monitorizados o elementos en los que estÃ© involucrado (por ejemplo, peticiones de las que usted sea autor o asignadas a usted)."
-  text_user_wrote: "%{value} escribiÃ³:"
-  text_wiki_destroy_confirmation: Â¿Seguro que quiere borrar el wiki y todo su contenido?
-  text_workflow_edit: Seleccionar un flujo de trabajo para actualizar
-  text_plugin_assets_writable: Se puede escribir en el directorio pÃºblico de las extensiones
-  warning_attachments_not_saved: "No se han podido grabar %{count} ficheros."
-  button_create_and_continue: Crear y continuar
-  text_custom_field_possible_values_info: 'Un valor en cada lÃ­nea'
-  label_display: Mostrar
-  field_editable: Modificable
-  setting_repository_log_display_limit: NÃºmero mÃ¡ximo de revisiones mostradas en el fichero de trazas
-  setting_file_max_size_displayed: TamaÃ±o mÃ¡ximo de los ficheros de texto mostrados
-  field_watcher: Seguidor
-  setting_openid: Permitir identificaciÃ³n y registro por OpenID
-  field_identity_url: URL de OpenID
-  label_login_with_open_id_option: o identifÃ­quese con OpenID
-  field_content: Contenido
-  label_descending: Descendente
-  label_sort: Ordenar
-  label_ascending: Ascendente
-  label_date_from_to: Desde %{start} hasta %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: Esta pÃ¡gina tiene %{descendants} pÃ¡gina(s) hija(s) y descendiente(s). Â¿QuÃ© desea hacer?
-  text_wiki_page_reassign_children: Reasignar pÃ¡ginas hijas a esta pÃ¡gina
-  text_wiki_page_nullify_children: Dejar pÃ¡ginas hijas como pÃ¡ginas raÃ­z
-  text_wiki_page_destroy_children: Eliminar pÃ¡ginas hijas y todos sus descendientes
-  setting_password_min_length: Longitud mÃ­nima de la contraseÃ±a
-  field_group_by: Agrupar resultados por
-  mail_subject_wiki_content_updated: "La pÃ¡gina wiki '%{id}' ha sido actualizada"
-  label_wiki_content_added: PÃ¡gina wiki aÃ±adida
-  mail_subject_wiki_content_added: "Se ha aÃ±adido la pÃ¡gina wiki '%{id}'."
-  mail_body_wiki_content_added: "%{author} ha aÃ±adido la pÃ¡gina wiki '%{id}'."
-  label_wiki_content_updated: PÃ¡gina wiki actualizada
-  mail_body_wiki_content_updated: La pÃ¡gina wiki '%{id}' ha sido actualizada por %{author}.
-  permission_add_project: Crear proyecto
-  setting_new_project_user_role_id: Permiso asignado a un usuario no-administrador para crear proyectos
-  label_view_all_revisions: Ver todas las revisiones
-  label_tag: Etiqueta
-  label_branch: Rama
-  error_no_tracker_in_project: Este proyecto no tiene asociados tipos de peticiones. Por favor, revise la configuraciÃ³n.
-  error_no_default_issue_status: No se ha definido un estado de peticiÃ³n por defecto. Por favor, revise la configuraciÃ³n (en "AdministraciÃ³n" -> "Estados de las peticiones").
-  text_journal_changed: "%{label} cambiado %{old} por %{new}"
-  text_journal_set_to: "%{label} establecido a %{value}"
-  text_journal_deleted: "%{label} eliminado (%{old})"
-  label_group_plural: Grupos
-  label_group: Grupo
-  label_group_new: Nuevo grupo
-  label_time_entry_plural: Tiempo dedicado
-  text_journal_added: "AÃ±adido %{label} %{value}"
-  field_active: Activo
-  enumeration_system_activity: Actividad del sistema
-  permission_delete_issue_watchers: Borrar seguidores
-  version_status_closed: cerrado
-  version_status_locked: bloqueado
-  version_status_open: abierto
-  error_can_not_reopen_issue_on_closed_version: No se puede reabrir una peticiÃ³n asignada a una versiÃ³n cerrada
-  
-  label_user_anonymous: AnÃ³nimo
-  button_move_and_follow: Mover y seguir
-  setting_default_projects_modules: MÃ³dulos activados por defecto en proyectos nuevos
-  setting_gravatar_default: Imagen Gravatar por defecto
-  field_sharing: Compartir
-  button_copy_and_follow: Copiar y seguir
-  label_version_sharing_hierarchy: Con la jerarquÃ­a del proyecto
-  label_version_sharing_tree: Con el Ã¡rbol del proyecto
-  label_version_sharing_descendants: Con proyectos hijo
-  label_version_sharing_system: Con todos los proyectos
-  label_version_sharing_none: No compartir
-  button_duplicate: Duplicar
-  error_can_not_archive_project: Este proyecto no puede ser archivado
-  label_copy_source: Fuente
-  setting_issue_done_ratio: Calcular el ratio de tareas realizadas con
-  setting_issue_done_ratio_issue_status: Usar el estado de tareas
-  error_issue_done_ratios_not_updated: Ratios de tareas realizadas no actualizado.
-  error_workflow_copy_target: Por favor, elija categorÃ­a(s) y perfil(es) destino
-  setting_issue_done_ratio_issue_field: Utilizar el campo de peticiÃ³n
-  label_copy_same_as_target: El mismo que el destino
-  label_copy_target: Destino
-  notice_issue_done_ratios_updated: Ratios de tareas realizadas actualizados.
-  error_workflow_copy_source: Por favor, elija una categorÃ­a o rol de origen
-  label_update_issue_done_ratios: Actualizar ratios de tareas realizadas
-  setting_start_of_week: Comenzar las semanas en
-  permission_view_issues: Ver peticiones
-  label_display_used_statuses_only: SÃ³lo mostrar los estados usados por este tipo de peticiÃ³n
-  label_revision_id: RevisiÃ³n %{value}
-  label_api_access_key: Clave de acceso de la API
-  label_api_access_key_created_on: Clave de acceso de la API creada hace %{value}
-  label_feeds_access_key: Clave de acceso RSS
-  notice_api_access_key_reseted: Clave de acceso a la API regenerada.
-  setting_rest_api_enabled: Activar servicio web REST
-  label_missing_api_access_key: Clave de acceso a la API ausente
-  label_missing_feeds_access_key: Clave de accesso RSS ausente
-  button_show: Mostrar
-  text_line_separated: MÃºltiples valores permitidos (un valor en cada lÃ­nea).
-  setting_mail_handler_body_delimiters: Truncar correos tras una de estas lÃ­neas
-  permission_add_subprojects: Crear subproyectos
-  label_subproject_new: Nuevo subproyecto
-  text_own_membership_delete_confirmation: |-
-    EstÃ¡ a punto de eliminar algÃºn o todos sus permisos y podrÃ­a perder la posibilidad de modificar este proyecto tras hacerlo.
-    Â¿EstÃ¡ seguro de querer continuar?
-  label_close_versions: Cerrar versiones completadas
-  label_board_sticky: Pegajoso
-  label_board_locked: Bloqueado
-  permission_export_wiki_pages: Exportar pÃ¡ginas wiki
-  setting_cache_formatted_text: Cachear texto formateado
-  permission_manage_project_activities: Gestionar actividades del proyecto
-  error_unable_delete_issue_status: Fue imposible eliminar el estado de la peticiÃ³n
-  label_profile: Perfil
-  permission_manage_subtasks: Gestionar subtareas
-  field_parent_issue: Tarea padre
-  label_subtask_plural: Subtareas
-  label_project_copy_notifications: Enviar notificaciones por correo electrÃ³nico durante la copia del proyecto
-  error_can_not_delete_custom_field: Fue imposible eliminar el campo personalizado
-  error_unable_to_connect: Fue imposible conectar con (%{value})
-  error_can_not_remove_role: Este rol estÃ¡ en uso y no puede ser eliminado.
-  error_can_not_delete_tracker: Este tipo contiene peticiones y no puede ser eliminado.
-  field_principal: Principal
-  label_my_page_block: Bloque Mi pÃ¡gina
-  notice_failed_to_save_members: "Fallo al guardar miembro(s): %{errors}."
-  text_zoom_out: Alejar
-  text_zoom_in: Acercar
-  notice_unable_delete_time_entry: Fue imposible eliminar la entrada de tiempo dedicado.
-  label_overall_spent_time: Tiempo total dedicado
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendario
-  button_edit_associated_wikipage: "Editar paginas Wiki asociadas: %{page_title}"
-  text_are_you_sure_with_children: Â¿Borrar peticiones y todas sus peticiones hijas?
-  field_text: Campo de texto
-  label_user_mail_option_only_owner: Solo para objetos que soy propietario
-  setting_default_notification_option: Opcion de notificacion por defecto
-  label_user_mail_option_only_my_events: Solo para objetos que soy seguidor o estoy involucrado
-  label_user_mail_option_only_assigned: Solo para objetos que estoy asignado
-  label_user_mail_option_none: Sin eventos
-  field_member_of_group: Asignado al grupo
-  field_assigned_to_role: Asignado al perfil
-  notice_not_authorized_archived_project: El proyecto al que intenta acceder ha sido archivado.
-  label_principal_search: "Buscar por usuario o grupo:"
-  label_user_search: "Buscar por usuario:"
-  field_visible: Visible
-  setting_emails_header: Encabezado de Correos
-
-  setting_commit_logtime_activity_id: Actividad de los tiempos registrados
-  text_time_logged_by_changeset: Aplicado en los cambios %{value}.
-  setting_commit_logtime_enabled: Habilitar registro de horas
-  notice_gantt_chart_truncated: Se recortÃ³ el diagrama porque excede el nÃºmero mÃ¡ximo de elementos que pueden ser mostrados (%{max})
-  setting_gantt_items_limit: NÃºmero mÃ¡ximo de elementos mostrados en el diagrama de Gantt
-  field_warn_on_leaving_unsaved: Avisarme cuando vaya a abandonar una pÃ¡gina con texto no guardado
-  text_warn_on_leaving_unsaved: Esta pÃ¡gina contiene texto no guardado y si la abandona sus cambios se perderÃ¡n
-  label_my_queries: Mis consultas personalizadas
-  text_journal_changed_no_detail: "Se actualizÃ³ %{label}"
-  label_news_comment_added: Comentario aÃ±adido a noticia
-  button_expand_all: Expandir todo
-  button_collapse_all: Contraer todo
-  label_additional_workflow_transitions_for_assignee: Transiciones adicionales permitidas cuando la peticiÃ³n estÃ¡ asignada al usuario
-  label_additional_workflow_transitions_for_author: Transiciones adicionales permitidas cuando el usuario es autor de la peticiÃ³n
-  label_bulk_edit_selected_time_entries: Editar en bloque las horas seleccionadas
-  text_time_entries_destroy_confirmation: Â¿EstÃ¡ seguro de querer eliminar (la hora seleccionada/las horas seleccionadas)?
-  label_role_anonymous: AnÃ³nimo
-  label_role_non_member: No miembro
-  label_issue_note_added: Nota aÃ±adida
-  label_issue_status_updated: Estado actualizado
-  label_issue_priority_updated: Prioridad actualizada
-  label_issues_visibility_own: Peticiones creadas por el usuario o asignadas a Ã©l
-  field_issues_visibility: Visibilidad de las peticiones
-  label_issues_visibility_all: Todas las peticiones
-  permission_set_own_issues_private: Poner las peticiones propias como pÃºblicas o privadas
-  field_is_private: Privada
-  permission_set_issues_private: Poner peticiones como pÃºblicas o privadas
-  label_issues_visibility_public: Todas las peticiones no privadas
-  text_issues_destroy_descendants_confirmation: Se procederÃ¡ a borrar tambiÃ©n %{count} subtarea(s).
-  field_commit_logs_encoding: CodificaciÃ³n de los mensajes de commit
-  field_scm_path_encoding: CodificaciÃ³n de las rutas
-  text_scm_path_encoding_note: "Por defecto: UTF-8"
-  field_path_to_repository: Ruta al repositorio
-  field_root_directory: Directorio raÃ­z
-  field_cvs_module: MÃ³dulo
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Repositorio local (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Orden
-  text_scm_command_version: VersiÃ³n
-  label_git_report_last_commit: Informar del Ãºltimo commit para ficheros y directorios
-  text_scm_config: Puede configurar las Ã³rdenes de cada scm en configuration/configuration.yml. Por favor, reinicie la aplicaciÃ³n despuÃ©s de editarlo
-  text_scm_command_not_available: La orden para el Scm no estÃ¡ disponible. Por favor, compruebe la configuraciÃ³n en el panel de administraciÃ³n.
-  notice_issue_successful_create: PeticiÃ³n %{id} creada.
-  label_between: entre
-  setting_issue_group_assignment: Permitir asignar peticiones a grupos
-  label_diff: diferencias
-  text_git_repository_note: El repositorio es bÃ¡sico y local (p.e. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: DirecciÃ³n de ordenaciÃ³n
-  description_project_scope: Ãmbito de bÃºsqueda
-  description_filter: Filtro
-  description_user_mail_notification: ConfiguraciÃ³n de notificaciones por correo
-  description_date_from: Introduzca la fecha de inicio
-  description_message_content: Contenido del mensaje
-  description_available_columns: Columnas disponibles
-  description_date_range_interval: Elija el rango seleccionando la fecha de inicio y fin
-  description_issue_category_reassign: Elija la categorÃ­a de la peticiÃ³n
-  description_search: Campo de bÃºsqueda
-  description_notes: Notas
-  description_date_range_list: Elija el rango en la lista
-  description_choose_project: Proyectos
-  description_date_to: Introduzca la fecha fin
-  description_query_sort_criteria_attribute: Atributo de ordenaciÃ³n
-  description_wiki_subpages_reassign: Elija la nueva pÃ¡gina padre
-  description_selected_columns: Columnas seleccionadas
-  label_parent_revision: Padre
-  label_child_revision: Hijo
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: Todas las columnas
-  button_export: Exportar
-  label_export_options: "%{export_format} opciones de exportaciÃ³n"
-  error_attachment_too_big: Este fichero no se puede adjuntar porque excede el tamaÃ±o mÃ¡ximo de fichero (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4b/4bca034528beb58f74c7ed4f1bd974d891aaa55f.svn-base
--- /dev/null
+++ b/.svn/pristine/4b/4bca034528beb58f74c7ed4f1bd974d891aaa55f.svn-base
@@ -0,0 +1,39 @@
+<div class="splitcontentleft">
+<% if @group.users.any? %>
+  <table class="list users">
+    <thead><tr>
+      <th><%= l(:label_user) %></th>
+      <th style="width:15%"></th>
+    </tr></thead>
+    <tbody>
+    <% @group.users.sort.each do |user| %>
+      <tr id="user-<%= user.id %>" class="<%= cycle 'odd', 'even' %>">
+        <td class="user"><%= link_to_user user %></td>
+        <td class="buttons">
+          <%= delete_link group_user_path(@group, :user_id => user), :remote => true %>
+        </td>
+      </tr>
+    <% end %>
+    </tbody>
+  </table>
+<% else %>
+  <p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
+</div>
+
+<div class="splitcontentright">
+  <%= form_for(@group, :remote => true, :url => group_users_path(@group),
+               :html => {:method => :post}) do |f| %>
+    <fieldset><legend><%=l(:label_user_new)%></legend>
+
+    <p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
+    <%= javascript_tag "observeSearchfield('user_search', null, '#{ escape_javascript autocomplete_for_user_group_path(@group) }')" %>
+
+    <div id="users">
+      <%= render_principals_for_new_group_users(@group) %>
+    </div>
+
+    <p><%= submit_tag l(:button_add) %></p>
+    </fieldset>
+  <% end %>
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4b/4bd5699fdfa1ef964b63852ff5e554bbdc600109.svn-base
--- a/.svn/pristine/4b/4bd5699fdfa1ef964b63852ff5e554bbdc600109.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-module Engines
-  class Plugin
-    class Loader < Rails::Plugin::Loader    
-      protected    
-        def register_plugin_as_loaded(plugin)
-          super plugin
-          Engines.plugins << plugin
-        end    
-    end
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4c2f7807c17edfaadfde41de28c64ed5f2677c01.svn-base
--- a/.svn/pristine/4c/4c2f7807c17edfaadfde41de28c64ed5f2677c01.svn-base
+++ /dev/null
@@ -1,27 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Platform
-    class << self
-      def mswin?
-        (RUBY_PLATFORM =~ /(:?mswin|mingw)/) ||
-           (RUBY_PLATFORM == 'java' && (ENV['OS'] || ENV['os']) =~ /windows/i)
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4c336c258123fb4e9b45bc7fc7cd3f56f7293d30.svn-base
--- /dev/null
+++ b/.svn/pristine/4c/4c336c258123fb4e9b45bc7fc7cd3f56f7293d30.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module IssueCategoriesHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4c46450a69eddda0d211771bcf055604ac13c9ff.svn-base
--- a/.svn/pristine/4c/4c46450a69eddda0d211771bcf055604ac13c9ff.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class Namespace::SharedPluginController < ApplicationController
-  def an_action
-    render_class_and_action 'from alpha_plugin'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4c59ba20a8f0cc2dfb2dedfa1e4641821d4c6a38.svn-base
--- a/.svn/pristine/4c/4c59ba20a8f0cc2dfb2dedfa1e4641821d4c6a38.svn-base
+++ /dev/null
@@ -1,86 +0,0 @@
-// ** I18N
-
-// Calendar NO language (Norwegian/Norsk bokmÃ¥l)
-// Author: Kai Olav Fredriksen <k@i.fredriksen.net>
-
-// full day names
-Calendar._DN = new Array
-("SÃ¸ndag",
- "Mandag",
- "Tirsdag",
- "Onsdag",
- "Torsdag",
- "Fredag",
- "LÃ¸rdag",
- "SÃ¸ndag");
-
-Calendar._SDN_len = 3; // short day name length
-Calendar._SMN_len = 3; // short month name length
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Januar",
- "Februar",
- "Mars",
- "April",
- "Mai",
- "Juni",
- "Juli",
- "August",
- "September",
- "Oktober",
- "November",
- "Desember");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Om kalenderen";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "Forrige Ã¥r (hold for meny)";
-Calendar._TT["PREV_MONTH"] = "Forrige mÃ¥ned (hold for meny)";
-Calendar._TT["GO_TODAY"] = "GÃ¥ til idag";
-Calendar._TT["NEXT_MONTH"] = "Neste mÃ¥ned (hold for meny)";
-Calendar._TT["NEXT_YEAR"] = "Neste Ã¥r (hold for meny)";
-Calendar._TT["SEL_DATE"] = "Velg dato";
-Calendar._TT["DRAG_TO_MOVE"] = "Dra for Ã¥ flytte";
-Calendar._TT["PART_TODAY"] = " (idag)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Vis %s fÃ¸rst";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Lukk";
-Calendar._TT["TODAY"] = "Idag";
-Calendar._TT["TIME_PART"] = "(Shift-)Klikk eller dra for Ã¥ endre verdi";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%%d.%m.%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "uke";
-Calendar._TT["TIME"] = "Tid:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4c87209f1f933df211a435d5f5082b69a9cf19f5.svn-base
--- a/.svn/pristine/4c/4c87209f1f933df211a435d5f5082b69a9cf19f5.svn-base
+++ /dev/null
@@ -1,297 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::ProjectsTest < ActionController::IntegrationTest
-  fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
-           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
-           :attachments, :custom_fields, :custom_values, :time_entries, :issue_categories
-
-  def setup
-    Setting.rest_api_enabled = '1'
-    set_tmp_attachments_directory
-  end
-
-  context "GET /projects" do
-    context ".xml" do
-      should "return projects" do
-        get '/projects.xml'
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-
-        assert_tag :tag => 'projects',
-          :child => {:tag => 'project', :child => {:tag => 'id', :content => '1'}}
-      end
-    end
-
-    context ".json" do
-      should "return projects" do
-        get '/projects.json'
-        assert_response :success
-        assert_equal 'application/json', @response.content_type
-
-        json = ActiveSupport::JSON.decode(response.body)
-        assert_kind_of Hash, json
-        assert_kind_of Array, json['projects']
-        assert_kind_of Hash, json['projects'].first
-        assert json['projects'].first.has_key?('id')
-      end
-    end
-  end
-
-  context "GET /projects/:id" do
-    context ".xml" do
-      # TODO: A private project is needed because should_allow_api_authentication
-      # actually tests that authentication is *required*, not just allowed
-      should_allow_api_authentication(:get, "/projects/2.xml")
-
-      should "return requested project" do
-        get '/projects/1.xml'
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-
-        assert_tag :tag => 'project',
-          :child => {:tag => 'id', :content => '1'}
-        assert_tag :tag => 'custom_field',
-          :attributes => {:name => 'Development status'}, :content => 'Stable'
-
-        assert_no_tag 'trackers'
-        assert_no_tag 'issue_categories'
-      end
-
-      context "with hidden custom fields" do
-        setup do
-          ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
-        end
-
-        should "not display hidden custom fields" do
-          get '/projects/1.xml'
-          assert_response :success
-          assert_equal 'application/xml', @response.content_type
-
-          assert_no_tag 'custom_field',
-            :attributes => {:name => 'Development status'}
-        end
-      end
-
-      should "return categories with include=issue_categories" do
-        get '/projects/1.xml?include=issue_categories'
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-
-        assert_tag 'issue_categories',
-          :attributes => {:type => 'array'},
-          :child => {
-            :tag => 'issue_category',
-            :attributes => {
-              :id => '2',
-              :name => 'Recipes'
-            }
-          }
-      end
-
-      should "return trackers with include=trackers" do
-        get '/projects/1.xml?include=trackers'
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-
-        assert_tag 'trackers',
-          :attributes => {:type => 'array'},
-          :child => {
-            :tag => 'tracker',
-            :attributes => {
-              :id => '2',
-              :name => 'Feature request'
-            }
-          }
-      end
-    end
-
-    context ".json" do
-      should_allow_api_authentication(:get, "/projects/2.json")
-
-      should "return requested project" do
-        get '/projects/1.json'
-
-        json = ActiveSupport::JSON.decode(response.body)
-        assert_kind_of Hash, json
-        assert_kind_of Hash, json['project']
-        assert_equal 1, json['project']['id']
-      end
-    end
-  end
-
-  context "POST /projects" do
-    context "with valid parameters" do
-      setup do
-        Setting.default_projects_modules = ['issue_tracking', 'repository']
-        @parameters = {:project => {:name => 'API test', :identifier => 'api-test'}}
-      end
-
-      context ".xml" do
-        should_allow_api_authentication(:post,
-                                        '/projects.xml',
-                                        {:project => {:name => 'API test', :identifier => 'api-test'}},
-                                        {:success_code => :created})
-
-
-        should "create a project with the attributes" do
-          assert_difference('Project.count') do
-            post '/projects.xml', @parameters, :authorization => credentials('admin')
-          end
-
-          project = Project.first(:order => 'id DESC')
-          assert_equal 'API test', project.name
-          assert_equal 'api-test', project.identifier
-          assert_equal ['issue_tracking', 'repository'], project.enabled_module_names.sort
-          assert_equal Tracker.all.size, project.trackers.size
-
-          assert_response :created
-          assert_equal 'application/xml', @response.content_type
-          assert_tag 'project', :child => {:tag => 'id', :content => project.id.to_s}
-        end
-
-        should "accept enabled_module_names attribute" do
-          @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
-
-          assert_difference('Project.count') do
-            post '/projects.xml', @parameters, :authorization => credentials('admin')
-          end
-
-          project = Project.first(:order => 'id DESC')
-          assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
-        end
-
-        should "accept tracker_ids attribute" do
-          @parameters[:project].merge!({:tracker_ids => [1, 3]})
-
-          assert_difference('Project.count') do
-            post '/projects.xml', @parameters, :authorization => credentials('admin')
-          end
-
-          project = Project.first(:order => 'id DESC')
-          assert_equal [1, 3], project.trackers.map(&:id).sort
-        end
-      end
-    end
-
-    context "with invalid parameters" do
-      setup do
-        @parameters = {:project => {:name => 'API test'}}
-      end
-
-      context ".xml" do
-        should "return errors" do
-          assert_no_difference('Project.count') do
-            post '/projects.xml', @parameters, :authorization => credentials('admin')
-          end
-
-          assert_response :unprocessable_entity
-          assert_equal 'application/xml', @response.content_type
-          assert_tag 'errors', :child => {:tag => 'error', :content => "Identifier can't be blank"}
-        end
-      end
-    end
-  end
-
-  context "PUT /projects/:id" do
-    context "with valid parameters" do
-      setup do
-        @parameters = {:project => {:name => 'API update'}}
-      end
-
-      context ".xml" do
-        should_allow_api_authentication(:put,
-                                        '/projects/2.xml',
-                                        {:project => {:name => 'API update'}},
-                                        {:success_code => :ok})
-
-        should "update the project" do
-          assert_no_difference 'Project.count' do
-            put '/projects/2.xml', @parameters, :authorization => credentials('jsmith')
-          end
-          assert_response :ok
-          assert_equal 'application/xml', @response.content_type
-          project = Project.find(2)
-          assert_equal 'API update', project.name
-        end
-
-        should "accept enabled_module_names attribute" do
-          @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
-
-          assert_no_difference 'Project.count' do
-            put '/projects/2.xml', @parameters, :authorization => credentials('admin')
-          end
-          assert_response :ok
-          project = Project.find(2)
-          assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
-        end
-
-        should "accept tracker_ids attribute" do
-          @parameters[:project].merge!({:tracker_ids => [1, 3]})
-
-          assert_no_difference 'Project.count' do
-            put '/projects/2.xml', @parameters, :authorization => credentials('admin')
-          end
-          assert_response :ok
-          project = Project.find(2)
-          assert_equal [1, 3], project.trackers.map(&:id).sort
-        end
-      end
-    end
-
-    context "with invalid parameters" do
-      setup do
-        @parameters = {:project => {:name => ''}}
-      end
-
-      context ".xml" do
-        should "return errors" do
-          assert_no_difference('Project.count') do
-            put '/projects/2.xml', @parameters, :authorization => credentials('admin')
-          end
-
-          assert_response :unprocessable_entity
-          assert_equal 'application/xml', @response.content_type
-          assert_tag 'errors', :child => {:tag => 'error', :content => "Name can't be blank"}
-        end
-      end
-    end
-  end
-
-  context "DELETE /projects/:id" do
-    context ".xml" do
-      should_allow_api_authentication(:delete,
-                                      '/projects/2.xml',
-                                      {},
-                                      {:success_code => :ok})
-
-      should "delete the project" do
-        assert_difference('Project.count',-1) do
-          delete '/projects/2.xml', {}, :authorization => credentials('admin')
-        end
-        assert_response :ok
-        assert_nil Project.find_by_id(2)
-      end
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4cde02772540ced7426b8c2828a1d2272fc2d8ad.svn-base
--- a/.svn/pristine/4c/4cde02772540ced7426b8c2828a1d2272fc2d8ad.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-// ** I18N
-
-// Calendar pt language
-// Author: Adalberto Machado, <betosm@terra.com.br>
-// Corrected by: Pedro AraÃºjo <phcrva19@hotmail.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Domingo",
- "Segunda",
- "TerÃ§a",
- "Quarta",
- "Quinta",
- "Sexta",
- "SÃ¡bado",
- "Domingo");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Dom",
- "Seg",
- "Ter",
- "Qua",
- "Qui",
- "Sex",
- "SÃ¡b",
- "Dom");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Janeiro",
- "Fevereiro",
- "MarÃ§o",
- "Abril",
- "Maio",
- "Junho",
- "Julho",
- "Agosto",
- "Setembro",
- "Outubro",
- "Novembro",
- "Dezembro");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Fev",
- "Mar",
- "Abr",
- "Mai",
- "Jun",
- "Jul",
- "Ago",
- "Set",
- "Out",
- "Nov",
- "Dez");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Sobre o calendÃ¡rio";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"Ãšltima versÃ£o visite: http://www.dynarch.com/projects/calendar/\n" +
-"DistribuÃ­do sobre a licenÃ§a GNU LGPL.  Veja http://gnu.org/licenses/lgpl.html para detalhes." +
-"\n\n" +
-"SelecÃ§Ã£o de data:\n" +
-"- Use os botÃµes \xab, \xbb para seleccionar o ano\n" +
-"- Use os botÃµes " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para seleccionar o mÃªs\n" +
-"- Segure o botÃ£o do rato em qualquer um desses botÃµes para selecÃ§Ã£o rÃ¡pida.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"SelecÃ§Ã£o de hora:\n" +
-"- Clique em qualquer parte da hora para incrementar\n" +
-"- ou Shift-click para decrementar\n" +
-"- ou clique e segure para selecÃ§Ã£o rÃ¡pida.";
-
-Calendar._TT["PREV_YEAR"] = "Ano ant. (segure para menu)";
-Calendar._TT["PREV_MONTH"] = "MÃªs ant. (segure para menu)";
-Calendar._TT["GO_TODAY"] = "Hoje";
-Calendar._TT["NEXT_MONTH"] = "Prox. mÃªs (segure para menu)";
-Calendar._TT["NEXT_YEAR"] = "Prox. ano (segure para menu)";
-Calendar._TT["SEL_DATE"] = "Seleccione a data";
-Calendar._TT["DRAG_TO_MOVE"] = "Arraste para mover";
-Calendar._TT["PART_TODAY"] = " (hoje)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Mostre %s primeiro";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Fechar";
-Calendar._TT["TODAY"] = "Hoje";
-Calendar._TT["TIME_PART"] = "(Shift-)Click ou arraste para mudar valor";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b";
-
-Calendar._TT["WK"] = "sm";
-Calendar._TT["TIME"] = "Hora:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4ce30d3521f9c879b76d2c58d967727fd036b9f7.svn-base
--- a/.svn/pristine/4c/4ce30d3521f9c879b76d2c58d967727fd036b9f7.svn-base
+++ /dev/null
@@ -1,104 +0,0 @@
---- 
-changesets_001: 
-  commit_date: 2007-04-11
-  committed_on: 2007-04-11 15:14:44 +02:00
-  revision: 1
-  id: 100
-  comments: My very first commit
-  repository_id: 10
-  committer: dlopper
-  user_id: 3
-changesets_002: 
-  commit_date: 2007-04-12
-  committed_on: 2007-04-12 15:14:44 +02:00
-  revision: 2
-  id: 101
-  comments: 'This commit fixes #1, #2 and references #1 & #3'
-  repository_id: 10
-  committer: dlopper
-  user_id: 3
-changesets_003: 
-  commit_date: 2007-04-12
-  committed_on: 2007-04-12 15:14:44 +02:00
-  revision: 3
-  id: 102
-  comments: |-
-    A commit with wrong issue ids
-    IssueID #666 #3
-  repository_id: 10
-  committer: dlopper
-  user_id: 3
-changesets_004: 
-  commit_date: 2007-04-12
-  committed_on: 2007-04-12 15:14:44 +02:00
-  revision: 4
-  id: 103
-  comments: |-
-    A commit with an issue id of an other project
-    IssueID 4 2
-  repository_id: 10
-  committer: dlopper
-  user_id: 3
-changesets_005: 
-  commit_date: "2007-09-10"
-  comments: Modified one file in the folder.
-  committed_on: 2007-09-10 19:01:08
-  revision: "5"
-  id: 104
-  scmid:
-  user_id: 3
-  repository_id: 10
-  committer: dlopper
-changesets_006: 
-  commit_date: "2007-09-10"
-  comments: Moved helloworld.rb from / to /folder.
-  committed_on: 2007-09-10 19:01:47
-  revision: "6"
-  id: 105
-  scmid:
-  user_id: 3
-  repository_id: 10
-  committer: dlopper
-changesets_007: 
-  commit_date: "2007-09-10"
-  comments: Removed one file.
-  committed_on: 2007-09-10 19:02:16
-  revision: "7"
-  id: 106
-  scmid:
-  user_id: 3
-  repository_id: 10
-  committer: dlopper
-changesets_008: 
-  commit_date: "2007-09-10"
-  comments: |-
-    This commits references an issue.
-    Refs #2
-  committed_on: 2007-09-10 19:04:35
-  revision: "8"
-  id: 107
-  scmid:
-  user_id: 3
-  repository_id: 10
-  committer: dlopper
-changesets_009: 
-  commit_date: "2009-09-10"
-  comments: One file added.
-  committed_on: 2009-09-10 19:04:35
-  revision: "9"
-  id: 108
-  scmid:
-  user_id: 3
-  repository_id: 10
-  committer: dlopper
-changesets_010: 
-  commit_date: "2009-09-10"
-  comments: Same file modified.
-  committed_on: 2009-09-10 19:04:35
-  revision: "10"
-  id: 109
-  scmid:
-  user_id: 3
-  repository_id: 10
-  committer: dlopper
-  
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4ce47e5153ddf18249e25aad233433aafed78ea8.svn-base
--- /dev/null
+++ b/.svn/pristine/4c/4ce47e5153ddf18249e25aad233433aafed78ea8.svn-base
@@ -0,0 +1,278 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Changeset < ActiveRecord::Base
+  belongs_to :repository
+  belongs_to :user
+  has_many :filechanges, :class_name => 'Change', :dependent => :delete_all
+  has_and_belongs_to_many :issues
+  has_and_belongs_to_many :parents,
+                          :class_name => "Changeset",
+                          :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}",
+                          :association_foreign_key => 'parent_id', :foreign_key => 'changeset_id'
+  has_and_belongs_to_many :children,
+                          :class_name => "Changeset",
+                          :join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}",
+                          :association_foreign_key => 'changeset_id', :foreign_key => 'parent_id'
+
+  acts_as_event :title => Proc.new {|o| o.title},
+                :description => :long_comments,
+                :datetime => :committed_on,
+                :url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :repository_id => o.repository.identifier_param, :rev => o.identifier}}
+
+  acts_as_searchable :columns => 'comments',
+                     :include => {:repository => :project},
+                     :project_key => "#{Repository.table_name}.project_id",
+                     :date_column => 'committed_on'
+
+  acts_as_activity_provider :timestamp => "#{table_name}.committed_on",
+                            :author_key => :user_id,
+                            :find_options => {:include => [:user, {:repository => :project}]}
+
+  validates_presence_of :repository_id, :revision, :committed_on, :commit_date
+  validates_uniqueness_of :revision, :scope => :repository_id
+  validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
+
+  scope :visible, lambda {|*args|
+    includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args))
+  }
+
+  after_create :scan_for_issues
+  before_create :before_create_cs
+
+  def revision=(r)
+    write_attribute :revision, (r.nil? ? nil : r.to_s)
+  end
+
+  # Returns the identifier of this changeset; depending on repository backends
+  def identifier
+    if repository.class.respond_to? :changeset_identifier
+      repository.class.changeset_identifier self
+    else
+      revision.to_s
+    end
+  end
+
+  def committed_on=(date)
+    self.commit_date = date
+    super
+  end
+
+  # Returns the readable identifier
+  def format_identifier
+    if repository.class.respond_to? :format_changeset_identifier
+      repository.class.format_changeset_identifier self
+    else
+      identifier
+    end
+  end
+
+  def project
+    repository.project
+  end
+
+  def author
+    user || committer.to_s.split('<').first
+  end
+
+  def before_create_cs
+    self.committer = self.class.to_utf8(self.committer, repository.repo_log_encoding)
+    self.comments  = self.class.normalize_comments(
+                       self.comments, repository.repo_log_encoding)
+    self.user = repository.find_committer_user(self.committer)
+  end
+
+  def scan_for_issues
+    scan_comment_for_issue_ids
+  end
+
+  TIMELOG_RE = /
+    (
+    ((\d+)(h|hours?))((\d+)(m|min)?)?
+    |
+    ((\d+)(h|hours?|m|min))
+    |
+    (\d+):(\d+)
+    |
+    (\d+([\.,]\d+)?)h?
+    )
+    /x
+
+  def scan_comment_for_issue_ids
+    return if comments.blank?
+    # keywords used to reference issues
+    ref_keywords = Setting.commit_ref_keywords.downcase.split(",").collect(&:strip)
+    ref_keywords_any = ref_keywords.delete('*')
+    # keywords used to fix issues
+    fix_keywords = Setting.commit_fix_keywords.downcase.split(",").collect(&:strip)
+
+    kw_regexp = (ref_keywords + fix_keywords).collect{|kw| Regexp.escape(kw)}.join("|")
+
+    referenced_issues = []
+
+    comments.scan(/([\s\(\[,-]|^)((#{kw_regexp})[\s:]+)?(#\d+(\s+@#{TIMELOG_RE})?([\s,;&]+#\d+(\s+@#{TIMELOG_RE})?)*)(?=[[:punct:]]|\s|<|$)/i) do |match|
+      action, refs = match[2], match[3]
+      next unless action.present? || ref_keywords_any
+
+      refs.scan(/#(\d+)(\s+@#{TIMELOG_RE})?/).each do |m|
+        issue, hours = find_referenced_issue_by_id(m[0].to_i), m[2]
+        if issue
+          referenced_issues << issue
+          fix_issue(issue) if fix_keywords.include?(action.to_s.downcase)
+          log_time(issue, hours) if hours && Setting.commit_logtime_enabled?
+        end
+      end
+    end
+
+    referenced_issues.uniq!
+    self.issues = referenced_issues unless referenced_issues.empty?
+  end
+
+  def short_comments
+    @short_comments || split_comments.first
+  end
+
+  def long_comments
+    @long_comments || split_comments.last
+  end
+
+  def text_tag(ref_project=nil)
+    tag = if scmid?
+      "commit:#{scmid}"
+    else
+      "r#{revision}"
+    end
+    if repository && repository.identifier.present?
+      tag = "#{repository.identifier}|#{tag}"
+    end
+    if ref_project && project && ref_project != project
+      tag = "#{project.identifier}:#{tag}"
+    end
+    tag
+  end
+
+  # Returns the title used for the changeset in the activity/search results
+  def title
+    repo = (repository && repository.identifier.present?) ? " (#{repository.identifier})" : ''
+    comm = short_comments.blank? ? '' : (': ' + short_comments)
+    "#{l(:label_revision)} #{format_identifier}#{repo}#{comm}"
+  end
+
+  # Returns the previous changeset
+  def previous
+    @previous ||= Changeset.where(["id < ? AND repository_id = ?", id, repository_id]).order('id DESC').first
+  end
+
+  # Returns the next changeset
+  def next
+    @next ||= Changeset.where(["id > ? AND repository_id = ?", id, repository_id]).order('id ASC').first
+  end
+
+  # Creates a new Change from it's common parameters
+  def create_change(change)
+    Change.create(:changeset     => self,
+                  :action        => change[:action],
+                  :path          => change[:path],
+                  :from_path     => change[:from_path],
+                  :from_revision => change[:from_revision])
+  end
+
+  # Finds an issue that can be referenced by the commit message
+  def find_referenced_issue_by_id(id)
+    return nil if id.blank?
+    issue = Issue.find_by_id(id.to_i, :include => :project)
+    if Setting.commit_cross_project_ref?
+      # all issues can be referenced/fixed
+    elsif issue
+      # issue that belong to the repository project, a subproject or a parent project only
+      unless issue.project &&
+                (project == issue.project || project.is_ancestor_of?(issue.project) ||
+                 project.is_descendant_of?(issue.project))
+        issue = nil
+      end
+    end
+    issue
+  end
+
+  private
+
+  def fix_issue(issue)
+    status = IssueStatus.find_by_id(Setting.commit_fix_status_id.to_i)
+    if status.nil?
+      logger.warn("No status matches commit_fix_status_id setting (#{Setting.commit_fix_status_id})") if logger
+      return issue
+    end
+
+    # the issue may have been updated by the closure of another one (eg. duplicate)
+    issue.reload
+    # don't change the status is the issue is closed
+    return if issue.status && issue.status.is_closed?
+
+    journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, text_tag(issue.project)))
+    issue.status = status
+    unless Setting.commit_fix_done_ratio.blank?
+      issue.done_ratio = Setting.commit_fix_done_ratio.to_i
+    end
+    Redmine::Hook.call_hook(:model_changeset_scan_commit_for_issue_ids_pre_issue_update,
+                            { :changeset => self, :issue => issue })
+    unless issue.save
+      logger.warn("Issue ##{issue.id} could not be saved by changeset #{id}: #{issue.errors.full_messages}") if logger
+    end
+    issue
+  end
+
+  def log_time(issue, hours)
+    time_entry = TimeEntry.new(
+      :user => user,
+      :hours => hours,
+      :issue => issue,
+      :spent_on => commit_date,
+      :comments => l(:text_time_logged_by_changeset, :value => text_tag(issue.project),
+                     :locale => Setting.default_language)
+      )
+    time_entry.activity = log_time_activity unless log_time_activity.nil?
+
+    unless time_entry.save
+      logger.warn("TimeEntry could not be created by changeset #{id}: #{time_entry.errors.full_messages}") if logger
+    end
+    time_entry
+  end
+
+  def log_time_activity
+    if Setting.commit_logtime_activity_id.to_i > 0
+      TimeEntryActivity.find_by_id(Setting.commit_logtime_activity_id.to_i)
+    end
+  end
+
+  def split_comments
+    comments =~ /\A(.+?)\r?\n(.*)$/m
+    @short_comments = $1 || comments
+    @long_comments = $2.to_s.strip
+    return @short_comments, @long_comments
+  end
+
+  public
+
+  # Strips and reencodes a commit log before insertion into the database
+  def self.normalize_comments(str, encoding)
+    Changeset.to_utf8(str.to_s.strip, encoding)
+  end
+
+  def self.to_utf8(str, encoding)
+    Redmine::CodesetUtil.to_utf8(str, encoding)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4ce572a386a0b87f49f89a4bc090bd7724a6e4b0.svn-base
--- a/.svn/pristine/4c/4ce572a386a0b87f49f89a4bc090bd7724a6e4b0.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-class SharedPluginModel < ActiveRecord::Base  
-  def self.report_location; TestHelper::report_location(__FILE__); end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4c/4cf321de05d6993523d4f53f4c3078dcaf49b46c.svn-base
--- /dev/null
+++ b/.svn/pristine/4c/4cf321de05d6993523d4f53f4c3078dcaf49b46c.svn-base
@@ -0,0 +1,265 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class SearchControllerTest < ActionController::TestCase
+  fixtures :projects, :enabled_modules, :roles, :users, :members, :member_roles,
+           :issues, :trackers, :issue_statuses, :enumerations,
+           :custom_fields, :custom_values,
+           :repositories, :changesets
+
+  def setup
+    User.current = nil
+  end
+
+  def test_search_for_projects
+    get :index
+    assert_response :success
+    assert_template 'index'
+
+    get :index, :q => "cook"
+    assert_response :success
+    assert_template 'index'
+    assert assigns(:results).include?(Project.find(1))
+  end
+
+  def test_search_all_projects
+    get :index, :q => 'recipe subproject commit', :all_words => ''
+    assert_response :success
+    assert_template 'index'
+
+    assert assigns(:results).include?(Issue.find(2))
+    assert assigns(:results).include?(Issue.find(5))
+    assert assigns(:results).include?(Changeset.find(101))
+    assert_tag :dt, :attributes => { :class => /issue/ },
+                    :child => { :tag => 'a',  :content => /Add ingredients categories/ },
+                    :sibling => { :tag => 'dd', :content => /should be classified by categories/ }
+
+    assert assigns(:results_by_type).is_a?(Hash)
+    assert_equal 5, assigns(:results_by_type)['changesets']
+    assert_tag :a, :content => 'Changesets (5)'
+  end
+
+  def test_search_issues
+    get :index, :q => 'issue', :issues => 1
+    assert_response :success
+    assert_template 'index'
+
+    assert_equal true, assigns(:all_words)
+    assert_equal false, assigns(:titles_only)
+    assert assigns(:results).include?(Issue.find(8))
+    assert assigns(:results).include?(Issue.find(5))
+    assert_tag :dt, :attributes => { :class => /issue closed/ },
+                    :child => { :tag => 'a',  :content => /Closed/ }
+  end
+
+  def test_search_issues_should_search_notes
+    Journal.create!(:journalized => Issue.find(2), :notes => 'Issue notes with searchkeyword')
+
+    get :index, :q => 'searchkeyword', :issues => 1
+    assert_response :success
+    assert_include Issue.find(2), assigns(:results)
+  end
+
+  def test_search_issues_with_multiple_matches_in_journals_should_return_issue_once
+    Journal.create!(:journalized => Issue.find(2), :notes => 'Issue notes with searchkeyword')
+    Journal.create!(:journalized => Issue.find(2), :notes => 'Issue notes with searchkeyword')
+
+    get :index, :q => 'searchkeyword', :issues => 1
+    assert_response :success
+    assert_include Issue.find(2), assigns(:results)
+    assert_equal 1, assigns(:results).size
+  end
+
+  def test_search_issues_should_search_private_notes_with_permission_only
+    Journal.create!(:journalized => Issue.find(2), :notes => 'Private notes with searchkeyword', :private_notes => true)
+    @request.session[:user_id] = 2
+
+    Role.find(1).add_permission! :view_private_notes
+    get :index, :q => 'searchkeyword', :issues => 1
+    assert_response :success
+    assert_include Issue.find(2), assigns(:results)
+
+    Role.find(1).remove_permission! :view_private_notes
+    get :index, :q => 'searchkeyword', :issues => 1
+    assert_response :success
+    assert_not_include Issue.find(2), assigns(:results)
+  end
+
+  def test_search_all_projects_with_scope_param
+    get :index, :q => 'issue', :scope => 'all'
+    assert_response :success
+    assert_template 'index'
+    assert assigns(:results).present?
+  end
+
+  def test_search_my_projects
+    @request.session[:user_id] = 2
+    get :index, :id => 1, :q => 'recipe subproject', :scope => 'my_projects', :all_words => ''
+    assert_response :success
+    assert_template 'index'
+    assert assigns(:results).include?(Issue.find(1))
+    assert !assigns(:results).include?(Issue.find(5))
+  end
+
+  def test_search_my_projects_without_memberships
+    # anonymous user has no memberships
+    get :index, :id => 1, :q => 'recipe subproject', :scope => 'my_projects', :all_words => ''
+    assert_response :success
+    assert_template 'index'
+    assert assigns(:results).empty?
+  end
+
+  def test_search_project_and_subprojects
+    get :index, :id => 1, :q => 'recipe subproject', :scope => 'subprojects', :all_words => ''
+    assert_response :success
+    assert_template 'index'
+    assert assigns(:results).include?(Issue.find(1))
+    assert assigns(:results).include?(Issue.find(5))
+  end
+
+  def test_search_without_searchable_custom_fields
+    CustomField.update_all "searchable = #{ActiveRecord::Base.connection.quoted_false}"
+
+    get :index, :id => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:project)
+
+    get :index, :id => 1, :q => "can"
+    assert_response :success
+    assert_template 'index'
+  end
+
+  def test_search_with_searchable_custom_fields
+    get :index, :id => 1, :q => "stringforcustomfield"
+    assert_response :success
+    results = assigns(:results)
+    assert_not_nil results
+    assert_equal 1, results.size
+    assert results.include?(Issue.find(7))
+  end
+
+  def test_search_all_words
+    # 'all words' is on by default
+    get :index, :id => 1, :q => 'recipe updating saving', :all_words => '1'
+    assert_equal true, assigns(:all_words)
+    results = assigns(:results)
+    assert_not_nil results
+    assert_equal 1, results.size
+    assert results.include?(Issue.find(3))
+  end
+
+  def test_search_one_of_the_words
+    get :index, :id => 1, :q => 'recipe updating saving', :all_words => ''
+    assert_equal false, assigns(:all_words)
+    results = assigns(:results)
+    assert_not_nil results
+    assert_equal 3, results.size
+    assert results.include?(Issue.find(3))
+  end
+
+  def test_search_titles_only_without_result
+    get :index, :id => 1, :q => 'recipe updating saving', :titles_only => '1'
+    results = assigns(:results)
+    assert_not_nil results
+    assert_equal 0, results.size
+  end
+
+  def test_search_titles_only
+    get :index, :id => 1, :q => 'recipe', :titles_only => '1'
+    assert_equal true, assigns(:titles_only)
+    results = assigns(:results)
+    assert_not_nil results
+    assert_equal 2, results.size
+  end
+
+  def test_search_content
+    Issue.update_all("description = 'This is a searchkeywordinthecontent'", "id=1")
+
+    get :index, :id => 1, :q => 'searchkeywordinthecontent', :titles_only => ''
+    assert_equal false, assigns(:titles_only)
+    results = assigns(:results)
+    assert_not_nil results
+    assert_equal 1, results.size
+  end
+
+  def test_search_with_offset
+    get :index, :q => 'coo', :offset => '20080806073000'
+    assert_response :success
+    results = assigns(:results)
+    assert results.any?
+    assert results.map(&:event_datetime).max < '20080806T073000'.to_time
+  end
+
+  def test_search_previous_with_offset
+    get :index, :q => 'coo', :offset => '20080806073000', :previous => '1'
+    assert_response :success
+    results = assigns(:results)
+    assert results.any?
+    assert results.map(&:event_datetime).min >= '20080806T073000'.to_time
+  end
+
+  def test_search_with_invalid_project_id
+    get :index, :id => 195, :q => 'recipe'
+    assert_response 404
+    assert_nil assigns(:results)
+  end
+
+  def test_quick_jump_to_issue
+    # issue of a public project
+    get :index, :q => "3"
+    assert_redirected_to '/issues/3'
+
+    # issue of a private project
+    get :index, :q => "4"
+    assert_response :success
+    assert_template 'index'
+  end
+
+  def test_large_integer
+    get :index, :q => '4615713488'
+    assert_response :success
+    assert_template 'index'
+  end
+
+  def test_tokens_with_quotes
+    get :index, :id => 1, :q => '"good bye" hello "bye bye"'
+    assert_equal ["good bye", "hello", "bye bye"], assigns(:tokens)
+  end
+
+  def test_results_should_be_escaped_once
+    assert Issue.find(1).update_attributes(:subject => '<subject> escaped_once', :description => '<description> escaped_once')
+    get :index, :q => 'escaped_once'
+    assert_response :success
+    assert_select '#search-results' do
+      assert_select 'dt.issue a', :text => /&lt;subject&gt;/
+      assert_select 'dd', :text => /&lt;description&gt;/
+    end
+  end
+
+  def test_keywords_should_be_highlighted
+    assert Issue.find(1).update_attributes(:subject => 'subject highlighted', :description => 'description highlighted')
+    get :index, :q => 'highlighted'
+    assert_response :success
+    assert_select '#search-results' do
+      assert_select 'dt.issue a span.highlight', :text => 'highlighted'
+      assert_select 'dd span.highlight', :text => 'highlighted'
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4d/4d32c1bf128521985a7cc66ecfe319a7797f8c8c.svn-base
--- /dev/null
+++ b/.svn/pristine/4d/4d32c1bf128521985a7cc66ecfe319a7797f8c8c.svn-base
@@ -0,0 +1,119 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class TimeEntry < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  # could have used polymorphic association
+  # project association here allows easy loading of time entries at project level with one database trip
+  belongs_to :project
+  belongs_to :issue
+  belongs_to :user
+  belongs_to :activity, :class_name => 'TimeEntryActivity', :foreign_key => 'activity_id'
+
+  attr_protected :project_id, :user_id, :tyear, :tmonth, :tweek
+
+  acts_as_customizable
+  acts_as_event :title => Proc.new {|o| "#{l_hours(o.hours)} (#{(o.issue || o.project).event_title})"},
+                :url => Proc.new {|o| {:controller => 'timelog', :action => 'index', :project_id => o.project, :issue_id => o.issue}},
+                :author => :user,
+                :group => :issue,
+                :description => :comments
+
+  acts_as_activity_provider :timestamp => "#{table_name}.created_on",
+                            :author_key => :user_id,
+                            :find_options => {:include => :project}
+
+  validates_presence_of :user_id, :activity_id, :project_id, :hours, :spent_on
+  validates_numericality_of :hours, :allow_nil => true, :message => :invalid
+  validates_length_of :comments, :maximum => 255, :allow_nil => true
+  validates :spent_on, :date => true
+  before_validation :set_project_if_nil
+  validate :validate_time_entry
+
+  scope :visible, lambda {|*args|
+    includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args))
+  }
+  scope :on_issue, lambda {|issue|
+    includes(:issue).where("#{Issue.table_name}.root_id = #{issue.root_id} AND #{Issue.table_name}.lft >= #{issue.lft} AND #{Issue.table_name}.rgt <= #{issue.rgt}")
+  }
+  scope :on_project, lambda {|project, include_subprojects|
+    includes(:project).where(project.project_condition(include_subprojects))
+  }
+  scope :spent_between, lambda {|from, to|
+    if from && to
+     where("#{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", from, to)
+    elsif from
+     where("#{TimeEntry.table_name}.spent_on >= ?", from)
+    elsif to
+     where("#{TimeEntry.table_name}.spent_on <= ?", to)
+    else
+     where(nil)
+    end
+  }
+
+  safe_attributes 'hours', 'comments', 'issue_id', 'activity_id', 'spent_on', 'custom_field_values', 'custom_fields'
+
+  def initialize(attributes=nil, *args)
+    super
+    if new_record? && self.activity.nil?
+      if default_activity = TimeEntryActivity.default
+        self.activity_id = default_activity.id
+      end
+      self.hours = nil if hours == 0
+    end
+  end
+
+  def set_project_if_nil
+    self.project = issue.project if issue && project.nil?
+  end
+
+  def validate_time_entry
+    errors.add :hours, :invalid if hours && (hours < 0 || hours >= 1000)
+    errors.add :project_id, :invalid if project.nil?
+    errors.add :issue_id, :invalid if (issue_id && !issue) || (issue && project!=issue.project)
+  end
+
+  def hours=(h)
+    write_attribute :hours, (h.is_a?(String) ? (h.to_hours || h) : h)
+  end
+
+  def hours
+    h = read_attribute(:hours)
+    if h.is_a?(Float)
+      h.round(2)
+    else
+      h
+    end
+  end
+
+  # tyear, tmonth, tweek assigned where setting spent_on attributes
+  # these attributes make time aggregations easier
+  def spent_on=(date)
+    super
+    if spent_on.is_a?(Time)
+      self.spent_on = spent_on.to_date
+    end
+    self.tyear = spent_on ? spent_on.year : nil
+    self.tmonth = spent_on ? spent_on.month : nil
+    self.tweek = spent_on ? Date.civil(spent_on.year, spent_on.month, spent_on.day).cweek : nil
+  end
+
+  # Returns true if the time entry can be edited by usr, otherwise false
+  def editable_by?(usr)
+    (usr == user && usr.allowed_to?(:edit_own_time_entries, project)) || usr.allowed_to?(:edit_time_entries, project)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4d/4d462e78d204c3aed1b100b04b6f63c31c637a6f.svn-base
--- a/.svn/pristine/4d/4d462e78d204c3aed1b100b04b6f63c31c637a6f.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar FA language
-// Author: Behrang Noroozinia, behrangn at g mail
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("ÛŒÚ©â€ŒØ´Ù†Ø¨Ù‡",
- "Ø¯ÙˆØ´Ù†Ø¨Ù‡",
- "Ø³Ù‡â€ŒØ´Ù†Ø¨Ù‡",
- "Ú†Ù‡Ø§Ø±Ø´Ù†Ø¨Ù‡",
- "Ù¾Ù†Ø¬â€ŒØ´Ù†Ø¨Ù‡",
- "Ø¢Ø¯ÛŒÙ†Ù‡",
- "Ø´Ù†Ø¨Ù‡",
- "ÛŒÚ©â€ŒØ´Ù†Ø¨Ù‡");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("ÛŒÚ©",
- "Ø¯Ùˆ",
- "Ø³Ù‡",
- "Ú†Ù‡Ø§Ø±",
- "Ù¾Ù†Ø¬",
- "Ø¢Ø¯ÛŒÙ†Ù‡",
- "Ø´Ù†Ø¨Ù‡",
- "ÛŒÚ©");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("Ú˜Ø§Ù†ÙˆÛŒÙ‡",
- "ÙÙˆØ±ÛŒÙ‡",
- "Ù…Ø§Ø±Ø³",
- "Ø¢ÙˆØ±ÛŒÙ„",
- "Ù…Ù‡",
- "Ú˜ÙˆØ¦Ù†",
- "Ú˜ÙˆØ¦ÛŒÙ‡",
- "Ø§ÙˆØª",
- "Ø³Ù¾ØªØ§Ù…Ø¨Ø±",
- "Ø§Ú©ØªØ¨Ø±",
- "Ù†ÙˆØ§Ù…Ø¨Ø±",
- "Ø¯Ø³Ø§Ù…Ø¨Ø±");
-
-// short month names
-Calendar._SMN = new Array
-("Ú˜Ø§Ù†",
- "ÙÙˆØ±",
- "Ù…Ø§Ø±",
- "Ø¢ÙˆØ±",
- "Ù…Ù‡",
- "Ú˜ÙˆØ¦Ù†",
- "Ú˜ÙˆØ¦ÛŒÙ‡",
- "Ø§ÙˆØª",
- "Ø³Ù¾Øª",
- "Ø§Ú©Øª",
- "Ù†ÙˆØ§",
- "Ø¯Ø³Ø§");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Ø¯Ø±Ø¨Ø§Ø±Ù‡ Ú¯Ø§Ù‡Ø´Ù…Ø§Ø±";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "Ø³Ø§Ù„ Ù¾ÛŒØ´ÛŒÙ† (Ø¨Ø±Ø§ÛŒ ÙÙ‡Ø±Ø³Øª Ù†Ú¯Ù‡ Ø¯Ø§Ø±ÛŒØ¯)";
-Calendar._TT["PREV_MONTH"] = "Ù…Ø§Ù‡ Ù¾ÛŒØ´ÛŒÙ† ( Ø¨Ø±Ø§ÛŒ ÙÙ‡Ø±Ø³Øª Ù†Ú¯Ù‡ Ø¯Ø§Ø±ÛŒØ¯)";
-Calendar._TT["GO_TODAY"] = "Ø¨Ø±Ùˆ Ø¨Ù‡ Ø§Ù…Ø±ÙˆØ²";
-Calendar._TT["NEXT_MONTH"] = "Ù…Ø§Ù‡ Ù¾Ø³ÛŒÙ† (Ø¨Ø±Ø§ÛŒ ÙÙ‡Ø±Ø³Øª Ù†Ú¯Ù‡ Ø¯Ø§Ø±ÛŒØ¯)";
-Calendar._TT["NEXT_YEAR"] = "Ø³Ø§Ù„ Ù¾Ø³ÛŒÙ† (Ø¨Ø±Ø§ÛŒ ÙÙ‡Ø±Ø³Øª Ù†Ú¯Ù‡ Ø¯Ø§Ø±ÛŒØ¯)";
-Calendar._TT["SEL_DATE"] = "Ú¯Ø²ÛŒÙ†Ø´";
-Calendar._TT["DRAG_TO_MOVE"] = "Ø¨Ø±Ø§ÛŒ Ø¬Ø§Ø¨Ø¬Ø§ÛŒÛŒ Ø¨Ú©Ø´ÛŒØ¯";
-Calendar._TT["PART_TODAY"] = " (Ø§Ù…Ø±ÙˆØ²)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Ø¢ØºØ§Ø² Ù‡ÙØªÙ‡ Ø§Ø² %s";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "4,5";
-
-Calendar._TT["CLOSE"] = "Ø¨Ø³ØªÙ‡";
-Calendar._TT["TODAY"] = "Ø§Ù…Ø±ÙˆØ²";
-Calendar._TT["TIME_PART"] = "Ø²Ø¯Ù† (Ø¨Ø§ Shift) ÛŒØ§ Ú©Ø´ÛŒØ¯Ù† Ø¨Ø±Ø§ÛŒ ÙˆÛŒØ±Ø§ÛŒØ´";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "Ù‡ÙØªÙ‡";
-Calendar._TT["TIME"] = "Ø²Ù…Ø§Ù†:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4d/4d4d388d3654f2fbefb4fdd7c3e99a9ffa1a3eeb.svn-base
--- /dev/null
+++ b/.svn/pristine/4d/4d4d388d3654f2fbefb4fdd7c3e99a9ffa1a3eeb.svn-base
@@ -0,0 +1,48 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class GanttsController < ApplicationController
+  menu_item :gantt
+  before_filter :find_optional_project
+
+  rescue_from Query::StatementInvalid, :with => :query_statement_invalid
+
+  helper :gantt
+  helper :issues
+  helper :projects
+  helper :queries
+  include QueriesHelper
+  helper :sort
+  include SortHelper
+  include Redmine::Export::PDF
+
+  def show
+    @gantt = Redmine::Helpers::Gantt.new(params)
+    @gantt.project = @project
+    retrieve_query
+    @query.group_by = nil
+    @gantt.query = @query if @query.valid?
+
+    basename = (@project ? "#{@project.identifier}-" : '') + 'gantt'
+
+    respond_to do |format|
+      format.html { render :action => "show", :layout => !request.xhr? }
+      format.png  { send_data(@gantt.to_image, :disposition => 'inline', :type => 'image/png', :filename => "#{basename}.png") } if @gantt.respond_to?('to_image')
+      format.pdf  { send_data(@gantt.to_pdf, :type => 'application/pdf', :filename => "#{basename}.pdf") }
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4d/4d670f96a6b54a9bfc31fb5cbe3121575a7b05e8.svn-base
--- /dev/null
+++ b/.svn/pristine/4d/4d670f96a6b54a9bfc31fb5cbe3121575a7b05e8.svn-base
@@ -0,0 +1,434 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../../test_helper', __FILE__)
+begin
+  require 'mocha'
+
+  class MercurialAdapterTest < ActiveSupport::TestCase
+    HELPERS_DIR        = Redmine::Scm::Adapters::MercurialAdapter::HELPERS_DIR
+    TEMPLATE_NAME      = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_NAME
+    TEMPLATE_EXTENSION = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_EXTENSION
+
+    REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
+    CHAR_1_HEX = "\xc3\x9c"
+
+    if File.directory?(REPOSITORY_PATH)
+      def setup
+        adapter_class = Redmine::Scm::Adapters::MercurialAdapter
+        assert adapter_class
+        assert adapter_class.client_command
+        assert_equal true, adapter_class.client_available
+        assert_equal true, adapter_class.client_version_above?([0, 9, 5])
+
+        @adapter = Redmine::Scm::Adapters::MercurialAdapter.new(
+                              REPOSITORY_PATH,
+                              nil,
+                              nil,
+                              nil,
+                             'ISO-8859-1')
+        @diff_c_support = true
+        @char_1        = CHAR_1_HEX.dup
+        @tag_char_1    = "tag-#{CHAR_1_HEX}-00"
+        @branch_char_0 = "branch-#{CHAR_1_HEX}-00"
+        @branch_char_1 = "branch-#{CHAR_1_HEX}-01"
+        if @tag_char_1.respond_to?(:force_encoding)
+          @char_1.force_encoding('UTF-8')
+          @tag_char_1.force_encoding('UTF-8')
+          @branch_char_0.force_encoding('UTF-8')
+          @branch_char_1.force_encoding('UTF-8')
+        end
+      end
+
+      def test_hgversion
+        to_test = { "Mercurial Distributed SCM (version 0.9.5)\n"  => [0,9,5],
+                    "Mercurial Distributed SCM (1.0)\n"            => [1,0],
+                    "Mercurial Distributed SCM (1e4ddc9ac9f7+20080325)\n" => nil,
+                    "Mercurial Distributed SCM (1.0.1+20080525)\n" => [1,0,1],
+                    "Mercurial Distributed SCM (1916e629a29d)\n"   => nil,
+                    "Mercurial SCM Distribuito (versione 0.9.5)\n" => [0,9,5],
+                    "(1.6)\n(1.7)\n(1.8)"                          => [1,6],
+                    "(1.7.1)\r\n(1.8.1)\r\n(1.9.1)"                => [1,7,1]}
+
+        to_test.each do |s, v|
+          test_hgversion_for(s, v)
+        end
+      end
+
+      def test_template_path
+        to_test = {
+                    [1,2]    => "1.0",
+                    []       => "1.0",
+                    [1,2,1]  => "1.0",
+                    [1,7]    => "1.0",
+                    [1,7,1]  => "1.0",
+                    [2,0]    => "1.0",
+                   }
+        to_test.each do |v, template|
+          test_template_path_for(v, template)
+        end
+      end
+
+      def test_info
+        [REPOSITORY_PATH, REPOSITORY_PATH + "/",
+             REPOSITORY_PATH + "//"].each do |repo|
+          adp = Redmine::Scm::Adapters::MercurialAdapter.new(repo)
+          repo_path =  adp.info.root_url.gsub(/\\/, "/")
+          assert_equal REPOSITORY_PATH, repo_path
+          assert_equal '31', adp.info.lastrev.revision
+          assert_equal '31eeee7395c8',adp.info.lastrev.scmid
+        end
+      end
+
+      def test_revisions
+        revisions = @adapter.revisions(nil, 2, 4)
+        assert_equal 3, revisions.size
+        assert_equal '2', revisions[0].revision
+        assert_equal '400bb8672109', revisions[0].scmid
+        assert_equal '4', revisions[2].revision
+        assert_equal 'def6d2f1254a', revisions[2].scmid
+
+        revisions = @adapter.revisions(nil, 2, 4, {:limit => 2})
+        assert_equal 2, revisions.size
+        assert_equal '2', revisions[0].revision
+        assert_equal '400bb8672109', revisions[0].scmid
+      end
+
+      def test_parents
+        revs1 = @adapter.revisions(nil, 0, 0)
+        assert_equal 1, revs1.size
+        assert_equal [], revs1[0].parents
+        revs2 = @adapter.revisions(nil, 1, 1)
+        assert_equal 1, revs2.size
+        assert_equal 1, revs2[0].parents.size
+        assert_equal "0885933ad4f6", revs2[0].parents[0]
+        revs3 = @adapter.revisions(nil, 30, 30)
+        assert_equal 1, revs3.size
+        assert_equal 2, revs3[0].parents.size
+        assert_equal "a94b0528f24f", revs3[0].parents[0]
+        assert_equal "3a330eb32958", revs3[0].parents[1]
+      end
+
+      def test_diff
+        if @adapter.class.client_version_above?([1, 2])
+          assert_nil @adapter.diff(nil, '100000')
+        end
+        assert_nil @adapter.diff(nil, '100000', '200000')
+        [2, '400bb8672109', '400', 400].each do |r1|
+          diff1 = @adapter.diff(nil, r1)
+          if @diff_c_support
+            assert_equal 28, diff1.size
+            buf = diff1[24].gsub(/\r\n|\r|\n/, "")
+            assert_equal "+    return true unless klass.respond_to?('watched_by')", buf
+          else
+            assert_equal 0, diff1.size
+          end
+          [4, 'def6d2f1254a'].each do |r2|
+            diff2 = @adapter.diff(nil, r1, r2)
+            assert_equal 49, diff2.size
+            buf =  diff2[41].gsub(/\r\n|\r|\n/, "")
+            assert_equal "+class WelcomeController < ApplicationController", buf
+            diff3 = @adapter.diff('sources/watchers_controller.rb', r1, r2)
+            assert_equal 20, diff3.size
+            buf =  diff3[12].gsub(/\r\n|\r|\n/, "")
+            assert_equal "+    @watched.remove_watcher(user)", buf
+
+            diff4 = @adapter.diff(nil, r2, r1)
+            assert_equal 49, diff4.size
+            buf =  diff4[41].gsub(/\r\n|\r|\n/, "")
+            assert_equal "-class WelcomeController < ApplicationController", buf
+            diff5 = @adapter.diff('sources/watchers_controller.rb', r2, r1)
+            assert_equal 20, diff5.size
+            buf =  diff5[9].gsub(/\r\n|\r|\n/, "")
+            assert_equal "-    @watched.remove_watcher(user)", buf
+          end
+        end
+      end
+
+      def test_diff_made_by_revision
+        if @diff_c_support
+          [24, '24', '4cddb4e45f52'].each do |r1|
+            diff1 = @adapter.diff(nil, r1)
+            assert_equal 5, diff1.size
+            buf = diff1[4].gsub(/\r\n|\r|\n/, "")
+            assert_equal '+0885933ad4f68d77c2649cd11f8311276e7ef7ce tag-init-revision', buf
+          end
+        end
+      end
+
+      def test_cat
+        [2, '400bb8672109', '400', 400].each do |r|
+          buf = @adapter.cat('sources/welcome_controller.rb', r)
+          assert buf
+          lines = buf.split("\r\n")
+          assert_equal 25, lines.length
+          assert_equal 'class WelcomeController < ApplicationController', lines[17]
+        end
+        assert_nil @adapter.cat('sources/welcome_controller.rb')
+      end
+
+      def test_annotate
+        assert_equal [], @adapter.annotate("sources/welcome_controller.rb").lines
+        [2, '400bb8672109', '400', 400].each do |r|
+          ann = @adapter.annotate('sources/welcome_controller.rb', r)
+          assert ann
+          assert_equal '1', ann.revisions[17].revision
+          assert_equal '9d5b5b004199', ann.revisions[17].identifier
+          assert_equal 'jsmith', ann.revisions[0].author
+          assert_equal 25, ann.lines.length
+          assert_equal 'class WelcomeController < ApplicationController', ann.lines[17]
+        end
+      end
+
+      def test_entries
+        assert_nil @adapter.entries(nil, '100000')
+
+        assert_equal 1, @adapter.entries("sources", 3).size
+        assert_equal 1, @adapter.entries("sources", 'b3a615152df8').size
+
+        [2, '400bb8672109', '400', 400].each do |r|
+          entries1 = @adapter.entries(nil, r)
+          assert entries1
+          assert_equal 3, entries1.size
+          assert_equal 'sources', entries1[1].name
+          assert_equal 'sources', entries1[1].path
+          assert_equal 'dir', entries1[1].kind
+          readme = entries1[2]
+          assert_equal 'README', readme.name
+          assert_equal 'README', readme.path
+          assert_equal 'file', readme.kind
+          assert_equal 27, readme.size
+          assert_equal '1', readme.lastrev.revision
+          assert_equal '9d5b5b004199', readme.lastrev.identifier
+          # 2007-12-14 10:24:01 +0100
+          assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time
+
+          entries2 = @adapter.entries('sources', r)
+          assert entries2
+          assert_equal 2, entries2.size
+          assert_equal 'watchers_controller.rb', entries2[0].name
+          assert_equal 'sources/watchers_controller.rb', entries2[0].path
+          assert_equal 'file', entries2[0].kind
+          assert_equal 'welcome_controller.rb', entries2[1].name
+          assert_equal 'sources/welcome_controller.rb', entries2[1].path
+          assert_equal 'file', entries2[1].kind
+        end
+      end
+
+      def test_entries_tag
+        entries1 = @adapter.entries(nil, 'tag_test.00')
+        assert entries1
+        assert_equal 3, entries1.size
+        assert_equal 'sources', entries1[1].name
+        assert_equal 'sources', entries1[1].path
+        assert_equal 'dir', entries1[1].kind
+        readme = entries1[2]
+        assert_equal 'README', readme.name
+        assert_equal 'README', readme.path
+        assert_equal 'file', readme.kind
+        assert_equal 21, readme.size
+        assert_equal '0', readme.lastrev.revision
+        assert_equal '0885933ad4f6', readme.lastrev.identifier
+        # 2007-12-14 10:22:52 +0100
+        assert_equal Time.gm(2007, 12, 14, 9, 22, 52), readme.lastrev.time
+      end
+
+      def test_entries_branch
+        entries1 = @adapter.entries(nil, 'test-branch-00')
+        assert entries1
+        assert_equal 5, entries1.size
+        assert_equal 'sql_escape', entries1[2].name
+        assert_equal 'sql_escape', entries1[2].path
+        assert_equal 'dir', entries1[2].kind
+        readme = entries1[4]
+        assert_equal 'README', readme.name
+        assert_equal 'README', readme.path
+        assert_equal 'file', readme.kind
+        assert_equal 365, readme.size
+        assert_equal '8', readme.lastrev.revision
+        assert_equal 'c51f5bb613cd', readme.lastrev.identifier
+        # 2001-02-01 00:00:00 -0900
+        assert_equal Time.gm(2001, 2, 1, 9, 0, 0), readme.lastrev.time
+      end
+
+      def test_locate_on_outdated_repository
+        assert_equal 1, @adapter.entries("images", 0).size
+        assert_equal 2, @adapter.entries("images").size
+        assert_equal 2, @adapter.entries("images", 2).size
+      end
+
+      def test_access_by_nodeid
+        path = 'sources/welcome_controller.rb'
+        assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400bb8672109')
+      end
+
+      def test_access_by_fuzzy_nodeid
+        path = 'sources/welcome_controller.rb'
+        # falls back to nodeid
+        assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400')
+      end
+
+      def test_tags
+        assert_equal [@tag_char_1, 'tag_test.00', 'tag-init-revision'], @adapter.tags
+      end
+
+      def test_tagmap
+        tm = {
+          @tag_char_1         => 'adf805632193',
+          'tag_test.00'       => '6987191f453a',
+          'tag-init-revision' => '0885933ad4f6',
+          }
+        assert_equal tm, @adapter.tagmap
+      end
+
+      def test_branches
+        brs = []
+        @adapter.branches.each do |b|
+          brs << b
+        end
+        assert_equal 7, brs.length
+        assert_equal 'default', brs[0].to_s
+        assert_equal '31', brs[0].revision
+        assert_equal '31eeee7395c8', brs[0].scmid
+        assert_equal 'test-branch-01', brs[1].to_s
+        assert_equal '30', brs[1].revision
+        assert_equal 'ad4dc4f80284', brs[1].scmid
+        assert_equal @branch_char_1, brs[2].to_s
+        assert_equal '27', brs[2].revision
+        assert_equal '7bbf4c738e71', brs[2].scmid
+        assert_equal 'branch (1)[2]&,%.-3_4', brs[3].to_s
+        assert_equal '25', brs[3].revision
+        assert_equal 'afc61e85bde7', brs[3].scmid
+        assert_equal @branch_char_0, brs[4].to_s
+        assert_equal '23', brs[4].revision
+        assert_equal 'c8d3e4887474', brs[4].scmid
+        assert_equal 'test_branch.latin-1', brs[5].to_s
+        assert_equal '22', brs[5].revision
+        assert_equal 'c2ffe7da686a', brs[5].scmid
+        assert_equal 'test-branch-00', brs[6].to_s
+        assert_equal '13', brs[6].revision
+        assert_equal '3a330eb32958', brs[6].scmid
+      end
+
+      def test_branchmap
+        bm = {
+           'default'               => '31eeee7395c8',
+           'test_branch.latin-1'   => 'c2ffe7da686a',
+           'branch (1)[2]&,%.-3_4' => 'afc61e85bde7',
+           'test-branch-00'        => '3a330eb32958',
+           "test-branch-01"        => 'ad4dc4f80284',
+           @branch_char_0          => 'c8d3e4887474',
+           @branch_char_1          => '7bbf4c738e71',
+         }
+        assert_equal bm, @adapter.branchmap
+      end
+
+      def test_path_space
+        p = 'README (1)[2]&,%.-3_4'
+        [15, '933ca60293d7'].each do |r1|
+          assert @adapter.diff(p, r1)
+          assert @adapter.cat(p, r1)
+          assert_equal 1, @adapter.annotate(p, r1).lines.length
+          [25, 'afc61e85bde7'].each do |r2|
+            assert @adapter.diff(p, r1, r2)
+          end
+        end
+      end
+
+      def test_tag_non_ascii
+        p = "latin-1-dir/test-#{@char_1}-1.txt"
+        assert @adapter.cat(p, @tag_char_1)
+        assert_equal 1, @adapter.annotate(p, @tag_char_1).lines.length
+      end
+
+      def test_branch_non_ascii
+        p = "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-1.txt"
+        assert @adapter.cat(p, @branch_char_1)
+        assert_equal 1, @adapter.annotate(p, @branch_char_1).lines.length
+      end
+
+      def test_nodes_in_branch
+         [
+            'default',
+            @branch_char_1,
+            'branch (1)[2]&,%.-3_4',
+            @branch_char_0,
+            'test_branch.latin-1',
+            'test-branch-00',
+               ].each do |bra|
+          nib0 = @adapter.nodes_in_branch(bra)
+          assert nib0
+          nib1 = @adapter.nodes_in_branch(bra, :limit => 1)
+          assert_equal 1, nib1.size
+          case bra
+            when 'branch (1)[2]&,%.-3_4'
+              if @adapter.class.client_version_above?([1, 6])
+                assert_equal 3, nib0.size
+                assert_equal nib0[0], 'afc61e85bde7'
+                nib2 = @adapter.nodes_in_branch(bra, :limit => 2)
+                assert_equal 2, nib2.size
+                assert_equal nib2[1], '933ca60293d7'
+              end
+            when @branch_char_1
+              if @adapter.class.client_version_above?([1, 6])
+                assert_equal 2, nib0.size
+                assert_equal nib0[1], '08ff3227303e'
+                nib2 = @adapter.nodes_in_branch(bra, :limit => 1)
+                assert_equal 1, nib2.size
+                assert_equal nib2[0], '7bbf4c738e71'
+              end
+          end
+        end
+      end
+
+      def test_path_encoding_default_utf8
+        adpt1 = Redmine::Scm::Adapters::MercurialAdapter.new(
+                                  REPOSITORY_PATH
+                                )
+        assert_equal "UTF-8", adpt1.path_encoding
+        adpt2 = Redmine::Scm::Adapters::MercurialAdapter.new(
+                                  REPOSITORY_PATH,
+                                  nil,
+                                  nil,
+                                  nil,
+                                  ""
+                                )
+        assert_equal "UTF-8", adpt2.path_encoding
+      end
+
+      private
+
+      def test_hgversion_for(hgversion, version)
+        @adapter.class.expects(:hgversion_from_command_line).returns(hgversion)
+        assert_equal version, @adapter.class.hgversion
+      end
+
+      def test_template_path_for(version, template)
+        assert_equal "#{HELPERS_DIR}/#{TEMPLATE_NAME}-#{template}.#{TEMPLATE_EXTENSION}",
+                     @adapter.class.template_path_for(version)
+        assert File.exist?(@adapter.class.template_path_for(version))
+      end
+    else
+      puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!"
+      def test_fake; assert true end
+    end
+  end
+rescue LoadError
+  class MercurialMochaFake < ActiveSupport::TestCase
+    def test_fake; assert(false, "Requires mocha to run those tests")  end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4d/4db1f392c52d1c52ef2d37c9a27b017bd4d891ac.svn-base
--- a/.svn/pristine/4d/4db1f392c52d1c52ef2d37c9a27b017bd4d891ac.svn-base
+++ /dev/null
@@ -1,278 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine #:nodoc:
-
-  class PluginNotFound < StandardError; end
-  class PluginRequirementError < StandardError; end
-
-  # Base class for Redmine plugins.
-  # Plugins are registered using the <tt>register</tt> class method that acts as the public constructor.
-  #
-  #   Redmine::Plugin.register :example do
-  #     name 'Example plugin'
-  #     author 'John Smith'
-  #     description 'This is an example plugin for Redmine'
-  #     version '0.0.1'
-  #     settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'
-  #   end
-  #
-  # === Plugin attributes
-  #
-  # +settings+ is an optional attribute that let the plugin be configurable.
-  # It must be a hash with the following keys:
-  # * <tt>:default</tt>: default value for the plugin settings
-  # * <tt>:partial</tt>: path of the configuration partial view, relative to the plugin <tt>app/views</tt> directory
-  # Example:
-  #   settings :default => {'foo'=>'bar'}, :partial => 'settings/settings'
-  # In this example, the settings partial will be found here in the plugin directory: <tt>app/views/settings/_settings.rhtml</tt>.
-  #
-  # When rendered, the plugin settings value is available as the local variable +settings+
-  class Plugin
-    @registered_plugins = {}
-    class << self
-      attr_reader :registered_plugins
-      private :new
-
-      def def_field(*names)
-        class_eval do
-          names.each do |name|
-            define_method(name) do |*args|
-              args.empty? ? instance_variable_get("@#{name}") : instance_variable_set("@#{name}", *args)
-            end
-          end
-        end
-      end
-    end
-    def_field :name, :description, :url, :author, :author_url, :version, :settings
-    attr_reader :id
-
-    # Plugin constructor
-    def self.register(id, &block)
-      p = new(id)
-      p.instance_eval(&block)
-      # Set a default name if it was not provided during registration
-      p.name(id.to_s.humanize) if p.name.nil?
-      # Adds plugin locales if any
-      # YAML translation files should be found under <plugin>/config/locales/
-      ::I18n.load_path += Dir.glob(File.join(Rails.root, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml'))
-      registered_plugins[id] = p
-    end
-
-    # Returns an array of all registered plugins
-    def self.all
-      registered_plugins.values.sort
-    end
-
-    # Finds a plugin by its id
-    # Returns a PluginNotFound exception if the plugin doesn't exist
-    def self.find(id)
-      registered_plugins[id.to_sym] || raise(PluginNotFound)
-    end
-
-    # Clears the registered plugins hash
-    # It doesn't unload installed plugins
-    def self.clear
-      @registered_plugins = {}
-    end
-
-    # Checks if a plugin is installed
-    #
-    # @param [String] id name of the plugin
-    def self.installed?(id)
-      registered_plugins[id.to_sym].present?
-    end
-
-    def initialize(id)
-      @id = id.to_sym
-    end
-
-    def <=>(plugin)
-      self.id.to_s <=> plugin.id.to_s
-    end
-
-    # Sets a requirement on Redmine version
-    # Raises a PluginRequirementError exception if the requirement is not met
-    #
-    # Examples
-    #   # Requires Redmine 0.7.3 or higher
-    #   requires_redmine :version_or_higher => '0.7.3'
-    #   requires_redmine '0.7.3'
-    #
-    #   # Requires a specific Redmine version
-    #   requires_redmine :version => '0.7.3'              # 0.7.3 only
-    #   requires_redmine :version => ['0.7.3', '0.8.0']   # 0.7.3 or 0.8.0
-    def requires_redmine(arg)
-      arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
-      arg.assert_valid_keys(:version, :version_or_higher)
-
-      current = Redmine::VERSION.to_a
-      arg.each do |k, v|
-        v = [] << v unless v.is_a?(Array)
-        versions = v.collect {|s| s.split('.').collect(&:to_i)}
-        case k
-        when :version_or_higher
-          raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
-          unless (current <=> versions.first) >= 0
-            raise PluginRequirementError.new("#{id} plugin requires Redmine #{v} or higher but current is #{current.join('.')}")
-          end
-        when :version
-          unless versions.include?(current.slice(0,3))
-            raise PluginRequirementError.new("#{id} plugin requires one the following Redmine versions: #{v.join(', ')} but current is #{current.join('.')}")
-          end
-        end
-      end
-      true
-    end
-
-    # Sets a requirement on a Redmine plugin version
-    # Raises a PluginRequirementError exception if the requirement is not met
-    #
-    # Examples
-    #   # Requires a plugin named :foo version 0.7.3 or higher
-    #   requires_redmine_plugin :foo, :version_or_higher => '0.7.3'
-    #   requires_redmine_plugin :foo, '0.7.3'
-    #
-    #   # Requires a specific version of a Redmine plugin
-    #   requires_redmine_plugin :foo, :version => '0.7.3'              # 0.7.3 only
-    #   requires_redmine_plugin :foo, :version => ['0.7.3', '0.8.0']   # 0.7.3 or 0.8.0
-    def requires_redmine_plugin(plugin_name, arg)
-      arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
-      arg.assert_valid_keys(:version, :version_or_higher)
-
-      plugin = Plugin.find(plugin_name)
-      current = plugin.version.split('.').collect(&:to_i)
-
-      arg.each do |k, v|
-        v = [] << v unless v.is_a?(Array)
-        versions = v.collect {|s| s.split('.').collect(&:to_i)}
-        case k
-        when :version_or_higher
-          raise ArgumentError.new("wrong number of versions (#{versions.size} for 1)") unless versions.size == 1
-          unless (current <=> versions.first) >= 0
-            raise PluginRequirementError.new("#{id} plugin requires the #{plugin_name} plugin #{v} or higher but current is #{current.join('.')}")
-          end
-        when :version
-          unless versions.include?(current.slice(0,3))
-            raise PluginRequirementError.new("#{id} plugin requires one the following versions of #{plugin_name}: #{v.join(', ')} but current is #{current.join('.')}")
-          end
-        end
-      end
-      true
-    end
-
-    # Adds an item to the given +menu+.
-    # The +id+ parameter (equals to the project id) is automatically added to the url.
-    #   menu :project_menu, :plugin_example, { :controller => 'example', :action => 'say_hello' }, :caption => 'Sample'
-    #
-    # +name+ parameter can be: :top_menu, :account_menu, :application_menu or :project_menu
-    #
-    def menu(menu, item, url, options={})
-      Redmine::MenuManager.map(menu).push(item, url, options)
-    end
-    alias :add_menu_item :menu
-
-    # Removes +item+ from the given +menu+.
-    def delete_menu_item(menu, item)
-      Redmine::MenuManager.map(menu).delete(item)
-    end
-
-    # Defines a permission called +name+ for the given +actions+.
-    #
-    # The +actions+ argument is a hash with controllers as keys and actions as values (a single value or an array):
-    #   permission :destroy_contacts, { :contacts => :destroy }
-    #   permission :view_contacts, { :contacts => [:index, :show] }
-    #
-    # The +options+ argument can be used to make the permission public (implicitly given to any user)
-    # or to restrict users the permission can be given to.
-    #
-    # Examples
-    #   # A permission that is implicitly given to any user
-    #   # This permission won't appear on the Roles & Permissions setup screen
-    #   permission :say_hello, { :example => :say_hello }, :public => true
-    #
-    #   # A permission that can be given to any user
-    #   permission :say_hello, { :example => :say_hello }
-    #
-    #   # A permission that can be given to registered users only
-    #   permission :say_hello, { :example => :say_hello }, :require => :loggedin
-    #
-    #   # A permission that can be given to project members only
-    #   permission :say_hello, { :example => :say_hello }, :require => :member
-    def permission(name, actions, options = {})
-      if @project_module
-        Redmine::AccessControl.map {|map| map.project_module(@project_module) {|map|map.permission(name, actions, options)}}
-      else
-        Redmine::AccessControl.map {|map| map.permission(name, actions, options)}
-      end
-    end
-
-    # Defines a project module, that can be enabled/disabled for each project.
-    # Permissions defined inside +block+ will be bind to the module.
-    #
-    #   project_module :things do
-    #     permission :view_contacts, { :contacts => [:list, :show] }, :public => true
-    #     permission :destroy_contacts, { :contacts => :destroy }
-    #   end
-    def project_module(name, &block)
-      @project_module = name
-      self.instance_eval(&block)
-      @project_module = nil
-    end
-
-    # Registers an activity provider.
-    #
-    # Options:
-    # * <tt>:class_name</tt> - one or more model(s) that provide these events (inferred from event_type by default)
-    # * <tt>:default</tt> - setting this option to false will make the events not displayed by default
-    #
-    # A model can provide several activity event types.
-    #
-    # Examples:
-    #   register :news
-    #   register :scrums, :class_name => 'Meeting'
-    #   register :issues, :class_name => ['Issue', 'Journal']
-    #
-    # Retrieving events:
-    # Associated model(s) must implement the find_events class method.
-    # ActiveRecord models can use acts_as_activity_provider as a way to implement this class method.
-    #
-    # The following call should return all the scrum events visible by current user that occured in the 5 last days:
-    #   Meeting.find_events('scrums', User.current, 5.days.ago, Date.today)
-    #   Meeting.find_events('scrums', User.current, 5.days.ago, Date.today, :project => foo) # events for project foo only
-    #
-    # Note that :view_scrums permission is required to view these events in the activity view.
-    def activity_provider(*args)
-      Redmine::Activity.register(*args)
-    end
-
-    # Registers a wiki formatter.
-    #
-    # Parameters:
-    # * +name+ - human-readable name
-    # * +formatter+ - formatter class, which should have an instance method +to_html+
-    # * +helper+ - helper module, which will be included by wiki pages
-    def wiki_format_provider(name, formatter, helper)
-      Redmine::WikiFormatting.register(name, formatter, helper)
-    end
-
-    # Returns +true+ if the plugin can be configured.
-    def configurable?
-      settings && settings.is_a?(Hash) && !settings[:partial].blank?
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4d/4db92861e8516d6d862c43d4820c7fc671e920ed.svn-base
--- /dev/null
+++ b/.svn/pristine/4d/4db92861e8516d6d862c43d4820c7fc671e920ed.svn-base
@@ -0,0 +1,1110 @@
+# Finnish translations for Ruby on Rails
+# by Marko SeppÃ¤ (marko.seppa@gmail.com)
+
+fi:
+  direction: ltr
+  date:
+    formats:
+      default: "%e. %Bta %Y"
+      long: "%A%e. %Bta %Y"
+      short: "%e.%m.%Y"
+
+    day_names: [Sunnuntai, Maanantai, Tiistai, Keskiviikko, Torstai, Perjantai, Lauantai]
+    abbr_day_names: [Su, Ma, Ti, Ke, To, Pe, La]
+    month_names: [~, Tammikuu, Helmikuu, Maaliskuu, Huhtikuu, Toukokuu, KesÃ¤kuu, HeinÃ¤kuu, Elokuu, Syyskuu, Lokakuu, Marraskuu, Joulukuu]
+    abbr_month_names: [~, Tammi, Helmi, Maalis, Huhti, Touko, KesÃ¤, HeinÃ¤, Elo, Syys, Loka, Marras, Joulu]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a, %e. %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%e. %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "aamupÃ¤ivÃ¤"
+    pm: "iltapÃ¤ivÃ¤"
+
+  support:
+    array:
+      words_connector: ", "
+      two_words_connector: " ja "
+      last_word_connector: " ja "
+
+
+
+  number:
+    format:
+      separator: ","
+      delimiter: "."
+      precision: 3
+
+    currency:
+      format:
+        format: "%n %u"
+        unit: "â‚¬"
+        separator: ","
+        delimiter: "."
+        precision: 2
+
+    percentage:
+      format:
+        # separator:
+        delimiter: ""
+        # precision:
+
+    precision:
+      format:
+        # separator:
+        delimiter: ""
+        # precision:
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Tavua"
+            other: "Tavua"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "puoli minuuttia"
+      less_than_x_seconds:
+        one:   "aiemmin kuin sekunti"
+        other: "aiemmin kuin %{count} sekuntia"
+      x_seconds:
+        one:   "sekunti"
+        other: "%{count} sekuntia"
+      less_than_x_minutes:
+        one:   "aiemmin kuin minuutti"
+        other: "aiemmin kuin %{count} minuuttia"
+      x_minutes:
+        one:   "minuutti"
+        other: "%{count} minuuttia"
+      about_x_hours:
+        one:   "noin tunti"
+        other: "noin %{count} tuntia"
+      x_hours:
+        one:   "1 tunti"
+        other: "%{count} tuntia"
+      x_days:
+        one:   "pÃ¤ivÃ¤"
+        other: "%{count} pÃ¤ivÃ¤Ã¤"
+      about_x_months:
+        one:   "noin kuukausi"
+        other: "noin %{count} kuukautta"
+      x_months:
+        one:   "kuukausi"
+        other: "%{count} kuukautta"
+      about_x_years:
+        one:   "vuosi"
+        other: "noin %{count} vuotta"
+      over_x_years:
+        one:   "yli vuosi"
+        other: "yli %{count} vuotta"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+    prompts:
+      year:   "Vuosi"
+      month:  "Kuukausi"
+      day:    "PÃ¤ivÃ¤"
+      hour:   "Tunti"
+      minute: "Minuutti"
+      second: "Sekuntia"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 virhe esti tÃ¤mÃ¤n %{model} mallinteen tallentamisen"
+          other:  "%{count} virhettÃ¤ esti tÃ¤mÃ¤n %{model} mallinteen tallentamisen"
+        body: "Seuraavat kentÃ¤t aiheuttivat ongelmia:"
+      messages:
+        inclusion: "ei lÃ¶ydy listauksesta"
+        exclusion: "on jo varattu"
+        invalid: "on kelvoton"
+        confirmation: "ei vastaa varmennusta"
+        accepted: "tÃ¤ytyy olla hyvÃ¤ksytty"
+        empty: "ei voi olla tyhjÃ¤"
+        blank: "ei voi olla sisÃ¤llÃ¶tÃ¶n"
+        too_long: "on liian pitkÃ¤ (maksimi on %{count} merkkiÃ¤)"
+        too_short: "on liian lyhyt (minimi on %{count} merkkiÃ¤)"
+        wrong_length: "on vÃ¤Ã¤rÃ¤n pituinen (tÃ¤ytyy olla tÃ¤smÃ¤lleen %{count} merkkiÃ¤)"
+        taken: "on jo kÃ¤ytÃ¶ssÃ¤"
+        not_a_number: "ei ole numero"
+        greater_than: "tÃ¤ytyy olla suurempi kuin %{count}"
+        greater_than_or_equal_to: "tÃ¤ytyy olla suurempi tai yhtÃ¤ suuri kuin%{count}"
+        equal_to: "tÃ¤ytyy olla yhtÃ¤ suuri kuin %{count}"
+        less_than: "tÃ¤ytyy olla pienempi kuin %{count}"
+        less_than_or_equal_to: "tÃ¤ytyy olla pienempi tai yhtÃ¤ suuri kuin %{count}"
+        odd: "tÃ¤ytyy olla pariton"
+        even: "tÃ¤ytyy olla parillinen"
+        greater_than_start_date: "tulee olla aloituspÃ¤ivÃ¤n jÃ¤lkeinen"
+        not_same_project: "ei kuulu samaan projektiin"
+        circular_dependency: "TÃ¤mÃ¤ suhde loisi kehÃ¤n."
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: Valitse, ole hyvÃ¤
+
+  general_text_No: 'Ei'
+  general_text_Yes: 'KyllÃ¤'
+  general_text_no: 'ei'
+  general_text_yes: 'kyllÃ¤'
+  general_lang_name: 'Finnish (Suomi)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-15
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Tilin pÃ¤ivitys onnistui.
+  notice_account_invalid_creditentials: Virheellinen kÃ¤yttÃ¤jÃ¤tunnus tai salasana
+  notice_account_password_updated: Salasanan pÃ¤ivitys onnistui.
+  notice_account_wrong_password: VÃ¤Ã¤rÃ¤ salasana
+  notice_account_register_done: Tilin luonti onnistui. Aktivoidaksesi tilin seuraa linkkiÃ¤ joka vÃ¤litettiin sÃ¤hkÃ¶postiisi.
+  notice_account_unknown_email: Tuntematon kÃ¤yttÃ¤jÃ¤.
+  notice_can_t_change_password: TÃ¤mÃ¤ tili kÃ¤yttÃ¤Ã¤ ulkoista tunnistautumisjÃ¤rjestelmÃ¤Ã¤. Salasanaa ei voi muuttaa.
+  notice_account_lost_email_sent: Sinulle on lÃ¤hetetty sÃ¤hkÃ¶posti jossa on ohje kuinka vaihdat salasanasi.
+  notice_account_activated: Tilisi on nyt aktivoitu, voit kirjautua sisÃ¤lle.
+  notice_successful_create: Luonti onnistui.
+  notice_successful_update: PÃ¤ivitys onnistui.
+  notice_successful_delete: Poisto onnistui.
+  notice_successful_connection: Yhteyden muodostus onnistui.
+  notice_file_not_found: Hakemaasi sivua ei lÃ¶ytynyt tai se on poistettu.
+  notice_locking_conflict: Toinen kÃ¤yttÃ¤jÃ¤ on pÃ¤ivittÃ¤nyt tiedot.
+  notice_not_authorized: Sinulla ei ole oikeutta nÃ¤yttÃ¤Ã¤ tÃ¤tÃ¤ sivua.
+  notice_email_sent: "SÃ¤hkÃ¶posti on lÃ¤hetty osoitteeseen %{value}"
+  notice_email_error: "SÃ¤hkÃ¶postilÃ¤hetyksessÃ¤ tapahtui virhe (%{value})"
+  notice_feeds_access_key_reseted: RSS salasana on nollaantunut.
+  notice_failed_to_save_issues: "%{count} Tapahtum(an/ien) tallennus epÃ¤onnistui %{total} valitut: %{ids}."
+  notice_no_issue_selected: "Tapahtumia ei ole valittu! Valitse tapahtumat joita haluat muokata."
+  notice_account_pending: "Tilisi on luotu ja odottaa yllÃ¤pitÃ¤jÃ¤n hyvÃ¤ksyntÃ¤Ã¤."
+  notice_default_data_loaded: Vakioasetusten palautus onnistui.
+
+  error_can_t_load_default_data: "Vakioasetuksia ei voitu ladata: %{value}"
+  error_scm_not_found: "SyÃ¶tettÃ¤ ja/tai versiota ei lÃ¶ydy tietovarastosta."
+  error_scm_command_failed: "Tietovarastoon pÃ¤Ã¤syssÃ¤ tapahtui virhe: %{value}"
+
+  mail_subject_lost_password: "Sinun %{value} salasanasi"
+  mail_body_lost_password: 'Vaihtaaksesi salasanasi, napsauta seuraavaa linkkiÃ¤:'
+  mail_subject_register: "%{value} tilin aktivointi"
+  mail_body_register: 'Aktivoidaksesi tilisi, napsauta seuraavaa linkkiÃ¤:'
+  mail_body_account_information_external: "Voit nyt kÃ¤yttÃ¤Ã¤ %{value} tiliÃ¤si kirjautuaksesi jÃ¤rjestelmÃ¤Ã¤n."
+  mail_body_account_information: Sinun tilin tiedot
+  mail_subject_account_activation_request: "%{value} tilin aktivointi pyyntÃ¶"
+  mail_body_account_activation_request: "Uusi kÃ¤yttÃ¤jÃ¤ (%{value}) on rekisterÃ¶itynyt. HÃ¤nen tili odottaa hyvÃ¤ksyntÃ¤Ã¤si:"
+
+
+  field_name: Nimi
+  field_description: Kuvaus
+  field_summary: Yhteenveto
+  field_is_required: Vaaditaan
+  field_firstname: Etunimi
+  field_lastname: Sukunimi
+  field_mail: SÃ¤hkÃ¶posti
+  field_filename: Tiedosto
+  field_filesize: Koko
+  field_downloads: Latausta
+  field_author: TekijÃ¤
+  field_created_on: Luotu
+  field_updated_on: PÃ¤ivitetty
+  field_field_format: Muoto
+  field_is_for_all: Kaikille projekteille
+  field_possible_values: Mahdolliset arvot
+  field_regexp: SÃ¤Ã¤nnÃ¶llinen lauseke (reg exp)
+  field_min_length: Minimipituus
+  field_max_length: Maksimipituus
+  field_value: Arvo
+  field_category: Luokka
+  field_title: Otsikko
+  field_project: Projekti
+  field_issue: Tapahtuma
+  field_status: Tila
+  field_notes: Muistiinpanot
+  field_is_closed: Tapahtuma suljettu
+  field_is_default: Vakioarvo
+  field_tracker: Tapahtuma
+  field_subject: Aihe
+  field_due_date: MÃ¤Ã¤rÃ¤aika
+  field_assigned_to: Nimetty
+  field_priority: Prioriteetti
+  field_fixed_version: Kohdeversio
+  field_user: KÃ¤yttÃ¤jÃ¤
+  field_role: Rooli
+  field_homepage: Kotisivu
+  field_is_public: Julkinen
+  field_parent: Aliprojekti
+  field_is_in_roadmap: Tapahtumat nÃ¤ytetÃ¤Ã¤n roadmap nÃ¤kymÃ¤ssÃ¤
+  field_login: Kirjautuminen
+  field_mail_notification: SÃ¤hkÃ¶posti muistutukset
+  field_admin: YllÃ¤pitÃ¤jÃ¤
+  field_last_login_on: Viimeinen yhteys
+  field_language: Kieli
+  field_effective_date: PÃ¤ivÃ¤
+  field_password: Salasana
+  field_new_password: Uusi salasana
+  field_password_confirmation: Vahvistus
+  field_version: Versio
+  field_type: Tyyppi
+  field_host: Verkko-osoite
+  field_port: Portti
+  field_account: Tili
+  field_base_dn: Base DN
+  field_attr_login: KirjautumismÃ¤Ã¤re
+  field_attr_firstname: EtuminenmÃ¤Ã¤re
+  field_attr_lastname: SukunimenmÃ¤Ã¤re
+  field_attr_mail: SÃ¤hkÃ¶postinmÃ¤Ã¤re
+  field_onthefly: Automaattinen kÃ¤yttÃ¤jien luonti
+  field_start_date: Alku
+  field_done_ratio: "% Tehty"
+  field_auth_source: Varmennusmuoto
+  field_hide_mail: Piiloita sÃ¤hkÃ¶postiosoitteeni
+  field_comments: Kommentti
+  field_url: URL
+  field_start_page: Aloitussivu
+  field_subproject: Aliprojekti
+  field_hours: Tuntia
+  field_activity: Historia
+  field_spent_on: PÃ¤ivÃ¤
+  field_identifier: Tunniste
+  field_is_filter: KÃ¤ytetÃ¤Ã¤n suodattimena
+  field_issue_to: LiittyvÃ¤ tapahtuma
+  field_delay: Viive
+  field_assignable: Tapahtumia voidaan nimetÃ¤ tÃ¤lle roolille
+  field_redirect_existing_links: Uudelleenohjaa olemassa olevat linkit
+  field_estimated_hours: Arvioitu aika
+  field_column_names: Saraketta
+  field_time_zone: AikavyÃ¶hyke
+  field_searchable: Haettava
+  field_default_value: Vakioarvo
+
+  setting_app_title: Ohjelman otsikko
+  setting_app_subtitle: Ohjelman alaotsikko
+  setting_welcome_text: Tervehdysteksti
+  setting_default_language: Vakiokieli
+  setting_login_required: Pakollinen kirjautuminen
+  setting_self_registration: ItserekisterÃ¶inti
+  setting_attachment_max_size: Liitteen maksimikoko
+  setting_issues_export_limit: Tapahtumien vientirajoite
+  setting_mail_from: LÃ¤hettÃ¤jÃ¤n sÃ¤hkÃ¶postiosoite
+  setting_bcc_recipients: Vastaanottajat piilokopiona (bcc)
+  setting_host_name: Verkko-osoite
+  setting_text_formatting: Tekstin muotoilu
+  setting_wiki_compression: Wiki historian pakkaus
+  setting_feeds_limit: SyÃ¶tteen sisÃ¤llÃ¶n raja
+  setting_autofetch_changesets: Automaattisten muutosjoukkojen haku
+  setting_sys_api_enabled: Salli WS tietovaraston hallintaan
+  setting_commit_ref_keywords: Viittaavat hakusanat
+  setting_commit_fix_keywords: Korjaavat hakusanat
+  setting_autologin: Automaatinen kirjautuminen
+  setting_date_format: PÃ¤ivÃ¤n muoto
+  setting_time_format: Ajan muoto
+  setting_cross_project_issue_relations: Salli projektien vÃ¤liset tapahtuminen suhteet
+  setting_issue_list_default_columns: Vakiosarakkeiden nÃ¤yttÃ¶ tapahtumalistauksessa
+  setting_emails_footer: SÃ¤hkÃ¶postin alatunniste
+  setting_protocol: Protokolla
+  setting_per_page_options: Sivun objektien mÃ¤Ã¤rÃ¤n asetukset
+
+  label_user: KÃ¤yttÃ¤jÃ¤
+  label_user_plural: KÃ¤yttÃ¤jÃ¤t
+  label_user_new: Uusi kÃ¤yttÃ¤jÃ¤
+  label_project: Projekti
+  label_project_new: Uusi projekti
+  label_project_plural: Projektit
+  label_x_projects:
+    zero:  no projects
+    one:   1 project
+    other: "%{count} projects"
+  label_project_all: Kaikki projektit
+  label_project_latest: Uusimmat projektit
+  label_issue: Tapahtuma
+  label_issue_new: Uusi tapahtuma
+  label_issue_plural: Tapahtumat
+  label_issue_view_all: NÃ¤ytÃ¤ kaikki tapahtumat
+  label_issues_by: "Tapahtumat %{value}"
+  label_document: Dokumentti
+  label_document_new: Uusi dokumentti
+  label_document_plural: Dokumentit
+  label_role: Rooli
+  label_role_plural: Roolit
+  label_role_new: Uusi rooli
+  label_role_and_permissions: Roolit ja oikeudet
+  label_member: JÃ¤sen
+  label_member_new: Uusi jÃ¤sen
+  label_member_plural: JÃ¤senet
+  label_tracker: Tapahtuma
+  label_tracker_plural: Tapahtumat
+  label_tracker_new: Uusi tapahtuma
+  label_workflow: TyÃ¶nkulku
+  label_issue_status: Tapahtuman tila
+  label_issue_status_plural: Tapahtumien tilat
+  label_issue_status_new: Uusi tila
+  label_issue_category: Tapahtumaluokka
+  label_issue_category_plural: Tapahtumaluokat
+  label_issue_category_new: Uusi luokka
+  label_custom_field: RÃ¤Ã¤tÃ¤lÃ¶ity kenttÃ¤
+  label_custom_field_plural: RÃ¤Ã¤tÃ¤lÃ¶idyt kentÃ¤t
+  label_custom_field_new: Uusi rÃ¤Ã¤tÃ¤lÃ¶ity kenttÃ¤
+  label_enumerations: Lista
+  label_enumeration_new: Uusi arvo
+  label_information: Tieto
+  label_information_plural: Tiedot
+  label_please_login: Kirjaudu ole hyvÃ¤
+  label_register: RekisterÃ¶idy
+  label_password_lost: Hukattu salasana
+  label_home: Koti
+  label_my_page: Omasivu
+  label_my_account: Oma tili
+  label_my_projects: Omat projektit
+  label_administration: YllÃ¤pito
+  label_login: Kirjaudu sisÃ¤Ã¤n
+  label_logout: Kirjaudu ulos
+  label_help: Ohjeet
+  label_reported_issues: Raportoidut tapahtumat
+  label_assigned_to_me_issues: Minulle nimetyt tapahtumat
+  label_last_login: Viimeinen yhteys
+  label_registered_on: RekisterÃ¶ity
+  label_activity: Historia
+  label_new: Uusi
+  label_logged_as: Kirjauduttu nimellÃ¤
+  label_environment: YmpÃ¤ristÃ¶
+  label_authentication: Varmennus
+  label_auth_source: Varmennustapa
+  label_auth_source_new: Uusi varmennustapa
+  label_auth_source_plural: Varmennustavat
+  label_subproject_plural: Aliprojektit
+  label_min_max_length: Min - Max pituudet
+  label_list: Lista
+  label_date: PÃ¤ivÃ¤
+  label_integer: Kokonaisluku
+  label_float: Liukuluku
+  label_boolean: Totuusarvomuuttuja
+  label_string: Merkkijono
+  label_text: PitkÃ¤ merkkijono
+  label_attribute: MÃ¤Ã¤re
+  label_attribute_plural: MÃ¤Ã¤reet
+  label_no_data: Ei tietoa nÃ¤ytettÃ¤vÃ¤ksi
+  label_change_status: Muutos tila
+  label_history: Historia
+  label_attachment: Tiedosto
+  label_attachment_new: Uusi tiedosto
+  label_attachment_delete: Poista tiedosto
+  label_attachment_plural: Tiedostot
+  label_report: Raportti
+  label_report_plural: Raportit
+  label_news: Uutinen
+  label_news_new: LisÃ¤Ã¤ uutinen
+  label_news_plural: Uutiset
+  label_news_latest: ViimeisimmÃ¤t uutiset
+  label_news_view_all: NÃ¤ytÃ¤ kaikki uutiset
+  label_settings: Asetukset
+  label_overview: Yleiskatsaus
+  label_version: Versio
+  label_version_new: Uusi versio
+  label_version_plural: Versiot
+  label_confirmation: Vahvistus
+  label_export_to: Vie
+  label_read: Lukee...
+  label_public_projects: Julkiset projektit
+  label_open_issues: avoin, yhteensÃ¤
+  label_open_issues_plural: avointa, yhteensÃ¤
+  label_closed_issues: suljettu
+  label_closed_issues_plural: suljettua
+  label_x_open_issues_abbr_on_total:
+    zero:  0 open / %{total}
+    one:   1 open / %{total}
+    other: "%{count} open / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 open
+    one:   1 open
+    other: "%{count} open"
+  label_x_closed_issues_abbr:
+    zero:  0 closed
+    one:   1 closed
+    other: "%{count} closed"
+  label_total: YhteensÃ¤
+  label_permissions: Oikeudet
+  label_current_status: Nykyinen tila
+  label_new_statuses_allowed: Uudet tilat sallittu
+  label_all: kaikki
+  label_none: ei mitÃ¤Ã¤n
+  label_nobody: ei kukaan
+  label_next: Seuraava
+  label_previous: Edellinen
+  label_used_by: KÃ¤ytetty
+  label_details: Yksityiskohdat
+  label_add_note: LisÃ¤Ã¤ muistiinpano
+  label_per_page: Per sivu
+  label_calendar: Kalenteri
+  label_months_from: kuukauden pÃ¤Ã¤ssÃ¤
+  label_gantt: Gantt
+  label_internal: SisÃ¤inen
+  label_last_changes: "viimeiset %{count} muutokset"
+  label_change_view_all: NÃ¤ytÃ¤ kaikki muutokset
+  label_personalize_page: Personoi tÃ¤mÃ¤ sivu
+  label_comment: Kommentti
+  label_comment_plural: Kommentit
+  label_x_comments:
+    zero: no comments
+    one: 1 comment
+    other: "%{count} comments"
+  label_comment_add: LisÃ¤Ã¤ kommentti
+  label_comment_added: Kommentti lisÃ¤tty
+  label_comment_delete: Poista kommentti
+  label_query: RÃ¤Ã¤tÃ¤lÃ¶ity haku
+  label_query_plural: RÃ¤Ã¤tÃ¤lÃ¶idyt haut
+  label_query_new: Uusi haku
+  label_filter_add: LisÃ¤Ã¤ suodatin
+  label_filter_plural: Suodattimet
+  label_equals: sama kuin
+  label_not_equals: eri kuin
+  label_in_less_than: pienempi kuin
+  label_in_more_than: suurempi kuin
+  label_today: tÃ¤nÃ¤Ã¤n
+  label_this_week: tÃ¤llÃ¤ viikolla
+  label_less_than_ago: vÃ¤hemmÃ¤n kuin pÃ¤ivÃ¤Ã¤ sitten
+  label_more_than_ago: enemÃ¤n kuin pÃ¤ivÃ¤Ã¤ sitten
+  label_ago: pÃ¤iviÃ¤ sitten
+  label_contains: sisÃ¤ltÃ¤Ã¤
+  label_not_contains: ei sisÃ¤llÃ¤
+  label_day_plural: pÃ¤ivÃ¤Ã¤
+  label_repository: Tietovarasto
+  label_repository_plural: Tietovarastot
+  label_browse: Selaus
+  label_revision: Versio
+  label_revision_plural: Versiot
+  label_added: lisÃ¤tty
+  label_modified: muokattu
+  label_deleted: poistettu
+  label_latest_revision: Viimeisin versio
+  label_latest_revision_plural: ViimeisimmÃ¤t versiot
+  label_view_revisions: NÃ¤ytÃ¤ versiot
+  label_max_size: Suurin koko
+  label_sort_highest: SiirrÃ¤ ylimmÃ¤iseksi
+  label_sort_higher: SiirrÃ¤ ylÃ¶s
+  label_sort_lower: SiirrÃ¤ alas
+  label_sort_lowest: SiirrÃ¤ alimmaiseksi
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "MÃ¤Ã¤rÃ¤aika %{value}"
+  label_roadmap_overdue: "%{value} myÃ¶hÃ¤ssÃ¤"
+  label_roadmap_no_issues: Ei tapahtumia tÃ¤lle versiolle
+  label_search: Haku
+  label_result_plural: Tulokset
+  label_all_words: kaikki sanat
+  label_wiki: Wiki
+  label_wiki_edit: Wiki muokkaus
+  label_wiki_edit_plural: Wiki muokkaukset
+  label_wiki_page: Wiki sivu
+  label_wiki_page_plural: Wiki sivut
+  label_index_by_title: Hakemisto otsikoittain
+  label_index_by_date: Hakemisto pÃ¤ivittÃ¤in
+  label_current_version: Nykyinen versio
+  label_preview: Esikatselu
+  label_feed_plural: SyÃ¶tteet
+  label_changes_details: Kaikkien muutosten yksityiskohdat
+  label_issue_tracking: Tapahtumien seuranta
+  label_spent_time: KÃ¤ytetty aika
+  label_f_hour: "%{value} tunti"
+  label_f_hour_plural: "%{value} tuntia"
+  label_time_tracking: Ajan seuranta
+  label_change_plural: Muutokset
+  label_statistics: Tilastot
+  label_commits_per_month: Tapahtumaa per kuukausi
+  label_commits_per_author: Tapahtumaa per tekijÃ¤
+  label_view_diff: NÃ¤ytÃ¤ erot
+  label_diff_inline: sisÃ¤llÃ¶ssÃ¤
+  label_diff_side_by_side: vierekkÃ¤in
+  label_options: Valinnat
+  label_copy_workflow_from: Kopioi tyÃ¶nkulku
+  label_permissions_report: Oikeuksien raportti
+  label_watched_issues: Seurattavat tapahtumat
+  label_related_issues: LiittyvÃ¤t tapahtumat
+  label_applied_status: LisÃ¤tty tila
+  label_loading: Lataa...
+  label_relation_new: Uusi suhde
+  label_relation_delete: Poista suhde
+  label_relates_to: liittyy
+  label_duplicates: kopio
+  label_blocks: estÃ¤Ã¤
+  label_blocked_by: estetty
+  label_precedes: edeltÃ¤Ã¤
+  label_follows: seuraa
+  label_end_to_start: lopusta alkuun
+  label_end_to_end: lopusta loppuun
+  label_start_to_start: alusta alkuun
+  label_start_to_end: alusta loppuun
+  label_stay_logged_in: Pysy kirjautuneena
+  label_disabled: poistettu kÃ¤ytÃ¶stÃ¤
+  label_show_completed_versions: NÃ¤ytÃ¤ valmiit versiot
+  label_me: minÃ¤
+  label_board: Keskustelupalsta
+  label_board_new: Uusi keskustelupalsta
+  label_board_plural: Keskustelupalstat
+  label_topic_plural: Aiheet
+  label_message_plural: Viestit
+  label_message_last: Viimeisin viesti
+  label_message_new: Uusi viesti
+  label_reply_plural: Vastaukset
+  label_send_information: LÃ¤hetÃ¤ tilin tiedot kÃ¤yttÃ¤jÃ¤lle
+  label_year: Vuosi
+  label_month: Kuukausi
+  label_week: Viikko
+  label_language_based: Pohjautuen kÃ¤yttÃ¤jÃ¤n kieleen
+  label_sort_by: "Lajittele %{value}"
+  label_send_test_email: LÃ¤hetÃ¤ testi sÃ¤hkÃ¶posti
+  label_feeds_access_key_created_on: "RSS salasana luotiin %{value} sitten"
+  label_module_plural: Moduulit
+  label_added_time_by: "LisÃ¤nnyt %{author} %{age} sitten"
+  label_updated_time: "PÃ¤ivitetty %{value} sitten"
+  label_jump_to_a_project: Siirry projektiin...
+  label_file_plural: Tiedostot
+  label_changeset_plural: MuutosryhmÃ¤t
+  label_default_columns: Vakiosarakkeet
+  label_no_change_option: (Ei muutosta)
+  label_bulk_edit_selected_issues: Perusmuotoile valitut tapahtumat
+  label_theme: Teema
+  label_default: Vakio
+  label_search_titles_only: Hae vain otsikot
+  label_user_mail_option_all: "Kaikista tapahtumista kaikissa projekteistani"
+  label_user_mail_option_selected: "Kaikista tapahtumista vain valitsemistani projekteista..."
+  label_user_mail_no_self_notified: "En halua muistutusta muutoksista joita itse teen"
+  label_registration_activation_by_email: tilin aktivointi sÃ¤hkÃ¶postitse
+  label_registration_manual_activation: tilin aktivointi kÃ¤sin
+  label_registration_automatic_activation: tilin aktivointi automaattisesti
+  label_display_per_page: "Per sivu: %{value}"
+  label_age: IkÃ¤
+  label_change_properties: Vaihda asetuksia
+  label_general: Yleinen
+
+  button_login: Kirjaudu
+  button_submit: LÃ¤hetÃ¤
+  button_save: Tallenna
+  button_check_all: Valitse kaikki
+  button_uncheck_all: Poista valinnat
+  button_delete: Poista
+  button_create: Luo
+  button_test: Testaa
+  button_edit: Muokkaa
+  button_add: LisÃ¤Ã¤
+  button_change: Muuta
+  button_apply: Ota kÃ¤yttÃ¶Ã¶n
+  button_clear: TyhjÃ¤Ã¤
+  button_lock: Lukitse
+  button_unlock: Vapauta
+  button_download: Lataa
+  button_list: Lista
+  button_view: NÃ¤ytÃ¤
+  button_move: SiirrÃ¤
+  button_back: Takaisin
+  button_cancel: Peruuta
+  button_activate: Aktivoi
+  button_sort: JÃ¤rjestÃ¤
+  button_log_time: Seuraa aikaa
+  button_rollback: Siirry takaisin tÃ¤hÃ¤n versioon
+  button_watch: Seuraa
+  button_unwatch: Ã„lÃ¤ seuraa
+  button_reply: Vastaa
+  button_archive: Arkistoi
+  button_unarchive: Palauta
+  button_reset: Nollaus
+  button_rename: Uudelleen nimeÃ¤
+  button_change_password: Vaihda salasana
+  button_copy: Kopioi
+  button_annotate: LisÃ¤Ã¤ selitys
+  button_update: PÃ¤ivitÃ¤
+
+  status_active: aktiivinen
+  status_registered: rekisterÃ¶ity
+  status_locked: lukittu
+
+  text_select_mail_notifications: Valitse tapahtumat joista tulisi lÃ¤hettÃ¤Ã¤ sÃ¤hkÃ¶postimuistutus.
+  text_regexp_info: esim. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 tarkoittaa, ei rajoitusta
+  text_project_destroy_confirmation: Oletko varma ettÃ¤ haluat poistaa tÃ¤mÃ¤n projektin ja kaikki siihen kuuluvat tiedot?
+  text_workflow_edit: Valitse rooli ja tapahtuma muokataksesi tyÃ¶nkulkua
+  text_are_you_sure: Oletko varma?
+  text_tip_issue_begin_day: tehtÃ¤vÃ¤ joka alkaa tÃ¤nÃ¤ pÃ¤ivÃ¤nÃ¤
+  text_tip_issue_end_day: tehtÃ¤vÃ¤ joka loppuu tÃ¤nÃ¤ pÃ¤ivÃ¤nÃ¤
+  text_tip_issue_begin_end_day: tehtÃ¤vÃ¤ joka alkaa ja loppuu tÃ¤nÃ¤ pÃ¤ivÃ¤nÃ¤
+  text_caracters_maximum: "%{count} merkkiÃ¤ enintÃ¤Ã¤n."
+  text_caracters_minimum: "TÃ¤ytyy olla vÃ¤hintÃ¤Ã¤n %{count} merkkiÃ¤ pitkÃ¤."
+  text_length_between: "Pituus vÃ¤lillÃ¤ %{min} ja %{max} merkkiÃ¤."
+  text_tracker_no_workflow: TyÃ¶nkulkua ei mÃ¤Ã¤ritelty tÃ¤lle tapahtumalle
+  text_unallowed_characters: KiellettyjÃ¤ merkkejÃ¤
+  text_comma_separated: Useat arvot sallittu (pilkku eroteltuna).
+  text_issues_ref_in_commit_messages: LiitÃ¤n ja korjaan ongelmia syÃ¶tetyssÃ¤ viestissÃ¤
+  text_issue_added: "Issue %{id} has been reported by %{author}."
+  text_issue_updated: "Issue %{id} has been updated by %{author}."
+  text_wiki_destroy_confirmation: Oletko varma ettÃ¤ haluat poistaa tÃ¤mÃ¤n wiki:n ja kaikki sen sisÃ¤ltÃ¤mÃ¤n tiedon?
+  text_issue_category_destroy_question: "Jotkut tapahtumat (%{count}) ovat nimetty tÃ¤lle luokalle. MitÃ¤ haluat tehdÃ¤?"
+  text_issue_category_destroy_assignments: Poista luokan tehtÃ¤vÃ¤t
+  text_issue_category_reassign_to: Vaihda tapahtuma tÃ¤hÃ¤n luokkaan
+  text_user_mail_option: "Valitsemattomille projekteille, saat vain muistutuksen asioista joita seuraat tai olet mukana (esim. tapahtumat joissa olet tekijÃ¤ tai nimettynÃ¤)."
+  text_no_configuration_data: "Rooleja, tapahtumien tiloja ja tyÃ¶nkulkua ei vielÃ¤ olla mÃ¤Ã¤ritelty.\nOn erittÃ¤in suotavaa ladata vakioasetukset. Voit muuttaa sitÃ¤ latauksen jÃ¤lkeen."
+  text_load_default_configuration: Lataa vakioasetukset
+
+  default_role_manager: PÃ¤Ã¤likkÃ¶
+  default_role_developer: KehittÃ¤jÃ¤
+  default_role_reporter: Tarkastelija
+  default_tracker_bug: Ohjelmointivirhe
+  default_tracker_feature: Ominaisuus
+  default_tracker_support: Tuki
+  default_issue_status_new: Uusi
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: HyvÃ¤ksytty
+  default_issue_status_feedback: Palaute
+  default_issue_status_closed: Suljettu
+  default_issue_status_rejected: HylÃ¤tty
+  default_doc_category_user: KÃ¤yttÃ¤jÃ¤ dokumentaatio
+  default_doc_category_tech: Tekninen dokumentaatio
+  default_priority_low: Matala
+  default_priority_normal: Normaali
+  default_priority_high: Korkea
+  default_priority_urgent: Kiireellinen
+  default_priority_immediate: ValitÃ¶n
+  default_activity_design: Suunnittelu
+  default_activity_development: Kehitys
+
+  enumeration_issue_priorities: Tapahtuman tÃ¤rkeysjÃ¤rjestys
+  enumeration_doc_categories: Dokumentin luokat
+  enumeration_activities: Historia (ajan seuranta)
+  label_associated_revisions: LiittyvÃ¤t versiot
+  setting_user_format: KÃ¤yttÃ¤jien esitysmuoto
+  text_status_changed_by_changeset: "PÃ¤ivitetty muutosversioon %{value}."
+  text_issues_destroy_confirmation: 'Oletko varma ettÃ¤ haluat poistaa valitut tapahtumat ?'
+  label_more: LisÃ¤Ã¤
+  label_issue_added: Tapahtuma lisÃ¤tty
+  label_issue_updated: Tapahtuma pÃ¤ivitetty
+  label_document_added: Dokumentti lisÃ¤tty
+  label_message_posted: Viesti lisÃ¤tty
+  label_file_added: Tiedosto lisÃ¤tty
+  label_scm: SCM
+  text_select_project_modules: 'Valitse modulit jotka haluat kÃ¤yttÃ¶Ã¶n tÃ¤hÃ¤n projektiin:'
+  label_news_added: Uutinen lisÃ¤tty
+  project_module_boards: Keskustelupalsta
+  project_module_issue_tracking: Tapahtuman seuranta
+  project_module_wiki: Wiki
+  project_module_files: Tiedostot
+  project_module_documents: Dokumentit
+  project_module_repository: Tietovarasto
+  project_module_news: Uutiset
+  project_module_time_tracking: Ajan seuranta
+  text_file_repository_writable: Kirjoitettava tiedostovarasto
+  text_default_administrator_account_changed: Vakio hallinoijan tunnus muutettu
+  text_rmagick_available: RMagick saatavilla (valinnainen)
+  button_configure: Asetukset
+  label_plugins: LisÃ¤osat
+  label_ldap_authentication: LDAP tunnistautuminen
+  label_downloads_abbr: D/L
+  label_add_another_file: LisÃ¤Ã¤ uusi tiedosto
+  label_this_month: tÃ¤ssÃ¤ kuussa
+  text_destroy_time_entries_question: "%{hours} tuntia on raportoitu tapahtumasta jonka aiot poistaa. MitÃ¤ haluat tehdÃ¤ ?"
+  label_last_n_days: "viimeiset %{count} pÃ¤ivÃ¤Ã¤"
+  label_all_time: koko ajalta
+  error_issue_not_found_in_project: 'Tapahtumaa ei lÃ¶ytynyt tai se ei kuulu tÃ¤hÃ¤n projektiin'
+  label_this_year: tÃ¤nÃ¤ vuonna
+  text_assign_time_entries_to_project: MÃ¤Ã¤ritÃ¤ tunnit projektille
+  label_date_range: AikavÃ¤li
+  label_last_week: viime viikolla
+  label_yesterday: eilen
+  label_optional_description: LisÃ¤kuvaus
+  label_last_month: viime kuussa
+  text_destroy_time_entries: Poista raportoidut tunnit
+  text_reassign_time_entries: 'SiirrÃ¤ raportoidut tunnit tÃ¤lle tapahtumalle:'
+  label_chronological_order: AikajÃ¤rjestyksessÃ¤
+  label_date_to: ''
+  setting_activity_days_default: PÃ¤ivien esittÃ¤minen projektien historiassa
+  label_date_from: ''
+  label_in: ''
+  setting_display_subprojects_issues: NÃ¤ytÃ¤ aliprojektien tapahtumat pÃ¤Ã¤projektissa oletusarvoisesti
+  field_comments_sorting: NÃ¤ytÃ¤ kommentit
+  label_reverse_chronological_order: KÃ¤Ã¤nteisessÃ¤ aikajÃ¤rjestyksessÃ¤
+  label_preferences: Asetukset
+  setting_default_projects_public: Uudet projektit ovat oletuksena julkisia
+  label_overall_activity: Kokonaishistoria
+  error_scm_annotate: "MerkintÃ¤Ã¤ ei ole tai siihen ei voi lisÃ¤tÃ¤ selityksiÃ¤."
+  label_planning: Suunnittelu
+  text_subprojects_destroy_warning: "TÃ¤mÃ¤n aliprojekti(t): %{value} tullaan myÃ¶s poistamaan."
+  label_and_its_subprojects: "%{value} ja aliprojektit"
+  mail_body_reminder: "%{count} sinulle nimettyÃ¤ tapahtuma(a) erÃ¤Ã¤ntyy %{days} pÃ¤ivÃ¤ sisÃ¤Ã¤n:"
+  mail_subject_reminder: "%{count} tapahtuma(a) erÃ¤Ã¤ntyy %{days} lÃ¤hipÃ¤ivinÃ¤"
+  text_user_wrote: "%{value} kirjoitti:"
+  label_duplicated_by: kopioinut
+  setting_enabled_scm: Versionhallinta kÃ¤ytettÃ¤vissÃ¤
+  text_enumeration_category_reassign_to: 'SiirrÃ¤ tÃ¤ksi arvoksi:'
+  text_enumeration_destroy_question: "%{count} kohdetta on sijoitettu tÃ¤lle arvolle."
+  label_incoming_emails: Saapuvat sÃ¤hkÃ¶postiviestit
+  label_generate_key: Luo avain
+  setting_mail_handler_api_enabled: Ota kÃ¤yttÃ¶Ã¶n WS saapuville sÃ¤hkÃ¶posteille
+  setting_mail_handler_api_key: API avain
+  text_email_delivery_not_configured: "SÃ¤hkÃ¶postin jakelu ei ole mÃ¤Ã¤ritelty ja sÃ¤hkÃ¶postimuistutukset eivÃ¤t ole kÃ¤ytÃ¶ssÃ¤.\nKonfiguroi sÃ¤hkÃ¶postipalvelinasetukset (SMTP) config/configuration.yml tiedostosta ja uudelleenkÃ¤ynnistÃ¤ sovellus jotta asetukset astuvat voimaan."
+  field_parent_title: Aloitussivu
+  label_issue_watchers: Tapahtuman seuraajat
+  button_quote: Vastaa
+  setting_sequential_project_identifiers: Luo perÃ¤kkÃ¤iset projektien tunnisteet
+  notice_unable_delete_version: Version poisto epÃ¤onnistui
+  label_renamed: uudelleennimetty
+  label_copied: kopioitu
+  setting_plain_text_mail: vain muotoilematonta tekstiÃ¤ (ei HTML)
+  permission_view_files: NÃ¤ytÃ¤ tiedostot
+  permission_edit_issues: Muokkaa tapahtumia
+  permission_edit_own_time_entries: Muokka omia aikamerkintÃ¶jÃ¤
+  permission_manage_public_queries: Hallinnoi julkisia hakuja
+  permission_add_issues: LisÃ¤Ã¤ tapahtumia
+  permission_log_time: Lokita kÃ¤ytettyÃ¤ aikaa
+  permission_view_changesets: NÃ¤ytÃ¤ muutosryhmÃ¤t
+  permission_view_time_entries: NÃ¤ytÃ¤ kÃ¤ytetty aika
+  permission_manage_versions: Hallinnoi versioita
+  permission_manage_wiki: Hallinnoi wikiÃ¤
+  permission_manage_categories: Hallinnoi tapahtumien luokkia
+  permission_protect_wiki_pages: Suojaa wiki sivut
+  permission_comment_news: Kommentoi uutisia
+  permission_delete_messages: Poista viestit
+  permission_select_project_modules: Valitse projektin modulit
+  permission_edit_wiki_pages: Muokkaa wiki sivuja
+  permission_add_issue_watchers: LisÃ¤Ã¤ seuraajia
+  permission_view_gantt: NÃ¤ytÃ¤ gantt kaavio
+  permission_move_issues: SiirrÃ¤ tapahtuma
+  permission_manage_issue_relations: Hallinoi tapahtuman suhteita
+  permission_delete_wiki_pages: Poista wiki sivuja
+  permission_manage_boards: Hallinnoi keskustelupalstaa
+  permission_delete_wiki_pages_attachments: Poista liitteitÃ¤
+  permission_view_wiki_edits: NÃ¤ytÃ¤ wiki historia
+  permission_add_messages: JÃ¤tÃ¤ viesti
+  permission_view_messages: NÃ¤ytÃ¤ viestejÃ¤
+  permission_manage_files: Hallinnoi tiedostoja
+  permission_edit_issue_notes: Muokkaa muistiinpanoja
+  permission_manage_news: Hallinnoi uutisia
+  permission_view_calendar: NÃ¤ytÃ¤ kalenteri
+  permission_manage_members: Hallinnoi jÃ¤seniÃ¤
+  permission_edit_messages: Muokkaa viestejÃ¤
+  permission_delete_issues: Poista tapahtumia
+  permission_view_issue_watchers: NÃ¤ytÃ¤ seuraaja lista
+  permission_manage_repository: Hallinnoi tietovarastoa
+  permission_commit_access: Tee pÃ¤Ã¤syoikeus
+  permission_browse_repository: Selaa tietovarastoa
+  permission_view_documents: NÃ¤ytÃ¤ dokumentit
+  permission_edit_project: Muokkaa projektia
+  permission_add_issue_notes: LisÃ¤Ã¤ muistiinpanoja
+  permission_save_queries: Tallenna hakuja
+  permission_view_wiki_pages: NÃ¤ytÃ¤ wiki
+  permission_rename_wiki_pages: UudelleennimeÃ¤ wiki sivuja
+  permission_edit_time_entries: Muokkaa aika lokeja
+  permission_edit_own_issue_notes: Muokkaa omia muistiinpanoja
+  setting_gravatar_enabled: KÃ¤ytÃ¤ Gravatar kÃ¤yttÃ¤jÃ¤ ikoneita
+  label_example: Esimerkki
+  text_repository_usernames_mapping: "Valitse pÃ¤ivittÃ¤Ã¤ksesi Redmine kÃ¤yttÃ¤jÃ¤ jokaiseen kÃ¤yttÃ¤jÃ¤Ã¤n joka lÃ¶ytyy tietovaraston lokista.\nKÃ¤yttÃ¤jÃ¤t joilla on sama Redmine ja tietovaraston kÃ¤yttÃ¤jÃ¤nimi tai sÃ¤hkÃ¶postiosoite, yhdistetÃ¤Ã¤n automaattisesti."
+  permission_edit_own_messages: Muokkaa omia viestejÃ¤
+  permission_delete_own_messages: Poista omia viestejÃ¤
+  label_user_activity: "KÃ¤yttÃ¤jÃ¤n %{value} historia"
+  label_updated_time_by: "Updated by %{author} %{age} ago"
+  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
+  setting_diff_max_lines_displayed: Max number of diff lines displayed
+  text_plugin_assets_writable: Plugin assets directory writable
+  warning_attachments_not_saved: "%{count} file(s) could not be saved."
+  button_create_and_continue: Create and continue
+  text_custom_field_possible_values_info: 'One line for each value'
+  label_display: Display
+  field_editable: Editable
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_file_max_size_displayed: Max size of text files displayed inline
+  field_watcher: Watcher
+  setting_openid: Allow OpenID login and registration
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: or login with OpenID
+  field_content: Content
+  label_descending: Descending
+  label_sort: Sort
+  label_ascending: Ascending
+  label_date_from_to: From %{start} to %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
+  text_wiki_page_reassign_children: Reassign child pages to this parent page
+  text_wiki_page_nullify_children: Keep child pages as root pages
+  text_wiki_page_destroy_children: Delete child pages and all their descendants
+  setting_password_min_length: Minimum password length
+  field_group_by: Group results by
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  label_wiki_content_added: Wiki page added
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
+  label_wiki_content_updated: Wiki page updated
+  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
+  permission_add_project: Create project
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  label_view_all_revisions: View all revisions
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
+  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
+  text_journal_changed: "%{label} changed from %{old} to %{new}"
+  text_journal_set_to: "%{label} set to %{value}"
+  text_journal_deleted: "%{label} deleted (%{old})"
+  label_group_plural: Groups
+  label_group: Group
+  label_group_new: New group
+  label_time_entry_plural: Spent time
+  text_journal_added: "%{label} %{value} added"
+  field_active: Active
+  enumeration_system_activity: System Activity
+  permission_delete_issue_watchers: Delete watchers
+  version_status_closed: closed
+  version_status_locked: locked
+  version_status_open: open
+  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
+  label_user_anonymous: Anonymous
+  button_move_and_follow: Move and follow
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_gravatar_default: Default Gravatar image
+  field_sharing: Sharing
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_system: With all projects
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_tree: With project tree
+  label_version_sharing_none: Not shared
+  error_can_not_archive_project: This project can not be archived
+  button_duplicate: Duplicate
+  button_copy_and_follow: Copy and follow
+  label_copy_source: Source
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_status: Use the issue status
+  error_issue_done_ratios_not_updated: Issue done ratios not updated.
+  error_workflow_copy_target: Please select target tracker(s) and role(s)
+  setting_issue_done_ratio_issue_field: Use the issue field
+  label_copy_same_as_target: Same as target
+  label_copy_target: Target
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  error_workflow_copy_source: Please select a source tracker or role
+  label_update_issue_done_ratios: Update issue done ratios
+  setting_start_of_week: Start calendars on
+  permission_view_issues: View Issues
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_revision_id: Revision %{value}
+  label_api_access_key: API access key
+  label_api_access_key_created_on: API access key created %{value} ago
+  label_feeds_access_key: RSS access key
+  notice_api_access_key_reseted: Your API access key was reset.
+  setting_rest_api_enabled: Enable REST web service
+  label_missing_api_access_key: Missing an API access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  button_show: Show
+  text_line_separated: Multiple values allowed (one line for each value).
+  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
+  permission_add_subprojects: Create subprojects
+  label_subproject_new: New subproject
+  text_own_membership_delete_confirmation: |-
+    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
+    Are you sure you want to continue?
+  label_close_versions: Close completed versions
+  label_board_sticky: Sticky
+  label_board_locked: Locked
+  permission_export_wiki_pages: Export wiki pages
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: Manage project activities
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_profile: Profile
+  permission_manage_subtasks: Manage subtasks
+  field_parent_issue: Parent task
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Tee viestien koodaus
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 tapahtuma
+    one:   1 tapahtuma
+    other: "%{count} tapahtumat"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: kaikki
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: YhteensÃ¤
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4d/4de18371feb9c1f0e9402b1bd393643194d5f79d.svn-base
--- /dev/null
+++ b/.svn/pristine/4d/4de18371feb9c1f0e9402b1bd393643194d5f79d.svn-base
@@ -0,0 +1,98 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingUsersTest < ActionController::IntegrationTest
+  def test_users
+    assert_routing(
+        { :method => 'get', :path => "/users" },
+        { :controller => 'users', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/users.xml" },
+        { :controller => 'users', :action => 'index', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/users/44" },
+        { :controller => 'users', :action => 'show', :id => '44' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/users/44.xml" },
+        { :controller => 'users', :action => 'show', :id => '44',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/users/current" },
+        { :controller => 'users', :action => 'show', :id => 'current' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/users/current.xml" },
+        { :controller => 'users', :action => 'show', :id => 'current',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/users/new" },
+        { :controller => 'users', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/users/444/edit" },
+        { :controller => 'users', :action => 'edit', :id => '444' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/users" },
+        { :controller => 'users', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/users.xml" },
+        { :controller => 'users', :action => 'create', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/users/444" },
+        { :controller => 'users', :action => 'update', :id => '444' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/users/444.xml" },
+        { :controller => 'users', :action => 'update', :id => '444',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/users/44" },
+        { :controller => 'users', :action => 'destroy', :id => '44' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/users/44.xml" },
+        { :controller => 'users', :action => 'destroy', :id => '44',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/users/123/memberships" },
+        { :controller => 'users', :action => 'edit_membership',
+          :id => '123' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/users/123/memberships/55" },
+        { :controller => 'users', :action => 'edit_membership',
+          :id => '123', :membership_id => '55' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/users/123/memberships/55" },
+        { :controller => 'users', :action => 'destroy_membership',
+          :id => '123', :membership_id => '55' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4d/4dfa42e1015d78dacb86fd8ca51a98e09e60e632.svn-base
--- /dev/null
+++ b/.svn/pristine/4d/4dfa42e1015d78dacb86fd8ca51a98e09e60e632.svn-base
@@ -0,0 +1,7 @@
+--- a.txt	2013-04-05 14:19:39.000000000 +0900
++++ b.txt	2013-04-05 14:19:51.000000000 +0900
+@@ -1,3 +1,3 @@
+ aaaa
+-æ—¥æœ¬
++ã«ã£ã½ã‚“æ—¥æœ¬
+ bbbb
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4e/4e2b9ddd1957e8e9b8adf4bab52aeff57edc2985.svn-base
--- a/.svn/pristine/4e/4e2b9ddd1957e8e9b8adf4bab52aeff57edc2985.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Diumenge",
- "Dilluns",
- "Dimarts",
- "Dimecres",
- "Dijous",
- "Divendres",
- "Dissabte",
- "Diumenge");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("dg",
- "dl",
- "dt",
- "dc",
- "dj",
- "dv",
- "ds",
- "dg");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Gener",
- "Febrer",
- "MarÃ§",
- "Abril",
- "Maig",
- "Juny",
- "Juliol",
- "Agost",
- "Setembre",
- "Octubre",
- "Novembre",
- "Desembre");
-
-// short month names
-Calendar._SMN = new Array
-("Gen",
- "Feb",
- "Mar",
- "Abr",
- "Mai",
- "Jun",
- "Jul",
- "Ago",
- "Set",
- "Oct",
- "Nov",
- "Des");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Quant al calendari";
-
-Calendar._TT["ABOUT"] =
-"Selector DHTML de data/hora\n" +
-"(c) dynarch.com 2002-2005 / Autor: Mihai Bazon\n" + // don't translate this this ;-)
-"Per aconseguir l'Ãºltima versiÃ³ visiteu: http://www.dynarch.com/projects/calendar/\n" +
-"DistribuÃ¯t sota la llicÃ¨ncia GNU LGPL. Vegeu http://gnu.org/licenses/lgpl.html per obtenir mÃ©s detalls." +
-"\n\n" +
-"SelecciÃ³ de la data:\n" +
-"- Utilitzeu els botons \xab, \xbb per seleccionar l'any\n" +
-"- Utilitzeu els botons " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " per seleccionar el mes\n" +
-"- Mantingueu premut el botÃ³ del ratolÃ­ sobre qualsevol d'aquests botons per a una selecciÃ³ mÃ©s rÃ pida.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"SelecciÃ³ de l'hora:\n" +
-"- Feu clic en qualsevol part de l'hora per incrementar-la\n" +
-"- o premeu majÃºscules per disminuir-la\n" +
-"- o feu clic i arrossegueu per a una selecciÃ³ mÃ©s rÃ pida.";
-
-Calendar._TT["PREV_YEAR"] = "Any anterior (mantenir per menÃº)";
-Calendar._TT["PREV_MONTH"] = "Mes anterior (mantenir per menÃº)";
-Calendar._TT["GO_TODAY"] = "Anar a avui";
-Calendar._TT["NEXT_MONTH"] = "Mes segÃ¼ent (mantenir per menÃº)";
-Calendar._TT["NEXT_YEAR"] = "Any segÃ¼ent (mantenir per menÃº)";
-Calendar._TT["SEL_DATE"] = "SelÂ·lecciona la data";
-Calendar._TT["DRAG_TO_MOVE"] = "Arrossega per moure";
-Calendar._TT["PART_TODAY"] = " (avui)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Primer mostra el %s";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Tanca";
-Calendar._TT["TODAY"] = "Avui";
-Calendar._TT["TIME_PART"] = "(MajÃºscules-)Feu clic o arrossegueu per canviar el valor";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%A, %e de %B de %Y";
-
-Calendar._TT["WK"] = "set";
-Calendar._TT["TIME"] = "Hora:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4e/4e463aec85dd46647cbb6a677bff53b3a10966f4.svn-base
--- a/.svn/pristine/4e/4e463aec85dd46647cbb6a677bff53b3a10966f4.svn-base
+++ /dev/null
@@ -1,31 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::NotifiableTest < ActiveSupport::TestCase
-  def setup
-  end
-
-  def test_all
-    assert_equal 12, Redmine::Notifiable.all.length
-
-    %w(issue_added issue_updated issue_note_added issue_status_updated issue_priority_updated news_added news_comment_added document_added file_added message_posted wiki_content_added wiki_content_updated).each do |notifiable|
-      assert Redmine::Notifiable.all.collect(&:name).include?(notifiable), "missing #{notifiable}"
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4e/4e62fffdedf392e04d93318885f3d58ff665b392.svn-base
--- /dev/null
+++ b/.svn/pristine/4e/4e62fffdedf392e04d93318885f3d58ff665b392.svn-base
@@ -0,0 +1,113 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class TokenTest < ActiveSupport::TestCase
+  fixtures :tokens
+
+  def test_create
+    token = Token.new
+    token.save
+    assert_equal 40, token.value.length
+    assert !token.expired?
+  end
+
+  def test_create_should_remove_existing_tokens
+    user = User.find(1)
+    t1 = Token.create(:user => user, :action => 'autologin')
+    t2 = Token.create(:user => user, :action => 'autologin')
+    assert_not_equal t1.value, t2.value
+    assert !Token.exists?(t1.id)
+    assert  Token.exists?(t2.id)
+  end
+
+  def test_destroy_expired_should_not_destroy_feeds_and_api_tokens
+    Token.delete_all
+
+    Token.create!(:user_id => 1, :action => 'api', :created_on => 7.days.ago)
+    Token.create!(:user_id => 1, :action => 'feeds', :created_on => 7.days.ago)
+
+    assert_no_difference 'Token.count' do
+      assert_equal 0, Token.destroy_expired
+    end
+  end
+
+  def test_destroy_expired_should_destroy_expired_tokens
+    Token.delete_all
+
+    Token.create!(:user_id => 1, :action => 'autologin', :created_on => 7.days.ago)
+    Token.create!(:user_id => 2, :action => 'autologin', :created_on => 3.days.ago)
+    Token.create!(:user_id => 3, :action => 'autologin', :created_on => 1.hour.ago)
+
+    assert_difference 'Token.count', -2 do
+      assert_equal 2, Token.destroy_expired
+    end
+  end
+
+  def test_find_active_user_should_return_user
+    token = Token.create!(:user_id => 1, :action => 'api')
+    assert_equal User.find(1), Token.find_active_user('api', token.value)
+  end
+
+  def test_find_active_user_should_return_nil_for_locked_user
+    token = Token.create!(:user_id => 1, :action => 'api')
+    User.find(1).lock!
+    assert_nil Token.find_active_user('api', token.value)
+  end
+
+  def test_find_user_should_return_user
+    token = Token.create!(:user_id => 1, :action => 'api')
+    assert_equal User.find(1), Token.find_user('api', token.value)
+  end
+
+  def test_find_user_should_return_locked_user
+    token = Token.create!(:user_id => 1, :action => 'api')
+    User.find(1).lock!
+    assert_equal User.find(1), Token.find_user('api', token.value)
+  end
+
+  def test_find_token_should_return_the_token
+    token = Token.create!(:user_id => 1, :action => 'api')
+    assert_equal token, Token.find_token('api', token.value)
+  end
+
+  def test_find_token_should_return_the_token_with_validity
+    token = Token.create!(:user_id => 1, :action => 'api', :created_on => 1.hour.ago)
+    assert_equal token, Token.find_token('api', token.value, 1)
+  end
+
+  def test_find_token_should_return_nil_with_wrong_action
+    token = Token.create!(:user_id => 1, :action => 'feeds')
+    assert_nil Token.find_token('api', token.value)
+  end
+
+  def test_find_token_should_return_nil_with_wrong_action
+    token = Token.create!(:user_id => 1, :action => 'feeds')
+    assert_nil Token.find_token('api', Token.generate_token_value)
+  end
+
+  def test_find_token_should_return_nil_without_user
+    token = Token.create!(:user_id => 999, :action => 'api')
+    assert_nil Token.find_token('api', token.value)
+  end
+
+  def test_find_token_should_return_nil_with_validity_expired
+    token = Token.create!(:user_id => 999, :action => 'api', :created_on => 2.days.ago)
+    assert_nil Token.find_token('api', token.value, 1)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4e/4e64ceb850aaa04a7acc9aad3a69b5f58d199fa5.svn-base
--- a/.svn/pristine/4e/4e64ceb850aaa04a7acc9aad3a69b5f58d199fa5.svn-base
+++ /dev/null
@@ -1,182 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redcloth3'
-require 'digest/md5'
-
-module Redmine
-  module WikiFormatting
-    module Textile
-      class Formatter < RedCloth3
-        include ActionView::Helpers::TagHelper
-
-        # auto_link rule after textile rules so that it doesn't break !image_url! tags
-        RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto]
-
-        def initialize(*args)
-          super
-          self.hard_breaks=true
-          self.no_span_caps=true
-          self.filter_styles=true
-        end
-
-        def to_html(*rules)
-          @toc = []
-          super(*RULES).to_s
-        end
-
-        def get_section(index)
-          section = extract_sections(index)[1]
-          hash = Digest::MD5.hexdigest(section)
-          return section, hash
-        end
-
-        def update_section(index, update, hash=nil)
-          t = extract_sections(index)
-          if hash.present? && hash != Digest::MD5.hexdigest(t[1])
-            raise Redmine::WikiFormatting::StaleSectionError
-          end
-          t[1] = update unless t[1].blank?
-          t.reject(&:blank?).join "\n\n"
-        end
-
-        def extract_sections(index)
-          @pre_list = []
-          text = self.dup
-          rip_offtags text, false, false
-          before = ''
-          s = ''
-          after = ''
-          i = 0
-          l = 1
-          started = false
-          ended = false
-          text.scan(/(((?:.*?)(\A|\r?\n\r?\n))(h(\d+)(#{A}#{C})\.(?::(\S+))? (.*?)$)|.*)/m).each do |all, content, lf, heading, level|
-            if heading.nil?
-              if ended
-                after << all
-              elsif started
-                s << all
-              else
-                before << all
-              end
-              break
-            end
-            i += 1
-            if ended
-              after << all
-            elsif i == index
-              l = level.to_i
-              before << content
-              s << heading
-              started = true
-            elsif i > index
-              s << content
-              if level.to_i > l
-                s << heading
-              else
-                after << heading
-                ended = true
-              end
-            else
-              before << all
-            end
-          end
-          sections = [before.strip, s.strip, after.strip]
-          sections.each {|section| smooth_offtags_without_code_highlighting section}
-          sections
-        end
-
-      private
-
-        # Patch for RedCloth.  Fixed in RedCloth r128 but _why hasn't released it yet.
-        # <a href="http://code.whytheluckystiff.net/redcloth/changeset/128">http://code.whytheluckystiff.net/redcloth/changeset/128</a>
-        def hard_break( text )
-          text.gsub!( /(.)\n(?!\n|\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks
-        end
-
-        alias :smooth_offtags_without_code_highlighting :smooth_offtags
-        # Patch to add code highlighting support to RedCloth
-        def smooth_offtags( text )
-          unless @pre_list.empty?
-            ## replace <pre> content
-            text.gsub!(/<redpre#(\d+)>/) do
-              content = @pre_list[$1.to_i]
-              if content.match(/<code\s+class="(\w+)">\s?(.+)/m)
-                content = "<code class=\"#{$1} syntaxhl\">" +
-                  Redmine::SyntaxHighlighting.highlight_by_language($2, $1)
-              end
-              content
-            end
-          end
-        end
-
-        AUTO_LINK_RE = %r{
-                        (                          # leading text
-                          <\w+.*?>|                # leading HTML tag, or
-                          [^=<>!:'"/]|             # leading punctuation, or
-                          ^                        # beginning of line
-                        )
-                        (
-                          (?:https?://)|           # protocol spec, or
-                          (?:s?ftps?://)|
-                          (?:www\.)                # www.*
-                        )
-                        (
-                          (\S+?)                   # url
-                          (\/)?                    # slash
-                        )
-                        ((?:&gt;)?|[^\w\=\/;\(\)]*?)               # post
-                        (?=<|\s|$)
-                       }x unless const_defined?(:AUTO_LINK_RE)
-
-        # Turns all urls into clickable links (code from Rails).
-        def inline_auto_link(text)
-          text.gsub!(AUTO_LINK_RE) do
-            all, leading, proto, url, post = $&, $1, $2, $3, $6
-            if leading =~ /<a\s/i || leading =~ /![<>=]?/
-              # don't replace URL's that are already linked
-              # and URL's prefixed with ! !> !< != (textile images)
-              all
-            else
-              # Idea below : an URL with unbalanced parethesis and
-              # ending by ')' is put into external parenthesis
-              if ( url[-1]==?) and ((url.count("(") - url.count(")")) < 0 ) )
-                url=url[0..-2] # discard closing parenth from url
-                post = ")"+post # add closing parenth to post
-              end
-              tag = content_tag('a', proto + url, :href => "#{proto=="www."?"http://www.":proto}#{url}", :class => 'external')
-              %(#{leading}#{tag}#{post})
-            end
-          end
-        end
-
-        # Turns all email addresses into clickable links (code from Rails).
-        def inline_auto_mailto(text)
-          text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
-            mail = $1
-            if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/)
-              mail
-            else
-              content_tag('a', mail, :href => "mailto:#{mail}", :class => "email")
-            end
-          end
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4e/4ead8da3bccd9129e3a3aa36afffc50dc032eb7b.svn-base
--- a/.svn/pristine/4e/4ead8da3bccd9129e3a3aa36afffc50dc032eb7b.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<p><%= l(:mail_body_wiki_content_updated, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url),
-                                          :author => h(@wiki_content.author)) %><br />
-<em><%=h @wiki_content.comments %></em></p>
-
-<p><%= l(:label_view_diff) %>:<br />
-<%= link_to h(@wiki_diff_url), @wiki_diff_url %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4f4249c007fe05ae60a997c7b935c55203608b2e.svn-base
--- a/.svn/pristine/4f/4f4249c007fe05ae60a997c7b935c55203608b2e.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * Raphael 1.5.2 - JavaScript Vector Library
- *
- * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
- * Licensed under the MIT (http://raphaeljs.com/license.html) license.
- */
-(function(){function cC(a,b,c,d,e,f){function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(B(f)<b)return e;j=(3*i*e+2*h)*e+g;if(B(j)<1e-6)break;e=e-f/j}c=0,d=1,e=a;if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(B(f-a)<b)return e;a>f?c=e:d=e,e=(d-c)/2+c}return e}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function m(a){return((i*a+h)*a+g)*a}var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;return n(a,1/(200*f))}function cB(b){return function(c,d,e,f){var g={back:b};a.is(e,"function")?f=e:g.rot=e,c&&c.constructor==bN&&(c=c.attrs.path),c&&(g.along=c);return this.animate(g,d,f)}}function cp(){return this.x+q+this.y}function bm(a,b,c){function d(){var g=Array[e].slice.call(arguments,0),h=g[v]("â–º"),i=d.cache=d.cache||{},j=d.count=d.count||[];if(i[f](h))return c?c(i[h]):i[h];j[w]>=1e3&&delete i[j.shift()],j[L](h),i[h]=a[m](b,g);return c?c(i[h]):i[h]}return d}function bh(){var a=[],b=0;for(;b<32;b++)a[b]=(~~(y.random()*16))[H](16);a[12]=4,a[16]=(a[16]&3|8)[H](16);return"r-"+a[v]("")}function a(){if(a.is(arguments[0],G)){var b=arguments[0],d=bV[m](a,b.splice(0,3+a.is(b[0],E))),e=d.set();for(var g=0,h=b[w];g<h;g++){var i=b[g]||{};c[f](i.type)&&e[L](d[i.type]().attr(i))}return e}return bV[m](a,arguments)}a.version="1.5.2";var b=/[, ]+/,c={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},d=/\{(\d+)\}/g,e="prototype",f="hasOwnProperty",g=document,h=window,i={was:Object[e][f].call(h,"Raphael"),is:h.Raphael},j=function(){this.customAttributes={}},k,l="appendChild",m="apply",n="concat",o="createTouch"in g,p="",q=" ",r=String,s="split",t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[s](q),u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},v="join",w="length",x=r[e].toLowerCase,y=Math,z=y.max,A=y.min,B=y.abs,C=y.pow,D=y.PI,E="number",F="string",G="array",H="toString",I="fill",J=Object[e][H],K={},L="push",M=/^url\(['"]?([^\)]+?)['"]?\)$/i,N=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,O={NaN:1,Infinity:1,"-Infinity":1},P=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,Q=y.round,R="setAttribute",S=parseFloat,T=parseInt,U=" progid:DXImageTransform.Microsoft",V=r[e].toUpperCase,W={blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},X={along:"along",blur:E,"clip-rect":"csv",cx:E,cy:E,fill:"colour","fill-opacity":E,"font-size":E,height:E,opacity:E,path:"path",r:E,rotation:"csv",rx:E,ry:E,scale:"csv",stroke:"colour","stroke-opacity":E,"stroke-width":E,translation:"csv",width:E,x:E,y:E},Y="replace",Z=/^(from|to|\d+%?)$/,$=/\s*,\s*/,_={hs:1,rg:1},ba=/,?([achlmqrstvxz]),?/gi,bb=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,bc=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,bd=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,be=function(a,b){return a.key-b.key};a.type=h.SVGAngle||g.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(a.type=="VML"){var bf=g.createElement("div"),bg;bf.innerHTML='<v:shape adj="1"/>',bg=bf.firstChild,bg.style.behavior="url(#default#VML)";if(!bg||typeof bg.adj!="object")return a.type=null;bf=null}a.svg=!(a.vml=a.type=="VML"),j[e]=a[e],k=j[e],a._id=0,a._oid=0,a.fn={},a.is=function(a,b){b=x.call(b);if(b=="finite")return!O[f](+a);return b=="null"&&a===null||b==typeof a||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||J.call(a).slice(8,-1).toLowerCase()==b},a.angle=function(b,c,d,e,f,g){if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return((h<0)*180+y.atan(-i/-h)*180/D+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)},a.rad=function(a){return a%360*D/180},a.deg=function(a){return a*180/D%360},a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,G)){var e=b.length;while(e--)if(B(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(f<d)return c-f;if(f>b-d)return c-f+b}return c},a.setWindow=function(a){h=a,g=h.document};var bi=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write("<body>"),e.close(),d=e.body}catch(f){d=createPopup().document.body}var h=d.createTextRange();bi=bm(function(a){try{d.style.color=r(a)[Y](c,p);var b=h.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b[H](16)).slice(-6)}catch(e){return"none"}})}else{var i=g.createElement("i");i.title="RaphaÃ«l Colour Picker",i.style.display="none",g.body[l](i),bi=bm(function(a){i.style.color=a;return g.defaultView.getComputedStyle(i,p).getPropertyValue("color")})}return bi(b)},bj=function(){return"hsb("+[this.h,this.s,this.b]+")"},bk=function(){return"hsl("+[this.h,this.s,this.l]+")"},bl=function(){return this.hex};a.hsb2rgb=function(b,c,d,e){a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b&&(d=b.b,c=b.s,b=b.h,e=b.o);return a.hsl2rgb(b,c,d/2,e)},a.hsl2rgb=function(b,c,d,e){a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b&&(d=b.l,c=b.s,b=b.h);if(b>1||c>1||d>1)b/=360,c/=100,d/=100;var f={},g=["r","g","b"],h,i,j,k,l,m;if(!c)f={r:d,g:d,b:d};else{d<.5?h=d*(1+c):h=d+c-d*c,i=2*d-h;for(var n=0;n<3;n++)j=b+1/3*-(n-1),j<0&&j++,j>1&&j--,j*6<1?f[g[n]]=i+(h-i)*6*j:j*2<1?f[g[n]]=h:j*3<2?f[g[n]]=i+(h-i)*(2/3-j)*6:f[g[n]]=i}f.r*=255,f.g*=255,f.b*=255,f.hex="#"+(16777216|f.b|f.g<<8|f.r<<16).toString(16).slice(1),a.is(e,"finite")&&(f.opacity=e),f.toString=bl;return f},a.rgb2hsb=function(b,c,d){c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b&&(d=b.b,c=b.g,b=b.r);if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r,c=e.g,d=e.b}if(b>1||c>1||d>1)b/=255,c/=255,d/=255;var f=z(b,c,d),g=A(b,c,d),h,i,j=f;if(g==f)return{h:0,s:0,b:f,toString:bj};var k=f-g;i=k/f,b==f?h=(c-d)/k:c==f?h=2+(d-b)/k:h=4+(b-c)/k,h/=6,h<0&&h++,h>1&&h--;return{h:h,s:i,b:j,toString:bj}},a.rgb2hsl=function(b,c,d){c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b&&(d=b.b,c=b.g,b=b.r);if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r,c=e.g,d=e.b}if(b>1||c>1||d>1)b/=255,c/=255,d/=255;var f=z(b,c,d),g=A(b,c,d),h,i,j=(f+g)/2,k;if(g==f)k={h:0,s:0,l:j};else{var l=f-g;i=j<.5?l/(f+g):l/(2-f-g),b==f?h=(c-d)/l:c==f?h=2+(d-b)/l:h=4+(b-c)/l,h/=6,h<0&&h++,h>1&&h--,k={h:h,s:i,l:j}}k.toString=bk;return k},a._path2string=function(){return this.join(",")[Y](ba,"$1")},a.getRGB=bm(function(b){if(!b||!!((b=r(b)).indexOf("-")+1))return{r:-1,g:-1,b:-1,hex:"none",error:1};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none"};!_[f](b.toLowerCase().substring(0,2))&&b.charAt()!="#"&&(b=bi(b));var c,d,e,g,h,i,j,k=b.match(N);if(k){k[2]&&(g=T(k[2].substring(5),16),e=T(k[2].substring(3,5),16),d=T(k[2].substring(1,3),16)),k[3]&&(g=T((i=k[3].charAt(3))+i,16),e=T((i=k[3].charAt(2))+i,16),d=T((i=k[3].charAt(1))+i,16)),k[4]&&(j=k[4][s]($),d=S(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=S(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),g=S(j[2]),j[2].slice(-1)=="%"&&(g*=2.55),k[1].toLowerCase().slice(0,4)=="rgba"&&(h=S(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100));if(k[5]){j=k[5][s]($),d=S(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=S(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),g=S(j[2]),j[2].slice(-1)=="%"&&(g*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="Â°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsba"&&(h=S(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,g,h)}if(k[6]){j=k[6][s]($),d=S(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=S(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),g=S(j[2]),j[2].slice(-1)=="%"&&(g*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="Â°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsla"&&(h=S(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,g,h)}k={r:d,g:e,b:g},k.hex="#"+(16777216|g|e<<8|d<<16).toString(16).slice(1),a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1}},a),a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b}));return c.hex},a.getColor.reset=function(){delete this.start},a.parsePathString=bm(function(b){if(!b)return null;var c={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,G)&&a.is(b[0],G)&&(d=bo(b)),d[w]||r(b)[Y](bb,function(a,b,e){var f=[],g=x.call(b);e[Y](bc,function(a,b){b&&f[L](+b)}),g=="m"&&f[w]>2&&(d[L]([b][n](f.splice(0,2))),g="l",b=b=="m"?"l":"L");while(f[w]>=c[g]){d[L]([b][n](f.splice(0,c[g])));if(!c[g])break}}),d[H]=a._path2string;return d}),a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,l=C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h,m=a+2*i*(c-a)+i*i*(e-2*c+a),n=b+2*i*(d-b)+i*i*(f-2*d+b),o=c+2*i*(e-c)+i*i*(g-2*e+c),p=d+2*i*(f-d)+i*i*(h-2*f+d),q=(1-i)*a+i*c,r=(1-i)*b+i*d,s=(1-i)*e+i*g,t=(1-i)*f+i*h,u=90-y.atan((m-o)/(n-p))*180/D;(m>o||n<p)&&(u+=180);return{x:k,y:l,m:{x:m,y:n},n:{x:o,y:p},start:{x:q,y:r},end:{x:s,y:t},alpha:u}};var bn=bm(function(a){if(!a)return{x:0,y:0,width:0,height:0};a=bw(a);var b=0,c=0,d=[],e=[],f;for(var g=0,h=a[w];g<h;g++){f=a[g];if(f[0]=="M")b=f[1],c=f[2],d[L](b),e[L](c);else{var i=bv(b,c,f[1],f[2],f[3],f[4],f[5],f[6]);d=d[n](i.min.x,i.max.x),e=e[n](i.min.y,i.max.y),b=f[5],c=f[6]}}var j=A[m](0,d),k=A[m](0,e);return{x:j,y:k,width:z[m](0,d)-j,height:z[m](0,e)-k}}),bo=function(b){var c=[];if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);for(var d=0,e=b[w];d<e;d++){c[d]=[];for(var f=0,g=b[d][w];f<g;f++)c[d][f]=b[d][f]}c[H]=a._path2string;return c},bp=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;b[0][0]=="M"&&(d=b[0][1],e=b[0][2],f=d,g=e,h++,c[L](["M",d,e]));for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=x.call(l[0])){k[0]=x.call(l[0]);switch(k[0]){case"a":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]-d).toFixed(3),k[7]=+(l[7]-e).toFixed(3);break;case"v":k[1]=+(l[1]-e).toFixed(3);break;case"m":f=l[1],g=l[2];default:for(var m=1,n=l[w];m<n;m++)k[m]=+(l[m]-(m%2?d:e)).toFixed(3)}}else{k=c[i]=[],l[0]=="m"&&(f=l[1]+d,g=l[2]+e);for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o]}var q=c[i][w];switch(c[i][0]){case"z":d=f,e=g;break;case"h":d+=+c[i][q-1];break;case"v":e+=+c[i][q-1];break;default:d+=+c[i][q-2],e+=+c[i][q-1]}}c[H]=a._path2string;return c},0,bo),bq=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;b[0][0]=="M"&&(d=+b[0][1],e=+b[0][2],f=d,g=e,h++,c[0]=["M",d,e]);for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=V.call(l[0])){k[0]=V.call(l[0]);switch(k[0]){case"A":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+d),k[7]=+(l[7]+e);break;case"V":k[1]=+l[1]+e;break;case"H":k[1]=+l[1]+d;break;case"M":f=+l[1]+d,g=+l[2]+e;default:for(var m=1,n=l[w];m<n;m++)k[m]=+l[m]+(m%2?d:e)}}else for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o];switch(k[0]){case"Z":d=f,e=g;break;case"H":d=k[1];break;case"V":e=k[1];break;case"M":f=c[i][c[i][w]-2],g=c[i][c[i][w]-1];default:d=c[i][c[i][w]-2],e=c[i][c[i][w]-1]}}c[H]=a._path2string;return c},null,bo),br=function(a,b,c,d){return[a,b,c,d,c,d]},bs=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},bt=function(a,b,c,d,e,f,g,h,i,j){var k=D*120/180,l=D/180*(+e||0),m=[],o,p=bm(function(a,b,c){var d=a*y.cos(c)-b*y.sin(c),e=a*y.sin(c)+b*y.cos(c);return{x:d,y:e}});if(!j){o=p(a,b,-l),a=o.x,b=o.y,o=p(h,i,-l),h=o.x,i=o.y;var q=y.cos(D/180*e),r=y.sin(D/180*e),t=(a-h)/2,u=(b-i)/2,x=t*t/(c*c)+u*u/(d*d);x>1&&(x=y.sqrt(x),c=x*c,d=x*d);var z=c*c,A=d*d,C=(f==g?-1:1)*y.sqrt(B((z*A-z*u*u-A*t*t)/(z*u*u+A*t*t))),E=C*c*u/d+(a+h)/2,F=C*-d*t/c+(b+i)/2,G=y.asin(((b-F)/d).toFixed(9)),H=y.asin(((i-F)/d).toFixed(9));G=a<E?D-G:G,H=h<E?D-H:H,G<0&&(G=D*2+G),H<0&&(H=D*2+H),g&&G>H&&(G=G-D*2),!g&&H>G&&(H=H-D*2)}else G=j[0],H=j[1],E=j[2],F=j[3];var I=H-G;if(B(I)>k){var J=H,K=h,L=i;H=G+k*(g&&H>G?1:-1),h=E+c*y.cos(H),i=F+d*y.sin(H),m=bt(h,i,c,d,e,0,g,K,L,[H,J,E,F])}I=H-G;var M=y.cos(G),N=y.sin(G),O=y.cos(H),P=y.sin(H),Q=y.tan(I/4),R=4/3*c*Q,S=4/3*d*Q,T=[a,b],U=[a+R*N,b-S*M],V=[h+R*P,i-S*O],W=[h,i];U[0]=2*T[0]-U[0],U[1]=2*T[1]-U[1];if(j)return[U,V,W][n](m);m=[U,V,W][n](m)[v]()[s](",");var X=[];for(var Y=0,Z=m[w];Y<Z;Y++)X[Y]=Y%2?p(m[Y-1],m[Y],l).y:p(m[Y],m[Y+1],l).x;return X},bu=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,y:C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h}},bv=bm(function(a,b,c,d,e,f,g,h){var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+y.sqrt(j*j-4*i*k))/2/i,n=(-j-y.sqrt(j*j-4*i*k))/2/i,o=[b,h],p=[a,g],q;B(l)>"1e12"&&(l=.5),B(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bu(a,b,c,d,e,f,g,h,l),p[L](q.x),o[L](q.y)),n>0&&n<1&&(q=bu(a,b,c,d,e,f,g,h,n),p[L](q.x),o[L](q.y)),i=f-2*d+b-(h-2*f+d),j=2*(d-b)-2*(f-d),k=b-d,l=(-j+y.sqrt(j*j-4*i*k))/2/i,n=(-j-y.sqrt(j*j-4*i*k))/2/i,B(l)>"1e12"&&(l=.5),B(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bu(a,b,c,d,e,f,g,h,l),p[L](q.x),o[L](q.y)),n>0&&n<1&&(q=bu(a,b,c,d,e,f,g,h,n),p[L](q.x),o[L](q.y));return{min:{x:A[m](0,p),y:A[m](0,o)},max:{x:z[m](0,p),y:z[m](0,o)}}}),bw=bm(function(a,b){var c=bq(a),d=b&&bq(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][n](bt[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x)),d=b.y+(b.y-(b.by||b.y)),a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x)),b.qy=b.y+(b.y-(b.qy||b.y)),a=["C"][n](bs(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][n](bs(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](br(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](br(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](br(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](br(b.x,b.y,b.X,b.Y))}return a},h=function(a,b){if(a[b][w]>7){a[b].shift();var e=a[b];while(e[w])a.splice(b++,0,["C"][n](e.splice(0,6)));a.splice(b,1),k=z(c[w],d&&d[w]||0)}},i=function(a,b,e,f,g){a&&b&&a[g][0]=="M"&&b[g][0]!="M"&&(b.splice(g,0,["M",f.x,f.y]),e.bx=0,e.by=0,e.x=a[g][1],e.y=a[g][2],k=z(c[w],d&&d[w]||0))};for(var j=0,k=z(c[w],d&&d[w]||0);j<k;j++){c[j]=g(c[j],e),h(c,j),d&&(d[j]=g(d[j],f)),d&&h(d,j),i(c,d,e,f,j),i(d,c,f,e,j);var l=c[j],o=d&&d[j],p=l[w],q=d&&o[w];e.x=l[p-2],e.y=l[p-1],e.bx=S(l[p-4])||e.x,e.by=S(l[p-3])||e.y,f.bx=d&&(S(o[q-4])||f.x),f.by=d&&(S(o[q-3])||f.y),f.x=d&&o[q-2],f.y=d&&o[q-1]}return d?[c,d]:c},null,bo),bx=bm(function(b){var c=[];for(var d=0,e=b[w];d<e;d++){var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);if(f.color.error)return null;f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),c[L](f)}for(d=1,e=c[w]-1;d<e;d++)if(!c[d].offset){var h=S(c[d-1].offset||0),i=0;for(var j=d+1;j<e;j++)if(c[j].offset){i=c[j].offset;break}i||(i=100,j=e),i=S(i);var k=(i-h)/(j-d+1);for(;d<j;d++)h+=k,c[d].offset=h+"%"}return c}),by=function(b,c,d,e){var f;if(!a.is(b,F)&&!a.is(b,"object"))return{container:1,x:b,y:c,width:d,height:e};f=a.is(b,F)?g.getElementById(b):b;if(f.tagName)return c==null?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}},bz=function(a,b){var c=this;for(var d in b)if(b[f](d)&&!(d in a))switch(typeof b[d]){case"function":(function(b){a[d]=a===c?b:function(){return b[m](c,arguments)}})(b[d]);break;case"object":a[d]=a[d]||{},bz.call(this,a[d],b[d]);break;default:a[d]=b[d]}},bA=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)},bB=function(a,b){b.top!==a&&(bA(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},bC=function(a,b){b.bottom!==a&&(bA(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},bD=function(a,b,c){bA(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},bE=function(a,b,c){bA(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},bF=function(a){return function(){throw new Error("RaphaÃ«l: you are calling to method â€œ"+a+"â€ of removed object")}};a.pathToRelative=bp;if(a.svg){k.svgns="http://www.w3.org/2000/svg",k.xlink="http://www.w3.org/1999/xlink",Q=function(a){return+a+(~~a===a)*.5};var bG=function(a,b){if(!b){a=g.createElementNS(k.svgns,a),a.style.webkitTapHighlightColor="rgba(0,0,0,0)";return a}for(var c in b)b[f](c)&&a[R](c,r(b[c]))};a[H]=function(){return"Your browser supports SVG.\nYou are running RaphaÃ«l "+this.version};var bH=function(a,b){var c=bG("path");b.canvas&&b.canvas[l](c);var d=new bN(c,b);d.type="path",bK(d,{fill:"none",stroke:"#000",path:a});return d},bI=function(a,b,c){var d="linear",e=.5,f=.5,h=a.style;b=r(b)[Y](bd,function(a,b,c){d="radial";if(b&&c){e=S(b),f=S(c);var g=(f>.5)*2-1;C(e-.5,2)+C(f-.5,2)>.25&&(f=y.sqrt(.25-C(e-.5,2))*g+.5)&&f!=.5&&(f=f.toFixed(5)-1e-5*g)}return p}),b=b[s](/\s*\-\s*/);if(d=="linear"){var i=b.shift();i=-S(i);if(isNaN(i))return null;var j=[0,0,y.cos(i*D/180),y.sin(i*D/180)],k=1/(z(B(j[2]),B(j[3]))||1);j[2]*=k,j[3]*=k,j[2]<0&&(j[0]=-j[2],j[2]=0),j[3]<0&&(j[1]=-j[3],j[3]=0)}var m=bx(b);if(!m)return null;var n=a.getAttribute(I);n=n.match(/^url\(#(.*)\)$/),n&&c.defs.removeChild(g.getElementById(n[1]));var o=bG(d+"Gradient");o.id=bh(),bG(o,d=="radial"?{fx:e,fy:f}:{x1:j[0],y1:j[1],x2:j[2],y2:j[3]}),c.defs[l](o);for(var q=0,t=m[w];q<t;q++){var u=bG("stop");bG(u,{offset:m[q].offset?m[q].offset:q?"100%":"0%","stop-color":m[q].color||"#fff"}),o[l](u)}bG(a,{fill:"url(#"+o.id+")",opacity:1,"fill-opacity":1}),h.fill=p,h.opacity=1,h.fillOpacity=1;return 1},bJ=function(b){var c=b.getBBox();bG(b.pattern,{patternTransform:a.format("translate({0},{1})",c.x,c.y)})},bK=function(c,d){var e={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},h=c.node,i=c.attrs,j=c.rotate(),k=function(a,b){b=e[x.call(b)];if(b){var c=a.attrs["stroke-width"]||"1",f=({round:c,square:c,butt:0})[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],i=b[w];while(i--)g[i]=b[i]*c+(i%2?1:-1)*f;bG(h,{"stroke-dasharray":g[v](",")})}};d[f]("rotation")&&(j=d.rotation);var m=r(j)[s](b);m.length-1?(m[1]=+m[1],m[2]=+m[2]):m=null,S(j)&&c.rotate(0,!0);for(var n in d)if(d[f](n)){if(!W[f](n))continue;var o=d[n];i[n]=o;switch(n){case"blur":c.blur(o);break;case"rotation":c.rotate(o,!0);break;case"href":case"title":case"target":var t=h.parentNode;if(x.call(t.tagName)!="a"){var u=bG("a");t.insertBefore(u,h),u[l](h),t=u}n=="target"&&o=="blank"?t.setAttributeNS(c.paper.xlink,"show","new"):t.setAttributeNS(c.paper.xlink,n,o);break;case"cursor":h.style.cursor=o;break;case"clip-rect":var y=r(o)[s](b);if(y[w]==4){c.clip&&c.clip.parentNode.parentNode.removeChild(c.clip.parentNode);var z=bG("clipPath"),A=bG("rect");z.id=bh(),bG(A,{x:y[0],y:y[1],width:y[2],height:y[3]}),z[l](A),c.paper.defs[l](z),bG(h,{"clip-path":"url(#"+z.id+")"}),c.clip=A}if(!o){var B=g.getElementById(h.getAttribute("clip-path")[Y](/(^url\(#|\)$)/g,p));B&&B.parentNode.removeChild(B),bG(h,{"clip-path":p}),delete c.clip}break;case"path":c.type=="path"&&bG(h,{d:o?i.path=bq(o):"M0,0"});break;case"width":h[R](n,o);if(i.fx)n="x",o=i.x;else break;case"x":i.fx&&(o=-i.x-(i.width||0));case"rx":if(n=="rx"&&c.type=="rect")break;case"cx":m&&(n=="x"||n=="cx")&&(m[1]+=o-i[n]),h[R](n,o),c.pattern&&bJ(c);break;case"height":h[R](n,o);if(i.fy)n="y",o=i.y;else break;case"y":i.fy&&(o=-i.y-(i.height||0));case"ry":if(n=="ry"&&c.type=="rect")break;case"cy":m&&(n=="y"||n=="cy")&&(m[2]+=o-i[n]),h[R](n,o),c.pattern&&bJ(c);break;case"r":c.type=="rect"?bG(h,{rx:o,ry:o}):h[R](n,o);break;case"src":c.type=="image"&&h.setAttributeNS(c.paper.xlink,"href",o);break;case"stroke-width":h.style.strokeWidth=o,h[R](n,o),i["stroke-dasharray"]&&k(c,i["stroke-dasharray"]);break;case"stroke-dasharray":k(c,o);break;case"translation":var C=r(o)[s](b);C[0]=+C[0]||0,C[1]=+C[1]||0,m&&(m[1]+=C[0],m[2]+=C[1]),cA.call(c,C[0],C[1]);break;case"scale":C=r(o)[s](b),c.scale(+C[0]||1,+C[1]||+C[0]||1,isNaN(S(C[2]))?null:+C[2],isNaN(S(C[3]))?null:+C[3]);break;case I:var D=r(o).match(M);if(D){z=bG("pattern");var E=bG("image");z.id=bh(),bG(z,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),bG(E,{x:0,y:0}),E.setAttributeNS(c.paper.xlink,"href",D[1]),z[l](E);var F=g.createElement("img");F.style.cssText="position:absolute;left:-9999em;top-9999em",F.onload=function(){bG(z,{width:this.offsetWidth,height:this.offsetHeight}),bG(E,{width:this.offsetWidth,height:this.offsetHeight}),g.body.removeChild(this),c.paper.safari()},g.body[l](F),F.src=D[1],c.paper.defs[l](z),h.style.fill="url(#"+z.id+")",bG(h,{fill:"url(#"+z.id+")"}),c.pattern=z,c.pattern&&bJ(c);break}var G=a.getRGB(o);if(!G.error)delete d.gradient,delete i.gradient,!a.is(i.opacity,"undefined")&&a.is(d.opacity,"undefined")&&bG(h,{opacity:i.opacity}),!a.is(i["fill-opacity"],"undefined")&&a.is(d["fill-opacity"],"undefined")&&bG(h,{"fill-opacity":i["fill-opacity"]});else if((({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper)){i.gradient=o,i.fill="none";break}G[f]("opacity")&&bG(h,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(o),h[R](n,G.hex),n=="stroke"&&G[f]("opacity")&&bG(h,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity});break;case"gradient":(({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper);break;case"opacity":i.gradient&&!i[f]("stroke-opacity")&&bG(h,{"stroke-opacity":o>1?o/100:o});case"fill-opacity":if(i.gradient){var H=g.getElementById(h.getAttribute(I)[Y](/^url\(#|\)$/g,p));if(H){var J=H.getElementsByTagName("stop");J[J[w]-1][R]("stop-opacity",o)}break};default:n=="font-size"&&(o=T(o,10)+"px");var K=n[Y](/(\-.)/g,function(a){return V.call(a.substring(1))});h.style[K]=o,h[R](n,o)}}bM(c,d),m?c.rotate(m.join(q)):S(j)&&c.rotate(j,!0)},bL=1.2,bM=function(b,c){if(b.type=="text"&&!!(c[f]("text")||c[f]("font")||c[f]("font-size")||c[f]("x")||c[f]("y"))){var d=b.attrs,e=b.node,h=e.firstChild?T(g.defaultView.getComputedStyle(e.firstChild,p).getPropertyValue("font-size"),10):10;if(c[f]("text")){d.text=c.text;while(e.firstChild)e.removeChild(e.firstChild);var i=r(c.text)[s]("\n");for(var j=0,k=i[w];j<k;j++)if(i[j]){var m=bG("tspan");j&&bG(m,{dy:h*bL,x:d.x}),m[l](g.createTextNode(i[j])),e[l](m)}}else{i=e.getElementsByTagName("tspan");for(j=0,k=i[w];j<k;j++)j&&bG(i[j],{dy:h*bL,x:d.x})}bG(e,{y:d.y});var n=b.getBBox(),o=d.y-(n.y+n.height/2);o&&a.is(o,"finite")&&bG(e,{y:d.y+o})}},bN=function(b,c){var d=0,e=0;this[0]=b,this.id=a._oid++,this.node=b,b.raphael=this,this.paper=c,this.attrs=this.attrs||{},this.transformations=[],this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},bO=bN[e];bN[e].rotate=function(c,d,e){if(this.removed)return this;if(c==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}var f=this.getBBox();c=r(c)[s](b),c[w]-1&&(d=S(c[1]),e=S(c[2])),c=S(c[0]),d!=null&&d!==!1?this._.rt.deg=c:this._.rt.deg+=c,e==null&&(d=null),this._.rt.cx=d,this._.rt.cy=e,d=d==null?f.x+f.width/2:d,e=e==null?f.y+f.height/2:e,this._.rt.deg?(this.transformations[0]=a.format("rotate({0} {1} {2})",this._.rt.deg,d,e),this.clip&&bG(this.clip,{transform:a.format("rotate({0} {1} {2})",-this._.rt.deg,d,e)})):(this.transformations[0]=p,this.clip&&bG(this.clip,{transform:p})),bG(this.node,{transform:this.transformations[v](q)});return this},bN[e].hide=function(){!this.removed&&(this.node.style.display="none");return this},bN[e].show=function(){!this.removed&&(this.node.style.display="");return this},bN[e].remove=function(){if(!this.removed){bA(this,this.paper),this.node.parentNode.removeChild(this.node);for(var a in this)delete this[a];this.removed=!0}},bN[e].getBBox=function(){if(this.removed)return this;if(this.type=="path")return bn(this.attrs.path);if(this.node.style.display=="none"){this.show();var a=!0}var b={};try{b=this.node.getBBox()}catch(c){}finally{b=b||{}}if(this.type=="text"){b={x:b.x,y:Infinity,width:0,height:0};for(var d=0,e=this.node.getNumberOfChars();d<e;d++){var f=this.node.getExtentOfChar(d);f.y<b.y&&(b.y=f.y),f.y+f.height-b.y>b.height&&(b.height=f.y+f.height-b.y),f.x+f.width-b.x>b.width&&(b.width=f.x+f.width-b.x)}}a&&this.hide();return b},bN[e].attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate()),(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale()),d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,F)){if(b=="translation")return cA.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(c==null&&a.is(b,G)){var g={};for(var h=0,i=b.length;h<i;h++)g[b[h]]=this.attr(b[h]);return g}if(c!=null){var j={};j[b]=c}else b!=null&&a.is(b,"object")&&(j=b);for(var k in this.paper.customAttributes)if(this.paper.customAttributes[f](k)&&j[f](k)&&a.is(this.paper.customAttributes[k],"function")){var l=this.paper.customAttributes[k].apply(this,[][n](j[k]));this.attrs[k]=j[k];for(var m in l)l[f](m)&&(j[m]=l[m])}bK(this,j);return this},bN[e].toFront=function(){if(this.removed)return this;this.node.parentNode[l](this.node);var a=this.paper;a.top!=this&&bB(this,a);return this},bN[e].toBack=function(){if(this.removed)return this;if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),bC(this,this.paper);var a=this.paper}return this},bN[e].insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length-1].node;b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode[l](this.node),bD(this,a,this.paper);return this},bN[e].insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;b.parentNode.insertBefore(this.node,b),bE(this,a,this.paper);return this},bN[e].blur=function(a){var b=this;if(+a!==0){var c=bG("filter"),d=bG("feGaussianBlur");b.attrs.blur=a,c.id=bh(),bG(d,{stdDeviation:+a||1.5}),c.appendChild(d),b.paper.defs.appendChild(c),b._blur=c,bG(b.node,{filter:"url(#"+c.id+")"})}else b._blur&&(b._blur.parentNode.removeChild(b._blur),delete b._blur,delete b.attrs.blur),b.node.removeAttribute("filter")};var bP=function(a,b,c,d){var e=bG("circle");a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",bG(e,f.attrs);return f},bQ=function(a,b,c,d,e,f){var g=bG("rect");a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",bG(g,h.attrs);return h},bR=function(a,b,c,d,e){var f=bG("ellipse");a.canvas&&a.canvas[l](f);var g=new bN(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",bG(f,g.attrs);return g},bS=function(a,b,c,d,e,f){var g=bG("image");bG(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(a.xlink,"href",b),a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image";return h},bT=function(a,b,c,d){var e=bG("text");bG(e,{x:b,y:c,"text-anchor":"middle"}),a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={x:b,y:c,"text-anchor":"middle",text:d,font:W.font,stroke:"none",fill:"#000"},f.type="text",bK(f,f.attrs);return f},bU=function(a,b){this.width=a||this.width,this.height=b||this.height,this.canvas[R]("width",this.width),this.canvas[R]("height",this.height);return this},bV=function(){var b=by[m](0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,h=b.height;if(!c)throw new Error("SVG container not found.");var i=bG("svg");d=d||0,e=e||0,f=f||512,h=h||342,bG(i,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:f,height:h}),c==1?(i.style.cssText="position:absolute;left:"+d+"px;top:"+e+"px",g.body[l](i)):c.firstChild?c.insertBefore(i,c.firstChild):c[l](i),c=new j,c.width=f,c.height=h,c.canvas=i,bz.call(c,c,a.fn),c.clear();return c};k.clear=function(){var a=this.canvas;while(a.firstChild)a.removeChild(a.firstChild);this.bottom=this.top=null,(this.desc=bG("desc"))[l](g.createTextNode("Created with RaphaÃ«l")),a[l](this.desc),a[l](this.defs=bG("defs"))},k.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a)}}if(a.vml){var bW={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},bX=/([clmz]),?([^clmz]*)/gi,bY=/ progid:\S+Blur\([^\)]+\)/g,bZ=/-?[^,\s-]+/g,b$=1e3+q+1e3,b_=10,ca={path:1,rect:1},cb=function(a){var b=/[ahqstv]/ig,c=bq;r(a).match(b)&&(c=bw),b=/[clmz]/g;if(c==bq&&!r(a).match(b)){var d=r(a)[Y](bX,function(a,b,c){var d=[],e=x.call(b)=="m",f=bW[b];c[Y](bZ,function(a){e&&d[w]==2&&(f+=d+bW[b=="m"?"l":"L"],d=[]),d[L](Q(a*b_))});return f+d});return d}var e=c(a),f,g;d=[];for(var h=0,i=e[w];h<i;h++){f=e[h],g=x.call(e[h][0]),g=="z"&&(g="x");for(var j=1,k=f[w];j<k;j++)g+=Q(f[j]*b_)+(j!=k-1?",":p);d[L](g)}return d[v](q)};a[H]=function(){return"Your browser doesnâ€™t support SVG. Falling down to VML.\nYou are running RaphaÃ«l "+this.version},bH=function(a,b){var c=cd("group");c.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px",c.coordsize=b.coordsize,c.coordorigin=b.coordorigin;var d=cd("shape"),e=d.style;e.width=b.width+"px",e.height=b.height+"px",d.coordsize=b$,d.coordorigin=b.coordorigin,c[l](d);var f=new bN(d,c,b),g={fill:"none",stroke:"#000"};a&&(g.path=a),f.type="path",f.path=[],f.Path=p,bK(f,g),b.canvas[l](c);var h=cd("skew");h.on=!0,d.appendChild(h),f.skew=h;return f},bK=function(c,d){c.attrs=c.attrs||{};var e=c.node,h=c.attrs,i=e.style,j,k=(d.x!=h.x||d.y!=h.y||d.width!=h.width||d.height!=h.height||d.r!=h.r)&&c.type=="rect",m=c;for(var n in d)d[f](n)&&(h[n]=d[n]);k&&(h.path=cc(h.x,h.y,h.width,h.height,h.r),c.X=h.x,c.Y=h.y,c.W=h.width,c.H=h.height),d.href&&(e.href=d.href),d.title&&(e.title=d.title),d.target&&(e.target=d.target),d.cursor&&(i.cursor=d.cursor),"blur"in d&&c.blur(d.blur);if(d.path&&c.type=="path"||k)e.path=cb(h.path);d.rotation!=null&&c.rotate(d.rotation,!0),d.translation&&(j=r(d.translation)[s](b),cA.call(c,j[0],j[1]),c._.rt.cx!=null&&(c._.rt.cx+=+j[0],c._.rt.cy+=+j[1],c.setBox(c.attrs,j[0],j[1]))),d.scale&&(j=r(d.scale)[s](b),c.scale(+j[0]||1,+j[1]||+j[0]||1,+j[2]||null,+j[3]||null));if("clip-rect"in d){var o=r(d["clip-rect"])[s](b);if(o[w]==4){o[2]=+o[2]+ +o[0],o[3]=+o[3]+ +o[1];var q=e.clipRect||g.createElement("div"),t=q.style,u=e.parentNode;t.clip=a.format("rect({1}px {2}px {3}px {0}px)",o),e.clipRect||(t.position="absolute",t.top=0,t.left=0,t.width=c.paper.width+"px",t.height=c.paper.height+"px",u.parentNode.insertBefore(q,u),q[l](u),e.clipRect=q)}d["clip-rect"]||e.clipRect&&(e.clipRect.style.clip=p)}c.type=="image"&&d.src&&(e.src=d.src),c.type=="image"&&d.opacity&&(e.filterOpacity=U+".Alpha(opacity="+d.opacity*100+")",i.filter=(e.filterMatrix||p)+(e.filterOpacity||p)),d.font&&(i.font=d.font),d["font-family"]&&(i.fontFamily='"'+d["font-family"][s](",")[0][Y](/^['"]+|['"]+$/g,p)+'"'),d["font-size"]&&(i.fontSize=d["font-size"]),d["font-weight"]&&(i.fontWeight=d["font-weight"]),d["font-style"]&&(i.fontStyle=d["font-style"]);if(d.opacity!=null||d["stroke-width"]!=null||d.fill!=null||d.stroke!=null||d["stroke-width"]!=null||d["stroke-opacity"]!=null||d["fill-opacity"]!=null||d["stroke-dasharray"]!=null||d["stroke-miterlimit"]!=null||d["stroke-linejoin"]!=null||d["stroke-linecap"]!=null){e=c.shape||e;var v=e.getElementsByTagName(I)&&e.getElementsByTagName(I)[0],x=!1;!v&&(x=v=cd(I));if("fill-opacity"in d||"opacity"in d){var y=((+h["fill-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+a.getRGB(d.fill).o+1||2)-1);y=A(z(y,0),1),v.opacity=y}d.fill&&(v.on=!0);if(v.on==null||d.fill=="none")v.on=!1;if(v.on&&d.fill){var B=d.fill.match(M);B?(v.src=B[1],v.type="tile"):(v.color=a.getRGB(d.fill).hex,v.src=p,v.type="solid",a.getRGB(d.fill).error&&(m.type in{circle:1,ellipse:1}||r(d.fill).charAt()!="r")&&bI(m,d.fill)&&(h.fill="none",h.gradient=d.fill))}x&&e[l](v);var C=e.getElementsByTagName("stroke")&&e.getElementsByTagName("stroke")[0],D=!1;!C&&(D=C=cd("stroke"));if(d.stroke&&d.stroke!="none"||d["stroke-width"]||d["stroke-opacity"]!=null||d["stroke-dasharray"]||d["stroke-miterlimit"]||d["stroke-linejoin"]||d["stroke-linecap"])C.on=!0;(d.stroke=="none"||C.on==null||d.stroke==0||d["stroke-width"]==0)&&(C.on=!1);var E=a.getRGB(d.stroke);C.on&&d.stroke&&(C.color=E.hex),y=((+h["stroke-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+E.o+1||2)-1);var F=(S(d["stroke-width"])||1)*.75;y=A(z(y,0),1),d["stroke-width"]==null&&(F=h["stroke-width"]),d["stroke-width"]&&(C.weight=F),F&&F<1&&(y*=F)&&(C.weight=1),C.opacity=y,d["stroke-linejoin"]&&(C.joinstyle=d["stroke-linejoin"]||"miter"),C.miterlimit=d["stroke-miterlimit"]||8,d["stroke-linecap"]&&(C.endcap=d["stroke-linecap"]=="butt"?"flat":d["stroke-linecap"]=="square"?"square":"round");if(d["stroke-dasharray"]){var G={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};C.dashstyle=G[f](d["stroke-dasharray"])?G[d["stroke-dasharray"]]:p}D&&e[l](C)}if(m.type=="text"){i=m.paper.span.style,h.font&&(i.font=h.font),h["font-family"]&&(i.fontFamily=h["font-family"]),h["font-size"]&&(i.fontSize=h["font-size"]),h["font-weight"]&&(i.fontWeight=h["font-weight"]),h["font-style"]&&(i.fontStyle=h["font-style"]),m.node.string&&(m.paper.span.innerHTML=r(m.node.string)[Y](/</g,"&#60;")[Y](/&/g,"&#38;")[Y](/\n/g,"<br>")),m.W=h.w=m.paper.span.offsetWidth,m.H=h.h=m.paper.span.offsetHeight,m.X=h.x,m.Y=h.y+Q(m.H/2);switch(h["text-anchor"]){case"start":m.node.style["v-text-align"]="left",m.bbx=Q(m.W/2);break;case"end":m.node.style["v-text-align"]="right",m.bbx=-Q(m.W/2);break;default:m.node.style["v-text-align"]="center"}}},bI=function(a,b){a.attrs=a.attrs||{};var c=a.attrs,d,e="linear",f=".5 .5";a.attrs.gradient=b,b=r(b)[Y](bd,function(a,b,c){e="radial",b&&c&&(b=S(b),c=S(c),C(b-.5,2)+C(c-.5,2)>.25&&(c=y.sqrt(.25-C(b-.5,2))*((c>.5)*2-1)+.5),f=b+q+c);return p}),b=b[s](/\s*\-\s*/);if(e=="linear"){var g=b.shift();g=-S(g);if(isNaN(g))return null}var h=bx(b);if(!h)return null;a=a.shape||a.node,d=a.getElementsByTagName(I)[0]||cd(I),!d.parentNode&&a.appendChild(d);if(h[w]){d.on=!0,d.method="none",d.color=h[0].color,d.color2=h[h[w]-1].color;var i=[];for(var j=0,k=h[w];j<k;j++)h[j].offset&&i[L](h[j].offset+q+h[j].color);d.colors&&(d.colors.value=i[w]?i[v]():"0% "+d.color),e=="radial"?(d.type="gradientradial",d.focus="100%",d.focussize=f,d.focusposition=f):(d.type="gradient",d.angle=(270-g)%360)}return 1},bN=function(b,c,d){var e=0,f=0,g=0,h=1;this[0]=b,this.id=a._oid++,this.node=b,b.raphael=this,this.X=0,this.Y=0,this.attrs={},this.Group=c,this.paper=d,this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1},!d.bottom&&(d.bottom=this),this.prev=d.top,d.top&&(d.top.next=this),d.top=this,this.next=null},bO=bN[e],bO.rotate=function(a,c,d){if(this.removed)return this;if(a==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}a=r(a)[s](b),a[w]-1&&(c=S(a[1]),d=S(a[2])),a=S(a[0]),c!=null?this._.rt.deg=a:this._.rt.deg+=a,d==null&&(c=null),this._.rt.cx=c,this._.rt.cy=d,this.setBox(this.attrs,c,d),this.Group.style.rotation=this._.rt.deg;return this},bO.setBox=function(a,b,c){if(this.removed)return this;var d=this.Group.style,e=this.shape&&this.shape.style||this.node.style;a=a||{};for(var g in a)a[f](g)&&(this.attrs[g]=a[g]);b=b||this._.rt.cx,c=c||this._.rt.cy;var h=this.attrs,i,j,k,l;switch(this.type){case"circle":i=h.cx-h.r,j=h.cy-h.r,k=l=h.r*2;break;case"ellipse":i=h.cx-h.rx,j=h.cy-h.ry,k=h.rx*2,l=h.ry*2;break;case"image":i=+h.x,j=+h.y,k=h.width||0,l=h.height||0;break;case"text":this.textpath.v=["m",Q(h.x),", ",Q(h.y-2),"l",Q(h.x)+1,", ",Q(h.y-2)][v](p),i=h.x-Q(this.W/2),j=h.y-this.H/2,k=this.W,l=this.H;break;case"rect":case"path":if(!this.attrs.path)i=0,j=0,k=this.paper.width,l=this.paper.height;else{var m=bn(this.attrs.path);i=m.x,j=m.y,k=m.width,l=m.height}break;default:i=0,j=0,k=this.paper.width,l=this.paper.height}b=b==null?i+k/2:b,c=c==null?j+l/2:c;var n=b-this.paper.width/2,o=c-this.paper.height/2,q;d.left!=(q=n+"px")&&(d.left=q),d.top!=(q=o+"px")&&(d.top=q),this.X=ca[f](this.type)?-n:i,this.Y=ca[f](this.type)?-o:j,this.W=k,this.H=l,ca[f](this.type)?(e.left!=(q=-n*b_+"px")&&(e.left=q),e.top!=(q=-o*b_+"px")&&(e.top=q)):this.type=="text"?(e.left!=(q=-n+"px")&&(e.left=q),e.top!=(q=-o+"px")&&(e.top=q)):(d.width!=(q=this.paper.width+"px")&&(d.width=q),d.height!=(q=this.paper.height+"px")&&(d.height=q),e.left!=(q=i-n+"px")&&(e.left=q),e.top!=(q=j-o+"px")&&(e.top=q),e.width!=(q=k+"px")&&(e.width=q),e.height!=(q=l+"px")&&(e.height=q))},bO.hide=function(){!this.removed&&(this.Group.style.display="none");return this},bO.show=function(){!this.removed&&(this.Group.style.display="block");return this},bO.getBBox=function(){if(this.removed)return this;if(ca[f](this.type))return bn(this.attrs.path);return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}},bO.remove=function(){if(!this.removed){bA(this,this.paper),this.node.parentNode.removeChild(this.node),this.Group.parentNode.removeChild(this.Group),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)delete this[a];this.removed=!0}},bO.attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate()),(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale()),d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,"string")){if(b=="translation")return cA.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(this.attrs&&c==null&&a.is(b,G)){var g,h={};for(e=0,g=b[w];e<g;e++)h[b[e]]=this.attr(b[e]);return h}var i;c!=null&&(i={},i[b]=c),c==null&&a.is(b,"object")&&(i=b);if(i){for(var j in this.paper.customAttributes)if(this.paper.customAttributes[f](j)&&i[f](j)&&a.is(this.paper.customAttributes[j],"function")){var k=this.paper.customAttributes[j].apply(this,[][n](i[j]));this.attrs[j]=i[j];for(var l in k)k[f](l)&&(i[l]=k[l])}i.text&&this.type=="text"&&(this.node.string=i.text),bK(this,i),i.gradient&&(({circle:1,ellipse:1})[f](this.type)||r(i.gradient).charAt()!="r")&&bI(this,i.gradient),(!ca[f](this.type)||this._.rt.deg)&&this.setBox(this.attrs)}return this},bO.toFront=function(){!this.removed&&this.Group.parentNode[l](this.Group),this.paper.top!=this&&bB(this,this.paper);return this},bO.toBack=function(){if(this.removed)return this;this.Group.parentNode.firstChild!=this.Group&&(this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild),bC(this,this.paper));return this},bO.insertAfter=function(a){if(this.removed)return this;a.constructor==cD&&(a=a[a.length-1]),a.Group.nextSibling?a.Group.parentNode.insertBefore(this.Group,a.Group.nextSibling):a.Group.parentNode[l](this.Group),bD(this,a,this.paper);return this},bO.insertBefore=function(a){if(this.removed)return this;a.constructor==cD&&(a=a[0]),a.Group.parentNode.insertBefore(this.Group,a.Group),bE(this,a,this.paper);return this},bO.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(bY,p),+b!==0?(this.attrs.blur=b,c.filter=d+q+U+".Blur(pixelradius="+(+b||1.5)+")",c.margin=a.format("-{0}px 0 0 -{0}px",Q(+b||1.5))):(c.filter=d,c.margin=0,delete this.attrs.blur)},bP=function(a,b,c,d){var e=cd("group"),f=cd("oval"),g=f.style;e.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px",e.coordsize=b$,e.coordorigin=a.coordorigin,e[l](f);var h=new bN(f,e,a);h.type="circle",bK(h,{stroke:"#000",fill:"none"}),h.attrs.cx=b,h.attrs.cy=c,h.attrs.r=d,h.setBox({x:b-d,y:c-d,width:d*2,height:d*2}),a.canvas[l](e);return h};function cc(b,c,d,e,f){return f?a.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",b+f,c,d-f*2,f,-f,e-f*2,f*2-d,f*2-e):a.format("M{0},{1}l{2},0,0,{3},{4},0z",b,c,d,e,-d)}bQ=function(a,b,c,d,e,f){var g=cc(b,c,d,e,f),h=a.path(g),i=h.attrs;h.X=i.x=b,h.Y=i.y=c,h.W=i.width=d,h.H=i.height=e,i.r=f,i.path=g,h.type="rect";return h},bR=function(a,b,c,d,e){var f=cd("group"),g=cd("oval"),h=g.style;f.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px",f.coordsize=b$,f.coordorigin=a.coordorigin,f[l](g);var i=new bN(g,f,a);i.type="ellipse",bK(i,{stroke:"#000"}),i.attrs.cx=b,i.attrs.cy=c,i.attrs.rx=d,i.attrs.ry=e,i.setBox({x:b-d,y:c-e,width:d*2,height:e*2}),a.canvas[l](f);return i},bS=function(a,b,c,d,e,f){var g=cd("group"),h=cd("image");g.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px",g.coordsize=b$,g.coordorigin=a.coordorigin,h.src=b,g[l](h);var i=new bN(h,g,a);i.type="image",i.attrs.src=b,i.attrs.x=c,i.attrs.y=d,i.attrs.w=e,i.attrs.h=f,i.setBox({x:c,y:d,width:e,height:f}),a.canvas[l](g);var j=cd("skew");j.on=!0,h.appendChild(j),i.skew=j;return i},bT=function(b,c,d,e){var f=cd("group"),g=cd("shape"),h=g.style,i=cd("path"),j=i.style,k=cd("textpath");f.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px",f.coordsize=b$,f.coordorigin=b.coordorigin,i.v=a.format("m{0},{1}l{2},{1}",Q(c*10),Q(d*10),Q(c*10)+1),i.textpathok=!0,h.width=b.width,h.height=b.height,k.string=r(e),k.on=!0,g[l](k),g[l](i),f[l](g);var m=new bN(k,f,b);m.shape=g,m.textpath=i,m.type="text",m.attrs.text=e,m.attrs.x=c,m.attrs.y=d,m.attrs.w=1,m.attrs.h=1,bK(m,{font:W.font,stroke:"none",fill:"#000"}),m.setBox(),b.canvas[l](f);return m},bU=function(a,b){var c=this.canvas.style;a==+a&&(a+="px"),b==+b&&(b+="px"),c.width=a,c.height=b,c.clip="rect(0 "+a+" "+b+" 0)";return this};var cd;g.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!g.namespaces.rvml&&g.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),cd=function(a){return g.createElement("<rvml:"+a+' class="rvml">')}}catch(ce){cd=function(a){return g.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}bV=function(){var b=by[m](0,arguments),c=b.container,d=b.height,e,f=b.width,h=b.x,i=b.y;if(!c)throw new Error("VML container not found.");var k=new j,n=k.canvas=g.createElement("div"),o=n.style;h=h||0,i=i||0,f=f||512,d=d||342,f==+f&&(f+="px"),d==+d&&(d+="px"),k.width=1e3,k.height=1e3,k.coordsize=b_*1e3+q+b_*1e3,k.coordorigin="0 0",k.span=g.createElement("span"),k.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",n[l](k.span),o.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d),c==1?(g.body[l](n),o.left=h+"px",o.top=i+"px",o.position="absolute"):c.firstChild?c.insertBefore(n,c.firstChild):c[l](n),bz.call(k,k,a.fn);return k},k.clear=function(){this.canvas.innerHTML=p,this.span=g.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas[l](this.span),this.bottom=this.top=null},k.remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a);return!0}}var cf=navigator.userAgent.match(/Version\/(.*?)\s/);navigator.vendor=="Apple Computer, Inc."&&(cf&&cf[1]<4||navigator.platform.slice(0,2)=="iP")?k.safari=function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});h.setTimeout(function(){a.remove()})}:k.safari=function(){};var cg=function(){this.returnValue=!1},ch=function(){return this.originalEvent.preventDefault()},ci=function(){this.cancelBubble=!0},cj=function(){return this.originalEvent.stopPropagation()},ck=function(){if(g.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,g=function(e){if(o&&u[f](b))for(var g=0,h=e.targetTouches&&e.targetTouches.length;g<h;g++)if(e.targetTouches[g].target==a){var i=e;e=e.targetTouches[g],e.originalEvent=i,e.preventDefault=ch,e.stopPropagation=cj;break}return c.call(d,e)};a.addEventListener(e,g,!1);return function(){a.removeEventListener(e,g,!1);return!0}};if(g.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.event,a.preventDefault=a.preventDefault||cg,a.stopPropagation=a.stopPropagation||ci;return c.call(d,a)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return!0};return f}}(),cl=[],cm=function(a){var b=a.clientX,c=a.clientY,d=g.documentElement.scrollTop||g.body.scrollTop,e=g.documentElement.scrollLeft||g.body.scrollLeft,f,h=cl.length;while(h--){f=cl[h];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];if(j.identifier==f.el._drag.id){b=j.clientX,c=j.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();b+=e,c+=d,f.move&&f.move.call(f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},cn=function(b){a.unmousemove(cm).unmouseup(cn);var c=cl.length,d;while(c--)d=cl[c],d.el._drag={},d.end&&d.end.call(d.end_scope||d.start_scope||d.move_scope||d.el,b);cl=[]};for(var co=t[w];co--;)(function(b){a[b]=bN[e][b]=function(c,d){a.is(c,"function")&&(this.events=this.events||[],this.events.push({name:b,f:c,unbind:ck(this.shape||this.node||g,b,c,d||this)}));return this},a["un"+b]=bN[e]["un"+b]=function(a){var c=this.events,d=c[w];while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind(),c.splice(d,1),!c.length&&delete this.events;return this}return this}})(t[co]);bO.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},bO.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)},bO.drag=function(b,c,d,e,f,h){this._drag={},this.mousedown(function(i){(i.originalEvent||i).preventDefault();var j=g.documentElement.scrollTop||g.body.scrollTop,k=g.documentElement.scrollLeft||g.body.scrollLeft;this._drag.x=i.clientX+k,this._drag.y=i.clientY+j,this._drag.id=i.identifier,c&&c.call(f||e||this,i.clientX+k,i.clientY+j,i),!cl.length&&a.mousemove(cm).mouseup(cn),cl.push({el:this,move:b,end:d,move_scope:e,start_scope:f,end_scope:h})});return this},bO.undrag=function(b,c,d){var e=cl.length;while(e--)cl[e].el==this&&cl[e].move==b&&cl[e].end==d&&cl.splice(e++,1);!cl.length&&a.unmousemove(cm).unmouseup(cn)},k.circle=function(a,b,c){return bP(this,a||0,b||0,c||0)},k.rect=function(a,b,c,d,e){return bQ(this,a||0,b||0,c||0,d||0,e||0)},k.ellipse=function(a,b,c,d){return bR(this,a||0,b||0,c||0,d||0)},k.path=function(b){b&&!a.is(b,F)&&!a.is(b[0],G)&&(b+=p);return bH(a.format[m](a,arguments),this)},k.image=function(a,b,c,d,e){return bS(this,a||"about:blank",b||0,c||0,d||0,e||0)},k.text=function(a,b,c){return bT(this,a||0,b||0,r(c))},k.set=function(a){arguments[w]>1&&(a=Array[e].splice.call(arguments,0,arguments[w]));return new cD(a)},k.setSize=bU,k.top=k.bottom=null,k.raphael=a,bO.resetScale=function(){if(this.removed)return this;this._.sx=1,this._.sy=1,this.attrs.scale="1 1"},bO.scale=function(a,b,c,d){if(this.removed)return this;if(a==null&&b==null)return{x:this._.sx,y:this._.sy,toString:cp};b=b||a,!+b&&(b=a);var e,f,g,h,i=this.attrs;if(a!=0){var j=this.getBBox(),k=j.x+j.width/2,l=j.y+j.height/2,m=B(a/this._.sx),o=B(b/this._.sy);c=+c||c==0?c:k,d=+d||d==0?d:l;var r=this._.sx>0,s=this._.sy>0,t=~~(a/B(a)),u=~~(b/B(b)),x=m*t,y=o*u,z=this.node.style,A=c+B(k-c)*x*(k>c==r?1:-1),C=d+B(l-d)*y*(l>d==s?1:-1),D=a*t>b*u?o:m;switch(this.type){case"rect":case"image":var E=i.width*m,F=i.height*o;this.attr({height:F,r:i.r*D,width:E,x:A-E/2,y:C-F/2});break;case"circle":case"ellipse":this.attr({rx:i.rx*m,ry:i.ry*o,r:i.r*D,cx:A,cy:C});break;case"text":this.attr({x:A,y:C});break;case"path":var G=bp(i.path),H=!0,I=r?x:m,J=s?y:o;for(var K=0,L=G[w];K<L;K++){var M=G[K],N=V.call(M[0]);if(N=="M"&&H)continue;H=!1;if(N=="A")M[G[K][w]-2]*=I,M[G[K][w]-1]*=J,M[1]*=m,M[2]*=o,M[5]=+(t+u?!!+M[5]:!+M[5]);else if(N=="H")for(var O=1,P=M[w];O<P;O++)M[O]*=I;else if(N=="V")for(O=1,P=M[w];O<P;O++)M[O]*=J;else for(O=1,P=M[w];O<P;O++)M[O]*=O%2?I:J}var Q=bn(G);e=A-Q.x-Q.width/2,f=C-Q.y-Q.height/2,G[0][1]+=e,G[0][2]+=f,this.attr({path:G})}this.type in{text:1,image:1}&&(t!=1||u!=1)?this.transformations?(this.transformations[2]="scale("[n](t,",",u,")"),this.node[R]("transform",this.transformations[v](q)),e=t==-1?-i.x-(E||0):i.x,f=u==-1?-i.y-(F||0):i.y,this.attr({x:e,y:f}),i.fx=t-1,i.fy=u-1):(this.node.filterMatrix=U+".Matrix(M11="[n](t,", M12=0, M21=0, M22=",u,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')"),z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)):this.transformations?(this.transformations[2]=p,this.node[R]("transform",this.transformations[v](q)),i.fx=0,i.fy=0):(this.node.filterMatrix=p,z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)),i.scale=[a,b,c,d][v](q),this._.sx=a,this._.sy=b}return this},bO.clone=function(){if(this.removed)return null;var a=this.attr();delete a.scale,delete a.translation;return this.paper[this.type]().attr(a)};var cq={},cr=function(b,c,d,e,f,g,h,i,j){var k=0,l=100,m=[b,c,d,e,f,g,h,i].join(),n=cq[m],o,p;!n&&(cq[m]=n={data:[]}),n.timer&&clearTimeout(n.timer),n.timer=setTimeout(function(){delete cq[m]},2e3);if(j!=null){var q=cr(b,c,d,e,f,g,h,i);l=~~q*10}for(var r=0;r<l+1;r++){n.data[j]>r?p=n.data[r*l]:(p=a.findDotsAtSegment(b,c,d,e,f,g,h,i,r/l),n.data[r]=p),r&&(k+=C(C(o.x-p.x,2)+C(o.y-p.y,2),.5));if(j!=null&&k>=j)return p;o=p}if(j==null)return k},cs=function(b,c){return function(d,e,f){d=bw(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M")g=+i[1],h=+i[2];else{j=cr(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cr(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),k+=["C",m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k,k=["M",m.x,m.y+"C",m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]][v](),n+=j,g=+i[5],h=+i[6];continue}if(!b&&!c){m=cr(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j,g=+i[5],h=+i[6]}k+=i}l.end=k,m=b?n:c?l:a.findDotsAtSegment(g,h,i[1],i[2],i[3],i[4],i[5],i[6],1),m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},ct=cs(1),cu=cs(),cv=cs(0,1);bO.getTotalLength=function(){if(this.type=="path"){if(this.node.getTotalLength)return this.node.getTotalLength();return ct(this.attrs.path)}},bO.getPointAtLength=function(a){if(this.type=="path")return cu(this.attrs.path,a)},bO.getSubpath=function(a,b){if(this.type=="path"){if(B(this.getTotalLength()-b)<"1e-6")return cv(this.attrs.path,a).end;var c=cv(this.attrs.path,b,1);return a?cv(c,a).end:c}},a.easing_formulas={linear:function(a){return a},"<":function(a){return C(a,3)},">":function(a){return C(a-1,3)+1},"<>":function(a){a=a*2;if(a<1)return C(a,3)/2;a-=2;return(C(a,3)+2)/2},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==0||a==1)return a;var b=.3,c=b/4;return C(2,-10*a)*y.sin((a-c)*2*D/b)+1},bounce:function(a){var b=7.5625,c=2.75,d;a<1/c?d=b*a*a:a<2/c?(a-=1.5/c,d=b*a*a+.75):a<2.5/c?(a-=2.25/c,d=b*a*a+.9375):(a-=2.625/c,d=b*a*a+.984375);return d}};var cw=[],cx=function(){var b=+(new Date);for(var c=0;c<cw[w];c++){var d=cw[c];if(d.stop||d.el.removed)continue;var e=b-d.start,g=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,n={},o;if(e<g){var r=h(e/g);for(var s in i)if(i[f](s)){switch(X[s]){case"along":o=r*g*j[s],k.back&&(o=k.len-o);var t=cu(k[s],o);m.translate(j.sx-j.x||0,j.sy-j.y||0),j.x=t.x,j.y=t.y,m.translate(t.x-j.sx,t.y-j.sy),k.rot&&m.rotate(j.r+t.alpha,t.x,t.y);break;case E:o=+i[s]+r*g*j[s];break;case"colour":o="rgb("+[cz(Q(i[s].r+r*g*j[s].r)),cz(Q(i[s].g+r*g*j[s].g)),cz(Q(i[s].b+r*g*j[s].b))][v](",")+")";break;case"path":o=[];for(var u=0,x=i[s][w];u<x;u++){o[u]=[i[s][u][0]];for(var y=1,z=i[s][u][w];y<z;y++)o[u][y]=+i[s][u][y]+r*g*j[s][u][y];o[u]=o[u][v](q)}o=o[v](q);break;case"csv":switch(s){case"translation":var A=r*g*j[s][0]-l.x,B=r*g*j[s][1]-l.y;l.x+=A,l.y+=B,o=A+q+B;break;case"rotation":o=+i[s][0]+r*g*j[s][0],i[s][1]&&(o+=","+i[s][1]+","+i[s][2]);break;case"scale":o=[+i[s][0]+r*g*j[s][0],+i[s][1]+r*g*j[s][1],2 in k[s]?k[s][2]:p,3 in k[s]?k[s][3]:p][v](q);break;case"clip-rect":o=[],u=4;while(u--)o[u]=+i[s][u]+r*g*j[s][u]}break;default:var C=[].concat(i[s]);o=[],u=m.paper.customAttributes[s].length;while(u--)o[u]=+C[u]+r*g*j[s][u]}n[s]=o}m.attr(n),m._run&&m._run.call(m)}else k.along&&(t=cu(k.along,k.len*!k.back),m.translate(j.sx-(j.x||0)+t.x-j.sx,j.sy-(j.y||0)+t.y-j.sy),k.rot&&m.rotate(j.r+t.alpha,t.x,t.y)),(l.x||l.y)&&m.translate(-l.x,-l.y),k.scale&&(k.scale+=p),m.attr(k),cw.splice(c--,1)}a.svg&&m&&m.paper&&m.paper.safari(),cw[w]&&setTimeout(cx)},cy=function(b,c,d,e,f){var g=d-e;c.timeouts.push(setTimeout(function(){a.is(f,"function")&&f.call(c),c.animate(b,g,b.easing)},e))},cz=function(a){return z(A(a,255),0)},cA=function(a,b){if(a==null)return{x:this._.tx,y:this._.ty,toString:cp};this._.tx+=+a,this._.ty+=+b;switch(this.type){case"circle":case"ellipse":this.attr({cx:+a+this.attrs.cx,cy:+b+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+a+this.attrs.x,y:+b+this.attrs.y});break;case"path":var c=bp(this.attrs.path);c[0][1]+=+a,c[0][2]+=+b,this.attr({path:c})}return this};bO.animateWith=function(a,b,c,d,e){for(var f=0,g=cw.length;f<g;f++)cw[f].el.id==a.id&&(b.start=cw[f].start);return this.animate(b,c,d,e)},bO.animateAlong=cB(),bO.animateAlongBack=cB(1),bO.onAnimation=function(a){this._run=a||0;return this},bO.animate=function(c,d,e,g){var h=this;h.timeouts=h.timeouts||[];if(a.is(e,"function")||!e)g=e||null;if(h.removed){g&&g.call(h);return h}var i={},j={},k=!1,l={};for(var m in c)if(c[f](m))if(X[f](m)||h.paper.customAttributes[f](m)){k=!0,i[m]=h.attr(m),i[m]==null&&(i[m]=W[m]),j[m]=c[m];switch(X[m]){case"along":var n=ct(c[m]),o=cu(c[m],n*!!c.back),p=h.getBBox();l[m]=n/d,l.tx=p.x,l.ty=p.y,l.sx=o.x,l.sy=o.y,j.rot=c.rot,j.back=c.back,j.len=n,c.rot&&(l.r=S(h.rotate())||0);break;case E:l[m]=(j[m]-i[m])/d;break;case"colour":i[m]=a.getRGB(i[m]);var q=a.getRGB(j[m]);l[m]={r:(q.r-i[m].r)/d,g:(q.g-i[m].g)/d,b:(q.b-i[m].b)/d};break;case"path":var t=bw(i[m],j[m]);i[m]=t[0];var u=t[1];l[m]=[];for(var v=0,x=i[m][w];v<x;v++){l[m][v]=[0];for(var y=1,z=i[m][v][w];y<z;y++)l[m][v][y]=(u[v][y]-i[m][v][y])/d}break;case"csv":var A=r(c[m])[s](b),B=r(i[m])[s](b);switch(m){case"translation":i[m]=[0,0],l[m]=[A[0]/d,A[1]/d];break;case"rotation":i[m]=B[1]==A[1]&&B[2]==A[2]?B:[0,A[1],A[2]],l[m]=[(A[0]-i[m][0])/d,0,0];break;case"scale":c[m]=A,i[m]=r(i[m])[s](b),l[m]=[(A[0]-i[m][0])/d,(A[1]-i[m][1])/d,0,0];break;case"clip-rect":i[m]=r(i[m])[s](b),l[m]=[],v=4;while(v--)l[m][v]=(A[v]-i[m][v])/d}j[m]=A;break;default:A=[].concat(c[m]),B=[].concat(i[m]),l[m]=[],v=h.paper.customAttributes[m][w];while(v--)l[m][v]=((A[v]||0)-(B[v]||0))/d}}if(!k){var C=[],D;for(var F in c)c[f](F)&&Z.test(F)&&(m={value:c[F]},F=="from"&&(F=0),F=="to"&&(F=100),m.key=T(F,10),C.push(m));C.sort(be),C[0].key&&C.unshift({key:0,value:h.attrs});for(v=0,x=C[w];v<x;v++)cy(C[v].value,h,d/100*C[v].key,d/100*(C[v-1]&&C[v-1].key||0),C[v-1]&&C[v-1].value.callback);D=C[C[w]-1].value.callback,D&&h.timeouts.push(setTimeout(function(){D.call(h)},d))}else{var G=a.easing_formulas[e];if(!G){G=r(e).match(P);if(G&&G[w]==5){var H=G;G=function(a){return cC(a,+H[1],+H[2],+H[3],+H[4],d)}}else G=function(a){return a}}cw.push({start:c.start||+(new Date),ms:d,easing:G,from:i,diff:l,to:j,el:h,t:{x:0,y:0}}),a.is(g,"function")&&(h._ac=setTimeout(function(){g.call(h)},d)),cw[w]==1&&setTimeout(cx)}return this},bO.stop=function(){for(var a=0;a<cw.length;a++)cw[a].el.id==this.id&&cw.splice(a--,1);for(a=0,ii=this.timeouts&&this.timeouts.length;a<ii;a++)clearTimeout(this.timeouts[a]);this.timeouts=[],clearTimeout(this._ac),delete this._ac;return this},bO.translate=function(a,b){return this.attr({translation:a+" "+b})},bO[H]=function(){return"RaphaÃ«lâ€™s object"},a.ae=cw;var cD=function(a){this.items=[],this[w]=0,this.type="set";if(a)for(var b=0,c=a[w];b<c;b++)a[b]&&(a[b].constructor==bN||a[b].constructor==cD)&&(this[this.items[w]]=this.items[this.items[w]]=a[b],this[w]++)};cD[e][L]=function(){var a,b;for(var c=0,d=arguments[w];c<d;c++)a=arguments[c],a&&(a.constructor==bN||a.constructor==cD)&&(b=this.items[w],this[b]=this.items[b]=a,this[w]++);return this},cD[e].pop=function(){delete this[this[w]--];return this.items.pop()};for(var cE in bO)bO[f](cE)&&(cD[e][cE]=function(a){return function(){for(var b=0,c=this.items[w];b<c;b++)this.items[b][a][m](this.items[b],arguments);return this}}(cE));cD[e].attr=function(b,c){if(b&&a.is(b,G)&&a.is(b[0],"object"))for(var d=0,e=b[w];d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items[w];f<g;f++)this.items[f].attr(b,c);return this},cD[e].animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items[w],g=f,h,i=this,j;e&&(j=function(){!--f&&e.call(i)}),d=a.is(d,F)?d:j,h=this.items[--g].animate(b,c,d,j);while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,b,c,d,j);return this},cD[e].insertAfter=function(a){var b=this.items[w];while(b--)this.items[b].insertAfter(a);return this},cD[e].getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items[w];e--;){var f=this.items[e].getBBox();a[L](f.x),b[L](f.y),c[L](f.x+f.width),d[L](f.y+f.height)}a=A[m](0,a),b=A[m](0,b);return{x:a,y:b,width:z[m](0,c)-a,height:z[m](0,d)-b}},cD[e].clone=function(a){a=new cD;for(var b=0,c=this.items[w];b<c;b++)a[L](this.items[b].clone());return a},a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[f](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c][L](b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=T(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[f](e)){var g=a.glyphs[e];b.glyphs[e]={w:g.w,k:{},d:g.d&&"M"+g.d[Y](/[mlcxtrv]/g,function(a){return({l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"})[a]||"M"})+"z"};if(g.k)for(var h in g.k)g[f](h)&&(b.glyphs[e].k[h]=g.k[h])}}return a},k.getFont=function(b,c,d,e){e=e||"normal",d=d||"normal",c=+c||({normal:400,bold:700,lighter:300,bolder:800})[c]||400;if(!!a.fonts){var g=a.fonts[b];if(!g){var h=new RegExp("(^|\\s)"+b[Y](/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[f](i)&&h.test(i)){g=a.fonts[i];break}}var j;if(g)for(var k=0,l=g[w];k<l;k++){j=g[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j}},k.print=function(c,d,e,f,g,h,i){h=h||"middle",i=z(A(i||0,1),-1);var j=this.set(),k=r(e)[s](p),l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];var o=f.face.bbox.split(b),q=+o[0],t=+o[1]+(h=="baseline"?o[3]-o[1]+ +f.face.descent:(o[3]-o[1])/2);for(var u=0,v=k[w];u<v;u++){var x=u&&f.glyphs[k[u-1]]||{},y=f.glyphs[k[u]];l+=u?(x.w||f.w)+(x.k&&x.k[k[u]]||0)+f.w*i:0,y&&y.d&&j[L](this.path(y.d).attr({fill:"#000",stroke:"none",translation:[l,0]}))}j.scale(n,n,q,t).translate(c-q,d-t)}return j},a.format=function(b,c){var e=a.is(c,G)?[0][n](c):arguments;b&&a.is(b,F)&&e[w]-1&&(b=b[Y](d,function(a,b){return e[++b]==null?p:e[b]}));return b||p},a.ninja=function(){i.was?h.Raphael=i.is:delete Raphael;return a},a.el=bO,a.st=cD[e],i.was?h.Raphael=a:Raphael=a})()
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4f5e9921a01dd7f12e2d5965f28343e0c44ae269.svn-base
--- a/.svn/pristine/4f/4f5e9921a01dd7f12e2d5965f28343e0c44ae269.svn-base
+++ /dev/null
@@ -1,1013 +0,0 @@
-# Portuguese localization for Ruby on Rails
-# by Ricardo Otero <oterosantos@gmail.com>
-# by Alberto Ferreira <toraxic@gmail.com>
-pt:
-  support:
-    array:
-      sentence_connector: "e"
-      skip_last_comma: true
-
-  direction: ltr
-  date:
-    formats:
-      default: "%d/%m/%Y"
-      short: "%d de %B"
-      long: "%d de %B de %Y"
-      only_day: "%d"
-    day_names: [Domingo, Segunda, TerÃ§a, Quarta, Quinta, Sexta, SÃ¡bado]
-    abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, SÃ¡b]
-    month_names: [~, Janeiro, Fevereiro, MarÃ§o, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro]
-    abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%A, %d de %B de %Y, %H:%Mh"
-      time: "%H:%M"
-      short: "%d/%m, %H:%M hs"
-      long: "%A, %d de %B de %Y, %H:%Mh"
-    am: ''
-    pm: ''
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "meio minuto"
-      less_than_x_seconds:
-        one: "menos de 1 segundo"
-        other: "menos de %{count} segundos"
-      x_seconds:
-        one: "1 segundo"
-        other: "%{count} segundos"
-      less_than_x_minutes:
-        one: "menos de um minuto"
-        other: "menos de %{count} minutos"
-      x_minutes:
-        one: "1 minuto"
-        other: "%{count} minutos"
-      about_x_hours:
-        one: "aproximadamente 1 hora"
-        other: "aproximadamente %{count} horas"
-      x_days:
-        one: "1 dia"
-        other: "%{count} dias"
-      about_x_months:
-        one: "aproximadamente 1 mÃªs"
-        other: "aproximadamente %{count} meses"
-      x_months:
-        one: "1 mÃªs"
-        other: "%{count} meses"
-      about_x_years:
-        one: "aproximadamente 1 ano"
-        other: "aproximadamente %{count} anos"
-      over_x_years:
-        one: "mais de 1 ano"
-        other: "mais de %{count} anos"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  number:
-    format:
-      precision: 3
-      separator: ','
-      delimiter: '.'
-    currency:
-      format:
-        unit: 'â‚¬'
-        precision: 2
-        format: "%u %n"
-        separator: ','
-        delimiter: '.'
-    percentage:
-      format:
-        delimiter: ''
-    precision:
-      format:
-        delimiter: ''
-    human:
-      format:
-        precision: 1
-        delimiter: ''
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one: "NÃ£o foi possÃ­vel guardar %{model}: 1 erro"
-          other: "NÃ£o foi possÃ­vel guardar %{model}: %{count} erros"
-        body: "Por favor, verifique os seguintes campos:"
-      messages:
-        inclusion: "nÃ£o estÃ¡ incluÃ­do na lista"
-        exclusion: "nÃ£o estÃ¡ disponÃ­vel"
-        invalid: "nÃ£o Ã© vÃ¡lido"
-        confirmation: "nÃ£o estÃ¡ de acordo com a confirmaÃ§Ã£o"
-        accepted:  "precisa de ser aceite"
-        empty: "nÃ£o pode estar em branco"
-        blank: "nÃ£o pode estar em branco"
-        too_long: "tem demasiados caracteres (mÃ¡ximo: %{count} caracteres)"
-        too_short: "tem poucos caracteres (mÃ­nimo: %{count} caracteres)"
-        wrong_length: "nÃ£o Ã© do tamanho correcto (necessita de ter %{count} caracteres)"
-        taken: "nÃ£o estÃ¡ disponÃ­vel"
-        not_a_number: "nÃ£o Ã© um nÃºmero"
-        greater_than: "tem de ser maior do que %{count}"
-        greater_than_or_equal_to: "tem de ser maior ou igual a %{count}"
-        equal_to: "tem de ser igual a %{count}"
-        less_than: "tem de ser menor do que %{count}"
-        less_than_or_equal_to: "tem de ser menor ou igual a %{count}"
-        odd: "tem de ser Ã­mpar"
-        even: "tem de ser par"
-        greater_than_start_date: "deve ser maior que a data inicial"
-        not_same_project: "nÃ£o pertence ao mesmo projecto"
-        circular_dependency: "Esta relaÃ§Ã£o iria criar uma dependÃªncia circular"
-        cant_link_an_issue_with_a_descendant: "NÃ£o Ã© possÃ­vel ligar uma tarefa a uma sub-tarefa que lhe Ã© pertencente"
-
-  ## Translated by: Pedro AraÃºjo <phcrva19@hotmail.com>
-  actionview_instancetag_blank_option: Seleccione
-
-  general_text_No: 'NÃ£o'
-  general_text_Yes: 'Sim'
-  general_text_no: 'nÃ£o'
-  general_text_yes: 'sim'
-  general_lang_name: 'PortuguÃªs'
-  general_csv_separator: ';'
-  general_csv_decimal_separator: ','
-  general_csv_encoding: ISO-8859-15
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: A conta foi actualizada com sucesso.
-  notice_account_invalid_creditentials: Utilizador ou palavra-chave invÃ¡lidos.
-  notice_account_password_updated: A palavra-chave foi alterada com sucesso.
-  notice_account_wrong_password: Palavra-chave errada.
-  notice_account_register_done: A conta foi criada com sucesso.
-  notice_account_unknown_email: Utilizador desconhecido.
-  notice_can_t_change_password: Esta conta utiliza uma fonte de autenticaÃ§Ã£o externa. NÃ£o Ã© possÃ­vel alterar a palavra-chave.
-  notice_account_lost_email_sent: Foi-lhe enviado um e-mail com as instruÃ§Ãµes para escolher uma nova palavra-chave.
-  notice_account_activated: A sua conta foi activada. Ã‰ agora possÃ­vel autenticar-se.
-  notice_successful_create: Criado com sucesso.
-  notice_successful_update: Alterado com sucesso.
-  notice_successful_delete: Apagado com sucesso.
-  notice_successful_connection: Ligado com sucesso.
-  notice_file_not_found: A pÃ¡gina que estÃ¡ a tentar aceder nÃ£o existe ou foi removida.
-  notice_locking_conflict: Os dados foram actualizados por outro utilizador.
-  notice_not_authorized: NÃ£o estÃ¡ autorizado a visualizar esta pÃ¡gina.
-  notice_email_sent: "Foi enviado um e-mail para %{value}"
-  notice_email_error: "Ocorreu um erro ao enviar o e-mail (%{value})"
-  notice_feeds_access_key_reseted: A sua chave de RSS foi inicializada.
-  notice_failed_to_save_issues: "NÃ£o foi possÃ­vel guardar %{count} tarefa(s) das %{total} seleccionadas: %{ids}."
-  notice_no_issue_selected: "Nenhuma tarefa seleccionada! Por favor, seleccione as tarefas que quer editar."
-  notice_account_pending: "A sua conta foi criada e estÃ¡ agora Ã  espera de aprovaÃ§Ã£o do administrador."
-  notice_default_data_loaded: ConfiguraÃ§Ã£o padrÃ£o carregada com sucesso.
-  notice_unable_delete_version: NÃ£o foi possÃ­vel apagar a versÃ£o.
-
-  error_can_t_load_default_data: "NÃ£o foi possÃ­vel carregar a configuraÃ§Ã£o padrÃ£o: %{value}"
-  error_scm_not_found: "A entrada ou revisÃ£o nÃ£o foi encontrada no repositÃ³rio."
-  error_scm_command_failed: "Ocorreu um erro ao tentar aceder ao repositÃ³rio: %{value}"
-  error_scm_annotate: "A entrada nÃ£o existe ou nÃ£o pode ser anotada."
-  error_issue_not_found_in_project: 'A tarefa nÃ£o foi encontrada ou nÃ£o pertence a este projecto.'
-
-  mail_subject_lost_password: "Palavra-chave de %{value}"
-  mail_body_lost_password: 'Para mudar a sua palavra-chave, clique na ligaÃ§Ã£o abaixo:'
-  mail_subject_register: "ActivaÃ§Ã£o de conta de %{value}"
-  mail_body_register: 'Para activar a sua conta, clique na ligaÃ§Ã£o abaixo:'
-  mail_body_account_information_external: "Pode utilizar a conta %{value} para autenticar-se."
-  mail_body_account_information: InformaÃ§Ã£o da sua conta
-  mail_subject_account_activation_request: "Pedido de activaÃ§Ã£o da conta %{value}"
-  mail_body_account_activation_request: "Um novo utilizador (%{value}) registou-se. A sua conta estÃ¡ Ã  espera de aprovaÃ§Ã£o:"
-  mail_subject_reminder: "%{count} tarefa(s) para entregar nos prÃ³ximos %{days} dias"
-  mail_body_reminder: "%{count} tarefa(s) que estÃ£o atribuÃ­das a si estÃ£o agendadas para estarem completas nos prÃ³ximos %{days} dias:"
-
-  gui_validation_error: 1 erro
-  gui_validation_error_plural: "%{count} erros"
-
-  field_name: Nome
-  field_description: DescriÃ§Ã£o
-  field_summary: SumÃ¡rio
-  field_is_required: ObrigatÃ³rio
-  field_firstname: Nome
-  field_lastname: Apelido
-  field_mail: E-mail
-  field_filename: Ficheiro
-  field_filesize: Tamanho
-  field_downloads: Downloads
-  field_author: Autor
-  field_created_on: Criado
-  field_updated_on: Alterado
-  field_field_format: Formato
-  field_is_for_all: Para todos os projectos
-  field_possible_values: Valores possÃ­veis
-  field_regexp: ExpressÃ£o regular
-  field_min_length: Tamanho mÃ­nimo
-  field_max_length: Tamanho mÃ¡ximo
-  field_value: Valor
-  field_category: Categoria
-  field_title: TÃ­tulo
-  field_project: Projecto
-  field_issue: Tarefa
-  field_status: Estado
-  field_notes: Notas
-  field_is_closed: Tarefa fechada
-  field_is_default: Valor por omissÃ£o
-  field_tracker: Tipo
-  field_subject: Assunto
-  field_due_date: Data fim
-  field_assigned_to: AtribuÃ­do a
-  field_priority: Prioridade
-  field_fixed_version: VersÃ£o
-  field_user: Utilizador
-  field_role: FunÃ§Ã£o
-  field_homepage: PÃ¡gina
-  field_is_public: PÃºblico
-  field_parent: Sub-projecto de
-  field_is_in_roadmap: Tarefas mostradas no mapa de planificaÃ§Ã£o
-  field_login: Nome de utilizador
-  field_mail_notification: NotificaÃ§Ãµes por e-mail
-  field_admin: Administrador
-  field_last_login_on: Ãšltima visita
-  field_language: LÃ­ngua
-  field_effective_date: Data
-  field_password: Palavra-chave
-  field_new_password: Nova palavra-chave
-  field_password_confirmation: ConfirmaÃ§Ã£o
-  field_version: VersÃ£o
-  field_type: Tipo
-  field_host: Servidor
-  field_port: Porta
-  field_account: Conta
-  field_base_dn: Base DN
-  field_attr_login: Atributo utilizador
-  field_attr_firstname: Atributo nome prÃ³prio
-  field_attr_lastname: Atributo Ãºltimo nome
-  field_attr_mail: Atributo e-mail
-  field_onthefly: CriaÃ§Ã£o imediata de utilizadores
-  field_start_date: Data inÃ­cio
-  field_done_ratio: "% Completo"
-  field_auth_source: Modo de autenticaÃ§Ã£o
-  field_hide_mail: Esconder endereÃ§o de e-mail
-  field_comments: ComentÃ¡rio
-  field_url: URL
-  field_start_page: PÃ¡gina inicial
-  field_subproject: Subprojecto
-  field_hours: Horas
-  field_activity: Actividade
-  field_spent_on: Data
-  field_identifier: Identificador
-  field_is_filter: Usado como filtro
-  field_issue_to: Tarefa relacionada
-  field_delay: Atraso
-  field_assignable: As tarefas podem ser associadas a esta funÃ§Ã£o
-  field_redirect_existing_links: Redireccionar ligaÃ§Ãµes existentes
-  field_estimated_hours: Tempo estimado
-  field_column_names: Colunas
-  field_time_zone: Fuso horÃ¡rio
-  field_searchable: ProcurÃ¡vel
-  field_default_value: Valor por omissÃ£o
-  field_comments_sorting: Mostrar comentÃ¡rios
-  field_parent_title: PÃ¡gina pai
-
-  setting_app_title: TÃ­tulo da aplicaÃ§Ã£o
-  setting_app_subtitle: Sub-tÃ­tulo da aplicaÃ§Ã£o
-  setting_welcome_text: Texto de boas vindas
-  setting_default_language: LÃ­ngua por omissÃ£o
-  setting_login_required: AutenticaÃ§Ã£o obrigatÃ³ria
-  setting_self_registration: Auto-registo
-  setting_attachment_max_size: Tamanho mÃ¡ximo do anexo
-  setting_issues_export_limit: Limite de exportaÃ§Ã£o das tarefas
-  setting_mail_from: E-mail enviado de
-  setting_bcc_recipients: Recipientes de BCC
-  setting_host_name: Hostname
-  setting_text_formatting: FormataÃ§Ã£o do texto
-  setting_wiki_compression: CompressÃ£o do histÃ³rico do Wiki
-  setting_feeds_limit: Limite de conteÃºdo do feed
-  setting_default_projects_public: Projectos novos sÃ£o pÃºblicos por omissÃ£o
-  setting_autofetch_changesets: Buscar automaticamente commits
-  setting_sys_api_enabled: Activar Web Service para gestÃ£o do repositÃ³rio
-  setting_commit_ref_keywords: Palavras-chave de referÃªncia
-  setting_commit_fix_keywords: Palavras-chave de fecho
-  setting_autologin: Login automÃ¡tico
-  setting_date_format: Formato da data
-  setting_time_format: Formato do tempo
-  setting_cross_project_issue_relations: Permitir relaÃ§Ãµes entre tarefas de projectos diferentes
-  setting_issue_list_default_columns: Colunas na lista de tarefas por omissÃ£o
-  setting_emails_footer: RodapÃ© do e-mails
-  setting_protocol: Protocolo
-  setting_per_page_options: OpÃ§Ãµes de objectos por pÃ¡gina
-  setting_user_format: Formato de apresentaÃ£o de utilizadores
-  setting_activity_days_default: Dias mostrados na actividade do projecto
-  setting_display_subprojects_issues: Mostrar as tarefas dos sub-projectos nos projectos principais
-  setting_enabled_scm: Activar SCM
-  setting_mail_handler_api_enabled: Activar Web Service para e-mails recebidos
-  setting_mail_handler_api_key: Chave da API
-  setting_sequential_project_identifiers: Gerar identificadores de projecto sequÃªnciais
-
-  project_module_issue_tracking: Tarefas
-  project_module_time_tracking: Registo de tempo
-  project_module_news: NotÃ­cias
-  project_module_documents: Documentos
-  project_module_files: Ficheiros
-  project_module_wiki: Wiki
-  project_module_repository: RepositÃ³rio
-  project_module_boards: Forum
-
-  label_user: Utilizador
-  label_user_plural: Utilizadores
-  label_user_new: Novo utilizador
-  label_project: Projecto
-  label_project_new: Novo projecto
-  label_project_plural: Projectos
-  label_x_projects:
-    zero:  no projects
-    one:   1 project
-    other: "%{count} projects"
-  label_project_all: Todos os projectos
-  label_project_latest: Ãšltimos projectos
-  label_issue: Tarefa
-  label_issue_new: Nova tarefa
-  label_issue_plural: Tarefas
-  label_issue_view_all: Ver todas as tarefas
-  label_issues_by: "Tarefas por %{value}"
-  label_issue_added: Tarefa adicionada
-  label_issue_updated: Tarefa actualizada
-  label_document: Documento
-  label_document_new: Novo documento
-  label_document_plural: Documentos
-  label_document_added: Documento adicionado
-  label_role: FunÃ§Ã£o
-  label_role_plural: FunÃ§Ãµes
-  label_role_new: Nova funÃ§Ã£o
-  label_role_and_permissions: FunÃ§Ãµes e permissÃµes
-  label_member: Membro
-  label_member_new: Novo membro
-  label_member_plural: Membros
-  label_tracker: Tipo
-  label_tracker_plural: Tipos
-  label_tracker_new: Novo tipo
-  label_workflow: Fluxo de trabalho
-  label_issue_status: Estado da tarefa
-  label_issue_status_plural: Estados da tarefa
-  label_issue_status_new: Novo estado
-  label_issue_category: Categoria de tarefa
-  label_issue_category_plural: Categorias de tarefa
-  label_issue_category_new: Nova categoria
-  label_custom_field: Campo personalizado
-  label_custom_field_plural: Campos personalizados
-  label_custom_field_new: Novo campo personalizado
-  label_enumerations: EnumeraÃ§Ãµes
-  label_enumeration_new: Novo valor
-  label_information: InformaÃ§Ã£o
-  label_information_plural: InformaÃ§Ãµes
-  label_please_login: Por favor autentique-se
-  label_register: Registar
-  label_password_lost: Perdi a palavra-chave
-  label_home: PÃ¡gina Inicial
-  label_my_page: PÃ¡gina Pessoal
-  label_my_account: Minha conta
-  label_my_projects: Meus projectos
-  label_administration: AdministraÃ§Ã£o
-  label_login: Entrar
-  label_logout: Sair
-  label_help: Ajuda
-  label_reported_issues: Tarefas criadas
-  label_assigned_to_me_issues: Tarefas atribuÃ­das a mim
-  label_last_login: Ãšltimo acesso
-  label_registered_on: Registado em
-  label_activity: Actividade
-  label_overall_activity: Actividade geral
-  label_new: Novo
-  label_logged_as: Ligado como
-  label_environment: Ambiente
-  label_authentication: AutenticaÃ§Ã£o
-  label_auth_source: Modo de autenticaÃ§Ã£o
-  label_auth_source_new: Novo modo de autenticaÃ§Ã£o
-  label_auth_source_plural: Modos de autenticaÃ§Ã£o
-  label_subproject_plural: Sub-projectos
-  label_and_its_subprojects: "%{value} e sub-projectos"
-  label_min_max_length: Tamanho mÃ­nimo-mÃ¡ximo
-  label_list: Lista
-  label_date: Data
-  label_integer: Inteiro
-  label_float: Decimal
-  label_boolean: Booleano
-  label_string: Texto
-  label_text: Texto longo
-  label_attribute: Atributo
-  label_attribute_plural: Atributos
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
-  label_no_data: Sem dados para mostrar
-  label_change_status: Mudar estado
-  label_history: HistÃ³rico
-  label_attachment: Ficheiro
-  label_attachment_new: Novo ficheiro
-  label_attachment_delete: Apagar ficheiro
-  label_attachment_plural: Ficheiros
-  label_file_added: Ficheiro adicionado
-  label_report: RelatÃ³rio
-  label_report_plural: RelatÃ³rios
-  label_news: NotÃ­cia
-  label_news_new: Nova notÃ­cia
-  label_news_plural: NotÃ­cias
-  label_news_latest: Ãšltimas notÃ­cias
-  label_news_view_all: Ver todas as notÃ­cias
-  label_news_added: NotÃ­cia adicionada
-  label_settings: ConfiguraÃ§Ãµes
-  label_overview: VisÃ£o geral
-  label_version: VersÃ£o
-  label_version_new: Nova versÃ£o
-  label_version_plural: VersÃµes
-  label_confirmation: ConfirmaÃ§Ã£o
-  label_export_to: 'TambÃ©m disponÃ­vel em:'
-  label_read: Ler...
-  label_public_projects: Projectos pÃºblicos
-  label_open_issues: aberto
-  label_open_issues_plural: abertos
-  label_closed_issues: fechado
-  label_closed_issues_plural: fechados
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_total: Total
-  label_permissions: PermissÃµes
-  label_current_status: Estado actual
-  label_new_statuses_allowed: Novos estados permitidos
-  label_all: todos
-  label_none: nenhum
-  label_nobody: ninguÃ©m
-  label_next: PrÃ³ximo
-  label_previous: Anterior
-  label_used_by: Usado por
-  label_details: Detalhes
-  label_add_note: Adicionar nota
-  label_per_page: Por pÃ¡gina
-  label_calendar: CalendÃ¡rio
-  label_months_from: meses de
-  label_gantt: Gantt
-  label_internal: Interno
-  label_last_changes: "Ãºltimas %{count} alteraÃ§Ãµes"
-  label_change_view_all: Ver todas as alteraÃ§Ãµes
-  label_personalize_page: Personalizar esta pÃ¡gina
-  label_comment: ComentÃ¡rio
-  label_comment_plural: ComentÃ¡rios
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_comment_add: Adicionar comentÃ¡rio
-  label_comment_added: ComentÃ¡rio adicionado
-  label_comment_delete: Apagar comentÃ¡rios
-  label_query: Consulta personalizada
-  label_query_plural: Consultas personalizadas
-  label_query_new: Nova consulta
-  label_filter_add: Adicionar filtro
-  label_filter_plural: Filtros
-  label_equals: Ã©
-  label_not_equals: nÃ£o Ã©
-  label_in_less_than: em menos de
-  label_in_more_than: em mais de
-  label_in: em
-  label_today: hoje
-  label_all_time: sempre
-  label_yesterday: ontem
-  label_this_week: esta semana
-  label_last_week: semana passada
-  label_last_n_days: "Ãºltimos %{count} dias"
-  label_this_month: este mÃªs
-  label_last_month: mÃªs passado
-  label_this_year: este ano
-  label_date_range: Date range
-  label_less_than_ago: menos de dias atrÃ¡s
-  label_more_than_ago: mais de dias atrÃ¡s
-  label_ago: dias atrÃ¡s
-  label_contains: contÃ©m
-  label_not_contains: nÃ£o contÃ©m
-  label_day_plural: dias
-  label_repository: RepositÃ³rio
-  label_repository_plural: RepositÃ³rios
-  label_browse: Navegar
-  label_modification: "%{count} alteraÃ§Ã£o"
-  label_modification_plural: "%{count} alteraÃ§Ãµes"
-  label_revision: RevisÃ£o
-  label_revision_plural: RevisÃµes
-  label_associated_revisions: RevisÃµes associadas
-  label_added: adicionado
-  label_modified: modificado
-  label_copied: copiado
-  label_renamed: renomeado
-  label_deleted: apagado
-  label_latest_revision: Ãšltima revisÃ£o
-  label_latest_revision_plural: Ãšltimas revisÃµes
-  label_view_revisions: Ver revisÃµes
-  label_max_size: Tamanho mÃ¡ximo
-  label_sort_highest: Mover para o inÃ­cio
-  label_sort_higher: Mover para cima
-  label_sort_lower: Mover para baixo
-  label_sort_lowest: Mover para o fim
-  label_roadmap: PlanificaÃ§Ã£o
-  label_roadmap_due_in: "Termina em %{value}"
-  label_roadmap_overdue: "Atrasado %{value}"
-  label_roadmap_no_issues: Sem tarefas para esta versÃ£o
-  label_search: Procurar
-  label_result_plural: Resultados
-  label_all_words: Todas as palavras
-  label_wiki: Wiki
-  label_wiki_edit: EdiÃ§Ã£o da Wiki
-  label_wiki_edit_plural: EdiÃ§Ãµes da Wiki
-  label_wiki_page: PÃ¡gina da Wiki
-  label_wiki_page_plural: PÃ¡ginas da Wiki
-  label_index_by_title: Ãndice por tÃ­tulo
-  label_index_by_date: Ãndice por data
-  label_current_version: VersÃ£o actual
-  label_preview: PrÃ©-visualizar
-  label_feed_plural: Feeds
-  label_changes_details: Detalhes de todas as mudanÃ§as
-  label_issue_tracking: Tarefas
-  label_spent_time: Tempo gasto
-  label_f_hour: "%{value} hora"
-  label_f_hour_plural: "%{value} horas"
-  label_time_tracking: Registo de tempo
-  label_change_plural: MudanÃ§as
-  label_statistics: EstatÃ­sticas
-  label_commits_per_month: Commits por mÃªs
-  label_commits_per_author: Commits por autor
-  label_view_diff: Ver diferenÃ§as
-  label_diff_inline: inline
-  label_diff_side_by_side: lado a lado
-  label_options: OpÃ§Ãµes
-  label_copy_workflow_from: Copiar fluxo de trabalho de
-  label_permissions_report: RelatÃ³rio de permissÃµes
-  label_watched_issues: Tarefas observadas
-  label_related_issues: Tarefas relacionadas
-  label_applied_status: Estado aplicado
-  label_loading: A carregar...
-  label_relation_new: Nova relaÃ§Ã£o
-  label_relation_delete: Apagar relaÃ§Ã£o
-  label_relates_to: relacionado a
-  label_duplicates: duplica
-  label_duplicated_by: duplicado por
-  label_blocks: bloqueia
-  label_blocked_by: bloqueado por
-  label_precedes: precede
-  label_follows: segue
-  label_end_to_start: fim a inÃ­cio
-  label_end_to_end: fim a fim
-  label_start_to_start: inÃ­cio a inÃ­cio
-  label_start_to_end: inÃ­cio a fim
-  label_stay_logged_in: Guardar sessÃ£o
-  label_disabled: desactivado
-  label_show_completed_versions: Mostrar versÃµes acabadas
-  label_me: eu
-  label_board: Forum
-  label_board_new: Novo forum
-  label_board_plural: Forums
-  label_topic_plural: TÃ³picos
-  label_message_plural: Mensagens
-  label_message_last: Ãšltima mensagem
-  label_message_new: Nova mensagem
-  label_message_posted: Mensagem adicionada
-  label_reply_plural: Respostas
-  label_send_information: Enviar dados da conta para o utilizador
-  label_year: Ano
-  label_month: mÃªs
-  label_week: Semana
-  label_date_from: De
-  label_date_to: Para
-  label_language_based: Baseado na lÃ­ngua do utilizador
-  label_sort_by: "Ordenar por %{value}"
-  label_send_test_email: enviar um e-mail de teste
-  label_feeds_access_key_created_on: "Chave RSS criada hÃ¡ %{value} atrÃ¡s"
-  label_module_plural: MÃ³dulos
-  label_added_time_by: "Adicionado por %{author} hÃ¡ %{age} atrÃ¡s"
-  label_updated_time: "Alterado hÃ¡ %{value} atrÃ¡s"
-  label_jump_to_a_project: Ir para o projecto...
-  label_file_plural: Ficheiros
-  label_changeset_plural: Changesets
-  label_default_columns: Colunas por omissÃ£o
-  label_no_change_option: (sem alteraÃ§Ã£o)
-  label_bulk_edit_selected_issues: Editar tarefas seleccionadas em conjunto
-  label_theme: Tema
-  label_default: PadrÃ£o
-  label_search_titles_only: Procurar apenas em tÃ­tulos
-  label_user_mail_option_all: "Para qualquer evento em todos os meus projectos"
-  label_user_mail_option_selected: "Para qualquer evento apenas nos projectos seleccionados..."
-  label_user_mail_no_self_notified: "NÃ£o quero ser notificado de alteraÃ§Ãµes feitas por mim"
-  label_registration_activation_by_email: ActivaÃ§Ã£o da conta por e-mail
-  label_registration_manual_activation: ActivaÃ§Ã£o manual da conta
-  label_registration_automatic_activation: ActivaÃ§Ã£o automÃ¡tica da conta
-  label_display_per_page: "Por pÃ¡gina: %{value}"
-  label_age: Idade
-  label_change_properties: Mudar propriedades
-  label_general: Geral
-  label_more: Mais
-  label_scm: SCM
-  label_plugins: ExtensÃµes
-  label_ldap_authentication: AutenticaÃ§Ã£o LDAP
-  label_downloads_abbr: D/L
-  label_optional_description: DescriÃ§Ã£o opcional
-  label_add_another_file: Adicionar outro ficheiro
-  label_preferences: PreferÃªncias
-  label_chronological_order: Em ordem cronolÃ³gica
-  label_reverse_chronological_order: Em ordem cronolÃ³gica inversa
-  label_planning: Planeamento
-  label_incoming_emails: E-mails a chegar
-  label_generate_key: Gerar uma chave
-  label_issue_watchers: Observadores
-
-  button_login: Entrar
-  button_submit: Submeter
-  button_save: Guardar
-  button_check_all: Marcar tudo
-  button_uncheck_all: Desmarcar tudo
-  button_delete: Apagar
-  button_create: Criar
-  button_test: Testar
-  button_edit: Editar
-  button_add: Adicionar
-  button_change: Alterar
-  button_apply: Aplicar
-  button_clear: Limpar
-  button_lock: Bloquear
-  button_unlock: Desbloquear
-  button_download: Download
-  button_list: Listar
-  button_view: Ver
-  button_move: Mover
-  button_back: Voltar
-  button_cancel: Cancelar
-  button_activate: Activar
-  button_sort: Ordenar
-  button_log_time: Tempo de trabalho
-  button_rollback: Voltar para esta versÃ£o
-  button_watch: Observar
-  button_unwatch: Deixar de observar
-  button_reply: Responder
-  button_archive: Arquivar
-  button_unarchive: Desarquivar
-  button_reset: Reinicializar
-  button_rename: Renomear
-  button_change_password: Mudar palavra-chave
-  button_copy: Copiar
-  button_annotate: Anotar
-  button_update: Actualizar
-  button_configure: Configurar
-  button_quote: Citar
-
-  status_active: activo
-  status_registered: registado
-  status_locked: bloqueado
-
-  text_select_mail_notifications: Seleccionar as acÃ§Ãµes que originam uma notificaÃ§Ã£o por e-mail.
-  text_regexp_info: ex. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 siginifica sem restriÃ§Ã£o
-  text_project_destroy_confirmation: Tem a certeza que deseja apagar o projecto e todos os dados relacionados?
-  text_subprojects_destroy_warning: "O(s) seu(s) sub-projecto(s): %{value} tambÃ©m serÃ¡/serÃ£o apagado(s)."
-  text_workflow_edit: Seleccione uma funÃ§Ã£o e um tipo de tarefa para editar o fluxo de trabalho
-  text_are_you_sure: Tem a certeza?
-  text_tip_issue_begin_day: tarefa a comeÃ§ar neste dia
-  text_tip_issue_end_day: tarefa a acabar neste dia
-  text_tip_issue_begin_end_day: tarefa a comeÃ§ar e acabar neste dia
-  text_project_identifier_info: 'Apenas sÃ£o permitidos letras minÃºsculas (a-z), nÃºmeros e hÃ­fens.<br />Uma vez guardado, o identificador nÃ£o poderÃ¡ ser alterado.'
-  text_caracters_maximum: "mÃ¡ximo %{count} caracteres."
-  text_caracters_minimum: "Deve ter pelo menos %{count} caracteres."
-  text_length_between: "Deve ter entre %{min} e %{max} caracteres."
-  text_tracker_no_workflow: Sem fluxo de trabalho definido para este tipo de tarefa.
-  text_unallowed_characters: Caracteres nÃ£o permitidos
-  text_comma_separated: Permitidos mÃºltiplos valores (separados por vÃ­rgula).
-  text_issues_ref_in_commit_messages: Referenciando e fechando tarefas em mensagens de commit
-  text_issue_added: "Tarefa %{id} foi criada por %{author}."
-  text_issue_updated: "Tarefa %{id} foi actualizada por %{author}."
-  text_wiki_destroy_confirmation: Tem a certeza que deseja apagar este wiki e todo o seu conteÃºdo?
-  text_issue_category_destroy_question: "Algumas tarefas (%{count}) estÃ£o atribuÃ­das a esta categoria. O que quer fazer?"
-  text_issue_category_destroy_assignments: Remover as atribuiÃ§Ãµes Ã  categoria
-  text_issue_category_reassign_to: Re-atribuir as tarefas para esta categoria
-  text_user_mail_option: "Para projectos nÃ£o seleccionados, apenas receberÃ¡ notificaÃ§Ãµes acerca de coisas que estÃ¡ a observar ou estÃ¡ envolvido (ex. tarefas das quais foi o criador ou lhes foram atribuÃ­das)."
-  text_no_configuration_data: "Perfis, tipos de tarefas, estados das tarefas e workflows ainda nÃ£o foram configurados.\nÃ‰ extremamente recomendado carregar as configuraÃ§Ãµes padrÃ£o. SerÃ¡ capaz de as modificar depois de estarem carregadas."
-  text_load_default_configuration: Carregar as configuraÃ§Ãµes padrÃ£o
-  text_status_changed_by_changeset: "Aplicado no changeset %{value}."
-  text_issues_destroy_confirmation: 'Tem a certeza que deseja apagar a(s) tarefa(s) seleccionada(s)?'
-  text_select_project_modules: 'Seleccione os mÃ³dulos a activar para este projecto:'
-  text_default_administrator_account_changed: Conta default de administrador alterada.
-  text_file_repository_writable: RepositÃ³rio de ficheiros com permissÃµes de escrita
-  text_rmagick_available: RMagick disponÃ­vel (opcional)
-  text_destroy_time_entries_question: "%{hours} horas de trabalho foram atribuÃ­das a estas tarefas que vai apagar. O que deseja fazer?"
-  text_destroy_time_entries: Apagar as horas
-  text_assign_time_entries_to_project: Atribuir as horas ao projecto
-  text_reassign_time_entries: 'Re-atribuir as horas para esta tarefa:'
-  text_user_wrote: "%{value} escreveu:"
-  text_enumeration_destroy_question: "%{count} objectos estÃ£o atribuÃ­dos a este valor."
-  text_enumeration_category_reassign_to: 'Re-atribuÃ­-los para este valor:'
-  text_email_delivery_not_configured: "Entrega por e-mail nÃ£o estÃ¡ configurada, e as notificaÃ§Ã£o estÃ£o desactivadas.\nConfigure o seu servidor de SMTP em config/configuration.yml e reinicie a aplicaÃ§Ã£o para activar estas funcionalidades."
-
-  default_role_manager: Gestor
-  default_role_developer: Programador
-  default_role_reporter: RepÃ³rter
-  default_tracker_bug: Bug
-  default_tracker_feature: Funcionalidade
-  default_tracker_support: Suporte
-  default_issue_status_new: Novo
-  default_issue_status_in_progress: Em curso
-  default_issue_status_resolved: Resolvido
-  default_issue_status_feedback: Feedback
-  default_issue_status_closed: Fechado
-  default_issue_status_rejected: Rejeitado
-  default_doc_category_user: DocumentaÃ§Ã£o de utilizador
-  default_doc_category_tech: DocumentaÃ§Ã£o tÃ©cnica
-  default_priority_low: Baixa
-  default_priority_normal: Normal
-  default_priority_high: Alta
-  default_priority_urgent: Urgente
-  default_priority_immediate: Imediata
-  default_activity_design: Planeamento
-  default_activity_development: Desenvolvimento
-
-  enumeration_issue_priorities: Prioridade de tarefas
-  enumeration_doc_categories: Categorias de documentos
-  enumeration_activities: Actividades (Registo de tempo)
-  setting_plain_text_mail: Apenas texto simples (sem HTML)
-  permission_view_files: Ver ficheiros
-  permission_edit_issues: Editar tarefas
-  permission_edit_own_time_entries: Editar horas pessoais
-  permission_manage_public_queries: Gerir queries pÃºblicas
-  permission_add_issues: Adicionar tarefas
-  permission_log_time: Registar tempo gasto
-  permission_view_changesets: Ver changesets
-  permission_view_time_entries: Ver tempo gasto
-  permission_manage_versions: Gerir versÃµes
-  permission_manage_wiki: Gerir wiki
-  permission_manage_categories: Gerir categorias de tarefas
-  permission_protect_wiki_pages: Proteger pÃ¡ginas de wiki
-  permission_comment_news: Comentar notÃ­cias
-  permission_delete_messages: Apagar mensagens
-  permission_select_project_modules: Seleccionar mÃ³dulos do projecto
-  permission_manage_documents: Gerir documentos
-  permission_edit_wiki_pages: Editar pÃ¡ginas de wiki
-  permission_add_issue_watchers: Adicionar observadores
-  permission_view_gantt: ver diagrama de Gantt
-  permission_move_issues: Mover tarefas
-  permission_manage_issue_relations: Gerir relaÃ§Ãµes de tarefas
-  permission_delete_wiki_pages: Apagar pÃ¡ginas de wiki
-  permission_manage_boards: Gerir forums
-  permission_delete_wiki_pages_attachments: Apagar anexos
-  permission_view_wiki_edits: Ver histÃ³rico da wiki
-  permission_add_messages: Submeter mensagens
-  permission_view_messages: Ver mensagens
-  permission_manage_files: Gerir ficheiros
-  permission_edit_issue_notes: Editar notas de tarefas
-  permission_manage_news: Gerir notÃ­cias
-  permission_view_calendar: Ver calendÃ¡rio
-  permission_manage_members: Gerir membros
-  permission_edit_messages: Editar mensagens
-  permission_delete_issues: Apagar tarefas
-  permission_view_issue_watchers: Ver lista de observadores
-  permission_manage_repository: Gerir repositÃ³rio
-  permission_commit_access: Acesso a submissÃ£o
-  permission_browse_repository: Navegar em repositÃ³rio
-  permission_view_documents: Ver documentos
-  permission_edit_project: Editar projecto
-  permission_add_issue_notes: Adicionar notas a tarefas
-  permission_save_queries: Guardar queries
-  permission_view_wiki_pages: Ver wiki
-  permission_rename_wiki_pages: Renomear pÃ¡ginas de wiki
-  permission_edit_time_entries: Editar entradas de tempo
-  permission_edit_own_issue_notes: Editar as prÃ³rpias notas
-  setting_gravatar_enabled: Utilizar Ã­cones Gravatar
-  label_example: Exemplo
-  text_repository_usernames_mapping: "Seleccionar ou actualizar o utilizador de Redmine mapeado a cada nome de utilizador encontrado no repositÃ³rio.\nUtilizadores com o mesmo nome de utilizador ou email no Redmine e no repositÃ³rio sÃ£o mapeados automaticamente."
-  permission_edit_own_messages: Editar as prÃ³prias mensagens
-  permission_delete_own_messages: Apagar as prÃ³prias mensagens
-  label_user_activity: "Actividade de %{value}"
-  label_updated_time_by: "Actualizado por %{author} hÃ¡ %{age}"
-  text_diff_truncated: '... Este diff foi truncado porque excede o tamanho mÃ¡ximo que pode ser mostrado.'
-  setting_diff_max_lines_displayed: NÃºmero mÃ¡ximo de linhas de diff mostradas
-  text_plugin_assets_writable: Escrita na pasta de activos dos mÃ³dulos de extensÃ£o possÃ­vel
-  warning_attachments_not_saved: "NÃ£o foi possÃ­vel gravar %{count} ficheiro(s) ."
-  button_create_and_continue: Criar e continuar
-  text_custom_field_possible_values_info: 'Uma linha para cada valor'
-  label_display: Mostrar
-  field_editable: EditÃ¡vel
-  setting_repository_log_display_limit: NÃºmero mÃ¡ximo de revisÃµes exibido no relatÃ³rio de ficheiro
-  setting_file_max_size_displayed: Tamanho mÃ¡ximo dos ficheiros de texto exibidos inline
-  field_watcher: Observador
-  setting_openid: Permitir inÃ­cio de sessÃ£o e registo com OpenID
-  field_identity_url: URL do OpenID
-  label_login_with_open_id_option: ou inÃ­cio de sessÃ£o com OpenID
-  field_content: ConteÃºdo
-  label_descending: Descendente
-  label_sort: Ordenar
-  label_ascending: Ascendente
-  label_date_from_to: De %{start} a %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: Esta pÃ¡gina tem %{descendants} pÃ¡gina(s) subordinada(s) e descendente(s). O que deseja fazer?
-  text_wiki_page_reassign_children: Reatribuir pÃ¡ginas subordinadas a esta pÃ¡gina principal
-  text_wiki_page_nullify_children: Manter pÃ¡ginas subordinadas como pÃ¡ginas raÃ­z
-  text_wiki_page_destroy_children: Apagar as pÃ¡ginas subordinadas e todos os seus descendentes
-  setting_password_min_length: Tamanho mÃ­nimo de palavra-chave
-  field_group_by: Agrupar resultados por
-  mail_subject_wiki_content_updated: "A pÃ¡gina Wiki '%{id}' foi actualizada"
-  label_wiki_content_added: PÃ¡gina Wiki adicionada
-  mail_subject_wiki_content_added: "A pÃ¡gina Wiki '%{id}' foi adicionada"
-  mail_body_wiki_content_added: A pÃ¡gina Wiki '%{id}' foi adicionada por %{author}.
-  label_wiki_content_updated: PÃ¡gina Wiki actualizada
-  mail_body_wiki_content_updated: A pÃ¡gina Wiki '%{id}' foi actualizada por %{author}.
-  permission_add_project: Criar projecto
-  setting_new_project_user_role_id: FunÃ§Ã£o atribuÃ­da a um utilizador nÃ£o-administrador que cria um projecto
-  label_view_all_revisions: Ver todas as revisÃµes
-  label_tag: Etiqueta
-  label_branch: Ramo
-  error_no_tracker_in_project: Este projecto nÃ£o tem associado nenhum tipo de tarefas. Verifique as definiÃ§Ãµes do projecto.
-  error_no_default_issue_status: NÃ£o estÃ¡ definido um estado padrÃ£o para as tarefas. Verifique a sua configuraÃ§Ã£o (dirija-se a "AdministraÃ§Ã£o -> Estados da tarefa").
-  label_group_plural: Grupos
-  label_group: Grupo
-  label_group_new: Novo grupo
-  label_time_entry_plural: Tempo registado
-  text_journal_changed: "%{label} alterado de %{old} para %{new}"
-  text_journal_set_to: "%{label} configurado como %{value}"
-  text_journal_deleted: "%{label} apagou (%{old})"
-  text_journal_added: "%{label} %{value} adicionado"
-  field_active: Activo
-  enumeration_system_activity: Actividade de sistema
-  permission_delete_issue_watchers: Apagar observadores
-  version_status_closed: fechado
-  version_status_locked: protegido
-  version_status_open: aberto
-  error_can_not_reopen_issue_on_closed_version: NÃ£o Ã© possÃ­vel voltar a abrir uma tarefa atribuÃ­da a uma versÃ£o fechada
-  label_user_anonymous: AnÃ³nimo
-  button_move_and_follow: Mover e seguir
-  setting_default_projects_modules: MÃ³dulos activos por predefiniÃ§Ã£o para novos projectos
-  setting_gravatar_default: Imagem Gravatar predefinida
-  field_sharing: Partilha
-  label_version_sharing_hierarchy: Com hierarquia do projecto
-  label_version_sharing_system: Com todos os projectos
-  label_version_sharing_descendants: Com os sub-projectos
-  label_version_sharing_tree: Com Ã¡rvore do projecto
-  label_version_sharing_none: NÃ£o partilhado
-  error_can_not_archive_project: NÃ£o Ã© possÃ­vel arquivar este projecto
-  button_duplicate: Duplicar
-  button_copy_and_follow: Copiar e seguir
-  label_copy_source: Origem
-  setting_issue_done_ratio: Calcular a percentagem de progresso da tarefa
-  setting_issue_done_ratio_issue_status: AtravÃ©s do estado da tarefa
-  error_issue_done_ratios_not_updated: Percentagens de progresso da tarefa nÃ£o foram actualizadas.
-  error_workflow_copy_target: Seleccione os tipos de tarefas e funÃ§Ãµes desejadas
-  setting_issue_done_ratio_issue_field: AtravÃ©s do campo da tarefa
-  label_copy_same_as_target: Mesmo que o alvo
-  label_copy_target: Alvo
-  notice_issue_done_ratios_updated: Percentagens de progresso da tarefa actualizadas.
-  error_workflow_copy_source: Seleccione um tipo de tarefa ou funÃ§Ã£o de origem
-  label_update_issue_done_ratios: Actualizar percentagens de progresso da tarefa
-  setting_start_of_week: Iniciar calendÃ¡rios a
-  permission_view_issues: Ver tarefas
-  label_display_used_statuses_only: SÃ³ exibir estados empregues por este tipo de tarefa
-  label_revision_id: RevisÃ£o %{value}
-  label_api_access_key: Chave de acesso API
-  label_api_access_key_created_on: Chave de acesso API criada hÃ¡ %{value}
-  label_feeds_access_key: Chave de acesso RSS
-  notice_api_access_key_reseted: A sua chave de acesso API foi reinicializada.
-  setting_rest_api_enabled: Activar serviÃ§o Web REST
-  label_missing_api_access_key: Chave de acesso API em falta
-  label_missing_feeds_access_key: Chave de acesso RSS em falta
-  button_show: Mostrar
-  text_line_separated: VÃ¡rios valores permitidos (uma linha para cada valor).
-  setting_mail_handler_body_delimiters: Truncar mensagens de correio electrÃ³nico apÃ³s uma destas linhas
-  permission_add_subprojects: Criar sub-projectos
-  label_subproject_new: Novo sub-projecto
-  text_own_membership_delete_confirmation: |-
-    EstÃ¡ prestes a eliminar parcial ou totalmente as suas permissÃµes. Ã‰ possÃ­vel que nÃ£o possa editar o projecto apÃ³s esta acÃ§Ã£o.
-    Tem a certeza de que deseja continuar?
-  label_close_versions: Fechar versÃµes completas
-  label_board_sticky: Fixar mensagem
-  label_board_locked: Proteger
-  permission_export_wiki_pages: Exportar pÃ¡ginas Wiki
-  setting_cache_formatted_text: Colocar formataÃ§Ã£o do texto na memÃ³ria cache
-  permission_manage_project_activities: Gerir actividades do projecto
-  error_unable_delete_issue_status: NÃ£o foi possÃ­vel apagar o estado da tarefa
-  label_profile: Perfil
-  permission_manage_subtasks: Gerir sub-tarefas
-  field_parent_issue: Tarefa principal
-  label_subtask_plural: Sub-tarefa
-  label_project_copy_notifications: Enviar notificaÃ§Ãµes por e-mail durante a cÃ³pia do projecto
-  error_can_not_delete_custom_field: NÃ£o foi possÃ­vel apagar o campo personalizado
-  error_unable_to_connect: NÃ£o foi possÃ­vel ligar (%{value})
-  error_can_not_remove_role: Esta funÃ§Ã£o estÃ¡ actualmente em uso e nÃ£o pode ser apagada.
-  error_can_not_delete_tracker: Existem ainda tarefas nesta categoria. NÃ£o Ã© possÃ­vel apagar este tipo de tarefa.
-  field_principal: Principal
-  label_my_page_block: Bloco da minha pÃ¡gina
-  notice_failed_to_save_members: "Erro ao guardar o(s) membro(s): %{errors}."
-  text_zoom_out: Ampliar
-  text_zoom_in: Reduzir
-  notice_unable_delete_time_entry: NÃ£o foi possÃ­vel apagar a entrada de tempo registado.
-  label_overall_spent_time: Total de tempo registado
-  field_time_entries: Tempo registado
-  project_module_gantt: Gantt
-  project_module_calendar: CalendÃ¡rio
-  button_edit_associated_wikipage: "Editar pÃ¡gina Wiki associada: %{page_title}"
-  text_are_you_sure_with_children: Apagar tarefa e todas as sub-tarefas?
-  field_text: Campo de texto
-  label_user_mail_option_only_owner: Apenas para tarefas das quais sou proprietÃ¡rio
-  setting_default_notification_option: OpÃ§Ã£o predefinida de notificaÃ§Ã£o
-  label_user_mail_option_only_my_events: Apenas para tarefas que observo ou em que estou envolvido
-  label_user_mail_option_only_assigned: Apenas para tarefas que me foram atribuÃ­das
-  label_user_mail_option_none: Sem eventos
-  field_member_of_group: Grupo do detentor de atribuiÃ§Ã£o
-  field_assigned_to_role: Papel do detentor de atribuiÃ§Ã£o
-  notice_not_authorized_archived_project: O projecto a que tentou aceder foi arquivado.
-  label_principal_search: "Procurar utilizador ou grupo:"
-  label_user_search: "Procurar utilizador:"
-  field_visible: VisÃ­vel
-  setting_emails_header: CabeÃ§alho dos e-mails
-  setting_commit_logtime_activity_id: Actividade para tempo registado
-  text_time_logged_by_changeset: Aplicado no conjunto de alteraÃ§Ãµes %{value}.
-  setting_commit_logtime_enabled: Activar registo de tempo
-  notice_gantt_chart_truncated: O grÃ¡fico foi truncado porque excede o nÃºmero mÃ¡ximo de itens visÃ­vel (%{mÃ¡x.})
-  setting_gantt_items_limit: NÃºmero mÃ¡ximo de itens exibidos no grÃ¡fico Gantt
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Encoding das mensagens de commit
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4f68d76f852340754bcbaa389f8acdaba7e60be4.svn-base
--- /dev/null
+++ b/.svn/pristine/4f/4f68d76f852340754bcbaa389f8acdaba7e60be4.svn-base
@@ -0,0 +1,217 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ProjectEnumerationsControllerTest < ActionController::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :custom_fields, :custom_fields_projects,
+           :custom_fields_trackers, :custom_values,
+           :time_entries
+
+  self.use_transactional_fixtures = false
+
+  def setup
+    @request.session[:user_id] = nil
+    Setting.default_language = 'en'
+  end
+
+  def test_update_to_override_system_activities
+    @request.session[:user_id] = 2 # manager
+    billable_field = TimeEntryActivityCustomField.find_by_name("Billable")
+
+    put :update, :project_id => 1, :enumerations => {
+      "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design, De-activate
+      "10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"}, # Development, Change custom value
+      "14"=>{"parent_id"=>"14", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"}, # Inactive Activity, Activate with custom value
+      "11"=>{"parent_id"=>"11", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"} # QA, no changes
+    }
+
+    assert_response :redirect
+    assert_redirected_to '/projects/ecookbook/settings/activities'
+
+    # Created project specific activities...
+    project = Project.find('ecookbook')
+
+    # ... Design
+    design = project.time_entry_activities.find_by_name("Design")
+    assert design, "Project activity not found"
+
+    assert_equal 9, design.parent_id # Relate to the system activity
+    assert_not_equal design.parent.id, design.id # Different records
+    assert_equal design.parent.name, design.name # Same name
+    assert !design.active?
+
+    # ... Development
+    development = project.time_entry_activities.find_by_name("Development")
+    assert development, "Project activity not found"
+
+    assert_equal 10, development.parent_id # Relate to the system activity
+    assert_not_equal development.parent.id, development.id # Different records
+    assert_equal development.parent.name, development.name # Same name
+    assert development.active?
+    assert_equal "0", development.custom_value_for(billable_field).value
+
+    # ... Inactive Activity
+    previously_inactive = project.time_entry_activities.find_by_name("Inactive Activity")
+    assert previously_inactive, "Project activity not found"
+
+    assert_equal 14, previously_inactive.parent_id # Relate to the system activity
+    assert_not_equal previously_inactive.parent.id, previously_inactive.id # Different records
+    assert_equal previously_inactive.parent.name, previously_inactive.name # Same name
+    assert previously_inactive.active?
+    assert_equal "1", previously_inactive.custom_value_for(billable_field).value
+
+    # ... QA
+    assert_equal nil, project.time_entry_activities.find_by_name("QA"), "Custom QA activity created when it wasn't modified"
+  end
+
+  def test_update_will_update_project_specific_activities
+    @request.session[:user_id] = 2 # manager
+
+    project_activity = TimeEntryActivity.new({
+                                               :name => 'Project Specific',
+                                               :parent => TimeEntryActivity.first,
+                                               :project => Project.find(1),
+                                               :active => true
+                                             })
+    assert project_activity.save
+    project_activity_two = TimeEntryActivity.new({
+                                                   :name => 'Project Specific Two',
+                                                   :parent => TimeEntryActivity.last,
+                                                   :project => Project.find(1),
+                                                   :active => true
+                                                 })
+    assert project_activity_two.save
+
+
+    put :update, :project_id => 1, :enumerations => {
+      project_activity.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # De-activate
+      project_activity_two.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"} # De-activate
+    }
+
+    assert_response :redirect
+    assert_redirected_to '/projects/ecookbook/settings/activities'
+
+    # Created project specific activities...
+    project = Project.find('ecookbook')
+    assert_equal 2, project.time_entry_activities.count
+
+    activity_one = project.time_entry_activities.find_by_name(project_activity.name)
+    assert activity_one, "Project activity not found"
+    assert_equal project_activity.id, activity_one.id
+    assert !activity_one.active?
+
+    activity_two = project.time_entry_activities.find_by_name(project_activity_two.name)
+    assert activity_two, "Project activity not found"
+    assert_equal project_activity_two.id, activity_two.id
+    assert !activity_two.active?
+  end
+
+  def test_update_when_creating_new_activities_will_convert_existing_data
+    assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size
+
+    @request.session[:user_id] = 2 # manager
+    put :update, :project_id => 1, :enumerations => {
+      "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"} # Design, De-activate
+    }
+    assert_response :redirect
+
+    # No more TimeEntries using the system activity
+    assert_equal 0, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries still assigned to system activities"
+    # All TimeEntries using project activity
+    project_specific_activity = TimeEntryActivity.find_by_parent_id_and_project_id(9, 1)
+    assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(project_specific_activity.id, 1).size, "No Time Entries assigned to the project activity"
+  end
+
+  def test_update_when_creating_new_activities_will_not_convert_existing_data_if_an_exception_is_raised
+    # TODO: Need to cause an exception on create but these tests
+    # aren't setup for mocking.  Just create a record now so the
+    # second one is a dupicate
+    parent = TimeEntryActivity.find(9)
+    TimeEntryActivity.create!({:name => parent.name, :project_id => 1, :position => parent.position, :active => true})
+    TimeEntry.create!({:project_id => 1, :hours => 1.0, :user => User.find(1), :issue_id => 3, :activity_id => 10, :spent_on => '2009-01-01'})
+
+    assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size
+    assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size
+
+    @request.session[:user_id] = 2 # manager
+    put :update, :project_id => 1, :enumerations => {
+      "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design
+      "10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"} # Development, Change custom value
+    }
+    assert_response :redirect
+
+    # TimeEntries shouldn't have been reassigned on the failed record
+    assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries are not assigned to system activities"
+    # TimeEntries shouldn't have been reassigned on the saved record either
+    assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size, "Time Entries are not assigned to system activities"
+  end
+
+  def test_destroy
+    @request.session[:user_id] = 2 # manager
+    project_activity = TimeEntryActivity.new({
+                                               :name => 'Project Specific',
+                                               :parent => TimeEntryActivity.first,
+                                               :project => Project.find(1),
+                                               :active => true
+                                             })
+    assert project_activity.save
+    project_activity_two = TimeEntryActivity.new({
+                                                   :name => 'Project Specific Two',
+                                                   :parent => TimeEntryActivity.last,
+                                                   :project => Project.find(1),
+                                                   :active => true
+                                                 })
+    assert project_activity_two.save
+
+    delete :destroy, :project_id => 1
+    assert_response :redirect
+    assert_redirected_to '/projects/ecookbook/settings/activities'
+
+    assert_nil TimeEntryActivity.find_by_id(project_activity.id)
+    assert_nil TimeEntryActivity.find_by_id(project_activity_two.id)
+  end
+
+  def test_destroy_should_reassign_time_entries_back_to_the_system_activity
+    @request.session[:user_id] = 2 # manager
+    project_activity = TimeEntryActivity.new({
+                                               :name => 'Project Specific Design',
+                                               :parent => TimeEntryActivity.find(9),
+                                               :project => Project.find(1),
+                                               :active => true
+                                             })
+    assert project_activity.save
+    assert TimeEntry.update_all("activity_id = '#{project_activity.id}'", ["project_id = ? AND activity_id = ?", 1, 9])
+    assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(project_activity.id, 1).size
+
+    delete :destroy, :project_id => 1
+    assert_response :redirect
+    assert_redirected_to '/projects/ecookbook/settings/activities'
+
+    assert_nil TimeEntryActivity.find_by_id(project_activity.id)
+    assert_equal 0, TimeEntry.find_all_by_activity_id_and_project_id(project_activity.id, 1).size, "TimeEntries still assigned to project specific activity"
+    assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "TimeEntries still assigned to project specific activity"
+  end
+
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4f7c43bee38a0086927663fbc7e435338678ebfe.svn-base
--- a/.svn/pristine/4f/4f7c43bee38a0086927663fbc7e435338678ebfe.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-<h2><%=l(:label_version)%></h2>
-
-<% labelled_tabular_form_for @version do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_save) %>
-<% end %>
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4f91e1e0bb038b11d88f8da5ac2ec5d27ca2031c.svn-base
--- a/.svn/pristine/4f/4f91e1e0bb038b11d88f8da5ac2ec5d27ca2031c.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class UserCustomField < CustomField
-  def type_name
-    :label_user_plural
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4f9b6989936a59570ee254faff0b99a606637086.svn-base
--- a/.svn/pristine/4f/4f9b6989936a59570ee254faff0b99a606637086.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-class InsertBuiltinRoles < ActiveRecord::Migration
-  def self.up
-    nonmember = Role.new(:name => 'Non member', :position => 0)
-    nonmember.builtin = Role::BUILTIN_NON_MEMBER
-    nonmember.save
-
-    anonymous = Role.new(:name => 'Anonymous', :position => 0)
-    anonymous.builtin = Role::BUILTIN_ANONYMOUS
-    anonymous.save
-  end
-
-  def self.down
-    Role.destroy_all 'builtin <> 0'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4fb5582b9423d32809fbaa513dda130c44491b13.svn-base
--- a/.svn/pristine/4f/4fb5582b9423d32809fbaa513dda130c44491b13.svn-base
+++ /dev/null
@@ -1,34 +0,0 @@
-desc 'Generates a configuration file for cookie store sessions.'
-
-file 'config/initializers/session_store.rb' do
-  path = File.join(Rails.root, 'config', 'initializers', 'session_store.rb')
-  secret = ActiveSupport::SecureRandom.hex(40)
-  File.open(path, 'w') do |f|
-    f.write <<"EOF"
-# This file was generated by 'rake config/initializers/session_store.rb',
-# and should not be made visible to public.
-# If you have a load-balancing Redmine cluster, you will need to use the
-# same version of this file on each machine. And be sure to restart your
-# server when you modify this file.
-
-# Your secret key for verifying cookie session data integrity. If you
-# change this key, all old sessions will become invalid! Make sure the
-# secret is at least 30 characters and all random, no regular words or
-# you'll be exposed to dictionary attacks.
-ActionController::Base.session = {
-  :key => '_redmine_session',
-  #
-  # Uncomment and edit the :session_path below if are hosting your Redmine
-  # at a suburi and don't want the top level path to access the cookies
-  #
-  # See: http://www.redmine.org/issues/3968
-  #
-  # :session_path => '/url_path_to/your/redmine/',
-  :secret => '#{secret}'
-}
-EOF
-  end
-end
-
-desc 'Generates a configuration file for cookie store sessions.'
-task :generate_session_store => ['config/initializers/session_store.rb']
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4fb8c835126f8a63271f8bd86689461f1834a855.svn-base
--- /dev/null
+++ b/.svn/pristine/4f/4fb8c835126f8a63271f8bd86689461f1834a855.svn-base
@@ -0,0 +1,202 @@
+--- 
+roles_001: 
+  name: Manager
+  id: 1
+  builtin: 0
+  issues_visibility: all
+  permissions: |
+    --- 
+    - :add_project
+    - :edit_project
+    - :close_project
+    - :select_project_modules
+    - :manage_members
+    - :manage_versions
+    - :manage_categories
+    - :view_issues
+    - :add_issues
+    - :edit_issues
+    - :manage_issue_relations
+    - :manage_subtasks
+    - :add_issue_notes
+    - :move_issues
+    - :delete_issues
+    - :view_issue_watchers
+    - :add_issue_watchers
+    - :set_issues_private
+    - :set_notes_private
+    - :view_private_notes
+    - :delete_issue_watchers
+    - :manage_public_queries
+    - :save_queries
+    - :view_gantt
+    - :view_calendar
+    - :log_time
+    - :view_time_entries
+    - :edit_time_entries
+    - :delete_time_entries
+    - :manage_news
+    - :comment_news
+    - :view_documents
+    - :add_documents
+    - :edit_documents
+    - :delete_documents
+    - :view_wiki_pages
+    - :export_wiki_pages
+    - :view_wiki_edits
+    - :edit_wiki_pages
+    - :delete_wiki_pages_attachments
+    - :protect_wiki_pages
+    - :delete_wiki_pages
+    - :rename_wiki_pages
+    - :add_messages
+    - :edit_messages
+    - :delete_messages
+    - :manage_boards
+    - :view_files
+    - :manage_files
+    - :browse_repository
+    - :manage_repository
+    - :view_changesets
+    - :manage_related_issues
+    - :manage_project_activities
+
+  position: 1
+roles_002: 
+  name: Developer
+  id: 2
+  builtin: 0
+  issues_visibility: default
+  permissions: |
+    --- 
+    - :edit_project
+    - :manage_members
+    - :manage_versions
+    - :manage_categories
+    - :view_issues
+    - :add_issues
+    - :edit_issues
+    - :manage_issue_relations
+    - :manage_subtasks
+    - :add_issue_notes
+    - :move_issues
+    - :delete_issues
+    - :view_issue_watchers
+    - :save_queries
+    - :view_gantt
+    - :view_calendar
+    - :log_time
+    - :view_time_entries
+    - :edit_own_time_entries
+    - :manage_news
+    - :comment_news
+    - :view_documents
+    - :add_documents
+    - :edit_documents
+    - :delete_documents
+    - :view_wiki_pages
+    - :view_wiki_edits
+    - :edit_wiki_pages
+    - :protect_wiki_pages
+    - :delete_wiki_pages
+    - :add_messages
+    - :edit_own_messages
+    - :delete_own_messages
+    - :manage_boards
+    - :view_files
+    - :manage_files
+    - :browse_repository
+    - :view_changesets
+
+  position: 2
+roles_003: 
+  name: Reporter
+  id: 3
+  builtin: 0
+  issues_visibility: default
+  permissions: |
+    --- 
+    - :edit_project
+    - :manage_members
+    - :manage_versions
+    - :manage_categories
+    - :view_issues
+    - :add_issues
+    - :edit_issues
+    - :manage_issue_relations
+    - :add_issue_notes
+    - :move_issues
+    - :view_issue_watchers
+    - :save_queries
+    - :view_gantt
+    - :view_calendar
+    - :log_time
+    - :view_time_entries
+    - :manage_news
+    - :comment_news
+    - :view_documents
+    - :add_documents
+    - :edit_documents
+    - :delete_documents
+    - :view_wiki_pages
+    - :view_wiki_edits
+    - :edit_wiki_pages
+    - :delete_wiki_pages
+    - :add_messages
+    - :manage_boards
+    - :view_files
+    - :manage_files
+    - :browse_repository
+    - :view_changesets
+
+  position: 3
+roles_004: 
+  name: Non member
+  id: 4
+  builtin: 1
+  issues_visibility: default
+  permissions: |
+    --- 
+    - :view_issues
+    - :add_issues
+    - :edit_issues
+    - :manage_issue_relations
+    - :add_issue_notes
+    - :save_queries
+    - :view_gantt
+    - :view_calendar
+    - :log_time
+    - :view_time_entries
+    - :comment_news
+    - :view_documents
+    - :view_wiki_pages
+    - :view_wiki_edits
+    - :edit_wiki_pages
+    - :add_messages
+    - :view_files
+    - :manage_files
+    - :browse_repository
+    - :view_changesets
+
+  position: 4
+roles_005: 
+  name: Anonymous
+  id: 5
+  builtin: 2
+  issues_visibility: default
+  permissions: |
+    --- 
+    - :view_issues
+    - :add_issue_notes
+    - :view_gantt
+    - :view_calendar
+    - :view_time_entries
+    - :view_documents
+    - :view_wiki_pages
+    - :view_wiki_edits
+    - :view_files
+    - :browse_repository
+    - :view_changesets
+
+  position: 5
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4fc2ff472415472e5bc5a895e07b22fbca85faf1.svn-base
--- /dev/null
+++ b/.svn/pristine/4f/4fc2ff472415472e5bc5a895e07b22fbca85faf1.svn-base
@@ -0,0 +1,40 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class MailHandlerController < ActionController::Base
+  before_filter :check_credential
+
+  # Submits an incoming email to MailHandler
+  def index
+    options = params.dup
+    email = options.delete(:email)
+    if MailHandler.receive(email, options)
+      render :nothing => true, :status => :created
+    else
+      render :nothing => true, :status => :unprocessable_entity
+    end
+  end
+
+  private
+
+  def check_credential
+    User.current = nil
+    unless Setting.mail_handler_api_enabled? && params[:key].to_s == Setting.mail_handler_api_key
+      render :text => 'Access denied. Incoming emails WS is disabled or key is invalid.', :status => 403
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/4f/4fc60931645e3d4832cac83cc1c9d2c25c5df098.svn-base
--- /dev/null
+++ b/.svn/pristine/4f/4fc60931645e3d4832cac83cc1c9d2c25c5df098.svn-base
@@ -0,0 +1,130 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class EnumerationTest < ActiveSupport::TestCase
+  fixtures :enumerations, :issues, :custom_fields, :custom_values
+
+  def test_objects_count
+    # low priority
+    assert_equal 6, Enumeration.find(4).objects_count
+    # urgent
+    assert_equal 0, Enumeration.find(7).objects_count
+  end
+
+  def test_in_use
+    # low priority
+    assert Enumeration.find(4).in_use?
+    # urgent
+    assert !Enumeration.find(7).in_use?
+  end
+
+  def test_default
+    e = Enumeration.default
+    assert e.is_a?(Enumeration)
+    assert e.is_default?
+    assert e.active?
+    assert_equal 'Default Enumeration', e.name
+  end
+
+  def test_default_non_active
+    e = Enumeration.find(12)
+    assert e.is_a?(Enumeration)
+    assert e.is_default?
+    assert e.active?
+    e.update_attributes(:active => false)
+    assert e.is_default?
+    assert !e.active?
+  end
+
+  def test_create
+    e = Enumeration.new(:name => 'Not default', :is_default => false)
+    e.type = 'Enumeration'
+    assert e.save
+    assert_equal 'Default Enumeration', Enumeration.default.name
+  end
+
+  def test_create_as_default
+    e = Enumeration.new(:name => 'Very urgent', :is_default => true)
+    e.type = 'Enumeration'
+    assert e.save
+    assert_equal e, Enumeration.default
+  end
+
+  def test_update_default
+    e = Enumeration.default
+    e.update_attributes(:name => 'Changed', :is_default => true)
+    assert_equal e, Enumeration.default
+  end
+
+  def test_update_default_to_non_default
+    e = Enumeration.default
+    e.update_attributes(:name => 'Changed', :is_default => false)
+    assert_nil Enumeration.default
+  end
+
+  def test_change_default
+    e = Enumeration.find_by_name('Default Enumeration')
+    e.update_attributes(:name => 'Changed Enumeration', :is_default => true)
+    assert_equal e, Enumeration.default
+  end
+
+  def test_destroy_with_reassign
+    Enumeration.find(4).destroy(Enumeration.find(6))
+    assert_nil Issue.where(:priority_id => 4).first
+    assert_equal 6, Enumeration.find(6).objects_count
+  end
+
+  def test_should_be_customizable
+    assert Enumeration.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
+  end
+
+  def test_should_belong_to_a_project
+    association = Enumeration.reflect_on_association(:project)
+    assert association, "No Project association found"
+    assert_equal :belongs_to, association.macro
+  end
+
+  def test_should_act_as_tree
+    enumeration = Enumeration.find(4)
+
+    assert enumeration.respond_to?(:parent)
+    assert enumeration.respond_to?(:children)
+  end
+
+  def test_is_override
+    # Defaults to off
+    enumeration = Enumeration.find(4)
+    assert !enumeration.is_override?
+
+    # Setup as an override
+    enumeration.parent = Enumeration.find(5)
+    assert enumeration.is_override?
+  end
+
+  def test_get_subclasses
+    classes = Enumeration.get_subclasses
+    assert_include IssuePriority, classes
+    assert_include DocumentCategory, classes
+    assert_include TimeEntryActivity, classes
+
+    classes.each do |klass|
+      assert_equal Enumeration, klass.superclass
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/50/504a75e28140e0b003d557f020f846d8f93e9c79.svn-base
--- /dev/null
+++ b/.svn/pristine/50/504a75e28140e0b003d557f020f846d8f93e9c79.svn-base
@@ -0,0 +1,73 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class SettingsController < ApplicationController
+  layout 'admin'
+  menu_item :plugins, :only => :plugin
+
+  helper :queries
+
+  before_filter :require_admin
+
+  def index
+    edit
+    render :action => 'edit'
+  end
+
+  def edit
+    @notifiables = Redmine::Notifiable.all
+    if request.post? && params[:settings] && params[:settings].is_a?(Hash)
+      settings = (params[:settings] || {}).dup.symbolize_keys
+      settings.each do |name, value|
+        # remove blank values in array settings
+        value.delete_if {|v| v.blank? } if value.is_a?(Array)
+        Setting[name] = value
+      end
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to settings_path(:tab => params[:tab])
+    else
+      @options = {}
+      user_format = User::USER_FORMATS.collect{|key, value| [key, value[:setting_order]]}.sort{|a, b| a[1] <=> b[1]}
+      @options[:user_format] = user_format.collect{|f| [User.current.name(f[0]), f[0].to_s]}
+      @deliveries = ActionMailer::Base.perform_deliveries
+
+      @guessed_host_and_path = request.host_with_port.dup
+      @guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank?
+
+      Redmine::Themes.rescan
+    end
+  end
+
+  def plugin
+    @plugin = Redmine::Plugin.find(params[:id])
+    unless @plugin.configurable?
+      render_404
+      return
+    end
+
+    if request.post?
+      Setting.send "plugin_#{@plugin.id}=", params[:settings]
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to plugin_settings_path(@plugin)
+    else
+      @partial = @plugin.settings[:partial]
+      @settings = Setting.send "plugin_#{@plugin.id}"
+    end
+  rescue Redmine::PluginNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/50/50652fe8225e67d65adfd17ea2e35e3021fb4461.svn-base
--- /dev/null
+++ b/.svn/pristine/50/50652fe8225e67d65adfd17ea2e35e3021fb4461.svn-base
@@ -0,0 +1,102 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::SafeAttributesTest < ActiveSupport::TestCase
+  fixtures :users
+
+  class Base
+    def attributes=(attrs)
+      attrs.each do |key, value|
+        send("#{key}=", value)
+      end
+    end
+  end
+
+  class Person < Base
+    attr_accessor :firstname, :lastname, :login
+    include Redmine::SafeAttributes
+    safe_attributes :firstname, :lastname
+    safe_attributes :login, :if => lambda {|person, user| user.admin?}
+  end
+
+  class Book < Base
+    attr_accessor :title
+    include Redmine::SafeAttributes
+    safe_attributes :title
+  end
+
+  def test_safe_attribute_names
+    p = Person.new
+    user = User.anonymous
+    assert_equal ['firstname', 'lastname'], p.safe_attribute_names(user)
+    assert p.safe_attribute?('firstname', user)
+    assert !p.safe_attribute?('login', user)
+
+    p = Person.new
+    user = User.find(1)
+    assert_equal ['firstname', 'lastname', 'login'], p.safe_attribute_names(user)
+    assert p.safe_attribute?('firstname', user)
+    assert p.safe_attribute?('login', user)
+  end
+
+  def test_safe_attribute_names_without_user
+    p = Person.new
+    User.current = nil
+    assert_equal ['firstname', 'lastname'], p.safe_attribute_names
+    assert p.safe_attribute?('firstname')
+    assert !p.safe_attribute?('login')
+
+    p = Person.new
+    User.current = User.find(1)
+    assert_equal ['firstname', 'lastname', 'login'], p.safe_attribute_names
+    assert p.safe_attribute?('firstname')
+    assert p.safe_attribute?('login')
+  end
+
+  def test_set_safe_attributes
+    p = Person.new
+    p.send('safe_attributes=', {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}, User.anonymous)
+    assert_equal 'John', p.firstname
+    assert_equal 'Smith', p.lastname
+    assert_nil p.login
+
+    p = Person.new
+    User.current = User.find(1)
+    p.send('safe_attributes=', {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}, User.find(1))
+    assert_equal 'John', p.firstname
+    assert_equal 'Smith', p.lastname
+    assert_equal 'jsmith', p.login
+  end
+
+  def test_set_safe_attributes_without_user
+    p = Person.new
+    User.current = nil
+    p.safe_attributes = {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}
+    assert_equal 'John', p.firstname
+    assert_equal 'Smith', p.lastname
+    assert_nil p.login
+
+    p = Person.new
+    User.current = User.find(1)
+    p.safe_attributes = {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}
+    assert_equal 'John', p.firstname
+    assert_equal 'Smith', p.lastname
+    assert_equal 'jsmith', p.login
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/50/509ee267bffe97965ae0a631af5009f5ad9e1775.svn-base
--- a/.svn/pristine/50/509ee267bffe97965ae0a631af5009f5ad9e1775.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-<div class="contextual">
-<% form_tag({:action => 'revision', :id => @project}) do %>
-<%=   l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 8 %>
-<%=   submit_tag 'OK' %>
-<% end %>
-</div>
-
-<h2><%= l(:label_revision_plural) %></h2>
-
-<%= render :partial => 'revisions',
-           :locals => {:project   => @project,
-                       :path      => '',
-                       :revisions => @changesets,
-                       :entry     => nil } %>
-
-<p class="pagination"><%= pagination_links_full @changeset_pages,@changeset_count %></p>
-
-<% content_for :header_tags do %>
-<%=   stylesheet_link_tag "scm" %>
-<%=   auto_discovery_link_tag(
-               :atom,
-               params.merge(
-                 {:format => 'atom', :page => nil, :key => User.current.rss_key})) %>
-<% end %>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
-<% end %>
-
-<% html_title(l(:label_revision_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/50/50da835a6f15cfea65885171e3501d71716f5bea.svn-base
--- a/.svn/pristine/50/50da835a6f15cfea65885171e3501d71716f5bea.svn-base
+++ /dev/null
@@ -1,43 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class EnabledModuleTest < ActiveSupport::TestCase
-  fixtures :projects, :wikis
-
-  def test_enabling_wiki_should_create_a_wiki
-    CustomField.delete_all
-    project = Project.create!(:name => 'Project with wiki', :identifier => 'wikiproject')
-    assert_nil project.wiki
-    project.enabled_module_names = ['wiki']
-    project.reload
-    assert_not_nil project.wiki
-    assert_equal 'Wiki', project.wiki.start_page
-  end
-
-  def test_reenabling_wiki_should_not_create_another_wiki
-    project = Project.find(1)
-    assert_not_nil project.wiki
-    project.enabled_module_names = []
-    project.reload
-    assert_no_difference 'Wiki.count' do
-      project.enabled_module_names = ['wiki']
-    end
-    assert_not_nil project.wiki
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/50/50fe0fccbefe1bf6410e617ed3aed18dfc4dd61e.svn-base
--- /dev/null
+++ b/.svn/pristine/50/50fe0fccbefe1bf6410e617ed3aed18dfc4dd61e.svn-base
@@ -0,0 +1,178 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class JournalTest < ActiveSupport::TestCase
+  fixtures :projects, :issues, :issue_statuses, :journals, :journal_details,
+           :users, :members, :member_roles, :roles, :enabled_modules,
+           :projects_trackers, :trackers
+
+  def setup
+    @journal = Journal.find 1
+  end
+
+  def test_journalized_is_an_issue
+    issue = @journal.issue
+    assert_kind_of Issue, issue
+    assert_equal 1, issue.id
+  end
+
+  def test_new_status
+    status = @journal.new_status
+    assert_not_nil status
+    assert_kind_of IssueStatus, status
+    assert_equal 2, status.id
+  end
+
+  def test_create_should_send_email_notification
+    ActionMailer::Base.deliveries.clear
+    issue = Issue.first
+    user = User.first
+    journal = issue.init_journal(user, issue)
+
+    assert journal.save
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_should_not_save_journal_with_blank_notes_and_no_details
+    journal = Journal.new(:journalized => Issue.first, :user => User.first)
+
+    assert_no_difference 'Journal.count' do
+      assert_equal false, journal.save
+    end
+  end
+
+  def test_create_should_not_split_non_private_notes
+    assert_difference 'Journal.count' do
+      assert_no_difference 'JournalDetail.count' do
+        journal = Journal.generate!(:notes => 'Notes')
+      end
+    end
+
+    assert_difference 'Journal.count' do
+      assert_difference 'JournalDetail.count' do
+        journal = Journal.generate!(:notes => 'Notes', :details => [JournalDetail.new])
+      end
+    end
+
+    assert_difference 'Journal.count' do
+      assert_difference 'JournalDetail.count' do
+        journal = Journal.generate!(:notes => '', :details => [JournalDetail.new])
+      end
+    end
+  end
+
+  def test_create_should_split_private_notes
+    assert_difference 'Journal.count' do
+      assert_no_difference 'JournalDetail.count' do
+        journal = Journal.generate!(:notes => 'Notes', :private_notes => true)
+        journal.reload
+        assert_equal true, journal.private_notes
+        assert_equal 'Notes', journal.notes
+      end
+    end
+
+    assert_difference 'Journal.count', 2 do
+      assert_difference 'JournalDetail.count' do
+        journal = Journal.generate!(:notes => 'Notes', :private_notes => true, :details => [JournalDetail.new])
+        journal.reload
+        assert_equal true, journal.private_notes
+        assert_equal 'Notes', journal.notes
+        assert_equal 0, journal.details.size
+
+        journal_with_changes = Journal.order('id DESC').offset(1).first
+        assert_equal false, journal_with_changes.private_notes
+        assert_nil journal_with_changes.notes
+        assert_equal 1, journal_with_changes.details.size
+        assert_equal journal.created_on, journal_with_changes.created_on
+      end
+    end
+
+    assert_difference 'Journal.count' do
+      assert_difference 'JournalDetail.count' do
+        journal = Journal.generate!(:notes => '', :private_notes => true, :details => [JournalDetail.new])
+        journal.reload
+        assert_equal false, journal.private_notes
+        assert_equal '', journal.notes
+        assert_equal 1, journal.details.size
+      end
+    end
+  end
+
+  def test_visible_scope_for_anonymous
+    # Anonymous user should see issues of public projects only
+    journals = Journal.visible(User.anonymous).all
+    assert journals.any?
+    assert_nil journals.detect {|journal| !journal.issue.project.is_public?}
+    # Anonymous user should not see issues without permission
+    Role.anonymous.remove_permission!(:view_issues)
+    journals = Journal.visible(User.anonymous).all
+    assert journals.empty?
+  end
+
+  def test_visible_scope_for_user
+    user = User.find(9)
+    assert user.projects.empty?
+    # Non member user should see issues of public projects only
+    journals = Journal.visible(user).all
+    assert journals.any?
+    assert_nil journals.detect {|journal| !journal.issue.project.is_public?}
+    # Non member user should not see issues without permission
+    Role.non_member.remove_permission!(:view_issues)
+    user.reload
+    journals = Journal.visible(user).all
+    assert journals.empty?
+    # User should see issues of projects for which he has view_issues permissions only
+    Member.create!(:principal => user, :project_id => 1, :role_ids => [1])
+    user.reload
+    journals = Journal.visible(user).all
+    assert journals.any?
+    assert_nil journals.detect {|journal| journal.issue.project_id != 1}
+  end
+
+  def test_visible_scope_for_admin
+    user = User.find(1)
+    user.members.each(&:destroy)
+    assert user.projects.empty?
+    journals = Journal.visible(user).all
+    assert journals.any?
+    # Admin should see issues on private projects that he does not belong to
+    assert journals.detect {|journal| !journal.issue.project.is_public?}
+  end
+
+  def test_details_should_normalize_dates
+    j = JournalDetail.create!(:old_value => Date.parse('2012-11-03'), :value => Date.parse('2013-01-02'))
+    j.reload
+    assert_equal '2012-11-03', j.old_value
+    assert_equal '2013-01-02', j.value
+  end
+
+  def test_details_should_normalize_true_values
+    j = JournalDetail.create!(:old_value => true, :value => true)
+    j.reload
+    assert_equal '1', j.old_value
+    assert_equal '1', j.value
+  end
+
+  def test_details_should_normalize_false_values
+    j = JournalDetail.create!(:old_value => false, :value => false)
+    j.reload
+    assert_equal '0', j.old_value
+    assert_equal '0', j.value
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/511d1a9b54cc17e8e6be5b0543b0c534e10de28e.svn-base
--- a/.svn/pristine/51/511d1a9b54cc17e8e6be5b0543b0c534e10de28e.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-require File.join(File.dirname(__FILE__), *%w[.. .. test_helper])
-
-class OverrideTest < ActiveSupport::TestCase
-  def test_overrides_from_the_application_should_work
-    assert true, "overriding plugin tests from the application should work"
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/514f8aeb54e3381fa2badbe487c0d7fd6bad2fd0.svn-base
--- /dev/null
+++ b/.svn/pristine/51/514f8aeb54e3381fa2badbe487c0d7fd6bad2fd0.svn-base
@@ -0,0 +1,145 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssueCategoriesControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, :issue_categories,
+           :issues
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 2
+  end
+
+  def test_new
+    @request.session[:user_id] = 2 # manager
+    get :new, :project_id => '1'
+    assert_response :success
+    assert_template 'new'
+    assert_select 'input[name=?]', 'issue_category[name]'
+  end
+
+  def test_new_from_issue_form
+    @request.session[:user_id] = 2 # manager
+    xhr :get, :new, :project_id => '1'
+
+    assert_response :success
+    assert_template 'new'
+    assert_equal 'text/javascript', response.content_type
+  end
+
+  def test_create
+    @request.session[:user_id] = 2 # manager
+    assert_difference 'IssueCategory.count' do
+      post :create, :project_id => '1', :issue_category => {:name => 'New category'}
+    end
+    assert_redirected_to '/projects/ecookbook/settings/categories'
+    category = IssueCategory.find_by_name('New category')
+    assert_not_nil category
+    assert_equal 1, category.project_id
+  end
+
+  def test_create_failure
+    @request.session[:user_id] = 2
+    post :create, :project_id => '1', :issue_category => {:name => ''}
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_create_from_issue_form
+    @request.session[:user_id] = 2 # manager
+    assert_difference 'IssueCategory.count' do
+      xhr :post, :create, :project_id => '1', :issue_category => {:name => 'New category'}
+    end
+    category = IssueCategory.first(:order => 'id DESC')
+    assert_equal 'New category', category.name
+
+    assert_response :success
+    assert_template 'create'
+    assert_equal 'text/javascript', response.content_type
+  end
+
+  def test_create_from_issue_form_with_failure
+    @request.session[:user_id] = 2 # manager
+    assert_no_difference 'IssueCategory.count' do
+      xhr :post, :create, :project_id => '1', :issue_category => {:name => ''}
+    end
+
+    assert_response :success
+    assert_template 'new'
+    assert_equal 'text/javascript', response.content_type
+  end
+
+  def test_edit
+    @request.session[:user_id] = 2
+    get :edit, :id => 2
+    assert_response :success
+    assert_template 'edit'
+    assert_select 'input[name=?][value=?]', 'issue_category[name]', 'Recipes'
+  end
+
+  def test_update
+    assert_no_difference 'IssueCategory.count' do
+      put :update, :id => 2, :issue_category => { :name => 'Testing' }
+    end
+    assert_redirected_to '/projects/ecookbook/settings/categories'
+    assert_equal 'Testing', IssueCategory.find(2).name
+  end
+
+  def test_update_failure
+    put :update, :id => 2, :issue_category => { :name => '' }
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_update_not_found
+    put :update, :id => 97, :issue_category => { :name => 'Testing' }
+    assert_response 404
+  end
+
+  def test_destroy_category_not_in_use
+    delete :destroy, :id => 2
+    assert_redirected_to '/projects/ecookbook/settings/categories'
+    assert_nil IssueCategory.find_by_id(2)
+  end
+
+  def test_destroy_category_in_use
+    delete :destroy, :id => 1
+    assert_response :success
+    assert_template 'destroy'
+    assert_not_nil IssueCategory.find_by_id(1)
+  end
+
+  def test_destroy_category_in_use_with_reassignment
+    issue = Issue.where(:category_id => 1).first
+    delete :destroy, :id => 1, :todo => 'reassign', :reassign_to_id => 2
+    assert_redirected_to '/projects/ecookbook/settings/categories'
+    assert_nil IssueCategory.find_by_id(1)
+    # check that the issue was reassign
+    assert_equal 2, issue.reload.category_id
+  end
+
+  def test_destroy_category_in_use_without_reassignment
+    issue = Issue.where(:category_id => 1).first
+    delete :destroy, :id => 1, :todo => 'nullify'
+    assert_redirected_to '/projects/ecookbook/settings/categories'
+    assert_nil IssueCategory.find_by_id(1)
+    # check that the issue category was nullified
+    assert_nil issue.reload.category_id
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/51931955320a8df763ed8cb90bc828e4398d3b92.svn-base
--- a/.svn/pristine/51/51931955320a8df763ed8cb90bc828e4398d3b92.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-COPYING
-ChangeLog
-History.txt
-Manifest.txt
-README
-Rakefile
-TODO
-lib/tree.rb
-lib/tree/binarytree.rb
-setup.rb
-test/test_binarytree.rb
-test/test_tree.rb
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/5194b9835666462a25b29cefc4dc53bf3bde050c.svn-base
--- a/.svn/pristine/51/5194b9835666462a25b29cefc4dc53bf3bde050c.svn-base
+++ /dev/null
@@ -1,1008 +0,0 @@
-mk:
-  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%d/%m/%Y"
-      short: "%d %b"
-      long: "%d %B, %Y"
-
-    day_names: [Ð½ÐµÐ´ÐµÐ»Ð°, Ð¿Ð¾Ð½ÐµÐ´ÐµÐ»Ð½Ð¸Ðº, Ð²Ñ‚Ð¾Ñ€Ð½Ð¸Ðº, ÑÑ€ÐµÐ´Ð°, Ñ‡ÐµÑ‚Ð²Ñ€Ñ‚Ð¾Ðº, Ð¿ÐµÑ‚Ð¾Ðº, ÑÐ°Ð±Ð¾Ñ‚Ð°]
-    abbr_day_names: [Ð½ÐµÐ´, Ð¿Ð¾Ð½, Ð²Ñ‚Ð¾, ÑÑ€Ðµ, Ñ‡ÐµÑ‚, Ð¿ÐµÑ‚, ÑÐ°Ð±]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Ñ˜Ð°Ð½ÑƒÐ°Ñ€Ð¸, Ñ„ÐµÐ²Ñ€ÑƒÐ°Ñ€Ð¸, Ð¼Ð°Ñ€Ñ‚, Ð°Ð¿Ñ€Ð¸Ð», Ð¼Ð°Ñ˜, Ñ˜ÑƒÐ½Ð¸, Ñ˜ÑƒÐ»Ð¸, Ð°Ð²Ð³ÑƒÑÑ‚, ÑÐµÐ¿Ñ‚ÐµÐ¼Ð²Ñ€Ð¸, Ð¾ÐºÑ‚Ð¾Ð¼Ð²Ñ€Ð¸, Ð½Ð¾ÐµÐ¼Ð²Ñ€Ð¸, Ð´ÐµÐºÐµÐ¼Ð²Ñ€Ð¸]
-    abbr_month_names: [~, Ñ˜Ð°Ð½, Ñ„ÐµÐ², Ð¼Ð°Ñ€, Ð°Ð¿Ñ€, Ð¼Ð°Ñ˜, Ñ˜ÑƒÐ½, Ñ˜ÑƒÐ», Ð°Ð²Ð³, ÑÐµÐ¿, Ð¾ÐºÑ‚, Ð½Ð¾Ðµ, Ð´ÐµÐº]
-    # Used in date_select and datime_select.
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%d/%m/%Y %H:%M"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%d %B, %Y %H:%M"
-    am: "Ð¿Ñ€ÐµÐ´Ð¿Ð»Ð°Ð´Ð½Ðµ"
-    pm: "Ð¿Ð¾Ð¿Ð»Ð°Ð´Ð½Ðµ"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "Ð¿Ð¾Ð»Ð° Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
-      less_than_x_seconds:
-        one:   "Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ 1 ÑÐµÐºÑƒÐ½Ð´Ð°"
-        other: "Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ %{count} ÑÐµÐºÑƒÐ½Ð´Ð¸"
-      x_seconds:
-        one:   "1 ÑÐµÐºÑƒÐ½Ð´Ð°"
-        other: "%{count} ÑÐµÐºÑƒÐ½Ð´Ð¸"
-      less_than_x_minutes:
-        one:   "Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ 1 Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
-        other: "Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ %{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð¸"
-      x_minutes:
-        one:   "1 Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
-        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð¸"
-      about_x_hours:
-        one:   "Ð¾ÐºÐ¾Ð»Ñƒ 1 Ñ‡Ð°Ñ"
-        other: "Ð¾ÐºÐ¾Ð»Ñƒ %{count} Ñ‡Ð°ÑÐ°"
-      x_days:
-        one:   "1 Ð´ÐµÐ½"
-        other: "%{count} Ð´ÐµÐ½Ð°"
-      about_x_months:
-        one:   "Ð¾ÐºÐ¾Ð»Ñƒ 1 Ð¼ÐµÑÐµÑ†"
-        other: "Ð¾ÐºÐ¾Ð»Ñƒ %{count} Ð¼ÐµÑÐµÑ†Ð¸"
-      x_months:
-        one:   "1 Ð¼ÐµÑÐµÑ†"
-        other: "%{count} Ð¼ÐµÑÐµÑ†Ð¸"
-      about_x_years:
-        one:   "Ð¾ÐºÐ¾Ð»Ñƒ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
-        other: "Ð¾ÐºÐ¾Ð»Ñƒ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
-      over_x_years:
-        one:   "Ð¿Ñ€ÐµÐºÑƒ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
-        other: "Ð¿Ñ€ÐµÐºÑƒ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
-      almost_x_years:
-        one:   "ÑÐºÐ¾Ñ€Ð¾ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
-        other: "ÑÐºÐ¾Ñ€Ð¾ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
-
-  number:
-    # Default format for numbers
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "Ð¸"
-      skip_last_comma: false
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "Ð½Ðµ Ðµ Ð²ÐºÐ»ÑƒÑ‡ÐµÐ½Ð¾ Ð²Ð¾ Ð»Ð¸ÑÑ‚Ð°Ñ‚Ð°"
-        exclusion: "Ðµ Ñ€ÐµÐ·ÐµÑ€Ð²Ð¸Ñ€Ð°Ð½Ð¾"
-        invalid: "Ðµ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð¾"
-        confirmation: "Ð½Ðµ ÑÐµ ÑÐ¾Ð²Ð¿Ð°Ñ“Ð° ÑÐ¾ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ð°Ñ‚Ð°"
-        accepted: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ñ€Ð¸Ñ„Ð°Ñ‚ÐµÐ½Ð¾"
-        empty: "Ð½ÐµÐ¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
-        blank: "Ð½ÐµÐ¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
-        too_long: "Ðµ Ð¿Ñ€ÐµÐ´Ð¾Ð»Ð³Ð¾ (Ð¼Ð°ÐºÑ. %{count} Ð·Ð½Ð°Ñ†Ð¸)"
-        too_short: "Ðµ Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‚ÐºÐ¾ (Ð¼Ð¸Ð½. %{count} Ð·Ð½Ð°Ñ†Ð¸)"
-        wrong_length: "Ðµ Ð¿Ð¾Ð³Ñ€ÐµÑˆÐ½Ð° Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð° (Ñ‚Ñ€ÐµÐ±Ð° Ð´Ð° Ðµ  %{count} Ð·Ð½Ð°Ñ†Ð¸)"
-        taken: "Ðµ Ð²ÐµÑœÐµ Ð·Ð°Ñ„Ð°Ñ‚ÐµÐ½Ð¾"
-        not_a_number: "Ð½Ðµ Ðµ Ð±Ñ€Ð¾Ñ˜"
-        not_a_date: "Ð½Ðµ Ðµ Ð²Ð°Ð»Ð¸Ð´Ð½Ð° Ð´Ð°Ñ‚Ð°"
-        greater_than: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð³Ð¾Ð»ÐµÐ¼Ð¾ Ð¾Ð´ %{count}"
-        greater_than_or_equal_to: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð³Ð¾Ð»ÐµÐ¼Ð¾ Ð¸Ð»Ð¸ ÐµÐ´Ð½Ð°ÐºÐ²Ð¾ Ð½Ð° %{count}"
-        equal_to: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ ÐµÐ´Ð½Ð°ÐºÐ²Ð¾ Ð½Ð° %{count}"
-        less_than: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð¼Ð°Ð»Ð¾ Ð¾Ð´ %{count}"
-        less_than_or_equal_to: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð¼Ð°Ð»Ð¾ Ð¸Ð»Ð¸ ÐµÐ´Ð½Ð°ÐºÐ²Ð¾ Ð½Ð° %{count}"
-        odd: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð½ÐµÐ¿Ð°Ñ€Ð½Ð¾"
-        even: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð°Ñ€Ð½Ð¾"
-        greater_than_start_date: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð³Ð¾Ð»ÐµÐ¼Ð° Ð¾Ð´ Ð¿Ð¾Ñ‡ÐµÑ‚Ð½Ð°Ñ‚Ð° Ð´Ð°Ñ‚Ð°"
-        not_same_project: "Ð½Ðµ Ð¿Ñ€Ð¸Ð¿Ð°Ñ“Ð° Ð½Ð° Ð¸ÑÑ‚Ð¸Ð¾Ñ‚ Ð¿Ñ€Ð¾ÐµÐºÑ‚"
-        circular_dependency: "ÐžÐ²Ð°Ð° Ð²Ñ€ÑÐºÐ° ÑœÐµ ÐºÑ€ÐµÐ¸Ñ€Ð° ÐºÑ€ÑƒÐ¶Ð½Ð° Ð·Ð°Ð²Ð¸ÑÐ½Ð¾ÑÑ‚"
-        cant_link_an_issue_with_a_descendant: "Ð—Ð°Ð´Ð°Ñ‡Ð° Ð½ÐµÐ¼Ð¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð¿Ð¾Ð²Ñ€Ð·Ðµ ÑÐ¾ ÐµÐ´Ð½Ð° Ð¾Ð´ Ð½ÐµÑ˜Ð·Ð¸Ð½Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸"
-
-  actionview_instancetag_blank_option: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ
-
-  general_text_No: 'ÐÐµ'
-  general_text_Yes: 'Ð”Ð°'
-  general_text_no: 'Ð½Ðµ'
-  general_text_yes: 'Ð´Ð°'
-  general_lang_name: 'Macedonian (ÐœÐ°ÐºÐµÐ´Ð¾Ð½ÑÐºÐ¸)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: ÐŸÑ€Ð¾Ñ„Ð¸Ð»Ð¾Ñ‚ Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½.
-  notice_account_invalid_creditentials: ÐÐµÑ‚Ð¾Ñ‡ÐµÐ½ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº Ð¸Ð»Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
-  notice_account_password_updated: Ð›Ð¾Ð·Ð¸Ð½ÐºÐ°Ñ‚Ð° Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°.
-  notice_account_wrong_password: ÐŸÐ¾Ð³Ñ€ÐµÑˆÐ½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
-  notice_account_register_done: ÐŸÑ€Ð¾Ñ„Ð¸Ð»Ð¾Ñ‚ Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½. Ð—Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð°, ÐºÐ»ÐºÐ½ÐµÑ‚Ðµ Ð½Ð° Ð²Ñ€ÑÐºÐ°Ñ‚Ð° ÑˆÑ‚Ð¾ Ð²Ð¸ Ðµ Ð¿Ñ€Ð°Ñ‚ÐµÐ½Ð° Ð¿Ð¾ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð°.
-  notice_account_unknown_email: ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ‚ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº.
-  notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
-  notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
-  notice_account_activated: Your account has been activated. You can now log in.
-  notice_successful_create: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ ÐºÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ.
-  notice_successful_update: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°ÑšÐµ.
-  notice_successful_delete: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð±Ñ€Ð¸ÑˆÐµÑšÐµ.
-  notice_successful_connection: Ð£ÑÐ¿ÐµÑˆÐ½Ð° ÐºÐ¾Ð½ÐµÐºÑ†Ð¸Ñ˜Ð°.
-  notice_file_not_found: The page you were trying to access doesn't exist or has been removed.
-  notice_locking_conflict: Data has been updated by another user.
-  notice_not_authorized: You are not authorized to access this page.
-  notice_email_sent: "Ð•-Ð¿Ð¾Ñ€Ð°ÐºÐ° Ðµ Ð¿Ñ€Ð°Ñ‚ÐµÐ½Ð° Ð½Ð° %{value}"
-  notice_email_error: "Ð¡Ðµ ÑÐ»ÑƒÑ‡Ð¸ Ð³Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð¿Ñ€Ð°ÑœÐ°ÑšÐµ Ð½Ð° Ðµ-Ð¿Ð¾Ñ€Ð°ÐºÐ°Ñ‚Ð° (%{value})"
-  notice_feeds_access_key_reseted: Ð’Ð°ÑˆÐ¸Ð¾Ñ‚ RSS ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿ Ðµ reset.
-  notice_api_access_key_reseted: Ð’Ð°ÑˆÐ¸Ð¾Ñ‚ API ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿ Ðµ reset.
-  notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
-  notice_account_pending: "Your account was created and is now pending administrator approval."
-  notice_default_data_loaded: Default configuration successfully loaded.
-  notice_unable_delete_version: Unable to delete version.
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-
-  error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
-  error_scm_not_found: "The entry or revision was not found in the repository."
-  error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
-  error_scm_annotate: "The entry does not exist or can not be annotated."
-  error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
-  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
-  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_can_not_delete_tracker: "This tracker contains issues and can't be deleted."
-  error_can_not_remove_role: "This role is in use and can not be deleted."
-  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version can not be reopened'
-  error_can_not_archive_project: This project can not be archived
-  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
-  error_workflow_copy_source: 'Please select a source tracker or role'
-  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
-  error_unable_delete_issue_status: 'Unable to delete issue status'
-  error_unable_to_connect: "Unable to connect (%{value})"
-  warning_attachments_not_saved: "%{count} file(s) could not be saved."
-
-  mail_subject_lost_password: "Ð’Ð°ÑˆÐ°Ñ‚Ð° %{value} Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°"
-  mail_body_lost_password: 'To change your password, click on the following link:'
-  mail_subject_register: "Your %{value} account activation"
-  mail_body_register: 'To activate your account, click on the following link:'
-  mail_body_account_information_external: "You can use your %{value} account to log in."
-  mail_body_account_information: Your account information
-  mail_subject_account_activation_request: "%{value} account activation request"
-  mail_body_account_activation_request: "ÐÐ¾Ð² ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº (%{value}) Ðµ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½. The account is pending your approval:"
-  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
-  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
-
-  gui_validation_error: 1 Ð³Ñ€ÐµÑˆÐºÐ°
-  gui_validation_error_plural: "%{count} Ð³Ñ€ÐµÑˆÐºÐ¸"
-
-  field_name: Ð˜Ð¼Ðµ
-  field_description: ÐžÐ¿Ð¸Ñ
-  field_summary: ÐšÑ€Ð°Ñ‚Ð¾Ðº Ð¾Ð¿Ð¸Ñ
-  field_is_required: Ð—Ð°Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾
-  field_firstname: Ð˜Ð¼Ðµ
-  field_lastname: ÐŸÑ€ÐµÐ·Ð¸Ð¼Ðµ
-  field_mail: Ð•-Ð¿Ð¾ÑˆÑ‚Ð°
-  field_filename: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  field_filesize: Ð“Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð°
-  field_downloads: ÐŸÑ€ÐµÐ²Ð·ÐµÐ¼Ð°ÑšÐ°
-  field_author: ÐÐ²Ñ‚Ð¾Ñ€
-  field_created_on: ÐšÑ€ÐµÐ¸Ñ€Ð°Ð½
-  field_updated_on: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾
-  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
-  field_is_for_all: Ð—Ð° ÑÐ¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  field_possible_values: ÐœÐ¾Ð¶Ð½Ð¸ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸
-  field_regexp: Regular expression
-  field_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð°
-  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð°
-  field_value: Ð’Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
-  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
-  field_title: ÐÐ°ÑÐ»Ð¾Ð²
-  field_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
-  field_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
-  field_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ
-  field_notes: Ð‘ÐµÐ»ÐµÑˆÐºÐ¸
-  field_is_closed: Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ðµ Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-  field_is_default: Default value
-  field_tracker: Tracker
-  field_subject: ÐÐ°ÑÐ»Ð¾Ð²
-  field_due_date: ÐšÑ€Ð°ÐµÐ½ Ñ€Ð¾Ðº
-  field_assigned_to: Ð”Ð¾Ð´ÐµÐ»ÐµÐ½Ð° Ð½Ð°
-  field_priority: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
-  field_fixed_version: Target version
-  field_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
-  field_principal: Principal
-  field_role: Ð£Ð»Ð¾Ð³Ð°
-  field_homepage: Ð’ÐµÐ± ÑÑ‚Ñ€Ð°Ð½Ð°
-  field_is_public: ÐˆÐ°Ð²ÐµÐ½
-  field_parent: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð½Ð°
-  field_is_in_roadmap: Issues displayed in roadmap
-  field_login: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
-  field_mail_notification: Ð˜Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°ÑšÐ° Ð¿Ð¾ e-Ð¿Ð¾ÑˆÑ‚Ð°
-  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
-  field_last_login_on: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ð½Ð°Ñ˜Ð°Ð²Ð°
-  field_language: ÐˆÐ°Ð·Ð¸Ðº
-  field_effective_date: Ð”Ð°Ñ‚Ð°
-  field_password: Ð›Ð¾Ð·Ð¸Ð½ÐºÐ°
-  field_new_password: ÐÐ¾Ð²Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
-  field_password_confirmation: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð°
-  field_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ð°
-  field_type: Ð¢Ð¸Ð¿
-  field_host: Ð¥Ð¾ÑÑ‚
-  field_port: ÐŸÐ¾Ñ€Ñ‚
-  field_account: Account
-  field_base_dn: Base DN
-  field_attr_login: Login attribute
-  field_attr_firstname: Firstname attribute
-  field_attr_lastname: Lastname attribute
-  field_attr_mail: Email attribute
-  field_onthefly: ÐœÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ð»Ð½Ð¾ (On-the-fly) ÐºÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸
-  field_start_date: ÐŸÐ¾Ñ‡ÐµÑ‚Ð¾Ðº
-  field_done_ratio: "% Ð—Ð°Ð²Ñ€ÑˆÐµÐ½Ð¾"
-  field_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
-  field_hide_mail: ÐšÑ€Ð¸Ñ˜ Ñ˜Ð° Ð¼Ð¾Ñ˜Ð°Ñ‚Ð° Ð°Ð´Ñ€ÐµÑÐ° Ð½Ð° Ðµ-Ð¿Ð¾ÑˆÑ‚Ð°
-  field_comments: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  field_url: URL
-  field_start_page: ÐŸÐ¾Ñ‡ÐµÑ‚Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð°
-  field_subproject: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  field_hours: Ð§Ð°ÑÐ¾Ð²Ð¸
-  field_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
-  field_spent_on: Ð”Ð°Ñ‚Ð°
-  field_identifier: Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€
-  field_is_filter: ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸ ÐºÐ°ÐºÐ¾ Ñ„Ð¸Ð»Ñ‚ÐµÑ€
-  field_issue_to: ÐŸÐ¾Ð²Ñ€Ð·Ð°Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  field_delay: Ð”Ð¾Ñ†Ð½ÐµÑšÐµ
-  field_assignable: ÐÐ° Ð¾Ð²Ð°Ð° ÑƒÐ»Ð¾Ð³Ð° Ð¼Ð¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð´Ð¾Ð´ÐµÐ»ÑƒÐ²Ð°Ð°Ñ‚ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  field_redirect_existing_links: ÐŸÑ€ÐµÐ½Ð°ÑÐ¾Ñ‡Ð¸ Ð³Ð¸ Ð¿Ð¾ÑÑ‚Ð¾ÐµÑ‡ÐºÐ¸Ñ‚Ðµ Ð²Ñ€ÑÐºÐ¸
-  field_estimated_hours: ÐŸÑ€Ð¾Ñ†ÐµÐ½ÐµÑ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  field_column_names: ÐšÐ¾Ð»Ð¾Ð½Ð¸
-  field_time_entries: Ð‘ÐµÐ»ÐµÐ¶Ð¸ Ð²Ñ€ÐµÐ¼Ðµ
-  field_time_zone: Ð’Ñ€ÐµÐ¼ÐµÐ½ÑÐºÐ° Ð·Ð¾Ð½Ð°
-  field_searchable: ÐœÐ¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð¿Ñ€ÐµÐ±Ð°Ñ€ÑƒÐ²Ð°
-  field_default_value: Default value
-  field_comments_sorting: ÐŸÑ€Ð¸ÐºÐ°Ð¶ÑƒÐ²Ð°Ñ˜ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
-  field_parent_title: Parent page
-  field_editable: ÐœÐ¾Ð¶Ðµ Ð´Ð° ÑÐµ ÑƒÑ€ÐµÐ´ÑƒÐ²Ð°
-  field_watcher: Watcher
-  field_identity_url: OpenID URL
-  field_content: Ð¡Ð¾Ð´Ñ€Ð¶Ð¸Ð½Ð°
-  field_group_by: Ð“Ñ€ÑƒÐ¿Ð¸Ñ€Ð°Ñ˜ Ð³Ð¸ Ñ€ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸Ñ‚Ðµ ÑÐ¿Ð¾Ñ€ÐµÐ´
-  field_sharing: Ð¡Ð¿Ð¾Ð´ÐµÐ»ÑƒÐ²Ð°ÑšÐµ
-  field_parent_issue: Parent task
-
-  setting_app_title: ÐÐ°ÑÐ»Ð¾Ð² Ð½Ð° Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°Ñ‚Ð°
-  setting_app_subtitle: ÐŸÐ¾Ð´Ð½Ð°ÑÐ»Ð¾Ð² Ð½Ð° Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°Ñ‚Ð°
-  setting_welcome_text: Ð¢ÐµÐºÑÑ‚ Ð·Ð° Ð´Ð¾Ð±Ñ€ÐµÐ´Ð¾Ñ˜Ð´Ðµ
-  setting_default_language: Default Ñ˜Ð°Ð·Ð¸Ðº
-  setting_login_required: Ð—Ð°Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
-  setting_self_registration: Ð¡Ð°Ð¼Ð¾-Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
-  setting_attachment_max_size: ÐœÐ°ÐºÑ. Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð° Ð½Ð° Ð¿Ñ€Ð¸Ð»Ð¾Ð³
-  setting_issues_export_limit: Issues export limit
-  setting_mail_from: Emission email address
-  setting_bcc_recipients: Blind carbon copy recipients (bcc)
-  setting_plain_text_mail: Ð¢ÐµÐºÑÑ‚ÑƒÐ°Ð»Ð½Ð¸ Ðµ-Ð¿Ð¾Ñ€Ð°ÐºÐ¸ (Ð±ÐµÐ· HTML)
-  setting_host_name: Ð˜Ð¼Ðµ Ð½Ð° Ñ…Ð¾ÑÑ‚ Ð¸ Ð¿Ð°Ñ‚ÐµÐºÐ°
-  setting_text_formatting: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð°ÑšÐµ Ð½Ð° Ñ‚ÐµÐºÑÑ‚
-  setting_wiki_compression: ÐšÐ¾Ð¼Ð¿Ñ€ÐµÑÐ¸Ñ˜Ð° Ð½Ð° Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°Ñ‚Ð° Ð½Ð° Ð²Ð¸ÐºÐ¸
-  setting_feeds_limit: Feed content limit
-  setting_default_projects_public: ÐÐ¾Ð²Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸ ÑÐµ Ð¸Ð½Ð¸Ñ†Ð¸Ñ˜Ð°Ð»Ð½Ð¾ Ñ˜Ð°Ð²Ð½Ð¸
-  setting_autofetch_changesets: Autofetch commits
-  setting_sys_api_enabled: Enable WS for repository management
-  setting_commit_ref_keywords: Referencing keywords
-  setting_commit_fix_keywords: Fixing keywords
-  setting_autologin: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ° Ð½Ð°Ñ˜Ð°Ð²Ð°
-  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð½Ð° Ð´Ð°Ñ‚Ð°
-  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
-  setting_cross_project_issue_relations: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸ Ñ€ÐµÐ»Ð°Ñ†Ð¸Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¼ÐµÑ“Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  setting_issue_list_default_columns: Default columns displayed on the issue list
-  setting_emails_footer: Emails footer
-  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
-  setting_per_page_options: Objects per page options
-  setting_user_format: ÐŸÑ€Ð¸ÐºÐ°Ð· Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸Ñ‚Ðµ
-  setting_activity_days_default: Ð”ÐµÐ½Ð¾Ð²Ð¸ Ð¿Ñ€Ð¸ÐºÐ°Ð¶Ð°Ð½Ð° Ð²Ð¾ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð° Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
-  setting_display_subprojects_issues: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸ Ð³Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ Ð²Ð¾ Ð³Ð»Ð°Ð²Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  setting_enabled_scm: ÐžÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð¸ SCM
-  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
-  setting_mail_handler_api_enabled: Enable WS for incoming emails
-  setting_mail_handler_api_key: API ÐºÐ»ÑƒÑ‡
-  setting_sequential_project_identifiers: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ñ˜ Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»Ð½Ð¸ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¸ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  setting_gravatar_enabled: ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸ Gravatar ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð¸ÐºÐ¾Ð½Ð¸
-  setting_gravatar_default: Default Gravatar image
-  setting_diff_max_lines_displayed: Max number of diff lines displayed
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_openid: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸ OpenID Ð½Ð°Ñ˜Ð°Ð²Ð° Ð¸ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
-  setting_password_min_length: ÐœÐ¸Ð½. Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð° Ð½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
-  setting_new_project_user_role_id: Ð£Ð»Ð¾Ð³Ð° Ð´Ð¾Ð´ÐµÐ»ÐµÐ½Ð° Ð½Ð° Ð½ÐµÐ°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€ÑÐºÐ¸ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº ÐºÐ¾Ñ˜ ÐºÑ€ÐµÐ¸Ñ€Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_field: Use the issue field
-  setting_issue_done_ratio_issue_status: Use the issue status
-  setting_start_of_week: Start calendars on
-  setting_rest_api_enabled: Enable REST web service
-  setting_cache_formatted_text: Cache formatted text
-
-  permission_add_project: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  permission_add_subprojects: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  permission_edit_project: Ð£Ñ€ÐµÐ´Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  permission_select_project_modules: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð·Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  permission_manage_members: Manage members
-  permission_manage_project_activities: Manage project activities
-  permission_manage_versions: Manage versions
-  permission_manage_categories: Manage issue categories
-  permission_view_issues: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_add_issues: Ð”Ð¾Ð´Ð°Ð²Ð°Ñ˜ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_edit_issues: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_manage_issue_relations: Manage issue relations
-  permission_add_issue_notes: Ð”Ð¾Ð´Ð°Ð²Ð°Ñ˜ Ð±ÐµÐ»ÐµÑˆÐºÐ¸
-  permission_edit_issue_notes: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð±ÐµÐ»ÐµÑˆÐºÐ¸
-  permission_edit_own_issue_notes: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸ Ð±ÐµÐ»ÐµÑˆÐºÐ¸
-  permission_move_issues: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚ÑƒÐ²Ð°Ñ˜ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_delete_issues: Ð‘Ñ€Ð¸ÑˆÐ¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_manage_public_queries: Manage public queries
-  permission_save_queries: Save queries
-  permission_view_gantt: View gantt chart
-  permission_view_calendar: View calendar
-  permission_view_issue_watchers: View watchers list
-  permission_add_issue_watchers: Add watchers
-  permission_delete_issue_watchers: Delete watchers
-  permission_log_time: Ð‘ÐµÐ»ÐµÐ¶Ð¸ Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  permission_view_time_entries: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  permission_edit_time_entries: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð±ÐµÐ»ÐµÑˆÐºÐ¸ Ð·Ð° Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  permission_edit_own_time_entries: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸ Ð±ÐµÐ»ÐµÑˆÐºÐ¸ Ð·Ð° Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  permission_manage_news: Manage news
-  permission_comment_news: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð°Ñ˜ Ð½Ð° Ð²ÐµÑÑ‚Ð¸
-  permission_manage_documents: Manage documents
-  permission_view_documents: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  permission_manage_files: Manage files
-  permission_view_files: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ¸
-  permission_manage_wiki: Manage wiki
-  permission_rename_wiki_pages: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_delete_wiki_pages: Ð‘Ñ€Ð¸ÑˆÐ¸ Ð²Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_view_wiki_pages: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸
-  permission_view_wiki_edits: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸ Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°
-  permission_edit_wiki_pages: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_delete_wiki_pages_attachments: Ð‘Ñ€Ð¸ÑˆÐ¸ Ð¿Ñ€Ð¸Ð»Ð¾Ð·Ð¸
-  permission_protect_wiki_pages: Ð—Ð°ÑˆÑ‚Ð¸Ñ‚ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  permission_manage_repository: Manage repository
-  permission_browse_repository: Browse repository
-  permission_view_changesets: View changesets
-  permission_commit_access: Commit access
-  permission_manage_boards: Manage boards
-  permission_view_messages: View messages
-  permission_add_messages: Post messages
-  permission_edit_messages: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð¿Ð¾Ñ€Ð°ÐºÐ¸
-  permission_edit_own_messages: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸ Ð¿Ð¾Ñ€Ð°ÐºÐ¸
-  permission_delete_messages: Ð‘Ñ€Ð¸ÑˆÐ¸ Ð¿Ð¾Ñ€Ð°ÐºÐ¸
-  permission_delete_own_messages: Ð‘Ñ€Ð¸ÑˆÐ¸ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸ Ð¿Ð¾Ñ€Ð°ÐºÐ¸
-  permission_export_wiki_pages: Export wiki pages
-  permission_manage_subtasks: Manage subtasks
-
-  project_module_issue_tracking: Ð¡Ð»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  project_module_time_tracking: Ð¡Ð»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
-  project_module_news: Ð’ÐµÑÑ‚Ð¸
-  project_module_documents: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  project_module_files: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ¸
-  project_module_wiki: Ð’Ð¸ÐºÐ¸
-  project_module_repository: Repository
-  project_module_boards: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
-  project_module_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
-  project_module_gantt: Gantt
-
-  label_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
-  label_user_plural: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸
-  label_user_new: ÐÐ¾Ð² ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
-  label_user_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼ÐµÐ½
-  label_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
-  label_project_new: ÐÐ¾Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  label_project_plural: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸
-  label_x_projects:
-    zero:  Ð½ÐµÐ¼Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-    one:   1 Ð¿Ñ€Ð¾ÐµÐºÑ‚
-    other: "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
-  label_project_all: Ð¡Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_project_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_new: ÐÐ¾Ð²Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_plural: Ð—Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_view_all: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issues_by: "Ð—Ð°Ð´Ð°Ñ‡Ð¸ Ð¿Ð¾ %{value}"
-  label_issue_added: Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
-  label_issue_updated: Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°
-  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_new: ÐÐ¾Ð² Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  label_document_added: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ñ‚ Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½
-  label_role: Ð£Ð»Ð¾Ð³Ð°
-  label_role_plural: Ð£Ð»Ð¾Ð³Ð¸
-  label_role_new: ÐÐ¾Ð²Ð° ÑƒÐ»Ð¾Ð³Ð°
-  label_role_and_permissions: Ð£Ð»Ð¾Ð³Ð¸ Ð¸ Ð¾Ð²Ð»Ð°ÑÑ‚ÑƒÐ²Ð°ÑšÐ°
-  label_member: Ð§Ð»ÐµÐ½
-  label_member_new: ÐÐ¾Ð² Ñ‡Ð»ÐµÐ½
-  label_member_plural: Ð§Ð»ÐµÐ½Ð¾Ð²Ð¸
-  label_tracker: Tracker
-  label_tracker_plural: Trackers
-  label_tracker_new: New tracker
-  label_workflow: Workflow
-  label_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_status_plural: Ð¡Ñ‚Ð°Ñ‚ÑƒÑÐ¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_status_new: ÐÐ¾Ð² ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð° Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_category_new: ÐÐ¾Ð²Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
-  label_custom_field: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ð´ÐµÐ½Ð¾ Ð¿Ð¾Ð»Ðµ
-  label_custom_field_plural: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ð´ÐµÐ½Ð¸ Ð¿Ð¾Ð»Ð¸ÑšÐ°
-  label_custom_field_new: ÐÐ¾Ð²Ð¾ Ð¿Ñ€Ð¸Ð»Ð°Ð³Ð¾Ð´ÐµÐ½Ð¾ Ð¿Ð¾Ð»Ðµ
-  label_enumerations: Enumerations
-  label_enumeration_new: ÐÐ¾Ð²Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
-  label_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ð°
-  label_information_plural: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸
-  label_please_login: ÐÐ°Ñ˜Ð°Ð²Ð¸ ÑÐµ
-  label_register: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ñ˜ ÑÐµ
-  label_login_with_open_id_option: Ð¸Ð»Ð¸ Ð½Ð°Ñ˜Ð°Ð²Ð¸ ÑÐµ ÑÐ¾ OpenID
-  label_password_lost: Ð˜Ð·Ð³ÑƒÐ±ÐµÐ½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
-  label_home: ÐŸÐ¾Ñ‡ÐµÑ‚Ð½Ð°
-  label_my_page: ÐœÐ¾Ñ˜Ð°Ñ‚Ð° ÑÑ‚Ñ€Ð°Ð½Ð°
-  label_my_account: ÐœÐ¾Ñ˜Ð¾Ñ‚ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»
-  label_my_projects: ÐœÐ¾Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_my_page_block: Ð‘Ð»Ð¾Ðº ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚
-  label_administration: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
-  label_login: ÐÐ°Ñ˜Ð°Ð²Ð¸ ÑÐµ
-  label_logout: ÐžÐ´Ñ˜Ð°Ð²Ð¸ ÑÐµ
-  label_help: ÐŸÐ¾Ð¼Ð¾Ñˆ
-  label_reported_issues: ÐŸÑ€Ð¸Ñ˜Ð°Ð²ÐµÐ½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_assigned_to_me_issues: Ð—Ð°Ð´Ð°Ñ‡Ð¸ Ð´Ð¾Ð´ÐµÐ»ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½Ðµ
-  label_last_login: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ð½Ð°Ñ˜Ð°Ð²Ð°
-  label_registered_on: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½ Ð½Ð°
-  label_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
-  label_overall_activity: Ð¡ÐµÐ²ÐºÑƒÐ¿Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
-  label_user_activity: "ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚ Ð½Ð° %{value}"
-  label_new: ÐÐ¾Ð²Ð°
-  label_logged_as: ÐÐ°Ñ˜Ð°Ð²ÐµÐ½Ð¸ ÑÑ‚Ðµ ÐºÐ°ÐºÐ¾
-  label_environment: ÐžÐ¿ÐºÑ€ÑƒÐ¶ÑƒÐ²Ð°ÑšÐµ
-  label_authentication: ÐÐ²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
-  label_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
-  label_auth_source_new: ÐÐ¾Ð² Ñ€ÐµÐ¶Ð¸Ð¼ Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
-  label_auth_source_plural: Ð ÐµÐ¶Ð¸Ð¼Ð¸ Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
-  label_subproject_plural: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_subproject_new: ÐÐ¾Ð² Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  label_and_its_subprojects: "%{value} Ð¸ Ð½ÐµÐ³Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
-  label_min_max_length: ÐœÐ¸Ð½. - ÐœÐ°ÐºÑ. Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð°
-  label_list: Ð›Ð¸ÑÑ‚Ð°
-  label_date: Ð”Ð°Ñ‚Ð°
-  label_integer: Integer
-  label_float: Float
-  label_boolean: Boolean
-  label_string: Ð¢ÐµÐºÑÑ‚
-  label_text: Ð”Ð¾Ð»Ð³ Ñ‚ÐµÐºÑÑ‚
-  label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
-  label_attribute_plural: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸
-  label_download: "%{count} Ð¿Ñ€ÐµÐ²Ð·ÐµÐ¼Ð°ÑšÐµ"
-  label_download_plural: "%{count} Ð¿Ñ€ÐµÐ²Ð·ÐµÐ¼Ð°ÑšÐ°"
-  label_no_data: ÐÐµÐ¼Ð° Ð¿Ð¾Ð´Ð°Ñ‚Ð¾Ñ†Ð¸ Ð·Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð¶ÑƒÐ²Ð°ÑšÐµ
-  label_change_status: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°
-  label_attachment: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  label_attachment_new: ÐÐ¾Ð²Ð° Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  label_attachment_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  label_attachment_plural: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ¸
-  label_file_added: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°Ñ‚Ð° Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
-  label_report: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ˜
-  label_report_plural: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ð¸
-  label_news: ÐÐ¾Ð²Ð¾ÑÑ‚
-  label_news_new: Ð”Ð¾Ð´Ð°Ð´Ð¸ Ð½Ð¾Ð²Ð¾ÑÑ‚
-  label_news_plural: ÐÐ¾Ð²Ð¾ÑÑ‚Ð¸
-  label_news_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
-  label_news_view_all: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
-  label_news_added: ÐÐ¾Ð²Ð¾ÑÑ‚Ñ‚Ð° Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
-  label_settings: Settings
-  label_overview: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
-  label_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ð°
-  label_version_new: ÐÐ¾Ð²Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
-  label_version_plural: Ð’ÐµÑ€Ð·Ð¸Ð¸
-  label_close_versions: Ð—Ð°Ñ‚Ð²Ð¾Ñ€Ð¸ Ð³Ð¸ Ð·Ð°Ð²Ñ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð²Ñ€Ð·Ð¸Ð¸
-  label_confirmation: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð°
-  label_export_to: 'Ð”Ð¾ÑÑ‚Ð°Ð¿Ð½Ð¾ Ð¸ Ð²Ð¾:'
-  label_read: ÐŸÑ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ˜...
-  label_public_projects: ÐˆÐ°Ð²Ð½Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_open_issues: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-  label_open_issues_plural: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-  label_closed_issues: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-  label_closed_issues_plural: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-  label_x_open_issues_abbr_on_total:
-    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸ / %{total}
-    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° / %{total}
-    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸ / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸"
-  label_x_closed_issues_abbr:
-    zero:  0 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-    one:   1 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-    other: "%{count} Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸"
-  label_total: Ð’ÐºÑƒÐ¿Ð½Ð¾
-  label_permissions: ÐžÐ²Ð»Ð°ÑÑ‚ÑƒÐ²Ð°ÑšÐ°
-  label_current_status: ÐœÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ð»ÐµÐ½ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_new_statuses_allowed: Ð”Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ Ð½Ð¾Ð²Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸
-  label_all: ÑÐ¸Ñ‚Ðµ
-  label_none: Ð½Ð¸ÐµÐ´ÐµÐ½
-  label_nobody: Ð½Ð¸ÐºÐ¾Ñ˜
-  label_next: Ð¡Ð»ÐµÐ´Ð½Ð¾
-  label_previous: ÐŸÑ€ÐµÑ‚Ñ…Ð¾Ð´Ð½Ð¾
-  label_used_by: ÐšÐ¾Ñ€Ð¸ÑÑ‚ÐµÐ½Ð¾ Ð¾Ð´
-  label_details: Ð”ÐµÑ‚Ð°Ð»Ð¸
-  label_add_note: Ð”Ð¾Ð´Ð°Ð´Ð¸ Ð±ÐµÐ»ÐµÑˆÐºÐ°
-  label_per_page: ÐŸÐ¾ ÑÑ‚Ñ€Ð°Ð½Ð°
-  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
-  label_months_from: Ð¼ÐµÑÐµÑ†Ð¸ Ð¾Ð´
-  label_gantt: Gantt
-  label_internal: Internal
-  label_last_changes: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸ %{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
-  label_change_view_all: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸
-  label_personalize_page: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ð´Ð¸ Ñ˜Ð° ÑÑ‚Ñ€Ð°Ð½Ð°Ð²Ð°
-  label_comment: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  label_comment_plural: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
-  label_x_comments:
-    zero: Ð½ÐµÐ¼Ð° ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
-    one: 1 ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-    other: "%{count} ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸"
-  label_comment_add: Ð”Ð¾Ð´Ð°Ð´Ð¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  label_comment_added: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¾Ñ‚ Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½
-  label_comment_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
-  label_query: Custom query
-  label_query_plural: Custom queries
-  label_query_new: New query
-  label_filter_add: Ð”Ð¾Ð´Ð°Ð´Ð¸ Ñ„Ð¸Ð»Ñ‚ÐµÑ€
-  label_filter_plural: Ð¤Ð¸Ð»Ñ‚Ñ€Ð¸
-  label_equals: Ðµ
-  label_not_equals: Ð½Ðµ Ðµ
-  label_in_less_than: Ð·Ð° Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´
-  label_in_more_than: Ð·Ð° Ð¿Ð¾Ð²ÐµÑœÐµ Ð¾Ð´
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: Ð²Ð¾
-  label_today: Ð´ÐµÐ½ÐµÑ
-  label_all_time: Ñ†ÐµÐ»Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_yesterday: Ð²Ñ‡ÐµÑ€Ð°
-  label_this_week: Ð¾Ð²Ð°Ð° Ð½ÐµÐ´ÐµÐ»Ð°
-  label_last_week: Ð¼Ð¸Ð½Ð°Ñ‚Ð°Ñ‚Ð° Ð½ÐµÐ´ÐµÐ»Ð°
-  label_last_n_days: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ‚Ðµ %{count} Ð´ÐµÐ½Ð°"
-  label_this_month: Ð¾Ð²Ð¾Ñ˜ Ð¼ÐµÑÐµÑ†
-  label_last_month: Ð¼Ð¸Ð½Ð°Ñ‚Ð¸Ð¾Ñ‚ Ð¼ÐµÑÐµÑ†
-  label_this_year: Ð¾Ð²Ð°Ð° Ð³Ð¾Ð´Ð¸Ð½Ð°
-  label_date_range: Date range
-  label_less_than_ago: Ð¿Ñ€ÐµÐ´ Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ Ð´ÐµÐ½Ð¾Ð²Ð¸
-  label_more_than_ago: Ð¿Ñ€ÐµÐ´ Ð¿Ð¾Ð²ÐµÑœÐµ Ð¾Ð´ Ð´ÐµÐ½Ð¾Ð²Ð¸
-  label_ago: Ð¿Ñ€ÐµÐ´ Ð´ÐµÐ½Ð¾Ð²Ð¸
-  label_contains: ÑÐ¾Ð´Ñ€Ð¶Ð¸
-  label_not_contains: Ð½Ðµ ÑÐ¾Ð´Ñ€Ð¶Ð¸
-  label_day_plural: Ð´ÐµÐ½Ð¾Ð²Ð¸
-  label_repository: Ð¡ÐºÐ»Ð°Ð´Ð¸ÑˆÑ‚Ðµ
-  label_repository_plural: Ð¡ÐºÐ»Ð°Ð´Ð¸ÑˆÑ‚Ð°
-  label_browse: ÐŸÑ€ÐµÐ»Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ˜
-  label_modification: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
-  label_modification_plural: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
-  label_branch: Ð“Ñ€Ð°Ð½ÐºÐ°
-  label_tag: Tag
-  label_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
-  label_revision_plural: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  label_revision_id: "Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð° %{value}"
-  label_associated_revisions: Associated revisions
-  label_added: added
-  label_modified: modified
-  label_copied: copied
-  label_renamed: renamed
-  label_deleted: deleted
-  label_latest_revision: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
-  label_latest_revision_plural: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  label_view_revisions: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸Ñ‚Ðµ
-  label_view_all_revisions: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  label_max_size: ÐœÐ°ÐºÑ. Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð°
-  label_sort_highest: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ñ˜Ð³Ð¾Ñ€Ðµ
-  label_sort_higher: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ð³Ð¾Ñ€Ðµ
-  label_sort_lower: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ð´Ð¾Ð»Ðµ
-  label_sort_lowest: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ñ˜Ð´Ð¾Ð»Ðµ
-  label_roadmap: Roadmap
-  label_roadmap_due_in: "Due in %{value}"
-  label_roadmap_overdue: "ÐšÐ°ÑÐ½Ð¸ %{value}"
-  label_roadmap_no_issues: ÐÐµÐ¼Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð·Ð° Ð¾Ð²Ð°Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
-  label_search: Ð‘Ð°Ñ€Ð°Ñ˜
-  label_result_plural: Ð ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸
-  label_all_words: Ð¡Ð¸Ñ‚Ðµ Ð·Ð±Ð¾Ñ€Ð¾Ð²Ð¸
-  label_wiki: Ð’Ð¸ÐºÐ¸
-  label_wiki_edit: Ð’Ð¸ÐºÐ¸ ÑƒÑ€ÐµÐ´ÑƒÐ²Ð°ÑšÐµ
-  label_wiki_edit_plural: Ð’Ð¸ÐºÐ¸ ÑƒÑ€ÐµÐ´ÑƒÐ²Ð°ÑšÐ°
-  label_wiki_page: Ð’Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  label_wiki_page_plural: Ð’Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
-  label_index_by_title: Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Ð½Ð°ÑÐ»Ð¾Ð²
-  label_index_by_date: Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Ð´Ð°Ñ‚Ð°
-  label_current_version: Current version
-  label_preview: Preview
-  label_feed_plural: Feeds
-  label_changes_details: Ð”ÐµÑ‚Ð°Ð»Ð¸ Ð·Ð° ÑÐ¸Ñ‚Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸
-  label_issue_tracking: Ð¡Ð»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_spent_time: ÐŸÐ¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_overall_spent_time: Ð’ÐºÑƒÐ¿Ð½Ð¾ Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_f_hour: "%{value} Ñ‡Ð°Ñ"
-  label_f_hour_plural: "%{value} Ñ‡Ð°ÑÐ°"
-  label_time_tracking: Ð¡Ð»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
-  label_change_plural: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸
-  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ¸
-  label_commits_per_month: Commits per month
-  label_commits_per_author: Commits per author
-  label_view_diff: View differences
-  label_diff_inline: inline
-  label_diff_side_by_side: side by side
-  label_options: ÐžÐ¿Ñ†Ð¸Ð¸
-  label_copy_workflow_from: Copy workflow from
-  label_permissions_report: Permissions report
-  label_watched_issues: Watched issues
-  label_related_issues: ÐŸÐ¾Ð²Ñ€Ð·Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_applied_status: Applied status
-  label_loading: Loading...
-  label_relation_new: ÐÐ¾Ð²Ð° Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ˜Ð°
-  label_relation_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ˜Ð°
-  label_relates_to: related to
-  label_duplicates: Ð´ÑƒÐ¿Ð»Ð¸ÐºÐ°Ñ‚Ð¸
-  label_duplicated_by: duplicated by
-  label_blocks: blocks
-  label_blocked_by: Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð°Ð½Ð¾ Ð¾Ð´
-  label_precedes: Ð¿Ñ€ÐµÑ‚Ñ…Ð¾Ð´Ð¸
-  label_follows: ÑÐ»ÐµÐ´Ð¸
-  label_end_to_start: ÐºÑ€Ð°Ñ˜ Ð´Ð¾ Ð¿Ð¾Ñ‡ÐµÑ‚Ð¾Ðº
-  label_end_to_end: ÐºÑ€Ð°Ñ˜ Ð´Ð¾ ÐºÑ€Ð°Ñ˜
-  label_start_to_start: Ð¿Ð¾Ñ‡ÐµÑ‚Ð¾Ðº Ð´Ð¾ Ð¿Ð¾Ñ‡ÐµÑ‚Ð¾Ðº
-  label_start_to_end: Ð¿Ð¾Ñ‡ÐµÑ‚Ð¾Ðº Ð´Ð¾ ÐºÑ€Ð°Ñ˜
-  label_stay_logged_in: ÐžÑÑ‚Ð°Ð½ÐµÑ‚Ðµ Ð½Ð°Ñ˜Ð°Ð²ÐµÐ½Ð¸
-  label_disabled: disabled
-  label_show_completed_versions: Show completed versions
-  label_me: Ñ˜Ð°Ñ
-  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
-  label_board_new: ÐÐ¾Ð² Ñ„Ð¾Ñ€ÑƒÐ¼
-  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
-  label_board_locked: Ð—Ð°ÐºÐ»ÑƒÑ‡ÐµÐ½
-  label_board_sticky: Sticky
-  label_topic_plural: Ð¢ÐµÐ¼Ð¸
-  label_message_plural: ÐŸÐ¾Ñ€Ð°ÐºÐ¸
-  label_message_last: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ð¿Ð¾Ñ€Ð°ÐºÐ°
-  label_message_new: ÐÐ¾Ð²Ð° Ð¿Ð¾Ñ€Ð°ÐºÐ°
-  label_message_posted: ÐŸÐ¾Ñ€Ð°ÐºÐ°Ñ‚Ðµ Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
-  label_reply_plural: ÐžÐ´Ð³Ð¾Ð²Ð¾Ñ€Ð¸
-  label_send_information: Ð˜ÑÐ¿Ñ€Ð°Ñ‚Ð¸ Ð³Ð¸ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸Ñ‚Ðµ Ð·Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð¾Ñ‚ Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ¾Ñ‚
-  label_year: Ð“Ð¾Ð´Ð¸Ð½Ð°
-  label_month: ÐœÐµÑÐµÑ†
-  label_week: ÐÐµÐ´ÐµÐ»Ð°
-  label_date_from: ÐžÐ´
-  label_date_to: Ð”Ð¾
-  label_language_based: Ð¡Ð¿Ð¾Ñ€ÐµÐ´ Ñ˜Ð°Ð·Ð¸ÐºÐ¾Ñ‚ Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ¾Ñ‚
-  label_sort_by: "ÐŸÐ¾Ð´Ñ€ÐµÐ´Ð¸ ÑÐ¿Ð¾Ñ€ÐµÐ´ %{value}"
-  label_send_test_email: Ð˜ÑÐ¿Ñ€Ð°Ñ‚Ð¸ Ñ‚ÐµÑÑ‚ Ðµ-Ð¿Ð¾Ñ€Ð°ÐºÐ°
-  label_feeds_access_key: RSS ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿
-  label_missing_feeds_access_key: ÐÐµÐ´Ð¾ÑÑ‚Ð¸ÐºÐ° RSS ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿
-  label_feeds_access_key_created_on: "RSS ÐºÐ»ÑƒÑ‡Ð¾Ñ‚ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½ Ð¿Ñ€ÐµÐ´ %{value}"
-  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ð¸
-  label_added_time_by: "Ð”Ð¾Ð´Ð°Ð´ÐµÐ½Ð¾ Ð¾Ð´ %{author} Ð¿Ñ€ÐµÐ´ %{age}"
-  label_updated_time_by: "ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾ Ð¾Ð´ %{author} Ð¿Ñ€ÐµÐ´ %{age}"
-  label_updated_time: "ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾ Ð¿Ñ€ÐµÐ´ %{value}"
-  label_jump_to_a_project: ÐŸÑ€ÐµÑ„Ñ€Ð»Ð¸ ÑÐµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚...
-  label_file_plural: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ¸
-  label_changeset_plural: Changesets
-  label_default_columns: ÐžÑÐ½Ð¾Ð²Ð½Ð¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸
-  label_no_change_option: (Ð‘ÐµÐ· Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°)
-  label_bulk_edit_selected_issues: Ð“Ñ€ÑƒÐ¿Ð½Ð¾ ÑƒÑ€ÐµÐ´ÑƒÐ²Ð°ÑšÐµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_theme: Ð¢ÐµÐ¼Ð°
-  label_default: Default
-  label_search_titles_only: ÐŸÑ€ÐµÐ±Ð°Ñ€ÑƒÐ²Ð°Ñ˜ ÑÐ°Ð¼Ð¾ Ð½Ð°ÑÐ»Ð¾Ð²Ð¸
-  label_user_mail_option_all: "Ð—Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ˜ Ð½Ð°ÑÑ‚Ð°Ð½ Ð²Ð¾ ÑÐ¸Ñ‚Ðµ Ð¼Ð¾Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
-  label_user_mail_option_selected: "Ð—Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ˜ Ð½Ð°ÑÑ‚Ð°Ð½ ÑÐ°Ð¼Ð¾ Ð²Ð¾ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸..."
-  label_user_mail_no_self_notified: "ÐÐµ Ð¼Ðµ Ð¸Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°Ñ˜ Ð·Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸Ñ‚Ðµ ÑˆÑ‚Ð¾ Ñ˜Ð°Ñ Ð³Ð¸ Ð¿Ñ€Ð°Ð²Ð°Ð¼"
-  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ð¿Ñ€ÐµÐºÑƒ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð°
-  label_registration_manual_activation: Ð¼Ð°Ð½ÑƒÐµÐ»Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»
-  label_registration_automatic_activation: Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»
-  label_display_per_page: "ÐŸÐ¾ ÑÑ‚Ñ€Ð°Ð½Ð°: %{value}"
-  label_age: Age
-  label_change_properties: Change properties
-  label_general: ÐžÐ¿ÑˆÑ‚Ð¾
-  label_more: ÐŸÐ¾Ð²ÐµÑœÐµ
-  label_scm: SCM
-  label_plugins: Ð”Ð¾Ð´Ð°Ñ‚Ð¾Ñ†Ð¸
-  label_ldap_authentication: LDAP Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
-  label_downloads_abbr: ÐŸÑ€ÐµÐ²Ð·ÐµÐ¼Ð°ÑšÐ°
-  label_optional_description: ÐžÐ¿Ð¸Ñ (Ð½ÐµÐ·Ð°Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾)
-  label_add_another_file: Ð”Ð¾Ð´Ð°Ð´Ð¸ ÑƒÑˆÑ‚Ðµ ÐµÐ´Ð½Ð° Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
-  label_preferences: Preferences
-  label_chronological_order: Ð’Ð¾ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾ÑˆÐºÐ¸ Ñ€ÐµÐ´
-  label_reverse_chronological_order: In reverse chronological order
-  label_planning: ÐŸÐ»Ð°Ð½Ð¸Ñ€Ð°ÑšÐµ
-  label_incoming_emails: Ð”Ð¾Ñ˜Ð´Ð¾Ð²Ð½Ð¸ Ðµ-Ð¿Ð¾Ñ€Ð°ÐºÐ¸
-  label_generate_key: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ñ˜ ÐºÐ»ÑƒÑ‡
-  label_issue_watchers: Watchers
-  label_example: ÐŸÑ€Ð¸Ð¼ÐµÑ€
-  label_display: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸
-  label_sort: ÐŸÐ¾Ð´Ñ€ÐµÐ´Ð¸
-  label_ascending: Ð Ð°ÑÑ‚ÐµÑ‡ÐºÐ¸
-  label_descending: ÐžÐ¿Ð°Ñ“Ð°Ñ‡ÐºÐ¸
-  label_date_from_to: ÐžÐ´ %{start} Ð´Ð¾ %{end}
-  label_wiki_content_added: Ð’Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
-  label_wiki_content_updated: Ð’Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°
-  label_group: Ð“Ñ€ÑƒÐ¿Ð°
-  label_group_plural: Ð“Ñ€ÑƒÐ¿Ð¸
-  label_group_new: ÐÐ¾Ð²Ð° Ð³Ñ€ÑƒÐ¿Ð°
-  label_time_entry_plural: ÐŸÐ¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
-  label_version_sharing_none: ÐÐµ ÑÐ¿Ð¾Ð´ÐµÐ»ÐµÐ½Ð¾
-  label_version_sharing_descendants: Ð¡Ð¾ ÑÐ¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_version_sharing_hierarchy: Ð¡Ð¾ Ñ…Ð¸ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ˜Ð°Ñ‚Ð° Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
-  label_version_sharing_tree: Ð¡Ð¾ Ð´Ñ€Ð²Ð¾Ñ‚Ð¾ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
-  label_version_sharing_system: Ð¡Ð¾ ÑÐ¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_update_issue_done_ratios: Update issue done ratios
-  label_copy_source: Ð˜Ð·Ð²Ð¾Ñ€
-  label_copy_target: Ð”ÐµÑÑ‚Ð¸Ð½Ð°Ñ†Ð¸Ñ˜Ð°
-  label_copy_same_as_target: Ð˜ÑÑ‚Ð¾ ÐºÐ°ÐºÐ¾ Ð´ÐµÑÑ‚Ð¸Ð½Ð°Ñ†Ð¸Ñ˜Ð°Ñ‚Ð°
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_api_access_key: API ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿
-  label_missing_api_access_key: ÐÐµÐ´Ð¾ÑÑ‚Ð¸Ð³Ð° API ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿
-  label_api_access_key_created_on: "API ÐºÐ»ÑƒÑ‡Ð¾Ñ‚ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿ Ðµ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½ Ð¿Ñ€ÐµÐ´ %{value}"
-  label_profile: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
-  label_subtask_plural: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_project_copy_notifications: ÐŸÑ€Ð°ÑœÐ°Ñ˜ Ð¸Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°ÑšÐ° Ð¿Ð¾ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð° Ð¿Ñ€Ð¸ ÐºÐ¾Ð¿Ð¸Ñ€Ð°ÑšÐµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
-
-  button_login: ÐÐ°Ñ˜Ð°Ð²Ð¸ ÑÐµ
-  button_submit: Ð˜ÑÐ¿Ñ€Ð°Ñ‚Ð¸
-  button_save: Ð—Ð°Ñ‡ÑƒÐ²Ð°Ñ˜
-  button_check_all: Ð¨Ñ‚Ð¸ÐºÐ»Ð¸Ñ€Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ
-  button_uncheck_all: ÐžÐ´ÑˆÑ‚Ð¸ÐºÐ»Ð¸Ñ€Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ
-  button_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸
-  button_create: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜
-  button_create_and_continue: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜ Ð¸ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸
-  button_test: Ð¢ÐµÑÑ‚
-  button_edit: Ð£Ñ€ÐµÐ´Ð¸
-  button_add: Ð”Ð¾Ð´Ð°Ð´Ð¸
-  button_change: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸
-  button_apply: ÐŸÑ€Ð¸Ð¼ÐµÐ½Ð¸
-  button_clear: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸
-  button_lock: Ð—Ð°ÐºÐ»ÑƒÑ‡Ð¸
-  button_unlock: ÐžÑ‚ÐºÐ»ÑƒÑ‡Ð¸
-  button_download: ÐŸÑ€ÐµÐ²Ð·ÐµÐ¼Ð¸
-  button_list: List
-  button_view: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜
-  button_move: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸
-  button_move_and_follow: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð¸ ÑÐ»ÐµÐ´Ð¸
-  button_back: Back
-  button_cancel: ÐžÑ‚ÐºÐ°Ð¶Ð¸
-  button_activate: ÐÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
-  button_sort: ÐŸÐ¾Ð´Ñ€ÐµÐ´Ð¸
-  button_log_time: Ð‘ÐµÐ»ÐµÐ¶Ð¸ Ð²Ñ€ÐµÐ¼Ðµ
-  button_rollback: Rollback to this version
-  button_watch: Ð¡Ð»ÐµÐ´Ð¸
-  button_unwatch: ÐÐµ ÑÐ»ÐµÐ´Ð¸
-  button_reply: ÐžÐ´Ð³Ð¾Ð²Ð¾Ñ€Ð¸
-  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
-  button_unarchive: ÐžÐ´Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
-  button_reset: Reset
-  button_rename: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ˜
-  button_change_password: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
-  button_copy: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜
-  button_copy_and_follow: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜ Ð¸ ÑÐ»ÐµÐ´Ð¸
-  button_annotate: Annotate
-  button_update: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ñ˜
-  button_configure: ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ñ˜
-  button_quote: Ð¦Ð¸Ñ‚Ð¸Ñ€Ð°Ñ˜
-  button_duplicate: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜
-  button_show: Show
-
-  status_active: Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¸
-  status_registered: Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½Ð¸
-  status_locked: Ð·Ð°ÐºÐ»ÑƒÑ‡ÐµÐ½Ð¸
-
-  version_status_open: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-  version_status_locked: Ð·Ð°ÐºÐ»ÑƒÑ‡ÐµÐ½Ð¸
-  version_status_closed: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
-
-  field_active: Active
-
-  text_select_mail_notifications: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð·Ð° ÐºÐ¾Ð¸ Ð½Ð°ÑÑ‚Ð°Ð½Ð¸ Ð´Ð° ÑÐµ Ð¿Ñ€Ð°ÑœÐ°Ð°Ñ‚ Ð¸Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°ÑšÐ° Ð¿Ð¾ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð° Ð´Ð° ÑÐµ Ð¿Ñ€Ð°ÑœÐ°Ð°Ñ‚.
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 Ð·Ð½Ð°Ñ‡Ð¸ Ð±ÐµÐ· Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÑƒÐ²Ð°ÑšÐµ
-  text_project_destroy_confirmation: Ð”Ð°Ð»Ð¸ ÑÑ‚Ðµ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´ÐµÐºÐ° ÑÐ°ÐºÐ°Ñ‚Ðµ Ð´Ð° Ð³Ð¾ Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚ Ð¸ ÑÐ¸Ñ‚Ðµ Ð¿Ð¾Ð²Ñ€Ð·Ð°Ð½Ð¸ Ð¿Ð¾Ð´Ð°Ñ‚Ð¾Ñ†Ð¸?
-  text_subprojects_destroy_warning: "ÐÐµÐ³Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸: %{value} Ð¸ÑÑ‚Ð¾ Ñ‚Ð°ÐºÐ° ÑœÐµ Ð±Ð¸Ð´Ð°Ñ‚ Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐ°Ð½Ð¸."
-  text_workflow_edit: Select a role and a tracker to edit the workflow
-  text_are_you_sure: Ð”Ð°Ð»Ð¸ ÑÑ‚Ðµ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸?
-  text_journal_changed: "%{label} Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÑ‚Ð¾ Ð¾Ð´ %{old} Ð²Ð¾ %{new}"
-  text_journal_set_to: "%{label} set to %{value}"
-  text_journal_deleted: "%{label} Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐ°Ð½ (%{old})"
-  text_journal_added: "%{label} %{value} Ð´Ð¾Ð´Ð°Ð´ÐµÐ½"
-  text_tip_issue_begin_day: Ð·Ð°Ð´Ð°Ñ‡Ð¸ ÑˆÑ‚Ð¾ Ð¿Ð¾Ñ‡Ð½ÑƒÐ²Ð°Ð°Ñ‚ Ð¾Ð²Ð¾Ñ˜ Ð´ÐµÐ½
-  text_tip_issue_end_day: Ð·Ð°Ð´Ð°Ñ‡Ð¸ ÑˆÑ‚Ð¾ Ð·Ð°Ð²Ñ€ÑˆÑƒÐ²Ð°Ð°Ñ‚ Ð¾Ð²Ð¾Ñ˜ Ð´ÐµÐ½
-  text_tip_issue_begin_end_day: Ð·Ð°Ð´Ð°Ñ‡Ð¸ ÑˆÑ‚Ð¾ Ð¿Ð¾Ñ‡Ð½ÑƒÐ²Ð°Ð°Ñ‚ Ð¸ Ð·Ð°Ð²Ñ€ÑˆÑƒÐ²Ð°Ð°Ñ‚ Ð¾Ð²Ð¾Ñ˜ Ð´ÐµÐ½
-  text_project_identifier_info: 'Ð¡Ð°Ð¼Ð¾ Ð¼Ð°Ð»Ð¸ Ð±ÑƒÐºÐ²Ð¸ (a-z), Ð±Ñ€Ð¾Ñ˜ÐºÐ¸ Ð¸ dashes ÑÐµ Ð´Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸<br />ÐŸÐ¾ Ð·Ð°Ñ‡ÑƒÐ²ÑƒÐ²Ð°ÑšÐµÑ‚Ð¾, Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ñ‚ Ð½ÐµÐ¼Ð¾Ð¶Ðµ Ð´Ð° ÑÐµ ÑÐ¼ÐµÐ½Ð¸.'
-  text_caracters_maximum: "%{count} Ð·Ð½Ð°Ñ†Ð¸ Ð¼Ð°ÐºÑÐ¸Ð¼ÑƒÐ¼."
-  text_caracters_minimum: "ÐœÐ¾Ñ€Ð° Ð´Ð° Ðµ Ð½Ð°Ñ˜Ð¼Ð°Ð»ÐºÑƒ %{count} Ð·Ð½Ð°Ñ†Ð¸ Ð´Ð¾Ð»Ð³Ð¾."
-  text_length_between: "Ð”Ð¾Ð»Ð¶Ð¸Ð½Ð° Ð¿Ð¾Ð¼ÐµÑ“Ñƒ %{min} Ð¸ %{max} Ð·Ð½Ð°Ñ†Ð¸."
-  text_tracker_no_workflow: No workflow defined for this tracker
-  text_unallowed_characters: ÐÐµÐ´Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ Ð·Ð½Ð°Ñ†Ð¸
-  text_comma_separated: Ð”Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐµ Ð¿Ð¾Ð²ÐµÑœÐµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸ (Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸ ÑÐ¾ Ð·Ð°Ð¿Ð¸Ñ€ÐºÐ°).
-  text_line_separated: Ð”Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐµ Ð¿Ð¾Ð²ÐµÑœÐµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸ (ÐµÐ´Ð½Ð° Ð»Ð¸Ð½Ð¸Ñ˜Ð° Ð·Ð° ÑÐµÐºÐ¾Ñ˜Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚).
-  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
-  text_issue_added: "Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° %{id} Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²ÐµÐ½Ð° Ð¾Ð´ %{author}."
-  text_issue_updated: "Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° %{id} Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð° Ð¾Ð´ %{author}."
-  text_wiki_destroy_confirmation: Ð”Ð°Ð»Ð¸ ÑÑ‚Ðµ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´ÐµÐºÐ° ÑÐ°ÐºÐ°Ñ‚Ðµ Ð´Ð° Ð³Ð¾ Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¾Ð²Ð° Ð²Ð¸ÐºÐ¸ Ð¸ Ñ†ÐµÐ»Ð°Ñ‚Ð° Ð½ÐµÐ³Ð¾Ð²Ð° ÑÐ¾Ð´Ñ€Ð¶Ð¸Ð½Ð°?
-  text_issue_category_destroy_question: "ÐÐµÐºÐ¾Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸ (%{count}) ÑÐµ Ð´Ð¾Ð´ÐµÐ»ÐµÐ½Ð¸ Ð½Ð° Ð¾Ð²Ð°Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°. Ð¨Ñ‚Ð¾ ÑÐ°ÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ðµ?"
-  text_issue_category_destroy_assignments: Remove category assignments
-  text_issue_category_reassign_to: Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð³Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ Ð½Ð° Ð¾Ð²Ð°Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
-  text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
-  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
-  text_load_default_configuration: Load the default configuration
-  text_status_changed_by_changeset: "Applied in changeset %{value}."
-  text_issues_destroy_confirmation: 'Ð”Ð°Ð»Ð¸ ÑÑ‚Ðµ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´ÐµÐºÐ° ÑÐ°ÐºÐ°Ñ‚Ðµ Ð´Ð° Ð³Ð¸ Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸?'
-  text_select_project_modules: 'Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð·Ð° Ð¾Ð²Ð¾Ñ˜ Ð¿Ñ€Ð¾ÐµÐºÑ‚:'
-  text_default_administrator_account_changed: Default administrator account changed
-  text_file_repository_writable: Ð’Ð¾ Ð¿Ð°Ð¿ÐºÐ°Ñ‚Ð° Ð·Ð° Ð¿Ñ€Ð¸Ð»Ð¾Ð·Ð¸ Ð¼Ð¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð·Ð°Ð¿Ð¸ÑˆÑƒÐ²Ð°
-  text_plugin_assets_writable: Ð’Ð¾ Ð¿Ð°Ð¿ÐºÐ°Ñ‚Ð° Ð·Ð° Ð´Ð¾Ð´Ð°Ñ‚Ð¾Ñ†Ð¸ Ð¼Ð¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð·Ð°Ð¿Ð¸ÑˆÑƒÐ²Ð°
-  text_rmagick_available: RMagick available (Ð½ÐµÐ·Ð°Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾)
-  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do ?"
-  text_destroy_time_entries: Delete reported hours
-  text_assign_time_entries_to_project: Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð³Ð¸ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²ÐµÐ½Ð¸Ñ‚Ðµ Ñ‡Ð°ÑÐ¾Ð²Ð¸ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
-  text_reassign_time_entries: 'Reassign reported hours to this issue:'
-  text_user_wrote: "%{value} Ð½Ð°Ð¿Ð¸ÑˆÐ°:"
-  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
-  text_enumeration_category_reassign_to: 'Reassign them to this value:'
-  text_email_delivery_not_configured: "Ð”Ð¾ÑÑ‚Ð°Ð²Ð°Ñ‚Ð° Ð¿Ð¾ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð° Ð½Ðµ Ðµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°, Ð¸ Ð¸Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°ÑšÐ°Ñ‚Ð° ÑÐµ Ð¾Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶ÐµÐ½Ð¸.\nÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ñ˜Ñ‚Ðµ Ð³Ð¾ Ð’Ð°ÑˆÐ¸Ð¾Ñ‚  SMTP ÑÐµÑ€Ð²ÐµÑ€ Ð²Ð¾ config/configuration.yml Ð¸ Ñ€ÐµÑÑ‚Ð°Ñ€Ñ‚Ð¸Ñ€Ð°Ñ˜Ñ‚Ðµ Ñ˜Ð° Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°Ñ‚Ð°."
-  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
-  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
-  text_custom_field_possible_values_info: 'One line for each value'
-  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
-  text_wiki_page_nullify_children: "Keep child pages as root pages"
-  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
-  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
-  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
-  text_zoom_in: Zoom in
-  text_zoom_out: Zoom out
-
-  default_role_manager: ÐœÐµÐ½Ð°ÑŸÐµÑ€
-  default_role_developer: Developer
-  default_role_reporter: Reporter
-  default_tracker_bug: Ð“Ñ€ÐµÑˆÐºÐ°
-  default_tracker_feature: Ð¤ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð°Ð»Ð½Ð¾ÑÑ‚
-  default_tracker_support: ÐŸÐ¾Ð´Ð´Ñ€ÑˆÐºÐ°
-  default_issue_status_new: ÐÐ¾Ð²Ð°
-  default_issue_status_in_progress: Ð’Ð¾ Ð¿Ñ€Ð¾Ð³Ñ€ÐµÑ
-  default_issue_status_resolved: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð°
-  default_issue_status_feedback: Feedback
-  default_issue_status_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
-  default_issue_status_rejected: ÐžÐ´Ð±Ð¸ÐµÐ½Ð°
-  default_doc_category_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ˜Ð°
-  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸Ñ‡ÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ˜Ð°
-  default_priority_low: ÐÐ¸Ð·Ð¾Ðº
-  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»ÐµÐ½
-  default_priority_high: Ð’Ð¸ÑÐ¾Ðº
-  default_priority_urgent: Ð˜Ñ‚Ð½Ð¾
-  default_priority_immediate: Ð’ÐµÐ´Ð½Ð°Ñˆ
-  default_activity_design: Ð”Ð¸Ð·Ð°Ñ˜Ð½
-  default_activity_development: Ð Ð°Ð·Ð²Ð¾Ñ˜
-
-  enumeration_issue_priorities: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  enumeration_activities: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð¸ (ÑÐ»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ)
-  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼ÑÐºÐ° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
-
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Commit messages encoding
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/519546b54485a90980ee98464e417cc62979df94.svn-base
--- a/.svn/pristine/51/519546b54485a90980ee98464e417cc62979df94.svn-base
+++ /dev/null
@@ -1,26 +0,0 @@
-module CodeRay
-  module Scanners
-    
-    # Scanner for plain text.
-    # 
-    # Yields just one token of the kind :plain.
-    # 
-    # Alias: +plaintext+, +plain+
-    class Text < Scanner
-      
-      register_for :text
-      title 'Plain text'
-      
-      KINDS_NOT_LOC = [:plain]  # :nodoc:
-      
-    protected
-      
-      def scan_tokens encoder, options
-        encoder.text_token string, :plain
-        encoder
-      end
-      
-    end
-    
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/519b223dadd478a188b887acb238e809d1e44602.svn-base
--- /dev/null
+++ b/.svn/pristine/51/519b223dadd478a188b887acb238e809d1e44602.svn-base
@@ -0,0 +1,1 @@
+$('#attachments_<%= j params[:attachment_id] %>').remove();
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/51b00c88d6dde33f6379ec80045abcc086071077.svn-base
--- /dev/null
+++ b/.svn/pristine/51/51b00c88d6dde33f6379ec80045abcc086071077.svn-base
@@ -0,0 +1,1086 @@
+sk:
+  direction: ltr
+  date:
+    formats:
+      default: "%Y-%m-%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [NedeÄ¾a, Pondelok, Utorok, Streda, Å tvrtok, Piatok, Sobota]
+    abbr_day_names: [Ne, Po, Ut, St, Å t, Pi, So]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, JanuÃ¡r, FebruÃ¡r, Marec, AprÃ­l, MÃ¡j, JÃºn, JÃºl, August, September, OktÃ³ber, November, December]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, MÃ¡j, JÃºn, JÃºl, Aug, Sep, Okt, Nov, Dec]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pol minÃºty"
+      less_than_x_seconds:
+        one:   "menej ako 1 sekunda"
+        other: "menej ako %{count} sekÃºnd"
+      x_seconds:
+        one:   "1 sekunda"
+        other: "%{count} sekÃºnd"
+      less_than_x_minutes:
+        one:   "menej ako minÃºta"
+        other: "menej ako %{count} minÃºt"
+      x_minutes:
+        one:   "1 minuta"
+        other: "%{count} minÃºt"
+      about_x_hours:
+        one:   "okolo 1 hodiny"
+        other: "okolo %{count} hodÃ­n"
+      x_hours:
+        one:   "1 hodina"
+        other: "%{count} hodÃ­n"
+      x_days:
+        one:   "1 deÅˆ"
+        other: "%{count} dnÃ­"
+      about_x_months:
+        one:   "okolo 1 mesiaca"
+        other: "okolo %{count} mesiace/ov"
+      x_months:
+        one:   "1 mesiac"
+        other: "%{count} mesiace/ov"
+      about_x_years:
+        one:   "okolo 1 roka"
+        other: "okolo %{count} roky/ov"
+      over_x_years:
+        one:   "cez 1 rok"
+        other: "cez %{count} roky/ov"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+
+    human:
+      format:
+        precision: 3
+        delimiter: ""
+      storage_units:
+        format: "%n %u"
+        units:
+          kb: KB
+          tb: TB
+          gb: GB
+          byte:
+            one: Byte
+            other: Bytes
+          mb: MB
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "a"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "nieje zahrnutÃ© v zozname"
+        exclusion: "je rezervovanÃ©"
+        invalid: "je neplatnÃ©"
+        confirmation: "sa nezhoduje s potvrdenÃ­m"
+        accepted: "musÃ­ byÅ¥ akceptovanÃ©"
+        empty: "nemÃ´Å¾e byÅ¥ prÃ¡zdne"
+        blank: "nemÃ´Å¾e byÅ¥ prÃ¡zdne"
+        too_long: "je prÃ­liÅ¡ dlhÃ©"
+        too_short: "je prÃ­liÅ¡ krÃ¡tke"
+        wrong_length: "mÃ¡ chybnÃº dÄºÅ¾ku"
+        taken: "je uÅ¾ pouÅ¾itÃ©"
+        not_a_number: "nieje ÄÃ­slo"
+        not_a_date: "nieje platnÃ½ dÃ¡tum"
+        greater_than: "musÃ­ byÅ¥ vÃ¤ÄÅ¡Ã­e ako %{count}"
+        greater_than_or_equal_to: "musÃ­ byÅ¥ vÃ¤ÄÅ¡ie alebo rovnÃ© %{count}"
+        equal_to: "musÃ­ byÅ¥ rovnÃ© %{count}"
+        less_than: "musÃ­ byÅ¥ menej ako %{count}"
+        less_than_or_equal_to: "musÃ­ byÅ¥ menej alebo rovnÃ© %{count}"
+        odd: "musÃ­ byÅ¥ nepÃ¡rne"
+        even: "musÃ­ byÅ¥ pÃ¡rne"
+        greater_than_start_date: "musÃ­ byÅ¥ neskÃ´r ako poÄiatoÄnÃ½ dÃ¡tum"
+        not_same_project: "nepatrÃ­ rovnakÃ©mu projektu"
+        circular_dependency: "Tento vzÅ¥ah by vytvoril cyklickÃº zÃ¡vislosÅ¥"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  # SK translation by Stanislav Pach | stano.pach@seznam.cz
+
+  actionview_instancetag_blank_option: ProsÃ­m vyberte
+
+  general_text_No: 'Nie'
+  general_text_Yes: 'Ãno'
+  general_text_no: 'nie'
+  general_text_yes: 'Ã¡no'
+  general_lang_name: 'SlovenÄina'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: ÃšÄet bol ÃºspeÅ¡ne zmenenÃ½.
+  notice_account_invalid_creditentials: ChybnÃ© meno alebo heslo
+  notice_account_password_updated: Heslo bolo ÃºspeÅ¡ne zmenenÃ©.
+  notice_account_wrong_password: ChybnÃ© heslo
+  notice_account_register_done: ÃšÄet bol ÃºspeÅ¡ne vytvorenÃ½. Pre aktivÃ¡ciu ÃºÄtu kliknite na odkaz v emailu, ktorÃ½ vam bol zaslanÃ½.
+  notice_account_unknown_email: NeznÃ¡my uÅ¾Ã­vateÄ¾.
+  notice_can_t_change_password: Tento ÃºÄet pouÅ¾Ã­va externÃº autentifikÃ¡ciu. Tu heslo zmeniÅ¥ nemÃ´Å¾ete.
+  notice_account_lost_email_sent: Bol vÃ¡m zaslanÃ½ email s inÅ¡trukciami ako si nastavite novÃ© heslo.
+  notice_account_activated: VÃ¡Å¡ ÃºÄet bol aktivovanÃ½. Teraz se mÃ´Å¾ete prihlÃ¡siÅ¥.
+  notice_successful_create: ÃšspeÅ¡ne vytvorenÃ©.
+  notice_successful_update: ÃšspeÅ¡ne aktualizovanÃ©.
+  notice_successful_delete: ÃšspeÅ¡ne odstrÃ¡nenÃ©.
+  notice_successful_connection: ÃšspeÅ¡ne pripojenÃ©.
+  notice_file_not_found: StrÃ¡nka, ktorÃº se snaÅ¾Ã­te zobraziÅ¥, neexistuje alebo bola zmazanÃ¡.
+  notice_locking_conflict: Ãšdaje boli zmenenÃ© inÃ½m uÅ¾Ã­vateÄ¾om.
+  notice_scm_error: PoloÅ¾ka a/alebo revÃ­zia neexistuje v repozitÃ¡ri.
+  notice_not_authorized: NemÃ¡te dostatoÄnÃ© prÃ¡va pre zobrazenie tejto strÃ¡nky.
+  notice_email_sent: "Na adresu %{value} bol odeslanÃ½ email"
+  notice_email_error: "Pri odosielanÃ­ emailu nastala chyba (%{value})"
+  notice_feeds_access_key_reseted: VÃ¡Å¡ klÃºÄ pre prÃ­stup k Atomu bol resetovanÃ½.
+  notice_failed_to_save_issues: "Nastala chyba pri uklÃ¡danÃ­ %{count} Ãºloh na %{total} zvolenÃ½: %{ids}."
+  notice_no_issue_selected: "Nebola zvolenÃ¡ Å¾iadnÃ¡ Ãºloha. ProsÃ­m, zvoÄ¾te Ãºlohy, ktorÃ© chcete upraviÅ¥"
+  notice_account_pending: "VÃ¡Å¡ ÃºÄet bol vytvorenÃ½, teraz ÄakÃ¡ na schvÃ¡lenie administrÃ¡torom."
+  notice_default_data_loaded: VÃ½chozia konfigurÃ¡cia ÃºspeÅ¡ne nahranÃ¡.
+
+  error_can_t_load_default_data: "VÃ½chozia konfigurÃ¡cia nebola nahranÃ¡: %{value}"
+  error_scm_not_found: "PoloÅ¾ka a/alebo revÃ­zia neexistuje v repozitÃ¡ri."
+  error_scm_command_failed: "Pri pokuse o prÃ­stup k repozitÃ¡ri doÅ¡lo k chybe: %{value}"
+  error_issue_not_found_in_project: 'Ãšloha nebola nÃ¡jdenÃ¡ alebo nepatrÃ­ k tomuto projektu'
+
+  mail_subject_lost_password: "VaÅ¡e heslo (%{value})"
+  mail_body_lost_password: 'Pre zmenu vaÅ¡eho hesla kliknite na nÃ¡sledujÃºci odkaz:'
+  mail_subject_register: "AktivÃ¡cia ÃºÄtu (%{value})"
+  mail_body_register: 'Pre aktivÃ¡ciu vaÅ¡eho ÃºÄtu kliknite na nÃ¡sledujÃºci odkaz:'
+  mail_body_account_information_external: "Pomocou vaÅ¡eho ÃºÄtu %{value} se mÃ´Å¾ete prihlÃ¡siÅ¥."
+  mail_body_account_information: InformÃ¡cie o vaÅ¡om ÃºÄte
+  mail_subject_account_activation_request: "AktivÃ¡cia %{value} ÃºÄtu"
+  mail_body_account_activation_request: "Bol zaregistrovanÃ½ novÃ½ uÅ¾ivateÄ¾ %{value}. AktivÃ¡cia jeho ÃºÄtu zÃ¡visÃ­ na vaÅ¡om potvrdenÃ­."
+
+
+  field_name: NÃ¡zov
+  field_description: Popis
+  field_summary: PrehÄ¾ad
+  field_is_required: PovinnÃ© pole
+  field_firstname: Meno
+  field_lastname: Priezvisko
+  field_mail: Email
+  field_filename: SÃºbor
+  field_filesize: VeÄ¾kosÅ¥
+  field_downloads: StiahnutÃ©
+  field_author: Autor
+  field_created_on: VytvorenÃ©
+  field_updated_on: AktualizovanÃ©
+  field_field_format: FormÃ¡t
+  field_is_for_all: Pre vÅ¡etky projekty
+  field_possible_values: MoÅ¾nÃ© hodnoty
+  field_regexp: RegulÃ©rny vÃ½raz
+  field_min_length: MinimÃ¡lna dÄºÅ¾ka
+  field_max_length: MaximÃ¡lna dÄºÅ¾ka
+  field_value: Hodnota
+  field_category: KategÃ³ria
+  field_title: NÃ¡zov
+  field_project: Projekt
+  field_issue: Ãšloha
+  field_status: Stav
+  field_notes: PoznÃ¡mka
+  field_is_closed: Ãšloha uzavretÃ¡
+  field_is_default: VÃ½chodzÃ­ stav
+  field_tracker: Fronta
+  field_subject: Predmet
+  field_due_date: UzavrieÅ¥ do
+  field_assigned_to: PriradenÃ©
+  field_priority: Priorita
+  field_fixed_version: PriradenÃ© k verzii
+  field_user: UÅ¾Ã­vateÄ¾
+  field_role: Rola
+  field_homepage: DomovskÃ¡ strÃ¡nka
+  field_is_public: VerejnÃ½
+  field_parent: NadradenÃ½ projekt
+  field_is_in_roadmap: Ãšlohy zobrazenÃ© v plÃ¡ne
+  field_login: Login
+  field_mail_notification: EmailovÃ© oznÃ¡menie
+  field_admin: AdministrÃ¡tor
+  field_last_login_on: PoslednÃ© prihlÃ¡senie
+  field_language: Jazyk
+  field_effective_date: DÃ¡tum
+  field_password: Heslo
+  field_new_password: NovÃ© heslo
+  field_password_confirmation: Potvrdenie
+  field_version: Verzia
+  field_type: Typ
+  field_host: Host
+  field_port: Port
+  field_account: ÃšÄet
+  field_base_dn: Base DN
+  field_attr_login: PrihlÃ¡senie (atribut)
+  field_attr_firstname: Meno (atribut)
+  field_attr_lastname: Priezvisko (atribut)
+  field_attr_mail: Email (atribut)
+  field_onthefly: AutomatickÃ© vytvÃ¡ranie uÅ¾Ã­vateÄ¾ov
+  field_start_date: ZaÄiatok
+  field_done_ratio: "% hotovo"
+  field_auth_source: AutentifikaÄnÃ½ mÃ³d
+  field_hide_mail: NezobrazovaÅ¥ mÃ´j email
+  field_comments: KomentÃ¡r
+  field_url: URL
+  field_start_page: VÃ½chozia strÃ¡nka
+  field_subproject: Podprojekt
+  field_hours: Hodiny
+  field_activity: Aktivita
+  field_spent_on: DÃ¡tum
+  field_identifier: IdentifikÃ¡tor
+  field_is_filter: PouÅ¾iÅ¥ ako filter
+  field_issue_to: SÃºvisiaca Ãºloha
+  field_delay: Oneskorenie
+  field_assignable: Ãšlohy mÃ´Å¾u byÅ¥ priradenÃ© tejto roli
+  field_redirect_existing_links: PresmerovaÅ¥ existujÃºce odkazy
+  field_estimated_hours: OdhadovanÃ¡ doba
+  field_column_names: StÄºpce
+  field_time_zone: ÄŒasovÃ© pÃ¡smo
+  field_searchable: UmoÅ¾niÅ¥ vyhÄ¾adÃ¡vanie
+  field_default_value: VÃ½chodzia hodnota
+  field_comments_sorting: ZobraziÅ¥ komentÃ¡re
+
+  setting_app_title: NÃ¡zov aplikÃ¡cie
+  setting_app_subtitle: Podtitulok aplikÃ¡cie
+  setting_welcome_text: UvÃ­tacÃ­ text
+  setting_default_language: VÃ½chodzÃ­ jazyk
+  setting_login_required: Auten. vyÅ¾adovanÃ¡
+  setting_self_registration: Povolenie registrÃ¡cie
+  setting_attachment_max_size: MaximÃ¡lna veÄ¾kosÅ¥ prÃ­lohy
+  setting_issues_export_limit: Limit pre export Ãºloh
+  setting_mail_from: OdosielaÅ¥ emaily z adresy
+  setting_bcc_recipients: PrÃ­jemcovia skrytej kÃ³pie (bcc)
+  setting_host_name: Hostname
+  setting_text_formatting: FormÃ¡tovanie textu
+  setting_wiki_compression: Kompresia histÃ³rie Wiki
+  setting_feeds_limit: Limit zobrazenÃ½ch poloÅ¾iek (Atom feed)
+  setting_default_projects_public: NovÃ© projekty nastavovaÅ¥ ako verejnÃ©
+  setting_autofetch_changesets: AutomatickÃ½ prenos zmien
+  setting_sys_api_enabled: Povolit WebovÃº SluÅ¾bu (WS) pre sprÃ¡vu repozitÃ¡ra
+  setting_commit_ref_keywords: KlÃºÄovÃ© slovÃ¡ pre odkazy
+  setting_commit_fix_keywords: KlÃºÄovÃ© slovÃ¡ pre uzavretie
+  setting_autologin: AutomatickÃ© prihlasovanie
+  setting_date_format: FormÃ¡t dÃ¡tumu
+  setting_time_format: FormÃ¡t Äasu
+  setting_cross_project_issue_relations: PovoliÅ¥ vÃ¤zby Ãºloh skrz projekty
+  setting_issue_list_default_columns: VÃ½chodzie stÄºpce zobrazenÃ© v zozname Ãºloh
+  setting_ itories_encodings: KÃ³dovanie
+  setting_emails_footer: ZapÃ¤tie emailov
+  setting_protocol: Protokol
+  setting_per_page_options: PovolenÃ© mnoÅ¾stvo riadkov na strÃ¡nke
+  setting_user_format: FormÃ¡t zobrazenia uÅ¾Ã­vateÄ¾a
+  setting_activity_days_default: "ZobrazenÃ© dni aktivity projektu:"
+  setting_display_subprojects_issues: Prednastavenie zobrazenia Ãºloh podporojektov v hlavnom projekte
+
+  project_module_issue_tracking: Sledovanie Ãºloh
+  project_module_time_tracking: Sledovanie Äasu
+  project_module_news: Novinky
+  project_module_documents: Dokumenty
+  project_module_files: SÃºbory
+  project_module_wiki: Wiki
+  project_module_repository: RepozitÃ¡r
+  project_module_boards: Diskusie
+
+  label_user: UÅ¾Ã­vateÄ¾
+  label_user_plural: UÅ¾Ã­vatelia
+  label_user_new: NovÃ½ uÅ¾Ã­vateÄ¾
+  label_project: Projekt
+  label_project_new: NovÃ½ projekt
+  label_project_plural: Projekty
+  label_x_projects:
+    zero:  Å¾iadne projekty
+    one:   1 projekt
+    other: "%{count} projekty/ov"
+  label_project_all: VÅ¡etky projekty
+  label_project_latest: PoslednÃ© projekty
+  label_issue: Ãšloha
+  label_issue_new: NovÃ¡ Ãºloha
+  label_issue_plural: Ãšlohy
+  label_issue_view_all: VÅ¡etky Ãºlohy
+  label_issues_by: "Ãšlohy od uÅ¾Ã­vateÄ¾a %{value}"
+  label_issue_added: Ãšloha pridanÃ¡
+  label_issue_updated: Ãšloha aktualizovanÃ¡
+  label_document: Dokument
+  label_document_new: NovÃ½ dokument
+  label_document_plural: Dokumenty
+  label_document_added: Dokument pridanÃ½
+  label_role: Rola
+  label_role_plural: Role
+  label_role_new: NovÃ¡ rola
+  label_role_and_permissions: Role a prÃ¡va
+  label_member: ÄŒlen
+  label_member_new: NovÃ½ Älen
+  label_member_plural: ÄŒlenovia
+  label_tracker: Fronta
+  label_tracker_plural: Fronty
+  label_tracker_new: NovÃ¡ fronta
+  label_workflow: Workflow
+  label_issue_status: Stav Ãºloh
+  label_issue_status_plural: Stavy Ãºloh
+  label_issue_status_new: NovÃ½ stav
+  label_issue_category: KategÃ³ria Ãºloh
+  label_issue_category_plural: KategÃ³rie Ãºloh
+  label_issue_category_new: NovÃ¡ kategÃ³ria
+  label_custom_field: UÅ¾Ã­vateÄ¾skÃ© pole
+  label_custom_field_plural: UÅ¾Ã­vateÄ¾skÃ© polia
+  label_custom_field_new: NovÃ© uÅ¾Ã­vateÄ¾skÃ© pole
+  label_enumerations: Zoznamy
+  label_enumeration_new: NovÃ¡ hodnota
+  label_information: InformÃ¡cia
+  label_information_plural: InformÃ¡cie
+  label_please_login: ProsÃ­m prihlÃ¡ste sa
+  label_register: RegistrovaÅ¥
+  label_password_lost: ZabudnutÃ© heslo
+  label_home: DomovskÃ¡ strÃ¡nka
+  label_my_page: Moja strÃ¡nka
+  label_my_account: MÃ´j ÃºÄet
+  label_my_projects: Moje projekty
+  label_administration: AdministrÃ¡cia
+  label_login: PrihlÃ¡senie
+  label_logout: OdhlÃ¡senie
+  label_help: NÃ¡poveda
+  label_reported_issues: NahlÃ¡senÃ© Ãºlohy
+  label_assigned_to_me_issues: Moje Ãºlohy
+  label_last_login: PoslednÃ© prihlÃ¡senie
+  label_registered_on: RegistrovanÃ½
+  label_activity: Aktivita
+  label_overall_activity: CelkovÃ¡ aktivita
+  label_new: NovÃ½
+  label_logged_as: PrihlÃ¡senÃ½ ako
+  label_environment: Prostredie
+  label_authentication: AutentifikÃ¡cia
+  label_auth_source: MÃ³d autentifikÃ¡cie
+  label_auth_source_new: NovÃ½ mÃ³d autentifikÃ¡cie
+  label_auth_source_plural: MÃ³dy autentifikÃ¡cie
+  label_subproject_plural: Podprojekty
+  label_min_max_length: Min - Max dÄºÅ¾ka
+  label_list: Zoznam
+  label_date: DÃ¡tum
+  label_integer: CelÃ© ÄÃ­slo
+  label_float: DesatinnÃ© ÄÃ­slo
+  label_boolean: Ãno/Nie
+  label_string: Text
+  label_text: DlhÃ½ text
+  label_attribute: Atribut
+  label_attribute_plural: Atributy
+  label_no_data: Å½iadnÃ© poloÅ¾ky
+  label_change_status: ZmeniÅ¥ stav
+  label_history: HistÃ³ria
+  label_attachment: SÃºbor
+  label_attachment_new: NovÃ½ sÃºbor
+  label_attachment_delete: OdstrÃ¡niÅ¥ sÃºbor
+  label_attachment_plural: SÃºbory
+  label_file_added: SÃºbor pridanÃ½
+  label_report: PrehÄ¾ad
+  label_report_plural: PrehÄ¾ady
+  label_news: Novinky
+  label_news_new: PridaÅ¥ novinku
+  label_news_plural: Novinky
+  label_news_latest: PoslednÃ© novinky
+  label_news_view_all: Zobrazit vÅ¡etky novinky
+  label_news_added: Novinka pridanÃ¡
+  label_settings: Nastavenie
+  label_overview: PrehÄ¾ad
+  label_version: Verzia
+  label_version_new: NovÃ¡ verzia
+  label_version_plural: Verzie
+  label_confirmation: Potvrdenie
+  label_export_to: 'TieÅ¾ k dispozÃ­ciÃ­:'
+  label_read: NaÄÃ­ta sa...
+  label_public_projects: VerejnÃ© projekty
+  label_open_issues: OtvorenÃ½
+  label_open_issues_plural: OtvorenÃ©
+  label_closed_issues: UzavrenÃ½
+  label_closed_issues_plural: UzavrenÃ©
+  label_x_open_issues_abbr_on_total:
+    zero:  0 otvorenÃ½ch z celkovo %{total}
+    one:   1 otvorenÃ½ z celkovo %{total}
+    other: "%{count} otvorenÃ©/Ã½ch z celkovo %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 otvorenÃ½ch
+    one:   1 otvorenÃ½
+    other: "%{count} otvorenÃ©/Ã½ch"
+  label_x_closed_issues_abbr:
+    zero:  0 zavretÃ½ch
+    one:   1 zavretÃ½
+    other: "%{count} zavretÃ©/Ã½ch"
+  label_total: Celkovo
+  label_permissions: PrÃ¡va
+  label_current_status: AktuÃ¡lny stav
+  label_new_statuses_allowed: NovÃ© povolenÃ© stavy
+  label_all: vÅ¡etko
+  label_none: niÄ
+  label_nobody: nikto
+  label_next: ÄŽalÅ¡Ã­
+  label_previous: PredchÃ¡dzajÃºci
+  label_used_by: PouÅ¾itÃ©
+  label_details: Detaily
+  label_add_note: PridaÅ¥ poznÃ¡mku
+  label_per_page: Na strÃ¡nku
+  label_calendar: KalendÃ¡r
+  label_months_from: mesiacov od
+  label_gantt: Ganttov graf
+  label_internal: InternÃ½
+  label_last_changes: "poslednÃ½ch %{count} zmien"
+  label_change_view_all: ZobraziÅ¥ vÅ¡etky zmeny
+  label_personalize_page: PrispÃ´sobiÅ¥ tÃºto strÃ¡nku
+  label_comment: KomentÃ¡r
+  label_comment_plural: KomentÃ¡re
+  label_x_comments:
+    zero: Å¾iaden komentÃ¡r
+    one: 1 komentÃ¡r
+    other: "%{count} komentÃ¡re/ov"
+  label_comment_add: PridaÅ¥ komentÃ¡r
+  label_comment_added: KomentÃ¡r pridanÃ½
+  label_comment_delete: OdstrÃ¡niÅ¥ komentÃ¡r
+  label_query: UÅ¾Ã­vateÄ¾skÃ½ dotaz
+  label_query_plural: UÅ¾Ã­vateÄ¾skÃ© dotazy
+  label_query_new: NovÃ½ dotaz
+  label_filter_add: PridaÅ¥ filter
+  label_filter_plural: Filtre
+  label_equals: je
+  label_not_equals: nieje
+  label_in_less_than: je menÅ¡Ã­ ako
+  label_in_more_than: je vÃ¤ÄÅ¡Ã­ ako
+  label_in: v
+  label_today: dnes
+  label_all_time: vÅ¾dy
+  label_yesterday: vÄera
+  label_this_week: tento tÃ½Å¾deÅˆ
+  label_last_week: minulÃ½ tÃ½Å¾deÅˆ
+  label_last_n_days: "poslednÃ½ch %{count} dnÃ­"
+  label_this_month: tento mesiac
+  label_last_month: minulÃ½ mesiac
+  label_this_year: tento rok
+  label_date_range: ÄŒasovÃ½ rozsah
+  label_less_than_ago: pred menej ako (dÅˆami)
+  label_more_than_ago: pred viac ako (dÅˆami)
+  label_ago: pred (dÅˆami)
+  label_contains: obsahuje
+  label_not_contains: neobsahuje
+  label_day_plural: dnÃ­
+  label_repository: RepozitÃ¡r
+  label_repository_plural: RepozitÃ¡re
+  label_browse: PrechÃ¡dzaÅ¥
+  label_revision: RevÃ­zia
+  label_revision_plural: RevÃ­ziÃ­
+  label_associated_revisions: SÃºvisiace verzie
+  label_added: pridanÃ©
+  label_modified: zmenenÃ©
+  label_deleted: odstrÃ¡nenÃ©
+  label_latest_revision: PoslednÃ¡ revÃ­zia
+  label_latest_revision_plural: PoslednÃ© revÃ­zie
+  label_view_revisions: ZobraziÅ¥ revÃ­zie
+  label_max_size: MaximÃ¡lna veÄ¾kosÅ¥
+  label_sort_highest: PresunÃºÅ¥ na zaÄiatok
+  label_sort_higher: PresunÃºÅ¥ navrch
+  label_sort_lower: PresunÃºÅ¥ dole
+  label_sort_lowest: PresunÃºÅ¥ na koniec
+  label_roadmap: PlÃ¡n
+  label_roadmap_due_in: "ZostÃ¡va %{value}"
+  label_roadmap_overdue: "%{value} neskoro"
+  label_roadmap_no_issues: Pre tÃºto verziu niesÃº Å¾iadne Ãºlohy
+  label_search: HÄ¾adaÅ¥
+  label_result_plural: VÃ½sledky
+  label_all_words: VÅ¡etky slova
+  label_wiki: Wiki
+  label_wiki_edit: Wiki Ãºprava
+  label_wiki_edit_plural: Wiki Ãºpravy
+  label_wiki_page: Wiki strÃ¡nka
+  label_wiki_page_plural: Wiki strÃ¡nky
+  label_index_by_title: Index podÄ¾a nÃ¡zvu
+  label_index_by_date: Index podÄ¾a dÃ¡tumu
+  label_current_version: AktuÃ¡lna verzia
+  label_preview: NÃ¡hÄ¾ad
+  label_feed_plural: PrÃ­spevky
+  label_changes_details: Detail vÅ¡etkÃ½ch zmien
+  label_issue_tracking: Sledovanie Ãºloh
+  label_spent_time: StrÃ¡venÃ½ Äas
+  label_f_hour: "%{value} hodina"
+  label_f_hour_plural: "%{value} hodÃ­n"
+  label_time_tracking: SledovÃ¡nie Äasu
+  label_change_plural: Zmeny
+  label_statistics: Å tatistiky
+  label_commits_per_month: Ãškony za mesiac
+  label_commits_per_author: Ãškony podÄ¾a autora
+  label_view_diff: Zobrazit rozdiely
+  label_diff_inline: vo vnÃºtri
+  label_diff_side_by_side: vedÄ¾a seba
+  label_options: Nastavenie
+  label_copy_workflow_from: KopÃ­rovaÅ¥ workflow z
+  label_permissions_report: PrehÄ¾ad prÃ¡v
+  label_watched_issues: SledovanÃ© Ãºlohy
+  label_related_issues: SÃºvisiace Ãºlohy
+  label_applied_status: PouÅ¾itÃ½ stav
+  label_loading: NahrÃ¡vam ...
+  label_relation_new: NovÃ¡ sÃºvislosÅ¥
+  label_relation_delete: OdstrÃ¡niÅ¥ sÃºvislosÅ¥
+  label_relates_to: sÃºvisiacÃ­ s
+  label_duplicates: duplicity
+  label_blocks: blokovanÃ½
+  label_blocked_by: zablokovanÃ½
+  label_precedes: predchÃ¡za
+  label_follows: nÃ¡sleduje
+  label_end_to_start: od konca na zaÄiatok
+  label_end_to_end: od konca do konca
+  label_start_to_start: od zaÄiatku do zaÄiatku
+  label_start_to_end: od zaÄiatku do konca
+  label_stay_logged_in: ZostaÅ¥ prihlÃ¡senÃ½
+  label_disabled: zakazanÃ©
+  label_show_completed_versions: UkÃ¡zaÅ¥ dokonÄenÃ© verzie
+  label_me: ja
+  label_board: FÃ³rum
+  label_board_new: NovÃ© fÃ³rum
+  label_board_plural: FÃ³ra
+  label_topic_plural: TÃ©my
+  label_message_plural: SprÃ¡vy
+  label_message_last: PoslednÃ¡ sprÃ¡va
+  label_message_new: NovÃ¡ sprÃ¡va
+  label_message_posted: SprÃ¡va pridanÃ¡
+  label_reply_plural: Odpovede
+  label_send_information: ZaslaÅ¥ informÃ¡cie o ÃºÄte uÅ¾Ã­vateÄ¾a
+  label_year: Rok
+  label_month: Mesiac
+  label_week: TÃ½Å¾den
+  label_date_from: Od
+  label_date_to: Do
+  label_language_based: PodÄ¾a vÃ½chozieho jazyka
+  label_sort_by: "Zoradenie podÄ¾a %{value}"
+  label_send_test_email: PoslaÅ¥ testovacÃ­ email
+  label_feeds_access_key_created_on: "PrÃ­stupovÃ½ klÃºÄ pre RSS bol vytvorenÃ½ pred %{value}"
+  label_module_plural: Moduly
+  label_added_time_by: "PridanÃ© uÅ¾Ã­vateÄ¾om %{author} pred %{age}"
+  label_updated_time: "AktualizovanÃ© pred %{value}"
+  label_jump_to_a_project: ZvoliÅ¥ projekt...
+  label_file_plural: SÃºbory
+  label_changeset_plural: Sady zmien
+  label_default_columns: VÃ½chodzie stÄºpce
+  label_no_change_option: (bez zmeny)
+  label_bulk_edit_selected_issues: SkupinovÃ¡ Ãºprava vybranÃ½ch Ãºloh
+  label_theme: TÃ©ma
+  label_default: VÃ½chodzÃ­
+  label_search_titles_only: VyhÄ¾adÃ¡vaÅ¥ iba v nÃ¡zvoch
+  label_user_mail_option_all: "Pre vÅ¡etky udÃ¡losti vÅ¡etkÃ½ch mojÃ­ch projektov"
+  label_user_mail_option_selected: "Pre vÅ¡etky udÃ¡losti vybranÃ½ch projektov"
+  label_user_mail_no_self_notified: "NezasielaÅ¥ informÃ¡cie o mnou vytvorenÃ½ch zmenÃ¡ch"
+  label_registration_activation_by_email: aktivÃ¡cia ÃºÄtu emailom
+  label_registration_manual_activation: manuÃ¡lna aktivÃ¡cia ÃºÄtu
+  label_registration_automatic_activation: automatickÃ¡ aktivÃ¡cia ÃºÄtu
+  label_display_per_page: "%{value} na strÃ¡nku"
+  label_age: Vek
+  label_change_properties: ZmeniÅ¥ vlastnosti
+  label_general: VÅ¡eobecnÃ©
+  label_more: Viac
+  label_scm: SCM
+  label_plugins: Pluginy
+  label_ldap_authentication: AutentifikÃ¡cia LDAP
+  label_downloads_abbr: D/L
+  label_optional_description: VoliteÄ¾nÃ½ popis
+  label_add_another_file: PridaÅ¥ ÄaÄ¾Å¡Ã­ sÃºbor
+  label_preferences: Nastavenia
+  label_chronological_order: V chronologickom poradÃ­
+  label_reverse_chronological_order: V obrÃ¡tenom chronologickom poradÃ­
+
+  button_login: PrihlÃ¡siÅ¥
+  button_submit: PotvrdiÅ¥
+  button_save: UloÅ¾iÅ¥
+  button_check_all: OznaÄiÅ¥ vÅ¡etko
+  button_uncheck_all: OdznaÄiÅ¥ vÅ¡etko
+  button_delete: OdstrÃ¡niÅ¥
+  button_create: VytvoriÅ¥
+  button_test: Test
+  button_edit: UpraviÅ¥
+  button_add: PridaÅ¥
+  button_change: ZmeniÅ¥
+  button_apply: PouÅ¾iÅ¥
+  button_clear: ZmazaÅ¥
+  button_lock: ZamknÃºÅ¥
+  button_unlock: OdomknÃºÅ¥
+  button_download: StiahnÃºÅ¥
+  button_list: VypÃ­saÅ¥
+  button_view: ZobraziÅ¥
+  button_move: PresunÃºÅ¥
+  button_back: NaspÃ¤Å¥
+  button_cancel: Storno
+  button_activate: AktivovaÅ¥
+  button_sort: Zoradenie
+  button_log_time: PridaÅ¥ Äas
+  button_rollback: NaspÃ¤Å¥ k tejto verzii
+  button_watch: SledovaÅ¥
+  button_unwatch: NesledovaÅ¥
+  button_reply: OdpovedaÅ¥
+  button_archive: ArchivovaÅ¥
+  button_unarchive: OdarchivovaÅ¥
+  button_reset: Reset
+  button_rename: PremenovaÅ¥
+  button_change_password: ZmeniÅ¥ heslo
+  button_copy: KopÃ­rovaÅ¥
+  button_annotate: KomentovaÅ¥
+  button_update: AktualizovaÅ¥
+  button_configure: KonfigurovaÅ¥
+
+  status_active: aktÃ­vny
+  status_registered: registrovanÃ½
+  status_locked: uzamknutÃ½
+
+  text_select_mail_notifications: Vyberte akciu, pri ktorej bude zaslanÃ© upozornenie emailom
+  text_regexp_info: napr. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 znamenÃ¡ bez limitu
+  text_project_destroy_confirmation: Ste si istÃ½, Å¾e chcete odstrÃ¡nit tento projekt a vÅ¡etky sÃºvisiace dÃ¡ta ?
+  text_workflow_edit: Vyberte rolu a frontu k Ãºprave workflow
+  text_are_you_sure: Ste si istÃ½?
+  text_tip_issue_begin_day: Ãºloha zaÄÃ­na v tento deÅˆ
+  text_tip_issue_end_day: Ãºloha konÄÃ­ v tento deÅˆ
+  text_tip_issue_begin_end_day: Ãºloha zaÄÃ­na a konÄÃ­ v tento deÅˆ
+  text_caracters_maximum: "%{count} znakov maximÃ¡lne."
+  text_caracters_minimum: "MusÃ­ byÅ¥ aspoÅˆ %{count} znaky/ov dlhÃ©."
+  text_length_between: "DÄºÅ¾ka medzi %{min} aÅ¾ %{max} znakmi."
+  text_tracker_no_workflow: Pre tuto frontu nieje definovanÃ½ Å¾iadnÃ½ workflow
+  text_unallowed_characters: NepovolenÃ© znaky
+  text_comma_separated: Je povolenÃ© viacero hodnÃ´t (oddelenÃ© navzÃ¡jom Äiarkou).
+  text_issues_ref_in_commit_messages: OdkazovaÅ¥ a upravovaÅ¥ Ãºlohy v sprÃ¡vach s nÃ¡sledovnym obsahom
+  text_issue_added: "Ãºloha %{id} bola vytvorenÃ¡ uÅ¾Ã­vateÄ¾om %{author}."
+  text_issue_updated: "Ãšloha %{id} byla aktualizovanÃ¡ uÅ¾Ã­vateÄ¾om %{author}."
+  text_wiki_destroy_confirmation: Naozaj si prajete odstrÃ¡niÅ¥ tÃºto Wiki a celÃ½ jej obsah?
+  text_issue_category_destroy_question: "NiektorÃ© Ãºlohy (%{count}) sÃº priradenÃ© k tejto kategÃ³rii. ÄŒo chtete  s nimi spraviÅ¥?"
+  text_issue_category_destroy_assignments: ZruÅ¡iÅ¥ priradenie ku kategÃ³rii
+  text_issue_category_reassign_to: PriradiÅ¥ Ãºlohy do tejto kategÃ³rie
+  text_user_mail_option: "U projektov, kterÃ© neboli vybranÃ©, budete dostÃ¡vaÅ¥ oznamenie iba o vaÅ¡ich Äi o sledovanÃ½ch poloÅ¾kÃ¡ch (napr. o poloÅ¾kÃ¡ch, ktorÃ½ch ste autor, alebo ku ktorÃ½m ste priradenÃ½/Ã¡)."
+  text_no_configuration_data: "Role, fronty, stavy Ãºloh ani workflow neboli zatiaÄ¾ nakonfigurovanÃ©.\nVelmi doporuÄujeme nahraÅ¥ vÃ½chodziu konfigurÃ¡ciu. Potom si mÃ´Å¾ete vÅ¡etko upraviÅ¥"
+  text_load_default_configuration: NahraÅ¥ vÃ½chodziu konfigurÃ¡ciu
+  text_status_changed_by_changeset: "AktualizovanÃ© v sade zmien %{value}."
+  text_issues_destroy_confirmation: 'Naozaj si prajete odstrÃ¡niÅ¥ vÅ¡etky zvolenÃ© Ãºlohy?'
+  text_select_project_modules: 'Aktivne moduly v tomto projekte:'
+  text_default_administrator_account_changed: ZmenenÃ© vÃ½chozie nastavenie administrÃ¡torskÃ©ho ÃºÄtu
+  text_file_repository_writable: PovolenÃ½ zÃ¡pis do repozitÃ¡ra
+  text_rmagick_available: RMagick k dispozÃ­ciÃ­ (voliteÄ¾nÃ©)
+  text_destroy_time_entries_question: U Ãºloh, kterÃ© chcete odstraniÅ¥, je evidovanÃ© %.02f prÃ¡ce. ÄŒo chcete vykonaÅ¥?
+  text_destroy_time_entries: OdstrÃ¡niÅ¥ evidovanÃ© hodiny.
+  text_assign_time_entries_to_project: PriradiÅ¥ evidovanÃ© hodiny projektu
+  text_reassign_time_entries: 'PreradiÅ¥ evidovanÃ© hodiny k tejto Ãºlohe:'
+
+  default_role_manager: ManaÅ¾Ã©r
+  default_role_developer: VÃ½vojÃ¡r
+  default_role_reporter: ReportÃ©r
+  default_tracker_bug: Chyba
+  default_tracker_feature: RozÅ¡Ã­renie
+  default_tracker_support: Podpora
+  default_issue_status_new: NovÃ½
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: VyrieÅ¡enÃ½
+  default_issue_status_feedback: ÄŒakÃ¡ sa
+  default_issue_status_closed: UzavrenÃ½
+  default_issue_status_rejected: OdmietnutÃ½
+  default_doc_category_user: UÅ¾Ã­vateÄ¾skÃ¡ dokumentÃ¡cia
+  default_doc_category_tech: TechnickÃ¡ dokumentÃ¡cia
+  default_priority_low: NÃ­zkÃ¡
+  default_priority_normal: NormÃ¡lna
+  default_priority_high: VysokÃ¡
+  default_priority_urgent: UrgentnÃ¡
+  default_priority_immediate: OkamÅ¾itÃ¡
+  default_activity_design: Design
+  default_activity_development: VÃ½voj
+
+  enumeration_issue_priorities: Priority Ãºloh
+  enumeration_doc_categories: Kategorie dokumentov
+  enumeration_activities: Aktivity (sledovanie Äasu)
+  error_scm_annotate: "PoloÅ¾ka neexistuje alebo nemÃ´Å¾e byÅ¥ komentovanÃ¡."
+  label_planning: PlÃ¡novanie
+  text_subprojects_destroy_warning: "Jeho podprojekt(y): %{value} budÃº takisto vymazanÃ©."
+  label_and_its_subprojects: "%{value} a jeho podprojekty"
+  mail_body_reminder: "%{count} Ãºloha(y), ktorÃ¡(Ã©) je(sÃº) vÃ¡m priradenÃ½(Ã©), ma(jÃº) byÅ¥ hotova(Ã©) za %{days} dnÃ­:"
+  mail_subject_reminder: "%{count} Ãºloha(y) ma(jÃº) byÅ¥ hotova(Ã©) za pÃ¡r %{days} dnÃ­"
+  text_user_wrote: "%{value} napÃ­sal:"
+  label_duplicated_by: duplikovanÃ½
+  setting_enabled_scm: ZapnÃºÅ¥ SCM
+  text_enumeration_category_reassign_to: 'PrenastaviÅ¥ na tÃºto hodnotu:'
+  text_enumeration_destroy_question: "%{count} objekty sÃº nastavenÃ© na tÃºto hodnotu."
+  label_incoming_emails: PrÃ­chÃ¡dzajÃºce emaily
+  label_generate_key: VygenerovaÅ¥ kÄ¾ÃºÄ
+  setting_mail_handler_api_enabled: ZapnÃºÅ¥ WebovÃº SluÅ¾bu (WS) pre prÃ­chodzie emaily
+  setting_mail_handler_api_key: API kÄ¾ÃºÄ
+  text_email_delivery_not_configured: "DoruÄenie emailov nieje nastavenÃ©, notifikÃ¡cie sÃº vypnutÃ©.\nNastavte vÃ¡Å¡ SMTP server v config/configuration.yml a reÅ¡tartnite aplikÃ¡ciu pre aktivÃ¡ciu funkcie."
+  field_parent_title: NadradenÃ¡ strÃ¡nka
+  label_issue_watchers: Pozorovatelia
+  button_quote: CitÃ¡cia
+  setting_sequential_project_identifiers: GenerovaÅ¥ sekvenÄnÃ© identifikÃ¡tory projektov
+  notice_unable_delete_version: Verzia nemÃ´Å¾e byÅ¥ zmazanÃ¡
+  label_renamed: premenovanÃ©
+  label_copied: kopÃ­rovanÃ©
+  setting_plain_text_mail: Len jednoduchÃ½ text (bez HTML)
+  permission_view_files: Zobrazenie sÃºborov
+  permission_edit_issues: Ãšprava Ãºloh
+  permission_edit_own_time_entries: Ãšprava vlastnÃ½ch zaznamov o strÃ¡venom Äase
+  permission_manage_public_queries: SprÃ¡va verejnÃ½ch otÃ¡ziek
+  permission_add_issues: Pridanie Ãºlohy
+  permission_log_time: ZaznamenÃ¡vanie strÃ¡venÃ©ho Äasu
+  permission_view_changesets: Zobrazenie sÃ¡d zmien
+  permission_view_time_entries: Zobrazenie strÃ¡venÃ©ho Äasu
+  permission_manage_versions: SprÃ¡va verziÃ­
+  permission_manage_wiki: SprÃ¡va Wiki
+  permission_manage_categories: SprÃ¡va kategÃ³riÃ­ Ãºloh
+  permission_protect_wiki_pages: Ochrana Wiki strÃ¡niek
+  permission_comment_news: Komentovanie noviniek
+  permission_delete_messages: Mazanie sprÃ¡v
+  permission_select_project_modules: VoÄ¾ba projektovÃ½ch modulov
+  permission_edit_wiki_pages: Ãšprava Wiki strÃ¡niek
+  permission_add_issue_watchers: Pridanie pozorovateÄ¾ov
+  permission_view_gantt: Zobrazenie Ganttovho diagramu
+  permission_move_issues: Presun Ãºloh
+  permission_manage_issue_relations: SprÃ¡va vzÅ¥ahov medzi Ãºlohami
+  permission_delete_wiki_pages: Mazanie Wiki strÃ¡niek
+  permission_manage_boards: SprÃ¡va diskusiÃ­
+  permission_delete_wiki_pages_attachments: Mazanie Wiki prÃ­loh
+  permission_view_wiki_edits: Zobrazenie Wiki Ãºprav
+  permission_add_messages: Pridanie sprÃ¡v
+  permission_view_messages: Zobrazenie sprÃ¡v
+  permission_manage_files: SprÃ¡va sÃºborov
+  permission_edit_issue_notes: Ãšprava poznÃ¡mok Ãºlohy
+  permission_manage_news: SprÃ¡va noviniek
+  permission_view_calendar: Zobrazenie kalendÃ¡ra
+  permission_manage_members: SprÃ¡va Älenov
+  permission_edit_messages: Ãšprava sprÃ¡v
+  permission_delete_issues: Mazanie sprÃ¡v
+  permission_view_issue_watchers: Zobrazenie zoznamu pozorovateÄ¾ov
+  permission_manage_repository: SprÃ¡va repozitÃ¡ra
+  permission_commit_access: PovoliÅ¥ prÃ­stup
+  permission_browse_repository: PrechÃ¡dzanie repozitÃ¡ra
+  permission_view_documents: Zobrazenie dokumentov
+  permission_edit_project: Ãšprava projektu
+  permission_add_issue_notes: Pridanie poznÃ¡mky Ãºlohy
+  permission_save_queries: UloÅ¾enie otÃ¡ziek
+  permission_view_wiki_pages: Zobrazenie Wiki strÃ¡niek
+  permission_rename_wiki_pages: Premenovanie Wiki strÃ¡niek
+  permission_edit_time_entries: Ãšprava zÃ¡znamov o strÃ¡venom Äase
+  permission_edit_own_issue_notes: Ãšprava vlastnÃ½ch poznÃ¡mok Ãºlohy
+  setting_gravatar_enabled: PouÅ¾itie uÅ¾Ã­vateÄ¾skÃ½ch Gravatar ikon
+  permission_edit_own_messages: Ãšprava vlastnÃ½ch sprÃ¡v
+  permission_delete_own_messages: Mazanie vlastnÃ½ch sprÃ¡v
+  text_repository_usernames_mapping: "Vyberte alebo upravte mapovanie medzi uÅ¾Ã­vateÄ¾mi systÃ©mu Redmine a uÅ¾Ã­vateÄ¾skÃ½mi menami nÃ¡jdenÃ½mi v logu repozitÃ¡ra.\nUÅ¾Ã­vatelia s rovnakÃ½m prihlasovacÃ­m menom alebo emailom v systÃ©me Redmine a repozitÃ¡ra sÃº mapovanÃ­ automaticky."
+  label_example: PrÃ­klad
+  label_user_activity: "Aktivita uÅ¾Ã­vateÄ¾a %{value}"
+  label_updated_time_by: "AktualizovanÃ© uÅ¾Ã­vateÄ¾om %{author} pred %{age}"
+  text_diff_truncated: '... Tento rozdielovÃ½ vÃ½pis bol skratenÃ½, pretoÅ¾e prekraÄuje maximÃ¡lnu veÄ¾kosÅ¥, ktorÃ¡ mÃ´Å¾e byÅ¥ zobrazenÃ¡.'
+  setting_diff_max_lines_displayed: MaximÃ¡lne mnoÅ¾stvo zobrazenÃ½ch riadkov rozdielovÃ©ho vÃ½pisu
+  text_plugin_assets_writable: AdresÃ¡r pre pluginy s moÅ¾nosÅ¥ou zÃ¡pisu
+  warning_attachments_not_saved: "%{count} sÃºbor(y) nemohol(li) byÅ¥ uloÅ¾enÃ©."
+  field_editable: EditovateÄ¾nÃ©
+  label_display: Zobrazenie
+  button_create_and_continue: VytvoriÅ¥ a pokraÄovaÅ¥
+  text_custom_field_possible_values_info: 'Jeden riadok pre kaÅ¾dÃº hodnotu'
+  setting_repository_log_display_limit: MaximÃ¡lne mnoÅ¾stvo reviziÃ­ zobrazenÃ© v logu
+  setting_file_max_size_displayed: MaximÃ¡lna veÄ¾kosÅ¥ textovÃ½ch sÃºborov zobrazenÃ½ch priamo na strÃ¡nke
+  field_watcher: PozorovateÄ¾
+  setting_openid: PovoliÅ¥ OpenID prihlasovanie a registrÃ¡ciu
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: alebo sa prihlÃ¡siÅ¥ pomocou OpenID
+  field_content: Obsah
+  label_descending: ZostupnÃ©
+  label_sort: Zoradenie
+  label_ascending: RastÃºce
+  label_date_from_to: Od %{start} do %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: TÃ¡to strÃ¡nka mÃ¡ %{descendants} podstrÃ¡nku/y a potomka/ov. ÄŒo chcete vykonaÅ¥?
+  text_wiki_page_reassign_children: PreradiÅ¥ podstrÃ¡nky k tejto hlavnej strÃ¡nke
+  text_wiki_page_nullify_children: ZachovaÅ¥ podstrÃ¡nky ako hlavnÃ© strÃ¡nky
+  text_wiki_page_destroy_children: VymazaÅ¥ podstrÃ¡nky a vÅ¡etkÃ½ch ich potomkov
+  setting_password_min_length: MinimÃ¡lna dÄºÅ¾ka hesla
+  field_group_by: SkupinovÃ© vÃ½sledky podÄ¾a
+  mail_subject_wiki_content_updated: "'%{id}' Wiki strÃ¡nka bola aktualizovanÃ¡"
+  label_wiki_content_added: Wiki strÃ¡nka pridanÃ¡
+  mail_subject_wiki_content_added: "'%{id}' Wiki strÃ¡nka bola pridanÃ¡"
+  mail_body_wiki_content_added: The '%{id}' Wiki strÃ¡nka bola pridanÃ¡ uÅ¾Ã­vateÄ¾om %{author}.
+  permission_add_project: Vytvorenie projektu
+  label_wiki_content_updated: Wiki strÃ¡nka aktualizovanÃ¡
+  mail_body_wiki_content_updated: Wiki strÃ¡nka '%{id}' bola aktualizovanÃ¡ uÅ¾Ã­vateÄ¾om %{author}.
+  setting_new_project_user_role_id: Rola dÃ¡na non-admin uÅ¾Ã­vateÄ¾ovi, ktorÃ½ vytvorÃ­ projekt
+  label_view_all_revisions: ZobraziÅ¥ vÅ¡etkz revÃ­zie
+  label_tag: Tag
+  label_branch: Vetva
+  error_no_tracker_in_project: K tomuto projektu nieje priradenÃ¡ Å¾iadna fronta. ProsÃ­m skontrolujte nastavenie projektu.
+  error_no_default_issue_status: Nieje definovanÃ½ vÃ½chodzÃ­ stav Ãºlohy. ProsÃ­m skontrolujte vase nastavenie (ChoÄte na "AdministrÃ¡cia -> Stavz Ãºloh").
+  text_journal_changed: "%{label} zmenenÃ© z %{old} na %{new}"
+  text_journal_set_to: "%{label} nastavenÃ© na %{value}"
+  text_journal_deleted: "%{label} zmazanÃ© (%{old})"
+  label_group_plural: Skupiny
+  label_group: Skupina
+  label_group_new: NovÃ¡ skupina
+  label_time_entry_plural: StrÃ¡venÃ½ Äas
+  text_journal_added: "%{label} %{value} pridanÃ©"
+  field_active: AktÃ­vne
+  enumeration_system_activity: Aktivita systÃ©mu
+  permission_delete_issue_watchers: OdstrÃ¡niÅ¥ pozorovateÄ¾ov
+  version_status_closed: zavretÃ©
+  version_status_locked: uzavretÃ©
+  version_status_open: otvorenÃ©
+  error_can_not_reopen_issue_on_closed_version: Ãšloha priradenÃ¡ uzavretej verziÃ­ nemÃ´Å¾e byÅ¥ znovu-otvorenÃ¡
+  label_user_anonymous: Anonym
+  button_move_and_follow: PresunÃºÅ¥ a nÃ¡sledovaÅ¥
+  setting_default_projects_modules: PrednastavenÃ© aktÃ­vne moduly pre novÃ© projekty
+  setting_gravatar_default: VÃ½chodzÃ­ Gravatar obrÃ¡zok
+  field_sharing: ZdieÄ¾anie
+  label_version_sharing_hierarchy: S hierarchiou projektu
+  label_version_sharing_system: So vÅ¡etkÃ½mi projektami
+  label_version_sharing_descendants: S podprojektami
+  label_version_sharing_tree: S projektovÃ½m stromom
+  label_version_sharing_none: NezdielanÃ©
+  error_can_not_archive_project: Tento projekt nemÃ´Å¾e byÅ¥ archivovanÃ½
+  button_duplicate: DuplikovaÅ¥
+  button_copy_and_follow: KopÃ­rovaÅ¥ a nÃ¡sledovaÅ¥
+  label_copy_source: Zdroj
+  setting_issue_done_ratio: VyrÃ¡taÅ¥ pomer vypracovania Ãºlohy s
+  setting_issue_done_ratio_issue_status: PouÅ¾iÅ¥ stav Ãºlohy
+  error_issue_done_ratios_not_updated: Stav vypracovania Ãºlohy neaktualizovanÃ½.
+  error_workflow_copy_target: ProsÃ­m zvoÄ¾te cieÄ¾ovÃº frontu(y) a rolu(e)
+  setting_issue_done_ratio_issue_field: PouÅ¾iÅ¥ pole Ãºlohy
+  label_copy_same_as_target: RovnakÃ© ako cieÄ¾
+  label_copy_target: CieÄ¾
+  notice_issue_done_ratios_updated: Stav vypracovania Ãºlohy aktualizovanÃ½.
+  error_workflow_copy_source: ProsÃ­m zvoÄ¾te zdrojovÃº frontu alebo rolu
+  label_update_issue_done_ratios: AktualizÃ¡cia stavu Ãºloh
+  setting_start_of_week: Å tart pracovnÃ©ho tÃ½Å¾dÅˆa v
+  permission_view_issues: ZobraziÅ¥ Ãºlohy
+  label_display_used_statuses_only: ZobraziÅ¥ len stavy, ktorÃ© sÃº priradenÃ© k tejto fronte
+  label_revision_id: RevÃ­zia %{value}
+  label_api_access_key: API prÃ­stupovÃ½ kÄ¾ÃºÄ
+  label_api_access_key_created_on: API prÃ­stupovÃ½ kÄ¾ÃºÄ vytvorenÃ½ pred %{value}
+  label_feeds_access_key: RSS prÃ­stupovÃ½ kÄ¾ÃºÄ
+  notice_api_access_key_reseted: VÃ¡Å¡ API prÃ­stupovÃ½ kÄ¾ÃºÄ bol resetovanÃ½.
+  setting_rest_api_enabled: ZapnÃºÅ¥ REST web sluÅ¾bu
+  label_missing_api_access_key: API prÃ­stupovÃ½ kÄ¾uÄ nenÃ¡jdenÃ½
+  label_missing_feeds_access_key: RSS prÃ­stupovÃ½ kÄ¾ÃºÄ nenÃ¡jdenÃ½
+  button_show: ZobraziÅ¥
+  text_line_separated: MoÅ¾nosÅ¥ viacerÃ½ch hodnÃ´t (jeden riadok pre kaÅ¾dÃº hodnotu).
+  setting_mail_handler_body_delimiters: OrezaÅ¥ emaily po nÃ¡sledujÃºcich riadkoch
+  permission_add_subprojects: VytvÃ¡ranie podprojektov
+  label_subproject_new: NovÃ½ podprojekt
+  text_own_membership_delete_confirmation: |-
+    PrÃ¡ve sa pokÃºÅ¡ate o odstrÃ¡nenie niektorÃ½ch alebo vÅ¡etkÃ½ch prÃ­stupovÃ½ch prÃ¡v a moÅ¾no nebudete maÅ¥ moÅ¾nost naÄalej upravovaÅ¥ tento projekt.
+    Ste si istÃ½(Ã¡), Å¾e chcete pokraÄovat?
+  label_close_versions: UzavrieÅ¥ ukonÄenÃ© verzie
+  label_board_sticky: Sticky
+  label_board_locked: UzamknutÃ©
+  permission_export_wiki_pages: ExportovaÅ¥ WiKi strÃ¡nky
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: NastavovaÅ¥ aktivity projektu
+  error_unable_delete_issue_status: Nieje moÅ¾nÃ© zmeniÅ¥ stav Ãºlohy
+  label_profile: Profil
+  permission_manage_subtasks: NastavovaÅ¥ podÃºlohy
+  field_parent_issue: NadradenÃ¡ Ãºloha
+  label_subtask_plural: PodÃºlohy
+  label_project_copy_notifications: ZaslaÅ¥ emailovÃ© upozornenie behom kopÃ­rovania projektu
+  error_can_not_delete_custom_field: Nieje moÅ¾nÃ© vymazaÅ¥ uÅ¾Ã­vateÄ¾skÃ© pole
+  error_unable_to_connect: Nieje moÅ¾nÃ© vymazaÅ¥ (%{value})
+  error_can_not_remove_role: TÃ¡to roÄ¾a sa pouÅ¾Ã­va a nemÃ´Å¾e byÅ¥ vymazanÃ¡.
+  error_can_not_delete_tracker: TÃ¡to fronta obsahuje Ãºlohy a nemÃ´Å¾e byÅ¥ vymazanÃ¡.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: KÃ³dovanie prenÃ¡Å¡anÃ½ch sprÃ¡v
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 Ãšloha
+    one:   1 Ãšloha
+    other: "%{count} Ãšlohy"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: vÅ¡etko
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: S podprojektami
+  label_cross_project_tree: S projektovÃ½m stromom
+  label_cross_project_hierarchy: S hierarchiou projektu
+  label_cross_project_system: So vÅ¡etkÃ½mi projektami
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Celkovo
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/51b862a2f02fe838775410e5f39462124421d172.svn-base
--- /dev/null
+++ b/.svn/pristine/51/51b862a2f02fe838775410e5f39462124421d172.svn-base
@@ -0,0 +1,65 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WorkflowTest < ActiveSupport::TestCase
+  fixtures :roles, :trackers, :issue_statuses
+
+  def test_copy
+    WorkflowTransition.delete_all
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 2)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 3, :assignee => true)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 4, :author => true)
+
+    assert_difference 'WorkflowTransition.count', 3 do
+      WorkflowTransition.copy(Tracker.find(2), Role.find(1), Tracker.find(3), Role.find(2))
+    end
+
+    assert WorkflowTransition.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false})
+    assert WorkflowTransition.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 3, :author => false, :assignee => true})
+    assert WorkflowTransition.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 4, :author => true, :assignee => false})
+  end
+
+  def test_workflow_permission_should_validate_rule
+    wp = WorkflowPermission.new(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :field_name => 'due_date')
+    assert !wp.save
+
+    wp.rule = 'foo'
+    assert !wp.save
+
+    wp.rule = 'required'
+    assert wp.save
+
+    wp.rule = 'readonly'
+    assert wp.save
+  end
+
+  def test_workflow_permission_should_validate_field_name
+    wp = WorkflowPermission.new(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :rule => 'required')
+    assert !wp.save
+
+    wp.field_name = 'foo'
+    assert !wp.save
+
+    wp.field_name = 'due_date'
+    assert wp.save
+
+    wp.field_name = '1'
+    assert wp.save
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/51b919386182e47c3ef0ca6e2a6f8f116db68244.svn-base
--- a/.svn/pristine/51/51b919386182e47c3ef0ca6e2a6f8f116db68244.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-class Thing
-  def self.from_plugin; TestHelper::report_location(__FILE__); end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/51be1ed9a6fd0f544bf7334bc87d5f8e3ed5bf74.svn-base
--- a/.svn/pristine/51/51be1ed9a6fd0f544bf7334bc87d5f8e3ed5bf74.svn-base
+++ /dev/null
@@ -1,56 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class CalendarsController < ApplicationController
-  menu_item :calendar
-  before_filter :find_optional_project
-
-  rescue_from Query::StatementInvalid, :with => :query_statement_invalid
-
-  helper :issues
-  helper :projects
-  helper :queries
-  include QueriesHelper
-  helper :sort
-  include SortHelper
-
-  def show
-    if params[:year] and params[:year].to_i > 1900
-      @year = params[:year].to_i
-      if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
-        @month = params[:month].to_i
-      end
-    end
-    @year ||= Date.today.year
-    @month ||= Date.today.month
-
-    @calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), current_language, :month)
-    retrieve_query
-    @query.group_by = nil
-    if @query.valid?
-      events = []
-      events += @query.issues(:include => [:tracker, :assigned_to, :priority],
-                              :conditions => ["((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?))", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt]
-                              )
-      events += @query.versions(:conditions => ["effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt])
-
-      @calendar.events = events
-    end
-
-    render :action => 'show', :layout => false if request.xhr?
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/51/51f64479905fa6ebe754a8ef36329d97b292d2ad.svn-base
--- a/.svn/pristine/51/51f64479905fa6ebe754a8ef36329d97b292d2ad.svn-base
+++ /dev/null
@@ -1,793 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class QueryColumn
-  attr_accessor :name, :sortable, :groupable, :default_order
-  include Redmine::I18n
-
-  def initialize(name, options={})
-    self.name = name
-    self.sortable = options[:sortable]
-    self.groupable = options[:groupable] || false
-    if groupable == true
-      self.groupable = name.to_s
-    end
-    self.default_order = options[:default_order]
-    @caption_key = options[:caption] || "field_#{name}"
-  end
-
-  def caption
-    l(@caption_key)
-  end
-
-  # Returns true if the column is sortable, otherwise false
-  def sortable?
-    !@sortable.nil?
-  end
-  
-  def sortable
-    @sortable.is_a?(Proc) ? @sortable.call : @sortable
-  end
-
-  def value(issue)
-    issue.send name
-  end
-
-  def css_classes
-    name
-  end
-end
-
-class QueryCustomFieldColumn < QueryColumn
-
-  def initialize(custom_field)
-    self.name = "cf_#{custom_field.id}".to_sym
-    self.sortable = custom_field.order_statement || false
-    if %w(list date bool int).include?(custom_field.field_format)
-      self.groupable = custom_field.order_statement
-    end
-    self.groupable ||= false
-    @cf = custom_field
-  end
-
-  def caption
-    @cf.name
-  end
-
-  def custom_field
-    @cf
-  end
-
-  def value(issue)
-    cv = issue.custom_values.detect {|v| v.custom_field_id == @cf.id}
-    cv && @cf.cast_value(cv.value)
-  end
-
-  def css_classes
-    @css_classes ||= "#{name} #{@cf.field_format}"
-  end
-end
-
-class Query < ActiveRecord::Base
-  class StatementInvalid < ::ActiveRecord::StatementInvalid
-  end
-
-  belongs_to :project
-  belongs_to :user
-  serialize :filters
-  serialize :column_names
-  serialize :sort_criteria, Array
-
-  attr_protected :project_id, :user_id
-
-  validates_presence_of :name, :on => :save
-  validates_length_of :name, :maximum => 255
-  validate :validate_query_filters
-
-  @@operators = { "="   => :label_equals,
-                  "!"   => :label_not_equals,
-                  "o"   => :label_open_issues,
-                  "c"   => :label_closed_issues,
-                  "!*"  => :label_none,
-                  "*"   => :label_all,
-                  ">="  => :label_greater_or_equal,
-                  "<="  => :label_less_or_equal,
-                  "><"  => :label_between,
-                  "<t+" => :label_in_less_than,
-                  ">t+" => :label_in_more_than,
-                  "t+"  => :label_in,
-                  "t"   => :label_today,
-                  "w"   => :label_this_week,
-                  ">t-" => :label_less_than_ago,
-                  "<t-" => :label_more_than_ago,
-                  "t-"  => :label_ago,
-                  "~"   => :label_contains,
-                  "!~"  => :label_not_contains }
-
-  cattr_reader :operators
-
-  @@operators_by_filter_type = { :list => [ "=", "!" ],
-                                 :list_status => [ "o", "=", "!", "c", "*" ],
-                                 :list_optional => [ "=", "!", "!*", "*" ],
-                                 :list_subprojects => [ "*", "!*", "=" ],
-                                 :date => [ "=", ">=", "<=", "><", "<t+", ">t+", "t+", "t", "w", ">t-", "<t-", "t-", "!*", "*" ],
-                                 :date_past => [ "=", ">=", "<=", "><", ">t-", "<t-", "t-", "t", "w", "!*", "*" ],
-                                 :string => [ "=", "~", "!", "!~" ],
-                                 :text => [  "~", "!~" ],
-                                 :integer => [ "=", ">=", "<=", "><", "!*", "*" ],
-                                 :float => [ "=", ">=", "<=", "><", "!*", "*" ] }
-
-  cattr_reader :operators_by_filter_type
-
-  @@available_columns = [
-    QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
-    QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position", :groupable => true),
-    QueryColumn.new(:parent, :sortable => ["#{Issue.table_name}.root_id", "#{Issue.table_name}.lft ASC"], :default_order => 'desc', :caption => :field_parent_issue),
-    QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true),
-    QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc', :groupable => true),
-    QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
-    QueryColumn.new(:author, :sortable => lambda {User.fields_for_order_statement("authors")}, :groupable => true),
-    QueryColumn.new(:assigned_to, :sortable => lambda {User.fields_for_order_statement}, :groupable => true),
-    QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'),
-    QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true),
-    QueryColumn.new(:fixed_version, :sortable => ["#{Version.table_name}.effective_date", "#{Version.table_name}.name"], :default_order => 'desc', :groupable => true),
-    QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date"),
-    QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date"),
-    QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours"),
-    QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true),
-    QueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc'),
-  ]
-  cattr_reader :available_columns
-
-  named_scope :visible, lambda {|*args|
-    user = args.shift || User.current
-    base = Project.allowed_to_condition(user, :view_issues, *args)
-    user_id = user.logged? ? user.id : 0
-    {
-      :conditions => ["(#{table_name}.project_id IS NULL OR (#{base})) AND (#{table_name}.is_public = ? OR #{table_name}.user_id = ?)", true, user_id],
-      :include => :project
-    }
-  }
-
-  def initialize(attributes = nil)
-    super attributes
-    self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} }
-  end
-
-  def after_initialize
-    # Store the fact that project is nil (used in #editable_by?)
-    @is_for_all = project.nil?
-  end
-
-  def validate_query_filters
-    filters.each_key do |field|
-      if values_for(field)
-        case type_for(field)
-        when :integer
-          errors.add(label_for(field), :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+$/) }
-        when :float
-          errors.add(label_for(field), :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+(\.\d*)?$/) }
-        when :date, :date_past
-          case operator_for(field)
-          when "=", ">=", "<=", "><"
-            errors.add(label_for(field), :invalid) if values_for(field).detect {|v| v.present? && (!v.match(/^\d{4}-\d{2}-\d{2}$/) || (Date.parse(v) rescue nil).nil?) }
-          when ">t-", "<t-", "t-"
-            errors.add(label_for(field), :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+$/) }
-          end
-        end
-      end
-
-      errors.add label_for(field), :blank unless
-          # filter requires one or more values
-          (values_for(field) and !values_for(field).first.blank?) or
-          # filter doesn't require any value
-          ["o", "c", "!*", "*", "t", "w"].include? operator_for(field)
-    end if filters
-  end
-
-  # Returns true if the query is visible to +user+ or the current user.
-  def visible?(user=User.current)
-    (project.nil? || user.allowed_to?(:view_issues, project)) && (self.is_public? || self.user_id == user.id)
-  end
-
-  def editable_by?(user)
-    return false unless user
-    # Admin can edit them all and regular users can edit their private queries
-    return true if user.admin? || (!is_public && self.user_id == user.id)
-    # Members can not edit public queries that are for all project (only admin is allowed to)
-    is_public && !@is_for_all && user.allowed_to?(:manage_public_queries, project)
-  end
-
-  def available_filters
-    return @available_filters if @available_filters
-
-    trackers = project.nil? ? Tracker.find(:all, :order => 'position') : project.rolled_up_trackers
-
-    @available_filters = { "status_id" => { :type => :list_status, :order => 1, :values => IssueStatus.find(:all, :order => 'position').collect{|s| [s.name, s.id.to_s] } },
-                           "tracker_id" => { :type => :list, :order => 2, :values => trackers.collect{|s| [s.name, s.id.to_s] } },
-                           "priority_id" => { :type => :list, :order => 3, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s] } },
-                           "subject" => { :type => :text, :order => 8 },
-                           "created_on" => { :type => :date_past, :order => 9 },
-                           "updated_on" => { :type => :date_past, :order => 10 },
-                           "start_date" => { :type => :date, :order => 11 },
-                           "due_date" => { :type => :date, :order => 12 },
-                           "estimated_hours" => { :type => :float, :order => 13 },
-                           "done_ratio" =>  { :type => :integer, :order => 14 }}
-
-    principals = []
-    if project
-      principals += project.principals.sort
-    else
-      all_projects = Project.visible.all
-      if all_projects.any?
-        # members of visible projects
-        principals += Principal.active.find(:all, :conditions => ["#{User.table_name}.id IN (SELECT DISTINCT user_id FROM members WHERE project_id IN (?))", all_projects.collect(&:id)]).sort
-
-        # project filter
-        project_values = []
-        Project.project_tree(all_projects) do |p, level|
-          prefix = (level > 0 ? ('--' * level + ' ') : '')
-          project_values << ["#{prefix}#{p.name}", p.id.to_s]
-        end
-        @available_filters["project_id"] = { :type => :list, :order => 1, :values => project_values} unless project_values.empty?
-      end
-    end
-    users = principals.select {|p| p.is_a?(User)}
-
-    assigned_to_values = []
-    assigned_to_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
-    assigned_to_values += (Setting.issue_group_assignment? ? principals : users).collect{|s| [s.name, s.id.to_s] }
-    @available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => assigned_to_values } unless assigned_to_values.empty?
-
-    author_values = []
-    author_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
-    author_values += users.collect{|s| [s.name, s.id.to_s] }
-    @available_filters["author_id"] = { :type => :list, :order => 5, :values => author_values } unless author_values.empty?
-
-    group_values = Group.all.collect {|g| [g.name, g.id.to_s] }
-    @available_filters["member_of_group"] = { :type => :list_optional, :order => 6, :values => group_values } unless group_values.empty?
-
-    role_values = Role.givable.collect {|r| [r.name, r.id.to_s] }
-    @available_filters["assigned_to_role"] = { :type => :list_optional, :order => 7, :values => role_values } unless role_values.empty?
-
-    if User.current.logged?
-      @available_filters["watcher_id"] = { :type => :list, :order => 15, :values => [["<< #{l(:label_me)} >>", "me"]] }
-    end
-
-    if project
-      # project specific filters
-      categories = project.issue_categories.all
-      unless categories.empty?
-        @available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => categories.collect{|s| [s.name, s.id.to_s] } }
-      end
-      versions = project.shared_versions.all
-      unless versions.empty?
-        @available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => versions.sort.collect{|s| ["#{s.project.name} - #{s.name}", s.id.to_s] } }
-      end
-      unless project.leaf?
-        subprojects = project.descendants.visible.all
-        unless subprojects.empty?
-          @available_filters["subproject_id"] = { :type => :list_subprojects, :order => 13, :values => subprojects.collect{|s| [s.name, s.id.to_s] } }
-        end
-      end
-      add_custom_fields_filters(project.all_issue_custom_fields)
-    else
-      # global filters for cross project issue list
-      system_shared_versions = Version.visible.find_all_by_sharing('system')
-      unless system_shared_versions.empty?
-        @available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => system_shared_versions.sort.collect{|s| ["#{s.project.name} - #{s.name}", s.id.to_s] } }
-      end
-      add_custom_fields_filters(IssueCustomField.find(:all, :conditions => {:is_filter => true, :is_for_all => true}))
-    end
-    @available_filters
-  end
-
-  def add_filter(field, operator, values)
-    # values must be an array
-    return unless values.nil? || values.is_a?(Array)
-    # check if field is defined as an available filter
-    if available_filters.has_key? field
-      filter_options = available_filters[field]
-      # check if operator is allowed for that filter
-      #if @@operators_by_filter_type[filter_options[:type]].include? operator
-      #  allowed_values = values & ([""] + (filter_options[:values] || []).collect {|val| val[1]})
-      #  filters[field] = {:operator => operator, :values => allowed_values } if (allowed_values.first and !allowed_values.first.empty?) or ["o", "c", "!*", "*", "t"].include? operator
-      #end
-      filters[field] = {:operator => operator, :values => (values || [''])}
-    end
-  end
-
-  def add_short_filter(field, expression)
-    return unless expression && available_filters.has_key?(field)
-    field_type = available_filters[field][:type]
-    @@operators_by_filter_type[field_type].sort.reverse.detect do |operator|
-      next unless expression =~ /^#{Regexp.escape(operator)}(.*)$/
-      add_filter field, operator, $1.present? ? $1.split('|') : ['']
-    end || add_filter(field, '=', expression.split('|'))
-  end
-
-  # Add multiple filters using +add_filter+
-  def add_filters(fields, operators, values)
-    if fields.is_a?(Array) && operators.is_a?(Hash) && (values.nil? || values.is_a?(Hash))
-      fields.each do |field|
-        add_filter(field, operators[field], values && values[field])
-      end
-    end
-  end
-
-  def has_filter?(field)
-    filters and filters[field]
-  end
-
-  def type_for(field)
-    available_filters[field][:type] if available_filters.has_key?(field)
-  end
-
-  def operator_for(field)
-    has_filter?(field) ? filters[field][:operator] : nil
-  end
-
-  def values_for(field)
-    has_filter?(field) ? filters[field][:values] : nil
-  end
-
-  def value_for(field, index=0)
-    (values_for(field) || [])[index]
-  end
-
-  def label_for(field)
-    label = available_filters[field][:name] if available_filters.has_key?(field)
-    label ||= field.gsub(/\_id$/, "")
-  end
-
-  def available_columns
-    return @available_columns if @available_columns
-    @available_columns = ::Query.available_columns
-    @available_columns += (project ?
-                            project.all_issue_custom_fields :
-                            IssueCustomField.find(:all)
-                           ).collect {|cf| QueryCustomFieldColumn.new(cf) }
-  end
-
-  def self.available_columns=(v)
-    self.available_columns = (v)
-  end
-
-  def self.add_available_column(column)
-    self.available_columns << (column) if column.is_a?(QueryColumn)
-  end
-
-  # Returns an array of columns that can be used to group the results
-  def groupable_columns
-    available_columns.select {|c| c.groupable}
-  end
-
-  # Returns a Hash of columns and the key for sorting
-  def sortable_columns
-    {'id' => "#{Issue.table_name}.id"}.merge(available_columns.inject({}) {|h, column|
-                                               h[column.name.to_s] = column.sortable
-                                               h
-                                             })
-  end
-
-  def columns
-    # preserve the column_names order
-    (has_default_columns? ? default_columns_names : column_names).collect do |name|
-       available_columns.find { |col| col.name == name }
-    end.compact
-  end
-
-  def default_columns_names
-    @default_columns_names ||= begin
-      default_columns = Setting.issue_list_default_columns.map(&:to_sym)
-
-      project.present? ? default_columns : [:project] | default_columns
-    end
-  end
-
-  def column_names=(names)
-    if names
-      names = names.select {|n| n.is_a?(Symbol) || !n.blank? }
-      names = names.collect {|n| n.is_a?(Symbol) ? n : n.to_sym }
-      # Set column_names to nil if default columns
-      if names == default_columns_names
-        names = nil
-      end
-    end
-    write_attribute(:column_names, names)
-  end
-
-  def has_column?(column)
-    column_names && column_names.include?(column.name)
-  end
-
-  def has_default_columns?
-    column_names.nil? || column_names.empty?
-  end
-
-  def sort_criteria=(arg)
-    c = []
-    if arg.is_a?(Hash)
-      arg = arg.keys.sort.collect {|k| arg[k]}
-    end
-    c = arg.select {|k,o| !k.to_s.blank?}.slice(0,3).collect {|k,o| [k.to_s, o == 'desc' ? o : 'asc']}
-    write_attribute(:sort_criteria, c)
-  end
-
-  def sort_criteria
-    read_attribute(:sort_criteria) || []
-  end
-
-  def sort_criteria_key(arg)
-    sort_criteria && sort_criteria[arg] && sort_criteria[arg].first
-  end
-
-  def sort_criteria_order(arg)
-    sort_criteria && sort_criteria[arg] && sort_criteria[arg].last
-  end
-
-  # Returns the SQL sort order that should be prepended for grouping
-  def group_by_sort_order
-    if grouped? && (column = group_by_column)
-      column.sortable.is_a?(Array) ?
-        column.sortable.collect {|s| "#{s} #{column.default_order}"}.join(',') :
-        "#{column.sortable} #{column.default_order}"
-    end
-  end
-
-  # Returns true if the query is a grouped query
-  def grouped?
-    !group_by_column.nil?
-  end
-
-  def group_by_column
-    groupable_columns.detect {|c| c.groupable && c.name.to_s == group_by}
-  end
-
-  def group_by_statement
-    group_by_column.try(:groupable)
-  end
-
-  def project_statement
-    project_clauses = []
-    if project && !project.descendants.active.empty?
-      ids = [project.id]
-      if has_filter?("subproject_id")
-        case operator_for("subproject_id")
-        when '='
-          # include the selected subprojects
-          ids += values_for("subproject_id").each(&:to_i)
-        when '!*'
-          # main project only
-        else
-          # all subprojects
-          ids += project.descendants.collect(&:id)
-        end
-      elsif Setting.display_subprojects_issues?
-        ids += project.descendants.collect(&:id)
-      end
-      project_clauses << "#{Project.table_name}.id IN (%s)" % ids.join(',')
-    elsif project
-      project_clauses << "#{Project.table_name}.id = %d" % project.id
-    end
-    project_clauses.any? ? project_clauses.join(' AND ') : nil
-  end
-
-  def statement
-    # filters clauses
-    filters_clauses = []
-    filters.each_key do |field|
-      next if field == "subproject_id"
-      v = values_for(field).clone
-      next unless v and !v.empty?
-      operator = operator_for(field)
-
-      # "me" value subsitution
-      if %w(assigned_to_id author_id watcher_id).include?(field)
-        if v.delete("me")
-          if User.current.logged?
-            v.push(User.current.id.to_s)
-            v += User.current.group_ids.map(&:to_s) if field == 'assigned_to_id'
-          else
-            v.push("0")
-          end
-        end
-      end
-
-      if field =~ /^cf_(\d+)$/
-        # custom field
-        filters_clauses << sql_for_custom_field(field, operator, v, $1)
-      elsif respond_to?("sql_for_#{field}_field")
-        # specific statement
-        filters_clauses << send("sql_for_#{field}_field", field, operator, v)
-      else
-        # regular field
-        filters_clauses << '(' + sql_for_field(field, operator, v, Issue.table_name, field) + ')'
-      end
-    end if filters and valid?
-
-    filters_clauses << project_statement
-    filters_clauses.reject!(&:blank?)
-
-    filters_clauses.any? ? filters_clauses.join(' AND ') : nil
-  end
-
-  # Returns the issue count
-  def issue_count
-    Issue.visible.count(:include => [:status, :project], :conditions => statement)
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  # Returns the issue count by group or nil if query is not grouped
-  def issue_count_by_group
-    r = nil
-    if grouped?
-      begin
-        # Rails will raise an (unexpected) RecordNotFound if there's only a nil group value
-        r = Issue.visible.count(:group => group_by_statement, :include => [:status, :project], :conditions => statement)
-      rescue ActiveRecord::RecordNotFound
-        r = {nil => issue_count}
-      end
-      c = group_by_column
-      if c.is_a?(QueryCustomFieldColumn)
-        r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h}
-      end
-    end
-    r
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  # Returns the issues
-  # Valid options are :order, :offset, :limit, :include, :conditions
-  def issues(options={})
-    order_option = [group_by_sort_order, options[:order]].reject {|s| s.blank?}.join(',')
-    order_option = nil if order_option.blank?
-    
-    joins = (order_option && order_option.include?('authors')) ? "LEFT OUTER JOIN users authors ON authors.id = #{Issue.table_name}.author_id" : nil
-
-    Issue.visible.scoped(:conditions => options[:conditions]).find :all, :include => ([:status, :project] + (options[:include] || [])).uniq,
-                     :conditions => statement,
-                     :order => order_option,
-                     :joins => joins,
-                     :limit  => options[:limit],
-                     :offset => options[:offset]
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  # Returns the journals
-  # Valid options are :order, :offset, :limit
-  def journals(options={})
-    Journal.visible.find :all, :include => [:details, :user, {:issue => [:project, :author, :tracker, :status]}],
-                       :conditions => statement,
-                       :order => options[:order],
-                       :limit => options[:limit],
-                       :offset => options[:offset]
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  # Returns the versions
-  # Valid options are :conditions
-  def versions(options={})
-    Version.visible.scoped(:conditions => options[:conditions]).find :all, :include => :project, :conditions => project_statement
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  def sql_for_watcher_id_field(field, operator, value)
-    db_table = Watcher.table_name
-    "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND " +
-      sql_for_field(field, '=', value, db_table, 'user_id') + ')'
-  end
-
-  def sql_for_member_of_group_field(field, operator, value)
-    if operator == '*' # Any group
-      groups = Group.all
-      operator = '=' # Override the operator since we want to find by assigned_to
-    elsif operator == "!*"
-      groups = Group.all
-      operator = '!' # Override the operator since we want to find by assigned_to
-    else
-      groups = Group.find_all_by_id(value)
-    end
-    groups ||= []
-
-    members_of_groups = groups.inject([]) {|user_ids, group|
-      if group && group.user_ids.present?
-        user_ids << group.user_ids
-      end
-      user_ids.flatten.uniq.compact
-    }.sort.collect(&:to_s)
-
-    '(' + sql_for_field("assigned_to_id", operator, members_of_groups, Issue.table_name, "assigned_to_id", false) + ')'
-  end
-
-  def sql_for_assigned_to_role_field(field, operator, value)
-    case operator
-    when "*", "!*" # Member / Not member
-      sw = operator == "!*" ? 'NOT' : ''
-      nl = operator == "!*" ? "#{Issue.table_name}.assigned_to_id IS NULL OR" : ''
-      "(#{nl} #{Issue.table_name}.assigned_to_id #{sw} IN (SELECT DISTINCT #{Member.table_name}.user_id FROM #{Member.table_name}" +
-        " WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id))"
-    when "=", "!"
-      role_cond = value.any? ? 
-        "#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")" :
-        "1=0"
-      
-      sw = operator == "!" ? 'NOT' : ''
-      nl = operator == "!" ? "#{Issue.table_name}.assigned_to_id IS NULL OR" : ''
-      "(#{nl} #{Issue.table_name}.assigned_to_id #{sw} IN (SELECT DISTINCT #{Member.table_name}.user_id FROM #{Member.table_name}, #{MemberRole.table_name}" +
-        " WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id AND #{Member.table_name}.id = #{MemberRole.table_name}.member_id AND #{role_cond}))"
-    end
-  end
-
-  private
-
-  def sql_for_custom_field(field, operator, value, custom_field_id)
-    db_table = CustomValue.table_name
-    db_field = 'value'
-    "#{Issue.table_name}.id IN (SELECT #{Issue.table_name}.id FROM #{Issue.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='Issue' AND #{db_table}.customized_id=#{Issue.table_name}.id AND #{db_table}.custom_field_id=#{custom_field_id} WHERE " +
-      sql_for_field(field, operator, value, db_table, db_field, true) + ')'
-  end
-
-  # Helper method to generate the WHERE sql for a +field+, +operator+ and a +value+
-  def sql_for_field(field, operator, value, db_table, db_field, is_custom_filter=false)
-    sql = ''
-    case operator
-    when "="
-      if value.any?
-        case type_for(field)
-        when :date, :date_past
-          sql = date_clause(db_table, db_field, (Date.parse(value.first) rescue nil), (Date.parse(value.first) rescue nil))
-        when :integer
-          sql = "#{db_table}.#{db_field} = #{value.first.to_i}"
-        when :float
-          sql = "#{db_table}.#{db_field} BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5}"
-        else
-          sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")"
-        end
-      else
-        # IN an empty set
-        sql = "1=0"
-      end
-    when "!"
-      if value.any?
-        sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))"
-      else
-        # NOT IN an empty set
-        sql = "1=1"
-      end
-    when "!*"
-      sql = "#{db_table}.#{db_field} IS NULL"
-      sql << " OR #{db_table}.#{db_field} = ''" if is_custom_filter
-    when "*"
-      sql = "#{db_table}.#{db_field} IS NOT NULL"
-      sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter
-    when ">="
-      if [:date, :date_past].include?(type_for(field))
-        sql = date_clause(db_table, db_field, (Date.parse(value.first) rescue nil), nil)
-      else
-        if is_custom_filter
-          sql = "CAST(#{db_table}.#{db_field} AS decimal(60,3)) >= #{value.first.to_f}"
-        else
-          sql = "#{db_table}.#{db_field} >= #{value.first.to_f}"
-        end
-      end
-    when "<="
-      if [:date, :date_past].include?(type_for(field))
-        sql = date_clause(db_table, db_field, nil, (Date.parse(value.first) rescue nil))
-      else
-        if is_custom_filter
-          sql = "CAST(#{db_table}.#{db_field} AS decimal(60,3)) <= #{value.first.to_f}"
-        else
-          sql = "#{db_table}.#{db_field} <= #{value.first.to_f}"
-        end
-      end
-    when "><"
-      if [:date, :date_past].include?(type_for(field))
-        sql = date_clause(db_table, db_field, (Date.parse(value[0]) rescue nil), (Date.parse(value[1]) rescue nil))
-      else
-        if is_custom_filter
-          sql = "CAST(#{db_table}.#{db_field} AS decimal(60,3)) BETWEEN #{value[0].to_f} AND #{value[1].to_f}"
-        else
-          sql = "#{db_table}.#{db_field} BETWEEN #{value[0].to_f} AND #{value[1].to_f}"
-        end
-      end
-    when "o"
-      sql = "#{IssueStatus.table_name}.is_closed=#{connection.quoted_false}" if field == "status_id"
-    when "c"
-      sql = "#{IssueStatus.table_name}.is_closed=#{connection.quoted_true}" if field == "status_id"
-    when ">t-"
-      sql = relative_date_clause(db_table, db_field, - value.first.to_i, 0)
-    when "<t-"
-      sql = relative_date_clause(db_table, db_field, nil, - value.first.to_i)
-    when "t-"
-      sql = relative_date_clause(db_table, db_field, - value.first.to_i, - value.first.to_i)
-    when ">t+"
-      sql = relative_date_clause(db_table, db_field, value.first.to_i, nil)
-    when "<t+"
-      sql = relative_date_clause(db_table, db_field, 0, value.first.to_i)
-    when "t+"
-      sql = relative_date_clause(db_table, db_field, value.first.to_i, value.first.to_i)
-    when "t"
-      sql = relative_date_clause(db_table, db_field, 0, 0)
-    when "w"
-      first_day_of_week = l(:general_first_day_of_week).to_i
-      day_of_week = Date.today.cwday
-      days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
-      sql = relative_date_clause(db_table, db_field, - days_ago, - days_ago + 6)
-    when "~"
-      sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
-    when "!~"
-      sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
-    else
-      raise "Unknown query operator #{operator}"
-    end
-
-    return sql
-  end
-
-  def add_custom_fields_filters(custom_fields)
-    @available_filters ||= {}
-
-    custom_fields.select(&:is_filter?).each do |field|
-      case field.field_format
-      when "text"
-        options = { :type => :text, :order => 20 }
-      when "list"
-        options = { :type => :list_optional, :values => field.possible_values, :order => 20}
-      when "date"
-        options = { :type => :date, :order => 20 }
-      when "bool"
-        options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], :order => 20 }
-      when "int"
-        options = { :type => :integer, :order => 20 }
-      when "float"
-        options = { :type => :float, :order => 20 }
-      when "user", "version"
-        next unless project
-        options = { :type => :list_optional, :values => field.possible_values_options(project), :order => 20}
-      else
-        options = { :type => :string, :order => 20 }
-      end
-      @available_filters["cf_#{field.id}"] = options.merge({ :name => field.name })
-    end
-  end
-
-  # Returns a SQL clause for a date or datetime field.
-  def date_clause(table, field, from, to)
-    s = []
-    if from
-      from_yesterday = from - 1
-      from_yesterday_utc = Time.gm(from_yesterday.year, from_yesterday.month, from_yesterday.day)
-      s << ("#{table}.#{field} > '%s'" % [connection.quoted_date(from_yesterday_utc.end_of_day)])
-    end
-    if to
-      to_utc = Time.gm(to.year, to.month, to.day)
-      s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date(to_utc.end_of_day)])
-    end
-    s.join(' AND ')
-  end
-
-  # Returns a SQL clause for a date or datetime field using relative dates.
-  def relative_date_clause(table, field, days_from, days_to)
-    date_clause(table, field, (days_from ? Date.today + days_from : nil), (days_to ? Date.today + days_to : nil))
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/52004253c47464e971de8985c2ff7d4abac9aadd.svn-base
--- a/.svn/pristine/52/52004253c47464e971de8985c2ff7d4abac9aadd.svn-base
+++ /dev/null
@@ -1,60 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'net/imap'
-
-module Redmine
-  module IMAP
-    class << self
-      def check(imap_options={}, options={})
-        host = imap_options[:host] || '127.0.0.1'
-        port = imap_options[:port] || '143'
-        ssl = !imap_options[:ssl].nil?
-        folder = imap_options[:folder] || 'INBOX'
-
-        imap = Net::IMAP.new(host, port, ssl)
-        imap.login(imap_options[:username], imap_options[:password]) unless imap_options[:username].nil?
-        imap.select(folder)
-        imap.search(['NOT', 'SEEN']).each do |message_id|
-          msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
-          logger.debug "Receiving message #{message_id}" if logger && logger.debug?
-          if MailHandler.receive(msg, options)
-            logger.debug "Message #{message_id} successfully received" if logger && logger.debug?
-            if imap_options[:move_on_success]
-              imap.copy(message_id, imap_options[:move_on_success])
-            end
-            imap.store(message_id, "+FLAGS", [:Seen, :Deleted])
-          else
-            logger.debug "Message #{message_id} can not be processed" if logger && logger.debug?
-            imap.store(message_id, "+FLAGS", [:Seen])
-            if imap_options[:move_on_failure]
-              imap.copy(message_id, imap_options[:move_on_failure])
-              imap.store(message_id, "+FLAGS", [:Deleted])
-            end
-          end
-        end
-        imap.expunge
-      end
-
-      private
-
-      def logger
-        RAILS_DEFAULT_LOGGER
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/5207c75436c85ec591b380afe15450272eeedb94.svn-base
--- a/.svn/pristine/52/5207c75436c85ec591b380afe15450272eeedb94.svn-base
+++ /dev/null
@@ -1,81 +0,0 @@
-module CodeRay
-  
-  # = Duo
-  #
-  # A Duo is a convenient way to use CodeRay. You just create a Duo,
-  # giving it a lang (language of the input code) and a format (desired
-  # output format), and call Duo#highlight with the code.
-  # 
-  # Duo makes it easy to re-use both scanner and encoder for a repetitive
-  # task. It also provides a very easy interface syntax:
-  # 
-  #   require 'coderay'
-  #   CodeRay::Duo[:python, :div].highlight 'import this'
-  # 
-  # Until you want to do uncommon things with CodeRay, I recommend to use
-  # this method, since it takes care of everything.
-  class Duo
-
-    attr_accessor :lang, :format, :options
-    
-    # Create a new Duo, holding a lang and a format to highlight code.
-    # 
-    # simple:
-    #   CodeRay::Duo[:ruby, :html].highlight 'bla 42'
-    # 
-    # with options:
-    #   CodeRay::Duo[:ruby, :html, :hint => :debug].highlight '????::??'
-    # 
-    # alternative syntax without options:
-    #   CodeRay::Duo[:ruby => :statistic].encode 'class << self; end'
-    # 
-    # alternative syntax with options:
-    #   CodeRay::Duo[{ :ruby => :statistic }, :do => :something].encode 'abc'
-    # 
-    # The options are forwarded to scanner and encoder
-    # (see CodeRay.get_scanner_options).
-    def initialize lang = nil, format = nil, options = {}
-      if format.nil? && lang.is_a?(Hash) && lang.size == 1
-        @lang = lang.keys.first
-        @format = lang[@lang]
-      else
-        @lang = lang
-        @format = format
-      end
-      @options = options
-    end
-    
-    class << self
-      # To allow calls like Duo[:ruby, :html].highlight.
-      alias [] new
-    end
-    
-    # The scanner of the duo. Only created once.
-    def scanner
-      @scanner ||= CodeRay.scanner @lang, CodeRay.get_scanner_options(@options)
-    end
-    
-    # The encoder of the duo. Only created once.
-    def encoder
-      @encoder ||= CodeRay.encoder @format, @options
-    end
-    
-    # Tokenize and highlight the code using +scanner+ and +encoder+.
-    def encode code, options = {}
-      options = @options.merge options
-      encoder.encode(code, @lang, options)
-    end
-    alias highlight encode
-    
-    # Allows to use Duo like a proc object:
-    # 
-    #  CodeRay::Duo[:python => :yaml].call(code)
-    # 
-    # or, in Ruby 1.9 and later:
-    # 
-    #  CodeRay::Duo[:python => :yaml].(code)
-    alias call encode
-    
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/520b379788e40ebe77f4044b9785418c4b20c19c.svn-base
--- a/.svn/pristine/52/520b379788e40ebe77f4044b9785418c4b20c19c.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Translater: Mads N. Vestergaard <mnv@coolsms.dk>
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("SÃ¸ndag",
- "Mandag",
- "Tirsdag",
- "Onsdag",
- "Torsdag",
- "Fredag",
- "LÃ¸rdag",
- "SÃ¸ndag");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("SÃ¸n",
- "Man",
- "Tir",
- "Ons",
- "Tor",
- "Fre",
- "LÃ¸r",
- "SÃ¸n");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Januar",
- "Februar",
- "Marts",
- "April",
- "Maj",
- "Juni",
- "Juli",
- "August",
- "September",
- "Oktober",
- "November",
- "December");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "Mar",
- "Apr",
- "Maj",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Okt",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Om denne kalender";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For seneste version, besÃ¸g: http://www.dynarch.com/projects/calendar/\n" +
-"Distribueret under GNU LGPL.  Se http://gnu.org/licenses/lgpl.html for detaljer." +
-"\n\n" +
-"Dato valg:\n" +
-"- Benyt \xab, \xbb tasterne til at vÃ¦lge Ã¥r\n" +
-"- Benyt " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " tasterne til at vÃ¦lge mÃ¥ned\n" +
-"- Hold musetasten inde pÃ¥ punkterne for at vÃ¦lge hurtigere.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Tids valg:\n" +
-"- Klik pÃ¥ en af tidsrammerne for at forhÃ¸je det\n" +
-"- eller Shift-klik for at mindske det\n" +
-"- eller klik og trÃ¦k for hurtigere valg.";
-
-Calendar._TT["PREV_YEAR"] = "Forrige Ã¥r (hold for menu)";
-Calendar._TT["PREV_MONTH"] = "Forrige mÃ¥ned (hold for menu)";
-Calendar._TT["GO_TODAY"] = "GÃ¥ til dags dato";
-Calendar._TT["NEXT_MONTH"] = "NÃ¦ste mÃ¥ned (hold for menu)";
-Calendar._TT["NEXT_YEAR"] = "NÃ¦ste Ã¥r (hold for menu)";
-Calendar._TT["SEL_DATE"] = "VÃ¦lg dato";
-Calendar._TT["DRAG_TO_MOVE"] = "TrÃ¦k for at flytte";
-Calendar._TT["PART_TODAY"] = " (dags dato)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Vis %s fÃ¸rst";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "6,7";
-
-Calendar._TT["CLOSE"] = "Luk";
-Calendar._TT["TODAY"] = "I dag";
-Calendar._TT["TIME_PART"] = "(Shift-)Klik eller trÃ¦k for at Ã¦ndre vÃ¦rdi";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "uge";
-Calendar._TT["TIME"] = "Tid:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/5239875e2f66506ef4227a2d0ff1c43dcfbd22ad.svn-base
--- a/.svn/pristine/52/5239875e2f66506ef4227a2d0ff1c43dcfbd22ad.svn-base
+++ /dev/null
@@ -1,121 +0,0 @@
-<ul>
-  <%= call_hook(:view_issues_context_menu_start, {:issues => @issues, :can => @can, :back => @back }) %>
-
-<% if !@issue.nil? -%>
-  <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
-          :class => 'icon-edit', :disabled => !@can[:edit] %></li>
-<% else %>
-  <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id)},
-          :class => 'icon-edit', :disabled => !@can[:edit] %></li>
-<% end %>
-
-  <% if @allowed_statuses.present? %>
-  <li class="folder">
-    <a href="#" class="submenu" onclick="return false;"><%= l(:field_status) %></a>
-    <ul>
-    <% @statuses.each do |s| -%>
-        <li><%= context_menu_link h(s.name), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {:status_id => s}, :back_url => @back}, :method => :post,
-                                  :selected => (@issue && s == @issue.status), :disabled => !(@can[:update] && @allowed_statuses.include?(s)) %></li>
-    <% end -%>
-    </ul>
-  </li>
-  <% end %>
-
-  <% unless @trackers.nil? %>
-  <li class="folder">
-    <a href="#" class="submenu"><%= l(:field_tracker) %></a>
-    <ul>
-    <% @trackers.each do |t| -%>
-        <li><%= context_menu_link h(t.name), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {'tracker_id' => t}, :back_url => @back}, :method => :post,
-                                  :selected => (@issue && t == @issue.tracker), :disabled => !@can[:edit] %></li>
-    <% end -%>
-    </ul>
-  </li>
-  <% end %>
-
-  <li class="folder">
-    <a href="#" class="submenu"><%= l(:field_priority) %></a>
-    <ul>
-    <% @priorities.each do |p| -%>
-        <li><%= context_menu_link h(p.name), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {'priority_id' => p}, :back_url => @back}, :method => :post,
-                                  :selected => (@issue && p == @issue.priority), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
-    <% end -%>
-    </ul>
-  </li>
-
-  <% #TODO: allow editing versions when multiple projects %>
-  <% unless @project.nil? || @project.shared_versions.open.empty? -%>
-  <li class="folder">
-    <a href="#" class="submenu"><%= l(:field_fixed_version) %></a>
-    <ul>
-    <% @project.shared_versions.open.sort.each do |v| -%>
-        <li><%= context_menu_link format_version_name(v), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => v}, :back_url => @back}, :method => :post,
-                                  :selected => (@issue && v == @issue.fixed_version), :disabled => !@can[:update] %></li>
-    <% end -%>
-        <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => 'none'}, :back_url => @back}, :method => :post,
-                                  :selected => (@issue && @issue.fixed_version.nil?), :disabled => !@can[:update] %></li>
-    </ul>
-  </li>
-  <% end %>
-  <% if @assignables.present? -%>
-  <li class="folder">
-    <a href="#" class="submenu"><%= l(:field_assigned_to) %></a>
-    <ul>
-    <% @assignables.each do |u| -%>
-        <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => u}, :back_url => @back}, :method => :post,
-                                  :selected => (@issue && u == @issue.assigned_to), :disabled => !@can[:update] %></li>
-    <% end -%>
-        <li><%= context_menu_link l(:label_nobody), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => 'none'}, :back_url => @back}, :method => :post,
-                                  :selected => (@issue && @issue.assigned_to.nil?), :disabled => !@can[:update] %></li>
-    </ul>
-  </li>
-  <% end %>
-  <% unless @project.nil? || @project.issue_categories.empty? -%>
-  <li class="folder">
-    <a href="#" class="submenu"><%= l(:field_category) %></a>
-    <ul>
-    <% @project.issue_categories.each do |u| -%>
-        <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {'category_id' => u}, :back_url => @back}, :method => :post,
-                                  :selected => (@issue && u == @issue.category), :disabled => !@can[:update] %></li>
-    <% end -%>
-        <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {'category_id' => 'none'}, :back_url => @back}, :method => :post,
-                                  :selected => (@issue && @issue.category.nil?), :disabled => !@can[:update] %></li>
-    </ul>
-  </li>
-  <% end -%>
-
-  <% if Issue.use_field_for_done_ratio? %>
-  <li class="folder">
-    <a href="#" class="submenu"><%= l(:field_done_ratio) %></a>
-    <ul>
-    <% (0..10).map{|x|x*10}.each do |p| -%>
-        <li><%= context_menu_link "#{p}%", {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :issue => {'done_ratio' => p}, :back_url => @back}, :method => :post,
-                                      :selected => (@issue && p == @issue.done_ratio), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
-    <% end -%>
-    </ul>
-  </li>
-  <% end %>
-
-<% if !@issue.nil? %>
-  <% if @can[:log_time] -%>
-  <li><%= context_menu_link l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue},
-          :class => 'icon-time-add' %></li>
-  <% end %>
-  <% if User.current.logged? %>
-  <li><%= watcher_link(@issue, User.current) %></li>
-  <% end %>
-<% end %>
-
-<% if @issue.present? %>
-  <li><%= context_menu_link l(:button_duplicate), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue},
-          :class => 'icon-duplicate', :disabled => !@can[:copy] %></li>
-<% end %>
-  <li><%= context_menu_link l(:button_copy), new_issue_move_path(:ids => @issues.collect(&:id), :copy_options => {:copy => 't'}),
-                          :class => 'icon-copy', :disabled => !@can[:move]  %></li>
-  <li><%= context_menu_link l(:button_move), new_issue_move_path(:ids => @issues.collect(&:id)),
-                          :class => 'icon-move', :disabled => !@can[:move]  %></li>
-  <li><%= context_menu_link l(:button_delete), {:controller => 'issues', :action => 'destroy', :ids => @issues.collect(&:id), :back_url => @back},
-                            :method => :post, :confirm => issues_destroy_confirmation_message(@issues), :class => 'icon-del', :disabled => !@can[:delete] %></li>
-
-  <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %>
-</ul>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/523c9c2d9c7b015aa1113d76af95f9049ad0813d.svn-base
--- a/.svn/pristine/52/523c9c2d9c7b015aa1113d76af95f9049ad0813d.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-# Only call Engines.init once, in the after_initialize block so that Rails
-# plugin reloading works when turned on
-config.after_initialize do
-  Engines.init(initializer) if defined? :Engines
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/524c64f89f9b5171077500c8f6e0240696dfd698.svn-base
--- a/.svn/pristine/52/524c64f89f9b5171077500c8f6e0240696dfd698.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/generate'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/52835e85663e2540d36b9bff7e6cf6a1403991c9.svn-base
--- a/.svn/pristine/52/52835e85663e2540d36b9bff7e6cf6a1403991c9.svn-base
+++ /dev/null
@@ -1,115 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::CodesetUtilTest < ActiveSupport::TestCase
-
-  def test_to_utf8_by_setting_from_latin1
-    with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
-      s1 = "Texte encod\xc3\xa9"
-      s2 = "Texte encod\xe9"
-      s3 = s2.dup
-      if s1.respond_to?(:force_encoding)
-        s1.force_encoding("UTF-8")
-        s2.force_encoding("ASCII-8BIT")
-        s3.force_encoding("UTF-8")
-      end
-      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2)
-      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3)
-    end
-  end
-
-  def test_to_utf8_by_setting_from_euc_jp
-    with_settings :repositories_encodings => 'UTF-8,EUC-JP' do
-      s1 = "\xe3\x83\xac\xe3\x83\x83\xe3\x83\x89\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\xb3"
-      s2 = "\xa5\xec\xa5\xc3\xa5\xc9\xa5\xde\xa5\xa4\xa5\xf3"
-      s3 = s2.dup
-      if s1.respond_to?(:force_encoding)
-        s1.force_encoding("UTF-8")
-        s2.force_encoding("ASCII-8BIT")
-        s3.force_encoding("UTF-8")
-      end
-      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2)
-      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3)
-    end
-  end
-
-  def test_to_utf8_by_setting_should_be_converted_all_latin1
-    with_settings :repositories_encodings => 'ISO-8859-1' do
-      s1 = "\xc3\x82\xc2\x80"
-      s2 = "\xC2\x80"
-      s3 = s2.dup
-      if s1.respond_to?(:force_encoding)
-        s1.force_encoding("UTF-8")
-        s2.force_encoding("ASCII-8BIT")
-        s3.force_encoding("UTF-8")
-      end
-      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2)
-      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3)
-    end
-  end
-
-  def test_to_utf8_by_setting_blank_string
-    assert_equal "",  Redmine::CodesetUtil.to_utf8_by_setting("")
-    assert_equal nil, Redmine::CodesetUtil.to_utf8_by_setting(nil)
-  end
-
-  def test_to_utf8_by_setting_returns_ascii_as_utf8
-    s1 = "ASCII"
-    s2 = s1.dup
-    if s1.respond_to?(:force_encoding)
-      s1.force_encoding("UTF-8")
-      s2.force_encoding("ISO-8859-1")
-    end
-    str1 = Redmine::CodesetUtil.to_utf8_by_setting(s1)
-    str2 = Redmine::CodesetUtil.to_utf8_by_setting(s2)
-    assert_equal s1, str1
-    assert_equal s1, str2
-    if s1.respond_to?(:force_encoding)
-      assert_equal "UTF-8", str1.encoding.to_s
-      assert_equal "UTF-8", str2.encoding.to_s
-    end
-  end
-
-  def test_to_utf8_by_setting_invalid_utf8_sequences_should_be_stripped
-    with_settings :repositories_encodings => '' do
-      # s1 = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
-      s1 = "Texte encod\xe9 en ISO-8859-1."
-      s1.force_encoding("ASCII-8BIT") if s1.respond_to?(:force_encoding)
-      str = Redmine::CodesetUtil.to_utf8_by_setting(s1)
-      if str.respond_to?(:force_encoding)
-        assert str.valid_encoding?
-        assert_equal "UTF-8", str.encoding.to_s
-      end
-      assert_equal "Texte encod? en ISO-8859-1.", str
-    end
-  end
-
-  def test_to_utf8_by_setting_invalid_utf8_sequences_should_be_stripped_ja_jis
-    with_settings :repositories_encodings => 'ISO-2022-JP' do
-      s1 = "test\xb5\xfetest\xb5\xfe"
-      s1.force_encoding("ASCII-8BIT") if s1.respond_to?(:force_encoding)
-      str = Redmine::CodesetUtil.to_utf8_by_setting(s1)
-      if str.respond_to?(:force_encoding)
-        assert str.valid_encoding?
-        assert_equal "UTF-8", str.encoding.to_s
-      end
-      assert_equal "test??test??", str
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/52861ceb2f3a417977bfbcbe6c0ba816774849bd.svn-base
--- a/.svn/pristine/52/52861ceb2f3a417977bfbcbe6c0ba816774849bd.svn-base
+++ /dev/null
@@ -1,101 +0,0 @@
---- 
-enabled_modules_001: 
-  name: issue_tracking
-  project_id: 1
-  id: 1
-enabled_modules_002: 
-  name: time_tracking
-  project_id: 1
-  id: 2
-enabled_modules_003: 
-  name: news
-  project_id: 1
-  id: 3
-enabled_modules_004: 
-  name: documents
-  project_id: 1
-  id: 4
-enabled_modules_005: 
-  name: files
-  project_id: 1
-  id: 5
-enabled_modules_006: 
-  name: wiki
-  project_id: 1
-  id: 6
-enabled_modules_007: 
-  name: repository
-  project_id: 1
-  id: 7
-enabled_modules_008: 
-  name: boards
-  project_id: 1
-  id: 8
-enabled_modules_009: 
-  name: repository
-  project_id: 3
-  id: 9
-enabled_modules_010: 
-  name: wiki
-  project_id: 3
-  id: 10
-enabled_modules_011: 
-  name: issue_tracking
-  project_id: 2
-  id: 11
-enabled_modules_012: 
-  name: time_tracking
-  project_id: 3
-  id: 12
-enabled_modules_013: 
-  name: issue_tracking
-  project_id: 3
-  id: 13
-enabled_modules_014: 
-  name: issue_tracking
-  project_id: 5
-  id: 14
-enabled_modules_015: 
-  name: wiki
-  project_id: 2
-  id: 15
-enabled_modules_016: 
-  name: boards
-  project_id: 2
-  id: 16
-enabled_modules_017: 
-  name: calendar
-  project_id: 1
-  id: 17
-enabled_modules_018: 
-  name: gantt 
-  project_id: 1
-  id: 18
-enabled_modules_019: 
-  name: calendar
-  project_id: 2
-  id: 19
-enabled_modules_020: 
-  name: gantt 
-  project_id: 2
-  id: 20
-enabled_modules_021: 
-  name: calendar
-  project_id: 3
-  id: 21
-enabled_modules_022: 
-  name: gantt
-  project_id: 3
-  id: 22
-enabled_modules_023: 
-  name: calendar
-  project_id: 5
-  id: 23
-enabled_modules_024: 
-  name: gantt 
-  project_id: 5
-  id: 24
-enabled_modules_025: 
-  name: news 
-  project_id: 2
-  id: 25
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/52e141046a10068211408d55ec6484cccb3d452a.svn-base
--- /dev/null
+++ b/.svn/pristine/52/52e141046a10068211408d55ec6484cccb3d452a.svn-base
@@ -0,0 +1,18 @@
+class CreateEnabledModules < ActiveRecord::Migration
+  def self.up
+    create_table :enabled_modules do |t|
+      t.column :project_id, :integer
+      t.column :name, :string, :null => false
+    end
+    add_index :enabled_modules, [:project_id], :name => :enabled_modules_project_id
+
+    # Enable all modules for existing projects
+    Project.all.each do |project|
+      project.enabled_module_names = Redmine::AccessControl.available_project_modules
+    end
+  end
+
+  def self.down
+    drop_table :enabled_modules
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/52f0bf1c239cf648c203a8def6f59245b007d594.svn-base
--- a/.svn/pristine/52/52f0bf1c239cf648c203a8def6f59245b007d594.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/console'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/52/52fb1ca187bdbea92b2ca21fb1a15fadb8ae488e.svn-base
--- a/.svn/pristine/52/52fb1ca187bdbea92b2ca21fb1a15fadb8ae488e.svn-base
+++ /dev/null
@@ -1,51 +0,0 @@
-# Tests in this file ensure that:
-#
-# * plugin controller actions are found
-# * actions defined in application controllers take precedence over those in plugins
-# * actions in controllers in subsequently loaded plugins take precendence over those in previously loaded plugins
-# * this works for actions in namespaced controllers accordingly
-
-require File.dirname(__FILE__) + '/../test_helper'
-
-class ControllerLoadingTest < ActionController::TestCase
-  def setup
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-  end
-
-  # plugin controller actions should be found
-
-	def test_WITH_an_action_defined_only_in_a_plugin_IT_should_use_this_action
-	  get_action_on_controller :an_action, :alpha_plugin
-    assert_response_body 'rendered in AlphaPluginController#an_action'
-  end
-  
-	def test_WITH_an_action_defined_only_in_a_namespaced_plugin_controller_IT_should_use_this_action
-	  get_action_on_controller :an_action, :alpha_plugin, :namespace
-    assert_response_body 'rendered in Namespace::AlphaPluginController#an_action'
-  end
-
-  # app takes precedence over plugins
-
-  def test_WITH_an_action_defined_in_both_app_and_plugin_IT_should_use_the_one_in_app
-	  get_action_on_controller :an_action, :app_and_plugin
-    assert_response_body 'rendered in AppAndPluginController#an_action (from app)'
-  end
-  
-  def test_WITH_an_action_defined_in_namespaced_controllers_in_both_app_and_plugin_IT_should_use_the_one_in_app
-	  get_action_on_controller :an_action, :app_and_plugin, :namespace
-    assert_response_body 'rendered in Namespace::AppAndPluginController#an_action (from app)'
-  end
-
-  # subsequently loaded plugins take precendence over previously loaded plugins
-
-  def test_WITH_an_action_defined_in_two_plugin_controllers_IT_should_use_the_latter_of_both
-	  get_action_on_controller :an_action, :shared_plugin
-    assert_response_body 'rendered in SharedPluginController#an_action (from beta_plugin)'
-  end
-  
-  def test_WITH_an_action_defined_in_two_namespaced_plugin_controllers_IT_should_use_the_latter_of_both
-	  get_action_on_controller :an_action, :shared_plugin, :namespace
-    assert_response_body 'rendered in Namespace::SharedPluginController#an_action (from beta_plugin)'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/53/5348a576b6e7f11a14f641fe1fc6002b23e71005.svn-base
--- /dev/null
+++ b/.svn/pristine/53/5348a576b6e7f11a14f641fe1fc6002b23e71005.svn-base
@@ -0,0 +1,6 @@
+<h2><%=l(:label_auth_source)%> (<%= h(@auth_source.auth_method_name) %>)</h2>
+
+<%= labelled_form_for @auth_source, :as => :auth_source, :url => auth_source_path(@auth_source), :html => {:id => 'auth_source_form'} do |f| %>
+  <%= render :partial => auth_source_partial_name(@auth_source), :locals => { :f => f } %>
+  <%= submit_tag l(:button_save) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/53/5379630b9d6429044c3fd0c2e60e7bdba5976f78.svn-base
--- a/.svn/pristine/53/5379630b9d6429044c3fd0c2e60e7bdba5976f78.svn-base
+++ /dev/null
@@ -1,94 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'welcome_controller'
-
-# Re-raise errors caught by the controller.
-class WelcomeController; def rescue_action(e) raise e end; end
-
-class WelcomeControllerTest < ActionController::TestCase
-  fixtures :projects, :news
-
-  def setup
-    @controller = WelcomeController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:news)
-    assert_not_nil assigns(:projects)
-    assert !assigns(:projects).include?(Project.find(:first, :conditions => {:is_public => false}))
-  end
-
-  def test_browser_language
-    Setting.default_language = 'en'
-    @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
-    get :index
-    assert_equal :fr, @controller.current_language
-  end
-
-  def test_browser_language_alternate
-    Setting.default_language = 'en'
-    @request.env['HTTP_ACCEPT_LANGUAGE'] = 'zh-TW'
-    get :index
-    assert_equal :"zh-TW", @controller.current_language
-  end
-
-  def test_browser_language_alternate_not_valid
-    Setting.default_language = 'en'
-    @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr-CA'
-    get :index
-    assert_equal :fr, @controller.current_language
-  end
-
-  def test_robots
-    get :robots
-    assert_response :success
-    assert_equal 'text/plain', @response.content_type
-    assert @response.body.match(%r{^Disallow: /projects/ecookbook/issues\r?$})
-  end
-
-  def test_warn_on_leaving_unsaved_turn_on
-    user = User.find(2)
-    user.pref.warn_on_leaving_unsaved = '1'
-    user.pref.save!
-    @request.session[:user_id] = 2
-
-    get :index
-    assert_tag 'script',
-      :attributes => {:type => "text/javascript"},
-      :content => %r{new WarnLeavingUnsaved}
-  end
-
-  def test_warn_on_leaving_unsaved_turn_off
-    user = User.find(2)
-    user.pref.warn_on_leaving_unsaved = '0'
-    user.pref.save!
-    @request.session[:user_id] = 2
-
-    get :index
-    assert_no_tag 'script',
-      :attributes => {:type => "text/javascript"},
-      :content => %r{new WarnLeavingUnsaved}
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/53/539b469592377fe5ec04bc7018cfe2f6bf2322bc.svn-base
--- /dev/null
+++ b/.svn/pristine/53/539b469592377fe5ec04bc7018cfe2f6bf2322bc.svn-base
@@ -0,0 +1,134 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingIssuesTest < ActionController::IntegrationTest
+  def test_issues_rest_actions
+    assert_routing(
+        { :method => 'get', :path => "/issues" },
+        { :controller => 'issues', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues.pdf" },
+        { :controller => 'issues', :action => 'index', :format => 'pdf' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues.atom" },
+        { :controller => 'issues', :action => 'index', :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues.xml" },
+        { :controller => 'issues', :action => 'index', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/64" },
+        { :controller => 'issues', :action => 'show', :id => '64' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/64.pdf" },
+        { :controller => 'issues', :action => 'show', :id => '64',
+          :format => 'pdf' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/64.atom" },
+        { :controller => 'issues', :action => 'show', :id => '64',
+          :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/64.xml" },
+        { :controller => 'issues', :action => 'show', :id => '64',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issues.xml" },
+        { :controller => 'issues', :action => 'create', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/64/edit" },
+        { :controller => 'issues', :action => 'edit', :id => '64' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/issues/1.xml" },
+        { :controller => 'issues', :action => 'update', :id => '1',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/issues/1.xml" },
+        { :controller => 'issues', :action => 'destroy', :id => '1',
+          :format => 'xml' }
+      )
+  end
+
+  def test_issues_rest_actions_scoped_under_project
+    assert_routing(
+        { :method => 'get', :path => "/projects/23/issues" },
+        { :controller => 'issues', :action => 'index', :project_id => '23' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/23/issues.pdf" },
+        { :controller => 'issues', :action => 'index', :project_id => '23',
+          :format => 'pdf' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/23/issues.atom" },
+        { :controller => 'issues', :action => 'index', :project_id => '23',
+          :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/23/issues.xml" },
+        { :controller => 'issues', :action => 'index', :project_id => '23',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/23/issues" },
+        { :controller => 'issues', :action => 'create', :project_id => '23' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/23/issues/new" },
+        { :controller => 'issues', :action => 'new', :project_id => '23' }
+      )
+  end
+
+  def test_issues_form_update
+    ["post", "put"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/projects/23/issues/update_form" },
+          { :controller => 'issues', :action => 'update_form', :project_id => '23' }
+        )
+    end
+  end
+
+  def test_issues_extra_actions
+    assert_routing(
+        { :method => 'get', :path => "/projects/23/issues/64/copy" },
+        { :controller => 'issues', :action => 'new', :project_id => '23',
+          :copy_from => '64' }
+      )
+    # For updating the bulk edit form
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/issues/bulk_edit" },
+          { :controller => 'issues', :action => 'bulk_edit' }
+        )
+    end
+    assert_routing(
+        { :method => 'post', :path => "/issues/bulk_update" },
+        { :controller => 'issues', :action => 'bulk_update' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/53/539f4d98713d0fa4ed6fd83111963b94c1350c7c.svn-base
--- a/.svn/pristine/53/539f4d98713d0fa4ed6fd83111963b94c1350c7c.svn-base
+++ /dev/null
@@ -1,122 +0,0 @@
-<attach event="ondocumentready" handler="parseStylesheets" />
-<script>
-/**
- *	Whatever:hover - V1.42.060206 - hover & active
- *	------------------------------------------------------------
- *	(c) 2005 - Peter Nederlof
- *	Peterned - http://www.xs4all.nl/~peterned/
- *	License  - http://creativecommons.org/licenses/LGPL/2.1/
- *
- *	Whatever:hover is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU Lesser General Public
- *	License as published by the Free Software Foundation; either
- *	version 2.1 of the License, or (at your option) any later version.
- *
- *	Whatever:hover is distributed in the hope that it will be useful,
- *	but WITHOUT ANY WARRANTY; without even the implied warranty of
- *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- *	Lesser General Public License for more details.
- *
- *	Credits and thanks to:
- *	Arnoud Berendsen, Martin Reurings, Robert Hanson
- *
- *	howto: body { behavior:url("csshover.htc"); }
- *	------------------------------------------------------------
- */
-
-var csshoverReg = /(^|\s)(([^a]([^ ]+)?)|(a([^#.][^ ]+)+)):(hover|active)/i,
-currentSheet, doc = window.document, hoverEvents = [], activators = {
-	onhover:{on:'onmouseover', off:'onmouseout'},
-	onactive:{on:'onmousedown', off:'onmouseup'}
-}
-
-function parseStylesheets() {
-	if(!/MSIE (5|6)/.test(navigator.userAgent)) return;
-	window.attachEvent('onunload', unhookHoverEvents);
-	var sheets = doc.styleSheets, l = sheets.length;
-	for(var i=0; i<l; i++) 
-		parseStylesheet(sheets[i]);
-}
-	function parseStylesheet(sheet) {
-		if(sheet.imports) {
-			try {
-				var imports = sheet.imports, l = imports.length;
-				for(var i=0; i<l; i++) parseStylesheet(sheet.imports[i]);
-			} catch(securityException){}
-		}
-
-		try {
-			var rules = (currentSheet = sheet).rules, l = rules.length;
-			for(var j=0; j<l; j++) parseCSSRule(rules[j]);
-		} catch(securityException){}
-	}
-
-	function parseCSSRule(rule) {
-		var select = rule.selectorText, style = rule.style.cssText;
-		if(!csshoverReg.test(select) || !style) return;
-
-		var pseudo = select.replace(/[^:]+:([a-z-]+).*/i, 'on$1');
-		var newSelect = select.replace(/(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi, '.$2' + pseudo);
-		var className = (/\.([a-z0-9_-]*on(hover|active))/i).exec(newSelect)[1];
-		var affected = select.replace(/:(hover|active).*$/, '');
-		var elements = getElementsBySelect(affected);
-		if(elements.length == 0) return;
-
-		currentSheet.addRule(newSelect, style);
-		for(var i=0; i<elements.length; i++)
-			new HoverElement(elements[i], className, activators[pseudo]);
-	}
-
-function HoverElement(node, className, events) {
-	if(!node.hovers) node.hovers = {};
-	if(node.hovers[className]) return;
-	node.hovers[className] = true;
-	hookHoverEvent(node, events.on, function() { node.className += ' ' + className; });
-	hookHoverEvent(node, events.off, function() { node.className = node.className.replace(new RegExp('\\s+'+className, 'g'),''); });
-}
-	function hookHoverEvent(node, type, handler) {
-		node.attachEvent(type, handler);
-		hoverEvents[hoverEvents.length] = { 
-			node:node, type:type, handler:handler 
-		};
-	}
-
-	function unhookHoverEvents() {
-		for(var e,i=0; i<hoverEvents.length; i++) {
-			e = hoverEvents[i]; 
-			e.node.detachEvent(e.type, e.handler);
-		}
-	}
-
-function getElementsBySelect(rule) {
-	var parts, nodes = [doc];
-	parts = rule.split(' ');
-	for(var i=0; i<parts.length; i++) {
-		nodes = getSelectedNodes(parts[i], nodes);
-	}	return nodes;
-}
-	function getSelectedNodes(select, elements) {
-		var result, node, nodes = [];
-		var identify = (/\#([a-z0-9_-]+)/i).exec(select);
-		if(identify) {
-			var element = doc.getElementById(identify[1]);
-			return element? [element]:nodes;
-		}
-		
-		var classname = (/\.([a-z0-9_-]+)/i).exec(select);
-		var tagName = select.replace(/(\.|\#|\:)[a-z0-9_-]+/i, '');
-		var classReg = classname? new RegExp('\\b' + classname[1] + '\\b'):false;
-		for(var i=0; i<elements.length; i++) {
-			result = tagName? elements[i].all.tags(tagName):elements[i].all; 
-			for(var j=0; j<result.length; j++) {
-				node = result[j];
-				if(classReg && !classReg.test(node.className)) continue;
-				nodes[nodes.length] = node;
-			}
-		}	
-		
-		return nodes;
-	}
-
-window.parseStylesheets = parseStylesheets;
-</script>
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/53/53a91881211d028f264cd0f5ef639191d1262e38.svn-base
--- /dev/null
+++ b/.svn/pristine/53/53a91881211d028f264cd0f5ef639191d1262e38.svn-base
@@ -0,0 +1,59 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::AccessControlTest < ActiveSupport::TestCase
+
+  def setup
+    @access_module = Redmine::AccessControl
+  end
+
+  def test_permissions
+    perms = @access_module.permissions
+    assert perms.is_a?(Array)
+    assert perms.first.is_a?(Redmine::AccessControl::Permission)
+  end
+
+  def test_module_permission
+    perm = @access_module.permission(:view_issues)
+    assert perm.is_a?(Redmine::AccessControl::Permission)
+    assert_equal :view_issues, perm.name
+    assert_equal :issue_tracking, perm.project_module
+    assert perm.actions.is_a?(Array)
+    assert perm.actions.include?('issues/index')
+  end
+
+  def test_no_module_permission
+    perm = @access_module.permission(:edit_project)
+    assert perm.is_a?(Redmine::AccessControl::Permission)
+    assert_equal :edit_project, perm.name
+    assert_nil perm.project_module
+    assert perm.actions.is_a?(Array)
+    assert perm.actions.include?('projects/settings')
+  end
+
+  def test_read_action_should_return_true_for_read_actions
+    assert_equal true, @access_module.read_action?(:view_project)
+    assert_equal true, @access_module.read_action?(:controller => 'projects', :action => 'show')
+  end
+
+  def test_read_action_should_return_false_for_update_actions
+    assert_equal false, @access_module.read_action?(:edit_project)
+    assert_equal false, @access_module.read_action?(:controller => 'projects', :action => 'edit')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/53/53ae85a75b984c31fad63866e54e9b00f6355b8c.svn-base
--- a/.svn/pristine/53/53ae85a75b984c31fad63866e54e9b00f6355b8c.svn-base
+++ /dev/null
@@ -1,1008 +0,0 @@
-# Greek translations for Ruby on Rails
-# by Vaggelis Typaldos (vtypal@gmail.com),  Spyros Raptis (spirosrap@gmail.com)
-
-el:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%m/%d/%Y"
-      short: "%b %d"
-      long: "%B %d, %Y"
-      
-    day_names: [ÎšÏ…ÏÎ¹Î±ÎºÎ®, Î”ÎµÏ…Ï„Î­ÏÎ±, Î¤ÏÎ¯Ï„Î·, Î¤ÎµÏ„Î¬ÏÏ„Î·, Î Î­Î¼Ï€Ï„Î·, Î Î±ÏÎ±ÏƒÎºÎµÏ…Î®, Î£Î¬Î²Î²Î±Ï„Î¿]
-    abbr_day_names: [ÎšÏ…Ï, Î”ÎµÏ…, Î¤ÏÎ¹, Î¤ÎµÏ„, Î ÎµÎ¼, Î Î±Ï, Î£Î±Î²]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Î™Î±Î½Î¿Ï…Î¬ÏÎ¹Î¿Ï‚, Î¦ÎµÎ²ÏÎ¿Ï…Î¬ÏÎ¹Î¿Ï‚, ÎœÎ¬ÏÏ„Î¹Î¿Ï‚, Î‘Ï€ÏÎ¯Î»Î¹Î¿Ï‚, ÎœÎ¬ÏŠÎ¿Ï‚, Î™Î¿ÏÎ½Î¹Î¿Ï‚, Î™Î¿ÏÎ»Î¹Î¿Ï‚, Î‘ÏÎ³Î¿Ï…ÏƒÏ„Î¿Ï‚, Î£ÎµÏ€Ï„Î­Î¼Î²ÏÎ¹Î¿Ï‚, ÎŸÎºÏ„ÏŽÎ²ÏÎ¹Î¿Ï‚, ÎÎ¿Î­Î¼Î²ÏÎ¹Î¿Ï‚, Î”ÎµÎºÎ­Î¼Î²ÏÎ¹Î¿Ï‚]
-    abbr_month_names: [~, Î™Î±Î½, Î¦ÎµÎ², ÎœÎ±Ï, Î‘Ï€Ï, ÎœÎ±ÏŠ, Î™Î¿Î½, Î™Î¿Î», Î‘Ï…Î³, Î£ÎµÏ€, ÎŸÎºÏ„, ÎÎ¿Îµ, Î”ÎµÎº]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%m/%d/%Y %I:%M %p"
-      time: "%I:%M %p"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "Ï€Î¼"
-    pm: "Î¼Î¼"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "Î¼Î¹ÏƒÏŒ Î»ÎµÏ€Ï„ÏŒ"
-      less_than_x_seconds:
-        one:   "Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ 1 Î´ÎµÏ…Ï„ÎµÏÏŒÎ»ÎµÏ€Ï„Î¿"
-        other: "Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ %{count} Î´ÎµÏ…Ï„ÎµÏÏŒÎ»ÎµÏ€Ï„Î±"
-      x_seconds:
-        one:   "1 Î´ÎµÏ…Ï„ÎµÏÏŒÎ»ÎµÏ€Ï„Î¿"
-        other: "%{count} Î´ÎµÏ…Ï„ÎµÏÏŒÎ»ÎµÏ€Ï„Î±"
-      less_than_x_minutes:
-        one:   "Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î­Î½Î± Î»ÎµÏ€Ï„ÏŒ"
-        other: "Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ %{count} Î»ÎµÏ€Ï„Î¬"
-      x_minutes:
-        one:   "1 Î»ÎµÏ€Ï„ÏŒ"
-        other: "%{count} Î»ÎµÏ€Ï„Î¬"
-      about_x_hours:
-        one:   "Ï€ÎµÏÎ¯Ï€Î¿Ï… 1 ÏŽÏÎ±"
-        other: "Ï€ÎµÏÎ¯Ï€Î¿Ï… %{count} ÏŽÏÎµÏ‚"
-      x_days:
-        one:   "1 Î·Î¼Î­ÏÎ±"
-        other: "%{count} Î·Î¼Î­ÏÎµÏ‚"
-      about_x_months:
-        one:   "Ï€ÎµÏÎ¯Ï€Î¿Ï… 1 Î¼Î®Î½Î±"
-        other: "Ï€ÎµÏÎ¯Ï€Î¿Ï… %{count} Î¼Î®Î½ÎµÏ‚"
-      x_months:
-        one:   "1 Î¼Î®Î½Î±"
-        other: "%{count} Î¼Î®Î½ÎµÏ‚"
-      about_x_years:
-        one:   "Ï€ÎµÏÎ¯Ï€Î¿Ï… 1 Ï‡ÏÏŒÎ½Î¿"
-        other: "Ï€ÎµÏÎ¯Ï€Î¿Ï… %{count} Ï‡ÏÏŒÎ½Î¹Î±"
-      over_x_years:
-        one:   "Ï€Î¬Î½Ï‰ Î±Ï€ÏŒ 1 Ï‡ÏÏŒÎ½Î¿"
-        other: "Ï€Î¬Î½Ï‰ Î±Ï€ÏŒ %{count} Ï‡ÏÏŒÎ½Î¹Î±"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-        
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-    human: 
-      format: 
-        precision: 1
-        delimiter: ""
-      storage_units: 
-        format: "%n %u"
-        units: 
-          kb: KB
-          tb: TB
-          gb: GB
-          byte: 
-            one: Byte
-            other: Bytes
-          mb: MB
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "and"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "Î´ÎµÎ½ Ï€ÎµÏÎ¹Î­Ï‡ÎµÏ„Î±Î¹ ÏƒÏ„Î· Î»Î¯ÏƒÏ„Î±"
-        exclusion: "Î­Ï‡ÎµÎ¹ ÎºÎ±Ï„Î¿Ï‡Ï…ÏÏ‰Î¸ÎµÎ¯"
-        invalid: "ÎµÎ¯Î½Î±Î¹ Î¬ÎºÏ…ÏÎ¿"
-        confirmation: "Î´ÎµÎ½ Î±Î½Ï„Î¹ÏƒÏ„Î¿Î¹Ï‡ÎµÎ¯ Î¼Îµ Ï„Î·Î½ ÎµÏ€Î¹Î²ÎµÎ²Î±Î¯Ï‰ÏƒÎ·"
-        accepted: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± Î³Î¯Î½ÎµÎ¹ Î±Ï€Î¿Î´Î¿Ï‡Î®"
-        empty: "Î´Îµ Î¼Ï€Î¿ÏÎµÎ¯ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¬Î´ÎµÎ¹Î¿"
-        blank: "Î´Îµ Î¼Ï€Î¿ÏÎµÎ¯ Î½Î± ÎµÎ¯Î½Î±Î¹ ÎºÎµÎ½ÏŒ"
-        too_long: "Î­Ï‡ÎµÎ¹ Ï€Î¿Î»Î»Î¿ÏÏ‚ (Î¼Î­Î³.ÎµÏ€Î¹Ï„Ï. %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚)"
-        too_short: "Î­Ï‡ÎµÎ¹ Î»Î¯Î³Î¿Ï…Ï‚ (ÎµÎ»Î¬Ï‡.ÎµÏ€Î¹Ï„Ï. %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚)"
-        wrong_length: "Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ ÏƒÏ‰ÏƒÏ„ÏŒÏ‚ Î¿ Î±ÏÎ¹Î¸Î¼ÏŒÏ‚ Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÏ‰Î½ (Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± Î­Ï‡ÎµÎ¹ %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚)"
-        taken: "Î­Ï‡ÎµÎ¹ Î®Î´Î· ÎºÎ±Ï„Î¿Ï‡Ï…ÏÏ‰Î¸ÎµÎ¯"
-        not_a_number: "Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ Î±ÏÎ¹Î¸Î¼ÏŒÏ‚"
-        not_a_date: "Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ ÏƒÏ‰ÏƒÏ„Î® Î·Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±"
-        greater_than: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼ÎµÎ³Î±Î»ÏÏ„ÎµÏÎ¿ Î±Ï€ÏŒ %{count}"
-        greater_than_or_equal_to: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼ÎµÎ³Î±Î»ÏÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î® Î¯ÏƒÎ¿ Î¼Îµ %{count}"
-        equal_to: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¯ÏƒÎ¿Î½ Î¼Îµ %{count}"
-        less_than: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼Î¹ÎºÏÏŒÏ„ÎµÏÎ· Î±Ï€ÏŒ %{count}"
-        less_than_or_equal_to: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼Î¹ÎºÏÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î® Î¯ÏƒÎ¿ Î¼Îµ  %{count}"
-        odd: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼Î¿Î½ÏŒÏ‚"
-        even: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¶Ï…Î³ÏŒÏ‚"
-        greater_than_start_date: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î±ÏÎ³ÏŒÏ„ÎµÏÎ± Î±Ï€ÏŒ Ï„Î·Î½ Î·Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î± Î­Î½Î±ÏÎ¾Î·Ï‚"
-        not_same_project: "Î´ÎµÎ½ Î±Î½Î®ÎºÎµÎ¹ ÏƒÏ„Î¿ Î¯Î´Î¹Î¿ Î­ÏÎ³Î¿"
-        circular_dependency: "Î‘Ï…Ï„Î® Î· ÏƒÏ‡Î­ÏƒÎ· Î¸Î± Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î®ÏƒÎµÎ¹ ÎºÏ…ÎºÎ»Î¹ÎºÎ­Ï‚ ÎµÎ¾Î±ÏÏ„Î®ÏƒÎµÎ¹Ï‚"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: Î Î±ÏÎ±ÎºÎ±Î»ÏŽ ÎµÏ€Î¹Î»Î­Î¾Ï„Îµ
-  
-  general_text_No: 'ÎŒÏ‡Î¹'
-  general_text_Yes: 'ÎÎ±Î¹'
-  general_text_no: 'ÏŒÏ‡Î¹'
-  general_text_yes: 'Î½Î±Î¹'
-  general_lang_name: 'Î•Î»Î»Î·Î½Î¹ÎºÎ¬'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '7'
-  
-  notice_account_updated: ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ ÎµÏ€Î¹Ï„Ï…Ï‡ÏŽÏ‚.
-  notice_account_invalid_creditentials: Î†ÎºÏ…ÏÎ¿ ÏŒÎ½Î¿Î¼Î± Ï‡ÏÎ®ÏƒÏ„Î· Î® ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
-  notice_account_password_updated: ÎŸ ÎºÏ‰Î´Î¹ÎºÏŒÏ‚ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ ÎµÏ€Î¹Ï„Ï…Ï‡ÏŽÏ‚.
-  notice_account_wrong_password: Î›Î¬Î¸Î¿Ï‚ ÎºÏ‰Î´Î¹ÎºÏŒÏ‚ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
-  notice_account_register_done: ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î®Î¸Î·ÎºÎµ ÎµÏ€Î¹Ï„Ï…Ï‡ÏŽÏ‚. Î“Î¹Î± Î½Î± ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Ï„Î¿ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒ ÏƒÎ±Ï‚, Ï€Î±Ï„Î®ÏƒÏ„Îµ Ï„Î¿ ÏƒÏÎ½Î´ÎµÏƒÎ¼Î¿ Ï€Î¿Ï… ÏƒÎ±Ï‚ Î­Ï‡ÎµÎ¹ Î±Ï€Î¿ÏƒÏ„Î±Î»ÎµÎ¯ Î¼Îµ email.
-  notice_account_unknown_email: Î†Î³Î½Ï‰ÏƒÏ„Î¿Ï‚ Ï‡ÏÎ®ÏƒÏ„Î·Ï‚.
-  notice_can_t_change_password: Î‘Ï…Ï„ÏŒÏ‚ Î¿ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ Ï‡ÏÎ·ÏƒÎ¹Î¼Î¿Ï€Î¿Î¹ÎµÎ¯ ÎµÎ¾Ï‰Ï„ÎµÏÎ¹ÎºÎ® Ï€Î·Î³Î® Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚. Î”ÎµÎ½ ÎµÎ¯Î½Î±Î¹ Î´Ï…Î½Î±Ï„ÏŒÎ½ Î½Î± Î±Î»Î»Î¬Î¾ÎµÏ„Îµ Ï„Î¿Î½ ÎºÏ‰Î´Î¹ÎºÏŒ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚.
-  notice_account_lost_email_sent: Î£Î±Ï‚ Î­Ï‡ÎµÎ¹ Î±Ï€Î¿ÏƒÏ„Î±Î»ÎµÎ¯ email Î¼Îµ Î¿Î´Î·Î³Î¯ÎµÏ‚ Î³Î¹Î± Ï„Î·Î½ ÎµÏ€Î¹Î»Î¿Î³Î® Î½Î­Î¿Ï… ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚.
-  notice_account_activated: ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ ÏƒÎ±Ï‚ Î­Ï‡ÎµÎ¹ ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î·Î¸ÎµÎ¯. Î¤ÏŽÏÎ± Î¼Ï€Î¿ÏÎµÎ¯Ï„Îµ Î½Î± ÏƒÏ…Î½Î´ÎµÎ¸ÎµÎ¯Ï„Îµ.
-  notice_successful_create: Î•Ï€Î¹Ï„Ï…Ï‡Î®Ï‚ Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î±.
-  notice_successful_update: Î•Ï€Î¹Ï„Ï…Ï‡Î®Ï‚ ÎµÎ½Î·Î¼Î­ÏÏ‰ÏƒÎ·.
-  notice_successful_delete: Î•Ï€Î¹Ï„Ï…Ï‡Î®Ï‚ Î´Î¹Î±Î³ÏÎ±Ï†Î®.
-  notice_successful_connection: Î•Ï€Î¹Ï„Ï…Ï‡Î®Ï‚ ÏƒÏÎ½Î´ÎµÏƒÎ·.
-  notice_file_not_found: Î— ÏƒÎµÎ»Î¯Î´Î± Ï€Î¿Ï… Î¶Î·Ï„Î®ÏƒÎ±Ï„Îµ Î´ÎµÎ½ Ï…Ï€Î¬ÏÏ‡ÎµÎ¹ Î® Î­Ï‡ÎµÎ¹ Î±Ï†Î±Î¹ÏÎµÎ¸ÎµÎ¯. 
-  notice_locking_conflict: Î¤Î± Î´ÎµÎ´Î¿Î¼Î­Î½Î± Î­Ï‡Î¿Ï…Î½ ÎµÎ½Î·Î¼ÎµÏÏ‰Î¸ÎµÎ¯ Î±Ï€ÏŒ Î¬Î»Î»Î¿ Ï‡ÏÎ®ÏƒÏ„Î·.
-  notice_not_authorized: Î”ÎµÎ½ Î­Ï‡ÎµÏ„Îµ Î´Î¹ÎºÎ±Î¯Ï‰Î¼Î± Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î· ÏƒÎµÎ»Î¯Î´Î±.
-  notice_email_sent: "ÎˆÎ½Î± Î¼Î®Î½Ï…Î¼Î± Î·Î»ÎµÎºÏ„ÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´ÏÎ¿Î¼ÎµÎ¯Î¿Ï… ÎµÏƒÏ„Î¬Î»Î· ÏƒÏ„Î¿ %{value}"
-  notice_email_error: "Î£Ï†Î¬Î»Î¼Î± ÎºÎ±Ï„Î¬ Ï„Î·Î½ Î±Ï€Î¿ÏƒÏ„Î¿Î»Î® Ï„Î¿Ï… Î¼Î·Î½ÏÎ¼Î±Ï„Î¿Ï‚ ÏƒÏ„Î¿ (%{value})"
-  notice_feeds_access_key_reseted:  ÎˆÎ³Î¹Î½Îµ ÎµÏ€Î±Î½Î±Ï†Î¿ÏÎ¬ ÏƒÏ„Î¿ ÎºÎ»ÎµÎ¹Î´Î¯ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ RSS.
-  notice_failed_to_save_issues: "Î‘Ï€Î¿Ï„Ï…Ï‡Î¯Î± Î±Ï€Î¿Î¸Î®ÎºÎµÏ…ÏƒÎ·Ï‚ %{count} Î¸ÎµÎ¼Î±(Ï„Ï‰Î½) Î±Ï€ÏŒ Ï„Î± %{total} ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î±: %{ids}."
-  notice_no_issue_selected: "ÎšÎ±Î½Î­Î½Î± Î¸Î­Î¼Î± Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î¿! Î Î±ÏÎ±ÎºÎ±Î»Î¿ÏÎ¼Îµ, ÎµÎ»Î­Î³Î¾Ï„Îµ Ï„Î± Î¸Î­Î¼Î±Ï„Î± Ï€Î¿Ï… Î¸Î­Î»ÎµÏ„Îµ Î½Î± ÎµÏ€ÎµÎ¾ÎµÏÎ³Î±ÏƒÏ„ÎµÎ¯Ï„Îµ."
-  notice_account_pending: "ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ ÏƒÎ±Ï‚ Î­Ï‡ÎµÎ¹ Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î·Î¸ÎµÎ¯ ÎºÎ±Î¹ ÎµÎ¯Î½Î±Î¹ ÏƒÎµ ÏƒÏ„Î¬Î´Î¹Î¿ Î­Î³ÎºÏÎ¹ÏƒÎ·Ï‚ Î±Ï€ÏŒ Ï„Î¿Î½ Î´Î¹Î±Ï‡ÎµÎ¹ÏÎ¹ÏƒÏ„Î®."
-  notice_default_data_loaded: ÎŸÎ¹ Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½ÎµÏ‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ Ï†Î¿ÏÏ„ÏŽÎ¸Î·ÎºÎ±Î½ ÎµÏ€Î¹Ï„Ï…Ï‡ÏŽÏ‚.
-  notice_unable_delete_version: Î‘Î´ÏÎ½Î±Ï„Î¿Î½ Î½Î± Î´Î¹Î±Î³ÏÎ±Ï†ÎµÎ¯ Î· Î­ÎºÎ´Î¿ÏƒÎ·.
-  
-  error_can_t_load_default_data: "ÎŸÎ¹ Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½ÎµÏ‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ Î´ÎµÎ½ Î¼Ï€ÏŒÏÎµÏƒÎ±Î½ Î½Î± Ï†Î¿ÏÏ„Ï‰Î¸Î¿ÏÎ½:: %{value}"
-  error_scm_not_found: "Î— ÎµÎ³Î³ÏÎ±Ï†Î® Î® Î· Î±Î½Î±Î¸ÎµÏŽÏÎ·ÏƒÎ· Î´ÎµÎ½ Î²ÏÎ­Î¸Î·ÎºÎµ ÏƒÏ„Î¿ Î±Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î¿."
-  error_scm_command_failed: "Î Î±ÏÎ¿Ï…ÏƒÎ¹Î¬ÏƒÏ„Î·ÎºÎµ ÏƒÏ†Î¬Î»Î¼Î± ÎºÎ±Ï„Î¬ Ï„Î·Î½ Ï€ÏÎ¿ÏƒÏ€Î¬Î¸ÎµÎ¹Î± Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ ÏƒÏ„Î¿ Î±Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î¿: %{value}"
-  error_scm_annotate: "Î— ÎºÎ±Ï„Î±Ï‡ÏŽÏÎ¹ÏƒÎ· Î´ÎµÎ½ Ï…Ï€Î¬ÏÏ‡ÎµÎ¹ Î® Î´ÎµÎ½ Î¼Ï€Î¿ÏÎµÎ¯ Î½Î± ÏƒÏ‡Î¿Î»Î¹Î±ÏƒÏ„ÎµÎ¯."
-  error_issue_not_found_in_project: 'Î¤Î¿ Î¸Î­Î¼Î± Î´ÎµÎ½ Î²ÏÎ­Î¸Î·ÎºÎµ Î® Î´ÎµÎ½ Î±Î½Î®ÎºÎµÎ¹ ÏƒÎµ Î±Ï…Ï„ÏŒ Ï„Î¿ Î­ÏÎ³Î¿'
-  error_no_tracker_in_project: 'Î”ÎµÎ½ Ï…Ï€Î¬ÏÏ‡ÎµÎ¹ Î±Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®Ï‚ Î³Î¹Î± Î±Ï…Ï„ÏŒ Ï„Î¿ Î­ÏÎ³Î¿. Î Î±ÏÎ±ÎºÎ±Î»ÏŽ ÎµÎ»Î­Î³Î¾Ï„Îµ Ï„Î¹Ï‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ Ï„Î¿Ï… Î­ÏÎ³Î¿Ï….'
-  error_no_default_issue_status: 'Î”ÎµÎ½ Î­Ï‡ÎµÎ¹ Î¿ÏÎ¹ÏƒÏ„ÎµÎ¯ Î· Ï€ÏÎ¿ÎµÏ€Î¹Î»Î¿Î³Î®  ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·Ï‚ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½. Î Î±ÏÎ±ÎºÎ±Î»ÏŽ ÎµÎ»Î­Î³Î¾Ï„Îµ Ï„Î¹Ï‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ ÏƒÎ±Ï‚ (ÎœÎµÏ„Î±Î²ÎµÎ¯Ï„Îµ ÏƒÏ„Î·Î½  "Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· -> ÎšÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½").'
-  
-  warning_attachments_not_saved: "%{count} Î±ÏÏ‡ÎµÎ¯Î¿(Î±) Î´Îµ Î¼Ï€Î¿ÏÎ¿ÏÎ½ Î½Î± Î±Ï€Î¿Î¸Î·ÎºÎµÏ…Ï„Î¿ÏÎ½."
-  
-  mail_subject_lost_password: "ÎŸ ÎºÏ‰Î´Î¹ÎºÏŒÏ‚ ÏƒÎ±Ï‚ %{value}"
-  mail_body_lost_password: 'Î“Î¹Î± Î½Î± Î±Î»Î»Î¬Î¾ÎµÏ„Îµ Ï„Î¿Î½ ÎºÏ‰Î´Î¹ÎºÏŒ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚, Ï€Î±Ï„Î®ÏƒÏ„Îµ Ï„Î¿Î½ Î±ÎºÏŒÎ»Î¿Ï…Î¸Î¿ ÏƒÏÎ½Î´ÎµÏƒÎ¼Î¿:'
-  mail_subject_register: "Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· Ï„Î¿Ï… Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï Ï‡ÏÎ®ÏƒÏ„Î· %{value} "
-  mail_body_register: 'Î“Î¹Î± Î½Î± ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Ï„Î¿ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒ ÏƒÎ±Ï‚, ÎµÏ€Î¹Î»Î­Î¾Ï„Îµ Ï„Î¿Î½ Î±ÎºÏŒÎ»Î¿Ï…Î¸Î¿ ÏƒÏÎ½Î´ÎµÏƒÎ¼Î¿:'
-  mail_body_account_information_external: "ÎœÏ€Î¿ÏÎµÎ¯Ï„Îµ Î½Î± Ï‡ÏÎ·ÏƒÎ¹Î¼Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Ï„Î¿Î½ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒ %{value} Î³Î¹Î± Î½Î± ÏƒÏ…Î½Î´ÎµÎ¸ÎµÎ¯Ï„Îµ."
-  mail_body_account_information: Î Î»Î·ÏÎ¿Ï†Î¿ÏÎ¯ÎµÏ‚ Ï„Î¿Ï… Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÎ±Ï‚
-  mail_subject_account_activation_request: "Î±Î¯Ï„Î·Î¼Î± ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï %{value}"
-  mail_body_account_activation_request: "'ÎˆÎ½Î±Ï‚ Î½Î­Î¿Ï‚ Ï‡ÏÎ®ÏƒÏ„Î·Ï‚ (%{value}) Î­Ï‡ÎµÎ¹ ÎµÎ³Î³ÏÎ±Ï†ÎµÎ¯. ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ ÎµÎ¯Î½Î±Î¹ ÏƒÎµ ÏƒÏ„Î¬Î´Î¹Î¿ Î±Î½Î±Î¼Î¿Î½Î®Ï‚ Ï„Î·Ï‚ Î­Î³ÎºÏÎ¹ÏƒÎ·Ï‚ ÏƒÎ±Ï‚:"
-  mail_subject_reminder: "%{count} Î¸Î­Î¼Î±(Ï„Î±) Î¼Îµ Ï€ÏÎ¿Î¸ÎµÏƒÎ¼Î¯Î± ÏƒÏ„Î¹Ï‚ ÎµÏ€ÏŒÎ¼ÎµÎ½ÎµÏ‚ %{days} Î·Î¼Î­ÏÎµÏ‚"
-  mail_body_reminder: "%{count}Î¸Î­Î¼Î±(Ï„Î±)  Ï€Î¿Ï… Î­Ï‡Î¿Ï…Î½ Î±Î½Î±Ï„ÎµÎ¸ÎµÎ¯ ÏƒÎµ ÏƒÎ±Ï‚, Î¼Îµ Ï€ÏÎ¿Î¸ÎµÏƒÎ¼Î¯Î± ÏƒÏ„Î¹Ï‚ ÎµÏ€ÏŒÎ¼ÎµÎ½ÎµÏ‚ %{days} Î·Î¼Î­ÏÎµÏ‚:"
-  mail_subject_wiki_content_added: "'Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ Î· ÏƒÎµÎ»Î¯Î´Î± wiki %{id}' "
-  mail_body_wiki_content_added: "Î— ÏƒÎµÎ»Î¯Î´Î± wiki '%{id}' Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author}."
-  mail_subject_wiki_content_updated: "'ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î· ÏƒÎµÎ»Î¯Î´Î± wiki %{id}' "
-  mail_body_wiki_content_updated: "Î— ÏƒÎµÎ»Î¯Î´Î± wiki  '%{id}' ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author}."
-  
-  gui_validation_error: 1 ÏƒÏ†Î¬Î»Î¼Î±
-  gui_validation_error_plural: "%{count} ÏƒÏ†Î¬Î»Î¼Î±Ï„Î±"
-  
-  field_name: ÎŒÎ½Î¿Î¼Î±
-  field_description: Î ÎµÏÎ¹Î³ÏÎ±Ï†Î®
-  field_summary: Î£Ï…Î½Î¿Ï€Ï„Î¹ÎºÎ¬
-  field_is_required: Î‘Ï€Î±Î¹Ï„ÎµÎ¯Ï„Î±Î¹
-  field_firstname: ÎŒÎ½Î¿Î¼Î±
-  field_lastname: Î•Ï€ÏŽÎ½Ï…Î¼Î¿
-  field_mail: Email
-  field_filename: Î‘ÏÏ‡ÎµÎ¯Î¿
-  field_filesize: ÎœÎ­Î³ÎµÎ¸Î¿Ï‚
-  field_downloads: ÎœÎµÏ„Î±Ï†Î¿ÏÏ„ÏŽÏƒÎµÎ¹Ï‚
-  field_author: Î£Ï…Î³Î³ÏÎ±Ï†Î­Î±Ï‚
-  field_created_on: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î®Î¸Î·ÎºÎµ
-  field_updated_on: Î•Î½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ
-  field_field_format: ÎœÎ¿ÏÏ†Î¿Ï€Î¿Î¯Î·ÏƒÎ·
-  field_is_for_all: Î“Î¹Î± ÏŒÎ»Î± Ï„Î± Î­ÏÎ³Î±
-  field_possible_values: Î Î¹Î¸Î±Î½Î­Ï‚ Ï„Î¹Î¼Î­Ï‚
-  field_regexp: ÎšÎ±Î½Î¿Î½Î¹ÎºÎ® Ï€Î±ÏÎ¬ÏƒÏ„Î±ÏƒÎ·
-  field_min_length: Î•Î»Î¬Ï‡Î¹ÏƒÏ„Î¿ Î¼Î®ÎºÎ¿Ï‚
-  field_max_length: ÎœÎ­Î³Î¹ÏƒÏ„Î¿ Î¼Î®ÎºÎ¿Ï‚
-  field_value: Î¤Î¹Î¼Î®
-  field_category: ÎšÎ±Ï„Î·Î³Î¿ÏÎ¯Î±
-  field_title: Î¤Î¯Ï„Î»Î¿Ï‚
-  field_project: ÎˆÏÎ³Î¿
-  field_issue: Î˜Î­Î¼Î±
-  field_status: ÎšÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·
-  field_notes: Î£Î·Î¼ÎµÎ¹ÏŽÏƒÎµÎ¹Ï‚
-  field_is_closed: ÎšÎ»ÎµÎ¹ÏƒÏ„Î¬ Î¸Î­Î¼Î±Ï„Î±
-  field_is_default: Î ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î· Ï„Î¹Î¼Î®
-  field_tracker: Î‘Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®Ï‚
-  field_subject: Î˜Î­Î¼Î±
-  field_due_date: Î ÏÎ¿Î¸ÎµÏƒÎ¼Î¯Î±
-  field_assigned_to: Î‘Î½Î¬Î¸ÎµÏƒÎ· ÏƒÎµ
-  field_priority: Î ÏÎ¿Ï„ÎµÏÎ±Î¹ÏŒÏ„Î·Ï„Î±
-  field_fixed_version: Î£Ï„ÏŒÏ‡Î¿Ï‚ Î­ÎºÎ´Î¿ÏƒÎ·Ï‚
-  field_user: Î§ÏÎ®ÏƒÏ„Î·Ï‚
-  field_role: Î¡ÏŒÎ»Î¿Ï‚
-  field_homepage: Î‘ÏÏ‡Î¹ÎºÎ® ÏƒÎµÎ»Î¯Î´Î±
-  field_is_public: Î”Î·Î¼ÏŒÏƒÎ¹Î¿
-  field_parent: Î•Ï€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î¿ Ï„Î¿Ï…
-  field_is_in_roadmap: Î ÏÎ¿Î²Î¿Î»Î® Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÏƒÏ„Î¿ Ï‡Î¬ÏÏ„Î· Ï€Î¿ÏÎµÎ¯Î±Ï‚
-  field_login: ÎŒÎ½Î¿Î¼Î± Ï‡ÏÎ®ÏƒÏ„Î·
-  field_mail_notification: Î•Î¹Î´Î¿Ï€Î¿Î¹Î®ÏƒÎµÎ¹Ï‚ email
-  field_admin: Î”Î¹Î±Ï‡ÎµÎ¹ÏÎ¹ÏƒÏ„Î®Ï‚
-  field_last_login_on: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± ÏƒÏÎ½Î´ÎµÏƒÎ·
-  field_language: Î“Î»ÏŽÏƒÏƒÎ±
-  field_effective_date: Î—Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±
-  field_password: ÎšÏ‰Î´Î¹ÎºÏŒÏ‚ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
-  field_new_password: ÎÎ­Î¿Ï‚ ÎºÏ‰Î´Î¹ÎºÏŒÏ‚ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
-  field_password_confirmation: Î•Ï€Î¹Î²ÎµÎ²Î±Î¯Ï‰ÏƒÎ·
-  field_version: ÎˆÎºÎ´Î¿ÏƒÎ·
-  field_type: Î¤ÏÏ€Î¿Ï‚
-  field_host: ÎšÏŒÎ¼Î²Î¿Ï‚
-  field_port: Î˜ÏÏÎ±
-  field_account: Î›Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚
-  field_base_dn: Î’Î¬ÏƒÎ· DN
-  field_attr_login: Î™Î´Î¹ÏŒÏ„Î·Ï„Î± ÎµÎ¹ÏƒÏŒÎ´Î¿Ï…
-  field_attr_firstname: Î™Î´Î¹ÏŒÏ„Î·Ï„Î± Î¿Î½ÏŒÎ¼Î±Ï„Î¿Ï‚
-  field_attr_lastname:  Î™Î´Î¹ÏŒÏ„Î·Ï„Î± ÎµÏ€Ï‰Î½ÏÎ¼Î¿Ï…
-  field_attr_mail: Î™Î´Î¹ÏŒÏ„Î·Ï„Î± email
-  field_onthefly: Î†Î¼ÎµÏƒÎ· Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± Ï‡ÏÎ®ÏƒÏ„Î·
-  field_start_date: Î•ÎºÎºÎ¯Î½Î·ÏƒÎ·
-  field_done_ratio: "% ÎµÏ€Î¹Ï„ÎµÏÏ‡Î¸Î·"
-  field_auth_source: Î¤ÏÏŒÏ€Î¿Ï‚ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚
-  field_hide_mail: Î‘Ï€ÏŒÎºÏÏ…ÏˆÎ· Î´Î¹ÎµÏÎ¸Ï…Î½ÏƒÎ·Ï‚ email
-  field_comments: Î£Ï‡ÏŒÎ»Î¹Î¿
-  field_url: URL
-  field_start_page: Î ÏÏŽÏ„Î· ÏƒÎµÎ»Î¯Î´Î±
-  field_subproject: Î•Ï€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î¿
-  field_hours: ÎÏÎµÏ‚
-  field_activity: Î”ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î±
-  field_spent_on: Î—Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±
-  field_identifier: Î£Ï„Î¿Î¹Ï‡ÎµÎ¯Î¿ Î±Î½Î±Î³Î½ÏŽÏÎ¹ÏƒÎ·Ï‚
-  field_is_filter: Î§ÏÎ®ÏƒÎ· Ï‰Ï‚ Ï†Î¯Î»Ï„ÏÎ¿
-  field_issue_to: Î£Ï‡ÎµÏ„Î¹ÎºÎ¬ Î¸Î­Î¼Î±Ï„Î±
-  field_delay: ÎšÎ±Î¸Ï…ÏƒÏ„Î­ÏÎ·ÏƒÎ·
-  field_assignable: Î˜Î­Î¼Î±Ï„Î± Ï€Î¿Ï… Î¼Ï€Î¿ÏÎ¿ÏÎ½ Î½Î± Î±Î½Î±Ï„ÎµÎ¸Î¿ÏÎ½ ÏƒÎµ Î±Ï…Ï„ÏŒ Ï„Î¿ ÏÏŒÎ»Î¿
-  field_redirect_existing_links: Î‘Î½Î±ÎºÎ±Ï„ÎµÏÎ¸Ï…Î½ÏƒÎ· Ï„Ï‰Î½ Ï„ÏÎµÏ‡ÏŒÎ½Ï„Ï‰Î½ ÏƒÏ…Î½Î´Î­ÏƒÎ¼Ï‰Î½
-  field_estimated_hours: Î•ÎºÏ„Î¹Î¼ÏŽÎ¼ÎµÎ½Î¿Ï‚ Ï‡ÏÏŒÎ½Î¿Ï‚
-  field_column_names: Î£Ï„Î®Î»ÎµÏ‚
-  field_time_zone: Î©ÏÎ¹Î±Î¯Î± Î¶ÏŽÎ½Î·
-  field_searchable: Î•ÏÎµÏ…Î½Î®ÏƒÎ¹Î¼Î¿
-  field_default_value: Î ÏÎ¿ÎºÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼Î­Î½Î· Ï„Î¹Î¼Î®
-  field_comments_sorting: Î ÏÎ¿Î²Î¿Î»Î® ÏƒÏ‡Î¿Î»Î¯Ï‰Î½
-  field_parent_title: Î“Î¿Î½Î¹ÎºÎ® ÏƒÎµÎ»Î¯Î´Î±
-  field_editable: Î•Ï€ÎµÎ¾ÎµÏÎ³Î¬ÏƒÎ¹Î¼Î¿
-  field_watcher: Î Î±ÏÎ±Ï„Î·ÏÎ·Ï„Î®Ï‚
-  field_identity_url: OpenID URL
-  field_content: Î ÎµÏÎ¹ÎµÏ‡ÏŒÎ¼ÎµÎ½Î¿
-  field_group_by: ÎŸÎ¼Î±Î´Î¹ÎºÎ¬ Î±Ï€Î¿Ï„ÎµÎ»Î­ÏƒÎ¼Î±Ï„Î± Î±Ï€ÏŒ 
-  
-  setting_app_title: Î¤Î¯Ï„Î»Î¿Ï‚ ÎµÏ†Î±ÏÎ¼Î¿Î³Î®Ï‚
-  setting_app_subtitle: Î¥Ï€ÏŒÏ„Î¹Ï„Î»Î¿Ï‚ ÎµÏ†Î±ÏÎ¼Î¿Î³Î®Ï‚
-  setting_welcome_text: ÎšÎµÎ¯Î¼ÎµÎ½Î¿ Ï…Ï€Î¿Î´Î¿Ï‡Î®Ï‚
-  setting_default_language: Î ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î· Î³Î»ÏŽÏƒÏƒÎ±
-  setting_login_required: Î‘Ï€Î±Î¹Ï„ÎµÎ¯Ï„Î±Î¹ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·
-  setting_self_registration: Î‘Ï…Ï„Î¿-ÎµÎ³Î³ÏÎ±Ï†Î®
-  setting_attachment_max_size: ÎœÎ­Î³. Î¼Î­Î³ÎµÎ¸Î¿Ï‚ ÏƒÏ…Î½Î·Î¼Î¼Î­Î½Î¿Ï…
-  setting_issues_export_limit: Î˜Î­Î¼Î±Ï„Î± Ï€ÎµÏÎ¹Î¿ÏÎ¹ÏƒÎ¼Î¿Ï ÎµÎ¾Î±Î³Ï‰Î³Î®Ï‚
-  setting_mail_from: ÎœÎµÏ„Î¬Î´Î¿ÏƒÎ· Î´Î¹ÎµÏÎ¸Ï…Î½ÏƒÎ·Ï‚ email
-  setting_bcc_recipients: Î‘Ï€Î¿Î´Î­ÎºÏ„ÎµÏ‚ ÎºÏÏ…Ï†Î®Ï‚ ÎºÎ¿Î¹Î½Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚ (bcc)
-  setting_plain_text_mail: Email Î±Ï€Î»Î¿Ï ÎºÎµÎ¹Î¼Î­Î½Î¿Ï… (ÏŒÏ‡Î¹ HTML)
-  setting_host_name: ÎŒÎ½Î¿Î¼Î± ÎºÏŒÎ¼Î²Î¿Ï… ÎºÎ±Î¹ Î´Î¹Î±Î´ÏÎ¿Î¼Î®
-  setting_text_formatting: ÎœÎ¿ÏÏ†Î¿Ï€Î¿Î¯Î·ÏƒÎ· ÎºÎµÎ¹Î¼Î­Î½Î¿Ï…
-  setting_wiki_compression: Î£Ï…Î¼Ï€Î¯ÎµÏƒÎ· Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÎ¿Ï wiki
-  setting_feeds_limit: Feed Ï€ÎµÏÎ¹Î¿ÏÎ¹ÏƒÎ¼Î¿Ï Ï€ÎµÏÎ¹ÎµÏ‡Î¿Î¼Î­Î½Î¿Ï…
-  setting_default_projects_public: Î¤Î± Î½Î­Î± Î­ÏÎ³Î± Î­Ï‡Î¿Ï…Î½ Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³ÎµÎ¯ Ï‰Ï‚ Î´Î·Î¼ÏŒÏƒÎ¹Î± 
-  setting_autofetch_changesets: Î‘Ï…Ï„ÏŒÎ¼Î±Ï„Î· Î»Î®ÏˆÎ· commits
-  setting_sys_api_enabled: Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· WS Î³Î¹Î± Î´Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î±Ï€Î¿Î¸ÎµÏ„Î·ÏÎ¯Î¿Ï…
-  setting_commit_ref_keywords: Î‘Î½Î±Ï†Î¿ÏÎ¬ ÏƒÎµ Î»Î­Î¾ÎµÎ¹Ï‚-ÎºÎ»ÎµÎ¹Î´Î¹Î¬
-  setting_commit_fix_keywords: ÎšÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼ÏŒÏ‚ ÏƒÎµ Î»Î­Î¾ÎµÎ¹Ï‚-ÎºÎ»ÎµÎ¹Î´Î¹Î¬
-  setting_autologin: Î‘Ï…Ï„ÏŒÎ¼Î±Ï„Î· ÏƒÏÎ½Î´ÎµÏƒÎ·
-  setting_date_format: ÎœÎ¿ÏÏ†Î® Î·Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±Ï‚
-  setting_time_format: ÎœÎ¿ÏÏ†Î® ÏŽÏÎ±Ï‚
-  setting_cross_project_issue_relations: Î•Ï€Î¹Ï„ÏÎ­ÏˆÏ„Îµ ÏƒÏ…ÏƒÏ‡ÎµÏ„Î¹ÏƒÎ¼ÏŒ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÏƒÎµ Î´Î¹Î±ÏƒÏ„Î±ÏÏÏ‰ÏƒÎ·-Î­ÏÎ³Ï‰Î½
-  setting_issue_list_default_columns: Î ÏÎ¿ÎºÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼Î­Î½ÎµÏ‚ ÎµÎ¼Ï†Î±Î½Î¹Î¶ÏŒÎ¼ÎµÎ½ÎµÏ‚ ÏƒÏ„Î®Î»ÎµÏ‚ ÏƒÏ„Î· Î»Î¯ÏƒÏ„Î± Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  setting_emails_footer: Î¥Ï€Î¿ÏƒÎ­Î»Î¹Î´Î¿ ÏƒÏ„Î± email
-  setting_protocol: Î ÏÏ‰Ï„ÏŒÎºÎ¿Î»Î¿
-  setting_per_page_options: Î‘Î½Ï„Î¹ÎºÎµÎ¯Î¼ÎµÎ½Î± Î±Î½Î¬ ÏƒÎµÎ»Î¯Î´Î± ÎµÏ€Î¹Î»Î¿Î³ÏŽÎ½
-  setting_user_format: ÎœÎ¿ÏÏ†Î® ÎµÎ¼Ï†Î¬Î½Î¹ÏƒÎ·Ï‚ Ï‡ÏÎ·ÏƒÏ„ÏŽÎ½
-  setting_activity_days_default: Î—Î¼Î­ÏÎµÏ‚ Ï€Î¿Ï… ÎµÎ¼Ï†Î±Î½Î¯Î¶ÎµÏ„Î±Î¹ ÏƒÏ„Î· Î´ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î± Î­ÏÎ³Î¿Ï…
-  setting_display_subprojects_issues: Î•Î¼Ï†Î¬Î½Î¹ÏƒÎ· Î±Ï€ÏŒ Ï€ÏÎ¿ÎµÏ€Î¹Î»Î¿Î³Î® Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÎµÏ€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Ï‰Î½ ÏƒÏ„Î± ÎºÏÏÎ¹Î± Î­ÏÎ³Î± 
-  setting_enabled_scm: Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· SCM
-  setting_mail_handler_api_enabled: Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· WS Î³Î¹Î± ÎµÎ¹ÏƒÎµÏÏ‡ÏŒÎ¼ÎµÎ½Î± email
-  setting_mail_handler_api_key: ÎºÎ»ÎµÎ¹Î´Î¯ API
-  setting_sequential_project_identifiers: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± Î´Î¹Î±Î´Î¿Ï‡Î¹ÎºÏŽÎ½ Î±Î½Î±Î³Î½Ï‰ÏÎ¹ÏƒÏ„Î¹ÎºÏŽÎ½ Î­ÏÎ³Î¿Ï…
-  setting_gravatar_enabled: Î§ÏÎ®ÏƒÎ· Gravatar ÎµÎ¹ÎºÎ¿Î½Î¹Î´Î¯Ï‰Î½ Ï‡ÏÎ·ÏƒÏ„ÏŽÎ½
-  setting_diff_max_lines_displayed: ÎœÎµÎ³.Î±ÏÎ¹Î¸Î¼ÏŒÏ‚ ÎµÎ¼Ï†Î¬Î½Î¹ÏƒÎ·Ï‚ Î³ÏÎ±Î¼Î¼ÏŽÎ½ diff
-  setting_file_max_size_displayed: ÎœÎµÎ³.Î¼Î­Î³ÎµÎ¸Î¿Ï‚ Ï„Ï‰Î½ Î±ÏÏ‡ÎµÎ¯Ï‰Î½ Î±Ï€Î»Î¿Ï ÎºÎµÎ¹Î¼Î­Î½Î¿Ï… Ï€Î¿Ï… ÎµÎ¼Ï†Î±Î½Î¯Î¶Î¿Î½Ï„Î±Î¹ ÏƒÎµ ÏƒÎµÎ¹ÏÎ¬
-  setting_repository_log_display_limit: ÎœÎ­Î³Î¹ÏƒÏ„Î¿Ï‚ Î±ÏÎ¹Î¸Î¼ÏŒÏ‚ Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÏ‰Î½ Ï€Î¿Ï… ÎµÎ¼Ï†Î±Î½Î¯Î¶Î¿Î½Ï„Î±Î¹ ÏƒÏ„Î¿ Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ Î±ÏÏ‡ÎµÎ¯Î¿Ï…
-  setting_openid: Î•Ï€Î¹Ï„ÏÎ­ÏˆÏ„Îµ ÏƒÏ…Î½Î´Î­ÏƒÎµÎ¹Ï‚ OpenID ÎºÎ±Î¹ ÎµÎ³Î³ÏÎ±Ï†Î®
-  setting_password_min_length: Î•Î»Î¬Ï‡Î¹ÏƒÏ„Î¿ Î¼Î®ÎºÎ¿Ï‚ ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
-  setting_new_project_user_role_id: Î‘Ï€ÏŒÎ´Î¿ÏƒÎ· ÏÏŒÎ»Î¿Ï… ÏƒÎµ Ï‡ÏÎ®ÏƒÏ„Î· Î¼Î·-Î´Î¹Î±Ï‡ÎµÎ¹ÏÎ¹ÏƒÏ„Î® ÏŒÏ„Î±Î½ Î´Î·Î¼Î¹Î¿Ï…ÏÎ³ÎµÎ¯ Î­Î½Î± Î­ÏÎ³Î¿
-  
-  permission_add_project: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± Î­ÏÎ³Î¿Ï…
-  permission_edit_project: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î­ÏÎ³Î¿Ï…
-  permission_select_project_modules: Î•Ï€Î¹Î»Î¿Î³Î® Î¼Î¿Î½Î¬Î´Ï‰Î½ Î­ÏÎ³Î¿Ï…
-  permission_manage_members: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î¼ÎµÎ»ÏŽÎ½
-  permission_manage_versions: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÎµÎºÎ´ÏŒÏƒÎµÏ‰Î½
-  permission_manage_categories: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÎºÎ±Ï„Î·Î³Î¿ÏÎ¹ÏŽÎ½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  permission_add_issues: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  permission_edit_issues: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  permission_manage_issue_relations: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÏƒÏ…ÏƒÏ‡ÎµÏ„Î¹ÏƒÎ¼ÏŽÎ½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  permission_add_issue_notes: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· ÏƒÎ·Î¼ÎµÎ¹ÏŽÏƒÎµÏ‰Î½
-  permission_edit_issue_notes: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± ÏƒÎ·Î¼ÎµÎ¹ÏŽÏƒÎµÏ‰Î½
-  permission_edit_own_issue_notes: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î´Î¹ÎºÏŽÎ½ Î¼Î¿Ï… ÏƒÎ·Î¼ÎµÎ¹ÏŽÏƒÎµÏ‰Î½
-  permission_move_issues: ÎœÎµÏ„Î±Ï†Î¿ÏÎ¬ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  permission_delete_issues: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  permission_manage_public_queries: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î´Î·Î¼ÏŒÏƒÎ¹Ï‰Î½ Î±Î½Î±Î¶Î·Ï„Î®ÏƒÎµÏ‰Î½
-  permission_save_queries: Î‘Ï€Î¿Î¸Î®ÎºÎµÏ…ÏƒÎ· Î±Î½Î±Î¶Î·Ï„Î®ÏƒÎµÏ‰Î½
-  permission_view_gantt: Î ÏÎ¿Î²Î¿Î»Î® Î´Î¹Î±Î³ÏÎ¬Î¼Î¼Î±Ï„Î¿Ï‚ gantt
-  permission_view_calendar: Î ÏÎ¿Î²Î¿Î»Î® Î·Î¼ÎµÏÎ¿Î»Î¿Î³Î¯Î¿Ï…
-  permission_view_issue_watchers: Î ÏÎ¿Î²Î¿Î»Î® Î»Î¯ÏƒÏ„Î±Ï‚ Ï€Î±ÏÎ±Ï„Î·ÏÎ·Ï„ÏŽÎ½
-  permission_add_issue_watchers: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Ï€Î±ÏÎ±Ï„Î·ÏÎ·Ï„ÏŽÎ½
-  permission_log_time: Î™ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ Ï‡ÏÏŒÎ½Î¿Ï… Ï€Î¿Ï… Î´Î±Ï€Î±Î½Î®Î¸Î·ÎºÎµ
-  permission_view_time_entries: Î ÏÎ¿Î²Î¿Î»Î® Ï‡ÏÏŒÎ½Î¿Ï… Ï€Î¿Ï… Î´Î±Ï€Î±Î½Î®Î¸Î·ÎºÎµ
-  permission_edit_time_entries: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÎ¿Ï Ï‡ÏÏŒÎ½Î¿Ï… 
-  permission_edit_own_time_entries: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î´Î¹ÎºÎ¿Ï Î¼Î¿Ï… Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÎ¿Ï Ï‡ÏÏŒÎ½Î¿Ï…
-  permission_manage_news: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î½Î­Ï‰Î½
-  permission_comment_news: Î£Ï‡Î¿Î»Î¹Î±ÏƒÎ¼ÏŒÏ‚ Î½Î­Ï‰Î½
-  permission_manage_documents: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÎµÎ³Î³ÏÎ¬Ï†Ï‰Î½
-  permission_view_documents: Î ÏÎ¿Î²Î¿Î»Î® ÎµÎ³Î³ÏÎ¬Ï†Ï‰Î½
-  permission_manage_files: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î±ÏÏ‡ÎµÎ¯Ï‰Î½
-  permission_view_files: Î ÏÎ¿Î²Î¿Î»Î® Î±ÏÏ‡ÎµÎ¯Ï‰Î½
-  permission_manage_wiki: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· wiki
-  permission_rename_wiki_pages: ÎœÎµÏ„Î¿Î½Î¿Î¼Î±ÏƒÎ¯Î± ÏƒÎµÎ»Î¯Î´Ï‰Î½ wiki
-  permission_delete_wiki_pages: Î”Î¹Î±Î³ÏÎ±Ï†Î® ÏƒÎµÎ»Î¯Î´Ï‰Î½ wiki
-  permission_view_wiki_pages: Î ÏÎ¿Î²Î¿Î»Î® wiki
-  permission_view_wiki_edits: Î ÏÎ¿Î²Î¿Î»Î® Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÎ¿Ï wiki
-  permission_edit_wiki_pages: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± ÏƒÎµÎ»Î¯Î´Ï‰Î½ wiki
-  permission_delete_wiki_pages_attachments: Î”Î¹Î±Î³ÏÎ±Ï†Î® ÏƒÏ…Î½Î·Î¼Î¼Î­Î½Ï‰Î½
-  permission_protect_wiki_pages: Î ÏÎ¿ÏƒÏ„Î±ÏƒÎ¯Î± ÏƒÎµÎ»Î¯Î´Ï‰Î½ wiki
-  permission_manage_repository: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î±Ï€Î¿Î¸ÎµÏ„Î·ÏÎ¯Î¿Ï…
-  permission_browse_repository: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÎµÎ³Î³ÏÎ¬Ï†Ï‰Î½
-  permission_view_changesets: Î ÏÎ¿Î²Î¿Î»Î® changesets
-  permission_commit_access: Î ÏÏŒÏƒÎ²Î±ÏƒÎ· commit
-  permission_manage_boards: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Ï€Î¹Î½Î¬ÎºÏ‰Î½ ÏƒÏ…Î¶Î·Ï„Î®ÏƒÎµÏ‰Î½
-  permission_view_messages: Î ÏÎ¿Î²Î¿Î»Î® Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
-  permission_add_messages: Î‘Ï€Î¿ÏƒÏ„Î¿Î»Î® Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
-  permission_edit_messages: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
-  permission_edit_own_messages: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î´Î¹ÎºÏŽÎ½ Î¼Î¿Ï… Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
-  permission_delete_messages: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
-  permission_delete_own_messages: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î´Î¹ÎºÏŽÎ½ Î¼Î¿Ï… Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
-  
-  project_module_issue_tracking: Î‘Î½Î¯Ï‡Î½ÎµÏ…ÏƒÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  project_module_time_tracking: Î‘Î½Î¯Ï‡Î½ÎµÏ…ÏƒÎ· Ï‡ÏÏŒÎ½Î¿Ï…
-  project_module_news: ÎÎ­Î±
-  project_module_documents: ÎˆÎ³Î³ÏÎ±Ï†Î±
-  project_module_files: Î‘ÏÏ‡ÎµÎ¯Î±
-  project_module_wiki: Wiki
-  project_module_repository: Î‘Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î¿
-  project_module_boards: Î Î¯Î½Î±ÎºÎµÏ‚ ÏƒÏ…Î¶Î·Ï„Î®ÏƒÎµÏ‰Î½
-  
-  label_user: Î§ÏÎ®ÏƒÏ„Î·Ï‚
-  label_user_plural: Î§ÏÎ®ÏƒÏ„ÎµÏ‚
-  label_user_new: ÎÎ­Î¿Ï‚ Î§ÏÎ®ÏƒÏ„Î·Ï‚
-  label_project: ÎˆÏÎ³Î¿
-  label_project_new: ÎÎ­Î¿ Î­ÏÎ³Î¿
-  label_project_plural: ÎˆÏÎ³Î±
-  label_x_projects:
-    zero:  ÎºÎ±Î½Î­Î½Î± Î­ÏÎ³Î¿
-    one:   1 Î­ÏÎ³Î¿
-    other: "%{count} Î­ÏÎ³Î±"
-  label_project_all: ÎŒÎ»Î± Ï„Î± Î­ÏÎ³Î±
-  label_project_latest: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± Î­ÏÎ³Î±
-  label_issue: Î˜Î­Î¼Î±
-  label_issue_new: ÎÎ­Î¿ Î¸Î­Î¼Î±
-  label_issue_plural: Î˜Î­Î¼Î±Ï„Î±
-  label_issue_view_all: Î ÏÎ¿Î²Î¿Î»Î® ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  label_issues_by: "Î˜Î­Î¼Î±Ï„Î± Ï„Î¿Ï…  %{value}"
-  label_issue_added: Î¤Î¿ Î¸Î­Î¼Î± Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
-  label_issue_updated: Î¤Î¿ Î¸Î­Î¼Î± ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ
-  label_document: ÎˆÎ³Î³ÏÎ±Ï†Î¿
-  label_document_new: ÎÎ­Î¿ Î­Î³Î³ÏÎ±Ï†Î¿
-  label_document_plural: ÎˆÎ³Î³ÏÎ±Ï†Î±
-  label_document_added: ÎˆÎ³Î³ÏÎ±Ï†Î¿ Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
-  label_role: Î¡ÏŒÎ»Î¿Ï‚
-  label_role_plural: Î¡ÏŒÎ»Î¿Î¹
-  label_role_new: ÎÎ­Î¿Ï‚ ÏÏŒÎ»Î¿Ï‚
-  label_role_and_permissions: Î¡ÏŒÎ»Î¿Î¹ ÎºÎ±Î¹ Î¬Î´ÎµÎ¹ÎµÏ‚
-  label_member: ÎœÎ­Î»Î¿Ï‚
-  label_member_new: ÎÎ­Î¿ Î¼Î­Î»Î¿Ï‚
-  label_member_plural: ÎœÎ­Î»Î·
-  label_tracker: Î‘Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®Ï‚
-  label_tracker_plural: Î‘Î½Î¹Ï‡Î½ÎµÏ…Ï„Î­Ï‚
-  label_tracker_new: ÎÎ­Î¿Ï‚ Î‘Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®Ï‚
-  label_workflow: Î¡Î¿Î® ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚
-  label_issue_status: ÎšÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ· Î¸Î­Î¼Î±Ï„Î¿Ï‚
-  label_issue_status_plural: ÎšÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ· Î¸Î­Î¼Î±Ï„Î¿Ï‚
-  label_issue_status_new: ÎÎ­Î± ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·
-  label_issue_category: ÎšÎ±Ï„Î·Î³Î¿ÏÎ¯Î± Î¸Î­Î¼Î±Ï„Î¿Ï‚
-  label_issue_category_plural: ÎšÎ±Ï„Î·Î³Î¿ÏÎ¯ÎµÏ‚ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  label_issue_category_new: ÎÎ­Î± ÎºÎ±Ï„Î·Î³Î¿ÏÎ¯Î±
-  label_custom_field: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½Î¿ Ï€ÎµÎ´Î¯Î¿
-  label_custom_field_plural: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½Î± Ï€ÎµÎ´Î¯Î±
-  label_custom_field_new: ÎÎ­Î¿ Ï€ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½Î¿ Ï€ÎµÎ´Î¯Î¿
-  label_enumerations: Î‘Ï€Î±ÏÎ¹Î¸Î¼Î®ÏƒÎµÎ¹Ï‚
-  label_enumeration_new: ÎÎ­Î± Ï„Î¹Î¼Î®
-  label_information: Î Î»Î·ÏÎ¿Ï†Î¿ÏÎ¯Î±
-  label_information_plural: Î Î»Î·ÏÎ¿Ï†Î¿ÏÎ¯ÎµÏ‚
-  label_please_login: Î Î±ÏÎ±ÎºÎ±Î»ÏŽ ÏƒÏ…Î½Î´ÎµÎ¸ÎµÎ¯Ï„Îµ
-  label_register: Î•Î³Î³ÏÎ±Ï†Î®
-  label_login_with_open_id_option: Î® ÏƒÏ…Î½Î´ÎµÎ¸ÎµÎ¯Ï„Îµ Î¼Îµ OpenID
-  label_password_lost: Î‘Î½Î¬ÎºÏ„Î·ÏƒÎ· ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
-  label_home: Î‘ÏÏ‡Î¹ÎºÎ® ÏƒÎµÎ»Î¯Î´Î±
-  label_my_page: Î— ÏƒÎµÎ»Î¯Î´Î± Î¼Î¿Ï…
-  label_my_account: ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ Î¼Î¿Ï…
-  label_my_projects: Î¤Î± Î­ÏÎ³Î± Î¼Î¿Ï…
-  label_administration: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ·
-  label_login: Î£ÏÎ½Î´ÎµÏƒÎ·
-  label_logout: Î‘Ï€Î¿ÏƒÏÎ½Î´ÎµÏƒÎ·
-  label_help: Î’Î¿Î®Î¸ÎµÎ¹Î±
-  label_reported_issues: Î•Î¹ÏƒÎ·Î³Î¼Î­Î½Î± Î¸Î­Î¼Î±Ï„Î±
-  label_assigned_to_me_issues: Î˜Î­Î¼Î±Ï„Î± Ï€Î¿Ï… Î­Ï‡Î¿Ï…Î½ Î±Î½Î±Ï„ÎµÎ¸ÎµÎ¯ ÏƒÎµ Î¼Î­Î½Î±
-  label_last_login: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± ÏƒÏÎ½Î´ÎµÏƒÎ·
-  label_registered_on: Î•Î³Î³ÏÎ¬Ï†Î·ÎºÎµ Ï„Î·Î½ 
-  label_activity: Î”ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î±
-  label_overall_activity: Î£Ï…Î½Î¿Î»Î¹ÎºÎ® Î´ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î±
-  label_user_activity: "Î´ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î± Ï„Î¿Ï… %{value}"
-  label_new: ÎÎ­Î¿
-  label_logged_as: Î£ÏÎ½Î´ÎµÎ´ÎµÎ¼Î­Î½Î¿Ï‚ Ï‰Ï‚
-  label_environment: Î ÎµÏÎ¹Î²Î¬Î»Î»Î¿Î½
-  label_authentication: Î Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·
-  label_auth_source: Î¤ÏÏŒÏ€Î¿Ï‚ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚
-  label_auth_source_new: ÎÎ­Î¿Ï‚ Ï„ÏÏŒÏ€Î¿Ï‚ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚
-  label_auth_source_plural: Î¤ÏÏŒÏ€Î¿Î¹ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚
-  label_subproject_plural: Î•Ï€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î±
-  label_and_its_subprojects: "%{value} ÎºÎ±Î¹ Ï„Î± ÎµÏ€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î± Ï„Î¿Ï…"
-  label_min_max_length: Î•Î»Î¬Ï‡. - ÎœÎ­Î³. Î¼Î®ÎºÎ¿Ï‚
-  label_list: Î›Î¯ÏƒÏ„Î±
-  label_date: Î—Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±
-  label_integer: Î‘ÎºÎ­ÏÎ±Î¹Î¿Ï‚
-  label_float: Î‘ÏÎ¹Î¸Î¼ÏŒÏ‚ ÎºÎ¹Î½Î·Ï„Î®Ï‚ Ï…Ï€Î¿Î´Î¹Î±ÏƒÏ„Î¿Î»Î®Ï‚
-  label_boolean: Î›Î¿Î³Î¹ÎºÏŒÏ‚
-  label_string: ÎšÎµÎ¯Î¼ÎµÎ½Î¿
-  label_text: ÎœÎ±ÎºÏÎ¿ÏƒÎºÎµÎ»Î­Ï‚ ÎºÎµÎ¯Î¼ÎµÎ½Î¿
-  label_attribute: Î™Î´Î¹ÏŒÏ„Î·Ï„Î±
-  label_attribute_plural: Î™Î´Î¹ÏŒÏ„Î·Ï„ÎµÏ‚
-  label_download: "%{count} ÎœÎµÏ„Î±Ï†ÏŒÏÏ„Ï‰ÏƒÎ·"
-  label_download_plural: "%{count} ÎœÎµÏ„Î±Ï†Î¿ÏÏ„ÏŽÏƒÎµÎ¹Ï‚"
-  label_no_data: Î”ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ Î´ÎµÎ´Î¿Î¼Î­Î½Î±
-  label_change_status: Î‘Î»Î»Î±Î³Î® ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·Ï‚
-  label_history: Î™ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ
-  label_attachment: Î‘ÏÏ‡ÎµÎ¯Î¿
-  label_attachment_new: ÎÎ­Î¿ Î±ÏÏ‡ÎµÎ¯Î¿
-  label_attachment_delete: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î±ÏÏ‡ÎµÎ¯Î¿Ï…
-  label_attachment_plural: Î‘ÏÏ‡ÎµÎ¯Î±
-  label_file_added: Î¤Î¿ Î±ÏÏ‡ÎµÎ¯Î¿ Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
-  label_report: Î‘Î½Î±Ï†Î¿ÏÎ¬
-  label_report_plural: Î‘Î½Î±Ï†Î¿ÏÎ­Ï‚
-  label_news: ÎÎ­Î±
-  label_news_new: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Î½Î­Ï‰Î½
-  label_news_plural: ÎÎ­Î±
-  label_news_latest: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± Î½Î­Î±
-  label_news_view_all: Î ÏÎ¿Î²Î¿Î»Î® ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î½Î­Ï‰Î½
-  label_news_added: Î¤Î± Î½Î­Î± Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎ±Î½
-  label_settings: Î¡Ï…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚
-  label_overview: Î•Ï€Î¹ÏƒÎºÏŒÏ€Î·ÏƒÎ·
-  label_version: ÎˆÎºÎ´Î¿ÏƒÎ·
-  label_version_new: ÎÎ­Î± Î­ÎºÎ´Î¿ÏƒÎ·
-  label_version_plural: Î•ÎºÎ´ÏŒÏƒÎµÎ¹Ï‚
-  label_confirmation: Î•Ï€Î¹Î²ÎµÎ²Î±Î¯Ï‰ÏƒÎ·
-  label_export_to: 'Î•Ï€Î¯ÏƒÎ·Ï‚ Î´Î¹Î±Î¸Î­ÏƒÎ¹Î¼Î¿ ÏƒÎµ:'
-  label_read: Î”Î¹Î¬Î²Î±ÏƒÎµ...
-  label_public_projects: Î”Î·Î¼ÏŒÏƒÎ¹Î± Î­ÏÎ³Î±
-  label_open_issues: Î‘Î½Î¿Î¹ÎºÏ„ÏŒ
-  label_open_issues_plural: Î‘Î½Î¿Î¹ÎºÏ„Î¬
-  label_closed_issues: ÎšÎ»ÎµÎ¹ÏƒÏ„ÏŒ
-  label_closed_issues_plural: ÎšÎ»ÎµÎ¹ÏƒÏ„Î¬
-  label_x_open_issues_abbr_on_total:
-    zero:  0 Î±Î½Î¿Î¹ÎºÏ„Î¬ / %{total}
-    one:   1 Î±Î½Î¿Î¹ÎºÏ„ÏŒ / %{total}
-    other: "%{count} Î±Î½Î¿Î¹ÎºÏ„Î¬ / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 Î±Î½Î¿Î¹ÎºÏ„Î¬
-    one:   1 Î±Î½Î¿Î¹ÎºÏ„ÏŒ
-    other: "%{count} Î±Î½Î¿Î¹ÎºÏ„Î¬"
-  label_x_closed_issues_abbr:
-    zero:  0 ÎºÎ»ÎµÎ¹ÏƒÏ„Î¬
-    one:   1 ÎºÎ»ÎµÎ¹ÏƒÏ„ÏŒ
-    other: "%{count} ÎºÎ»ÎµÎ¹ÏƒÏ„Î¬"
-  label_total: Î£ÏÎ½Î¿Î»Î¿
-  label_permissions: Î†Î´ÎµÎ¹ÎµÏ‚
-  label_current_status: Î¤ÏÎ­Ï‡Î¿Ï…ÏƒÎ± ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·
-  label_new_statuses_allowed: ÎÎ­ÎµÏ‚ ÎºÎ±Ï„Î±ÏƒÏ„Î¬ÏƒÎµÎ¹Ï‚ ÎµÏ€Î¹Ï„ÏÎ­Ï€Î¿Î½Ï„Î±Î¹
-  label_all: ÏŒÎ»Î±
-  label_none: ÎºÎ±Î½Î­Î½Î±
-  label_nobody: ÎºÎ±Î½ÎµÎ¯Ï‚
-  label_next: Î•Ï€ÏŒÎ¼ÎµÎ½Î¿
-  label_previous: Î ÏÎ¿Î·Î³Î¿ÏÎ¼ÎµÎ½Î¿
-  label_used_by: Î§ÏÎ·ÏƒÎ¹Î¼Î¿Ï€Î¿Î¹Î®Î¸Î·ÎºÎµ Î±Ï€ÏŒ
-  label_details: Î›ÎµÏ€Ï„Î¿Î¼Î­ÏÎµÎ¹ÎµÏ‚
-  label_add_note: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· ÏƒÎ·Î¼ÎµÎ¯Ï‰ÏƒÎ·Ï‚
-  label_per_page: Î‘Î½Î¬ ÏƒÎµÎ»Î¯Î´Î±
-  label_calendar: Î—Î¼ÎµÏÎ¿Î»ÏŒÎ³Î¹Î¿
-  label_months_from: Î¼Î·Î½ÏŽÎ½ Î±Ï€ÏŒ
-  label_gantt: Gantt
-  label_internal: Î•ÏƒÏ‰Ï„ÎµÏÎ¹ÎºÏŒ
-  label_last_changes: "Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯ÎµÏ‚ %{count} Î±Î»Î»Î±Î³Î­Ï‚"
-  label_change_view_all: Î ÏÎ¿Î²Î¿Î»Î® ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î±Î»Î»Î±Î³ÏŽÎ½
-  label_personalize_page: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿Î³Î® ÏƒÎµÎ»Î¯Î´Î±Ï‚
-  label_comment: Î£Ï‡ÏŒÎ»Î¹Î¿
-  label_comment_plural: Î£Ï‡ÏŒÎ»Î¹Î±
-  label_x_comments:
-    zero: Î´ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ ÏƒÏ‡ÏŒÎ»Î¹Î±
-    one: 1 ÏƒÏ‡ÏŒÎ»Î¹Î¿
-    other: "%{count} ÏƒÏ‡ÏŒÎ»Î¹Î±"
-  label_comment_add: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· ÏƒÏ‡Î¿Î»Î¯Î¿Ï…
-  label_comment_added: Î¤Î± ÏƒÏ‡ÏŒÎ»Î¹Î± Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎ±Î½
-  label_comment_delete: Î”Î¹Î±Î³ÏÎ±Ï†Î® ÏƒÏ‡Î¿Î»Î¯Ï‰Î½
-  label_query: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½Î· Î±Î½Î±Î¶Î®Ï„Î·ÏƒÎ·
-  label_query_plural: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½ÎµÏ‚ Î±Î½Î±Î¶Î·Ï„Î®ÏƒÎµÎ¹Ï‚
-  label_query_new: ÎÎ­Î± Î±Î½Î±Î¶Î®Ï„Î·ÏƒÎ·
-  label_filter_add: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Ï†Î¯Î»Ï„ÏÎ¿Ï…
-  label_filter_plural: Î¦Î¯Î»Ï„ÏÎ±
-  label_equals: ÎµÎ¯Î½Î±Î¹
-  label_not_equals: Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹
-  label_in_less_than: Î¼Î¹ÎºÏÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ
-  label_in_more_than: Ï€ÎµÏÎ¹ÏƒÏƒÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: ÏƒÎµ
-  label_today: ÏƒÎ®Î¼ÎµÏÎ±
-  label_all_time: ÏƒÏ…Î½Î­Ï‡ÎµÎ¹Î±
-  label_yesterday: Ï‡Î¸ÎµÏ‚
-  label_this_week: Î±Ï…Ï„Î® Ï„Î·Î½ ÎµÎ²Î´Î¿Î¼Î¬Î´Î±
-  label_last_week: Ï„Î·Î½ Ï€ÏÎ¿Î·Î³Î¿ÏÎ¼ÎµÎ½Î· ÎµÎ²Î´Î¿Î¼Î¬Î´Î±
-  label_last_n_days: "Ï„ÎµÎ»ÎµÏ…Ï„Î±Î¯ÎµÏ‚ %{count} Î¼Î­ÏÎµÏ‚"
-  label_this_month: Î±Ï…Ï„ÏŒ Ï„Î¿ Î¼Î®Î½Î±
-  label_last_month: Ï„Î¿Î½ Ï€ÏÎ¿Î·Î³Î¿ÏÎ¼ÎµÎ½Î¿ Î¼Î®Î½Î±
-  label_this_year: Î±Ï…Ï„ÏŒ Ï„Î¿ Ï‡ÏÏŒÎ½Î¿
-  label_date_range: Î§ÏÎ¿Î½Î¹ÎºÏŒ Î´Î¹Î¬ÏƒÏ„Î·Î¼Î±
-  label_less_than_ago: ÏƒÎµ Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î·Î¼Î­ÏÎµÏ‚ Ï€ÏÎ¹Î½
-  label_more_than_ago: ÏƒÎµ Ï€ÎµÏÎ¹ÏƒÏƒÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î·Î¼Î­ÏÎµÏ‚ Ï€ÏÎ¹Î½
-  label_ago: Î·Î¼Î­ÏÎµÏ‚ Ï€ÏÎ¹Î½
-  label_contains: Ï€ÎµÏÎ¹Î­Ï‡ÎµÎ¹
-  label_not_contains: Î´ÎµÎ½ Ï€ÎµÏÎ¹Î­Ï‡ÎµÎ¹
-  label_day_plural: Î¼Î­ÏÎµÏ‚
-  label_repository: Î‘Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î¿
-  label_repository_plural: Î‘Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î±
-  label_browse: Î Î»Î¿Î®Î³Î·ÏƒÎ·
-  label_modification: "%{count} Ï„ÏÎ¿Ï€Î¿Ï€Î¿Î¯Î·ÏƒÎ·"
-  label_modification_plural: "%{count} Ï„ÏÎ¿Ï€Î¿Ï€Î¿Î¹Î®ÏƒÎµÎ¹Ï‚"
-  label_branch: Branch
-  label_tag: Tag 
-  label_revision: Î‘Î½Î±Î¸ÎµÏŽÏÎ·ÏƒÎ·
-  label_revision_plural: Î‘Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÎ¹Ï‚
-  label_associated_revisions: Î£Ï…Î½ÎµÏ„Î±Î¹ÏÎ¹ÎºÎ­Ï‚ Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÎ¹Ï‚
-  label_added: Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
-  label_modified: Ï„ÏÎ¿Ï€Î¿Ï€Î¿Î¹Î®Î¸Î·ÎºÎµ
-  label_copied: Î±Î½Ï„Î¹Î³ÏÎ¬Ï†Î·ÎºÎµ
-  label_renamed: Î¼ÎµÏ„Î¿Î½Î¿Î¼Î¬ÏƒÏ„Î·ÎºÎµ
-  label_deleted: Î´Î¹Î±Î³ÏÎ¬Ï†Î·ÎºÎµ
-  label_latest_revision: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± Î±Î½Î±Î¸ÎµÏŽÏÎ¹ÏƒÎ·
-  label_latest_revision_plural: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯ÎµÏ‚ Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÎ¹Ï‚
-  label_view_revisions: Î ÏÎ¿Î²Î¿Î»Î® Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÏ‰Î½
-  label_view_all_revisions: Î ÏÎ¿Î²Î¿Î»Î® ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÏ‰Î½
-  label_max_size: ÎœÎ­Î³Î¹ÏƒÏ„Î¿ Î¼Î­Î³ÎµÎ¸Î¿Ï‚
-  label_sort_highest: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ· ÏƒÏ„Î·Î½ ÎºÎ¿ÏÏ…Ï†Î®
-  label_sort_higher: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ· Ï€ÏÎ¿Ï‚ Ï„Î± Ï€Î¬Î½Ï‰
-  label_sort_lower: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ· Ï€ÏÎ¿Ï‚ Ï„Î± ÎºÎ¬Ï„Ï‰
-  label_sort_lowest: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ· ÏƒÏ„Î¿ ÎºÎ±Ï„ÏŽÏ„Î±Ï„Î¿ Î¼Î­ÏÎ¿Ï‚
-  label_roadmap: Î§Î¬ÏÏ„Î·Ï‚ Ï€Î¿ÏÎµÎ¯Î±Ï‚
-  label_roadmap_due_in: "Î ÏÎ¿Î¸ÎµÏƒÎ¼Î¯Î± ÏƒÎµ %{value}"
-  label_roadmap_overdue: "%{value} ÎºÎ±Î¸Ï…ÏƒÏ„ÎµÏÎ·Î¼Î­Î½Î¿"
-  label_roadmap_no_issues: Î”ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ Î¸Î­Î¼Î±Ï„Î± Î³Î¹Î± Î±Ï…Ï„Î® Ï„Î·Î½ Î­ÎºÎ´Î¿ÏƒÎ·
-  label_search: Î‘Î½Î±Î¶Î®Ï„Î·ÏƒÎ·
-  label_result_plural: Î‘Ï€Î¿Ï„ÎµÎ»Î­ÏƒÎ¼Î±Ï„Î±
-  label_all_words:  ÎŒÎ»ÎµÏ‚ Î¿Î¹ Î»Î­Î¾ÎµÎ¹Ï‚
-  label_wiki: Wiki
-  label_wiki_edit: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± wiki
-  label_wiki_edit_plural: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± wiki
-  label_wiki_page: Î£ÎµÎ»Î¯Î´Î± Wiki
-  label_wiki_page_plural: Î£ÎµÎ»Î¯Î´ÎµÏ‚ Wiki
-  label_index_by_title: Î”ÎµÎ¯ÎºÏ„Î·Ï‚ Î±Î½Î¬ Ï„Î¯Ï„Î»Î¿
-  label_index_by_date: Î”ÎµÎ¯ÎºÏ„Î·Ï‚ Î±Î½Î¬ Î·Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±
-  label_current_version: Î¤ÏÎ­Ï‡Î¿Ï…ÏƒÎ± Î­ÎºÎ´Î¿ÏƒÎ·
-  label_preview: Î ÏÎ¿ÎµÏ€Î¹ÏƒÎºÏŒÏ€Î·ÏƒÎ·
-  label_feed_plural: Feeds
-  label_changes_details: Î›ÎµÏ€Ï„Î¿Î¼Î­ÏÎµÎ¹ÎµÏ‚ ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î±Î»Î»Î±Î³ÏŽÎ½
-  label_issue_tracking: Î‘Î½Î¯Ï‡Î½ÎµÏ…ÏƒÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  label_spent_time: Î”Î±Ï€Î±Î½Î·Î¼Î­Î½Î¿Ï‚ Ï‡ÏÏŒÎ½Î¿Ï‚
-  label_f_hour: "%{value} ÏŽÏÎ±"
-  label_f_hour_plural: "%{value} ÏŽÏÎµÏ‚"
-  label_time_tracking: Î‘Î½Î¯Ï‡Î½ÎµÏ…ÏƒÎ· Ï‡ÏÏŒÎ½Î¿Ï…
-  label_change_plural: Î‘Î»Î»Î±Î³Î­Ï‚
-  label_statistics: Î£Ï„Î±Ï„Î¹ÏƒÏ„Î¹ÎºÎ¬
-  label_commits_per_month: Commits Î±Î½Î¬ Î¼Î®Î½Î±
-  label_commits_per_author: Commits Î±Î½Î¬ ÏƒÏ…Î³Î³ÏÎ±Ï†Î­Î±
-  label_view_diff: Î ÏÎ¿Î²Î¿Î»Î® Î´Î¹Î±Ï†Î¿ÏÏŽÎ½
-  label_diff_inline: ÏƒÎµ ÏƒÎµÎ¹ÏÎ¬
-  label_diff_side_by_side: Î±Î½Ï„Î¹ÎºÏÏ…ÏƒÏ„Î¬
-  label_options: Î•Ï€Î¹Î»Î¿Î³Î­Ï‚
-  label_copy_workflow_from: Î‘Î½Ï„Î¹Î³ÏÎ±Ï†Î® ÏÎ¿Î®Ï‚ ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚ Î±Ï€ÏŒ
-  label_permissions_report: Î£Ï…Î½Î¿Ï€Ï„Î¹ÎºÏŒÏ‚ Ï€Î¯Î½Î±ÎºÎ±Ï‚ Î±Î´ÎµÎ¹ÏŽÎ½
-  label_watched_issues: Î˜Î­Î¼Î±Ï„Î± Ï…Ï€ÏŒ Ï€Î±ÏÎ±ÎºÎ¿Î»Î¿ÏÎ¸Î·ÏƒÎ·
-  label_related_issues: Î£Ï‡ÎµÏ„Î¹ÎºÎ¬ Î¸Î­Î¼Î±Ï„Î±
-  label_applied_status: Î•Ï†Î±ÏÎ¼Î¿Î³Î® ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·Ï‚
-  label_loading: Î¦Î¿ÏÏ„ÏŽÎ½ÎµÏ„Î±Î¹...
-  label_relation_new: ÎÎ­Î± ÏƒÏ…ÏƒÏ‡Î­Ï„Î¹ÏƒÎ·
-  label_relation_delete: Î”Î¹Î±Î³ÏÎ±Ï†Î® ÏƒÏ…ÏƒÏ‡Î­Ï„Î¹ÏƒÎ·Ï‚
-  label_relates_to: ÏƒÏ‡ÎµÏ„Î¹ÎºÏŒ Î¼Îµ
-  label_duplicates: Î±Î½Ï„Î¯Î³ÏÎ±Ï†Î±
-  label_duplicated_by: Î±Î½Ï„Î¹Î³ÏÎ¬Ï†Î·ÎºÎµ Î±Ï€ÏŒ
-  label_blocks: Ï†ÏÎ±Î³Î­Ï‚
-  label_blocked_by: Ï†ÏÎ±Î³Î® Î±Ï€ÏŒ Ï„Î¿Î½
-  label_precedes: Ï€ÏÎ¿Î·Î³ÎµÎ¯Ï„Î±Î¹
-  label_follows: Î±ÎºÎ¿Î»Î¿Ï…Î¸ÎµÎ¯
-  label_end_to_start: Î±Ï€ÏŒ Ï„Î¿ Ï„Î­Î»Î¿Ï‚ ÏƒÏ„Î·Î½ Î±ÏÏ‡Î®
-  label_end_to_end: Î±Ï€ÏŒ Ï„Î¿ Ï„Î­Î»Î¿Ï‚ ÏƒÏ„Î¿ Ï„Î­Î»Î¿Ï‚
-  label_start_to_start: Î±Ï€ÏŒ Ï„Î·Î½ Î±ÏÏ‡Î® ÏƒÏ„Î·Î½ Î±ÏÏ‡Î®
-  label_start_to_end: Î±Ï€ÏŒ Ï„Î·Î½ Î±ÏÏ‡Î® ÏƒÏ„Î¿ Ï„Î­Î»Î¿Ï‚
-  label_stay_logged_in: Î Î±ÏÎ±Î¼Î¿Î½Î® ÏƒÏÎ½Î´ÎµÏƒÎ·Ï‚
-  label_disabled: Î±Ï€ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î·Î¼Î­Î½Î·
-  label_show_completed_versions: Î ÏÎ¿Î²Î¿Î»Î® Î¿Î»Î¿ÎºÎ»Î·ÏÏ‰Î¼Î­Î½Ï‰Î½ ÎµÎºÎ´ÏŒÏƒÎµÏ‰Î½
-  label_me: ÎµÎ³ÏŽ
-  label_board: Î¦ÏŒÏÎ¿Ï…Î¼
-  label_board_new: ÎÎ­Î¿ Ï†ÏŒÏÎ¿Ï…Î¼
-  label_board_plural: Î¦ÏŒÏÎ¿Ï…Î¼
-  label_topic_plural: Î˜Î­Î¼Î±Ï„Î±
-  label_message_plural: ÎœÎ·Î½ÏÎ¼Î±Ï„Î±
-  label_message_last: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î¿ Î¼Î®Î½Ï…Î¼Î±
-  label_message_new: ÎÎ­Î¿ Î¼Î®Î½Ï…Î¼Î±
-  label_message_posted: Î¤Î¿ Î¼Î®Î½Ï…Î¼Î± Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
-  label_reply_plural: Î‘Ï€Î±Î½Ï„Î®ÏƒÎµÎ¹Ï‚
-  label_send_information: Î‘Ï€Î¿ÏƒÏ„Î¿Î»Î® Ï€Î»Î·ÏÎ¿Ï†Î¿ÏÎ¹ÏŽÎ½ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÏ„Î¿ Ï‡ÏÎ®ÏƒÏ„Î·
-  label_year: ÎˆÏ„Î¿Ï‚
-  label_month: ÎœÎ®Î½Î±Ï‚
-  label_week: Î•Î²Î´Î¿Î¼Î¬Î´Î±
-  label_date_from: Î‘Ï€ÏŒ
-  label_date_to:  ÎˆÏ‰Ï‚
-  label_language_based: ÎœÎµ Î²Î¬ÏƒÎ· Ï„Î· Î³Î»ÏŽÏƒÏƒÎ± Ï„Î¿Ï… Ï‡ÏÎ®ÏƒÏ„Î·
-  label_sort_by: "Î¤Î±Î¾Î¹Î½ÏŒÎ¼Î·ÏƒÎ· Î±Î½Î¬ %{value}"
-  label_send_test_email: Î‘Ï€Î¿ÏƒÏ„Î¿Î»Î® Î´Î¿ÎºÎ¹Î¼Î±ÏƒÏ„Î¹ÎºÎ¿Ï email
-  label_feeds_access_key_created_on: "Ï„Î¿ ÎºÎ»ÎµÎ¹Î´Î¯ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ RSS Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î®Î¸Î·ÎºÎµ Ï€ÏÎ¹Î½ Î±Ï€ÏŒ %{value}"
-  label_module_plural: ÎœÎ¿Î½Î¬Î´ÎµÏ‚
-  label_added_time_by: "Î ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author} Ï€ÏÎ¹Î½ Î±Ï€ÏŒ %{age}"
-  label_updated_time_by: "Î•Î½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author} Ï€ÏÎ¹Î½ Î±Ï€ÏŒ %{age}"
-  label_updated_time: "Î•Î½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Ï€ÏÎ¹Î½ Î±Ï€ÏŒ %{value}"
-  label_jump_to_a_project: ÎœÎµÏ„Î±Î²ÎµÎ¯Ï„Îµ ÏƒÎµ Î­Î½Î± Î­ÏÎ³Î¿...
-  label_file_plural: Î‘ÏÏ‡ÎµÎ¯Î±
-  label_changeset_plural: Changesets
-  label_default_columns: Î ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½ÎµÏ‚ ÏƒÏ„Î®Î»ÎµÏ‚
-  label_no_change_option: (Î”ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ Î±Î»Î»Î±Î³Î­Ï‚)
-  label_bulk_edit_selected_issues: ÎœÎ±Î¶Î¹ÎºÎ® ÎµÏ€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Ï‰Î½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
-  label_theme: Î˜Î­Î¼Î±
-  label_default: Î ÏÎ¿ÎµÏ€Î¹Î»Î¿Î³Î®
-  label_search_titles_only: Î‘Î½Î±Î¶Î®Ï„Î·ÏƒÎ· Ï„Î¯Ï„Î»Ï‰Î½ Î¼ÏŒÎ½Î¿
-  label_user_mail_option_all: "Î“Î¹Î± ÏŒÎ»ÎµÏ‚ Ï„Î¹Ï‚ ÎµÎ¾ÎµÎ»Î¯Î¾ÎµÎ¹Ï‚ ÏƒÎµ ÏŒÎ»Î± Ï„Î± Î­ÏÎ³Î± Î¼Î¿Ï…"
-  label_user_mail_option_selected: "Î“Î¹Î± ÏŒÎ»ÎµÏ‚ Ï„Î¹Ï‚ ÎµÎ¾ÎµÎ»Î¯Î¾ÎµÎ¹Ï‚ Î¼ÏŒÎ½Î¿ ÏƒÏ„Î± ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î± Î­ÏÎ³Î±..."
-  label_user_mail_no_self_notified: "Î”ÎµÎ½ Î¸Î­Î»Ï‰ Î½Î± ÎµÎ¹Î´Î¿Ï€Î¿Î¹Î¿ÏÎ¼Î±Î¹ Î³Î¹Î± Ï„Î¹Ï‚ Î´Î¹ÎºÎ­Ï‚ Î¼Î¿Ï… Î±Î»Î»Î±Î³Î­Ï‚"
-  label_registration_activation_by_email: ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï Î¼Îµ email
-  label_registration_manual_activation: Ï‡ÎµÎ¹ÏÎ¿ÎºÎ¯Î½Î·Ï„Î· ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï
-  label_registration_automatic_activation: Î±Ï…Ï„ÏŒÎ¼Î±Ï„Î· ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï
-  label_display_per_page: "Î‘Î½Î¬ ÏƒÎµÎ»Î¯Î´Î±: %{value}"
-  label_age: Î—Î»Î¹ÎºÎ¯Î±
-  label_change_properties: Î‘Î»Î»Î±Î³Î® Î¹Î´Î¹Î¿Ï„Î®Ï„Ï‰Î½
-  label_general: Î“ÎµÎ½Î¹ÎºÎ¬
-  label_more: Î ÎµÏÎ¹ÏƒÏƒÏŒÏ„ÎµÏÎ±
-  label_scm: SCM
-  label_plugins: Plugins
-  label_ldap_authentication: Î Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ· LDAP
-  label_downloads_abbr: Îœ/Î¦
-  label_optional_description: Î ÏÎ¿Î±Î¹ÏÎµÏ„Î¹ÎºÎ® Ï€ÎµÏÎ¹Î³ÏÎ±Ï†Î®
-  label_add_another_file: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Î¬Î»Î»Î¿Ï… Î±ÏÏ‡ÎµÎ¯Î¿Ï…
-  label_preferences: Î ÏÎ¿Ï„Î¹Î¼Î®ÏƒÎµÎ¹Ï‚
-  label_chronological_order: ÎšÎ±Ï„Î¬ Ï‡ÏÎ¿Î½Î¿Î»Î¿Î³Î¹ÎºÎ® ÏƒÎµÎ¹ÏÎ¬
-  label_reverse_chronological_order: ÎšÎ±Ï„Î¬ Î±Î½Ï„Î¯ÏƒÏ„ÏÎ¿Ï†Î· Ï‡ÏÎ¿Î½Î¿Î»Î¿Î³Î¹ÎºÎ® ÏƒÎµÎ¹ÏÎ¬
-  label_planning: Î£Ï‡ÎµÎ´Î¹Î±ÏƒÎ¼ÏŒÏ‚
-  label_incoming_emails: Î•Î¹ÏƒÎµÏÏ‡ÏŒÎ¼ÎµÎ½Î± email
-  label_generate_key: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï
-  label_issue_watchers: Î Î±ÏÎ±Ï„Î·ÏÎ·Ï„Î­Ï‚
-  label_example: Î Î±ÏÎ¬Î´ÎµÎ¹Î³Î¼Î±
-  label_display: Î ÏÎ¿Î²Î¿Î»Î®
-  label_sort: Î¤Î±Î¾Î¹Î½ÏŒÎ¼Î·ÏƒÎ·
-  label_ascending: Î‘ÏÎ¾Î¿Ï…ÏƒÎ±
-  label_descending: Î¦Î¸Î¯Î½Î¿Ï…ÏƒÎ±
-  label_date_from_to: Î‘Ï€ÏŒ %{start} Î­Ï‰Ï‚ %{end}
-  label_wiki_content_added: Î— ÏƒÎµÎ»Î¯Î´Î± Wiki Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
-  label_wiki_content_updated: Î— ÏƒÎµÎ»Î¯Î´Î± Wiki ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ
-  
-  button_login: Î£ÏÎ½Î´ÎµÏƒÎ·
-  button_submit: Î‘Ï€Î¿ÏƒÏ„Î¿Î»Î®
-  button_save: Î‘Ï€Î¿Î¸Î®ÎºÎµÏ…ÏƒÎ·
-  button_check_all: Î•Ï€Î¹Î»Î¿Î³Î® ÏŒÎ»Ï‰Î½
-  button_uncheck_all: Î‘Ï€Î¿ÎµÏ€Î¹Î»Î¿Î³Î® ÏŒÎ»Ï‰Î½
-  button_delete: Î”Î¹Î±Î³ÏÎ±Ï†Î®
-  button_create: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î±
-  button_create_and_continue: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± ÎºÎ±Î¹ ÏƒÏ…Î½Î­Ï‡ÎµÎ¹Î±
-  button_test: Î¤ÎµÏƒÏ„
-  button_edit: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î±
-  button_add: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ·
-  button_change: Î‘Î»Î»Î±Î³Î®
-  button_apply: Î•Ï†Î±ÏÎ¼Î¿Î³Î®
-  button_clear: ÎšÎ±Î¸Î±ÏÎ¹ÏƒÎ¼ÏŒÏ‚
-  button_lock: ÎšÎ»ÎµÎ¯Î´Ï‰Î¼Î±
-  button_unlock: ÎžÎµÎºÎ»ÎµÎ¯Î´Ï‰Î¼Î±
-  button_download: ÎœÎµÏ„Î±Ï†ÏŒÏÏ„Ï‰ÏƒÎ·
-  button_list: Î›Î¯ÏƒÏ„Î±
-  button_view: Î ÏÎ¿Î²Î¿Î»Î®
-  button_move: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ·
-  button_back: Î Î¯ÏƒÏ‰
-  button_cancel: Î‘ÎºÏÏÏ‰ÏƒÎ·
-  button_activate: Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ·
-  button_sort: Î¤Î±Î¾Î¹Î½ÏŒÎ¼Î·ÏƒÎ·
-  button_log_time: Î™ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ Ï‡ÏÏŒÎ½Î¿Ï…
-  button_rollback: Î•Ï€Î±Î½Î±Ï†Î¿ÏÎ¬ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î·Î½ Î­ÎºÎ´Î¿ÏƒÎ·
-  button_watch: Î Î±ÏÎ±ÎºÎ¿Î»Î¿ÏÎ¸Î·ÏƒÎ·
-  button_unwatch: Î‘Î½Î±Î¯ÏÎµÏƒÎ· Ï€Î±ÏÎ±ÎºÎ¿Î»Î¿ÏÎ¸Î·ÏƒÎ·Ï‚
-  button_reply: Î‘Ï€Î¬Î½Ï„Î·ÏƒÎ·
-  button_archive: Î‘ÏÏ‡ÎµÎ¹Î¿Î¸Î­Ï„Î·ÏƒÎ·
-  button_unarchive: Î‘Î½Î±Î¯ÏÎµÏƒÎ· Î±ÏÏ‡ÎµÎ¹Î¿Î¸Î­Ï„Î·ÏƒÎ·Ï‚
-  button_reset: Î•Ï€Î±Î½Î±Ï†Î¿ÏÎ¬
-  button_rename: ÎœÎµÏ„Î¿Î½Î¿Î¼Î±ÏƒÎ¯Î±
-  button_change_password: Î‘Î»Î»Î±Î³Î® ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
-  button_copy: Î‘Î½Ï„Î¹Î³ÏÎ±Ï†Î®
-  button_annotate: Î£Ï‡Î¿Î»Î¹Î±ÏƒÎ¼ÏŒÏ‚
-  button_update: Î•Î½Î·Î¼Î­ÏÏ‰ÏƒÎ·
-  button_configure: Î¡ÏÎ¸Î¼Î¹ÏƒÎ·
-  button_quote: Î Î±ÏÎ¬Î¸ÎµÏƒÎ·
-  
-  status_active: ÎµÎ½ÎµÏÎ³ÏŒ(Ï‚)/Î®
-  status_registered: ÎµÎ³ÎµÎ³Î³ÏÎ±Î¼Î¼Î­Î½Î¿(Ï‚)/Î·
-  status_locked: ÎºÎ»ÎµÎ¹Î´Ï‰Î¼Î­Î½Î¿(Ï‚)/Î·
-  
-  text_select_mail_notifications: Î•Ï€Î¹Î»Î¿Î³Î® ÎµÎ½ÎµÏÎ³ÎµÎ¹ÏŽÎ½ Î³Î¹Î± Ï„Î¹Ï‚ Î¿Ï€Î¿Î¯ÎµÏ‚ Î¸Î± Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± Î±Ï€Î¿ÏƒÏ„Î±Î»ÎµÎ¯ ÎµÎ¹Î´Î¿Ï€Î¿Î¯Î·ÏƒÎ· Î¼Îµ email.
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 ÏƒÎ·Î¼Î±Î¯Î½ÎµÎ¹ ÏŒÏ„Î¹ Î´ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ Ï€ÎµÏÎ¹Î¿ÏÎ¹ÏƒÎ¼Î¿Î¯
-  text_project_destroy_confirmation: Î•Î¯ÏƒÏ„Îµ ÏƒÎ¯Î³Î¿Ï…ÏÎ¿Î¹ ÏŒÏ„Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± Î´Î¹Î±Î³ÏÎ¬ÏˆÎµÏ„Îµ Î±Ï…Ï„ÏŒ Ï„Î¿ Î­ÏÎ³Î¿ ÎºÎ±Î¹ Ï„Î± ÏƒÏ‡ÎµÏ„Î¹ÎºÎ¬ Î´ÎµÎ´Î¿Î¼Î­Î½Î± Ï„Î¿Ï…;
-  text_subprojects_destroy_warning: "Î•Ï€Î¯ÏƒÎ·Ï‚ Ï„Î¿(Î±) ÎµÏ€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î¿(Î±): %{value}  Î¸Î± Î´Î¹Î±Î³ÏÎ±Ï†Î¿ÏÎ½."
-  text_workflow_edit: Î•Ï€Î¹Î»Î­Î¾Ï„Îµ Î­Î½Î± ÏÏŒÎ»Î¿ ÎºÎ±Î¹ Î­Î½Î±Î½ Î±Î½Î¹Ï‡Î½ÎµÏ…Ï„Î® Î³Î¹Î± Î½Î± ÎµÏ€ÎµÎ¾ÎµÏÎ³Î±ÏƒÏ„ÎµÎ¯Ï„Îµ  Ï„Î· ÏÎ¿Î® ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚
-  text_are_you_sure: Î•Î¯ÏƒÏ„Îµ ÏƒÎ¯Î³Î¿Ï…ÏÎ¿Ï‚ ;
-  text_tip_issue_begin_day: ÎºÎ±Î¸Î®ÎºÎ¿Î½Ï„Î± Ï€Î¿Ï… Î¾ÎµÎºÎ¹Î½Î¬Î½Îµ ÏƒÎ®Î¼ÎµÏÎ±
-  text_tip_issue_end_day: ÎºÎ±Î¸Î®ÎºÎ¿Î½Ï„Î± Ï€Î¿Ï… Ï„ÎµÎ»ÎµÎ¹ÏŽÎ½Î¿Ï…Î½ ÏƒÎ®Î¼ÎµÏÎ±
-  text_tip_issue_begin_end_day: ÎºÎ±Î¸Î®ÎºÎ¿Î½Ï„Î± Ï€Î¿Ï… Î¾ÎµÎºÎ¹Î½Î¬Î½Îµ ÎºÎ±Î¹ Ï„ÎµÎ»ÎµÎ¹ÏŽÎ½Î¿Ï…Î½ ÏƒÎ®Î¼ÎµÏÎ±
-  text_project_identifier_info: 'Î•Ï€Î¹Ï„ÏÎ­Ï€Î¿Î½Ï„Î±Î¹ Î¼ÏŒÎ½Î¿ Î¼Î¹ÎºÏÎ¬ Ï€ÎµÎ¶Î¬ Î³ÏÎ¬Î¼Î¼Î±Ï„Î± (a-z), Î±ÏÎ¹Î¸Î¼Î¿Î¯ ÎºÎ±Î¹ Ï€Î±ÏÎ»ÎµÏ‚. <br /> ÎœÎµÏ„Î¬ Ï„Î·Î½ Î±Ï€Î¿Î¸Î®ÎºÎµÏ…ÏƒÎ·, Ï„Î¿ Î±Î½Î±Î³Î½Ï‰ÏÎ¹ÏƒÏ„Î¹ÎºÏŒ Î´ÎµÎ½ Î¼Ï€Î¿ÏÎµÎ¯ Î½Î± Î±Î»Î»Î¬Î¾ÎµÎ¹.'
-  text_caracters_maximum: "Î¼Î­Î³Î¹ÏƒÏ„Î¿Ï‚ Î±ÏÎ¹Î¸Î¼ÏŒÏ‚ %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚."
-  text_caracters_minimum: "Î ÏÎ­Ï€ÎµÎ¹ Î½Î± Ï€ÎµÏÎ¹Î­Ï‡ÎµÎ¹ Ï„Î¿Ï…Î»Î¬Ï‡Î¹ÏƒÏ„Î¿Î½ %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚."
-  text_length_between: "ÎœÎ®ÎºÎ¿Ï‚ Î¼ÎµÏ„Î±Î¾Ï %{min} ÎºÎ±Î¹ %{max} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚."
-  text_tracker_no_workflow: Î”ÎµÎ½ Î­Ï‡ÎµÎ¹ Î¿ÏÎ¹ÏƒÏ„ÎµÎ¯ ÏÎ¿Î® ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚ Î³Î¹Î± Î±Ï…Ï„ÏŒ Ï„Î¿Î½ Î±Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®
-  text_unallowed_characters: ÎœÎ· ÎµÏ€Î¹Ï„ÏÎµÏ€ÏŒÎ¼ÎµÎ½Î¿Î¹ Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚
-  text_comma_separated: Î•Ï€Î¹Ï„ÏÎ­Ï€Î¿Î½Ï„Î±Î¹ Ï€Î¿Î»Î»Î±Ï€Î»Î­Ï‚ Ï„Î¹Î¼Î­Ï‚ (Ï‡Ï‰ÏÎ¹ÏƒÎ¼Î­Î½ÎµÏ‚ Î¼Îµ ÎºÏŒÎ¼Î¼Î±).
-  text_issues_ref_in_commit_messages: Î‘Î½Î±Ï†Î¿ÏÎ¬ ÎºÎ±Î¹ ÎºÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼ÏŒÏ‚ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÏƒÎµ Î¼Î·Î½ÏÎ¼Î±Ï„Î± commit
-  text_issue_added: "Î¤Î¿ Î¸Î­Î¼Î± %{id} Ï€Î±ÏÎ¿Ï…ÏƒÎ¹Î¬ÏƒÏ„Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author}."
-  text_issue_updated: "Î¤Î¿ Î¸Î­Î¼Î± %{id} ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author}."
-  text_wiki_destroy_confirmation: Î•Î¯ÏƒÏ„Îµ ÏƒÎ¯Î³Î¿Ï…ÏÎ¿Î¹ ÏŒÏ„Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± Î´Î¹Î±Î³ÏÎ¬ÏˆÎµÏ„Îµ Î±Ï…Ï„ÏŒ Ï„Î¿ wiki ÎºÎ±Î¹ ÏŒÎ»Î¿ Ï„Î¿ Ï€ÎµÏÎ¹ÎµÏ‡ÏŒÎ¼ÎµÎ½Î¿ Ï„Î¿Ï… ;
-  text_issue_category_destroy_question: "ÎšÎ¬Ï€Î¿Î¹Î± Î¸Î­Î¼Î±Ï„Î± (%{count}) Î­Ï‡Î¿Ï…Î½ ÎµÎºÏ‡Ï‰ÏÎ·Î¸ÎµÎ¯ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î·Î½ ÎºÎ±Ï„Î·Î³Î¿ÏÎ¯Î±. Î¤Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± ÎºÎ¬Î½ÎµÏ„Îµ ;"
-  text_issue_category_destroy_assignments: Î‘Ï†Î±Î¯ÏÎµÏƒÎ· ÎµÎºÏ‡Ï‰ÏÎ®ÏƒÎµÏ‰Î½ ÎºÎ±Ï„Î·Î³Î¿ÏÎ¯Î±Ï‚
-  text_issue_category_reassign_to: Î•Ï€Î±Î½ÎµÎºÏ‡ÏŽÏÎ·ÏƒÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î·Î½ ÎºÎ±Ï„Î·Î³Î¿ÏÎ¯Î±
-  text_user_mail_option: "Î“Î¹Î± Î¼Î· ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î± Î­ÏÎ³Î±, Î¸Î± Î»Î¬Î²ÎµÏ„Îµ ÎµÎ¹Î´Î¿Ï€Î¿Î¹Î®ÏƒÎµÎ¹Ï‚ Î¼ÏŒÎ½Î¿ Î³Î¹Î± Ï€ÏÎ¬Î³Î¼Î±Ï„Î± Ï€Î¿Ï… Ï€Î±ÏÎ±ÎºÎ¿Î»Î¿Ï…Î¸ÎµÎ¯Ï„Îµ Î® ÏƒÏ„Î± Î¿Ï€Î¿Î¯Î± ÏƒÏ…Î¼Î¼ÎµÏ„Î­Ï‡Ï‰ ÎµÎ½ÎµÏÎ³Î¬ (Ï€.Ï‡. Î¸Î­Î¼Î±Ï„Î± Ï„Ï‰Î½ Î¿Ï€Î¿Î¯Ï‰Î½ ÎµÎ¯ÏƒÏ„Îµ ÏƒÏ…Î³Î³ÏÎ±Ï†Î­Î±Ï‚ Î® ÏƒÎ±Ï‚ Î­Ï‡Î¿Ï…Î½ Î±Î½Î±Ï„ÎµÎ¸ÎµÎ¯)."
-  text_no_configuration_data: "ÎŸÎ¹ ÏÏŒÎ»Î¿Î¹, Î¿Î¹ Î±Î½Î¹Ï‡Î½ÎµÏ…Ï„Î­Ï‚, Î· ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ· Ï„Ï‰Î½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÎºÎ±Î¹ Î· ÏÎ¿Î® ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚ Î´ÎµÎ½ Î­Ï‡Î¿Ï…Î½ ÏÏ…Î¸Î¼Î¹ÏƒÏ„ÎµÎ¯ Î±ÎºÏŒÎ¼Î±.\nÎ£Ï…Î½Î¹ÏƒÏ„Î¬Ï„Î±Î¹ Î¹Î´Î¹Î±Î¯Ï„ÎµÏÎ± Î½Î± Ï†Î¿ÏÏ„ÏŽÏƒÎµÏ„Îµ Ï„Î¹Ï‚ Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½ÎµÏ‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚. Î˜Î± ÎµÎ¯ÏƒÏ„Îµ ÏƒÎµ Î¸Î­ÏƒÎ· Î½Î± Ï„Î¹Ï‚ Ï„ÏÎ¿Ï€Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Î¼ÎµÏ„Î¬ Ï„Î· Ï†ÏŒÏÏ„Ï‰ÏƒÎ· Ï„Î¿Ï…Ï‚."
-  text_load_default_configuration: Î¦ÏŒÏÏ„Ï‰ÏƒÎ· Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Ï‰Î½ ÏÏ…Î¸Î¼Î¯ÏƒÎµÏ‰Î½
-  text_status_changed_by_changeset: "Î•Ï†Î±ÏÎ¼ÏŒÏƒÏ„Î·ÎºÎµ ÏƒÏ„Î¿ changeset %{value}."
-  text_issues_destroy_confirmation: 'Î•Î¯ÏƒÏ„Îµ ÏƒÎ¯Î³Î¿Ï…ÏÎ¿Ï‚ ÏŒÏ„Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± Î´Î¹Î±Î³ÏÎ¬ÏˆÎµÏ„Îµ Ï„Î¿ ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î¿ Î¸Î­Î¼Î±(Ï„Î±);'
-  text_select_project_modules: 'Î•Ï€Î¹Î»Î­Î¾Ï„Îµ Ï€Î¿Î¹ÎµÏ‚ Î¼Î¿Î½Î¬Î´ÎµÏ‚ Î¸Î± ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Î³Î¹Î± Î±Ï…Ï„ÏŒ Ï„Î¿ Î­ÏÎ³Î¿:'
-  text_default_administrator_account_changed: ÎŸ Ï€ÏÎ¿ÎºÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼Î­Î½Î¿Ï‚ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ Ï„Î¿Ï… Î´Î¹Î±Ï‡ÎµÎ¹ÏÎ¹ÏƒÏ„Î® Î¬Î»Î»Î±Î¾Îµ
-  text_file_repository_writable: Î•Î³Î³ÏÎ¬ÏˆÎ¹Î¼Î¿Ï‚ ÎºÎ±Ï„Î¬Î»Î¿Î³Î¿Ï‚ ÏƒÏ…Î½Î·Î¼Î¼Î­Î½Ï‰Î½
-  text_plugin_assets_writable: Î•Î³Î³ÏÎ¬ÏˆÎ¹Î¼Î¿Ï‚ ÎºÎ±Ï„Î¬Î»Î¿Î³Î¿Ï‚ plugin assets
-  text_rmagick_available: Î”Î¹Î±Î¸Î­ÏƒÎ¹Î¼Î¿ RMagick (Ï€ÏÎ¿Î±Î¹ÏÎµÏ„Î¹ÎºÏŒ)
-  text_destroy_time_entries_question: "%{hours} Î´Î±Ï€Î±Î½Î®Î¸Î·ÎºÎ±Î½ ÏƒÏ‡ÎµÏ„Î¹ÎºÎ¬ Î¼Îµ Ï„Î± Î¸Î­Î¼Î±Ï„Î± Ï€Î¿Ï… Ï€ÏÏŒÎºÎµÎ¹Ï„Î±Î¹ Î½Î± Î´Î¹Î±Î³ÏÎ¬ÏˆÎµÏ„Îµ. Î¤Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± ÎºÎ¬Î½ÎµÏ„Îµ ;"
-  text_destroy_time_entries: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î±Î½Î±Ï†ÎµÏÏŒÎ¼ÎµÎ½Ï‰Î½ Ï‰ÏÏŽÎ½
-  text_assign_time_entries_to_project: Î‘Î½Î¬Î¸ÎµÏƒÎ· Î±Î½Î±Ï†ÎµÏÏŒÎ¼ÎµÎ½Ï‰Î½ Ï‰ÏÏŽÎ½ ÏƒÏ„Î¿ Î­ÏÎ³Î¿
-  text_reassign_time_entries: 'Î‘Î½Î¬Î¸ÎµÏƒÎ· ÎµÎº Î½Î­Î¿Ï… Ï„Ï‰Î½ Î±Î½Î±Ï†ÎµÏÏŒÎ¼ÎµÎ½Ï‰Î½ Ï‰ÏÏŽÎ½ ÏƒÏ„Î¿ Î¸Î­Î¼Î±:'
-  text_user_wrote: "%{value} Î­Î³ÏÎ±ÏˆÎµ:"
-  text_enumeration_destroy_question: "%{count} Î±Î½Ï„Î¹ÎºÎµÎ¯Î¼ÎµÎ½Î± Î­Ï‡Î¿Ï…Î½ Ï„ÎµÎ¸ÎµÎ¯ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î·Î½ Ï„Î¹Î¼Î®."
-  text_enumeration_category_reassign_to: 'Î•Ï€Î±Î½ÎµÎºÏ‡ÏŽÏÎ·ÏƒÎ· Ï„Î¿Ï…Ï‚ ÏƒÏ„Î·Î½ Ï€Î±ÏÎ¿ÏÏƒÎ± Î±Î¾Î¯Î±:'
-  text_email_delivery_not_configured: "Î”ÎµÎ½ Î­Ï‡Î¿Ï…Î½ Î³Î¯Î½ÎµÎ¹ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ Ï€Î±ÏÎ¬Î´Î¿ÏƒÎ·Ï‚ email, ÎºÎ±Î¹ Î¿Î¹ ÎµÎ¹Î´Î¿Ï€Î¿Î¹Î®ÏƒÎµÎ¹Ï‚ ÎµÎ¯Î½Î±Î¹ Î±Ï€ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î·Î¼Î­Î½ÎµÏ‚.\nÎ”Î·Î»ÏŽÏƒÏ„Îµ Ï„Î¿Î½ ÎµÎ¾Ï…Ï€Î·ÏÎµÏ„Î·Ï„Î® SMTP ÏƒÏ„Î¿ config/configuration.yml ÎºÎ±Î¹ ÎºÎ¬Î½Ï„Îµ ÎµÏ€Î±Î½Î±ÎºÎºÎ¯Î½Î·ÏƒÎ· Ï„Î·Î½ ÎµÏ†Î±ÏÎ¼Î¿Î³Î® Î³Î¹Î± Î½Î± Ï„Î¹Ï‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚."
-  text_repository_usernames_mapping: "Î•Ï€Î¹Î»Î­Î¾Ï„Îµ Î® ÎµÎ½Î·Î¼ÎµÏÏŽÏƒÏ„Îµ Ï„Î¿Î½ Ï‡ÏÎ®ÏƒÏ„Î· Redmine Ï€Î¿Ï… Î±Î½Ï„Î¹ÏƒÏ„Î¿Î¹Ï‡ÎµÎ¯ ÏƒÎµ ÎºÎ¬Î¸Îµ ÏŒÎ½Î¿Î¼Î± Ï‡ÏÎ®ÏƒÏ„Î·  ÏƒÏ„Î¿ Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ Ï„Î¿Ï… Î±Ï€Î¿Î¸ÎµÏ„Î·ÏÎ¯Î¿Ï….\nÎ§ÏÎ®ÏƒÏ„ÎµÏ‚ Î¼Îµ Ï„Î¿ Î¯Î´Î¹Î¿ ÏŒÎ½Î¿Î¼Î± Ï‡ÏÎ®ÏƒÏ„Î· Î® email ÏƒÏ„Î¿ Redmine ÎºÎ±Î¹ ÏƒÏ„Î¿ Î±Ï€Î¿Î¸ÎµÏ„Î·ÏÎ¯Î¿ Î±Î½Ï„Î¹ÏƒÏ„Î¿Î¹Ï‡Î¯Î¶Î¿Î½Ï„Î±Î¹ Î±Ï…Ï„ÏŒÎ¼Î±Ï„Î±."
-  text_diff_truncated: '... Î‘Ï…Ï„ÏŒ Ï„Î¿ diff ÎµÏ‡ÎµÎ¯ ÎºÎ¿Ï€ÎµÎ¯ ÎµÏ€ÎµÎ¹Î´Î® Ï…Ï€ÎµÏÎ²Î±Î¯Î½ÎµÎ¹ Ï„Î¿ Î¼Î­Î³Î¹ÏƒÏ„Î¿ Î¼Î­Î³ÎµÎ¸Î¿Ï‚ Ï€Î¿Ï… Î¼Ï€Î¿ÏÎµÎ¯ Î½Î± Ï€ÏÎ¿Î²Î»Î·Î¸ÎµÎ¯.'
-  text_custom_field_possible_values_info: 'ÎœÎ¯Î± Î³ÏÎ±Î¼Î¼Î® Î³Î¹Î± ÎºÎ¬Î¸Îµ Ï„Î¹Î¼Î®'
-  text_wiki_page_destroy_question: "Î‘Ï…Ï„Î® Î· ÏƒÎµÎ»Î¯Î´Î± Î­Ï‡ÎµÎ¹ %{descendants} ÏƒÎµÎ»Î¯Î´ÎµÏ‚ Ï„Î­ÎºÎ½Ï‰Î½ ÎºÎ±Î¹ Î±Ï€Î¿Î³ÏŒÎ½Ï‰Î½. Î¤Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± ÎºÎ¬Î½ÎµÏ„Îµ ;"
-  text_wiki_page_nullify_children: "Î”Î¹Î±Ï„Î·ÏÎ®ÏƒÏ„Îµ Ï„Î¹Ï‚ ÏƒÎµÎ»Î¯Î´ÎµÏ‚ Ï„Î­ÎºÎ½Ï‰Î½ Ï‰Ï‚ ÏƒÎµÎ»Î¯Î´ÎµÏ‚ root"
-  text_wiki_page_destroy_children: "Î”Î¹Î±Î³ÏÎ¬ÏˆÏ„Îµ ÏŒÎ»ÎµÏ‚ Ï„Î¹Ï‚ ÏƒÎµÎ»Î¯Î´ÎµÏ‚ Ï„Î­ÎºÎ½Ï‰Î½ ÎºÎ±Î¹ Ï„Ï‰Î½ Î±Ï€Î¿Î³ÏŒÎ½Ï‰Î½ Ï„Î¿Ï…Ï‚"
-  text_wiki_page_reassign_children: "Î•Ï€Î±Î½ÎµÎºÏ‡ÏŽÏÎ¹ÏƒÎ· Ï„Ï‰Î½ ÏƒÎµÎ»Î¯Î´Ï‰Î½ Ï„Î­ÎºÎ½Ï‰Î½ ÏƒÏ„Î· Î³Î¿Î½Î¹ÎºÎ® ÏƒÎµÎ»Î¯Î´Î±"
-  
-  default_role_manager: Manager
-  default_role_developer: Developer
-  default_role_reporter: Reporter
-  default_tracker_bug: Î£Ï†Î¬Î»Î¼Î±Ï„Î±
-  default_tracker_feature: Î›ÎµÎ¹Ï„Î¿Ï…ÏÎ³Î¯ÎµÏ‚
-  default_tracker_support: Î¥Ï€Î¿ÏƒÏ„Î®ÏÎ¹Î¾Î·
-  default_issue_status_new: ÎÎ­Î±
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: Î•Ï€Î¹Î»Ï…Î¼Î­Î½Î¿
-  default_issue_status_feedback: Î£Ï‡ÏŒÎ»Î¹Î±
-  default_issue_status_closed: ÎšÎ»ÎµÎ¹ÏƒÏ„ÏŒ
-  default_issue_status_rejected: Î‘Ï€Î¿ÏÏÎ¹Ï€Ï„Î­Î¿
-  default_doc_category_user: Î¤ÎµÎºÎ¼Î·ÏÎ¯Ï‰ÏƒÎ· Ï‡ÏÎ®ÏƒÏ„Î·
-  default_doc_category_tech: Î¤ÎµÏ‡Î½Î¹ÎºÎ® Ï„ÎµÎºÎ¼Î·ÏÎ¯Ï‰ÏƒÎ·
-  default_priority_low: Î§Î±Î¼Î·Î»Î®
-  default_priority_normal: ÎšÎ±Î½Î¿Î½Î¹ÎºÎ®
-  default_priority_high: Î¥ÏˆÎ·Î»Î®
-  default_priority_urgent: Î•Ï€ÎµÎ¯Î³Î¿Î½
-  default_priority_immediate: Î†Î¼ÎµÏƒÎ·
-  default_activity_design: Î£Ï‡ÎµÎ´Î¹Î±ÏƒÎ¼ÏŒÏ‚
-  default_activity_development: Î‘Î½Î¬Ï€Ï„Ï…Î¾Î·
-  
-  enumeration_issue_priorities: Î ÏÎ¿Ï„ÎµÏÎ±Î¹ÏŒÏ„Î·Ï„Î± Î¸Î­Î¼Î±Ï„Î¿Ï‚
-  enumeration_doc_categories: ÎšÎ±Ï„Î·Î³Î¿ÏÎ¯Î± ÎµÎ³Î³ÏÎ¬Ï†Ï‰Î½
-  enumeration_activities: Î”ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„ÎµÏ‚ (ÎºÎ±Ï„Î±ÎºÎµÏÎ¼Î±Ï„Î¹ÏƒÎ¼ÏŒÏ‚ Ï‡ÏÏŒÎ½Î¿Ï…)
-  text_journal_changed: "%{label} Î¬Î»Î»Î±Î¾Îµ Î±Ï€ÏŒ %{old} ÏƒÎµ %{new}"
-  text_journal_set_to: "%{label} Î¿ÏÎ¯Î¶ÎµÏ„Î±Î¹ ÏƒÎµ %{value}"
-  text_journal_deleted: "%{label} Î´Î¹Î±Î³ÏÎ¬Ï†Î·ÎºÎµ (%{old})"
-  label_group_plural: ÎŸÎ¼Î¬Î´ÎµÏ‚
-  label_group: ÎŸÎ¼Î¬Î´Î±
-  label_group_new: ÎÎ­Î± Î¿Î¼Î¬Î´Î±
-  label_time_entry_plural: Î§ÏÏŒÎ½Î¿Ï‚ Ï€Î¿Ï… Î´Î±Ï€Î±Î½Î®Î¸Î·ÎºÎµ
-  text_journal_added: "%{label} %{value} added"
-  field_active: Active
-  enumeration_system_activity: System Activity
-  permission_delete_issue_watchers: Delete watchers
-  version_status_closed: closed
-  version_status_locked: locked
-  version_status_open: open
-  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
-  label_user_anonymous: Anonymous
-  button_move_and_follow: Move and follow
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_gravatar_default: Default Gravatar image
-  field_sharing: Sharing
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_system: With all projects
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_tree: With project tree
-  label_version_sharing_none: Not shared
-  error_can_not_archive_project: This project can not be archived
-  button_duplicate: Duplicate
-  button_copy_and_follow: Copy and follow
-  label_copy_source: Source
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Same as target
-  label_copy_target: Target
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  error_workflow_copy_source: Please select a source tracker or role
-  label_update_issue_done_ratios: Update issue done ratios
-  setting_start_of_week: Start calendars on
-  permission_view_issues: View Issues
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API access key
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_missing_api_access_key: Missing an API access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  button_show: Show
-  text_line_separated: Multiple values allowed (one line for each value).
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: ÎšÏ‰Î´Î¹ÎºÎ¿Ï€Î¿Î¯Î·ÏƒÎ· Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½ commit
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/53/53e7bfd13c1bbfd84e32b60344b616bb91f37951.svn-base
--- a/.svn/pristine/53/53e7bfd13c1bbfd84e32b60344b616bb91f37951.svn-base
+++ /dev/null
@@ -1,401 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class MailHandler < ActionMailer::Base
-  include ActionView::Helpers::SanitizeHelper
-  include Redmine::I18n
-
-  class UnauthorizedAction < StandardError; end
-  class MissingInformation < StandardError; end
-
-  attr_reader :email, :user
-
-  def self.receive(email, options={})
-    @@handler_options = options.dup
-
-    @@handler_options[:issue] ||= {}
-
-    @@handler_options[:allow_override] = @@handler_options[:allow_override].split(',').collect(&:strip) if @@handler_options[:allow_override].is_a?(String)
-    @@handler_options[:allow_override] ||= []
-    # Project needs to be overridable if not specified
-    @@handler_options[:allow_override] << 'project' unless @@handler_options[:issue].has_key?(:project)
-    # Status overridable by default
-    @@handler_options[:allow_override] << 'status' unless @@handler_options[:issue].has_key?(:status)
-
-    @@handler_options[:no_permission_check] = (@@handler_options[:no_permission_check].to_s == '1' ? true : false)
-    super email
-  end
-
-  # Processes incoming emails
-  # Returns the created object (eg. an issue, a message) or false
-  def receive(email)
-    @email = email
-    sender_email = email.from.to_a.first.to_s.strip
-    # Ignore emails received from the application emission address to avoid hell cycles
-    if sender_email.downcase == Setting.mail_from.to_s.strip.downcase
-      logger.info  "MailHandler: ignoring email from Redmine emission address [#{sender_email}]" if logger && logger.info
-      return false
-    end
-    @user = User.find_by_mail(sender_email) if sender_email.present?
-    if @user && !@user.active?
-      logger.info  "MailHandler: ignoring email from non-active user [#{@user.login}]" if logger && logger.info
-      return false
-    end
-    if @user.nil?
-      # Email was submitted by an unknown user
-      case @@handler_options[:unknown_user]
-      when 'accept'
-        @user = User.anonymous
-      when 'create'
-        @user = create_user_from_email(email)
-        if @user
-          logger.info "MailHandler: [#{@user.login}] account created" if logger && logger.info
-          Mailer.deliver_account_information(@user, @user.password)
-        else
-          logger.error "MailHandler: could not create account for [#{sender_email}]" if logger && logger.error
-          return false
-        end
-      else
-        # Default behaviour, emails from unknown users are ignored
-        logger.info  "MailHandler: ignoring email from unknown user [#{sender_email}]" if logger && logger.info
-        return false
-      end
-    end
-    User.current = @user
-    dispatch
-  end
-
-  private
-
-  MESSAGE_ID_RE = %r{^<redmine\.([a-z0-9_]+)\-(\d+)\.\d+@}
-  ISSUE_REPLY_SUBJECT_RE = %r{\[[^\]]*#(\d+)\]}
-  MESSAGE_REPLY_SUBJECT_RE = %r{\[[^\]]*msg(\d+)\]}
-
-  def dispatch
-    headers = [email.in_reply_to, email.references].flatten.compact
-    if headers.detect {|h| h.to_s =~ MESSAGE_ID_RE}
-      klass, object_id = $1, $2.to_i
-      method_name = "receive_#{klass}_reply"
-      if self.class.private_instance_methods.collect(&:to_s).include?(method_name)
-        send method_name, object_id
-      else
-        # ignoring it
-      end
-    elsif m = email.subject.match(ISSUE_REPLY_SUBJECT_RE)
-      receive_issue_reply(m[1].to_i)
-    elsif m = email.subject.match(MESSAGE_REPLY_SUBJECT_RE)
-      receive_message_reply(m[1].to_i)
-    else
-      dispatch_to_default
-    end
-  rescue ActiveRecord::RecordInvalid => e
-    # TODO: send a email to the user
-    logger.error e.message if logger
-    false
-  rescue MissingInformation => e
-    logger.error "MailHandler: missing information from #{user}: #{e.message}" if logger
-    false
-  rescue UnauthorizedAction => e
-    logger.error "MailHandler: unauthorized attempt from #{user}" if logger
-    false
-  end
-
-  def dispatch_to_default
-    receive_issue
-  end
-
-  # Creates a new issue
-  def receive_issue
-    project = target_project
-    # check permission
-    unless @@handler_options[:no_permission_check]
-      raise UnauthorizedAction unless user.allowed_to?(:add_issues, project)
-    end
-
-    issue = Issue.new(:author => user, :project => project)
-    issue.safe_attributes = issue_attributes_from_keywords(issue)
-    issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)}
-    issue.subject = email.subject.to_s.chomp[0,255]
-    if issue.subject.blank?
-      issue.subject = '(no subject)'
-    end
-    issue.description = cleaned_up_text_body
-
-    # add To and Cc as watchers before saving so the watchers can reply to Redmine
-    add_watchers(issue)
-    issue.save!
-    add_attachments(issue)
-    logger.info "MailHandler: issue ##{issue.id} created by #{user}" if logger && logger.info
-    issue
-  end
-
-  # Adds a note to an existing issue
-  def receive_issue_reply(issue_id)
-    issue = Issue.find_by_id(issue_id)
-    return unless issue
-    # check permission
-    unless @@handler_options[:no_permission_check]
-      raise UnauthorizedAction unless user.allowed_to?(:add_issue_notes, issue.project) || user.allowed_to?(:edit_issues, issue.project)
-    end
-
-    # ignore CLI-supplied defaults for new issues
-    @@handler_options[:issue].clear
-
-    journal = issue.init_journal(user)
-    issue.safe_attributes = issue_attributes_from_keywords(issue)
-    issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)}
-    journal.notes = cleaned_up_text_body
-    add_attachments(issue)
-    issue.save!
-    logger.info "MailHandler: issue ##{issue.id} updated by #{user}" if logger && logger.info
-    journal
-  end
-
-  # Reply will be added to the issue
-  def receive_journal_reply(journal_id)
-    journal = Journal.find_by_id(journal_id)
-    if journal && journal.journalized_type == 'Issue'
-      receive_issue_reply(journal.journalized_id)
-    end
-  end
-
-  # Receives a reply to a forum message
-  def receive_message_reply(message_id)
-    message = Message.find_by_id(message_id)
-    if message
-      message = message.root
-
-      unless @@handler_options[:no_permission_check]
-        raise UnauthorizedAction unless user.allowed_to?(:add_messages, message.project)
-      end
-
-      if !message.locked?
-        reply = Message.new(:subject => email.subject.gsub(%r{^.*msg\d+\]}, '').strip,
-                            :content => cleaned_up_text_body)
-        reply.author = user
-        reply.board = message.board
-        message.children << reply
-        add_attachments(reply)
-        reply
-      else
-        logger.info "MailHandler: ignoring reply from [#{sender_email}] to a locked topic" if logger && logger.info
-      end
-    end
-  end
-
-  def add_attachments(obj)
-    if email.attachments && email.attachments.any?
-      email.attachments.each do |attachment|
-        obj.attachments << Attachment.create(:container => obj,
-                          :file => attachment,
-                          :author => user,
-                          :content_type => attachment.content_type)
-      end
-    end
-  end
-
-  # Adds To and Cc as watchers of the given object if the sender has the
-  # appropriate permission
-  def add_watchers(obj)
-    if user.allowed_to?("add_#{obj.class.name.underscore}_watchers".to_sym, obj.project)
-      addresses = [email.to, email.cc].flatten.compact.uniq.collect {|a| a.strip.downcase}
-      unless addresses.empty?
-        watchers = User.active.find(:all, :conditions => ['LOWER(mail) IN (?)', addresses])
-        watchers.each {|w| obj.add_watcher(w)}
-      end
-    end
-  end
-
-  def get_keyword(attr, options={})
-    @keywords ||= {}
-    if @keywords.has_key?(attr)
-      @keywords[attr]
-    else
-      @keywords[attr] = begin
-        if (options[:override] || @@handler_options[:allow_override].include?(attr.to_s)) && (v = extract_keyword!(plain_text_body, attr, options[:format]))
-          v
-        elsif !@@handler_options[:issue][attr].blank?
-          @@handler_options[:issue][attr]
-        end
-      end
-    end
-  end
-
-  # Destructively extracts the value for +attr+ in +text+
-  # Returns nil if no matching keyword found
-  def extract_keyword!(text, attr, format=nil)
-    keys = [attr.to_s.humanize]
-    if attr.is_a?(Symbol)
-      keys << l("field_#{attr}", :default => '', :locale =>  user.language) if user && user.language.present?
-      keys << l("field_#{attr}", :default => '', :locale =>  Setting.default_language) if Setting.default_language.present?
-    end
-    keys.reject! {|k| k.blank?}
-    keys.collect! {|k| Regexp.escape(k)}
-    format ||= '.+'
-    text.gsub!(/^(#{keys.join('|')})[ \t]*:[ \t]*(#{format})\s*$/i, '')
-    $2 && $2.strip
-  end
-
-  def target_project
-    # TODO: other ways to specify project:
-    # * parse the email To field
-    # * specific project (eg. Setting.mail_handler_target_project)
-    target = Project.find_by_identifier(get_keyword(:project))
-    raise MissingInformation.new('Unable to determine target project') if target.nil?
-    target
-  end
-
-  # Returns a Hash of issue attributes extracted from keywords in the email body
-  def issue_attributes_from_keywords(issue)
-    assigned_to = (k = get_keyword(:assigned_to, :override => true)) && find_assignee_from_keyword(k, issue)
-
-    attrs = {
-      'tracker_id' => (k = get_keyword(:tracker)) && issue.project.trackers.named(k).first.try(:id),
-      'status_id' =>  (k = get_keyword(:status)) && IssueStatus.named(k).first.try(:id),
-      'priority_id' => (k = get_keyword(:priority)) && IssuePriority.named(k).first.try(:id),
-      'category_id' => (k = get_keyword(:category)) && issue.project.issue_categories.named(k).first.try(:id),
-      'assigned_to_id' => assigned_to.try(:id),
-      'fixed_version_id' => (k = get_keyword(:fixed_version, :override => true)) && issue.project.shared_versions.named(k).first.try(:id),
-      'start_date' => get_keyword(:start_date, :override => true, :format => '\d{4}-\d{2}-\d{2}'),
-      'due_date' => get_keyword(:due_date, :override => true, :format => '\d{4}-\d{2}-\d{2}'),
-      'estimated_hours' => get_keyword(:estimated_hours, :override => true),
-      'done_ratio' => get_keyword(:done_ratio, :override => true, :format => '(\d|10)?0')
-    }.delete_if {|k, v| v.blank? }
-
-    if issue.new_record? && attrs['tracker_id'].nil?
-      attrs['tracker_id'] = issue.project.trackers.find(:first).try(:id)
-    end
-
-    attrs
-  end
-
-  # Returns a Hash of issue custom field values extracted from keywords in the email body
-  def custom_field_values_from_keywords(customized)
-    customized.custom_field_values.inject({}) do |h, v|
-      if value = get_keyword(v.custom_field.name, :override => true)
-        h[v.custom_field.id.to_s] = value
-      end
-      h
-    end
-  end
-
-  # Returns the text/plain part of the email
-  # If not found (eg. HTML-only email), returns the body with tags removed
-  def plain_text_body
-    return @plain_text_body unless @plain_text_body.nil?
-    parts = @email.parts.collect {|c| (c.respond_to?(:parts) && !c.parts.empty?) ? c.parts : c}.flatten
-    if parts.empty?
-      parts << @email
-    end
-    plain_text_part = parts.detect {|p| p.content_type == 'text/plain'}
-    if plain_text_part.nil?
-      # no text/plain part found, assuming html-only email
-      # strip html tags and remove doctype directive
-      @plain_text_body = strip_tags(@email.body.to_s)
-      @plain_text_body.gsub! %r{^<!DOCTYPE .*$}, ''
-    else
-      @plain_text_body = plain_text_part.body.to_s
-    end
-    @plain_text_body.strip!
-    @plain_text_body
-  end
-
-  def cleaned_up_text_body
-    cleanup_body(plain_text_body)
-  end
-
-  def self.full_sanitizer
-    @full_sanitizer ||= HTML::FullSanitizer.new
-  end
-
-  def self.assign_string_attribute_with_limit(object, attribute, value)
-    limit = object.class.columns_hash[attribute.to_s].limit || 255
-    value = value.to_s.slice(0, limit)
-    object.send("#{attribute}=", value)
-  end
-
-  # Returns a User from an email address and a full name
-  def self.new_user_from_attributes(email_address, fullname=nil)
-    user = User.new
-
-    # Truncating the email address would result in an invalid format
-    user.mail = email_address
-    assign_string_attribute_with_limit(user, 'login', email_address)
-
-    names = fullname.blank? ? email_address.gsub(/@.*$/, '').split('.') : fullname.split
-    assign_string_attribute_with_limit(user, 'firstname', names.shift)
-    assign_string_attribute_with_limit(user, 'lastname', names.join(' '))
-    user.lastname = '-' if user.lastname.blank?
-
-    password_length = [Setting.password_min_length.to_i, 10].max
-    user.password = ActiveSupport::SecureRandom.hex(password_length / 2 + 1)
-    user.language = Setting.default_language
-
-    unless user.valid?
-      user.login = "user#{ActiveSupport::SecureRandom.hex(6)}" if user.errors.on(:login)
-      user.firstname = "-" if user.errors.on(:firstname)
-      user.lastname = "-" if user.errors.on(:lastname)
-    end
-
-    user
-  end
-
-  # Creates a User for the +email+ sender
-  # Returns the user or nil if it could not be created
-  def create_user_from_email(email)
-    addr = email.from_addrs.to_a.first
-    if addr && !addr.spec.blank?
-      user = self.class.new_user_from_attributes(addr.spec, addr.name)
-      if user.save
-        user
-      else
-        logger.error "MailHandler: failed to create User: #{user.errors.full_messages}" if logger
-        nil
-      end
-    else
-      logger.error "MailHandler: failed to create User: no FROM address found" if logger
-      nil
-    end
-  end
-
-  private
-
-  # Removes the email body of text after the truncation configurations.
-  def cleanup_body(body)
-    delimiters = Setting.mail_handler_body_delimiters.to_s.split(/[\r\n]+/).reject(&:blank?).map {|s| Regexp.escape(s)}
-    unless delimiters.empty?
-      regex = Regexp.new("^[> ]*(#{ delimiters.join('|') })\s*[\r\n].*", Regexp::MULTILINE)
-      body = body.gsub(regex, '')
-    end
-    body.strip
-  end
-
-  def find_assignee_from_keyword(keyword, issue)
-    keyword = keyword.to_s.downcase
-    assignable = issue.assignable_users
-    assignee = nil
-    assignee ||= assignable.detect {|a| a.mail.to_s.downcase == keyword || a.login.to_s.downcase == keyword}
-    if assignee.nil? && keyword.match(/ /)
-      firstname, lastname = *(keyword.split) # "First Last Throwaway"
-      assignee ||= assignable.detect {|a| a.is_a?(User) && a.firstname.to_s.downcase == firstname && a.lastname.to_s.downcase == lastname}
-    end
-    if assignee.nil?
-      assignee ||= assignable.detect {|a| a.is_a?(Group) && a.name.downcase == keyword}
-    end
-    assignee
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/53/53f766f688d3e6af398e819fa2270ab5c1d44704.svn-base
--- a/.svn/pristine/53/53f766f688d3e6af398e819fa2270ab5c1d44704.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= TestHelper.view_path_for __FILE__ %> (from alpha_plugin)
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/54/5417555cbbf2ff6b51352d6d03cb030a8f16ca7e.svn-base
--- a/.svn/pristine/54/5417555cbbf2ff6b51352d6d03cb030a8f16ca7e.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class WelcomeController < ApplicationController
-  caches_action :robots
-
-  def index
-    @news = News.latest User.current
-    @projects = Project.latest User.current
-  end
-
-  def robots
-    @projects = Project.all_public.active
-    render :layout => false, :content_type => 'text/plain'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/54/543c086fba1141b0a1920a3d969a31cde9c83e3e.svn-base
--- /dev/null
+++ b/.svn/pristine/54/543c086fba1141b0a1920a3d969a31cde9c83e3e.svn-base
@@ -0,0 +1,99 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../../test_helper', __FILE__)
+begin
+  require 'mocha'
+
+  class CvsAdapterTest < ActiveSupport::TestCase
+    REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s
+    REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
+    MODULE_NAME = 'test'
+
+    if File.directory?(REPOSITORY_PATH)
+      def setup
+        @adapter = Redmine::Scm::Adapters::CvsAdapter.new(MODULE_NAME, REPOSITORY_PATH)
+      end
+
+      def test_scm_version
+        to_test = { "\nConcurrent Versions System (CVS) 1.12.13 (client/server)\n"  => [1,12,13],
+                    "\r\n1.12.12\r\n1.12.11"                   => [1,12,12],
+                    "1.12.11\r\n1.12.10\r\n"                   => [1,12,11]}
+        to_test.each do |s, v|
+          test_scm_version_for(s, v)
+        end
+      end
+
+      def test_revisions_all
+        cnt = 0
+        @adapter.revisions('', nil, nil, :log_encoding => 'UTF-8') do |revision|
+          cnt += 1
+        end
+        assert_equal 16, cnt
+      end
+
+      def test_revisions_from_rev3
+        rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
+        cnt = 0
+        @adapter.revisions('', rev3_committed_on, nil, :log_encoding => 'UTF-8') do |revision|
+          cnt += 1
+        end
+        assert_equal 4, cnt
+      end
+
+      def test_entries_rev3
+        rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
+        entries = @adapter.entries('sources', rev3_committed_on)
+        assert_equal 2, entries.size
+        assert_equal entries[0].name, "watchers_controller.rb"
+        assert_equal entries[0].lastrev.time, Time.gm(2007, 12, 13, 16, 27, 22)
+      end
+
+      def test_path_encoding_default_utf8
+        adpt1 = Redmine::Scm::Adapters::CvsAdapter.new(
+                                  MODULE_NAME,
+                                  REPOSITORY_PATH
+                                )
+        assert_equal "UTF-8", adpt1.path_encoding
+        adpt2 = Redmine::Scm::Adapters::CvsAdapter.new(
+                                  MODULE_NAME,
+                                  REPOSITORY_PATH,
+                                  nil,
+                                  nil,
+                                  ""
+                                )
+        assert_equal "UTF-8", adpt2.path_encoding
+      end
+
+      private
+
+      def test_scm_version_for(scm_command_version, version)
+        @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
+        assert_equal version, @adapter.class.scm_command_version
+      end
+    else
+      puts "Cvs test repository NOT FOUND. Skipping unit tests !!!"
+      def test_fake; assert true end
+    end
+  end
+
+rescue LoadError
+  class CvsMochaFake < ActiveSupport::TestCase
+    def test_fake; assert(false, "Requires mocha to run those tests")  end
+  end
+end
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/54/545555b790077e8ce0b627745954990d978f492e.svn-base
--- /dev/null
+++ b/.svn/pristine/54/545555b790077e8ce0b627745954990d978f492e.svn-base
@@ -0,0 +1,43 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class EnabledModuleTest < ActiveSupport::TestCase
+  fixtures :projects, :wikis
+
+  def test_enabling_wiki_should_create_a_wiki
+    CustomField.delete_all
+    project = Project.create!(:name => 'Project with wiki', :identifier => 'wikiproject')
+    assert_nil project.wiki
+    project.enabled_module_names = ['wiki']
+    project.reload
+    assert_not_nil project.wiki
+    assert_equal 'Wiki', project.wiki.start_page
+  end
+
+  def test_reenabling_wiki_should_not_create_another_wiki
+    project = Project.find(1)
+    assert_not_nil project.wiki
+    project.enabled_module_names = []
+    project.reload
+    assert_no_difference 'Wiki.count' do
+      project.enabled_module_names = ['wiki']
+    end
+    assert_not_nil project.wiki
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/54/54759b2876d30caf9b91631c76f57195d0fdce73.svn-base
--- a/.svn/pristine/54/54759b2876d30caf9b91631c76f57195d0fdce73.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-<%= error_messages_for 'role' %>
-
-<div class="box">
-<% unless @role.builtin? %>
-<p><%= f.text_field :name, :required => true %></p>
-<p><%= f.check_box :assignable %></p>
-<% end %>
-<p><%= f.select :issues_visibility, Role::ISSUES_VISIBILITY_OPTIONS.collect {|v| [l(v.last), v.first]} %></p>
-<% if @role.new_record? && @roles.any? %>
-<p><label for="copy_workflow_from"><%= l(:label_copy_workflow_from) %></label>
-<%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@roles, :id, :name)) %></p>
-<% end %>
-</div>
-
-<h3><%= l(:label_permissions) %></h3>
-<div class="box" id="permissions">
-<% perms_by_module = @permissions.group_by {|p| p.project_module.to_s} %>
-<% perms_by_module.keys.sort.each do |mod| %>
-    <fieldset><legend><%= mod.blank? ? l(:label_project) : l_or_humanize(mod, :prefix => 'project_module_') %></legend>
-    <% perms_by_module[mod].each do |permission| %>
-        <label class="floating">
-        <%= check_box_tag 'role[permissions][]', permission.name, (@role.permissions.include? permission.name) %>
-        <%= l_or_humanize(permission.name, :prefix => 'permission_') %>
-        </label>
-    <% end %>
-    </fieldset>
-<% end %>
-<br /><%= check_all_links 'permissions' %>
-<%= hidden_field_tag 'role[permissions][]', '' %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/54/549732f3fd96b4524d8aa62cc5177f9b0ad9d268.svn-base
--- a/.svn/pristine/54/549732f3fd96b4524d8aa62cc5177f9b0ad9d268.svn-base
+++ /dev/null
@@ -1,47 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class SearchHelperTest < ActionView::TestCase
-  include SearchHelper
-
-  def test_highlight_single_token
-    assert_equal 'This is a <span class="highlight token-0">token</span>.',
-                 highlight_tokens('This is a token.', %w(token))
-  end
-
-  def test_highlight_multiple_tokens
-    assert_equal 'This is a <span class="highlight token-0">token</span> and <span class="highlight token-1">another</span> <span class="highlight token-0">token</span>.',
-                 highlight_tokens('This is a token and another token.', %w(token another))
-  end
-
-  def test_highlight_should_not_exceed_maximum_length
-    s = (('1234567890' * 100) + ' token ') * 100
-    r = highlight_tokens(s, %w(token))
-    assert r.include?('<span class="highlight token-0">token</span>')
-    assert r.length <= 1300
-  end
-
-  def test_highlight_multibyte
-    s = ('Ð¹' * 200) + ' token ' + ('Ð¹' * 200)
-    r = highlight_tokens(s, %w(token))
-    assert_equal  ('Ð¹' * 45) + ' ... ' + ('Ð¹' * 44) + ' <span class="highlight token-0">token</span> ' + ('Ð¹' * 44) + ' ... ' + ('Ð¹' * 45), r
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/54/549c0979db66eee16f159587f161c81dea52c794.svn-base
--- a/.svn/pristine/54/549c0979db66eee16f159587f161c81dea52c794.svn-base
+++ /dev/null
@@ -1,28 +0,0 @@
-<h2><%= l(:label_revision) %> <%= @diff_format_revisions %> <%=h @path %></h2>
-
-<!-- Choose view type -->
-<% form_tag({:path => to_path_param(@path)}, :method => 'get') do %>
-  <%= hidden_field_tag('rev', params[:rev]) if params[:rev] %>
-  <%= hidden_field_tag('rev_to', params[:rev_to]) if params[:rev_to] %>
-  <p>
-    <label><%= l(:label_view_diff) %></label>
-    <%= select_tag 'type',
-                    options_for_select(
-                      [[l(:label_diff_inline), "inline"], [l(:label_diff_side_by_side), "sbs"]], @diff_type),
-                    :onchange => "if (this.value != '') {this.form.submit()}" %>
-  </p>
-<% end %>
-
-<% cache(@cache_key) do -%>
-<%= render :partial => 'common/diff', :locals => {:diff => @diff, :diff_type => @diff_type} %>
-<% end -%>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Diff', :url => params, :caption => 'Unified diff' %>
-<% end %>
-
-<% html_title(with_leading_slash(@path), 'Diff') -%>
-
-<% content_for :header_tags do %>
-<%= stylesheet_link_tag "scm" %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/54/54aaade6975dce4afcd932f697233c2ac56da5c0.svn-base
--- a/.svn/pristine/54/54aaade6975dce4afcd932f697233c2ac56da5c0.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class SharedPluginController < ApplicationController
-  def an_action
-    render_class_and_action 'from beta_plugin'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/550aea64d9d567b8fd19eb6154f19d0a52250270.svn-base
--- a/.svn/pristine/55/550aea64d9d567b8fd19eb6154f19d0a52250270.svn-base
+++ /dev/null
@@ -1,205 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-# Copyright (C) 2007  Patrick Aljord patcito@Å‹mail.com
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/git_adapter'
-
-class Repository::Git < Repository
-  attr_protected :root_url
-  validates_presence_of :url
-
-  def self.human_attribute_name(attribute_key_name)
-    attr_name = attribute_key_name
-    if attr_name == "url"
-      attr_name = "path_to_repository"
-    end
-    super(attr_name)
-  end
-
-  def self.scm_adapter_class
-    Redmine::Scm::Adapters::GitAdapter
-  end
-
-  def self.scm_name
-    'Git'
-  end
-
-  def report_last_commit
-    extra_report_last_commit
-  end
-
-  def extra_report_last_commit
-    return false if extra_info.nil?
-    v = extra_info["extra_report_last_commit"]
-    return false if v.nil?
-    v.to_s != '0'
-  end
-
-  def supports_directory_revisions?
-    true
-  end
-
-  def supports_revision_graph?
-    true
-  end
-
-  def repo_log_encoding
-    'UTF-8'
-  end
-
-  # Returns the identifier for the given git changeset
-  def self.changeset_identifier(changeset)
-    changeset.scmid
-  end
-
-  # Returns the readable identifier for the given git changeset
-  def self.format_changeset_identifier(changeset)
-    changeset.revision[0, 8]
-  end
-
-  def branches
-    scm.branches
-  end
-
-  def tags
-    scm.tags
-  end
-
-  def default_branch
-    scm.default_branch
-  rescue Exception => e
-    logger.error "git: error during get default branch: #{e.message}"
-    nil
-  end
-
-  def find_changeset_by_name(name)
-    return nil if name.nil? || name.empty?
-    e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
-    return e if e
-    changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
-  end
-
-  def entries(path=nil, identifier=nil)
-    scm.entries(path,
-                identifier,
-                options = {:report_last_commit => extra_report_last_commit})
-  end
-
-  # With SCMs that have a sequential commit numbering,
-  # such as Subversion and Mercurial,
-  # Redmine is able to be clever and only fetch changesets
-  # going forward from the most recent one it knows about.
-  # 
-  # However, Git does not have a sequential commit numbering.
-  #
-  # In order to fetch only new adding revisions,
-  # Redmine needs to parse revisions per branch.
-  # Branch "last_scmid" is for this requirement.
-  #
-  # In Git and Mercurial, revisions are not in date order.
-  # Redmine Mercurial fixed issues.
-  #    * Redmine Takes Too Long On Large Mercurial Repository
-  #      http://www.redmine.org/issues/3449
-  #    * Sorting for changesets might go wrong on Mercurial repos
-  #      http://www.redmine.org/issues/3567
-  #
-  # Database revision column is text, so Redmine can not sort by revision.
-  # Mercurial has revision number, and revision number guarantees revision order.
-  # Redmine Mercurial model stored revisions ordered by database id to database.
-  # So, Redmine Mercurial model can use correct ordering revisions.
-  #
-  # Redmine Mercurial adapter uses "hg log -r 0:tip --limit 10"
-  # to get limited revisions from old to new.
-  # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
-  #
-  # The repository can still be fully reloaded by calling #clear_changesets
-  # before fetching changesets (eg. for offline resync)
-  def fetch_changesets
-    scm_brs = branches
-    return if scm_brs.nil? || scm_brs.empty?
-    h1 = extra_info || {}
-    h  = h1.dup
-    h["branches"]       ||= {}
-    h["db_consistent"]  ||= {}
-    if changesets.count == 0
-      h["db_consistent"]["ordering"] = 1
-      merge_extra_info(h)
-      self.save
-    elsif ! h["db_consistent"].has_key?("ordering")
-      h["db_consistent"]["ordering"] = 0
-      merge_extra_info(h)
-      self.save
-    end
-    scm_brs.each do |br1|
-      br = br1.to_s
-      from_scmid = nil
-      from_scmid = h["branches"][br]["last_scmid"] if h["branches"][br]
-      h["branches"][br] ||= {}
-      scm.revisions('', from_scmid, br, {:reverse => true}) do |rev|
-        db_rev = find_changeset_by_name(rev.revision)
-        transaction do
-          if db_rev.nil?
-            db_saved_rev = save_revision(rev)
-            parents = {}
-            parents[db_saved_rev] = rev.parents unless rev.parents.nil?
-            parents.each do |ch, chparents|
-              ch.parents = chparents.collect{|rp| find_changeset_by_name(rp)}.compact
-            end
-          end
-          h["branches"][br]["last_scmid"] = rev.scmid
-          merge_extra_info(h)
-          self.save
-        end
-      end
-    end
-  end
-
-  def save_revision(rev)
-    changeset = Changeset.new(
-              :repository   => self,
-              :revision     => rev.identifier,
-              :scmid        => rev.scmid,
-              :committer    => rev.author,
-              :committed_on => rev.time,
-              :comments     => rev.message
-              )
-    if changeset.save
-      rev.paths.each do |file|
-        Change.create(
-                  :changeset => changeset,
-                  :action    => file[:action],
-                  :path      => file[:path])
-      end
-    end
-    changeset
-  end
-  private :save_revision
-
-  def latest_changesets(path,rev,limit=10)
-    revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
-    return [] if revisions.nil? || revisions.empty?
-
-    changesets.find(
-      :all,
-      :conditions => [
-        "scmid IN (?)",
-        revisions.map!{|c| c.scmid}
-      ],
-      :order => 'committed_on DESC'
-    )
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/551de1919df18269d3487971094e6e1b67a8e45d.svn-base
--- a/.svn/pristine/55/551de1919df18269d3487971094e6e1b67a8e45d.svn-base
+++ /dev/null
@@ -1,1818 +0,0 @@
-/*  Copyright Mihai Bazon, 2002-2005  |  www.bazon.net/mishoo
- * -----------------------------------------------------------
- *
- * The DHTML Calendar, version 1.0 "It is happening again"
- *
- * Details and latest version at:
- * www.dynarch.com/projects/calendar
- *
- * This script is developed by Dynarch.com.  Visit us at www.dynarch.com.
- *
- * This script is distributed under the GNU Lesser General Public License.
- * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
- */
-
-// $Id: calendar.js,v 1.51 2005/03/07 16:44:31 mishoo Exp $
-
-/** The Calendar object constructor. */
-Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
-	// member variables
-	this.activeDiv = null;
-	this.currentDateEl = null;
-	this.getDateStatus = null;
-	this.getDateToolTip = null;
-	this.getDateText = null;
-	this.timeout = null;
-	this.onSelected = onSelected || null;
-	this.onClose = onClose || null;
-	this.dragging = false;
-	this.hidden = false;
-	this.minYear = 1970;
-	this.maxYear = 2050;
-	this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
-	this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
-	this.isPopup = true;
-	this.weekNumbers = true;
-	this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc.
-	this.showsOtherMonths = false;
-	this.dateStr = dateStr;
-	this.ar_days = null;
-	this.showsTime = false;
-	this.time24 = true;
-	this.yearStep = 2;
-	this.hiliteToday = true;
-	this.multiple = null;
-	// HTML elements
-	this.table = null;
-	this.element = null;
-	this.tbody = null;
-	this.firstdayname = null;
-	// Combo boxes
-	this.monthsCombo = null;
-	this.yearsCombo = null;
-	this.hilitedMonth = null;
-	this.activeMonth = null;
-	this.hilitedYear = null;
-	this.activeYear = null;
-	// Information
-	this.dateClicked = false;
-
-	// one-time initializations
-	if (typeof Calendar._SDN == "undefined") {
-		// table of short day names
-		if (typeof Calendar._SDN_len == "undefined")
-			Calendar._SDN_len = 3;
-		var ar = new Array();
-		for (var i = 8; i > 0;) {
-			ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
-		}
-		Calendar._SDN = ar;
-		// table of short month names
-		if (typeof Calendar._SMN_len == "undefined")
-			Calendar._SMN_len = 3;
-		ar = new Array();
-		for (var i = 12; i > 0;) {
-			ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
-		}
-		Calendar._SMN = ar;
-	}
-};
-
-// ** constants
-
-/// "static", needed for event handlers.
-Calendar._C = null;
-
-/// detect a special case of "web browser"
-Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
-		   !/opera/i.test(navigator.userAgent) );
-
-Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );
-
-/// detect Opera browser
-Calendar.is_opera = /opera/i.test(navigator.userAgent);
-
-/// detect KHTML-based browsers
-Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);
-
-// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
-//        library, at some point.
-
-Calendar.getAbsolutePos = function(el) {
-	var SL = 0, ST = 0;
-	var is_div = /^div$/i.test(el.tagName);
-	if (is_div && el.scrollLeft)
-		SL = el.scrollLeft;
-	if (is_div && el.scrollTop)
-		ST = el.scrollTop;
-	var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
-	if (el.offsetParent) {
-		var tmp = this.getAbsolutePos(el.offsetParent);
-		r.x += tmp.x;
-		r.y += tmp.y;
-	}
-	return r;
-};
-
-Calendar.isRelated = function (el, evt) {
-	var related = evt.relatedTarget;
-	if (!related) {
-		var type = evt.type;
-		if (type == "mouseover") {
-			related = evt.fromElement;
-		} else if (type == "mouseout") {
-			related = evt.toElement;
-		}
-	}
-	while (related) {
-		if (related == el) {
-			return true;
-		}
-		related = related.parentNode;
-	}
-	return false;
-};
-
-Calendar.removeClass = function(el, className) {
-	if (!(el && el.className)) {
-		return;
-	}
-	var cls = el.className.split(" ");
-	var ar = new Array();
-	for (var i = cls.length; i > 0;) {
-		if (cls[--i] != className) {
-			ar[ar.length] = cls[i];
-		}
-	}
-	el.className = ar.join(" ");
-};
-
-Calendar.addClass = function(el, className) {
-	Calendar.removeClass(el, className);
-	el.className += " " + className;
-};
-
-// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately.
-Calendar.getElement = function(ev) {
-	var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget;
-	while (f.nodeType != 1 || /^div$/i.test(f.tagName))
-		f = f.parentNode;
-	return f;
-};
-
-Calendar.getTargetElement = function(ev) {
-	var f = Calendar.is_ie ? window.event.srcElement : ev.target;
-	while (f.nodeType != 1)
-		f = f.parentNode;
-	return f;
-};
-
-Calendar.stopEvent = function(ev) {
-	ev || (ev = window.event);
-	if (Calendar.is_ie) {
-		ev.cancelBubble = true;
-		ev.returnValue = false;
-	} else {
-		ev.preventDefault();
-		ev.stopPropagation();
-	}
-	return false;
-};
-
-Calendar.addEvent = function(el, evname, func) {
-	if (el.attachEvent) { // IE
-		el.attachEvent("on" + evname, func);
-	} else if (el.addEventListener) { // Gecko / W3C
-		el.addEventListener(evname, func, true);
-	} else {
-		el["on" + evname] = func;
-	}
-};
-
-Calendar.removeEvent = function(el, evname, func) {
-	if (el.detachEvent) { // IE
-		el.detachEvent("on" + evname, func);
-	} else if (el.removeEventListener) { // Gecko / W3C
-		el.removeEventListener(evname, func, true);
-	} else {
-		el["on" + evname] = null;
-	}
-};
-
-Calendar.createElement = function(type, parent) {
-	var el = null;
-	if (document.createElementNS) {
-		// use the XHTML namespace; IE won't normally get here unless
-		// _they_ "fix" the DOM2 implementation.
-		el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
-	} else {
-		el = document.createElement(type);
-	}
-	if (typeof parent != "undefined") {
-		parent.appendChild(el);
-	}
-	return el;
-};
-
-// END: UTILITY FUNCTIONS
-
-// BEGIN: CALENDAR STATIC FUNCTIONS
-
-/** Internal -- adds a set of events to make some element behave like a button. */
-Calendar._add_evs = function(el) {
-	with (Calendar) {
-		addEvent(el, "mouseover", dayMouseOver);
-		addEvent(el, "mousedown", dayMouseDown);
-		addEvent(el, "mouseout", dayMouseOut);
-		if (is_ie) {
-			addEvent(el, "dblclick", dayMouseDblClick);
-			el.setAttribute("unselectable", true);
-		}
-	}
-};
-
-Calendar.findMonth = function(el) {
-	if (typeof el.month != "undefined") {
-		return el;
-	} else if (typeof el.parentNode.month != "undefined") {
-		return el.parentNode;
-	}
-	return null;
-};
-
-Calendar.findYear = function(el) {
-	if (typeof el.year != "undefined") {
-		return el;
-	} else if (typeof el.parentNode.year != "undefined") {
-		return el.parentNode;
-	}
-	return null;
-};
-
-Calendar.showMonthsCombo = function () {
-	var cal = Calendar._C;
-	if (!cal) {
-		return false;
-	}
-	var cal = cal;
-	var cd = cal.activeDiv;
-	var mc = cal.monthsCombo;
-	if (cal.hilitedMonth) {
-		Calendar.removeClass(cal.hilitedMonth, "hilite");
-	}
-	if (cal.activeMonth) {
-		Calendar.removeClass(cal.activeMonth, "active");
-	}
-	var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
-	Calendar.addClass(mon, "active");
-	cal.activeMonth = mon;
-	var s = mc.style;
-	s.display = "block";
-	if (cd.navtype < 0)
-		s.left = cd.offsetLeft + "px";
-	else {
-		var mcw = mc.offsetWidth;
-		if (typeof mcw == "undefined")
-			// Konqueror brain-dead techniques
-			mcw = 50;
-		s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
-	}
-	s.top = (cd.offsetTop + cd.offsetHeight) + "px";
-};
-
-Calendar.showYearsCombo = function (fwd) {
-	var cal = Calendar._C;
-	if (!cal) {
-		return false;
-	}
-	var cal = cal;
-	var cd = cal.activeDiv;
-	var yc = cal.yearsCombo;
-	if (cal.hilitedYear) {
-		Calendar.removeClass(cal.hilitedYear, "hilite");
-	}
-	if (cal.activeYear) {
-		Calendar.removeClass(cal.activeYear, "active");
-	}
-	cal.activeYear = null;
-	var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
-	var yr = yc.firstChild;
-	var show = false;
-	for (var i = 12; i > 0; --i) {
-		if (Y >= cal.minYear && Y <= cal.maxYear) {
-			yr.innerHTML = Y;
-			yr.year = Y;
-			yr.style.display = "block";
-			show = true;
-		} else {
-			yr.style.display = "none";
-		}
-		yr = yr.nextSibling;
-		Y += fwd ? cal.yearStep : -cal.yearStep;
-	}
-	if (show) {
-		var s = yc.style;
-		s.display = "block";
-		if (cd.navtype < 0)
-			s.left = cd.offsetLeft + "px";
-		else {
-			var ycw = yc.offsetWidth;
-			if (typeof ycw == "undefined")
-				// Konqueror brain-dead techniques
-				ycw = 50;
-			s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
-		}
-		s.top = (cd.offsetTop + cd.offsetHeight) + "px";
-	}
-};
-
-// event handlers
-
-Calendar.tableMouseUp = function(ev) {
-	var cal = Calendar._C;
-	if (!cal) {
-		return false;
-	}
-	if (cal.timeout) {
-		clearTimeout(cal.timeout);
-	}
-	var el = cal.activeDiv;
-	if (!el) {
-		return false;
-	}
-	var target = Calendar.getTargetElement(ev);
-	ev || (ev = window.event);
-	Calendar.removeClass(el, "active");
-	if (target == el || target.parentNode == el) {
-		Calendar.cellClick(el, ev);
-	}
-	var mon = Calendar.findMonth(target);
-	var date = null;
-	if (mon) {
-		date = new Date(cal.date);
-		if (mon.month != date.getMonth()) {
-			date.setMonth(mon.month);
-			cal.setDate(date);
-			cal.dateClicked = false;
-			cal.callHandler();
-		}
-	} else {
-		var year = Calendar.findYear(target);
-		if (year) {
-			date = new Date(cal.date);
-			if (year.year != date.getFullYear()) {
-				date.setFullYear(year.year);
-				cal.setDate(date);
-				cal.dateClicked = false;
-				cal.callHandler();
-			}
-		}
-	}
-	with (Calendar) {
-		removeEvent(document, "mouseup", tableMouseUp);
-		removeEvent(document, "mouseover", tableMouseOver);
-		removeEvent(document, "mousemove", tableMouseOver);
-		cal._hideCombos();
-		_C = null;
-		return stopEvent(ev);
-	}
-};
-
-Calendar.tableMouseOver = function (ev) {
-	var cal = Calendar._C;
-	if (!cal) {
-		return;
-	}
-	var el = cal.activeDiv;
-	var target = Calendar.getTargetElement(ev);
-	if (target == el || target.parentNode == el) {
-		Calendar.addClass(el, "hilite active");
-		Calendar.addClass(el.parentNode, "rowhilite");
-	} else {
-		if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
-			Calendar.removeClass(el, "active");
-		Calendar.removeClass(el, "hilite");
-		Calendar.removeClass(el.parentNode, "rowhilite");
-	}
-	ev || (ev = window.event);
-	if (el.navtype == 50 && target != el) {
-		var pos = Calendar.getAbsolutePos(el);
-		var w = el.offsetWidth;
-		var x = ev.clientX;
-		var dx;
-		var decrease = true;
-		if (x > pos.x + w) {
-			dx = x - pos.x - w;
-			decrease = false;
-		} else
-			dx = pos.x - x;
-
-		if (dx < 0) dx = 0;
-		var range = el._range;
-		var current = el._current;
-		var count = Math.floor(dx / 10) % range.length;
-		for (var i = range.length; --i >= 0;)
-			if (range[i] == current)
-				break;
-		while (count-- > 0)
-			if (decrease) {
-				if (--i < 0)
-					i = range.length - 1;
-			} else if ( ++i >= range.length )
-				i = 0;
-		var newval = range[i];
-		el.innerHTML = newval;
-
-		cal.onUpdateTime();
-	}
-	var mon = Calendar.findMonth(target);
-	if (mon) {
-		if (mon.month != cal.date.getMonth()) {
-			if (cal.hilitedMonth) {
-				Calendar.removeClass(cal.hilitedMonth, "hilite");
-			}
-			Calendar.addClass(mon, "hilite");
-			cal.hilitedMonth = mon;
-		} else if (cal.hilitedMonth) {
-			Calendar.removeClass(cal.hilitedMonth, "hilite");
-		}
-	} else {
-		if (cal.hilitedMonth) {
-			Calendar.removeClass(cal.hilitedMonth, "hilite");
-		}
-		var year = Calendar.findYear(target);
-		if (year) {
-			if (year.year != cal.date.getFullYear()) {
-				if (cal.hilitedYear) {
-					Calendar.removeClass(cal.hilitedYear, "hilite");
-				}
-				Calendar.addClass(year, "hilite");
-				cal.hilitedYear = year;
-			} else if (cal.hilitedYear) {
-				Calendar.removeClass(cal.hilitedYear, "hilite");
-			}
-		} else if (cal.hilitedYear) {
-			Calendar.removeClass(cal.hilitedYear, "hilite");
-		}
-	}
-	return Calendar.stopEvent(ev);
-};
-
-Calendar.tableMouseDown = function (ev) {
-	if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
-		return Calendar.stopEvent(ev);
-	}
-};
-
-Calendar.calDragIt = function (ev) {
-	var cal = Calendar._C;
-	if (!(cal && cal.dragging)) {
-		return false;
-	}
-	var posX;
-	var posY;
-	if (Calendar.is_ie) {
-		posY = window.event.clientY + document.body.scrollTop;
-		posX = window.event.clientX + document.body.scrollLeft;
-	} else {
-		posX = ev.pageX;
-		posY = ev.pageY;
-	}
-	cal.hideShowCovered();
-	var st = cal.element.style;
-	st.left = (posX - cal.xOffs) + "px";
-	st.top = (posY - cal.yOffs) + "px";
-	return Calendar.stopEvent(ev);
-};
-
-Calendar.calDragEnd = function (ev) {
-	var cal = Calendar._C;
-	if (!cal) {
-		return false;
-	}
-	cal.dragging = false;
-	with (Calendar) {
-		removeEvent(document, "mousemove", calDragIt);
-		removeEvent(document, "mouseup", calDragEnd);
-		tableMouseUp(ev);
-	}
-	cal.hideShowCovered();
-};
-
-Calendar.dayMouseDown = function(ev) {
-	var el = Calendar.getElement(ev);
-	if (el.disabled) {
-		return false;
-	}
-	var cal = el.calendar;
-	cal.activeDiv = el;
-	Calendar._C = cal;
-	if (el.navtype != 300) with (Calendar) {
-		if (el.navtype == 50) {
-			el._current = el.innerHTML;
-			addEvent(document, "mousemove", tableMouseOver);
-		} else
-			addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver);
-		addClass(el, "hilite active");
-		addEvent(document, "mouseup", tableMouseUp);
-	} else if (cal.isPopup) {
-		cal._dragStart(ev);
-	}
-	if (el.navtype == -1 || el.navtype == 1) {
-		if (cal.timeout) clearTimeout(cal.timeout);
-		cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
-	} else if (el.navtype == -2 || el.navtype == 2) {
-		if (cal.timeout) clearTimeout(cal.timeout);
-		cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
-	} else {
-		cal.timeout = null;
-	}
-	return Calendar.stopEvent(ev);
-};
-
-Calendar.dayMouseDblClick = function(ev) {
-	Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
-	if (Calendar.is_ie) {
-		document.selection.empty();
-	}
-};
-
-Calendar.dayMouseOver = function(ev) {
-	var el = Calendar.getElement(ev);
-	if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
-		return false;
-	}
-	if (el.ttip) {
-		if (el.ttip.substr(0, 1) == "_") {
-			el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
-		}
-		el.calendar.tooltips.innerHTML = el.ttip;
-	}
-	if (el.navtype != 300) {
-		Calendar.addClass(el, "hilite");
-		if (el.caldate) {
-			Calendar.addClass(el.parentNode, "rowhilite");
-		}
-	}
-	return Calendar.stopEvent(ev);
-};
-
-Calendar.dayMouseOut = function(ev) {
-	with (Calendar) {
-		var el = getElement(ev);
-		if (isRelated(el, ev) || _C || el.disabled)
-			return false;
-		removeClass(el, "hilite");
-		if (el.caldate)
-			removeClass(el.parentNode, "rowhilite");
-		if (el.calendar)
-			el.calendar.tooltips.innerHTML = _TT["SEL_DATE"];
-		return stopEvent(ev);
-	}
-};
-
-/**
- *  A generic "click" handler :) handles all types of buttons defined in this
- *  calendar.
- */
-Calendar.cellClick = function(el, ev) {
-	var cal = el.calendar;
-	var closing = false;
-	var newdate = false;
-	var date = null;
-	if (typeof el.navtype == "undefined") {
-		if (cal.currentDateEl) {
-			Calendar.removeClass(cal.currentDateEl, "selected");
-			Calendar.addClass(el, "selected");
-			closing = (cal.currentDateEl == el);
-			if (!closing) {
-				cal.currentDateEl = el;
-			}
-		}
-		cal.date.setDateOnly(el.caldate);
-		date = cal.date;
-		var other_month = !(cal.dateClicked = !el.otherMonth);
-		if (!other_month && !cal.currentDateEl)
-			cal._toggleMultipleDate(new Date(date));
-		else
-			newdate = !el.disabled;
-		// a date was clicked
-		if (other_month)
-			cal._init(cal.firstDayOfWeek, date);
-	} else {
-		if (el.navtype == 200) {
-			Calendar.removeClass(el, "hilite");
-			cal.callCloseHandler();
-			return;
-		}
-		date = new Date(cal.date);
-		if (el.navtype == 0)
-			date.setDateOnly(new Date()); // TODAY
-		// unless "today" was clicked, we assume no date was clicked so
-		// the selected handler will know not to close the calenar when
-		// in single-click mode.
-		// cal.dateClicked = (el.navtype == 0);
-		cal.dateClicked = false;
-		var year = date.getFullYear();
-		var mon = date.getMonth();
-		function setMonth(m) {
-			var day = date.getDate();
-			var max = date.getMonthDays(m);
-			if (day > max) {
-				date.setDate(max);
-			}
-			date.setMonth(m);
-		};
-		switch (el.navtype) {
-		    case 400:
-			Calendar.removeClass(el, "hilite");
-			var text = Calendar._TT["ABOUT"];
-			if (typeof text != "undefined") {
-				text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
-			} else {
-				// FIXME: this should be removed as soon as lang files get updated!
-				text = "Help and about box text is not translated into this language.\n" +
-					"If you know this language and you feel generous please update\n" +
-					"the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
-					"and send it back to <mihai_bazon@yahoo.com> to get it into the distribution  ;-)\n\n" +
-					"Thank you!\n" +
-					"http://dynarch.com/mishoo/calendar.epl\n";
-			}
-			alert(text);
-			return;
-		    case -2:
-			if (year > cal.minYear) {
-				date.setFullYear(year - 1);
-			}
-			break;
-		    case -1:
-			if (mon > 0) {
-				setMonth(mon - 1);
-			} else if (year-- > cal.minYear) {
-				date.setFullYear(year);
-				setMonth(11);
-			}
-			break;
-		    case 1:
-			if (mon < 11) {
-				setMonth(mon + 1);
-			} else if (year < cal.maxYear) {
-				date.setFullYear(year + 1);
-				setMonth(0);
-			}
-			break;
-		    case 2:
-			if (year < cal.maxYear) {
-				date.setFullYear(year + 1);
-			}
-			break;
-		    case 100:
-			cal.setFirstDayOfWeek(el.fdow);
-			return;
-		    case 50:
-			var range = el._range;
-			var current = el.innerHTML;
-			for (var i = range.length; --i >= 0;)
-				if (range[i] == current)
-					break;
-			if (ev && ev.shiftKey) {
-				if (--i < 0)
-					i = range.length - 1;
-			} else if ( ++i >= range.length )
-				i = 0;
-			var newval = range[i];
-			el.innerHTML = newval;
-			cal.onUpdateTime();
-			return;
-		    case 0:
-			// TODAY will bring us here
-			if ((typeof cal.getDateStatus == "function") &&
-			    cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
-				return false;
-			}
-			break;
-		}
-		if (!date.equalsTo(cal.date)) {
-			cal.setDate(date);
-			newdate = true;
-		} else if (el.navtype == 0)
-			newdate = closing = true;
-	}
-	if (newdate) {
-		ev && cal.callHandler();
-	}
-	if (closing) {
-		Calendar.removeClass(el, "hilite");
-		ev && cal.callCloseHandler();
-	}
-};
-
-// END: CALENDAR STATIC FUNCTIONS
-
-// BEGIN: CALENDAR OBJECT FUNCTIONS
-
-/**
- *  This function creates the calendar inside the given parent.  If _par is
- *  null than it creates a popup calendar inside the BODY element.  If _par is
- *  an element, be it BODY, then it creates a non-popup calendar (still
- *  hidden).  Some properties need to be set before calling this function.
- */
-Calendar.prototype.create = function (_par) {
-	var parent = null;
-	if (! _par) {
-		// default parent is the document body, in which case we create
-		// a popup calendar.
-		parent = document.getElementsByTagName("body")[0];
-		this.isPopup = true;
-	} else {
-		parent = _par;
-		this.isPopup = false;
-	}
-	this.date = this.dateStr ? new Date(this.dateStr) : new Date();
-
-	var table = Calendar.createElement("table");
-	this.table = table;
-	table.cellSpacing = 0;
-	table.cellPadding = 0;
-	table.calendar = this;
-	Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);
-
-	var div = Calendar.createElement("div");
-	this.element = div;
-	div.className = "calendar";
-	if (this.isPopup) {
-		div.style.position = "absolute";
-		div.style.display = "none";
-	}
-	div.appendChild(table);
-
-	var thead = Calendar.createElement("thead", table);
-	var cell = null;
-	var row = null;
-
-	var cal = this;
-	var hh = function (text, cs, navtype) {
-		cell = Calendar.createElement("td", row);
-		cell.colSpan = cs;
-		cell.className = "button";
-		if (navtype != 0 && Math.abs(navtype) <= 2)
-			cell.className += " nav";
-		Calendar._add_evs(cell);
-		cell.calendar = cal;
-		cell.navtype = navtype;
-		cell.innerHTML = "<div unselectable='on'>" + text + "</div>";
-		return cell;
-	};
-
-	row = Calendar.createElement("tr", thead);
-	var title_length = 6;
-	(this.isPopup) && --title_length;
-	(this.weekNumbers) && ++title_length;
-
-	hh("?", 1, 400).ttip = Calendar._TT["INFO"];
-	this.title = hh("", title_length, 300);
-	this.title.className = "title";
-	if (this.isPopup) {
-		this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
-		this.title.style.cursor = "move";
-		hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
-	}
-
-	row = Calendar.createElement("tr", thead);
-	row.className = "headrow";
-
-	this._nav_py = hh("&#x00ab;", 1, -2);
-	this._nav_py.ttip = Calendar._TT["PREV_YEAR"];
-
-	this._nav_pm = hh("&#x2039;", 1, -1);
-	this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];
-
-	this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
-	this._nav_now.ttip = Calendar._TT["GO_TODAY"];
-
-	this._nav_nm = hh("&#x203a;", 1, 1);
-	this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];
-
-	this._nav_ny = hh("&#x00bb;", 1, 2);
-	this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];
-
-	// day names
-	row = Calendar.createElement("tr", thead);
-	row.className = "daynames";
-	if (this.weekNumbers) {
-		cell = Calendar.createElement("td", row);
-		cell.className = "name wn";
-		cell.innerHTML = Calendar._TT["WK"];
-	}
-	for (var i = 7; i > 0; --i) {
-		cell = Calendar.createElement("td", row);
-		if (!i) {
-			cell.navtype = 100;
-			cell.calendar = this;
-			Calendar._add_evs(cell);
-		}
-	}
-	this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
-	this._displayWeekdays();
-
-	var tbody = Calendar.createElement("tbody", table);
-	this.tbody = tbody;
-
-	for (i = 6; i > 0; --i) {
-		row = Calendar.createElement("tr", tbody);
-		if (this.weekNumbers) {
-			cell = Calendar.createElement("td", row);
-		}
-		for (var j = 7; j > 0; --j) {
-			cell = Calendar.createElement("td", row);
-			cell.calendar = this;
-			Calendar._add_evs(cell);
-		}
-	}
-
-	if (this.showsTime) {
-		row = Calendar.createElement("tr", tbody);
-		row.className = "time";
-
-		cell = Calendar.createElement("td", row);
-		cell.className = "time";
-		cell.colSpan = 2;
-		cell.innerHTML = Calendar._TT["TIME"] || "&nbsp;";
-
-		cell = Calendar.createElement("td", row);
-		cell.className = "time";
-		cell.colSpan = this.weekNumbers ? 4 : 3;
-
-		(function(){
-			function makeTimePart(className, init, range_start, range_end) {
-				var part = Calendar.createElement("span", cell);
-				part.className = className;
-				part.innerHTML = init;
-				part.calendar = cal;
-				part.ttip = Calendar._TT["TIME_PART"];
-				part.navtype = 50;
-				part._range = [];
-				if (typeof range_start != "number")
-					part._range = range_start;
-				else {
-					for (var i = range_start; i <= range_end; ++i) {
-						var txt;
-						if (i < 10 && range_end >= 10) txt = '0' + i;
-						else txt = '' + i;
-						part._range[part._range.length] = txt;
-					}
-				}
-				Calendar._add_evs(part);
-				return part;
-			};
-			var hrs = cal.date.getHours();
-			var mins = cal.date.getMinutes();
-			var t12 = !cal.time24;
-			var pm = (hrs > 12);
-			if (t12 && pm) hrs -= 12;
-			var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
-			var span = Calendar.createElement("span", cell);
-			span.innerHTML = ":";
-			span.className = "colon";
-			var M = makeTimePart("minute", mins, 0, 59);
-			var AP = null;
-			cell = Calendar.createElement("td", row);
-			cell.className = "time";
-			cell.colSpan = 2;
-			if (t12)
-				AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
-			else
-				cell.innerHTML = "&nbsp;";
-
-			cal.onSetTime = function() {
-				var pm, hrs = this.date.getHours(),
-					mins = this.date.getMinutes();
-				if (t12) {
-					pm = (hrs >= 12);
-					if (pm) hrs -= 12;
-					if (hrs == 0) hrs = 12;
-					AP.innerHTML = pm ? "pm" : "am";
-				}
-				H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs;
-				M.innerHTML = (mins < 10) ? ("0" + mins) : mins;
-			};
-
-			cal.onUpdateTime = function() {
-				var date = this.date;
-				var h = parseInt(H.innerHTML, 10);
-				if (t12) {
-					if (/pm/i.test(AP.innerHTML) && h < 12)
-						h += 12;
-					else if (/am/i.test(AP.innerHTML) && h == 12)
-						h = 0;
-				}
-				var d = date.getDate();
-				var m = date.getMonth();
-				var y = date.getFullYear();
-				date.setHours(h);
-				date.setMinutes(parseInt(M.innerHTML, 10));
-				date.setFullYear(y);
-				date.setMonth(m);
-				date.setDate(d);
-				this.dateClicked = false;
-				this.callHandler();
-			};
-		})();
-	} else {
-		this.onSetTime = this.onUpdateTime = function() {};
-	}
-
-	var tfoot = Calendar.createElement("tfoot", table);
-
-	row = Calendar.createElement("tr", tfoot);
-	row.className = "footrow";
-
-	cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
-	cell.className = "ttip";
-	if (this.isPopup) {
-		cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
-		cell.style.cursor = "move";
-	}
-	this.tooltips = cell;
-
-	div = Calendar.createElement("div", this.element);
-	this.monthsCombo = div;
-	div.className = "combo";
-	for (i = 0; i < Calendar._MN.length; ++i) {
-		var mn = Calendar.createElement("div");
-		mn.className = Calendar.is_ie ? "label-IEfix" : "label";
-		mn.month = i;
-		mn.innerHTML = Calendar._SMN[i];
-		div.appendChild(mn);
-	}
-
-	div = Calendar.createElement("div", this.element);
-	this.yearsCombo = div;
-	div.className = "combo";
-	for (i = 12; i > 0; --i) {
-		var yr = Calendar.createElement("div");
-		yr.className = Calendar.is_ie ? "label-IEfix" : "label";
-		div.appendChild(yr);
-	}
-
-	this._init(this.firstDayOfWeek, this.date);
-	parent.appendChild(this.element);
-};
-
-/** keyboard navigation, only for popup calendars */
-Calendar._keyEvent = function(ev) {
-	var cal = window._dynarch_popupCalendar;
-	if (!cal || cal.multiple)
-		return false;
-	(Calendar.is_ie) && (ev = window.event);
-	var act = (Calendar.is_ie || ev.type == "keypress"),
-		K = ev.keyCode;
-	if (ev.ctrlKey) {
-		switch (K) {
-		    case 37: // KEY left
-			act && Calendar.cellClick(cal._nav_pm);
-			break;
-		    case 38: // KEY up
-			act && Calendar.cellClick(cal._nav_py);
-			break;
-		    case 39: // KEY right
-			act && Calendar.cellClick(cal._nav_nm);
-			break;
-		    case 40: // KEY down
-			act && Calendar.cellClick(cal._nav_ny);
-			break;
-		    default:
-			return false;
-		}
-	} else switch (K) {
-	    case 32: // KEY space (now)
-		Calendar.cellClick(cal._nav_now);
-		break;
-	    case 27: // KEY esc
-		act && cal.callCloseHandler();
-		break;
-	    case 37: // KEY left
-	    case 38: // KEY up
-	    case 39: // KEY right
-	    case 40: // KEY down
-		if (act) {
-			var prev, x, y, ne, el, step;
-			prev = K == 37 || K == 38;
-			step = (K == 37 || K == 39) ? 1 : 7;
-			function setVars() {
-				el = cal.currentDateEl;
-				var p = el.pos;
-				x = p & 15;
-				y = p >> 4;
-				ne = cal.ar_days[y][x];
-			};setVars();
-			function prevMonth() {
-				var date = new Date(cal.date);
-				date.setDate(date.getDate() - step);
-				cal.setDate(date);
-			};
-			function nextMonth() {
-				var date = new Date(cal.date);
-				date.setDate(date.getDate() + step);
-				cal.setDate(date);
-			};
-			while (1) {
-				switch (K) {
-				    case 37: // KEY left
-					if (--x >= 0)
-						ne = cal.ar_days[y][x];
-					else {
-						x = 6;
-						K = 38;
-						continue;
-					}
-					break;
-				    case 38: // KEY up
-					if (--y >= 0)
-						ne = cal.ar_days[y][x];
-					else {
-						prevMonth();
-						setVars();
-					}
-					break;
-				    case 39: // KEY right
-					if (++x < 7)
-						ne = cal.ar_days[y][x];
-					else {
-						x = 0;
-						K = 40;
-						continue;
-					}
-					break;
-				    case 40: // KEY down
-					if (++y < cal.ar_days.length)
-						ne = cal.ar_days[y][x];
-					else {
-						nextMonth();
-						setVars();
-					}
-					break;
-				}
-				break;
-			}
-			if (ne) {
-				if (!ne.disabled)
-					Calendar.cellClick(ne);
-				else if (prev)
-					prevMonth();
-				else
-					nextMonth();
-			}
-		}
-		break;
-	    case 13: // KEY enter
-		if (act)
-			Calendar.cellClick(cal.currentDateEl, ev);
-		break;
-	    default:
-		return false;
-	}
-	return Calendar.stopEvent(ev);
-};
-
-/**
- *  (RE)Initializes the calendar to the given date and firstDayOfWeek
- */
-Calendar.prototype._init = function (firstDayOfWeek, date) {
-	var today = new Date(),
-		TY = today.getFullYear(),
-		TM = today.getMonth(),
-		TD = today.getDate();
-	this.table.style.visibility = "hidden";
-	var year = date.getFullYear();
-	if (year < this.minYear) {
-		year = this.minYear;
-		date.setFullYear(year);
-	} else if (year > this.maxYear) {
-		year = this.maxYear;
-		date.setFullYear(year);
-	}
-	this.firstDayOfWeek = firstDayOfWeek;
-	this.date = new Date(date);
-	var month = date.getMonth();
-	var mday = date.getDate();
-	var no_days = date.getMonthDays();
-
-	// calendar voodoo for computing the first day that would actually be
-	// displayed in the calendar, even if it's from the previous month.
-	// WARNING: this is magic. ;-)
-	date.setDate(1);
-	var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
-	if (day1 < 0)
-		day1 += 7;
-	date.setDate(0-day1);
-	date.setDate(date.getDate() + 1);
-
-	var row = this.tbody.firstChild;
-	var MN = Calendar._SMN[month];
-	var ar_days = this.ar_days = new Array();
-	var weekend = Calendar._TT["WEEKEND"];
-	var dates = this.multiple ? (this.datesCells = {}) : null;
-	for (var i = 0; i < 6; ++i, row = row.nextSibling) {
-		var cell = row.firstChild;
-		if (this.weekNumbers) {
-			cell.className = "day wn";
-			cell.innerHTML = date.getWeekNumber();
-			cell = cell.nextSibling;
-		}
-		row.className = "daysrow";
-		var hasdays = false, iday, dpos = ar_days[i] = [];
-		for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
-			iday = date.getDate();
-			var wday = date.getDay();
-			cell.className = "day";
-			cell.pos = i << 4 | j;
-			dpos[j] = cell;
-			var current_month = (date.getMonth() == month);
-			if (!current_month) {
-				if (this.showsOtherMonths) {
-					cell.className += " othermonth";
-					cell.otherMonth = true;
-				} else {
-					cell.className = "emptycell";
-					cell.innerHTML = "&nbsp;";
-					cell.disabled = true;
-					continue;
-				}
-			} else {
-				cell.otherMonth = false;
-				hasdays = true;
-			}
-			cell.disabled = false;
-			cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
-			if (dates)
-				dates[date.print("%Y%m%d")] = cell;
-			if (this.getDateStatus) {
-				var status = this.getDateStatus(date, year, month, iday);
-				if (this.getDateToolTip) {
-					var toolTip = this.getDateToolTip(date, year, month, iday);
-					if (toolTip)
-						cell.title = toolTip;
-				}
-				if (status === true) {
-					cell.className += " disabled";
-					cell.disabled = true;
-				} else {
-					if (/disabled/i.test(status))
-						cell.disabled = true;
-					cell.className += " " + status;
-				}
-			}
-			if (!cell.disabled) {
-				cell.caldate = new Date(date);
-				cell.ttip = "_";
-				if (!this.multiple && current_month
-				    && iday == mday && this.hiliteToday) {
-					cell.className += " selected";
-					this.currentDateEl = cell;
-				}
-				if (date.getFullYear() == TY &&
-				    date.getMonth() == TM &&
-				    iday == TD) {
-					cell.className += " today";
-					cell.ttip += Calendar._TT["PART_TODAY"];
-				}
-				if (weekend.indexOf(wday.toString()) != -1)
-					cell.className += cell.otherMonth ? " oweekend" : " weekend";
-			}
-		}
-		if (!(hasdays || this.showsOtherMonths))
-			row.className = "emptyrow";
-	}
-	this.title.innerHTML = Calendar._MN[month] + ", " + year;
-	this.onSetTime();
-	this.table.style.visibility = "visible";
-	this._initMultipleDates();
-	// PROFILE
-	// this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
-};
-
-Calendar.prototype._initMultipleDates = function() {
-	if (this.multiple) {
-		for (var i in this.multiple) {
-			var cell = this.datesCells[i];
-			var d = this.multiple[i];
-			if (!d)
-				continue;
-			if (cell)
-				cell.className += " selected";
-		}
-	}
-};
-
-Calendar.prototype._toggleMultipleDate = function(date) {
-	if (this.multiple) {
-		var ds = date.print("%Y%m%d");
-		var cell = this.datesCells[ds];
-		if (cell) {
-			var d = this.multiple[ds];
-			if (!d) {
-				Calendar.addClass(cell, "selected");
-				this.multiple[ds] = date;
-			} else {
-				Calendar.removeClass(cell, "selected");
-				delete this.multiple[ds];
-			}
-		}
-	}
-};
-
-Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
-	this.getDateToolTip = unaryFunction;
-};
-
-/**
- *  Calls _init function above for going to a certain date (but only if the
- *  date is different than the currently selected one).
- */
-Calendar.prototype.setDate = function (date) {
-	if (!date.equalsTo(this.date)) {
-		this._init(this.firstDayOfWeek, date);
-	}
-};
-
-/**
- *  Refreshes the calendar.  Useful if the "disabledHandler" function is
- *  dynamic, meaning that the list of disabled date can change at runtime.
- *  Just * call this function if you think that the list of disabled dates
- *  should * change.
- */
-Calendar.prototype.refresh = function () {
-	this._init(this.firstDayOfWeek, this.date);
-};
-
-/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */
-Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
-	this._init(firstDayOfWeek, this.date);
-	this._displayWeekdays();
-};
-
-/**
- *  Allows customization of what dates are enabled.  The "unaryFunction"
- *  parameter must be a function object that receives the date (as a JS Date
- *  object) and returns a boolean value.  If the returned value is true then
- *  the passed date will be marked as disabled.
- */
-Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
-	this.getDateStatus = unaryFunction;
-};
-
-/** Customization of allowed year range for the calendar. */
-Calendar.prototype.setRange = function (a, z) {
-	this.minYear = a;
-	this.maxYear = z;
-};
-
-/** Calls the first user handler (selectedHandler). */
-Calendar.prototype.callHandler = function () {
-	if (this.onSelected) {
-		this.onSelected(this, this.date.print(this.dateFormat));
-	}
-};
-
-/** Calls the second user handler (closeHandler). */
-Calendar.prototype.callCloseHandler = function () {
-	if (this.onClose) {
-		this.onClose(this);
-	}
-	this.hideShowCovered();
-};
-
-/** Removes the calendar object from the DOM tree and destroys it. */
-Calendar.prototype.destroy = function () {
-	var el = this.element.parentNode;
-	el.removeChild(this.element);
-	Calendar._C = null;
-	window._dynarch_popupCalendar = null;
-};
-
-/**
- *  Moves the calendar element to a different section in the DOM tree (changes
- *  its parent).
- */
-Calendar.prototype.reparent = function (new_parent) {
-	var el = this.element;
-	el.parentNode.removeChild(el);
-	new_parent.appendChild(el);
-};
-
-// This gets called when the user presses a mouse button anywhere in the
-// document, if the calendar is shown.  If the click was outside the open
-// calendar this function closes it.
-Calendar._checkCalendar = function(ev) {
-	var calendar = window._dynarch_popupCalendar;
-	if (!calendar) {
-		return false;
-	}
-	var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
-	for (; el != null && el != calendar.element; el = el.parentNode);
-	if (el == null) {
-		// calls closeHandler which should hide the calendar.
-		window._dynarch_popupCalendar.callCloseHandler();
-		return Calendar.stopEvent(ev);
-	}
-};
-
-/** Shows the calendar. */
-Calendar.prototype.show = function () {
-	var rows = this.table.getElementsByTagName("tr");
-	for (var i = rows.length; i > 0;) {
-		var row = rows[--i];
-		Calendar.removeClass(row, "rowhilite");
-		var cells = row.getElementsByTagName("td");
-		for (var j = cells.length; j > 0;) {
-			var cell = cells[--j];
-			Calendar.removeClass(cell, "hilite");
-			Calendar.removeClass(cell, "active");
-		}
-	}
-	this.element.style.display = "block";
-	this.hidden = false;
-	if (this.isPopup) {
-		window._dynarch_popupCalendar = this;
-		Calendar.addEvent(document, "keydown", Calendar._keyEvent);
-		Calendar.addEvent(document, "keypress", Calendar._keyEvent);
-		Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
-	}
-	this.hideShowCovered();
-};
-
-/**
- *  Hides the calendar.  Also removes any "hilite" from the class of any TD
- *  element.
- */
-Calendar.prototype.hide = function () {
-	if (this.isPopup) {
-		Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
-		Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
-		Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
-	}
-	this.element.style.display = "none";
-	this.hidden = true;
-	this.hideShowCovered();
-};
-
-/**
- *  Shows the calendar at a given absolute position (beware that, depending on
- *  the calendar element style -- position property -- this might be relative
- *  to the parent's containing rectangle).
- */
-Calendar.prototype.showAt = function (x, y) {
-	var s = this.element.style;
-	s.left = x + "px";
-	s.top = y + "px";
-	this.show();
-};
-
-/** Shows the calendar near a given element. */
-Calendar.prototype.showAtElement = function (el, opts) {
-	var self = this;
-	var p = Calendar.getAbsolutePos(el);
-	if (!opts || typeof opts != "string") {
-		this.showAt(p.x, p.y + el.offsetHeight);
-		return true;
-	}
-	function fixPosition(box) {
-		if (box.x < 0)
-			box.x = 0;
-		if (box.y < 0)
-			box.y = 0;
-		var cp = document.createElement("div");
-		var s = cp.style;
-		s.position = "absolute";
-		s.right = s.bottom = s.width = s.height = "0px";
-		document.body.appendChild(cp);
-		var br = Calendar.getAbsolutePos(cp);
-		document.body.removeChild(cp);
-		if (Calendar.is_ie) {
-			br.y += document.body.scrollTop;
-			br.x += document.body.scrollLeft;
-		} else {
-			br.y += window.scrollY;
-			br.x += window.scrollX;
-		}
-		var tmp = box.x + box.width - br.x;
-		if (tmp > 0) box.x -= tmp;
-		tmp = box.y + box.height - br.y;
-		if (tmp > 0) box.y -= tmp;
-	};
-	this.element.style.display = "block";
-	Calendar.continuation_for_the_fucking_khtml_browser = function() {
-		var w = self.element.offsetWidth;
-		var h = self.element.offsetHeight;
-		self.element.style.display = "none";
-		var valign = opts.substr(0, 1);
-		var halign = "l";
-		if (opts.length > 1) {
-			halign = opts.substr(1, 1);
-		}
-		// vertical alignment
-		switch (valign) {
-		    case "T": p.y -= h; break;
-		    case "B": p.y += el.offsetHeight; break;
-		    case "C": p.y += (el.offsetHeight - h) / 2; break;
-		    case "t": p.y += el.offsetHeight - h; break;
-		    case "b": break; // already there
-		}
-		// horizontal alignment
-		switch (halign) {
-		    case "L": p.x -= w; break;
-		    case "R": p.x += el.offsetWidth; break;
-		    case "C": p.x += (el.offsetWidth - w) / 2; break;
-		    case "l": p.x += el.offsetWidth - w; break;
-		    case "r": break; // already there
-		}
-		p.width = w;
-		p.height = h + 40;
-		self.monthsCombo.style.display = "none";
-		fixPosition(p);
-		self.showAt(p.x, p.y);
-	};
-	if (Calendar.is_khtml)
-		setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
-	else
-		Calendar.continuation_for_the_fucking_khtml_browser();
-};
-
-/** Customizes the date format. */
-Calendar.prototype.setDateFormat = function (str) {
-	this.dateFormat = str;
-};
-
-/** Customizes the tooltip date format. */
-Calendar.prototype.setTtDateFormat = function (str) {
-	this.ttDateFormat = str;
-};
-
-/**
- *  Tries to identify the date represented in a string.  If successful it also
- *  calls this.setDate which moves the calendar to the given date.
- */
-Calendar.prototype.parseDate = function(str, fmt) {
-	if (!fmt)
-		fmt = this.dateFormat;
-	this.setDate(Date.parseDate(str, fmt));
-};
-
-Calendar.prototype.hideShowCovered = function () {
-	if (!Calendar.is_ie && !Calendar.is_opera)
-		return;
-	function getVisib(obj){
-		var value = obj.style.visibility;
-		if (!value) {
-			if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
-				if (!Calendar.is_khtml)
-					value = document.defaultView.
-						getComputedStyle(obj, "").getPropertyValue("visibility");
-				else
-					value = '';
-			} else if (obj.currentStyle) { // IE
-				value = obj.currentStyle.visibility;
-			} else
-				value = '';
-		}
-		return value;
-	};
-
-	var tags = new Array("applet", "iframe", "select");
-	var el = this.element;
-
-	var p = Calendar.getAbsolutePos(el);
-	var EX1 = p.x;
-	var EX2 = el.offsetWidth + EX1;
-	var EY1 = p.y;
-	var EY2 = el.offsetHeight + EY1;
-
-	for (var k = tags.length; k > 0; ) {
-		var ar = document.getElementsByTagName(tags[--k]);
-		var cc = null;
-
-		for (var i = ar.length; i > 0;) {
-			cc = ar[--i];
-
-			p = Calendar.getAbsolutePos(cc);
-			var CX1 = p.x;
-			var CX2 = cc.offsetWidth + CX1;
-			var CY1 = p.y;
-			var CY2 = cc.offsetHeight + CY1;
-
-			if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
-				if (!cc.__msh_save_visibility) {
-					cc.__msh_save_visibility = getVisib(cc);
-				}
-				cc.style.visibility = cc.__msh_save_visibility;
-			} else {
-				if (!cc.__msh_save_visibility) {
-					cc.__msh_save_visibility = getVisib(cc);
-				}
-				cc.style.visibility = "hidden";
-			}
-		}
-	}
-};
-
-/** Internal function; it displays the bar with the names of the weekday. */
-Calendar.prototype._displayWeekdays = function () {
-	var fdow = this.firstDayOfWeek;
-	var cell = this.firstdayname;
-	var weekend = Calendar._TT["WEEKEND"];
-	for (var i = 0; i < 7; ++i) {
-		cell.className = "day name";
-		var realday = (i + fdow) % 7;
-		if (i) {
-			cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]);
-			cell.navtype = 100;
-			cell.calendar = this;
-			cell.fdow = realday;
-			Calendar._add_evs(cell);
-		}
-		if (weekend.indexOf(realday.toString()) != -1) {
-			Calendar.addClass(cell, "weekend");
-		}
-		cell.innerHTML = Calendar._SDN[(i + fdow) % 7];
-		cell = cell.nextSibling;
-	}
-};
-
-/** Internal function.  Hides all combo boxes that might be displayed. */
-Calendar.prototype._hideCombos = function () {
-	this.monthsCombo.style.display = "none";
-	this.yearsCombo.style.display = "none";
-};
-
-/** Internal function.  Starts dragging the element. */
-Calendar.prototype._dragStart = function (ev) {
-	if (this.dragging) {
-		return;
-	}
-	this.dragging = true;
-	var posX;
-	var posY;
-	if (Calendar.is_ie) {
-		posY = window.event.clientY + document.body.scrollTop;
-		posX = window.event.clientX + document.body.scrollLeft;
-	} else {
-		posY = ev.clientY + window.scrollY;
-		posX = ev.clientX + window.scrollX;
-	}
-	var st = this.element.style;
-	this.xOffs = posX - parseInt(st.left);
-	this.yOffs = posY - parseInt(st.top);
-	with (Calendar) {
-		addEvent(document, "mousemove", calDragIt);
-		addEvent(document, "mouseup", calDragEnd);
-	}
-};
-
-// BEGIN: DATE OBJECT PATCHES
-
-/** Adds the number of days array to the Date object. */
-Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
-
-/** Constants used for time computations */
-Date.SECOND = 1000 /* milliseconds */;
-Date.MINUTE = 60 * Date.SECOND;
-Date.HOUR   = 60 * Date.MINUTE;
-Date.DAY    = 24 * Date.HOUR;
-Date.WEEK   =  7 * Date.DAY;
-
-Date.parseDate = function(str, fmt) {
-	var today = new Date();
-	var y = 0;
-	var m = -1;
-	var d = 0;
-	var a = str.split(/\W+/);
-	var b = fmt.match(/%./g);
-	var i = 0, j = 0;
-	var hr = 0;
-	var min = 0;
-	for (i = 0; i < a.length; ++i) {
-		if (!a[i])
-			continue;
-		switch (b[i]) {
-		    case "%d":
-		    case "%e":
-			d = parseInt(a[i], 10);
-			break;
-
-		    case "%m":
-			m = parseInt(a[i], 10) - 1;
-			break;
-
-		    case "%Y":
-		    case "%y":
-			y = parseInt(a[i], 10);
-			(y < 100) && (y += (y > 29) ? 1900 : 2000);
-			break;
-
-		    case "%b":
-		    case "%B":
-			for (j = 0; j < 12; ++j) {
-				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
-			}
-			break;
-
-		    case "%H":
-		    case "%I":
-		    case "%k":
-		    case "%l":
-			hr = parseInt(a[i], 10);
-			break;
-
-		    case "%P":
-		    case "%p":
-			if (/pm/i.test(a[i]) && hr < 12)
-				hr += 12;
-			else if (/am/i.test(a[i]) && hr >= 12)
-				hr -= 12;
-			break;
-
-		    case "%M":
-			min = parseInt(a[i], 10);
-			break;
-		}
-	}
-	if (isNaN(y)) y = today.getFullYear();
-	if (isNaN(m)) m = today.getMonth();
-	if (isNaN(d)) d = today.getDate();
-	if (isNaN(hr)) hr = today.getHours();
-	if (isNaN(min)) min = today.getMinutes();
-	if (y != 0 && m != -1 && d != 0)
-		return new Date(y, m, d, hr, min, 0);
-	y = 0; m = -1; d = 0;
-	for (i = 0; i < a.length; ++i) {
-		if (a[i].search(/[a-zA-Z]+/) != -1) {
-			var t = -1;
-			for (j = 0; j < 12; ++j) {
-				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
-			}
-			if (t != -1) {
-				if (m != -1) {
-					d = m+1;
-				}
-				m = t;
-			}
-		} else if (parseInt(a[i], 10) <= 12 && m == -1) {
-			m = a[i]-1;
-		} else if (parseInt(a[i], 10) > 31 && y == 0) {
-			y = parseInt(a[i], 10);
-			(y < 100) && (y += (y > 29) ? 1900 : 2000);
-		} else if (d == 0) {
-			d = a[i];
-		}
-	}
-	if (y == 0)
-		y = today.getFullYear();
-	if (m != -1 && d != 0)
-		return new Date(y, m, d, hr, min, 0);
-	return today;
-};
-
-/** Returns the number of days in the current month */
-Date.prototype.getMonthDays = function(month) {
-	var year = this.getFullYear();
-	if (typeof month == "undefined") {
-		month = this.getMonth();
-	}
-	if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
-		return 29;
-	} else {
-		return Date._MD[month];
-	}
-};
-
-/** Returns the number of day in the year. */
-Date.prototype.getDayOfYear = function() {
-	var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
-	var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
-	var time = now - then;
-	return Math.floor(time / Date.DAY);
-};
-
-/** Returns the number of the week in year, as defined in ISO 8601.
-    This function is only correct if `this` is the first day of the week. */
-Date.prototype.getWeekNumber = function() {
-	var d =  new Date(this.getFullYear(), this.getMonth(), this.getDate());
-	var days = 1000*60*60*24; // one day in milliseconds
-	
-	// get the thursday of the current week
-	var this_thursday = new Date(
-		d.valueOf() // selected date
-		- (d.getDay() % 7)*days   // previous sunday
-		+ 4*days                  // + 4 days
-	).valueOf();
-	
-	// the thursday in the first week of the year
-	var first_thursday = new Date(
-		new Date(this.getFullYear(), 0, 4).valueOf() // January 4 is in the first week by definition
-		- (d.getDay() % 7)*days   // previous sunday
-		+ 4*days                  // + 4 days
-	).valueOf();
-	
-	return Math.round((this_thursday - first_thursday) / (7*days)) + 1;
-};
-
-/** Checks date and time equality */
-Date.prototype.equalsTo = function(date) {
-	return ((this.getFullYear() == date.getFullYear()) &&
-		(this.getMonth() == date.getMonth()) &&
-		(this.getDate() == date.getDate()) &&
-		(this.getHours() == date.getHours()) &&
-		(this.getMinutes() == date.getMinutes()));
-};
-
-/** Set only the year, month, date parts (keep existing time) */
-Date.prototype.setDateOnly = function(date) {
-	var tmp = new Date(date);
-	this.setDate(1);
-	this.setFullYear(tmp.getFullYear());
-	this.setMonth(tmp.getMonth());
-	this.setDate(tmp.getDate());
-};
-
-/** Prints the date in a string according to the given format. */
-Date.prototype.print = function (str) {
-	var m = this.getMonth();
-	var d = this.getDate();
-	var y = this.getFullYear();
-	var wn = this.getWeekNumber();
-	var w = this.getDay();
-	var s = {};
-	var hr = this.getHours();
-	var pm = (hr >= 12);
-	var ir = (pm) ? (hr - 12) : hr;
-	var dy = this.getDayOfYear();
-	if (ir == 0)
-		ir = 12;
-	var min = this.getMinutes();
-	var sec = this.getSeconds();
-	s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
-	s["%A"] = Calendar._DN[w]; // full weekday name
-	s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
-	s["%B"] = Calendar._MN[m]; // full month name
-	// FIXME: %c : preferred date and time representation for the current locale
-	s["%C"] = 1 + Math.floor(y / 100); // the century number
-	s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
-	s["%e"] = d; // the day of the month (range 1 to 31)
-	// FIXME: %D : american date style: %m/%d/%y
-	// FIXME: %E, %F, %G, %g, %h (man strftime)
-	s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
-	s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
-	s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
-	s["%k"] = hr;		// hour, range 0 to 23 (24h format)
-	s["%l"] = ir;		// hour, range 1 to 12 (12h format)
-	s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
-	s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
-	s["%n"] = "\n";		// a newline character
-	s["%p"] = pm ? "PM" : "AM";
-	s["%P"] = pm ? "pm" : "am";
-	// FIXME: %r : the time in am/pm notation %I:%M:%S %p
-	// FIXME: %R : the time in 24-hour notation %H:%M
-	s["%s"] = Math.floor(this.getTime() / 1000);
-	s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
-	s["%t"] = "\t";		// a tab character
-	// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
-	s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
-	s["%u"] = w + 1;	// the day of the week (range 1 to 7, 1 = MON)
-	s["%w"] = w;		// the day of the week (range 0 to 6, 0 = SUN)
-	// FIXME: %x : preferred date representation for the current locale without the time
-	// FIXME: %X : preferred time representation for the current locale without the date
-	s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
-	s["%Y"] = y;		// year with the century
-	s["%%"] = "%";		// a literal '%' character
-
-	var re = /%./g;
-	if (!Calendar.is_ie5 && !Calendar.is_khtml)
-		return str.replace(re, function (par) { return s[par] || par; });
-
-	var a = str.match(re);
-	for (var i = 0; i < a.length; i++) {
-		var tmp = s[a[i]];
-		if (tmp) {
-			re = new RegExp(a[i], 'g');
-			str = str.replace(re, tmp);
-		}
-	}
-
-	return str;
-};
-
-Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
-Date.prototype.setFullYear = function(y) {
-	var d = new Date(this);
-	d.__msh_oldSetFullYear(y);
-	if (d.getMonth() != this.getMonth())
-		this.setDate(28);
-	this.__msh_oldSetFullYear(y);
-};
-
-// END: DATE OBJECT PATCHES
-
-
-// global object that remembers the calendar
-window._dynarch_popupCalendar = null;
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/5525a45bbbb907719075729bed82fd9497b6bd66.svn-base
--- a/.svn/pristine/55/5525a45bbbb907719075729bed82fd9497b6bd66.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-<% form_remote_tag(:url => {}, :html => { :id => "journal-#{@journal.id}-form" }) do %>
-    <%= label_tag "notes", l(:description_notes), :class => "hidden-for-sighted" %>
-    <%= text_area_tag :notes, @journal.notes,
-          :id => "journal_#{@journal.id}_notes",
-          :class => 'wiki-edit',
-          :rows => (@journal.notes.blank? ? 10 : [[10, @journal.notes.length / 50].max, 100].min) %>
-    <%= call_hook(:view_journals_notes_form_after_notes, { :journal => @journal}) %>
-    <p><%= submit_tag l(:button_save) %>
-    <%= link_to_remote l(:label_preview),
-                       { :url => preview_issue_path(:project_id => @project, :id => @journal.issue),
-                         :method => 'post',
-                         :update => "journal_#{@journal.id}_preview",
-                         :with => "Form.serialize('journal-#{@journal.id}-form')",
-                         :complete => "Element.scrollTo('journal_#{@journal.id}_preview')"
-                       }, :accesskey => accesskey(:preview) %>
-    |
-    <%= link_to l(:button_cancel), '#', :onclick => "Element.remove('journal-#{@journal.id}-form'); " +
-                                                    "Element.show('journal-#{@journal.id}-notes'); return false;" %></p>
-
-    <div id="journal_<%= @journal.id %>_preview" class="wiki"></div>
-<% end %>
-<%= wikitoolbar_for "journal_#{@journal.id}_notes" %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/5526a744674ffd2fe7e8f915bcf310ae2c2760f4.svn-base
--- a/.svn/pristine/55/5526a744674ffd2fe7e8f915bcf310ae2c2760f4.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class TimeEntryCustomField < CustomField
-  def type_name
-    :label_spent_time
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/552dd1073a880087085df9bfb9b43d69f28e0bfa.svn-base
--- a/.svn/pristine/55/552dd1073a880087085df9bfb9b43d69f28e0bfa.svn-base
+++ /dev/null
@@ -1,49 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class DefaultDataTest < ActiveSupport::TestCase
-  include Redmine::I18n
-  fixtures :roles
-
-  def test_no_data
-    assert !Redmine::DefaultData::Loader::no_data?
-    Role.delete_all("builtin = 0")
-    Tracker.delete_all
-    IssueStatus.delete_all
-    Enumeration.delete_all
-    assert Redmine::DefaultData::Loader::no_data?
-  end
-
-  def test_load
-    valid_languages.each do |lang|
-      begin
-        Role.delete_all("builtin = 0")
-        Tracker.delete_all
-        IssueStatus.delete_all
-        Enumeration.delete_all
-        assert Redmine::DefaultData::Loader::load(lang)
-        assert_not_nil DocumentCategory.first
-        assert_not_nil IssuePriority.first
-        assert_not_nil TimeEntryActivity.first
-      rescue ActiveRecord::RecordInvalid => e
-        assert false, ":#{lang} default data is invalid (#{e.message})."
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/554119d7707f8ea022be31bc48239ea95d10b4bf.svn-base
--- a/.svn/pristine/55/554119d7707f8ea022be31bc48239ea95d10b4bf.svn-base
+++ /dev/null
@@ -1,161 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class CustomField < ActiveRecord::Base
-  has_many :custom_values, :dependent => :delete_all
-  acts_as_list :scope => 'type = \'#{self.class}\''
-  serialize :possible_values
-
-  validates_presence_of :name, :field_format
-  validates_uniqueness_of :name, :scope => :type
-  validates_length_of :name, :maximum => 30
-  validates_inclusion_of :field_format, :in => Redmine::CustomFieldFormat.available_formats
-
-  validate :validate_values
-
-  def initialize(attributes = nil)
-    super
-    self.possible_values ||= []
-  end
-
-  def before_validation
-    # make sure these fields are not searchable
-    self.searchable = false if %w(int float date bool).include?(field_format)
-    true
-  end
-
-  def validate_values
-    if self.field_format == "list"
-      errors.add(:possible_values, :blank) if self.possible_values.nil? || self.possible_values.empty?
-      errors.add(:possible_values, :invalid) unless self.possible_values.is_a? Array
-    end
-
-    if regexp.present?
-      begin
-        Regexp.new(regexp)
-      rescue
-        errors.add(:regexp, :invalid)
-      end
-    end
-
-    # validate default value
-    v = CustomValue.new(:custom_field => self.clone, :value => default_value, :customized => nil)
-    v.custom_field.is_required = false
-    errors.add(:default_value, :invalid) unless v.valid?
-  end
-
-  def possible_values_options(obj=nil)
-    case field_format
-    when 'user', 'version'
-      if obj.respond_to?(:project) && obj.project
-        case field_format
-        when 'user'
-          obj.project.users.sort.collect {|u| [u.to_s, u.id.to_s]}
-        when 'version'
-          obj.project.shared_versions.sort.collect {|u| [u.to_s, u.id.to_s]}
-        end
-      elsif obj.is_a?(Array)
-        obj.collect {|o| possible_values_options(o)}.inject {|memo, v| memo & v}
-      else
-        []
-      end
-    else
-      read_attribute :possible_values
-    end
-  end
-
-  def possible_values(obj=nil)
-    case field_format
-    when 'user', 'version'
-      possible_values_options(obj).collect(&:last)
-    else
-      read_attribute :possible_values
-    end
-  end
-
-  # Makes possible_values accept a multiline string
-  def possible_values=(arg)
-    if arg.is_a?(Array)
-      write_attribute(:possible_values, arg.compact.collect(&:strip).select {|v| !v.blank?})
-    else
-      self.possible_values = arg.to_s.split(/[\n\r]+/)
-    end
-  end
-
-  def cast_value(value)
-    casted = nil
-    unless value.blank?
-      case field_format
-      when 'string', 'text', 'list'
-        casted = value
-      when 'date'
-        casted = begin; value.to_date; rescue; nil end
-      when 'bool'
-        casted = (value == '1' ? true : false)
-      when 'int'
-        casted = value.to_i
-      when 'float'
-        casted = value.to_f
-      when 'user', 'version'
-        casted = (value.blank? ? nil : field_format.classify.constantize.find_by_id(value.to_i))
-      end
-    end
-    casted
-  end
-
-  # Returns a ORDER BY clause that can used to sort customized
-  # objects by their value of the custom field.
-  # Returns false, if the custom field can not be used for sorting.
-  def order_statement
-    case field_format
-      when 'string', 'text', 'list', 'date', 'bool'
-        # COALESCE is here to make sure that blank and NULL values are sorted equally
-        "COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" +
-          " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" +
-          " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" +
-          " AND cv_sort.custom_field_id=#{id} LIMIT 1), '')"
-      when 'int', 'float'
-        # Make the database cast values into numeric
-        # Postgresql will raise an error if a value can not be casted!
-        # CustomValue validations should ensure that it doesn't occur
-        "(SELECT CAST(cv_sort.value AS decimal(60,3)) FROM #{CustomValue.table_name} cv_sort" +
-          " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" +
-          " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" +
-          " AND cv_sort.custom_field_id=#{id} AND cv_sort.value <> '' AND cv_sort.value IS NOT NULL LIMIT 1)"
-      else
-        nil
-    end
-  end
-
-  def <=>(field)
-    position <=> field.position
-  end
-
-  def self.customized_class
-    self.name =~ /^(.+)CustomField$/
-    begin; $1.constantize; rescue nil; end
-  end
-
-  # to move in project_custom_field
-  def self.for_all
-    find(:all, :conditions => ["is_for_all=?", true], :order => 'position')
-  end
-
-  def type_name
-    nil
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/5598548a6818651218cba8411c616699a4a94a8f.svn-base
--- /dev/null
+++ b/.svn/pristine/55/5598548a6818651218cba8411c616699a4a94a8f.svn-base
@@ -0,0 +1,9 @@
+class AddAttachmentsDiskDirectory < ActiveRecord::Migration
+  def up
+    add_column :attachments, :disk_directory, :string
+  end
+
+  def down
+    remove_column :attachments, :disk_directory
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/559c056bb0193e75aa2a9f749bccfd079cee7e4f.svn-base
--- /dev/null
+++ b/.svn/pristine/55/559c056bb0193e75aa2a9f749bccfd079cee7e4f.svn-base
@@ -0,0 +1,22 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class DocumentObserver < ActiveRecord::Observer
+  def after_create(document)
+    Mailer.document_added(document).deliver if Setting.notified_events.include?('document_added')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/55bd4be64003cd23d5039420dcbb14a174a1cede.svn-base
--- a/.svn/pristine/55/55bd4be64003cd23d5039420dcbb14a174a1cede.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class AppAndPluginController < ApplicationController
-  def an_action
-    render_class_and_action 'from alpha_plugin'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/55/55c44f6ea2479c136aea73b874b97160faaae047.svn-base
--- a/.svn/pristine/55/55c44f6ea2479c136aea73b874b97160faaae047.svn-base
+++ /dev/null
@@ -1,46 +0,0 @@
-module CodeRay
-module Encoders
-  
-  # Concats the tokens into a single string, resulting in the original
-  # code string if no tokens were removed.
-  # 
-  # Alias: +plain+, +plaintext+
-  # 
-  # == Options
-  # 
-  # === :separator
-  # A separator string to join the tokens.
-  # 
-  # Default: empty String
-  class Text < Encoder
-    
-    register_for :text
-    
-    FILE_EXTENSION = 'txt'
-    
-    DEFAULT_OPTIONS = {
-      :separator => nil
-    }
-    
-    def text_token text, kind
-      super
-      
-      if @first
-        @first = false
-      else
-        @out << @sep
-      end if @sep
-    end
-    
-  protected
-    def setup options
-      super
-      
-      @first = true
-      @sep = options[:separator]
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/56/560f0241ba8e6899cca067c7cd63919a0ce16a9c.svn-base
--- a/.svn/pristine/56/560f0241ba8e6899cca067c7cd63919a0ce16a9c.svn-base
+++ /dev/null
@@ -1,65 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # = Debug Scanner
-  # 
-  # Interprets the output of the Encoders::Debug encoder.
-  class Debug < Scanner
-    
-    register_for :debug
-    title 'CodeRay Token Dump Import'
-    
-  protected
-    
-    def scan_tokens encoder, options
-      
-      opened_tokens = []
-      
-      until eos?
-        
-        if match = scan(/\s+/)
-          encoder.text_token match, :space
-          
-        elsif match = scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) \)? /x)
-          kind = self[1].to_sym
-          match = self[2].gsub(/\\(.)/m, '\1')
-          unless TokenKinds.has_key? kind
-            kind = :error
-            match = matched
-          end
-          encoder.text_token match, kind
-          
-        elsif match = scan(/ (\w+) ([<\[]) /x)
-          kind = self[1].to_sym
-          opened_tokens << kind
-          case self[2]
-          when '<'
-            encoder.begin_group kind
-          when '['
-            encoder.begin_line kind
-          else
-            raise 'CodeRay bug: This case should not be reached.'
-          end
-          
-        elsif !opened_tokens.empty? && match = scan(/ > /x)
-          encoder.end_group opened_tokens.pop
-          
-        elsif !opened_tokens.empty? && match = scan(/ \] /x)
-          encoder.end_line opened_tokens.pop
-          
-        else
-          encoder.text_token getch, :space
-          
-        end
-        
-      end
-      
-      encoder.end_group opened_tokens.pop until opened_tokens.empty?
-      
-      encoder
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/56/5616c9d52a62f8dbe0d12f53a6285e1110cf74e0.svn-base
--- a/.svn/pristine/56/5616c9d52a62f8dbe0d12f53a6285e1110cf74e0.svn-base
+++ /dev/null
@@ -1,115 +0,0 @@
-module CodeRay
-module Encoders
-
-  class HTML
-
-    module Numbering  # :nodoc:
-
-      def self.number! output, mode = :table, options = {}
-        return self unless mode
-
-        options = DEFAULT_OPTIONS.merge options
-
-        start = options[:line_number_start]
-        unless start.is_a? Integer
-          raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start
-        end
-        
-        anchor_prefix = options[:line_number_anchors]
-        anchor_prefix = 'line' if anchor_prefix == true
-        anchor_prefix = anchor_prefix.to_s[/\w+/] if anchor_prefix
-        anchoring =
-          if anchor_prefix
-            proc do |line|
-              line = line.to_s
-              anchor = anchor_prefix + line
-              "<a href=\"##{anchor}\" name=\"#{anchor}\">#{line}</a>"
-            end
-          else
-            proc { |line| line.to_s }  # :to_s.to_proc in Ruby 1.8.7+
-          end
-        
-        bold_every = options[:bold_every]
-        highlight_lines = options[:highlight_lines]
-        bolding =
-          if bold_every == false && highlight_lines == nil
-            anchoring
-          elsif highlight_lines.is_a? Enumerable
-            highlight_lines = highlight_lines.to_set
-            proc do |line|
-              if highlight_lines.include? line
-                "<strong class=\"highlighted\">#{anchoring[line]}</strong>"  # highlighted line numbers in bold
-              else
-                anchoring[line]
-              end
-            end
-          elsif bold_every.is_a? Integer
-            raise ArgumentError, ":bolding can't be 0." if bold_every == 0
-            proc do |line|
-              if line % bold_every == 0
-                "<strong>#{anchoring[line]}</strong>"  # every bold_every-th number in bold
-              else
-                anchoring[line]
-              end
-            end
-          else
-            raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
-          end
-        
-        line_count = output.count("\n")
-        position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n)
-        if position_of_last_newline
-          after_last_newline = output[position_of_last_newline + 1 .. -1]
-          ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
-          line_count += 1 if not ends_with_newline
-        end
-        
-        case mode
-        when :inline
-          max_width = (start + line_count).to_s.size
-          line_number = start
-          nesting = []
-          output.gsub!(/^.*$\n?/) do |line|
-            line.chomp!
-            open = nesting.join
-            line.scan(%r!<(/)?span[^>]*>?!) do |close,|
-              if close
-                nesting.pop
-              else
-                nesting << $&
-              end
-            end
-            close = '</span>' * nesting.size
-            
-            line_number_text = bolding.call line_number
-            indent = ' ' * (max_width - line_number.to_s.size)  # TODO: Optimize (10^x)
-            line_number += 1
-            "<span class=\"line-numbers\">#{indent}#{line_number_text}</span>#{open}#{line}#{close}\n"
-          end
-
-        when :table
-          line_numbers = (start ... start + line_count).map(&bolding).join("\n")
-          line_numbers << "\n"
-          line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers)
-
-          output.gsub!(/<\/div>\n/, '</div>')
-          output.wrap_in! line_numbers_table_template
-          output.wrapped_in = :div
-
-        when :list
-          raise NotImplementedError, 'The :list option is no longer available. Use :table.'
-
-        else
-          raise ArgumentError, 'Unknown value %p for mode: expected one of %p' %
-            [mode, [:table, :inline]]
-        end
-
-        output
-      end
-
-    end
-
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/56/56225b936777b98c482ec9e85d159d74d839691e.svn-base
--- /dev/null
+++ b/.svn/pristine/56/56225b936777b98c482ec9e85d159d74d839691e.svn-base
@@ -0,0 +1,362 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../test_helper', __FILE__)
+
+class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
+  include ApplicationHelper
+  include ActionView::Helpers::TextHelper
+  include ActionView::Helpers::SanitizeHelper
+  include ERB::Util
+  extend ActionView::Helpers::SanitizeHelper::ClassMethods
+
+  fixtures :projects, :roles, :enabled_modules, :users,
+                      :repositories, :changesets,
+                      :trackers, :issue_statuses, :issues,
+                      :versions, :documents,
+                      :wikis, :wiki_pages, :wiki_contents,
+                      :boards, :messages,
+                      :attachments
+
+  def setup
+    super
+    @project = nil
+  end
+
+  def teardown
+  end
+
+  def test_macro_registration
+    Redmine::WikiFormatting::Macros.register do
+      macro :foo do |obj, args|
+        "Foo: #{args.size} (#{args.join(',')}) (#{args.class.name})"
+      end
+    end
+
+    assert_equal '<p>Foo: 0 () (Array)</p>', textilizable("{{foo}}")
+    assert_equal '<p>Foo: 0 () (Array)</p>', textilizable("{{foo()}}")
+    assert_equal '<p>Foo: 1 (arg1) (Array)</p>', textilizable("{{foo(arg1)}}")
+    assert_equal '<p>Foo: 2 (arg1,arg2) (Array)</p>', textilizable("{{foo(arg1, arg2)}}")
+  end
+
+  def test_macro_registration_parse_args_set_to_false_should_disable_arguments_parsing
+    Redmine::WikiFormatting::Macros.register do
+      macro :bar, :parse_args => false do |obj, args|
+        "Bar: (#{args}) (#{args.class.name})"
+      end
+    end
+
+    assert_equal '<p>Bar: (args, more args) (String)</p>', textilizable("{{bar(args, more args)}}")
+    assert_equal '<p>Bar: () (String)</p>', textilizable("{{bar}}")
+    assert_equal '<p>Bar: () (String)</p>', textilizable("{{bar()}}")
+  end
+
+  def test_macro_registration_with_3_args_should_receive_text_argument
+    Redmine::WikiFormatting::Macros.register do
+      macro :baz do |obj, args, text|
+        "Baz: (#{args.join(',')}) (#{text.class.name}) (#{text})"
+      end
+    end
+
+    assert_equal "<p>Baz: () (NilClass) ()</p>", textilizable("{{baz}}")
+    assert_equal "<p>Baz: () (NilClass) ()</p>", textilizable("{{baz()}}")
+    assert_equal "<p>Baz: () (String) (line1\nline2)</p>", textilizable("{{baz()\nline1\nline2\n}}")
+    assert_equal "<p>Baz: (arg1,arg2) (String) (line1\nline2)</p>", textilizable("{{baz(arg1, arg2)\nline1\nline2\n}}")
+  end
+
+  def test_macro_name_with_upper_case
+    Redmine::WikiFormatting::Macros.macro(:UpperCase) {|obj, args| "Upper"}
+
+    assert_equal "<p>Upper</p>", textilizable("{{UpperCase}}")
+  end
+
+  def test_multiple_macros_on_the_same_line
+    Redmine::WikiFormatting::Macros.macro :foo do |obj, args|
+      args.any? ? "args: #{args.join(',')}" : "no args" 
+    end
+
+    assert_equal '<p>no args no args</p>', textilizable("{{foo}} {{foo}}")
+    assert_equal '<p>args: a,b no args</p>', textilizable("{{foo(a,b)}} {{foo}}")
+    assert_equal '<p>args: a,b args: c,d</p>', textilizable("{{foo(a,b)}} {{foo(c,d)}}")
+    assert_equal '<p>no args args: c,d</p>', textilizable("{{foo}} {{foo(c,d)}}")
+  end
+
+  def test_macro_should_receive_the_object_as_argument_when_with_object_and_attribute
+    issue = Issue.find(1)
+    issue.description = "{{hello_world}}"
+    assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(issue, :description)
+  end
+
+  def test_macro_should_receive_the_object_as_argument_when_called_with_object_option
+    text = "{{hello_world}}"
+    assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(text, :object => Issue.find(1))
+  end
+
+  def test_extract_macro_options_should_with_args
+    options = extract_macro_options(["arg1", "arg2"], :foo, :size)
+    assert_equal([["arg1", "arg2"], {}], options)
+  end
+
+  def test_extract_macro_options_should_with_options
+    options = extract_macro_options(["foo=bar", "size=2"], :foo, :size)
+    assert_equal([[], {:foo => "bar", :size => "2"}], options)
+  end
+
+  def test_extract_macro_options_should_with_args_and_options
+    options = extract_macro_options(["arg1", "arg2", "foo=bar", "size=2"], :foo, :size)
+    assert_equal([["arg1", "arg2"], {:foo => "bar", :size => "2"}], options)
+  end
+
+  def test_extract_macro_options_should_parse_options_lazily
+    options = extract_macro_options(["params=x=1&y=2"], :params)
+    assert_equal([[], {:params => "x=1&y=2"}], options)
+  end
+
+  def test_macro_exception_should_be_displayed
+    Redmine::WikiFormatting::Macros.macro :exception do |obj, args|
+      raise "My message"
+    end
+
+    text = "{{exception}}"
+    assert_include '<div class="flash error">Error executing the <strong>exception</strong> macro (My message)</div>', textilizable(text)
+  end
+
+  def test_macro_arguments_should_not_be_parsed_by_formatters
+    text = '{{hello_world(http://www.redmine.org, #1)}}'
+    assert_include 'Arguments: http://www.redmine.org, #1', textilizable(text)
+  end
+
+  def test_exclamation_mark_should_not_run_macros
+    text = "!{{hello_world}}"
+    assert_equal '<p>{{hello_world}}</p>', textilizable(text)
+  end
+
+  def test_exclamation_mark_should_escape_macros
+    text = "!{{hello_world(<tag>)}}"
+    assert_equal '<p>{{hello_world(&lt;tag&gt;)}}</p>', textilizable(text)
+  end
+
+  def test_unknown_macros_should_not_be_replaced
+    text = "{{unknown}}"
+    assert_equal '<p>{{unknown}}</p>', textilizable(text)
+  end
+
+  def test_unknown_macros_should_parsed_as_text
+    text = "{{unknown(*test*)}}"
+    assert_equal '<p>{{unknown(<strong>test</strong>)}}</p>', textilizable(text)
+  end
+
+  def test_unknown_macros_should_be_escaped
+    text = "{{unknown(<tag>)}}"
+    assert_equal '<p>{{unknown(&lt;tag&gt;)}}</p>', textilizable(text)
+  end
+
+  def test_html_safe_macro_output_should_not_be_escaped
+    Redmine::WikiFormatting::Macros.macro :safe_macro do |obj, args|
+      "<tag>".html_safe
+    end
+    assert_equal '<p><tag></p>', textilizable("{{safe_macro}}")
+  end
+
+  def test_macro_hello_world
+    text = "{{hello_world}}"
+    assert textilizable(text).match(/Hello world!/)
+  end
+
+  def test_macro_hello_world_should_escape_arguments
+    text = "{{hello_world(<tag>)}}"
+    assert_include 'Arguments: &lt;tag&gt;', textilizable(text)
+  end
+
+  def test_macro_macro_list
+    text = "{{macro_list}}"
+    assert_match %r{<code>hello_world</code>}, textilizable(text)
+  end
+
+  def test_macro_include
+    @project = Project.find(1)
+    # include a page of the current project wiki
+    text = "{{include(Another page)}}"
+    assert_include 'This is a link to a ticket', textilizable(text)
+
+    @project = nil
+    # include a page of a specific project wiki
+    text = "{{include(ecookbook:Another page)}}"
+    assert_include 'This is a link to a ticket', textilizable(text)
+
+    text = "{{include(ecookbook:)}}"
+    assert_include 'CookBook documentation', textilizable(text)
+
+    text = "{{include(unknowidentifier:somepage)}}"
+    assert_include 'Page not found', textilizable(text)
+  end
+
+  def test_macro_collapse
+    text = "{{collapse\n*Collapsed* block of text\n}}"
+    result = textilizable(text)
+
+    assert_select_in result, 'div.collapsed-text'
+    assert_select_in result, 'strong', :text => 'Collapsed'
+    assert_select_in result, 'a.collapsible.collapsed', :text => 'Show'
+    assert_select_in result, 'a.collapsible', :text => 'Hide'
+  end
+
+  def test_macro_collapse_with_one_arg
+    text = "{{collapse(Example)\n*Collapsed* block of text\n}}"
+    result = textilizable(text)
+
+    assert_select_in result, 'div.collapsed-text'
+    assert_select_in result, 'strong', :text => 'Collapsed'
+    assert_select_in result, 'a.collapsible.collapsed', :text => 'Example'
+    assert_select_in result, 'a.collapsible', :text => 'Example'
+  end
+
+  def test_macro_collapse_with_two_args
+    text = "{{collapse(Show example, Hide example)\n*Collapsed* block of text\n}}"
+    result = textilizable(text)
+
+    assert_select_in result, 'div.collapsed-text'
+    assert_select_in result, 'strong', :text => 'Collapsed'
+    assert_select_in result, 'a.collapsible.collapsed', :text => 'Show example'
+    assert_select_in result, 'a.collapsible', :text => 'Hide example'
+  end
+
+  def test_macro_child_pages
+    expected =  "<p><ul class=\"pages-hierarchy\">\n" +
+                 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
+                 "<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
+                 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
+                 "</ul>\n</p>"
+
+    @project = Project.find(1)
+    # child pages of the current wiki page
+    assert_equal expected, textilizable("{{child_pages}}", :object => WikiPage.find(2).content)
+    # child pages of another page
+    assert_equal expected, textilizable("{{child_pages(Another_page)}}", :object => WikiPage.find(1).content)
+
+    @project = Project.find(2)
+    assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page)}}", :object => WikiPage.find(1).content)
+  end
+
+  def test_macro_child_pages_with_parent_option
+    expected =  "<p><ul class=\"pages-hierarchy\">\n" +
+                 "<li><a href=\"/projects/ecookbook/wiki/Another_page\">Another page</a>\n" +
+                 "<ul class=\"pages-hierarchy\">\n" +
+                 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
+                 "<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
+                 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
+                 "</ul>\n</li>\n</ul>\n</p>"
+
+    @project = Project.find(1)
+    # child pages of the current wiki page
+    assert_equal expected, textilizable("{{child_pages(parent=1)}}", :object => WikiPage.find(2).content)
+    # child pages of another page
+    assert_equal expected, textilizable("{{child_pages(Another_page, parent=1)}}", :object => WikiPage.find(1).content)
+
+    @project = Project.find(2)
+    assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page, parent=1)}}", :object => WikiPage.find(1).content)
+  end
+
+  def test_macro_child_pages_with_depth_option
+    expected =  "<p><ul class=\"pages-hierarchy\">\n" +
+                 "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a></li>\n" +
+                 "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
+                 "</ul>\n</p>"
+
+    @project = Project.find(1)
+    assert_equal expected, textilizable("{{child_pages(depth=1)}}", :object => WikiPage.find(2).content)
+  end
+
+  def test_macro_child_pages_without_wiki_page_should_fail
+    assert_match /can be called from wiki pages only/, textilizable("{{child_pages}}")
+  end
+
+  def test_macro_thumbnail
+    assert_equal '<p><a href="/attachments/17" class="thumbnail" title="testfile.PNG"><img alt="testfile.PNG" src="/attachments/thumbnail/17" /></a></p>',
+      textilizable("{{thumbnail(testfile.png)}}", :object => Issue.find(14))
+  end
+
+  def test_macro_thumbnail_with_size
+    assert_equal '<p><a href="/attachments/17" class="thumbnail" title="testfile.PNG"><img alt="testfile.PNG" src="/attachments/thumbnail/17/200" /></a></p>',
+      textilizable("{{thumbnail(testfile.png, size=200)}}", :object => Issue.find(14))
+  end
+
+  def test_macro_thumbnail_with_title
+    assert_equal '<p><a href="/attachments/17" class="thumbnail" title="Cool image"><img alt="testfile.PNG" src="/attachments/thumbnail/17" /></a></p>',
+      textilizable("{{thumbnail(testfile.png, title=Cool image)}}", :object => Issue.find(14))
+  end
+
+  def test_macro_thumbnail_with_invalid_filename_should_fail
+    assert_include 'test.png not found',
+      textilizable("{{thumbnail(test.png)}}", :object => Issue.find(14))
+  end
+
+  def test_macros_should_not_be_executed_in_pre_tags
+    text = <<-RAW
+{{hello_world(foo)}}
+
+<pre>
+{{hello_world(pre)}}
+!{{hello_world(pre)}}
+</pre>
+
+{{hello_world(bar)}}
+RAW
+
+    expected = <<-EXPECTED
+<p>Hello world! Object: NilClass, Arguments: foo and no block of text.</p>
+
+<pre>
+{{hello_world(pre)}}
+!{{hello_world(pre)}}
+</pre>
+
+<p>Hello world! Object: NilClass, Arguments: bar and no block of text.</p>
+EXPECTED
+
+    assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
+  end
+
+  def test_macros_should_be_escaped_in_pre_tags
+    text = "<pre>{{hello_world(<tag>)}}</pre>"
+    assert_equal "<pre>{{hello_world(&lt;tag&gt;)}}</pre>", textilizable(text)
+  end
+
+  def test_macros_should_not_mangle_next_macros_outputs
+    text = '{{macro(2)}} !{{macro(2)}} {{hello_world(foo)}}'
+    assert_equal '<p>{{macro(2)}} {{macro(2)}} Hello world! Object: NilClass, Arguments: foo and no block of text.</p>', textilizable(text)
+  end
+
+  def test_macros_with_text_should_not_mangle_following_macros
+    text = <<-RAW
+{{hello_world
+Line of text
+}}
+
+{{hello_world
+Another line of text
+}}
+RAW
+
+    expected = <<-EXPECTED
+<p>Hello world! Object: NilClass, Called with no argument and a 12 bytes long block of text.</p>
+<p>Hello world! Object: NilClass, Called with no argument and a 20 bytes long block of text.</p>
+EXPECTED
+
+    assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/56/56493cc79ece7ebee244c20a035044b3abd7b20d.svn-base
--- a/.svn/pristine/56/56493cc79ece7ebee244c20a035044b3abd7b20d.svn-base
+++ /dev/null
@@ -1,192 +0,0 @@
-module CodeRay
-module Scanners
-
-  class CSS < Scanner
-    
-    register_for :css
-    
-    KINDS_NOT_LOC = [
-      :comment,
-      :class, :pseudo_class, :type,
-      :constant, :directive,
-      :key, :value, :operator, :color, :float, :string,
-      :error, :important,
-    ]  # :nodoc:
-    
-    module RE  # :nodoc:
-      Hex = /[0-9a-fA-F]/
-      Unicode = /\\#{Hex}{1,6}(?:\r\n|\s)?/ # differs from standard because it allows uppercase hex too
-      Escape = /#{Unicode}|\\[^\r\n\f0-9a-fA-F]/
-      NMChar = /[-_a-zA-Z0-9]|#{Escape}/
-      NMStart = /[_a-zA-Z]|#{Escape}/
-      NL = /\r\n|\r|\n|\f/
-      String1 = /"(?:[^\n\r\f\\"]|\\#{NL}|#{Escape})*"?/  # TODO: buggy regexp
-      String2 = /'(?:[^\n\r\f\\']|\\#{NL}|#{Escape})*'?/  # TODO: buggy regexp
-      String = /#{String1}|#{String2}/
-      
-      HexColor = /#(?:#{Hex}{6}|#{Hex}{3})/
-      Color = /#{HexColor}/
-      
-      Num = /-?(?:[0-9]+|[0-9]*\.[0-9]+)/
-      Name = /#{NMChar}+/
-      Ident = /-?#{NMStart}#{NMChar}*/
-      AtKeyword = /@#{Ident}/
-      Percentage = /#{Num}%/
-      
-      reldimensions = %w[em ex px]
-      absdimensions = %w[in cm mm pt pc]
-      Unit = Regexp.union(*(reldimensions + absdimensions))
-      
-      Dimension = /#{Num}#{Unit}/
-      
-      Comment = %r! /\* (?: .*? \*/ | .* ) !mx
-      Function = /(?:url|alpha|attr|counters?)\((?:[^)\n\r\f]|\\\))*\)?/
-      
-      Id = /##{Name}/
-      Class = /\.#{Name}/
-      PseudoClass = /:#{Name}/
-      AttributeSelector = /\[[^\]]*\]?/
-    end
-    
-  protected
-    
-    def scan_tokens encoder, options
-      
-      value_expected = nil
-      states = [:initial]
-      
-      until eos?
-        
-        if match = scan(/\s+/)
-          encoder.text_token match, :space
-          
-        elsif case states.last
-          when :initial, :media
-            if match = scan(/(?>#{RE::Ident})(?!\()|\*/ox)
-              encoder.text_token match, :type
-              next
-            elsif match = scan(RE::Class)
-              encoder.text_token match, :class
-              next
-            elsif match = scan(RE::Id)
-              encoder.text_token match, :constant
-              next
-            elsif match = scan(RE::PseudoClass)
-              encoder.text_token match, :pseudo_class
-              next
-            elsif match = scan(RE::AttributeSelector)
-              # TODO: Improve highlighting inside of attribute selectors.
-              encoder.text_token match[0,1], :operator
-              encoder.text_token match[1..-2], :attribute_name if match.size > 2
-              encoder.text_token match[-1,1], :operator if match[-1] == ?]
-              next
-            elsif match = scan(/@media/)
-              encoder.text_token match, :directive
-              states.push :media_before_name
-              next
-            end
-          
-          when :block
-            if match = scan(/(?>#{RE::Ident})(?!\()/ox)
-              if value_expected
-                encoder.text_token match, :value
-              else
-                encoder.text_token match, :key
-              end
-              next
-            end
-            
-          when :media_before_name
-            if match = scan(RE::Ident)
-              encoder.text_token match, :type
-              states[-1] = :media_after_name
-              next
-            end
-          
-          when :media_after_name
-            if match = scan(/\{/)
-              encoder.text_token match, :operator
-              states[-1] = :media
-              next
-            end
-          
-          else
-            #:nocov:
-            raise_inspect 'Unknown state', encoder
-            #:nocov:
-            
-          end
-          
-        elsif match = scan(/\/\*(?:.*?\*\/|\z)/m)
-          encoder.text_token match, :comment
-          
-        elsif match = scan(/\{/)
-          value_expected = false
-          encoder.text_token match, :operator
-          states.push :block
-          
-        elsif match = scan(/\}/)
-          value_expected = false
-          if states.last == :block || states.last == :media
-            encoder.text_token match, :operator
-            states.pop
-          else
-            encoder.text_token match, :error
-          end
-          
-        elsif match = scan(/#{RE::String}/o)
-          encoder.begin_group :string
-          encoder.text_token match[0, 1], :delimiter
-          encoder.text_token match[1..-2], :content if match.size > 2
-          encoder.text_token match[-1, 1], :delimiter if match.size >= 2
-          encoder.end_group :string
-          
-        elsif match = scan(/#{RE::Function}/o)
-          encoder.begin_group :string
-          start = match[/^\w+\(/]
-          encoder.text_token start, :delimiter
-          if match[-1] == ?)
-            encoder.text_token match[start.size..-2], :content
-            encoder.text_token ')', :delimiter
-          else
-            encoder.text_token match[start.size..-1], :content
-          end
-          encoder.end_group :string
-          
-        elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox)
-          encoder.text_token match, :float
-          
-        elsif match = scan(/#{RE::Color}/o)
-          encoder.text_token match, :color
-          
-        elsif match = scan(/! *important/)
-          encoder.text_token match, :important
-          
-        elsif match = scan(/(?:rgb|hsl)a?\([^()\n]*\)?/)
-          encoder.text_token match, :color
-          
-        elsif match = scan(RE::AtKeyword)
-          encoder.text_token match, :directive
-          
-        elsif match = scan(/ [+>:;,.=()\/] /x)
-          if match == ':'
-            value_expected = true
-          elsif match == ';'
-            value_expected = false
-          end
-          encoder.text_token match, :operator
-          
-        else
-          encoder.text_token getch, :error
-          
-        end
-        
-      end
-      
-      encoder
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/57/570f0eb4fa534b2c22e5b144e19ab45bcea2dbda.svn-base
--- /dev/null
+++ b/.svn/pristine/57/570f0eb4fa534b2c22e5b144e19ab45bcea2dbda.svn-base
@@ -0,0 +1,87 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module SafeAttributes
+    def self.included(base)
+      base.extend(ClassMethods)
+    end
+
+    module ClassMethods
+      # Declares safe attributes
+      # An optional Proc can be given for conditional inclusion
+      #
+      # Example:
+      #   safe_attributes 'title', 'pages'
+      #   safe_attributes 'isbn', :if => {|book, user| book.author == user}
+      def safe_attributes(*args)
+        @safe_attributes ||= []
+        if args.empty?
+          if superclass.include?(Redmine::SafeAttributes)
+            @safe_attributes + superclass.safe_attributes 
+          else
+            @safe_attributes
+          end
+        else
+          options = args.last.is_a?(Hash) ? args.pop : {}
+          @safe_attributes << [args, options]
+        end
+      end
+    end
+
+    # Returns an array that can be safely set by user or current user
+    #
+    # Example:
+    #   book.safe_attributes # => ['title', 'pages']
+    #   book.safe_attributes(book.author) # => ['title', 'pages', 'isbn']
+    def safe_attribute_names(user=nil)
+      return @safe_attribute_names if @safe_attribute_names && user.nil?
+      names = []
+      self.class.safe_attributes.collect do |attrs, options|
+        if options[:if].nil? || options[:if].call(self, user || User.current)
+          names += attrs.collect(&:to_s)
+        end
+      end
+      names.uniq!
+      @safe_attribute_names = names if user.nil?
+      names
+    end
+
+    # Returns true if attr can be set by user or the current user
+    def safe_attribute?(attr, user=nil)
+      safe_attribute_names(user).include?(attr.to_s)
+    end
+
+    # Returns a hash with unsafe attributes removed
+    # from the given attrs hash
+    #
+    # Example:
+    #   book.delete_unsafe_attributes({'title' => 'My book', 'foo' => 'bar'})
+    #   # => {'title' => 'My book'}
+    def delete_unsafe_attributes(attrs, user=User.current)
+      safe = safe_attribute_names(user)
+      attrs.dup.delete_if {|k,v| !safe.include?(k)}
+    end
+
+    # Sets attributes from attrs that are safe
+    # attrs is a Hash with string keys
+    def safe_attributes=(attrs, user=User.current)
+      return unless attrs.is_a?(Hash)
+      self.attributes = delete_unsafe_attributes(attrs, user)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/57/5731b1ac892937f048c7117fb4cf074f794ff9f0.svn-base
--- /dev/null
+++ b/.svn/pristine/57/5731b1ac892937f048c7117fb4cf074f794ff9f0.svn-base
@@ -0,0 +1,58 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::QueriesTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :queries
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "/queries" do
+    context "GET" do
+
+      should "return queries" do
+        get '/queries.xml'
+
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+        assert_tag :tag => 'queries',
+          :attributes => {:type => 'array'},
+          :child => {
+            :tag => 'query',
+            :child => {
+              :tag => 'id',
+              :content => '4',
+              :sibling => {
+                :tag => 'name',
+                :content => 'Public query for all projects'
+              }
+            }
+          }
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/57/5743d81934695d3c76c9de1e610ada18ddc3f631.svn-base
--- a/.svn/pristine/57/5743d81934695d3c76c9de1e610ada18ddc3f631.svn-base
+++ /dev/null
@@ -1,138 +0,0 @@
-# One of the magic features that that engines plugin provides is the ability to
-# override selected methods in controllers and helpers from your application.
-# This is achieved by trapping requests to load those files, and then mixing in
-# code from plugins (in the order the plugins were loaded) before finally loading
-# any versions from the main +app+ directory.
-#
-# The behaviour of this extension is output to the log file for help when
-# debugging.
-#
-# == Example
-#
-# A plugin contains the following controller in <tt>plugin/app/controllers/my_controller.rb</tt>:
-#
-#   class MyController < ApplicationController
-#     def index
-#       @name = "HAL 9000"
-#     end
-#     def list
-#       @robots = Robot.find(:all)
-#     end
-#   end
-#
-# In one application that uses this plugin, we decide that the name used in the
-# index action should be "Robbie", not "HAL 9000". To override this single method,
-# we create the corresponding controller in our application 
-# (<tt>RAILS_ROOT/app/controllers/my_controller.rb</tt>), and redefine the method:
-#
-#   class MyController < ApplicationController
-#     def index
-#       @name = "Robbie"
-#     end
-#   end
-#
-# The list method remains as it was defined in the plugin controller.
-#
-# The same basic principle applies to helpers, and also views and partials (although
-# view overriding is performed in Engines::RailsExtensions::Templates; see that
-# module for more information).
-#
-# === What about models?
-#
-# Unfortunately, it's not possible to provide this kind of magic for models.
-# The only reason why it's possible for controllers and helpers is because
-# they can be recognised by their filenames ("whatever_controller", "jazz_helper"),
-# whereas models appear the same as any other typical Ruby library ("node",
-# "user", "image", etc.). 
-#
-# If mixing were allowed in models, it would mean code mixing for *every* 
-# file that was loaded via +require_or_load+, and this could result in
-# problems where, for example, a Node model might start to include 
-# functionality from another file called "node" somewhere else in the
-# <tt>$LOAD_PATH</tt>.
-#
-# One way to overcome this is to provide model functionality as a module in
-# a plugin, which developers can then include into their own model
-# implementations.
-#
-# Another option is to provide an abstract model (see the ActiveRecord::Base
-# documentation) and have developers subclass this model in their own
-# application if they must.
-#
-# ---
-#
-# The Engines::RailsExtensions::Dependencies module includes a method to
-# override Dependencies.require_or_load, which is called to load code needed
-# by Rails as it encounters constants that aren't defined.
-#
-# This method is enhanced with the code-mixing features described above.
-#
-module Engines::RailsExtensions::Dependencies
-  def self.included(base) #:nodoc:
-    base.class_eval { alias_method_chain :require_or_load, :engine_additions }
-  end
-
-  # Attempt to load the given file from any plugins, as well as the application.
-  # This performs the 'code mixing' magic, allowing application controllers and
-  # helpers to override single methods from those in plugins.
-  # If the file can be found in any plugins, it will be loaded first from those
-  # locations. Finally, the application version is loaded, using Ruby's behaviour
-  # to replace existing methods with their new definitions.
-  #
-  # If <tt>Engines.disable_code_mixing == true</tt>, the first controller/helper on the
-  # <tt>$LOAD_PATH</tt> will be used (plugins' +app+ directories are always lower on the
-  # <tt>$LOAD_PATH</tt> than the main +app+ directory).
-  #
-  # If <tt>Engines.disable_application_code_loading == true</tt>, controllers will
-  # not be loaded from the main +app+ directory *if* they are present in any
-  # plugins.
-  #
-  # Returns true if the file could be loaded (from anywhere); false otherwise -
-  # mirroring the behaviour of +require_or_load+ from Rails (which mirrors
-  # that of Ruby's own +require+, I believe).
-  def require_or_load_with_engine_additions(file_name, const_path=nil)
-    return require_or_load_without_engine_additions(file_name, const_path) if Engines.disable_code_mixing
-
-    file_loaded = false
-
-    # try and load the plugin code first
-    # can't use model, as there's nothing in the name to indicate that the file is a 'model' file
-    # rather than a library or anything else.
-    Engines.code_mixing_file_types.each do |file_type| 
-      # if we recognise this type
-      # (this regexp splits out the module/filename from any instances of app/#{type}, so that
-      #  modules are still respected.)
-      if file_name =~ /^(.*app\/#{file_type}s\/)+(.*_#{file_type})(\.rb)?$/
-        base_name = $2
-        # ... go through the plugins from first started to last, so that
-        # code with a high precedence (started later) will override lower precedence
-        # implementations
-        Engines.plugins.each do |plugin|
-          plugin_file_name = File.expand_path(File.join(plugin.directory, 'app', "#{file_type}s", base_name))
-          if File.file?("#{plugin_file_name}.rb")
-            file_loaded = true if require_or_load_without_engine_additions(plugin_file_name, const_path)
-          end
-        end
-    
-        # finally, load any application-specific controller classes using the 'proper'
-        # rails load mechanism, EXCEPT when we're testing engines and could load this file
-        # from an engine
-        unless Engines.disable_application_code_loading
-          # Ensure we are only loading from the /app directory at this point
-          app_file_name = File.join(RAILS_ROOT, 'app', "#{file_type}s", "#{base_name}")
-          if File.file?("#{app_file_name}.rb")
-            file_loaded = true if require_or_load_without_engine_additions(app_file_name, const_path)
-          end
-        end        
-      end 
-    end
-
-    # if we managed to load a file, return true. If not, default to the original method.
-    # Note that this relies on the RHS of a boolean || not to be evaluated if the LHS is true.
-    file_loaded || require_or_load_without_engine_additions(file_name, const_path)
-  end  
-end
-
-module ActiveSupport::Dependencies #:nodoc:
-  include Engines::RailsExtensions::Dependencies
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/57/5776267a0b45dc755c049113094ec8f5df6e6255.svn-base
--- /dev/null
+++ b/.svn/pristine/57/5776267a0b45dc755c049113094ec8f5df6e6255.svn-base
@@ -0,0 +1,28 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class WikiContentObserver < ActiveRecord::Observer
+  def after_create(wiki_content)
+    Mailer.wiki_content_added(wiki_content).deliver if Setting.notified_events.include?('wiki_content_added')
+  end
+
+  def after_update(wiki_content)
+    if wiki_content.text_changed?
+      Mailer.wiki_content_updated(wiki_content).deliver if Setting.notified_events.include?('wiki_content_updated')
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/57/579026907a1e3f3daa7c80962425f77970ae109e.svn-base
--- /dev/null
+++ b/.svn/pristine/57/579026907a1e3f3daa7c80962425f77970ae109e.svn-base
@@ -0,0 +1,1091 @@
+# Redmine catalan translation:
+# by Joan Duran
+
+ca:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d-%m-%Y"
+      short: "%e de %b"
+      long: "%a, %e de %b de %Y"
+
+    day_names: [Diumenge, Dilluns, Dimarts, Dimecres, Dijous, Divendres, Dissabte]
+    abbr_day_names: [dg, dl, dt, dc, dj, dv, ds]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Gener, Febrer, MarÃ§, Abril, Maig, Juny, Juliol, Agost, Setembre, Octubre, Novembre, Desembre]
+    abbr_month_names: [~, Gen, Feb, Mar, Abr, Mai, Jun, Jul, Ago, Set, Oct, Nov, Des]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%d-%m-%Y %H:%M"
+      time: "%H:%M"
+      short: "%e de %b, %H:%M"
+      long: "%a, %e de %b de %Y, %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "mig minut"
+      less_than_x_seconds:
+        one:   "menys d'un segon"
+        other: "menys de %{count} segons"
+      x_seconds:
+        one:   "1 segons"
+        other: "%{count} segons"
+      less_than_x_minutes:
+        one:   "menys d'un minut"
+        other: "menys de %{count} minuts"
+      x_minutes:
+        one:   "1 minut"
+        other: "%{count} minuts"
+      about_x_hours:
+        one:   "aproximadament 1 hora"
+        other: "aproximadament %{count} hores"
+      x_hours:
+        one:   "1 hora"
+        other: "%{count} hores"
+      x_days:
+        one:   "1 dia"
+        other: "%{count} dies"
+      about_x_months:
+        one:   "aproximadament 1 mes"
+        other: "aproximadament %{count} mesos"
+      x_months:
+        one:   "1 mes"
+        other: "%{count} mesos"
+      about_x_years:
+        one:   "aproximadament 1 any"
+        other: "aproximadament %{count} anys"
+      over_x_years:
+        one:   "mÃ©s d'un any"
+        other: "mÃ©s de %{count} anys"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    # Default format for numbers
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "i"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "no estÃ  inclÃ²s a la llista"
+        exclusion: "estÃ  reservat"
+        invalid: "no Ã©s vÃ lid"
+        confirmation: "la confirmaciÃ³ no coincideix"
+        accepted: "s'ha d'acceptar"
+        empty: "no pot estar buit"
+        blank: "no pot estar en blanc"
+        too_long: "Ã©s massa llarg"
+        too_short: "Ã©s massa curt"
+        wrong_length: "la longitud Ã©s incorrecta"
+        taken: "ja s'estÃ  utilitzant"
+        not_a_number: "no Ã©s un nÃºmero"
+        not_a_date: "no Ã©s una data vÃ lida"
+        greater_than: "ha de ser mÃ©s gran que %{count}"
+        greater_than_or_equal_to: "ha de ser mÃ©s gran o igual a %{count}"
+        equal_to: "ha de ser igual a %{count}"
+        less_than: "ha de ser menys que %{count}"
+        less_than_or_equal_to: "ha de ser menys o igual a %{count}"
+        odd: "ha de ser senar"
+        even: "ha de ser parell"
+        greater_than_start_date: "ha de ser superior que la data inicial"
+        not_same_project: "no pertany al mateix projecte"
+        circular_dependency: "Aquesta relaciÃ³ crearia una dependÃ¨ncia circular"
+        cant_link_an_issue_with_a_descendant: "Un assumpte no es pot enllaÃ§ar a una de les seves subtasques"
+
+  actionview_instancetag_blank_option: Seleccioneu
+
+  general_text_No: 'No'
+  general_text_Yes: 'Si'
+  general_text_no: 'no'
+  general_text_yes: 'si'
+  general_lang_name: 'CatalÃ '
+  general_csv_separator: ';'
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-15
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: "El compte s'ha actualitzat correctament."
+  notice_account_invalid_creditentials: Usuari o contrasenya invÃ lid
+  notice_account_password_updated: "La contrasenya s'ha modificat correctament."
+  notice_account_wrong_password: Contrasenya incorrecta
+  notice_account_register_done: "El compte s'ha creat correctament. Per a activar el compte, feu clic en l'enllaÃ§ que us han enviat per correu electrÃ²nic."
+  notice_account_unknown_email: Usuari desconegut.
+  notice_can_t_change_password: "Aquest compte utilitza una font d'autenticaciÃ³ externa. No Ã©s possible canviar la contrasenya."
+  notice_account_lost_email_sent: "S'ha enviat un correu electrÃ²nic amb instruccions per a seleccionar una contrasenya nova."
+  notice_account_activated: "El compte s'ha activat. Ara podeu entrar."
+  notice_successful_create: "S'ha creat correctament."
+  notice_successful_update: "S'ha modificat correctament."
+  notice_successful_delete: "S'ha suprimit correctament."
+  notice_successful_connection: "S'ha connectat correctament."
+  notice_file_not_found: "La pÃ gina a la que intenteu accedir no existeix o s'ha suprimit."
+  notice_locking_conflict: Un altre usuari ha actualitzat les dades.
+  notice_not_authorized: No teniu permÃ­s per a accedir a aquesta pÃ gina.
+  notice_email_sent: "S'ha enviat un correu electrÃ²nic a %{value}"
+  notice_email_error: "S'ha produÃ¯t un error en enviar el correu (%{value})"
+  notice_feeds_access_key_reseted: "S'ha reiniciat la clau d'accÃ©s del RSS."
+  notice_api_access_key_reseted: "S'ha reiniciat la clau d'accÃ©s a l'API."
+  notice_failed_to_save_issues: "No s'han pogut desar %{count} assumptes de %{total} seleccionats: %{ids}."
+  notice_failed_to_save_members: "No s'han pogut desar els membres: %{errors}."
+  notice_no_issue_selected: "No s'ha seleccionat cap assumpte. Activeu els assumptes que voleu editar."
+  notice_account_pending: "S'ha creat el compte i ara estÃ  pendent de l'aprovaciÃ³ de l'administrador."
+  notice_default_data_loaded: "S'ha carregat correctament la configuraciÃ³ predeterminada."
+  notice_unable_delete_version: "No s'ha pogut suprimir la versiÃ³."
+  notice_unable_delete_time_entry: "No s'ha pogut suprimir l'entrada del registre de temps."
+  notice_issue_done_ratios_updated: "S'ha actualitzat el tant per cent dels assumptes."
+
+  error_can_t_load_default_data: "No s'ha pogut carregar la configuraciÃ³ predeterminada: %{value} "
+  error_scm_not_found: "No s'ha trobat l'entrada o la revisiÃ³ en el dipÃ²sit."
+  error_scm_command_failed: "S'ha produÃ¯t un error en intentar accedir al dipÃ²sit: %{value}"
+  error_scm_annotate: "L'entrada no existeix o no s'ha pogut anotar."
+  error_issue_not_found_in_project: "No s'ha trobat l'assumpte o no pertany a aquest projecte"
+  error_no_tracker_in_project: "Aquest projecte no tÃ© seguidor associat. Comproveu els parÃ metres del projecte."
+  error_no_default_issue_status: "No s'ha definit cap estat d'assumpte predeterminat. Comproveu la configuraciÃ³ (aneu a Â«AdministraciÃ³ -> Estats de l'assumpteÂ»)."
+  error_can_not_delete_custom_field: "No s'ha pogut suprimir el camp personalitat"
+  error_can_not_delete_tracker: "Aquest seguidor contÃ© assumptes i no es pot suprimir."
+  error_can_not_remove_role: "Aquest rol s'estÃ  utilitzant i no es pot suprimir."
+  error_can_not_reopen_issue_on_closed_version: "Un assumpte assignat a una versiÃ³ tancada no es pot tornar a obrir"
+  error_can_not_archive_project: "Aquest projecte no es pot arxivar"
+  error_issue_done_ratios_not_updated: "No s'ha actualitza el tant per cent dels assumptes."
+  error_workflow_copy_source: "Seleccioneu un seguidor o rol font"
+  error_workflow_copy_target: "Seleccioneu seguidors i rols objectiu"
+  error_unable_delete_issue_status: "No s'ha pogut suprimir l'estat de l'assumpte"
+  error_unable_to_connect: "No s'ha pogut connectar (%{value})"
+  warning_attachments_not_saved: "No s'han pogut desar %{count} fitxers."
+
+  mail_subject_lost_password: "Contrasenya de %{value}"
+  mail_body_lost_password: "Per a canviar la contrasenya, feu clic en l'enllaÃ§ segÃ¼ent:"
+  mail_subject_register: "ActivaciÃ³ del compte de %{value}"
+  mail_body_register: "Per a activar el compte, feu clic en l'enllaÃ§ segÃ¼ent:"
+  mail_body_account_information_external: "Podeu utilitzar el compte Â«%{value}Â» per a entrar."
+  mail_body_account_information: InformaciÃ³ del compte
+  mail_subject_account_activation_request: "SolÂ·licitud d'activaciÃ³ del compte de %{value}"
+  mail_body_account_activation_request: "S'ha registrat un usuari nou (%{value}). El seu compte estÃ  pendent d'aprovaciÃ³:"
+  mail_subject_reminder: "%{count} assumptes venceran els segÃ¼ents %{days} dies"
+  mail_body_reminder: "%{count} assumptes que teniu assignades venceran els segÃ¼ents %{days} dies:"
+  mail_subject_wiki_content_added: "S'ha afegit la pÃ gina wiki Â«%{id}Â»"
+  mail_body_wiki_content_added: "En %{author} ha afegit la pÃ gina wiki Â«%{id}Â»."
+  mail_subject_wiki_content_updated: "S'ha actualitzat la pÃ gina wiki Â«%{id}Â»"
+  mail_body_wiki_content_updated: "En %{author} ha actualitzat la pÃ gina wiki Â«%{id}Â»."
+
+
+  field_name: Nom
+  field_description: DescripciÃ³
+  field_summary: Resum
+  field_is_required: Necessari
+  field_firstname: Nom
+  field_lastname: Cognom
+  field_mail: Correu electrÃ²nic
+  field_filename: Fitxer
+  field_filesize: Mida
+  field_downloads: Baixades
+  field_author: Autor
+  field_created_on: Creat
+  field_updated_on: Actualitzat
+  field_field_format: Format
+  field_is_for_all: Per a tots els projectes
+  field_possible_values: Valores possibles
+  field_regexp: ExpressiÃ³ regular
+  field_min_length: Longitud mÃ­nima
+  field_max_length: Longitud mÃ xima
+  field_value: Valor
+  field_category: Categoria
+  field_title: TÃ­tol
+  field_project: Projecte
+  field_issue: Assumpte
+  field_status: Estat
+  field_notes: Notes
+  field_is_closed: Assumpte tancat
+  field_is_default: Estat predeterminat
+  field_tracker: Seguidor
+  field_subject: Tema
+  field_due_date: Data de venciment
+  field_assigned_to: Assignat a
+  field_priority: Prioritat
+  field_fixed_version: VersiÃ³ objectiu
+  field_user: Usuari
+  field_principal: Principal
+  field_role: Rol
+  field_homepage: PÃ gina web
+  field_is_public: PÃºblic
+  field_parent: Subprojecte de
+  field_is_in_roadmap: Assumptes mostrats en la planificaciÃ³
+  field_login: Entrada
+  field_mail_notification: Notificacions per correu electrÃ²nic
+  field_admin: Administrador
+  field_last_login_on: Ãšltima connexiÃ³
+  field_language: Idioma
+  field_effective_date: Data
+  field_password: Contrasenya
+  field_new_password: Contrasenya nova
+  field_password_confirmation: ConfirmaciÃ³
+  field_version: VersiÃ³
+  field_type: Tipus
+  field_host: Ordinador
+  field_port: Port
+  field_account: Compte
+  field_base_dn: Base DN
+  field_attr_login: "Atribut d'entrada"
+  field_attr_firstname: Atribut del nom
+  field_attr_lastname: Atribut del cognom
+  field_attr_mail: Atribut del correu electrÃ²nic
+  field_onthefly: "CreaciÃ³ de l'usuari Â«al volÂ»"
+  field_start_date: Inici
+  field_done_ratio: "% realitzat"
+  field_auth_source: "Mode d'autenticaciÃ³"
+  field_hide_mail: "Oculta l'adreÃ§a de correu electrÃ²nic"
+  field_comments: Comentari
+  field_url: URL
+  field_start_page: PÃ gina inicial
+  field_subproject: Subprojecte
+  field_hours: Hores
+  field_activity: Activitat
+  field_spent_on: Data
+  field_identifier: Identificador
+  field_is_filter: "S'ha utilitzat com a filtre"
+  field_issue_to: Assumpte relacionat
+  field_delay: Retard
+  field_assignable: Es poden assignar assumptes a aquest rol
+  field_redirect_existing_links: Redirigeix els enllaÃ§os existents
+  field_estimated_hours: Temps previst
+  field_column_names: Columnes
+  field_time_entries: "Registre de temps"
+  field_time_zone: Zona horÃ ria
+  field_searchable: Es pot cercar
+  field_default_value: Valor predeterminat
+  field_comments_sorting: Mostra els comentaris
+  field_parent_title: PÃ gina pare
+  field_editable: Es pot editar
+  field_watcher: VigilÃ ncia
+  field_identity_url: URL OpenID
+  field_content: Contingut
+  field_group_by: "Agrupa els resultats per"
+  field_sharing: ComparticiÃ³
+  field_parent_issue: "Tasca pare"
+
+  setting_app_title: "TÃ­tol de l'aplicaciÃ³"
+  setting_app_subtitle: "SubtÃ­tol de l'aplicaciÃ³"
+  setting_welcome_text: Text de benvinguda
+  setting_default_language: Idioma predeterminat
+  setting_login_required: Es necessita autenticaciÃ³
+  setting_self_registration: Registre automÃ tic
+  setting_attachment_max_size: Mida mÃ xima dels adjunts
+  setting_issues_export_limit: "LÃ­mit d'exportaciÃ³ d'assumptes"
+  setting_mail_from: "AdreÃ§a de correu electrÃ²nic d'emissiÃ³"
+  setting_bcc_recipients: Vincula els destinataris de les cÃ²pies amb carbÃ³ (bcc)
+  setting_plain_text_mail: nomÃ©s text pla (no HTML)
+  setting_host_name: "Nom de l'ordinador"
+  setting_text_formatting: Format del text
+  setting_wiki_compression: "Comprimeix l'historial del wiki"
+  setting_feeds_limit: LÃ­mit de contingut del canal
+  setting_default_projects_public: Els projectes nous sÃ³n pÃºblics per defecte
+  setting_autofetch_changesets: Omple automÃ ticament les publicacions
+  setting_sys_api_enabled: Habilita el WS per a la gestiÃ³ del dipÃ²sit
+  setting_commit_ref_keywords: Paraules claus per a la referÃ¨ncia
+  setting_commit_fix_keywords: Paraules claus per a la correcciÃ³
+  setting_autologin: Entrada automÃ tica
+  setting_date_format: Format de la data
+  setting_time_format: Format de hora
+  setting_cross_project_issue_relations: "Permet les relacions d'assumptes entre projectes"
+  setting_issue_list_default_columns: "Columnes mostrades per defecte en la llista d'assumptes"
+  setting_emails_footer: Peu dels correus electrÃ²nics
+  setting_protocol: Protocol
+  setting_per_page_options: Opcions dels objectes per pÃ gina
+  setting_user_format: "Format de com mostrar l'usuari"
+  setting_activity_days_default: "Dies a mostrar l'activitat del projecte"
+  setting_display_subprojects_issues: "Mostra els assumptes d'un subprojecte en el projecte pare per defecte"
+  setting_enabled_scm: "Habilita l'SCM"
+  setting_mail_handler_body_delimiters: "Trunca els correus electrÃ²nics desprÃ©s d'una d'aquestes lÃ­nies"
+  setting_mail_handler_api_enabled: "Habilita el WS per correus electrÃ²nics d'entrada"
+  setting_mail_handler_api_key: Clau API
+  setting_sequential_project_identifiers: Genera identificadors de projecte seqÃ¼encials
+  setting_gravatar_enabled: "Utilitza les icones d'usuari Gravatar"
+  setting_gravatar_default: "Imatge Gravatar predeterminada"
+  setting_diff_max_lines_displayed: NÃºmero mÃ xim de lÃ­nies amb diferÃ¨ncies mostrades
+  setting_file_max_size_displayed: Mida mÃ xima dels fitxers de text mostrats en lÃ­nia
+  setting_repository_log_display_limit: NÃºmero mÃ xim de revisions que es mostren al registre de fitxers
+  setting_openid: "Permet entrar i registrar-se amb l'OpenID"
+  setting_password_min_length: "Longitud mÃ­nima de la contrasenya"
+  setting_new_project_user_role_id: "Aquest rol es dÃ³na a un usuari no administrador per a crear projectes"
+  setting_default_projects_modules: "MÃ²duls activats per defecte en els projectes nous"
+  setting_issue_done_ratio: "Calcula tant per cent realitzat de l'assumpte amb"
+  setting_issue_done_ratio_issue_status: "Utilitza l'estat de l'assumpte"
+  setting_issue_done_ratio_issue_field: "Utilitza el camp de l'assumpte"
+  setting_start_of_week: "Inicia les setmanes en"
+  setting_rest_api_enabled: "Habilita el servei web REST"
+  setting_cache_formatted_text: Cache formatted text
+
+  permission_add_project: "Crea projectes"
+  permission_add_subprojects: "Crea subprojectes"
+  permission_edit_project: Edita el projecte
+  permission_select_project_modules: Selecciona els mÃ²duls del projecte
+  permission_manage_members: Gestiona els membres
+  permission_manage_project_activities: "Gestiona les activitats del projecte"
+  permission_manage_versions: Gestiona les versions
+  permission_manage_categories: Gestiona les categories dels assumptes
+  permission_view_issues: "Visualitza els assumptes"
+  permission_add_issues: Afegeix assumptes
+  permission_edit_issues: Edita els assumptes
+  permission_manage_issue_relations: Gestiona les relacions dels assumptes
+  permission_add_issue_notes: Afegeix notes
+  permission_edit_issue_notes: Edita les notes
+  permission_edit_own_issue_notes: Edita les notes prÃ²pies
+  permission_move_issues: Mou els assumptes
+  permission_delete_issues: Suprimeix els assumptes
+  permission_manage_public_queries: Gestiona les consultes pÃºbliques
+  permission_save_queries: Desa les consultes
+  permission_view_gantt: Visualitza la grÃ fica de Gantt
+  permission_view_calendar: Visualitza el calendari
+  permission_view_issue_watchers: Visualitza la llista de vigilÃ ncies
+  permission_add_issue_watchers: Afegeix vigilÃ ncies
+  permission_delete_issue_watchers: Suprimeix els vigilants
+  permission_log_time: Registra el temps invertit
+  permission_view_time_entries: Visualitza el temps invertit
+  permission_edit_time_entries: Edita els registres de temps
+  permission_edit_own_time_entries: Edita els registres de temps propis
+  permission_manage_news: Gestiona les noticies
+  permission_comment_news: Comenta les noticies
+  permission_view_documents: Visualitza els documents
+  permission_manage_files: Gestiona els fitxers
+  permission_view_files: Visualitza els fitxers
+  permission_manage_wiki: Gestiona el wiki
+  permission_rename_wiki_pages: Canvia el nom de les pÃ gines wiki
+  permission_delete_wiki_pages: Suprimeix les pÃ gines wiki
+  permission_view_wiki_pages: Visualitza el wiki
+  permission_view_wiki_edits: "Visualitza l'historial del wiki"
+  permission_edit_wiki_pages: Edita les pÃ gines wiki
+  permission_delete_wiki_pages_attachments: Suprimeix adjunts
+  permission_protect_wiki_pages: Protegeix les pÃ gines wiki
+  permission_manage_repository: Gestiona el dipÃ²sit
+  permission_browse_repository: Navega pel dipÃ²sit
+  permission_view_changesets: Visualitza els canvis realitzats
+  permission_commit_access: AccÃ©s a les publicacions
+  permission_manage_boards: Gestiona els taulers
+  permission_view_messages: Visualitza els missatges
+  permission_add_messages: Envia missatges
+  permission_edit_messages: Edita els missatges
+  permission_edit_own_messages: Edita els missatges propis
+  permission_delete_messages: Suprimeix els missatges
+  permission_delete_own_messages: Suprimeix els missatges propis
+  permission_export_wiki_pages: "Exporta les pÃ gines wiki"
+  permission_manage_subtasks: "Gestiona subtasques"
+
+  project_module_issue_tracking: "Seguidor d'assumptes"
+  project_module_time_tracking: Seguidor de temps
+  project_module_news: Noticies
+  project_module_documents: Documents
+  project_module_files: Fitxers
+  project_module_wiki: Wiki
+  project_module_repository: DipÃ²sit
+  project_module_boards: Taulers
+  project_module_calendar: Calendari
+  project_module_gantt: Gantt
+
+  label_user: Usuari
+  label_user_plural: Usuaris
+  label_user_new: Usuari nou
+  label_user_anonymous: AnÃ²nim
+  label_project: Projecte
+  label_project_new: Projecte nou
+  label_project_plural: Projectes
+  label_x_projects:
+    zero:  cap projecte
+    one:   1 projecte
+    other: "%{count} projectes"
+  label_project_all: Tots els projectes
+  label_project_latest: Els Ãºltims projectes
+  label_issue: Assumpte
+  label_issue_new: Assumpte nou
+  label_issue_plural: Assumptes
+  label_issue_view_all: Visualitza tots els assumptes
+  label_issues_by: "Assumptes per %{value}"
+  label_issue_added: Assumpte afegit
+  label_issue_updated: Assumpte actualitzat
+  label_document: Document
+  label_document_new: Document nou
+  label_document_plural: Documents
+  label_document_added: Document afegit
+  label_role: Rol
+  label_role_plural: Rols
+  label_role_new: Rol nou
+  label_role_and_permissions: Rols i permisos
+  label_member: Membre
+  label_member_new: Membre nou
+  label_member_plural: Membres
+  label_tracker: Seguidor
+  label_tracker_plural: Seguidors
+  label_tracker_new: Seguidor nou
+  label_workflow: Flux de treball
+  label_issue_status: "Estat de l'assumpte"
+  label_issue_status_plural: "Estats de l'assumpte"
+  label_issue_status_new: Estat nou
+  label_issue_category: "Categoria de l'assumpte"
+  label_issue_category_plural: "Categories de l'assumpte"
+  label_issue_category_new: Categoria nova
+  label_custom_field: Camp personalitzat
+  label_custom_field_plural: Camps personalitzats
+  label_custom_field_new: Camp personalitzat nou
+  label_enumerations: Enumeracions
+  label_enumeration_new: Valor nou
+  label_information: InformaciÃ³
+  label_information_plural: InformaciÃ³
+  label_please_login: Entreu
+  label_register: Registre
+  label_login_with_open_id_option: "o entra amb l'OpenID"
+  label_password_lost: Contrasenya perduda
+  label_home: Inici
+  label_my_page: La meva pÃ gina
+  label_my_account: El meu compte
+  label_my_projects: Els meus projectes
+  label_my_page_block: "Els meus blocs de pÃ gina"
+  label_administration: AdministraciÃ³
+  label_login: Entra
+  label_logout: Surt
+  label_help: Ajuda
+  label_reported_issues: Assumptes informats
+  label_assigned_to_me_issues: Assumptes assignats a mi
+  label_last_login: Ãšltima connexiÃ³
+  label_registered_on: Informat el
+  label_activity: Activitat
+  label_overall_activity: Activitat global
+  label_user_activity: "Activitat de %{value}"
+  label_new: Nou
+  label_logged_as: Heu entrat com a
+  label_environment: Entorn
+  label_authentication: AutenticaciÃ³
+  label_auth_source: "Mode d'autenticaciÃ³"
+  label_auth_source_new: "Mode d'autenticaciÃ³ nou"
+  label_auth_source_plural: "Modes d'autenticaciÃ³"
+  label_subproject_plural: Subprojectes
+  label_subproject_new: "Subprojecte nou"
+  label_and_its_subprojects: "%{value} i els seus subprojectes"
+  label_min_max_length: Longitud mÃ­n - max
+  label_list: Llist
+  label_date: Data
+  label_integer: Enter
+  label_float: Flotant
+  label_boolean: BooleÃ 
+  label_string: Text
+  label_text: Text llarg
+  label_attribute: Atribut
+  label_attribute_plural: Atributs
+  label_no_data: Sense dades a mostrar
+  label_change_status: "Canvia l'estat"
+  label_history: Historial
+  label_attachment: Fitxer
+  label_attachment_new: Fitxer nou
+  label_attachment_delete: Suprimeix el fitxer
+  label_attachment_plural: Fitxers
+  label_file_added: Fitxer afegit
+  label_report: Informe
+  label_report_plural: Informes
+  label_news: Noticies
+  label_news_new: Afegeix noticies
+  label_news_plural: Noticies
+  label_news_latest: Ãšltimes noticies
+  label_news_view_all: Visualitza totes les noticies
+  label_news_added: Noticies afegides
+  label_settings: ParÃ metres
+  label_overview: Resum
+  label_version: VersiÃ³
+  label_version_new: VersiÃ³ nova
+  label_version_plural: Versions
+  label_close_versions: "Tanca les versions completades"
+  label_confirmation: ConfirmaciÃ³
+  label_export_to: "TambÃ© disponible a:"
+  label_read: Llegeix...
+  label_public_projects: Projectes pÃºblics
+  label_open_issues: obert
+  label_open_issues_plural: oberts
+  label_closed_issues: tancat
+  label_closed_issues_plural: tancats
+  label_x_open_issues_abbr_on_total:
+    zero:  0 oberts / %{total}
+    one:   1 obert / %{total}
+    other: "%{count} oberts / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 oberts
+    one:   1 obert
+    other: "%{count} oberts"
+  label_x_closed_issues_abbr:
+    zero:  0 tancats
+    one:   1 tancat
+    other: "%{count} tancats"
+  label_total: Total
+  label_permissions: Permisos
+  label_current_status: Estat actual
+  label_new_statuses_allowed: Nous estats autoritzats
+  label_all: tots
+  label_none: cap
+  label_nobody: ningÃº
+  label_next: SegÃ¼ent
+  label_previous: Anterior
+  label_used_by: Utilitzat per
+  label_details: Detalls
+  label_add_note: Afegeix una nota
+  label_per_page: Per pÃ gina
+  label_calendar: Calendari
+  label_months_from: mesos des de
+  label_gantt: Gantt
+  label_internal: Intern
+  label_last_changes: "Ãºltims %{count} canvis"
+  label_change_view_all: Visualitza tots els canvis
+  label_personalize_page: Personalitza aquesta pÃ gina
+  label_comment: Comentari
+  label_comment_plural: Comentaris
+  label_x_comments:
+    zero: sense comentaris
+    one: 1 comentari
+    other: "%{count} comentaris"
+  label_comment_add: Afegeix un comentari
+  label_comment_added: Comentari afegit
+  label_comment_delete: Suprimeix comentaris
+  label_query: Consulta personalitzada
+  label_query_plural: Consultes personalitzades
+  label_query_new: Consulta nova
+  label_filter_add: Afegeix un filtre
+  label_filter_plural: Filtres
+  label_equals: Ã©s
+  label_not_equals: no Ã©s
+  label_in_less_than: en menys de
+  label_in_more_than: en mÃ©s de
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  label_in: en
+  label_today: avui
+  label_all_time: tot el temps
+  label_yesterday: ahir
+  label_this_week: aquesta setmana
+  label_last_week: "l'Ãºltima setmana"
+  label_last_n_days: "els Ãºltims %{count} dies"
+  label_this_month: aquest mÃ©s
+  label_last_month: "l'Ãºltim mÃ©s"
+  label_this_year: aquest any
+  label_date_range: Abast de les dates
+  label_less_than_ago: fa menys de
+  label_more_than_ago: fa mÃ©s de
+  label_ago: fa
+  label_contains: contÃ©
+  label_not_contains: no contÃ©
+  label_day_plural: dies
+  label_repository: DipÃ²sit
+  label_repository_plural: DipÃ²sits
+  label_browse: Navega
+  label_branch: Branca
+  label_tag: Etiqueta
+  label_revision: RevisiÃ³
+  label_revision_plural: Revisions
+  label_revision_id: "RevisiÃ³ %{value}"
+  label_associated_revisions: Revisions associades
+  label_added: afegit
+  label_modified: modificat
+  label_copied: copiat
+  label_renamed: reanomenat
+  label_deleted: suprimit
+  label_latest_revision: Ãšltima revisiÃ³
+  label_latest_revision_plural: Ãšltimes revisions
+  label_view_revisions: Visualitza les revisions
+  label_view_all_revisions: "Visualitza totes les revisions"
+  label_max_size: Mida mÃ xima
+  label_sort_highest: Mou a la part superior
+  label_sort_higher: Mou cap amunt
+  label_sort_lower: Mou cap avall
+  label_sort_lowest: Mou a la part inferior
+  label_roadmap: PlanificaciÃ³
+  label_roadmap_due_in: "VenÃ§ en %{value}"
+  label_roadmap_overdue: "%{value} tard"
+  label_roadmap_no_issues: No hi ha assumptes per a aquesta versiÃ³
+  label_search: Cerca
+  label_result_plural: Resultats
+  label_all_words: Totes les paraules
+  label_wiki: Wiki
+  label_wiki_edit: EdiciÃ³ wiki
+  label_wiki_edit_plural: Edicions wiki
+  label_wiki_page: PÃ gina wiki
+  label_wiki_page_plural: PÃ gines wiki
+  label_index_by_title: Ãndex per tÃ­tol
+  label_index_by_date: Ãndex per data
+  label_current_version: VersiÃ³ actual
+  label_preview: PrevisualitzaciÃ³
+  label_feed_plural: Canals
+  label_changes_details: Detalls de tots els canvis
+  label_issue_tracking: "Seguiment d'assumptes"
+  label_spent_time: Temps invertit
+  label_overall_spent_time: "Temps total invertit"
+  label_f_hour: "%{value} hora"
+  label_f_hour_plural: "%{value} hores"
+  label_time_tracking: Temps de seguiment
+  label_change_plural: Canvis
+  label_statistics: EstadÃ­stiques
+  label_commits_per_month: Publicacions per mes
+  label_commits_per_author: Publicacions per autor
+  label_view_diff: Visualitza les diferÃ¨ncies
+  label_diff_inline: en lÃ­nia
+  label_diff_side_by_side: costat per costat
+  label_options: Opcions
+  label_copy_workflow_from: Copia el flux de treball des de
+  label_permissions_report: Informe de permisos
+  label_watched_issues: Assumptes vigilats
+  label_related_issues: Assumptes relacionats
+  label_applied_status: Estat aplicat
+  label_loading: "S'estÃ  carregant..."
+  label_relation_new: RelaciÃ³ nova
+  label_relation_delete: Suprimeix la relaciÃ³
+  label_relates_to: relacionat amb
+  label_duplicates: duplicats
+  label_duplicated_by: duplicat per
+  label_blocks: bloqueja
+  label_blocked_by: bloquejats per
+  label_precedes: anterior a
+  label_follows: posterior a
+  label_end_to_start: final al comenÃ§ament
+  label_end_to_end: final al final
+  label_start_to_start: comenÃ§ament al comenÃ§ament
+  label_start_to_end: comenÃ§ament al final
+  label_stay_logged_in: "MantÃ© l'entrada"
+  label_disabled: inhabilitat
+  label_show_completed_versions: Mostra les versions completes
+  label_me: jo mateix
+  label_board: FÃ²rum
+  label_board_new: FÃ²rum nou
+  label_board_plural: FÃ²rums
+  label_board_locked: Bloquejat
+  label_board_sticky: Sticky
+  label_topic_plural: Temes
+  label_message_plural: Missatges
+  label_message_last: Ãšltim missatge
+  label_message_new: Missatge nou
+  label_message_posted: Missatge afegit
+  label_reply_plural: Respostes
+  label_send_information: "Envia la informaciÃ³ del compte a l'usuari"
+  label_year: Any
+  label_month: Mes
+  label_week: Setmana
+  label_date_from: Des de
+  label_date_to: A
+  label_language_based: "Basat en l'idioma de l'usuari"
+  label_sort_by: "Ordena per %{value}"
+  label_send_test_email: Envia un correu electrÃ²nic de prova
+  label_feeds_access_key: "Clau d'accÃ©s del RSS"
+  label_missing_feeds_access_key: "Falta una clau d'accÃ©s del RSS"
+  label_feeds_access_key_created_on: "Clau d'accÃ©s del RSS creada fa %{value}"
+  label_module_plural: MÃ²duls
+  label_added_time_by: "Afegit per %{author} fa %{age}"
+  label_updated_time_by: "Actualitzat per %{author} fa %{age}"
+  label_updated_time: "Actualitzat fa %{value}"
+  label_jump_to_a_project: Salta al projecte...
+  label_file_plural: Fitxers
+  label_changeset_plural: Conjunt de canvis
+  label_default_columns: Columnes predeterminades
+  label_no_change_option: (sense canvis)
+  label_bulk_edit_selected_issues: Edita en bloc els assumptes seleccionats
+  label_theme: Tema
+  label_default: Predeterminat
+  label_search_titles_only: Cerca nomÃ©s en els tÃ­tols
+  label_user_mail_option_all: "Per qualsevol esdeveniment en tots els meus projectes"
+  label_user_mail_option_selected: "Per qualsevol esdeveniment en els projectes seleccionats..."
+  label_user_mail_no_self_notified: "No vull ser notificat pels canvis que faig jo mateix"
+  label_registration_activation_by_email: activaciÃ³ del compte per correu electrÃ²nic
+  label_registration_manual_activation: activaciÃ³ del compte manual
+  label_registration_automatic_activation: activaciÃ³ del compte automÃ tica
+  label_display_per_page: "Per pÃ gina: %{value}"
+  label_age: Edat
+  label_change_properties: Canvia les propietats
+  label_general: General
+  label_more: MÃ©s
+  label_scm: SCM
+  label_plugins: Connectors
+  label_ldap_authentication: AutenticaciÃ³ LDAP
+  label_downloads_abbr: Baixades
+  label_optional_description: DescripciÃ³ opcional
+  label_add_another_file: Afegeix un altre fitxer
+  label_preferences: PreferÃ¨ncies
+  label_chronological_order: En ordre cronolÃ²gic
+  label_reverse_chronological_order: En ordre cronolÃ²gic invers
+  label_planning: PlanificaciÃ³
+  label_incoming_emails: "Correu electrÃ²nics d'entrada"
+  label_generate_key: Genera una clau
+  label_issue_watchers: VigilÃ ncies
+  label_example: Exemple
+  label_display: Mostra
+  label_sort: Ordena
+  label_ascending: Ascendent
+  label_descending: Descendent
+  label_date_from_to: Des de %{start} a %{end}
+  label_wiki_content_added: "S'ha afegit la pÃ gina wiki"
+  label_wiki_content_updated: "S'ha actualitzat la pÃ gina wiki"
+  label_group: Grup
+  label_group_plural: Grups
+  label_group_new: Grup nou
+  label_time_entry_plural: Temps invertit
+  label_version_sharing_hierarchy: "Amb la jerarquia del projecte"
+  label_version_sharing_system: "Amb tots els projectes"
+  label_version_sharing_descendants: "Amb tots els subprojectes"
+  label_version_sharing_tree: "Amb l'arbre del projecte"
+  label_version_sharing_none: "Sense compartir"
+  label_update_issue_done_ratios: "Actualitza el tant per cent dels assumptes realitzats"
+  label_copy_source: Font
+  label_copy_target: Objectiu
+  label_copy_same_as_target: "El mateix que l'objectiu"
+  label_display_used_statuses_only: "Mostra nomÃ©s els estats que utilitza aquest seguidor"
+  label_api_access_key: "Clau d'accÃ©s a l'API"
+  label_missing_api_access_key: "Falta una clau d'accÃ©s de l'API"
+  label_api_access_key_created_on: "Clau d'accÃ©s de l'API creada fa %{value}"
+  label_profile: Perfil
+  label_subtask_plural: Subtasques
+  label_project_copy_notifications: "Envia notificacions de correu electrÃ²nic durant la cÃ²pia del projecte"
+
+  button_login: Entra
+  button_submit: Tramet
+  button_save: Desa
+  button_check_all: Activa-ho tot
+  button_uncheck_all: Desactiva-ho tot
+  button_delete: Suprimeix
+  button_create: Crea
+  button_create_and_continue: Crea i continua
+  button_test: Test
+  button_edit: Edit
+  button_add: Afegeix
+  button_change: Canvia
+  button_apply: Aplica
+  button_clear: Neteja
+  button_lock: Bloca
+  button_unlock: Desbloca
+  button_download: Baixa
+  button_list: Llista
+  button_view: Visualitza
+  button_move: Mou
+  button_move_and_follow: "Mou i segueix"
+  button_back: Enrere
+  button_cancel: CancelÂ·la
+  button_activate: Activa
+  button_sort: Ordena
+  button_log_time: "Registre de temps"
+  button_rollback: Torna a aquesta versiÃ³
+  button_watch: Vigila
+  button_unwatch: No vigilis
+  button_reply: Resposta
+  button_archive: Arxiva
+  button_unarchive: Desarxiva
+  button_reset: Reinicia
+  button_rename: Reanomena
+  button_change_password: Canvia la contrasenya
+  button_copy: Copia
+  button_copy_and_follow: "Copia i segueix"
+  button_annotate: Anota
+  button_update: Actualitza
+  button_configure: Configura
+  button_quote: Cita
+  button_duplicate: Duplica
+  button_show: Mostra
+
+  status_active: actiu
+  status_registered: informat
+  status_locked: bloquejat
+
+  version_status_open: oberta
+  version_status_locked: bloquejada
+  version_status_closed: tancada
+
+  field_active: Actiu
+
+  text_select_mail_notifications: "Seleccioneu les accions per les quals s'hauria d'enviar una notificaciÃ³ per correu electrÃ²nic."
+  text_regexp_info: ex. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 significa sense restricciÃ³
+  text_project_destroy_confirmation: Segur que voleu suprimir aquest projecte i les dades relacionades?
+  text_subprojects_destroy_warning: "TambÃ© seran suprimits els seus subprojectes: %{value}."
+  text_workflow_edit: Seleccioneu un rol i un seguidor per a editar el flux de treball
+  text_are_you_sure: Segur?
+  text_journal_changed: "%{label} ha canviat de %{old} a %{new}"
+  text_journal_set_to: "%{label} s'ha establert a %{value}"
+  text_journal_deleted: "%{label} s'ha suprimit (%{old})"
+  text_journal_added: "S'ha afegit %{label} %{value}"
+  text_tip_issue_begin_day: "tasca que s'inicia aquest dia"
+  text_tip_issue_end_day: tasca que finalitza aquest dia
+  text_tip_issue_begin_end_day: "tasca que s'inicia i finalitza aquest dia"
+  text_caracters_maximum: "%{count} carÃ cters com a mÃ xim."
+  text_caracters_minimum: "Com a mÃ­nim ha de tenir %{count} carÃ cters."
+  text_length_between: "Longitud entre %{min} i %{max} carÃ cters."
+  text_tracker_no_workflow: "No s'ha definit cap flux de treball per a aquest seguidor"
+  text_unallowed_characters: CarÃ cters no permesos
+  text_comma_separated: Es permeten valors mÃºltiples (separats per una coma).
+  text_line_separated: "Es permeten diversos valors (una lÃ­nia per cada valor)."
+  text_issues_ref_in_commit_messages: ReferÃ¨ncia i soluciona els assumptes en els missatges publicats
+  text_issue_added: "L'assumpte %{id} ha sigut informat per %{author}."
+  text_issue_updated: "L'assumpte %{id} ha sigut actualitzat per %{author}."
+  text_wiki_destroy_confirmation: Segur que voleu suprimir aquest wiki i tots els seus continguts?
+  text_issue_category_destroy_question: "Alguns assumptes (%{count}) estan assignats a aquesta categoria. QuÃ¨ voleu fer?"
+  text_issue_category_destroy_assignments: Suprimeix les assignacions de la categoria
+  text_issue_category_reassign_to: Torna a assignar els assumptes a aquesta categoria
+  text_user_mail_option: "Per als projectes no seleccionats, nomÃ©s rebreu notificacions sobre les coses que vigileu o que hi esteu implicat (ex. assumptes que en sou l'autor o hi esteu assignat)."
+  text_no_configuration_data: "Encara no s'han configurat els rols, seguidors, estats de l'assumpte i flux de treball.\nÃ‰s altament recomanable que carregueu la configuraciÃ³ predeterminada. Podreu modificar-la un cop carregada."
+  text_load_default_configuration: Carrega la configuraciÃ³ predeterminada
+  text_status_changed_by_changeset: "Aplicat en el conjunt de canvis %{value}."
+  text_issues_destroy_confirmation: "Segur que voleu suprimir els assumptes seleccionats?"
+  text_select_project_modules: "Seleccioneu els mÃ²duls a habilitar per a aquest projecte:"
+  text_default_administrator_account_changed: "S'ha canviat el compte d'administrador predeterminat"
+  text_file_repository_writable: Es pot escriure en el dipÃ²sit de fitxers
+  text_plugin_assets_writable: Es pot escriure als connectors actius
+  text_rmagick_available: RMagick disponible (opcional)
+  text_destroy_time_entries_question: "S'han informat %{hours} hores en els assumptes que aneu a suprimir. QuÃ¨ voleu fer?"
+  text_destroy_time_entries: Suprimeix les hores informades
+  text_assign_time_entries_to_project: Assigna les hores informades al projecte
+  text_reassign_time_entries: "Torna a assignar les hores informades a aquest assumpte:"
+  text_user_wrote: "%{value} va escriure:"
+  text_enumeration_destroy_question: "%{count} objectes estan assignats a aquest valor."
+  text_enumeration_category_reassign_to: "Torna a assignar-los a aquest valor:"
+  text_email_delivery_not_configured: "El lliurament per correu electrÃ²nic no estÃ  configurat i les notificacions estan inhabilitades.\nConfigureu el servidor SMTP a config/configuration.yml i reinicieu l'aplicaciÃ³ per habilitar-lo."
+  text_repository_usernames_mapping: "Seleccioneu l'assignaciÃ³ entre els usuaris del Redmine i cada nom d'usuari trobat al dipÃ²sit.\nEls usuaris amb el mateix nom d'usuari o correu del Redmine i del dipÃ²sit s'assignaran automÃ ticament."
+  text_diff_truncated: "... Aquestes diferÃ¨ncies s'han trucat perquÃ¨ excedeixen la mida mÃ xima que es pot mostrar."
+  text_custom_field_possible_values_info: "Una lÃ­nia per a cada valor"
+  text_wiki_page_destroy_question: "Aquesta pÃ gina tÃ© %{descendants} pÃ gines fill i descendents. QuÃ¨ voleu fer?"
+  text_wiki_page_nullify_children: "Deixa les pÃ gines fill com a pÃ gines arrel"
+  text_wiki_page_destroy_children: "Suprimeix les pÃ gines fill i tots els seus descendents"
+  text_wiki_page_reassign_children: "Reasigna les pÃ gines fill a aquesta pÃ gina pare"
+  text_own_membership_delete_confirmation: "Esteu a punt de suprimir algun o tots els vostres permisos i potser no podreu editar mÃ©s aquest projecte.\nSegur que voleu continuar?"
+  text_zoom_in: Redueix
+  text_zoom_out: Amplia
+
+  default_role_manager: Gestor
+  default_role_developer: Desenvolupador
+  default_role_reporter: Informador
+  default_tracker_bug: Error
+  default_tracker_feature: CaracterÃ­stica
+  default_tracker_support: Suport
+  default_issue_status_new: Nou
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: Resolt
+  default_issue_status_feedback: Comentaris
+  default_issue_status_closed: Tancat
+  default_issue_status_rejected: Rebutjat
+  default_doc_category_user: "DocumentaciÃ³ d'usuari"
+  default_doc_category_tech: DocumentaciÃ³ tÃ¨cnica
+  default_priority_low: Baixa
+  default_priority_normal: Normal
+  default_priority_high: Alta
+  default_priority_urgent: Urgent
+  default_priority_immediate: Immediata
+  default_activity_design: Disseny
+  default_activity_development: Desenvolupament
+
+  enumeration_issue_priorities: Prioritat dels assumptes
+  enumeration_doc_categories: Categories del document
+  enumeration_activities: Activitats (seguidor de temps)
+  enumeration_system_activity: Activitat del sistema
+
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: CodificaciÃ³ dels missatges publicats
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 assumpte
+    one:   1 assumpte
+    other: "%{count} assumptes"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: tots
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: "Amb tots els subprojectes"
+  label_cross_project_tree: "Amb l'arbre del projecte"
+  label_cross_project_hierarchy: "Amb la jerarquia del projecte"
+  label_cross_project_system: "Amb tots els projectes"
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/57/57c1667a6b0b8222beaeafcee0db4e38818fa2d0.svn-base
--- a/.svn/pristine/57/57c1667a6b0b8222beaeafcee0db4e38818fa2d0.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-require File.dirname(__FILE__) + "/rails/init"  
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/57/57d9fc955c1c0bed1abfed5bf47b0ed281a3ff4b.svn-base
--- a/.svn/pristine/57/57d9fc955c1c0bed1abfed5bf47b0ed281a3ff4b.svn-base
+++ /dev/null
@@ -1,1009 +0,0 @@
-mn:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y/%m/%d"
-      short: "%b %d"
-      long: "%Y, %B %d"
-      
-    day_names: [Ð”Ð°Ð²Ð°Ð°, ÐœÑÐ³Ð¼Ð°Ñ€, Ð›Ñ…Ð°Ð³Ð²Ð°, ÐŸÒ¯Ñ€ÑÐ², Ð‘Ð°Ð°ÑÐ°Ð½, Ð‘ÑÐ¼Ð±Ð°, ÐÑÐ¼]
-    abbr_day_names: [Ð”Ð°Ð², ÐœÑÐ³, Ð›Ñ…Ð°, ÐŸÒ¯Ñ€, Ð‘ÑÐ½, Ð‘ÑÐ¼, ÐÑÐ¼]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, 1-Ñ€ ÑÐ°Ñ€, 2-Ñ€ ÑÐ°Ñ€, 3-Ñ€ ÑÐ°Ñ€, 4-Ñ€ ÑÐ°Ñ€, 5-Ñ€ ÑÐ°Ñ€, 6-Ñ€ ÑÐ°Ñ€, 7-Ñ€ ÑÐ°Ñ€, 8-Ñ€ ÑÐ°Ñ€, 9-Ñ€ ÑÐ°Ñ€, 10-Ñ€ ÑÐ°Ñ€, 11-Ñ€ ÑÐ°Ñ€, 12-Ñ€ ÑÐ°Ñ€]
-    abbr_month_names: [~, 1ÑÐ°Ñ€, 2ÑÐ°Ñ€, 3ÑÐ°Ñ€, 4ÑÐ°Ñ€, 5ÑÐ°Ñ€, 6ÑÐ°Ñ€, 7ÑÐ°Ñ€, 8ÑÐ°Ñ€, 9ÑÐ°Ñ€, 10ÑÐ°Ñ€, 11ÑÐ°Ñ€, 12ÑÐ°Ñ€]
-    # Used in date_select and datime_select.
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%Y/%m/%d %I:%M %p"
-      time: "%I:%M %p"
-      short: "%d %b %H:%M"
-      long: "%Y, %B %d %H:%M"
-    am: "am"
-    pm: "pm"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "Ñ…Ð°Ð³Ð°Ñ Ð¼Ð¸Ð½ÑƒÑ‚"
-      less_than_x_seconds:
-        one:   "ÑÐµÐºÑƒÐ½Ð´ Ð¾Ñ€Ñ‡Ð¸Ð¼"
-        other: "%{count} ÑÐµÐºÑƒÐ½Ð´ÑÑÑ Ð±Ð°Ð³Ð° Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°"
-      x_seconds:
-        one:   "1 ÑÐµÐºÑƒÐ½Ð´"
-        other: "%{count} ÑÐµÐºÑƒÐ½Ð´"
-      less_than_x_minutes:
-        one:   "Ð¼Ð¸Ð½ÑƒÑ‚Ð°Ð°Ñ Ð±Ð°Ð³Ð° Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°"
-        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð°Ð°Ñ Ð±Ð°Ð³Ð° Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°"
-      x_minutes:
-        one:   "1 Ð¼Ð¸Ð½ÑƒÑ‚"
-        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚"
-      about_x_hours:
-        one:   "1 Ñ†Ð°Ð³ Ð¾Ñ€Ñ‡Ð¸Ð¼"
-        other: "Ð¾Ð¹Ñ€Ð¾Ð»Ñ†Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ %{count} Ñ†Ð°Ð³"
-      x_days:
-        one:   "1 Ó©Ð´Ó©Ñ€"
-        other: "%{count} Ó©Ð´Ó©Ñ€"
-      about_x_months:
-        one:   "1 ÑÐ°Ñ€ Ð¾Ñ€Ñ‡Ð¸Ð¼"
-        other: "Ð¾Ð¹Ñ€Ð¾Ð»Ñ†Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ %{count} ÑÐ°Ñ€"
-      x_months:
-        one:   "1 ÑÐ°Ñ€"
-        other: "%{count} ÑÐ°Ñ€"
-      about_x_years:
-        one:   "Ð¾Ð¹Ñ€Ð¾Ð»Ñ†Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ 1 Ð¶Ð¸Ð»"
-        other: "Ð¾Ð¹Ñ€Ð¾Ð»Ñ†Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ %{count} Ð¶Ð¸Ð»"
-      over_x_years:
-        one:   "1 Ð¶Ð¸Ð»ÑÑÑ Ð¸Ñ…"
-        other: "%{count} Ð¶Ð¸Ð»ÑÑÑ Ð¸Ñ…"
-      almost_x_years:
-        one:   "Ð±Ð°Ñ€Ð°Ð³ 1 Ð¶Ð¸Ð»"
-        other: "Ð±Ð°Ñ€Ð°Ð³ %{count} Ð¶Ð¸Ð»"
-
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Ð‘Ð°Ð¹Ñ‚"
-            other: "Ð‘Ð°Ð¹Ñ‚"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "Ð±Ð°Ñ"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ‚Ð°Ð´ Ð·Ð°Ð°Ð³Ð´Ð°Ð°Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°"
-        exclusion: "Ð½Ó©Ó©Ñ†Ð»Ó©Ð³Ð´ÑÓ©Ð½"
-        invalid: "Ð±ÑƒÑ€ÑƒÑƒ"
-        confirmation: "Ð±Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑÐ°Ð½ Ó©Ð³Ó©Ð³Ð´Ó©Ð»Ñ‚ÑÐ¹ Ñ‚Ð°Ð°Ñ€Ð°Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°"
-        accepted: "Ñ…Ò¯Ð»ÑÑÐ¶ Ð°Ð²Ð°Ñ… Ñ‘ÑÑ‚Ð¾Ð¹"
-        empty: "Ñ…Ð¾Ð¾ÑÐ¾Ð½ Ð±Ð°Ð¹Ð¶ Ð±Ð¾Ð»Ð¾Ñ…Ð³Ò¯Ð¹"
-        blank: "Ð±Ð»Ð°Ð½Ðº Ð±Ð°Ð¹Ð¶ Ð±Ð¾Ð»Ð¾Ñ…Ð³Ò¯Ð¹"
-        too_long: "Ð´ÑÐ½Ð´Ò¯Ò¯ ÑƒÑ€Ñ‚ Ð±Ð°Ð¹Ð½Ð° (Ñ…Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð¸Ñ…Ð´ÑÑ %{count} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚)"
-        too_short: "Ð´ÑÐ½Ð´Ò¯Ò¯ Ð±Ð¾Ð³Ð¸Ð½Ð¾ Ð±Ð°Ð¹Ð½Ð° (Ñ…Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð±Ð°Ð³Ð°Ð´Ð°Ð° %{count} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚)"
-        wrong_length: "Ð±ÑƒÑ€ÑƒÑƒ ÑƒÑ€Ñ‚Ñ‚Ð°Ð¹ Ð±Ð°Ð¹Ð½Ð° (Ð·Ð°Ð°Ð²Ð°Ð» %{count} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚)"
-        taken: "Ð°Ð»ÑŒ Ñ…ÑÐ´Ð¸Ð¹Ð½Ñ Ð°Ð²ÑÐ°Ð½ Ð±Ð°Ð¹Ð½Ð°"
-        not_a_number: "Ñ‚Ð¾Ð¾ Ð±Ð¸Ñˆ Ð±Ð°Ð¹Ð½Ð°"
-        not_a_date: "Ð·Ó©Ð² Ð¾Ð³Ð½Ð¾Ð¾ Ð±Ð¸Ñˆ Ð±Ð°Ð¹Ð½Ð°"
-        greater_than: "%{count} Ð¸Ñ… Ð±Ð°Ð¹Ñ… Ñ‘ÑÑ‚Ð¾Ð¹"
-        greater_than_or_equal_to: "must be greater than or equal to %{count}"
-        equal_to: "must be equal to %{count}"
-        less_than: "must be less than %{count}"
-        less_than_or_equal_to: "must be less than or equal to %{count}"
-        odd: "Ð·Ð°Ð°Ð²Ð°Ð» ÑÐ¾Ð½Ð´Ð³Ð¾Ð¹"
-        even: "Ð·Ð°Ð°Ð²Ð°Ð» Ñ‚ÑÐ³Ñˆ"
-        greater_than_start_date: "must be greater than start date"
-        not_same_project: "Ð½ÑÐ³ Ð¸Ð¶Ð¸Ð» Ñ‚Ó©ÑÓ©Ð»Ð´ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°"
-        circular_dependency: "Ð­Ð½Ñ Ñ…Ð°Ñ€ÑŒÑ†Ð°Ð° Ð½ÑŒ Ð³Ð¸Ð½Ð¶Ð¸Ð½(Ñ€ÐµÐºÑƒÑ€ÑÐ¸Ð²) Ñ…Ð°Ñ€ÑŒÑ†Ð°Ð° Ò¯Ò¯ÑÐ³ÑÑ… ÑŽÐ¼ Ð±Ð°Ð¹Ð½Ð°"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: Ð¡Ð¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ
-  
-  general_text_No: 'Ò®Ð³Ò¯Ð¹'
-  general_text_Yes: 'Ð¢Ð¸Ð¹Ð¼'
-  general_text_no: 'Ò¯Ð³Ò¯Ð¹'
-  general_text_yes: 'Ñ‚Ð¸Ð¹Ð¼'
-  general_lang_name: 'Mongolian (ÐœÐ¾Ð½Ð³Ð¾Ð»)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '7'
-  
-  notice_account_updated: Ð”Ð°Ð½ÑÑ‹Ð³ Ð°Ð¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ó©Ó©Ñ€Ñ‡Ð¸Ð»Ð»Ó©Ó©.
-  notice_account_invalid_creditentials: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ð½ÑÑ€ ÑÑÐ²ÑÐ» Ð½ÑƒÑƒÑ† Ò¯Ð³ Ð±ÑƒÑ€ÑƒÑƒ Ð±Ð°Ð¹Ð½Ð°
-  notice_account_password_updated: ÐÑƒÑƒÑ† Ò¯Ð³Ð¸Ð¹Ð³ Ð°Ð¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ó©Ó©Ñ€Ñ‡Ð¸Ð»Ð»Ó©Ó©.
-  notice_account_wrong_password: Ð‘ÑƒÑ€ÑƒÑƒ Ð½ÑƒÑƒÑ† Ò¯Ð³
-  notice_account_register_done: Ð¨Ð¸Ð½Ñ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ Ð°Ð¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ò¯Ò¯ÑÐ³ÑÐ»ÑÑ. Ð˜Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…Ð¸Ð¹Ð½ Ñ‚ÑƒÐ»Ð´, Ð±Ð¸Ð´Ð½Ð¸Ð¹ Ñ‚Ð°Ð½ÑŒ Ð»ÑƒÑƒ Ð¸Ð»Ð³ÑÑÑÑÐ½ Ð¼ÑÐ¹Ð» Ð´Ð¾Ñ‚Ð¾Ñ€ Ð±Ð°Ð¹Ð³Ð°Ð° Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ Ð´Ð°Ñ€Ð°Ð°Ñ€Ð°Ð¹.
-  notice_account_unknown_email: Ò®Ð» Ð¼ÑÐ´ÑÐ³Ð´ÑÑ… Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡.
-  notice_can_t_change_password: Ð­Ð½Ñ ÑÑ€Ñ… Ð³Ð°Ð´Ð°Ð°Ð´ Ð½ÑÐ²Ñ‚Ñ€ÑÐ»Ñ‚ÑÐ´ Ð°ÑˆÐ¸Ð³Ð»Ð°Ð´Ð°Ð³ ÑƒÑ‡Ñ€Ð°Ð°Ñ Ð½ÑƒÑƒÑ† Ò¯Ð³Ð¸Ð¹Ð³ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ… Ð±Ð¾Ð»Ð¾Ð¼Ð¶Ð³Ò¯Ð¹.
-  notice_account_lost_email_sent: Ð‘Ð¸Ð´ Ñ‚Ð°Ð½ÑŒÐ´ Ð¼ÑÐ¹Ð»ÑÑÑ€ Ð½ÑƒÑƒÑ† Ò¯Ð³ÑÑ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ… Ð·Ð°Ð°Ð²Ñ€Ñ‹Ð³ Ð¸Ð»Ð³ÑÑÑÑÐ½ Ð±Ð°Ð¹Ð³Ð°Ð°.
-  notice_account_activated: Ð¢Ð°Ð½Ñ‹ Ð´Ð°Ð½Ñ Ð¸Ð´ÑÐ²Ñ…Ð¶Ð»ÑÑ. ÐžÐ´Ð¾Ð¾ Ð½ÑÐ²Ñ‚ÑÑ€Ñ‡ Ð¾Ñ€Ð¶ Ð±Ð¾Ð»Ð½Ð¾.
-  notice_successful_create: ÐÐ¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ò¯Ò¯ÑÐ³ÑÐ»ÑÑ.
-  notice_successful_update: ÐÐ¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ó©Ó©Ñ€Ñ‡Ð¸Ð»Ð»Ó©Ó©.
-  notice_successful_delete: ÐÐ¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ ÑƒÑÑ‚Ð³Ð°Ð»Ð°Ð°.
-  notice_successful_connection: ÐÐ¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ñ…Ð¾Ð»Ð±Ð¾Ð³Ð´Ð»Ð¾Ð¾.
-  notice_file_not_found: Ð¢Ð°Ð½Ñ‹ Ò¯Ð·ÑÑ… Ð³ÑÑÑÐ½ Ñ…ÑƒÑƒÐ´Ð°Ñ Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ ÑŽÐ¼ÑƒÑƒ ÑƒÑÑ‚Ð³Ð°Ð³Ð´ÑÐ°Ð½ Ð±Ð°Ð¹Ð½Ð°.
-  notice_locking_conflict: Ó¨Ð³Ó©Ð³Ð´Ð»Ð¸Ð¹Ð³ Ó©Ó©Ñ€ Ñ…Ò¯Ð½ Ó©Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½ Ð±Ð°Ð¹Ð½Ð°.
-  notice_not_authorized: Ð¢Ð°Ð½Ð´ ÑÐ½Ñ Ñ…ÑƒÑƒÐ´ÑÑ‹Ð³ Ò¯Ð·ÑÑ… ÑÑ€Ñ… Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°.
-  notice_email_sent: "%{value} - Ñ€ÑƒÑƒ Ð¼ÑÐ¹Ð» Ð¸Ð»Ð³ÑÑÐ»ÑÑ"
-  notice_email_error: "ÐœÑÐ¹Ð» Ð¸Ð»Ð³ÑÑÑ…ÑÐ´ Ð°Ð»Ð´Ð°Ð° Ð³Ð°Ñ€Ð»Ð°Ð° (%{value})"
-  notice_feeds_access_key_reseted: Ð¢Ð°Ð½Ñ‹ RSS Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€Ð¸Ð¹Ð³ Ð´Ð°Ñ…Ð¸Ð½ ÑÑ…Ð»Ò¯Ò¯Ð»Ð»ÑÑ.
-  notice_api_access_key_reseted: Your API access key was reset.
-  notice_failed_to_save_issues: "%{total} Ð°ÑÑƒÑƒÐ´Ð°Ð» ÑÐ¾Ð½Ð³Ð¾Ð³Ð´ÑÐ¾Ð½Ð¾Ð¾Ñ %{count} Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð³ Ð½ÑŒ Ñ…Ð°Ð´Ð³Ð°Ð»Ð°Ñ…Ð°Ð´ Ð°Ð»Ð´Ð°Ð° Ð³Ð°Ñ€Ð»Ð°Ð°: %{ids}."
-  notice_no_issue_selected: "Ð¯Ð¼Ð°Ñ€ Ñ‡ Ð°ÑÑƒÑƒÐ´Ð°Ð» ÑÐ¾Ð½Ð³Ð¾Ð³Ð´Ð¾Ð¾Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°! Ð—Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ… Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ð°Ð° ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ."
-  notice_account_pending: "Ð¢Ð°Ð½Ñ‹ Ð´Ð°Ð½ÑÑ‹Ð³ Ò¯Ò¯ÑÐ³ÑÐ¶ Ð´ÑƒÑƒÑÐ»Ð°Ð°, Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€ Ð±Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑƒÑƒÐ»Ð°Ñ… Ñ…Ò¯Ñ€Ñ‚ÑÐ» Ñ…Ò¯Ð»ÑÑÐ½Ñ Ò¯Ò¯."
-  notice_default_data_loaded: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ñ‚Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾Ð³ Ð°Ð¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ð°Ñ‡Ð°Ð°Ð»Ð»Ð°Ð°.
-  notice_unable_delete_version: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ… Ð±Ð¾Ð»Ð¾Ð¼Ð¶Ð³Ò¯Ð¹.
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  
-  error_can_t_load_default_data: "Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ñ‚Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾Ð³ Ð°Ñ‡Ð°Ð°Ð»Ð¶ Ñ‡Ð°Ð´ÑÐ°Ð½Ð³Ò¯Ð¹: %{value}"
-  error_scm_not_found: "Repository Ð´Ð¾Ñ‚Ð¾Ñ€ Ñ‚ÑƒÑ…Ð°Ð¹Ð½ Ð±Ð¸Ñ‡Ð»ÑÐ³ ÑÑÐ²ÑÐ» Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ñ‹Ð³ Ð¾Ð»ÑÐ¾Ð½Ð³Ò¯Ð¹."
-  error_scm_command_failed: "Repository-Ð´ Ñ…Ð°Ð½Ð´Ð°Ñ…Ð°Ð´ Ð°Ð»Ð´Ð°Ð° Ð³Ð°Ñ€Ð»Ð°Ð°:  %{value}"
-  error_scm_annotate: "Ð‘Ð¸Ñ‡Ð»ÑÐ³ Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°, ÑÑÐ²ÑÐ» Ð±Ð¸Ñ‡Ð»ÑÐ³Ñ‚ Ñ‚Ð°Ð¹Ð»Ð±Ð°Ñ€ Ñ…Ð°Ð²ÑÐ°Ñ€Ð³Ð°Ð¶ Ð±Ð¾Ð»Ð¾Ñ…Ð³Ò¯Ð¹."
-  error_issue_not_found_in_project: 'Ð¡Ð¾Ð½Ð³Ð¾ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ´Ð°Ð» ÑÐ½Ñ Ñ‚Ó©ÑÓ©Ð»Ð´ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð´Ð°Ð³Ð³Ò¯Ð¹ ÑŽÐ¼ ÑƒÑƒ ÑÑÐ²ÑÐ» ÑÐ¸ÑÑ‚ÐµÐ¼Ð´ Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°.'
-  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
-  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
-  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version can not be reopened'
-  error_can_not_archive_project: This project can not be archived
-  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
-  error_workflow_copy_source: 'Please select a source tracker or role'
-  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
-  
-  warning_attachments_not_saved: "%{count} file(s) Ñ„Ð°Ð¹Ð»Ñ‹Ð³ Ñ…Ð°Ð´Ð³Ð°Ð»Ð¶ Ñ‡Ð°Ð´ÑÐ°Ð½Ð³Ò¯Ð¹."
-  
-  mail_subject_lost_password: "Ð¢Ð°Ð½Ñ‹ %{value} Ð½ÑƒÑƒÑ† Ò¯Ð³"
-  mail_body_lost_password: 'ÐÑƒÑƒÑ† Ò¯Ð³ÑÑ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…Ð¸Ð¹Ð½ Ñ‚ÑƒÐ»Ð´ Ð´Ð¾Ð¾Ñ€Ñ… Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ Ð´Ð°Ñ€Ð½Ð° ÑƒÑƒ:'
-  mail_subject_register: "Ð¢Ð°Ð½Ñ‹ %{value} Ð´Ð°Ð½ÑÑ‹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…"
-  mail_body_register: 'Ð”Ð°Ð½ÑÐ°Ð° Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…Ð¸Ð¹Ð½ Ñ‚ÑƒÐ»Ð´ Ð´Ð¾Ð¾Ñ€Ñ… Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ Ð´Ð°Ñ€Ð½Ð° ÑƒÑƒ:'
-  mail_body_account_information_external: "Ð¢Ð° Ó©Ó©Ñ€Ð¸Ð¹Ð½Ñ…Ó©Ó© %{value} Ð´Ð°Ð½ÑÑ‹Ð³ Ð°ÑˆÐ¸Ð³Ð»Ð°Ð¶ Ñ…Ð¾Ð»Ð±Ð¾Ð³Ð´Ð¾Ð¶ Ð±Ð¾Ð»Ð½Ð¾."
-  mail_body_account_information: Ð¢Ð°Ð½Ñ‹ Ð´Ð°Ð½ÑÐ½Ñ‹ Ñ‚ÑƒÑ…Ð°Ð¹ Ð¼ÑÐ´ÑÑÐ»ÑÐ»
-  mail_subject_account_activation_request: "%{value} Ð´Ð°Ð½ÑÑ‹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ… Ñ…Ò¯ÑÑÐ»Ñ‚"
-  mail_body_account_activation_request: "Ð¨Ð¸Ð½Ñ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ (%{value}) Ð±Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑÐ½ Ð±Ð°Ð¹Ð½Ð°. Ð¢Ð°Ð½Ñ‹ Ð±Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑƒÑƒÐ»Ð°Ñ…Ñ‹Ð³ Ñ…Ò¯Ð»ÑÑÐ¶ Ð±Ð°Ð¹Ð½Ð°:"
-  mail_subject_reminder: "Ð”Ð°Ñ€Ð°Ð°Ð³Ð¸Ð¹Ð½ Ó©Ð´Ñ€Ò¯Ò¯Ð´ÑÐ´ %{count} Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð³ ÑˆÐ¸Ð¹Ð´ÑÑ… Ñ…ÑÑ€ÑÐ³Ñ‚ÑÐ¹ (%{days})"
-  mail_body_reminder: "Ð¢Ð°Ð½Ð´ Ð¾Ð½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½ %{count} Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð´Ð°Ñ€Ð°Ð°Ð³Ð¸Ð¹Ð½ %{days} Ó©Ð´Ñ€Ò¯Ò¯Ð´ÑÐ´ ÑˆÐ¸Ð¹Ð´ÑÑ… Ñ…ÑÑ€ÑÐ³Ñ‚ÑÐ¹:"
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
-  
-  gui_validation_error: 1 Ð°Ð»Ð´Ð°Ð°
-  gui_validation_error_plural: "%{count} Ð°Ð»Ð´Ð°Ð°"
-  
-  field_name: ÐÑÑ€
-  field_description: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€
-  field_summary: Ð”Ò¯Ð³Ð½ÑÐ»Ñ‚
-  field_is_required: Ð—Ð°Ð¹Ð»ÑˆÐ³Ò¯Ð¹
-  field_firstname: Ð¢Ð°Ð½Ñ‹ Ð½ÑÑ€
-  field_lastname: ÐžÐ²Ð¾Ð³
-  field_mail: Ð˜Ð¼ÑÐ¹Ð»
-  field_filename: Ð¤Ð°Ð¹Ð»
-  field_filesize: Ð¥ÑÐ¼Ð¶ÑÑ
-  field_downloads: Ð¢Ð°Ñ‚Ð°Ð¶ Ð°Ð²Ð°Ñ… Ð·Ò¯Ð¹Ð»Ñ
-  field_author: Ð—Ð¾Ñ…Ð¸Ð¾Ð³Ñ‡
-  field_created_on: Ò®Ò¯ÑÑÑÐ½
-  field_updated_on: Ó¨Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½
-  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
-  field_is_for_all: Ð‘Ò¯Ñ… Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´
-  field_possible_values: Ð‘Ð¾Ð»Ð¾Ð¼Ð¶Ñ‚Ð¾Ð¹ ÑƒÑ‚Ð³ÑƒÑƒÐ´
-  field_regexp: Ð­Ð½Ð³Ð¸Ð¹Ð½ Ð¸Ð»ÑÑ€Ñ…Ð¸Ð¹Ð»ÑÐ»
-  field_min_length: ÐœÐ¸Ð½Ð¸Ð¼ÑƒÐ¼ ÑƒÑ€Ñ‚
-  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼ÑƒÐ¼ ÑƒÑ€Ñ‚
-  field_value: Ð£Ñ‚Ð³Ð°
-  field_category: Ð¢Ó©Ñ€Ó©Ð»
-  field_title: Ð“Ð°Ñ€Ñ‡Ð¸Ð³
-  field_project: Ð¢Ó©ÑÓ©Ð»
-  field_issue: ÐÑÑƒÑƒÐ´Ð°Ð»
-  field_status: Ð¢Ó©Ð»Ó©Ð²
-  field_notes: Ð¢ÑÐ¼Ð´ÑÐ³Ð»ÑÐ»Ò¯Ò¯Ð´
-  field_is_closed: ÐÑÑƒÑƒÐ´Ð°Ð» Ñ…Ð°Ð°Ð³Ð´ÑÐ°Ð½
-  field_is_default: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ ÑƒÑ‚Ð³Ð°
-  field_tracker: Ð§Ð¸Ð³Ð»ÑÐ»
-  field_subject: Ð“Ð°Ñ€Ñ‡Ð¸Ð³
-  field_due_date: Ð”ÑƒÑƒÑÐ°Ñ… Ð¾Ð³Ð½Ð¾Ð¾
-  field_assigned_to: ÐžÐ½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½
-  field_priority: Ð—ÑÑ€ÑÐ³Ð»ÑÐ»
-  field_fixed_version: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
-  field_user: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡
-  field_role: Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…
-  field_homepage: ÐÒ¯Ò¯Ñ€ Ñ…ÑƒÑƒÐ´Ð°Ñ
-  field_is_public: ÐžÐ»Ð¾Ð½ Ð½Ð¸Ð¹Ñ‚Ð¸Ð¹Ð½
-  field_parent: Ð­Ñ†ÑÐ³ Ñ‚Ó©ÑÓ©Ð» Ð½ÑŒ
-  field_is_in_roadmap: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑÐ²Ñ†Ñ‹Ð½ Ð·ÑƒÑ€Ð°Ð³ Ð´ÑÑÑ€ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ…
-  field_login: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð½ÑÑ€
-  field_mail_notification: Ð˜Ð¼ÑÐ¹Ð» Ð¼ÑÐ´ÑÐ³Ð´Ð»Ò¯Ò¯Ð´
-  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
-  field_last_login_on: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ñ…Ð¾Ð»Ð±Ð¾Ð¾
-  field_language: Ð¥ÑÐ»
-  field_effective_date: ÐžÐ³Ð½Ð¾Ð¾
-  field_password: ÐÑƒÑƒÑ† Ò¯Ð³
-  field_new_password: Ð¨Ð½Ð½Ñ Ð½ÑƒÑƒÑ† Ò¯Ð³
-  field_password_confirmation: Ð‘Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑƒÑƒÐ»Ð°Ñ…
-  field_version: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
-  field_type: Ð¢Ó©Ñ€Ó©Ð»
-  field_host: Ð¥Ð¾ÑÑ‚
-  field_port: ÐŸÐ¾Ñ€Ñ‚
-  field_account: Ð”Ð°Ð½Ñ
-  field_base_dn: Ò®Ð½Ð´ÑÑÐ½ Ð”Ð
-  field_attr_login: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
-  field_attr_firstname: Ð¢Ð°Ð½Ñ‹ Ð½ÑÑ€ Ð°Ñ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
-  field_attr_lastname: ÐžÐ²Ð¾Ð³ Ð°Ñ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
-  field_attr_mail: Ð˜Ð¼ÑÐ¹Ð» Ð°Ñ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
-  field_onthefly: Ð¥Ò¯ÑÑÑÐ½ Ò¯ÐµÐ´ÑÑ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ Ò¯Ò¯ÑÐ³ÑÑ…
-  field_start_date: Ð­Ñ…Ð»ÑÐ»
-  field_done_ratio: "%% Ð“Ò¯Ð¹Ñ†ÑÑ‚Ð³ÑÑÑÐ½"
-  field_auth_source: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ€Ð³Ð°
-  field_hide_mail: ÐœÐ¸Ð½Ð¸Ð¹ Ð¸Ð¼ÑÐ¹Ð» Ñ…Ð°ÑÐ³Ð¸Ð¹Ð³ Ð½ÑƒÑƒ
-  field_comments: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€
-  field_url: URL Ð¥Ð°ÑÐ³
-  field_start_page: Ð¢ÑÑ€Ð³Ò¯Ò¯Ð½ Ñ…ÑƒÑƒÐ´Ð°Ñ
-  field_subproject: Ð”ÑÐ´ Ñ‚Ó©ÑÓ©Ð»
-  field_hours: Ð¦Ð°Ð³
-  field_activity: Ò®Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°
-  field_spent_on: ÐžÐ³Ð½Ð¾Ð¾
-  field_identifier: Ð¢Ó©ÑÐ»Ð¸Ð¹Ð½ Ð³Ð»Ð¾Ð±Ð°Ð» Ð½ÑÑ€
-  field_is_filter: Ð¨Ò¯Ò¯Ð»Ñ‚Ò¯Ò¯Ñ€ Ð±Ð¾Ð»Ð³Ð¾Ð½ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ð´Ð´ÑÐ³
-  field_issue_to: Ð¥Ð°Ð¼Ð°Ð°Ñ‚Ð°Ð¹ Ð°ÑÑƒÑƒÐ´Ð°Ð»
-  field_delay: Ð¥Ð¾Ñ†Ñ€Ð¾Ð»Ñ‚
-  field_assignable: Ð­Ð½Ñ Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…ÑÐ´ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð¾Ð½Ð¾Ð¾Ð¶ Ó©Ð³Ñ‡ Ð±Ð¾Ð»Ð½Ð¾
-  field_redirect_existing_links: Ð‘Ð°Ð¹Ð³Ð°Ð° Ñ…Ð¾Ð»Ð±Ð¾Ð¾ÑÑƒÑƒÐ´Ñ‹Ð³ Ð´Ð°Ñ…Ð¸Ð½ Ñ‡Ð¸Ð³Ð»Ò¯Ò¯Ð»ÑÑ…
-  field_estimated_hours: Ð‘Ð°Ñ€Ð°Ð³Ñ†Ð°Ð°Ð»ÑÐ°Ð½ Ñ†Ð°Ð³
-  field_column_names: Ð‘Ð°Ð³Ð°Ð½ÑƒÑƒÐ´
-  field_time_zone: Ð¦Ð°Ð³Ñ‹Ð½ Ð±Ò¯Ñ
-  field_searchable: Ð¥Ð°Ð¹Ð¶ Ð±Ð¾Ð»Ð¾Ñ…
-  field_default_value: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ ÑƒÑ‚Ð³Ð°
-  field_comments_sorting: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€ÑƒÑƒÐ»
-  field_parent_title: Ð­Ñ†ÑÐ³ Ñ…ÑƒÑƒÐ´Ð°Ñ
-  field_editable: Ð—Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ð³Ð´Ð°Ð½Ð°
-  field_watcher: Ð¥Ð°Ñ€Ð½Ð°
-  field_identity_url: OpenID URL
-  field_content: ÐÐ³ÑƒÑƒÐ»Ð³Ð°
-  field_group_by: Ò®Ñ€ Ð´Ò¯Ð½Ð³ÑÑÑ€ Ð±Ò¯Ð»ÑÐ³Ð»ÑÑ…
-  field_sharing: Sharing
-  
-  setting_app_title: ÐŸÑ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹Ð½ Ð³Ð°Ñ€Ñ‡Ð¸Ð³
-  setting_app_subtitle: ÐŸÑ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹Ð½ Ð´ÑÐ´ Ð³Ð°Ñ€Ñ‡Ð¸Ð³
-  setting_welcome_text: ÐœÑÐ½Ð´Ñ‡Ð¸Ð»Ð³ÑÑ
-  setting_default_language: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ñ…ÑÐ»
-  setting_login_required: ÐÑÐ²Ñ‚Ñ€ÑÑ… ÑˆÐ°Ð°Ñ€Ð´Ð»Ð°Ð³Ð°Ñ‚Ð°Ð¹
-  setting_self_registration: Ó¨Ó©Ñ€Ð¸Ð¹Ð³Ó©Ó© Ð±Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑ…
-  setting_attachment_max_size: Ð¥Ð°Ð²ÑÑ€Ð°Ð»Ñ‚ Ñ„Ð°Ð¹Ð»Ñ‹Ð½ Ð´ÑÑÐ´ Ñ…ÑÐ¼Ð¶ÑÑ
-  setting_issues_export_limit: ÐÑÑƒÑƒÐ´Ð°Ð» ÑÐºÑÐ¿Ð¾Ñ€Ñ‚Ð»Ð¾Ñ… Ñ…ÑÐ·Ð³Ð°Ð°Ñ€
-  setting_mail_from: Ð¯Ð¼Ð°Ñ€ Ð¸Ð¼ÑÐ¹Ð» Ñ…Ð°ÑÐ³ Ò¯Ò¯ÑÐ³ÑÑ…
-  setting_bcc_recipients: BCC Ñ‚Ð°Ð»Ð±Ð°Ñ€Ñ‹Ð½ Ñ…Ð°ÑÐ³ÑƒÑƒÐ´ (bcc)
-  setting_plain_text_mail: Ð´Ð°Ð½ Ñ‚ÐµÐºÑÑ‚ Ð¼ÑÐ¹Ð» (HTML Ð±Ð¸Ñˆ)
-  setting_host_name: Ð¥Ð¾ÑÑ‚Ñ‹Ð½ Ð½ÑÑ€ Ð±Ð¾Ð»Ð¾Ð½ Ð·Ð°Ð¼
-  setting_text_formatting: Ð¢ÐµÐºÑÑ‚ Ñ…ÑÐ»Ð±ÑÑ€Ð¶Ò¯Ò¯Ð»ÑÐ»Ñ‚
-  setting_wiki_compression: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð½ Ñ‚Ò¯Ò¯Ñ… Ð´ÑÑÑ€ ÑˆÐ°Ñ…Ð°Ð»Ñ‚ Ñ…Ð¸Ð¹Ñ…
-  setting_feeds_limit: Ð¤Ð¸Ð¹Ð´ Ð°Ð³ÑƒÑƒÐ»Ð³Ñ‹Ð½ Ñ…ÑÐ·Ð³Ð°Ð°Ñ€
-  setting_default_projects_public: Ð¨Ð¸Ð½Ñ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð°Ð°Ñ€ Ð¾Ð»Ð¾Ð½ Ð½Ð¸Ð¹Ñ‚Ð¸Ð¹Ð½Ñ… Ð±Ð°Ð¹Ð½Ð°
-  setting_autofetch_changesets: ÐšÐ¾Ð¼Ð¸Ñ‚ÑƒÑƒÐ´Ñ‹Ð³ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð°Ð°Ñ€ Ñ‚Ð°Ñ‚Ð°Ð¶ Ð°Ð²Ð°Ñ…
-  setting_sys_api_enabled: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸ Ð¼ÐµÐ½ÐµÐ¶Ð¼ÐµÐ½Ñ‚ÑÐ´ Ð·Ð¾Ñ€Ð¸ÑƒÐ»Ð°Ð½ WS-Ð¸Ð¹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
-  setting_commit_ref_keywords: Ð¥Ð°Ð¼Ð°Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ… Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ Ò¯Ð³Ñ
-  setting_commit_fix_keywords: Ð—Ð¾Ð¾Ð»Ñ‚Ñ‚Ð¾Ð¹ Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ Ò¯Ð³Ñ
-  setting_autologin: ÐšÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€ Ð´ÑÑÑ€ ÑÐ°Ð½Ð°Ñ…
-  setting_date_format: ÐžÐ³Ð½Ð¾Ð¾Ð½Ñ‹ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚
-  setting_time_format: Ð¦Ð°Ð³Ð¸Ð¹Ð½ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚
-  setting_cross_project_issue_relations: Ð¢Ó©ÑÓ©Ð» Ñ…Ð¾Ð¾Ñ€Ð¾Ð½Ð´ Ð°ÑÑƒÑƒÐ´Ð°Ð» Ñ…Ð°Ð¼Ð°Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ…Ñ‹Ð³ Ð·Ó©Ð²ÑˆÓ©Ó©Ñ€Ó©Ñ…
-  setting_issue_list_default_columns: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ… ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ð±Ð°Ð³Ð°Ð½ÑƒÑƒÐ´
-  setting_emails_footer: Ð˜Ð¼ÑÐ¹Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…Ó©Ð» Ñ…ÑÑÑÐ³
-  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
-  setting_per_page_options: ÐÑÐ³ Ñ…ÑƒÑƒÐ´ÑÐ°Ð½Ð´ Ð±Ð°Ð¹Ñ… Ð¾Ð±ÑŒÐµÐºÑ‚ÑƒÑƒÐ´Ñ‹Ð½ Ñ‚Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾
-  setting_user_format: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð´Ð¸Ð¹Ð³ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ… Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚
-  setting_activity_days_default: Ð¢Ó©ÑÐ»Ð¸Ð¹Ð½ Ò¯Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð° Ñ…ÑÑÑÐ³Ñ‚ Ò¯Ð·Ò¯Ò¯Ð»ÑÑ… Ó©Ð´Ñ€Ð¸Ð¹Ð½ Ñ‚Ð¾Ð¾
-  setting_display_subprojects_issues: Ð”ÑÐ´ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð°Ð°Ñ€ Ð³Ð¾Ð» Ñ‚Ó©ÑÓ©Ð» Ð´ÑÑÑ€ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ…
-  setting_enabled_scm: SCM - Ð¸Ð¹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
-  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
-  setting_mail_handler_api_enabled: Ð˜Ñ€ÑÑÐ½ Ð¼ÑÐ¹Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´ WS-Ð¸Ð¹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
-  setting_mail_handler_api_key: API Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€
-  setting_sequential_project_identifiers: Ð”ÑÑ Ð´Ð°Ñ€Ð°Ð°Ð»ÑÐ°Ð½ Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ð³Ð»Ð¾Ð±Ð°Ð» Ð½ÑÑ€ Ò¯Ò¯ÑÐ³ÑÐ¶ Ð±Ð°Ð¹Ñ…
-  setting_gravatar_enabled: Gravatar Ð´Ò¯Ñ€ÑÒ¯Ò¯Ð´Ð¸Ð¹Ð³ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð´ÑÐ´ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ¶ Ð±Ð°Ð¹Ñ…
-  setting_gravatar_default: Default Gravatar image
-  setting_diff_max_lines_displayed: Ð¯Ð»Ð³Ð°Ð°Ñ‚Ð°Ð¹ Ð¼Ó©Ñ€Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ‚Ð¾Ð¾ (Ð´ÑÑÐ´ Ñ‚Ð°Ð» Ð½ÑŒ)
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_openid: Allow OpenID login and registration
-  setting_password_min_length: Minimum password length
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_field: Use the issue field
-  setting_issue_done_ratio_issue_status: Use the issue status
-  setting_start_of_week: Start calendars on
-  setting_rest_api_enabled: Enable REST web service
-  setting_cache_formatted_text: Cache formatted text
-  
-  permission_add_project: Create project
-  permission_add_subprojects: Create subprojects
-  permission_edit_project: Ð¢Ó©ÑÐ»Ð¸Ð¹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  permission_select_project_modules: Ð¢Ó©ÑÐ»Ð¸Ð¹Ð½ Ð¼Ð¾Ð´ÑƒÐ»ÑƒÑƒÐ´Ð¸Ð¹Ð³ ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ
-  permission_manage_members: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð¸Ð¹Ð½ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð´
-  permission_manage_project_activities: Manage project activities
-  permission_manage_versions: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
-  permission_manage_categories: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ð°Ð½Ð³Ð¸Ð»Ð»ÑƒÑƒÐ´
-  permission_view_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  permission_add_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´ Ð½ÑÐ¼ÑÑ…
-  permission_edit_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  permission_manage_issue_relations: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð»Ñ‹Ð³ Ð·Ð¾Ñ…Ð¸Ñ†ÑƒÑƒÐ»Ð°Ñ…
-  permission_add_issue_notes: Ð¢ÑÐ¼Ð´ÑÐ³Ð»ÑÐ» Ð½ÑÐ¼ÑÑ…
-  permission_edit_issue_notes: Ð¢ÑÐ¼Ð´ÑÐ³Ð»ÑÐ»Ò¯Ò¯Ð´ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  permission_edit_own_issue_notes: Ó¨Ó©Ñ€Ð¸Ð¹Ð½ Ò¯Ð»Ð´ÑÑÑÑÐ½ Ñ‚ÑÐ¼Ð´ÑÐ³Ð»ÑÐ»Ò¯Ò¯Ð´Ð¸Ð¹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  permission_move_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð·Ó©Ó©Ñ…
-  permission_delete_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
-  permission_manage_public_queries: ÐžÐ»Ð¾Ð½ Ð½Ð¸Ð¹Ñ‚Ð¸Ð¹Ð½ Ð°ÑÑƒÑƒÐ»Ñ‚ÑƒÑƒÐ´
-  permission_save_queries: ÐÑÑƒÑƒÐ»Ñ‚ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ð´Ð³Ð°Ð»Ð°Ñ…
-  permission_view_gantt: Ð“Ð°Ð½Ñ‚ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ñ‹Ð³ Ò¯Ð·ÑÑ…
-  permission_view_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€ÑŒ Ò¯Ð·ÑÑ…
-  permission_view_issue_watchers: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ñ‡Ð´Ñ‹Ð½ Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ‚Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  permission_add_issue_watchers: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ñ‡Ð¸Ð´ Ð½ÑÐ¼ÑÑ…
-  permission_delete_issue_watchers: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ñ‡Ð´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
-  permission_log_time: Ð—Ð°Ñ€Ñ†ÑƒÑƒÐ»ÑÐ°Ð½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð³ Ð»Ð¾Ð³ Ñ…Ð¸Ð¹Ñ…
-  permission_view_time_entries: Ð—Ð°Ñ€Ñ†ÑƒÑƒÐ»ÑÐ°Ð½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  permission_edit_time_entries: Ð¥ÑƒÐ³Ð°Ñ†Ð°Ð°Ð½Ñ‹ Ð»Ð¾Ð³ÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  permission_edit_own_time_entries: Ó¨Ó©Ñ€Ð¸Ð¹Ð½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð½Ñ‹ Ð»Ð¾Ð³ÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  permission_manage_news: ÐœÑÐ´ÑÑ Ð¼ÑÐ´ÑÑÐ»Ð»Ò¯Ò¯Ð´
-  permission_comment_news: ÐœÑÐ´ÑÑÐ½Ð´ Ñ‚Ð°Ð¹Ð»Ð±Ð°Ñ€ Ò¯Ð»Ð´ÑÑÑ…
-  permission_manage_documents: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ÑƒÑƒÐ´
-  permission_view_documents: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  permission_manage_files: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´
-  permission_view_files: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  permission_manage_wiki: Ð’Ð¸ÐºÐ¸ ÑƒÐ´Ð¸Ñ€Ð´Ð°Ñ…
-  permission_rename_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ Ð´Ð°Ñ…Ð¸Ð¶ Ð½ÑÑ€Ð»ÑÑ…
-  permission_delete_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
-  permission_view_wiki_pages: Ð’Ð¸ÐºÐ¸ Ò¯Ð·ÑÑ…
-  permission_view_wiki_edits: Ð’Ð¸ÐºÐ¸ Ñ‚Ò¯Ò¯Ñ… Ò¯Ð·ÑÑ…
-  permission_edit_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  permission_delete_wiki_pages_attachments: Ð¥Ð°Ð²ÑÑ€Ð°Ð»Ñ‚ÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
-  permission_protect_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ð¼Ð³Ð°Ð°Ð»Ð°Ñ…
-  permission_manage_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸
-  permission_browse_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ð¹Ð³ Ò¯Ð·ÑÑ…
-  permission_view_changesets: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  permission_commit_access: ÐšÐ¾Ð¼Ð¼Ð¸Ñ‚ Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚
-  permission_manage_boards: Ð¡Ð°Ð¼Ð±Ð°Ñ€ÑƒÑƒÐ´
-  permission_view_messages: Ð—ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  permission_add_messages: Ð—ÑƒÑ€Ð²Ð°Ñ Ð¸Ð»Ð³ÑÑÑ…
-  permission_edit_messages: Ð—ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  permission_edit_own_messages: Ó¨Ó©Ñ€Ð¸Ð¹Ð½ Ð·ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  permission_delete_messages: Ð—ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
-  permission_delete_own_messages: Ó¨Ó©Ñ€Ð¸Ð¹Ð½ Ð·ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
-  permission_export_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ ÑÐºÑÐ¿Ð¾Ñ€Ñ‚ Ñ…Ð¸Ð¹Ñ…
-  
-  project_module_issue_tracking: ÐÑÑƒÑƒÐ´Ð°Ð» Ñ…ÑÐ½Ð°Ñ…
-  project_module_time_tracking: Ð¥ÑƒÐ³Ð°Ñ†Ð°Ð° Ñ…ÑÐ½Ð°Ñ…
-  project_module_news: ÐœÑÐ´ÑÑ Ð¼ÑÐ´ÑÑÐ»Ð»Ò¯Ò¯Ð´
-  project_module_documents: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ÑƒÑƒÐ´
-  project_module_files: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´
-  project_module_wiki: Ð’Ð¸ÐºÐ¸
-  project_module_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸
-  project_module_boards: Ð¡Ð°Ð¼Ð±Ð°Ñ€ÑƒÑƒÐ´
-  
-  label_user: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡
-  label_user_plural: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð´
-  label_user_new: Ð¨Ð¸Ð½Ñ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡
-  label_user_anonymous: Ð¥Ð°Ð¼Ð°Ð°Ð³Ò¯Ð¹ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡
-  label_project: Ð¢Ó©ÑÓ©Ð»
-  label_project_new: Ð¨Ð¸Ð½Ñ Ñ‚Ó©ÑÓ©Ð»
-  label_project_plural: Ð¢Ó©ÑÐ»Ò¯Ò¯Ð´
-  label_x_projects:
-    zero:  Ñ‚Ó©ÑÓ©Ð» Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹
-    one:   1 Ñ‚Ó©ÑÓ©Ð»
-    other: "%{count} Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´"
-  label_project_all: Ð‘Ò¯Ñ… Ð¢Ó©ÑÐ»Ò¯Ò¯Ð´
-  label_project_latest: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ò¯ÐµÐ¸Ð¹Ð½ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´
-  label_issue: ÐÑÑƒÑƒÐ´Ð°Ð»
-  label_issue_new: Ð¨Ð¸Ð½Ñ Ð°ÑÑƒÑƒÐ´Ð°Ð»
-  label_issue_plural: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
-  label_issue_view_all: Ð‘Ò¯Ñ… Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  label_issues_by: "%{value} - Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´"
-  label_issue_added: ÐÑÑƒÑƒÐ´Ð°Ð» Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
-  label_issue_updated: ÐÑÑƒÑƒÐ´Ð°Ð» Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð³Ð´Ð»Ó©Ó©
-  label_document: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚
-  label_document_new: Ð¨Ð¸Ð½Ñ Ð±Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚
-  label_document_plural: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ÑƒÑƒÐ´
-  label_document_added: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
-  label_role: Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…
-  label_role_plural: Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…Ò¯Ò¯Ð´
-  label_role_new: Ð¨Ð¸Ð½Ñ Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…
-  label_role_and_permissions: Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…Ò¯Ò¯Ð´ Ð±Ð¾Ð»Ð¾Ð½ Ð·Ó©Ð²ÑˆÓ©Ó©Ñ€Ð»Ò¯Ò¯Ð´
-  label_member: Ð“Ð¸ÑˆÒ¯Ò¯Ð½
-  label_member_new: Ð¨Ð¸Ð½Ñ Ð³Ð¸ÑˆÒ¯Ò¯Ð½
-  label_member_plural: Ð“Ð¸ÑˆÒ¯Ò¯Ð´
-  label_tracker: Ð§Ð¸Ð³Ð»ÑÐ»
-  label_tracker_plural: Ð§Ð¸Ð³Ð»ÑÐ»Ò¯Ò¯Ð´
-  label_tracker_new: Ð¨Ð¸Ð½Ñ Ñ‡Ð¸Ð³Ð»ÑÐ»
-  label_workflow: ÐÐ¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð°Ð»
-  label_issue_status: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‚Ó©Ð»Ó©Ð²
-  label_issue_status_plural: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‚Ó©Ð»Ð²Ò¯Ò¯Ð´
-  label_issue_status_new: Ð¨Ð¸Ð½Ñ Ñ‚Ó©Ð»Ó©Ð²
-  label_issue_category: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ð°Ð½Ð³Ð¸Ð»Ð°Ð»
-  label_issue_category_plural: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ð°Ð½Ð³Ð¸Ð»Ð»ÑƒÑƒÐ´
-  label_issue_category_new: Ð¨Ð¸Ð½Ñ Ð°Ð½Ð³Ð¸Ð»Ð°Ð»
-  label_custom_field: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ñ‚Ð°Ð»Ð±Ð°Ñ€
-  label_custom_field_plural: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ñ‚Ð°Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
-  label_custom_field_new: Ð¨Ð¸Ð½ÑÑÑ€ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ñ‚Ð°Ð»Ð±Ð°Ñ€ Ò¯Ò¯ÑÐ³ÑÑ…
-  label_enumerations: ÐÐ½Ð³Ð¸Ð»Ð»ÑƒÑƒÐ´
-  label_enumeration_new: Ð¨Ð¸Ð½Ñ ÑƒÑ‚Ð³Ð°
-  label_information: ÐœÑÐ´ÑÑÐ»ÑÐ»
-  label_information_plural: ÐœÑÐ´ÑÑÐ»Ð»Ò¯Ò¯Ð´
-  label_please_login: ÐÑÐ²Ñ‚ÑÑ€Ñ‡ Ð¾Ñ€Ð½Ð¾ ÑƒÑƒ
-  label_register: Ð‘Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑ…
-  label_login_with_open_id_option: or login with OpenID
-  label_password_lost: ÐÑƒÑƒÑ† Ò¯Ð³ÑÑ Ð°Ð»Ð´ÑÐ°Ð½
-  label_home: ÐÒ¯Ò¯Ñ€
-  label_my_page: ÐœÐ¸Ð½Ð¸Ð¹ Ñ…ÑƒÑƒÐ´Ð°Ñ
-  label_my_account: ÐœÐ¸Ð½Ð¸Ð¹ Ð´Ð°Ð½Ñ
-  label_my_projects: ÐœÐ¸Ð½Ð¸Ð¹ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´
-  label_administration: ÐÐ´Ð¼Ð¸Ð½ Ñ…ÑÑÑÐ³
-  label_login: ÐÑÐ²Ñ‚Ñ€ÑÑ…
-  label_logout: Ð“Ð°Ñ€Ð°Ñ…
-  label_help: Ð¢ÑƒÑÐ»Ð°Ð¼Ð¶
-  label_reported_issues: ÐœÑÐ´ÑÐ³Ð´ÑÑÐ½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
-  label_assigned_to_me_issues: ÐÐ°Ð´Ð°Ð´ Ð¾Ð½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
-  label_last_login: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ñ…Ð¾Ð»Ð±Ð¾Ð»Ñ‚
-  label_registered_on: Ð‘Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑÐ½ Ð¾Ð³Ð½Ð¾Ð¾
-  label_activity: Ò®Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°
-  label_overall_activity: Ð•Ñ€Ó©Ð½Ñ…Ð¸Ð¹ Ò¯Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°
-  label_user_activity: "%{value}-Ð¸Ð¹Ð½ Ò¯Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°"
-  label_new: Ð¨Ð¸Ð½Ñ
-  label_logged_as: Ð¥Ð¾Ð»Ð±Ð¾Ð³Ð´ÑÐ¾Ð½ Ð½ÑÑ€
-  label_environment: ÐžÑ€Ñ‡Ð¸Ð½
-  label_authentication: ÐÑÐ²Ñ‚Ñ€ÑÑ…
-  label_auth_source: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ€Ð³Ð°
-  label_auth_source_new: Ð¨Ð¸Ð½Ñ Ð½ÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ€Ð³Ð°
-  label_auth_source_plural: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ€Ð³ÑƒÑƒÐ´
-  label_subproject_plural: Ð”ÑÐ´ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´
-  label_subproject_new: Ð¨Ð¸Ð½Ñ Ð´ÑÐ´ Ñ‚Ó©ÑÓ©Ð»
-  label_and_its_subprojects: "%{value} Ð±Ð¾Ð»Ð¾Ð½ Ñ…Ð¾Ð»Ð±Ð¾Ð³Ð´Ð¾Ñ… Ð´ÑÐ´ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´"
-  label_min_max_length: Ð”ÑÑÐ´ - Ð”Ð¾Ð¾Ð´ ÑƒÑ€Ñ‚
-  label_list: Ð–Ð°Ð³ÑÐ°Ð°Ð»Ñ‚
-  label_date: ÐžÐ³Ð½Ð¾Ð¾
-  label_integer: Ð‘Ò¯Ñ…ÑÐ» Ñ‚Ð¾Ð¾
-  label_float: Ð‘ÑƒÑ‚Ð°Ñ€Ñ…Ð°Ð¹ Ñ‚Ð¾Ð¾
-  label_boolean: Ò®Ð½ÑÐ½ Ñ…ÑƒÐ´Ð°Ð» ÑƒÑ‚Ð³Ð°
-  label_string: Ð¢ÐµÐºÑÑ‚
-  label_text: Ð£Ñ€Ñ‚ Ñ‚ÐµÐºÑÑ‚
-  label_attribute: ÐÑ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
-  label_attribute_plural: ÐÑ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚ÑƒÑƒÐ´
-  label_download: "%{count} Ð¢Ð°Ñ‚Ð°Ð¶ Ð°Ð²ÑÐ°Ð½ Ð·Ò¯Ð¹Ð»"
-  label_download_plural: "%{count} Ð¢Ð°Ñ‚Ð°Ð¶ Ð°Ð²ÑÐ°Ð½ Ð·Ò¯Ð¹Ð»Ñ"
-  label_no_data: Ò®Ð·Ò¯Ò¯Ð»ÑÑ… Ó©Ð³Ó©Ð³Ð´Ó©Ð» Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°
-  label_change_status: Ð¢Ó©Ð»Ð²Ð¸Ð¹Ð³ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…
-  label_history: Ð¢Ò¯Ò¯Ñ…
-  label_attachment: Ð¤Ð°Ð¹Ð»
-  label_attachment_new: Ð¨Ð¸Ð½Ñ Ñ„Ð°Ð¹Ð»
-  label_attachment_delete: Ð¤Ð°Ð¹Ð» ÑƒÑÑ‚Ð³Ð°Ñ…
-  label_attachment_plural: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´
-  label_file_added: Ð¤Ð°Ð¹Ð» Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
-  label_report: Ð¢Ð°Ð¹Ð»Ð°Ð½
-  label_report_plural: Ð¢Ð°Ð¹Ð»Ð°Ð½Ð³ÑƒÑƒÐ´ 
-  label_news: ÐœÑÐ´ÑÑ
-  label_news_new: Ð¨Ð¸Ð½Ñ Ð¼ÑÐ´ÑÑ
-  label_news_plural: ÐœÑÐ´ÑÑ
-  label_news_latest: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ò¯ÐµÐ¸Ð¹Ð½ Ð¼ÑÐ´ÑÑÐ½Ò¯Ò¯Ð´
-  label_news_view_all: Ð‘Ò¯Ñ… Ð¼ÑÐ´ÑÑÐ³ Ñ…Ð°Ñ€Ð°Ñ…
-  label_news_added: ÐœÑÐ´ÑÑ Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
-  label_change_log: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ð¸Ð¹Ð½ Ð»Ð¾Ð³
-  label_settings: Ð¢Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾
-  label_overview: Ð­Ñ…Ð»ÑÐ»
-  label_version: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
-  label_version_new: Ð¨Ð¸Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
-  label_version_plural: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
-  label_close_versions: Ð“Ò¯Ð¹Ñ†ÑÑ‚ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ð°Ð»Ð°Ð°
-  label_confirmation: Ð‘Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑƒÑƒÐ»Ð°Ñ…
-  label_export_to: 'Ó¨Ó©Ñ€ Ð°Ð²Ñ‡ Ð±Ð¾Ð»Ð¾Ñ… Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚:'
-  label_read: Ð£Ð½ÑˆÐ¸Ñ…...
-  label_public_projects: ÐžÐ»Ð¾Ð½ Ð½Ð¸Ð¹Ñ‚Ð¸Ð¹Ð½ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´
-  label_open_issues: Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
-  label_open_issues_plural: Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
-  label_closed_issues: Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
-  label_closed_issues_plural: Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
-  label_x_open_issues_abbr_on_total:
-    zero:  0 Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹ / %{total}
-    one:   1 Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹ / %{total}
-    other: "%{count} Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹ / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
-    one:   1 Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
-    other: "%{count} Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹"
-  label_x_closed_issues_abbr:
-    zero:  0 Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
-    one:   1 Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
-    other: "%{count} Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹"
-  label_total: ÐÐ¸Ð¹Ñ‚
-  label_permissions: Ð—Ó©Ð²ÑˆÓ©Ó©Ñ€Ð»Ò¯Ò¯Ð´
-  label_current_status: ÐžÐ´Ð¾Ð¾Ð³Ð¸Ð¹Ð½ Ñ‚Ó©Ð»Ó©Ð²
-  label_new_statuses_allowed: Ð¨Ð¸Ð½ÑÑÑ€ Ð¾Ð»Ð³Ð¾Ð¶ Ð±Ð¾Ð»Ð¾Ñ… Ñ‚Ó©Ð»Ð²Ò¯Ò¯Ð´
-  label_all: Ð±Ò¯Ð³Ð´
-  label_none: Ñ…Ð¾Ð¾ÑÐ¾Ð½
-  label_nobody: Ñ…ÑÐ½ Ñ‡ Ð±Ð¸Ñˆ
-  label_next: Ð”Ð°Ñ€Ð°Ð°Ð³Ð¸Ð¹Ð½
-  label_previous: Ó¨Ð¼Ð½Ó©Ñ…
-  label_used_by: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ð´Ð´ÑÐ³
-  label_details: Ð”ÑÐ»Ð³ÑÑ€ÑÐ½Ð³Ò¯Ð¹
-  label_add_note: Ð¢ÑÐ¼Ð´ÑÐ³Ð»ÑÐ» Ð½ÑÐ¼ÑÑ…
-  label_per_page: ÐÑÐ³ Ñ…ÑƒÑƒÐ´ÑÐ°Ð½Ð´
-  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€ÑŒ
-  label_months_from: Ð¡Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ð°Ð½Ð°Ð°Ñ
-  label_gantt: Ð“Ð°Ð½Ñ‚ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼
-  label_internal: Ð”Ð¾Ñ‚Ð¾Ð¾Ð´
-  label_last_changes: "ÑÒ¯Ò¯Ð»Ð¸Ð¹Ð½ %{count} Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´"
-  label_change_view_all: Ð‘Ò¯Ñ… Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  label_personalize_page: Ð­Ð½Ñ Ñ…ÑƒÑƒÐ´ÑÑ‹Ð³ Ó©Ó©Ñ€Ñ‚ Ð·Ð¾Ñ€Ð¸ÑƒÐ»Ð°Ð½ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…
-  label_comment: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€
-  label_comment_plural: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
-  label_x_comments:
-    zero: ÑÑÑ‚Ð³ÑÐ³Ð´ÑÐ» Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹
-    one: 1 ÑÑÑ‚Ð³ÑÐ³Ð´ÑÐ»Ñ‚ÑÐ¹
-    other: "%{count} ÑÑÑ‚Ð³ÑÐ³Ð´ÑÐ»Ñ‚ÑÐ¹"
-  label_comment_add: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ Ð½ÑÐ¼ÑÑ…
-  label_comment_added: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
-  label_comment_delete: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´ ÑƒÑÑ‚Ð³Ð°Ñ…
-  label_query: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ»Ñ‚
-  label_query_plural: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ»Ñ‚ÑƒÑƒÐ´
-  label_query_new: Ð¨Ð¸Ð½ÑÑÑ€ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ»Ñ‚ Ò¯Ò¯ÑÐ³ÑÑ…
-  label_filter_add: Ð¨Ò¯Ò¯Ð»Ñ‚Ò¯Ò¯Ñ€ Ð½ÑÐ¼ÑÑ…
-  label_filter_plural: Ð¨Ò¯Ò¯Ð»Ñ‚Ò¯Ò¯Ñ€Ò¯Ò¯Ð´
-  label_equals: Ð±Ð¾Ð»
-  label_not_equals: Ð±Ð¸Ñˆ
-  label_in_less_than: Ð°Ð°Ñ Ð±Ð°Ð³Ð°
-  label_in_more_than: Ð°Ð°Ñ Ð¸Ñ…
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: Ð´Ð¾Ñ‚Ð¾Ñ€
-  label_today: Ó©Ð½Ó©Ó©Ð´Ó©Ñ€
-  label_all_time: Ð±Ò¯Ñ… Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°
-  label_yesterday: Ó©Ñ‡Ð¸Ð³Ð´Ó©Ñ€
-  label_this_week: ÑÐ½Ñ Ð´Ð¾Ð»Ð¾Ð¾ Ñ…Ð¾Ð½Ð¾Ð³
-  label_last_week: Ó©Ð½Ð³Ó©Ñ€ÑÓ©Ð½ Ð´Ð¾Ð»Ð¾Ð¾ Ñ…Ð¾Ð½Ð¾Ð³
-  label_last_n_days: "ÑÒ¯Ò¯Ð»Ð¸Ð¹Ð½ %{count} Ó©Ð´Ñ€Ò¯Ò¯Ð´"
-  label_this_month: ÑÐ½Ñ ÑÐ°Ñ€
-  label_last_month: ÑÒ¯Ò¯Ð»Ð¸Ð¹Ð½ ÑÐ°Ñ€
-  label_this_year: ÑÐ½Ñ Ð¶Ð¸Ð»
-  label_date_range: Ð¥ÑÐ·Ð³Ð°Ð°Ñ€ Ð¾Ð³Ð½Ð¾Ð¾
-  label_less_than_ago: Ð±Ð°Ð³Ð° Ó©Ð´Ñ€Ð¸Ð¹Ð½ Ð´Ð¾Ñ‚Ð¾Ñ€
-  label_more_than_ago: Ð¸Ñ… Ó©Ð´Ñ€Ð¸Ð¹Ð½ Ð´Ð¾Ñ‚Ð¾Ñ€
-  label_ago: Ó©Ð´Ñ€Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó©
-  label_contains: Ð°Ð³ÑƒÑƒÐ»Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð°
-  label_not_contains: Ð°Ð³ÑƒÑƒÐ»Ð°Ð°Ð³Ò¯Ð¹
-  label_day_plural: Ó©Ð´Ñ€Ò¯Ò¯Ð´
-  label_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸
-  label_repository_plural: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€ÑƒÑƒÐ´
-  label_browse: Ò®Ð·ÑÑ…
-  label_modification: "%{count} Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚"
-  label_modification_plural: "%{count} Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´"
-  label_branch: Ð¡Ð°Ð»Ð±Ð°Ñ€
-  label_tag: Ð¨Ð¾ÑˆÐ³Ð¾ 
-  label_revision: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
-  label_revision_plural: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
-  label_revision_id: "%{value} Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€"
-  label_associated_revisions: Ð¥Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
-  label_added: Ð½ÑÐ¼ÑÐ³Ð´ÑÑÐ½
-  label_modified: Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð³Ð´ÑÓ©Ð½
-  label_copied: Ñ…ÑƒÑƒÐ»ÑÐ°Ð½
-  label_renamed: Ð½ÑÑ€Ð¸Ð¹Ð³ Ð½ÑŒ Ó©Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½
-  label_deleted: ÑƒÑÑ‚Ð³Ð°ÑÐ°Ð½
-  label_latest_revision: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ò¯ÐµÐ¸Ð¹Ð½ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
-  label_latest_revision_plural: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ò¯ÐµÐ¸Ð¹Ð½ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
-  label_view_revisions: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  label_view_all_revisions: Ð‘Ò¯Ñ… Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  label_max_size: Maximum size
-  label_sort_highest: Ð¥Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð´ÑÑÑ€
-  label_sort_higher: Ð”ÑÑÑˆ Ð½ÑŒ
-  label_sort_lower: Ð”Ð¾Ð¾Ñˆ Ð½ÑŒ
-  label_sort_lowest: Ð¥Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð´Ð¾Ð¾Ñ€
-  label_roadmap: Ð¥Ó©Ñ‚Ó©Ñ‡
-  label_roadmap_due_in: "%{value} Ð´Ð¾Ñ‚Ð¾Ñ€ Ð´ÑƒÑƒÑÐ³Ð°Ñ…"
-  label_roadmap_overdue: "%{value} Ð¾Ñ€Ð¾Ð¹Ñ‚ÑÐ¾Ð½"
-  label_roadmap_no_issues: Ð­Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ñ‚ Ð°ÑÑƒÑƒÐ´Ð°Ð» Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°
-  label_search: Ð¥Ð°Ð¹Ñ…
-  label_result_plural: Ò®Ñ€ Ð´Ò¯Ð½
-  label_all_words: Ð‘Ò¯Ñ… Ò¯Ð³Ñ
-  label_wiki: Ð’Ð¸ÐºÐ¸
-  label_wiki_edit: Ð’Ð¸ÐºÐ¸ Ð·Ð°ÑÐ²Ð°Ñ€
-  label_wiki_edit_plural: Ð’Ð¸ÐºÐ¸ Ð·Ð°ÑÐ²Ð°Ñ€ÑƒÑƒÐ´
-  label_wiki_page: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´Ð°Ñ
-  label_wiki_page_plural: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´Ð°Ñ
-  label_index_by_title: Ð“Ð°Ñ€Ñ‡Ð³Ð°Ð°Ñ€ ÑÑ€ÑÐ¼Ð±ÑÐ»ÑÑ…
-  label_index_by_date: ÐžÐ³Ð½Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ ÑÑ€ÑÐ¼Ð±ÑÐ»ÑÑ…
-  label_current_version: ÐžÐ´Ð¾Ð¾Ð³Ð¸Ð¹Ð½ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
-  label_preview: Ð¯Ð¼Ð°Ñ€ Ñ…Ð°Ñ€Ð°Ð³Ð´Ð°Ñ…Ñ‹Ð³ ÑˆÐ°Ð»Ð³Ð°Ñ…
-  label_feed_plural: Feeds
-  label_changes_details: Ð‘Ò¯Ñ… Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ð´ÑÐ»Ð³ÑÑ€ÑÐ½Ð³Ò¯Ð¹
-  label_issue_tracking: ÐÑÑƒÑƒÐ´Ð°Ð» Ñ…ÑÐ½Ð°Ñ…
-  label_spent_time: Ð—Ð°Ñ€Ñ†ÑƒÑƒÐ»ÑÐ°Ð½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°
-  label_f_hour: "%{value} Ñ†Ð°Ð³"
-  label_f_hour_plural: "%{value} Ñ†Ð°Ð³"
-  label_time_tracking: Ð¥ÑƒÐ³Ð°Ñ†Ð°Ð°Ð³ Ñ…ÑÐ½Ð°Ñ…
-  label_change_plural: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´
-  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸Ðº
-  label_commits_per_month: Ð¡Ð°Ñ€Ð´ Ñ…Ð¸Ð¹ÑÑÐ½ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ñ‹Ð½ Ñ‚Ð¾Ð¾
-  label_commits_per_author: Ð—Ð¾Ñ…Ð¸Ð¾Ð³Ñ‡ Ð±Ò¯Ñ€Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ñ‹Ð½ Ñ‚Ð¾Ð¾
-  label_view_diff: Ð¯Ð»Ð³Ð°Ð°Ð½ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
-  label_diff_inline: Ð´Ð¾Ñ‚Ð¾Ñ€ Ð½ÑŒ
-  label_diff_side_by_side: Ð·ÑÑ€ÑÐ³Ñ†Ò¯Ò¯Ð»Ð¶
-  label_options: Ð¢Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾
-  label_copy_workflow_from: ÐÐ¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ñ‹Ð³ Ñ…ÑƒÑƒÐ»Ð°Ñ…
-  label_permissions_report: Ð—Ó©Ð²ÑˆÓ©Ó©Ñ€Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ‚Ð°Ð±Ð»Ð¸Ñ†
-  label_watched_issues: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ð´Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
-  label_related_issues: Ð¥Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
-  label_applied_status: ÐžÐ»Ð³Ð¾ÑÐ¾Ð½ Ñ‚Ó©Ð»Ó©Ð²
-  label_loading: ÐÑ‡Ð°Ð°Ð»Ð¶ Ð±Ð°Ð¹Ð½Ð°...
-  label_relation_new: Ð¨Ð¸Ð½Ñ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»
-  label_relation_delete: Ð¥Ð°Ð¼Ð°Ð°Ñ€Ð»Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
-  label_relates_to: ÑÐ½Ð³Ð¸Ð¹Ð½ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
-  label_duplicates: Ñ…Ð¾Ñ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
-  label_duplicated_by: Ð´Ð°Ð²Ñ…Ð°Ñ€Ð´ÑƒÑƒÐ»ÑÐ°Ð½ ÑÐ·ÑÐ½
-  label_blocks: ÑˆÐ°Ð°Ñ€Ð´Ð°Ñ… Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
-  label_blocked_by: Ð±Ð»Ð¾ÐºÐ¾Ð»ÑÐ¾Ð½ ÑÐ·ÑÐ½
-  label_precedes: ÑƒÑ€ÑŒÐ´Ñ‡Ð¸Ð»Ð°Ñ… Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
-  label_follows: Ð´Ð°Ð³Ð°Ð¶
-  label_end_to_start: Ñ…Ð¾Ð¹Ð½Ð¾Ð¾Ñ Ð½ÑŒ ÑƒÑ€Ð°Ð³ÑˆÐ°Ð°
-  label_end_to_end: Ñ…Ð¾Ð¹Ð½Ð¾Ð¾Ñ Ð½ÑŒ Ñ…Ð¾Ð¹ÑˆÐ¾Ð¾
-  label_start_to_start: ÑƒÑ€Ð´Ð°Ð°Ñ Ð½ÑŒ ÑƒÑ€Ð°Ð³Ð°Ð°
-  label_start_to_end: ÑƒÑ€Ð´Ð°Ð°Ñ Ð½ÑŒ Ñ…Ð¾Ð¹ÑˆÐ¾Ð¾
-  label_stay_logged_in: Ð­Ð½Ñ ÐºÐ¾Ð¼ÑŒÑŽÑ‚ÐµÑ€ Ð´ÑÑÑ€ ÑÐ°Ð½Ð°Ñ…
-  label_disabled: Ð¸Ð´ÑÐ²Ñ…Ð³Ò¯Ð¹ Ð±Ð¾Ð»ÑÐ¾Ð½
-  label_show_completed_versions: Ð“Ò¯Ð¹Ñ†ÑÐ´ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ…
-  label_me: Ð±Ð¸
-  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
-  label_board_new: Ð¨Ð¸Ð½Ñ Ñ„Ð¾Ñ€ÑƒÐ¼
-  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼ÑƒÑƒÐ´
-  label_board_locked: Ð¢Ò¯Ð³Ð¶ÑÑÑ‚ÑÐ¹
-  label_board_sticky: Sticky
-  label_topic_plural: Ð¡ÑÐ´Ð²Ò¯Ò¯Ð´
-  label_message_plural: Ð—ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´
-  label_message_last: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ð·ÑƒÑ€Ð²Ð°Ñ
-  label_message_new: Ð¨Ð¸Ð½Ñ Ð·ÑƒÑ€Ð²Ð°Ñ
-  label_message_posted: Ð—ÑƒÑ€Ð²Ð°Ñ Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
-  label_reply_plural: Ð¥Ð°Ñ€Ð¸ÑƒÐ»Ñ‚ÑƒÑƒÐ´
-  label_send_information: Ð”Ð°Ð½ÑÐ½Ñ‹ Ð¼ÑÐ´ÑÑÐ»Ð»Ð¸Ð¹Ð³ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð´ Ð¸Ð»Ð³ÑÑÑ…
-  label_year: Ð–Ð¸Ð»
-  label_month: Ð¡Ð°Ñ€
-  label_week: Ð”Ð¾Ð»Ð¾Ð¾ Ñ…Ð¾Ð½Ð¾Ð³
-  label_date_from: Ð¥ÑÐ·ÑÑÐ½ÑÑÑ
-  label_date_to: Ð¥ÑÐ´Ð¸Ð¹ Ñ…Ò¯Ñ€Ñ‚ÑÐ»
-  label_language_based: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ…ÑÐ»Ð½Ð°Ñ ÑˆÐ°Ð»Ñ‚Ð³Ð°Ð°Ð»Ð°Ð½
-  label_sort_by: "%{value} Ñ‚Ð°Ð»Ð±Ð°Ñ€Ð°Ð°Ñ€ Ð½ÑŒ ÑÑ€ÑÐ¼Ð±ÑÐ»ÑÑ…"
-  label_send_test_email: Ð¢ÑƒÑ€ÑˆÐ¸Ñ… Ð¼ÑÐ¹Ð» Ð¸Ð»Ð³ÑÑÑ…
-  label_feeds_access_key: RSS Ñ…Ð°Ð½Ð´Ð°Ñ… Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€
-  label_missing_feeds_access_key: RSS Ñ…Ð°Ð½Ð´Ð°Ñ… Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ Ð°Ð»Ð³Ð°
-  label_feeds_access_key_created_on: "RSS Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ %{value}-Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó© Ò¯Ò¯ÑÑÑÐ½"
-  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»ÑƒÑƒÐ´
-  label_added_time_by: "%{author} %{age}-Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó© Ð½ÑÐ¼ÑÑÐ½"
-  label_updated_time_by: "%{author} %{age}-Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó© Ó©Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½"
-  label_updated_time: "%{value} -Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó© Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð³Ð´ÑÓ©Ð½"
-  label_jump_to_a_project: Ð¢Ó©ÑÓ©Ð» Ñ€Ò¯Ò¯ Ð¾Ñ‡Ð¸Ñ…...
-  label_file_plural: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´
-  label_changeset_plural: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´
-  label_default_columns: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ð±Ð°Ð³Ð°Ð½ÑƒÑƒÐ´
-  label_no_change_option: (Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚ Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹)
-  label_bulk_edit_selected_issues: Ð¡Ð¾Ð½Ð³Ð¾Ð³Ð´ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð±Ó©Ó©Ð½Ó©Ó©Ñ€ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  label_theme: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð¸Ð¹Ð½ Ð”Ð¸Ð·Ð°Ð¹Ð½
-  label_default: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚
-  label_search_titles_only: Ð—Ó©Ð²Ñ…Ó©Ð½ Ð³Ð°Ñ€Ñ‡Ð¸Ð³ Ñ…Ð°Ð¹Ñ…
-  label_user_mail_option_all: "ÐœÐ¸Ð½Ð¸Ð¹ Ð±Ò¯Ñ… Ñ‚Ó©ÑÓ©Ð» Ð´ÑÑÑ€Ñ… Ð±Ò¯Ñ… Ò¯Ð·ÑÐ³Ð´Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´"
-  label_user_mail_option_selected: "Ð¡Ð¾Ð½Ð³Ð¾Ð³Ð´ÑÐ¾Ð½ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´ Ð±Ò¯Ñ… Ò¯Ð·ÑÐ³Ð´ÑÐ» Ð´ÑÑÑ€..."
-  label_user_mail_no_self_notified: "ÐœÐ¸Ð½Ð¸Ð¹ Ó©Ó©Ñ€Ð¸Ð¹Ð½ Ñ…Ð¸Ð¹ÑÑÐ½ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ‚ÑƒÑ…Ð°Ð¹ Ð½Ð°Ð´Ð°Ð´ Ð¼ÑÐ´ÑÐ³Ð´ÑÑ… Ñ…ÑÑ€ÑÐ³Ð³Ò¯Ð¹"
-  label_registration_activation_by_email: Ð´Ð°Ð½ÑÑ‹Ð³ Ð¸Ð¼ÑÐ¹Ð»ÑÑÑ€ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
-  label_registration_manual_activation: Ð´Ð°Ð½ÑÑ‹Ð³ Ð³Ð°Ñ€Ð°Ð°Ñ€ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
-  label_registration_automatic_activation: Ð´Ð°Ð½ÑÑ‹Ð³ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð°Ð°Ñ€ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
-  label_display_per_page: 'ÐÑÐ³ Ñ…ÑƒÑƒÐ´ÑÐ°Ð½Ð´: %{value}'
-  label_age: ÐÐ°Ñ
-  label_change_properties: Ð¢Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾Ð³ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…
-  label_general: Ð•Ñ€Ó©Ð½Ñ…Ð¸Ð¹
-  label_more: Ð¦Ð°Ð°Ñˆ Ð½ÑŒ
-  label_scm: SCM
-  label_plugins: ÐœÐ¾Ð´ÑƒÐ»ÑƒÑƒÐ´
-  label_ldap_authentication: LDAP Ð½ÑÐ²Ñ‚Ñ€ÑÑ… Ð³Ð¾Ñ€Ð¸Ð¼
-  label_downloads_abbr: D/L
-  label_optional_description: Ð”ÑƒÑ€Ñ‹Ð½ Ñ‚Ð°Ð¹Ð»Ð±Ð°Ñ€
-  label_add_another_file: Ð”Ð°Ñ…Ð¸Ð½ Ñ„Ð°Ð¹Ð» Ð½ÑÐ¼ÑÑ…
-  label_preferences: Ð¢Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾
-  label_chronological_order: Ð¦Ð°Ð³Ð°Ð°Ð½ Ñ‚Ð¾Ð»Ð³Ð¾Ð¹Ð½ Ò¯ÑÐ³Ð¸Ð¹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ð°Ð°Ñ€
-  label_reverse_chronological_order: Ð£Ñ€Ð²ÑƒÑƒ Ñ†Ð°Ð³Ð°Ð°Ð½ Ñ‚Ð¾Ð»Ð³Ð¾Ð¹Ð½ Ò¯ÑÐ³Ð¸Ð¹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ð°Ð°Ñ€
-  label_planning: Ð¢Ó©Ð»Ó©Ð²Ð»Ó©Ð»Ñ‚
-  label_incoming_emails: Ð˜Ñ€ÑÑÐ½ Ð¼ÑÐ¹Ð»Ò¯Ò¯Ð´
-  label_generate_key: Ð¢Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ Ò¯Ò¯ÑÐ³ÑÑ…
-  label_issue_watchers: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ñ‡Ð¸Ð´
-  label_example: Ð–Ð¸ÑˆÑÑ
-  label_display: Display
-  label_sort: Sort
-  label_ascending: Ascending
-  label_descending: Descending
-  label_date_from_to: From %{start} to %{end}
-  label_wiki_content_added: Wiki page added
-  label_wiki_content_updated: Wiki page updated
-  label_group: Group
-  label_group_plural: Groups
-  label_group_new: New group
-  label_time_entry_plural: Spent time
-  label_version_sharing_none: Not shared
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_tree: With project tree
-  label_version_sharing_system: With all projects
-  label_update_issue_done_ratios: Update issue done ratios
-  label_copy_source: Source
-  label_copy_target: Target
-  label_copy_same_as_target: Same as target
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_api_access_key: API access key
-  label_missing_api_access_key: Missing an API access key
-  label_api_access_key_created_on: "API access key created %{value} ago"
-  
-  button_login: ÐÑÐ²Ñ‚Ñ€ÑÑ…
-  button_submit: Ð˜Ð»Ð³ÑÑÑ…
-  button_save: Ð¥Ð°Ð´Ð³Ð°Ð»Ð°Ñ…
-  button_check_all: Ð‘Ò¯Ð³Ð´Ð¸Ð¹Ð³ ÑÐ¾Ð½Ð³Ð¾
-  button_uncheck_all: Ð‘Ò¯Ð³Ð´Ð¸Ð¹Ð³ Ò¯Ð» ÑÐ¾Ð½Ð³Ð¾
-  button_delete: Ð£ÑÑ‚Ð³Ð°Ñ…
-  button_create: Ò®Ò¯ÑÐ³ÑÑ…
-  button_create_and_continue: Ò®Ò¯ÑÐ³ÑÑÐ´ Ñ†Ð°Ð°Ñˆ Ò¯Ñ€Ð³ÑÐ»Ð¶Ð»Ò¯Ò¯Ð»ÑÑ…
-  button_test: Ð¢ÑƒÑ€ÑˆÐ¸Ñ…
-  button_edit: Ð—Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
-  button_add: ÐÑÐ¼ÑÑ…
-  button_change: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ñ…
-  button_apply: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ð¸Ð¹Ð³ Ñ…Ð°Ð´Ð³Ð°Ð»Ð°Ñ…
-  button_clear: Ð¦ÑÐ²ÑÑ€Ð»ÑÑ…
-  button_lock: Ð¢Ò¯Ð³Ð¶Ð¸Ñ…
-  button_unlock: Ð¢Ò¯Ð³Ð¶ÑÑÐ³ Ñ‚Ð°Ð¹Ð»Ð°Ñ…
-  button_download: Ð¢Ð°Ñ‚Ð°Ñ…
-  button_list: Ð–Ð°Ð³ÑÐ°Ð°Ð»Ñ‚
-  button_view: Ð¥Ð°Ñ€Ð°Ñ…
-  button_move: Ð—Ó©Ó©Ñ…
-  button_move_and_follow: Ð—Ó©Ó© Ð±Ð°Ñ Ð´Ð°Ð³Ð°
-  button_back: Ð‘ÑƒÑ†Ð°Ñ…
-  button_cancel: Ð‘Ð¾Ð»Ð¸Ñ…
-  button_activate: Ð˜Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
-  button_sort: Ð­Ñ€ÑÐ¼Ð±ÑÐ»ÑÑ…
-  button_log_time: Ð›Ð¾Ð³ Ñ…Ð¸Ð¹ÑÑÐ½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°
-  button_rollback: Ð­Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ Ñ€ÑƒÑƒ Ð±ÑƒÑ†Ð°Ñ…
-  button_watch: ÐÐ¶Ð¸Ð³Ð»Ð°Ñ…
-  button_unwatch: ÐÐ¶Ð¸Ð³Ð»Ð°Ñ…Ð°Ð° Ð±Ð¾Ð»Ð¸Ñ…
-  button_reply: Ð¥Ð°Ñ€Ð¸ÑƒÐ»Ð°Ñ…
-  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð»Ð°Ñ…
-  button_unarchive: ÐÑ€Ñ…Ð¸Ð²Ñ‹Ð³ Ð·Ð°Ð´Ð»Ð°Ñ…
-  button_reset: ÐÐ½Ñ…Ð½Ñ‹ ÑƒÑ‚Ð³ÑƒÑƒÐ´
-  button_rename: ÐÑÑ€Ð¸Ð¹Ð³ Ð½ÑŒ ÑÐ¾Ð»Ð¸Ñ…
-  button_change_password: ÐÑƒÑƒÑ† Ò¯Ð³ÑÑ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…
-  button_copy: Ð¥ÑƒÑƒÐ»Ð°Ñ…
-  button_copy_and_follow: Ð—Ó©Ó© Ð±Ð°Ñ Ð´Ð°Ð³Ð°
-  button_annotate: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ Ñ…Ð°Ð²ÑÐ°Ñ€Ð³Ð°Ñ…
-  button_update: Ð¨Ð¸Ð½ÑÑ‡Ð»ÑÑ…
-  button_configure: Ð¢Ð¾Ñ…Ð¸Ñ€ÑƒÑƒÐ»Ð°Ñ…
-  button_quote: Ð˜ÑˆÐ»ÑÐ»
-  button_duplicate: Ð¥ÑƒÑƒÐ»Ð±Ð°Ñ€
-  button_show: Ò®Ð·ÑÑ…
-  
-  status_active: Ð¸Ð´ÑÐ²Ñ…Ñ‚ÑÐ¹
-  status_registered: Ð±Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑÐ½
-  status_locked: Ñ‚Ò¯Ð³Ð¶ÑÑÑ‚ÑÐ¹
-  
-  version_status_open: Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
-  version_status_locked: Ñ‚Ò¯Ð³Ð¶ÑÑÑ‚ÑÐ¹
-  version_status_closed: Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
-
-  field_active: Ð¸Ð´ÑÐ²Ñ…Ñ‚ÑÐ¹
-  
-  text_select_mail_notifications: Ð¯Ð¼Ð°Ñ€ Ò¯ÐµÐ´ Ð¸Ð¼ÑÐ¹Ð»ÑÑÑ€ Ð¼ÑÐ´ÑÐ³Ð´ÑÐ» Ð¸Ð»Ð³ÑÑÑ…Ð¸Ð¹Ð³ ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ.
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 Ð³ÑÐ²ÑÐ» ÑÐ¼Ð°Ñ€ Ñ‡ Ñ…ÑÐ·Ð³Ð°Ð°Ñ€Ð³Ò¯Ð¹ Ð³ÑÑÑÐ½ Ò¯Ð³
-  text_project_destroy_confirmation: Ð¢Ð° ÑÐ½Ñ Ñ‚Ó©ÑÓ©Ð» Ð±Ð¾Ð»Ð¾Ð¾Ð´ Ð±ÑƒÑÐ°Ð´ Ð¼ÑÐ´ÑÑÐ»Ð»Ð¸Ð¹Ð³ Ð½ÑŒ Ò¯Ð½ÑÑ…ÑÑÑ€ ÑƒÑÑ‚Ð³Ð°Ð¼Ð°Ð°Ñ€ Ð±Ð°Ð¹Ð½Ð° ÑƒÑƒ ?
-  text_subprojects_destroy_warning: "Ð£Ð³ Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ð´ÑÐ´ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´ : %{value} Ð½ÑŒ Ð±Ð°Ñ ÑƒÑÑ‚Ð³Ð°Ð³Ð´Ð°Ñ… Ð±Ð¾Ð»Ð½Ð¾."
-  text_workflow_edit: ÐÐ¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ñ‹Ð³ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…Ð¸Ð¹Ð½ Ñ‚ÑƒÐ»Ð´ Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ… Ð±Ð¾Ð»Ð¾Ð½ Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‡Ð¸Ð³Ð»ÑÐ»Ð¸Ð¹Ð³ ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ
-  text_are_you_sure: Ð¢Ð° Ð¸Ñ‚Ð³ÑÐ»Ñ‚ÑÐ¹ Ð±Ð°Ð¹Ð½Ð° ÑƒÑƒ ?
-  text_journal_changed: "%{label} %{old} Ð±Ð°Ð¹ÑÐ°Ð½ Ð½ÑŒ %{new} Ð±Ð¾Ð»Ð¾Ð²"
-  text_journal_set_to: "%{label} %{value} Ð±Ð¾Ð»Ð³Ð¾Ð¶ Ó©Ó©Ñ€Ñ‡Ð¸Ð»Ð»Ó©Ó©"
-  text_journal_deleted: "%{label} ÑƒÑÑ‚ÑÐ°Ð½ (%{old})"
-  text_journal_added: "%{label} %{value} Ð½ÑÐ¼ÑÐ³Ð´ÑÑÐ½"
-  text_tip_issue_begin_day: ÑÐ½Ñ Ó©Ð´Ó©Ñ€ ÑÑ…Ð»ÑÑ… Ð°Ð¶Ð¸Ð»
-  text_tip_issue_end_day: ÑÐ½Ñ Ó©Ð´Ó©Ñ€ Ð´ÑƒÑƒÑÐ°Ñ… Ð°Ð¶Ð¸Ð»
-  text_tip_issue_begin_end_day: ÑÐ½Ñ Ó©Ð´Ó©Ñ€ ÑÑ…Ð»ÑÑÐ´ Ð¼Ó©Ð½ Ð´ÑƒÑƒÑÑ‡ Ð±Ð°Ð¹Ð³Ð°Ð° Ð°Ð¶Ð¸Ð»
-  text_project_identifier_info: 'Ð—Ó©Ð²Ñ…Ó©Ð½ Ð¶Ð¸Ð¶Ð¸Ð³ Ò¯ÑÐ³Ò¯Ò¯Ð´ Ð±Ð¾Ð»Ð¾Ð½ (a-z), Ñ‚Ð¾Ð¾ and Ð´ÑƒÐ½Ð´ÑƒÑƒÑ€ Ð·ÑƒÑ€Ð°Ð°Ñ Ð°ÑˆÐ¸Ð³Ð»Ð°Ð¶ Ð±Ð¾Ð»Ð½Ð¾.<br />ÐÑÐ³ÑÐ½Ñ‚ Ñ…Ð°Ð´Ð³Ð°Ð»ÑÐ°Ð½ Ñ…Ð¾Ð¹Ð½Ð¾, Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ð³Ð»Ð¾Ð±Ð°Ð» Ð½ÑÑ€Ð¸Ð¹Ð³ Ó©Ó©Ñ€Ð»Ñ‡Ó©Ñ… Ð±Ð¾Ð»Ð¾Ð¼Ð¶Ð³Ò¯Ð¹.'
-  text_caracters_maximum: "Ð´ÑÑÐ´ Ñ‚Ð°Ð» Ð½ÑŒ %{count} Ò¯ÑÑÐ³."
-  text_caracters_minimum: "Ð¥Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð±Ð°Ð³Ð°Ð´Ð°Ð° ÑÐ´Ð°Ð¶ %{count} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚ Ð±Ð°Ð¹Ñ…."
-  text_length_between: "Ð£Ñ€Ñ‚ Ð½ÑŒ Ð±Ð°Ð³Ð°Ð´Ð°Ð° %{min}, Ð¸Ñ…Ð´ÑÑ %{max} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚."
-  text_tracker_no_workflow: Ð­Ð½ÑÑ…Ò¯Ò¯ Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‡Ð¸Ð³Ð»ÑÐ»Ð´ ÑÐ¼Ð°Ñ€ Ñ‡ Ð°Ð¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð°Ð» Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»Ð¾Ð³Ð´Ð¾Ð¾Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°
-  text_unallowed_characters: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ¶ Ð±Ð¾Ð»Ð¾Ñ…Ð³Ò¯Ð¹ Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚Ò¯Ò¯Ð´
-  text_comma_separated: Ð¢Ð°ÑÐ»Ð°Ð»Ð°Ð°Ñ€ Ð·Ð°Ð°Ð³Ð»Ð°Ð½ Ð¾Ð»Ð¾Ð½ ÑƒÑ‚Ð³Ð° Ð¾Ñ€ÑƒÑƒÐ»Ð¶ Ð±Ð¾Ð»Ð½Ð¾.
-  text_line_separated: Multiple values allowed (one line for each value).
-  text_issues_ref_in_commit_messages: ÐšÐ¾Ð¼Ð¼Ð¸Ñ‚Ð¸Ð¹Ð½ Ð·ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ð°Ð´ Ñ…Ð°Ð¼Ð°Ð°Ñ€ÑƒÑƒÐ»ÑÐ°Ð½ Ð±Ð¾Ð»Ð¾Ð½ Ð±Ð°Ð¹Ð½Ð³Ñ‹Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
-  text_issue_added: "ÐÑÑƒÑƒÐ´Ð°Ð» %{id} - Ð¸Ð¹Ð³ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ %{author} Ð¼ÑÐ´ÑÐ³Ð´ÑÑÐ½ Ð±Ð°Ð¹Ð½Ð°."
-  text_issue_updated: "ÐÑÑƒÑƒÐ´Ð°Ð» %{id} - Ð¸Ð¹Ð³ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ %{author} Ó©Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½ Ð±Ð°Ð¹Ð½Ð°."
-  text_wiki_destroy_confirmation: Ð¢Ð° ÑÐ½Ñ Ð²Ð¸ÐºÐ¸ Ð±Ð¾Ð»Ð¾Ð½ Ñ…Ð¾Ð»Ð±Ð¾Ð³Ð´Ð¾Ñ… Ð±Ò¯Ñ… Ð¼ÑÐ´ÑÑÐ»Ð»Ð¸Ð¹Ð³ Ò¯Ð½ÑÑ…ÑÑÑ€ ÑƒÑÑ‚Ð³Ð°Ð¼Ð°Ð°Ñ€ Ð±Ð°Ð¹Ð½Ð° ÑƒÑƒ ?
-  text_issue_category_destroy_question: "Ð­Ð½Ñ Ð°Ð½Ð³Ð¸Ð»Ð°Ð»Ð´ Ð·Ð°Ñ€Ð¸Ð¼ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´ (%{count})  Ð¾Ñ€ÑÐ¾Ð½ Ð±Ð°Ð¹Ð½Ð°. Ð¢Ð° ÑÐ°Ñ… Ð²Ñ ?"
-  text_issue_category_destroy_assignments: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑÐ½Ñ Ð°Ð½Ð³Ð¸Ð»Ð»Ð°Ð°Ñ Ð°Ð²Ð°Ñ…
-  text_issue_category_reassign_to: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑÐ½Ñ Ð°Ð½Ð³Ð¸Ð»Ð°Ð»Ð´ Ð´Ð°Ñ…Ð¸Ð½ Ð¾Ð½Ð¾Ð¾Ñ…
-  text_user_mail_option: "Ð¡Ð¾Ð½Ð³Ð¾Ð³Ð´Ð¾Ð¾Ð³Ò¯Ð¹ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´, Ñ‚Ð° Ð·Ó©Ð²Ñ…Ó©Ð½ Ó©Ó©Ñ€Ð¸Ð¹Ð½Ñ…Ó©Ó© Ð°Ð¶Ð¸Ð³Ð»Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð·Ò¯Ð¹Ð»Ñ ÑŽÐ¼ÑƒÑƒ Ñ‚Ð°Ð½Ð´ Ñ…Ð°Ð¼Ð°Ð°Ñ‚Ð°Ð¹ Ð·Ò¯Ð¹Ð»ÑÐ¸Ð¹Ð½ Ñ‚Ð°Ð»Ð°Ð°Ñ€ Ð¼ÑÐ´ÑÐ³Ð´ÑÐ» Ð°Ð²Ð°Ñ… Ð±Ð¾Ð»Ð½Ð¾ (Ð¢Ð°Ð½Ñ‹ Ð¾Ñ€ÑƒÑƒÐ»ÑÐ°Ð½ Ð°ÑÑƒÑƒÐ´Ð°Ð», ÑÑÐ²ÑÐ» Ñ‚Ð°Ð½Ð´ Ð¾Ð½Ð¾Ð¾ÑÐ¾Ð½ Ð³ÑÑ… Ð¼ÑÑ‚)."
-  text_no_configuration_data: "Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…Ò¯Ò¯Ð´, Ñ‡Ð¸Ð³Ð»ÑÐ»Ò¯Ò¯Ð´, Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‚Ó©Ð»Ð²Ò¯Ò¯Ð´ Ð±Ð¾Ð»Ð¾Ð½ Ð°Ð¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ñ‹Ð½ Ñ‚ÑƒÑ…Ð°Ð¹ Ð¼ÑÐ´ÑÑÐ»Ð»Ð¸Ð¹Ð³ Ñ…Ð°Ñ€Ð°Ð°Ñ…Ð°Ð½ Ð¾Ñ€ÑƒÑƒÐ»Ð°Ð°Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°.\nÐ¢Ð° ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ó©Ð³Ó©Ð³Ð´Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð³ Ð´Ð°Ñ€ÑƒÐ¹Ñ…Ð°Ð½ Ð¾Ñ€ÑƒÑƒÐ»Ð°Ñ…Ñ‹Ð³ Ð·Ó©Ð²Ð»Ó©Ð¶ Ð±Ð°Ð¹Ð½Ð°, Ð¾Ñ€ÑƒÑƒÐ»ÑÐ°Ð½ Ñ…Ð¾Ð¹Ð½Ð¾ Ñ‚Ð° Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ð¶ Ð±Ð¾Ð»Ð½Ð¾."
-  text_load_default_configuration: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ó©Ð³Ó©Ð³Ð´Ð»Ð¸Ð¹Ð³ Ð°Ñ‡Ð°Ð°Ð»Ð°Ñ…
-  text_status_changed_by_changeset: "%{value} Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ó©Ð´ Ñ…Ð¸Ð¹Ð³Ð´ÑÑÐ½."
-  text_issues_destroy_confirmation: 'Ð¢Ð° ÑÐ¾Ð½Ð³Ð¾Ð³Ð´ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ò¯Ð½ÑÑ…ÑÑÑ€ ÑƒÑÑ‚Ð³Ð°Ð¼Ð°Ð°Ñ€ Ð±Ð°Ð¹Ð½Ð° ÑƒÑƒ ?'
-  text_select_project_modules:  'Ð­Ð½Ñ Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ… Ð¼Ð¾Ð´ÑƒÐ»ÑƒÑƒÐ´Ð°Ð° ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ:'
-  text_default_administrator_account_changed: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ñ‹Ð½ Ð±Ò¯Ñ€Ñ‚Ð³ÑÐ» Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð³Ð´Ð»Ó©Ó©
-  text_file_repository_writable: Ð¥Ð°Ð²ÑÑ€Ð°Ð»Ñ‚ Ñ„Ð°Ð¹Ð» Ñ…Ð°Ð´Ð³Ð°Ð»Ð°Ñ… Ñ…Ð°Ð²Ñ‚Ð°Ñ Ñ€ÑƒÑƒ Ð±Ð¸Ñ‡Ð¸Ñ… ÑÑ€Ñ…Ñ‚ÑÐ¹
-  text_plugin_assets_writable: ÐŸÐ»Ð°Ð³Ð¸Ð½ Ð¼Ð¾Ð´ÑƒÐ»Ð¸Ð¹Ð½ Ð°ÑÑÐµÑ‚ Ñ…Ð°Ð²Ñ‚Ð°Ñ Ñ€ÑƒÑƒ Ð±Ð¸Ñ‡Ð¸Ñ… ÑÑ€Ñ…Ñ‚ÑÐ¹
-  text_rmagick_available: RMagick ÑÑƒÑƒÐ»Ð³Ð°Ð³Ð´ÑÐ°Ð½ (Ð·Ð°Ð°Ð²Ð°Ð» Ð±Ð¸Ñˆ)
-  text_destroy_time_entries_question: "Ð¢Ð°Ð½Ñ‹ ÑƒÑÑ‚Ð³Ð°Ñ… Ð³ÑÐ¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´ Ð´ÑÑÑ€ Ð½Ð¸Ð¹Ñ‚ %{hours} Ñ†Ð°Ð³ Ð·Ð°Ñ€Ñ†ÑƒÑƒÐ»ÑÐ°Ð½ ÑŽÐ¼ Ð±Ð°Ð¹Ð½Ð°, Ñ‚Ð° ÑÐ°Ñ… Ð²Ñ ?"
-  text_destroy_time_entries: ÐœÑÐ´ÑÐ³Ð´ÑÑÐ½ Ñ†Ð°Ð³ÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
-  text_assign_time_entries_to_project: ÐœÑÐ´ÑÐ³Ð´ÑÑÐ½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ‚Ó©ÑÓ©Ð»Ð´ Ð¾Ð½Ð¾Ð¾Ñ…
-  text_reassign_time_entries: 'ÐœÑÐ´ÑÐ³Ð´ÑÑÐ½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑÐ½Ñ Ð°ÑÑƒÑƒÐ´Ð°Ð»Ð´ Ð´Ð°Ñ…Ð¸Ð½ Ð¾Ð½Ð¾Ð¾:'
-  text_user_wrote: "%{value} Ð±Ð¸Ñ‡Ð¸Ñ…Ð´ÑÑ:"
-  text_enumeration_destroy_question: "Ð­Ð½Ñ ÑƒÑ‚Ð³Ð°Ð´ %{count} Ð¾Ð±ÑŒÐµÐºÑ‚ Ð¾Ð½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½ Ð±Ð°Ð¹Ð½Ð°."
-  text_enumeration_category_reassign_to: 'Ð¢ÑÐ´Ð³ÑÑÑ€Ð¸Ð¹Ð³ ÑÐ½Ñ ÑƒÑ‚Ð³Ð°Ð´ Ð´Ð°Ñ…Ð¸Ð½ Ð¾Ð½Ð¾Ð¾:'
-  text_email_delivery_not_configured: "Ð˜Ð¼ÑÐ¹Ð»Ð¸Ð¹Ð½ Ñ‚Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾Ð³ Ñ…Ð°Ñ€Ð°Ð°Ñ…Ð°Ð½ Ñ‚Ð¾Ñ…Ð¸Ñ€ÑƒÑƒÐ»Ð°Ð°Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°, Ñ‚Ð¸Ð¹Ð¼ÑÑÑ Ð¸Ð¼ÑÐ¹Ð» Ð¼ÑÐ´ÑÐ³Ð´ÑÐ» ÑÐ²ÑƒÑƒÐ»Ð°Ñ… Ð±Ð¾Ð»Ð¾Ð¼Ð¶Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°.\nSMTP ÑÐµÑ€Ð²ÑÑ€ÑÑ config/configuration.yml Ñ„Ð°Ð¹Ð» Ð´Ð¾Ñ‚Ð¾Ñ€ Ñ‚Ð¾Ñ…Ð¸Ñ€ÑƒÑƒÐ»Ð°Ð°Ð´ Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ð¼ÐµÐ½ÐµÐ¶ÐµÑ€ÑÑ Ð´Ð°Ñ…Ð¸Ð°Ð´ ÑÑ…Ð»Ò¯Ò¯Ð»ÑÑÑ€ÑÐ¹."
-  text_repository_usernames_mapping: "Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ð¹Ð½ Ð»Ð¾Ð³Ð´ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±Ò¯Ñ… Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ð½ÑÑ€Ò¯Ò¯Ð´ÑÐ´ Ñ…Ð°Ñ€Ð³Ð°Ð»Ð·ÑÐ°Ð½ Ð¢Ó©ÑÐ»Ð¸Ð¹Ð½ ÐœÐµÐ½ÐµÐ¶ÐµÑ€ ÑÐ¸ÑÑ‚ÐµÐ¼Ð´ Ð±Ò¯Ñ€Ñ‚Ð³ÑÐ»Ñ‚ÑÐ¹ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð´Ð¸Ð¹Ð³ Ð¡Ð¾Ð½Ð³Ð¾Ñ… ÑŽÐ¼ÑƒÑƒ ÑˆÐ¸Ð½ÑÑ‡Ð¸Ð»Ð½Ñ Ò¯Ò¯.\nÐ¢Ó©ÑÐ»Ð¸Ð¹Ð½ Ð¼ÐµÐ½ÐµÐ¶ÐµÑ€ Ð±Ð¾Ð»Ð¾Ð½ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ð´ Ð±Ð°Ð¹Ð³Ð°Ð° Ð¸Ð¶Ð¸Ð»Ñ…ÑÐ½ Ð½ÑÑ€ ÑŽÐ¼ÑƒÑƒ Ð¸Ð¼ÑÐ¹Ð»Ñ‚ÑÐ¹ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð´ Ñ…Ð°Ñ€Ð¸Ð»Ñ†Ð°Ð½ Ñ…Ð°Ñ€Ð³Ð°Ð»Ð·Ð½Ð°."
-  text_diff_truncated: '... Ð¤Ð°Ð¹Ð»Ñ‹Ð½ ÑÐ»Ð³Ð°Ð²Ñ€Ñ‹Ð½ Ñ…ÑÐ¼Ð¶ÑÑ Ò¯Ð·Ò¯Ò¯Ð»ÑÑ…ÑÐ´ Ð´ÑÐ½Ð´Ò¯Ò¯ ÑƒÑ€Ñ‚ Ð±Ð°Ð¹Ð³Ð°Ð° ÑƒÑ‡Ñ€Ð°Ð°Ñ Ñ‚Ó©Ð³ÑÐ³Ó©Ð»Ó©Ó©Ñ Ð½ÑŒ Ñ…Ð°ÑÑ‡ Ò¯Ð·Ò¯Ò¯Ð»ÑÐ².'
-  text_custom_field_possible_values_info: 'One line for each value'
-  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
-  text_wiki_page_nullify_children: "Keep child pages as root pages"
-  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
-  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
-  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
-  
-  default_role_manager: ÐœÐµÐ½ÐµÐ¶ÐµÑ€
-  default_role_developer: Ð¥Ó©Ð³Ð¶Ò¯Ò¯Ð»ÑÐ³Ñ‡
-  default_role_reporter: ÐœÑÐ´ÑÐ³Ð´ÑÐ³Ñ‡
-  default_tracker_bug: ÐÐ»Ð´Ð°Ð°
-  default_tracker_feature: ÐžÐ½Ñ†Ð»Ð¾Ð³
-  default_tracker_support: Ð¢ÑƒÑÐ»Ð°Ð¼Ð¶
-  default_issue_status_new: Ð¨Ð¸Ð½Ñ
-  default_issue_status_in_progress: ÐÑ…Ð¸Ñ†Ñ‚Ð°Ð¹
-  default_issue_status_assigned: ÐžÐ½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½
-  default_issue_status_resolved: Ð¨Ð¸Ð¹Ð´Ð²ÑÑ€Ð»ÑÐ³Ð´ÑÑÐ½
-  default_issue_status_feedback: Feedback
-  default_issue_status_closed: Ð¥Ð°Ð°Ð³Ð´ÑÐ°Ð½
-  default_issue_status_rejected: Ð¥Ò¯Ð»ÑÑÐ¶ Ð°Ð²Ð°Ð°Ð³Ò¯Ð¹
-  default_doc_category_user: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ð±Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚
-  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸ÐºÐ¸Ð¹Ð½ Ð±Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚
-  default_priority_low: Ð‘Ð°Ð³Ð°
-  default_priority_normal: Ð¥ÑÐ²Ð¸Ð¹Ð½
-  default_priority_high: Ó¨Ð½Ð´Ó©Ñ€
-  default_priority_urgent: ÐÑÐ½ ÑÐ°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
-  default_priority_immediate: ÐÑÐ½ Ð´Ð°Ñ€ÑƒÐ¹
-  default_activity_design: Ð”Ð¸Ð·Ð°Ð¹Ð½
-  default_activity_development: Ð¥Ó©Ð³Ð¶Ò¯Ò¯Ð»ÑÐ»Ñ‚
-  
-  enumeration_issue_priorities: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ð·ÑÑ€ÑÐ³Ð»ÑÐ»Ò¯Ò¯Ð´
-  enumeration_doc_categories: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚Ñ‹Ð½ Ð°Ð½Ð³Ð¸Ð»Ð»ÑƒÑƒÐ´
-  enumeration_activities: Ò®Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°Ð½ÑƒÑƒÐ´ (Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð³ Ñ…ÑÐ½Ð°Ñ…)
-  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð¸Ð¹Ð½ Ò¯Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°
-
-  permission_manage_subtasks: Manage subtasks
-  label_profile: Profile
-  field_parent_issue: Parent task
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: ÐšÐ¾Ð¼Ð¼Ð¸Ñ‚ Ñ…Ð¸Ð¹Ñ… Ò¯ÐµÐ´ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ… Ñ‚ÐµÐºÑÑ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð½ ÑÐ½ÐºÐ¾Ð´Ð¸Ð½Ð³
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/57/57ecc0dda1965991f4066469497ab0ab44365ffc.svn-base
--- /dev/null
+++ b/.svn/pristine/57/57ecc0dda1965991f4066469497ab0ab44365ffc.svn-base
@@ -0,0 +1,355 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+RedmineApp::Application.routes.draw do
+  root :to => 'welcome#index', :as => 'home'
+
+  match 'login', :to => 'account#login', :as => 'signin', :via => [:get, :post]
+  match 'logout', :to => 'account#logout', :as => 'signout', :via => [:get, :post]
+  match 'account/register', :to => 'account#register', :via => [:get, :post], :as => 'register'
+  match 'account/lost_password', :to => 'account#lost_password', :via => [:get, :post], :as => 'lost_password'
+  match 'account/activate', :to => 'account#activate', :via => :get
+
+  match '/news/preview', :controller => 'previews', :action => 'news', :as => 'preview_news', :via => [:get, :post, :put]
+  match '/issues/preview/new/:project_id', :to => 'previews#issue', :as => 'preview_new_issue', :via => [:get, :post, :put]
+  match '/issues/preview/edit/:id', :to => 'previews#issue', :as => 'preview_edit_issue', :via => [:get, :post, :put]
+  match '/issues/preview', :to => 'previews#issue', :as => 'preview_issue', :via => [:get, :post, :put]
+
+  match 'projects/:id/wiki', :to => 'wikis#edit', :via => :post
+  match 'projects/:id/wiki/destroy', :to => 'wikis#destroy', :via => [:get, :post]
+
+  match 'boards/:board_id/topics/new', :to => 'messages#new', :via => [:get, :post], :as => 'new_board_message'
+  get 'boards/:board_id/topics/:id', :to => 'messages#show', :as => 'board_message'
+  match 'boards/:board_id/topics/quote/:id', :to => 'messages#quote', :via => [:get, :post]
+  get 'boards/:board_id/topics/:id/edit', :to => 'messages#edit'
+
+  post 'boards/:board_id/topics/preview', :to => 'messages#preview', :as => 'preview_board_message'
+  post 'boards/:board_id/topics/:id/replies', :to => 'messages#reply'
+  post 'boards/:board_id/topics/:id/edit', :to => 'messages#edit'
+  post 'boards/:board_id/topics/:id/destroy', :to => 'messages#destroy'
+
+  # Misc issue routes. TODO: move into resources
+  match '/issues/auto_complete', :to => 'auto_completes#issues', :via => :get, :as => 'auto_complete_issues'
+  match '/issues/context_menu', :to => 'context_menus#issues', :as => 'issues_context_menu', :via => [:get, :post]
+  match '/issues/changes', :to => 'journals#index', :as => 'issue_changes', :via => :get
+  match '/issues/:id/quoted', :to => 'journals#new', :id => /\d+/, :via => :post, :as => 'quoted_issue'
+
+  match '/journals/diff/:id', :to => 'journals#diff', :id => /\d+/, :via => :get
+  match '/journals/edit/:id', :to => 'journals#edit', :id => /\d+/, :via => [:get, :post]
+
+  get '/projects/:project_id/issues/gantt', :to => 'gantts#show', :as => 'project_gantt'
+  get '/issues/gantt', :to => 'gantts#show'
+
+  get '/projects/:project_id/issues/calendar', :to => 'calendars#show', :as => 'project_calendar'
+  get '/issues/calendar', :to => 'calendars#show'
+
+  get 'projects/:id/issues/report', :to => 'reports#issue_report', :as => 'project_issues_report'
+  get 'projects/:id/issues/report/:detail', :to => 'reports#issue_report_details', :as => 'project_issues_report_details'
+
+  match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post]
+  match 'my/account/destroy', :controller => 'my', :action => 'destroy', :via => [:get, :post]
+  match 'my/page', :controller => 'my', :action => 'page', :via => :get
+  match 'my', :controller => 'my', :action => 'index', :via => :get # Redirects to my/page
+  match 'my/reset_rss_key', :controller => 'my', :action => 'reset_rss_key', :via => :post
+  match 'my/reset_api_key', :controller => 'my', :action => 'reset_api_key', :via => :post
+  match 'my/password', :controller => 'my', :action => 'password', :via => [:get, :post]
+  match 'my/page_layout', :controller => 'my', :action => 'page_layout', :via => :get
+  match 'my/add_block', :controller => 'my', :action => 'add_block', :via => :post
+  match 'my/remove_block', :controller => 'my', :action => 'remove_block', :via => :post
+  match 'my/order_blocks', :controller => 'my', :action => 'order_blocks', :via => :post
+
+  resources :users
+  match 'users/:id/memberships/:membership_id', :to => 'users#edit_membership', :via => :put, :as => 'user_membership'
+  match 'users/:id/memberships/:membership_id', :to => 'users#destroy_membership', :via => :delete
+  match 'users/:id/memberships', :to => 'users#edit_membership', :via => :post, :as => 'user_memberships'
+
+  post 'watchers/watch', :to => 'watchers#watch', :as => 'watch'
+  delete 'watchers/watch', :to => 'watchers#unwatch'
+  get 'watchers/new', :to => 'watchers#new'
+  post 'watchers', :to => 'watchers#create'
+  post 'watchers/append', :to => 'watchers#append'
+  delete 'watchers', :to => 'watchers#destroy'
+  get 'watchers/autocomplete_for_user', :to => 'watchers#autocomplete_for_user'
+  # Specific routes for issue watchers API
+  post 'issues/:object_id/watchers', :to => 'watchers#create', :object_type => 'issue'
+  delete 'issues/:object_id/watchers/:user_id' => 'watchers#destroy', :object_type => 'issue'
+
+  resources :projects do
+    member do
+      get 'settings(/:tab)', :action => 'settings', :as => 'settings'
+      post 'modules'
+      post 'archive'
+      post 'unarchive'
+      post 'close'
+      post 'reopen'
+      match 'copy', :via => [:get, :post]
+    end
+
+    shallow do
+      resources :memberships, :controller => 'members', :only => [:index, :show, :new, :create, :update, :destroy] do
+        collection do
+          get 'autocomplete'
+        end
+      end
+    end
+
+    resource :enumerations, :controller => 'project_enumerations', :only => [:update, :destroy]
+
+    get 'issues/:copy_from/copy', :to => 'issues#new', :as => 'copy_issue'
+    resources :issues, :only => [:index, :new, :create] do
+      resources :time_entries, :controller => 'timelog' do
+        collection do
+          get 'report'
+        end
+      end
+    end
+    # issue form update
+    match 'issues/update_form', :controller => 'issues', :action => 'update_form', :via => [:put, :post], :as => 'issue_form'
+
+    resources :files, :only => [:index, :new, :create]
+
+    resources :versions, :except => [:index, :show, :edit, :update, :destroy] do
+      collection do
+        put 'close_completed'
+      end
+    end
+    get 'versions.:format', :to => 'versions#index'
+    get 'roadmap', :to => 'versions#index', :format => false
+    get 'versions', :to => 'versions#index'
+
+    resources :news, :except => [:show, :edit, :update, :destroy]
+    resources :time_entries, :controller => 'timelog' do
+      get 'report', :on => :collection
+    end
+    resources :queries, :only => [:new, :create]
+    shallow do
+      resources :issue_categories
+    end
+    resources :documents, :except => [:show, :edit, :update, :destroy]
+    resources :boards
+    shallow do
+      resources :repositories, :except => [:index, :show] do
+        member do
+          match 'committers', :via => [:get, :post]
+        end
+      end
+    end
+  
+    match 'wiki/index', :controller => 'wiki', :action => 'index', :via => :get
+    resources :wiki, :except => [:index, :new, :create], :as => 'wiki_page' do
+      member do
+        get 'rename'
+        post 'rename'
+        get 'history'
+        get 'diff'
+        match 'preview', :via => [:post, :put]
+        post 'protect'
+        post 'add_attachment'
+      end
+      collection do
+        get 'export'
+        get 'date_index'
+      end
+    end
+    match 'wiki', :controller => 'wiki', :action => 'show', :via => :get
+    get 'wiki/:id/:version', :to => 'wiki#show', :constraints => {:version => /\d+/}
+    delete 'wiki/:id/:version', :to => 'wiki#destroy_version'
+    get 'wiki/:id/:version/annotate', :to => 'wiki#annotate'
+    get 'wiki/:id/:version/diff', :to => 'wiki#diff'
+  end
+
+  resources :issues do
+    collection do
+      match 'bulk_edit', :via => [:get, :post]
+      post 'bulk_update'
+    end
+    resources :time_entries, :controller => 'timelog' do
+      collection do
+        get 'report'
+      end
+    end
+    shallow do
+      resources :relations, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
+    end
+  end
+  match '/issues', :controller => 'issues', :action => 'destroy', :via => :delete
+
+  resources :queries, :except => [:show]
+
+  resources :news, :only => [:index, :show, :edit, :update, :destroy]
+  match '/news/:id/comments', :to => 'comments#create', :via => :post
+  match '/news/:id/comments/:comment_id', :to => 'comments#destroy', :via => :delete
+
+  resources :versions, :only => [:show, :edit, :update, :destroy] do
+    post 'status_by', :on => :member
+  end
+
+  resources :documents, :only => [:show, :edit, :update, :destroy] do
+    post 'add_attachment', :on => :member
+  end
+
+  match '/time_entries/context_menu', :to => 'context_menus#time_entries', :as => :time_entries_context_menu, :via => [:get, :post]
+
+  resources :time_entries, :controller => 'timelog', :except => :destroy do
+    collection do
+      get 'report'
+      get 'bulk_edit'
+      post 'bulk_update'
+    end
+  end
+  match '/time_entries/:id', :to => 'timelog#destroy', :via => :delete, :id => /\d+/
+  # TODO: delete /time_entries for bulk deletion
+  match '/time_entries/destroy', :to => 'timelog#destroy', :via => :delete
+
+  get 'projects/:id/activity', :to => 'activities#index'
+  get 'projects/:id/activity.:format', :to => 'activities#index'
+  get 'activity', :to => 'activities#index'
+
+  # repositories routes
+  get 'projects/:id/repository/:repository_id/statistics', :to => 'repositories#stats'
+  get 'projects/:id/repository/:repository_id/graph', :to => 'repositories#graph'
+
+  get 'projects/:id/repository/:repository_id/changes(/*path(.:ext))',
+      :to => 'repositories#changes'
+
+  get 'projects/:id/repository/:repository_id/revisions/:rev', :to => 'repositories#revision'
+  get 'projects/:id/repository/:repository_id/revision', :to => 'repositories#revision'
+  post   'projects/:id/repository/:repository_id/revisions/:rev/issues', :to => 'repositories#add_related_issue'
+  delete 'projects/:id/repository/:repository_id/revisions/:rev/issues/:issue_id', :to => 'repositories#remove_related_issue'
+  get 'projects/:id/repository/:repository_id/revisions', :to => 'repositories#revisions'
+  get 'projects/:id/repository/:repository_id/revisions/:rev/:action(/*path(.:ext))',
+      :controller => 'repositories',
+      :format => false,
+      :constraints => {
+            :action => /(browse|show|entry|raw|annotate|diff)/,
+            :rev    => /[a-z0-9\.\-_]+/
+          }
+
+  get 'projects/:id/repository/statistics', :to => 'repositories#stats'
+  get 'projects/:id/repository/graph', :to => 'repositories#graph'
+
+  get 'projects/:id/repository/changes(/*path(.:ext))',
+      :to => 'repositories#changes'
+
+  get 'projects/:id/repository/revisions', :to => 'repositories#revisions'
+  get 'projects/:id/repository/revisions/:rev', :to => 'repositories#revision'
+  get 'projects/:id/repository/revision', :to => 'repositories#revision'
+  post   'projects/:id/repository/revisions/:rev/issues', :to => 'repositories#add_related_issue'
+  delete 'projects/:id/repository/revisions/:rev/issues/:issue_id', :to => 'repositories#remove_related_issue'
+  get 'projects/:id/repository/revisions/:rev/:action(/*path(.:ext))',
+      :controller => 'repositories',
+      :format => false,
+      :constraints => {
+            :action => /(browse|show|entry|raw|annotate|diff)/,
+            :rev    => /[a-z0-9\.\-_]+/
+          }
+  get 'projects/:id/repository/:repository_id/:action(/*path(.:ext))',
+      :controller => 'repositories',
+      :action => /(browse|show|entry|raw|changes|annotate|diff)/
+  get 'projects/:id/repository/:action(/*path(.:ext))',
+      :controller => 'repositories',
+      :action => /(browse|show|entry|raw|changes|annotate|diff)/
+
+  get 'projects/:id/repository/:repository_id', :to => 'repositories#show', :path => nil
+  get 'projects/:id/repository', :to => 'repositories#show', :path => nil
+
+  # additional routes for having the file name at the end of url
+  get 'attachments/:id/:filename', :to => 'attachments#show', :id => /\d+/, :filename => /.*/, :as => 'named_attachment'
+  get 'attachments/download/:id/:filename', :to => 'attachments#download', :id => /\d+/, :filename => /.*/, :as => 'download_named_attachment'
+  get 'attachments/download/:id', :to => 'attachments#download', :id => /\d+/
+  get 'attachments/thumbnail/:id(/:size)', :to => 'attachments#thumbnail', :id => /\d+/, :size => /\d+/, :as => 'thumbnail'
+  resources :attachments, :only => [:show, :destroy]
+
+  resources :groups do
+    member do
+      get 'autocomplete_for_user'
+    end
+  end
+
+  match 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :via => :post, :as => 'group_users'
+  match 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :via => :delete, :as => 'group_user'
+  match 'groups/destroy_membership/:id', :controller => 'groups', :action => 'destroy_membership', :id => /\d+/, :via => :post
+  match 'groups/edit_membership/:id', :controller => 'groups', :action => 'edit_membership', :id => /\d+/, :via => :post
+
+  resources :trackers, :except => :show do
+    collection do
+      match 'fields', :via => [:get, :post]
+    end
+  end
+  resources :issue_statuses, :except => :show do
+    collection do
+      post 'update_issue_done_ratio'
+    end
+  end
+  resources :custom_fields, :except => :show
+  resources :roles do
+    collection do
+      match 'permissions', :via => [:get, :post]
+    end
+  end
+  resources :enumerations, :except => :show
+  match 'enumerations/:type', :to => 'enumerations#index', :via => :get
+
+  get 'projects/:id/search', :controller => 'search', :action => 'index'
+  get 'search', :controller => 'search', :action => 'index'
+
+  match 'mail_handler', :controller => 'mail_handler', :action => 'index', :via => :post
+
+  match 'admin', :controller => 'admin', :action => 'index', :via => :get
+  match 'admin/projects', :controller => 'admin', :action => 'projects', :via => :get
+  match 'admin/plugins', :controller => 'admin', :action => 'plugins', :via => :get
+  match 'admin/info', :controller => 'admin', :action => 'info', :via => :get
+  match 'admin/test_email', :controller => 'admin', :action => 'test_email', :via => :get
+  match 'admin/default_configuration', :controller => 'admin', :action => 'default_configuration', :via => :post
+
+  resources :auth_sources do
+    member do
+      get 'test_connection', :as => 'try_connection'
+    end
+    collection do
+      get 'autocomplete_for_new_user'
+    end
+  end
+
+  match 'workflows', :controller => 'workflows', :action => 'index', :via => :get
+  match 'workflows/edit', :controller => 'workflows', :action => 'edit', :via => [:get, :post]
+  match 'workflows/permissions', :controller => 'workflows', :action => 'permissions', :via => [:get, :post]
+  match 'workflows/copy', :controller => 'workflows', :action => 'copy', :via => [:get, :post]
+  match 'settings', :controller => 'settings', :action => 'index', :via => :get
+  match 'settings/edit', :controller => 'settings', :action => 'edit', :via => [:get, :post]
+  match 'settings/plugin/:id', :controller => 'settings', :action => 'plugin', :via => [:get, :post], :as => 'plugin_settings'
+
+  match 'sys/projects', :to => 'sys#projects', :via => :get
+  match 'sys/projects/:id/repository', :to => 'sys#create_project_repository', :via => :post
+  match 'sys/fetch_changesets', :to => 'sys#fetch_changesets', :via => :get
+
+  match 'uploads', :to => 'attachments#upload', :via => :post
+
+  get 'robots.txt', :to => 'welcome#robots'
+
+  Dir.glob File.expand_path("plugins/*", Rails.root) do |plugin_dir|
+    file = File.join(plugin_dir, "config/routes.rb")
+    if File.exists?(file)
+      begin
+        instance_eval File.read(file)
+      rescue Exception => e
+        puts "An error occurred while loading the routes definition of #{File.basename(plugin_dir)} plugin (#{file}): #{e.message}."
+        exit 1
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/58/5822b09752fa0149f57efed74cf7dcc3c9694bb5.svn-base
--- a/.svn/pristine/58/5822b09752fa0149f57efed74cf7dcc3c9694bb5.svn-base
+++ /dev/null
@@ -1,38 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Utils
-    class << self
-      # Returns the relative root url of the application
-      def relative_url_root
-        ActionController::Base.respond_to?('relative_url_root') ?
-          ActionController::Base.relative_url_root.to_s :
-          ActionController::AbstractRequest.relative_url_root.to_s
-      end
-
-      # Sets the relative root url of the application
-      def relative_url_root=(arg)
-        if ActionController::Base.respond_to?('relative_url_root=')
-          ActionController::Base.relative_url_root=arg
-        else
-          ActionController::AbstractRequest.relative_url_root=arg
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/58/5852d7fa42575c6a27e640ff68cec09c3d3e0a43.svn-base
--- a/.svn/pristine/58/5852d7fa42575c6a27e640ff68cec09c3d3e0a43.svn-base
+++ /dev/null
@@ -1,157 +0,0 @@
-# = Redmine configuration file
-#
-# Each environment has it's own configuration options.  If you are only
-# running in production, only the production block needs to be configured.
-# Environment specific configuration options override the default ones.
-#
-# Note that this file needs to be a valid YAML file.
-# DO NOT USE TABS! Use 2 spaces instead of tabs for identation.
-#
-# == Outgoing email settings (email_delivery setting)
-#
-# === Common configurations
-#
-# ==== Sendmail command
-#
-# production:
-#   email_delivery:
-#     delivery_method: :sendmail
-#
-# ==== Simple SMTP server at localhost
-#
-# production:
-#   email_delivery:
-#     delivery_method: :smtp
-#     smtp_settings:
-#       address: "localhost"
-#       port: 25
-#
-# ==== SMTP server at example.com using LOGIN authentication and checking HELO for foo.com
-#
-# production:
-#   email_delivery:
-#     delivery_method: :smtp
-#     smtp_settings:
-#       address: "example.com"
-#       port: 25
-#       authentication: :login
-#       domain: 'foo.com'
-#       user_name: 'myaccount'
-#       password: 'password'
-#
-# ==== SMTP server at example.com using PLAIN authentication
-#
-# production:
-#   email_delivery:
-#     delivery_method: :smtp
-#     smtp_settings:
-#       address: "example.com"
-#       port: 25
-#       authentication: :plain
-#       domain: 'example.com'
-#       user_name: 'myaccount'
-#       password: 'password'
-#
-# ==== SMTP server at using TLS (GMail)
-#
-# This requires some additional configuration.  See the article at:
-# http://redmineblog.com/articles/setup-redmine-to-send-email-using-gmail/
-#
-# production:
-#   email_delivery:
-#     delivery_method: :smtp
-#     smtp_settings:
-#       tls: true
-#       enable_starttls_auto: true
-#       address: "smtp.gmail.com"
-#       port: 587
-#       domain: "smtp.gmail.com" # 'your.domain.com' for GoogleApps
-#       authentication: :plain
-#       user_name: "your_email@gmail.com"
-#       password: "your_password"
-#
-#
-# === More configuration options
-#
-# See the "Configuration options" at the following website for a list of the
-# full options allowed:
-#
-# http://wiki.rubyonrails.org/rails/pages/HowToSendEmailsWithActionMailer
-
-
-# default configuration options for all environments
-default:
-  # Outgoing emails configuration (see examples above)
-  email_delivery:
-    delivery_method: :smtp
-    smtp_settings:
-      address: smtp.example.net
-      port: 25
-      domain: example.net
-      authentication: :login
-      user_name: "redmine@example.net"
-      password: "redmine"
-
-  # Absolute path to the directory where attachments are stored.
-  # The default is the 'files' directory in your Redmine instance.
-  # Your Redmine instance needs to have write permission on this
-  # directory.
-  # Examples:
-  # attachments_storage_path: /var/redmine/files
-  # attachments_storage_path: D:/redmine/files
-  attachments_storage_path:
-
-  # Configuration of the autologin cookie.
-  # autologin_cookie_name: the name of the cookie (default: autologin)
-  # autologin_cookie_path: the cookie path (default: /)
-  # autologin_cookie_secure: true sets the cookie secure flag (default: false)
-  autologin_cookie_name:
-  autologin_cookie_path:
-  autologin_cookie_secure:
-
-  # Configuration of SCM executable command.
-  #
-  # Absolute path (e.g. /usr/local/bin/hg) or command name (e.g. hg.exe, bzr.exe)
-  # On Windows + CRuby, *.cmd, *.bat (e.g. hg.cmd, bzr.bat) does not work.
-  #
-  # On Windows + JRuby 1.6.2, path which contains spaces does not work.
-  # For example, "C:\Program Files\TortoiseHg\hg.exe".
-  # If you want to this feature, you need to install to the path which does not contains spaces.
-  # For example, "C:\TortoiseHg\hg.exe".
-  #
-  # Examples:
-  # scm_subversion_command: svn                                       # (default: svn)
-  # scm_mercurial_command:  C:\Program Files\TortoiseHg\hg.exe        # (default: hg)
-  # scm_git_command:        /usr/local/bin/git                        # (default: git)
-  # scm_cvs_command:        cvs                                       # (default: cvs)
-  # scm_bazaar_command:     bzr.exe                                   # (default: bzr)
-  # scm_darcs_command:      darcs-1.0.9-i386-linux                    # (default: darcs)
-  #
-  scm_subversion_command:
-  scm_mercurial_command:
-  scm_git_command:
-  scm_cvs_command:
-  scm_bazaar_command:
-  scm_darcs_command:
-
-  # Key used to encrypt sensitive data in the database (SCM and LDAP passwords).
-  # If you don't want to enable data encryption, just leave it blank.
-  # WARNING: losing/changing this key will make encrypted data unreadable.
-  #
-  # If you want to encrypt existing passwords in your database:
-  # * set the cipher key here in your configuration file
-  # * encrypt data using 'rake db:encrypt RAILS_ENV=production'
-  #
-  # If you have encrypted data and want to change this key, you have to:
-  # * decrypt data using 'rake db:decrypt RAILS_ENV=production' first
-  # * change the cipher key here in your configuration file
-  # * encrypt data using 'rake db:encrypt RAILS_ENV=production'
-  database_cipher_key:
-
-# specific configuration options for production environment
-# that overrides the default ones
-production:
-
-# specific configuration options for development environment
-# that overrides the default ones
-development:
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/58/5878eef8c7c288582eab7e2a8dc69cc546b48c08.svn-base
--- /dev/null
+++ b/.svn/pristine/58/5878eef8c7c288582eab7e2a8dc69cc546b48c08.svn-base
@@ -0,0 +1,27 @@
+<h3 class="title"><%= l(:permission_add_issue_watchers) %></h3>
+
+<%= form_tag({:controller => 'watchers',
+              :action => (watched ? 'create' : 'append'),
+              :object_type => (watched && watched.class.name.underscore),
+              :object_id => watched,
+              :project_id => @project},
+             :remote => true,
+             :method => :post,
+             :id => 'new-watcher-form') do %>
+
+  <p><%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
+  <%= javascript_tag "observeSearchfield('user_search', 'users_for_watcher', '#{ escape_javascript url_for(:controller => 'watchers',
+                 :action => 'autocomplete_for_user',
+                 :object_type => (watched && watched.class.name.underscore),
+                 :object_id => watched,
+                 :project_id => @project) }')" %>
+
+  <div id="users_for_watcher">
+    <%= principals_check_box_tags 'watcher[user_ids][]', (watched ? watched.addable_watcher_users : User.active.all(:limit => 100)) %>
+  </div>
+
+  <p class="buttons">
+    <%= submit_tag l(:button_add), :name => nil, :onclick => "hideModal(this);" %>
+    <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
+  </p>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/58/587f513ddb7f708d124448f5d5cd571d4d406ca2.svn-base
--- a/.svn/pristine/58/587f513ddb7f708d124448f5d5cd571d4d406ca2.svn-base
+++ /dev/null
@@ -1,87 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssueMovesController < ApplicationController
-  menu_item :issues
-
-  default_search_scope :issues
-  before_filter :find_issues, :check_project_uniqueness
-  before_filter :authorize
-
-  def new
-    prepare_for_issue_move
-    render :layout => false if request.xhr?
-  end
-
-  def create
-    prepare_for_issue_move
-
-    if request.post?
-      new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
-      unsaved_issue_ids = []
-      moved_issues = []
-      @issues.each do |issue|
-        issue.reload
-        issue.init_journal(User.current)
-        issue.current_journal.notes = @notes if @notes.present?
-        call_hook(:controller_issues_move_before_save, { :params => params, :issue => issue, :target_project => @target_project, :copy => !!@copy })
-        if r = issue.move_to_project(@target_project, new_tracker, {:copy => @copy, :attributes => extract_changed_attributes_for_move(params)})
-          moved_issues << r
-        else
-          unsaved_issue_ids << issue.id
-        end
-      end
-      set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids)
-
-      if params[:follow]
-        if @issues.size == 1 && moved_issues.size == 1
-          redirect_to :controller => 'issues', :action => 'show', :id => moved_issues.first
-        else
-          redirect_to :controller => 'issues', :action => 'index', :project_id => (@target_project || @project)
-        end
-      else
-        redirect_to :controller => 'issues', :action => 'index', :project_id => @project
-      end
-      return
-    end
-  end
-
-  private
-
-  def prepare_for_issue_move
-    @issues.sort!
-    @copy = params[:copy_options] && params[:copy_options][:copy]
-    @allowed_projects = Issue.allowed_target_projects_on_move
-    @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:new_project_id]} if params[:new_project_id]
-    @target_project ||= @project
-    @trackers = @target_project.trackers
-    @available_statuses = Workflow.available_statuses(@project)
-    @notes = params[:notes]
-    @notes ||= ''
-  end
-
-  def extract_changed_attributes_for_move(params)
-    changed_attributes = {}
-    [:assigned_to_id, :status_id, :start_date, :due_date, :priority_id].each do |valid_attribute|
-      unless params[valid_attribute].blank?
-        changed_attributes[valid_attribute] = (params[valid_attribute] == 'none' ? nil : params[valid_attribute])
-      end
-    end
-    changed_attributes
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/58/58ad4095c1a6118f6d53fd92a945cd194604e422.svn-base
--- /dev/null
+++ b/.svn/pristine/58/58ad4095c1a6118f6d53fd92a945cd194604e422.svn-base
@@ -0,0 +1,81 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class PreviewsControllerTest < ActionController::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :journals, :journal_details,
+           :news
+
+  def test_preview_new_issue
+    @request.session[:user_id] = 2
+    post :issue, :project_id => '1', :issue => {:description => 'Foo'}
+    assert_response :success
+    assert_template 'preview'
+    assert_not_nil assigns(:description)
+  end
+
+  def test_preview_issue_notes
+    @request.session[:user_id] = 2
+    post :issue, :project_id => '1', :id => 1,
+         :issue => {:description => Issue.find(1).description, :notes => 'Foo'}
+    assert_response :success
+    assert_template 'preview'
+    assert_not_nil assigns(:notes)
+  end
+
+  def test_preview_journal_notes_for_update
+    @request.session[:user_id] = 2
+    post :issue, :project_id => '1', :id => 1, :notes => 'Foo'
+    assert_response :success
+    assert_template 'preview'
+    assert_not_nil assigns(:notes)
+    assert_tag :p, :content => 'Foo'
+  end
+
+  def test_preview_new_news
+    get :news, :project_id => 1,
+                  :news => {:title => '',
+                            :description => 'News description',
+                            :summary => ''}
+    assert_response :success
+    assert_template 'common/_preview'
+    assert_tag :tag => 'fieldset', :attributes => { :class => 'preview' },
+                                   :content => /News description/
+  end
+
+  def test_existing_new_news
+    get :news, :project_id => 1, :id => 2,
+                  :news => {:title => '',
+                            :description => 'News description',
+                            :summary => ''}
+    assert_response :success
+    assert_template 'common/_preview'
+    assert_equal News.find(2), assigns(:previewed)
+    assert_not_nil assigns(:attachments)
+
+    assert_tag :tag => 'fieldset', :attributes => { :class => 'preview' },
+                                   :content => /News description/
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/58/58ae812bb411d7616ba525dd2ae2b02bda08fbd2.svn-base
--- /dev/null
+++ b/.svn/pristine/58/58ae812bb411d7616ba525dd2ae2b02bda08fbd2.svn-base
@@ -0,0 +1,59 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class UserPreference < ActiveRecord::Base
+  belongs_to :user
+  serialize :others
+
+  attr_protected :others, :user_id
+
+  before_save :set_others_hash
+  
+  def initialize(attributes=nil, *args)
+    super
+    self.others ||= {}
+  end
+
+  def set_others_hash
+    self.others ||= {}
+  end
+
+  def [](attr_name)
+    if attribute_present? attr_name
+      super
+    else
+      others ? others[attr_name] : nil
+    end
+  end
+
+  def []=(attr_name, value)
+    if attribute_present? attr_name
+      super
+    else
+      h = (read_attribute(:others) || {}).dup
+      h.update(attr_name => value)
+      write_attribute(:others, h)
+      value
+    end
+  end
+
+  def comments_sorting; self[:comments_sorting] end
+  def comments_sorting=(order); self[:comments_sorting]=order end
+
+  def warn_on_leaving_unsaved; self[:warn_on_leaving_unsaved] || '1'; end
+  def warn_on_leaving_unsaved=(value); self[:warn_on_leaving_unsaved]=value; end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/58/58b49876d90ca4f57b376fabd8862c7bd7f14741.svn-base
--- a/.svn/pristine/58/58b49876d90ca4f57b376fabd8862c7bd7f14741.svn-base
+++ /dev/null
@@ -1,172 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class GroupsController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin
-
-  helper :custom_fields
-
-  # GET /groups
-  # GET /groups.xml
-  def index
-    @groups = Group.find(:all, :order => 'lastname')
-
-    respond_to do |format|
-      format.html # index.html.erb
-      format.xml  { render :xml => @groups }
-    end
-  end
-
-  # GET /groups/1
-  # GET /groups/1.xml
-  def show
-    @group = Group.find(params[:id])
-
-    respond_to do |format|
-      format.html # show.html.erb
-      format.xml  { render :xml => @group }
-    end
-  end
-
-  # GET /groups/new
-  # GET /groups/new.xml
-  def new
-    @group = Group.new
-
-    respond_to do |format|
-      format.html # new.html.erb
-      format.xml  { render :xml => @group }
-    end
-  end
-
-  # GET /groups/1/edit
-  def edit
-    @group = Group.find(params[:id], :include => :projects)
-  end
-
-  # POST /groups
-  # POST /groups.xml
-  def create
-    @group = Group.new(params[:group])
-
-    respond_to do |format|
-      if @group.save
-        format.html {
-          flash[:notice] = l(:notice_successful_create)
-          redirect_to(params[:continue] ? new_group_path : groups_path)
-        }
-        format.xml  { render :xml => @group, :status => :created, :location => @group }
-      else
-        format.html { render :action => "new" }
-        format.xml  { render :xml => @group.errors, :status => :unprocessable_entity }
-      end
-    end
-  end
-
-  # PUT /groups/1
-  # PUT /groups/1.xml
-  def update
-    @group = Group.find(params[:id])
-
-    respond_to do |format|
-      if @group.update_attributes(params[:group])
-        flash[:notice] = l(:notice_successful_update)
-        format.html { redirect_to(groups_path) }
-        format.xml  { head :ok }
-      else
-        format.html { render :action => "edit" }
-        format.xml  { render :xml => @group.errors, :status => :unprocessable_entity }
-      end
-    end
-  end
-
-  # DELETE /groups/1
-  # DELETE /groups/1.xml
-  def destroy
-    @group = Group.find(params[:id])
-    @group.destroy
-
-    respond_to do |format|
-      format.html { redirect_to(groups_url) }
-      format.xml  { head :ok }
-    end
-  end
-
-  def add_users
-    @group = Group.find(params[:id])
-    users = User.find_all_by_id(params[:user_ids])
-    @group.users << users if request.post?
-    respond_to do |format|
-      format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
-      format.js {
-        render(:update) {|page|
-          page.replace_html "tab-content-users", :partial => 'groups/users'
-          users.each {|user| page.visual_effect(:highlight, "user-#{user.id}") }
-        }
-      }
-    end
-  end
-
-  def remove_user
-    @group = Group.find(params[:id])
-    @group.users.delete(User.find(params[:user_id])) if request.delete?
-    respond_to do |format|
-      format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
-      format.js { render(:update) {|page| page.replace_html "tab-content-users", :partial => 'groups/users'} }
-    end
-  end
-
-  def autocomplete_for_user
-    @group = Group.find(params[:id])
-    @users = User.active.not_in_group(@group).like(params[:q]).all(:limit => 100)
-    render :layout => false
-  end
-
-  def edit_membership
-    @group = Group.find(params[:id])
-    @membership = Member.edit_membership(params[:membership_id], params[:membership], @group)
-    @membership.save if request.post?
-    respond_to do |format|
-      if @membership.valid?
-        format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'memberships' }
-        format.js {
-          render(:update) {|page|
-            page.replace_html "tab-content-memberships", :partial => 'groups/memberships'
-            page.visual_effect(:highlight, "member-#{@membership.id}")
-          }
-        }
-      else
-        format.js {
-          render(:update) {|page|
-            page.alert(l(:notice_failed_to_save_members, :errors => @membership.errors.full_messages.join(', ')))
-          }
-        }
-      end
-    end
-  end
-
-  def destroy_membership
-    @group = Group.find(params[:id])
-    Member.find(params[:membership_id]).destroy if request.post?
-    respond_to do |format|
-      format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'memberships' }
-      format.js { render(:update) {|page| page.replace_html "tab-content-memberships", :partial => 'groups/memberships'} }
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/58/58b9e1838c5a7e00090791cde1a148c4ef4ea8e1.svn-base
--- /dev/null
+++ b/.svn/pristine/58/58b9e1838c5a7e00090791cde1a148c4ef4ea8e1.svn-base
@@ -0,0 +1,82 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module WatchersHelper
+
+  def watcher_tag(object, user, options={})
+    ActiveSupport::Deprecation.warn "#watcher_tag is deprecated and will be removed in Redmine 3.0. Use #watcher_link instead."
+    watcher_link(object, user)
+  end
+
+  def watcher_link(objects, user)
+    return '' unless user && user.logged?
+    objects = Array.wrap(objects)
+
+    watched = objects.any? {|object| object.watched_by?(user)}
+    css = [watcher_css(objects), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ')
+    text = watched ? l(:button_unwatch) : l(:button_watch)
+    url = watch_path(
+      :object_type => objects.first.class.to_s.underscore,
+      :object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort)
+    )
+    method = watched ? 'delete' : 'post'
+
+    link_to text, url, :remote => true, :method => method, :class => css
+  end
+
+  # Returns the css class used to identify watch links for a given +object+
+  def watcher_css(objects)
+    objects = Array.wrap(objects)
+    id = (objects.size == 1 ? objects.first.id : 'bulk')
+    "#{objects.first.class.to_s.underscore}-#{id}-watcher"
+  end
+
+  # Returns a comma separated list of users watching the given object
+  def watchers_list(object)
+    remove_allowed = User.current.allowed_to?("delete_#{object.class.name.underscore}_watchers".to_sym, object.project)
+    content = ''.html_safe
+    lis = object.watcher_users.collect do |user|
+      s = ''.html_safe
+      s << avatar(user, :size => "16").to_s
+      s << link_to_user(user, :class => 'user')
+      if remove_allowed
+        url = {:controller => 'watchers',
+               :action => 'destroy',
+               :object_type => object.class.to_s.underscore,
+               :object_id => object.id,
+               :user_id => user}
+        s << ' '
+        s << link_to(image_tag('delete.png'), url,
+                     :remote => true, :method => 'delete', :class => "delete")
+      end
+      content << content_tag('li', s, :class => "user-#{user.id}")
+    end
+    content.present? ? content_tag('ul', content, :class => 'watchers') : content
+  end
+
+  def watchers_checkboxes(object, users, checked=nil)
+    users.map do |user|
+      c = checked.nil? ? object.watched_by?(user) : checked
+      tag = check_box_tag 'issue[watcher_user_ids][]', user.id, c, :id => nil
+      content_tag 'label', "#{tag} #{h(user)}".html_safe,
+                  :id => "issue_watcher_user_ids_#{user.id}",
+                  :class => "floating"
+    end.join.html_safe
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/58/58db9baf0f6d2aa4b263068238c559860f800493.svn-base
--- a/.svn/pristine/58/58db9baf0f6d2aa4b263068238c559860f800493.svn-base
+++ /dev/null
@@ -1,59 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::ThemesTest < ActiveSupport::TestCase
-
-  def test_themes
-    themes = Redmine::Themes.themes
-    assert_kind_of Array, themes
-    assert_kind_of Redmine::Themes::Theme, themes.first
-  end
-
-  def test_rescan
-    Redmine::Themes.themes.pop
-
-    assert_difference 'Redmine::Themes.themes.size' do
-      Redmine::Themes.rescan
-    end
-  end
-
-  def test_theme_loaded
-    theme = Redmine::Themes.themes.last
-
-    assert_equal theme, Redmine::Themes.theme(theme.id)
-  end
-
-  def test_theme_loaded_without_rescan
-    theme = Redmine::Themes.themes.last
-
-    assert_equal theme, Redmine::Themes.theme(theme.id, :rescan => false)
-  end
-
-  def test_theme_not_loaded
-    theme = Redmine::Themes.themes.pop
-
-    assert_equal theme, Redmine::Themes.theme(theme.id)
-  end
-
-  def test_theme_not_loaded_without_rescan
-    theme = Redmine::Themes.themes.pop
-
-    assert_nil Redmine::Themes.theme(theme.id, :rescan => false)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/59/590eaa24ab9f834ac16f2b590030d2f8381b4376.svn-base
--- a/.svn/pristine/59/590eaa24ab9f834ac16f2b590030d2f8381b4376.svn-base
+++ /dev/null
@@ -1,111 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class RoleTest < ActiveSupport::TestCase
-  fixtures :roles, :workflows
-
-  def test_copy_workflows
-    source = Role.find(1)
-    assert_equal 90, source.workflows.size
-
-    target = Role.new(:name => 'Target')
-    assert target.save
-    target.workflows.copy(source)
-    target.reload
-    assert_equal 90, target.workflows.size
-  end
-
-  def test_add_permission
-    role = Role.find(1)
-    size = role.permissions.size
-    role.add_permission!("apermission", "anotherpermission")
-    role.reload
-    assert role.permissions.include?(:anotherpermission)
-    assert_equal size + 2, role.permissions.size
-  end
-
-  def test_remove_permission
-    role = Role.find(1)
-    size = role.permissions.size
-    perm = role.permissions[0..1]
-    role.remove_permission!(*perm)
-    role.reload
-    assert ! role.permissions.include?(perm[0])
-    assert_equal size - 2, role.permissions.size
-  end
-
-  def test_name
-    I18n.locale = 'fr'
-    assert_equal 'Manager', Role.find(1).name
-    assert_equal 'Anonyme', Role.anonymous.name
-    assert_equal 'Non membre', Role.non_member.name
-  end
-
-  context "#anonymous" do
-    should "return the anonymous role" do
-      role = Role.anonymous
-      assert role.builtin?
-      assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
-    end
-
-    context "with a missing anonymous role" do
-      setup do
-        Role.delete_all("builtin = #{Role::BUILTIN_ANONYMOUS}")
-      end
-
-      should "create a new anonymous role" do
-        assert_difference('Role.count') do
-          Role.anonymous
-        end
-      end
-
-      should "return the anonymous role" do
-        role = Role.anonymous
-        assert role.builtin?
-        assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
-      end
-    end
-  end
-
-  context "#non_member" do
-    should "return the non-member role" do
-      role = Role.non_member
-      assert role.builtin?
-      assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
-    end
-
-    context "with a missing non-member role" do
-      setup do
-        Role.delete_all("builtin = #{Role::BUILTIN_NON_MEMBER}")
-      end
-
-      should "create a new non-member role" do
-        assert_difference('Role.count') do
-          Role.non_member
-        end
-      end
-
-      should "return the non-member role" do
-        role = Role.non_member
-        assert role.builtin?
-        assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/59/594645e33ca990837dd2f730162a5f369b707902.svn-base
--- a/.svn/pristine/59/594645e33ca990837dd2f730162a5f369b707902.svn-base
+++ /dev/null
@@ -1,449 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'tree' # gem install rubytree
-
-# Monkey patch the TreeNode to add on a few more methods :nodoc:
-module TreeNodePatch
-  def self.included(base)
-    base.class_eval do
-      attr_reader :last_items_count
-
-      alias :old_initilize :initialize
-      def initialize(name, content = nil)
-        old_initilize(name, content)
-      	@childrenHash ||= {}
-        @last_items_count = 0
-        extend(InstanceMethods)
-      end
-    end
-  end
-
-  module InstanceMethods
-    # Adds the specified child node to the receiver node.  The child node's
-    # parent is set to be the receiver.  The child is added as the first child in
-    # the current list of children for the receiver node.
-    def prepend(child)
-      raise "Child already added" if @childrenHash.has_key?(child.name)
-
-      @childrenHash[child.name]  = child
-      @children = [child] + @children
-      child.parent = self
-      return child
-
-    end
-
-    # Adds the specified child node to the receiver node.  The child node's
-    # parent is set to be the receiver.  The child is added at the position
-    # into the current list of children for the receiver node.
-    def add_at(child, position)
-      raise "Child already added" if @childrenHash.has_key?(child.name)
-
-      @childrenHash[child.name]  = child
-      @children = @children.insert(position, child)
-      child.parent = self
-      return child
-
-    end
-
-    def add_last(child)
-      raise "Child already added" if @childrenHash.has_key?(child.name)
-
-      @childrenHash[child.name]  = child
-      @children <<  child
-      @last_items_count += 1
-      child.parent = self
-      return child
-
-    end
-
-    # Adds the specified child node to the receiver node.  The child node's
-    # parent is set to be the receiver.  The child is added as the last child in
-    # the current list of children for the receiver node.
-    def add(child)
-      raise "Child already added" if @childrenHash.has_key?(child.name)
-
-      @childrenHash[child.name]  = child
-      position = @children.size - @last_items_count
-      @children.insert(position, child)
-      child.parent = self
-      return child
-
-    end
-
-    # Wrapp remove! making sure to decrement the last_items counter if
-    # the removed child was a last item
-    def remove!(child)
-      @last_items_count -= +1 if child && child.last
-      super
-    end
-
-
-    # Will return the position (zero-based) of the current child in
-    # it's parent
-    def position
-      self.parent.children.index(self)
-    end
-  end
-end
-Tree::TreeNode.send(:include, TreeNodePatch)
-
-module Redmine
-  module MenuManager
-    class MenuError < StandardError #:nodoc:
-    end
-
-    module MenuController
-      def self.included(base)
-        base.extend(ClassMethods)
-      end
-
-      module ClassMethods
-        @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}}
-        mattr_accessor :menu_items
-
-        # Set the menu item name for a controller or specific actions
-        # Examples:
-        #   * menu_item :tickets # => sets the menu name to :tickets for the whole controller
-        #   * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only
-        #   * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only
-        #
-        # The default menu item name for a controller is controller_name by default
-        # Eg. the default menu item name for ProjectsController is :projects
-        def menu_item(id, options = {})
-          if actions = options[:only]
-            actions = [] << actions unless actions.is_a?(Array)
-            actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id}
-          else
-            menu_items[controller_name.to_sym][:default] = id
-          end
-        end
-      end
-
-      def menu_items
-        self.class.menu_items
-      end
-
-      # Returns the menu item name according to the current action
-      def current_menu_item
-        @current_menu_item ||= menu_items[controller_name.to_sym][:actions][action_name.to_sym] ||
-                                 menu_items[controller_name.to_sym][:default]
-      end
-
-      # Redirects user to the menu item of the given project
-      # Returns false if user is not authorized
-      def redirect_to_project_menu_item(project, name)
-        item = Redmine::MenuManager.items(:project_menu).detect {|i| i.name.to_s == name.to_s}
-        if item && User.current.allowed_to?(item.url, project) && (item.condition.nil? || item.condition.call(project))
-          redirect_to({item.param => project}.merge(item.url))
-          return true
-        end
-        false
-      end
-    end
-
-    module MenuHelper
-      # Returns the current menu item name
-      def current_menu_item
-        controller.current_menu_item
-      end
-
-      # Renders the application main menu
-      def render_main_menu(project)
-        render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
-      end
-
-      def display_main_menu?(project)
-        menu_name = project && !project.new_record? ? :project_menu : :application_menu
-        Redmine::MenuManager.items(menu_name).size > 1 # 1 element is the root
-      end
-
-      def render_menu(menu, project=nil)
-        links = []
-        menu_items_for(menu, project) do |node|
-          links << render_menu_node(node, project)
-        end
-        links.empty? ? nil : content_tag('ul', links.join("\n").html_safe)
-      end
-
-      def render_menu_node(node, project=nil)
-        if node.hasChildren? || !node.child_menus.nil?
-          return render_menu_node_with_children(node, project)
-        else
-          caption, url, selected = extract_node_details(node, project)
-          return content_tag('li',
-                               render_single_menu_node(node, caption, url, selected))
-        end
-      end
-
-      def render_menu_node_with_children(node, project=nil)
-        caption, url, selected = extract_node_details(node, project)
-
-        html = [].tap do |html|
-          html << '<li>'
-          # Parent
-          html << render_single_menu_node(node, caption, url, selected)
-
-          # Standard children
-          standard_children_list = "".tap do |child_html|
-            node.children.each do |child|
-              child_html << render_menu_node(child, project)
-            end
-          end
-
-          html << content_tag(:ul, standard_children_list, :class => 'menu-children') unless standard_children_list.empty?
-
-          # Unattached children
-          unattached_children_list = render_unattached_children_menu(node, project)
-          html << content_tag(:ul, unattached_children_list, :class => 'menu-children unattached') unless unattached_children_list.blank?
-
-          html << '</li>'
-        end
-        return html.join("\n")
-      end
-
-      # Returns a list of unattached children menu items
-      def render_unattached_children_menu(node, project)
-        return nil unless node.child_menus
-
-        "".tap do |child_html|
-          unattached_children = node.child_menus.call(project)
-          # Tree nodes support #each so we need to do object detection
-          if unattached_children.is_a? Array
-            unattached_children.each do |child|
-              child_html << content_tag(:li, render_unattached_menu_item(child, project))
-            end
-          else
-            raise MenuError, ":child_menus must be an array of MenuItems"
-          end
-        end
-      end
-
-      def render_single_menu_node(item, caption, url, selected)
-        link_to(h(caption), url, item.html_options(:selected => selected))
-      end
-
-      def render_unattached_menu_item(menu_item, project)
-        raise MenuError, ":child_menus must be an array of MenuItems" unless menu_item.is_a? MenuItem
-
-        if User.current.allowed_to?(menu_item.url, project)
-          link_to(h(menu_item.caption),
-                  menu_item.url,
-                  menu_item.html_options)
-        end
-      end
-
-      def menu_items_for(menu, project=nil)
-        items = []
-        Redmine::MenuManager.items(menu).root.children.each do |node|
-          if allowed_node?(node, User.current, project)
-            if block_given?
-              yield node
-            else
-              items << node  # TODO: not used?
-            end
-          end
-        end
-        return block_given? ? nil : items
-      end
-
-      def extract_node_details(node, project=nil)
-        item = node
-        url = case item.url
-        when Hash
-          project.nil? ? item.url : {item.param => project}.merge(item.url)
-        when Symbol
-          send(item.url)
-        else
-          item.url
-        end
-        caption = item.caption(project)
-        return [caption, url, (current_menu_item == item.name)]
-      end
-
-      # Checks if a user is allowed to access the menu item by:
-      #
-      # * Checking the conditions of the item
-      # * Checking the url target (project only)
-      def allowed_node?(node, user, project)
-        if node.condition && !node.condition.call(project)
-          # Condition that doesn't pass
-          return false
-        end
-
-        if project
-          return user && user.allowed_to?(node.url, project)
-        else
-          # outside a project, all menu items allowed
-          return true
-        end
-      end
-    end
-
-    class << self
-      def map(menu_name)
-        @items ||= {}
-        mapper = Mapper.new(menu_name.to_sym, @items)
-        if block_given?
-          yield mapper
-        else
-          mapper
-        end
-      end
-
-      def items(menu_name)
-        @items[menu_name.to_sym] || Tree::TreeNode.new(:root, {})
-      end
-    end
-
-    class Mapper
-      def initialize(menu, items)
-        items[menu] ||= Tree::TreeNode.new(:root, {})
-        @menu = menu
-        @menu_items = items[menu]
-      end
-
-      @@last_items_count = Hash.new {|h,k| h[k] = 0}
-
-      # Adds an item at the end of the menu. Available options:
-      # * param: the parameter name that is used for the project id (default is :id)
-      # * if: a Proc that is called before rendering the item, the item is displayed only if it returns true
-      # * caption that can be:
-      #   * a localized string Symbol
-      #   * a String
-      #   * a Proc that can take the project as argument
-      # * before, after: specify where the menu item should be inserted (eg. :after => :activity)
-      # * parent: menu item will be added as a child of another named menu (eg. :parent => :issues)
-      # * children: a Proc that is called before rendering the item. The Proc should return an array of MenuItems, which will be added as children to this item.
-      #   eg. :children => Proc.new {|project| [Redmine::MenuManager::MenuItem.new(...)] }
-      # * last: menu item will stay at the end (eg. :last => true)
-      # * html_options: a hash of html options that are passed to link_to
-      def push(name, url, options={})
-        options = options.dup
-
-        if options[:parent]
-          subtree = self.find(options[:parent])
-          if subtree
-            target_root = subtree
-          else
-            target_root = @menu_items.root
-          end
-
-        else
-          target_root = @menu_items.root
-        end
-
-        # menu item position
-        if first = options.delete(:first)
-          target_root.prepend(MenuItem.new(name, url, options))
-        elsif before = options.delete(:before)
-
-          if exists?(before)
-            target_root.add_at(MenuItem.new(name, url, options), position_of(before))
-          else
-            target_root.add(MenuItem.new(name, url, options))
-          end
-
-        elsif after = options.delete(:after)
-
-          if exists?(after)
-            target_root.add_at(MenuItem.new(name, url, options), position_of(after) + 1)
-          else
-            target_root.add(MenuItem.new(name, url, options))
-          end
-
-        elsif options[:last] # don't delete, needs to be stored
-          target_root.add_last(MenuItem.new(name, url, options))
-        else
-          target_root.add(MenuItem.new(name, url, options))
-        end
-      end
-
-      # Removes a menu item
-      def delete(name)
-        if found = self.find(name)
-          @menu_items.remove!(found)
-        end
-      end
-
-      # Checks if a menu item exists
-      def exists?(name)
-        @menu_items.any? {|node| node.name == name}
-      end
-
-      def find(name)
-        @menu_items.find {|node| node.name == name}
-      end
-
-      def position_of(name)
-        @menu_items.each do |node|
-          if node.name == name
-            return node.position
-          end
-        end
-      end
-    end
-
-    class MenuItem < Tree::TreeNode
-      include Redmine::I18n
-      attr_reader :name, :url, :param, :condition, :parent, :child_menus, :last
-
-      def initialize(name, url, options)
-        raise ArgumentError, "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call)
-        raise ArgumentError, "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash)
-        raise ArgumentError, "Cannot set the :parent to be the same as this item" if options[:parent] == name.to_sym
-        raise ArgumentError, "Invalid option :children for menu item '#{name}'" if options[:children] && !options[:children].respond_to?(:call)
-        @name = name
-        @url = url
-        @condition = options[:if]
-        @param = options[:param] || :id
-        @caption = options[:caption]
-        @html_options = options[:html] || {}
-        # Adds a unique class to each menu item based on its name
-        @html_options[:class] = [@html_options[:class], @name.to_s.dasherize].compact.join(' ')
-        @parent = options[:parent]
-        @child_menus = options[:children]
-        @last = options[:last] || false
-        super @name.to_sym
-      end
-
-      def caption(project=nil)
-        if @caption.is_a?(Proc)
-          c = @caption.call(project).to_s
-          c = @name.to_s.humanize if c.blank?
-          c
-        else
-          if @caption.nil?
-            l_or_humanize(name, :prefix => 'label_')
-          else
-            @caption.is_a?(Symbol) ? l(@caption) : @caption
-          end
-        end
-      end
-
-      def html_options(options={})
-        if options[:selected]
-          o = @html_options.dup
-          o[:class] += ' selected'
-          o
-        else
-          @html_options
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/59/595569d84d22df6ad4296b4d377f37df66d05fc6.svn-base
--- a/.svn/pristine/59/595569d84d22df6ad4296b4d377f37df66d05fc6.svn-base
+++ /dev/null
@@ -1,298 +0,0 @@
-# -*- coding: utf-8 -*-
-require File.expand_path('../../test_helper', __FILE__)
-
-class TimeEntryReportsControllerTest < ActionController::TestCase
-  fixtures :projects, :enabled_modules, :roles, :members, :member_roles,
-           :issues, :time_entries, :users, :trackers, :enumerations,
-           :issue_statuses, :custom_fields, :custom_values
-
-  include Redmine::I18n
-
-  def setup
-    Setting.default_language = "en"
-  end
-
-  def test_report_at_project_level
-    get :report, :project_id => 'ecookbook'
-    assert_response :success
-    assert_template 'report'
-    assert_tag :form,
-      :attributes => {:action => "/projects/ecookbook/time_entries/report", :id => 'query_form'}
-  end
-
-  def test_report_all_projects
-    get :report
-    assert_response :success
-    assert_template 'report'
-    assert_tag :form,
-      :attributes => {:action => "/time_entries/report", :id => 'query_form'}
-  end
-
-  def test_report_all_projects_denied
-    r = Role.anonymous
-    r.permissions.delete(:view_time_entries)
-    r.permissions_will_change!
-    r.save
-    get :report
-    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Ftime_entries%2Freport'
-  end
-
-  def test_report_all_projects_one_criteria
-    get :report, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
-    assert_response :success
-    assert_template 'report'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "8.65", "%.2f" % assigns(:total_hours)
-  end
-
-  def test_report_all_time
-    get :report, :project_id => 1, :criterias => ['project', 'issue']
-    assert_response :success
-    assert_template 'report'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "162.90", "%.2f" % assigns(:total_hours)
-  end
-
-  def test_report_all_time_by_day
-    get :report, :project_id => 1, :criterias => ['project', 'issue'], :columns => 'day'
-    assert_response :success
-    assert_template 'report'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "162.90", "%.2f" % assigns(:total_hours)
-    assert_tag :tag => 'th', :content => '2007-03-12'
-  end
-
-  def test_report_one_criteria
-    get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
-    assert_response :success
-    assert_template 'report'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "8.65", "%.2f" % assigns(:total_hours)
-  end
-
-  def test_report_two_criterias
-    get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
-    assert_response :success
-    assert_template 'report'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "162.90", "%.2f" % assigns(:total_hours)
-  end
-
-  def test_report_one_day
-    get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criterias => ["member", "activity"]
-    assert_response :success
-    assert_template 'report'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "4.25", "%.2f" % assigns(:total_hours)
-  end
-
-  def test_report_at_issue_level
-    get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
-    assert_response :success
-    assert_template 'report'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "154.25", "%.2f" % assigns(:total_hours)
-    assert_tag :form,
-      :attributes => {:action => "/projects/ecookbook/issues/1/time_entries/report", :id => 'query_form'}
-  end
-
-  def test_report_custom_field_criteria
-    get :report, :project_id => 1, :criterias => ['project', 'cf_1', 'cf_7']
-    assert_response :success
-    assert_template 'report'
-    assert_not_nil assigns(:total_hours)
-    assert_not_nil assigns(:criterias)
-    assert_equal 3, assigns(:criterias).size
-    assert_equal "162.90", "%.2f" % assigns(:total_hours)
-    # Custom field column
-    assert_tag :tag => 'th', :content => 'Database'
-    # Custom field row
-    assert_tag :tag => 'td', :content => 'MySQL',
-                             :sibling => { :tag => 'td', :attributes => { :class => 'hours' },
-                                                         :child => { :tag => 'span', :attributes => { :class => 'hours hours-int' },
-                                                                                     :content => '1' }}
-    # Second custom field column
-    assert_tag :tag => 'th', :content => 'Billable'
-  end
-
-  def test_report_one_criteria_no_result
-    get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criterias => ['project']
-    assert_response :success
-    assert_template 'report'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "0.00", "%.2f" % assigns(:total_hours)
-  end
-
-  def test_report_all_projects_csv_export
-    get :report, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30",
-        :criterias => ["project", "member", "activity"], :format => "csv"
-    assert_response :success
-    assert_equal 'text/csv', @response.content_type
-    lines = @response.body.chomp.split("\n")
-    # Headers
-    assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total',
-                 lines.first
-    # Total row
-    assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
-  end
-
-  def test_report_csv_export
-    get :report, :project_id => 1, :columns => 'month',
-        :from => "2007-01-01", :to => "2007-06-30",
-        :criterias => ["project", "member", "activity"], :format => "csv"
-    assert_response :success
-    assert_equal 'text/csv', @response.content_type
-    lines = @response.body.chomp.split("\n")
-    # Headers
-    assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total',
-                 lines.first
-    # Total row
-    assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
-  end
-
-  def test_csv_big_5
-    Setting.default_language = "zh-TW"
-    str_utf8  = "\xe4\xb8\x80\xe6\x9c\x88"
-    str_big5  = "\xa4@\xa4\xeb"
-    if str_utf8.respond_to?(:force_encoding)
-      str_utf8.force_encoding('UTF-8')
-      str_big5.force_encoding('Big5')
-    end
-    user = User.find_by_id(3)
-    user.firstname = str_utf8
-    user.lastname  = "test-lastname"
-    assert user.save
-    comments = "test_csv_big_5"
-    te1 = TimeEntry.create(:spent_on => '2011-11-11',
-                           :hours    => 7.3,
-                           :project  => Project.find(1),
-                           :user     => user,
-                           :activity => TimeEntryActivity.find_by_name('Design'),
-                           :comments => comments)
-
-    te2 = TimeEntry.find_by_comments(comments)
-    assert_not_nil te2
-    assert_equal 7.3, te2.hours
-    assert_equal 3, te2.user_id
-
-    get :report, :project_id => 1, :columns => 'day',
-        :from => "2011-11-11", :to => "2011-11-11",
-        :criterias => ["member"], :format => "csv"
-    assert_response :success
-    assert_equal 'text/csv', @response.content_type
-    lines = @response.body.chomp.split("\n")    
-    # Headers
-    s1 = "\xa6\xa8\xad\xfb,2011-11-11,\xc1`\xadp"
-    s2 = "\xc1`\xadp"
-    if s1.respond_to?(:force_encoding)
-      s1.force_encoding('Big5')
-      s2.force_encoding('Big5')
-    end
-    assert_equal s1, lines.first
-    # Total row
-    assert_equal "#{str_big5} #{user.lastname},7.30,7.30", lines[1]
-    assert_equal "#{s2},7.30,7.30", lines[2]
-
-    str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
-    if str_tw.respond_to?(:force_encoding)
-      str_tw.force_encoding('UTF-8')
-    end
-    assert_equal str_tw, l(:general_lang_name)
-    assert_equal 'Big5', l(:general_csv_encoding)
-    assert_equal ',', l(:general_csv_separator)
-    assert_equal '.', l(:general_csv_decimal_separator)
-  end
-
-  def test_csv_cannot_convert_should_be_replaced_big_5
-    Setting.default_language = "zh-TW"
-    str_utf8  = "\xe4\xbb\xa5\xe5\x86\x85"
-    if str_utf8.respond_to?(:force_encoding)
-      str_utf8.force_encoding('UTF-8')
-    end
-    user = User.find_by_id(3)
-    user.firstname = str_utf8
-    user.lastname  = "test-lastname"
-    assert user.save
-    comments = "test_replaced"
-    te1 = TimeEntry.create(:spent_on => '2011-11-11',
-                           :hours    => 7.3,
-                           :project  => Project.find(1),
-                           :user     => user,
-                           :activity => TimeEntryActivity.find_by_name('Design'),
-                           :comments => comments)
-
-    te2 = TimeEntry.find_by_comments(comments)
-    assert_not_nil te2
-    assert_equal 7.3, te2.hours
-    assert_equal 3, te2.user_id
-
-    get :report, :project_id => 1, :columns => 'day',
-        :from => "2011-11-11", :to => "2011-11-11",
-        :criterias => ["member"], :format => "csv"
-    assert_response :success
-    assert_equal 'text/csv', @response.content_type
-    lines = @response.body.chomp.split("\n")    
-    # Headers
-    s1 = "\xa6\xa8\xad\xfb,2011-11-11,\xc1`\xadp"
-    if s1.respond_to?(:force_encoding)
-      s1.force_encoding('Big5')
-    end
-    assert_equal s1, lines.first
-    # Total row
-    s2 = ""
-    if s2.respond_to?(:force_encoding)
-      s2 = "\xa5H?"
-      s2.force_encoding('Big5')
-    elsif RUBY_PLATFORM == 'java'
-      s2 = "??"
-    else
-      s2 = "\xa5H???"
-    end
-    assert_equal "#{s2} #{user.lastname},7.30,7.30", lines[1]
-  end
-
-  def test_csv_fr
-    with_settings :default_language => "fr" do
-      str1  = "test_csv_fr"
-      user = User.find_by_id(3)
-      te1 = TimeEntry.create(:spent_on => '2011-11-11',
-                             :hours    => 7.3,
-                             :project  => Project.find(1),
-                             :user     => user,
-                             :activity => TimeEntryActivity.find_by_name('Design'),
-                             :comments => str1)
-
-      te2 = TimeEntry.find_by_comments(str1)
-      assert_not_nil te2
-      assert_equal 7.3, te2.hours
-      assert_equal 3, te2.user_id
-
-      get :report, :project_id => 1, :columns => 'day',
-          :from => "2011-11-11", :to => "2011-11-11",
-          :criterias => ["member"], :format => "csv"
-      assert_response :success
-      assert_equal 'text/csv', @response.content_type
-      lines = @response.body.chomp.split("\n")    
-      # Headers
-      s1 = "Membre;2011-11-11;Total"
-      s2 = "Total"
-      if s1.respond_to?(:force_encoding)
-        s1.force_encoding('ISO-8859-1')
-        s2.force_encoding('ISO-8859-1')
-      end
-      assert_equal s1, lines.first
-      # Total row
-      assert_equal "#{user.firstname} #{user.lastname};7,30;7,30", lines[1]
-      assert_equal "#{s2};7,30;7,30", lines[2]
-
-      str_fr = "Fran\xc3\xa7ais"
-      if str_fr.respond_to?(:force_encoding)
-        str_fr.force_encoding('UTF-8')
-      end
-      assert_equal str_fr, l(:general_lang_name)
-      assert_equal 'ISO-8859-1', l(:general_csv_encoding)
-      assert_equal ';', l(:general_csv_separator)
-      assert_equal ',', l(:general_csv_decimal_separator)
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/59/59560647b1b38d17ca5eda58f2c560506ef65f44.svn-base
--- /dev/null
+++ b/.svn/pristine/59/59560647b1b38d17ca5eda58f2c560506ef65f44.svn-base
@@ -0,0 +1,68 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssuePriority < Enumeration
+  has_many :issues, :foreign_key => 'priority_id'
+
+  after_destroy {|priority| priority.class.compute_position_names}
+  after_save {|priority| priority.class.compute_position_names if priority.position_changed? && priority.position}
+
+  OptionName = :enumeration_issue_priorities
+
+  def option_name
+    OptionName
+  end
+
+  def objects_count
+    issues.count
+  end
+
+  def transfer_relations(to)
+    issues.update_all("priority_id = #{to.id}")
+  end
+
+  def css_classes
+    "priority-#{id} priority-#{position_name}"
+  end
+
+  # Clears position_name for all priorities
+  # Called from migration 20121026003537_populate_enumerations_position_name
+  def self.clear_position_names
+    update_all :position_name => nil
+  end
+
+  # Updates position_name for active priorities
+  # Called from migration 20121026003537_populate_enumerations_position_name
+  def self.compute_position_names
+    priorities = where(:active => true).all.sort_by(&:position)
+    if priorities.any?
+      default = priorities.detect(&:is_default?) || priorities[(priorities.size - 1) / 2]
+      priorities.each_with_index do |priority, index|
+        name = case
+          when priority.position == default.position
+            "default"
+          when priority.position < default.position
+            index == 0 ? "lowest" : "low#{index+1}"
+          else
+            index == (priorities.size - 1) ? "highest" : "high#{priorities.size - index}"
+          end
+
+        update_all({:position_name => name}, :id => priority.id)
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/59/5957c73ec3e45b1dba5f2bd95614bcd541de4b15.svn-base
--- /dev/null
+++ b/.svn/pristine/59/5957c73ec3e45b1dba5f2bd95614bcd541de4b15.svn-base
@@ -0,0 +1,128 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class WorkflowsController < ApplicationController
+  layout 'admin'
+
+  before_filter :require_admin, :find_roles, :find_trackers
+
+  def index
+    @workflow_counts = WorkflowTransition.count_by_tracker_and_role
+  end
+
+  def edit
+    @role = Role.find_by_id(params[:role_id]) if params[:role_id]
+    @tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
+
+    if request.post?
+      WorkflowTransition.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
+      (params[:issue_status] || []).each { |status_id, transitions|
+        transitions.each { |new_status_id, options|
+          author = options.is_a?(Array) && options.include?('author') && !options.include?('always')
+          assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always')
+          WorkflowTransition.create(:role_id => @role.id, :tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee)
+        }
+      }
+      if @role.save
+        redirect_to workflows_edit_path(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
+        return
+      end
+    end
+
+    @used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
+    if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
+      @statuses = @tracker.issue_statuses
+    end
+    @statuses ||= IssueStatus.sorted.all
+
+    if @tracker && @role && @statuses.any?
+      workflows = WorkflowTransition.where(:role_id => @role.id, :tracker_id => @tracker.id).all
+      @workflows = {}
+      @workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
+      @workflows['author'] = workflows.select {|w| w.author}
+      @workflows['assignee'] = workflows.select {|w| w.assignee}
+    end
+  end
+
+  def permissions
+    @role = Role.find_by_id(params[:role_id]) if params[:role_id]
+    @tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
+
+    if request.post? && @role && @tracker
+      WorkflowPermission.replace_permissions(@tracker, @role, params[:permissions] || {})
+      redirect_to workflows_permissions_path(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
+      return
+    end
+
+    @used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
+    if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
+      @statuses = @tracker.issue_statuses
+    end
+    @statuses ||= IssueStatus.sorted.all
+
+    if @role && @tracker
+      @fields = (Tracker::CORE_FIELDS_ALL - @tracker.disabled_core_fields).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]}
+      @custom_fields = @tracker.custom_fields
+
+      @permissions = WorkflowPermission.where(:tracker_id => @tracker.id, :role_id => @role.id).all.inject({}) do |h, w|
+        h[w.old_status_id] ||= {}
+        h[w.old_status_id][w.field_name] = w.rule
+        h
+      end
+      @statuses.each {|status| @permissions[status.id] ||= {}}
+    end
+  end
+
+  def copy
+
+    if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any'
+      @source_tracker = nil
+    else
+      @source_tracker = Tracker.find_by_id(params[:source_tracker_id].to_i)
+    end
+    if params[:source_role_id].blank? || params[:source_role_id] == 'any'
+      @source_role = nil
+    else
+      @source_role = Role.find_by_id(params[:source_role_id].to_i)
+    end
+
+    @target_trackers = params[:target_tracker_ids].blank? ? nil : Tracker.find_all_by_id(params[:target_tracker_ids])
+    @target_roles = params[:target_role_ids].blank? ? nil : Role.find_all_by_id(params[:target_role_ids])
+
+    if request.post?
+      if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?)
+        flash.now[:error] = l(:error_workflow_copy_source)
+      elsif @target_trackers.blank? || @target_roles.blank?
+        flash.now[:error] = l(:error_workflow_copy_target)
+      else
+        WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles)
+        flash[:notice] = l(:notice_successful_update)
+        redirect_to workflows_copy_path(:source_tracker_id => @source_tracker, :source_role_id => @source_role)
+      end
+    end
+  end
+
+  private
+
+  def find_roles
+    @roles = Role.sorted.all
+  end
+
+  def find_trackers
+    @trackers = Tracker.sorted.all
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/59/596c198f119f4338d149538588dba74545c206cb.svn-base
Binary file .svn/pristine/59/596c198f119f4338d149538588dba74545c206cb.svn-base has changed
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/59/59aca64abbe8279f6a8e6795b265ac2c66a49a15.svn-base
--- a/.svn/pristine/59/59aca64abbe8279f6a8e6795b265ac2c66a49a15.svn-base
+++ /dev/null
@@ -1,1005 +0,0 @@
-th:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y-%m-%d"
-      short: "%b %d"
-      long: "%B %d, %Y"
-      
-    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
-    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
-    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%a, %d %b %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "am"
-    pm: "pm"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "half a minute"
-      less_than_x_seconds:
-        one:   "less than 1 second"
-        other: "less than %{count} seconds"
-      x_seconds:
-        one:   "1 second"
-        other: "%{count} seconds"
-      less_than_x_minutes:
-        one:   "less than a minute"
-        other: "less than %{count} minutes"
-      x_minutes:
-        one:   "1 minute"
-        other: "%{count} minutes"
-      about_x_hours:
-        one:   "about 1 hour"
-        other: "about %{count} hours"
-      x_days:
-        one:   "1 day"
-        other: "%{count} days"
-      about_x_months:
-        one:   "about 1 month"
-        other: "about %{count} months"
-      x_months:
-        one:   "1 month"
-        other: "%{count} months"
-      about_x_years:
-        one:   "about 1 year"
-        other: "about %{count} years"
-      over_x_years:
-        one:   "over 1 year"
-        other: "over %{count} years"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-    human: 
-      format: 
-        precision: 1
-        delimiter: ""
-      storage_units: 
-        format: "%n %u"
-        units: 
-          kb: KB
-          tb: TB
-          gb: GB
-          byte: 
-            one: Byte
-            other: Bytes
-          mb: MB
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "and"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "à¹„à¸¡à¹ˆà¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¸£à¸²à¸¢à¸à¸²à¸£"
-        exclusion: "à¸–à¸¹à¸à¸ªà¸‡à¸§à¸™à¹„à¸§à¹‰"
-        invalid: "à¹„à¸¡à¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡"
-        confirmation: "à¸žà¸´à¸¡à¸žà¹Œà¹„à¸¡à¹ˆà¹€à¸«à¸¡à¸·à¸­à¸™à¹€à¸”à¸´à¸¡"
-        accepted: "à¸•à¹‰à¸­à¸‡à¸¢à¸­à¸¡à¸£à¸±à¸š"
-        empty: "à¸•à¹‰à¸­à¸‡à¹€à¸•à¸´à¸¡"
-        blank: "à¸•à¹‰à¸­à¸‡à¹€à¸•à¸´à¸¡"
-        too_long: "à¸¢à¸²à¸§à¹€à¸à¸´à¸™à¹„à¸›"
-        too_short: "à¸ªà¸±à¹‰à¸™à¹€à¸à¸´à¸™à¹„à¸›"
-        wrong_length: "à¸„à¸§à¸²à¸¡à¸¢à¸²à¸§à¹„à¸¡à¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡"
-        taken: "à¸–à¸¹à¸à¹ƒà¸Šà¹‰à¹„à¸›à¹à¸¥à¹‰à¸§"
-        not_a_number: "à¹„à¸¡à¹ˆà¹ƒà¸Šà¹ˆà¸•à¸±à¸§à¹€à¸¥à¸‚"
-        not_a_date: "à¹„à¸¡à¹ˆà¹ƒà¸Šà¹ˆà¸§à¸±à¸™à¸—à¸µà¹ˆ à¸—à¸µà¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡"
-        greater_than: "must be greater than %{count}"
-        greater_than_or_equal_to: "must be greater than or equal to %{count}"
-        equal_to: "must be equal to %{count}"
-        less_than: "must be less than %{count}"
-        less_than_or_equal_to: "must be less than or equal to %{count}"
-        odd: "must be odd"
-        even: "must be even"
-        greater_than_start_date: "à¸•à¹‰à¸­à¸‡à¸¡à¸²à¸à¸à¸§à¹ˆà¸²à¸§à¸±à¸™à¹€à¸£à¸´à¹ˆà¸¡"
-        not_same_project: "à¹„à¸¡à¹ˆà¹„à¸”à¹‰à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¹€à¸”à¸µà¸¢à¸§à¸à¸±à¸™"
-        circular_dependency: "à¸„à¸§à¸²à¸¡à¸ªà¸±à¸¡à¸žà¸±à¸™à¸˜à¹Œà¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡à¹€à¸›à¹‡à¸™à¸§à¸‡à¸à¸¥à¸¡"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: à¸à¸£à¸¸à¸“à¸²à¹€à¸¥à¸·à¸­à¸
-  
-  general_text_No: 'à¹„à¸¡à¹ˆ'
-  general_text_Yes: 'à¹ƒà¸Šà¹ˆ'
-  general_text_no: 'à¹„à¸¡à¹ˆ'
-  general_text_yes: 'à¹ƒà¸Šà¹ˆ'
-  general_lang_name: 'Thai (à¹„à¸—à¸¢)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: Windows-874
-  general_pdf_encoding: cp874
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: à¸šà¸±à¸à¸Šà¸µà¹„à¸”à¹‰à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹à¸¥à¹‰à¸§.
-  notice_account_invalid_creditentials: à¸Šà¸·à¹‰à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸«à¸£à¸·à¸­à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™à¹„à¸¡à¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡
-  notice_account_password_updated: à¸£à¸«à¸±à¸ªà¹„à¸”à¹‰à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹à¸¥à¹‰à¸§.
-  notice_account_wrong_password: à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™à¹„à¸¡à¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡
-  notice_account_register_done: à¸šà¸±à¸à¸Šà¸µà¸–à¸¹à¸à¸ªà¸£à¹‰à¸²à¸‡à¹à¸¥à¹‰à¸§. à¸à¸£à¸¸à¸“à¸²à¹€à¸Šà¹‡à¸„à¹€à¸¡à¸¥à¹Œ à¹à¸¥à¹‰à¸§à¸„à¸¥à¸´à¹Šà¸à¸—à¸µà¹ˆà¸¥à¸´à¸‡à¸„à¹Œà¹ƒà¸™à¸­à¸µà¹€à¸¡à¸¥à¹Œà¹€à¸žà¸·à¹ˆà¸­à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰à¸šà¸±à¸à¸Šà¸µ
-  notice_account_unknown_email: à¹„à¸¡à¹ˆà¸¡à¸µà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¸­à¸µà¹€à¸¡à¸¥à¹Œà¸™à¸µà¹‰.
-  notice_can_t_change_password: à¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¹ƒà¸Šà¹‰à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™à¸ˆà¸²à¸à¹à¸«à¸¥à¹ˆà¸‡à¸ à¸²à¸¢à¸™à¸­à¸. à¹„à¸¡à¹ˆà¸ªà¸²à¸¡à¸²à¸£à¸–à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™à¹„à¸”à¹‰.
-  notice_account_lost_email_sent: à¹€à¸£à¸²à¹„à¸”à¹‰à¸ªà¹ˆà¸‡à¸­à¸µà¹€à¸¡à¸¥à¹Œà¸žà¸£à¹‰à¸­à¸¡à¸§à¸´à¸˜à¸µà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸£à¸«à¸±à¸µà¸ªà¸œà¹ˆà¸²à¸™à¹ƒà¸«à¸¡à¹ˆà¹ƒà¸«à¹‰à¸„à¸¸à¸“à¹à¸¥à¹‰à¸§ à¸à¸£à¸¸à¸“à¸²à¹€à¸Šà¹‡à¸„à¹€à¸¡à¸¥à¹Œ.
-  notice_account_activated: à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¸„à¸¸à¸“à¹„à¸”à¹‰à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰à¹à¸¥à¹‰à¸§. à¸•à¸­à¸™à¸™à¸µà¹‰à¸„à¸¸à¸“à¸ªà¸²à¸¡à¸²à¸£à¸–à¹€à¸‚à¹‰à¸²à¸ªà¸¹à¹ˆà¸£à¸°à¸šà¸šà¹„à¸”à¹‰à¹à¸¥à¹‰à¸§.
-  notice_successful_create: à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
-  notice_successful_update: à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
-  notice_successful_delete: à¸¥à¸šà¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
-  notice_successful_connection: à¸•à¸´à¸”à¸•à¹ˆà¸­à¸ªà¸³à¹€à¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
-  notice_file_not_found: à¸«à¸™à¹‰à¸²à¸—à¸µà¹ˆà¸„à¸¸à¸“à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸”à¸¹à¹„à¸¡à¹ˆà¸¡à¸µà¸­à¸¢à¸¹à¹ˆà¸ˆà¸£à¸´à¸‡ à¸«à¸£à¸·à¸­à¸–à¸¹à¸à¸¥à¸šà¹„à¸›à¹à¸¥à¹‰à¸§.
-  notice_locking_conflict: à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹‚à¸”à¸¢à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸„à¸™à¸­à¸·à¹ˆà¸™.
-  notice_not_authorized: à¸„à¸¸à¸“à¹„à¸¡à¹ˆà¸¡à¸µà¸ªà¸´à¸—à¸˜à¸´à¹€à¸‚à¹‰à¸²à¸–à¸¶à¸‡à¸«à¸™à¹‰à¸²à¸™à¸µà¹‰.
-  notice_email_sent: "à¸­à¸µà¹€à¸¡à¸¥à¹Œà¹„à¸”à¹‰à¸–à¸¹à¸à¸ªà¹ˆà¸‡à¸–à¸¶à¸‡ %{value}"
-  notice_email_error: "à¹€à¸à¸´à¸”à¸„à¸§à¸²à¸¡à¸œà¸´à¸”à¸žà¸¥à¸²à¸”à¸‚à¸“à¸°à¸à¸³à¸ªà¹ˆà¸‡à¸­à¸µà¹€à¸¡à¸¥à¹Œ (%{value})"
-  notice_feeds_access_key_reseted: RSS access key à¸‚à¸­à¸‡à¸„à¸¸à¸“à¸–à¸¹à¸ reset à¹à¸¥à¹‰à¸§.
-  notice_failed_to_save_issues: "%{count} à¸›à¸±à¸à¸«à¸²à¸ˆà¸²à¸ %{total} à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸–à¸¹à¸à¹€à¸¥à¸·à¸­à¸à¹„à¸¡à¹ˆà¸ªà¸²à¸¡à¸²à¸£à¸–à¸ˆà¸±à¸”à¹€à¸à¹‡à¸š: %{ids}."
-  notice_no_issue_selected: "à¹„à¸¡à¹ˆà¸¡à¸µà¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸–à¸¹à¸à¹€à¸¥à¸·à¸­à¸! à¸à¸£à¸¸à¸“à¸²à¹€à¸¥à¸·à¸­à¸à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸„à¸¸à¸“à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚."
-  notice_account_pending: "à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¸„à¸¸à¸“à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§ à¸‚à¸“à¸°à¸™à¸µà¹‰à¸£à¸­à¸à¸²à¸£à¸­à¸™à¸¸à¸¡à¸±à¸•à¸´à¸ˆà¸²à¸à¸œà¸¹à¹‰à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£."
-  notice_default_data_loaded: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¹‚à¸«à¸¥à¸”à¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
-  
-  error_can_t_load_default_data: "à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¹‚à¸«à¸¥à¸”à¹„à¸¡à¹ˆà¸ªà¸³à¹€à¸£à¹‡à¸ˆ: %{value}"
-  error_scm_not_found: "à¹„à¸¡à¹ˆà¸žà¸šà¸£à¸¸à¹ˆà¸™à¸—à¸µà¹ˆà¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹ƒà¸™à¹à¸«à¸¥à¹ˆà¸‡à¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š."
-  error_scm_command_failed: "à¹€à¸à¸´à¸”à¸„à¸§à¸²à¸¡à¸œà¸´à¸”à¸žà¸¥à¸²à¸”à¹ƒà¸™à¸à¸²à¸£à¹€à¸‚à¹‰à¸²à¸–à¸¶à¸‡à¹à¸«à¸¥à¹ˆà¸‡à¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š: %{value}"
-  error_scm_annotate: "entry à¹„à¸¡à¹ˆà¸¡à¸µà¸­à¸¢à¸¹à¹ˆà¸ˆà¸£à¸´à¸‡ à¸«à¸£à¸·à¸­à¹„à¸¡à¹ˆà¸ªà¸²à¸¡à¸²à¸£à¸–à¹€à¸‚à¸µà¸¢à¸™à¸«à¸¡à¸²à¸¢à¹€à¸«à¸•à¸¸à¸›à¸£à¸°à¸à¸­à¸š."
-  error_issue_not_found_in_project: 'à¹„à¸¡à¹ˆà¸žà¸šà¸›à¸±à¸à¸«à¸²à¸™à¸µà¹‰ à¸«à¸£à¸·à¸­à¸›à¸±à¸à¸«à¸²à¹„à¸¡à¹ˆà¹„à¸”à¹‰à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸™à¸µà¹‰'
-  
-  mail_subject_lost_password: "à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™ %{value} à¸‚à¸­à¸‡à¸„à¸¸à¸“"
-  mail_body_lost_password: 'à¸„à¸¥à¸´à¹Šà¸à¸—à¸µà¹ˆà¸¥à¸´à¸‡à¸„à¹Œà¸•à¹ˆà¸­à¹„à¸›à¸™à¸µà¹‰à¹€à¸žà¸·à¹ˆà¸­à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™:'
-  mail_subject_register: "à¹€à¸›à¸´à¸”à¸šà¸±à¸à¸Šà¸µ %{value} à¸‚à¸­à¸‡à¸„à¸¸à¸“"
-  mail_body_register: 'à¸„à¸¥à¸´à¹Šà¸à¸—à¸µà¹ˆà¸¥à¸´à¸‡à¸„à¹Œà¸•à¹ˆà¸­à¹„à¸›à¸™à¸µà¹‰à¹€à¸žà¸·à¹ˆà¸­à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™:'
-  mail_body_account_information_external: "à¸„à¸¸à¸“à¸ªà¸²à¸¡à¸²à¸£à¸–à¹ƒà¸Šà¹‰à¸šà¸±à¸à¸Šà¸µ %{value} à¹€à¸žà¸·à¹ˆà¸­à¹€à¸‚à¹‰à¸²à¸ªà¸¹à¹ˆà¸£à¸°à¸šà¸š."
-  mail_body_account_information: à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¸„à¸¸à¸“
-  mail_subject_account_activation_request: "à¸à¸£à¸¸à¸“à¸²à¹€à¸›à¸´à¸”à¸šà¸±à¸à¸Šà¸µ %{value}"
-  mail_body_account_activation_request: "à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¹ƒà¸«à¸¡à¹ˆ (%{value}) à¹„à¸”à¹‰à¸¥à¸‡à¸—à¸°à¹€à¸šà¸µà¸¢à¸™. à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¹€à¸‚à¸²à¸à¸³à¸¥à¸±à¸‡à¸£à¸­à¸­à¸™à¸¸à¸¡à¸±à¸•à¸´:"
-  
-  gui_validation_error: 1 à¸‚à¹‰à¸­à¸œà¸´à¸”à¸žà¸¥à¸²à¸”
-  gui_validation_error_plural: "%{count} à¸‚à¹‰à¸­à¸œà¸´à¸”à¸žà¸¥à¸²à¸”"
-  
-  field_name: à¸Šà¸·à¹ˆà¸­
-  field_description: à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”
-  field_summary: à¸ªà¸£à¸¸à¸›à¸¢à¹ˆà¸­
-  field_is_required: à¸•à¹‰à¸­à¸‡à¹ƒà¸ªà¹ˆ
-  field_firstname: à¸Šà¸·à¹ˆà¸­
-  field_lastname: à¸™à¸²à¸¡à¸ªà¸à¸¸à¸¥
-  field_mail: à¸­à¸µà¹€à¸¡à¸¥à¹Œ
-  field_filename: à¹à¸Ÿà¹‰à¸¡
-  field_filesize: à¸‚à¸™à¸²à¸”
-  field_downloads: à¸”à¸²à¸§à¸™à¹Œà¹‚à¸«à¸¥à¸”
-  field_author: à¸œà¸¹à¹‰à¹à¸•à¹ˆà¸‡
-  field_created_on: à¸ªà¸£à¹‰à¸²à¸‡
-  field_updated_on: à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡
-  field_field_format: à¸£à¸¹à¸›à¹à¸šà¸š
-  field_is_for_all: à¸ªà¸³à¸«à¸£à¸±à¸šà¸—à¸¸à¸à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
-  field_possible_values: à¸„à¹ˆà¸²à¸—à¸µà¹ˆà¹€à¸›à¹‡à¸™à¹„à¸›à¹„à¸”à¹‰
-  field_regexp: Regular expression
-  field_min_length: à¸ªà¸±à¹‰à¸™à¸ªà¸¸à¸”
-  field_max_length: à¸¢à¸²à¸§à¸ªà¸¸à¸”
-  field_value: à¸„à¹ˆà¸²
-  field_category: à¸›à¸£à¸°à¹€à¸ à¸—
-  field_title: à¸Šà¸·à¹ˆà¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡
-  field_project: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
-  field_issue: à¸›à¸±à¸à¸«à¸²
-  field_status: à¸ªà¸–à¸²à¸™à¸°
-  field_notes: à¸šà¸±à¸™à¸—à¸¶à¸
-  field_is_closed: à¸›à¸±à¸à¸«à¸²à¸ˆà¸š
-  field_is_default: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
-  field_tracker: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡
-  field_subject: à¹€à¸£à¸·à¹ˆà¸­à¸‡
-  field_due_date: à¸§à¸±à¸™à¸„à¸£à¸šà¸à¸³à¸«à¸™à¸”
-  field_assigned_to: à¸¡à¸­à¸šà¸«à¸¡à¸²à¸¢à¹ƒà¸«à¹‰
-  field_priority: à¸„à¸§à¸²à¸¡à¸ªà¸³à¸„à¸±à¸
-  field_fixed_version: à¸£à¸¸à¹ˆà¸™
-  field_user: à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
-  field_role: à¸šà¸—à¸šà¸²à¸—
-  field_homepage: à¸«à¸™à¹‰à¸²à¹à¸£à¸
-  field_is_public: à¸ªà¸²à¸˜à¸²à¸£à¸“à¸°
-  field_parent: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢à¸‚à¸­à¸‡
-  field_is_in_roadmap: à¸›à¸±à¸à¸«à¸²à¹à¸ªà¸”à¸‡à¹ƒà¸™ à¹à¸œà¸™à¸‡à¸²à¸™
-  field_login: à¸Šà¸·à¹ˆà¸­à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸š
-  field_mail_notification: à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•à¸·à¸­à¸™à¸—à¸²à¸‡à¸­à¸µà¹€à¸¡à¸¥à¹Œ
-  field_admin: à¸œà¸¹à¹‰à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£
-  field_last_login_on: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸šà¸„à¸£à¸±à¹‰à¸‡à¸ªà¸¸à¸”à¸—à¹‰à¸²à¸¢
-  field_language: à¸ à¸²à¸©à¸²
-  field_effective_date: à¸§à¸±à¸™à¸—à¸µà¹ˆ
-  field_password: à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
-  field_new_password: à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™à¹ƒà¸«à¸¡à¹ˆ
-  field_password_confirmation: à¸¢à¸·à¸™à¸¢à¸±à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
-  field_version: à¸£à¸¸à¹ˆà¸™
-  field_type: à¸Šà¸™à¸´à¸”
-  field_host: à¹‚à¸®à¸ªà¸•à¹Œ
-  field_port: à¸žà¸­à¸£à¹Œà¸•
-  field_account: à¸šà¸±à¸à¸Šà¸µ
-  field_base_dn: Base DN
-  field_attr_login: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸š attribute
-  field_attr_firstname: à¸Šà¸·à¹ˆà¸­ attribute
-  field_attr_lastname: à¸™à¸²à¸¡à¸ªà¸à¸¸à¸¥ attribute
-  field_attr_mail: à¸­à¸µà¹€à¸¡à¸¥à¹Œ attribute
-  field_onthefly: à¸ªà¸£à¹‰à¸²à¸‡à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸—à¸±à¸™à¸—à¸µ
-  field_start_date: à¹€à¸£à¸´à¹ˆà¸¡
-  field_done_ratio: "% à¸ªà¸³à¹€à¸£à¹‡à¸ˆ"
-  field_auth_source: à¸§à¸´à¸˜à¸µà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™
-  field_hide_mail: à¸‹à¹ˆà¸­à¸™à¸­à¸µà¹€à¸¡à¸¥à¹Œà¸‚à¸­à¸‡à¸‰à¸±à¸™
-  field_comments: à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
-  field_url: URL
-  field_start_page: à¸«à¸™à¹‰à¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
-  field_subproject: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢
-  field_hours: à¸Šà¸±à¹ˆà¸§à¹‚à¸¡à¸‡
-  field_activity: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡
-  field_spent_on: à¸§à¸±à¸™à¸—à¸µà¹ˆ
-  field_identifier: à¸Šà¸·à¹ˆà¸­à¹€à¸‰à¸žà¸²à¸°
-  field_is_filter: à¹ƒà¸Šà¹‰à¹€à¸›à¹‡à¸™à¸•à¸±à¸§à¸à¸£à¸­à¸‡
-  field_issue_to: à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¸­à¸‡
-  field_delay: à¹€à¸¥à¸·à¹ˆà¸­à¸™
-  field_assignable: à¸›à¸±à¸à¸«à¸²à¸ªà¸²à¸¡à¸²à¸£à¸–à¸¡à¸­à¸šà¸«à¸¡à¸²à¸¢à¹ƒà¸«à¹‰à¸„à¸™à¸—à¸µà¹ˆà¸—à¸³à¸šà¸—à¸šà¸²à¸—à¸™à¸µà¹‰
-  field_redirect_existing_links: à¸¢à¹‰à¸²à¸¢à¸ˆà¸¸à¸”à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚à¸¢à¸‡à¸™à¸µà¹‰
-  field_estimated_hours: à¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¹‚à¸”à¸¢à¸›à¸£à¸°à¸¡à¸²à¸“
-  field_column_names: à¸ªà¸”à¸¡à¸ à¹Œ
-  field_time_zone: à¸¢à¹ˆà¸²à¸™à¹€à¸§à¸¥à¸²
-  field_searchable: à¸„à¹‰à¸™à¸«à¸²à¹„à¸”à¹‰
-  field_default_value: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
-  field_comments_sorting: à¹à¸ªà¸”à¸‡à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
-  
-  setting_app_title: à¸Šà¸·à¹ˆà¸­à¹‚à¸›à¸£à¹à¸à¸£à¸¡
-  setting_app_subtitle: à¸Šà¸·à¹ˆà¸­à¹‚à¸›à¸£à¹à¸à¸£à¸¡à¸£à¸­à¸‡
-  setting_welcome_text: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¸•à¹‰à¸­à¸™à¸£à¸±à¸š
-  setting_default_language: à¸ à¸²à¸©à¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
-  setting_login_required: à¸•à¹‰à¸­à¸‡à¸›à¹‰à¸­à¸™à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰-à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
-  setting_self_registration: à¸¥à¸‡à¸—à¸°à¹€à¸šà¸µà¸¢à¸™à¸”à¹‰à¸§à¸¢à¸•à¸™à¹€à¸­à¸‡
-  setting_attachment_max_size: à¸‚à¸™à¸²à¸”à¹à¸Ÿà¹‰à¸¡à¹à¸™à¸šà¸ªà¸¹à¸‡à¸ªà¸¸à¸”
-  setting_issues_export_limit: à¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸à¸›à¸±à¸à¸«à¸²à¸ªà¸¹à¸‡à¸ªà¸¸à¸”
-  setting_mail_from: à¸­à¸µà¹€à¸¡à¸¥à¹Œà¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¸ªà¹ˆà¸‡
-  setting_bcc_recipients: à¹„à¸¡à¹ˆà¸£à¸°à¸šà¸¸à¸Šà¸·à¹ˆà¸­à¸œà¸¹à¹‰à¸£à¸±à¸š (bcc)
-  setting_host_name: à¸Šà¸·à¹ˆà¸­à¹‚à¸®à¸ªà¸•à¹Œ
-  setting_text_formatting: à¸à¸²à¸£à¸ˆà¸±à¸”à¸£à¸¹à¸›à¹à¸šà¸šà¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
-  setting_wiki_compression: à¸šà¸µà¸šà¸­à¸±à¸”à¸›à¸£à¸°à¸§à¸±à¸•à¸´ Wiki
-  setting_feeds_limit: à¸ˆà¸³à¸™à¸§à¸™ Feed
-  setting_default_projects_public: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¹ƒà¸«à¸¡à¹ˆà¸¡à¸µà¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¹€à¸›à¹‡à¸™ à¸ªà¸²à¸˜à¸²à¸£à¸“à¸°
-  setting_autofetch_changesets: à¸”à¸¶à¸‡ commits à¸­à¸±à¸•à¹‚à¸™à¸¡à¸±à¸•à¸´
-  setting_sys_api_enabled: à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰ WS à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
-  setting_commit_ref_keywords: à¸„à¸³à¸ªà¸³à¸„à¸±à¸ Referencing
-  setting_commit_fix_keywords: à¸„à¸³à¸ªà¸³à¸„à¸±à¸ Fixing
-  setting_autologin: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸šà¸­à¸±à¸•à¹‚à¸™à¸¡à¸±à¸•à¸´
-  setting_date_format: à¸£à¸¹à¸›à¹à¸šà¸šà¸§à¸±à¸™à¸—à¸µà¹ˆ
-  setting_time_format: à¸£à¸¹à¸›à¹à¸šà¸šà¹€à¸§à¸¥à¸²
-  setting_cross_project_issue_relations: à¸­à¸™à¸¸à¸à¸²à¸•à¹ƒà¸«à¹‰à¸£à¸°à¸šà¸¸à¸›à¸±à¸à¸«à¸²à¸‚à¹‰à¸²à¸¡à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
-  setting_issue_list_default_columns: à¸ªà¸”à¸¡à¸ à¹Œà¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¹à¸ªà¸”à¸‡à¹ƒà¸™à¸£à¸²à¸¢à¸à¸²à¸£à¸›à¸±à¸à¸«à¸²
-  setting_emails_footer: à¸„à¸³à¸¥à¸‡à¸—à¹‰à¸²à¸¢à¸­à¸µà¹€à¸¡à¸¥à¹Œ
-  setting_protocol: Protocol
-  setting_per_page_options: à¸•à¸±à¸§à¹€à¸¥à¸·à¸­à¸à¸ˆà¸³à¸™à¸§à¸™à¸•à¹ˆà¸­à¸«à¸™à¹‰à¸²
-  setting_user_format: à¸£à¸¹à¸›à¹à¸šà¸šà¸à¸²à¸£à¹à¸ªà¸”à¸‡à¸Šà¸·à¹ˆà¸­à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
-  setting_activity_days_default: à¸ˆà¸³à¸™à¸§à¸™à¸§à¸±à¸™à¸—à¸µà¹ˆà¹à¸ªà¸”à¸‡à¹ƒà¸™à¸à¸´à¸ˆà¸à¸£à¸£à¸¡à¸‚à¸­à¸‡à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
-  setting_display_subprojects_issues: à¹à¸ªà¸”à¸‡à¸›à¸±à¸à¸«à¸²à¸‚à¸­à¸‡à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢à¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸«à¸¥à¸±à¸
-  
-  project_module_issue_tracking: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡à¸›à¸±à¸à¸«à¸²
-  project_module_time_tracking: à¸à¸²à¸£à¹ƒà¸Šà¹‰à¹€à¸§à¸¥à¸²
-  project_module_news: à¸‚à¹ˆà¸²à¸§
-  project_module_documents: à¹€à¸­à¸à¸ªà¸²à¸£
-  project_module_files: à¹à¸Ÿà¹‰à¸¡
-  project_module_wiki: Wiki
-  project_module_repository: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
-  project_module_boards: à¸à¸£à¸°à¸”à¸²à¸™à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
-  
-  label_user: à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
-  label_user_plural: à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
-  label_user_new: à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¹ƒà¸«à¸¡à¹ˆ
-  label_project: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
-  label_project_new: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¹ƒà¸«à¸¡à¹ˆ
-  label_project_plural: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
-  label_x_projects:
-    zero:  no projects
-    one:   1 project
-    other: "%{count} projects"
-  label_project_all: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
-  label_project_latest: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
-  label_issue: à¸›à¸±à¸à¸«à¸²
-  label_issue_new: à¸›à¸±à¸à¸«à¸²à¹ƒà¸«à¸¡à¹ˆ
-  label_issue_plural: à¸›à¸±à¸à¸«à¸²
-  label_issue_view_all: à¸”à¸¹à¸›à¸±à¸à¸«à¸²à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
-  label_issues_by: "à¸›à¸±à¸à¸«à¸²à¹‚à¸”à¸¢ %{value}"
-  label_issue_added: à¸›à¸±à¸à¸«à¸²à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
-  label_issue_updated: à¸›à¸±à¸à¸«à¸²à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡
-  label_document: à¹€à¸­à¸à¸ªà¸²à¸£
-  label_document_new: à¹€à¸­à¸à¸ªà¸²à¸£à¹ƒà¸«à¸¡à¹ˆ
-  label_document_plural: à¹€à¸­à¸à¸ªà¸²à¸£
-  label_document_added: à¹€à¸­à¸à¸ªà¸²à¸£à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
-  label_role: à¸šà¸—à¸šà¸²à¸—
-  label_role_plural: à¸šà¸—à¸šà¸²à¸—
-  label_role_new: à¸šà¸—à¸šà¸²à¸—à¹ƒà¸«à¸¡à¹ˆ
-  label_role_and_permissions: à¸šà¸—à¸šà¸²à¸—à¹à¸¥à¸°à¸ªà¸´à¸—à¸˜à¸´
-  label_member: à¸ªà¸¡à¸²à¸Šà¸´à¸
-  label_member_new: à¸ªà¸¡à¸²à¸Šà¸´à¸à¹ƒà¸«à¸¡à¹ˆ
-  label_member_plural: à¸ªà¸¡à¸²à¸Šà¸´à¸
-  label_tracker: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡
-  label_tracker_plural: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡
-  label_tracker_new: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡à¹ƒà¸«à¸¡à¹ˆ
-  label_workflow: à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™
-  label_issue_status: à¸ªà¸–à¸²à¸™à¸°à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
-  label_issue_status_plural: à¸ªà¸–à¸²à¸™à¸°à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
-  label_issue_status_new: à¸ªà¸–à¸²à¸™à¸°à¹ƒà¸«à¸¡
-  label_issue_category: à¸›à¸£à¸°à¹€à¸ à¸—à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
-  label_issue_category_plural: à¸›à¸£à¸°à¹€à¸ à¸—à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
-  label_issue_category_new: à¸›à¸£à¸°à¹€à¸ à¸—à¹ƒà¸«à¸¡à¹ˆ
-  label_custom_field: à¹€à¸‚à¸•à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¹à¸šà¸šà¸£à¸°à¸šà¸¸à¹€à¸­à¸‡
-  label_custom_field_plural: à¹€à¸‚à¸•à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¹à¸šà¸šà¸£à¸°à¸šà¸¸à¹€à¸­à¸‡
-  label_custom_field_new: à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸‚à¸•à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¹à¸šà¸šà¸£à¸°à¸šà¸¸à¹€à¸­à¸‡
-  label_enumerations: à¸£à¸²à¸¢à¸à¸²à¸£
-  label_enumeration_new: à¸ªà¸£à¹‰à¸²à¸‡à¹ƒà¸«à¸¡à¹ˆ
-  label_information: à¸‚à¹‰à¸­à¸¡à¸¹à¸¥
-  label_information_plural: à¸‚à¹‰à¸­à¸¡à¸¹à¸¥
-  label_please_login: à¸à¸£à¸¸à¸“à¸²à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸šà¸à¹ˆà¸­à¸™
-  label_register: à¸¥à¸‡à¸—à¸°à¹€à¸šà¸µà¸¢à¸™
-  label_password_lost: à¸¥à¸·à¸¡à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
-  label_home: à¸«à¸™à¹‰à¸²à¹à¸£à¸
-  label_my_page: à¸«à¸™à¹‰à¸²à¸‚à¸­à¸‡à¸‰à¸±à¸™
-  label_my_account: à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¸‰à¸±à¸™
-  label_my_projects: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸‚à¸­à¸‡à¸‰à¸±à¸™
-  label_administration: à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£
-  label_login: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸š
-  label_logout: à¸­à¸­à¸à¸£à¸°à¸šà¸š
-  label_help: à¸Šà¹ˆà¸§à¸¢à¹€à¸«à¸¥à¸·à¸­
-  label_reported_issues: à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¹à¸ˆà¹‰à¸‡à¹„à¸§à¹‰
-  label_assigned_to_me_issues: à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸¡à¸­à¸šà¸«à¸¡à¸²à¸¢à¹ƒà¸«à¹‰à¸‰à¸±à¸™
-  label_last_login: à¸•à¸´à¸”à¸•à¹ˆà¸­à¸„à¸£à¸±à¹‰à¸‡à¸ªà¸¸à¸”à¸—à¹‰à¸²à¸¢
-  label_registered_on: à¸¥à¸‡à¸—à¸°à¹€à¸šà¸µà¸¢à¸™à¹€à¸¡à¸·à¹ˆà¸­
-  label_activity: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡
-  label_activity_plural: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡
-  label_activity_latest: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
-  label_overall_activity: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡à¹‚à¸”à¸¢à¸£à¸§à¸¡
-  label_new: à¹ƒà¸«à¸¡à¹ˆ
-  label_logged_as: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸šà¹ƒà¸™à¸Šà¸·à¹ˆà¸­
-  label_environment: à¸ªà¸ à¸²à¸žà¹à¸§à¸”à¸¥à¹‰à¸­à¸¡
-  label_authentication: à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™
-  label_auth_source: à¸§à¸´à¸˜à¸µà¸à¸²à¸£à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™
-  label_auth_source_new: à¸ªà¸£à¹‰à¸²à¸‡à¸§à¸´à¸˜à¸µà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™à¹ƒà¸«à¸¡à¹ˆ
-  label_auth_source_plural: à¸§à¸´à¸˜à¸µà¸à¸²à¸£ Authentication
-  label_subproject_plural: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢
-  label_min_max_length: à¸ªà¸±à¹‰à¸™-à¸¢à¸²à¸§ à¸ªà¸¸à¸”à¸—à¸µà¹ˆ
-  label_list: à¸£à¸²à¸¢à¸à¸²à¸£
-  label_date: à¸§à¸±à¸™à¸—à¸µà¹ˆ
-  label_integer: à¸ˆà¸³à¸™à¸§à¸™à¹€à¸•à¹‡à¸¡
-  label_float: à¸ˆà¸³à¸™à¸§à¸™à¸ˆà¸£à¸´à¸‡
-  label_boolean: à¸–à¸¹à¸à¸œà¸´à¸”
-  label_string: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
-  label_text: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¸‚à¸™à¸²à¸”à¸¢à¸²à¸§
-  label_attribute: à¸„à¸¸à¸“à¸¥à¸±à¸à¸©à¸“à¸°
-  label_attribute_plural: à¸„à¸¸à¸“à¸¥à¸±à¸à¸©à¸“à¸°
-  label_download: "%{count} à¸”à¸²à¸§à¸™à¹Œà¹‚à¸«à¸¥à¸”"
-  label_download_plural: "%{count} à¸”à¸²à¸§à¸™à¹Œà¹‚à¸«à¸¥à¸”"
-  label_no_data: à¸ˆà¸³à¸™à¸§à¸™à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¸—à¸µà¹ˆà¹à¸ªà¸”à¸‡
-  label_change_status: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸ªà¸–à¸²à¸™à¸°
-  label_history: à¸›à¸£à¸°à¸§à¸±à¸•à¸´
-  label_attachment: à¹à¸Ÿà¹‰à¸¡
-  label_attachment_new: à¹à¸Ÿà¹‰à¸¡à¹ƒà¸«à¸¡à¹ˆ
-  label_attachment_delete: à¸¥à¸šà¹à¸Ÿà¹‰à¸¡
-  label_attachment_plural: à¹à¸Ÿà¹‰à¸¡
-  label_file_added: à¹à¸Ÿà¹‰à¸¡à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
-  label_report: à¸£à¸²à¸¢à¸‡à¸²à¸™
-  label_report_plural: à¸£à¸²à¸¢à¸‡à¸²à¸™
-  label_news: à¸‚à¹ˆà¸²à¸§
-  label_news_new: à¹€à¸žà¸´à¹ˆà¸¡à¸‚à¹ˆà¸²à¸§
-  label_news_plural: à¸‚à¹ˆà¸²à¸§
-  label_news_latest: à¸‚à¹ˆà¸²à¸§à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
-  label_news_view_all: à¸”à¸¹à¸‚à¹ˆà¸²à¸§à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
-  label_news_added: à¸‚à¹ˆà¸²à¸§à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
-  label_settings: à¸›à¸£à¸±à¸šà¹à¸•à¹ˆà¸‡
-  label_overview: à¸ à¸²à¸žà¸£à¸§à¸¡
-  label_version: à¸£à¸¸à¹ˆà¸™
-  label_version_new: à¸£à¸¸à¹ˆà¸™à¹ƒà¸«à¸¡à¹ˆ
-  label_version_plural: à¸£à¸¸à¹ˆà¸™
-  label_confirmation: à¸¢à¸·à¸™à¸¢à¸±à¸™
-  label_export_to: 'à¸£à¸¹à¸›à¹à¸šà¸šà¸­à¸·à¹ˆà¸™à¹† :'
-  label_read: à¸­à¹ˆà¸²à¸™...
-  label_public_projects: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸ªà¸²à¸˜à¸²à¸£à¸“à¸°
-  label_open_issues: à¹€à¸›à¸´à¸”
-  label_open_issues_plural: à¹€à¸›à¸´à¸”
-  label_closed_issues: à¸›à¸´à¸”
-  label_closed_issues_plural: à¸›à¸´à¸”
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_total: à¸ˆà¸³à¸™à¸§à¸™à¸£à¸§à¸¡
-  label_permissions: à¸ªà¸´à¸—à¸˜à¸´
-  label_current_status: à¸ªà¸–à¸²à¸™à¸°à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™
-  label_new_statuses_allowed: à¸­à¸™à¸¸à¸à¸²à¸•à¹ƒà¸«à¹‰à¸¡à¸µà¸ªà¸–à¸²à¸™à¸°à¹ƒà¸«à¸¡à¹ˆ
-  label_all: à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
-  label_none: à¹„à¸¡à¹ˆà¸¡à¸µ
-  label_nobody: à¹„à¸¡à¹ˆà¸¡à¸µà¹ƒà¸„à¸£
-  label_next: à¸•à¹ˆà¸­à¹„à¸›
-  label_previous: à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²
-  label_used_by: à¸–à¸¹à¸à¹ƒà¸Šà¹‰à¹‚à¸”à¸¢
-  label_details: à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”
-  label_add_note: à¹€à¸žà¸´à¹ˆà¸¡à¸šà¸±à¸™à¸—à¸¶à¸
-  label_per_page: à¸•à¹ˆà¸­à¸«à¸™à¹‰à¸²
-  label_calendar: à¸›à¸à¸´à¸—à¸´à¸™
-  label_months_from: à¹€à¸”à¸·à¸­à¸™à¸ˆà¸²à¸
-  label_gantt: Gantt
-  label_internal: à¸ à¸²à¸¢à¹ƒà¸™
-  label_last_changes: "last %{count} à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡"
-  label_change_view_all: à¸”à¸¹à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
-  label_personalize_page: à¸›à¸£à¸±à¸šà¹à¸•à¹ˆà¸‡à¸«à¸™à¹‰à¸²à¸™à¸µà¹‰
-  label_comment: à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
-  label_comment_plural: à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_comment_add: à¹€à¸žà¸´à¹ˆà¸¡à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
-  label_comment_added: à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
-  label_comment_delete: à¸¥à¸šà¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
-  label_query: à¹à¸šà¸šà¸ªà¸­à¸šà¸–à¸²à¸¡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”à¹€à¸­à¸‡
-  label_query_plural: à¹à¸šà¸šà¸ªà¸­à¸šà¸–à¸²à¸¡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”à¹€à¸­à¸‡
-  label_query_new: à¹à¸šà¸šà¸ªà¸­à¸šà¸–à¸²à¸¡à¹ƒà¸«à¸¡à¹ˆ
-  label_filter_add: à¹€à¸žà¸´à¹ˆà¸¡à¸•à¸±à¸§à¸à¸£à¸­à¸‡
-  label_filter_plural: à¸•à¸±à¸§à¸à¸£à¸­à¸‡
-  label_equals: à¸„à¸·à¸­
-  label_not_equals: à¹„à¸¡à¹ˆà¹ƒà¸Šà¹ˆ
-  label_in_less_than: à¸™à¹‰à¸­à¸¢à¸à¸§à¹ˆà¸²
-  label_in_more_than: à¸¡à¸²à¸à¸à¸§à¹ˆà¸²
-  label_in: à¹ƒà¸™à¸Šà¹ˆà¸§à¸‡
-  label_today: à¸§à¸±à¸™à¸™à¸µà¹‰
-  label_all_time: à¸•à¸¥à¸­à¸”à¹€à¸§à¸¥à¸²
-  label_yesterday: à¹€à¸¡à¸·à¹ˆà¸­à¸§à¸²à¸™
-  label_this_week: à¸­à¸²à¸—à¸´à¸•à¸¢à¹Œà¸™à¸µà¹‰
-  label_last_week: à¸­à¸²à¸—à¸´à¸•à¸¢à¹Œà¸—à¸µà¹ˆà¹à¸¥à¹‰à¸§
-  label_last_n_days: "%{count} à¸§à¸±à¸™à¸¢à¹‰à¸­à¸™à¸«à¸¥à¸±à¸‡"
-  label_this_month: à¹€à¸”à¸·à¸­à¸™à¸™à¸µà¹‰
-  label_last_month: à¹€à¸”à¸·à¸­à¸™à¸—à¸µà¹ˆà¹à¸¥à¹‰à¸§
-  label_this_year: à¸›à¸µà¸™à¸µà¹‰
-  label_date_range: à¸Šà¹ˆà¸§à¸‡à¸§à¸±à¸™à¸—à¸µà¹ˆ
-  label_less_than_ago: à¸™à¹‰à¸­à¸¢à¸à¸§à¹ˆà¸²à¸«à¸™à¸¶à¹ˆà¸‡à¸§à¸±à¸™
-  label_more_than_ago: à¸¡à¸²à¸à¸à¸§à¹ˆà¸²à¸«à¸™à¸¶à¹ˆà¸‡à¸§à¸±à¸™
-  label_ago: à¸§à¸±à¸™à¸œà¹ˆà¸²à¸™à¸¡à¸²à¹à¸¥à¹‰à¸§
-  label_contains: à¸¡à¸µ...
-  label_not_contains: à¹„à¸¡à¹ˆà¸¡à¸µ...
-  label_day_plural: à¸§à¸±à¸™
-  label_repository: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
-  label_repository_plural: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
-  label_browse: à¹€à¸›à¸´à¸”à¸«à¸²
-  label_modification: "%{count} à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡"
-  label_modification_plural: "%{count} à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡"
-  label_revision: à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚
-  label_revision_plural: à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚
-  label_associated_revisions: à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚à¸—à¸µà¹ˆà¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¸­à¸‡
-  label_added: à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
-  label_modified: à¸–à¸¹à¸à¹à¸à¹‰à¹„à¸‚
-  label_deleted: à¸–à¸¹à¸à¸¥à¸š
-  label_latest_revision: à¸£à¸¸à¹ˆà¸™à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
-  label_latest_revision_plural: à¸£à¸¸à¹ˆà¸™à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
-  label_view_revisions: à¸”à¸¹à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚
-  label_max_size: à¸‚à¸™à¸²à¸”à¹ƒà¸«à¸à¹ˆà¸ªà¸¸à¸”
-  label_sort_highest: à¸¢à¹‰à¸²à¸¢à¹„à¸›à¸šà¸™à¸ªà¸¸à¸”
-  label_sort_higher: à¸¢à¹‰à¸²à¸¢à¸‚à¸¶à¹‰à¸™
-  label_sort_lower: à¸¢à¹‰à¸²à¸¢à¸¥à¸‡
-  label_sort_lowest: à¸¢à¹‰à¸²à¸¢à¹„à¸›à¸¥à¹ˆà¸²à¸‡à¸ªà¸¸à¸”
-  label_roadmap: à¹à¸œà¸™à¸‡à¸²à¸™
-  label_roadmap_due_in: "à¸–à¸¶à¸‡à¸à¸³à¸«à¸™à¸”à¹ƒà¸™ %{value}"
-  label_roadmap_overdue: "%{value} à¸Šà¹‰à¸²à¸à¸§à¹ˆà¸²à¸à¸³à¸«à¸™à¸”"
-  label_roadmap_no_issues: à¹„à¸¡à¹ˆà¸¡à¸µà¸›à¸±à¸à¸«à¸²à¸ªà¸³à¸«à¸£à¸±à¸šà¸£à¸¸à¹ˆà¸™à¸™à¸µà¹‰
-  label_search: à¸„à¹‰à¸™à¸«à¸²
-  label_result_plural: à¸œà¸¥à¸à¸²à¸£à¸„à¹‰à¸™à¸«à¸²
-  label_all_words: à¸—à¸¸à¸à¸„à¸³
-  label_wiki: Wiki
-  label_wiki_edit: à¹à¸à¹‰à¹„à¸‚ Wiki
-  label_wiki_edit_plural: à¹à¸à¹‰à¹„à¸‚ Wiki
-  label_wiki_page: à¸«à¸™à¹‰à¸² Wiki
-  label_wiki_page_plural: à¸«à¸™à¹‰à¸² Wiki
-  label_index_by_title: à¹€à¸£à¸µà¸¢à¸‡à¸•à¸²à¸¡à¸Šà¸·à¹ˆà¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡
-  label_index_by_date: à¹€à¸£à¸µà¸¢à¸‡à¸•à¸²à¸¡à¸§à¸±à¸™
-  label_current_version: à¸£à¸¸à¹ˆà¸™à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™
-  label_preview: à¸•à¸±à¸§à¸­à¸¢à¹ˆà¸²à¸‡à¸à¹ˆà¸­à¸™à¸ˆà¸±à¸”à¹€à¸à¹‡à¸š
-  label_feed_plural: Feeds
-  label_changes_details: à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
-  label_issue_tracking: à¸•à¸´à¸”à¸•à¸²à¸¡à¸›à¸±à¸à¸«à¸²
-  label_spent_time: à¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰
-  label_f_hour: "%{value} à¸Šà¸±à¹ˆà¸§à¹‚à¸¡à¸‡"
-  label_f_hour_plural: "%{value} à¸Šà¸±à¹ˆà¸§à¹‚à¸¡à¸‡"
-  label_time_tracking: à¸•à¸´à¸”à¸•à¸²à¸¡à¸à¸²à¸£à¹ƒà¸Šà¹‰à¹€à¸§à¸¥à¸²
-  label_change_plural: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡
-  label_statistics: à¸ªà¸–à¸´à¸•à¸´
-  label_commits_per_month: Commits à¸•à¹ˆà¸­à¹€à¸”à¸·à¸­à¸™
-  label_commits_per_author: Commits à¸•à¹ˆà¸­à¸œà¸¹à¹‰à¹à¸•à¹ˆà¸‡
-  label_view_diff: à¸”à¸¹à¸„à¸§à¸²à¸¡à¹à¸•à¸à¸•à¹ˆà¸²à¸‡
-  label_diff_inline: inline
-  label_diff_side_by_side: side by side
-  label_options: à¸•à¸±à¸§à¹€à¸¥à¸·à¸­à¸
-  label_copy_workflow_from: à¸„à¸±à¸”à¸¥à¸­à¸à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™à¸ˆà¸²à¸
-  label_permissions_report: à¸£à¸²à¸¢à¸‡à¸²à¸™à¸ªà¸´à¸—à¸˜à¸´
-  label_watched_issues: à¹€à¸à¹‰à¸²à¸”à¸¹à¸›à¸±à¸à¸«à¸²
-  label_related_issues: à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¸­à¸‡
-  label_applied_status: à¸ˆà¸±à¸”à¹€à¸à¹‡à¸šà¸ªà¸–à¸²à¸™à¸°
-  label_loading: à¸à¸³à¸¥à¸±à¸‡à¹‚à¸«à¸¥à¸”...
-  label_relation_new: à¸„à¸§à¸²à¸¡à¸ªà¸±à¸¡à¸žà¸±à¸™à¸˜à¹Œà¹ƒà¸«à¸¡à¹ˆ
-  label_relation_delete: à¸¥à¸šà¸„à¸§à¸²à¸¡à¸ªà¸±à¸¡à¸žà¸±à¸™à¸˜à¹Œ
-  label_relates_to: à¸ªà¸±à¸¡à¸žà¸±à¸™à¸˜à¹Œà¸à¸±à¸š
-  label_duplicates: à¸‹à¹‰à¸³
-  label_blocks: à¸à¸µà¸”à¸à¸±à¸™
-  label_blocked_by: à¸à¸µà¸”à¸à¸±à¸™à¹‚à¸”à¸¢
-  label_precedes: à¸™à¸³à¸«à¸™à¹‰à¸²
-  label_follows: à¸•à¸²à¸¡à¸«à¸¥à¸±à¸‡
-  label_end_to_start: à¸ˆà¸š-à¹€à¸£à¸´à¹ˆà¸¡
-  label_end_to_end: à¸ˆà¸š-à¸ˆà¸š
-  label_start_to_start: à¹€à¸£à¸´à¹ˆà¸¡-à¹€à¸£à¸´à¹ˆà¸¡
-  label_start_to_end: à¹€à¸£à¸´à¹ˆà¸¡-à¸ˆà¸š
-  label_stay_logged_in: à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¸£à¸°à¸šà¸šà¸•à¹ˆà¸­
-  label_disabled: à¹„à¸¡à¹ˆà¹ƒà¸Šà¹‰à¸‡à¸²à¸™
-  label_show_completed_versions: à¹à¸ªà¸”à¸‡à¸£à¸¸à¹ˆà¸™à¸—à¸µà¹ˆà¸ªà¸¡à¸šà¸¹à¸£à¸“à¹Œ
-  label_me: à¸‰à¸±à¸™
-  label_board: à¸ªà¸ à¸²à¸à¸²à¹à¸Ÿ
-  label_board_new: à¸ªà¸£à¹‰à¸²à¸‡à¸ªà¸ à¸²à¸à¸²à¹à¸Ÿ
-  label_board_plural: à¸ªà¸ à¸²à¸à¸²à¹à¸Ÿ
-  label_topic_plural: à¸«à¸±à¸§à¸‚à¹‰à¸­
-  label_message_plural: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
-  label_message_last: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
-  label_message_new: à¹€à¸‚à¸µà¸¢à¸™à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¹ƒà¸«à¸¡à¹ˆ
-  label_message_posted: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡à¹à¸¥à¹‰à¸§
-  label_reply_plural: à¸•à¸­à¸šà¸à¸¥à¸±à¸š
-  label_send_information: à¸ªà¹ˆà¸‡à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”à¸‚à¸­à¸‡à¸šà¸±à¸à¸Šà¸µà¹ƒà¸«à¹‰à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
-  label_year: à¸›à¸µ
-  label_month: à¹€à¸”à¸·à¸­à¸™
-  label_week: à¸ªà¸±à¸›à¸”à¸²à¸«à¹Œ
-  label_date_from: à¸ˆà¸²à¸
-  label_date_to: à¸–à¸¶à¸‡
-  label_language_based: à¸‚à¸¶à¹‰à¸™à¸­à¸¢à¸¹à¹ˆà¸à¸±à¸šà¸ à¸²à¸©à¸²à¸‚à¸­à¸‡à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
-  label_sort_by: "à¹€à¸£à¸µà¸¢à¸‡à¹‚à¸”à¸¢ %{value}"
-  label_send_test_email: à¸ªà¹ˆà¸‡à¸ˆà¸”à¸«à¸¡à¸²à¸¢à¸—à¸”à¸ªà¸­à¸š
-  label_feeds_access_key_created_on: "RSS access key à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸¡à¸·à¹ˆà¸­ %{value} à¸—à¸µà¹ˆà¸œà¹ˆà¸²à¸™à¸¡à¸²"
-  label_module_plural: à¸ªà¹ˆà¸§à¸™à¸›à¸£à¸°à¸à¸­à¸š
-  label_added_time_by: "à¹€à¸žà¸´à¹ˆà¸¡à¹‚à¸”à¸¢ %{author} %{age} à¸—à¸µà¹ˆà¸œà¹ˆà¸²à¸™à¸¡à¸²"
-  label_updated_time: "à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡ %{value} à¸—à¸µà¹ˆà¸œà¹ˆà¸²à¸™à¸¡à¸²"
-  label_jump_to_a_project: à¹„à¸›à¸—à¸µà¹ˆà¹‚à¸„à¸£à¸‡à¸à¸²à¸£...
-  label_file_plural: à¹à¸Ÿà¹‰à¸¡
-  label_changeset_plural: à¸à¸¥à¸¸à¹ˆà¸¡à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡
-  label_default_columns: à¸ªà¸”à¸¡à¸ à¹Œà¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
-  label_no_change_option: (à¹„à¸¡à¹ˆà¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡)
-  label_bulk_edit_selected_issues: à¹à¸à¹‰à¹„à¸‚à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¹€à¸¥à¸·à¸­à¸à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
-  label_theme: à¸Šà¸¸à¸”à¸£à¸¹à¸›à¹à¸šà¸š
-  label_default: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
-  label_search_titles_only: à¸„à¹‰à¸™à¸«à¸²à¸ˆà¸²à¸à¸Šà¸·à¹ˆà¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡à¹€à¸—à¹ˆà¸²à¸™à¸±à¹‰à¸™
-  label_user_mail_option_all: "à¸—à¸¸à¸à¹† à¹€à¸«à¸•à¸¸à¸à¸²à¸£à¸“à¹Œà¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸‚à¸­à¸‡à¸‰à¸±à¸™"
-  label_user_mail_option_selected: "à¸—à¸¸à¸à¹† à¹€à¸«à¸•à¸¸à¸à¸²à¸£à¸“à¹Œà¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸—à¸µà¹ˆà¹€à¸¥à¸·à¸­à¸..."
-  label_user_mail_no_self_notified: "à¸‰à¸±à¸™à¹„à¸¡à¹ˆà¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹„à¸”à¹‰à¸£à¸±à¸šà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•à¸·à¸­à¸™à¹ƒà¸™à¸ªà¸´à¹ˆà¸‡à¸—à¸µà¹ˆà¸‰à¸±à¸™à¸—à¸³à¹€à¸­à¸‡"
-  label_registration_activation_by_email: à¹€à¸›à¸´à¸”à¸šà¸±à¸à¸Šà¸µà¸œà¹ˆà¸²à¸™à¸­à¸µà¹€à¸¡à¸¥à¹Œ
-  label_registration_manual_activation: à¸­à¸™à¸¸à¸¡à¸±à¸•à¸´à¹‚à¸”à¸¢à¸œà¸¹à¹‰à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£
-  label_registration_automatic_activation: à¹€à¸›à¸´à¸”à¸šà¸±à¸à¸Šà¸µà¸­à¸±à¸•à¹‚à¸™à¸¡à¸±à¸•à¸´
-  label_display_per_page: "à¸•à¹ˆà¸­à¸«à¸™à¹‰à¸²: %{value}"
-  label_age: à¸­à¸²à¸¢à¸¸
-  label_change_properties: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸„à¸¸à¸“à¸ªà¸¡à¸šà¸±à¸•à¸´
-  label_general: à¸—à¸±à¹ˆà¸§à¹† à¹„à¸›
-  label_more: à¸­à¸·à¹ˆà¸™ à¹†
-  label_scm: à¸•à¸±à¸§à¸ˆà¸±à¸”à¸à¸²à¸£à¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
-  label_plugins: à¸ªà¹ˆà¸§à¸™à¹€à¸ªà¸£à¸´à¸¡
-  label_ldap_authentication: à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™à¹‚à¸”à¸¢à¹ƒà¸Šà¹‰ LDAP
-  label_downloads_abbr: D/L
-  label_optional_description: à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”à¹€à¸žà¸´à¹ˆà¸¡à¹€à¸•à¸´à¸¡
-  label_add_another_file: à¹€à¸žà¸´à¹ˆà¸¡à¹à¸Ÿà¹‰à¸¡à¸­à¸·à¹ˆà¸™à¹†
-  label_preferences: à¸„à¹ˆà¸²à¸—à¸µà¹ˆà¸Šà¸­à¸šà¹ƒà¸ˆ
-  label_chronological_order: à¹€à¸£à¸µà¸¢à¸‡à¸ˆà¸²à¸à¹€à¸à¹ˆà¸²à¹„à¸›à¹ƒà¸«à¸¡à¹ˆ
-  label_reverse_chronological_order: à¹€à¸£à¸µà¸¢à¸‡à¸ˆà¸²à¸à¹ƒà¸«à¸¡à¹ˆà¹„à¸›à¹€à¸à¹ˆà¸²
-  label_planning: à¸à¸²à¸£à¸§à¸²à¸‡à¹à¸œà¸™
-  
-  button_login: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸š
-  button_submit: à¸ˆà¸±à¸”à¸ªà¹ˆà¸‡à¸‚à¹‰à¸­à¸¡à¸¹à¸¥
-  button_save: à¸ˆà¸±à¸”à¹€à¸à¹‡à¸š
-  button_check_all: à¹€à¸¥à¸·à¸­à¸à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
-  button_uncheck_all: à¹„à¸¡à¹ˆà¹€à¸¥à¸·à¸­à¸à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
-  button_delete: à¸¥à¸š
-  button_create: à¸ªà¸£à¹‰à¸²à¸‡
-  button_test: à¸—à¸”à¸ªà¸­à¸š
-  button_edit: à¹à¸à¹‰à¹„à¸‚
-  button_add: à¹€à¸žà¸´à¹ˆà¸¡
-  button_change: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡
-  button_apply: à¸›à¸£à¸°à¸¢à¸¸à¸à¸•à¹Œà¹ƒà¸Šà¹‰
-  button_clear: à¸¥à¹‰à¸²à¸‡à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
-  button_lock: à¸¥à¹‡à¸­à¸„
-  button_unlock: à¸¢à¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸¥à¹‡à¸­à¸„
-  button_download: à¸”à¸²à¸§à¸™à¹Œà¹‚à¸«à¸¥à¸”
-  button_list: à¸£à¸²à¸¢à¸à¸²à¸£
-  button_view: à¸¡à¸¸à¸¡à¸¡à¸­à¸‡
-  button_move: à¸¢à¹‰à¸²à¸¢
-  button_back: à¸à¸¥à¸±à¸š
-  button_cancel: à¸¢à¸à¹€à¸¥à¸´à¸
-  button_activate: à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰
-  button_sort: à¸ˆà¸±à¸”à¹€à¸£à¸µà¸¢à¸‡
-  button_log_time: à¸šà¸±à¸™à¸—à¸¶à¸à¹€à¸§à¸¥à¸²
-  button_rollback: à¸–à¸­à¸¢à¸à¸¥à¸±à¸šà¸¡à¸²à¸—à¸µà¹ˆà¸£à¸¸à¹ˆà¸™à¸™à¸µà¹‰
-  button_watch: à¹€à¸à¹‰à¸²à¸”à¸¹
-  button_unwatch: à¹€à¸¥à¸´à¸à¹€à¸à¹‰à¸²à¸”à¸¹
-  button_reply: à¸•à¸­à¸šà¸à¸¥à¸±à¸š
-  button_archive: à¹€à¸à¹‡à¸šà¹€à¸‚à¹‰à¸²à¹‚à¸à¸”à¸±à¸‡
-  button_unarchive: à¹€à¸­à¸²à¸­à¸­à¸à¸ˆà¸²à¸à¹‚à¸à¸”à¸±à¸‡
-  button_reset: à¹€à¸£à¸´à¹ˆà¸¡à¹ƒà¸«à¸¡à¸—
-  button_rename: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸Šà¸·à¹ˆà¸­
-  button_change_password: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
-  button_copy: à¸„à¸±à¸”à¸¥à¸­à¸
-  button_annotate: à¸«à¸¡à¸²à¸¢à¹€à¸«à¸•à¸¸à¸›à¸£à¸°à¸à¸­à¸š
-  button_update: à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡
-  button_configure: à¸›à¸£à¸±à¸šà¹à¸•à¹ˆà¸‡
-  
-  status_active: à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹à¸¥à¹‰à¸§
-  status_registered: à¸£à¸­à¸à¸²à¸£à¸­à¸™à¸¸à¸¡à¸±à¸•à¸´
-  status_locked: à¸¥à¹‡à¸­à¸„
-  
-  text_select_mail_notifications: à¹€à¸¥à¸·à¸­à¸à¸à¸²à¸£à¸à¸£à¸°à¸—à¸³à¸—à¸µà¹ˆà¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹ƒà¸«à¹‰à¸ªà¹ˆà¸‡à¸­à¸µà¹€à¸¡à¸¥à¹Œà¹à¸ˆà¹‰à¸‡.
-  text_regexp_info: à¸•à¸±à¸§à¸­à¸¢à¹ˆà¸²à¸‡ ^[A-Z0-9]+$
-  text_min_max_length_info: 0 à¸«à¸¡à¸²à¸¢à¸–à¸¶à¸‡à¹„à¸¡à¹ˆà¸ˆà¸³à¸à¸±à¸”
-  text_project_destroy_confirmation: à¸„à¸¸à¸“à¹à¸™à¹ˆà¹ƒà¸ˆà¹„à¸«à¸¡à¸§à¹ˆà¸²à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸¥à¸šà¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¹à¸¥à¸°à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¸—à¸µà¹ˆà¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¹ˆà¸­à¸‡ ?
-  text_subprojects_destroy_warning: "à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢: %{value} à¸ˆà¸°à¸–à¸¹à¸à¸¥à¸šà¸”à¹‰à¸§à¸¢."
-  text_workflow_edit: à¹€à¸¥à¸·à¸­à¸à¸šà¸—à¸šà¸²à¸—à¹à¸¥à¸°à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡ à¹€à¸žà¸·à¹ˆà¸­à¹à¸à¹‰à¹„à¸‚à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™
-  text_are_you_sure: à¸„à¸¸à¸“à¹à¸™à¹ˆà¹ƒà¸ˆà¹„à¸«à¸¡ ?
-  text_tip_issue_begin_day: à¸‡à¸²à¸™à¸—à¸µà¹ˆà¹€à¸£à¸´à¹ˆà¸¡à¸§à¸±à¸™à¸™à¸µà¹‰
-  text_tip_issue_end_day: à¸‡à¸²à¸™à¸—à¸µà¹ˆà¸ˆà¸šà¸§à¸±à¸™à¸™à¸µà¹‰
-  text_tip_issue_begin_end_day: à¸‡à¸²à¸™à¸—à¸µà¹ˆà¹€à¸£à¸´à¹ˆà¸¡à¹à¸¥à¸°à¸ˆà¸šà¸§à¸±à¸™à¸™à¸µà¹‰
-  text_project_identifier_info: 'à¸ à¸²à¸©à¸²à¸­à¸±à¸‡à¸à¸¤à¸©à¸•à¸±à¸§à¹€à¸¥à¹‡à¸(a-z), à¸•à¸±à¸§à¹€à¸¥à¸‚(0-9) à¹à¸¥à¸°à¸‚à¸µà¸” (-) à¹€à¸—à¹ˆà¸²à¸™à¸±à¹‰à¸™.<br />à¹€à¸¡à¸·à¹ˆà¸­à¸ˆà¸±à¸”à¹€à¸à¹‡à¸šà¹à¸¥à¹‰à¸§, à¸Šà¸·à¹ˆà¸­à¹€à¸‰à¸žà¸²à¸°à¹„à¸¡à¹ˆà¸ªà¸²à¸¡à¸²à¸£à¸–à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹„à¸”à¹‰'
-  text_caracters_maximum: "à¸ªà¸¹à¸‡à¸ªà¸¸à¸” %{count} à¸•à¸±à¸§à¸­à¸±à¸à¸©à¸£."
-  text_caracters_minimum: "à¸•à¹‰à¸­à¸‡à¸¢à¸²à¸§à¸­à¸¢à¹ˆà¸²à¸‡à¸™à¹‰à¸­à¸¢ %{count} à¸•à¸±à¸§à¸­à¸±à¸à¸©à¸£."
-  text_length_between: "à¸„à¸§à¸²à¸¡à¸¢à¸²à¸§à¸£à¸°à¸«à¸§à¹ˆà¸²à¸‡ %{min} à¸–à¸¶à¸‡ %{max} à¸•à¸±à¸§à¸­à¸±à¸à¸©à¸£."
-  text_tracker_no_workflow: à¹„à¸¡à¹ˆà¹„à¸”à¹‰à¸šà¸±à¸à¸à¸±à¸•à¸´à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡à¸™à¸µà¹‰
-  text_unallowed_characters: à¸•à¸±à¸§à¸­à¸±à¸à¸©à¸£à¸•à¹‰à¸­à¸‡à¸«à¹‰à¸²à¸¡
-  text_comma_separated: à¹ƒà¸ªà¹ˆà¹„à¸”à¹‰à¸«à¸¥à¸²à¸¢à¸„à¹ˆà¸² à¹‚à¸”à¸¢à¸„à¸±à¹ˆà¸™à¸”à¹‰à¸§à¸¢à¸¥à¸¹à¸à¸™à¹‰à¸³( ,).
-  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
-  text_issue_added: "à¸›à¸±à¸à¸«à¸² %{id} à¸–à¸¹à¸à¹à¸ˆà¹‰à¸‡à¹‚à¸”à¸¢ %{author}."
-  text_issue_updated: "à¸›à¸±à¸à¸«à¸² %{id} à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹‚à¸”à¸¢ %{author}."
-  text_wiki_destroy_confirmation: à¸„à¸¸à¸“à¹à¸™à¹ˆà¹ƒà¸ˆà¸«à¸£à¸·à¸­à¸§à¹ˆà¸²à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸¥à¸š wiki à¸™à¸µà¹‰à¸žà¸£à¹‰à¸­à¸¡à¸—à¸±à¹‰à¸‡à¹€à¸™à¸µà¹‰à¸­à¸«à¸²?
-  text_issue_category_destroy_question: "à¸šà¸²à¸‡à¸›à¸±à¸à¸«à¸² (%{count}) à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¸›à¸£à¸°à¹€à¸ à¸—à¸™à¸µà¹‰. à¸„à¸¸à¸“à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸—à¸³à¸­à¸¢à¹ˆà¸²à¸‡à¹„à¸£ ?"
-  text_issue_category_destroy_assignments: à¸¥à¸šà¸›à¸£à¸°à¹€à¸ à¸—à¸™à¸µà¹‰
-  text_issue_category_reassign_to: à¸£à¸°à¸šà¸¸à¸›à¸±à¸à¸«à¸²à¹ƒà¸™à¸›à¸£à¸°à¹€à¸ à¸—à¸™à¸µà¹‰
-  text_user_mail_option: "à¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸—à¸µà¹ˆà¹„à¸¡à¹ˆà¹„à¸”à¹‰à¹€à¸¥à¸·à¸­à¸, à¸„à¸¸à¸“à¸ˆà¸°à¹„à¸”à¹‰à¸£à¸±à¸šà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸ªà¸´à¹ˆà¸‡à¸—à¸µà¹ˆà¸„à¸¸à¸“à¹€à¸à¹‰à¸²à¸”à¸¹à¸«à¸£à¸·à¸­à¸¡à¸µà¸ªà¹ˆà¸§à¸™à¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¸­à¸‡ (à¹€à¸Šà¹ˆà¸™à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸„à¸¸à¸“à¹à¸ˆà¹‰à¸‡à¹„à¸§à¹‰à¸«à¸£à¸·à¸­à¹„à¸”à¹‰à¸£à¸±à¸šà¸¡à¸­à¸šà¸«à¸¡à¸²à¸¢)."
-  text_no_configuration_data: "à¸šà¸—à¸šà¸²à¸—, à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡, à¸ªà¸–à¸²à¸™à¸°à¸›à¸±à¸à¸«à¸² à¹à¸¥à¸°à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™à¸¢à¸±à¸‡à¹„à¸¡à¹ˆà¹„à¸”à¹‰à¸–à¸¹à¸à¸•à¸±à¹‰à¸‡à¸„à¹ˆà¸².\nà¸‚à¸­à¹à¸™à¸°à¸™à¸³à¹ƒà¸«à¹‰à¹‚à¸«à¸¥à¸”à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™. à¸„à¸¸à¸“à¸ªà¸²à¸¡à¸²à¸£à¸–à¹à¸à¹‰à¹„à¸‚à¸„à¹ˆà¸²à¹„à¸”à¹‰à¸«à¸¥à¸±à¸‡à¸ˆà¸²à¸à¹‚à¸«à¸¥à¸”à¹à¸¥à¹‰à¸§."
-  text_load_default_configuration: à¹‚à¸«à¸¥à¸”à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
-  text_status_changed_by_changeset: "à¸›à¸£à¸°à¸¢à¸¸à¸à¸•à¹Œà¹ƒà¸Šà¹‰à¹ƒà¸™à¸à¸¥à¸¸à¹ˆà¸¡à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡ %{value}."
-  text_issues_destroy_confirmation: 'à¸„à¸¸à¸“à¹à¸™à¹ˆà¹ƒà¸ˆà¹„à¸«à¸¡à¸§à¹ˆà¸²à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸¥à¸šà¸›à¸±à¸à¸«à¸²(à¸—à¸±à¹‰à¸‡à¸«à¸¥à¸²à¸¢)à¸—à¸µà¹ˆà¹€à¸¥à¸·à¸­à¸à¹„à¸§à¹‰?'
-  text_select_project_modules: 'à¹€à¸¥à¸·à¸­à¸à¸ªà¹ˆà¸§à¸™à¸›à¸£à¸°à¸à¸­à¸šà¸—à¸µà¹ˆà¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸ªà¸³à¸«à¸£à¸±à¸šà¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸™à¸µà¹‰:'
-  text_default_administrator_account_changed: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¸‚à¸­à¸‡à¸šà¸±à¸à¸Šà¸µà¸œà¸¹à¹‰à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£à¸–à¸¹à¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡
-  text_file_repository_writable: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸šà¸ªà¸²à¸¡à¸²à¸£à¸–à¹€à¸‚à¸µà¸¢à¸™à¹„à¸”à¹‰
-  text_rmagick_available: RMagick à¸¡à¸µà¹ƒà¸«à¹‰à¹ƒà¸Šà¹‰ (à¹€à¸›à¹‡à¸™à¸•à¸±à¸§à¹€à¸¥à¸·à¸­à¸)
-  text_destroy_time_entries_question: "%{hours} à¸Šà¸±à¹ˆà¸§à¹‚à¸¡à¸‡à¸—à¸µà¹ˆà¸–à¸¹à¸à¹à¸ˆà¹‰à¸‡à¹ƒà¸™à¸›à¸±à¸à¸«à¸²à¸™à¸µà¹‰à¸ˆà¸°à¹‚à¸”à¸™à¸¥à¸š. à¸„à¸¸à¸“à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸—à¸³à¸­à¸¢à¹ˆà¸²à¸‡à¹„à¸£?"
-  text_destroy_time_entries: à¸¥à¸šà¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¸£à¸²à¸¢à¸‡à¸²à¸™à¹„à¸§à¹‰
-  text_assign_time_entries_to_project: à¸£à¸°à¸šà¸¸à¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸™à¸µà¹‰
-  text_reassign_time_entries: 'à¸£à¸°à¸šà¸¸à¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸™à¸µà¹ˆà¸­à¸µà¸à¸„à¸£à¸±à¹‰à¸‡:'
-  
-  default_role_manager: à¸œà¸¹à¹‰à¸ˆà¸±à¸”à¸à¸²à¸£
-  default_role_developer: à¸œà¸¹à¹‰à¸žà¸±à¸’à¸™à¸²
-  default_role_reporter: à¸œà¸¹à¹‰à¸£à¸²à¸¢à¸‡à¸²à¸™
-  default_tracker_bug: à¸šà¸±à¹Šà¸
-  default_tracker_feature: à¸¥à¸±à¸à¸©à¸“à¸°à¹€à¸”à¹ˆà¸™
-  default_tracker_support: à¸ªà¸™à¸±à¸šà¸ªà¸™à¸¸à¸™
-  default_issue_status_new: à¹€à¸à¸´à¸”à¸‚à¸¶à¹‰à¸™
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: à¸”à¸³à¹€à¸™à¸´à¸™à¸à¸²à¸£
-  default_issue_status_feedback: à¸£à¸­à¸„à¸³à¸•à¸­à¸š
-  default_issue_status_closed: à¸ˆà¸š
-  default_issue_status_rejected: à¸¢à¸à¹€à¸¥à¸´à¸
-  default_doc_category_user: à¹€à¸­à¸à¸ªà¸²à¸£à¸‚à¸­à¸‡à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
-  default_doc_category_tech: à¹€à¸­à¸à¸ªà¸²à¸£à¸—à¸²à¸‡à¹€à¸—à¸„à¸™à¸´à¸„
-  default_priority_low: à¸•à¹ˆà¸³
-  default_priority_normal: à¸›à¸à¸•à¸´
-  default_priority_high: à¸ªà¸¹à¸‡
-  default_priority_urgent: à¹€à¸£à¹ˆà¸‡à¸”à¹ˆà¸§à¸™
-  default_priority_immediate: à¸”à¹ˆà¸§à¸™à¸¡à¸²à¸
-  default_activity_design: à¸­à¸­à¸à¹à¸šà¸š
-  default_activity_development: à¸žà¸±à¸’à¸™à¸²
-  
-  enumeration_issue_priorities: à¸„à¸§à¸²à¸¡à¸ªà¸³à¸„à¸±à¸à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
-  enumeration_doc_categories: à¸›à¸£à¸°à¹€à¸ à¸—à¹€à¸­à¸à¸ªà¸²à¸£
-  enumeration_activities: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡ (à¹ƒà¸Šà¹‰à¹ƒà¸™à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡à¹€à¸§à¸¥à¸²)
-  label_and_its_subprojects: "%{value} and its subprojects"
-  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
-  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
-  text_user_wrote: "%{value} wrote:"
-  label_duplicated_by: duplicated by
-  setting_enabled_scm: Enabled SCM
-  text_enumeration_category_reassign_to: 'Reassign them to this value:'
-  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
-  label_incoming_emails: Incoming emails
-  label_generate_key: Generate a key
-  setting_mail_handler_api_enabled: Enable WS for incoming emails
-  setting_mail_handler_api_key: API key
-  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
-  field_parent_title: Parent page
-  label_issue_watchers: Watchers
-  button_quote: Quote
-  setting_sequential_project_identifiers: Generate sequential project identifiers
-  notice_unable_delete_version: Unable to delete version
-  label_renamed: renamed
-  label_copied: copied
-  setting_plain_text_mail: plain text only (no HTML)
-  permission_view_files: View files
-  permission_edit_issues: Edit issues
-  permission_edit_own_time_entries: Edit own time logs
-  permission_manage_public_queries: Manage public queries
-  permission_add_issues: Add issues
-  permission_log_time: Log spent time
-  permission_view_changesets: View changesets
-  permission_view_time_entries: View spent time
-  permission_manage_versions: Manage versions
-  permission_manage_wiki: Manage wiki
-  permission_manage_categories: Manage issue categories
-  permission_protect_wiki_pages: Protect wiki pages
-  permission_comment_news: Comment news
-  permission_delete_messages: Delete messages
-  permission_select_project_modules: Select project modules
-  permission_manage_documents: Manage documents
-  permission_edit_wiki_pages: Edit wiki pages
-  permission_add_issue_watchers: Add watchers
-  permission_view_gantt: View gantt chart
-  permission_move_issues: Move issues
-  permission_manage_issue_relations: Manage issue relations
-  permission_delete_wiki_pages: Delete wiki pages
-  permission_manage_boards: Manage boards
-  permission_delete_wiki_pages_attachments: Delete attachments
-  permission_view_wiki_edits: View wiki history
-  permission_add_messages: Post messages
-  permission_view_messages: View messages
-  permission_manage_files: Manage files
-  permission_edit_issue_notes: Edit notes
-  permission_manage_news: Manage news
-  permission_view_calendar: View calendrier
-  permission_manage_members: Manage members
-  permission_edit_messages: Edit messages
-  permission_delete_issues: Delete issues
-  permission_view_issue_watchers: View watchers list
-  permission_manage_repository: Manage repository
-  permission_commit_access: Commit access
-  permission_browse_repository: Browse repository
-  permission_view_documents: View documents
-  permission_edit_project: Edit project
-  permission_add_issue_notes: Add notes
-  permission_save_queries: Save queries
-  permission_view_wiki_pages: View wiki
-  permission_rename_wiki_pages: Rename wiki pages
-  permission_edit_time_entries: Edit time logs
-  permission_edit_own_issue_notes: Edit own notes
-  setting_gravatar_enabled: Use Gravatar user icons
-  label_example: Example
-  text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
-  permission_edit_own_messages: Edit own messages
-  permission_delete_own_messages: Delete own messages
-  label_user_activity: "%{value}'s activity"
-  label_updated_time_by: "Updated by %{author} %{age} ago"
-  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
-  setting_diff_max_lines_displayed: Max number of diff lines displayed
-  text_plugin_assets_writable: Plugin assets directory writable
-  warning_attachments_not_saved: "%{count} file(s) could not be saved."
-  button_create_and_continue: Create and continue
-  text_custom_field_possible_values_info: 'One line for each value'
-  label_display: Display
-  field_editable: Editable
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  field_watcher: Watcher
-  setting_openid: Allow OpenID login and registration
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: or login with OpenID
-  field_content: Content
-  label_descending: Descending
-  label_sort: Sort
-  label_ascending: Ascending
-  label_date_from_to: From %{start} to %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
-  text_wiki_page_reassign_children: Reassign child pages to this parent page
-  text_wiki_page_nullify_children: Keep child pages as root pages
-  text_wiki_page_destroy_children: Delete child pages and all their descendants
-  setting_password_min_length: Minimum password length
-  field_group_by: Group results by
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  label_wiki_content_added: Wiki page added
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
-  label_wiki_content_updated: Wiki page updated
-  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
-  permission_add_project: Create project
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  label_view_all_revisions: View all revisions
-  label_tag: Tag
-  label_branch: Branch
-  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
-  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
-  text_journal_changed: "%{label} changed from %{old} to %{new}"
-  text_journal_set_to: "%{label} set to %{value}"
-  text_journal_deleted: "%{label} deleted (%{old})"
-  label_group_plural: Groups
-  label_group: Group
-  label_group_new: New group
-  label_time_entry_plural: Spent time
-  text_journal_added: "%{label} %{value} added"
-  field_active: Active
-  enumeration_system_activity: System Activity
-  permission_delete_issue_watchers: Delete watchers
-  version_status_closed: closed
-  version_status_locked: locked
-  version_status_open: open
-  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
-  label_user_anonymous: Anonymous
-  button_move_and_follow: Move and follow
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_gravatar_default: Default Gravatar image
-  field_sharing: Sharing
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_system: With all projects
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_tree: With project tree
-  label_version_sharing_none: Not shared
-  error_can_not_archive_project: This project can not be archived
-  button_duplicate: Duplicate
-  button_copy_and_follow: Copy and follow
-  label_copy_source: Source
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Same as target
-  label_copy_target: Target
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  error_workflow_copy_source: Please select a source tracker or role
-  label_update_issue_done_ratios: Update issue done ratios
-  setting_start_of_week: Start calendars on
-  permission_view_issues: View Issues
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API access key
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_missing_api_access_key: Missing an API access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  button_show: Show
-  text_line_separated: Multiple values allowed (one line for each value).
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Commit messages encoding
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5a/5a549df68d552afbb24a2891641ac0c3cca19477.svn-base
--- /dev/null
+++ b/.svn/pristine/5a/5a549df68d552afbb24a2891641ac0c3cca19477.svn-base
@@ -0,0 +1,32 @@
+<div class="contextual">
+<% if User.current.allowed_to?(:edit_documents, @project) %>
+<%= link_to l(:button_edit), edit_document_path(@document), :class => 'icon icon-edit', :accesskey => accesskey(:edit) %>
+<% end %>
+<% if User.current.allowed_to?(:delete_documents, @project) %>
+<%= delete_link document_path(@document) %>
+<% end %>
+</div>
+
+<h2><%=h @document.title %></h2>
+
+<p><em><%=h @document.category.name %><br />
+<%= format_date @document.created_on %></em></p>
+<div class="wiki">
+<%= textilizable @document, :description, :attachments => @document.attachments %>
+</div>
+
+<h3><%= l(:label_attachment_plural) %></h3>
+<%= link_to_attachments @document %>
+
+<% if authorize_for('documents', 'add_attachment') %>
+<p><%= link_to l(:label_attachment_new), {}, :onclick => "$('#add_attachment_form').show(); return false;",
+                                             :id => 'attach_files_link' %></p>
+  <%= form_tag({ :controller => 'documents', :action => 'add_attachment', :id => @document }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
+  <div class="box">
+  <p><%= render :partial => 'attachments/form' %></p>
+  </div>
+  <%= submit_tag l(:button_add) %>
+  <% end %>
+<% end %>
+
+<% html_title @document.title -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5a/5a62234b780985b2a0def003065d9dfb9410c414.svn-base
--- a/.svn/pristine/5a/5a62234b780985b2a0def003065d9dfb9410c414.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-= Redmine
-
-Redmine is a flexible project management web application written using Ruby on Rails framework.
-
-More details can be found at http://www.redmine.org
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5a/5a6564a54f44ce0a2f2a1f8ee7e59d575551ecf9.svn-base
Binary file .svn/pristine/5a/5a6564a54f44ce0a2f2a1f8ee7e59d575551ecf9.svn-base has changed
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5a/5aa3c5fccf79f48430b6e2714bcb9f02b7096762.svn-base
--- a/.svn/pristine/5a/5aa3c5fccf79f48430b6e2714bcb9f02b7096762.svn-base
+++ /dev/null
@@ -1,55 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class CommentsControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news, :comments
-
-  def setup
-    User.current = nil
-  end
-
-  def test_add_comment
-    @request.session[:user_id] = 2
-    post :create, :id => 1, :comment => { :comments => 'This is a test comment' }
-    assert_redirected_to '/news/1'
-
-    comment = News.find(1).comments.find(:first, :order => 'created_on DESC')
-    assert_not_nil comment
-    assert_equal 'This is a test comment', comment.comments
-    assert_equal User.find(2), comment.author
-  end
-
-  def test_empty_comment_should_not_be_added
-    @request.session[:user_id] = 2
-    assert_no_difference 'Comment.count' do
-      post :create, :id => 1, :comment => { :comments => '' }
-      assert_response :redirect
-      assert_redirected_to '/news/1'
-    end
-  end
-
-  def test_destroy_comment
-    comments_count = News.find(1).comments.size
-    @request.session[:user_id] = 2
-    delete :destroy, :id => 1, :comment_id => 2
-    assert_redirected_to '/news/1'
-    assert_nil Comment.find_by_id(2)
-    assert_equal comments_count - 1, News.find(1).comments.size
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5a/5ab5d51a3e643e063b36d3e9325764dc09e247cb.svn-base
--- /dev/null
+++ b/.svn/pristine/5a/5ab5d51a3e643e063b36d3e9325764dc09e247cb.svn-base
@@ -0,0 +1,6 @@
+<%= error_messages_for 'auth_source' %>
+
+<div class="box tabular">
+  <p><%= f.text_field :name, :required => true %></p>
+  <p><%= f.check_box :onthefly_register, :label => :field_onthefly %></p>
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5b/5b2317c90ed81995ffba20202367b84382beccbf.svn-base
--- a/.svn/pristine/5b/5b2317c90ed81995ffba20202367b84382beccbf.svn-base
+++ /dev/null
@@ -1,95 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class WikiContentTest < ActiveSupport::TestCase
-  fixtures :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions, :users
-
-  def setup
-    @wiki = Wiki.find(1)
-    @page = @wiki.pages.first
-  end
-
-  def test_create
-    page = WikiPage.new(:wiki => @wiki, :title => "Page")
-    page.content = WikiContent.new(:text => "Content text", :author => User.find(1), :comments => "My comment")
-    assert page.save
-    page.reload
-
-    content = page.content
-    assert_kind_of WikiContent, content
-    assert_equal 1, content.version
-    assert_equal 1, content.versions.length
-    assert_equal "Content text", content.text
-    assert_equal "My comment", content.comments
-    assert_equal User.find(1), content.author
-    assert_equal content.text, content.versions.last.text
-  end
-
-  def test_create_should_send_email_notification
-    Setting.notified_events = ['wiki_content_added']
-    ActionMailer::Base.deliveries.clear
-    page = WikiPage.new(:wiki => @wiki, :title => "A new page")
-    page.content = WikiContent.new(:text => "Content text", :author => User.find(1), :comments => "My comment")
-    assert page.save
-
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_update
-    content = @page.content
-    version_count = content.version
-    content.text = "My new content"
-    assert content.save
-    content.reload
-    assert_equal version_count+1, content.version
-    assert_equal version_count+1, content.versions.length
-  end
-
-  def test_update_should_send_email_notification
-    Setting.notified_events = ['wiki_content_updated']
-    ActionMailer::Base.deliveries.clear
-    content = @page.content
-    content.text = "My new content"
-    assert content.save
-
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_fetch_history
-    assert !@page.content.versions.empty?
-    @page.content.versions.each do |version|
-      assert_kind_of String, version.text
-    end
-  end
-
-  def test_large_text_should_not_be_truncated_to_64k
-    page = WikiPage.new(:wiki => @wiki, :title => "Big page")
-    page.content = WikiContent.new(:text => "a" * 500.kilobyte, :author => User.find(1))
-    assert page.save
-    page.reload
-    assert_equal 500.kilobyte, page.content.text.size
-  end
-  
-  def test_current_version
-    content = WikiContent.find(11)
-    assert_equal true, content.current_version?
-    assert_equal true, content.versions.first(:order => 'version DESC').current_version?
-    assert_equal false, content.versions.first(:order => 'version ASC').current_version?
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5b/5b5912958e71fec54e66733c9c7981555c23902f.svn-base
--- /dev/null
+++ b/.svn/pristine/5b/5b5912958e71fec54e66733c9c7981555c23902f.svn-base
@@ -0,0 +1,50 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::HttpBasicLoginWithApiTokenTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  def setup
+    Setting.rest_api_enabled = '1'
+    Setting.login_required = '1'
+  end
+
+  def teardown
+    Setting.rest_api_enabled = '0'
+    Setting.login_required = '0'
+  end
+
+  # Using the NewsController because it's a simple API.
+  context "get /news" do
+
+    context "in :xml format" do
+      should_allow_http_basic_auth_with_key(:get, "/news.xml")
+    end
+
+    context "in :json format" do
+      should_allow_http_basic_auth_with_key(:get, "/news.json")
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5b/5b67cbc43876349cb50763840008cc0544dfb9b5.svn-base
--- /dev/null
+++ b/.svn/pristine/5b/5b67cbc43876349cb50763840008cc0544dfb9b5.svn-base
@@ -0,0 +1,136 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class GroupTest < ActiveSupport::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :groups_users
+
+  include Redmine::I18n
+
+  def test_create
+    g = Group.new(:name => 'New group')
+    assert g.save
+    g.reload
+    assert_equal 'New group', g.name
+  end
+
+  def test_name_should_accept_255_characters
+    name = 'a' * 255
+    g = Group.new(:name => name)
+    assert g.save
+    g.reload
+    assert_equal name, g.name
+  end
+
+  def test_blank_name_error_message
+    set_language_if_valid 'en'
+    g = Group.new
+    assert !g.save
+    assert_include "Name can't be blank", g.errors.full_messages
+  end
+
+  def test_blank_name_error_message_fr
+    set_language_if_valid 'fr'
+    str = "Nom doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    g = Group.new
+    assert !g.save
+    assert_include str, g.errors.full_messages
+  end
+
+  def test_group_roles_should_be_given_to_added_user
+    group = Group.find(11)
+    user = User.find(9)
+    project = Project.first
+
+    Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
+    group.users << user
+    assert user.member_of?(project)
+  end
+
+  def test_new_roles_should_be_given_to_existing_user
+    group = Group.find(11)
+    user = User.find(9)
+    project = Project.first
+
+    group.users << user
+    m = Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
+    assert user.member_of?(project)
+  end
+
+  def test_user_roles_should_updated_when_updating_user_ids
+    group = Group.find(11)
+    user = User.find(9)
+    project = Project.first
+
+    Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
+    group.user_ids = [user.id]
+    group.save!
+    assert User.find(9).member_of?(project)
+
+    group.user_ids = [1]
+    group.save!
+    assert !User.find(9).member_of?(project)
+  end
+
+  def test_user_roles_should_updated_when_updating_group_roles
+    group = Group.find(11)
+    user = User.find(9)
+    project = Project.first
+    group.users << user
+    m = Member.create!(:principal => group, :project => project, :role_ids => [1])
+    assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
+
+    m.role_ids = [1, 2]
+    assert_equal [1, 2], user.reload.roles_for_project(project).collect(&:id).sort
+
+    m.role_ids = [2]
+    assert_equal [2], user.reload.roles_for_project(project).collect(&:id).sort
+
+    m.role_ids = [1]
+    assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
+  end
+
+  def test_user_memberships_should_be_removed_when_removing_group_membership
+    assert User.find(8).member_of?(Project.find(5))
+    Member.find_by_project_id_and_user_id(5, 10).destroy
+    assert !User.find(8).member_of?(Project.find(5))
+  end
+
+  def test_user_roles_should_be_removed_when_removing_user_from_group
+    assert User.find(8).member_of?(Project.find(5))
+    User.find(8).groups = []
+    assert !User.find(8).member_of?(Project.find(5))
+  end
+
+  def test_destroy_should_unassign_issues
+    group = Group.first
+    Issue.update_all(["assigned_to_id = ?", group.id], 'id = 1')
+
+    assert group.destroy
+    assert group.destroyed?
+
+    assert_equal nil, Issue.find(1).assigned_to_id
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5b/5ba499ead951b0f7092a76c82d09ab18e9ef0b47.svn-base
--- a/.svn/pristine/5b/5ba499ead951b0f7092a76c82d09ab18e9ef0b47.svn-base
+++ /dev/null
@@ -1,42 +0,0 @@
-# $Id: testber.rb 57 2006-04-18 00:18:48Z blackhedd $
-#
-#
-
-
-$:.unshift "lib"
-
-require 'net/ldap'
-require 'stringio'
-
-
-class TestBer < Test::Unit::TestCase
-
-  def setup
-  end
-
-  # TODO: Add some much bigger numbers
-  # 5000000000 is a Bignum, which hits different code.
-  def test_ber_integers
-    assert_equal( "\002\001\005", 5.to_ber )
-    assert_equal( "\002\002\203t", 500.to_ber )
-    assert_equal( "\002\003\203\206P", 50000.to_ber )
-    assert_equal( "\002\005\222\320\227\344\000", 5000000000.to_ber )
-  end
-
-  def test_ber_parsing
-    assert_equal( 6, "\002\001\006".read_ber( Net::LDAP::AsnSyntax ))
-    assert_equal( "testing", "\004\007testing".read_ber( Net::LDAP::AsnSyntax ))
-  end
-
-
-  def test_ber_parser_on_ldap_bind_request
-    s = StringIO.new "0$\002\001\001`\037\002\001\003\004\rAdministrator\200\vad_is_bogus"
-    assert_equal( [1, [3, "Administrator", "ad_is_bogus"]], s.read_ber( Net::LDAP::AsnSyntax ))
-  end
-
-
-
-
-end
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5b/5ba4b3bae1ac655e0a9cb68df6a092b2c3782db0.svn-base
--- a/.svn/pristine/5b/5ba4b3bae1ac655e0a9cb68df6a092b2c3782db0.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-class <%= migration_name %> < ActiveRecord::Migration
-  def self.up
-    create_table :<%= table_name %> do |t|
-<% for attribute in attributes -%>
-      t.column :<%= attribute.name %>, :<%= attribute.type %>
-<% end -%>
-    end
-  end
-
-  def self.down
-    drop_table :<%= table_name %>
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5c/5c0d725f7c169077f48040da16fb4cb01381f158.svn-base
--- a/.svn/pristine/5c/5c0d725f7c169077f48040da16fb4cb01381f158.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-issue_relation_001:
-  id: 1
-  issue_from_id: 10
-  issue_to_id: 9
-  relation_type: blocks
-  delay:
-issue_relation_002:
-  id: 2
-  issue_from_id: 2
-  issue_to_id: 3
-  relation_type: relates
-  delay:
-  
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5c/5c1734e1eca1c54bac30b17ddeecdedbc05caf30.svn-base
--- /dev/null
+++ b/.svn/pristine/5c/5c1734e1eca1c54bac30b17ddeecdedbc05caf30.svn-base
@@ -0,0 +1,35 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+namespace :db do
+  desc 'Encrypts SCM and LDAP passwords in the database.'
+  task :encrypt => :environment do
+    unless (Repository.encrypt_all(:password) &&
+      AuthSource.encrypt_all(:account_password))
+      raise "Some objects could not be saved after encryption, update was rollback'ed."
+    end
+  end
+
+  desc 'Decrypts SCM and LDAP passwords in the database.'
+  task :decrypt => :environment do
+    unless (Repository.decrypt_all(:password) &&
+      AuthSource.decrypt_all(:account_password))
+      raise "Some objects could not be saved after decryption, update was rollback'ed."
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5d/5d08d1e25f5add23341eebe953f9997482bf5a56.svn-base
--- a/.svn/pristine/5d/5d08d1e25f5add23341eebe953f9997482bf5a56.svn-base
+++ /dev/null
@@ -1,69 +0,0 @@
-# $Id: testldif.rb 61 2006-04-18 20:55:55Z blackhedd $
-#
-#
-
-
-$:.unshift "lib"
-
-require 'test/unit'
-
-require 'net/ldap'
-require 'net/ldif'
-
-require 'sha1'
-require 'base64'
-
-class TestLdif < Test::Unit::TestCase
-
-  TestLdifFilename = "tests/testdata.ldif"
-
-  def test_empty_ldif
-    ds = Net::LDAP::Dataset::read_ldif( StringIO.new )
-    assert_equal( true, ds.empty? )
-  end
-
-  def test_ldif_with_comments
-    str = ["# Hello from LDIF-land", "# This is an unterminated comment"]
-    io = StringIO.new( str[0] + "\r\n" + str[1] )
-    ds = Net::LDAP::Dataset::read_ldif( io )
-    assert_equal( str, ds.comments )
-  end
-
-  def test_ldif_with_password
-    psw = "goldbricks"
-    hashed_psw = "{SHA}" + Base64::encode64( SHA1.new(psw).digest ).chomp
-
-    ldif_encoded = Base64::encode64( hashed_psw ).chomp
-    ds = Net::LDAP::Dataset::read_ldif( StringIO.new( "dn: Goldbrick\r\nuserPassword:: #{ldif_encoded}\r\n\r\n" ))
-    recovered_psw = ds["Goldbrick"][:userpassword].shift
-    assert_equal( hashed_psw, recovered_psw )
-  end
-
-  def test_ldif_with_continuation_lines
-    ds = Net::LDAP::Dataset::read_ldif( StringIO.new( "dn: abcdefg\r\n   hijklmn\r\n\r\n" ))
-    assert_equal( true, ds.has_key?( "abcdefg hijklmn" ))
-  end
-
-  # TODO, INADEQUATE. We need some more tests
-  # to verify the content.
-  def test_ldif
-    File.open( TestLdifFilename, "r" ) {|f|
-      ds = Net::LDAP::Dataset::read_ldif( f )
-      assert_equal( 13, ds.length )
-    }
-  end
-
-  # TODO, need some tests.
-  # Must test folded lines and base64-encoded lines as well as normal ones.
-  def test_to_ldif
-    File.open( TestLdifFilename, "r" ) {|f|
-      ds = Net::LDAP::Dataset::read_ldif( f )
-      ds.to_ldif
-      assert_equal( true, false ) # REMOVE WHEN WE HAVE SOME TESTS HERE.
-    }
-  end
-
-
-end
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5d/5d26bd43e6982490a87abc50362d543225e9666c.svn-base
--- /dev/null
+++ b/.svn/pristine/5d/5d26bd43e6982490a87abc50362d543225e9666c.svn-base
@@ -0,0 +1,37 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Change < ActiveRecord::Base
+  belongs_to :changeset
+
+  validates_presence_of :changeset_id, :action, :path
+  before_save :init_path
+  before_validation :replace_invalid_utf8_of_path
+
+  def relative_path
+    changeset.repository.relative_path(path)
+  end
+
+  def replace_invalid_utf8_of_path
+    self.path      = Redmine::CodesetUtil.replace_invalid_utf8(self.path)
+    self.from_path = Redmine::CodesetUtil.replace_invalid_utf8(self.from_path)
+  end
+
+  def init_path
+    self.path ||= ""
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5d/5d3bf2e1b9c594ae744623dfe07d0b12193cbe25.svn-base
--- /dev/null
+++ b/.svn/pristine/5d/5d3bf2e1b9c594ae744623dfe07d0b12193cbe25.svn-base
@@ -0,0 +1,1110 @@
+# Polish translations for Ruby on Rails
+# by Jacek Becela (jacek.becela@gmail.com, http://github.com/ncr)
+# by Krzysztof Podejma (kpodejma@customprojects.pl, http://www.customprojects.pl)
+
+pl:
+  number:
+    format:
+      separator: ","
+      delimiter: " "
+      precision: 2
+    currency:
+      format:
+        format: "%n %u"
+        unit: "PLN"
+    percentage:
+      format:
+        delimiter: ""
+    precision:
+      format:
+        delimiter: ""
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "B"
+            other: "B"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  direction: ltr
+  date:
+    formats:
+      default: "%Y-%m-%d"
+      short: "%d %b"
+      long: "%d %B %Y"
+
+    day_names: [Niedziela, PoniedziaÅ‚ek, Wtorek, Åšroda, Czwartek, PiÄ…tek, Sobota]
+    abbr_day_names: [nie, pon, wto, Å›ro, czw, pia, sob]
+
+    month_names: [~, StyczeÅ„, Luty, Marzec, KwiecieÅ„, Maj, Czerwiec, Lipiec, SierpieÅ„, WrzesieÅ„, PaÅºdziernik, Listopad, GrudzieÅ„]
+    abbr_month_names: [~, sty, lut, mar, kwi, maj, cze, lip, sie, wrz, paÅº, lis, gru]
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y, %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b, %H:%M"
+      long: "%d %B %Y, %H:%M"
+    am: "przed poÅ‚udniem"
+    pm: "po poÅ‚udniu"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pÃ³Å‚ minuty"
+      less_than_x_seconds:
+        one:   "mniej niÅ¼ sekundÄ™"
+        few:   "mniej niÅ¼ %{count} sekundy"
+        other: "mniej niÅ¼ %{count} sekund"
+      x_seconds:
+        one:   "sekundÄ™"
+        few:   "%{count} sekundy"
+        other: "%{count} sekund"
+      less_than_x_minutes:
+        one:   "mniej niÅ¼ minutÄ™"
+        few:   "mniej niÅ¼ %{count} minuty"
+        other: "mniej niÅ¼ %{count} minut"
+      x_minutes:
+        one:   "minutÄ™"
+        few:   "%{count} minuty"
+        other: "%{count} minut"
+      about_x_hours:
+        one:   "okoÅ‚o godziny"
+        other: "okoÅ‚o %{count} godzin"
+      x_hours:
+        one:   "1 godzina"
+        other: "%{count} godzin"
+      x_days:
+        one:   "1 dzieÅ„"
+        other: "%{count} dni"
+      about_x_months:
+        one:   "okoÅ‚o miesiÄ…ca"
+        other: "okoÅ‚o %{count} miesiÄ™cy"
+      x_months:
+        one:   "1 miesiÄ…c"
+        few:   "%{count} miesiÄ…ce"
+        other: "%{count} miesiÄ™cy"
+      about_x_years:
+        one:   "okoÅ‚o roku"
+        other: "okoÅ‚o %{count} lat"
+      over_x_years:
+        one:   "ponad rok"
+        few:   "ponad %{count} lata"
+        other: "ponad %{count} lat"
+      almost_x_years:
+        one:   "prawie 1 rok"
+        few:   "prawie %{count} lata"
+        other: "prawie %{count} lat"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "%{model} nie zostaÅ‚ zachowany z powodu jednego bÅ‚Ä™du"
+          other:  "%{model} nie zostaÅ‚ zachowany z powodu %{count} bÅ‚Ä™dÃ³w"
+        body: "BÅ‚Ä™dy dotyczÄ… nastÄ™pujÄ…cych pÃ³l:"
+      messages:
+        inclusion: "nie znajduje siÄ™ na liÅ›cie dopuszczalnych wartoÅ›ci"
+        exclusion: "znajduje siÄ™ na liÅ›cie zabronionych wartoÅ›ci"
+        invalid: "jest nieprawidÅ‚owe"
+        confirmation: "nie zgadza siÄ™ z potwierdzeniem"
+        accepted: "musi byÄ‡ zaakceptowane"
+        empty: "nie moÅ¼e byÄ‡ puste"
+        blank: "nie moÅ¼e byÄ‡ puste"
+        too_long: "jest za dÅ‚ugie (maksymalnie %{count} znakÃ³w)"
+        too_short: "jest za krÃ³tkie (minimalnie %{count} znakÃ³w)"
+        wrong_length: "jest nieprawidÅ‚owej dÅ‚ugoÅ›ci (powinna wynosiÄ‡ %{count} znakÃ³w)"
+        taken: "jest juÅ¼ zajÄ™te"
+        not_a_number: "nie jest liczbÄ…"
+        greater_than: "musi byÄ‡ wiÄ™ksze niÅ¼ %{count}"
+        greater_than_or_equal_to: "musi byÄ‡ wiÄ™ksze lub rÃ³wne %{count}"
+        equal_to: "musi byÄ‡ rÃ³wne %{count}"
+        less_than: "musi byÄ‡ mniejsze niÅ¼ %{count}"
+        less_than_or_equal_to: "musi byÄ‡ mniejsze lub rÃ³wne %{count}"
+        odd: "musi byÄ‡ nieparzyste"
+        even: "musi byÄ‡ parzyste"
+        greater_than_start_date: "musi byÄ‡ wiÄ™ksze niÅ¼ poczÄ…tkowa data"
+        not_same_project: "nie naleÅ¼y do tego samego projektu"
+        circular_dependency: "Ta relacja moÅ¼e wytworzyÄ‡ zapÄ™tlonÄ… zaleÅ¼noÅ›Ä‡"
+        cant_link_an_issue_with_a_descendant: "Zagadnienie nie moÅ¼e zostaÄ‡ powiÄ…zane z jednym z wÅ‚asnych podzagadnieÅ„"
+
+  support:
+    array:
+      sentence_connector: "i"
+      skip_last_comma: true
+
+  # Keep this line in order to avoid problems with Windows Notepad UTF-8 EF-BB-BFidea...
+  # Best regards from Lublin@Poland :-)
+  # PL translation by Mariusz@Olejnik.net,
+  # Wiktor Wandachowicz <siryes@gmail.com>, 2010
+
+  actionview_instancetag_blank_option: ProszÄ™ wybraÄ‡
+  actionview_instancetag_blank_option: ProszÄ™ wybierz
+
+  button_activate: Aktywuj
+  button_add: Dodaj
+  button_annotate: Adnotuj
+  button_apply: Ustaw
+  button_archive: Archiwizuj
+  button_back: Wstecz
+  button_cancel: Anuluj
+  button_change: ZmieÅ„
+  button_change_password: ZmieÅ„ hasÅ‚o
+  button_check_all: Zaznacz wszystko
+  button_clear: WyczyÅ›Ä‡
+  button_configure: Konfiguruj
+  button_copy: Kopia
+  button_create: StwÃ³rz
+  button_delete: UsuÅ„
+  button_download: Pobierz
+  button_edit: Edytuj
+  button_list: Lista
+  button_lock: Zablokuj
+  button_log_time: Dziennik
+  button_login: Login
+  button_move: PrzenieÅ›
+  button_quote: Cytuj
+  button_rename: ZmieÅ„ nazwÄ™
+  button_reply: Odpowiedz
+  button_reset: Resetuj
+  button_rollback: PrzywrÃ³Ä‡ do tej wersji
+  button_save: Zapisz
+  button_sort: Sortuj
+  button_submit: WyÅ›lij
+  button_test: Testuj
+  button_unarchive: PrzywrÃ³Ä‡ z archiwum
+  button_uncheck_all: Odznacz wszystko
+  button_unlock: Odblokuj
+  button_unwatch: Nie obserwuj
+  button_update: Uaktualnij
+  button_view: PokaÅ¼
+  button_watch: Obserwuj
+  default_activity_design: Projektowanie
+  default_activity_development: RozwÃ³j
+  default_doc_category_tech: Dokumentacja techniczna
+  default_doc_category_user: Dokumentacja uÅ¼ytkownika
+  default_issue_status_in_progress: W toku
+  default_issue_status_closed: ZamkniÄ™ty
+  default_issue_status_feedback: OdpowiedÅº
+  default_issue_status_new: Nowy
+  default_issue_status_rejected: Odrzucony
+  default_issue_status_resolved: RozwiÄ…zany
+  default_priority_high: Wysoki
+  default_priority_immediate: Natychmiastowy
+  default_priority_low: Niski
+  default_priority_normal: Normalny
+  default_priority_urgent: Pilny
+  default_role_developer: Programista
+  default_role_manager: Kierownik
+  default_role_reporter: ZgÅ‚aszajÄ…cy
+  default_tracker_bug: BÅ‚Ä…d
+  default_tracker_feature: Zadanie
+  default_tracker_support: Wsparcie
+  enumeration_activities: DziaÅ‚ania (Å›ledzenie czasu)
+  enumeration_doc_categories: Kategorie dokumentÃ³w
+  enumeration_issue_priorities: Priorytety zagadnieÅ„
+  error_can_t_load_default_data: "DomyÅ›lna konfiguracja nie moÅ¼e byÄ‡ zaÅ‚adowana: %{value}"
+  error_issue_not_found_in_project: 'Zagadnienie nie zostaÅ‚o znalezione lub nie naleÅ¼y do tego projektu'
+  error_scm_annotate: "Wpis nie istnieje lub nie moÅ¼na do niego dodawaÄ‡ adnotacji."
+  error_scm_command_failed: "WystÄ…piÅ‚ bÅ‚Ä…d przy prÃ³bie dostÄ™pu do repozytorium: %{value}"
+  error_scm_not_found: "Obiekt lub wersja nie zostaÅ‚y znalezione w repozytorium."
+  field_account: Konto
+  field_activity: AktywnoÅ›Ä‡
+  field_admin: Administrator
+  field_assignable: Zagadnienia mogÄ… byÄ‡ przypisane do tej roli
+  field_assigned_to: Przypisany do
+  field_attr_firstname: ImiÄ™ atrybut
+  field_attr_lastname: Nazwisko atrybut
+  field_attr_login: Login atrybut
+  field_attr_mail: E-mail atrybut
+  field_auth_source: Tryb identyfikacji
+  field_author: Autor
+  field_base_dn: Base DN
+  field_category: Kategoria
+  field_column_names: Nazwy kolumn
+  field_comments: Komentarz
+  field_comments_sorting: Pokazuj komentarze
+  field_created_on: Stworzone
+  field_default_value: DomyÅ›lny
+  field_delay: OpÃ³Åºnienie
+  field_description: Opis
+  field_done_ratio: "% Wykonane"
+  field_downloads: PobraÅ„
+  field_due_date: Data oddania
+  field_effective_date: Data
+  field_estimated_hours: Szacowany czas
+  field_field_format: Format
+  field_filename: Plik
+  field_filesize: Rozmiar
+  field_firstname: ImiÄ™
+  field_fixed_version: Wersja docelowa
+  field_hide_mail: Ukryj mÃ³j adres e-mail
+  field_homepage: Strona www
+  field_host: Host
+  field_hours: Godzin
+  field_identifier: Identyfikator
+  field_is_closed: Zagadnienie zamkniÄ™te
+  field_is_default: DomyÅ›lny status
+  field_is_filter: Atrybut filtrowania
+  field_is_for_all: Dla wszystkich projektÃ³w
+  field_is_in_roadmap: Zagadnienie pokazywane na mapie
+  field_is_public: Publiczny
+  field_is_required: Wymagane
+  field_issue: Zagadnienie
+  field_issue_to: PowiÄ…zania zagadnienia
+  field_language: JÄ™zyk
+  field_last_login_on: Ostatnie poÅ‚Ä…czenie
+  field_lastname: Nazwisko
+  field_login: Login
+  field_mail: E-mail
+  field_mail_notification: Powiadomienia e-mail
+  field_max_length: Maksymalna dÅ‚ugoÅ›Ä‡
+  field_min_length: Minimalna dÅ‚ugoÅ›Ä‡
+  field_name: Nazwa
+  field_new_password: Nowe hasÅ‚o
+  field_notes: Notatki
+  field_onthefly: Tworzenie uÅ¼ytkownika w locie
+  field_parent: Projekt nadrzÄ™dny
+  field_parent_title: Strona rodzica
+  field_password: HasÅ‚o
+  field_password_confirmation: Potwierdzenie
+  field_port: Port
+  field_possible_values: MoÅ¼liwe wartoÅ›ci
+  field_priority: Priorytet
+  field_project: Projekt
+  field_redirect_existing_links: Przekierowanie istniejÄ…cych odnoÅ›nikÃ³w
+  field_regexp: WyraÅ¼enie regularne
+  field_role: Rola
+  field_searchable: Przeszukiwalne
+  field_spent_on: Data
+  field_start_date: Data rozpoczÄ™cia
+  field_start_page: Strona startowa
+  field_status: Status
+  field_subject: Temat
+  field_subproject: Podprojekt
+  field_summary: Podsumowanie
+  field_time_zone: Strefa czasowa
+  field_title: TytuÅ‚
+  field_tracker: Typ zagadnienia
+  field_type: Typ
+  field_updated_on: Zmienione
+  field_url: URL
+  field_user: UÅ¼ytkownik
+  field_value: WartoÅ›Ä‡
+  field_version: Wersja
+  field_vf_personnel: Personel
+  field_vf_watcher: Obserwator
+  general_csv_decimal_separator: ','
+  general_csv_encoding: UTF-8
+  general_csv_separator: ';'
+  general_first_day_of_week: '1'
+  general_lang_name: 'Polski'
+  general_pdf_encoding: UTF-8
+  general_text_No: 'Nie'
+  general_text_Yes: 'Tak'
+  general_text_no: 'nie'
+  general_text_yes: 'tak'
+
+  label_activity: AktywnoÅ›Ä‡
+  label_add_another_file: Dodaj kolejny plik
+  label_add_note: Dodaj notatkÄ™
+  label_added: dodane
+  label_added_time_by: "Dodane przez %{author} %{age} temu"
+  label_administration: Administracja
+  label_age: Wiek
+  label_ago: dni temu
+  label_all: wszystko
+  label_all_time: caÅ‚y czas
+  label_all_words: Wszystkie sÅ‚owa
+  label_and_its_subprojects: "%{value} i podprojekty"
+  label_applied_status: Stosowany status
+  label_assigned_to_me_issues: Zagadnienia przypisane do mnie
+  label_associated_revisions: Skojarzone rewizje
+  label_attachment: Plik
+  label_attachment_delete: UsuÅ„ plik
+  label_attachment_new: Nowy plik
+  label_attachment_plural: Pliki
+  label_attribute: Atrybut
+  label_attribute_plural: Atrybuty
+  label_auth_source: Tryb identyfikacji
+  label_auth_source_new: Nowy tryb identyfikacji
+  label_auth_source_plural: Tryby identyfikacji
+  label_authentication: Identyfikacja
+  label_blocked_by: blokowane przez
+  label_blocks: blokuje
+  label_board: Forum
+  label_board_new: Nowe forum
+  label_board_plural: Fora
+  label_boolean: WartoÅ›Ä‡ logiczna
+  label_browse: PrzeglÄ…d
+  label_bulk_edit_selected_issues: Zbiorowa edycja zagadnieÅ„
+  label_calendar: Kalendarz
+  label_change_plural: Zmiany
+  label_change_properties: ZmieÅ„ wÅ‚aÅ›ciwoÅ›ci
+  label_change_status: Status zmian
+  label_change_view_all: PokaÅ¼ wszystkie zmiany
+  label_changes_details: SzczegÃ³Å‚y wszystkich zmian
+  label_changeset_plural: Zestawienia zmian
+  label_chronological_order: W kolejnoÅ›ci chronologicznej
+  label_closed_issues: zamkniÄ™te
+  label_closed_issues_plural234: zamkniÄ™te
+  label_closed_issues_plural5: zamkniÄ™te
+  label_closed_issues_plural: zamkniÄ™te
+  label_x_open_issues_abbr_on_total:
+    zero:  0 otwartych / %{total}
+    one:   1 otwarty / %{total}
+    few:   "%{count} otwarte / %{total}"
+    other: "%{count} otwartych / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 otwartych
+    one:   1 otwarty
+    few:   "%{count} otwarte"
+    other: "%{count} otwartych"
+  label_x_closed_issues_abbr:
+    zero:  0 zamkniÄ™tych
+    one:   1 zamkniÄ™ty
+    few:   "%{count} zamkniÄ™te"
+    other: "%{count} zamkniÄ™tych"
+  label_comment: Komentarz
+  label_comment_add: Dodaj komentarz
+  label_comment_added: Komentarz dodany
+  label_comment_delete: UsuÅ„ komentarze
+  label_comment_plural234: Komentarze
+  label_comment_plural5: Komentarzy
+  label_comment_plural: Komentarze
+  label_x_comments:
+    zero: brak komentarzy
+    one: 1 komentarz
+    few: "%{count} komentarze"
+    other: "%{count} komentarzy"
+  label_commits_per_author: Zatwierdzenia wedÅ‚ug autorÃ³w
+  label_commits_per_month: Zatwierdzenia wedÅ‚ug miesiÄ™cy
+  label_confirmation: Potwierdzenie
+  label_contains: zawiera
+  label_copied: skopiowano
+  label_copy_workflow_from: Kopiuj przepÅ‚yw pracy z
+  label_current_status: Obecny status
+  label_current_version: Obecna wersja
+  label_custom_field: Pole niestandardowe
+  label_custom_field_new: Nowe pole niestandardowe
+  label_custom_field_plural: Pola niestandardowe
+  label_date: Data
+  label_date_from: Od
+  label_date_range: Zakres dat
+  label_date_to: Do
+  label_day_plural: dni
+  label_default: DomyÅ›lne
+  label_default_columns: DomyÅ›lne kolumny
+  label_deleted: usuniÄ™te
+  label_details: SzczegÃ³Å‚y
+  label_diff_inline: w linii
+  label_diff_side_by_side: obok siebie
+  label_disabled: zablokowany
+  label_display_per_page: "Na stronÄ™: %{value}"
+  label_document: Dokument
+  label_document_added: Dodano dokument
+  label_document_new: Nowy dokument
+  label_document_plural: Dokumenty
+  label_downloads_abbr: Pobieranie
+  label_duplicated_by: zduplikowane przez
+  label_duplicates: duplikuje
+  label_end_to_end: koniec do koÅ„ca
+  label_end_to_start: koniec do poczÄ…tku
+  label_enumeration_new: Nowa wartoÅ›Ä‡
+  label_enumerations: Wyliczenia
+  label_environment: Åšrodowisko
+  label_equals: rÃ³wna siÄ™
+  label_example: PrzykÅ‚ad
+  label_export_to: Eksportuj do
+  label_f_hour: "%{value} godzina"
+  label_f_hour_plural: "%{value} godzin"
+  label_feed_plural: IloÅ›Ä‡ Atom
+  label_feeds_access_key_created_on: "Klucz dostÄ™pu do kanaÅ‚u Atom stworzony %{value} temu"
+  label_file_added: Dodano plik
+  label_file_plural: Pliki
+  label_filter_add: Dodaj filtr
+  label_filter_plural: Filtry
+  label_float: Liczba zmiennoprzecinkowa
+  label_follows: nastÄ™puje po
+  label_gantt: Gantt
+  label_general: OgÃ³lne
+  label_generate_key: Wygeneruj klucz
+  label_help: Pomoc
+  label_history: Historia
+  label_home: GÅ‚Ã³wna
+  label_in: w
+  label_in_less_than: mniejsze niÅ¼
+  label_in_more_than: wiÄ™ksze niÅ¼
+  label_incoming_emails: PrzychodzÄ…ca poczta elektroniczna
+  label_index_by_date: Indeks wg daty
+  label_index_by_title: Indeks
+  label_information: Informacja
+  label_information_plural: Informacje
+  label_integer: Liczba caÅ‚kowita
+  label_internal: WewnÄ™trzny
+  label_issue: Zagadnienie
+  label_issue_added: Dodano zagadnienie
+  label_issue_category: Kategoria zagadnienia
+  label_issue_category_new: Nowa kategoria
+  label_issue_category_plural: Kategorie zagadnieÅ„
+  label_issue_new: Nowe zagadnienie
+  label_issue_plural: Zagadnienia
+  label_issue_status: Status zagadnienia
+  label_issue_status_new: Nowy status
+  label_issue_status_plural: Statusy zagadnieÅ„
+  label_issue_tracking: Åšledzenie zagadnieÅ„
+  label_issue_updated: Uaktualniono zagadnienie
+  label_issue_view_all: Zobacz wszystkie zagadnienia
+  label_issue_watchers: Obserwatorzy
+  label_issues_by: "Zagadnienia wprowadzone przez %{value}"
+  label_jump_to_a_project: Skocz do projektu...
+  label_language_based: Na podstawie jÄ™zyka
+  label_last_changes: "ostatnie %{count} zmian"
+  label_last_login: Ostatnie poÅ‚Ä…czenie
+  label_last_month: ostatni miesiÄ…c
+  label_last_n_days: "ostatnie %{count} dni"
+  label_last_week: ostatni tydzieÅ„
+  label_latest_revision: Najnowsza rewizja
+  label_latest_revision_plural: Najnowsze rewizje
+  label_ldap_authentication: Autoryzacja LDAP
+  label_less_than_ago: dni mniej
+  label_list: Lista
+  label_loading: Åadowanie...
+  label_logged_as: Zalogowany jako
+  label_login: Login
+  label_logout: Wylogowanie
+  label_max_size: Maksymalny rozmiar
+  label_me: ja
+  label_member: Uczestnik
+  label_member_new: Nowy uczestnik
+  label_member_plural: Uczestnicy
+  label_message_last: Ostatnia wiadomoÅ›Ä‡
+  label_message_new: Nowa wiadomoÅ›Ä‡
+  label_message_plural: WiadomoÅ›ci
+  label_message_posted: Dodano wiadomoÅ›Ä‡
+  label_min_max_length: Min - Maks dÅ‚ugoÅ›Ä‡
+  label_modified: zmodyfikowane
+  label_module_plural: ModuÅ‚y
+  label_month: MiesiÄ…c
+  label_months_from: miesiÄ…ce od
+  label_more: WiÄ™cej
+  label_more_than_ago: dni wiÄ™cej
+  label_my_account: Moje konto
+  label_my_page: Moja strona
+  label_my_projects: Moje projekty
+  label_new: Nowy
+  label_new_statuses_allowed: Uprawnione nowe statusy
+  label_news: Komunikat
+  label_news_added: Dodano komunikat
+  label_news_latest: Ostatnie komunikaty
+  label_news_new: Dodaj komunikat
+  label_news_plural: Komunikaty
+  label_news_view_all: PokaÅ¼ wszystkie komunikaty
+  label_next: NastÄ™pne
+  label_no_change_option: (Bez zmian)
+  label_no_data: Brak danych do pokazania
+  label_nobody: nikt
+  label_none: brak
+  label_not_contains: nie zawiera
+  label_not_equals: rÃ³Å¼ni siÄ™
+  label_open_issues: otwarte
+  label_open_issues_plural234: otwarte
+  label_open_issues_plural5: otwartych
+  label_open_issues_plural: otwarte
+  label_optional_description: Opcjonalny opis
+  label_options: Opcje
+  label_overall_activity: OgÃ³lna aktywnoÅ›Ä‡
+  label_overview: PrzeglÄ…d
+  label_password_lost: Zapomniane hasÅ‚o
+  label_per_page: Na stronÄ™
+  label_permissions: Uprawnienia
+  label_permissions_report: Raport uprawnieÅ„
+  label_personalize_page: Personalizuj tÄ™ stronÄ™
+  label_planning: Planowanie
+  label_please_login: Zaloguj siÄ™
+  label_plugins: Wtyczki
+  label_precedes: poprzedza
+  label_preferences: Preferencje
+  label_preview: PodglÄ…d
+  label_previous: Poprzednie
+  label_project: Projekt
+  label_project_all: Wszystkie projekty
+  label_project_latest: Ostatnie projekty
+  label_project_new: Nowy projekt
+  label_project_plural234: Projekty
+  label_project_plural5: ProjektÃ³w
+  label_project_plural: Projekty
+  label_x_projects:
+    zero:  brak projektÃ³w
+    one:   1 projekt
+    few:   "%{count} projekty"
+    other: "%{count} projektÃ³w"
+  label_public_projects: Projekty publiczne
+  label_query: Kwerenda
+  label_query_new: Nowa kwerenda
+  label_query_plural: Kwerendy
+  label_read: Czytanie...
+  label_register: Rejestracja
+  label_registered_on: Zarejestrowany
+  label_registration_activation_by_email: aktywacja konta przez e-mail
+  label_registration_automatic_activation: automatyczna aktywacja kont
+  label_registration_manual_activation: manualna aktywacja kont
+  label_related_issues: PowiÄ…zane zagadnienia
+  label_relates_to: powiÄ…zane z
+  label_relation_delete: UsuÅ„ powiÄ…zanie
+  label_relation_new: Nowe powiÄ…zanie
+  label_renamed: zmieniono nazwÄ™
+  label_reply_plural: Odpowiedzi
+  label_report: Raport
+  label_report_plural: Raporty
+  label_reported_issues: Wprowadzone zagadnienia
+  label_repository: Repozytorium
+  label_repository_plural: Repozytoria
+  label_result_plural: RezultatÃ³w
+  label_reverse_chronological_order: W kolejnoÅ›ci odwrotnej do chronologicznej
+  label_revision: Rewizja
+  label_revision_plural: Rewizje
+  label_roadmap: Mapa
+  label_roadmap_due_in: W czasie
+  label_roadmap_no_issues: Brak zagadnieÅ„ do tej wersji
+  label_roadmap_overdue: "%{value} spÃ³Åºnienia"
+  label_role: Rola
+  label_role_and_permissions: Role i uprawnienia
+  label_role_new: Nowa rola
+  label_role_plural: Role
+  label_scm: SCM
+  label_search: Szukaj
+  label_search_titles_only: Przeszukuj tylko tytuÅ‚y
+  label_send_information: WyÅ›lij informacjÄ™ uÅ¼ytkownikowi
+  label_send_test_email: WyÅ›lij prÃ³bny e-mail
+  label_settings: Ustawienia
+  label_show_completed_versions: PokaÅ¼ kompletne wersje
+  label_sort_by: "Sortuj po %{value}"
+  label_sort_higher: Do gÃ³ry
+  label_sort_highest: PrzesuÅ„ na gÃ³rÄ™
+  label_sort_lower: Do doÅ‚u
+  label_sort_lowest: PrzesuÅ„ na dÃ³Å‚
+  label_spent_time: Przepracowany czas
+  label_start_to_end: poczÄ…tek do koÅ„ca
+  label_start_to_start: poczÄ…tek do poczÄ…tku
+  label_statistics: Statystyki
+  label_stay_logged_in: PozostaÅ„ zalogowany
+  label_string: Tekst
+  label_subproject_plural: Podprojekty
+  label_text: DÅ‚ugi tekst
+  label_theme: Temat
+  label_this_month: ten miesiÄ…c
+  label_this_week: ten tydzieÅ„
+  label_this_year: ten rok
+  label_time_tracking: Åšledzenie czasu pracy
+  label_today: dzisiaj
+  label_topic_plural: Tematy
+  label_total: OgÃ³Å‚em
+  label_tracker: Typ zagadnienia
+  label_tracker_new: Nowy typ zagadnienia
+  label_tracker_plural: Typy zagadnieÅ„
+  label_updated_time: "Zaktualizowane %{value} temu"
+  label_used_by: UÅ¼ywane przez
+  label_user: UÅ¼ytkownik
+  label_user_mail_no_self_notified: "Nie chcÄ™ powiadomieÅ„ o zmianach, ktÃ³re sam wprowadzam."
+  label_user_mail_option_all: "Dla kaÅ¼dego zdarzenia w kaÅ¼dym moim projekcie"
+  label_user_mail_option_selected: "Dla kaÅ¼dego zdarzenia w wybranych projektach..."
+  label_user_new: Nowy uÅ¼ytkownik
+  label_user_plural: UÅ¼ytkownicy
+  label_version: Wersja
+  label_version_new: Nowa wersja
+  label_version_plural: Wersje
+  label_view_diff: PokaÅ¼ rÃ³Å¼nice
+  label_view_revisions: PokaÅ¼ rewizje
+  label_watched_issues: Obserwowane zagadnienia
+  label_week: TydzieÅ„
+  label_wiki: Wiki
+  label_wiki_edit: Edycja wiki
+  label_wiki_edit_plural: Edycje wiki
+  label_wiki_page: Strona wiki
+  label_wiki_page_plural: Strony wiki
+  label_workflow: PrzepÅ‚yw pracy
+  label_year: Rok
+  label_yesterday: wczoraj
+  mail_body_account_activation_request: "Zarejestrowano nowego uÅ¼ytkownika: (%{value}). Konto oczekuje na twoje zatwierdzenie:"
+  mail_body_account_information: Twoje konto
+  mail_body_account_information_external: "MoÅ¼esz uÅ¼yÄ‡ Twojego konta %{value} do zalogowania."
+  mail_body_lost_password: 'W celu zmiany swojego hasÅ‚a uÅ¼yj poniÅ¼szego odnoÅ›nika:'
+  mail_body_register: 'W celu aktywacji Twojego konta, uÅ¼yj poniÅ¼szego odnoÅ›nika:'
+  mail_body_reminder: "Wykaz przypisanych do Ciebie zagadnieÅ„, ktÃ³rych termin wypada w ciÄ…gu nastÄ™pnych %{count} dni"
+  mail_subject_account_activation_request: "Zapytanie aktywacyjne konta %{value}"
+  mail_subject_lost_password: "Twoje hasÅ‚o do %{value}"
+  mail_subject_register: "Aktywacja konta w %{value}"
+  mail_subject_reminder: "Uwaga na terminy, masz zagadnienia do obsÅ‚uÅ¼enia w ciÄ…gu nastÄ™pnych %{count} dni! (%{days})"
+  notice_account_activated: Twoje konto zostaÅ‚o aktywowane. MoÅ¼esz siÄ™ zalogowaÄ‡.
+  notice_account_invalid_creditentials: ZÅ‚y uÅ¼ytkownik lub hasÅ‚o
+  notice_account_lost_email_sent: E-mail z instrukcjami zmiany hasÅ‚a zostaÅ‚ wysÅ‚any do Ciebie.
+  notice_account_password_updated: HasÅ‚o prawidÅ‚owo zmienione.
+  notice_account_pending: "Twoje konto zostaÅ‚o utworzone i oczekuje na zatwierdzenie administratora."
+  notice_account_register_done: Konto prawidÅ‚owo utworzone.
+  notice_account_unknown_email: Nieznany uÅ¼ytkownik.
+  notice_account_updated: Konto prawidÅ‚owo zaktualizowane.
+  notice_account_wrong_password: ZÅ‚e hasÅ‚o
+  notice_can_t_change_password: To konto ma zewnÄ™trzne ÅºrÃ³dÅ‚o identyfikacji. Nie moÅ¼esz zmieniÄ‡ hasÅ‚a.
+  notice_default_data_loaded: DomyÅ›lna konfiguracja zostaÅ‚a pomyÅ›lnie zaÅ‚adowana.
+  notice_email_error: "WystÄ…piÅ‚ bÅ‚Ä…d w trakcie wysyÅ‚ania e-maila (%{value})"
+  notice_email_sent: "E-mail zostaÅ‚ wysÅ‚any do %{value}"
+  notice_failed_to_save_issues: "BÅ‚Ä…d podczas zapisu zagadnieÅ„ %{count} z %{total} zaznaczonych: %{ids}."
+  notice_feeds_access_key_reseted: TwÃ³j klucz dostÄ™pu do kanaÅ‚u Atom zostaÅ‚ zresetowany.
+  notice_file_not_found: Strona do ktÃ³rej prÃ³bujesz siÄ™ dostaÄ‡ nie istnieje lub zostaÅ‚a usuniÄ™ta.
+  notice_locking_conflict: Dane poprawione przez innego uÅ¼ytkownika.
+  notice_no_issue_selected: "Nie wybrano zagadnienia! Zaznacz zagadnienie, ktÃ³re chcesz edytowaÄ‡."
+  notice_not_authorized: Nie posiadasz autoryzacji do oglÄ…dania tej strony.
+  notice_successful_connection: Udane nawiÄ…zanie poÅ‚Ä…czenia.
+  notice_successful_create: Utworzenie zakoÅ„czone sukcesem.
+  notice_successful_delete: UsuniÄ™cie zakoÅ„czone sukcesem.
+  notice_successful_update: Uaktualnienie zakoÅ„czone sukcesem.
+  notice_unable_delete_version: Nie moÅ¼na usunÄ…Ä‡ wersji
+  permission_add_issue_notes: Dodawanie notatek
+  permission_add_issue_watchers: Dodawanie obserwatorÃ³w
+  permission_add_issues: Dodawanie zagadnieÅ„
+  permission_add_messages: Dodawanie wiadomoÅ›ci
+  permission_browse_repository: PrzeglÄ…danie repozytorium
+  permission_comment_news: Komentowanie komunikatÃ³w
+  permission_commit_access: Wykonywanie zatwierdzeÅ„
+  permission_delete_issues: Usuwanie zagadnieÅ„
+  permission_delete_messages: Usuwanie wiadomoÅ›ci
+  permission_delete_wiki_pages: Usuwanie stron wiki
+  permission_delete_wiki_pages_attachments: Usuwanie zaÅ‚Ä…cznikÃ³w
+  permission_delete_own_messages: Usuwanie wÅ‚asnych wiadomoÅ›ci
+  permission_edit_issue_notes: Edycja notatek
+  permission_edit_issues: Edycja zagadnieÅ„
+  permission_edit_messages: Edycja wiadomoÅ›ci
+  permission_edit_own_issue_notes: Edycja wÅ‚asnych notatek
+  permission_edit_own_messages: Edycja wÅ‚asnych wiadomoÅ›ci
+  permission_edit_own_time_entries: Edycja wÅ‚asnego dziennika
+  permission_edit_project: Edycja projektÃ³w
+  permission_edit_time_entries: Edycja wpisÃ³w dziennika
+  permission_edit_wiki_pages: Edycja stron wiki
+  permission_log_time: Zapisywanie przepracowanego czasu
+  permission_manage_boards: ZarzÄ…dzanie forami
+  permission_manage_categories: ZarzÄ…dzanie kategoriami zagadnieÅ„
+  permission_manage_files: ZarzÄ…dzanie plikami
+  permission_manage_issue_relations: ZarzÄ…dzanie powiÄ…zaniami zagadnieÅ„
+  permission_manage_members: ZarzÄ…dzanie uczestnikami
+  permission_manage_news: ZarzÄ…dzanie komunikatami
+  permission_manage_public_queries: ZarzÄ…dzanie publicznymi kwerendami
+  permission_manage_repository: ZarzÄ…dzanie repozytorium
+  permission_manage_versions: ZarzÄ…dzanie wersjami
+  permission_manage_wiki: ZarzÄ…dzanie wiki
+  permission_move_issues: Przenoszenie zagadnieÅ„
+  permission_protect_wiki_pages: Blokowanie stron wiki
+  permission_rename_wiki_pages: Zmiana nazw stron wiki
+  permission_save_queries: Zapisywanie kwerend
+  permission_select_project_modules: Wybieranie moduÅ‚Ã³w projektu
+  permission_view_calendar: PodglÄ…d kalendarza
+  permission_view_changesets: PodglÄ…d zmian
+  permission_view_documents: PodglÄ…d dokumentÃ³w
+  permission_view_files: PodglÄ…d plikÃ³w
+  permission_view_gantt: PodglÄ…d diagramu Gantta
+  permission_view_issue_watchers: PodglÄ…d listy obserwatorÃ³w
+  permission_view_messages: PodglÄ…d wiadomoÅ›ci
+  permission_view_time_entries: PodglÄ…d przepracowanego czasu
+  permission_view_wiki_edits: PodglÄ…d historii wiki
+  permission_view_wiki_pages: PodglÄ…d wiki
+  project_module_boards: Fora
+  project_module_documents: Dokumenty
+  project_module_files: Pliki
+  project_module_issue_tracking: Åšledzenie zagadnieÅ„
+  project_module_news: Komunikaty
+  project_module_repository: Repozytorium
+  project_module_time_tracking: Åšledzenie czasu pracy
+  project_module_wiki: Wiki
+  setting_activity_days_default: Dni wyÅ›wietlane w aktywnoÅ›ci projektu
+  setting_app_subtitle: PodtytuÅ‚ aplikacji
+  setting_app_title: TytuÅ‚ aplikacji
+  setting_attachment_max_size: Maks. rozm. zaÅ‚Ä…cznika
+  setting_autofetch_changesets: Automatyczne pobieranie zmian
+  setting_autologin: Automatyczne logowanie
+  setting_bcc_recipients: Odbiorcy kopii tajnej (kt/bcc)
+  setting_commit_fix_keywords: SÅ‚owa zmieniajÄ…ce status
+  setting_commit_ref_keywords: SÅ‚owa tworzÄ…ce powiÄ…zania
+  setting_cross_project_issue_relations: ZezwÃ³l na powiÄ…zania zagadnieÅ„ miÄ™dzy projektami
+  setting_date_format: Format daty
+  setting_default_language: DomyÅ›lny jÄ™zyk
+  setting_default_projects_public: Nowe projekty sÄ… domyÅ›lnie publiczne
+  setting_display_subprojects_issues: DomyÅ›lnie pokazuj zagadnienia podprojektÃ³w w gÅ‚Ã³wnym projekcie
+  setting_emails_footer: Stopka e-mail
+  setting_enabled_scm: DostÄ™pny SCM
+  setting_feeds_limit: Limit danych Atom
+  setting_gravatar_enabled: UÅ¼ywaj ikon uÅ¼ytkownikÃ³w Gravatar
+  setting_host_name: Nazwa hosta i Å›cieÅ¼ka
+  setting_issue_list_default_columns: DomyÅ›lne kolumny wyÅ›wietlane na liÅ›cie zagadnieÅ„
+  setting_issues_export_limit: Limit eksportu zagadnieÅ„
+  setting_login_required: Wymagane zalogowanie
+  setting_mail_from: Adres e-mail wysyÅ‚ki
+  setting_mail_handler_api_enabled: Uaktywnij usÅ‚ugi sieciowe (WebServices) dla poczty przychodzÄ…cej
+  setting_mail_handler_api_key: Klucz API
+  setting_per_page_options: Opcje iloÅ›ci obiektÃ³w na stronie
+  setting_plain_text_mail: tylko tekst (bez HTML)
+  setting_protocol: ProtokÃ³Å‚
+  setting_self_registration: Samodzielna rejestracja uÅ¼ytkownikÃ³w
+  setting_sequential_project_identifiers: Generuj sekwencyjne identyfikatory projektÃ³w
+  setting_sys_api_enabled: WÅ‚Ä…czenie WS do zarzÄ…dzania repozytorium
+  setting_text_formatting: Formatowanie tekstu
+  setting_time_format: Format czasu
+  setting_user_format: WÅ‚asny format wyÅ›wietlania
+  setting_welcome_text: Tekst powitalny
+  setting_wiki_compression: Kompresja historii Wiki
+  status_active: aktywny
+  status_locked: zablokowany
+  status_registered: zarejestrowany
+  text_are_you_sure: JesteÅ› pewien ?
+  text_assign_time_entries_to_project: Przypisz wpisy dziennika do projektu
+  text_caracters_maximum: "%{count} znakÃ³w maksymalnie."
+  text_caracters_minimum: "Musi byÄ‡ nie krÃ³tsze niÅ¼ %{count} znakÃ³w."
+  text_comma_separated: Dozwolone wielokrotne wartoÅ›ci (rozdzielone przecinkami).
+  text_default_administrator_account_changed: Zmieniono domyÅ›lne hasÅ‚o administratora
+  text_destroy_time_entries: UsuÅ„ wpisy dziennika
+  text_destroy_time_entries_question: Przepracowano %{hours} godzin przy zagadnieniu, ktÃ³re chcesz usunÄ…Ä‡. Co chcesz zrobiÄ‡?
+  text_email_delivery_not_configured: "Dostarczanie poczty elektronicznej nie zostaÅ‚o skonfigurowane, wiÄ™c powiadamianie jest nieaktywne.\nSkonfiguruj serwer SMTP w config/email.yml a nastÄ™pnie zrestartuj aplikacjÄ™ i uaktywnij to."
+  text_enumeration_category_reassign_to: 'ZmieÅ„ przypisanie na tÄ… wartoÅ›Ä‡:'
+  text_enumeration_destroy_question: "%{count} obiektÃ³w jest przypisanych do tej wartoÅ›ci."
+  text_file_repository_writable: Zapisywalne repozytorium plikÃ³w
+  text_issue_added: "Zagadnienie %{id} zostaÅ‚o wprowadzone (przez %{author})."
+  text_issue_category_destroy_assignments: UsuÅ„ przydziaÅ‚y kategorii
+  text_issue_category_destroy_question: "Do tej kategorii sÄ… przypisane zagadnienia (%{count}). Co chcesz zrobiÄ‡?"
+  text_issue_category_reassign_to: Przydziel zagadnienie do tej kategorii
+  text_issue_updated: "Zagadnienie %{id} zostaÅ‚o zaktualizowane (przez %{author})."
+  text_issues_destroy_confirmation: 'Czy jesteÅ› pewien, Å¼e chcesz usunÄ…Ä‡ wskazane zagadnienia?'
+  text_issues_ref_in_commit_messages: OdwoÅ‚ania do zagadnieÅ„ w komentarzach zatwierdzeÅ„
+  text_length_between: "DÅ‚ugoÅ›Ä‡ pomiÄ™dzy %{min} i %{max} znakÃ³w."
+  text_load_default_configuration: ZaÅ‚aduj domyÅ›lnÄ… konfiguracjÄ™
+  text_min_max_length_info: 0 oznacza brak restrykcji
+  text_no_configuration_data: "Role uÅ¼ytkownikÃ³w, typy zagadnieÅ„, statusy zagadnieÅ„ oraz przepÅ‚yw pracy nie zostaÅ‚y jeszcze skonfigurowane.\nWysoce zalecane jest by zaÅ‚adowaÄ‡ domyÅ›lnÄ… konfiguracjÄ™. Po zaÅ‚adowaniu bÄ™dzie moÅ¼liwoÅ›Ä‡ edycji tych danych."
+  text_project_destroy_confirmation: JesteÅ› pewien, Å¼e chcesz usunÄ…Ä‡ ten projekt i wszystkie powiÄ…zane dane?
+  text_reassign_time_entries: 'Przepnij przepracowany czas do tego zagadnienia:'
+  text_regexp_info: np. ^[A-Z0-9]+$
+  text_repository_usernames_mapping: "Wybierz lub uaktualnij przyporzÄ…dkowanie uÅ¼ytkownikÃ³w Redmine do uÅ¼ytkownikÃ³w repozytorium.\nUÅ¼ytkownicy z takÄ… samÄ… nazwÄ… lub adresem e-mail sÄ… przyporzÄ…dkowani automatycznie."
+  text_rmagick_available: RMagick dostÄ™pne (opcjonalnie)
+  text_select_mail_notifications: Zaznacz czynnoÅ›ci przy ktÃ³rych uÅ¼ytkownik powinien byÄ‡ powiadomiony e-mailem.
+  text_select_project_modules: 'Wybierz moduÅ‚y do aktywacji w tym projekcie:'
+  text_status_changed_by_changeset: "Zastosowane w zmianach %{value}."
+  text_subprojects_destroy_warning: "Podprojekt(y): %{value} zostanÄ… takÅ¼e usuniÄ™te."
+  text_tip_issue_begin_day: zadanie zaczynajÄ…ce siÄ™ dzisiaj
+  text_tip_issue_begin_end_day: zadanie zaczynajÄ…ce i koÅ„czÄ…ce siÄ™ dzisiaj
+  text_tip_issue_end_day: zadanie koÅ„czÄ…ce siÄ™ dzisiaj
+  text_tracker_no_workflow: Brak przepÅ‚ywu pracy zdefiniowanego dla tego typu zagadnienia
+  text_unallowed_characters: Niedozwolone znaki
+  text_user_mail_option: "W przypadku niezaznaczonych projektÃ³w, bÄ™dziesz otrzymywaÅ‚ powiadomienia tylko na temat zagadnieÅ„ ktÃ³re obserwujesz, lub w ktÃ³rych bierzesz udziaÅ‚ (np. jesteÅ› autorem lub adresatem)."
+  text_user_wrote: "%{value} napisaÅ‚(a):"
+  text_wiki_destroy_confirmation: JesteÅ› pewien, Å¼e chcesz usunÄ…Ä‡ to wiki i caÅ‚Ä… jego zawartoÅ›Ä‡?
+  text_workflow_edit: Zaznacz rolÄ™ i typ zagadnienia do edycji przepÅ‚ywu pracy
+
+  label_user_activity: "AktywnoÅ›Ä‡: %{value}"
+  label_updated_time_by: "Uaktualnione przez %{author} %{age} temu"
+  text_diff_truncated: '... Ten plik rÃ³Å¼nic zostaÅ‚ przyciÄ™ty poniewaÅ¼ jest zbyt dÅ‚ugi.'
+  setting_diff_max_lines_displayed: Maksymalna liczba linii rÃ³Å¼nicy do pokazania
+  text_plugin_assets_writable: Zapisywalny katalog zasobÃ³w wtyczek
+  warning_attachments_not_saved: "%{count} zaÅ‚Ä…cznik(Ã³w) nie zostaÅ‚o zapisanych."
+  field_editable: Edytowalne
+  label_display: WyglÄ…d
+  button_create_and_continue: StwÃ³rz i dodaj kolejne
+  text_custom_field_possible_values_info: 'KaÅ¼da wartoÅ›Ä‡ w osobnej linii'
+  setting_repository_log_display_limit: Maksymalna liczba rewizji pokazywanych w logu pliku
+  setting_file_max_size_displayed: Maksymalny rozmiar plikÃ³w tekstowych osadzanych w stronie
+  field_watcher: Obserwator
+  setting_openid: Logowanie i rejestracja przy uÅ¼yciu OpenID
+  field_identity_url: Identyfikator OpenID (URL)
+  label_login_with_open_id_option: albo uÅ¼yj OpenID
+  field_content: TreÅ›Ä‡
+  label_descending: MalejÄ…co
+  label_sort: Sortuj
+  label_ascending: RosnÄ…co
+  label_date_from_to: Od %{start} do %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Ta strona posiada podstrony (%{descendants}). Co chcesz zrobiÄ‡?
+  text_wiki_page_reassign_children: Podepnij je do strony nadrzÄ™dnej wzglÄ™dem usuwanej
+  text_wiki_page_nullify_children: PrzesuÅ„ je na szczyt hierarchii
+  text_wiki_page_destroy_children: UsuÅ„ wszystkie podstrony
+  setting_password_min_length: Minimalna dÅ‚ugoÅ›Ä‡ hasÅ‚a
+  field_group_by: Grupuj wyniki wg
+  mail_subject_wiki_content_updated: "Strona wiki '%{id}' zostaÅ‚a uaktualniona"
+  label_wiki_content_added: Dodano stronÄ™ wiki
+  mail_subject_wiki_content_added: "Strona wiki '%{id}' zostaÅ‚a dodana"
+  mail_body_wiki_content_added: Strona wiki '%{id}' zostaÅ‚a dodana przez %{author}.
+  label_wiki_content_updated: Uaktualniono stronÄ™ wiki
+  mail_body_wiki_content_updated: Strona wiki '%{id}' zostaÅ‚a uaktualniona przez %{author}.
+  permission_add_project: Tworzenie projektu
+  setting_new_project_user_role_id: Rola nadawana twÃ³rcom projektÃ³w, ktÃ³rzy nie posiadajÄ… uprawnieÅ„ administatora
+  label_view_all_revisions: PokaÅ¼ wszystkie rewizje
+  label_tag: SÅ‚owo kluczowe
+  label_branch: GaÅ‚Ä…Åº
+  error_no_tracker_in_project: Projekt nie posiada powiÄ…zanych typÃ³w zagadnieÅ„. SprawdÅº ustawienia projektu.
+  error_no_default_issue_status: Nie zdefiniowano domyÅ›lnego statusu zagadnieÅ„. SprawdÅº konfiguracjÄ™ (PrzejdÅº do "Administracja -> Statusy zagadnieÅ„").
+  text_journal_changed: "Zmieniono %{label} z %{old} na %{new}"
+  text_journal_set_to: "Ustawiono %{label} na %{value}"
+  text_journal_deleted: "UsuniÄ™to %{label} (%{old})"
+  label_group_plural: Grupy
+  label_group: Grupa
+  label_group_new: Nowa grupa
+  label_time_entry_plural: Przepracowany czas
+  text_journal_added: "Dodano %{label} %{value}"
+  field_active: Aktywne
+  enumeration_system_activity: AktywnoÅ›Ä‡ systemowa
+  button_copy_and_follow: Kopiuj i przejdÅº do kopii zagadnienia
+  button_duplicate: Duplikuj
+  button_move_and_follow: PrzenieÅ› i przejdÅº do zagadnienia
+  button_show: PokaÅ¼
+  error_can_not_archive_project: Ten projekt nie moÅ¼e zostaÄ‡ zarchiwizowany
+  error_can_not_reopen_issue_on_closed_version: Zagadnienie przydzielone do zakoÅ„czonej wersji nie moÅ¼e zostaÄ‡ ponownie otwarte
+  error_issue_done_ratios_not_updated: "% wykonania zagadnienia nie zostaÅ‚ uaktualniony."
+  error_workflow_copy_source: ProszÄ™ wybraÄ‡ ÅºrÃ³dÅ‚owy typ zagadnienia lub rolÄ™
+  error_workflow_copy_target: ProszÄ™ wybraÄ‡ docelowe typ(y) zagadnieÅ„ i rolÄ™(e)
+  field_sharing: WspÃ³Å‚dzielenie
+  label_api_access_key: Klucz dostÄ™pu do API
+  label_api_access_key_created_on: Klucz dostÄ™pu do API zostaÅ‚ utworzony %{value} temu
+  label_close_versions: Zamknij ukoÅ„czone wersje
+  label_copy_same_as_target: Jak cel
+  label_copy_source: Å¹rÃ³dÅ‚o
+  label_copy_target: Cel
+  label_display_used_statuses_only: WyÅ›wietlaj tylko statusy uÅ¼ywane przez ten typ zagadnienia
+  label_feeds_access_key: Klucz dostÄ™pu do kanaÅ‚u Atom
+  label_missing_api_access_key: Brakuje klucza dostÄ™pu do API
+  label_missing_feeds_access_key: Brakuje klucza dostÄ™pu do kanaÅ‚u Atom
+  label_revision_id: Rewizja %{value}
+  label_subproject_new: Nowy podprojekt
+  label_update_issue_done_ratios: Uaktualnij % wykonania
+  label_user_anonymous: Anonimowy
+  label_version_sharing_descendants: Z podprojektami
+  label_version_sharing_hierarchy: Z hierarchiÄ… projektÃ³w
+  label_version_sharing_none: Brak wspÃ³Å‚dzielenia
+  label_version_sharing_system: Ze wszystkimi projektami
+  label_version_sharing_tree: Z drzewem projektÃ³w
+  notice_api_access_key_reseted: TwÃ³j klucz dostÄ™pu do API zostaÅ‚ zresetowany.
+  notice_issue_done_ratios_updated: Uaktualnienie % wykonania zakoÅ„czone sukcesem.
+  permission_add_subprojects: Tworzenie podprojektÃ³w
+  permission_delete_issue_watchers: UsuÅ„ obserwatorÃ³w
+  permission_view_issues: PrzeglÄ…danie zagadnieÅ„
+  setting_default_projects_modules: DomyÅ›lnie wÅ‚Ä…czone moduÅ‚y dla nowo tworzonych projektÃ³w
+  setting_gravatar_default: DomyÅ›lny obraz Gravatar
+  setting_issue_done_ratio: Obliczaj postÄ™p realizacji zagadnieÅ„ za pomocÄ…
+  setting_issue_done_ratio_issue_field: "% Wykonania zagadnienia"
+  setting_issue_done_ratio_issue_status: Statusu zagadnienia
+  setting_mail_handler_body_delimiters: Przycinaj e-maile po jednej z tych linii
+  setting_rest_api_enabled: Uaktywnij usÅ‚ugÄ™ sieciowÄ… REST
+  setting_start_of_week: Pierwszy dzieÅ„ tygodnia
+  text_line_separated: Dozwolone jest wiele wartoÅ›ci (kaÅ¼da wartoÅ›Ä‡ w osobnej linii).
+  text_own_membership_delete_confirmation: |-
+    Masz zamiar usunÄ…Ä‡ niektÃ³re lub wszystkie swoje uprawnienia. Po wykonaniu tej czynnoÅ›ci moÅ¼esz utraciÄ‡ moÅ¼liwoÅ›ci edycji tego projektu.
+    Czy na pewno chcesz kontynuowaÄ‡?
+  version_status_closed: zamkniÄ™ta
+  version_status_locked: zablokowana
+  version_status_open: otwarta
+
+  label_board_sticky: Przyklejona
+  label_board_locked: ZamkniÄ™ta
+  permission_export_wiki_pages: Eksport stron wiki
+  permission_manage_project_activities: ZarzÄ…dzanie aktywnoÅ›ciami projektu
+  setting_cache_formatted_text: Buforuj sformatowany tekst
+  error_unable_delete_issue_status: Nie moÅ¼na usunÄ…Ä‡ statusu zagadnienia
+  label_profile: Profil
+  permission_manage_subtasks: ZarzÄ…dzanie podzagadnieniami
+  field_parent_issue: Zagadnienie nadrzÄ™dne
+  label_subtask_plural: Podzagadnienia
+  label_project_copy_notifications: WyÅ›lij powiadomienia e-mailowe przy kopiowaniu projektu
+  error_can_not_delete_custom_field: Nie moÅ¼na usunÄ…Ä‡ tego pola
+  error_unable_to_connect: Nie moÅ¼na poÅ‚Ä…czyÄ‡ (%{value})
+  error_can_not_remove_role: Ta rola przypisana jest niektÃ³rym uÅ¼ytkownikom i nie moÅ¼e zostaÄ‡ usuniÄ™ta.
+  error_can_not_delete_tracker: Ten typ przypisany jest do czÄ™Å›ci zagadnieÅ„ i nie moÅ¼e zostaÄ‡ usuniÄ™ty.
+  field_principal: PrzeÅ‚oÅ¼ony
+  label_my_page_block: Elementy
+  notice_failed_to_save_members: "Nie moÅ¼na zapisaÄ‡ uczestnikÃ³w: %{errors}."
+  text_zoom_out: Zmniejsz
+  text_zoom_in: PowiÄ™ksz
+  notice_unable_delete_time_entry: Nie moÅ¼na usunÄ…Ä‡ wpisu z dziennika.
+  label_overall_spent_time: Przepracowany czas
+  field_time_entries: Dziennik
+  project_module_gantt: Diagram Gantta
+  project_module_calendar: Kalendarz
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: "Tylko to, co obserwujÄ™ lub w czym biorÄ™ udziaÅ‚"
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Szukaj uÅ¼ytkownika lub grupy:"
+  label_user_search: "Szukaj uÅ¼ytkownika:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Kodowanie komentarzy zatwierdzeÅ„
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 zagadnienie
+    one:   1 zagadnienie
+    other: "%{count} zagadnienia"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: 'Dozwolone maÅ‚e litery (a-z), liczby i myÅ›lniki.<br />Raz zapisany, identyfikator nie moÅ¼e byÄ‡ zmieniony.'
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: wszystko
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Z podprojektami
+  label_cross_project_tree: Z drzewem projektÃ³w
+  label_cross_project_hierarchy: Z hierarchiÄ… projektÃ³w
+  label_cross_project_system: Ze wszystkimi projektami
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: OgÃ³Å‚em
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5d/5d3d445e6a2c90ebc1a3730a84d68683aaccf4dc.svn-base
--- a/.svn/pristine/5d/5d3d445e6a2c90ebc1a3730a84d68683aaccf4dc.svn-base
+++ /dev/null
@@ -1,4 +0,0 @@
-require File.expand_path('../../../test_helper', __FILE__)
-
-class IssueMovesHelperTest < ActionView::TestCase
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5d/5d49f8300d8c88036656ba3ee811b034c32e1e91.svn-base
--- /dev/null
+++ b/.svn/pristine/5d/5d49f8300d8c88036656ba3ee811b034c32e1e91.svn-base
@@ -0,0 +1,23 @@
+module Redmine
+  module Scm
+    class Base
+      class << self
+
+        def all
+          @scms || []
+        end
+
+        # Add a new SCM adapter and repository
+        def add(scm_name)
+          @scms ||= []
+          @scms << scm_name
+        end
+
+        # Remove a SCM adapter from Redmine's list of supported scms
+        def delete(scm_name)
+          @scms.delete(scm_name)
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5d/5d94857704d99231f1b0ea1e206666d924acf9ab.svn-base
--- a/.svn/pristine/5d/5d94857704d99231f1b0ea1e206666d924acf9ab.svn-base
+++ /dev/null
@@ -1,284 +0,0 @@
-module CodeRay
-  
-  # = PluginHost
-  #
-  # A simple subclass/subfolder plugin system.
-  #
-  # Example:
-  #  class Generators
-  #    extend PluginHost
-  #    plugin_path 'app/generators'
-  #  end
-  #  
-  #  class Generator
-  #    extend Plugin
-  #    PLUGIN_HOST = Generators
-  #  end
-  #  
-  #  class FancyGenerator < Generator
-  #    register_for :fancy
-  #  end
-  #  
-  #  Generators[:fancy]  #-> FancyGenerator
-  #  # or
-  #  CodeRay.require_plugin 'Generators/fancy'
-  #  # or
-  #  Generators::Fancy
-  module PluginHost
-    
-    # Raised if Encoders::[] fails because:
-    # * a file could not be found
-    # * the requested Plugin is not registered
-    PluginNotFound = Class.new LoadError
-    HostNotFound = Class.new LoadError
-    
-    PLUGIN_HOSTS = []
-    PLUGIN_HOSTS_BY_ID = {}  # dummy hash
-    
-    # Loads all plugins using list and load.
-    def load_all
-      for plugin in list
-        load plugin
-      end
-    end
-    
-    # Returns the Plugin for +id+.
-    #
-    # Example:
-    #  yaml_plugin = MyPluginHost[:yaml]
-    def [] id, *args, &blk
-      plugin = validate_id(id)
-      begin
-        plugin = plugin_hash.[] plugin, *args, &blk
-      end while plugin.is_a? Symbol
-      plugin
-    end
-    
-    alias load []
-    
-    # Tries to +load+ the missing plugin by translating +const+ to the
-    # underscore form (eg. LinesOfCode becomes lines_of_code).
-    def const_missing const
-      id = const.to_s.
-        gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
-        gsub(/([a-z\d])([A-Z])/,'\1_\2').
-        downcase
-      load id
-    end
-    
-    class << self
-      
-      # Adds the module/class to the PLUGIN_HOSTS list.
-      def extended mod
-        PLUGIN_HOSTS << mod
-      end
-      
-    end
-    
-    # The path where the plugins can be found.
-    def plugin_path *args
-      unless args.empty?
-        @plugin_path = File.expand_path File.join(*args)
-      end
-      @plugin_path ||= ''
-    end
-    
-    # Map a plugin_id to another.
-    #
-    # Usage: Put this in a file plugin_path/_map.rb.
-    #
-    #  class MyColorHost < PluginHost
-    #    map :navy => :dark_blue,
-    #      :maroon => :brown,
-    #      :luna => :moon
-    #  end
-    def map hash
-      for from, to in hash
-        from = validate_id from
-        to = validate_id to
-        plugin_hash[from] = to unless plugin_hash.has_key? from
-      end
-    end
-    
-    # Define the default plugin to use when no plugin is found
-    # for a given id, or return the default plugin.
-    #
-    # See also map.
-    #
-    #  class MyColorHost < PluginHost
-    #    map :navy => :dark_blue
-    #    default :gray
-    #  end
-    #  
-    #  MyColorHost.default  # loads and returns the Gray plugin
-    def default id = nil
-      if id
-        id = validate_id id
-        raise "The default plugin can't be named \"default\"." if id == :default
-        plugin_hash[:default] = id
-      else
-        load :default
-      end
-    end
-    
-    # Every plugin must register itself for +id+ by calling register_for,
-    # which calls this method.
-    #
-    # See Plugin#register_for.
-    def register plugin, id
-      plugin_hash[validate_id(id)] = plugin
-    end
-    
-    # A Hash of plugion_id => Plugin pairs.
-    def plugin_hash
-      @plugin_hash ||= make_plugin_hash
-    end
-    
-    # Returns an array of all .rb files in the plugin path.
-    #
-    # The extension .rb is not included.
-    def list
-      Dir[path_to('*')].select do |file|
-        File.basename(file)[/^(?!_)\w+\.rb$/]
-      end.map do |file|
-        File.basename(file, '.rb').to_sym
-      end
-    end
-    
-    # Returns an array of all Plugins.
-    # 
-    # Note: This loads all plugins using load_all.
-    def all_plugins
-      load_all
-      plugin_hash.values.grep(Class)
-    end
-    
-    # Loads the map file (see map).
-    #
-    # This is done automatically when plugin_path is called.
-    def load_plugin_map
-      mapfile = path_to '_map'
-      @plugin_map_loaded = true
-      if File.exist? mapfile
-        require mapfile
-        true
-      else
-        false
-      end
-    end
-    
-  protected
-    
-    # Return a plugin hash that automatically loads plugins.
-    def make_plugin_hash
-      @plugin_map_loaded ||= false
-      Hash.new do |h, plugin_id|
-        id = validate_id(plugin_id)
-        path = path_to id
-        begin
-          raise LoadError, "#{path} not found" unless File.exist? path
-          require path
-        rescue LoadError => boom
-          if @plugin_map_loaded
-            if h.has_key?(:default)
-              warn '%p could not load plugin %p; falling back to %p' % [self, id, h[:default]]
-              h[:default]
-            else
-              raise PluginNotFound, '%p could not load plugin %p: %s' % [self, id, boom]
-            end
-          else
-            load_plugin_map
-            h[plugin_id]
-          end
-        else
-          # Plugin should have registered by now
-          if h.has_key? id
-            h[id]
-          else
-            raise PluginNotFound, "No #{self.name} plugin for #{id.inspect} found in #{path}."
-          end
-        end
-      end
-    end
-    
-    # Returns the expected path to the plugin file for the given id.
-    def path_to plugin_id
-      File.join plugin_path, "#{plugin_id}.rb"
-    end
-    
-    # Converts +id+ to a Symbol if it is a String,
-    # or returns +id+ if it already is a Symbol.
-    #
-    # Raises +ArgumentError+ for all other objects, or if the
-    # given String includes non-alphanumeric characters (\W).
-    def validate_id id
-      if id.is_a? Symbol or id.nil?
-        id
-      elsif id.is_a? String
-        if id[/\w+/] == id
-          id.downcase.to_sym
-        else
-          raise ArgumentError, "Invalid id given: #{id}"
-        end
-      else
-        raise ArgumentError, "String or Symbol expected, but #{id.class} given."
-      end
-    end
-    
-  end
-  
-  
-  # = Plugin
-  #
-  #  Plugins have to include this module.
-  #
-  #  IMPORTANT: Use extend for this module.
-  #
-  #  See CodeRay::PluginHost for examples.
-  module Plugin
-    
-    attr_reader :plugin_id
-    
-    # Register this class for the given +id+.
-    # 
-    # Example:
-    #   class MyPlugin < PluginHost::BaseClass
-    #     register_for :my_id
-    #     ...
-    #   end
-    #
-    # See PluginHost.register.
-    def register_for id
-      @plugin_id = id
-      plugin_host.register self, id
-    end
-    
-    # Returns the title of the plugin, or sets it to the
-    # optional argument +title+.
-    def title title = nil
-      if title
-        @title = title.to_s
-      else
-        @title ||= name[/([^:]+)$/, 1]
-      end
-    end
-    
-    # The PluginHost for this Plugin class.
-    def plugin_host host = nil
-      if host.is_a? PluginHost
-        const_set :PLUGIN_HOST, host
-      end
-      self::PLUGIN_HOST
-    end
-    
-    def aliases
-      plugin_host.load_plugin_map
-      plugin_host.plugin_hash.inject [] do |aliases, (key, _)|
-        aliases << key if plugin_host[key] == self
-        aliases
-      end
-    end
-    
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5d/5da0b4c4bee024389ce63f0775bf42e759cc86ef.svn-base
--- a/.svn/pristine/5d/5da0b4c4bee024389ce63f0775bf42e759cc86ef.svn-base
+++ /dev/null
@@ -1,52 +0,0 @@
-
-require File.expand_path('../../../../../../test_helper', __FILE__)
-
-class FilesystemAdapterTest < ActiveSupport::TestCase
-  REPOSITORY_PATH = Rails.root.join('tmp/test/filesystem_repository').to_s
-
-  if File.directory?(REPOSITORY_PATH)
-    def setup
-      @adapter = Redmine::Scm::Adapters::FilesystemAdapter.new(REPOSITORY_PATH)
-    end
-
-    def test_entries
-      assert_equal 3, @adapter.entries.size
-      assert_equal ["dir", "japanese", "test"], @adapter.entries.collect(&:name)
-      assert_equal ["dir", "japanese", "test"], @adapter.entries(nil).collect(&:name)
-      assert_equal ["dir", "japanese", "test"], @adapter.entries("/").collect(&:name)
-      ["dir", "/dir", "/dir/", "dir/"].each do |path|
-        assert_equal ["subdir", "dirfile"], @adapter.entries(path).collect(&:name)
-      end
-      # If y try to use "..", the path is ignored
-      ["/../","dir/../", "..", "../", "/..", "dir/.."].each do |path|
-        assert_equal ["dir", "japanese", "test"], @adapter.entries(path).collect(&:name),
-             ".. must be ignored in path argument"
-      end
-    end
-
-    def test_cat
-      assert_equal "TEST CAT\n", @adapter.cat("test")
-      assert_equal "TEST CAT\n", @adapter.cat("/test")
-      # Revision number is ignored
-      assert_equal "TEST CAT\n", @adapter.cat("/test", 1)
-    end
-
-    def test_path_encoding_default_utf8
-      adpt1 = Redmine::Scm::Adapters::FilesystemAdapter.new(
-                                  REPOSITORY_PATH
-                                )
-      assert_equal "UTF-8", adpt1.path_encoding
-      adpt2 = Redmine::Scm::Adapters::FilesystemAdapter.new(
-                                  REPOSITORY_PATH,
-                                  nil,
-                                  nil,
-                                  nil,
-                                  ""
-                                )
-      assert_equal "UTF-8", adpt2.path_encoding
-    end
-  else
-    puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5d/5db9ffd3614f105788069a6feb5a6c5de41466cf.svn-base
--- /dev/null
+++ b/.svn/pristine/5d/5db9ffd3614f105788069a6feb5a6c5de41466cf.svn-base
@@ -0,0 +1,476 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ChangesetTest < ActiveSupport::TestCase
+  fixtures :projects, :repositories,
+           :issues, :issue_statuses, :issue_categories,
+           :changesets, :changes,
+           :enumerations,
+           :custom_fields, :custom_values,
+           :users, :members, :member_roles, :trackers,
+           :enabled_modules, :roles
+
+  def test_ref_keywords_any
+    ActionMailer::Base.deliveries.clear
+    Setting.commit_fix_status_id = IssueStatus.find(
+                                   :first, :conditions => ["is_closed = ?", true]).id
+    Setting.commit_fix_done_ratio = '90'
+    Setting.commit_ref_keywords = '*'
+    Setting.commit_fix_keywords = 'fixes , closes'
+
+    c = Changeset.new(:repository   => Project.find(1).repository,
+                      :committed_on => Time.now,
+                      :comments     => 'New commit (#2). Fixes #1',
+                      :revision     => '12345')
+    assert c.save
+    assert_equal [1, 2], c.issue_ids.sort
+    fixed = Issue.find(1)
+    assert fixed.closed?
+    assert_equal 90, fixed.done_ratio
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_ref_keywords
+    Setting.commit_ref_keywords = 'refs'
+    Setting.commit_fix_keywords = ''
+    c = Changeset.new(:repository   => Project.find(1).repository,
+                      :committed_on => Time.now,
+                      :comments     => 'Ignores #2. Refs #1',
+                      :revision     => '12345')
+    assert c.save
+    assert_equal [1], c.issue_ids.sort
+  end
+
+  def test_ref_keywords_any_only
+    Setting.commit_ref_keywords = '*'
+    Setting.commit_fix_keywords = ''
+    c = Changeset.new(:repository   => Project.find(1).repository,
+                      :committed_on => Time.now,
+                      :comments     => 'Ignores #2. Refs #1',
+                      :revision     => '12345')
+    assert c.save
+    assert_equal [1, 2], c.issue_ids.sort
+  end
+
+  def test_ref_keywords_any_with_timelog
+    Setting.commit_ref_keywords = '*'
+    Setting.commit_logtime_enabled = '1'
+
+    {
+      '2' => 2.0,
+      '2h' => 2.0,
+      '2hours' => 2.0,
+      '15m' => 0.25,
+      '15min' => 0.25,
+      '3h15' => 3.25,
+      '3h15m' => 3.25,
+      '3h15min' => 3.25,
+      '3:15' => 3.25,
+      '3.25' => 3.25,
+      '3.25h' => 3.25,
+      '3,25' => 3.25,
+      '3,25h' => 3.25,
+    }.each do |syntax, expected_hours|
+      c = Changeset.new(:repository   => Project.find(1).repository,
+                        :committed_on => 24.hours.ago,
+                        :comments     => "Worked on this issue #1 @#{syntax}",
+                        :revision     => '520',
+                        :user         => User.find(2))
+      assert_difference 'TimeEntry.count' do
+        c.scan_comment_for_issue_ids
+      end
+      assert_equal [1], c.issue_ids.sort
+
+      time = TimeEntry.first(:order => 'id desc')
+      assert_equal 1, time.issue_id
+      assert_equal 1, time.project_id
+      assert_equal 2, time.user_id
+      assert_equal expected_hours, time.hours,
+          "@#{syntax} should be logged as #{expected_hours} hours but was #{time.hours}"
+      assert_equal Date.yesterday, time.spent_on
+      assert time.activity.is_default?
+      assert time.comments.include?('r520'),
+            "r520 was expected in time_entry comments: #{time.comments}"
+    end
+  end
+
+  def test_ref_keywords_closing_with_timelog
+    Setting.commit_fix_status_id = IssueStatus.find(
+                                    :first, :conditions => ["is_closed = ?", true]).id
+    Setting.commit_ref_keywords = '*'
+    Setting.commit_fix_keywords = 'fixes , closes'
+    Setting.commit_logtime_enabled = '1'
+
+    c = Changeset.new(:repository   => Project.find(1).repository,
+                      :committed_on => Time.now,
+                      :comments     => 'This is a comment. Fixes #1 @4.5, #2 @1',
+                      :user         => User.find(2))
+    assert_difference 'TimeEntry.count', 2 do
+      c.scan_comment_for_issue_ids
+    end
+
+    assert_equal [1, 2], c.issue_ids.sort
+    assert Issue.find(1).closed?
+    assert Issue.find(2).closed?
+
+    times = TimeEntry.all(:order => 'id desc', :limit => 2)
+    assert_equal [1, 2], times.collect(&:issue_id).sort
+  end
+
+  def test_ref_keywords_any_line_start
+    Setting.commit_ref_keywords = '*'
+    c = Changeset.new(:repository   => Project.find(1).repository,
+                      :committed_on => Time.now,
+                      :comments     => '#1 is the reason of this commit',
+                      :revision     => '12345')
+    assert c.save
+    assert_equal [1], c.issue_ids.sort
+  end
+
+  def test_ref_keywords_allow_brackets_around_a_issue_number
+    Setting.commit_ref_keywords = '*'
+    c = Changeset.new(:repository   => Project.find(1).repository,
+                      :committed_on => Time.now,
+                      :comments     => '[#1] Worked on this issue',
+                      :revision     => '12345')
+    assert c.save
+    assert_equal [1], c.issue_ids.sort
+  end
+
+  def test_ref_keywords_allow_brackets_around_multiple_issue_numbers
+    Setting.commit_ref_keywords = '*'
+    c = Changeset.new(:repository   => Project.find(1).repository,
+                      :committed_on => Time.now,
+                      :comments     => '[#1 #2, #3] Worked on these',
+                      :revision     => '12345')
+    assert c.save
+    assert_equal [1,2,3], c.issue_ids.sort
+  end
+
+  def test_commit_referencing_a_subproject_issue
+    c = Changeset.new(:repository   => Project.find(1).repository,
+                      :committed_on => Time.now,
+                      :comments     => 'refs #5, a subproject issue',
+                      :revision     => '12345')
+    assert c.save
+    assert_equal [5], c.issue_ids.sort
+    assert c.issues.first.project != c.project
+  end
+
+  def test_commit_closing_a_subproject_issue
+    with_settings :commit_fix_status_id => 5, :commit_fix_keywords => 'closes',
+                  :default_language => 'en' do
+      issue = Issue.find(5)
+      assert !issue.closed?
+      assert_difference 'Journal.count' do
+        c = Changeset.new(:repository   => Project.find(1).repository,
+                          :committed_on => Time.now,
+                          :comments     => 'closes #5, a subproject issue',
+                          :revision     => '12345')
+        assert c.save
+      end
+      assert issue.reload.closed?
+      journal = Journal.first(:order => 'id DESC')
+      assert_equal issue, journal.issue
+      assert_include "Applied in changeset ecookbook:r12345.", journal.notes
+    end
+  end
+
+  def test_commit_referencing_a_parent_project_issue
+    # repository of child project
+    r = Repository::Subversion.create!(
+          :project => Project.find(3),
+          :url     => 'svn://localhost/test')
+    c = Changeset.new(:repository   => r,
+                      :committed_on => Time.now,
+                      :comments     => 'refs #2, an issue of a parent project',
+                      :revision     => '12345')
+    assert c.save
+    assert_equal [2], c.issue_ids.sort
+    assert c.issues.first.project != c.project
+  end
+
+  def test_commit_referencing_a_project_with_commit_cross_project_ref_disabled
+    r = Repository::Subversion.create!(
+          :project => Project.find(3),
+          :url     => 'svn://localhost/test')
+          
+    with_settings :commit_cross_project_ref => '0' do
+      c = Changeset.new(:repository   => r,
+                        :committed_on => Time.now,
+                        :comments     => 'refs #4, an issue of a different project',
+                        :revision     => '12345')
+      assert c.save
+      assert_equal [], c.issue_ids
+    end
+  end
+
+  def test_commit_referencing_a_project_with_commit_cross_project_ref_enabled
+    r = Repository::Subversion.create!(
+          :project => Project.find(3),
+          :url     => 'svn://localhost/test')
+          
+    with_settings :commit_cross_project_ref => '1' do
+      c = Changeset.new(:repository   => r,
+                        :committed_on => Time.now,
+                        :comments     => 'refs #4, an issue of a different project',
+                        :revision     => '12345')
+      assert c.save
+      assert_equal [4], c.issue_ids
+    end
+  end
+
+  def test_text_tag_revision
+    c = Changeset.new(:revision => '520')
+    assert_equal 'r520', c.text_tag
+  end
+
+  def test_text_tag_revision_with_same_project
+    c = Changeset.new(:revision => '520', :repository => Project.find(1).repository)
+    assert_equal 'r520', c.text_tag(Project.find(1))
+  end
+
+  def test_text_tag_revision_with_different_project
+    c = Changeset.new(:revision => '520', :repository => Project.find(1).repository)
+    assert_equal 'ecookbook:r520', c.text_tag(Project.find(2))
+  end
+
+  def test_text_tag_revision_with_repository_identifier
+    r = Repository::Subversion.create!(
+          :project_id => 1,
+          :url     => 'svn://localhost/test',
+          :identifier => 'documents')
+    
+    c = Changeset.new(:revision => '520', :repository => r)
+    assert_equal 'documents|r520', c.text_tag
+    assert_equal 'ecookbook:documents|r520', c.text_tag(Project.find(2))
+  end
+
+  def test_text_tag_hash
+    c = Changeset.new(
+          :scmid    => '7234cb2750b63f47bff735edc50a1c0a433c2518',
+          :revision => '7234cb2750b63f47bff735edc50a1c0a433c2518')
+    assert_equal 'commit:7234cb2750b63f47bff735edc50a1c0a433c2518', c.text_tag
+  end
+
+  def test_text_tag_hash_with_same_project
+    c = Changeset.new(:revision => '7234cb27', :scmid => '7234cb27', :repository => Project.find(1).repository)
+    assert_equal 'commit:7234cb27', c.text_tag(Project.find(1))
+  end
+
+  def test_text_tag_hash_with_different_project
+    c = Changeset.new(:revision => '7234cb27', :scmid => '7234cb27', :repository => Project.find(1).repository)
+    assert_equal 'ecookbook:commit:7234cb27', c.text_tag(Project.find(2))
+  end
+
+  def test_text_tag_hash_all_number
+    c = Changeset.new(:scmid => '0123456789', :revision => '0123456789')
+    assert_equal 'commit:0123456789', c.text_tag
+  end
+
+  def test_previous
+    changeset = Changeset.find_by_revision('3')
+    assert_equal Changeset.find_by_revision('2'), changeset.previous
+  end
+
+  def test_previous_nil
+    changeset = Changeset.find_by_revision('1')
+    assert_nil changeset.previous
+  end
+
+  def test_next
+    changeset = Changeset.find_by_revision('2')
+    assert_equal Changeset.find_by_revision('3'), changeset.next
+  end
+
+  def test_next_nil
+    changeset = Changeset.find_by_revision('10')
+    assert_nil changeset.next
+  end
+
+  def test_comments_should_be_converted_to_utf8
+    proj = Project.find(3)
+    # str = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
+    str = "Texte encod\xe9 en ISO-8859-1."
+    str.force_encoding("ASCII-8BIT") if str.respond_to?(:force_encoding)
+    r = Repository::Bazaar.create!(
+            :project      => proj,
+            :url          => '/tmp/test/bazaar',
+            :log_encoding => 'ISO-8859-1' )
+    assert r
+    c = Changeset.new(:repository   => r,
+                      :committed_on => Time.now,
+                      :revision     => '123',
+                      :scmid        => '12345',
+                      :comments     => str)
+    assert( c.save )
+    str_utf8 = "Texte encod\xc3\xa9 en ISO-8859-1."
+    str_utf8.force_encoding("UTF-8") if str_utf8.respond_to?(:force_encoding)
+    assert_equal str_utf8, c.comments
+  end
+
+  def test_invalid_utf8_sequences_in_comments_should_be_replaced_latin1
+    proj = Project.find(3)
+    # str = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
+    str1 = "Texte encod\xe9 en ISO-8859-1."
+    str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test"
+    str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding)
+    str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding)
+    r = Repository::Bazaar.create!(
+            :project      => proj,
+            :url          => '/tmp/test/bazaar',
+            :log_encoding => 'UTF-8' )
+    assert r
+    c = Changeset.new(:repository   => r,
+                      :committed_on => Time.now,
+                      :revision     => '123',
+                      :scmid        => '12345',
+                      :comments     => str1,
+                      :committer    => str2)
+    assert( c.save )
+    assert_equal "Texte encod? en ISO-8859-1.", c.comments
+    assert_equal "?a?b?c?d?e test", c.committer
+  end
+
+  def test_invalid_utf8_sequences_in_comments_should_be_replaced_ja_jis
+    proj = Project.find(3)
+    str = "test\xb5\xfetest\xb5\xfe"
+    if str.respond_to?(:force_encoding)
+      str.force_encoding('ASCII-8BIT')
+    end
+    r = Repository::Bazaar.create!(
+            :project      => proj,
+            :url          => '/tmp/test/bazaar',
+            :log_encoding => 'ISO-2022-JP' )
+    assert r
+    c = Changeset.new(:repository   => r,
+                      :committed_on => Time.now,
+                      :revision     => '123',
+                      :scmid        => '12345',
+                      :comments     => str)
+    assert( c.save )
+    assert_equal "test??test??", c.comments
+  end
+
+  def test_comments_should_be_converted_all_latin1_to_utf8
+    s1 = "\xC2\x80"
+    s2 = "\xc3\x82\xc2\x80"
+    s4 = s2.dup
+    if s1.respond_to?(:force_encoding)
+      s3 = s1.dup
+      s1.force_encoding('ASCII-8BIT')
+      s2.force_encoding('ASCII-8BIT')
+      s3.force_encoding('ISO-8859-1')
+      s4.force_encoding('UTF-8')
+      assert_equal s3.encode('UTF-8'), s4
+    end
+    proj = Project.find(3)
+    r = Repository::Bazaar.create!(
+            :project      => proj,
+            :url          => '/tmp/test/bazaar',
+            :log_encoding => 'ISO-8859-1' )
+    assert r
+    c = Changeset.new(:repository   => r,
+                      :committed_on => Time.now,
+                      :revision     => '123',
+                      :scmid        => '12345',
+                      :comments     => s1)
+    assert( c.save )
+    assert_equal s4, c.comments
+  end
+
+  def test_invalid_utf8_sequences_in_paths_should_be_replaced
+    proj = Project.find(3)
+    str1 = "Texte encod\xe9 en ISO-8859-1"
+    str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test"
+    str1.force_encoding("UTF-8")      if str1.respond_to?(:force_encoding)
+    str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding)
+    r = Repository::Bazaar.create!(
+            :project => proj,
+            :url => '/tmp/test/bazaar',
+            :log_encoding => 'UTF-8' )
+    assert r
+    cs = Changeset.new(
+               :repository   => r,
+               :committed_on => Time.now,
+               :revision     => '123',
+               :scmid        => '12345',
+               :comments     => "test")
+    assert(cs.save)
+    ch = Change.new(
+                  :changeset     => cs,
+                  :action        => "A",
+                  :path          => str1,
+                  :from_path     => str2,
+                  :from_revision => "345")
+    assert(ch.save)
+    assert_equal "Texte encod? en ISO-8859-1", ch.path
+    assert_equal "?a?b?c?d?e test", ch.from_path
+  end
+
+  def test_comments_nil
+    proj = Project.find(3)
+    r = Repository::Bazaar.create!(
+            :project      => proj,
+            :url          => '/tmp/test/bazaar',
+            :log_encoding => 'ISO-8859-1' )
+    assert r
+    c = Changeset.new(:repository   => r,
+                      :committed_on => Time.now,
+                      :revision     => '123',
+                      :scmid        => '12345',
+                      :comments     => nil,
+                      :committer    => nil)
+    assert( c.save )
+    assert_equal "", c.comments
+    assert_equal nil, c.committer
+    if c.comments.respond_to?(:force_encoding)
+      assert_equal "UTF-8", c.comments.encoding.to_s
+    end
+  end
+
+  def test_comments_empty
+    proj = Project.find(3)
+    r = Repository::Bazaar.create!(
+            :project      => proj,
+            :url          => '/tmp/test/bazaar',
+            :log_encoding => 'ISO-8859-1' )
+    assert r
+    c = Changeset.new(:repository   => r,
+                      :committed_on => Time.now,
+                      :revision     => '123',
+                      :scmid        => '12345',
+                      :comments     => "",
+                      :committer    => "")
+    assert( c.save )
+    assert_equal "", c.comments
+    assert_equal "", c.committer
+    if c.comments.respond_to?(:force_encoding)
+      assert_equal "UTF-8", c.comments.encoding.to_s
+      assert_equal "UTF-8", c.committer.encoding.to_s
+    end
+  end
+
+  def test_identifier
+    c = Changeset.find_by_revision('1')
+    assert_equal c.revision, c.identifier
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5d/5dc200a9880b49ee8adf93752f95bd14fc23a33e.svn-base
--- a/.svn/pristine/5d/5dc200a9880b49ee8adf93752f95bd14fc23a33e.svn-base
+++ /dev/null
@@ -1,98 +0,0 @@
-# Generates a migration which migrates all plugins to their latest versions
-# within the database.
-class PluginMigrationGenerator < Rails::Generator::Base
-  
-  # 255 characters max for Windows NTFS (http://en.wikipedia.org/wiki/Filename)
-  # minus 14 for timestamp, minus some extra chars for dot, underscore, file 
-  # extension. So let's have 230.
-  MAX_FILENAME_LENGTH = 230
-    
-  def initialize(runtime_args, runtime_options={})
-    super
-    @options = {:assigns => {}}
-    ensure_schema_table_exists    
-    get_plugins_to_migrate(runtime_args)
-    
-    if @plugins_to_migrate.empty?
-      puts "All plugins are migrated to their latest versions"
-      exit(0)
-    end
-
-    @options[:migration_file_name] = build_migration_name
-    @options[:assigns][:class_name] = build_migration_name.classify
-  end
-  
-  def manifest
-    record do |m|
-      m.migration_template 'plugin_migration.erb', 'db/migrate', @options
-    end
-  end
-  
-  protected
-
-    # Create the schema table if it doesn't already exist.
-    def ensure_schema_table_exists
-      ActiveRecord::Base.connection.initialize_schema_migrations_table
-    end
-
-    # Determine all the plugins which have migrations that aren't present
-    # according to the plugin schema information from the database.
-    def get_plugins_to_migrate(plugin_names)
-
-      # First, grab all the plugins which exist and have migrations
-      @plugins_to_migrate = if plugin_names.empty?
-        Engines.plugins
-      else
-        plugin_names.map do |name| 
-          Engines.plugins[name] ? Engines.plugins[name] : raise("Cannot find the plugin '#{name}'")
-        end
-      end
-      
-      @plugins_to_migrate.reject! { |p| !p.respond_to?(:latest_migration) || p.latest_migration.nil? }
-      
-      # Then find the current versions from the database    
-      @current_versions = {}
-      @plugins_to_migrate.each do |plugin|
-        @current_versions[plugin.name] = Engines::Plugin::Migrator.current_version(plugin)
-      end
-
-      # Then find the latest versions from their migration directories
-      @new_versions = {}      
-      @plugins_to_migrate.each do |plugin|
-        @new_versions[plugin.name] = plugin.latest_migration
-      end
-      
-      # Remove any plugins that don't need migration
-      @plugins_to_migrate.map { |p| p.name }.each do |name|
-        @plugins_to_migrate.delete(Engines.plugins[name]) if @current_versions[name] == @new_versions[name]
-      end
-      
-      @options[:assigns][:plugins] = @plugins_to_migrate
-      @options[:assigns][:new_versions] = @new_versions
-      @options[:assigns][:current_versions] = @current_versions
-    end
-
-    # Returns a migration name. If the descriptive migration name based on the 
-    # plugin names involved is shorter than 230 characters that one will be
-    # used. Otherwise a shorter name will be returned.
-    def build_migration_name
-      descriptive_migration_name.tap do |name|        
-        name.replace short_migration_name if name.length > MAX_FILENAME_LENGTH
-      end
-    end
-
-    # Construct a unique migration name based on the plugins involved and the
-    # versions they should reach after this migration is run. The name constructed
-    # needs to be lowercase
-    def descriptive_migration_name
-      @plugins_to_migrate.map do |plugin| 
-        "#{plugin.name}_to_version_#{@new_versions[plugin.name]}" 
-      end.join("_and_").downcase
-    end
-
-    # Short migration name that will be used if the descriptive_migration_name
-    # exceeds 230 characters
-    def short_migration_name
-      'plugin_migrations'
-    end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5e/5e3393ea8f73093b28938371fb5146fc323458f9.svn-base
--- a/.svn/pristine/5e/5e3393ea8f73093b28938371fb5146fc323458f9.svn-base
+++ /dev/null
@@ -1,17 +0,0 @@
-begin
-  require 'rails/version'
-  unless Rails::VERSION::MAJOR >= 2 && Rails::VERSION::MINOR >= 3 && Rails::VERSION::TINY >= 2
-    raise "This version of the engines plugin requires Rails 2.3.2 or later!"
-  end
-end
-
-require File.join(File.dirname(__FILE__), 'lib/engines')
-
-# initialize Rails::Configuration with our own default values to spare users 
-# some hassle with the installation and keep the environment cleaner
-
-{ :default_plugin_locators => (defined?(Gem) ? [Rails::Plugin::GemLocator] : []).push(Engines::Plugin::FileSystemLocator),
-  :default_plugin_loader => Engines::Plugin::Loader,
-  :default_plugins => [:engines, :all] }.each do |name, default|    
-  Rails::Configuration.send(:define_method, name) { default }
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5e/5e37d42ab73a7b90b18f47c2e9486d6d1d7f855f.svn-base
--- a/.svn/pristine/5e/5e37d42ab73a7b90b18f47c2e9486d6d1d7f855f.svn-base
+++ /dev/null
@@ -1,16 +0,0 @@
-<h2><%=l(:label_issue_category)%>: <%=h @category.name %></h2>
-
-<% form_tag(issue_category_path(@category), :method => :delete) do %>
-<div class="box">
-<p><strong><%= l(:text_issue_category_destroy_question, @issue_count) %></strong></p>
-<p><label><%= radio_button_tag 'todo', 'nullify', true %> <%= l(:text_issue_category_destroy_assignments) %></label><br />
-<% if @categories.size > 0 %>
-<label><%= radio_button_tag 'todo', 'reassign', false %> <%= l(:text_issue_category_reassign_to) %></label>:
-<%= label_tag "reassign_to_id", l(:description_issue_category_reassign), :class => "hidden-for-sighted" %>
-<%= select_tag 'reassign_to_id', options_from_collection_for_select(@categories, 'id', 'name') %></p>
-<% end %>
-</div>
-
-<%= submit_tag l(:button_apply) %>
-<%= link_to l(:button_cancel), :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5e/5e390d048451969a2cf8ae5ceb1da6dd876fe459.svn-base
--- a/.svn/pristine/5e/5e390d048451969a2cf8ae5ceb1da6dd876fe459.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-<% if @entry && @entry.kind == 'file' %>
-
-<p>
-<%= link_to_if action_name != 'changes', l(:label_history), {:action => 'changes', :id => @project, :path => to_path_param(@path), :rev => @rev } %> |
-<% if @repository.supports_cat? %>
-    <%= link_to_if action_name != 'entry', l(:button_view), {:action => 'entry', :id => @project, :path => to_path_param(@path), :rev => @rev } %> |
-<% end %>
-<% if @repository.supports_annotate? %>
-    <%= link_to_if action_name != 'annotate', l(:button_annotate), {:action => 'annotate', :id => @project, :path => to_path_param(@path), :rev => @rev } %> |
-<% end %>
-<%= link_to(l(:button_download), {:action => 'entry', :id => @project, :path => to_path_param(@path), :rev => @rev, :format => 'raw' }) if @repository.supports_cat? %>
-<%= "(#{number_to_human_size(@entry.size)})" if @entry.size %>
-</p>
-
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5e/5e76196c9e35c9b7b34f45d88fc793cafc843bca.svn-base
--- a/.svn/pristine/5e/5e76196c9e35c9b7b34f45d88fc793cafc843bca.svn-base
+++ /dev/null
@@ -1,18 +0,0 @@
-api.array :versions, api_meta(:total_count => @versions.size) do
-  @versions.each do |version|
-    api.version do
-      api.id version.id
-      api.project(:id => version.project_id, :name => version.project.name) unless version.project.nil?
-
-      api.name        version.name
-      api.description version.description
-      api.status      version.status
-      api.due_date    version.effective_date
-
-      render_api_custom_values version.custom_field_values, api
-
-      api.created_on version.created_on
-      api.updated_on version.updated_on
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5e/5eb189ca68bafa164c9eaf8f70c4f655a815135e.svn-base
--- a/.svn/pristine/5e/5eb189ca68bafa164c9eaf8f70c4f655a815135e.svn-base
+++ /dev/null
@@ -1,77 +0,0 @@
-module CodeRay
-  
-  # = WordList
-  # 
-  # <b>A Hash subclass designed for mapping word lists to token types.</b>
-  # 
-  # Copyright (c) 2006-2011 by murphy (Kornelius Kalnbach) <murphy rubychan de>
-  #
-  # License:: LGPL / ask the author
-  # Version:: 2.0 (2011-05-08)
-  #
-  # A WordList is a Hash with some additional features.
-  # It is intended to be used for keyword recognition.
-  #
-  # WordList is optimized to be used in Scanners,
-  # typically to decide whether a given ident is a special token.
-  #
-  # For case insensitive words use WordList::CaseIgnoring.
-  #
-  # Example:
-  #
-  #  # define word arrays
-  #  RESERVED_WORDS = %w[
-  #    asm break case continue default do else
-  #  ]
-  #  
-  #  PREDEFINED_TYPES = %w[
-  #    int long short char void
-  #  ]
-  #  
-  #  # make a WordList
-  #  IDENT_KIND = WordList.new(:ident).
-  #    add(RESERVED_WORDS, :reserved).
-  #    add(PREDEFINED_TYPES, :predefined_type)
-  #  
-  #  ...
-  #  
-  #  def scan_tokens tokens, options
-  #    ...
-  #    
-  #    elsif scan(/[A-Za-z_][A-Za-z_0-9]*/)
-  #      # use it
-  #      kind = IDENT_KIND[match]
-  #      ...
-  class WordList < Hash
-    
-    # Create a new WordList with +default+ as default value.
-    def initialize default = false
-      super default
-    end
-    
-    # Add words to the list and associate them with +value+.
-    # 
-    # Returns +self+, so you can concat add calls.
-    def add words, value = true
-      words.each { |word| self[word] = value }
-      self
-    end
-    
-  end
-  
-  
-  # A CaseIgnoring WordList is like a WordList, only that
-  # keys are compared case-insensitively (normalizing keys using +downcase+).
-  class WordList::CaseIgnoring < WordList
-    
-    def [] key
-      super key.downcase
-    end
-    
-    def []= key, value
-      super key.downcase, value
-    end
-    
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5f/5f0a13fce17c6abc15fce65d4826f03678f86c58.svn-base
--- a/.svn/pristine/5f/5f0a13fce17c6abc15fce65d4826f03678f86c58.svn-base
+++ /dev/null
@@ -1,87 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class AuthSourcesController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin
-
-  # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
-  verify :method => :post, :only => [ :destroy, :create, :update ],
-         :redirect_to => { :template => :index }
-
-  def index
-    @auth_source_pages, @auth_sources = paginate auth_source_class.name.tableize, :per_page => 10
-    render "auth_sources/index"
-  end
-
-  def new
-    @auth_source = auth_source_class.new
-    render 'auth_sources/new'
-  end
-
-  def create
-    @auth_source = auth_source_class.new(params[:auth_source])
-    if @auth_source.save
-      flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index'
-    else
-      render 'auth_sources/new'
-    end
-  end
-
-  def edit
-    @auth_source = AuthSource.find(params[:id])
-    render 'auth_sources/edit'
-  end
-
-  def update
-    @auth_source = AuthSource.find(params[:id])
-    if @auth_source.update_attributes(params[:auth_source])
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
-    else
-      render 'auth_sources/edit'
-    end
-  end
-
-  def test_connection
-    @auth_method = AuthSource.find(params[:id])
-    begin
-      @auth_method.test_connection
-      flash[:notice] = l(:notice_successful_connection)
-    rescue => text
-      flash[:error] = l(:error_unable_to_connect, text.message)
-    end
-    redirect_to :action => 'index'
-  end
-
-  def destroy
-    @auth_source = AuthSource.find(params[:id])
-    unless @auth_source.users.find(:first)
-      @auth_source.destroy
-      flash[:notice] = l(:notice_successful_delete)
-    end
-    redirect_to :action => 'index'
-  end
-
-  protected
-
-  def auth_source_class
-    AuthSource
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5f/5f0eae515ed184a3480763e5de7b865ac6400930.svn-base
--- /dev/null
+++ b/.svn/pristine/5f/5f0eae515ed184a3480763e5de7b865ac6400930.svn-base
@@ -0,0 +1,163 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WikiContentTest < ActiveSupport::TestCase
+  fixtures :projects, :enabled_modules,
+           :users, :members, :member_roles, :roles,
+           :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
+
+  def setup
+    @wiki = Wiki.find(1)
+    @page = @wiki.pages.first
+  end
+
+  def test_create
+    page = WikiPage.new(:wiki => @wiki, :title => "Page")
+    page.content = WikiContent.new(:text => "Content text", :author => User.find(1), :comments => "My comment")
+    assert page.save
+    page.reload
+
+    content = page.content
+    assert_kind_of WikiContent, content
+    assert_equal 1, content.version
+    assert_equal 1, content.versions.length
+    assert_equal "Content text", content.text
+    assert_equal "My comment", content.comments
+    assert_equal User.find(1), content.author
+    assert_equal content.text, content.versions.last.text
+  end
+
+  def test_create_should_send_email_notification
+    ActionMailer::Base.deliveries.clear
+    page = WikiPage.new(:wiki => @wiki, :title => "A new page")
+    page.content = WikiContent.new(:text => "Content text", :author => User.find(1), :comments => "My comment")
+
+    with_settings :notified_events => %w(wiki_content_added) do
+      assert page.save
+    end
+
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_update_should_be_versioned
+    content = @page.content
+    version_count = content.version
+    content.text = "My new content"
+    assert_difference 'WikiContent::Version.count' do
+      assert content.save
+    end
+    content.reload
+    assert_equal version_count+1, content.version
+    assert_equal version_count+1, content.versions.length
+
+    version = WikiContent::Version.first(:order => 'id DESC')
+    assert_equal @page.id, version.page_id
+    assert_equal '', version.compression
+    assert_equal "My new content", version.data
+    assert_equal "My new content", version.text
+  end
+
+  def test_update_with_gzipped_history
+    with_settings :wiki_compression => 'gzip' do
+      content = @page.content
+      content.text = "My new content"
+      assert_difference 'WikiContent::Version.count' do
+        assert content.save
+      end
+    end
+
+    version = WikiContent::Version.first(:order => 'id DESC')
+    assert_equal @page.id, version.page_id
+    assert_equal 'gzip', version.compression
+    assert_not_equal "My new content", version.data
+    assert_equal "My new content", version.text
+  end
+
+  def test_update_should_send_email_notification
+    ActionMailer::Base.deliveries.clear
+    content = @page.content
+    content.text = "My new content"
+
+    with_settings :notified_events => %w(wiki_content_updated) do
+      assert content.save
+    end
+
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_fetch_history
+    assert !@page.content.versions.empty?
+    @page.content.versions.each do |version|
+      assert_kind_of String, version.text
+    end
+  end
+
+  def test_large_text_should_not_be_truncated_to_64k
+    page = WikiPage.new(:wiki => @wiki, :title => "Big page")
+    page.content = WikiContent.new(:text => "a" * 500.kilobyte, :author => User.find(1))
+    assert page.save
+    page.reload
+    assert_equal 500.kilobyte, page.content.text.size
+  end
+  
+  def test_current_version
+    content = WikiContent.find(11)
+    assert_equal true, content.current_version?
+    assert_equal true, content.versions.first(:order => 'version DESC').current_version?
+    assert_equal false, content.versions.first(:order => 'version ASC').current_version?
+  end
+
+  def test_previous_for_first_version_should_return_nil
+    content = WikiContent::Version.find_by_page_id_and_version(1, 1)
+    assert_nil content.previous
+  end
+
+  def test_previous_for_version_should_return_previous_version
+    content = WikiContent::Version.find_by_page_id_and_version(1, 3)
+    assert_not_nil content.previous
+    assert_equal 2, content.previous.version
+  end
+
+  def test_previous_for_version_with_gap_should_return_previous_available_version
+    WikiContent::Version.find_by_page_id_and_version(1, 2).destroy
+
+    content = WikiContent::Version.find_by_page_id_and_version(1, 3)
+    assert_not_nil content.previous
+    assert_equal 1, content.previous.version
+  end
+
+  def test_next_for_last_version_should_return_nil
+    content = WikiContent::Version.find_by_page_id_and_version(1, 3)
+    assert_nil content.next
+  end
+
+  def test_next_for_version_should_return_next_version
+    content = WikiContent::Version.find_by_page_id_and_version(1, 1)
+    assert_not_nil content.next
+    assert_equal 2, content.next.version
+  end
+
+  def test_next_for_version_with_gap_should_return_next_available_version
+    WikiContent::Version.find_by_page_id_and_version(1, 2).destroy
+
+    content = WikiContent::Version.find_by_page_id_and_version(1, 1)
+    assert_not_nil content.next
+    assert_equal 3, content.next.version
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5f/5f34122110535f3ec5de210020321433576b63f3.svn-base
--- /dev/null
+++ b/.svn/pristine/5f/5f34122110535f3ec5de210020321433576b63f3.svn-base
@@ -0,0 +1,185 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module DefaultData
+    class DataAlreadyLoaded < Exception; end
+
+    module Loader
+      include Redmine::I18n
+
+      class << self
+        # Returns true if no data is already loaded in the database
+        # otherwise false
+        def no_data?
+          !Role.where(:builtin => 0).exists? &&
+            !Tracker.exists? &&
+            !IssueStatus.exists? &&
+            !Enumeration.exists?
+        end
+
+        # Loads the default data
+        # Raises a RecordNotSaved exception if something goes wrong
+        def load(lang=nil)
+          raise DataAlreadyLoaded.new("Some configuration data is already loaded.") unless no_data?
+          set_language_if_valid(lang)
+
+          Role.transaction do
+            # Roles
+            manager = Role.create! :name => l(:default_role_manager),
+                                   :issues_visibility => 'all',
+                                   :position => 1
+            manager.permissions = manager.setable_permissions.collect {|p| p.name}
+            manager.save!
+
+            developer = Role.create!  :name => l(:default_role_developer),
+                                      :position => 2,
+                                      :permissions => [:manage_versions,
+                                                      :manage_categories,
+                                                      :view_issues,
+                                                      :add_issues,
+                                                      :edit_issues,
+                                                      :view_private_notes,
+                                                      :set_notes_private,
+                                                      :manage_issue_relations,
+                                                      :manage_subtasks,
+                                                      :add_issue_notes,
+                                                      :save_queries,
+                                                      :view_gantt,
+                                                      :view_calendar,
+                                                      :log_time,
+                                                      :view_time_entries,
+                                                      :comment_news,
+                                                      :view_documents,
+                                                      :view_wiki_pages,
+                                                      :view_wiki_edits,
+                                                      :edit_wiki_pages,
+                                                      :delete_wiki_pages,
+                                                      :add_messages,
+                                                      :edit_own_messages,
+                                                      :view_files,
+                                                      :manage_files,
+                                                      :browse_repository,
+                                                      :view_changesets,
+                                                      :commit_access,
+                                                      :manage_related_issues]
+
+            reporter = Role.create! :name => l(:default_role_reporter),
+                                    :position => 3,
+                                    :permissions => [:view_issues,
+                                                    :add_issues,
+                                                    :add_issue_notes,
+                                                    :save_queries,
+                                                    :view_gantt,
+                                                    :view_calendar,
+                                                    :log_time,
+                                                    :view_time_entries,
+                                                    :comment_news,
+                                                    :view_documents,
+                                                    :view_wiki_pages,
+                                                    :view_wiki_edits,
+                                                    :add_messages,
+                                                    :edit_own_messages,
+                                                    :view_files,
+                                                    :browse_repository,
+                                                    :view_changesets]
+
+            Role.non_member.update_attribute :permissions, [:view_issues,
+                                                            :add_issues,
+                                                            :add_issue_notes,
+                                                            :save_queries,
+                                                            :view_gantt,
+                                                            :view_calendar,
+                                                            :view_time_entries,
+                                                            :comment_news,
+                                                            :view_documents,
+                                                            :view_wiki_pages,
+                                                            :view_wiki_edits,
+                                                            :add_messages,
+                                                            :view_files,
+                                                            :browse_repository,
+                                                            :view_changesets]
+
+            Role.anonymous.update_attribute :permissions, [:view_issues,
+                                                           :view_gantt,
+                                                           :view_calendar,
+                                                           :view_time_entries,
+                                                           :view_documents,
+                                                           :view_wiki_pages,
+                                                           :view_wiki_edits,
+                                                           :view_files,
+                                                           :browse_repository,
+                                                           :view_changesets]
+
+            # Trackers
+            Tracker.create!(:name => l(:default_tracker_bug),     :is_in_chlog => true,  :is_in_roadmap => false, :position => 1)
+            Tracker.create!(:name => l(:default_tracker_feature), :is_in_chlog => true,  :is_in_roadmap => true,  :position => 2)
+            Tracker.create!(:name => l(:default_tracker_support), :is_in_chlog => false, :is_in_roadmap => false, :position => 3)
+
+            # Issue statuses
+            new       = IssueStatus.create!(:name => l(:default_issue_status_new), :is_closed => false, :is_default => true, :position => 1)
+            in_progress  = IssueStatus.create!(:name => l(:default_issue_status_in_progress), :is_closed => false, :is_default => false, :position => 2)
+            resolved  = IssueStatus.create!(:name => l(:default_issue_status_resolved), :is_closed => false, :is_default => false, :position => 3)
+            feedback  = IssueStatus.create!(:name => l(:default_issue_status_feedback), :is_closed => false, :is_default => false, :position => 4)
+            closed    = IssueStatus.create!(:name => l(:default_issue_status_closed), :is_closed => true, :is_default => false, :position => 5)
+            rejected  = IssueStatus.create!(:name => l(:default_issue_status_rejected), :is_closed => true, :is_default => false, :position => 6)
+
+            # Workflow
+            Tracker.all.each { |t|
+              IssueStatus.all.each { |os|
+                IssueStatus.all.each { |ns|
+                  WorkflowTransition.create!(:tracker_id => t.id, :role_id => manager.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
+                }
+              }
+            }
+
+            Tracker.all.each { |t|
+              [new, in_progress, resolved, feedback].each { |os|
+                [in_progress, resolved, feedback, closed].each { |ns|
+                  WorkflowTransition.create!(:tracker_id => t.id, :role_id => developer.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
+                }
+              }
+            }
+
+            Tracker.all.each { |t|
+              [new, in_progress, resolved, feedback].each { |os|
+                [closed].each { |ns|
+                  WorkflowTransition.create!(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
+                }
+              }
+              WorkflowTransition.create!(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => resolved.id, :new_status_id => feedback.id)
+            }
+
+            # Enumerations
+            IssuePriority.create!(:name => l(:default_priority_low), :position => 1)
+            IssuePriority.create!(:name => l(:default_priority_normal), :position => 2, :is_default => true)
+            IssuePriority.create!(:name => l(:default_priority_high), :position => 3)
+            IssuePriority.create!(:name => l(:default_priority_urgent), :position => 4)
+            IssuePriority.create!(:name => l(:default_priority_immediate), :position => 5)
+
+            DocumentCategory.create!(:name => l(:default_doc_category_user), :position => 1)
+            DocumentCategory.create!(:name => l(:default_doc_category_tech), :position => 2)
+
+            TimeEntryActivity.create!(:name => l(:default_activity_design), :position => 1)
+            TimeEntryActivity.create!(:name => l(:default_activity_development), :position => 2)
+          end
+          true
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5f/5f8859116475dd06123c2a90756b26148236e7e2.svn-base
--- a/.svn/pristine/5f/5f8859116475dd06123c2a90756b26148236e7e2.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-# The PluginList class is an array, enhanced to allow access to loaded plugins
-# by name, and iteration over loaded plugins in order of priority. This array is used
-# by Engines::RailsExtensions::RailsInitializer to create the Engines.plugins array.
-#
-# Each loaded plugin has a corresponding Plugin instance within this array, and 
-# the order the plugins were loaded is reflected in the entries in this array.
-#
-# For more information, see the Rails module.
-module Engines
-  class Plugin
-    class List < Array
-      # Finds plugins with the set with the given name (accepts Strings or Symbols), or
-      # index. So, Engines.plugins[0] returns the first-loaded Plugin, and Engines.plugins[:engines]
-      # returns the Plugin instance for the engines plugin itself.
-      def [](name_or_index)
-        if name_or_index.is_a?(Fixnum)
-          super
-        else
-          self.find { |plugin| plugin.name.to_s == name_or_index.to_s }
-        end
-      end
-  
-      # Go through each plugin, highest priority first (last loaded first). Effectively,
-      # this is like <tt>Engines.plugins.reverse</tt>
-      def by_precedence
-        reverse
-      end
-    end
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5f/5f91c8ec766f59461497fadde2dab5afeb5e2ac6.svn-base
--- /dev/null
+++ b/.svn/pristine/5f/5f91c8ec766f59461497fadde2dab5afeb5e2ac6.svn-base
@@ -0,0 +1,31 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::NotifiableTest < ActiveSupport::TestCase
+  def setup
+  end
+
+  def test_all
+    assert_equal 12, Redmine::Notifiable.all.length
+
+    %w(issue_added issue_updated issue_note_added issue_status_updated issue_priority_updated news_added news_comment_added document_added file_added message_posted wiki_content_added wiki_content_updated).each do |notifiable|
+      assert Redmine::Notifiable.all.collect(&:name).include?(notifiable), "missing #{notifiable}"
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/5f/5ffda40b0da33ea2cbd4a1b56f89be0bef6f6786.svn-base
--- a/.svn/pristine/5f/5ffda40b0da33ea2cbd4a1b56f89be0bef6f6786.svn-base
+++ /dev/null
@@ -1,27 +0,0 @@
-<div class="contextual">
-<%= link_to_if_authorized l(:label_query_new), new_project_query_path(:project_id => @project), :class => 'icon icon-add' %>
-</div>
-
-<h2><%= l(:label_query_plural) %></h2>
-
-<% if @queries.empty? %>
-  <p><i><%=l(:label_no_data)%></i></p>
-<% else %>
-  <table class="list">
-  <% @queries.each do |query| %>
-    <tr class="<%= cycle('odd', 'even') %>">
-      <td>
-        <%= link_to h(query.name), :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query %>
-      </td>
-      <td align="right">
-        <small>
-        <% if query.editable_by?(User.current) %>
-        <%= link_to l(:button_edit), edit_query_path(query), :class => 'icon icon-edit' %>
-        <%= link_to l(:button_delete), query_path(query), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
-        </small>
-      <% end %>
-      </td>
-    </tr>
-  <% end %>
-  </table>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/60/6089c129623045cd6c157b0be5cbb46ac9a89d00.svn-base
--- a/.svn/pristine/60/6089c129623045cd6c157b0be5cbb46ac9a89d00.svn-base
+++ /dev/null
@@ -1,10 +0,0 @@
-if @journal.frozen?
-  # journal was destroyed
-  page.remove "change-#{@journal.id}"
-else
-  page.replace "journal-#{@journal.id}-notes", render_notes(@journal.issue, @journal, :reply_links => authorize_for('issues', 'edit'))
-  page.show "journal-#{@journal.id}-notes"
-  page.remove "journal-#{@journal.id}-form"
-end
-
-call_hook(:view_journals_update_rjs_bottom, { :page => page, :journal => @journal })
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/60/60a7eaf3b71f4ea5a952f91807abdd540583522f.svn-base
--- a/.svn/pristine/60/60a7eaf3b71f4ea5a952f91807abdd540583522f.svn-base
+++ /dev/null
@@ -1,205 +0,0 @@
-# $Id: pdu.rb 126 2006-05-31 15:55:16Z blackhedd $
-#
-# LDAP PDU support classes
-#
-#
-#----------------------------------------------------------------------------
-#
-# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
-#
-# Gmail: garbagecat10
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#---------------------------------------------------------------------------
-#
-
-
-
-module Net
-
-
-class LdapPduError < Exception; end
-
-
-class LdapPdu
-
-  BindResult = 1
-  SearchReturnedData = 4
-  SearchResult = 5
-  ModifyResponse = 7
-  AddResponse = 9
-  DeleteResponse = 11
-  ModifyRDNResponse = 13
-  SearchResultReferral = 19
-
-  attr_reader :msg_id, :app_tag
-  attr_reader :search_dn, :search_attributes, :search_entry
-  attr_reader :search_referrals
-
-  #
-  # initialize
-  # An LDAP PDU always looks like a BerSequence with
-  # at least two elements: an integer (message-id number), and
-  # an application-specific sequence.
-  # Some LDAPv3 packets also include an optional
-  # third element, which is a sequence of "controls"
-  # (See RFC 2251, section 4.1.12).
-  # The application-specific tag in the sequence tells
-  # us what kind of packet it is, and each kind has its
-  # own format, defined in RFC-1777.
-  # Observe that many clients (such as ldapsearch)
-  # do not necessarily enforce the expected application
-  # tags on received protocol packets. This implementation
-  # does interpret the RFC strictly in this regard, and
-  # it remains to be seen whether there are servers out
-  # there that will not work well with our approach.
-  #
-  # Added a controls-processor to SearchResult.
-  # Didn't add it everywhere because it just _feels_
-  # like it will need to be refactored.
-  #
-  def initialize ber_object
-    begin
-      @msg_id = ber_object[0].to_i
-      @app_tag = ber_object[1].ber_identifier - 0x60
-    rescue
-      # any error becomes a data-format error
-      raise LdapPduError.new( "ldap-pdu format error" )
-    end
-
-    case @app_tag
-    when BindResult
-      parse_ldap_result ber_object[1]
-    when SearchReturnedData
-      parse_search_return ber_object[1]
-    when SearchResultReferral
-      parse_search_referral ber_object[1]
-    when SearchResult
-      parse_ldap_result ber_object[1]
-      parse_controls(ber_object[2]) if ber_object[2]
-    when ModifyResponse
-      parse_ldap_result ber_object[1]
-    when AddResponse
-      parse_ldap_result ber_object[1]
-    when DeleteResponse
-      parse_ldap_result ber_object[1]
-    when ModifyRDNResponse
-      parse_ldap_result ber_object[1]
-    else
-      raise LdapPduError.new( "unknown pdu-type: #{@app_tag}" )
-    end
-  end
-
-  #
-  # result_code
-  # This returns an LDAP result code taken from the PDU,
-  # but it will be nil if there wasn't a result code.
-  # That can easily happen depending on the type of packet.
-  #
-  def result_code code = :resultCode
-    @ldap_result and @ldap_result[code]
-  end
-
-  # Return RFC-2251 Controls if any.
-  # Messy. Does this functionality belong somewhere else?
-  def result_controls
-    @ldap_controls || []
-  end
-
-
-  #
-  # parse_ldap_result
-  #
-  def parse_ldap_result sequence
-    sequence.length >= 3 or raise LdapPduError
-    @ldap_result = {:resultCode => sequence[0], :matchedDN => sequence[1], :errorMessage => sequence[2]}
-  end
-  private :parse_ldap_result
-
-  #
-  # parse_search_return
-  # Definition from RFC 1777 (we're handling application-4 here)
-  #
-  # Search Response ::=
-  #    CHOICE {
-  #         entry          [APPLICATION 4] SEQUENCE {
-  #                             objectName     LDAPDN,
-  #                             attributes     SEQUENCE OF SEQUENCE {
-  #                                                 AttributeType,
-  #                                                 SET OF AttributeValue
-  #                                            }
-  #                        },
-  #         resultCode     [APPLICATION 5] LDAPResult
-  #     }
-  #
-  # We concoct a search response that is a hash of the returned attribute values.
-  # NOW OBSERVE CAREFULLY: WE ARE DOWNCASING THE RETURNED ATTRIBUTE NAMES.
-  # This is to make them more predictable for user programs, but it
-  # may not be a good idea. Maybe this should be configurable.
-  # ALTERNATE IMPLEMENTATION: In addition to @search_dn and @search_attributes,
-  # we also return @search_entry, which is an LDAP::Entry object.
-  # If that works out well, then we'll remove the first two.
-  #
-  # Provisionally removed obsolete search_attributes and search_dn, 04May06.
-  #
-  def parse_search_return sequence
-    sequence.length >= 2 or raise LdapPduError
-    @search_entry = LDAP::Entry.new( sequence[0] )
-    #@search_dn = sequence[0]
-    #@search_attributes = {}
-    sequence[1].each {|seq|
-      @search_entry[seq[0]] = seq[1]
-      #@search_attributes[seq[0].downcase.intern] = seq[1]
-    }
-  end
-
-  #
-  # A search referral is a sequence of one or more LDAP URIs.
-  # Any number of search-referral replies can be returned by the server, interspersed
-  # with normal replies in any order.
-  # Until I can think of a better way to do this, we'll return the referrals as an array.
-  # It'll be up to higher-level handlers to expose something reasonable to the client.
-  def parse_search_referral uris
-    @search_referrals = uris
-  end
-
-
-  # Per RFC 2251, an LDAP "control" is a sequence of tuples, each consisting
-  # of an OID, a boolean criticality flag defaulting FALSE, and an OPTIONAL
-  # Octet String. If only two fields are given, the second one may be
-  # either criticality or data, since criticality has a default value.
-  # Someday we may want to come back here and add support for some of
-  # more-widely used controls. RFC-2696 is a good example.
-  #
-  def parse_controls sequence
-    @ldap_controls = sequence.map do |control|
-      o = OpenStruct.new
-      o.oid,o.criticality,o.value = control[0],control[1],control[2]
-      if o.criticality and o.criticality.is_a?(String)
-        o.value = o.criticality
-        o.criticality = false
-      end
-      o
-    end
-  end
-  private :parse_controls
-
-
-end
-
-
-end # module Net
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/60/60c7c698ddb29ef3812a4b75182c078fbc9cc19b.svn-base
--- a/.svn/pristine/60/60c7c698ddb29ef3812a4b75182c078fbc9cc19b.svn-base
+++ /dev/null
@@ -1,72 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Helpers
-    class Diff
-      include ERB::Util
-      include ActionView::Helpers::TagHelper
-      include ActionView::Helpers::TextHelper
-      attr_reader :diff, :words
-
-      def initialize(content_to, content_from)
-        @words = content_to.to_s.split(/(\s+)/)
-        @words = @words.select {|word| word != ' '}
-        words_from = content_from.to_s.split(/(\s+)/)
-        words_from = words_from.select {|word| word != ' '}
-        @diff = words_from.diff @words
-      end
-
-      def to_html
-        words = self.words.collect{|word| h(word)}
-        words_add = 0
-        words_del = 0
-        dels = 0
-        del_off = 0
-        diff.diffs.each do |diff|
-          add_at = nil
-          add_to = nil
-          del_at = nil
-          deleted = ""
-          diff.each do |change|
-            pos = change[1]
-            if change[0] == "+"
-              add_at = pos + dels unless add_at
-              add_to = pos + dels
-              words_add += 1
-            else
-              del_at = pos unless del_at
-              deleted << ' ' + h(change[2])
-              words_del  += 1
-            end
-          end
-          if add_at
-            words[add_at] = '<span class="diff_in">' + words[add_at]
-            words[add_to] = words[add_to] + '</span>'
-          end
-          if del_at
-            words.insert del_at - del_off + dels + words_add, '<span class="diff_out">' + deleted + '</span>'
-            dels += 1
-            del_off += words_del
-            words_del = 0
-          end
-        end
-        words.join(' ').html_safe
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/60/60f6cd76a2cf878fbe57eea952f6c764270ac27b.svn-base
--- a/.svn/pristine/60/60f6cd76a2cf878fbe57eea952f6c764270ac27b.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar FI language
-// Author: Antti PerkiÃ¶mÃ¤ki <antti.perkiomaki@gmail.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Sunnuntai",
- "Maanantai",
- "Tiistai",
- "Keskiviikko",
- "Torstai",
- "Perjantai",
- "Lauantai",
- "Sunnuntai");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Su",
- "Ma",
- "Ti",
- "Ke",
- "To",
- "Pe",
- "La",
- "Su");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Tammikuu",
- "Helmikuu",
- "Maaliskuu",
- "Huhtikuu",
- "Toukokuu",
- "KesÃ¤kuu",
- "HeinÃ¤kuu",
- "Elokuu",
- "Syyskuu",
- "Lokakuu",
- "Marraskuu",
- "Joulukuu");
-
-// short month names
-Calendar._SMN = new Array
-("Tammi",
- "Helmi",
- "Maalis",
- "Huhti",
- "Touko",
- "KesÃ¤",
- "HeinÃ¤",
- "Elo",
- "Syys",
- "Loka",
- "Marras",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Tietoa kalenterista";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / TekijÃ¤: Mihai Bazon\n" + // don't translate this this ;-)
-"Viimeisin versio: http://www.dynarch.com/projects/calendar/\n" +
-"Jaettu GNU LGPL alaisena. Katso lisÃ¤tiedot http://gnu.org/licenses/lgpl.html" +
-"\n\n" +
-"PÃ¤ivÃ¤ valitsin:\n" +
-"- KÃ¤ytÃ¤ \xab, \xbb painikkeita valitaksesi vuoden\n" +
-"- KÃ¤ytÃ¤ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " painikkeita valitaksesi kuukauden\n" +
-"- PidÃ¤ alhaalla hiiren painiketta missÃ¤ tahansa yllÃ¤mainituissa painikkeissa valitaksesi nopeammin.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Ajan valinta:\n" +
-"- Paina mitÃ¤ tahansa ajan osaa kasvattaaksesi sitÃ¤\n" +
-"- tai VaihtonÃ¤ppÃ¤in-paina laskeaksesi sitÃ¤\n" +
-"- tai paina ja raahaa valitaksesi nopeammin.";
-
-Calendar._TT["PREV_YEAR"] = "Edellinen vuosi (valikko tulee painaessa)";
-Calendar._TT["PREV_MONTH"] = "Edellinen kuukausi (valikko tulee painaessa)";
-Calendar._TT["GO_TODAY"] = "Siirry TÃ¤nÃ¤Ã¤n";
-Calendar._TT["NEXT_MONTH"] = "Seuraava kuukausi (valikko tulee painaessa)";
-Calendar._TT["NEXT_YEAR"] = "Seuraava vuosi (valikko tulee painaessa)";
-Calendar._TT["SEL_DATE"] = "Valitse pÃ¤ivÃ¤";
-Calendar._TT["DRAG_TO_MOVE"] = "Rahaa siirtÃ¤Ã¤ksesi";
-Calendar._TT["PART_TODAY"] = " (tÃ¤nÃ¤Ã¤n)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "NÃ¤ytÃ¤ %s ensin";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "6,0";
-
-Calendar._TT["CLOSE"] = "Sulje";
-Calendar._TT["TODAY"] = "TÃ¤nÃ¤Ã¤n";
-Calendar._TT["TIME_PART"] = "(VaihtonÃ¤ppÃ¤in-)Paina tai raahaa vaihtaaksesi arvoa";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "vko";
-Calendar._TT["TIME"] = "Aika:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/60/60fb53c461a41fb9a73cca759c107e76107c0242.svn-base
--- a/.svn/pristine/60/60fb53c461a41fb9a73cca759c107e76107c0242.svn-base
+++ /dev/null
@@ -1,176 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Role < ActiveRecord::Base
-  # Built-in roles
-  BUILTIN_NON_MEMBER = 1
-  BUILTIN_ANONYMOUS  = 2
-
-  ISSUES_VISIBILITY_OPTIONS = [
-    ['all', :label_issues_visibility_all],
-    ['default', :label_issues_visibility_public],
-    ['own', :label_issues_visibility_own]
-  ]
-
-  named_scope :givable, { :conditions => "builtin = 0", :order => 'position' }
-  named_scope :builtin, lambda { |*args|
-    compare = 'not' if args.first == true
-    { :conditions => "#{compare} builtin = 0" }
-  }
-
-  before_destroy :check_deletable
-  has_many :workflows, :dependent => :delete_all do
-    def copy(source_role)
-      Workflow.copy(nil, source_role, nil, proxy_owner)
-    end
-  end
-
-  has_many :member_roles, :dependent => :destroy
-  has_many :members, :through => :member_roles
-  acts_as_list
-
-  serialize :permissions, Array
-  attr_protected :builtin
-
-  validates_presence_of :name
-  validates_uniqueness_of :name
-  validates_length_of :name, :maximum => 30
-  validates_inclusion_of :issues_visibility,
-    :in => ISSUES_VISIBILITY_OPTIONS.collect(&:first),
-    :if => lambda {|role| role.respond_to?(:issues_visibility)}
-
-  def permissions
-    read_attribute(:permissions) || []
-  end
-
-  def permissions=(perms)
-    perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms
-    write_attribute(:permissions, perms)
-  end
-
-  def add_permission!(*perms)
-    self.permissions = [] unless permissions.is_a?(Array)
-
-    permissions_will_change!
-    perms.each do |p|
-      p = p.to_sym
-      permissions << p unless permissions.include?(p)
-    end
-    save!
-  end
-
-  def remove_permission!(*perms)
-    return unless permissions.is_a?(Array)
-    permissions_will_change!
-    perms.each { |p| permissions.delete(p.to_sym) }
-    save!
-  end
-
-  # Returns true if the role has the given permission
-  def has_permission?(perm)
-    !permissions.nil? && permissions.include?(perm.to_sym)
-  end
-
-  def <=>(role)
-    role ? position <=> role.position : -1
-  end
-
-  def to_s
-    name
-  end
-
-  def name
-    case builtin
-    when 1; l(:label_role_non_member, :default => read_attribute(:name))
-    when 2; l(:label_role_anonymous,  :default => read_attribute(:name))
-    else; read_attribute(:name)
-    end
-  end
-
-  # Return true if the role is a builtin role
-  def builtin?
-    self.builtin != 0
-  end
-
-  # Return true if the role is a project member role
-  def member?
-    !self.builtin?
-  end
-
-  # Return true if role is allowed to do the specified action
-  # action can be:
-  # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
-  # * a permission Symbol (eg. :edit_project)
-  def allowed_to?(action)
-    if action.is_a? Hash
-      allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
-    else
-      allowed_permissions.include? action
-    end
-  end
-
-  # Return all the permissions that can be given to the role
-  def setable_permissions
-    setable_permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions
-    setable_permissions -= Redmine::AccessControl.members_only_permissions if self.builtin == BUILTIN_NON_MEMBER
-    setable_permissions -= Redmine::AccessControl.loggedin_only_permissions if self.builtin == BUILTIN_ANONYMOUS
-    setable_permissions
-  end
-
-  # Find all the roles that can be given to a project member
-  def self.find_all_givable
-    find(:all, :conditions => {:builtin => 0}, :order => 'position')
-  end
-
-  # Return the builtin 'non member' role.  If the role doesn't exist,
-  # it will be created on the fly.
-  def self.non_member
-    find_or_create_system_role(BUILTIN_NON_MEMBER, 'Non member')
-  end
-
-  # Return the builtin 'anonymous' role.  If the role doesn't exist,
-  # it will be created on the fly.
-  def self.anonymous
-    find_or_create_system_role(BUILTIN_ANONYMOUS, 'Anonymous')
-  end
-
-private
-
-  def allowed_permissions
-    @allowed_permissions ||= permissions + Redmine::AccessControl.public_permissions.collect {|p| p.name}
-  end
-
-  def allowed_actions
-    @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
-  end
-
-  def check_deletable
-    raise "Can't delete role" if members.any?
-    raise "Can't delete builtin role" if builtin?
-  end
-
-  def self.find_or_create_system_role(builtin, name)
-    role = first(:conditions => {:builtin => builtin})
-    if role.nil?
-      role = create(:name => name, :position => 0) do |r|
-        r.builtin = builtin
-      end
-      raise "Unable to create the #{name} role." if role.new_record?
-    end
-    role
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/61/610feb39e0b4d5a86f5c3afb7419c2dc54df3346.svn-base
--- /dev/null
+++ b/.svn/pristine/61/610feb39e0b4d5a86f5c3afb7419c2dc54df3346.svn-base
@@ -0,0 +1,83 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class AdminController < ApplicationController
+  layout 'admin'
+  menu_item :projects, :only => :projects
+  menu_item :plugins, :only => :plugins
+  menu_item :info, :only => :info
+
+  before_filter :require_admin
+  helper :sort
+  include SortHelper
+
+  def index
+    @no_configuration_data = Redmine::DefaultData::Loader::no_data?
+  end
+
+  def projects
+    @status = params[:status] || 1
+
+    scope = Project.status(@status).order('lft')
+    scope = scope.like(params[:name]) if params[:name].present?
+    @projects = scope.all
+
+    render :action => "projects", :layout => false if request.xhr?
+  end
+
+  def plugins
+    @plugins = Redmine::Plugin.all
+  end
+
+  # Loads the default configuration
+  # (roles, trackers, statuses, workflow, enumerations)
+  def default_configuration
+    if request.post?
+      begin
+        Redmine::DefaultData::Loader::load(params[:lang])
+        flash[:notice] = l(:notice_default_data_loaded)
+      rescue Exception => e
+        flash[:error] = l(:error_can_t_load_default_data, e.message)
+      end
+    end
+    redirect_to admin_path
+  end
+
+  def test_email
+    raise_delivery_errors = ActionMailer::Base.raise_delivery_errors
+    # Force ActionMailer to raise delivery errors so we can catch it
+    ActionMailer::Base.raise_delivery_errors = true
+    begin
+      @test = Mailer.test_email(User.current).deliver
+      flash[:notice] = l(:notice_email_sent, User.current.mail)
+    rescue Exception => e
+      flash[:error] = l(:notice_email_error, e.message)
+    end
+    ActionMailer::Base.raise_delivery_errors = raise_delivery_errors
+    redirect_to settings_path(:tab => 'notifications')
+  end
+
+  def info
+    @db_adapter_name = ActiveRecord::Base.connection.adapter_name
+    @checklist = [
+      [:text_default_administrator_account_changed, User.default_admin_account_changed?],
+      [:text_file_repository_writable, File.writable?(Attachment.storage_path)],
+      [:text_plugin_assets_writable,   File.writable?(Redmine::Plugin.public_directory)],
+      [:text_rmagick_available,        Object.const_defined?(:Magick)]
+    ]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/61/61309acbc5f96ce770001ad1501caa18b7f75258.svn-base
--- a/.svn/pristine/61/61309acbc5f96ce770001ad1501caa18b7f75258.svn-base
+++ /dev/null
@@ -1,176 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class TimeEntryTest < ActiveSupport::TestCase
-  fixtures :issues, :projects, :users, :time_entries,
-           :members, :roles, :member_roles, :auth_sources,
-           :trackers, :issue_statuses,
-           :projects_trackers,
-           :journals, :journal_details,
-           :issue_categories, :enumerations,
-           :groups_users,
-           :enabled_modules,
-           :workflows
-
-  def test_hours_format
-    assertions = { "2"      => 2.0,
-                   "21.1"   => 21.1,
-                   "2,1"    => 2.1,
-                   "1,5h"   => 1.5,
-                   "7:12"   => 7.2,
-                   "10h"    => 10.0,
-                   "10 h"   => 10.0,
-                   "45m"    => 0.75,
-                   "45 m"   => 0.75,
-                   "3h15"   => 3.25,
-                   "3h 15"  => 3.25,
-                   "3 h 15"   => 3.25,
-                   "3 h 15m"  => 3.25,
-                   "3 h 15 m" => 3.25,
-                   "3 hours"  => 3.0,
-                   "12min"    => 0.2,
-                  }
-
-    assertions.each do |k, v|
-      t = TimeEntry.new(:hours => k)
-      assert_equal v, t.hours, "Converting #{k} failed:"
-    end
-  end
-
-  def test_hours_should_default_to_nil
-    assert_nil TimeEntry.new.hours
-  end
-
-  def test_spent_on_with_blank
-    c = TimeEntry.new
-    c.spent_on = ''
-    assert_nil c.spent_on
-  end
-
-  def test_spent_on_with_nil
-    c = TimeEntry.new
-    c.spent_on = nil
-    assert_nil c.spent_on
-  end
-
-  def test_spent_on_with_string
-    c = TimeEntry.new
-    c.spent_on = "2011-01-14"
-    assert_equal Date.parse("2011-01-14"), c.spent_on
-  end
-
-  def test_spent_on_with_invalid_string
-    c = TimeEntry.new
-    c.spent_on = "foo"
-    assert_nil c.spent_on
-  end
-
-  def test_spent_on_with_date
-    c = TimeEntry.new
-    c.spent_on = Date.today
-    assert_equal Date.today, c.spent_on
-  end
-
-  def test_spent_on_with_time
-    c = TimeEntry.new
-    c.spent_on = Time.now
-    assert_equal Date.today, c.spent_on
-  end
-
-  def test_validate_time_entry
-    anon     = User.anonymous
-    project  = Project.find(1)
-    issue    = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => anon.id, :status_id => 1,
-                         :priority => IssuePriority.all.first, :subject => 'test_create',
-                         :description => 'IssueTest#test_create', :estimated_hours => '1:30')
-    assert issue.save
-    activity = TimeEntryActivity.find_by_name('Design')
-    te = TimeEntry.create(:spent_on => '2010-01-01',
-                          :hours    => 100000,
-                          :issue    => issue,
-                          :project  => project,
-                          :user     => anon,
-                          :activity => activity)
-    assert_equal 1, te.errors.count
-  end
-
-  def test_set_project_if_nil
-    anon     = User.anonymous
-    project  = Project.find(1)
-    issue    = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => anon.id, :status_id => 1,
-                         :priority => IssuePriority.all.first, :subject => 'test_create',
-                         :description => 'IssueTest#test_create', :estimated_hours => '1:30')
-    assert issue.save
-    activity = TimeEntryActivity.find_by_name('Design')
-    te = TimeEntry.create(:spent_on => '2010-01-01',
-                          :hours    => 10,
-                          :issue    => issue,
-                          :user     => anon,
-                          :activity => activity)
-    assert_equal project.id, te.project.id
-  end
-
-  context "#earilest_date_for_project" do
-    setup do
-      User.current = nil
-      @public_project = Project.generate!(:is_public => true)
-      @issue = Issue.generate_for_project!(@public_project)
-      TimeEntry.generate!(:spent_on => '2010-01-01',
-                          :issue => @issue,
-                          :project => @public_project)
-    end
-
-    context "without a project" do
-      should "return the lowest spent_on value that is visible to the current user" do
-        assert_equal "2007-03-12", TimeEntry.earilest_date_for_project.to_s
-      end
-    end
-
-    context "with a project" do
-      should "return the lowest spent_on value that is visible to the current user for that project and it's subprojects only" do
-        assert_equal "2010-01-01", TimeEntry.earilest_date_for_project(@public_project).to_s
-      end
-    end
-
-  end
-
-  context "#latest_date_for_project" do
-    setup do
-      User.current = nil
-      @public_project = Project.generate!(:is_public => true)
-      @issue = Issue.generate_for_project!(@public_project)
-      TimeEntry.generate!(:spent_on => '2010-01-01',
-                          :issue => @issue,
-                          :project => @public_project)
-    end
-
-    context "without a project" do
-      should "return the highest spent_on value that is visible to the current user" do
-        assert_equal "2010-01-01", TimeEntry.latest_date_for_project.to_s
-      end
-    end
-
-    context "with a project" do
-      should "return the highest spent_on value that is visible to the current user for that project and it's subprojects only" do
-        project = Project.find(1)
-        assert_equal "2007-04-22", TimeEntry.latest_date_for_project(project).to_s
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/61/61668dfcefb644406f6147ff8d4029159a7244df.svn-base
--- a/.svn/pristine/61/61668dfcefb644406f6147ff8d4029159a7244df.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-<% form_tag({:action => 'edit', :tab => 'authentication'}) do %>
-
-<div class="box tabular settings">
-<p><%= setting_check_box :login_required %></p>
-
-<p><%= setting_select :autologin, [[l(:label_disabled), 0]] + [1, 7, 30, 365].collect{|days| [l('datetime.distance_in_words.x_days', :count => days), days.to_s]} %></p>
-
-<p><%= setting_select :self_registration, [[l(:label_disabled), "0"],
-                                           [l(:label_registration_activation_by_email), "1"],
-                                           [l(:label_registration_manual_activation), "2"],
-                                           [l(:label_registration_automatic_activation), "3"]] %></p>
-
-<p><%= setting_text_field :password_min_length, :size => 6 %></p>
-
-<p><%= setting_check_box :lost_password, :label => :label_password_lost %></p>
-
-<p><%= setting_check_box :openid, :disabled => !Object.const_defined?(:OpenID) %></p>
-
-<p><%= setting_check_box :rest_api_enabled %></p>
-</div>
-
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/61/61a91d37bba4f376ceeb50ad99e25e5c58c85000.svn-base
--- a/.svn/pristine/61/61a91d37bba4f376ceeb50ad99e25e5c58c85000.svn-base
+++ /dev/null
@@ -1,29 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class ExceptionNotificationCompatibilityTest < ActionController::TestCase
-  ExceptionNotifier.exception_recipients = %w(joe@schmoe.com bill@schmoe.com)
-  class SimpleController < ApplicationController
-    include ExceptionNotifiable
-    local_addresses.clear
-    consider_all_requests_local = false
-    def index
-      begin
-        raise "Fail!"
-      rescue Exception => e
-        rescue_action_in_public(e)
-      end
-    end
-  end
-  
-  def setup
-    @controller = SimpleController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-  end
-  
-  def test_should_work
-    assert_nothing_raised do
-      get :index
-    end
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/61/61b65742b8b81ec430e2510c699672b59ba4470d.svn-base
--- a/.svn/pristine/61/61b65742b8b81ec430e2510c699672b59ba4470d.svn-base
+++ /dev/null
@@ -1,129 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// Translator: David Duret, <pilgrim@mala-template.net> from previous french version
-
-// full day names
-Calendar._DN = new Array
-("Dimanche",
- "Lundi",
- "Mardi",
- "Mercredi",
- "Jeudi",
- "Vendredi",
- "Samedi",
- "Dimanche");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Dim",
- "Lun",
- "Mar",
- "Mer",
- "Jeu",
- "Ven",
- "Sam",
- "Dim");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Janvier",
- "FÃ©vrier",
- "Mars",
- "Avril",
- "Mai",
- "Juin",
- "Juillet",
- "AoÃ»t",
- "Septembre",
- "Octobre",
- "Novembre",
- "DÃ©cembre");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Fev",
- "Mar",
- "Avr",
- "Mai",
- "Juin",
- "Juil",
- "Aout",
- "Sep",
- "Oct",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "A propos du calendrier";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Heure Selecteur\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"Pour la derniere version visitez : http://www.dynarch.com/projects/calendar/\n" +
-"DistribuÃ© par GNU LGPL.  Voir http://gnu.org/licenses/lgpl.html pour les details." +
-"\n\n" +
-"Selection de la date :\n" +
-"- Utiliser les bouttons \xab, \xbb  pour selectionner l\'annee\n" +
-"- Utiliser les bouttons " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pour selectionner les mois\n" +
-"- Garder la souris sur n'importe quels boutons pour une selection plus rapide";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Selection de l\'heure :\n" +
-"- Cliquer sur heures ou minutes pour incrementer\n" +
-"- ou Maj-clic pour decrementer\n" +
-"- ou clic et glisser-deplacer pour une selection plus rapide";
-
-Calendar._TT["PREV_YEAR"] = "AnnÃ©e prÃ©c. (maintenir pour menu)";
-Calendar._TT["PREV_MONTH"] = "Mois prÃ©c. (maintenir pour menu)";
-Calendar._TT["GO_TODAY"] = "Atteindre la date du jour";
-Calendar._TT["NEXT_MONTH"] = "Mois suiv. (maintenir pour menu)";
-Calendar._TT["NEXT_YEAR"] = "AnnÃ©e suiv. (maintenir pour menu)";
-Calendar._TT["SEL_DATE"] = "SÃ©lectionner une date";
-Calendar._TT["DRAG_TO_MOVE"] = "DÃ©placer";
-Calendar._TT["PART_TODAY"] = " (Aujourd'hui)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Afficher %s en premier";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Fermer";
-Calendar._TT["TODAY"] = "Aujourd'hui";
-Calendar._TT["TIME_PART"] = "(Maj-)Clic ou glisser pour modifier la valeur";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "Sem.";
-Calendar._TT["TIME"] = "Heure :";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/61/61e50703af02347b6cb421c714576454eb248e4a.svn-base
--- a/.svn/pristine/61/61e50703af02347b6cb421c714576454eb248e4a.svn-base
+++ /dev/null
@@ -1,82 +0,0 @@
-require File.expand_path('../../../../../../test_helper', __FILE__)
-begin
-  require 'mocha'
-
-  class CvsAdapterTest < ActiveSupport::TestCase
-    REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s
-    REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
-    MODULE_NAME = 'test'
-
-    if File.directory?(REPOSITORY_PATH)
-      def setup
-        @adapter = Redmine::Scm::Adapters::CvsAdapter.new(MODULE_NAME, REPOSITORY_PATH)
-      end
-
-      def test_scm_version
-        to_test = { "\nConcurrent Versions System (CVS) 1.12.13 (client/server)\n"  => [1,12,13],
-                    "\r\n1.12.12\r\n1.12.11"                   => [1,12,12],
-                    "1.12.11\r\n1.12.10\r\n"                   => [1,12,11]}
-        to_test.each do |s, v|
-          test_scm_version_for(s, v)
-        end
-      end
-
-      def test_revisions_all
-        cnt = 0
-        @adapter.revisions('', nil, nil, :log_encoding => 'UTF-8') do |revision|
-          cnt += 1
-        end
-        assert_equal 16, cnt
-      end
-
-      def test_revisions_from_rev3
-        rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
-        cnt = 0
-        @adapter.revisions('', rev3_committed_on, nil, :log_encoding => 'UTF-8') do |revision|
-          cnt += 1
-        end
-        assert_equal 4, cnt
-      end
-
-      def test_entries_rev3
-        rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
-        entries = @adapter.entries('sources', rev3_committed_on)
-        assert_equal 2, entries.size
-        assert_equal entries[0].name, "watchers_controller.rb"
-        assert_equal entries[0].lastrev.time, Time.gm(2007, 12, 13, 16, 27, 22)
-      end
-
-      def test_path_encoding_default_utf8
-        adpt1 = Redmine::Scm::Adapters::CvsAdapter.new(
-                                  MODULE_NAME,
-                                  REPOSITORY_PATH
-                                )
-        assert_equal "UTF-8", adpt1.path_encoding
-        adpt2 = Redmine::Scm::Adapters::CvsAdapter.new(
-                                  MODULE_NAME,
-                                  REPOSITORY_PATH,
-                                  nil,
-                                  nil,
-                                  ""
-                                )
-        assert_equal "UTF-8", adpt2.path_encoding
-      end
-
-      private
-
-      def test_scm_version_for(scm_command_version, version)
-        @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
-        assert_equal version, @adapter.class.scm_command_version
-      end
-    else
-      puts "Cvs test repository NOT FOUND. Skipping unit tests !!!"
-      def test_fake; assert true end
-    end
-  end
-
-rescue LoadError
-  class CvsMochaFake < ActiveSupport::TestCase
-    def test_fake; assert(false, "Requires mocha to run those tests")  end
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/61/61f5175c584e56d932e6fd6922f31fce1b57acd4.svn-base
--- /dev/null
+++ b/.svn/pristine/61/61f5175c584e56d932e6fd6922f31fce1b57acd4.svn-base
@@ -0,0 +1,88 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueRelationsController < ApplicationController
+  before_filter :find_issue, :find_project_from_association, :authorize, :only => [:index, :create]
+  before_filter :find_relation, :except => [:index, :create]
+
+  accept_api_auth :index, :show, :create, :destroy
+
+  def index
+    @relations = @issue.relations
+
+    respond_to do |format|
+      format.html { render :nothing => true }
+      format.api
+    end
+  end
+
+  def show
+    raise Unauthorized unless @relation.visible?
+
+    respond_to do |format|
+      format.html { render :nothing => true }
+      format.api
+    end
+  end
+
+  def create
+    @relation = IssueRelation.new(params[:relation])
+    @relation.issue_from = @issue
+    if params[:relation] && m = params[:relation][:issue_to_id].to_s.strip.match(/^#?(\d+)$/)
+      @relation.issue_to = Issue.visible.find_by_id(m[1].to_i)
+    end
+    saved = @relation.save
+
+    respond_to do |format|
+      format.html { redirect_to issue_path(@issue) }
+      format.js {
+        @relations = @issue.reload.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
+      }
+      format.api {
+        if saved
+          render :action => 'show', :status => :created, :location => relation_url(@relation)
+        else
+          render_validation_errors(@relation)
+        end
+      }
+    end
+  end
+
+  def destroy
+    raise Unauthorized unless @relation.deletable?
+    @relation.destroy
+
+    respond_to do |format|
+      format.html { redirect_to issue_path(@relation.issue_from) }
+      format.js
+      format.api  { render_api_ok }
+    end
+  end
+
+private
+  def find_issue
+    @issue = @object = Issue.find(params[:issue_id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def find_relation
+    @relation = IssueRelation.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/62/62244ea8823525f3feb5603a1babb7b2ffdb7ec8.svn-base
--- /dev/null
+++ b/.svn/pristine/62/62244ea8823525f3feb5603a1babb7b2ffdb7ec8.svn-base
@@ -0,0 +1,22 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueObserver < ActiveRecord::Observer
+  def after_create(issue)
+    Mailer.issue_add(issue).deliver if Setting.notified_events.include?('issue_added')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/62/62a5609a8ce41f5e32619c5cb46089fa3e9c24f7.svn-base
--- a/.svn/pristine/62/62a5609a8ce41f5e32619c5cb46089fa3e9c24f7.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar Chinese language
-// Author: Andy Wu, <andywu.zh@gmail.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("æ˜ŸæœŸæ—¥",
- "æ˜ŸæœŸä¸€",
- "æ˜ŸæœŸäºŒ",
- "æ˜ŸæœŸä¸‰",
- "æ˜ŸæœŸå››",
- "æ˜ŸæœŸäº”",
- "æ˜ŸæœŸå…­",
- "æ˜ŸæœŸæ—¥");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("æ—¥",
- "ä¸€",
- "äºŒ",
- "ä¸‰",
- "å››",
- "äº”",
- "å…­",
- "æ—¥");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("1æœˆ",
- "2æœˆ",
- "3æœˆ",
- "4æœˆ",
- "5æœˆ",
- "6æœˆ",
- "7æœˆ",
- "8æœˆ",
- "9æœˆ",
- "10æœˆ",
- "11æœˆ",
- "12æœˆ");
-
-// short month names
-Calendar._SMN = new Array
-("1æœˆ",
- "2æœˆ",
- "3æœˆ",
- "4æœˆ",
- "5æœˆ",
- "6æœˆ",
- "7æœˆ",
- "8æœˆ",
- "9æœˆ",
- "10æœˆ",
- "11æœˆ",
- "12æœˆ");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "å…³äºŽæ—¥åŽ†";
-
-Calendar._TT["ABOUT"] =
-"DHTML æ—¥æœŸ/æ—¶é—´ é€‰æ‹©å™¨\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"æœ€æ–°ç‰ˆæœ¬è¯·è®¿é—®ï¼š http://www.dynarch.com/projects/calendar/\n" +
-"éµå¾ª GNU LGPL å‘å¸ƒã€‚è¯¦æƒ…è¯·æŸ¥é˜… http://gnu.org/licenses/lgpl.html " +
-"\n\n" +
-"æ—¥æœŸé€‰æ‹©ï¼š\n" +
-"- ä½¿ç”¨ \xabï¼Œ\xbb æŒ‰é’®é€‰æ‹©å¹´\n" +
-"- ä½¿ç”¨ " + String.fromCharCode(0x2039) + "ï¼Œ" + String.fromCharCode(0x203a) + " æŒ‰é’®é€‰æ‹©æœˆ\n" +
-"- åœ¨ä¸Šè¿°æŒ‰é’®ä¸ŠæŒ‰ä½ä¸æ”¾å¯ä»¥å¿«é€Ÿé€‰æ‹©";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"æ—¶é—´é€‰æ‹©ï¼š\n" +
-"- ç‚¹å‡»æ—¶é—´çš„ä»»æ„éƒ¨åˆ†æ¥å¢žåŠ \n" +
-"- ShiftåŠ ç‚¹å‡»æ¥å‡å°‘\n" +
-"- ç‚¹å‡»åŽæ‹–åŠ¨è¿›è¡Œå¿«é€Ÿé€‰æ‹©";
-
-Calendar._TT["PREV_YEAR"] = "ä¸Šå¹´ï¼ˆæŒ‰ä½ä¸æ”¾æ˜¾ç¤ºèœå•ï¼‰";
-Calendar._TT["PREV_MONTH"] = "ä¸Šæœˆï¼ˆæŒ‰ä½ä¸æ”¾æ˜¾ç¤ºèœå•ï¼‰";
-Calendar._TT["GO_TODAY"] = "å›žåˆ°ä»Šå¤©";
-Calendar._TT["NEXT_MONTH"] = "ä¸‹æœˆï¼ˆæŒ‰ä½ä¸æ”¾æ˜¾ç¤ºèœå•ï¼‰";
-Calendar._TT["NEXT_YEAR"] = "ä¸‹å¹´ï¼ˆæŒ‰ä½ä¸æ”¾æ˜¾ç¤ºèœå•ï¼‰";
-Calendar._TT["SEL_DATE"] = "é€‰æ‹©æ—¥æœŸ";
-Calendar._TT["DRAG_TO_MOVE"] = "æ‹–åŠ¨";
-Calendar._TT["PART_TODAY"] = " (ä»Šæ—¥)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "ä¸€å‘¨å¼€å§‹äºŽ %s";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "å…³é—­";
-Calendar._TT["TODAY"] = "ä»Šå¤©";
-Calendar._TT["TIME_PART"] = "ShiftåŠ ç‚¹å‡»æˆ–è€…æ‹–åŠ¨æ¥å˜æ›´";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "æ˜ŸæœŸ%a %b%eæ—¥";
-
-Calendar._TT["WK"] = "å‘¨";
-Calendar._TT["TIME"] = "æ—¶é—´ï¼š";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/62/62c1677139f8e602a41e89d444679c525b9002b9.svn-base
--- /dev/null
+++ b/.svn/pristine/62/62c1677139f8e602a41e89d444679c525b9002b9.svn-base
@@ -0,0 +1,604 @@
+# -*- coding: utf-8 -*-
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class TimelogControllerTest < ActionController::TestCase
+  fixtures :projects, :enabled_modules, :roles, :members,
+           :member_roles, :issues, :time_entries, :users,
+           :trackers, :enumerations, :issue_statuses,
+           :custom_fields, :custom_values,
+           :projects_trackers, :custom_fields_trackers,
+           :custom_fields_projects
+
+  include Redmine::I18n
+
+  def test_new_with_project_id
+    @request.session[:user_id] = 3
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+    assert_select 'select[name=?]', 'time_entry[project_id]', 0
+    assert_select 'input[name=?][value=1][type=hidden]', 'time_entry[project_id]'
+  end
+
+  def test_new_with_issue_id
+    @request.session[:user_id] = 3
+    get :new, :issue_id => 2
+    assert_response :success
+    assert_template 'new'
+    assert_select 'select[name=?]', 'time_entry[project_id]', 0
+    assert_select 'input[name=?][value=1][type=hidden]', 'time_entry[project_id]'
+  end
+
+  def test_new_without_project
+    @request.session[:user_id] = 3
+    get :new
+    assert_response :success
+    assert_template 'new'
+    assert_select 'select[name=?]', 'time_entry[project_id]'
+    assert_select 'input[name=?]', 'time_entry[project_id]', 0
+  end
+
+  def test_new_without_project_should_prefill_the_form
+    @request.session[:user_id] = 3
+    get :new, :time_entry => {:project_id => '1'}
+    assert_response :success
+    assert_template 'new'
+    assert_select 'select[name=?]', 'time_entry[project_id]' do
+      assert_select 'option[value=1][selected=selected]'
+    end
+    assert_select 'input[name=?]', 'time_entry[project_id]', 0
+  end
+
+  def test_new_without_project_should_deny_without_permission
+    Role.all.each {|role| role.remove_permission! :log_time}
+    @request.session[:user_id] = 3
+
+    get :new
+    assert_response 403
+  end
+
+  def test_new_should_select_default_activity
+    @request.session[:user_id] = 3
+    get :new, :project_id => 1
+    assert_response :success
+    assert_select 'select[name=?]', 'time_entry[activity_id]' do
+      assert_select 'option[selected=selected]', :text => 'Development'
+    end
+  end
+
+  def test_new_should_only_show_active_time_entry_activities
+    @request.session[:user_id] = 3
+    get :new, :project_id => 1
+    assert_response :success
+    assert_no_tag 'option', :content => 'Inactive Activity'
+  end
+
+  def test_get_edit_existing_time
+    @request.session[:user_id] = 2
+    get :edit, :id => 2, :project_id => nil
+    assert_response :success
+    assert_template 'edit'
+    # Default activity selected
+    assert_tag :tag => 'form', :attributes => { :action => '/projects/ecookbook/time_entries/2' }
+  end
+
+  def test_get_edit_with_an_existing_time_entry_with_inactive_activity
+    te = TimeEntry.find(1)
+    te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
+    te.save!
+
+    @request.session[:user_id] = 1
+    get :edit, :project_id => 1, :id => 1
+    assert_response :success
+    assert_template 'edit'
+    # Blank option since nothing is pre-selected
+    assert_tag :tag => 'option', :content => '--- Please select ---'
+  end
+
+  def test_post_create
+    # TODO: should POST to issuesâ€™ time log instead of project. change form
+    # and routing
+    @request.session[:user_id] = 3
+    post :create, :project_id => 1,
+                :time_entry => {:comments => 'Some work on TimelogControllerTest',
+                                # Not the default activity
+                                :activity_id => '11',
+                                :spent_on => '2008-03-14',
+                                :issue_id => '1',
+                                :hours => '7.3'}
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+
+    i = Issue.find(1)
+    t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
+    assert_not_nil t
+    assert_equal 11, t.activity_id
+    assert_equal 7.3, t.hours
+    assert_equal 3, t.user_id
+    assert_equal i, t.issue
+    assert_equal i.project, t.project
+  end
+
+  def test_post_create_with_blank_issue
+    # TODO: should POST to issuesâ€™ time log instead of project. change form
+    # and routing
+    @request.session[:user_id] = 3
+    post :create, :project_id => 1,
+                :time_entry => {:comments => 'Some work on TimelogControllerTest',
+                                # Not the default activity
+                                :activity_id => '11',
+                                :issue_id => '',
+                                :spent_on => '2008-03-14',
+                                :hours => '7.3'}
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+
+    t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
+    assert_not_nil t
+    assert_equal 11, t.activity_id
+    assert_equal 7.3, t.hours
+    assert_equal 3, t.user_id
+  end
+
+  def test_create_and_continue
+    @request.session[:user_id] = 2
+    post :create, :project_id => 1,
+                :time_entry => {:activity_id => '11',
+                                :issue_id => '',
+                                :spent_on => '2008-03-14',
+                                :hours => '7.3'},
+                :continue => '1'
+    assert_redirected_to '/projects/ecookbook/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D='
+  end
+
+  def test_create_and_continue_with_issue_id
+    @request.session[:user_id] = 2
+    post :create, :project_id => 1,
+                :time_entry => {:activity_id => '11',
+                                :issue_id => '1',
+                                :spent_on => '2008-03-14',
+                                :hours => '7.3'},
+                :continue => '1'
+    assert_redirected_to '/projects/ecookbook/issues/1/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=1'
+  end
+
+  def test_create_and_continue_without_project
+    @request.session[:user_id] = 2
+    post :create, :time_entry => {:project_id => '1',
+                                :activity_id => '11',
+                                :issue_id => '',
+                                :spent_on => '2008-03-14',
+                                :hours => '7.3'},
+                  :continue => '1'
+
+    assert_redirected_to '/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=&time_entry%5Bproject_id%5D=1'
+  end
+
+  def test_create_without_log_time_permission_should_be_denied
+    @request.session[:user_id] = 2
+    Role.find_by_name('Manager').remove_permission! :log_time
+    post :create, :project_id => 1,
+                :time_entry => {:activity_id => '11',
+                                :issue_id => '',
+                                :spent_on => '2008-03-14',
+                                :hours => '7.3'}
+
+    assert_response 403
+  end
+
+  def test_create_with_failure
+    @request.session[:user_id] = 2
+    post :create, :project_id => 1,
+                :time_entry => {:activity_id => '',
+                                :issue_id => '',
+                                :spent_on => '2008-03-14',
+                                :hours => '7.3'}
+
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_create_without_project
+    @request.session[:user_id] = 2
+    assert_difference 'TimeEntry.count' do
+      post :create, :time_entry => {:project_id => '1',
+                                  :activity_id => '11',
+                                  :issue_id => '',
+                                  :spent_on => '2008-03-14',
+                                  :hours => '7.3'}
+    end
+
+    assert_redirected_to '/projects/ecookbook/time_entries'
+    time_entry = TimeEntry.first(:order => 'id DESC')
+    assert_equal 1, time_entry.project_id
+  end
+
+  def test_create_without_project_should_fail_with_issue_not_inside_project
+    @request.session[:user_id] = 2
+    assert_no_difference 'TimeEntry.count' do
+      post :create, :time_entry => {:project_id => '1',
+                                  :activity_id => '11',
+                                  :issue_id => '5',
+                                  :spent_on => '2008-03-14',
+                                  :hours => '7.3'}
+    end
+
+    assert_response :success
+    assert assigns(:time_entry).errors[:issue_id].present?
+  end
+
+  def test_create_without_project_should_deny_without_permission
+    @request.session[:user_id] = 2
+    Project.find(3).disable_module!(:time_tracking)
+
+    assert_no_difference 'TimeEntry.count' do
+      post :create, :time_entry => {:project_id => '3',
+                                  :activity_id => '11',
+                                  :issue_id => '',
+                                  :spent_on => '2008-03-14',
+                                  :hours => '7.3'}
+    end
+
+    assert_response 403
+  end
+
+  def test_create_without_project_with_failure
+    @request.session[:user_id] = 2
+    assert_no_difference 'TimeEntry.count' do
+      post :create, :time_entry => {:project_id => '1',
+                                  :activity_id => '11',
+                                  :issue_id => '',
+                                  :spent_on => '2008-03-14',
+                                  :hours => ''}
+    end
+
+    assert_response :success
+    assert_tag 'select', :attributes => {:name => 'time_entry[project_id]'},
+      :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}}
+  end
+
+  def test_update
+    entry = TimeEntry.find(1)
+    assert_equal 1, entry.issue_id
+    assert_equal 2, entry.user_id
+
+    @request.session[:user_id] = 1
+    put :update, :id => 1,
+                :time_entry => {:issue_id => '2',
+                                :hours => '8'}
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    entry.reload
+
+    assert_equal 8, entry.hours
+    assert_equal 2, entry.issue_id
+    assert_equal 2, entry.user_id
+  end
+
+  def test_get_bulk_edit
+    @request.session[:user_id] = 2
+    get :bulk_edit, :ids => [1, 2]
+    assert_response :success
+    assert_template 'bulk_edit'
+
+    assert_select 'ul#bulk-selection' do
+      assert_select 'li', 2
+      assert_select 'li a', :text => '03/23/2007 - eCookbook: 4.25 hours'
+    end
+
+    assert_select 'form#bulk_edit_form[action=?]', '/time_entries/bulk_update' do
+      # System wide custom field
+      assert_select 'select[name=?]', 'time_entry[custom_field_values][10]'
+  
+      # Activities
+      assert_select 'select[name=?]', 'time_entry[activity_id]' do
+        assert_select 'option[value=]', :text => '(No change)'
+        assert_select 'option[value=9]', :text => 'Design'
+      end
+    end
+  end
+
+  def test_get_bulk_edit_on_different_projects
+    @request.session[:user_id] = 2
+    get :bulk_edit, :ids => [1, 2, 6]
+    assert_response :success
+    assert_template 'bulk_edit'
+  end
+
+  def test_bulk_update
+    @request.session[:user_id] = 2
+    # update time entry activity
+    post :bulk_update, :ids => [1, 2], :time_entry => { :activity_id => 9}
+
+    assert_response 302
+    # check that the issues were updated
+    assert_equal [9, 9], TimeEntry.find_all_by_id([1, 2]).collect {|i| i.activity_id}
+  end
+
+  def test_bulk_update_with_failure
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 2], :time_entry => { :hours => 'A'}
+
+    assert_response 302
+    assert_match /Failed to save 2 time entrie/, flash[:error]
+  end
+
+  def test_bulk_update_on_different_projects
+    @request.session[:user_id] = 2
+    # makes user a manager on the other project
+    Member.create!(:user_id => 2, :project_id => 3, :role_ids => [1])
+    
+    # update time entry activity
+    post :bulk_update, :ids => [1, 2, 4], :time_entry => { :activity_id => 9 }
+
+    assert_response 302
+    # check that the issues were updated
+    assert_equal [9, 9, 9], TimeEntry.find_all_by_id([1, 2, 4]).collect {|i| i.activity_id}
+  end
+
+  def test_bulk_update_on_different_projects_without_rights
+    @request.session[:user_id] = 3
+    user = User.find(3)
+    action = { :controller => "timelog", :action => "bulk_update" }
+    assert user.allowed_to?(action, TimeEntry.find(1).project)
+    assert ! user.allowed_to?(action, TimeEntry.find(5).project)
+    post :bulk_update, :ids => [1, 5], :time_entry => { :activity_id => 9 }
+    assert_response 403
+  end
+
+  def test_bulk_update_custom_field
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 2], :time_entry => { :custom_field_values => {'10' => '0'} }
+
+    assert_response 302
+    assert_equal ["0", "0"], TimeEntry.find_all_by_id([1, 2]).collect {|i| i.custom_value_for(10).value}
+  end
+
+  def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1,2], :back_url => '/time_entries'
+
+    assert_response :redirect
+    assert_redirected_to '/time_entries'
+  end
+
+  def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
+
+    assert_response :redirect
+    assert_redirected_to :controller => 'timelog', :action => 'index', :project_id => Project.find(1).identifier
+  end
+
+  def test_post_bulk_update_without_edit_permission_should_be_denied
+    @request.session[:user_id] = 2
+    Role.find_by_name('Manager').remove_permission! :edit_time_entries
+    post :bulk_update, :ids => [1,2]
+
+    assert_response 403
+  end
+
+  def test_destroy
+    @request.session[:user_id] = 2
+    delete :destroy, :id => 1
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    assert_equal I18n.t(:notice_successful_delete), flash[:notice]
+    assert_nil TimeEntry.find_by_id(1)
+  end
+
+  def test_destroy_should_fail
+    # simulate that this fails (e.g. due to a plugin), see #5700
+    TimeEntry.any_instance.expects(:destroy).returns(false)
+
+    @request.session[:user_id] = 2
+    delete :destroy, :id => 1
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    assert_equal I18n.t(:notice_unable_delete_time_entry), flash[:error]
+    assert_not_nil TimeEntry.find_by_id(1)
+  end
+
+  def test_index_all_projects
+    get :index
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:total_hours)
+    assert_equal "162.90", "%.2f" % assigns(:total_hours)
+    assert_tag :form,
+      :attributes => {:action => "/time_entries", :id => 'query_form'}
+  end
+
+  def test_index_all_projects_should_show_log_time_link
+    @request.session[:user_id] = 2
+    get :index
+    assert_response :success
+    assert_template 'index'
+    assert_tag 'a', :attributes => {:href => '/time_entries/new'}, :content => /Log time/
+  end
+
+  def test_index_at_project_level
+    get :index, :project_id => 'ecookbook'
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:entries)
+    assert_equal 4, assigns(:entries).size
+    # project and subproject
+    assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
+    assert_not_nil assigns(:total_hours)
+    assert_equal "162.90", "%.2f" % assigns(:total_hours)
+    assert_tag :form,
+      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
+  end
+
+  def test_index_at_project_level_with_date_range
+    get :index, :project_id => 'ecookbook',
+      :f => ['spent_on'],
+      :op => {'spent_on' => '><'},
+      :v => {'spent_on' => ['2007-03-20', '2007-04-30']}
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:entries)
+    assert_equal 3, assigns(:entries).size
+    assert_not_nil assigns(:total_hours)
+    assert_equal "12.90", "%.2f" % assigns(:total_hours)
+    assert_tag :form,
+      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
+  end
+
+  def test_index_at_project_level_with_date_range_using_from_and_to_params
+    get :index, :project_id => 'ecookbook', :from => '2007-03-20', :to => '2007-04-30'
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:entries)
+    assert_equal 3, assigns(:entries).size
+    assert_not_nil assigns(:total_hours)
+    assert_equal "12.90", "%.2f" % assigns(:total_hours)
+    assert_tag :form,
+      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
+  end
+
+  def test_index_at_project_level_with_period
+    get :index, :project_id => 'ecookbook',
+      :f => ['spent_on'],
+      :op => {'spent_on' => '>t-'},
+      :v => {'spent_on' => ['7']}
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:entries)
+    assert_not_nil assigns(:total_hours)
+    assert_tag :form,
+      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
+  end
+
+  def test_index_at_issue_level
+    get :index, :issue_id => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:entries)
+    assert_equal 2, assigns(:entries).size
+    assert_not_nil assigns(:total_hours)
+    assert_equal 154.25, assigns(:total_hours)
+    # display all time
+    assert_nil assigns(:from)
+    assert_nil assigns(:to)
+    # TODO: remove /projects/:project_id/issues/:issue_id/time_entries routes
+    # to use /issues/:issue_id/time_entries
+    assert_tag :form,
+      :attributes => {:action => "/projects/ecookbook/issues/1/time_entries", :id => 'query_form'}
+  end
+
+  def test_index_should_sort_by_spent_on_and_created_on
+    t1 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-16', :created_on => '2012-06-16 20:00:00', :activity_id => 10)
+    t2 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-16', :created_on => '2012-06-16 20:05:00', :activity_id => 10)
+    t3 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-15', :created_on => '2012-06-16 20:10:00', :activity_id => 10)
+
+    get :index, :project_id => 1,
+      :f => ['spent_on'],
+      :op => {'spent_on' => '><'},
+      :v => {'spent_on' => ['2012-06-15', '2012-06-16']}
+    assert_response :success
+    assert_equal [t2, t1, t3], assigns(:entries)
+
+    get :index, :project_id => 1,
+      :f => ['spent_on'],
+      :op => {'spent_on' => '><'},
+      :v => {'spent_on' => ['2012-06-15', '2012-06-16']},
+      :sort => 'spent_on'
+    assert_response :success
+    assert_equal [t3, t1, t2], assigns(:entries)
+  end
+
+  def test_index_with_filter_on_issue_custom_field
+    issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {2 => 'filter_on_issue_custom_field'})
+    entry = TimeEntry.generate!(:issue => issue, :hours => 2.5)
+
+    get :index, :f => ['issue.cf_2'], :op => {'issue.cf_2' => '='}, :v => {'issue.cf_2' => ['filter_on_issue_custom_field']}
+    assert_response :success
+    assert_equal [entry], assigns(:entries)
+  end
+
+  def test_index_with_issue_custom_field_column
+    issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {2 => 'filter_on_issue_custom_field'})
+    entry = TimeEntry.generate!(:issue => issue, :hours => 2.5)
+
+    get :index, :c => %w(project spent_on issue comments hours issue.cf_2)
+    assert_response :success
+    assert_include :'issue.cf_2', assigns(:query).column_names
+    assert_select 'td.issue_cf_2', :text => 'filter_on_issue_custom_field'
+  end
+
+  def test_index_atom_feed
+    get :index, :project_id => 1, :format => 'atom'
+    assert_response :success
+    assert_equal 'application/atom+xml', @response.content_type
+    assert_not_nil assigns(:items)
+    assert assigns(:items).first.is_a?(TimeEntry)
+  end
+
+  def test_index_at_project_level_should_include_csv_export_dialog
+    get :index, :project_id => 'ecookbook', 
+      :f => ['spent_on'],
+      :op => {'spent_on' => '>='},
+      :v => {'spent_on' => ['2007-04-01']},
+      :c => ['spent_on', 'user']
+    assert_response :success
+
+    assert_select '#csv-export-options' do
+      assert_select 'form[action=?][method=get]', '/projects/ecookbook/time_entries.csv' do
+        # filter
+        assert_select 'input[name=?][value=?]', 'f[]', 'spent_on'
+        assert_select 'input[name=?][value=?]', 'op[spent_on]', '&gt;='
+        assert_select 'input[name=?][value=?]', 'v[spent_on][]', '2007-04-01'
+        # columns
+        assert_select 'input[name=?][value=?]', 'c[]', 'spent_on'
+        assert_select 'input[name=?][value=?]', 'c[]', 'user'
+        assert_select 'input[name=?]', 'c[]', 2
+      end
+    end
+  end
+
+  def test_index_cross_project_should_include_csv_export_dialog
+    get :index
+    assert_response :success
+
+    assert_select '#csv-export-options' do
+      assert_select 'form[action=?][method=get]', '/time_entries.csv'
+    end
+  end
+
+  def test_index_at_issue_level_should_include_csv_export_dialog
+    get :index, :project_id => 'ecookbook', :issue_id => 3
+    assert_response :success
+
+    assert_select '#csv-export-options' do
+      assert_select 'form[action=?][method=get]', '/projects/ecookbook/issues/3/time_entries.csv'
+    end
+  end
+
+  def test_index_csv_all_projects
+    Setting.date_format = '%m/%d/%Y'
+    get :index, :format => 'csv'
+    assert_response :success
+    assert_equal 'text/csv; header=present', response.content_type
+  end
+
+  def test_index_csv
+    Setting.date_format = '%m/%d/%Y'
+    get :index, :project_id => 1, :format => 'csv'
+    assert_response :success
+    assert_equal 'text/csv; header=present', response.content_type
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/62/62d25b06b15c0b260279da71be5d88bfab79f61e.svn-base
--- a/.svn/pristine/62/62d25b06b15c0b260279da71be5d88bfab79f61e.svn-base
+++ /dev/null
@@ -1,131 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class WikiPageTest < ActiveSupport::TestCase
-  fixtures :projects, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
-
-  def setup
-    @wiki = Wiki.find(1)
-    @page = @wiki.pages.first
-  end
-
-  def test_create
-    page = WikiPage.new(:wiki => @wiki)
-    assert !page.save
-    assert_equal 1, page.errors.count
-
-    page.title = "Page"
-    assert page.save
-    page.reload
-    assert !page.protected?
-
-    @wiki.reload
-    assert @wiki.pages.include?(page)
-  end
-
-  def test_sidebar_should_be_protected_by_default
-    page = @wiki.find_or_new_page('sidebar')
-    assert page.new_record?
-    assert page.protected?
-  end
-
-  def test_find_or_new_page
-    page = @wiki.find_or_new_page("CookBook documentation")
-    assert_kind_of WikiPage, page
-    assert !page.new_record?
-
-    page = @wiki.find_or_new_page("Non existing page")
-    assert_kind_of WikiPage, page
-    assert page.new_record?
-  end
-
-  def test_parent_title
-    page = WikiPage.find_by_title('Another_page')
-    assert_nil page.parent_title
-
-    page = WikiPage.find_by_title('Page_with_an_inline_image')
-    assert_equal 'CookBook documentation', page.parent_title
-  end
-
-  def test_assign_parent
-    page = WikiPage.find_by_title('Another_page')
-    page.parent_title = 'CookBook documentation'
-    assert page.save
-    page.reload
-    assert_equal WikiPage.find_by_title('CookBook_documentation'), page.parent
-  end
-
-  def test_unassign_parent
-    page = WikiPage.find_by_title('Page_with_an_inline_image')
-    page.parent_title = ''
-    assert page.save
-    page.reload
-    assert_nil page.parent
-  end
-
-  def test_parent_validation
-    page = WikiPage.find_by_title('CookBook_documentation')
-
-    # A page that doesn't exist
-    page.parent_title = 'Unknown title'
-    assert !page.save
-    assert_equal I18n.translate('activerecord.errors.messages.invalid'), page.errors.on(:parent_title)
-    # A child page
-    page.parent_title = 'Page_with_an_inline_image'
-    assert !page.save
-    assert_equal I18n.translate('activerecord.errors.messages.circular_dependency'), page.errors.on(:parent_title)
-    # The page itself
-    page.parent_title = 'CookBook_documentation'
-    assert !page.save
-    assert_equal I18n.translate('activerecord.errors.messages.circular_dependency'), page.errors.on(:parent_title)
-
-    page.parent_title = 'Another_page'
-    assert page.save
-  end
-
-  def test_destroy
-    page = WikiPage.find(1)
-    page.destroy
-    assert_nil WikiPage.find_by_id(1)
-    # make sure that page content and its history are deleted
-    assert WikiContent.find_all_by_page_id(1).empty?
-    assert WikiContent.versioned_class.find_all_by_page_id(1).empty?
-  end
-
-  def test_destroy_should_not_nullify_children
-    page = WikiPage.find(2)
-    child_ids = page.child_ids
-    assert child_ids.any?
-    page.destroy
-    assert_nil WikiPage.find_by_id(2)
-
-    children = WikiPage.find_all_by_id(child_ids)
-    assert_equal child_ids.size, children.size
-    children.each do |child|
-      assert_nil child.parent_id
-    end
-  end
-
-  def test_updated_on_eager_load
-    page = WikiPage.with_updated_on.first
-    assert page.is_a?(WikiPage)
-    assert_not_nil page.read_attribute(:updated_on)
-    assert_equal page.content.updated_on, page.updated_on
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/62/62ecd1bfcad4ed987069f0252b9c65f6abdbb461.svn-base
--- /dev/null
+++ b/.svn/pristine/62/62ecd1bfcad4ed987069f0252b9c65f6abdbb461.svn-base
@@ -0,0 +1,72 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class UserPreferenceTest < ActiveSupport::TestCase
+  fixtures :users, :user_preferences
+
+  def test_create
+    user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
+    user.login = "newuser"
+    user.password, user.password_confirmation = "password", "password"
+    assert user.save
+
+    assert_kind_of UserPreference, user.pref
+    assert_kind_of Hash, user.pref.others
+    assert user.pref.save
+  end
+
+  def test_update
+    user = User.find(1)
+    assert_equal true, user.pref.hide_mail
+    user.pref['preftest'] = 'value'
+    assert user.pref.save
+
+    user.reload
+    assert_equal 'value', user.pref['preftest']
+  end
+
+  def test_others_hash
+    user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
+    user.login = "newuser"
+    user.password, user.password_confirmation = "password", "password"
+    assert user.save
+    assert_nil user.preference
+    up = UserPreference.new(:user => user)
+    assert_kind_of Hash, up.others
+    up.others = nil
+    assert_nil up.others
+    assert up.save
+    assert_kind_of Hash, up.others
+  end
+
+  def test_reading_value_from_nil_others_hash
+    up = UserPreference.new(:user => User.new)
+    up.others = nil
+    assert_nil up.others
+    assert_nil up[:foo]
+  end
+
+  def test_writing_value_to_nil_others_hash
+    up = UserPreference.new(:user => User.new)
+    up.others = nil
+    assert_nil up.others
+    up[:foo] = 'bar'
+    assert_equal 'bar', up[:foo]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/63/6337da68aa661918822db9c4ab113e8ae3671adf.svn-base
--- /dev/null
+++ b/.svn/pristine/63/6337da68aa661918822db9c4ab113e8ae3671adf.svn-base
@@ -0,0 +1,846 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
+  fixtures :projects,
+    :users,
+    :roles,
+    :members,
+    :member_roles,
+    :issues,
+    :issue_statuses,
+    :issue_relations,
+    :versions,
+    :trackers,
+    :projects_trackers,
+    :issue_categories,
+    :enabled_modules,
+    :enumerations,
+    :attachments,
+    :workflows,
+    :custom_fields,
+    :custom_values,
+    :custom_fields_projects,
+    :custom_fields_trackers,
+    :time_entries,
+    :journals,
+    :journal_details,
+    :queries,
+    :attachments
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "/issues" do
+    # Use a private project to make sure auth is really working and not just
+    # only showing public issues.
+    should_allow_api_authentication(:get, "/projects/private-child/issues.xml")
+
+    should "contain metadata" do
+      get '/issues.xml'
+
+      assert_tag :tag => 'issues',
+        :attributes => {
+          :type => 'array',
+          :total_count => assigns(:issue_count),
+          :limit => 25,
+          :offset => 0
+        }
+    end
+
+    context "with offset and limit" do
+      should "use the params" do
+        get '/issues.xml?offset=2&limit=3'
+
+        assert_equal 3, assigns(:limit)
+        assert_equal 2, assigns(:offset)
+        assert_tag :tag => 'issues', :children => {:count => 3, :only => {:tag => 'issue'}}
+      end
+    end
+
+    context "with nometa param" do
+      should "not contain metadata" do
+        get '/issues.xml?nometa=1'
+
+        assert_tag :tag => 'issues',
+          :attributes => {
+            :type => 'array',
+            :total_count => nil,
+            :limit => nil,
+            :offset => nil
+          }
+      end
+    end
+
+    context "with nometa header" do
+      should "not contain metadata" do
+        get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'}
+
+        assert_tag :tag => 'issues',
+          :attributes => {
+            :type => 'array',
+            :total_count => nil,
+            :limit => nil,
+            :offset => nil
+          }
+      end
+    end
+
+    context "with relations" do
+      should "display relations" do
+        get '/issues.xml?include=relations'
+
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+        assert_tag 'relations',
+          :parent => {:tag => 'issue', :child => {:tag => 'id', :content => '3'}},
+          :children => {:count => 1},
+          :child => {
+            :tag => 'relation',
+            :attributes => {:id => '2', :issue_id => '2', :issue_to_id => '3',
+                            :relation_type => 'relates'}
+          }
+        assert_tag 'relations',
+          :parent => {:tag => 'issue', :child => {:tag => 'id', :content => '1'}},
+          :children => {:count => 0}
+      end
+    end
+
+    context "with invalid query params" do
+      should "return errors" do
+        get '/issues.xml', {:f => ['start_date'], :op => {:start_date => '='}}
+
+        assert_response :unprocessable_entity
+        assert_equal 'application/xml', @response.content_type
+        assert_tag 'errors', :child => {:tag => 'error', :content => "Start date can't be blank"}
+      end
+    end
+
+    context "with custom field filter" do
+      should "show only issues with the custom field value" do
+        get '/issues.xml',
+            {:set_filter => 1, :f => ['cf_1'], :op => {:cf_1 => '='},
+             :v => {:cf_1 => ['MySQL']}}
+        expected_ids = Issue.visible.all(
+            :include => :custom_values,
+            :conditions => {:custom_values => {:custom_field_id => 1, :value => 'MySQL'}}).map(&:id)
+        assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
+           ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
+        end
+      end
+    end
+
+    context "with custom field filter (shorthand method)" do
+      should "show only issues with the custom field value" do
+        get '/issues.xml', { :cf_1 => 'MySQL' }
+
+        expected_ids = Issue.visible.all(
+            :include => :custom_values,
+            :conditions => {:custom_values => {:custom_field_id => 1, :value => 'MySQL'}}).map(&:id)
+
+        assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
+          ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
+        end
+      end
+    end
+  end
+
+  context "/index.json" do
+    should_allow_api_authentication(:get, "/projects/private-child/issues.json")
+  end
+
+  context "/index.xml with filter" do
+    should "show only issues with the status_id" do
+      get '/issues.xml?status_id=5'
+
+      expected_ids = Issue.visible.all(:conditions => {:status_id => 5}).map(&:id)
+
+      assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
+         ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
+      end
+    end
+  end
+
+  context "/index.json with filter" do
+    should "show only issues with the status_id" do
+      get '/issues.json?status_id=5'
+
+      json = ActiveSupport::JSON.decode(response.body)
+      status_ids_used = json['issues'].collect {|j| j['status']['id'] }
+      assert_equal 3, status_ids_used.length
+      assert status_ids_used.all? {|id| id == 5 }
+    end
+
+  end
+
+  # Issue 6 is on a private project
+  context "/issues/6.xml" do
+    should_allow_api_authentication(:get, "/issues/6.xml")
+  end
+
+  context "/issues/6.json" do
+    should_allow_api_authentication(:get, "/issues/6.json")
+  end
+
+  context "GET /issues/:id" do
+    context "with journals" do
+      context ".xml" do
+        should "display journals" do
+          get '/issues/1.xml?include=journals'
+
+          assert_tag :tag => 'issue',
+            :child => {
+              :tag => 'journals',
+              :attributes => { :type => 'array' },
+              :child => {
+                :tag => 'journal',
+                :attributes => { :id => '1'},
+                :child => {
+                  :tag => 'details',
+                  :attributes => { :type => 'array' },
+                  :child => {
+                    :tag => 'detail',
+                    :attributes => { :name => 'status_id' },
+                    :child => {
+                      :tag => 'old_value',
+                      :content => '1',
+                      :sibling => {
+                        :tag => 'new_value',
+                        :content => '2'
+                      }
+                    }
+                  }
+                }
+              }
+            }
+        end
+      end
+    end
+
+    context "with custom fields" do
+      context ".xml" do
+        should "display custom fields" do
+          get '/issues/3.xml'
+
+          assert_tag :tag => 'issue',
+            :child => {
+              :tag => 'custom_fields',
+              :attributes => { :type => 'array' },
+              :child => {
+                :tag => 'custom_field',
+                :attributes => { :id => '1'},
+                :child => {
+                  :tag => 'value',
+                  :content => 'MySQL'
+                }
+              }
+            }
+
+          assert_nothing_raised do
+            Hash.from_xml(response.body).to_xml
+          end
+        end
+      end
+    end
+
+    context "with multi custom fields" do
+      setup do
+        field = CustomField.find(1)
+        field.update_attribute :multiple, true
+        issue = Issue.find(3)
+        issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
+        issue.save!
+      end
+
+      context ".xml" do
+        should "display custom fields" do
+          get '/issues/3.xml'
+          assert_response :success
+          assert_tag :tag => 'issue',
+            :child => {
+              :tag => 'custom_fields',
+              :attributes => { :type => 'array' },
+              :child => {
+                :tag => 'custom_field',
+                :attributes => { :id => '1'},
+                :child => {
+                  :tag => 'value',
+                  :attributes => { :type => 'array' },
+                  :children => { :count => 2 }
+                }
+              }
+            }
+
+          xml = Hash.from_xml(response.body)
+          custom_fields = xml['issue']['custom_fields']
+          assert_kind_of Array, custom_fields
+          field = custom_fields.detect {|f| f['id'] == '1'}
+          assert_kind_of Hash, field
+          assert_equal ['MySQL', 'Oracle'], field['value'].sort
+        end
+      end
+
+      context ".json" do
+        should "display custom fields" do
+          get '/issues/3.json'
+          assert_response :success
+          json = ActiveSupport::JSON.decode(response.body)
+          custom_fields = json['issue']['custom_fields']
+          assert_kind_of Array, custom_fields
+          field = custom_fields.detect {|f| f['id'] == 1}
+          assert_kind_of Hash, field
+          assert_equal ['MySQL', 'Oracle'], field['value'].sort
+        end
+      end
+    end
+
+    context "with empty value for multi custom field" do
+      setup do
+        field = CustomField.find(1)
+        field.update_attribute :multiple, true
+        issue = Issue.find(3)
+        issue.custom_field_values = {1 => ['']}
+        issue.save!
+      end
+
+      context ".xml" do
+        should "display custom fields" do
+          get '/issues/3.xml'
+          assert_response :success
+          assert_tag :tag => 'issue',
+            :child => {
+              :tag => 'custom_fields',
+              :attributes => { :type => 'array' },
+              :child => {
+                :tag => 'custom_field',
+                :attributes => { :id => '1'},
+                :child => {
+                  :tag => 'value',
+                  :attributes => { :type => 'array' },
+                  :children => { :count => 0 }
+                }
+              }
+            }
+
+          xml = Hash.from_xml(response.body)
+          custom_fields = xml['issue']['custom_fields']
+          assert_kind_of Array, custom_fields
+          field = custom_fields.detect {|f| f['id'] == '1'}
+          assert_kind_of Hash, field
+          assert_equal [], field['value']
+        end
+      end
+
+      context ".json" do
+        should "display custom fields" do
+          get '/issues/3.json'
+          assert_response :success
+          json = ActiveSupport::JSON.decode(response.body)
+          custom_fields = json['issue']['custom_fields']
+          assert_kind_of Array, custom_fields
+          field = custom_fields.detect {|f| f['id'] == 1}
+          assert_kind_of Hash, field
+          assert_equal [], field['value'].sort
+        end
+      end
+    end
+
+    context "with attachments" do
+      context ".xml" do
+        should "display attachments" do
+          get '/issues/3.xml?include=attachments'
+
+          assert_tag :tag => 'issue',
+            :child => {
+              :tag => 'attachments',
+              :children => {:count => 5},
+              :child => {
+                :tag => 'attachment',
+                :child => {
+                  :tag => 'filename',
+                  :content => 'source.rb',
+                  :sibling => {
+                    :tag => 'content_url',
+                    :content => 'http://www.example.com/attachments/download/4/source.rb'
+                  }
+                }
+              }
+            }
+        end
+      end
+    end
+
+    context "with subtasks" do
+      setup do
+        @c1 = Issue.create!(
+                :status_id => 1, :subject => "child c1",
+                :tracker_id => 1, :project_id => 1, :author_id => 1,
+                :parent_issue_id => 1
+              )
+        @c2 = Issue.create!(
+                :status_id => 1, :subject => "child c2",
+                :tracker_id => 1, :project_id => 1, :author_id => 1,
+                :parent_issue_id => 1
+              )
+        @c3 = Issue.create!(
+                :status_id => 1, :subject => "child c3",
+                :tracker_id => 1, :project_id => 1, :author_id => 1,
+                :parent_issue_id => @c1.id
+              )
+      end
+
+      context ".xml" do
+        should "display children" do
+          get '/issues/1.xml?include=children'
+
+          assert_tag :tag => 'issue',
+            :child => {
+              :tag => 'children',
+              :children => {:count => 2},
+              :child => {
+                :tag => 'issue',
+                :attributes => {:id => @c1.id.to_s},
+                :child => {
+                  :tag => 'subject',
+                  :content => 'child c1',
+                  :sibling => {
+                    :tag => 'children',
+                    :children => {:count => 1},
+                    :child => {
+                      :tag => 'issue',
+                      :attributes => {:id => @c3.id.to_s}
+                    }
+                  }
+                }
+              }
+            }
+        end
+
+        context ".json" do
+          should "display children" do
+            get '/issues/1.json?include=children'
+
+            json = ActiveSupport::JSON.decode(response.body)
+            assert_equal([
+              {
+                'id' => @c1.id, 'subject' => 'child c1', 'tracker' => {'id' => 1, 'name' => 'Bug'},
+                'children' => [{'id' => @c3.id, 'subject' => 'child c3',
+                                'tracker' => {'id' => 1, 'name' => 'Bug'} }]
+              },
+              { 'id' => @c2.id, 'subject' => 'child c2', 'tracker' => {'id' => 1, 'name' => 'Bug'} }
+              ],
+              json['issue']['children'])
+          end
+        end
+      end
+    end
+  end
+
+  test "GET /issues/:id.xml?include=watchers should include watchers" do
+    Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
+
+    get '/issues/1.xml?include=watchers', {}, credentials('jsmith')
+
+    assert_response :ok
+    assert_equal 'application/xml', response.content_type
+    assert_select 'issue' do
+      assert_select 'watchers', Issue.find(1).watchers.count
+      assert_select 'watchers' do
+        assert_select 'user[id=3]'
+      end
+    end
+  end
+
+  context "POST /issues.xml" do
+    should_allow_api_authentication(
+      :post,
+      '/issues.xml',
+      {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}},
+      {:success_code => :created}
+    )
+    should "create an issue with the attributes" do
+      assert_difference('Issue.count') do
+        post '/issues.xml',
+             {:issue => {:project_id => 1, :subject => 'API test',
+              :tracker_id => 2, :status_id => 3}}, credentials('jsmith')
+      end
+      issue = Issue.first(:order => 'id DESC')
+      assert_equal 1, issue.project_id
+      assert_equal 2, issue.tracker_id
+      assert_equal 3, issue.status_id
+      assert_equal 'API test', issue.subject
+
+      assert_response :created
+      assert_equal 'application/xml', @response.content_type
+      assert_tag 'issue', :child => {:tag => 'id', :content => issue.id.to_s}
+    end
+  end
+
+  test "POST /issues.xml with watcher_user_ids should create issue with watchers" do
+    assert_difference('Issue.count') do
+      post '/issues.xml',
+           {:issue => {:project_id => 1, :subject => 'Watchers',
+            :tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]}}, credentials('jsmith')
+      assert_response :created
+    end
+    issue = Issue.order('id desc').first
+    assert_equal 2, issue.watchers.size
+    assert_equal [1, 3], issue.watcher_user_ids.sort
+  end
+
+  context "POST /issues.xml with failure" do
+    should "have an errors tag" do
+      assert_no_difference('Issue.count') do
+        post '/issues.xml', {:issue => {:project_id => 1}}, credentials('jsmith')
+      end
+
+      assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
+    end
+  end
+
+  context "POST /issues.json" do
+    should_allow_api_authentication(:post,
+                                    '/issues.json',
+                                    {:issue => {:project_id => 1, :subject => 'API test',
+                                     :tracker_id => 2, :status_id => 3}},
+                                    {:success_code => :created})
+
+    should "create an issue with the attributes" do
+      assert_difference('Issue.count') do
+        post '/issues.json',
+             {:issue => {:project_id => 1, :subject => 'API test',
+                         :tracker_id => 2, :status_id => 3}},
+             credentials('jsmith')
+      end
+
+      issue = Issue.first(:order => 'id DESC')
+      assert_equal 1, issue.project_id
+      assert_equal 2, issue.tracker_id
+      assert_equal 3, issue.status_id
+      assert_equal 'API test', issue.subject
+    end
+
+  end
+
+  context "POST /issues.json with failure" do
+    should "have an errors element" do
+      assert_no_difference('Issue.count') do
+        post '/issues.json', {:issue => {:project_id => 1}}, credentials('jsmith')
+      end
+
+      json = ActiveSupport::JSON.decode(response.body)
+      assert json['errors'].include?("Subject can't be blank")
+    end
+  end
+
+  # Issue 6 is on a private project
+  context "PUT /issues/6.xml" do
+    setup do
+      @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
+    end
+
+    should_allow_api_authentication(:put,
+                                    '/issues/6.xml',
+                                    {:issue => {:subject => 'API update', :notes => 'A new note'}},
+                                    {:success_code => :ok})
+
+    should "not create a new issue" do
+      assert_no_difference('Issue.count') do
+        put '/issues/6.xml', @parameters, credentials('jsmith')
+      end
+    end
+
+    should "create a new journal" do
+      assert_difference('Journal.count') do
+        put '/issues/6.xml', @parameters, credentials('jsmith')
+      end
+    end
+
+    should "add the note to the journal" do
+      put '/issues/6.xml', @parameters, credentials('jsmith')
+
+      journal = Journal.last
+      assert_equal "A new note", journal.notes
+    end
+
+    should "update the issue" do
+      put '/issues/6.xml', @parameters, credentials('jsmith')
+
+      issue = Issue.find(6)
+      assert_equal "API update", issue.subject
+    end
+
+  end
+
+  context "PUT /issues/3.xml with custom fields" do
+    setup do
+      @parameters = {
+        :issue => {:custom_fields => [{'id' => '1', 'value' => 'PostgreSQL' },
+        {'id' => '2', 'value' => '150'}]}
+      }
+    end
+
+    should "update custom fields" do
+      assert_no_difference('Issue.count') do
+        put '/issues/3.xml', @parameters, credentials('jsmith')
+      end
+
+      issue = Issue.find(3)
+      assert_equal '150', issue.custom_value_for(2).value
+      assert_equal 'PostgreSQL', issue.custom_value_for(1).value
+    end
+  end
+
+  context "PUT /issues/3.xml with multi custom fields" do
+    setup do
+      field = CustomField.find(1)
+      field.update_attribute :multiple, true
+      @parameters = {
+        :issue => {:custom_fields => [{'id' => '1', 'value' => ['MySQL', 'PostgreSQL'] },
+        {'id' => '2', 'value' => '150'}]}
+      }
+    end
+
+    should "update custom fields" do
+      assert_no_difference('Issue.count') do
+        put '/issues/3.xml', @parameters, credentials('jsmith')
+      end
+
+      issue = Issue.find(3)
+      assert_equal '150', issue.custom_value_for(2).value
+      assert_equal ['MySQL', 'PostgreSQL'], issue.custom_field_value(1).sort
+    end
+  end
+
+  context "PUT /issues/3.xml with project change" do
+    setup do
+      @parameters = {:issue => {:project_id => 2, :subject => 'Project changed'}}
+    end
+
+    should "update project" do
+      assert_no_difference('Issue.count') do
+        put '/issues/3.xml', @parameters, credentials('jsmith')
+      end
+
+      issue = Issue.find(3)
+      assert_equal 2, issue.project_id
+      assert_equal 'Project changed', issue.subject
+    end
+  end
+
+  context "PUT /issues/6.xml with failed update" do
+    setup do
+      @parameters = {:issue => {:subject => ''}}
+    end
+
+    should "not create a new issue" do
+      assert_no_difference('Issue.count') do
+        put '/issues/6.xml', @parameters, credentials('jsmith')
+      end
+    end
+
+    should "not create a new journal" do
+      assert_no_difference('Journal.count') do
+        put '/issues/6.xml', @parameters, credentials('jsmith')
+      end
+    end
+
+    should "have an errors tag" do
+      put '/issues/6.xml', @parameters, credentials('jsmith')
+
+      assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
+    end
+  end
+
+  context "PUT /issues/6.json" do
+    setup do
+      @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
+    end
+
+    should_allow_api_authentication(:put,
+                                    '/issues/6.json',
+                                    {:issue => {:subject => 'API update', :notes => 'A new note'}},
+                                    {:success_code => :ok})
+
+    should "update the issue" do
+      assert_no_difference('Issue.count') do
+        assert_difference('Journal.count') do
+          put '/issues/6.json', @parameters, credentials('jsmith')
+
+          assert_response :ok
+          assert_equal '', response.body
+        end
+      end
+
+      issue = Issue.find(6)
+      assert_equal "API update", issue.subject
+      journal = Journal.last
+      assert_equal "A new note", journal.notes
+    end
+  end
+
+  context "PUT /issues/6.json with failed update" do
+    should "return errors" do
+      assert_no_difference('Issue.count') do
+        assert_no_difference('Journal.count') do
+          put '/issues/6.json', {:issue => {:subject => ''}}, credentials('jsmith')
+
+          assert_response :unprocessable_entity
+        end
+      end
+
+      json = ActiveSupport::JSON.decode(response.body)
+      assert json['errors'].include?("Subject can't be blank")
+    end
+  end
+
+  context "DELETE /issues/1.xml" do
+    should_allow_api_authentication(:delete,
+                                    '/issues/6.xml',
+                                    {},
+                                    {:success_code => :ok})
+
+    should "delete the issue" do
+      assert_difference('Issue.count', -1) do
+        delete '/issues/6.xml', {}, credentials('jsmith')
+
+        assert_response :ok
+        assert_equal '', response.body
+      end
+
+      assert_nil Issue.find_by_id(6)
+    end
+  end
+
+  context "DELETE /issues/1.json" do
+    should_allow_api_authentication(:delete,
+                                    '/issues/6.json',
+                                    {},
+                                    {:success_code => :ok})
+
+    should "delete the issue" do
+      assert_difference('Issue.count', -1) do
+        delete '/issues/6.json', {}, credentials('jsmith')
+
+        assert_response :ok
+        assert_equal '', response.body
+      end
+
+      assert_nil Issue.find_by_id(6)
+    end
+  end
+
+  test "POST /issues/:id/watchers.xml should add watcher" do
+    assert_difference 'Watcher.count' do
+      post '/issues/1/watchers.xml', {:user_id => 3}, credentials('jsmith')
+
+      assert_response :ok
+      assert_equal '', response.body
+    end
+    watcher = Watcher.order('id desc').first
+    assert_equal Issue.find(1), watcher.watchable
+    assert_equal User.find(3), watcher.user
+  end
+
+  test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do
+    Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
+
+    assert_difference 'Watcher.count', -1 do
+      delete '/issues/1/watchers/3.xml', {}, credentials('jsmith')
+
+      assert_response :ok
+      assert_equal '', response.body
+    end
+    assert_equal false, Issue.find(1).watched_by?(User.find(3))
+  end
+
+  def test_create_issue_with_uploaded_file
+    set_tmp_attachments_directory
+    # upload the file
+    assert_difference 'Attachment.count' do
+      post '/uploads.xml', 'test_create_with_upload',
+           {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
+      assert_response :created
+    end
+    xml = Hash.from_xml(response.body)
+    token = xml['upload']['token']
+    attachment = Attachment.first(:order => 'id DESC')
+
+    # create the issue with the upload's token
+    assert_difference 'Issue.count' do
+      post '/issues.xml',
+           {:issue => {:project_id => 1, :subject => 'Uploaded file',
+                       :uploads => [{:token => token, :filename => 'test.txt',
+                                     :content_type => 'text/plain'}]}},
+           credentials('jsmith')
+      assert_response :created
+    end
+    issue = Issue.first(:order => 'id DESC')
+    assert_equal 1, issue.attachments.count
+    assert_equal attachment, issue.attachments.first
+
+    attachment.reload
+    assert_equal 'test.txt', attachment.filename
+    assert_equal 'text/plain', attachment.content_type
+    assert_equal 'test_create_with_upload'.size, attachment.filesize
+    assert_equal 2, attachment.author_id
+
+    # get the issue with its attachments
+    get "/issues/#{issue.id}.xml", :include => 'attachments'
+    assert_response :success
+    xml = Hash.from_xml(response.body)
+    attachments = xml['issue']['attachments']
+    assert_kind_of Array, attachments
+    assert_equal 1, attachments.size
+    url = attachments.first['content_url']
+    assert_not_nil url
+
+    # download the attachment
+    get url
+    assert_response :success
+  end
+
+  def test_update_issue_with_uploaded_file
+    set_tmp_attachments_directory
+    # upload the file
+    assert_difference 'Attachment.count' do
+      post '/uploads.xml', 'test_upload_with_upload',
+           {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
+      assert_response :created
+    end
+    xml = Hash.from_xml(response.body)
+    token = xml['upload']['token']
+    attachment = Attachment.first(:order => 'id DESC')
+
+    # update the issue with the upload's token
+    assert_difference 'Journal.count' do
+      put '/issues/1.xml',
+          {:issue => {:notes => 'Attachment added',
+                      :uploads => [{:token => token, :filename => 'test.txt',
+                                    :content_type => 'text/plain'}]}},
+          credentials('jsmith')
+      assert_response :ok
+      assert_equal '', @response.body
+    end
+
+    issue = Issue.find(1)
+    assert_include attachment, issue.attachments
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/63/634fa24a02c5bb6db30eef5565a1a7bdf8877051.svn-base
--- a/.svn/pristine/63/634fa24a02c5bb6db30eef5565a1a7bdf8877051.svn-base
+++ /dev/null
@@ -1,202 +0,0 @@
-# redMine - project management software
-# Copyright (C) 2006-2007  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-
-# DO NOT MODIFY THIS FILE !!!
-# Settings can be defined through the application in Admin -> Settings
-
-app_title:
-  default: Redmine
-app_subtitle:
-  default: Project management
-welcome_text:
-  default:
-login_required:
-  default: 0
-self_registration:
-  default: '2'
-lost_password:
-  default: 1
-password_min_length:
-  format: int
-  default: 4
-attachment_max_size:
-  format: int
-  default: 5120
-issues_export_limit:
-  format: int
-  default: 500
-activity_days_default:
-  format: int
-  default: 30
-per_page_options:
-  default: '25,50,100'
-mail_from:
-  default: redmine@example.net
-bcc_recipients:
-  default: 1
-plain_text_mail:
-  default: 0
-text_formatting:
-  default: textile
-cache_formatted_text:
-  default: 0
-wiki_compression:
-  default: ""
-default_language:
-  default: en
-host_name:
-  default: localhost:3000
-protocol:
-  default: http
-feeds_limit:
-  format: int
-  default: 15
-gantt_items_limit:
-  format: int
-  default: 500
-# Maximum size of files that can be displayed
-# inline through the file viewer (in KB)
-file_max_size_displayed:
-  format: int
-  default: 512
-diff_max_lines_displayed:
-  format: int
-  default: 1500
-enabled_scm:
-  serialized: true
-  default: 
-  - Subversion
-  - Darcs
-  - Mercurial
-  - Cvs
-  - Bazaar
-  - Git
-autofetch_changesets:
-  default: 1
-sys_api_enabled:
-  default: 0
-sys_api_key:
-  default: ''
-commit_ref_keywords:
-  default: 'refs,references,IssueID'
-commit_fix_keywords:
-  default: 'fixes,closes'
-commit_fix_status_id:
-  format: int
-  default: 0
-commit_fix_done_ratio:
-  default: 100
-commit_logtime_enabled:
-  default: 0
-commit_logtime_activity_id:
-  format: int
-  default: 0
-# autologin duration in days
-# 0 means autologin is disabled 
-autologin:
-  format: int
-  default: 0
-# date format
-date_format:
-  default: ''
-time_format:
-  default: ''
-user_format:
-  default: :firstname_lastname
-  format: symbol
-cross_project_issue_relations:
-  default: 0
-issue_group_assignment:
-  default: 0
-default_issue_start_date_to_creation_date:
-  default: 1
-notified_events:
-  serialized: true
-  default: 
-  - issue_added
-  - issue_updated
-mail_handler_body_delimiters:
-  default: ''
-mail_handler_api_enabled:
-  default: 0
-mail_handler_api_key:
-  default: 
-issue_list_default_columns:
-  serialized: true
-  default: 
-  - tracker
-  - status
-  - priority
-  - subject
-  - assigned_to
-  - updated_on
-display_subprojects_issues:
-  default: 1
-issue_done_ratio:
-  default: 'issue_field'
-default_projects_public:
-  default: 1
-default_projects_modules:
-  serialized: true
-  default: 
-  - issue_tracking
-  - time_tracking
-  - news
-  - documents
-  - files
-  - wiki
-  - repository
-  - boards
-  - calendar
-  - gantt
-# Role given to a non-admin user who creates a project
-new_project_user_role_id:
-  format: int
-  default: ''
-sequential_project_identifiers:
-  default: 0
-# encodings used to convert repository files content to UTF-8
-# multiple values accepted, comma separated
-repositories_encodings:
-  default: ''
-# encoding used to convert commit logs to UTF-8
-commit_logs_encoding:
-  default: 'UTF-8'
-repository_log_display_limit:
-  format: int
-  default: 100
-ui_theme:
-  default: ''
-emails_footer:
-  default: |-
-    You have received this notification because you have either subscribed to it, or are involved in it.
-    To change your notification preferences, please click here: http://hostname/my/account
-gravatar_enabled:  
-  default: 0
-openid:
-  default: 0
-gravatar_default:
-  default: ''
-start_of_week:
-  default: ''
-rest_api_enabled:
-  default: 0
-default_notification_option:
-  default: 'only_my_events'
-emails_header:
-  default: ''
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/63/6363e04d893f5e743cf860de53b9bf91e0dfa927.svn-base
--- a/.svn/pristine/63/6363e04d893f5e743cf860de53b9bf91e0dfa927.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-<%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %>
-
-<div class="contextual">
-  <%= render :partial => 'navigation' %>
-</div>
-
-<h2><%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2>
-
-<p><%= render :partial => 'link_to_functions' %></p>
-
-<%= render :partial => 'common/file', :locals => {:filename => @path, :content => @content} %>
-
-<% content_for :header_tags do %>
-<%= stylesheet_link_tag "scm" %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/63/636943525457e5c4d4d0c3e654c86a8a51ed59f5.svn-base
--- a/.svn/pristine/63/636943525457e5c4d4d0c3e654c86a8a51ed59f5.svn-base
+++ /dev/null
@@ -1,159 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::I18nTest < ActiveSupport::TestCase
-  include Redmine::I18n
-  include ActionView::Helpers::NumberHelper
-
-  def setup
-    @hook_module = Redmine::Hook
-  end
-
-  def test_date_format_default
-    set_language_if_valid 'en'
-    today = Date.today
-    Setting.date_format = ''
-    assert_equal I18n.l(today), format_date(today)
-  end
-
-  def test_date_format
-    set_language_if_valid 'en'
-    today = Date.today
-    Setting.date_format = '%d %m %Y'
-    assert_equal today.strftime('%d %m %Y'), format_date(today)
-  end
-
-  def test_date_and_time_for_each_language
-    Setting.date_format = ''
-    valid_languages.each do |lang|
-      set_language_if_valid lang
-      assert_nothing_raised "#{lang} failure" do
-        format_date(Date.today)
-        format_time(Time.now)
-        format_time(Time.now, false)
-        assert_not_equal 'default', ::I18n.l(Date.today, :format => :default),
-                         "date.formats.default missing in #{lang}"
-        assert_not_equal 'time',    ::I18n.l(Time.now, :format => :time),
-                         "time.formats.time missing in #{lang}"
-      end
-      assert l('date.day_names').is_a?(Array)
-      assert_equal 7, l('date.day_names').size
-
-      assert l('date.month_names').is_a?(Array)
-      assert_equal 13, l('date.month_names').size
-    end
-  end
-
-  def test_time_format
-    set_language_if_valid 'en'
-    now = Time.parse('2011-02-20 15:45:22')
-    with_settings :time_format => '%H:%M' do
-      with_settings :date_format => '' do
-        assert_equal '02/20/2011 15:45', format_time(now)
-        assert_equal '15:45', format_time(now, false)
-      end
-      with_settings :date_format => '%Y-%m-%d' do
-        assert_equal '2011-02-20 15:45', format_time(now)
-        assert_equal '15:45', format_time(now, false)
-      end
-    end
-  end
-
-  def test_time_format_default
-    set_language_if_valid 'en'
-    now = Time.parse('2011-02-20 15:45:22')
-    with_settings :time_format => '' do
-      with_settings :date_format => '' do
-        assert_equal '02/20/2011 03:45 pm', format_time(now)
-        assert_equal '03:45 pm', format_time(now, false)
-      end
-      with_settings :date_format => '%Y-%m-%d' do
-        assert_equal '2011-02-20 03:45 pm', format_time(now)
-        assert_equal '03:45 pm', format_time(now, false)
-      end
-    end
-  end
-
-  def test_time_format
-    set_language_if_valid 'en'
-    now = Time.now
-    Setting.date_format = '%d %m %Y'
-    Setting.time_format = '%H %M'
-    assert_equal now.strftime('%d %m %Y %H %M'), format_time(now)
-    assert_equal now.strftime('%H %M'), format_time(now, false)
-  end
-
-  def test_utc_time_format
-    set_language_if_valid 'en'
-    now = Time.now
-    Setting.date_format = '%d %m %Y'
-    Setting.time_format = '%H %M'
-    assert_equal now.strftime('%d %m %Y %H %M'), format_time(now.utc)
-    assert_equal now.strftime('%H %M'), format_time(now.utc, false)
-  end
-
-  def test_number_to_human_size_for_each_language
-    valid_languages.each do |lang|
-      set_language_if_valid lang
-      assert_nothing_raised "#{lang} failure" do
-        number_to_human_size(1024*1024*4)
-      end
-    end
-  end
-
-  def test_valid_languages
-    assert valid_languages.is_a?(Array)
-    assert valid_languages.first.is_a?(Symbol)
-  end
-
-  def test_valid_language
-    to_test = {'fr' => :fr,
-               'Fr' => :fr,
-               'zh' => :zh,
-               'zh-tw' => :"zh-TW",
-               'zh-TW' => :"zh-TW",
-               'zh-ZZ' => nil }
-    to_test.each {|lang, expected| assert_equal expected, find_language(lang)}
-  end
-
-  def test_fallback
-    ::I18n.backend.store_translations(:en, {:untranslated => "Untranslated string"})
-    ::I18n.locale = 'en'
-    assert_equal "Untranslated string", l(:untranslated)
-    ::I18n.locale = 'fr'
-    assert_equal "Untranslated string", l(:untranslated)
-
-    ::I18n.backend.store_translations(:fr, {:untranslated => "Pas de traduction"})
-    ::I18n.locale = 'en'
-    assert_equal "Untranslated string", l(:untranslated)
-    ::I18n.locale = 'fr'
-    assert_equal "Pas de traduction", l(:untranslated)
-  end
-
-  def test_utf8
-    set_language_if_valid 'ja'
-    str_ja_yes  = "\xe3\x81\xaf\xe3\x81\x84"
-    i18n_ja_yes = l(:general_text_Yes)
-    if str_ja_yes.respond_to?(:force_encoding)
-      str_ja_yes.force_encoding('UTF-8')
-      assert_equal "UTF-8", i18n_ja_yes.encoding.to_s
-    end
-    assert_equal str_ja_yes, i18n_ja_yes
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/63/638ef428af64a93a5a54376e8e444c15761d3973.svn-base
--- /dev/null
+++ b/.svn/pristine/63/638ef428af64a93a5a54376e8e444c15761d3973.svn-base
@@ -0,0 +1,57 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class CommentTest < ActiveSupport::TestCase
+  fixtures :users, :news, :comments, :projects, :enabled_modules
+
+  def setup
+    @jsmith = User.find(2)
+    @news = News.find(1)
+  end
+
+  def test_create
+    comment = Comment.new(:commented => @news, :author => @jsmith, :comments => "my comment")
+    assert comment.save
+    @news.reload
+    assert_equal 2, @news.comments_count
+  end
+
+  def test_create_should_send_notification
+    Watcher.create!(:watchable => @news, :user => @jsmith)
+
+    with_settings :notified_events => %w(news_comment_added) do
+      assert_difference 'ActionMailer::Base.deliveries.size' do
+        Comment.create!(:commented => @news, :author => @jsmith, :comments => "my comment")
+      end
+    end
+  end
+
+  def test_validate
+    comment = Comment.new(:commented => @news)
+    assert !comment.save
+    assert_equal 2, comment.errors.count
+  end
+
+  def test_destroy
+    comment = Comment.find(1)
+    assert comment.destroy
+    @news.reload
+    assert_equal 0, @news.comments_count
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/63/63ab165c5d9aefdb49df1a8bc5d36c75c1c75e7e.svn-base
--- a/.svn/pristine/63/63ab165c5d9aefdb49df1a8bc5d36c75c1c75e7e.svn-base
+++ /dev/null
@@ -1,151 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class ContextMenusControllerTest < ActionController::TestCase
-  fixtures :projects,
-           :trackers,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :auth_sources,
-           :enabled_modules,
-           :workflows,
-           :journals, :journal_details,
-           :versions,
-           :issues, :issue_statuses, :issue_categories,
-           :users,
-           :enumerations
-
-  def test_context_menu_one_issue
-    @request.session[:user_id] = 2
-    get :issues, :ids => [1]
-    assert_response :success
-    assert_template 'context_menu'
-    assert_tag :tag => 'a', :content => 'Edit',
-                            :attributes => { :href => '/issues/1/edit',
-                                             :class => 'icon-edit' }
-    assert_tag :tag => 'a', :content => 'Closed',
-                            :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bstatus_id%5D=5',
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Immediate',
-                            :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
-                                             :class => '' }
-    assert_no_tag :tag => 'a', :content => 'Inactive Priority'
-    # Versions
-    assert_tag :tag => 'a', :content => '2.0',
-                            :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
-                            :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
-                                             :class => '' }
-
-    assert_tag :tag => 'a', :content => 'Dave Lopper',
-                            :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Duplicate',
-                            :attributes => { :href => '/projects/ecookbook/issues/1/copy',
-                                             :class => 'icon-duplicate' }
-    assert_tag :tag => 'a', :content => 'Copy',
-                            :attributes => { :href => '/issues/move/new?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1',
-                                             :class => 'icon-copy' }
-    assert_tag :tag => 'a', :content => 'Move',
-                            :attributes => { :href => '/issues/move/new?ids%5B%5D=1',
-                                             :class => 'icon-move' }
-    assert_tag :tag => 'a', :content => 'Delete',
-                            :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
-                                             :class => 'icon-del' }
-  end
-
-  def test_context_menu_one_issue_by_anonymous
-    get :issues, :ids => [1]
-    assert_response :success
-    assert_template 'context_menu'
-    assert_tag :tag => 'a', :content => 'Delete',
-                            :attributes => { :href => '#',
-                                             :class => 'icon-del disabled' }
-  end
-
-  def test_context_menu_multiple_issues_of_same_project
-    @request.session[:user_id] = 2
-    get :issues, :ids => [1, 2]
-    assert_response :success
-    assert_template 'context_menu'
-    assert_not_nil assigns(:issues)
-    assert_equal [1, 2], assigns(:issues).map(&:id).sort
-
-    ids = assigns(:issues).map(&:id).map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
-    assert_tag :tag => 'a', :content => 'Edit',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}",
-                                             :class => 'icon-edit' }
-    assert_tag :tag => 'a', :content => 'Closed',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}&amp;issue%5Bstatus_id%5D=5",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Immediate',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}&amp;issue%5Bpriority_id%5D=8",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Dave Lopper',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}&amp;issue%5Bassigned_to_id%5D=3",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Copy',
-                            :attributes => { :href => "/issues/move/new?copy_options%5Bcopy%5D=t&amp;#{ids}",
-                                             :class => 'icon-copy' }
-    assert_tag :tag => 'a', :content => 'Move',
-                            :attributes => { :href => "/issues/move/new?#{ids}",
-                                             :class => 'icon-move' }
-    assert_tag :tag => 'a', :content => 'Delete',
-                            :attributes => { :href => "/issues/destroy?#{ids}",
-                                             :class => 'icon-del' }
-  end
-
-  def test_context_menu_multiple_issues_of_different_projects
-    @request.session[:user_id] = 2
-    get :issues, :ids => [1, 2, 6]
-    assert_response :success
-    assert_template 'context_menu'
-    assert_not_nil assigns(:issues)
-    assert_equal [1, 2, 6], assigns(:issues).map(&:id).sort
-
-    ids = assigns(:issues).map(&:id).map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
-    assert_tag :tag => 'a', :content => 'Edit',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}",
-                                             :class => 'icon-edit' }
-    assert_tag :tag => 'a', :content => 'Closed',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}&amp;issue%5Bstatus_id%5D=5",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Immediate',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}&amp;issue%5Bpriority_id%5D=8",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'John Smith',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}&amp;issue%5Bassigned_to_id%5D=2",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Delete',
-                            :attributes => { :href => "/issues/destroy?#{ids}",
-                                             :class => 'icon-del' }
-  end
-
-  def test_context_menu_issue_visibility
-    get :issues, :ids => [1, 4]
-    assert_response :success
-    assert_template 'context_menu'
-    assert_equal [1], assigns(:issues).collect(&:id)
-  end
-  
-  def test_time_entries_context_menu
-    @request.session[:user_id] = 2
-    get :time_entries, :ids => [1, 2]
-    assert_response :success
-    assert_template 'time_entries'
-    assert_tag 'a', :content => 'Edit'
-    assert_no_tag 'a', :content => 'Edit', :attributes => {:class => /disabled/}
-  end
-  
-  def test_time_entries_context_menu_without_edit_permission
-    @request.session[:user_id] = 2
-    Role.find_by_name('Manager').remove_permission! :edit_time_entries
-    
-    get :time_entries, :ids => [1, 2]
-    assert_response :success
-    assert_template 'time_entries'
-    assert_tag 'a', :content => 'Edit', :attributes => {:class => /disabled/}
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/63/63f5d9f908a9cb71c1fdf7287c1a8cd3db047d81.svn-base
--- /dev/null
+++ b/.svn/pristine/63/63f5d9f908a9cb71c1fdf7287c1a8cd3db047d81.svn-base
@@ -0,0 +1,211 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class TrackersControllerTest < ActionController::TestCase
+  fixtures :trackers, :projects, :projects_trackers, :users, :issues, :custom_fields
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 1 # admin
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+  end
+  
+  def test_index_by_anonymous_should_redirect_to_login_form
+    @request.session[:user_id] = nil
+    get :index
+    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Ftrackers'
+  end
+  
+  def test_index_by_user_should_respond_with_406
+    @request.session[:user_id] = 2
+    get :index
+    assert_response 406
+  end
+
+  def test_new
+    get :new
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_create
+    assert_difference 'Tracker.count' do
+      post :create, :tracker => { :name => 'New tracker', :project_ids => ['1', '', ''], :custom_field_ids => ['1', '6', ''] }
+    end
+    assert_redirected_to :action => 'index'
+    tracker = Tracker.first(:order => 'id DESC')
+    assert_equal 'New tracker', tracker.name
+    assert_equal [1], tracker.project_ids.sort
+    assert_equal Tracker::CORE_FIELDS, tracker.core_fields
+    assert_equal [1, 6], tracker.custom_field_ids.sort
+    assert_equal 0, tracker.workflow_rules.count
+  end
+
+  def create_with_disabled_core_fields
+    assert_difference 'Tracker.count' do
+      post :create, :tracker => { :name => 'New tracker', :core_fields => ['assigned_to_id', 'fixed_version_id', ''] }
+    end
+    assert_redirected_to :action => 'index'
+    tracker = Tracker.first(:order => 'id DESC')
+    assert_equal 'New tracker', tracker.name
+    assert_equal %w(assigned_to_id fixed_version_id), tracker.core_fields
+  end
+
+  def test_create_new_with_workflow_copy
+    assert_difference 'Tracker.count' do
+      post :create, :tracker => { :name => 'New tracker' }, :copy_workflow_from => 1
+    end
+    assert_redirected_to :action => 'index'
+    tracker = Tracker.find_by_name('New tracker')
+    assert_equal 0, tracker.projects.count
+    assert_equal Tracker.find(1).workflow_rules.count, tracker.workflow_rules.count
+  end
+
+  def test_create_with_failure
+    assert_no_difference 'Tracker.count' do
+      post :create, :tracker => { :name => '', :project_ids => ['1', '', ''], :custom_field_ids => ['1', '6', ''] }
+    end
+    assert_response :success
+    assert_template 'new'
+    assert_error_tag :content => /name can&#x27;t be blank/i
+  end
+
+  def test_edit
+    Tracker.find(1).project_ids = [1, 3]
+
+    get :edit, :id => 1
+    assert_response :success
+    assert_template 'edit'
+
+    assert_tag :input, :attributes => { :name => 'tracker[project_ids][]',
+                                        :value => '1',
+                                        :checked => 'checked' }
+
+    assert_tag :input, :attributes => { :name => 'tracker[project_ids][]',
+                                        :value => '2',
+                                        :checked => nil }
+
+    assert_tag :input, :attributes => { :name => 'tracker[project_ids][]',
+                                        :value => '',
+                                        :type => 'hidden'}
+  end
+
+  def test_edit_should_check_core_fields
+    tracker = Tracker.find(1)
+    tracker.core_fields = %w(assigned_to_id fixed_version_id)
+    tracker.save!
+
+    get :edit, :id => 1
+    assert_response :success
+    assert_template 'edit'
+
+    assert_select 'input[name=?][value=assigned_to_id][checked=checked]', 'tracker[core_fields][]'
+    assert_select 'input[name=?][value=fixed_version_id][checked=checked]', 'tracker[core_fields][]'
+
+    assert_select 'input[name=?][value=category_id]', 'tracker[core_fields][]'
+    assert_select 'input[name=?][value=category_id][checked=checked]', 'tracker[core_fields][]', 0
+
+    assert_select 'input[name=?][value=][type=hidden]', 'tracker[core_fields][]'
+  end
+
+  def test_update
+    put :update, :id => 1, :tracker => { :name => 'Renamed',
+                                        :project_ids => ['1', '2', ''] }
+    assert_redirected_to :action => 'index'
+    assert_equal [1, 2], Tracker.find(1).project_ids.sort
+  end
+
+  def test_update_without_projects
+    put :update, :id => 1, :tracker => { :name => 'Renamed',
+                                        :project_ids => [''] }
+    assert_redirected_to :action => 'index'
+    assert Tracker.find(1).project_ids.empty?
+  end
+
+  def test_update_without_core_fields
+    put :update, :id => 1, :tracker => { :name => 'Renamed', :core_fields => [''] }
+    assert_redirected_to :action => 'index'
+    assert Tracker.find(1).core_fields.empty?
+  end
+
+  def test_update_with_failure
+    put :update, :id => 1, :tracker => { :name => '' }
+    assert_response :success
+    assert_template 'edit'
+    assert_error_tag :content => /name can&#x27;t be blank/i
+  end
+
+  def test_move_lower
+   tracker = Tracker.find_by_position(1)
+   put :update, :id => 1, :tracker => { :move_to => 'lower' }
+   assert_equal 2, tracker.reload.position
+  end
+
+  def test_destroy
+    tracker = Tracker.create!(:name => 'Destroyable')
+    assert_difference 'Tracker.count', -1 do
+      delete :destroy, :id => tracker.id
+    end
+    assert_redirected_to :action => 'index'
+    assert_nil flash[:error]
+  end
+
+  def test_destroy_tracker_in_use
+    assert_no_difference 'Tracker.count' do
+      delete :destroy, :id => 1
+    end
+    assert_redirected_to :action => 'index'
+    assert_not_nil flash[:error]
+  end
+
+  def test_get_fields
+    get :fields
+    assert_response :success
+    assert_template 'fields'
+
+    assert_select 'form' do
+      assert_select 'input[type=checkbox][name=?][value=assigned_to_id]', 'trackers[1][core_fields][]'
+      assert_select 'input[type=checkbox][name=?][value=2]', 'trackers[1][custom_field_ids][]'
+
+      assert_select 'input[type=hidden][name=?][value=]', 'trackers[1][core_fields][]'
+      assert_select 'input[type=hidden][name=?][value=]', 'trackers[1][custom_field_ids][]'
+    end
+  end
+
+  def test_post_fields
+    post :fields, :trackers => {
+      '1' => {'core_fields' => ['assigned_to_id', 'due_date', ''], 'custom_field_ids' => ['1', '2']},
+      '2' => {'core_fields' => [''], 'custom_field_ids' => ['']}
+    }
+    assert_redirected_to '/trackers/fields'
+
+    tracker = Tracker.find(1)
+    assert_equal %w(assigned_to_id due_date), tracker.core_fields
+    assert_equal [1, 2], tracker.custom_field_ids.sort
+
+    tracker = Tracker.find(2)
+    assert_equal [], tracker.core_fields
+    assert_equal [], tracker.custom_field_ids.sort
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/64/6402c0873c916f8ca24a20adde0b93d3110a6089.svn-base
--- /dev/null
+++ b/.svn/pristine/64/6402c0873c916f8ca24a20adde0b93d3110a6089.svn-base
@@ -0,0 +1,118 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# FileSystem adapter
+# File written by Paul Rivier, at Demotera.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/abstract_adapter'
+require 'find'
+
+module Redmine
+  module Scm
+    module Adapters
+      class FilesystemAdapter < AbstractAdapter
+
+        class << self
+          def client_available
+            true
+          end
+        end
+
+        def initialize(url, root_url=nil, login=nil, password=nil,
+                       path_encoding=nil)
+          @url = with_trailling_slash(url)
+          @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
+        end
+
+        def path_encoding
+          @path_encoding
+        end
+
+        def format_path_ends(path, leading=true, trailling=true)
+          path = leading ? with_leading_slash(path) :
+            without_leading_slash(path)
+          trailling ? with_trailling_slash(path) :
+            without_trailling_slash(path)
+        end
+
+        def info
+          info = Info.new({:root_url => target(),
+                            :lastrev => nil
+                          })
+          info
+        rescue CommandFailed
+          return nil
+        end
+
+        def entries(path="", identifier=nil, options={})
+          entries = Entries.new
+          trgt_utf8 = target(path)
+          trgt = scm_iconv(@path_encoding, 'UTF-8', trgt_utf8)
+          Dir.new(trgt).each do |e1|
+            e_utf8 = scm_iconv('UTF-8', @path_encoding, e1)
+            next if e_utf8.blank?
+            relative_path_utf8 = format_path_ends(
+                (format_path_ends(path,false,true) + e_utf8),false,false)
+            t1_utf8 = target(relative_path_utf8)
+            t1 = scm_iconv(@path_encoding, 'UTF-8', t1_utf8)
+            relative_path = scm_iconv(@path_encoding, 'UTF-8', relative_path_utf8)
+            e1 = scm_iconv(@path_encoding, 'UTF-8', e_utf8)
+            if File.exist?(t1) and # paranoid test
+                  %w{file directory}.include?(File.ftype(t1)) and # avoid special types
+                  not File.basename(e1).match(/^\.+$/) # avoid . and ..
+              p1         = File.readable?(t1) ? relative_path : ""
+              utf_8_path = scm_iconv('UTF-8', @path_encoding, p1)
+              entries <<
+                Entry.new({ :name => scm_iconv('UTF-8', @path_encoding, File.basename(e1)),
+                          # below : list unreadable files, but dont link them.
+                          :path => utf_8_path,
+                          :kind => (File.directory?(t1) ? 'dir' : 'file'),
+                          :size => (File.directory?(t1) ? nil : [File.size(t1)].pack('l').unpack('L').first),
+                          :lastrev =>
+                              Revision.new({:time => (File.mtime(t1)) })
+                        })
+            end
+          end
+          entries.sort_by_name
+        rescue  => err
+          logger.error "scm: filesystem: error: #{err.message}"
+          raise CommandFailed.new(err.message)
+        end
+
+        def cat(path, identifier=nil)
+          p = scm_iconv(@path_encoding, 'UTF-8', target(path))
+          File.new(p, "rb").read
+        rescue  => err
+          logger.error "scm: filesystem: error: #{err.message}"
+          raise CommandFailed.new(err.message)
+        end
+
+        private
+
+        # AbstractAdapter::target is implicitly made to quote paths.
+        # Here we do not shell-out, so we do not want quotes.
+        def target(path=nil)
+          # Prevent the use of ..
+          if path and !path.match(/(^|\/)\.\.(\/|$)/)
+            return "#{self.url}#{without_leading_slash(path)}"
+          end
+          return self.url
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/64/64036c3be2c819ccb0429f69ed2813c1f8f00a12.svn-base
--- a/.svn/pristine/64/64036c3be2c819ccb0429f69ed2813c1f8f00a12.svn-base
+++ /dev/null
@@ -1,250 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'queries_controller'
-
-# Re-raise errors caught by the controller.
-class QueriesController; def rescue_action(e) raise e end; end
-
-class QueriesControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :members, :member_roles, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :queries
-
-  def setup
-    @controller = QueriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_get_new_project_query
-    @request.session[:user_id] = 2
-    get :new, :project_id => 1
-    assert_response :success
-    assert_template 'new'
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'query[is_public]',
-                                                 :checked => nil }
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'query_is_for_all',
-                                                 :checked => nil,
-                                                 :disabled => nil }
-  end
-
-  def test_get_new_global_query
-    @request.session[:user_id] = 2
-    get :new
-    assert_response :success
-    assert_template 'new'
-    assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                    :name => 'query[is_public]' }
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'query_is_for_all',
-                                                 :checked => 'checked',
-                                                 :disabled => nil }
-  end
-
-  def test_new_project_public_query
-    @request.session[:user_id] = 2
-    post :create,
-         :project_id => 'ecookbook',
-         :default_columns => '1',
-         :f => ["status_id", "assigned_to_id"],
-         :op => {"assigned_to_id" => "=", "status_id" => "o"},
-         :v => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
-         :query => {"name" => "test_new_project_public_query", "is_public" => "1"}
-
-    q = Query.find_by_name('test_new_project_public_query')
-    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
-    assert q.is_public?
-    assert q.has_default_columns?
-    assert q.valid?
-  end
-
-  def test_new_project_private_query
-    @request.session[:user_id] = 3
-    post :create,
-         :project_id => 'ecookbook',
-         :default_columns => '1',
-         :fields => ["status_id", "assigned_to_id"],
-         :operators => {"assigned_to_id" => "=", "status_id" => "o"},
-         :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
-         :query => {"name" => "test_new_project_private_query", "is_public" => "1"}
-
-    q = Query.find_by_name('test_new_project_private_query')
-    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
-    assert !q.is_public?
-    assert q.has_default_columns?
-    assert q.valid?
-  end
-
-  def test_new_global_private_query_with_custom_columns
-    @request.session[:user_id] = 3
-    post :create,
-         :fields => ["status_id", "assigned_to_id"],
-         :operators => {"assigned_to_id" => "=", "status_id" => "o"},
-         :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
-         :query => {"name" => "test_new_global_private_query", "is_public" => "1"},
-         :c => ["", "tracker", "subject", "priority", "category"]
-
-    q = Query.find_by_name('test_new_global_private_query')
-    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
-    assert !q.is_public?
-    assert !q.has_default_columns?
-    assert_equal [:tracker, :subject, :priority, :category], q.columns.collect {|c| c.name}
-    assert q.valid?
-  end
-
-  def test_new_global_query_with_custom_filters
-    @request.session[:user_id] = 3
-    post :create,
-         :fields => ["assigned_to_id"],
-         :operators => {"assigned_to_id" => "="},
-         :values => { "assigned_to_id" => ["me"]},
-         :query => {"name" => "test_new_global_query"}
-
-    q = Query.find_by_name('test_new_global_query')
-    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
-    assert !q.has_filter?(:status_id)
-    assert_equal ['assigned_to_id'], q.filters.keys
-    assert q.valid?
-  end
-
-  def test_new_with_sort
-    @request.session[:user_id] = 1
-    post :create,
-         :default_columns => '1',
-         :operators => {"status_id" => "o"},
-         :values => {"status_id" => ["1"]},
-         :query => {:name => "test_new_with_sort",
-                    :is_public => "1",
-                    :sort_criteria => {"0" => ["due_date", "desc"], "1" => ["tracker", ""]}}
-
-    query = Query.find_by_name("test_new_with_sort")
-    assert_not_nil query
-    assert_equal [['due_date', 'desc'], ['tracker', 'asc']], query.sort_criteria
-  end
-
-  def test_get_edit_global_public_query
-    @request.session[:user_id] = 1
-    get :edit, :id => 4
-    assert_response :success
-    assert_template 'edit'
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'query[is_public]',
-                                                 :checked => 'checked' }
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'query_is_for_all',
-                                                 :checked => 'checked',
-                                                 :disabled => 'disabled' }
-  end
-
-  def test_edit_global_public_query
-    @request.session[:user_id] = 1
-    put :update,
-         :id => 4,
-         :default_columns => '1',
-         :fields => ["status_id", "assigned_to_id"],
-         :operators => {"assigned_to_id" => "=", "status_id" => "o"},
-         :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
-         :query => {"name" => "test_edit_global_public_query", "is_public" => "1"}
-
-    assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 4
-    q = Query.find_by_name('test_edit_global_public_query')
-    assert q.is_public?
-    assert q.has_default_columns?
-    assert q.valid?
-  end
-
-  def test_get_edit_global_private_query
-    @request.session[:user_id] = 3
-    get :edit, :id => 3
-    assert_response :success
-    assert_template 'edit'
-    assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                    :name => 'query[is_public]' }
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'query_is_for_all',
-                                                 :checked => 'checked',
-                                                 :disabled => 'disabled' }
-  end
-
-  def test_edit_global_private_query
-    @request.session[:user_id] = 3
-    put :update,
-         :id => 3,
-         :default_columns => '1',
-         :fields => ["status_id", "assigned_to_id"],
-         :operators => {"assigned_to_id" => "=", "status_id" => "o"},
-         :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
-         :query => {"name" => "test_edit_global_private_query", "is_public" => "1"}
-
-    assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 3
-    q = Query.find_by_name('test_edit_global_private_query')
-    assert !q.is_public?
-    assert q.has_default_columns?
-    assert q.valid?
-  end
-
-  def test_get_edit_project_private_query
-    @request.session[:user_id] = 3
-    get :edit, :id => 2
-    assert_response :success
-    assert_template 'edit'
-    assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                    :name => 'query[is_public]' }
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'query_is_for_all',
-                                                 :checked => nil,
-                                                 :disabled => nil }
-  end
-
-  def test_get_edit_project_public_query
-    @request.session[:user_id] = 2
-    get :edit, :id => 1
-    assert_response :success
-    assert_template 'edit'
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'query[is_public]',
-                                                 :checked => 'checked'
-                                                  }
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'query_is_for_all',
-                                                 :checked => nil,
-                                                 :disabled => 'disabled' }
-  end
-
-  def test_get_edit_sort_criteria
-    @request.session[:user_id] = 1
-    get :edit, :id => 5
-    assert_response :success
-    assert_template 'edit'
-    assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' },
-                                 :child => { :tag => 'option', :attributes => { :value => 'priority',
-                                                                                :selected => 'selected' } }
-    assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' },
-                                 :child => { :tag => 'option', :attributes => { :value => 'desc',
-                                                                                :selected => 'selected' } }
-  end
-
-  def test_destroy
-    @request.session[:user_id] = 2
-    delete :destroy, :id => 1
-    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :set_filter => 1, :query_id => nil
-    assert_nil Query.find_by_id(1)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/64/642c69f33e7614a977979878c1ccc6e65c0c0226.svn-base
--- a/.svn/pristine/64/642c69f33e7614a977979878c1ccc6e65c0c0226.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/breakpointer'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/64/643e94db4aed32471bbf1bd1d5bd4f887d610b4b.svn-base
--- a/.svn/pristine/64/643e94db4aed32471bbf1bd1d5bd4f887d610b4b.svn-base
+++ /dev/null
@@ -1,100 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class AttachmentsController < ApplicationController
-  before_filter :find_project
-  before_filter :file_readable, :read_authorize, :except => :destroy
-  before_filter :delete_authorize, :only => :destroy
-
-  accept_api_auth :show, :download
-
-  def show
-    respond_to do |format|
-      format.html {
-        if @attachment.is_diff?
-          @diff = File.new(@attachment.diskfile, "rb").read
-          @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
-          @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
-          # Save diff type as user preference
-          if User.current.logged? && @diff_type != User.current.pref[:diff_type]
-            User.current.pref[:diff_type] = @diff_type
-            User.current.preference.save
-          end
-          render :action => 'diff'
-        elsif @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte
-          @content = File.new(@attachment.diskfile, "rb").read
-          render :action => 'file'
-        else
-          download
-        end
-      }
-      format.api
-    end
-  end
-
-  def download
-    if @attachment.container.is_a?(Version) || @attachment.container.is_a?(Project)
-      @attachment.increment_download
-    end
-
-    # images are sent inline
-    send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
-                                    :type => detect_content_type(@attachment),
-                                    :disposition => (@attachment.image? ? 'inline' : 'attachment')
-
-  end
-
-  verify :method => :delete, :only => :destroy
-  def destroy
-    # Make sure association callbacks are called
-    @attachment.container.attachments.delete(@attachment)
-    redirect_to :back
-  rescue ::ActionController::RedirectBackError
-    redirect_to :controller => 'projects', :action => 'show', :id => @project
-  end
-
-private
-  def find_project
-    @attachment = Attachment.find(params[:id])
-    # Show 404 if the filename in the url is wrong
-    raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename
-    @project = @attachment.project
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  # Checks that the file exists and is readable
-  def file_readable
-    @attachment.readable? ? true : render_404
-  end
-
-  def read_authorize
-    @attachment.visible? ? true : deny_access
-  end
-
-  def delete_authorize
-    @attachment.deletable? ? true : deny_access
-  end
-
-  def detect_content_type(attachment)
-    content_type = attachment.content_type
-    if content_type.blank?
-      content_type = Redmine::MimeType.of(attachment.filename)
-    end
-    content_type.to_s
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/64/6495ba1b375d76ae48a1a29718388eabb1d9a8c0.svn-base
--- /dev/null
+++ b/.svn/pristine/64/6495ba1b375d76ae48a1a29718388eabb1d9a8c0.svn-base
@@ -0,0 +1,49 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class CustomValue < ActiveRecord::Base
+  belongs_to :custom_field
+  belongs_to :customized, :polymorphic => true
+
+  def initialize(attributes=nil, *args)
+    super
+    if new_record? && custom_field && (customized_type.blank? || (customized && customized.new_record?))
+      self.value ||= custom_field.default_value
+    end
+  end
+
+  # Returns true if the boolean custom value is true
+  def true?
+    self.value == '1'
+  end
+
+  def editable?
+    custom_field.editable?
+  end
+
+  def visible?
+    custom_field.visible?
+  end
+
+  def required?
+    custom_field.is_required?
+  end
+
+  def to_s
+    value.to_s
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/64/64d46ee6e8251803e7c04c919d09da2321bf22b4.svn-base
--- a/.svn/pristine/64/64d46ee6e8251803e7c04c919d09da2321bf22b4.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-class AppAndPluginLibModel < ActiveRecord::Base
-  def self.report_location; TestHelper::report_location(__FILE__); end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/64/64d9599d84742c6f276c43c19ddf01ad011835e1.svn-base
--- a/.svn/pristine/64/64d9599d84742c6f276c43c19ddf01ad011835e1.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar RU language
-// Translation: Sly Golovanov, http://golovanov.net, <sly@golovanov.net>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Ð²Ð¾ÑÐºÑ€ÐµÑÐµÐ½ÑŒÐµ",
- "Ð¿Ð¾Ð½ÐµÐ´ÐµÐ»ÑŒÐ½Ð¸Ðº",
- "Ð²Ñ‚Ð¾Ñ€Ð½Ð¸Ðº",
- "ÑÑ€ÐµÐ´Ð°",
- "Ñ‡ÐµÑ‚Ð²ÐµÑ€Ð³",
- "Ð¿ÑÑ‚Ð½Ð¸Ñ†Ð°",
- "ÑÑƒÐ±Ð±Ð¾Ñ‚Ð°",
- "Ð²Ð¾ÑÐºÑ€ÐµÑÐµÐ½ÑŒÐµ");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Ð²ÑÐº",
- "Ð¿Ð¾Ð½",
- "Ð²Ñ‚Ñ€",
- "ÑÑ€Ð´",
- "Ñ‡ÐµÑ‚",
- "Ð¿ÑÑ‚",
- "ÑÑƒÐ±",
- "Ð²ÑÐº");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("ÑÐ½Ð²Ð°Ñ€ÑŒ",
- "Ñ„ÐµÐ²Ñ€Ð°Ð»ÑŒ",
- "Ð¼Ð°Ñ€Ñ‚",
- "Ð°Ð¿Ñ€ÐµÐ»ÑŒ",
- "Ð¼Ð°Ð¹",
- "Ð¸ÑŽÐ½ÑŒ",
- "Ð¸ÑŽÐ»ÑŒ",
- "Ð°Ð²Ð³ÑƒÑÑ‚",
- "ÑÐµÐ½Ñ‚ÑÐ±Ñ€ÑŒ",
- "Ð¾ÐºÑ‚ÑÐ±Ñ€ÑŒ",
- "Ð½Ð¾ÑÐ±Ñ€ÑŒ",
- "Ð´ÐµÐºÐ°Ð±Ñ€ÑŒ");
-
-// short month names
-Calendar._SMN = new Array
-("ÑÐ½Ð²",
- "Ñ„ÐµÐ²",
- "Ð¼Ð°Ñ€",
- "Ð°Ð¿Ñ€",
- "Ð¼Ð°Ð¹",
- "Ð¸ÑŽÐ½",
- "Ð¸ÑŽÐ»",
- "Ð°Ð²Ð³",
- "ÑÐµÐ½",
- "Ð¾ÐºÑ‚",
- "Ð½Ð¾Ñ",
- "Ð´ÐµÐº");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Ðž ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ðµ...";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"ÐšÐ°Ðº Ð²Ñ‹Ð±Ñ€Ð°Ñ‚ÑŒ Ð´Ð°Ñ‚Ñƒ:\n" +
-"- ÐŸÑ€Ð¸ Ð¿Ð¾Ð¼Ð¾Ñ‰Ð¸ ÐºÐ½Ð¾Ð¿Ð¾Ðº \xab, \xbb Ð¼Ð¾Ð¶Ð½Ð¾ Ð²Ñ‹Ð±Ñ€Ð°Ñ‚ÑŒ Ð³Ð¾Ð´\n" +
-"- ÐŸÑ€Ð¸ Ð¿Ð¾Ð¼Ð¾Ñ‰Ð¸ ÐºÐ½Ð¾Ð¿Ð¾Ðº " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Ð¼Ð¾Ð¶Ð½Ð¾ Ð²Ñ‹Ð±Ñ€Ð°Ñ‚ÑŒ Ð¼ÐµÑÑÑ†\n" +
-"- ÐŸÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚Ðµ ÑÑ‚Ð¸ ÐºÐ½Ð¾Ð¿ÐºÐ¸ Ð½Ð°Ð¶Ð°Ñ‚Ñ‹Ð¼Ð¸, Ñ‡Ñ‚Ð¾Ð±Ñ‹ Ð¿Ð¾ÑÐ²Ð¸Ð»Ð¾ÑÑŒ Ð¼ÐµÐ½ÑŽ Ð±Ñ‹ÑÑ‚Ñ€Ð¾Ð³Ð¾ Ð²Ñ‹Ð±Ð¾Ñ€Ð°.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"ÐšÐ°Ðº Ð²Ñ‹Ð±Ñ€Ð°Ñ‚ÑŒ Ð²Ñ€ÐµÐ¼Ñ:\n" +
-"- ÐŸÑ€Ð¸ ÐºÐ»Ð¸ÐºÐµ Ð½Ð° Ñ‡Ð°ÑÐ°Ñ… Ð¸Ð»Ð¸ Ð¼Ð¸Ð½ÑƒÑ‚Ð°Ñ… Ð¾Ð½Ð¸ ÑƒÐ²ÐµÐ»Ð¸Ñ‡Ð¸Ð²Ð°ÑŽÑ‚ÑÑ\n" +
-"- Ð¿Ñ€Ð¸ ÐºÐ»Ð¸ÐºÐµ Ñ Ð½Ð°Ð¶Ð°Ñ‚Ð¾Ð¹ ÐºÐ»Ð°Ð²Ð¸ÑˆÐµÐ¹ Shift Ð¾Ð½Ð¸ ÑƒÐ¼ÐµÐ½ÑŒÑˆÐ°ÑŽÑ‚ÑÑ\n" +
-"- ÐµÑÐ»Ð¸ Ð½Ð°Ð¶Ð°Ñ‚ÑŒ Ð¸ Ð´Ð²Ð¸Ð³Ð°Ñ‚ÑŒ Ð¼Ñ‹ÑˆÐºÐ¾Ð¹ Ð²Ð»ÐµÐ²Ð¾/Ð²Ð¿Ñ€Ð°Ð²Ð¾, Ð¾Ð½Ð¸ Ð±ÑƒÐ´ÑƒÑ‚ Ð¼ÐµÐ½ÑÑ‚ÑŒÑÑ Ð±Ñ‹ÑÑ‚Ñ€ÐµÐµ.";
-
-Calendar._TT["PREV_YEAR"] = "ÐÐ° Ð³Ð¾Ð´ Ð½Ð°Ð·Ð°Ð´ (ÑƒÐ´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ‚ÑŒ Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)";
-Calendar._TT["PREV_MONTH"] = "ÐÐ° Ð¼ÐµÑÑÑ† Ð½Ð°Ð·Ð°Ð´ (ÑƒÐ´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ‚ÑŒ Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)";
-Calendar._TT["GO_TODAY"] = "Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ";
-Calendar._TT["NEXT_MONTH"] = "ÐÐ° Ð¼ÐµÑÑÑ† Ð²Ð¿ÐµÑ€ÐµÐ´ (ÑƒÐ´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ‚ÑŒ Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)";
-Calendar._TT["NEXT_YEAR"] = "ÐÐ° Ð³Ð¾Ð´ Ð²Ð¿ÐµÑ€ÐµÐ´ (ÑƒÐ´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ‚ÑŒ Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)";
-Calendar._TT["SEL_DATE"] = "Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð´Ð°Ñ‚Ñƒ";
-Calendar._TT["DRAG_TO_MOVE"] = "ÐŸÐµÑ€ÐµÑ‚Ð°ÑÐºÐ¸Ð²Ð°Ð¹Ñ‚Ðµ Ð¼Ñ‹ÑˆÐºÐ¾Ð¹";
-Calendar._TT["PART_TODAY"] = " (ÑÐµÐ³Ð¾Ð´Ð½Ñ)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "ÐŸÐµÑ€Ð²Ñ‹Ð¹ Ð´ÐµÐ½ÑŒ Ð½ÐµÐ´ÐµÐ»Ð¸ Ð±ÑƒÐ´ÐµÑ‚ %s";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Ð—Ð°ÐºÑ€Ñ‹Ñ‚ÑŒ";
-Calendar._TT["TODAY"] = "Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ";
-Calendar._TT["TIME_PART"] = "(Shift-)ÐºÐ»Ð¸Ðº Ð¸Ð»Ð¸ Ð½Ð°Ð¶Ð°Ñ‚ÑŒ Ð¸ Ð´Ð²Ð¸Ð³Ð°Ñ‚ÑŒ";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%e %b, %a";
-
-Calendar._TT["WK"] = "Ð½ÐµÐ´";
-Calendar._TT["TIME"] = "Ð’Ñ€ÐµÐ¼Ñ:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/64/64e2a2f022fb062bdaa6b6061eb9a2636bb458a2.svn-base
--- /dev/null
+++ b/.svn/pristine/64/64e2a2f022fb062bdaa6b6061eb9a2636bb458a2.svn-base
@@ -0,0 +1,75 @@
+<%= error_messages_for 'member' %>
+<% roles = Role.find_all_givable
+   members = @project.member_principals.includes(:roles, :principal).all.sort %>
+
+<div class="splitcontentleft">
+<% if members.any? %>
+<table class="list members">
+  <thead><tr>
+    <th><%= l(:label_user) %> / <%= l(:label_group) %></th>
+    <th><%= l(:label_role_plural) %></th>
+    <th style="width:15%"></th>
+          <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %>
+  </tr></thead>
+  <tbody>
+  <% members.each do |member| %>
+  <% next if member.new_record? %>
+  <tr id="member-<%= member.id %>" class="<%= cycle 'odd', 'even' %> member">
+  <td class="<%= member.principal.class.name.downcase %>"><%= link_to_user member.principal %></td>
+  <td class="roles">
+    <span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span>
+      <%= form_for(member, {:as => :membership, :remote => true, :url => membership_path(member),
+                                          :method => :put,
+                                          :html => { :id => "member-#{member.id}-roles-form", :class => 'hol' }}
+             ) do |f| %>
+        <p><% roles.each do |role| %>
+        <label><%= check_box_tag 'membership[role_ids][]', role.id, member.roles.include?(role),
+                                                       :disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br />
+        <% end %></p>
+        <%= hidden_field_tag 'membership[role_ids][]', '' %>
+        <p><%= submit_tag l(:button_change), :class => "small" %>
+        <%= link_to_function l(:button_cancel),
+                             "$('#member-#{member.id}-roles').show(); $('#member-#{member.id}-roles-form').hide(); return false;"
+             %></p>
+      <% end %>
+  </td>
+  <td class="buttons">
+      <%= link_to_function l(:button_edit),
+                           "$('#member-#{member.id}-roles').hide(); $('#member-#{member.id}-roles-form').show(); return false;",
+                           :class => 'icon icon-edit' %>
+      <%= delete_link membership_path(member),
+                      :remote => true,
+                      :data => (!User.current.admin? && member.include?(User.current) ? {:confirm => l(:text_own_membership_delete_confirmation)} : {}) if member.deletable? %>
+  </td>
+  <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %>
+  </tr>
+<% end; reset_cycle %>
+  </tbody>
+</table>
+<% else %>
+<p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
+</div>
+
+<div class="splitcontentright">
+<% if roles.any? %>
+  <%= form_for(@member, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %>
+    <fieldset><legend><%=l(:label_member_new)%></legend>
+
+    <p><%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %></p>
+    <%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_project_memberships_path(@project, :format => 'js') }')" %>
+
+    <div id="principals_for_new_member">
+      <%= render_principals_for_new_members(@project) %>
+    </div>
+
+    <p><%= l(:label_role_plural) %>:
+    <% roles.each do |role| %>
+      <label><%= check_box_tag 'membership[role_ids][]', role.id %> <%=h role %></label>
+     <% end %></p>
+
+    <p><%= submit_tag l(:button_add), :id => 'member-add-submit' %></p>
+    </fieldset>
+  <% end %>
+<% end %>
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/6522becd35e6716c94ac60c2f3bd1780740bea87.svn-base
--- /dev/null
+++ b/.svn/pristine/65/6522becd35e6716c94ac60c2f3bd1780740bea87.svn-base
@@ -0,0 +1,62 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class DocumentTest < ActiveSupport::TestCase
+  fixtures :projects, :enumerations, :documents, :attachments,
+           :enabled_modules,
+           :users, :members, :member_roles, :roles,
+           :groups_users
+
+  def test_create
+    doc = Document.new(:project => Project.find(1), :title => 'New document', :category => Enumeration.find_by_name('User documentation'))
+    assert doc.save
+  end
+
+  def test_create_should_send_email_notification
+    ActionMailer::Base.deliveries.clear
+    
+    with_settings :notified_events => %w(document_added) do
+      doc = Document.new(:project => Project.find(1), :title => 'New document', :category => Enumeration.find_by_name('User documentation'))
+      assert doc.save
+    end
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_create_with_default_category
+    # Sets a default category
+    e = Enumeration.find_by_name('Technical documentation')
+    e.update_attributes(:is_default => true)
+
+    doc = Document.new(:project => Project.find(1), :title => 'New document')
+    assert_equal e, doc.category
+    assert doc.save
+  end
+
+  def test_updated_on_with_attachments
+    d = Document.find(1)
+    assert d.attachments.any?
+    assert_equal d.attachments.map(&:created_on).max, d.updated_on
+  end
+
+  def test_updated_on_without_attachments
+    d = Document.find(2)
+    assert d.attachments.empty?
+    assert_equal d.created_on, d.updated_on
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/652cee5115cd618a1d7b1b071076d6439b22f7ec.svn-base
--- a/.svn/pristine/65/652cee5115cd618a1d7b1b071076d6439b22f7ec.svn-base
+++ /dev/null
@@ -1,60 +0,0 @@
-class ContextMenusController < ApplicationController
-  helper :watchers
-  helper :issues
-
-  def issues
-    @issues = Issue.visible.all(:conditions => {:id => params[:ids]}, :include => :project)
-
-    if (@issues.size == 1)
-      @issue = @issues.first
-      @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
-    else
-      @allowed_statuses = @issues.map do |i|
-        i.new_statuses_allowed_to(User.current)
-      end.inject do |memo,s|
-        memo & s
-      end
-    end
-    @projects = @issues.collect(&:project).compact.uniq
-    @project = @projects.first if @projects.size == 1
-
-    @can = {:edit => User.current.allowed_to?(:edit_issues, @projects),
-            :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
-            :update => (User.current.allowed_to?(:edit_issues, @projects) || (User.current.allowed_to?(:change_status, @projects) && !@allowed_statuses.blank?)),
-            :move => (@project && User.current.allowed_to?(:move_issues, @project)),
-            :copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
-            :delete => User.current.allowed_to?(:delete_issues, @projects)
-            }
-    if @project
-      if @issue
-        @assignables = @issue.assignable_users
-      else
-        @assignables = @project.assignable_users
-      end
-      @trackers = @project.trackers
-    else
-      #when multiple projects, we only keep the intersection of each set
-      @assignables = @projects.map(&:assignable_users).inject{|memo,a| memo & a}
-      @trackers = @projects.map(&:trackers).inject{|memo,t| memo & t}
-    end
-
-    @priorities = IssuePriority.active.reverse
-    @statuses = IssueStatus.find(:all, :order => 'position')
-    @back = back_url
-
-    render :layout => false
-  end
-
-  def time_entries
-    @time_entries = TimeEntry.all(
-       :conditions => {:id => params[:ids]}, :include => :project)
-    @projects = @time_entries.collect(&:project).compact.uniq
-    @project = @projects.first if @projects.size == 1
-    @activities = TimeEntryActivity.shared.active
-    @can = {:edit   => User.current.allowed_to?(:edit_time_entries, @projects),
-            :delete => User.current.allowed_to?(:edit_time_entries, @projects)
-            }
-    @back = back_url
-    render :layout => false
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/6548ced1be2ac2971e9540ff4fe8979b3f03573e.svn-base
--- /dev/null
+++ b/.svn/pristine/65/6548ced1be2ac2971e9540ff4fe8979b3f03573e.svn-base
@@ -0,0 +1,80 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingIssueStatusesTest < ActionController::IntegrationTest
+  def test_issue_statuses
+    assert_routing(
+        { :method => 'get', :path => "/issue_statuses" },
+        { :controller => 'issue_statuses', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issue_statuses.xml" },
+        { :controller => 'issue_statuses', :action => 'index', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issue_statuses" },
+        { :controller => 'issue_statuses', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issue_statuses.xml" },
+        { :controller => 'issue_statuses', :action => 'create', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issue_statuses/new" },
+        { :controller => 'issue_statuses', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issue_statuses/new.xml" },
+        { :controller => 'issue_statuses', :action => 'new', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issue_statuses/1/edit" },
+        { :controller => 'issue_statuses', :action => 'edit', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/issue_statuses/1" },
+        { :controller => 'issue_statuses', :action => 'update',
+          :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/issue_statuses/1.xml" },
+        { :controller => 'issue_statuses', :action => 'update',
+          :format => 'xml', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/issue_statuses/1" },
+        { :controller => 'issue_statuses', :action => 'destroy',
+          :id => '1' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/issue_statuses/1.xml" },
+        { :controller => 'issue_statuses', :action => 'destroy',
+          :format => 'xml', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issue_statuses/update_issue_done_ratio" },
+        { :controller => 'issue_statuses', :action => 'update_issue_done_ratio' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issue_statuses/update_issue_done_ratio.xml" },
+        { :controller => 'issue_statuses', :action => 'update_issue_done_ratio',
+          :format => 'xml' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/65538df31e36234b3f7b2e1412df21f4d984c90c.svn-base
--- a/.svn/pristine/65/65538df31e36234b3f7b2e1412df21f4d984c90c.svn-base
+++ /dev/null
@@ -1,10 +0,0 @@
-<h2><%= l(:label_settings) %>: <%=h @plugin.name %></h2>
-
-<div id="settings">
-<% form_tag({:action => 'plugin'}) do %>
-<div class="box tabular">
-<%= render :partial => @partial, :locals => {:settings => @settings}%>
-</div>
-<%= submit_tag l(:button_apply) %>
-<% end %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/65761dc96875890d24f44eea0c8e51f6640664b9.svn-base
--- a/.svn/pristine/65/65761dc96875890d24f44eea0c8e51f6640664b9.svn-base
+++ /dev/null
@@ -1,173 +0,0 @@
-var commits = chunk.commits,
-    comms = {},
-    pixelsX = [],
-    pixelsY = [],
-    mmax = Math.max,
-    max_rdmid = 0,
-    max_space = 0,
-    parents = {};
-for (var i = 0, ii = commits.length; i < ii; i++) {
-    for (var j = 0, jj = commits[i].parents.length; j < jj; j++) {
-        parents[commits[i].parents[j][0]] = true;
-    }
-    max_rdmid = Math.max(max_rdmid, commits[i].rdmid);
-    max_space = Math.max(max_space, commits[i].space);
-}
-
-for (i = 0; i < ii; i++) {
-    if (commits[i].scmid in parents) {
-        commits[i].isParent = true;
-    }
-    comms[commits[i].scmid] = commits[i];
-}
-var colors = ["#000"];
-for (var k = 0; k < max_space; k++) {
-    colors.push(Raphael.getColor());
-}
-
-function branchGraph(holder) {
-    var xstep = 20;
-    var ystep = $$('tr.changeset')[0].getHeight();
-    var ch, cw;
-    cw = max_space * xstep + xstep;
-    ch = max_rdmid * ystep + ystep;
-    var r = Raphael("holder", cw, ch),
-        top = r.set();
-    var cuday = 0, cumonth = "";
-
-    for (i = 0; i < ii; i++) {
-        var x, y;
-        y = 10 + ystep *(max_rdmid - commits[i].rdmid);
-        x = 3 + xstep * commits[i].space;
-        var stroke = "none";
-        r.circle(x, y, 3).attr({fill: colors[commits[i].space], stroke: stroke});
-        if (commits[i].refs != null && commits[i].refs != "") {
-            var longrefs  = commits[i].refs
-            var shortrefs = commits[i].refs;
-            if (shortrefs.length > 15) {
-              shortrefs = shortrefs.substr(0,13) + "...";
-              }
-            var t = r.text(x+5,y+5,shortrefs).attr({font: "12px Fontin-Sans, Arial", fill: "#666",
-            title: longrefs, cursor: "pointer", rotation: "0"});
-
-            var textbox = t.getBBox();
-            t.translate(textbox.width / 2, textbox.height / -3);
-         }
-        for (var j = 0, jj = commits[i].parents.length; j < jj; j++) {
-            var c = comms[commits[i].parents[j][0]];
-            var p,arrow;
-            if (c) {
-                var cy, cx;
-                cy = 10 + ystep * (max_rdmid - c.rdmid),
-                cx = 3 + xstep * c.space;
-
-                if (c.space == commits[i].space) {
-                    p = r.path("M" + x + "," + y + "L" + cx + "," + cy);
-                } else {
-                    p = r.path(["M", x, y, "C",x,y,x, y+(cy-y)/2,x+(cx-x)/2, y+(cy-y)/2,
-                                "C", x+(cx-x)/2,y+(cy-y)/2, cx, cy-(cy-y)/2, cx, cy]);
-                }
-            } else {
-              p = r.path("M" + x + "," + y + "L" + x + "," + ch);
-             }
-            p.attr({stroke: colors[commits[i].space], "stroke-width": 1.5});
-         }
-        (function (c, x, y) {
-            top.push(r.circle(x, y, 10).attr({fill: "#000", opacity: 0,
-                                              cursor: "pointer", href: commits[i].href})
-              .hover(function () {}, function () {})
-              );
-        }(commits[i], x, y));
-     }
-    top.toFront();
-    var hw = holder.offsetWidth,
-        hh = holder.offsetHeight,
-        drag,
-        dragger = function (e) {
-            if (drag) {
-                e = e || window.event;
-                holder.scrollLeft = drag.sl - (e.clientX - drag.x);
-                holder.scrollTop = drag.st - (e.clientY - drag.y);
-            }
-        };
-    holder.onmousedown = function (e) {
-        e = e || window.event;
-        drag = {x: e.clientX, y: e.clientY, st: holder.scrollTop, sl: holder.scrollLeft};
-        document.onmousemove = dragger;
-    };
-    document.onmouseup = function () {
-        drag = false;
-        document.onmousemove = null;
-    };
-    holder.scrollLeft = cw;
-};
-
-Raphael.fn.popupit = function (x, y, set, dir, size) {
-    dir = dir == null ? 2 : dir;
-    size = size || 5;
-    x = Math.round(x);
-    y = Math.round(y);
-    var bb = set.getBBox(),
-        w = Math.round(bb.width / 2),
-        h = Math.round(bb.height / 2),
-        dx = [0, w + size * 2, 0, -w - size * 2],
-        dy = [-h * 2 - size * 3, -h - size, 0, -h - size],
-        p = ["M", x - dx[dir], y - dy[dir], "l", -size, (dir == 2) * -size, -mmax(w - size, 0),
-             0, "a", size, size, 0, 0, 1, -size, -size,
-            "l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0,
-            -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size,
-            "l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0),
-            0, "a", size, size, 0, 0, 1, size, size,
-            "l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0,
-            mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size,
-            "l", -mmax(w - size, 0), 0, "z"].join(","),
-        xy = [{x: x, y: y + size * 2 + h},
-              {x: x - size * 2 - w, y: y},
-              {x: x, y: y - size * 2 - h},
-              {x: x + size * 2 + w, y: y}]
-              [dir];
-    set.translate(xy.x - w - bb.x, xy.y - h - bb.y);
-    return this.set(this.path(p).attr({fill: "#234", stroke: "none"})
-                     .insertBefore(set.node ? set : set[0]), set);
-};
-
-Raphael.fn.popup = function (x, y, text, dir, size) {
-    dir = dir == null ? 2 : dir > 3 ? 3 : dir;
-    size = size || 5;
-    text = text || "$9.99";
-    var res = this.set(),
-        d = 3;
-    res.push(this.path().attr({fill: "#000", stroke: "#000"}));
-    res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff", "font-family": "Helvetica, Arial"}));
-    res.update = function (X, Y, withAnimation) {
-        X = X || x;
-        Y = Y || y;
-        var bb = this[1].getBBox(),
-            w = bb.width / 2,
-            h = bb.height / 2,
-            dx = [0, w + size * 2, 0, -w - size * 2],
-            dy = [-h * 2 - size * 3, -h - size, 0, -h - size],
-            p = ["M", X - dx[dir], Y - dy[dir], "l", -size, (dir == 2) * -size,
-                 -mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size,
-                "l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size,
-                 0, -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size,
-                "l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0),
-                 0, "a", size, size, 0, 0, 1, size, size,
-                "l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0,
-                mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size,
-                "l", -mmax(w - size, 0), 0, "z"].join(","),
-            xy = [{x: X, y: Y + size * 2 + h},
-                  {x: X - size * 2 - w, y: Y},
-                  {x: X, y: Y - size * 2 - h},
-                  {x: X + size * 2 + w, y: Y}]
-                  [dir];
-        xy.path = p;
-        if (withAnimation) {
-            this.animate(xy, 500, ">");
-        } else {
-            this.attr(xy);
-         }
-        return this;
-     };
-    return res.update(x, y);
-};
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/657bd14b118043b9ebda19a4d6192af1ad0ce4ac.svn-base
--- a/.svn/pristine/65/657bd14b118043b9ebda19a4d6192af1ad0ce4ac.svn-base
+++ /dev/null
@@ -1,60 +0,0 @@
-Return-Path: <JSmith@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
-Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
-From: "John Smith" <JSmith@somenet.foo>
-To: <redmine@somenet.foo>
-Subject: New ticket on a given project
-Date: Sun, 22 Jun 2008 12:28:07 +0200
-MIME-Version: 1.0
-Content-Type: text/plain;
-	format=flowed;
-	charset="iso-8859-1";
-	reply-type=original
-Content-Transfer-Encoding: 7bit
-X-Priority: 3
-X-MSMail-Priority: Normal
-X-Mailer: Microsoft Outlook Express 6.00.2900.2869
-X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet 
-turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus 
-blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti 
-sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In 
-in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras 
-sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum 
-id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus 
-eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique 
-sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et 
-malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
-platea dictumst.
-
---- This line starts with a delimiter and should not be stripped
-
-This paragraph is before delimiters.
-
-BREAK
-
-This paragraph is between delimiters.
-
----
-
-This paragraph is after the delimiter so it shouldn't appear.
-
-Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque 
-sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. 
-Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, 
-dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed, 
-massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo 
-pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
-
-Project: onlinestore
-Status: Resolved
-due date: 2010-12-31
-Start Date:2010-01-01
-Assigned to: John Smith
-fixed version: alpha
-estimated hours: 2.5
-done ratio: 30
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/659cc1b107566502a54373a80e2f28e678539ea0.svn-base
--- a/.svn/pristine/65/659cc1b107566502a54373a80e2f28e678539ea0.svn-base
+++ /dev/null
@@ -1,140 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # Scanner for YAML.
-  #
-  # Based on the YAML scanner from Syntax by Jamis Buck.
-  class YAML < Scanner
-    
-    register_for :yaml
-    file_extension 'yml'
-    
-    KINDS_NOT_LOC = :all
-    
-  protected
-    
-    def scan_tokens encoder, options
-      
-      state = :initial
-      key_indent = string_indent = 0
-      
-      until eos?
-        
-        key_indent = nil if bol?
-        
-        if match = scan(/ +[\t ]*/)
-          encoder.text_token match, :space
-          
-        elsif match = scan(/\n+/)
-          encoder.text_token match, :space
-          state = :initial if match.index(?\n)
-          
-        elsif match = scan(/#.*/)
-          encoder.text_token match, :comment
-          
-        elsif bol? and case
-          when match = scan(/---|\.\.\./)
-            encoder.begin_group :head
-            encoder.text_token match, :head
-            encoder.end_group :head
-            next
-          when match = scan(/%.*/)
-            encoder.text_token match, :doctype
-            next
-          end
-        
-        elsif state == :value and case
-          when !check(/(?:"[^"]*")(?=: |:$)/) && match = scan(/"/)
-            encoder.begin_group :string
-            encoder.text_token match, :delimiter
-            encoder.text_token match, :content if match = scan(/ [^"\\]* (?: \\. [^"\\]* )* /mx)
-            encoder.text_token match, :delimiter if match = scan(/"/)
-            encoder.end_group :string
-            next
-          when match = scan(/[|>][-+]?/)
-            encoder.begin_group :string
-            encoder.text_token match, :delimiter
-            string_indent = key_indent || column(pos - match.size) - 1
-            encoder.text_token matched, :content if scan(/(?:\n+ {#{string_indent + 1}}.*)+/)
-            encoder.end_group :string
-            next
-          when match = scan(/(?![!"*&]).+?(?=$|\s+#)/)
-            encoder.begin_group :string
-            encoder.text_token match, :content
-            string_indent = key_indent || column(pos - match.size) - 1
-            encoder.text_token matched, :content if scan(/(?:\n+ {#{string_indent + 1}}.*)+/)
-            encoder.end_group :string
-            next
-          end
-          
-        elsif case
-          when match = scan(/[-:](?= |$)/)
-            state = :value if state == :colon && (match == ':' || match == '-')
-            state = :value if state == :initial && match == '-'
-            encoder.text_token match, :operator
-            next
-          when match = scan(/[,{}\[\]]/)
-            encoder.text_token match, :operator
-            next
-          when state == :initial && match = scan(/[\w.() ]*\S(?= *:(?: |$))/)
-            encoder.text_token match, :key
-            key_indent = column(pos - match.size) - 1
-            state = :colon
-            next
-          when match = scan(/(?:"[^"\n]*"|'[^'\n]*')(?= *:(?: |$))/)
-            encoder.begin_group :key
-            encoder.text_token match[0,1], :delimiter
-            encoder.text_token match[1..-2], :content
-            encoder.text_token match[-1,1], :delimiter
-            encoder.end_group :key
-            key_indent = column(pos - match.size) - 1
-            state = :colon
-            next
-          when match = scan(/(![\w\/]+)(:([\w:]+))?/)
-            encoder.text_token self[1], :type
-            if self[2]
-              encoder.text_token ':', :operator
-              encoder.text_token self[3], :class
-            end
-            next
-          when match = scan(/&\S+/)
-            encoder.text_token match, :variable
-            next
-          when match = scan(/\*\w+/)
-            encoder.text_token match, :global_variable
-            next
-          when match = scan(/<</)
-            encoder.text_token match, :class_variable
-            next
-          when match = scan(/\d\d:\d\d:\d\d/)
-            encoder.text_token match, :octal
-            next
-          when match = scan(/\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d(\.\d+)? [-+]\d\d:\d\d/)
-            encoder.text_token match, :octal
-            next
-          when match = scan(/:\w+/)
-            encoder.text_token match, :symbol
-            next
-          when match = scan(/[^:\s]+(:(?! |$)[^:\s]*)* .*/)
-            encoder.text_token match, :error
-            next
-          when match = scan(/[^:\s]+(:(?! |$)[^:\s]*)*/)
-            encoder.text_token match, :error
-            next
-          end
-          
-        else
-          raise if eos?
-          encoder.text_token getch, :error
-          
-        end
-        
-      end
-      
-      encoder
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/65b88641ff8e4579cbf40b69a6bf7f5392a27740.svn-base
--- /dev/null
+++ b/.svn/pristine/65/65b88641ff8e4579cbf40b69a6bf7f5392a27740.svn-base
@@ -0,0 +1,106 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssuePriorityTest < ActiveSupport::TestCase
+  fixtures :enumerations, :issues
+
+  def test_named_scope
+    assert_equal Enumeration.find_by_name('Normal'), Enumeration.named('normal').first
+  end
+
+  def test_default_should_return_the_default_priority
+    assert_equal Enumeration.find_by_name('Normal'), IssuePriority.default
+  end
+
+  def test_default_should_return_nil_when_no_default_priority
+    IssuePriority.update_all :is_default => false
+    assert_nil IssuePriority.default
+  end
+
+  def test_should_be_an_enumeration
+    assert IssuePriority.ancestors.include?(Enumeration)
+  end
+
+  def test_objects_count
+    # low priority
+    assert_equal 6, IssuePriority.find(4).objects_count
+    # urgent
+    assert_equal 0, IssuePriority.find(7).objects_count
+  end
+
+  def test_option_name
+    assert_equal :enumeration_issue_priorities, IssuePriority.new.option_name
+  end
+
+  def test_should_be_created_at_last_position
+    IssuePriority.delete_all
+
+    priorities = [1, 2, 3].map {|i| IssuePriority.create!(:name => "P#{i}")}
+    assert_equal [1, 2, 3], priorities.map(&:position)
+  end
+
+  def test_reset_positions_in_list_should_set_sequential_positions
+    IssuePriority.delete_all
+
+    priorities = [1, 2, 3].map {|i| IssuePriority.create!(:name => "P#{i}")}
+    priorities[0].update_attribute :position, 4
+    priorities[1].update_attribute :position, 2
+    priorities[2].update_attribute :position, 7
+    assert_equal [4, 2, 7], priorities.map(&:reload).map(&:position)
+
+    priorities[0].reset_positions_in_list
+    assert_equal [2, 1, 3], priorities.map(&:reload).map(&:position)
+  end
+
+  def test_moving_in_list_should_reset_positions
+    priority = IssuePriority.first
+    priority.expects(:reset_positions_in_list).once
+    priority.move_to = 'higher'
+  end
+
+  def test_clear_position_names_should_set_position_names_to_nil
+    IssuePriority.clear_position_names
+    assert IssuePriority.all.all? {|priority| priority.position_name.nil?}
+  end
+
+  def test_compute_position_names_with_default_priority
+    IssuePriority.clear_position_names
+
+    IssuePriority.compute_position_names
+    assert_equal %w(lowest default high3 high2 highest), IssuePriority.active.all.sort.map(&:position_name)
+  end
+
+  def test_compute_position_names_without_default_priority_should_split_priorities
+    IssuePriority.clear_position_names
+    IssuePriority.update_all :is_default => false
+
+    IssuePriority.compute_position_names
+    assert_equal %w(lowest low2 default high2 highest), IssuePriority.active.all.sort.map(&:position_name)
+  end
+
+  def test_adding_a_priority_should_update_position_names
+    priority = IssuePriority.create!(:name => 'New')
+    assert_equal %w(lowest default high4 high3 high2 highest), IssuePriority.active.all.sort.map(&:position_name)
+  end
+
+  def test_destroying_a_priority_should_update_position_names
+    IssuePriority.find_by_position_name('highest').destroy
+    assert_equal %w(lowest default high2 highest), IssuePriority.active.all.sort.map(&:position_name)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/65c4d0cb8c8282f190e809331350172b32319080.svn-base
--- a/.svn/pristine/65/65c4d0cb8c8282f190e809331350172b32319080.svn-base
+++ /dev/null
@@ -1,55 +0,0 @@
-# General Apache options
-<IfModule mod_fastcgi.c>
-	AddHandler fastcgi-script .fcgi
-</IfModule>
-<IfModule mod_fcgid.c>
-	AddHandler fcgid-script .fcgi
-</IfModule>
-<IfModule mod_cgi.c>
-	AddHandler cgi-script .cgi
-</IfModule>
-Options +FollowSymLinks +ExecCGI
-
-# If you don't want Rails to look in certain directories,
-# use the following rewrite rules so that Apache won't rewrite certain requests
-# 
-# Example:
-#   RewriteCond %{REQUEST_URI} ^/notrails.*
-#   RewriteRule .* - [L]
-
-# Redirect all requests not available on the filesystem to Rails
-# By default the cgi dispatcher is used which is very slow
-# 
-# For better performance replace the dispatcher with the fastcgi one
-#
-# Example:
-#   RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
-RewriteEngine On
-
-# If your Rails application is accessed via an Alias directive,
-# then you MUST also set the RewriteBase in this htaccess file.
-#
-# Example:
-#   Alias /myrailsapp /path/to/myrailsapp/public
-#   RewriteBase /myrailsapp
-
-RewriteRule ^$ index.html [QSA]
-RewriteRule ^([^.]+)$ $1.html [QSA]
-RewriteCond %{REQUEST_FILENAME} !-f
-<IfModule mod_fastcgi.c>
-	RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
-</IfModule>
-<IfModule mod_fcgid.c>
-	RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
-</IfModule>
-<IfModule mod_cgi.c>
-	RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
-</IfModule>
-
-# In case Rails experiences terminal errors
-# Instead of displaying this message you can supply a file here which will be rendered instead
-# 
-# Example:
-#   ErrorDocument 500 /500.html
-
-ErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/65c994bd2135199487251ba6af321a01cf90b1ea.svn-base
Binary file .svn/pristine/65/65c994bd2135199487251ba6af321a01cf90b1ea.svn-base has changed
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/65e9a6c068b35b0498ff2c94d67db3241b91f5be.svn-base
--- /dev/null
+++ b/.svn/pristine/65/65e9a6c068b35b0498ff2c94d67db3241b91f5be.svn-base
@@ -0,0 +1,126 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::IssueCategoriesTest < Redmine::ApiTest::Base
+  fixtures :projects, :users, :issue_categories, :issues,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "GET /projects/:project_id/issue_categories.xml" do
+    should "return issue categories" do
+      get '/projects/1/issue_categories.xml', {}, credentials('jsmith')
+      assert_response :success
+      assert_equal 'application/xml', @response.content_type
+      assert_tag :tag => 'issue_categories',
+        :child => {:tag => 'issue_category', :child => {:tag => 'id', :content => '2'}}
+    end
+  end
+
+  context "GET /issue_categories/2.xml" do
+    should "return requested issue category" do
+      get '/issue_categories/2.xml', {}, credentials('jsmith')
+      assert_response :success
+      assert_equal 'application/xml', @response.content_type
+      assert_tag :tag => 'issue_category',
+        :child => {:tag => 'id', :content => '2'}
+    end
+  end
+
+  context "POST /projects/:project_id/issue_categories.xml" do
+    should "return create issue category" do
+      assert_difference 'IssueCategory.count' do
+        post '/projects/1/issue_categories.xml', {:issue_category => {:name => 'API'}}, credentials('jsmith')
+      end
+      assert_response :created
+      assert_equal 'application/xml', @response.content_type
+
+      category = IssueCategory.first(:order => 'id DESC')
+      assert_equal 'API', category.name
+      assert_equal 1, category.project_id
+    end
+
+    context "with invalid parameters" do
+      should "return errors" do
+        assert_no_difference 'IssueCategory.count' do
+          post '/projects/1/issue_categories.xml', {:issue_category => {:name => ''}}, credentials('jsmith')
+        end
+        assert_response :unprocessable_entity
+        assert_equal 'application/xml', @response.content_type
+
+        assert_tag 'errors', :child => {:tag => 'error', :content => "Name can't be blank"}
+      end
+    end
+  end
+
+  context "PUT /issue_categories/2.xml" do
+    context "with valid parameters" do
+      should "update issue category" do
+        assert_no_difference 'IssueCategory.count' do
+          put '/issue_categories/2.xml', {:issue_category => {:name => 'API Update'}}, credentials('jsmith')
+        end
+        assert_response :ok
+        assert_equal '', @response.body
+        assert_equal 'API Update', IssueCategory.find(2).name
+      end
+    end
+
+    context "with invalid parameters" do
+      should "return errors" do
+        assert_no_difference 'IssueCategory.count' do
+          put '/issue_categories/2.xml', {:issue_category => {:name => ''}}, credentials('jsmith')
+        end
+        assert_response :unprocessable_entity
+        assert_equal 'application/xml', @response.content_type
+
+        assert_tag 'errors', :child => {:tag => 'error', :content => "Name can't be blank"}
+      end
+    end
+  end
+
+  context "DELETE /issue_categories/1.xml" do
+    should "destroy issue categories" do
+      assert_difference 'IssueCategory.count', -1 do
+        delete '/issue_categories/1.xml', {}, credentials('jsmith')
+      end
+      assert_response :ok
+      assert_equal '', @response.body
+      assert_nil IssueCategory.find_by_id(1)
+    end
+    
+    should "reassign issues with :reassign_to_id param" do
+      issue_count = Issue.count(:conditions => {:category_id => 1})
+      assert issue_count > 0
+
+      assert_difference 'IssueCategory.count', -1 do
+        assert_difference 'Issue.count(:conditions => {:category_id => 2})', 3 do
+          delete '/issue_categories/1.xml', {:reassign_to_id => 2}, credentials('jsmith')
+        end
+      end
+      assert_response :ok
+      assert_equal '', @response.body
+      assert_nil IssueCategory.find_by_id(1)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/65/65ef890cea4ede6b19d9b1202dd3caee109782b0.svn-base
--- a/.svn/pristine/65/65ef890cea4ede6b19d9b1202dd3caee109782b0.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-<%= l(:text_issue_updated, :id => "##{@issue.id}", :author => h(@journal.user)) %>
-
-<ul>
-<% for detail in @journal.details %>
-    <li><%= show_detail(detail, true) %></li>
-<% end %>
-</ul>
-
-<%= textilizable(@journal, :notes, :only_path => false) %>
-<hr />
-<%= render :partial => "issue.html.erb", :locals => { :issue => @issue, :issue_url => @issue_url } %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/66/66131eee4b40e2c9d9cbb2ef1cd7414a3df88d2c.svn-base
--- a/.svn/pristine/66/66131eee4b40e2c9d9cbb2ef1cd7414a3df88d2c.svn-base
+++ /dev/null
@@ -1,36 +0,0 @@
-module Engines
-  module Assets    
-    class << self      
-      @@readme = %{Files in this directory are automatically generated from your plugins.
-They are copied from the 'assets' directories of each plugin into this directory
-each time Rails starts (script/server, script/console... and so on).
-Any edits you make will NOT persist across the next server restart; instead you
-should edit the files within the <plugin_name>/assets/ directory itself.}     
-       
-      # Ensure that the plugin asset subdirectory of RAILS_ROOT/public exists, and
-      # that we've added a little warning message to instruct developers not to mess with
-      # the files inside, since they're automatically generated.
-      def initialize_base_public_directory
-        dir = Engines.public_directory
-        unless File.exist?(dir)
-          FileUtils.mkdir_p(dir)
-        end
-        readme = File.join(dir, "README")        
-        File.open(readme, 'w') { |f| f.puts @@readme } unless File.exist?(readme)
-      end
-    
-      # Replicates the subdirectories under the plugins's +assets+ (or +public+) 
-      # directory into the corresponding public directory. See also 
-      # Plugin#public_directory for more.
-      def mirror_files_for(plugin)
-        return if plugin.public_directory.nil?
-        begin 
-          Engines.mirror_files_from(plugin.public_directory, File.join(Engines.public_directory, plugin.name))      
-        rescue Exception => e
-          Engines.logger.warn "WARNING: Couldn't create the public file structure for plugin '#{plugin.name}'; Error follows:"
-          Engines.logger.warn e
-        end
-      end
-    end 
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/66/662e86180d02fd07ea0b83b2c6615af46feab399.svn-base
--- /dev/null
+++ b/.svn/pristine/66/662e86180d02fd07ea0b83b2c6615af46feab399.svn-base
@@ -0,0 +1,105 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueStatus < ActiveRecord::Base
+  before_destroy :check_integrity
+  has_many :workflows, :class_name => 'WorkflowTransition', :foreign_key => "old_status_id"
+  acts_as_list
+
+  before_destroy :delete_workflow_rules
+  after_save     :update_default
+
+  validates_presence_of :name
+  validates_uniqueness_of :name
+  validates_length_of :name, :maximum => 30
+  validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true
+
+  scope :sorted, lambda { order("#{table_name}.position ASC") }
+  scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
+
+  def update_default
+    IssueStatus.update_all({:is_default => false}, ['id <> ?', id]) if self.is_default?
+  end
+
+  # Returns the default status for new issues
+  def self.default
+    where(:is_default => true).first
+  end
+
+  # Update all the +Issues+ setting their done_ratio to the value of their +IssueStatus+
+  def self.update_issue_done_ratios
+    if Issue.use_status_for_done_ratio?
+      IssueStatus.where("default_done_ratio >= 0").all.each do |status|
+        Issue.update_all({:done_ratio => status.default_done_ratio}, {:status_id => status.id})
+      end
+    end
+
+    return Issue.use_status_for_done_ratio?
+  end
+
+  # Returns an array of all statuses the given role can switch to
+  # Uses association cache when called more than one time
+  def new_statuses_allowed_to(roles, tracker, author=false, assignee=false)
+    if roles && tracker
+      role_ids = roles.collect(&:id)
+      transitions = workflows.select do |w|
+        role_ids.include?(w.role_id) &&
+        w.tracker_id == tracker.id &&
+        ((!w.author && !w.assignee) || (author && w.author) || (assignee && w.assignee))
+      end
+      transitions.map(&:new_status).compact.sort
+    else
+      []
+    end
+  end
+
+  # Same thing as above but uses a database query
+  # More efficient than the previous method if called just once
+  def find_new_statuses_allowed_to(roles, tracker, author=false, assignee=false)
+    if roles.present? && tracker
+      conditions = "(author = :false AND assignee = :false)"
+      conditions << " OR author = :true" if author
+      conditions << " OR assignee = :true" if assignee
+
+      workflows.
+        includes(:new_status).
+        where(["role_id IN (:role_ids) AND tracker_id = :tracker_id AND (#{conditions})",
+          {:role_ids => roles.collect(&:id), :tracker_id => tracker.id, :true => true, :false => false}
+          ]).all.
+        map(&:new_status).compact.sort
+    else
+      []
+    end
+  end
+
+  def <=>(status)
+    position <=> status.position
+  end
+
+  def to_s; name end
+
+  private
+
+  def check_integrity
+    raise "Can't delete status" if Issue.where(:status_id => id).any?
+  end
+
+  # Deletes associated workflows
+  def delete_workflow_rules
+    WorkflowRule.delete_all(["old_status_id = :id OR new_status_id = :id", {:id => id}])
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/66/665335962ecb9e0672e62f281339799d0339e4f1.svn-base
--- a/.svn/pristine/66/665335962ecb9e0672e62f281339799d0339e4f1.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/plugin'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/66/66aa08562a330b659bb4aa3903977c6e536a5787.svn-base
--- a/.svn/pristine/66/66aa08562a330b659bb4aa3903977c6e536a5787.svn-base
+++ /dev/null
@@ -1,52 +0,0 @@
-#context-menu { position: absolute; z-index: 40; font-size: 0.9em;}
-
-#context-menu ul, #context-menu li, #context-menu a {
-    display:block;
-    margin:0;
-    padding:0;
-    border:0;
-}
-
-#context-menu ul {
-    width:150px;
-    border-top:1px solid #ddd;
-    border-left:1px solid #ddd;
-    border-bottom:1px solid #777;
-    border-right:1px solid #777;
-    background:white;
-    list-style:none;
-}
-
-#context-menu li {
-    position:relative;
-    padding:1px;
-    z-index:39;
-    border:1px solid white;
-}
-#context-menu li.folder ul { position:absolute; left:168px; /* IE6 */ top:-2px; max-height:300px; overflow:hidden; overflow-y: auto; }
-#context-menu li.folder>ul { left:148px; }
-
-#context-menu.reverse-y li.folder>ul { top:auto; bottom:0; }
-#context-menu.reverse-x li.folder ul { left:auto; right:168px; /* IE6 */ }
-#context-menu.reverse-x li.folder>ul { right:148px; }
-
-#context-menu a {
-    text-decoration:none !important;
-    background-repeat: no-repeat;
-    background-position: 1px 50%;
-    padding: 1px 0px 1px 20px;
-    width:100%; /* IE */
-}
-#context-menu li>a { width:auto; } /* others */
-#context-menu a.disabled, #context-menu a.disabled:hover {color: #ccc;}
-#context-menu li a.submenu { background:url("../images/bullet_arrow_right.png") right no-repeat; }
-#context-menu li:hover { border:1px solid gray; background-color:#eee; }
-#context-menu a:hover {color:#2A5685;}
-#context-menu li.folder:hover { z-index:40; }
-#context-menu ul ul, #context-menu  li:hover ul ul { display:none; }
-#context-menu li:hover ul, #context-menu li:hover li:hover ul { display:block; }
-
-/* selected element */
-.context-menu-selection { background-color:#507AAA !important; color:#f8f8f8 !important; }
-.context-menu-selection a, .context-menu-selection a:hover { color:#f8f8f8 !important; }
-.context-menu-selection:hover { background-color:#507AAA !important; color:#f8f8f8  !important; }
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/66/66ab27fbec26a34302ffce7f06e525b4e0ebdfde.svn-base
--- /dev/null
+++ b/.svn/pristine/66/66ab27fbec26a34302ffce7f06e525b4e0ebdfde.svn-base
@@ -0,0 +1,15 @@
+class AddCustomFieldsPosition < ActiveRecord::Migration
+  def self.up
+    add_column(:custom_fields, :position, :integer, :default => 1)
+    CustomField.all.group_by(&:type).each  do |t, fields|
+      fields.each_with_index do |field, i|
+        # do not call model callbacks
+        CustomField.update_all "position = #{i+1}", {:id => field.id}
+      end
+    end
+  end
+
+  def self.down
+    remove_column :custom_fields, :position
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/66/66ab50d76f6f50210c09955e4a16c4d364df47ff.svn-base
--- a/.svn/pristine/66/66ab50d76f6f50210c09955e4a16c4d364df47ff.svn-base
+++ /dev/null
@@ -1,111 +0,0 @@
-module CodeRay
-module Encoders
-  
-  load :filter
-  
-  # A Filter that selects tokens based on their token kind.
-  # 
-  # == Options
-  # 
-  # === :exclude
-  # 
-  # One or many symbols (in an Array) which shall be excluded.
-  # 
-  # Default: []
-  # 
-  # === :include
-  # 
-  # One or many symbols (in an array) which shall be included.
-  # 
-  # Default: :all, which means all tokens are included.
-  # 
-  # Exclusion wins over inclusion.
-  # 
-  # See also: CommentFilter
-  class TokenKindFilter < Filter
-    
-    register_for :token_kind_filter
-    
-    DEFAULT_OPTIONS = {
-      :exclude => [],
-      :include => :all
-    }
-    
-  protected
-    def setup options
-      super
-      
-      @group_excluded = false
-      @exclude = options[:exclude]
-      @exclude = Array(@exclude) unless @exclude == :all
-      @include = options[:include]
-      @include = Array(@include) unless @include == :all
-    end
-    
-    def include_text_token? text, kind
-      include_group? kind
-    end
-    
-    def include_group? kind
-       (@include == :all || @include.include?(kind)) &&
-      !(@exclude == :all || @exclude.include?(kind))
-    end
-    
-  public
-    
-    # Add the token to the output stream if +kind+ matches the conditions.
-    def text_token text, kind
-      super if !@group_excluded && include_text_token?(text, kind)
-    end
-    
-    # Add the token group to the output stream if +kind+ matches the
-    # conditions.
-    # 
-    # If it does not, all tokens inside the group are excluded from the
-    # stream, even if their kinds match.
-    def begin_group kind
-      if @group_excluded
-        @group_excluded += 1
-      elsif include_group? kind
-        super
-      else
-        @group_excluded = 1
-      end
-    end
-    
-    # See +begin_group+.
-    def begin_line kind
-      if @group_excluded
-        @group_excluded += 1
-      elsif include_group? kind
-        super
-      else
-        @group_excluded = 1
-      end
-    end
-    
-    # Take care of re-enabling the delegation of tokens to the output stream
-    # if an exluded group has ended.
-    def end_group kind
-      if @group_excluded
-        @group_excluded -= 1
-        @group_excluded = false if @group_excluded.zero?
-      else
-        super
-      end
-    end
-    
-    # See +end_group+.
-    def end_line kind
-      if @group_excluded
-        @group_excluded -= 1
-        @group_excluded = false if @group_excluded.zero?
-      else
-        super
-      end
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/66/66dfb65ecc4431408ec461d6daa3720b2fb4b2a0.svn-base
--- a/.svn/pristine/66/66dfb65ecc4431408ec461d6daa3720b2fb4b2a0.svn-base
+++ /dev/null
@@ -1,1008 +0,0 @@
-ar:
-  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
-  direction: rtl
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%m/%d/%Y"
-      short: "%b %d"
-      long: "%B %d, %Y"
-
-    day_names: [Ø§Ù„Ø§Ø­Ø¯, Ø§Ù„Ø§Ø«Ù†ÙŠÙ†, Ø§Ù„Ø«Ù„Ø§Ø«Ø§Ø¡, Ø§Ù„Ø§Ø±Ø¨Ø¹Ø§Ø¡, Ø§Ù„Ø®Ù…ÙŠØ³, Ø§Ù„Ø¬Ù…Ø¹Ø©, Ø§Ù„Ø³Ø¨Øª]
-    abbr_day_names: [Ø£Ø­, Ø§Ø«, Ø«, Ø§Ø±, Ø®, Ø¬, Ø³]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ, Ø´Ø¨Ø§Ø·, Ø¢Ø°Ø§Ø±, Ù†ÙŠØ³Ø§Ù†, Ø£ÙŠØ§Ø±, Ø­Ø²ÙŠØ±Ø§Ù†, ØªÙ…ÙˆØ², Ø¢Ø¨, Ø£ÙŠÙ„ÙˆÙ„, ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø£ÙˆÙ„, ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ, ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø£ÙˆÙ„]
-    abbr_month_names: [~, ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ, Ø´Ø¨Ø§Ø·, Ø¢Ø°Ø§Ø±, Ù†ÙŠØ³Ø§Ù†, Ø£ÙŠØ§Ø±, Ø­Ø²ÙŠØ±Ø§Ù†, ØªÙ…ÙˆØ², Ø¢Ø¨, Ø£ÙŠÙ„ÙˆÙ„, ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø£ÙˆÙ„, ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ, ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø£ÙˆÙ„]
-    # Used in date_select and datime_select.
-    order:
-      - :Ø§Ù„Ø³Ù†Ø©
-      - :Ø§Ù„Ø´Ù‡Ø±
-      - :Ø§Ù„ÙŠÙˆÙ…
-
-  time:
-    formats:
-      default: "%m/%d/%Y %I:%M %p"
-      time: "%I:%M %p"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "ØµØ¨Ø§Ø­Ø§"
-    pm: "Ù…Ø³Ø§Ø¡Ø§"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "Ù†ØµÙ Ø¯Ù‚ÙŠÙ‚Ø©"
-      less_than_x_seconds:
-        one:   "Ø£Ù‚Ù„ Ù…Ù† Ø«Ø§Ù†ÙŠØ©"
-        other: "Ø«ÙˆØ§Ù†ÙŠ %{count}Ø£Ù‚Ù„ Ù…Ù† "
-      x_seconds:
-        one:   "Ø«Ø§Ù†ÙŠØ©"
-        other: "%{count}Ø«ÙˆØ§Ù†ÙŠ "
-      less_than_x_minutes:
-        one:   "Ø£Ù‚Ù„ Ù…Ù† Ø¯Ù‚ÙŠÙ‚Ø©"
-        other: "Ø¯Ù‚Ø§Ø¦Ù‚%{count}Ø£Ù‚Ù„ Ù…Ù† "
-      x_minutes:
-        one:   "Ø¯Ù‚ÙŠÙ‚Ø©"
-        other: "%{count} Ø¯Ù‚Ø§Ø¦Ù‚"
-      about_x_hours:
-        one:   "Ø­ÙˆØ§Ù„ÙŠ Ø³Ø§Ø¹Ø©"
-        other: "Ø³Ø§Ø¹Ø§Øª %{count}Ø­ÙˆØ§Ù„ÙŠ "
-      x_days:
-        one:   "ÙŠÙˆÙ…"
-        other: "%{count} Ø£ÙŠØ§Ù…"
-      about_x_months:
-        one:   "Ø­ÙˆØ§Ù„ÙŠ Ø´Ù‡Ø±"
-        other: "Ø£Ø´Ù‡Ø±  %{count} Ø­ÙˆØ§Ù„ÙŠ"
-      x_months:
-        one:   "Ø´Ù‡Ø±"
-        other: "%{count} Ø£Ø´Ù‡Ø±"
-      about_x_years:
-        one:   "Ø­ÙˆØ§Ù„ÙŠ Ø³Ù†Ø©"
-        other: "Ø³Ù†ÙˆØ§Øª  %{count}Ø­ÙˆØ§Ù„ÙŠ "
-      over_x_years:
-        one:   "Ø§ÙƒØ«Ø± Ù…Ù† Ø³Ù†Ø©"
-        other: "Ø³Ù†ÙˆØ§Øª  %{count}Ø£ÙƒØ«Ø± Ù…Ù† "
-      almost_x_years:
-        one:   "ØªÙ‚Ø±ÙŠØ¨Ø§ Ø³Ù†Ø©"
-        other: "Ø³Ù†ÙˆØ§Øª %{count} Ù†Ù‚Ø±ÙŠØ¨Ø§"
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "kB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "Ùˆ"
-      skip_last_comma: Ø®Ø·Ø£
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    " %{model} Ø®Ø·Ø£ ÙŠÙ…Ù†Ø¹ ØªØ®Ø²ÙŠÙ†"
-          other:  " %{model} ÙŠÙ…Ù†Ø¹ ØªØ®Ø²ÙŠÙ†%{count}Ø®Ø·Ø£ Ø±Ù‚Ù…  "
-      messages:
-        inclusion: "ØºÙŠØ± Ù…Ø¯Ø±Ø¬Ø© Ø¹Ù„Ù‰ Ø§Ù„Ù‚Ø§Ø¦Ù…Ø©"
-        exclusion: "Ù…Ø­Ø¬ÙˆØ²"
-        invalid: "ØºÙŠØ± ØµØ§Ù„Ø­"
-        confirmation: "ØºÙŠØ± Ù…ØªØ·Ø§Ø¨Ù‚"
-        accepted: "Ù…Ù‚Ø¨ÙˆÙ„Ø©"
-        empty: "Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø§Ù† ØªÙƒÙˆÙ† ÙØ§Ø±ØºØ©"
-        blank: "Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø§Ù† ØªÙƒÙˆÙ† ÙØ§Ø±ØºØ©"
-        too_long: " %{count}Ø·ÙˆÙŠÙ„Ø© Ø¬Ø¯Ø§ØŒ Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù‡Ùˆ )"
-        too_short: " %{count}Ù‚ØµÙŠØ±Ø© Ø¬Ø¯Ø§ØŒ Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¯Ù†Ù‰ Ù‡Ùˆ)"
-        wrong_length: " %{count}Ø®Ø·Ø£ ÙÙŠ Ø§Ù„Ø·ÙˆÙ„ØŒ ÙŠØ¬Ø¨ Ø§Ù† ÙŠÙƒÙˆÙ† )"
-        taken: "Ù„Ù‚Ø¯ Ø§ØªØ®Ø°Øª Ø³Ø§Ø¨Ù‚Ø§"
-        not_a_number: "Ù„ÙŠØ³ Ø±Ù‚Ù…Ø§"
-        not_a_date: "Ù„ÙŠØ³ ØªØ§Ø±ÙŠØ®Ø§ ØµØ§Ù„Ø­Ø§"
-        greater_than: "%{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§ÙƒØ«Ø± Ù…Ù† "
-        greater_than_or_equal_to: "%{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§ÙƒØ«Ø± Ù…Ù† Ø§Ùˆ ØªØ³Ø§ÙˆÙŠ"
-        equal_to: "%{count}ÙŠØ¬Ø¨ Ø§Ù† ØªØ³Ø§ÙˆÙŠ"
-        less_than: " %{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§Ù‚Ù„ Ù…Ù†"
-        less_than_or_equal_to: " %{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§Ù‚Ù„ Ù…Ù† Ø§Ùˆ ØªØ³Ø§ÙˆÙŠ"
-        odd: "must be odd"
-        even: "must be even"
-        greater_than_start_date: "ÙŠØ¬Ø¨ Ø§Ù† ØªÙƒÙˆÙ† Ø§ÙƒØ«Ø± Ù…Ù† ØªØ§Ø±ÙŠØ® Ø§Ù„Ø¨Ø¯Ø§ÙŠØ©"
-        not_same_project: "Ù„Ø§ ÙŠÙ†ØªÙ…ÙŠ Ø§Ù„Ù‰ Ù†ÙØ³ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹"
-        circular_dependency: "Ù‡Ø°Ù‡ Ø§Ù„Ø¹Ù„Ø§Ù‚Ø© Ø³ÙˆÙ ØªØ®Ù„Ù‚ Ø¹Ù„Ø§Ù‚Ø© ØªØ¨Ø¹ÙŠØ© Ø¯Ø§Ø¦Ø±ÙŠØ©"
-        cant_link_an_issue_with_a_descendant: "Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø§Ù† ØªÙƒÙˆÙ† Ø§Ù„Ù…Ø´ÙƒÙ„Ø© Ù…Ø±ØªØ¨Ø·Ø© Ø¨ÙˆØ§Ø­Ø¯Ø© Ù…Ù† Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ÙØ±Ø¹ÙŠØ©"
-
-  actionview_instancetag_blank_option: Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ø¯ÙŠØ¯
-
-  general_text_No: 'Ù„Ø§'
-  general_text_Yes: 'Ù†Ø¹Ù…'
-  general_text_no: 'Ù„Ø§'
-  general_text_yes: 'Ù†Ø¹Ù…'
-  general_lang_name: 'Arabic (Ø¹Ø±Ø¨ÙŠ)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '7'
-
-  notice_account_updated: Ù„Ù‚Ø¯ ØªÙ… ØªØ¬Ø¯ÙŠØ¯ Ø§Ù„Ø­Ø³Ø§Ø¨ Ø¨Ù†Ø¬Ø§Ø­.
-  notice_account_invalid_creditentials: Ø§Ø³Ù… Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… Ø§Ùˆ ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± ØºÙŠØ± ØµØ­ÙŠØ­Ø©
-  notice_account_password_updated: Ù„Ù‚Ø¯ ØªÙ… ØªØ¬Ø¯ÙŠØ¯ ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± Ø¨Ù†Ø¬Ø§Ø­.
-  notice_account_wrong_password: ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± ØºÙŠØ± ØµØ­ÙŠØ­Ø©
-  notice_account_register_done: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù†Ø´Ø§Ø¡ Ø­Ø³Ø§Ø¨Ùƒ Ø¨Ù†Ø¬Ø§Ø­ØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ ØªØ£ÙƒÙŠØ¯ Ø§Ù„Ø·Ù„Ø¨ Ù…Ù† Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  notice_account_unknown_email: Ù…Ø³ØªØ®Ø¯Ù… ØºÙŠØ± Ù…Ø¹Ø±ÙˆÙ.
-  notice_can_t_change_password: Ù‡Ø°Ø§ Ø§Ù„Ø­Ø³Ø§Ø¨ ÙŠØ³ØªØ®Ø¯Ù… Ø¬Ù‡Ø§Ø² Ø®Ø§Ø±Ø¬ÙŠ ØºÙŠØ± Ù…ØµØ±Ø­ Ø¨Ù‡ Ù„Ø§ ÙŠÙ…ÙƒÙ† ØªØºÙŠØ± ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
-  notice_account_lost_email_sent: Ù„Ù‚Ø¯ ØªÙ… Ø§Ø±Ø³Ø§Ù„ Ø±Ø³Ø§Ù„Ø© Ø¹Ù„Ù‰ Ø¨Ø±ÙŠØ¯Ùƒ Ø¨Ø§Ù„ØªØ¹Ù„ÙŠÙ…Ø§Øª Ø§Ù„Ù„Ø§Ø²Ù…Ø© Ù„ØªØºÙŠØ± ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
-  notice_account_activated: Ù„Ù‚Ø¯ ØªÙ… ØªÙØ¹ÙŠÙ„ Ø­Ø³Ø§Ø¨ÙƒØŒ ÙŠÙ…ÙƒÙ†Ùƒ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„Ø§Ù†
-  notice_successful_create: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù„Ø§Ù†Ø´Ø§Ø¡ Ø¨Ù†Ø¬Ø§Ø­
-  notice_successful_update: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù„ØªØ­Ø¯ÙŠØ« Ø¨Ù†Ø¬Ø§Ø­
-  notice_successful_delete: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù„Ø­Ø°Ù Ø¨Ù†Ø¬Ø§Ø­
-  notice_successful_connection: Ù„Ù‚Ø¯ ØªÙ… Ø§Ù„Ø±Ø¨Ø· Ø¨Ù†Ø¬Ø§Ø­
-  notice_file_not_found: Ø§Ù„ØµÙØ­Ø© Ø§Ù„ØªÙŠ ØªØ­Ø§ÙˆÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„ÙŠÙ‡Ø§ ØºÙŠØ± Ù…ÙˆØ¬ÙˆØ¯Ù‡ Ø§Ùˆ ØªÙ… Ø­Ø°ÙÙ‡Ø§
-  notice_locking_conflict: ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ø¨ÙŠØ§Ù†Ø§Øª Ø¹Ù† Ø·Ø±ÙŠÙ‚ Ù…Ø³ØªØ®Ø¯Ù… Ø¢Ø®Ø±.
-  notice_not_authorized: ØºÙŠØ± Ù…ØµØ±Ø­ Ù„Ùƒ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„Ù‰ Ù‡Ø°Ù‡ Ø§Ù„Ù…Ù†Ø·Ù‚Ø©.
-  notice_not_authorized_archived_project: Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ Ø§Ù„Ø°ÙŠ ØªØ­Ø§ÙˆÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„ÙŠÙ‡ ØªÙ… Ø§Ø±Ø´ÙØªÙ‡
-  notice_email_sent: "%{value}ØªÙ… Ø§Ø±Ø³Ø§Ù„ Ø±Ø³Ø§Ù„Ø© Ø§Ù„Ù‰ "
-  notice_email_error: " (%{value})Ù„Ù‚Ø¯ Ø­Ø¯Ø« Ø®Ø·Ø£ Ù…Ø§ Ø§Ø«Ù†Ø§Ø¡ Ø§Ø±Ø³Ø§Ù„ Ø§Ù„Ø±Ø³Ø§Ù„Ø© Ø§Ù„Ù‰ "
-  notice_feeds_access_key_reseted: ÙƒÙ„Ù…Ø© Ø§Ù„Ø¯Ø®ÙˆÙ„  RSSÙ„Ù‚Ø¯ ØªÙ… ØªØ¹Ø¯ÙŠÙ„ .
-  notice_api_access_key_reseted:  ÙƒÙ„Ù…Ø© Ø§Ù„Ø¯Ø®ÙˆÙ„APIÙ„Ù‚Ø¯ ØªÙ… ØªØ¹Ø¯ÙŠÙ„ .
-  notice_failed_to_save_issues: "ÙØ´Ù„ ÙÙŠ Ø­ÙØ¸ Ø§Ù„Ù…Ù„Ù"
-  notice_failed_to_save_members: "ÙØ´Ù„ ÙÙŠ Ø­ÙØ¸ Ø§Ù„Ø§Ø¹Ø¶Ø§Ø¡: %{errors}."
-  notice_no_issue_selected: "Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ¯ Ø´ÙŠØ¡ØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ ØªØ­Ø¯ÙŠØ¯ Ø§Ù„Ù…Ø³Ø£Ù„Ø© Ø§Ù„ØªÙŠ ØªØ±ÙŠØ¯"
-  notice_account_pending: "Ù„Ù‚Ø¯ ØªÙ… Ø§Ù†Ø´Ø§Ø¡ Ø­Ø³Ø§Ø¨ÙƒØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„Ø§Ù†ØªØ¸Ø§Ø± Ø­ØªÙ‰ ØªØªÙ… Ø§Ù„Ù…ÙˆØ§ÙÙ‚Ø©"
-  notice_default_data_loaded: ØªÙ… ØªØ­Ù…ÙŠÙ„ Ø§Ù„ØªÙƒÙˆÙŠÙ† Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ Ø¨Ù†Ø¬Ø§Ø­
-  notice_unable_delete_version: ØºÙŠØ± Ù‚Ø§Ø¯Ø± Ø¹Ù„Ù‰ Ù…Ø³Ø­ Ø§Ù„Ù†Ø³Ø®Ø©.
-  notice_unable_delete_time_entry: ØºÙŠØ± Ù‚Ø§Ø¯Ø± Ø¹Ù„Ù‰ Ù…Ø³Ø­ ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„.
-  notice_issue_done_ratios_updated: Ù„Ù‚Ø¯ ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ù†Ø³Ø¨.
-  notice_gantt_chart_truncated: " (%{max})Ù„Ù‚Ø¯ ØªÙ… Ø§Ù‚ØªØ·Ø§Ø¹ Ø§Ù„Ø±Ø³Ù… Ø§Ù„Ø¨ÙŠØ§Ù†ÙŠ Ù„Ø§Ù†Ù‡ ØªØ¬Ø§ÙˆØ² Ø§Ù„Ø§Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„Ø¹Ù†Ø§ØµØ± Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¹Ø±Ø¶Ù‡Ø§ "
-  notice_issue_successful_create: "%{id}Ù„Ù‚Ø¯ ØªÙ… Ø§Ù†Ø´Ø§Ø¡ "
-
-
-  error_can_t_load_default_data: "Ù„Ù… ÙŠØªÙ… ØªØ­Ù…ÙŠÙ„ Ø§Ù„ØªÙƒÙˆÙŠÙ† Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ ÙƒØ§Ù…Ù„Ø§ %{value}"
-  error_scm_not_found: "Ù„Ù… ÙŠØªÙ… Ø§Ù„Ø¹Ø«ÙˆØ± Ø¹Ù„Ù‰ Ø§Ø¯Ø®Ø§Ù„ ÙÙŠ Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹"
-  error_scm_command_failed: "Ø­Ø¯Ø« Ø®Ø·Ø£ Ø¹Ù†Ø¯ Ù…Ø­Ø§ÙˆÙ„Ø© Ø§Ù„ÙˆØµÙˆÙ„ Ø§Ù„Ù‰ Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹: %{value}"
-  error_scm_annotate: "Ø§Ù„Ø§Ø¯Ø®Ø§Ù„ ØºÙŠØ± Ù…ÙˆØ¬ÙˆØ¯."
-  error_scm_annotate_big_text_file: "Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø­ÙØ¸ Ø§Ù„Ø§Ø¯Ø®Ø§Ù„ Ù„Ø§Ù†Ù‡ ØªØ¬Ø§ÙˆØ² Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø­Ø¬Ù… Ø§Ù„Ù…Ù„Ù."
-  error_issue_not_found_in_project: 'Ù„Ù… ÙŠØªÙ… Ø§Ù„Ø¹Ø«ÙˆØ± Ø¹Ù„Ù‰ Ø§Ù„Ù…Ø®Ø±Ø¬ Ø§Ùˆ Ø§Ù†Ù‡ ÙŠÙ†ØªÙ…ÙŠ Ø§Ù„Ù‰ Ù…Ø´Ø±ÙˆØ¹ Ø§Ø®Ø±'
-  error_no_tracker_in_project: 'Ù„Ø§ ÙŠÙˆØ¬Ø¯ Ù…ØªØªØ¨Ø¹ Ù„Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ù‚Ù‚ Ù…Ù† Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„Ù…Ø´Ø±ÙˆØ¹. '
-  error_no_default_issue_status: 'Ù„Ù… ÙŠØªÙ… Ø§Ù„ØªØ¹Ø±Ù Ø¹Ù„Ù‰ Ø§ÙŠ ÙˆØ¶Ø¹ Ø§ÙØªØ±Ø§Ø¶ÙŠØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ù‚Ù‚ Ù…Ù† Ø§Ù„ØªÙƒÙˆÙŠÙ† Ø§Ù„Ø®Ø§Øµ Ø¨Ùƒ (Ø§Ø°Ù‡Ø¨ Ø§Ù„Ù‰ Ø¥Ø¯Ø§Ø±Ø©-Ø¥ØµØ¯Ø§Ø± Ø§Ù„Ø­Ø§Ù„Ø§Øª)'
-  error_can_not_delete_custom_field: ØºÙŠØ± Ù‚Ø§Ø¯Ø± Ø¹Ù„Ù‰ Ø­Ø°Ù Ø§Ù„Ø­Ù‚Ù„ Ø§Ù„Ù…Ø¸Ù„Ù„
-  error_can_not_delete_tracker: "Ù‡Ø°Ø§ Ø§Ù„Ù…ØªØªØ¨Ø¹ ÙŠØ­ØªÙˆÙŠ Ø¹Ù„Ù‰ Ù…Ø³Ø§Ø¦Ù„ Ù†Ø´Ø·Ø© ÙˆÙ„Ø§ ÙŠÙ…ÙƒÙ† Ø­Ø°ÙÙ‡"
-  error_can_not_remove_role: "Ù‡Ø°Ø§ Ø§Ù„Ø¯ÙˆØ± Ù‚ÙŠØ¯ Ø§Ù„Ø§Ø³ØªØ®Ø¯Ø§Ù…ØŒ Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø­Ø°ÙÙ‡"
-  error_can_not_reopen_issue_on_closed_version: 'Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø¥Ø¹Ø§Ø¯Ø© ÙØªØ­ Ù‚Ø¶ÙŠØ© Ù…Ø¹ÙŠÙ†Ù‡ Ù„Ø§ØµØ¯Ø§Ø± Ù…Ù‚ÙÙ„'
-  error_can_not_archive_project: Ù„Ø§ ÙŠÙ…ÙƒÙ† Ø§Ø±Ø´ÙØ© Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
-  error_issue_done_ratios_not_updated: "Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ù†Ø³Ø¨"
-  error_workflow_copy_source: 'Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ø®ØªÙŠØ§Ø± Ø§Ù„Ù…ØªØªØ¨Ø¹ Ø§Ùˆ Ø§Ù„Ø§Ø¯ÙˆØ§Ø±'
-  error_workflow_copy_target: 'Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ø®ØªÙŠØ§Ø± Ù‡Ø¯Ù Ø§Ù„Ù…ØªØªØ¨Ø¹ Ø§Ùˆ Ù‡Ø¯Ù Ø§Ù„Ø§Ø¯ÙˆØ§Ø±'
-  error_unable_delete_issue_status: 'ØºÙŠØ± Ù‚Ø§Ø¯Ø± Ø¹Ù„Ù‰ Ø­Ø°Ù Ø­Ø§Ù„Ø© Ø§Ù„Ù‚Ø¶ÙŠØ©'
-  error_unable_to_connect: "ØªØ¹Ø°Ø± Ø§Ù„Ø§ØªØµØ§Ù„(%{value})"
-  error_attachment_too_big: " (%{max_size})Ù„Ø§ ÙŠÙ…ÙƒÙ† ØªØ­Ù…ÙŠÙ„ Ù‡Ø°Ø§ Ø§Ù„Ù…Ù„ÙØŒ Ù„Ù‚Ø¯ ØªØ¬Ø§ÙˆØ² Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¨Ù‡ "
-  warning_attachments_not_saved: "%{count}ØªØ¹Ø°Ø± Ø­ÙØ¸ Ø§Ù„Ù…Ù„Ù"
-
-  mail_subject_lost_password: " %{value}ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± Ø§Ù„Ø®Ø§ØµØ© Ø¨Ùƒ "
-  mail_body_lost_password: 'Ù„ØªØºÙŠØ± ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±ØŒ Ø§Ù†Ù‚Ø± Ø¹Ù„Ù‰ Ø§Ù„Ø±ÙˆØ§Ø¨Ø· Ø§Ù„ØªØ§Ù„ÙŠØ©:'
-  mail_subject_register: " %{value}ØªÙØ¹ÙŠÙ„ Ø­Ø³Ø§Ø¨Ùƒ "
-  mail_body_register: 'Ù„ØªÙØ¹ÙŠÙ„ Ø­Ø³Ø§Ø¨ÙƒØŒ Ø§Ù†Ù‚Ø± Ø¹Ù„Ù‰ Ø§Ù„Ø±ÙˆØ§Ø¨Ø· Ø§Ù„ØªØ§Ù„ÙŠØ©:'
-  mail_body_account_information_external: " %{value}Ø§ØµØ¨Ø­ Ø¨Ø§Ù…ÙƒØ§Ù†Ùƒ Ø§Ø³ØªØ®Ø¯Ø§Ù… Ø­Ø³Ø§Ø¨Ùƒ Ù„Ù„Ø¯Ø®ÙˆÙ„"
-  mail_body_account_information: Ù…Ø¹Ù„ÙˆÙ…Ø§Øª Ø­Ø³Ø§Ø¨Ùƒ
-  mail_subject_account_activation_request: "%{value}Ø·Ù„Ø¨ ØªÙØ¹ÙŠÙ„ Ø§Ù„Ø­Ø³Ø§Ø¨ "
-  mail_body_account_activation_request: " (%{value})ØªÙ… ØªØ³Ø¬ÙŠÙ„ Ø­Ø³Ø§Ø¨ Ø¬Ø¯ÙŠØ¯ØŒ Ø¨Ø§Ù†ØªØ¸Ø§Ø± Ø§Ù„Ù…ÙˆØ§ÙÙ‚Ø©:"
-  mail_subject_reminder: "%{count}ØªÙ… ØªØ£Ø¬ÙŠÙ„ Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ØªØ§Ù„ÙŠØ©  "
-  mail_body_reminder: "%{count}ÙŠØ¬Ø¨ Ø§Ù† ØªÙ‚ÙˆÙ… Ø¨ØªØ³Ù„ÙŠÙ… Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ØªØ§Ù„ÙŠØ© :"
-  mail_subject_wiki_content_added: "'%{id}' ØªÙ… Ø§Ø¶Ø§ÙØ© ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ"
-  mail_body_wiki_content_added: "The '%{id}' ØªÙ… Ø§Ø¶Ø§ÙØ© ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ Ù…Ù† Ù‚Ø¨Ù„ %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' ØªÙ… ØªØ­Ø¯ÙŠØ« ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ"
-  mail_body_wiki_content_updated: "The '%{id}'ØªÙ… ØªØ­Ø¯ÙŠØ« ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ Ù…Ù† Ù‚Ø¨Ù„ %{author}."
-
-  gui_validation_error: Ø®Ø·Ø£
-  gui_validation_error_plural: "%{count}Ø£Ø®Ø·Ø§Ø¡"
-
-  field_name: Ø§Ù„Ø§Ø³Ù…
-  field_description: Ø§Ù„ÙˆØµÙ
-  field_summary: Ø§Ù„Ù…Ù„Ø®Øµ
-  field_is_required: Ù…Ø·Ù„ÙˆØ¨
-  field_firstname: Ø§Ù„Ø§Ø³Ù… Ø§Ù„Ø§ÙˆÙ„
-  field_lastname: Ø§Ù„Ø§Ø³Ù… Ø§Ù„Ø§Ø®ÙŠØ±
-  field_mail: Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  field_filename: Ø§Ø³Ù… Ø§Ù„Ù…Ù„Ù
-  field_filesize: Ø­Ø¬Ù… Ø§Ù„Ù…Ù„Ù
-  field_downloads: Ø§Ù„ØªÙ†Ø²ÙŠÙ„
-  field_author: Ø§Ù„Ù…Ø¤Ù„Ù
-  field_created_on: ØªÙ… Ø§Ù„Ø§Ù†Ø´Ø§Ø¡ ÙÙŠ
-  field_updated_on: ØªÙ… Ø§Ù„ØªØ­Ø¯ÙŠØ«
-  field_field_format: ØªÙ†Ø³ÙŠÙ‚ Ø§Ù„Ø­Ù‚Ù„
-  field_is_for_all: Ù„ÙƒÙ„ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹Ø§Øª
-  field_possible_values: Ù‚ÙŠÙ… Ù…Ø­ØªÙ…Ù„Ø©
-  field_regexp: Ø§Ù„ØªØ¹Ø¨ÙŠØ± Ø§Ù„Ø¹Ø§Ø¯ÙŠ
-  field_min_length: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¯Ù†Ù‰ Ù„Ù„Ø·ÙˆÙ„
-  field_max_length: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¹Ù„Ù‰ Ù„Ù„Ø·ÙˆÙ„
-  field_value: Ø§Ù„Ù‚ÙŠÙ…Ø©
-  field_category: Ø§Ù„ÙØ¦Ø©
-  field_title: Ø§Ù„Ø¹Ù†ÙˆØ§Ù†
-  field_project: Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
-  field_issue: Ø§Ù„Ù‚Ø¶ÙŠØ©
-  field_status: Ø§Ù„Ø­Ø§Ù„Ø©
-  field_notes: Ù…Ù„Ø§Ø­Ø¸Ø§Øª
-  field_is_closed: Ø§Ù„Ù‚Ø¶ÙŠØ© Ù…ØºÙ„Ù‚Ø©
-  field_is_default: Ø§Ù„Ù‚ÙŠÙ…Ø© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
-  field_tracker: Ø§Ù„Ù…ØªØªØ¨Ø¹
-  field_subject: Ø§Ù„Ù…ÙˆØ¶ÙˆØ¹
-  field_due_date: ØªØ§Ø±ÙŠØ® Ø§Ù„Ø§Ø³ØªØ­Ù‚Ø§Ù‚
-  field_assigned_to: Ø§Ù„Ù…Ø­Ø§Ù„ Ø§Ù„ÙŠÙ‡
-  field_priority: Ø§Ù„Ø£ÙˆÙ„ÙˆÙŠØ©
-  field_fixed_version: Ø§Ù„Ø§ØµØ¯Ø§Ø± Ø§Ù„Ù…Ø³ØªÙ‡Ø¯Ù
-  field_user: Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
-  field_principal: Ø§Ù„Ø±Ø¦ÙŠØ³ÙŠ
-  field_role: Ø¯ÙˆØ±
-  field_homepage: Ø§Ù„ØµÙØ­Ø© Ø§Ù„Ø±Ø¦ÙŠØ³ÙŠØ©
-  field_is_public: Ø¹Ø§Ù…
-  field_parent: Ù…Ø´Ø±ÙˆØ¹ ÙØ±Ø¹ÙŠ Ù…Ù†
-  field_is_in_roadmap: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© ÙÙŠ Ø®Ø§Ø±Ø·Ø© Ø§Ù„Ø·Ø±ÙŠÙ‚
-  field_login: ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„
-  field_mail_notification: Ù…Ù„Ø§Ø­Ø¸Ø§Øª Ø¹Ù„Ù‰ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  field_admin: Ø§Ù„Ù…Ø¯ÙŠØ±
-  field_last_login_on: Ø§Ø®Ø± Ø§ØªØµØ§Ù„
-  field_language: Ù„ØºØ©
-  field_effective_date: ØªØ§Ø±ÙŠØ®
-  field_password: ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
-  field_new_password: ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ± Ø§Ù„Ø¬Ø¯ÙŠØ¯Ø©
-  field_password_confirmation: ØªØ£ÙƒÙŠØ¯
-  field_version: Ø¥ØµØ¯Ø§Ø±
-  field_type: Ù†ÙˆØ¹
-  field_host: Ø§Ù„Ù…Ø¶ÙŠÙ
-  field_port: Ø§Ù„Ù…Ù†ÙØ°
-  field_account: Ø§Ù„Ø­Ø³Ø§Ø¨
-  field_base_dn: DN Ù‚Ø§Ø¹Ø¯Ø©
-  field_attr_login: Ø³Ù…Ø© Ø§Ù„Ø¯Ø®ÙˆÙ„
-  field_attr_firstname: Ø³Ù…Ø© Ø§Ù„Ø§Ø³Ù… Ø§Ù„Ø§ÙˆÙ„
-  field_attr_lastname: Ø³Ù…Ø© Ø§Ù„Ø§Ø³Ù… Ø§Ù„Ø§Ø®ÙŠØ±
-  field_attr_mail: Ø³Ù…Ø© Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  field_onthefly: Ø¥Ù†Ø´Ø§Ø¡ Ø­Ø³Ø§Ø¨ Ù…Ø³ØªØ®Ø¯Ù… Ø¹Ù„Ù‰ ØªØ­Ø±Ùƒ
-  field_start_date: ØªØ§Ø±ÙŠØ® Ø§Ù„Ø¨Ø¯ÙŠØ©
-  field_done_ratio: "% ØªÙ…"
-  field_auth_source: ÙˆØ¶Ø¹ Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
-  field_hide_mail: Ø¥Ø®ÙØ§Ø¡ Ø¨Ø±ÙŠØ¯ÙŠ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  field_comments: ØªØ¹Ù„ÙŠÙ‚
-  field_url: Ø±Ø§Ø¨Ø·
-  field_start_page: ØµÙØ­Ø© Ø§Ù„Ø¨Ø¯Ø§ÙŠØ©
-  field_subproject: Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ Ø§Ù„ÙØ±Ø¹ÙŠ
-  field_hours: Ø³Ø§Ø¹Ø§Øª
-  field_activity: Ø§Ù„Ù†Ø´Ø§Ø·
-  field_spent_on: ØªØ§Ø±ÙŠØ®
-  field_identifier: Ø§Ù„Ù…Ø¹Ø±Ù
-  field_is_filter: Ø§Ø³ØªØ®Ø¯Ù… ÙƒØªØµÙÙŠØ©
-  field_issue_to: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù…ØªØµÙ„Ø©
-  field_delay: ØªØ£Ø®ÙŠØ±
-  field_assignable: ÙŠÙ…ÙƒÙ† Ø§Ù† ØªØ³ØªÙ†Ø¯ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù‰ Ù‡Ø°Ø§ Ø§Ù„Ø¯ÙˆØ±
-  field_redirect_existing_links: Ø¥Ø¹Ø§Ø¯Ø© ØªÙˆØ¬ÙŠÙ‡ Ø§Ù„Ø±ÙˆØ§Ø¨Ø· Ø§Ù„Ù…ÙˆØ¬ÙˆØ¯Ø©
-  field_estimated_hours: Ø§Ù„ÙˆÙ‚Øª Ø§Ù„Ù…ØªÙˆÙ‚Ø¹
-  field_column_names: Ø£Ø¹Ù…Ø¯Ø©
-  field_time_entries: ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„
-  field_time_zone: Ø§Ù„Ù…Ù†Ø·Ù‚Ø© Ø§Ù„Ø²Ù…Ù†ÙŠØ©
-  field_searchable: ÙŠÙ…ÙƒÙ† Ø§Ù„Ø¨Ø­Ø« ÙÙŠÙ‡
-  field_default_value: Ø§Ù„Ù‚ÙŠÙ…Ø© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
-  field_comments_sorting: Ø§Ø¹Ø±Ø¶ Ø§Ù„ØªØ¹Ù„ÙŠÙ‚Ø§Øª
-  field_parent_title: ØµÙØ­Ø© Ø§Ù„ÙˆØ§Ù„Ø¯ÙŠÙ†
-  field_editable: ÙŠÙ…ÙƒÙ† Ø§Ø¹Ø§Ø¯Ø© ØªØ­Ø±ÙŠØ±Ù‡
-  field_watcher: Ù…Ø±Ø§Ù‚Ø¨
-  field_identity_url: Ø§ÙØªØ­ Ø§Ù„Ø±Ø§Ø¨Ø· Ø§Ù„Ø®Ø§Øµ Ø¨Ø§Ù„Ù‡ÙˆÙŠØ© Ø§Ù„Ø´Ø®ØµÙŠØ©
-  field_content: Ø§Ù„Ù…Ø­ØªÙˆÙŠØ§Øª
-  field_group_by: Ù…Ø¬Ù…ÙˆØ¹Ø© Ø§Ù„Ù†ØªØ§Ø¦Ø¬ Ø¹Ù† Ø·Ø±ÙŠÙ‚
-  field_sharing: Ù…Ø´Ø§Ø±ÙƒØ©
-  field_parent_issue: Ù…Ù‡Ù…Ø© Ø§Ù„ÙˆØ§Ù„Ø¯ÙŠÙ†
-  field_member_of_group: "Ù…Ø¬Ù…ÙˆØ¹Ø© Ø§Ù„Ù…Ø­Ø§Ù„"
-  field_assigned_to_role: "Ø¯ÙˆØ± Ø§Ù„Ù…Ø­Ø§Ù„"
-  field_text: Ø­Ù‚Ù„ Ù†ØµÙŠ
-  field_visible: ØºÙŠØ± Ù…Ø±Ø¦ÙŠ
-  field_warn_on_leaving_unsaved: "Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ø°ÙŠØ± Ø¹Ù†Ø¯ Ù…ØºØ§Ø¯Ø±Ø© ØµÙØ­Ø© ÙˆØ§Ù„Ù†Øµ ØºÙŠØ± Ù…Ø­ÙÙˆØ¸"
-  field_issues_visibility: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù…Ø±Ø¦ÙŠØ©
-  field_is_private: Ø®Ø§Øµ
-  field_commit_logs_encoding: Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„ØªØ±Ù…ÙŠØ²
-  field_scm_path_encoding: ØªØ±Ù…ÙŠØ² Ø§Ù„Ù…Ø³Ø§Ø±
-  field_path_to_repository: Ù…Ø³Ø§Ø± Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹
-  field_root_directory: Ø¯Ù„ÙŠÙ„ Ø§Ù„Ø¬Ø°Ø±
-  field_cvsroot: CVSØ¬Ø°Ø±
-  field_cvs_module: ÙˆØ­Ø¯Ø©
-
-  setting_app_title: Ø¹Ù†ÙˆØ§Ù† Ø§Ù„ØªØ·Ø¨ÙŠÙ‚
-  setting_app_subtitle: Ø§Ù„Ø¹Ù†ÙˆØ§Ù† Ø§Ù„ÙØ±Ø¹ÙŠ Ù„Ù„ØªØ·Ø¨ÙŠÙ‚
-  setting_welcome_text: Ù†Øµ Ø§Ù„ØªØ±Ø­ÙŠØ¨
-  setting_default_language: Ø§Ù„Ù„ØºØ© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
-  setting_login_required: Ù…Ø·Ù„ÙˆØ¨ Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
-  setting_self_registration: Ø§Ù„ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø°Ø§ØªÙŠ
-  setting_attachment_max_size: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ù„Ù…Ù„ÙØ§Øª Ø§Ù„Ù…Ø±ÙÙ‚Ø©
-  setting_issues_export_limit: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„ØªØµØ¯ÙŠØ±
-  setting_mail_from: Ø§Ù†Ø¨Ø¹Ø§Ø«Ø§Øª Ø¹Ù†ÙˆØ§Ù† Ø¨Ø±ÙŠØ¯Ùƒ
-  setting_bcc_recipients: Ù…Ø³ØªÙ„Ù…ÙŠÙ† Ø§Ù„Ù†Ø³Ø® Ø§Ù„Ù…Ø®ÙÙŠØ© (bcc)
-  setting_plain_text_mail: Ù†Øµ Ø¹Ø§Ø¯ÙŠ (no HTML)
-  setting_host_name: Ø§Ø³Ù… ÙˆÙ…Ø³Ø§Ø± Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
-  setting_text_formatting: ØªÙ†Ø³ÙŠÙ‚ Ø§Ù„Ù†Øµ
-  setting_wiki_compression: Ø¶ØºØ· ØªØ§Ø±ÙŠØ® Ø§Ù„ÙˆÙŠÙƒÙŠ
-  setting_feeds_limit: Atom feeds Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„Ø¨Ù†ÙˆØ¯ ÙÙŠ
-  setting_default_projects_public: Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„Ø¬Ø¯ÙŠØ¯Ù‡ Ù…ØªØ§Ø­Ø© Ù„Ù„Ø¬Ù…ÙŠØ¹ Ø§ÙØªØ±Ø§Ø¶ÙŠØ§
-  setting_autofetch_changesets: Ø§Ù„Ø¥Ø­Ø¶Ø§Ø± Ø§Ù„ØªÙ„Ù‚Ø§Ø¦ÙŠ
-  setting_sys_api_enabled: Ù…Ù† Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹ WS ØªÙ…ÙƒÙŠÙ†
-  setting_commit_ref_keywords: Ù…Ø±Ø¬Ø¹ÙŠØ© Ø§Ù„ÙƒÙ„Ù…Ø§Øª Ø§Ù„Ù…ÙØªØ§Ø­ÙŠØ©
-  setting_commit_fix_keywords: ØªØµØ­ÙŠØ­ Ø§Ù„ÙƒÙ„Ù…Ø§Øª Ø§Ù„Ù…ÙØªØ§Ø­ÙŠØ©
-  setting_autologin: Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø§Ù„ØªÙ„Ù‚Ø§Ø¦ÙŠ
-  setting_date_format: ØªÙ†Ø³ÙŠÙ‚ Ø§Ù„ØªØ§Ø±ÙŠØ®
-  setting_time_format: ØªÙ†Ø³ÙŠÙ‚ Ø§Ù„ÙˆÙ‚Øª
-  setting_cross_project_issue_relations: Ø§Ù„Ø³Ù…Ø§Ø­ Ø¨Ø§Ø¯Ø§Ø±Ø¬ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ ÙÙŠ Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
-  setting_issue_list_default_columns: Ø§Ù„Ø§Ø¹Ù…Ø¯Ø© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ© Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© ÙÙŠ Ù‚Ø§Ø¦Ù…Ø© Ø§Ù„Ù‚Ø¶ÙŠØ©
-  setting_repositories_encodings: ØªØ±Ù…ÙŠØ² Ø§Ù„Ù…Ø±ÙÙ‚Ø§Øª ÙˆØ§Ù„Ù…Ø³ØªÙˆØ¯Ø¹Ø§Øª
-  setting_emails_header: Ø±Ø£Ø³ Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  setting_emails_footer: Ø°ÙŠÙ„ Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  setting_protocol: Ø¨Ø±ÙˆØªÙˆÙƒÙˆÙ„
-  setting_per_page_options: Ø§Ù„ÙƒØ§Ø¦Ù†Ø§Øª Ù„ÙƒÙ„ Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„ØµÙØ­Ø©
-  setting_user_format: ØªÙ†Ø³ÙŠÙ‚ Ø¹Ø±Ø¶ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
-  setting_activity_days_default: Ø§Ù„Ø§ÙŠØ§Ù… Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© Ø¹Ù„Ù‰ Ù†Ø´Ø§Ø· Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
-  setting_display_subprojects_issues: Ø¹Ø±Ø¶ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„ÙØ±Ø¹ÙŠØ© Ù„Ù„Ù…Ø´Ø§Ø±Ø¹ Ø§Ù„Ø±Ø¦ÙŠØ³ÙŠØ© Ø¨Ø´ÙƒÙ„ Ø§ÙØªØ±Ø§Ø¶ÙŠ
-  setting_enabled_scm: SCM ØªÙ…ÙƒÙŠÙ†
-  setting_mail_handler_body_delimiters: "Ø§Ù‚ØªØ·Ø§Ø¹ Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ Ø¨Ø¹Ø¯ Ù‡Ø°Ù‡ Ø§Ù„Ø®Ø·ÙˆØ·"
-  setting_mail_handler_api_enabled: Ù„Ù„Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„ÙˆØ§Ø±Ø¯Ø©WS ØªÙ…ÙƒÙŠÙ†
-  setting_mail_handler_api_key: API Ù…ÙØªØ§Ø­
-  setting_sequential_project_identifiers: Ø§Ù†Ø´Ø§Ø¡ Ù…Ø¹Ø±ÙØ§Øª Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ Ø§Ù„Ù…ØªØ³Ù„Ø³Ù„Ø©
-  setting_gravatar_enabled: ÙƒØ£ÙŠÙ‚ÙˆÙ†Ø© Ù…Ø³ØªØ®Ø¯Ù…Gravatar Ø§Ø³ØªØ®Ø¯Ø§Ù…
-  setting_gravatar_default: Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©Gravatar ØµÙˆØ±Ø©
-  setting_diff_max_lines_displayed: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„Ø®Ø·ÙˆØ·
-  setting_file_max_size_displayed: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø£Ù‚ØµÙ‰ Ù„Ø­Ø¬Ù… Ø§Ù„Ù†Øµ Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶ Ø¹Ù„Ù‰ Ø§Ù„Ù…Ù„ÙØ§Øª Ø§Ù„Ù…Ø±ÙÙ‚Ø©
-  setting_repository_log_display_limit: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„ØªÙ†Ù‚ÙŠØ­Ø§Øª Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© Ø¹Ù„Ù‰ Ù…Ù„Ù Ø§Ù„Ø³Ø¬Ù„
-  setting_openid: Ø§Ù„Ø³Ù…Ø§Ø­ Ø¨Ø¯Ø®ÙˆÙ„ Ø§Ø³Ù… Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… Ø§Ù„Ù…ÙØªÙˆØ­ ÙˆØ§Ù„ØªØ³Ø¬ÙŠÙ„
-  setting_password_min_length: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¯Ù†ÙŠ Ù„Ø·ÙˆÙ„ ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
-  setting_new_project_user_role_id: Ø§Ù„Ø¯ÙˆØ± Ø§Ù„Ù…Ø³Ù†Ø¯ Ø§Ù„Ù‰ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… ØºÙŠØ± Ø§Ù„Ù…Ø³Ø¤ÙˆÙ„ Ø§Ù„Ø°ÙŠ ÙŠÙ‚ÙˆÙ… Ø¨Ø¥Ù†Ø´Ø§Ø¡ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
-  setting_default_projects_modules: ØªÙ…ÙƒÙŠÙ† Ø§Ù„ÙˆØ­Ø¯Ø§Øª Ø§Ù„Ù†Ù…Ø·ÙŠØ© Ù„Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„Ø¬Ø¯ÙŠØ¯Ø© Ø¨Ø´ÙƒÙ„ Ø§ÙØªØ±Ø§Ø¶ÙŠ
-  setting_issue_done_ratio: Ø­Ø³Ø§Ø¨ Ù†Ø³Ø¨Ø© Ø§Ù„Ù‚Ø¶ÙŠØ© Ø§Ù„Ù…Ù†ØªÙ‡ÙŠØ©
-  setting_issue_done_ratio_issue_field: Ø§Ø³ØªØ®Ø¯Ù… Ø­Ù‚Ù„ Ø§Ù„Ù‚Ø¶ÙŠØ©
-  setting_issue_done_ratio_issue_status: Ø§Ø³ØªØ®Ø¯Ù… ÙˆØ¶Ø¹ Ø§Ù„Ù‚Ø¶ÙŠØ©
-  setting_start_of_week: Ø¨Ø¯Ø£ Ø§Ù„ØªÙ‚ÙˆÙŠÙ…
-  setting_rest_api_enabled: ØªÙ…ÙƒÙŠÙ† Ø¨Ø§Ù‚ÙŠ Ø®Ø¯Ù…Ø§Øª Ø§Ù„ÙˆÙŠØ¨
-  setting_cache_formatted_text: Ø§Ù„Ù†Øµ Ø§Ù„Ù…Ø³Ø¨Ù‚ ØªÙ†Ø³ÙŠÙ‚Ù‡ ÙÙŠ Ø°Ø§ÙƒØ±Ø© Ø§Ù„ØªØ®Ø²ÙŠÙ† Ø§Ù„Ù…Ø¤Ù‚Øª
-  setting_default_notification_option: Ø®ÙŠØ§Ø± Ø§Ù„Ø§Ø¹Ù„Ø§Ù… Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ
-  setting_commit_logtime_enabled: ØªÙ…ÙŠÙƒÙ† ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„
-  setting_commit_logtime_activity_id: Ø§Ù„Ù†Ø´Ø§Ø· ÙÙŠ ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„
-  setting_gantt_items_limit: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ù„Ø¹Ø¯Ø¯ Ø§Ù„Ø¹Ù†Ø§ØµØ± Ø§Ù„Ù…Ø¹Ø±ÙˆØ¶Ø© Ø¹Ù„Ù‰ Ø§Ù„Ù…Ø®Ø·Ø·
-  setting_issue_group_assignment: Ø§Ù„Ø³Ù…Ø§Ø­ Ù„Ù„Ø¥Ø­Ø§Ù„Ø© Ø§Ù„Ù‰ Ø§Ù„Ù…Ø¬Ù…ÙˆØ¹Ø§Øª
-  setting_default_issue_start_date_to_creation_date: Ø§Ø³ØªØ®Ø¯Ø§Ù… Ø§Ù„ØªØ§Ø±ÙŠØ® Ø§Ù„Ø­Ø§Ù„ÙŠ ÙƒØªØ§Ø±ÙŠØ® Ø¨Ø¯Ø£ Ù„Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ø¬Ø¯ÙŠØ¯Ø©
-
-  permission_add_project: Ø¥Ù†Ø´Ø§Ø¡ Ù…Ø´Ø±ÙˆØ¹
-  permission_add_subprojects: Ø¥Ù†Ø´Ø§Ø¡ Ù…Ø´Ø§Ø±ÙŠØ¹ ÙØ±Ø¹ÙŠØ©
-  permission_edit_project: ØªØ¹Ø¯ÙŠÙ„ Ù…Ø´Ø±ÙˆØ¹
-  permission_select_project_modules: ØªØ­Ø¯ÙŠØ¯ Ø´ÙƒÙ„ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
-  permission_manage_members: Ø¥Ø¯Ø§Ø±Ø© Ø§Ù„Ø§Ø¹Ø¶Ø§Ø¡
-  permission_manage_project_activities: Ø§Ø¯Ø§Ø±Ø© Ø§ØµØ¯Ø§Ø±Ø§Øª Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
-  permission_manage_versions: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ø§ØµØ¯Ø§Ø±Ø§Øª
-  permission_manage_categories: Ø§Ø¯Ø§Ø±Ø© Ø§Ù†ÙˆØ§Ø¹ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  permission_view_issues: Ø¹Ø±Ø¶ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  permission_add_issues: Ø§Ø¶Ø§ÙØ© Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  permission_edit_issues: ØªØ¹Ø¯ÙŠÙ„ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  permission_manage_issue_relations: Ø§Ø¯Ø§Ø±Ø© Ø¹Ù„Ø§Ù‚Ø§Øª Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  permission_set_issues_private: ØªØ¹ÙŠÙ† Ù‚Ø¶Ø§ÙŠØ§ Ø¹Ø§Ù…Ø© Ø§Ùˆ Ø®Ø§ØµØ©
-  permission_set_own_issues_private: ØªØ¹ÙŠÙ† Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ø®Ø§ØµØ© Ø¨Ùƒ ÙƒÙ‚Ø¶Ø§ÙŠØ§ Ø¹Ø§Ù…Ø© Ø§Ùˆ Ø®Ø§ØµØ©
-  permission_add_issue_notes: Ø§Ø¶Ø§ÙØ© Ù…Ù„Ø§Ø­Ø¸Ø§Øª
-  permission_edit_issue_notes: ØªØ¹Ø¯ÙŠÙ„ Ù…Ù„Ø§Ø­Ø¸Ø§Øª
-  permission_edit_own_issue_notes: ØªØ¹Ø¯ÙŠÙ„ Ù…Ù„Ø§Ø­Ø¸Ø§ØªÙƒ
-  permission_move_issues: ØªØ­Ø±ÙŠÙƒ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  permission_delete_issues: Ø­Ø°Ù Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  permission_manage_public_queries: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ø§Ø³ØªØ¹Ù„Ø§Ù…Ø§Øª Ø§Ù„Ø¹Ø§Ù…Ø©
-  permission_save_queries: Ø­ÙØ¸ Ø§Ù„Ø§Ø³ØªØ¹Ù„Ø§Ù…Ø§Øª
-  permission_view_gantt: Ø¹Ø±Ø¶ Ø·Ø±ÙŠÙ‚Ø©"Ø¬Ø§Ù†Øª"
-  permission_view_calendar: Ø¹Ø±Ø¶ Ø§Ù„ØªÙ‚ÙˆÙŠÙ…
-  permission_view_issue_watchers: Ø¹Ø±Ø¶ Ù‚Ø§Ø¦Ù…Ø© Ø§Ù„Ù…Ø±Ø§Ù‚Ø¨ÙŠÙ†
-  permission_add_issue_watchers: Ø§Ø¶Ø§ÙØ© Ù…Ø±Ø§Ù‚Ø¨ÙŠÙ†
-  permission_delete_issue_watchers: Ø­Ø°Ù Ù…Ø±Ø§Ù‚Ø¨ÙŠÙ†
-  permission_log_time: Ø§Ù„ÙˆÙ‚Øª Ø§Ù„Ù…Ø³ØªØºØ±Ù‚ Ø¨Ø§Ù„Ø¯Ø®ÙˆÙ„
-  permission_view_time_entries: Ø¹Ø±Ø¶ Ø§Ù„ÙˆÙ‚Øª Ø§Ù„Ù…Ø³ØªØºØ±Ù‚
-  permission_edit_time_entries: ØªØ¹Ø¯ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„Ø§Øª Ø§Ù„Ø²Ù…Ù†ÙŠØ©
-  permission_edit_own_time_entries: ØªØ¹Ø¯ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„Ø§Øª Ø§Ù„Ø´Ø®ØµÙŠØ©
-  permission_manage_news: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ø§Ø®Ø¨Ø§Ø±
-  permission_comment_news: Ø§Ø®Ø¨Ø§Ø± Ø§Ù„ØªØ¹Ù„ÙŠÙ‚Ø§Øª
-  permission_manage_documents: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª
-  permission_view_documents: Ø¹Ø±Ø¶ Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª
-  permission_manage_files: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ù„ÙØ§Øª
-  permission_view_files: Ø¹Ø±Ø¶ Ø§Ù„Ù…Ù„ÙØ§Øª
-  permission_manage_wiki: Ø§Ø¯Ø§Ø±Ø© ÙˆÙŠÙƒÙŠ
-  permission_rename_wiki_pages: Ø§Ø¹Ø§Ø¯Ø© ØªØ³Ù…ÙŠØ© ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
-  permission_delete_wiki_pages: Ø­Ø°Ù‚ ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
-  permission_view_wiki_pages: Ø¹Ø±Ø¶ ÙˆÙŠÙƒÙŠ
-  permission_view_wiki_edits: Ø¹Ø±Ø¶ ØªØ§Ø±ÙŠØ® ÙˆÙŠÙƒÙŠ
-  permission_edit_wiki_pages: ØªØ¹Ø¯ÙŠÙ„ ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
-  permission_delete_wiki_pages_attachments: Ø­Ø°Ù Ø§Ù„Ù…Ø±ÙÙ‚Ø§Øª
-  permission_protect_wiki_pages: Ø­Ù…Ø§ÙŠØ© ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
-  permission_manage_repository: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹Ø§Øª
-  permission_browse_repository: Ø§Ø³ØªØ¹Ø±Ø§Ø¶ Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹Ø§Øª
-  permission_view_changesets: Ø¹Ø±Ø¶ Ø·Ø§Ù‚Ù… Ø§Ù„ØªØºÙŠÙŠØ±
-  permission_commit_access: Ø§Ù„ÙˆØµÙˆÙ„
-  permission_manage_boards: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ù†ØªØ¯ÙŠØ§Øª
-  permission_view_messages: Ø¹Ø±Ø¶ Ø§Ù„Ø±Ø³Ø§Ø¦Ù„
-  permission_add_messages: Ù†Ø´Ø± Ø§Ù„Ø±Ø³Ø§Ø¦Ù„
-  permission_edit_messages: ØªØ­Ø±ÙŠØ± Ø§Ù„Ø±Ø³Ø§Ø¦Ù„
-  permission_edit_own_messages: ØªØ­Ø±ÙŠØ± Ø§Ù„Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø®Ø§ØµØ©
-  permission_delete_messages: Ø­Ø°Ù Ø§Ù„Ø±Ø³Ø§Ø¦Ù„
-  permission_delete_own_messages: Ø­Ø°Ù Ø§Ù„Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø®Ø§ØµØ©
-  permission_export_wiki_pages: ØªØµØ¯ÙŠØ± ØµÙØ­Ø§Øª ÙˆÙŠÙƒÙŠ
-  permission_manage_subtasks: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ÙØ±Ø¹ÙŠØ©
-
-  project_module_issue_tracking: ØªØ¹Ù‚Ø¨ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  project_module_time_tracking: Ø§Ù„ØªØ¹Ù‚Ø¨ Ø§Ù„Ø²Ù…Ù†ÙŠ
-  project_module_news: Ø§Ù„Ø§Ø®Ø¨Ø§Ø±
-  project_module_documents: Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª
-  project_module_files: Ø§Ù„Ù…Ù„ÙØ§Øª
-  project_module_wiki: ÙˆÙŠÙƒÙŠ
-  project_module_repository: Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹
-  project_module_boards: Ø§Ù„Ù…Ù†ØªØ¯ÙŠØ§Øª
-  project_module_calendar: Ø§Ù„ØªÙ‚ÙˆÙŠÙ…
-  project_module_gantt: Ø¬Ø§Ù†Øª
-
-  label_user: Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
-  label_user_plural: Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…ÙŠÙ†
-  label_user_new: Ù…Ø³ØªØ®Ø¯Ù… Ø¬Ø¯ÙŠØ¯
-  label_user_anonymous: Ù…Ø¬Ù‡ÙˆÙ„ Ø§Ù„Ù‡ÙˆÙŠØ©
-  label_project: Ù…Ø´Ø±ÙˆØ¹
-  label_project_new: Ù…Ø´Ø±ÙˆØ¹ Ø¬Ø¯ÙŠØ¯
-  label_project_plural: Ù…Ø´Ø§Ø±ÙŠØ¹
-  label_x_projects:
-    zero: Ù„Ø§ ÙŠÙˆØ¬Ø¯ Ù…Ø´Ø§Ø±ÙŠØ¹
-    one: Ù…Ø´Ø±ÙˆØ¹ ÙˆØ§Ø­Ø¯
-    other: "%{count} Ù…Ø´Ø§Ø±ÙŠØ¹"
-  label_project_all: ÙƒÙ„ Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹
-  label_project_latest: Ø§Ø­Ø¯Ø« Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹
-  label_issue: Ù‚Ø¶ÙŠØ©
-  label_issue_new: Ù‚Ø¶ÙŠØ© Ø¬Ø¯ÙŠØ¯Ø©
-  label_issue_plural: Ù‚Ø¶Ø§ÙŠØ§
-  label_issue_view_all: Ø¹Ø±Ø¶ ÙƒÙ„ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  label_issues_by: " %{value}Ø§Ù„Ù‚Ø¶ÙŠØ© Ù„ØµØ­Ø§Ø¨Ù‡Ø§"
-  label_issue_added: ØªÙ… Ø§Ø¶Ø§ÙØ© Ø§Ù„Ù‚Ø¶ÙŠØ©
-  label_issue_updated: ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ù‚Ø¶ÙŠØ©
-  label_issue_note_added: ØªÙ… Ø§Ø¶Ø§ÙØ© Ø§Ù„Ù…Ù„Ø§Ø­Ø¸Ø©
-  label_issue_status_updated: ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ø­Ø§Ù„Ø©
-  label_issue_priority_updated: ØªÙ… ØªØ­Ø¯ÙŠØ« Ø§Ù„Ø§ÙˆÙ„ÙˆÙŠØ§Øª
-  label_document: Ù…Ø³ØªÙ†Ø¯
-  label_document_new: Ù…Ø³ØªÙ†Ø¯ Ø¬Ø¯ÙŠØ¯
-  label_document_plural: Ù…Ø³ØªÙ†Ø¯Ø§Øª
-  label_document_added: ØªÙ… Ø§Ø¶Ø§ÙØ© Ù…Ø³ØªÙ†Ø¯
-  label_role: Ø¯ÙˆØ±
-  label_role_plural: Ø§Ø¯ÙˆØ§Ø±
-  label_role_new: Ø¯ÙˆØ± Ø¬Ø¯ÙŠØ¯
-  label_role_and_permissions: Ø§Ù„Ø§Ø¯ÙˆØ§Ø± ÙˆØ§Ù„Ø§Ø°Ù†
-  label_role_anonymous: Ù…Ø¬Ù‡ÙˆÙ„ Ø§Ù„Ù‡ÙˆÙŠØ©
-  label_role_non_member: Ù„ÙŠØ³ Ø¹Ø¶Ùˆ
-  label_member: Ø¹Ø¶Ùˆ
-  label_member_new: Ø¹Ø¶Ùˆ Ø¬Ø¯ÙŠØ¯
-  label_member_plural: Ø§Ø¹Ø¶Ø§Ø¡
-  label_tracker: Ø§Ù„Ù…ØªØªØ¨Ø¹
-  label_tracker_plural: Ø§Ù„Ù…ØªØªØ¨Ø¹ÙŠÙ†
-  label_tracker_new: Ù…ØªØªØ¨Ø¹ Ø¬Ø¯ÙŠØ¯
-  label_workflow: Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„
-  label_issue_status: ÙˆØ¶Ø¹ Ø§Ù„Ù‚Ø¶ÙŠØ©
-  label_issue_status_plural: Ø§ÙˆØ¶Ø§Ø¹ Ø§Ù„Ù‚Ø¶ÙŠØ©
-  label_issue_status_new: ÙˆØ¶Ø¹ Ø¬Ø¯ÙŠØ¯
-  label_issue_category: Ù†ÙˆØ¹ Ø§Ù„Ù‚Ø¶ÙŠØ©
-  label_issue_category_plural: Ø§Ù†ÙˆØ§Ø¹ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  label_issue_category_new: Ù†ÙˆØ¹ Ø¬Ø¯ÙŠØ¯
-  label_custom_field: ØªØ®ØµÙŠØµ Ø­Ù‚Ù„
-  label_custom_field_plural: ØªØ®ØµÙŠØµ Ø­Ù‚ÙˆÙ„
-  label_custom_field_new: Ø­Ù‚Ù„ Ù…Ø®ØµØµ Ø¬Ø¯ÙŠØ¯
-  label_enumerations: Ø§Ù„ØªØ¹Ø¯Ø§Ø¯Ø§Øª
-  label_enumeration_new: Ù‚ÙŠÙ…Ø© Ø¬Ø¯ÙŠØ¯Ø©
-  label_information: Ù…Ø¹Ù„ÙˆÙ…Ø©
-  label_information_plural: Ù…Ø¹Ù„ÙˆÙ…Ø§Øª
-  label_please_login: Ø¨Ø±Ø¬Ù‰ ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„
-  label_register: ØªØ³Ø¬ÙŠÙ„
-  label_login_with_open_id_option: Ø§Ùˆ Ø§Ù„Ø¯Ø®ÙˆÙ„ Ø¨Ù‡ÙˆÙŠØ© Ù…ÙØªÙˆØ­Ø©
-  label_password_lost: ÙÙ‚Ø¯Øª ÙƒÙ„Ù…Ø© Ø§Ù„Ø³Ø±
-  label_home: Ø§Ù„ØµÙØ­Ø© Ø§Ù„Ø±Ø¦ÙŠØ³ÙŠØ©
-  label_my_page: Ø§Ù„ØµÙØ­Ø© Ø§Ù„Ø®Ø§ØµØ© Ø¨ÙŠ
-  label_my_account: Ø­Ø³Ø§Ø¨ÙŠ
-  label_my_projects: Ù…Ø´Ø§Ø±ÙŠØ¹ÙŠ Ø§Ù„Ø®Ø§ØµØ©
-  label_my_page_block: Ø­Ø¬Ø¨ ØµÙØ­ØªÙŠ Ø§Ù„Ø®Ø§ØµØ©
-  label_administration: Ø§Ù„Ø¥Ø¯Ø§Ø±Ø©
-  label_login: ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„
-  label_logout: ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø®Ø±ÙˆØ¬
-  label_help: Ù…Ø³Ø§Ø¹Ø¯Ø©
-  label_reported_issues: Ø£Ø¨Ù„Øº Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  label_assigned_to_me_issues: Ø§Ù„Ù…Ø³Ø§Ø¦Ù„ Ø§Ù„Ù…Ø¹Ù†ÙŠØ© Ø¥Ù„Ù‰
-  label_last_login: Ø¢Ø®Ø± Ø§ØªØµØ§Ù„
-  label_registered_on: Ù…Ø³Ø¬Ù„ Ø¹Ù„Ù‰
-  label_activity: Ø§Ù„Ù†Ø´Ø§Ø·
-  label_overall_activity: Ø§Ù„Ù†Ø´Ø§Ø· Ø§Ù„Ø¹Ø§Ù…
-  label_user_activity: "Ù‚ÙŠÙ…Ø© Ø§Ù„Ù†Ø´Ø§Ø·"
-  label_new: Ø¬Ø¯ÙŠØ¯Ø©
-  label_logged_as: ØªÙ… ØªØ³Ø¬ÙŠÙ„ Ø¯Ø®ÙˆÙ„Ùƒ
-  label_environment: Ø§Ù„Ø¨ÙŠØ¦Ø©
-  label_authentication: Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
-  label_auth_source: ÙˆØ¶Ø¹ Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
-  label_auth_source_new: ÙˆØ¶Ø¹ Ù…ØµØ§Ø¯Ù‚Ø© Ø¬Ø¯ÙŠØ¯Ø©
-  label_auth_source_plural: Ø£ÙˆØ¶Ø§Ø¹ Ø§Ù„Ù…ØµØ§Ø¯Ù‚Ø©
-  label_subproject_plural: Ù…Ø´Ø§Ø±ÙŠØ¹ ÙØ±Ø¹ÙŠØ©
-  label_subproject_new: Ù…Ø´Ø±ÙˆØ¹ ÙØ±Ø¹ÙŠ Ø¬Ø¯ÙŠØ¯
-  label_and_its_subprojects: "Ù‚ÙŠÙ…Ø©Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„ÙØ±Ø¹ÙŠØ© Ø§Ù„Ø®Ø§ØµØ© Ø¨Ùƒ"
-  label_min_max_length: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ ÙˆØ§Ù„Ø§Ø¯Ù†Ù‰ Ù„Ù„Ø·ÙˆÙ„
-  label_list: Ù‚Ø§Ø¦Ù…Ø©
-  label_date: ØªØ§Ø±ÙŠØ®
-  label_integer: Ø¹Ø¯Ø¯ ØµØ­ÙŠØ­
-  label_float: ØªØ¹ÙˆÙŠÙ…
-  label_boolean: Ù…Ù†Ø·Ù‚ÙŠØ©
-  label_string: Ø§Ù„Ù†Øµ
-  label_text: Ù†Øµ Ø·ÙˆÙŠÙ„
-  label_attribute: Ø³Ù…Ø©
-  label_attribute_plural: Ø§Ù„Ø³Ù…Ø§Øª
-  label_download: "ØªØ­Ù…ÙŠÙ„"
-  label_download_plural: "ØªØ­Ù…ÙŠÙ„"
-  label_no_data: Ù„Ø§ ØªÙˆØ¬Ø¯ Ø¨ÙŠØ§Ù†Ø§Øª Ù„Ù„Ø¹Ø±Ø¶
-  label_change_status: ØªØºÙŠÙŠØ± Ø§Ù„ÙˆØ¶Ø¹
-  label_history: Ø§Ù„ØªØ§Ø±ÙŠØ®
-  label_attachment: Ø§Ù„Ù…Ù„Ù
-  label_attachment_new: Ù…Ù„Ù Ø¬Ø¯ÙŠØ¯
-  label_attachment_delete: Ø­Ø°Ù Ø§Ù„Ù…Ù„Ù
-  label_attachment_plural: Ø§Ù„Ù…Ù„ÙØ§Øª
-  label_file_added: Ø§Ù„Ù…Ù„Ù Ø§Ù„Ù…Ø¶Ø§Ù
-  label_report: ØªÙ‚Ø±ÙŠØ±
-  label_report_plural: Ø§Ù„ØªÙ‚Ø§Ø±ÙŠØ±
-  label_news: Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
-  label_news_new: Ø¥Ø¶Ø§ÙØ© Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
-  label_news_plural: Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
-  label_news_latest: Ø¢Ø®Ø± Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
-  label_news_view_all: Ø¹Ø±Ø¶ ÙƒÙ„ Ø§Ù„Ø£Ø®Ø¨Ø§Ø±
-  label_news_added: Ø§Ù„Ø£Ø®Ø¨Ø§Ø± Ø§Ù„Ù…Ø¶Ø§ÙØ©
-  label_news_comment_added: Ø¥Ø¶Ø§ÙØ© Ø§Ù„ØªØ¹Ù„ÙŠÙ‚Ø§Øª Ø¹Ù„Ù‰ Ø£Ø®Ø¨Ø§Ø±
-  label_settings: Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª
-  label_overview: Ù„Ù…Ø­Ø© Ø¹Ø§Ù…Ø©
-  label_version: Ø§Ù„Ø¥ØµØ¯Ø§Ø±
-  label_version_new: Ø§Ù„Ø¥ØµØ¯Ø§Ø± Ø§Ù„Ø¬Ø¯ÙŠØ¯
-  label_version_plural: Ø§Ù„Ø¥ØµØ¯Ø§Ø±Ø§Øª
-  label_close_versions: Ø£ÙƒÙ…Ù„Øª Ø¥ØºÙ„Ø§Ù‚ Ø§Ù„Ø¥ØµØ¯Ø§Ø±Ø§Øª
-  label_confirmation: ØªØ£ÙƒÙŠØ¯
-  label_export_to: 'Ù…ØªÙˆÙØ±Ø© Ø£ÙŠØ¶Ø§ ÙÙŠ:'
-  label_read: Ø§Ù„Ù‚Ø±Ø§Ø¡Ø©...
-  label_public_projects: Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„Ø¹Ø§Ù…Ø©
-  label_open_issues: ÙØªØ­ Ù‚Ø¶ÙŠØ©
-  label_open_issues_plural:  ÙØªØ­ Ù‚Ø¶Ø§ÙŠØ§
-  label_closed_issues: Ù‚Ø¶ÙŠØ© Ù…ØºÙ„Ù‚Ø©
-  label_closed_issues_plural: Ù‚Ø¶Ø§ÙŠØ§ Ù…ØºÙ„Ù‚Ø©
-  label_x_open_issues_abbr_on_total:
-    zero: 0 Ù…ÙØªÙˆØ­ / %{total}
-    one: 1 Ù…ÙØªÙˆØ­ / %{total}
-    other: "%{count} Ù…ÙØªÙˆØ­ / %{total}"
-  label_x_open_issues_abbr:
-    zero: 0 Ù…ÙØªÙˆØ­
-    one: 1 Ù…Ù‚ØªÙˆØ­
-    other: "%{count} Ù…ÙØªÙˆØ­"
-  label_x_closed_issues_abbr:
-    zero: 0 Ù…ØºÙ„Ù‚
-    one: 1 Ù…ØºÙ„Ù‚
-    other: "%{count} Ù…ØºÙ„Ù‚"
-  label_total: Ø§Ù„Ø¥Ø¬Ù…Ø§Ù„ÙŠ
-  label_permissions: Ø£Ø°ÙˆÙ†Ø§Øª
-  label_current_status: Ø§Ù„ÙˆØ¶Ø¹ Ø§Ù„Ø­Ø§Ù„ÙŠ
-  label_new_statuses_allowed: ÙŠØ³Ù…Ø­ Ø¨Ø§Ø¯Ø±Ø§Ø¬ Ø­Ø§Ù„Ø§Øª Ø¬Ø¯ÙŠØ¯Ø©
-  label_all: Ø¬Ù…ÙŠØ¹
-  label_none: Ù„Ø§ Ø´ÙŠØ¡
-  label_nobody: Ù„Ø§ Ø£Ø­Ø¯
-  label_next: Ø§Ù„Ù‚Ø§Ø¯Ù…
-  label_previous: Ø§Ù„Ø³Ø§Ø¨Ù‚
-  label_used_by: Ø§Ù„ØªÙŠ ÙŠØ³ØªØ®Ø¯Ù…Ù‡Ø§
-  label_details: Ø§Ù„ØªÙØ§ØµÙŠÙ„
-  label_add_note: Ø¥Ø¶Ø§ÙØ© Ù…Ù„Ø§Ø­Ø¸Ø©
-  label_per_page: ÙƒÙ„ ØµÙØ­Ø©
-  label_calendar: Ø§Ù„ØªÙ‚ÙˆÙŠÙ…
-  label_months_from: Ø¨Ø¹Ø¯ Ø£Ø´Ù‡Ø± Ù…Ù†
-  label_gantt: Ø¬Ø§Ù†Øª
-  label_internal: Ø§Ù„Ø¯Ø§Ø®Ù„ÙŠØ©
-  label_last_changes: "Ø¢Ø®Ø± Ø§Ù„ØªØºÙŠÙŠØ±Ø§Øª %{count}"
-  label_change_view_all: Ø¹Ø±Ø¶ ÙƒØ§ÙØ© Ø§Ù„ØªØºÙŠÙŠØ±Ø§Øª
-  label_personalize_page: ØªØ®ØµÙŠØµ Ù‡Ø°Ù‡ Ø§Ù„ØµÙØ­Ø©
-  label_comment: ØªØ¹Ù„ÙŠÙ‚
-  label_comment_plural: ØªØ¹Ù„ÙŠÙ‚Ø§Øª
-  label_x_comments:
-    zero: Ù„Ø§ ÙŠÙˆØ¬Ø¯ ØªØ¹Ù„ÙŠÙ‚Ø§Øª
-    one: ØªØ¹Ù„ÙŠÙ‚ ÙˆØ§Ø­Ø¯
-    other: "%{count} ØªØ¹Ù„ÙŠÙ‚Ø§Øª"
-  label_comment_add: Ø¥Ø¶Ø§ÙØ© ØªØ¹Ù„ÙŠÙ‚
-  label_comment_added: ØªÙ… Ø¥Ø¶Ø§ÙØ© Ø§Ù„ØªØ¹Ù„ÙŠÙ‚
-  label_comment_delete: Ø­Ø°Ù Ø§Ù„ØªØ¹Ù„ÙŠÙ‚Ø§Øª
-  label_query: Ø§Ø³ØªØ¹Ù„Ø§Ù… Ù…Ø®ØµØµ
-  label_query_plural: Ø§Ø³ØªØ¹Ù„Ø§Ù…Ø§Øª Ù…Ø®ØµØµØ©
-  label_query_new: Ø§Ø³ØªØ¹Ù„Ø§Ù… Ø¬Ø¯ÙŠØ¯
-  label_my_queries: Ø§Ø³ØªØ¹Ù„Ø§Ù…Ø§ØªÙŠ Ø§Ù„Ù…Ø®ØµØµØ©
-  label_filter_add: Ø¥Ø¶Ø§ÙØ© Ø¹Ø§Ù…Ù„ ØªØµÙÙŠØ©
-  label_filter_plural: Ø¹ÙˆØ§Ù…Ù„ Ø§Ù„ØªØµÙÙŠØ©
-  label_equals: ÙŠØ³Ø§ÙˆÙŠ
-  label_not_equals: Ù„Ø§ ÙŠØ³Ø§ÙˆÙŠ
-  label_in_less_than: ÙÙŠ Ø£Ù‚Ù„ Ù…Ù†
-  label_in_more_than: ÙÙŠ Ø£ÙƒØ«Ø± Ù…Ù†
-  label_greater_or_equal: '>='
-  label_less_or_equal: '< ='
-  label_between: Ø¨ÙŠÙ†
-  label_in: ÙÙŠ
-  label_today: Ø§Ù„ÙŠÙˆÙ…
-  label_all_time: ÙƒÙ„ Ø§Ù„ÙˆÙ‚Øª
-  label_yesterday: Ø¨Ø§Ù„Ø£Ù…Ø³
-  label_this_week: Ù‡Ø°Ø§ Ø§Ù„Ø£Ø³Ø¨ÙˆØ¹
-  label_last_week: Ø§Ù„Ø£Ø³Ø¨ÙˆØ¹ Ø§Ù„Ù…Ø§Ø¶ÙŠ
-  label_last_n_days: "Ø§ÙŠØ§Ù… %{count} Ø§Ø®Ø±"
-  label_this_month: Ù‡Ø°Ø§ Ø§Ù„Ø´Ù‡Ø±
-  label_last_month: Ø§Ù„Ø´Ù‡Ø± Ø§Ù„Ù…Ø§Ø¶ÙŠ
-  label_this_year: Ù‡Ø°Ø§ Ø§Ù„Ø¹Ø§Ù…
-  label_date_range: Ù†Ø·Ø§Ù‚ Ø§Ù„ØªØ§Ø±ÙŠØ®
-  label_less_than_ago: Ø£Ù‚Ù„ Ù…Ù† Ù‚Ø¨Ù„ Ø£ÙŠØ§Ù…
-  label_more_than_ago: Ø£ÙƒØ«Ø± Ù…Ù† Ù‚Ø¨Ù„ Ø£ÙŠØ§Ù…
-  label_ago: Ù…Ù†Ø° Ø£ÙŠØ§Ù…
-  label_contains: ÙŠØ­ØªÙˆÙŠ Ø¹Ù„Ù‰
-  label_not_contains: Ù„Ø§ ÙŠØ­ØªÙˆÙŠ Ø¹Ù„Ù‰
-  label_day_plural: Ø£ÙŠØ§Ù…
-  label_repository: Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹
-  label_repository_plural: Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹Ø§Øª
-  label_browse: ØªØµÙØ­
-  label_modification: "%{count} ØªØºÙŠØ±"
-  label_modification_plural: "%{count}ØªØºÙŠØ±Ø§Øª "
-  label_branch: ÙØ±Ø¹
-  label_tag: Ø±Ø¨Ø·
-  label_revision: Ù…Ø±Ø§Ø¬Ø¹Ø©
-  label_revision_plural: ØªÙ†Ù‚ÙŠØ­Ø§Øª
-  label_revision_id: " %{value}Ù…Ø±Ø§Ø¬Ø¹Ø©"
-  label_associated_revisions: Ø§Ù„ØªÙ†Ù‚ÙŠØ­Ø§Øª Ø§Ù„Ù…Ø±ØªØ¨Ø·Ø©
-  label_added: Ø¥Ø¶Ø§ÙØ©
-  label_modified: ØªØ¹Ø¯ÙŠÙ„
-  label_copied: Ù†Ø³Ø®
-  label_renamed: Ø¥Ø¹Ø§Ø¯Ø© ØªØ³Ù…ÙŠØ©
-  label_deleted: Ø­Ø°Ù
-  label_latest_revision: Ø¢Ø®Ø± ØªÙ†Ù‚ÙŠØ­
-  label_latest_revision_plural: Ø£Ø­Ø¯Ø« Ø§Ù„Ù…Ø±Ø§Ø¬Ø¹Ø§Øª
-  label_view_revisions: Ø¹Ø±Ø¶ Ø§Ù„ØªÙ†Ù‚ÙŠØ­Ø§Øª
-  label_view_all_revisions: Ø¹Ø±Ø¶ ÙƒØ§ÙØ© Ø§Ù„Ù…Ø±Ø§Ø¬Ø¹Ø§Øª
-  label_max_size: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø£Ù‚ØµÙ‰ Ù„Ù„Ø­Ø¬Ù…
-  label_sort_highest: Ø§Ù„ØªØ­Ø±Ùƒ Ø¥Ù„Ù‰ Ø£Ø¹Ù„Ù‰
-  label_sort_higher: ØªØ­Ø±ÙŠÙƒ Ù„Ø£Ø¹Ù„Ù‰
-  label_sort_lower: ØªØ­Ø±ÙŠÙƒ Ù„Ø£Ø³ÙÙ„
-  label_sort_lowest: Ø§Ù„Ø§Ù†ØªÙ‚Ø§Ù„ Ø¥Ù„Ù‰ Ø£Ø³ÙÙ„
-  label_roadmap: Ø®Ø§Ø±Ø·Ø© Ø§Ù„Ø·Ø±ÙŠÙ‚
-  label_roadmap_due_in: " %{value}ØªØ³ØªØ­Ù‚ ÙÙŠ "
-  label_roadmap_overdue: "%{value}ØªØ£Ø®ÙŠØ±"
-  label_roadmap_no_issues: Ù„Ø§ ÙŠÙˆØ¬Ø¯ Ù‚Ø¶Ø§ÙŠØ§ Ù„Ù‡Ø°Ø§ Ø§Ù„Ø¥ØµØ¯Ø§Ø±
-  label_search: Ø§Ù„Ø¨Ø­Ø«
-  label_result_plural: Ø§Ù„Ù†ØªØ§Ø¦Ø¬
-  label_all_words: ÙƒÙ„ Ø§Ù„ÙƒÙ„Ù…Ø§Øª
-  label_wiki: ÙˆÙŠÙƒÙŠ
-  label_wiki_edit: ØªØ­Ø±ÙŠØ± ÙˆÙŠÙƒÙŠ
-  label_wiki_edit_plural: Ø¹Ù…Ù„ÙŠØ§Øª ØªØ­Ø±ÙŠØ± ÙˆÙŠÙƒÙŠ
-  label_wiki_page: ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ
-  label_wiki_page_plural: ÙˆÙŠÙƒÙŠ ØµÙØ­Ø§Øª
-  label_index_by_title: Ø§Ù„ÙÙ‡Ø±Ø³ Ø­Ø³Ø¨ Ø§Ù„Ø¹Ù†ÙˆØ§Ù†
-  label_index_by_date: Ø§Ù„ÙÙ‡Ø±Ø³ Ø­Ø³Ø¨ Ø§Ù„ØªØ§Ø±ÙŠØ®
-  label_current_version: Ø§Ù„Ø¥ØµØ¯Ø§Ø± Ø§Ù„Ø­Ø§Ù„ÙŠ
-  label_preview: Ù…Ø¹Ø§ÙŠÙ†Ø©
-  label_feed_plural: Ù…ÙˆØ¬Ø² ÙˆÙŠØ¨
-  label_changes_details: ØªÙØ§ØµÙŠÙ„ Ø¬Ù…ÙŠØ¹ Ø§Ù„ØªØºÙŠÙŠØ±Ø§Øª
-  label_issue_tracking: ØªØ¹Ù‚Ø¨ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  label_spent_time: Ø£Ù…Ø¶Ù‰ Ø¨Ø¹Ø¶ Ø§Ù„ÙˆÙ‚Øª
-  label_overall_spent_time: Ø§Ù„ÙˆÙ‚Øª Ø§Ù„Ø°ÙŠ ØªÙ… Ø§Ù†ÙØ§Ù‚Ù‡ ÙƒØ§Ù…Ù„Ø§
-  label_f_hour: "%{value} Ø³Ø§Ø¹Ø©"
-  label_f_hour_plural: "%{value} Ø³Ø§Ø¹Ø§Øª"
-  label_time_tracking: ØªØ¹Ù‚Ø¨ Ø§Ù„ÙˆÙ‚Øª
-  label_change_plural: Ø§Ù„ØªØºÙŠÙŠØ±Ø§Øª
-  label_statistics: Ø¥Ø­ØµØ§Ø¡Ø§Øª
-  label_commits_per_month: ÙŠØ«Ø¨Øª ÙÙŠ Ø§Ù„Ø´Ù‡Ø±
-  label_commits_per_author: ÙŠØ«Ø¨Øª Ù„ÙƒÙ„ Ù…Ø¤Ù„Ù
-  label_diff: Ø§Ù„Ø§Ø®ØªÙ„Ø§ÙØ§Øª
-  label_view_diff: Ø¹Ø±Ø¶ Ø§Ù„Ø§Ø®ØªÙ„Ø§ÙØ§Øª
-  label_diff_inline: Ù…Ø¶Ù…Ù†Ø©
-  label_diff_side_by_side: Ø¬Ù†Ø¨Ø§ Ø¥Ù„Ù‰ Ø¬Ù†Ø¨
-  label_options: Ø®ÙŠØ§Ø±Ø§Øª
-  label_copy_workflow_from: Ù†Ø³Ø® Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„ Ù…Ù†
-  label_permissions_report: ØªÙ‚Ø±ÙŠØ± Ø£Ø°ÙˆÙ†Ø§Øª
-  label_watched_issues: Ø´Ø§Ù‡Ø¯ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  label_related_issues: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø°Ø§Øª Ø§Ù„ØµÙ„Ø©
-  label_applied_status: ØªØ·Ø¨ÙŠÙ‚ Ù…Ø±ÙƒØ²
-  label_loading: ØªØ­Ù…ÙŠÙ„...
-  label_relation_new: Ø¹Ù„Ø§Ù‚Ø© Ø¬Ø¯ÙŠØ¯Ø©
-  label_relation_delete: Ø­Ø°Ù Ø§Ù„Ø¹Ù„Ø§Ù‚Ø©
-  label_relates_to: Ø°Ø§Øª Ø§Ù„ØµÙ„Ø© Ø¥Ù„Ù‰
-  label_duplicates: Ø§Ù„ØªÙƒØ±Ø§Ø±Ø§Øª
-  label_duplicated_by: Ø§Ø²Ø¯ÙˆØ§Ø¬
-  label_blocks: Ø­Ø¸Ø±
-  label_blocked_by: Ø­Ø¸Ø± Ø¨ÙˆØ§Ø³Ø·Ø©
-  label_precedes: ÙŠØ³Ø¨Ù‚
-  label_follows: ÙŠØªØ¨Ø¹
-  label_end_to_start: Ù†Ù‡Ø§ÙŠØ© Ù„Ø¨Ø¯Ø¡
-  label_end_to_end: Ù†Ù‡Ø§ÙŠØ© Ø¥Ù„Ù‰ Ù†Ù‡Ø§ÙŠØ©
-  label_start_to_start: Ø¨Ø¯Ø¡ Ø¥Ù„Ù‰ Ø¨Ø¯Ø¡
-  label_start_to_end: Ø¨Ø¯Ø§ÙŠØ© Ù„Ù†Ù‡Ø§ÙŠØ©
-  label_stay_logged_in: ØªØ³Ø¬ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„ ÙÙŠ
-  label_disabled: ØªØ¹Ø·ÙŠÙ„
-  label_show_completed_versions: Ø£ÙƒÙ…Ù„Øª Ø¥Ø¸Ù‡Ø§Ø± Ø¥ØµØ¯Ø§Ø±Ø§Øª
-  label_me: Ù„ÙŠ
-  label_board: Ø§Ù„Ù…Ù†ØªØ¯Ù‰
-  label_board_new: Ù…Ù†ØªØ¯Ù‰ Ø¬Ø¯ÙŠØ¯
-  label_board_plural: Ø§Ù„Ù…Ù†ØªØ¯ÙŠØ§Øª
-  label_board_locked: ØªØ£Ù…ÙŠÙ†
-  label_board_sticky: Ù„Ø²Ø¬Ø©
-  label_topic_plural: Ø§Ù„Ù…ÙˆØ§Ø¶ÙŠØ¹
-  label_message_plural: Ø±Ø³Ø§Ø¦Ù„
-  label_message_last: Ø¢Ø®Ø± Ø±Ø³Ø§Ù„Ø©
-  label_message_new: Ø±Ø³Ø§Ù„Ø© Ø¬Ø¯ÙŠØ¯Ø©
-  label_message_posted: ØªÙ… Ø§Ø¶Ø§ÙØ© Ø§Ù„Ø±Ø³Ø§Ù„Ø©
-  label_reply_plural: Ø§Ù„Ø±Ø¯ÙˆØ¯
-  label_send_information: Ø¥Ø±Ø³Ø§Ù„ Ù…Ø¹Ù„ÙˆÙ…Ø§Øª Ø§Ù„Ø­Ø³Ø§Ø¨ Ù„Ù„Ù…Ø³ØªØ®Ø¯Ù…
-  label_year: Ø³Ù†Ø©
-  label_month: Ø´Ù‡Ø±
-  label_week: Ø£Ø³Ø¨ÙˆØ¹
-  label_date_from: Ù…Ù†
-  label_date_to: Ø¥Ù„Ù‰
-  label_language_based: Ø§Ø³ØªÙ†Ø§Ø¯Ø§Ù‹ Ø¥Ù„Ù‰ Ù„ØºØ© Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
-  label_sort_by: " %{value}Ø§Ù„ØªØ±ØªÙŠØ¨ Ø­Ø³Ø¨ "
-  label_send_test_email: Ø§Ø±Ø³Ù„ Ø±Ø³Ø§Ù„Ø© Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠØ© ÙƒØ§Ø®ØªØ¨Ø§Ø±
-  label_feeds_access_key: RSS Ù…ÙØªØ§Ø­ Ø¯Ø®ÙˆÙ„
-  label_missing_feeds_access_key: Ù…ÙÙ‚ÙˆØ¯RSS Ù…ÙØªØ§Ø­ Ø¯Ø®ÙˆÙ„
-  label_feeds_access_key_created_on: "RSS ØªÙ… Ø§Ù†Ø´Ø§Ø¡ Ù…ÙØªØ§Ø­ %{value} Ù…Ù†Ø°"
-  label_module_plural: Ø§Ù„ÙˆØ­Ø¯Ø§Øª Ø§Ù„Ù†Ù…Ø·ÙŠØ©
-  label_added_time_by: " ØªÙ… Ø§Ø¶Ø§ÙØªÙ‡ Ù…Ù† Ù‚Ø¨Ù„%{author} %{age} Ù…Ù†Ø°"
-  label_updated_time_by: " ØªÙ… ØªØ­Ø¯ÙŠØ«Ù‡ Ù…Ù† Ù‚Ø¨Ù„%{author} %{age} Ù…Ù†Ø°"
-  label_updated_time: "ØªÙ… Ø§Ù„ØªØ­Ø¯ÙŠØ«  %{value} Ù…Ù†Ø°"
-  label_jump_to_a_project: Ø§Ù„Ø§Ù†ØªÙ‚Ø§Ù„ Ø¥Ù„Ù‰ Ù…Ø´Ø±ÙˆØ¹...
-  label_file_plural: Ø§Ù„Ù…Ù„ÙØ§Øª
-  label_changeset_plural: Ø§Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„ØªØºÙŠØ±
-  label_default_columns: Ø§Ù„Ø§Ø¹Ù…Ø¯Ø© Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
-  label_no_change_option: (Ø£ÙŠ ØªØºÙŠÙŠØ±)
-  label_bulk_edit_selected_issues: ØªØ­Ø±ÙŠØ± Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ù…Ø¸Ù„Ù„Ø©
-  label_bulk_edit_selected_time_entries: ØªØ¹Ø¯ÙŠÙ„ ÙƒÙ„ Ø§Ù„Ø¥Ø¯Ø®Ø§Ù„Ø§Øª ÙÙŠ ÙƒÙ„ Ø§Ù„Ø§ÙˆÙ‚Ø§Øª
-  label_theme: Ø§Ù„Ù…ÙˆØ¶ÙˆØ¹
-  label_default: Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ
-  label_search_titles_only: Ø§Ù„Ø¨Ø­Ø« ÙÙŠ Ø§Ù„Ø¹Ù†Ø§ÙˆÙŠÙ† ÙÙ‚Ø·
-  label_user_mail_option_all: "Ø¬Ù…ÙŠØ¹ Ø§Ù„Ø®ÙŠØ§Ø±Ø§Øª"
-  label_user_mail_option_selected: "Ø§Ù„Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„Ù…Ø¸Ù„Ù„Ø© ÙÙ‚Ø·"
-  label_user_mail_option_none: "Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ¯ Ø§ÙŠ Ø®ÙŠØ§Ø±Ø§Øª"
-  label_user_mail_option_only_my_events: "Ø§Ù„Ø³Ù…Ø§Ø­ Ù„ÙŠ ÙÙ‚Ø· Ø¨Ù…Ø´Ø§Ù‡Ø¯Ø© Ø§Ù„Ø§Ø­Ø¯Ø§Ø« Ø§Ù„Ø®Ø§ØµØ©"
-  label_user_mail_option_only_assigned: "ÙÙ‚Ø· Ø§Ù„Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„ØªÙŠ ØªÙ… ØªØ¹ÙŠÙŠÙ†Ù‡Ø§"
-  label_user_mail_option_only_owner: "ÙÙ‚Ø· Ù„Ù„Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„ØªÙŠ Ø§Ù…Ù„ÙƒÙ‡Ø§"
-  label_user_mail_no_self_notified: "Ù„Ø§ ØªØ±ÙŠØ¯ Ø§Ø¹Ù„Ø§Ù…Ùƒ Ø¨Ø§Ù„ØªØºÙŠØ±Ø§Øª Ø§Ù„ØªÙŠ ØªØ¬Ø±ÙŠÙ‡Ø§ Ø¨Ù†ÙØ³Ùƒ"
-  label_registration_activation_by_email: Ø­Ø³Ø§Ø¨ Ø§Ù„ØªÙ†Ø´ÙŠØ· Ø¹Ø¨Ø± Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  label_registration_manual_activation: ØªÙ†Ø´ÙŠØ· Ø§Ù„Ø­Ø³Ø§Ø¨ Ø§Ù„ÙŠØ¯ÙˆÙŠ
-  label_registration_automatic_activation: ØªÙ†Ø´ÙŠØ· Ø§Ù„Ø­Ø³Ø§Ø¨ Ø§Ù„ØªÙ„Ù‚Ø§Ø¦ÙŠ
-  label_display_per_page: "Ù„ÙƒÙ„ ØµÙØ­Ø©: %{value}"
-  label_age: Ø§Ù„Ø¹Ù…Ø±
-  label_change_properties: ØªØºÙŠÙŠØ± Ø§Ù„Ø®ØµØ§Ø¦Øµ
-  label_general: Ø¹Ø§Ù…Ø©
-  label_more: Ø£ÙƒØ«Ø±
-  label_scm: scm
-  label_plugins: Ø§Ù„Ø¥Ø¶Ø§ÙØ§Øª
-  label_ldap_authentication: Ù…ØµØ§Ø¯Ù‚Ø© LDAP
-  label_downloads_abbr: D/L
-  label_optional_description: ÙˆØµÙ Ø§Ø®ØªÙŠØ§Ø±ÙŠ
-  label_add_another_file: Ø¥Ø¶Ø§ÙØ© Ù…Ù„Ù Ø¢Ø®Ø±
-  label_preferences: ØªÙØ¶ÙŠÙ„Ø§Øª
-  label_chronological_order: ÙÙŠ ØªØ±ØªÙŠØ¨ Ø²Ù…Ù†ÙŠ
-  label_reverse_chronological_order: ÙÙŠ ØªØ±ØªÙŠØ¨ Ø²Ù…Ù†ÙŠ Ø¹ÙƒØ³ÙŠ
-  label_planning: Ø§Ù„ØªØ®Ø·ÙŠØ·
-  label_incoming_emails: Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ Ø§Ù„ÙˆØ§Ø±Ø¯
-  label_generate_key: Ø¥Ù†Ø´Ø§Ø¡ Ù…ÙØªØ§Ø­
-  label_issue_watchers: Ø§Ù„Ù…Ø±Ø§Ù‚Ø¨ÙˆÙ†
-  label_example: Ù…Ø«Ø§Ù„
-  label_display: Ø§Ù„Ø¹Ø±Ø¶
-  label_sort: ÙØ±Ø²
-  label_ascending: ØªØµØ§Ø¹Ø¯ÙŠ
-  label_descending: ØªÙ†Ø§Ø²Ù„ÙŠ
-  label_date_from_to: Ù…Ù† %{start} Ø§Ù„Ù‰ %{end}
-  label_wiki_content_added: Ø¥Ø¶Ø§ÙØ© ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ
-  label_wiki_content_updated: ØªØ­Ø¯ÙŠØ« ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ
-  label_group: Ù…Ø¬Ù…ÙˆØ¹Ø©
-  label_group_plural: Ø§Ù„Ù…Ø¬Ù…ÙˆØ¹Ø§Øª
-  label_group_new: Ù…Ø¬Ù…ÙˆØ¹Ø© Ø¬Ø¯ÙŠØ¯Ø©
-  label_time_entry_plural: Ø£Ù…Ø¶Ù‰ Ø¨Ø¹Ø¶ Ø§Ù„ÙˆÙ‚Øª
-  label_version_sharing_none: Ù„Ù… ÙŠØ´Ø§Ø±Ùƒ
-  label_version_sharing_descendants: ÙŠØ´Ø§Ø±Ùƒ
-  label_version_sharing_hierarchy: Ù…Ø¹ Ø§Ù„ØªØ³Ù„Ø³Ù„ Ø§Ù„Ù‡Ø±Ù…ÙŠ Ù„Ù„Ù…Ø´Ø±ÙˆØ¹
-  label_version_sharing_tree: Ù…Ø¹ Ø´Ø¬Ø±Ø© Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
-  label_version_sharing_system: Ù…Ø¹ Ø¬Ù…ÙŠØ¹ Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹
-  label_update_issue_done_ratios: ØªØ­Ø¯ÙŠØ« Ù‚Ø¶ÙŠØ©Ø§Ù„Ù†Ø³Ø¨
-  label_copy_source: Ù…ØµØ¯Ø±
-  label_copy_target: Ø§Ù„Ù‡Ø¯Ù
-  label_copy_same_as_target: Ù†ÙØ³ Ø§Ù„Ù‡Ø¯Ù
-  label_display_used_statuses_only: Ø¹Ø±Ø¶ Ø§Ù„Ø­Ø§Ù„Ø§Øª Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…Ø© Ù…Ù† Ù‚Ø¨Ù„ Ù‡Ø°Ø§ "ØªØ¹Ù‚Ø¨" ÙÙ‚Ø·
-  label_api_access_key: Ù…ÙØªØ§Ø­ Ø§Ù„ÙˆØµÙˆÙ„ Ø¥Ù„Ù‰ API
-  label_missing_api_access_key: API Ù„Ù… ÙŠØªÙ… Ø§Ù„Ø­ØµÙˆÙ„ Ø¹Ù„Ù‰ Ù…ÙØªØ§Ø­ Ø§Ù„ÙˆØµÙˆÙ„
-  label_api_access_key_created_on: " API  Ø¥Ù†Ø´Ø§Ø¡ Ù…ÙØªØ§Ø­ Ø§Ù„ÙˆØµÙˆÙ„ Ø¥Ù„Ù‰"
-  label_profile: Ø§Ù„Ù…Ù„Ù Ø§Ù„Ø´Ø®ØµÙŠ
-  label_subtask_plural: Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ÙØ±Ø¹ÙŠØ©
-  label_project_copy_notifications: Ø¥Ø±Ø³Ø§Ù„ Ø¥Ø´Ø¹Ø§Ø± Ø§Ù„Ù‰ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø¥Ù„ÙƒØªØ±ÙˆÙ†ÙŠ Ø¹Ù†Ø¯ Ù†Ø³Ø® Ø§Ù„Ù…Ø´Ø±ÙˆØ¹
-  label_principal_search: "Ø§Ù„Ø¨Ø­Ø« Ø¹Ù† Ù…Ø³ØªØ®Ø¯Ù… Ø£Ùˆ Ù…Ø¬Ù…ÙˆØ¹Ø©:"
-  label_user_search: "Ø§Ù„Ø¨Ø­Ø« Ø¹Ù† Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…:"
-  label_additional_workflow_transitions_for_author: Ø§Ù„Ø§Ù†ØªÙ‚Ø§Ù„Ø§Øª Ø§Ù„Ø¥Ø¶Ø§ÙÙŠØ© Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¨Ù‡Ø§ Ø¹Ù†Ø¯ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… ØµØ§Ø­Ø¨ Ø§Ù„Ø¨Ù„Ø§Øº
-  label_additional_workflow_transitions_for_assignee: Ø§Ù„Ø§Ù†ØªÙ‚Ø§Ù„Ø§Øª Ø§Ù„Ø¥Ø¶Ø§ÙÙŠØ© Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¨Ù‡Ø§ Ø¹Ù†Ø¯ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù… Ø§Ù„Ù…Ø­Ø§Ù„ Ø¥Ù„ÙŠÙ‡
-  label_issues_visibility_all: Ø¬Ù…ÙŠØ¹ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§
-  label_issues_visibility_public: Ø¬Ù…ÙŠØ¹ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„Ø®Ø§ØµØ©
-  label_issues_visibility_own: Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ Ø§Ù„ØªÙŠ Ø£Ù†Ø´Ø£Ù‡Ø§ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
-  label_git_report_last_commit: Ø§Ø¹ØªÙ…Ø§Ø¯ Ø§Ù„ØªÙ‚Ø±ÙŠØ± Ø§Ù„Ø£Ø®ÙŠØ± Ù„Ù„Ù…Ù„ÙØ§Øª ÙˆØ§Ù„Ø¯Ù„Ø§Ø¦Ù„
-  label_parent_revision: Ø§Ù„ÙˆØ§Ù„Ø¯ÙŠÙ†
-  label_child_revision: Ø§Ù„Ø·ÙÙ„
-  label_export_options: "%{export_format} Ø®ÙŠØ§Ø±Ø§Øª Ø§Ù„ØªØµØ¯ÙŠØ±"
-
-  button_login: Ø¯Ø®ÙˆÙ„
-  button_submit: ØªØ«Ø¨ÙŠØª
-  button_save: Ø­ÙØ¸
-  button_check_all: Ù†Ø­Ø¯ÙŠØ¯ Ø§Ù„ÙƒÙ„
-  button_uncheck_all: Ø¹Ø¯Ù… ØªØ­Ø¯ÙŠØ¯ Ø§Ù„ÙƒÙ„
-  button_collapse_all:  ØªÙ‚Ù„ÙŠØµ Ø§Ù„ÙƒÙ„
-  button_expand_all: Ø¹Ø±Ø¶ Ø§Ù„ÙƒÙ„
-  button_delete: Ø­Ø°Ù
-  button_create: Ø§Ù†Ø´Ø§Ø¡
-  button_create_and_continue: Ø§Ù†Ø´Ø§Ø¡ ÙˆØ§Ø³ØªÙ…Ø±Ø§Ø±
-  button_test: Ø§Ø®ØªØ¨Ø§Ø±
-  button_edit: ØªØ¹Ø¯ÙŠÙ„
-  button_edit_associated_wikipage: "ØªØºÙŠØ± ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ: %{page_title}"
-  button_add: Ø§Ø¶Ø§ÙØ©
-  button_change: ØªØºÙŠØ±
-  button_apply: ØªØ·Ø¨ÙŠÙ‚
-  button_clear: ÙˆØ§Ø¶Ø­
-  button_lock: Ù‚ÙÙ„
-  button_unlock: Ø§Ù„ØºØ§Ø¡ Ø§Ù„Ù‚ÙÙ„
-  button_download: ØªÙ†Ø²ÙŠÙ„
-  button_list: Ù‚Ø§Ø¦Ù…Ø©
-  button_view: Ø¹Ø±Ø¶
-  button_move: ØªØ­Ø±Ùƒ
-  button_move_and_follow: ØªØ­Ø±Ùƒ ÙˆØ§ØªØ¨Ø¹
-  button_back: Ø±Ø¬ÙˆØ¹
-  button_cancel: Ø¥Ù„ØºØ§Ø¡
-  button_activate: ØªÙ†Ø´ÙŠØ·
-  button_sort: ØªØ±ØªÙŠØ¨
-  button_log_time: ÙˆÙ‚Øª Ø§Ù„Ø¯Ø®ÙˆÙ„
-  button_rollback: Ø§Ù„Ø±Ø¬ÙˆØ¹ Ø§Ù„Ù‰ Ù‡Ø°Ø§ Ø§Ù„Ø§ØµØ¯Ø§Ø±
-  button_watch: ÙŠØ´Ø§Ù‡Ø¯
-  button_unwatch: Ø¥Ù„ØºØ§Ø¡ Ø§Ù„Ù…Ø´Ø§Ù‡Ø¯Ø©
-  button_reply: Ø±Ø¯
-  button_archive: Ø§Ù„Ø§Ø±Ø´ÙŠÙ
-  button_unarchive: Ø¥Ù„ØºØ§Ø¡ Ø§Ù„Ø§Ø±Ø´ÙØ©
-  button_reset: Ø¥Ø¹Ø§Ø¯Ø©
-  button_rename: Ø¥Ø¹Ø§Ø¯Ø© Ø§Ù„ØªØ³Ù…ÙŠØ©
-  button_change_password: ØªØºÙŠØ± ÙƒÙ„Ù…Ø© Ø§Ù„Ù…Ø±ÙˆØ±
-  button_copy: Ù†Ø³Ø®
-  button_copy_and_follow: Ù†Ø³Ø® ÙˆØ§ØªØ¨Ø§Ø¹
-  button_annotate: ØªØ¹Ù„ÙŠÙ‚
-  button_update: ØªØ­Ø¯ÙŠØ«
-  button_configure: ØªÙƒÙˆÙŠÙ†
-  button_quote: ÙŠÙ‚ØªØ¨Ø³
-  button_duplicate: ÙŠØ¶Ø§Ø¹Ù
-  button_show: ÙŠØ¸Ù‡Ø±
-  button_edit_section: ÙŠØ¹Ø¯Ù„ Ù‡Ø°Ø§ Ø§Ù„Ø¬Ø²Ø¡
-  button_export: ÙŠØ³ØªÙˆØ±Ø¯
-
-  status_active: Ù†Ø´ÙŠØ·
-  status_registered: Ù…Ø³Ø¬Ù„
-  status_locked: Ù…Ù‚ÙÙ„
-
-  version_status_open: Ù…ÙØªÙˆØ­
-  version_status_locked: Ù…Ù‚ÙÙ„
-  version_status_closed: Ù…ØºÙ„Ù‚
-
-  field_active: ÙØ¹Ø§Ù„
-
-  text_select_mail_notifications: Ø­Ø¯Ø¯ Ø§Ù„Ø§Ù…ÙˆØ± Ø§Ù„ØªÙŠ ÙŠØ¬Ø¨ Ø§Ø¨Ù„Ø§ØºÙƒ Ø¨Ù‡Ø§ Ø¹Ù† Ø·Ø±ÙŠÙ‚ Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  text_regexp_info: Ù…Ø«Ø§Ù„. ^[A-Z0-9]+$
-  text_min_max_length_info: Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ ÙˆØ§Ù„Ø§Ø¯Ù†ÙŠ Ù„Ø·ÙˆÙ„ Ø§Ù„Ù…Ø¹Ù„ÙˆÙ…Ø§Øª
-  text_project_destroy_confirmation: Ù‡Ù„ Ø£Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø£Ù†Ùƒ ØªØ±ÙŠØ¯ Ø­Ø°Ù Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ ÙˆØ§Ù„Ø¨ÙŠØ§Ù†Ø§Øª Ø°Ø§Øª Ø§Ù„ØµÙ„Ø©ØŸ
-  text_subprojects_destroy_warning: "subproject(s): Ø³ÙŠØªÙ… Ø­Ø°Ù Ø£ÙŠØ¶Ø§."
-  text_workflow_edit: Ø­Ø¯Ø¯ Ø¯ÙˆØ±Ø§Ù‹ ÙˆØªØ¹Ù‚Ø¨ Ù„ØªØ­Ø±ÙŠØ± Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„
-  text_are_you_sure: Ù‡Ù„ Ø£Ù†Øª Ù…ØªØ£ÙƒØ¯ØŸ
-  text_are_you_sure_with_children: "Ø­Ø°Ù Ø§Ù„Ù…ÙˆØ¶ÙˆØ¹ ÙˆØ¬Ù…ÙŠØ¹ Ø§Ù„Ù…Ø³Ø§Ø¦Ù„ Ø§Ù„Ù…ØªØ¹Ù„Ù‚Ø© Ø¨Ø§Ù„Ø·ÙÙ„ØŸ"
-  text_journal_changed: "%{label} ØªØºÙŠØ± %{old} Ø§Ù„Ù‰ %{new}"
-  text_journal_changed_no_detail: "%{label} ØªÙ… Ø§Ù„ØªØ­Ø¯ÙŠØ«"
-  text_journal_set_to: "%{label} ØªØºÙŠØ± Ø§Ù„Ù‰ %{value}"
-  text_journal_deleted: "%{label} ØªÙ… Ø§Ù„Ø­Ø°Ù (%{old})"
-  text_journal_added: "%{label} %{value} ØªÙ… Ø§Ù„Ø§Ø¶Ø§ÙØ©"
-  text_tip_issue_begin_day: Ù‚Ø¶ÙŠØ© Ø¨Ø¯Ø£Øª Ø§Ù„ÙŠÙˆÙ…
-  text_tip_issue_end_day: Ù‚Ø¶ÙŠØ© Ø§Ù†ØªÙ‡Øª Ø§Ù„ÙŠÙˆÙ…
-  text_tip_issue_begin_end_day: Ù‚Ø¶ÙŠØ© Ø¨Ø¯Ø£Øª ÙˆØ§Ù†ØªÙ‡Øª Ø§Ù„ÙŠÙˆÙ…
-  text_caracters_maximum: "%{count} Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰."
-  text_caracters_minimum: "Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ø¯Ù†Ù‰  %{count}"
-  text_length_between: "Ø§Ù„Ø·ÙˆÙ„ %{min} Ø¨ÙŠÙ† %{max} Ø±Ù…Ø²"
-  text_tracker_no_workflow: Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ¯ Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„ Ù„Ù‡Ø°Ø§ Ø§Ù„Ù…ØªØªØ¨Ø¹
-  text_unallowed_characters: Ø±Ù…ÙˆØ² ØºÙŠØ± Ù…Ø³Ù…ÙˆØ­Ø©
-  text_comma_separated: Ù…Ø³Ù…ÙˆØ­ Ø±Ù…ÙˆØ² Ù…ØªÙ†ÙˆØ¹Ø© ÙŠÙØµÙ„Ù‡Ø§ ÙØ§ØµÙ„Ø© .
-  text_line_separated: Ù…Ø³Ù…ÙˆØ­ Ø±Ù…ÙˆØ² Ù…ØªÙ†ÙˆØ¹Ø© ÙŠÙØµÙ„Ù‡Ø§ Ø³Ø·ÙˆØ±
-  text_issues_ref_in_commit_messages: Ø§Ù„Ø±Ø¬ÙˆØ¹ ÙˆØ§ØµÙ„Ø§Ø­ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§ ÙÙŠ Ø±Ø³Ø§Ø¦Ù„ Ø§Ù„Ù…Ø´ØªÙƒÙŠÙ†
-  text_issue_added: "Ø§Ù„Ù‚Ø¶ÙŠØ© %{id} ØªÙ… Ø§Ø¨Ù„Ø§ØºÙ‡Ø§ Ø¹Ù† Ø·Ø±ÙŠÙ‚ %{author}."
-  text_issue_updated: "Ø§Ù„Ù‚Ø¶ÙŠØ© %{id} ØªÙ… ØªØ­Ø¯ÙŠØ«Ù‡Ø§ Ø¹Ù† Ø·Ø±ÙŠÙ‚ %{author}."
-  text_wiki_destroy_confirmation: Ù‡Ù„ Ø§Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø±ØºØ¨ØªÙƒ ÙÙŠ Ø­Ø°Ù Ù‡Ø°Ø§ Ø§Ù„ÙˆÙŠÙƒÙŠ ÙˆÙ…Ø­ØªÙˆÙŠØ§ØªÙ‡ØŸ
-  text_issue_category_destroy_question: "Ø¨Ø¹Ø¶ Ø§Ù„Ù‚Ø¶Ø§ÙŠØ§  (%{count}) Ù…Ø±ØªØ¨Ø·Ø© Ø¨Ù‡Ø°Ù‡ Ø§Ù„ÙØ¦Ø©ØŒ Ù…Ø§Ø°Ø§ ØªØ±ÙŠØ¯ Ø§Ù† ØªÙØ¹Ù„ Ø¨Ù‡Ø§ØŸ"
-  text_issue_category_destroy_assignments: Ø­Ø°Ù Ø§Ù„ÙØ¦Ø©
-  text_issue_category_reassign_to: Ø§Ø¹Ø§Ø¯Ø© ØªØ«Ø¨ÙŠØª Ø§Ù„Ø¨Ù†ÙˆØ¯ ÙÙŠ Ø§Ù„ÙØ¦Ø©
-  text_user_mail_option: "Ø¨Ø§Ù„Ù†Ø³Ø¨Ø© Ù„Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ ØºÙŠØ± Ø§Ù„Ù…Ø­Ø¯Ø¯Ø©ØŒ Ø³ÙˆÙ ÙŠØªÙ… Ø§Ø¨Ù„Ø§ØºÙƒ Ø¹Ù† Ø§Ù„Ù…Ø´Ø§Ø±ÙŠØ¹ Ø§Ù„ØªÙŠ ØªØ´Ø§Ù‡Ø¯Ù‡Ø§ Ø§Ùˆ ØªØ´Ø§Ø±Ùƒ Ø¨Ù‡Ø§ ÙÙ‚Ø·!"
-  text_no_configuration_data: "Ø§Ù„Ø§Ø¯ÙˆØ§Ø± ÙˆØ§Ù„Ù…ØªØªØ¨Ø¹ ÙˆØ­Ø§Ù„Ø§Øª Ø§Ù„Ù‚Ø¶ÙŠØ© ÙˆÙ…Ø®Ø·Ø· Ø³ÙŠØ± Ø§Ù„Ø¹Ù…Ù„ Ù„Ù… ÙŠØªÙ… ØªØ­Ø¯ÙŠØ¯ ÙˆØ¶Ø¹Ù‡Ø§ Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ Ø¨Ø¹Ø¯. "
-  text_load_default_configuration: Ø§Ø­Ù…Ù„ Ø§Ù„Ø§Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©
-  text_status_changed_by_changeset: " Ø·Ø¨Ù‚ Ø§Ù„ØªØºÙŠØ±Ø§Øª Ø§Ù„Ù…Ø¹ÙŠÙ†Ø© Ø¹Ù„Ù‰ %{value}."
-  text_time_logged_by_changeset: "ØªÙ… ØªØ·Ø¨ÙŠÙ‚ Ø§Ù„ØªØºÙŠØ±Ø§Øª Ø§Ù„Ù…Ø¹ÙŠÙ†Ø© Ø¹Ù„Ù‰  %{value}."
-  text_issues_destroy_confirmation: Ù‡Ù„ Ø§Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø­Ø°Ù Ø§Ù„Ø¨Ù†ÙˆØ¯ Ø§Ù„Ù…Ø¸Ù„Ù„Ø©ØŸ'
-  text_issues_destroy_descendants_confirmation: "Ø³ÙˆÙ ÙŠØ¤Ø¯ÙŠ Ù‡Ø°Ø§ Ø§Ù„Ù‰ Ø­Ø°Ù  %{count} Ø§Ù„Ù…Ù‡Ø§Ù… Ø§Ù„ÙØ±Ø¹ÙŠØ© Ø§ÙŠØ¶Ø§."
-  text_time_entries_destroy_confirmation: "Ù‡Ù„ Ø§Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø±ØºØ¨ØªÙƒ ÙÙŠ Ø­Ø°Ù Ø§Ù„Ø§Ø¯Ø®Ø§Ù„Ø§Øª Ø§Ù„Ø²Ù…Ù†ÙŠØ© Ø§Ù„Ù…Ø­Ø¯Ø¯Ø©ØŸ"
-  text_select_project_modules: Ù‚Ù… Ø¨ØªØ­Ø¯ÙŠØ¯ Ø§Ù„ÙˆØ¶Ø¹ Ø§Ù„Ù…Ù†Ø§Ø³Ø¨ Ù„Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹:'
-  text_default_administrator_account_changed: ØªÙ… ØªØ¹Ø¯ÙŠÙ„ Ø§Ù„Ø§Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ© Ù„Ø­Ø³Ø§Ø¨ Ø§Ù„Ù…Ø¯ÙŠØ±
-  text_file_repository_writable: Ø§Ù„Ù…Ø±ÙÙ‚Ø§Øª Ù‚Ø§Ø¨Ù„Ø© Ù„Ù„ÙƒØªØ§Ø¨Ø©
-  text_plugin_assets_writable: Ø§Ù„Ø¯Ù„ÙŠÙ„ Ø§Ù„Ù…Ø³Ø§Ø¹Ø¯ Ù‚Ø§Ø¨Ù„ Ù„Ù„ÙƒØªØ§Ø¨Ø©
-  text_destroy_time_entries_question: " Ø³Ø§Ø¹Ø© Ø¹Ù„Ù‰ Ø§Ù„Ù‚Ø¶ÙŠØ© Ø§Ù„ØªÙŠ ØªÙˆØ¯ Ø­Ø°ÙÙ‡Ø§ØŒ Ù…Ø§Ø°Ø§ ØªØ±ÙŠØ¯ Ø§Ù† ØªÙØ¹Ù„ØŸ %{hours} ØªÙ… ØªØ«Ø¨ÙŠØª"
-  text_destroy_time_entries: Ù‚Ù… Ø¨Ø­Ø°Ù Ø§Ù„Ø³Ø§Ø¹Ø§Øª Ø§Ù„Ù…Ø³Ø¬Ù„Ø©
-  text_assign_time_entries_to_project: Ø«Ø¨Øª Ø§Ù„Ø³Ø§Ø¹Ø§Øª Ø§Ù„Ù…Ø³Ø¬Ù„Ø© Ø¹Ù„Ù‰ Ø§Ù„ØªÙ‚Ø±ÙŠØ±
-  text_reassign_time_entries: 'Ø§Ø¹Ø§Ø¯Ø© ØªØ«Ø¨ÙŠØª Ø§Ù„Ø³Ø§Ø¹Ø§Øª Ø§Ù„Ù…Ø³Ø¬Ù„Ø© Ù„Ù‡Ø°Ù‡ Ø§Ù„Ù‚Ø¶ÙŠØ©:'
-  text_user_wrote: "%{value} ÙƒØªØ¨:"
-  text_enumeration_destroy_question: "%{count} Ø§Ù„ÙƒØ§Ø¦Ù†Ø§Øª Ø§Ù„Ù…Ø¹Ù†ÙŠØ© Ù„Ù‡Ø°Ù‡ Ø§Ù„Ù‚ÙŠÙ…Ø©"
-  text_enumeration_category_reassign_to: Ø§Ø¹Ø§Ø¯Ø© ØªØ«Ø¨ÙŠØª Ø§Ù„ÙƒØ§Ø¦Ù†Ø§Øª Ø§Ù„ØªØ§Ù„ÙŠØ© Ù„Ù‡Ø°Ù‡ Ø§Ù„Ù‚ÙŠÙ…Ø©:'
-  text_email_delivery_not_configured: "Ù„Ù… ÙŠØªÙ… ØªØ³Ù„ÙŠÙ… Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ"
-  text_diff_truncated: '... Ù„Ù‚Ø¯ ØªÙ… Ø§Ù‚ØªØ·Ù„Ø¹ Ù‡Ø°Ø§ Ø§Ù„Ø¬Ø²Ø¡ Ù„Ø§Ù†Ù‡ ØªØ¬Ø§ÙˆØ² Ø§Ù„Ø­Ø¯ Ø§Ù„Ø§Ù‚ØµÙ‰ Ø§Ù„Ù…Ø³Ù…ÙˆØ­ Ø¨Ø¹Ø±Ø¶Ù‡'
-  text_custom_field_possible_values_info: 'Ø³Ø·Ø± Ù„ÙƒÙ„ Ù‚ÙŠÙ…Ø©'
-  text_wiki_page_nullify_children: "Ø§Ù„Ø§Ø­ØªÙØ§Ø¸ Ø¨ØµÙØ­Ø§Øª Ø§Ù„Ø·ÙÙ„ ÙƒØµÙØ­Ø§Øª Ø¬Ø°Ø±"
-  text_wiki_page_destroy_children: "Ø­Ø°Ù ØµÙØ­Ø§Øª Ø§Ù„Ø·ÙÙ„ ÙˆØ¬Ù…ÙŠØ¹ Ø£ÙˆÙ„Ø§Ø¯Ù‡Ù…"
-  text_wiki_page_reassign_children: "Ø¥Ø¹Ø§Ø¯Ø© ØªØ¹ÙŠÙŠÙ† ØµÙØ­Ø§Øª ØªØ§Ø¨Ø¹Ø© Ù„Ù‡Ø°Ù‡ Ø§Ù„ØµÙØ­Ø© Ø§Ù„Ø£ØµÙ„ÙŠØ©"
-  text_own_membership_delete_confirmation: "Ø§Ù†Øª Ø¹Ù„Ù‰ ÙˆØ´Ùƒ Ø¥Ø²Ø§Ù„Ø© Ø¨Ø¹Ø¶ Ø£Ùˆ ÙƒØ§ÙØ© Ø§Ù„Ø£Ø°ÙˆÙ†Ø§Øª Ø§Ù„Ø®Ø§ØµØ© Ø¨ÙƒØŒ Ù„Ù† ØªÙƒÙˆÙ† Ù‚Ø§Ø¯Ø±Ø§Ù‹ Ø¹Ù„Ù‰ ØªØ­Ø±ÙŠØ± Ù‡Ø°Ø§ Ø§Ù„Ù…Ø´Ø±ÙˆØ¹ Ø¨Ø¹Ø¯ Ø°Ù„Ùƒ. Ù‡Ù„ Ø£Ù†Øª Ù…ØªØ£ÙƒØ¯ Ù…Ù† Ø£Ù†Ùƒ ØªØ±ÙŠØ¯ Ø§Ù„Ù…ØªØ§Ø¨Ø¹Ø©ØŸ"
-  text_zoom_in: ØªØµØºÙŠØ±
-  text_zoom_out: ØªÙƒØ¨ÙŠØ±
-  text_warn_on_leaving_unsaved: "Ø§Ù„ØµÙØ­Ø© ØªØ­ØªÙˆÙŠ Ø¹Ù„Ù‰ Ù†Øµ ØºÙŠØ± Ù…Ø®Ø²Ù†ØŒ Ø³ÙˆÙ ÙŠÙÙ‚Ø¯ Ø§Ù„Ù†Øµ Ø§Ø°Ø§ ØªÙ… Ø§Ù„Ø®Ø±ÙˆØ¬ Ù…Ù† Ø§Ù„ØµÙØ­Ø©."
-  text_scm_path_encoding_note: "Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ: UTF-8"
-  text_git_repository_note: Ù…Ø³ØªÙˆØ¯Ø¹ ÙØ§Ø±Øº ÙˆÙ…Ø­Ù„ÙŠ
-  text_mercurial_repository_note: Ù…Ø³ØªÙˆØ¯Ø¹ Ù…Ø­Ù„ÙŠ
-  text_scm_command: Ø§Ù…Ø±
-  text_scm_command_version: Ø§ØµØ¯Ø§Ø±
-  text_scm_config: Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ø¹Ø§Ø¯Ø© ØªØ´ØºÙŠÙ„ Ø§Ù„ØªØ·Ø¨ÙŠÙ‚
-  text_scm_command_not_available: Ø§Ù„Ø§Ù…Ø± ØºÙŠØ± Ù…ØªÙˆÙØ±ØŒ Ø§Ù„Ø±Ø¬Ø§Ø¡ Ø§Ù„ØªØ­Ù‚Ù‚ Ù…Ù† Ù„ÙˆØ­Ø© Ø§Ù„ØªØ­ÙƒÙ…
-
-  default_role_manager: Ù…Ø¯ÙŠØ±
-  default_role_developer: Ù…Ø·ÙˆØ±
-  default_role_reporter: Ù…Ø±Ø§Ø³Ù„
-  default_tracker_bug: Ø§Ù„Ø´ÙˆØ§Ø¦Ø¨
-  default_tracker_feature: Ø®Ø§ØµÙŠØ©
-  default_tracker_support: Ø¯Ø¹Ù…
-  default_issue_status_new: Ø¬Ø¯ÙŠØ¯
-  default_issue_status_in_progress: Ø¬Ø§Ø±ÙŠ Ø§Ù„ØªØ­Ù…ÙŠÙ„
-  default_issue_status_resolved: Ø§Ù„Ø­Ù„
-  default_issue_status_feedback: Ø§Ù„ØªØºØ°ÙŠØ© Ø§Ù„Ø±Ø§Ø¬Ø¹Ø©
-  default_issue_status_closed: Ù…ØºÙ„Ù‚
-  default_issue_status_rejected: Ù…Ø±ÙÙˆØ¶
-  default_doc_category_user: Ù…Ø³ØªÙ†Ø¯Ø§Øª Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…
-  default_doc_category_tech: Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª Ø§Ù„ØªÙ‚Ù†ÙŠØ©
-  default_priority_low: Ù‚Ù„ÙŠÙ„
-  default_priority_normal: Ø¹Ø§Ø¯ÙŠ
-  default_priority_high: Ø¹Ø§Ù„ÙŠ
-  default_priority_urgent: Ø·Ø§Ø±Ø¦
-  default_priority_immediate: Ù…Ø¨Ø§Ø´Ø±Ø©
-  default_activity_design: ØªØµÙ…ÙŠÙ…
-  default_activity_development: ØªØ·ÙˆÙŠØ±
-
-  enumeration_issue_priorities: Ø§Ù„Ø§ÙˆÙ„ÙˆÙŠØ§Øª
-  enumeration_doc_categories: ØªØµÙ†ÙŠÙ Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª
-  enumeration_activities: Ø§Ù„Ø§Ù†Ø´Ø·Ø©
-  enumeration_system_activity: Ù†Ø´Ø§Ø· Ø§Ù„Ù†Ø¸Ø§Ù…
-  description_filter: ÙÙ„ØªØ±Ø©
-  description_search: Ø­Ù‚Ù„ Ø§Ù„Ø¨Ø­Ø«
-  description_choose_project: Ù…Ø´Ø§Ø±ÙŠØ¹
-  description_project_scope: Ù…Ø¬Ø§Ù„ Ø§Ù„Ø¨Ø­Ø«
-  description_notes: Ù…Ù„Ø§Ø­Ø¸Ø§Øª
-  description_message_content: Ù…Ø­ØªÙˆÙŠØ§Øª Ø§Ù„Ø±Ø³Ø§Ù„Ø©
-  description_query_sort_criteria_attribute: Ù†ÙˆØ¹ Ø§Ù„ØªØ±ØªÙŠØ¨
-  description_query_sort_criteria_direction: Ø§ØªØ¬Ø§Ù‡ Ø§Ù„ØªØ±ØªÙŠØ¨
-  description_user_mail_notification: Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§Ù„Ø¨Ø±ÙŠØ¯ Ø§Ù„Ø§Ù„ÙƒØªØ±ÙˆÙ†ÙŠ
-  description_available_columns: Ø§Ù„Ø§Ø¹Ù…Ø¯Ø© Ø§Ù„Ù…ØªÙˆÙØ±Ø©
-  description_selected_columns: Ø§Ù„Ø§Ø¹Ù…Ø¯Ø© Ø§Ù„Ù…Ø­Ø¯Ø¯Ø©
-  description_all_columns: ÙƒÙ„ Ø§Ù„Ø§Ø¹Ù…Ø¯Ø©
-  description_issue_category_reassign: Ø§Ø®ØªØ± Ø§Ù„ØªØµÙ†ÙŠÙ
-  description_wiki_subpages_reassign: Ø§Ø®ØªØ± ØµÙØ­Ø© Ø¬Ø¯ÙŠØ¯Ø©
-  description_date_range_list: Ø§Ø®ØªØ± Ø§Ù„Ù…Ø¬Ø§Ù„ Ù…Ù† Ø§Ù„Ù‚Ø§Ø¦Ù…Ø©
-  description_date_range_interval: Ø§Ø®ØªØ± Ø§Ù„Ù…Ø¯Ø© Ø¹Ù† Ø·Ø±ÙŠÙ‚ Ø§Ø®ØªÙŠØ§Ø± ØªØ§Ø±ÙŠØ® Ø§Ù„Ø¨Ø¯Ø§ÙŠØ© ÙˆØ§Ù„Ù†Ù‡Ø§ÙŠØ©
-  description_date_from: Ø§Ø¯Ø®Ù„ ØªØ§Ø±ÙŠØ® Ø§Ù„Ø¨Ø¯Ø§ÙŠØ©
-  description_date_to: Ø§Ø¯Ø®Ù„ ØªØ§Ø±ÙŠØ® Ø§Ù„Ø§Ù†ØªÙ‡Ø§Ø¡
-  text_rmagick_available: RMagick available (optional)
-  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
-  text_project_identifier_info: Only lower case letters (a-z), numbers and dashes are allowed.<br />Once saved, the identifier cannot be changed.
-  text_repository_usernames_mapping: |-
-    Select or update the Redmine user mapped to each username found in the repository log.
-    Users with the same Redmine and repository username or email are automatically mapped.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/67/674b8036a925ccf2c9ef3d3610ab9b8e2eef3746.svn-base
--- a/.svn/pristine/67/674b8036a925ccf2c9ef3d3610ab9b8e2eef3746.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-def deprecated_task(name, new_name)
-  task name=>new_name do 
-    $stderr.puts "\nNote: The rake task #{name} has been deprecated, please use the replacement version #{new_name}"
-  end
-end
-
-deprecated_task :load_default_data, "redmine:load_default_data"
-deprecated_task :migrate_from_mantis, "redmine:migrate_from_mantis"
-deprecated_task :migrate_from_trac, "redmine:migrate_from_trac"
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/67/67867a3abe62489d5d689d70198440d4c835b00f.svn-base
--- /dev/null
+++ b/.svn/pristine/67/67867a3abe62489d5d689d70198440d4c835b00f.svn-base
@@ -0,0 +1,1090 @@
+# Serbian translations for Redmine
+# by Vladimir MedaroviÄ‡ (vlada@medarovic.com)
+sr:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d.%m.%Y."
+      short: "%e %b"
+      long: "%B %e, %Y"
+
+    day_names: [Ð½ÐµÐ´ÐµÑ™Ð°, Ð¿Ð¾Ð½ÐµÐ´ÐµÑ™Ð°Ðº, ÑƒÑ‚Ð¾Ñ€Ð°Ðº, ÑÑ€ÐµÐ´Ð°, Ñ‡ÐµÑ‚Ð²Ñ€Ñ‚Ð°Ðº, Ð¿ÐµÑ‚Ð°Ðº, ÑÑƒÐ±Ð¾Ñ‚Ð°]
+    abbr_day_names: [Ð½ÐµÐ´, Ð¿Ð¾Ð½, ÑƒÑ‚Ð¾, ÑÑ€Ðµ, Ñ‡ÐµÑ‚, Ð¿ÐµÑ‚, ÑÑƒÐ±]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Ñ˜Ð°Ð½ÑƒÐ°Ñ€, Ñ„ÐµÐ±Ñ€ÑƒÐ°Ñ€, Ð¼Ð°Ñ€Ñ‚, Ð°Ð¿Ñ€Ð¸Ð», Ð¼Ð°Ñ˜, Ñ˜ÑƒÐ½, Ñ˜ÑƒÐ», Ð°Ð²Ð³ÑƒÑÑ‚, ÑÐµÐ¿Ñ‚ÐµÐ¼Ð±Ð°Ñ€, Ð¾ÐºÑ‚Ð¾Ð±Ð°Ñ€, Ð½Ð¾Ð²ÐµÐ¼Ð±Ð°Ñ€, Ð´ÐµÑ†ÐµÐ¼Ð±Ð°Ñ€]
+    abbr_month_names: [~, Ñ˜Ð°Ð½, Ñ„ÐµÐ±, Ð¼Ð°Ñ€, Ð°Ð¿Ñ€, Ð¼Ð°Ñ˜, Ñ˜ÑƒÐ½, Ñ˜ÑƒÐ», Ð°Ð²Ð³, ÑÐµÐ¿, Ð¾ÐºÑ‚, Ð½Ð¾Ð², Ð´ÐµÑ†]
+    # Used in date_select and datime_select.
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%d.%m.%Y. Ñƒ %H:%M"
+      time: "%H:%M"
+      short: "%d. %b Ñƒ %H:%M"
+      long: "%d. %B %Y Ñƒ %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "Ð¿Ð¾Ð»Ð° Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
+      less_than_x_seconds:
+        one:   "Ð¼Ð°ÑšÐµ Ð¾Ð´ Ñ˜ÐµÐ´Ð½Ðµ ÑÐµÐºÑƒÐ½Ð´Ðµ"
+        other: "Ð¼Ð°ÑšÐµ Ð¾Ð´ %{count} ÑÐµÐº."
+      x_seconds:
+        one:   "Ñ˜ÐµÐ´Ð½Ð° ÑÐµÐºÑƒÐ½Ð´Ð°"
+        other: "%{count} ÑÐµÐº."
+      less_than_x_minutes:
+        one:   "Ð¼Ð°ÑšÐµ Ð¾Ð´ Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
+        other: "Ð¼Ð°ÑšÐµ Ð¾Ð´ %{count} Ð¼Ð¸Ð½."
+      x_minutes:
+        one:   "Ñ˜ÐµÐ´Ð°Ð½ Ð¼Ð¸Ð½ÑƒÑ‚"
+        other: "%{count} Ð¼Ð¸Ð½."
+      about_x_hours:
+        one:   "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ Ñ˜ÐµÐ´Ð°Ð½ ÑÐ°Ñ‚"
+        other: "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ %{count} ÑÐ°Ñ‚Ð¸"
+      x_hours:
+        one:   "1 ÑÐ°Ñ‚"
+        other: "%{count} ÑÐ°Ñ‚Ð¸"
+      x_days:
+        one:   "Ñ˜ÐµÐ´Ð°Ð½ Ð´Ð°Ð½"
+        other: "%{count} Ð´Ð°Ð½Ð°"
+      about_x_months:
+        one:   "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ Ñ˜ÐµÐ´Ð°Ð½ Ð¼ÐµÑÐµÑ†"
+        other: "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ %{count} Ð¼ÐµÑÐµÑ†Ð¸"
+      x_months:
+        one:   "Ñ˜ÐµÐ´Ð°Ð½ Ð¼ÐµÑÐµÑ†"
+        other: "%{count} Ð¼ÐµÑÐµÑ†Ð¸"
+      about_x_years:
+        one:   "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ Ð³Ð¾Ð´Ð¸Ð½Ñƒ Ð´Ð°Ð½Ð°"
+        other: "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ %{count} Ð³Ð¾Ð´."
+      over_x_years:
+        one:   "Ð¿Ñ€ÐµÐºÐ¾ Ð³Ð¾Ð´Ð¸Ð½Ñƒ Ð´Ð°Ð½Ð°"
+        other: "Ð¿Ñ€ÐµÐºÐ¾ %{count} Ð³Ð¾Ð´."
+      almost_x_years:
+        one:   "ÑÐºÐ¾Ñ€Ð¾ Ð³Ð¾Ð´Ð¸Ð½Ñƒ Ð´Ð°Ð½Ð°"
+        other: "ÑÐºÐ¾Ñ€Ð¾ %{count} Ð³Ð¾Ð´."
+
+  number:
+    format:
+      separator: ","
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "Ð¸"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "Ð½Ð¸Ñ˜Ðµ ÑƒÐºÑ™ÑƒÑ‡ÐµÐ½ Ñƒ ÑÐ¿Ð¸ÑÐ°Ðº"
+        exclusion: "Ñ˜Ðµ Ñ€ÐµÐ·ÐµÑ€Ð²Ð¸ÑÐ°Ð½"
+        invalid: "Ñ˜Ðµ Ð½ÐµÐ¸ÑÐ¿Ñ€Ð°Ð²Ð°Ð½"
+        confirmation: "Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ð° Ð½Ðµ Ð¾Ð´Ð³Ð¾Ð²Ð°Ñ€Ð°"
+        accepted: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¿Ñ€Ð¸Ñ…Ð²Ð°Ñ›ÐµÐ½"
+        empty: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
+        blank: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
+        too_long: "Ñ˜Ðµ Ð¿Ñ€ÐµÐ´ÑƒÐ³Ð°Ñ‡ÐºÐ° (Ð¼Ð°ÐºÑÐ¸Ð¼ÑƒÐ¼ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ñ˜Ðµ %{count})"
+        too_short: "Ñ˜Ðµ Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‚ÐºÐ° (Ð¼Ð¸Ð½Ð¸Ð¼ÑƒÐ¼ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ñ˜Ðµ %{count})"
+        wrong_length: "Ñ˜Ðµ Ð¿Ð¾Ð³Ñ€ÐµÑˆÐ½Ðµ Ð´ÑƒÐ¶Ð¸Ð½Ðµ (Ð±Ñ€Ð¾Ñ˜ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ %{count})"
+        taken: "Ñ˜Ðµ Ð²ÐµÑ› Ñƒ ÑƒÐ¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸"
+        not_a_number: "Ð½Ð¸Ñ˜Ðµ Ð±Ñ€Ð¾Ñ˜"
+        not_a_date: "Ð½Ð¸Ñ˜Ðµ Ð¸ÑÐ¿Ñ€Ð°Ð²Ð°Ð½ Ð´Ð°Ñ‚ÑƒÐ¼"
+        greater_than: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð²ÐµÑ›Ð¸ Ð¾Ð´ %{count}"
+        greater_than_or_equal_to: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð²ÐµÑ›Ð¸ Ð¸Ð»Ð¸ Ñ˜ÐµÐ´Ð½Ð°Ðº %{count}"
+        equal_to: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ñ˜ÐµÐ´Ð½Ð°Ðº %{count}"
+        less_than: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¼Ð°ÑšÐ¸ Ð¾Ð´ %{count}"
+        less_than_or_equal_to: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¼Ð°ÑšÐ¸ Ð¸Ð»Ð¸ Ñ˜ÐµÐ´Ð½Ð°Ðº %{count}"
+        odd: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¿Ð°Ñ€Ð°Ð½"
+        even: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð½ÐµÐ¿Ð°Ñ€Ð°Ð½"
+        greater_than_start_date: "Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð²ÐµÑ›Ð¸ Ð¾Ð´ Ð¿Ð¾Ñ‡ÐµÑ‚Ð½Ð¾Ð³ Ð´Ð°Ñ‚ÑƒÐ¼Ð°"
+        not_same_project: "Ð½Ðµ Ð¿Ñ€Ð¸Ð¿Ð°Ð´Ð° Ð¸ÑÑ‚Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ñƒ"
+        circular_dependency: "ÐžÐ²Ð° Ð²ÐµÐ·Ð° Ñ›Ðµ ÑÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ ÐºÑ€ÑƒÐ¶Ð½Ñƒ Ñ€ÐµÑ„ÐµÑ€ÐµÐ½Ñ†Ñƒ"
+        cant_link_an_issue_with_a_descendant: "ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½ ÑÐ° Ñ˜ÐµÐ´Ð½Ð¸Ð¼ Ð¾Ð´ ÑÐ²Ð¾Ñ˜Ð¸Ñ… Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‚Ð°ÐºÐ°"
+
+  actionview_instancetag_blank_option: ÐœÐ¾Ð»Ð¸Ð¼ Ð¾Ð´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ
+
+  general_text_No: 'ÐÐµ'
+  general_text_Yes: 'Ð”Ð°'
+  general_text_no: 'Ð½Ðµ'
+  general_text_yes: 'Ð´Ð°'
+  general_lang_name: 'Serbian Cyrillic (Ð¡Ñ€Ð¿ÑÐºÐ¸)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: ÐÐ°Ð»Ð¾Ð³ Ñ˜Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½.
+  notice_account_invalid_creditentials: ÐÐµÐ¸ÑÐ¿Ñ€Ð°Ð²Ð½Ð¾ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¾ Ð¸Ð¼Ðµ Ð¸Ð»Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°.
+  notice_account_password_updated: Ð›Ð¾Ð·Ð¸Ð½ÐºÐ° Ñ˜Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°.
+  notice_account_wrong_password: ÐŸÐ¾Ð³Ñ€ÐµÑˆÐ½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
+  notice_account_register_done: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³ Ñ˜Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½. ÐšÐ»Ð¸ÐºÐ½Ð¸Ñ‚Ðµ Ð½Ð° Ð»Ð¸Ð½Ðº ÐºÐ¾Ñ˜Ð¸ ÑÑ‚Ðµ Ð´Ð¾Ð±Ð¸Ð»Ð¸ Ñƒ Ðµ-Ð¿Ð¾Ñ€ÑƒÑ†Ð¸ Ð·Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ñƒ.
+  notice_account_unknown_email: ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ‚ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº.
+  notice_can_t_change_password: ÐžÐ²Ð°Ñ˜ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³ Ð·Ð° Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ñƒ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð° ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¸ ÑÐ¿Ð¾Ñ™Ð½Ð¸ Ð¸Ð·Ð²Ð¾Ñ€. ÐÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ñ˜Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸Ñ‚Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÑƒ.
+  notice_account_lost_email_sent: ÐŸÐ¾ÑÐ»Ð°Ñ‚Ð° Ð²Ð°Ð¼ Ñ˜Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐ° ÑÐ° ÑƒÐ¿ÑƒÑ‚ÑÑ‚Ð²Ð¾Ð¼ Ð·Ð° Ð¸Ð·Ð±Ð¾Ñ€ Ð½Ð¾Ð²Ðµ Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ
+  notice_account_activated: Ð’Ð°Ñˆ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³ Ñ˜Ðµ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½. Ð¡Ð°Ð´Ð° ÑÐµ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð¸Ñ‚Ð¸.
+  notice_successful_create: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ ÐºÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ.
+  notice_successful_update: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°ÑšÐµ.
+  notice_successful_delete: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð±Ñ€Ð¸ÑÐ°ÑšÐµ.
+  notice_successful_connection: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð¿Ð¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ.
+  notice_file_not_found: Ð¡Ñ‚Ñ€Ð°Ð½Ð° ÐºÐ¾Ñ˜Ð¾Ñ˜ Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð¸Ñ‚Ð¸ Ð½Ðµ Ð¿Ð¾ÑÑ‚Ð¾Ñ˜Ð¸ Ð¸Ð»Ð¸ Ñ˜Ðµ ÑƒÐºÐ»Ð¾ÑšÐµÐ½Ð°.
+  notice_locking_conflict: ÐŸÐ¾Ð´Ð°Ñ‚Ð°Ðº Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½ Ð¾Ð´ ÑÑ‚Ñ€Ð°Ð½Ðµ Ð´Ñ€ÑƒÐ³Ð¾Ð³ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ°.
+  notice_not_authorized: ÐÐ¸ÑÑ‚Ðµ Ð¾Ð²Ð»Ð°ÑˆÑ›ÐµÐ½Ð¸ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿ Ð¾Ð²Ð¾Ñ˜ ÑÑ‚Ñ€Ð°Ð½Ð¸.
+  notice_email_sent: "E-Ð¿Ð¾Ñ€ÑƒÐºÐ° Ñ˜Ðµ Ð¿Ð¾ÑÐ»Ð°Ñ‚Ð° Ð½Ð° %{value}"
+  notice_email_error: "Ð”Ð¾Ð³Ð¾Ð´Ð¸Ð»Ð° ÑÐµ Ð³Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸Ð»Ð¸ÐºÐ¾Ð¼ ÑÐ»Ð°ÑšÐ° Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ (%{value})"
+  notice_feeds_access_key_reseted: Ð’Ð°Ñˆ RSS Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ñ˜Ðµ Ð¿Ð¾Ð½Ð¸ÑˆÑ‚ÐµÐ½.
+  notice_api_access_key_reseted: Ð’Ð°Ñˆ API Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ñ˜Ðµ Ð¿Ð¾Ð½Ð¸ÑˆÑ‚ÐµÐ½.
+  notice_failed_to_save_issues: "ÐÐµÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑÐ½Ð¸Ð¼Ð°ÑšÐµ %{count} Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð¾Ð´ %{total} Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½Ð¸Ñ…: %{ids}."
+  notice_failed_to_save_members: "ÐÐµÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑÐ½Ð¸Ð¼Ð°ÑšÐµ Ñ‡Ð»Ð°Ð½Ð°(Ð¾Ð²Ð°): %{errors}."
+  notice_no_issue_selected: "ÐÐ¸ Ñ˜ÐµÐ´Ð°Ð½ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ Ð½Ð¸Ñ˜Ðµ Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½! ÐœÐ¾Ð»Ð¸Ð¼Ð¾, Ð¾Ð´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ ÐºÐ¾Ñ˜Ð¸ Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° Ð¼ÐµÑšÐ°Ñ‚Ðµ."
+  notice_account_pending: "Ð’Ð°Ñˆ Ð½Ð°Ð»Ð¾Ð³ Ñ˜Ðµ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½ Ð¸ Ñ‡ÐµÐºÐ° Ð½Ð° Ð¾Ð´Ð¾Ð±Ñ€ÐµÑšÐµ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð°."
+  notice_default_data_loaded: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ Ñ˜Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑƒÑ‡Ð¸Ñ‚Ð°Ð½Ð¾.
+  notice_unable_delete_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ñƒ Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸.
+  notice_unable_delete_time_entry: Ð¡Ñ‚Ð°Ð²ÐºÑƒ ÐµÐ²Ð¸Ð´ÐµÐ½Ñ†Ð¸Ñ˜Ðµ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð° Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸.
+  notice_issue_done_ratios_updated: ÐžÐ´Ð½Ð¾Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½.
+
+  error_can_t_load_default_data: "ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ ÑƒÑ‡Ð¸Ñ‚Ð°Ñ‚Ð¸: %{value}"
+  error_scm_not_found: "Ð¡Ñ‚Ð°Ð²ÐºÐ° Ð¸Ð»Ð¸ Ð¸ÑÐ¿Ñ€Ð°Ð²ÐºÐ° Ð½Ð¸ÑÑƒ Ð¿Ñ€Ð¾Ð½Ð°Ñ’ÐµÐ½Ðµ Ñƒ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ñƒ."
+  error_scm_command_failed: "Ð“Ñ€ÐµÑˆÐºÐ° ÑÐµ Ñ˜Ð°Ð²Ð¸Ð»Ð° Ð¿Ñ€Ð¸Ð»Ð¸ÐºÐ¾Ð¼ Ð¿Ð¾ÐºÑƒÑˆÐ°Ñ˜Ð° Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð° ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ñƒ: %{value}"
+  error_scm_annotate: "Ð¡Ñ‚Ð°Ð²ÐºÐ° Ð½Ðµ Ð¿Ð¾ÑÑ‚Ð¾Ñ˜Ð¸ Ð¸Ð»Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð°."
+  error_issue_not_found_in_project: 'ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ð½Ð¸Ñ˜Ðµ Ð¿Ñ€Ð¾Ð½Ð°Ñ’ÐµÐ½ Ð¸Ð»Ð¸ Ð½Ðµ Ð¿Ñ€Ð¸Ð¿Ð°Ð´Ð° Ð¾Ð²Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ñƒ.'
+  error_no_tracker_in_project: 'ÐÐ¸ Ñ˜ÐµÐ´Ð½Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð½Ð¸Ñ˜Ðµ Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð¾ ÑÐ° Ð¾Ð²Ð¸Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¾Ð¼. ÐœÐ¾Ð»Ð¸Ð¼Ð¾ Ð¿Ñ€Ð¾Ð²ÐµÑ€Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´ÐµÑˆÐ°Ð²Ð°ÑšÐ° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°.'
+  error_no_default_issue_status: 'ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð½Ð¸Ñ˜Ðµ Ð´ÐµÑ„Ð¸Ð½Ð¸ÑÐ°Ð½. ÐœÐ¾Ð»Ð¸Ð¼Ð¾ Ð¿Ñ€Ð¾Ð²ÐµÑ€Ð¸Ñ‚Ðµ Ð²Ð°ÑˆÐµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ (Ð¸Ð´Ð¸Ñ‚Ðµ Ð½Ð° "ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð° -> Ð¡Ñ‚Ð°Ñ‚ÑƒÑÐ¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°").'
+  error_can_not_delete_custom_field: ÐÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ñ˜Ðµ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸ Ð¿Ñ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð¾ Ð¿Ð¾Ñ™Ðµ
+  error_can_not_delete_tracker: "ÐžÐ²Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ ÑÐ°Ð´Ñ€Ð¶Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ðµ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¾Ð±Ñ€Ð¸ÑÐ°Ð½Ð¾."
+  error_can_not_remove_role: "ÐžÐ²Ð° ÑƒÐ»Ð¾Ð³Ð° Ñ˜Ðµ Ñƒ ÑƒÐ¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¾Ð±Ñ€Ð¸ÑÐ°Ð½Ð°."
+  error_can_not_reopen_issue_on_closed_version: 'ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½ Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¾Ñ˜ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½'
+  error_can_not_archive_project: ÐžÐ²Ð°Ñ˜ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚ ÑÐµ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ñ‚Ð¸
+  error_issue_done_ratios_not_updated: "ÐžÐ´Ð½Ð¾Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð½Ð¸Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½."
+  error_workflow_copy_source: 'ÐœÐ¾Ð»Ð¸Ð¼Ð¾ Ð¾Ð´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¸Ð·Ð²Ð¾Ñ€Ð½Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð¸Ð»Ð¸ ÑƒÐ»Ð¾Ð³Ñƒ'
+  error_workflow_copy_target: 'ÐœÐ¾Ð»Ð¸Ð¼Ð¾ Ð¾Ð´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¾Ð´Ñ€ÐµÐ´Ð¸ÑˆÐ½Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð¸ ÑƒÐ»Ð¾Ð³Ñƒ'
+  error_unable_delete_issue_status: 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ Ð¾Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸'
+  error_unable_to_connect: "ÐŸÐ¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ ÑÐ° (%{value}) Ñ˜Ðµ Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›Ðµ"
+  warning_attachments_not_saved: "%{count} Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ° Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ ÑÐ½Ð¸Ð¼Ñ™ÐµÐ½Ð°."
+
+  mail_subject_lost_password: "Ð’Ð°ÑˆÐ° %{value} Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°"
+  mail_body_lost_password: 'Ð—Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñƒ Ð²Ð°ÑˆÐµ Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ, ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ‚Ðµ Ð½Ð° ÑÐ»ÐµÐ´ÐµÑ›Ð¸ Ð»Ð¸Ð½Ðº:'
+  mail_subject_register: "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð²Ð°ÑˆÐµÐ³ %{value} Ð½Ð°Ð»Ð¾Ð³Ð°"
+  mail_body_register: 'Ð—Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ñƒ Ð²Ð°ÑˆÐµÐ³ Ð½Ð°Ð»Ð¾Ð³Ð°, ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ‚Ðµ Ð½Ð° ÑÐ»ÐµÐ´ÐµÑ›Ð¸ Ð»Ð¸Ð½Ðº:'
+  mail_body_account_information_external: "Ð’Ð°Ñˆ Ð½Ð°Ð»Ð¾Ð³ %{value} Ð¼Ð¾Ð¶ÐµÑ‚Ðµ ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¸Ñ‚Ð¸ Ð·Ð° Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñƒ."
+  mail_body_account_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ðµ Ð¾ Ð²Ð°ÑˆÐµÐ¼ Ð½Ð°Ð»Ð¾Ð³Ñƒ
+  mail_subject_account_activation_request: "Ð—Ð°Ñ…Ñ‚ÐµÐ² Ð·Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ñƒ Ð½Ð°Ð»Ð¾Ð³Ð° %{value}"
+  mail_body_account_activation_request: "ÐÐ¾Ð²Ð¸ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº (%{value}) Ñ˜Ðµ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½. ÐÐ°Ð»Ð¾Ð³ Ñ‡ÐµÐºÐ° Ð½Ð° Ð²Ð°ÑˆÐµ Ð¾Ð´Ð¾Ð±Ñ€ÐµÑšÐµ:"
+  mail_subject_reminder: "%{count} Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð´Ð¾ÑÐ¿ÐµÐ²Ð° Ð½Ð°Ñ€ÐµÐ´Ð½Ð¸Ñ… %{days} Ð´Ð°Ð½Ð°"
+  mail_body_reminder: "%{count} Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ð¸Ñ… Ð²Ð°Ð¼Ð° Ð´Ð¾ÑÐ¿ÐµÐ²Ð° Ñƒ Ð½Ð°Ñ€ÐµÐ´Ð½Ð¸Ñ… %{days} Ð´Ð°Ð½Ð°:"
+  mail_subject_wiki_content_added: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° '%{id}' Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚Ð°"
+  mail_body_wiki_content_added: "%{author} Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ð¾ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ '%{id}'."
+  mail_subject_wiki_content_updated: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° '%{id}' Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°"
+  mail_body_wiki_content_updated: "%{author} Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð¾ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ '%{id}'."
+
+
+  field_name: ÐÐ°Ð·Ð¸Ð²
+  field_description: ÐžÐ¿Ð¸Ñ
+  field_summary: Ð ÐµÐ·Ð¸Ð¼Ðµ
+  field_is_required: ÐžÐ±Ð°Ð²ÐµÐ·Ð½Ð¾
+  field_firstname: Ð˜Ð¼Ðµ
+  field_lastname: ÐŸÑ€ÐµÐ·Ð¸Ð¼Ðµ
+  field_mail: Ð•-Ð°Ð´Ñ€ÐµÑÐ°
+  field_filename: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  field_filesize: Ð’ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð°
+  field_downloads: ÐŸÑ€ÐµÑƒÐ·Ð¸Ð¼Ð°ÑšÐ°
+  field_author: ÐÑƒÑ‚Ð¾Ñ€
+  field_created_on: ÐšÑ€ÐµÐ¸Ñ€Ð°Ð½Ð¾
+  field_updated_on: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾
+  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
+  field_is_for_all: Ð—Ð° ÑÐ²Ðµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ðµ
+  field_possible_values: ÐœÐ¾Ð³ÑƒÑ›Ðµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸
+  field_regexp: Ð ÐµÐ³ÑƒÐ»Ð°Ñ€Ð°Ð½ Ð¸Ð·Ñ€Ð°Ð·
+  field_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑƒÐ¶Ð¸Ð½Ð°
+  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑƒÐ¶Ð¸Ð½Ð°
+  field_value: Ð’Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
+  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
+  field_title: ÐÐ°ÑÐ»Ð¾Ð²
+  field_project: ÐŸÑ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
+  field_issue: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼
+  field_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ
+  field_notes: Ð‘ÐµÐ»ÐµÑˆÐºÐµ
+  field_is_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼
+  field_is_default: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
+  field_tracker: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ
+  field_subject: ÐŸÑ€ÐµÐ´Ð¼ÐµÑ‚
+  field_due_date: ÐšÑ€Ð°Ñ˜ÑšÐ¸ Ñ€Ð¾Ðº
+  field_assigned_to: Ð”Ð¾Ð´ÐµÑ™ÐµÐ½Ð¾
+  field_priority: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
+  field_fixed_version: ÐžÐ´Ñ€ÐµÐ´Ð¸ÑˆÐ½Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
+  field_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
+  field_principal: Ð“Ð»Ð°Ð²Ð½Ð¸
+  field_role: Ð£Ð»Ð¾Ð³Ð°
+  field_homepage: ÐŸÐ¾Ñ‡ÐµÑ‚Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  field_is_public: ÐˆÐ°Ð²Ð½Ð¾ Ð¾Ð±Ñ˜Ð°Ð²Ñ™Ð¸Ð²Ð°ÑšÐµ
+  field_parent: ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚ Ð¾Ð´
+  field_is_in_roadmap: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ð¸ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸ Ñƒ Ð¿Ð»Ð°Ð½Ñƒ Ñ€Ð°Ð´Ð°
+  field_login: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¾ Ð¸Ð¼Ðµ
+  field_mail_notification: ÐžÐ±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐ° Ð¿ÑƒÑ‚ÐµÐ¼ Ðµ-Ð¿Ð¾ÑˆÑ‚Ðµ
+  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
+  field_last_login_on: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐµ Ð¿Ð¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ
+  field_language: ÐˆÐµÐ·Ð¸Ðº
+  field_effective_date: Ð”Ð°Ñ‚ÑƒÐ¼
+  field_password: Ð›Ð¾Ð·Ð¸Ð½ÐºÐ°
+  field_new_password: ÐÐ¾Ð²Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
+  field_password_confirmation: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ
+  field_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ð°
+  field_type: Ð¢Ð¸Ð¿
+  field_host: Ð“Ð»Ð°Ð²Ð½Ð¸ Ñ€Ð°Ñ‡ÑƒÐ½Ð°Ñ€
+  field_port: ÐŸÐ¾Ñ€Ñ‚
+  field_account: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³
+  field_base_dn: Ð‘Ð°Ð·Ð½Ð¸ DN
+  field_attr_login: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™Ð¸Ð²Ð°ÑšÐ°
+  field_attr_firstname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð¸Ð¼ÐµÐ½Ð°
+  field_attr_lastname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð¿Ñ€ÐµÐ·Ð¸Ð¼ÐµÐ½Ð°
+  field_attr_mail: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ðµ-Ð°Ð´Ñ€ÐµÑÐµ
+  field_onthefly: ÐšÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ° Ñƒ Ñ‚Ð¾ÐºÑƒ Ñ€Ð°Ð´Ð°
+  field_start_date: ÐŸÐ¾Ñ‡ÐµÑ‚Ð°Ðº
+  field_done_ratio: "% ÑƒÑ€Ð°Ñ’ÐµÐ½Ð¾"
+  field_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
+  field_hide_mail: Ð¡Ð°ÐºÑ€Ð¸Ñ˜ Ð¼Ð¾Ñ˜Ñƒ Ðµ-Ð°Ð´Ñ€ÐµÑÑƒ
+  field_comments: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  field_url: URL
+  field_start_page: ÐŸÐ¾Ñ‡ÐµÑ‚Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  field_subproject: ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
+  field_hours: ÑÐ°Ñ‚Ð¸
+  field_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
+  field_spent_on: Ð”Ð°Ñ‚ÑƒÐ¼
+  field_identifier: Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€
+  field_is_filter: Ð£Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸ ÐºÐ°Ð¾ Ñ„Ð¸Ð»Ñ‚ÐµÑ€
+  field_issue_to: Ð¡Ñ€Ð¾Ð´Ð½Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
+  field_delay: ÐšÐ°ÑˆÑšÐµÑšÐµ
+  field_assignable: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ð¼Ð¾Ð¶Ðµ Ð±Ð¸Ñ‚Ð¸ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½ Ð¾Ð²Ð¾Ñ˜ ÑƒÐ»Ð¾Ð·Ð¸
+  field_redirect_existing_links: ÐŸÑ€ÐµÑƒÑÐ¼ÐµÑ€Ð¸ Ð¿Ð¾ÑÑ‚Ð¾Ñ˜ÐµÑ›Ðµ Ð²ÐµÐ·Ðµ
+  field_estimated_hours: ÐŸÑ€Ð¾Ñ‚ÐµÐºÐ»Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  field_column_names: ÐšÐ¾Ð»Ð¾Ð½Ðµ
+  field_time_zone: Ð’Ñ€ÐµÐ¼ÐµÐ½ÑÐºÐ° Ð·Ð¾Ð½Ð°
+  field_searchable: ÐœÐ¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð¿Ñ€ÐµÑ‚Ñ€Ð°Ð¶ÑƒÑ˜Ðµ
+  field_default_value: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
+  field_comments_sorting: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ðµ
+  field_parent_title: ÐœÐ°Ñ‚Ð¸Ñ‡Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  field_editable: Ð˜Ð·Ð¼ÐµÐ½Ñ™Ð¸Ð²Ð¾
+  field_watcher: ÐŸÐ¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡
+  field_identity_url: OpenID URL
+  field_content: Ð¡Ð°Ð´Ñ€Ð¶Ð°Ñ˜
+  field_group_by: Ð“Ñ€ÑƒÐ¿Ð¸ÑÐ°ÑšÐµ Ñ€ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð° Ð¿Ð¾
+  field_sharing: Ð”ÐµÑ™ÐµÑšÐµ
+  field_parent_issue: ÐœÐ°Ñ‚Ð¸Ñ‡Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº
+
+  setting_app_title: ÐÐ°ÑÐ»Ð¾Ð² Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ðµ
+  setting_app_subtitle: ÐŸÐ¾Ð´Ð½Ð°ÑÐ»Ð¾Ð² Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ðµ
+  setting_welcome_text: Ð¢ÐµÐºÑÑ‚ Ð´Ð¾Ð±Ñ€Ð¾Ð´Ð¾ÑˆÐ»Ð¸Ñ†Ðµ
+  setting_default_language: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¸ Ñ˜ÐµÐ·Ð¸Ðº
+  setting_login_required: ÐžÐ±Ð°Ð²ÐµÐ·Ð½Ð° Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ð° Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
+  setting_self_registration: Ð¡Ð°Ð¼Ð¾Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
+  setting_attachment_max_size: ÐœÐ°ÐºÑ. Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ðµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
+  setting_issues_export_limit: ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÑšÐµ Ð¸Ð·Ð²Ð¾Ð·Ð° â€žÐ¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°â€œ
+  setting_mail_from: Ð•-Ð°Ð´Ñ€ÐµÑÐ° Ð¿Ð¾ÑˆÐ¸Ñ™Ð°Ð¾Ñ†Ð°
+  setting_bcc_recipients: ÐŸÑ€Ð¸Ð¼Ð°Ð¾Ñ†Ð¸ â€žBccâ€œ ÐºÐ¾Ð¿Ð¸Ñ˜Ðµ
+  setting_plain_text_mail: ÐŸÐ¾Ñ€ÑƒÐºÐ° ÑÐ° Ñ‡Ð¸ÑÑ‚Ð¸Ð¼ Ñ‚ÐµÐºÑÑ‚Ð¾Ð¼ (Ð±ÐµÐ· HTML-Ð°)
+  setting_host_name: ÐŸÑƒÑ‚Ð°ÑšÐ° Ð¸ Ð½Ð°Ð·Ð¸Ð² Ð³Ð»Ð°Ð²Ð½Ð¾Ð³ Ñ€Ð°Ñ‡ÑƒÐ½Ð°Ñ€Ð°
+  setting_text_formatting: ÐžÐ±Ð»Ð¸ÐºÐ¾Ð²Ð°ÑšÐµ Ñ‚ÐµÐºÑÑ‚Ð°
+  setting_wiki_compression: ÐšÐ¾Ð¼Ð¿Ñ€ÐµÑÐ¸Ñ˜Ð° Wiki Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ðµ
+  setting_feeds_limit: ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÑšÐµ ÑÐ°Ð´Ñ€Ð¶Ð°Ñ˜Ð° Ð¸Ð·Ð²Ð¾Ñ€Ð° Ð²ÐµÑÑ‚Ð¸
+  setting_default_projects_public: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð° ÑÐµ Ñ˜Ð°Ð²Ð½Ð¾ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð¸Ð²Ð°ÑšÐµ Ð½Ð¾Ð²Ð¸Ñ… Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°
+  setting_autofetch_changesets: Ð˜Ð·Ð²Ñ€ÑˆÐ°Ð²Ð°ÑšÐµ Ð°ÑƒÑ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ¾Ð³ Ð¿Ñ€ÐµÑƒÐ·Ð¸Ð¼Ð°ÑšÐ°
+  setting_sys_api_enabled: ÐžÐ¼Ð¾Ð³ÑƒÑ›Ð°Ð²Ð°ÑšÐµ WS Ð·Ð° ÑƒÐ¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚ÐµÐ¼
+  setting_commit_ref_keywords: Ð ÐµÑ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ€Ð°ÑšÐµ ÐºÑ™ÑƒÑ‡Ð½Ð¸Ñ… Ñ€ÐµÑ‡Ð¸
+  setting_commit_fix_keywords: ÐŸÐ¾Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ ÐºÑ™ÑƒÑ‡Ð½Ð¸Ñ… Ñ€ÐµÑ‡Ð¸
+  setting_autologin: ÐÑƒÑ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ° Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð°
+  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð´Ð°Ñ‚ÑƒÐ¼Ð°
+  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
+  setting_cross_project_issue_relations: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸ Ð¿Ð¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð¸Ð· ÑƒÐ½Ð°ÐºÑ€ÑÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°
+  setting_issue_list_default_columns: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ðµ ÐºÐ¾Ð»Ð¾Ð½Ðµ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ðµ Ð½Ð° ÑÐ¿Ð¸ÑÐºÑƒ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  setting_emails_footer: ÐŸÐ¾Ð´Ð½Ð¾Ð¶Ñ˜Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
+  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
+  setting_per_page_options: ÐžÐ¿Ñ†Ð¸Ñ˜Ðµ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð° Ð¾Ð±Ñ˜ÐµÐºÐ°Ñ‚Ð° Ð¿Ð¾ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  setting_user_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ°
+  setting_activity_days_default: Ð‘Ñ€Ð¾Ñ˜ Ð´Ð°Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸Ñ… Ð½Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð½Ð¾Ñ˜ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð¸
+  setting_display_subprojects_issues: ÐŸÑ€Ð¸ÐºÐ°Ð·ÑƒÑ˜ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ðµ Ð¸Ð· Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð° Ð½Ð° Ð³Ð»Ð°Ð²Ð½Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ñƒ, ÑƒÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð½Ð¸Ñ˜Ðµ Ð´Ñ€ÑƒÐ³Ð°Ñ‡Ð¸Ñ˜Ðµ Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾
+  setting_enabled_scm: ÐžÐ¼Ð¾Ð³ÑƒÑ›Ð°Ð²Ð°ÑšÐµ SCM
+  setting_mail_handler_body_delimiters: "Ð¡ÐºÑ€Ð°Ñ›Ð¸Ð²Ð°ÑšÐµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ Ð½Ð°ÐºÐ¾Ð½ Ñ˜ÐµÐ´Ð½Ðµ Ð¾Ð´ Ð¾Ð²Ð¸Ñ… Ð»Ð¸Ð½Ð¸Ñ˜Ð°"
+  setting_mail_handler_api_enabled: ÐžÐ¼Ð¾Ð³ÑƒÑ›Ð°Ð²Ð°ÑšÐµ WS Ð´Ð¾Ð»Ð°Ð·Ð½Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
+  setting_mail_handler_api_key: API ÐºÑ™ÑƒÑ‡
+  setting_sequential_project_identifiers: Ð“ÐµÐ½ÐµÑ€Ð¸ÑÐ°ÑšÐµ ÑÐµÐºÐ²ÐµÐ½Ñ†Ð¸Ñ˜Ð°Ð»Ð½Ð¾Ð³ Ð¸Ð¼ÐµÐ½Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
+  setting_gravatar_enabled: ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸ Gravatar ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐµ Ð¸ÐºÐ¾Ð½Ðµ
+  setting_gravatar_default: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð° Gravatar ÑÐ»Ð¸ÐºÐ°
+  setting_diff_max_lines_displayed: ÐœÐ°ÐºÑ. Ð±Ñ€Ð¾Ñ˜ Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸Ñ… Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð¸Ñ‚Ð¸Ñ… Ð»Ð¸Ð½Ð¸Ñ˜Ð°
+  setting_file_max_size_displayed: ÐœÐ°ÐºÑ. Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ñ‚ÐµÐºÑÑ‚. Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸Ñ… ÑƒÐ¼ÐµÑ‚Ð½ÑƒÑ‚Ð¾
+  setting_repository_log_display_limit: ÐœÐ°ÐºÑ. Ð±Ñ€Ð¾Ñ˜ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°Ð½Ð¸Ñ… Ñƒ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÑ†Ð¸ Ð·Ð° ÐµÐ²Ð¸Ð´ÐµÐ½Ñ†Ð¸Ñ˜Ñƒ
+  setting_openid: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸ OpenID Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñƒ Ð¸ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ñƒ
+  setting_password_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑƒÐ¶Ð¸Ð½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ
+  setting_new_project_user_role_id: ÐšÑ€ÐµÐ°Ñ‚Ð¾Ñ€Ñƒ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð° (ÐºÐ¾Ñ˜Ð¸ Ð½Ð¸Ñ˜Ðµ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€) Ð´Ð¾Ð´ÐµÑ™ÑƒÑ˜Ðµ Ñ˜Ðµ ÑƒÐ»Ð¾Ð³Ð°
+  setting_default_projects_modules: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ Ð¾Ð¼Ð¾Ð³ÑƒÑ›ÐµÐ½Ð¸ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð·Ð° Ð½Ð¾Ð²Ðµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ðµ
+  setting_issue_done_ratio: Ð˜Ð·Ñ€Ð°Ñ‡ÑƒÐ½Ð°Ñ˜ Ð¾Ð´Ð½Ð¾Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  setting_issue_done_ratio_issue_field: ÐºÐ¾Ñ€Ð¸ÑÑ‚ÐµÑ›Ð¸ Ð¿Ð¾Ñ™Ðµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  setting_issue_done_ratio_issue_status: ÐºÐ¾Ñ€Ð¸ÑÑ‚ÐµÑ›Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  setting_start_of_week: ÐŸÑ€Ð²Ð¸ Ð´Ð°Ð½ Ñƒ ÑÐµÐ´Ð¼Ð¸Ñ†Ð¸
+  setting_rest_api_enabled: ÐžÐ¼Ð¾Ð³ÑƒÑ›Ð¸ REST web ÑƒÑÐ»ÑƒÐ³Ðµ
+  setting_cache_formatted_text: ÐšÐµÑˆÐ¸Ñ€Ð°ÑšÐµ Ð¾Ð±Ñ€Ð°Ñ’ÐµÐ½Ð¾Ð³ Ñ‚ÐµÐºÑÑ‚Ð°
+
+  permission_add_project: ÐšÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
+  permission_add_subprojects: ÐšÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ Ð¿Ð¾Ñ‚Ð¿Ð¾Ñ˜ÐµÐºÑ‚Ð°
+  permission_edit_project: Ð˜Ð·Ð¼ÐµÐ½Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°
+  permission_select_project_modules: ÐžÐ´Ð°Ð±Ð¸Ñ€Ð°ÑšÐµ Ð¼Ð¾Ð´ÑƒÐ»Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
+  permission_manage_members: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ñ‡Ð»Ð°Ð½Ð¾Ð²Ð¸Ð¼Ð°
+  permission_manage_project_activities: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð½Ð¸Ð¼ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð¸Ð¼Ð°
+  permission_manage_versions: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°Ð¼Ð°
+  permission_manage_categories: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°Ð¼Ð° Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  permission_view_issues: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  permission_add_issues: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  permission_edit_issues: Ð˜Ð·Ð¼ÐµÐ½Ð° Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  permission_manage_issue_relations: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð²ÐµÐ·Ð°Ð¼Ð° Ð¸Ð·Ð¼ÐµÑ’Ñƒ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  permission_add_issue_notes: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ð±ÐµÐ»ÐµÑˆÐºÐ¸
+  permission_edit_issue_notes: Ð˜Ð·Ð¼ÐµÐ½Ð° Ð±ÐµÐ»ÐµÑˆÐºÐ¸
+  permission_edit_own_issue_notes: Ð˜Ð·Ð¼ÐµÐ½Ð° ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸Ñ… Ð±ÐµÐ»ÐµÑˆÐºÐ¸
+  permission_move_issues: ÐŸÐ¾Ð¼ÐµÑ€Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  permission_delete_issues: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  permission_manage_public_queries: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ñ˜Ð°Ð²Ð½Ð¸Ð¼ ÑƒÐ¿Ð¸Ñ‚Ð¸Ð¼Ð°
+  permission_save_queries: Ð¡Ð½Ð¸Ð¼Ð°ÑšÐµ ÑƒÐ¿Ð¸Ñ‚Ð°
+  permission_view_gantt: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð“Ð°Ð½Ñ‚Ð¾Ð²Ð¾Ð³ Ð´Ð¸Ñ˜Ð°Ð³Ñ€Ð°Ð¼Ð°
+  permission_view_calendar: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ð°
+  permission_view_issue_watchers: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÑÐ¿Ð¸ÑÐºÐ° Ð¿Ð¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡Ð°
+  permission_add_issue_watchers: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ð¿Ð¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡Ð°
+  permission_delete_issue_watchers: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð¿Ð¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡Ð°
+  permission_log_time: Ð‘ÐµÐ»ÐµÐ¶ÐµÑšÐµ ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾Ð³ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
+  permission_view_time_entries: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾Ð³ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
+  permission_edit_time_entries: Ð˜Ð·Ð¼ÐµÐ½Ð° ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾Ð³ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
+  permission_edit_own_time_entries: Ð˜Ð·Ð¼ÐµÐ½Ð° ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¾Ð³ ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾Ð³ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
+  permission_manage_news: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð²ÐµÑÑ‚Ð¸Ð¼Ð°
+  permission_comment_news: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÑÐ°ÑšÐµ Ð²ÐµÑÑ‚Ð¸
+  permission_view_documents: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ð°Ñ‚Ð°
+  permission_manage_files: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°Ð¼Ð°
+  permission_view_files: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  permission_manage_wiki: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ð¼Ð°
+  permission_rename_wiki_pages: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð° Ð¸Ð¼ÐµÐ½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ð¼Ð°
+  permission_delete_wiki_pages: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  permission_view_wiki_pages: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  permission_view_wiki_edits: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ wiki Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ðµ
+  permission_edit_wiki_pages: Ð˜Ð·Ð¼ÐµÐ½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  permission_delete_wiki_pages_attachments: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ… Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  permission_protect_wiki_pages: Ð—Ð°ÑˆÑ‚Ð¸Ñ‚Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  permission_manage_repository: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚ÐµÐ¼
+  permission_browse_repository: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ð°
+  permission_view_changesets: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ ÑÐºÑƒÐ¿Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°
+  permission_commit_access: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð° Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð°
+  permission_manage_boards: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ñ„Ð¾Ñ€ÑƒÐ¼Ð¸Ð¼Ð°
+  permission_view_messages: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð¿Ð¾Ñ€ÑƒÐºÐ°
+  permission_add_messages: Ð¡Ð»Ð°ÑšÐµ Ð¿Ð¾Ñ€ÑƒÐºÐ°
+  permission_edit_messages: Ð˜Ð·Ð¼ÐµÐ½Ð° Ð¿Ð¾Ñ€ÑƒÐºÐ°
+  permission_edit_own_messages: Ð˜Ð·Ð¼ÐµÐ½Ð° ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸Ñ… Ð¿Ð¾Ñ€ÑƒÐºÐ°
+  permission_delete_messages: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð¿Ð¾Ñ€ÑƒÐºÐ°
+  permission_delete_own_messages: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸Ñ… Ð¿Ð¾Ñ€ÑƒÐºÐ°
+  permission_export_wiki_pages: Ð˜Ð·Ð²Ð¾Ð· wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  permission_manage_subtasks: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ†Ð¸Ð¼Ð°
+
+  project_module_issue_tracking: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  project_module_time_tracking: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
+  project_module_news: Ð’ÐµÑÑ‚Ð¸
+  project_module_documents: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  project_module_files: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
+  project_module_wiki: Wiki
+  project_module_repository: Ð¡Ð¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ðµ
+  project_module_boards: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
+
+  label_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
+  label_user_plural: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸
+  label_user_new: ÐÐ¾Ð²Ð¸ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
+  label_user_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼Ð°Ð½
+  label_project: ÐŸÑ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
+  label_project_new: ÐÐ¾Ð²Ð¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
+  label_project_plural: ÐŸÑ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
+  label_x_projects:
+    zero:  Ð½ÐµÐ¼Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°
+    one:   Ñ˜ÐµÐ´Ð°Ð½ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
+    other: "%{count} Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚Ð°"
+  label_project_all: Ð¡Ð²Ð¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
+  label_project_latest: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐ¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
+  label_issue: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼
+  label_issue_new: ÐÐ¾Ð²Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼
+  label_issue_plural: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
+  label_issue_view_all: ÐŸÑ€Ð¸ÐºÐ°Ð· ÑÐ²Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  label_issues_by: "ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ð¸ (%{value})"
+  label_issue_added: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚
+  label_issue_updated: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼ Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½
+  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_new: ÐÐ¾Ð²Ð¸ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  label_document_added: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚ Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚
+  label_role: Ð£Ð»Ð¾Ð³Ð°
+  label_role_plural: Ð£Ð»Ð¾Ð³Ðµ
+  label_role_new: ÐÐ¾Ð²Ð° ÑƒÐ»Ð¾Ð³Ð°
+  label_role_and_permissions: Ð£Ð»Ð¾Ð³Ðµ Ð¸ Ð´Ð¾Ð·Ð²Ð¾Ð»Ðµ
+  label_member: Ð§Ð»Ð°Ð½
+  label_member_new: ÐÐ¾Ð²Ð¸ Ñ‡Ð»Ð°Ð½
+  label_member_plural: Ð§Ð»Ð°Ð½Ð¾Ð²Ð¸
+  label_tracker: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ
+  label_tracker_plural: ÐŸÑ€Ð°Ñ›ÐµÑšÐ°
+  label_tracker_new: ÐÐ¾Ð²Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ
+  label_workflow: Ð¢Ð¾Ðº Ð¿Ð¾ÑÐ»Ð°
+  label_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  label_issue_status_plural: Ð¡Ñ‚Ð°Ñ‚ÑƒÑÐ¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  label_issue_status_new: ÐÐ¾Ð²Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð° Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ðµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  label_issue_category_new: ÐÐ¾Ð²Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
+  label_custom_field: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð¾ Ð¿Ð¾Ñ™Ðµ
+  label_custom_field_plural: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð° Ð¿Ð¾Ñ™Ð°
+  label_custom_field_new: ÐÐ¾Ð²Ð¾ Ð¿Ñ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð¾ Ð¿Ð¾Ñ™Ðµ
+  label_enumerations: ÐÐ°Ð±Ñ€Ð¾Ñ˜Ð¸Ð²Ð° Ð»Ð¸ÑÑ‚Ð°
+  label_enumeration_new: ÐÐ¾Ð²Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
+  label_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ð°
+  label_information_plural: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ðµ
+  label_please_login: ÐœÐ¾Ð»Ð¸Ð¼Ð¾, Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð¸Ñ‚Ðµ ÑÐµ
+  label_register: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
+  label_login_with_open_id_option: Ð¸Ð»Ð¸ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð° ÑÐ° OpenID
+  label_password_lost: Ð˜Ð·Ð³ÑƒÐ±Ñ™ÐµÐ½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
+  label_home: ÐŸÐ¾Ñ‡ÐµÑ‚Ð°Ðº
+  label_my_page: ÐœÐ¾Ñ˜Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  label_my_account: ÐœÐ¾Ñ˜ Ð½Ð°Ð»Ð¾Ð³
+  label_my_projects: ÐœÐ¾Ñ˜Ð¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
+  label_my_page_block: My page block
+  label_administration: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
+  label_login: ÐŸÑ€Ð¸Ñ˜Ð°Ð²Ð°
+  label_logout: ÐžÐ´Ñ˜Ð°Ð²Ð°
+  label_help: ÐŸÐ¾Ð¼Ð¾Ñ›
+  label_reported_issues: ÐŸÑ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
+  label_assigned_to_me_issues: ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ð¸ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ð¸ Ð¼ÐµÐ½Ð¸
+  label_last_login: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐµ Ð¿Ð¾Ð²ÐµÐ·Ð¸Ð²Ð°ÑšÐµ
+  label_registered_on: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½
+  label_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
+  label_overall_activity: Ð¦ÐµÐ»Ð¾ÐºÑƒÐ¿Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
+  label_user_activity: "ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ° %{value}"
+  label_new: ÐÐ¾Ð²Ð¾
+  label_logged_as: ÐŸÑ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ð¸ ÑÑ‚Ðµ ÐºÐ°Ð¾
+  label_environment: ÐžÐºÑ€ÑƒÐ¶ÐµÑšÐµ
+  label_authentication: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð° Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
+  label_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
+  label_auth_source_new: ÐÐ¾Ð²Ð¸ Ñ€ÐµÐ¶Ð¸Ð¼ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
+  label_auth_source_plural: Ð ÐµÐ¶Ð¸Ð¼Ð¸ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
+  label_subproject_plural: ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
+  label_subproject_new: ÐÐ¾Ð²Ð¸ Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚
+  label_and_its_subprojects: "%{value} Ð¸ ÑšÐµÐ³Ð¾Ð²Ð¸ Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸"
+  label_min_max_length: ÐœÐ¸Ð½. - ÐœÐ°ÐºÑ. Ð´ÑƒÐ¶Ð¸Ð½Ð°
+  label_list: Ð¡Ð¿Ð¸ÑÐ°Ðº
+  label_date: Ð”Ð°Ñ‚ÑƒÐ¼
+  label_integer: Ð¦ÐµÐ¾ Ð±Ñ€Ð¾Ñ˜
+  label_float: Ð¡Ð° Ð¿Ð¾ÐºÑ€ÐµÑ‚Ð½Ð¸Ð¼ Ð·Ð°Ñ€ÐµÐ·Ð¾Ð¼
+  label_boolean: Ð›Ð¾Ð³Ð¸Ñ‡ÐºÐ¸ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€
+  label_string: Ð¢ÐµÐºÑÑ‚
+  label_text: Ð”ÑƒÐ³Ð¸ Ñ‚ÐµÐºÑÑ‚
+  label_attribute: ÐžÑÐ¾Ð±Ð¸Ð½Ð°
+  label_attribute_plural: ÐžÑÐ¾Ð±Ð¸Ð½Ðµ
+  label_no_data: ÐÐµÐ¼Ð° Ð¿Ð¾Ð´Ð°Ñ‚Ð°ÐºÐ° Ð·Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð¸Ð²Ð°ÑšÐµ
+  label_change_status: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð° ÑÑ‚Ð°Ñ‚ÑƒÑÐ°
+  label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°
+  label_attachment: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  label_attachment_new: ÐÐ¾Ð²Ð° Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  label_attachment_delete: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
+  label_attachment_plural: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
+  label_file_added: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ° Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚Ð°
+  label_report: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ˜
+  label_report_plural: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ˜Ð¸
+  label_news: Ð’ÐµÑÑ‚Ð¸
+  label_news_new: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ð²ÐµÑÑ‚Ð¸
+  label_news_plural: Ð’ÐµÑÑ‚Ð¸
+  label_news_latest: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐµ Ð²ÐµÑÑ‚Ð¸
+  label_news_view_all: ÐŸÑ€Ð¸ÐºÐ°Ð· ÑÐ²Ð¸Ñ… Ð²ÐµÑÑ‚Ð¸
+  label_news_added: Ð’ÐµÑÑ‚Ð¸ ÑÑƒ Ð´Ð¾Ð´Ð°Ñ‚Ðµ
+  label_settings: ÐŸÐ¾Ð´ÐµÑˆÐ°Ð²Ð°ÑšÐ°
+  label_overview: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
+  label_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ð°
+  label_version_new: ÐÐ¾Ð²Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
+  label_version_plural: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ðµ
+  label_close_versions: Ð—Ð°Ñ‚Ð²Ð¾Ñ€Ð¸ Ð·Ð°Ð²Ñ€ÑˆÐµÐ½Ðµ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ðµ
+  label_confirmation: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð°
+  label_export_to: 'Ð¢Ð°ÐºÐ¾Ñ’Ðµ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð½Ð¾ Ð¸ Ñƒ Ð²Ð°Ñ€Ð¸Ñ˜Ð°Ð½Ñ‚Ð¸:'
+  label_read: Ð§Ð¸Ñ‚Ð°ÑšÐµ...
+  label_public_projects: ÐˆÐ°Ð²Ð½Ð¸ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸
+  label_open_issues: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½
+  label_open_issues_plural: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…
+  label_closed_issues: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½
+  label_closed_issues_plural: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…
+  label_x_open_issues_abbr_on_total:
+    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ… / %{total}
+    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½ / %{total}
+    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ… / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…
+    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½
+    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…"
+  label_x_closed_issues_abbr:
+    zero:  0 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…
+    one:   1 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½
+    other: "%{count} Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ñ…"
+  label_total: Ð£ÐºÑƒÐ¿Ð½Ð¾
+  label_permissions: Ð”Ð¾Ð·Ð²Ð¾Ð»Ðµ
+  label_current_status: Ð¢Ñ€ÐµÐ½ÑƒÑ‚Ð½Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_new_statuses_allowed: ÐÐ¾Ð²Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸ Ð´Ð¾Ð·Ð²Ð¾Ñ™ÐµÐ½Ð¸
+  label_all: ÑÐ²Ð¸
+  label_none: Ð½Ð¸Ñ˜ÐµÐ´Ð°Ð½
+  label_nobody: Ð½Ð¸ÐºÐ¾Ð¼Ðµ
+  label_next: Ð¡Ð»ÐµÐ´ÐµÑ›Ðµ
+  label_previous: ÐŸÑ€ÐµÑ‚Ñ…Ð¾Ð´Ð½Ð¾
+  label_used_by: ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸Ð¾
+  label_details: Ð”ÐµÑ‚Ð°Ñ™Ð¸
+  label_add_note: Ð”Ð¾Ð´Ð°Ñ˜ Ð±ÐµÐ»ÐµÑˆÐºÑƒ
+  label_per_page: ÐŸÐ¾ ÑÑ‚Ñ€Ð°Ð½Ð¸
+  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
+  label_months_from: Ð¼ÐµÑÐµÑ†Ð¸ Ð¾Ð´
+  label_gantt: Ð“Ð°Ð½Ñ‚Ð¾Ð² Ð´Ð¸Ñ˜Ð°Ð³Ñ€Ð°Ð¼
+  label_internal: Ð£Ð½ÑƒÑ‚Ñ€Ð°ÑˆÑšÐ¸
+  label_last_changes: "Ð¿Ð¾ÑÐ»ÐµÐ´ÑšÐ¸Ñ… %{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°"
+  label_change_view_all: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸ ÑÐ²Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ðµ
+  label_personalize_page: ÐŸÐµÑ€ÑÐ¾Ð½Ð°Ð»Ð¸Ð·ÑƒÑ˜ Ð¾Ð²Ñƒ ÑÑ‚Ñ€Ð°Ð½Ñƒ
+  label_comment: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  label_comment_plural: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
+  label_x_comments:
+    zero: Ð±ÐµÐ· ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð°
+    one: Ñ˜ÐµÐ´Ð°Ð½ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+    other: "%{count} ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð°"
+  label_comment_add: Ð”Ð¾Ð´Ð°Ñ˜ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  label_comment_added: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€ Ð´Ð¾Ð´Ð°Ñ‚
+  label_comment_delete: ÐžÐ±Ñ€Ð¸ÑˆÐ¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ðµ
+  label_query: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½ ÑƒÐ¿Ð¸Ñ‚
+  label_query_plural: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ñ’ÐµÐ½Ð¸ ÑƒÐ¿Ð¸Ñ‚Ð¸
+  label_query_new: ÐÐ¾Ð²Ð¸ ÑƒÐ¿Ð¸Ñ‚
+  label_filter_add: Ð”Ð¾Ð´Ð°Ð²Ð°ÑšÐµ Ñ„Ð¸Ð»Ñ‚ÐµÑ€Ð°
+  label_filter_plural: Ð¤Ð¸Ð»Ñ‚ÐµÑ€Ð¸
+  label_equals: Ñ˜Ðµ
+  label_not_equals: Ð½Ð¸Ñ˜Ðµ
+  label_in_less_than: Ð¼Ð°ÑšÐµ Ð¾Ð´
+  label_in_more_than: Ð²Ð¸ÑˆÐµ Ð¾Ð´
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: Ñƒ
+  label_today: Ð´Ð°Ð½Ð°Ñ
+  label_all_time: ÑÐ²Ðµ Ð²Ñ€ÐµÐ¼Ðµ
+  label_yesterday: Ñ˜ÑƒÑ‡Ðµ
+  label_this_week: Ð¾Ð²Ðµ ÑÐµÐ´Ð¼Ð¸Ñ†Ðµ
+  label_last_week: Ð¿Ð¾ÑÐ»ÐµÐ´ÑšÐµ ÑÐµÐ´Ð¼Ð¸Ñ†Ðµ
+  label_last_n_days: "Ð¿Ð¾ÑÐ»ÐµÐ´ÑšÐ¸Ñ… %{count} Ð´Ð°Ð½Ð°"
+  label_this_month: Ð¾Ð²Ð¾Ð³ Ð¼ÐµÑÐµÑ†Ð°
+  label_last_month: Ð¿Ð¾ÑÐ»ÐµÐ´ÑšÐµÐ³ Ð¼ÐµÑÐµÑ†Ð°
+  label_this_year: Ð¾Ð²Ðµ Ð³Ð¾Ð´Ð¸Ð½Ðµ
+  label_date_range: Ð’Ñ€ÐµÐ¼ÐµÐ½ÑÐºÐ¸ Ð¿ÐµÑ€Ð¸Ð¾Ð´
+  label_less_than_ago: Ð¿Ñ€Ðµ Ð¼Ð°ÑšÐµ Ð¾Ð´ Ð½ÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð´Ð°Ð½Ð°
+  label_more_than_ago: Ð¿Ñ€Ðµ Ð²Ð¸ÑˆÐµ Ð¾Ð´ Ð½ÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð´Ð°Ð½Ð°
+  label_ago: Ð¿Ñ€Ðµ Ð½ÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð´Ð°Ð½Ð°
+  label_contains: ÑÐ°Ð´Ñ€Ð¶Ð¸
+  label_not_contains: Ð½Ðµ ÑÐ°Ð´Ñ€Ð¶Ð¸
+  label_day_plural: Ð´Ð°Ð½Ð°
+  label_repository: Ð¡Ð¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ðµ
+  label_repository_plural: Ð¡Ð¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ð°
+  label_browse: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ
+  label_branch: Ð“Ñ€Ð°Ð½Ð°
+  label_tag: ÐžÐ·Ð½Ð°ÐºÐ°
+  label_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
+  label_revision_plural: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ðµ
+  label_revision_id: "Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð° %{value}"
+  label_associated_revisions: ÐŸÑ€Ð¸Ð´Ñ€ÑƒÐ¶ÐµÐ½Ðµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ðµ
+  label_added: Ð´Ð¾Ð´Ð°Ñ‚Ð¾
+  label_modified: Ð¿Ñ€Ð¾Ð¼ÐµÑšÐµÐ½Ð¾
+  label_copied: ÐºÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ð¾
+  label_renamed: Ð¿Ñ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¾
+  label_deleted: Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ð½Ð¾
+  label_latest_revision: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐ° Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
+  label_latest_revision_plural: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ðµ
+  label_view_revisions: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
+  label_view_all_revisions: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ ÑÐ²Ð¸Ñ… Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
+  label_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð°
+  label_sort_highest: ÐŸÑ€ÐµÐ¼ÐµÑˆÑ‚Ð°ÑšÐµ Ð½Ð° Ð²Ñ€Ñ…
+  label_sort_higher: ÐŸÑ€ÐµÐ¼ÐµÑˆÑ‚Ð°ÑšÐµ Ð½Ð° Ð³Ð¾Ñ€Ðµ
+  label_sort_lower: ÐŸÑ€ÐµÐ¼ÐµÑˆÑ‚Ð°ÑšÐµ Ð½Ð° Ð´Ð¾Ð»Ðµ
+  label_sort_lowest: ÐŸÑ€ÐµÐ¼ÐµÑˆÑ‚Ð°ÑšÐµ Ð½Ð° Ð´Ð½Ð¾
+  label_roadmap: ÐŸÐ»Ð°Ð½ Ñ€Ð°Ð´Ð°
+  label_roadmap_due_in: "Ð”Ð¾ÑÐ¿ÐµÐ²Ð° %{value}"
+  label_roadmap_overdue: "%{value} Ð½Ð°Ñ˜ÐºÐ°ÑÐ½Ð¸Ñ˜Ðµ"
+  label_roadmap_no_issues: ÐÐµÐ¼Ð° Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð·Ð° Ð¾Ð²Ñƒ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ñƒ
+  label_search: ÐŸÑ€ÐµÑ‚Ñ€Ð°Ð³Ð°
+  label_result_plural: Ð ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸
+  label_all_words: Ð¡Ð²Ðµ Ñ€ÐµÑ‡Ð¸
+  label_wiki: Wiki
+  label_wiki_edit: Wiki Ð¸Ð·Ð¼ÐµÐ½Ð°
+  label_wiki_edit_plural: Wiki Ð¸Ð·Ð¼ÐµÐ½Ðµ
+  label_wiki_page: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  label_wiki_page_plural: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ
+  label_index_by_title: Ð˜Ð½Ð´ÐµÐºÑÐ¸Ñ€Ð°ÑšÐµ Ð¿Ð¾ Ð½Ð°ÑÐ»Ð¾Ð²Ñƒ
+  label_index_by_date: Ð˜Ð½Ð´ÐµÐºÑÐ¸Ñ€Ð°ÑšÐµ Ð¿Ð¾ Ð´Ð°Ñ‚ÑƒÐ¼Ñƒ
+  label_current_version: Ð¢Ñ€ÐµÐ½ÑƒÑ‚Ð½Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
+  label_preview: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
+  label_feed_plural: Ð˜Ð·Ð²Ð¾Ñ€Ð¸ Ð²ÐµÑÑ‚Ð¸
+  label_changes_details: Ð”ÐµÑ‚Ð°Ñ™Ð¸ ÑÐ²Ð¸Ñ… Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°
+  label_issue_tracking: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  label_spent_time: Ð£Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_overall_spent_time: Ð¦ÐµÐ»Ð¾ÐºÑƒÐ¿Ð½Ð¾ ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_f_hour: "%{value} ÑÐ°Ñ‚"
+  label_f_hour_plural: "%{value} ÑÐ°Ñ‚Ð¸"
+  label_time_tracking: ÐŸÑ€Ð°Ñ›ÐµÑšÐµ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
+  label_change_plural: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ðµ
+  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ°
+  label_commits_per_month: Ð˜Ð·Ð²Ñ€ÑˆÐµÑšÐ° Ð¼ÐµÑÐµÑ‡Ð½Ð¾
+  label_commits_per_author: Ð˜Ð·Ð²Ñ€ÑˆÐµÑšÐ° Ð¿Ð¾ Ð°ÑƒÑ‚Ð¾Ñ€Ñƒ
+  label_view_diff: ÐŸÐ¾Ð³Ð»ÐµÐ´Ð°Ñ˜ Ñ€Ð°Ð·Ð»Ð¸ÐºÐµ
+  label_diff_inline: ÑƒÐ½ÑƒÑ‚Ñ€Ð°
+  label_diff_side_by_side: ÑƒÐ¿Ð¾Ñ€ÐµÐ´Ð¾
+  label_options: ÐžÐ¿Ñ†Ð¸Ñ˜Ðµ
+  label_copy_workflow_from: ÐšÐ¾Ð¿Ð¸Ñ€Ð°ÑšÐµ Ñ‚Ð¾ÐºÐ° Ð¿Ð¾ÑÐ»Ð° Ð¾Ð´
+  label_permissions_report: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ˜ Ð¾ Ð´Ð¾Ð·Ð²Ð¾Ð»Ð°Ð¼Ð°
+  label_watched_issues: ÐŸÐ¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ð½Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
+  label_related_issues: Ð¡Ñ€Ð¾Ð´Ð½Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸
+  label_applied_status: ÐŸÑ€Ð¸Ð¼ÐµÑšÐµÐ½Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸
+  label_loading: Ð£Ñ‡Ð¸Ñ‚Ð°Ð²Ð°ÑšÐµ...
+  label_relation_new: ÐÐ¾Ð²Ð° Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ˜Ð°
+  label_relation_delete: Ð‘Ñ€Ð¸ÑÐ°ÑšÐµ Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ˜Ðµ
+  label_relates_to: ÑÑ€Ð¾Ð´Ð½Ð¸Ñ… ÑÐ°
+  label_duplicates: Ð´ÑƒÐ¿Ð»Ð¸Ñ€Ð°Ð½Ð¸Ñ…
+  label_duplicated_by: Ð´ÑƒÐ¿Ð»Ð¸Ñ€Ð°Ð½Ð¸Ñ… Ð¾Ð´
+  label_blocks: Ð¾Ð´Ð±Ð¸Ñ˜ÐµÐ½Ð¸Ñ…
+  label_blocked_by: Ð¾Ð´Ð±Ð¸Ñ˜ÐµÐ½Ð¸Ñ… Ð¾Ð´
+  label_precedes: Ð¿Ñ€ÐµÑ‚Ñ…Ð¾Ð´Ð¸
+  label_follows: Ð¿Ñ€Ð°Ñ›ÐµÐ½Ð¸Ñ…
+  label_end_to_start: Ð¾Ð´ ÐºÑ€Ð°Ñ˜Ð° Ð´Ð¾ Ð¿Ð¾Ñ‡ÐµÑ‚ÐºÐ°
+  label_end_to_end: Ð¾Ð´ ÐºÑ€Ð°Ñ˜Ð° Ð´Ð¾ ÐºÑ€Ð°Ñ˜Ð°
+  label_start_to_start: Ð¾Ð´ Ð¿Ð¾Ñ‡ÐµÑ‚ÐºÐ° Ð´Ð¾ Ð¿Ð¾Ñ‡ÐµÑ‚ÐºÐ°
+  label_start_to_end: Ð¾Ð´ Ð¿Ð¾Ñ‡ÐµÑ‚ÐºÐ° Ð´Ð¾ ÐºÑ€Ð°Ñ˜Ð°
+  label_stay_logged_in: ÐžÑÑ‚Ð°Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ð¸
+  label_disabled: Ð¾Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›ÐµÐ½Ð¾
+  label_show_completed_versions: ÐŸÑ€Ð¸ÐºÐ°Ð·Ð¸Ð²Ð°ÑšÐµ Ð·Ð°Ð²Ñ€ÑˆÐµÐ½Ðµ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ðµ
+  label_me: Ð¼ÐµÐ½Ð¸
+  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
+  label_board_new: ÐÐ¾Ð²Ð¸ Ñ„Ð¾Ñ€ÑƒÐ¼
+  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
+  label_board_locked: Ð—Ð°ÐºÑ™ÑƒÑ‡Ð°Ð½Ð°
+  label_board_sticky: Ð›ÐµÐ¿Ñ™Ð¸Ð²Ð°
+  label_topic_plural: Ð¢ÐµÐ¼Ðµ
+  label_message_plural: ÐŸÐ¾Ñ€ÑƒÐºÐµ
+  label_message_last: ÐŸÐ¾ÑÐ»ÐµÐ´ÑšÐ° Ð¿Ð¾Ñ€ÑƒÐºÐ°
+  label_message_new: ÐÐ¾Ð²Ð° Ð¿Ð¾Ñ€ÑƒÐºÐ°
+  label_message_posted: ÐŸÐ¾Ñ€ÑƒÐºÐ° Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚Ð°
+  label_reply_plural: ÐžÐ´Ð³Ð¾Ð²Ð¾Ñ€Ð¸
+  label_send_information: ÐŸÐ¾ÑˆÐ°Ñ™Ð¸ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÑƒ Ð´ÐµÑ‚Ð°Ñ™Ðµ Ð½Ð°Ð»Ð¾Ð³Ð°
+  label_year: Ð“Ð¾Ð´Ð¸Ð½Ð°
+  label_month: ÐœÐµÑÐµÑ†
+  label_week: Ð¡ÐµÐ´Ð¼Ð¸Ñ†Ð°
+  label_date_from: Ð¨Ð°Ñ™Ðµ
+  label_date_to: ÐŸÑ€Ð¸Ð¼Ð°
+  label_language_based: Ð‘Ð°Ð·Ð¸Ñ€Ð°Ð½Ð¾ Ð½Ð° Ñ˜ÐµÐ·Ð¸ÐºÑƒ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ°
+  label_sort_by: "Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ð¾ Ð¿Ð¾ %{value}"
+  label_send_test_email: Ð¡Ð»Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð½Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
+  label_feeds_access_key: RSS Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡
+  label_missing_feeds_access_key: RSS Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ˜Ðµ
+  label_feeds_access_key_created_on: "RSS Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ñ˜Ðµ Ð½Ð°Ð¿Ñ€Ð°Ð²Ñ™ÐµÐ½ Ð¿Ñ€Ðµ %{value}"
+  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ð¸
+  label_added_time_by: "Ð”Ð¾Ð´Ð°Ð¾ %{author} Ð¿Ñ€Ðµ %{age}"
+  label_updated_time_by: "ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð¾ %{author} Ð¿Ñ€Ðµ %{age}"
+  label_updated_time: "ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾ Ð¿Ñ€Ðµ %{value}"
+  label_jump_to_a_project: Ð¡ÐºÐ¾Ðº Ð½Ð° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚...
+  label_file_plural: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ
+  label_changeset_plural: Ð¡ÐºÑƒÐ¿Ð¾Ð²Ð¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°
+  label_default_columns: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ðµ ÐºÐ¾Ð»Ð¾Ð½Ðµ
+  label_no_change_option: (Ð‘ÐµÐ· Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°)
+  label_bulk_edit_selected_issues: Ð“Ñ€ÑƒÐ¿Ð½Ð° Ð¸Ð·Ð¼ÐµÐ½Ð° Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  label_theme: Ð¢ÐµÐ¼Ð°
+  label_default: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾
+  label_search_titles_only: ÐŸÑ€ÐµÑ‚Ñ€Ð°Ð¶ÑƒÑ˜ ÑÐ°Ð¼Ð¾ Ð½Ð°ÑÐ»Ð¾Ð²Ðµ
+  label_user_mail_option_all: "Ð—Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ˜Ð¸ Ð´Ð¾Ð³Ð°Ñ’Ð°Ñ˜ Ð½Ð° ÑÐ²Ð¸Ð¼ Ð¼Ð¾Ñ˜Ð¸Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°"
+  label_user_mail_option_selected: "Ð—Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ˜Ð¸ Ð´Ð¾Ð³Ð°Ñ’Ð°Ñ˜ Ð½Ð° ÑÐ°Ð¼Ð¾ Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½Ð¸Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°..."
+  label_user_mail_no_self_notified: "ÐÐµ Ð¶ÐµÐ»Ð¸Ð¼ Ð±Ð¸Ñ‚Ð¸ Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚Ð°Ð²Ð°Ð½ Ð·Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ðµ ÐºÐ¾Ñ˜Ðµ ÑÐ°Ð¼ Ð¿Ñ€Ð°Ð²Ð¸Ð¼"
+  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð°Ð»Ð¾Ð³Ð° Ð¿ÑƒÑ‚ÐµÐ¼ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
+  label_registration_manual_activation: Ñ€ÑƒÑ‡Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð°Ð»Ð¾Ð³Ð°
+  label_registration_automatic_activation: Ð°ÑƒÑ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð°Ð»Ð¾Ð³Ð°
+  label_display_per_page: "Ð‘Ñ€Ð¾Ñ˜ ÑÑ‚Ð°Ð²ÐºÐ¸ Ð¿Ð¾ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸: %{value}"
+  label_age: Ð¡Ñ‚Ð°Ñ€Ð¾ÑÑ‚
+  label_change_properties: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸ ÑÐ²Ð¾Ñ˜ÑÑ‚Ð²Ð°
+  label_general: ÐžÐ¿ÑˆÑ‚Ð¸
+  label_more: Ð’Ð¸ÑˆÐµ
+  label_scm: SCM
+  label_plugins: Ð”Ð¾Ð´Ð°Ñ‚Ð½Ðµ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ðµ
+  label_ldap_authentication: LDAP Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ð° Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‚ÐµÑ‚Ð°
+  label_downloads_abbr: D/L
+  label_optional_description: ÐžÐ¿Ñ†Ð¸Ð¾Ð½Ð¾ Ð¾Ð¿Ð¸Ñ
+  label_add_another_file: Ð”Ð¾Ð´Ð°Ñ˜ Ñ˜Ð¾Ñˆ Ñ˜ÐµÐ´Ð½Ñƒ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÑƒ
+  label_preferences: ÐŸÐ¾Ð´ÐµÑˆÐ°Ð²Ð°ÑšÐ°
+  label_chronological_order: Ð¿Ð¾ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾ÑˆÐºÐ¾Ð¼ Ñ€ÐµÐ´Ð¾ÑÐ»ÐµÐ´Ñƒ
+  label_reverse_chronological_order: Ð¿Ð¾ Ð¾Ð±Ñ€Ð½ÑƒÑ‚Ð¾Ð¼ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾ÑˆÐºÐ¾Ð¼ Ñ€ÐµÐ´Ð¾ÑÐ»ÐµÐ´Ñƒ
+  label_planning: ÐŸÐ»Ð°Ð½Ð¸Ñ€Ð°ÑšÐµ
+  label_incoming_emails: Ð”Ð¾Ð»Ð°Ð·Ð½Ðµ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐµ
+  label_generate_key: Ð“ÐµÐ½ÐµÑ€Ð¸ÑÐ°ÑšÐµ ÐºÑ™ÑƒÑ‡Ð°
+  label_issue_watchers: ÐŸÐ¾ÑÐ¼Ð°Ñ‚Ñ€Ð°Ñ‡Ð¸
+  label_example: ÐŸÑ€Ð¸Ð¼ÐµÑ€
+  label_display: ÐŸÑ€Ð¸ÐºÐ°Ð·
+  label_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°ÑšÐµ
+  label_ascending: Ð Ð°ÑÑ‚ÑƒÑ›Ð¸ Ð½Ð¸Ð·
+  label_descending: ÐžÐ¿Ð°Ð´Ð°Ñ˜ÑƒÑ›Ð¸ Ð½Ð¸Ð·
+  label_date_from_to: ÐžÐ´ %{start} Ð´Ð¾ %{end}
+  label_wiki_content_added: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ñ˜Ðµ Ð´Ð¾Ð´Ð°Ñ‚Ð°
+  label_wiki_content_updated: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°
+  label_group: Ð“Ñ€ÑƒÐ¿Ð°
+  label_group_plural: Ð“Ñ€ÑƒÐ¿Ðµ
+  label_group_new: ÐÐ¾Ð²Ð° Ð³Ñ€ÑƒÐ¿Ð°
+  label_time_entry_plural: Ð£Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_version_sharing_none: ÐÐ¸Ñ˜Ðµ Ð´ÐµÑ™ÐµÐ½Ð¾
+  label_version_sharing_descendants: Ð¡Ð° Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°
+  label_version_sharing_hierarchy: Ð¡Ð° Ñ…Ð¸Ñ˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ˜Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
+  label_version_sharing_tree: Ð¡Ð° ÑÑ‚Ð°Ð±Ð»Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
+  label_version_sharing_system: Ð¡Ð° ÑÐ²Ð¸Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°
+  label_update_issue_done_ratios: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ñ˜ Ð¾Ð´Ð½Ð¾Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ… Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  label_copy_source: Ð˜Ð·Ð²Ð¾Ñ€
+  label_copy_target: ÐžÐ´Ñ€ÐµÐ´Ð¸ÑˆÑ‚Ðµ
+  label_copy_same_as_target: Ð˜ÑÑ‚Ð¾ ÐºÐ°Ð¾ Ð¾Ð´Ñ€ÐµÐ´Ð¸ÑˆÑ‚Ðµ
+  label_display_used_statuses_only: ÐŸÑ€Ð¸ÐºÐ°Ð·ÑƒÑ˜ ÑÑ‚Ð°Ñ‚ÑƒÑÐµ ÐºÐ¾Ñ€Ð¸ÑˆÑ›ÐµÐ½Ðµ ÑÐ°Ð¼Ð¾ Ð¾Ð´ ÑÑ‚Ñ€Ð°Ð½Ðµ Ð¾Ð²Ð¾Ð³ Ð¿Ñ€Ð°Ñ›ÐµÑšÐ°
+  label_api_access_key: API Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡
+  label_missing_api_access_key: ÐÐµÐ´Ð¾ÑÑ‚Ð°Ñ˜Ðµ API Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡
+  label_api_access_key_created_on: "API Ð¿Ñ€Ð¸ÑÑ‚ÑƒÐ¿Ð½Ð¸ ÐºÑ™ÑƒÑ‡ Ñ˜Ðµ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½ Ð¿Ñ€Ðµ %{value}"
+  label_profile: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
+  label_subtask_plural: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº
+  label_project_copy_notifications: ÐŸÐ¾ÑˆÐ°Ñ™Ð¸ Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÑƒ ÑÐ° Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐµÐ¼ Ð¿Ñ€Ð¸Ð»Ð¸ÐºÐ¾Ð¼ ÐºÐ¾Ð¿Ð¸Ñ€Ð°ÑšÐ° Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
+
+  button_login: ÐŸÑ€Ð¸Ñ˜Ð°Ð²Ð°
+  button_submit: ÐŸÐ¾ÑˆÐ°Ñ™Ð¸
+  button_save: Ð¡Ð½Ð¸Ð¼Ð¸
+  button_check_all: Ð£ÐºÑ™ÑƒÑ‡Ð¸ ÑÐ²Ðµ
+  button_uncheck_all: Ð˜ÑÐºÑ™ÑƒÑ‡Ð¸ ÑÐ²Ðµ
+  button_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸
+  button_create: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜
+  button_create_and_continue: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜ Ð¸ Ð½Ð°ÑÑ‚Ð°Ð²Ð¸
+  button_test: Ð¢ÐµÑÑ‚
+  button_edit: Ð˜Ð·Ð¼ÐµÐ½Ð¸
+  button_add: Ð”Ð¾Ð´Ð°Ñ˜
+  button_change: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸
+  button_apply: ÐŸÑ€Ð¸Ð¼ÐµÐ½Ð¸
+  button_clear: ÐžÐ±Ñ€Ð¸ÑˆÐ¸
+  button_lock: Ð—Ð°ÐºÑ™ÑƒÑ‡Ð°Ñ˜
+  button_unlock: ÐžÑ‚ÐºÑ™ÑƒÑ‡Ð°Ñ˜
+  button_download: ÐŸÑ€ÐµÑƒÐ·Ð¼Ð¸
+  button_list: Ð¡Ð¿Ð¸ÑÐ°Ðº
+  button_view: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸
+  button_move: ÐŸÐ¾Ð¼ÐµÑ€Ð¸
+  button_move_and_follow: ÐŸÐ¾Ð¼ÐµÑ€Ð¸ Ð¸ Ð¿Ñ€Ð°Ñ‚Ð¸
+  button_back: ÐÐ°Ð·Ð°Ð´
+  button_cancel: ÐŸÐ¾Ð½Ð¸ÑˆÑ‚Ð¸
+  button_activate: ÐÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
+  button_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ñ˜
+  button_log_time: Ð•Ð²Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ€Ð°Ñ˜ Ð²Ñ€ÐµÐ¼Ðµ
+  button_rollback: ÐŸÐ¾Ð²Ñ€Ð°Ñ‚Ð°Ðº Ð½Ð° Ð¾Ð²Ñƒ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ñƒ
+  button_watch: ÐŸÑ€Ð°Ñ‚Ð¸
+  button_unwatch: ÐÐµ Ð¿Ñ€Ð°Ñ‚Ð¸ Ð²Ð¸ÑˆÐµ
+  button_reply: ÐžÐ´Ð³Ð¾Ð²Ð¾Ñ€Ð¸
+  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
+  button_unarchive: Ð’Ñ€Ð°Ñ‚Ð¸ Ð¸Ð· Ð°Ñ€Ñ…Ð¸Ð²Ðµ
+  button_reset: ÐŸÐ¾Ð½Ð¸ÑˆÑ‚Ð¸
+  button_rename: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÑ˜
+  button_change_password: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÑƒ
+  button_copy: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜
+  button_copy_and_follow: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜ Ð¸ Ð¿Ñ€Ð°Ñ‚Ð¸
+  button_annotate: ÐŸÑ€Ð¸Ð±ÐµÐ»ÐµÐ¶Ð¸
+  button_update: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ñ˜
+  button_configure: ÐŸÐ¾Ð´ÐµÑÐ¸
+  button_quote: ÐŸÐ¾Ð´ Ð½Ð°Ð²Ð¾Ð´Ð½Ð¸Ñ†Ð¸Ð¼Ð°
+  button_duplicate: Ð”ÑƒÐ¿Ð»Ð¸Ñ€Ð°Ñ˜
+  button_show: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸
+
+  status_active: Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¸
+  status_registered: Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½Ð¸
+  status_locked: Ð·Ð°ÐºÑ™ÑƒÑ‡Ð°Ð½Ð¸
+
+  version_status_open: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½
+  version_status_locked: Ð·Ð°ÐºÑ™ÑƒÑ‡Ð°Ð½
+  version_status_closed: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½
+
+  field_active: ÐÐºÑ‚Ð¸Ð²Ð°Ð½
+
+  text_select_mail_notifications: ÐžÐ´Ð°Ð±ÐµÑ€Ð¸ Ð°ÐºÑ†Ð¸Ñ˜Ðµ Ð·Ð° ÐºÐ¾Ñ˜Ðµ Ñ›Ðµ Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐµ Ð±Ð¸Ñ‚Ð¸ Ð¿Ð¾ÑÐ»Ð°Ñ‚Ð¾ Ð¿ÑƒÑ‚ÐµÐ¼ Ðµ-Ð¿Ð¾ÑˆÑ‚Ðµ.
+  text_regexp_info: Ð½Ð¿Ñ€. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 Ð·Ð½Ð°Ñ‡Ð¸ Ð±ÐµÐ· Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÑšÐ°
+  text_project_destroy_confirmation: ÐˆÐµÑÑ‚Ðµ Ð»Ð¸ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¾Ð²Ð°Ñ˜ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚ Ð¸ ÑÐ²Ðµ Ð¿Ñ€Ð¸Ð¿Ð°Ð´Ð°Ñ˜ÑƒÑ›Ðµ Ð¿Ð¾Ð´Ð°Ñ‚ÐºÐµ?
+  text_subprojects_destroy_warning: "ÐŸÐ¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸: %{value} Ñ›Ðµ Ñ‚Ð°ÐºÐ¾Ñ’Ðµ Ð±Ð¸Ñ‚Ð¸ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ð½."
+  text_workflow_edit: ÐžÐ´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ ÑƒÐ»Ð¾Ð³Ñƒ Ð¸ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð·Ð° Ð¸Ð·Ð¼ÐµÐ½Ñƒ Ñ‚Ð¾ÐºÐ° Ð¿Ð¾ÑÐ»Ð°
+  text_are_you_sure: ÐˆÐµÑÑ‚Ðµ Ð»Ð¸ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸?
+  text_journal_changed: "%{label} Ð¿Ñ€Ð¾Ð¼ÐµÑšÐµÐ½ Ð¾Ð´ %{old} Ñƒ %{new}"
+  text_journal_set_to: "%{label} Ð¿Ð¾ÑÑ‚Ð°Ð²Ñ™ÐµÐ½ Ñƒ %{value}"
+  text_journal_deleted: "%{label} Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ð½Ð¾ (%{old})"
+  text_journal_added: "%{label} %{value} Ð´Ð¾Ð´Ð°Ñ‚Ð¾"
+  text_tip_issue_begin_day: Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº Ð¿Ð¾Ñ‡Ð¸ÑšÐµ Ð¾Ð²Ð¾Ð³ Ð´Ð°Ð½Ð°
+  text_tip_issue_end_day: Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº ÑÐµ Ð·Ð°Ð²Ñ€ÑˆÐ°Ð²Ð° Ð¾Ð²Ð¾Ð³ Ð´Ð°Ð½Ð°
+  text_tip_issue_begin_end_day: Ð·Ð°Ð´Ð°Ñ‚Ð°Ðº Ð¿Ð¾Ñ‡Ð¸ÑšÐµ Ð¸ Ð·Ð°Ð²Ñ€ÑˆÐ°Ð²Ð° Ð¾Ð²Ð¾Ð³ Ð´Ð°Ð½Ð°
+  text_caracters_maximum: "ÐÐ°Ñ˜Ð²Ð¸ÑˆÐµ %{count} Ð·Ð½Ð°Ðº(Ð¾Ð²Ð°)."
+  text_caracters_minimum: "Ð‘Ñ€Ð¾Ñ˜ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð½Ð°Ñ˜Ð¼Ð°ÑšÐµ %{count}."
+  text_length_between: "Ð‘Ñ€Ð¾Ñ˜ Ð·Ð½Ð°ÐºÐ¾Ð²Ð° Ð¼Ð¾Ñ€Ð° Ð±Ð¸Ñ‚Ð¸ Ð¸Ð·Ð¼ÐµÑ’Ñƒ %{min} Ð¸ %{max}."
+  text_tracker_no_workflow: ÐžÐ²Ð¾ Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð½ÐµÐ¼Ð° Ð´ÐµÑ„Ð¸Ð½Ð¸ÑÐ°Ð½ Ñ‚Ð¾Ðº Ð¿Ð¾ÑÐ»Ð°
+  text_unallowed_characters: ÐÐµÐ´Ð¾Ð·Ð²Ð¾Ñ™ÐµÐ½Ð¸ Ð·Ð½Ð°ÐºÐ¾Ð²Ð¸
+  text_comma_separated: Ð”Ð¾Ð·Ð²Ð¾Ñ™ÐµÐ½Ðµ ÑÑƒ Ð²Ð¸ÑˆÐµÑÑ‚Ñ€ÑƒÐºÐµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸ (Ð¾Ð´Ð²Ð¾Ñ˜ÐµÐ½Ðµ Ð·Ð°Ñ€ÐµÐ·Ð¾Ð¼).
+  text_line_separated: Ð”Ð¾Ð·Ð²Ð¾Ñ™ÐµÐ½Ðµ ÑÑƒ Ð²Ð¸ÑˆÐµÑÑ‚Ñ€ÑƒÐºÐµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸ (Ñ˜ÐµÐ´Ð°Ð½ Ñ€ÐµÐ´ Ð·Ð° ÑÐ²Ð°ÐºÑƒ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚).
+  text_issues_ref_in_commit_messages: Ð ÐµÑ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ€Ð°ÑšÐµ Ð¸ Ð¿Ð¾Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ñƒ Ð¸Ð·Ð²Ñ€ÑˆÐ½Ð¸Ð¼ Ð¿Ð¾Ñ€ÑƒÐºÐ°Ð¼Ð°
+  text_issue_added: "%{author} Ñ˜Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ð¸Ð¾ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ %{id}."
+  text_issue_updated: "%{author} Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð¾ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ %{id}."
+  text_wiki_destroy_confirmation: ÐˆÐµÑÑ‚Ðµ Ð»Ð¸ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° Ð¾Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ wiki Ð¸ ÑÐ°Ð² ÑÐ°Ð´Ñ€Ð¶Ð°Ñ˜?
+  text_issue_category_destroy_question: "ÐÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° (%{count}) Ñ˜Ðµ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ð¾ Ð¾Ð²Ð¾Ñ˜ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð¸. Ð¨Ñ‚Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° ÑƒÑ€Ð°Ð´Ð¸Ñ‚Ðµ?"
+  text_issue_category_destroy_assignments: Ð£ÐºÐ»Ð¾Ð½Ð¸ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ðµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ðµ
+  text_issue_category_reassign_to: Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ðµ Ð¾Ð²Ð¾Ñ˜ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð¸
+  text_user_mail_option: "Ð—Ð° Ð½ÐµÐ¸Ð·Ð°Ð±Ñ€Ð°Ð½Ðµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ðµ, Ð´Ð¾Ð±Ð¸Ñ›ÐµÑ‚Ðµ ÑÐ°Ð¼Ð¾ Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐµ Ð¾ ÑÑ‚Ð²Ð°Ñ€Ð¸Ð¼Ð° ÐºÐ¾Ñ˜Ðµ Ð¿Ñ€Ð°Ñ‚Ð¸Ñ‚Ðµ Ð¸Ð»Ð¸ ÑÑ‚Ðµ ÑƒÐºÑ™ÑƒÑ‡ÐµÐ½Ð¸ (Ð½Ð¿Ñ€. Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð¸ Ñ‡Ð¸Ñ˜Ð¸ ÑÑ‚Ðµ Ð²Ð¸ Ð°ÑƒÑ‚Ð¾Ñ€ Ð¸Ð»Ð¸ Ð·Ð°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ðº)."
+  text_no_configuration_data: "Ð£Ð»Ð¾Ð³Ðµ, Ð¿Ñ€Ð°Ñ›ÐµÑšÐ°, ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ð¸ Ñ‚Ð¾ÐºÐ° Ð¿Ð¾ÑÐ»Ð° Ñ˜Ð¾Ñˆ ÑƒÐ²ÐµÐº Ð½Ð¸ÑÑƒ Ð¿Ð¾Ð´ÐµÑˆÐµÐ½Ð¸.\nÐŸÑ€ÐµÐ¿Ð¾Ñ€ÑƒÑ‡Ñ™Ð¸Ð²Ð¾ Ñ˜Ðµ Ð´Ð° ÑƒÑ‡Ð¸Ñ‚Ð°Ñ‚Ðµ Ð¿Ð¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ. Ð˜Ð·Ð¼ÐµÐ½Ð° Ñ˜Ðµ Ð¼Ð¾Ð³ÑƒÑ›Ð° Ð½Ð°ÐºÐ¾Ð½ Ð¿Ñ€Ð²Ð¾Ð³ ÑƒÑ‡Ð¸Ñ‚Ð°Ð²Ð°ÑšÐ°."
+  text_load_default_configuration: Ð£Ñ‡Ð¸Ñ‚Ð°Ñ˜ Ð¿Ð¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¾ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°ÑšÐµ
+  text_status_changed_by_changeset: "ÐŸÑ€Ð¸Ð¼ÐµÑšÐµÐ½Ð¾ Ñƒ ÑÐºÑƒÐ¿Ñƒ ÑÐ° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°Ð¼Ð° %{value}."
+  text_issues_destroy_confirmation: 'ÐˆÐµÑÑ‚Ðµ Ð»Ð¸ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¾Ð´Ð°Ð±Ñ€Ð°Ð½Ðµ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ðµ?'
+  text_select_project_modules: 'ÐžÐ´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ðµ ÐºÐ¾Ñ˜Ðµ Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð¾Ð¼Ð¾Ð³ÑƒÑ›Ð¸Ñ‚Ð¸ Ð·Ð° Ð¾Ð²Ð°Ñ˜ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚:'
+  text_default_administrator_account_changed: ÐŸÐ¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°Ð½Ð¸ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€ÑÐºÐ¸ Ð½Ð°Ð»Ð¾Ð³ Ñ˜Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÑšÐµÐ½
+  text_file_repository_writable: Ð¤Ð°ÑÑ†Ð¸ÐºÐ»Ð° Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ… Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ° Ñ˜Ðµ ÑƒÐ¿Ð¸ÑÐ¸Ð²Ð°
+  text_plugin_assets_writable: Ð¤Ð°ÑÑ†Ð¸ÐºÐ»Ð° ÐµÐ»ÐµÐ¼ÐµÐ½Ð°Ñ‚Ð° Ð´Ð¾Ð´Ð°Ñ‚Ð½Ð¸Ñ… ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð¸ Ñ˜Ðµ ÑƒÐ¿Ð¸ÑÐ¸Ð²Ð°
+  text_rmagick_available: RMagick Ñ˜Ðµ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð°Ð½ (Ð¾Ð¿Ñ†Ð¸Ð¾Ð½Ð¾)
+  text_destroy_time_entries_question: "%{hours} ÑÐ°Ñ‚Ð¸ Ñ˜Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ð¾ Ð·Ð° Ð¾Ð²Ð°Ñ˜ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼ ÐºÐ¾Ñ˜Ð¸ Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð¸Ð·Ð±Ñ€Ð¸ÑÐ°Ñ‚Ð¸. Ð¨Ñ‚Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° ÑƒÑ€Ð°Ð´Ð¸Ñ‚Ðµ?"
+  text_destroy_time_entries: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ðµ ÑÐ°Ñ‚Ðµ
+  text_assign_time_entries_to_project: Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ðµ ÑÐ°Ñ‚Ðµ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ñƒ
+  text_reassign_time_entries: 'Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²Ñ™ÐµÐ½Ðµ ÑÐ°Ñ‚Ðµ Ð¾Ð²Ð¾Ð¼ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ñƒ:'
+  text_user_wrote: "%{value} Ñ˜Ðµ Ð½Ð°Ð¿Ð¸ÑÐ°Ð¾:"
+  text_enumeration_destroy_question: "%{count} Ð¾Ð±Ñ˜ÐµÐºÐ°Ñ‚(Ð°) Ñ˜Ðµ Ð´Ð¾Ð´ÐµÑ™ÐµÐ½Ð¾ Ð¾Ð²Ð¾Ñ˜ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸."
+  text_enumeration_category_reassign_to: 'Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¸Ñ… Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¾Ð²Ð¾Ñ˜ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸:'
+  text_email_delivery_not_configured: "Ð˜ÑÐ¿Ð¾Ñ€ÑƒÐºÐ° Ðµ-Ð¿Ð¾Ñ€ÑƒÐºÐ° Ð½Ð¸Ñ˜Ðµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸ÑÐ°Ð½Ð° Ð¸ Ð¾Ð±Ð°Ð²ÐµÑˆÑ‚ÐµÑšÐ° ÑÑƒ Ð¾Ð½ÐµÐ¼Ð¾Ð³ÑƒÑ›ÐµÐ½Ð°.\nÐŸÐ¾Ð´ÐµÑÐ¸Ñ‚Ðµ Ð²Ð°Ñˆ SMTP ÑÐµÑ€Ð²ÐµÑ€ Ñƒ config/configuration.yml Ð¸ Ð¿Ð¾ÐºÑ€ÐµÐ½Ð¸Ñ‚Ðµ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ñƒ Ð·Ð° ÑšÐ¸Ñ…Ð¾Ð²Ð¾ Ð¾Ð¼Ð¾Ð³ÑƒÑ›Ð°Ð²Ð°ÑšÐµ."
+  text_repository_usernames_mapping: "ÐžÐ´Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¸Ð»Ð¸ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ñ˜Ñ‚Ðµ Redmine ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐµ Ð¼Ð°Ð¿Ð¸Ñ€Ð°ÑšÐµÐ¼ ÑÐ²Ð°ÐºÐ¾Ð³ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¾Ð³ Ð¸Ð¼ÐµÐ½Ð° Ð¿Ñ€Ð¾Ð½Ð°Ñ’ÐµÐ½Ð¾Ð³ Ñƒ ÐµÐ²Ð¸Ð´ÐµÐ½Ñ†Ð¸Ñ˜Ð¸ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ð°.\nÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸ ÑÐ° Ð¸ÑÑ‚Ð¸Ð¼ Redmine Ð¸Ð¼ÐµÐ½Ð¾Ð¼ Ð¸ Ð¸Ð¼ÐµÐ½Ð¾Ð¼ ÑÐ¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ð° Ð¸Ð»Ð¸ Ðµ-Ð°Ð´Ñ€ÐµÑÐ¾Ð¼ ÑÑƒ Ð°ÑƒÑ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ¸ Ð¼Ð°Ð¿Ð¸Ñ€Ð°Ð½Ð¸."
+  text_diff_truncated: '... ÐžÐ²Ð° Ñ€Ð°Ð·Ð»Ð¸ÐºÐ° Ñ˜Ðµ Ð¸ÑÐµÑ‡ÐµÐ½Ð° Ñ˜ÐµÑ€ Ñ˜Ðµ Ð´Ð¾ÑÑ‚Ð¸Ð³Ð½ÑƒÑ‚Ð° Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð°.'
+  text_custom_field_possible_values_info: 'ÐˆÐµÐ´Ð°Ð½ Ñ€ÐµÐ´ Ð·Ð° ÑÐ²Ð°ÐºÑƒ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚'
+  text_wiki_page_destroy_question: "ÐžÐ²Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¸Ð¼Ð° %{descendants} Ð¿Ð¾Ð´Ñ€ÐµÑ’ÐµÐ½Ð¸Ñ… ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¸ Ð¿Ð¾Ð´ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°. Ð¨Ñ‚Ð° Ð¶ÐµÐ»Ð¸Ñ‚Ðµ Ð´Ð° ÑƒÑ€Ð°Ð´Ð¸Ñ‚Ðµ?"
+  text_wiki_page_nullify_children: "Ð—Ð°Ð´Ñ€Ð¶Ð¸ Ð¿Ð¾Ð´Ñ€ÐµÑ’ÐµÐ½Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ ÐºÐ°Ð¾ ÐºÐ¾Ñ€ÐµÐ½Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ"
+  text_wiki_page_destroy_children: "Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ Ð¿Ð¾Ð´Ñ€ÐµÑ’ÐµÐ½Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ Ð¸ ÑÐ²Ðµ ÑšÐ¸Ñ…Ð¾Ð²Ðµ Ð¿Ð¾Ð´ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ"
+  text_wiki_page_reassign_children: "Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¿Ð¾Ð´Ñ€ÐµÑ’ÐµÐ½Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ðµ Ð¾Ð²Ð¾Ñ˜ Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾Ñ˜ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸"
+  text_own_membership_delete_confirmation: "ÐÐ°ÐºÐ¾Ð½ ÑƒÐºÐ»Ð°ÑšÐ°ÑšÐ° Ð¿Ð¾Ñ˜ÐµÐ´Ð¸Ð½Ð¸Ñ… Ð¸Ð»Ð¸ ÑÐ²Ð¸Ñ… Ð²Ð°ÑˆÐ¸Ñ… Ð´Ð¾Ð·Ð²Ð¾Ð»Ð° Ð½ÐµÑ›ÐµÑ‚Ðµ Ð²Ð¸ÑˆÐµ Ð¼Ð¾Ñ›Ð¸ Ð´Ð° ÑƒÑ€ÐµÑ’ÑƒÑ˜ÐµÑ‚Ðµ Ð¾Ð²Ð°Ñ˜ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÐ°Ñ‚.\nÐ–ÐµÐ»Ð¸Ñ‚Ðµ Ð»Ð¸ Ð´Ð° Ð½Ð°ÑÑ‚Ð°Ð²Ð¸Ñ‚Ðµ?"
+  text_zoom_in: Ð£Ð²ÐµÑ›Ð°Ñ˜
+  text_zoom_out: Ð£Ð¼Ð°ÑšÐ¸
+
+  default_role_manager: ÐœÐµÐ½Ð°ÑŸÐµÑ€
+  default_role_developer: ÐŸÑ€Ð¾Ð³Ñ€Ð°Ð¼ÐµÑ€
+  default_role_reporter: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ‡
+  default_tracker_bug: Ð“Ñ€ÐµÑˆÐºÐ°
+  default_tracker_feature: Ð¤ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð°Ð»Ð½Ð¾ÑÑ‚
+  default_tracker_support: ÐŸÐ¾Ð´Ñ€ÑˆÐºÐ°
+  default_issue_status_new: ÐÐ¾Ð²Ð¾
+  default_issue_status_in_progress: Ð£ Ñ‚Ð¾ÐºÑƒ
+  default_issue_status_resolved: Ð ÐµÑˆÐµÐ½Ð¾
+  default_issue_status_feedback: ÐŸÐ¾Ð²Ñ€Ð°Ñ‚Ð½Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ð°
+  default_issue_status_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¾
+  default_issue_status_rejected: ÐžÐ´Ð±Ð¸Ñ˜ÐµÐ½Ð¾
+  default_doc_category_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ˜Ð°
+  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸Ñ‡ÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ˜Ð°
+  default_priority_low: ÐÐ¸Ð·Ð°Ðº
+  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»Ð°Ð½
+  default_priority_high: Ð’Ð¸ÑÐ¾Ðº
+  default_priority_urgent: Ð¥Ð¸Ñ‚Ð½Ð¾
+  default_priority_immediate: ÐÐµÐ¿Ð¾ÑÑ€ÐµÐ´Ð½Ð¾
+  default_activity_design: Ð”Ð¸Ð·Ð°Ñ˜Ð½
+  default_activity_development: Ð Ð°Ð·Ð²Ð¾Ñ˜
+
+  enumeration_issue_priorities: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¸ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°
+  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ðµ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°
+  enumeration_activities: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð¸ (Ð¿Ñ€Ð°Ñ›ÐµÑšÐµ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°)
+  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼ÑÐºÐ° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
+
+  field_time_entries: Ð’Ñ€ÐµÐ¼Ðµ ÐµÐ²Ð¸Ð´ÐµÐ½Ñ†Ð¸Ñ˜Ðµ
+  project_module_gantt: Ð“Ð°Ð½Ñ‚Ð¾Ð² Ð´Ð¸Ñ˜Ð°Ð³Ñ€Ð°Ð¼
+  project_module_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
+
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: ÐšÐ¾Ð´Ð¸Ñ€Ð°ÑšÐµ Ð¸Ð·Ð²Ñ€ÑˆÐ½Ð¸Ñ… Ð¿Ð¾Ñ€ÑƒÐºÐ°
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼
+    one:   1 ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼
+    other: "%{count} ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ð¸"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: ÑÐ²Ð¸
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Ð¡Ð° Ð¿Ð¾Ñ‚Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°
+  label_cross_project_tree: Ð¡Ð° ÑÑ‚Ð°Ð±Ð»Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
+  label_cross_project_hierarchy: Ð¡Ð° Ñ…Ð¸Ñ˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ˜Ð¾Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð°
+  label_cross_project_system: Ð¡Ð° ÑÐ²Ð¸Ð¼ Ð¿Ñ€Ð¾Ñ˜ÐµÐºÑ‚Ð¸Ð¼Ð°
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ð£ÐºÑƒÐ¿Ð½Ð¾
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/67/67aa4777ed1332a8a87bb44f4455573440b70d60.svn-base
--- a/.svn/pristine/67/67aa4777ed1332a8a87bb44f4455573440b70d60.svn-base
+++ /dev/null
@@ -1,24 +0,0 @@
-/* ssh views */
-
-CREATE OR REPLACE VIEW ssh_users as
-select login as username, hashed_password as password
-from users
-where status = 1;
-
-
-/* nss views */
-
-CREATE OR REPLACE VIEW nss_groups AS
-select identifier AS name, (id + 5000) AS gid, 'x' AS password
-from projects;
-
-CREATE OR REPLACE VIEW nss_users AS
-select login AS username, CONCAT_WS(' ', firstname, lastname) as realname, (id + 5000) AS uid, 'x' AS password
-from users
-where status = 1;
-
-CREATE OR REPLACE VIEW nss_grouplist AS
-select (members.project_id + 5000) AS gid, users.login AS username 
-from users, members
-where users.id = members.user_id
-and users.status = 1;
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/67/67ef2cb1f5b1a30645948e8400fbb5f9ee122b3c.svn-base
--- /dev/null
+++ b/.svn/pristine/67/67ef2cb1f5b1a30645948e8400fbb5f9ee122b3c.svn-base
@@ -0,0 +1,425 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoriesSubversionControllerTest < ActionController::TestCase
+  tests RepositoriesController
+
+  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
+           :repositories, :issues, :issue_statuses, :changesets, :changes,
+           :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
+
+  PRJ_ID = 3
+  NUM_REV = 11
+
+  def setup
+    Setting.default_language = 'en'
+    User.current = nil
+
+    @project = Project.find(PRJ_ID)
+    @repository = Repository::Subversion.create(:project => @project,
+               :url => self.class.subversion_repository_url)
+    assert @repository
+  end
+
+  if repository_configured?('subversion')
+    def test_new
+      @request.session[:user_id] = 1
+      @project.repository.destroy
+      get :new, :project_id => 'subproject1', :repository_scm => 'Subversion'
+      assert_response :success
+      assert_template 'new'
+      assert_kind_of Repository::Subversion, assigns(:repository)
+      assert assigns(:repository).new_record?
+    end
+
+    def test_show
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_not_nil assigns(:changesets)
+
+      entry = assigns(:entries).detect {|e| e.name == 'subversion_test'}
+      assert_not_nil entry
+      assert_equal 'dir', entry.kind
+      assert_select 'tr.dir a[href=/projects/subproject1/repository/show/subversion_test]'
+
+      assert_tag 'input', :attributes => {:name => 'rev'}
+      assert_tag 'a', :content => 'Statistics'
+      assert_tag 'a', :content => 'Atom'
+      assert_tag :tag => 'a',
+                 :attributes => {:href => '/projects/subproject1/repository'},
+                 :content => 'root'
+    end
+
+    def test_show_non_default
+      Repository::Subversion.create(:project => @project,
+        :url => self.class.subversion_repository_url,
+        :is_default => false, :identifier => 'svn')
+
+      get :show, :id => PRJ_ID, :repository_id => 'svn'
+      assert_response :success
+      assert_template 'show'
+      assert_select 'tr.dir a[href=/projects/subproject1/repository/svn/show/subversion_test]'
+      # Repository menu should link to the main repo
+      assert_select '#main-menu a[href=/projects/subproject1/repository]'
+    end
+
+    def test_browse_directory
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['subversion_test'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal [
+           '[folder_with_brackets]', 'folder', '.project',
+           'helloworld.c', 'textfile.txt'
+         ],
+        assigns(:entries).collect(&:name)
+      entry = assigns(:entries).detect {|e| e.name == 'helloworld.c'}
+      assert_equal 'file', entry.kind
+      assert_equal 'subversion_test/helloworld.c', entry.path
+      assert_tag :a, :content => 'helloworld.c', :attributes => { :class => /text\-x\-c/ }
+    end
+
+    def test_browse_at_given_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['subversion_test'])[:param],
+          :rev => 4
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['folder', '.project', 'helloworld.c', 'helloworld.rb', 'textfile.txt'],
+                   assigns(:entries).collect(&:name)
+    end
+
+    def test_file_changes
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :changes, :id => PRJ_ID,
+          :path => repository_path_hash(['subversion_test', 'folder', 'helloworld.rb'])[:param]
+      assert_response :success
+      assert_template 'changes'
+
+      changesets = assigns(:changesets)
+      assert_not_nil changesets
+      assert_equal %w(6 3 2), changesets.collect(&:revision)
+
+      # svn properties displayed with svn >= 1.5 only
+      if Redmine::Scm::Adapters::SubversionAdapter.client_version_above?([1, 5, 0])
+        assert_not_nil assigns(:properties)
+        assert_equal 'native', assigns(:properties)['svn:eol-style']
+        assert_tag :ul,
+                   :child => { :tag => 'li',
+                               :child => { :tag => 'b', :content => 'svn:eol-style' },
+                               :child => { :tag => 'span', :content => 'native' } }
+      end
+    end
+
+    def test_directory_changes
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :changes, :id => PRJ_ID,
+          :path => repository_path_hash(['subversion_test', 'folder'])[:param]
+      assert_response :success
+      assert_template 'changes'
+
+      changesets = assigns(:changesets)
+      assert_not_nil changesets
+      assert_equal %w(10 9 7 6 5 2), changesets.collect(&:revision)
+    end
+
+    def test_entry
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
+      assert_response :success
+      assert_template 'entry'
+    end
+
+    def test_entry_should_send_if_too_big
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      # no files in the test repo is larger than 1KB...
+      with_settings :file_max_size_displayed => 0 do
+        get :entry, :id => PRJ_ID,
+            :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
+        assert_response :success
+        assert_equal 'attachment; filename="helloworld.c"',
+                     @response.headers['Content-Disposition']
+      end
+    end
+
+    def test_entry_should_send_images_inline
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['subversion_test', 'folder', 'subfolder', 'rubylogo.gif'])[:param]
+      assert_response :success
+      assert_equal 'inline; filename="rubylogo.gif"', response.headers['Content-Disposition']
+    end
+
+    def test_entry_at_given_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['subversion_test', 'helloworld.rb'])[:param],
+          :rev => 2
+      assert_response :success
+      assert_template 'entry'
+      # this line was removed in r3 and file was moved in r6
+      assert_tag :tag => 'td', :attributes => { :class => /line-code/},
+                               :content => /Here's the code/
+    end
+
+    def test_entry_not_found
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['subversion_test', 'zzz.c'])[:param]
+      assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ },
+                 :content => /The entry or revision was not found in the repository/
+    end
+
+    def test_entry_download
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :raw, :id => PRJ_ID,
+          :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
+      assert_response :success
+      assert_equal 'attachment; filename="helloworld.c"', @response.headers['Content-Disposition']
+    end
+
+    def test_directory_entry
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['subversion_test', 'folder'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entry)
+      assert_equal 'folder', assigns(:entry).name
+    end
+
+    # TODO: this test needs fixtures.
+    def test_revision
+      get :revision, :id => 1, :rev => 2
+      assert_response :success
+      assert_template 'revision'
+
+      assert_select 'ul' do
+        assert_select 'li' do
+          # link to the entry at rev 2
+          assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/2/entry/test/some/path/in/the/repo', :text => 'repo'
+          # link to partial diff
+          assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/2/diff/test/some/path/in/the/repo'
+        end
+      end
+    end
+
+    def test_invalid_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :revision, :id => PRJ_ID, :rev => 'something_weird'
+      assert_response 404
+      assert_error_tag :content => /was not found/
+    end
+
+    def test_invalid_revision_diff
+      get :diff, :id => PRJ_ID, :rev => '1', :rev_to => 'something_weird'
+      assert_response 404
+      assert_error_tag :content => /was not found/
+    end
+
+    def test_empty_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['', ' ', nil].each do |r|
+        get :revision, :id => PRJ_ID, :rev => r
+        assert_response 404
+        assert_error_tag :content => /was not found/
+      end
+    end
+
+    # TODO: this test needs fixtures.
+    def test_revision_with_repository_pointing_to_a_subdirectory
+      r = Project.find(1).repository
+      # Changes repository url to a subdirectory
+      r.update_attribute :url, (r.url + '/test/some')
+
+      get :revision, :id => 1, :rev => 2
+      assert_response :success
+      assert_template 'revision'
+
+      assert_select 'ul' do
+        assert_select 'li' do
+          # link to the entry at rev 2
+          assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/2/entry/path/in/the/repo', :text => 'repo'
+          # link to partial diff
+          assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/2/diff/path/in/the/repo'
+        end
+      end
+    end
+
+    def test_revision_diff
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['inline', 'sbs'].each do |dt|
+        get :diff, :id => PRJ_ID, :rev => 3, :type => dt
+        assert_response :success
+        assert_template 'diff'
+        assert_select 'h2', :text => /Revision 3/
+        assert_select 'th.filename', :text => 'subversion_test/textfile.txt'
+      end
+    end
+
+    def test_revision_diff_raw_format
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      get :diff, :id => PRJ_ID, :rev => 3, :format => 'diff'
+      assert_response :success
+      assert_equal 'text/x-patch', @response.content_type
+      assert_equal 'Index: subversion_test/textfile.txt', @response.body.split(/\r?\n/).first
+    end
+
+    def test_directory_diff
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['inline', 'sbs'].each do |dt|
+        get :diff, :id => PRJ_ID, :rev => 6, :rev_to => 2,
+            :path => repository_path_hash(['subversion_test', 'folder'])[:param],
+            :type => dt
+        assert_response :success
+        assert_template 'diff'
+
+        diff = assigns(:diff)
+        assert_not_nil diff
+        # 2 files modified
+        assert_equal 2, Redmine::UnifiedDiff.new(diff).size
+        assert_tag :tag => 'h2', :content => /2:6/
+      end
+    end
+
+    def test_annotate
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :annotate, :id => PRJ_ID,
+          :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
+      assert_response :success
+      assert_template 'annotate'
+
+      assert_select 'tr' do
+        assert_select 'th.line-num', :text => '1'
+        assert_select 'td.revision', :text => '4'
+        assert_select 'td.author', :text => 'jp'
+        assert_select 'td', :text => /stdio.h/
+      end
+      # Same revision
+      assert_select 'tr' do
+        assert_select 'th.line-num', :text => '2'
+        assert_select 'td.revision', :text => ''
+        assert_select 'td.author', :text => ''
+      end
+    end
+
+    def test_annotate_at_given_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :annotate, :id => PRJ_ID, :rev => 8,
+          :path => repository_path_hash(['subversion_test', 'helloworld.c'])[:param]
+      assert_response :success
+      assert_template 'annotate'
+      assert_tag :tag => 'h2', :content => /@ 8/
+    end
+
+    def test_destroy_valid_repository
+      @request.session[:user_id] = 1 # admin
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      assert_equal NUM_REV, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+
+    def test_destroy_invalid_repository
+      @request.session[:user_id] = 1 # admin
+      @project.repository.destroy
+      @repository = Repository::Subversion.create!(
+                       :project => @project,
+                       :url     => "file:///invalid")
+      @repository.fetch_changesets
+      assert_equal 0, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+  else
+    puts "Subversion test repository NOT FOUND. Skipping functional tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/67/67f3eefb3b2c497cfa5d20b68f15bca1281bb897.svn-base
--- a/.svn/pristine/67/67f3eefb3b2c497cfa5d20b68f15bca1281bb897.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<%= error_messages_for 'category' %>
-
-<div class="box">
-<p><%= f.text_field :name, :size => 30, :required => true %></p>
-<p><%= f.select :assigned_to_id, principals_options_for_select(@project.assignable_users, @category.assigned_to), :include_blank => true %></p>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/68/68223188fb3e37e391044629dba24730132e043f.svn-base
--- /dev/null
+++ b/.svn/pristine/68/68223188fb3e37e391044629dba24730132e043f.svn-base
@@ -0,0 +1,512 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+desc 'Mantis migration script'
+
+require 'active_record'
+require 'iconv' if RUBY_VERSION < '1.9'
+require 'pp'
+
+namespace :redmine do
+task :migrate_from_mantis => :environment do
+
+  module MantisMigrate
+
+      DEFAULT_STATUS = IssueStatus.default
+      assigned_status = IssueStatus.find_by_position(2)
+      resolved_status = IssueStatus.find_by_position(3)
+      feedback_status = IssueStatus.find_by_position(4)
+      closed_status = IssueStatus.where(:is_closed => true).first
+      STATUS_MAPPING = {10 => DEFAULT_STATUS,  # new
+                        20 => feedback_status, # feedback
+                        30 => DEFAULT_STATUS,  # acknowledged
+                        40 => DEFAULT_STATUS,  # confirmed
+                        50 => assigned_status, # assigned
+                        80 => resolved_status, # resolved
+                        90 => closed_status    # closed
+                        }
+
+      priorities = IssuePriority.all
+      DEFAULT_PRIORITY = priorities[2]
+      PRIORITY_MAPPING = {10 => priorities[1], # none
+                          20 => priorities[1], # low
+                          30 => priorities[2], # normal
+                          40 => priorities[3], # high
+                          50 => priorities[4], # urgent
+                          60 => priorities[5]  # immediate
+                          }
+
+      TRACKER_BUG = Tracker.find_by_position(1)
+      TRACKER_FEATURE = Tracker.find_by_position(2)
+
+      roles = Role.where(:builtin => 0).order('position ASC').all
+      manager_role = roles[0]
+      developer_role = roles[1]
+      DEFAULT_ROLE = roles.last
+      ROLE_MAPPING = {10 => DEFAULT_ROLE,   # viewer
+                      25 => DEFAULT_ROLE,   # reporter
+                      40 => DEFAULT_ROLE,   # updater
+                      55 => developer_role, # developer
+                      70 => manager_role,   # manager
+                      90 => manager_role    # administrator
+                      }
+
+      CUSTOM_FIELD_TYPE_MAPPING = {0 => 'string', # String
+                                   1 => 'int',    # Numeric
+                                   2 => 'int',    # Float
+                                   3 => 'list',   # Enumeration
+                                   4 => 'string', # Email
+                                   5 => 'bool',   # Checkbox
+                                   6 => 'list',   # List
+                                   7 => 'list',   # Multiselection list
+                                   8 => 'date',   # Date
+                                   }
+
+      RELATION_TYPE_MAPPING = {1 => IssueRelation::TYPE_RELATES,    # related to
+                               2 => IssueRelation::TYPE_RELATES,    # parent of
+                               3 => IssueRelation::TYPE_RELATES,    # child of
+                               0 => IssueRelation::TYPE_DUPLICATES, # duplicate of
+                               4 => IssueRelation::TYPE_DUPLICATES  # has duplicate
+                               }
+
+    class MantisUser < ActiveRecord::Base
+      self.table_name = :mantis_user_table
+
+      def firstname
+        @firstname = realname.blank? ? username : realname.split.first[0..29]
+        @firstname
+      end
+
+      def lastname
+        @lastname = realname.blank? ? '-' : realname.split[1..-1].join(' ')[0..29]
+        @lastname = '-' if @lastname.blank?
+        @lastname
+      end
+
+      def email
+        if read_attribute(:email).match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i) &&
+             !User.find_by_mail(read_attribute(:email))
+          @email = read_attribute(:email)
+        else
+          @email = "#{username}@foo.bar"
+        end
+      end
+
+      def username
+        read_attribute(:username)[0..29].gsub(/[^a-zA-Z0-9_\-@\.]/, '-')
+      end
+    end
+
+    class MantisProject < ActiveRecord::Base
+      self.table_name = :mantis_project_table
+      has_many :versions, :class_name => "MantisVersion", :foreign_key => :project_id
+      has_many :categories, :class_name => "MantisCategory", :foreign_key => :project_id
+      has_many :news, :class_name => "MantisNews", :foreign_key => :project_id
+      has_many :members, :class_name => "MantisProjectUser", :foreign_key => :project_id
+
+      def identifier
+        read_attribute(:name).gsub(/[^a-z0-9\-]+/, '-').slice(0, Project::IDENTIFIER_MAX_LENGTH)
+      end
+    end
+
+    class MantisVersion < ActiveRecord::Base
+      self.table_name = :mantis_project_version_table
+
+      def version
+        read_attribute(:version)[0..29]
+      end
+
+      def description
+        read_attribute(:description)[0..254]
+      end
+    end
+
+    class MantisCategory < ActiveRecord::Base
+      self.table_name = :mantis_project_category_table
+    end
+
+    class MantisProjectUser < ActiveRecord::Base
+      self.table_name = :mantis_project_user_list_table
+    end
+
+    class MantisBug < ActiveRecord::Base
+      self.table_name = :mantis_bug_table
+      belongs_to :bug_text, :class_name => "MantisBugText", :foreign_key => :bug_text_id
+      has_many :bug_notes, :class_name => "MantisBugNote", :foreign_key => :bug_id
+      has_many :bug_files, :class_name => "MantisBugFile", :foreign_key => :bug_id
+      has_many :bug_monitors, :class_name => "MantisBugMonitor", :foreign_key => :bug_id
+    end
+
+    class MantisBugText < ActiveRecord::Base
+      self.table_name = :mantis_bug_text_table
+
+      # Adds Mantis steps_to_reproduce and additional_information fields
+      # to description if any
+      def full_description
+        full_description = description
+        full_description += "\n\n*Steps to reproduce:*\n\n#{steps_to_reproduce}" unless steps_to_reproduce.blank?
+        full_description += "\n\n*Additional information:*\n\n#{additional_information}" unless additional_information.blank?
+        full_description
+      end
+    end
+
+    class MantisBugNote < ActiveRecord::Base
+      self.table_name = :mantis_bugnote_table
+      belongs_to :bug, :class_name => "MantisBug", :foreign_key => :bug_id
+      belongs_to :bug_note_text, :class_name => "MantisBugNoteText", :foreign_key => :bugnote_text_id
+    end
+
+    class MantisBugNoteText < ActiveRecord::Base
+      self.table_name = :mantis_bugnote_text_table
+    end
+
+    class MantisBugFile < ActiveRecord::Base
+      self.table_name = :mantis_bug_file_table
+
+      def size
+        filesize
+      end
+
+      def original_filename
+        MantisMigrate.encode(filename)
+      end
+
+      def content_type
+        file_type
+      end
+
+      def read(*args)
+          if @read_finished
+              nil
+          else
+              @read_finished = true
+              content
+          end
+      end
+    end
+
+    class MantisBugRelationship < ActiveRecord::Base
+      self.table_name = :mantis_bug_relationship_table
+    end
+
+    class MantisBugMonitor < ActiveRecord::Base
+      self.table_name = :mantis_bug_monitor_table
+    end
+
+    class MantisNews < ActiveRecord::Base
+      self.table_name = :mantis_news_table
+    end
+
+    class MantisCustomField < ActiveRecord::Base
+      self.table_name = :mantis_custom_field_table
+      set_inheritance_column :none
+      has_many :values, :class_name => "MantisCustomFieldString", :foreign_key => :field_id
+      has_many :projects, :class_name => "MantisCustomFieldProject", :foreign_key => :field_id
+
+      def format
+        read_attribute :type
+      end
+
+      def name
+        read_attribute(:name)[0..29]
+      end
+    end
+
+    class MantisCustomFieldProject < ActiveRecord::Base
+      self.table_name = :mantis_custom_field_project_table
+    end
+
+    class MantisCustomFieldString < ActiveRecord::Base
+      self.table_name = :mantis_custom_field_string_table
+    end
+
+    def self.migrate
+
+      # Users
+      print "Migrating users"
+      User.delete_all "login <> 'admin'"
+      users_map = {}
+      users_migrated = 0
+      MantisUser.all.each do |user|
+        u = User.new :firstname => encode(user.firstname),
+                     :lastname => encode(user.lastname),
+                     :mail => user.email,
+                     :last_login_on => user.last_visit
+        u.login = user.username
+        u.password = 'mantis'
+        u.status = User::STATUS_LOCKED if user.enabled != 1
+        u.admin = true if user.access_level == 90
+        next unless u.save!
+        users_migrated += 1
+        users_map[user.id] = u.id
+        print '.'
+      end
+      puts
+
+      # Projects
+      print "Migrating projects"
+      Project.destroy_all
+      projects_map = {}
+      versions_map = {}
+      categories_map = {}
+      MantisProject.all.each do |project|
+        p = Project.new :name => encode(project.name),
+                        :description => encode(project.description)
+        p.identifier = project.identifier
+        next unless p.save
+        projects_map[project.id] = p.id
+        p.enabled_module_names = ['issue_tracking', 'news', 'wiki']
+        p.trackers << TRACKER_BUG unless p.trackers.include?(TRACKER_BUG)
+        p.trackers << TRACKER_FEATURE unless p.trackers.include?(TRACKER_FEATURE)
+        print '.'
+
+        # Project members
+        project.members.each do |member|
+          m = Member.new :user => User.find_by_id(users_map[member.user_id]),
+                           :roles => [ROLE_MAPPING[member.access_level] || DEFAULT_ROLE]
+          m.project = p
+          m.save
+        end
+
+        # Project versions
+        project.versions.each do |version|
+          v = Version.new :name => encode(version.version),
+                          :description => encode(version.description),
+                          :effective_date => (version.date_order ? version.date_order.to_date : nil)
+          v.project = p
+          v.save
+          versions_map[version.id] = v.id
+        end
+
+        # Project categories
+        project.categories.each do |category|
+          g = IssueCategory.new :name => category.category[0,30]
+          g.project = p
+          g.save
+          categories_map[category.category] = g.id
+        end
+      end
+      puts
+
+      # Bugs
+      print "Migrating bugs"
+      Issue.destroy_all
+      issues_map = {}
+      keep_bug_ids = (Issue.count == 0)
+      MantisBug.find_each(:batch_size => 200) do |bug|
+        next unless projects_map[bug.project_id] && users_map[bug.reporter_id]
+        i = Issue.new :project_id => projects_map[bug.project_id],
+                      :subject => encode(bug.summary),
+                      :description => encode(bug.bug_text.full_description),
+                      :priority => PRIORITY_MAPPING[bug.priority] || DEFAULT_PRIORITY,
+                      :created_on => bug.date_submitted,
+                      :updated_on => bug.last_updated
+        i.author = User.find_by_id(users_map[bug.reporter_id])
+        i.category = IssueCategory.find_by_project_id_and_name(i.project_id, bug.category[0,30]) unless bug.category.blank?
+        i.fixed_version = Version.find_by_project_id_and_name(i.project_id, bug.fixed_in_version) unless bug.fixed_in_version.blank?
+        i.status = STATUS_MAPPING[bug.status] || DEFAULT_STATUS
+        i.tracker = (bug.severity == 10 ? TRACKER_FEATURE : TRACKER_BUG)
+        i.id = bug.id if keep_bug_ids
+        next unless i.save
+        issues_map[bug.id] = i.id
+        print '.'
+        STDOUT.flush
+
+        # Assignee
+        # Redmine checks that the assignee is a project member
+        if (bug.handler_id && users_map[bug.handler_id])
+          i.assigned_to = User.find_by_id(users_map[bug.handler_id])
+          i.save(:validate => false)
+        end
+
+        # Bug notes
+        bug.bug_notes.each do |note|
+          next unless users_map[note.reporter_id]
+          n = Journal.new :notes => encode(note.bug_note_text.note),
+                          :created_on => note.date_submitted
+          n.user = User.find_by_id(users_map[note.reporter_id])
+          n.journalized = i
+          n.save
+        end
+
+        # Bug files
+        bug.bug_files.each do |file|
+          a = Attachment.new :created_on => file.date_added
+          a.file = file
+          a.author = User.first
+          a.container = i
+          a.save
+        end
+
+        # Bug monitors
+        bug.bug_monitors.each do |monitor|
+          next unless users_map[monitor.user_id]
+          i.add_watcher(User.find_by_id(users_map[monitor.user_id]))
+        end
+      end
+
+      # update issue id sequence if needed (postgresql)
+      Issue.connection.reset_pk_sequence!(Issue.table_name) if Issue.connection.respond_to?('reset_pk_sequence!')
+      puts
+
+      # Bug relationships
+      print "Migrating bug relations"
+      MantisBugRelationship.all.each do |relation|
+        next unless issues_map[relation.source_bug_id] && issues_map[relation.destination_bug_id]
+        r = IssueRelation.new :relation_type => RELATION_TYPE_MAPPING[relation.relationship_type]
+        r.issue_from = Issue.find_by_id(issues_map[relation.source_bug_id])
+        r.issue_to = Issue.find_by_id(issues_map[relation.destination_bug_id])
+        pp r unless r.save
+        print '.'
+        STDOUT.flush
+      end
+      puts
+
+      # News
+      print "Migrating news"
+      News.destroy_all
+      MantisNews.where('project_id > 0').all.each do |news|
+        next unless projects_map[news.project_id]
+        n = News.new :project_id => projects_map[news.project_id],
+                     :title => encode(news.headline[0..59]),
+                     :description => encode(news.body),
+                     :created_on => news.date_posted
+        n.author = User.find_by_id(users_map[news.poster_id])
+        n.save
+        print '.'
+        STDOUT.flush
+      end
+      puts
+
+      # Custom fields
+      print "Migrating custom fields"
+      IssueCustomField.destroy_all
+      MantisCustomField.all.each do |field|
+        f = IssueCustomField.new :name => field.name[0..29],
+                                 :field_format => CUSTOM_FIELD_TYPE_MAPPING[field.format],
+                                 :min_length => field.length_min,
+                                 :max_length => field.length_max,
+                                 :regexp => field.valid_regexp,
+                                 :possible_values => field.possible_values.split('|'),
+                                 :is_required => field.require_report?
+        next unless f.save
+        print '.'
+        STDOUT.flush
+        # Trackers association
+        f.trackers = Tracker.all
+
+        # Projects association
+        field.projects.each do |project|
+          f.projects << Project.find_by_id(projects_map[project.project_id]) if projects_map[project.project_id]
+        end
+
+        # Values
+        field.values.each do |value|
+          v = CustomValue.new :custom_field_id => f.id,
+                              :value => value.value
+          v.customized = Issue.find_by_id(issues_map[value.bug_id]) if issues_map[value.bug_id]
+          v.save
+        end unless f.new_record?
+      end
+      puts
+
+      puts
+      puts "Users:           #{users_migrated}/#{MantisUser.count}"
+      puts "Projects:        #{Project.count}/#{MantisProject.count}"
+      puts "Memberships:     #{Member.count}/#{MantisProjectUser.count}"
+      puts "Versions:        #{Version.count}/#{MantisVersion.count}"
+      puts "Categories:      #{IssueCategory.count}/#{MantisCategory.count}"
+      puts "Bugs:            #{Issue.count}/#{MantisBug.count}"
+      puts "Bug notes:       #{Journal.count}/#{MantisBugNote.count}"
+      puts "Bug files:       #{Attachment.count}/#{MantisBugFile.count}"
+      puts "Bug relations:   #{IssueRelation.count}/#{MantisBugRelationship.count}"
+      puts "Bug monitors:    #{Watcher.count}/#{MantisBugMonitor.count}"
+      puts "News:            #{News.count}/#{MantisNews.count}"
+      puts "Custom fields:   #{IssueCustomField.count}/#{MantisCustomField.count}"
+    end
+
+    def self.encoding(charset)
+      @charset = charset
+    end
+
+    def self.establish_connection(params)
+      constants.each do |const|
+        klass = const_get(const)
+        next unless klass.respond_to? 'establish_connection'
+        klass.establish_connection params
+      end
+    end
+
+    def self.encode(text)
+      if RUBY_VERSION < '1.9'
+        @ic ||= Iconv.new('UTF-8', @charset)
+        @ic.iconv text
+      else
+        text.to_s.force_encoding(@charset).encode('UTF-8')
+      end
+    end
+  end
+
+  puts
+  if Redmine::DefaultData::Loader.no_data?
+    puts "Redmine configuration need to be loaded before importing data."
+    puts "Please, run this first:"
+    puts
+    puts "  rake redmine:load_default_data RAILS_ENV=\"#{ENV['RAILS_ENV']}\""
+    exit
+  end
+
+  puts "WARNING: Your Redmine data will be deleted during this process."
+  print "Are you sure you want to continue ? [y/N] "
+  STDOUT.flush
+  break unless STDIN.gets.match(/^y$/i)
+
+  # Default Mantis database settings
+  db_params = {:adapter => 'mysql2',
+               :database => 'bugtracker',
+               :host => 'localhost',
+               :username => 'root',
+               :password => '' }
+
+  puts
+  puts "Please enter settings for your Mantis database"
+  [:adapter, :host, :database, :username, :password].each do |param|
+    print "#{param} [#{db_params[param]}]: "
+    value = STDIN.gets.chomp!
+    db_params[param] = value unless value.blank?
+  end
+
+  while true
+    print "encoding [UTF-8]: "
+    STDOUT.flush
+    encoding = STDIN.gets.chomp!
+    encoding = 'UTF-8' if encoding.blank?
+    break if MantisMigrate.encoding encoding
+    puts "Invalid encoding!"
+  end
+  puts
+
+  # Make sure bugs can refer bugs in other projects
+  Setting.cross_project_issue_relations = 1 if Setting.respond_to? 'cross_project_issue_relations'
+
+  # Turn off email notifications
+  Setting.notified_events = []
+
+  MantisMigrate.establish_connection db_params
+  MantisMigrate.migrate
+end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/68/6868bae4892efaa793d57d13538c445e84b6efeb.svn-base
--- a/.svn/pristine/68/6868bae4892efaa793d57d13538c445e84b6efeb.svn-base
+++ /dev/null
@@ -1,41 +0,0 @@
-<%= error_messages_for 'tracker' %>
-
-<div class="splitcontentleft">
-<div class="box tabular">
-<!--[form:tracker]-->
-<p><%= f.text_field :name, :required => true %></p>
-<p><%= f.check_box :is_in_roadmap %></p>
-
-<% if IssueCustomField.all.any? %>
-<p>
-  <label><%= l(:label_custom_field_plural) %></label>
-  <% IssueCustomField.all.each do |field| %>
-    <label class="block">
-      <%= check_box_tag 'tracker[custom_field_ids][]',field.id, @tracker.custom_fields.include?(field) %>
-      <%=h field.name %>
-    </label>
-  <% end %>
-</p>
-<%= hidden_field_tag 'tracker[custom_field_ids][]', '' %>
-<% end %>
-
-<% if @tracker.new_record? && @trackers.any? %>
-<p><label for="copy_workflow_from"><%= l(:label_copy_workflow_from) %></label>
-<%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@trackers, :id, :name)) %></p>
-<% end %>
-<!--[eoform:tracker]-->
-</div>
-<%= submit_tag l(@tracker.new_record? ? :button_create : :button_save) %>
-</div>
-
-<div class="splitcontentright">
-<% if @projects.any? %>
-<fieldset class="box" id="tracker_project_ids"><legend><%= l(:label_project_plural) %></legend>
-<%= project_nested_ul(@projects) do |p|
-  content_tag('label', check_box_tag('tracker[project_ids][]', p.id, @tracker.projects.include?(p), :id => nil) + ' ' + h(p))
-end %>
-<%= hidden_field_tag('tracker[project_ids][]', '', :id => nil) %>
-<p><%= check_all_links 'tracker_project_ids' %></p>
-</fieldset>
-<% end %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/68/6879000e58347aae2d239ff118e15a1cadd798ce.svn-base
--- a/.svn/pristine/68/6879000e58347aae2d239ff118e15a1cadd798ce.svn-base
+++ /dev/null
@@ -1,1121 +0,0 @@
-# Russian localization for Ruby on Rails 2.2+
-# by Yaroslav Markin <yaroslav@markin.net>
-#
-# Be sure to check out "russian" gem (http://github.com/yaroslav/russian) for
-# full Russian language support in Rails (month names, pluralization, etc).
-# The following is an excerpt from that gem.
-#
-# Ð”Ð»Ñ Ð¿Ð¾Ð»Ð½Ð¾Ñ†ÐµÐ½Ð½Ð¾Ð¹ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ Ñ€ÑƒÑÑÐºÐ¾Ð³Ð¾ ÑÐ·Ñ‹ÐºÐ° (Ð²Ð°Ñ€Ð¸Ð°Ð½Ñ‚Ñ‹ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ð¹ Ð¼ÐµÑÑÑ†ÐµÐ²,
-# Ð¿Ð»ÑŽÑ€Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¸ Ñ‚Ð°Ðº Ð´Ð°Ð»ÐµÐµ) Ð² Rails 2.2 Ð½ÑƒÐ¶Ð½Ð¾ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÑŒ gem "russian"
-# (http://github.com/yaroslav/russian). Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð¸Ðµ Ð´Ð°Ð½Ð½Ñ‹Ðµ -- Ð²Ñ‹Ð´ÐµÑ€Ð¶ÐºÐ° Ð¸Ñ… Ð½ÐµÐ³Ð¾, Ñ‡Ñ‚Ð¾Ð±Ñ‹
-# Ð±Ñ‹Ð»Ð° Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ÑŒ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ð¹ Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ð° Ñ€ÑƒÑÑÐºÐ¸Ð¹ ÑÐ·Ñ‹Ðº.
-
-ru:
-  direction: ltr
-  date:
-    formats:
-      default: "%d.%m.%Y"
-      short: "%d %b"
-      long: "%d %B %Y"
-
-    day_names: [Ð²Ð¾ÑÐºÑ€ÐµÑÐµÐ½ÑŒÐµ, Ð¿Ð¾Ð½ÐµÐ´ÐµÐ»ÑŒÐ½Ð¸Ðº, Ð²Ñ‚Ð¾Ñ€Ð½Ð¸Ðº, ÑÑ€ÐµÐ´Ð°, Ñ‡ÐµÑ‚Ð²ÐµÑ€Ð³, Ð¿ÑÑ‚Ð½Ð¸Ñ†Ð°, ÑÑƒÐ±Ð±Ð¾Ñ‚Ð°]
-    standalone_day_names: [Ð’Ð¾ÑÐºÑ€ÐµÑÐµÐ½ÑŒÐµ, ÐŸÐ¾Ð½ÐµÐ´ÐµÐ»ÑŒÐ½Ð¸Ðº, Ð’Ñ‚Ð¾Ñ€Ð½Ð¸Ðº, Ð¡Ñ€ÐµÐ´Ð°, Ð§ÐµÑ‚Ð²ÐµÑ€Ð³, ÐŸÑÑ‚Ð½Ð¸Ñ†Ð°, Ð¡ÑƒÐ±Ð±Ð¾Ñ‚Ð°]
-    abbr_day_names: [Ð’Ñ, ÐŸÐ½, Ð’Ñ‚, Ð¡Ñ€, Ð§Ñ‚, ÐŸÑ‚, Ð¡Ð±]
-
-    month_names: [~, ÑÐ½Ð²Ð°Ñ€Ñ, Ñ„ÐµÐ²Ñ€Ð°Ð»Ñ, Ð¼Ð°Ñ€Ñ‚Ð°, Ð°Ð¿Ñ€ÐµÐ»Ñ, Ð¼Ð°Ñ, Ð¸ÑŽÐ½Ñ, Ð¸ÑŽÐ»Ñ, Ð°Ð²Ð³ÑƒÑÑ‚Ð°, ÑÐµÐ½Ñ‚ÑÐ±Ñ€Ñ, Ð¾ÐºÑ‚ÑÐ±Ñ€Ñ, Ð½Ð¾ÑÐ±Ñ€Ñ, Ð´ÐµÐºÐ°Ð±Ñ€Ñ]
-    # see russian gem for info on "standalone" day names
-    standalone_month_names: [~, Ð¯Ð½Ð²Ð°Ñ€ÑŒ, Ð¤ÐµÐ²Ñ€Ð°Ð»ÑŒ, ÐœÐ°Ñ€Ñ‚, ÐÐ¿Ñ€ÐµÐ»ÑŒ, ÐœÐ°Ð¹, Ð˜ÑŽÐ½ÑŒ, Ð˜ÑŽÐ»ÑŒ, ÐÐ²Ð³ÑƒÑÑ‚, Ð¡ÐµÐ½Ñ‚ÑÐ±Ñ€ÑŒ, ÐžÐºÑ‚ÑÐ±Ñ€ÑŒ, ÐÐ¾ÑÐ±Ñ€ÑŒ, Ð”ÐµÐºÐ°Ð±Ñ€ÑŒ]
-    abbr_month_names: [~, ÑÐ½Ð²., Ñ„ÐµÐ²Ñ€., Ð¼Ð°Ñ€Ñ‚Ð°, Ð°Ð¿Ñ€., Ð¼Ð°Ñ, Ð¸ÑŽÐ½Ñ, Ð¸ÑŽÐ»Ñ, Ð°Ð²Ð³., ÑÐµÐ½Ñ‚., Ð¾ÐºÑ‚., Ð½Ð¾ÑÐ±., Ð´ÐµÐº.]
-    standalone_abbr_month_names: [~, ÑÐ½Ð²., Ñ„ÐµÐ²Ñ€., Ð¼Ð°Ñ€Ñ‚, Ð°Ð¿Ñ€., Ð¼Ð°Ð¹, Ð¸ÑŽÐ½ÑŒ, Ð¸ÑŽÐ»ÑŒ, Ð°Ð²Ð³., ÑÐµÐ½Ñ‚., Ð¾ÐºÑ‚., Ð½Ð¾ÑÐ±., Ð´ÐµÐº.]
-
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%a, %d %b %Y, %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b, %H:%M"
-      long: "%d %B %Y, %H:%M"
-
-    am: "ÑƒÑ‚Ñ€Ð°"
-    pm: "Ð²ÐµÑ‡ÐµÑ€Ð°"
-
-  number:
-    format:
-      separator: ","
-      delimiter: " "
-      precision: 3
-
-    currency:
-      format:
-        format: "%n %u"
-        unit: "Ñ€ÑƒÐ±."
-        separator: "."
-        delimiter: " "
-        precision: 2
-
-    percentage:
-      format:
-        delimiter: ""
-
-    precision:
-      format:
-        delimiter: ""
-
-    human:
-      format:
-        delimiter: ""
-        precision: 2
-      # Rails 2.2
-      # storage_units: [Ð±Ð°Ð¹Ñ‚, ÐšÐ‘, ÐœÐ‘, Ð“Ð‘, Ð¢Ð‘]
-
-      # Rails 2.3
-      storage_units:
-        # Storage units output formatting.
-        # %u is the storage unit, %n is the number (default: 2 MB)
-        format: "%n %u"
-        units:
-          byte:
-            one:   "Ð±Ð°Ð¹Ñ‚"
-            few:   "Ð±Ð°Ð¹Ñ‚Ð°"
-            many:  "Ð±Ð°Ð¹Ñ‚"
-            other: "Ð±Ð°Ð¹Ñ‚Ð°"
-          kb: "ÐšÐ‘"
-          mb: "ÐœÐ‘"
-          gb: "Ð“Ð‘"
-          tb: "Ð¢Ð‘"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "Ð¼ÐµÐ½ÑŒÑˆÐµ Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
-      less_than_x_seconds:
-        one:   "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐµÐºÑƒÐ½Ð´Ñ‹"
-        few:   "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐµÐºÑƒÐ½Ð´"
-        many:  "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐµÐºÑƒÐ½Ð´"
-        other: "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐµÐºÑƒÐ½Ð´Ñ‹"
-      x_seconds:
-        one:   "%{count} ÑÐµÐºÑƒÐ½Ð´Ð°"
-        few:   "%{count} ÑÐµÐºÑƒÐ½Ð´Ñ‹"
-        many:  "%{count} ÑÐµÐºÑƒÐ½Ð´"
-        other: "%{count} ÑÐµÐºÑƒÐ½Ð´Ñ‹"
-      less_than_x_minutes:
-        one:   "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
-        few:   "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} Ð¼Ð¸Ð½ÑƒÑ‚"
-        many:  "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} Ð¼Ð¸Ð½ÑƒÑ‚"
-        other: "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
-      x_minutes:
-        one:   "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñƒ"
-        few:   "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
-        many:  "%{count} Ð¼Ð¸Ð½ÑƒÑ‚"
-        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
-      about_x_hours:
-        one:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
-        few:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
-        many:  "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
-        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
-      x_days:
-        one:   "%{count} Ð´ÐµÐ½ÑŒ"
-        few:   "%{count} Ð´Ð½Ñ"
-        many:  "%{count} Ð´Ð½ÐµÐ¹"
-        other: "%{count} Ð´Ð½Ñ"
-      about_x_months:
-        one:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÑÑ†Ð°"
-        few:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÑÑ†ÐµÐ²"
-        many:  "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÑÑ†ÐµÐ²"
-        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÑÑ†Ð°"
-      x_months:
-        one:   "%{count} Ð¼ÐµÑÑÑ†"
-        few:   "%{count} Ð¼ÐµÑÑÑ†Ð°"
-        many:  "%{count} Ð¼ÐµÑÑÑ†ÐµÐ²"
-        other: "%{count} Ð¼ÐµÑÑÑ†Ð°"
-      about_x_years:
-        one:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð³Ð¾Ð´Ð°"
-        few:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð»ÐµÑ‚"
-        many:  "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð»ÐµÑ‚"
-        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð»ÐµÑ‚"
-      over_x_years:
-        one:   "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð³Ð¾Ð´Ð°"
-        few:   "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð»ÐµÑ‚"
-        many:  "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð»ÐµÑ‚"
-        other: "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð»ÐµÑ‚"
-      almost_x_years:
-        one:   "Ð¿Ð¾Ñ‡Ñ‚Ð¸ 1 Ð³Ð¾Ð´"
-        few:   "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´Ð°"
-        many:  "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð»ÐµÑ‚"
-        other: "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´Ð°"
-    prompts:
-      year: "Ð“Ð¾Ð´"
-      month: "ÐœÐµÑÑÑ†"
-      day: "Ð”ÐµÐ½ÑŒ"
-      hour: "Ð§Ð°ÑÐ¾Ð²"
-      minute: "ÐœÐ¸Ð½ÑƒÑ‚"
-      second: "Ð¡ÐµÐºÑƒÐ½Ð´"
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:   "%{model}: ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð½Ðµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ Ð¸Ð·-Ð·Ð° %{count} Ð¾ÑˆÐ¸Ð±ÐºÐ¸"
-          few:   "%{model}: ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð½Ðµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ Ð¸Ð·-Ð·Ð° %{count} Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
-          many:  "%{model}: ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð½Ðµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ Ð¸Ð·-Ð·Ð° %{count} Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
-          other: "%{model}: ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð½Ðµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ Ð¸Ð·-Ð·Ð° %{count} Ð¾ÑˆÐ¸Ð±ÐºÐ¸"
-
-        body: "ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ñ‹ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ»Ð¸ ÑÐ¾ ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð¸Ð¼Ð¸ Ð¿Ð¾Ð»ÑÐ¼Ð¸:"
-
-      messages:
-        inclusion: "Ð¸Ð¼ÐµÐµÑ‚ Ð½ÐµÐ¿Ñ€ÐµÐ´ÑƒÑÐ¼Ð¾Ñ‚Ñ€ÐµÐ½Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
-        exclusion: "Ð¸Ð¼ÐµÐµÑ‚ Ð·Ð°Ñ€ÐµÐ·ÐµÑ€Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
-        invalid: "Ð¸Ð¼ÐµÐµÑ‚ Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
-        confirmation: "Ð½Ðµ ÑÐ¾Ð²Ð¿Ð°Ð´Ð°ÐµÑ‚ Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼"
-        accepted: "Ð½ÑƒÐ¶Ð½Ð¾ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚ÑŒ"
-        empty: "Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¿ÑƒÑÑ‚Ñ‹Ð¼"
-        blank: "Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¿ÑƒÑÑ‚Ñ‹Ð¼"
-        too_long:
-          one:   "ÑÐ»Ð¸ÑˆÐºÐ¾Ð¼ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñ‡ÐµÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»)"
-          few:   "ÑÐ»Ð¸ÑˆÐºÐ¾Ð¼ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñ‡ÐµÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
-          many:  "ÑÐ»Ð¸ÑˆÐºÐ¾Ð¼ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñ‡ÐµÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²)"
-          other: "ÑÐ»Ð¸ÑˆÐºÐ¾Ð¼ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñ‡ÐµÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
-        too_short:
-          one:   "Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ‚Ð¾Ñ‡Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
-          few:   "Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ‚Ð¾Ñ‡Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²)"
-          many:  "Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ‚Ð¾Ñ‡Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²)"
-          other: "Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ‚Ð¾Ñ‡Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
-        wrong_length:
-          one:   "Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð´Ð»Ð¸Ð½Ð¾Ð¹ Ñ€Ð¾Ð²Ð½Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»)"
-          few:   "Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð´Ð»Ð¸Ð½Ð¾Ð¹ Ñ€Ð¾Ð²Ð½Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
-          many:  "Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð´Ð»Ð¸Ð½Ð¾Ð¹ Ñ€Ð¾Ð²Ð½Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²)"
-          other: "Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð´Ð»Ð¸Ð½Ð¾Ð¹ Ñ€Ð¾Ð²Ð½Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
-        taken: "ÑƒÐ¶Ðµ ÑÑƒÑ‰ÐµÑÑ‚Ð²ÑƒÐµÑ‚"
-        not_a_number: "Ð½Ðµ ÑÐ²Ð»ÑÐµÑ‚ÑÑ Ñ‡Ð¸ÑÐ»Ð¾Ð¼"
-        greater_than: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð±Ð¾Ð»ÑŒÑˆÐµÐµ %{count}"
-        greater_than_or_equal_to: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð±Ð¾Ð»ÑŒÑˆÐµÐµ Ð¸Ð»Ð¸ Ñ€Ð°Ð²Ð½Ð¾Ðµ %{count}"
-        equal_to: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð»Ð¸ÑˆÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ, Ñ€Ð°Ð²Ð½Ð¾Ðµ %{count}"
-        less_than: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð¼ÐµÐ½ÑŒÑˆÐµÐµ Ñ‡ÐµÐ¼ %{count}"
-        less_than_or_equal_to: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð¼ÐµÐ½ÑŒÑˆÐµÐµ Ð¸Ð»Ð¸ Ñ€Ð°Ð²Ð½Ð¾Ðµ %{count}"
-        odd: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð»Ð¸ÑˆÑŒ Ð½ÐµÑ‡ÐµÑ‚Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
-        even: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð»Ð¸ÑˆÑŒ Ñ‡ÐµÑ‚Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
-        greater_than_start_date: "Ð´Ð¾Ð»Ð¶Ð½Ð° Ð±Ñ‹Ñ‚ÑŒ Ð¿Ð¾Ð·Ð´Ð½ÐµÐµ Ð´Ð°Ñ‚Ñ‹ Ð½Ð°Ñ‡Ð°Ð»Ð°"
-        not_same_project: "Ð½Ðµ Ð¾Ñ‚Ð½Ð¾ÑÐ¸Ñ‚ÑÑ Ðº Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ"
-        circular_dependency: "Ð¢Ð°ÐºÐ°Ñ ÑÐ²ÑÐ·ÑŒ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÑ‚ Ðº Ñ†Ð¸ÐºÐ»Ð¸Ñ‡ÐµÑÐºÐ¾Ð¹ Ð·Ð°Ð²Ð¸ÑÐ¸Ð¼Ð¾ÑÑ‚Ð¸"
-        cant_link_an_issue_with_a_descendant: "Ð—Ð°Ð´Ð°Ñ‡Ð° Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ ÑÐ²ÑÐ·Ð°Ð½Ð° ÑÐ¾ ÑÐ²Ð¾ÐµÐ¹ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡ÐµÐ¹"
-
-  support:
-    array:
-      # Rails 2.2
-      sentence_connector: "Ð¸"
-      skip_last_comma: true
-
-      # Rails 2.3
-      words_connector: ", "
-      two_words_connector: " Ð¸ "
-      last_word_connector: " Ð¸ "
-
-  actionview_instancetag_blank_option: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ
-
-  button_activate: ÐÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_add: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ
-  button_annotate: ÐÐ²Ñ‚Ð¾Ñ€ÑÑ‚Ð²Ð¾
-  button_apply: ÐŸÑ€Ð¸Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ
-  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_back: ÐÐ°Ð·Ð°Ð´
-  button_cancel: ÐžÑ‚Ð¼ÐµÐ½Ð°
-  button_change_password: Ð˜Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
-  button_change: Ð˜Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ
-  button_check_all: ÐžÑ‚Ð¼ÐµÑ‚Ð¸Ñ‚ÑŒ Ð²ÑÐµ
-  button_clear: ÐžÑ‡Ð¸ÑÑ‚Ð¸Ñ‚ÑŒ
-  button_configure: ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹
-  button_copy: ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_create: Ð¡Ð¾Ð·Ð´Ð°Ñ‚ÑŒ
-  button_create_and_continue: Ð¡Ð¾Ð·Ð´Ð°Ñ‚ÑŒ Ð¸ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÑŒ
-  button_delete: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ
-  button_download: Ð—Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ
-  button_edit: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_edit_associated_wikipage: "Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ ÑÐ²ÑÐ·Ð°Ð½Ð½ÑƒÑŽ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ: %{page_title}"
-  button_list: Ð¡Ð¿Ð¸ÑÐ¾Ðº
-  button_lock: Ð—Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_login: Ð’Ñ…Ð¾Ð´
-  button_log_time: Ð—Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
-  button_move: ÐŸÐµÑ€ÐµÐ¼ÐµÑÑ‚Ð¸Ñ‚ÑŒ
-  button_quote: Ð¦Ð¸Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_rename: ÐŸÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_reply: ÐžÑ‚Ð²ÐµÑ‚Ð¸Ñ‚ÑŒ
-  button_reset: Ð¡Ð±Ñ€Ð¾ÑÐ¸Ñ‚ÑŒ
-  button_rollback: Ð’ÐµÑ€Ð½ÑƒÑ‚ÑŒÑÑ Ðº Ð´Ð°Ð½Ð½Ð¾Ð¹ Ð²ÐµÑ€ÑÐ¸Ð¸
-  button_save: Ð¡Ð¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ
-  button_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_submit: ÐŸÑ€Ð¸Ð½ÑÑ‚ÑŒ
-  button_test: ÐŸÑ€Ð¾Ð²ÐµÑ€Ð¸Ñ‚ÑŒ
-  button_unarchive: Ð Ð°Ð·Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_uncheck_all: ÐžÑ‡Ð¸ÑÑ‚Ð¸Ñ‚ÑŒ
-  button_unlock: Ð Ð°Ð·Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_unwatch: ÐÐµ ÑÐ»ÐµÐ´Ð¸Ñ‚ÑŒ
-  button_update: ÐžÐ±Ð½Ð¾Ð²Ð¸Ñ‚ÑŒ
-  button_view: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ
-  button_watch: Ð¡Ð»ÐµÐ´Ð¸Ñ‚ÑŒ
-
-  default_activity_design: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ
-  default_activity_development: Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ°
-  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸Ñ‡ÐµÑÐºÐ°Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ
-  default_doc_category_user: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑÐºÐ°Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ
-  default_issue_status_in_progress: Ð’ Ñ€Ð°Ð±Ð¾Ñ‚Ðµ
-  default_issue_status_closed: Ð—Ð°ÐºÑ€Ñ‹Ñ‚Ð°
-  default_issue_status_feedback: ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑÐ²ÑÐ·ÑŒ
-  default_issue_status_new: ÐÐ¾Ð²Ð°Ñ
-  default_issue_status_rejected: ÐžÑ‚ÐºÐ»Ð¾Ð½ÐµÐ½Ð°
-  default_issue_status_resolved: Ð ÐµÑˆÐµÐ½Ð°
-  default_priority_high: Ð’Ñ‹ÑÐ¾ÐºÐ¸Ð¹
-  default_priority_immediate: ÐÐµÐ¼ÐµÐ´Ð»ÐµÐ½Ð½Ñ‹Ð¹
-  default_priority_low: ÐÐ¸Ð·ÐºÐ¸Ð¹
-  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹
-  default_priority_urgent: Ð¡Ñ€Ð¾Ñ‡Ð½Ñ‹Ð¹
-  default_role_developer: Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸Ðº
-  default_role_manager: ÐœÐµÐ½ÐµÐ´Ð¶ÐµÑ€
-  default_role_reporter: Ð ÐµÐ¿Ð¾Ñ€Ñ‚Ñ‘Ñ€
-  default_tracker_bug: ÐžÑˆÐ¸Ð±ÐºÐ°
-  default_tracker_feature: Ð£Ð»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ðµ
-  default_tracker_support: ÐŸÐ¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ°
-
-  enumeration_activities: Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ (ÑƒÑ‡ÐµÑ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸)
-  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ð²
-  enumeration_issue_priorities: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ñ‹ Ð·Ð°Ð´Ð°Ñ‡
-
-  error_can_not_remove_role: Ð­Ñ‚Ð° Ñ€Ð¾Ð»ÑŒ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÑ‚ÑÑ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ ÑƒÐ´Ð°Ð»ÐµÐ½Ð°.
-  error_can_not_delete_custom_field: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð½Ð°ÑÑ‚Ñ€Ð°Ð¸Ð²Ð°ÐµÐ¼Ð¾Ðµ Ð¿Ð¾Ð»Ðµ
-  error_can_not_delete_tracker: Ð­Ñ‚Ð¾Ñ‚ Ñ‚Ñ€ÐµÐºÐµÑ€ ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ ÑƒÐ´Ð°Ð»ÐµÐ½.
-  error_can_t_load_default_data: "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ Ð½Ðµ Ð±Ñ‹Ð»Ð° Ð·Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð°: %{value}"
-  error_issue_not_found_in_project: Ð—Ð°Ð´Ð°Ñ‡Ð° Ð½Ðµ Ð±Ñ‹Ð»Ð° Ð½Ð°Ð¹Ð´ÐµÐ½Ð° Ð¸Ð»Ð¸ Ð½Ðµ Ð¿Ñ€Ð¸ÐºÑ€ÐµÐ¿Ð»ÐµÐ½Ð° Ðº ÑÑ‚Ð¾Ð¼Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ
-  error_scm_annotate: "Ð”Ð°Ð½Ð½Ñ‹Ðµ Ð¾Ñ‚ÑÑƒÑ‚ÑÑ‚Ð²ÑƒÑŽÑ‚ Ð¸Ð»Ð¸ Ð½Ðµ Ð¼Ð¾Ð³ÑƒÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐ°Ð½Ñ‹."
-  error_scm_command_failed: "ÐžÑˆÐ¸Ð±ÐºÐ° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ñƒ: %{value}"
-  error_scm_not_found: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ Ð½Ðµ ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð¸/Ð¸Ð»Ð¸ Ð¸ÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ.
-  error_unable_to_connect: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒÑÑ (%{value})
-  error_unable_delete_issue_status: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-
-  field_account: Ð£Ñ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ
-  field_activity: Ð”ÐµÑÑ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ
-  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
-  field_assignable: Ð—Ð°Ð´Ð°Ñ‡Ð° Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð° ÑÑ‚Ð¾Ð¹ Ñ€Ð¾Ð»Ð¸
-  field_assigned_to: ÐÐ°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð°
-  field_attr_firstname: Ð˜Ð¼Ñ
-  field_attr_lastname: Ð¤Ð°Ð¼Ð¸Ð»Ð¸Ñ
-  field_attr_login: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Login
-  field_attr_mail: email
-  field_author: ÐÐ²Ñ‚Ð¾Ñ€
-  field_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸
-  field_base_dn: BaseDN
-  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
-  field_column_names: Ð¡Ñ‚Ð¾Ð»Ð±Ñ†Ñ‹
-  field_comments: ÐšÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹
-  field_comments_sorting: ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²
-  field_content: Content
-  field_created_on: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¾
-  field_default_value: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  field_delay: ÐžÑ‚Ð»Ð¾Ð¶Ð¸Ñ‚ÑŒ
-  field_description: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ
-  field_done_ratio: Ð“Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ
-  field_downloads: Ð—Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸
-  field_due_date: Ð”Ð°Ñ‚Ð° Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ
-  field_editable: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€ÑƒÐµÐ¼Ð¾Ðµ
-  field_effective_date: Ð”Ð°Ñ‚Ð°
-  field_estimated_hours: ÐžÑ†ÐµÐ½ÐºÐ° Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
-  field_filename: Ð¤Ð°Ð¹Ð»
-  field_filesize: Ð Ð°Ð·Ð¼ÐµÑ€
-  field_firstname: Ð˜Ð¼Ñ
-  field_fixed_version: Ð’ÐµÑ€ÑÐ¸Ñ
-  field_hide_mail: Ð¡ÐºÑ€Ñ‹Ð²Ð°Ñ‚ÑŒ Ð¼Ð¾Ð¹ email
-  field_homepage: Ð¡Ñ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð°Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  field_host: ÐšÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€
-  field_hours: Ñ‡Ð°Ñ(Ð°,Ð¾Ð²)
-  field_identifier: Ð£Ð½Ð¸ÐºÐ°Ð»ÑŒÐ½Ñ‹Ð¹ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€
-  field_identity_url: OpenID URL
-  field_is_closed: Ð—Ð°Ð´Ð°Ñ‡Ð° Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð°
-  field_is_default: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  field_is_filter: Ð˜ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÑ‚ÑÑ Ð² ÐºÐ°Ñ‡ÐµÑÑ‚Ð²Ðµ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð°
-  field_is_for_all: Ð”Ð»Ñ Ð²ÑÐµÑ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
-  field_is_in_roadmap: Ð—Ð°Ð´Ð°Ñ‡Ð¸, Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ðµ Ð² Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ð¾Ð¼ Ð¿Ð»Ð°Ð½Ðµ
-  field_is_public: ÐžÐ±Ñ‰ÐµÐ´Ð¾ÑÑ‚ÑƒÐ¿Ð½Ñ‹Ð¹
-  field_is_required: ÐžÐ±ÑÐ·Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ðµ
-  field_issue_to: Ð¡Ð²ÑÐ·Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  field_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
-  field_language: Ð¯Ð·Ñ‹Ðº
-  field_last_login_on: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½ÐµÐµ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ
-  field_lastname: Ð¤Ð°Ð¼Ð¸Ð»Ð¸Ñ
-  field_login: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ
-  field_mail: Email
-  field_mail_notification: Ð£Ð²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ email
-  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°
-  field_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°
-  field_name: Ð˜Ð¼Ñ
-  field_new_password: ÐÐ¾Ð²Ñ‹Ð¹ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
-  field_notes: ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ
-  field_onthefly: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ð° Ð»ÐµÑ‚Ñƒ
-  field_parent_title: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑÐºÐ°Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  field_parent: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑÐºÐ¸Ð¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  field_parent_issue: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑÐºÐ°Ñ Ð·Ð°Ð´Ð°Ñ‡Ð°
-  field_password_confirmation: ÐŸÐ¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ðµ
-  field_password: ÐŸÐ°Ñ€Ð¾Ð»ÑŒ
-  field_port: ÐŸÐ¾Ñ€Ñ‚
-  field_possible_values: Ð’Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ‹Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ
-  field_priority: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
-  field_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
-  field_redirect_existing_links: ÐŸÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÑŒ ÑÑƒÑ‰ÐµÑÑ‚Ð²ÑƒÑŽÑ‰Ð¸Ðµ ÑÑÑ‹Ð»ÐºÐ¸
-  field_regexp: Ð ÐµÐ³ÑƒÐ»ÑÑ€Ð½Ð¾Ðµ Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ
-  field_role: Ð Ð¾Ð»ÑŒ
-  field_searchable: Ð”Ð¾ÑÑ‚ÑƒÐ¿Ð½Ð¾ Ð´Ð»Ñ Ð¿Ð¾Ð¸ÑÐºÐ°
-  field_spent_on: Ð”Ð°Ñ‚Ð°
-  field_start_date: ÐÐ°Ñ‡Ð°Ñ‚Ð°
-  field_start_page: Ð¡Ñ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð°Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  field_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ
-  field_subject: Ð¢ÐµÐ¼Ð°
-  field_subproject: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  field_summary: ÐšÑ€Ð°Ñ‚ÐºÐ¾Ðµ Ð¾Ð¿Ð¸ÑÐ°Ð½Ð¸Ðµ
-  field_text: Ð¢ÐµÐºÑÑ‚Ð¾Ð²Ð¾Ðµ Ð¿Ð¾Ð»Ðµ
-  field_time_entries: Ð—Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
-  field_time_zone: Ð§Ð°ÑÐ¾Ð²Ð¾Ð¹ Ð¿Ð¾ÑÑ
-  field_title: Ð—Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº
-  field_tracker: Ð¢Ñ€ÐµÐºÐµÑ€
-  field_type: Ð¢Ð¸Ð¿
-  field_updated_on: ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾
-  field_url: URL
-  field_user: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ
-  field_value: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ
-  field_version: Ð’ÐµÑ€ÑÐ¸Ñ
-  field_watcher: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»ÑŒ
-
-  general_csv_decimal_separator: ','
-  general_csv_encoding: UTF-8
-  general_csv_separator: ';'
-  general_first_day_of_week: '1'
-  general_lang_name: 'Russian (Ð ÑƒÑÑÐºÐ¸Ð¹)'
-  general_pdf_encoding: UTF-8
-  general_text_no: 'Ð½ÐµÑ‚'
-  general_text_No: 'ÐÐµÑ‚'
-  general_text_yes: 'Ð´Ð°'
-  general_text_Yes: 'Ð”Ð°'
-
-  gui_validation_error: 1 Ð¾ÑˆÐ¸Ð±ÐºÐ°
-  gui_validation_error_plural: "%{count} Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
-  gui_validation_error_plural2: "%{count} Ð¾ÑˆÐ¸Ð±ÐºÐ¸"
-  gui_validation_error_plural5: "%{count} Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
-
-  label_activity: Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ
-  label_add_another_file: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ ÐµÑ‰Ñ‘ Ð¾Ð´Ð¸Ð½ Ñ„Ð°Ð¹Ð»
-  label_added_time_by: "Ð”Ð¾Ð±Ð°Ð²Ð¸Ð»(Ð°) %{author} %{age} Ð½Ð°Ð·Ð°Ð´"
-  label_added: Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¾
-  label_add_note: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ðµ
-  label_administration: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ
-  label_age: Ð’Ð¾Ð·Ñ€Ð°ÑÑ‚
-  label_ago: Ð´Ð½ÐµÐ¹(Ñ) Ð½Ð°Ð·Ð°Ð´
-  label_all_time: Ð²ÑÑ‘ Ð²Ñ€ÐµÐ¼Ñ
-  label_all_words: Ð’ÑÐµ ÑÐ»Ð¾Ð²Ð°
-  label_all: Ð²ÑÐµ
-  label_and_its_subprojects: "%{value} Ð¸ Ð²ÑÐµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹"
-  label_applied_status: ÐŸÑ€Ð¸Ð¼ÐµÐ½Ð¸Ð¼Ñ‹Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_ascending: ÐŸÐ¾ Ð²Ð¾Ð·Ñ€Ð°ÑÑ‚Ð°Ð½Ð¸ÑŽ
-  label_assigned_to_me_issues: ÐœÐ¾Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_associated_revisions: Ð¡Ð²ÑÐ·Ð°Ð½Ð½Ñ‹Ðµ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
-  label_attachment: Ð¤Ð°Ð¹Ð»
-  label_attachment_delete: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ñ„Ð°Ð¹Ð»
-  label_attachment_new: ÐÐ¾Ð²Ñ‹Ð¹ Ñ„Ð°Ð¹Ð»
-  label_attachment_plural: Ð¤Ð°Ð¹Ð»Ñ‹
-  label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
-  label_attribute_plural: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚Ñ‹
-  label_authentication: ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ
-  label_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸
-  label_auth_source_new: ÐÐ¾Ð²Ñ‹Ð¹ Ñ€ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸
-  label_auth_source_plural: Ð ÐµÐ¶Ð¸Ð¼Ñ‹ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸
-  label_blocked_by: Ð±Ð»Ð¾ÐºÐ¸Ñ€ÑƒÐµÑ‚ÑÑ
-  label_blocks: Ð±Ð»Ð¾ÐºÐ¸Ñ€ÑƒÐµÑ‚
-  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
-  label_board_new: ÐÐ¾Ð²Ñ‹Ð¹ Ñ„Ð¾Ñ€ÑƒÐ¼
-  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ñ‹
-  label_boolean: Ð›Ð¾Ð³Ð¸Ñ‡ÐµÑÐºÐ¸Ð¹
-  label_browse: ÐžÐ±Ð·Ð¾Ñ€
-  label_bulk_edit_selected_issues: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð²ÑÐµ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€ÑŒ
-  label_calendar_filter: Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ
-  label_calendar_no_assigned: Ð½Ðµ Ð¼Ð¾Ð¸
-  label_change_plural: ÐŸÑ€Ð°Ð²ÐºÐ¸
-  label_change_properties: Ð˜Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ ÑÐ²Ð¾Ð¹ÑÑ‚Ð²Ð°
-  label_change_status: Ð˜Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_change_view_all: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ð²ÑÐµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ
-  label_changes_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð¾ÑÑ‚Ð¸ Ð¿Ð¾ Ð²ÑÐµÐ¼ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸ÑÐ¼
-  label_changeset_plural: Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ
-  label_chronological_order: Ð’ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑÐºÐ¾Ð¼ Ð¿Ð¾Ñ€ÑÐ´ÐºÐµ
-  label_closed_issues: Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾
-  label_closed_issues_plural: Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾
-  label_closed_issues_plural2: Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾
-  label_closed_issues_plural5: Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾
-  label_comment: ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹
-  label_comment_add: ÐžÑÑ‚Ð°Ð²Ð¸Ñ‚ÑŒ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹
-  label_comment_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð½Ñ‹Ð¹ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹
-  label_comment_delete: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¸
-  label_comment_plural: ÐšÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¸
-  label_comment_plural2: ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ
-  label_comment_plural5: ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²
-  label_commits_per_author: Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ð½Ð° Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ
-  label_commits_per_month: Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ð² Ð¼ÐµÑÑÑ†
-  label_confirmation: ÐŸÐ¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ðµ
-  label_contains: ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚
-  label_copied: ÑÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¾
-  label_copy_workflow_from: Ð¡ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹ Ð¸Ð·
-  label_current_status: Ð¢ÐµÐºÑƒÑ‰Ð¸Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_current_version: Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ
-  label_custom_field: ÐÐ°ÑÑ‚Ñ€Ð°Ð¸Ð²Ð°ÐµÐ¼Ð¾Ðµ Ð¿Ð¾Ð»Ðµ
-  label_custom_field_new: ÐÐ¾Ð²Ð¾Ðµ Ð½Ð°ÑÑ‚Ñ€Ð°Ð¸Ð²Ð°ÐµÐ¼Ð¾Ðµ Ð¿Ð¾Ð»Ðµ
-  label_custom_field_plural: ÐÐ°ÑÑ‚Ñ€Ð°Ð¸Ð²Ð°ÐµÐ¼Ñ‹Ðµ Ð¿Ð¾Ð»Ñ
-  label_date_from: Ð¡
-  label_date_from_to: Ð¡ %{start} Ð¿Ð¾ %{end}
-  label_date_range: Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð¹ Ð¸Ð½Ñ‚ÐµÑ€Ð²Ð°Ð»
-  label_date_to: Ð¿Ð¾
-  label_date: Ð”Ð°Ñ‚Ð°
-  label_day_plural: Ð´Ð½ÐµÐ¹(Ñ)
-  label_default: ÐŸÐ¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  label_default_columns: Ð¡Ñ‚Ð¾Ð»Ð±Ñ†Ñ‹ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  label_deleted: ÑƒÐ´Ð°Ð»ÐµÐ½Ð¾
-  label_descending: ÐŸÐ¾ ÑƒÐ±Ñ‹Ð²Ð°Ð½Ð¸ÑŽ
-  label_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð¾ÑÑ‚Ð¸
-  label_diff_inline: Ð² Ñ‚ÐµÐºÑÑ‚Ðµ
-  label_diff_side_by_side: Ñ€ÑÐ´Ð¾Ð¼
-  label_disabled: Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¾
-  label_display: ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ
-  label_display_per_page: "ÐÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ: %{value}"
-  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
-  label_download: "%{count} Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°"
-  label_download_plural: "%{count} ÑÐºÐ°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ð¹"
-  label_download_plural2: "%{count} Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸"
-  label_download_plural5: "%{count} Ð·Ð°Ð³Ñ€ÑƒÐ·Ð¾Ðº"
-  label_downloads_abbr: Ð¡ÐºÐ°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ð¹
-  label_duplicated_by: Ð´ÑƒÐ±Ð»Ð¸Ñ€ÑƒÐµÑ‚ÑÑ
-  label_duplicates: Ð´ÑƒÐ±Ð»Ð¸Ñ€ÑƒÐµÑ‚
-  label_end_to_end: Ñ ÐºÐ¾Ð½Ñ†Ð° Ðº ÐºÐ¾Ð½Ñ†Ñƒ
-  label_end_to_start: Ñ ÐºÐ¾Ð½Ñ†Ð° Ðº Ð½Ð°Ñ‡Ð°Ð»Ñƒ
-  label_enumeration_new: ÐÐ¾Ð²Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ
-  label_enumerations: Ð¡Ð¿Ð¸ÑÐºÐ¸ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹
-  label_environment: ÐžÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ðµ
-  label_equals: ÑÐ²Ð»ÑÐµÑ‚ÑÑ
-  label_example: ÐŸÑ€Ð¸Ð¼ÐµÑ€
-  label_export_to: Ð­ÐºÑÐ¿Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð²
-  label_feed_plural: RSS
-  label_feeds_access_key_created_on: "ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° RSS ÑÐ¾Ð·Ð´Ð°Ð½ %{value} Ð½Ð°Ð·Ð°Ð´"
-  label_f_hour: "%{value} Ñ‡Ð°Ñ"
-  label_f_hour_plural: "%{value} Ñ‡Ð°ÑÐ¾Ð²"
-  label_file_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ Ñ„Ð°Ð¹Ð»
-  label_file_plural: Ð¤Ð°Ð¹Ð»Ñ‹
-  label_filter_add: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€
-  label_filter_plural: Ð¤Ð¸Ð»ÑŒÑ‚Ñ€Ñ‹
-  label_float: Ð¡ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ Ñ‚Ð¾Ñ‡ÐºÐ¾Ð¹
-  label_follows: Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ
-  label_gantt: Ð”Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ð° Ð“Ð°Ð½Ñ‚Ð°
-  label_general: ÐžÐ±Ñ‰ÐµÐµ
-  label_generate_key: Ð¡Ð³ÐµÐ½ÐµÑ€Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ ÐºÐ»ÑŽÑ‡
-  label_greater_or_equal: ">="
-  label_help: ÐŸÐ¾Ð¼Ð¾Ñ‰ÑŒ
-  label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ
-  label_home: Ð”Ð¾Ð¼Ð°ÑˆÐ½ÑÑ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  label_incoming_emails: ÐŸÑ€Ð¸Ñ‘Ð¼ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
-  label_index_by_date: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
-  label_index_by_title: ÐžÐ³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ
-  label_information_plural: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
-  label_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
-  label_in_less_than: Ð¼ÐµÐ½ÐµÐµ Ñ‡ÐµÐ¼
-  label_in_more_than: Ð±Ð¾Ð»ÐµÐµ Ñ‡ÐµÐ¼
-  label_integer: Ð¦ÐµÐ»Ñ‹Ð¹
-  label_internal: Ð’Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½Ð¸Ð¹
-  label_in: Ð²
-  label_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_category_new: ÐÐ¾Ð²Ð°Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
-  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_new: ÐÐ¾Ð²Ð°Ñ Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_plural: Ð—Ð°Ð´Ð°Ñ‡Ð¸
-  label_issues_by: "Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ %{value}"
-  label_issue_status_new: ÐÐ¾Ð²Ñ‹Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_issue_status_plural: Ð¡Ñ‚Ð°Ñ‚ÑƒÑÑ‹ Ð·Ð°Ð´Ð°Ñ‡
-  label_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_tracking: Ð—Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_updated: ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
-  label_issue_view_all: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ð²ÑÐµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_issue_watchers: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
-  label_jump_to_a_project: ÐŸÐµÑ€ÐµÐ¹Ñ‚Ð¸ Ðº Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ...
-  label_language_based: ÐÐ° Ð¾ÑÐ½Ð¾Ð²Ðµ ÑÐ·Ñ‹ÐºÐ°
-  label_last_changes: "Ð¼ÐµÐ½ÐµÐµ %{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹"
-  label_last_login: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½ÐµÐµ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ
-  label_last_month: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ð¹ Ð¼ÐµÑÑÑ†
-  label_last_n_days: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ %{count} Ð´Ð½ÐµÐ¹"
-  label_last_week: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½ÑÑ Ð½ÐµÐ´ÐµÐ»Ñ
-  label_latest_revision: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½ÑÑ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ñ
-  label_latest_revision_plural: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
-  label_ldap_authentication: ÐÐ²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ LDAP
-  label_less_or_equal: <=
-  label_less_than_ago: Ð¼ÐµÐ½ÐµÐµ, Ñ‡ÐµÐ¼ Ð´Ð½ÐµÐ¹(Ñ) Ð½Ð°Ð·Ð°Ð´
-  label_list: Ð¡Ð¿Ð¸ÑÐ¾Ðº
-  label_loading: Ð—Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°...
-  label_logged_as: Ð’Ð¾ÑˆÐ»Ð¸ ÐºÐ°Ðº
-  label_login: Ð’Ð¾Ð¹Ñ‚Ð¸
-  label_login_with_open_id_option: Ð¸Ð»Ð¸ Ð²Ð¾Ð¹Ñ‚Ð¸ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ OpenID
-  label_logout: Ð’Ñ‹Ð¹Ñ‚Ð¸
-  label_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ Ñ€Ð°Ð·Ð¼ÐµÑ€
-  label_member_new: ÐÐ¾Ð²Ñ‹Ð¹ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸Ðº
-  label_member: Ð£Ñ‡Ð°ÑÑ‚Ð½Ð¸Ðº
-  label_member_plural: Ð£Ñ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ¸
-  label_message_last: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½ÐµÐµ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
-  label_message_new: ÐÐ¾Ð²Ð¾Ðµ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
-  label_message_plural: Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
-  label_message_posted: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¾ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
-  label_me: Ð¼Ð½Ðµ
-  label_min_max_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ - Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°
-  label_modification: "%{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ"
-  label_modification_plural: "%{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹"
-  label_modification_plural2: "%{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ"
-  label_modification_plural5: "%{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹"
-  label_modified: Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¾
-  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ð¸
-  label_months_from: Ð¼ÐµÑÑÑ†ÐµÐ²(Ñ†Ð°) Ñ
-  label_month: ÐœÐµÑÑÑ†
-  label_more_than_ago: Ð±Ð¾Ð»ÐµÐµ, Ñ‡ÐµÐ¼ Ð´Ð½ÐµÐ¹(Ñ) Ð½Ð°Ð·Ð°Ð´
-  label_more: Ð‘Ð¾Ð»ÑŒÑˆÐµ
-  label_my_account: ÐœÐ¾Ñ ÑƒÑ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ
-  label_my_page: ÐœÐ¾Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  label_my_page_block: Ð‘Ð»Ð¾Ðº Ð¼Ð¾ÐµÐ¹ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹
-  label_my_projects: ÐœÐ¾Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
-  label_new: ÐÐ¾Ð²Ñ‹Ð¹
-  label_new_statuses_allowed: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð½Ñ‹Ðµ Ð½Ð¾Ð²Ñ‹Ðµ ÑÑ‚Ð°Ñ‚ÑƒÑÑ‹
-  label_news_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð° Ð½Ð¾Ð²Ð¾ÑÑ‚ÑŒ
-  label_news_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
-  label_news_new: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ð½Ð¾Ð²Ð¾ÑÑ‚ÑŒ
-  label_news_plural: ÐÐ¾Ð²Ð¾ÑÑ‚Ð¸
-  label_news_view_all: ÐŸÐ¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ð²ÑÐµ Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
-  label_news: ÐÐ¾Ð²Ð¾ÑÑ‚Ð¸
-  label_next: Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰ÐµÐµ
-  label_nobody: Ð½Ð¸ÐºÑ‚Ð¾
-  label_no_change_option: (ÐÐµÑ‚ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹)
-  label_no_data: ÐÐµÑ‚ Ð´Ð°Ð½Ð½Ñ‹Ñ… Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ
-  label_none: Ð¾Ñ‚ÑÑƒÑ‚ÑÑ‚Ð²ÑƒÐµÑ‚
-  label_not_contains: Ð½Ðµ ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚
-  label_not_equals: Ð½Ðµ ÑÐ²Ð»ÑÐµÑ‚ÑÑ
-  label_open_issues: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾
-  label_open_issues_plural: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾
-  label_open_issues_plural2: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾
-  label_open_issues_plural5: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾
-  label_optional_description: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ (Ð½ÐµÐ¾Ð±ÑÐ·Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾)
-  label_options: ÐžÐ¿Ñ†Ð¸Ð¸
-  label_overall_activity: Ð¡Ð²Ð¾Ð´Ð½Ñ‹Ð¹ Ð¾Ñ‚Ñ‡ÐµÑ‚ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹
-  label_overview: ÐžÐ±Ð·Ð¾Ñ€
-  label_password_lost: Ð’Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¿Ð°Ñ€Ð¾Ð»Ñ
-  label_permissions_report: ÐžÑ‚Ñ‡ÐµÑ‚ Ð¿Ð¾ Ð¿Ñ€Ð°Ð²Ð°Ð¼ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð°
-  label_permissions: ÐŸÑ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð°
-  label_per_page: ÐÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ
-  label_personalize_page: ÐŸÐµÑ€ÑÐ¾Ð½Ð°Ð»Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð´Ð°Ð½Ð½ÑƒÑŽ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ
-  label_planning: ÐŸÐ»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ
-  label_please_login: ÐŸÐ¾Ð¶Ð°Ð»ÑƒÐ¹ÑÑ‚Ð°, Ð²Ð¾Ð¹Ð´Ð¸Ñ‚Ðµ.
-  label_plugins: ÐœÐ¾Ð´ÑƒÐ»Ð¸
-  label_precedes: ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ
-  label_preferences: ÐŸÑ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ
-  label_preview: ÐŸÑ€ÐµÐ´Ð¿Ñ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€
-  label_previous: ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰ÐµÐµ
-  label_profile: ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŒ
-  label_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
-  label_project_all: Ð’ÑÐµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
-  label_project_copy_notifications: ÐžÑ‚Ð¿Ñ€Ð°Ð²Ð»ÑÑ‚ÑŒ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ð¹ Ð¿Ð¾Ñ‡Ñ‚Ðµ Ð¿Ñ€Ð¸ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
-  label_project_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
-  label_project_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  label_project_plural: ÐŸÑ€Ð¾ÐµÐºÑ‚Ñ‹
-  label_project_plural2: Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
-  label_project_plural5: Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
-  label_public_projects: ÐžÐ±Ñ‰Ð¸Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
-  label_query: Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð½Ñ‹Ð¹ Ð·Ð°Ð¿Ñ€Ð¾Ñ
-  label_query_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð·Ð°Ð¿Ñ€Ð¾Ñ
-  label_query_plural: Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð½Ñ‹Ðµ Ð·Ð°Ð¿Ñ€Ð¾ÑÑ‹
-  label_read: Ð§Ñ‚ÐµÐ½Ð¸Ðµ...
-  label_register: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
-  label_registered_on: Ð—Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½(Ð°)
-  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ ÑƒÑ‡ÐµÑ‚Ð½Ñ‹Ñ… Ð·Ð°Ð¿Ð¸ÑÐµÐ¹ Ð¿Ð¾ email
-  label_registration_automatic_activation: Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑÐºÐ°Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ ÑƒÑ‡ÐµÑ‚Ð½Ñ‹Ñ… Ð·Ð°Ð¿Ð¸ÑÐµÐ¹
-  label_registration_manual_activation: Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ ÑƒÑ‡ÐµÑ‚Ð½Ñ‹Ðµ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ
-  label_related_issues: Ð¡Ð²ÑÐ·Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_relates_to: ÑÐ²ÑÐ·Ð°Ð½Ð° Ñ
-  label_relation_delete: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ ÑÐ²ÑÐ·ÑŒ
-  label_relation_new: ÐÐ¾Ð²Ð¾Ðµ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ðµ
-  label_renamed: Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¾
-  label_reply_plural: ÐžÑ‚Ð²ÐµÑ‚Ñ‹
-  label_report: ÐžÑ‚Ñ‡ÐµÑ‚
-  label_report_plural: ÐžÑ‚Ñ‡ÐµÑ‚Ñ‹
-  label_reported_issues: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_repository: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
-  label_repository_plural: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
-  label_result_plural: Ð ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ‹
-  label_reverse_chronological_order: Ð’ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾Ð¼ Ð¿Ð¾Ñ€ÑÐ´ÐºÐµ
-  label_revision: Ð ÐµÐ´Ð°ÐºÑ†Ð¸Ñ
-  label_revision_plural: Ð ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
-  label_roadmap: ÐžÐ¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ñ‹Ð¹ Ð¿Ð»Ð°Ð½
-  label_roadmap_due_in: "Ð’ ÑÑ€Ð¾Ðº %{value}"
-  label_roadmap_no_issues: ÐÐµÑ‚ Ð·Ð°Ð´Ð°Ñ‡ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ Ð²ÐµÑ€ÑÐ¸Ð¸
-  label_roadmap_overdue: "Ð¾Ð¿Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ %{value}"
-  label_role: Ð Ð¾Ð»ÑŒ
-  label_role_and_permissions: Ð Ð¾Ð»Ð¸ Ð¸ Ð¿Ñ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð°
-  label_role_new: ÐÐ¾Ð²Ð°Ñ Ñ€Ð¾Ð»ÑŒ
-  label_role_plural: Ð Ð¾Ð»Ð¸
-  label_scm: Ð¢Ð¸Ð¿ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
-  label_search: ÐŸÐ¾Ð¸ÑÐº
-  label_search_titles_only: Ð˜ÑÐºÐ°Ñ‚ÑŒ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð² Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÑÑ…
-  label_send_information: ÐžÑ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÑŒ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŽ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÑŽ Ð¿Ð¾ ÑƒÑ‡ÐµÑ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸
-  label_send_test_email: ÐŸÐ¾ÑÐ»Ð°Ñ‚ÑŒ email Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸
-  label_settings: ÐÐ°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸
-  label_show_completed_versions: ÐŸÐ¾ÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ‹Ðµ Ð²ÐµÑ€ÑÐ¸Ð¸
-  label_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  label_sort_by: "Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ %{value}"
-  label_sort_higher: Ð’Ð²ÐµÑ€Ñ…
-  label_sort_highest: Ð’ Ð½Ð°Ñ‡Ð°Ð»Ð¾
-  label_sort_lower: Ð’Ð½Ð¸Ð·
-  label_sort_lowest: Ð’ ÐºÐ¾Ð½ÐµÑ†
-  label_spent_time: Ð—Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
-  label_start_to_end: Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° Ðº ÐºÐ¾Ð½Ñ†Ñƒ
-  label_start_to_start: Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° Ðº Ð½Ð°Ñ‡Ð°Ð»Ñƒ
-  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ°
-  label_stay_logged_in: ÐžÑÑ‚Ð°Ð²Ð°Ñ‚ÑŒÑÑ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ðµ
-  label_string: Ð¢ÐµÐºÑÑ‚
-  label_subproject_plural: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
-  label_subtask_plural: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_text: Ð”Ð»Ð¸Ð½Ð½Ñ‹Ð¹ Ñ‚ÐµÐºÑÑ‚
-  label_theme: Ð¢ÐµÐ¼Ð°
-  label_this_month: ÑÑ‚Ð¾Ñ‚ Ð¼ÐµÑÑÑ†
-  label_this_week: Ð½Ð° ÑÑ‚Ð¾Ð¹ Ð½ÐµÐ´ÐµÐ»Ðµ
-  label_this_year: ÑÑ‚Ð¾Ñ‚ Ð³Ð¾Ð´
-  label_time_tracking: Ð£Ñ‡ÐµÑ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  label_timelog_today: Ð Ð°ÑÑ…Ð¾Ð´ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ Ð½Ð° ÑÐµÐ³Ð¾Ð´Ð½Ñ
-  label_today: ÑÐµÐ³Ð¾Ð´Ð½Ñ
-  label_topic_plural: Ð¢ÐµÐ¼Ñ‹
-  label_total: Ð’ÑÐµÐ³Ð¾
-  label_tracker: Ð¢Ñ€ÐµÐºÐµÑ€
-  label_tracker_new: ÐÐ¾Ð²Ñ‹Ð¹ Ñ‚Ñ€ÐµÐºÐµÑ€
-  label_tracker_plural: Ð¢Ñ€ÐµÐºÐµÑ€Ñ‹
-  label_updated_time: "ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾ %{value} Ð½Ð°Ð·Ð°Ð´"
-  label_updated_time_by: "ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾ %{author} %{age} Ð½Ð°Ð·Ð°Ð´"
-  label_used_by: Ð˜ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÑ‚ÑÑ
-  label_user: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ
-  label_user_activity: "Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %{value}"
-  label_user_mail_no_self_notified: "ÐÐµ Ð¸Ð·Ð²ÐµÑ‰Ð°Ñ‚ÑŒ Ð¾Ð± Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸ÑÑ…, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ñ ÑÐ´ÐµÐ»Ð°Ð» ÑÐ°Ð¼"
-  label_user_mail_option_all: "Ðž Ð²ÑÐµÑ… ÑÐ¾Ð±Ñ‹Ñ‚Ð¸ÑÑ… Ð²Ð¾ Ð²ÑÐµÑ… Ð¼Ð¾Ð¸Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ñ…"
-  label_user_mail_option_selected: "Ðž Ð²ÑÐµÑ… ÑÐ¾Ð±Ñ‹Ñ‚Ð¸ÑÑ… Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð² Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ðµ..."
-  label_user_mail_option_only_owner: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð², Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… Ñ ÑÐ²Ð»ÑÑŽÑÑŒ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼
-  label_user_mail_option_only_my_events: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð², ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ñ Ð¾Ñ‚ÑÐ»ÐµÐ¶Ð¸Ð²Ð°ÑŽ Ð¸Ð»Ð¸ Ð² ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… ÑƒÑ‡Ð°ÑÑ‚Ð²ÑƒÑŽ
-  label_user_mail_option_only_assigned: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð², ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ñ‹ Ð¼Ð½Ðµ
-  label_user_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ
-  label_user_plural: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ð¸
-  label_version: Ð’ÐµÑ€ÑÐ¸Ñ
-  label_version_new: ÐÐ¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ
-  label_version_plural: Ð’ÐµÑ€ÑÐ¸Ð¸
-  label_view_diff: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ð¾Ñ‚Ð»Ð¸Ñ‡Ð¸Ñ
-  label_view_revisions: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
-  label_watched_issues: ÐžÑ‚ÑÐ»ÐµÐ¶Ð¸Ð²Ð°ÐµÐ¼Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_week: ÐÐµÐ´ÐµÐ»Ñ
-  label_wiki: Wiki
-  label_wiki_edit: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Wiki
-  label_wiki_edit_plural: Wiki
-  label_wiki_page: Ð¡Ñ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Wiki
-  label_wiki_page_plural: Ð¡Ñ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Wiki
-  label_workflow: ÐŸÐ¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹
-  label_x_closed_issues_abbr:
-    zero:  "0 Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾"
-    one:   "1 Ð·Ð°ÐºÑ€Ñ‹Ñ‚"
-    few:   "%{count} Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾"
-    many:  "%{count} Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾"
-    other: "%{count} Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾"
-  label_x_comments:
-    zero:  "Ð½ÐµÑ‚ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²"
-    one:   "1 ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹"
-    few:   "%{count} ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ"
-    many:  "%{count} ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²"
-    other: "%{count} ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²"
-  label_x_open_issues_abbr:
-    zero:  "0 Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾"
-    one:   "1 Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚"
-    few:   "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾"
-    many:  "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾"
-    other: "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾"
-  label_x_open_issues_abbr_on_total:
-    zero:  "0 Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾ / %{total}"
-    one:   "1 Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ / %{total}"
-    few:   "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾ / %{total}"
-    many:  "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾ / %{total}"
-    other: "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾ / %{total}"
-  label_x_projects:
-    zero:  "Ð½ÐµÑ‚ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²"
-    one:   "1 Ð¿Ñ€Ð¾ÐµÐºÑ‚"
-    few:   "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°"
-    many:  "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²"
-    other: "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²"
-  label_year: Ð“Ð¾Ð´
-  label_yesterday: Ð²Ñ‡ÐµÑ€Ð°
-
-  mail_body_account_activation_request: "Ð—Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½ Ð½Ð¾Ð²Ñ‹Ð¹ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ (%{value}). Ð£Ñ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ‚ Ð’Ð°ÑˆÐµÐ³Ð¾ ÑƒÑ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ:"
-  mail_body_account_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ Ð’Ð°ÑˆÐµÐ¹ ÑƒÑ‡ÐµÑ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸
-  mail_body_account_information_external: "Ð’Ñ‹ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÑŒ Ð’Ð°ÑˆÑƒ %{value} ÑƒÑ‡ÐµÑ‚Ð½ÑƒÑŽ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð°."
-  mail_body_lost_password: 'Ð”Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð¿Ñ€Ð¾Ð¹Ð´Ð¸Ñ‚Ðµ Ð¿Ð¾ ÑÐ»ÐµÐ´ÑƒÑŽÑ‰ÐµÐ¹ ÑÑÑ‹Ð»ÐºÐµ:'
-  mail_body_register: 'Ð”Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ð¸ ÑƒÑ‡ÐµÑ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð¿Ñ€Ð¾Ð¹Ð´Ð¸Ñ‚Ðµ Ð¿Ð¾ ÑÐ»ÐµÐ´ÑƒÑŽÑ‰ÐµÐ¹ ÑÑÑ‹Ð»ÐºÐµ:'
-  mail_body_reminder: "%{count} Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ‹Ñ… Ð½Ð° Ð’Ð°Ñ Ð·Ð°Ð´Ð°Ñ‡ Ð½Ð° ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð¸Ðµ %{days} Ð´Ð½ÐµÐ¹:"
-  mail_subject_account_activation_request: "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸ÑŽ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ðµ %{value}"
-  mail_subject_lost_password: "Ð’Ð°Ñˆ %{value} Ð¿Ð°Ñ€Ð¾Ð»ÑŒ"
-  mail_subject_register: "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ ÑƒÑ‡ÐµÑ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ %{value}"
-  mail_subject_reminder: "%{count} Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ‹Ñ… Ð½Ð° Ð’Ð°Ñ Ð·Ð°Ð´Ð°Ñ‡ Ð² Ð±Ð»Ð¸Ð¶Ð°Ð¹ÑˆÐ¸Ðµ %{days} Ð´Ð½ÐµÐ¹"
-
-  notice_account_activated: Ð’Ð°ÑˆÐ° ÑƒÑ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð°. Ð’Ñ‹ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð²Ð¾Ð¹Ñ‚Ð¸.
-  notice_account_invalid_creditentials: ÐÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ðµ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
-  notice_account_lost_email_sent: Ð’Ð°Ð¼ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¾ Ð¿Ð¸ÑÑŒÐ¼Ð¾ Ñ Ð¸Ð½ÑÑ‚Ñ€ÑƒÐºÑ†Ð¸ÑÐ¼Ð¸ Ð¿Ð¾ Ð²Ñ‹Ð±Ð¾Ñ€Ñƒ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ð¿Ð°Ñ€Ð¾Ð»Ñ.
-  notice_account_password_updated: ÐŸÐ°Ñ€Ð¾Ð»ÑŒ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½.
-  notice_account_pending: "Ð’Ð°ÑˆÐ° ÑƒÑ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ ÑÐ¾Ð·Ð´Ð°Ð½Ð° Ð¸ Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ‚ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð°."
-  notice_account_register_done: Ð£Ñ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑÐ¾Ð·Ð´Ð°Ð½Ð°. Ð”Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ð¸ Ð’Ð°ÑˆÐµÐ¹ ÑƒÑ‡ÐµÑ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð¿Ñ€Ð¾Ð¹Ð´Ð¸Ñ‚Ðµ Ð¿Ð¾ ÑÑÑ‹Ð»ÐºÐµ, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð²Ñ‹ÑÐ»Ð°Ð½Ð° Ð’Ð°Ð¼ Ð¿Ð¾ ÑÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ð¹ Ð¿Ð¾Ñ‡Ñ‚Ðµ.
-  notice_account_unknown_email: ÐÐµÐ¸Ð·Ð²ÐµÑÑ‚Ð½Ñ‹Ð¹ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ.
-  notice_account_updated: Ð£Ñ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð°.
-  notice_account_wrong_password: ÐÐµÐ²ÐµÑ€Ð½Ñ‹Ð¹ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
-  notice_can_t_change_password: Ð”Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ÑƒÑ‡ÐµÑ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÑ‚ÑÑ Ð¸ÑÑ‚Ð¾Ñ‡Ð½Ð¸Ðº Ð²Ð½ÐµÑˆÐ½ÐµÐ¹ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸. ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ.
-  notice_default_data_loaded: Ð‘Ñ‹Ð»Ð° Ð·Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð° ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ.
-  notice_email_error: "Ð’Ð¾ Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ Ð¿Ð¸ÑÑŒÐ¼Ð° Ð¿Ñ€Ð¾Ð¸Ð·Ð¾ÑˆÐ»Ð° Ð¾ÑˆÐ¸Ð±ÐºÐ° (%{value})"
-  notice_email_sent: "ÐžÑ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¾ Ð¿Ð¸ÑÑŒÐ¼Ð¾ %{value}"
-  notice_failed_to_save_issues: "ÐÐµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ ÑÐ¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ %{count} Ð¿ÑƒÐ½ÐºÑ‚(Ð¾Ð²) Ð¸Ð· %{total} Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ…: %{ids}."
-  notice_failed_to_save_members: "ÐÐµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ ÑÐ¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ°(Ð¾Ð²): %{errors}."
-  notice_feeds_access_key_reseted: Ð’Ð°Ñˆ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° RSS Ð±Ñ‹Ð» ÑÐ±Ñ€Ð¾ÑˆÐµÐ½.
-  notice_file_not_found: Ð¡Ñ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°, Ð½Ð° ÐºÐ¾Ñ‚Ð¾Ñ€ÑƒÑŽ Ð’Ñ‹ Ð¿Ñ‹Ñ‚Ð°ÐµÑ‚ÐµÑÑŒ Ð·Ð°Ð¹Ñ‚Ð¸, Ð½Ðµ ÑÑƒÑ‰ÐµÑÑ‚Ð²ÑƒÐµÑ‚ Ð¸Ð»Ð¸ ÑƒÐ´Ð°Ð»ÐµÐ½Ð°.
-  notice_locking_conflict: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð° Ð´Ñ€ÑƒÐ³Ð¸Ð¼ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¼.
-  notice_no_issue_selected: "ÐÐµ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð¾ Ð½Ð¸ Ð¾Ð´Ð½Ð¾Ð¹ Ð·Ð°Ð´Ð°Ñ‡Ð¸! ÐŸÐ¾Ð¶Ð°Ð»ÑƒÐ¹ÑÑ‚Ð°, Ð¾Ñ‚Ð¼ÐµÑ‚ÑŒÑ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð’Ñ‹ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ Ð¾Ñ‚Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ."
-  notice_not_authorized: Ð£ Ð’Ð°Ñ Ð½ÐµÑ‚ Ð¿Ñ€Ð°Ð² Ð´Ð»Ñ Ð¿Ð¾ÑÐµÑ‰ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹.
-  notice_successful_connection: ÐŸÐ¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑƒÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾.
-  notice_successful_create: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
-  notice_successful_delete: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
-  notice_successful_update: ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
-  notice_unable_delete_version: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð²ÐµÑ€ÑÐ¸ÑŽ.
-
-  permission_add_issues: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡
-  permission_add_issue_notes: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ð¹
-  permission_add_issue_watchers: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»ÐµÐ¹
-  permission_add_messages: ÐžÑ‚Ð¿Ñ€Ð°Ð²ÐºÐ° ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
-  permission_browse_repository: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
-  permission_comment_news: ÐšÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ð½Ð¾Ð²Ð¾ÑÑ‚ÐµÐ¹
-  permission_commit_access: Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ Ñ„Ð°Ð¹Ð»Ð¾Ð² Ð² Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
-  permission_delete_issues: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡
-  permission_delete_messages: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
-  permission_delete_own_messages: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ñ… ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
-  permission_delete_wiki_pages: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
-  permission_delete_wiki_pages_attachments: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ Ð¿Ñ€Ð¸ÐºÑ€ÐµÐ¿Ð»ÐµÐ½Ð½Ñ‹Ñ… Ñ„Ð°Ð¹Ð»Ð¾Ð²
-  permission_edit_issue_notes: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ð¹
-  permission_edit_issues: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡
-  permission_edit_messages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
-  permission_edit_own_issue_notes: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ñ… Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ð¹
-  permission_edit_own_messages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ñ… ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
-  permission_edit_own_time_entries: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ð¾Ð³Ð¾ ÑƒÑ‡ÐµÑ‚Ð° Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  permission_edit_project: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
-  permission_edit_time_entries: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑƒÑ‡ÐµÑ‚Ð° Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  permission_edit_wiki_pages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
-  permission_export_wiki_pages: Ð­ÐºÑÐ¿Ð¾Ñ€Ñ‚ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
-  permission_log_time: Ð£Ñ‡ÐµÑ‚ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  permission_view_changesets: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
-  permission_view_time_entries: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  permission_manage_project_activities: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ‚Ð¸Ð¿Ð°Ð¼Ð¸ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹ Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
-  permission_manage_boards: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ„Ð¾Ñ€ÑƒÐ¼Ð°Ð¼Ð¸
-  permission_manage_categories: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸ÑÐ¼Ð¸ Ð·Ð°Ð´Ð°Ñ‡
-  permission_manage_documents: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ð¼Ð¸
-  permission_manage_files: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸
-  permission_manage_issue_relations: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑÐ²ÑÐ·Ñ‹Ð²Ð°Ð½Ð¸ÐµÐ¼ Ð·Ð°Ð´Ð°Ñ‡
-  permission_manage_members: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ°Ð¼Ð¸
-  permission_manage_news: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð¾Ð²Ð¾ÑÑ‚ÑÐ¼Ð¸
-  permission_manage_public_queries: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¾Ð±Ñ‰Ð¸Ð¼Ð¸ Ð·Ð°Ð¿Ñ€Ð¾ÑÐ°Ð¼Ð¸
-  permission_manage_repository: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÐ¼
-  permission_manage_subtasks: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð°Ð¼Ð¸
-  permission_manage_versions: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð²ÐµÑ€ÑÐ¸ÑÐ¼Ð¸
-  permission_manage_wiki: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Wiki
-  permission_move_issues: ÐŸÐµÑ€ÐµÐ½Ð¾Ñ Ð·Ð°Ð´Ð°Ñ‡
-  permission_protect_wiki_pages: Ð‘Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
-  permission_rename_wiki_pages: ÐŸÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ðµ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
-  permission_save_queries: Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð·Ð°Ð¿Ñ€Ð¾ÑÐ¾Ð²
-  permission_select_project_modules: Ð’Ñ‹Ð±Ð¾Ñ€ Ð¼Ð¾Ð´ÑƒÐ»ÐµÐ¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
-  permission_view_calendar: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ
-  permission_view_documents: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ð²
-  permission_view_files: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ñ„Ð°Ð¹Ð»Ð¾Ð²
-  permission_view_gantt: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ñ‹ Ð“Ð°Ð½Ñ‚Ð°
-  permission_view_issue_watchers: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ ÑÐ¿Ð¸ÑÐºÐ° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»ÐµÐ¹
-  permission_view_messages: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
-  permission_view_wiki_edits: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ð¸ Wiki
-  permission_view_wiki_pages: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Wiki
-
-  project_module_boards: Ð¤Ð¾Ñ€ÑƒÐ¼Ñ‹
-  project_module_documents: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
-  project_module_files: Ð¤Ð°Ð¹Ð»Ñ‹
-  project_module_issue_tracking: Ð—Ð°Ð´Ð°Ñ‡Ð¸
-  project_module_news: ÐÐ¾Ð²Ð¾ÑÑ‚Ð¸
-  project_module_repository: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
-  project_module_time_tracking: Ð£Ñ‡ÐµÑ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  project_module_wiki: Wiki
-  project_module_gantt: Ð”Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ð° Ð“Ð°Ð½Ñ‚Ð°
-  project_module_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€ÑŒ
-
-  setting_activity_days_default: ÐšÐ¾Ð»Ð¸Ñ‡ÐµÑÑ‚Ð²Ð¾ Ð´Ð½ÐµÐ¹, Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ñ… Ð² Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸ÑÑ…
-  setting_app_subtitle: ÐŸÐ¾Ð´Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ
-  setting_app_title: ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ðµ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ
-  setting_attachment_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ
-  setting_autofetch_changesets: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑÐºÐ¸ ÑÐ»ÐµÐ´Ð¸Ñ‚ÑŒ Ð·Ð° Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸ÑÐ¼Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
-  setting_autologin: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑÐºÐ¸Ð¹ Ð²Ñ…Ð¾Ð´
-  setting_bcc_recipients: Ð˜ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÑŒ ÑÐºÑ€Ñ‹Ñ‚Ñ‹Ðµ ÐºÐ¾Ð¿Ð¸Ð¸ (BCC)
-  setting_cache_formatted_text: ÐšÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ñ‹Ð¹ Ñ‚ÐµÐºÑÑ‚
-  setting_commit_fix_keywords: ÐÐ°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… ÑÐ»Ð¾Ð²
-  setting_commit_ref_keywords: ÐšÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ðµ ÑÐ»Ð¾Ð²Ð° Ð´Ð»Ñ Ð¿Ð¾Ð¸ÑÐºÐ°
-  setting_cross_project_issue_relations: Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð¿ÐµÑ€ÐµÑÐµÑ‡ÐµÐ½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡ Ð¿Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼
-  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð´Ð°Ñ‚Ñ‹
-  setting_default_language: Ð¯Ð·Ñ‹Ðº Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  setting_default_notification_option: Ð¡Ð¿Ð¾ÑÐ¾Ð± Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  setting_default_projects_public: ÐÐ¾Ð²Ñ‹Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹ ÑÐ²Ð»ÑÑŽÑ‚ÑÑ Ð¾Ð±Ñ‰ÐµÐ´Ð¾ÑÑ‚ÑƒÐ¿Ð½Ñ‹Ð¼Ð¸
-  setting_diff_max_lines_displayed: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ðµ Ñ‡Ð¸ÑÐ»Ð¾ ÑÑ‚Ñ€Ð¾Ðº Ð´Ð»Ñ diff
-  setting_display_subprojects_issues: ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð² Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  setting_emails_footer: ÐŸÐ¾Ð´ÑÑ‚Ñ€Ð¾Ñ‡Ð½Ñ‹Ðµ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð¿Ð¸ÑÑŒÐ¼Ð°
-  setting_enabled_scm: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð½Ñ‹Ðµ SCM
-  setting_feeds_limit: ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ðµ ÐºÐ¾Ð»Ð¸Ñ‡ÐµÑÑ‚Ð²Ð° Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð² Ð´Ð»Ñ RSS Ð¿Ð¾Ñ‚Ð¾ÐºÐ°
-  setting_file_max_size_displayed: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ñ‚ÐµÐºÑÑ‚Ð¾Ð²Ð¾Ð³Ð¾ Ñ„Ð°Ð¹Ð»Ð° Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ
-  setting_gravatar_enabled: Ð˜ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÑŒ Ð°Ð²Ð°Ñ‚Ð°Ñ€ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð· Gravatar
-  setting_host_name: Ð˜Ð¼Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð°
-  setting_issue_list_default_columns: Ð¡Ñ‚Ð¾Ð»Ð±Ñ†Ñ‹, Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ðµ Ð² ÑÐ¿Ð¸ÑÐºÐµ Ð·Ð°Ð´Ð°Ñ‡ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  setting_issues_export_limit: ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ðµ Ð¿Ð¾ ÑÐºÑÐ¿Ð¾Ñ€Ñ‚Ð¸Ñ€ÑƒÐµÐ¼Ñ‹Ð¼ Ð·Ð°Ð´Ð°Ñ‡Ð°Ð¼
-  setting_login_required: ÐÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð° Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ
-  setting_mail_from: Ð˜ÑÑ…Ð¾Ð´ÑÑ‰Ð¸Ð¹ email Ð°Ð´Ñ€ÐµÑ
-  setting_mail_handler_api_enabled: Ð’ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ð²ÐµÐ±-ÑÐµÑ€Ð²Ð¸Ñ Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´ÑÑ‰Ð¸Ñ… ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
-  setting_mail_handler_api_key: API ÐºÐ»ÑŽÑ‡
-  setting_openid: Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ OpenID Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° Ð¸ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ð¸
-  setting_per_page_options: ÐšÐ¾Ð»Ð¸Ñ‡ÐµÑÑ‚Ð²Ð¾ Ð·Ð°Ð¿Ð¸ÑÐµÐ¹ Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ
-  setting_plain_text_mail: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð¿Ñ€Ð¾ÑÑ‚Ð¾Ð¹ Ñ‚ÐµÐºÑÑ‚ (Ð±ÐµÐ· HTML)
-  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
-  setting_repository_log_display_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ðµ ÐºÐ¾Ð»Ð¸Ñ‡ÐµÑÑ‚Ð²Ð¾ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¹, Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ñ… Ð² Ð¶ÑƒÑ€Ð½Ð°Ð»Ðµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹
-  setting_self_registration: Ð¡Ð°Ð¼Ð¾Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
-  setting_sequential_project_identifiers: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ñ‹ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
-  setting_sys_api_enabled: Ð’ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ð²ÐµÐ±-ÑÐµÑ€Ð²Ð¸Ñ Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÐ¼
-  setting_text_formatting: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ñ‚ÐµÐºÑÑ‚Ð°
-  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  setting_user_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐ½Ð¸
-  setting_welcome_text: Ð¢ÐµÐºÑÑ‚ Ð¿Ñ€Ð¸Ð²ÐµÑ‚ÑÑ‚Ð²Ð¸Ñ
-  setting_wiki_compression: Ð¡Ð¶Ð°Ñ‚Ð¸Ðµ Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ð¸ Wiki
-
-  status_active: Ð°ÐºÑ‚Ð¸Ð²ÐµÐ½
-  status_locked: Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½
-  status_registered: Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½
-
-  text_are_you_sure_with_children: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡Ñƒ Ð¸ Ð²ÑÐµ ÐµÐµ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸?
-  text_are_you_sure: Ð’Ñ‹ ÑƒÐ²ÐµÑ€ÐµÐ½Ñ‹?
-  text_assign_time_entries_to_project: ÐŸÑ€Ð¸ÐºÑ€ÐµÐ¿Ð¸Ñ‚ÑŒ Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ Ðº Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ
-  text_caracters_maximum: "ÐœÐ°ÐºÑÐ¸Ð¼ÑƒÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²(Ð°)."
-  text_caracters_minimum: "Ð”Ð¾Ð»Ð¶Ð½Ð¾ Ð±Ñ‹Ñ‚ÑŒ Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²."
-  text_comma_separated: Ð”Ð¾Ð¿ÑƒÑÑ‚Ð¸Ð¼Ñ‹ Ð½ÐµÑÐºÐ¾Ð»ÑŒÐºÐ¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ (Ñ‡ÐµÑ€ÐµÐ· Ð·Ð°Ð¿ÑÑ‚ÑƒÑŽ).
-  text_custom_field_possible_values_info: 'ÐŸÐ¾ Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÑŽ Ð² ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑ‚Ñ€Ð¾ÐºÐµ'
-  text_default_administrator_account_changed: Ð£Ñ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð° Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð°
-  text_destroy_time_entries_question: "ÐÐ° ÑÑ‚Ñƒ Ð·Ð°Ð´Ð°Ñ‡Ñƒ Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¾ %{hours} Ñ‡Ð°ÑÐ°(Ð¾Ð²) Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸. Ð§Ñ‚Ð¾ Ð’Ñ‹ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¸Ð½ÑÑ‚ÑŒ?"
-  text_destroy_time_entries: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
-  text_diff_truncated: '... Ð­Ñ‚Ð¾Ñ‚ diff Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½, Ñ‚Ð°Ðº ÐºÐ°Ðº Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐ°ÐµÑ‚ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ð¹ Ñ€Ð°Ð·Ð¼ÐµÑ€.'
-  text_email_delivery_not_configured: "ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð¿Ð¾Ñ‡Ñ‚Ð¾Ð²Ñ‹Ð¼ ÑÐµÑ€Ð²ÐµÑ€Ð¾Ð¼ Ð½Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾ÐµÐ½Ñ‹ Ð¸ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ email Ð½Ðµ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð°.\nÐÐ°ÑÑ‚Ñ€Ð¾Ð¸Ñ‚ÑŒ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹ Ð´Ð»Ñ Ð’Ð°ÑˆÐµÐ³Ð¾ SMTP-ÑÐµÑ€Ð²ÐµÑ€Ð° Ð’Ñ‹ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð² Ñ„Ð°Ð¹Ð»Ðµ config/configuration.yml. Ð”Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑÑ‚Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ."
-  text_enumeration_category_reassign_to: 'ÐÐ°Ð·Ð½Ð°Ñ‡Ð¸Ñ‚ÑŒ Ð¸Ð¼ ÑÐ»ÐµÐ´ÑƒÑŽÑ‰ÐµÐµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ:'
-  text_enumeration_destroy_question: "%{count} Ð¾Ð±ÑŠÐµÐºÑ‚(Ð°,Ð¾Ð²) ÑÐ²ÑÐ·Ð°Ð½Ñ‹ Ñ ÑÑ‚Ð¸Ð¼ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÐµÐ¼."
-  text_file_repository_writable: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ Ñ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð¾Ð¼ Ð½Ð° Ð·Ð°Ð¿Ð¸ÑÑŒ
-  text_issue_added: "Ð¡Ð¾Ð·Ð´Ð°Ð½Ð° Ð½Ð¾Ð²Ð°Ñ Ð·Ð°Ð´Ð°Ñ‡Ð° %{id} (%{author})."
-  text_issue_category_destroy_assignments: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸
-  text_issue_category_destroy_question: "ÐÐµÑÐºÐ¾Ð»ÑŒÐºÐ¾ Ð·Ð°Ð´Ð°Ñ‡ (%{count}) Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾ Ð² Ð´Ð°Ð½Ð½ÑƒÑŽ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸ÑŽ. Ð§Ñ‚Ð¾ Ð’Ñ‹ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¸Ð½ÑÑ‚ÑŒ?"
-  text_issue_category_reassign_to: ÐŸÐµÑ€ÐµÐ½Ð°Ð·Ð½Ð°Ñ‡Ð¸Ñ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸
-  text_issues_destroy_confirmation: 'Ð’Ñ‹ ÑƒÐ²ÐµÑ€ÐµÐ½Ñ‹, Ñ‡Ñ‚Ð¾ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸?'
-  text_issues_ref_in_commit_messages: Ð¡Ð¾Ð¿Ð¾ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¸ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ ÑÑ‚Ð°Ñ‚ÑƒÑÐ° Ð·Ð°Ð´Ð°Ñ‡ Ð¸ÑÑ…Ð¾Ð´Ñ Ð¸Ð· Ñ‚ÐµÐºÑÑ‚Ð° ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
-  text_issue_updated: "Ð—Ð°Ð´Ð°Ñ‡Ð° %{id} Ð±Ñ‹Ð»Ð° Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð° (%{author})."
-  text_journal_changed: "ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ %{label} Ð¸Ð·Ð¼ÐµÐ½Ð¸Ð»ÑÑ Ñ %{old} Ð½Ð° %{new}"
-  text_journal_deleted: "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ %{old} Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° %{label} ÑƒÐ´Ð°Ð»ÐµÐ½Ð¾"
-  text_journal_set_to: "ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ %{label} Ð¸Ð·Ð¼ÐµÐ½Ð¸Ð»ÑÑ Ð½Ð° %{value}"
-  text_length_between: "Ð”Ð»Ð¸Ð½Ð° Ð¼ÐµÐ¶Ð´Ñƒ %{min} Ð¸ %{max} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²."
-  text_load_default_configuration: Ð—Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸ÑŽ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  text_min_max_length_info: 0 Ð¾Ð·Ð½Ð°Ñ‡Ð°ÐµÑ‚ Ð¾Ñ‚ÑÑƒÑ‚ÑÑ‚Ð²Ð¸Ðµ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ð¹
-  text_no_configuration_data: "Ð Ð¾Ð»Ð¸, Ñ‚Ñ€ÐµÐºÐµÑ€Ñ‹, ÑÑ‚Ð°Ñ‚ÑƒÑÑ‹ Ð·Ð°Ð´Ð°Ñ‡ Ð¸ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ñ‹Ð¹ Ð¿Ð»Ð°Ð½ Ð½Ðµ Ð±Ñ‹Ð»Ð¸ ÑÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ñ‹.\nÐÐ°ÑÑ‚Ð¾ÑÑ‚ÐµÐ»ÑŒÐ½Ð¾ Ñ€ÐµÐºÐ¾Ð¼ÐµÐ½Ð´ÑƒÐµÑ‚ÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸ÑŽ Ð¿Ð¾-ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ. Ð’Ñ‹ ÑÐ¼Ð¾Ð¶ÐµÑ‚Ðµ ÐµÑ‘ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð¿Ð¾Ñ‚Ð¾Ð¼."
-  text_plugin_assets_writable: ÐšÐ°Ñ‚Ð°Ð»Ð¾Ð³ Ð¼Ð¾Ð´ÑƒÐ»ÐµÐ¹ Ð´Ð¾ÑÑ‚ÑƒÐ¿ÐµÐ½ Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸ÑÐ¸
-  text_project_destroy_confirmation: Ð’Ñ‹ Ð½Ð°ÑÑ‚Ð°Ð¸Ð²Ð°ÐµÑ‚Ðµ Ð½Ð° ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ð¸ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð° Ð¸ Ð²ÑÐµÐ¹ Ð¾Ñ‚Ð½Ð¾ÑÑÑ‰ÐµÐ¹ÑÑ Ðº Ð½ÐµÐ¼Ñƒ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸?
-  text_project_identifier_info: 'Ð”Ð¾Ð¿ÑƒÑÑ‚Ð¸Ð¼Ñ‹ ÑÑ‚Ñ€Ð¾Ñ‡Ð½Ñ‹Ðµ Ð±ÑƒÐºÐ²Ñ‹ (a-z), Ñ†Ð¸Ñ„Ñ€Ñ‹ Ð¸ Ð´ÐµÑ„Ð¸Ñ.<br />Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð½Ñ‹Ð¹ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½.'
-  text_reassign_time_entries: 'ÐŸÐµÑ€ÐµÐ½ÐµÑÑ‚Ð¸ Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ Ð½Ð° ÑÐ»ÐµÐ´ÑƒÑŽÑ‰ÑƒÑŽ Ð·Ð°Ð´Ð°Ñ‡Ñƒ:'
-  text_regexp_info: "Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€: ^[A-Z0-9]+$"
-  text_repository_usernames_mapping: "Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¸Ð»Ð¸ Ð¾Ð±Ð½Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Redmine, ÑÐ²ÑÐ·Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñ Ð½Ð°Ð¹Ð´ÐµÐ½Ð½Ñ‹Ð¼Ð¸ Ð¸Ð¼ÐµÐ½Ð°Ð¼Ð¸ Ð² Ð¶ÑƒÑ€Ð½Ð°Ð»Ðµ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°.\nÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ð¸ Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼Ð¸ Ð¸Ð¼ÐµÐ½Ð°Ð¼Ð¸ Ð¸Ð»Ð¸ email Ð² Redmine Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ ÑÐ²ÑÐ·Ñ‹Ð²Ð°ÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑÐºÐ¸."
-  text_rmagick_available: Ð”Ð¾ÑÑ‚ÑƒÐ¿Ð½Ð¾ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ðµ RMagick (Ð¾Ð¿Ñ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ð¾)
-  text_select_mail_notifications: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ, Ð¿Ñ€Ð¸ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… Ð±ÑƒÐ´ÐµÑ‚ Ð¾Ñ‚ÑÑ‹Ð»Ð°Ñ‚ÑŒÑÑ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° ÑÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½ÑƒÑŽ Ð¿Ð¾Ñ‡Ñ‚Ñƒ.
-  text_select_project_modules: 'Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ð¸, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð±ÑƒÐ´ÑƒÑ‚ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ñ‹ Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚Ðµ:'
-  text_status_changed_by_changeset: "Ð ÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ð¾ Ð² %{value} Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸."
-  text_subprojects_destroy_warning: "ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹: %{value} Ñ‚Ð°ÐºÐ¶Ðµ Ð±ÑƒÐ´ÑƒÑ‚ ÑƒÐ´Ð°Ð»ÐµÐ½Ñ‹."
-  text_tip_issue_begin_day: Ð´Ð°Ñ‚Ð° Ð½Ð°Ñ‡Ð°Ð»Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  text_tip_issue_begin_end_day: Ð½Ð°Ñ‡Ð°Ð»Ð¾ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¸ Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ðµ ÐµÐµ Ð² ÑÑ‚Ð¾Ñ‚ Ð¶Ðµ Ð´ÐµÐ½ÑŒ
-  text_tip_issue_end_day: Ð´Ð°Ñ‚Ð° Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  text_tracker_no_workflow: Ð”Ð»Ñ ÑÑ‚Ð¾Ð³Ð¾ Ñ‚Ñ€ÐµÐºÐµÑ€Ð° Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹ Ð½Ðµ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð°
-  text_unallowed_characters: Ð—Ð°Ð¿Ñ€ÐµÑ‰ÐµÐ½Ð½Ñ‹Ðµ ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ‹
-  text_user_mail_option: "Ð”Ð»Ñ Ð½ÐµÐ²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð², Ð’Ñ‹ Ð±ÑƒÐ´ÐµÑ‚Ðµ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÑŒ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð¾ Ñ‚Ð¾Ð¼, Ñ‡Ñ‚Ð¾ Ð¿Ñ€Ð¾ÑÐ¼Ð°Ñ‚Ñ€Ð¸Ð²Ð°ÐµÑ‚Ðµ Ð¸Ð»Ð¸ Ð² Ñ‡ÐµÐ¼ ÑƒÑ‡Ð°ÑÑ‚Ð²ÑƒÐµÑ‚Ðµ (Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€, Ð·Ð°Ð´Ð°Ñ‡Ð¸, Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… Ð’Ñ‹ ÑÐ²Ð»ÑÐµÑ‚ÐµÑÑŒ, Ð¸Ð»Ð¸ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð’Ð°Ð¼ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ñ‹)."
-  text_user_wrote: "%{value} Ð¿Ð¸ÑÐ°Ð»(Ð°):"
-  text_wiki_destroy_confirmation: Ð’Ñ‹ ÑƒÐ²ÐµÑ€ÐµÐ½Ñ‹, Ñ‡Ñ‚Ð¾ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð´Ð°Ð½Ð½ÑƒÑŽ Wiki Ð¸ Ð²ÑÐµ ÐµÐµ ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ð¼Ð¾Ðµ?
-  text_workflow_edit: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ñ€Ð¾Ð»ÑŒ Ð¸ Ñ‚Ñ€ÐµÐºÐµÑ€ Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚Ð¸ ÑÐ¾ÑÑ‚Ð¾ÑÐ½Ð¸Ð¹
-
-  warning_attachments_not_saved: "%{count} Ñ„Ð°Ð¹Ð»(Ð¾Ð²) Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑÐ¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ."
-  text_wiki_page_destroy_question: Ð­Ñ‚Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¸Ð¼ÐµÐµÑ‚ %{descendants} Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ñ… ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ† Ð¸ Ð¸Ñ… Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ¾Ð². Ð§Ñ‚Ð¾ Ð²Ñ‹ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¸Ð½ÑÑ‚ÑŒ?
-  text_wiki_page_reassign_children: ÐŸÐµÑ€ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Ð½Ð° Ñ‚ÐµÐºÑƒÑ‰ÑƒÑŽ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ
-  text_wiki_page_nullify_children: Ð¡Ð´ÐµÐ»Ð°Ñ‚ÑŒ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Ð³Ð»Ð°Ð²Ð½Ñ‹Ð¼Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ð¼Ð¸
-  text_wiki_page_destroy_children: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Ð¸ Ð²ÑÐµÑ… Ð¸Ñ… Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ¾Ð²
-  setting_password_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ñ
-  field_group_by: Ð“Ñ€ÑƒÐ¿Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ‹ Ð¿Ð¾
-  mail_subject_wiki_content_updated: "Wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° '%{id}' Ð±Ñ‹Ð»Ð° Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð°"
-  label_wiki_content_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð° wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  mail_subject_wiki_content_added: "Wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°  '%{id}' Ð±Ñ‹Ð»Ð° Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð°"
-  mail_body_wiki_content_added: "%{author} Ð´Ð¾Ð±Ð°Ð²Ð¸Ð»(Ð°) wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ '%{id}'."
-  label_wiki_content_updated: ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð° wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
-  mail_body_wiki_content_updated: "%{author} Ð¾Ð±Ð½Ð¾Ð²Ð¸Ð»(Ð°) wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ '%{id}'."
-  permission_add_project: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
-  setting_new_project_user_role_id: Ð Ð¾Ð»ÑŒ, Ð½Ð°Ð·Ð½Ð°Ñ‡Ð°ÐµÐ¼Ð°Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŽ, ÑÐ¾Ð·Ð´Ð°Ð²ÑˆÐµÐ¼Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  label_view_all_revisions: ÐŸÐ¾ÐºÐ°Ð·Ð°Ñ‚ÑŒ Ð²ÑÐµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
-  label_tag: ÐœÐµÑ‚ÐºÐ°
-  label_branch: Ð’ÐµÑ‚Ð²ÑŒ
-  error_no_tracker_in_project: Ð¡ ÑÑ‚Ð¸Ð¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð¼ Ð½Ðµ Ð°ÑÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð¾Ð²Ð°Ð½ Ð½Ð¸ Ð¾Ð´Ð¸Ð½ Ñ‚Ñ€ÐµÐºÐµÑ€. ÐŸÑ€Ð¾Ð²ÐµÑ€ÑŒÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°.
-  error_no_default_issue_status: ÐÐµ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð´Ð°Ñ‡ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ. ÐŸÑ€Ð¾Ð²ÐµÑ€ÑŒÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸ (ÑÐ¼. "ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ -> Ð¡Ñ‚Ð°Ñ‚ÑƒÑÑ‹ Ð·Ð°Ð´Ð°Ñ‡").
-  label_group_plural: Ð“Ñ€ÑƒÐ¿Ð¿Ñ‹
-  label_group: Ð“Ñ€ÑƒÐ¿Ð¿Ð°
-  label_group_new: ÐÐ¾Ð²Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð°
-  label_time_entry_plural: Ð—Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
-  text_journal_added: "%{label} %{value} Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½"
-  field_active: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾
-  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð½Ð¾Ðµ
-  permission_delete_issue_watchers: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»ÐµÐ¹
-  version_status_closed: Ð·Ð°ÐºÑ€Ñ‹Ñ‚
-  version_status_locked: Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½
-  version_status_open: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚
-  error_can_not_reopen_issue_on_closed_version: Ð—Ð°Ð´Ð°Ñ‡Ð°, Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ð°Ñ Ðº Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾Ð¹ Ð²ÐµÑ€ÑÐ¸Ð¸, Ð½Ðµ ÑÐ¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð° ÑÐ½Ð¾Ð²Ð°
-  label_user_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼
-  button_move_and_follow: ÐŸÐµÑ€ÐµÐ¼ÐµÑÑ‚Ð¸Ñ‚ÑŒ Ð¸ Ð¿ÐµÑ€ÐµÐ¹Ñ‚Ð¸
-  setting_default_projects_modules: Ð’ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ‹Ðµ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
-  setting_gravatar_default: Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ Gravatar Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
-  field_sharing: Ð¡Ð¾Ð²Ð¼ÐµÑÑ‚Ð½Ð¾Ðµ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ðµ
-  label_version_sharing_hierarchy: Ð¡ Ð¸ÐµÑ€Ð°Ñ€Ñ…Ð¸ÐµÐ¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
-  label_version_sharing_system: Ð¡Ð¾ Ð²ÑÐµÐ¼Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
-  label_version_sharing_descendants: Ð¡ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
-  label_version_sharing_tree: Ð¡ Ð´ÐµÑ€ÐµÐ²Ð¾Ð¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
-  label_version_sharing_none: Ð‘ÐµÐ· ÑÐ¾Ð²Ð¼ÐµÑÑ‚Ð½Ð¾Ð³Ð¾ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ
-  error_can_not_archive_project: Ð­Ñ‚Ð¾Ñ‚ Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð·Ð°Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½
-  button_duplicate: Ð”ÑƒÐ±Ð»Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
-  button_copy_and_follow: ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¸ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÑŒ
-  label_copy_source: Ð˜ÑÑ‚Ð¾Ñ‡Ð½Ð¸Ðº
-  setting_issue_done_ratio:  Ð Ð°ÑÑÑ‡Ð¸Ñ‚Ñ‹Ð²Ð°Ñ‚ÑŒ Ð³Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ð¿Ð¾Ð»Ñ
-  setting_issue_done_ratio_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  error_issue_done_ratios_not_updated: ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ Ð³Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡ Ð½Ðµ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½
-  error_workflow_copy_target: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ñ†ÐµÐ»ÐµÐ²Ñ‹Ðµ Ñ‚Ñ€ÐµÐºÐµÑ€Ñ‹ Ð¸ Ñ€Ð¾Ð»Ð¸
-  setting_issue_done_ratio_issue_field: Ð“Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  label_copy_same_as_target: Ð¢Ð¾ Ð¶Ðµ, Ñ‡Ñ‚Ð¾ Ð¸ Ñƒ Ñ†ÐµÐ»Ð¸
-  label_copy_target: Ð¦ÐµÐ»ÑŒ
-  notice_issue_done_ratios_updated: ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ &laquo;Ð³Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ&raquo; Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½.
-  error_workflow_copy_source: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¸ÑÑ…Ð¾Ð´Ð½Ñ‹Ð¹ Ñ‚Ñ€ÐµÐºÐµÑ€ Ð¸Ð»Ð¸ Ñ€Ð¾Ð»ÑŒ
-  label_update_issue_done_ratios: ÐžÐ±Ð½Ð¾Ð²Ð¸Ñ‚ÑŒ Ð³Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡
-  setting_start_of_week: Ð”ÐµÐ½ÑŒ Ð½Ð°Ñ‡Ð°Ð»Ð° Ð½ÐµÐ´ÐµÐ»Ð¸
-  label_api_access_key: ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº API
-  text_line_separated: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¾ Ð½ÐµÑÐºÐ¾Ð»ÑŒÐºÐ¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ (Ð¿Ð¾ Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÑŽ Ð² ÑÑ‚Ñ€Ð¾ÐºÑƒ).
-  label_revision_id: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ %{value}
-  permission_view_issues: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð·Ð°Ð´Ð°Ñ‡
-  label_display_used_statuses_only: ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°Ñ‚ÑŒ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ‚Ðµ ÑÑ‚Ð°Ñ‚ÑƒÑÑ‹, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑŽÑ‚ÑÑ Ð² ÑÑ‚Ð¾Ð¼ Ñ‚Ñ€ÐµÐºÐµÑ€Ðµ
-  label_api_access_key_created_on: ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿ Ðº API Ð±Ñ‹Ð» ÑÐ¾Ð·Ð´Ð°Ð½ %{value} Ð½Ð°Ð·Ð°Ð´
-  label_feeds_access_key: ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº RSS
-  notice_api_access_key_reseted: Ð’Ð°Ñˆ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº API Ð±Ñ‹Ð» ÑÐ±Ñ€Ð¾ÑˆÐµÐ½.
-  setting_rest_api_enabled: Ð’ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ð²ÐµÐ±-ÑÐµÑ€Ð²Ð¸Ñ REST
-  button_show: ÐŸÐ¾ÐºÐ°Ð·Ð°Ñ‚ÑŒ
-  label_missing_api_access_key: ÐžÑ‚ÑÑƒÑ‚ÑÑ‚Ð²ÑƒÐµÑ‚ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº API
-  label_missing_feeds_access_key: ÐžÑ‚ÑÑƒÑ‚ÑÑ‚Ð²ÑƒÐµÑ‚ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº RSS
-  setting_mail_handler_body_delimiters: Ð£Ñ€ÐµÐ·Ð°Ñ‚ÑŒ Ð¿Ð¸ÑÑŒÐ¼Ð¾ Ð¿Ð¾ÑÐ»Ðµ Ð¾Ð´Ð½Ð¾Ð¹ Ð¸Ð· ÑÑ‚Ð¸Ñ… ÑÑ‚Ñ€Ð¾Ðº
-  permission_add_subprojects: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
-  label_subproject_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  text_own_membership_delete_confirmation: |-
-    Ð’Ñ‹ ÑÐ¾Ð±Ð¸Ñ€Ð°ÐµÑ‚ÐµÑÑŒ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð¸Ð»Ð¸ Ð²ÑÐµ Ð¿Ñ€Ð°Ð²Ð°, Ð¸Ð·-Ð·Ð° Ñ‡ÐµÐ³Ð¾ Ð¼Ð¾Ð³ÑƒÑ‚ Ð¿Ñ€Ð¾Ð¿Ð°ÑÑ‚ÑŒ Ð¿Ñ€Ð°Ð²Ð° Ð½Ð° Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÑ‚Ð¾Ð³Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°.
-    ÐŸÑ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÑŒ?
-  label_close_versions: Ð—Ð°ÐºÑ€Ñ‹Ñ‚ÑŒ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ‹Ðµ Ð²ÐµÑ€ÑÐ¸Ð¸
-  label_board_sticky: ÐŸÑ€Ð¸ÐºÑ€ÐµÐ¿Ð»ÐµÐ½Ð°
-  label_board_locked: Ð—Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð°
-  field_principal: Ð˜Ð¼Ñ
-  text_zoom_out: ÐžÑ‚Ð´Ð°Ð»Ð¸Ñ‚ÑŒ
-  text_zoom_in: ÐŸÑ€Ð¸Ð±Ð»Ð¸Ð·Ð¸Ñ‚ÑŒ
-  notice_unable_delete_time_entry: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð°.
-  label_overall_spent_time: Ð’ÑÐµÐ³Ð¾ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  label_user_mail_option_none: ÐÐµÑ‚ ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ð¹
-  field_member_of_group: Ð“Ñ€ÑƒÐ¿Ð¿Ð° Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾
-  field_assigned_to_role: Ð Ð¾Ð»ÑŒ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾
-  notice_not_authorized_archived_project: Ð—Ð°Ð¿Ñ€Ð°ÑˆÐ¸Ð²Ð°ÐµÐ¼Ñ‹Ð¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð±Ñ‹Ð» Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½.
-  label_principal_search: "ÐÐ°Ð¹Ñ‚Ð¸ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ð³Ñ€ÑƒÐ¿Ð¿Ñƒ:"
-  label_user_search: "ÐÐ°Ð¹Ñ‚Ð¸ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:"
-  field_visible: Ð’Ð¸Ð´Ð¸Ð¼Ð¾Ðµ
-  setting_emails_header: Ð—Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Ð¿Ð¸ÑÑŒÐ¼Ð°
-
-  setting_commit_logtime_activity_id: Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸Ðµ Ð´Ð»Ñ ÑƒÑ‡ÐµÑ‚Ð° Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  text_time_logged_by_changeset: Ð£Ñ‡Ñ‚ÐµÐ½Ð¾ Ð² Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸ %{value}.
-  setting_commit_logtime_enabled: Ð’ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ ÑƒÑ‡ÐµÑ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  notice_gantt_chart_truncated: Ð”Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ð° Ð±ÑƒÐ´ÐµÑ‚ ÑƒÑÐµÑ‡ÐµÐ½Ð°, Ð¿Ð¾ÑÐºÐ¾Ð»ÑŒÐºÑƒ Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐµÐ½Ð¾ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ðµ ÐºÐ¾Ð»-Ð²Ð¾ ÑÐ»ÐµÐ¼ÐµÐ½Ñ‚Ð¾Ð², ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð¼Ð¾Ð³ÑƒÑ‚ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°Ñ‚ÑŒÑÑ (%{max})
-  setting_gantt_items_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ðµ ÐºÐ¾Ð»-Ð²Ð¾ ÑÐ»ÐµÐ¼ÐµÐ½Ñ‚Ð¾Ð² Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ñ… Ð½Ð° Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ðµ Ð“Ð°Ð½Ñ‚Ð°
-  field_warn_on_leaving_unsaved: ÐŸÑ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´Ð°Ñ‚ÑŒ Ð¿Ñ€Ð¸ Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¸Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Ñ Ð½ÐµÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð½Ñ‹Ð¼ Ñ‚ÐµÐºÑÑ‚Ð¾Ð¼
-  text_warn_on_leaving_unsaved: Ð¢ÐµÐºÑƒÑ‰Ð°Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚ Ð½ÐµÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð½Ñ‹Ð¹ Ñ‚ÐµÐºÑÑ‚, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¹ Ð±ÑƒÐ´ÐµÑ‚ Ð¿Ð¾Ñ‚ÐµÑ€ÑÐ½, ÐµÑÐ»Ð¸ Ð²Ñ‹ Ð¿Ð¾ÐºÐ¸Ð½ÐµÑ‚Ðµ ÑÑ‚Ñƒ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ.
-  label_my_queries: ÐœÐ¾Ð¸ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð½Ñ‹Ðµ Ð·Ð°Ð¿Ñ€Ð¾ÑÑ‹
-  text_journal_changed_no_detail: "%{label} Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾"
-  label_news_comment_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹ Ðº Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
-  button_expand_all: Ð Ð°Ð·Ð²ÐµÑ€Ð½ÑƒÑ‚ÑŒ Ð²ÑÐµ
-  button_collapse_all: Ð¡Ð²ÐµÑ€Ð½ÑƒÑ‚ÑŒ Ð²ÑÐµ
-  label_additional_workflow_transitions_for_assignee: Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ðµ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ñ‹, ÐºÐ¾Ð³Ð´Ð° Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ ÑÐ²Ð»ÑÐµÑ‚ÑÑ Ð¸ÑÐ¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÐµÐ¼
-  label_additional_workflow_transitions_for_author: Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ðµ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ñ‹, ÐºÐ¾Ð³Ð´Ð° Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ ÑÐ²Ð»ÑÐµÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼
-  label_bulk_edit_selected_time_entries: ÐœÐ°ÑÑÐ¾Ð²Ð¾Ðµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ… Ð·Ð°Ð¿Ð¸ÑÐµÐ¹ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
-  text_time_entries_destroy_confirmation: Ð’Ñ‹ ÑƒÐ²ÐµÑ€ÐµÐ½Ñ‹ Ñ‡Ñ‚Ð¾ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸?
-  label_role_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼
-  label_role_non_member: ÐÐµ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸Ðº
-  label_issue_note_added: ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ðµ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¾
-  label_issue_status_updated: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½
-  label_issue_priority_updated: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½
-  label_issues_visibility_own: Ð—Ð°Ð´Ð°Ñ‡Ð¸ ÑÐ¾Ð·Ð´Ð°Ð½Ð½Ñ‹Ðµ Ð¸Ð»Ð¸ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ‹Ðµ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŽ
-  field_issues_visibility: Ð’Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡
-  label_issues_visibility_all: Ð’ÑÐµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  permission_set_own_issues_private: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚Ð¸ (Ð¾Ð±Ñ‰Ð°Ñ/Ñ‡Ð°ÑÑ‚Ð½Ð°Ñ) Ð´Ð»Ñ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ñ… Ð·Ð°Ð´Ð°Ñ‡
-  field_is_private: Ð§Ð°ÑÑ‚Ð½Ð°Ñ
-  permission_set_issues_private: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚Ð¸ (Ð¾Ð±Ñ‰Ð°Ñ/Ñ‡Ð°ÑÑ‚Ð½Ð°Ñ) Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ñ‡
-  label_issues_visibility_public: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð¾Ð±Ñ‰Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
-  text_issues_destroy_descendants_confirmation: Ð¢Ð°Ðº Ð¶Ðµ Ð±ÑƒÐ´ÐµÑ‚ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¾ %{count} Ð·Ð°Ð´Ð°Ñ‡(Ð¸).
-  field_commit_logs_encoding: ÐšÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ² Ð² Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
-  field_scm_path_encoding: ÐšÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° Ð¿ÑƒÑ‚Ð¸
-  text_scm_path_encoding_note: "ÐŸÐ¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ: UTF-8"
-  field_path_to_repository: ÐŸÑƒÑ‚ÑŒ Ðº Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ñƒ
-  field_root_directory: ÐšÐ¾Ñ€Ð½ÐµÐ²Ð°Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ
-  field_cvs_module: ÐœÐ¾Ð´ÑƒÐ»ÑŒ
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ðµ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ (Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€, /hgrepo, c:\hgrepo)
-  text_scm_command: ÐšÐ¾Ð¼Ð°Ð½Ð´Ð°
-  text_scm_command_version: Ð’ÐµÑ€ÑÐ¸Ñ
-  label_git_report_last_commit: Ð£ÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ÑÐ»ÐµÐ´Ð½ÐµÐµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð² Ð¸ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ð¹
-  text_scm_config: Ð’Ñ‹ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¸Ñ‚ÑŒ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ‹ SCM Ð² Ñ„Ð°Ð¹Ð»Ðµ config/configuration.yml. ÐŸÐ¾Ð¶Ð°Ð»ÑƒÐ¹ÑÑ‚Ð°, Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑÑ‚Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ Ð¿Ð¾ÑÐ»Ðµ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑ‚Ð¾Ð³Ð¾ Ñ„Ð°Ð¹Ð»Ð°.
-  text_scm_command_not_available: ÐšÐ¾Ð¼Ð°Ð½Ð´Ð° ÑÐ¸ÑÑ‚ÐµÐ¼Ñ‹ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»Ñ Ð²ÐµÑ€ÑÐ¸Ð¹ Ð½ÐµÐ´Ð¾ÑÑ‚ÑƒÐ¿Ð½Ð°. ÐŸÐ¾Ð¶Ð°Ð»ÑƒÐ¹ÑÑ‚Ð°, Ð¿Ñ€Ð¾Ð²ÐµÑ€ÑŒÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸ Ð² Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¸Ð²Ð½Ð¾Ð¹ Ð¿Ð°Ð½ÐµÐ»Ð¸.
-  notice_issue_successful_create: Ð—Ð°Ð´Ð°Ñ‡Ð° %{id} ÑÐ¾Ð·Ð´Ð°Ð½Ð°.
-  label_between: Ð¼ÐµÐ¶Ð´Ñƒ
-  setting_issue_group_assignment: Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡ Ð³Ñ€ÑƒÐ¿Ð¿Ð°Ð¼ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/68/689ac1bb7ff5cc9966ab0877e8f6f03c5f72ee2b.svn-base
--- a/.svn/pristine/68/689ac1bb7ff5cc9966ab0877e8f6f03c5f72ee2b.svn-base
+++ /dev/null
@@ -1,282 +0,0 @@
-module RedmineDiff
-  class Diff
-
-    VERSION = 0.3
-
-    def Diff.lcs(a, b)
-      astart = 0
-      bstart = 0
-      afinish = a.length-1
-      bfinish = b.length-1
-      mvector = []
-
-      # First we prune off any common elements at the beginning
-      while (astart <= afinish && bstart <= afinish && a[astart] == b[bstart])
-        mvector[astart] = bstart
-        astart += 1
-        bstart += 1
-      end
-
-      # now the end
-      while (astart <= afinish && bstart <= bfinish && a[afinish] == b[bfinish])
-        mvector[afinish] = bfinish
-        afinish -= 1
-        bfinish -= 1
-      end
-
-      bmatches = b.reverse_hash(bstart..bfinish)
-      thresh = []
-      links = []
-
-      (astart..afinish).each { |aindex|
-        aelem = a[aindex]
-        next unless bmatches.has_key? aelem
-        k = nil
-        bmatches[aelem].reverse.each { |bindex|
-    if k && (thresh[k] > bindex) && (thresh[k-1] < bindex)
-      thresh[k] = bindex
-    else
-      k = thresh.replacenextlarger(bindex, k)
-    end
-    links[k] = [ (k==0) ? nil : links[k-1], aindex, bindex ] if k
-        }
-      }
-
-      if !thresh.empty?
-        link = links[thresh.length-1]
-        while link
-    mvector[link[1]] = link[2]
-    link = link[0]
-        end
-      end
-
-      return mvector
-    end
-
-    def makediff(a, b)
-      mvector = Diff.lcs(a, b)
-      ai = bi = 0
-      while ai < mvector.length
-        bline = mvector[ai]
-        if bline
-    while bi < bline
-      discardb(bi, b[bi])
-      bi += 1
-    end
-    match(ai, bi)
-    bi += 1
-        else
-    discarda(ai, a[ai])
-        end
-        ai += 1
-      end
-      while ai < a.length
-        discarda(ai, a[ai])
-        ai += 1
-      end
-      while bi < b.length
-        discardb(bi, b[bi])
-        bi += 1
-      end
-      match(ai, bi)
-      1
-    end
-
-    def compactdiffs
-      diffs = []
-      @diffs.each { |df|
-        i = 0
-        curdiff = []
-        while i < df.length
-    whot = df[i][0]
-    s = @isstring ? df[i][2].chr : [df[i][2]]
-    p = df[i][1]
-    last = df[i][1]
-    i += 1
-    while df[i] && df[i][0] == whot && df[i][1] == last+1
-      s << df[i][2]
-      last  = df[i][1]
-      i += 1
-    end
-    curdiff.push [whot, p, s]
-        end
-        diffs.push curdiff
-      }
-      return diffs
-    end
-
-    attr_reader :diffs, :difftype
-
-    def initialize(diffs_or_a, b = nil, isstring = nil)
-      if b.nil?
-        @diffs = diffs_or_a
-        @isstring = isstring
-      else
-        @diffs = []
-        @curdiffs = []
-        makediff(diffs_or_a, b)
-        @difftype = diffs_or_a.class
-      end
-    end
-
-    def match(ai, bi)
-      @diffs.push @curdiffs unless @curdiffs.empty?
-      @curdiffs = []
-    end
-
-    def discarda(i, elem)
-      @curdiffs.push ['-', i, elem]
-    end
-
-    def discardb(i, elem)
-      @curdiffs.push ['+', i, elem]
-    end
-
-    def compact
-      return Diff.new(compactdiffs)
-    end
-
-    def compact!
-      @diffs = compactdiffs
-    end
-
-    def inspect
-      @diffs.inspect
-    end
-
-  end
-end
-
-module Diffable
-  def diff(b)
-    RedmineDiff::Diff.new(self, b)
-  end
-
-  # Create a hash that maps elements of the array to arrays of indices
-  # where the elements are found.
-
-  def reverse_hash(range = (0...self.length))
-    revmap = {}
-    range.each { |i|
-      elem = self[i]
-      if revmap.has_key? elem
-  revmap[elem].push i
-      else
-  revmap[elem] = [i]
-      end
-    }
-    return revmap
-  end
-
-  def replacenextlarger(value, high = nil)
-    high ||= self.length
-    if self.empty? || value > self[-1]
-      push value
-      return high
-    end
-    # binary search for replacement point
-    low = 0
-    while low < high
-      index = (high+low)/2
-      found = self[index]
-      return nil if value == found
-      if value > found
-  low = index + 1
-      else
-  high = index
-      end
-    end
-
-    self[low] = value
-    # $stderr << "replace #{value} : 0/#{low}/#{init_high} (#{steps} steps) (#{init_high-low} off )\n"
-    # $stderr.puts self.inspect
-    #gets
-    #p length - low
-    return low
-  end
-
-  def patch(diff)
-    newary = nil
-    if diff.difftype == String
-      newary = diff.difftype.new('')
-    else
-      newary = diff.difftype.new
-    end
-    ai = 0
-    bi = 0
-    diff.diffs.each { |d|
-      d.each { |mod|
-  case mod[0]
-  when '-'
-    while ai < mod[1]
-      newary << self[ai]
-      ai += 1
-      bi += 1
-    end
-    ai += 1
-  when '+'
-    while bi < mod[1]
-      newary << self[ai]
-      ai += 1
-      bi += 1
-    end
-    newary << mod[2]
-    bi += 1
-  else
-    raise "Unknown diff action"
-  end
-      }
-    }
-    while ai < self.length
-      newary << self[ai]
-      ai += 1
-      bi += 1
-    end
-    return newary
-  end
-end
-
-class Array
-  include Diffable
-end
-
-class String
-  include Diffable
-end
-
-=begin
-  = Diff
-  (({diff.rb})) - computes the differences between two arrays or
-  strings. Copyright (C) 2001 Lars Christensen
-
-  == Synopsis
-
-      diff = Diff.new(a, b)
-      b = a.patch(diff)
-
-  == Class Diff
-  === Class Methods
-  --- Diff.new(a, b)
-  --- a.diff(b)
-        Creates a Diff object which represent the differences between
-        ((|a|)) and ((|b|)). ((|a|)) and ((|b|)) can be either be arrays
-        of any objects, strings, or object of any class that include
-        module ((|Diffable|))
-
-  == Module Diffable
-  The module ((|Diffable|)) is intended to be included in any class for
-  which differences are to be computed. Diffable is included into String
-  and Array when (({diff.rb})) is (({require}))'d.
-
-  Classes including Diffable should implement (({[]})) to get element at
-  integer indices, (({<<})) to append elements to the object and
-  (({ClassName#new})) should accept 0 arguments to create a new empty
-  object.
-
-  === Instance Methods
-  --- Diffable#patch(diff)
-        Applies the differences from ((|diff|)) to the object ((|obj|))
-        and return the result. ((|obj|)) is not changed. ((|obj|)) and
-        can be either an array or a string, but must match the object
-        from which the ((|diff|)) was created.
-=end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/68/68cec9b340a32b5033a24e6ea73291b5b640c745.svn-base
--- /dev/null
+++ b/.svn/pristine/68/68cec9b340a32b5033a24e6ea73291b5b640c745.svn-base
@@ -0,0 +1,53 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class CommentsController < ApplicationController
+  default_search_scope :news
+  model_object News
+  before_filter :find_model_object
+  before_filter :find_project_from_association
+  before_filter :authorize
+
+  def create
+    raise Unauthorized unless @news.commentable?
+
+    @comment = Comment.new
+    @comment.safe_attributes = params[:comment]
+    @comment.author = User.current
+    if @news.comments << @comment
+      flash[:notice] = l(:label_comment_added)
+    end
+
+    redirect_to news_path(@news)
+  end
+
+  def destroy
+    @news.comments.find(params[:comment_id]).destroy
+    redirect_to news_path(@news)
+  end
+
+  private
+
+  # ApplicationController's find_model_object sets it based on the controller
+  # name so it needs to be overriden and set to @news instead
+  def find_model_object
+    super
+    @news = @object
+    @comment = nil
+    @news
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/68/68ece530a0ccbfc8971b82acf79987aea8d5c3f8.svn-base
--- a/.svn/pristine/68/68ece530a0ccbfc8971b82acf79987aea8d5c3f8.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-<%= wiki_page_breadcrumb(@page) %>
-
-<h2><%=h @page.pretty_title %></h2>
-
-<% form_tag({}, :method => :delete) do %>
-<div class="box">
-<p><strong><%= l(:text_wiki_page_destroy_question, :descendants => @descendants_count) %></strong></p>
-<p><label><%= radio_button_tag 'todo', 'nullify', true %> <%= l(:text_wiki_page_nullify_children) %></label><br />
-<label><%= radio_button_tag 'todo', 'destroy', false %> <%= l(:text_wiki_page_destroy_children) %></label>
-<% if @reassignable_to.any? %>
-<br />
-<label><%= radio_button_tag 'todo', 'reassign', false %> <%= l(:text_wiki_page_reassign_children) %></label>:
-<%= label_tag "reassign_to_id", l(:description_wiki_subpages_reassign), :class => "hidden-for-sighted" %>
-<%= select_tag 'reassign_to_id', wiki_page_options_for_select(@reassignable_to),
-                                 :onclick => "$('todo_reassign').checked = true;" %>
-<% end %>
-</p>
-</div>
-
-<%= submit_tag l(:button_apply) %>
-<%= link_to l(:button_cancel), :controller => 'wiki', :action => 'show', :project_id => @project, :id => @page.title %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/69/69158657960dc5c8b5881d15914dd410bb7c7a73.svn-base
--- a/.svn/pristine/69/69158657960dc5c8b5881d15914dd410bb7c7a73.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class Namespace::AppAndPluginController < ApplicationController
-  def an_action
-    render_class_and_action 'from app'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/69/69209f3722ef1c32ee917d4039ec4d55989dd5fc.svn-base
--- /dev/null
+++ b/.svn/pristine/69/69209f3722ef1c32ee917d4039ec4d55989dd5fc.svn-base
@@ -0,0 +1,194 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class IssuesHelperTest < ActionView::TestCase
+  include ApplicationHelper
+  include IssuesHelper
+  include CustomFieldsHelper
+  include ERB::Util
+
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :custom_fields,
+           :attachments,
+           :versions
+
+  def setup
+    super
+    set_language_if_valid('en')
+    User.current = nil
+  end
+
+  def test_issue_heading
+    assert_equal "Bug #1", issue_heading(Issue.find(1))
+  end
+
+  def test_issues_destroy_confirmation_message_with_one_root_issue
+    assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find(1))
+  end
+
+  def test_issues_destroy_confirmation_message_with_an_arrayt_of_root_issues
+    assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find([1, 2]))
+  end
+
+  def test_issues_destroy_confirmation_message_with_one_parent_issue
+    Issue.find(2).update_attribute :parent_issue_id, 1
+    assert_equal l(:text_issues_destroy_confirmation) + "\n" + l(:text_issues_destroy_descendants_confirmation, :count => 1),
+      issues_destroy_confirmation_message(Issue.find(1))
+  end
+
+  def test_issues_destroy_confirmation_message_with_one_parent_issue_and_its_child
+    Issue.find(2).update_attribute :parent_issue_id, 1
+    assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find([1, 2]))
+  end
+
+  test 'IssuesHelper#show_detail with no_html should show a changing attribute' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => '40', :value => '100', :prop_key => 'done_ratio')
+    assert_equal "% Done changed from 40 to 100", show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail with no_html should show a new attribute' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => nil, :value => '100', :prop_key => 'done_ratio')
+    assert_equal "% Done set to 100", show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail with no_html should show a deleted attribute' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => '50', :value => nil, :prop_key => 'done_ratio')
+    assert_equal "% Done deleted (50)", show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail with html should show a changing attribute with HTML highlights' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => '40', :value => '100', :prop_key => 'done_ratio')
+    html = show_detail(detail, false)
+
+    assert_include '<strong>% Done</strong>', html
+    assert_include '<i>40</i>', html
+    assert_include '<i>100</i>', html
+  end
+
+  test 'IssuesHelper#show_detail with html should show a new attribute with HTML highlights' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => nil, :value => '100', :prop_key => 'done_ratio')
+    html = show_detail(detail, false)
+
+    assert_include '<strong>% Done</strong>', html
+    assert_include '<i>100</i>', html
+  end
+
+  test 'IssuesHelper#show_detail with html should show a deleted attribute with HTML highlights' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => '50', :value => nil, :prop_key => 'done_ratio')
+    html = show_detail(detail, false)
+
+    assert_include '<strong>% Done</strong>', html
+    assert_include '<del><i>50</i></del>', html
+  end
+
+  test 'IssuesHelper#show_detail with a start_date attribute should format the dates' do
+    detail = JournalDetail.new(
+               :property  => 'attr',
+               :old_value => '2010-01-01',
+               :value     => '2010-01-31',
+               :prop_key  => 'start_date'
+            )
+    with_settings :date_format => '%m/%d/%Y' do
+      assert_match "01/31/2010", show_detail(detail, true)
+      assert_match "01/01/2010", show_detail(detail, true)
+    end
+  end
+
+  test 'IssuesHelper#show_detail with a due_date attribute should format the dates' do
+    detail = JournalDetail.new(
+              :property  => 'attr',
+              :old_value => '2010-01-01',
+              :value     => '2010-01-31',
+              :prop_key  => 'due_date'
+            )
+    with_settings :date_format => '%m/%d/%Y' do
+      assert_match "01/31/2010", show_detail(detail, true)
+      assert_match "01/01/2010", show_detail(detail, true)
+    end
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a project attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'project_id', :old_value => 1, :value => 2)
+    assert_match 'eCookbook', show_detail(detail, true)
+    assert_match 'OnlineStore', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a issue status attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'status_id', :old_value => 1, :value => 2)
+    assert_match 'New', show_detail(detail, true)
+    assert_match 'Assigned', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a tracker attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'tracker_id', :old_value => 1, :value => 2)
+    assert_match 'Bug', show_detail(detail, true)
+    assert_match 'Feature request', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a assigned to attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'assigned_to_id', :old_value => 1, :value => 2)
+    assert_match 'Redmine Admin', show_detail(detail, true)
+    assert_match 'John Smith', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a priority attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'priority_id', :old_value => 4, :value => 5)
+    assert_match 'Low', show_detail(detail, true)
+    assert_match 'Normal', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a category attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'category_id', :old_value => 1, :value => 2)
+    assert_match 'Printing', show_detail(detail, true)
+    assert_match 'Recipes', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a fixed version attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'fixed_version_id', :old_value => 1, :value => 2)
+    assert_match '0.1', show_detail(detail, true)
+    assert_match '1.0', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a estimated hours attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'estimated_hours', :old_value => '5', :value => '6.3')
+    assert_match '5.00', show_detail(detail, true)
+    assert_match '6.30', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a custom field' do
+    detail = JournalDetail.new(:property => 'cf', :prop_key => '1', :old_value => 'MySQL', :value => 'PostgreSQL')
+    assert_equal 'Database changed from MySQL to PostgreSQL', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show added file' do
+    detail = JournalDetail.new(:property => 'attachment', :prop_key => '1', :old_value => nil, :value => 'error281.txt')
+    assert_match 'error281.txt', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show removed file' do
+    detail = JournalDetail.new(:property => 'attachment', :prop_key => '1', :old_value => 'error281.txt', :value => nil)
+    assert_match 'error281.txt', show_detail(detail, true)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/69/6975387439910072689171fac66ca5755876b0a7.svn-base
--- a/.svn/pristine/69/6975387439910072689171fac66ca5755876b0a7.svn-base
+++ /dev/null
@@ -1,107 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-require 'issue_statuses_controller'
-
-# Re-raise errors caught by the controller.
-class IssueStatusesController; def rescue_action(e) raise e end; end
-
-
-class IssueStatusesControllerTest < ActionController::TestCase
-  fixtures :issue_statuses, :issues
-
-  def setup
-    @controller = IssueStatusesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @request.session[:user_id] = 1 # admin
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-  end
-  
-  def test_index_by_anonymous_should_redirect_to_login_form
-    @request.session[:user_id] = nil
-    get :index
-    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fissue_statuses'
-  end
-  
-  def test_index_by_user_should_respond_with_406
-    @request.session[:user_id] = 2
-    get :index
-    assert_response 406
-  end
-
-  def test_new
-    get :new
-    assert_response :success
-    assert_template 'new'
-  end
-
-  def test_create
-    assert_difference 'IssueStatus.count' do
-      post :create, :issue_status => {:name => 'New status'}
-    end
-    assert_redirected_to :action => 'index'
-    status = IssueStatus.find(:first, :order => 'id DESC')
-    assert_equal 'New status', status.name
-  end
-
-  def test_edit
-    get :edit, :id => '3'
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_update
-    put :update, :id => '3', :issue_status => {:name => 'Renamed status'}
-    assert_redirected_to :action => 'index'
-    status = IssueStatus.find(3)
-    assert_equal 'Renamed status', status.name
-  end
-
-  def test_destroy
-    Issue.delete_all("status_id = 1")
-
-    assert_difference 'IssueStatus.count', -1 do
-      delete :destroy, :id => '1'
-    end
-    assert_redirected_to :action => 'index'
-    assert_nil IssueStatus.find_by_id(1)
-  end
-
-  def test_destroy_should_block_if_status_in_use
-    assert_not_nil Issue.find_by_status_id(1)
-
-    assert_no_difference 'IssueStatus.count' do
-      delete :destroy, :id => '1'
-    end
-    assert_redirected_to :action => 'index'
-    assert_not_nil IssueStatus.find_by_id(1)
-  end
-
-  context "on POST to :update_issue_done_ratio" do
-    context "with Setting.issue_done_ratio using the issue_field" do
-      setup do
-        Setting.issue_done_ratio = 'issue_field'
-        post :update_issue_done_ratio
-      end
-
-      should_set_the_flash_to /not updated/
-      should_redirect_to('the index') { '/issue_statuses' }
-    end
-
-    context "with Setting.issue_done_ratio using the issue_status" do
-      setup do
-        Setting.issue_done_ratio = 'issue_status'
-        post :update_issue_done_ratio
-      end
-
-      should_set_the_flash_to /Issue done ratios updated/
-      should_redirect_to('the index') { '/issue_statuses' }
-    end
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/69/6985b7da5db7388f839f13e1c4ad6f39ec6acc94.svn-base
--- a/.svn/pristine/69/6985b7da5db7388f839f13e1c4ad6f39ec6acc94.svn-base
+++ /dev/null
@@ -1,94 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class AuthSourcesControllerTest < ActionController::TestCase
-
-  def setup
-    @request.session[:user_id] = 1
-  end
-
-  context "get :index" do
-    setup do
-      get :index
-    end
-
-    should_assign_to :auth_sources
-    should_assign_to :auth_source_pages
-    should_respond_with :success
-    should_render_template :index
-  end
-
-  context "get :new" do
-    setup do
-      get :new
-    end
-
-    should_assign_to :auth_source
-    should_respond_with :success
-    should_render_template :new
-
-    should "initilize a new AuthSource" do
-      assert_equal AuthSource, assigns(:auth_source).class
-      assert assigns(:auth_source).new_record?
-    end
-  end
-
-  context "post :create" do
-    setup do
-      post :create, :auth_source => {:name => 'Test'}
-    end
-
-    should_respond_with :redirect
-    should_redirect_to("index") {{:action => 'index'}}
-    should_set_the_flash_to /success/i
-  end
-
-  context "get :edit" do
-    setup do
-      @auth_source = AuthSource.generate!(:name => 'TestEdit')
-      get :edit, :id => @auth_source.id
-    end
-
-    should_assign_to(:auth_source) {@auth_source}
-    should_respond_with :success
-    should_render_template :edit
-  end
-
-  context "post :update" do
-    setup do
-      @auth_source = AuthSource.generate!(:name => 'TestEdit')
-      post :update, :id => @auth_source.id, :auth_source => {:name => 'TestUpdate'}
-    end
-
-    should_respond_with :redirect
-    should_redirect_to("index") {{:action => 'index'}}
-    should_set_the_flash_to /update/i
-  end
-
-  context "post :destroy" do
-    setup do
-      @auth_source = AuthSource.generate!(:name => 'TestEdit')
-    end
-
-    context "without users" do
-      setup do
-        post :destroy, :id => @auth_source.id
-      end
-
-      should_respond_with :redirect
-      should_redirect_to("index") {{:action => 'index'}}
-      should_set_the_flash_to /deletion/i
-    end
-
-    context "with users" do
-      setup do
-        User.generate!(:auth_source => @auth_source)
-        post :destroy, :id => @auth_source.id
-      end
-
-      should_respond_with :redirect
-      should "not destroy the AuthSource" do
-        assert AuthSource.find(@auth_source.id)
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/69/698f61b75b6827fc986074ba0064676c404b5ac4.svn-base
--- a/.svn/pristine/69/698f61b75b6827fc986074ba0064676c404b5ac4.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar LV language
-// Translation: Dzintars Bergs, dzintars.bergs@gmail.com
-// Encoding: UTF-8
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("SvÄ“tdiena",
- "Pirmdiena",
- "Otrdiena",
- "TreÅ¡diena",
- "Ceturtdiena",
- "Piektdiena",
- "Sestdiena",
- "SvÄ“tdiena");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Sv",
- "Pr",
- "Ot",
- "Tr",
- "Ct",
- "Pk",
- "St",
- "Sv");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("JanvÄris",
- "FebruÄris",
- "Marts",
- "AprÄ«lis",
- "Maijs",
- "JÅ«nijs",
- "JÅ«lijs",
- "Augusts",
- "Septembris",
- "Oktobris",
- "Novembris",
- "Decembris");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "Mar",
- "Apr",
- "Mai",
- "JÅ«n",
- "JÅ«l",
- "Aug",
- "Sep",
- "Okt",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Par kalendÄru";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "IepriekÅ¡Ä“jais gads (pieturÄ“t, lai atvÄ“rtu izvÄ“lni)";
-Calendar._TT["PREV_MONTH"] = "IepriekÅ¡Ä“jais mÄ“nesis (pieturÄ“t, lai atvÄ“rtu izvÄ“lni)";
-Calendar._TT["GO_TODAY"] = "Iet uz Å¡odienu";
-Calendar._TT["NEXT_MONTH"] = "NÄkoÅ¡ais mÄ“nesis (pieturÄ“t, lai atvÄ“rtu izvÄ“lni)";
-Calendar._TT["NEXT_YEAR"] = "NÄkoÅ¡ais gads (pieturÄ“t, lai atvÄ“rtu izvÄ“lni)";
-Calendar._TT["SEL_DATE"] = "IzvÄ“lieties datumu";
-Calendar._TT["DRAG_TO_MOVE"] = "Vilkt, lai pÄrvietotu";
-Calendar._TT["PART_TODAY"] = "(Å¡odiena)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "RÄdÄ«t %s pirmo";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "AizvÄ“rt";
-Calendar._TT["TODAY"] = "Å odiena";
-Calendar._TT["TIME_PART"] = "(Shift-)Click vai ievilkt, lai mainÄ«tu vÄ“rtÄ«bu";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y";
-Calendar._TT["TT_DATE_FORMAT"] = " %b, %a %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Laiks:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/69/699a58897b9f326128b2eda7e3ea2de970223d84.svn-base
--- a/.svn/pristine/69/699a58897b9f326128b2eda7e3ea2de970223d84.svn-base
+++ /dev/null
@@ -1,56 +0,0 @@
-<div class="contextual">
-<%= link_to(l(:button_edit), edit_version_path(@version), :class => 'icon icon-edit') if User.current.allowed_to?(:manage_versions, @version.project) %>
-<%= link_to_if_authorized(l(:button_edit_associated_wikipage, :page_title => @version.wiki_page_title), {:controller => 'wiki', :action => 'edit', :project_id => @version.project, :id => Wiki.titleize(@version.wiki_page_title)}, :class => 'icon icon-edit') unless @version.wiki_page_title.blank? || @version.project.wiki.nil? %>
-<%= link_to(l(:button_delete), version_path(@version, :back_url => url_for(:controller => 'versions', :action => 'index', :project_id => @version.project)),
-  :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') if User.current.allowed_to?(:manage_versions, @version.project) %>
-<%= call_hook(:view_versions_show_contextual, { :version => @version, :project => @project }) %>
-</div>
-
-<h2><%= h(@version.name) %></h2>
-
-<div id="roadmap">
-<%= render :partial => 'versions/overview', :locals => {:version => @version} %>
-<%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %>
-
-<div id="version-summary">
-<% if @version.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %>
-<fieldset><legend><%= l(:label_time_tracking) %></legend>
-<table>
-<tr>
-    <td width="130px" align="right"><%= l(:field_estimated_hours) %></td>
-    <td width="240px" class="total-hours"width="130px" align="right"><%= html_hours(l_hours(@version.estimated_hours)) %></td>
-</tr>
-<% if User.current.allowed_to?(:view_time_entries, @project) %>
-<tr>
-    <td width="130px" align="right"><%= l(:label_spent_time) %></td>
-    <td width="240px" class="total-hours"><%= html_hours(l_hours(@version.spent_hours)) %></td>
-</tr>
-<% end %>
-</table>
-</fieldset>
-<% end %>
-
-<div id="status_by">
-<%= render_issue_status_by(@version, params[:status_by]) if @version.fixed_issues.count > 0 %>
-</div>
-</div>
-
-<% if @issues.present? %>
-<% form_tag({}) do -%>
-  <table class="list related-issues">
-  <caption><%= l(:label_related_issues) %></caption>
-  <%- @issues.each do |issue| -%>
-    <tr class="hascontextmenu">
-      <td class="checkbox"><%= check_box_tag 'ids[]', issue.id %></td>
-      <td><%= link_to_issue(issue, :project => (@project != issue.project)) %></td>
-    </tr>
-  <% end %>
-  </table>
-<% end %>
-<%= context_menu issues_context_menu_path %>
-<% end %>
-</div>
-
-<%= call_hook :view_versions_show_bottom, :version => @version %>
-
-<% html_title @version.name %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/69/69aea32e67c1e43bf9542a209fc02cf6c1b5854c.svn-base
--- a/.svn/pristine/69/69aea32e67c1e43bf9542a209fc02cf6c1b5854c.svn-base
+++ /dev/null
@@ -1,193 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'repositories_controller'
-
-# Re-raise errors caught by the controller.
-class RepositoriesController; def rescue_action(e) raise e end; end
-
-class RepositoriesBazaarControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles,
-           :repositories, :enabled_modules
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository/trunk').to_s
-  PRJ_ID = 3
-
-  def setup
-    @controller = RepositoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @project = Project.find(PRJ_ID)
-    @repository = Repository::Bazaar.create(
-                    :project      => @project,
-                    :url          => REPOSITORY_PATH,
-                    :log_encoding => 'UTF-8')
-    assert @repository
-  end
-
-  if File.directory?(REPOSITORY_PATH)
-    def test_browse_root
-      get :show, :id => PRJ_ID
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal 2, assigns(:entries).size
-      assert assigns(:entries).detect {|e| e.name == 'directory' && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'doc-mkdir.txt' && e.kind == 'file'}
-    end
-
-    def test_browse_directory
-      get :show, :id => PRJ_ID, :path => ['directory']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['doc-ls.txt', 'document.txt', 'edit.png'], assigns(:entries).collect(&:name)
-      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
-      assert_not_nil entry
-      assert_equal 'file', entry.kind
-      assert_equal 'directory/edit.png', entry.path
-    end
-
-    def test_browse_at_given_revision
-      get :show, :id => PRJ_ID, :path => [], :rev => 3
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['directory', 'doc-deleted.txt', 'doc-ls.txt', 'doc-mkdir.txt'],
-                   assigns(:entries).collect(&:name)
-    end
-
-    def test_changes
-      get :changes, :id => PRJ_ID, :path => ['doc-mkdir.txt']
-      assert_response :success
-      assert_template 'changes'
-      assert_tag :tag => 'h2', :content => 'doc-mkdir.txt'
-    end
-
-    def test_entry_show
-      get :entry, :id => PRJ_ID, :path => ['directory', 'doc-ls.txt']
-      assert_response :success
-      assert_template 'entry'
-      # Line 19
-      assert_tag :tag => 'th',
-                 :content => /29/,
-                 :attributes => { :class => /line-num/ },
-                 :sibling => { :tag => 'td', :content => /Show help message/ }
-    end
-
-    def test_entry_download
-      get :entry, :id => PRJ_ID, :path => ['directory', 'doc-ls.txt'], :format => 'raw'
-      assert_response :success
-      # File content
-      assert @response.body.include?('Show help message')
-    end
-
-    def test_directory_entry
-      get :entry, :id => PRJ_ID, :path => ['directory']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entry)
-      assert_equal 'directory', assigns(:entry).name
-    end
-
-    def test_diff
-      # Full diff of changeset 3
-      ['inline', 'sbs'].each do |dt|
-        get :diff, :id => PRJ_ID, :rev => 3, :type => dt
-        assert_response :success
-        assert_template 'diff'
-        # Line 11 removed
-        assert_tag :tag => 'th',
-                   :content => '11',
-                   :sibling => { :tag => 'td',
-                                 :attributes => { :class => /diff_out/ },
-                                 :content => /Display more information/ }
-      end
-    end
-
-    def test_annotate
-      get :annotate, :id => PRJ_ID, :path => ['doc-mkdir.txt']
-      assert_response :success
-      assert_template 'annotate'
-      assert_tag :tag => 'th', :content => '2',
-                 :sibling => {
-                    :tag => 'td',
-                    :child => {
-                       :tag => 'a',
-                       :content => '3'
-                       }
-                    }
-      assert_tag :tag => 'th', :content => '2',
-                 :sibling => { :tag => 'td', :content => /jsmith/ }
-      assert_tag :tag => 'th', :content => '2',
-                 :sibling => {
-                    :tag => 'td',
-                    :child => {
-                       :tag => 'a',
-                       :content => '3'
-                       }
-                    }
-      assert_tag :tag => 'th', :content => '2',
-                 :sibling => { :tag => 'td', :content => /Main purpose/ }
-    end
-
-    def test_destroy_valid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert @repository.changesets.count > 0
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-
-    def test_destroy_invalid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert @repository.changesets.count > 0
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-
-      @repository = Repository::Bazaar.create(
-                    :project      => @project,
-                    :url          => "/invalid",
-                    :log_encoding => 'UTF-8')
-      assert @repository
-      @repository.fetch_changesets
-      @repository.reload
-      assert_equal 0, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-  else
-    puts "Bazaar test repository NOT FOUND. Skipping functional tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/69/69bc5c1c53ea4e9d8ad8c537b1338f42510d7272.svn-base
--- /dev/null
+++ b/.svn/pristine/69/69bc5c1c53ea4e9d8ad8c537b1338f42510d7272.svn-base
@@ -0,0 +1,435 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module MenuManager
+    class MenuError < StandardError #:nodoc:
+    end
+
+    module MenuController
+      def self.included(base)
+        base.extend(ClassMethods)
+      end
+
+      module ClassMethods
+        @@menu_items = Hash.new {|hash, key| hash[key] = {:default => key, :actions => {}}}
+        mattr_accessor :menu_items
+
+        # Set the menu item name for a controller or specific actions
+        # Examples:
+        #   * menu_item :tickets # => sets the menu name to :tickets for the whole controller
+        #   * menu_item :tickets, :only => :list # => sets the menu name to :tickets for the 'list' action only
+        #   * menu_item :tickets, :only => [:list, :show] # => sets the menu name to :tickets for 2 actions only
+        #
+        # The default menu item name for a controller is controller_name by default
+        # Eg. the default menu item name for ProjectsController is :projects
+        def menu_item(id, options = {})
+          if actions = options[:only]
+            actions = [] << actions unless actions.is_a?(Array)
+            actions.each {|a| menu_items[controller_name.to_sym][:actions][a.to_sym] = id}
+          else
+            menu_items[controller_name.to_sym][:default] = id
+          end
+        end
+      end
+
+      def menu_items
+        self.class.menu_items
+      end
+
+      # Returns the menu item name according to the current action
+      def current_menu_item
+        @current_menu_item ||= menu_items[controller_name.to_sym][:actions][action_name.to_sym] ||
+                                 menu_items[controller_name.to_sym][:default]
+      end
+
+      # Redirects user to the menu item of the given project
+      # Returns false if user is not authorized
+      def redirect_to_project_menu_item(project, name)
+        item = Redmine::MenuManager.items(:project_menu).detect {|i| i.name.to_s == name.to_s}
+        if item && User.current.allowed_to?(item.url, project) && (item.condition.nil? || item.condition.call(project))
+          redirect_to({item.param => project}.merge(item.url))
+          return true
+        end
+        false
+      end
+    end
+
+    module MenuHelper
+      # Returns the current menu item name
+      def current_menu_item
+        controller.current_menu_item
+      end
+
+      # Renders the application main menu
+      def render_main_menu(project)
+        render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
+      end
+
+      def display_main_menu?(project)
+        menu_name = project && !project.new_record? ? :project_menu : :application_menu
+        Redmine::MenuManager.items(menu_name).children.present?
+      end
+
+      def render_menu(menu, project=nil)
+        links = []
+        menu_items_for(menu, project) do |node|
+          links << render_menu_node(node, project)
+        end
+        links.empty? ? nil : content_tag('ul', links.join("\n").html_safe)
+      end
+
+      def render_menu_node(node, project=nil)
+        if node.children.present? || !node.child_menus.nil?
+          return render_menu_node_with_children(node, project)
+        else
+          caption, url, selected = extract_node_details(node, project)
+          return content_tag('li',
+                               render_single_menu_node(node, caption, url, selected))
+        end
+      end
+
+      def render_menu_node_with_children(node, project=nil)
+        caption, url, selected = extract_node_details(node, project)
+
+        html = [].tap do |html|
+          html << '<li>'
+          # Parent
+          html << render_single_menu_node(node, caption, url, selected)
+
+          # Standard children
+          standard_children_list = "".html_safe.tap do |child_html|
+            node.children.each do |child|
+              child_html << render_menu_node(child, project)
+            end
+          end
+
+          html << content_tag(:ul, standard_children_list, :class => 'menu-children') unless standard_children_list.empty?
+
+          # Unattached children
+          unattached_children_list = render_unattached_children_menu(node, project)
+          html << content_tag(:ul, unattached_children_list, :class => 'menu-children unattached') unless unattached_children_list.blank?
+
+          html << '</li>'
+        end
+        return html.join("\n").html_safe
+      end
+
+      # Returns a list of unattached children menu items
+      def render_unattached_children_menu(node, project)
+        return nil unless node.child_menus
+
+        "".html_safe.tap do |child_html|
+          unattached_children = node.child_menus.call(project)
+          # Tree nodes support #each so we need to do object detection
+          if unattached_children.is_a? Array
+            unattached_children.each do |child|
+              child_html << content_tag(:li, render_unattached_menu_item(child, project))
+            end
+          else
+            raise MenuError, ":child_menus must be an array of MenuItems"
+          end
+        end
+      end
+
+      def render_single_menu_node(item, caption, url, selected)
+        link_to(h(caption), url, item.html_options(:selected => selected))
+      end
+
+      def render_unattached_menu_item(menu_item, project)
+        raise MenuError, ":child_menus must be an array of MenuItems" unless menu_item.is_a? MenuItem
+
+        if User.current.allowed_to?(menu_item.url, project)
+          link_to(h(menu_item.caption),
+                  menu_item.url,
+                  menu_item.html_options)
+        end
+      end
+
+      def menu_items_for(menu, project=nil)
+        items = []
+        Redmine::MenuManager.items(menu).root.children.each do |node|
+          if allowed_node?(node, User.current, project)
+            if block_given?
+              yield node
+            else
+              items << node  # TODO: not used?
+            end
+          end
+        end
+        return block_given? ? nil : items
+      end
+
+      def extract_node_details(node, project=nil)
+        item = node
+        url = case item.url
+        when Hash
+          project.nil? ? item.url : {item.param => project}.merge(item.url)
+        when Symbol
+          send(item.url)
+        else
+          item.url
+        end
+        caption = item.caption(project)
+        return [caption, url, (current_menu_item == item.name)]
+      end
+
+      # Checks if a user is allowed to access the menu item by:
+      #
+      # * Checking the url target (project only)
+      # * Checking the conditions of the item
+      def allowed_node?(node, user, project)
+        if project && user && !user.allowed_to?(node.url, project)
+          return false
+        end
+        if node.condition && !node.condition.call(project)
+          # Condition that doesn't pass
+          return false
+        end
+        return true
+      end
+    end
+
+    class << self
+      def map(menu_name)
+        @items ||= {}
+        mapper = Mapper.new(menu_name.to_sym, @items)
+        if block_given?
+          yield mapper
+        else
+          mapper
+        end
+      end
+
+      def items(menu_name)
+        @items[menu_name.to_sym] || MenuNode.new(:root, {})
+      end
+    end
+
+    class Mapper
+      def initialize(menu, items)
+        items[menu] ||= MenuNode.new(:root, {})
+        @menu = menu
+        @menu_items = items[menu]
+      end
+
+      # Adds an item at the end of the menu. Available options:
+      # * param: the parameter name that is used for the project id (default is :id)
+      # * if: a Proc that is called before rendering the item, the item is displayed only if it returns true
+      # * caption that can be:
+      #   * a localized string Symbol
+      #   * a String
+      #   * a Proc that can take the project as argument
+      # * before, after: specify where the menu item should be inserted (eg. :after => :activity)
+      # * parent: menu item will be added as a child of another named menu (eg. :parent => :issues)
+      # * children: a Proc that is called before rendering the item. The Proc should return an array of MenuItems, which will be added as children to this item.
+      #   eg. :children => Proc.new {|project| [Redmine::MenuManager::MenuItem.new(...)] }
+      # * last: menu item will stay at the end (eg. :last => true)
+      # * html_options: a hash of html options that are passed to link_to
+      def push(name, url, options={})
+        options = options.dup
+
+        if options[:parent]
+          subtree = self.find(options[:parent])
+          if subtree
+            target_root = subtree
+          else
+            target_root = @menu_items.root
+          end
+
+        else
+          target_root = @menu_items.root
+        end
+
+        # menu item position
+        if first = options.delete(:first)
+          target_root.prepend(MenuItem.new(name, url, options))
+        elsif before = options.delete(:before)
+
+          if exists?(before)
+            target_root.add_at(MenuItem.new(name, url, options), position_of(before))
+          else
+            target_root.add(MenuItem.new(name, url, options))
+          end
+
+        elsif after = options.delete(:after)
+
+          if exists?(after)
+            target_root.add_at(MenuItem.new(name, url, options), position_of(after) + 1)
+          else
+            target_root.add(MenuItem.new(name, url, options))
+          end
+
+        elsif options[:last] # don't delete, needs to be stored
+          target_root.add_last(MenuItem.new(name, url, options))
+        else
+          target_root.add(MenuItem.new(name, url, options))
+        end
+      end
+
+      # Removes a menu item
+      def delete(name)
+        if found = self.find(name)
+          @menu_items.remove!(found)
+        end
+      end
+
+      # Checks if a menu item exists
+      def exists?(name)
+        @menu_items.any? {|node| node.name == name}
+      end
+
+      def find(name)
+        @menu_items.find {|node| node.name == name}
+      end
+
+      def position_of(name)
+        @menu_items.each do |node|
+          if node.name == name
+            return node.position
+          end
+        end
+      end
+    end
+
+    class MenuNode
+      include Enumerable
+      attr_accessor :parent
+      attr_reader :last_items_count, :name
+
+      def initialize(name, content = nil)
+        @name = name
+        @children = []
+        @last_items_count = 0
+      end
+
+      def children
+        if block_given?
+          @children.each {|child| yield child}
+        else
+          @children
+        end
+      end
+
+      # Returns the number of descendants + 1
+      def size
+        @children.inject(1) {|sum, node| sum + node.size}
+      end
+
+      def each &block
+        yield self
+        children { |child| child.each(&block) }
+      end
+
+      # Adds a child at first position
+      def prepend(child)
+        add_at(child, 0)
+      end
+
+      # Adds a child at given position
+      def add_at(child, position)
+        raise "Child already added" if find {|node| node.name == child.name}
+
+        @children = @children.insert(position, child)
+        child.parent = self
+        child
+      end
+
+      # Adds a child as last child
+      def add_last(child)
+        add_at(child, -1)
+        @last_items_count += 1
+        child
+      end
+
+      # Adds a child
+      def add(child)
+        position = @children.size - @last_items_count
+        add_at(child, position)
+      end
+      alias :<< :add
+
+      # Removes a child
+      def remove!(child)
+        @children.delete(child)
+        @last_items_count -= +1 if child && child.last
+        child.parent = nil
+        child
+      end
+
+      # Returns the position for this node in it's parent
+      def position
+        self.parent.children.index(self)
+      end
+
+      # Returns the root for this node
+      def root
+        root = self
+        root = root.parent while root.parent
+        root
+      end
+    end
+
+    class MenuItem < MenuNode
+      include Redmine::I18n
+      attr_reader :name, :url, :param, :condition, :parent, :child_menus, :last
+
+      def initialize(name, url, options)
+        raise ArgumentError, "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call)
+        raise ArgumentError, "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash)
+        raise ArgumentError, "Cannot set the :parent to be the same as this item" if options[:parent] == name.to_sym
+        raise ArgumentError, "Invalid option :children for menu item '#{name}'" if options[:children] && !options[:children].respond_to?(:call)
+        @name = name
+        @url = url
+        @condition = options[:if]
+        @param = options[:param] || :id
+        @caption = options[:caption]
+        @html_options = options[:html] || {}
+        # Adds a unique class to each menu item based on its name
+        @html_options[:class] = [@html_options[:class], @name.to_s.dasherize].compact.join(' ')
+        @parent = options[:parent]
+        @child_menus = options[:children]
+        @last = options[:last] || false
+        super @name.to_sym
+      end
+
+      def caption(project=nil)
+        if @caption.is_a?(Proc)
+          c = @caption.call(project).to_s
+          c = @name.to_s.humanize if c.blank?
+          c
+        else
+          if @caption.nil?
+            l_or_humanize(name, :prefix => 'label_')
+          else
+            @caption.is_a?(Symbol) ? l(@caption) : @caption
+          end
+        end
+      end
+
+      def html_options(options={})
+        if options[:selected]
+          o = @html_options.dup
+          o[:class] += ' selected'
+          o
+        else
+          @html_options
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/69/69d93dae7af0a934d2b88863b74d127eebc3a82f.svn-base
--- a/.svn/pristine/69/69d93dae7af0a934d2b88863b74d127eebc3a82f.svn-base
+++ /dev/null
@@ -1,20 +0,0 @@
-Description:
-    The plugin generator creates stubs for a new Redmine plugin.
-	
-Example:
-    ./script/generate redmine_plugin meetings
-      create  vendor/plugins/redmine_meetings/app/controllers
-      create  vendor/plugins/redmine_meetings/app/helpers
-      create  vendor/plugins/redmine_meetings/app/models
-      create  vendor/plugins/redmine_meetings/app/views
-      create  vendor/plugins/redmine_meetings/db/migrate
-      create  vendor/plugins/redmine_meetings/lib/tasks
-      create  vendor/plugins/redmine_meetings/assets/images
-      create  vendor/plugins/redmine_meetings/assets/javascripts
-      create  vendor/plugins/redmine_meetings/assets/stylesheets
-      create  vendor/plugins/redmine_meetings/lang
-      create  vendor/plugins/redmine_meetings/README
-      create  vendor/plugins/redmine_meetings/init.rb
-      create  vendor/plugins/redmine_meetings/lang/en.yml
-      create  vendor/plugins/redmine_meetings/config/locales/en.yml
-      create  vendor/plugins/redmine_meetings/test/test_helper.rb
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6a/6a0944d7e583de44e8a1af8231e3395612ce51a0.svn-base
--- a/.svn/pristine/6a/6a0944d7e583de44e8a1af8231e3395612ce51a0.svn-base
+++ /dev/null
@@ -1,40 +0,0 @@
-<%= render :partial => 'action_menu' %>
-
-<h2><%=l(:label_workflow)%></h2>
-
-<% form_tag({}, :id => 'workflow_copy_form') do %>
-<fieldset class="tabular box">
-<legend><%= l(:label_copy_source) %></legend>
-<p>
-  <label><%= l(:label_tracker) %></label>
-  <%= select_tag('source_tracker_id',
-                  "<option value=\"\">--- #{l(:actionview_instancetag_blank_option)} ---</option>" +
-                  "<option value=\"any\">--- #{ l(:label_copy_same_as_target) } ---</option>" +
-                  options_from_collection_for_select(@trackers, 'id', 'name', @source_tracker && @source_tracker.id)) %>
-</p>
-<p>
-  <label><%= l(:label_role) %></label>
-  <%= select_tag('source_role_id',
-                  "<option value=\"\">--- #{l(:actionview_instancetag_blank_option)} ---</option>" +
-                  "<option value=\"any\">--- #{ l(:label_copy_same_as_target) } ---</option>" +
-                  options_from_collection_for_select(@roles, 'id', 'name', @source_role && @source_role.id)) %>
-</p>
-</fieldset>
-
-<fieldset class="tabular box">
-<legend><%= l(:label_copy_target) %></legend>
-<p>
-  <label><%= l(:label_tracker) %></label>
-  <%= select_tag 'target_tracker_ids',
-                  "<option value=\"\" disabled=\"disabled\">--- #{l(:actionview_instancetag_blank_option)} ---</option>" +
-                  options_from_collection_for_select(@trackers, 'id', 'name', @target_trackers && @target_trackers.map(&:id)), :multiple => true %>
-</p>
-<p>
-  <label><%= l(:label_role) %></label>
-  <%= select_tag 'target_role_ids',
-                  "<option value=\"\" disabled=\"disabled\">--- #{l(:actionview_instancetag_blank_option)} ---</option>" +
-                  options_from_collection_for_select(@roles, 'id', 'name', @target_roles && @target_roles.map(&:id)), :multiple => true %>
-</p>
-</fieldset>
-<%= submit_tag l(:button_copy) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6a/6a4fdd885d26844cca5f9f69058f8424de0ff4e2.svn-base
--- a/.svn/pristine/6a/6a4fdd885d26844cca5f9f69058f8424de0ff4e2.svn-base
+++ /dev/null
@@ -1,95 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Activity
-    # Class used to retrieve activity events
-    class Fetcher
-      attr_reader :user, :project, :scope
-
-      # Needs to be unloaded in development mode
-      @@constantized_providers = Hash.new {|h,k| h[k] = Redmine::Activity.providers[k].collect {|t| t.constantize } }
-
-      def initialize(user, options={})
-        options.assert_valid_keys(:project, :with_subprojects, :author)
-        @user = user
-        @project = options[:project]
-        @options = options
-
-        @scope = event_types
-      end
-
-      # Returns an array of available event types
-      def event_types
-        return @event_types unless @event_types.nil?
-
-        @event_types = Redmine::Activity.available_event_types
-        @event_types = @event_types.select {|o| @project.self_and_descendants.detect {|p| @user.allowed_to?("view_#{o}".to_sym, p)}} if @project
-        @event_types
-      end
-
-      # Yields to filter the activity scope
-      def scope_select(&block)
-        @scope = @scope.select {|t| yield t }
-      end
-
-      # Sets the scope
-      # Argument can be :all, :default or an array of event types
-      def scope=(s)
-        case s
-        when :all
-          @scope = event_types
-        when :default
-          default_scope!
-        else
-          @scope = s & event_types
-        end
-      end
-
-      # Resets the scope to the default scope
-      def default_scope!
-        @scope = Redmine::Activity.default_event_types
-      end
-
-      # Returns an array of events for the given date range
-      # sorted in reverse chronological order
-      def events(from = nil, to = nil, options={})
-        e = []
-        @options[:limit] = options[:limit]
-
-        @scope.each do |event_type|
-          constantized_providers(event_type).each do |provider|
-            e += provider.find_events(event_type, @user, from, to, @options)
-          end
-        end
-
-        e.sort! {|a,b| b.event_datetime <=> a.event_datetime}
-
-        if options[:limit]
-          e = e.slice(0, options[:limit])
-        end
-        e
-      end
-
-      private
-
-      def constantized_providers(event_type)
-        @@constantized_providers[event_type]
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6a/6a5d3fae16f610dc522054eb46ce6c8d182d8b9a.svn-base
--- /dev/null
+++ b/.svn/pristine/6a/6a5d3fae16f610dc522054eb46ce6c8d182d8b9a.svn-base
@@ -0,0 +1,425 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class UsersControllerTest < ActionController::TestCase
+  include Redmine::I18n
+
+  fixtures :users, :projects, :members, :member_roles, :roles,
+           :custom_fields, :custom_values, :groups_users,
+           :auth_sources
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 1 # admin
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:users)
+    # active users only
+    assert_nil assigns(:users).detect {|u| !u.active?}
+  end
+
+  def test_index_with_status_filter
+    get :index, :status => 3
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:users)
+    assert_equal [3], assigns(:users).map(&:status).uniq
+  end
+
+  def test_index_with_name_filter
+    get :index, :name => 'john'
+    assert_response :success
+    assert_template 'index'
+    users = assigns(:users)
+    assert_not_nil users
+    assert_equal 1, users.size
+    assert_equal 'John', users.first.firstname
+  end
+
+  def test_index_with_group_filter
+    get :index, :group_id => '10'
+    assert_response :success
+    assert_template 'index'
+    users = assigns(:users)
+    assert users.any?
+    assert_equal([], (users - Group.find(10).users))
+    assert_select 'select[name=group_id]' do
+      assert_select 'option[value=10][selected=selected]'
+    end
+  end
+
+  def test_show
+    @request.session[:user_id] = nil
+    get :show, :id => 2
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:user)
+
+    assert_tag 'li', :content => /Phone number/
+  end
+
+  def test_show_should_not_display_hidden_custom_fields
+    @request.session[:user_id] = nil
+    UserCustomField.find_by_name('Phone number').update_attribute :visible, false
+    get :show, :id => 2
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:user)
+
+    assert_no_tag 'li', :content => /Phone number/
+  end
+
+  def test_show_should_not_fail_when_custom_values_are_nil
+    user = User.find(2)
+
+    # Create a custom field to illustrate the issue
+    custom_field = CustomField.create!(:name => 'Testing', :field_format => 'text')
+    custom_value = user.custom_values.build(:custom_field => custom_field).save!
+
+    get :show, :id => 2
+    assert_response :success
+  end
+
+  def test_show_inactive
+    @request.session[:user_id] = nil
+    get :show, :id => 5
+    assert_response 404
+  end
+
+  def test_show_should_not_reveal_users_with_no_visible_activity_or_project
+    @request.session[:user_id] = nil
+    get :show, :id => 9
+    assert_response 404
+  end
+
+  def test_show_inactive_by_admin
+    @request.session[:user_id] = 1
+    get :show, :id => 5
+    assert_response 200
+    assert_not_nil assigns(:user)
+  end
+
+  def test_show_displays_memberships_based_on_project_visibility
+    @request.session[:user_id] = 1
+    get :show, :id => 2
+    assert_response :success
+    memberships = assigns(:memberships)
+    assert_not_nil memberships
+    project_ids = memberships.map(&:project_id)
+    assert project_ids.include?(2) #private project admin can see
+  end
+
+  def test_show_current_should_require_authentication
+    @request.session[:user_id] = nil
+    get :show, :id => 'current'
+    assert_response 302
+  end
+
+  def test_show_current
+    @request.session[:user_id] = 2
+    get :show, :id => 'current'
+    assert_response :success
+    assert_template 'show'
+    assert_equal User.find(2), assigns(:user)
+  end
+
+  def test_new
+    get :new
+    assert_response :success
+    assert_template :new
+    assert assigns(:user)
+  end
+
+  def test_create
+    Setting.bcc_recipients = '1'
+
+    assert_difference 'User.count' do
+      assert_difference 'ActionMailer::Base.deliveries.size' do
+        post :create,
+          :user => {
+            :firstname => 'John',
+            :lastname => 'Doe',
+            :login => 'jdoe',
+            :password => 'secret123',
+            :password_confirmation => 'secret123',
+            :mail => 'jdoe@gmail.com',
+            :mail_notification => 'none'
+          },
+          :send_information => '1'
+      end
+    end
+
+    user = User.first(:order => 'id DESC')
+    assert_redirected_to :controller => 'users', :action => 'edit', :id => user.id
+
+    assert_equal 'John', user.firstname
+    assert_equal 'Doe', user.lastname
+    assert_equal 'jdoe', user.login
+    assert_equal 'jdoe@gmail.com', user.mail
+    assert_equal 'none', user.mail_notification
+    assert user.check_password?('secret123')
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert_equal [user.mail], mail.bcc
+    assert_mail_body_match 'secret', mail
+  end
+
+  def test_create_with_preferences
+    assert_difference 'User.count' do
+      post :create,
+        :user => {
+          :firstname => 'John',
+          :lastname => 'Doe',
+          :login => 'jdoe',
+          :password => 'secret123',
+          :password_confirmation => 'secret123',
+          :mail => 'jdoe@gmail.com',
+          :mail_notification => 'none'
+        },
+        :pref => {
+          'hide_mail' => '1',
+          'time_zone' => 'Paris',
+          'comments_sorting' => 'desc',
+          'warn_on_leaving_unsaved' => '0'
+        }
+    end
+    user = User.first(:order => 'id DESC')
+    assert_equal 'jdoe', user.login
+    assert_equal true, user.pref.hide_mail
+    assert_equal 'Paris', user.pref.time_zone
+    assert_equal 'desc', user.pref[:comments_sorting]
+    assert_equal '0', user.pref[:warn_on_leaving_unsaved]
+  end
+
+  def test_create_with_failure
+    assert_no_difference 'User.count' do
+      post :create, :user => {}
+    end
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_edit
+    get :edit, :id => 2
+    assert_response :success
+    assert_template 'edit'
+    assert_equal User.find(2), assigns(:user)
+  end
+
+  def test_update
+    ActionMailer::Base.deliveries.clear
+    put :update, :id => 2,
+        :user => {:firstname => 'Changed', :mail_notification => 'only_assigned'},
+        :pref => {:hide_mail => '1', :comments_sorting => 'desc'}
+    user = User.find(2)
+    assert_equal 'Changed', user.firstname
+    assert_equal 'only_assigned', user.mail_notification
+    assert_equal true, user.pref[:hide_mail]
+    assert_equal 'desc', user.pref[:comments_sorting]
+    assert ActionMailer::Base.deliveries.empty?
+  end
+
+  def test_update_with_failure
+    assert_no_difference 'User.count' do
+      put :update, :id => 2, :user => {:firstname => ''}
+    end
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_update_with_group_ids_should_assign_groups
+    put :update, :id => 2, :user => {:group_ids => ['10']}
+    user = User.find(2)
+    assert_equal [10], user.group_ids
+  end
+
+  def test_update_with_activation_should_send_a_notification
+    u = User.new(:firstname => 'Foo', :lastname => 'Bar', :mail => 'foo.bar@somenet.foo', :language => 'fr')
+    u.login = 'foo'
+    u.status = User::STATUS_REGISTERED
+    u.save!
+    ActionMailer::Base.deliveries.clear
+    Setting.bcc_recipients = '1'
+
+    put :update, :id => u.id, :user => {:status => User::STATUS_ACTIVE}
+    assert u.reload.active?
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert_equal ['foo.bar@somenet.foo'], mail.bcc
+    assert_mail_body_match ll('fr', :notice_account_activated), mail
+  end
+
+  def test_update_with_password_change_should_send_a_notification
+    ActionMailer::Base.deliveries.clear
+    Setting.bcc_recipients = '1'
+
+    put :update, :id => 2, :user => {:password => 'newpass123', :password_confirmation => 'newpass123'}, :send_information => '1'
+    u = User.find(2)
+    assert u.check_password?('newpass123')
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert_equal [u.mail], mail.bcc
+    assert_mail_body_match 'newpass123', mail
+  end
+
+  def test_update_user_switchin_from_auth_source_to_password_authentication
+    # Configure as auth source
+    u = User.find(2)
+    u.auth_source = AuthSource.find(1)
+    u.save!
+
+    put :update, :id => u.id, :user => {:auth_source_id => '', :password => 'newpass123', :password_confirmation => 'newpass123'}
+
+    assert_equal nil, u.reload.auth_source
+    assert u.check_password?('newpass123')
+  end
+
+  def test_update_notified_project
+    get :edit, :id => 2
+    assert_response :success
+    assert_template 'edit'
+    u = User.find(2)
+    assert_equal [1, 2, 5], u.projects.collect{|p| p.id}.sort
+    assert_equal [1, 2, 5], u.notified_projects_ids.sort
+    assert_tag :tag => 'input',
+               :attributes => {
+                  :id    => 'notified_project_ids_',
+                  :value => 1,
+                }
+    assert_equal 'all', u.mail_notification
+    put :update, :id => 2,
+        :user => {
+           :mail_notification => 'selected',
+         },
+        :notified_project_ids => [1, 2]
+    u = User.find(2)
+    assert_equal 'selected', u.mail_notification
+    assert_equal [1, 2], u.notified_projects_ids.sort
+  end
+
+  def test_destroy
+    assert_difference 'User.count', -1 do
+      delete :destroy, :id => 2
+    end
+    assert_redirected_to '/users'
+    assert_nil User.find_by_id(2)
+  end
+
+  def test_destroy_should_be_denied_for_non_admin_users
+    @request.session[:user_id] = 3
+
+    assert_no_difference 'User.count' do
+      get :destroy, :id => 2
+    end
+    assert_response 403
+  end
+
+  def test_destroy_should_redirect_to_back_url_param
+    assert_difference 'User.count', -1 do
+      delete :destroy, :id => 2, :back_url => '/users?name=foo'
+    end
+    assert_redirected_to '/users?name=foo'
+  end
+
+  def test_create_membership
+    assert_difference 'Member.count' do
+      post :edit_membership, :id => 7, :membership => { :project_id => 3, :role_ids => [2]}
+    end
+    assert_redirected_to :action => 'edit', :id => '7', :tab => 'memberships'
+    member = Member.first(:order => 'id DESC')
+    assert_equal User.find(7), member.principal
+    assert_equal [2], member.role_ids
+    assert_equal 3, member.project_id
+  end
+
+  def test_create_membership_js_format
+    assert_difference 'Member.count' do
+      post :edit_membership, :id => 7, :membership => {:project_id => 3, :role_ids => [2]}, :format => 'js'
+      assert_response :success
+      assert_template 'edit_membership'
+      assert_equal 'text/javascript', response.content_type
+    end
+    member = Member.first(:order => 'id DESC')
+    assert_equal User.find(7), member.principal
+    assert_equal [2], member.role_ids
+    assert_equal 3, member.project_id
+    assert_include 'tab-content-memberships', response.body
+  end
+
+  def test_create_membership_js_format_with_failure
+    assert_no_difference 'Member.count' do
+      post :edit_membership, :id => 7, :membership => {:project_id => 3}, :format => 'js'
+      assert_response :success
+      assert_template 'edit_membership'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_include 'alert', response.body, "Alert message not sent"
+    assert_include 'Role can\\\'t be empty', response.body, "Error message not sent"
+  end
+
+  def test_update_membership
+    assert_no_difference 'Member.count' do
+      put :edit_membership, :id => 2, :membership_id => 1, :membership => { :role_ids => [2]}
+      assert_redirected_to :action => 'edit', :id => '2', :tab => 'memberships'
+    end
+    assert_equal [2], Member.find(1).role_ids
+  end
+
+  def test_update_membership_js_format
+    assert_no_difference 'Member.count' do
+      put :edit_membership, :id => 2, :membership_id => 1, :membership => {:role_ids => [2]}, :format => 'js'
+      assert_response :success
+      assert_template 'edit_membership'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_equal [2], Member.find(1).role_ids
+    assert_include 'tab-content-memberships', response.body
+  end
+
+  def test_destroy_membership
+    assert_difference 'Member.count', -1 do
+      delete :destroy_membership, :id => 2, :membership_id => 1
+    end
+    assert_redirected_to :action => 'edit', :id => '2', :tab => 'memberships'
+    assert_nil Member.find_by_id(1)
+  end
+
+  def test_destroy_membership_js_format
+    assert_difference 'Member.count', -1 do
+      delete :destroy_membership, :id => 2, :membership_id => 1, :format => 'js'
+      assert_response :success
+      assert_template 'destroy_membership'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_nil Member.find_by_id(1)
+    assert_include 'tab-content-memberships', response.body
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6a/6a60898740de505326813cfa3f1724d25fce3f5e.svn-base
--- a/.svn/pristine/6a/6a60898740de505326813cfa3f1724d25fce3f5e.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-<h2><%= link_to l(:label_custom_field_plural), :controller => 'custom_fields', :action => 'index' %>
-  &#187; <%= link_to l(@custom_field.type_name), :controller => 'custom_fields', :action => 'index', :tab => @custom_field.class.name %>
-  &#187; <%=h @custom_field.name %></h2>
-
-<% labelled_tabular_form_for :custom_field, @custom_field, :url => { :action => "edit", :id => @custom_field } do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6a/6a90c258580c8739754206289754513f15068486.svn-base
--- a/.svn/pristine/6a/6a90c258580c8739754206289754513f15068486.svn-base
+++ /dev/null
@@ -1,207 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'my_controller'
-
-# Re-raise errors caught by the controller.
-class MyController; def rescue_action(e) raise e end; end
-
-class MyControllerTest < ActionController::TestCase
-  fixtures :users, :user_preferences, :roles, :projects, :issues, :issue_statuses, :trackers, :enumerations, :custom_fields
-
-  def setup
-    @controller = MyController.new
-    @request    = ActionController::TestRequest.new
-    @request.session[:user_id] = 2
-    @response   = ActionController::TestResponse.new
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'page'
-  end
-
-  def test_page
-    get :page
-    assert_response :success
-    assert_template 'page'
-  end
-
-  def test_my_account_should_show_editable_custom_fields
-    get :account
-    assert_response :success
-    assert_template 'account'
-    assert_equal User.find(2), assigns(:user)
-
-    assert_tag :input, :attributes => { :name => 'user[custom_field_values][4]'}
-  end
-
-  def test_my_account_should_not_show_non_editable_custom_fields
-    UserCustomField.find(4).update_attribute :editable, false
-
-    get :account
-    assert_response :success
-    assert_template 'account'
-    assert_equal User.find(2), assigns(:user)
-
-    assert_no_tag :input, :attributes => { :name => 'user[custom_field_values][4]'}
-  end
-
-  def test_update_account
-    post :account,
-      :user => {
-        :firstname => "Joe",
-        :login => "root",
-        :admin => 1,
-        :group_ids => ['10'],
-        :custom_field_values => {"4" => "0100562500"}
-      }
-
-    assert_redirected_to '/my/account'
-    user = User.find(2)
-    assert_equal user, assigns(:user)
-    assert_equal "Joe", user.firstname
-    assert_equal "jsmith", user.login
-    assert_equal "0100562500", user.custom_value_for(4).value
-    # ignored
-    assert !user.admin?
-    assert user.groups.empty?
-  end
-
-  def test_change_password
-    get :password
-    assert_response :success
-    assert_template 'password'
-
-    # non matching password confirmation
-    post :password, :password => 'jsmith',
-                    :new_password => 'hello',
-                    :new_password_confirmation => 'hello2'
-    assert_response :success
-    assert_template 'password'
-    assert_tag :tag => "div", :attributes => { :class => "errorExplanation" }
-
-    # wrong password
-    post :password, :password => 'wrongpassword',
-                    :new_password => 'hello',
-                    :new_password_confirmation => 'hello'
-    assert_response :success
-    assert_template 'password'
-    assert_equal 'Wrong password', flash[:error]
-
-    # good password
-    post :password, :password => 'jsmith',
-                    :new_password => 'hello',
-                    :new_password_confirmation => 'hello'
-    assert_redirected_to '/my/account'
-    assert User.try_to_login('jsmith', 'hello')
-  end
-
-  def test_page_layout
-    get :page_layout
-    assert_response :success
-    assert_template 'page_layout'
-  end
-
-  def test_add_block
-    xhr :post, :add_block, :block => 'issuesreportedbyme'
-    assert_response :success
-    assert User.find(2).pref[:my_page_layout]['top'].include?('issuesreportedbyme')
-  end
-
-  def test_remove_block
-    xhr :post, :remove_block, :block => 'issuesassignedtome'
-    assert_response :success
-    assert !User.find(2).pref[:my_page_layout].values.flatten.include?('issuesassignedtome')
-  end
-
-  def test_order_blocks
-    xhr :post, :order_blocks, :group => 'left', 'list-left' => ['documents', 'calendar', 'latestnews']
-    assert_response :success
-    assert_equal ['documents', 'calendar', 'latestnews'], User.find(2).pref[:my_page_layout]['left']
-  end
-
-  context "POST to reset_rss_key" do
-    context "with an existing rss_token" do
-      setup do
-        @previous_token_value = User.find(2).rss_key # Will generate one if it's missing
-        post :reset_rss_key
-      end
-
-      should "destroy the existing token" do
-        assert_not_equal @previous_token_value, User.find(2).rss_key
-      end
-
-      should "create a new token" do
-        assert User.find(2).rss_token
-      end
-
-      should_set_the_flash_to /reset/
-      should_redirect_to('my account') {'/my/account' }
-    end
-
-    context "with no rss_token" do
-      setup do
-        assert_nil User.find(2).rss_token
-        post :reset_rss_key
-      end
-
-      should "create a new token" do
-        assert User.find(2).rss_token
-      end
-
-      should_set_the_flash_to /reset/
-      should_redirect_to('my account') {'/my/account' }
-    end
-  end
-
-  context "POST to reset_api_key" do
-    context "with an existing api_token" do
-      setup do
-        @previous_token_value = User.find(2).api_key # Will generate one if it's missing
-        post :reset_api_key
-      end
-
-      should "destroy the existing token" do
-        assert_not_equal @previous_token_value, User.find(2).api_key
-      end
-
-      should "create a new token" do
-        assert User.find(2).api_token
-      end
-
-      should_set_the_flash_to /reset/
-      should_redirect_to('my account') {'/my/account' }
-    end
-
-    context "with no api_token" do
-      setup do
-        assert_nil User.find(2).api_token
-        post :reset_api_key
-      end
-
-      should "create a new token" do
-        assert User.find(2).api_token
-      end
-
-      should_set_the_flash_to /reset/
-      should_redirect_to('my account') {'/my/account' }
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6a/6ad1a9c5c31bdf856fc5268290ebc1f7efdb0480.svn-base
--- /dev/null
+++ b/.svn/pristine/6a/6ad1a9c5c31bdf856fc5268290ebc1f7efdb0480.svn-base
@@ -0,0 +1,208 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Role < ActiveRecord::Base
+  # Custom coder for the permissions attribute that should be an
+  # array of symbols. Rails 3 uses Psych which can be *unbelievably*
+  # slow on some platforms (eg. mingw32).
+  class PermissionsAttributeCoder
+    def self.load(str)
+      str.to_s.scan(/:([a-z0-9_]+)/).flatten.map(&:to_sym)
+    end
+
+    def self.dump(value)
+      YAML.dump(value)
+    end
+  end
+
+  # Built-in roles
+  BUILTIN_NON_MEMBER = 1
+  BUILTIN_ANONYMOUS  = 2
+
+  ISSUES_VISIBILITY_OPTIONS = [
+    ['all', :label_issues_visibility_all],
+    ['default', :label_issues_visibility_public],
+    ['own', :label_issues_visibility_own]
+  ]
+
+  scope :sorted, lambda { order("#{table_name}.builtin ASC, #{table_name}.position ASC") }
+  scope :givable, lambda { order("#{table_name}.position ASC").where(:builtin => 0) }
+  scope :builtin, lambda { |*args|
+    compare = (args.first == true ? 'not' : '')
+    where("#{compare} builtin = 0")
+  }
+
+  before_destroy :check_deletable
+  has_many :workflow_rules, :dependent => :delete_all do
+    def copy(source_role)
+      WorkflowRule.copy(nil, source_role, nil, proxy_association.owner)
+    end
+  end
+
+  has_many :member_roles, :dependent => :destroy
+  has_many :members, :through => :member_roles
+  acts_as_list
+
+  serialize :permissions, ::Role::PermissionsAttributeCoder
+  attr_protected :builtin
+
+  validates_presence_of :name
+  validates_uniqueness_of :name
+  validates_length_of :name, :maximum => 30
+  validates_inclusion_of :issues_visibility,
+    :in => ISSUES_VISIBILITY_OPTIONS.collect(&:first),
+    :if => lambda {|role| role.respond_to?(:issues_visibility)}
+
+  # Copies attributes from another role, arg can be an id or a Role
+  def copy_from(arg, options={})
+    return unless arg.present?
+    role = arg.is_a?(Role) ? arg : Role.find_by_id(arg.to_s)
+    self.attributes = role.attributes.dup.except("id", "name", "position", "builtin", "permissions")
+    self.permissions = role.permissions.dup
+    self
+  end
+
+  def permissions=(perms)
+    perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms
+    write_attribute(:permissions, perms)
+  end
+
+  def add_permission!(*perms)
+    self.permissions = [] unless permissions.is_a?(Array)
+
+    permissions_will_change!
+    perms.each do |p|
+      p = p.to_sym
+      permissions << p unless permissions.include?(p)
+    end
+    save!
+  end
+
+  def remove_permission!(*perms)
+    return unless permissions.is_a?(Array)
+    permissions_will_change!
+    perms.each { |p| permissions.delete(p.to_sym) }
+    save!
+  end
+
+  # Returns true if the role has the given permission
+  def has_permission?(perm)
+    !permissions.nil? && permissions.include?(perm.to_sym)
+  end
+
+  def <=>(role)
+    if role
+      if builtin == role.builtin
+        position <=> role.position
+      else
+        builtin <=> role.builtin
+      end
+    else
+      -1
+    end
+  end
+
+  def to_s
+    name
+  end
+
+  def name
+    case builtin
+    when 1; l(:label_role_non_member, :default => read_attribute(:name))
+    when 2; l(:label_role_anonymous,  :default => read_attribute(:name))
+    else; read_attribute(:name)
+    end
+  end
+
+  # Return true if the role is a builtin role
+  def builtin?
+    self.builtin != 0
+  end
+
+  # Return true if the role is the anonymous role
+  def anonymous?
+    builtin == 2
+  end
+  
+  # Return true if the role is a project member role
+  def member?
+    !self.builtin?
+  end
+
+  # Return true if role is allowed to do the specified action
+  # action can be:
+  # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
+  # * a permission Symbol (eg. :edit_project)
+  def allowed_to?(action)
+    if action.is_a? Hash
+      allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
+    else
+      allowed_permissions.include? action
+    end
+  end
+
+  # Return all the permissions that can be given to the role
+  def setable_permissions
+    setable_permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions
+    setable_permissions -= Redmine::AccessControl.members_only_permissions if self.builtin == BUILTIN_NON_MEMBER
+    setable_permissions -= Redmine::AccessControl.loggedin_only_permissions if self.builtin == BUILTIN_ANONYMOUS
+    setable_permissions
+  end
+
+  # Find all the roles that can be given to a project member
+  def self.find_all_givable
+    Role.givable.all
+  end
+
+  # Return the builtin 'non member' role.  If the role doesn't exist,
+  # it will be created on the fly.
+  def self.non_member
+    find_or_create_system_role(BUILTIN_NON_MEMBER, 'Non member')
+  end
+
+  # Return the builtin 'anonymous' role.  If the role doesn't exist,
+  # it will be created on the fly.
+  def self.anonymous
+    find_or_create_system_role(BUILTIN_ANONYMOUS, 'Anonymous')
+  end
+
+private
+
+  def allowed_permissions
+    @allowed_permissions ||= permissions + Redmine::AccessControl.public_permissions.collect {|p| p.name}
+  end
+
+  def allowed_actions
+    @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
+  end
+
+  def check_deletable
+    raise "Can't delete role" if members.any?
+    raise "Can't delete builtin role" if builtin?
+  end
+
+  def self.find_or_create_system_role(builtin, name)
+    role = where(:builtin => builtin).first
+    if role.nil?
+      role = create(:name => name, :position => 0) do |r|
+        r.builtin = builtin
+      end
+      raise "Unable to create the #{name} role." if role.new_record?
+    end
+    role
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6a/6ae02e008b39a032972c4d067b7e08a8c9bd1a60.svn-base
--- a/.svn/pristine/6a/6ae02e008b39a032972c4d067b7e08a8c9bd1a60.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class PluginsTest < Test::Unit::TestCase
-  
-  def test_should_allow_access_to_plugins_by_strings_or_symbols
-    p = Engines.plugins["alpha_plugin"]
-    q = Engines.plugins[:alpha_plugin]
-    assert_kind_of Engines::Plugin, p
-    assert_equal p, q
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6a/6af6e8ac0e3a74e02bdf5cc6d1f6d7050cfd38b0.svn-base
--- a/.svn/pristine/6a/6af6e8ac0e3a74e02bdf5cc6d1f6d7050cfd38b0.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-
-namespace :db do
-  desc 'Encrypts SCM and LDAP passwords in the database.'
-  task :encrypt => :environment do
-    unless (Repository.encrypt_all(:password) && 
-      AuthSource.encrypt_all(:account_password))
-      raise "Some objects could not be saved after encryption, update was rollback'ed."
-    end
-  end
-  
-  desc 'Decrypts SCM and LDAP passwords in the database.'
-  task :decrypt => :environment do
-    unless (Repository.decrypt_all(:password) &&
-      AuthSource.decrypt_all(:account_password))
-      raise "Some objects could not be saved after decryption, update was rollback'ed."
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6b/6b2c4a778dca89a31620a55a65371a0aa4017062.svn-base
--- /dev/null
+++ b/.svn/pristine/6b/6b2c4a778dca89a31620a55a65371a0aa4017062.svn-base
@@ -0,0 +1,60 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingBoardsTest < ActionController::IntegrationTest
+  def test_boards
+    assert_routing(
+        { :method => 'get', :path => "/projects/world_domination/boards" },
+        { :controller => 'boards', :action => 'index', :project_id => 'world_domination' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/world_domination/boards/new" },
+        { :controller => 'boards', :action => 'new', :project_id => 'world_domination' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/world_domination/boards/44" },
+        { :controller => 'boards', :action => 'show', :project_id => 'world_domination',
+          :id => '44' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/world_domination/boards/44.atom" },
+        { :controller => 'boards', :action => 'show', :project_id => 'world_domination',
+          :id => '44', :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/world_domination/boards/44/edit" },
+        { :controller => 'boards', :action => 'edit', :project_id => 'world_domination',
+          :id => '44' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/world_domination/boards" },
+        { :controller => 'boards', :action => 'create', :project_id => 'world_domination' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/projects/world_domination/boards/44" },
+        { :controller => 'boards', :action => 'update', :project_id => 'world_domination',
+          :id => '44' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/projects/world_domination/boards/44" },
+        { :controller => 'boards', :action => 'destroy', :project_id => 'world_domination',
+          :id => '44' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6b/6b42e6adb8523e15e9ff195fc3496e5284a69b00.svn-base
--- /dev/null
+++ b/.svn/pristine/6b/6b42e6adb8523e15e9ff195fc3496e5284a69b00.svn-base
@@ -0,0 +1,33 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module ActivitiesHelper
+  def sort_activity_events(events)
+    events_by_group = events.group_by(&:event_group)
+    sorted_events = []
+    events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each do |event|
+      if group_events = events_by_group.delete(event.event_group)
+        group_events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each_with_index do |e, i|
+          sorted_events << [e, i > 0]
+        end
+      end
+    end
+    sorted_events
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6b/6b4c50390f939790cfd61f918f38b017e779b22e.svn-base
--- /dev/null
+++ b/.svn/pristine/6b/6b4c50390f939790cfd61f918f38b017e779b22e.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module TrackersHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6b/6b54a0eb8e943798ef2435d13b405e9ba04b4b70.svn-base
--- a/.svn/pristine/6b/6b54a0eb8e943798ef2435d13b405e9ba04b4b70.svn-base
+++ /dev/null
@@ -1,49 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2008  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class TrackerTest < ActiveSupport::TestCase
-  fixtures :trackers, :workflows, :issue_statuses, :roles
-
-  def test_copy_workflows
-    source = Tracker.find(1)
-    assert_equal 89, source.workflows.size
-
-    target = Tracker.new(:name => 'Target')
-    assert target.save
-    target.workflows.copy(source)
-    target.reload
-    assert_equal 89, target.workflows.size
-  end
-
-  def test_issue_statuses
-    tracker = Tracker.find(1)
-    Workflow.delete_all
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
-    Workflow.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
-
-    assert_kind_of Array, tracker.issue_statuses
-    assert_kind_of IssueStatus, tracker.issue_statuses.first
-    assert_equal [2, 3, 5], Tracker.find(1).issue_statuses.collect(&:id)
-  end
-
-  def test_issue_statuses_empty
-    Workflow.delete_all("tracker_id = 1")
-    assert_equal [], Tracker.find(1).issue_statuses
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6b/6b5b987c21a18cc797539b6f0cafd0fae162a091.svn-base
--- a/.svn/pristine/6b/6b5b987c21a18cc797539b6f0cafd0fae162a091.svn-base
+++ /dev/null
@@ -1,4 +0,0 @@
-<p><%= l(:mail_body_lost_password) %><br />
-<%= auto_link(@url) %></p>
-
-<p><%= l(:field_login) %>: <b><%=h @token.user.login %></b></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6b/6b825f96e86174ddd396f80166966bf671099ba1.svn-base
--- a/.svn/pristine/6b/6b825f96e86174ddd396f80166966bf671099ba1.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-ï»¿// ** I18N
-
-// Calendar HU language
-// Author: TakÃ¡cs GÃ¡bor
-// Encoding: UTF-8
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("VasÃ¡rnap",
- "HÃ©tfÅ‘",
- "Kedd",
- "Szerda",
- "CsÃ¼tÃ¶rtÃ¶k",
- "PÃ©ntek",
- "Szombat",
- "VasÃ¡rnap");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Vas",
- "HÃ©t",
- "Ked",
- "Sze",
- "CsÃ¼",
- "PÃ©n",
- "Szo",
- "Vas");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("JanuÃ¡r",
- "FebruÃ¡r",
- "MÃ¡rcius",
- "Ãprilis",
- "MÃ¡jus",
- "JÃºnius",
- "JÃºlius",
- "Augusztus",
- "Szeptember",
- "OktÃ³ber",
- "November",
- "December");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "MÃ¡r",
- "Ãpr",
- "MÃ¡j",
- "JÃºn",
- "JÃºl",
- "Aug",
- "Szep",
- "Okt",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "A naptÃ¡r leÃ­rÃ¡sa";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "ElÅ‘zÅ‘ Ã©v (nyomvatart = menÃ¼)";
-Calendar._TT["PREV_MONTH"] = "ElÅ‘zÅ‘ hÃ³nap (nyomvatart = menÃ¼)";
-Calendar._TT["GO_TODAY"] = "IrÃ¡ny a Ma";
-Calendar._TT["NEXT_MONTH"] = "KÃ¶vetkezÅ‘ hÃ³nap (nyomvatart = menÃ¼)";
-Calendar._TT["NEXT_YEAR"] = "KÃ¶vetkezÅ‘ Ã©v (nyomvatart = menÃ¼)";
-Calendar._TT["SEL_DATE"] = "VÃ¡lasszon dÃ¡tumot";
-Calendar._TT["DRAG_TO_MOVE"] = "Fogd Ã©s vidd";
-Calendar._TT["PART_TODAY"] = " (ma)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "%s megjelenÃ­tÃ©se elsÅ‘kÃ©nt";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "BezÃ¡r";
-Calendar._TT["TODAY"] = "Ma";
-Calendar._TT["TIME_PART"] = "(Shift-)Click vagy hÃºzd az Ã©rtÃ©k vÃ¡ltoztatÃ¡sÃ¡hoz";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y.%m.%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%B %e, %A";
-
-Calendar._TT["WK"] = "hÃ©t";
-Calendar._TT["TIME"] = "IdÅ‘:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6b/6b9da48548a1beb99525f99aa84dd3c7f5182449.svn-base
--- a/.svn/pristine/6b/6b9da48548a1beb99525f99aa84dd3c7f5182449.svn-base
+++ /dev/null
@@ -1,52 +0,0 @@
-<h3><%=l(:label_spent_time)%> (<%= l(:label_last_n_days, 7) %>)</h3>
-<%
-entries = TimeEntry.find(:all,
-        :conditions => ["#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", @user.id, Date.today - 6, Date.today],
-        :include => [:activity, :project, {:issue => [:tracker, :status]}],
-        :order => "#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC")
-entries_by_day = entries.group_by(&:spent_on)
-%>
-
-<div class="total-hours">
-<p><%= l(:label_total) %>: <%= html_hours("%.2f" % entries.sum(&:hours).to_f) %></p>
-</div>
-
-<% if entries.any? %>
-<table class="list time-entries">
-<thead><tr>
-<th><%= l(:label_activity) %></th>
-<th><%= l(:label_project) %></th>
-<th><%= l(:field_comments) %></th>
-<th><%= l(:field_hours) %></th>
-<th></th>
-</tr></thead>
-<tbody>
-<% entries_by_day.keys.sort.reverse.each do |day| %>
-    <tr class="odd">
-    <td><strong><%= day == Date.today ? l(:label_today).titleize : format_date(day) %></strong></td>
-    <td colspan="2"></td>
-    <td class="hours"><em><%= html_hours("%.2f" % entries_by_day[day].sum(&:hours).to_f) %></em></td>
-    <td></td>
-    </tr>
-    <% entries_by_day[day].each do |entry| -%>
-    <tr class="time-entry" style="border-bottom: 1px solid #f5f5f5;">
-    <td class="activity"><%=h entry.activity %></td>
-    <td class="subject"><%=h entry.project %> <%= ' - ' + link_to_issue(entry.issue, :truncate => 50) if entry.issue %></td>
-    <td class="comments"><%=h entry.comments %></td>
-    <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
-    <td align="center">
-    <% if entry.editable_by?(@user) -%>
-        <%= link_to image_tag('edit.png'), {:controller => 'timelog', :action => 'edit', :id => entry},
-                                           :title => l(:button_edit) %>
-        <%= link_to image_tag('delete.png'), {:controller => 'timelog', :action => 'destroy', :id => entry},
-                                             :confirm => l(:text_are_you_sure),
-                                             :method => :delete,
-                                             :title => l(:button_delete) %>
-    <% end -%>
-    </td>
-    </tr>
-    <% end -%>
-<% end -%>
-</tbody>
-</table>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6c/6c0616986104fa86ed47ef83a0066e97c4dd3dae.svn-base
--- a/.svn/pristine/6c/6c0616986104fa86ed47ef83a0066e97c4dd3dae.svn-base
+++ /dev/null
@@ -1,4 +0,0 @@
-<% labelled_form_for @group do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6c/6c1bc2cf6fdcda95eb68095dcabf8689b24d2903.svn-base
--- a/.svn/pristine/6c/6c1bc2cf6fdcda95eb68095dcabf8689b24d2903.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../test_helper', __FILE__)
-require 'iconv'
-
-class PdfTest < ActiveSupport::TestCase
-  fixtures :users, :projects, :roles, :members, :member_roles,
-           :enabled_modules, :issues, :trackers, :attachments
-
-  def test_fix_text_encoding_nil
-    assert_equal '', Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(nil, "UTF-8")
-    assert_equal '', Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(nil, "ISO-8859-1")
-  end
-
-  def test_rdm_pdf_iconv_cannot_convert_ja_cp932
-    encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" )
-    utf8_txt_1  = "\xe7\x8b\x80\xe6\x85\x8b"
-    utf8_txt_2  = "\xe7\x8b\x80\xe6\x85\x8b\xe7\x8b\x80"
-    utf8_txt_3  = "\xe7\x8b\x80\xe7\x8b\x80\xe6\x85\x8b\xe7\x8b\x80"
-    if utf8_txt_1.respond_to?(:force_encoding)
-      txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding)
-      txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding)
-      txt_3 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding)
-      assert_equal "?\x91\xd4", txt_1
-      assert_equal "?\x91\xd4?", txt_2
-      assert_equal "??\x91\xd4?", txt_3
-      assert_equal "ASCII-8BIT", txt_1.encoding.to_s
-      assert_equal "ASCII-8BIT", txt_2.encoding.to_s
-      assert_equal "ASCII-8BIT", txt_3.encoding.to_s
-    elsif RUBY_PLATFORM == 'java'
-      assert_equal "??",
-                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding)
-      assert_equal "???",
-                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding)
-      assert_equal "????",
-                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding)
-    else
-      assert_equal "???\x91\xd4",
-                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding)
-      assert_equal "???\x91\xd4???",
-                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding)
-      assert_equal "??????\x91\xd4???",
-                   Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding)
-    end
-  end
-
-  def test_rdm_pdf_iconv_invalid_utf8_should_be_replaced_en
-    str1 = "Texte encod\xe9 en ISO-8859-1"
-    str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test"
-    str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding)
-    str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding)
-    txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str1, 'UTF-8')
-    txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str2, 'UTF-8')
-    if txt_1.respond_to?(:force_encoding)
-      assert_equal "ASCII-8BIT", txt_1.encoding.to_s
-      assert_equal "ASCII-8BIT", txt_2.encoding.to_s
-    end
-    assert_equal "Texte encod? en ISO-8859-1", txt_1
-    assert_equal "?a?b?c?d?e test", txt_2
-  end
-
-  def test_rdm_pdf_iconv_invalid_utf8_should_be_replaced_ja
-    str1 = "Texte encod\xe9 en ISO-8859-1"
-    str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test"
-    str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding)
-    str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding)
-    encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" )
-    txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str1, encoding)
-    txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str2, encoding)
-    if txt_1.respond_to?(:force_encoding)
-      assert_equal "ASCII-8BIT", txt_1.encoding.to_s
-      assert_equal "ASCII-8BIT", txt_2.encoding.to_s
-    end
-    assert_equal "Texte encod? en ISO-8859-1", txt_1
-    assert_equal "?a?b?c?d?e test", txt_2
-  end
-
-  def test_attach
-    Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
-
-    str2 = "\x83e\x83X\x83g"
-    str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding)
-    encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" )
-
-    a1 = Attachment.find(17)
-    a2 = Attachment.find(19)
-
-    User.current = User.find(1)
-    assert a1.readable?
-    assert a1.visible?
-    assert a2.readable?
-    assert a2.visible?
-
-    aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8")
-    assert_equal 17, aa1.id
-    aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding)
-    assert_equal 19, aa2.id
-
-    User.current = nil
-    assert a1.readable?
-    assert (! a1.visible?)
-    assert a2.readable?
-    assert (! a2.visible?)
-
-    aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8")
-    assert_equal nil, aa1
-    aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding)
-    assert_equal nil, aa2
-
-    set_tmp_attachments_directory
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6c/6c5422ed0dce695a568f6fb2acde79357b8cbed3.svn-base
--- a/.svn/pristine/6c/6c5422ed0dce695a568f6fb2acde79357b8cbed3.svn-base
+++ /dev/null
@@ -1,110 +0,0 @@
-module ActiveRecord
-  module Acts
-    module Tree
-      def self.included(base)
-        base.extend(ClassMethods)
-      end
-
-      # Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children
-      # association. This requires that you have a foreign key column, which by default is called +parent_id+.
-      #
-      #   class Category < ActiveRecord::Base
-      #     acts_as_tree :order => "name"
-      #   end
-      #
-      #   Example:
-      #   root
-      #    \_ child1
-      #         \_ subchild1
-      #         \_ subchild2
-      #
-      #   root      = Category.create("name" => "root")
-      #   child1    = root.children.create("name" => "child1")
-      #   subchild1 = child1.children.create("name" => "subchild1")
-      #
-      #   root.parent   # => nil
-      #   child1.parent # => root
-      #   root.children # => [child1]
-      #   root.children.first.children.first # => subchild1
-      #
-      # In addition to the parent and children associations, the following instance methods are added to the class
-      # after calling <tt>acts_as_tree</tt>:
-      # * <tt>siblings</tt> - Returns all the children of the parent, excluding the current node (<tt>[subchild2]</tt> when called on <tt>subchild1</tt>)
-      # * <tt>self_and_siblings</tt> - Returns all the children of the parent, including the current node (<tt>[subchild1, subchild2]</tt> when called on <tt>subchild1</tt>)
-      # * <tt>ancestors</tt> - Returns all the ancestors of the current node (<tt>[child1, root]</tt> when called on <tt>subchild2</tt>)
-      # * <tt>root</tt> - Returns the root of the current node (<tt>root</tt> when called on <tt>subchild2</tt>)
-      module ClassMethods
-        # Configuration options are:
-        #
-        # * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
-        # * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
-        # * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
-        def acts_as_tree(options = {})
-          configuration = { :foreign_key => "parent_id", :dependent => :destroy, :order => nil, :counter_cache => nil }
-          configuration.update(options) if options.is_a?(Hash)
-
-          belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
-          has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => configuration[:dependent]
-
-          class_eval <<-EOV
-            include ActiveRecord::Acts::Tree::InstanceMethods
-
-            def self.roots
-              find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
-            end
-
-            def self.root
-              find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
-            end
-          EOV
-        end
-      end
-
-      module InstanceMethods
-        # Returns list of ancestors, starting from parent until root.
-        #
-        #   subchild1.ancestors # => [child1, root]
-        def ancestors
-          node, nodes = self, []
-          nodes << node = node.parent while node.parent
-          nodes
-        end
-
-        # Returns list of descendants.
-        #
-        #   root.descendants # => [child1, subchild1, subchild2]
-        def descendants
-          children + children.collect(&:children).flatten
-        end
-
-        # Returns list of descendants and a reference to the current node.
-        #
-        #   root.self_and_descendants # => [root, child1, subchild1, subchild2]
-        def self_and_descendants
-          [self] + descendants
-        end
-
-        # Returns the root node of the tree.
-        def root
-          node = self
-          node = node.parent while node.parent
-          node
-        end
-
-        # Returns all siblings of the current node.
-        #
-        #   subchild1.siblings # => [subchild2]
-        def siblings
-          self_and_siblings - [self]
-        end
-
-        # Returns all siblings and a reference to the current node.
-        #
-        #   subchild1.self_and_siblings # => [subchild1, subchild2]
-        def self_and_siblings
-          parent ? parent.children : self.class.roots
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6c/6cbb31787f87074f8260891401b8d0cb7419e27e.svn-base
--- a/.svn/pristine/6c/6cbb31787f87074f8260891401b8d0cb7419e27e.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class <%= class_name %>ControllerTest < ActionController::TestCase
-  # Replace this with your real tests.
-  def test_truth
-    assert true
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6c/6cd92c68c4e67170a380505918766fcdb88e0c8f.svn-base
--- /dev/null
+++ b/.svn/pristine/6c/6cd92c68c4e67170a380505918766fcdb88e0c8f.svn-base
@@ -0,0 +1,16 @@
+class CalendarAndActivity < ActiveRecord::Migration
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    Permission.create :controller => "projects", :action => "activity", :description => "label_activity", :sort => 160, :is_public => true, :mail_option => 0, :mail_enabled => 0
+    Permission.create :controller => "projects", :action => "calendar", :description => "label_calendar", :sort => 165, :is_public => true, :mail_option => 0, :mail_enabled => 0
+    Permission.create :controller => "projects", :action => "gantt", :description => "label_gantt", :sort => 166, :is_public => true, :mail_option => 0, :mail_enabled => 0
+  end
+
+  def self.down
+    Permission.where("controller=? and action=?", 'projects', 'activity').first.destroy
+    Permission.where("controller=? and action=?", 'projects', 'calendar').first.destroy
+    Permission.where("controller=? and action=?", 'projects', 'gantt').first.destroy
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6c/6cda2c2cd26c7545900827e5478deaa9348538cb.svn-base
--- a/.svn/pristine/6c/6cda2c2cd26c7545900827e5478deaa9348538cb.svn-base
+++ /dev/null
@@ -1,51 +0,0 @@
-<div class="contextual">
-<%= link_to(l(:button_change_password), {:action => 'password'}, :class => 'icon icon-passwd') if @user.change_password_allowed? %>
-<%= call_hook(:view_my_account_contextual, :user => @user)%>
-</div>
-
-<h2><%=l(:label_my_account)%></h2>
-<%= error_messages_for 'user' %>
-
-<% form_for :user, @user, :url => { :action => "account" },
-                          :builder => TabularFormBuilder,
-                          :lang => current_language,
-                          :html => { :id => 'my_account_form' } do |f| %>
-<div class="splitcontentleft">
-<fieldset class="box tabular">
-  <legend><%=l(:label_information_plural)%></legend>
-  <p><%= f.text_field :firstname, :required => true %></p>
-  <p><%= f.text_field :lastname, :required => true %></p>
-  <p><%= f.text_field :mail, :required => true %></p>
-  <p><%= f.select :language, lang_options_for_select %></p>
-  <% if Setting.openid? %>
-  <p><%= f.text_field :identity_url  %></p>
-  <% end %>
-
-  <% @user.custom_field_values.select(&:editable?).each do |value| %>
-    <p><%= custom_field_tag_with_label :user, value %></p>
-  <% end %>
-  <%= call_hook(:view_my_account, :user => @user, :form => f) %>
-</fieldset>
-
-<%= submit_tag l(:button_save) %>
-</div>
-
-<div class="splitcontentright">
-<fieldset class="box">
-  <legend><%=l(:field_mail_notification)%></legend>
-  <%= render :partial => 'users/mail_notifications' %>
-</fieldset>
-
-<fieldset class="box tabular">
-  <legend><%=l(:label_preferences)%></legend>
-  <%= render :partial => 'users/preferences' %>
-</fieldset>
-
-</div>
-<% end %>
-
-<% content_for :sidebar do %>
-<%= render :partial => 'sidebar' %>
-<% end %>
-
-<% html_title(l(:label_my_account)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6d/6d24a0dc5e3b6f9a7f6072591c406a9d6ee664eb.svn-base
--- a/.svn/pristine/6d/6d24a0dc5e3b6f9a7f6072591c406a9d6ee664eb.svn-base
+++ /dev/null
@@ -1,26 +0,0 @@
-# Tests in this file ensure that:
-#
-# * translations in the application take precedence over those in plugins
-# * translations in subsequently loaded plugins take precendence over those in previously loaded plugins
-
-require File.dirname(__FILE__) + '/../test_helper'
-
-class LocaleLoadingTest < ActionController::TestCase
-  def setup
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-  end
-
-  # app takes precedence over plugins
-	
-  def test_WITH_a_translation_defined_in_both_app_and_plugin_IT_should_find_the_one_in_app
-    assert_equal I18n.t('hello'), 'Hello world'
-  end
-	
-  # subsequently loaded plugins take precendence over previously loaded plugins
-	
-  def test_WITH_a_translation_defined_in_two_plugins_IT_should_find_the_latter_of_both
-    assert_equal I18n.t('plugin'), 'beta'
-  end
-end
-	
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6d/6d3caa4ed6a43a4bdaff9ded0c658d9c377a52de.svn-base
--- a/.svn/pristine/6d/6d3caa4ed6a43a4bdaff9ded0c658d9c377a52de.svn-base
+++ /dev/null
@@ -1,2 +0,0 @@
-# English strings go here
-my_label: "My label"
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6d/6d3d8dfed27856a76e41a252f404513d7b64d5b0.svn-base
--- /dev/null
+++ b/.svn/pristine/6d/6d3d8dfed27856a76e41a252f404513d7b64d5b0.svn-base
@@ -0,0 +1,12 @@
+
+require File.expand_path(File.dirname(__FILE__) + '../../../../../test/test_helper')
+
+class SamplePluginRoutingTest < ActionDispatch::IntegrationTest
+  def test_example
+    assert_routing(
+        { :method => 'get', :path => "/projects/1234/hello" },
+        { :controller => 'example', :action => 'say_hello',
+          :id => '1234' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6d/6d3df7e3002585d4b82d0225bf30bfb49566483a.svn-base
--- /dev/null
+++ b/.svn/pristine/6d/6d3df7e3002585d4b82d0225bf30bfb49566483a.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module NewsHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6d/6d7a886110aeab37816e5215a40006734bda0844.svn-base
--- /dev/null
+++ b/.svn/pristine/6d/6d7a886110aeab37816e5215a40006734bda0844.svn-base
@@ -0,0 +1,13 @@
+class AddViewWikiEditsPermission < ActiveRecord::Migration
+  def self.up
+    Role.all.each do |r|
+      r.add_permission!(:view_wiki_edits) if r.has_permission?(:view_wiki_pages)
+    end
+  end
+
+  def self.down
+    Role.all.each do |r|
+      r.remove_permission!(:view_wiki_edits)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6d/6d7d58f8eaab5d307f2462af49611d6e47d8e3a9.svn-base
Binary file .svn/pristine/6d/6d7d58f8eaab5d307f2462af49611d6e47d8e3a9.svn-base has changed
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6d/6dbc9c710fb965b8c65653004923b7333ec3b49d.svn-base
--- a/.svn/pristine/6d/6dbc9c710fb965b8c65653004923b7333ec3b49d.svn-base
+++ /dev/null
@@ -1,20 +0,0 @@
-Gem::Specification.new do |s|
-  s.name = "awesome_nested_set"
-  s.version = "1.1.1"
-  s.summary = "An awesome replacement for acts_as_nested_set and better_nested_set."
-  s.description = s.summary
- 
-  s.files = %w(init.rb MIT-LICENSE Rakefile README.rdoc lib/awesome_nested_set.rb lib/awesome_nested_set/compatability.rb lib/awesome_nested_set/helper.rb lib/awesome_nested_set/named_scope.rb rails/init.rb test/awesome_nested_set_test.rb test/test_helper.rb test/awesome_nested_set/helper_test.rb test/db/database.yml test/db/schema.rb test/fixtures/categories.yml test/fixtures/category.rb test/fixtures/departments.yml test/fixtures/notes.yml)
- 
-  s.add_dependency "activerecord", ['>= 1.1']
- 
-  s.has_rdoc = true
-  s.extra_rdoc_files = [ "README.rdoc"]
-  s.rdoc_options = ["--main", "README.rdoc", "--inline-source", "--line-numbers"]
- 
-  s.test_files = %w(test/awesome_nested_set_test.rb test/test_helper.rb test/awesome_nested_set/helper_test.rb test/db/database.yml test/db/schema.rb test/fixtures/categories.yml test/fixtures/category.rb test/fixtures/departments.yml test/fixtures/notes.yml)
-  s.require_path = 'lib'
-  s.author = "Collective Idea"
-  s.email = "info@collectiveidea.com"
-  s.homepage = "http://collectiveidea.com"
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6d/6dcc3a263131f2160989fed213e79d95e99859f8.svn-base
--- a/.svn/pristine/6d/6dcc3a263131f2160989fed213e79d95e99859f8.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("æ˜ŸæœŸæ—¥",
- "æ˜ŸæœŸä¸€",
- "æ˜ŸæœŸäºŒ",
- "æ˜ŸæœŸä¸‰",
- "æ˜ŸæœŸå››",
- "æ˜ŸæœŸäº”",
- "æ˜ŸæœŸå…­",
- "æ˜ŸæœŸæ—¥");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("æ—¥",
- "ä¸€",
- "äºŒ",
- "ä¸‰",
- "å››",
- "äº”",
- "å…­",
- "æ—¥");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("ä¸€æœˆ",
- "äºŒæœˆ",
- "ä¸‰æœˆ",
- "å››æœˆ",
- "äº”æœˆ",
- "å…­æœˆ",
- "ä¸ƒæœˆ",
- "å…«æœˆ",
- "ä¹æœˆ",
- "åæœˆ",
- "åä¸€æœˆ",
- "åäºŒæœˆ");
-
-// short month names
-Calendar._SMN = new Array
-("ä¸€æœˆ",
- "äºŒæœˆ",
- "ä¸‰æœˆ",
- "å››æœˆ",
- "äº”æœˆ",
- "å…­æœˆ",
- "ä¸ƒæœˆ",
- "å…«æœˆ",
- "ä¹æœˆ",
- "åæœˆ",
- "åä¸€æœˆ",
- "åäºŒæœˆ");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "é—œæ–¼ calendar";
-
-Calendar._TT["ABOUT"] =
-"DHTML æ—¥æœŸ/æ™‚é–“ é¸æ“‡å™¨\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"æœ€æ–°ç‰ˆæœ¬å–å¾—ä½å€: http://www.dynarch.com/projects/calendar/\n" +
-"ä½¿ç”¨ GNU LGPL ç™¼è¡Œ.  åƒè€ƒ http://gnu.org/licenses/lgpl.html ä»¥å–å¾—æ›´å¤šé—œæ–¼ LGPL ä¹‹ç´°ç¯€ã€‚" +
-"\n\n" +
-"æ—¥æœŸé¸æ“‡æ–¹å¼:\n" +
-"- ä½¿ç”¨æ»‘é¼ é»žæ“Š \xab ã€ \xbb æŒ‰éˆ•é¸æ“‡å¹´ä»½\n" +
-"- ä½¿ç”¨æ»‘é¼ é»žæ“Š " + String.fromCharCode(0x2039) + " ã€ " + String.fromCharCode(0x203a) + " æŒ‰éˆ•é¸æ“‡æœˆä»½\n" +
-"- ä½¿ç”¨æ»‘é¼ é»žæ“Šä¸Šè¿°æŒ‰éˆ•ä¸¦æŒ‰ä½ä¸æ”¾ï¼Œå¯é–‹å•Ÿå¿«é€Ÿé¸å–®ã€‚";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"æ™‚é–“é¸æ“‡æ–¹å¼ï¼š\n" +
-"- ã€Œå–®æ“Šã€æ™‚åˆ†ç§’ç‚ºéžå¢ž\n" +
-"- æˆ– ã€ŒShift-å–®æ“Šã€ç‚ºéžæ¸›\n" +
-"- æˆ– ã€Œå–®æ“Šä¸”æ‹–æ‹‰ã€ç‚ºå¿«é€Ÿé¸æ“‡";
-
-Calendar._TT["PREV_YEAR"] = "å‰ä¸€å¹´ (æŒ‰ä½ä¸æ”¾å¯é¡¯ç¤ºé¸å–®)";
-Calendar._TT["PREV_MONTH"] = "å‰ä¸€å€‹æœˆ (æŒ‰ä½ä¸æ”¾å¯é¡¯ç¤ºé¸å–®)";
-Calendar._TT["GO_TODAY"] = "é¸æ“‡ä»Šå¤©";
-Calendar._TT["NEXT_MONTH"] = "å¾Œä¸€å€‹æœˆ (æŒ‰ä½ä¸æ”¾å¯é¡¯ç¤ºé¸å–®)";
-Calendar._TT["NEXT_YEAR"] = "ä¸‹ä¸€å¹´ (æŒ‰ä½ä¸æ”¾å¯é¡¯å¼é¸å–®)";
-Calendar._TT["SEL_DATE"] = "è«‹é»žé¸æ—¥æœŸ";
-Calendar._TT["DRAG_TO_MOVE"] = "æŒ‰ä½ä¸æ”¾å¯æ‹–æ‹‰è¦–çª—";
-Calendar._TT["PART_TODAY"] = " (ä»Šå¤©)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "ä»¥ %s åšç‚ºä¸€é€±çš„é¦–æ—¥";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "é—œé–‰è¦–çª—";
-Calendar._TT["TODAY"] = "ä»Šå¤©";
-Calendar._TT["TIME_PART"] = "(Shift-)åŠ ã€Œå–®æ“Šã€æˆ–ã€Œæ‹–æ‹‰ã€å¯è®Šæ›´å€¼";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "æ˜ŸæœŸ %a, %b %e æ—¥";
-
-Calendar._TT["WK"] = "é€±";
-Calendar._TT["TIME"] = "æ™‚é–“:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6d/6df92bac55b1c152d6b305930ebfee76752ffbdb.svn-base
--- /dev/null
+++ b/.svn/pristine/6d/6df92bac55b1c152d6b305930ebfee76752ffbdb.svn-base
@@ -0,0 +1,90 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::RolesTest < Redmine::ApiTest::Base
+  fixtures :roles
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "/roles" do
+    context "GET" do
+      context "xml" do
+        should "return the roles" do
+          get '/roles.xml'
+
+          assert_response :success
+          assert_equal 'application/xml', @response.content_type
+          assert_equal 3, assigns(:roles).size
+
+          assert_tag :tag => 'roles',
+            :attributes => {:type => 'array'},
+            :child => {
+              :tag => 'role',
+              :child => {
+                :tag => 'id',
+                :content => '2',
+                :sibling => {
+                  :tag => 'name',
+                  :content => 'Developer'
+                }
+              }
+            }
+        end
+      end
+
+      context "json" do
+        should "return the roles" do
+          get '/roles.json'
+
+          assert_response :success
+          assert_equal 'application/json', @response.content_type
+          assert_equal 3, assigns(:roles).size
+
+          json = ActiveSupport::JSON.decode(response.body)
+          assert_kind_of Hash, json
+          assert_kind_of Array, json['roles']
+          assert_include({'id' => 2, 'name' => 'Developer'}, json['roles'])
+        end
+      end
+    end
+  end
+
+  context "/roles/:id" do
+    context "GET" do
+      context "xml" do
+        should "return the role" do
+          get '/roles/1.xml'
+
+          assert_response :success
+          assert_equal 'application/xml', @response.content_type
+
+          assert_select 'role' do
+            assert_select 'name', :text => 'Manager'
+            assert_select 'role permissions[type=array]' do
+              assert_select 'permission', Role.find(1).permissions.size
+              assert_select 'permission', :text => 'view_issues'
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6e/6e054c706d00d186090b4624c3e7d460d0636103.svn-base
--- a/.svn/pristine/6e/6e054c706d00d186090b4624c3e7d460d0636103.svn-base
+++ /dev/null
@@ -1,168 +0,0 @@
-module CodeRay
-module Scanners
-  
-  load :ruby
-  load :html
-  load :java_script
-  
-  class HAML < Scanner
-    
-    register_for :haml
-    title 'HAML Template'
-    
-    KINDS_NOT_LOC = HTML::KINDS_NOT_LOC
-    
-  protected
-    
-    def setup
-      super
-      @ruby_scanner          = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true
-      @embedded_ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true, :state => @ruby_scanner.interpreted_string_state
-      @html_scanner          = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true
-    end
-    
-    def scan_tokens encoder, options
-      
-      match = nil
-      code = ''
-      
-      until eos?
-        
-        if bol?
-          if match = scan(/!!!.*/)
-            encoder.text_token match, :doctype
-            next
-          end
-          
-          if match = scan(/(?>( *)(\/(?!\[if)|-\#|:javascript|:ruby|:\w+) *)(?=\n)/)
-            encoder.text_token match, :comment
-            
-            code = self[2]
-            if match = scan(/(?:\n+#{self[1]} .*)+/)
-              case code
-              when '/', '-#'
-                encoder.text_token match, :comment
-              when ':javascript'
-                # TODO: recognize #{...} snippets inside JavaScript
-                @java_script_scanner ||= CodeRay.scanner :java_script, :tokens => @tokens, :keep_tokens => true
-                @java_script_scanner.tokenize match, :tokens => encoder
-              when ':ruby'
-                @ruby_scanner.tokenize match, :tokens => encoder
-              when /:\w+/
-                encoder.text_token match, :comment
-              else
-                raise 'else-case reached: %p' % [code]
-              end
-            end
-          end
-          
-          if match = scan(/ +/)
-            encoder.text_token match, :space
-          end
-          
-          if match = scan(/\/.*/)
-            encoder.text_token match, :comment
-            next
-          end
-          
-          if match = scan(/\\/)
-            encoder.text_token match, :plain
-            if match = scan(/.+/)
-              @html_scanner.tokenize match, :tokens => encoder
-            end
-            next
-          end
-          
-          tag = false
-          
-          if match = scan(/%[\w:]+\/?/)
-            encoder.text_token match, :tag
-            # if match = scan(/( +)(.+)/)
-            #   encoder.text_token self[1], :space
-            #   @embedded_ruby_scanner.tokenize self[2], :tokens => encoder
-            # end
-            tag = true
-          end
-          
-          while match = scan(/([.#])[-\w]*\w/)
-            encoder.text_token match, self[1] == '#' ? :constant : :class
-            tag = true
-          end
-          
-          if tag && match = scan(/(\()([^)]+)?(\))?/)
-            # TODO: recognize title=@title, class="widget_#{@widget.number}"
-            encoder.text_token self[1], :plain
-            @html_scanner.tokenize self[2], :tokens => encoder, :state => :attribute if self[2]
-            encoder.text_token self[3], :plain if self[3]
-          end
-          
-          if tag && match = scan(/\{/)
-            encoder.text_token match, :plain
-            
-            code = ''
-            level = 1
-            while true
-              code << scan(/([^\{\},\n]|, *\n?)*/)
-              case match = getch
-              when '{'
-                level += 1
-                code << match
-              when '}'
-                level -= 1
-                if level > 0
-                  code << match
-                else
-                  break
-                end
-              when "\n", ",", nil
-                break
-              end
-            end
-            @ruby_scanner.tokenize code, :tokens => encoder unless code.empty?
-            
-            encoder.text_token match, :plain if match
-          end
-          
-          if tag && match = scan(/(\[)([^\]\n]+)?(\])?/)
-            encoder.text_token self[1], :plain
-            @ruby_scanner.tokenize self[2], :tokens => encoder if self[2]
-            encoder.text_token self[3], :plain if self[3]
-          end
-          
-          if tag && match = scan(/\//)
-            encoder.text_token match, :tag
-          end
-          
-          if scan(/(>?<?[-=]|[&!]=|(& |!)|~)( *)([^,\n\|]+(?:(, *|\|(?=.|\n.*\|$))\n?[^,\n\|]*)*)?/)
-            encoder.text_token self[1] + self[3], :plain
-            if self[4]
-              if self[2]
-                @embedded_ruby_scanner.tokenize self[4], :tokens => encoder
-              else
-                @ruby_scanner.tokenize self[4], :tokens => encoder
-              end
-            end
-          elsif match = scan(/((?:<|><?)(?![!?\/\w]))?(.+)?/)
-            encoder.text_token self[1], :plain if self[1]
-            # TODO: recognize #{...} snippets
-            @html_scanner.tokenize self[2], :tokens => encoder if self[2]
-          end
-          
-        elsif match = scan(/.+/)
-          @html_scanner.tokenize match, :tokens => encoder
-          
-        end
-        
-        if match = scan(/\n/)
-          encoder.text_token match, :space
-        end
-      end
-      
-      encoder
-      
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6e/6e0ffe833f69aa1e063e889d3d2d973e8870aa17.svn-base
--- /dev/null
+++ b/.svn/pristine/6e/6e0ffe833f69aa1e063e889d3d2d973e8870aa17.svn-base
@@ -0,0 +1,11 @@
+<h3><%=l(:label_watched_issues)%> (<%= Issue.visible.watched_by(user.id).count %>)</h3>
+<% watched_issues = issueswatched_items %>
+
+<%= render :partial => 'issues/list_simple', :locals => { :issues => watched_issues } %>
+<% if watched_issues.length > 0 %>
+<p class="small"><%= link_to l(:label_issue_view_all), :controller => 'issues',
+                                                       :action => 'index',
+                                                       :set_filter => 1,
+                                                       :watcher_id => 'me',
+                                                       :sort => 'updated_on:desc' %></p>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6e/6e2879c545234404374d4007620d9c471722b1c4.svn-base
--- a/.svn/pristine/6e/6e2879c545234404374d4007620d9c471722b1c4.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= principals_check_box_tags 'member[user_ids][]', @principals %>
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6e/6e3338f454d707517019dd9e77ecbfdcf1570d99.svn-base
--- /dev/null
+++ b/.svn/pristine/6e/6e3338f454d707517019dd9e77ecbfdcf1570d99.svn-base
@@ -0,0 +1,355 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class CustomField < ActiveRecord::Base
+  include Redmine::SubclassFactory
+
+  has_many :custom_values, :dependent => :delete_all
+  acts_as_list :scope => 'type = \'#{self.class}\''
+  serialize :possible_values
+
+  validates_presence_of :name, :field_format
+  validates_uniqueness_of :name, :scope => :type
+  validates_length_of :name, :maximum => 30
+  validates_inclusion_of :field_format, :in => Redmine::CustomFieldFormat.available_formats
+
+  validate :validate_custom_field
+  before_validation :set_searchable
+  after_save :handle_multiplicity_change
+
+  scope :sorted, lambda { order("#{table_name}.position ASC") }
+
+  CUSTOM_FIELDS_TABS = [
+    {:name => 'IssueCustomField', :partial => 'custom_fields/index',
+     :label => :label_issue_plural},
+    {:name => 'TimeEntryCustomField', :partial => 'custom_fields/index',
+     :label => :label_spent_time},
+    {:name => 'ProjectCustomField', :partial => 'custom_fields/index',
+     :label => :label_project_plural},
+    {:name => 'VersionCustomField', :partial => 'custom_fields/index',
+     :label => :label_version_plural},
+    {:name => 'UserCustomField', :partial => 'custom_fields/index',
+     :label => :label_user_plural},
+    {:name => 'GroupCustomField', :partial => 'custom_fields/index',
+     :label => :label_group_plural},
+    {:name => 'TimeEntryActivityCustomField', :partial => 'custom_fields/index',
+     :label => TimeEntryActivity::OptionName},
+    {:name => 'IssuePriorityCustomField', :partial => 'custom_fields/index',
+     :label => IssuePriority::OptionName},
+    {:name => 'DocumentCategoryCustomField', :partial => 'custom_fields/index',
+     :label => DocumentCategory::OptionName}
+  ]
+
+  CUSTOM_FIELDS_NAMES = CUSTOM_FIELDS_TABS.collect{|v| v[:name]}
+
+  def field_format=(arg)
+    # cannot change format of a saved custom field
+    super if new_record?
+  end
+
+  def set_searchable
+    # make sure these fields are not searchable
+    self.searchable = false if %w(int float date bool).include?(field_format)
+    # make sure only these fields can have multiple values
+    self.multiple = false unless %w(list user version).include?(field_format)
+    true
+  end
+
+  def validate_custom_field
+    if self.field_format == "list"
+      errors.add(:possible_values, :blank) if self.possible_values.nil? || self.possible_values.empty?
+      errors.add(:possible_values, :invalid) unless self.possible_values.is_a? Array
+    end
+
+    if regexp.present?
+      begin
+        Regexp.new(regexp)
+      rescue
+        errors.add(:regexp, :invalid)
+      end
+    end
+
+    if default_value.present? && !valid_field_value?(default_value)
+      errors.add(:default_value, :invalid)
+    end
+  end
+
+  def possible_values_options(obj=nil)
+    case field_format
+    when 'user', 'version'
+      if obj.respond_to?(:project) && obj.project
+        case field_format
+        when 'user'
+          obj.project.users.sort.collect {|u| [u.to_s, u.id.to_s]}
+        when 'version'
+          obj.project.shared_versions.sort.collect {|u| [u.to_s, u.id.to_s]}
+        end
+      elsif obj.is_a?(Array)
+        obj.collect {|o| possible_values_options(o)}.reduce(:&)
+      else
+        []
+      end
+    when 'bool'
+      [[l(:general_text_Yes), '1'], [l(:general_text_No), '0']]
+    else
+      possible_values || []
+    end
+  end
+
+  def possible_values(obj=nil)
+    case field_format
+    when 'user', 'version'
+      possible_values_options(obj).collect(&:last)
+    when 'bool'
+      ['1', '0']
+    else
+      values = super()
+      if values.is_a?(Array)
+        values.each do |value|
+          value.force_encoding('UTF-8') if value.respond_to?(:force_encoding)
+        end
+      end
+      values || []
+    end
+  end
+
+  # Makes possible_values accept a multiline string
+  def possible_values=(arg)
+    if arg.is_a?(Array)
+      super(arg.compact.collect(&:strip).select {|v| !v.blank?})
+    else
+      self.possible_values = arg.to_s.split(/[\n\r]+/)
+    end
+  end
+
+  def cast_value(value)
+    casted = nil
+    unless value.blank?
+      case field_format
+      when 'string', 'text', 'list'
+        casted = value
+      when 'date'
+        casted = begin; value.to_date; rescue; nil end
+      when 'bool'
+        casted = (value == '1' ? true : false)
+      when 'int'
+        casted = value.to_i
+      when 'float'
+        casted = value.to_f
+      when 'user', 'version'
+        casted = (value.blank? ? nil : field_format.classify.constantize.find_by_id(value.to_i))
+      end
+    end
+    casted
+  end
+
+  def value_from_keyword(keyword, customized)
+    possible_values_options = possible_values_options(customized)
+    if possible_values_options.present?
+      keyword = keyword.to_s.downcase
+      if v = possible_values_options.detect {|text, id| text.downcase == keyword}
+        if v.is_a?(Array)
+          v.last
+        else
+          v
+        end
+      end
+    else
+      keyword
+    end
+  end
+
+  # Returns a ORDER BY clause that can used to sort customized
+  # objects by their value of the custom field.
+  # Returns nil if the custom field can not be used for sorting.
+  def order_statement
+    return nil if multiple?
+    case field_format
+      when 'string', 'text', 'list', 'date', 'bool'
+        # COALESCE is here to make sure that blank and NULL values are sorted equally
+        "COALESCE(#{join_alias}.value, '')"
+      when 'int', 'float'
+        # Make the database cast values into numeric
+        # Postgresql will raise an error if a value can not be casted!
+        # CustomValue validations should ensure that it doesn't occur
+        "CAST(CASE #{join_alias}.value WHEN '' THEN '0' ELSE #{join_alias}.value END AS decimal(30,3))"
+      when 'user', 'version'
+        value_class.fields_for_order_statement(value_join_alias)
+      else
+        nil
+    end
+  end
+
+  # Returns a GROUP BY clause that can used to group by custom value
+  # Returns nil if the custom field can not be used for grouping.
+  def group_statement
+    return nil if multiple?
+    case field_format
+      when 'list', 'date', 'bool', 'int'
+        order_statement
+      when 'user', 'version'
+        "COALESCE(#{join_alias}.value, '')"
+      else
+        nil
+    end
+  end
+
+  def join_for_order_statement
+    case field_format
+      when 'user', 'version'
+        "LEFT OUTER JOIN #{CustomValue.table_name} #{join_alias}" +
+          " ON #{join_alias}.customized_type = '#{self.class.customized_class.base_class.name}'" +
+          " AND #{join_alias}.customized_id = #{self.class.customized_class.table_name}.id" +
+          " AND #{join_alias}.custom_field_id = #{id}" +
+          " AND #{join_alias}.value <> ''" +
+          " AND #{join_alias}.id = (SELECT max(#{join_alias}_2.id) FROM #{CustomValue.table_name} #{join_alias}_2" +
+            " WHERE #{join_alias}_2.customized_type = #{join_alias}.customized_type" +
+            " AND #{join_alias}_2.customized_id = #{join_alias}.customized_id" +
+            " AND #{join_alias}_2.custom_field_id = #{join_alias}.custom_field_id)" +
+          " LEFT OUTER JOIN #{value_class.table_name} #{value_join_alias}" +
+          " ON CAST(CASE #{join_alias}.value WHEN '' THEN '0' ELSE #{join_alias}.value END AS decimal(30,0)) = #{value_join_alias}.id"
+      when 'int', 'float'
+        "LEFT OUTER JOIN #{CustomValue.table_name} #{join_alias}" +
+          " ON #{join_alias}.customized_type = '#{self.class.customized_class.base_class.name}'" +
+          " AND #{join_alias}.customized_id = #{self.class.customized_class.table_name}.id" +
+          " AND #{join_alias}.custom_field_id = #{id}" +
+          " AND #{join_alias}.value <> ''" +
+          " AND #{join_alias}.id = (SELECT max(#{join_alias}_2.id) FROM #{CustomValue.table_name} #{join_alias}_2" +
+            " WHERE #{join_alias}_2.customized_type = #{join_alias}.customized_type" +
+            " AND #{join_alias}_2.customized_id = #{join_alias}.customized_id" +
+            " AND #{join_alias}_2.custom_field_id = #{join_alias}.custom_field_id)"
+      when 'string', 'text', 'list', 'date', 'bool'
+        "LEFT OUTER JOIN #{CustomValue.table_name} #{join_alias}" +
+          " ON #{join_alias}.customized_type = '#{self.class.customized_class.base_class.name}'" +
+          " AND #{join_alias}.customized_id = #{self.class.customized_class.table_name}.id" +
+          " AND #{join_alias}.custom_field_id = #{id}" +
+          " AND #{join_alias}.id = (SELECT max(#{join_alias}_2.id) FROM #{CustomValue.table_name} #{join_alias}_2" +
+            " WHERE #{join_alias}_2.customized_type = #{join_alias}.customized_type" +
+            " AND #{join_alias}_2.customized_id = #{join_alias}.customized_id" +
+            " AND #{join_alias}_2.custom_field_id = #{join_alias}.custom_field_id)"
+      else
+        nil
+    end
+  end
+
+  def join_alias
+    "cf_#{id}"
+  end
+
+  def value_join_alias
+    join_alias + "_" + field_format
+  end
+
+  def <=>(field)
+    position <=> field.position
+  end
+
+  # Returns the class that values represent
+  def value_class
+    case field_format
+      when 'user', 'version'
+        field_format.classify.constantize
+      else
+        nil
+    end
+  end
+
+  def self.customized_class
+    self.name =~ /^(.+)CustomField$/
+    begin; $1.constantize; rescue nil; end
+  end
+
+  # to move in project_custom_field
+  def self.for_all
+    where(:is_for_all => true).order('position').all
+  end
+
+  def type_name
+    nil
+  end
+
+  # Returns the error messages for the given value
+  # or an empty array if value is a valid value for the custom field
+  def validate_field_value(value)
+    errs = []
+    if value.is_a?(Array)
+      if !multiple?
+        errs << ::I18n.t('activerecord.errors.messages.invalid')
+      end
+      if is_required? && value.detect(&:present?).nil?
+        errs << ::I18n.t('activerecord.errors.messages.blank')
+      end
+      value.each {|v| errs += validate_field_value_format(v)}
+    else
+      if is_required? && value.blank?
+        errs << ::I18n.t('activerecord.errors.messages.blank')
+      end
+      errs += validate_field_value_format(value)
+    end
+    errs
+  end
+
+  # Returns true if value is a valid value for the custom field
+  def valid_field_value?(value)
+    validate_field_value(value).empty?
+  end
+
+  def format_in?(*args)
+    args.include?(field_format)
+  end
+
+  protected
+
+  # Returns the error message for the given value regarding its format
+  def validate_field_value_format(value)
+    errs = []
+    if value.present?
+      errs << ::I18n.t('activerecord.errors.messages.invalid') unless regexp.blank? or value =~ Regexp.new(regexp)
+      errs << ::I18n.t('activerecord.errors.messages.too_short', :count => min_length) if min_length > 0 and value.length < min_length
+      errs << ::I18n.t('activerecord.errors.messages.too_long', :count => max_length) if max_length > 0 and value.length > max_length
+
+      # Format specific validations
+      case field_format
+      when 'int'
+        errs << ::I18n.t('activerecord.errors.messages.not_a_number') unless value =~ /^[+-]?\d+$/
+      when 'float'
+        begin; Kernel.Float(value); rescue; errs << ::I18n.t('activerecord.errors.messages.invalid') end
+      when 'date'
+        errs << ::I18n.t('activerecord.errors.messages.not_a_date') unless value =~ /^\d{4}-\d{2}-\d{2}$/ && begin; value.to_date; rescue; false end
+      when 'list'
+        errs << ::I18n.t('activerecord.errors.messages.inclusion') unless possible_values.include?(value)
+      end
+    end
+    errs
+  end
+
+  # Removes multiple values for the custom field after setting the multiple attribute to false
+  # We kepp the value with the highest id for each customized object
+  def handle_multiplicity_change
+    if !new_record? && multiple_was && !multiple
+      ids = custom_values.
+        where("EXISTS(SELECT 1 FROM #{CustomValue.table_name} cve WHERE cve.custom_field_id = #{CustomValue.table_name}.custom_field_id" +
+          " AND cve.customized_type = #{CustomValue.table_name}.customized_type AND cve.customized_id = #{CustomValue.table_name}.customized_id" +
+          " AND cve.id > #{CustomValue.table_name}.id)").
+        pluck(:id)
+
+      if ids.any?
+        custom_values.where(:id => ids).delete_all
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6e/6e61a701e2749bf002d37820f0ff37fbc966f8bd.svn-base
--- /dev/null
+++ b/.svn/pristine/6e/6e61a701e2749bf002d37820f0ff37fbc966f8bd.svn-base
@@ -0,0 +1,29 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine #:nodoc:
+  module CoreExtensions #:nodoc:
+    module String #:nodoc:
+      # Custom string inflections
+      module Inflections
+        def with_leading_slash
+          starts_with?('/') ? self : "/#{ self }"
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6e/6eadc5531e55c7dfea168413bcc84110076f8d5b.svn-base
--- a/.svn/pristine/6e/6eadc5531e55c7dfea168413bcc84110076f8d5b.svn-base
+++ /dev/null
@@ -1,96 +0,0 @@
-module CodeRay
-module Encoders
-  
-  # Makes a statistic for the given tokens.
-  # 
-  # Alias: +stats+
-  class Statistic < Encoder
-    
-    register_for :statistic
-    
-    attr_reader :type_stats, :real_token_count  # :nodoc:
-    
-    TypeStats = Struct.new :count, :size  # :nodoc:
-    
-  protected
-    
-    def setup options
-      super
-      
-      @type_stats = Hash.new { |h, k| h[k] = TypeStats.new 0, 0 }
-      @real_token_count = 0
-    end
-    
-    STATS = <<-STATS  # :nodoc:
-
-Code Statistics
-
-Tokens            %8d
-  Non-Whitespace  %8d
-Bytes Total       %8d
-
-Token Types (%d):
-  type                     count     ratio    size (average)
--------------------------------------------------------------
-%s
-    STATS
-    
-    TOKEN_TYPES_ROW = <<-TKR  # :nodoc:
-  %-20s  %8d  %6.2f %%   %5.1f
-    TKR
-    
-    def finish options
-      all = @type_stats['TOTAL']
-      all_count, all_size = all.count, all.size
-      @type_stats.each do |type, stat|
-        stat.size /= stat.count.to_f
-      end
-      types_stats = @type_stats.sort_by { |k, v| [-v.count, k.to_s] }.map do |k, v|
-        TOKEN_TYPES_ROW % [k, v.count, 100.0 * v.count / all_count, v.size]
-      end.join
-      @out << STATS % [
-        all_count, @real_token_count, all_size,
-        @type_stats.delete_if { |k, v| k.is_a? String }.size,
-        types_stats
-      ]
-      
-      super
-    end
-    
-  public
-    
-    def text_token text, kind
-      @real_token_count += 1 unless kind == :space
-      @type_stats[kind].count += 1
-      @type_stats[kind].size += text.size
-      @type_stats['TOTAL'].size += text.size
-      @type_stats['TOTAL'].count += 1
-    end
-    
-    # TODO Hierarchy handling
-    def begin_group kind
-      block_token ':begin_group', kind
-    end
-    
-    def end_group kind
-      block_token ':end_group', kind
-    end
-    
-    def begin_line kind
-      block_token ':begin_line', kind
-    end
-    
-    def end_line kind
-      block_token ':end_line', kind
-    end
-    
-    def block_token action, kind
-      @type_stats['TOTAL'].count += 1
-      @type_stats[action].count += 1
-      @type_stats[kind].count += 1
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6e/6eb8f6ba1fb9f77eecb3f59c8c17c2519975f45e.svn-base
--- a/.svn/pristine/6e/6eb8f6ba1fb9f77eecb3f59c8c17c2519975f45e.svn-base
+++ /dev/null
@@ -1,120 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'news_controller'
-
-# Re-raise errors caught by the controller.
-class NewsController; def rescue_action(e) raise e end; end
-
-class NewsControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news, :comments
-
-  def setup
-    @controller = NewsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:newss)
-    assert_nil assigns(:project)
-  end
-
-  def test_index_with_project
-    get :index, :project_id => 1
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:newss)
-  end
-
-  def test_show
-    get :show, :id => 1
-    assert_response :success
-    assert_template 'show'
-    assert_tag :tag => 'h2', :content => /eCookbook first release/
-  end
-
-  def test_show_not_found
-    get :show, :id => 999
-    assert_response 404
-  end
-
-  def test_get_new
-    @request.session[:user_id] = 2
-    get :new, :project_id => 1
-    assert_response :success
-    assert_template 'new'
-  end
-
-  def test_post_create
-    ActionMailer::Base.deliveries.clear
-    Setting.notified_events << 'news_added'
-
-    @request.session[:user_id] = 2
-    post :create, :project_id => 1, :news => { :title => 'NewsControllerTest',
-                                            :description => 'This is the description',
-                                            :summary => '' }
-    assert_redirected_to '/projects/ecookbook/news'
-
-    news = News.find_by_title('NewsControllerTest')
-    assert_not_nil news
-    assert_equal 'This is the description', news.description
-    assert_equal User.find(2), news.author
-    assert_equal Project.find(1), news.project
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_get_edit
-    @request.session[:user_id] = 2
-    get :edit, :id => 1
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_put_update
-    @request.session[:user_id] = 2
-    put :update, :id => 1, :news => { :description => 'Description changed by test_post_edit' }
-    assert_redirected_to '/news/1'
-    news = News.find(1)
-    assert_equal 'Description changed by test_post_edit', news.description
-  end
-
-  def test_post_create_with_validation_failure
-    @request.session[:user_id] = 2
-    post :create, :project_id => 1, :news => { :title => '',
-                                            :description => 'This is the description',
-                                            :summary => '' }
-    assert_response :success
-    assert_template 'new'
-    assert_not_nil assigns(:news)
-    assert assigns(:news).new_record?
-    assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' },
-                              :content => /1 error/
-  end
-
-  def test_destroy
-    @request.session[:user_id] = 2
-    delete :destroy, :id => 1
-    assert_redirected_to '/projects/ecookbook/news'
-    assert_nil News.find_by_id(1)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6e/6ed00895e314aeaec84d2e309911a6ab1bb54af7.svn-base
--- a/.svn/pristine/6e/6ed00895e314aeaec84d2e309911a6ab1bb54af7.svn-base
+++ /dev/null
@@ -1,17 +0,0 @@
-module CodeRay
-module Scanners
-
-  load :html
-
-  # Scanner for XML.
-  #
-  # Currently this is the same scanner as Scanners::HTML.
-  class XML < HTML
-
-    register_for :xml
-    file_extension 'xml'
-    
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6f/6f3de0785368c550e0511d7f874b1261b16e18b8.svn-base
--- /dev/null
+++ b/.svn/pristine/6f/6f3de0785368c550e0511d7f874b1261b16e18b8.svn-base
@@ -0,0 +1,220 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssuesTest < ActionController::IntegrationTest
+  fixtures :projects,
+           :users,
+           :roles,
+           :members,
+           :member_roles,
+           :trackers,
+           :projects_trackers,
+           :enabled_modules,
+           :issue_statuses,
+           :issues,
+           :enumerations,
+           :custom_fields,
+           :custom_values,
+           :custom_fields_trackers
+
+  # create an issue
+  def test_add_issue
+    log_user('jsmith', 'jsmith')
+    get 'projects/1/issues/new', :tracker_id => '1'
+    assert_response :success
+    assert_template 'issues/new'
+
+    post 'projects/1/issues', :tracker_id => "1",
+                                 :issue => { :start_date => "2006-12-26",
+                                             :priority_id => "4",
+                                             :subject => "new test issue",
+                                             :category_id => "",
+                                             :description => "new issue",
+                                             :done_ratio => "0",
+                                             :due_date => "",
+                                             :assigned_to_id => "" },
+                                 :custom_fields => {'2' => 'Value for field 2'}
+    # find created issue
+    issue = Issue.find_by_subject("new test issue")
+    assert_kind_of Issue, issue
+
+    # check redirection
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
+    follow_redirect!
+    assert_equal issue, assigns(:issue)
+
+    # check issue attributes
+    assert_equal 'jsmith', issue.author.login
+    assert_equal 1, issue.project.id
+    assert_equal 1, issue.status.id
+  end
+
+  # add then remove 2 attachments to an issue
+  def test_issue_attachments
+    log_user('jsmith', 'jsmith')
+    set_tmp_attachments_directory
+
+    put 'issues/1',
+         :notes => 'Some notes',
+         :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'This is an attachment'}}
+    assert_redirected_to "/issues/1"
+
+    # make sure attachment was saved
+    attachment = Issue.find(1).attachments.find_by_filename("testfile.txt")
+    assert_kind_of Attachment, attachment
+    assert_equal Issue.find(1), attachment.container
+    assert_equal 'This is an attachment', attachment.description
+    # verify the size of the attachment stored in db
+    #assert_equal file_data_1.length, attachment.filesize
+    # verify that the attachment was written to disk
+    assert File.exist?(attachment.diskfile)
+
+    # remove the attachments
+    Issue.find(1).attachments.each(&:destroy)
+    assert_equal 0, Issue.find(1).attachments.length
+  end
+
+  def test_other_formats_links_on_index
+    get '/projects/ecookbook/issues'
+
+    %w(Atom PDF CSV).each do |format|
+      assert_tag :a, :content => format,
+                     :attributes => { :href => "/projects/ecookbook/issues.#{format.downcase}",
+                                      :rel => 'nofollow' }
+    end
+  end
+
+  def test_other_formats_links_on_index_without_project_id_in_url
+    get '/issues', :project_id => 'ecookbook'
+
+    %w(Atom PDF CSV).each do |format|
+      assert_tag :a, :content => format,
+                     :attributes => { :href => "/projects/ecookbook/issues.#{format.downcase}",
+                                      :rel => 'nofollow' }
+    end
+  end
+
+  def test_pagination_links_on_index
+    Setting.per_page_options = '2'
+    get '/projects/ecookbook/issues'
+
+    assert_tag :a, :content => '2',
+                   :attributes => { :href => '/projects/ecookbook/issues?page=2' }
+
+  end
+
+  def test_pagination_links_on_index_without_project_id_in_url
+    Setting.per_page_options = '2'
+    get '/issues', :project_id => 'ecookbook'
+
+    assert_tag :a, :content => '2',
+                   :attributes => { :href => '/projects/ecookbook/issues?page=2' }
+
+  end
+
+  def test_issue_with_user_custom_field
+    @field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :trackers => Tracker.all)
+    Role.anonymous.add_permission! :add_issues, :edit_issues
+    users = Project.find(1).users
+    tester = users.first
+
+    # Issue form
+    get '/projects/ecookbook/issues/new'
+    assert_response :success
+    assert_tag :select,
+      :attributes => {:name => "issue[custom_field_values][#{@field.id}]"},
+      :children => {:count => (users.size + 1)}, # +1 for blank value
+      :child => {
+        :tag => 'option',
+        :attributes => {:value => tester.id.to_s},
+        :content => tester.name
+      }
+
+    # Create issue
+    assert_difference 'Issue.count' do
+      post '/projects/ecookbook/issues',
+        :issue => {
+          :tracker_id => '1',
+          :priority_id => '4',
+          :subject => 'Issue with user custom field',
+          :custom_field_values => {@field.id.to_s => users.first.id.to_s}
+        }
+    end
+    issue = Issue.first(:order => 'id DESC')
+    assert_response 302
+
+    # Issue view
+    follow_redirect!
+    assert_tag :th,
+      :content => /Tester/,
+      :sibling => {
+        :tag => 'td',
+        :content => tester.name
+      }
+    assert_tag :select,
+      :attributes => {:name => "issue[custom_field_values][#{@field.id}]"},
+      :children => {:count => (users.size + 1)}, # +1 for blank value
+      :child => {
+        :tag => 'option',
+        :attributes => {:value => tester.id.to_s, :selected => 'selected'},
+        :content => tester.name
+      }
+
+    # Update issue
+    new_tester = users[1]
+    assert_difference 'Journal.count' do
+      put "/issues/#{issue.id}",
+        :notes => 'Updating custom field',
+        :issue => {
+          :custom_field_values => {@field.id.to_s => new_tester.id.to_s}
+        }
+    end
+    assert_response 302
+
+    # Issue view
+    follow_redirect!
+    assert_tag :content => 'Tester',
+      :ancestor => {:tag => 'ul', :attributes => {:class => /details/}},
+      :sibling => {
+        :content => tester.name,
+        :sibling => {
+          :content => new_tester.name
+        }
+      }
+  end
+
+  def test_update_using_invalid_http_verbs
+    subject = 'Updated by an invalid http verb'
+
+    get '/issues/update/1', {:issue => {:subject => subject}}, credentials('jsmith')
+    assert_response 404
+    assert_not_equal subject, Issue.find(1).subject
+
+    post '/issues/1', {:issue => {:subject => subject}}, credentials('jsmith')
+    assert_response 404
+    assert_not_equal subject, Issue.find(1).subject
+  end
+
+  def test_get_watch_should_be_invalid
+    assert_no_difference 'Watcher.count' do
+      get '/watchers/watch?object_type=issue&object_id=1', {}, credentials('jsmith')
+      assert_response 404
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6f/6f3eae848dd2627dfa6aa6d53a27862ad05c9e96.svn-base
--- a/.svn/pristine/6f/6f3eae848dd2627dfa6aa6d53a27862ad05c9e96.svn-base
+++ /dev/null
@@ -1,83 +0,0 @@
-The engines plugin enhances Rails' own plugin framework, making it simple to share controllers, helpers, models, public assets, routes and migrations in plugins.
-
-For more information, see http://rails-engines.org
-
-= Using the plugin
-
-Once you've installed the engines plugin, you'll need to add a single line to the top of config/environment.rb:
-
-  require File.join(File.dirname(__FILE__), '../vendor/plugins/engines/boot')
-  
-You should add this line just below the require for Rails' own boot.rb file. This will enabled the enhanced plugin loading mechanism automatically for you (i.e. you don't need to set config.plugin_loader manually).
-
-With that aside, you're now ready to start using more powerful plugins in your application. Read on to find out more about what the engines plugin enables.
-
-
-== Better plugins
-
-In addition to the regular set of plugin-supported files (lib, init.rb, tasks, generators, tests), plugins can carry the following when the engines plugin is also installed.
-
-
-=== Controllers, Helpers, and Views
-
-Include these files in an <tt>app</tt> directory just like you would in a normal Rails application. If you need to override a method, view or partial, create the corresponding file in your main <tt>app</tt> directory and it will be used instead.
-
-* Controllers & Helpers: See Engines::RailsExtensions::Dependencies for more information.
-* Views: now handled almost entirely by ActionView itself (see Engines::Plugin#add_plugin_view_paths for more information)
-
-=== Models
-
-Model code can similarly be placed in an <tt>app/models/</tt> directory. Unfortunately, it's not possible to automatically override methods within a model; if your application needs to change the way a model behaves, consider creating a subclass, or replacing the model entirely within your application's <tt>app/models/</tt> directory. See Engines::RailsExtensions::Dependencies for more information.
-
-IMPORTANT NOTE: when you load code from within plugins, it is typically not handled well by Rails in terms of unloading and reloading changes. Look here for more information - http://rails-engines.org/development/common-issues-when-overloading-code-from-plugins/
-
-=== Routes
-
-Include your route declarations in a <tt>routes.rb</tt> file at the root of your plugins, e.g.:
-
-  connect "/my/url", :controller => "some_controller"
-  my_named_route "do_stuff", :controller => "blah", :action => "stuff"
-  # etc.
-  
-You can then load these files into your application by declaring their inclusion in the application's <tt>config/routes.rb</tt>:
-
-  map.from_plugin :plugin_name
-
-See Engines::RailsExtensions::Routing for more information.
-  
-=== Migrations
-
-Migrations record the changes in your database as your application evolves. With engines 1.2, migrations from plugins can also join in this evolution as first-class entities. To add migrations to a plugin, include a <tt>db/migrate/</tt> folder and add migrations there as normal. These migrations can then be integrated into the main flow of database evolution by running the plugin_migration generator:
-
-  script/generate plugin_migration
-  
-This will produce a migration in your application. Running this migration (via <tt>rake db:migrate</tt>, as normal) will migrate the database according to the latest migrations in each plugin. See Engines::RailsExtensions::Migrations for more information.
-
-
-=== More powerful Rake tasks
-
-The engines plugin enhances and adds to the suite of default rake tasks for working with plugins. The <tt>doc:plugins</tt> task now includes controllers, helpers and models under <tt>app</tt>, and anything other code found under the plugin's <tt>code_paths</tt> attribute. New testing tasks have been added to run unit, functional and integration tests from plugins, whilst making it easier to load fixtures from plugins. See Engines::Testing for more details about testing, and run
-
-  rake -T
-  
-to see the set of rake tasks available.
-
-= Testing the engines plugin itself
-
-Because of the way the engines plugin modifies Rails, the simplest way to consistently test it against multiple versions is by generating a test harness application - a full Rails application that includes tests to verify the engines plugin behaviour in a real, running environment.
-
-Run the tests like this:
-
-  $ cd engines
-  $ rake test
-  
-This will generate a test_app directory within the engines plugin (using the default 'rails' command), import tests and code into that application and then run the test suite.
-
-If you wish to test against a specific version of Rails, run the tests with the RAILS environment variable set to the local directory containing your Rails checkout
-
-  $ rake test RAILS=/Users/james/Code/rails_edge_checkout
-  
-Alternatively, you can clone the latest version of Rails ('edge rails') from github like so:
-
-  $ rake test RAILS=edge
-  
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6f/6f698b7e19aa2a0b60b2198d129cd28a41bdf55a.svn-base
--- a/.svn/pristine/6f/6f698b7e19aa2a0b60b2198d129cd28a41bdf55a.svn-base
+++ /dev/null
@@ -1,14 +0,0 @@
-== Sample plugin
-
-This is a sample plugin for Redmine
-
-== Installation
-
-1. Copy the plugin directory into the vendor/plugins directory
-
-2. Migrate plugin:
-   rake db:migrate_plugins
-
-3. Start Redmine
-
-Installed plugins are listed and can be configured from 'Admin -> Plugins' screen.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6f/6f837ff76b98a304a7758e9ac959a9fc7a915173.svn-base
--- /dev/null
+++ b/.svn/pristine/6f/6f837ff76b98a304a7758e9ac959a9fc7a915173.svn-base
@@ -0,0 +1,244 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class CustomFieldTest < ActiveSupport::TestCase
+  fixtures :custom_fields
+
+  def test_create
+    field = UserCustomField.new(:name => 'Money money money', :field_format => 'float')
+    assert field.save
+  end
+
+  def test_before_validation
+    field = CustomField.new(:name => 'test_before_validation', :field_format => 'int')
+    field.searchable = true
+    assert field.save
+    assert_equal false, field.searchable
+    field.searchable = true
+    assert field.save
+    assert_equal false, field.searchable
+  end
+
+  def test_regexp_validation
+    field = IssueCustomField.new(:name => 'regexp', :field_format => 'text', :regexp => '[a-z0-9')
+    assert !field.save
+    assert_include I18n.t('activerecord.errors.messages.invalid'),
+                   field.errors[:regexp]
+    field.regexp = '[a-z0-9]'
+    assert field.save
+  end
+
+  def test_default_value_should_be_validated
+    field = CustomField.new(:name => 'Test', :field_format => 'int')
+    field.default_value = 'abc'
+    assert !field.valid?
+    field.default_value = '6'
+    assert field.valid?
+  end
+
+  def test_default_value_should_not_be_validated_when_blank
+    field = CustomField.new(:name => 'Test', :field_format => 'list', :possible_values => ['a', 'b'], :is_required => true, :default_value => '')
+    assert field.valid?
+  end
+
+  def test_should_not_change_field_format_of_existing_custom_field
+    field = CustomField.find(1)
+    field.field_format = 'int'
+    assert_equal 'list', field.field_format
+  end
+
+  def test_possible_values_should_accept_an_array
+    field = CustomField.new
+    field.possible_values = ["One value", ""]
+    assert_equal ["One value"], field.possible_values
+  end
+
+  def test_possible_values_should_accept_a_string
+    field = CustomField.new
+    field.possible_values = "One value"
+    assert_equal ["One value"], field.possible_values
+  end
+
+  def test_possible_values_should_accept_a_multiline_string
+    field = CustomField.new
+    field.possible_values = "One value\nAnd another one  \r\n \n"
+    assert_equal ["One value", "And another one"], field.possible_values
+  end
+
+  if "string".respond_to?(:encoding)
+    def test_possible_values_stored_as_binary_should_be_utf8_encoded
+      field = CustomField.find(11)
+      assert_kind_of Array, field.possible_values
+      assert field.possible_values.size > 0
+      field.possible_values.each do |value|
+        assert_equal "UTF-8", value.encoding.name
+      end
+    end
+  end
+
+  def test_destroy
+    field = CustomField.find(1)
+    assert field.destroy
+  end
+
+  def test_new_subclass_instance_should_return_an_instance
+    f = CustomField.new_subclass_instance('IssueCustomField')
+    assert_kind_of IssueCustomField, f
+  end
+
+  def test_new_subclass_instance_should_set_attributes
+    f = CustomField.new_subclass_instance('IssueCustomField', :name => 'Test')
+    assert_kind_of IssueCustomField, f
+    assert_equal 'Test', f.name
+  end
+
+  def test_new_subclass_instance_with_invalid_class_name_should_return_nil
+    assert_nil CustomField.new_subclass_instance('WrongClassName')
+  end
+
+  def test_new_subclass_instance_with_non_subclass_name_should_return_nil
+    assert_nil CustomField.new_subclass_instance('Project')
+  end
+
+  def test_string_field_validation_with_blank_value
+    f = CustomField.new(:field_format => 'string')
+
+    assert f.valid_field_value?(nil)
+    assert f.valid_field_value?('')
+
+    f.is_required = true
+    assert !f.valid_field_value?(nil)
+    assert !f.valid_field_value?('')
+  end
+
+  def test_string_field_validation_with_min_and_max_lengths
+    f = CustomField.new(:field_format => 'string', :min_length => 2, :max_length => 5)
+
+    assert f.valid_field_value?(nil)
+    assert f.valid_field_value?('')
+    assert f.valid_field_value?('a' * 2)
+    assert !f.valid_field_value?('a')
+    assert !f.valid_field_value?('a' * 6)
+  end
+
+  def test_string_field_validation_with_regexp
+    f = CustomField.new(:field_format => 'string', :regexp => '^[A-Z0-9]*$')
+
+    assert f.valid_field_value?(nil)
+    assert f.valid_field_value?('')
+    assert f.valid_field_value?('ABC')
+    assert !f.valid_field_value?('abc')
+  end
+
+  def test_date_field_validation
+    f = CustomField.new(:field_format => 'date')
+
+    assert f.valid_field_value?(nil)
+    assert f.valid_field_value?('')
+    assert f.valid_field_value?('1975-07-14')
+    assert !f.valid_field_value?('1975-07-33')
+    assert !f.valid_field_value?('abc')
+  end
+
+  def test_list_field_validation
+    f = CustomField.new(:field_format => 'list', :possible_values => ['value1', 'value2'])
+
+    assert f.valid_field_value?(nil)
+    assert f.valid_field_value?('')
+    assert f.valid_field_value?('value2')
+    assert !f.valid_field_value?('abc')
+  end
+
+  def test_int_field_validation
+    f = CustomField.new(:field_format => 'int')
+
+    assert f.valid_field_value?(nil)
+    assert f.valid_field_value?('')
+    assert f.valid_field_value?('123')
+    assert f.valid_field_value?('+123')
+    assert f.valid_field_value?('-123')
+    assert !f.valid_field_value?('6abc')
+  end
+
+  def test_float_field_validation
+    f = CustomField.new(:field_format => 'float')
+
+    assert f.valid_field_value?(nil)
+    assert f.valid_field_value?('')
+    assert f.valid_field_value?('11.2')
+    assert f.valid_field_value?('-6.250')
+    assert f.valid_field_value?('5')
+    assert !f.valid_field_value?('6abc')
+  end
+
+  def test_multi_field_validation
+    f = CustomField.new(:field_format => 'list', :multiple => 'true', :possible_values => ['value1', 'value2'])
+
+    assert f.valid_field_value?(nil)
+    assert f.valid_field_value?('')
+    assert f.valid_field_value?([])
+    assert f.valid_field_value?([nil])
+    assert f.valid_field_value?([''])
+
+    assert f.valid_field_value?('value2')
+    assert !f.valid_field_value?('abc')
+
+    assert f.valid_field_value?(['value2'])
+    assert !f.valid_field_value?(['abc'])
+
+    assert f.valid_field_value?(['', 'value2'])
+    assert !f.valid_field_value?(['', 'abc'])
+
+    assert f.valid_field_value?(['value1', 'value2'])
+    assert !f.valid_field_value?(['value1', 'abc'])
+  end
+
+  def test_changing_multiple_to_false_should_delete_multiple_values
+    field = ProjectCustomField.create!(:name => 'field', :field_format => 'list', :multiple => 'true', :possible_values => ['field1', 'field2'])
+    other = ProjectCustomField.create!(:name => 'other', :field_format => 'list', :multiple => 'true', :possible_values => ['other1', 'other2'])
+
+    item_with_multiple_values = Project.generate!(:custom_field_values => {field.id => ['field1', 'field2'], other.id => ['other1', 'other2']})
+    item_with_single_values = Project.generate!(:custom_field_values => {field.id => ['field1'], other.id => ['other2']})
+
+    assert_difference 'CustomValue.count', -1 do
+      field.multiple = false
+      field.save!
+    end
+
+    item_with_multiple_values = Project.find(item_with_multiple_values.id)
+    assert_kind_of String, item_with_multiple_values.custom_field_value(field)
+    assert_kind_of Array, item_with_multiple_values.custom_field_value(other)
+    assert_equal 2, item_with_multiple_values.custom_field_value(other).size
+  end
+
+  def test_value_class_should_return_the_class_used_for_fields_values
+    assert_equal User, CustomField.new(:field_format => 'user').value_class
+    assert_equal Version, CustomField.new(:field_format => 'version').value_class
+  end
+
+  def test_value_class_should_return_nil_for_other_fields
+    assert_nil CustomField.new(:field_format => 'text').value_class
+    assert_nil CustomField.new.value_class
+  end
+
+  def test_value_from_keyword_for_list_custom_field
+    field = CustomField.find(1)
+    assert_equal 'PostgreSQL', field.value_from_keyword('postgresql', Issue.find(1))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6f/6f938056d9ea2cfe9c4f2e93944e625cd1a36508.svn-base
--- a/.svn/pristine/6f/6f938056d9ea2cfe9c4f2e93944e625cd1a36508.svn-base
+++ /dev/null
@@ -1,341 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/abstract_adapter'
-require 'cgi'
-
-module Redmine
-  module Scm
-    module Adapters
-      class MercurialAdapter < AbstractAdapter
-
-        # Mercurial executable name
-        HG_BIN = Redmine::Configuration['scm_mercurial_command'] || "hg"
-        HELPERS_DIR = File.dirname(__FILE__) + "/mercurial"
-        HG_HELPER_EXT = "#{HELPERS_DIR}/redminehelper.py"
-        TEMPLATE_NAME = "hg-template"
-        TEMPLATE_EXTENSION = "tmpl"
-
-        # raised if hg command exited with error, e.g. unknown revision.
-        class HgCommandAborted < CommandFailed; end
-
-        class << self
-          def client_command
-            @@bin    ||= HG_BIN
-          end
-
-          def sq_bin
-            @@sq_bin ||= shell_quote_command
-          end
-
-          def client_version
-            @@client_version ||= (hgversion || [])
-          end
-
-          def client_available
-            client_version_above?([1, 2])
-          end
-
-          def hgversion
-            # The hg version is expressed either as a
-            # release number (eg 0.9.5 or 1.0) or as a revision
-            # id composed of 12 hexa characters.
-            theversion = hgversion_from_command_line.dup
-            if theversion.respond_to?(:force_encoding)
-              theversion.force_encoding('ASCII-8BIT')
-            end
-            if m = theversion.match(%r{\A(.*?)((\d+\.)+\d+)})
-              m[2].scan(%r{\d+}).collect(&:to_i)
-            end
-          end
-
-          def hgversion_from_command_line
-            shellout("#{sq_bin} --version") { |io| io.read }.to_s
-          end
-
-          def template_path
-            @@template_path ||= template_path_for(client_version)
-          end
-
-          def template_path_for(version)
-            "#{HELPERS_DIR}/#{TEMPLATE_NAME}-1.0.#{TEMPLATE_EXTENSION}"
-          end
-        end
-
-        def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil)
-          super
-          @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
-        end
-
-        def path_encoding
-          @path_encoding
-        end
-
-        def info
-          tip = summary['repository']['tip']
-          Info.new(:root_url => CGI.unescape(summary['repository']['root']),
-                   :lastrev => Revision.new(:revision => tip['revision'],
-                                            :scmid => tip['node']))
-        # rescue HgCommandAborted
-        rescue Exception => e
-          logger.error "hg: error during getting info: #{e.message}"
-          nil
-        end
-
-        def tags
-          as_ary(summary['repository']['tag']).map { |e| e['name'] }
-        end
-
-        # Returns map of {'tag' => 'nodeid', ...}
-        def tagmap
-          alist = as_ary(summary['repository']['tag']).map do |e|
-            e.values_at('name', 'node')
-          end
-          Hash[*alist.flatten]
-        end
-
-        def branches
-          brs = []
-          as_ary(summary['repository']['branch']).each do |e|
-            br = Branch.new(e['name'])
-            br.revision =  e['revision']
-            br.scmid    =  e['node']
-            brs << br
-          end
-          brs
-        end
-
-        # Returns map of {'branch' => 'nodeid', ...}
-        def branchmap
-          alist = as_ary(summary['repository']['branch']).map do |e|
-            e.values_at('name', 'node')
-          end
-          Hash[*alist.flatten]
-        end
-
-        def summary
-          return @summary if @summary
-          hg 'rhsummary' do |io|
-            output = io.read
-            if output.respond_to?(:force_encoding)
-              output.force_encoding('UTF-8')
-            end
-            begin
-              @summary = ActiveSupport::XmlMini.parse(output)['rhsummary']
-            rescue
-            end
-          end
-        end
-        private :summary
-
-        def entries(path=nil, identifier=nil, options={})
-          p1 = scm_iconv(@path_encoding, 'UTF-8', path)
-          manifest = hg('rhmanifest', '-r', CGI.escape(hgrev(identifier)),
-                        CGI.escape(without_leading_slash(p1.to_s))) do |io|
-            output = io.read
-            if output.respond_to?(:force_encoding)
-              output.force_encoding('UTF-8')
-            end
-            begin
-              ActiveSupport::XmlMini.parse(output)['rhmanifest']['repository']['manifest']
-            rescue
-            end
-          end
-          path_prefix = path.blank? ? '' : with_trailling_slash(path)
-
-          entries = Entries.new
-          as_ary(manifest['dir']).each do |e|
-            n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name']))
-            p = "#{path_prefix}#{n}"
-            entries << Entry.new(:name => n, :path => p, :kind => 'dir')
-          end
-
-          as_ary(manifest['file']).each do |e|
-            n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name']))
-            p = "#{path_prefix}#{n}"
-            lr = Revision.new(:revision => e['revision'], :scmid => e['node'],
-                              :identifier => e['node'],
-                              :time => Time.at(e['time'].to_i))
-            entries << Entry.new(:name => n, :path => p, :kind => 'file',
-                                 :size => e['size'].to_i, :lastrev => lr)
-          end
-
-          entries
-        rescue HgCommandAborted
-          nil  # means not found
-        end
-
-        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
-          revs = Revisions.new
-          each_revision(path, identifier_from, identifier_to, options) { |e| revs << e }
-          revs
-        end
-
-        # Iterates the revisions by using a template file that
-        # makes Mercurial produce a xml output.
-        def each_revision(path=nil, identifier_from=nil, identifier_to=nil, options={})
-          hg_args = ['log', '--debug', '-C', '--style', self.class.template_path]
-          hg_args << '-r' << "#{hgrev(identifier_from)}:#{hgrev(identifier_to)}"
-          hg_args << '--limit' << options[:limit] if options[:limit]
-          hg_args << hgtarget(path) unless path.blank?
-          log = hg(*hg_args) do |io|
-            output = io.read
-            if output.respond_to?(:force_encoding)
-              output.force_encoding('UTF-8')
-            end
-            begin
-              # Mercurial < 1.5 does not support footer template for '</log>'
-              ActiveSupport::XmlMini.parse("#{output}</log>")['log']
-            rescue
-            end
-          end
-          as_ary(log['logentry']).each do |le|
-            cpalist = as_ary(le['paths']['path-copied']).map do |e|
-              [e['__content__'], e['copyfrom-path']].map do |s|
-                scm_iconv('UTF-8', @path_encoding, CGI.unescape(s))
-              end
-            end
-            cpmap = Hash[*cpalist.flatten]
-            paths = as_ary(le['paths']['path']).map do |e|
-              p = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['__content__']) )
-              {:action        => e['action'],
-               :path          => with_leading_slash(p),
-               :from_path     => (cpmap.member?(p) ? with_leading_slash(cpmap[p]) : nil),
-               :from_revision => (cpmap.member?(p) ? le['node'] : nil)}
-            end.sort { |a, b| a[:path] <=> b[:path] }
-            parents_ary = []
-            as_ary(le['parents']['parent']).map do |par|
-              parents_ary << par['__content__'] if par['__content__'] != "000000000000"
-            end
-            yield Revision.new(:revision => le['revision'],
-                               :scmid    => le['node'],
-                               :author   => (le['author']['__content__'] rescue ''),
-                               :time     => Time.parse(le['date']['__content__']),
-                               :message  => le['msg']['__content__'],
-                               :paths    => paths,
-                               :parents  => parents_ary)
-          end
-          self
-        end
-
-        # Returns list of nodes in the specified branch
-        def nodes_in_branch(branch, options={})
-          hg_args = ['rhlog', '--template', '{node|short}\n', '--rhbranch', CGI.escape(branch)]
-          hg_args << '--from' << CGI.escape(branch)
-          hg_args << '--to'   << '0'
-          hg_args << '--limit' << options[:limit] if options[:limit]
-          hg(*hg_args) { |io| io.readlines.map { |e| e.chomp } }
-        end
-
-        def diff(path, identifier_from, identifier_to=nil)
-          hg_args = %w|rhdiff|
-          if identifier_to
-            hg_args << '-r' << hgrev(identifier_to) << '-r' << hgrev(identifier_from)
-          else
-            hg_args << '-c' << hgrev(identifier_from)
-          end
-          unless path.blank?
-            p = scm_iconv(@path_encoding, 'UTF-8', path)
-            hg_args << CGI.escape(hgtarget(p))
-          end
-          diff = []
-          hg *hg_args do |io|
-            io.each_line do |line|
-              diff << line
-            end
-          end
-          diff
-        rescue HgCommandAborted
-          nil  # means not found
-        end
-
-        def cat(path, identifier=nil)
-          p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path))
-          hg 'rhcat', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io|
-            io.binmode
-            io.read
-          end
-        rescue HgCommandAborted
-          nil  # means not found
-        end
-
-        def annotate(path, identifier=nil)
-          p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path))
-          blame = Annotate.new
-          hg 'rhannotate', '-ncu', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io|
-            io.each_line do |line|
-              line.force_encoding('ASCII-8BIT') if line.respond_to?(:force_encoding)
-              next unless line =~ %r{^([^:]+)\s(\d+)\s([0-9a-f]+):\s(.*)$}
-              r = Revision.new(:author => $1.strip, :revision => $2, :scmid => $3,
-                               :identifier => $3)
-              blame.add_line($4.rstrip, r)
-            end
-          end
-          blame
-        rescue HgCommandAborted
-          # means not found or cannot be annotated
-          Annotate.new
-        end
-
-        class Revision < Redmine::Scm::Adapters::Revision
-          # Returns the readable identifier
-          def format_identifier
-            "#{revision}:#{scmid}"
-          end
-        end
-
-        # Runs 'hg' command with the given args
-        def hg(*args, &block)
-          repo_path = root_url || url
-          full_args = ['-R', repo_path, '--encoding', 'utf-8']
-          full_args << '--config' << "extensions.redminehelper=#{HG_HELPER_EXT}"
-          full_args << '--config' << 'diff.git=false'
-          full_args += args
-          ret = shellout(
-                   self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
-                   &block
-                   )
-          if $? && $?.exitstatus != 0
-            raise HgCommandAborted, "hg exited with non-zero status: #{$?.exitstatus}"
-          end
-          ret
-        end
-        private :hg
-
-        # Returns correct revision identifier
-        def hgrev(identifier, sq=false)
-          rev = identifier.blank? ? 'tip' : identifier.to_s
-          rev = shell_quote(rev) if sq
-          rev
-        end
-        private :hgrev
-
-        def hgtarget(path)
-          path ||= ''
-          root_url + '/' + without_leading_slash(path)
-        end
-        private :hgtarget
-
-        def as_ary(o)
-          return [] unless o
-          o.is_a?(Array) ? o : Array[o]
-        end
-        private :as_ary
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6f/6fc3080d660626f975ab483d311285aeb4746301.svn-base
--- a/.svn/pristine/6f/6fc3080d660626f975ab483d311285aeb4746301.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-<%= wiki_page_breadcrumb(@page) %>
-
-<h2><%=h @page.pretty_title %></h2>
-
-<% form_for :content, @content, :url => {:action => 'update', :id => @page.title}, :html => {:method => :put, :multipart => true, :id => 'wiki_form'} do |f| %>
-<%= f.hidden_field :version %>
-<% if @section %>
-<%= hidden_field_tag 'section', @section %>
-<%= hidden_field_tag 'section_hash', @section_hash %>
-<% end %>
-<%= error_messages_for 'content' %>
-
-<p><%= text_area_tag 'content[text]', @text, :cols => 100, :rows => 25, :class => 'wiki-edit', :accesskey => accesskey(:edit) %></p>
-<p><label><%= l(:field_comments) %></label><br /><%= f.text_field :comments, :size => 120 %></p>
-<p><label><%=l(:label_attachment_plural)%></label><br /><%= render :partial => 'attachments/form' %></p>
-
-<p><%= submit_tag l(:button_save) %>
-   <%= link_to_remote l(:label_preview),
-                       { :url => { :controller => 'wiki', :action => 'preview', :project_id => @project, :id => @page.title },
-                         :method => :post,
-                         :update => 'preview',
-                         :with => "Form.serialize('wiki_form')",
-                         :complete => "Element.scrollTo('preview')"
-                       }, :accesskey => accesskey(:preview) %></p>
-<%= wikitoolbar_for 'content_text' %>
-<% end %>
-
-<div id="preview" class="wiki"></div>
-
-<% content_for :header_tags do %>
-  <%= stylesheet_link_tag 'scm' %>
-  <%= robot_exclusion_tag %>
-<% end %>
-
-<% html_title @page.pretty_title %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/6f/6ffa0ee9adc461e348a513bb42e310bb6ccba1cd.svn-base
--- /dev/null
+++ b/.svn/pristine/6f/6ffa0ee9adc461e348a513bb42e310bb6ccba1cd.svn-base
@@ -0,0 +1,217 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class BoardsControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
+
+  def setup
+    User.current = nil
+  end
+
+  def test_index
+    get :index, :project_id => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:boards)
+    assert_not_nil assigns(:project)
+  end
+
+  def test_index_not_found
+    get :index, :project_id => 97
+    assert_response 404
+  end
+
+  def test_index_should_show_messages_if_only_one_board
+    Project.find(1).boards.slice(1..-1).each(&:destroy)
+
+    get :index, :project_id => 1
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:topics)
+  end
+
+  def test_show
+    get :show, :project_id => 1, :id => 1
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:board)
+    assert_not_nil assigns(:project)
+    assert_not_nil assigns(:topics)
+  end
+
+  def test_show_should_display_sticky_messages_first
+    Message.update_all(:sticky => 0)
+    Message.update_all({:sticky => 1}, {:id => 1})
+
+    get :show, :project_id => 1, :id => 1
+    assert_response :success
+
+    topics = assigns(:topics)
+    assert_not_nil topics
+    assert topics.size > 1, "topics size was #{topics.size}"
+    assert topics.first.sticky?
+    assert topics.first.updated_on < topics.second.updated_on
+  end
+
+  def test_show_should_display_message_with_last_reply_first
+    Message.update_all(:sticky => 0)
+
+    # Reply to an old topic
+    old_topic = Message.where(:board_id => 1, :parent_id => nil).order('created_on ASC').first
+    reply = Message.new(:board_id => 1, :subject => 'New reply', :content => 'New reply', :author_id => 2)
+    old_topic.children << reply
+
+    get :show, :project_id => 1, :id => 1
+    assert_response :success
+    topics = assigns(:topics)
+    assert_not_nil topics
+    assert_equal old_topic, topics.first
+  end
+
+  def test_show_with_permission_should_display_the_new_message_form
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :id => 1
+    assert_response :success
+    assert_template 'show'
+
+    assert_select 'form#message-form' do
+      assert_select 'input[name=?]', 'message[subject]'
+    end
+  end
+
+  def test_show_atom
+    get :show, :project_id => 1, :id => 1, :format => 'atom'
+    assert_response :success
+    assert_template 'common/feed'
+    assert_not_nil assigns(:board)
+    assert_not_nil assigns(:project)
+    assert_not_nil assigns(:messages)
+  end
+
+  def test_show_not_found
+    get :index, :project_id => 1, :id => 97
+    assert_response 404
+  end
+
+  def test_new
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'select[name=?]', 'board[parent_id]' do
+      assert_select 'option', (Project.find(1).boards.size + 1)
+      assert_select 'option[value=]', :text => ''
+      assert_select 'option[value=1]', :text => 'Help'
+    end
+  end
+
+  def test_new_without_project_boards
+    Project.find(1).boards.delete_all
+    @request.session[:user_id] = 2
+
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'select[name=?]', 'board[parent_id]', 0
+  end
+
+  def test_create
+    @request.session[:user_id] = 2
+    assert_difference 'Board.count' do
+      post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing board creation'}
+    end
+    assert_redirected_to '/projects/ecookbook/settings/boards'
+    board = Board.first(:order => 'id DESC')
+    assert_equal 'Testing', board.name
+    assert_equal 'Testing board creation', board.description
+  end
+
+  def test_create_with_parent
+    @request.session[:user_id] = 2
+    assert_difference 'Board.count' do
+      post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing', :parent_id => 2}
+    end
+    assert_redirected_to '/projects/ecookbook/settings/boards'
+    board = Board.first(:order => 'id DESC')
+    assert_equal Board.find(2), board.parent
+  end
+
+  def test_create_with_failure
+    @request.session[:user_id] = 2
+    assert_no_difference 'Board.count' do
+      post :create, :project_id => 1, :board => { :name => '', :description => 'Testing board creation'}
+    end
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_edit
+    @request.session[:user_id] = 2
+    get :edit, :project_id => 1, :id => 2
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_edit_with_parent
+    board = Board.generate!(:project_id => 1, :parent_id => 2)
+    @request.session[:user_id] = 2
+    get :edit, :project_id => 1, :id => board.id
+    assert_response :success
+    assert_template 'edit'
+
+    assert_select 'select[name=?]', 'board[parent_id]' do
+      assert_select 'option[value=2][selected=selected]'
+    end
+  end
+
+  def test_update
+    @request.session[:user_id] = 2
+    assert_no_difference 'Board.count' do
+      put :update, :project_id => 1, :id => 2, :board => { :name => 'Testing', :description => 'Testing board update'}
+    end
+    assert_redirected_to '/projects/ecookbook/settings/boards'
+    assert_equal 'Testing', Board.find(2).name
+  end
+
+  def test_update_position
+    @request.session[:user_id] = 2
+    put :update, :project_id => 1, :id => 2, :board => { :move_to => 'highest'}
+    assert_redirected_to '/projects/ecookbook/settings/boards'
+    board = Board.find(2)
+    assert_equal 1, board.position
+  end
+
+  def test_update_with_failure
+    @request.session[:user_id] = 2
+    put :update, :project_id => 1, :id => 2, :board => { :name => '', :description => 'Testing board update'}
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_destroy
+    @request.session[:user_id] = 2
+    assert_difference 'Board.count', -1 do
+      delete :destroy, :project_id => 1, :id => 2
+    end
+    assert_redirected_to '/projects/ecookbook/settings/boards'
+    assert_nil Board.find_by_id(2)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/70/7005c1ac60bfaef4c1c73b8db2692b1b9a732a71.svn-base
--- /dev/null
+++ b/.svn/pristine/70/7005c1ac60bfaef4c1c73b8db2692b1b9a732a71.svn-base
@@ -0,0 +1,64 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class CommentsControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news, :comments
+
+  def setup
+    User.current = nil
+  end
+
+  def test_add_comment
+    @request.session[:user_id] = 2
+    post :create, :id => 1, :comment => { :comments => 'This is a test comment' }
+    assert_redirected_to '/news/1'
+
+    comment = News.find(1).comments.last
+    assert_not_nil comment
+    assert_equal 'This is a test comment', comment.comments
+    assert_equal User.find(2), comment.author
+  end
+
+  def test_empty_comment_should_not_be_added
+    @request.session[:user_id] = 2
+    assert_no_difference 'Comment.count' do
+      post :create, :id => 1, :comment => { :comments => '' }
+      assert_response :redirect
+      assert_redirected_to '/news/1'
+    end
+  end
+
+  def test_create_should_be_denied_if_news_is_not_commentable
+    News.any_instance.stubs(:commentable?).returns(false)
+    @request.session[:user_id] = 2
+    assert_no_difference 'Comment.count' do
+      post :create, :id => 1, :comment => { :comments => 'This is a test comment' }
+      assert_response 403
+    end
+  end
+
+  def test_destroy_comment
+    comments_count = News.find(1).comments.size
+    @request.session[:user_id] = 2
+    delete :destroy, :id => 1, :comment_id => 2
+    assert_redirected_to '/news/1'
+    assert_nil Comment.find_by_id(2)
+    assert_equal comments_count - 1, News.find(1).comments.size
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/70/7056d41df5e2a1e9fde837930bc56e51e678d276.svn-base
--- /dev/null
+++ b/.svn/pristine/70/7056d41df5e2a1e9fde837930bc56e51e678d276.svn-base
@@ -0,0 +1,1086 @@
+# Bulgarian translation by Nikolay Solakov and Ivan Cenov
+bg:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d-%m-%Y"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [ÐÐµÐ´ÐµÐ»Ñ, ÐŸÐ¾Ð½ÐµÐ´ÐµÐ»Ð½Ð¸Ðº, Ð’Ñ‚Ð¾Ñ€Ð½Ð¸Ðº, Ð¡Ñ€ÑÐ´Ð°, Ð§ÐµÑ‚Ð²ÑŠÑ€Ñ‚ÑŠÐº, ÐŸÐµÑ‚ÑŠÐº, Ð¡ÑŠÐ±Ð¾Ñ‚Ð°]
+    abbr_day_names: [ÐÐµÐ´, ÐŸÐ¾Ð½, Ð’Ñ‚Ð¾, Ð¡Ñ€Ñ, Ð§ÐµÑ‚, ÐŸÐµÑ‚, Ð¡ÑŠÐ±]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Ð¯Ð½ÑƒÐ°Ñ€Ð¸, Ð¤ÐµÐ²Ñ€ÑƒÐ°Ñ€Ð¸, ÐœÐ°Ñ€Ñ‚, ÐÐ¿Ñ€Ð¸Ð», ÐœÐ°Ð¹, Ð®Ð½Ð¸, Ð®Ð»Ð¸, ÐÐ²Ð³ÑƒÑÑ‚, Ð¡ÐµÐ¿Ñ‚ÐµÐ¼Ð²Ñ€Ð¸, ÐžÐºÑ‚Ð¾Ð¼Ð²Ñ€Ð¸, ÐÐ¾ÐµÐ¼Ð²Ñ€Ð¸, Ð”ÐµÐºÐµÐ¼Ð²Ñ€Ð¸]
+    abbr_month_names: [~, Ð¯Ð½Ñƒ, Ð¤ÐµÐ², ÐœÐ°Ñ€, ÐÐ¿Ñ€, ÐœÐ°Ð¹, Ð®Ð½Ð¸, Ð®Ð»Ð¸, ÐÐ²Ð³, Ð¡ÐµÐ¿, ÐžÐºÑ‚, ÐÐ¾Ðµ, Ð”ÐµÐº]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "half a minute"
+      less_than_x_seconds:
+        one:   "Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚ 1 ÑÐµÐºÑƒÐ½Ð´Ð°"
+        other: "Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚ %{count} ÑÐµÐºÑƒÐ½Ð´Ð¸"
+      x_seconds:
+        one:   "1 ÑÐµÐºÑƒÐ½Ð´Ð°"
+        other: "%{count} ÑÐµÐºÑƒÐ½Ð´Ð¸"
+      less_than_x_minutes:
+        one:   "Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚ 1 Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
+        other: "Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚ %{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð¸"
+      x_minutes:
+        one:   "1 Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
+        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð¸"
+      about_x_hours:
+        one:   "Ð¾ÐºÐ¾Ð»Ð¾ 1 Ñ‡Ð°Ñ"
+        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
+      x_hours:
+        one:   "1 Ñ‡Ð°Ñ"
+        other: "%{count} Ñ‡Ð°ÑÐ°"
+      x_days:
+        one:   "1 Ð´ÐµÐ½"
+        other: "%{count} Ð´ÐµÐ½Ð°"
+      about_x_months:
+        one:   "Ð¾ÐºÐ¾Ð»Ð¾ 1 Ð¼ÐµÑÐµÑ†"
+        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÐµÑ†Ð°"
+      x_months:
+        one:   "1 Ð¼ÐµÑÐµÑ†"
+        other: "%{count} Ð¼ÐµÑÐµÑ†Ð°"
+      about_x_years:
+        one:   "Ð¾ÐºÐ¾Ð»Ð¾ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
+        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
+      over_x_years:
+        one:   "Ð½Ð°Ð´ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
+        other: "Ð½Ð°Ð´ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
+      almost_x_years:
+        one:   "Ð¿Ð¾Ñ‡Ñ‚Ð¸ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
+        other: "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: Ð±Ð°Ð¹Ñ‚
+            other: Ð±Ð°Ð¹Ñ‚Ð°
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "Ð¸"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 Ð³Ñ€ÐµÑˆÐºÐ° Ð¿Ð¾Ð¿Ñ€ÐµÑ‡Ð¸ Ñ‚Ð¾Ð·Ð¸ %{model} Ð´Ð° Ð±ÑŠÐ´Ðµ Ð·Ð°Ð¿Ð¸ÑÐ°Ð½"
+          other:  "%{count} Ð³Ñ€ÐµÑˆÐºÐ¸ Ð¿Ð¾Ð¿Ñ€ÐµÑ‡Ð¸Ñ…Ð° Ñ‚Ð¾Ð·Ð¸ %{model} Ð´Ð° Ð±ÑŠÐ´Ðµ Ð·Ð°Ð¿Ð¸ÑÐ°Ð½"
+      messages:
+        inclusion: "Ð½Ðµ ÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð° Ð² ÑÐ¿Ð¸ÑÑŠÐºÐ°"
+        exclusion: "Ðµ Ð·Ð°Ð¿Ð°Ð·ÐµÐ½Ð¾"
+        invalid: "Ðµ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð¾"
+        confirmation: "Ð»Ð¸Ð¿ÑÐ²Ð° Ð¾Ð´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ðµ"
+        accepted: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° ÑÐµ Ð¿Ñ€Ð¸ÐµÐ¼Ðµ"
+        empty: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
+        blank: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
+        too_long: "Ðµ Ð¿Ñ€ÐµÐºÐ°Ð»ÐµÐ½Ð¾ Ð´ÑŠÐ»Ð³Ð¾"
+        too_short: "Ðµ Ð¿Ñ€ÐµÐºÐ°Ð»ÐµÐ½Ð¾ ÐºÑŠÑÐ¾"
+        wrong_length: "Ðµ Ñ Ð³Ñ€ÐµÑˆÐ½Ð° Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð°"
+        taken: "Ð²ÐµÑ‡Ðµ ÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð°"
+        not_a_number: "Ð½Ðµ Ðµ Ñ‡Ð¸ÑÐ»Ð¾"
+        not_a_date: "Ðµ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð° Ð´Ð°Ñ‚Ð°"
+        greater_than: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾-Ð³Ð¾Ð»ÑÐ¼[a/Ð¾] Ð¾Ñ‚ %{count}"
+        greater_than_or_equal_to: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾-Ð³Ð¾Ð»ÑÐ¼[a/Ð¾] Ð¾Ñ‚ Ð¸Ð»Ð¸ Ñ€Ð°Ð²ÐµÐ½[a/o] Ð½Ð° %{count}"
+        equal_to: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ñ€Ð°Ð²ÐµÐ½[a/o] Ð½Ð° %{count}"
+        less_than: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾-Ð¼Ð°Ð»ÑŠÐº[a/o] Ð¾Ñ‚ %{count}"
+        less_than_or_equal_to: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾-Ð¼Ð°Ð»ÑŠÐº[a/o] Ð¾Ñ‚ Ð¸Ð»Ð¸ Ñ€Ð°Ð²ÐµÐ½[a/o] Ð½Ð° %{count}"
+        odd: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ð½ÐµÑ‡ÐµÑ‚ÐµÐ½[a/o]"
+        even: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ð±ÑŠÐ´Ðµ Ñ‡ÐµÑ‚ÐµÐ½[a/o]"
+        greater_than_start_date: "Ñ‚Ñ€ÑÐ±Ð²Ð° Ð´Ð° Ðµ ÑÐ»ÐµÐ´ Ð½Ð°Ñ‡Ð°Ð»Ð½Ð°Ñ‚Ð° Ð´Ð°Ñ‚Ð°"
+        not_same_project: "Ð½Ðµ Ðµ Ð¾Ñ‚ ÑÑŠÑ‰Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚"
+        circular_dependency: "Ð¢Ð°Ð·Ð¸ Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ Ñ‰Ðµ Ð´Ð¾Ð²ÐµÐ´Ðµ Ð´Ð¾ Ð±ÐµÐ·ÐºÑ€Ð°Ð¹Ð½Ð° Ð·Ð°Ð²Ð¸ÑÐ¸Ð¼Ð¾ÑÑ‚"
+        cant_link_an_issue_with_a_descendant: "Ð•Ð´Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð° Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ð° ÐºÑŠÐ¼ ÑÐ²Ð¾Ñ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð°"
+
+  actionview_instancetag_blank_option: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ
+
+  general_text_No: 'ÐÐµ'
+  general_text_Yes: 'Ð”Ð°'
+  general_text_no: 'Ð½Ðµ'
+  general_text_yes: 'Ð´Ð°'
+  general_lang_name: 'Bulgarian (Ð‘ÑŠÐ»Ð³Ð°Ñ€ÑÐºÐ¸)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŠÑ‚ Ðµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
+  notice_account_invalid_creditentials: ÐÐµÐ²Ð°Ð»Ð¸Ð´ÐµÐ½ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» Ð¸Ð»Ð¸ Ð¿Ð°Ñ€Ð¾Ð»Ð°.
+  notice_account_password_updated: ÐŸÐ°Ñ€Ð¾Ð»Ð°Ñ‚Ð° Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½Ð°.
+  notice_account_wrong_password: Ð“Ñ€ÐµÑˆÐ½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
+  notice_account_register_done: ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŠÑ‚ Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
+  notice_account_unknown_email: ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ‚ e-mail.
+  notice_can_t_change_password: Ð¢Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ðµ Ñ Ð²ÑŠÐ½ÑˆÐµÐ½ Ð¼ÐµÑ‚Ð¾Ð´ Ð·Ð° Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ. ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð° ÑÐ¼ÑÐ½Ð° Ð½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°Ñ‚Ð°.
+  notice_account_lost_email_sent: Ð˜Ð·Ð¿Ñ€Ð°Ñ‚ÐµÐ½ Ð²Ð¸ Ðµ e-mail Ñ Ð¸Ð½ÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ð¸ Ð·Ð° Ð¸Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð½Ð¾Ð²Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°.
+  notice_account_activated: ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŠÑ‚ Ð²Ð¸ Ðµ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½. Ð’ÐµÑ‡Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð²Ð»ÐµÐ·ÐµÑ‚Ðµ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ð°Ñ‚Ð°.
+  notice_successful_create: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ ÑÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ.
+  notice_successful_update: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð¾Ð±Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ.
+  notice_successful_delete: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ.
+  notice_successful_connection: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ.
+  notice_file_not_found: ÐÐµÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð°Ñ‰Ð° Ð¸Ð»Ð¸ Ð¿Ñ€ÐµÐ¼ÐµÑÑ‚ÐµÐ½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°.
+  notice_locking_conflict: Ð”Ñ€ÑƒÐ³ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ Ñ‚ÐµÐ·Ð¸ Ð´Ð°Ð½Ð½Ð¸ Ð² Ð¼Ð¾Ð¼ÐµÐ½Ñ‚Ð°.
+  notice_not_authorized: ÐÑÐ¼Ð°Ñ‚Ðµ Ð¿Ñ€Ð°Ð²Ð¾ Ð½Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿ Ð´Ð¾ Ñ‚Ð°Ð·Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°.
+  notice_not_authorized_archived_project: ÐŸÑ€Ð¾ÐµÐºÑ‚ÑŠÑ‚, ÐºÐ¾Ð¹Ñ‚Ð¾ ÑÐµ Ð¾Ð¿Ð¸Ñ‚Ð²Ð°Ñ‚Ðµ Ð´Ð° Ð²Ð¸Ð´Ð¸Ñ‚Ðµ Ðµ Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½. ÐÐºÐ¾ ÑÐ¼ÑÑ‚Ð°Ñ‚Ðµ, Ñ‡Ðµ Ñ‚Ð¾Ð²Ð° Ð½Ðµ Ðµ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð½Ð¾, Ð¾Ð±ÑŠÑ€Ð½ÐµÑ‚Ðµ ÑÐµ ÐºÑŠÐ¼ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð° Ð·Ð° Ñ€Ð°Ð·Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ.
+  notice_email_sent: "Ð˜Ð·Ð¿Ñ€Ð°Ñ‚ÐµÐ½ e-mail Ð½Ð° %{value}"
+  notice_email_error: "Ð“Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð¸Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° e-mail (%{value})"
+  notice_feeds_access_key_reseted: Ð’Ð°ÑˆÐ¸Ñ ÐºÐ»ÑŽÑ‡ Ð·Ð° RSS Ð´Ð¾ÑÑ‚ÑŠÐ¿ Ð±ÐµÑˆÐµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½.
+  notice_api_access_key_reseted: Ð’Ð°ÑˆÐ¸ÑÑ‚ API ÐºÐ»ÑŽÑ‡ Ð·Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿ Ð±ÐµÑˆÐµ Ð¸Ð·Ñ‡Ð¸ÑÑ‚ÐµÐ½.
+  notice_failed_to_save_issues: "ÐÐµÑƒÑÐ¿ÐµÑˆÐµÐ½ Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° %{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¾Ñ‚ %{total} Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸: %{ids}."
+  notice_failed_to_save_time_entries: "ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° %{count} Ð·Ð°Ð¿Ð¸ÑÐ° Ð·Ð° Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ Ð¾Ñ‚ %{total} Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸: %{ids}."
+  notice_failed_to_save_members: "ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° Ñ‡Ð»ÐµÐ½(Ð¾Ð²Ðµ): %{errors}."
+  notice_no_issue_selected: "ÐÑÐ¼Ð° Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸."
+  notice_account_pending: "ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŠÑ‚ Ð’Ð¸ Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½ Ð¸ Ð¾Ñ‡Ð°ÐºÐ²Ð° Ð¾Ð´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ðµ Ð¾Ñ‚ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€."
+  notice_default_data_loaded: ÐŸÑ€Ð¸Ð¼ÐµÑ€Ð½Ð°Ñ‚Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ðµ Ð·Ð°Ñ€ÐµÐ´ÐµÐ½Ð° ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
+  notice_unable_delete_version: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð²ÐµÑ€ÑÐ¸Ñ
+  notice_unable_delete_time_entry: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ.
+  notice_issue_done_ratios_updated: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½ Ð¿Ñ€Ð¾Ñ†ÐµÐ½Ñ‚ Ð½Ð° Ð·Ð°Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸.
+  notice_gantt_chart_truncated: ÐœÑ€ÐµÐ¶Ð¾Ð²Ð¸ÑÑ‚ Ð³Ñ€Ð°Ñ„Ð¸Ðº Ðµ ÑÑŠÐºÑ€Ð°Ñ‚ÐµÐ½, Ð¿Ð¾Ð½ÐµÐ¶Ðµ Ð±Ñ€Ð¾ÑÑ‚ Ð½Ð° Ð¾Ð±ÐµÐºÑ‚Ð¸Ñ‚Ðµ, ÐºÐ¾Ð¸Ñ‚Ð¾ Ð¼Ð¾Ð³Ð°Ñ‚ Ð´Ð° Ð±ÑŠÐ´Ð°Ñ‚ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ð¸ Ðµ Ñ‚Ð²ÑŠÑ€Ð´Ðµ Ð³Ð¾Ð»ÑÐ¼ (%{max})
+  notice_issue_successful_create: Ð—Ð°Ð´Ð°Ñ‡Ð° %{id} Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½Ð°.
+  notice_issue_update_conflict: Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ðµ Ð±Ð¸Ð»Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½Ð° Ð¾Ñ‚ Ð´Ñ€ÑƒÐ³ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ», Ð´Ð¾ÐºÐ°Ñ‚Ð¾ Ð²Ð¸Ðµ ÑÑ‚Ðµ Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð»Ð¸.
+  notice_account_deleted: Ð’Ð°ÑˆÐ¸ÑÑ‚ Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ð±ÐµÑˆÐµ Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½Ð°Ñ‚ Ð±ÐµÐ· Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð²ÑŠÐ·ÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ.
+  notice_user_successful_create: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» %{id} Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½.
+
+  error_can_t_load_default_data: "Ð“Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð·Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð½Ð°Ñ‡Ð°Ð»Ð½Ð°Ñ‚Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ: %{value}"
+  error_scm_not_found: ÐÐµÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð°Ñ‰ Ð¾Ð±ÐµÐºÑ‚ Ð² Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÑ‚Ð¾.
+  error_scm_command_failed: "Ð“Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð¾Ð¿Ð¸Ñ‚ Ð·Ð° ÐºÐ¾Ð¼ÑƒÐ½Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ: %{value}"
+  error_scm_annotate: "ÐžÐ±ÐµÐºÑ‚ÑŠÑ‚ Ð½Ðµ ÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð° Ð¸Ð»Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð°Ð½Ð¾Ñ‚Ð¸Ñ€Ð°Ð½."
+  error_scm_annotate_big_text_file: "Ð¤Ð°Ð¹Ð»ÑŠÑ‚ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð°Ð½Ð¾Ñ‚Ð¸Ñ€Ð°Ð½, Ð¿Ð¾Ð½ÐµÐ¶Ðµ Ð½Ð°Ð´Ñ…Ð²ÑŠÑ€Ð»Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ð·Ð° Ñ‚ÐµÐºÑÑ‚Ð¾Ð²Ð¸ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ."
+  error_issue_not_found_in_project: 'Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ð½Ðµ Ðµ Ð½Ð°Ð¼ÐµÑ€ÐµÐ½Ð° Ð¸Ð»Ð¸ Ð½Ðµ Ð¿Ñ€Ð¸Ð½Ð°Ð´Ð»ÐµÐ¶Ð¸ Ð½Ð° Ñ‚Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚'
+  error_no_tracker_in_project: ÐÑÐ¼Ð° Ð°ÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð°Ð½Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€Ð¸ Ñ Ñ‚Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚. ÐŸÑ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸Ñ‚Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°.
+  error_no_default_issue_status: ÐÑÐ¼Ð° ÑƒÑÑ‚Ð°Ð½Ð¾Ð²ÐµÐ½Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ñ‰Ð¾ ÑÐµ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ Ð·Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ. ÐœÐ¾Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ Ð²Ð°ÑˆÐ°Ñ‚Ð° ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ (Ð’Ð¸Ð¶Ñ‚Ðµ "ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ -> Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ñ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸").
+  error_can_not_delete_custom_field: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¾ Ð¿Ð¾Ð»Ðµ
+  error_can_not_delete_tracker: Ð¢Ð¾Ð·Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€ ÑÑŠÐ´ÑŠÑ€Ð¶Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚.
+  error_can_not_remove_role: Ð¢Ð°Ð·Ð¸ Ñ€Ð¾Ð»Ñ ÑÐµ Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚Ð°.
+  error_can_not_reopen_issue_on_closed_version: Ð—Ð°Ð´Ð°Ñ‡Ð°, Ð°ÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð°Ð½Ð° ÑÑŠÑ Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° Ð²ÐµÑ€ÑÐ¸Ñ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° Ð¾Ñ‚Ð½Ð¾Ð²Ð¾
+  error_can_not_archive_project: Ð¢Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½
+  error_issue_done_ratios_not_updated: ÐŸÑ€Ð¾Ñ†ÐµÐ½Ñ‚ÑŠÑ‚ Ð½Ð° Ð·Ð°Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð½Ðµ Ðµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½.
+  error_workflow_copy_source: ÐœÐ¾Ð»Ñ Ð¸Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ source Ñ‚Ñ€Ð°ÐºÐµÑ€ Ð¸Ð»Ð¸ Ñ€Ð¾Ð»Ñ
+  error_workflow_copy_target: ÐœÐ¾Ð»Ñ Ð¸Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ñ‚Ñ€Ð°ÐºÐµÑ€(Ð¸) Ð¸ Ñ€Ð¾Ð»Ñ (Ñ€Ð¾Ð»Ð¸).
+  error_unable_delete_issue_status: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¸Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  error_unable_to_connect: ÐÐµÐ²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ Ñ (%{value})
+  error_attachment_too_big: Ð¢Ð¾Ð·Ð¸ Ñ„Ð°Ð¹Ð» Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ ÐºÐ°Ñ‡ÐµÐ½, Ð¿Ð¾Ð½ÐµÐ¶Ðµ Ð½Ð°Ð´Ñ…Ð²ÑŠÑ€Ð»Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð°Ñ‚Ð° Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð° Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð° (%{max_size})
+  error_session_expired: Ð’Ð°ÑˆÐ°Ñ‚Ð° ÑÐµÑÐ¸Ñ Ðµ Ð¸Ð·Ñ‚ÐµÐºÐ»Ð°. ÐœÐ¾Ð»Ñ Ð²Ð»ÐµÐ·ÐµÑ‚Ðµ Ð² Redmine Ð¾Ñ‚Ð½Ð¾Ð²Ð¾.
+  warning_attachments_not_saved: "%{count} Ñ„Ð°Ð¹Ð»Ð° Ð½Ðµ Ð±ÑÑ…Ð° Ð·Ð°Ð¿Ð¸ÑÐ°Ð½Ð¸."
+
+  mail_subject_lost_password: "Ð’Ð°ÑˆÐ°Ñ‚Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð° (%{value})"
+  mail_body_lost_password: 'Ð—Ð° Ð´Ð° ÑÐ¼ÐµÐ½Ð¸Ñ‚Ðµ Ð¿Ð°Ñ€Ð¾Ð»Ð°Ñ‚Ð° ÑÐ¸, Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð¹Ñ‚Ðµ ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð»Ð¸Ð½Ðº:'
+  mail_subject_register: "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð» (%{value})"
+  mail_body_register: 'Ð—Ð° Ð´Ð° Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ñ‚Ðµ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð° ÑÐ¸ Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð¹Ñ‚Ðµ ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð»Ð¸Ð½Ðº:'
+  mail_body_account_information_external: "ÐœÐ¾Ð¶ÐµÑ‚Ðµ Ð´Ð° Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ñ‚Ðµ Ð²Ð°ÑˆÐ¸Ñ %{value} Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ð·Ð° Ð²Ñ…Ð¾Ð´."
+  mail_body_account_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÑÑ‚Ð° Ð·Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð° Ð²Ð¸
+  mail_subject_account_activation_request: "Ð—Ð°ÑÐ²ÐºÐ° Ð·Ð° Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ð² %{value}"
+  mail_body_account_activation_request: "Ð˜Ð¼Ð° Ð½Ð¾Ð²Ð¾Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» (%{value}), Ð¾Ñ‡Ð°ÐºÐ²Ð°Ñ‰ Ð²Ð°ÑˆÐµÑ‚Ð¾ Ð¾Ð´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ðµ:"
+  mail_subject_reminder: "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ñ ÐºÑ€Ð°ÐµÐ½ ÑÑ€Ð¾Ðº Ñ ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ‚Ðµ %{days} Ð´Ð½Ð¸"
+  mail_body_reminder: "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸, Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð²Ð°Ñ ÑÐ° Ñ ÐºÑ€Ð°ÐµÐ½ ÑÑ€Ð¾Ðº Ð² ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ‚Ðµ %{days} Ð´Ð½Ð¸:"
+  mail_subject_wiki_content_added: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð°"
+  mail_body_wiki_content_added: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð° Ð¾Ñ‚ %{author}.
+  mail_subject_wiki_content_updated: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð°"
+  mail_body_wiki_content_updated: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð° Ð¾Ñ‚ %{author}.
+
+  field_name: Ð˜Ð¼Ðµ
+  field_description: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ
+  field_summary: ÐÐ½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ
+  field_is_required: Ð—Ð°Ð´ÑŠÐ»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾
+  field_firstname: Ð˜Ð¼Ðµ
+  field_lastname: Ð¤Ð°Ð¼Ð¸Ð»Ð¸Ñ
+  field_mail: Email
+  field_filename: Ð¤Ð°Ð¹Ð»
+  field_filesize: Ð“Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð°
+  field_downloads: Ð˜Ð·Ñ‚ÐµÐ³Ð»ÐµÐ½Ð¸ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
+  field_author: ÐÐ²Ñ‚Ð¾Ñ€
+  field_created_on: ÐžÑ‚ Ð´Ð°Ñ‚Ð°
+  field_updated_on: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð°
+  field_closed_on: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+  field_field_format: Ð¢Ð¸Ð¿
+  field_is_for_all: Ð—Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  field_possible_values: Ð’ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¸ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚Ð¸
+  field_regexp: Ð ÐµÐ³ÑƒÐ»ÑÑ€ÐµÐ½ Ð¸Ð·Ñ€Ð°Ð·
+  field_min_length: ÐœÐ¸Ð½. Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð°
+  field_max_length: ÐœÐ°ÐºÑ. Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð°
+  field_value: Ð¡Ñ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚
+  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
+  field_title: Ð—Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ
+  field_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
+  field_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
+  field_status: Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
+  field_notes: Ð‘ÐµÐ»ÐµÐ¶ÐºÐ°
+  field_is_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  field_is_default: Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
+  field_tracker: Ð¢Ñ€Ð°ÐºÐµÑ€
+  field_subject: Ð—Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ
+  field_due_date: ÐšÑ€Ð°Ð¹Ð½Ð° Ð´Ð°Ñ‚Ð°
+  field_assigned_to: Ð’ÑŠÐ·Ð»Ð¾Ð¶ÐµÐ½Ð° Ð½Ð°
+  field_priority: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
+  field_fixed_version: ÐŸÐ»Ð°Ð½ÑƒÐ²Ð°Ð½Ð° Ð²ÐµÑ€ÑÐ¸Ñ
+  field_user: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
+  field_principal: Principal
+  field_role: Ð Ð¾Ð»Ñ
+  field_homepage: ÐÐ°Ñ‡Ð°Ð»Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  field_is_public: ÐŸÑƒÐ±Ð»Ð¸Ñ‡ÐµÐ½
+  field_parent: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð½Ð°
+  field_is_in_roadmap: Ð”Ð° ÑÐµ Ð²Ð¸Ð¶Ð´Ð° Ð»Ð¸ Ð² ÐŸÑŠÑ‚Ð½Ð° ÐºÐ°Ñ€Ñ‚Ð°
+  field_login: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
+  field_mail_notification: Ð˜Ð·Ð²ÐµÑÑ‚Ð¸Ñ Ð¿Ð¾ Ð¿Ð¾Ñ‰Ð°Ñ‚Ð°
+  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
+  field_last_login_on: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¾ ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ
+  field_language: Ð•Ð·Ð¸Ðº
+  field_effective_date: Ð”Ð°Ñ‚Ð°
+  field_password: ÐŸÐ°Ñ€Ð¾Ð»Ð°
+  field_new_password: ÐÐ¾Ð²Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
+  field_password_confirmation: ÐŸÐ¾Ñ‚Ð²ÑŠÑ€Ð¶Ð´ÐµÐ½Ð¸Ðµ
+  field_version: Ð’ÐµÑ€ÑÐ¸Ñ
+  field_type: Ð¢Ð¸Ð¿
+  field_host: Ð¥Ð¾ÑÑ‚
+  field_port: ÐŸÐ¾Ñ€Ñ‚
+  field_account: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
+  field_base_dn: Base DN
+  field_attr_login: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Login
+  field_attr_firstname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ ÐŸÑŠÑ€Ð²Ð¾ Ð¸Ð¼Ðµ (Firstname)
+  field_attr_lastname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð¤Ð°Ð¼Ð¸Ð»Ð¸Ñ (Lastname)
+  field_attr_mail: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Email
+  field_onthefly: Ð”Ð¸Ð½Ð°Ð¼Ð¸Ñ‡Ð½Ð¾ ÑÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
+  field_start_date: ÐÐ°Ñ‡Ð°Ð»Ð½Ð° Ð´Ð°Ñ‚Ð°
+  field_done_ratio: "% ÐŸÑ€Ð¾Ð³Ñ€ÐµÑ"
+  field_auth_source: ÐÐ°Ñ‡Ð¸Ð½ Ð½Ð° Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
+  field_hide_mail: Ð¡ÐºÑ€Ð¸Ð¹ e-mail Ð°Ð´Ñ€ÐµÑÐ° Ð¼Ð¸
+  field_comments: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  field_url: ÐÐ´Ñ€ÐµÑ
+  field_start_page: ÐÐ°Ñ‡Ð°Ð»Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  field_subproject: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  field_hours: Ð§Ð°ÑÐ¾Ð²Ðµ
+  field_activity: Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚
+  field_spent_on: Ð”Ð°Ñ‚Ð°
+  field_identifier: Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€
+  field_is_filter: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° ÑÐµ Ð·Ð° Ñ„Ð¸Ð»Ñ‚ÑŠÑ€
+  field_issue_to: Ð¡Ð²ÑŠÑ€Ð·Ð°Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  field_delay: ÐžÑ‚Ð¼ÐµÑÑ‚Ð²Ð°Ð½Ðµ
+  field_assignable: Ð’ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ Ðµ Ð²ÑŠÐ·Ð»Ð°Ð³Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð·Ð° Ñ‚Ð°Ð·Ð¸ Ñ€Ð¾Ð»Ñ
+  field_redirect_existing_links: ÐŸÑ€ÐµÐ½Ð°ÑÐ¾Ñ‡Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð°Ñ‰Ð¸ Ð»Ð¸Ð½ÐºÐ¾Ð²Ðµ
+  field_estimated_hours: Ð˜Ð·Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  field_column_names: ÐšÐ¾Ð»Ð¾Ð½Ð¸
+  field_time_entries: Log time
+  field_time_zone: Ð§Ð°ÑÐ¾Ð²Ð° Ð·Ð¾Ð½Ð°
+  field_searchable: Ð¡ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ñ‚ÑŠÑ€ÑÐµÐ½Ðµ
+  field_default_value: Ð¡Ñ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
+  field_comments_sorting: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ‚Ðµ
+  field_parent_title: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  field_editable: Editable
+  field_watcher: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»
+  field_identity_url: OpenID URL
+  field_content: Ð¡ÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ
+  field_group_by: Ð“Ñ€ÑƒÐ¿Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ñ€ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸Ñ‚Ðµ Ð¿Ð¾
+  field_sharing: Sharing
+  field_parent_issue: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  field_member_of_group: Ð§Ð»ÐµÐ½ Ð½Ð° Ð³Ñ€ÑƒÐ¿Ð°
+  field_assigned_to_role: Assignee's role
+  field_text: Ð¢ÐµÐºÑÑ‚Ð¾Ð²Ð¾ Ð¿Ð¾Ð»Ðµ
+  field_visible: Ð’Ð¸Ð´Ð¸Ð¼
+  field_warn_on_leaving_unsaved: ÐŸÑ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ´Ð¸ Ð¼Ðµ, ÐºÐ¾Ð³Ð°Ñ‚Ð¾ Ð½Ð°Ð¿ÑƒÑÐºÐ°Ð¼ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ñ Ð½ÐµÐ·Ð°Ð¿Ð¸ÑÐ°Ð½Ð¾ ÑÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ
+  field_issues_visibility: Ð’Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
+  field_is_private: Ð›Ð¸Ñ‡Ð½Ð°
+  field_commit_logs_encoding: ÐšÐ¾Ð´Ð¾Ð²Ð° Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸ÑÑ‚Ð° Ð¿Ñ€Ð¸ Ð¿Ð¾Ð²ÐµÑ€ÑÐ²Ð°Ð½Ðµ
+  field_scm_path_encoding: ÐšÐ¾Ð´Ð¾Ð²Ð° Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ð½Ð° Ð¿ÑŠÑ‚Ð¸Ñ‰Ð°Ñ‚Ð° (path)
+  field_path_to_repository: ÐŸÑŠÑ‚ Ð´Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÑ‚Ð¾
+  field_root_directory: ÐšÐ¾Ñ€ÐµÐ½Ð½Ð° Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ (Ð¿Ð°Ð¿ÐºÐ°)
+  field_cvsroot: CVSROOT
+  field_cvs_module: ÐœÐ¾Ð´ÑƒÐ»
+  field_repository_is_default: Ð“Ð»Ð°Ð²Ð½Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  field_multiple: Ð˜Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð¿Ð¾Ð²ÐµÑ‡Ðµ Ð¾Ñ‚ ÐµÐ´Ð½Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚
+  field_auth_source_ldap_filter: LDAP Ñ„Ð¸Ð»Ñ‚ÑŠÑ€
+  field_core_fields: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸ Ð¿Ð¾Ð»ÐµÑ‚Ð°
+  field_timeout: Ð¢Ð°Ð¹Ð¼Ð°ÑƒÑ‚ (Ð² ÑÐµÐºÑƒÐ½Ð´Ð¸)
+  field_board_parent: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ Ñ„Ð¾Ñ€ÑƒÐ¼
+  field_private_notes: Ð›Ð¸Ñ‡Ð½Ð¸ Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸
+  field_inherit_members: ÐÐ°ÑÐ»ÐµÐ´ÑÐ²Ð°Ð½Ðµ Ð½Ð° Ñ‡Ð»ÐµÐ½Ð¾Ð²ÐµÑ‚Ðµ Ð½Ð° Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚
+
+  setting_app_title: Ð—Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ
+  setting_app_subtitle: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ
+  setting_welcome_text: Ð”Ð¾Ð¿ÑŠÐ»Ð½Ð¸Ñ‚ÐµÐ»ÐµÐ½ Ñ‚ÐµÐºÑÑ‚
+  setting_default_language: Ð•Ð·Ð¸Ðº Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
+  setting_login_required: Ð˜Ð·Ð¸ÑÐºÐ²Ð°Ð½Ðµ Ð·Ð° Ð²Ñ…Ð¾Ð´ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ð°Ñ‚Ð°
+  setting_self_registration: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸
+  setting_attachment_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð° Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½ Ñ„Ð°Ð¹Ð»
+  setting_issues_export_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð·Ð° ÐµÐºÑÐ¿Ð¾Ñ€Ñ‚
+  setting_mail_from: E-mail Ð°Ð´Ñ€ÐµÑ Ð·Ð° ÐµÐ¼Ð¸ÑÐ¸Ð¸
+  setting_bcc_recipients: ÐŸÐ¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ð¸ Ð½Ð° ÑÐºÑ€Ð¸Ñ‚Ð¾ ÐºÐ¾Ð¿Ð¸Ðµ (bcc)
+  setting_plain_text_mail: ÑÐ°Ð¼Ð¾ Ñ‡Ð¸ÑÑ‚ Ñ‚ÐµÐºÑÑ‚ (Ð±ÐµÐ· HTML)
+  setting_host_name: Ð¥Ð¾ÑÑ‚
+  setting_text_formatting: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ñ‚ÐµÐºÑÑ‚Ð°
+  setting_wiki_compression: ÐšÐ¾Ð¼Ð¿Ñ€ÐµÑÐ¸Ñ€Ð°Ð½Ðµ Ð½Ð° Wiki Ð¸ÑÑ‚Ð¾Ñ€Ð¸ÑÑ‚Ð°
+  setting_feeds_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð² ATOM ÐµÐ¼Ð¸ÑÐ¸Ð¸
+  setting_default_projects_public: ÐÐ¾Ð²Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸ ÑÐ° Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
+  setting_autofetch_changesets: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾ Ð¸Ð·Ð²Ð»Ð¸Ñ‡Ð°Ð½Ðµ Ð½Ð° Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸Ñ‚Ðµ
+  setting_sys_api_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° WS Ð·Ð° ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ
+  setting_commit_ref_keywords: ÐžÑ‚Ð±ÐµÐ»ÑÐ·Ð²Ð°Ñ‰Ð¸ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¸ Ð´ÑƒÐ¼Ð¸
+  setting_commit_fix_keywords: ÐŸÑ€Ð¸ÐºÐ»ÑŽÑ‡Ð²Ð°Ñ‰Ð¸ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¸ Ð´ÑƒÐ¼Ð¸
+  setting_autologin: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÐ½ Ð²Ñ…Ð¾Ð´
+  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð½Ð° Ð´Ð°Ñ‚Ð°Ñ‚Ð°
+  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð½Ð° Ñ‡Ð°ÑÐ°
+  setting_cross_project_issue_relations: Ð ÐµÐ»Ð°Ñ†Ð¸Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¼ÐµÐ¶Ð´Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  setting_cross_project_subtasks: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¾Ñ‚ Ð´Ñ€ÑƒÐ³Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  setting_issue_list_default_columns: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ð¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
+  setting_repositories_encodings: ÐšÐ¾Ð´Ð¾Ð²Ð° Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½Ð¸Ñ‚Ðµ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°Ñ‚Ð°
+  setting_emails_header: Email header
+  setting_emails_footer: ÐŸÐ¾Ð´Ñ‚ÐµÐºÑÑ‚ Ð·Ð° e-mail
+  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
+  setting_per_page_options: ÐžÐ¿Ñ†Ð¸Ð¸ Ð·Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ€Ð°Ð½Ðµ
+  setting_user_format: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚
+  setting_activity_days_default: Ð‘Ñ€Ð¾Ð¹ Ð´Ð½Ð¸ Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ð½Ð¸ Ð½Ð° Ñ‚Ð°Ð± Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚
+  setting_display_subprojects_issues: Ð—Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ Ð¾Ñ‚ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ ÑÐµ Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ñ‚ Ð² Ð³Ð»Ð°Ð²Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  setting_enabled_scm: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð° SCM
+  setting_mail_handler_body_delimiters: ÐžÑ‚Ñ€ÑÐ·Ð²Ð°Ð½Ðµ Ð½Ð° e-mail-Ð¸Ñ‚Ðµ ÑÐ»ÐµÐ´ ÐµÐ´Ð¸Ð½ Ð¾Ñ‚ Ñ‚ÐµÐ·Ð¸ Ñ€ÐµÐ´Ð¾Ð²Ðµ
+  setting_mail_handler_api_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° WS Ð·Ð° Ð²Ñ…Ð¾Ð´ÑÑ‰Ð¸ e-mail-Ð¸
+  setting_mail_handler_api_key: API ÐºÐ»ÑŽÑ‡
+  setting_sequential_project_identifiers: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»Ð½Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ð¸ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¸
+  setting_gravatar_enabled: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ñ€Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ Ð¸ÐºÐ¾Ð½Ð¸ Ð¾Ñ‚ Gravatar
+  setting_gravatar_default: ÐŸÐ¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ñ‰Ð¾ ÑÐµ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ Ð¾Ñ‚ Gravatar
+  setting_diff_max_lines_displayed: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ð½Ð¸ diff Ñ€ÐµÐ´Ð¾Ð²Ðµ
+  setting_file_max_size_displayed: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ð½Ð° Ñ‚ÐµÐºÑÑ‚Ð¾Ð²Ð¸Ñ‚Ðµ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ, Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ð½Ð¸ inline
+  setting_repository_log_display_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð½Ð° Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ð½ÐµÑ‚Ðµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸ Ð² Ð»Ð¾Ð³ Ñ„Ð°Ð¹Ð»Ð°
+  setting_openid: Ð Ð°Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° OpenID Ð²Ñ…Ð¾Ð´ Ð¸ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
+  setting_password_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð° Ð½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
+  setting_new_project_user_role_id: Ð Ð¾Ð»Ñ, Ð´Ð°Ð²Ð°Ð½Ð° Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ», ÑÑŠÐ·Ð´Ð°Ð²Ð°Ñ‰ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸, ÐºÐ¾Ð¹Ñ‚Ð¾ Ð½Ðµ Ðµ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
+  setting_default_projects_modules: ÐÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ð¸ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ Ð·Ð° Ð½Ð¾Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  setting_issue_done_ratio: Ð˜Ð·Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð¿Ñ€Ð¾Ñ†ÐµÐ½Ñ‚Ð° Ð½Ð° Ð³Ð¾Ñ‚Ð¾Ð²Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ñ
+  setting_issue_done_ratio_issue_field: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ð»Ðµ '% ÐŸÑ€Ð¾Ð³Ñ€ÐµÑ'
+  setting_issue_done_ratio_issue_status: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸ÐµÑ‚Ð¾ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
+  setting_start_of_week: ÐŸÑŠÑ€Ð²Ð¸ Ð´ÐµÐ½ Ð½Ð° ÑÐµÐ´Ð¼Ð¸Ñ†Ð°Ñ‚Ð°
+  setting_rest_api_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° REST web ÑÑŠÑ€Ð²Ð¸Ñ
+  setting_cache_formatted_text: ÐšÐµÑˆÐ¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ñ‚ÐµÐºÑÑ‚Ð¾Ð²Ðµ
+  setting_default_notification_option: ÐŸÐ¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ñ‰ ÑÐµ Ð½Ð°Ñ‡Ð¸Ð½ Ð·Ð° Ð¸Ð·Ð²ÐµÑÑ‚ÑÐ²Ð°Ð½Ðµ
+  setting_commit_logtime_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¾Ñ‚Ñ‡Ð¸Ñ‚Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  setting_commit_logtime_activity_id: Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚ Ð¿Ñ€Ð¸ Ð¾Ñ‚Ñ‡Ð¸Ñ‚Ð°Ð½Ðµ Ð½Ð° Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  setting_gantt_items_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð±Ñ€Ð¾Ð¹ Ð¾Ð±ÐµÐºÑ‚Ð¸, ÐºÐ¾Ð¸Ñ‚Ð¾ Ð´Ð° ÑÐµ Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ñ‚ Ð² Ð¼Ñ€ÐµÐ¶Ð¾Ð² Ð³Ñ€Ð°Ñ„Ð¸Ðº
+  setting_issue_group_assignment: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¾ Ð½Ð°Ð·Ð½Ð°Ñ‡Ð°Ð²Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð½Ð° Ð³Ñ€ÑƒÐ¿Ð¸
+  setting_default_issue_start_date_to_creation_date: ÐÐ°Ñ‡Ð°Ð»Ð½Ð° Ð´Ð°Ñ‚Ð° Ð½Ð° Ð½Ð¾Ð²Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð´Ð½ÐµÑˆÐ½Ð°Ñ‚Ð° Ð´Ð°Ñ‚Ð°
+  setting_commit_cross_project_ref: ÐžÑ‚Ð±ÐµÐ»ÑÐ·Ð²Ð°Ð½Ðµ Ð¸ Ð¿Ñ€Ð¸ÐºÐ»ÑŽÑ‡Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¾Ñ‚ Ð´Ñ€ÑƒÐ³Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸, Ð½ÐµÑÐ²ÑŠÑ€Ð·Ð°Ð½Ð¸ Ñ ÐºÐ¾Ð½ÐºÑ€ÐµÑ‚Ð½Ð¾Ñ‚Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  setting_unsubscribe: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸Ñ‚Ðµ Ð¼Ð¾Ð³Ð°Ñ‚ Ð´Ð° Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð²Ð°Ñ‚ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð¸Ñ‚Ðµ ÑÐ¸
+  setting_session_lifetime: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÐµÐ½ Ð¶Ð¸Ð²Ð¾Ñ‚ Ð½Ð° ÑÐµÑÐ¸Ð¸Ñ‚Ðµ
+  setting_session_timeout: Ð¢Ð°Ð¹Ð¼Ð°ÑƒÑ‚ Ð·Ð° Ð½ÐµÐ°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚ Ð¿Ñ€ÐµÐ´Ð¸ Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‚ÑÐ²Ð°Ð½Ðµ Ð½Ð° ÑÐµÑÐ¸Ð¸Ñ‚Ðµ
+  setting_thumbnails_enabled: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ð¼Ð¸Ð½Ð¸Ð°Ñ‚ÑŽÑ€Ð¸ Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½Ð¸Ñ‚Ðµ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ
+  setting_thumbnails_size: Ð Ð°Ð·Ð¼ÐµÑ€ Ð½Ð° Ð¼Ð¸Ð½Ð¸Ð°Ñ‚ÑŽÑ€Ð¸Ñ‚Ðµ (Ð² Ð¿Ð¸ÐºÑÐµÐ»Ð¸)
+  setting_non_working_week_days: ÐÐµ Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸ Ð´Ð½Ð¸
+  setting_jsonp_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð´Ñ€ÑŠÐ¶ÐºÐ° Ð½Ð° JSONP
+  setting_default_projects_tracker_ids: Ð¢Ñ€Ð°ÐºÐµÑ€Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ Ð·Ð° Ð½Ð¾Ð²Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+
+  permission_add_project: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  permission_add_subprojects: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  permission_edit_project: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  permission_close_project: Ð—Ð°Ñ‚Ð²Ð°Ñ€ÑÐ½Ðµ / Ð¾Ñ‚Ð²Ð°Ñ€ÑÐ½Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  permission_select_project_modules: Ð˜Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ð¸ Ð¼Ð¾Ð´ÑƒÐ»Ð¸
+  permission_manage_members: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ñ‡Ð»ÐµÐ½Ð¾Ð²ÐµÑ‚Ðµ (Ð½Ð° ÐµÐºÐ¸Ð¿)
+  permission_manage_project_activities: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð´ÐµÐ¹Ð½Ð¾ÑÑ‚Ð¸Ñ‚Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
+  permission_manage_versions: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð²ÐµÑ€ÑÐ¸Ð¸Ñ‚Ðµ
+  permission_manage_categories: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸Ñ‚Ðµ
+  permission_view_issues: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
+  permission_add_issues: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_edit_issues: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_manage_issue_relations: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð²Ñ€ÑŠÐ·ÐºÐ¸Ñ‚Ðµ Ð¼ÐµÐ¶Ð´Ñƒ Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
+  permission_set_own_issues_private: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸ Ð¸Ð»Ð¸ Ð»Ð¸Ñ‡Ð½Ð¸
+  permission_set_issues_private: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸ Ð¸Ð»Ð¸ Ð»Ð¸Ñ‡Ð½Ð¸
+  permission_add_issue_notes: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸
+  permission_edit_issue_notes: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸
+  permission_edit_own_issue_notes: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸ Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸
+  permission_view_private_notes: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð»Ð¸Ñ‡Ð½Ð¸ Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸
+  permission_set_notes_private: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ Ð½Ð° Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸Ñ‚Ðµ Ð»Ð¸Ñ‡Ð½Ð¸
+  permission_move_issues: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_delete_issues: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_manage_public_queries: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸Ñ‚Ðµ Ð·Ð°ÑÐ²ÐºÐ¸
+  permission_save_queries: Ð—Ð°Ð¿Ð¸Ñ Ð½Ð° Ð·Ð°Ð¿Ð¸Ñ‚Ð²Ð°Ð½Ð¸Ñ (queries)
+  permission_view_gantt: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¼Ñ€ÐµÐ¶Ð¾Ð² Ð³Ñ€Ð°Ñ„Ð¸Ðº
+  permission_view_calendar: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ð¸
+  permission_view_issue_watchers: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° ÑÐ¿Ð¸ÑÑŠÐº Ñ Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
+  permission_add_issue_watchers: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
+  permission_delete_issue_watchers: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
+  permission_log_time: Log spent time
+  permission_view_time_entries: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¸Ð·Ñ€Ð°Ð·Ñ…Ð¾Ð´Ð²Ð°Ð½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  permission_edit_time_entries: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° time logs
+  permission_edit_own_time_entries: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸Ñ‚Ðµ time logs
+  permission_manage_news: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð½Ð¾Ð²Ð¸Ð½Ð¸
+  permission_comment_news: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð½Ð¾Ð²Ð¸Ð½Ð¸
+  permission_view_documents: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  permission_add_documents: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  permission_edit_documents: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  permission_delete_documents: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  permission_manage_files: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
+  permission_view_files: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
+  permission_manage_wiki: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° wiki
+  permission_rename_wiki_pages: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ðµ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_delete_wiki_pages: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_view_wiki_pages: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° wiki
+  permission_view_wiki_edits: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° wiki Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ
+  permission_edit_wiki_pages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_delete_wiki_pages_attachments: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½Ð¸ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ ÐºÑŠÐ¼ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_protect_wiki_pages: Ð—Ð°ÐºÐ»ÑŽÑ‡Ð²Ð°Ð½Ðµ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_manage_repository: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
+  permission_browse_repository: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
+  permission_view_changesets: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° changesets
+  permission_commit_access: ÐŸÐ¾Ð²ÐµÑ€ÑÐ²Ð°Ð½Ðµ
+  permission_manage_boards: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° boards
+  permission_view_messages: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
+  permission_add_messages: ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
+  permission_edit_messages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
+  permission_edit_own_messages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸ ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
+  permission_delete_messages: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
+  permission_delete_own_messages: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸ ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
+  permission_export_wiki_pages: Ð•ÐºÑÐ¿Ð¾Ñ€Ñ‚ Ð½Ð° wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_manage_subtasks: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
+  permission_manage_related_issues: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð²Ñ€ÑŠÐ·ÐºÐ¸Ñ‚Ðµ Ð¼ÐµÐ¶Ð´Ñƒ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
+
+  project_module_issue_tracking: Ð¢Ñ€Ð°ÐºÐ¸Ð½Ð³
+  project_module_time_tracking: ÐžÑ‚Ð´ÐµÐ»ÑÐ½Ðµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
+  project_module_news: ÐÐ¾Ð²Ð¸Ð½Ð¸
+  project_module_documents: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  project_module_files: Ð¤Ð°Ð¹Ð»Ð¾Ð²Ðµ
+  project_module_wiki: Wiki
+  project_module_repository: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  project_module_boards: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
+  project_module_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
+  project_module_gantt: ÐœÑ€ÐµÐ¶Ð¾Ð² Ð³Ñ€Ð°Ñ„Ð¸Ðº
+
+  label_user: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
+  label_user_plural: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸
+  label_user_new: ÐÐ¾Ð² Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»
+  label_user_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼ÐµÐ½
+  label_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
+  label_project_new: ÐÐ¾Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_project_plural: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸
+  label_x_projects:
+    zero:  0 Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
+    one:   1 Ð¿Ñ€Ð¾ÐµÐºÑ‚
+    other: "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°"
+  label_project_all: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_project_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_new: ÐÐ¾Ð²Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_plural: Ð—Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_view_all: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issues_by: "Ð—Ð°Ð´Ð°Ñ‡Ð¸ Ð¿Ð¾ %{value}"
+  label_issue_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_updated: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_note_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð° Ð±ÐµÐ»ÐµÐ¶ÐºÐ°
+  label_issue_status_updated: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð¾ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
+  label_issue_priority_updated: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
+  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_new: ÐÐ¾Ð² Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  label_document_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_role: Ð Ð¾Ð»Ñ
+  label_role_plural: Ð Ð¾Ð»Ð¸
+  label_role_new: ÐÐ¾Ð²Ð° Ñ€Ð¾Ð»Ñ
+  label_role_and_permissions: Ð Ð¾Ð»Ð¸ Ð¸ Ð¿Ñ€Ð°Ð²Ð°
+  label_role_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼ÐµÐ½
+  label_role_non_member: ÐÐµ Ñ‡Ð»ÐµÐ½
+  label_member: Ð§Ð»ÐµÐ½
+  label_member_new: ÐÐ¾Ð² Ñ‡Ð»ÐµÐ½
+  label_member_plural: Ð§Ð»ÐµÐ½Ð¾Ð²Ðµ
+  label_tracker: Ð¢Ñ€Ð°ÐºÐµÑ€
+  label_tracker_plural: Ð¢Ñ€Ð°ÐºÐµÑ€Ð¸
+  label_tracker_new: ÐÐ¾Ð² Ñ‚Ñ€Ð°ÐºÐµÑ€
+  label_workflow: Ð Ð°Ð±Ð¾Ñ‚ÐµÐ½ Ð¿Ñ€Ð¾Ñ†ÐµÑ
+  label_issue_status: Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_status_plural: Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ñ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_status_new: ÐÐ¾Ð²Ð¾ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
+  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_category_new: ÐÐ¾Ð²Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
+  label_custom_field: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¾ Ð¿Ð¾Ð»Ðµ
+  label_custom_field_plural: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ Ð¿Ð¾Ð»ÐµÑ‚Ð°
+  label_custom_field_new: ÐÐ¾Ð²Ð¾ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¾ Ð¿Ð¾Ð»Ðµ
+  label_enumerations: Ð¡Ð¿Ð¸ÑÑŠÑ†Ð¸
+  label_enumeration_new: ÐÐ¾Ð²Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚
+  label_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
+  label_information_plural: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
+  label_please_login: Ð’Ñ…Ð¾Ð´
+  label_register: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
+  label_login_with_open_id_option: Ð¸Ð»Ð¸ Ð²Ñ…Ð¾Ð´ Ñ‡Ñ€ÐµÐ· OpenID
+  label_password_lost: Ð—Ð°Ð±Ñ€Ð°Ð²ÐµÐ½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
+  label_home: ÐÐ°Ñ‡Ð°Ð»Ð¾
+  label_my_page: Ð›Ð¸Ñ‡Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  label_my_account: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
+  label_my_projects: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸, Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑƒÑ‡Ð°ÑÑ‚Ð²Ð°Ð¼
+  label_my_page_block: Ð‘Ð»Ð¾ÐºÐ¾Ð²Ðµ Ð² Ð»Ð¸Ñ‡Ð½Ð°Ñ‚Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  label_administration: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
+  label_login: Ð’Ñ…Ð¾Ð´
+  label_logout: Ð˜Ð·Ñ…Ð¾Ð´
+  label_help: ÐŸÐ¾Ð¼Ð¾Ñ‰
+  label_reported_issues: ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_assigned_to_me_issues: Ð’ÑŠÐ·Ð»Ð¾Ð¶ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½
+  label_last_login: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¾ ÑÐ²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ
+  label_registered_on: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
+  label_activity: Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚
+  label_overall_activity: Ð¦ÑÐ»Ð¾ÑÑ‚Ð½Ð° Ð´ÐµÐ¹Ð½Ð¾ÑÑ‚
+  label_user_activity: "ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚ Ð½Ð° %{value}"
+  label_new: ÐÐ¾Ð²
+  label_logged_as: Ð—Ð´Ñ€Ð°Ð²ÐµÐ¹Ñ‚Ðµ,
+  label_environment: Ð¡Ñ€ÐµÐ´Ð°
+  label_authentication: ÐžÑ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
+  label_auth_source: ÐÐ°Ñ‡Ð¸Ð½ Ð½Ð° Ð¾Ñ‚Ð¾Ñ€Ð¾Ð·Ð°Ñ†Ð¸Ñ
+  label_auth_source_new: ÐÐ¾Ð² Ð½Ð°Ñ‡Ð¸Ð½ Ð½Ð° Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
+  label_auth_source_plural: ÐÐ°Ñ‡Ð¸Ð½Ð¸ Ð½Ð° Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
+  label_subproject_plural: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_subproject_new: ÐÐ¾Ð² Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_and_its_subprojects: "%{value} Ð¸ Ð½ÐµÐ³Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
+  label_min_max_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° - Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð´ÑŠÐ»Ð¶Ð¸Ð½Ð°
+  label_list: Ð¡Ð¿Ð¸ÑÑŠÐº
+  label_date: Ð”Ð°Ñ‚Ð°
+  label_integer: Ð¦ÐµÐ»Ð¾Ñ‡Ð¸ÑÐ»ÐµÐ½
+  label_float: Ð”Ñ€Ð¾Ð±Ð½Ð¾
+  label_boolean: Ð§ÐµÐºÐ±Ð¾ÐºÑ
+  label_string: Ð¢ÐµÐºÑÑ‚
+  label_text: Ð”ÑŠÐ»ÑŠÐ³ Ñ‚ÐµÐºÑÑ‚
+  label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
+  label_attribute_plural: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸
+  label_no_data: ÐÑÐ¼Ð° Ð¸Ð·Ñ…Ð¾Ð´Ð½Ð¸ Ð´Ð°Ð½Ð½Ð¸
+  label_change_status: ÐŸÑ€Ð¾Ð¼ÑÐ½Ð° Ð½Ð° ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸ÐµÑ‚Ð¾
+  label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ
+  label_attachment: Ð¤Ð°Ð¹Ð»
+  label_attachment_new: ÐÐ¾Ð² Ñ„Ð°Ð¹Ð»
+  label_attachment_delete: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ
+  label_attachment_plural: Ð¤Ð°Ð¹Ð»Ð¾Ð²Ðµ
+  label_file_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½ Ñ„Ð°Ð¹Ð»
+  label_report: Ð¡Ð¿Ñ€Ð°Ð²ÐºÐ°
+  label_report_plural: Ð¡Ð¿Ñ€Ð°Ð²ÐºÐ¸
+  label_news: ÐÐ¾Ð²Ð¸Ð½Ð¸
+  label_news_new: Ð”Ð¾Ð±Ð°Ð²Ð¸
+  label_news_plural: ÐÐ¾Ð²Ð¸Ð½Ð¸
+  label_news_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ð½Ð¾Ð²Ð¸Ð½Ð¸
+  label_news_view_all: Ð’Ð¸Ð¶ Ð²ÑÐ¸Ñ‡ÐºÐ¸
+  label_news_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð° Ð½Ð¾Ð²Ð¸Ð½Ð°
+  label_news_comment_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€ ÐºÑŠÐ¼ Ð½Ð¾Ð²Ð¸Ð½Ð°
+  label_settings: ÐÐ°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸
+  label_overview: ÐžÐ±Ñ‰ Ð¸Ð·Ð³Ð»ÐµÐ´
+  label_version: Ð’ÐµÑ€ÑÐ¸Ñ
+  label_version_new: ÐÐ¾Ð²Ð° Ð²ÐµÑ€ÑÐ¸Ñ
+  label_version_plural: Ð’ÐµÑ€ÑÐ¸Ð¸
+  label_close_versions: Ð—Ð°Ñ‚Ð²Ð°Ñ€ÑÐ½Ðµ Ð½Ð° Ð·Ð°Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð²ÐµÑ€ÑÐ¸Ð¸
+  label_confirmation: ÐžÐ´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ðµ
+  label_export_to: Ð•ÐºÑÐ¿Ð¾Ñ€Ñ‚ ÐºÑŠÐ¼
+  label_read: Read...
+  label_public_projects: ÐŸÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_open_issues: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+  label_open_issues_plural: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+  label_closed_issues: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+  label_closed_issues_plural: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+  label_x_open_issues_abbr_on_total:
+    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸ / %{total}
+    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° / %{total}
+    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸ / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸"
+  label_x_closed_issues_abbr:
+    zero:  0 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+    one:   1 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+    other: "%{count} Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸"
+  label_x_issues:
+    zero:  0 Ð·Ð°Ð´Ð°Ñ‡Ð¸
+    one:   1 Ð·Ð°Ð´Ð°Ñ‡Ð°
+    other: "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸"
+  label_total: ÐžÐ±Ñ‰Ð¾
+  label_total_time: ÐžÐ±Ñ‰Ð¾
+  label_permissions: ÐŸÑ€Ð°Ð²Ð°
+  label_current_status: Ð¢ÐµÐºÑƒÑ‰Ð¾ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
+  label_new_statuses_allowed: ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ñ
+  label_all: Ð²ÑÐ¸Ñ‡ÐºÐ¸
+  label_any: Ð±ÐµÐ· Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ
+  label_none: Ð½Ð¸ÐºÐ°ÐºÐ²Ð¸
+  label_nobody: Ð½Ð¸ÐºÐ¾Ð¹
+  label_next: Ð¡Ð»ÐµÐ´Ð²Ð°Ñ‰
+  label_previous: ÐŸÑ€ÐµÐ´Ð¸ÑˆÐµÐ½
+  label_used_by: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° ÑÐµ Ð¾Ñ‚
+  label_details: Ð”ÐµÑ‚Ð°Ð¹Ð»Ð¸
+  label_add_note: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð±ÐµÐ»ÐµÐ¶ÐºÐ°
+  label_per_page: ÐÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
+  label_months_from: Ð¼ÐµÑÐµÑ†Ð° Ð¾Ñ‚
+  label_gantt: ÐœÑ€ÐµÐ¶Ð¾Ð² Ð³Ñ€Ð°Ñ„Ð¸Ðº
+  label_internal: Ð’ÑŠÑ‚Ñ€ÐµÑˆÐµÐ½
+  label_last_changes: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸ %{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
+  label_change_view_all: Ð’Ð¸Ð¶ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸
+  label_personalize_page: ÐŸÐµÑ€ÑÐ¾Ð½Ð°Ð»Ð¸Ð·Ð¸Ñ€Ð°Ð½Ðµ
+  label_comment: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  label_comment_plural: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
+  label_x_comments:
+    zero: 0 ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð°
+    one: 1 ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+    other: "%{count} ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð°"
+  label_comment_add: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  label_comment_added: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  label_comment_delete: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
+  label_query: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ° ÑÐ¿Ñ€Ð°Ð²ÐºÐ°
+  label_query_plural: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ ÑÐ¿Ñ€Ð°Ð²ÐºÐ¸
+  label_query_new: ÐÐ¾Ð²Ð° Ð·Ð°ÑÐ²ÐºÐ°
+  label_my_queries: ÐœÐ¾Ð¸Ñ‚Ðµ Ð·Ð°ÑÐ²ÐºÐ¸
+  label_filter_add: Ð”Ð¾Ð±Ð°Ð²Ð¸ Ñ„Ð¸Ð»Ñ‚ÑŠÑ€
+  label_filter_plural: Ð¤Ð¸Ð»Ñ‚Ñ€Ð¸
+  label_equals: Ðµ
+  label_not_equals: Ð½Ðµ Ðµ
+  label_in_less_than: ÑÐ»ÐµÐ´ Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚
+  label_in_more_than: ÑÐ»ÐµÐ´ Ð¿Ð¾Ð²ÐµÑ‡Ðµ Ð¾Ñ‚
+  label_in_the_next_days: Ð² ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ‚Ðµ
+  label_in_the_past_days: Ð² Ð¿Ñ€ÐµÐ´Ð¸ÑˆÐ½Ð¸Ñ‚Ðµ
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  label_between: Ð¼ÐµÐ¶Ð´Ñƒ
+  label_in: Ð² ÑÐ»ÐµÐ´Ð²Ð°Ñ‰Ð¸Ñ‚Ðµ
+  label_today: Ð´Ð½ÐµÑ
+  label_all_time: Ð²ÑÐ¸Ñ‡ÐºÐ¸
+  label_yesterday: Ð²Ñ‡ÐµÑ€Ð°
+  label_this_week: Ñ‚Ð°Ð·Ð¸ ÑÐµÐ´Ð¼Ð¸Ñ†Ð°
+  label_last_week: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð°Ñ‚Ð° ÑÐµÐ´Ð¼Ð¸Ñ†Ð°
+  label_last_n_weeks: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ‚Ðµ %{count} ÑÐµÐ´Ð¼Ð¸Ñ†Ð¸
+  label_last_n_days: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ‚Ðµ %{count} Ð´Ð½Ð¸"
+  label_this_month: Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð¼ÐµÑÐµÑ†
+  label_last_month: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð¼ÐµÑÐµÑ†
+  label_this_year: Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ‚Ð° Ð³Ð¾Ð´Ð¸Ð½Ð°
+  label_date_range: ÐŸÐµÑ€Ð¸Ð¾Ð´
+  label_less_than_ago: Ð¿Ñ€ÐµÐ´Ð¸ Ð¿Ð¾-Ð¼Ð°Ð»ÐºÐ¾ Ð¾Ñ‚
+  label_more_than_ago: Ð¿Ñ€ÐµÐ´Ð¸ Ð¿Ð¾Ð²ÐµÑ‡Ðµ Ð¾Ñ‚
+  label_ago: Ð¿Ñ€ÐµÐ´Ð¸
+  label_contains: ÑÑŠÐ´ÑŠÑ€Ð¶Ð°
+  label_not_contains: Ð½Ðµ ÑÑŠÐ´ÑŠÑ€Ð¶Ð°
+  label_any_issues_in_project: Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¾Ñ‚ Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_any_issues_not_in_project: Ð·Ð°Ð´Ð°Ñ‡Ð¸, ÐºÐ¾Ð¸Ñ‚Ð¾ Ð½Ðµ ÑÐ° Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_no_issues_in_project: Ð½Ð¸ÐºÐ°ÐºÐ²Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_day_plural: Ð´Ð½Ð¸
+  label_repository: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  label_repository_new: ÐÐ¾Ð²Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  label_repository_plural: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
+  label_browse: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ
+  label_branch: Ñ€Ð°Ð±Ð¾Ñ‚ÐµÐ½ Ð²Ð°Ñ€Ð¸Ð°Ð½Ñ‚
+  label_tag: Ð’ÐµÑ€ÑÐ¸Ñ
+  label_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ
+  label_revision_plural: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  label_revision_id: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ %{value}
+  label_associated_revisions: ÐÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð°Ð½Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  label_added: Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð¾
+  label_modified: Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½Ð¾
+  label_copied: ÐºÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ð¾
+  label_renamed: Ð¿Ñ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð¾
+  label_deleted: Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚Ð¾
+  label_latest_revision: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ
+  label_latest_revision_plural: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  label_view_revisions: Ð’Ð¸Ð¶ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸Ñ‚Ðµ
+  label_view_all_revisions: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  label_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð°
+  label_sort_highest: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ð¹-Ð³Ð¾Ñ€Ðµ
+  label_sort_higher: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð¿Ð¾-Ð³Ð¾Ñ€Ðµ
+  label_sort_lower: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð¿Ð¾-Ð´Ð¾Ð»Ñƒ
+  label_sort_lowest: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ð¹-Ð´Ð¾Ð»Ñƒ
+  label_roadmap: ÐŸÑŠÑ‚Ð½Ð° ÐºÐ°Ñ€Ñ‚Ð°
+  label_roadmap_due_in: "Ð˜Ð·Ð»Ð¸Ð·Ð° ÑÐ»ÐµÐ´ %{value}"
+  label_roadmap_overdue: "%{value} Ð·Ð°ÐºÑŠÑÐ½ÐµÐ½Ð¸Ðµ"
+  label_roadmap_no_issues: ÐÑÐ¼Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð·Ð° Ñ‚Ð°Ð·Ð¸ Ð²ÐµÑ€ÑÐ¸Ñ
+  label_search: Ð¢ÑŠÑ€ÑÐµÐ½Ðµ
+  label_result_plural: PÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸
+  label_all_words: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð´ÑƒÐ¼Ð¸
+  label_wiki: Wiki
+  label_wiki_edit: Wiki Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ñ
+  label_wiki_edit_plural: Wiki Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
+  label_wiki_page: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  label_wiki_page_plural: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  label_index_by_title: Ð˜Ð½Ð´ÐµÐºÑ
+  label_index_by_date: Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Ð´Ð°Ñ‚Ð°
+  label_current_version: Ð¢ÐµÐºÑƒÑ‰Ð° Ð²ÐµÑ€ÑÐ¸Ñ
+  label_preview: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
+  label_feed_plural: Ð•Ð¼Ð¸ÑÐ¸Ð¸
+  label_changes_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸
+  label_issue_tracking: Ð¢Ñ€Ð°ÐºÐ¸Ð½Ð³
+  label_spent_time: ÐžÑ‚Ð´ÐµÐ»ÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_overall_spent_time: ÐžÐ±Ñ‰Ð¾ ÑƒÐ¿Ð¾Ñ‚Ñ€ÐµÐ±ÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_f_hour: "%{value} Ñ‡Ð°Ñ"
+  label_f_hour_plural: "%{value} Ñ‡Ð°ÑÐ°"
+  label_time_tracking: ÐžÑ‚Ð´ÐµÐ»ÑÐ½Ðµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
+  label_change_plural: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸
+  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ¸
+  label_commits_per_month: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸ Ð¿Ð¾ Ð¼ÐµÑÐµÑ†Ð¸
+  label_commits_per_author: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸ Ð¿Ð¾ Ð°Ð²Ñ‚Ð¾Ñ€
+  label_diff: diff
+  label_view_diff: Ð’Ð¸Ð¶ Ñ€Ð°Ð·Ð»Ð¸ÐºÐ¸Ñ‚Ðµ
+  label_diff_inline: Ñ…Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»Ð½Ð¾
+  label_diff_side_by_side: Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»Ð½Ð¾
+  label_options: ÐžÐ¿Ñ†Ð¸Ð¸
+  label_copy_workflow_from: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ð¹ Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð¾Ñ‚
+  label_permissions_report: Ð¡Ð¿Ñ€Ð°Ð²ÐºÐ° Ð·Ð° Ð¿Ñ€Ð°Ð²Ð°
+  label_watched_issues: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ð²Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_related_issues: Ð¡Ð²ÑŠÑ€Ð·Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_applied_status: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²ÐµÐ½Ð¾ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
+  label_loading: Ð—Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½Ðµ...
+  label_relation_new: ÐÐ¾Ð²Ð° Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ
+  label_relation_delete: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ
+  label_relates_to: ÑÐ²ÑŠÑ€Ð·Ð°Ð½Ð° ÑÑŠÑ
+  label_duplicates: Ð´ÑƒÐ±Ð»Ð¸Ñ€Ð°
+  label_duplicated_by: Ð´ÑƒÐ±Ð»Ð¸Ñ€Ð°Ð½Ð° Ð¾Ñ‚
+  label_blocks: Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð°
+  label_blocked_by: Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð°Ð½Ð° Ð¾Ñ‚
+  label_precedes: Ð¿Ñ€ÐµÐ´ÑˆÐµÑÑ‚Ð²Ð°
+  label_follows: Ð¸Ð·Ð¿ÑŠÐ»Ð½ÑÐ²Ð° ÑÐµ ÑÐ»ÐµÐ´
+  label_copied_to: ÐºÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ð° Ð²
+  label_copied_from: ÐºÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ð° Ð¾Ñ‚
+  label_end_to_start: ÐºÑ€Ð°Ð¹ ÐºÑŠÐ¼ Ð½Ð°Ñ‡Ð°Ð»Ð¾
+  label_end_to_end: ÐºÑ€Ð°Ð¹ ÐºÑŠÐ¼ ÐºÑ€Ð°Ð¹
+  label_start_to_start: Ð½Ð°Ñ‡Ð°Ð»Ð¾ ÐºÑŠÐ¼ Ð½Ð°Ñ‡Ð°Ð»Ð¾
+  label_start_to_end: Ð½Ð°Ñ‡Ð°Ð»Ð¾ ÐºÑŠÐ¼ ÐºÑ€Ð°Ð¹
+  label_stay_logged_in: Ð—Ð°Ð¿Ð¾Ð¼Ð½Ð¸ Ð¼Ðµ
+  label_disabled: Ð·Ð°Ð±Ñ€Ð°Ð½ÐµÐ½Ð¾
+  label_show_completed_versions: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ñ€ÐµÐ°Ð»Ð¸Ð·Ð¸Ñ€Ð°Ð½Ð¸ Ð²ÐµÑ€ÑÐ¸Ð¸
+  label_me: Ð°Ð·
+  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
+  label_board_new: ÐÐ¾Ð² Ñ„Ð¾Ñ€ÑƒÐ¼
+  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
+  label_board_locked: Ð—Ð°ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°
+  label_board_sticky: Sticky
+  label_topic_plural: Ð¢ÐµÐ¼Ð¸
+  label_message_plural: Ð¡ÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
+  label_message_last: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¾ ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
+  label_message_new: ÐÐ¾Ð²Ð° Ñ‚ÐµÐ¼Ð°
+  label_message_posted: Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð¾ ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
+  label_reply_plural: ÐžÑ‚Ð³Ð¾Ð²Ð¾Ñ€Ð¸
+  label_send_information: Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÑÑ‚Ð° Ð´Ð¾ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ
+  label_year: Ð“Ð¾Ð´Ð¸Ð½Ð°
+  label_month: ÐœÐµÑÐµÑ†
+  label_week: Ð¡ÐµÐ´Ð¼Ð¸Ñ†Ð°
+  label_date_from: ÐžÑ‚
+  label_date_to: Ð”Ð¾
+  label_language_based: Ð’ Ð·Ð°Ð²Ð¸ÑÐ¸Ð¼Ð¾ÑÑ‚ Ð¾Ñ‚ ÐµÐ·Ð¸ÐºÐ°
+  label_sort_by: "Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ Ð¿Ð¾ %{value}"
+  label_send_test_email: Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° Ñ‚ÐµÑÑ‚Ð¾Ð² e-mail
+  label_feeds_access_key: RSS access ÐºÐ»ÑŽÑ‡
+  label_missing_feeds_access_key: Ð›Ð¸Ð¿ÑÐ²Ð°Ñ‰ RSS ÐºÐ»ÑŽÑ‡ Ð·Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿
+  label_feeds_access_key_created_on: "%{value} Ð¾Ñ‚ ÑÑŠÐ·Ð´Ð°Ð²Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° RSS ÐºÐ»ÑŽÑ‡Ð°"
+  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ð¸
+  label_added_time_by: "ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ð½Ð° Ð¾Ñ‚ %{author} Ð¿Ñ€ÐµÐ´Ð¸ %{age}"
+  label_updated_time_by: "ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð° Ð¾Ñ‚ %{author} Ð¿Ñ€ÐµÐ´Ð¸ %{age}"
+  label_updated_time: "ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð° Ð¿Ñ€ÐµÐ´Ð¸ %{value}"
+  label_jump_to_a_project: ÐŸÑ€Ð¾ÐµÐºÑ‚...
+  label_file_plural: Ð¤Ð°Ð¹Ð»Ð¾Ð²Ðµ
+  label_changeset_plural: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  label_default_columns: ÐŸÐ¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
+  label_no_change_option: (Ð‘ÐµÐ· Ð¿Ñ€Ð¾Ð¼ÑÐ½Ð°)
+  label_bulk_edit_selected_issues: Ð“Ñ€ÑƒÐ¿Ð¾Ð²Ð¾ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_bulk_edit_selected_time_entries: Ð“Ñ€ÑƒÐ¿Ð¾Ð²Ð¾ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð·Ð° Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_theme: Ð¢ÐµÐ¼Ð°
+  label_default: ÐŸÐ¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
+  label_search_titles_only: Ð¡Ð°Ð¼Ð¾ Ð² Ð·Ð°Ð³Ð»Ð°Ð²Ð¸ÑÑ‚Ð°
+  label_user_mail_option_all: "Ð—Ð° Ð²ÑÑÐºÐ¾ ÑÑŠÐ±Ð¸Ñ‚Ð¸Ðµ Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ, Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑƒÑ‡Ð°ÑÑ‚Ð²Ð°Ð¼"
+  label_user_mail_option_selected: "Ð—Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸ ÑÑŠÐ±Ð¸Ñ‚Ð¸Ñ ÑÐ°Ð¼Ð¾ Ð² Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸..."
+  label_user_mail_option_none: "Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ð²Ð°Ð½Ð¸ Ð¸Ð»Ð¸ Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑƒÑ‡Ð°ÑÑ‚Ð²Ð°Ð¼ (Ð°Ð²Ñ‚Ð¾Ñ€ Ð¸Ð»Ð¸ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½)"
+  label_user_mail_option_only_my_events: Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ð½ÐµÑ‰Ð°, Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑÑŠÐ¼ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½/Ð°
+  label_user_mail_option_only_assigned: Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ð½ÐµÑ‰Ð°, Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½
+  label_user_mail_option_only_owner: Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ð½ÐµÑ‰Ð°, Ð½Ð° ÐºÐ¾Ð¸Ñ‚Ð¾ Ð°Ð· ÑÑŠÐ¼ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸Ðº
+  label_user_mail_no_self_notified: "ÐÐµ Ð¸ÑÐºÐ°Ð¼ Ð¸Ð·Ð²ÐµÑÑ‚Ð¸Ñ Ð·Ð° Ð¸Ð·Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸ Ð¾Ñ‚ Ð¼ÐµÐ½ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
+  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð° Ð¿Ð¾ email
+  label_registration_manual_activation: Ñ€ÑŠÑ‡Ð½Ð¾ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ
+  label_registration_automatic_activation: Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ
+  label_display_per_page: "ÐÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¿Ð¾: %{value}"
+  label_age: Ð’ÑŠÐ·Ñ€Ð°ÑÑ‚
+  label_change_properties: ÐŸÑ€Ð¾Ð¼ÑÐ½Ð° Ð½Ð° Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸
+  label_general: ÐžÑÐ½Ð¾Ð²Ð½Ð¸
+  label_more: ÐžÑ‰Ðµ
+  label_scm: SCM (Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð° Ð·Ð° ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð» Ð½Ð° Ð²ÐµÑ€ÑÐ¸Ð¸Ñ‚Ðµ)
+  label_plugins: ÐŸÐ»ÑŠÐ³Ð¸Ð½Ð¸
+  label_ldap_authentication: LDAP Ð¾Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ
+  label_downloads_abbr: D/L
+  label_optional_description: ÐÐµÐ·Ð°Ð´ÑŠÐ»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾ Ð¾Ð¿Ð¸ÑÐ°Ð½Ð¸Ðµ
+  label_add_another_file: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð´Ñ€ÑƒÐ³ Ñ„Ð°Ð¹Ð»
+  label_preferences: ÐŸÑ€ÐµÐ´Ð¿Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð¸Ñ
+  label_chronological_order: Ð¥Ñ€Ð¾Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ‡ÐµÐ½ Ñ€ÐµÐ´
+  label_reverse_chronological_order: ÐžÐ±Ñ€Ð°Ñ‚ÐµÐ½ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ‡ÐµÐ½ Ñ€ÐµÐ´
+  label_planning: ÐŸÐ»Ð°Ð½Ð¸Ñ€Ð°Ð½Ðµ
+  label_incoming_emails: Ð’Ñ…Ð¾Ð´ÑÑ‰Ð¸ e-mail-Ð¸
+  label_generate_key: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÐºÐ»ÑŽÑ‡
+  label_issue_watchers: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
+  label_example: ÐŸÑ€Ð¸Ð¼ÐµÑ€
+  label_display: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ðµ
+  label_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ
+  label_ascending: ÐÐ°Ñ€Ð°ÑÑ‚Ð²Ð°Ñ‰
+  label_descending: ÐÐ°Ð¼Ð°Ð»ÑÐ²Ð°Ñ‰
+  label_date_from_to: ÐžÑ‚ %{start} Ð´Ð¾ %{end}
+  label_wiki_content_added: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð±ÐµÑˆÐµ Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð°
+  label_wiki_content_updated: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð±ÐµÑˆÐµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð°
+  label_group: Ð“Ñ€ÑƒÐ¿Ð°
+  label_group_plural: Ð“Ñ€ÑƒÐ¿Ð¸
+  label_group_new: ÐÐ¾Ð²Ð° Ð³Ñ€ÑƒÐ¿Ð°
+  label_time_entry_plural: Ð˜Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_version_sharing_none: ÐÐµ ÑÐ¿Ð¾Ð´ÐµÐ»ÐµÐ½
+  label_version_sharing_descendants: Ð¡ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_version_sharing_hierarchy: Ð¡ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ð° Ð¹ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ
+  label_version_sharing_tree: Ð¡ Ð´ÑŠÑ€Ð²Ð¾ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ
+  label_version_sharing_system: Ð¡ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_update_issue_done_ratios: ÐžÐ±Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾Ñ†ÐµÐ½Ñ‚Ð° Ð½Ð° Ð·Ð°Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_copy_source: Ð˜Ð·Ñ‚Ð¾Ñ‡Ð½Ð¸Ðº
+  label_copy_target: Ð¦ÐµÐ»
+  label_copy_same_as_target: Ð¡ÑŠÑ‰Ð¾ ÐºÐ°Ñ‚Ð¾ Ñ†ÐµÐ»Ñ‚Ð°
+  label_display_used_statuses_only: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ðµ ÑÐ°Ð¼Ð¾ Ð½Ð° ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸ÑÑ‚Ð°, Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½Ð¸ Ð¾Ñ‚ Ñ‚Ð¾Ð·Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€
+  label_api_access_key: API ÐºÐ»ÑŽÑ‡ Ð·Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿
+  label_missing_api_access_key: Ð›Ð¸Ð¿ÑÐ²Ð°Ñ‰ API ÐºÐ»ÑŽÑ‡
+  label_api_access_key_created_on: API ÐºÐ»ÑŽÑ‡ Ð·Ð° Ð´Ð¾ÑÑ‚ÑŠÐ¿ Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½ Ð¿Ñ€ÐµÐ´Ð¸ %{value}
+  label_profile: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
+  label_subtask_plural: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_project_copy_notifications: Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° Send e-mail Ð¸Ð·Ð²ÐµÑÑ‚Ð¸Ñ Ð¿Ð¾ Ð²Ñ€ÐµÐ¼Ðµ Ð½Ð° ÐºÐ¾Ð¿Ð¸Ñ€Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
+  label_principal_search: "Ð¢ÑŠÑ€ÑÐµÐ½Ðµ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» Ð¸Ð»Ð¸ Ð³Ñ€ÑƒÐ¿Ð°:"
+  label_user_search: "Ð¢ÑŠÑ€ÑÐµÐ½Ðµ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»:"
+  label_additional_workflow_transitions_for_author: ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ° Ð´Ð¾Ð¿ÑŠÐ»Ð½Ð¸Ñ‚ÐµÐ»Ð½Ð¸ Ð¿Ñ€ÐµÑ…Ð¾Ð´Ð¸, ÐºÐ¾Ð³Ð°Ñ‚Ð¾ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÑ‚ Ðµ Ð°Ð²Ñ‚Ð¾Ñ€ÑŠÑ‚
+  label_additional_workflow_transitions_for_assignee:  ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ° Ð´Ð¾Ð¿ÑŠÐ»Ð½Ð¸Ñ‚ÐµÐ»Ð½Ð¸ Ð¿Ñ€ÐµÑ…Ð¾Ð´Ð¸, ÐºÐ¾Ð³Ð°Ñ‚Ð¾ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»ÑÑ‚ Ðµ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÑÑ‚ ÐºÑŠÐ¼ Ð·Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð°
+  label_issues_visibility_all: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issues_visibility_public: Ð’ÑÐ¸Ñ‡ÐºÐ¸ Ð½Ðµ-Ð»Ð¸Ñ‡Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issues_visibility_own: Ð—Ð°Ð´Ð°Ñ‡Ð¸, ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½Ð¸ Ð¾Ñ‚ Ð¸Ð»Ð¸ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ
+  label_git_report_last_commit: Ð˜Ð·Ð²ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¾Ñ‚Ð¾ Ð¿Ð¾Ð²ÐµÑ€ÑÐ²Ð°Ð½Ðµ Ð·Ð° Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ Ð¸ Ð¿Ð°Ð¿ÐºÐ¸
+  label_parent_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»
+  label_child_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ Ð½Ð°ÑÐ»ÐµÐ´Ð½Ð¸Ðº
+  label_export_options: "%{export_format} Ð¾Ð¿Ñ†Ð¸Ð¸ Ð·Ð° ÐµÐºÑÐ¿Ð¾Ñ€Ñ‚"
+  label_copy_attachments: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½Ð¸Ñ‚Ðµ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
+  label_copy_subtasks: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Ð—Ð°Ð²ÑŠÑ€ÑˆÐµÐ½Ð¸ Ð²ÐµÑ€ÑÐ¸Ð¸
+  label_search_for_watchers: Ð¢ÑŠÑ€ÑÐµÐ½Ðµ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸ Ð·Ð° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
+  label_session_expiration: Ð˜Ð·Ñ‚Ð¸Ñ‡Ð°Ð½Ðµ Ð½Ð° ÑÐµÑÐ¸Ð¸Ñ‚Ðµ
+  label_show_closed_projects: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_status_transitions: ÐŸÑ€ÐµÑ…Ð¾Ð´Ð¸ Ð¼ÐµÐ¶Ð´Ñƒ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸ÑÑ‚Ð°
+  label_fields_permissions: Ð’Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚ Ð½Ð° Ð¿Ð¾Ð»ÐµÑ‚Ð°Ñ‚Ð°
+  label_readonly: Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ñ‡ÐµÑ‚ÐµÐ½Ðµ
+  label_required: Ð—Ð°Ð´ÑŠÐ»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_issue: Issue's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_user: User's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_cross_project_descendants: Ð¡ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_cross_project_tree: Ð¡ Ð´ÑŠÑ€Ð²Ð¾ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ
+  label_cross_project_hierarchy: Ð¡ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ð° Ð¹ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ
+  label_cross_project_system: Ð¡ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_gantt_progress_line: Ð›Ð¸Ð½Ð¸Ñ Ð½Ð° Ð¸Ð·Ð¿ÑŠÐ»Ð½ÐµÐ½Ð¸ÐµÑ‚Ð¾
+
+  button_login: Ð’Ñ…Ð¾Ð´
+  button_submit: Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ
+  button_save: Ð—Ð°Ð¿Ð¸Ñ
+  button_check_all: Ð˜Ð·Ð±Ð¾Ñ€ Ð½Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸
+  button_uncheck_all: Ð˜Ð·Ñ‡Ð¸ÑÑ‚Ð²Ð°Ð½Ðµ Ð½Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸
+  button_collapse_all: Ð¡ÐºÑ€Ð¸Ð²Ð°Ð½Ðµ Ð²ÑÐ¸Ñ‡ÐºÐ¸
+  button_expand_all: Ð Ð°Ð·Ð³ÑŠÐ²Ð°Ð½Ðµ Ð²ÑÐ¸Ñ‡ÐºÐ¸
+  button_delete: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ
+  button_create: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ
+  button_create_and_continue: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð¸ Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð°Ð²Ð°Ð½Ðµ
+  button_test: Ð¢ÐµÑÑ‚
+  button_edit: Ð ÐµÐ´Ð°ÐºÑ†Ð¸Ñ
+  button_edit_associated_wikipage: "Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð°ÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð°Ð½Ð°Ñ‚Ð° Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°: %{page_title}"
+  button_add: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ
+  button_change: ÐŸÑ€Ð¾Ð¼ÑÐ½Ð°
+  button_apply: ÐŸÑ€Ð¸Ð»Ð¾Ð¶Ð¸
+  button_clear: Ð˜Ð·Ñ‡Ð¸ÑÑ‚Ð¸
+  button_lock: Ð—Ð°ÐºÐ»ÑŽÑ‡Ð²Ð°Ð½Ðµ
+  button_unlock: ÐžÑ‚ÐºÐ»ÑŽÑ‡Ð²Ð°Ð½Ðµ
+  button_download: Ð˜Ð·Ñ‚ÐµÐ³Ð»ÑÐ½Ðµ
+  button_list: Ð¡Ð¿Ð¸ÑÑŠÐº
+  button_view: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
+  button_move: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð²Ð°Ð½Ðµ
+  button_move_and_follow: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð²Ð°Ð½Ðµ Ð¸ Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð°Ð²Ð°Ð½Ðµ
+  button_back: ÐÐ°Ð·Ð°Ð´
+  button_cancel: ÐžÑ‚ÐºÐ°Ð·
+  button_activate: ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ
+  button_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ
+  button_log_time: ÐžÑ‚Ð´ÐµÐ»ÑÐ½Ðµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
+  button_rollback: Ð’ÑŠÑ€Ð½Ð¸ ÑÐµ ÐºÑŠÐ¼ Ñ‚Ð°Ð·Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ
+  button_watch: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ð²Ð°Ð½Ðµ
+  button_unwatch: ÐšÑ€Ð°Ð¹ Ð½Ð° Ð½Ð°Ð±Ð»ÑŽÐ´ÐµÐ½Ð¸ÐµÑ‚Ð¾
+  button_reply: ÐžÑ‚Ð³Ð¾Ð²Ð¾Ñ€
+  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ
+  button_unarchive: Ð Ð°Ð·Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½Ðµ
+  button_reset: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð°Ð½Ð¾Ð²Ð¾
+  button_rename: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ðµ
+  button_change_password: ÐŸÑ€Ð¾Ð¼ÑÐ½Ð° Ð½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ð°
+  button_copy: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ðµ
+  button_copy_and_follow: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ð½Ðµ Ð¸ Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð°Ð²Ð°Ð½Ðµ
+  button_annotate: ÐÐ½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ
+  button_update: ÐžÐ±Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ
+  button_configure: ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð½Ðµ
+  button_quote: Ð¦Ð¸Ñ‚Ð°Ñ‚
+  button_duplicate: Ð”ÑƒÐ±Ð»Ð¸Ñ€Ð°Ð½Ðµ
+  button_show: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ðµ
+  button_hide: Ð¡ÐºÑ€Ð¸Ð²Ð°Ð½Ðµ
+  button_edit_section: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ñ‚Ð°Ð·Ð¸ ÑÐµÐºÑ†Ð¸Ñ
+  button_export: Ð•ÐºÑÐ¿Ð¾Ñ€Ñ‚
+  button_delete_my_account: ÐŸÑ€ÐµÐ¼Ð°Ñ…Ð²Ð°Ð½Ðµ Ð½Ð° Ð¼Ð¾Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»
+  button_close: Ð—Ð°Ñ‚Ð²Ð°Ñ€ÑÐ½Ðµ
+  button_reopen: ÐžÑ‚Ð²Ð°Ñ€ÑÐ½Ðµ
+
+  status_active: Ð°ÐºÑ‚Ð¸Ð²ÐµÐ½
+  status_registered: Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½
+  status_locked: Ð·Ð°ÐºÐ»ÑŽÑ‡ÐµÐ½
+
+  project_status_active: Ð°ÐºÑ‚Ð¸Ð²ÐµÐ½
+  project_status_closed: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½
+  project_status_archived: Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ð½
+
+  version_status_open: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+  version_status_locked: Ð·Ð°ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°
+  version_status_closed: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+
+  field_active: ÐÐºÑ‚Ð¸Ð²ÐµÐ½
+
+  text_select_mail_notifications: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ ÑÑŠÐ±Ð¸Ñ‚Ð¸Ñ Ð·Ð° Ð¸Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ Ð½Ð° e-mail.
+  text_regexp_info: Ð¿Ñ€. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 - Ð±ÐµÐ· Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ
+  text_project_destroy_confirmation: Ð¡Ð¸Ð³ÑƒÑ€Ð½Ð¸ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð° Ð¸ Ð´Ð°Ð½Ð½Ð¸Ñ‚Ðµ Ð² Ð½ÐµÐ³Ð¾?
+  text_subprojects_destroy_warning: "ÐÐµÐ³Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸: %{value} ÑÑŠÑ‰Ð¾ Ñ‰Ðµ Ð±ÑŠÐ´Ð°Ñ‚ Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚Ð¸."
+  text_workflow_edit: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ñ€Ð¾Ð»Ñ Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€ Ð·Ð° Ð´Ð° Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ñ‚Ðµ Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑ
+  text_are_you_sure: Ð¡Ð¸Ð³ÑƒÑ€Ð½Ð¸ Ð»Ð¸ ÑÑ‚Ðµ?
+  text_journal_changed: "%{label} Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½ Ð¾Ñ‚ %{old} Ð½Ð° %{new}"
+  text_journal_changed_no_detail: "%{label} Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÐ½"
+  text_journal_set_to: "%{label} ÑƒÑÑ‚Ð°Ð½Ð¾Ð²ÐµÐ½ Ð½Ð° %{value}"
+  text_journal_deleted: "%{label} Ð¸Ð·Ñ‚Ñ€Ð¸Ñ‚ (%{old})"
+  text_journal_added: "Ð”Ð¾Ð±Ð°Ð²ÐµÐ½Ð¾ %{label} %{value}"
+  text_tip_issue_begin_day: Ð·Ð°Ð´Ð°Ñ‡Ð°, Ð·Ð°Ð¿Ð¾Ñ‡Ð²Ð°Ñ‰Ð° Ñ‚Ð¾Ð·Ð¸ Ð´ÐµÐ½
+  text_tip_issue_end_day: Ð·Ð°Ð´Ð°Ñ‡Ð°, Ð·Ð°Ð²ÑŠÑ€ÑˆÐ²Ð°Ñ‰Ð° Ñ‚Ð¾Ð·Ð¸ Ð´ÐµÐ½
+  text_tip_issue_begin_end_day: Ð·Ð°Ð´Ð°Ñ‡Ð°, Ð·Ð°Ð¿Ð¾Ñ‡Ð²Ð°Ñ‰Ð° Ð¸ Ð·Ð°Ð²ÑŠÑ€ÑˆÐ²Ð°Ñ‰Ð° Ñ‚Ð¾Ð·Ð¸ Ð´ÐµÐ½
+  text_project_identifier_info: 'ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ° Ð¼Ð°Ð»ÐºÐ¸ Ð±ÑƒÐºÐ²Ð¸ (a-z), Ñ†Ð¸Ñ„Ñ€Ð¸, Ñ‚Ð¸Ñ€ÐµÑ‚Ð° Ð¸ _.<br />ÐŸÑ€Ð¾Ð¼ÑÐ½Ð° ÑÐ»ÐµÐ´ ÑÑŠÐ·Ð´Ð°Ð²Ð°Ð½ÐµÑ‚Ð¾ Ð¼Ñƒ Ð½Ðµ Ðµ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð°.'
+  text_caracters_maximum: "Ð”Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°."
+  text_caracters_minimum: "ÐœÐ¸Ð½Ð¸Ð¼ÑƒÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°."
+  text_length_between: "ÐžÑ‚ %{min} Ð´Ð¾ %{max} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°."
+  text_tracker_no_workflow: ÐÑÐ¼Ð° Ð´ÐµÑ„Ð¸Ð½Ð¸Ñ€Ð°Ð½ Ñ€Ð°Ð±Ð¾Ñ‚ÐµÐ½ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð·Ð° Ñ‚Ð¾Ð·Ð¸ Ñ‚Ñ€Ð°ÐºÐµÑ€
+  text_unallowed_characters: ÐÐµÐ¿Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¸
+  text_comma_separated: ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¾ Ðµ Ð¸Ð·Ð±Ñ€Ð¾ÑÐ²Ð°Ð½Ðµ (Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ» Ð·Ð°Ð¿ÐµÑ‚Ð°Ñ).
+  text_line_separated: ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ° Ð¼Ð½Ð¾Ð³Ð¾ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚Ð¸ (Ð¿Ð¾ ÐµÐ´Ð½Ð¾ Ð½Ð° Ñ€ÐµÐ´).
+  text_issues_ref_in_commit_messages: ÐžÑ‚Ð±ÐµÐ»ÑÐ·Ð²Ð°Ð½Ðµ Ð¸ Ð¿Ñ€Ð¸ÐºÐ»ÑŽÑ‡Ð²Ð°Ð½Ðµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¾Ñ‚ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  text_issue_added: "ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ð½Ð° Ðµ Ð½Ð¾Ð²Ð° Ð·Ð°Ð´Ð°Ñ‡Ð° Ñ Ð½Ð¾Ð¼ÐµÑ€ %{id} (Ð¾Ñ‚ %{author})."
+  text_issue_updated: "Ð—Ð°Ð´Ð°Ñ‡Ð° %{id} Ðµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð° (Ð¾Ñ‚ %{author})."
+  text_wiki_destroy_confirmation: Ð¡Ð¸Ð³ÑƒÑ€Ð½Ð¸ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ Ñ‚Ð¾Ð²Ð° Wiki Ð¸ Ñ†ÑÐ»Ð¾Ñ‚Ð¾ Ð¼Ñƒ ÑÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ?
+  text_issue_category_destroy_question: "Ð˜Ð¼Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ (%{count}) Ð¾Ð±Ð²ÑŠÑ€Ð·Ð°Ð½Ð¸ Ñ Ñ‚Ð°Ð·Ð¸ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ. ÐšÐ°ÐºÐ²Ð¾ Ñ‰Ðµ Ð¸Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ?"
+  text_issue_category_destroy_assignments: ÐŸÑ€ÐµÐ¼Ð°Ñ…Ð²Ð°Ð½Ðµ Ð½Ð° Ð²Ñ€ÑŠÐ·ÐºÐ¸Ñ‚Ðµ Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸ÑÑ‚Ð°
+  text_issue_category_reassign_to: ÐŸÑ€ÐµÐ¾Ð±Ð²ÑŠÑ€Ð·Ð²Ð°Ð½Ðµ Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
+  text_user_mail_option: "Ð—Ð° Ð½ÐµÐ¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸, Ñ‰Ðµ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ð²Ð°Ñ‚Ðµ Ð¸Ð·Ð²ÐµÑÑ‚Ð¸Ñ ÑÐ°Ð¼Ð¾ Ð·Ð° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ð²Ð°Ð½Ð¸ Ð´ÐµÐ¹Ð½Ð¾ÑÑ‚Ð¸ Ð¸Ð»Ð¸ Ð² ÐºÐ¾Ð¸Ñ‚Ð¾ ÑƒÑ‡Ð°ÑÑ‚Ð²Ð°Ñ‚Ðµ (Ñ‚.Ðµ. Ð°Ð²Ñ‚Ð¾Ñ€ Ð¸Ð»Ð¸ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½)."
+  text_no_configuration_data: "Ð’ÑÐµ Ð¾Ñ‰Ðµ Ð½Ðµ ÑÐ° ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¸ Ð Ð¾Ð»Ð¸, Ñ‚Ñ€Ð°ÐºÐµÑ€Ð¸, ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ñ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¸ Ñ€Ð°Ð±Ð¾Ñ‚ÐµÐ½ Ð¿Ñ€Ð¾Ñ†ÐµÑ.\nÐ¡Ñ‚Ñ€Ð¾Ð³Ð¾ ÑÐµ Ð¿Ñ€ÐµÐ¿Ð¾Ñ€ÑŠÑ‡Ð²Ð° Ð·Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð½Ð°Ñ‚Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ. Ð’ÐµÐ´Ð½ÑŠÐ¶ Ð·Ð°Ñ€ÐµÐ´ÐµÐ½Ð° Ñ‰Ðµ Ð¸Ð¼Ð°Ñ‚Ðµ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð´Ð° Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ñ‚Ðµ."
+  text_load_default_configuration: Ð—Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð½Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
+  text_status_changed_by_changeset: "ÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¾ Ñ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ %{value}."
+  text_time_logged_by_changeset: ÐŸÑ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¾ Ð² Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ %{value}.
+  text_issues_destroy_confirmation: 'Ð¡Ð¸Ð³ÑƒÑ€Ð½Ð¸ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸?'
+  text_issues_destroy_descendants_confirmation: Ð¢Ð°Ð·Ð¸ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ‰Ðµ Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½Ðµ Ð¸ %{count} Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð°(Ð¸).
+  text_time_entries_destroy_confirmation: Ð¡Ð¸Ð³ÑƒÑ€ÐµÐ½ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð·Ð° Ð¸Ð·Ñ€Ð°Ð·Ñ…Ð¾Ð´Ð²Ð°Ð½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ?
+  text_select_project_modules: 'Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¸Ñ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð·Ð° Ñ‚Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚:'
+  text_default_administrator_account_changed: Ð¡Ð¼ÐµÐ½ÐµÐ½ Ñ„Ð°Ð±Ñ€Ð¸Ñ‡Ð½Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€ÑÐºÐ¸ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»
+  text_file_repository_writable: Ð’ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¿Ð¸ÑÐ°Ð½Ðµ Ð² Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÑ‚Ð¾ Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
+  text_plugin_assets_writable: ÐŸÐ°Ð¿ÐºÐ°Ñ‚Ð° Ð½Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð²ÐºÐ¸Ñ‚Ðµ Ðµ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð° Ð·Ð° Ð·Ð°Ð¿Ð¸Ñ
+  text_rmagick_available: ÐÐ°Ð»Ð¸Ñ‡ÐµÐ½ RMagick (Ð¿Ð¾ Ð¸Ð·Ð±Ð¾Ñ€)
+  text_destroy_time_entries_question: "%{hours} Ñ‡Ð°ÑÐ° ÑÐ° Ð¾Ñ‚Ð´ÐµÐ»ÐµÐ½Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ, ÐºÐ¾Ð¸Ñ‚Ð¾ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¸Ð·Ñ‚Ñ€Ð¸ÐµÑ‚Ðµ. ÐšÐ°ÐºÐ²Ð¾ Ð¸Ð·Ð±Ð¸Ñ€Ð°Ñ‚Ðµ?"
+  text_destroy_time_entries: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð¾Ñ‚Ð´ÐµÐ»ÐµÐ½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  text_assign_time_entries_to_project: ÐŸÑ€ÐµÑ…Ð²ÑŠÑ€Ð»ÑÐ½Ðµ Ð½Ð° Ð¾Ñ‚Ð´ÐµÐ»ÐµÐ½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ ÐºÑŠÐ¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  text_reassign_time_entries: 'ÐŸÑ€ÐµÑ…Ð²ÑŠÑ€Ð»ÑÐ½Ðµ Ð½Ð° Ð¾Ñ‚Ð´ÐµÐ»ÐµÐ½Ð¾Ñ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ ÐºÑŠÐ¼ Ð·Ð°Ð´Ð°Ñ‡Ð°:'
+  text_user_wrote: "%{value} Ð½Ð°Ð¿Ð¸ÑÐ°:"
+  text_enumeration_destroy_question: "%{count} Ð¾Ð±ÐµÐºÑ‚Ð° ÑÐ° ÑÐ²ÑŠÑ€Ð·Ð°Ð½Ð¸ Ñ Ñ‚Ð°Ð·Ð¸ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚."
+  text_enumeration_category_reassign_to: 'ÐŸÑ€ÐµÑÐ²ÑŠÑ€Ð¶ÐµÑ‚Ðµ Ð³Ð¸ ÐºÑŠÐ¼ Ñ‚Ð°Ð·Ð¸ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚:'
+  text_email_delivery_not_configured: "Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½ÐµÑ‚Ð¾ Ð½Ð° e-mail-Ð¸ Ð½Ðµ Ðµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾ Ð¸ Ð¸Ð·Ð²ÐµÑÑ‚Ð¸ÑÑ‚Ð° Ð½Ðµ ÑÐ° Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸.\nÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð¹Ñ‚Ðµ Ð²Ð°ÑˆÐ¸Ñ SMTP ÑÑŠÑ€Ð²ÑŠÑ€ Ð² config/configuration.yml Ð¸ Ñ€ÐµÑÑ‚Ð°Ñ€Ñ‚Ð¸Ñ€Ð°Ð¹Ñ‚Ðµ Redmine, Ð·Ð° Ð´Ð° Ð³Ð¸ Ñ€Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚Ðµ."
+  text_repository_usernames_mapping: "Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð¸Ð»Ð¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÑ‚Ðµ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸Ñ‚Ðµ Ð² Redmine, ÑÑŠÐ¾Ñ‚Ð²ÐµÑ‚ÑÑ‚Ð²Ð°Ñ‰Ð¸ Ð½Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸Ñ‚Ðµ Ð² Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÐ° Ð½Ð° Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÑ‚Ð¾ (repository).\nÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ð¸Ñ‚Ðµ Ñ ÐµÐ´Ð½Ð°ÐºÐ²Ð¸ Ð¸Ð¼ÐµÐ½Ð° Ð² Redmine Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°Ñ‚Ð° ÑÐµ ÑÑŠÐ²Ð¼ÐµÑÑ‚ÑÐ²Ð°Ñ‚ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾."
+  text_diff_truncated: '... Ð¢Ð¾Ð·Ð¸ diff Ð½Ðµ Ðµ Ð¿ÑŠÐ»ÐµÐ½, Ð¿Ð¾Ð½ÐµÐ¶Ðµ Ðµ Ð½Ð°Ð´Ñ…Ð²ÑŠÑ€Ð»Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€, ÐºÐ¾Ð¹Ñ‚Ð¾ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½.'
+  text_custom_field_possible_values_info: 'Ð•Ð´Ð½Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚ Ð½Ð° Ñ€ÐµÐ´'
+  text_wiki_page_destroy_question: Ð¢Ð°Ð·Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¸Ð¼Ð° %{descendants} ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸ Ð´ÐµÑ†Ð° Ð¸ descendant(s). ÐšÐ°ÐºÐ²Ð¾ Ð¶ÐµÐ»Ð°ÐµÑ‚Ðµ Ð´Ð° Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ðµ?
+  text_wiki_page_nullify_children: Ð—Ð°Ð¿Ð°Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ñ‚ÐµÐ·Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸ ÐºÐ°Ñ‚Ð¾ ÐºÐ¾Ñ€ÐµÐ½Ð½Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  text_wiki_page_destroy_children: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸Ñ‚Ðµ Ð´ÐµÑ†Ð° Ð¸ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ñ‚ÐµÑ…Ð½Ð¸ descendants
+  text_wiki_page_reassign_children: ÐŸÑ€ÐµÐ½Ð°Ð·Ð½Ð°Ñ‡Ð°Ð²Ð°Ð½Ðµ Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸Ñ‚Ðµ Ð´ÐµÑ†Ð° Ð½Ð° Ñ‚Ð°Ð·Ð¸ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  text_own_membership_delete_confirmation: "Ð’Ð¸Ðµ ÑÑ‚Ðµ Ð½Ð° Ð¿ÑŠÑ‚ Ð´Ð° Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½ÐµÑ‚Ðµ Ð½ÑÐºÐ¾Ð¸ Ð¸Ð»Ð¸ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð²Ð°ÑˆÐ¸ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¸ Ðµ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ ÑÐ»ÐµÐ´ Ñ‚Ð¾Ð²Ð° Ð´Ð° Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð´Ð° Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ñ‚Ðµ Ñ‚Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚.\nÐ¡Ð¸Ð³ÑƒÑ€ÐµÐ½ Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¸ÑÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð¸Ñ‚Ðµ?"
+  text_zoom_in: Ð£Ð²ÐµÐ»Ð¸Ñ‡Ð°Ð²Ð°Ð½Ðµ
+  text_zoom_out: ÐÐ°Ð¼Ð°Ð»ÑÐ²Ð°Ð½Ðµ
+  text_warn_on_leaving_unsaved: Ð¡Ñ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° ÑÑŠÐ´ÑŠÑ€Ð¶Ð° Ð½ÐµÐ·Ð°Ð¿Ð¸ÑÐ°Ð½Ð¾ ÑÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ, ÐºÐ¾ÐµÑ‚Ð¾ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð·Ð°Ð³ÑƒÐ±ÐµÐ½Ð¾, Ð°ÐºÐ¾ Ñ Ð½Ð°Ð¿ÑƒÑÐ½ÐµÑ‚Ðµ.
+  text_scm_path_encoding_note: "ÐŸÐ¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ: UTF-8"
+  text_git_repository_note: ÐŸÑ€Ð°Ð·Ð½Ð¾ Ð¸ Ð»Ð¾ÐºÐ°Ð»Ð½Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ (Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€ /gitrepo, c:\gitrepo)
+  text_mercurial_repository_note: Ð›Ð¾ÐºÐ°Ð»Ð½Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ (Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€ /hgrepo, c:\hgrepo)
+  text_scm_command: SCM ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°
+  text_scm_command_version: Ð’ÐµÑ€ÑÐ¸Ñ
+  text_scm_config: ÐœÐ¾Ð¶ÐµÑ‚Ðµ Ð´Ð° ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ñ‚Ðµ SCM ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸Ñ‚Ðµ Ð² config/configuration.yml. Ð—Ð° Ð´Ð° Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ñ‚Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸Ñ‚Ðµ, Ñ€ÐµÑÑ‚Ð°Ñ€Ñ‚Ð¸Ñ€Ð°Ð¹Ñ‚Ðµ Redmine.
+  text_scm_command_not_available: SCM ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð° Ð½Ðµ Ðµ Ð½Ð°Ð»Ð¸Ñ‡Ð½Ð° Ð¸Ð»Ð¸ Ð´Ð¾ÑÑ‚ÑŠÐ¿Ð½Ð°. ÐŸÑ€Ð¾Ð²ÐµÑ€ÐµÑ‚Ðµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸ÑÑ‚Ð° Ð² Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¸Ð²Ð½Ð¸Ñ Ð¿Ð°Ð½ÐµÐ».
+  text_issue_conflict_resolution_overwrite: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð°Ð½Ðµ Ð½Ð° Ð¼Ð¾Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸ (Ð¿Ñ€ÐµÐ´Ð¸ÑˆÐ½Ð¸Ñ‚Ðµ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ Ñ‰Ðµ Ð±ÑŠÐ´Ð°Ñ‚ Ð·Ð°Ð¿Ð°Ð·ÐµÐ½Ð¸, Ð½Ð¾ Ð½ÑÐºÐ¾Ð¸ Ð´Ñ€ÑƒÐ³Ð¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ð°Ñ‚ Ð¿Ñ€ÐµÐ·Ð°Ð¿Ð¸ÑÐ°Ð½Ð¸)
+  text_issue_conflict_resolution_add_notes: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð¼Ð¾Ð¸Ñ‚Ðµ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ Ð¸ Ð¾Ñ‚Ñ…Ð²ÑŠÑ€Ð»ÑÐ½Ðµ Ð½Ð° Ð´Ñ€ÑƒÐ³Ð¸Ñ‚Ðµ Ð¼Ð¾Ð¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸
+  text_issue_conflict_resolution_cancel: ÐžÑ‚Ñ…Ð²ÑŠÑ€Ð»ÑÐ½Ðµ Ð½Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¼Ð¾Ð¸ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸ Ð¸ Ð¿Ñ€ÐµÐ·Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° %{link}
+  text_account_destroy_confirmation: "Ð¡Ð¸Ð³ÑƒÑ€ÐµÐ½/Ð½Ð° Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¶ÐµÐ»Ð°ÐµÑ‚Ðµ Ð´Ð° Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð¸Ñ‚Ðµ?\nÐ’Ð°ÑˆÐ¸ÑÑ‚ Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ñ‰Ðµ Ð±ÑŠÐ´Ðµ Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½Ð°Ñ‚ Ð±ÐµÐ· Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð²ÑŠÐ·ÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ."
+  text_session_expiration_settings: "Ð’Ð½Ð¸Ð¼Ð°Ð½Ð¸Ðµ: Ð¿Ñ€Ð¾Ð¼ÑÐ½Ð°Ñ‚Ð° Ð½Ð° Ñ‚ÐµÐ·Ð¸ ÑƒÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ð¾Ñ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‚Ð¸ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¸ ÑÐµÑÐ¸Ð¸, Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÐµÐ»Ð½Ð¾ Ð¸ Ð²Ð°ÑˆÐ°Ñ‚Ð°."
+  text_project_closed: Ð¢Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ðµ Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½ Ð¸ Ðµ ÑÐ°Ð¼Ð¾ Ð·Ð° Ñ‡ÐµÑ‚ÐµÐ½Ðµ.
+  text_turning_multiple_off: ÐÐºÐ¾ Ð·Ð°Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚Ñ‚Ð° Ð·Ð° Ð¿Ð¾Ð²ÐµÑ‡Ðµ Ð¾Ñ‚ ÐµÐ´Ð½Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚, Ð¿Ð¾Ð²ÐµÑ‡ÐµÑ‚Ð¾ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚Ð¸ Ñ‰Ðµ Ð±ÑŠÐ´Ð°Ñ‚
+    Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½Ð°Ñ‚Ð¸ Ñ Ñ†ÐµÐ» Ð´Ð° Ð¾ÑÑ‚Ð°Ð½Ðµ ÑÐ°Ð¼Ð¾ Ð¿Ð¾ ÐµÐ´Ð½Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¿Ð¾Ð»Ðµ.
+
+  default_role_manager: ÐœÐµÐ½Ð¸Ð´Ð¶ÑŠÑ€
+  default_role_developer: Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸Ðº
+  default_role_reporter: ÐŸÑƒÐ±Ð»Ð¸ÐºÑƒÐ²Ð°Ñ‰
+  default_tracker_bug: Ð“Ñ€ÐµÑˆÐºÐ°
+  default_tracker_feature: Ð¤ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð°Ð»Ð½Ð¾ÑÑ‚
+  default_tracker_support: ÐŸÐ¾Ð´Ð´Ñ€ÑŠÐ¶ÐºÐ°
+  default_issue_status_new: ÐÐ¾Ð²Ð°
+  default_issue_status_in_progress: Ð˜Ð·Ð¿ÑŠÐ»Ð½ÐµÐ½Ð¸Ðµ
+  default_issue_status_resolved: ÐŸÑ€Ð¸ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°
+  default_issue_status_feedback: ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð° Ð²Ñ€ÑŠÐ·ÐºÐ°
+  default_issue_status_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+  default_issue_status_rejected: ÐžÑ‚Ñ…Ð²ÑŠÑ€Ð»ÐµÐ½Ð°
+  default_doc_category_user: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð·Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ
+  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸Ñ‡ÐµÑÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ
+  default_priority_low: ÐÐ¸ÑÑŠÐº
+  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»ÐµÐ½
+  default_priority_high: Ð’Ð¸ÑÐ¾Ðº
+  default_priority_urgent: Ð¡Ð¿ÐµÑˆÐµÐ½
+  default_priority_immediate: Ð’ÐµÐ´Ð½Ð°Ð³Ð°
+  default_activity_design: Ð”Ð¸Ð·Ð°Ð¹Ð½
+  default_activity_development: Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ°
+
+  enumeration_issue_priorities: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  enumeration_activities: Ð”ÐµÐ¹Ð½Ð¾ÑÑ‚Ð¸ (time tracking)
+  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
+  description_filter: Ð¤Ð¸Ð»Ñ‚ÑŠÑ€
+  description_search: Ð¢ÑŠÑ€ÑÐµÐ½Ðµ
+  description_choose_project: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸
+  description_project_scope: ÐžÐ±Ñ…Ð²Ð°Ñ‚ Ð½Ð° Ñ‚ÑŠÑ€ÑÐµÐ½ÐµÑ‚Ð¾
+  description_notes: Ð‘ÐµÐ»ÐµÐ¶ÐºÐ¸
+  description_message_content: Ð¡ÑŠÐ´ÑŠÑ€Ð¶Ð°Ð½Ð¸Ðµ Ð½Ð° ÑÑŠÐ¾Ð±Ñ‰ÐµÐ½Ð¸ÐµÑ‚Ð¾
+  description_query_sort_criteria_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð½Ð° ÑÐ¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ
+  description_query_sort_criteria_direction: ÐŸÐ¾ÑÐ¾ÐºÐ° Ð½Ð° ÑÐ¾Ñ€Ñ‚Ð¸Ñ€Ð°Ð½Ðµ
+  description_user_mail_notification: ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¸Ð·Ð²ÐµÑÑ‚Ð¸ÑÑ‚Ð° Ð¿Ð¾ Ð¿Ð¾Ñ‰Ð°Ñ‚Ð°
+  description_available_columns: ÐÐ°Ð»Ð¸Ñ‡Ð½Ð¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸
+  description_selected_columns: Ð˜Ð·Ð±Ñ€Ð°Ð½Ð¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸
+  description_issue_category_reassign: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
+  description_wiki_subpages_reassign: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð½Ð¾Ð²Ð° Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  description_all_columns: Ð’ÑÐ¸Ñ‡ÐºÐ¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸
+  description_date_range_list: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ð¾Ñ‚ ÑÐ¿Ð¸ÑÑŠÐºÐ°
+  description_date_range_interval: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ñ‡Ñ€ÐµÐ· Ð·Ð°Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð½Ð°Ñ‡Ð°Ð»Ð½Ð° Ð¸ ÐºÑ€Ð°Ð¹Ð½Ð° Ð´Ð°Ñ‚Ð¸
+  description_date_from: Ð’ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ Ð½Ð°Ñ‡Ð°Ð»Ð½Ð° Ð´Ð°Ñ‚Ð°
+  description_date_to: Ð’ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ ÐºÑ€Ð°Ð¹Ð½Ð° Ð´Ð°Ñ‚Ð°
+  text_repository_identifier_info: 'ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐ° Ð¼Ð°Ð»ÐºÐ¸ Ð±ÑƒÐºÐ²Ð¸ (a-z), Ñ†Ð¸Ñ„Ñ€Ð¸, Ñ‚Ð¸Ñ€ÐµÑ‚Ð° Ð¸ _.<br />ÐŸÑ€Ð¾Ð¼ÑÐ½Ð° ÑÐ»ÐµÐ´ ÑÑŠÐ·Ð´Ð°Ð²Ð°Ð½ÐµÑ‚Ð¾ Ð¼Ñƒ Ð½Ðµ Ðµ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð°.'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/70/706a81236a3578317d828beb9423327b5b69e98d.svn-base
--- a/.svn/pristine/70/706a81236a3578317d828beb9423327b5b69e98d.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-class <%= class_name %> < ActiveRecord::Migration
-  def self.up
-  <%- plugins.each do |plugin| -%>
-    Engines.plugins["<%= plugin.name %>"].migrate(<%= new_versions[plugin.name] %>)
-  <%- end -%>
-  end
-
-  def self.down
-  <%- plugins.each do |plugin| -%>
-    Engines.plugins["<%= plugin.name %>"].migrate(<%= current_versions[plugin.name] %>)
-  <%- end -%>
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/70/70b84ab9e3add639c1ef335fb9d7383dcdf7f5f5.svn-base
--- a/.svn/pristine/70/70b84ab9e3add639c1ef335fb9d7383dcdf7f5f5.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class LdapAuthSourcesControllerTest < ActionController::TestCase
-
-  def setup
-    @request.session[:user_id] = 1
-  end
-
-  context "get :new" do
-    setup do
-      get :new
-    end
-
-    should_assign_to :auth_source
-    should_respond_with :success
-    should_render_template :new
-
-    should "initilize a new AuthSource" do
-      assert_equal AuthSourceLdap, assigns(:auth_source).class
-      assert assigns(:auth_source).new_record?
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/70/70dfef569a65ef5db9a25ad36d19a3ee38afe71d.svn-base
--- a/.svn/pristine/70/70dfef569a65ef5db9a25ad36d19a3ee38afe71d.svn-base
+++ /dev/null
@@ -1,18 +0,0 @@
-class CopyRepositoriesLogEncoding < ActiveRecord::Migration
-  def self.up
-    encoding = Setting.commit_logs_encoding.to_s.strip
-    encoding = encoding.blank? ? 'UTF-8' : encoding
-    Repository.find(:all).each do |repo|
-      scm = repo.scm_name
-      case scm
-        when 'Subversion', 'Mercurial', 'Git', 'Filesystem' 
-          repo.update_attribute(:log_encoding, nil)
-        else
-          repo.update_attribute(:log_encoding, encoding)
-      end
-    end
-  end
-
-  def self.down
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/70/70e864184fd8408391ed37d61337591c474549c4.svn-base
--- /dev/null
+++ b/.svn/pristine/70/70e864184fd8408391ed37d61337591c474549c4.svn-base
@@ -0,0 +1,247 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module WikiFormatting
+    module Macros
+      module Definitions
+        # Returns true if +name+ is the name of an existing macro
+        def macro_exists?(name)
+          Redmine::WikiFormatting::Macros.available_macros.key?(name.to_sym)
+        end
+
+        def exec_macro(name, obj, args, text)
+          macro_options = Redmine::WikiFormatting::Macros.available_macros[name.to_sym]
+          return unless macro_options
+
+          method_name = "macro_#{name}"
+          unless macro_options[:parse_args] == false
+            args = args.split(',').map(&:strip)
+          end
+
+          begin
+            if self.class.instance_method(method_name).arity == 3
+              send(method_name, obj, args, text)
+            elsif text
+              raise "This macro does not accept a block of text"
+            else
+              send(method_name, obj, args)
+            end
+          rescue => e
+            "<div class=\"flash error\">Error executing the <strong>#{h name}</strong> macro (#{h e.to_s})</div>".html_safe
+          end
+        end
+
+        def extract_macro_options(args, *keys)
+          options = {}
+          while args.last.to_s.strip =~ %r{^(.+?)\=(.+)$} && keys.include?($1.downcase.to_sym)
+            options[$1.downcase.to_sym] = $2
+            args.pop
+          end
+          return [args, options]
+        end
+      end
+
+      @@available_macros = {}
+      mattr_accessor :available_macros
+
+      class << self
+        # Plugins can use this method to define new macros:
+        #
+        #   Redmine::WikiFormatting::Macros.register do
+        #     desc "This is my macro"
+        #     macro :my_macro do |obj, args|
+        #       "My macro output"
+        #     end
+        #   
+        #     desc "This is my macro that accepts a block of text"
+        #     macro :my_macro do |obj, args, text|
+        #       "My macro output"
+        #     end
+        #   end
+        def register(&block)
+          class_eval(&block) if block_given?
+        end
+
+        # Defines a new macro with the given name, options and block.
+        #
+        # Options:
+        # * :desc - A description of the macro
+        # * :parse_args => false - Disables arguments parsing (the whole arguments 
+        #   string is passed to the macro)
+        #
+        # Macro blocks accept 2 or 3 arguments:
+        # * obj: the object that is rendered (eg. an Issue, a WikiContent...)
+        # * args: macro arguments
+        # * text: the block of text given to the macro (should be present only if the
+        #   macro accepts a block of text). text is a String or nil if the macro is
+        #   invoked without a block of text.  
+        #
+        # Examples:
+        # By default, when the macro is invoked, the coma separated list of arguments
+        # is split and passed to the macro block as an array. If no argument is given
+        # the macro will be invoked with an empty array:
+        #
+        #   macro :my_macro do |obj, args|
+        #     # args is an array
+        #     # and this macro do not accept a block of text
+        #   end
+        #
+        # You can disable arguments spliting with the :parse_args => false option. In
+        # this case, the full string of arguments is passed to the macro:
+        #
+        #   macro :my_macro, :parse_args => false do |obj, args|
+        #     # args is a string
+        #   end
+        #
+        # Macro can optionally accept a block of text:
+        #
+        #   macro :my_macro do |obj, args, text|
+        #     # this macro accepts a block of text
+        #   end
+        #
+        # Macros are invoked in formatted text using double curly brackets. Arguments
+        # must be enclosed in parenthesis if any. A new line after the macro name or the
+        # arguments starts the block of text that will be passe to the macro (invoking
+        # a macro that do not accept a block of text with some text will fail).
+        # Examples:
+        #
+        #   No arguments:
+        #   {{my_macro}}
+        #
+        #   With arguments:
+        #   {{my_macro(arg1, arg2)}}
+        #
+        #   With a block of text:
+        #   {{my_macro
+        #   multiple lines
+        #   of text
+        #   }}
+        #
+        #   With arguments and a block of text
+        #   {{my_macro(arg1, arg2)
+        #   multiple lines
+        #   of text
+        #   }}
+        #
+        # If a block of text is given, the closing tag }} must be at the start of a new line.
+        def macro(name, options={}, &block)
+          options.assert_valid_keys(:desc, :parse_args)
+          unless name.to_s.match(/\A\w+\z/)
+            raise "Invalid macro name: #{name} (only 0-9, A-Z, a-z and _ characters are accepted)"
+          end
+          unless block_given?
+            raise "Can not create a macro without a block!"
+          end
+          name = name.to_s.downcase.to_sym
+          available_macros[name] = {:desc => @@desc || ''}.merge(options)
+          @@desc = nil
+          Definitions.send :define_method, "macro_#{name}", &block
+        end
+
+        # Sets description for the next macro to be defined
+        def desc(txt)
+          @@desc = txt
+        end
+      end
+
+      # Builtin macros
+      desc "Sample macro."
+      macro :hello_world do |obj, args, text|
+        h("Hello world! Object: #{obj.class.name}, " + 
+          (args.empty? ? "Called with no argument" : "Arguments: #{args.join(', ')}") +
+          " and " + (text.present? ? "a #{text.size} bytes long block of text." : "no block of text.")
+        )
+      end
+
+      desc "Displays a list of all available macros, including description if available."
+      macro :macro_list do |obj, args|
+        out = ''.html_safe
+        @@available_macros.each do |macro, options|
+          out << content_tag('dt', content_tag('code', macro.to_s))
+          out << content_tag('dd', textilizable(options[:desc]))
+        end
+        content_tag('dl', out)
+      end
+
+      desc "Displays a list of child pages. With no argument, it displays the child pages of the current wiki page. Examples:\n\n" +
+             "  !{{child_pages}} -- can be used from a wiki page only\n" +
+             "  !{{child_pages(depth=2)}} -- display 2 levels nesting only\n"
+             "  !{{child_pages(Foo)}} -- lists all children of page Foo\n" +
+             "  !{{child_pages(Foo, parent=1)}} -- same as above with a link to page Foo"
+      macro :child_pages do |obj, args|
+        args, options = extract_macro_options(args, :parent, :depth)
+        options[:depth] = options[:depth].to_i if options[:depth].present?
+
+        page = nil
+        if args.size > 0
+          page = Wiki.find_page(args.first.to_s, :project => @project)
+        elsif obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)
+          page = obj.page
+        else
+          raise 'With no argument, this macro can be called from wiki pages only.'
+        end
+        raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project)
+        pages = page.self_and_descendants(options[:depth]).group_by(&:parent_id)
+        render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id)
+      end
+
+      desc "Include a wiki page. Example:\n\n  !{{include(Foo)}}\n\nor to include a page of a specific project wiki:\n\n  !{{include(projectname:Foo)}}"
+      macro :include do |obj, args|
+        page = Wiki.find_page(args.first.to_s, :project => @project)
+        raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project)
+        @included_wiki_pages ||= []
+        raise 'Circular inclusion detected' if @included_wiki_pages.include?(page.title)
+        @included_wiki_pages << page.title
+        out = textilizable(page.content, :text, :attachments => page.attachments, :headings => false)
+        @included_wiki_pages.pop
+        out
+      end
+
+      desc "Inserts of collapsed block of text. Example:\n\n  {{collapse(View details...)\nThis is a block of text that is collapsed by default.\nIt can be expanded by clicking a link.\n}}"
+      macro :collapse do |obj, args, text|
+        html_id = "collapse-#{Redmine::Utils.random_hex(4)}"
+        show_label = args[0] || l(:button_show)
+        hide_label = args[1] || args[0] || l(:button_hide)
+        js = "$('##{html_id}-show, ##{html_id}-hide').toggle(); $('##{html_id}').fadeToggle(150);"
+        out = ''.html_safe
+        out << link_to_function(show_label, js, :id => "#{html_id}-show", :class => 'collapsible collapsed')
+        out << link_to_function(hide_label, js, :id => "#{html_id}-hide", :class => 'collapsible', :style => 'display:none;')
+        out << content_tag('div', textilizable(text, :object => obj), :id => html_id, :class => 'collapsed-text', :style => 'display:none;')
+        out
+      end
+
+      desc "Displays a clickable thumbnail of an attached image. Examples:\n\n<pre>{{thumbnail(image.png)}}\n{{thumbnail(image.png, size=300, title=Thumbnail)}}</pre>"
+      macro :thumbnail do |obj, args|
+        args, options = extract_macro_options(args, :size, :title)
+        filename = args.first
+        raise 'Filename required' unless filename.present?
+        size = options[:size]
+        raise 'Invalid size parameter' unless size.nil? || size.match(/^\d+$/)
+        size = size.to_i
+        size = nil unless size > 0
+        if obj && obj.respond_to?(:attachments) && attachment = Attachment.latest_attach(obj.attachments, filename)
+          title = options[:title] || attachment.title
+          img = image_tag(url_for(:controller => 'attachments', :action => 'thumbnail', :id => attachment, :size => size), :alt => attachment.filename)
+          link_to(img, url_for(:controller => 'attachments', :action => 'show', :id => attachment), :class => 'thumbnail', :title => title)
+        else
+          raise "Attachment #{filename} not found"
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/70/70fcc81fd15a480f7d8ac6f47bf3e67d8c9739ca.svn-base
--- a/.svn/pristine/70/70fcc81fd15a480f7d8ac6f47bf3e67d8c9739ca.svn-base
+++ /dev/null
@@ -1,24 +0,0 @@
-module CodeRay
-module Encoders
-  
-  load :html
-  
-  # Wraps the output into a HTML page, using CSS classes and
-  # line numbers in the table format by default.
-  # 
-  # See Encoders::HTML for available options.
-  class Page < HTML
-    
-    FILE_EXTENSION = 'html'
-    
-    register_for :page
-    
-    DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
-      :css          => :class,
-      :wrap         => :page,
-      :line_numbers => :table
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/71/714859f726ef05e105f7c83270e22457a9138242.svn-base
--- /dev/null
+++ b/.svn/pristine/71/714859f726ef05e105f7c83270e22457a9138242.svn-base
@@ -0,0 +1,35 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine #:nodoc:
+  module CoreExtensions #:nodoc:
+    module Date #:nodoc:
+      # Custom date calculations
+      module Calculations
+        # Returns difference with specified date in months
+        def months_ago(date = self.class.today)
+          (date.year - self.year)*12 + (date.month - self.month)
+        end
+
+        # Returns difference with specified date in weeks
+        def weeks_ago(date = self.class.today)
+          (date.year - self.year)*52 + (date.cweek - self.cweek)
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/71/71c72fcec779c58b3cb29e26161e013284f30b8a.svn-base
--- a/.svn/pristine/71/71c72fcec779c58b3cb29e26161e013284f30b8a.svn-base
+++ /dev/null
@@ -1,63 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class ApplicationTest < ActionController::IntegrationTest
-  include Redmine::I18n
-
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows
-
-  def test_set_localization
-    Setting.default_language = 'en'
-
-    # a french user
-    get 'projects', { }, 'Accept-Language' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
-    assert_response :success
-    assert_tag :tag => 'h2', :content => 'Projets'
-    assert_equal :fr, current_language
-
-    # then an italien user
-    get 'projects', { }, 'Accept-Language' => 'it;q=0.8,en-us;q=0.5,en;q=0.3'
-    assert_response :success
-    assert_tag :tag => 'h2', :content => 'Progetti'
-    assert_equal :it, current_language
-
-    # not a supported language: default language should be used
-    get 'projects', { }, 'Accept-Language' => 'zz'
-    assert_response :success
-    assert_tag :tag => 'h2', :content => 'Projects'
-  end
-
-  def test_token_based_access_should_not_start_session
-    # issue of a private project
-    get 'issues/4.atom'
-    assert_response 302
-
-    rss_key = User.find(2).rss_key
-    get "issues/4.atom?key=#{rss_key}"
-    assert_response 200
-    assert_nil session[:user_id]
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/72/723213b09aa91cffeb184141cd322a54885c2096.svn-base
--- /dev/null
+++ b/.svn/pristine/72/723213b09aa91cffeb184141cd322a54885c2096.svn-base
@@ -0,0 +1,1079 @@
+# Norwegian, norsk bokmÃ¥l, by irb.no
+"no":
+  support:
+    array:
+      sentence_connector: "og"
+  direction: ltr
+  date:
+    formats:
+      default: "%d.%m.%Y"
+      short: "%e. %b"
+      long: "%e. %B %Y"
+    day_names: [sÃ¸ndag, mandag, tirsdag, onsdag, torsdag, fredag, lÃ¸rdag]
+    abbr_day_names: [sÃ¸n, man, tir, ons, tor, fre, lÃ¸r]
+    month_names: [~, januar, februar, mars, april, mai, juni, juli, august, september, oktober, november, desember]
+    abbr_month_names: [~, jan, feb, mar, apr, mai, jun, jul, aug, sep, okt, nov, des]
+    order:
+      - :day
+      - :month
+      - :year
+  time:
+    formats:
+      default: "%A, %e. %B %Y, %H:%M"
+      time: "%H:%M"
+      short: "%e. %B, %H:%M"
+      long: "%A, %e. %B %Y, %H:%M"
+    am: ""
+    pm: ""
+  datetime:
+    distance_in_words:
+      half_a_minute: "et halvt minutt"
+      less_than_x_seconds:
+        one: "mindre enn 1 sekund"
+        other: "mindre enn %{count} sekunder"
+      x_seconds:
+        one: "1 sekund"
+        other: "%{count} sekunder"
+      less_than_x_minutes:
+        one: "mindre enn 1 minutt"
+        other: "mindre enn %{count} minutter"
+      x_minutes:
+        one: "1 minutt"
+        other: "%{count} minutter"
+      about_x_hours:
+        one: "rundt 1 time"
+        other: "rundt %{count} timer"
+      x_hours:
+        one:   "1 time"
+        other: "%{count} timer"
+      x_days:
+        one: "1 dag"
+        other: "%{count} dager"
+      about_x_months:
+        one: "rundt 1 mÃ¥ned"
+        other: "rundt %{count} mÃ¥neder"
+      x_months:
+        one: "1 mÃ¥ned"
+        other: "%{count} mÃ¥neder"
+      about_x_years:
+        one: "rundt 1 Ã¥r"
+        other: "rundt %{count} Ã¥r"
+      over_x_years:
+        one: "over 1 Ã¥r"
+        other: "over %{count} Ã¥r"
+      almost_x_years:
+        one:   "nesten 1 Ã¥r"
+        other: "nesten %{count} Ã¥r"
+  number:
+    format:
+      precision: 3
+      separator: "."
+      delimiter: ","
+    currency:
+      format:
+        unit: "kr"
+        format: "%n %u"
+    precision:
+      format:
+        delimiter: ""
+        precision: 4
+    human:
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  activerecord:
+    errors:
+      template:
+        header: "kunne ikke lagre %{model} pÃ¥ grunn av %{count} feil."
+        body: "det oppstod problemer i fÃ¸lgende felt:"
+      messages:
+        inclusion: "er ikke inkludert i listen"
+        exclusion: "er reservert"
+        invalid: "er ugyldig"
+        confirmation: "passer ikke bekreftelsen"
+        accepted: "mÃ¥ vÃ¦re akseptert"
+        empty: "kan ikke vÃ¦re tom"
+        blank: "kan ikke vÃ¦re blank"
+        too_long: "er for lang (maksimum %{count} tegn)"
+        too_short: "er for kort (minimum %{count} tegn)"
+        wrong_length: "er av feil lengde (maksimum %{count} tegn)"
+        taken: "er allerede i bruk"
+        not_a_number: "er ikke et tall"
+        greater_than: "mÃ¥ vÃ¦re stÃ¸rre enn %{count}"
+        greater_than_or_equal_to: "mÃ¥ vÃ¦re stÃ¸rre enn eller lik %{count}"
+        equal_to: "mÃ¥ vÃ¦re lik %{count}"
+        less_than: "mÃ¥ vÃ¦re mindre enn %{count}"
+        less_than_or_equal_to: "mÃ¥ vÃ¦re mindre enn eller lik %{count}"
+        odd: "mÃ¥ vÃ¦re oddetall"
+        even: "mÃ¥ vÃ¦re partall"
+        greater_than_start_date: "mÃ¥ vÃ¦re stÃ¸rre enn startdato"
+        not_same_project: "hÃ¸rer ikke til samme prosjekt"
+        circular_dependency: "Denne relasjonen ville lagd en sirkulÃ¦r avhengighet"
+        cant_link_an_issue_with_a_descendant: "En sak kan ikke kobles mot en av sine undersaker"
+
+
+  actionview_instancetag_blank_option: Vennligst velg
+
+  general_text_No: 'Nei'
+  general_text_Yes: 'Ja'
+  general_text_no: 'nei'
+  general_text_yes: 'ja'
+  general_lang_name: 'Norwegian (Norsk bokmÃ¥l)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Kontoen er oppdatert.
+  notice_account_invalid_creditentials: Feil brukernavn eller passord
+  notice_account_password_updated: Passordet er oppdatert.
+  notice_account_wrong_password: Feil passord
+  notice_account_register_done: Kontoen er opprettet. Klikk lenken som er sendt deg i e-post for Ã¥ aktivere kontoen.
+  notice_account_unknown_email: Ukjent bruker.
+  notice_can_t_change_password: Denne kontoen bruker ekstern godkjenning. Passordet kan ikke endres.
+  notice_account_lost_email_sent: En e-post med instruksjoner for Ã¥ velge et nytt passord er sendt til deg.
+  notice_account_activated: Din konto er aktivert. Du kan nÃ¥ logge inn.
+  notice_successful_create: Opprettet.
+  notice_successful_update: Oppdatert.
+  notice_successful_delete: Slettet.
+  notice_successful_connection: Koblet opp.
+  notice_file_not_found: Siden du forsÃ¸kte Ã¥ vise eksisterer ikke, eller er slettet.
+  notice_locking_conflict: Data har blitt oppdatert av en annen bruker.
+  notice_not_authorized: Du har ikke adgang til denne siden.
+  notice_email_sent: "En e-post er sendt til %{value}"
+  notice_email_error: "En feil oppstod under sending av e-post (%{value})"
+  notice_feeds_access_key_reseted: Din RSS-tilgangsnÃ¸kkel er nullstilt.
+  notice_failed_to_save_issues: "Lykkes ikke Ã¥ lagre %{count} sak(er) pÃ¥ %{total} valgt: %{ids}."
+  notice_no_issue_selected: "Ingen sak valgt! Vennligst merk sakene du vil endre."
+  notice_account_pending: "Din konto ble opprettet og avventer nÃ¥ administrativ godkjenning."
+  notice_default_data_loaded: Standardkonfigurasjonen lastet inn.
+
+  error_can_t_load_default_data: "Standardkonfigurasjonen kunne ikke lastes inn: %{value}"
+  error_scm_not_found: "Elementet og/eller revisjonen eksisterer ikke i depoet."
+  error_scm_command_failed: "En feil oppstod under tilkobling til depoet: %{value}"
+  error_scm_annotate: "Elementet eksisterer ikke, eller kan ikke noteres."
+  error_issue_not_found_in_project: 'Saken eksisterer ikke, eller hÃ¸rer ikke til dette prosjektet'
+
+  mail_subject_lost_password: "Ditt %{value} passord"
+  mail_body_lost_password: 'Klikk fÃ¸lgende lenke for Ã¥ endre ditt passord:'
+  mail_subject_register: "%{value} kontoaktivering"
+  mail_body_register: 'Klikk fÃ¸lgende lenke for Ã¥ aktivere din konto:'
+  mail_body_account_information_external: "Du kan bruke din %{value}-konto for Ã¥ logge inn."
+  mail_body_account_information: Informasjon om din konto
+  mail_subject_account_activation_request: "%{value} kontoaktivering"
+  mail_body_account_activation_request: "En ny bruker (%{value}) er registrert, og avventer din godkjenning:"
+  mail_subject_reminder: "%{count} sak(er) har frist de kommende %{days} dagene"
+  mail_body_reminder: "%{count} sak(er) som er tildelt deg har frist de kommende %{days} dager:"
+
+
+  field_name: Navn
+  field_description: Beskrivelse
+  field_summary: Oppsummering
+  field_is_required: Kreves
+  field_firstname: Fornavn
+  field_lastname: Etternavn
+  field_mail: E-post
+  field_filename: Fil
+  field_filesize: StÃ¸rrelse
+  field_downloads: Nedlastinger
+  field_author: Forfatter
+  field_created_on: Opprettet
+  field_updated_on: Oppdatert
+  field_field_format: Format
+  field_is_for_all: For alle prosjekter
+  field_possible_values: Lovlige verdier
+  field_regexp: Regular expression
+  field_min_length: Minimum lengde
+  field_max_length: Maksimum lengde
+  field_value: Verdi
+  field_category: Kategori
+  field_title: Tittel
+  field_project: Prosjekt
+  field_issue: Sak
+  field_status: Status
+  field_notes: Notater
+  field_is_closed: Lukker saken
+  field_is_default: Standardverdi
+  field_tracker: Sakstype
+  field_subject: Emne
+  field_due_date: Frist
+  field_assigned_to: Tildelt til
+  field_priority: Prioritet
+  field_fixed_version: MÃ¥l-versjon
+  field_user: Bruker
+  field_role: Rolle
+  field_homepage: Hjemmeside
+  field_is_public: Offentlig
+  field_parent: Underprosjekt av
+  field_is_in_roadmap: Vises i veikart
+  field_login: Brukernavn
+  field_mail_notification: E-post-varsling
+  field_admin: Administrator
+  field_last_login_on: Sist innlogget
+  field_language: SprÃ¥k
+  field_effective_date: Dato
+  field_password: Passord
+  field_new_password: Nytt passord
+  field_password_confirmation: Bekreft passord
+  field_version: Versjon
+  field_type: Type
+  field_host: Vert
+  field_port: Port
+  field_account: Konto
+  field_base_dn: Base DN
+  field_attr_login: Brukernavnsattributt
+  field_attr_firstname: Fornavnsattributt
+  field_attr_lastname: Etternavnsattributt
+  field_attr_mail: E-post-attributt
+  field_onthefly: On-the-fly brukeropprettelse
+  field_start_date: Start
+  field_done_ratio: "% Ferdig"
+  field_auth_source: Autentiseringskilde
+  field_hide_mail: Skjul min epost-adresse
+  field_comments: Kommentarer
+  field_url: URL
+  field_start_page: Startside
+  field_subproject: Underprosjekt
+  field_hours: Timer
+  field_activity: Aktivitet
+  field_spent_on: Dato
+  field_identifier: Identifikasjon
+  field_is_filter: Brukes som filter
+  field_issue_to: Relaterte saker
+  field_delay: Forsinkelse
+  field_assignable: Saker kan tildeles denne rollen
+  field_redirect_existing_links: Viderekoble eksisterende lenker
+  field_estimated_hours: Estimert tid
+  field_column_names: Kolonner
+  field_time_zone: Tidssone
+  field_searchable: SÃ¸kbar
+  field_default_value: Standardverdi
+  field_comments_sorting: Vis kommentarer
+
+  setting_app_title: Applikasjonstittel
+  setting_app_subtitle: Applikasjonens undertittel
+  setting_welcome_text: Velkomsttekst
+  setting_default_language: StandardsprÃ¥k
+  setting_login_required: Krever innlogging
+  setting_self_registration: Selvregistrering
+  setting_attachment_max_size: Maks. stÃ¸rrelse vedlegg
+  setting_issues_export_limit: Eksportgrense for saker
+  setting_mail_from: Avsenders epost
+  setting_bcc_recipients: Blindkopi (bcc) til mottakere
+  setting_host_name: Vertsnavn
+  setting_text_formatting: Tekstformattering
+  setting_wiki_compression: Komprimering av Wiki-historikk
+  setting_feeds_limit: Innholdsgrense for Feed
+  setting_default_projects_public: Nye prosjekter er offentlige som standard
+  setting_autofetch_changesets: Autohenting av endringssett
+  setting_sys_api_enabled: Aktiver webservice for depot-administrasjon
+  setting_commit_ref_keywords: NÃ¸kkelord for referanse
+  setting_commit_fix_keywords: NÃ¸kkelord for retting
+  setting_autologin: Autoinnlogging
+  setting_date_format: Datoformat
+  setting_time_format: Tidsformat
+  setting_cross_project_issue_relations: Tillat saksrelasjoner pÃ¥ kryss av prosjekter
+  setting_issue_list_default_columns: Standardkolonner vist i sakslisten
+  setting_emails_footer: Epost-signatur
+  setting_protocol: Protokoll
+  setting_per_page_options: Alternativer, objekter pr. side
+  setting_user_format: Visningsformat, brukere
+  setting_activity_days_default: Dager vist pÃ¥ prosjektaktivitet
+  setting_display_subprojects_issues: Vis saker fra underprosjekter pÃ¥ hovedprosjekt som standard
+  setting_enabled_scm: Aktiviserte SCM
+
+  project_module_issue_tracking: SakshÃ¥ndtering
+  project_module_time_tracking: Tidsregistrering
+  project_module_news: Nyheter
+  project_module_documents: Dokumenter
+  project_module_files: Filer
+  project_module_wiki: Wiki
+  project_module_repository: Depot
+  project_module_boards: Forumer
+
+  label_user: Bruker
+  label_user_plural: Brukere
+  label_user_new: Ny bruker
+  label_project: Prosjekt
+  label_project_new: Nytt prosjekt
+  label_project_plural: Prosjekter
+  label_x_projects:
+    zero:  ingen prosjekter
+    one:   1 prosjekt
+    other: "%{count} prosjekter"
+  label_project_all: Alle prosjekter
+  label_project_latest: Siste prosjekter
+  label_issue: Sak
+  label_issue_new: Ny sak
+  label_issue_plural: Saker
+  label_issue_view_all: Vis alle saker
+  label_issues_by: "Saker etter %{value}"
+  label_issue_added: Sak lagt til
+  label_issue_updated: Sak oppdatert
+  label_document: Dokument
+  label_document_new: Nytt dokument
+  label_document_plural: Dokumenter
+  label_document_added: Dokument lagt til
+  label_role: Rolle
+  label_role_plural: Roller
+  label_role_new: Ny rolle
+  label_role_and_permissions: Roller og rettigheter
+  label_member: Medlem
+  label_member_new: Nytt medlem
+  label_member_plural: Medlemmer
+  label_tracker: Sakstype
+  label_tracker_plural: Sakstyper
+  label_tracker_new: Ny sakstype
+  label_workflow: Arbeidsflyt
+  label_issue_status: Saksstatus
+  label_issue_status_plural: Saksstatuser
+  label_issue_status_new: Ny status
+  label_issue_category: Sakskategori
+  label_issue_category_plural: Sakskategorier
+  label_issue_category_new: Ny kategori
+  label_custom_field: Eget felt
+  label_custom_field_plural: Egne felt
+  label_custom_field_new: Nytt eget felt
+  label_enumerations: Listeverdier
+  label_enumeration_new: Ny verdi
+  label_information: Informasjon
+  label_information_plural: Informasjon
+  label_please_login: Vennlist logg inn
+  label_register: Registrer
+  label_password_lost: Mistet passord
+  label_home: Hjem
+  label_my_page: Min side
+  label_my_account: Min konto
+  label_my_projects: Mine prosjekter
+  label_administration: Administrasjon
+  label_login: Logg inn
+  label_logout: Logg ut
+  label_help: Hjelp
+  label_reported_issues: Rapporterte saker
+  label_assigned_to_me_issues: Saker tildelt meg
+  label_last_login: Sist innlogget
+  label_registered_on: Registrert
+  label_activity: Aktivitet
+  label_overall_activity: All aktivitet
+  label_new: Ny
+  label_logged_as: Innlogget som
+  label_environment: MiljÃ¸
+  label_authentication: Autentisering
+  label_auth_source: Autentiseringskilde
+  label_auth_source_new: Ny autentiseringskilde
+  label_auth_source_plural: Autentiseringskilder
+  label_subproject_plural: Underprosjekter
+  label_and_its_subprojects: "%{value} og dets underprosjekter"
+  label_min_max_length: Min.-maks. lengde
+  label_list: Liste
+  label_date: Dato
+  label_integer: Heltall
+  label_float: Kommatall
+  label_boolean: Sann/usann
+  label_string: Tekst
+  label_text: Lang tekst
+  label_attribute: Attributt
+  label_attribute_plural: Attributter
+  label_no_data: Ingen data Ã¥ vise
+  label_change_status: Endre status
+  label_history: Historikk
+  label_attachment: Fil
+  label_attachment_new: Ny fil
+  label_attachment_delete: Slett fil
+  label_attachment_plural: Filer
+  label_file_added: Fil lagt til
+  label_report: Rapport
+  label_report_plural: Rapporter
+  label_news: Nyheter
+  label_news_new: Legg til nyhet
+  label_news_plural: Nyheter
+  label_news_latest: Siste nyheter
+  label_news_view_all: Vis alle nyheter
+  label_news_added: Nyhet lagt til
+  label_settings: Innstillinger
+  label_overview: Oversikt
+  label_version: Versjon
+  label_version_new: Ny versjon
+  label_version_plural: Versjoner
+  label_confirmation: Bekreftelse
+  label_export_to: Eksporter til
+  label_read: Leser...
+  label_public_projects: Offentlige prosjekt
+  label_open_issues: Ã¥pen
+  label_open_issues_plural: Ã¥pne
+  label_closed_issues: lukket
+  label_closed_issues_plural: lukkede
+  label_x_open_issues_abbr_on_total:
+    zero:  0 Ã¥pne / %{total}
+    one:   1 Ã¥pen / %{total}
+    other: "%{count} Ã¥pne / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 Ã¥pne
+    one:   1 Ã¥pen
+    other: "%{count} Ã¥pne"
+  label_x_closed_issues_abbr:
+    zero:  0 lukket
+    one:   1 lukket
+    other: "%{count} lukket"
+  label_total: Totalt
+  label_permissions: Rettigheter
+  label_current_status: NÃ¥vÃ¦rende status
+  label_new_statuses_allowed: Tillate nye statuser
+  label_all: alle
+  label_none: ingen
+  label_nobody: ingen
+  label_next: Neste
+  label_previous: Forrige
+  label_used_by: Brukt av
+  label_details: Detaljer
+  label_add_note: Legg til notat
+  label_per_page: Pr. side
+  label_calendar: Kalender
+  label_months_from: mÃ¥neder fra
+  label_gantt: Gantt
+  label_internal: Intern
+  label_last_changes: "siste %{count} endringer"
+  label_change_view_all: Vis alle endringer
+  label_personalize_page: Tilpass denne siden
+  label_comment: Kommentar
+  label_comment_plural: Kommentarer
+  label_x_comments:
+    zero: ingen kommentarer
+    one: 1 kommentar
+    other: "%{count} kommentarer"
+  label_comment_add: Legg til kommentar
+  label_comment_added: Kommentar lagt til
+  label_comment_delete: Slett kommentar
+  label_query: Egen spÃ¸rring
+  label_query_plural: Egne spÃ¸rringer
+  label_query_new: Ny spÃ¸rring
+  label_filter_add: Legg til filter
+  label_filter_plural: Filtre
+  label_equals: er
+  label_not_equals: er ikke
+  label_in_less_than: er mindre enn
+  label_in_more_than: in mer enn
+  label_in: i
+  label_today: idag
+  label_all_time: all tid
+  label_yesterday: i gÃ¥r
+  label_this_week: denne uken
+  label_last_week: sist uke
+  label_last_n_days: "siste %{count} dager"
+  label_this_month: denne mÃ¥neden
+  label_last_month: siste mÃ¥ned
+  label_this_year: dette Ã¥ret
+  label_date_range: Dato-spenn
+  label_less_than_ago: mindre enn dager siden
+  label_more_than_ago: mer enn dager siden
+  label_ago: dager siden
+  label_contains: inneholder
+  label_not_contains: ikke inneholder
+  label_day_plural: dager
+  label_repository: Depot
+  label_repository_plural: Depoter
+  label_browse: Utforsk
+  label_revision: Revisjon
+  label_revision_plural: Revisjoner
+  label_associated_revisions: Assosierte revisjoner
+  label_added: lagt til
+  label_modified: endret
+  label_deleted: slettet
+  label_latest_revision: Siste revisjon
+  label_latest_revision_plural: Siste revisjoner
+  label_view_revisions: Vis revisjoner
+  label_max_size: Maksimum stÃ¸rrelse
+  label_sort_highest: Flytt til toppen
+  label_sort_higher: Flytt opp
+  label_sort_lower: Flytt ned
+  label_sort_lowest: Flytt til bunnen
+  label_roadmap: Veikart
+  label_roadmap_due_in: "Frist om %{value}"
+  label_roadmap_overdue: "%{value} over fristen"
+  label_roadmap_no_issues: Ingen saker for denne versjonen
+  label_search: SÃ¸k
+  label_result_plural: Resultater
+  label_all_words: Alle ord
+  label_wiki: Wiki
+  label_wiki_edit: Wiki endring
+  label_wiki_edit_plural: Wiki endringer
+  label_wiki_page: Wiki-side
+  label_wiki_page_plural: Wiki-sider
+  label_index_by_title: Indekser etter tittel
+  label_index_by_date: Indekser etter dato
+  label_current_version: Gjeldende versjon
+  label_preview: ForhÃ¥ndsvis
+  label_feed_plural: Feeder
+  label_changes_details: Detaljer om alle endringer
+  label_issue_tracking: SakshÃ¥ndtering
+  label_spent_time: Brukt tid
+  label_f_hour: "%{value} time"
+  label_f_hour_plural: "%{value} timer"
+  label_time_tracking: Tidsregistrering
+  label_change_plural: Endringer
+  label_statistics: Statistikk
+  label_commits_per_month: Innsendinger pr. mÃ¥ned
+  label_commits_per_author: Innsendinger pr. forfatter
+  label_view_diff: Vis forskjeller
+  label_diff_inline: i teksten
+  label_diff_side_by_side: side ved side
+  label_options: Alternativer
+  label_copy_workflow_from: Kopier arbeidsflyt fra
+  label_permissions_report: Rettighetsrapport
+  label_watched_issues: OvervÃ¥kede saker
+  label_related_issues: Relaterte saker
+  label_applied_status: Gitt status
+  label_loading: Laster...
+  label_relation_new: Ny relasjon
+  label_relation_delete: Slett relasjon
+  label_relates_to: relatert til
+  label_duplicates: dupliserer
+  label_duplicated_by: duplisert av
+  label_blocks: blokkerer
+  label_blocked_by: blokkert av
+  label_precedes: kommer fÃ¸r
+  label_follows: fÃ¸lger
+  label_end_to_start: slutt til start
+  label_end_to_end: slutt til slutt
+  label_start_to_start: start til start
+  label_start_to_end: start til slutt
+  label_stay_logged_in: Hold meg innlogget
+  label_disabled: avslÃ¥tt
+  label_show_completed_versions: Vis ferdige versjoner
+  label_me: meg
+  label_board: Forum
+  label_board_new: Nytt forum
+  label_board_plural: Forumer
+  label_topic_plural: Emner
+  label_message_plural: Meldinger
+  label_message_last: Siste melding
+  label_message_new: Ny melding
+  label_message_posted: Melding lagt til
+  label_reply_plural: Svar
+  label_send_information: Send kontoinformasjon til brukeren
+  label_year: Ã…r
+  label_month: MÃ¥ned
+  label_week: Uke
+  label_date_from: Fra
+  label_date_to: Til
+  label_language_based: Basert pÃ¥ brukerens sprÃ¥k
+  label_sort_by: "Sorter etter %{value}"
+  label_send_test_email: Send en epost-test
+  label_feeds_access_key_created_on: "RSS tilgangsnÃ¸kkel opprettet for %{value} siden"
+  label_module_plural: Moduler
+  label_added_time_by: "Lagt til av %{author} for %{age} siden"
+  label_updated_time: "Oppdatert for %{value} siden"
+  label_jump_to_a_project: GÃ¥ til et prosjekt...
+  label_file_plural: Filer
+  label_changeset_plural: Endringssett
+  label_default_columns: Standardkolonner
+  label_no_change_option: (Ingen endring)
+  label_bulk_edit_selected_issues: Samlet endring av valgte saker
+  label_theme: Tema
+  label_default: Standard
+  label_search_titles_only: SÃ¸k bare i titler
+  label_user_mail_option_all: "For alle hendelser pÃ¥ mine prosjekter"
+  label_user_mail_option_selected: "For alle hendelser pÃ¥ valgte prosjekt..."
+  label_user_mail_no_self_notified: "Jeg vil ikke bli varslet om endringer jeg selv gjÃ¸r"
+  label_registration_activation_by_email: kontoaktivering pr. e-post
+  label_registration_manual_activation: manuell kontoaktivering
+  label_registration_automatic_activation: automatisk kontoaktivering
+  label_display_per_page: "Pr. side: %{value}"
+  label_age: Alder
+  label_change_properties: Endre egenskaper
+  label_general: Generell
+  label_more: Mer
+  label_scm: SCM
+  label_plugins: Tillegg
+  label_ldap_authentication: LDAP-autentisering
+  label_downloads_abbr: Nedl.
+  label_optional_description: Valgfri beskrivelse
+  label_add_another_file: Legg til en fil til
+  label_preferences: Brukerinnstillinger
+  label_chronological_order: I kronologisk rekkefÃ¸lge
+  label_reverse_chronological_order: I omvendt kronologisk rekkefÃ¸lge
+  label_planning: Planlegging
+
+  button_login: Logg inn
+  button_submit: Send
+  button_save: Lagre
+  button_check_all: Merk alle
+  button_uncheck_all: Avmerk alle
+  button_delete: Slett
+  button_create: Opprett
+  button_test: Test
+  button_edit: Endre
+  button_add: Legg til
+  button_change: Endre
+  button_apply: Bruk
+  button_clear: Nullstill
+  button_lock: LÃ¥s
+  button_unlock: LÃ¥s opp
+  button_download: Last ned
+  button_list: Liste
+  button_view: Vis
+  button_move: Flytt
+  button_back: Tilbake
+  button_cancel: Avbryt
+  button_activate: Aktiver
+  button_sort: Sorter
+  button_log_time: Logg tid
+  button_rollback: Rull tilbake til denne versjonen
+  button_watch: OvervÃ¥k
+  button_unwatch: Stopp overvÃ¥kning
+  button_reply: Svar
+  button_archive: Arkiver
+  button_unarchive: GjÃ¸r om arkivering
+  button_reset: Nullstill
+  button_rename: Endre navn
+  button_change_password: Endre passord
+  button_copy: Kopier
+  button_annotate: NotÃ©r
+  button_update: Oppdater
+  button_configure: Konfigurer
+
+  status_active: aktiv
+  status_registered: registrert
+  status_locked: lÃ¥st
+
+  text_select_mail_notifications: Velg hendelser som skal varsles med e-post.
+  text_regexp_info: f.eks. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 betyr ingen begrensning
+  text_project_destroy_confirmation: Er du sikker pÃ¥ at du vil slette dette prosjekter og alle relatert data ?
+  text_subprojects_destroy_warning: "Underprojekt(ene): %{value} vil ogsÃ¥ bli slettet."
+  text_workflow_edit: Velg en rolle og en sakstype for Ã¥ endre arbeidsflyten
+  text_are_you_sure: Er du sikker ?
+  text_tip_issue_begin_day: oppgaven starter denne dagen
+  text_tip_issue_end_day: oppgaven avsluttes denne dagen
+  text_tip_issue_begin_end_day: oppgaven starter og avsluttes denne dagen
+  text_caracters_maximum: "%{count} tegn maksimum."
+  text_caracters_minimum: "MÃ¥ vÃ¦re minst %{count} tegn langt."
+  text_length_between: "Lengde mellom %{min} og %{max} tegn."
+  text_tracker_no_workflow: Ingen arbeidsflyt definert for denne sakstypen
+  text_unallowed_characters: Ugyldige tegn
+  text_comma_separated: Flere verdier tillat (kommaseparert).
+  text_issues_ref_in_commit_messages: Referering og retting av saker i innsendingsmelding
+  text_issue_added: "Sak %{id} er innrapportert av %{author}."
+  text_issue_updated: "Sak %{id} er oppdatert av %{author}."
+  text_wiki_destroy_confirmation: Er du sikker pÃ¥ at du vil slette denne wikien og alt innholdet ?
+  text_issue_category_destroy_question: "Noen saker (%{count}) er lagt til i denne kategorien. Hva vil du gjÃ¸re ?"
+  text_issue_category_destroy_assignments: Fjern bruk av kategorier
+  text_issue_category_reassign_to: OverfÃ¸r sakene til denne kategorien
+  text_user_mail_option: "For ikke-valgte prosjekter vil du bare motta varsling om ting du overvÃ¥ker eller er involveret i (eks. saker du er forfatter av eller er tildelt)."
+  text_no_configuration_data: "Roller, arbeidsflyt, sakstyper og -statuser er ikke konfigurert enda.\nDet anbefales sterkt Ã¥ laste inn standardkonfigurasjonen. Du vil kunne endre denne etter den er innlastet."
+  text_load_default_configuration: Last inn standardkonfigurasjonen
+  text_status_changed_by_changeset: "Brukt i endringssett %{value}."
+  text_issues_destroy_confirmation: 'Er du sikker pÃ¥ at du vil slette valgte sak(er) ?'
+  text_select_project_modules: 'Velg moduler du vil aktivere for dette prosjektet:'
+  text_default_administrator_account_changed: Standard administrator-konto er endret
+  text_file_repository_writable: Fil-arkivet er skrivbart
+  text_rmagick_available: RMagick er tilgjengelig (valgfritt)
+  text_destroy_time_entries_question: "%{hours} timer er fÃ¸rt pÃ¥ sakene du er i ferd med Ã¥ slette. Hva vil du gjÃ¸re ?"
+  text_destroy_time_entries: Slett fÃ¸rte timer
+  text_assign_time_entries_to_project: OverfÃ¸r fÃ¸rte timer til prosjektet
+  text_reassign_time_entries: 'OverfÃ¸r fÃ¸rte timer til denne saken:'
+  text_user_wrote: "%{value} skrev:"
+
+  default_role_manager: Leder
+  default_role_developer: Utvikler
+  default_role_reporter: RapportÃ¸r
+  default_tracker_bug: Feil
+  default_tracker_feature: Funksjon
+  default_tracker_support: Support
+  default_issue_status_new: Ny
+  default_issue_status_in_progress: PÃ¥gÃ¥r
+  default_issue_status_resolved: Avklart
+  default_issue_status_feedback: Tilbakemelding
+  default_issue_status_closed: Lukket
+  default_issue_status_rejected: Avvist
+  default_doc_category_user: Brukerdokumentasjon
+  default_doc_category_tech: Teknisk dokumentasjon
+  default_priority_low: Lav
+  default_priority_normal: Normal
+  default_priority_high: HÃ¸y
+  default_priority_urgent: Haster
+  default_priority_immediate: OmgÃ¥ende
+  default_activity_design: Design
+  default_activity_development: Utvikling
+
+  enumeration_issue_priorities: Sakssprioriteringer
+  enumeration_doc_categories: Dokumentkategorier
+  enumeration_activities: Aktiviteter (tidsregistrering)
+  text_enumeration_category_reassign_to: 'Endre dem til denne verdien:'
+  text_enumeration_destroy_question: "%{count} objekter er endret til denne verdien."
+  label_incoming_emails: Innkommende e-post
+  label_generate_key: Generer en nÃ¸kkel
+  setting_mail_handler_api_enabled: Skru pÃ¥ WS for innkommende epost
+  setting_mail_handler_api_key: API-nÃ¸kkel
+  text_email_delivery_not_configured: "Levering av epost er ikke satt opp, og varsler er skrudd av.\nStill inn din SMTP-tjener i config/configuration.yml og start programmet pÃ¥ nytt for Ã¥ skru det pÃ¥."
+  field_parent_title: Overordnet side
+  label_issue_watchers: OvervÃ¥kere
+  button_quote: Sitat
+  setting_sequential_project_identifiers: Generer sekvensielle prosjekt-IDer
+  notice_unable_delete_version: Kan ikke slette versjonen
+  label_renamed: gitt nytt navn
+  label_copied: kopiert
+  setting_plain_text_mail: kun ren tekst (ikke HTML)
+  permission_view_files: Vise filer
+  permission_edit_issues: Redigere saker
+  permission_edit_own_time_entries: Redigere egne timelister
+  permission_manage_public_queries: Administrere delte sÃ¸k
+  permission_add_issues: Legge inn saker
+  permission_log_time: LoggfÃ¸re timer
+  permission_view_changesets: Vise endringssett
+  permission_view_time_entries: Vise brukte timer
+  permission_manage_versions: Administrere versjoner
+  permission_manage_wiki: Administrere wiki
+  permission_manage_categories: Administrere kategorier for saker
+  permission_protect_wiki_pages: Beskytte wiki-sider
+  permission_comment_news: Kommentere nyheter
+  permission_delete_messages: Slette meldinger
+  permission_select_project_modules: Velge prosjektmoduler
+  permission_edit_wiki_pages: Redigere wiki-sider
+  permission_add_issue_watchers: Legge til overvÃ¥kere
+  permission_view_gantt: Vise gantt-diagram
+  permission_move_issues: Flytte saker
+  permission_manage_issue_relations: Administrere saksrelasjoner
+  permission_delete_wiki_pages: Slette wiki-sider
+  permission_manage_boards: Administrere forum
+  permission_delete_wiki_pages_attachments: Slette vedlegg
+  permission_view_wiki_edits: Vise wiki-historie
+  permission_add_messages: Sende meldinger
+  permission_view_messages: Vise meldinger
+  permission_manage_files: Administrere filer
+  permission_edit_issue_notes: Redigere notater
+  permission_manage_news: Administrere nyheter
+  permission_view_calendar: Vise kalender
+  permission_manage_members: Administrere medlemmer
+  permission_edit_messages: Redigere meldinger
+  permission_delete_issues: Slette saker
+  permission_view_issue_watchers: Vise liste over overvÃ¥kere
+  permission_manage_repository: Administrere depot
+  permission_commit_access: Tilgang til innsending
+  permission_browse_repository: Bla gjennom depot
+  permission_view_documents: Vise dokumenter
+  permission_edit_project: Redigere prosjekt
+  permission_add_issue_notes: Legge til notater
+  permission_save_queries: Lagre sÃ¸k
+  permission_view_wiki_pages: Vise wiki
+  permission_rename_wiki_pages: Gi wiki-sider nytt navn
+  permission_edit_time_entries: Redigere timelister
+  permission_edit_own_issue_notes: Redigere egne notater
+  setting_gravatar_enabled: Bruk Gravatar-brukerikoner
+  label_example: Eksempel
+  text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  permission_edit_own_messages: Rediger egne meldinger
+  permission_delete_own_messages: Slett egne meldinger
+  label_user_activity: "%{value}s aktivitet"
+  label_updated_time_by: "Oppdatert av %{author} for %{age} siden"
+  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
+  setting_diff_max_lines_displayed: Max number of diff lines displayed
+  text_plugin_assets_writable: Plugin assets directory writable
+  warning_attachments_not_saved: "%{count} fil(er) kunne ikke lagres."
+  button_create_and_continue: Opprett og fortsett
+  text_custom_field_possible_values_info: 'En linje for hver verdi'
+  label_display: Visning
+  field_editable: Redigerbar
+  setting_repository_log_display_limit: Maks antall revisjoner vist i fil-loggen
+  setting_file_max_size_displayed: Max size of text files displayed inline
+  field_watcher: OvervÃ¥ker
+  setting_openid: Tillat OpenID innlogging og registrering
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: eller logg inn med OpenID
+  field_content: Innhold
+  label_descending: Synkende
+  label_sort: Sorter
+  label_ascending: Stigende
+  label_date_from_to: Fra %{start} til %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Denne siden har %{descendants} underside(r). Hva Ã¸nsker du Ã¥ gjÃ¸re?
+  text_wiki_page_reassign_children: Tilknytt undersider til denne overordnede siden
+  text_wiki_page_nullify_children: Behold undersider som rotsider
+  text_wiki_page_destroy_children: Slett undersider og alle deres underliggende sider
+  setting_password_min_length: Minimum passordlengde
+  field_group_by: Grupper resultater etter
+  mail_subject_wiki_content_updated: "Wiki-side '%{id}' er oppdatert"
+  label_wiki_content_added: Wiki-side opprettet
+  mail_subject_wiki_content_added: "Wiki-side '%{id}' er opprettet"
+  mail_body_wiki_content_added: Wiki-siden '%{id}' ble opprettet av %{author}.
+  label_wiki_content_updated: Wiki-side oppdatert
+  mail_body_wiki_content_updated: Wiki-siden '%{id}' ble oppdatert av %{author}.
+  permission_add_project: Opprett prosjekt
+  setting_new_project_user_role_id: Rolle gitt en ikke-administratorbruker som oppretter et prosjekt
+  label_view_all_revisions: Se alle revisjoner
+  label_tag: Tag
+  label_branch: Gren
+  error_no_tracker_in_project: Ingen sakstyper er tilknyttet dette prosjektet. Vennligst kontroller prosjektets innstillinger.
+  error_no_default_issue_status: Ingen standard saksstatus er angitt. Vennligst kontroller konfigurasjonen (GÃ¥ til "Administrasjon -> Saksstatuser").
+  text_journal_changed: "%{label} endret fra %{old} til %{new}"
+  text_journal_set_to: "%{label} satt til %{value}"
+  text_journal_deleted: "%{label} slettet (%{old})"
+  label_group_plural: Grupper
+  label_group: Gruppe
+  label_group_new: Ny gruppe
+  label_time_entry_plural: Brukt tid
+  text_journal_added: "%{label} %{value} lagt til"
+  field_active: Aktiv
+  enumeration_system_activity: Systemaktivitet
+  permission_delete_issue_watchers: Slett overvÃ¥kere
+  version_status_closed: stengt
+  version_status_locked: lÃ¥st
+  version_status_open: Ã¥pen
+  error_can_not_reopen_issue_on_closed_version: En sak tilknyttet en stengt versjon kan ikke gjenÃ¥pnes.
+  label_user_anonymous: Anonym
+  button_move_and_follow: Flytt og fÃ¸lg etter
+  setting_default_projects_modules: Standard aktiverte moduler for nye prosjekter
+  setting_gravatar_default: Standard Gravatar-bilde
+  field_sharing: Deling
+  label_version_sharing_hierarchy: Med prosjekt-hierarki
+  label_version_sharing_system: Med alle prosjekter
+  label_version_sharing_descendants: Med underprosjekter
+  label_version_sharing_tree: Med prosjekt-tre
+  label_version_sharing_none: Ikke delt
+  error_can_not_archive_project: Dette prosjektet kan ikke arkiveres
+  button_duplicate: Duplikat
+  button_copy_and_follow: Kopier og fÃ¸lg etter
+  label_copy_source: Kilde
+  setting_issue_done_ratio: Kalkuler ferdigstillingsprosent ut i fra
+  setting_issue_done_ratio_issue_status: Bruk saksstatuser
+  error_issue_done_ratios_not_updated: Ferdigstillingsprosent oppdateres ikke.
+  error_workflow_copy_target: Vennligst velg sakstype(r) og rolle(r)
+  setting_issue_done_ratio_issue_field: Bruk felt fra saker
+  label_copy_same_as_target: Samme som mÃ¥l
+  label_copy_target: MÃ¥l
+  notice_issue_done_ratios_updated: Ferdigstillingsprosent oppdatert.
+  error_workflow_copy_source: Vennligst velg en kilde-sakstype eller rolle.
+  label_update_issue_done_ratios: Oppdatert ferdigstillingsprosent
+  setting_start_of_week: Start kalender pÃ¥
+  permission_view_issues: Se pÃ¥ saker
+  label_display_used_statuses_only: Vis kun statuser som brukes av denne sakstypen
+  label_revision_id: Revision %{value}
+  label_api_access_key: API tilgangsnÃ¸kkel
+  label_api_access_key_created_on: API tilgangsnÃ¸kkel opprettet for %{value} siden
+  label_feeds_access_key: RSS tilgangsnÃ¸kkel
+  notice_api_access_key_reseted: Din API tilgangsnÃ¸kkel ble resatt.
+  setting_rest_api_enabled: Aktiver REST webservice
+  label_missing_api_access_key: Mangler en API tilgangsnÃ¸kkel
+  label_missing_feeds_access_key: Mangler en RSS tilgangsnÃ¸kkel
+  button_show: Vis
+  text_line_separated: Flere verdier er tillatt (en linje per verdi).
+  setting_mail_handler_body_delimiters: Avkort epost etter en av disse linjene
+  permission_add_subprojects: Opprett underprosjekt
+  label_subproject_new: Nytt underprosjekt
+  text_own_membership_delete_confirmation: |-
+    Du er i ferd med Ã¥ fjerne noen eller alle rettigheter og vil kanskje ikke vÃ¦re i stand til Ã¥ redigere dette prosjektet etterpÃ¥.
+    Er du sikker pÃ¥ at du vil fortsette?
+  label_close_versions: Steng fullfÃ¸rte versjoner
+  label_board_sticky: Fast
+  label_board_locked: LÃ¥st
+  permission_export_wiki_pages: Eksporter wiki-sider
+  setting_cache_formatted_text: Mellomlagre formattert tekst
+  permission_manage_project_activities: Administrere prosjektaktiviteter
+  error_unable_delete_issue_status: Kan ikke slette saksstatus
+  label_profile: Profil
+  permission_manage_subtasks: Administrere undersaker
+  field_parent_issue: Overordnet sak
+  label_subtask_plural: Undersaker
+  label_project_copy_notifications: Send epost-varslinger under prosjektkopiering
+  error_can_not_delete_custom_field: Kan ikke slette eget felt
+  error_unable_to_connect: Kunne ikke koble til (%{value})
+  error_can_not_remove_role: Denne rollen er i bruk og kan ikke slettes.
+  error_can_not_delete_tracker: Denne sakstypen inneholder saker og kan ikke slettes.
+  field_principal: Principal
+  label_my_page_block: Min side felt
+  notice_failed_to_save_members: "Feil ved lagring av medlem(mer): %{errors}."
+  text_zoom_out: Zoom ut
+  text_zoom_in: Zoom inn
+  notice_unable_delete_time_entry: Kan ikke slette oppfÃ¸ring fra timeliste.
+  label_overall_spent_time: All tidsbruk
+  field_time_entries: LoggfÃ¸r tid
+  project_module_gantt: Gantt
+  project_module_calendar: Kalender
+  button_edit_associated_wikipage: "Rediger tilhÃ¸rende Wiki-side: %{page_title}"
+  field_text: Tekstfelt
+  label_user_mail_option_only_owner: Kun for ting jeg eier
+  setting_default_notification_option: Standardvalg for varslinger
+  label_user_mail_option_only_my_events: Kun for ting jeg overvÃ¥ker eller er involvert i
+  label_user_mail_option_only_assigned: Kun for ting jeg er tildelt
+  label_user_mail_option_none: Ingen hendelser
+  field_member_of_group: Den tildeltes gruppe
+  field_assigned_to_role: Den tildeltes rolle
+  notice_not_authorized_archived_project: Prosjektet du forsÃ¸ker Ã¥ Ã¥pne er blitt arkivert.
+  label_principal_search: "SÃ¸k etter bruker eller gruppe:"
+  label_user_search: "SÃ¸k etter bruker:"
+  field_visible: Synlig
+  setting_emails_header: Eposthode
+  setting_commit_logtime_activity_id: Aktivitet for logget tid.
+  text_time_logged_by_changeset: Lagt til i endringssett %{value}.
+  setting_commit_logtime_enabled: MuliggjÃ¸r loggfÃ¸ring av tid
+  notice_gantt_chart_truncated: Diagrammet ble avkortet fordi det overstiger det maksimale antall elementer som kan vises (%{max})
+  setting_gantt_items_limit: Maksimalt antall elementer vist pÃ¥ gantt-diagrammet
+  field_warn_on_leaving_unsaved: Vis meg en advarsel nÃ¥r jeg forlater en side med ikke lagret tekst
+  text_warn_on_leaving_unsaved: Siden inneholder tekst som ikke er lagret og som vil bli tapt om du forlater denne siden.
+  label_my_queries: Mine egne spÃ¸rringer
+  text_journal_changed_no_detail: "%{label} oppdatert"
+  label_news_comment_added: Kommentar lagt til en nyhet
+  button_expand_all: Utvid alle
+  button_collapse_all: Kollaps alle
+  label_additional_workflow_transitions_for_assignee: Ytterligere overganger tillatt nÃ¥r brukeren er den som er tildelt saken
+  label_additional_workflow_transitions_for_author: Ytterligere overganger tillatt nÃ¥r brukeren er den som har opprettet saken
+  label_bulk_edit_selected_time_entries: Masserediger valgte timeliste-oppfÃ¸ringer
+  text_time_entries_destroy_confirmation: Er du sikker pÃ¥ du vil slette de(n) valgte timeliste-oppfÃ¸ringen(e)?
+  label_role_anonymous: Anonym
+  label_role_non_member: Ikke medlem
+  label_issue_note_added: Notat lagt til
+  label_issue_status_updated: Status oppdatert
+  label_issue_priority_updated: Prioritet oppdatert
+  label_issues_visibility_own: Saker opprettet av eller tildelt brukeren
+  field_issues_visibility: Synlighet pÃ¥ saker
+  label_issues_visibility_all: Alle saker
+  permission_set_own_issues_private: GjÃ¸r egne saker offentlige eller private
+  field_is_private: Privat
+  permission_set_issues_private: GjÃ¸r saker offentlige eller private
+  label_issues_visibility_public: Alle ikke-private saker
+  text_issues_destroy_descendants_confirmation: Dette vil ogsÃ¥ slette %{count} undersak(er).
+  field_commit_logs_encoding: Tegnkoding for innsendingsmeldinger
+  field_scm_path_encoding: Koding av sti
+  text_scm_path_encoding_note: "Standard: UTF-8"
+  field_path_to_repository: Sti til depot
+  field_root_directory: Rotkatalog
+  field_cvs_module: Modul
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Lokalt depot (f.eks. /hgrepo, c:\hgrepo)
+  text_scm_command: Kommando
+  text_scm_command_version: Versjon
+  label_git_report_last_commit: Rapporter siste innsending for filer og kataloger
+  text_scm_config: Du kan konfigurere scm kommandoer i config/configuration.yml. Vennligst restart applikasjonen etter Ã¥ ha redigert filen.
+  text_scm_command_not_available: Scm kommando er ikke tilgjengelig. Vennligst kontroller innstillingene i administrasjonspanelet.
+
+  text_git_repository_note: Depot er bart og lokalt (f.eks. /gitrepo, c:\gitrepo)
+
+  notice_issue_successful_create: Sak %{id} opprettet.
+  label_between: mellom
+  setting_issue_group_assignment: Tillat tildeling av saker til grupper
+  label_diff: diff
+
+  description_query_sort_criteria_direction: Sorteringsretning
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Oppgi startdato
+  description_message_content: Meldingsinnhold
+  description_available_columns: Tilgjengelige kolonner
+  description_date_range_interval: Velg datointervall ved Ã¥ spesifisere start- og sluttdato
+  description_issue_category_reassign: Choose issue category
+  description_search: SÃ¸kefelt
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Prosjekter
+  description_date_to: Oppgi sluttdato
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Velg ny overordnet side
+  description_selected_columns: Valgte kolonner
+  label_parent_revision: Overordnet
+  label_child_revision: Underordnet
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Bruk dagens dato som startdato for nye saker
+  button_edit_section: Rediger denne seksjonen
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: Alle kolonnene
+  button_export: Eksporter
+  label_export_options: "%{export_format} eksportvalg"
+  error_attachment_too_big: Filen overstiger maksimum filstÃ¸rrelse (%{max_size}) og kan derfor ikke lastes opp
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 saker
+    one:   1 sak
+    other: "%{count} saker"
+  label_repository_new: Nytt depot
+  field_repository_is_default: Hoveddepot
+  label_copy_attachments: Kopier vedlegg
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Kun smÃ¥ bokstaver (a-z), tall, bindestrek (-) og "underscore" (_) er tillatt.<br />Etter lagring er det ikke mulig Ã¥ gjÃ¸re endringer.
+  field_multiple: Flere verdier
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: Saken ble oppdatert av en annen bruker mens du redigerte den.
+  text_issue_conflict_resolution_cancel: Forkast alle endringen mine og vis %{link} pÃ¥ nytt
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Din konto er ugjenkallelig slettet.
+  setting_unsubscribe: Tillat brukere Ã¥ slette sin egen konto
+  button_delete_my_account: Slett kontoen min
+  text_account_destroy_confirmation: |-
+    Er du sikker pÃ¥ at du Ã¸nsker Ã¥ fortsette?
+    Kontoen din vil bli ugjenkallelig slettet uten mulighet for Ã¥ reaktiveres igjen.
+  error_session_expired: Ã˜kten har gÃ¥tt ut pÃ¥ tid. Vennligst logg pÃ¥ igjen.
+  text_session_expiration_settings: "Advarsel: ved Ã¥ endre disse innstillingene kan aktive Ã¸kter gÃ¥ ut pÃ¥ tid, inkludert din egen."
+  setting_session_lifetime: Ã˜ktenes makslengde
+  setting_session_timeout: Ã˜kten er avsluttet pÃ¥ grunn av inaktivitet
+  label_session_expiration: Ã˜kten er avsluttet
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: alle
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Med underprosjekter
+  label_cross_project_tree: Med prosjekt-tre
+  label_cross_project_hierarchy: Med prosjekt-hierarki
+  label_cross_project_system: Med alle prosjekter
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Totalt
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/72/724819b2d9d18cf8969d26980587e66cfd665de8.svn-base
--- /dev/null
+++ b/.svn/pristine/72/724819b2d9d18cf8969d26980587e66cfd665de8.svn-base
@@ -0,0 +1,20 @@
+<%= form_tag({:action => 'edit', :tab => 'projects'}) do %>
+
+<div class="box tabular settings">
+<p><%= setting_check_box :default_projects_public %></p>
+
+<p><%= setting_multiselect(:default_projects_modules,
+        Redmine::AccessControl.available_project_modules.collect {|m| [l_or_humanize(m, :prefix => "project_module_"), m.to_s]}) %></p>
+
+<p><%= setting_multiselect(:default_projects_tracker_ids,
+        Tracker.sorted.all.collect {|t| [t.name, t.id.to_s]}) %></p>
+
+<p><%= setting_check_box :sequential_project_identifiers %></p>
+
+<p><%= setting_select :new_project_user_role_id,
+                      Role.find_all_givable.collect {|r| [r.name, r.id.to_s]},
+                      :blank => "--- #{l(:actionview_instancetag_blank_option)} ---" %></p>
+</div>
+
+<%= submit_tag l(:button_save) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/72/72607bd4ab6cb744483458ba6f765737733a7ddf.svn-base
--- /dev/null
+++ b/.svn/pristine/72/72607bd4ab6cb744483458ba6f765737733a7ddf.svn-base
@@ -0,0 +1,51 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'action_view/helpers/form_helper'
+
+class Redmine::Views::LabelledFormBuilder < ActionView::Helpers::FormBuilder
+  include Redmine::I18n
+
+  (field_helpers.map(&:to_s) - %w(radio_button hidden_field fields_for) +
+        %w(date_select)).each do |selector|
+    src = <<-END_SRC
+    def #{selector}(field, options = {})
+      label_for_field(field, options) + super(field, options.except(:label)).html_safe
+    end
+    END_SRC
+    class_eval src, __FILE__, __LINE__
+  end
+
+  def select(field, choices, options = {}, html_options = {})
+    label_for_field(field, options) + super(field, choices, options, html_options.except(:label)).html_safe
+  end
+
+  def time_zone_select(field, priority_zones = nil, options = {}, html_options = {})
+        label_for_field(field, options) + super(field, priority_zones, options, html_options.except(:label)).html_safe
+  end
+
+  # Returns a label tag for the given field
+  def label_for_field(field, options = {})
+      return ''.html_safe if options.delete(:no_label)
+      text = options[:label].is_a?(Symbol) ? l(options[:label]) : options[:label]
+      text ||= l(("field_" + field.to_s.gsub(/\_id$/, "")).to_sym)
+      text += @template.content_tag("span", " *", :class => "required") if options.delete(:required)
+      @template.content_tag("label", text.html_safe,
+                                     :class => (@object && @object.errors[field].present? ? "error" : nil),
+                                     :for => (@object_name.to_s + "_" + field.to_s))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/72/727598dda4e9d027f8791398b5529d584c755883.svn-base
--- /dev/null
+++ b/.svn/pristine/72/727598dda4e9d027f8791398b5529d584c755883.svn-base
@@ -0,0 +1,1127 @@
+# Swedish translation for Ruby on Rails
+# by Johan LundstrÃ¶m (johanlunds@gmail.com),
+# with parts taken from http://github.com/daniel/swe_rails
+
+sv:
+  number:
+    # Used in number_with_delimiter()
+    # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+    format:
+      # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+      separator: ","
+      # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
+      delimiter: "."
+      # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
+      precision: 2
+
+    # Used in number_to_currency()
+    currency:
+      format:
+        # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+        format: "%n %u"
+        unit: "kr"
+        # These three are to override number.format and are optional
+        # separator: "."
+        # delimiter: ","
+        # precision: 2
+
+    # Used in number_to_percentage()
+    percentage:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # Used in number_to_precision()
+    precision:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # Used in number_to_human_size()
+    human:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+  datetime:
+    distance_in_words:
+      half_a_minute: "en halv minut"
+      less_than_x_seconds:
+        one:   "mindre Ã¤n en sekund"
+        other: "mindre Ã¤n %{count} sekunder"
+      x_seconds:
+        one:   "en sekund"
+        other: "%{count} sekunder"
+      less_than_x_minutes:
+        one:   "mindre Ã¤n en minut"
+        other: "mindre Ã¤n %{count} minuter"
+      x_minutes:
+        one:   "en minut"
+        other: "%{count} minuter"
+      about_x_hours:
+        one:   "ungefÃ¤r en timme"
+        other: "ungefÃ¤r %{count} timmar"
+      x_hours:
+        one:   "1 timme"
+        other: "%{count} timmar"
+      x_days:
+        one:   "en dag"
+        other: "%{count} dagar"
+      about_x_months:
+        one:   "ungefÃ¤r en mÃ¥nad"
+        other: "ungefÃ¤r %{count} mÃ¥nader"
+      x_months:
+        one:   "en mÃ¥nad"
+        other: "%{count} mÃ¥nader"
+      about_x_years:
+        one:   "ungefÃ¤r ett Ã¥r"
+        other: "ungefÃ¤r %{count} Ã¥r"
+      over_x_years:
+        one:   "mer Ã¤n ett Ã¥r"
+        other: "mer Ã¤n %{count} Ã¥r"
+      almost_x_years:
+        one:   "nÃ¤stan 1 Ã¥r"
+        other: "nÃ¤stan %{count} Ã¥r"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "Ett fel fÃ¶rhindrade denna %{model} frÃ¥n att sparas"
+          other:  "%{count} fel fÃ¶rhindrade denna %{model} frÃ¥n att sparas"
+        # The variable :count is also available
+        body: "Det var problem med fÃ¶ljande fÃ¤lt:"
+      # The values :model, :attribute and :value are always available for interpolation
+      # The value :count is available when applicable. Can be used for pluralization.
+      messages:
+        inclusion: "finns inte i listan"
+        exclusion: "Ã¤r reserverat"
+        invalid: "Ã¤r ogiltigt"
+        confirmation: "stÃ¤mmer inte Ã¶verens"
+        accepted : "mÃ¥ste vara accepterad"
+        empty: "fÃ¥r ej vara tom"
+        blank: "mÃ¥ste anges"
+        too_long: "Ã¤r fÃ¶r lÃ¥ng (maximum Ã¤r %{count} tecken)"
+        too_short: "Ã¤r fÃ¶r kort (minimum Ã¤r %{count} tecken)"
+        wrong_length: "har fel lÃ¤ngd (ska vara %{count} tecken)"
+        taken: "har redan tagits"
+        not_a_number: "Ã¤r inte ett nummer"
+        greater_than: "mÃ¥ste vara stÃ¶rre Ã¤n %{count}"
+        greater_than_or_equal_to: "mÃ¥ste vara stÃ¶rre Ã¤n eller lika med %{count}"
+        equal_to: "mÃ¥ste vara samma som"
+        less_than: "mÃ¥ste vara mindre Ã¤n %{count}"
+        less_than_or_equal_to: "mÃ¥ste vara mindre Ã¤n eller lika med %{count}"
+        odd: "mÃ¥ste vara udda"
+        even: "mÃ¥ste vara jÃ¤mnt"
+        greater_than_start_date: "mÃ¥ste vara senare Ã¤n startdatumet"
+        not_same_project: "tillhÃ¶r inte samma projekt"
+        circular_dependency: "Denna relation skulle skapa ett cirkulÃ¤rt beroende"
+        cant_link_an_issue_with_a_descendant: "Ett Ã¤rende kan inte lÃ¤nkas till ett av dess underÃ¤renden"
+
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%e %b"
+      long: "%e %B, %Y"
+
+    day_names: [sÃ¶ndag, mÃ¥ndag, tisdag, onsdag, torsdag, fredag, lÃ¶rdag]
+    abbr_day_names: [sÃ¶n, mÃ¥n, tis, ons, tor, fre, lÃ¶r]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, januari, februari, mars, april, maj, juni, juli, augusti, september, oktober, november, december]
+    abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, dec]
+    # Used in date_select and datime_select.
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%Y-%m-%d %H:%M"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%d %B, %Y %H:%M"
+    am: ""
+    pm: ""
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "och"
+      skip_last_comma: true
+
+  actionview_instancetag_blank_option: Var god vÃ¤lj
+
+  general_text_No: 'Nej'
+  general_text_Yes: 'Ja'
+  general_text_no: 'nej'
+  general_text_yes: 'ja'
+  general_lang_name: 'Svenska'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Kontot har uppdaterats
+  notice_account_invalid_creditentials: Fel anvÃ¤ndarnamn eller lÃ¶senord
+  notice_account_password_updated: LÃ¶senordet har uppdaterats
+  notice_account_wrong_password: Fel lÃ¶senord
+  notice_account_register_done: Kontot har skapats. FÃ¶r att aktivera kontot, klicka pÃ¥ lÃ¤nken i mailet som skickades till dig.
+  notice_account_unknown_email: OkÃ¤nd anvÃ¤ndare.
+  notice_can_t_change_password: Detta konto anvÃ¤nder en extern autentiseringskÃ¤lla. Det gÃ¥r inte att byta lÃ¶senord.
+  notice_account_lost_email_sent: Ett mail med instruktioner om hur man vÃ¤ljer ett nytt lÃ¶senord har skickats till dig.
+  notice_account_activated: Ditt konto har blivit aktiverat. Du kan nu logga in.
+  notice_successful_create: Skapades korrekt.
+  notice_successful_update: Uppdatering lyckades.
+  notice_successful_delete: Borttagning lyckades.
+  notice_successful_connection: Uppkoppling lyckades.
+  notice_file_not_found: Sidan du fÃ¶rsÃ¶kte komma Ã¥t existerar inte eller Ã¤r borttagen.
+  notice_locking_conflict: Data har uppdaterats av en annan anvÃ¤ndare.
+  notice_not_authorized: Du saknar behÃ¶righet att komma Ã¥t den hÃ¤r sidan.
+  notice_not_authorized_archived_project: Projektet du fÃ¶rsÃ¶ker komma Ã¥t har arkiverats.
+  notice_email_sent: "Ett mail skickades till %{value}"
+  notice_email_error: "Ett fel intrÃ¤ffade nÃ¤r mail skickades (%{value})"
+  notice_feeds_access_key_reseted: Din RSS-nyckel Ã¥terstÃ¤lldes.
+  notice_api_access_key_reseted: Din API-nyckel Ã¥terstÃ¤lldes.
+  notice_failed_to_save_issues: "Misslyckades med att spara %{count} Ã¤rende(n) pÃ¥ %{total} valda: %{ids}."
+  notice_failed_to_save_time_entries: "Misslyckades med att spara %{count} tidloggning(ar) pÃ¥ %{total} valda: %{ids}."
+  notice_failed_to_save_members: "Misslyckades med att spara medlem(mar): %{errors}."
+  notice_no_issue_selected: "Inget Ã¤rende Ã¤r markerat! Var vÃ¤nlig, markera de Ã¤renden du vill Ã¤ndra."
+  notice_account_pending: "Ditt konto skapades och avvaktar nu administratÃ¶rens godkÃ¤nnande."
+  notice_default_data_loaded: Standardkonfiguration inlÃ¤st.
+  notice_unable_delete_version: Denna version var inte mÃ¶jlig att ta bort.
+  notice_unable_delete_time_entry: Tidloggning kunde inte tas bort.
+  notice_issue_done_ratios_updated: "% klart uppdaterade."
+  notice_gantt_chart_truncated: "Schemat fÃ¶rminskades eftersom det Ã¶verskrider det maximala antalet aktiviteter som kan visas (%{max})"
+  notice_issue_successful_create: "Ã„rende %{id} skapades."
+  notice_issue_update_conflict: "Detta Ã¤rende har uppdaterats av en annan anvÃ¤ndare samtidigt som du redigerade det."
+  notice_account_deleted: "Ditt konto har avslutats permanent."
+  notice_user_successful_create: "AnvÃ¤ndare %{id} skapad."
+
+  error_can_t_load_default_data: "Standardkonfiguration gick inte att lÃ¤sa in: %{value}"
+  error_scm_not_found: "InlÃ¤gg och/eller revision finns inte i detta versionsarkiv."
+  error_scm_command_failed: "Ett fel intrÃ¤ffade vid fÃ¶rsÃ¶k att nÃ¥ versionsarkivet: %{value}"
+  error_scm_annotate: "InlÃ¤gget existerar inte eller kan inte kommenteras."
+  error_scm_annotate_big_text_file: InlÃ¤gget kan  inte annoteras eftersom det Ã¶verskrider maximal storlek fÃ¶r textfiler.
+  error_issue_not_found_in_project: 'Ã„rendet hittades inte eller sÃ¥ tillhÃ¶r det inte detta projekt'
+  error_no_tracker_in_project: 'Ingen Ã¤rendetyp Ã¤r associerad med projektet. VÃ¤nligen kontrollera projektinstÃ¤llningarna.'
+  error_no_default_issue_status: 'Ingen status Ã¤r definierad som standard fÃ¶r nya Ã¤renden. VÃ¤nligen kontrollera din konfiguration (GÃ¥ till "Administration -> Ã„rendestatus").'
+  error_can_not_delete_custom_field: Kan inte ta bort anvÃ¤ndardefinerat fÃ¤lt
+  error_can_not_delete_tracker: "Det finns Ã¤renden av denna typ och den Ã¤r dÃ¤rfÃ¶r inte mÃ¶jlig att ta bort."
+  error_can_not_remove_role: "Denna roll anvÃ¤nds och den Ã¤r dÃ¤rfÃ¶r inte mÃ¶jlig att ta bort."
+  error_can_not_reopen_issue_on_closed_version: 'Ett Ã¤rende tilldelat en stÃ¤ngd version kan inte Ã¶ppnas pÃ¥ nytt'
+  error_can_not_archive_project: Detta projekt kan inte arkiveras
+  error_issue_done_ratios_not_updated: "% klart inte uppdaterade."
+  error_workflow_copy_source: 'VÃ¤nligen vÃ¤lj kÃ¤llans Ã¤rendetyp eller roll'
+  error_workflow_copy_target: 'VÃ¤nligen vÃ¤lj Ã¤rendetyp(er) och roll(er) fÃ¶r mÃ¥l'
+  error_unable_delete_issue_status: 'Ã„rendestatus kunde inte tas bort'
+  error_unable_to_connect: "Kan inte ansluta (%{value})"
+  error_attachment_too_big: "Denna fil kan inte laddas upp eftersom den Ã¶verstiger maximalt tillÃ¥ten filstorlek (%{max_size})"
+  error_session_expired: "Din session har gÃ¥tt ut. VÃ¤nligen logga in pÃ¥ nytt."
+  warning_attachments_not_saved: "%{count} fil(er) kunde inte sparas."
+
+  mail_subject_lost_password: "Ditt %{value} lÃ¶senord"
+  mail_body_lost_password: 'FÃ¶r att Ã¤ndra ditt lÃ¶senord, klicka pÃ¥ fÃ¶ljande lÃ¤nk:'
+  mail_subject_register: "Din %{value} kontoaktivering"
+  mail_body_register: 'FÃ¶r att aktivera ditt konto, klicka pÃ¥ fÃ¶ljande lÃ¤nk:'
+  mail_body_account_information_external: "Du kan anvÃ¤nda ditt %{value}-konto fÃ¶r att logga in."
+  mail_body_account_information: Din kontoinformation
+  mail_subject_account_activation_request: "%{value} begÃ¤ran om kontoaktivering"
+  mail_body_account_activation_request: "En ny anvÃ¤ndare (%{value}) har registrerat sig och avvaktar ditt godkÃ¤nnande:"
+  mail_subject_reminder: "%{count} Ã¤rende(n) har deadline under de kommande %{days} dagarna"
+  mail_body_reminder: "%{count} Ã¤rende(n) som Ã¤r tilldelat dig har deadline under de %{days} dagarna:"
+  mail_subject_wiki_content_added: "'%{id}' wikisida has lagts till"
+  mail_body_wiki_content_added: "The '%{id}' wikisida has lagts till av %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' wikisida har uppdaterats"
+  mail_body_wiki_content_updated: "The '%{id}' wikisida har uppdaterats av %{author}."
+
+
+  field_name: Namn
+  field_description: Beskrivning
+  field_summary: Sammanfattning
+  field_is_required: Obligatorisk
+  field_firstname: FÃ¶rnamn
+  field_lastname: Efternamn
+  field_mail: Mail
+  field_filename: Fil
+  field_filesize: Storlek
+  field_downloads: Nerladdningar
+  field_author: FÃ¶rfattare
+  field_created_on: Skapad
+  field_updated_on: Uppdaterad
+  field_closed_on: StÃ¤ngd
+  field_field_format: Format
+  field_is_for_all: FÃ¶r alla projekt
+  field_possible_values: MÃ¶jliga vÃ¤rden
+  field_regexp: ReguljÃ¤rt uttryck
+  field_min_length: MinimilÃ¤ngd
+  field_max_length: MaxlÃ¤ngd
+  field_value: VÃ¤rde
+  field_category: Kategori
+  field_title: Titel
+  field_project: Projekt
+  field_issue: Ã„rende
+  field_status: Status
+  field_notes: Anteckningar
+  field_is_closed: Ã„rendet Ã¤r stÃ¤ngt
+  field_is_default: StandardvÃ¤rde
+  field_tracker: Ã„rendetyp
+  field_subject: Ã„mne
+  field_due_date: Deadline
+  field_assigned_to: Tilldelad till
+  field_priority: Prioritet
+  field_fixed_version: VersionsmÃ¥l
+  field_user: AnvÃ¤ndare
+  field_principal: Principal
+  field_role: Roll
+  field_homepage: Hemsida
+  field_is_public: Publik
+  field_parent: Underprojekt till
+  field_is_in_roadmap: Visa Ã¤renden i roadmap
+  field_login: AnvÃ¤ndarnamn
+  field_mail_notification: Mailnotifieringar
+  field_admin: AdministratÃ¶r
+  field_last_login_on: Senaste inloggning
+  field_language: SprÃ¥k
+  field_effective_date: Datum
+  field_password: LÃ¶senord
+  field_new_password: Nytt lÃ¶senord
+  field_password_confirmation: BekrÃ¤fta lÃ¶senord
+  field_version: Version
+  field_type: Typ
+  field_host: VÃ¤rddator
+  field_port: Port
+  field_account: Konto
+  field_base_dn: Bas-DN
+  field_attr_login: Inloggningsattribut
+  field_attr_firstname: FÃ¶rnamnsattribut
+  field_attr_lastname: Efternamnsattribut
+  field_attr_mail: Mailattribut
+  field_onthefly: Skapa anvÃ¤ndare on-the-fly
+  field_start_date: Startdatum
+  field_done_ratio: "% Klart"
+  field_auth_source: AutentiseringslÃ¤ge
+  field_hide_mail: DÃ¶lj min mailadress
+  field_comments: Kommentar
+  field_url: URL
+  field_start_page: Startsida
+  field_subproject: Underprojekt
+  field_hours: Timmar
+  field_activity: Aktivitet
+  field_spent_on: Datum
+  field_identifier: Identifierare
+  field_is_filter: AnvÃ¤nd som filter
+  field_issue_to: Relaterade Ã¤renden
+  field_delay: FÃ¶rdrÃ¶jning
+  field_assignable: Ã„renden kan tilldelas denna roll
+  field_redirect_existing_links: Omdirigera existerande lÃ¤nkar
+  field_estimated_hours: Estimerad tid
+  field_column_names: Kolumner
+  field_time_entries: Spenderad tid
+  field_time_zone: Tidszon
+  field_searchable: SÃ¶kbar
+  field_default_value: StandardvÃ¤rde
+  field_comments_sorting: Visa kommentarer
+  field_parent_title: FÃ¶rÃ¤ldersida
+  field_editable: Redigerbar
+  field_watcher: Bevakare
+  field_identity_url: OpenID URL
+  field_content: InnehÃ¥ll
+  field_group_by: Gruppera resultat efter
+  field_sharing: Delning
+  field_parent_issue: FÃ¶rÃ¤lderaktivitet
+  field_member_of_group: "Tilldelad anvÃ¤ndares grupp"
+  field_assigned_to_role: "Tilldelad anvÃ¤ndares roll"
+  field_text: TextfÃ¤lt
+  field_visible: Synlig
+  field_warn_on_leaving_unsaved: Varna om jag lÃ¤mnar en sida med osparad text
+  field_issues_visibility: Ã„rendesynlighet
+  field_is_private: Privat
+  field_commit_logs_encoding: TeckenuppsÃ¤ttning fÃ¶r commit-meddelanden
+  field_scm_path_encoding: SÃ¶kvÃ¤gskodning
+  field_path_to_repository: SÃ¶kvÃ¤g till versionsarkiv
+  field_root_directory: Rotmapp
+  field_cvsroot: CVSROOT
+  field_cvs_module: Modul
+  field_repository_is_default: Huvudarkiv
+  field_multiple: Flera vÃ¤rden
+  field_auth_source_ldap_filter: LDAP-filter
+  field_core_fields: StandardfÃ¤lt
+  field_timeout: "Timeout (i sekunder)"
+  field_board_parent: FÃ¶rÃ¤lderforum
+  field_private_notes: Privata anteckningar
+  field_inherit_members: Ã„rv medlemmar
+
+  setting_app_title: Applikationsrubrik
+  setting_app_subtitle: Applikationsunderrubrik
+  setting_welcome_text: VÃ¤lkomsttext
+  setting_default_language: StandardsprÃ¥k
+  setting_login_required: KrÃ¤ver inloggning
+  setting_self_registration: SjÃ¤lvregistrering
+  setting_attachment_max_size: Maxstorlek pÃ¥ bilaga
+  setting_issues_export_limit: ExportgrÃ¤ns fÃ¶r Ã¤renden
+  setting_mail_from: AvsÃ¤ndaradress
+  setting_bcc_recipients: Hemlig kopia (bcc) till mottagare
+  setting_plain_text_mail: Oformaterad text i mail (ingen HTML)
+  setting_host_name: VÃ¤rddatornamn
+  setting_text_formatting: Textformatering
+  setting_wiki_compression: Komprimering av wikihistorik
+  setting_feeds_limit: InnehÃ¥llsgrÃ¤ns fÃ¶r Feed
+  setting_default_projects_public: Nya projekt Ã¤r publika
+  setting_autofetch_changesets: Automatisk hÃ¤mtning av commits
+  setting_sys_api_enabled: Aktivera WS fÃ¶r versionsarkivhantering
+  setting_commit_ref_keywords: Referens-nyckelord
+  setting_commit_fix_keywords: Fix-nyckelord
+  setting_autologin: Automatisk inloggning
+  setting_date_format: Datumformat
+  setting_time_format: Tidsformat
+  setting_cross_project_subtasks: TillÃ¥t underaktiviteter mellan projekt
+  setting_cross_project_issue_relations: TillÃ¥t Ã¤renderelationer mellan projekt
+  setting_issue_list_default_columns: Standardkolumner i Ã¤rendelistan
+  setting_repositories_encodings: Encoding fÃ¶r bilagor och versionsarkiv
+  setting_emails_header: Mail-header
+  setting_emails_footer: Signatur
+  setting_protocol: Protokoll
+  setting_per_page_options: Alternativ, objekt per sida
+  setting_user_format: Visningsformat fÃ¶r anvÃ¤ndare
+  setting_activity_days_default: Dagar som visas pÃ¥ projektaktivitet
+  setting_display_subprojects_issues: Visa Ã¤renden frÃ¥n underprojekt i huvudprojekt
+  setting_enabled_scm: Aktivera SCM
+  setting_mail_handler_body_delimiters: "Trunkera mail efter en av fÃ¶ljande rader"
+  setting_mail_handler_api_enabled: Aktivera WS fÃ¶r inkommande mail
+  setting_mail_handler_api_key: API-nyckel
+  setting_sequential_project_identifiers: Generera projektidentifierare sekventiellt
+  setting_gravatar_enabled: AnvÃ¤nd Gravatar-avatarer
+  setting_gravatar_default: FÃ¶rvald Gravatar-bild
+  setting_diff_max_lines_displayed: Maximalt antal synliga rader i diff
+  setting_file_max_size_displayed: Maxstorlek pÃ¥ textfiler som visas inline
+  setting_repository_log_display_limit: Maximalt antal revisioner i filloggen
+  setting_openid: TillÃ¥t inloggning och registrering med OpenID
+  setting_password_min_length: Minsta tillÃ¥tna lÃ¶senordslÃ¤ngd
+  setting_new_project_user_role_id: Tilldelad roll fÃ¶r en icke-administratÃ¶r som skapar ett projekt
+  setting_default_projects_modules: Aktiverade moduler fÃ¶r nya projekt
+  setting_issue_done_ratio: BerÃ¤kna % klart med
+  setting_issue_done_ratio_issue_field: AnvÃ¤nd Ã¤rendefÃ¤ltet
+  setting_issue_done_ratio_issue_status: AnvÃ¤nd Ã¤rendestatus
+  setting_start_of_week: FÃ¶rsta dagen i veckan
+  setting_rest_api_enabled: Aktivera REST webbtjÃ¤nst
+  setting_cache_formatted_text: Cacha formaterad text
+  setting_default_notification_option: Standard notifieringsalternativ
+  setting_commit_logtime_enabled: Aktivera tidloggning
+  setting_commit_logtime_activity_id: Aktivitet fÃ¶r loggad tid
+  setting_gantt_items_limit: Maximalt antal aktiviteter som visas i gantt-schemat
+  setting_issue_group_assignment: TillÃ¥t att Ã¤renden tilldelas till grupper
+  setting_default_issue_start_date_to_creation_date: AnvÃ¤nd dagens datum som startdatum fÃ¶r nya Ã¤renden
+  setting_commit_cross_project_ref: TillÃ¥t Ã¤rende i alla de andra projekten att bli refererade och fixade
+  setting_unsubscribe: TillÃ¥t anvÃ¤ndare att avsluta prenumereration
+  setting_session_lifetime: Maximal sessionslivslÃ¤ngd
+  setting_session_timeout: TidsgrÃ¤ns fÃ¶r sessionsinaktivitet
+  setting_thumbnails_enabled: Visa miniatyrbilder av bilagor
+  setting_thumbnails_size: Storlek pÃ¥ miniatyrbilder (i pixlar)
+  setting_non_working_week_days: Lediga dagar
+  setting_jsonp_enabled: Aktivera JSONP-stÃ¶d
+  setting_default_projects_tracker_ids: StandardÃ¤rendetyper fÃ¶r nya projekt
+
+  permission_add_project: Skapa projekt
+  permission_add_subprojects: Skapa underprojekt
+  permission_edit_project: Ã„ndra projekt
+  permission_close_project: StÃ¤nga / Ã¥terÃ¶ppna projektet
+  permission_select_project_modules: VÃ¤lja projektmoduler
+  permission_manage_members: Hantera medlemmar
+  permission_manage_project_activities: Hantera projektaktiviteter
+  permission_manage_versions: Hantera versioner
+  permission_manage_categories: Hantera Ã¤rendekategorier
+  permission_add_issues: LÃ¤gga till Ã¤renden
+  permission_edit_issues: Ã„ndra Ã¤renden
+  permission_view_issues: Visa Ã¤renden
+  permission_manage_issue_relations: Hantera Ã¤renderelationer
+  permission_set_issues_private: SÃ¤tta Ã¤renden publika eller privata
+  permission_set_own_issues_private: SÃ¤tta egna Ã¤renden publika eller privata
+  permission_add_issue_notes: LÃ¤gga till Ã¤rendeanteckning
+  permission_edit_issue_notes: Ã„ndra Ã¤rendeanteckningar
+  permission_edit_own_issue_notes: Ã„ndra egna Ã¤rendeanteckningar
+  permission_view_private_notes: Visa privata anteckningar
+  permission_set_notes_private: StÃ¤lla in anteckningar som privata
+  permission_move_issues: Flytta Ã¤renden
+  permission_delete_issues: Ta bort Ã¤renden
+  permission_manage_public_queries: Hantera publika frÃ¥gor
+  permission_save_queries: Spara frÃ¥gor
+  permission_view_gantt: Visa Gantt-schema
+  permission_view_calendar: Visa kalender
+  permission_view_issue_watchers: Visa bevakarlista
+  permission_add_issue_watchers: LÃ¤gga till bevakare
+  permission_delete_issue_watchers: Ta bort bevakare
+  permission_log_time: Logga spenderad tid
+  permission_view_time_entries: Visa spenderad tid
+  permission_edit_time_entries: Ã„ndra tidloggningar
+  permission_edit_own_time_entries: Ã„ndra egna tidloggningar
+  permission_manage_news: Hantera nyheter
+  permission_comment_news: Kommentera nyheter
+  permission_view_documents: Visa dokument
+  permission_add_documents: LÃ¤gga till dokument
+  permission_edit_documents: Ã„ndra dokument
+  permission_delete_documents: Ta bort dokument
+  permission_manage_files: Hantera filer
+  permission_view_files: Visa filer
+  permission_manage_wiki: Hantera wiki
+  permission_rename_wiki_pages: Byta namn pÃ¥ wikisidor
+  permission_delete_wiki_pages: Ta bort wikisidor
+  permission_view_wiki_pages: Visa wiki
+  permission_view_wiki_edits: Visa wikihistorik
+  permission_edit_wiki_pages: Ã„ndra wikisidor
+  permission_delete_wiki_pages_attachments: Ta bort bilagor
+  permission_protect_wiki_pages: Skydda wikisidor
+  permission_manage_repository: Hantera versionsarkiv
+  permission_browse_repository: BlÃ¤ddra i versionsarkiv
+  permission_view_changesets: Visa changesets
+  permission_commit_access: Commit-Ã¥tkomst
+  permission_manage_boards: Hantera forum
+  permission_view_messages: Visa meddelanden
+  permission_add_messages: LÃ¤gg till meddelanden
+  permission_edit_messages: Ã„ndra meddelanden
+  permission_edit_own_messages: Ã„ndra egna meddelanden
+  permission_delete_messages: Ta bort meddelanden
+  permission_delete_own_messages: Ta bort egna meddelanden
+  permission_export_wiki_pages: Exportera wikisidor
+  permission_manage_subtasks: Hantera underaktiviteter
+  permission_manage_related_issues: Hantera relaterade Ã¤renden
+
+  project_module_issue_tracking: Ã„rendeuppfÃ¶ljning
+  project_module_time_tracking: TidsuppfÃ¶ljning
+  project_module_news: Nyheter
+  project_module_documents: Dokument
+  project_module_files: Filer
+  project_module_wiki: Wiki
+  project_module_repository: Versionsarkiv
+  project_module_boards: Forum
+  project_module_calendar: Kalender
+  project_module_gantt: Gantt
+
+  label_user: AnvÃ¤ndare
+  label_user_plural: AnvÃ¤ndare
+  label_user_new: Ny anvÃ¤ndare
+  label_user_anonymous: Anonym
+  label_project: Projekt
+  label_project_new: Nytt projekt
+  label_project_plural: Projekt
+  label_x_projects:
+    zero:  inga projekt
+    one:   1 projekt
+    other: "%{count} projekt"
+  label_project_all: Alla projekt
+  label_project_latest: Senaste projekt
+  label_issue: Ã„rende
+  label_issue_new: Nytt Ã¤rende
+  label_issue_plural: Ã„renden
+  label_issue_view_all: Visa alla Ã¤renden
+  label_issues_by: "Ã„renden %{value}"
+  label_issue_added: Ã„rende tillagt
+  label_issue_updated: Ã„rende uppdaterat
+  label_issue_note_added: Anteckning tillagd
+  label_issue_status_updated: Status uppdaterad
+  label_issue_priority_updated: Prioritet uppdaterad
+  label_document: Dokument
+  label_document_new: Nytt dokument
+  label_document_plural: Dokument
+  label_document_added: Dokument tillagt
+  label_role: Roll
+  label_role_plural: Roller
+  label_role_new: Ny roll
+  label_role_and_permissions: Roller och behÃ¶righeter
+  label_role_anonymous: Anonym
+  label_role_non_member: Icke-medlem
+  label_member: Medlem
+  label_member_new: Ny medlem
+  label_member_plural: Medlemmar
+  label_tracker: Ã„rendetyp
+  label_tracker_plural: Ã„rendetyper
+  label_tracker_new: Ny Ã¤rendetyp
+  label_workflow: ArbetsflÃ¶de
+  label_issue_status: Ã„rendestatus
+  label_issue_status_plural: Ã„rendestatus
+  label_issue_status_new: Ny status
+  label_issue_category: Ã„rendekategori
+  label_issue_category_plural: Ã„rendekategorier
+  label_issue_category_new: Ny kategori
+  label_custom_field: AnvÃ¤ndardefinerat fÃ¤lt
+  label_custom_field_plural: AnvÃ¤ndardefinerade fÃ¤lt
+  label_custom_field_new: Nytt anvÃ¤ndardefinerat fÃ¤lt
+  label_enumerations: UpprÃ¤kningar
+  label_enumeration_new: Nytt vÃ¤rde
+  label_information: Information
+  label_information_plural: Information
+  label_please_login: Var god logga in
+  label_register: Registrera
+  label_login_with_open_id_option: eller logga in med OpenID
+  label_password_lost: GlÃ¶mt lÃ¶senord
+  label_home: Hem
+  label_my_page: Min sida
+  label_my_account: Mitt konto
+  label_my_projects: Mina projekt
+  label_my_page_block: '"Min sida"-block'
+  label_administration: Administration
+  label_login: Logga in
+  label_logout: Logga ut
+  label_help: HjÃ¤lp
+  label_reported_issues: Rapporterade Ã¤renden
+  label_assigned_to_me_issues: Ã„renden tilldelade till mig
+  label_last_login: Senaste inloggning
+  label_registered_on: Registrerad
+  label_activity: Aktivitet
+  label_overall_activity: All aktivitet
+  label_user_activity: "Aktiviteter fÃ¶r %{value}"
+  label_new: Ny
+  label_logged_as: Inloggad som
+  label_environment: MiljÃ¶
+  label_authentication: Autentisering
+  label_auth_source: AutentiseringslÃ¤ge
+  label_auth_source_new: Nytt autentiseringslÃ¤ge
+  label_auth_source_plural: AutentiseringslÃ¤gen
+  label_subproject_plural: Underprojekt
+  label_subproject_new: Nytt underprojekt
+  label_and_its_subprojects: "%{value} och dess underprojekt"
+  label_min_max_length: Min./Max.-lÃ¤ngd
+  label_list: Lista
+  label_date: Datum
+  label_integer: Heltal
+  label_float: Flyttal
+  label_boolean: Boolean
+  label_string: Text
+  label_text: LÃ¥ng text
+  label_attribute: Attribut
+  label_attribute_plural: Attribut
+  label_no_data: Ingen data att visa
+  label_change_status: Ã„ndra status
+  label_history: Historia
+  label_attachment: Fil
+  label_attachment_new: Ny fil
+  label_attachment_delete: Ta bort fil
+  label_attachment_plural: Filer
+  label_file_added: Fil tillagd
+  label_report: Rapport
+  label_report_plural: Rapporter
+  label_news: Nyhet
+  label_news_new: LÃ¤gg till nyhet
+  label_news_plural: Nyheter
+  label_news_latest: Senaste nyheterna
+  label_news_view_all: Visa alla nyheter
+  label_news_added: Nyhet tillagd
+  label_news_comment_added: Kommentar tillagd till en nyhet
+  label_settings: InstÃ¤llningar
+  label_overview: Ã–versikt
+  label_version: Version
+  label_version_new: Ny version
+  label_version_plural: Versioner
+  label_close_versions: StÃ¤ng klara versioner
+  label_confirmation: BekrÃ¤ftelse
+  label_export_to: 'Finns Ã¤ven som:'
+  label_read: LÃ¤s...
+  label_public_projects: Publika projekt
+  label_open_issues: Ã¶ppen
+  label_open_issues_plural: Ã¶ppna
+  label_closed_issues: stÃ¤ngd
+  label_closed_issues_plural: stÃ¤ngda
+  label_x_open_issues_abbr_on_total:
+    zero:  0 Ã¶ppna av %{total}
+    one:   1 Ã¶ppen av %{total}
+    other: "%{count} Ã¶ppna av %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 Ã¶ppna
+    one:   1 Ã¶ppen
+    other: "%{count} Ã¶ppna"
+  label_x_closed_issues_abbr:
+    zero:  0 stÃ¤ngda
+    one:   1 stÃ¤ngd
+    other: "%{count} stÃ¤ngda"
+  label_x_issues:
+    zero:  0 Ã¤renden
+    one:   1 Ã¤rende
+    other: "%{count} Ã¤renden"
+  label_total: Total
+  label_total_time: Total tid
+  label_permissions: BehÃ¶righeter
+  label_current_status: Nuvarande status
+  label_new_statuses_allowed: Nya tillÃ¥tna statusvÃ¤rden
+  label_all: alla
+  label_any: vad/vem som helst
+  label_none: inget/ingen
+  label_nobody: ingen
+  label_next: NÃ¤sta
+  label_previous: FÃ¶regÃ¥ende
+  label_used_by: AnvÃ¤nd av
+  label_details: Detaljer
+  label_add_note: LÃ¤gg till anteckning
+  label_per_page: Per sida
+  label_calendar: Kalender
+  label_months_from: mÃ¥nader frÃ¥n
+  label_gantt: Gantt
+  label_internal: Intern
+  label_last_changes: "senaste %{count} Ã¤ndringar"
+  label_change_view_all: Visa alla Ã¤ndringar
+  label_personalize_page: Anpassa denna sida
+  label_comment: Kommentar
+  label_comment_plural: Kommentarer
+  label_x_comments:
+    zero: inga kommentarer
+    one: 1 kommentar
+    other: "%{count} kommentarer"
+  label_comment_add: LÃ¤gg till kommentar
+  label_comment_added: Kommentar tillagd
+  label_comment_delete: Ta bort kommentar
+  label_query: AnvÃ¤ndardefinerad frÃ¥ga
+  label_query_plural: AnvÃ¤ndardefinerade frÃ¥gor
+  label_query_new: Ny frÃ¥ga
+  label_my_queries: Mina egna frÃ¥gor
+  label_filter_add: LÃ¤gg till filter
+  label_filter_plural: Filter
+  label_equals: Ã¤r
+  label_not_equals: Ã¤r inte
+  label_in_less_than: om mindre Ã¤n
+  label_in_more_than: om mer Ã¤n
+  label_in_the_next_days: under kommande
+  label_in_the_past_days: under fÃ¶regÃ¥ende
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_between: mellan
+  label_in: om
+  label_today: idag
+  label_all_time: nÃ¤rsom
+  label_yesterday: igÃ¥r
+  label_this_week: denna vecka
+  label_last_week: senaste veckan
+  label_last_n_weeks: "senaste %{count} veckorna"
+  label_last_n_days: "senaste %{count} dagarna"
+  label_this_month: denna mÃ¥nad
+  label_last_month: senaste mÃ¥naden
+  label_this_year: detta Ã¥ret
+  label_date_range: Datumintervall
+  label_less_than_ago: mindre Ã¤n dagar sedan
+  label_more_than_ago: mer Ã¤n dagar sedan
+  label_ago: dagar sedan
+  label_contains: innehÃ¥ller
+  label_not_contains: innehÃ¥ller inte
+  label_any_issues_in_project: nÃ¥gra Ã¤renden i projektet
+  label_any_issues_not_in_project: nÃ¥gra Ã¤renden utanfÃ¶r projektet
+  label_no_issues_in_project: inga Ã¤renden i projektet
+  label_day_plural: dagar
+  label_repository: Versionsarkiv
+  label_repository_new: Nytt versionsarkiv
+  label_repository_plural: Versionsarkiv
+  label_browse: BlÃ¤ddra
+  label_branch: Branch
+  label_tag: Tag
+  label_revision: Revision
+  label_revision_plural: Revisioner
+  label_revision_id: "Revision %{value}"
+  label_associated_revisions: Associerade revisioner
+  label_added: tillagd
+  label_modified: modifierad
+  label_copied: kopierad
+  label_renamed: omdÃ¶pt
+  label_deleted: borttagen
+  label_latest_revision: Senaste revisionen
+  label_latest_revision_plural: Senaste revisionerna
+  label_view_revisions: Visa revisioner
+  label_view_all_revisions: Visa alla revisioner
+  label_max_size: Maxstorlek
+  label_sort_highest: Flytta till toppen
+  label_sort_higher: Flytta upp
+  label_sort_lower: Flytta ner
+  label_sort_lowest: Flytta till botten
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "FÃ¤rdig om %{value}"
+  label_roadmap_overdue: "%{value} sen"
+  label_roadmap_no_issues: Inga Ã¤renden fÃ¶r denna version
+  label_search: SÃ¶k
+  label_result_plural: Resultat
+  label_all_words: Alla ord
+  label_wiki: Wiki
+  label_wiki_edit: WikiÃ¤ndring
+  label_wiki_edit_plural: WikiÃ¤ndringar
+  label_wiki_page: Wikisida
+  label_wiki_page_plural: Wikisidor
+  label_index_by_title: InnehÃ¥ll efter titel
+  label_index_by_date: InnehÃ¥ll efter datum
+  label_current_version: Nuvarande version
+  label_preview: FÃ¶rhandsgranska
+  label_feed_plural: Feeds
+  label_changes_details: Detaljer om alla Ã¤ndringar
+  label_issue_tracking: Ã„rendeuppfÃ¶ljning
+  label_spent_time: Spenderad tid
+  label_overall_spent_time: Total tid spenderad
+  label_f_hour: "%{value} timme"
+  label_f_hour_plural: "%{value} timmar"
+  label_time_tracking: TidsuppfÃ¶ljning
+  label_change_plural: Ã„ndringar
+  label_statistics: Statistik
+  label_commits_per_month: Commits per mÃ¥nad
+  label_commits_per_author: Commits per fÃ¶rfattare
+  label_diff: diff
+  label_view_diff: Visa skillnader
+  label_diff_inline: i texten
+  label_diff_side_by_side: sida vid sida
+  label_options: InstÃ¤llningar
+  label_copy_workflow_from: Kopiera arbetsflÃ¶de frÃ¥n
+  label_permissions_report: BehÃ¶righetsrapport
+  label_watched_issues: Bevakade Ã¤renden
+  label_related_issues: Relaterade Ã¤renden
+  label_applied_status: Tilldelad status
+  label_loading: Laddar...
+  label_relation_new: Ny relation
+  label_relation_delete: Ta bort relation
+  label_relates_to: Relaterar till
+  label_duplicates: Kopierar
+  label_duplicated_by: Kopierad av
+  label_blocks: Blockerar
+  label_blocked_by: Blockerad av
+  label_precedes: Kommer fÃ¶re
+  label_follows: FÃ¶ljer
+  label_copied_to: Kopierad till
+  label_copied_from: Kopierad frÃ¥n
+  label_end_to_start: slut till start
+  label_end_to_end: slut till slut
+  label_start_to_start: start till start
+  label_start_to_end: start till slut
+  label_stay_logged_in: FÃ¶rbli inloggad
+  label_disabled: inaktiverad
+  label_show_completed_versions: Visa fÃ¤rdiga versioner
+  label_me: mig
+  label_board: Forum
+  label_board_new: Nytt forum
+  label_board_plural: Forum
+  label_board_locked: LÃ¥st
+  label_board_sticky: Sticky
+  label_topic_plural: Ã„mnen
+  label_message_plural: Meddelanden
+  label_message_last: Senaste meddelande
+  label_message_new: Nytt meddelande
+  label_message_posted: Meddelande tillagt
+  label_reply_plural: Svar
+  label_send_information: Skicka kontoinformation till anvÃ¤ndaren
+  label_year: Ã…r
+  label_month: MÃ¥nad
+  label_week: Vecka
+  label_date_from: FrÃ¥n
+  label_date_to: Till
+  label_language_based: SprÃ¥kbaserad
+  label_sort_by: "Sortera pÃ¥ %{value}"
+  label_send_test_email: Skicka testmail
+  label_feeds_access_key: RSS-nyckel
+  label_missing_feeds_access_key: Saknar en RSS-nyckel
+  label_feeds_access_key_created_on: "RSS-nyckel skapad fÃ¶r %{value} sedan"
+  label_module_plural: Moduler
+  label_added_time_by: "Tillagd av %{author} fÃ¶r %{age} sedan"
+  label_updated_time_by: "Uppdaterad av %{author} fÃ¶r %{age} sedan"
+  label_updated_time: "Uppdaterad fÃ¶r %{value} sedan"
+  label_jump_to_a_project: GÃ¥ till projekt...
+  label_file_plural: Filer
+  label_changeset_plural: Changesets
+  label_default_columns: Standardkolumner
+  label_no_change_option: (Ingen Ã¤ndring)
+  label_bulk_edit_selected_issues: Gemensam Ã¤ndring av markerade Ã¤renden
+  label_bulk_edit_selected_time_entries: Gruppredigera valda tidloggningar
+  label_theme: Tema
+  label_default: Standard
+  label_search_titles_only: SÃ¶k endast i titlar
+  label_user_mail_option_all: "FÃ¶r alla hÃ¤ndelser i mina projekt"
+  label_user_mail_option_selected: "FÃ¶r alla hÃ¤ndelser i markerade projekt..."
+  label_user_mail_option_none: "Inga hÃ¤ndelser"
+  label_user_mail_option_only_my_events: "Endast fÃ¶r saker jag bevakar eller Ã¤r inblandad i"
+  label_user_mail_option_only_assigned: "Endast fÃ¶r saker jag Ã¤r tilldelad"
+  label_user_mail_option_only_owner: "Endast fÃ¶r saker jag Ã¤ger"
+  label_user_mail_no_self_notified: "Jag vill inte bli underrÃ¤ttad om Ã¤ndringar som jag har gjort"
+  label_registration_activation_by_email: kontoaktivering med mail
+  label_registration_manual_activation: manuell kontoaktivering
+  label_registration_automatic_activation: automatisk kontoaktivering
+  label_display_per_page: "Per sida: %{value}"
+  label_age: Ã…lder
+  label_change_properties: Ã„ndra instÃ¤llningar
+  label_general: AllmÃ¤nt
+  label_more: Mer
+  label_scm: SCM
+  label_plugins: TillÃ¤gg
+  label_ldap_authentication: LDAP-autentisering
+  label_downloads_abbr: Nerl.
+  label_optional_description: Valfri beskrivning
+  label_add_another_file: LÃ¤gg till ytterligare en fil
+  label_preferences: AnvÃ¤ndarinstÃ¤llningar
+  label_chronological_order: I kronologisk ordning
+  label_reverse_chronological_order: I omvÃ¤nd kronologisk ordning
+  label_planning: Planering
+  label_incoming_emails: Inkommande mail
+  label_generate_key: Generera en nyckel
+  label_issue_watchers: Bevakare
+  label_example: Exempel
+  label_display: Visa
+  label_sort: Sortera
+  label_descending: Fallande
+  label_ascending: Stigande
+  label_date_from_to: FrÃ¥n %{start} till %{end}
+  label_wiki_content_added: Wikisida tillagd
+  label_wiki_content_updated: Wikisida uppdaterad
+  label_group: Grupp
+  label_group_plural: Grupper
+  label_group_new: Ny grupp
+  label_time_entry_plural: Spenderad tid
+  label_version_sharing_none: Inte delad
+  label_version_sharing_descendants: Med underprojekt
+  label_version_sharing_hierarchy: Med projekthierarki
+  label_version_sharing_tree: Med projekttrÃ¤d
+  label_version_sharing_system: Med alla projekt
+  label_update_issue_done_ratios: Uppdatera % klart
+  label_copy_source: KÃ¤lla
+  label_copy_target: MÃ¥l
+  label_copy_same_as_target: Samma som mÃ¥l
+  label_display_used_statuses_only: Visa endast status som anvÃ¤nds av denna Ã¤rendetyp
+  label_api_access_key: API-nyckel
+  label_missing_api_access_key: Saknar en API-nyckel
+  label_api_access_key_created_on: "API-nyckel skapad fÃ¶r %{value} sedan"
+  label_profile: Profil
+  label_subtask_plural: Underaktiviteter
+  label_project_copy_notifications: Skicka mailnotifieringar nÃ¤r projektet kopieras
+  label_principal_search: "SÃ¶k efter anvÃ¤ndare eller grupp:"
+  label_user_search: "SÃ¶k efter anvÃ¤ndare:"
+  label_additional_workflow_transitions_for_author: Ytterligare Ã¶vergÃ¥ngar tillÃ¥tna nÃ¤r anvÃ¤ndaren Ã¤r den som skapat Ã¤rendet
+  label_additional_workflow_transitions_for_assignee: Ytterligare Ã¶vergÃ¥ngar tillÃ¥tna nÃ¤r anvÃ¤ndaren Ã¤r den som tilldelats Ã¤rendet
+  label_issues_visibility_all: Alla Ã¤renden
+  label_issues_visibility_public: Alla icke-privata Ã¤renden
+  label_issues_visibility_own: Ã„renden skapade av eller tilldelade till anvÃ¤ndaren
+  label_git_report_last_commit: Rapportera senaste commit av filer och mappar
+  label_parent_revision: FÃ¶rÃ¤lder
+  label_child_revision: Barn
+  label_export_options: "%{export_format} exportalternativ"
+  label_copy_attachments: Kopiera bilagor
+  label_copy_subtasks: Kopiera underaktiviteter
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Klara versioner
+  label_search_for_watchers: SÃ¶k efter bevakare att lÃ¤gga till
+  label_session_expiration: SessionsutgÃ¥ng
+  label_show_closed_projects: Visa stÃ¤ngda projekt
+  label_status_transitions: StatusÃ¶vergÃ¥ngar
+  label_fields_permissions: FÃ¤ltbehÃ¶righeter
+  label_readonly: Skrivskyddad
+  label_required: NÃ¶dvÃ¤ndig
+  label_attribute_of_project: Projektets %{name}
+  label_attribute_of_issue: Ã„rendets %{name}
+  label_attribute_of_author: FÃ¶rfattarens %{name}
+  label_attribute_of_assigned_to: Tilldelad anvÃ¤ndares %{name}
+  label_attribute_of_user: AnvÃ¤ndarens %{name}
+  label_attribute_of_fixed_version: MÃ¥lversionens %{name}
+  label_cross_project_descendants: Med underprojekt
+  label_cross_project_tree: Med projekttrÃ¤d
+  label_cross_project_hierarchy: Med projekthierarki
+  label_cross_project_system: Med alla projekt
+  label_gantt_progress_line: Framstegslinje
+
+  button_login: Logga in
+  button_submit: Skicka
+  button_save: Spara
+  button_check_all: Markera alla
+  button_uncheck_all: Avmarkera alla
+  button_collapse_all: Kollapsa alla
+  button_expand_all: Expandera alla
+  button_delete: Ta bort
+  button_create: Skapa
+  button_create_and_continue: Skapa och fortsÃ¤tt
+  button_test: Testa
+  button_edit: Ã„ndra
+  button_edit_associated_wikipage: "Ã„ndra associerad Wikisida: %{page_title}"
+  button_add: LÃ¤gg till
+  button_change: Ã„ndra
+  button_apply: VerkstÃ¤ll
+  button_clear: Ã…terstÃ¤ll
+  button_lock: LÃ¥s
+  button_unlock: LÃ¥s upp
+  button_download: Ladda ner
+  button_list: Lista
+  button_view: Visa
+  button_move: Flytta
+  button_move_and_follow: Flytta och fÃ¶lj efter
+  button_back: Tillbaka
+  button_cancel: Avbryt
+  button_activate: Aktivera
+  button_sort: Sortera
+  button_log_time: Logga tid
+  button_rollback: Ã…terstÃ¤ll till denna version
+  button_watch: Bevaka
+  button_unwatch: Stoppa bevakning
+  button_reply: Svara
+  button_archive: Arkivera
+  button_unarchive: Ta bort frÃ¥n arkiv
+  button_reset: Ã…terstÃ¤ll
+  button_rename: Byt namn
+  button_change_password: Ã„ndra lÃ¶senord
+  button_copy: Kopiera
+  button_copy_and_follow: Kopiera och fÃ¶lj efter
+  button_annotate: Kommentera
+  button_update: Uppdatera
+  button_configure: Konfigurera
+  button_quote: Citera
+  button_duplicate: Duplicera
+  button_show: Visa
+  button_hide: GÃ¶m
+  button_edit_section: Redigera denna sektion
+  button_export: Exportera
+  button_delete_my_account: Ta bort mitt konto
+  button_close: StÃ¤ng
+  button_reopen: Ã…terÃ¶ppna
+
+  status_active: aktiv
+  status_registered: registrerad
+  status_locked: lÃ¥st
+
+  project_status_active: aktiv
+  project_status_closed: stÃ¤ngd
+  project_status_archived: arkiverad
+
+  version_status_open: Ã¶ppen
+  version_status_locked: lÃ¥st
+  version_status_closed: stÃ¤ngd
+
+  field_active: Aktiv
+
+  text_select_mail_notifications: VÃ¤lj fÃ¶r vilka hÃ¤ndelser mail ska skickas.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 betyder ingen grÃ¤ns
+  text_project_destroy_confirmation: Ã„r du sÃ¤ker pÃ¥ att du vill ta bort detta projekt och all relaterad data?
+  text_subprojects_destroy_warning: "Alla underprojekt: %{value} kommer ocksÃ¥ tas bort."
+  text_workflow_edit: VÃ¤lj en roll och en Ã¤rendetyp fÃ¶r att Ã¤ndra arbetsflÃ¶de
+  text_are_you_sure: Ã„r du sÃ¤ker ?
+  text_journal_changed: "%{label} Ã¤ndrad frÃ¥n %{old} till %{new}"
+  text_journal_changed_no_detail: "%{label} uppdaterad"
+  text_journal_set_to: "%{label} satt till %{value}"
+  text_journal_deleted: "%{label} borttagen (%{old})"
+  text_journal_added: "%{label} %{value} tillagd"
+  text_tip_issue_begin_day: Ã¤rende som bÃ¶rjar denna dag
+  text_tip_issue_end_day: Ã¤rende som slutar denna dag
+  text_tip_issue_begin_end_day: Ã¤rende som bÃ¶rjar och slutar denna dag
+  text_project_identifier_info: 'Endast gemener (a-z), siffror, streck och understreck Ã¤r tillÃ¥tna, mÃ¥ste bÃ¶rja med en bokstav.<br />NÃ¤r identifieraren sparats kan den inte Ã¤ndras.'
+  text_caracters_maximum: "max %{count} tecken."
+  text_caracters_minimum: "MÃ¥ste vara minst %{count} tecken lÃ¥ng."
+  text_length_between: "LÃ¤ngd mellan %{min} och %{max} tecken."
+  text_tracker_no_workflow: Inget arbetsflÃ¶de definerat fÃ¶r denna Ã¤rendetyp
+  text_unallowed_characters: OtillÃ¥tna tecken
+  text_comma_separated: Flera vÃ¤rden tillÃ¥tna (kommaseparerade).
+  text_line_separated: Flera vÃ¤rden tillÃ¥tna (ett vÃ¤rde per rad).
+  text_issues_ref_in_commit_messages: Referera och fixa Ã¤renden i commit-meddelanden
+  text_issue_added: "Ã„rende %{id} har rapporterats (av %{author})."
+  text_issue_updated: "Ã„rende %{id} har uppdaterats (av %{author})."
+  text_wiki_destroy_confirmation: Ã„r du sÃ¤ker pÃ¥ att du vill ta bort denna wiki och allt dess innehÃ¥ll ?
+  text_issue_category_destroy_question: "NÃ¥gra Ã¤renden (%{count}) Ã¤r tilldelade till denna kategori. Vad vill du gÃ¶ra ?"
+  text_issue_category_destroy_assignments: Ta bort kategoritilldelningar
+  text_issue_category_reassign_to: Ã…tertilldela Ã¤renden till denna kategori
+  text_user_mail_option: "FÃ¶r omarkerade projekt kommer du bara bli underrÃ¤ttad om saker du bevakar eller Ã¤r inblandad i (T.ex. Ã¤renden du skapat eller tilldelats)."
+  text_no_configuration_data: "Roller, Ã¤rendetyper, Ã¤rendestatus och arbetsflÃ¶den har inte konfigurerats Ã¤nnu.\nDet rekommenderas att lÃ¤sa in standardkonfigurationen. Du kommer att kunna gÃ¶ra Ã¤ndringar efter att den blivit inlÃ¤st."
+  text_load_default_configuration: LÃ¤s in standardkonfiguration
+  text_status_changed_by_changeset: "Tilldelad i changeset %{value}."
+  text_time_logged_by_changeset: "Tilldelad i changeset %{value}."
+  text_issues_destroy_confirmation: 'Ã„r du sÃ¤ker pÃ¥ att du vill radera markerade Ã¤rende(n) ?'
+  text_issues_destroy_descendants_confirmation: Detta kommer Ã¤ven ta bort %{count} underaktivitet(er).
+  text_time_entries_destroy_confirmation: Ã„r du sÃ¤ker pÃ¥ att du vill ta bort valda tidloggningar?
+  text_select_project_modules: 'VÃ¤lj vilka moduler som ska vara aktiva fÃ¶r projektet:'
+  text_default_administrator_account_changed: StandardadministratÃ¶rens konto Ã¤ndrat
+  text_file_repository_writable: Arkivet fÃ¶r bifogade filer Ã¤r skrivbart
+  text_plugin_assets_writable: Arkivet fÃ¶r plug-ins Ã¤r skrivbart
+  text_rmagick_available: RMagick tillgÃ¤ngligt (ej obligatoriskt)
+  text_destroy_time_entries_question: "%{hours} timmar har rapporterats pÃ¥ Ã¤rendena du Ã¤r pÃ¥ vÃ¤g att ta bort. Vad vill du gÃ¶ra ?"
+  text_destroy_time_entries: Ta bort rapporterade timmar
+  text_assign_time_entries_to_project: Tilldela rapporterade timmar till projektet
+  text_reassign_time_entries: 'Ã…tertilldela rapporterade timmar till detta Ã¤rende:'
+  text_user_wrote: "%{value} skrev:"
+  text_enumeration_destroy_question: "%{count} objekt Ã¤r tilldelade till detta vÃ¤rde."
+  text_enumeration_category_reassign_to: 'Ã…tertilldela till detta vÃ¤rde:'
+  text_email_delivery_not_configured: "Mailfunktionen har inte konfigurerats, och notifieringar via mail kan dÃ¤rfÃ¶r inte skickas.\nKonfigurera din SMTP-server i config/configuration.yml och starta om applikationen fÃ¶r att aktivera dem."
+  text_repository_usernames_mapping: "VÃ¤lj eller uppdatera den Redmine-anvÃ¤ndare som Ã¤r mappad till varje anvÃ¤ndarnamn i versionarkivloggen.\nAnvÃ¤ndare med samma anvÃ¤ndarnamn eller mailadress i bÃ¥de Redmine och versionsarkivet mappas automatiskt."
+  text_diff_truncated: '... Denna diff har fÃ¶rminskats eftersom den Ã¶verskrider den maximala storlek som kan visas.'
+  text_custom_field_possible_values_info: 'Ett vÃ¤rde per rad'
+  text_wiki_page_destroy_question: "Denna sida har %{descendants} underliggande sidor. Vad vill du gÃ¶ra?"
+  text_wiki_page_nullify_children: "BehÃ¥ll undersidor som rotsidor"
+  text_wiki_page_destroy_children: "Ta bort alla underliggande sidor"
+  text_wiki_page_reassign_children: "Flytta undersidor till denna fÃ¶rÃ¤ldersida"
+  text_own_membership_delete_confirmation: "NÃ¥gra av, eller alla, dina behÃ¶righeter kommer att tas bort och du kanske inte lÃ¤ngre kommer kunna gÃ¶ra Ã¤ndringar i det hÃ¤r projektet.\nVill du verkligen fortsÃ¤tta?"
+  text_zoom_out: Zooma ut
+  text_zoom_in: Zooma in
+  text_warn_on_leaving_unsaved: "Nuvarande sida innehÃ¥ller osparad text som kommer fÃ¶rsvinna om du lÃ¤mnar sidan."
+  text_scm_path_encoding_note: "Standard: UTF-8"
+  text_git_repository_note: Versionsarkiv Ã¤r tomt och lokalt (t.ex. /gitrepo, c:\gitrepo)
+  text_mercurial_repository_note: Lokalt versionsarkiv (t.ex. /hgrepo, c:\hgrepo)
+  text_scm_command: Kommando
+  text_scm_command_version: Version
+  text_scm_config: Du kan konfigurera dina scm-kommando i config/configuration.yml. VÃ¤nligen starta om applikationen nÃ¤r Ã¤ndringar gjorts.
+  text_scm_command_not_available: Scm-kommando Ã¤r inte tillgÃ¤ngligt. VÃ¤nligen kontrollera instÃ¤llningarna i administratÃ¶rspanelen.
+  text_issue_conflict_resolution_overwrite: "AnvÃ¤nd mina Ã¤ndringar i alla fall (tidigare anteckningar kommer behÃ¥llas men nÃ¥gra Ã¤ndringar kan bli Ã¶verskrivna)"
+  text_issue_conflict_resolution_add_notes: "LÃ¤gg till mina anteckningar och kasta mina andra Ã¤ndringar"
+  text_issue_conflict_resolution_cancel: "Kasta alla mina Ã¤ndringar och visa igen %{link}"
+  text_account_destroy_confirmation: "Ã„r du sÃ¤ker pÃ¥ att du vill fortsÃ¤tta?\nDitt konto kommer tas bort permanent, utan mÃ¶jlighet att Ã¥teraktivera det."
+  text_session_expiration_settings: "Varning: Ã¤ndring av dessa instÃ¤llningar kan fÃ¥ alla nuvarande sessioner, inklusive din egen, att gÃ¥ ut."
+  text_project_closed: Detta projekt Ã¤r stÃ¤ngt och skrivskyddat.
+  text_turning_multiple_off: "Om du inaktiverar mÃ¶jligheten till flera vÃ¤rden kommer endast ett vÃ¤rde per objekt behÃ¥llas."
+
+  default_role_manager: Projektledare
+  default_role_developer: Utvecklare
+  default_role_reporter: RapportÃ¶r
+  default_tracker_bug: Bugg
+  default_tracker_feature: Funktionalitet
+  default_tracker_support: Support
+  default_issue_status_new: Ny
+  default_issue_status_in_progress: PÃ¥gÃ¥r
+  default_issue_status_resolved: LÃ¶st
+  default_issue_status_feedback: Ã…terkoppling
+  default_issue_status_closed: StÃ¤ngd
+  default_issue_status_rejected: Avslagen
+  default_doc_category_user: AnvÃ¤ndardokumentation
+  default_doc_category_tech: Teknisk dokumentation
+  default_priority_low: LÃ¥g
+  default_priority_normal: Normal
+  default_priority_high: HÃ¶g
+  default_priority_urgent: BrÃ¥dskande
+  default_priority_immediate: Omedelbar
+  default_activity_design: Design
+  default_activity_development: Utveckling
+
+  enumeration_issue_priorities: Ã„rendeprioriteter
+  enumeration_doc_categories: Dokumentkategorier
+  enumeration_activities: Aktiviteter (tidsuppfÃ¶ljning)
+  enumeration_system_activity: Systemaktivitet
+  description_filter: Filter
+  description_search: SÃ¶kfÃ¤lt
+  description_choose_project: Projekt
+  description_project_scope: SÃ¶komfÃ¥ng
+  description_notes: Anteckningar
+  description_message_content: MeddelandeinnehÃ¥ll
+  description_query_sort_criteria_attribute: Sorteringsattribut
+  description_query_sort_criteria_direction: Sorteringsriktning
+  description_user_mail_notification: MailnotifieringsinstÃ¤llningar
+  description_available_columns: TillgÃ¤ngliga Kolumner
+  description_selected_columns: Valda Kolumner
+  description_all_columns: Alla kolumner
+  description_issue_category_reassign: VÃ¤lj Ã¤rendekategori
+  description_wiki_subpages_reassign: VÃ¤lj ny fÃ¶rÃ¤ldersida
+  description_date_range_list: VÃ¤lj intervall frÃ¥n listan
+  description_date_range_interval: Ange intervall genom att vÃ¤lja start- och slutdatum
+  description_date_from: Ange startdatum
+  description_date_to: Ange slutdatum
+  text_repository_identifier_info: 'Endast gemener (a-z), siffror, streck och understreck Ã¤r tillÃ¥tna.<br />NÃ¤r identifieraren sparats kan den inte Ã¤ndras.'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/72/727874d7bc35b744eb4b647417de27d95212b4b8.svn-base
--- a/.svn/pristine/72/727874d7bc35b744eb4b647417de27d95212b4b8.svn-base
+++ /dev/null
@@ -1,1150 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class IssueTest < ActiveSupport::TestCase
-  fixtures :projects, :users, :members, :member_roles, :roles,
-           :trackers, :projects_trackers,
-           :enabled_modules,
-           :versions,
-           :issue_statuses, :issue_categories, :issue_relations, :workflows,
-           :enumerations,
-           :issues,
-           :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
-           :time_entries
-
-  def test_create
-    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
-                      :status_id => 1, :priority => IssuePriority.all.first,
-                      :subject => 'test_create',
-                      :description => 'IssueTest#test_create', :estimated_hours => '1:30')
-    assert issue.save
-    issue.reload
-    assert_equal 1.5, issue.estimated_hours
-  end
-
-  def test_create_minimal
-    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
-                      :status_id => 1, :priority => IssuePriority.all.first,
-                      :subject => 'test_create')
-    assert issue.save
-    assert issue.description.nil?
-  end
-
-  def test_create_with_required_custom_field
-    field = IssueCustomField.find_by_name('Database')
-    field.update_attribute(:is_required, true)
-
-    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
-                      :status_id => 1, :subject => 'test_create',
-                      :description => 'IssueTest#test_create_with_required_custom_field')
-    assert issue.available_custom_fields.include?(field)
-    # No value for the custom field
-    assert !issue.save
-    assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
-    # Blank value
-    issue.custom_field_values = { field.id => '' }
-    assert !issue.save
-    assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
-    # Invalid value
-    issue.custom_field_values = { field.id => 'SQLServer' }
-    assert !issue.save
-    assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
-    # Valid value
-    issue.custom_field_values = { field.id => 'PostgreSQL' }
-    assert issue.save
-    issue.reload
-    assert_equal 'PostgreSQL', issue.custom_value_for(field).value
-  end
-
-  def test_create_with_group_assignment
-    with_settings :issue_group_assignment => '1' do
-      assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
-                       :subject => 'Group assignment',
-                       :assigned_to_id => 11).save
-      issue = Issue.first(:order => 'id DESC')
-      assert_kind_of Group, issue.assigned_to
-      assert_equal Group.find(11), issue.assigned_to
-    end
-  end
-
-  def assert_visibility_match(user, issues)
-    assert_equal issues.collect(&:id).sort, Issue.all.select {|issue| issue.visible?(user)}.collect(&:id).sort
-  end
-
-  def test_visible_scope_for_anonymous
-    # Anonymous user should see issues of public projects only
-    issues = Issue.visible(User.anonymous).all
-    assert issues.any?
-    assert_nil issues.detect {|issue| !issue.project.is_public?}
-    assert_nil issues.detect {|issue| issue.is_private?}
-    assert_visibility_match User.anonymous, issues
-  end
-
-  def test_visible_scope_for_anonymous_with_own_issues_visibility
-    Role.anonymous.update_attribute :issues_visibility, 'own'
-    Issue.create!(:project_id => 1, :tracker_id => 1,
-                  :author_id => User.anonymous.id,
-                  :subject => 'Issue by anonymous')
-
-    issues = Issue.visible(User.anonymous).all
-    assert issues.any?
-    assert_nil issues.detect {|issue| issue.author != User.anonymous}
-    assert_visibility_match User.anonymous, issues
-  end
-
-  def test_visible_scope_for_anonymous_without_view_issues_permissions
-    # Anonymous user should not see issues without permission
-    Role.anonymous.remove_permission!(:view_issues)
-    issues = Issue.visible(User.anonymous).all
-    assert issues.empty?
-    assert_visibility_match User.anonymous, issues
-  end
-
-  def test_visible_scope_for_non_member
-    user = User.find(9)
-    assert user.projects.empty?
-    # Non member user should see issues of public projects only
-    issues = Issue.visible(user).all
-    assert issues.any?
-    assert_nil issues.detect {|issue| !issue.project.is_public?}
-    assert_nil issues.detect {|issue| issue.is_private?}
-    assert_visibility_match user, issues
-  end
-
-  def test_visible_scope_for_non_member_with_own_issues_visibility
-    Role.non_member.update_attribute :issues_visibility, 'own'
-    Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 9, :subject => 'Issue by non member')
-    user = User.find(9)
-
-    issues = Issue.visible(user).all
-    assert issues.any?
-    assert_nil issues.detect {|issue| issue.author != user}
-    assert_visibility_match user, issues
-  end
-
-  def test_visible_scope_for_non_member_without_view_issues_permissions
-    # Non member user should not see issues without permission
-    Role.non_member.remove_permission!(:view_issues)
-    user = User.find(9)
-    assert user.projects.empty?
-    issues = Issue.visible(user).all
-    assert issues.empty?
-    assert_visibility_match user, issues
-  end
-
-  def test_visible_scope_for_member
-    user = User.find(9)
-    # User should see issues of projects for which he has view_issues permissions only
-    Role.non_member.remove_permission!(:view_issues)
-    Member.create!(:principal => user, :project_id => 3, :role_ids => [2])
-    issues = Issue.visible(user).all
-    assert issues.any?
-    assert_nil issues.detect {|issue| issue.project_id != 3}
-    assert_nil issues.detect {|issue| issue.is_private?}
-    assert_visibility_match user, issues
-  end
-
-  def test_visible_scope_for_member_with_groups_should_return_assigned_issues
-    user = User.find(8)
-    assert user.groups.any?
-    Member.create!(:principal => user.groups.first, :project_id => 1, :role_ids => [2])
-    Role.non_member.remove_permission!(:view_issues)
-    
-    issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
-      :status_id => 1, :priority => IssuePriority.all.first,
-      :subject => 'Assignment test',
-      :assigned_to => user.groups.first,
-      :is_private => true)
-    
-    Role.find(2).update_attribute :issues_visibility, 'default'
-    issues = Issue.visible(User.find(8)).all
-    assert issues.any?
-    assert issues.include?(issue)
-    
-    Role.find(2).update_attribute :issues_visibility, 'own'
-    issues = Issue.visible(User.find(8)).all
-    assert issues.any?
-    assert issues.include?(issue)
-  end
-
-  def test_visible_scope_for_admin
-    user = User.find(1)
-    user.members.each(&:destroy)
-    assert user.projects.empty?
-    issues = Issue.visible(user).all
-    assert issues.any?
-    # Admin should see issues on private projects that he does not belong to
-    assert issues.detect {|issue| !issue.project.is_public?}
-    # Admin should see private issues of other users
-    assert issues.detect {|issue| issue.is_private? && issue.author != user}
-    assert_visibility_match user, issues
-  end
-
-  def test_visible_scope_with_project
-    project = Project.find(1)
-    issues = Issue.visible(User.find(2), :project => project).all
-    projects = issues.collect(&:project).uniq
-    assert_equal 1, projects.size
-    assert_equal project, projects.first
-  end
-
-  def test_visible_scope_with_project_and_subprojects
-    project = Project.find(1)
-    issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all
-    projects = issues.collect(&:project).uniq
-    assert projects.size > 1
-    assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)}
-  end
-
-  def test_visible_and_nested_set_scopes
-    assert_equal 0, Issue.find(1).descendants.visible.all.size
-  end
-
-  def test_errors_full_messages_should_include_custom_fields_errors
-    field = IssueCustomField.find_by_name('Database')
-
-    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
-                      :status_id => 1, :subject => 'test_create',
-                      :description => 'IssueTest#test_create_with_required_custom_field')
-    assert issue.available_custom_fields.include?(field)
-    # Invalid value
-    issue.custom_field_values = { field.id => 'SQLServer' }
-
-    assert !issue.valid?
-    assert_equal 1, issue.errors.full_messages.size
-    assert_equal "Database #{I18n.translate('activerecord.errors.messages.inclusion')}",
-                 issue.errors.full_messages.first
-  end
-
-  def test_update_issue_with_required_custom_field
-    field = IssueCustomField.find_by_name('Database')
-    field.update_attribute(:is_required, true)
-
-    issue = Issue.find(1)
-    assert_nil issue.custom_value_for(field)
-    assert issue.available_custom_fields.include?(field)
-    # No change to custom values, issue can be saved
-    assert issue.save
-    # Blank value
-    issue.custom_field_values = { field.id => '' }
-    assert !issue.save
-    # Valid value
-    issue.custom_field_values = { field.id => 'PostgreSQL' }
-    assert issue.save
-    issue.reload
-    assert_equal 'PostgreSQL', issue.custom_value_for(field).value
-  end
-
-  def test_should_not_update_attributes_if_custom_fields_validation_fails
-    issue = Issue.find(1)
-    field = IssueCustomField.find_by_name('Database')
-    assert issue.available_custom_fields.include?(field)
-
-    issue.custom_field_values = { field.id => 'Invalid' }
-    issue.subject = 'Should be not be saved'
-    assert !issue.save
-
-    issue.reload
-    assert_equal "Can't print recipes", issue.subject
-  end
-
-  def test_should_not_recreate_custom_values_objects_on_update
-    field = IssueCustomField.find_by_name('Database')
-
-    issue = Issue.find(1)
-    issue.custom_field_values = { field.id => 'PostgreSQL' }
-    assert issue.save
-    custom_value = issue.custom_value_for(field)
-    issue.reload
-    issue.custom_field_values = { field.id => 'MySQL' }
-    assert issue.save
-    issue.reload
-    assert_equal custom_value.id, issue.custom_value_for(field).id
-  end
-
-  def test_should_not_update_custom_fields_on_changing_tracker_with_different_custom_fields
-    issue = Issue.new(:project_id => 1)
-    issue.attributes = {:tracker_id => 1, :author_id => 1, :status_id => 1, :subject => 'Test', :custom_field_values => {'2' => 'Test'}}
-    issue.save!
-
-    assert !Tracker.find(2).custom_field_ids.include?(2)
-
-    issue = Issue.find(issue.id)
-    issue.attributes = {:tracker_id => 2, :custom_field_values => {'1' => ''}}
-
-    issue = Issue.find(issue.id)
-    custom_value = issue.custom_value_for(2)
-    assert_not_nil custom_value
-    assert_equal 'Test', custom_value.value
-  end
-
-  def test_assigning_tracker_id_should_reload_custom_fields_values
-    issue = Issue.new(:project => Project.find(1))
-    assert issue.custom_field_values.empty?
-    issue.tracker_id = 1
-    assert issue.custom_field_values.any?
-  end
-
-  def test_assigning_attributes_should_assign_tracker_id_first
-    attributes = ActiveSupport::OrderedHash.new
-    attributes['custom_field_values'] = { '1' => 'MySQL' }
-    attributes['tracker_id'] = '1'
-    issue = Issue.new(:project => Project.find(1))
-    issue.attributes = attributes
-    assert_not_nil issue.custom_value_for(1)
-    assert_equal 'MySQL', issue.custom_value_for(1).value
-  end
-
-  def test_should_update_issue_with_disabled_tracker
-    p = Project.find(1)
-    issue = Issue.find(1)
-
-    p.trackers.delete(issue.tracker)
-    assert !p.trackers.include?(issue.tracker)
-
-    issue.reload
-    issue.subject = 'New subject'
-    assert issue.save
-  end
-
-  def test_should_not_set_a_disabled_tracker
-    p = Project.find(1)
-    p.trackers.delete(Tracker.find(2))
-
-    issue = Issue.find(1)
-    issue.tracker_id = 2
-    issue.subject = 'New subject'
-    assert !issue.save
-    assert_not_nil issue.errors[:tracker_id]
-  end
-
-  def test_category_based_assignment
-    issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
-                         :status_id => 1, :priority => IssuePriority.all.first,
-                         :subject => 'Assignment test',
-                         :description => 'Assignment test', :category_id => 1)
-    assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
-  end
-
-  def test_new_statuses_allowed_to
-    Workflow.delete_all
-
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
-    status = IssueStatus.find(1)
-    role = Role.find(1)
-    tracker = Tracker.find(1)
-    user = User.find(2)
-
-    issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1)
-    assert_equal [1, 2], issue.new_statuses_allowed_to(user).map(&:id)
-
-    issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user)
-    assert_equal [1, 2, 3, 5], issue.new_statuses_allowed_to(user).map(&:id)
-
-    issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :assigned_to => user)
-    assert_equal [1, 2, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
-
-    issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user, :assigned_to => user)
-    assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
-  end
-
-  def test_copy
-    issue = Issue.new.copy_from(1)
-    assert issue.save
-    issue.reload
-    orig = Issue.find(1)
-    assert_equal orig.subject, issue.subject
-    assert_equal orig.tracker, issue.tracker
-    assert_equal "125", issue.custom_value_for(2).value
-  end
-
-  def test_copy_should_copy_status
-    orig = Issue.find(8)
-    assert orig.status != IssueStatus.default
-
-    issue = Issue.new.copy_from(orig)
-    assert issue.save
-    issue.reload
-    assert_equal orig.status, issue.status
-  end
-
-  def test_should_close_duplicates
-    # Create 3 issues
-    issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
-                       :status_id => 1, :priority => IssuePriority.all.first,
-                       :subject => 'Duplicates test', :description => 'Duplicates test')
-    assert issue1.save
-    issue2 = issue1.clone
-    assert issue2.save
-    issue3 = issue1.clone
-    assert issue3.save
-
-    # 2 is a dupe of 1
-    IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
-    # And 3 is a dupe of 2
-    IssueRelation.create(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
-    # And 3 is a dupe of 1 (circular duplicates)
-    IssueRelation.create(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
-
-    assert issue1.reload.duplicates.include?(issue2)
-
-    # Closing issue 1
-    issue1.init_journal(User.find(:first), "Closing issue1")
-    issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
-    assert issue1.save
-    # 2 and 3 should be also closed
-    assert issue2.reload.closed?
-    assert issue3.reload.closed?
-  end
-
-  def test_should_not_close_duplicated_issue
-    # Create 3 issues
-    issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
-                       :status_id => 1, :priority => IssuePriority.all.first,
-                       :subject => 'Duplicates test', :description => 'Duplicates test')
-    assert issue1.save
-    issue2 = issue1.clone
-    assert issue2.save
-
-    # 2 is a dupe of 1
-    IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
-    # 2 is a dup of 1 but 1 is not a duplicate of 2
-    assert !issue2.reload.duplicates.include?(issue1)
-
-    # Closing issue 2
-    issue2.init_journal(User.find(:first), "Closing issue2")
-    issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
-    assert issue2.save
-    # 1 should not be also closed
-    assert !issue1.reload.closed?
-  end
-
-  def test_assignable_versions
-    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
-    assert_equal ['open'], issue.assignable_versions.collect(&:status).uniq
-  end
-
-  def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
-    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
-    assert !issue.save
-    assert_not_nil issue.errors[:fixed_version_id]
-  end
-
-  def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
-    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 2, :subject => 'New issue')
-    assert !issue.save
-    assert_not_nil issue.errors[:fixed_version_id]
-  end
-
-  def test_should_be_able_to_assign_a_new_issue_to_an_open_version
-    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 3, :subject => 'New issue')
-    assert issue.save
-  end
-
-  def test_should_be_able_to_update_an_issue_assigned_to_a_closed_version
-    issue = Issue.find(11)
-    assert_equal 'closed', issue.fixed_version.status
-    issue.subject = 'Subject changed'
-    assert issue.save
-  end
-
-  def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
-    issue = Issue.find(11)
-    issue.status_id = 1
-    assert !issue.save
-    assert_not_nil issue.errors[:base]
-  end
-
-  def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
-    issue = Issue.find(11)
-    issue.status_id = 1
-    issue.fixed_version_id = 3
-    assert issue.save
-  end
-
-  def test_should_be_able_to_reopen_an_issue_assigned_to_a_locked_version
-    issue = Issue.find(12)
-    assert_equal 'locked', issue.fixed_version.status
-    issue.status_id = 1
-    assert issue.save
-  end
-
-  def test_move_to_another_project_with_same_category
-    issue = Issue.find(1)
-    assert issue.move_to_project(Project.find(2))
-    issue.reload
-    assert_equal 2, issue.project_id
-    # Category changes
-    assert_equal 4, issue.category_id
-    # Make sure time entries were move to the target project
-    assert_equal 2, issue.time_entries.first.project_id
-  end
-
-  def test_move_to_another_project_without_same_category
-    issue = Issue.find(2)
-    assert issue.move_to_project(Project.find(2))
-    issue.reload
-    assert_equal 2, issue.project_id
-    # Category cleared
-    assert_nil issue.category_id
-  end
-
-  def test_move_to_another_project_should_clear_fixed_version_when_not_shared
-    issue = Issue.find(1)
-    issue.update_attribute(:fixed_version_id, 1)
-    assert issue.move_to_project(Project.find(2))
-    issue.reload
-    assert_equal 2, issue.project_id
-    # Cleared fixed_version
-    assert_equal nil, issue.fixed_version
-  end
-
-  def test_move_to_another_project_should_keep_fixed_version_when_shared_with_the_target_project
-    issue = Issue.find(1)
-    issue.update_attribute(:fixed_version_id, 4)
-    assert issue.move_to_project(Project.find(5))
-    issue.reload
-    assert_equal 5, issue.project_id
-    # Keep fixed_version
-    assert_equal 4, issue.fixed_version_id
-  end
-
-  def test_move_to_another_project_should_clear_fixed_version_when_not_shared_with_the_target_project
-    issue = Issue.find(1)
-    issue.update_attribute(:fixed_version_id, 1)
-    assert issue.move_to_project(Project.find(5))
-    issue.reload
-    assert_equal 5, issue.project_id
-    # Cleared fixed_version
-    assert_equal nil, issue.fixed_version
-  end
-
-  def test_move_to_another_project_should_keep_fixed_version_when_shared_systemwide
-    issue = Issue.find(1)
-    issue.update_attribute(:fixed_version_id, 7)
-    assert issue.move_to_project(Project.find(2))
-    issue.reload
-    assert_equal 2, issue.project_id
-    # Keep fixed_version
-    assert_equal 7, issue.fixed_version_id
-  end
-
-  def test_move_to_another_project_with_disabled_tracker
-    issue = Issue.find(1)
-    target = Project.find(2)
-    target.tracker_ids = [3]
-    target.save
-    assert_equal false, issue.move_to_project(target)
-    issue.reload
-    assert_equal 1, issue.project_id
-  end
-
-  def test_copy_to_the_same_project
-    issue = Issue.find(1)
-    copy = nil
-    assert_difference 'Issue.count' do
-      copy = issue.move_to_project(issue.project, nil, :copy => true)
-    end
-    assert_kind_of Issue, copy
-    assert_equal issue.project, copy.project
-    assert_equal "125", copy.custom_value_for(2).value
-  end
-
-  def test_copy_to_another_project_and_tracker
-    issue = Issue.find(1)
-    copy = nil
-    assert_difference 'Issue.count' do
-      copy = issue.move_to_project(Project.find(3), Tracker.find(2), :copy => true)
-    end
-    copy.reload
-    assert_kind_of Issue, copy
-    assert_equal Project.find(3), copy.project
-    assert_equal Tracker.find(2), copy.tracker
-    # Custom field #2 is not associated with target tracker
-    assert_nil copy.custom_value_for(2)
-  end
-
-  context "#move_to_project" do
-    context "as a copy" do
-      setup do
-        @issue = Issue.find(1)
-        @copy = nil
-      end
-
-      should "not create a journal" do
-        @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:assigned_to_id => 3}})
-        assert_equal 0, @copy.reload.journals.size
-      end
-
-      should "allow assigned_to changes" do
-        @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:assigned_to_id => 3}})
-        assert_equal 3, @copy.assigned_to_id
-      end
-
-      should "allow status changes" do
-        @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:status_id => 2}})
-        assert_equal 2, @copy.status_id
-      end
-
-      should "allow start date changes" do
-        date = Date.today
-        @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:start_date => date}})
-        assert_equal date, @copy.start_date
-      end
-
-      should "allow due date changes" do
-        date = Date.today
-        @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:due_date => date}})
-
-        assert_equal date, @copy.due_date
-      end
-
-      should "set current user as author" do
-        User.current = User.find(9)
-        @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {}})
-
-        assert_equal User.current, @copy.author
-      end
-
-      should "keep journal notes" do
-        date = Date.today
-        notes = "Notes added when copying"
-        User.current = User.find(9)
-        @issue.init_journal(User.current, notes)
-        @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:start_date => date}})
-
-        assert_equal 1, @copy.journals.size
-        journal = @copy.journals.first
-        assert_equal 0, journal.details.size
-        assert_equal notes, journal.notes
-      end
-    end
-  end
-
-  def test_recipients_should_not_include_users_that_cannot_view_the_issue
-    issue = Issue.find(12)
-    assert issue.recipients.include?(issue.author.mail)
-    # move the issue to a private project
-    copy  = issue.move_to_project(Project.find(5), Tracker.find(2), :copy => true)
-    # author is not a member of project anymore
-    assert !copy.recipients.include?(copy.author.mail)
-  end
-
-  def test_recipients_should_include_the_assigned_group_members
-    group_member = User.generate_with_protected!
-    group = Group.generate!
-    group.users << group_member
-
-    issue = Issue.find(12)
-    issue.assigned_to = group
-    assert issue.recipients.include?(group_member.mail)
-  end
-
-  def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
-    user = User.find(3)
-    issue = Issue.find(9)
-    Watcher.create!(:user => user, :watchable => issue)
-    assert issue.watched_by?(user)
-    assert !issue.watcher_recipients.include?(user.mail)
-  end
-
-  def test_issue_destroy
-    Issue.find(1).destroy
-    assert_nil Issue.find_by_id(1)
-    assert_nil TimeEntry.find_by_issue_id(1)
-  end
-
-  def test_blocked
-    blocked_issue = Issue.find(9)
-    blocking_issue = Issue.find(10)
-
-    assert blocked_issue.blocked?
-    assert !blocking_issue.blocked?
-  end
-
-  def test_blocked_issues_dont_allow_closed_statuses
-    blocked_issue = Issue.find(9)
-
-    allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002))
-    assert !allowed_statuses.empty?
-    closed_statuses = allowed_statuses.select {|st| st.is_closed?}
-    assert closed_statuses.empty?
-  end
-
-  def test_unblocked_issues_allow_closed_statuses
-    blocking_issue = Issue.find(10)
-
-    allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002))
-    assert !allowed_statuses.empty?
-    closed_statuses = allowed_statuses.select {|st| st.is_closed?}
-    assert !closed_statuses.empty?
-  end
-
-  def test_rescheduling_an_issue_should_reschedule_following_issue
-    issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => '-', :start_date => Date.today, :due_date => Date.today + 2)
-    issue2 = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => '-', :start_date => Date.today, :due_date => Date.today + 2)
-    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
-    assert_equal issue1.due_date + 1, issue2.reload.start_date
-
-    issue1.due_date = Date.today + 5
-    issue1.save!
-    assert_equal issue1.due_date + 1, issue2.reload.start_date
-  end
-
-  def test_overdue
-    assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
-    assert !Issue.new(:due_date => Date.today).overdue?
-    assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
-    assert !Issue.new(:due_date => nil).overdue?
-    assert !Issue.new(:due_date => 1.day.ago.to_date, :status => IssueStatus.find(:first, :conditions => {:is_closed => true})).overdue?
-  end
-
-  context "#behind_schedule?" do
-    should "be false if the issue has no start_date" do
-      assert !Issue.new(:start_date => nil, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
-    end
-
-    should "be false if the issue has no end_date" do
-      assert !Issue.new(:start_date => 1.day.from_now.to_date, :due_date => nil, :done_ratio => 0).behind_schedule?
-    end
-
-    should "be false if the issue has more done than it's calendar time" do
-      assert !Issue.new(:start_date => 50.days.ago.to_date, :due_date => 50.days.from_now.to_date, :done_ratio => 90).behind_schedule?
-    end
-
-    should "be true if the issue hasn't been started at all" do
-      assert Issue.new(:start_date => 1.day.ago.to_date, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
-    end
-
-    should "be true if the issue has used more calendar time than it's done ratio" do
-      assert Issue.new(:start_date => 100.days.ago.to_date, :due_date => Date.today, :done_ratio => 90).behind_schedule?
-    end
-  end
-
-  context "#assignable_users" do
-    should "be Users" do
-      assert_kind_of User, Issue.find(1).assignable_users.first
-    end
-
-    should "include the issue author" do
-      project = Project.find(1)
-      non_project_member = User.generate!
-      issue = Issue.generate_for_project!(project, :author => non_project_member)
-
-      assert issue.assignable_users.include?(non_project_member)
-    end
-
-    should "include the current assignee" do
-      project = Project.find(1)
-      user = User.generate!
-      issue = Issue.generate_for_project!(project, :assigned_to => user)
-      user.lock!
-
-      assert Issue.find(issue.id).assignable_users.include?(user)
-    end
-
-    should "not show the issue author twice" do
-      assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
-      assert_equal 2, assignable_user_ids.length
-
-      assignable_user_ids.each do |user_id|
-        assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length, "User #{user_id} appears more or less than once"
-      end
-    end
-
-    context "with issue_group_assignment" do
-      should "include groups" do
-        issue = Issue.new(:project => Project.find(2))
-
-        with_settings :issue_group_assignment => '1' do
-          assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
-          assert issue.assignable_users.include?(Group.find(11))
-        end
-      end
-    end
-
-    context "without issue_group_assignment" do
-      should "not include groups" do
-        issue = Issue.new(:project => Project.find(2))
-
-        with_settings :issue_group_assignment => '0' do
-          assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
-          assert !issue.assignable_users.include?(Group.find(11))
-        end
-      end
-    end
-  end
-
-  def test_create_should_send_email_notification
-    ActionMailer::Base.deliveries.clear
-    issue = Issue.new(:project_id => 1, :tracker_id => 1,
-                      :author_id => 3, :status_id => 1,
-                      :priority => IssuePriority.all.first,
-                      :subject => 'test_create', :estimated_hours => '1:30')
-
-    assert issue.save
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_stale_issue_should_not_send_email_notification
-    ActionMailer::Base.deliveries.clear
-    issue = Issue.find(1)
-    stale = Issue.find(1)
-
-    issue.init_journal(User.find(1))
-    issue.subject = 'Subjet update'
-    assert issue.save
-    assert_equal 1, ActionMailer::Base.deliveries.size
-    ActionMailer::Base.deliveries.clear
-
-    stale.init_journal(User.find(1))
-    stale.subject = 'Another subjet update'
-    assert_raise ActiveRecord::StaleObjectError do
-      stale.save
-    end
-    assert ActionMailer::Base.deliveries.empty?
-  end
-
-  def test_journalized_description
-    IssueCustomField.delete_all
-
-    i = Issue.first
-    old_description = i.description
-    new_description = "This is the new description"
-
-    i.init_journal(User.find(2))
-    i.description = new_description
-    assert_difference 'Journal.count', 1 do
-      assert_difference 'JournalDetail.count', 1 do
-        i.save!
-      end
-    end
-
-    detail = JournalDetail.first(:order => 'id DESC')
-    assert_equal i, detail.journal.journalized
-    assert_equal 'attr', detail.property
-    assert_equal 'description', detail.prop_key
-    assert_equal old_description, detail.old_value
-    assert_equal new_description, detail.value
-  end
-
-  def test_blank_descriptions_should_not_be_journalized
-    IssueCustomField.delete_all
-    Issue.update_all("description = NULL", "id=1")
-
-    i = Issue.find(1)
-    i.init_journal(User.find(2))
-    i.subject = "blank description"
-    i.description = "\r\n"
-
-    assert_difference 'Journal.count', 1 do
-      assert_difference 'JournalDetail.count', 1 do
-        i.save!
-      end
-    end
-  end
-
-  def test_description_eol_should_be_normalized
-    i = Issue.new(:description => "CR \r LF \n CRLF \r\n")
-    assert_equal "CR \r\n LF \r\n CRLF \r\n", i.description
-  end
-
-  def test_saving_twice_should_not_duplicate_journal_details
-    i = Issue.find(:first)
-    i.init_journal(User.find(2), 'Some notes')
-    # initial changes
-    i.subject = 'New subject'
-    i.done_ratio = i.done_ratio + 10
-    assert_difference 'Journal.count' do
-      assert i.save
-    end
-    # 1 more change
-    i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id])
-    assert_no_difference 'Journal.count' do
-      assert_difference 'JournalDetail.count', 1 do
-        i.save
-      end
-    end
-    # no more change
-    assert_no_difference 'Journal.count' do
-      assert_no_difference 'JournalDetail.count' do
-        i.save
-      end
-    end
-  end
-
-  def test_all_dependent_issues
-    IssueRelation.delete_all
-    assert IssueRelation.create!(:issue_from => Issue.find(1),
-                                 :issue_to   => Issue.find(2),
-                                 :relation_type => IssueRelation::TYPE_PRECEDES)
-    assert IssueRelation.create!(:issue_from => Issue.find(2),
-                                 :issue_to   => Issue.find(3),
-                                 :relation_type => IssueRelation::TYPE_PRECEDES)
-    assert IssueRelation.create!(:issue_from => Issue.find(3),
-                                 :issue_to   => Issue.find(8),
-                                 :relation_type => IssueRelation::TYPE_PRECEDES)
-
-    assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
-  end
-
-  def test_all_dependent_issues_with_persistent_circular_dependency
-    IssueRelation.delete_all
-    assert IssueRelation.create!(:issue_from => Issue.find(1),
-                                 :issue_to   => Issue.find(2),
-                                 :relation_type => IssueRelation::TYPE_PRECEDES)
-    assert IssueRelation.create!(:issue_from => Issue.find(2),
-                                 :issue_to   => Issue.find(3),
-                                 :relation_type => IssueRelation::TYPE_PRECEDES)
-    # Validation skipping
-    assert IssueRelation.new(:issue_from => Issue.find(3),
-                             :issue_to   => Issue.find(1),
-                             :relation_type => IssueRelation::TYPE_PRECEDES).save(false)
-
-    assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort
-  end
-
-  def test_all_dependent_issues_with_persistent_multiple_circular_dependencies
-    IssueRelation.delete_all
-    assert IssueRelation.create!(:issue_from => Issue.find(1),
-                                 :issue_to   => Issue.find(2),
-                                 :relation_type => IssueRelation::TYPE_RELATES)
-    assert IssueRelation.create!(:issue_from => Issue.find(2),
-                                 :issue_to   => Issue.find(3),
-                                 :relation_type => IssueRelation::TYPE_RELATES)
-    assert IssueRelation.create!(:issue_from => Issue.find(3),
-                                 :issue_to   => Issue.find(8),
-                                 :relation_type => IssueRelation::TYPE_RELATES)
-    # Validation skipping
-    assert IssueRelation.new(:issue_from => Issue.find(8),
-                             :issue_to   => Issue.find(2),
-                             :relation_type => IssueRelation::TYPE_RELATES).save(false)
-    assert IssueRelation.new(:issue_from => Issue.find(3),
-                             :issue_to   => Issue.find(1),
-                             :relation_type => IssueRelation::TYPE_RELATES).save(false)
-
-    assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
-  end
-
-  context "#done_ratio" do
-    setup do
-      @issue = Issue.find(1)
-      @issue_status = IssueStatus.find(1)
-      @issue_status.update_attribute(:default_done_ratio, 50)
-      @issue2 = Issue.find(2)
-      @issue_status2 = IssueStatus.find(2)
-      @issue_status2.update_attribute(:default_done_ratio, 0)
-    end
-
-    context "with Setting.issue_done_ratio using the issue_field" do
-      setup do
-        Setting.issue_done_ratio = 'issue_field'
-      end
-
-      should "read the issue's field" do
-        assert_equal 0, @issue.done_ratio
-        assert_equal 30, @issue2.done_ratio
-      end
-    end
-
-    context "with Setting.issue_done_ratio using the issue_status" do
-      setup do
-        Setting.issue_done_ratio = 'issue_status'
-      end
-
-      should "read the Issue Status's default done ratio" do
-        assert_equal 50, @issue.done_ratio
-        assert_equal 0, @issue2.done_ratio
-      end
-    end
-  end
-
-  context "#update_done_ratio_from_issue_status" do
-    setup do
-      @issue = Issue.find(1)
-      @issue_status = IssueStatus.find(1)
-      @issue_status.update_attribute(:default_done_ratio, 50)
-      @issue2 = Issue.find(2)
-      @issue_status2 = IssueStatus.find(2)
-      @issue_status2.update_attribute(:default_done_ratio, 0)
-    end
-
-    context "with Setting.issue_done_ratio using the issue_field" do
-      setup do
-        Setting.issue_done_ratio = 'issue_field'
-      end
-
-      should "not change the issue" do
-        @issue.update_done_ratio_from_issue_status
-        @issue2.update_done_ratio_from_issue_status
-
-        assert_equal 0, @issue.read_attribute(:done_ratio)
-        assert_equal 30, @issue2.read_attribute(:done_ratio)
-      end
-    end
-
-    context "with Setting.issue_done_ratio using the issue_status" do
-      setup do
-        Setting.issue_done_ratio = 'issue_status'
-      end
-
-      should "change the issue's done ratio" do
-        @issue.update_done_ratio_from_issue_status
-        @issue2.update_done_ratio_from_issue_status
-
-        assert_equal 50, @issue.read_attribute(:done_ratio)
-        assert_equal 0, @issue2.read_attribute(:done_ratio)
-      end
-    end
-  end
-
-  test "#by_tracker" do
-    User.current = User.anonymous
-    groups = Issue.by_tracker(Project.find(1))
-    assert_equal 3, groups.size
-    assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
-  end
-
-  test "#by_version" do
-    User.current = User.anonymous
-    groups = Issue.by_version(Project.find(1))
-    assert_equal 3, groups.size
-    assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
-  end
-
-  test "#by_priority" do
-    User.current = User.anonymous
-    groups = Issue.by_priority(Project.find(1))
-    assert_equal 4, groups.size
-    assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
-  end
-
-  test "#by_category" do
-    User.current = User.anonymous
-    groups = Issue.by_category(Project.find(1))
-    assert_equal 2, groups.size
-    assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
-  end
-
-  test "#by_assigned_to" do
-    User.current = User.anonymous
-    groups = Issue.by_assigned_to(Project.find(1))
-    assert_equal 2, groups.size
-    assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
-  end
-
-  test "#by_author" do
-    User.current = User.anonymous
-    groups = Issue.by_author(Project.find(1))
-    assert_equal 4, groups.size
-    assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
-  end
-
-  test "#by_subproject" do
-    User.current = User.anonymous
-    groups = Issue.by_subproject(Project.find(1))
-    # Private descendant not visible
-    assert_equal 1, groups.size
-    assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
-  end
-
-  context ".allowed_target_projects_on_move" do
-    should "return all active projects for admin users" do
-      User.current = User.find(1)
-      assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
-    end
-
-    should "return allowed projects for non admin users" do
-      User.current = User.find(2)
-      Role.non_member.remove_permission! :move_issues
-      assert_equal 3, Issue.allowed_target_projects_on_move.size
-
-      Role.non_member.add_permission! :move_issues
-      assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
-    end
-  end
-
-  def test_recently_updated_with_limit_scopes
-    #should return the last updated issue
-    assert_equal 1, Issue.recently_updated.with_limit(1).length
-    assert_equal Issue.find(:first, :order => "updated_on DESC"), Issue.recently_updated.with_limit(1).first
-  end
-
-  def test_on_active_projects_scope
-    assert Project.find(2).archive
-
-    before = Issue.on_active_project.length
-    # test inclusion to results
-    issue = Issue.generate_for_project!(Project.find(1), :tracker => Project.find(2).trackers.first)
-    assert_equal before + 1, Issue.on_active_project.length
-
-    # Move to an archived project
-    issue.project = Project.find(2)
-    assert issue.save
-    assert_equal before, Issue.on_active_project.length
-  end
-
-  context "Issue#recipients" do
-    setup do
-      @project = Project.find(1)
-      @author = User.generate_with_protected!
-      @assignee = User.generate_with_protected!
-      @issue = Issue.generate_for_project!(@project, :assigned_to => @assignee, :author => @author)
-    end
-
-    should "include project recipients" do
-      assert @project.recipients.present?
-      @project.recipients.each do |project_recipient|
-        assert @issue.recipients.include?(project_recipient)
-      end
-    end
-
-    should "include the author if the author is active" do
-      assert @issue.author, "No author set for Issue"
-      assert @issue.recipients.include?(@issue.author.mail)
-    end
-
-    should "include the assigned to user if the assigned to user is active" do
-      assert @issue.assigned_to, "No assigned_to set for Issue"
-      assert @issue.recipients.include?(@issue.assigned_to.mail)
-    end
-
-    should "not include users who opt out of all email" do
-      @author.update_attribute(:mail_notification, :none)
-
-      assert !@issue.recipients.include?(@issue.author.mail)
-    end
-
-    should "not include the issue author if they are only notified of assigned issues" do
-      @author.update_attribute(:mail_notification, :only_assigned)
-
-      assert !@issue.recipients.include?(@issue.author.mail)
-    end
-
-    should "not include the assigned user if they are only notified of owned issues" do
-      @assignee.update_attribute(:mail_notification, :only_owner)
-
-      assert !@issue.recipients.include?(@issue.assigned_to.mail)
-    end
-
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/72/72b134a74f37265288938527276f0807a1362abf.svn-base
--- a/.svn/pristine/72/72b134a74f37265288938527276f0807a1362abf.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= link_to l(:label_issue_status_plural), issue_statuses_path %> &#187; <%=l(:label_issue_status_new)%></h2>
-
-<% form_for @issue_status, :builder => TabularFormBuilder do |f| %>
-  <%= render :partial => 'form', :locals => {:f => f} %>
-  <%= submit_tag l(:button_create) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/72/72f0350ace5f91c2452fe68fefaac12651ddb55a.svn-base
--- a/.svn/pristine/72/72f0350ace5f91c2452fe68fefaac12651ddb55a.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= l(:label_query) %></h2>
-
-<% form_tag(query_path(@query), :onsubmit => 'selectAllOptions("selected_columns");', :method => :put) do %>
-  <%= render :partial => 'form', :locals => {:query => @query} %>
-  <%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/72/72fa979a7098a778692a53bd6065af66a4a95005.svn-base
--- /dev/null
+++ b/.svn/pristine/72/72fa979a7098a778692a53bd6065af66a4a95005.svn-base
@@ -0,0 +1,1089 @@
+mk:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d/%m/%Y"
+      short: "%d %b"
+      long: "%d %B, %Y"
+
+    day_names: [Ð½ÐµÐ´ÐµÐ»Ð°, Ð¿Ð¾Ð½ÐµÐ´ÐµÐ»Ð½Ð¸Ðº, Ð²Ñ‚Ð¾Ñ€Ð½Ð¸Ðº, ÑÑ€ÐµÐ´Ð°, Ñ‡ÐµÑ‚Ð²Ñ€Ñ‚Ð¾Ðº, Ð¿ÐµÑ‚Ð¾Ðº, ÑÐ°Ð±Ð¾Ñ‚Ð°]
+    abbr_day_names: [Ð½ÐµÐ´, Ð¿Ð¾Ð½, Ð²Ñ‚Ð¾, ÑÑ€Ðµ, Ñ‡ÐµÑ‚, Ð¿ÐµÑ‚, ÑÐ°Ð±]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Ñ˜Ð°Ð½ÑƒÐ°Ñ€Ð¸, Ñ„ÐµÐ²Ñ€ÑƒÐ°Ñ€Ð¸, Ð¼Ð°Ñ€Ñ‚, Ð°Ð¿Ñ€Ð¸Ð», Ð¼Ð°Ñ˜, Ñ˜ÑƒÐ½Ð¸, Ñ˜ÑƒÐ»Ð¸, Ð°Ð²Ð³ÑƒÑÑ‚, ÑÐµÐ¿Ñ‚ÐµÐ¼Ð²Ñ€Ð¸, Ð¾ÐºÑ‚Ð¾Ð¼Ð²Ñ€Ð¸, Ð½Ð¾ÐµÐ¼Ð²Ñ€Ð¸, Ð´ÐµÐºÐµÐ¼Ð²Ñ€Ð¸]
+    abbr_month_names: [~, Ñ˜Ð°Ð½, Ñ„ÐµÐ², Ð¼Ð°Ñ€, Ð°Ð¿Ñ€, Ð¼Ð°Ñ˜, Ñ˜ÑƒÐ½, Ñ˜ÑƒÐ», Ð°Ð²Ð³, ÑÐµÐ¿, Ð¾ÐºÑ‚, Ð½Ð¾Ðµ, Ð´ÐµÐº]
+    # Used in date_select and datime_select.
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%d/%m/%Y %H:%M"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%d %B, %Y %H:%M"
+    am: "Ð¿Ñ€ÐµÐ´Ð¿Ð»Ð°Ð´Ð½Ðµ"
+    pm: "Ð¿Ð¾Ð¿Ð»Ð°Ð´Ð½Ðµ"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "Ð¿Ð¾Ð»Ð° Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
+      less_than_x_seconds:
+        one:   "Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ 1 ÑÐµÐºÑƒÐ½Ð´Ð°"
+        other: "Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ %{count} ÑÐµÐºÑƒÐ½Ð´Ð¸"
+      x_seconds:
+        one:   "1 ÑÐµÐºÑƒÐ½Ð´Ð°"
+        other: "%{count} ÑÐµÐºÑƒÐ½Ð´Ð¸"
+      less_than_x_minutes:
+        one:   "Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ 1 Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
+        other: "Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ %{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð¸"
+      x_minutes:
+        one:   "1 Ð¼Ð¸Ð½ÑƒÑ‚Ð°"
+        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð¸"
+      about_x_hours:
+        one:   "Ð¾ÐºÐ¾Ð»Ñƒ 1 Ñ‡Ð°Ñ"
+        other: "Ð¾ÐºÐ¾Ð»Ñƒ %{count} Ñ‡Ð°ÑÐ°"
+      x_hours:
+        one:   "1 Ñ‡Ð°Ñ"
+        other: "%{count} Ñ‡Ð°ÑÐ°"
+      x_days:
+        one:   "1 Ð´ÐµÐ½"
+        other: "%{count} Ð´ÐµÐ½Ð°"
+      about_x_months:
+        one:   "Ð¾ÐºÐ¾Ð»Ñƒ 1 Ð¼ÐµÑÐµÑ†"
+        other: "Ð¾ÐºÐ¾Ð»Ñƒ %{count} Ð¼ÐµÑÐµÑ†Ð¸"
+      x_months:
+        one:   "1 Ð¼ÐµÑÐµÑ†"
+        other: "%{count} Ð¼ÐµÑÐµÑ†Ð¸"
+      about_x_years:
+        one:   "Ð¾ÐºÐ¾Ð»Ñƒ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
+        other: "Ð¾ÐºÐ¾Ð»Ñƒ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
+      over_x_years:
+        one:   "Ð¿Ñ€ÐµÐºÑƒ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
+        other: "Ð¿Ñ€ÐµÐºÑƒ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
+      almost_x_years:
+        one:   "ÑÐºÐ¾Ñ€Ð¾ 1 Ð³Ð¾Ð´Ð¸Ð½Ð°"
+        other: "ÑÐºÐ¾Ñ€Ð¾ %{count} Ð³Ð¾Ð´Ð¸Ð½Ð¸"
+
+  number:
+    # Default format for numbers
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "Ð¸"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "Ð½Ðµ Ðµ Ð²ÐºÐ»ÑƒÑ‡ÐµÐ½Ð¾ Ð²Ð¾ Ð»Ð¸ÑÑ‚Ð°Ñ‚Ð°"
+        exclusion: "Ðµ Ñ€ÐµÐ·ÐµÑ€Ð²Ð¸Ñ€Ð°Ð½Ð¾"
+        invalid: "Ðµ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð¾"
+        confirmation: "Ð½Ðµ ÑÐµ ÑÐ¾Ð²Ð¿Ð°Ñ“Ð° ÑÐ¾ Ð¿Ð¾Ñ‚Ð²Ñ€Ð´Ð°Ñ‚Ð°"
+        accepted: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ñ€Ð¸Ñ„Ð°Ñ‚ÐµÐ½Ð¾"
+        empty: "Ð½ÐµÐ¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
+        blank: "Ð½ÐµÐ¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð¿Ñ€Ð°Ð·Ð½Ð¾"
+        too_long: "Ðµ Ð¿Ñ€ÐµÐ´Ð¾Ð»Ð³Ð¾ (Ð¼Ð°ÐºÑ. %{count} Ð·Ð½Ð°Ñ†Ð¸)"
+        too_short: "Ðµ Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‚ÐºÐ¾ (Ð¼Ð¸Ð½. %{count} Ð·Ð½Ð°Ñ†Ð¸)"
+        wrong_length: "Ðµ Ð¿Ð¾Ð³Ñ€ÐµÑˆÐ½Ð° Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð° (Ñ‚Ñ€ÐµÐ±Ð° Ð´Ð° Ðµ  %{count} Ð·Ð½Ð°Ñ†Ð¸)"
+        taken: "Ðµ Ð²ÐµÑœÐµ Ð·Ð°Ñ„Ð°Ñ‚ÐµÐ½Ð¾"
+        not_a_number: "Ð½Ðµ Ðµ Ð±Ñ€Ð¾Ñ˜"
+        not_a_date: "Ð½Ðµ Ðµ Ð²Ð°Ð»Ð¸Ð´Ð½Ð° Ð´Ð°Ñ‚Ð°"
+        greater_than: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð³Ð¾Ð»ÐµÐ¼Ð¾ Ð¾Ð´ %{count}"
+        greater_than_or_equal_to: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð³Ð¾Ð»ÐµÐ¼Ð¾ Ð¸Ð»Ð¸ ÐµÐ´Ð½Ð°ÐºÐ²Ð¾ Ð½Ð° %{count}"
+        equal_to: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ ÐµÐ´Ð½Ð°ÐºÐ²Ð¾ Ð½Ð° %{count}"
+        less_than: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð¼Ð°Ð»Ð¾ Ð¾Ð´ %{count}"
+        less_than_or_equal_to: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð¼Ð°Ð»Ð¾ Ð¸Ð»Ð¸ ÐµÐ´Ð½Ð°ÐºÐ²Ð¾ Ð½Ð° %{count}"
+        odd: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð½ÐµÐ¿Ð°Ñ€Ð½Ð¾"
+        even: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð°Ñ€Ð½Ð¾"
+        greater_than_start_date: "Ð¼Ð¾Ñ€Ð° Ð´Ð° Ðµ Ð¿Ð¾Ð³Ð¾Ð»ÐµÐ¼Ð° Ð¾Ð´ Ð¿Ð¾Ñ‡ÐµÑ‚Ð½Ð°Ñ‚Ð° Ð´Ð°Ñ‚Ð°"
+        not_same_project: "Ð½Ðµ Ð¿Ñ€Ð¸Ð¿Ð°Ñ“Ð° Ð½Ð° Ð¸ÑÑ‚Ð¸Ð¾Ñ‚ Ð¿Ñ€Ð¾ÐµÐºÑ‚"
+        circular_dependency: "ÐžÐ²Ð°Ð° Ð²Ñ€ÑÐºÐ° ÑœÐµ ÐºÑ€ÐµÐ¸Ñ€Ð° ÐºÑ€ÑƒÐ¶Ð½Ð° Ð·Ð°Ð²Ð¸ÑÐ½Ð¾ÑÑ‚"
+        cant_link_an_issue_with_a_descendant: "Ð—Ð°Ð´Ð°Ñ‡Ð° Ð½ÐµÐ¼Ð¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð¿Ð¾Ð²Ñ€Ð·Ðµ ÑÐ¾ ÐµÐ´Ð½Ð° Ð¾Ð´ Ð½ÐµÑ˜Ð·Ð¸Ð½Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸"
+
+  actionview_instancetag_blank_option: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ
+
+  general_text_No: 'ÐÐµ'
+  general_text_Yes: 'Ð”Ð°'
+  general_text_no: 'Ð½Ðµ'
+  general_text_yes: 'Ð´Ð°'
+  general_lang_name: 'Macedonian (ÐœÐ°ÐºÐµÐ´Ð¾Ð½ÑÐºÐ¸)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: ÐŸÑ€Ð¾Ñ„Ð¸Ð»Ð¾Ñ‚ Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½.
+  notice_account_invalid_creditentials: ÐÐµÑ‚Ð¾Ñ‡ÐµÐ½ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº Ð¸Ð»Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
+  notice_account_password_updated: Ð›Ð¾Ð·Ð¸Ð½ÐºÐ°Ñ‚Ð° Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°.
+  notice_account_wrong_password: ÐŸÐ¾Ð³Ñ€ÐµÑˆÐ½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
+  notice_account_register_done: ÐŸÑ€Ð¾Ñ„Ð¸Ð»Ð¾Ñ‚ Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½. Ð—Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð°, ÐºÐ»ÐºÐ½ÐµÑ‚Ðµ Ð½Ð° Ð²Ñ€ÑÐºÐ°Ñ‚Ð° ÑˆÑ‚Ð¾ Ð²Ð¸ Ðµ Ð¿Ñ€Ð°Ñ‚ÐµÐ½Ð° Ð¿Ð¾ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð°.
+  notice_account_unknown_email: ÐÐµÐ¿Ð¾Ð·Ð½Ð°Ñ‚ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº.
+  notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
+  notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
+  notice_account_activated: Your account has been activated. You can now log in.
+  notice_successful_create: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ ÐºÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ.
+  notice_successful_update: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°ÑšÐµ.
+  notice_successful_delete: Ð£ÑÐ¿ÐµÑˆÐ½Ð¾ Ð±Ñ€Ð¸ÑˆÐµÑšÐµ.
+  notice_successful_connection: Ð£ÑÐ¿ÐµÑˆÐ½Ð° ÐºÐ¾Ð½ÐµÐºÑ†Ð¸Ñ˜Ð°.
+  notice_file_not_found: The page you were trying to access doesn't exist or has been removed.
+  notice_locking_conflict: Data has been updated by another user.
+  notice_not_authorized: You are not authorized to access this page.
+  notice_email_sent: "Ð•-Ð¿Ð¾Ñ€Ð°ÐºÐ° Ðµ Ð¿Ñ€Ð°Ñ‚ÐµÐ½Ð° Ð½Ð° %{value}"
+  notice_email_error: "Ð¡Ðµ ÑÐ»ÑƒÑ‡Ð¸ Ð³Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð¿Ñ€Ð°ÑœÐ°ÑšÐµ Ð½Ð° Ðµ-Ð¿Ð¾Ñ€Ð°ÐºÐ°Ñ‚Ð° (%{value})"
+  notice_feeds_access_key_reseted: Ð’Ð°ÑˆÐ¸Ð¾Ñ‚ RSS ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿ Ðµ reset.
+  notice_api_access_key_reseted: Ð’Ð°ÑˆÐ¸Ð¾Ñ‚ API ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿ Ðµ reset.
+  notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+  notice_account_pending: "Your account was created and is now pending administrator approval."
+  notice_default_data_loaded: Default configuration successfully loaded.
+  notice_unable_delete_version: Unable to delete version.
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+
+  error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
+  error_scm_not_found: "The entry or revision was not found in the repository."
+  error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
+  error_scm_annotate: "The entry does not exist or can not be annotated."
+  error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
+  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
+  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_can_not_delete_tracker: "This tracker contains issues and can't be deleted."
+  error_can_not_remove_role: "This role is in use and can not be deleted."
+  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version can not be reopened'
+  error_can_not_archive_project: This project can not be archived
+  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
+  error_workflow_copy_source: 'Please select a source tracker or role'
+  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
+  error_unable_delete_issue_status: 'Unable to delete issue status'
+  error_unable_to_connect: "Unable to connect (%{value})"
+  warning_attachments_not_saved: "%{count} file(s) could not be saved."
+
+  mail_subject_lost_password: "Ð’Ð°ÑˆÐ°Ñ‚Ð° %{value} Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°"
+  mail_body_lost_password: 'To change your password, click on the following link:'
+  mail_subject_register: "Your %{value} account activation"
+  mail_body_register: 'To activate your account, click on the following link:'
+  mail_body_account_information_external: "You can use your %{value} account to log in."
+  mail_body_account_information: Your account information
+  mail_subject_account_activation_request: "%{value} account activation request"
+  mail_body_account_activation_request: "ÐÐ¾Ð² ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº (%{value}) Ðµ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½. The account is pending your approval:"
+  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
+  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
+
+
+  field_name: Ð˜Ð¼Ðµ
+  field_description: ÐžÐ¿Ð¸Ñ
+  field_summary: ÐšÑ€Ð°Ñ‚Ð¾Ðº Ð¾Ð¿Ð¸Ñ
+  field_is_required: Ð—Ð°Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾
+  field_firstname: Ð˜Ð¼Ðµ
+  field_lastname: ÐŸÑ€ÐµÐ·Ð¸Ð¼Ðµ
+  field_mail: Ð•-Ð¿Ð¾ÑˆÑ‚Ð°
+  field_filename: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  field_filesize: Ð“Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð°
+  field_downloads: ÐŸÑ€ÐµÐ²Ð·ÐµÐ¼Ð°ÑšÐ°
+  field_author: ÐÐ²Ñ‚Ð¾Ñ€
+  field_created_on: ÐšÑ€ÐµÐ¸Ñ€Ð°Ð½
+  field_updated_on: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾
+  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
+  field_is_for_all: Ð—Ð° ÑÐ¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  field_possible_values: ÐœÐ¾Ð¶Ð½Ð¸ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸
+  field_regexp: Regular expression
+  field_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»Ð½Ð° Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð°
+  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»Ð½Ð° Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð°
+  field_value: Ð’Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
+  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
+  field_title: ÐÐ°ÑÐ»Ð¾Ð²
+  field_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
+  field_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
+  field_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ
+  field_notes: Ð‘ÐµÐ»ÐµÑˆÐºÐ¸
+  field_is_closed: Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ðµ Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+  field_is_default: Default value
+  field_tracker: Tracker
+  field_subject: ÐÐ°ÑÐ»Ð¾Ð²
+  field_due_date: ÐšÑ€Ð°ÐµÐ½ Ñ€Ð¾Ðº
+  field_assigned_to: Ð”Ð¾Ð´ÐµÐ»ÐµÐ½Ð° Ð½Ð°
+  field_priority: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
+  field_fixed_version: Target version
+  field_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
+  field_principal: Principal
+  field_role: Ð£Ð»Ð¾Ð³Ð°
+  field_homepage: Ð’ÐµÐ± ÑÑ‚Ñ€Ð°Ð½Ð°
+  field_is_public: ÐˆÐ°Ð²ÐµÐ½
+  field_parent: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð½Ð°
+  field_is_in_roadmap: Issues displayed in roadmap
+  field_login: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
+  field_mail_notification: Ð˜Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°ÑšÐ° Ð¿Ð¾ e-Ð¿Ð¾ÑˆÑ‚Ð°
+  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
+  field_last_login_on: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ð½Ð°Ñ˜Ð°Ð²Ð°
+  field_language: ÐˆÐ°Ð·Ð¸Ðº
+  field_effective_date: Ð”Ð°Ñ‚Ð°
+  field_password: Ð›Ð¾Ð·Ð¸Ð½ÐºÐ°
+  field_new_password: ÐÐ¾Ð²Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
+  field_password_confirmation: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð°
+  field_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ð°
+  field_type: Ð¢Ð¸Ð¿
+  field_host: Ð¥Ð¾ÑÑ‚
+  field_port: ÐŸÐ¾Ñ€Ñ‚
+  field_account: Account
+  field_base_dn: Base DN
+  field_attr_login: Login attribute
+  field_attr_firstname: Firstname attribute
+  field_attr_lastname: Lastname attribute
+  field_attr_mail: Email attribute
+  field_onthefly: ÐœÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ð»Ð½Ð¾ (On-the-fly) ÐºÑ€ÐµÐ¸Ñ€Ð°ÑšÐµ Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸
+  field_start_date: ÐŸÐ¾Ñ‡ÐµÑ‚Ð¾Ðº
+  field_done_ratio: "% Ð—Ð°Ð²Ñ€ÑˆÐµÐ½Ð¾"
+  field_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
+  field_hide_mail: ÐšÑ€Ð¸Ñ˜ Ñ˜Ð° Ð¼Ð¾Ñ˜Ð°Ñ‚Ð° Ð°Ð´Ñ€ÐµÑÐ° Ð½Ð° Ðµ-Ð¿Ð¾ÑˆÑ‚Ð°
+  field_comments: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  field_url: URL
+  field_start_page: ÐŸÐ¾Ñ‡ÐµÑ‚Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð°
+  field_subproject: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  field_hours: Ð§Ð°ÑÐ¾Ð²Ð¸
+  field_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
+  field_spent_on: Ð”Ð°Ñ‚Ð°
+  field_identifier: Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€
+  field_is_filter: ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸ ÐºÐ°ÐºÐ¾ Ñ„Ð¸Ð»Ñ‚ÐµÑ€
+  field_issue_to: ÐŸÐ¾Ð²Ñ€Ð·Ð°Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  field_delay: Ð”Ð¾Ñ†Ð½ÐµÑšÐµ
+  field_assignable: ÐÐ° Ð¾Ð²Ð°Ð° ÑƒÐ»Ð¾Ð³Ð° Ð¼Ð¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð´Ð¾Ð´ÐµÐ»ÑƒÐ²Ð°Ð°Ñ‚ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  field_redirect_existing_links: ÐŸÑ€ÐµÐ½Ð°ÑÐ¾Ñ‡Ð¸ Ð³Ð¸ Ð¿Ð¾ÑÑ‚Ð¾ÐµÑ‡ÐºÐ¸Ñ‚Ðµ Ð²Ñ€ÑÐºÐ¸
+  field_estimated_hours: ÐŸÑ€Ð¾Ñ†ÐµÐ½ÐµÑ‚Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  field_column_names: ÐšÐ¾Ð»Ð¾Ð½Ð¸
+  field_time_entries: Ð‘ÐµÐ»ÐµÐ¶Ð¸ Ð²Ñ€ÐµÐ¼Ðµ
+  field_time_zone: Ð’Ñ€ÐµÐ¼ÐµÐ½ÑÐºÐ° Ð·Ð¾Ð½Ð°
+  field_searchable: ÐœÐ¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð¿Ñ€ÐµÐ±Ð°Ñ€ÑƒÐ²Ð°
+  field_default_value: Default value
+  field_comments_sorting: ÐŸÑ€Ð¸ÐºÐ°Ð¶ÑƒÐ²Ð°Ñ˜ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
+  field_parent_title: Parent page
+  field_editable: ÐœÐ¾Ð¶Ðµ Ð´Ð° ÑÐµ ÑƒÑ€ÐµÐ´ÑƒÐ²Ð°
+  field_watcher: Watcher
+  field_identity_url: OpenID URL
+  field_content: Ð¡Ð¾Ð´Ñ€Ð¶Ð¸Ð½Ð°
+  field_group_by: Ð“Ñ€ÑƒÐ¿Ð¸Ñ€Ð°Ñ˜ Ð³Ð¸ Ñ€ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸Ñ‚Ðµ ÑÐ¿Ð¾Ñ€ÐµÐ´
+  field_sharing: Ð¡Ð¿Ð¾Ð´ÐµÐ»ÑƒÐ²Ð°ÑšÐµ
+  field_parent_issue: Parent task
+
+  setting_app_title: ÐÐ°ÑÐ»Ð¾Ð² Ð½Ð° Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°Ñ‚Ð°
+  setting_app_subtitle: ÐŸÐ¾Ð´Ð½Ð°ÑÐ»Ð¾Ð² Ð½Ð° Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°Ñ‚Ð°
+  setting_welcome_text: Ð¢ÐµÐºÑÑ‚ Ð·Ð° Ð´Ð¾Ð±Ñ€ÐµÐ´Ð¾Ñ˜Ð´Ðµ
+  setting_default_language: Default Ñ˜Ð°Ð·Ð¸Ðº
+  setting_login_required: Ð—Ð°Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
+  setting_self_registration: Ð¡Ð°Ð¼Ð¾-Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
+  setting_attachment_max_size: ÐœÐ°ÐºÑ. Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð° Ð½Ð° Ð¿Ñ€Ð¸Ð»Ð¾Ð³
+  setting_issues_export_limit: Issues export limit
+  setting_mail_from: Emission email address
+  setting_bcc_recipients: Blind carbon copy recipients (bcc)
+  setting_plain_text_mail: Ð¢ÐµÐºÑÑ‚ÑƒÐ°Ð»Ð½Ð¸ Ðµ-Ð¿Ð¾Ñ€Ð°ÐºÐ¸ (Ð±ÐµÐ· HTML)
+  setting_host_name: Ð˜Ð¼Ðµ Ð½Ð° Ñ…Ð¾ÑÑ‚ Ð¸ Ð¿Ð°Ñ‚ÐµÐºÐ°
+  setting_text_formatting: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð°ÑšÐµ Ð½Ð° Ñ‚ÐµÐºÑÑ‚
+  setting_wiki_compression: ÐšÐ¾Ð¼Ð¿Ñ€ÐµÑÐ¸Ñ˜Ð° Ð½Ð° Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°Ñ‚Ð° Ð½Ð° Ð²Ð¸ÐºÐ¸
+  setting_feeds_limit: Feed content limit
+  setting_default_projects_public: ÐÐ¾Ð²Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸ ÑÐµ Ð¸Ð½Ð¸Ñ†Ð¸Ñ˜Ð°Ð»Ð½Ð¾ Ñ˜Ð°Ð²Ð½Ð¸
+  setting_autofetch_changesets: Autofetch commits
+  setting_sys_api_enabled: Enable WS for repository management
+  setting_commit_ref_keywords: Referencing keywords
+  setting_commit_fix_keywords: Fixing keywords
+  setting_autologin: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ° Ð½Ð°Ñ˜Ð°Ð²Ð°
+  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð½Ð° Ð´Ð°Ñ‚Ð°
+  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
+  setting_cross_project_issue_relations: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸ Ñ€ÐµÐ»Ð°Ñ†Ð¸Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¼ÐµÑ“Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  setting_issue_list_default_columns: Default columns displayed on the issue list
+  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
+  setting_per_page_options: Objects per page options
+  setting_user_format: ÐŸÑ€Ð¸ÐºÐ°Ð· Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸Ñ‚Ðµ
+  setting_activity_days_default: Ð”ÐµÐ½Ð¾Ð²Ð¸ Ð¿Ñ€Ð¸ÐºÐ°Ð¶Ð°Ð½Ð° Ð²Ð¾ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð° Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
+  setting_display_subprojects_issues: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸ Ð³Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ Ð²Ð¾ Ð³Ð»Ð°Ð²Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  setting_enabled_scm: ÐžÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð¸ SCM
+  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
+  setting_mail_handler_api_enabled: Enable WS for incoming emails
+  setting_mail_handler_api_key: API ÐºÐ»ÑƒÑ‡
+  setting_sequential_project_identifiers: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ñ˜ Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»Ð½Ð¸ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¸ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  setting_gravatar_enabled: ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸ Gravatar ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ¸ Ð¸ÐºÐ¾Ð½Ð¸
+  setting_gravatar_default: Default Gravatar image
+  setting_diff_max_lines_displayed: Max number of diff lines displayed
+  setting_file_max_size_displayed: Max size of text files displayed inline
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_openid: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸ OpenID Ð½Ð°Ñ˜Ð°Ð²Ð° Ð¸ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
+  setting_password_min_length: ÐœÐ¸Ð½. Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð° Ð½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
+  setting_new_project_user_role_id: Ð£Ð»Ð¾Ð³Ð° Ð´Ð¾Ð´ÐµÐ»ÐµÐ½Ð° Ð½Ð° Ð½ÐµÐ°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€ÑÐºÐ¸ ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº ÐºÐ¾Ñ˜ ÐºÑ€ÐµÐ¸Ñ€Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_field: Use the issue field
+  setting_issue_done_ratio_issue_status: Use the issue status
+  setting_start_of_week: Start calendars on
+  setting_rest_api_enabled: Enable REST web service
+  setting_cache_formatted_text: Cache formatted text
+
+  permission_add_project: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  permission_add_subprojects: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  permission_edit_project: Ð£Ñ€ÐµÐ´Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  permission_select_project_modules: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð·Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  permission_manage_members: Manage members
+  permission_manage_project_activities: Manage project activities
+  permission_manage_versions: Manage versions
+  permission_manage_categories: Manage issue categories
+  permission_view_issues: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_add_issues: Ð”Ð¾Ð´Ð°Ð²Ð°Ñ˜ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_edit_issues: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_manage_issue_relations: Manage issue relations
+  permission_add_issue_notes: Ð”Ð¾Ð´Ð°Ð²Ð°Ñ˜ Ð±ÐµÐ»ÐµÑˆÐºÐ¸
+  permission_edit_issue_notes: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð±ÐµÐ»ÐµÑˆÐºÐ¸
+  permission_edit_own_issue_notes: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸ Ð±ÐµÐ»ÐµÑˆÐºÐ¸
+  permission_move_issues: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚ÑƒÐ²Ð°Ñ˜ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_delete_issues: Ð‘Ñ€Ð¸ÑˆÐ¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_manage_public_queries: Manage public queries
+  permission_save_queries: Save queries
+  permission_view_gantt: View gantt chart
+  permission_view_calendar: View calendar
+  permission_view_issue_watchers: View watchers list
+  permission_add_issue_watchers: Add watchers
+  permission_delete_issue_watchers: Delete watchers
+  permission_log_time: Ð‘ÐµÐ»ÐµÐ¶Ð¸ Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  permission_view_time_entries: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  permission_edit_time_entries: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð±ÐµÐ»ÐµÑˆÐºÐ¸ Ð·Ð° Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  permission_edit_own_time_entries: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸ Ð±ÐµÐ»ÐµÑˆÐºÐ¸ Ð·Ð° Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  permission_manage_news: Manage news
+  permission_comment_news: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð°Ñ˜ Ð½Ð° Ð²ÐµÑÑ‚Ð¸
+  permission_view_documents: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  permission_manage_files: Manage files
+  permission_view_files: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ¸
+  permission_manage_wiki: Manage wiki
+  permission_rename_wiki_pages: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_delete_wiki_pages: Ð‘Ñ€Ð¸ÑˆÐ¸ Ð²Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_view_wiki_pages: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸
+  permission_view_wiki_edits: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸ Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°
+  permission_edit_wiki_pages: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_delete_wiki_pages_attachments: Ð‘Ñ€Ð¸ÑˆÐ¸ Ð¿Ñ€Ð¸Ð»Ð¾Ð·Ð¸
+  permission_protect_wiki_pages: Ð—Ð°ÑˆÑ‚Ð¸Ñ‚ÑƒÐ²Ð°Ñ˜ Ð²Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  permission_manage_repository: Manage repository
+  permission_browse_repository: Browse repository
+  permission_view_changesets: View changesets
+  permission_commit_access: Commit access
+  permission_manage_boards: Manage boards
+  permission_view_messages: View messages
+  permission_add_messages: Post messages
+  permission_edit_messages: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð¿Ð¾Ñ€Ð°ÐºÐ¸
+  permission_edit_own_messages: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸ Ð¿Ð¾Ñ€Ð°ÐºÐ¸
+  permission_delete_messages: Ð‘Ñ€Ð¸ÑˆÐ¸ Ð¿Ð¾Ñ€Ð°ÐºÐ¸
+  permission_delete_own_messages: Ð‘Ñ€Ð¸ÑˆÐ¸ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸ Ð¿Ð¾Ñ€Ð°ÐºÐ¸
+  permission_export_wiki_pages: Export wiki pages
+  permission_manage_subtasks: Manage subtasks
+
+  project_module_issue_tracking: Ð¡Ð»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  project_module_time_tracking: Ð¡Ð»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
+  project_module_news: Ð’ÐµÑÑ‚Ð¸
+  project_module_documents: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  project_module_files: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ¸
+  project_module_wiki: Ð’Ð¸ÐºÐ¸
+  project_module_repository: Repository
+  project_module_boards: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
+  project_module_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
+  project_module_gantt: Gantt
+
+  label_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
+  label_user_plural: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸
+  label_user_new: ÐÐ¾Ð² ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº
+  label_user_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼ÐµÐ½
+  label_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
+  label_project_new: ÐÐ¾Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_project_plural: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸
+  label_x_projects:
+    zero:  Ð½ÐµÐ¼Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+    one:   1 Ð¿Ñ€Ð¾ÐµÐºÑ‚
+    other: "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
+  label_project_all: Ð¡Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_project_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_new: ÐÐ¾Ð²Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_plural: Ð—Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_view_all: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issues_by: "Ð—Ð°Ð´Ð°Ñ‡Ð¸ Ð¿Ð¾ %{value}"
+  label_issue_added: Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
+  label_issue_updated: Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°
+  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_new: ÐÐ¾Ð² Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  label_document_added: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ñ‚ Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½
+  label_role: Ð£Ð»Ð¾Ð³Ð°
+  label_role_plural: Ð£Ð»Ð¾Ð³Ð¸
+  label_role_new: ÐÐ¾Ð²Ð° ÑƒÐ»Ð¾Ð³Ð°
+  label_role_and_permissions: Ð£Ð»Ð¾Ð³Ð¸ Ð¸ Ð¾Ð²Ð»Ð°ÑÑ‚ÑƒÐ²Ð°ÑšÐ°
+  label_member: Ð§Ð»ÐµÐ½
+  label_member_new: ÐÐ¾Ð² Ñ‡Ð»ÐµÐ½
+  label_member_plural: Ð§Ð»ÐµÐ½Ð¾Ð²Ð¸
+  label_tracker: Tracker
+  label_tracker_plural: Trackers
+  label_tracker_new: New tracker
+  label_workflow: Workflow
+  label_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_status_plural: Ð¡Ñ‚Ð°Ñ‚ÑƒÑÐ¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_status_new: ÐÐ¾Ð² ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð° Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_category_new: ÐÐ¾Ð²Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
+  label_custom_field: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ð´ÐµÐ½Ð¾ Ð¿Ð¾Ð»Ðµ
+  label_custom_field_plural: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ð´ÐµÐ½Ð¸ Ð¿Ð¾Ð»Ð¸ÑšÐ°
+  label_custom_field_new: ÐÐ¾Ð²Ð¾ Ð¿Ñ€Ð¸Ð»Ð°Ð³Ð¾Ð´ÐµÐ½Ð¾ Ð¿Ð¾Ð»Ðµ
+  label_enumerations: Enumerations
+  label_enumeration_new: ÐÐ¾Ð²Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚
+  label_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ˜Ð°
+  label_information_plural: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸
+  label_please_login: ÐÐ°Ñ˜Ð°Ð²Ð¸ ÑÐµ
+  label_register: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ñ˜ ÑÐµ
+  label_login_with_open_id_option: Ð¸Ð»Ð¸ Ð½Ð°Ñ˜Ð°Ð²Ð¸ ÑÐµ ÑÐ¾ OpenID
+  label_password_lost: Ð˜Ð·Ð³ÑƒÐ±ÐµÐ½Ð° Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
+  label_home: ÐŸÐ¾Ñ‡ÐµÑ‚Ð½Ð°
+  label_my_page: ÐœÐ¾Ñ˜Ð°Ñ‚Ð° ÑÑ‚Ñ€Ð°Ð½Ð°
+  label_my_account: ÐœÐ¾Ñ˜Ð¾Ñ‚ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»
+  label_my_projects: ÐœÐ¾Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_my_page_block: Ð‘Ð»Ð¾Ðº ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚
+  label_administration: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ˜Ð°
+  label_login: ÐÐ°Ñ˜Ð°Ð²Ð¸ ÑÐµ
+  label_logout: ÐžÐ´Ñ˜Ð°Ð²Ð¸ ÑÐµ
+  label_help: ÐŸÐ¾Ð¼Ð¾Ñˆ
+  label_reported_issues: ÐŸÑ€Ð¸Ñ˜Ð°Ð²ÐµÐ½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_assigned_to_me_issues: Ð—Ð°Ð´Ð°Ñ‡Ð¸ Ð´Ð¾Ð´ÐµÐ»ÐµÐ½Ð¸ Ð½Ð° Ð¼ÐµÐ½Ðµ
+  label_last_login: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ð½Ð°Ñ˜Ð°Ð²Ð°
+  label_registered_on: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½ Ð½Ð°
+  label_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
+  label_overall_activity: Ð¡ÐµÐ²ÐºÑƒÐ¿Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
+  label_user_activity: "ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚ Ð½Ð° %{value}"
+  label_new: ÐÐ¾Ð²Ð°
+  label_logged_as: ÐÐ°Ñ˜Ð°Ð²ÐµÐ½Ð¸ ÑÑ‚Ðµ ÐºÐ°ÐºÐ¾
+  label_environment: ÐžÐ¿ÐºÑ€ÑƒÐ¶ÑƒÐ²Ð°ÑšÐµ
+  label_authentication: ÐÐ²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
+  label_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
+  label_auth_source_new: ÐÐ¾Ð² Ñ€ÐµÐ¶Ð¸Ð¼ Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
+  label_auth_source_plural: Ð ÐµÐ¶Ð¸Ð¼Ð¸ Ð½Ð° Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
+  label_subproject_plural: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_subproject_new: ÐÐ¾Ð² Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_and_its_subprojects: "%{value} Ð¸ Ð½ÐµÐ³Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
+  label_min_max_length: ÐœÐ¸Ð½. - ÐœÐ°ÐºÑ. Ð´Ð¾Ð»Ð¶Ð¸Ð½Ð°
+  label_list: Ð›Ð¸ÑÑ‚Ð°
+  label_date: Ð”Ð°Ñ‚Ð°
+  label_integer: Integer
+  label_float: Float
+  label_boolean: Boolean
+  label_string: Ð¢ÐµÐºÑÑ‚
+  label_text: Ð”Ð¾Ð»Ð³ Ñ‚ÐµÐºÑÑ‚
+  label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
+  label_attribute_plural: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸
+  label_no_data: ÐÐµÐ¼Ð° Ð¿Ð¾Ð´Ð°Ñ‚Ð¾Ñ†Ð¸ Ð·Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð¶ÑƒÐ²Ð°ÑšÐµ
+  label_change_status: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°
+  label_attachment: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  label_attachment_new: ÐÐ¾Ð²Ð° Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  label_attachment_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  label_attachment_plural: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ¸
+  label_file_added: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°Ñ‚Ð° Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
+  label_report: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ñ˜
+  label_report_plural: Ð˜Ð·Ð²ÐµÑˆÑ‚Ð°Ð¸
+  label_news: ÐÐ¾Ð²Ð¾ÑÑ‚
+  label_news_new: Ð”Ð¾Ð´Ð°Ð´Ð¸ Ð½Ð¾Ð²Ð¾ÑÑ‚
+  label_news_plural: ÐÐ¾Ð²Ð¾ÑÑ‚Ð¸
+  label_news_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
+  label_news_view_all: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
+  label_news_added: ÐÐ¾Ð²Ð¾ÑÑ‚Ñ‚Ð° Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
+  label_settings: Settings
+  label_overview: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´
+  label_version: Ð’ÐµÑ€Ð·Ð¸Ñ˜Ð°
+  label_version_new: ÐÐ¾Ð²Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
+  label_version_plural: Ð’ÐµÑ€Ð·Ð¸Ð¸
+  label_close_versions: Ð—Ð°Ñ‚Ð²Ð¾Ñ€Ð¸ Ð³Ð¸ Ð·Ð°Ð²Ñ€ÑˆÐµÐ½Ð¸Ñ‚Ðµ Ð²Ñ€Ð·Ð¸Ð¸
+  label_confirmation: ÐŸÐ¾Ñ‚Ð²Ñ€Ð´Ð°
+  label_export_to: 'Ð”Ð¾ÑÑ‚Ð°Ð¿Ð½Ð¾ Ð¸ Ð²Ð¾:'
+  label_read: ÐŸÑ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ˜...
+  label_public_projects: ÐˆÐ°Ð²Ð½Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_open_issues: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+  label_open_issues_plural: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+  label_closed_issues: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+  label_closed_issues_plural: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+  label_x_open_issues_abbr_on_total:
+    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸ / %{total}
+    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° / %{total}
+    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸ / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+    one:   1 Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+    other: "%{count} Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸"
+  label_x_closed_issues_abbr:
+    zero:  0 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+    one:   1 Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+    other: "%{count} Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸"
+  label_total: Ð’ÐºÑƒÐ¿Ð½Ð¾
+  label_permissions: ÐžÐ²Ð»Ð°ÑÑ‚ÑƒÐ²Ð°ÑšÐ°
+  label_current_status: ÐœÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ð»ÐµÐ½ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_new_statuses_allowed: Ð”Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ Ð½Ð¾Ð²Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸
+  label_all: ÑÐ¸Ñ‚Ðµ
+  label_none: Ð½Ð¸ÐµÐ´ÐµÐ½
+  label_nobody: Ð½Ð¸ÐºÐ¾Ñ˜
+  label_next: Ð¡Ð»ÐµÐ´Ð½Ð¾
+  label_previous: ÐŸÑ€ÐµÑ‚Ñ…Ð¾Ð´Ð½Ð¾
+  label_used_by: ÐšÐ¾Ñ€Ð¸ÑÑ‚ÐµÐ½Ð¾ Ð¾Ð´
+  label_details: Ð”ÐµÑ‚Ð°Ð»Ð¸
+  label_add_note: Ð”Ð¾Ð´Ð°Ð´Ð¸ Ð±ÐµÐ»ÐµÑˆÐºÐ°
+  label_per_page: ÐŸÐ¾ ÑÑ‚Ñ€Ð°Ð½Ð°
+  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
+  label_months_from: Ð¼ÐµÑÐµÑ†Ð¸ Ð¾Ð´
+  label_gantt: Gantt
+  label_internal: Internal
+  label_last_changes: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸ %{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
+  label_change_view_all: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸
+  label_personalize_page: ÐŸÑ€Ð¸Ð»Ð°Ð³Ð¾Ð´Ð¸ Ñ˜Ð° ÑÑ‚Ñ€Ð°Ð½Ð°Ð²Ð°
+  label_comment: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  label_comment_plural: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
+  label_x_comments:
+    zero: Ð½ÐµÐ¼Ð° ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
+    one: 1 ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+    other: "%{count} ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸"
+  label_comment_add: Ð”Ð¾Ð´Ð°Ð´Ð¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  label_comment_added: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¾Ñ‚ Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½
+  label_comment_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸
+  label_query: Custom query
+  label_query_plural: Custom queries
+  label_query_new: New query
+  label_filter_add: Ð”Ð¾Ð´Ð°Ð´Ð¸ Ñ„Ð¸Ð»Ñ‚ÐµÑ€
+  label_filter_plural: Ð¤Ð¸Ð»Ñ‚Ñ€Ð¸
+  label_equals: Ðµ
+  label_not_equals: Ð½Ðµ Ðµ
+  label_in_less_than: Ð·Ð° Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´
+  label_in_more_than: Ð·Ð° Ð¿Ð¾Ð²ÐµÑœÐµ Ð¾Ð´
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: Ð²Ð¾
+  label_today: Ð´ÐµÐ½ÐµÑ
+  label_all_time: Ñ†ÐµÐ»Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_yesterday: Ð²Ñ‡ÐµÑ€Ð°
+  label_this_week: Ð¾Ð²Ð°Ð° Ð½ÐµÐ´ÐµÐ»Ð°
+  label_last_week: Ð¼Ð¸Ð½Ð°Ñ‚Ð°Ñ‚Ð° Ð½ÐµÐ´ÐµÐ»Ð°
+  label_last_n_days: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ‚Ðµ %{count} Ð´ÐµÐ½Ð°"
+  label_this_month: Ð¾Ð²Ð¾Ñ˜ Ð¼ÐµÑÐµÑ†
+  label_last_month: Ð¼Ð¸Ð½Ð°Ñ‚Ð¸Ð¾Ñ‚ Ð¼ÐµÑÐµÑ†
+  label_this_year: Ð¾Ð²Ð°Ð° Ð³Ð¾Ð´Ð¸Ð½Ð°
+  label_date_range: Date range
+  label_less_than_ago: Ð¿Ñ€ÐµÐ´ Ð¿Ð¾Ð¼Ð°Ð»ÐºÑƒ Ð¾Ð´ Ð´ÐµÐ½Ð¾Ð²Ð¸
+  label_more_than_ago: Ð¿Ñ€ÐµÐ´ Ð¿Ð¾Ð²ÐµÑœÐµ Ð¾Ð´ Ð´ÐµÐ½Ð¾Ð²Ð¸
+  label_ago: Ð¿Ñ€ÐµÐ´ Ð´ÐµÐ½Ð¾Ð²Ð¸
+  label_contains: ÑÐ¾Ð´Ñ€Ð¶Ð¸
+  label_not_contains: Ð½Ðµ ÑÐ¾Ð´Ñ€Ð¶Ð¸
+  label_day_plural: Ð´ÐµÐ½Ð¾Ð²Ð¸
+  label_repository: Ð¡ÐºÐ»Ð°Ð´Ð¸ÑˆÑ‚Ðµ
+  label_repository_plural: Ð¡ÐºÐ»Ð°Ð´Ð¸ÑˆÑ‚Ð°
+  label_browse: ÐŸÑ€ÐµÐ»Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ˜
+  label_branch: Ð“Ñ€Ð°Ð½ÐºÐ°
+  label_tag: Tag
+  label_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
+  label_revision_plural: Ð ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  label_revision_id: "Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð° %{value}"
+  label_associated_revisions: Associated revisions
+  label_added: added
+  label_modified: modified
+  label_copied: copied
+  label_renamed: renamed
+  label_deleted: deleted
+  label_latest_revision: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ñ€ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
+  label_latest_revision_plural: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  label_view_revisions: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸Ñ‚Ðµ
+  label_view_all_revisions: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  label_max_size: ÐœÐ°ÐºÑ. Ð³Ð¾Ð»ÐµÐ¼Ð¸Ð½Ð°
+  label_sort_highest: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ñ˜Ð³Ð¾Ñ€Ðµ
+  label_sort_higher: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ð³Ð¾Ñ€Ðµ
+  label_sort_lower: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ð´Ð¾Ð»Ðµ
+  label_sort_lowest: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð½Ð°Ñ˜Ð´Ð¾Ð»Ðµ
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "Due in %{value}"
+  label_roadmap_overdue: "ÐšÐ°ÑÐ½Ð¸ %{value}"
+  label_roadmap_no_issues: ÐÐµÐ¼Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð·Ð° Ð¾Ð²Ð°Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð°
+  label_search: Ð‘Ð°Ñ€Ð°Ñ˜
+  label_result_plural: Ð ÐµÐ·ÑƒÐ»Ñ‚Ð°Ñ‚Ð¸
+  label_all_words: Ð¡Ð¸Ñ‚Ðµ Ð·Ð±Ð¾Ñ€Ð¾Ð²Ð¸
+  label_wiki: Ð’Ð¸ÐºÐ¸
+  label_wiki_edit: Ð’Ð¸ÐºÐ¸ ÑƒÑ€ÐµÐ´ÑƒÐ²Ð°ÑšÐµ
+  label_wiki_edit_plural: Ð’Ð¸ÐºÐ¸ ÑƒÑ€ÐµÐ´ÑƒÐ²Ð°ÑšÐ°
+  label_wiki_page: Ð’Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  label_wiki_page_plural: Ð’Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸
+  label_index_by_title: Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Ð½Ð°ÑÐ»Ð¾Ð²
+  label_index_by_date: Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Ð´Ð°Ñ‚Ð°
+  label_current_version: Current version
+  label_preview: Preview
+  label_feed_plural: Feeds
+  label_changes_details: Ð”ÐµÑ‚Ð°Ð»Ð¸ Ð·Ð° ÑÐ¸Ñ‚Ðµ Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸
+  label_issue_tracking: Ð¡Ð»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_spent_time: ÐŸÐ¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_overall_spent_time: Ð’ÐºÑƒÐ¿Ð½Ð¾ Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_f_hour: "%{value} Ñ‡Ð°Ñ"
+  label_f_hour_plural: "%{value} Ñ‡Ð°ÑÐ°"
+  label_time_tracking: Ð¡Ð»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
+  label_change_plural: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸
+  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ¸
+  label_commits_per_month: Commits per month
+  label_commits_per_author: Commits per author
+  label_view_diff: View differences
+  label_diff_inline: inline
+  label_diff_side_by_side: side by side
+  label_options: ÐžÐ¿Ñ†Ð¸Ð¸
+  label_copy_workflow_from: Copy workflow from
+  label_permissions_report: Permissions report
+  label_watched_issues: Watched issues
+  label_related_issues: ÐŸÐ¾Ð²Ñ€Ð·Ð°Ð½Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_applied_status: Applied status
+  label_loading: Loading...
+  label_relation_new: ÐÐ¾Ð²Ð° Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ˜Ð°
+  label_relation_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸ Ñ€ÐµÐ»Ð°Ñ†Ð¸Ñ˜Ð°
+  label_relates_to: related to
+  label_duplicates: Ð´ÑƒÐ¿Ð»Ð¸ÐºÐ°Ñ‚Ð¸
+  label_duplicated_by: duplicated by
+  label_blocks: blocks
+  label_blocked_by: Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð°Ð½Ð¾ Ð¾Ð´
+  label_precedes: Ð¿Ñ€ÐµÑ‚Ñ…Ð¾Ð´Ð¸
+  label_follows: ÑÐ»ÐµÐ´Ð¸
+  label_end_to_start: ÐºÑ€Ð°Ñ˜ Ð´Ð¾ Ð¿Ð¾Ñ‡ÐµÑ‚Ð¾Ðº
+  label_end_to_end: ÐºÑ€Ð°Ñ˜ Ð´Ð¾ ÐºÑ€Ð°Ñ˜
+  label_start_to_start: Ð¿Ð¾Ñ‡ÐµÑ‚Ð¾Ðº Ð´Ð¾ Ð¿Ð¾Ñ‡ÐµÑ‚Ð¾Ðº
+  label_start_to_end: Ð¿Ð¾Ñ‡ÐµÑ‚Ð¾Ðº Ð´Ð¾ ÐºÑ€Ð°Ñ˜
+  label_stay_logged_in: ÐžÑÑ‚Ð°Ð½ÐµÑ‚Ðµ Ð½Ð°Ñ˜Ð°Ð²ÐµÐ½Ð¸
+  label_disabled: disabled
+  label_show_completed_versions: Show completed versions
+  label_me: Ñ˜Ð°Ñ
+  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
+  label_board_new: ÐÐ¾Ð² Ñ„Ð¾Ñ€ÑƒÐ¼
+  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
+  label_board_locked: Ð—Ð°ÐºÐ»ÑƒÑ‡ÐµÐ½
+  label_board_sticky: Sticky
+  label_topic_plural: Ð¢ÐµÐ¼Ð¸
+  label_message_plural: ÐŸÐ¾Ñ€Ð°ÐºÐ¸
+  label_message_last: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð° Ð¿Ð¾Ñ€Ð°ÐºÐ°
+  label_message_new: ÐÐ¾Ð²Ð° Ð¿Ð¾Ñ€Ð°ÐºÐ°
+  label_message_posted: ÐŸÐ¾Ñ€Ð°ÐºÐ°Ñ‚Ðµ Ðµ Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
+  label_reply_plural: ÐžÐ´Ð³Ð¾Ð²Ð¾Ñ€Ð¸
+  label_send_information: Ð˜ÑÐ¿Ñ€Ð°Ñ‚Ð¸ Ð³Ð¸ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸Ñ‚Ðµ Ð·Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ð¾Ñ‚ Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ¾Ñ‚
+  label_year: Ð“Ð¾Ð´Ð¸Ð½Ð°
+  label_month: ÐœÐµÑÐµÑ†
+  label_week: ÐÐµÐ´ÐµÐ»Ð°
+  label_date_from: ÐžÐ´
+  label_date_to: Ð”Ð¾
+  label_language_based: Ð¡Ð¿Ð¾Ñ€ÐµÐ´ Ñ˜Ð°Ð·Ð¸ÐºÐ¾Ñ‚ Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ¾Ñ‚
+  label_sort_by: "ÐŸÐ¾Ð´Ñ€ÐµÐ´Ð¸ ÑÐ¿Ð¾Ñ€ÐµÐ´ %{value}"
+  label_send_test_email: Ð˜ÑÐ¿Ñ€Ð°Ñ‚Ð¸ Ñ‚ÐµÑÑ‚ Ðµ-Ð¿Ð¾Ñ€Ð°ÐºÐ°
+  label_feeds_access_key: RSS ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿
+  label_missing_feeds_access_key: ÐÐµÐ´Ð¾ÑÑ‚Ð¸ÐºÐ° RSS ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿
+  label_feeds_access_key_created_on: "RSS ÐºÐ»ÑƒÑ‡Ð¾Ñ‚ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½ Ð¿Ñ€ÐµÐ´ %{value}"
+  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ð¸
+  label_added_time_by: "Ð”Ð¾Ð´Ð°Ð´ÐµÐ½Ð¾ Ð¾Ð´ %{author} Ð¿Ñ€ÐµÐ´ %{age}"
+  label_updated_time_by: "ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾ Ð¾Ð´ %{author} Ð¿Ñ€ÐµÐ´ %{age}"
+  label_updated_time: "ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð¾ Ð¿Ñ€ÐµÐ´ %{value}"
+  label_jump_to_a_project: ÐŸÑ€ÐµÑ„Ñ€Ð»Ð¸ ÑÐµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚...
+  label_file_plural: Ð”Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ¸
+  label_changeset_plural: Changesets
+  label_default_columns: ÐžÑÐ½Ð¾Ð²Ð½Ð¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸
+  label_no_change_option: (Ð‘ÐµÐ· Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°)
+  label_bulk_edit_selected_issues: Ð“Ñ€ÑƒÐ¿Ð½Ð¾ ÑƒÑ€ÐµÐ´ÑƒÐ²Ð°ÑšÐµ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_theme: Ð¢ÐµÐ¼Ð°
+  label_default: Default
+  label_search_titles_only: ÐŸÑ€ÐµÐ±Ð°Ñ€ÑƒÐ²Ð°Ñ˜ ÑÐ°Ð¼Ð¾ Ð½Ð°ÑÐ»Ð¾Ð²Ð¸
+  label_user_mail_option_all: "Ð—Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ˜ Ð½Ð°ÑÑ‚Ð°Ð½ Ð²Ð¾ ÑÐ¸Ñ‚Ðµ Ð¼Ð¾Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸"
+  label_user_mail_option_selected: "Ð—Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ˜ Ð½Ð°ÑÑ‚Ð°Ð½ ÑÐ°Ð¼Ð¾ Ð²Ð¾ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸..."
+  label_user_mail_no_self_notified: "ÐÐµ Ð¼Ðµ Ð¸Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°Ñ˜ Ð·Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸Ñ‚Ðµ ÑˆÑ‚Ð¾ Ñ˜Ð°Ñ Ð³Ð¸ Ð¿Ñ€Ð°Ð²Ð°Ð¼"
+  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ð¿Ñ€ÐµÐºÑƒ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð°
+  label_registration_manual_activation: Ð¼Ð°Ð½ÑƒÐµÐ»Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»
+  label_registration_automatic_activation: Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚ÑÐºÐ° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ˜Ð° Ð½Ð° Ð¿Ñ€Ð¾Ñ„Ð¸Ð»
+  label_display_per_page: "ÐŸÐ¾ ÑÑ‚Ñ€Ð°Ð½Ð°: %{value}"
+  label_age: Age
+  label_change_properties: Change properties
+  label_general: ÐžÐ¿ÑˆÑ‚Ð¾
+  label_more: ÐŸÐ¾Ð²ÐµÑœÐµ
+  label_scm: SCM
+  label_plugins: Ð”Ð¾Ð´Ð°Ñ‚Ð¾Ñ†Ð¸
+  label_ldap_authentication: LDAP Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°
+  label_downloads_abbr: ÐŸÑ€ÐµÐ²Ð·ÐµÐ¼Ð°ÑšÐ°
+  label_optional_description: ÐžÐ¿Ð¸Ñ (Ð½ÐµÐ·Ð°Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾)
+  label_add_another_file: Ð”Ð¾Ð´Ð°Ð´Ð¸ ÑƒÑˆÑ‚Ðµ ÐµÐ´Ð½Ð° Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
+  label_preferences: Preferences
+  label_chronological_order: Ð’Ð¾ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾ÑˆÐºÐ¸ Ñ€ÐµÐ´
+  label_reverse_chronological_order: In reverse chronological order
+  label_planning: ÐŸÐ»Ð°Ð½Ð¸Ñ€Ð°ÑšÐµ
+  label_incoming_emails: Ð”Ð¾Ñ˜Ð´Ð¾Ð²Ð½Ð¸ Ðµ-Ð¿Ð¾Ñ€Ð°ÐºÐ¸
+  label_generate_key: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð°Ñ˜ ÐºÐ»ÑƒÑ‡
+  label_issue_watchers: Watchers
+  label_example: ÐŸÑ€Ð¸Ð¼ÐµÑ€
+  label_display: ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸
+  label_sort: ÐŸÐ¾Ð´Ñ€ÐµÐ´Ð¸
+  label_ascending: Ð Ð°ÑÑ‚ÐµÑ‡ÐºÐ¸
+  label_descending: ÐžÐ¿Ð°Ñ“Ð°Ñ‡ÐºÐ¸
+  label_date_from_to: ÐžÐ´ %{start} Ð´Ð¾ %{end}
+  label_wiki_content_added: Ð’Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð´Ð¾Ð´Ð°Ð´ÐµÐ½Ð°
+  label_wiki_content_updated: Ð’Ð¸ÐºÐ¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°
+  label_group: Ð“Ñ€ÑƒÐ¿Ð°
+  label_group_plural: Ð“Ñ€ÑƒÐ¿Ð¸
+  label_group_new: ÐÐ¾Ð²Ð° Ð³Ñ€ÑƒÐ¿Ð°
+  label_time_entry_plural: ÐŸÐ¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
+  label_version_sharing_none: ÐÐµ ÑÐ¿Ð¾Ð´ÐµÐ»ÐµÐ½Ð¾
+  label_version_sharing_descendants: Ð¡Ð¾ ÑÐ¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_version_sharing_hierarchy: Ð¡Ð¾ Ñ…Ð¸ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ˜Ð°Ñ‚Ð° Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
+  label_version_sharing_tree: Ð¡Ð¾ Ð´Ñ€Ð²Ð¾Ñ‚Ð¾ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
+  label_version_sharing_system: Ð¡Ð¾ ÑÐ¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_update_issue_done_ratios: Update issue done ratios
+  label_copy_source: Ð˜Ð·Ð²Ð¾Ñ€
+  label_copy_target: Ð”ÐµÑÑ‚Ð¸Ð½Ð°Ñ†Ð¸Ñ˜Ð°
+  label_copy_same_as_target: Ð˜ÑÑ‚Ð¾ ÐºÐ°ÐºÐ¾ Ð´ÐµÑÑ‚Ð¸Ð½Ð°Ñ†Ð¸Ñ˜Ð°Ñ‚Ð°
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_api_access_key: API ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿
+  label_missing_api_access_key: ÐÐµÐ´Ð¾ÑÑ‚Ð¸Ð³Ð° API ÐºÐ»ÑƒÑ‡ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿
+  label_api_access_key_created_on: "API ÐºÐ»ÑƒÑ‡Ð¾Ñ‚ Ð·Ð° Ð¿Ñ€Ð¸ÑÑ‚Ð°Ð¿ Ðµ ÐºÑ€ÐµÐ¸Ñ€Ð°Ð½ Ð¿Ñ€ÐµÐ´ %{value}"
+  label_profile: ÐŸÑ€Ð¾Ñ„Ð¸Ð»
+  label_subtask_plural: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_project_copy_notifications: ÐŸÑ€Ð°ÑœÐ°Ñ˜ Ð¸Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°ÑšÐ° Ð¿Ð¾ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð° Ð¿Ñ€Ð¸ ÐºÐ¾Ð¿Ð¸Ñ€Ð°ÑšÐµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
+
+  button_login: ÐÐ°Ñ˜Ð°Ð²Ð¸ ÑÐµ
+  button_submit: Ð˜ÑÐ¿Ñ€Ð°Ñ‚Ð¸
+  button_save: Ð—Ð°Ñ‡ÑƒÐ²Ð°Ñ˜
+  button_check_all: Ð¨Ñ‚Ð¸ÐºÐ»Ð¸Ñ€Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ
+  button_uncheck_all: ÐžÐ´ÑˆÑ‚Ð¸ÐºÐ»Ð¸Ñ€Ð°Ñ˜ Ð³Ð¸ ÑÐ¸Ñ‚Ðµ
+  button_delete: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸
+  button_create: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜
+  button_create_and_continue: ÐšÑ€ÐµÐ¸Ñ€Ð°Ñ˜ Ð¸ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸
+  button_test: Ð¢ÐµÑÑ‚
+  button_edit: Ð£Ñ€ÐµÐ´Ð¸
+  button_add: Ð”Ð¾Ð´Ð°Ð´Ð¸
+  button_change: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸
+  button_apply: ÐŸÑ€Ð¸Ð¼ÐµÐ½Ð¸
+  button_clear: Ð˜Ð·Ð±Ñ€Ð¸ÑˆÐ¸
+  button_lock: Ð—Ð°ÐºÐ»ÑƒÑ‡Ð¸
+  button_unlock: ÐžÑ‚ÐºÐ»ÑƒÑ‡Ð¸
+  button_download: ÐŸÑ€ÐµÐ²Ð·ÐµÐ¼Ð¸
+  button_list: List
+  button_view: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°Ñ˜
+  button_move: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸
+  button_move_and_follow: ÐŸÑ€ÐµÐ¼ÐµÑÑ‚Ð¸ Ð¸ ÑÐ»ÐµÐ´Ð¸
+  button_back: Back
+  button_cancel: ÐžÑ‚ÐºÐ°Ð¶Ð¸
+  button_activate: ÐÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
+  button_sort: ÐŸÐ¾Ð´Ñ€ÐµÐ´Ð¸
+  button_log_time: Ð‘ÐµÐ»ÐµÐ¶Ð¸ Ð²Ñ€ÐµÐ¼Ðµ
+  button_rollback: Rollback to this version
+  button_watch: Ð¡Ð»ÐµÐ´Ð¸
+  button_unwatch: ÐÐµ ÑÐ»ÐµÐ´Ð¸
+  button_reply: ÐžÐ´Ð³Ð¾Ð²Ð¾Ñ€Ð¸
+  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
+  button_unarchive: ÐžÐ´Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð°Ñ˜
+  button_reset: Reset
+  button_rename: ÐŸÑ€ÐµÐ¸Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ˜
+  button_change_password: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸ Ð»Ð¾Ð·Ð¸Ð½ÐºÐ°
+  button_copy: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜
+  button_copy_and_follow: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜ Ð¸ ÑÐ»ÐµÐ´Ð¸
+  button_annotate: Annotate
+  button_update: ÐÐ¶ÑƒÑ€Ð¸Ñ€Ð°Ñ˜
+  button_configure: ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ñ˜
+  button_quote: Ð¦Ð¸Ñ‚Ð¸Ñ€Ð°Ñ˜
+  button_duplicate: ÐšÐ¾Ð¿Ð¸Ñ€Ð°Ñ˜
+  button_show: Show
+
+  status_active: Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¸
+  status_registered: Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð°Ð½Ð¸
+  status_locked: Ð·Ð°ÐºÐ»ÑƒÑ‡ÐµÐ½Ð¸
+
+  version_status_open: Ð¾Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+  version_status_locked: Ð·Ð°ÐºÐ»ÑƒÑ‡ÐµÐ½Ð¸
+  version_status_closed: Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸
+
+  field_active: Active
+
+  text_select_mail_notifications: Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð·Ð° ÐºÐ¾Ð¸ Ð½Ð°ÑÑ‚Ð°Ð½Ð¸ Ð´Ð° ÑÐµ Ð¿Ñ€Ð°ÑœÐ°Ð°Ñ‚ Ð¸Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°ÑšÐ° Ð¿Ð¾ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð° Ð´Ð° ÑÐµ Ð¿Ñ€Ð°ÑœÐ°Ð°Ñ‚.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 Ð·Ð½Ð°Ñ‡Ð¸ Ð±ÐµÐ· Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÑƒÐ²Ð°ÑšÐµ
+  text_project_destroy_confirmation: Ð”Ð°Ð»Ð¸ ÑÑ‚Ðµ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´ÐµÐºÐ° ÑÐ°ÐºÐ°Ñ‚Ðµ Ð´Ð° Ð³Ð¾ Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚ Ð¸ ÑÐ¸Ñ‚Ðµ Ð¿Ð¾Ð²Ñ€Ð·Ð°Ð½Ð¸ Ð¿Ð¾Ð´Ð°Ñ‚Ð¾Ñ†Ð¸?
+  text_subprojects_destroy_warning: "ÐÐµÐ³Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸: %{value} Ð¸ÑÑ‚Ð¾ Ñ‚Ð°ÐºÐ° ÑœÐµ Ð±Ð¸Ð´Ð°Ñ‚ Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐ°Ð½Ð¸."
+  text_workflow_edit: Select a role and a tracker to edit the workflow
+  text_are_you_sure: Ð”Ð°Ð»Ð¸ ÑÑ‚Ðµ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸?
+  text_journal_changed: "%{label} Ð¿Ñ€Ð¾Ð¼ÐµÐ½ÐµÑ‚Ð¾ Ð¾Ð´ %{old} Ð²Ð¾ %{new}"
+  text_journal_set_to: "%{label} set to %{value}"
+  text_journal_deleted: "%{label} Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐ°Ð½ (%{old})"
+  text_journal_added: "%{label} %{value} Ð´Ð¾Ð´Ð°Ð´ÐµÐ½"
+  text_tip_issue_begin_day: Ð·Ð°Ð´Ð°Ñ‡Ð¸ ÑˆÑ‚Ð¾ Ð¿Ð¾Ñ‡Ð½ÑƒÐ²Ð°Ð°Ñ‚ Ð¾Ð²Ð¾Ñ˜ Ð´ÐµÐ½
+  text_tip_issue_end_day: Ð·Ð°Ð´Ð°Ñ‡Ð¸ ÑˆÑ‚Ð¾ Ð·Ð°Ð²Ñ€ÑˆÑƒÐ²Ð°Ð°Ñ‚ Ð¾Ð²Ð¾Ñ˜ Ð´ÐµÐ½
+  text_tip_issue_begin_end_day: Ð·Ð°Ð´Ð°Ñ‡Ð¸ ÑˆÑ‚Ð¾ Ð¿Ð¾Ñ‡Ð½ÑƒÐ²Ð°Ð°Ñ‚ Ð¸ Ð·Ð°Ð²Ñ€ÑˆÑƒÐ²Ð°Ð°Ñ‚ Ð¾Ð²Ð¾Ñ˜ Ð´ÐµÐ½
+  text_caracters_maximum: "%{count} Ð·Ð½Ð°Ñ†Ð¸ Ð¼Ð°ÐºÑÐ¸Ð¼ÑƒÐ¼."
+  text_caracters_minimum: "ÐœÐ¾Ñ€Ð° Ð´Ð° Ðµ Ð½Ð°Ñ˜Ð¼Ð°Ð»ÐºÑƒ %{count} Ð·Ð½Ð°Ñ†Ð¸ Ð´Ð¾Ð»Ð³Ð¾."
+  text_length_between: "Ð”Ð¾Ð»Ð¶Ð¸Ð½Ð° Ð¿Ð¾Ð¼ÐµÑ“Ñƒ %{min} Ð¸ %{max} Ð·Ð½Ð°Ñ†Ð¸."
+  text_tracker_no_workflow: No workflow defined for this tracker
+  text_unallowed_characters: ÐÐµÐ´Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ Ð·Ð½Ð°Ñ†Ð¸
+  text_comma_separated: Ð”Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐµ Ð¿Ð¾Ð²ÐµÑœÐµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸ (Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸ ÑÐ¾ Ð·Ð°Ð¿Ð¸Ñ€ÐºÐ°).
+  text_line_separated: Ð”Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÐµ Ð¿Ð¾Ð²ÐµÑœÐµ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸ (ÐµÐ´Ð½Ð° Ð»Ð¸Ð½Ð¸Ñ˜Ð° Ð·Ð° ÑÐµÐºÐ¾Ñ˜Ð° Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚).
+  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
+  text_issue_added: "Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° %{id} Ðµ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²ÐµÐ½Ð° Ð¾Ð´ %{author}."
+  text_issue_updated: "Ð—Ð°Ð´Ð°Ñ‡Ð°Ñ‚Ð° %{id} Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð° Ð¾Ð´ %{author}."
+  text_wiki_destroy_confirmation: Ð”Ð°Ð»Ð¸ ÑÑ‚Ðµ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´ÐµÐºÐ° ÑÐ°ÐºÐ°Ñ‚Ðµ Ð´Ð° Ð³Ð¾ Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¾Ð²Ð° Ð²Ð¸ÐºÐ¸ Ð¸ Ñ†ÐµÐ»Ð°Ñ‚Ð° Ð½ÐµÐ³Ð¾Ð²Ð° ÑÐ¾Ð´Ñ€Ð¶Ð¸Ð½Ð°?
+  text_issue_category_destroy_question: "ÐÐµÐºÐ¾Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸ (%{count}) ÑÐµ Ð´Ð¾Ð´ÐµÐ»ÐµÐ½Ð¸ Ð½Ð° Ð¾Ð²Ð°Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°. Ð¨Ñ‚Ð¾ ÑÐ°ÐºÐ°Ñ‚Ðµ Ð´Ð° Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ðµ?"
+  text_issue_category_destroy_assignments: Remove category assignments
+  text_issue_category_reassign_to: Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð³Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸Ñ‚Ðµ Ð½Ð° Ð¾Ð²Ð°Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°
+  text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
+  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
+  text_load_default_configuration: Load the default configuration
+  text_status_changed_by_changeset: "Applied in changeset %{value}."
+  text_issues_destroy_confirmation: 'Ð”Ð°Ð»Ð¸ ÑÑ‚Ðµ ÑÐ¸Ð³ÑƒÑ€Ð½Ð¸ Ð´ÐµÐºÐ° ÑÐ°ÐºÐ°Ñ‚Ðµ Ð´Ð° Ð³Ð¸ Ð¸Ð·Ð±Ñ€Ð¸ÑˆÐµÑ‚Ðµ Ð¸Ð·Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸?'
+  text_select_project_modules: 'Ð˜Ð·Ð±ÐµÑ€ÐµÑ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð·Ð° Ð¾Ð²Ð¾Ñ˜ Ð¿Ñ€Ð¾ÐµÐºÑ‚:'
+  text_default_administrator_account_changed: Default administrator account changed
+  text_file_repository_writable: Ð’Ð¾ Ð¿Ð°Ð¿ÐºÐ°Ñ‚Ð° Ð·Ð° Ð¿Ñ€Ð¸Ð»Ð¾Ð·Ð¸ Ð¼Ð¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð·Ð°Ð¿Ð¸ÑˆÑƒÐ²Ð°
+  text_plugin_assets_writable: Ð’Ð¾ Ð¿Ð°Ð¿ÐºÐ°Ñ‚Ð° Ð·Ð° Ð´Ð¾Ð´Ð°Ñ‚Ð¾Ñ†Ð¸ Ð¼Ð¾Ð¶Ðµ Ð´Ð° ÑÐµ Ð·Ð°Ð¿Ð¸ÑˆÑƒÐ²Ð°
+  text_rmagick_available: RMagick available (Ð½ÐµÐ·Ð°Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾)
+  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do ?"
+  text_destroy_time_entries: Delete reported hours
+  text_assign_time_entries_to_project: Ð”Ð¾Ð´ÐµÐ»Ð¸ Ð³Ð¸ Ð¿Ñ€Ð¸Ñ˜Ð°Ð²ÐµÐ½Ð¸Ñ‚Ðµ Ñ‡Ð°ÑÐ¾Ð²Ð¸ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
+  text_reassign_time_entries: 'Reassign reported hours to this issue:'
+  text_user_wrote: "%{value} Ð½Ð°Ð¿Ð¸ÑˆÐ°:"
+  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
+  text_enumeration_category_reassign_to: 'Reassign them to this value:'
+  text_email_delivery_not_configured: "Ð”Ð¾ÑÑ‚Ð°Ð²Ð°Ñ‚Ð° Ð¿Ð¾ Ðµ-Ð¿Ð¾ÑˆÑ‚Ð° Ð½Ðµ Ðµ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°, Ð¸ Ð¸Ð·Ð²ÐµÑÑ‚ÑƒÐ²Ð°ÑšÐ°Ñ‚Ð° ÑÐµ Ð¾Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶ÐµÐ½Ð¸.\nÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð°Ñ˜Ñ‚Ðµ Ð³Ð¾ Ð’Ð°ÑˆÐ¸Ð¾Ñ‚  SMTP ÑÐµÑ€Ð²ÐµÑ€ Ð²Ð¾ config/configuration.yml Ð¸ Ñ€ÐµÑÑ‚Ð°Ñ€Ñ‚Ð¸Ñ€Ð°Ñ˜Ñ‚Ðµ Ñ˜Ð° Ð°Ð¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ˜Ð°Ñ‚Ð°."
+  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
+  text_custom_field_possible_values_info: 'One line for each value'
+  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
+  text_wiki_page_nullify_children: "Keep child pages as root pages"
+  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
+  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
+  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
+  text_zoom_in: Zoom in
+  text_zoom_out: Zoom out
+
+  default_role_manager: ÐœÐµÐ½Ð°ÑŸÐµÑ€
+  default_role_developer: Developer
+  default_role_reporter: Reporter
+  default_tracker_bug: Ð“Ñ€ÐµÑˆÐºÐ°
+  default_tracker_feature: Ð¤ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð°Ð»Ð½Ð¾ÑÑ‚
+  default_tracker_support: ÐŸÐ¾Ð´Ð´Ñ€ÑˆÐºÐ°
+  default_issue_status_new: ÐÐ¾Ð²Ð°
+  default_issue_status_in_progress: Ð’Ð¾ Ð¿Ñ€Ð¾Ð³Ñ€ÐµÑ
+  default_issue_status_resolved: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð°
+  default_issue_status_feedback: Feedback
+  default_issue_status_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
+  default_issue_status_rejected: ÐžÐ´Ð±Ð¸ÐµÐ½Ð°
+  default_doc_category_user: ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ‡ÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ˜Ð°
+  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸Ñ‡ÐºÐ° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ˜Ð°
+  default_priority_low: ÐÐ¸Ð·Ð¾Ðº
+  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»ÐµÐ½
+  default_priority_high: Ð’Ð¸ÑÐ¾Ðº
+  default_priority_urgent: Ð˜Ñ‚Ð½Ð¾
+  default_priority_immediate: Ð’ÐµÐ´Ð½Ð°Ñˆ
+  default_activity_design: Ð”Ð¸Ð·Ð°Ñ˜Ð½
+  default_activity_development: Ð Ð°Ð·Ð²Ð¾Ñ˜
+
+  enumeration_issue_priorities: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  enumeration_activities: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ð¸ (ÑÐ»ÐµÐ´ÐµÑšÐµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ)
+  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼ÑÐºÐ° Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚
+
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Commit messages encoding
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 Ð—Ð°Ð´Ð°Ñ‡Ð°
+    one:   1 Ð—Ð°Ð´Ð°Ñ‡Ð°
+    other: "%{count} Ð—Ð°Ð´Ð°Ñ‡Ð¸"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: ÑÐ¸Ñ‚Ðµ
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Ð¡Ð¾ ÑÐ¸Ñ‚Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_cross_project_tree: Ð¡Ð¾ Ð´Ñ€Ð²Ð¾Ñ‚Ð¾ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
+  label_cross_project_hierarchy: Ð¡Ð¾ Ñ…Ð¸ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ˜Ð°Ñ‚Ð° Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ñ‚
+  label_cross_project_system: Ð¡Ð¾ ÑÐ¸Ñ‚Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ð’ÐºÑƒÐ¿Ð½Ð¾
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_footer: Email footer
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/730cecaf2c14ad4ffdebffd122755f219888a9de.svn-base
--- /dev/null
+++ b/.svn/pristine/73/730cecaf2c14ad4ffdebffd122755f219888a9de.svn-base
@@ -0,0 +1,1093 @@
+# Update to 2.2 by Karel Picman <karel.picman@kontron.com>
+# Update to 1.1 by Michal Gebauer <mishak@mishak.net>
+# Updated by Josef LiÅ¡ka <jl@chl.cz>
+# CZ translation by Maxim KruÅ¡ina | Massimo Filippi, s.r.o. | maxim@mxm.cz
+# Based on original CZ translation by Jan KadleÄek
+cs:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [NedÄ›le, PondÄ›lÃ­, ÃšterÃ½, StÅ™eda, ÄŒtvrtek, PÃ¡tek, Sobota]
+    abbr_day_names: [Ne, Po, Ãšt, St, ÄŒt, PÃ¡, So]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Leden, Ãšnor, BÅ™ezen, Duben, KvÄ›ten, ÄŒerven, ÄŒervenec, Srpen, ZÃ¡Å™Ã­, Å˜Ã­jen, Listopad, Prosinec]
+    abbr_month_names: [~, Led, Ãšno, BÅ™e, Dub, KvÄ›, ÄŒer, ÄŒec, Srp, ZÃ¡Å™, Å˜Ã­j, Lis, Pro]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "dop."
+    pm: "odp."
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pÅ¯l minuty"
+      less_than_x_seconds:
+        one:   "mÃ©nÄ› neÅ¾ sekunda"
+        other: "mÃ©nÄ› neÅ¾ %{count} sekund"
+      x_seconds:
+        one:   "1 sekunda"
+        other: "%{count} sekund"
+      less_than_x_minutes:
+        one:   "mÃ©nÄ› neÅ¾ minuta"
+        other: "mÃ©nÄ› neÅ¾ %{count} minut"
+      x_minutes:
+        one:   "1 minuta"
+        other: "%{count} minut"
+      about_x_hours:
+        one:   "asi 1 hodina"
+        other: "asi %{count} hodin"
+      x_hours:
+        one:   "1 hodina"
+        other: "%{count} hodin"
+      x_days:
+        one:   "1 den"
+        other: "%{count} dnÅ¯"
+      about_x_months:
+        one:   "asi 1 mÄ›sÃ­c"
+        other: "asi %{count} mÄ›sÃ­cÅ¯"
+      x_months:
+        one:   "1 mÄ›sÃ­c"
+        other: "%{count} mÄ›sÃ­cÅ¯"
+      about_x_years:
+        one:   "asi 1 rok"
+        other: "asi %{count} let"
+      over_x_years:
+        one:   "vÃ­ce neÅ¾ 1 rok"
+        other: "vÃ­ce neÅ¾ %{count} roky"
+      almost_x_years:
+        one:   "tÃ©meÅ™ 1 rok"
+        other: "tÃ©mÄ›Å™ %{count} roky"
+
+  number:
+    # VÃ½chozÃ­ formÃ¡t pro ÄÃ­sla
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Bajt"
+            other: "BajtÅ¯"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "a"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 chyba zabrÃ¡nila uloÅ¾enÃ­ %{model}"
+          other:  "%{count} chyb zabrÃ¡nilo uloÅ¾enÃ­ %{model}"
+      messages:
+        inclusion: "nenÃ­ zahrnuto v seznamu"
+        exclusion: "je rezervovÃ¡no"
+        invalid: "je neplatnÃ©"
+        confirmation: "se neshoduje s potvrzenÃ­m"
+        accepted: "musÃ­ bÃ½t akceptovÃ¡no"
+        empty: "nemÅ¯Å¾e bÃ½t prÃ¡zdnÃ½"
+        blank: "nemÅ¯Å¾e bÃ½t prÃ¡zdnÃ½"
+        too_long: "je pÅ™Ã­liÅ¡ dlouhÃ½"
+        too_short: "je pÅ™Ã­liÅ¡ krÃ¡tkÃ½"
+        wrong_length: "mÃ¡ chybnou dÃ©lku"
+        taken: "je jiÅ¾ pouÅ¾ito"
+        not_a_number: "nenÃ­ ÄÃ­slo"
+        not_a_date: "nenÃ­ platnÃ© datum"
+        greater_than: "musÃ­ bÃ½t vÄ›tÅ¡Ã­ neÅ¾ %{count}"
+        greater_than_or_equal_to: "musÃ­ bÃ½t vÄ›tÅ¡Ã­ nebo rovno %{count}"
+        equal_to: "musÃ­ bÃ½t pÅ™esnÄ› %{count}"
+        less_than: "musÃ­ bÃ½t mÃ©nÄ› neÅ¾ %{count}"
+        less_than_or_equal_to: "musÃ­ bÃ½t mÃ©nÄ› nebo rovno %{count}"
+        odd: "musÃ­ bÃ½t lichÃ©"
+        even: "musÃ­ bÃ½t sudÃ©"
+        greater_than_start_date: "musÃ­ bÃ½t vÄ›tÅ¡Ã­ neÅ¾ poÄÃ¡teÄnÃ­ datum"
+        not_same_project: "nepatÅ™Ã­ stejnÃ©mu projektu"
+        circular_dependency: "Tento vztah by vytvoÅ™il cyklickou zÃ¡vislost"
+        cant_link_an_issue_with_a_descendant: "Ãškol nemÅ¯Å¾e bÃ½t spojen s jednÃ­m z jeho dÃ­lÄÃ­ch ÃºkolÅ¯"
+
+  actionview_instancetag_blank_option: ProsÃ­m vyberte
+
+  general_text_No: 'Ne'
+  general_text_Yes: 'Ano'
+  general_text_no: 'ne'
+  general_text_yes: 'ano'
+  general_lang_name: 'Czech (ÄŒeÅ¡tina)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: ÃšÄet byl ÃºspÄ›Å¡nÄ› zmÄ›nÄ›n.
+  notice_account_invalid_creditentials: ChybnÃ© jmÃ©no nebo heslo
+  notice_account_password_updated: Heslo bylo ÃºspÄ›Å¡nÄ› zmÄ›nÄ›no.
+  notice_account_wrong_password: ChybnÃ© heslo
+  notice_account_register_done: ÃšÄet byl ÃºspÄ›Å¡nÄ› vytvoÅ™en. Pro aktivaci ÃºÄtu kliknÄ›te na odkaz v emailu, kterÃ½ vÃ¡m byl zaslÃ¡n.
+  notice_account_unknown_email: NeznÃ¡mÃ½ uÅ¾ivatel.
+  notice_can_t_change_password: Tento ÃºÄet pouÅ¾Ã­vÃ¡ externÃ­ autentifikaci. Zde heslo zmÄ›nit nemÅ¯Å¾ete.
+  notice_account_lost_email_sent: Byl vÃ¡m zaslÃ¡n email s intrukcemi jak si nastavÃ­te novÃ© heslo.
+  notice_account_activated: VÃ¡Å¡ ÃºÄet byl aktivovÃ¡n. NynÃ­ se mÅ¯Å¾ete pÅ™ihlÃ¡sit.
+  notice_successful_create: ÃšspÄ›Å¡nÄ› vytvoÅ™eno.
+  notice_successful_update: ÃšspÄ›Å¡nÄ› aktualizovÃ¡no.
+  notice_successful_delete: ÃšspÄ›Å¡nÄ› odstranÄ›no.
+  notice_successful_connection: ÃšspÄ›Å¡nÃ© pÅ™ipojenÃ­.
+  notice_file_not_found: StrÃ¡nka, kterou se snaÅ¾Ã­te zobrazit, neexistuje nebo byla smazÃ¡na.
+  notice_locking_conflict: Ãšdaje byly zmÄ›nÄ›ny jinÃ½m uÅ¾ivatelem.
+  notice_not_authorized: NemÃ¡te dostateÄnÃ¡ prÃ¡va pro zobrazenÃ­ tÃ©to strÃ¡nky.
+  notice_not_authorized_archived_project: Projekt, ke kterÃ©mu se snaÅ¾Ã­te pÅ™istupovat, byl archivovÃ¡n.
+  notice_email_sent: "Na adresu %{value} byl odeslÃ¡n email"
+  notice_email_error: "PÅ™i odesÃ­lÃ¡nÃ­ emailu nastala chyba (%{value})"
+  notice_feeds_access_key_reseted: VÃ¡Å¡ klÃ­Ä pro pÅ™Ã­stup k RSS byl resetovÃ¡n.
+  notice_api_access_key_reseted: VÃ¡Å¡ API pÅ™Ã­stupovÃ½ klÃ­Ä byl resetovÃ¡n.
+  notice_failed_to_save_issues: "Chyba pÅ™i uloÅ¾enÃ­ %{count} Ãºkolu(Å¯) z %{total} vybranÃ½ch: %{ids}."
+  notice_failed_to_save_members: "NepodaÅ™ilo se uloÅ¾it Älena(y): %{errors}."
+  notice_no_issue_selected: "Nebyl zvolen Å¾Ã¡dnÃ½ Ãºkol. ProsÃ­m, zvolte Ãºkoly, kterÃ© chcete editovat"
+  notice_account_pending: "VÃ¡Å¡ ÃºÄet byl vytvoÅ™en, nynÃ­ ÄekÃ¡ na schvÃ¡lenÃ­ administrÃ¡torem."
+  notice_default_data_loaded: VÃ½chozÃ­ konfigurace ÃºspÄ›Å¡nÄ› nahrÃ¡na.
+  notice_unable_delete_version: Nemohu odstanit verzi
+  notice_unable_delete_time_entry: Nelze smazat zÃ¡znam Äasu.
+  notice_issue_done_ratios_updated: Koeficienty dokonÄenÃ­ Ãºkolu byly aktualizovÃ¡ny.
+  notice_gantt_chart_truncated: Graf byl oÅ™Ã­znut, poÄet poloÅ¾ek pÅ™esÃ¡hl limit pro zobrazenÃ­ (%{max})
+
+  error_can_t_load_default_data: "VÃ½chozÃ­ konfigurace nebyla nahrÃ¡na: %{value}"
+  error_scm_not_found: "PoloÅ¾ka a/nebo revize neexistujÃ­ v repozitÃ¡Å™i."
+  error_scm_command_failed: "PÅ™i pokusu o pÅ™Ã­stup k repozitÃ¡Å™i doÅ¡lo k chybÄ›: %{value}"
+  error_scm_annotate: "PoloÅ¾ka neexistuje nebo nemÅ¯Å¾e bÃ½t komentovÃ¡na."
+  error_issue_not_found_in_project: 'Ãškol nebyl nalezen nebo nepatÅ™Ã­ k tomuto projektu'
+  error_no_tracker_in_project: Å½Ã¡dnÃ¡ fronta nebyla pÅ™iÅ™azena tomuto projektu. ProsÃ­m zkontroluje nastavenÃ­ projektu.
+  error_no_default_issue_status: NenÃ­ nastaven vÃ½chozÃ­ stav ÃºkolÅ¯. ProsÃ­m zkontrolujte nastavenÃ­ ("Administrace -> Stavy ÃºkolÅ¯").
+  error_can_not_delete_custom_field: Nelze smazat volitelnÃ© pole
+  error_can_not_delete_tracker: Tato fronta obsahuje Ãºkoly a nemÅ¯Å¾e bÃ½t smazÃ¡na.
+  error_can_not_remove_role: Tato role je prÃ¡vÄ› pouÅ¾Ã­vanÃ¡ a nelze ji smazat.
+  error_can_not_reopen_issue_on_closed_version: Ãškol pÅ™iÅ™azenÃ½ k uzavÅ™enÃ© verzi nemÅ¯Å¾e bÃ½t znovu otevÅ™en
+  error_can_not_archive_project: Tento projekt nemÅ¯Å¾e bÃ½t archivovÃ¡n
+  error_issue_done_ratios_not_updated: Koeficient dokonÄenÃ­ Ãºkolu nebyl aktualizovÃ¡n.
+  error_workflow_copy_source: ProsÃ­m vyberte zdrojovou frontu nebo roli
+  error_workflow_copy_target: ProsÃ­m vyberte cÃ­lovou frontu(y) a roli(e)
+  error_unable_delete_issue_status: Nelze smazat stavy ÃºkolÅ¯
+  error_unable_to_connect: Nelze se pÅ™ipojit (%{value})
+  warning_attachments_not_saved: "%{count} soubor(Å¯) nebylo moÅ¾nÃ© uloÅ¾it."
+
+  mail_subject_lost_password: "VaÅ¡e heslo (%{value})"
+  mail_body_lost_password: 'Pro zmÄ›nu vaÅ¡eho hesla kliknÄ›te na nÃ¡sledujÃ­cÃ­ odkaz:'
+  mail_subject_register: "Aktivace ÃºÄtu (%{value})"
+  mail_body_register: 'Pro aktivaci vaÅ¡eho ÃºÄtu kliknÄ›te na nÃ¡sledujÃ­cÃ­ odkaz:'
+  mail_body_account_information_external: "PomocÃ­ vaÅ¡eho ÃºÄtu %{value} se mÅ¯Å¾ete pÅ™ihlÃ¡sit."
+  mail_body_account_information: Informace o vaÅ¡em ÃºÄtu
+  mail_subject_account_activation_request: "Aktivace %{value} ÃºÄtu"
+  mail_body_account_activation_request: "Byl zaregistrovÃ¡n novÃ½ uÅ¾ivatel %{value}. Aktivace jeho ÃºÄtu zÃ¡visÃ­ na vaÅ¡em potvrzenÃ­."
+  mail_subject_reminder: "%{count} Ãºkol(Å¯) mÃ¡ termÃ­n bÄ›hem nÄ›kolik dnÃ­ (%{days})"
+  mail_body_reminder: "%{count} Ãºkol(Å¯), kterÃ© mÃ¡te pÅ™iÅ™azeny mÃ¡ termÃ­n bÄ›hem nÄ›kolika dnÃ­ (%{days}):"
+  mail_subject_wiki_content_added: "'%{id}' Wiki strÃ¡nka byla pÅ™idÃ¡na"
+  mail_body_wiki_content_added: "'%{id}' Wiki strÃ¡nka byla pÅ™idÃ¡na od %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' Wiki strÃ¡nka byla aktualizovÃ¡na"
+  mail_body_wiki_content_updated: "'%{id}' Wiki strÃ¡nka byla aktualizovÃ¡na od %{author}."
+
+
+  field_name: NÃ¡zev
+  field_description: Popis
+  field_summary: PÅ™ehled
+  field_is_required: PovinnÃ© pole
+  field_firstname: JmÃ©no
+  field_lastname: PÅ™Ã­jmenÃ­
+  field_mail: Email
+  field_filename: Soubor
+  field_filesize: Velikost
+  field_downloads: StaÅ¾eno
+  field_author: Autor
+  field_created_on: VytvoÅ™eno
+  field_updated_on: AktualizovÃ¡no
+  field_field_format: FormÃ¡t
+  field_is_for_all: Pro vÅ¡echny projekty
+  field_possible_values: MoÅ¾nÃ© hodnoty
+  field_regexp: RegulÃ¡rnÃ­ vÃ½raz
+  field_min_length: MinimÃ¡lnÃ­ dÃ©lka
+  field_max_length: MaximÃ¡lnÃ­ dÃ©lka
+  field_value: Hodnota
+  field_category: Kategorie
+  field_title: NÃ¡zev
+  field_project: Projekt
+  field_issue: Ãškol
+  field_status: Stav
+  field_notes: PoznÃ¡mka
+  field_is_closed: Ãškol uzavÅ™en
+  field_is_default: VÃ½chozÃ­ stav
+  field_tracker: Fronta
+  field_subject: PÅ™edmÄ›t
+  field_due_date: UzavÅ™Ã­t do
+  field_assigned_to: PÅ™iÅ™azeno
+  field_priority: Priorita
+  field_fixed_version: CÃ­lovÃ¡ verze
+  field_user: UÅ¾ivatel
+  field_principal: HlavnÃ­
+  field_role: Role
+  field_homepage: DomovskÃ¡ strÃ¡nka
+  field_is_public: VeÅ™ejnÃ½
+  field_parent: NadÅ™azenÃ½ projekt
+  field_is_in_roadmap: Ãškoly zobrazenÃ© v plÃ¡nu
+  field_login: PÅ™ihlÃ¡Å¡enÃ­
+  field_mail_notification: EmailovÃ¡ oznÃ¡menÃ­
+  field_admin: AdministrÃ¡tor
+  field_last_login_on: PoslednÃ­ pÅ™ihlÃ¡Å¡enÃ­
+  field_language: Jazyk
+  field_effective_date: Datum
+  field_password: Heslo
+  field_new_password: NovÃ© heslo
+  field_password_confirmation: PotvrzenÃ­
+  field_version: Verze
+  field_type: Typ
+  field_host: Host
+  field_port: Port
+  field_account: ÃšÄet
+  field_base_dn: Base DN
+  field_attr_login: PÅ™ihlÃ¡Å¡enÃ­ (atribut)
+  field_attr_firstname: JmÃ©no (atribut)
+  field_attr_lastname: PÅ™Ã­jemnÃ­ (atribut)
+  field_attr_mail: Email (atribut)
+  field_onthefly: AutomatickÃ© vytvÃ¡Å™enÃ­ uÅ¾ivatelÅ¯
+  field_start_date: ZaÄÃ¡tek
+  field_done_ratio: "% Hotovo"
+  field_auth_source: AutentifikaÄnÃ­ mÃ³d
+  field_hide_mail: Nezobrazovat mÅ¯j email
+  field_comments: KomentÃ¡Å™
+  field_url: URL
+  field_start_page: VÃ½chozÃ­ strÃ¡nka
+  field_subproject: Podprojekt
+  field_hours: Hodiny
+  field_activity: Aktivita
+  field_spent_on: Datum
+  field_identifier: IdentifikÃ¡tor
+  field_is_filter: PouÅ¾Ã­t jako filtr
+  field_issue_to: SouvisejÃ­cÃ­ Ãºkol
+  field_delay: ZpoÅ¾dÄ›nÃ­
+  field_assignable: Ãškoly mohou bÃ½t pÅ™iÅ™azeny tÃ©to roli
+  field_redirect_existing_links: PÅ™esmÄ›rovat stÃ¡vajÃ­cÃ­ odkazy
+  field_estimated_hours: OdhadovanÃ¡ doba
+  field_column_names: Sloupce
+  field_time_entries: ZaznamenanÃ½ Äas
+  field_time_zone: ÄŒasovÃ© pÃ¡smo
+  field_searchable: UmoÅ¾nit vyhledÃ¡vÃ¡nÃ­
+  field_default_value: VÃ½chozÃ­ hodnota
+  field_comments_sorting: Zobrazit komentÃ¡Å™e
+  field_parent_title: RodiÄovskÃ¡ strÃ¡nka
+  field_editable: EditovatelnÃ½
+  field_watcher: Sleduje
+  field_identity_url: OpenID URL
+  field_content: Obsah
+  field_group_by: Seskupovat vÃ½sledky podle
+  field_sharing: SdÃ­lenÃ­
+  field_parent_issue: RodiÄovskÃ½ Ãºkol
+  field_member_of_group: Skupina pÅ™iÅ™aditele
+  field_assigned_to_role: Role pÅ™iÅ™aditele
+  field_text: TextovÃ© pole
+  field_visible: ViditelnÃ½
+
+  setting_app_title: NÃ¡zev aplikace
+  setting_app_subtitle: Podtitulek aplikace
+  setting_welcome_text: UvÃ­tacÃ­ text
+  setting_default_language: VÃ½chozÃ­ jazyk
+  setting_login_required: Autentifikace vyÅ¾adovÃ¡na
+  setting_self_registration: Povolena automatickÃ¡ registrace
+  setting_attachment_max_size: MaximÃ¡lnÃ­ velikost pÅ™Ã­lohy
+  setting_issues_export_limit: Limit pro export ÃºkolÅ¯
+  setting_mail_from: OdesÃ­lat emaily z adresy
+  setting_bcc_recipients: PÅ™Ã­jemci jako skrytÃ¡ kopie (bcc)
+  setting_plain_text_mail: pouze prostÃ½ text (ne HTML)
+  setting_host_name: JmÃ©no serveru
+  setting_text_formatting: FormÃ¡tovÃ¡nÃ­ textu
+  setting_wiki_compression: Komprese historie Wiki
+  setting_feeds_limit: Limit obsahu pÅ™Ã­spÄ›vkÅ¯
+  setting_default_projects_public: NovÃ© projekty nastavovat jako veÅ™ejnÃ©
+  setting_autofetch_changesets: Automaticky stahovat commity
+  setting_sys_api_enabled: Povolit WS pro sprÃ¡vu repozitory
+  setting_commit_ref_keywords: KlÃ­ÄovÃ¡ slova pro odkazy
+  setting_commit_fix_keywords: KlÃ­ÄovÃ¡ slova pro uzavÅ™enÃ­
+  setting_autologin: AutomatickÃ© pÅ™ihlaÅ¡ovÃ¡nÃ­
+  setting_date_format: FormÃ¡t data
+  setting_time_format: FormÃ¡t Äasu
+  setting_cross_project_issue_relations: Povolit vazby ÃºkolÅ¯ napÅ™Ã­Ä projekty
+  setting_issue_list_default_columns: VÃ½chozÃ­ sloupce zobrazenÃ© v seznamu ÃºkolÅ¯
+  setting_emails_header: ZÃ¡hlavÃ­ emailÅ¯
+  setting_emails_footer: ZÃ¡patÃ­ emailÅ¯
+  setting_protocol: Protokol
+  setting_per_page_options: PovolenÃ© poÄty Å™Ã¡dkÅ¯ na strÃ¡nce
+  setting_user_format: FormÃ¡t zobrazenÃ­ uÅ¾ivatele
+  setting_activity_days_default: Dny zobrazenÃ© v Äinnosti projektu
+  setting_display_subprojects_issues: Automaticky zobrazit Ãºkoly podprojektu v hlavnÃ­m projektu
+  setting_enabled_scm: PovolenÃ© SCM
+  setting_mail_handler_body_delimiters: ZkrÃ¡tit e-maily po jednom z tÄ›chto Å™Ã¡dkÅ¯
+  setting_mail_handler_api_enabled: Povolit WS pro pÅ™Ã­chozÃ­ e-maily
+  setting_mail_handler_api_key: API klÃ­Ä
+  setting_sequential_project_identifiers: Generovat sekvenÄnÃ­ identifikÃ¡tory projektÅ¯
+  setting_gravatar_enabled: PouÅ¾Ã­t uÅ¾ivatelskÃ© ikony Gravatar
+  setting_gravatar_default: VÃ½chozÃ­ Gravatar
+  setting_diff_max_lines_displayed: MaximÃ¡lnÃ­ poÄet zobrazenÃ½ch Å™Ã¡dkÅ¯ rozdÃ­lu
+  setting_file_max_size_displayed: MaximÃ¡lnÃ­ velikost textovÃ½ch souborÅ¯ zobrazenÃ½ch pÅ™Ã­mo na strÃ¡nce
+  setting_repository_log_display_limit: MaximÃ¡lnÃ­ poÄet revizÃ­ zobrazenÃ½ch v logu souboru
+  setting_openid: UmoÅ¾nit pÅ™ihlaÅ¡ovÃ¡nÃ­ a registrace s OpenID
+  setting_password_min_length: MinimÃ¡lnÃ­ dÃ©lka hesla
+  setting_new_project_user_role_id: Role pÅ™iÅ™azenÃ¡ uÅ¾ivateli bez prÃ¡v administrÃ¡tora, kterÃ½ projekt vytvoÅ™il
+  setting_default_projects_modules: VÃ½chozÃ­ zapnutnÃ© moduly pro novÃ½ projekt
+  setting_issue_done_ratio: SpoÄÃ­tat koeficient dokonÄenÃ­ Ãºkolu s
+  setting_issue_done_ratio_issue_field: PouÅ¾Ã­t pole Ãºkolu
+  setting_issue_done_ratio_issue_status: PouÅ¾Ã­t stav Ãºkolu
+  setting_start_of_week: ZaÄÃ­nat kalendÃ¡Å™e
+  setting_rest_api_enabled: Zapnout sluÅ¾bu REST
+  setting_cache_formatted_text: UklÃ¡dat formÃ¡tovanÃ½ text do vyrovnÃ¡vacÃ­ pamÄ›ti
+  setting_default_notification_option: VÃ½chozÃ­ nastavenÃ­ oznÃ¡menÃ­
+  setting_commit_logtime_enabled: Povolit zapisovÃ¡nÃ­ Äasu
+  setting_commit_logtime_activity_id: Aktivita pro zapsanÃ½ Äas
+  setting_gantt_items_limit: MaximÃ¡lnÃ­ poÄet poloÅ¾ek zobrazenÃ½ na ganttovÄ› diagramu
+
+  permission_add_project: VytvoÅ™it projekt
+  permission_add_subprojects: VytvoÅ™it podprojekty
+  permission_edit_project: Ãšprava projektÅ¯
+  permission_select_project_modules: VÃ½bÄ›r modulÅ¯ projektu
+  permission_manage_members: SpravovÃ¡nÃ­ ÄlenstvÃ­
+  permission_manage_project_activities: Spravovat aktivity projektu
+  permission_manage_versions: SpravovÃ¡nÃ­ verzÃ­
+  permission_manage_categories: SpravovÃ¡nÃ­ kategoriÃ­ ÃºkolÅ¯
+  permission_view_issues: Zobrazit Ãºkoly
+  permission_add_issues: PÅ™idÃ¡vÃ¡nÃ­ ÃºkolÅ¯
+  permission_edit_issues: UpravovÃ¡nÃ­ ÃºkolÅ¯
+  permission_manage_issue_relations: SpravovÃ¡nÃ­ vztahÅ¯ mezi Ãºkoly
+  permission_add_issue_notes: PÅ™idÃ¡vÃ¡nÃ­ poznÃ¡mek
+  permission_edit_issue_notes: UpravovÃ¡nÃ­ poznÃ¡mek
+  permission_edit_own_issue_notes: UpravovÃ¡nÃ­ vlastnÃ­ch poznÃ¡mek
+  permission_move_issues: PÅ™esouvÃ¡nÃ­ ÃºkolÅ¯
+  permission_delete_issues: MazÃ¡nÃ­ ÃºkolÅ¯
+  permission_manage_public_queries: SprÃ¡va veÅ™ejnÃ½ch dotazÅ¯
+  permission_save_queries: UklÃ¡dÃ¡nÃ­ dotazÅ¯
+  permission_view_gantt: ZobrazenÃ­ ganttova diagramu
+  permission_view_calendar: ProhlÃ­Å¾enÃ­ kalendÃ¡Å™e
+  permission_view_issue_watchers: ZobrazenÃ­ seznamu sledujÃ­cÃ­ch uÅ¾ivatelÅ¯
+  permission_add_issue_watchers: PÅ™idÃ¡nÃ­ sledujÃ­cÃ­ch uÅ¾ivatelÅ¯
+  permission_delete_issue_watchers: Smazat sledujÃ­cÃ­ uÅ¾ivatele
+  permission_log_time: ZaznamenÃ¡vÃ¡nÃ­ strÃ¡venÃ©ho Äasu
+  permission_view_time_entries: ZobrazenÃ­ strÃ¡venÃ©ho Äasu
+  permission_edit_time_entries: UpravovÃ¡nÃ­ zÃ¡znamÅ¯ o strÃ¡venÃ©m Äasu
+  permission_edit_own_time_entries: UpravovÃ¡nÃ­ vlastnÃ­ch zÃ¡zamÅ¯ o strÃ¡venÃ©m Äase
+  permission_manage_news: SpravovÃ¡nÃ­ novinek
+  permission_comment_news: KomentovÃ¡nÃ­ novinek
+  permission_view_documents: ProhlÃ­Å¾enÃ­ dokumentÅ¯
+  permission_manage_files: SpravovÃ¡nÃ­ souborÅ¯
+  permission_view_files: ProhlÃ­Å¾enÃ­ souborÅ¯
+  permission_manage_wiki: SpravovÃ¡nÃ­ Wiki
+  permission_rename_wiki_pages: PÅ™ejmenovÃ¡vÃ¡nÃ­ Wiki strÃ¡nek
+  permission_delete_wiki_pages: MazÃ¡nÃ­ strÃ¡nek na Wiki
+  permission_view_wiki_pages: ProhlÃ­Å¾enÃ­ Wiki
+  permission_view_wiki_edits: ProhlÃ­Å¾enÃ­ historie Wiki
+  permission_edit_wiki_pages: UpravovÃ¡nÃ­ strÃ¡nek Wiki
+  permission_delete_wiki_pages_attachments: MazÃ¡nÃ­ pÅ™Ã­loh
+  permission_protect_wiki_pages: ZabezpeÄenÃ­ Wiki strÃ¡nek
+  permission_manage_repository: SpravovÃ¡nÃ­ repozitÃ¡Å™e
+  permission_browse_repository: ProchÃ¡zenÃ­ repozitÃ¡Å™e
+  permission_view_changesets: ZobrazovÃ¡nÃ­ sady zmÄ›n
+  permission_commit_access: Commit pÅ™Ã­stup
+  permission_manage_boards: SprÃ¡va diskusnÃ­ch fÃ³r
+  permission_view_messages: ProhlÃ­Å¾enÃ­ zprÃ¡v
+  permission_add_messages: PosÃ­lÃ¡nÃ­ zprÃ¡v
+  permission_edit_messages: UpravovÃ¡nÃ­ zprÃ¡v
+  permission_edit_own_messages: Upravit vlastnÃ­ zprÃ¡vy
+  permission_delete_messages: MazÃ¡nÃ­ zprÃ¡v
+  permission_delete_own_messages: Smazat vlastnÃ­ zprÃ¡vy
+  permission_export_wiki_pages: Exportovat Wiki strÃ¡nky
+  permission_manage_subtasks: Spravovat dÃ­lÄÃ­ Ãºkoly
+
+  project_module_issue_tracking: SledovÃ¡nÃ­ ÃºkolÅ¯
+  project_module_time_tracking: SledovÃ¡nÃ­ Äasu
+  project_module_news: Novinky
+  project_module_documents: Dokumenty
+  project_module_files: Soubory
+  project_module_wiki: Wiki
+  project_module_repository: RepozitÃ¡Å™
+  project_module_boards: Diskuse
+  project_module_calendar: KalendÃ¡Å™
+  project_module_gantt: Gantt
+
+  label_user: UÅ¾ivatel
+  label_user_plural: UÅ¾ivatelÃ©
+  label_user_new: NovÃ½ uÅ¾ivatel
+  label_user_anonymous: AnonymnÃ­
+  label_project: Projekt
+  label_project_new: NovÃ½ projekt
+  label_project_plural: Projekty
+  label_x_projects:
+    zero:  Å¾Ã¡dnÃ© projekty
+    one:   1 projekt
+    other: "%{count} projekty(Å¯)"
+  label_project_all: VÅ¡echny projekty
+  label_project_latest: PoslednÃ­ projekty
+  label_issue: Ãškol
+  label_issue_new: NovÃ½ Ãºkol
+  label_issue_plural: Ãškoly
+  label_issue_view_all: VÅ¡echny Ãºkoly
+  label_issues_by: "Ãškoly podle %{value}"
+  label_issue_added: Ãškol pÅ™idÃ¡n
+  label_issue_updated: Ãškol aktualizovÃ¡n
+  label_document: Dokument
+  label_document_new: NovÃ½ dokument
+  label_document_plural: Dokumenty
+  label_document_added: Dokument pÅ™idÃ¡n
+  label_role: Role
+  label_role_plural: Role
+  label_role_new: NovÃ¡ role
+  label_role_and_permissions: Role a prÃ¡va
+  label_member: ÄŒlen
+  label_member_new: NovÃ½ Älen
+  label_member_plural: ÄŒlenovÃ©
+  label_tracker: Fronta
+  label_tracker_plural: Fronty
+  label_tracker_new: NovÃ¡ fronta
+  label_workflow: PrÅ¯bÄ›h prÃ¡ce
+  label_issue_status: Stav Ãºkolu
+  label_issue_status_plural: Stavy ÃºkolÅ¯
+  label_issue_status_new: NovÃ½ stav
+  label_issue_category: Kategorie Ãºkolu
+  label_issue_category_plural: Kategorie ÃºkolÅ¯
+  label_issue_category_new: NovÃ¡ kategorie
+  label_custom_field: UÅ¾ivatelskÃ© pole
+  label_custom_field_plural: UÅ¾ivatelskÃ¡ pole
+  label_custom_field_new: NovÃ© uÅ¾ivatelskÃ© pole
+  label_enumerations: Seznamy
+  label_enumeration_new: NovÃ¡ hodnota
+  label_information: Informace
+  label_information_plural: Informace
+  label_please_login: PÅ™ihlaÅ¡te se, prosÃ­m
+  label_register: Registrovat
+  label_login_with_open_id_option: nebo se pÅ™ihlaÅ¡te s OpenID
+  label_password_lost: ZapomenutÃ© heslo
+  label_home: ÃšvodnÃ­
+  label_my_page: Moje strÃ¡nka
+  label_my_account: MÅ¯j ÃºÄet
+  label_my_projects: Moje projekty
+  label_my_page_block: Bloky na mÃ© strÃ¡nce
+  label_administration: Administrace
+  label_login: PÅ™ihlÃ¡Å¡enÃ­
+  label_logout: OdhlÃ¡Å¡enÃ­
+  label_help: NÃ¡povÄ›da
+  label_reported_issues: NahlÃ¡Å¡enÃ© Ãºkoly
+  label_assigned_to_me_issues: MÃ© Ãºkoly
+  label_last_login: PoslednÃ­ pÅ™ihlÃ¡Å¡enÃ­
+  label_registered_on: RegistrovÃ¡n
+  label_activity: Aktivita
+  label_overall_activity: CelkovÃ¡ aktivita
+  label_user_activity: "Aktivita uÅ¾ivatele: %{value}"
+  label_new: NovÃ½
+  label_logged_as: PÅ™ihlÃ¡Å¡en jako
+  label_environment: ProstÅ™edÃ­
+  label_authentication: Autentifikace
+  label_auth_source: MÃ³d autentifikace
+  label_auth_source_new: NovÃ½ mÃ³d autentifikace
+  label_auth_source_plural: MÃ³dy autentifikace
+  label_subproject_plural: Podprojekty
+  label_subproject_new: NovÃ½ podprojekt
+  label_and_its_subprojects: "%{value} a jeho  podprojekty"
+  label_min_max_length: Min - Max dÃ©lka
+  label_list: Seznam
+  label_date: Datum
+  label_integer: CelÃ© ÄÃ­slo
+  label_float: DesetinnÃ© ÄÃ­slo
+  label_boolean: Ano/Ne
+  label_string: Text
+  label_text: DlouhÃ½ text
+  label_attribute: Atribut
+  label_attribute_plural: Atributy
+  label_no_data: Å½Ã¡dnÃ© poloÅ¾ky
+  label_change_status: ZmÄ›nit stav
+  label_history: Historie
+  label_attachment: Soubor
+  label_attachment_new: NovÃ½ soubor
+  label_attachment_delete: Odstranit soubor
+  label_attachment_plural: Soubory
+  label_file_added: Soubor pÅ™idÃ¡n
+  label_report: PÅ™ehled
+  label_report_plural: PÅ™ehledy
+  label_news: Novinky
+  label_news_new: PÅ™idat novinku
+  label_news_plural: Novinky
+  label_news_latest: PoslednÃ­ novinky
+  label_news_view_all: Zobrazit vÅ¡echny novinky
+  label_news_added: Novinka pÅ™idÃ¡na
+  label_settings: NastavenÃ­
+  label_overview: PÅ™ehled
+  label_version: Verze
+  label_version_new: NovÃ¡ verze
+  label_version_plural: Verze
+  label_close_versions: ZavÅ™Ã­t dokonÄenÃ© verze
+  label_confirmation: PotvrzenÃ­
+  label_export_to: 'TakÃ© k dispozici:'
+  label_read: NaÄÃ­tÃ¡ se...
+  label_public_projects: VeÅ™ejnÃ© projekty
+  label_open_issues: otevÅ™enÃ½
+  label_open_issues_plural: otevÅ™enÃ©
+  label_closed_issues: uzavÅ™enÃ½
+  label_closed_issues_plural: uzavÅ™enÃ©
+  label_x_open_issues_abbr_on_total:
+    zero:  0 otevÅ™enÃ½ch / %{total}
+    one:   1 otevÅ™enÃ½ / %{total}
+    other: "%{count} otevÅ™enÃ½ch / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 otevÅ™enÃ½ch
+    one:   1 otevÅ™enÃ½
+    other: "%{count} otevÅ™enÃ½ch"
+  label_x_closed_issues_abbr:
+    zero:  0 uzavÅ™enÃ½ch
+    one:   1 uzavÅ™enÃ½
+    other: "%{count} uzavÅ™enÃ½ch"
+  label_total: Celkem
+  label_permissions: PrÃ¡va
+  label_current_status: AktuÃ¡lnÃ­ stav
+  label_new_statuses_allowed: NovÃ© povolenÃ© stavy
+  label_all: vÅ¡e
+  label_none: nic
+  label_nobody: nikdo
+  label_next: DalÅ¡Ã­
+  label_previous: PÅ™edchozÃ­
+  label_used_by: PouÅ¾ito
+  label_details: Detaily
+  label_add_note: PÅ™idat poznÃ¡mku
+  label_per_page: Na strÃ¡nku
+  label_calendar: KalendÃ¡Å™
+  label_months_from: mÄ›sÃ­cÅ¯ od
+  label_gantt: GanttÅ¯v diagram
+  label_internal: InternÃ­
+  label_last_changes: "poslednÃ­ch %{count} zmÄ›n"
+  label_change_view_all: Zobrazit vÅ¡echny zmÄ›ny
+  label_personalize_page: PÅ™izpÅ¯sobit tuto strÃ¡nku
+  label_comment: KomentÃ¡Å™
+  label_comment_plural: KomentÃ¡Å™e
+  label_x_comments:
+    zero: Å¾Ã¡dnÃ© komentÃ¡Å™e
+    one: 1 komentÃ¡Å™
+    other: "%{count} komentÃ¡Å™Å¯"
+  label_comment_add: PÅ™idat komentÃ¡Å™e
+  label_comment_added: KomentÃ¡Å™ pÅ™idÃ¡n
+  label_comment_delete: Odstranit komentÃ¡Å™
+  label_query: UÅ¾ivatelskÃ½ dotaz
+  label_query_plural: UÅ¾ivatelskÃ© dotazy
+  label_query_new: NovÃ½ dotaz
+  label_filter_add: PÅ™idat filtr
+  label_filter_plural: Filtry
+  label_equals: je
+  label_not_equals: nenÃ­
+  label_in_less_than: je mÄ›Å¡Ã­ neÅ¾
+  label_in_more_than: je vÄ›tÅ¡Ã­ neÅ¾
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: v
+  label_today: dnes
+  label_all_time: vÅ¡e
+  label_yesterday: vÄera
+  label_this_week: tento tÃ½den
+  label_last_week: minulÃ½ tÃ½den
+  label_last_n_days: "poslednÃ­ch %{count} dnÅ¯"
+  label_this_month: tento mÄ›sÃ­c
+  label_last_month: minulÃ½ mÄ›sÃ­c
+  label_this_year: tento rok
+  label_date_range: ÄŒasovÃ½ rozsah
+  label_less_than_ago: pÅ™ed mÃ©nÄ› jak (dny)
+  label_more_than_ago: pÅ™ed vÃ­ce jak (dny)
+  label_ago: pÅ™ed (dny)
+  label_contains: obsahuje
+  label_not_contains: neobsahuje
+  label_day_plural: dny
+  label_repository: RepozitÃ¡Å™
+  label_repository_plural: RepozitÃ¡Å™e
+  label_browse: ProchÃ¡zet
+  label_branch: VÄ›tev
+  label_tag: Tag
+  label_revision: Revize
+  label_revision_plural: RevizÃ­
+  label_revision_id: "Revize %{value}"
+  label_associated_revisions: SouvisejÃ­cÃ­ verze
+  label_added: pÅ™idÃ¡no
+  label_modified: zmÄ›nÄ›no
+  label_copied: zkopÃ­rovÃ¡no
+  label_renamed: pÅ™ejmenovÃ¡no
+  label_deleted: odstranÄ›no
+  label_latest_revision: PoslednÃ­ revize
+  label_latest_revision_plural: PoslednÃ­ revize
+  label_view_revisions: Zobrazit revize
+  label_view_all_revisions: Zobrazit vÅ¡echny revize
+  label_max_size: MaximÃ¡lnÃ­ velikost
+  label_sort_highest: PÅ™esunout na zaÄÃ¡tek
+  label_sort_higher: PÅ™esunout nahoru
+  label_sort_lower: PÅ™esunout dolÅ¯
+  label_sort_lowest: PÅ™esunout na konec
+  label_roadmap: PlÃ¡n
+  label_roadmap_due_in: "ZbÃ½vÃ¡ %{value}"
+  label_roadmap_overdue: "%{value} pozdÄ›"
+  label_roadmap_no_issues: Pro tuto verzi nejsou Å¾Ã¡dnÃ© Ãºkoly
+  label_search: Hledat
+  label_result_plural: VÃ½sledky
+  label_all_words: VÅ¡echna slova
+  label_wiki: Wiki
+  label_wiki_edit: Wiki Ãºprava
+  label_wiki_edit_plural: Wiki Ãºpravy
+  label_wiki_page: Wiki strÃ¡nka
+  label_wiki_page_plural: Wiki strÃ¡nky
+  label_index_by_title: Index dle nÃ¡zvu
+  label_index_by_date: Index dle data
+  label_current_version: AktuÃ¡lnÃ­ verze
+  label_preview: NÃ¡hled
+  label_feed_plural: PÅ™Ã­spÄ›vky
+  label_changes_details: Detail vÅ¡ech zmÄ›n
+  label_issue_tracking: SledovÃ¡nÃ­ ÃºkolÅ¯
+  label_spent_time: StrÃ¡venÃ½ Äas
+  label_overall_spent_time: Celkem strÃ¡venÃ½ Äas
+  label_f_hour: "%{value} hodina"
+  label_f_hour_plural: "%{value} hodin"
+  label_time_tracking: SledovÃ¡nÃ­ Äasu
+  label_change_plural: ZmÄ›ny
+  label_statistics: Statistiky
+  label_commits_per_month: CommitÅ¯ za mÄ›sÃ­c
+  label_commits_per_author: CommitÅ¯ za autora
+  label_view_diff: Zobrazit rozdÃ­ly
+  label_diff_inline: uvnitÅ™
+  label_diff_side_by_side: vedle sebe
+  label_options: NastavenÃ­
+  label_copy_workflow_from: KopÃ­rovat prÅ¯bÄ›h prÃ¡ce z
+  label_permissions_report: PÅ™ehled prÃ¡v
+  label_watched_issues: SledovanÃ© Ãºkoly
+  label_related_issues: SouvisejÃ­cÃ­ Ãºkoly
+  label_applied_status: PouÅ¾itÃ½ stav
+  label_loading: NahrÃ¡vÃ¡m...
+  label_relation_new: NovÃ¡ souvislost
+  label_relation_delete: Odstranit souvislost
+  label_relates_to: souvisejÃ­cÃ­ s
+  label_duplicates: duplikuje
+  label_duplicated_by: duplikovÃ¡n
+  label_blocks: blokuje
+  label_blocked_by: blokovÃ¡n
+  label_precedes: pÅ™edchÃ¡zÃ­
+  label_follows: nÃ¡sleduje
+  label_end_to_start: od konce do zaÄÃ¡tku
+  label_end_to_end: od konce do konce
+  label_start_to_start: od zaÄÃ¡tku do zaÄÃ¡tku
+  label_start_to_end: od zaÄÃ¡tku do konce
+  label_stay_logged_in: ZÅ¯stat pÅ™ihlÃ¡Å¡enÃ½
+  label_disabled: zakÃ¡zÃ¡n
+  label_show_completed_versions: Zobrazit dokonÄenÃ© verze
+  label_me: jÃ¡
+  label_board: FÃ³rum
+  label_board_new: NovÃ© fÃ³rum
+  label_board_plural: FÃ³ra
+  label_board_locked: ZamÄeno
+  label_board_sticky: NÃ¡lepka
+  label_topic_plural: TÃ©mata
+  label_message_plural: ZprÃ¡vy
+  label_message_last: PoslednÃ­ zprÃ¡va
+  label_message_new: NovÃ¡ zprÃ¡va
+  label_message_posted: ZprÃ¡va pÅ™idÃ¡na
+  label_reply_plural: OdpovÄ›di
+  label_send_information: Zaslat informace o ÃºÄtu uÅ¾ivateli
+  label_year: Rok
+  label_month: MÄ›sÃ­c
+  label_week: TÃ½den
+  label_date_from: Od
+  label_date_to: Do
+  label_language_based: Podle vÃ½chozÃ­ho jazyka
+  label_sort_by: "SeÅ™adit podle %{value}"
+  label_send_test_email: Poslat testovacÃ­ email
+  label_feeds_access_key: PÅ™Ã­stupovÃ½ klÃ­Ä pro RSS
+  label_missing_feeds_access_key: PostrÃ¡dÃ¡ pÅ™Ã­stupovÃ½ klÃ­Ä pro RSS
+  label_feeds_access_key_created_on: "PÅ™Ã­stupovÃ½ klÃ­Ä pro RSS byl vytvoÅ™en pÅ™ed %{value}"
+  label_module_plural: Moduly
+  label_added_time_by: "PÅ™idÃ¡no uÅ¾ivatelem %{author} pÅ™ed %{age}"
+  label_updated_time_by: "AktualizovÃ¡no uÅ¾ivatelem %{author} pÅ™ed %{age}"
+  label_updated_time: "AktualizovÃ¡no pÅ™ed %{value}"
+  label_jump_to_a_project: Vyberte projekt...
+  label_file_plural: Soubory
+  label_changeset_plural: Sady zmÄ›n
+  label_default_columns: VÃ½chozÃ­ sloupce
+  label_no_change_option: (beze zmÄ›ny)
+  label_bulk_edit_selected_issues: HromadnÃ¡ Ãºprava vybranÃ½ch ÃºkolÅ¯
+  label_theme: TÃ©ma
+  label_default: VÃ½chozÃ­
+  label_search_titles_only: VyhledÃ¡vat pouze v nÃ¡zvech
+  label_user_mail_option_all: "Pro vÅ¡echny udÃ¡losti vÅ¡ech mÃ½ch projektÅ¯"
+  label_user_mail_option_selected: "Pro vÅ¡echny udÃ¡losti vybranÃ½ch projektÅ¯..."
+  label_user_mail_option_none: "Å½Ã¡dnÃ© udÃ¡losti"
+  label_user_mail_option_only_my_events: "Jen pro vÄ›ci, co sleduji nebo jsem v nich zapojen"
+  label_user_mail_option_only_assigned: "Jen pro vÄ›ci, ke kterÃ½m sem pÅ™iÅ™azen"
+  label_user_mail_option_only_owner: "Jen pro vÄ›ci, kterÃ© vlastnÃ­m"
+  label_user_mail_no_self_notified: "NezasÃ­lat informace o mnou vytvoÅ™enÃ½ch zmÄ›nÃ¡ch"
+  label_registration_activation_by_email: aktivace ÃºÄtu emailem
+  label_registration_manual_activation: manuÃ¡lnÃ­ aktivace ÃºÄtu
+  label_registration_automatic_activation: automatickÃ¡ aktivace ÃºÄtu
+  label_display_per_page: "%{value} na strÃ¡nku"
+  label_age: VÄ›k
+  label_change_properties: ZmÄ›nit vlastnosti
+  label_general: ObecnÃ©
+  label_more: VÃ­ce
+  label_scm: SCM
+  label_plugins: DoplÅˆky
+  label_ldap_authentication: Autentifikace LDAP
+  label_downloads_abbr: StaÅ¾.
+  label_optional_description: VolitelnÃ½ popis
+  label_add_another_file: PÅ™idat dalÅ¡Ã­ soubor
+  label_preferences: NastavenÃ­
+  label_chronological_order: V chronologickÃ©m poÅ™adÃ­
+  label_reverse_chronological_order: V obrÃ¡canÃ©m chronologickÃ©m poÅ™adÃ­
+  label_planning: PlÃ¡novÃ¡nÃ­
+  label_incoming_emails: PÅ™Ã­chozÃ­ e-maily
+  label_generate_key: Generovat klÃ­Ä
+  label_issue_watchers: SledovÃ¡nÃ­
+  label_example: PÅ™Ã­klad
+  label_display: Zobrazit
+  label_sort: Å˜azenÃ­
+  label_ascending: VzestupnÄ›
+  label_descending: SestupnÄ›
+  label_date_from_to: Od %{start} do %{end}
+  label_wiki_content_added: Wiki strÃ¡nka pÅ™idÃ¡na
+  label_wiki_content_updated: Wiki strÃ¡nka aktualizovÃ¡na
+  label_group: Skupina
+  label_group_plural: Skupiny
+  label_group_new: NovÃ¡ skupina
+  label_time_entry_plural: StrÃ¡venÃ½ Äas
+  label_version_sharing_none: NesdÃ­leno
+  label_version_sharing_descendants: S podprojekty
+  label_version_sharing_hierarchy: S hierarchiÃ­ projektu
+  label_version_sharing_tree: Se stromem projektu
+  label_version_sharing_system: Se vÅ¡emi projekty
+  label_update_issue_done_ratios: Aktualizovat koeficienty dokonÄenÃ­ ÃºkolÅ¯
+  label_copy_source: Zdroj
+  label_copy_target: CÃ­l
+  label_copy_same_as_target: StejnÃ½ jako cÃ­l
+  label_display_used_statuses_only: Zobrazit pouze stavy kterÃ© jsou pouÅ¾itÃ© touto frontou
+  label_api_access_key: API pÅ™Ã­stupovÃ½ klÃ­Ä
+  label_missing_api_access_key: ChybÄ›jÃ­cÃ­ pÅ™Ã­stupovÃ½ klÃ­Ä API
+  label_api_access_key_created_on: API pÅ™Ã­stupovÃ½ klÃ­Ä vytvoÅ™en %{value}
+  label_profile: Profil
+  label_subtask_plural: DÃ­lÄÃ­ Ãºkoly
+  label_project_copy_notifications: Odeslat email oznÃ¡menÃ­ v prÅ¯bÄ›hu kopie projektu
+  label_principal_search: "Hledat uÅ¾ivatele nebo skupinu:"
+  label_user_search: "Hledat uÅ¾ivatele:"
+
+  button_login: PÅ™ihlÃ¡sit
+  button_submit: Potvrdit
+  button_save: UloÅ¾it
+  button_check_all: ZaÅ¡rtnout vÅ¡e
+  button_uncheck_all: OdÅ¡rtnout vÅ¡e
+  button_delete: Odstranit
+  button_create: VytvoÅ™it
+  button_create_and_continue: VytvoÅ™it a pokraÄovat
+  button_test: Testovat
+  button_edit: Upravit
+  button_edit_associated_wikipage: "Upravit pÅ™iÅ™azenou Wiki strÃ¡nku: %{page_title}"
+  button_add: PÅ™idat
+  button_change: ZmÄ›nit
+  button_apply: PouÅ¾Ã­t
+  button_clear: Smazat
+  button_lock: Zamknout
+  button_unlock: Odemknout
+  button_download: StÃ¡hnout
+  button_list: Vypsat
+  button_view: Zobrazit
+  button_move: PÅ™esunout
+  button_move_and_follow: PÅ™esunout a nÃ¡sledovat
+  button_back: ZpÄ›t
+  button_cancel: Storno
+  button_activate: Aktivovat
+  button_sort: SeÅ™adit
+  button_log_time: PÅ™idat Äas
+  button_rollback: ZpÄ›t k tÃ©to verzi
+  button_watch: Sledovat
+  button_unwatch: Nesledovat
+  button_reply: OdpovÄ›dÄ›t
+  button_archive: Archivovat
+  button_unarchive: Dearchivovat
+  button_reset: Resetovat
+  button_rename: PÅ™ejmenovat
+  button_change_password: ZmÄ›nit heslo
+  button_copy: KopÃ­rovat
+  button_copy_and_follow: KopÃ­rovat a nÃ¡sledovat
+  button_annotate: Komentovat
+  button_update: Aktualizovat
+  button_configure: Konfigurovat
+  button_quote: Citovat
+  button_duplicate: Duplikovat
+  button_show: Zobrazit
+
+  status_active: aktivnÃ­
+  status_registered: registrovanÃ½
+  status_locked: zamÄenÃ½
+
+  version_status_open: otevÅ™enÃ½
+  version_status_locked: zamÄenÃ½
+  version_status_closed: zavÅ™enÃ½
+
+  field_active: AktivnÃ­
+
+  text_select_mail_notifications: Vyberte akci, pÅ™i kterÃ© bude zaslÃ¡no upozornÄ›nÃ­ emailem.
+  text_regexp_info: napÅ™. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 znamenÃ¡ bez limitu
+  text_project_destroy_confirmation: Jste si jisti, Å¾e chcete odstranit tento projekt a vÅ¡echna souvisejÃ­cÃ­ data?
+  text_subprojects_destroy_warning: "Jeho podprojek(y): %{value} budou takÃ© smazÃ¡ny."
+  text_workflow_edit: Vyberte roli a frontu k editaci prÅ¯bÄ›hu prÃ¡ce
+  text_are_you_sure: Jste si jisti?
+  text_journal_changed: "%{label} zmÄ›nÄ›n z %{old} na %{new}"
+  text_journal_set_to: "%{label} nastaven na %{value}"
+  text_journal_deleted: "%{label} smazÃ¡n (%{old})"
+  text_journal_added: "%{label} %{value} pÅ™idÃ¡n"
+  text_tip_issue_begin_day: Ãºkol zaÄÃ­nÃ¡ v tento den
+  text_tip_issue_end_day: Ãºkol konÄÃ­ v tento den
+  text_tip_issue_begin_end_day: Ãºkol zaÄÃ­nÃ¡ a konÄÃ­ v tento den
+  text_caracters_maximum: "%{count} znakÅ¯ maximÃ¡lnÄ›."
+  text_caracters_minimum: "MusÃ­ bÃ½t alespoÅˆ %{count} znakÅ¯ dlouhÃ©."
+  text_length_between: "DÃ©lka mezi %{min} a %{max} znaky."
+  text_tracker_no_workflow: Pro tuto frontu nenÃ­ definovÃ¡n Å¾Ã¡dnÃ½ prÅ¯bÄ›h prÃ¡ce
+  text_unallowed_characters: NepovolenÃ© znaky
+  text_comma_separated: Povoleno vÃ­ce hodnot (oddÄ›lÄ›nÃ© ÄÃ¡rkou).
+  text_line_separated: VÃ­ce hodnot povoleno (jeden Å™Ã¡dek pro kaÅ¾dou hodnotu).
+  text_issues_ref_in_commit_messages: OdkazovÃ¡nÃ­ a opravovÃ¡nÃ­ ÃºkolÅ¯ v poznÃ¡mkÃ¡ch commitÅ¯
+  text_issue_added: "Ãškol %{id} byl vytvoÅ™en uÅ¾ivatelem %{author}."
+  text_issue_updated: "Ãškol %{id} byl aktualizovÃ¡n uÅ¾ivatelem %{author}."
+  text_wiki_destroy_confirmation: Opravdu si pÅ™ejete odstranit tuto Wiki a celÃ½ jejÃ­ obsah?
+  text_issue_category_destroy_question: "NÄ›kterÃ© Ãºkoly (%{count}) jsou pÅ™iÅ™azeny k tÃ©to kategorii. Co s nimi chtete udÄ›lat?"
+  text_issue_category_destroy_assignments: ZruÅ¡it pÅ™iÅ™azenÃ­ ke kategorii
+  text_issue_category_reassign_to: PÅ™iÅ™adit Ãºkoly do tÃ©to kategorie
+  text_user_mail_option: "U projektÅ¯, kterÃ© nebyly vybrÃ¡ny, budete dostÃ¡vat oznÃ¡menÃ­ pouze o vaÅ¡ich Äi o sledovanÃ½ch poloÅ¾kÃ¡ch (napÅ™. o poloÅ¾kÃ¡ch jejichÅ¾ jste autor nebo ke kterÃ½m jste pÅ™iÅ™azen(a))."
+  text_no_configuration_data: "Role, fronty, stavy ÃºkolÅ¯ ani prÅ¯bÄ›h prÃ¡ce nebyly zatÃ­m nakonfigurovÃ¡ny.\nVelice doporuÄujeme nahrÃ¡t vÃ½chozÃ­ konfiguraci. Po tÃ© si mÅ¯Å¾ete vÅ¡e upravit"
+  text_load_default_configuration: NahrÃ¡t vÃ½chozÃ­ konfiguraci
+  text_status_changed_by_changeset: "PouÅ¾ito v sadÄ› zmÄ›n %{value}."
+  text_time_logged_by_changeset: AplikovÃ¡no v sadÄ› zmÄ›n %{value}.
+  text_issues_destroy_confirmation: 'Opravdu si pÅ™ejete odstranit vÅ¡echny zvolenÃ© Ãºkoly?'
+  text_select_project_modules: 'AktivnÃ­ moduly v tomto projektu:'
+  text_default_administrator_account_changed: VÃ½chozÃ­ nastavenÃ­ administrÃ¡torskÃ©ho ÃºÄtu zmÄ›nÄ›no
+  text_file_repository_writable: Povolen zÃ¡pis do adresÃ¡Å™e uklÃ¡dÃ¡nÃ­ souborÅ¯
+  text_plugin_assets_writable: MoÅ¾nost zÃ¡pisu do adresÃ¡Å™e plugin assets
+  text_rmagick_available: RMagick k dispozici (volitelnÃ©)
+  text_destroy_time_entries_question: "U ÃºkolÅ¯, kterÃ© chcete odstranit, je evidovÃ¡no %{hours} prÃ¡ce. Co chete udÄ›lat?"
+  text_destroy_time_entries: Odstranit zaznamenanÃ© hodiny.
+  text_assign_time_entries_to_project: PÅ™iÅ™adit zaznamenanÃ© hodiny projektu
+  text_reassign_time_entries: 'PÅ™eÅ™adit zaznamenanÃ© hodiny k tomuto Ãºkolu:'
+  text_user_wrote: "%{value} napsal:"
+  text_enumeration_destroy_question: "NÄ›kolik (%{count}) objektÅ¯ je pÅ™iÅ™azeno k tÃ©to hodnotÄ›."
+  text_enumeration_category_reassign_to: 'PÅ™eÅ™adit je do tÃ©to:'
+  text_email_delivery_not_configured: "DoruÄovÃ¡nÃ­ e-mailÅ¯ nenÃ­ nastaveno a odesÃ­lÃ¡nÃ­ notifikacÃ­ je zakÃ¡zÃ¡no.\nNastavte VÃ¡Å¡ SMTP server v souboru config/configuration.yml a restartujte aplikaci."
+  text_repository_usernames_mapping: "Vybrat nebo upravit mapovÃ¡nÃ­ mezi Redmine uÅ¾ivateli a uÅ¾ivatelskÃ½mi jmÃ©ny nalezenÃ½mi v logu repozitÃ¡Å™e.\nUÅ¾ivatelÃ© se shodnÃ½m Redmine uÅ¾ivatelskÃ½m jmÃ©nem a uÅ¾ivatelskÃ½m jmÃ©nem v repozitÃ¡Å™i jsou mapovÃ¡ni automaticky."
+  text_diff_truncated: '... RozdÃ­lovÃ½ soubor je zkrÃ¡cen, protoÅ¾e jeho dÃ©lka pÅ™esahuje max. limit.'
+  text_custom_field_possible_values_info: 'KaÅ¾dÃ¡ hodnota na novÃ©m Å™Ã¡dku'
+  text_wiki_page_destroy_question: Tato strÃ¡nka mÃ¡ %{descendants} podstrÃ¡nek a potomkÅ¯. Co chcete udÄ›lat?
+  text_wiki_page_nullify_children: Ponechat podstrÃ¡nky jako koÅ™enovÃ© strÃ¡nky
+  text_wiki_page_destroy_children: Smazat podstrÃ¡nky a vÅ¡echny jejich potomky
+  text_wiki_page_reassign_children: PÅ™iÅ™adit podstrÃ¡nky k tomuto rodiÄi
+  text_own_membership_delete_confirmation: "ChystÃ¡te se odebrat si nÄ›kterÃ¡ nebo vÅ¡echna svÃ¡ oprÃ¡vnÄ›nÃ­, potom jiÅ¾ nemusÃ­te bÃ½t schopni upravit tento projekt.\nOpravdu chcete pokraÄovat?"
+  text_zoom_in: PÅ™iblÃ­Å¾it
+  text_zoom_out: OddÃ¡lit
+
+  default_role_manager: ManaÅ¾er
+  default_role_developer: VÃ½vojÃ¡Å™
+  default_role_reporter: ReportÃ©r
+  default_tracker_bug: Chyba
+  default_tracker_feature: PoÅ¾adavek
+  default_tracker_support: Podpora
+  default_issue_status_new: NovÃ½
+  default_issue_status_in_progress: Ve vÃ½voji
+  default_issue_status_resolved: VyÅ™eÅ¡enÃ½
+  default_issue_status_feedback: ÄŒekÃ¡ se
+  default_issue_status_closed: UzavÅ™enÃ½
+  default_issue_status_rejected: OdmÃ­tnutÃ½
+  default_doc_category_user: UÅ¾ivatelskÃ¡ dokumentace
+  default_doc_category_tech: TechnickÃ¡ dokumentace
+  default_priority_low: NÃ­zkÃ¡
+  default_priority_normal: NormÃ¡lnÃ­
+  default_priority_high: VysokÃ¡
+  default_priority_urgent: UrgentnÃ­
+  default_priority_immediate: OkamÅ¾itÃ¡
+  default_activity_design: NÃ¡vhr
+  default_activity_development: VÃ½voj
+
+  enumeration_issue_priorities: Priority ÃºkolÅ¯
+  enumeration_doc_categories: Kategorie dokumentÅ¯
+  enumeration_activities: Aktivity (sledovÃ¡nÃ­ Äasu)
+  enumeration_system_activity: SystÃ©movÃ¡ aktivita
+
+  field_warn_on_leaving_unsaved: Varuj mÄ› pÅ™ed opuÅ¡tÄ›nÃ­m strÃ¡nky s neuloÅ¾enÃ½m textem
+  text_warn_on_leaving_unsaved: AktuÃ¡lnÃ­ strÃ¡nka obsahuje neuloÅ¾enÃ½ text, kterÃ½ bude ztracen, kdyÅ¾ opustÃ­te strÃ¡nku.
+  label_my_queries: Moje vlastnÃ­ dotazy
+  text_journal_changed_no_detail: "%{label} aktualizovÃ¡n"
+  label_news_comment_added: K novince byl pÅ™idÃ¡n komentÃ¡Å™
+  button_expand_all: Rozbal vÅ¡e
+  button_collapse_all: Sbal vÅ¡e
+  label_additional_workflow_transitions_for_assignee: DalÅ¡Ã­ zmÄ›na stavu povolena, jestliÅ¾e je uÅ¾ivatel pÅ™iÅ™azen
+  label_additional_workflow_transitions_for_author: DalÅ¡Ã­ zmÄ›na stavu povolena, jestliÅ¾e je uÅ¾ivatel autorem
+  label_bulk_edit_selected_time_entries: HromadnÃ¡ zmÄ›na zÃ¡znamÅ¯ Äasu
+  text_time_entries_destroy_confirmation: Jste si jistÃ­, Å¾e chcete smazat vybranÃ½ zÃ¡znam(y) Äasu?
+  label_role_anonymous: AnonymnÃ­
+  label_role_non_member: NenÃ­ Älenem
+  label_issue_note_added: PÅ™idÃ¡na poznÃ¡mka
+  label_issue_status_updated: AktualizovÃ¡n stav
+  label_issue_priority_updated: AktualizovÃ¡na priorita
+  label_issues_visibility_own: Ãškol vytvoÅ™en nebo pÅ™iÅ™azen uÅ¾ivatel(i/em)
+  field_issues_visibility: Viditelnost ÃºkolÅ¯
+  label_issues_visibility_all: VÅ¡echny Ãºkoly
+  permission_set_own_issues_private: Nastavit vlastnÃ­ Ãºkoly jako veÅ™ejnÃ© nebo soukromÃ©
+  field_is_private: SoukromÃ½
+  permission_set_issues_private: Nastavit Ãºkoly jako veÅ™ejnÃ© nebo soukromÃ©
+  label_issues_visibility_public: VÅ¡echny Ãºkoly, kterÃ© nejsou soukromÃ©
+  text_issues_destroy_descendants_confirmation: "%{count} dÃ­lÄÃ­(ch) Ãºkol(Å¯) bude rovnÄ›Å¾ smazÃ¡n(o)."
+  field_commit_logs_encoding: KÃ³dovÃ¡nÃ­ zprÃ¡v pÅ™i commitu
+  field_scm_path_encoding: KÃ³dovÃ¡nÃ­ cesty SCM
+  text_scm_path_encoding_note: "VÃ½chozÃ­: UTF-8"
+  field_path_to_repository: Cesta k repositÃ¡Å™i
+  field_root_directory: KoÅ™enovÃ½ adresÃ¡Å™
+  field_cvs_module: Modul
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: LokÃ¡lnÃ­ repositÃ¡Å™ (napÅ™. /hgrepo, c:\hgrepo)
+  text_scm_command: PÅ™Ã­kaz
+  text_scm_command_version: Verze
+  label_git_report_last_commit: Reportovat poslednÃ­ commit pro soubory a adresÃ¡Å™e
+  text_scm_config: MÅ¯Å¾ete si nastavit vaÅ¡e SCM pÅ™Ã­kazy v config/configuration.yml. Restartujte, prosÃ­m, aplikaci po jejich ÃºpravÄ›.
+  text_scm_command_not_available: SCM pÅ™Ã­kaz nenÃ­ k dispozici. Zkontrolujte, prosÃ­m, nastavenÃ­ v panelu Administrace.
+  notice_issue_successful_create: Ãškol %{id} vytvoÅ™en.
+  label_between: mezi
+  setting_issue_group_assignment: Povolit pÅ™iÅ™azenÃ­ Ãºkolu skupinÄ›
+  label_diff: rozdÃ­l
+  text_git_repository_note: RepositÃ¡Å™ je "bare and local" (napÅ™. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: SmÄ›r tÅ™Ã­dÄ›nÃ­
+  description_project_scope: Rozsah vyhledÃ¡vÃ¡nÃ­
+  description_filter: Filtr
+  description_user_mail_notification: NastavenÃ­ emailovÃ½ch notifikacÃ­
+  description_date_from: Zadejte poÄÃ¡teÄnÃ­ datum
+  description_message_content: Obsah zprÃ¡vy
+  description_available_columns: DostupnÃ© sloupce
+  description_date_range_interval: Zvolte rozsah vÃ½bÄ›rem poÄÃ¡teÄnÃ­ho a koncovÃ©ho data
+  description_issue_category_reassign: Zvolte kategorii Ãºkolu
+  description_search: VyhledÃ¡vacÃ­ pole
+  description_notes: PoznÃ¡mky
+  description_date_range_list: Zvolte rozsah ze seznamu
+  description_choose_project: Projekty
+  description_date_to: Zadejte datum
+  description_query_sort_criteria_attribute: TÅ™Ã­dÃ­cÃ­ atribut
+  description_wiki_subpages_reassign: Zvolte novou rodiÄovskou strÃ¡nku
+  description_selected_columns: VybranÃ½ sloupec
+  label_parent_revision: RodiÄ
+  label_child_revision: Potomek
+  error_scm_annotate_big_text_file: Vstup nemÅ¯Å¾e bÃ½t komentovÃ¡n, protoÅ¾e pÅ™ekraÄuje povolenou velikost textovÃ©ho souboru
+  setting_default_issue_start_date_to_creation_date: PouÅ¾ij aktuÃ¡lnÃ­ datum jako poÄÃ¡teÄnÃ­ datum pro novÃ© Ãºkoly
+  button_edit_section: Uprav tuto ÄÃ¡st
+  setting_repositories_encodings: KÃ³dovÃ¡nÃ­ pÅ™Ã­loh a repositÃ¡Å™Å¯
+  description_all_columns: VÅ¡echny sloupce
+  button_export: Export
+  label_export_options: "nastavenÃ­ exportu %{export_format}"
+  error_attachment_too_big: Soubor nemÅ¯Å¾e bÃ½t nahrÃ¡n, protoÅ¾e jeho velikost je vÄ›tÅ¡Ã­ neÅ¾ maximÃ¡lnÃ­ (%{max_size})
+  notice_failed_to_save_time_entries: "Chyba pÅ™i uklÃ¡dÃ¡nÃ­ %{count} Äasov(Ã½ch/Ã©ho) zÃ¡znam(Å¯) z %{total} vybranÃ©ho: %{ids}."
+  label_x_issues:
+    zero:  0 Ãškol
+    one:   1 Ãškol
+    other: "%{count} Ãškoly"
+  label_repository_new: NovÃ½ repositÃ¡Å™
+  field_repository_is_default: HlavnÃ­ repositÃ¡Å™
+  label_copy_attachments: KopÃ­rovat pÅ™Ã­lohy
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: DokonÄenÃ© verze
+  text_project_identifier_info: Jsou povolena pouze malÃ¡ pÃ­smena (a-z), ÄÃ­slice, pomlÄky a podtrÅ¾Ã­tka.<br />Po uloÅ¾enÃ­ jiÅ¾ nelze identifikÃ¡tor mÄ›nit.
+  field_multiple: VÃ­ce hodnot
+  setting_commit_cross_project_ref: Povolit reference a opravy ÃºkolÅ¯ ze vÅ¡ech ostatnÃ­ch projektÅ¯
+  text_issue_conflict_resolution_add_notes: PÅ™idat moje poznÃ¡mky a zahodit ostatnÃ­ zmÄ›ny
+  text_issue_conflict_resolution_overwrite: PÅ™esto pÅ™ijmout moje Ãºpravy (pÅ™edchozÃ­ poznÃ¡mky budou zachovÃ¡ny, ale nÄ›kterÃ© zmÄ›ny mohou bÃ½t pÅ™epsÃ¡ny)
+  notice_issue_update_conflict: BÄ›hem vaÅ¡ich Ãºprav byl Ãºkol aktualizovÃ¡n jinÃ½m uÅ¾ivatelem.
+  text_issue_conflict_resolution_cancel: ZahoÄ vÅ¡echny moje zmÄ›ny a znovu zobraz %{link}
+  permission_manage_related_issues: Spravuj souvisejÃ­cÃ­ Ãºkoly
+  field_auth_source_ldap_filter: LDAP filtr
+  label_search_for_watchers: Hledej sledujÃ­cÃ­ pro pÅ™idÃ¡nÃ­
+  notice_account_deleted: VÃ¡Å¡ ÃºÄet byl trvale smazÃ¡n.
+  setting_unsubscribe: Povolit uÅ¾ivatelÅ¯m smazÃ¡nÃ­ jejich vlastnÃ­ho ÃºÄtu
+  button_delete_my_account: Smazat mÅ¯j ÃºÄet
+  text_account_destroy_confirmation: |-
+    SkuteÄnÄ› chcete pokraÄovat?
+    VÃ¡Å¡ ÃºÄet bude nenÃ¡vratnÄ› smazÃ¡n.
+  error_session_expired: VaÅ¡e sezenÃ­ vyprÅ¡elo. Znovu se pÅ™ihlaste, prosÃ­m.
+  text_session_expiration_settings: "VarovÃ¡nÃ­: zmÄ›nou tohoto nastavenÃ­ mohou vyprÅ¡et aktuÃ¡lnÃ­ sezenÃ­ vÄetnÄ› toho vaÅ¡eho."
+  setting_session_lifetime: MaximÃ¡lnÃ­ Äas sezenÃ­
+  setting_session_timeout: VyprÅ¡enÃ­ sezenÃ­ bez aktivity
+  label_session_expiration: VyprÅ¡enÃ­ sezenÃ­
+  permission_close_project: ZavÅ™Ã­t / OtevÅ™Ã­t projekt
+  label_show_closed_projects: Zobrazit zavÅ™enÃ© projekty
+  button_close: ZavÅ™Ã­t
+  button_reopen: Znovu otevÅ™Ã­t
+  project_status_active: aktivnÃ­
+  project_status_closed: zavÅ™enÃ½
+  project_status_archived: archivovanÃ½
+  text_project_closed: Tento projekt je uzevÅ™enÃ½ a je pouze pro ÄtenÃ­.
+  notice_user_successful_create: UÅ¾ivatel %{id} vytvoÅ™en.
+  field_core_fields: StandardnÃ­ pole
+  field_timeout: VyprÅ¡enÃ­ (v sekundÃ¡ch)
+  setting_thumbnails_enabled: Zobrazit nÃ¡hled pÅ™Ã­lohy
+  setting_thumbnails_size: Velikost nÃ¡hledu (v pixelech)
+  label_status_transitions: ZmÄ›na stavu
+  label_fields_permissions: PrÃ¡va k polÃ­m
+  label_readonly: Pouze pro ÄtenÃ­
+  label_required: VyÅ¾adovÃ¡no
+  text_repository_identifier_info: Jou povoleny pouze malÃ¡ pÃ­smena (a-z), ÄÃ­slice, pomlÄky a podtrÅ¾Ã­tka.<br />Po uloÅ¾enÃ­ jiÅ¾ nelze identifikÃ¡tor zmÄ›nit.
+  field_board_parent: RodiÄovskÃ© fÃ³rum
+  label_attribute_of_project: ProjektovÃ© %{name}
+  label_attribute_of_author: Autorovo %{name}
+  label_attribute_of_assigned_to: "%{name} pÅ™iÅ™azenÃ©(ho)"
+  label_attribute_of_fixed_version: CÃ­lovÃ¡ verze %{name}
+  label_copy_subtasks: KopÃ­rovat dÃ­lÄÃ­ Ãºkoly
+  label_copied_to: zkopÃ­rovÃ¡no do
+  label_copied_from: zkopÃ­rovÃ¡no z
+  label_any_issues_in_project: jakÃ©koli Ãºkoly v projektu
+  label_any_issues_not_in_project: jakÃ©koli Ãºkoly mimo projekt
+  field_private_notes: SoukromÃ© poznÃ¡mky
+  permission_view_private_notes: Zobrazit soukromÃ© poznÃ¡mky
+  permission_set_notes_private: Nastavit poznÃ¡mky jako soukromÃ©
+  label_no_issues_in_project: Å¾Ã¡dnÃ© Ãºkoly v projektu
+  label_any: vÅ¡e
+  label_last_n_weeks: poslednÃ­ %{count} tÃ½dny
+  setting_cross_project_subtasks: Povolit dÃ­lÄÃ­ Ãºkoly napÅ™Ã­Ä projekty
+  label_cross_project_descendants: S podprojekty
+  label_cross_project_tree: Se stromem projektu
+  label_cross_project_hierarchy: S hierarchiÃ­ projektu
+  label_cross_project_system: Se vÅ¡emi projekty
+  button_hide: SkrÃ½t
+  setting_non_working_week_days: Dny pracovnÃ­ho volna/klidu
+  label_in_the_next_days: v pÅ™Ã­stÃ­ch
+  label_in_the_past_days: v minulÃ½ch
+  label_attribute_of_user: "%{name} uÅ¾ivatel(e/ky)"
+  text_turning_multiple_off: JestliÅ¾e zakÃ¡Å¾ete vÃ­ce hodnot, 
+    hodnoty budou smazÃ¡ny za ÃºÄelem rezervace pouze jedinÃ© hodnoty na poloÅ¾ku.    
+  label_attribute_of_issue: "%{name} Ãºkolu"
+  permission_add_documents: PÅ™idat dokument
+  permission_edit_documents: Upravit dokumenty
+  permission_delete_documents: Smazet dokumenty
+  label_gantt_progress_line: VÃ½vojovÃ¡ ÄÃ¡ra
+  setting_jsonp_enabled: Povolit podporu JSONP
+  field_inherit_members: ZdÄ›dit Äleny
+  field_closed_on: UzavÅ™eno
+  setting_default_projects_tracker_ids: VÃ½chozÃ­ fronta pro novÃ© projekty
+  label_total_time: Celkem
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/730e7c9bc9c48dc81b3322907773ad6f6d8d03cc.svn-base
--- a/.svn/pristine/73/730e7c9bc9c48dc81b3322907773ad6f6d8d03cc.svn-base
+++ /dev/null
@@ -1,94 +0,0 @@
---- 
-enumerations_001: 
-  name: Uncategorized
-  id: 1
-  type: DocumentCategory
-  active: true
-enumerations_002: 
-  name: User documentation
-  id: 2
-  type: DocumentCategory
-  active: true
-enumerations_003: 
-  name: Technical documentation
-  id: 3
-  type: DocumentCategory
-  active: true
-enumerations_004: 
-  name: Low
-  id: 4
-  type: IssuePriority
-  active: true
-  position: 1
-enumerations_005: 
-  name: Normal
-  id: 5
-  type: IssuePriority
-  is_default: true
-  active: true
-  position: 2
-enumerations_006: 
-  name: High
-  id: 6
-  type: IssuePriority
-  active: true
-  position: 3
-enumerations_007: 
-  name: Urgent
-  id: 7
-  type: IssuePriority
-  active: true
-  position: 4
-enumerations_008: 
-  name: Immediate
-  id: 8
-  type: IssuePriority
-  active: true
-  position: 5
-enumerations_009: 
-  name: Design
-  id: 9
-  type: TimeEntryActivity
-  position: 1
-  active: true
-enumerations_010: 
-  name: Development
-  id: 10
-  type: TimeEntryActivity
-  position: 2
-  is_default: true
-  active: true
-enumerations_011: 
-  name: QA
-  id: 11
-  type: TimeEntryActivity
-  position: 3
-  active: true
-enumerations_012:
-  name: Default Enumeration
-  id: 12
-  type: Enumeration
-  is_default: true
-  active: true
-enumerations_013:
-  name: Another Enumeration
-  id: 13
-  type: Enumeration
-  active: true
-enumerations_014: 
-  name: Inactive Activity
-  id: 14
-  type: TimeEntryActivity
-  position: 4
-  active: false
-enumerations_015:
-  name: Inactive Priority
-  id: 15
-  type: IssuePriority
-  position: 6
-  active: false
-enumerations_016:
-  name: Inactive Document Category
-  id: 16
-  type: DocumentCategory
-  active: false
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/7312a1538a08cc5ceaf5579a66a48a6614d8eeab.svn-base
--- a/.svn/pristine/73/7312a1538a08cc5ceaf5579a66a48a6614d8eeab.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class TimeEntryActivityCustomField < CustomField
-  def type_name
-    :enumeration_activities
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/73173a3d1c043da06788c9ebc548d80e9e88eac5.svn-base
--- /dev/null
+++ b/.svn/pristine/73/73173a3d1c043da06788c9ebc548d80e9e88eac5.svn-base
@@ -0,0 +1,14 @@
+class AddCommentsPermissions < ActiveRecord::Migration
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    Permission.create :controller => "news", :action => "add_comment", :description => "label_comment_add", :sort => 1130, :is_public => false, :mail_option => 0, :mail_enabled => 0
+    Permission.create :controller => "news", :action => "destroy_comment", :description => "label_comment_delete", :sort => 1133, :is_public => false, :mail_option => 0, :mail_enabled => 0
+  end
+
+  def self.down
+    Permission.where("controller=? and action=?", 'news', 'add_comment').first.destroy
+    Permission.where("controller=? and action=?", 'news', 'destroy_comment').first.destroy
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/73179d2fe09358707afe7a7d33051ef88d9c1267.svn-base
--- /dev/null
+++ b/.svn/pristine/73/73179d2fe09358707afe7a7d33051ef88d9c1267.svn-base
@@ -0,0 +1,34 @@
+<table class="query-columns">
+  <tr>
+    <td style="padding-left:0">
+      <%= label_tag "available_columns", l(:description_available_columns) %>
+      <br />
+      <%= select_tag 'available_columns',
+              options_for_select(query_available_inline_columns_options(query)),
+              :multiple => true, :size => 10, :style => "width:150px",
+              :ondblclick => "moveOptions(this.form.available_columns, this.form.selected_columns);" %>
+    </td>
+    <td class="buttons">
+      <input type="button" value="&#8594;"
+       onclick="moveOptions(this.form.available_columns, this.form.selected_columns);" /><br />
+      <input type="button" value="&#8592;"
+       onclick="moveOptions(this.form.selected_columns, this.form.available_columns);" />
+    </td>
+    <td>
+      <%= label_tag "selected_columns", l(:description_selected_columns) %>
+      <br />
+      <%= select_tag tag_name,
+              options_for_select(query_selected_inline_columns_options(query)),
+              :id => 'selected_columns', :multiple => true, :size => 10, :style => "width:150px",
+              :ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);" %>
+    </td>
+    <td class="buttons">
+      <input type="button" value="&#8593;" onclick="moveOptionUp(this.form.selected_columns);" /><br />
+      <input type="button" value="&#8595;" onclick="moveOptionDown(this.form.selected_columns);" />
+    </td>
+  </tr>
+</table>
+
+<% content_for :header_tags do %>
+<%= javascript_include_tag 'select_list_move' %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/7324bdf575eb0516e737af169c50f43705081a91.svn-base
--- /dev/null
+++ b/.svn/pristine/73/7324bdf575eb0516e737af169c50f43705081a91.svn-base
@@ -0,0 +1,170 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssueRelationTest < ActiveSupport::TestCase
+  fixtures :projects,
+           :users,
+           :roles,
+           :members,
+           :member_roles,
+           :issues,
+           :issue_statuses,
+           :issue_relations,
+           :enabled_modules,
+           :enumerations,
+           :trackers
+
+  include Redmine::I18n
+
+  def test_create
+    from = Issue.find(1)
+    to = Issue.find(2)
+
+    relation = IssueRelation.new :issue_from => from, :issue_to => to,
+                                 :relation_type => IssueRelation::TYPE_PRECEDES
+    assert relation.save
+    relation.reload
+    assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type
+    assert_equal from, relation.issue_from
+    assert_equal to, relation.issue_to
+  end
+
+  def test_create_minimum
+    relation = IssueRelation.new :issue_from => Issue.find(1), :issue_to => Issue.find(2)
+    assert relation.save
+    assert_equal IssueRelation::TYPE_RELATES, relation.relation_type
+  end
+
+  def test_follows_relation_should_be_reversed
+    from = Issue.find(1)
+    to = Issue.find(2)
+
+    relation = IssueRelation.new :issue_from => from, :issue_to => to,
+                                 :relation_type => IssueRelation::TYPE_FOLLOWS
+    assert relation.save
+    relation.reload
+    assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type
+    assert_equal to, relation.issue_from
+    assert_equal from, relation.issue_to
+  end
+
+  def test_follows_relation_should_not_be_reversed_if_validation_fails
+    from = Issue.find(1)
+    to = Issue.find(2)
+
+    relation = IssueRelation.new :issue_from => from, :issue_to => to,
+                                 :relation_type => IssueRelation::TYPE_FOLLOWS,
+                                 :delay => 'xx'
+    assert !relation.save
+    assert_equal IssueRelation::TYPE_FOLLOWS, relation.relation_type
+    assert_equal from, relation.issue_from
+    assert_equal to, relation.issue_to
+  end
+
+  def test_relation_type_for
+    from = Issue.find(1)
+    to = Issue.find(2)
+
+    relation = IssueRelation.new :issue_from => from, :issue_to => to,
+                                 :relation_type => IssueRelation::TYPE_PRECEDES
+    assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type_for(from)
+    assert_equal IssueRelation::TYPE_FOLLOWS, relation.relation_type_for(to)
+  end
+
+  def test_set_issue_to_dates_without_issue_to
+    r = IssueRelation.new(:issue_from => Issue.new(:start_date => Date.today),
+                          :relation_type => IssueRelation::TYPE_PRECEDES,
+                          :delay => 1)
+    assert_nil r.set_issue_to_dates
+  end
+
+  def test_set_issue_to_dates_without_issues
+    r = IssueRelation.new(:relation_type => IssueRelation::TYPE_PRECEDES, :delay => 1)
+    assert_nil r.set_issue_to_dates
+  end
+
+  def test_validates_circular_dependency
+    IssueRelation.delete_all
+    assert IssueRelation.create!(
+             :issue_from => Issue.find(1), :issue_to => Issue.find(2),
+             :relation_type => IssueRelation::TYPE_PRECEDES
+           )
+    assert IssueRelation.create!(
+             :issue_from => Issue.find(2), :issue_to => Issue.find(3),
+             :relation_type => IssueRelation::TYPE_PRECEDES
+           )
+    r = IssueRelation.new(
+          :issue_from => Issue.find(3), :issue_to => Issue.find(1),
+          :relation_type => IssueRelation::TYPE_PRECEDES
+        )
+    assert !r.save
+    assert_not_nil r.errors[:base]
+  end
+
+  def test_validates_circular_dependency_of_subtask
+    set_language_if_valid 'en'
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+    IssueRelation.create!(
+      :issue_from => issue1, :issue_to => issue2,
+      :relation_type => IssueRelation::TYPE_PRECEDES
+    )
+    child = Issue.generate!(:parent_issue_id => issue2.id)
+    issue1.reload
+    child.reload
+
+    r = IssueRelation.new(
+          :issue_from => child, :issue_to => issue1,
+          :relation_type => IssueRelation::TYPE_PRECEDES
+        )
+    assert !r.save
+    assert_include 'This relation would create a circular dependency', r.errors.full_messages
+  end
+
+  def test_subtasks_should_allow_precedes_relation
+    parent = Issue.generate!
+    child1 = Issue.generate!(:parent_issue_id => parent.id)
+    child2 = Issue.generate!(:parent_issue_id => parent.id)
+
+    r = IssueRelation.new(
+          :issue_from => child1, :issue_to => child2,
+          :relation_type => IssueRelation::TYPE_PRECEDES
+        )
+    assert r.valid?
+    assert r.save
+  end
+
+  def test_validates_circular_dependency_on_reverse_relations
+    IssueRelation.delete_all
+    assert IssueRelation.create!(
+             :issue_from => Issue.find(1), :issue_to => Issue.find(3),
+             :relation_type => IssueRelation::TYPE_BLOCKS
+           )
+    assert IssueRelation.create!(
+             :issue_from => Issue.find(1), :issue_to => Issue.find(2),
+             :relation_type => IssueRelation::TYPE_BLOCKED
+           )
+    r = IssueRelation.new(
+          :issue_from => Issue.find(2), :issue_to => Issue.find(1),
+          :relation_type => IssueRelation::TYPE_BLOCKED
+        )
+    assert !r.save
+    assert_not_nil r.errors[:base]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/733b596d53c40ed4baf1da5919b8ef878d966efe.svn-base
--- a/.svn/pristine/73/733b596d53c40ed4baf1da5919b8ef878d966efe.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-<%= wiki_page_breadcrumb(@page) %>
-
-<h2><%= h(@page.pretty_title) %></h2>
-
-<h3><%= l(:label_history) %></h3>
-
-<% form_tag({:action => "diff"}, :method => :get) do %>
-<table class="list wiki-page-versions">
-<thead><tr>
-    <th>#</th>
-    <th></th>
-    <th></th>
-    <th><%= l(:field_updated_on) %></th>
-    <th><%= l(:field_author) %></th>
-    <th><%= l(:field_comments) %></th>
-    <th></th>
-</tr></thead>
-<tbody>
-<% show_diff = @versions.size > 1 %>
-<% line_num = 1 %>
-<% @versions.each do |ver| %>
-<tr class="wiki-page-version <%= cycle("odd", "even") %>">
-    <td class="id"><%= link_to h(ver.version), :action => 'show', :id => @page.title, :project_id => @page.project, :version => ver.version %></td>
-    <td class="checkbox"><%= radio_button_tag('version', ver.version, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < @versions.size) %></td>
-    <td class="checkbox"><%= radio_button_tag('version_from', ver.version, (line_num==2), :id => "cbto-#{line_num}") if show_diff && (line_num > 1) %></td>
-    <td class="updated_on"><%= format_time(ver.updated_on) %></td>
-    <td class="author"><%= link_to_user ver.author %></td>
-    <td class="comments"><%=h ver.comments %></td>
-    <td class="buttons"><%= link_to l(:button_annotate), :action => 'annotate', :id => @page.title, :version => ver.version %></td>
-</tr>
-<% line_num += 1 %>
-<% end %>
-</tbody>
-</table>
-<%= submit_tag l(:label_view_diff), :class => 'small' if show_diff %>
-<span class="pagination"><%= pagination_links_full @version_pages, @version_count, :page_param => :p %></span>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/734682732665154f00709d93da629e994804ff9b.svn-base
--- a/.svn/pristine/73/734682732665154f00709d93da629e994804ff9b.svn-base
+++ /dev/null
@@ -1,10 +0,0 @@
-require 'redmine'
-
-Redmine::Plugin.register :<%= plugin_name %> do
-  name '<%= plugin_pretty_name %> plugin'
-  author 'Author name'
-  description 'This is a plugin for Redmine'
-  version '0.0.1'
-  url 'http://example.com/path/to/plugin'
-  author_url 'http://example.com/about'
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/734f23aed8fb2921f077702e98029d9edca35572.svn-base
--- a/.svn/pristine/73/734f23aed8fb2921f077702e98029d9edca35572.svn-base
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/usr/bin/env ruby
-
-# == Synopsis
-#
-# Reads an email from standard input and forward it to a Redmine server
-# through a HTTP request.
-#
-# == Usage
-#
-#    rdm-mailhandler [options] --url=<Redmine URL> --key=<API key>
-#
-# == Arguments
-# 
-#   -u, --url                      URL of the Redmine server
-#   -k, --key                      Redmine API key
-#   
-# General options:
-#       --unknown-user=ACTION      how to handle emails from an unknown user
-#                                  ACTION can be one of the following values:
-#                                  ignore: email is ignored (default)
-#                                  accept: accept as anonymous user
-#                                  create: create a user account
-#       --no-permission-check      disable permission checking when receiving
-#                                  the email
-#       --key-file=PATH            path to a file that contains the Redmine
-#                                  API key (use this option instead of --key
-#                                  if you don't the key to appear in the
-#                                  command line)
-#       --no-check-certificate     do not check server certificate
-#   -h, --help                     show this help
-#   -v, --verbose                  show extra information
-#   -V, --version                  show version information and exit
-# 
-# Issue attributes control options:
-#   -p, --project=PROJECT          identifier of the target project
-#   -s, --status=STATUS            name of the target status
-#   -t, --tracker=TRACKER          name of the target tracker
-#       --category=CATEGORY        name of the target category
-#       --priority=PRIORITY        name of the target priority
-#   -o, --allow-override=ATTRS     allow email content to override attributes
-#                                  specified by previous options
-#                                  ATTRS is a comma separated list of attributes
-#       
-# == Examples
-# No project specified. Emails MUST contain the 'Project' keyword:
-# 
-#   rdm-mailhandler --url http://redmine.domain.foo --key secret
-#   
-# Fixed project and default tracker specified, but emails can override
-# both tracker and priority attributes using keywords:
-# 
-#   rdm-mailhandler --url https://domain.foo/redmine --key secret \\
-#                   --project foo \\
-#                   --tracker bug \\
-#                   --allow-override tracker,priority
-
-require 'net/http'
-require 'net/https'
-require 'uri'
-require 'getoptlong'
-require 'rdoc/usage'
-
-module Net
-  class HTTPS < HTTP
-    def self.post_form(url, params, headers, options={})
-      request = Post.new(url.path)
-      request.form_data = params
-      request.basic_auth url.user, url.password if url.user
-      request.initialize_http_header(headers)
-      http = new(url.host, url.port)
-      http.use_ssl = (url.scheme == 'https')
-      if options[:no_check_certificate]
-        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
-      end
-      http.start {|h| h.request(request) }
-    end
-  end
-end
-
-class RedmineMailHandler
-  VERSION = '0.1'
-  
-  attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :no_permission_check, :url, :key, :no_check_certificate
-
-  def initialize
-    self.issue_attributes = {}
-    
-    opts = GetoptLong.new(
-      [ '--help',           '-h', GetoptLong::NO_ARGUMENT ],
-      [ '--version',        '-V', GetoptLong::NO_ARGUMENT ],
-      [ '--verbose',        '-v', GetoptLong::NO_ARGUMENT ],
-      [ '--url',            '-u', GetoptLong::REQUIRED_ARGUMENT ],
-      [ '--key',            '-k', GetoptLong::REQUIRED_ARGUMENT],
-      [ '--key-file',             GetoptLong::REQUIRED_ARGUMENT],
-      [ '--project',        '-p', GetoptLong::REQUIRED_ARGUMENT ],
-      [ '--status',         '-s', GetoptLong::REQUIRED_ARGUMENT ],
-      [ '--tracker',        '-t', GetoptLong::REQUIRED_ARGUMENT],
-      [ '--category',             GetoptLong::REQUIRED_ARGUMENT],
-      [ '--priority',             GetoptLong::REQUIRED_ARGUMENT],
-      [ '--allow-override', '-o', GetoptLong::REQUIRED_ARGUMENT],
-      [ '--unknown-user',         GetoptLong::REQUIRED_ARGUMENT],
-      [ '--no-permission-check',  GetoptLong::NO_ARGUMENT],
-      [ '--no-check-certificate', GetoptLong::NO_ARGUMENT]
-    )
-
-    opts.each do |opt, arg|
-      case opt
-      when '--url'
-        self.url = arg.dup
-      when '--key'
-        self.key = arg.dup
-      when '--key-file'
-        begin
-          self.key = File.read(arg).strip
-        rescue Exception => e
-          $stderr.puts "Unable to read the key from #{arg}: #{e.message}"
-          exit 1
-        end
-      when '--help'
-        usage
-      when '--verbose'
-        self.verbose = true
-      when '--version'
-        puts VERSION; exit
-      when '--project', '--status', '--tracker', '--category', '--priority'
-        self.issue_attributes[opt.gsub(%r{^\-\-}, '')] = arg.dup
-      when '--allow-override'
-        self.allow_override = arg.dup
-      when '--unknown-user'
-        self.unknown_user = arg.dup
-      when '--no-permission-check'
-        self.no_permission_check = '1'
-      when '--no-check-certificate'
-        self.no_check_certificate = true
-      end
-    end
-    
-    RDoc.usage if url.nil?
-  end
-  
-  def submit(email)
-    uri = url.gsub(%r{/*$}, '') + '/mail_handler'
-    
-    headers = { 'User-Agent' => "Redmine mail handler/#{VERSION}" }
-    
-    data = { 'key' => key, 'email' => email, 
-                           'allow_override' => allow_override,
-                           'unknown_user' => unknown_user,
-                           'no_permission_check' => no_permission_check}
-    issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
-             
-    debug "Posting to #{uri}..."
-    response = Net::HTTPS.post_form(URI.parse(uri), data, headers, :no_check_certificate => no_check_certificate)
-    debug "Response received: #{response.code}"
-    
-    case response.code.to_i
-      when 403
-        warn "Request was denied by your Redmine server. " + 
-             "Make sure that 'WS for incoming emails' is enabled in application settings and that you provided the correct API key."
-        return 77
-      when 422
-        warn "Request was denied by your Redmine server. " +
-             "Possible reasons: email is sent from an invalid email address or is missing some information."
-        return 77
-      when 400..499
-        warn "Request was denied by your Redmine server (#{response.code})."
-        return 77
-      when 500..599
-        warn "Failed to contact your Redmine server (#{response.code})."
-        return 75
-      when 201
-        debug "Proccessed successfully"
-        return 0
-      else
-        return 1
-    end
-  end
-  
-  private
-  
-  def debug(msg)
-    puts msg if verbose
-  end
-end
-
-handler = RedmineMailHandler.new
-exit(handler.submit(STDIN.read))
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/736844820e97591097b5dc584954a779de2b5787.svn-base
--- a/.svn/pristine/73/736844820e97591097b5dc584954a779de2b5787.svn-base
+++ /dev/null
@@ -1,283 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class AccountController < ApplicationController
-  helper :custom_fields
-  include CustomFieldsHelper
-
-  # prevents login action to be filtered by check_if_login_required application scope filter
-  skip_before_filter :check_if_login_required
-
-  # Login request and validation
-  def login
-    if request.get?
-      logout_user
-    else
-      authenticate_user
-    end
-  end
-
-  # Log out current user and redirect to welcome page
-  def logout
-    logout_user
-    redirect_to home_url
-  end
-
-  # Enable user to choose a new password
-  def lost_password
-    redirect_to(home_url) && return unless Setting.lost_password?
-    if params[:token]
-      @token = Token.find_by_action_and_value("recovery", params[:token])
-      redirect_to(home_url) && return unless @token and !@token.expired?
-      @user = @token.user
-      if request.post?
-        @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
-        if @user.save
-          @token.destroy
-          flash[:notice] = l(:notice_account_password_updated)
-          redirect_to :action => 'login'
-          return
-        end
-      end
-      render :template => "account/password_recovery"
-      return
-    else
-      if request.post?
-        user = User.find_by_mail(params[:mail])
-        # user not found in db
-        (flash.now[:error] = l(:notice_account_unknown_email); return) unless user
-        # user uses an external authentification
-        (flash.now[:error] = l(:notice_can_t_change_password); return) if user.auth_source_id
-        # create a new token for password recovery
-        token = Token.new(:user => user, :action => "recovery")
-        if token.save
-          Mailer.deliver_lost_password(token)
-          flash[:notice] = l(:notice_account_lost_email_sent)
-          redirect_to :action => 'login'
-          return
-        end
-      end
-    end
-  end
-
-  # User self-registration
-  def register
-    redirect_to(home_url) && return unless Setting.self_registration? || session[:auth_source_registration]
-    if request.get?
-      session[:auth_source_registration] = nil
-      @user = User.new(:language => Setting.default_language)
-    else
-      @user = User.new(params[:user])
-      @user.admin = false
-      @user.register
-      if session[:auth_source_registration]
-        @user.activate
-        @user.login = session[:auth_source_registration][:login]
-        @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
-        if @user.save
-          session[:auth_source_registration] = nil
-          self.logged_user = @user
-          flash[:notice] = l(:notice_account_activated)
-          redirect_to :controller => 'my', :action => 'account'
-        end
-      else
-        @user.login = params[:user][:login]
-        @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
-
-        case Setting.self_registration
-        when '1'
-          register_by_email_activation(@user)
-        when '3'
-          register_automatically(@user)
-        else
-          register_manually_by_administrator(@user)
-        end
-      end
-    end
-  end
-
-  # Token based account activation
-  def activate
-    redirect_to(home_url) && return unless Setting.self_registration? && params[:token]
-    token = Token.find_by_action_and_value('register', params[:token])
-    redirect_to(home_url) && return unless token and !token.expired?
-    user = token.user
-    redirect_to(home_url) && return unless user.registered?
-    user.activate
-    if user.save
-      token.destroy
-      flash[:notice] = l(:notice_account_activated)
-    end
-    redirect_to :action => 'login'
-  end
-
-  private
-
-  def logout_user
-    if User.current.logged?
-      cookies.delete :autologin
-      Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
-      self.logged_user = nil
-    end
-  end
-
-  def authenticate_user
-    if Setting.openid? && using_open_id?
-      open_id_authenticate(params[:openid_url])
-    else
-      password_authentication
-    end
-  end
-
-  def password_authentication
-    user = User.try_to_login(params[:username], params[:password])
-
-    if user.nil?
-      invalid_credentials
-    elsif user.new_record?
-      onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
-    else
-      # Valid user
-      successful_authentication(user)
-    end
-  end
-
-  def open_id_authenticate(openid_url)
-    authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => signin_url) do |result, identity_url, registration|
-      if result.successful?
-        user = User.find_or_initialize_by_identity_url(identity_url)
-        if user.new_record?
-          # Self-registration off
-          redirect_to(home_url) && return unless Setting.self_registration?
-
-          # Create on the fly
-          user.login = registration['nickname'] unless registration['nickname'].nil?
-          user.mail = registration['email'] unless registration['email'].nil?
-          user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
-          user.random_password
-          user.register
-
-          case Setting.self_registration
-          when '1'
-            register_by_email_activation(user) do
-              onthefly_creation_failed(user)
-            end
-          when '3'
-            register_automatically(user) do
-              onthefly_creation_failed(user)
-            end
-          else
-            register_manually_by_administrator(user) do
-              onthefly_creation_failed(user)
-            end
-          end
-        else
-          # Existing record
-          if user.active?
-            successful_authentication(user)
-          else
-            account_pending
-          end
-        end
-      end
-    end
-  end
-
-  def successful_authentication(user)
-    # Valid user
-    self.logged_user = user
-    # generate a key and set cookie if autologin
-    if params[:autologin] && Setting.autologin?
-      set_autologin_cookie(user)
-    end
-    call_hook(:controller_account_success_authentication_after, {:user => user })
-    redirect_back_or_default :controller => 'my', :action => 'page'
-  end
-
-  def set_autologin_cookie(user)
-    token = Token.create(:user => user, :action => 'autologin')
-    cookie_name = Redmine::Configuration['autologin_cookie_name'] || 'autologin'
-    cookie_options = {
-      :value => token.value,
-      :expires => 1.year.from_now,
-      :path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
-      :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
-      :httponly => true
-    }
-    cookies[cookie_name] = cookie_options
-  end
-
-  # Onthefly creation failed, display the registration form to fill/fix attributes
-  def onthefly_creation_failed(user, auth_source_options = { })
-    @user = user
-    session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
-    render :action => 'register'
-  end
-
-  def invalid_credentials
-    logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
-    flash.now[:error] = l(:notice_account_invalid_creditentials)
-  end
-
-  # Register a user for email activation.
-  #
-  # Pass a block for behavior when a user fails to save
-  def register_by_email_activation(user, &block)
-    token = Token.new(:user => user, :action => "register")
-    if user.save and token.save
-      Mailer.deliver_register(token)
-      flash[:notice] = l(:notice_account_register_done)
-      redirect_to :action => 'login'
-    else
-      yield if block_given?
-    end
-  end
-
-  # Automatically register a user
-  #
-  # Pass a block for behavior when a user fails to save
-  def register_automatically(user, &block)
-    # Automatic activation
-    user.activate
-    user.last_login_on = Time.now
-    if user.save
-      self.logged_user = user
-      flash[:notice] = l(:notice_account_activated)
-      redirect_to :controller => 'my', :action => 'account'
-    else
-      yield if block_given?
-    end
-  end
-
-  # Manual activation by the administrator
-  #
-  # Pass a block for behavior when a user fails to save
-  def register_manually_by_administrator(user, &block)
-    if user.save
-      # Sends an email to the administrators
-      Mailer.deliver_account_activation_request(user)
-      account_pending
-    else
-      yield if block_given?
-    end
-  end
-
-  def account_pending
-    flash[:notice] = l(:notice_account_pending)
-    redirect_to :action => 'login'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/73/73f54ba2c494fc625d52c6218a1293d90db7ca39.svn-base
--- a/.svn/pristine/73/73f54ba2c494fc625d52c6218a1293d90db7ca39.svn-base
+++ /dev/null
@@ -1,46 +0,0 @@
-require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
-require 'rake/gempackagetask'
-require 'rcov/rcovtask'
-require "load_multi_rails_rake_tasks" 
-
-spec = eval(File.read("#{File.dirname(__FILE__)}/awesome_nested_set.gemspec"))
-PKG_NAME = spec.name
-PKG_VERSION = spec.version
- 
-Rake::GemPackageTask.new(spec) do |pkg|
-  pkg.need_zip = true
-  pkg.need_tar = true
-end
-
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the awesome_nested_set plugin.'
-Rake::TestTask.new(:test) do |t|
-  t.libs << 'lib'
-  t.pattern = 'test/**/*_test.rb'
-  t.verbose = true
-end
-
-desc 'Generate documentation for the awesome_nested_set plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
-  rdoc.rdoc_dir = 'rdoc'
-  rdoc.title    = 'AwesomeNestedSet'
-  rdoc.options << '--line-numbers' << '--inline-source'
-  rdoc.rdoc_files.include('README.rdoc')
-  rdoc.rdoc_files.include('lib/**/*.rb')
-end
-
-namespace :test do
-  desc "just rcov minus html output"
-  Rcov::RcovTask.new(:coverage) do |t|
-    # t.libs << 'test'
-    t.test_files = FileList['test/**/*_test.rb']
-    t.output_dir = 'coverage'
-    t.verbose = true
-    t.rcov_opts = %w(--exclude test,/usr/lib/ruby,/Library/Ruby,lib/awesome_nested_set/named_scope.rb --sort coverage)
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/7404304328de19a679b0fab3d9a0a81e75864fb9.svn-base
--- a/.svn/pristine/74/7404304328de19a679b0fab3d9a0a81e75864fb9.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-<p class="icon icon-example-works"><%= l(:text_say_hello) %></p>
-
-<p><label>Example setting</label>: <%= @value %></p>
-
-<%= link_to_if_authorized 'Good bye', :action => 'say_goodbye', :id => @project %>
-
-<% content_for :header_tags do %>
-  <%= stylesheet_link_tag "example.css", :plugin => "sample_plugin", :media => "screen" %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/741eb5d407aff37a5362c7877d98828f37bf017e.svn-base
--- /dev/null
+++ b/.svn/pristine/74/741eb5d407aff37a5362c7877d98828f37bf017e.svn-base
@@ -0,0 +1,1090 @@
+hr:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%m/%d/%Y"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [Ponedjeljak, Utorak, Srijeda, ÄŒetvrtak, Petak, Subota, Nedjelja]
+    abbr_day_names: [Ned, Pon, Uto, Sri, ÄŒet, Pet, Sub]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Sijecanj, Veljaca, OÅ¾ujak, Travanj, Svibanj, Lipanj, Srpanj, Kolovoz, Rujan, Listopad, Studeni, Prosinac]
+    abbr_month_names: [~, Sij, Velj, OÅ¾u, Tra, Svi, Lip, Srp, Kol, Ruj, List, Stu, Pro]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%m/%d/%Y %I:%M %p"
+      time: "%I:%M %p"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pola minute"
+      less_than_x_seconds:
+        one:   "manje od sekunde"
+        other: "manje od %{count} sekundi"
+      x_seconds:
+        one:   "1 sekunda"
+        other: "%{count} sekundi"
+      less_than_x_minutes:
+        one:   "manje od minute"
+        other: "manje od %{count} minuta"
+      x_minutes:
+        one:   "1 minuta"
+        other: "%{count} minuta"
+      about_x_hours:
+        one:   "oko sat vremena"
+        other: "oko %{count} sati"
+      x_hours:
+        one:   "1 sata"
+        other: "%{count} sati"
+      x_days:
+        one:   "1 dan"
+        other: "%{count} dana"
+      about_x_months:
+        one:   "oko 1 mjesec"
+        other: "oko %{count} mjeseci"
+      x_months:
+        one:   "mjesec"
+        other: "%{count} mjeseci"
+      about_x_years:
+        one:   "1 godina"
+        other: "%{count} godina"
+      over_x_years:
+        one:   "preko 1 godine"
+        other: "preko %{count} godina"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "i"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "nije ukljuceno u listu"
+        exclusion: "je rezervirano"
+        invalid: "nije ispravno"
+        confirmation: "ne odgovara za potvrdu"
+        accepted: "mora biti prihvaÄ‡en"
+        empty: "ne moÅ¾e biti prazno"
+        blank: "ne moÅ¾e biti razmaka"
+        too_long: "je predug (maximum is %{count} characters)"
+        too_short: "je prekratak (minimum is %{count} characters)"
+        wrong_length: "je pogreÅ¡ne duÅ¾ine (should be %{count} characters)"
+        taken: "veÄ‡ je zauzeto"
+        not_a_number: "nije broj"
+        not_a_date: "nije ispravan datum"
+        greater_than: "mora biti veÄ‡i od %{count}"
+        greater_than_or_equal_to: "mora biti veÄ‡i ili jednak %{count}"
+        equal_to: "mora biti jednak %{count}"
+        less_than: "mora biti manji od %{count}"
+        less_than_or_equal_to: "mora bit manji ili jednak%{count}"
+        odd: "mora biti neparan"
+        even: "mora biti paran"
+        greater_than_start_date: "mora biti veci nego pocetni datum"
+        not_same_project: "ne pripada istom projektu"
+        circular_dependency: "Ovaj relacija stvara kruÅ¾nu ovisnost"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: Molimo odaberite
+
+  general_text_No: 'Ne'
+  general_text_Yes: 'Da'
+  general_text_no: 'ne'
+  general_text_yes: 'da'
+  general_lang_name: 'Hrvatski'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_updated: VaÅ¡ profil je uspjeÅ¡no promijenjen.
+  notice_account_invalid_creditentials: Neispravno korisniÄko ime ili zaporka.
+  notice_account_password_updated: Zaporka je uspjeÅ¡no promijenjena.
+  notice_account_wrong_password: PogreÅ¡na zaporka
+  notice_account_register_done: Racun je uspjeÅ¡no napravljen. Da biste aktivirali svoj raÄun, kliknite na link koji vam je poslan na e-mail.
+  notice_account_unknown_email: Nepoznati korisnik.
+  notice_can_t_change_password: Ovaj raÄun koristi eksterni izvor prijavljivanja. NemoguÄ‡e je promijeniti zaporku.
+  notice_account_lost_email_sent: E-mail s uputama kako bi odabrali novu zaporku je poslan na na vaÅ¡u e-mail adresu.
+  notice_account_activated: VaÅ¡ racun je aktiviran. MoÅ¾ete se prijaviti.
+  notice_successful_create: UspjeÅ¡no napravljeno.
+  notice_successful_update: UspjeÅ¡na promjena.
+  notice_successful_delete: UspjeÅ¡no brisanje.
+  notice_successful_connection: UspjeÅ¡na veza.
+  notice_file_not_found: Stranica kojoj ste pokuÅ¡ali pristupiti ne postoji ili je uklonjena.
+  notice_locking_conflict: Podataci su aÅ¾urirani od strane drugog korisnika.
+  notice_not_authorized: Niste ovlaÅ¡teni za pristup ovoj stranici.
+  notice_email_sent: E-mail je poslan %{value}"
+  notice_email_error: Dogodila se pogreÅ¡ka tijekom slanja E-maila (%{value})"
+  notice_feeds_access_key_reseted: VaÅ¡ RSS pristup je resetovan.
+  notice_api_access_key_reseted: VaÅ¡ API pristup je resetovan.
+  notice_failed_to_save_issues: "Neuspjelo spremanje %{count} predmeta na %{total} odabrane: %{ids}."
+  notice_no_issue_selected: "Niti jedan predmet nije odabran! Molim, odaberite predmete koje Å¾elite urediti."
+  notice_account_pending: "VaÅ¡ korisnicki raÄun je otvoren, Äeka odobrenje administratora."
+  notice_default_data_loaded: Konfiguracija je uspjeÅ¡no uÄitana.
+  notice_unable_delete_version: Nije moguÄ‡e izbrisati verziju.
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+
+  error_can_t_load_default_data: "Zadanu konfiguracija nije uÄitana: %{value}"
+  error_scm_not_found: "Unos i/ili revizija nije pronaÄ‘en."
+  error_scm_command_failed: "Dogodila se pogreÅ¡ka prilikom pokuÅ¡aja pristupa: %{value}"
+  error_scm_annotate: "Ne postoji ili ne moÅ¾e biti obiljeÅ¾en."
+  error_issue_not_found_in_project: 'Nije pronaÄ‘en ili ne pripada u ovaj projekt'
+  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
+  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
+  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version can not be reopened'
+  error_can_not_archive_project: This project can not be archived
+  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
+  error_workflow_copy_source: 'Please select a source tracker or role'
+  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
+
+  warning_attachments_not_saved: "%{count} Datoteka/e nije mogla biti spremljena."
+
+  mail_subject_lost_password: "VaÅ¡a %{value} zaporka"
+  mail_body_lost_password: 'Kako biste promijenili VaÅ¡u zaporku slijedite poveznicu:'
+  mail_subject_register: "Aktivacija korisniÄog raÄuna %{value}"
+  mail_body_register: 'Da biste aktivirali svoj raÄun, kliknite na sljedeci link:'
+  mail_body_account_information_external: "MoÅ¾ete koristiti vaÅ¡ raÄun %{value} za prijavu."
+  mail_body_account_information: VaÅ¡i korisniÄki podaci
+  mail_subject_account_activation_request: "%{value} predmet za aktivaciju korisniÄkog raÄuna"
+  mail_body_account_activation_request: "Novi korisnik (%{value}) je registriran. Njegov korisniÄki raÄun Äeka vaÅ¡e odobrenje:"
+  mail_subject_reminder: "%{count} predmet(a) dospijeva sljedeÄ‡ih %{days} dana"
+  mail_body_reminder: "%{count} vama dodijeljen(ih) predmet(a) dospijeva u sljedeÄ‡ih %{days} dana:"
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
+
+
+  field_name: Ime
+  field_description: Opis
+  field_summary: SaÅ¾etak
+  field_is_required: Obavezno
+  field_firstname: Ime
+  field_lastname: Prezime
+  field_mail: E-poÅ¡ta
+  field_filename: Datoteka
+  field_filesize: VeliÄina
+  field_downloads: Preuzimanja
+  field_author: Autor
+  field_created_on: Napravljen
+  field_updated_on: Promijenjen
+  field_field_format: Format
+  field_is_for_all: Za sve projekte
+  field_possible_values: MoguÄ‡e vrijednosti
+  field_regexp: Regularni izraz
+  field_min_length: Minimalna duÅ¾ina
+  field_max_length: Maksimalna duÅ¾ina
+  field_value: Vrijednost
+  field_category: Kategorija
+  field_title: Naslov
+  field_project: Projekt
+  field_issue: Predmet
+  field_status: Status
+  field_notes: Napomene
+  field_is_closed: Predmet je zatvoren
+  field_is_default: Zadana vrijednost
+  field_tracker: Tracker
+  field_subject: Predmet
+  field_due_date: Do datuma
+  field_assigned_to: Dodijeljeno
+  field_priority: Prioritet
+  field_fixed_version: Verzija
+  field_user: Korisnik
+  field_role: Uloga
+  field_homepage: Naslovnica
+  field_is_public: Javni projekt
+  field_parent: Potprojekt od
+  field_is_in_roadmap: Predmeti se prikazuju u Putokazu
+  field_login: KorisniÄko ime
+  field_mail_notification: Obavijest putem e-poÅ¡te
+  field_admin: Administrator
+  field_last_login_on: Zadnja prijava
+  field_language: Primarni jezik
+  field_effective_date: Datum
+  field_password: Zaporka
+  field_new_password: Nova zaporka
+  field_password_confirmation: Potvrda zaporke
+  field_version: Verzija
+  field_type: Tip
+  field_host: Host
+  field_port: Port
+  field_account: Racun
+  field_base_dn: Osnovni DN
+  field_attr_login: Login atribut
+  field_attr_firstname: Atribut imena
+  field_attr_lastname: Atribut prezimena
+  field_attr_mail: Atribut e-poÅ¡te
+  field_onthefly: "Izrada korisnika \"u hodu\""
+  field_start_date: Pocetak
+  field_done_ratio: "% UÄinjeno"
+  field_auth_source: Vrsta prijavljivanja
+  field_hide_mail: Sakrij moju adresu e-poÅ¡te
+  field_comments: Komentar
+  field_url: URL
+  field_start_page: PoÄetna stranica
+  field_subproject: Potprojekt
+  field_hours: Sati
+  field_activity: Aktivnost
+  field_spent_on: Datum
+  field_identifier: Identifikator
+  field_is_filter: KoriÅ¡teno kao filtar
+  field_issue_to_id: Povezano s predmetom
+  field_delay: Odgodeno
+  field_assignable: Predmeti mogu biti dodijeljeni ovoj ulozi
+  field_redirect_existing_links: Preusmjeravanje postojeÄ‡ih linkova
+  field_estimated_hours: Procijenjeno vrijeme
+  field_column_names: Stupci
+  field_time_zone: Vremenska zona
+  field_searchable: PretraÅ¾ivo
+  field_default_value: Zadana vrijednost
+  field_comments_sorting: Prikaz komentara
+  field_parent_title: Parent page
+  field_editable: Editable
+  field_watcher: Watcher
+  field_identity_url: OpenID URL
+  field_content: Content
+  field_group_by: Group results by
+
+  setting_app_title: Naziv aplikacije
+  setting_app_subtitle: Podnaslov aplikacije
+  setting_welcome_text: Tekst dobrodoÅ¡lice
+  setting_default_language: Zadani jezik
+  setting_login_required: Potrebna je prijava
+  setting_self_registration: Samoregistracija je dozvoljena
+  setting_attachment_max_size: Maksimalna veliÄina privitka
+  setting_issues_export_limit: OgraniÄenje izvoza predmeta
+  setting_mail_from: Izvorna adresa e-poÅ¡te
+  setting_bcc_recipients: Blind carbon copy primatelja (bcc)
+  setting_plain_text_mail: obiÄni tekst poÅ¡te (bez HTML-a)
+  setting_host_name: Naziv domaÄ‡ina (host)
+  setting_text_formatting: Oblikovanje teksta
+  setting_wiki_compression: SaÅ¾imanje
+  setting_feeds_limit: Ogranicenje unosa sadrÅ¾aja
+  setting_default_projects_public: Novi projekti su javni po defaultu
+  setting_autofetch_changesets: Autofetch commits
+  setting_sys_api_enabled: OmoguÄ‡i WS za upravljanje skladiÅ¡tem
+  setting_commit_ref_keywords: Referentne kljuÄne rijeÄi
+  setting_commit_fix_keywords: Fiksne kljuÄne rijeÄi
+  setting_autologin: Automatska prijava
+  setting_date_format: Format datuma
+  setting_time_format: Format vremena
+  setting_cross_project_issue_relations: Dozvoli povezivanje predmeta izmedu razliÄitih projekata
+  setting_issue_list_default_columns: Stupci prikazani na listi predmeta
+  setting_emails_footer: Zaglavlje e-poÅ¡te
+  setting_protocol: Protokol
+  setting_per_page_options: Objekata po stranici opcija
+  setting_user_format: Oblik prikaza korisnika
+  setting_activity_days_default: Dani prikazane aktivnosti na projektu
+  setting_display_subprojects_issues: Prikaz predmeta potprojekta na glavnom projektu po defaultu
+  setting_enabled_scm: OmoguÄ‡en SCM
+  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
+  setting_mail_handler_api_enabled: Omoguci WS za dolaznu e-poÅ¡tu
+  setting_mail_handler_api_key: API kljuÄ
+  setting_sequential_project_identifiers: Generiraj slijedne identifikatore projekta
+  setting_gravatar_enabled: Koristi Gravatar korisniÄke ikone
+  setting_gravatar_default: Default Gravatar image
+  setting_diff_max_lines_displayed: Maksimalni broj diff linija za prikazati
+  setting_file_max_size_displayed: Max size of text files displayed inline
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_openid: Allow OpenID login and registration
+  setting_password_min_length: Minimum password length
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_field: Use the issue field
+  setting_issue_done_ratio_issue_status: Use the issue status
+  setting_start_of_week: Start calendars on
+  setting_rest_api_enabled: Enable REST web service
+
+  permission_add_project: Dodaj projekt
+  permission_add_subprojects: Dodaj potprojekt
+  permission_edit_project: Uredi projekt
+  permission_select_project_modules: Odaberi projektne module
+  permission_manage_members: Upravljaj Älanovima
+  permission_manage_versions: Upravljaj verzijama
+  permission_manage_categories: Upravljaj kategorijama predmeta
+  permission_view_issues: Pregledaj zahtjeve
+  permission_add_issues: Dodaj predmete
+  permission_edit_issues: Uredi predmete
+  permission_manage_issue_relations: Upravljaj relacijama predmeta
+  permission_add_issue_notes: Dodaj biljeÅ¡ke
+  permission_edit_issue_notes: Uredi biljeÅ¡ke
+  permission_edit_own_issue_notes: Uredi vlastite biljeÅ¡ke
+  permission_move_issues: Premjesti predmete
+  permission_delete_issues: Brisanje predmeta
+  permission_manage_public_queries: Upravljaj javnim upitima
+  permission_save_queries: Spremi upite
+  permission_view_gantt: Pregledaj gantt grafikon
+  permission_view_calendar: Pregledaj kalendar
+  permission_view_issue_watchers: Pregledaj listu promatraca
+  permission_add_issue_watchers: Dodaj promatraÄa
+  permission_delete_issue_watchers: Delete watchers
+  permission_log_time: Dnevnik utroÅ¡enog vremena
+  permission_view_time_entries: Pregledaj utroÅ¡eno vrijeme
+  permission_edit_time_entries: Uredi vremenske dnevnike
+  permission_edit_own_time_entries: Edit own time logs
+  permission_manage_news: Upravljaj novostima
+  permission_comment_news: Komentiraj novosti
+  permission_view_documents: Pregledaj dokumente
+  permission_manage_files: Upravljaj datotekama
+  permission_view_files: Pregledaj datoteke
+  permission_manage_wiki: Upravljaj wikijem
+  permission_rename_wiki_pages: Promijeni ime wiki stranicama
+  permission_delete_wiki_pages: ObriÅ¡i wiki stranice
+  permission_view_wiki_pages: Pregledaj wiki
+  permission_view_wiki_edits: Pregledaj povijest wikija
+  permission_edit_wiki_pages: Uredi wiki stranice
+  permission_delete_wiki_pages_attachments: ObriÅ¡i privitke
+  permission_protect_wiki_pages: ZaÅ¡titi wiki stranice
+  permission_manage_repository: Upravljaj skladiÅ¡tem
+  permission_browse_repository: Browse repository
+  permission_view_changesets: View changesets
+  permission_commit_access: MoguÄ‡nost pohranjivanja
+  permission_manage_boards: Manage boards
+  permission_view_messages: Pregledaj poruke
+  permission_add_messages: Objavi poruke
+  permission_edit_messages: Uredi poruke
+  permission_edit_own_messages: Uredi vlastite poruke
+  permission_delete_messages: ObriÅ¡i poruke
+  permission_delete_own_messages: ObriÅ¡i vlastite poruke
+
+  project_module_issue_tracking: PraÄ‡enje predmeta
+  project_module_time_tracking: PraÄ‡enje vremena
+  project_module_news: Novosti
+  project_module_documents: Dokumenti
+  project_module_files: Datoteke
+  project_module_wiki: Wiki
+  project_module_repository: SkladiÅ¡te
+  project_module_boards: Boards
+
+  label_user: Korisnik
+  label_user_plural: Korisnici
+  label_user_new: Novi korisnik
+  label_user_anonymous: Anonymous
+  label_project: Projekt
+  label_project_new: Novi projekt
+  label_project_plural: Projekti
+  label_x_projects:
+    zero:  no projects
+    one:   1 project
+    other: "%{count} projects"
+  label_project_all: Svi Projekti
+  label_project_latest: Najnoviji projekt
+  label_issue: Predmet
+  label_issue_new: Novi predmet
+  label_issue_plural: Predmeti
+  label_issue_view_all: Pregled svih predmeta
+  label_issues_by: "Predmeti od %{value}"
+  label_issue_added: Predmet dodan
+  label_issue_updated: Predmet promijenjen
+  label_document: Dokument
+  label_document_new: Novi dokument
+  label_document_plural: Dokumenti
+  label_document_added: Dokument dodan
+  label_role: Uloga
+  label_role_plural: Uloge
+  label_role_new: Nova uloga
+  label_role_and_permissions: Uloge i ovlasti
+  label_member: ÄŒlan
+  label_member_new: Novi Älan
+  label_member_plural: ÄŒlanovi
+  label_tracker: Vrsta
+  label_tracker_plural: Vrste predmeta
+  label_tracker_new: Nova vrsta
+  label_workflow: Tijek rada
+  label_issue_status: Status predmeta
+  label_issue_status_plural: Status predmeta
+  label_issue_status_new: Novi status
+  label_issue_category: Kategorija predmeta
+  label_issue_category_plural: Kategorije predmeta
+  label_issue_category_new: Nova kategorija
+  label_custom_field: KorisniÄki definirano polje
+  label_custom_field_plural: KorisniÄki definirana polja
+  label_custom_field_new: Novo korisniÄki definirano polje
+  label_enumerations: Pobrojenice
+  label_enumeration_new: Nova vrijednost
+  label_information: Informacija
+  label_information_plural: Informacije
+  label_please_login: Molim prijavite se
+  label_register: Registracija
+  label_login_with_open_id_option: or login with OpenID
+  label_password_lost: Izgubljena zaporka
+  label_home: PoÄetna stranica
+  label_my_page: Moja stranica
+  label_my_account: Moj profil
+  label_my_projects: Moji projekti
+  label_administration: Administracija
+  label_login: Korisnik
+  label_logout: Odjava
+  label_help: PomoÄ‡
+  label_reported_issues: Prijavljeni predmeti
+  label_assigned_to_me_issues: Moji predmeti
+  label_last_login: Last connection
+  label_registered_on: Registrirano
+  label_activity: Aktivnosti
+  label_overall_activity: Aktivnosti
+  label_user_activity: "%{value} ova/ina aktivnost"
+  label_new: Novi
+  label_logged_as: Prijavljeni ste kao
+  label_environment: Okolina
+  label_authentication: Autentikacija
+  label_auth_source: NaÄin prijavljivanja
+  label_auth_source_new: Novi naÄin prijavljivanja
+  label_auth_source_plural: NaÄini prijavljivanja
+  label_subproject_plural: Potprojekti
+  label_subproject_new: Novi potprojekt
+  label_and_its_subprojects: "%{value} i njegovi potprojekti"
+  label_min_max_length: Min - Maks  veliÄina
+  label_list: Liste
+  label_date: Datum
+  label_integer: Integer
+  label_float: Float
+  label_boolean: Boolean
+  label_string: Text
+  label_text: Long text
+  label_attribute: Atribut
+  label_attribute_plural: Atributi
+  label_no_data: Nema podataka za prikaz
+  label_change_status: Promjena statusa
+  label_history: Povijest
+  label_attachment: Datoteka
+  label_attachment_new: Nova datoteka
+  label_attachment_delete: Brisanje datoteke
+  label_attachment_plural: Datoteke
+  label_file_added: Datoteka dodana
+  label_report: IzvjeÅ¡Ä‡e
+  label_report_plural: IzvjeÅ¡Ä‡a
+  label_news: Novosti
+  label_news_new: Dodaj novost
+  label_news_plural: Novosti
+  label_news_latest: Novosti
+  label_news_view_all: Pregled svih novosti
+  label_news_added: Novosti dodane
+  label_settings: Postavke
+  label_overview: Pregled
+  label_version: Verzija
+  label_version_new: Nova verzija
+  label_version_plural: Verzije
+  label_confirmation: Potvrda
+  label_export_to: 'Izvoz u:'
+  label_read: ÄŒitaj...
+  label_public_projects: Javni projekti
+  label_open_issues: Otvoren
+  label_open_issues_plural: Otvoreno
+  label_closed_issues: Zatvoren
+  label_closed_issues_plural: Zatvoreno
+  label_x_open_issues_abbr_on_total:
+    zero:  0 open / %{total}
+    one:   1 open / %{total}
+    other: "%{count} open / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 open
+    one:   1 open
+    other: "%{count} open"
+  label_x_closed_issues_abbr:
+    zero:  0 closed
+    one:   1 closed
+    other: "%{count} closed"
+  label_total: Ukupno
+  label_permissions: Dozvole
+  label_current_status: Trenutni status
+  label_new_statuses_allowed: Novi status je dozvoljen
+  label_all: Svi
+  label_none: nema
+  label_nobody: nitko
+  label_next: Naredni
+  label_previous: Prethodni
+  label_used_by: KoriÅ¡ten od
+  label_details: Detalji
+  label_add_note: Dodaj napomenu
+  label_per_page: Po stranici
+  label_calendar: Kalendar
+  label_months_from: Mjeseci od
+  label_gantt: Gantt
+  label_internal: Interno
+  label_last_changes: "Posljednjih %{count} promjena"
+  label_change_view_all: Prikaz svih promjena
+  label_personalize_page: Prilagodite ovu stranicu
+  label_comment: Komentar
+  label_comment_plural: Komentari
+  label_x_comments:
+    zero: no comments
+    one: 1 comment
+    other: "%{count} comments"
+  label_comment_add: Dodaj komentar
+  label_comment_added: Komentar dodan
+  label_comment_delete: Brisanje komentara
+  label_query: KorisniÄki upit
+  label_query_plural: KorisniÄki upiti
+  label_query_new: Novi upit
+  label_filter_add: Dodaj filtar
+  label_filter_plural: Filtri
+  label_equals: je
+  label_not_equals: nije
+  label_in_less_than: za manje od
+  label_in_more_than: za viÅ¡e od
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: za toÄno
+  label_today: danas
+  label_all_time: sva vremena
+  label_yesterday: juÄer
+  label_this_week: ovog tjedna
+  label_last_week: proÅ¡log tjedna
+  label_last_n_days: "zadnjih %{count} dana"
+  label_this_month: ovog mjeseca
+  label_last_month: proÅ¡log mjeseca
+  label_this_year: ove godine
+  label_date_range: vremenski raspon
+  label_less_than_ago: manje od
+  label_more_than_ago: viÅ¡e od
+  label_ago: prije
+  label_contains: SadrÅ¾i
+  label_not_contains: ne sadrÅ¾i
+  label_day_plural: dana
+  label_repository: SkladiÅ¡te
+  label_repository_plural: SkladiÅ¡ta
+  label_browse: Pregled
+  label_branch: Branch
+  label_tag: Tag
+  label_revision: Revizija
+  label_revision_plural: Revizije
+  label_revision_id: "Revision %{value}"
+  label_associated_revisions: Dodijeljene revizije
+  label_added: dodano
+  label_modified: promijenjen
+  label_copied: kopirano
+  label_renamed: preimenovano
+  label_deleted: obrisano
+  label_latest_revision: Posljednja revizija
+  label_latest_revision_plural: Posljednje revizije
+  label_view_revisions: Pregled revizija
+  label_view_all_revisions: View all revisions
+  label_max_size: Maksimalna veliÄina
+  label_sort_highest: Premjesti na vrh
+  label_sort_higher: Premjesti prema gore
+  label_sort_lower: Premjesti prema dolje
+  label_sort_lowest: Premjesti na dno
+  label_roadmap: Putokaz
+  label_roadmap_due_in: "ZavrÅ¡ava se za %{value}"
+  label_roadmap_overdue: "%{value} kasni"
+  label_roadmap_no_issues: Nema predmeta za ovu verziju
+  label_search: TraÅ¾i
+  label_result_plural: Rezultati
+  label_all_words: Sve rijeÄi
+  label_wiki: Wiki
+  label_wiki_edit: Wiki promjena
+  label_wiki_edit_plural: Wiki promjene
+  label_wiki_page: Wiki stranica
+  label_wiki_page_plural: Wiki stranice
+  label_index_by_title: Indeks po naslovima
+  label_index_by_date: Indeks po datumu
+  label_current_version: Trenutna verzija
+  label_preview: Brzi pregled
+  label_feed_plural: Feeds
+  label_changes_details: Detalji svih promjena
+  label_issue_tracking: PraÄ‡enje predmeta
+  label_spent_time: UtroÅ¡eno vrijeme
+  label_f_hour: "%{value} sata"
+  label_f_hour_plural: "%{value} sati"
+  label_time_tracking: PraÄ‡enje vremena
+  label_change_plural: Promjene
+  label_statistics: Statistika
+  label_commits_per_month: Pohrana po mjesecu
+  label_commits_per_author: Pohrana po autoru
+  label_view_diff: Pregled razlika
+  label_diff_inline: uvuÄeno
+  label_diff_side_by_side: paralelno
+  label_options: Opcije
+  label_copy_workflow_from: Kopiraj tijek rada od
+  label_permissions_report: IzvjeÅ¡Ä‡e o dozvolama
+  label_watched_issues: PraÄ‡eni predmeti
+  label_related_issues: Povezani predmeti
+  label_applied_status: Primijenjen status
+  label_loading: UÄitavam...
+  label_relation_new: Nova relacija
+  label_relation_delete: Brisanje relacije
+  label_relates_to: u relaciji sa
+  label_duplicates: Duplira
+  label_duplicated_by: ponovljen kao
+  label_blocks: blokira
+  label_blocked_by: blokiran od strane
+  label_precedes: prethodi
+  label_follows: slijedi
+  label_end_to_start: od kraja do poÄetka
+  label_end_to_end: od kraja do kraja
+  label_end_to_start: od kraja do poÄetka
+  label_end_to_end: od kraja do kraja
+  label_stay_logged_in: Ostanite prijavljeni
+  label_disabled: IskljuÄen
+  label_show_completed_versions: PrikaÅ¾i zavrÅ¡ene verzije
+  label_me: ja
+  label_board: Forum
+  label_board_new: Novi forum
+  label_board_plural: Forumi
+  label_topic_plural: Teme
+  label_message_plural: Poruke
+  label_message_last: Posljednja poruka
+  label_message_new: Nova poruka
+  label_message_posted: Poruka dodana
+  label_reply_plural: Odgovori
+  label_send_information: PoÅ¡alji korisniku informaciju o profilu
+  label_year: Godina
+  label_month: Mjesec
+  label_week: Tjedan
+  label_date_from: Od
+  label_date_to: Do
+  label_language_based: Zasnovano na jeziku
+  label_sort_by: "Uredi po %{value}"
+  label_send_test_email: PoÅ¡alji testno E-pismo
+  label_feeds_access_key: RSS access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  label_feeds_access_key_created_on: "RSS kljuc za pristup je napravljen prije %{value}"
+  label_module_plural: Moduli
+  label_added_time_by: "Promijenio %{author} prije %{age}"
+  label_updated_time_by: "Dodao/la %{author} prije %{age}"
+  label_updated_time: "Promijenjeno prije %{value}"
+  label_jump_to_a_project: Prebaci se na projekt...
+  label_file_plural: Datoteke
+  label_changeset_plural: Promjene
+  label_default_columns: Zadani stupci
+  label_no_change_option: (Bez promjene)
+  label_bulk_edit_selected_issues: ZajedniÄka promjena izabranih predmeta
+  label_theme: Tema
+  label_default: Zadana
+  label_search_titles_only: PretraÅ¾ivanje samo naslova
+  label_user_mail_option_all: "Za bilo koji dogaÄ‘aj na svim mojim projektima"
+  label_user_mail_option_selected: "Za bilo koji dogaÄ‘aj samo za izabrane projekte..."
+  label_user_mail_no_self_notified: "Ne Å¾elim primati obavijesti o promjenama koje sam napravim"
+  label_registration_activation_by_email: aktivacija putem e-poÅ¡te
+  label_registration_manual_activation: ruÄna aktivacija
+  label_registration_automatic_activation: automatska aktivacija
+  label_display_per_page: "Po stranici: %{value}"
+  label_age: Starost
+  label_change_properties: Promijeni svojstva
+  label_general: OpÄ‡enito
+  label_more: JoÅ¡
+  label_scm: SCM
+  label_plugins: Plugins
+  label_ldap_authentication: LDAP autentikacija
+  label_downloads_abbr: D/L
+  label_optional_description: Opcije
+  label_add_another_file: Dodaj joÅ¡ jednu datoteku
+  label_preferences: Preferences
+  label_chronological_order: U kronoloÅ¡kom redoslijedu
+  label_reverse_chronological_order: U obrnutom kronoloÅ¡kom redoslijedu
+  label_planning: Planiranje
+  label_incoming_emails: Dolazne poruke e-poÅ¡te
+  label_generate_key: Generiraj kljuÄ
+  label_issue_watchers: PromatraÄi
+  label_example: Primjer
+  label_display: Display
+  label_sort: Sort
+  label_ascending: Ascending
+  label_descending: Descending
+  label_date_from_to: From %{start} to %{end}
+  label_wiki_content_added: Wiki page added
+  label_wiki_content_updated: Wiki page updated
+  label_group: Group
+  label_group_plural: Grupe
+  label_group_new: Nova grupa
+  label_time_entry_plural: Spent time
+  label_version_sharing_none: Not shared
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_tree: With project tree
+  label_version_sharing_system: With all projects
+  label_update_issue_done_ratios: Update issue done ratios
+  label_copy_source: Source
+  label_copy_target: Target
+  label_copy_same_as_target: Same as target
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_api_access_key: API access key
+  label_missing_api_access_key: Missing an API access key
+  label_api_access_key_created_on: "API access key created %{value} ago"
+
+  button_login: Prijavi
+  button_submit: PoÅ¡alji
+  button_save: Spremi
+  button_check_all: OznaÄi sve
+  button_uncheck_all: IskljuÄi sve
+  button_delete: ObriÅ¡i
+  button_create: Napravi
+  button_create_and_continue: Napravi i nastavi
+  button_test: Test
+  button_edit: Uredi
+  button_add: Dodaj
+  button_change: Promijeni
+  button_apply: Primijeni
+  button_clear: Ukloni
+  button_lock: ZakljuÄaj
+  button_unlock: OtkljuÄaj
+  button_download: Preuzmi
+  button_list: Spisak
+  button_view: Pregled
+  button_move: Premjesti
+  button_move_and_follow: Move and follow
+  button_back: Nazad
+  button_cancel: Odustani
+  button_activate: Aktiviraj
+  button_sort: Redoslijed
+  button_log_time: ZapiÅ¡i vrijeme
+  button_rollback: IzvrÅ¡i rollback na ovu verziju
+  button_watch: Prati
+  button_unwatch: Prekini pracenje
+  button_reply: Odgovori
+  button_archive: Arhiviraj
+  button_rollback: Dearhiviraj
+  button_reset: PoniÅ¡ti
+  button_rename: Promijeni ime
+  button_change_password: Promjena zaporke
+  button_copy: Kopiraj
+  button_copy_and_follow: Copy and follow
+  button_annotate: Annotate
+  button_update: Promijeni
+  button_configure: Konfiguracija
+  button_quote: Navod
+  button_duplicate: Duplicate
+  button_show: Show
+
+  status_active: aktivan
+  status_registered: Registriran
+  status_locked: zakljuÄan
+
+  version_status_open: open
+  version_status_locked: locked
+  version_status_closed: closed
+
+  field_active: Active
+
+  text_select_mail_notifications: Izbor akcija za koje Ä‡e biti poslana obavijest e-poÅ¡tom.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 znaÄi bez ograniÄenja
+  text_project_destroy_confirmation: Da li ste sigurni da Å¾elite izbrisati ovaj projekt i sve njegove podatke?
+  text_subprojects_destroy_warning: "Njegov(i) potprojekt(i): %{value} Ä‡e takoÄ‘er biti obrisan."
+  text_workflow_edit: Select a role and a tracker to edit the workflow
+  text_are_you_sure: Da li ste sigurni?
+  text_journal_changed: "%{label} promijenjen iz %{old} u %{new}"
+  text_journal_set_to: "%{label} postavi na %{value}"
+  text_journal_deleted: "%{label} izbrisano (%{old})"
+  text_journal_added: "%{label} %{value} added"
+  text_tip_issue_begin_day: Zadaci koji poÄinju ovog dana
+  text_tip_issue_end_day: zadaci koji se zavrÅ¡avaju ovog dana
+  text_tip_issue_begin_end_day: Zadaci koji poÄinju i zavrÅ¡avaju se ovog dana
+  text_caracters_maximum: "NajviÅ¡e %{count} znakova."
+  text_caracters_minimum: "Mora biti dugaÄko najmanje %{count} znakova."
+  text_length_between: "DuÅ¾ina izmedu %{min} i %{max} znakova."
+  text_tracker_no_workflow: Tijek rada nije definiran za ovaj tracker
+  text_unallowed_characters: Nedozvoljeni znakovi
+  text_comma_separated: ViÅ¡estruke vrijednosti su dozvoljene (razdvojene zarezom).
+  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
+  text_tracker_no_workflow: No workflow defined for this tracker
+  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
+  text_issue_added: "Predmet %{id} je prijavljen (prijavio %{author})."
+  text_issue_updated: "Predmet %{id} je promijenjen %{author})."
+  text_wiki_destroy_confirmation: Da li ste sigurni da Å¾elite izbrisati ovaj wiki i njegov sadrÅ¾aj?
+  text_issue_category_destroy_question: "Neke predmeti (%{count}) su dodijeljeni ovoj kategoriji. Å to Å¾elite uraditi?"
+  text_issue_category_destroy_assignments: Ukloni dodjeljivanje kategorija
+  text_issue_category_reassign_to: Ponovo dodijeli predmete ovoj kategoriji
+  text_user_mail_option: "Za neizabrane projekte, primit Ä‡ete obavjesti samo o stvarima koje pratite ili u kojima sudjelujete (npr. predmete koje ste vi napravili ili koje su vama dodjeljeni)."
+  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
+  text_load_default_configuration: UÄitaj poÄetnu konfiguraciju
+  text_status_changed_by_changeset: "Applied in changeset %{value}."
+  text_issues_destroy_confirmation: 'Jeste li sigurni da Å¾elite obrisati izabrani/e predmet(e)?'
+  text_select_project_modules: 'Odaberite module koji Ä‡e biti omoguÄ‡eni za ovaj projekt:'
+  text_default_administrator_account_changed: Default administrator account changed
+  text_file_repository_writable: Dozvoljeno pisanje u direktorij za privitke
+  text_plugin_assets_writable: Plugin assets directory writable
+  text_rmagick_available: RMagick dostupan (nije obavezno)
+  text_destroy_time_entries_question: "%{hours} sati je prijavljeno za predmete koje Å¾elite obrisati. Å to Ä‡ete uÄiniti?"
+  text_destroy_time_entries: ObriÅ¡i prijavljene sate
+  text_assign_time_entries_to_project: PridruÅ¾i prijavljene sate projektu
+  text_reassign_time_entries: 'Premjesti prijavljene sate ovom predmetu:'
+  text_user_wrote: "%{value} je napisao/la:"
+  text_enumeration_destroy_question: "%{count} objekata je pridruÅ¾eno toj vrijednosti."
+  text_enumeration_category_reassign_to: 'Premjesti ih ovoj vrijednosti:'
+  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
+  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  text_diff_truncated: '... Ovaj diff je odrezan zato Å¡to prelazi maksimalnu veliÄinu koja moÅ¾e biti prikazana.'
+  text_custom_field_possible_values_info: 'One line for each value'
+  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
+  text_wiki_page_nullify_children: "Keep child pages as root pages"
+  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
+  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
+  default_role_manager: Upravitelj
+  default_role_developer: Razvojni inÅ¾enjer
+  default_role_reporter: Korisnik
+  default_tracker_bug: PogreÅ¡ka
+  default_tracker_feature: Funkcionalnost
+  default_tracker_support: PodrÅ¡ka
+  default_issue_status_new: Novo
+  default_issue_status_assigned: Dodijeljeno
+  default_issue_status_resolved: RijeÅ¡eno
+  default_issue_status_feedback: Povratna informacija
+  default_issue_status_closed: Zatvoreno
+  default_issue_status_rejected: Odbaceno
+  default_doc_category_user: KorisniÄka dokumentacija
+  default_doc_category_tech: TehniÄka dokumentacija
+  default_priority_low: Nizak
+  default_priority_normal: Redovan
+  default_priority_high: Visok
+  default_priority_urgent: Hitan
+  default_priority_immediate: Odmah
+  default_activity_design: Dizajn
+  default_activity_development: Razvoj
+  enumeration_issue_priorities: Prioriteti predmeta
+  enumeration_doc_categories: Kategorija dokumenata
+  enumeration_activities: Aktivnosti (po vremenu)
+  enumeration_system_activity: System Activity
+  field_sharing: Sharing
+  text_line_separated: Multiple values allowed (one line for each value).
+  label_close_versions: Close completed versions
+  button_unarchive: Unarchive
+  label_start_to_end: start to end
+  label_start_to_start: start to start
+  field_issue_to: Related issue
+  default_issue_status_in_progress: In Progress
+  text_own_membership_delete_confirmation: |-
+    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
+    Are you sure you want to continue?
+  label_board_sticky: Sticky
+  label_board_locked: Locked
+  permission_export_wiki_pages: Export wiki pages
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: Manage project activities
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_profile: Profile
+  permission_manage_subtasks: Manage subtasks
+  field_parent_issue: Parent task
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Commit messages encoding
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 predmet
+    one:   1 predmet
+    other: "%{count} predmeti"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: Svi
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ukupno
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/743a4dc7b2a0298d7100e21b5ae7b16566c99a77.svn-base
--- a/.svn/pristine/74/743a4dc7b2a0298d7100e21b5ae7b16566c99a77.svn-base
+++ /dev/null
@@ -1,93 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class WatchersController < ApplicationController
-  before_filter :find_project
-  before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch]
-  before_filter :authorize, :only => [:new, :destroy]
-
-  verify :method => :post,
-         :only => [ :watch, :unwatch ],
-         :render => { :nothing => true, :status => :method_not_allowed }
-
-  def watch
-    if @watched.respond_to?(:visible?) && !@watched.visible?(User.current)
-      render_403
-    else
-      set_watcher(User.current, true)
-    end
-  end
-
-  def unwatch
-    set_watcher(User.current, false)
-  end
-
-  def new
-    @watcher = Watcher.new(params[:watcher])
-    @watcher.watchable = @watched
-    @watcher.save if request.post?
-    respond_to do |format|
-      format.html { redirect_to :back }
-      format.js do
-        render :update do |page|
-          page.replace_html 'watchers', :partial => 'watchers/watchers', :locals => {:watched => @watched}
-        end
-      end
-    end
-  rescue ::ActionController::RedirectBackError
-    render :text => 'Watcher added.', :layout => true
-  end
-
-  def destroy
-    @watched.set_watcher(User.find(params[:user_id]), false) if request.post?
-    respond_to do |format|
-      format.html { redirect_to :back }
-      format.js do
-        render :update do |page|
-          page.replace_html 'watchers', :partial => 'watchers/watchers', :locals => {:watched => @watched}
-        end
-      end
-    end
-  end
-
-private
-  def find_project
-    klass = Object.const_get(params[:object_type].camelcase)
-    return false unless klass.respond_to?('watched_by')
-    @watched = klass.find(params[:object_id])
-    @project = @watched.project
-  rescue
-    render_404
-  end
-
-  def set_watcher(user, watching)
-    @watched.set_watcher(user, watching)
-    respond_to do |format|
-      format.html { redirect_to :back }
-      format.js do
-        render(:update) do |page|
-          c = watcher_css(@watched)
-          page.select(".#{c}").each do |item|
-            page.replace_html item, watcher_link(@watched, user)
-          end
-        end
-      end
-    end
-  rescue ::ActionController::RedirectBackError
-    render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/7454b0c86e4f8493693e8238d3d4dafc54d562c2.svn-base
--- a/.svn/pristine/74/7454b0c86e4f8493693e8238d3d4dafc54d562c2.svn-base
+++ /dev/null
@@ -1,64 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class CustomFieldsController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin
-
-  def index
-    @custom_fields_by_type = CustomField.find(:all).group_by {|f| f.class.name }
-    @tab = params[:tab] || 'IssueCustomField'
-  end
-
-  def new
-    @custom_field = begin
-      if params[:type].to_s.match(/.+CustomField$/)
-        params[:type].to_s.constantize.new(params[:custom_field])
-      end
-    rescue
-    end
-    (redirect_to(:action => 'index'); return) unless @custom_field.is_a?(CustomField)
-
-    if request.post? and @custom_field.save
-      flash[:notice] = l(:notice_successful_create)
-      call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field)
-      redirect_to :action => 'index', :tab => @custom_field.class.name
-    else
-      @trackers = Tracker.find(:all, :order => 'position')
-    end
-  end
-
-  def edit
-    @custom_field = CustomField.find(params[:id])
-    if request.post? and @custom_field.update_attributes(params[:custom_field])
-      flash[:notice] = l(:notice_successful_update)
-      call_hook(:controller_custom_fields_edit_after_save, :params => params, :custom_field => @custom_field)
-      redirect_to :action => 'index', :tab => @custom_field.class.name
-    else
-      @trackers = Tracker.find(:all, :order => 'position')
-    end
-  end
-
-  def destroy
-    @custom_field = CustomField.find(params[:id]).destroy
-    redirect_to :action => 'index', :tab => @custom_field.class.name
-  rescue
-    flash[:error] = l(:error_can_not_delete_custom_field)
-    redirect_to :action => 'index'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/74646d64b0858dd62aa32241e9f5deb66f244cbc.svn-base
--- a/.svn/pristine/74/74646d64b0858dd62aa32241e9f5deb66f244cbc.svn-base
+++ /dev/null
@@ -1,75 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'blankslate'
-
-module Redmine
-  module Views
-    module Builders
-      class Structure < BlankSlate
-        def initialize
-          @struct = [{}]
-        end
-
-        def array(tag, options={}, &block)
-          @struct << []
-          block.call(self)
-          ret = @struct.pop
-          @struct.last[tag] = ret
-          @struct.last.merge!(options) if options
-        end
-
-        def method_missing(sym, *args, &block)
-          if args.any?
-            if args.first.is_a?(Hash)
-              if @struct.last.is_a?(Array)
-                @struct.last << args.first unless block
-              else
-                @struct.last[sym] = args.first
-              end
-            else
-              if @struct.last.is_a?(Array)
-                @struct.last << (args.last || {}).merge(:value => args.first)
-              else
-                @struct.last[sym] = args.first
-              end
-            end
-          end
-
-          if block
-            @struct << (args.first.is_a?(Hash) ? args.first : {})
-            block.call(self)
-            ret = @struct.pop
-            if @struct.last.is_a?(Array)
-              @struct.last << ret
-            else
-              if @struct.last.has_key?(sym) && @struct.last[sym].is_a?(Hash)
-                @struct.last[sym].merge! ret
-              else
-                @struct.last[sym] = ret
-              end
-            end
-          end
-        end
-
-        def output
-          raise "Need to implement #{self.class.name}#output"
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/74659fa6cdf8fb6e2bcf14986b0b23d99872b7b3.svn-base
--- /dev/null
+++ b/.svn/pristine/74/74659fa6cdf8fb6e2bcf14986b0b23d99872b7b3.svn-base
@@ -0,0 +1,225 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../../test_helper', __FILE__)
+begin
+  require 'mocha'
+
+  class BazaarAdapterTest < ActiveSupport::TestCase
+    REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s
+    REPOSITORY_PATH.gsub!(/\/+/, '/')
+
+    if File.directory?(REPOSITORY_PATH)
+      def setup
+        @adapter = Redmine::Scm::Adapters::BazaarAdapter.new(
+                                File.join(REPOSITORY_PATH, "trunk")
+                                )
+      end
+
+      def test_scm_version
+        to_test = { "Bazaar (bzr) 2.1.2\n"             => [2,1,2],
+                    "2.1.1\n1.7\n1.8"                  => [2,1,1],
+                    "2.0.1\r\n1.8.1\r\n1.9.1"          => [2,0,1]}
+        to_test.each do |s, v|
+          test_scm_version_for(s, v)
+        end
+      end
+
+      def test_cat
+        cat = @adapter.cat('directory/document.txt')
+        assert cat =~ /Write the contents of a file as of a given revision to standard output/
+      end
+
+      def test_cat_path_invalid
+        assert_nil @adapter.cat('invalid')
+      end
+
+      def test_cat_revision_invalid
+        assert_nil @adapter.cat('doc-mkdir.txt', '12345678')
+      end
+
+      def test_diff
+        diff1 = @adapter.diff('doc-mkdir.txt', 3, 2)
+        assert_equal 21, diff1.size
+        buf =  diff1[14].gsub(/\r\n|\r|\n/, "")
+        assert_equal "-Display more information.", buf
+      end
+
+      def test_diff_path_invalid
+        assert_equal [], @adapter.diff('invalid', 1)
+      end
+
+      def test_diff_revision_invalid
+        assert_equal [], @adapter.diff(nil, 12345678)
+        assert_equal [], @adapter.diff(nil, 12345678, 87654321)
+      end
+
+      def test_annotate
+        annotate = @adapter.annotate('doc-mkdir.txt')
+        assert_equal 17, annotate.lines.size
+        assert_equal '1', annotate.revisions[0].identifier
+        assert_equal 'jsmith@', annotate.revisions[0].author
+        assert_equal 'mkdir', annotate.lines[0]
+      end
+
+      def test_annotate_path_invalid
+        assert_nil @adapter.annotate('invalid')
+      end
+
+      def test_annotate_revision_invalid
+        assert_nil @adapter.annotate('doc-mkdir.txt', '12345678')
+      end
+
+      def test_branch_conf_path
+        p = "c:\\test\\test\\"
+        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
+        assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
+        p = "c:\\test\\test\\.bzr"
+        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
+        assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
+        p = "c:\\test\\test\\.bzr\\"
+        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
+        assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
+        p = "c:\\test\\test"
+        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
+        assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
+        p = "\\\\server\\test\\test\\"
+        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
+        assert_equal File.join("\\\\server\\test\\test", ".bzr", "branch", "branch.conf"), bcp
+      end
+
+      def test_append_revisions_only_true
+        assert_equal true, @adapter.append_revisions_only
+      end
+
+      def test_append_revisions_only_false
+        adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
+                                File.join(REPOSITORY_PATH, "empty-branch")
+                                )
+        assert_equal false, adpt.append_revisions_only
+      end
+
+      def test_append_revisions_only_shared_repo
+        adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
+                                REPOSITORY_PATH
+                                )
+        assert_equal false, adpt.append_revisions_only
+      end
+
+      def test_info_not_nil
+        assert_not_nil @adapter.info
+      end
+
+      def test_info_nil
+        adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
+                  "/invalid/invalid/"
+                  )
+        assert_nil adpt.info
+      end
+
+      def test_info
+        info = @adapter.info
+        assert_equal 4, info.lastrev.identifier.to_i
+      end
+
+      def test_info_emtpy
+        adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
+                                File.join(REPOSITORY_PATH, "empty-branch")
+                                )
+        assert_equal 0, adpt.info.lastrev.identifier.to_i
+      end
+
+      def test_entries_path_invalid
+        assert_equal [], @adapter.entries('invalid')
+      end
+
+      def test_entries_revision_invalid
+        assert_nil @adapter.entries(nil, 12345678)
+      end
+
+      def test_revisions
+        revisions = @adapter.revisions(nil, 4, 2)
+        assert_equal 3, revisions.size
+        assert_equal 2, revisions[2].identifier
+        assert_equal 'jsmith@foo.bar-20071203175224-v0eog5d5wrgdrshg', revisions[2].scmid
+        assert_equal 4, revisions[0].identifier
+        assert_equal 'jsmith@foo.bar-20071203175422-t40bf8li5zz0c4cg', revisions[0].scmid
+        assert_equal 2, revisions[0].paths.size
+        assert_equal 'D', revisions[0].paths[0][:action]
+        assert_equal '/doc-deleted.txt', revisions[0].paths[0][:path]
+        assert_equal 'docdeleted.txt-20071203175320-iwwj561ojuubs3gt-1', revisions[0].paths[0][:revision]
+        assert_equal 'M', revisions[0].paths[1][:action]
+        assert_equal '/directory/doc-ls.txt', revisions[0].paths[1][:path]
+        assert_equal 'docls.txt-20071203175005-a3hyc3mn0shl7cgu-1', revisions[0].paths[1][:revision]
+      end
+
+      def test_revisions_path_invalid
+        assert_nil @adapter.revisions('invalid')
+      end
+
+      def test_revisions_revision_invalid
+        assert_nil @adapter.revisions(nil, 12345678)
+        assert_nil @adapter.revisions(nil, 12345678, 87654321)
+      end
+
+      def test_entry
+        entry = @adapter.entry()
+        assert_equal "", entry.path
+        assert_equal "dir", entry.kind
+        entry = @adapter.entry('')
+        assert_equal "", entry.path
+        assert_equal "dir", entry.kind
+        assert_nil @adapter.entry('invalid')
+        assert_nil @adapter.entry('/invalid')
+        assert_nil @adapter.entry('/invalid/')
+        assert_nil @adapter.entry('invalid/invalid')
+        assert_nil @adapter.entry('invalid/invalid/')
+        assert_nil @adapter.entry('/invalid/invalid')
+        assert_nil @adapter.entry('/invalid/invalid/')
+        ["doc-ls.txt", "/doc-ls.txt"].each do |path|
+          entry = @adapter.entry(path, 2)
+          assert_equal "doc-ls.txt", entry.path
+          assert_equal "file", entry.kind
+        end
+        ["directory", "/directory", "/directory/"].each do |path|
+          entry = @adapter.entry(path, 2)
+          assert_equal "directory", entry.path
+          assert_equal "dir", entry.kind
+        end
+        ["directory/document.txt", "/directory/document.txt"].each do |path|
+          entry = @adapter.entry(path, 2)
+          assert_equal "directory/document.txt", entry.path
+          assert_equal "file", entry.kind
+        end
+      end
+
+      private
+
+      def test_scm_version_for(scm_command_version, version)
+        @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
+        assert_equal version, @adapter.class.scm_command_version
+      end
+    else
+      puts "Bazaar test repository NOT FOUND. Skipping unit tests !!!"
+      def test_fake; assert true end
+    end
+  end
+rescue LoadError
+  class BazaarMochaFake < ActiveSupport::TestCase
+    def test_fake; assert(false, "Requires mocha to run those tests")  end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/746eb676a490baf5ce191dc6543fabe7fb71d84c.svn-base
--- a/.svn/pristine/74/746eb676a490baf5ce191dc6543fabe7fb71d84c.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-module CodeRay
-module Styles
-  
-  default :alpha
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/74c381bd74bb7f13d9d8695257e06bccd688238e.svn-base
--- a/.svn/pristine/74/74c381bd74bb7f13d9d8695257e06bccd688238e.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-Signup template from application
-
-Here's a local variable set in the Mail object: <%= @name %>.
-
-And here's a method called in a mail helper: <%= do_something_helpful(@name) %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/74ced18dca894e05230dcd0fed4eb5324521d734.svn-base
--- /dev/null
+++ b/.svn/pristine/74/74ced18dca894e05230dcd0fed4eb5324521d734.svn-base
@@ -0,0 +1,51 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::IssueStatusesTest < Redmine::ApiTest::Base
+  fixtures :issue_statuses
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "/issue_statuses" do
+    context "GET" do
+
+      should "return issue statuses" do
+        get '/issue_statuses.xml'
+
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+        assert_tag :tag => 'issue_statuses',
+          :attributes => {:type => 'array'},
+          :child => {
+            :tag => 'issue_status',
+            :child => {
+              :tag => 'id',
+              :content => '2',
+              :sibling => {
+                :tag => 'name',
+                :content => 'Assigned'
+              }
+            }
+          }
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/74/74d9194a2436a04f76d12b3254f21b2676662dd5.svn-base
--- a/.svn/pristine/74/74d9194a2436a04f76d12b3254f21b2676662dd5.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-class BuildProjectsTree < ActiveRecord::Migration
-  def self.up
-    Project.rebuild!
-  end
-
-  def self.down
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/75/7537e9eba2daabb99d2e6fee47a3f35857d9e159.svn-base
--- a/.svn/pristine/75/7537e9eba2daabb99d2e6fee47a3f35857d9e159.svn-base
+++ /dev/null
@@ -1,41 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class ArbitraryCodeMixingTest < Test::Unit::TestCase  
-  def setup
-    Engines.code_mixing_file_types = %w(controller helper)
-  end
-  
-  def test_should_allow_setting_of_different_code_mixing_file_types
-    assert_nothing_raised {
-      Engines.mix_code_from :things
-    }
-  end
-
-  def test_should_add_new_types_to_existing_code_mixing_file_types
-    Engines.mix_code_from :things
-    assert_equal ["controller", "helper", "thing"], Engines.code_mixing_file_types
-    Engines.mix_code_from :other
-    assert_equal ["controller", "helper", "thing", "other"], Engines.code_mixing_file_types
-  end
-  
-  def test_should_allow_setting_of_multiple_types_at_once
-    Engines.mix_code_from :things, :other
-    assert_equal ["controller", "helper", "thing", "other"], Engines.code_mixing_file_types
-  end
-   
-  def test_should_singularize_elements_to_be_mixed
-    # this is the only test using mocha, so let's try to work around it
-    # also, this seems to be already tested with the :things in the tests above
-    # arg = stub(:to_s => stub(:singularize => "element")) 
-    Engines.mix_code_from :elements
-    assert Engines.code_mixing_file_types.include?("element")
-  end
-  
-  # TODO doesn't seem to work as expected?
-  
-  # def test_should_successfully_mix_custom_types
-  #   Engines.mix_code_from :things    
-  #   assert_equal 'Thing (from app)', Thing.from_app
-  #   assert_equal 'Thing (from test_code_mixing)', Thing.from_plugin
-  # end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/75/7564d8cc7d8f96cea467c64ec9f7ec7cf4ca759a.svn-base
--- a/.svn/pristine/75/7564d8cc7d8f96cea467c64ec9f7ec7cf4ca759a.svn-base
+++ /dev/null
@@ -1,34 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssuePriority < Enumeration
-  has_many :issues, :foreign_key => 'priority_id'
-
-  OptionName = :enumeration_issue_priorities
-
-  def option_name
-    OptionName
-  end
-
-  def objects_count
-    issues.count
-  end
-
-  def transfer_relations(to)
-    issues.update_all("priority_id = #{to.id}")
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/75/7564dff632a56de9feef3194aae6511189c0892c.svn-base
--- a/.svn/pristine/75/7564dff632a56de9feef3194aae6511189c0892c.svn-base
+++ /dev/null
@@ -1,14 +0,0 @@
-<%= error_messages_for 'relation' %>
-
-<p><%= f.select :relation_type, collection_for_relation_type_select, {}, :onchange => "setPredecessorFieldsVisibility();" %>
-<%= l(:label_issue) %> #<%= f.text_field :issue_to_id, :size => 10 %>
-<div id="related_issue_candidates" class="autocomplete"></div>
-<%= javascript_tag "observeRelatedIssueField('#{auto_complete_issues_path(:id => @issue, :project_id => @project) }')" %>
-<span id="predecessor_fields" style="display:none;">
-<%= l(:field_delay) %>: <%= f.text_field :delay, :size => 3 %> <%= l(:label_day_plural) %>
-</span>
-<%= submit_tag l(:button_add) %>
-<%= toggle_link l(:button_cancel), 'new-relation-form'%>
-</p>
-
-<%= javascript_tag "setPredecessorFieldsVisibility();" %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/75/756d2effd3b96f4e4b0f3695a706738e31fc6e53.svn-base
--- /dev/null
+++ b/.svn/pristine/75/756d2effd3b96f4e4b0f3695a706738e31fc6e53.svn-base
@@ -0,0 +1,268 @@
+--- 
+issues_001: 
+  created_on: <%= 3.days.ago.to_s(:db) %>
+  project_id: 1
+  updated_on: <%= 1.day.ago.to_s(:db) %>
+  priority_id: 4
+  subject: Can't print recipes
+  id: 1
+  fixed_version_id: 
+  category_id: 1
+  description: Unable to print recipes
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 1
+  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
+  due_date: <%= 10.day.from_now.to_date.to_s(:db) %>
+  root_id: 1
+  lft: 1
+  rgt: 2
+  lock_version: 3
+issues_002: 
+  created_on: 2006-07-19 21:04:21 +02:00
+  project_id: 1
+  updated_on: 2006-07-19 21:09:50 +02:00
+  priority_id: 5
+  subject: Add ingredients categories
+  id: 2
+  fixed_version_id: 2
+  category_id: 
+  description: Ingredients of the recipe should be classified by categories
+  tracker_id: 2
+  assigned_to_id: 3
+  author_id: 2
+  status_id: 2
+  start_date: <%= 2.day.ago.to_date.to_s(:db) %>
+  due_date: 
+  root_id: 2
+  lft: 1
+  rgt: 2
+  lock_version: 3
+  done_ratio: 30
+issues_003: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  project_id: 1
+  updated_on: 2006-07-19 21:07:27 +02:00
+  priority_id: 4
+  subject: Error 281 when updating a recipe
+  id: 3
+  fixed_version_id: 
+  category_id: 
+  description: Error 281 is encountered when saving a recipe
+  tracker_id: 1
+  assigned_to_id: 3
+  author_id: 2
+  status_id: 1
+  start_date: <%= 15.day.ago.to_date.to_s(:db) %>
+  due_date: <%= 5.day.ago.to_date.to_s(:db) %>
+  root_id: 3
+  lft: 1
+  rgt: 2
+issues_004: 
+  created_on: <%= 5.days.ago.to_s(:db) %>
+  project_id: 2
+  updated_on: <%= 2.days.ago.to_s(:db) %>
+  priority_id: 4
+  subject: Issue on project 2
+  id: 4
+  fixed_version_id: 
+  category_id: 
+  description: Issue on project 2
+  tracker_id: 1
+  assigned_to_id: 2
+  author_id: 2
+  status_id: 1
+  root_id: 4
+  lft: 1
+  rgt: 2
+issues_005: 
+  created_on: <%= 5.days.ago.to_s(:db) %>
+  project_id: 3
+  updated_on: <%= 2.days.ago.to_s(:db) %>
+  priority_id: 4
+  subject: Subproject issue
+  id: 5
+  fixed_version_id: 
+  category_id: 
+  description: This is an issue on a cookbook subproject
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 1
+  root_id: 5
+  lft: 1
+  rgt: 2
+issues_006: 
+  created_on: <%= 1.minute.ago.to_s(:db) %>
+  project_id: 5
+  updated_on: <%= 1.minute.ago.to_s(:db) %>
+  priority_id: 4
+  subject: Issue of a private subproject
+  id: 6
+  fixed_version_id: 
+  category_id: 
+  description: This is an issue of a private subproject of cookbook
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 1
+  start_date: <%= Date.today.to_s(:db) %>
+  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
+  root_id: 6
+  lft: 1
+  rgt: 2
+issues_007: 
+  created_on: <%= 10.days.ago.to_s(:db) %>
+  project_id: 1
+  updated_on: <%= 10.days.ago.to_s(:db) %>
+  priority_id: 5
+  subject: Issue due today
+  id: 7
+  fixed_version_id: 
+  category_id: 
+  description: This is an issue that is due today
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 1
+  start_date: <%= 10.days.ago.to_s(:db) %>
+  due_date: <%= Date.today.to_s(:db) %>
+  lock_version: 0
+  root_id: 7
+  lft: 1
+  rgt: 2
+issues_008: 
+  created_on: <%= 10.days.ago.to_s(:db) %>
+  project_id: 1
+  updated_on: <%= 10.days.ago.to_s(:db) %>
+  priority_id: 5
+  subject: Closed issue
+  id: 8
+  fixed_version_id: 
+  category_id: 
+  description: This is a closed issue.
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 5
+  start_date: 
+  due_date: 
+  lock_version: 0
+  root_id: 8
+  lft: 1
+  rgt: 2
+  closed_on: <%= 3.days.ago.to_s(:db) %>
+issues_009: 
+  created_on: <%= 1.minute.ago.to_s(:db) %>
+  project_id: 5
+  updated_on: <%= 1.minute.ago.to_s(:db) %>
+  priority_id: 5
+  subject: Blocked Issue
+  id: 9
+  fixed_version_id: 
+  category_id: 
+  description: This is an issue that is blocked by issue #10
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 1
+  start_date: <%= Date.today.to_s(:db) %>
+  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
+  root_id: 9
+  lft: 1
+  rgt: 2
+issues_010: 
+  created_on: <%= 1.minute.ago.to_s(:db) %>
+  project_id: 5
+  updated_on: <%= 1.minute.ago.to_s(:db) %>
+  priority_id: 5
+  subject: Issue Doing the Blocking
+  id: 10
+  fixed_version_id: 
+  category_id: 
+  description: This is an issue that blocks issue #9
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 1
+  start_date: <%= Date.today.to_s(:db) %>
+  due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
+  root_id: 10
+  lft: 1
+  rgt: 2
+issues_011: 
+  created_on: <%= 3.days.ago.to_s(:db) %>
+  project_id: 1
+  updated_on: <%= 1.day.ago.to_s(:db) %>
+  priority_id: 5
+  subject: Closed issue on a closed version
+  id: 11
+  fixed_version_id: 1 
+  category_id: 1
+  description:
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 5
+  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
+  due_date:
+  root_id: 11
+  lft: 1
+  rgt: 2
+  closed_on: <%= 1.day.ago.to_s(:db) %>
+issues_012: 
+  created_on: <%= 3.days.ago.to_s(:db) %>
+  project_id: 1
+  updated_on: <%= 1.day.ago.to_s(:db) %>
+  priority_id: 5
+  subject: Closed issue on a locked version
+  id: 12
+  fixed_version_id: 2 
+  category_id: 1
+  description:
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 3
+  status_id: 5
+  start_date: <%= 1.day.ago.to_date.to_s(:db) %>
+  due_date:
+  root_id: 12
+  lft: 1
+  rgt: 2
+  closed_on: <%= 1.day.ago.to_s(:db) %>
+issues_013:
+  created_on: <%= 5.days.ago.to_s(:db) %>
+  project_id: 3
+  updated_on: <%= 2.days.ago.to_s(:db) %>
+  priority_id: 4
+  subject: Subproject issue two
+  id: 13
+  fixed_version_id: 
+  category_id: 
+  description: This is a second issue on a cookbook subproject
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 1
+  root_id: 13
+  lft: 1
+  rgt: 2
+issues_014:
+  id: 14
+  created_on: <%= 15.days.ago.to_s(:db) %>
+  project_id: 3
+  updated_on: <%= 15.days.ago.to_s(:db) %>
+  priority_id: 5
+  subject: Private issue on public project
+  fixed_version_id: 
+  category_id: 
+  description: This is a private issue
+  tracker_id: 1
+  assigned_to_id: 
+  author_id: 2
+  status_id: 1
+  is_private: true
+  root_id: 14
+  lft: 1
+  rgt: 2
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/75/757babb19cbbfc71f08831b6bce5cad46e54487c.svn-base
--- /dev/null
+++ b/.svn/pristine/75/757babb19cbbfc71f08831b6bce5cad46e54487c.svn-base
@@ -0,0 +1,268 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+# Copyright (C) 2007  Patrick Aljord patcito@Å‹mail.com
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/git_adapter'
+
+class Repository::Git < Repository
+  attr_protected :root_url
+  validates_presence_of :url
+
+  def self.human_attribute_name(attribute_key_name, *args)
+    attr_name = attribute_key_name.to_s
+    if attr_name == "url"
+      attr_name = "path_to_repository"
+    end
+    super(attr_name, *args)
+  end
+
+  def self.scm_adapter_class
+    Redmine::Scm::Adapters::GitAdapter
+  end
+
+  def self.scm_name
+    'Git'
+  end
+
+  def report_last_commit
+    extra_report_last_commit
+  end
+
+  def extra_report_last_commit
+    return false if extra_info.nil?
+    v = extra_info["extra_report_last_commit"]
+    return false if v.nil?
+    v.to_s != '0'
+  end
+
+  def supports_directory_revisions?
+    true
+  end
+
+  def supports_revision_graph?
+    true
+  end
+
+  def repo_log_encoding
+    'UTF-8'
+  end
+
+  # Returns the identifier for the given git changeset
+  def self.changeset_identifier(changeset)
+    changeset.scmid
+  end
+
+  # Returns the readable identifier for the given git changeset
+  def self.format_changeset_identifier(changeset)
+    changeset.revision[0, 8]
+  end
+
+  def branches
+    scm.branches
+  end
+
+  def tags
+    scm.tags
+  end
+
+  def default_branch
+    scm.default_branch
+  rescue Exception => e
+    logger.error "git: error during get default branch: #{e.message}"
+    nil
+  end
+
+  def find_changeset_by_name(name)
+    if name.present?
+      changesets.where(:revision => name.to_s).first ||
+        changesets.where('scmid LIKE ?', "#{name}%").first
+    end
+  end
+
+  def entries(path=nil, identifier=nil)
+    entries = scm.entries(path, identifier, :report_last_commit => extra_report_last_commit)
+    load_entries_changesets(entries)
+    entries
+  end
+
+  # With SCMs that have a sequential commit numbering,
+  # such as Subversion and Mercurial,
+  # Redmine is able to be clever and only fetch changesets
+  # going forward from the most recent one it knows about.
+  #
+  # However, Git does not have a sequential commit numbering.
+  #
+  # In order to fetch only new adding revisions,
+  # Redmine needs to save "heads".
+  #
+  # In Git and Mercurial, revisions are not in date order.
+  # Redmine Mercurial fixed issues.
+  #    * Redmine Takes Too Long On Large Mercurial Repository
+  #      http://www.redmine.org/issues/3449
+  #    * Sorting for changesets might go wrong on Mercurial repos
+  #      http://www.redmine.org/issues/3567
+  #
+  # Database revision column is text, so Redmine can not sort by revision.
+  # Mercurial has revision number, and revision number guarantees revision order.
+  # Redmine Mercurial model stored revisions ordered by database id to database.
+  # So, Redmine Mercurial model can use correct ordering revisions.
+  #
+  # Redmine Mercurial adapter uses "hg log -r 0:tip --limit 10"
+  # to get limited revisions from old to new.
+  # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
+  #
+  # The repository can still be fully reloaded by calling #clear_changesets
+  # before fetching changesets (eg. for offline resync)
+  def fetch_changesets
+    scm_brs = branches
+    return if scm_brs.nil? || scm_brs.empty?
+
+    h1 = extra_info || {}
+    h  = h1.dup
+    repo_heads = scm_brs.map{ |br| br.scmid }
+    h["heads"] ||= []
+    prev_db_heads = h["heads"].dup
+    if prev_db_heads.empty?
+      prev_db_heads += heads_from_branches_hash
+    end
+    return if prev_db_heads.sort == repo_heads.sort
+
+    h["db_consistent"]  ||= {}
+    if changesets.count == 0
+      h["db_consistent"]["ordering"] = 1
+      merge_extra_info(h)
+      self.save
+    elsif ! h["db_consistent"].has_key?("ordering")
+      h["db_consistent"]["ordering"] = 0
+      merge_extra_info(h)
+      self.save
+    end
+    save_revisions(prev_db_heads, repo_heads)
+  end
+
+  def save_revisions(prev_db_heads, repo_heads)
+    h = {}
+    opts = {}
+    opts[:reverse]  = true
+    opts[:excludes] = prev_db_heads
+    opts[:includes] = repo_heads
+
+    revisions = scm.revisions('', nil, nil, opts)
+    return if revisions.blank?
+
+    # Make the search for existing revisions in the database in a more sufficient manner
+    #
+    # Git branch is the reference to the specific revision.
+    # Git can *delete* remote branch and *re-push* branch.
+    #
+    #  $ git push remote :branch
+    #  $ git push remote branch
+    #
+    # After deleting branch, revisions remain in repository until "git gc".
+    # On git 1.7.2.3, default pruning date is 2 weeks.
+    # So, "git log --not deleted_branch_head_revision" return code is 0.
+    #
+    # After re-pushing branch, "git log" returns revisions which are saved in database.
+    # So, Redmine needs to scan revisions and database every time.
+    #
+    # This is replacing the one-after-one queries.
+    # Find all revisions, that are in the database, and then remove them from the revision array.
+    # Then later we won't need any conditions for db existence.
+    # Query for several revisions at once, and remove them from the revisions array, if they are there.
+    # Do this in chunks, to avoid eventual memory problems (in case of tens of thousands of commits).
+    # If there are no revisions (because the original code's algorithm filtered them),
+    # then this part will be stepped over.
+    # We make queries, just if there is any revision.
+    limit = 100
+    offset = 0
+    revisions_copy = revisions.clone # revisions will change
+    while offset < revisions_copy.size
+      recent_changesets_slice = changesets.find(
+                                     :all,
+                                     :conditions => [
+                                        'scmid IN (?)',
+                                        revisions_copy.slice(offset, limit).map{|x| x.scmid}
+                                      ]
+                                    )
+      # Subtract revisions that redmine already knows about
+      recent_revisions = recent_changesets_slice.map{|c| c.scmid}
+      revisions.reject!{|r| recent_revisions.include?(r.scmid)}
+      offset += limit
+    end
+
+    revisions.each do |rev|
+      transaction do
+        # There is no search in the db for this revision, because above we ensured,
+        # that it's not in the db.
+        save_revision(rev)
+      end
+    end
+    h["heads"] = repo_heads.dup
+    merge_extra_info(h)
+    self.save
+  end
+  private :save_revisions
+
+  def save_revision(rev)
+    parents = (rev.parents || []).collect{|rp| find_changeset_by_name(rp)}.compact
+    changeset = Changeset.create(
+              :repository   => self,
+              :revision     => rev.identifier,
+              :scmid        => rev.scmid,
+              :committer    => rev.author,
+              :committed_on => rev.time,
+              :comments     => rev.message,
+              :parents      => parents
+              )
+    unless changeset.new_record?
+      rev.paths.each { |change| changeset.create_change(change) }
+    end
+    changeset
+  end
+  private :save_revision
+
+  def heads_from_branches_hash
+    h1 = extra_info || {}
+    h  = h1.dup
+    h["branches"] ||= {}
+    h['branches'].map{|br, hs| hs['last_scmid']}
+  end
+
+  def latest_changesets(path,rev,limit=10)
+    revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
+    return [] if revisions.nil? || revisions.empty?
+
+    changesets.find(
+      :all,
+      :conditions => [
+        "scmid IN (?)",
+        revisions.map!{|c| c.scmid}
+      ]
+    )
+  end
+
+  def clear_extra_info_of_changesets
+    return if extra_info.nil?
+    v = extra_info["extra_report_last_commit"]
+    write_attribute(:extra_info, nil)
+    h = {}
+    h["extra_report_last_commit"] = v
+    merge_extra_info(h)
+    self.save
+  end
+  private :clear_extra_info_of_changesets
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/75/7582ac57d0446c5241d409e5e3670c3e4ce6c265.svn-base
--- a/.svn/pristine/75/7582ac57d0446c5241d409e5e3670c3e4ce6c265.svn-base
+++ /dev/null
@@ -1,1020 +0,0 @@
-# Galician (Spain) for Ruby on Rails
-# by Marcos Arias Pena (markus@agil-e.com)
-
-gl:
-  number:
-    format:
-      separator: "," 
-      delimiter: "." 
-      precision: 3
-
-    currency:
-      format:
-        format: "%n %u" 
-        unit: "â‚¬" 
-        separator: "," 
-        delimiter: "." 
-        precision: 2
-
-    percentage:
-      format:
-        # separator: 
-        delimiter: "" 
-        # precision: 
-
-    precision:
-      format:
-        # separator:
-        delimiter: "" 
-        # precision:
-
-    human:
-      format:
-        # separator: 
-        delimiter: "" 
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-  
-  
-  direction: ltr
-  date:
-    formats:
-      default:  "%e/%m/%Y"
-      short:    "%e %b"
-      long:     "%A %e de %B de %Y"
-    day_names:        [Domingo, Luns, Martes, MÃ©rcores, Xoves, Venres, SÃ¡bado]
-    abbr_day_names:   [Dom, Lun, Mar, Mer, Xov, Ven, Sab]
-    month_names:      [~, Xaneiro, Febreiro, Marzo, Abril, Maio, Xunio, Xullo, Agosto, Setembro, Outubro, Novembro, Decembro]
-    abbr_month_names: [~, Xan, Feb, Maz, Abr, Mai, Xun, Xul, Ago, Set, Out, Nov, Dec]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default:    "%A, %e de %B de %Y, %H:%M hs"
-      time:       "%H:%M hs"
-      short:      "%e/%m, %H:%M hs"
-      long:       "%A %e de %B de %Y Ã¡s %H:%M horas"
-    
-    am: ''
-    pm: ''
-    
-  datetime:
-    distance_in_words:
-      half_a_minute: 'medio minuto'
-      less_than_x_seconds:
-        zero: 'menos dun segundo'
-        one: '1 segundo'
-        few: 'poucos segundos'
-        other: '%{count} segundos'
-      x_seconds:
-        one: '1 segundo'
-        other: '%{count} segundos'
-      less_than_x_minutes:
-        zero: 'menos dun minuto'
-        one: '1 minuto'
-        other: '%{count} minutos'
-      x_minutes:
-        one: '1 minuto'
-        other: '%{count} minuto'
-      about_x_hours:
-        one: 'aproximadamente unha hora'
-        other: '%{count} horas'
-      x_days:
-        one: '1 dÃ­a'
-        other: '%{count} dÃ­as'
-      x_weeks:
-        one: '1 semana'
-        other: '%{count} semanas'
-      about_x_months:
-        one: 'aproximadamente 1 mes'
-        other: '%{count} meses'
-      x_months:
-        one: '1 mes'
-        other: '%{count} meses'
-      about_x_years:
-        one: 'aproximadamente 1 ano'
-        other: '%{count} anos'
-      over_x_years:
-        one: 'mÃ¡is dun ano'
-        other: '%{count} anos'
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-      now: 'agora'
-      today: 'hoxe'
-      tomorrow: 'maÃ±Ã¡'
-      in: 'dentro de'
-  
-  support:
-    array:
-      sentence_connector: e
-
-  activerecord:
-    models:
-    attributes:
-    errors:
-      template:
-        header:
-          one: "1 erro evitou que se poidese gardar o %{model}"
-          other: "%{count} erros evitaron que se poidese gardar o %{model}"
-        body: "AtopÃ¡ronse os seguintes problemas:"
-      messages:
-        inclusion: "non estÃ¡ incluido na lista"
-        exclusion: "xa existe"
-        invalid: "non Ã© vÃ¡lido"
-        confirmation: "non coincide coa confirmaciÃ³n"
-        accepted: "debe ser aceptado"
-        empty: "non pode estar valeiro"
-        blank: "non pode estar en blanco"
-        too_long: "Ã© demasiado longo (non mÃ¡is de %{count} carÃ¡cteres)"
-        too_short: "Ã© demasiado curto (non menos de %{count} carÃ¡cteres)"
-        wrong_length: "non ten a lonxitude correcta (debe ser de %{count} carÃ¡cteres)"
-        taken: "non estÃ¡ dispoÃ±ible"
-        not_a_number: "non Ã© un nÃºmero"
-        greater_than: "debe ser maior que %{count}"
-        greater_than_or_equal_to: "debe ser maior ou igual que %{count}"
-        equal_to: "debe ser igual a %{count}"
-        less_than: "debe ser menor que %{count}"
-        less_than_or_equal_to: "debe ser menor ou igual que %{count}"
-        odd: "debe ser par"
-        even: "debe ser impar"
-        greater_than_start_date: "debe ser posterior Ã¡ data de comezo"
-        not_same_project: "non pertence ao mesmo proxecto"
-        circular_dependency: "Esta relaciÃ³n poderÃ­a crear unha dependencia circular"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: Por favor seleccione
-  
-  button_activate: Activar
-  button_add: Engadir
-  button_annotate: Anotar
-  button_apply: Aceptar
-  button_archive: Arquivar
-  button_back: AtrÃ¡s
-  button_cancel: Cancelar
-  button_change: Cambiar
-  button_change_password: Cambiar contrasinal
-  button_check_all: Seleccionar todo
-  button_clear: Anular
-  button_configure: Configurar
-  button_copy: Copiar
-  button_create: Crear
-  button_delete: Borrar
-  button_download: Descargar
-  button_edit: Modificar
-  button_list: Listar
-  button_lock: Bloquear
-  button_log_time: Tempo dedicado
-  button_login: ConexiÃ³n
-  button_move: Mover
-  button_quote: Citar
-  button_rename: Renomear
-  button_reply: Respostar
-  button_reset: Restablecer
-  button_rollback: Volver a esta versiÃ³n
-  button_save: Gardar
-  button_sort: Ordenar
-  button_submit: Aceptar
-  button_test: Probar
-  button_unarchive: Desarquivar
-  button_uncheck_all: Non seleccionar nada
-  button_unlock: Desbloquear
-  button_unwatch: Non monitorizar
-  button_update: Actualizar
-  button_view: Ver
-  button_watch: Monitorizar
-  default_activity_design: DeseÃ±o
-  default_activity_development: Desenvolvemento
-  default_doc_category_tech: DocumentaciÃ³n tÃ©cnica
-  default_doc_category_user: DocumentaciÃ³n de usuario
-  default_issue_status_in_progress: In Progress
-  default_issue_status_closed: Pechada
-  default_issue_status_feedback: Comentarios
-  default_issue_status_new: Nova
-  default_issue_status_rejected: Rexeitada
-  default_issue_status_resolved: Resolta
-  default_priority_high: Alta
-  default_priority_immediate: Inmediata
-  default_priority_low: Baixa
-  default_priority_normal: Normal
-  default_priority_urgent: Urxente
-  default_role_developer: Desenvolvedor
-  default_role_manager: Xefe de proxecto
-  default_role_reporter: Informador
-  default_tracker_bug: Erros
-  default_tracker_feature: Tarefas
-  default_tracker_support: Soporte
-  enumeration_activities: Actividades (tempo dedicado)
-  enumeration_doc_categories: CategorÃ­as do documento
-  enumeration_issue_priorities: Prioridade das peticiÃ³ns
-  error_can_t_load_default_data: "Non se puido cargar a configuraciÃ³n por defecto: %{value}"
-  error_issue_not_found_in_project: 'A peticiÃ³n non se atopa ou non estÃ¡ asociada a este proxecto'
-  error_scm_annotate: "Non existe a entrada ou non se puido anotar"
-  error_scm_command_failed: "Aconteceu un erro ao acceder Ã³ repositorio: %{value}"
-  error_scm_not_found: "A entrada e/ou revisiÃ³n non existe no repositorio."
-  field_account: Conta
-  field_activity: Actividade
-  field_admin: Administrador
-  field_assignable: PÃ³dense asignar peticiÃ³ns a este perfil
-  field_assigned_to: Asignado a
-  field_attr_firstname: Atributo do nome
-  field_attr_lastname: Atributo do apelido
-  field_attr_login: Atributo do identificador
-  field_attr_mail: Atributo do Email
-  field_auth_source: Modo de identificaciÃ³n
-  field_author: Autor
-  field_base_dn: DN base
-  field_category: CategorÃ­a
-  field_column_names: Columnas
-  field_comments: Comentario
-  field_comments_sorting: Mostrar comentarios
-  field_created_on: Creado
-  field_default_value: Estado por defecto
-  field_delay: Retraso
-  field_description: DescriciÃ³n
-  field_done_ratio: "% Realizado"
-  field_downloads: Descargas
-  field_due_date: Data fin
-  field_effective_date: Data
-  field_estimated_hours: Tempo estimado
-  field_field_format: Formato
-  field_filename: Arquivo
-  field_filesize: TamaÃ±o
-  field_firstname: Nome
-  field_fixed_version: VersiÃ³n prevista
-  field_hide_mail: Ocultar a miÃ±a direcciÃ³n de correo
-  field_homepage: Sitio web
-  field_host: AnfitriÃ³n
-  field_hours: Horas
-  field_identifier: Identificador
-  field_is_closed: PeticiÃ³n resolta
-  field_is_default: Estado por defecto
-  field_is_filter: Usado como filtro
-  field_is_for_all: Para todos os proxectos
-  field_is_in_roadmap: Consultar as peticiÃ³ns na planificaciÃ³n
-  field_is_public: PÃºblico
-  field_is_required: Obrigatorio
-  field_issue: PeticiÃ³n
-  field_issue_to: PeticiÃ³n relacionada
-  field_language: Idioma
-  field_last_login_on: Ãšltima conexiÃ³n
-  field_lastname: Apelido
-  field_login: Identificador
-  field_mail: Correo electrÃ³nico
-  field_mail_notification: NotificaciÃ³ns por correo
-  field_max_length: Lonxitude mÃ¡xima
-  field_min_length: Lonxitude mÃ­nima
-  field_name: Nome
-  field_new_password: Novo contrasinal
-  field_notes: Notas
-  field_onthefly: CreaciÃ³n do usuario "ao voo"
-  field_parent: Proxecto pai
-  field_parent_title: PÃ¡xina pai
-  field_password: Contrasinal
-  field_password_confirmation: ConfirmaciÃ³n
-  field_port: Porto
-  field_possible_values: Valores posibles
-  field_priority: Prioridade
-  field_project: Proxecto
-  field_redirect_existing_links: Redireccionar enlaces existentes
-  field_regexp: ExpresiÃ³n regular
-  field_role: Perfil
-  field_searchable: IncluÃ­r nas bÃºsquedas
-  field_spent_on: Data
-  field_start_date: Data de inicio
-  field_start_page: PÃ¡xina principal
-  field_status: Estado
-  field_subject: Tema
-  field_subproject: Proxecto secundario
-  field_summary: Resumo
-  field_time_zone: Zona horaria
-  field_title: TÃ­tulo
-  field_tracker: Tipo
-  field_type: Tipo
-  field_updated_on: Actualizado
-  field_url: URL
-  field_user: Usuario
-  field_value: Valor
-  field_version: VersiÃ³n
-  general_csv_decimal_separator: ','
-  general_csv_encoding: ISO-8859-15
-  general_csv_separator: ';'
-  general_first_day_of_week: '1'
-  general_lang_name: 'Galego'
-  general_pdf_encoding: UTF-8
-  general_text_No: 'Non'
-  general_text_Yes: 'Si'
-  general_text_no: 'non'
-  general_text_yes: 'si'
-  gui_validation_error: 1 erro
-  gui_validation_error_plural: "%{count} erros"
-  label_activity: Actividade
-  label_add_another_file: Engadir outro arquivo
-  label_add_note: Engadir unha nota
-  label_added: engadido
-  label_added_time_by: "Engadido por %{author} fai %{age}"
-  label_administration: AdministraciÃ³n
-  label_age: Idade
-  label_ago: fai
-  label_all: todos
-  label_all_time: todo o tempo
-  label_all_words: TÃ³dalas palabras
-  label_and_its_subprojects: "%{value} e proxectos secundarios"
-  label_applied_status: Aplicar estado
-  label_assigned_to_me_issues: PeticiÃ³ns asignadas a min
-  label_associated_revisions: RevisiÃ³ns asociadas
-  label_attachment: Arquivo
-  label_attachment_delete: Borrar o arquivo
-  label_attachment_new: Novo arquivo
-  label_attachment_plural: Arquivos
-  label_attribute: Atributo
-  label_attribute_plural: Atributos
-  label_auth_source: Modo de autenticaciÃ³n
-  label_auth_source_new: Novo modo de autenticaciÃ³n
-  label_auth_source_plural: Modos de autenticaciÃ³n
-  label_authentication: AutenticaciÃ³n
-  label_blocked_by: bloqueado por
-  label_blocks: bloquea a
-  label_board: Foro
-  label_board_new: Novo foro
-  label_board_plural: Foros
-  label_boolean: Booleano
-  label_browse: Ollar
-  label_bulk_edit_selected_issues: Editar as peticiÃ³ns seleccionadas
-  label_calendar: Calendario
-  label_change_plural: Cambios
-  label_change_properties: Cambiar propiedades
-  label_change_status: Cambiar o estado
-  label_change_view_all: Ver tÃ³dolos cambios
-  label_changes_details: Detalles de tÃ³dolos cambios
-  label_changeset_plural: Cambios
-  label_chronological_order: En orde cronolÃ³xica
-  label_closed_issues: pechada
-  label_closed_issues_plural: pechadas
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_comment: Comentario
-  label_comment_add: Engadir un comentario
-  label_comment_added: Comentario engadido
-  label_comment_delete: Borrar comentarios
-  label_comment_plural: Comentarios
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_commits_per_author: Commits por autor
-  label_commits_per_month: Commits por mes
-  label_confirmation: ConfirmaciÃ³n
-  label_contains: conten
-  label_copied: copiado
-  label_copy_workflow_from: Copiar fluxo de traballo dende
-  label_current_status: Estado actual
-  label_current_version: VersiÃ³n actual
-  label_custom_field: Campo personalizado
-  label_custom_field_new: Novo campo personalizado
-  label_custom_field_plural: Campos personalizados
-  label_date: Data
-  label_date_from: Dende
-  label_date_range: Rango de datas
-  label_date_to: Ata
-  label_day_plural: dÃ­as
-  label_default: Por defecto
-  label_default_columns: Columnas por defecto
-  label_deleted: suprimido
-  label_details: Detalles
-  label_diff_inline: en liÃ±a
-  label_diff_side_by_side: cara a cara
-  label_disabled: deshabilitado
-  label_display_per_page: "Por pÃ¡xina: %{value}"
-  label_document: Documento
-  label_document_added: Documento engadido
-  label_document_new: Novo documento
-  label_document_plural: Documentos
-  label_download: "%{count} Descarga"
-  label_download_plural: "%{count} Descargas"
-  label_downloads_abbr: D/L
-  label_duplicated_by: duplicada por
-  label_duplicates: duplicada de
-  label_end_to_end: fin a fin
-  label_end_to_start: fin a principio
-  label_enumeration_new: Novo valor
-  label_enumerations: Listas de valores
-  label_environment: Entorno
-  label_equals: igual
-  label_example: Exemplo
-  label_export_to: 'Exportar a:'
-  label_f_hour: "%{value} hora"
-  label_f_hour_plural: "%{value} horas"
-  label_feed_plural: Feeds
-  label_feeds_access_key_created_on: "Clave de acceso por RSS creada fai %{value}"
-  label_file_added: Arquivo engadido
-  label_file_plural: Arquivos
-  label_filter_add: Engadir o filtro
-  label_filter_plural: Filtros
-  label_float: Flotante
-  label_follows: posterior a
-  label_gantt: Gantt
-  label_general: Xeral
-  label_generate_key: Xerar clave
-  label_help: Axuda
-  label_history: HistÃ³rico
-  label_home: Inicio
-  label_in: en
-  label_in_less_than: en menos que
-  label_in_more_than: en mais que
-  label_incoming_emails: Correos entrantes
-  label_index_by_date: Ãndice por data
-  label_index_by_title: Ãndice por tÃ­tulo
-  label_information: InformaciÃ³n
-  label_information_plural: InformaciÃ³n
-  label_integer: NÃºmero
-  label_internal: Interno
-  label_issue: PeticiÃ³n
-  label_issue_added: PeticiÃ³n engadida
-  label_issue_category: CategorÃ­a das peticiÃ³ns
-  label_issue_category_new: Nova categorÃ­a
-  label_issue_category_plural: CategorÃ­as das peticiÃ³ns
-  label_issue_new: Nova peticiÃ³n
-  label_issue_plural: PeticiÃ³ns
-  label_issue_status: Estado da peticiÃ³n
-  label_issue_status_new: Novo estado
-  label_issue_status_plural: Estados das peticiÃ³ns
-  label_issue_tracking: PeticiÃ³ns
-  label_issue_updated: PeticiÃ³n actualizada
-  label_issue_view_all: Ver tÃ³dalas peticiÃ³ns
-  label_issue_watchers: Seguidores
-  label_issues_by: "PeticiÃ³ns por %{value}"
-  label_jump_to_a_project: Ir ao proxecto...
-  label_language_based: Baseado no idioma
-  label_last_changes: "Ãºltimos %{count} cambios"
-  label_last_login: Ãšltima conexiÃ³n
-  label_last_month: Ãºltimo mes
-  label_last_n_days: "Ãºltimos %{count} dÃ­as"
-  label_last_week: Ãºltima semana
-  label_latest_revision: Ãšltima revisiÃ³n
-  label_latest_revision_plural: Ãšltimas revisiÃ³ns
-  label_ldap_authentication: AutenticaciÃ³n LDAP
-  label_less_than_ago: fai menos de
-  label_list: Lista
-  label_loading: Cargando...
-  label_logged_as: Conectado como
-  label_login: ConexiÃ³n
-  label_logout: DesconexiÃ³n
-  label_max_size: TamaÃ±o mÃ¡ximo
-  label_me: eu mesmo
-  label_member: Membro
-  label_member_new: Novo membro
-  label_member_plural: Membros
-  label_message_last: Ãšltima mensaxe
-  label_message_new: Nova mensaxe
-  label_message_plural: Mensaxes
-  label_message_posted: Mensaxe engadida
-  label_min_max_length: Lonxitude mÃ­n - mÃ¡x
-  label_modification: "%{count} modificaciÃ³n"
-  label_modification_plural: "%{count} modificaciÃ³ns"
-  label_modified: modificado
-  label_module_plural: MÃ³dulos
-  label_month: Mes
-  label_months_from: meses de
-  label_more: Mais
-  label_more_than_ago: fai mais de
-  label_my_account: A miÃ±a conta
-  label_my_page: A miÃ±a pÃ¡xina
-  label_my_projects: Os meus proxectos
-  label_new: Novo
-  label_new_statuses_allowed: Novos estados autorizados
-  label_news: Noticia
-  label_news_added: Noticia engadida
-  label_news_latest: Ãšltimas noticias
-  label_news_new: Nova noticia
-  label_news_plural: Noticias
-  label_news_view_all: Ver tÃ³dalas noticias
-  label_next: Seguinte
-  label_no_change_option: (Sen cambios)
-  label_no_data: NingÃºn dato a mostrar
-  label_nobody: ninguÃ©n
-  label_none: ningÃºn
-  label_not_contains: non conten
-  label_not_equals: non igual
-  label_open_issues: aberta
-  label_open_issues_plural: abertas
-  label_optional_description: DescriciÃ³n opcional
-  label_options: OpciÃ³ns
-  label_overall_activity: Actividade global
-  label_overview: Vistazo
-  label_password_lost: Â¿Esqueciches o contrasinal?
-  label_per_page: Por pÃ¡xina
-  label_permissions: Permisos
-  label_permissions_report: Informe de permisos
-  label_personalize_page: Personalizar esta pÃ¡xina
-  label_planning: PlanificaciÃ³n
-  label_please_login: ConexiÃ³n
-  label_plugins: ExtensiÃ³ns
-  label_precedes: anterior a
-  label_preferences: Preferencias
-  label_preview: Previsualizar
-  label_previous: Anterior
-  label_project: Proxecto
-  label_project_all: TÃ³dolos proxectos
-  label_project_latest: Ãšltimos proxectos
-  label_project_new: Novo proxecto
-  label_project_plural: Proxectos
-  label_x_projects:
-    zero:  no projects
-    one:   1 project
-    other: "%{count} projects"
-  label_public_projects: Proxectos pÃºblicos
-  label_query: Consulta personalizada
-  label_query_new: Nova consulta
-  label_query_plural: Consultas personalizadas
-  label_read: Ler...
-  label_register: Rexistrar
-  label_registered_on: Inscrito o
-  label_registration_activation_by_email: activaciÃ³n de conta por correo
-  label_registration_automatic_activation: activaciÃ³n automÃ¡tica de conta
-  label_registration_manual_activation: activaciÃ³n manual de conta
-  label_related_issues: PeticiÃ³ns relacionadas
-  label_relates_to: relacionada con
-  label_relation_delete: Eliminar relaciÃ³n
-  label_relation_new: Nova relaciÃ³n
-  label_renamed: renomeado
-  label_reply_plural: Respostas
-  label_report: Informe
-  label_report_plural: Informes
-  label_reported_issues: PeticiÃ³ns rexistradas por min
-  label_repository: Repositorio
-  label_repository_plural: Repositorios
-  label_result_plural: Resultados
-  label_reverse_chronological_order: En orde cronolÃ³xica inversa
-  label_revision: RevisiÃ³n
-  label_revision_plural: RevisiÃ³ns
-  label_roadmap: PlanificaciÃ³n
-  label_roadmap_due_in: "Remata en %{value}"
-  label_roadmap_no_issues: Non hai peticiÃ³ns para esta versiÃ³n
-  label_roadmap_overdue: "%{value} tarde"
-  label_role: Perfil
-  label_role_and_permissions: Perfiles e permisos
-  label_role_new: Novo perfil
-  label_role_plural: Perfiles
-  label_scm: SCM
-  label_search: BÃºsqueda
-  label_search_titles_only: Buscar sÃ³ en tÃ­tulos
-  label_send_information: Enviar informaciÃ³n da conta Ã³ usuario
-  label_send_test_email: Enviar un correo de proba
-  label_settings: ConfiguraciÃ³n
-  label_show_completed_versions: Mostra as versiÃ³ns rematadas
-  label_sort_by: "Ordenar por %{value}"
-  label_sort_higher: Subir
-  label_sort_highest: Primeiro
-  label_sort_lower: Baixar
-  label_sort_lowest: Ãšltimo
-  label_spent_time: Tempo dedicado
-  label_start_to_end: comezo a fin
-  label_start_to_start: comezo a comezo
-  label_statistics: EstatÃ­sticas
-  label_stay_logged_in: Lembrar contrasinal
-  label_string: Texto
-  label_subproject_plural: Proxectos secundarios
-  label_text: Texto largo
-  label_theme: Tema
-  label_this_month: este mes
-  label_this_week: esta semana
-  label_this_year: este ano
-  label_time_tracking: Control de tempo
-  label_today: hoxe
-  label_topic_plural: Temas
-  label_total: Total
-  label_tracker: Tipo
-  label_tracker_new: Novo tipo
-  label_tracker_plural: Tipos de peticiÃ³ns
-  label_updated_time: "Actualizado fai %{value}"
-  label_updated_time_by: "Actualizado por %{author} fai %{age}"
-  label_used_by: Utilizado por
-  label_user: Usuario
-  label_user_activity: "Actividade de %{value}"
-  label_user_mail_no_self_notified: "Non quero ser avisado de cambios feitos por min"
-  label_user_mail_option_all: "Para calquera evento en tÃ³dolos proxectos"
-  label_user_mail_option_selected: "Para calquera evento dos proxectos seleccionados..."
-  label_user_new: Novo usuario
-  label_user_plural: Usuarios
-  label_version: VersiÃ³n
-  label_version_new: Nova versiÃ³n
-  label_version_plural: VersiÃ³ns
-  label_view_diff: Ver diferencias
-  label_view_revisions: Ver as revisiÃ³ns
-  label_watched_issues: PeticiÃ³ns monitorizadas
-  label_week: Semana
-  label_wiki: Wiki
-  label_wiki_edit: Wiki ediciÃ³n
-  label_wiki_edit_plural: Wiki ediciÃ³ns
-  label_wiki_page: Wiki pÃ¡xina
-  label_wiki_page_plural: Wiki pÃ¡xinas
-  label_workflow: Fluxo de traballo
-  label_year: Ano
-  label_yesterday: onte
-  mail_body_account_activation_request: "Inscribiuse un novo usuario (%{value}). A conta estÃ¡ pendente de aprobaciÃ³n:"
-  mail_body_account_information: InformaciÃ³n sobre a sÃºa conta
-  mail_body_account_information_external: "Pode usar a sÃºa conta %{value} para conectarse."
-  mail_body_lost_password: 'Para cambiar o seu contrasinal, faga clic no seguinte enlace:'
-  mail_body_register: 'Para activar a sÃºa conta, faga clic no seguinte enlace:'
-  mail_body_reminder: "%{count} peticiÃ³n(s) asignadas a ti rematan nos prÃ³ximos %{days} dÃ­as:"
-  mail_subject_account_activation_request: "PeticiÃ³n de activaciÃ³n de conta %{value}"
-  mail_subject_lost_password: "O teu contrasinal de %{value}"
-  mail_subject_register: "ActivaciÃ³n da conta de %{value}"
-  mail_subject_reminder: "%{count} peticiÃ³n(s) rematarÃ¡n nos prÃ³ximos %{days} dÃ­as"
-  notice_account_activated: A sÃºa conta foi activada. Xa pode conectarse.
-  notice_account_invalid_creditentials: Usuario ou contrasinal invÃ¡lido.
-  notice_account_lost_email_sent: Enviouse un correo con instruciÃ³ns para elixir un novo contrasinal.
-  notice_account_password_updated: Contrasinal modificado correctamente.
-  notice_account_pending: "A sÃºa conta creouse e estÃ¡ pendente da aprobaciÃ³n por parte do administrador."
-  notice_account_register_done: Conta creada correctamente. Para activala, faga clic sobre o enlace que se lle enviou por correo.
-  notice_account_unknown_email: Usuario descoÃ±ecido.
-  notice_account_updated: Conta actualizada correctamente.
-  notice_account_wrong_password: Contrasinal incorrecto.
-  notice_can_t_change_password: Esta conta utiliza unha fonte de autenticaciÃ³n externa. Non Ã© posible cambiar o contrasinal.
-  notice_default_data_loaded: ConfiguraciÃ³n por defecto cargada correctamente.
-  notice_email_error: "Ocorreu un error enviando o correo (%{value})"
-  notice_email_sent: "Enviouse un correo a %{value}"
-  notice_failed_to_save_issues: "Imposible gravar %{count} peticiÃ³n(s) de %{total} seleccionada(s): %{ids}."
-  notice_feeds_access_key_reseted: A sÃºa clave de acceso para RSS reiniciouse.
-  notice_file_not_found: A pÃ¡xina Ã¡ que tenta acceder non existe.
-  notice_locking_conflict: Os datos modificÃ¡ronse por outro usuario.
-  notice_no_issue_selected: "Ningunha peticiÃ³n seleccionada. Por favor, comprobe a peticiÃ³n que quere modificar"
-  notice_not_authorized: Non ten autorizaciÃ³n para acceder a esta pÃ¡xina.
-  notice_successful_connection: ConexiÃ³n correcta.
-  notice_successful_create: CreaciÃ³n correcta.
-  notice_successful_delete: Borrado correcto.
-  notice_successful_update: ModificaciÃ³n correcta.
-  notice_unable_delete_version: Non se pode borrar a versiÃ³n
-  permission_add_issue_notes: Engadir notas
-  permission_add_issue_watchers: Engadir seguidores
-  permission_add_issues: Engadir peticiÃ³ns
-  permission_add_messages: Enviar mensaxes
-  permission_browse_repository: Ollar repositorio
-  permission_comment_news: Comentar noticias
-  permission_commit_access: Acceso de escritura
-  permission_delete_issues: Borrar peticiÃ³ns
-  permission_delete_messages: Borrar mensaxes
-  permission_delete_own_messages: Borrar mensaxes propios
-  permission_delete_wiki_pages: Borrar pÃ¡xinas wiki
-  permission_delete_wiki_pages_attachments: Borrar arquivos
-  permission_edit_issue_notes: Modificar notas
-  permission_edit_issues: Modificar peticiÃ³ns
-  permission_edit_messages: Modificar mensaxes
-  permission_edit_own_issue_notes: Modificar notas propias
-  permission_edit_own_messages: Editar mensaxes propios
-  permission_edit_own_time_entries: Modificar tempos dedicados propios
-  permission_edit_project: Modificar proxecto
-  permission_edit_time_entries: Modificar tempos dedicados
-  permission_edit_wiki_pages: Modificar pÃ¡xinas wiki
-  permission_log_time: Anotar tempo dedicado
-  permission_manage_boards: Administrar foros
-  permission_manage_categories: Administrar categorÃ­as de peticiÃ³ns
-  permission_manage_documents: Administrar documentos
-  permission_manage_files: Administrar arquivos
-  permission_manage_issue_relations: Administrar relaciÃ³n con outras peticiÃ³ns
-  permission_manage_members: Administrar membros
-  permission_manage_news: Administrar noticias
-  permission_manage_public_queries: Administrar consultas pÃºblicas
-  permission_manage_repository: Administrar repositorio
-  permission_manage_versions: Administrar versiÃ³ns
-  permission_manage_wiki: Administrar wiki
-  permission_move_issues: Mover peticiÃ³ns
-  permission_protect_wiki_pages: Protexer pÃ¡xinas wiki
-  permission_rename_wiki_pages: Renomear pÃ¡xinas wiki
-  permission_save_queries: Gravar consultas
-  permission_select_project_modules: Seleccionar mÃ³dulos do proxecto
-  permission_view_calendar: Ver calendario
-  permission_view_changesets: Ver cambios
-  permission_view_documents: Ver documentos
-  permission_view_files: Ver arquivos
-  permission_view_gantt: Ver diagrama de Gantt
-  permission_view_issue_watchers: Ver lista de seguidores
-  permission_view_messages: Ver mensaxes
-  permission_view_time_entries: Ver tempo dedicado
-  permission_view_wiki_edits: Ver histÃ³rico do wiki
-  permission_view_wiki_pages: Ver wiki
-  project_module_boards: Foros
-  project_module_documents: Documentos
-  project_module_files: Arquivos
-  project_module_issue_tracking: PeticiÃ³ns
-  project_module_news: Noticias
-  project_module_repository: Repositorio
-  project_module_time_tracking: Control de tempo
-  project_module_wiki: Wiki
-  setting_activity_days_default: DÃ­as a mostrar na actividade do proxecto
-  setting_app_subtitle: SubtÃ­tulo da aplicaciÃ³n
-  setting_app_title: TÃ­tulo da aplicaciÃ³n
-  setting_attachment_max_size: TamaÃ±o mÃ¡ximo do arquivo
-  setting_autofetch_changesets: Autorechear os commits do repositorio
-  setting_autologin: ConexiÃ³n automÃ¡tica
-  setting_bcc_recipients: Ocultar as copias de carbÃ³n (bcc)
-  setting_commit_fix_keywords: Palabras clave para a correcciÃ³n
-  setting_commit_ref_keywords: Palabras clave para a referencia
-  setting_cross_project_issue_relations: Permitir relacionar peticiÃ³ns de distintos proxectos
-  setting_date_format: Formato da data
-  setting_default_language: Idioma por defecto
-  setting_default_projects_public: Os proxectos novos son pÃºblicos por defecto
-  setting_diff_max_lines_displayed: NÃºmero mÃ¡ximo de diferencias mostradas
-  setting_display_subprojects_issues: Mostrar por defecto peticiÃ³ns de prox. secundarios no principal
-  setting_emails_footer: Pe de mensaxes
-  setting_enabled_scm: Activar SCM
-  setting_feeds_limit: LÃ­mite de contido para sindicaciÃ³n
-  setting_gravatar_enabled: Usar iconas de usuario (Gravatar)
-  setting_host_name: Nome e ruta do servidor
-  setting_issue_list_default_columns: Columnas por defecto para a lista de peticiÃ³ns
-  setting_issues_export_limit: LÃ­mite de exportaciÃ³n de peticiÃ³ns
-  setting_login_required: RequÃ­rese identificaciÃ³n
-  setting_mail_from: Correo dende o que enviar mensaxes
-  setting_mail_handler_api_enabled: Activar SW para mensaxes entrantes
-  setting_mail_handler_api_key: Clave da API
-  setting_per_page_options: Obxectos por pÃ¡xina
-  setting_plain_text_mail: sÃ³ texto plano (non HTML)
-  setting_protocol: Protocolo
-  setting_self_registration: Rexistro permitido
-  setting_sequential_project_identifiers: Xerar identificadores de proxecto
-  setting_sys_api_enabled: Habilitar SW para a xestiÃ³n do repositorio
-  setting_text_formatting: Formato de texto
-  setting_time_format: Formato de hora
-  setting_user_format: Formato de nome de usuario
-  setting_welcome_text: Texto de benvida
-  setting_wiki_compression: CompresiÃ³n do historial do Wiki
-  status_active: activo
-  status_locked: bloqueado
-  status_registered: rexistrado
-  text_are_you_sure: Â¿EstÃ¡ seguro?
-  text_assign_time_entries_to_project: Asignar as horas Ã³ proxecto
-  text_caracters_maximum: "%{count} caracteres como mÃ¡ximo."
-  text_caracters_minimum: "%{count} caracteres como mÃ­nimo"
-  text_comma_separated: MÃºltiples valores permitidos (separados por coma).
-  text_default_administrator_account_changed: Conta de administrador por defecto modificada
-  text_destroy_time_entries: Borrar as horas
-  text_destroy_time_entries_question: Existen %{hours} horas asignadas Ã¡ peticiÃ³n que quere borrar. Â¿Que quere facer ?
-  text_diff_truncated: '... Diferencia truncada por exceder o mÃ¡ximo tamaÃ±o visualizable.'
-  text_email_delivery_not_configured: "O envÃ­o de correos non estÃ¡ configurado, e as notificaciÃ³ns desactivÃ¡ronse. \n Configure o servidor de SMTP en config/configuration.yml e reinicie a aplicaciÃ³n para activar os cambios."
-  text_enumeration_category_reassign_to: 'Reasignar Ã³ seguinte valor:'
-  text_enumeration_destroy_question: "%{count} obxectos con este valor asignado."
-  text_file_repository_writable: PÃ³dese escribir no repositorio
-  text_issue_added: "PeticiÃ³n %{id} engadida por %{author}."
-  text_issue_category_destroy_assignments: Deixar as peticiÃ³ns sen categorÃ­a
-  text_issue_category_destroy_question: "Algunhas peticiÃ³ns (%{count}) estÃ¡n asignadas a esta categorÃ­a. Â¿Que desexa facer?"
-  text_issue_category_reassign_to: Reasignar as peticiÃ³ns Ã¡ categorÃ­a
-  text_issue_updated: "A peticiÃ³n %{id} actualizouse por %{author}."
-  text_issues_destroy_confirmation: 'Â¿Seguro que quere borrar as peticiÃ³ns seleccionadas?'
-  text_issues_ref_in_commit_messages: Referencia e peticiÃ³n de correcciÃ³n nas mensaxes
-  text_length_between: "Lonxitude entre %{min} e %{max} caracteres."
-  text_load_default_configuration: Cargar a configuraciÃ³n por defecto
-  text_min_max_length_info: 0 para ningunha restriciÃ³n
-  text_no_configuration_data: "Inda non se configuraron perfiles, nin tipos, estados e fluxo de traballo asociado a peticiÃ³ns. RecomÃ©ndase encarecidamente cargar a configuraciÃ³n por defecto. Unha vez cargada, poderÃ¡ modificala."
-  text_project_destroy_confirmation: Â¿EstÃ¡s seguro de querer eliminar o proxecto?
-  text_project_identifier_info: 'Letras minÃºsculas (a-z), nÃºmeros e signos de puntuaciÃ³n permitidos.<br />Unha vez gardado, o identificador non pode modificarse.'
-  text_reassign_time_entries: 'Reasignar as horas a esta peticiÃ³n:'
-  text_regexp_info: ex. ^[A-Z0-9]+$
-  text_repository_usernames_mapping: "Estableza a correspondencia entre os usuarios de Redmine e os presentes no log do repositorio.\nOs usuarios co mesmo nome ou correo en Redmine e no repositorio serÃ¡n asociados automaticamente."
-  text_rmagick_available: RMagick dispoÃ±ible (opcional)
-  text_select_mail_notifications: Seleccionar os eventos a notificar
-  text_select_project_modules: 'Seleccione os mÃ³dulos a activar para este proxecto:'
-  text_status_changed_by_changeset: "Aplicado nos cambios %{value}"
-  text_subprojects_destroy_warning: "Os proxectos secundarios: %{value} tamÃ©n se eliminarÃ¡n"
-  text_tip_issue_begin_day: tarefa que comeza este dÃ­a
-  text_tip_issue_begin_end_day: tarefa que comeza e remata este dÃ­a
-  text_tip_issue_end_day: tarefa que remata este dÃ­a
-  text_tracker_no_workflow: Non hai ningÃºn fluxo de traballo definido para este tipo de peticiÃ³n
-  text_unallowed_characters: Caracteres non permitidos
-  text_user_mail_option: "Dos proxectos non seleccionados, sÃ³ recibirÃ¡ notificaciÃ³ns sobre elementos monitorizados ou elementos nos que estea involucrado (por exemplo, peticiÃ³ns das que vostede sexa autor ou asignadas a vostede)."
-  text_user_wrote: "%{value} escribiu:"
-  text_wiki_destroy_confirmation: Â¿Seguro que quere borrar o wiki e todo o seu contido?
-  text_workflow_edit: Seleccionar un fluxo de traballo para actualizar
-  warning_attachments_not_saved: "%{count} file(s) could not be saved."
-  field_editable: Editable
-  text_plugin_assets_writable: Plugin assets directory writable
-  label_display: Display
-  button_create_and_continue: Create and continue
-  text_custom_field_possible_values_info: 'One line for each value'
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  field_watcher: Watcher
-  setting_openid: Allow OpenID login and registration
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: or login with OpenID
-  field_content: Content
-  label_descending: Descending
-  label_sort: Sort
-  label_ascending: Ascending
-  label_date_from_to: From %{start} to %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
-  text_wiki_page_reassign_children: Reassign child pages to this parent page
-  text_wiki_page_nullify_children: Keep child pages as root pages
-  text_wiki_page_destroy_children: Delete child pages and all their descendants
-  setting_password_min_length: Minimum password length
-  field_group_by: Group results by
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  label_wiki_content_added: Wiki page added
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
-  label_wiki_content_updated: Wiki page updated
-  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
-  permission_add_project: Create project
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  label_view_all_revisions: View all revisions
-  label_tag: Tag
-  label_branch: Branch
-  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
-  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
-  text_journal_changed: "%{label} changed from %{old} to %{new}"
-  text_journal_set_to: "%{label} set to %{value}"
-  text_journal_deleted: "%{label} deleted (%{old})"
-  label_group_plural: Groups
-  label_group: Group
-  label_group_new: New group
-  label_time_entry_plural: Spent time
-  text_journal_added: "%{label} %{value} added"
-  field_active: Active
-  enumeration_system_activity: System Activity
-  permission_delete_issue_watchers: Delete watchers
-  version_status_closed: closed
-  version_status_locked: locked
-  version_status_open: open
-  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
-  label_user_anonymous: Anonymous
-  button_move_and_follow: Move and follow
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_gravatar_default: Default Gravatar image
-  field_sharing: Sharing
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_system: With all projects
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_tree: With project tree
-  label_version_sharing_none: Not shared
-  error_can_not_archive_project: This project can not be archived
-  button_duplicate: Duplicate
-  button_copy_and_follow: Copy and follow
-  label_copy_source: Source
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Same as target
-  label_copy_target: Target
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  error_workflow_copy_source: Please select a source tracker or role
-  label_update_issue_done_ratios: Update issue done ratios
-  setting_start_of_week: Start calendars on
-  permission_view_issues: View Issues
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API access key
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_missing_api_access_key: Missing an API access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  button_show: Show
-  text_line_separated: Multiple values allowed (one line for each value).
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: CodificaciÃ³n das mensaxes de commit
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/75/7589507f7ac535cf051469c3e0cd34a9aef60ed2.svn-base
--- /dev/null
+++ b/.svn/pristine/75/7589507f7ac535cf051469c3e0cd34a9aef60ed2.svn-base
@@ -0,0 +1,12 @@
+class PopulateMemberRoles < ActiveRecord::Migration
+  def self.up
+    MemberRole.delete_all
+    Member.all.each do |member|
+      MemberRole.create!(:member_id => member.id, :role_id => member.role_id)
+    end
+  end
+
+  def self.down
+    MemberRole.delete_all
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/75/75f107e6669aa82c7a67c545bb8556cd17f911cf.svn-base
--- a/.svn/pristine/75/75f107e6669aa82c7a67c545bb8556cd17f911cf.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-desc 'Load Redmine default configuration data. Language is chosen interactively or by setting REDMINE_LANG environment variable.'
-
-namespace :redmine do
-  task :load_default_data => :environment do
-    include Redmine::I18n
-    set_language_if_valid('en')
-
-    envlang = ENV['REDMINE_LANG']
-    if !envlang || !set_language_if_valid(envlang)
-      puts
-      while true
-        print "Select language: "
-        print valid_languages.collect(&:to_s).sort.join(", ")
-        print " [#{current_language}] "
-        STDOUT.flush
-        lang = STDIN.gets.chomp!
-        break if lang.empty?
-        break if set_language_if_valid(lang)
-        puts "Unknown language!"
-      end
-      STDOUT.flush
-      puts "===================================="
-    end
-
-    begin
-      Redmine::DefaultData::Loader.load(current_language)
-      puts "Default configuration data loaded."
-    rescue Redmine::DefaultData::DataAlreadyLoaded => error
-      puts error
-    rescue => error
-      puts "Error: " + error
-      puts "Default configuration data was not loaded."
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/760f88c85efa4fcdc85da6f311991a1e4bd6de1d.svn-base
--- /dev/null
+++ b/.svn/pristine/76/760f88c85efa4fcdc85da6f311991a1e4bd6de1d.svn-base
@@ -0,0 +1,1100 @@
+# Galician (Spain) for Ruby on Rails
+# by Marcos Arias Pena (markus@agil-e.com)
+
+gl:
+  number:
+    format:
+      separator: ","
+      delimiter: "."
+      precision: 3
+
+    currency:
+      format:
+        format: "%n %u"
+        unit: "â‚¬"
+        separator: ","
+        delimiter: "."
+        precision: 2
+
+    percentage:
+      format:
+        # separator:
+        delimiter: ""
+        # precision:
+
+    precision:
+      format:
+        # separator:
+        delimiter: ""
+        # precision:
+
+    human:
+      format:
+        # separator:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  direction: ltr
+  date:
+    formats:
+      default:  "%e/%m/%Y"
+      short:    "%e %b"
+      long:     "%A %e de %B de %Y"
+    day_names:        [Domingo, Luns, Martes, MÃ©rcores, Xoves, Venres, SÃ¡bado]
+    abbr_day_names:   [Dom, Lun, Mar, Mer, Xov, Ven, Sab]
+    month_names:      [~, Xaneiro, Febreiro, Marzo, Abril, Maio, Xunio, Xullo, Agosto, Setembro, Outubro, Novembro, Decembro]
+    abbr_month_names: [~, Xan, Feb, Maz, Abr, Mai, Xun, Xul, Ago, Set, Out, Nov, Dec]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default:    "%A, %e de %B de %Y, %H:%M hs"
+      time:       "%H:%M hs"
+      short:      "%e/%m, %H:%M hs"
+      long:       "%A %e de %B de %Y Ã¡s %H:%M horas"
+
+    am: ''
+    pm: ''
+
+  datetime:
+    distance_in_words:
+      half_a_minute: 'medio minuto'
+      less_than_x_seconds:
+        zero: 'menos dun segundo'
+        one: '1 segundo'
+        few: 'poucos segundos'
+        other: '%{count} segundos'
+      x_seconds:
+        one: '1 segundo'
+        other: '%{count} segundos'
+      less_than_x_minutes:
+        zero: 'menos dun minuto'
+        one: '1 minuto'
+        other: '%{count} minutos'
+      x_minutes:
+        one: '1 minuto'
+        other: '%{count} minuto'
+      about_x_hours:
+        one: 'aproximadamente unha hora'
+        other: '%{count} horas'
+      x_hours:
+        one:   "1 hora"
+        other: "%{count} horas"
+      x_days:
+        one: '1 dÃ­a'
+        other: '%{count} dÃ­as'
+      x_weeks:
+        one: '1 semana'
+        other: '%{count} semanas'
+      about_x_months:
+        one: 'aproximadamente 1 mes'
+        other: '%{count} meses'
+      x_months:
+        one: '1 mes'
+        other: '%{count} meses'
+      about_x_years:
+        one: 'aproximadamente 1 ano'
+        other: '%{count} anos'
+      over_x_years:
+        one: 'mÃ¡is dun ano'
+        other: '%{count} anos'
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+      now: 'agora'
+      today: 'hoxe'
+      tomorrow: 'maÃ±Ã¡'
+      in: 'dentro de'
+
+  support:
+    array:
+      sentence_connector: e
+
+  activerecord:
+    models:
+    attributes:
+    errors:
+      template:
+        header:
+          one: "1 erro evitou que se poidese gardar o %{model}"
+          other: "%{count} erros evitaron que se poidese gardar o %{model}"
+        body: "AtopÃ¡ronse os seguintes problemas:"
+      messages:
+        inclusion: "non estÃ¡ incluido na lista"
+        exclusion: "xa existe"
+        invalid: "non Ã© vÃ¡lido"
+        confirmation: "non coincide coa confirmaciÃ³n"
+        accepted: "debe ser aceptado"
+        empty: "non pode estar valeiro"
+        blank: "non pode estar en blanco"
+        too_long: "Ã© demasiado longo (non mÃ¡is de %{count} carÃ¡cteres)"
+        too_short: "Ã© demasiado curto (non menos de %{count} carÃ¡cteres)"
+        wrong_length: "non ten a lonxitude correcta (debe ser de %{count} carÃ¡cteres)"
+        taken: "non estÃ¡ dispoÃ±ible"
+        not_a_number: "non Ã© un nÃºmero"
+        greater_than: "debe ser maior que %{count}"
+        greater_than_or_equal_to: "debe ser maior ou igual que %{count}"
+        equal_to: "debe ser igual a %{count}"
+        less_than: "debe ser menor que %{count}"
+        less_than_or_equal_to: "debe ser menor ou igual que %{count}"
+        odd: "debe ser par"
+        even: "debe ser impar"
+        greater_than_start_date: "debe ser posterior Ã¡ data de comezo"
+        not_same_project: "non pertence ao mesmo proxecto"
+        circular_dependency: "Esta relaciÃ³n poderÃ­a crear unha dependencia circular"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: Por favor seleccione
+
+  button_activate: Activar
+  button_add: Engadir
+  button_annotate: Anotar
+  button_apply: Aceptar
+  button_archive: Arquivar
+  button_back: AtrÃ¡s
+  button_cancel: Cancelar
+  button_change: Cambiar
+  button_change_password: Cambiar contrasinal
+  button_check_all: Seleccionar todo
+  button_clear: Anular
+  button_configure: Configurar
+  button_copy: Copiar
+  button_create: Crear
+  button_delete: Borrar
+  button_download: Descargar
+  button_edit: Modificar
+  button_list: Listar
+  button_lock: Bloquear
+  button_log_time: Tempo dedicado
+  button_login: ConexiÃ³n
+  button_move: Mover
+  button_quote: Citar
+  button_rename: Renomear
+  button_reply: Respostar
+  button_reset: Restablecer
+  button_rollback: Volver a esta versiÃ³n
+  button_save: Gardar
+  button_sort: Ordenar
+  button_submit: Aceptar
+  button_test: Probar
+  button_unarchive: Desarquivar
+  button_uncheck_all: Non seleccionar nada
+  button_unlock: Desbloquear
+  button_unwatch: Non monitorizar
+  button_update: Actualizar
+  button_view: Ver
+  button_watch: Monitorizar
+  default_activity_design: DeseÃ±o
+  default_activity_development: Desenvolvemento
+  default_doc_category_tech: DocumentaciÃ³n tÃ©cnica
+  default_doc_category_user: DocumentaciÃ³n de usuario
+  default_issue_status_in_progress: In Progress
+  default_issue_status_closed: Pechada
+  default_issue_status_feedback: Comentarios
+  default_issue_status_new: Nova
+  default_issue_status_rejected: Rexeitada
+  default_issue_status_resolved: Resolta
+  default_priority_high: Alta
+  default_priority_immediate: Inmediata
+  default_priority_low: Baixa
+  default_priority_normal: Normal
+  default_priority_urgent: Urxente
+  default_role_developer: Desenvolvedor
+  default_role_manager: Xefe de proxecto
+  default_role_reporter: Informador
+  default_tracker_bug: Erros
+  default_tracker_feature: Tarefas
+  default_tracker_support: Soporte
+  enumeration_activities: Actividades (tempo dedicado)
+  enumeration_doc_categories: CategorÃ­as do documento
+  enumeration_issue_priorities: Prioridade das peticiÃ³ns
+  error_can_t_load_default_data: "Non se puido cargar a configuraciÃ³n por defecto: %{value}"
+  error_issue_not_found_in_project: 'A peticiÃ³n non se atopa ou non estÃ¡ asociada a este proxecto'
+  error_scm_annotate: "Non existe a entrada ou non se puido anotar"
+  error_scm_command_failed: "Aconteceu un erro ao acceder Ã³ repositorio: %{value}"
+  error_scm_not_found: "A entrada e/ou revisiÃ³n non existe no repositorio."
+  field_account: Conta
+  field_activity: Actividade
+  field_admin: Administrador
+  field_assignable: PÃ³dense asignar peticiÃ³ns a este perfil
+  field_assigned_to: Asignado a
+  field_attr_firstname: Atributo do nome
+  field_attr_lastname: Atributo do apelido
+  field_attr_login: Atributo do identificador
+  field_attr_mail: Atributo do Email
+  field_auth_source: Modo de identificaciÃ³n
+  field_author: Autor
+  field_base_dn: DN base
+  field_category: CategorÃ­a
+  field_column_names: Columnas
+  field_comments: Comentario
+  field_comments_sorting: Mostrar comentarios
+  field_created_on: Creado
+  field_default_value: Estado por defecto
+  field_delay: Retraso
+  field_description: DescriciÃ³n
+  field_done_ratio: "% Realizado"
+  field_downloads: Descargas
+  field_due_date: Data fin
+  field_effective_date: Data
+  field_estimated_hours: Tempo estimado
+  field_field_format: Formato
+  field_filename: Arquivo
+  field_filesize: TamaÃ±o
+  field_firstname: Nome
+  field_fixed_version: VersiÃ³n prevista
+  field_hide_mail: Ocultar a miÃ±a direcciÃ³n de correo
+  field_homepage: Sitio web
+  field_host: AnfitriÃ³n
+  field_hours: Horas
+  field_identifier: Identificador
+  field_is_closed: PeticiÃ³n resolta
+  field_is_default: Estado por defecto
+  field_is_filter: Usado como filtro
+  field_is_for_all: Para todos os proxectos
+  field_is_in_roadmap: Consultar as peticiÃ³ns na planificaciÃ³n
+  field_is_public: PÃºblico
+  field_is_required: Obrigatorio
+  field_issue: PeticiÃ³n
+  field_issue_to: PeticiÃ³n relacionada
+  field_language: Idioma
+  field_last_login_on: Ãšltima conexiÃ³n
+  field_lastname: Apelido
+  field_login: Identificador
+  field_mail: Correo electrÃ³nico
+  field_mail_notification: NotificaciÃ³ns por correo
+  field_max_length: Lonxitude mÃ¡xima
+  field_min_length: Lonxitude mÃ­nima
+  field_name: Nome
+  field_new_password: Novo contrasinal
+  field_notes: Notas
+  field_onthefly: CreaciÃ³n do usuario "ao voo"
+  field_parent: Proxecto pai
+  field_parent_title: PÃ¡xina pai
+  field_password: Contrasinal
+  field_password_confirmation: ConfirmaciÃ³n
+  field_port: Porto
+  field_possible_values: Valores posibles
+  field_priority: Prioridade
+  field_project: Proxecto
+  field_redirect_existing_links: Redireccionar enlaces existentes
+  field_regexp: ExpresiÃ³n regular
+  field_role: Perfil
+  field_searchable: IncluÃ­r nas bÃºsquedas
+  field_spent_on: Data
+  field_start_date: Data de inicio
+  field_start_page: PÃ¡xina principal
+  field_status: Estado
+  field_subject: Tema
+  field_subproject: Proxecto secundario
+  field_summary: Resumo
+  field_time_zone: Zona horaria
+  field_title: TÃ­tulo
+  field_tracker: Tipo
+  field_type: Tipo
+  field_updated_on: Actualizado
+  field_url: URL
+  field_user: Usuario
+  field_value: Valor
+  field_version: VersiÃ³n
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-15
+  general_csv_separator: ';'
+  general_first_day_of_week: '1'
+  general_lang_name: 'Galego'
+  general_pdf_encoding: UTF-8
+  general_text_No: 'Non'
+  general_text_Yes: 'Si'
+  general_text_no: 'non'
+  general_text_yes: 'si'
+  label_activity: Actividade
+  label_add_another_file: Engadir outro arquivo
+  label_add_note: Engadir unha nota
+  label_added: engadido
+  label_added_time_by: "Engadido por %{author} fai %{age}"
+  label_administration: AdministraciÃ³n
+  label_age: Idade
+  label_ago: fai
+  label_all: todos
+  label_all_time: todo o tempo
+  label_all_words: TÃ³dalas palabras
+  label_and_its_subprojects: "%{value} e proxectos secundarios"
+  label_applied_status: Aplicar estado
+  label_assigned_to_me_issues: PeticiÃ³ns asignadas a min
+  label_associated_revisions: RevisiÃ³ns asociadas
+  label_attachment: Arquivo
+  label_attachment_delete: Borrar o arquivo
+  label_attachment_new: Novo arquivo
+  label_attachment_plural: Arquivos
+  label_attribute: Atributo
+  label_attribute_plural: Atributos
+  label_auth_source: Modo de autenticaciÃ³n
+  label_auth_source_new: Novo modo de autenticaciÃ³n
+  label_auth_source_plural: Modos de autenticaciÃ³n
+  label_authentication: AutenticaciÃ³n
+  label_blocked_by: bloqueado por
+  label_blocks: bloquea a
+  label_board: Foro
+  label_board_new: Novo foro
+  label_board_plural: Foros
+  label_boolean: Booleano
+  label_browse: Ollar
+  label_bulk_edit_selected_issues: Editar as peticiÃ³ns seleccionadas
+  label_calendar: Calendario
+  label_change_plural: Cambios
+  label_change_properties: Cambiar propiedades
+  label_change_status: Cambiar o estado
+  label_change_view_all: Ver tÃ³dolos cambios
+  label_changes_details: Detalles de tÃ³dolos cambios
+  label_changeset_plural: Cambios
+  label_chronological_order: En orde cronolÃ³xica
+  label_closed_issues: pechada
+  label_closed_issues_plural: pechadas
+  label_x_open_issues_abbr_on_total:
+    zero:  0 open / %{total}
+    one:   1 open / %{total}
+    other: "%{count} open / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 open
+    one:   1 open
+    other: "%{count} open"
+  label_x_closed_issues_abbr:
+    zero:  0 closed
+    one:   1 closed
+    other: "%{count} closed"
+  label_comment: Comentario
+  label_comment_add: Engadir un comentario
+  label_comment_added: Comentario engadido
+  label_comment_delete: Borrar comentarios
+  label_comment_plural: Comentarios
+  label_x_comments:
+    zero: no comments
+    one: 1 comment
+    other: "%{count} comments"
+  label_commits_per_author: Commits por autor
+  label_commits_per_month: Commits por mes
+  label_confirmation: ConfirmaciÃ³n
+  label_contains: conten
+  label_copied: copiado
+  label_copy_workflow_from: Copiar fluxo de traballo dende
+  label_current_status: Estado actual
+  label_current_version: VersiÃ³n actual
+  label_custom_field: Campo personalizado
+  label_custom_field_new: Novo campo personalizado
+  label_custom_field_plural: Campos personalizados
+  label_date: Data
+  label_date_from: Dende
+  label_date_range: Rango de datas
+  label_date_to: Ata
+  label_day_plural: dÃ­as
+  label_default: Por defecto
+  label_default_columns: Columnas por defecto
+  label_deleted: suprimido
+  label_details: Detalles
+  label_diff_inline: en liÃ±a
+  label_diff_side_by_side: cara a cara
+  label_disabled: deshabilitado
+  label_display_per_page: "Por pÃ¡xina: %{value}"
+  label_document: Documento
+  label_document_added: Documento engadido
+  label_document_new: Novo documento
+  label_document_plural: Documentos
+  label_downloads_abbr: D/L
+  label_duplicated_by: duplicada por
+  label_duplicates: duplicada de
+  label_end_to_end: fin a fin
+  label_end_to_start: fin a principio
+  label_enumeration_new: Novo valor
+  label_enumerations: Listas de valores
+  label_environment: Entorno
+  label_equals: igual
+  label_example: Exemplo
+  label_export_to: 'Exportar a:'
+  label_f_hour: "%{value} hora"
+  label_f_hour_plural: "%{value} horas"
+  label_feed_plural: Feeds
+  label_feeds_access_key_created_on: "Clave de acceso por RSS creada fai %{value}"
+  label_file_added: Arquivo engadido
+  label_file_plural: Arquivos
+  label_filter_add: Engadir o filtro
+  label_filter_plural: Filtros
+  label_float: Flotante
+  label_follows: posterior a
+  label_gantt: Gantt
+  label_general: Xeral
+  label_generate_key: Xerar clave
+  label_help: Axuda
+  label_history: HistÃ³rico
+  label_home: Inicio
+  label_in: en
+  label_in_less_than: en menos que
+  label_in_more_than: en mais que
+  label_incoming_emails: Correos entrantes
+  label_index_by_date: Ãndice por data
+  label_index_by_title: Ãndice por tÃ­tulo
+  label_information: InformaciÃ³n
+  label_information_plural: InformaciÃ³n
+  label_integer: NÃºmero
+  label_internal: Interno
+  label_issue: PeticiÃ³n
+  label_issue_added: PeticiÃ³n engadida
+  label_issue_category: CategorÃ­a das peticiÃ³ns
+  label_issue_category_new: Nova categorÃ­a
+  label_issue_category_plural: CategorÃ­as das peticiÃ³ns
+  label_issue_new: Nova peticiÃ³n
+  label_issue_plural: PeticiÃ³ns
+  label_issue_status: Estado da peticiÃ³n
+  label_issue_status_new: Novo estado
+  label_issue_status_plural: Estados das peticiÃ³ns
+  label_issue_tracking: PeticiÃ³ns
+  label_issue_updated: PeticiÃ³n actualizada
+  label_issue_view_all: Ver tÃ³dalas peticiÃ³ns
+  label_issue_watchers: Seguidores
+  label_issues_by: "PeticiÃ³ns por %{value}"
+  label_jump_to_a_project: Ir ao proxecto...
+  label_language_based: Baseado no idioma
+  label_last_changes: "Ãºltimos %{count} cambios"
+  label_last_login: Ãšltima conexiÃ³n
+  label_last_month: Ãºltimo mes
+  label_last_n_days: "Ãºltimos %{count} dÃ­as"
+  label_last_week: Ãºltima semana
+  label_latest_revision: Ãšltima revisiÃ³n
+  label_latest_revision_plural: Ãšltimas revisiÃ³ns
+  label_ldap_authentication: AutenticaciÃ³n LDAP
+  label_less_than_ago: fai menos de
+  label_list: Lista
+  label_loading: Cargando...
+  label_logged_as: Conectado como
+  label_login: ConexiÃ³n
+  label_logout: DesconexiÃ³n
+  label_max_size: TamaÃ±o mÃ¡ximo
+  label_me: eu mesmo
+  label_member: Membro
+  label_member_new: Novo membro
+  label_member_plural: Membros
+  label_message_last: Ãšltima mensaxe
+  label_message_new: Nova mensaxe
+  label_message_plural: Mensaxes
+  label_message_posted: Mensaxe engadida
+  label_min_max_length: Lonxitude mÃ­n - mÃ¡x
+  label_modified: modificado
+  label_module_plural: MÃ³dulos
+  label_month: Mes
+  label_months_from: meses de
+  label_more: Mais
+  label_more_than_ago: fai mais de
+  label_my_account: A miÃ±a conta
+  label_my_page: A miÃ±a pÃ¡xina
+  label_my_projects: Os meus proxectos
+  label_new: Novo
+  label_new_statuses_allowed: Novos estados autorizados
+  label_news: Noticia
+  label_news_added: Noticia engadida
+  label_news_latest: Ãšltimas noticias
+  label_news_new: Nova noticia
+  label_news_plural: Noticias
+  label_news_view_all: Ver tÃ³dalas noticias
+  label_next: Seguinte
+  label_no_change_option: (Sen cambios)
+  label_no_data: NingÃºn dato a mostrar
+  label_nobody: ninguÃ©n
+  label_none: ningÃºn
+  label_not_contains: non conten
+  label_not_equals: non igual
+  label_open_issues: aberta
+  label_open_issues_plural: abertas
+  label_optional_description: DescriciÃ³n opcional
+  label_options: OpciÃ³ns
+  label_overall_activity: Actividade global
+  label_overview: Vistazo
+  label_password_lost: Â¿Esqueciches o contrasinal?
+  label_per_page: Por pÃ¡xina
+  label_permissions: Permisos
+  label_permissions_report: Informe de permisos
+  label_personalize_page: Personalizar esta pÃ¡xina
+  label_planning: PlanificaciÃ³n
+  label_please_login: ConexiÃ³n
+  label_plugins: ExtensiÃ³ns
+  label_precedes: anterior a
+  label_preferences: Preferencias
+  label_preview: Previsualizar
+  label_previous: Anterior
+  label_project: Proxecto
+  label_project_all: TÃ³dolos proxectos
+  label_project_latest: Ãšltimos proxectos
+  label_project_new: Novo proxecto
+  label_project_plural: Proxectos
+  label_x_projects:
+    zero:  no projects
+    one:   1 project
+    other: "%{count} projects"
+  label_public_projects: Proxectos pÃºblicos
+  label_query: Consulta personalizada
+  label_query_new: Nova consulta
+  label_query_plural: Consultas personalizadas
+  label_read: Ler...
+  label_register: Rexistrar
+  label_registered_on: Inscrito o
+  label_registration_activation_by_email: activaciÃ³n de conta por correo
+  label_registration_automatic_activation: activaciÃ³n automÃ¡tica de conta
+  label_registration_manual_activation: activaciÃ³n manual de conta
+  label_related_issues: PeticiÃ³ns relacionadas
+  label_relates_to: relacionada con
+  label_relation_delete: Eliminar relaciÃ³n
+  label_relation_new: Nova relaciÃ³n
+  label_renamed: renomeado
+  label_reply_plural: Respostas
+  label_report: Informe
+  label_report_plural: Informes
+  label_reported_issues: PeticiÃ³ns rexistradas por min
+  label_repository: Repositorio
+  label_repository_plural: Repositorios
+  label_result_plural: Resultados
+  label_reverse_chronological_order: En orde cronolÃ³xica inversa
+  label_revision: RevisiÃ³n
+  label_revision_plural: RevisiÃ³ns
+  label_roadmap: PlanificaciÃ³n
+  label_roadmap_due_in: "Remata en %{value}"
+  label_roadmap_no_issues: Non hai peticiÃ³ns para esta versiÃ³n
+  label_roadmap_overdue: "%{value} tarde"
+  label_role: Perfil
+  label_role_and_permissions: Perfiles e permisos
+  label_role_new: Novo perfil
+  label_role_plural: Perfiles
+  label_scm: SCM
+  label_search: BÃºsqueda
+  label_search_titles_only: Buscar sÃ³ en tÃ­tulos
+  label_send_information: Enviar informaciÃ³n da conta Ã³ usuario
+  label_send_test_email: Enviar un correo de proba
+  label_settings: ConfiguraciÃ³n
+  label_show_completed_versions: Mostra as versiÃ³ns rematadas
+  label_sort_by: "Ordenar por %{value}"
+  label_sort_higher: Subir
+  label_sort_highest: Primeiro
+  label_sort_lower: Baixar
+  label_sort_lowest: Ãšltimo
+  label_spent_time: Tempo dedicado
+  label_start_to_end: comezo a fin
+  label_start_to_start: comezo a comezo
+  label_statistics: EstatÃ­sticas
+  label_stay_logged_in: Lembrar contrasinal
+  label_string: Texto
+  label_subproject_plural: Proxectos secundarios
+  label_text: Texto largo
+  label_theme: Tema
+  label_this_month: este mes
+  label_this_week: esta semana
+  label_this_year: este ano
+  label_time_tracking: Control de tempo
+  label_today: hoxe
+  label_topic_plural: Temas
+  label_total: Total
+  label_tracker: Tipo
+  label_tracker_new: Novo tipo
+  label_tracker_plural: Tipos de peticiÃ³ns
+  label_updated_time: "Actualizado fai %{value}"
+  label_updated_time_by: "Actualizado por %{author} fai %{age}"
+  label_used_by: Utilizado por
+  label_user: Usuario
+  label_user_activity: "Actividade de %{value}"
+  label_user_mail_no_self_notified: "Non quero ser avisado de cambios feitos por min"
+  label_user_mail_option_all: "Para calquera evento en tÃ³dolos proxectos"
+  label_user_mail_option_selected: "Para calquera evento dos proxectos seleccionados..."
+  label_user_new: Novo usuario
+  label_user_plural: Usuarios
+  label_version: VersiÃ³n
+  label_version_new: Nova versiÃ³n
+  label_version_plural: VersiÃ³ns
+  label_view_diff: Ver diferencias
+  label_view_revisions: Ver as revisiÃ³ns
+  label_watched_issues: PeticiÃ³ns monitorizadas
+  label_week: Semana
+  label_wiki: Wiki
+  label_wiki_edit: Wiki ediciÃ³n
+  label_wiki_edit_plural: Wiki ediciÃ³ns
+  label_wiki_page: Wiki pÃ¡xina
+  label_wiki_page_plural: Wiki pÃ¡xinas
+  label_workflow: Fluxo de traballo
+  label_year: Ano
+  label_yesterday: onte
+  mail_body_account_activation_request: "Inscribiuse un novo usuario (%{value}). A conta estÃ¡ pendente de aprobaciÃ³n:"
+  mail_body_account_information: InformaciÃ³n sobre a sÃºa conta
+  mail_body_account_information_external: "Pode usar a sÃºa conta %{value} para conectarse."
+  mail_body_lost_password: 'Para cambiar o seu contrasinal, faga clic no seguinte enlace:'
+  mail_body_register: 'Para activar a sÃºa conta, faga clic no seguinte enlace:'
+  mail_body_reminder: "%{count} peticiÃ³n(s) asignadas a ti rematan nos prÃ³ximos %{days} dÃ­as:"
+  mail_subject_account_activation_request: "PeticiÃ³n de activaciÃ³n de conta %{value}"
+  mail_subject_lost_password: "O teu contrasinal de %{value}"
+  mail_subject_register: "ActivaciÃ³n da conta de %{value}"
+  mail_subject_reminder: "%{count} peticiÃ³n(s) rematarÃ¡n nos prÃ³ximos %{days} dÃ­as"
+  notice_account_activated: A sÃºa conta foi activada. Xa pode conectarse.
+  notice_account_invalid_creditentials: Usuario ou contrasinal invÃ¡lido.
+  notice_account_lost_email_sent: Enviouse un correo con instruciÃ³ns para elixir un novo contrasinal.
+  notice_account_password_updated: Contrasinal modificado correctamente.
+  notice_account_pending: "A sÃºa conta creouse e estÃ¡ pendente da aprobaciÃ³n por parte do administrador."
+  notice_account_register_done: Conta creada correctamente. Para activala, faga clic sobre o enlace que se lle enviou por correo.
+  notice_account_unknown_email: Usuario descoÃ±ecido.
+  notice_account_updated: Conta actualizada correctamente.
+  notice_account_wrong_password: Contrasinal incorrecto.
+  notice_can_t_change_password: Esta conta utiliza unha fonte de autenticaciÃ³n externa. Non Ã© posible cambiar o contrasinal.
+  notice_default_data_loaded: ConfiguraciÃ³n por defecto cargada correctamente.
+  notice_email_error: "Ocorreu un error enviando o correo (%{value})"
+  notice_email_sent: "Enviouse un correo a %{value}"
+  notice_failed_to_save_issues: "Imposible gravar %{count} peticiÃ³n(s) de %{total} seleccionada(s): %{ids}."
+  notice_feeds_access_key_reseted: A sÃºa clave de acceso para RSS reiniciouse.
+  notice_file_not_found: A pÃ¡xina Ã¡ que tenta acceder non existe.
+  notice_locking_conflict: Os datos modificÃ¡ronse por outro usuario.
+  notice_no_issue_selected: "Ningunha peticiÃ³n seleccionada. Por favor, comprobe a peticiÃ³n que quere modificar"
+  notice_not_authorized: Non ten autorizaciÃ³n para acceder a esta pÃ¡xina.
+  notice_successful_connection: ConexiÃ³n correcta.
+  notice_successful_create: CreaciÃ³n correcta.
+  notice_successful_delete: Borrado correcto.
+  notice_successful_update: ModificaciÃ³n correcta.
+  notice_unable_delete_version: Non se pode borrar a versiÃ³n
+  permission_add_issue_notes: Engadir notas
+  permission_add_issue_watchers: Engadir seguidores
+  permission_add_issues: Engadir peticiÃ³ns
+  permission_add_messages: Enviar mensaxes
+  permission_browse_repository: Ollar repositorio
+  permission_comment_news: Comentar noticias
+  permission_commit_access: Acceso de escritura
+  permission_delete_issues: Borrar peticiÃ³ns
+  permission_delete_messages: Borrar mensaxes
+  permission_delete_own_messages: Borrar mensaxes propios
+  permission_delete_wiki_pages: Borrar pÃ¡xinas wiki
+  permission_delete_wiki_pages_attachments: Borrar arquivos
+  permission_edit_issue_notes: Modificar notas
+  permission_edit_issues: Modificar peticiÃ³ns
+  permission_edit_messages: Modificar mensaxes
+  permission_edit_own_issue_notes: Modificar notas propias
+  permission_edit_own_messages: Editar mensaxes propios
+  permission_edit_own_time_entries: Modificar tempos dedicados propios
+  permission_edit_project: Modificar proxecto
+  permission_edit_time_entries: Modificar tempos dedicados
+  permission_edit_wiki_pages: Modificar pÃ¡xinas wiki
+  permission_log_time: Anotar tempo dedicado
+  permission_manage_boards: Administrar foros
+  permission_manage_categories: Administrar categorÃ­as de peticiÃ³ns
+  permission_manage_files: Administrar arquivos
+  permission_manage_issue_relations: Administrar relaciÃ³n con outras peticiÃ³ns
+  permission_manage_members: Administrar membros
+  permission_manage_news: Administrar noticias
+  permission_manage_public_queries: Administrar consultas pÃºblicas
+  permission_manage_repository: Administrar repositorio
+  permission_manage_versions: Administrar versiÃ³ns
+  permission_manage_wiki: Administrar wiki
+  permission_move_issues: Mover peticiÃ³ns
+  permission_protect_wiki_pages: Protexer pÃ¡xinas wiki
+  permission_rename_wiki_pages: Renomear pÃ¡xinas wiki
+  permission_save_queries: Gravar consultas
+  permission_select_project_modules: Seleccionar mÃ³dulos do proxecto
+  permission_view_calendar: Ver calendario
+  permission_view_changesets: Ver cambios
+  permission_view_documents: Ver documentos
+  permission_view_files: Ver arquivos
+  permission_view_gantt: Ver diagrama de Gantt
+  permission_view_issue_watchers: Ver lista de seguidores
+  permission_view_messages: Ver mensaxes
+  permission_view_time_entries: Ver tempo dedicado
+  permission_view_wiki_edits: Ver histÃ³rico do wiki
+  permission_view_wiki_pages: Ver wiki
+  project_module_boards: Foros
+  project_module_documents: Documentos
+  project_module_files: Arquivos
+  project_module_issue_tracking: PeticiÃ³ns
+  project_module_news: Noticias
+  project_module_repository: Repositorio
+  project_module_time_tracking: Control de tempo
+  project_module_wiki: Wiki
+  setting_activity_days_default: DÃ­as a mostrar na actividade do proxecto
+  setting_app_subtitle: SubtÃ­tulo da aplicaciÃ³n
+  setting_app_title: TÃ­tulo da aplicaciÃ³n
+  setting_attachment_max_size: TamaÃ±o mÃ¡ximo do arquivo
+  setting_autofetch_changesets: Autorechear os commits do repositorio
+  setting_autologin: ConexiÃ³n automÃ¡tica
+  setting_bcc_recipients: Ocultar as copias de carbÃ³n (bcc)
+  setting_commit_fix_keywords: Palabras clave para a correcciÃ³n
+  setting_commit_ref_keywords: Palabras clave para a referencia
+  setting_cross_project_issue_relations: Permitir relacionar peticiÃ³ns de distintos proxectos
+  setting_date_format: Formato da data
+  setting_default_language: Idioma por defecto
+  setting_default_projects_public: Os proxectos novos son pÃºblicos por defecto
+  setting_diff_max_lines_displayed: NÃºmero mÃ¡ximo de diferencias mostradas
+  setting_display_subprojects_issues: Mostrar por defecto peticiÃ³ns de prox. secundarios no principal
+  setting_emails_footer: Pe de mensaxes
+  setting_enabled_scm: Activar SCM
+  setting_feeds_limit: LÃ­mite de contido para sindicaciÃ³n
+  setting_gravatar_enabled: Usar iconas de usuario (Gravatar)
+  setting_host_name: Nome e ruta do servidor
+  setting_issue_list_default_columns: Columnas por defecto para a lista de peticiÃ³ns
+  setting_issues_export_limit: LÃ­mite de exportaciÃ³n de peticiÃ³ns
+  setting_login_required: RequÃ­rese identificaciÃ³n
+  setting_mail_from: Correo dende o que enviar mensaxes
+  setting_mail_handler_api_enabled: Activar SW para mensaxes entrantes
+  setting_mail_handler_api_key: Clave da API
+  setting_per_page_options: Obxectos por pÃ¡xina
+  setting_plain_text_mail: sÃ³ texto plano (non HTML)
+  setting_protocol: Protocolo
+  setting_self_registration: Rexistro permitido
+  setting_sequential_project_identifiers: Xerar identificadores de proxecto
+  setting_sys_api_enabled: Habilitar SW para a xestiÃ³n do repositorio
+  setting_text_formatting: Formato de texto
+  setting_time_format: Formato de hora
+  setting_user_format: Formato de nome de usuario
+  setting_welcome_text: Texto de benvida
+  setting_wiki_compression: CompresiÃ³n do historial do Wiki
+  status_active: activo
+  status_locked: bloqueado
+  status_registered: rexistrado
+  text_are_you_sure: Â¿EstÃ¡ seguro?
+  text_assign_time_entries_to_project: Asignar as horas Ã³ proxecto
+  text_caracters_maximum: "%{count} caracteres como mÃ¡ximo."
+  text_caracters_minimum: "%{count} caracteres como mÃ­nimo"
+  text_comma_separated: MÃºltiples valores permitidos (separados por coma).
+  text_default_administrator_account_changed: Conta de administrador por defecto modificada
+  text_destroy_time_entries: Borrar as horas
+  text_destroy_time_entries_question: Existen %{hours} horas asignadas Ã¡ peticiÃ³n que quere borrar. Â¿Que quere facer ?
+  text_diff_truncated: '... Diferencia truncada por exceder o mÃ¡ximo tamaÃ±o visualizable.'
+  text_email_delivery_not_configured: "O envÃ­o de correos non estÃ¡ configurado, e as notificaciÃ³ns desactivÃ¡ronse. \n Configure o servidor de SMTP en config/configuration.yml e reinicie a aplicaciÃ³n para activar os cambios."
+  text_enumeration_category_reassign_to: 'Reasignar Ã³ seguinte valor:'
+  text_enumeration_destroy_question: "%{count} obxectos con este valor asignado."
+  text_file_repository_writable: PÃ³dese escribir no repositorio
+  text_issue_added: "PeticiÃ³n %{id} engadida por %{author}."
+  text_issue_category_destroy_assignments: Deixar as peticiÃ³ns sen categorÃ­a
+  text_issue_category_destroy_question: "Algunhas peticiÃ³ns (%{count}) estÃ¡n asignadas a esta categorÃ­a. Â¿Que desexa facer?"
+  text_issue_category_reassign_to: Reasignar as peticiÃ³ns Ã¡ categorÃ­a
+  text_issue_updated: "A peticiÃ³n %{id} actualizouse por %{author}."
+  text_issues_destroy_confirmation: 'Â¿Seguro que quere borrar as peticiÃ³ns seleccionadas?'
+  text_issues_ref_in_commit_messages: Referencia e peticiÃ³n de correcciÃ³n nas mensaxes
+  text_length_between: "Lonxitude entre %{min} e %{max} caracteres."
+  text_load_default_configuration: Cargar a configuraciÃ³n por defecto
+  text_min_max_length_info: 0 para ningunha restriciÃ³n
+  text_no_configuration_data: "Inda non se configuraron perfiles, nin tipos, estados e fluxo de traballo asociado a peticiÃ³ns. RecomÃ©ndase encarecidamente cargar a configuraciÃ³n por defecto. Unha vez cargada, poderÃ¡ modificala."
+  text_project_destroy_confirmation: Â¿EstÃ¡s seguro de querer eliminar o proxecto?
+  text_reassign_time_entries: 'Reasignar as horas a esta peticiÃ³n:'
+  text_regexp_info: ex. ^[A-Z0-9]+$
+  text_repository_usernames_mapping: "Estableza a correspondencia entre os usuarios de Redmine e os presentes no log do repositorio.\nOs usuarios co mesmo nome ou correo en Redmine e no repositorio serÃ¡n asociados automaticamente."
+  text_rmagick_available: RMagick dispoÃ±ible (opcional)
+  text_select_mail_notifications: Seleccionar os eventos a notificar
+  text_select_project_modules: 'Seleccione os mÃ³dulos a activar para este proxecto:'
+  text_status_changed_by_changeset: "Aplicado nos cambios %{value}"
+  text_subprojects_destroy_warning: "Os proxectos secundarios: %{value} tamÃ©n se eliminarÃ¡n"
+  text_tip_issue_begin_day: tarefa que comeza este dÃ­a
+  text_tip_issue_begin_end_day: tarefa que comeza e remata este dÃ­a
+  text_tip_issue_end_day: tarefa que remata este dÃ­a
+  text_tracker_no_workflow: Non hai ningÃºn fluxo de traballo definido para este tipo de peticiÃ³n
+  text_unallowed_characters: Caracteres non permitidos
+  text_user_mail_option: "Dos proxectos non seleccionados, sÃ³ recibirÃ¡ notificaciÃ³ns sobre elementos monitorizados ou elementos nos que estea involucrado (por exemplo, peticiÃ³ns das que vostede sexa autor ou asignadas a vostede)."
+  text_user_wrote: "%{value} escribiu:"
+  text_wiki_destroy_confirmation: Â¿Seguro que quere borrar o wiki e todo o seu contido?
+  text_workflow_edit: Seleccionar un fluxo de traballo para actualizar
+  warning_attachments_not_saved: "%{count} file(s) could not be saved."
+  field_editable: Editable
+  text_plugin_assets_writable: Plugin assets directory writable
+  label_display: Display
+  button_create_and_continue: Create and continue
+  text_custom_field_possible_values_info: 'One line for each value'
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_file_max_size_displayed: Max size of text files displayed inline
+  field_watcher: Watcher
+  setting_openid: Allow OpenID login and registration
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: or login with OpenID
+  field_content: Content
+  label_descending: Descending
+  label_sort: Sort
+  label_ascending: Ascending
+  label_date_from_to: From %{start} to %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
+  text_wiki_page_reassign_children: Reassign child pages to this parent page
+  text_wiki_page_nullify_children: Keep child pages as root pages
+  text_wiki_page_destroy_children: Delete child pages and all their descendants
+  setting_password_min_length: Minimum password length
+  field_group_by: Group results by
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  label_wiki_content_added: Wiki page added
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
+  label_wiki_content_updated: Wiki page updated
+  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
+  permission_add_project: Create project
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  label_view_all_revisions: View all revisions
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
+  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
+  text_journal_changed: "%{label} changed from %{old} to %{new}"
+  text_journal_set_to: "%{label} set to %{value}"
+  text_journal_deleted: "%{label} deleted (%{old})"
+  label_group_plural: Groups
+  label_group: Group
+  label_group_new: New group
+  label_time_entry_plural: Spent time
+  text_journal_added: "%{label} %{value} added"
+  field_active: Active
+  enumeration_system_activity: System Activity
+  permission_delete_issue_watchers: Delete watchers
+  version_status_closed: closed
+  version_status_locked: locked
+  version_status_open: open
+  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
+  label_user_anonymous: Anonymous
+  button_move_and_follow: Move and follow
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_gravatar_default: Default Gravatar image
+  field_sharing: Sharing
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_system: With all projects
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_tree: With project tree
+  label_version_sharing_none: Not shared
+  error_can_not_archive_project: This project can not be archived
+  button_duplicate: Duplicate
+  button_copy_and_follow: Copy and follow
+  label_copy_source: Source
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_status: Use the issue status
+  error_issue_done_ratios_not_updated: Issue done ratios not updated.
+  error_workflow_copy_target: Please select target tracker(s) and role(s)
+  setting_issue_done_ratio_issue_field: Use the issue field
+  label_copy_same_as_target: Same as target
+  label_copy_target: Target
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  error_workflow_copy_source: Please select a source tracker or role
+  label_update_issue_done_ratios: Update issue done ratios
+  setting_start_of_week: Start calendars on
+  permission_view_issues: View Issues
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_revision_id: Revision %{value}
+  label_api_access_key: API access key
+  label_api_access_key_created_on: API access key created %{value} ago
+  label_feeds_access_key: RSS access key
+  notice_api_access_key_reseted: Your API access key was reset.
+  setting_rest_api_enabled: Enable REST web service
+  label_missing_api_access_key: Missing an API access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  button_show: Show
+  text_line_separated: Multiple values allowed (one line for each value).
+  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
+  permission_add_subprojects: Create subprojects
+  label_subproject_new: New subproject
+  text_own_membership_delete_confirmation: |-
+    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
+    Are you sure you want to continue?
+  label_close_versions: Close completed versions
+  label_board_sticky: Sticky
+  label_board_locked: Locked
+  permission_export_wiki_pages: Export wiki pages
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: Manage project activities
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_profile: Profile
+  permission_manage_subtasks: Manage subtasks
+  field_parent_issue: Parent task
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: CodificaciÃ³n das mensaxes de commit
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 peticiÃ³n
+    one:   1 peticiÃ³n
+    other: "%{count} peticiÃ³ns"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: todos
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/7613b919071a0b15c5315d48513bd037d7d92c4b.svn-base
--- /dev/null
+++ b/.svn/pristine/76/7613b919071a0b15c5315d48513bd037d7d92c4b.svn-base
@@ -0,0 +1,85 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Helpers
+
+    # Simple class to compute the start and end dates of a calendar
+    class Calendar
+      include Redmine::I18n
+      attr_reader :startdt, :enddt
+
+      def initialize(date, lang = current_language, period = :month)
+        @date = date
+        @events = []
+        @ending_events_by_days = {}
+        @starting_events_by_days = {}
+        set_language_if_valid lang
+        case period
+        when :month
+          @startdt = Date.civil(date.year, date.month, 1)
+          @enddt = (@startdt >> 1)-1
+          # starts from the first day of the week
+          @startdt = @startdt - (@startdt.cwday - first_wday)%7
+          # ends on the last day of the week
+          @enddt = @enddt + (last_wday - @enddt.cwday)%7
+        when :week
+          @startdt = date - (date.cwday - first_wday)%7
+          @enddt = date + (last_wday - date.cwday)%7
+        else
+          raise 'Invalid period'
+        end
+      end
+
+      # Sets calendar events
+      def events=(events)
+        @events = events
+        @ending_events_by_days = @events.group_by {|event| event.due_date}
+        @starting_events_by_days = @events.group_by {|event| event.start_date}
+      end
+
+      # Returns events for the given day
+      def events_on(day)
+        ((@ending_events_by_days[day] || []) + (@starting_events_by_days[day] || [])).uniq
+      end
+
+      # Calendar current month
+      def month
+        @date.month
+      end
+
+      # Return the first day of week
+      # 1 = Monday ... 7 = Sunday
+      def first_wday
+        case Setting.start_of_week.to_i
+        when 1
+          @first_dow ||= (1 - 1)%7 + 1
+        when 6
+          @first_dow ||= (6 - 1)%7 + 1
+        when 7
+          @first_dow ||= (7 - 1)%7 + 1
+        else
+          @first_dow ||= (l(:general_first_day_of_week).to_i - 1)%7 + 1
+        end
+      end
+
+      def last_wday
+        @last_dow ||= (first_wday + 5)%7 + 1
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/76250042c24ef04826eb632546dd6627448cd0da.svn-base
--- a/.svn/pristine/76/76250042c24ef04826eb632546dd6627448cd0da.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday",
- "Sunday");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Sun",
- "Mon",
- "Tue",
- "Wed",
- "Thu",
- "Fri",
- "Sat",
- "Sun");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "Mar",
- "Apr",
- "May",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Oct",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "About the calendar";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)";
-Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)";
-Calendar._TT["GO_TODAY"] = "Go Today";
-Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)";
-Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)";
-Calendar._TT["SEL_DATE"] = "Select date";
-Calendar._TT["DRAG_TO_MOVE"] = "Drag to move";
-Calendar._TT["PART_TODAY"] = " (today)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Display %s first";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Close";
-Calendar._TT["TODAY"] = "Today";
-Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Time:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/7646d2e1c72093f6ce9fbc03074e4564c3417f93.svn-base
--- /dev/null
+++ b/.svn/pristine/76/7646d2e1c72093f6ce9fbc03074e4564c3417f93.svn-base
@@ -0,0 +1,1091 @@
+# Serbian translations for Redmine
+# by Vladimir MedaroviÄ‡ (vlada@medarovic.com)
+sr-YU:
+  direction: ltr
+  jquery:
+    locale: "sr"
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d.%m.%Y."
+      short: "%e %b"
+      long: "%B %e, %Y"
+
+    day_names: [nedelja, ponedeljak, utorak, sreda, Äetvrtak, petak, subota]
+    abbr_day_names: [ned, pon, uto, sre, Äet, pet, sub]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, januar, februar, mart, april, maj, jun, jul, avgust, septembar, oktobar, novembar, decembar]
+    abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, avg, sep, okt, nov, dec]
+    # Used in date_select and datime_select.
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%d.%m.%Y. u %H:%M"
+      time: "%H:%M"
+      short: "%d. %b u %H:%M"
+      long: "%d. %B %Y u %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pola minuta"
+      less_than_x_seconds:
+        one:   "manje od jedne sekunde"
+        other: "manje od %{count} sek."
+      x_seconds:
+        one:   "jedna sekunda"
+        other: "%{count} sek."
+      less_than_x_minutes:
+        one:   "manje od minuta"
+        other: "manje od %{count} min."
+      x_minutes:
+        one:   "jedan minut"
+        other: "%{count} min."
+      about_x_hours:
+        one:   "pribliÅ¾no jedan sat"
+        other: "pribliÅ¾no %{count} sati"
+      x_hours:
+        one:   "1 sat"
+        other: "%{count} sati"
+      x_days:
+        one:   "jedan dan"
+        other: "%{count} dana"
+      about_x_months:
+        one:   "pribliÅ¾no jedan mesec"
+        other: "pribliÅ¾no %{count} meseci"
+      x_months:
+        one:   "jedan mesec"
+        other: "%{count} meseci"
+      about_x_years:
+        one:   "pribliÅ¾no godinu dana"
+        other: "pribliÅ¾no %{count} god."
+      over_x_years:
+        one:   "preko godinu dana"
+        other: "preko %{count} god."
+      almost_x_years:
+        one:   "skoro godinu dana"
+        other: "skoro %{count} god."
+
+  number:
+    format:
+      separator: ","
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "i"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "nije ukljuÄen u spisak"
+        exclusion: "je rezervisan"
+        invalid: "je neispravan"
+        confirmation: "potvrda ne odgovara"
+        accepted: "mora biti prihvaÄ‡en"
+        empty: "ne moÅ¾e biti prazno"
+        blank: "ne moÅ¾e biti prazno"
+        too_long: "je predugaÄka (maksimum znakova je %{count})"
+        too_short: "je prekratka (minimum znakova je %{count})"
+        wrong_length: "je pogreÅ¡ne duÅ¾ine (broj znakova mora biti %{count})"
+        taken: "je veÄ‡ u upotrebi"
+        not_a_number: "nije broj"
+        not_a_date: "nije ispravan datum"
+        greater_than: "mora biti veÄ‡i od %{count}"
+        greater_than_or_equal_to: "mora biti veÄ‡i ili jednak %{count}"
+        equal_to: "mora biti jednak %{count}"
+        less_than: "mora biti manji od %{count}"
+        less_than_or_equal_to: "mora biti manji ili jednak %{count}"
+        odd: "mora biti paran"
+        even: "mora biti neparan"
+        greater_than_start_date: "mora biti veÄ‡i od poÄetnog datuma"
+        not_same_project: "ne pripada istom projektu"
+        circular_dependency: "Ova veza Ä‡e stvoriti kruÅ¾nu referencu"
+        cant_link_an_issue_with_a_descendant: "Problem ne moÅ¾e biti povezan sa jednim od svojih podzadataka"
+
+  actionview_instancetag_blank_option: Molim odaberite
+
+  general_text_No: 'Ne'
+  general_text_Yes: 'Da'
+  general_text_no: 'ne'
+  general_text_yes: 'da'
+  general_lang_name: 'Serbian (Srpski)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Nalog je uspeÅ¡no aÅ¾uriran.
+  notice_account_invalid_creditentials: Neispravno korisniÄko ime ili lozinka.
+  notice_account_password_updated: Lozinka je uspeÅ¡no aÅ¾urirana.
+  notice_account_wrong_password: PogreÅ¡na lozinka
+  notice_account_register_done: KorisniÄki nalog je uspeÅ¡no kreiran. Kliknite na link koji ste dobili u e-poruci za aktivaciju.
+  notice_account_unknown_email: Nepoznat korisnik.
+  notice_can_t_change_password: Ovaj korisniÄki nalog za potvrdu identiteta koristi spoljni izvor. NemoguÄ‡e je promeniti lozinku.
+  notice_account_lost_email_sent: Poslata vam je e-poruka sa uputstvom za izbor nove lozinke
+  notice_account_activated: VaÅ¡ korisniÄki nalog je aktiviran. Sada se moÅ¾ete prijaviti.
+  notice_successful_create: UspeÅ¡no kreiranje.
+  notice_successful_update: UspeÅ¡no aÅ¾uriranje.
+  notice_successful_delete: UspeÅ¡no brisanje.
+  notice_successful_connection: UspeÅ¡no povezivanje.
+  notice_file_not_found: Strana kojoj Å¾elite pristupiti ne postoji ili je uklonjena.
+  notice_locking_conflict: Podatak je aÅ¾uriran od strane drugog korisnika.
+  notice_not_authorized: Niste ovlaÅ¡Ä‡eni za pristup ovoj strani.
+  notice_email_sent: "E-poruka je poslata na %{value}"
+  notice_email_error: "Dogodila se greÅ¡ka prilikom slanja e-poruke (%{value})"
+  notice_feeds_access_key_reseted: VaÅ¡ RSS pristupni kljuÄ je poniÅ¡ten.
+  notice_api_access_key_reseted: VaÅ¡ API pristupni kljuÄ je poniÅ¡ten.
+  notice_failed_to_save_issues: "NeuspeÅ¡no snimanje %{count} problema od %{total} odabranih: %{ids}."
+  notice_failed_to_save_members: "NeuspeÅ¡no snimanje Älana(ova): %{errors}."
+  notice_no_issue_selected: "Ni jedan problem nije odabran! Molimo, odaberite problem koji Å¾elite da menjate."
+  notice_account_pending: "VaÅ¡ nalog je kreiran i Äeka na odobrenje administratora."
+  notice_default_data_loaded: Podrazumevano konfigurisanje je uspeÅ¡no uÄitano.
+  notice_unable_delete_version: Verziju je nemoguÄ‡e izbrisati.
+  notice_unable_delete_time_entry: Stavku evidencije vremena je nemoguÄ‡e izbrisati.
+  notice_issue_done_ratios_updated: Odnos reÅ¡enih problema je aÅ¾uriran.
+
+  error_can_t_load_default_data: "Podrazumevano konfigurisanje je nemoguÄ‡e uÄitati: %{value}"
+  error_scm_not_found: "Stavka ili ispravka nisu pronaÄ‘ene u spremiÅ¡tu."
+  error_scm_command_failed: "GreÅ¡ka se javila prilikom pokuÅ¡aja pristupa spremiÅ¡tu: %{value}"
+  error_scm_annotate: "Stavka ne postoji ili ne moÅ¾e biti oznaÄena."
+  error_issue_not_found_in_project: 'Problem nije pronaÄ‘en ili ne pripada ovom projektu.'
+  error_no_tracker_in_project: 'Ni jedno praÄ‡enje nije povezano sa ovim projektom. Molimo proverite podeÅ¡avanja projekta.'
+  error_no_default_issue_status: 'Podrazumevani status problema nije definisan. Molimo proverite vaÅ¡e konfigurisanje (idite na "Administracija -> Statusi problema").'
+  error_can_not_delete_custom_field: NemoguÄ‡e je izbrisati prilagoÄ‘eno polje
+  error_can_not_delete_tracker: "Ovo praÄ‡enje sadrÅ¾i probleme i ne moÅ¾e biti obrisano."
+  error_can_not_remove_role: "Ova uloga je u upotrebi i ne moÅ¾e biti obrisana."
+  error_can_not_reopen_issue_on_closed_version: 'Problem dodeljen zatvorenoj verziji ne moÅ¾e biti ponovo otvoren'
+  error_can_not_archive_project: Ovaj projekat se ne moÅ¾e arhivirati
+  error_issue_done_ratios_not_updated: "Odnos reÅ¡enih problema nije aÅ¾uriran."
+  error_workflow_copy_source: 'Molimo odaberite izvorno praÄ‡enje ili ulogu'
+  error_workflow_copy_target: 'Molimo odaberite odrediÅ¡no praÄ‡enje i ulogu'
+  error_unable_delete_issue_status: 'Status problema je nemoguÄ‡e obrisati'
+  error_unable_to_connect: "Povezivanje sa (%{value}) je nemoguÄ‡e"
+  warning_attachments_not_saved: "%{count} datoteka ne moÅ¾e biti snimljena."
+
+  mail_subject_lost_password: "VaÅ¡a %{value} lozinka"
+  mail_body_lost_password: 'Za promenu vaÅ¡e lozinke, kliknite na sledeÄ‡i link:'
+  mail_subject_register: "Aktivacija vaÅ¡eg %{value} naloga"
+  mail_body_register: 'Za aktivaciju vaÅ¡eg naloga, kliknite na sledeÄ‡i link:'
+  mail_body_account_information_external: "VaÅ¡ nalog %{value} moÅ¾ete koristiti za prijavu."
+  mail_body_account_information: Informacije o vaÅ¡em nalogu
+  mail_subject_account_activation_request: "Zahtev za aktivaciju naloga %{value}"
+  mail_body_account_activation_request: "Novi korisnik (%{value}) je registrovan. Nalog Äeka na vaÅ¡e odobrenje:"
+  mail_subject_reminder: "%{count} problema dospeva narednih %{days} dana"
+  mail_body_reminder: "%{count} problema dodeljenih vama dospeva u narednih %{days} dana:"
+  mail_subject_wiki_content_added: "Wiki stranica '%{id}' je dodata"
+  mail_body_wiki_content_added: "%{author} je dodao wiki stranicu '%{id}'."
+  mail_subject_wiki_content_updated: "Wiki stranica '%{id}' je aÅ¾urirana"
+  mail_body_wiki_content_updated: "%{author} je aÅ¾urirao wiki stranicu '%{id}'."
+
+
+  field_name: Naziv
+  field_description: Opis
+  field_summary: Rezime
+  field_is_required: Obavezno
+  field_firstname: Ime
+  field_lastname: Prezime
+  field_mail: E-adresa
+  field_filename: Datoteka
+  field_filesize: VeliÄina
+  field_downloads: Preuzimanja
+  field_author: Autor
+  field_created_on: Kreirano
+  field_updated_on: AÅ¾urirano
+  field_field_format: Format
+  field_is_for_all: Za sve projekte
+  field_possible_values: MoguÄ‡e vrednosti
+  field_regexp: Regularan izraz
+  field_min_length: Minimalna duÅ¾ina
+  field_max_length: Maksimalna duÅ¾ina
+  field_value: Vrednost
+  field_category: Kategorija
+  field_title: Naslov
+  field_project: Projekat
+  field_issue: Problem
+  field_status: Status
+  field_notes: BeleÅ¡ke
+  field_is_closed: Zatvoren problem
+  field_is_default: Podrazumevana vrednost
+  field_tracker: PraÄ‡enje
+  field_subject: Predmet
+  field_due_date: Krajnji rok
+  field_assigned_to: Dodeljeno
+  field_priority: Prioritet
+  field_fixed_version: OdrediÅ¡na verzija
+  field_user: Korisnik
+  field_principal: Glavni
+  field_role: Uloga
+  field_homepage: PoÄetna stranica
+  field_is_public: Javno objavljivanje
+  field_parent: Potprojekat od
+  field_is_in_roadmap: Problemi prikazani u planu rada
+  field_login: KorisniÄko ime
+  field_mail_notification: ObaveÅ¡tenja putem e-poÅ¡te
+  field_admin: Administrator
+  field_last_login_on: Poslednje povezivanje
+  field_language: Jezik
+  field_effective_date: Datum
+  field_password: Lozinka
+  field_new_password: Nova lozinka
+  field_password_confirmation: Potvrda lozinke
+  field_version: Verzija
+  field_type: Tip
+  field_host: Glavni raÄunar
+  field_port: Port
+  field_account: KorisniÄki nalog
+  field_base_dn: Bazni DN
+  field_attr_login: Atribut prijavljivanja
+  field_attr_firstname: Atribut imena
+  field_attr_lastname: Atribut prezimena
+  field_attr_mail: Atribut e-adrese
+  field_onthefly: Kreiranje korisnika u toku rada
+  field_start_date: PoÄetak
+  field_done_ratio: "% uraÄ‘eno"
+  field_auth_source: ReÅ¾im potvrde identiteta
+  field_hide_mail: Sakrij moju e-adresu
+  field_comments: Komentar
+  field_url: URL
+  field_start_page: PoÄetna stranica
+  field_subproject: Potprojekat
+  field_hours: sati
+  field_activity: Aktivnost
+  field_spent_on: Datum
+  field_identifier: Identifikator
+  field_is_filter: Upotrebi kao filter
+  field_issue_to: Srodni problemi
+  field_delay: KaÅ¡njenje
+  field_assignable: Problem moÅ¾e biti dodeljen ovoj ulozi
+  field_redirect_existing_links: Preusmeri postojeÄ‡e veze
+  field_estimated_hours: Procenjeno vreme 
+  field_column_names: Kolone
+  field_time_zone: Vremenska zona
+  field_searchable: MoÅ¾e da se pretraÅ¾uje
+  field_default_value: Podrazumevana vrednost
+  field_comments_sorting: PrikaÅ¾i komentare
+  field_parent_title: MatiÄna stranica
+  field_editable: Izmenljivo
+  field_watcher: PosmatraÄ
+  field_identity_url: OpenID URL
+  field_content: SadrÅ¾aj
+  field_group_by: Grupisanje rezultata po
+  field_sharing: Deljenje
+  field_parent_issue: MatiÄni zadatak
+
+  setting_app_title: Naslov aplikacije
+  setting_app_subtitle: Podnaslov aplikacije
+  setting_welcome_text: Tekst dobrodoÅ¡lice
+  setting_default_language: Podrazumevani jezik
+  setting_login_required: Obavezna potvrda identiteta
+  setting_self_registration: Samoregistracija
+  setting_attachment_max_size: Maks. veliÄina priloÅ¾ene datoteke
+  setting_issues_export_limit: OgraniÄenje izvoza â€žproblemaâ€œ
+  setting_mail_from: E-adresa poÅ¡iljaoca
+  setting_bcc_recipients: Primaoci â€žBccâ€œ kopije
+  setting_plain_text_mail: Poruka sa Äistim tekstom (bez HTML-a)
+  setting_host_name: Putanja i naziv glavnog raÄunara
+  setting_text_formatting: Oblikovanje teksta
+  setting_wiki_compression: Kompresija Wiki istorije
+  setting_feeds_limit: OgraniÄenje sadrÅ¾aja izvora vesti
+  setting_default_projects_public: Podrazumeva se javno prikazivanje novih projekata
+  setting_autofetch_changesets: IzvrÅ¡avanje automatskog preuzimanja
+  setting_sys_api_enabled: OmoguÄ‡avanje WS za upravljanje spremiÅ¡tem
+  setting_commit_ref_keywords: Referenciranje kljuÄnih reÄi
+  setting_commit_fix_keywords: Popravljanje kljuÄnih reÄi
+  setting_autologin: Automatska prijava
+  setting_date_format: Format datuma
+  setting_time_format: Format vremena
+  setting_cross_project_issue_relations: Dozvoli povezivanje problema iz unakrsnih projekata
+  setting_issue_list_default_columns: Podrazumevane kolone prikazane na spisku problema
+  setting_emails_footer: PodnoÅ¾je stranice e-poruke
+  setting_protocol: Protokol
+  setting_per_page_options: Opcije prikaza objekata po stranici
+  setting_user_format: Format prikaza korisnika
+  setting_activity_days_default: Broj dana prikazanih na projektnoj aktivnosti
+  setting_display_subprojects_issues: Prikazuj probleme iz potprojekata na glavnom projektu, ukoliko nije drugaÄije navedeno
+  setting_enabled_scm: OmoguÄ‡avanje SCM
+  setting_mail_handler_body_delimiters: "SkraÄ‡ivanje e-poruke nakon jedne od ovih linija"
+  setting_mail_handler_api_enabled: OmoguÄ‡avanje WS dolazne e-poruke
+  setting_mail_handler_api_key: API kljuÄ
+  setting_sequential_project_identifiers: Generisanje sekvencijalnog imena projekta
+  setting_gravatar_enabled: Koristi Gravatar korisniÄke ikone
+  setting_gravatar_default: Podrazumevana Gravatar slika
+  setting_diff_max_lines_displayed: Maks. broj prikazanih razliÄitih linija
+  setting_file_max_size_displayed: Maks. veliÄina tekst. datoteka prikazanih umetnuto
+  setting_repository_log_display_limit: Maks. broj revizija prikazanih u datoteci za evidenciju
+  setting_openid: Dozvoli OpenID prijavu i registraciju
+  setting_password_min_length: Minimalna duÅ¾ina lozinke
+  setting_new_project_user_role_id: Kreatoru projekta (koji nije administrator) dodeljuje je uloga
+  setting_default_projects_modules: Podrazumevano omoguÄ‡eni moduli za nove projekte
+  setting_issue_done_ratio: IzraÄunaj odnos reÅ¡enih problema
+  setting_issue_done_ratio_issue_field: koristeÄ‡i polje problema
+  setting_issue_done_ratio_issue_status: koristeÄ‡i status problema
+  setting_start_of_week: Prvi dan u sedmici
+  setting_rest_api_enabled: OmoguÄ‡i REST web usluge
+  setting_cache_formatted_text: KeÅ¡iranje obraÄ‘enog teksta
+
+  permission_add_project: Kreiranje projekta
+  permission_add_subprojects: Kreiranje potpojekta
+  permission_edit_project: Izmena projekata
+  permission_select_project_modules: Odabiranje modula projekta
+  permission_manage_members: Upravljanje Älanovima
+  permission_manage_project_activities: Upravljanje projektnim aktivnostima
+  permission_manage_versions: Upravljanje verzijama
+  permission_manage_categories: Upravljanje kategorijama problema
+  permission_view_issues: Pregled problema
+  permission_add_issues: Dodavanje problema
+  permission_edit_issues: Izmena problema
+  permission_manage_issue_relations: Upravljanje vezama izmeÄ‘u problema
+  permission_add_issue_notes: Dodavanje beleÅ¡ki
+  permission_edit_issue_notes: Izmena beleÅ¡ki
+  permission_edit_own_issue_notes: Izmena sopstvenih beleÅ¡ki
+  permission_move_issues: Pomeranje problema
+  permission_delete_issues: Brisanje problema
+  permission_manage_public_queries: Upravljanje javnim upitima
+  permission_save_queries: Snimanje upita
+  permission_view_gantt: Pregledanje Gantovog dijagrama
+  permission_view_calendar: Pregledanje kalendara
+  permission_view_issue_watchers: Pregledanje spiska posmatraÄa
+  permission_add_issue_watchers: Dodavanje posmatraÄa
+  permission_delete_issue_watchers: Brisanje posmatraÄa
+  permission_log_time: BeleÅ¾enje utroÅ¡enog vremena
+  permission_view_time_entries: Pregledanje utroÅ¡enog vremena
+  permission_edit_time_entries: Izmena utroÅ¡enog vremena
+  permission_edit_own_time_entries: Izmena sopstvenog utroÅ¡enog vremena
+  permission_manage_news: Upravljanje vestima
+  permission_comment_news: Komentarisanje vesti
+  permission_view_documents: Pregledanje dokumenata
+  permission_manage_files: Upravljanje datotekama
+  permission_view_files: Pregledanje datoteka
+  permission_manage_wiki: Upravljanje wiki stranicama
+  permission_rename_wiki_pages: Promena imena wiki stranicama
+  permission_delete_wiki_pages: Brisanje wiki stranica
+  permission_view_wiki_pages: Pregledanje wiki stranica
+  permission_view_wiki_edits: Pregledanje wiki istorije
+  permission_edit_wiki_pages: Izmena wiki stranica
+  permission_delete_wiki_pages_attachments: Brisanje priloÅ¾enih datoteka
+  permission_protect_wiki_pages: ZaÅ¡tita wiki stranica
+  permission_manage_repository: Upravljanje spremiÅ¡tem
+  permission_browse_repository: Pregledanje spremiÅ¡ta
+  permission_view_changesets: Pregledanje skupa promena
+  permission_commit_access: Potvrda pristupa
+  permission_manage_boards: Upravljanje forumima
+  permission_view_messages: Pregledanje poruka
+  permission_add_messages: Slanje poruka
+  permission_edit_messages: Izmena poruka
+  permission_edit_own_messages: Izmena sopstvenih poruka
+  permission_delete_messages: Brisanje poruka
+  permission_delete_own_messages: Brisanje sopstvenih poruka
+  permission_export_wiki_pages: Izvoz wiki stranica
+  permission_manage_subtasks: Upravljanje podzadacima
+
+  project_module_issue_tracking: PraÄ‡enje problema
+  project_module_time_tracking: PraÄ‡enje vremena
+  project_module_news: Vesti
+  project_module_documents: Dokumenti
+  project_module_files: Datoteke
+  project_module_wiki: Wiki
+  project_module_repository: SpremiÅ¡te
+  project_module_boards: Forumi
+
+  label_user: Korisnik
+  label_user_plural: Korisnici
+  label_user_new: Novi korisnik
+  label_user_anonymous: Anoniman
+  label_project: Projekat
+  label_project_new: Novi projekat
+  label_project_plural: Projekti
+  label_x_projects:
+    zero:  nema projekata
+    one:   jedan projekat
+    other: "%{count} projekata"
+  label_project_all: Svi projekti
+  label_project_latest: Poslednji projekti
+  label_issue: Problem
+  label_issue_new: Novi problem
+  label_issue_plural: Problemi
+  label_issue_view_all: Prikaz svih problema
+  label_issues_by: "Problemi (%{value})"
+  label_issue_added: Problem je dodat
+  label_issue_updated: Problem je aÅ¾uriran
+  label_document: Dokument
+  label_document_new: Novi dokument
+  label_document_plural: Dokumenti
+  label_document_added: Dokument je dodat
+  label_role: Uloga
+  label_role_plural: Uloge
+  label_role_new: Nova uloga
+  label_role_and_permissions: Uloge i dozvole
+  label_member: ÄŒlan
+  label_member_new: Novi Älan
+  label_member_plural: ÄŒlanovi
+  label_tracker: PraÄ‡enje
+  label_tracker_plural: PraÄ‡enja
+  label_tracker_new: Novo praÄ‡enje
+  label_workflow: Tok posla
+  label_issue_status: Status problema
+  label_issue_status_plural: Statusi problema
+  label_issue_status_new: Novi status
+  label_issue_category: Kategorija problema
+  label_issue_category_plural: Kategorije problema
+  label_issue_category_new: Nova kategorija
+  label_custom_field: PrilagoÄ‘eno polje
+  label_custom_field_plural: PrilagoÄ‘ena polja
+  label_custom_field_new: Novo prilagoÄ‘eno polje
+  label_enumerations: Nabrojiva lista
+  label_enumeration_new: Nova vrednost
+  label_information: Informacija
+  label_information_plural: Informacije
+  label_please_login: Molimo, prijavite se
+  label_register: Registracija
+  label_login_with_open_id_option: ili prijava sa OpenID
+  label_password_lost: Izgubljena lozinka
+  label_home: PoÄetak
+  label_my_page: Moja stranica
+  label_my_account: Moj nalog
+  label_my_projects: Moji projekti
+  label_my_page_block: My page block
+  label_administration: Administracija
+  label_login: Prijava
+  label_logout: Odjava
+  label_help: PomoÄ‡
+  label_reported_issues: Prijavljeni problemi
+  label_assigned_to_me_issues: Problemi dodeljeni meni
+  label_last_login: Poslednje povezivanje
+  label_registered_on: Registrovan
+  label_activity: Aktivnost
+  label_overall_activity: Celokupna aktivnost
+  label_user_activity: "Aktivnost korisnika %{value}"
+  label_new: Novo
+  label_logged_as: Prijavljeni ste kao
+  label_environment: OkruÅ¾enje
+  label_authentication: Potvrda identiteta
+  label_auth_source: ReÅ¾im potvrde identiteta
+  label_auth_source_new: Novi reÅ¾im potvrde identiteta
+  label_auth_source_plural: ReÅ¾imi potvrde identiteta
+  label_subproject_plural: Potprojekti
+  label_subproject_new: Novi potprojekat
+  label_and_its_subprojects: "%{value} i njegovi potprojekti"
+  label_min_max_length: Min. - Maks. duÅ¾ina
+  label_list: Spisak
+  label_date: Datum
+  label_integer: Ceo broj
+  label_float: Sa pokretnim zarezom
+  label_boolean: LogiÄki operator
+  label_string: Tekst
+  label_text: Dugi tekst
+  label_attribute: Osobina
+  label_attribute_plural: Osobine
+  label_no_data: Nema podataka za prikazivanje
+  label_change_status: Promena statusa
+  label_history: Istorija
+  label_attachment: Datoteka
+  label_attachment_new: Nova datoteka
+  label_attachment_delete: Brisanje datoteke
+  label_attachment_plural: Datoteke
+  label_file_added: Datoteka je dodata
+  label_report: IzveÅ¡taj
+  label_report_plural: IzveÅ¡taji
+  label_news: Vesti
+  label_news_new: Dodavanje vesti
+  label_news_plural: Vesti
+  label_news_latest: Poslednje vesti
+  label_news_view_all: Prikaz svih vesti
+  label_news_added: Vesti su dodate
+  label_settings: PodeÅ¡avanja
+  label_overview: Pregled
+  label_version: Verzija
+  label_version_new: Nova verzija
+  label_version_plural: Verzije
+  label_close_versions: Zatvori zavrÅ¡ene verzije
+  label_confirmation: Potvrda
+  label_export_to: 'TakoÄ‘e dostupno i u varijanti:'
+  label_read: ÄŒitanje...
+  label_public_projects: Javni projekti
+  label_open_issues: otvoren
+  label_open_issues_plural: otvorenih
+  label_closed_issues: zatvoren
+  label_closed_issues_plural: zatvorenih
+  label_x_open_issues_abbr_on_total:
+    zero:  0 otvorenih / %{total}
+    one:   1 otvoren / %{total}
+    other: "%{count} otvorenih / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 otvorenih
+    one:   1 otvoren
+    other: "%{count} otvorenih"
+  label_x_closed_issues_abbr:
+    zero:  0 zatvorenih
+    one:   1 zatvoren
+    other: "%{count} zatvorenih"
+  label_total: Ukupno
+  label_permissions: Dozvole
+  label_current_status: Trenutni status
+  label_new_statuses_allowed: Novi statusi dozvoljeni
+  label_all: svi
+  label_none: nijedan
+  label_nobody: nikome
+  label_next: SledeÄ‡e
+  label_previous: Prethodno
+  label_used_by: Koristio
+  label_details: Detalji
+  label_add_note: Dodaj beleÅ¡ku
+  label_per_page: Po strani
+  label_calendar: Kalendar
+  label_months_from: meseci od
+  label_gantt: Gantov dijagram
+  label_internal: UnutraÅ¡nji
+  label_last_changes: "poslednjih %{count} promena"
+  label_change_view_all: PrikaÅ¾i sve promene
+  label_personalize_page: Personalizuj ovu stranu
+  label_comment: Komentar
+  label_comment_plural: Komentari
+  label_x_comments:
+    zero: bez komentara
+    one: jedan komentar
+    other: "%{count} komentara"
+  label_comment_add: Dodaj komentar
+  label_comment_added: Komentar dodat
+  label_comment_delete: ObriÅ¡i komentare
+  label_query: PrilagoÄ‘en upit
+  label_query_plural: PrilagoÄ‘eni upiti
+  label_query_new: Novi upit
+  label_filter_add: Dodavanje filtera
+  label_filter_plural: Filteri
+  label_equals: je
+  label_not_equals: nije
+  label_in_less_than: manje od
+  label_in_more_than: viÅ¡e od
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: u
+  label_today: danas
+  label_all_time: sve vreme
+  label_yesterday: juÄe
+  label_this_week: ove sedmice
+  label_last_week: poslednje sedmice
+  label_last_n_days: "poslednjih %{count} dana"
+  label_this_month: ovog meseca
+  label_last_month: poslednjeg meseca
+  label_this_year: ove godine
+  label_date_range: Vremenski period
+  label_less_than_ago: pre manje od nekoliko dana
+  label_more_than_ago: pre viÅ¡e od nekoliko dana
+  label_ago: pre nekoliko dana
+  label_contains: sadrÅ¾i
+  label_not_contains: ne sadrÅ¾i
+  label_day_plural: dana
+  label_repository: SpremiÅ¡te
+  label_repository_plural: SpremiÅ¡ta
+  label_browse: Pregledanje
+  label_branch: Grana
+  label_tag: Oznaka
+  label_revision: Revizija
+  label_revision_plural: Revizije
+  label_revision_id: "Revizija %{value}"
+  label_associated_revisions: PridruÅ¾ene revizije
+  label_added: dodato
+  label_modified: promenjeno
+  label_copied: kopirano
+  label_renamed: preimenovano
+  label_deleted: izbrisano
+  label_latest_revision: Poslednja revizija
+  label_latest_revision_plural: Poslednje revizije
+  label_view_revisions: Pregled revizija
+  label_view_all_revisions: Pregled svih revizija
+  label_max_size: Maksimalna veliÄina
+  label_sort_highest: PremeÅ¡tanje na vrh
+  label_sort_higher: PremeÅ¡tanje na gore
+  label_sort_lower: PremeÅ¡tanje na dole
+  label_sort_lowest: PremeÅ¡tanje na dno
+  label_roadmap: Plan rada
+  label_roadmap_due_in: "Dospeva %{value}"
+  label_roadmap_overdue: "%{value} najkasnije"
+  label_roadmap_no_issues: Nema problema za ovu verziju
+  label_search: Pretraga
+  label_result_plural: Rezultati
+  label_all_words: Sve reÄi
+  label_wiki: Wiki
+  label_wiki_edit: Wiki izmena
+  label_wiki_edit_plural: Wiki izmene
+  label_wiki_page: Wiki stranica
+  label_wiki_page_plural: Wiki stranice
+  label_index_by_title: Indeksiranje po naslovu
+  label_index_by_date: Indeksiranje po datumu
+  label_current_version: Trenutna verzija
+  label_preview: Pregled
+  label_feed_plural: Izvori vesti
+  label_changes_details: Detalji svih promena
+  label_issue_tracking: PraÄ‡enje problema
+  label_spent_time: UtroÅ¡eno vreme
+  label_overall_spent_time: Celokupno utroÅ¡eno vreme
+  label_f_hour: "%{value} sat"
+  label_f_hour_plural: "%{value} sati"
+  label_time_tracking: PraÄ‡enje vremena
+  label_change_plural: Promene
+  label_statistics: Statistika
+  label_commits_per_month: IzvrÅ¡enja meseÄno
+  label_commits_per_author: IzvrÅ¡enja po autoru
+  label_view_diff: Pogledaj razlike
+  label_diff_inline: unutra
+  label_diff_side_by_side: uporedo
+  label_options: Opcije
+  label_copy_workflow_from: Kopiranje toka posla od
+  label_permissions_report: IzveÅ¡taj o dozvolama
+  label_watched_issues: Posmatrani problemi
+  label_related_issues: Srodni problemi
+  label_applied_status: Primenjeni statusi
+  label_loading: UÄitavanje...
+  label_relation_new: Nova relacija
+  label_relation_delete: Brisanje relacije
+  label_relates_to: srodnih sa
+  label_duplicates: dupliranih
+  label_duplicated_by: dupliranih od
+  label_blocks: odbijenih
+  label_blocked_by: odbijenih od
+  label_precedes: prethodi
+  label_follows: praÄ‡enih
+  label_end_to_start: od kraja do poÄetka
+  label_end_to_end: od kraja do kraja
+  label_start_to_start: od poÄetka do poÄetka
+  label_start_to_end: od poÄetka do kraja
+  label_stay_logged_in: Ostanite prijavljeni
+  label_disabled: onemoguÄ‡eno
+  label_show_completed_versions: Prikazivanje zavrÅ¡ene verzije
+  label_me: meni
+  label_board: Forum
+  label_board_new: Novi forum
+  label_board_plural: Forumi
+  label_board_locked: ZakljuÄana
+  label_board_sticky: Lepljiva
+  label_topic_plural: Teme
+  label_message_plural: Poruke
+  label_message_last: Poslednja poruka
+  label_message_new: Nova poruka
+  label_message_posted: Poruka je dodata
+  label_reply_plural: Odgovori
+  label_send_information: PoÅ¡alji korisniku detalje naloga
+  label_year: Godina
+  label_month: Mesec
+  label_week: Sedmica
+  label_date_from: Å alje
+  label_date_to: Prima
+  label_language_based: Bazirano na jeziku korisnika
+  label_sort_by: "Sortirano po %{value}"
+  label_send_test_email: Slanje probne e-poruke
+  label_feeds_access_key: RSS pristupni kljuÄ
+  label_missing_feeds_access_key: RSS pristupni kljuÄ nedostaje
+  label_feeds_access_key_created_on: "RSS pristupni kljuÄ je napravljen pre %{value}"
+  label_module_plural: Moduli
+  label_added_time_by: "Dodao %{author} pre %{age}"
+  label_updated_time_by: "AÅ¾urirao %{author} pre %{age}"
+  label_updated_time: "AÅ¾urirano pre %{value}"
+  label_jump_to_a_project: Skok na projekat...
+  label_file_plural: Datoteke
+  label_changeset_plural: Skupovi promena
+  label_default_columns: Podrazumevane kolone
+  label_no_change_option: (Bez promena)
+  label_bulk_edit_selected_issues: Grupna izmena odabranih problema
+  label_theme: Tema
+  label_default: Podrazumevano
+  label_search_titles_only: PretraÅ¾uj samo naslove
+  label_user_mail_option_all: "Za bilo koji dogaÄ‘aj na svim mojim projektima"
+  label_user_mail_option_selected: "Za bilo koji dogaÄ‘aj na samo odabranim projektima..."
+  label_user_mail_no_self_notified: "Ne Å¾elim biti obaveÅ¡tavan za promene koje sam pravim"
+  label_registration_activation_by_email: aktivacija naloga putem e-poruke
+  label_registration_manual_activation: ruÄna aktivacija naloga
+  label_registration_automatic_activation: automatska aktivacija naloga
+  label_display_per_page: "Broj stavki po stranici: %{value}"
+  label_age: Starost
+  label_change_properties: Promeni svojstva
+  label_general: OpÅ¡ti
+  label_more: ViÅ¡e
+  label_scm: SCM
+  label_plugins: Dodatne komponente
+  label_ldap_authentication: LDAP potvrda identiteta
+  label_downloads_abbr: D/L
+  label_optional_description: Opciono opis
+  label_add_another_file: Dodaj joÅ¡ jednu datoteku
+  label_preferences: PodeÅ¡avanja
+  label_chronological_order: po hronoloÅ¡kom redosledu
+  label_reverse_chronological_order: po obrnutom hronoloÅ¡kom redosledu
+  label_planning: Planiranje
+  label_incoming_emails: Dolazne e-poruke
+  label_generate_key: Generisanje kljuÄa
+  label_issue_watchers: PosmatraÄi
+  label_example: Primer
+  label_display: Prikaz
+  label_sort: Sortiranje
+  label_ascending: RastuÄ‡i niz
+  label_descending: OpadajuÄ‡i niz
+  label_date_from_to: Od %{start} do %{end}
+  label_wiki_content_added: Wiki stranica je dodata
+  label_wiki_content_updated: Wiki stranica je aÅ¾urirana
+  label_group: Grupa
+  label_group_plural: Grupe
+  label_group_new: Nova grupa
+  label_time_entry_plural: UtroÅ¡eno vreme
+  label_version_sharing_none: Nije deljeno
+  label_version_sharing_descendants: Sa potprojektima
+  label_version_sharing_hierarchy: Sa hijerarhijom projekta
+  label_version_sharing_tree: Sa stablom projekta
+  label_version_sharing_system: Sa svim projektima
+  label_update_issue_done_ratios: AÅ¾uriraj odnos reÅ¡enih problema
+  label_copy_source: Izvor
+  label_copy_target: OdrediÅ¡te
+  label_copy_same_as_target: Isto kao odrediÅ¡te
+  label_display_used_statuses_only: Prikazuj statuse koriÅ¡Ä‡ene samo od strane ovog praÄ‡enja
+  label_api_access_key: API pristupni kljuÄ
+  label_missing_api_access_key: Nedostaje API pristupni kljuÄ
+  label_api_access_key_created_on: "API pristupni kljuÄ je kreiran pre %{value}"
+  label_profile: Profil
+  label_subtask_plural: Podzadatak
+  label_project_copy_notifications: PoÅ¡alji e-poruku sa obaveÅ¡tenjem prilikom kopiranja projekta
+
+  button_login: Prijava
+  button_submit: PoÅ¡alji
+  button_save: Snimi
+  button_check_all: UkljuÄi sve
+  button_uncheck_all: IskljuÄi sve
+  button_delete: IzbriÅ¡i
+  button_create: Kreiraj
+  button_create_and_continue: Kreiraj i nastavi
+  button_test: Test
+  button_edit: Izmeni
+  button_add: Dodaj
+  button_change: Promeni
+  button_apply: Primeni
+  button_clear: ObriÅ¡i
+  button_lock: ZakljuÄaj
+  button_unlock: OtkljuÄaj
+  button_download: Preuzmi
+  button_list: Spisak
+  button_view: PrikaÅ¾i
+  button_move: Pomeri
+  button_move_and_follow: Pomeri i prati
+  button_back: Nazad
+  button_cancel: PoniÅ¡ti
+  button_activate: Aktiviraj
+  button_sort: Sortiraj
+  button_log_time: Evidentiraj vreme
+  button_rollback: Povratak na ovu verziju
+  button_watch: Prati
+  button_unwatch: Ne prati viÅ¡e
+  button_reply: Odgovori
+  button_archive: Arhiviraj
+  button_unarchive: Vrati iz arhive
+  button_reset: PoniÅ¡ti
+  button_rename: Preimenuj
+  button_change_password: Promeni lozinku
+  button_copy: Kopiraj
+  button_copy_and_follow: Kopiraj i prati
+  button_annotate: PribeleÅ¾i
+  button_update: AÅ¾uriraj
+  button_configure: Podesi
+  button_quote: Pod navodnicima
+  button_duplicate: Dupliraj
+  button_show: PrikaÅ¾i
+
+  status_active: aktivni
+  status_registered: registrovani
+  status_locked: zakljuÄani
+
+  version_status_open: otvoren
+  version_status_locked: zakljuÄan
+  version_status_closed: zatvoren
+
+  field_active: Aktivan
+
+  text_select_mail_notifications: Odaberi akcije za koje Ä‡e obaveÅ¡tenje biti poslato putem e-poÅ¡te.
+  text_regexp_info: npr. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 znaÄi bez ograniÄenja
+  text_project_destroy_confirmation: Jeste li sigurni da Å¾elite da izbriÅ¡ete ovaj projekat i sve pripadajuÄ‡e podatke?
+  text_subprojects_destroy_warning: "Potprojekti: %{value} Ä‡e takoÄ‘e biti izbrisan."
+  text_workflow_edit: Odaberite ulogu i praÄ‡enje za izmenu toka posla
+  text_are_you_sure: Jeste li sigurni?
+  text_journal_changed: "%{label} promenjen od %{old} u %{new}"
+  text_journal_set_to: "%{label} postavljen u %{value}"
+  text_journal_deleted: "%{label} izbrisano (%{old})"
+  text_journal_added: "%{label} %{value} dodato"
+  text_tip_issue_begin_day: zadatak poÄinje ovog dana
+  text_tip_issue_end_day: zadatak se zavrÅ¡ava ovog dana
+  text_tip_issue_begin_end_day: zadatak poÄinje i zavrÅ¡ava ovog dana
+  text_caracters_maximum: "NajviÅ¡e %{count} znak(ova)."
+  text_caracters_minimum: "Broj znakova mora biti najmanje %{count}."
+  text_length_between: "Broj znakova mora biti izmeÄ‘u %{min} i %{max}."
+  text_tracker_no_workflow: Ovo praÄ‡enje nema definisan tok posla
+  text_unallowed_characters: Nedozvoljeni znakovi
+  text_comma_separated: Dozvoljene su viÅ¡estruke vrednosti (odvojene zarezom).
+  text_line_separated: Dozvoljene su viÅ¡estruke vrednosti (jedan red za svaku vrednost).
+  text_issues_ref_in_commit_messages: Referenciranje i popravljanje problema u izvrÅ¡nim porukama
+  text_issue_added: "%{author} je prijavio problem %{id}."
+  text_issue_updated: "%{author} je aÅ¾urirao problem %{id}."
+  text_wiki_destroy_confirmation: Jeste li sigurni da Å¾elite da obriÅ¡ete wiki i sav sadrÅ¾aj?
+  text_issue_category_destroy_question: "Nekoliko problema (%{count}) je dodeljeno ovoj kategoriji. Å ta Å¾elite da uradite?"
+  text_issue_category_destroy_assignments: Ukloni dodeljene kategorije
+  text_issue_category_reassign_to: Dodeli ponovo probleme ovoj kategoriji
+  text_user_mail_option: "Za neizabrane projekte, dobiÄ‡ete samo obaveÅ¡tenje o stvarima koje pratite ili ste ukljuÄeni (npr. problemi Äiji ste vi autor ili zastupnik)."
+  text_no_configuration_data: "Uloge, praÄ‡enja, statusi problema i toka posla joÅ¡ uvek nisu podeÅ¡eni.\nPreporuÄljivo je da uÄitate podrazumevano konfigurisanje. Izmena je moguÄ‡a nakon prvog uÄitavanja."
+  text_load_default_configuration: UÄitaj podrazumevano konfigurisanje
+  text_status_changed_by_changeset: "Primenjeno u skupu sa promenama %{value}."
+  text_issues_destroy_confirmation: 'Jeste li sigurni da Å¾elite da izbriÅ¡ete odabrane probleme?'
+  text_select_project_modules: 'Odaberite module koje Å¾elite omoguÄ‡iti za ovaj projekat:'
+  text_default_administrator_account_changed: Podrazumevani administratorski nalog je promenjen
+  text_file_repository_writable: Fascikla priloÅ¾enih datoteka je upisiva
+  text_plugin_assets_writable: Fascikla elemenata dodatnih komponenti je upisiva
+  text_rmagick_available: RMagick je dostupan (opciono)
+  text_destroy_time_entries_question: "%{hours} sati je prijavljeno za ovaj problem koji Å¾elite izbrisati. Å ta Å¾elite da uradite?"
+  text_destroy_time_entries: IzbriÅ¡i prijavljene sate
+  text_assign_time_entries_to_project: Dodeli prijavljene sate projektu
+  text_reassign_time_entries: 'Dodeli ponovo prijavljene sate ovom problemu:'
+  text_user_wrote: "%{value} je napisao:"
+  text_enumeration_destroy_question: "%{count} objekat(a) je dodeljeno ovoj vrednosti."
+  text_enumeration_category_reassign_to: 'Dodeli ih ponovo ovoj vrednosti:'
+  text_email_delivery_not_configured: "Isporuka e-poruka nije konfigurisana i obaveÅ¡tenja su onemoguÄ‡ena.\nPodesite vaÅ¡ SMTP server u config/configuration.yml i pokrenite ponovo aplikaciju za njihovo omoguÄ‡avanje."
+  text_repository_usernames_mapping: "Odaberite ili aÅ¾urirajte Redmine korisnike mapiranjem svakog korisniÄkog imena pronaÄ‘enog u evidenciji spremiÅ¡ta.\nKorisnici sa istim Redmine imenom i imenom spremiÅ¡ta ili e-adresom su automatski mapirani."
+  text_diff_truncated: '... Ova razlika je iseÄena jer je dostignuta maksimalna veliÄina prikaza.'
+  text_custom_field_possible_values_info: 'Jedan red za svaku vrednost'
+  text_wiki_page_destroy_question: "Ova stranica ima %{descendants} podreÄ‘enih stranica i podstranica. Å ta Å¾elite da uradite?"
+  text_wiki_page_nullify_children: "ZadrÅ¾i podreÄ‘ene stranice kao korene stranice"
+  text_wiki_page_destroy_children: "IzbriÅ¡i podreÄ‘ene stranice i sve njihove podstranice"
+  text_wiki_page_reassign_children: "Dodeli ponovo podreÄ‘ene stranice ovoj matiÄnoj stranici"
+  text_own_membership_delete_confirmation: "Nakon uklanjanja pojedinih ili svih vaÅ¡ih dozvola neÄ‡ete viÅ¡e moÄ‡i da ureÄ‘ujete ovaj projekat.\nÅ½elite li da nastavite?"
+  text_zoom_in: UveÄ‡aj
+  text_zoom_out: Umanji
+
+  default_role_manager: MenadÅ¾er
+  default_role_developer: Programer
+  default_role_reporter: IzveÅ¡taÄ
+  default_tracker_bug: GreÅ¡ka
+  default_tracker_feature: Funkcionalnost
+  default_tracker_support: PodrÅ¡ka
+  default_issue_status_new: Novo
+  default_issue_status_in_progress: U toku
+  default_issue_status_resolved: ReÅ¡eno
+  default_issue_status_feedback: Povratna informacija
+  default_issue_status_closed: Zatvoreno
+  default_issue_status_rejected: Odbijeno
+  default_doc_category_user: KorisniÄka dokumentacija
+  default_doc_category_tech: TehniÄka dokumentacija
+  default_priority_low: Nizak
+  default_priority_normal: Normalan
+  default_priority_high: Visok
+  default_priority_urgent: Hitno
+  default_priority_immediate: Neposredno
+  default_activity_design: Dizajn
+  default_activity_development: Razvoj
+
+  enumeration_issue_priorities: Prioriteti problema
+  enumeration_doc_categories: Kategorije dokumenta
+  enumeration_activities: Aktivnosti (praÄ‡enje vremena)
+  enumeration_system_activity: Sistemska aktivnost
+
+  field_time_entries: Vreme evidencije
+  project_module_gantt: Gantov dijagram
+  project_module_calendar: Kalendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Samo za stvari koje posedujem
+  setting_default_notification_option: Podrazumevana opcija za notifikaciju
+  label_user_mail_option_only_my_events: Za dogadjaje koje pratim ili sam u njih ukljuÄen
+  label_user_mail_option_only_assigned: Za dogadjaje koji su mi dodeljeni liÄno
+  label_user_mail_option_none: Bez obaveÅ¡tenja
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: Projekat kome pokuÅ¡avate da pristupite je arhiviran
+  label_principal_search: "TraÅ¾i korisnike ili grupe:"
+  label_user_search: "TraÅ¾i korisnike:"
+  field_visible: Vidljivo
+  setting_emails_header: Email zaglavlje
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: OmoguÄ‡i praÄ‡enje vremena
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maksimalan broj stavki na gant grafiku
+  field_warn_on_leaving_unsaved: Upozori me ako napuÅ¡tam stranu sa tekstom koji nije snimljen
+  text_warn_on_leaving_unsaved: Strana sadrÅ¾i tekst koji nije snimljen i biÄ‡e izgubljen ako je napustite.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} aÅ¾uriran"
+  label_news_comment_added: Komentar dodat u novosti
+  button_expand_all: ProÅ¡iri sve
+  button_collapse_all: Zatvori sve
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Da li ste sigurni da Å¾elite da obriÅ¡ete selektovane stavke ?
+  label_role_anonymous: Anonimus
+  label_role_non_member: Nije Älan
+  label_issue_note_added: Nota dodana
+  label_issue_status_updated: Status aÅ¾uriran
+  label_issue_priority_updated: Prioritet aÅ¾uriran
+  label_issues_visibility_own: Problem kreiran od strane ili je dodeljen korisniku
+  field_issues_visibility: Vidljivost problema
+  label_issues_visibility_all: Svi problemi
+  permission_set_own_issues_private: Podesi sopstveni problem kao privatan ili javan
+  field_is_private: Privatno
+  permission_set_issues_private: Podesi problem kao privatan ili javan
+  label_issues_visibility_public: Svi javni problemi
+  text_issues_destroy_descendants_confirmation: Ova operacija Ä‡e takoÄ‘e obrisati  %{count} podzadataka.
+  field_commit_logs_encoding: Kodiranje izvrÅ¡nih poruka
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 problem
+    one:   1 problem
+    other: "%{count} problemi"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: svi
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Sa potprojektima
+  label_cross_project_tree: Sa stablom projekta
+  label_cross_project_hierarchy: Sa hijerarhijom projekta
+  label_cross_project_system: Sa svim projektima
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ukupno
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/764f20578b33c5ef0c99adc3a136111ff27ce87f.svn-base
--- a/.svn/pristine/76/764f20578b33c5ef0c99adc3a136111ff27ce87f.svn-base
+++ /dev/null
@@ -1,65 +0,0 @@
-module CodeRay
-module Encoders
-
-  class HTML
-    class CSS  # :nodoc:
-
-      attr :stylesheet
-
-      def CSS.load_stylesheet style = nil
-        CodeRay::Styles[style]
-      end
-
-      def initialize style = :default
-        @classes = Hash.new
-        style = CSS.load_stylesheet style
-        @stylesheet = [
-          style::CSS_MAIN_STYLES,
-          style::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ')
-        ].join("\n")
-        parse style::TOKEN_COLORS
-      end
-
-      def get_style styles
-        cl = @classes[styles.first]
-        return '' unless cl
-        style = ''
-        1.upto styles.size do |offset|
-          break if style = cl[styles[offset .. -1]]
-        end
-        # warn 'Style not found: %p' % [styles] if style.empty?
-        return style
-      end
-
-    private
-
-      CSS_CLASS_PATTERN = /
-        (                    # $1 = selectors
-          (?:
-            (?: \s* \. [-\w]+ )+
-            \s* ,?
-          )+
-        )
-        \s* \{ \s*
-        ( [^\}]+ )?          # $2 = style
-        \s* \} \s*
-      |
-        ( [^\n]+ )           # $3 = error
-      /mx
-      def parse stylesheet
-        stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error|
-          raise "CSS parse error: '#{error.inspect}' not recognized" if error
-          for selector in selectors.split(',')
-            classes = selector.scan(/[-\w]+/)
-            cl = classes.pop
-            @classes[cl] ||= Hash.new
-            @classes[cl][classes] = style.to_s.strip.delete(' ').chomp(';')
-          end
-        end
-      end
-
-    end
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/7653b9d7574c0a4c89892ba03eb88b9209dbb271.svn-base
--- a/.svn/pristine/76/7653b9d7574c0a4c89892ba03eb88b9209dbb271.svn-base
+++ /dev/null
@@ -1,66 +0,0 @@
-module CodeRay
-module Scanners
-
-  # = Debug Scanner
-  # 
-  # Parses the output of the Encoders::Debug encoder.
-  class Raydebug < Scanner
-
-    register_for :raydebug
-    file_extension 'raydebug'
-    title 'CodeRay Token Dump'
-    
-  protected
-    
-    def scan_tokens encoder, options
-
-      opened_tokens = []
-
-      until eos?
-
-        if match = scan(/\s+/)
-          encoder.text_token match, :space
-          
-        elsif match = scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) /x)
-          kind = self[1]
-          encoder.text_token kind, :class
-          encoder.text_token '(', :operator
-          match = self[2]
-          encoder.text_token match, kind.to_sym
-          encoder.text_token match, :operator if match = scan(/\)/)
-          
-        elsif match = scan(/ (\w+) ([<\[]) /x)
-          kind = self[1]
-          case self[2]
-          when '<'
-            encoder.text_token kind, :class
-          when '['
-            encoder.text_token kind, :class
-          else
-            raise 'CodeRay bug: This case should not be reached.'
-          end
-          kind = kind.to_sym
-          opened_tokens << kind
-          encoder.begin_group kind
-          encoder.text_token self[2], :operator
-          
-        elsif !opened_tokens.empty? && match = scan(/ [>\]] /x)
-          encoder.text_token match, :operator
-          encoder.end_group opened_tokens.pop
-          
-        else
-          encoder.text_token getch, :space
-          
-        end
-        
-      end
-      
-      encoder.end_group opened_tokens.pop until opened_tokens.empty?
-      
-      encoder
-    end
-
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/765c4d02e29c8c91040d1cddac7513edae190213.svn-base
--- a/.svn/pristine/76/765c4d02e29c8c91040d1cddac7513edae190213.svn-base
+++ /dev/null
@@ -1,18 +0,0 @@
-<h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%=h @message.subject %></h2>
-
-<% form_for :message, @message, :url => {:action => 'edit'}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
-  <%= render :partial => 'form', :locals => {:f => f, :replying => !@message.parent.nil?} %>
-  <%= submit_tag l(:button_save) %>
-  <%= link_to_remote l(:label_preview),
-                     { :url => { :controller => 'messages', :action => 'preview', :board_id => @board },
-                       :method => 'post',
-                       :update => 'preview',
-                       :with => "Form.serialize('message-form')",
-                       :complete => "Element.scrollTo('preview')"
-                     }, :accesskey => accesskey(:preview) %>
-<% end %>
-<div id="preview" class="wiki"></div>
-
-<% content_for :header_tags do %>
-    <%= stylesheet_link_tag 'scm' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/7692f8f9ec64d588c08e89635d4d3bb3b5c0c1d4.svn-base
--- a/.svn/pristine/76/7692f8f9ec64d588c08e89635d4d3bb3b5c0c1d4.svn-base
+++ /dev/null
@@ -1,44 +0,0 @@
---- 
-projects_trackers_001: 
-  project_id: 4
-  tracker_id: 3
-projects_trackers_002: 
-  project_id: 1
-  tracker_id: 1
-projects_trackers_003: 
-  project_id: 5
-  tracker_id: 1
-projects_trackers_004: 
-  project_id: 1
-  tracker_id: 2
-projects_trackers_005: 
-  project_id: 5
-  tracker_id: 2
-projects_trackers_006: 
-  project_id: 5
-  tracker_id: 3
-projects_trackers_007: 
-  project_id: 2
-  tracker_id: 1
-projects_trackers_008: 
-  project_id: 2
-  tracker_id: 2
-projects_trackers_009: 
-  project_id: 2
-  tracker_id: 3
-projects_trackers_010: 
-  project_id: 3
-  tracker_id: 2
-projects_trackers_011: 
-  project_id: 3
-  tracker_id: 3
-projects_trackers_012: 
-  project_id: 4
-  tracker_id: 1
-projects_trackers_013: 
-  project_id: 4
-  tracker_id: 2
-projects_trackers_014: 
-  project_id: 1
-  tracker_id: 3
-  
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/76b52953c1403e5158177a89f2ffc5c4d36f9088.svn-base
--- /dev/null
+++ b/.svn/pristine/76/76b52953c1403e5158177a89f2ffc5c4d36f9088.svn-base
@@ -0,0 +1,48 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class SearchHelperTest < ActionView::TestCase
+  include SearchHelper
+  include ERB::Util
+
+  def test_highlight_single_token
+    assert_equal 'This is a <span class="highlight token-0">token</span>.',
+                 highlight_tokens('This is a token.', %w(token))
+  end
+
+  def test_highlight_multiple_tokens
+    assert_equal 'This is a <span class="highlight token-0">token</span> and <span class="highlight token-1">another</span> <span class="highlight token-0">token</span>.',
+                 highlight_tokens('This is a token and another token.', %w(token another))
+  end
+
+  def test_highlight_should_not_exceed_maximum_length
+    s = (('1234567890' * 100) + ' token ') * 100
+    r = highlight_tokens(s, %w(token))
+    assert r.include?('<span class="highlight token-0">token</span>')
+    assert r.length <= 1300
+  end
+
+  def test_highlight_multibyte
+    s = ('Ð¹' * 200) + ' token ' + ('Ð¹' * 200)
+    r = highlight_tokens(s, %w(token))
+    assert_equal  ('Ð¹' * 45) + ' ... ' + ('Ð¹' * 44) + ' <span class="highlight token-0">token</span> ' + ('Ð¹' * 44) + ' ... ' + ('Ð¹' * 45), r
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/76/76f5b1657c4e0eb2717b1dfffe6b49bb8cd094b8.svn-base
--- /dev/null
+++ b/.svn/pristine/76/76f5b1657c4e0eb2717b1dfffe6b49bb8cd094b8.svn-base
@@ -0,0 +1,22 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class VersionCustomField < CustomField
+  def type_name
+    :label_version_plural
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/77/7718e8a0efeaa5f26e8369285e5ddf3e72a45738.svn-base
--- a/.svn/pristine/77/7718e8a0efeaa5f26e8369285e5ddf3e72a45738.svn-base
+++ /dev/null
@@ -1,26 +0,0 @@
-class PluginMail < ActionMailer::Base
-  def mail_from_plugin(note=nil)
-    body(:note => note)
-  end
-  
-  def mail_from_plugin_with_application_template(note=nil)
-    body(:note => note)
-  end
-  
-  def multipart_from_plugin
-    content_type 'multipart/alternative'
-    part :content_type => "text/html", :body => render_message("multipart_from_plugin_html", {})
-    part "text/plain" do |p|
-      p.body = render_message("multipart_from_plugin_plain", {})
-    end
-  end
-  
-  def multipart_from_plugin_with_application_template
-    content_type 'multipart/alternative'
-    part :content_type => "text/html", :body => render_message("multipart_from_plugin_with_application_template_html", {})
-    part "text/plain" do |p|
-      p.body = render_message("multipart_from_plugin_with_application_template_plain", {})
-    end
-  end  
-  
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/77/7727bb04d0abb3e8e4031848fb82a82cb998f0af.svn-base
--- /dev/null
+++ b/.svn/pristine/77/7727bb04d0abb3e8e4031848fb82a82cb998f0af.svn-base
@@ -0,0 +1,115 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Acts
+    module Attachable
+      def self.included(base)
+        base.extend ClassMethods
+      end
+
+      module ClassMethods
+        def acts_as_attachable(options = {})
+          cattr_accessor :attachable_options
+          self.attachable_options = {}
+          attachable_options[:view_permission] = options.delete(:view_permission) || "view_#{self.name.pluralize.underscore}".to_sym
+          attachable_options[:delete_permission] = options.delete(:delete_permission) || "edit_#{self.name.pluralize.underscore}".to_sym
+
+          has_many :attachments, options.merge(:as => :container,
+                                               :order => "#{Attachment.table_name}.created_on ASC, #{Attachment.table_name}.id ASC",
+                                               :dependent => :destroy)
+          send :include, Redmine::Acts::Attachable::InstanceMethods
+          before_save :attach_saved_attachments
+        end
+      end
+
+      module InstanceMethods
+        def self.included(base)
+          base.extend ClassMethods
+        end
+
+        def attachments_visible?(user=User.current)
+          (respond_to?(:visible?) ? visible?(user) : true) &&
+            user.allowed_to?(self.class.attachable_options[:view_permission], self.project)
+        end
+
+        def attachments_deletable?(user=User.current)
+          (respond_to?(:visible?) ? visible?(user) : true) &&
+            user.allowed_to?(self.class.attachable_options[:delete_permission], self.project)
+        end
+
+        def saved_attachments
+          @saved_attachments ||= []
+        end
+
+        def unsaved_attachments
+          @unsaved_attachments ||= []
+        end
+
+        def save_attachments(attachments, author=User.current)
+          if attachments.is_a?(Hash)
+            attachments = attachments.stringify_keys
+            attachments = attachments.to_a.sort {|a, b|
+              if a.first.to_i > 0 && b.first.to_i > 0
+                a.first.to_i <=> b.first.to_i
+              elsif a.first.to_i > 0
+                1
+              elsif b.first.to_i > 0
+                -1
+              else
+                a.first <=> b.first
+              end
+            }
+            attachments = attachments.map(&:last)
+          end
+          if attachments.is_a?(Array)
+            attachments.each do |attachment|
+              next unless attachment.is_a?(Hash)
+              a = nil
+              if file = attachment['file']
+                next unless file.size > 0
+                a = Attachment.create(:file => file, :author => author)
+              elsif token = attachment['token']
+                a = Attachment.find_by_token(token)
+                next unless a
+                a.filename = attachment['filename'] unless attachment['filename'].blank?
+                a.content_type = attachment['content_type']
+              end
+              next unless a
+              a.description = attachment['description'].to_s.strip
+              if a.new_record?
+                unsaved_attachments << a
+              else
+                saved_attachments << a
+              end
+            end
+          end
+          {:files => saved_attachments, :unsaved => unsaved_attachments}
+        end
+
+        def attach_saved_attachments
+          saved_attachments.each do |attachment|
+            self.attachments << attachment
+          end
+        end
+
+        module ClassMethods
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/77/77535eb0610e7a795a3a338ad92c9bcb966e9ab9.svn-base
--- a/.svn/pristine/77/77535eb0610e7a795a3a338ad92c9bcb966e9ab9.svn-base
+++ /dev/null
@@ -1,63 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class MemberRole < ActiveRecord::Base
-  belongs_to :member
-  belongs_to :role
-
-  after_destroy :remove_member_if_empty
-
-  after_create :add_role_to_group_users
-  after_destroy :remove_role_from_group_users
-
-  validates_presence_of :role
-
-  def validate
-    errors.add :role_id, :invalid if role && !role.member?
-  end
-
-  def inherited?
-    !inherited_from.nil?
-  end
-
-  private
-
-  def remove_member_if_empty
-    if member.roles.empty?
-      member.destroy
-    end
-  end
-
-  def add_role_to_group_users
-    if member.principal.is_a?(Group)
-      member.principal.users.each do |user|
-        user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id)
-        user_member.member_roles << MemberRole.new(:role => role, :inherited_from => id)
-        user_member.save!
-      end
-    end
-  end
-
-  def remove_role_from_group_users
-    MemberRole.find(:all, :conditions => { :inherited_from => id }).group_by(&:member).each do |member, member_roles|
-      member_roles.each(&:destroy)
-      if member && member.user
-        Watcher.prune(:user => member.user, :project => member.project)
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/77/77b5f4fec79f0d6eb61a76e965e02cb7504641fe.svn-base
--- /dev/null
+++ b/.svn/pristine/77/77b5f4fec79f0d6eb61a76e965e02cb7504641fe.svn-base
@@ -0,0 +1,306 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoryBazaarTest < ActiveSupport::TestCase
+  fixtures :projects
+
+  include Redmine::I18n
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s
+  REPOSITORY_PATH_TRUNK = File.join(REPOSITORY_PATH, "trunk")
+  NUM_REV = 4
+
+  REPOSITORY_PATH_NON_ASCII = Rails.root.join(REPOSITORY_PATH + '/' + 'non_ascii').to_s
+
+  # Bazaar core does not support xml output such as Subversion and Mercurial.
+  # "bzr" command output and command line parameter depend on locale.
+  # So, non ASCII path tests cannot run independent locale.
+  #
+  # If you want to run Bazaar non ASCII path tests on Linux *Ruby 1.9*,
+  # you need to set locale character set "ISO-8859-1".
+  # E.g. "LANG=en_US.ISO-8859-1".
+  # On Linux other platforms (e.g. Ruby 1.8, JRuby),
+  # you need to set "RUN_LATIN1_OUTPUT_TEST = true" manually.
+  #
+  # On Windows, because it is too hard to change system locale,
+  # you cannot run Bazaar non ASCII path tests.
+  #
+  RUN_LATIN1_OUTPUT_TEST = (RUBY_PLATFORM != 'java' &&
+                             REPOSITORY_PATH.respond_to?(:force_encoding) &&
+                             Encoding.locale_charmap == "ISO-8859-1")
+
+  CHAR_1_UTF8_HEX   = "\xc3\x9c"
+  CHAR_1_LATIN1_HEX = "\xdc"
+
+  def setup
+    @project = Project.find(3)
+    @repository = Repository::Bazaar.create(
+              :project => @project, :url => REPOSITORY_PATH_TRUNK,
+              :log_encoding => 'UTF-8')
+    assert @repository
+    @char_1_utf8      = CHAR_1_UTF8_HEX.dup
+    @char_1_ascii8bit = CHAR_1_LATIN1_HEX.dup
+    if @char_1_utf8.respond_to?(:force_encoding)
+      @char_1_utf8.force_encoding('UTF-8')
+      @char_1_ascii8bit.force_encoding('ASCII-8BIT')
+    end
+  end
+
+  def test_blank_path_to_repository_error_message
+    set_language_if_valid 'en'
+    repo = Repository::Bazaar.new(
+                          :project      => @project,
+                          :identifier   => 'test',
+                          :log_encoding => 'UTF-8'
+                        )
+    assert !repo.save
+    assert_include "Path to repository can't be blank",
+                   repo.errors.full_messages
+  end
+
+  def test_blank_path_to_repository_error_message_fr
+    set_language_if_valid 'fr'
+    str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    repo = Repository::Bazaar.new(
+                          :project      => @project,
+                          :url          => "",
+                          :identifier   => 'test',
+                          :log_encoding => 'UTF-8'
+                        )
+    assert !repo.save
+    assert_include str, repo.errors.full_messages
+  end
+
+  if File.directory?(REPOSITORY_PATH_TRUNK)
+    def test_fetch_changesets_from_scratch
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_equal 9, @repository.filechanges.count
+      assert_equal 'Initial import', @repository.changesets.find_by_revision('1').comments
+    end
+
+    def test_fetch_changesets_incremental
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      # Remove changesets with revision > 5
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 2}
+      @project.reload
+      assert_equal 2, @repository.changesets.count
+
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+    end
+
+    def test_entries
+      entries = @repository.entries
+      assert_kind_of Redmine::Scm::Adapters::Entries, entries
+      assert_equal 2, entries.size
+
+      assert_equal 'dir', entries[0].kind
+      assert_equal 'directory', entries[0].name
+      assert_equal 'directory', entries[0].path
+
+      assert_equal 'file', entries[1].kind
+      assert_equal 'doc-mkdir.txt', entries[1].name
+      assert_equal 'doc-mkdir.txt', entries[1].path
+    end
+
+    def test_entries_in_subdirectory
+      entries = @repository.entries('directory')
+      assert_equal 3, entries.size
+
+      assert_equal 'file', entries.last.kind
+      assert_equal 'edit.png', entries.last.name
+      assert_equal 'directory/edit.png', entries.last.path
+    end
+
+    def test_previous
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      changeset = @repository.find_changeset_by_name('3')
+      assert_equal @repository.find_changeset_by_name('2'), changeset.previous
+    end
+
+    def test_previous_nil
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      changeset = @repository.find_changeset_by_name('1')
+      assert_nil changeset.previous
+    end
+
+    def test_next
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      changeset = @repository.find_changeset_by_name('2')
+      assert_equal @repository.find_changeset_by_name('3'), changeset.next
+    end
+
+    def test_next_nil
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      changeset = @repository.find_changeset_by_name('4')
+      assert_nil changeset.next
+    end
+
+    if File.directory?(REPOSITORY_PATH_NON_ASCII) && RUN_LATIN1_OUTPUT_TEST
+      def test_cat_latin1_path
+        latin1_repo = create_latin1_repo
+        buf = latin1_repo.cat(
+                 "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-2.txt", 2)
+        assert buf
+        lines = buf.split("\n")
+        assert_equal 2, lines.length
+        assert_equal 'It is written in Python.', lines[1]
+
+        buf = latin1_repo.cat(
+                 "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", 2)
+        assert buf
+        lines = buf.split("\n")
+        assert_equal 1, lines.length
+        assert_equal "test-#{@char_1_ascii8bit}.txt", lines[0]
+      end
+
+      def test_annotate_latin1_path
+        latin1_repo = create_latin1_repo
+        ann1 = latin1_repo.annotate(
+                   "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-2.txt", 2)
+        assert_equal 2, ann1.lines.size
+        assert_equal '2', ann1.revisions[0].identifier
+        assert_equal 'test00@', ann1.revisions[0].author
+        assert_equal 'It is written in Python.', ann1.lines[1]
+        ann2 = latin1_repo.annotate(
+                   "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", 2)
+        assert_equal 1, ann2.lines.size
+        assert_equal '2', ann2.revisions[0].identifier
+        assert_equal 'test00@', ann2.revisions[0].author
+        assert_equal "test-#{@char_1_ascii8bit}.txt", ann2.lines[0]
+      end
+
+      def test_diff_latin1_path
+        latin1_repo = create_latin1_repo
+        diff1 = latin1_repo.diff(
+                  "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", 2, 1)
+        assert_equal 7, diff1.size
+        buf =  diff1[5].gsub(/\r\n|\r|\n/, "")
+        assert_equal "+test-#{@char_1_ascii8bit}.txt", buf
+      end
+
+      def test_entries_latin1_path
+        latin1_repo = create_latin1_repo
+        entries = latin1_repo.entries("test-#{@char_1_utf8}-dir", 2)
+        assert_kind_of Redmine::Scm::Adapters::Entries, entries
+        assert_equal 3, entries.size
+        assert_equal 'file', entries[1].kind
+        assert_equal "test-#{@char_1_utf8}-1.txt", entries[0].name
+        assert_equal "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", entries[0].path
+      end
+
+      def test_entry_latin1_path
+        latin1_repo = create_latin1_repo
+        ["test-#{@char_1_utf8}-dir",
+          "/test-#{@char_1_utf8}-dir",
+          "/test-#{@char_1_utf8}-dir/"
+        ].each do |path|
+          entry = latin1_repo.entry(path, 2)
+          assert_equal "test-#{@char_1_utf8}-dir", entry.path
+          assert_equal "dir", entry.kind
+        end
+        ["test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt",
+          "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt"
+        ].each do |path|
+          entry = latin1_repo.entry(path, 2)
+          assert_equal "test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt",
+                       entry.path
+          assert_equal "file", entry.kind
+        end
+      end
+
+      def test_changeset_latin1_path
+        latin1_repo = create_latin1_repo
+        assert_equal 0, latin1_repo.changesets.count
+        latin1_repo.fetch_changesets
+        @project.reload
+        assert_equal 3, latin1_repo.changesets.count
+
+        cs2 = latin1_repo.changesets.find_by_revision('2')
+        assert_not_nil cs2
+        assert_equal "test-#{@char_1_utf8}", cs2.comments
+        c2  = cs2.filechanges.sort_by(&:path)
+        assert_equal 4, c2.size
+        assert_equal 'A', c2[0].action
+        assert_equal "/test-#{@char_1_utf8}-dir/", c2[0].path
+        assert_equal 'A', c2[1].action
+        assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-1.txt", c2[1].path
+        assert_equal 'A', c2[2].action
+        assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-2.txt", c2[2].path
+        assert_equal 'A', c2[3].action
+        assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}.txt", c2[3].path
+
+        cs3 = latin1_repo.changesets.find_by_revision('3')
+        assert_not_nil cs3
+        assert_equal "modify, move and delete #{@char_1_utf8} files", cs3.comments
+        c3  = cs3.filechanges.sort_by(&:path)
+        assert_equal 3, c3.size
+        assert_equal 'M', c3[0].action
+        assert_equal "/test-#{@char_1_utf8}-1.txt", c3[0].path
+        assert_equal 'D', c3[1].action
+        assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}-2.txt", c3[1].path
+        assert_equal 'M', c3[2].action
+        assert_equal "/test-#{@char_1_utf8}-dir/test-#{@char_1_utf8}.txt", c3[2].path
+      end
+    else
+      msg = "Bazaar non ASCII output test cannot run this environment." + "\n"
+      if msg.respond_to?(:force_encoding)
+        msg += "Encoding.locale_charmap: " + Encoding.locale_charmap + "\n"
+      end
+      puts msg
+    end
+
+    private
+
+    def create_latin1_repo
+      repo = Repository::Bazaar.create(
+                            :project      => @project,
+                            :identifier   => 'latin1',
+                            :url => REPOSITORY_PATH_NON_ASCII,
+                            :log_encoding => 'ISO-8859-1'
+                        )
+      assert repo
+      repo
+    end
+  else
+    puts "Bazaar test repository NOT FOUND. Skipping unit tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/77/77d58783aae2a4640c9d8514879fb6e9b163a2b5.svn-base
--- /dev/null
+++ b/.svn/pristine/77/77d58783aae2a4640c9d8514879fb6e9b163a2b5.svn-base
@@ -0,0 +1,1087 @@
+# Italian translations for Ruby on Rails
+# by Claudio Poli (masterkain@gmail.com)
+# by Diego Pierotto (ita.translations@tiscali.it)
+# by Emidio Stani (emidiostani@gmail.com)
+
+it:
+  direction: ltr
+  date:
+    formats:
+      default: "%d-%m-%Y"
+      short: "%d %b"
+      long: "%d %B %Y"
+      only_day: "%e"
+
+    day_names: [Domenica, LunedÃ¬, MartedÃ¬, MercoledÃ¬, GiovedÃ¬, VenerdÃ¬, Sabato]
+    abbr_day_names: [Dom, Lun, Mar, Mer, Gio, Ven, Sab]
+    month_names: [~, Gennaio, Febbraio, Marzo, Aprile, Maggio, Giugno, Luglio, Agosto, Settembre, Ottobre, Novembre, Dicembre]
+    abbr_month_names: [~, Gen, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a %d %b %Y, %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%d %B %Y %H:%M"
+      only_second: "%S"
+
+      datetime:
+        formats:
+          default: "%d-%m-%YT%H:%M:%S%Z"
+
+    am: 'am'
+    pm: 'pm'
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "mezzo minuto"
+      less_than_x_seconds:
+        one:  "meno di un secondo"
+        other: "meno di %{count} secondi"
+      x_seconds:
+        one:  "1 secondo"
+        other: "%{count} secondi"
+      less_than_x_minutes:
+        one:  "meno di un minuto"
+        other: "meno di %{count} minuti"
+      x_minutes:
+        one:  "1 minuto"
+        other: "%{count} minuti"
+      about_x_hours:
+        one:  "circa un'ora"
+        other: "circa %{count} ore"
+      x_hours:
+        one:   "1 ora"
+        other: "%{count} ore"
+      x_days:
+        one:  "1 giorno"
+        other: "%{count} giorni"
+      about_x_months:
+        one:  "circa un mese"
+        other: "circa %{count} mesi"
+      x_months:
+        one:  "1 mese"
+        other: "%{count} mesi"
+      about_x_years:
+        one:  "circa un anno"
+        other: "circa %{count} anni"
+      over_x_years:
+        one:  "oltre un anno"
+        other: "oltre %{count} anni"
+      almost_x_years:
+        one:   "quasi 1 anno"
+        other: "quasi %{count} anni"
+
+  number:
+    format:
+      precision: 3
+      separator: ','
+      delimiter: '.'
+    currency:
+      format:
+        unit: 'â‚¬'
+        precision: 2
+        format: '%n %u'
+    human:
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  support:
+    array:
+      sentence_connector: "e"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one: "Non posso salvare questo %{model}: 1 errore"
+          other: "Non posso salvare questo %{model}: %{count} errori."
+        body: "Per favore ricontrolla i seguenti campi:"
+      messages:
+        inclusion: "non Ã¨ incluso nella lista"
+        exclusion: "Ã¨ riservato"
+        invalid: "non Ã¨ valido"
+        confirmation: "non coincide con la conferma"
+        accepted: "deve essere accettata"
+        empty: "non puÃ² essere vuoto"
+        blank: "non puÃ² essere lasciato in bianco"
+        too_long: "Ã¨ troppo lungo (il massimo Ã¨ %{count} lettere)"
+        too_short: "Ã¨ troppo corto (il minimo Ã¨ %{count} lettere)"
+        wrong_length: "Ã¨ della lunghezza sbagliata (deve essere di %{count} lettere)"
+        taken: "Ã¨ giÃ  in uso"
+        not_a_number: "non Ã¨ un numero"
+        greater_than: "deve essere superiore a %{count}"
+        greater_than_or_equal_to: "deve essere superiore o uguale a %{count}"
+        equal_to: "deve essere uguale a %{count}"
+        less_than: "deve essere meno di %{count}"
+        less_than_or_equal_to: "deve essere meno o uguale a %{count}"
+        odd: "deve essere dispari"
+        even: "deve essere pari"
+        greater_than_start_date: "deve essere maggiore della data di partenza"
+        not_same_project: "non appartiene allo stesso progetto"
+        circular_dependency: "Questa relazione creerebbe una dipendenza circolare"
+        cant_link_an_issue_with_a_descendant: "Una segnalazione non puÃ² essere collegata a una delle sue discendenti"
+
+  actionview_instancetag_blank_option: Scegli
+
+  general_text_No: 'No'
+  general_text_Yes: 'SÃ¬'
+  general_text_no: 'no'
+  general_text_yes: 'sÃ¬'
+  general_lang_name: 'Italiano'
+  general_csv_separator: ';'
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: L'utente Ã¨ stato aggiornato.
+  notice_account_invalid_creditentials: Nome utente o password non validi.
+  notice_account_password_updated: La password Ã¨ stata aggiornata.
+  notice_account_wrong_password: Password errata
+  notice_account_register_done: L'utente Ã¨ stato creato.
+  notice_account_unknown_email: Utente sconosciuto.
+  notice_can_t_change_password: Questo utente utilizza un metodo di autenticazione esterno. Impossibile cambiare la password.
+  notice_account_lost_email_sent: Ti Ã¨ stata spedita una email con le istruzioni per cambiare la password.
+  notice_account_activated: Il tuo account Ã¨ stato attivato. Ora puoi effettuare l'accesso.
+  notice_successful_create: Creazione effettuata.
+  notice_successful_update: Modifica effettuata.
+  notice_successful_delete: Eliminazione effettuata.
+  notice_successful_connection: Connessione effettuata.
+  notice_file_not_found: La pagina desiderata non esiste o Ã¨ stata rimossa.
+  notice_locking_conflict: Le informazioni sono state modificate da un altro utente.
+  notice_not_authorized: Non sei autorizzato ad accedere a questa pagina.
+  notice_email_sent: "Una email Ã¨ stata spedita a %{value}"
+  notice_email_error: "Si Ã¨ verificato un errore durante l'invio di una email (%{value})"
+  notice_feeds_access_key_reseted: La tua chiave di accesso RSS Ã¨ stata reimpostata.
+
+  error_scm_not_found: "La risorsa e/o la versione non esistono nel repository."
+  error_scm_command_failed: "Si Ã¨ verificato un errore durante l'accesso al repository: %{value}"
+
+  mail_subject_lost_password: "Password %{value}"
+  mail_body_lost_password: 'Per cambiare la password, usa il seguente collegamento:'
+  mail_subject_register: "Attivazione utente %{value}"
+  mail_body_register: "Per attivare l'utente, usa il seguente collegamento:"
+
+
+  field_name: Nome
+  field_description: Descrizione
+  field_summary: Sommario
+  field_is_required: Richiesto
+  field_firstname: Nome
+  field_lastname: Cognome
+  field_mail: Email
+  field_filename: File
+  field_filesize: Dimensione
+  field_downloads: Download
+  field_author: Autore
+  field_created_on: Creato
+  field_updated_on: Aggiornato
+  field_field_format: Formato
+  field_is_for_all: Per tutti i progetti
+  field_possible_values: Valori possibili
+  field_regexp: Espressione regolare
+  field_min_length: Lunghezza minima
+  field_max_length: Lunghezza massima
+  field_value: Valore
+  field_category: Categoria
+  field_title: Titolo
+  field_project: Progetto
+  field_issue: Segnalazione
+  field_status: Stato
+  field_notes: Note
+  field_is_closed: Chiudi la segnalazione
+  field_is_default: Stato predefinito
+  field_tracker: Tracker
+  field_subject: Oggetto
+  field_due_date: Scadenza
+  field_assigned_to: Assegnato a
+  field_priority: PrioritÃ 
+  field_fixed_version: Versione prevista
+  field_user: Utente
+  field_role: Ruolo
+  field_homepage: Homepage
+  field_is_public: Pubblico
+  field_parent: Sottoprogetto di
+  field_is_in_roadmap: Segnalazioni mostrate nella roadmap
+  field_login: Utente
+  field_mail_notification: Notifiche via email
+  field_admin: Amministratore
+  field_last_login_on: Ultima connessione
+  field_language: Lingua
+  field_effective_date: Data
+  field_password: Password
+  field_new_password: Nuova password
+  field_password_confirmation: Conferma
+  field_version: Versione
+  field_type: Tipo
+  field_host: Host
+  field_port: Porta
+  field_account: Utente
+  field_base_dn: DN base
+  field_attr_login: Attributo connessione
+  field_attr_firstname: Attributo nome
+  field_attr_lastname: Attributo cognome
+  field_attr_mail: Attributo email
+  field_onthefly: Creazione utente "al volo"
+  field_start_date: Inizio
+  field_done_ratio: "% completato"
+  field_auth_source: ModalitÃ  di autenticazione
+  field_hide_mail: Nascondi il mio indirizzo email
+  field_comments: Commento
+  field_url: URL
+  field_start_page: Pagina principale
+  field_subproject: Sottoprogetto
+  field_hours: Ore
+  field_activity: AttivitÃ 
+  field_spent_on: Data
+  field_identifier: Identificativo
+  field_is_filter: Usato come filtro
+  field_issue_to: Segnalazioni correlate
+  field_delay: Ritardo
+  field_assignable: E' possibile assegnare segnalazioni a questo ruolo
+  field_redirect_existing_links: Redirige i collegamenti esistenti
+  field_estimated_hours: Tempo stimato
+  field_default_value: Stato predefinito
+
+  setting_app_title: Titolo applicazione
+  setting_app_subtitle: Sottotitolo applicazione
+  setting_welcome_text: Testo di benvenuto
+  setting_default_language: Lingua predefinita
+  setting_login_required: Autenticazione richiesta
+  setting_self_registration: Auto-registrazione abilitata
+  setting_attachment_max_size: Dimensione massima allegati
+  setting_issues_export_limit: Limite esportazione segnalazioni
+  setting_mail_from: Indirizzo sorgente email
+  setting_host_name: Nome host
+  setting_text_formatting: Formattazione testo
+  setting_wiki_compression: Comprimi cronologia wiki
+  setting_feeds_limit: Limite contenuti del feed
+  setting_autofetch_changesets: Acquisisci automaticamente le commit
+  setting_sys_api_enabled: Abilita WS per la gestione del repository
+  setting_commit_ref_keywords: Parole chiave riferimento
+  setting_commit_fix_keywords: Parole chiave chiusura
+  setting_autologin: Connessione automatica
+  setting_date_format: Formato data
+  setting_cross_project_issue_relations: Consenti la creazione di relazioni tra segnalazioni in progetti differenti
+
+  label_user: Utente
+  label_user_plural: Utenti
+  label_user_new: Nuovo utente
+  label_project: Progetto
+  label_project_new: Nuovo progetto
+  label_project_plural: Progetti
+  label_x_projects:
+    zero:  nessun progetto
+    one:   1 progetto
+    other: "%{count} progetti"
+  label_project_all: Tutti i progetti
+  label_project_latest: Ultimi progetti registrati
+  label_issue: Segnalazione
+  label_issue_new: Nuova segnalazione
+  label_issue_plural: Segnalazioni
+  label_issue_view_all: Mostra tutte le segnalazioni
+  label_document: Documento
+  label_document_new: Nuovo documento
+  label_document_plural: Documenti
+  label_role: Ruolo
+  label_role_plural: Ruoli
+  label_role_new: Nuovo ruolo
+  label_role_and_permissions: Ruoli e permessi
+  label_member: Membro
+  label_member_new: Nuovo membro
+  label_member_plural: Membri
+  label_tracker: Tracker
+  label_tracker_plural: Tracker
+  label_tracker_new: Nuovo tracker
+  label_workflow: Workflow
+  label_issue_status: Stato segnalazione
+  label_issue_status_plural: Stati segnalazioni
+  label_issue_status_new: Nuovo stato
+  label_issue_category: Categoria segnalazione
+  label_issue_category_plural: Categorie segnalazioni
+  label_issue_category_new: Nuova categoria
+  label_custom_field: Campo personalizzato
+  label_custom_field_plural: Campi personalizzati
+  label_custom_field_new: Nuovo campo personalizzato
+  label_enumerations: Enumerazioni
+  label_enumeration_new: Nuovo valore
+  label_information: Informazione
+  label_information_plural: Informazioni
+  label_please_login: Entra
+  label_register: Registrati
+  label_password_lost: Password dimenticata
+  label_home: Home
+  label_my_page: Pagina personale
+  label_my_account: Il mio utente
+  label_my_projects: I miei progetti
+  label_administration: Amministrazione
+  label_login: Entra
+  label_logout: Esci
+  label_help: Aiuto
+  label_reported_issues: Segnalazioni
+  label_assigned_to_me_issues: Le mie segnalazioni
+  label_last_login: Ultimo collegamento
+  label_registered_on: Registrato il
+  label_activity: AttivitÃ 
+  label_new: Nuovo
+  label_logged_as: Collegato come
+  label_environment: Ambiente
+  label_authentication: Autenticazione
+  label_auth_source: ModalitÃ  di autenticazione
+  label_auth_source_new: Nuova modalitÃ  di autenticazione
+  label_auth_source_plural: ModalitÃ  di autenticazione
+  label_subproject_plural: Sottoprogetti
+  label_min_max_length: Lunghezza minima - massima
+  label_list: Elenco
+  label_date: Data
+  label_integer: Intero
+  label_boolean: Booleano
+  label_string: Testo
+  label_text: Testo esteso
+  label_attribute: Attributo
+  label_attribute_plural: Attributi
+  label_no_data: Nessun dato disponibile
+  label_change_status: Cambia stato
+  label_history: Cronologia
+  label_attachment: File
+  label_attachment_new: Nuovo file
+  label_attachment_delete: Elimina file
+  label_attachment_plural: File
+  label_report: Report
+  label_report_plural: Report
+  label_news: Notizia
+  label_news_new: Aggiungi notizia
+  label_news_plural: Notizie
+  label_news_latest: Utime notizie
+  label_news_view_all: Tutte le notizie
+  label_settings: Impostazioni
+  label_overview: Panoramica
+  label_version: Versione
+  label_version_new: Nuova versione
+  label_version_plural: Versioni
+  label_confirmation: Conferma
+  label_export_to: Esporta su
+  label_read: Leggi...
+  label_public_projects: Progetti pubblici
+  label_open_issues: aperta
+  label_open_issues_plural: aperte
+  label_closed_issues: chiusa
+  label_closed_issues_plural: chiuse
+  label_x_open_issues_abbr_on_total:
+    zero:  0 aperte / %{total}
+    one:   1 aperta / %{total}
+    other: "%{count} aperte / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 aperte
+    one:   1 aperta
+    other: "%{count} aperte"
+  label_x_closed_issues_abbr:
+    zero:  0 chiuse
+    one:   1 chiusa
+    other: "%{count} chiuse"
+  label_total: Totale
+  label_permissions: Permessi
+  label_current_status: Stato attuale
+  label_new_statuses_allowed: Nuovi stati possibili
+  label_all: tutti
+  label_none: nessuno
+  label_next: Successivo
+  label_previous: Precedente
+  label_used_by: Usato da
+  label_details: Dettagli
+  label_add_note: Aggiungi una nota
+  label_per_page: Per pagina
+  label_calendar: Calendario
+  label_months_from: mesi da
+  label_gantt: Gantt
+  label_internal: Interno
+  label_last_changes: "ultime %{count} modifiche"
+  label_change_view_all: Tutte le modifiche
+  label_personalize_page: Personalizza la pagina
+  label_comment: Commento
+  label_comment_plural: Commenti
+  label_x_comments:
+    zero: nessun commento
+    one: 1 commento
+    other: "%{count} commenti"
+  label_comment_add: Aggiungi un commento
+  label_comment_added: Commento aggiunto
+  label_comment_delete: Elimina commenti
+  label_query: Query personalizzata
+  label_query_plural: Query personalizzate
+  label_query_new: Nuova query
+  label_filter_add: Aggiungi filtro
+  label_filter_plural: Filtri
+  label_equals: Ã¨
+  label_not_equals: non Ã¨
+  label_in_less_than: Ã¨ minore di
+  label_in_more_than: Ã¨ maggiore di
+  label_in: in
+  label_today: oggi
+  label_this_week: questa settimana
+  label_less_than_ago: meno di giorni fa
+  label_more_than_ago: piÃ¹ di giorni fa
+  label_ago: giorni fa
+  label_contains: contiene
+  label_not_contains: non contiene
+  label_day_plural: giorni
+  label_repository: Repository
+  label_browse: Sfoglia
+  label_revision: Versione
+  label_revision_plural: Versioni
+  label_added: aggiunto
+  label_modified: modificato
+  label_deleted: eliminato
+  label_latest_revision: Ultima versione
+  label_latest_revision_plural: Ultime versioni
+  label_view_revisions: Mostra versioni
+  label_max_size: Dimensione massima
+  label_sort_highest: Sposta in cima
+  label_sort_higher: Su
+  label_sort_lower: GiÃ¹
+  label_sort_lowest: Sposta in fondo
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "Da ultimare in %{value}"
+  label_roadmap_overdue: "%{value} di ritardo"
+  label_roadmap_no_issues: Nessuna segnalazione per questa versione
+  label_search: Ricerca
+  label_result_plural: Risultati
+  label_all_words: Tutte le parole
+  label_wiki: Wiki
+  label_wiki_edit: Modifica wiki
+  label_wiki_edit_plural: Modifiche wiki
+  label_wiki_page: Pagina Wiki
+  label_wiki_page_plural: Pagine wiki
+  label_index_by_title: Ordina per titolo
+  label_index_by_date: Ordina per data
+  label_current_version: Versione corrente
+  label_preview: Anteprima
+  label_feed_plural: Feed
+  label_changes_details: Particolari di tutti i cambiamenti
+  label_issue_tracking: Tracking delle segnalazioni
+  label_spent_time: Tempo impiegato
+  label_f_hour: "%{value} ora"
+  label_f_hour_plural: "%{value} ore"
+  label_time_tracking: Tracking del tempo
+  label_change_plural: Modifiche
+  label_statistics: Statistiche
+  label_commits_per_month: Commit per mese
+  label_commits_per_author: Commit per autore
+  label_view_diff: mostra differenze
+  label_diff_inline: in linea
+  label_diff_side_by_side: fianco a fianco
+  label_options: Opzioni
+  label_copy_workflow_from: Copia workflow da
+  label_permissions_report: Report permessi
+  label_watched_issues: Segnalazioni osservate
+  label_related_issues: Segnalazioni correlate
+  label_applied_status: Stato applicato
+  label_loading: Caricamento...
+  label_relation_new: Nuova relazione
+  label_relation_delete: Elimina relazione
+  label_relates_to: correlato a
+  label_duplicates: duplicati
+  label_blocks: blocchi
+  label_blocked_by: bloccato da
+  label_precedes: precede
+  label_follows: segue
+  label_end_to_start: fine a inizio
+  label_end_to_end: fine a fine
+  label_start_to_start: inizio a inizio
+  label_start_to_end: inizio a fine
+  label_stay_logged_in: Rimani collegato
+  label_disabled: disabilitato
+  label_show_completed_versions: Mostra versioni completate
+  label_me: me
+  label_board: Forum
+  label_board_new: Nuovo forum
+  label_board_plural: Forum
+  label_topic_plural: Argomenti
+  label_message_plural: Messaggi
+  label_message_last: Ultimo messaggio
+  label_message_new: Nuovo messaggio
+  label_reply_plural: Risposte
+  label_send_information: Invia all'utente le informazioni relative all'account
+  label_year: Anno
+  label_month: Mese
+  label_week: Settimana
+  label_date_from: Da
+  label_date_to: A
+  label_language_based: Basato sul linguaggio
+  label_sort_by: "Ordina per %{value}"
+  label_send_test_email: Invia una email di prova
+  label_feeds_access_key_created_on: "chiave di accesso RSS creata %{value} fa"
+  label_module_plural: Moduli
+  label_added_time_by: "Aggiunto da %{author} %{age} fa"
+  label_updated_time: "Aggiornato %{value} fa"
+  label_jump_to_a_project: Vai al progetto...
+
+  button_login: Entra
+  button_submit: Invia
+  button_save: Salva
+  button_check_all: Seleziona tutti
+  button_uncheck_all: Deseleziona tutti
+  button_delete: Elimina
+  button_create: Crea
+  button_test: Prova
+  button_edit: Modifica
+  button_add: Aggiungi
+  button_change: Cambia
+  button_apply: Applica
+  button_clear: Pulisci
+  button_lock: Blocca
+  button_unlock: Sblocca
+  button_download: Scarica
+  button_list: Elenca
+  button_view: Mostra
+  button_move: Sposta
+  button_back: Indietro
+  button_cancel: Annulla
+  button_activate: Attiva
+  button_sort: Ordina
+  button_log_time: Registra tempo
+  button_rollback: Ripristina questa versione
+  button_watch: Osserva
+  button_unwatch: Dimentica
+  button_reply: Rispondi
+  button_archive: Archivia
+  button_unarchive: Ripristina
+  button_reset: Reimposta
+  button_rename: Rinomina
+
+  status_active: attivo
+  status_registered: registrato
+  status_locked: bloccato
+
+  text_select_mail_notifications: Seleziona le azioni per cui deve essere inviata una notifica.
+  text_regexp_info: es. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 significa nessuna restrizione
+  text_project_destroy_confirmation: Sei sicuro di voler eliminare il progetto e tutti i dati ad esso collegati?
+  text_workflow_edit: Seleziona un ruolo ed un tracker per modificare il workflow
+  text_are_you_sure: Sei sicuro ?
+  text_tip_issue_begin_day: attivitÃ  che iniziano in questa giornata
+  text_tip_issue_end_day: attivitÃ  che terminano in questa giornata
+  text_tip_issue_begin_end_day: attivitÃ  che iniziano e terminano in questa giornata
+  text_caracters_maximum: "massimo %{count} caratteri."
+  text_length_between: "Lunghezza compresa tra %{min} e %{max} caratteri."
+  text_tracker_no_workflow: Nessun workflow definito per questo tracker
+  text_unallowed_characters: Caratteri non permessi
+  text_comma_separated: Valori multipli permessi (separati da virgole).
+  text_issues_ref_in_commit_messages: Segnalazioni di riferimento e chiusura nei messaggi di commit
+  text_issue_added: "%{author} ha aggiunto la segnalazione %{id}."
+  text_issue_updated: "La segnalazione %{id} Ã¨ stata aggiornata da %{author}."
+  text_wiki_destroy_confirmation: Sicuro di voler eliminare questo wiki e tutti i suoi contenuti?
+  text_issue_category_destroy_question: "Alcune segnalazioni (%{count}) risultano assegnate a questa categoria. Cosa vuoi fare ?"
+  text_issue_category_destroy_assignments: Rimuovi le assegnazioni a questa categoria
+  text_issue_category_reassign_to: Riassegna segnalazioni a questa categoria
+
+  default_role_manager: Gestore
+  default_role_developer: Sviluppatore
+  default_role_reporter: Segnalatore
+  default_tracker_bug: Segnalazione
+  default_tracker_feature: Funzione
+  default_tracker_support: Supporto
+  default_issue_status_new: Nuovo
+  default_issue_status_in_progress: In elaborazione
+  default_issue_status_resolved: Risolto
+  default_issue_status_feedback: Commenti
+  default_issue_status_closed: Chiuso
+  default_issue_status_rejected: Rifiutato
+  default_doc_category_user: Documentazione utente
+  default_doc_category_tech: Documentazione tecnica
+  default_priority_low: Bassa
+  default_priority_normal: Normale
+  default_priority_high: Alta
+  default_priority_urgent: Urgente
+  default_priority_immediate: Immediata
+  default_activity_design: Progettazione
+  default_activity_development: Sviluppo
+
+  enumeration_issue_priorities: PrioritÃ  segnalazioni
+  enumeration_doc_categories: Categorie di documenti
+  enumeration_activities: AttivitÃ  (time tracking)
+  label_file_plural: File
+  label_changeset_plural: Changeset
+  field_column_names: Colonne
+  label_default_columns: Colonne predefinite
+  setting_issue_list_default_columns: Colonne predefinite mostrate nell'elenco segnalazioni
+  notice_no_issue_selected: "Nessuna segnalazione selezionata! Seleziona le segnalazioni che intendi modificare."
+  label_bulk_edit_selected_issues: Modifica massiva delle segnalazioni selezionate
+  label_no_change_option: (Nessuna modifica)
+  notice_failed_to_save_issues: "Impossibile salvare %{count} segnalazioni su %{total} selezionate: %{ids}."
+  label_theme: Tema
+  label_default: Predefinito
+  label_search_titles_only: Cerca solo nei titoli
+  label_nobody: nessuno
+  button_change_password: Modifica password
+  text_user_mail_option: "Per i progetti non selezionati, riceverai solo le notifiche riguardanti le cose che osservi o nelle quali sei coinvolto (per esempio segnalazioni che hai creato o che ti sono state assegnate)."
+  label_user_mail_option_selected: "Solo per gli eventi relativi ai progetti selezionati..."
+  label_user_mail_option_all: "Per ogni evento relativo ad uno dei miei progetti"
+  setting_emails_footer: PiÃ¨ di pagina email
+  label_float: Decimale
+  button_copy: Copia
+  mail_body_account_information_external: "Puoi utilizzare il tuo account %{value} per accedere al sistema."
+  mail_body_account_information: Le informazioni riguardanti il tuo account
+  setting_protocol: Protocollo
+  label_user_mail_no_self_notified: "Non voglio notifiche riguardanti modifiche da me apportate"
+  setting_time_format: Formato ora
+  label_registration_activation_by_email: attivazione account via email
+  mail_subject_account_activation_request: "%{value} richiesta attivazione account"
+  mail_body_account_activation_request: "Un nuovo utente (%{value}) ha effettuato la registrazione. Il suo account Ã¨ in attesa di abilitazione da parte tua:"
+  label_registration_automatic_activation: attivazione account automatica
+  label_registration_manual_activation: attivazione account manuale
+  notice_account_pending: "Il tuo account Ã¨ stato creato ed Ã¨ in attesa di attivazione da parte dell'amministratore."
+  field_time_zone: Fuso orario
+  text_caracters_minimum: "Deve essere lungo almeno %{count} caratteri."
+  setting_bcc_recipients: Destinatari in copia nascosta (bcc)
+  button_annotate: Annota
+  label_issues_by: "Segnalazioni di %{value}"
+  field_searchable: Ricercabile
+  label_display_per_page: "Per pagina: %{value}"
+  setting_per_page_options: Opzioni oggetti per pagina
+  label_age: EtÃ 
+  notice_default_data_loaded: Configurazione predefinita caricata con successo.
+  text_load_default_configuration: Carica la configurazione predefinita
+  text_no_configuration_data: "Ruoli, tracker, stati delle segnalazioni e workflow non sono stati ancora configurati.\nE' vivamente consigliato caricare la configurazione predefinita. Potrai modificarla una volta caricata."
+  error_can_t_load_default_data: "Non Ã¨ stato possibile caricare la configurazione predefinita : %{value}"
+  button_update: Aggiorna
+  label_change_properties: Modifica le proprietÃ 
+  label_general: Generale
+  label_repository_plural: Repository
+  label_associated_revisions: Revisioni associate
+  setting_user_format: Formato visualizzazione utenti
+  text_status_changed_by_changeset: "Applicata nel changeset %{value}."
+  label_more: Altro
+  text_issues_destroy_confirmation: 'Sei sicuro di voler eliminare le segnalazioni selezionate?'
+  label_scm: SCM
+  text_select_project_modules: 'Seleziona i moduli abilitati per questo progetto:'
+  label_issue_added: Segnalazioni aggiunte
+  label_issue_updated: Segnalazioni aggiornate
+  label_document_added: Documenti aggiunti
+  label_message_posted: Messaggi aggiunti
+  label_file_added: File aggiunti
+  label_news_added: Notizie aggiunte
+  project_module_boards: Forum
+  project_module_issue_tracking: Tracking delle segnalazioni
+  project_module_wiki: Wiki
+  project_module_files: File
+  project_module_documents: Documenti
+  project_module_repository: Repository
+  project_module_news: Notizie
+  project_module_time_tracking: Time tracking
+  text_file_repository_writable: Repository dei file scrivibile
+  text_default_administrator_account_changed: L'account amministrativo predefinito Ã¨ stato modificato
+  text_rmagick_available: RMagick disponibile (opzionale)
+  button_configure: Configura
+  label_plugins: Plugin
+  label_ldap_authentication: Autenticazione LDAP
+  label_downloads_abbr: D/L
+  label_this_month: questo mese
+  label_last_n_days: "ultimi %{count} giorni"
+  label_all_time: sempre
+  label_this_year: quest'anno
+  label_date_range: Intervallo di date
+  label_last_week: ultima settimana
+  label_yesterday: ieri
+  label_last_month: ultimo mese
+  label_add_another_file: Aggiungi un altro file
+  label_optional_description: Descrizione opzionale
+  text_destroy_time_entries_question: "%{hours} ore risultano spese sulle segnalazioni che stai per eliminare. Cosa vuoi fare ?"
+  error_issue_not_found_in_project: 'La segnalazione non Ã¨ stata trovata o non appartiene al progetto'
+  text_assign_time_entries_to_project: Assegna le ore segnalate al progetto
+  text_destroy_time_entries: Elimina le ore segnalate
+  text_reassign_time_entries: 'Riassegna le ore a questa segnalazione:'
+  setting_activity_days_default: Giorni mostrati sulle attivitÃ  di progetto
+  label_chronological_order: In ordine cronologico
+  field_comments_sorting: Mostra commenti
+  label_reverse_chronological_order: In ordine cronologico inverso
+  label_preferences: Preferenze
+  setting_display_subprojects_issues: Mostra le segnalazioni dei sottoprogetti nel progetto principale in modo predefinito
+  label_overall_activity: AttivitÃ  generale
+  setting_default_projects_public: I nuovi progetti sono pubblici in modo predefinito
+  error_scm_annotate: "L'oggetto non esiste o non puÃ² essere annotato."
+  label_planning: Pianificazione
+  text_subprojects_destroy_warning: "Anche i suoi sottoprogetti: %{value} verranno eliminati."
+  label_and_its_subprojects: "%{value} ed i suoi sottoprogetti"
+  mail_body_reminder: "%{count} segnalazioni che ti sono state assegnate scadranno nei prossimi %{days} giorni:"
+  mail_subject_reminder: "%{count} segnalazioni in scadenza nei prossimi %{days} giorni"
+  text_user_wrote: "%{value} ha scritto:"
+  label_duplicated_by: duplicato da
+  setting_enabled_scm: SCM abilitato
+  text_enumeration_category_reassign_to: 'Riassegnale a questo valore:'
+  text_enumeration_destroy_question: "%{count} oggetti hanno un assegnamento su questo valore."
+  label_incoming_emails: Email in arrivo
+  label_generate_key: Genera una chiave
+  setting_mail_handler_api_enabled: Abilita WS per le email in arrivo
+  setting_mail_handler_api_key: Chiave API
+  text_email_delivery_not_configured: "La consegna via email non Ã¨ configurata e le notifiche sono disabilitate.\nConfigura il tuo server SMTP in config/configuration.yml e riavvia l'applicazione per abilitarle."
+  field_parent_title: Pagina principale
+  label_issue_watchers: Osservatori
+  button_quote: Quota
+  setting_sequential_project_identifiers: Genera progetti con identificativi in sequenza
+  notice_unable_delete_version: Impossibile eliminare la versione
+  label_renamed: rinominato
+  label_copied: copiato
+  setting_plain_text_mail: Solo testo (non HTML)
+  permission_view_files: Vedi files
+  permission_edit_issues: Modifica segnalazioni
+  permission_edit_own_time_entries: Modifica propri time logs
+  permission_manage_public_queries: Gestisci query pubbliche
+  permission_add_issues: Aggiungi segnalazioni
+  permission_log_time: Segna tempo impiegato
+  permission_view_changesets: Vedi changesets
+  permission_view_time_entries: Vedi tempi impiegati
+  permission_manage_versions: Gestisci versioni
+  permission_manage_wiki: Gestisci wiki
+  permission_manage_categories: Gestisci categorie segnalazioni
+  permission_protect_wiki_pages: Proteggi pagine wiki
+  permission_comment_news: Commenta notizie
+  permission_delete_messages: Elimina messaggi
+  permission_select_project_modules: Seleziona moduli progetto
+  permission_edit_wiki_pages: Modifica pagine wiki
+  permission_add_issue_watchers: Aggiungi osservatori
+  permission_view_gantt: Vedi diagrammi gantt
+  permission_move_issues: Muovi segnalazioni
+  permission_manage_issue_relations: Gestisci relazioni tra segnalazioni
+  permission_delete_wiki_pages: Elimina pagine wiki
+  permission_manage_boards: Gestisci forum
+  permission_delete_wiki_pages_attachments: Elimina allegati
+  permission_view_wiki_edits: Vedi cronologia wiki
+  permission_add_messages: Aggiungi messaggi
+  permission_view_messages: Vedi messaggi
+  permission_manage_files: Gestisci files
+  permission_edit_issue_notes: Modifica note
+  permission_manage_news: Gestisci notizie
+  permission_view_calendar: Vedi calendario
+  permission_manage_members: Gestisci membri
+  permission_edit_messages: Modifica messaggi
+  permission_delete_issues: Elimina segnalazioni
+  permission_view_issue_watchers: Vedi lista osservatori
+  permission_manage_repository: Gestisci repository
+  permission_commit_access: Permesso di commit
+  permission_browse_repository: Sfoglia repository
+  permission_view_documents: Vedi documenti
+  permission_edit_project: Modifica progetti
+  permission_add_issue_notes: Aggiungi note
+  permission_save_queries: Salva query
+  permission_view_wiki_pages: Vedi pagine wiki
+  permission_rename_wiki_pages: Rinomina pagine wiki
+  permission_edit_time_entries: Modifica time logs
+  permission_edit_own_issue_notes: Modifica proprie note
+  setting_gravatar_enabled: Usa icone utente Gravatar
+  label_example: Esempio
+  text_repository_usernames_mapping: "Seleziona per aggiornare la corrispondenza tra gli utenti Redmine e quelli presenti nel log del repository.\nGli utenti Redmine e repository con lo stesso note utente o email sono mappati automaticamente."
+  permission_edit_own_messages: Modifica propri messaggi
+  permission_delete_own_messages: Elimina propri messaggi
+  label_user_activity: "attivitÃ  di %{value}"
+  label_updated_time_by: "Aggiornato da %{author} %{age} fa"
+  text_diff_truncated: '... Le differenze sono state troncate perchÃ¨ superano il limite massimo visualizzabile.'
+  setting_diff_max_lines_displayed: Limite massimo di differenze (linee) mostrate
+  text_plugin_assets_writable: Directory attivitÃ  dei plugins scrivibile
+  warning_attachments_not_saved: "%{count} file non possono essere salvati."
+  button_create_and_continue: Crea e continua
+  text_custom_field_possible_values_info: 'Un valore per ogni riga'
+  label_display: Mostra
+  field_editable: Modificabile
+  setting_repository_log_display_limit: Numero massimo di revisioni elencate nella cronologia file
+  setting_file_max_size_displayed: Dimensione massima dei contenuti testuali visualizzati
+  field_watcher: Osservatore
+  setting_openid: Accetta connessione e registrazione con OpenID
+  field_identity_url: URL OpenID
+  label_login_with_open_id_option: oppure autenticati usando OpenID
+  field_content: Contenuto
+  label_descending: Discendente
+  label_sort: Ordina
+  label_ascending: Ascendente
+  label_date_from_to: Da %{start} a %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Questa pagina ha %{descendants} pagine figlie. Cosa ne vuoi fare?
+  text_wiki_page_reassign_children: Riassegna le pagine figlie al padre di questa pagina
+  text_wiki_page_nullify_children: Mantieni le pagine figlie come pagine radice
+  text_wiki_page_destroy_children: Elimina le pagine figlie e tutta la discendenza
+  setting_password_min_length: Lunghezza minima password
+  field_group_by: Raggruppa risultati per
+  mail_subject_wiki_content_updated: "La pagina wiki '%{id}' Ã¨ stata aggiornata"
+  label_wiki_content_added: Aggiunta pagina al wiki
+  mail_subject_wiki_content_added: "La pagina '%{id}' Ã¨ stata aggiunta al wiki"
+  mail_body_wiki_content_added: La pagina '%{id}' Ã¨ stata aggiunta al wiki da %{author}.
+  label_wiki_content_updated: Aggiornata pagina wiki
+  mail_body_wiki_content_updated: La pagina '%{id}' wiki Ã¨ stata aggiornata da%{author}.
+  permission_add_project: Crea progetto
+  setting_new_project_user_role_id: Ruolo assegnato agli utenti non amministratori che creano un progetto
+  label_view_all_revisions: Mostra tutte le revisioni
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: Nessun tracker Ã¨ associato a questo progetto. Per favore verifica le impostazioni del Progetto.
+  error_no_default_issue_status: Nessuno stato predefinito delle segnalazioni Ã¨ configurato. Per favore verifica le impostazioni (Vai in "Amministrazione -> Stati segnalazioni").
+  text_journal_changed: "%{label} modificata da %{old} a %{new}"
+  text_journal_set_to: "%{label} impostata a %{value}"
+  text_journal_deleted: "%{label} eliminata (%{old})"
+  label_group_plural: Gruppi
+  label_group: Gruppo
+  label_group_new: Nuovo gruppo
+  label_time_entry_plural: Tempo impiegato
+  text_journal_added: "%{value} %{label} aggiunto"
+  field_active: Attivo
+  enumeration_system_activity: AttivitÃ  di sistema
+  permission_delete_issue_watchers: Elimina osservatori
+  version_status_closed: chiusa
+  version_status_locked: bloccata
+  version_status_open: aperta
+  error_can_not_reopen_issue_on_closed_version: Una segnalazione assegnata ad una versione chiusa non puÃ² essere riaperta
+  label_user_anonymous: Anonimo
+  button_move_and_follow: Sposta e segui
+  setting_default_projects_modules: Moduli predefiniti abilitati per i nuovi progetti
+  setting_gravatar_default: Immagine Gravatar predefinita
+  field_sharing: Condivisione
+  label_version_sharing_hierarchy: Con gerarchia progetto
+  label_version_sharing_system: Con tutti i progetti
+  label_version_sharing_descendants: Con sottoprogetti
+  label_version_sharing_tree: Con progetto padre
+  label_version_sharing_none: Nessuna condivisione
+  error_can_not_archive_project: Questo progetto non puÃ² essere archiviato
+  button_duplicate: Duplica
+  button_copy_and_follow: Copia e segui
+  label_copy_source: Sorgente
+  setting_issue_done_ratio: Calcola la percentuale di segnalazioni completate con
+  setting_issue_done_ratio_issue_status: Usa lo stato segnalazioni
+  error_issue_done_ratios_not_updated: La percentuale delle segnalazioni completate non Ã¨ aggiornata.
+  error_workflow_copy_target: Per favore seleziona trackers finali e ruolo(i)
+  setting_issue_done_ratio_issue_field: Usa il campo segnalazioni
+  label_copy_same_as_target: Uguale a destinazione
+  label_copy_target: Destinazione
+  notice_issue_done_ratios_updated: La percentuale delle segnalazioni completate Ã¨ aggiornata.
+  error_workflow_copy_source: Per favore seleziona un tracker sorgente o ruolo
+  label_update_issue_done_ratios: Aggiorna la percentuale delle segnalazioni completate
+  setting_start_of_week: Avvia calendari il
+  permission_view_issues: Mostra segnalazioni
+  label_display_used_statuses_only: Mostra solo stati che vengono usati per questo tracker
+  label_revision_id: Revisione %{value}
+  label_api_access_key: Chiave di accesso API
+  label_api_access_key_created_on: Chiave di accesso API creata %{value} fa
+  label_feeds_access_key: Chiave di accesso RSS
+  notice_api_access_key_reseted: La chiave di accesso API Ã¨ stata reimpostata.
+  setting_rest_api_enabled: Abilita il servizio web REST
+  label_missing_api_access_key: Chiave di accesso API mancante
+  label_missing_feeds_access_key: Chiave di accesso RSS mancante
+  button_show: Mostra
+  text_line_separated: Valori multipli permessi (un valore per ogni riga).
+  setting_mail_handler_body_delimiters: Tronca email dopo una di queste righe
+  permission_add_subprojects: Crea sottoprogetti
+  label_subproject_new: Nuovo sottoprogetto
+  text_own_membership_delete_confirmation: |-
+    Stai per eliminare alcuni o tutti i permessi e non sarai piÃ¹ in grado di modificare questo progetto dopo tale azione.
+    Sei sicuro di voler continuare?
+  label_close_versions: Versioni completate chiuse
+  label_board_sticky: Annunci
+  label_board_locked: Bloccato
+  permission_export_wiki_pages: Esporta pagine wiki
+  setting_cache_formatted_text: Cache testo formattato
+  permission_manage_project_activities: Gestisci attivitÃ  progetti
+  error_unable_delete_issue_status: Impossibile eliminare lo stato segnalazioni
+  label_profile: Profilo
+  permission_manage_subtasks: Gestisci sottoattivitÃ 
+  field_parent_issue: AttivitÃ  principale
+  label_subtask_plural: SottoattivitÃ 
+  label_project_copy_notifications: Invia notifiche email durante la copia del progetto
+  error_can_not_delete_custom_field: Impossibile eliminare il campo personalizzato
+  error_unable_to_connect: Impossibile connettersi (%{value})
+  error_can_not_remove_role: Questo ruolo Ã¨ in uso e non puÃ² essere eliminato.
+  error_can_not_delete_tracker: Questo tracker contiene segnalazioni e non puÃ² essere eliminato.
+  field_principal: Principale
+  label_my_page_block: La mia pagina di blocco
+  notice_failed_to_save_members: "Impossibile salvare il membro(i): %{errors}."
+  text_zoom_out: Riduci ingrandimento
+  text_zoom_in: Aumenta ingrandimento
+  notice_unable_delete_time_entry: Impossibile eliminare il valore time log.
+  label_overall_spent_time: Totale tempo impiegato
+  field_time_entries: Tempo di collegamento
+  project_module_gantt: Gantt
+  project_module_calendar: Calendario
+  button_edit_associated_wikipage: "Modifica la pagina wiki associata: %{page_title}"
+  field_text: Campo di testo
+  label_user_mail_option_only_owner: Solo se io sono il proprietario
+  setting_default_notification_option: Opzione di notifica predefinita
+  label_user_mail_option_only_my_events: Solo se sono un osservatore o sono coinvolto
+  label_user_mail_option_only_assigned: Solo quando mi assegnano attivitÃ 
+  label_user_mail_option_none: Nessun evento
+  field_member_of_group: Gruppo dell'assegnatario
+  field_assigned_to_role: Ruolo dell'assegnatario
+  notice_not_authorized_archived_project: Il progetto a cui stai accedendo Ã¨ stato archiviato.
+  label_principal_search: "Cerca utente o gruppo:"
+  label_user_search: "Cerca utente:"
+  field_visible: Visibile
+  setting_emails_header: Intestazione email
+  setting_commit_logtime_activity_id: AttivitÃ  per il tempo di collegamento
+  text_time_logged_by_changeset: Usato nel changeset %{value}.
+  setting_commit_logtime_enabled: Abilita registrazione del tempo di collegamento
+  notice_gantt_chart_truncated: Il grafico Ã¨ stato troncato perchÃ¨ eccede il numero di oggetti (%{max}) da visualizzare
+  setting_gantt_items_limit: Massimo numero di oggetti da visualizzare sul diagramma di gantt
+  field_warn_on_leaving_unsaved: Avvisami quando lascio una pagina con testo non salvato
+  text_warn_on_leaving_unsaved: La pagina corrente contiene del testo non salvato che verrÃ  perso se lasci questa pagina.
+  label_my_queries: Le mie queries personalizzate
+  text_journal_changed_no_detail: "%{label} aggiornato"
+  label_news_comment_added: Commento aggiunto a una notizia
+  button_expand_all: Espandi tutto
+  button_collapse_all: Comprimi tutto
+  label_additional_workflow_transitions_for_assignee: Transizioni supplementari consentite quando l'utente Ã¨ l'assegnatario
+  label_additional_workflow_transitions_for_author: Transizioni supplementari consentite quando l'utente Ã¨ l'autore
+  label_bulk_edit_selected_time_entries: Modifica massiva delle ore segnalate selezionate
+  text_time_entries_destroy_confirmation: Sei sicuro di voler eliminare l'ora\e selezionata\e?
+  label_role_anonymous: Anonimo
+  label_role_non_member: Non membro
+  label_issue_note_added: Nota aggiunta
+  label_issue_status_updated: Stato aggiornato
+  label_issue_priority_updated: PrioritÃ  aggiornata
+  label_issues_visibility_own: Segnalazioni create o assegnate all'utente
+  field_issues_visibility: VisibilitÃ  segnalazioni
+  label_issues_visibility_all: Tutte le segnalazioni
+  permission_set_own_issues_private: Imposta le proprie segnalazioni pubbliche o private
+  field_is_private: Privato
+  permission_set_issues_private: Imposta le segnalazioni pubbliche o private
+  label_issues_visibility_public: Tutte le segnalazioni non private
+  text_issues_destroy_descendants_confirmation: Questo eliminerÃ  anche %{count} sottoattivitÃ .
+  field_commit_logs_encoding: Codifica dei messaggi di commit
+  field_scm_path_encoding: Codifica del percorso
+  text_scm_path_encoding_note: "Predefinito: UTF-8"
+  field_path_to_repository: Percorso del repository
+  field_root_directory: Directory radice
+  field_cvs_module: Modulo
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Repository locale (es. /hgrepo, c:\hgrepo)
+  text_scm_command: Comando
+  text_scm_command_version: Versione
+  label_git_report_last_commit: Riporta l'ultimo commit per files e directories
+  text_scm_config: Puoi configurare i comandi scm nel file config/configuration.yml. E' necessario riavviare l'applicazione dopo averlo modificato.
+  text_scm_command_not_available: Il comando scm non Ã¨ disponibile. Controllare le impostazioni nel pannello di amministrazione.
+  notice_issue_successful_create: Segnalazione %{id} creata.
+  label_between: tra
+  setting_issue_group_assignment: Permetti di assegnare una segnalazione a gruppi
+  label_diff: diff
+  text_git_repository_note: Il repository Ã¨ spoglio e locale (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Ordinamento
+  description_project_scope: Search scope
+  description_filter: Filtro
+  description_user_mail_notification: Impostazioni notifica via mail
+  description_date_from: Inserisci la data d'inizio
+  description_message_content: Contenuto del messaggio
+  description_available_columns: Colonne disponibili
+  description_date_range_interval: Scegli l'intervallo selezionando la data di inizio e di fine
+  description_issue_category_reassign: Scegli la categoria della segnalazione
+  description_search: Campo di ricerca
+  description_notes: Note
+  description_date_range_list: Scegli l'intervallo dalla lista
+  description_choose_project: Progetti
+  description_date_to: Inserisci la data di fine
+  description_query_sort_criteria_attribute: Attributo di ordinamento
+  description_wiki_subpages_reassign: Scegli la nuova pagina padre
+  description_selected_columns: Colonne selezionate
+  label_parent_revision: Padre
+  label_child_revision: Figlio
+  error_scm_annotate_big_text_file: La nota non puÃ² essere salvata, supera la dimensiona massima del campo di testo.
+  setting_default_issue_start_date_to_creation_date: Usa la data corrente come data d'inizio per le nuove segnalazioni
+  button_edit_section: Modifica questa sezione
+  setting_repositories_encodings: Codifica degli allegati e dei repository
+  description_all_columns: Tutte le colonne
+  button_export: Esporta
+  label_export_options: "%{export_format} opzioni per l'export"
+  error_attachment_too_big: Questo file non puÃ² essere caricato in quanto la sua dimensione supera la massima consentita (%{max_size})
+  notice_failed_to_save_time_entries: "Non ho potuto salvare %{count} registrazioni di tempo impiegato su %{total} selezionate: %{ids}."
+  label_x_issues:
+    zero:  0 segnalazione
+    one:   1 segnalazione
+    other: "%{count} segnalazioni"
+  label_repository_new: Nuovo repository
+  field_repository_is_default: Repository principale
+  label_copy_attachments: Copia allegati
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Consentiti solo lettere minuscole (a-z), numeri, trattini e trattini bassi.<br />Una volta salvato, l'identificatore non puÃ² essere modificato.
+  field_multiple: Valori multipli
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Aggiunge le mie note e non salvare le mie ulteriori modifiche
+  text_issue_conflict_resolution_overwrite: Applica comunque le mie modifiche (le note precedenti verranno mantenute ma alcuni cambiamenti potrebbero essere sovrascritti)
+  notice_issue_update_conflict: La segnalazione Ã¨ stata aggiornata da un altro utente mentre la stavi editando.
+  text_issue_conflict_resolution_cancel: Cancella ogni modifica e rivisualizza %{link}
+  permission_manage_related_issues: Gestisci relative segnalazioni
+  field_auth_source_ldap_filter: Filtro LDAP
+  label_search_for_watchers: Cerca osservatori da aggiungere
+  notice_account_deleted: Il tuo account sarÃ  definitivamente rimosso.
+  setting_unsubscribe: Consentire agli utenti di cancellare il proprio account
+  button_delete_my_account: Cancella il mio account
+  text_account_destroy_confirmation: "Sei sicuro di voler procedere?\nIl tuo account sarÃ  definitivamente cancellato, senza alcuna possibilitÃ  di ripristino."
+  error_session_expired: "La tua sessione Ã¨ scaduta. Effettua nuovamente il login."
+  text_session_expiration_settings: "Attenzione: la modifica di queste impostazioni puÃ² far scadere le sessioni correnti, compresa la tua."
+  setting_session_lifetime: Massima durata di una sessione
+  setting_session_timeout: Timeout di inattivitÃ  di una sessione
+  label_session_expiration: Scadenza sessione
+  permission_close_project: Chiusura / riapertura progetto
+  label_show_closed_projects: Vedi progetti chiusi
+  button_close: Chiudi
+  button_reopen: Riapri
+  project_status_active: attivo
+  project_status_closed: chiuso
+  project_status_archived: archiviato
+  text_project_closed: Questo progetto Ã¨ chiuso e in sola lettura.
+  notice_user_successful_create: Creato utente %{id}.
+  field_core_fields: Campi standard
+  field_timeout: Timeout (in secondi)
+  setting_thumbnails_enabled: Mostra miniature degli allegati
+  setting_thumbnails_size: Dimensioni delle miniature (in pixels)
+  label_status_transitions: Transizioni di stato
+  label_fields_permissions: Permessi sui campi
+  label_readonly: Sola lettura
+  label_required: Richiesto
+  text_repository_identifier_info: Consentiti solo lettere minuscole (a-z), numeri, trattini e trattini bassi.<br />Una volta salvato, ll'identificatore non puÃ² essere modificato.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assegnatari %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copia sottoattivitÃ 
+  label_copied_to: copia a
+  label_copied_from: copia da
+  label_any_issues_in_project: ogni segnalazione del progetto
+  label_any_issues_not_in_project: ogni segnalazione non nel progetto
+  field_private_notes: Note private
+  permission_view_private_notes: Visualizza note private
+  permission_set_notes_private: Imposta note come private
+  label_no_issues_in_project: progetto privo di segnalazioni
+  label_any: tutti
+  label_last_n_weeks: ultime %{count} settimane
+  setting_cross_project_subtasks: Consenti sottoattivitÃ  cross-project
+  label_cross_project_descendants: Con sottoprogetti
+  label_cross_project_tree: Con progetto padre
+  label_cross_project_hierarchy: Con gerarchia progetto
+  label_cross_project_system: Con tutti i progetti
+  button_hide: Nascondi
+  setting_non_working_week_days: Giorni non lavorativi
+  label_in_the_next_days: nei prossimi
+  label_in_the_past_days: nei passati
+  label_attribute_of_user: Utente %{name}
+  text_turning_multiple_off: Disabilitando valori multipli, i valori multipli verranno rimossi, in modo da mantenere un solo valore per item.
+  label_attribute_of_issue: Segnalazione %{name}
+  permission_add_documents: Aggiungi documenti
+  permission_edit_documents: Edita documenti
+  permission_delete_documents: Cancella documenti
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Abilita supporto a JSONP
+  field_inherit_members: Eredita membri
+  field_closed_on: Chiuso
+  setting_default_projects_tracker_ids: Trackers di default per nuovi progetti
+  label_total_time: Totale
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/77/77dddf9e601d2a13642541b4fb2f841096013486.svn-base
--- /dev/null
+++ b/.svn/pristine/77/77dddf9e601d2a13642541b4fb2f841096013486.svn-base
@@ -0,0 +1,165 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WelcomeControllerTest < ActionController::TestCase
+  fixtures :projects, :news, :users, :members
+
+  def setup
+    User.current = nil
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:news)
+    assert_not_nil assigns(:projects)
+    assert !assigns(:projects).include?(Project.where(:is_public => false).first)
+  end
+
+  def test_browser_language
+    Setting.default_language = 'en'
+    @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
+    get :index
+    assert_equal :fr, @controller.current_language
+  end
+
+  def test_browser_language_alternate
+    Setting.default_language = 'en'
+    @request.env['HTTP_ACCEPT_LANGUAGE'] = 'zh-TW'
+    get :index
+    assert_equal :"zh-TW", @controller.current_language
+  end
+
+  def test_browser_language_alternate_not_valid
+    Setting.default_language = 'en'
+    @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr-CA'
+    get :index
+    assert_equal :fr, @controller.current_language
+  end
+
+  def test_robots
+    get :robots
+    assert_response :success
+    assert_equal 'text/plain', @response.content_type
+    assert @response.body.match(%r{^Disallow: /projects/ecookbook/issues\r?$})
+  end
+
+  def test_warn_on_leaving_unsaved_turn_on
+    user = User.find(2)
+    user.pref.warn_on_leaving_unsaved = '1'
+    user.pref.save!
+    @request.session[:user_id] = 2
+
+    get :index
+    assert_tag 'script',
+      :attributes => {:type => "text/javascript"},
+      :content => %r{warnLeavingUnsaved}
+  end
+
+  def test_warn_on_leaving_unsaved_turn_off
+    user = User.find(2)
+    user.pref.warn_on_leaving_unsaved = '0'
+    user.pref.save!
+    @request.session[:user_id] = 2
+
+    get :index
+    assert_no_tag 'script',
+      :attributes => {:type => "text/javascript"},
+      :content => %r{warnLeavingUnsaved}
+  end
+
+  def test_logout_link_should_post
+    @request.session[:user_id] = 2
+
+    get :index
+    assert_select 'a[href=/logout][data-method=post]', :text => 'Sign out'
+  end
+
+  def test_call_hook_mixed_in
+    assert @controller.respond_to?(:call_hook)
+  end
+
+  def test_project_jump_box_should_escape_names_once
+    Project.find(1).update_attribute :name, 'Foo & Bar'
+    @request.session[:user_id] = 2
+
+    get :index
+    assert_select "#header select" do
+      assert_select "option", :text => 'Foo &amp; Bar'
+    end
+  end
+
+  context "test_api_offset_and_limit" do
+    context "without params" do
+      should "return 0, 25" do
+        assert_equal [0, 25], @controller.api_offset_and_limit({})
+      end
+    end
+
+    context "with limit" do
+      should "return 0, limit" do
+        assert_equal [0, 30], @controller.api_offset_and_limit({:limit => 30})
+      end
+
+      should "not exceed 100" do
+        assert_equal [0, 100], @controller.api_offset_and_limit({:limit => 120})
+      end
+
+      should "not be negative" do
+        assert_equal [0, 25], @controller.api_offset_and_limit({:limit => -10})
+      end
+    end
+
+    context "with offset" do
+      should "return offset, 25" do
+        assert_equal [10, 25], @controller.api_offset_and_limit({:offset => 10})
+      end
+
+      should "not be negative" do
+        assert_equal [0, 25], @controller.api_offset_and_limit({:offset => -10})
+      end
+
+      context "and limit" do
+        should "return offset, limit" do
+          assert_equal [10, 50], @controller.api_offset_and_limit({:offset => 10, :limit => 50})
+        end
+      end
+    end
+
+    context "with page" do
+      should "return offset, 25" do
+        assert_equal [0, 25], @controller.api_offset_and_limit({:page => 1})
+        assert_equal [50, 25], @controller.api_offset_and_limit({:page => 3})
+      end
+
+      should "not be negative" do
+        assert_equal [0, 25], @controller.api_offset_and_limit({:page => 0})
+        assert_equal [0, 25], @controller.api_offset_and_limit({:page => -2})
+      end
+
+      context "and limit" do
+        should "return offset, limit" do
+          assert_equal [0, 100], @controller.api_offset_and_limit({:page => 1, :limit => 100})
+          assert_equal [200, 100], @controller.api_offset_and_limit({:page => 3, :limit => 100})
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/77/77edc6851d3d16ead6a951e08fc89080d2584af3.svn-base
--- /dev/null
+++ b/.svn/pristine/77/77edc6851d3d16ead6a951e08fc89080d2584af3.svn-base
@@ -0,0 +1,178 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Setting < ActiveRecord::Base
+
+  DATE_FORMATS = [
+        '%Y-%m-%d',
+        '%d/%m/%Y',
+        '%d.%m.%Y',
+        '%d-%m-%Y',
+        '%m/%d/%Y',
+        '%d %b %Y',
+        '%d %B %Y',
+        '%b %d, %Y',
+        '%B %d, %Y'
+    ]
+
+  TIME_FORMATS = [
+    '%H:%M',
+    '%I:%M %p'
+    ]
+
+  ENCODINGS = %w(US-ASCII
+                  windows-1250
+                  windows-1251
+                  windows-1252
+                  windows-1253
+                  windows-1254
+                  windows-1255
+                  windows-1256
+                  windows-1257
+                  windows-1258
+                  windows-31j
+                  ISO-2022-JP
+                  ISO-2022-KR
+                  ISO-8859-1
+                  ISO-8859-2
+                  ISO-8859-3
+                  ISO-8859-4
+                  ISO-8859-5
+                  ISO-8859-6
+                  ISO-8859-7
+                  ISO-8859-8
+                  ISO-8859-9
+                  ISO-8859-13
+                  ISO-8859-15
+                  KOI8-R
+                  UTF-8
+                  UTF-16
+                  UTF-16BE
+                  UTF-16LE
+                  EUC-JP
+                  Shift_JIS
+                  CP932
+                  GB18030
+                  GBK
+                  ISCII91
+                  EUC-KR
+                  Big5
+                  Big5-HKSCS
+                  TIS-620)
+
+  cattr_accessor :available_settings
+  @@available_settings = YAML::load(File.open("#{Rails.root}/config/settings.yml"))
+  Redmine::Plugin.all.each do |plugin|
+    next unless plugin.settings
+    @@available_settings["plugin_#{plugin.id}"] = {'default' => plugin.settings[:default], 'serialized' => true}
+  end
+
+  validates_uniqueness_of :name
+  validates_inclusion_of :name, :in => @@available_settings.keys
+  validates_numericality_of :value, :only_integer => true, :if => Proc.new { |setting| @@available_settings[setting.name]['format'] == 'int' }
+
+  # Hash used to cache setting values
+  @cached_settings = {}
+  @cached_cleared_on = Time.now
+
+  def value
+    v = read_attribute(:value)
+    # Unserialize serialized settings
+    v = YAML::load(v) if @@available_settings[name]['serialized'] && v.is_a?(String)
+    v = v.to_sym if @@available_settings[name]['format'] == 'symbol' && !v.blank?
+    v
+  end
+
+  def value=(v)
+    v = v.to_yaml if v && @@available_settings[name] && @@available_settings[name]['serialized']
+    write_attribute(:value, v.to_s)
+  end
+
+  # Returns the value of the setting named name
+  def self.[](name)
+    v = @cached_settings[name]
+    v ? v : (@cached_settings[name] = find_or_default(name).value)
+  end
+
+  def self.[]=(name, v)
+    setting = find_or_default(name)
+    setting.value = (v ? v : "")
+    @cached_settings[name] = nil
+    setting.save
+    setting.value
+  end
+
+  # Defines getter and setter for each setting
+  # Then setting values can be read using: Setting.some_setting_name
+  # or set using Setting.some_setting_name = "some value"
+  @@available_settings.each do |name, params|
+    src = <<-END_SRC
+    def self.#{name}
+      self[:#{name}]
+    end
+
+    def self.#{name}?
+      self[:#{name}].to_i > 0
+    end
+
+    def self.#{name}=(value)
+      self[:#{name}] = value
+    end
+    END_SRC
+    class_eval src, __FILE__, __LINE__
+  end
+
+  # Helper that returns an array based on per_page_options setting
+  def self.per_page_options_array
+    per_page_options.split(%r{[\s,]}).collect(&:to_i).select {|n| n > 0}.sort
+  end
+
+  def self.openid?
+    Object.const_defined?(:OpenID) && self[:openid].to_i > 0
+  end
+
+  # Checks if settings have changed since the values were read
+  # and clears the cache hash if it's the case
+  # Called once per request
+  def self.check_cache
+    settings_updated_on = Setting.maximum(:updated_on)
+    if settings_updated_on && @cached_cleared_on <= settings_updated_on
+      clear_cache
+    end
+  end
+  
+  # Clears the settings cache
+  def self.clear_cache
+    @cached_settings.clear
+    @cached_cleared_on = Time.now
+    logger.info "Settings cache cleared." if logger
+  end
+
+private
+  # Returns the Setting instance for the setting named name
+  # (record found in database or new record with default value)
+  def self.find_or_default(name)
+    name = name.to_s
+    raise "There's no setting named #{name}" unless @@available_settings.has_key?(name)
+    setting = find_by_name(name)
+    unless setting
+      setting = new(:name => name)
+      setting.value = @@available_settings[name]['default']
+    end
+    setting
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/7828cc0008d3db898fec05425bedf18d84ff5098.svn-base
--- a/.svn/pristine/78/7828cc0008d3db898fec05425bedf18d84ff5098.svn-base
+++ /dev/null
@@ -1,29 +0,0 @@
-<% if issues && issues.any? %>
-<% form_tag({}) do %>
-  <table class="list issues">
-    <thead><tr>
-    <th>#</th>
-    <th><%=l(:field_project)%></th>
-    <th><%=l(:field_tracker)%></th>
-    <th><%=l(:field_subject)%></th>
-    </tr></thead>
-    <tbody>
-    <% for issue in issues %>
-    <tr id="issue-<%= h(issue.id) %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %>">
-      <td class="id">
-        <%= check_box_tag("ids[]", issue.id, false, :style => 'display:none;') %>
-        <%= link_to(h(issue.id), :controller => 'issues', :action => 'show', :id => issue) %>
-      </td>
-      <td class="project"><%= link_to_project(issue.project) %></td>
-      <td class="tracker"><%=h issue.tracker %></td>
-      <td class="subject">
-        <%= link_to h(truncate(issue.subject, :length => 60)), :controller => 'issues', :action => 'show', :id => issue %> (<%=h issue.status %>)
-      </td>
-    </tr>
-    <% end %>
-    </tbody>
-  </table>
-<% end %>
-<% else %>
-  <p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/782c6f591e4e955b6c072dd5cc852035f16ba97d.svn-base
--- /dev/null
+++ b/.svn/pristine/78/782c6f591e4e955b6c072dd5cc852035f16ba97d.svn-base
@@ -0,0 +1,17 @@
+<h3><%= l(:label_issue_plural) %></h3>
+<%= link_to l(:label_issue_view_all), _project_issues_path(@project, :set_filter => 1) %><br />
+<% if @project %>
+<%= link_to l(:field_summary), project_issues_report_path(@project) %><br />
+<% end %>
+<%= call_hook(:view_issues_sidebar_issues_bottom) %>
+
+<% if User.current.allowed_to?(:view_calendar, @project, :global => true) %>
+  <%= link_to l(:label_calendar), _project_calendar_path(@project) %><br />
+<% end %>
+<% if User.current.allowed_to?(:view_gantt, @project, :global => true) %>
+  <%= link_to l(:label_gantt), _project_gantt_path(@project) %><br />
+<% end %>
+<%= call_hook(:view_issues_sidebar_planning_bottom) %>
+
+<%= render_sidebar_queries %>
+<%= call_hook(:view_issues_sidebar_queries_bottom) %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/78376d3215166c5e884949655b3cf6e5caa6e30e.svn-base
--- /dev/null
+++ b/.svn/pristine/78/78376d3215166c5e884949655b3cf6e5caa6e30e.svn-base
@@ -0,0 +1,129 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ActivityTest < ActiveSupport::TestCase
+  fixtures :projects, :versions, :attachments, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
+           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages, :time_entries,
+           :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
+
+  def setup
+    @project = Project.find(1)
+  end
+
+  def test_activity_without_subprojects
+    events = find_events(User.anonymous, :project => @project)
+    assert_not_nil events
+
+    assert events.include?(Issue.find(1))
+    assert !events.include?(Issue.find(4))
+    # subproject issue
+    assert !events.include?(Issue.find(5))
+  end
+
+  def test_activity_with_subprojects
+    events = find_events(User.anonymous, :project => @project, :with_subprojects => 1)
+    assert_not_nil events
+
+    assert events.include?(Issue.find(1))
+    # subproject issue
+    assert events.include?(Issue.find(5))
+  end
+
+  def test_global_activity_anonymous
+    events = find_events(User.anonymous)
+    assert_not_nil events
+
+    assert events.include?(Issue.find(1))
+    assert events.include?(Message.find(5))
+    # Issue of a private project
+    assert !events.include?(Issue.find(4))
+    # Private issue and comment
+    assert !events.include?(Issue.find(14))
+    assert !events.include?(Journal.find(5))
+  end
+
+  def test_global_activity_logged_user
+    events = find_events(User.find(2)) # manager
+    assert_not_nil events
+
+    assert events.include?(Issue.find(1))
+    # Issue of a private project the user belongs to
+    assert events.include?(Issue.find(4))
+  end
+
+  def test_user_activity
+    user = User.find(2)
+    events = Redmine::Activity::Fetcher.new(User.anonymous, :author => user).events(nil, nil, :limit => 10)
+
+    assert(events.size > 0)
+    assert(events.size <= 10)
+    assert_nil(events.detect {|e| e.event_author != user})
+  end
+
+  def test_files_activity
+    f = Redmine::Activity::Fetcher.new(User.anonymous, :project => Project.find(1))
+    f.scope = ['files']
+    events = f.events
+
+    assert_kind_of Array, events
+    assert events.include?(Attachment.find_by_container_type_and_container_id('Project', 1))
+    assert events.include?(Attachment.find_by_container_type_and_container_id('Version', 1))
+    assert_equal [Attachment], events.collect(&:class).uniq
+    assert_equal %w(Project Version), events.collect(&:container_type).uniq.sort
+  end
+
+  def test_event_group_for_issue
+    issue = Issue.find(1)
+    assert_equal issue, issue.event_group
+  end
+
+  def test_event_group_for_journal
+    issue = Issue.find(1)
+    journal = issue.journals.first
+    assert_equal issue, journal.event_group
+  end
+
+  def test_event_group_for_issue_time_entry
+    time = TimeEntry.where(:issue_id => 1).first
+    assert_equal time.issue, time.event_group
+  end
+
+  def test_event_group_for_project_time_entry
+    time = TimeEntry.where(:issue_id => nil).first
+    assert_equal time, time.event_group
+  end
+
+  def test_event_group_for_message
+    message = Message.find(1)
+    reply = message.children.first
+    assert_equal message, message.event_group
+    assert_equal message, reply.event_group
+  end
+
+  def test_event_group_for_wiki_content_version
+    content = WikiContent::Version.find(1)
+    assert_equal content.page, content.event_group
+  end
+
+  private
+
+  def find_events(user, options={})
+    Redmine::Activity::Fetcher.new(user, options).events(Date.today - 30, Date.today + 1)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/784c9b0d2d8855db8c97b7e039fb2ee4a682fc0e.svn-base
--- a/.svn/pristine/78/784c9b0d2d8855db8c97b7e039fb2ee4a682fc0e.svn-base
+++ /dev/null
@@ -1,19 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class TestingTest < Test::Unit::TestCase
-  def setup
-    Engines::Testing.set_fixture_path
-    @filename = File.join(Engines::Testing.temporary_fixtures_directory, 'testing_fixtures.yml')
-    File.delete(@filename) if File.exists?(@filename)
-  end
-  
-  def teardown
-    File.delete(@filename) if File.exists?(@filename)
-  end
-
-  def test_should_copy_fixtures_files_to_tmp_directory
-    assert !File.exists?(@filename)
-    Engines::Testing.setup_plugin_fixtures
-    assert File.exists?(@filename)
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/78656abccdc6e881919c3599b07b9c04e13170fc.svn-base
--- a/.svn/pristine/78/78656abccdc6e881919c3599b07b9c04e13170fc.svn-base
+++ /dev/null
@@ -1,87 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'reports_controller'
-
-# Re-raise errors caught by the controller.
-class ReportsController; def rescue_action(e) raise e end; end
-
-
-class ReportsControllerTest < ActionController::TestCase
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :versions
-
-  def setup
-    @controller = ReportsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  context "GET :issue_report without details" do
-    setup do
-      get :issue_report, :id => 1
-    end
-
-    should_respond_with :success
-    should_render_template :issue_report
-
-    [:issues_by_tracker, :issues_by_version, :issues_by_category, :issues_by_assigned_to,
-     :issues_by_author, :issues_by_subproject].each do |ivar|
-      should_assign_to ivar
-      should "set a value for #{ivar}" do
-        assert assigns[ivar.to_s].present?
-      end
-    end
-  end
-
-  context "GET :issue_report_details" do
-    %w(tracker version priority category assigned_to author subproject).each do |detail|
-      context "for #{detail}" do
-        setup do
-          get :issue_report_details, :id => 1, :detail => detail
-        end
-
-        should_respond_with :success
-        should_render_template :issue_report_details
-        should_assign_to :field
-        should_assign_to :rows
-        should_assign_to :data
-        should_assign_to :report_title
-      end
-    end
-
-    context "with an invalid detail" do
-      setup do
-        get :issue_report_details, :id => 1, :detail => 'invalid'
-      end
-
-      should_respond_with :redirect
-      should_redirect_to('the issue report') {{:controller => 'reports', :action => 'issue_report', :id => 'ecookbook'}}
-    end
-
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/787bda5f0568c9fa3603342f51af7f230d71bae6.svn-base
--- /dev/null
+++ b/.svn/pristine/78/787bda5f0568c9fa3603342f51af7f230d71bae6.svn-base
@@ -0,0 +1,236 @@
+var contextMenuObserving;
+var contextMenuUrl;
+
+function contextMenuRightClick(event) {
+  var target = $(event.target);
+  if (target.is('a')) {return;}
+  var tr = target.parents('tr').first();
+  if (!tr.hasClass('hascontextmenu')) {return;}
+  event.preventDefault();
+  if (!contextMenuIsSelected(tr)) {
+    contextMenuUnselectAll();
+    contextMenuAddSelection(tr);
+    contextMenuSetLastSelected(tr);
+  }
+  contextMenuShow(event);
+}
+
+function contextMenuClick(event) {
+  var target = $(event.target);
+  var lastSelected;
+
+  if (target.is('a') && target.hasClass('submenu')) {
+    event.preventDefault();
+    return;
+  }
+  contextMenuHide();
+  if (target.is('a') || target.is('img')) { return; }
+  if (event.which == 1 || (navigator.appVersion.match(/\bMSIE\b/))) {
+    var tr = target.parents('tr').first();
+    if (tr.length && tr.hasClass('hascontextmenu')) {
+      // a row was clicked, check if the click was on checkbox
+      if (target.is('input')) {
+        // a checkbox may be clicked
+        if (target.attr('checked')) {
+          tr.addClass('context-menu-selection');
+        } else {
+          tr.removeClass('context-menu-selection');
+        }
+      } else {
+        if (event.ctrlKey || event.metaKey) {
+          contextMenuToggleSelection(tr);
+        } else if (event.shiftKey) {
+          lastSelected = contextMenuLastSelected();
+          if (lastSelected.length) {
+            var toggling = false;
+            $('.hascontextmenu').each(function(){
+              if (toggling || $(this).is(tr)) {
+                contextMenuAddSelection($(this));
+              }
+              if ($(this).is(tr) || $(this).is(lastSelected)) {
+                toggling = !toggling;
+              }
+            });
+          } else {
+            contextMenuAddSelection(tr);
+          }
+        } else {
+          contextMenuUnselectAll();
+          contextMenuAddSelection(tr);
+        }
+        contextMenuSetLastSelected(tr);
+      }
+    } else {
+      // click is outside the rows
+      if (target.is('a') && (target.hasClass('disabled') || target.hasClass('submenu'))) {
+        event.preventDefault();
+      } else {
+        contextMenuUnselectAll();
+      }
+    }
+  }
+}
+
+function contextMenuCreate() {
+  if ($('#context-menu').length < 1) {
+    var menu = document.createElement("div");
+    menu.setAttribute("id", "context-menu");
+    menu.setAttribute("style", "display:none;");
+    document.getElementById("content").appendChild(menu);
+  }
+}
+
+function contextMenuShow(event) {
+  var mouse_x = event.pageX;
+  var mouse_y = event.pageY;
+  var render_x = mouse_x;
+  var render_y = mouse_y;
+  var dims;
+  var menu_width;
+  var menu_height;
+  var window_width;
+  var window_height;
+  var max_width;
+  var max_height;
+
+  $('#context-menu').css('left', (render_x + 'px'));
+  $('#context-menu').css('top', (render_y + 'px'));
+  $('#context-menu').html('');
+
+  $.ajax({
+    url: contextMenuUrl,
+    data: $(event.target).parents('form').first().serialize(),
+    success: function(data, textStatus, jqXHR) {
+      $('#context-menu').html(data);
+      menu_width = $('#context-menu').width();
+      menu_height = $('#context-menu').height();
+      max_width = mouse_x + 2*menu_width;
+      max_height = mouse_y + menu_height;
+
+      var ws = window_size();
+      window_width = ws.width;
+      window_height = ws.height;
+
+      /* display the menu above and/or to the left of the click if needed */
+      if (max_width > window_width) {
+       render_x -= menu_width;
+       $('#context-menu').addClass('reverse-x');
+      } else {
+       $('#context-menu').removeClass('reverse-x');
+      }
+      if (max_height > window_height) {
+       render_y -= menu_height;
+       $('#context-menu').addClass('reverse-y');
+      } else {
+       $('#context-menu').removeClass('reverse-y');
+      }
+      if (render_x <= 0) render_x = 1;
+      if (render_y <= 0) render_y = 1;
+      $('#context-menu').css('left', (render_x + 'px'));
+      $('#context-menu').css('top', (render_y + 'px'));
+      $('#context-menu').show();
+
+      //if (window.parseStylesheets) { window.parseStylesheets(); } // IE
+
+    }
+  });
+}
+
+function contextMenuSetLastSelected(tr) {
+  $('.cm-last').removeClass('cm-last');
+  tr.addClass('cm-last');
+}
+
+function contextMenuLastSelected() {
+  return $('.cm-last').first();
+}
+
+function contextMenuUnselectAll() {
+  $('.hascontextmenu').each(function(){
+    contextMenuRemoveSelection($(this));
+  });
+  $('.cm-last').removeClass('cm-last');
+}
+
+function contextMenuHide() {
+  $('#context-menu').hide();
+}
+
+function contextMenuToggleSelection(tr) {
+  if (contextMenuIsSelected(tr)) {
+    contextMenuRemoveSelection(tr);
+  } else {
+    contextMenuAddSelection(tr);
+  }
+}
+
+function contextMenuAddSelection(tr) {
+  tr.addClass('context-menu-selection');
+  contextMenuCheckSelectionBox(tr, true);
+  contextMenuClearDocumentSelection();
+}
+
+function contextMenuRemoveSelection(tr) {
+  tr.removeClass('context-menu-selection');
+  contextMenuCheckSelectionBox(tr, false);
+}
+
+function contextMenuIsSelected(tr) {
+  return tr.hasClass('context-menu-selection');
+}
+
+function contextMenuCheckSelectionBox(tr, checked) {
+  tr.find('input[type=checkbox]').attr('checked', checked);
+}
+
+function contextMenuClearDocumentSelection() {
+  // TODO
+  if (document.selection) {
+    document.selection.empty(); // IE
+  } else {
+    window.getSelection().removeAllRanges();
+  }
+}
+
+function contextMenuInit(url) {
+  contextMenuUrl = url;
+  contextMenuCreate();
+  contextMenuUnselectAll();
+  
+  if (!contextMenuObserving) {
+    $(document).click(contextMenuClick);
+    $(document).contextmenu(contextMenuRightClick);
+    contextMenuObserving = true;
+  }
+}
+
+function toggleIssuesSelection(el) {
+  var boxes = $(el).parents('form').find('input[type=checkbox]');
+  var all_checked = true;
+  boxes.each(function(){ if (!$(this).attr('checked')) { all_checked = false; } });
+  boxes.each(function(){
+    if (all_checked) {
+      $(this).removeAttr('checked');
+      $(this).parents('tr').removeClass('context-menu-selection');
+    } else if (!$(this).attr('checked')) {
+      $(this).attr('checked', true);
+      $(this).parents('tr').addClass('context-menu-selection');
+    }
+  });
+}
+
+function window_size() {
+  var w;
+  var h;
+  if (window.innerWidth) {
+    w = window.innerWidth;
+    h = window.innerHeight;
+  } else if (document.documentElement) {
+    w = document.documentElement.clientWidth;
+    h = document.documentElement.clientHeight;
+  } else {
+    w = document.body.clientWidth;
+    h = document.body.clientHeight;
+  }
+  return {width: w, height: h};
+}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/7884d1a52f46dcfb203fc57885fb084b78063ba1.svn-base
--- /dev/null
+++ b/.svn/pristine/78/7884d1a52f46dcfb203fc57885fb084b78063ba1.svn-base
@@ -0,0 +1,242 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/abstract_adapter'
+require 'rexml/document'
+
+module Redmine
+  module Scm
+    module Adapters
+      class DarcsAdapter < AbstractAdapter
+        # Darcs executable name
+        DARCS_BIN = Redmine::Configuration['scm_darcs_command'] || "darcs"
+
+        class << self
+          def client_command
+            @@bin    ||= DARCS_BIN
+          end
+
+          def sq_bin
+            @@sq_bin ||= shell_quote_command
+          end
+
+          def client_version
+            @@client_version ||= (darcs_binary_version || [])
+          end
+
+          def client_available
+            !client_version.empty?
+          end
+
+          def darcs_binary_version
+            darcsversion = darcs_binary_version_from_command_line.dup
+            if darcsversion.respond_to?(:force_encoding)
+              darcsversion.force_encoding('ASCII-8BIT')
+            end
+            if m = darcsversion.match(%r{\A(.*?)((\d+\.)+\d+)})
+              m[2].scan(%r{\d+}).collect(&:to_i)
+            end
+          end
+
+          def darcs_binary_version_from_command_line
+            shellout("#{sq_bin} --version") { |io| io.read }.to_s
+          end
+        end
+
+        def initialize(url, root_url=nil, login=nil, password=nil,
+                       path_encoding=nil)
+          @url = url
+          @root_url = url
+        end
+
+        def supports_cat?
+          # cat supported in darcs 2.0.0 and higher
+          self.class.client_version_above?([2, 0, 0])
+        end
+
+        # Get info about the darcs repository
+        def info
+          rev = revisions(nil,nil,nil,{:limit => 1})
+          rev ? Info.new({:root_url => @url, :lastrev => rev.last}) : nil
+        end
+
+        # Returns an Entries collection
+        # or nil if the given path doesn't exist in the repository
+        def entries(path=nil, identifier=nil, options={})
+          path_prefix = (path.blank? ? '' : "#{path}/")
+          if path.blank?
+            path = ( self.class.client_version_above?([2, 2, 0]) ? @url : '.' )
+          end
+          entries = Entries.new
+          cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --xml-output"
+          cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
+          cmd << " #{shell_quote path}"
+          shellout(cmd) do |io|
+            begin
+              doc = REXML::Document.new(io)
+              if doc.root.name == 'directory'
+                doc.elements.each('directory/*') do |element|
+                  next unless ['file', 'directory'].include? element.name
+                  entries << entry_from_xml(element, path_prefix)
+                end
+              elsif doc.root.name == 'file'
+                entries << entry_from_xml(doc.root, path_prefix)
+              end
+            rescue
+            end
+          end
+          return nil if $? && $?.exitstatus != 0
+          entries.compact!
+          entries.sort_by_name
+        end
+
+        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
+          path = '.' if path.blank?
+          revisions = Revisions.new
+          cmd = "#{self.class.sq_bin} changes --repodir #{shell_quote @url} --xml-output"
+          cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from
+          cmd << " --last #{options[:limit].to_i}" if options[:limit]
+          shellout(cmd) do |io|
+            begin
+              doc = REXML::Document.new(io)
+              doc.elements.each("changelog/patch") do |patch|
+                message = patch.elements['name'].text
+                message << "\n" + patch.elements['comment'].text.gsub(/\*\*\*END OF DESCRIPTION\*\*\*.*\z/m, '') if patch.elements['comment']
+                revisions << Revision.new({:identifier => nil,
+                              :author => patch.attributes['author'],
+                              :scmid => patch.attributes['hash'],
+                              :time => Time.parse(patch.attributes['local_date']),
+                              :message => message,
+                              :paths => (options[:with_path] ? get_paths_for_patch(patch.attributes['hash']) : nil)
+                            })
+              end
+            rescue
+            end
+          end
+          return nil if $? && $?.exitstatus != 0
+          revisions
+        end
+
+        def diff(path, identifier_from, identifier_to=nil)
+          path = '*' if path.blank?
+          cmd = "#{self.class.sq_bin} diff --repodir #{shell_quote @url}"
+          if identifier_to.nil?
+            cmd << " --match #{shell_quote("hash #{identifier_from}")}"
+          else
+            cmd << " --to-match #{shell_quote("hash #{identifier_from}")}"
+            cmd << " --from-match #{shell_quote("hash #{identifier_to}")}"
+          end
+          cmd << " -u #{shell_quote path}"
+          diff = []
+          shellout(cmd) do |io|
+            io.each_line do |line|
+              diff << line
+            end
+          end
+          return nil if $? && $?.exitstatus != 0
+          diff
+        end
+
+        def cat(path, identifier=nil)
+          cmd = "#{self.class.sq_bin} show content --repodir #{shell_quote @url}"
+          cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
+          cmd << " #{shell_quote path}"
+          cat = nil
+          shellout(cmd) do |io|
+            io.binmode
+            cat = io.read
+          end
+          return nil if $? && $?.exitstatus != 0
+          cat
+        end
+
+        private
+
+        # Returns an Entry from the given XML element
+        # or nil if the entry was deleted
+        def entry_from_xml(element, path_prefix)
+          modified_element = element.elements['modified']
+          if modified_element.elements['modified_how'].text.match(/removed/)
+            return nil
+          end
+
+          Entry.new({:name => element.attributes['name'],
+                     :path => path_prefix + element.attributes['name'],
+                     :kind => element.name == 'file' ? 'file' : 'dir',
+                     :size => nil,
+                     :lastrev => Revision.new({
+                       :identifier => nil,
+                       :scmid => modified_element.elements['patch'].attributes['hash']
+                       })
+                     })
+        end
+
+        def get_paths_for_patch(hash)
+          paths = get_paths_for_patch_raw(hash)
+          if self.class.client_version_above?([2, 4])
+            orig_paths = paths
+            paths = []
+            add_paths = []
+            add_paths_name = []
+            mod_paths = []
+            other_paths = []
+            orig_paths.each do |path|
+              if path[:action] == 'A'
+                add_paths << path
+                add_paths_name << path[:path]
+              elsif path[:action] == 'M'
+                mod_paths << path
+              else
+                other_paths << path
+              end
+            end
+            add_paths_name.each do |add_path|
+              mod_paths.delete_if { |m| m[:path] == add_path }
+            end
+            paths.concat add_paths
+            paths.concat mod_paths
+            paths.concat other_paths
+          end
+          paths
+        end
+
+        # Retrieve changed paths for a single patch
+        def get_paths_for_patch_raw(hash)
+          cmd = "#{self.class.sq_bin} annotate --repodir #{shell_quote @url} --summary --xml-output"
+          cmd << " --match #{shell_quote("hash #{hash}")} "
+          paths = []
+          shellout(cmd) do |io|
+            begin
+              # Darcs xml output has multiple root elements in this case (tested with darcs 1.0.7)
+              # A root element is added so that REXML doesn't raise an error
+              doc = REXML::Document.new("<fake_root>" + io.read + "</fake_root>")
+              doc.elements.each('fake_root/summary/*') do |modif|
+                paths << {:action => modif.name[0,1].upcase,
+                          :path => "/" + modif.text.chomp.gsub(/^\s*/, '')
+                         }
+              end
+            rescue
+            end
+          end
+          paths
+        rescue CommandFailed
+          paths
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/7887ac0add3adb74049da4eb63c9169b67eaf06b.svn-base
--- a/.svn/pristine/78/7887ac0add3adb74049da4eb63c9169b67eaf06b.svn-base
+++ /dev/null
@@ -1,226 +0,0 @@
-require 'rake'
-require 'rake/rdoctask'
-require 'tmpdir'
-
-task :default => :doc
-
-desc 'Generate documentation for the engines plugin.'
-Rake::RDocTask.new(:doc) do |doc|
-  doc.rdoc_dir = 'doc'
-  doc.title    = 'Engines'
-  doc.main     = "README"
-  doc.rdoc_files.include("README", "CHANGELOG", "MIT-LICENSE")
-  doc.rdoc_files.include('lib/**/*.rb')
-  doc.options << '--line-numbers' << '--inline-source'
-end
-
-desc 'Run the engine plugin tests within their test harness'
-task :cruise do
-  # checkout the project into a temporary directory
-  version = "rails_2.0"
-  test_dir = "#{Dir.tmpdir}/engines_plugin_#{version}_test"
-  puts "Checking out test harness for #{version} into #{test_dir}"
-  `svn co http://svn.rails-engines.org/test/engines/#{version} #{test_dir}`
-
-  # run all the tests in this project
-  Dir.chdir(test_dir)
-  load 'Rakefile'
-  puts "Running all tests in test harness"
-  ['db:migrate', 'test', 'test:plugins'].each do |t|
-    Rake::Task[t].invoke
-  end  
-end
-
-task :clean => [:clobber_doc, "test:clean"]
-
-namespace :test do
-  
-  # Yields a block with STDOUT and STDERR silenced. If you *really* want
-  # to output something, the block is yielded with the original output
-  # streams, i.e.
-  #
-  #   silence do |o, e|
-  #     puts 'hello!' # no output produced
-  #     o.puts 'hello!' # output on STDOUT
-  #   end
-  #
-  # (based on silence_stream in ActiveSupport.)
-  def silence
-    yield(STDOUT, STDERR) if ENV['VERBOSE']
-    streams = [STDOUT, STDERR]
-    actual_stdout = STDOUT.dup
-    actual_stderr = STDERR.dup
-    streams.each do |s| 
-      s.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null') 
-      s.sync = true
-    end
-    yield actual_stdout, actual_stderr
-  ensure
-    STDOUT.reopen(actual_stdout)
-    STDERR.reopen(actual_stderr)
-  end
-  
-  def test_app_dir
-    File.join(File.dirname(__FILE__), 'test_app')
-  end
-  
-  def run(cmd)
-    cmd = cmd.join(" && ") if cmd.is_a?(Array)
-    system(cmd) || raise("failed running '#{cmd}'")
-  end
-  
-  desc 'Remove the test application'
-  task :clean do
-    FileUtils.rm_r(test_app_dir) if File.exist?(test_app_dir)
-  end
-  
-  desc 'Build the test rails application (use RAILS=[edge,<directory>] to test against specific version)'
-  task :generate_app do
-    silence do |out, err|
-      out.puts "> Creating test application at #{test_app_dir}"
-        
-      if ENV['RAILS']
-        vendor_dir = File.join(test_app_dir, 'vendor')
-        FileUtils.mkdir_p vendor_dir
-        
-        if ENV['RAILS'] == 'edge'
-          out.puts "    Cloning Edge Rails from GitHub"
-          run "cd #{vendor_dir} && git clone --depth 1 git://github.com/rails/rails.git"
-        elsif ENV['RAILS'] =~ /\d\.\d\.\d/
-          if ENV['CURL']
-            out.puts "    Cloning Rails Tag #{ENV['RAILS']} from GitHub using curl and tar"
-            run ["cd #{vendor_dir}",
-                 "mkdir rails",
-                 "cd rails",
-                 "curl -s -L http://github.com/rails/rails/tarball/#{ENV['RAILS']} | tar xzv --strip-components 1"]
-          else
-            out.puts "    Cloning Rails Tag #{ENV['RAILS']} from GitHub (can be slow - set CURL=true to use curl)"
-            run ["cd #{vendor_dir}",
-                 "git clone git://github.com/rails/rails.git",
-                 "cd rails",
-                 "git pull",
-                 "git checkout v#{ENV['RAILS']}"]
-          end
-        elsif File.exist?(ENV['RAILS'])
-          out.puts "    Linking rails from #{ENV['RAILS']}"
-          run "cd #{vendor_dir} && ln -s #{ENV['RAILS']} rails"
-        else
-          raise "Couldn't build test application from '#{ENV['RAILS']}'"
-        end
-      
-        out.puts "    generating rails default directory structure"
-        run "ruby #{File.join(vendor_dir, 'rails', 'railties', 'bin', 'rails')} #{test_app_dir}"
-      else
-        version = `rails --version`.chomp.split.last
-        out.puts "    building rails using the 'rails' command (rails version: #{version})"
-        run "rails #{test_app_dir}"
-      end
-    
-      # get the database config and schema in place
-      out.puts "    writing database.yml"
-      require 'yaml'
-      File.open(File.join(test_app_dir, 'config', 'database.yml'), 'w') do |f|
-        f.write(%w(development test).inject({}) do |h, env| 
-          h[env] = {"adapter" => "sqlite3", "database" => "engines_#{env}.sqlite3"} ; h
-        end.to_yaml)
-      end
-      out.puts "    installing exception_notification plugin"
-      run "cd #{test_app_dir} && ./script/plugin install git://github.com/rails/exception_notification.git"
-    end
-  end
-  
-  # We can't link the plugin, as it needs to be present for script/generate to find
-  # the plugin generator.
-  # TODO: find and +1/create issue for loading generators from symlinked plugins
-  desc 'Mirror the engines plugin into the test application'
-  task :copy_engines_plugin do
-    puts "> Copying engines plugin into test application"
-    engines_plugin = File.join(test_app_dir, "vendor", "plugins", "engines")
-    FileUtils.rm_r(engines_plugin) if File.exist?(engines_plugin)
-    FileUtils.mkdir_p(engines_plugin)
-    FileList["*"].exclude("test_app").each do |file|
-      FileUtils.cp_r(file, engines_plugin)
-    end
-  end
-  
-  def insert_line(line, options)
-    line = line + "\n"
-    target_file = File.join(test_app_dir, options[:into])
-    lines = File.readlines(target_file)
-    return if lines.include?(line)
-    
-    if options[:after]
-      if options[:after].is_a?(String)
-        after_line = options[:after] + "\n"
-      else
-        after_line = lines.find { |l| l =~ options[:after] }
-        raise "couldn't find a line matching #{options[:after].inspect} in #{target_file}" unless after_line
-      end
-      index = lines.index(after_line)
-      raise "couldn't find line '#{after_line}' in #{target_file}" unless index
-      lines.insert(index + 1, line)
-    else
-      lines << line
-    end
-    File.open(target_file, 'w') { |f| f.write lines.join }
-  end
-  
-  def mirror_test_files(src, dest=nil)
-    destination_dir = File.join(*([test_app_dir, dest].compact))
-    FileUtils.cp_r(File.join(File.dirname(__FILE__), 'test', src), destination_dir)
-  end
-  
-  desc 'Update the plugin and tests files in the test application from the plugin'
-  task :mirror_engine_files => [:test_app, :copy_engines_plugin] do
-    puts "> Tweaking generated application to be suitable for testing"
-    
-    # Replace the Rails plugin loader with the engines one.
-    insert_line("require File.join(File.dirname(__FILE__), '../vendor/plugins/engines/boot')",
-                :into => 'config/environment.rb',
-                :after => "require File.join(File.dirname(__FILE__), 'boot')")
-    
-    # Add the engines test helper to handle fixtures & stuff.
-    insert_line("require 'engines_test_helper'", :into => 'test/test_helper.rb')
-    
-    # Run engine plugin tests when running the application 
-    insert_line("task :test => ['test:engines:all']", :into => 'Rakefile')
-    
-    # We want exceptions to be raised
-    insert_line("def rescue_action(e) raise e end;", 
-                :into => "app/controllers/application_controller.rb",
-                :after => "class ApplicationController < ActionController::Base")
-    
-    # We need this method to test where actions are being rendered from.
-    insert_line("include RenderInformation", 
-                :into => "app/controllers/application_controller.rb",
-                :after => "class ApplicationController < ActionController::Base")
-    
-    puts "> Mirroring test application files into #{test_app_dir}"
-    mirror_test_files('app')
-    mirror_test_files('lib')
-    mirror_test_files('plugins', 'vendor')
-    mirror_test_files('unit', 'test')
-    mirror_test_files('functional', 'test')
-  end
-  
-  desc 'Prepare the engines test environment'
-  task :test_app do
-    version_tag = File.join(test_app_dir, 'RAILS_VERSION')
-    existing_version = File.read(version_tag).chomp rescue 'unknown'
-    if existing_version == ENV['RAILS']
-      puts "> Reusing existing test application (#{ENV['RAILS']})"
-    else
-      puts "> Recreating test application"
-      Rake::Task["test:clean"].invoke
-      Rake::Task["test:generate_app"].invoke
-      
-      File.open(version_tag, "w") { |f| f.write ENV['RAILS'] }
-    end
-  end
-end
-
-task :test => "test:mirror_engine_files" do
-  puts "> Loading the test application environment and running tests"
-  # We use exec here to replace the current running rake process
-  exec("cd #{test_app_dir} && rake db:migrate && rake")
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/78a1de16a7f51fffc3afacfeda93104b299506dc.svn-base
--- a/.svn/pristine/78/78a1de16a7f51fffc3afacfeda93104b299506dc.svn-base
+++ /dev/null
@@ -1,323 +0,0 @@
-# encoding: utf-8
-require 'strscan'
-
-module CodeRay
-
-  autoload :WordList, 'coderay/helpers/word_list'
-  
-  # = Scanners
-  #
-  # This module holds the Scanner class and its subclasses.
-  # For example, the Ruby scanner is named CodeRay::Scanners::Ruby
-  # can be found in coderay/scanners/ruby.
-  #
-  # Scanner also provides methods and constants for the register
-  # mechanism and the [] method that returns the Scanner class
-  # belonging to the given lang.
-  #
-  # See PluginHost.
-  module Scanners
-    extend PluginHost
-    plugin_path File.dirname(__FILE__), 'scanners'
-    
-    
-    # = Scanner
-    #
-    # The base class for all Scanners.
-    #
-    # It is a subclass of Ruby's great +StringScanner+, which
-    # makes it easy to access the scanning methods inside.
-    #
-    # It is also +Enumerable+, so you can use it like an Array of
-    # Tokens:
-    #
-    #   require 'coderay'
-    #   
-    #   c_scanner = CodeRay::Scanners[:c].new "if (*p == '{') nest++;"
-    #   
-    #   for text, kind in c_scanner
-    #     puts text if kind == :operator
-    #   end
-    #   
-    #   # prints: (*==)++;
-    #
-    # OK, this is a very simple example :)
-    # You can also use +map+, +any?+, +find+ and even +sort_by+,
-    # if you want.
-    class Scanner < StringScanner
-      
-      extend Plugin
-      plugin_host Scanners
-      
-      # Raised if a Scanner fails while scanning
-      ScanError = Class.new StandardError
-      
-      # The default options for all scanner classes.
-      #
-      # Define @default_options for subclasses.
-      DEFAULT_OPTIONS = { }
-      
-      KINDS_NOT_LOC = [:comment, :doctype, :docstring]
-      
-      attr_accessor :state
-      
-      class << self
-        
-        # Normalizes the given code into a string with UNIX newlines, in the
-        # scanner's internal encoding, with invalid and undefined charachters
-        # replaced by placeholders. Always returns a new object.
-        def normalize code
-          # original = code
-          code = code.to_s unless code.is_a? ::String
-          return code if code.empty?
-          
-          if code.respond_to? :encoding
-            code = encode_with_encoding code, self.encoding
-          else
-            code = to_unix code
-          end
-          # code = code.dup if code.eql? original
-          code
-        end
-        
-        # The typical filename suffix for this scanner's language.
-        def file_extension extension = lang
-          @file_extension ||= extension.to_s
-        end
-        
-        # The encoding used internally by this scanner.
-        def encoding name = 'UTF-8'
-          @encoding ||= defined?(Encoding.find) && Encoding.find(name)
-        end
-        
-        # The lang of this Scanner class, which is equal to its Plugin ID.
-        def lang
-          @plugin_id
-        end
-        
-      protected
-        
-        def encode_with_encoding code, target_encoding
-          if code.encoding == target_encoding
-            if code.valid_encoding?
-              return to_unix(code)
-            else
-              source_encoding = guess_encoding code
-            end
-          else
-            source_encoding = code.encoding
-          end
-          # print "encode_with_encoding from #{source_encoding} to #{target_encoding}"
-          code.encode target_encoding, source_encoding, :universal_newline => true, :undef => :replace, :invalid => :replace
-        end
-        
-        def to_unix code
-          code.index(?\r) ? code.gsub(/\r\n?/, "\n") : code
-        end
-        
-        def guess_encoding s
-          #:nocov:
-          IO.popen("file -b --mime -", "w+") do |file|
-            file.write s[0, 1024]
-            file.close_write
-            begin
-              Encoding.find file.gets[/charset=([-\w]+)/, 1]
-            rescue ArgumentError
-              Encoding::BINARY
-            end
-          end
-          #:nocov:
-        end
-        
-      end
-      
-      # Create a new Scanner.
-      #
-      # * +code+ is the input String and is handled by the superclass
-      #   StringScanner.
-      # * +options+ is a Hash with Symbols as keys.
-      #   It is merged with the default options of the class (you can
-      #   overwrite default options here.)
-      #
-      # Else, a Tokens object is used.
-      def initialize code = '', options = {}
-        if self.class == Scanner
-          raise NotImplementedError, "I am only the basic Scanner class. I can't scan anything. :( Use my subclasses."
-        end
-        
-        @options = self.class::DEFAULT_OPTIONS.merge options
-        
-        super self.class.normalize(code)
-        
-        @tokens = options[:tokens] || Tokens.new
-        @tokens.scanner = self if @tokens.respond_to? :scanner=
-        
-        setup
-      end
-      
-      # Sets back the scanner. Subclasses should redefine the reset_instance
-      # method instead of this one.
-      def reset
-        super
-        reset_instance
-      end
-      
-      # Set a new string to be scanned.
-      def string= code
-        code = self.class.normalize(code)
-        super code
-        reset_instance
-      end
-      
-      # the Plugin ID for this scanner
-      def lang
-        self.class.lang
-      end
-      
-      # the default file extension for this scanner
-      def file_extension
-        self.class.file_extension
-      end
-      
-      # Scan the code and returns all tokens in a Tokens object.
-      def tokenize source = nil, options = {}
-        options = @options.merge(options)
-        @tokens = options[:tokens] || @tokens || Tokens.new
-        @tokens.scanner = self if @tokens.respond_to? :scanner=
-        case source
-        when Array
-          self.string = self.class.normalize(source.join)
-        when nil
-          reset
-        else
-          self.string = self.class.normalize(source)
-        end
-        
-        begin
-          scan_tokens @tokens, options
-        rescue => e
-          message = "Error in %s#scan_tokens, initial state was: %p" % [self.class, defined?(state) && state]
-          raise_inspect e.message, @tokens, message, 30, e.backtrace
-        end
-        
-        @cached_tokens = @tokens
-        if source.is_a? Array
-          @tokens.split_into_parts(*source.map { |part| part.size })
-        else
-          @tokens
-        end
-      end
-      
-      # Cache the result of tokenize.
-      def tokens
-        @cached_tokens ||= tokenize
-      end
-      
-      # Traverse the tokens.
-      def each &block
-        tokens.each(&block)
-      end
-      include Enumerable
-      
-      # The current line position of the scanner, starting with 1.
-      # See also: #column.
-      #
-      # Beware, this is implemented inefficiently. It should be used
-      # for debugging only.
-      def line pos = self.pos
-        return 1 if pos <= 0
-        binary_string[0...pos].count("\n") + 1
-      end
-      
-      # The current column position of the scanner, starting with 1.
-      # See also: #line.
-      def column pos = self.pos
-        return 1 if pos <= 0
-        pos - (binary_string.rindex(?\n, pos - 1) || -1)
-      end
-      
-      # The string in binary encoding.
-      # 
-      # To be used with #pos, which is the index of the byte the scanner
-      # will scan next.
-      def binary_string
-        @binary_string ||=
-          if string.respond_to?(:bytesize) && string.bytesize != string.size
-            #:nocov:
-            string.dup.force_encoding('binary')
-            #:nocov:
-          else
-            string
-          end
-      end
-      
-    protected
-      
-      # Can be implemented by subclasses to do some initialization
-      # that has to be done once per instance.
-      #
-      # Use reset for initialization that has to be done once per
-      # scan.
-      def setup  # :doc:
-      end
-      
-      # This is the central method, and commonly the only one a
-      # subclass implements.
-      #
-      # Subclasses must implement this method; it must return +tokens+
-      # and must only use Tokens#<< for storing scanned tokens!
-      def scan_tokens tokens, options  # :doc:
-        raise NotImplementedError, "#{self.class}#scan_tokens not implemented."
-      end
-      
-      # Resets the scanner.
-      def reset_instance
-        @tokens.clear if @tokens.respond_to?(:clear) && !@options[:keep_tokens]
-        @cached_tokens = nil
-        @binary_string = nil if defined? @binary_string
-      end
-      
-      # Scanner error with additional status information
-      def raise_inspect msg, tokens, state = self.state || 'No state given!', ambit = 30, backtrace = caller
-        raise ScanError, <<-EOE % [
-
-
-***ERROR in %s: %s (after %d tokens)
-
-tokens:
-%s
-
-current line: %d  column: %d  pos: %d
-matched: %p  state: %p
-bol? = %p,  eos? = %p
-
-surrounding code:
-%p  ~~  %p
-
-
-***ERROR***
-
-        EOE
-          File.basename(caller[0]),
-          msg,
-          tokens.respond_to?(:size) ? tokens.size : 0,
-          tokens.respond_to?(:last) ? tokens.last(10).map { |t| t.inspect }.join("\n") : '',
-          line, column, pos,
-          matched, state, bol?, eos?,
-          binary_string[pos - ambit, ambit],
-          binary_string[pos, ambit],
-        ], backtrace
-      end
-      
-      # Shorthand for scan_until(/\z/).
-      # This method also avoids a JRuby 1.9 mode bug.
-      def scan_rest
-        rest = self.rest
-        terminate
-        rest
-      end
-      
-    end
-    
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/78ae413198b7dc2195c980bf2f03968e4d50e683.svn-base
--- /dev/null
+++ b/.svn/pristine/78/78ae413198b7dc2195c980bf2f03968e4d50e683.svn-base
@@ -0,0 +1,3898 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssuesControllerTest < ActionController::TestCase
+  fixtures :projects,
+           :users,
+           :roles,
+           :members,
+           :member_roles,
+           :issues,
+           :issue_statuses,
+           :versions,
+           :trackers,
+           :projects_trackers,
+           :issue_categories,
+           :enabled_modules,
+           :enumerations,
+           :attachments,
+           :workflows,
+           :custom_fields,
+           :custom_values,
+           :custom_fields_projects,
+           :custom_fields_trackers,
+           :time_entries,
+           :journals,
+           :journal_details,
+           :queries,
+           :repositories,
+           :changesets
+
+  include Redmine::I18n
+
+  def setup
+    User.current = nil
+  end
+
+  def test_index
+    with_settings :default_language => "en" do
+      get :index
+      assert_response :success
+      assert_template 'index'
+      assert_not_nil assigns(:issues)
+      assert_nil assigns(:project)
+
+      # links to visible issues
+      assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
+      assert_select 'a[href=/issues/5]', :text => /Subproject issue/
+      # private projects hidden
+      assert_select 'a[href=/issues/6]', 0
+      assert_select 'a[href=/issues/4]', 0
+      # project column
+      assert_select 'th', :text => /Project/
+    end
+  end
+
+  def test_index_should_not_list_issues_when_module_disabled
+    EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
+    get :index
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+    assert_nil assigns(:project)
+
+    assert_select 'a[href=/issues/1]', 0
+    assert_select 'a[href=/issues/5]', :text => /Subproject issue/
+  end
+
+  def test_index_should_list_visible_issues_only
+    get :index, :per_page => 100
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert_nil assigns(:issues).detect {|issue| !issue.visible?}
+  end
+
+  def test_index_with_project
+    Setting.display_subprojects_issues = 0
+    get :index, :project_id => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+
+    assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
+    assert_select 'a[href=/issues/5]', 0
+  end
+
+  def test_index_with_project_and_subprojects
+    Setting.display_subprojects_issues = 1
+    get :index, :project_id => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+
+    assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
+    assert_select 'a[href=/issues/5]', :text => /Subproject issue/
+    assert_select 'a[href=/issues/6]', 0
+  end
+
+  def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
+    @request.session[:user_id] = 2
+    Setting.display_subprojects_issues = 1
+    get :index, :project_id => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+
+    assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
+    assert_select 'a[href=/issues/5]', :text => /Subproject issue/
+    assert_select 'a[href=/issues/6]', :text => /Issue of a private subproject/
+  end
+
+  def test_index_with_project_and_default_filter
+    get :index, :project_id => 1, :set_filter => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+
+    query = assigns(:query)
+    assert_not_nil query
+    # default filter
+    assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
+  end
+
+  def test_index_with_project_and_filter
+    get :index, :project_id => 1, :set_filter => 1,
+      :f => ['tracker_id'],
+      :op => {'tracker_id' => '='},
+      :v => {'tracker_id' => ['1']}
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+
+    query = assigns(:query)
+    assert_not_nil query
+    assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
+  end
+
+  def test_index_with_short_filters
+    to_test = {
+      'status_id' => {
+        'o' => { :op => 'o', :values => [''] },
+        'c' => { :op => 'c', :values => [''] },
+        '7' => { :op => '=', :values => ['7'] },
+        '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
+        '=7' => { :op => '=', :values => ['7'] },
+        '!3' => { :op => '!', :values => ['3'] },
+        '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
+      'subject' => {
+        'This is a subject' => { :op => '=', :values => ['This is a subject'] },
+        'o' => { :op => '=', :values => ['o'] },
+        '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
+        '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
+      'tracker_id' => {
+        '3' => { :op => '=', :values => ['3'] },
+        '=3' => { :op => '=', :values => ['3'] }},
+      'start_date' => {
+        '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
+        '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
+        '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
+        '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
+        '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
+        '<t+2' => { :op => '<t+', :values => ['2'] },
+        '>t+2' => { :op => '>t+', :values => ['2'] },
+        't+2' => { :op => 't+', :values => ['2'] },
+        't' => { :op => 't', :values => [''] },
+        'w' => { :op => 'w', :values => [''] },
+        '>t-2' => { :op => '>t-', :values => ['2'] },
+        '<t-2' => { :op => '<t-', :values => ['2'] },
+        't-2' => { :op => 't-', :values => ['2'] }},
+      'created_on' => {
+        '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
+        '<t-2' => { :op => '<t-', :values => ['2'] },
+        '>t-2' => { :op => '>t-', :values => ['2'] },
+        't-2' => { :op => 't-', :values => ['2'] }},
+      'cf_1' => {
+        'c' => { :op => '=', :values => ['c'] },
+        '!c' => { :op => '!', :values => ['c'] },
+        '!*' => { :op => '!*', :values => [''] },
+        '*' => { :op => '*', :values => [''] }},
+      'estimated_hours' => {
+        '=13.4' => { :op => '=', :values => ['13.4'] },
+        '>=45' => { :op => '>=', :values => ['45'] },
+        '<=125' => { :op => '<=', :values => ['125'] },
+        '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
+        '!*' => { :op => '!*', :values => [''] },
+        '*' => { :op => '*', :values => [''] }}
+    }
+
+    default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
+
+    to_test.each do |field, expression_and_expected|
+      expression_and_expected.each do |filter_expression, expected|
+
+        get :index, :set_filter => 1, field => filter_expression
+
+        assert_response :success
+        assert_template 'index'
+        assert_not_nil assigns(:issues)
+
+        query = assigns(:query)
+        assert_not_nil query
+        assert query.has_filter?(field)
+        assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
+      end
+    end
+  end
+
+  def test_index_with_project_and_empty_filters
+    get :index, :project_id => 1, :set_filter => 1, :fields => ['']
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+
+    query = assigns(:query)
+    assert_not_nil query
+    # no filter
+    assert_equal({}, query.filters)
+  end
+
+  def test_index_with_project_custom_field_filter
+    field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
+    CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
+    CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
+    filter_name = "project.cf_#{field.id}"
+    @request.session[:user_id] = 1
+
+    get :index, :set_filter => 1,
+      :f => [filter_name],
+      :op => {filter_name => '='},
+      :v => {filter_name => ['Foo']}
+    assert_response :success
+    assert_template 'index'
+    assert_equal [3, 5], assigns(:issues).map(&:project_id).uniq.sort
+  end
+
+  def test_index_with_query
+    get :index, :project_id => 1, :query_id => 5
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+    assert_nil assigns(:issue_count_by_group)
+  end
+
+  def test_index_with_query_grouped_by_tracker
+    get :index, :project_id => 1, :query_id => 6
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+    assert_not_nil assigns(:issue_count_by_group)
+  end
+
+  def test_index_with_query_grouped_by_list_custom_field
+    get :index, :project_id => 1, :query_id => 9
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues)
+    assert_not_nil assigns(:issue_count_by_group)
+  end
+
+  def test_index_with_query_grouped_by_user_custom_field
+    cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
+
+    get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
+    assert_response :success
+
+    assert_select 'tr.group', 3
+    assert_select 'tr.group' do
+      assert_select 'a', :text => 'John Smith'
+      assert_select 'span.count', :text => '1'
+    end
+    assert_select 'tr.group' do
+      assert_select 'a', :text => 'Dave Lopper'
+      assert_select 'span.count', :text => '2'
+    end
+  end
+
+  def test_index_with_query_grouped_by_tracker
+    3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
+
+    get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc'
+    assert_response :success
+
+    trackers = assigns(:issues).map(&:tracker).uniq
+    assert_equal [1, 2, 3], trackers.map(&:id)
+  end
+
+  def test_index_with_query_grouped_by_tracker_in_reverse_order
+    3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
+
+    get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc,tracker:desc'
+    assert_response :success
+
+    trackers = assigns(:issues).map(&:tracker).uniq
+    assert_equal [3, 2, 1], trackers.map(&:id)
+  end
+
+  def test_index_with_query_id_and_project_id_should_set_session_query
+    get :index, :project_id => 1, :query_id => 4
+    assert_response :success
+    assert_kind_of Hash, session[:query]
+    assert_equal 4, session[:query][:id]
+    assert_equal 1, session[:query][:project_id]
+  end
+
+  def test_index_with_invalid_query_id_should_respond_404
+    get :index, :project_id => 1, :query_id => 999
+    assert_response 404
+  end
+
+  def test_index_with_cross_project_query_in_session_should_show_project_issues
+    q = IssueQuery.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
+    @request.session[:query] = {:id => q.id, :project_id => 1}
+
+    with_settings :display_subprojects_issues => '0' do
+      get :index, :project_id => 1
+    end
+    assert_response :success
+    assert_not_nil assigns(:query)
+    assert_equal q.id, assigns(:query).id
+    assert_equal 1, assigns(:query).project_id
+    assert_equal [1], assigns(:issues).map(&:project_id).uniq
+  end
+
+  def test_private_query_should_not_be_available_to_other_users
+    q = IssueQuery.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
+    @request.session[:user_id] = 3
+
+    get :index, :query_id => q.id
+    assert_response 403
+  end
+
+  def test_private_query_should_be_available_to_its_user
+    q = IssueQuery.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
+    @request.session[:user_id] = 2
+
+    get :index, :query_id => q.id
+    assert_response :success
+  end
+
+  def test_public_query_should_be_available_to_other_users
+    q = IssueQuery.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
+    @request.session[:user_id] = 3
+
+    get :index, :query_id => q.id
+    assert_response :success
+  end
+
+  def test_index_should_omit_page_param_in_export_links
+    get :index, :page => 2
+    assert_response :success
+    assert_select 'a.atom[href=/issues.atom]'
+    assert_select 'a.csv[href=/issues.csv]'
+    assert_select 'a.pdf[href=/issues.pdf]'
+    assert_select 'form#csv-export-form[action=/issues.csv]'
+  end
+
+  def test_index_csv
+    get :index, :format => 'csv'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert_equal 'text/csv; header=present', @response.content_type
+    assert @response.body.starts_with?("#,")
+    lines = @response.body.chomp.split("\n")
+    assert_equal assigns(:query).columns.size, lines[0].split(',').size
+  end
+
+  def test_index_csv_with_project
+    get :index, :project_id => 1, :format => 'csv'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert_equal 'text/csv; header=present', @response.content_type
+  end
+
+  def test_index_csv_with_description
+    Issue.generate!(:description => 'test_index_csv_with_description')
+
+    with_settings :default_language => 'en' do
+      get :index, :format => 'csv', :description => '1'
+      assert_response :success
+      assert_not_nil assigns(:issues)
+    end
+
+    assert_equal 'text/csv; header=present', response.content_type
+    headers = response.body.chomp.split("\n").first.split(',')
+    assert_include 'Description', headers
+    assert_include 'test_index_csv_with_description', response.body
+  end
+
+  def test_index_csv_with_spent_time_column
+    issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
+    TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
+
+    get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
+    assert_response :success
+    assert_equal 'text/csv; header=present', @response.content_type
+    lines = @response.body.chomp.split("\n")
+    assert_include "#{issue.id},#{issue.subject},7.33", lines
+  end
+
+  def test_index_csv_with_all_columns
+    get :index, :format => 'csv', :columns => 'all'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert_equal 'text/csv; header=present', @response.content_type
+    assert_match /\A#,/, response.body
+    lines = response.body.chomp.split("\n")
+    assert_equal assigns(:query).available_inline_columns.size, lines[0].split(',').size
+  end
+
+  def test_index_csv_with_multi_column_field
+    CustomField.find(1).update_attribute :multiple, true
+    issue = Issue.find(1)
+    issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
+    issue.save!
+
+    get :index, :format => 'csv', :columns => 'all'
+    assert_response :success
+    lines = @response.body.chomp.split("\n")
+    assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
+  end
+
+  def test_index_csv_should_format_float_custom_fields_with_csv_decimal_separator
+    field = IssueCustomField.create!(:name => 'Float', :is_for_all => true, :tracker_ids => [1], :field_format => 'float')
+    issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id => '185.6'})
+
+    with_settings :default_language => 'fr' do
+      get :index, :format => 'csv', :columns => 'all'
+      assert_response :success
+      issue_line = response.body.chomp.split("\n").map {|line| line.split(';')}.detect {|line| line[0]==issue.id.to_s}
+      assert_include '185,60', issue_line
+    end
+
+    with_settings :default_language => 'en' do
+      get :index, :format => 'csv', :columns => 'all'
+      assert_response :success
+      issue_line = response.body.chomp.split("\n").map {|line| line.split(',')}.detect {|line| line[0]==issue.id.to_s}
+      assert_include '185.60', issue_line
+    end
+  end
+
+  def test_index_csv_big_5
+    with_settings :default_language => "zh-TW" do
+      str_utf8  = "\xe4\xb8\x80\xe6\x9c\x88"
+      str_big5  = "\xa4@\xa4\xeb"
+      if str_utf8.respond_to?(:force_encoding)
+        str_utf8.force_encoding('UTF-8')
+        str_big5.force_encoding('Big5')
+      end
+      issue = Issue.generate!(:subject => str_utf8)
+
+      get :index, :project_id => 1, 
+                  :f => ['subject'], 
+                  :op => '=', :values => [str_utf8],
+                  :format => 'csv'
+      assert_equal 'text/csv; header=present', @response.content_type
+      lines = @response.body.chomp.split("\n")
+      s1 = "\xaa\xac\xbaA"
+      if str_utf8.respond_to?(:force_encoding)
+        s1.force_encoding('Big5')
+      end
+      assert_include s1, lines[0]
+      assert_include str_big5, lines[1]
+    end
+  end
+
+  def test_index_csv_cannot_convert_should_be_replaced_big_5
+    with_settings :default_language => "zh-TW" do
+      str_utf8  = "\xe4\xbb\xa5\xe5\x86\x85"
+      if str_utf8.respond_to?(:force_encoding)
+        str_utf8.force_encoding('UTF-8')
+      end
+      issue = Issue.generate!(:subject => str_utf8)
+
+      get :index, :project_id => 1, 
+                  :f => ['subject'], 
+                  :op => '=', :values => [str_utf8],
+                  :c => ['status', 'subject'],
+                  :format => 'csv',
+                  :set_filter => 1
+      assert_equal 'text/csv; header=present', @response.content_type
+      lines = @response.body.chomp.split("\n")
+      s1 = "\xaa\xac\xbaA" # status
+      if str_utf8.respond_to?(:force_encoding)
+        s1.force_encoding('Big5')
+      end
+      assert lines[0].include?(s1)
+      s2 = lines[1].split(",")[2]
+      if s1.respond_to?(:force_encoding)
+        s3 = "\xa5H?" # subject
+        s3.force_encoding('Big5')
+        assert_equal s3, s2
+      elsif RUBY_PLATFORM == 'java'
+        assert_equal "??", s2
+      else
+        assert_equal "\xa5H???", s2
+      end
+    end
+  end
+
+  def test_index_csv_tw
+    with_settings :default_language => "zh-TW" do
+      str1  = "test_index_csv_tw"
+      issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
+
+      get :index, :project_id => 1, 
+                  :f => ['subject'], 
+                  :op => '=', :values => [str1],
+                  :c => ['estimated_hours', 'subject'],
+                  :format => 'csv',
+                  :set_filter => 1
+      assert_equal 'text/csv; header=present', @response.content_type
+      lines = @response.body.chomp.split("\n")
+      assert_equal "#{issue.id},1234.50,#{str1}", lines[1]
+    end
+  end
+
+  def test_index_csv_fr
+    with_settings :default_language => "fr" do
+      str1  = "test_index_csv_fr"
+      issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
+
+      get :index, :project_id => 1, 
+                  :f => ['subject'], 
+                  :op => '=', :values => [str1],
+                  :c => ['estimated_hours', 'subject'],
+                  :format => 'csv',
+                  :set_filter => 1
+      assert_equal 'text/csv; header=present', @response.content_type
+      lines = @response.body.chomp.split("\n")
+      assert_equal "#{issue.id};1234,50;#{str1}", lines[1]
+    end
+  end
+
+  def test_index_pdf
+    ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
+      with_settings :default_language => lang do
+
+        get :index
+        assert_response :success
+        assert_template 'index'
+
+        if lang == "ja"
+          if RUBY_PLATFORM != 'java'
+            assert_equal "CP932", l(:general_pdf_encoding)
+          end
+          if RUBY_PLATFORM == 'java' && l(:general_pdf_encoding) == "CP932"
+            next
+          end
+        end
+
+        get :index, :format => 'pdf'
+        assert_response :success
+        assert_not_nil assigns(:issues)
+        assert_equal 'application/pdf', @response.content_type
+
+        get :index, :project_id => 1, :format => 'pdf'
+        assert_response :success
+        assert_not_nil assigns(:issues)
+        assert_equal 'application/pdf', @response.content_type
+
+        get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
+        assert_response :success
+        assert_not_nil assigns(:issues)
+        assert_equal 'application/pdf', @response.content_type
+      end
+    end
+  end
+
+  def test_index_pdf_with_query_grouped_by_list_custom_field
+    get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert_not_nil assigns(:issue_count_by_group)
+    assert_equal 'application/pdf', @response.content_type
+  end
+
+  def test_index_atom
+    get :index, :project_id => 'ecookbook', :format => 'atom'
+    assert_response :success
+    assert_template 'common/feed'
+    assert_equal 'application/atom+xml', response.content_type
+
+    assert_select 'feed' do
+      assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
+      assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
+      assert_select 'entry link[href=?]', 'http://test.host/issues/1'
+    end
+  end
+
+  def test_index_sort
+    get :index, :sort => 'tracker,id:desc'
+    assert_response :success
+
+    sort_params = @request.session['issues_index_sort']
+    assert sort_params.is_a?(String)
+    assert_equal 'tracker,id:desc', sort_params
+
+    issues = assigns(:issues)
+    assert_not_nil issues
+    assert !issues.empty?
+    assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
+  end
+
+  def test_index_sort_by_field_not_included_in_columns
+    Setting.issue_list_default_columns = %w(subject author)
+    get :index, :sort => 'tracker'
+  end
+  
+  def test_index_sort_by_assigned_to
+    get :index, :sort => 'assigned_to'
+    assert_response :success
+    assignees = assigns(:issues).collect(&:assigned_to).compact
+    assert_equal assignees.sort, assignees
+  end
+  
+  def test_index_sort_by_assigned_to_desc
+    get :index, :sort => 'assigned_to:desc'
+    assert_response :success
+    assignees = assigns(:issues).collect(&:assigned_to).compact
+    assert_equal assignees.sort.reverse, assignees
+  end
+  
+  def test_index_group_by_assigned_to
+    get :index, :group_by => 'assigned_to', :sort => 'priority'
+    assert_response :success
+  end
+  
+  def test_index_sort_by_author
+    get :index, :sort => 'author'
+    assert_response :success
+    authors = assigns(:issues).collect(&:author)
+    assert_equal authors.sort, authors
+  end
+  
+  def test_index_sort_by_author_desc
+    get :index, :sort => 'author:desc'
+    assert_response :success
+    authors = assigns(:issues).collect(&:author)
+    assert_equal authors.sort.reverse, authors
+  end
+  
+  def test_index_group_by_author
+    get :index, :group_by => 'author', :sort => 'priority'
+    assert_response :success
+  end
+  
+  def test_index_sort_by_spent_hours
+    get :index, :sort => 'spent_hours:desc'
+    assert_response :success
+    hours = assigns(:issues).collect(&:spent_hours)
+    assert_equal hours.sort.reverse, hours
+  end
+
+  def test_index_sort_by_user_custom_field
+    cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
+
+    get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
+    assert_response :success
+
+    assert_equal [2, 3, 1], assigns(:issues).select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
+  end
+
+  def test_index_with_columns
+    columns = ['tracker', 'subject', 'assigned_to']
+    get :index, :set_filter => 1, :c => columns
+    assert_response :success
+
+    # query should use specified columns
+    query = assigns(:query)
+    assert_kind_of IssueQuery, query
+    assert_equal columns, query.column_names.map(&:to_s)
+
+    # columns should be stored in session
+    assert_kind_of Hash, session[:query]
+    assert_kind_of Array, session[:query][:column_names]
+    assert_equal columns, session[:query][:column_names].map(&:to_s)
+
+    # ensure only these columns are kept in the selected columns list
+    assert_select 'select#selected_columns option' do
+      assert_select 'option', 3
+      assert_select 'option[value=tracker]'
+      assert_select 'option[value=project]', 0
+    end
+  end
+
+  def test_index_without_project_should_implicitly_add_project_column_to_default_columns
+    Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
+    get :index, :set_filter => 1
+
+    # query should use specified columns
+    query = assigns(:query)
+    assert_kind_of IssueQuery, query
+    assert_equal [:id, :project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
+  end
+
+  def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
+    Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
+    columns = ['id', 'tracker', 'subject', 'assigned_to']
+    get :index, :set_filter => 1, :c => columns
+
+    # query should use specified columns
+    query = assigns(:query)
+    assert_kind_of IssueQuery, query
+    assert_equal columns.map(&:to_sym), query.columns.map(&:name)
+  end
+
+  def test_index_with_custom_field_column
+    columns = %w(tracker subject cf_2)
+    get :index, :set_filter => 1, :c => columns
+    assert_response :success
+
+    # query should use specified columns
+    query = assigns(:query)
+    assert_kind_of IssueQuery, query
+    assert_equal columns, query.column_names.map(&:to_s)
+
+    assert_select 'table.issues td.cf_2.string'
+  end
+
+  def test_index_with_multi_custom_field_column
+    field = CustomField.find(1)
+    field.update_attribute :multiple, true
+    issue = Issue.find(1)
+    issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
+    issue.save!
+
+    get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
+    assert_response :success
+
+    assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
+  end
+
+  def test_index_with_multi_user_custom_field_column
+    field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
+      :tracker_ids => [1], :is_for_all => true)
+    issue = Issue.find(1)
+    issue.custom_field_values = {field.id => ['2', '3']}
+    issue.save!
+
+    get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
+    assert_response :success
+
+    assert_select "table.issues td.cf_#{field.id}" do
+      assert_select 'a', 2
+      assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
+      assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
+    end
+  end
+
+  def test_index_with_date_column
+    with_settings :date_format => '%d/%m/%Y' do
+      Issue.find(1).update_attribute :start_date, '1987-08-24'
+
+      get :index, :set_filter => 1, :c => %w(start_date)
+
+      assert_select "table.issues td.start_date", :text => '24/08/1987'
+    end
+  end
+
+  def test_index_with_done_ratio_column
+    Issue.find(1).update_attribute :done_ratio, 40
+
+    get :index, :set_filter => 1, :c => %w(done_ratio)
+
+    assert_select 'table.issues td.done_ratio' do
+      assert_select 'table.progress' do
+        assert_select 'td.closed[style=?]', 'width: 40%;'
+      end
+    end
+  end
+
+  def test_index_with_spent_hours_column
+    get :index, :set_filter => 1, :c => %w(subject spent_hours)
+
+    assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
+  end
+
+  def test_index_should_not_show_spent_hours_column_without_permission
+    Role.anonymous.remove_permission! :view_time_entries
+    get :index, :set_filter => 1, :c => %w(subject spent_hours)
+
+    assert_select 'td.spent_hours', 0
+  end
+
+  def test_index_with_fixed_version_column
+    get :index, :set_filter => 1, :c => %w(fixed_version)
+
+    assert_select 'table.issues td.fixed_version' do
+      assert_select 'a[href=?]', '/versions/2', :text => '1.0'
+    end
+  end
+
+  def test_index_with_relations_column
+    IssueRelation.delete_all
+    IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
+    IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
+    IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
+    IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
+
+    get :index, :set_filter => 1, :c => %w(subject relations)
+    assert_response :success
+    assert_select "tr#issue-1 td.relations" do
+      assert_select "span", 3
+      assert_select "span", :text => "Related to #7"
+      assert_select "span", :text => "Related to #8"
+      assert_select "span", :text => "Blocks #11"
+    end
+    assert_select "tr#issue-2 td.relations" do
+      assert_select "span", 1
+      assert_select "span", :text => "Blocked by #12"
+    end
+    assert_select "tr#issue-3 td.relations" do
+      assert_select "span", 0
+    end
+
+    get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
+    assert_response :success
+    assert_equal 'text/csv; header=present', response.content_type
+    lines = response.body.chomp.split("\n")
+    assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
+    assert_include '2,Blocked by #12', lines
+    assert_include '3,""', lines
+
+    get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', response.content_type
+  end
+
+  def test_index_with_description_column
+    get :index, :set_filter => 1, :c => %w(subject description)
+
+    assert_select 'table.issues thead th', 3 # columns: chekbox + id + subject
+    assert_select 'td.description[colspan=3]', :text => 'Unable to print recipes'
+
+    get :index, :set_filter => 1, :c => %w(subject description), :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', response.content_type
+  end
+
+  def test_index_send_html_if_query_is_invalid
+    get :index, :f => ['start_date'], :op => {:start_date => '='}
+    assert_equal 'text/html', @response.content_type
+    assert_template 'index'
+  end
+
+  def test_index_send_nothing_if_query_is_invalid
+    get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
+    assert_equal 'text/csv', @response.content_type
+    assert @response.body.blank?
+  end
+
+  def test_show_by_anonymous
+    get :show, :id => 1
+    assert_response :success
+    assert_template 'show'
+    assert_equal Issue.find(1), assigns(:issue)
+
+    assert_select 'div.issue div.description', :text => /Unable to print recipes/
+
+    # anonymous role is allowed to add a note
+    assert_select 'form#issue-form' do
+      assert_select 'fieldset' do
+        assert_select 'legend', :text => 'Notes'
+        assert_select 'textarea[name=?]', 'issue[notes]'
+      end
+    end
+
+    assert_select 'title', :text => "Bug #1: Can&#x27;t print recipes - eCookbook - Redmine"
+  end
+
+  def test_show_by_manager
+    @request.session[:user_id] = 2
+    get :show, :id => 1
+    assert_response :success
+
+    assert_select 'a', :text => /Quote/
+
+    assert_select 'form#issue-form' do
+      assert_select 'fieldset' do
+        assert_select 'legend', :text => 'Change properties'
+        assert_select 'input[name=?]', 'issue[subject]'
+      end
+      assert_select 'fieldset' do
+        assert_select 'legend', :text => 'Log time'
+        assert_select 'input[name=?]', 'time_entry[hours]'
+      end
+      assert_select 'fieldset' do
+        assert_select 'legend', :text => 'Notes'
+        assert_select 'textarea[name=?]', 'issue[notes]'
+      end
+    end
+  end
+
+  def test_show_should_display_update_form
+    @request.session[:user_id] = 2
+    get :show, :id => 1
+    assert_response :success
+
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]'
+      assert_select 'select[name=?]', 'issue[project_id]'
+      assert_select 'select[name=?]', 'issue[tracker_id]'
+      assert_select 'input[name=?]', 'issue[subject]'
+      assert_select 'textarea[name=?]', 'issue[description]'
+      assert_select 'select[name=?]', 'issue[status_id]'
+      assert_select 'select[name=?]', 'issue[priority_id]'
+      assert_select 'select[name=?]', 'issue[assigned_to_id]'
+      assert_select 'select[name=?]', 'issue[category_id]'
+      assert_select 'select[name=?]', 'issue[fixed_version_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]'
+      assert_select 'input[name=?]', 'issue[start_date]'
+      assert_select 'input[name=?]', 'issue[due_date]'
+      assert_select 'select[name=?]', 'issue[done_ratio]'
+      assert_select 'input[name=?]', 'issue[custom_field_values][2]'
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
+      assert_select 'textarea[name=?]', 'issue[notes]'
+    end
+  end
+
+  def test_show_should_display_update_form_with_minimal_permissions
+    Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
+    WorkflowTransition.delete_all :role_id => 1
+
+    @request.session[:user_id] = 2
+    get :show, :id => 1
+    assert_response :success
+
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]', 0
+      assert_select 'select[name=?]', 'issue[project_id]', 0
+      assert_select 'select[name=?]', 'issue[tracker_id]', 0
+      assert_select 'input[name=?]', 'issue[subject]', 0
+      assert_select 'textarea[name=?]', 'issue[description]', 0
+      assert_select 'select[name=?]', 'issue[status_id]', 0
+      assert_select 'select[name=?]', 'issue[priority_id]', 0
+      assert_select 'select[name=?]', 'issue[assigned_to_id]', 0
+      assert_select 'select[name=?]', 'issue[category_id]', 0
+      assert_select 'select[name=?]', 'issue[fixed_version_id]', 0
+      assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
+      assert_select 'input[name=?]', 'issue[start_date]', 0
+      assert_select 'input[name=?]', 'issue[due_date]', 0
+      assert_select 'select[name=?]', 'issue[done_ratio]', 0
+      assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
+      assert_select 'textarea[name=?]', 'issue[notes]'
+    end
+  end
+
+  def test_show_should_display_update_form_with_workflow_permissions
+    Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
+
+    @request.session[:user_id] = 2
+    get :show, :id => 1
+    assert_response :success
+
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]', 0
+      assert_select 'select[name=?]', 'issue[project_id]', 0
+      assert_select 'select[name=?]', 'issue[tracker_id]', 0
+      assert_select 'input[name=?]', 'issue[subject]', 0
+      assert_select 'textarea[name=?]', 'issue[description]', 0
+      assert_select 'select[name=?]', 'issue[status_id]'
+      assert_select 'select[name=?]', 'issue[priority_id]', 0
+      assert_select 'select[name=?]', 'issue[assigned_to_id]'
+      assert_select 'select[name=?]', 'issue[category_id]', 0
+      assert_select 'select[name=?]', 'issue[fixed_version_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
+      assert_select 'input[name=?]', 'issue[start_date]', 0
+      assert_select 'input[name=?]', 'issue[due_date]', 0
+      assert_select 'select[name=?]', 'issue[done_ratio]'
+      assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
+      assert_select 'textarea[name=?]', 'issue[notes]'
+    end
+  end
+
+  def test_show_should_not_display_update_form_without_permissions
+    Role.find(1).update_attribute :permissions, [:view_issues]
+
+    @request.session[:user_id] = 2
+    get :show, :id => 1
+    assert_response :success
+
+    assert_select 'form#issue-form', 0
+  end
+
+  def test_update_form_should_not_display_inactive_enumerations
+    assert !IssuePriority.find(15).active?
+
+    @request.session[:user_id] = 2
+    get :show, :id => 1
+    assert_response :success
+
+    assert_select 'form#issue-form' do
+      assert_select 'select[name=?]', 'issue[priority_id]' do
+        assert_select 'option[value=4]'
+        assert_select 'option[value=15]', 0
+      end
+    end
+  end
+
+  def test_update_form_should_allow_attachment_upload
+    @request.session[:user_id] = 2
+    get :show, :id => 1
+
+    assert_select 'form#issue-form[method=post][enctype=multipart/form-data]' do
+      assert_select 'input[type=file][name=?]', 'attachments[dummy][file]'
+    end
+  end
+
+  def test_show_should_deny_anonymous_access_without_permission
+    Role.anonymous.remove_permission!(:view_issues)
+    get :show, :id => 1
+    assert_response :redirect
+  end
+
+  def test_show_should_deny_anonymous_access_to_private_issue
+    Issue.update_all(["is_private = ?", true], "id = 1")
+    get :show, :id => 1
+    assert_response :redirect
+  end
+
+  def test_show_should_deny_non_member_access_without_permission
+    Role.non_member.remove_permission!(:view_issues)
+    @request.session[:user_id] = 9
+    get :show, :id => 1
+    assert_response 403
+  end
+
+  def test_show_should_deny_non_member_access_to_private_issue
+    Issue.update_all(["is_private = ?", true], "id = 1")
+    @request.session[:user_id] = 9
+    get :show, :id => 1
+    assert_response 403
+  end
+
+  def test_show_should_deny_member_access_without_permission
+    Role.find(1).remove_permission!(:view_issues)
+    @request.session[:user_id] = 2
+    get :show, :id => 1
+    assert_response 403
+  end
+
+  def test_show_should_deny_member_access_to_private_issue_without_permission
+    Issue.update_all(["is_private = ?", true], "id = 1")
+    @request.session[:user_id] = 3
+    get :show, :id => 1
+    assert_response 403
+  end
+
+  def test_show_should_allow_author_access_to_private_issue
+    Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
+    @request.session[:user_id] = 3
+    get :show, :id => 1
+    assert_response :success
+  end
+
+  def test_show_should_allow_assignee_access_to_private_issue
+    Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
+    @request.session[:user_id] = 3
+    get :show, :id => 1
+    assert_response :success
+  end
+
+  def test_show_should_allow_member_access_to_private_issue_with_permission
+    Issue.update_all(["is_private = ?", true], "id = 1")
+    User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
+    @request.session[:user_id] = 3
+    get :show, :id => 1
+    assert_response :success
+  end
+
+  def test_show_should_not_disclose_relations_to_invisible_issues
+    Setting.cross_project_issue_relations = '1'
+    IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
+    # Relation to a private project issue
+    IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
+
+    get :show, :id => 1
+    assert_response :success
+
+    assert_select 'div#relations' do
+      assert_select 'a', :text => /#2$/
+      assert_select 'a', :text => /#4$/, :count => 0
+    end
+  end
+
+  def test_show_should_list_subtasks
+    Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
+
+    get :show, :id => 1
+    assert_response :success
+
+    assert_select 'div#issue_tree' do
+      assert_select 'td.subject', :text => /Child Issue/
+    end
+  end
+
+  def test_show_should_list_parents
+    issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
+
+    get :show, :id => issue.id
+    assert_response :success
+
+    assert_select 'div.subject' do
+      assert_select 'h3', 'Child Issue'
+      assert_select 'a[href=/issues/1]'
+    end
+  end
+
+  def test_show_should_not_display_prev_next_links_without_query_in_session
+    get :show, :id => 1
+    assert_response :success
+    assert_nil assigns(:prev_issue_id)
+    assert_nil assigns(:next_issue_id)
+
+    assert_select 'div.next-prev-links', 0
+  end
+
+  def test_show_should_display_prev_next_links_with_query_in_session
+    @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
+    @request.session['issues_index_sort'] = 'id'
+
+    with_settings :display_subprojects_issues => '0' do
+      get :show, :id => 3
+    end
+
+    assert_response :success
+    # Previous and next issues for all projects
+    assert_equal 2, assigns(:prev_issue_id)
+    assert_equal 5, assigns(:next_issue_id)
+
+    count = Issue.open.visible.count
+
+    assert_select 'div.next-prev-links' do
+      assert_select 'a[href=/issues/2]', :text => /Previous/
+      assert_select 'a[href=/issues/5]', :text => /Next/
+      assert_select 'span.position', :text => "3 of #{count}"
+    end
+  end
+
+  def test_show_should_display_prev_next_links_with_saved_query_in_session
+    query = IssueQuery.create!(:name => 'test', :is_public => true,  :user_id => 1,
+      :filters => {'status_id' => {:values => ['5'], :operator => '='}},
+      :sort_criteria => [['id', 'asc']])
+    @request.session[:query] = {:id => query.id, :project_id => nil}
+
+    get :show, :id => 11
+
+    assert_response :success
+    assert_equal query, assigns(:query)
+    # Previous and next issues for all projects
+    assert_equal 8, assigns(:prev_issue_id)
+    assert_equal 12, assigns(:next_issue_id)
+
+    assert_select 'div.next-prev-links' do
+      assert_select 'a[href=/issues/8]', :text => /Previous/
+      assert_select 'a[href=/issues/12]', :text => /Next/
+    end
+  end
+
+  def test_show_should_display_prev_next_links_with_query_and_sort_on_association
+    @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
+    
+    %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
+      @request.session['issues_index_sort'] = assoc_sort
+
+      get :show, :id => 3
+      assert_response :success, "Wrong response status for #{assoc_sort} sort"
+
+      assert_select 'div.next-prev-links' do
+        assert_select 'a', :text => /(Previous|Next)/
+      end
+    end
+  end
+
+  def test_show_should_display_prev_next_links_with_project_query_in_session
+    @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
+    @request.session['issues_index_sort'] = 'id'
+
+    with_settings :display_subprojects_issues => '0' do
+      get :show, :id => 3
+    end
+
+    assert_response :success
+    # Previous and next issues inside project
+    assert_equal 2, assigns(:prev_issue_id)
+    assert_equal 7, assigns(:next_issue_id)
+
+    assert_select 'div.next-prev-links' do
+      assert_select 'a[href=/issues/2]', :text => /Previous/
+      assert_select 'a[href=/issues/7]', :text => /Next/
+    end
+  end
+
+  def test_show_should_not_display_prev_link_for_first_issue
+    @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
+    @request.session['issues_index_sort'] = 'id'
+
+    with_settings :display_subprojects_issues => '0' do
+      get :show, :id => 1
+    end
+
+    assert_response :success
+    assert_nil assigns(:prev_issue_id)
+    assert_equal 2, assigns(:next_issue_id)
+
+    assert_select 'div.next-prev-links' do
+      assert_select 'a', :text => /Previous/, :count => 0
+      assert_select 'a[href=/issues/2]', :text => /Next/
+    end
+  end
+
+  def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
+    @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
+    @request.session['issues_index_sort'] = 'id'
+
+    get :show, :id => 1
+
+    assert_response :success
+    assert_nil assigns(:prev_issue_id)
+    assert_nil assigns(:next_issue_id)
+
+    assert_select 'a', :text => /Previous/, :count => 0
+    assert_select 'a', :text => /Next/, :count => 0
+  end
+
+  def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
+    cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
+    CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
+
+    query = IssueQuery.create!(:name => 'test', :is_public => true,  :user_id => 1, :filters => {},
+      :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
+    @request.session[:query] = {:id => query.id, :project_id => nil}
+
+    get :show, :id => 3
+    assert_response :success
+
+    assert_equal 2, assigns(:prev_issue_id)
+    assert_equal 1, assigns(:next_issue_id)
+
+    assert_select 'div.next-prev-links' do
+      assert_select 'a[href=/issues/2]', :text => /Previous/
+      assert_select 'a[href=/issues/1]', :text => /Next/
+    end
+  end
+
+  def test_show_should_display_link_to_the_assignee
+    get :show, :id => 2
+    assert_response :success
+    assert_select '.assigned-to' do
+      assert_select 'a[href=/users/3]'
+    end
+  end
+
+  def test_show_should_display_visible_changesets_from_other_projects
+    project = Project.find(2)
+    issue = project.issues.first
+    issue.changeset_ids = [102]
+    issue.save!
+    # changesets from other projects should be displayed even if repository
+    # is disabled on issue's project
+    project.disable_module! :repository
+
+    @request.session[:user_id] = 2
+    get :show, :id => issue.id
+
+    assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
+  end
+
+  def test_show_should_display_watchers
+    @request.session[:user_id] = 2
+    Issue.find(1).add_watcher User.find(2)
+
+    get :show, :id => 1
+    assert_select 'div#watchers ul' do
+      assert_select 'li' do
+        assert_select 'a[href=/users/2]'
+        assert_select 'a img[alt=Delete]'
+      end
+    end
+  end
+
+  def test_show_should_display_watchers_with_gravatars
+    @request.session[:user_id] = 2
+    Issue.find(1).add_watcher User.find(2)
+
+    with_settings :gravatar_enabled => '1' do
+      get :show, :id => 1
+    end
+
+    assert_select 'div#watchers ul' do
+      assert_select 'li' do
+        assert_select 'img.gravatar'
+        assert_select 'a[href=/users/2]'
+        assert_select 'a img[alt=Delete]'
+      end
+    end
+  end
+
+  def test_show_with_thumbnails_enabled_should_display_thumbnails
+    @request.session[:user_id] = 2
+
+    with_settings :thumbnails_enabled => '1' do
+      get :show, :id => 14
+      assert_response :success
+    end
+
+    assert_select 'div.thumbnails' do
+      assert_select 'a[href=/attachments/16/testfile.png]' do
+        assert_select 'img[src=/attachments/thumbnail/16]'
+      end
+    end
+  end
+
+  def test_show_with_thumbnails_disabled_should_not_display_thumbnails
+    @request.session[:user_id] = 2
+
+    with_settings :thumbnails_enabled => '0' do
+      get :show, :id => 14
+      assert_response :success
+    end
+
+    assert_select 'div.thumbnails', 0
+  end
+
+  def test_show_with_multi_custom_field
+    field = CustomField.find(1)
+    field.update_attribute :multiple, true
+    issue = Issue.find(1)
+    issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
+    issue.save!
+
+    get :show, :id => 1
+    assert_response :success
+
+    assert_select 'td', :text => 'MySQL, Oracle'
+  end
+
+  def test_show_with_multi_user_custom_field
+    field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
+      :tracker_ids => [1], :is_for_all => true)
+    issue = Issue.find(1)
+    issue.custom_field_values = {field.id => ['2', '3']}
+    issue.save!
+
+    get :show, :id => 1
+    assert_response :success
+
+    # TODO: should display links
+    assert_select 'td', :text => 'Dave Lopper, John Smith'
+  end
+
+  def test_show_should_display_private_notes_with_permission_only
+    journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
+    @request.session[:user_id] = 2
+
+    get :show, :id => 2
+    assert_response :success
+    assert_include journal, assigns(:journals)
+
+    Role.find(1).remove_permission! :view_private_notes
+    get :show, :id => 2
+    assert_response :success
+    assert_not_include journal, assigns(:journals)
+  end
+
+  def test_show_atom
+    get :show, :id => 2, :format => 'atom'
+    assert_response :success
+    assert_template 'journals/index'
+    # Inline image
+    assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
+  end
+
+  def test_show_export_to_pdf
+    get :show, :id => 3, :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', @response.content_type
+    assert @response.body.starts_with?('%PDF')
+    assert_not_nil assigns(:issue)
+  end
+
+  def test_show_export_to_pdf_with_ancestors
+    issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
+
+    get :show, :id => issue.id, :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', @response.content_type
+    assert @response.body.starts_with?('%PDF')
+  end
+
+  def test_show_export_to_pdf_with_descendants
+    c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
+    c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
+    c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
+
+    get :show, :id => 1, :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', @response.content_type
+    assert @response.body.starts_with?('%PDF')
+  end
+
+  def test_show_export_to_pdf_with_journals
+    get :show, :id => 1, :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', @response.content_type
+    assert @response.body.starts_with?('%PDF')
+  end
+
+  def test_show_export_to_pdf_with_changesets
+    Issue.find(3).changesets = Changeset.find_all_by_id(100, 101, 102)
+
+    get :show, :id => 3, :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', @response.content_type
+    assert @response.body.starts_with?('%PDF')
+  end
+
+  def test_show_invalid_should_respond_with_404
+    get :show, :id => 999
+    assert_response 404
+  end
+
+  def test_get_new
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]'
+      assert_select 'select[name=?]', 'issue[project_id]', 0
+      assert_select 'select[name=?]', 'issue[tracker_id]'
+      assert_select 'input[name=?]', 'issue[subject]'
+      assert_select 'textarea[name=?]', 'issue[description]'
+      assert_select 'select[name=?]', 'issue[status_id]'
+      assert_select 'select[name=?]', 'issue[priority_id]'
+      assert_select 'select[name=?]', 'issue[assigned_to_id]'
+      assert_select 'select[name=?]', 'issue[category_id]'
+      assert_select 'select[name=?]', 'issue[fixed_version_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]'
+      assert_select 'input[name=?]', 'issue[start_date]'
+      assert_select 'input[name=?]', 'issue[due_date]'
+      assert_select 'select[name=?]', 'issue[done_ratio]'
+      assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]'
+    end
+
+    # Be sure we don't display inactive IssuePriorities
+    assert ! IssuePriority.find(15).active?
+    assert_select 'select[name=?]', 'issue[priority_id]' do
+      assert_select 'option[value=15]', 0
+    end
+  end
+
+  def test_get_new_with_minimal_permissions
+    Role.find(1).update_attribute :permissions, [:add_issues]
+    WorkflowTransition.delete_all :role_id => 1
+
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]', 0
+      assert_select 'select[name=?]', 'issue[project_id]', 0
+      assert_select 'select[name=?]', 'issue[tracker_id]'
+      assert_select 'input[name=?]', 'issue[subject]'
+      assert_select 'textarea[name=?]', 'issue[description]'
+      assert_select 'select[name=?]', 'issue[status_id]'
+      assert_select 'select[name=?]', 'issue[priority_id]'
+      assert_select 'select[name=?]', 'issue[assigned_to_id]'
+      assert_select 'select[name=?]', 'issue[category_id]'
+      assert_select 'select[name=?]', 'issue[fixed_version_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
+      assert_select 'input[name=?]', 'issue[start_date]'
+      assert_select 'input[name=?]', 'issue[due_date]'
+      assert_select 'select[name=?]', 'issue[done_ratio]'
+      assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
+    end
+  end
+
+  def test_get_new_with_list_custom_field
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
+      assert_select 'option', 4
+      assert_select 'option[value=MySQL]', :text => 'MySQL'
+    end
+  end
+
+  def test_get_new_with_multi_custom_field
+    field = IssueCustomField.find(1)
+    field.update_attribute :multiple, true
+
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
+      assert_select 'option', 3
+      assert_select 'option[value=MySQL]', :text => 'MySQL'
+    end
+    assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
+  end
+
+  def test_get_new_with_multi_user_custom_field
+    field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
+      :tracker_ids => [1], :is_for_all => true)
+
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
+      assert_select 'option', Project.find(1).users.count
+      assert_select 'option[value=2]', :text => 'John Smith'
+    end
+    assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
+  end
+
+  def test_get_new_with_date_custom_field
+    field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
+
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+    assert_response :success
+
+    assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
+  end
+
+  def test_get_new_with_text_custom_field
+    field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
+
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+    assert_response :success
+
+    assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
+  end
+
+  def test_get_new_without_default_start_date_is_creation_date
+    Setting.default_issue_start_date_to_creation_date = 0
+
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'input[name=?]', 'issue[start_date]'
+    assert_select 'input[name=?][value]', 'issue[start_date]', 0
+  end
+
+  def test_get_new_with_default_start_date_is_creation_date
+    Setting.default_issue_start_date_to_creation_date = 1
+
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'input[name=?][value=?]', 'issue[start_date]', Date.today.to_s
+  end
+
+  def test_get_new_form_should_allow_attachment_upload
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :tracker_id => 1
+
+    assert_select 'form[id=issue-form][method=post][enctype=multipart/form-data]' do
+      assert_select 'input[name=?][type=file]', 'attachments[dummy][file]'
+    end
+  end
+
+  def test_get_new_should_prefill_the_form_from_params
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1,
+      :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
+
+    issue = assigns(:issue)
+    assert_equal 3, issue.tracker_id
+    assert_equal 'Prefilled', issue.description
+    assert_equal 'Custom field value', issue.custom_field_value(2)
+
+    assert_select 'select[name=?]', 'issue[tracker_id]' do
+      assert_select 'option[value=3][selected=selected]'
+    end
+    assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
+    assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
+  end
+
+  def test_get_new_should_mark_required_fields
+    cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
+    cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
+    @request.session[:user_id] = 2
+
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'label[for=issue_start_date]' do
+      assert_select 'span[class=required]', 0
+    end
+    assert_select 'label[for=issue_due_date]' do
+      assert_select 'span[class=required]'
+    end
+    assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
+      assert_select 'span[class=required]', 0
+    end
+    assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
+      assert_select 'span[class=required]'
+    end
+  end
+
+  def test_get_new_should_not_display_readonly_fields
+    cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
+    cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
+    @request.session[:user_id] = 2
+
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'input[name=?]', 'issue[start_date]'
+    assert_select 'input[name=?]', 'issue[due_date]', 0
+    assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
+    assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
+  end
+
+  def test_get_new_without_tracker_id
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    issue = assigns(:issue)
+    assert_not_nil issue
+    assert_equal Project.find(1).trackers.first, issue.tracker
+  end
+
+  def test_get_new_with_no_default_status_should_display_an_error
+    @request.session[:user_id] = 2
+    IssueStatus.delete_all
+
+    get :new, :project_id => 1
+    assert_response 500
+    assert_error_tag :content => /No default issue/
+  end
+
+  def test_get_new_with_no_tracker_should_display_an_error
+    @request.session[:user_id] = 2
+    Tracker.delete_all
+
+    get :new, :project_id => 1
+    assert_response 500
+    assert_error_tag :content => /No tracker/
+  end
+
+  def test_update_form_for_new_issue
+    @request.session[:user_id] = 2
+    xhr :post, :update_form, :project_id => 1,
+                     :issue => {:tracker_id => 2,
+                                :subject => 'This is the test_new issue',
+                                :description => 'This is the description',
+                                :priority_id => 5}
+    assert_response :success
+    assert_template 'update_form'
+    assert_template 'form'
+    assert_equal 'text/javascript', response.content_type
+
+    issue = assigns(:issue)
+    assert_kind_of Issue, issue
+    assert_equal 1, issue.project_id
+    assert_equal 2, issue.tracker_id
+    assert_equal 'This is the test_new issue', issue.subject
+  end
+
+  def test_update_form_for_new_issue_should_propose_transitions_based_on_initial_status
+    @request.session[:user_id] = 2
+    WorkflowTransition.delete_all
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
+
+    xhr :post, :update_form, :project_id => 1,
+                     :issue => {:tracker_id => 1,
+                                :status_id => 5,
+                                :subject => 'This is an issue'}
+
+    assert_equal 5, assigns(:issue).status_id
+    assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
+  end
+
+  def test_post_create
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 3,
+                            :status_id => 2,
+                            :subject => 'This is the test_new issue',
+                            :description => 'This is the description',
+                            :priority_id => 5,
+                            :start_date => '2010-11-07',
+                            :estimated_hours => '',
+                            :custom_field_values => {'2' => 'Value for field 2'}}
+    end
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
+
+    issue = Issue.find_by_subject('This is the test_new issue')
+    assert_not_nil issue
+    assert_equal 2, issue.author_id
+    assert_equal 3, issue.tracker_id
+    assert_equal 2, issue.status_id
+    assert_equal Date.parse('2010-11-07'), issue.start_date
+    assert_nil issue.estimated_hours
+    v = issue.custom_values.where(:custom_field_id => 2).first
+    assert_not_nil v
+    assert_equal 'Value for field 2', v.value
+  end
+
+  def test_post_new_with_group_assignment
+    group = Group.find(11)
+    project = Project.find(1)
+    project.members << Member.new(:principal => group, :roles => [Role.givable.first])
+
+    with_settings :issue_group_assignment => '1' do
+      @request.session[:user_id] = 2
+      assert_difference 'Issue.count' do
+        post :create, :project_id => project.id,
+                      :issue => {:tracker_id => 3,
+                                 :status_id => 1,
+                                 :subject => 'This is the test_new_with_group_assignment issue',
+                                 :assigned_to_id => group.id}
+      end
+    end
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
+
+    issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
+    assert_not_nil issue
+    assert_equal group, issue.assigned_to
+  end
+
+  def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
+    Setting.default_issue_start_date_to_creation_date = 0
+
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 3,
+                            :status_id => 2,
+                            :subject => 'This is the test_new issue',
+                            :description => 'This is the description',
+                            :priority_id => 5,
+                            :estimated_hours => '',
+                            :custom_field_values => {'2' => 'Value for field 2'}}
+    end
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
+
+    issue = Issue.find_by_subject('This is the test_new issue')
+    assert_not_nil issue
+    assert_nil issue.start_date
+  end
+
+  def test_post_create_without_start_date_and_default_start_date_is_creation_date
+    Setting.default_issue_start_date_to_creation_date = 1
+
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 3,
+                            :status_id => 2,
+                            :subject => 'This is the test_new issue',
+                            :description => 'This is the description',
+                            :priority_id => 5,
+                            :estimated_hours => '',
+                            :custom_field_values => {'2' => 'Value for field 2'}}
+    end
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
+
+    issue = Issue.find_by_subject('This is the test_new issue')
+    assert_not_nil issue
+    assert_equal Date.today, issue.start_date
+  end
+
+  def test_post_create_and_continue
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+        :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
+        :continue => ''
+    end
+
+    issue = Issue.first(:order => 'id DESC')
+    assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
+    assert_not_nil flash[:notice], "flash was not set"
+    assert_include %|<a href="/issues/#{issue.id}" title="This is first issue">##{issue.id}</a>|, flash[:notice], "issue link not found in the flash message"
+  end
+
+  def test_post_create_without_custom_fields_param
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is the test_new issue',
+                            :description => 'This is the description',
+                            :priority_id => 5}
+    end
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
+  end
+
+  def test_post_create_with_multi_custom_field
+    field = IssueCustomField.find_by_name('Database')
+    field.update_attribute(:multiple, true)
+
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is the test_new issue',
+                            :description => 'This is the description',
+                            :priority_id => 5,
+                            :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
+    end
+    assert_response 302
+    issue = Issue.first(:order => 'id DESC')
+    assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
+  end
+
+  def test_post_create_with_empty_multi_custom_field
+    field = IssueCustomField.find_by_name('Database')
+    field.update_attribute(:multiple, true)
+
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is the test_new issue',
+                            :description => 'This is the description',
+                            :priority_id => 5,
+                            :custom_field_values => {'1' => ['']}}
+    end
+    assert_response 302
+    issue = Issue.first(:order => 'id DESC')
+    assert_equal [''], issue.custom_field_value(1).sort
+  end
+
+  def test_post_create_with_multi_user_custom_field
+    field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
+      :tracker_ids => [1], :is_for_all => true)
+
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is the test_new issue',
+                            :description => 'This is the description',
+                            :priority_id => 5,
+                            :custom_field_values => {field.id.to_s => ['', '2', '3']}}
+    end
+    assert_response 302
+    issue = Issue.first(:order => 'id DESC')
+    assert_equal ['2', '3'], issue.custom_field_value(field).sort
+  end
+
+  def test_post_create_with_required_custom_field_and_without_custom_fields_param
+    field = IssueCustomField.find_by_name('Database')
+    field.update_attribute(:is_required, true)
+
+    @request.session[:user_id] = 2
+    assert_no_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is the test_new issue',
+                            :description => 'This is the description',
+                            :priority_id => 5}
+    end
+    assert_response :success
+    assert_template 'new'
+    issue = assigns(:issue)
+    assert_not_nil issue
+    assert_error_tag :content => /Database can&#x27;t be blank/
+  end
+
+  def test_create_should_validate_required_fields
+    cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
+    cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Issue.count' do
+      post :create, :project_id => 1, :issue => {
+        :tracker_id => 2,
+        :status_id => 1,
+        :subject => 'Test',
+        :start_date => '',
+        :due_date => '',
+        :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
+      }
+      assert_response :success
+      assert_template 'new'
+    end
+
+    assert_error_tag :content => /Due date can&#x27;t be blank/i
+    assert_error_tag :content => /Bar can&#x27;t be blank/i
+  end
+
+  def test_create_should_ignore_readonly_fields
+    cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
+    cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1, :issue => {
+        :tracker_id => 2,
+        :status_id => 1,
+        :subject => 'Test',
+        :start_date => '2012-07-14',
+        :due_date => '2012-07-16',
+        :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
+      }
+      assert_response 302
+    end
+
+    issue = Issue.first(:order => 'id DESC')
+    assert_equal Date.parse('2012-07-14'), issue.start_date
+    assert_nil issue.due_date
+    assert_equal 'value1', issue.custom_field_value(cf1)
+    assert_nil issue.custom_field_value(cf2)
+  end
+
+  def test_post_create_with_watchers
+    @request.session[:user_id] = 2
+    ActionMailer::Base.deliveries.clear
+
+    assert_difference 'Watcher.count', 2 do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is a new issue with watchers',
+                            :description => 'This is the description',
+                            :priority_id => 5,
+                            :watcher_user_ids => ['2', '3']}
+    end
+    issue = Issue.find_by_subject('This is a new issue with watchers')
+    assert_not_nil issue
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
+
+    # Watchers added
+    assert_equal [2, 3], issue.watcher_user_ids.sort
+    assert issue.watched_by?(User.find(3))
+    # Watchers notified
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
+  end
+
+  def test_post_create_subissue
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is a child issue',
+                            :parent_issue_id => '2'}
+      assert_response 302
+    end
+    issue = Issue.order('id DESC').first
+    assert_equal Issue.find(2), issue.parent
+  end
+
+  def test_post_create_subissue_with_sharp_parent_id
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is a child issue',
+                            :parent_issue_id => '#2'}
+      assert_response 302
+    end
+    issue = Issue.order('id DESC').first
+    assert_equal Issue.find(2), issue.parent
+  end
+
+  def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is a child issue',
+                            :parent_issue_id => '4'}
+
+      assert_response :success
+      assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
+      assert_error_tag :content => /Parent task is invalid/i
+    end
+  end
+
+  def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is a child issue',
+                            :parent_issue_id => '01ABC'}
+
+      assert_response :success
+      assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
+      assert_error_tag :content => /Parent task is invalid/i
+    end
+  end
+
+  def test_post_create_private
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is a private issue',
+                            :is_private => '1'}
+    end
+    issue = Issue.first(:order => 'id DESC')
+    assert issue.is_private?
+  end
+
+  def test_post_create_private_with_set_own_issues_private_permission
+    role = Role.find(1)
+    role.remove_permission! :set_issues_private
+    role.add_permission! :set_own_issues_private
+
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 1,
+                            :subject => 'This is a private issue',
+                            :is_private => '1'}
+    end
+    issue = Issue.first(:order => 'id DESC')
+    assert issue.is_private?
+  end
+
+  def test_post_create_should_send_a_notification
+    ActionMailer::Base.deliveries.clear
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1,
+                 :issue => {:tracker_id => 3,
+                            :subject => 'This is the test_new issue',
+                            :description => 'This is the description',
+                            :priority_id => 5,
+                            :estimated_hours => '',
+                            :custom_field_values => {'2' => 'Value for field 2'}}
+    end
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
+
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_post_create_should_preserve_fields_values_on_validation_failure
+    @request.session[:user_id] = 2
+    post :create, :project_id => 1,
+               :issue => {:tracker_id => 1,
+                          # empty subject
+                          :subject => '',
+                          :description => 'This is a description',
+                          :priority_id => 6,
+                          :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'textarea[name=?]', 'issue[description]', :text => 'This is a description'
+    assert_select 'select[name=?]', 'issue[priority_id]' do
+      assert_select 'option[value=6][selected=selected]', :text => 'High'
+    end
+    # Custom fields
+    assert_select 'select[name=?]', 'issue[custom_field_values][1]' do
+      assert_select 'option[value=Oracle][selected=selected]', :text => 'Oracle'
+    end
+    assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Value for field 2'
+  end
+
+  def test_post_create_with_failure_should_preserve_watchers
+    assert !User.find(8).member_of?(Project.find(1))
+
+    @request.session[:user_id] = 2
+    post :create, :project_id => 1,
+         :issue => {:tracker_id => 1,
+                    :watcher_user_ids => ['3', '8']}
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'input[name=?][value=2]:not(checked)', 'issue[watcher_user_ids][]'
+    assert_select 'input[name=?][value=3][checked=checked]', 'issue[watcher_user_ids][]'
+    assert_select 'input[name=?][value=8][checked=checked]', 'issue[watcher_user_ids][]'
+  end
+
+  def test_post_create_should_ignore_non_safe_attributes
+    @request.session[:user_id] = 2
+    assert_nothing_raised do
+      post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
+    end
+  end
+
+  def test_post_create_with_attachment
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count' do
+      assert_difference 'Attachment.count' do
+        post :create, :project_id => 1,
+          :issue => { :tracker_id => '1', :subject => 'With attachment' },
+          :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
+      end
+    end
+
+    issue = Issue.first(:order => 'id DESC')
+    attachment = Attachment.first(:order => 'id DESC')
+
+    assert_equal issue, attachment.container
+    assert_equal 2, attachment.author_id
+    assert_equal 'testfile.txt', attachment.filename
+    assert_equal 'text/plain', attachment.content_type
+    assert_equal 'test file', attachment.description
+    assert_equal 59, attachment.filesize
+    assert File.exists?(attachment.diskfile)
+    assert_equal 59, File.size(attachment.diskfile)
+  end
+
+  def test_post_create_with_failure_should_save_attachments
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Issue.count' do
+      assert_difference 'Attachment.count' do
+        post :create, :project_id => 1,
+          :issue => { :tracker_id => '1', :subject => '' },
+          :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
+        assert_response :success
+        assert_template 'new'
+      end
+    end
+
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal 'testfile.txt', attachment.filename
+    assert File.exists?(attachment.diskfile)
+    assert_nil attachment.container
+
+    assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
+  end
+
+  def test_post_create_with_failure_should_keep_saved_attachments
+    set_tmp_attachments_directory
+    attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Issue.count' do
+      assert_no_difference 'Attachment.count' do
+        post :create, :project_id => 1,
+          :issue => { :tracker_id => '1', :subject => '' },
+          :attachments => {'p0' => {'token' => attachment.token}}
+        assert_response :success
+        assert_template 'new'
+      end
+    end
+
+    assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
+  end
+
+  def test_post_create_should_attach_saved_attachments
+    set_tmp_attachments_directory
+    attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count' do
+      assert_no_difference 'Attachment.count' do
+        post :create, :project_id => 1,
+          :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
+          :attachments => {'p0' => {'token' => attachment.token}}
+        assert_response 302
+      end
+    end
+
+    issue = Issue.first(:order => 'id DESC')
+    assert_equal 1, issue.attachments.count
+
+    attachment.reload
+    assert_equal issue, attachment.container
+  end
+
+  context "without workflow privilege" do
+    setup do
+      WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
+      Role.anonymous.add_permission! :add_issues, :add_issue_notes
+    end
+
+    context "#new" do
+      should "propose default status only" do
+        get :new, :project_id => 1
+        assert_response :success
+        assert_template 'new'
+        assert_select 'select[name=?]', 'issue[status_id]' do
+          assert_select 'option', 1
+          assert_select 'option[value=?]', IssueStatus.default.id.to_s
+        end
+      end
+
+      should "accept default status" do
+        assert_difference 'Issue.count' do
+          post :create, :project_id => 1,
+                     :issue => {:tracker_id => 1,
+                                :subject => 'This is an issue',
+                                :status_id => 1}
+        end
+        issue = Issue.last(:order => 'id')
+        assert_equal IssueStatus.default, issue.status
+      end
+
+      should "ignore unauthorized status" do
+        assert_difference 'Issue.count' do
+          post :create, :project_id => 1,
+                     :issue => {:tracker_id => 1,
+                                :subject => 'This is an issue',
+                                :status_id => 3}
+        end
+        issue = Issue.last(:order => 'id')
+        assert_equal IssueStatus.default, issue.status
+      end
+    end
+
+    context "#update" do
+      should "ignore status change" do
+        assert_difference 'Journal.count' do
+          put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
+        end
+        assert_equal 1, Issue.find(1).status_id
+      end
+
+      should "ignore attributes changes" do
+        assert_difference 'Journal.count' do
+          put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
+        end
+        issue = Issue.find(1)
+        assert_equal "Can't print recipes", issue.subject
+        assert_nil issue.assigned_to
+      end
+    end
+  end
+
+  context "with workflow privilege" do
+    setup do
+      WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
+      WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
+      WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
+      Role.anonymous.add_permission! :add_issues, :add_issue_notes
+    end
+
+    context "#update" do
+      should "accept authorized status" do
+        assert_difference 'Journal.count' do
+          put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
+        end
+        assert_equal 3, Issue.find(1).status_id
+      end
+
+      should "ignore unauthorized status" do
+        assert_difference 'Journal.count' do
+          put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
+        end
+        assert_equal 1, Issue.find(1).status_id
+      end
+
+      should "accept authorized attributes changes" do
+        assert_difference 'Journal.count' do
+          put :update, :id => 1, :issue => {:assigned_to_id => 2, :notes => 'just trying'}
+        end
+        issue = Issue.find(1)
+        assert_equal 2, issue.assigned_to_id
+      end
+
+      should "ignore unauthorized attributes changes" do
+        assert_difference 'Journal.count' do
+          put :update, :id => 1, :issue => {:subject => 'changed', :notes => 'just trying'}
+        end
+        issue = Issue.find(1)
+        assert_equal "Can't print recipes", issue.subject
+      end
+    end
+
+    context "and :edit_issues permission" do
+      setup do
+        Role.anonymous.add_permission! :add_issues, :edit_issues
+      end
+
+      should "accept authorized status" do
+        assert_difference 'Journal.count' do
+          put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
+        end
+        assert_equal 3, Issue.find(1).status_id
+      end
+
+      should "ignore unauthorized status" do
+        assert_difference 'Journal.count' do
+          put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
+        end
+        assert_equal 1, Issue.find(1).status_id
+      end
+
+      should "accept authorized attributes changes" do
+        assert_difference 'Journal.count' do
+          put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
+        end
+        issue = Issue.find(1)
+        assert_equal "changed", issue.subject
+        assert_equal 2, issue.assigned_to_id
+      end
+    end
+  end
+
+  def test_new_as_copy
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :copy_from => 1
+
+    assert_response :success
+    assert_template 'new'
+
+    assert_not_nil assigns(:issue)
+    orig = Issue.find(1)
+    assert_equal 1, assigns(:issue).project_id
+    assert_equal orig.subject, assigns(:issue).subject
+    assert assigns(:issue).copy?
+
+    assert_select 'form[id=issue-form][action=/projects/ecookbook/issues]' do
+      assert_select 'select[name=?]', 'issue[project_id]' do
+        assert_select 'option[value=1][selected=selected]', :text => 'eCookbook'
+        assert_select 'option[value=2]:not([selected])', :text => 'OnlineStore'
+      end
+      assert_select 'input[name=copy_from][value=1]'
+    end
+
+    # "New issue" menu item should not link to copy
+    assert_select '#main-menu a.new-issue[href=/projects/ecookbook/issues/new]'
+  end
+
+  def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
+    @request.session[:user_id] = 2
+    issue = Issue.find(3)
+    assert issue.attachments.count > 0
+    get :new, :project_id => 1, :copy_from => 3
+
+    assert_select 'input[name=copy_attachments][type=checkbox][checked=checked][value=1]'
+  end
+
+  def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
+    @request.session[:user_id] = 2
+    issue = Issue.find(3)
+    issue.attachments.delete_all
+    get :new, :project_id => 1, :copy_from => 3
+
+    assert_select 'input[name=copy_attachments]', 0
+  end
+
+  def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
+    @request.session[:user_id] = 2
+    issue = Issue.generate_with_descendants!
+    get :new, :project_id => 1, :copy_from => issue.id
+
+    assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value=1]'
+  end
+
+  def test_new_as_copy_with_invalid_issue_should_respond_with_404
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1, :copy_from => 99999
+    assert_response 404
+  end
+
+  def test_create_as_copy_on_different_project
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1, :copy_from => 1,
+        :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
+
+      assert_not_nil assigns(:issue)
+      assert assigns(:issue).copy?
+    end
+    issue = Issue.first(:order => 'id DESC')
+    assert_redirected_to "/issues/#{issue.id}"
+
+    assert_equal 2, issue.project_id
+    assert_equal 3, issue.tracker_id
+    assert_equal 'Copy', issue.subject
+  end
+
+  def test_create_as_copy_should_copy_attachments
+    @request.session[:user_id] = 2
+    issue = Issue.find(3)
+    count = issue.attachments.count
+    assert count > 0
+
+    assert_difference 'Issue.count' do
+      assert_difference 'Attachment.count', count do
+        assert_no_difference 'Journal.count' do
+          post :create, :project_id => 1, :copy_from => 3,
+            :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
+            :copy_attachments => '1'
+        end
+      end
+    end
+    copy = Issue.first(:order => 'id DESC')
+    assert_equal count, copy.attachments.count
+    assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
+  end
+
+  def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
+    @request.session[:user_id] = 2
+    issue = Issue.find(3)
+    count = issue.attachments.count
+    assert count > 0
+
+    assert_difference 'Issue.count' do
+      assert_no_difference 'Attachment.count' do
+        assert_no_difference 'Journal.count' do
+          post :create, :project_id => 1, :copy_from => 3,
+            :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'}
+        end
+      end
+    end
+    copy = Issue.first(:order => 'id DESC')
+    assert_equal 0, copy.attachments.count
+  end
+
+  def test_create_as_copy_with_attachments_should_add_new_files
+    @request.session[:user_id] = 2
+    issue = Issue.find(3)
+    count = issue.attachments.count
+    assert count > 0
+
+    assert_difference 'Issue.count' do
+      assert_difference 'Attachment.count', count + 1 do
+        assert_no_difference 'Journal.count' do
+          post :create, :project_id => 1, :copy_from => 3,
+            :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
+            :copy_attachments => '1',
+            :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
+        end
+      end
+    end
+    copy = Issue.first(:order => 'id DESC')
+    assert_equal count + 1, copy.attachments.count
+  end
+
+  def test_create_as_copy_should_add_relation_with_copied_issue
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count' do
+      assert_difference 'IssueRelation.count' do
+        post :create, :project_id => 1, :copy_from => 1,
+          :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
+      end
+    end
+    copy = Issue.first(:order => 'id DESC')
+    assert_equal 1, copy.relations.size
+  end
+
+  def test_create_as_copy_should_copy_subtasks
+    @request.session[:user_id] = 2
+    issue = Issue.generate_with_descendants!
+    count = issue.descendants.count
+
+    assert_difference 'Issue.count', count+1 do
+      assert_no_difference 'Journal.count' do
+        post :create, :project_id => 1, :copy_from => issue.id,
+          :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'},
+          :copy_subtasks => '1'
+      end
+    end
+    copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
+    assert_equal count, copy.descendants.count
+    assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
+  end
+
+  def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
+    @request.session[:user_id] = 2
+    issue = Issue.generate_with_descendants!
+
+    assert_difference 'Issue.count', 1 do
+      assert_no_difference 'Journal.count' do
+        post :create, :project_id => 1, :copy_from => 3,
+          :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'}
+      end
+    end
+    copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
+    assert_equal 0, copy.descendants.count
+  end
+
+  def test_create_as_copy_with_failure
+    @request.session[:user_id] = 2
+    post :create, :project_id => 1, :copy_from => 1,
+      :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
+
+    assert_response :success
+    assert_template 'new'
+
+    assert_not_nil assigns(:issue)
+    assert assigns(:issue).copy?
+
+    assert_select 'form#issue-form[action=/projects/ecookbook/issues]' do
+      assert_select 'select[name=?]', 'issue[project_id]' do
+        assert_select 'option[value=1]:not([selected])', :text => 'eCookbook'
+        assert_select 'option[value=2][selected=selected]', :text => 'OnlineStore'
+      end
+      assert_select 'input[name=copy_from][value=1]'
+    end
+  end
+
+  def test_create_as_copy_on_project_without_permission_should_ignore_target_project
+    @request.session[:user_id] = 2
+    assert !User.find(2).member_of?(Project.find(4))
+
+    assert_difference 'Issue.count' do
+      post :create, :project_id => 1, :copy_from => 1,
+        :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
+    end
+    issue = Issue.first(:order => 'id DESC')
+    assert_equal 1, issue.project_id
+  end
+
+  def test_get_edit
+    @request.session[:user_id] = 2
+    get :edit, :id => 1
+    assert_response :success
+    assert_template 'edit'
+    assert_not_nil assigns(:issue)
+    assert_equal Issue.find(1), assigns(:issue)
+
+    # Be sure we don't display inactive IssuePriorities
+    assert ! IssuePriority.find(15).active?
+    assert_select 'select[name=?]', 'issue[priority_id]' do
+      assert_select 'option[value=15]', 0
+    end
+  end
+
+  def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
+    @request.session[:user_id] = 2
+    Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
+    
+    get :edit, :id => 1
+    assert_select 'input[name=?]', 'time_entry[hours]'
+  end
+
+  def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
+    @request.session[:user_id] = 2
+    Role.find_by_name('Manager').remove_permission! :log_time
+    
+    get :edit, :id => 1
+    assert_select 'input[name=?]', 'time_entry[hours]', 0
+  end
+
+  def test_get_edit_with_params
+    @request.session[:user_id] = 2
+    get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
+        :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => 10 }
+    assert_response :success
+    assert_template 'edit'
+
+    issue = assigns(:issue)
+    assert_not_nil issue
+
+    assert_equal 5, issue.status_id
+    assert_select 'select[name=?]', 'issue[status_id]' do
+      assert_select 'option[value=5][selected=selected]', :text => 'Closed'
+    end
+
+    assert_equal 7, issue.priority_id
+    assert_select 'select[name=?]', 'issue[priority_id]' do
+      assert_select 'option[value=7][selected=selected]', :text => 'Urgent'
+    end
+
+    assert_select 'input[name=?][value=2.5]', 'time_entry[hours]'
+    assert_select 'select[name=?]', 'time_entry[activity_id]' do
+      assert_select 'option[value=10][selected=selected]', :text => 'Development'
+    end
+    assert_select 'input[name=?][value=test_get_edit_with_params]', 'time_entry[comments]'
+  end
+
+  def test_get_edit_with_multi_custom_field
+    field = CustomField.find(1)
+    field.update_attribute :multiple, true
+    issue = Issue.find(1)
+    issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
+    issue.save!
+
+    @request.session[:user_id] = 2
+    get :edit, :id => 1
+    assert_response :success
+    assert_template 'edit'
+
+    assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
+      assert_select 'option', 3
+      assert_select 'option[value=MySQL][selected=selected]'
+      assert_select 'option[value=Oracle][selected=selected]'
+      assert_select 'option[value=PostgreSQL]:not([selected])'
+    end
+  end
+
+  def test_update_form_for_existing_issue
+    @request.session[:user_id] = 2
+    xhr :put, :update_form, :project_id => 1,
+                             :id => 1,
+                             :issue => {:tracker_id => 2,
+                                        :subject => 'This is the test_new issue',
+                                        :description => 'This is the description',
+                                        :priority_id => 5}
+    assert_response :success
+    assert_equal 'text/javascript', response.content_type
+    assert_template 'update_form'
+    assert_template 'form'
+
+    issue = assigns(:issue)
+    assert_kind_of Issue, issue
+    assert_equal 1, issue.id
+    assert_equal 1, issue.project_id
+    assert_equal 2, issue.tracker_id
+    assert_equal 'This is the test_new issue', issue.subject
+  end
+
+  def test_update_form_for_existing_issue_should_keep_issue_author
+    @request.session[:user_id] = 3
+    xhr :put, :update_form, :project_id => 1, :id => 1, :issue => {:subject => 'Changed'}
+    assert_response :success
+    assert_equal 'text/javascript', response.content_type
+
+    issue = assigns(:issue)
+    assert_equal User.find(2), issue.author
+    assert_equal 2, issue.author_id
+    assert_not_equal User.current, issue.author
+  end
+
+  def test_update_form_for_existing_issue_should_propose_transitions_based_on_initial_status
+    @request.session[:user_id] = 2
+    WorkflowTransition.delete_all
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
+
+    xhr :put, :update_form, :project_id => 1,
+                    :id => 2,
+                    :issue => {:tracker_id => 2,
+                               :status_id => 5,
+                               :subject => 'This is an issue'}
+
+    assert_equal 5, assigns(:issue).status_id
+    assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
+  end
+
+  def test_update_form_for_existing_issue_with_project_change
+    @request.session[:user_id] = 2
+    xhr :put, :update_form, :project_id => 1,
+                             :id => 1,
+                             :issue => {:project_id => 2,
+                                        :tracker_id => 2,
+                                        :subject => 'This is the test_new issue',
+                                        :description => 'This is the description',
+                                        :priority_id => 5}
+    assert_response :success
+    assert_template 'form'
+
+    issue = assigns(:issue)
+    assert_kind_of Issue, issue
+    assert_equal 1, issue.id
+    assert_equal 2, issue.project_id
+    assert_equal 2, issue.tracker_id
+    assert_equal 'This is the test_new issue', issue.subject
+  end
+
+  def test_put_update_without_custom_fields_param
+    @request.session[:user_id] = 2
+    ActionMailer::Base.deliveries.clear
+
+    issue = Issue.find(1)
+    assert_equal '125', issue.custom_value_for(2).value
+    old_subject = issue.subject
+    new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
+
+    assert_difference('Journal.count') do
+      assert_difference('JournalDetail.count', 2) do
+        put :update, :id => 1, :issue => {:subject => new_subject,
+                                         :priority_id => '6',
+                                         :category_id => '1' # no change
+                                        }
+      end
+    end
+    assert_redirected_to :action => 'show', :id => '1'
+    issue.reload
+    assert_equal new_subject, issue.subject
+    # Make sure custom fields were not cleared
+    assert_equal '125', issue.custom_value_for(2).value
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
+    assert_mail_body_match "Subject changed from #{old_subject} to #{new_subject}", mail
+  end
+
+  def test_put_update_with_project_change
+    @request.session[:user_id] = 2
+    ActionMailer::Base.deliveries.clear
+
+    assert_difference('Journal.count') do
+      assert_difference('JournalDetail.count', 3) do
+        put :update, :id => 1, :issue => {:project_id => '2',
+                                         :tracker_id => '1', # no change
+                                         :priority_id => '6',
+                                         :category_id => '3'
+                                        }
+      end
+    end
+    assert_redirected_to :action => 'show', :id => '1'
+    issue = Issue.find(1)
+    assert_equal 2, issue.project_id
+    assert_equal 1, issue.tracker_id
+    assert_equal 6, issue.priority_id
+    assert_equal 3, issue.category_id
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
+    assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
+  end
+
+  def test_put_update_with_tracker_change
+    @request.session[:user_id] = 2
+    ActionMailer::Base.deliveries.clear
+
+    assert_difference('Journal.count') do
+      assert_difference('JournalDetail.count', 2) do
+        put :update, :id => 1, :issue => {:project_id => '1',
+                                         :tracker_id => '2',
+                                         :priority_id => '6'
+                                        }
+      end
+    end
+    assert_redirected_to :action => 'show', :id => '1'
+    issue = Issue.find(1)
+    assert_equal 1, issue.project_id
+    assert_equal 2, issue.tracker_id
+    assert_equal 6, issue.priority_id
+    assert_equal 1, issue.category_id
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
+    assert_mail_body_match "Tracker changed from Bug to Feature request", mail
+  end
+
+  def test_put_update_with_custom_field_change
+    @request.session[:user_id] = 2
+    issue = Issue.find(1)
+    assert_equal '125', issue.custom_value_for(2).value
+
+    assert_difference('Journal.count') do
+      assert_difference('JournalDetail.count', 3) do
+        put :update, :id => 1, :issue => {:subject => 'Custom field change',
+                                         :priority_id => '6',
+                                         :category_id => '1', # no change
+                                         :custom_field_values => { '2' => 'New custom value' }
+                                        }
+      end
+    end
+    assert_redirected_to :action => 'show', :id => '1'
+    issue.reload
+    assert_equal 'New custom value', issue.custom_value_for(2).value
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
+  end
+
+  def test_put_update_with_multi_custom_field_change
+    field = CustomField.find(1)
+    field.update_attribute :multiple, true
+    issue = Issue.find(1)
+    issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
+    issue.save!
+
+    @request.session[:user_id] = 2
+    assert_difference('Journal.count') do
+      assert_difference('JournalDetail.count', 3) do
+        put :update, :id => 1,
+          :issue => {
+            :subject => 'Custom field change',
+            :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
+          }
+      end
+    end
+    assert_redirected_to :action => 'show', :id => '1'
+    assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
+  end
+
+  def test_put_update_with_status_and_assignee_change
+    issue = Issue.find(1)
+    assert_equal 1, issue.status_id
+    @request.session[:user_id] = 2
+    assert_difference('TimeEntry.count', 0) do
+      put :update,
+           :id => 1,
+           :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
+           :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
+    end
+    assert_redirected_to :action => 'show', :id => '1'
+    issue.reload
+    assert_equal 2, issue.status_id
+    j = Journal.order('id DESC').first
+    assert_equal 'Assigned to dlopper', j.notes
+    assert_equal 2, j.details.size
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_mail_body_match "Status changed from New to Assigned", mail
+    # subject should contain the new status
+    assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
+  end
+
+  def test_put_update_with_note_only
+    notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
+    # anonymous user
+    put :update,
+         :id => 1,
+         :issue => { :notes => notes }
+    assert_redirected_to :action => 'show', :id => '1'
+    j = Journal.order('id DESC').first
+    assert_equal notes, j.notes
+    assert_equal 0, j.details.size
+    assert_equal User.anonymous, j.user
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_mail_body_match notes, mail
+  end
+
+  def test_put_update_with_private_note_only
+    notes = 'Private note'
+    @request.session[:user_id] = 2
+
+    assert_difference 'Journal.count' do
+      put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
+      assert_redirected_to :action => 'show', :id => '1'
+    end
+
+    j = Journal.order('id DESC').first
+    assert_equal notes, j.notes
+    assert_equal true, j.private_notes
+  end
+
+  def test_put_update_with_private_note_and_changes
+    notes = 'Private note'
+    @request.session[:user_id] = 2
+
+    assert_difference 'Journal.count', 2 do
+      put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
+      assert_redirected_to :action => 'show', :id => '1'
+    end
+
+    j = Journal.order('id DESC').first
+    assert_equal notes, j.notes
+    assert_equal true, j.private_notes
+    assert_equal 0, j.details.count
+
+    j = Journal.order('id DESC').offset(1).first
+    assert_nil j.notes
+    assert_equal false, j.private_notes
+    assert_equal 1, j.details.count
+  end
+
+  def test_put_update_with_note_and_spent_time
+    @request.session[:user_id] = 2
+    spent_hours_before = Issue.find(1).spent_hours
+    assert_difference('TimeEntry.count') do
+      put :update,
+           :id => 1,
+           :issue => { :notes => '2.5 hours added' },
+           :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
+    end
+    assert_redirected_to :action => 'show', :id => '1'
+
+    issue = Issue.find(1)
+
+    j = Journal.order('id DESC').first
+    assert_equal '2.5 hours added', j.notes
+    assert_equal 0, j.details.size
+
+    t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
+    assert_not_nil t
+    assert_equal 2.5, t.hours
+    assert_equal spent_hours_before + 2.5, issue.spent_hours
+  end
+
+  def test_put_update_should_preserve_parent_issue_even_if_not_visible
+    parent = Issue.generate!(:project_id => 1, :is_private => true)
+    issue = Issue.generate!(:parent_issue_id => parent.id)
+    assert !parent.visible?(User.find(3))
+    @request.session[:user_id] = 3
+
+    get :edit, :id => issue.id
+    assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', parent.id.to_s
+
+    put :update, :id => issue.id, :issue => {:subject => 'New subject', :parent_issue_id => parent.id.to_s}
+    assert_response 302
+    assert_equal parent, issue.parent
+  end
+
+  def test_put_update_with_attachment_only
+    set_tmp_attachments_directory
+
+    # Delete all fixtured journals, a race condition can occur causing the wrong
+    # journal to get fetched in the next find.
+    Journal.delete_all
+
+    # anonymous user
+    assert_difference 'Attachment.count' do
+      put :update, :id => 1,
+        :issue => {:notes => ''},
+        :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
+    end
+
+    assert_redirected_to :action => 'show', :id => '1'
+    j = Issue.find(1).journals.reorder('id DESC').first
+    assert j.notes.blank?
+    assert_equal 1, j.details.size
+    assert_equal 'testfile.txt', j.details.first.value
+    assert_equal User.anonymous, j.user
+
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal Issue.find(1), attachment.container
+    assert_equal User.anonymous, attachment.author
+    assert_equal 'testfile.txt', attachment.filename
+    assert_equal 'text/plain', attachment.content_type
+    assert_equal 'test file', attachment.description
+    assert_equal 59, attachment.filesize
+    assert File.exists?(attachment.diskfile)
+    assert_equal 59, File.size(attachment.diskfile)
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_mail_body_match 'testfile.txt', mail
+  end
+
+  def test_put_update_with_failure_should_save_attachments
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Journal.count' do
+      assert_difference 'Attachment.count' do
+        put :update, :id => 1,
+          :issue => { :subject => '' },
+          :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
+        assert_response :success
+        assert_template 'edit'
+      end
+    end
+
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal 'testfile.txt', attachment.filename
+    assert File.exists?(attachment.diskfile)
+    assert_nil attachment.container
+
+    assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
+  end
+
+  def test_put_update_with_failure_should_keep_saved_attachments
+    set_tmp_attachments_directory
+    attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Journal.count' do
+      assert_no_difference 'Attachment.count' do
+        put :update, :id => 1,
+          :issue => { :subject => '' },
+          :attachments => {'p0' => {'token' => attachment.token}}
+        assert_response :success
+        assert_template 'edit'
+      end
+    end
+
+    assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
+  end
+
+  def test_put_update_should_attach_saved_attachments
+    set_tmp_attachments_directory
+    attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
+    @request.session[:user_id] = 2
+
+    assert_difference 'Journal.count' do
+      assert_difference 'JournalDetail.count' do
+        assert_no_difference 'Attachment.count' do
+          put :update, :id => 1,
+            :issue => {:notes => 'Attachment added'},
+            :attachments => {'p0' => {'token' => attachment.token}}
+          assert_redirected_to '/issues/1'
+        end
+      end
+    end
+
+    attachment.reload
+    assert_equal Issue.find(1), attachment.container
+
+    journal = Journal.first(:order => 'id DESC')
+    assert_equal 1, journal.details.size
+    assert_equal 'testfile.txt', journal.details.first.value
+  end
+
+  def test_put_update_with_attachment_that_fails_to_save
+    set_tmp_attachments_directory
+
+    # Delete all fixtured journals, a race condition can occur causing the wrong
+    # journal to get fetched in the next find.
+    Journal.delete_all
+
+    # Mock out the unsaved attachment
+    Attachment.any_instance.stubs(:create).returns(Attachment.new)
+
+    # anonymous user
+    put :update,
+         :id => 1,
+         :issue => {:notes => ''},
+         :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
+    assert_redirected_to :action => 'show', :id => '1'
+    assert_equal '1 file(s) could not be saved.', flash[:warning]
+  end
+
+  def test_put_update_with_no_change
+    issue = Issue.find(1)
+    issue.journals.clear
+    ActionMailer::Base.deliveries.clear
+
+    put :update,
+         :id => 1,
+         :issue => {:notes => ''}
+    assert_redirected_to :action => 'show', :id => '1'
+
+    issue.reload
+    assert issue.journals.empty?
+    # No email should be sent
+    assert ActionMailer::Base.deliveries.empty?
+  end
+
+  def test_put_update_should_send_a_notification
+    @request.session[:user_id] = 2
+    ActionMailer::Base.deliveries.clear
+    issue = Issue.find(1)
+    old_subject = issue.subject
+    new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
+
+    put :update, :id => 1, :issue => {:subject => new_subject,
+                                     :priority_id => '6',
+                                     :category_id => '1' # no change
+                                    }
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_put_update_with_invalid_spent_time_hours_only
+    @request.session[:user_id] = 2
+    notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
+
+    assert_no_difference('Journal.count') do
+      put :update,
+           :id => 1,
+           :issue => {:notes => notes},
+           :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
+    end
+    assert_response :success
+    assert_template 'edit'
+
+    assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
+    assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
+    assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2z'
+  end
+
+  def test_put_update_with_invalid_spent_time_comments_only
+    @request.session[:user_id] = 2
+    notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
+
+    assert_no_difference('Journal.count') do
+      put :update,
+           :id => 1,
+           :issue => {:notes => notes},
+           :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
+    end
+    assert_response :success
+    assert_template 'edit'
+
+    assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
+    assert_error_tag :descendant => {:content => /Hours can&#x27;t be blank/}
+    assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
+    assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'this is my comment'
+  end
+
+  def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
+    issue = Issue.find(2)
+    @request.session[:user_id] = 2
+
+    put :update,
+         :id => issue.id,
+         :issue => {
+           :fixed_version_id => 4
+         }
+
+    assert_response :redirect
+    issue.reload
+    assert_equal 4, issue.fixed_version_id
+    assert_not_equal issue.project_id, issue.fixed_version.project_id
+  end
+
+  def test_put_update_should_redirect_back_using_the_back_url_parameter
+    issue = Issue.find(2)
+    @request.session[:user_id] = 2
+
+    put :update,
+         :id => issue.id,
+         :issue => {
+           :fixed_version_id => 4
+         },
+         :back_url => '/issues'
+
+    assert_response :redirect
+    assert_redirected_to '/issues'
+  end
+
+  def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
+    issue = Issue.find(2)
+    @request.session[:user_id] = 2
+
+    put :update,
+         :id => issue.id,
+         :issue => {
+           :fixed_version_id => 4
+         },
+         :back_url => 'http://google.com'
+
+    assert_response :redirect
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
+  end
+
+  def test_get_bulk_edit
+    @request.session[:user_id] = 2
+    get :bulk_edit, :ids => [1, 2]
+    assert_response :success
+    assert_template 'bulk_edit'
+
+    assert_select 'ul#bulk-selection' do
+      assert_select 'li', 2
+      assert_select 'li a', :text => 'Bug #1'
+    end
+
+    assert_select 'form#bulk_edit_form[action=?]', '/issues/bulk_update' do
+      assert_select 'input[name=?]', 'ids[]', 2
+      assert_select 'input[name=?][value=1][type=hidden]', 'ids[]'
+
+      assert_select 'select[name=?]', 'issue[project_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]'
+  
+      # Project specific custom field, date type
+      field = CustomField.find(9)
+      assert !field.is_for_all?
+      assert_equal 'date', field.field_format
+      assert_select 'input[name=?]', 'issue[custom_field_values][9]'
+  
+      # System wide custom field
+      assert CustomField.find(1).is_for_all?
+      assert_select 'select[name=?]', 'issue[custom_field_values][1]'
+  
+      # Be sure we don't display inactive IssuePriorities
+      assert ! IssuePriority.find(15).active?
+      assert_select 'select[name=?]', 'issue[priority_id]' do
+        assert_select 'option[value=15]', 0
+      end
+    end
+  end
+
+  def test_get_bulk_edit_on_different_projects
+    @request.session[:user_id] = 2
+    get :bulk_edit, :ids => [1, 2, 6]
+    assert_response :success
+    assert_template 'bulk_edit'
+
+    # Can not set issues from different projects as children of an issue
+    assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
+
+    # Project specific custom field, date type
+    field = CustomField.find(9)
+    assert !field.is_for_all?
+    assert !field.project_ids.include?(Issue.find(6).project_id)
+    assert_select 'input[name=?]', 'issue[custom_field_values][9]', 0
+  end
+
+  def test_get_bulk_edit_with_user_custom_field
+    field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
+
+    @request.session[:user_id] = 2
+    get :bulk_edit, :ids => [1, 2]
+    assert_response :success
+    assert_template 'bulk_edit'
+
+    assert_select 'select.user_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
+      assert_select 'option', Project.find(1).users.count + 2 # "no change" + "none" options
+    end
+  end
+
+  def test_get_bulk_edit_with_version_custom_field
+    field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
+
+    @request.session[:user_id] = 2
+    get :bulk_edit, :ids => [1, 2]
+    assert_response :success
+    assert_template 'bulk_edit'
+
+    assert_select 'select.version_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
+      assert_select 'option', Project.find(1).shared_versions.count + 2 # "no change" + "none" options
+    end
+  end
+
+  def test_get_bulk_edit_with_multi_custom_field
+    field = CustomField.find(1)
+    field.update_attribute :multiple, true
+
+    @request.session[:user_id] = 2
+    get :bulk_edit, :ids => [1, 2]
+    assert_response :success
+    assert_template 'bulk_edit'
+
+    assert_select 'select[name=?]', 'issue[custom_field_values][1][]' do
+      assert_select 'option', field.possible_values.size + 1 # "none" options
+    end
+  end
+
+  def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
+    WorkflowTransition.delete_all
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 1)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
+    @request.session[:user_id] = 2
+    get :bulk_edit, :ids => [1, 2]
+
+    assert_response :success
+    statuses = assigns(:available_statuses)
+    assert_not_nil statuses
+    assert_equal [1, 3], statuses.map(&:id).sort
+
+    assert_select 'select[name=?]', 'issue[status_id]' do
+      assert_select 'option', 3 # 2 statuses + "no change" option
+    end
+  end
+
+  def test_bulk_edit_should_propose_target_project_open_shared_versions
+    @request.session[:user_id] = 2
+    post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
+    assert_response :success
+    assert_template 'bulk_edit'
+    assert_equal Project.find(1).shared_versions.open.all.sort, assigns(:versions).sort
+
+    assert_select 'select[name=?]', 'issue[fixed_version_id]' do
+      assert_select 'option', :text => '2.0'
+    end
+  end
+
+  def test_bulk_edit_should_propose_target_project_categories
+    @request.session[:user_id] = 2
+    post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
+    assert_response :success
+    assert_template 'bulk_edit'
+    assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
+
+    assert_select 'select[name=?]', 'issue[category_id]' do
+      assert_select 'option', :text => 'Recipes'
+    end
+  end
+
+  def test_bulk_update
+    @request.session[:user_id] = 2
+    # update issues priority
+    post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
+                                     :issue => {:priority_id => 7,
+                                                :assigned_to_id => '',
+                                                :custom_field_values => {'2' => ''}}
+
+    assert_response 302
+    # check that the issues were updated
+    assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
+
+    issue = Issue.find(1)
+    journal = issue.journals.reorder('created_on DESC').first
+    assert_equal '125', issue.custom_value_for(2).value
+    assert_equal 'Bulk editing', journal.notes
+    assert_equal 1, journal.details.size
+  end
+
+  def test_bulk_update_with_group_assignee
+    group = Group.find(11)
+    project = Project.find(1)
+    project.members << Member.new(:principal => group, :roles => [Role.givable.first])
+
+    @request.session[:user_id] = 2
+    # update issues assignee
+    post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
+                                     :issue => {:priority_id => '',
+                                                :assigned_to_id => group.id,
+                                                :custom_field_values => {'2' => ''}}
+
+    assert_response 302
+    assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
+  end
+
+  def test_bulk_update_on_different_projects
+    @request.session[:user_id] = 2
+    # update issues priority
+    post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
+                                     :issue => {:priority_id => 7,
+                                                :assigned_to_id => '',
+                                                :custom_field_values => {'2' => ''}}
+
+    assert_response 302
+    # check that the issues were updated
+    assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
+
+    issue = Issue.find(1)
+    journal = issue.journals.reorder('created_on DESC').first
+    assert_equal '125', issue.custom_value_for(2).value
+    assert_equal 'Bulk editing', journal.notes
+    assert_equal 1, journal.details.size
+  end
+
+  def test_bulk_update_on_different_projects_without_rights
+    @request.session[:user_id] = 3
+    user = User.find(3)
+    action = { :controller => "issues", :action => "bulk_update" }
+    assert user.allowed_to?(action, Issue.find(1).project)
+    assert ! user.allowed_to?(action, Issue.find(6).project)
+    post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
+                                     :issue => {:priority_id => 7,
+                                                :assigned_to_id => '',
+                                                :custom_field_values => {'2' => ''}}
+    assert_response 403
+    assert_not_equal "Bulk should fail", Journal.last.notes
+  end
+
+  def test_bullk_update_should_send_a_notification
+    @request.session[:user_id] = 2
+    ActionMailer::Base.deliveries.clear
+    post(:bulk_update,
+         {
+           :ids => [1, 2],
+           :notes => 'Bulk editing',
+           :issue => {
+             :priority_id => 7,
+             :assigned_to_id => '',
+             :custom_field_values => {'2' => ''}
+           }
+         })
+
+    assert_response 302
+    assert_equal 2, ActionMailer::Base.deliveries.size
+  end
+
+  def test_bulk_update_project
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
+    # Issues moved to project 2
+    assert_equal 2, Issue.find(1).project_id
+    assert_equal 2, Issue.find(2).project_id
+    # No tracker change
+    assert_equal 1, Issue.find(1).tracker_id
+    assert_equal 2, Issue.find(2).tracker_id
+  end
+
+  def test_bulk_update_project_on_single_issue_should_follow_when_needed
+    @request.session[:user_id] = 2
+    post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
+    assert_redirected_to '/issues/1'
+  end
+
+  def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
+    @request.session[:user_id] = 2
+    post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
+    assert_redirected_to '/projects/onlinestore/issues'
+  end
+
+  def test_bulk_update_tracker
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
+    assert_equal 2, Issue.find(1).tracker_id
+    assert_equal 2, Issue.find(2).tracker_id
+  end
+
+  def test_bulk_update_status
+    @request.session[:user_id] = 2
+    # update issues priority
+    post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
+                                     :issue => {:priority_id => '',
+                                                :assigned_to_id => '',
+                                                :status_id => '5'}
+
+    assert_response 302
+    issue = Issue.find(1)
+    assert issue.closed?
+  end
+
+  def test_bulk_update_priority
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
+
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
+    assert_equal 6, Issue.find(1).priority_id
+    assert_equal 6, Issue.find(2).priority_id
+  end
+
+  def test_bulk_update_with_notes
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
+
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
+    assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
+    assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
+  end
+
+  def test_bulk_update_parent_id
+    IssueRelation.delete_all
+
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 3],
+      :notes => 'Bulk editing parent',
+      :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
+
+    assert_response 302
+    parent = Issue.find(2)
+    assert_equal parent.id, Issue.find(1).parent_id
+    assert_equal parent.id, Issue.find(3).parent_id
+    assert_equal [1, 3], parent.children.collect(&:id).sort
+  end
+
+  def test_bulk_update_custom_field
+    @request.session[:user_id] = 2
+    # update issues priority
+    post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
+                                     :issue => {:priority_id => '',
+                                                :assigned_to_id => '',
+                                                :custom_field_values => {'2' => '777'}}
+
+    assert_response 302
+
+    issue = Issue.find(1)
+    journal = issue.journals.reorder('created_on DESC').first
+    assert_equal '777', issue.custom_value_for(2).value
+    assert_equal 1, journal.details.size
+    assert_equal '125', journal.details.first.old_value
+    assert_equal '777', journal.details.first.value
+  end
+
+  def test_bulk_update_custom_field_to_blank
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
+                                     :issue => {:priority_id => '',
+                                                :assigned_to_id => '',
+                                                :custom_field_values => {'1' => '__none__'}}
+    assert_response 302
+    assert_equal '', Issue.find(1).custom_field_value(1)
+    assert_equal '', Issue.find(3).custom_field_value(1)
+  end
+
+  def test_bulk_update_multi_custom_field
+    field = CustomField.find(1)
+    field.update_attribute :multiple, true
+
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
+                                     :issue => {:priority_id => '',
+                                                :assigned_to_id => '',
+                                                :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
+
+    assert_response 302
+
+    assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
+    assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
+    # the custom field is not associated with the issue tracker
+    assert_nil Issue.find(2).custom_field_value(1)
+  end
+
+  def test_bulk_update_multi_custom_field_to_blank
+    field = CustomField.find(1)
+    field.update_attribute :multiple, true
+
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
+                                     :issue => {:priority_id => '',
+                                                :assigned_to_id => '',
+                                                :custom_field_values => {'1' => ['__none__']}}
+    assert_response 302
+    assert_equal [''], Issue.find(1).custom_field_value(1)
+    assert_equal [''], Issue.find(3).custom_field_value(1)
+  end
+
+  def test_bulk_update_unassign
+    assert_not_nil Issue.find(2).assigned_to
+    @request.session[:user_id] = 2
+    # unassign issues
+    post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
+    assert_response 302
+    # check that the issues were updated
+    assert_nil Issue.find(2).assigned_to
+  end
+
+  def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
+    @request.session[:user_id] = 2
+
+    post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
+
+    assert_response :redirect
+    issues = Issue.find([1,2])
+    issues.each do |issue|
+      assert_equal 4, issue.fixed_version_id
+      assert_not_equal issue.project_id, issue.fixed_version.project_id
+    end
+  end
+
+  def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1,2], :back_url => '/issues'
+
+    assert_response :redirect
+    assert_redirected_to '/issues'
+  end
+
+  def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
+
+    assert_response :redirect
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
+  end
+
+  def test_bulk_update_with_failure_should_set_flash
+    @request.session[:user_id] = 2
+    Issue.update_all("subject = ''", "id = 2") # Make it invalid
+    post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
+
+    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
+    assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error]
+  end
+
+  def test_get_bulk_copy
+    @request.session[:user_id] = 2
+    get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
+    assert_response :success
+    assert_template 'bulk_edit'
+
+    issues = assigns(:issues)
+    assert_not_nil issues
+    assert_equal [1, 2, 3], issues.map(&:id).sort
+
+    assert_select 'input[name=copy_attachments]'
+  end
+
+  def test_bulk_copy_to_another_project
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count', 2 do
+      assert_no_difference 'Project.find(1).issues.count' do
+        post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
+      end
+    end
+    assert_redirected_to '/projects/ecookbook/issues'
+
+    copies = Issue.all(:order => 'id DESC', :limit => issues.size)
+    copies.each do |copy|
+      assert_equal 2, copy.project_id
+    end
+  end
+
+  def test_bulk_copy_should_allow_not_changing_the_issue_attributes
+    @request.session[:user_id] = 2
+    issues = [
+      Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1, :priority_id => 2, :subject => 'issue 1', :author_id => 1, :assigned_to_id => nil),
+      Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2, :priority_id => 1, :subject => 'issue 2', :author_id => 2, :assigned_to_id => 3)
+    ]
+
+    assert_difference 'Issue.count', issues.size do
+      post :bulk_update, :ids => issues.map(&:id), :copy => '1', 
+           :issue => {
+             :project_id => '', :tracker_id => '', :assigned_to_id => '',
+             :status_id => '', :start_date => '', :due_date => ''
+           }
+    end
+
+    copies = Issue.all(:order => 'id DESC', :limit => issues.size)
+    issues.each do |orig|
+      copy = copies.detect {|c| c.subject == orig.subject}
+      assert_not_nil copy
+      assert_equal orig.project_id, copy.project_id
+      assert_equal orig.tracker_id, copy.tracker_id
+      assert_equal orig.status_id, copy.status_id
+      assert_equal orig.assigned_to_id, copy.assigned_to_id
+      assert_equal orig.priority_id, copy.priority_id
+    end
+  end
+
+  def test_bulk_copy_should_allow_changing_the_issue_attributes
+    # Fixes random test failure with Mysql
+    # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
+    # doesn't return the expected results
+    Issue.delete_all("project_id=2")
+
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count', 2 do
+      assert_no_difference 'Project.find(1).issues.count' do
+        post :bulk_update, :ids => [1, 2], :copy => '1', 
+             :issue => {
+               :project_id => '2', :tracker_id => '', :assigned_to_id => '4',
+               :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
+             }
+      end
+    end
+
+    copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
+    assert_equal 2, copied_issues.size
+    copied_issues.each do |issue|
+      assert_equal 2, issue.project_id, "Project is incorrect"
+      assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
+      assert_equal 1, issue.status_id, "Status is incorrect"
+      assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
+      assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
+    end
+  end
+
+  def test_bulk_copy_should_allow_adding_a_note
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count', 1 do
+      post :bulk_update, :ids => [1], :copy => '1',
+           :notes => 'Copying one issue',
+           :issue => {
+             :project_id => '', :tracker_id => '', :assigned_to_id => '4',
+             :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
+           }
+    end
+
+    issue = Issue.first(:order => 'id DESC')
+    assert_equal 1, issue.journals.size
+    journal = issue.journals.first
+    assert_equal 0, journal.details.size
+    assert_equal 'Copying one issue', journal.notes
+  end
+
+  def test_bulk_copy_should_allow_not_copying_the_attachments
+    attachment_count = Issue.find(3).attachments.size
+    assert attachment_count > 0
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', 1 do
+      assert_no_difference 'Attachment.count' do
+        post :bulk_update, :ids => [3], :copy => '1',
+             :issue => {
+               :project_id => ''
+             }
+      end
+    end
+  end
+
+  def test_bulk_copy_should_allow_copying_the_attachments
+    attachment_count = Issue.find(3).attachments.size
+    assert attachment_count > 0
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', 1 do
+      assert_difference 'Attachment.count', attachment_count do
+        post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
+             :issue => {
+               :project_id => ''
+             }
+      end
+    end
+  end
+
+  def test_bulk_copy_should_add_relations_with_copied_issues
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', 2 do
+      assert_difference 'IssueRelation.count', 2 do
+        post :bulk_update, :ids => [1, 3], :copy => '1', 
+             :issue => {
+               :project_id => '1'
+             }
+      end
+    end
+  end
+
+  def test_bulk_copy_should_allow_not_copying_the_subtasks
+    issue = Issue.generate_with_descendants!
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', 1 do
+      post :bulk_update, :ids => [issue.id], :copy => '1',
+           :issue => {
+             :project_id => ''
+           }
+    end
+  end
+
+  def test_bulk_copy_should_allow_copying_the_subtasks
+    issue = Issue.generate_with_descendants!
+    count = issue.descendants.count
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', count+1 do
+      post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
+           :issue => {
+             :project_id => ''
+           }
+    end
+    copy = Issue.where(:parent_id => nil).order("id DESC").first
+    assert_equal count, copy.descendants.count
+  end
+
+  def test_bulk_copy_should_not_copy_selected_subtasks_twice
+    issue = Issue.generate_with_descendants!
+    count = issue.descendants.count
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', count+1 do
+      post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
+           :issue => {
+             :project_id => ''
+           }
+    end
+    copy = Issue.where(:parent_id => nil).order("id DESC").first
+    assert_equal count, copy.descendants.count
+  end
+
+  def test_bulk_copy_to_another_project_should_follow_when_needed
+    @request.session[:user_id] = 2
+    post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
+    issue = Issue.first(:order => 'id DESC')
+    assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
+  end
+
+  def test_destroy_issue_with_no_time_entries
+    assert_nil TimeEntry.find_by_issue_id(2)
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', -1 do
+      delete :destroy, :id => 2
+    end
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    assert_nil Issue.find_by_id(2)
+  end
+
+  def test_destroy_issues_with_time_entries
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Issue.count' do
+      delete :destroy, :ids => [1, 3]
+    end
+    assert_response :success
+    assert_template 'destroy'
+    assert_not_nil assigns(:hours)
+    assert Issue.find_by_id(1) && Issue.find_by_id(3)
+
+    assert_select 'form' do
+      assert_select 'input[name=_method][value=delete]'
+    end
+  end
+
+  def test_destroy_issues_and_destroy_time_entries
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', -2 do
+      assert_difference 'TimeEntry.count', -3 do
+        delete :destroy, :ids => [1, 3], :todo => 'destroy'
+      end
+    end
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
+    assert_nil TimeEntry.find_by_id([1, 2])
+  end
+
+  def test_destroy_issues_and_assign_time_entries_to_project
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', -2 do
+      assert_no_difference 'TimeEntry.count' do
+        delete :destroy, :ids => [1, 3], :todo => 'nullify'
+      end
+    end
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
+    assert_nil TimeEntry.find(1).issue_id
+    assert_nil TimeEntry.find(2).issue_id
+  end
+
+  def test_destroy_issues_and_reassign_time_entries_to_another_issue
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', -2 do
+      assert_no_difference 'TimeEntry.count' do
+        delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
+      end
+    end
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
+    assert_equal 2, TimeEntry.find(1).issue_id
+    assert_equal 2, TimeEntry.find(2).issue_id
+  end
+
+  def test_destroy_issues_from_different_projects
+    @request.session[:user_id] = 2
+
+    assert_difference 'Issue.count', -3 do
+      delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
+    end
+    assert_redirected_to :controller => 'issues', :action => 'index'
+    assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
+  end
+
+  def test_destroy_parent_and_child_issues
+    parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
+    child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
+    assert child.is_descendant_of?(parent.reload)
+
+    @request.session[:user_id] = 2
+    assert_difference 'Issue.count', -2 do
+      delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
+    end
+    assert_response 302
+  end
+
+  def test_destroy_invalid_should_respond_with_404
+    @request.session[:user_id] = 2
+    assert_no_difference 'Issue.count' do
+      delete :destroy, :id => 999
+    end
+    assert_response 404
+  end
+
+  def test_default_search_scope
+    get :index
+
+    assert_select 'div#quick-search form' do
+      assert_select 'input[name=issues][value=1][type=hidden]'
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/78cbb9f26be10a59d967769f645d28516059e6e0.svn-base
--- a/.svn/pristine/78/78cbb9f26be10a59d967769f645d28516059e6e0.svn-base
+++ /dev/null
@@ -1,126 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Chá»§ nháº­t",
- "Thá»© Hai",
- "Thá»© Ba",
- "Thá»© TÆ°",
- "Thá»© NÄƒm",
- "Thá»© SÃ¡u",
- "Thá»© Báº£y",
- "Chá»§ Nháº­t");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("C.Nháº­t",
- "Hai",
- "Ba",
- "TÆ°",
- "NÄƒm",
- "SÃ¡u",
- "Báº£y",
- "C.Nháº­t");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("ThÃ¡ng GiÃªng",
- "ThÃ¡ng Hai",
- "ThÃ¡ng Ba",
- "ThÃ¡ng TÆ°",
- "ThÃ¡ng NÄƒm",
- "ThÃ¡ng SÃ¡u",
- "ThÃ¡ng Báº£y",
- "ThÃ¡ng TÃ¡m",
- "ThÃ¡ng ChÃ­n",
- "ThÃ¡ng MÆ°á»i",
- "ThÃ¡ng M.Má»™t",
- "ThÃ¡ng Cháº¡p");
-
-// short month names
-Calendar._SMN = new Array
-("Mmá»™t",
- "Hai",
- "Ba",
- "TÆ°",
- "NÄƒm",
- "SÃ¡u",
- "Báº£y",
- "TÃ¡m",
- "ChÃ­n",
- "MÆ°á»i",
- "MMá»™t",
- "Cháº¡p");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Giá»›i thiá»‡u";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector (c) dynarch.com 2002-2005 / TÃ¡c giáº£: Mihai Bazon. " + // don't translate this this ;-)
-"PhiÃªn báº£n má»›i nháº¥t cÃ³ táº¡i: http://www.dynarch.com/projects/calendar/. " +
-"Sáº£n pháº©m Ä‘Æ°á»£c phÃ¢n phá»‘i theo giáº¥y phÃ©p GNU LGPL. Xem chi tiáº¿t táº¡i http://gnu.org/licenses/lgpl.html." +
-"\n\n" +
-"Chá»n ngÃ y:\n" +
-"- DÃ¹ng nÃºt \xab, \xbb Ä‘á»ƒ chá»n nÄƒm\n" +
-"- DÃ¹ng nÃºt " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Ä‘á»ƒ chá»n thÃ¡ng\n" +
-"- Giá»¯ chuá»™t vÃ o cÃ¡c nÃºt trÃªn Ä‘á»ƒ cÃ³ danh sÃ¡ch nÄƒm vÃ  thÃ¡ng.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Chá»n thá»i gian:\n" +
-"- Click chuá»™t trÃªn tá»«ng pháº§n cá»§a thá»i gian Ä‘á»ƒ chá»‰nh sá»­a\n" +
-"- hoáº·c nháº¥n Shift + click chuá»™t Ä‘á»ƒ tÄƒng giÃ¡ trá»‹\n" +
-"- hoáº·c click chuá»™t vÃ  kÃ©o (drag) Ä‘á»ƒ chá»n nhanh.";
-
-Calendar._TT["PREV_YEAR"] = "NÄƒm trÆ°á»›c (giá»¯ chuá»™t Ä‘á»ƒ cÃ³ menu)";
-Calendar._TT["PREV_MONTH"] = "ThÃ¡ng trÆ°á»›c (giá»¯ chuá»™t Ä‘á»ƒ cÃ³ menu)";
-Calendar._TT["GO_TODAY"] = "Ä‘áº¿n HÃ´m nay";
-Calendar._TT["NEXT_MONTH"] = "ThÃ¡ng tá»›i (giá»¯ chuá»™t Ä‘á»ƒ cÃ³ menu)";
-Calendar._TT["NEXT_YEAR"] = "NgÃ y tá»›i (giá»¯ chuá»™t Ä‘á»ƒ cÃ³ menu)";
-Calendar._TT["SEL_DATE"] = "Chá»n ngÃ y";
-Calendar._TT["DRAG_TO_MOVE"] = "KÃ©o (drag) Ä‘á»ƒ di chuyá»ƒn";
-Calendar._TT["PART_TODAY"] = " (hÃ´m nay)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Hiá»ƒn thá»‹ %s trÆ°á»›c";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "ÄÃ³ng";
-Calendar._TT["TODAY"] = "HÃ´m nay";
-Calendar._TT["TIME_PART"] = "Click, shift-click hoáº·c kÃ©o (drag) Ä‘á»ƒ Ä‘á»•i giÃ¡ trá»‹";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Time:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/78d4b11a09b045fdd7cd2b6a434ac47f6be2b36b.svn-base
--- /dev/null
+++ b/.svn/pristine/78/78d4b11a09b045fdd7cd2b6a434ac47f6be2b36b.svn-base
@@ -0,0 +1,38 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingContextMenusTest < ActionController::IntegrationTest
+  def test_context_menus_time_entries
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/time_entries/context_menu" },
+          { :controller => 'context_menus', :action => 'time_entries' }
+        )
+    end
+  end
+
+  def test_context_menus_issues
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/issues/context_menu" },
+          { :controller => 'context_menus', :action => 'issues' }
+        )
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/78/78dfa12979bae9d902d8a61dfe74ca64de496f0f.svn-base
--- /dev/null
+++ b/.svn/pristine/78/78dfa12979bae9d902d8a61dfe74ca64de496f0f.svn-base
@@ -0,0 +1,810 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'tcpdf'
+require 'fpdf/chinese'
+require 'fpdf/japanese'
+require 'fpdf/korean'
+
+if RUBY_VERSION < '1.9'
+  require 'iconv'
+end
+
+module Redmine
+  module Export
+    module PDF
+      include ActionView::Helpers::TextHelper
+      include ActionView::Helpers::NumberHelper
+      include IssuesHelper
+
+      class ITCPDF < TCPDF
+        include Redmine::I18n
+        attr_accessor :footer_date
+
+        def initialize(lang, orientation='P')
+          @@k_path_cache = Rails.root.join('tmp', 'pdf')
+          FileUtils.mkdir_p @@k_path_cache unless File::exist?(@@k_path_cache)
+          set_language_if_valid lang
+          pdf_encoding = l(:general_pdf_encoding).upcase
+          super(orientation, 'mm', 'A4', (pdf_encoding == 'UTF-8'), pdf_encoding)
+          case current_language.to_s.downcase
+          when 'vi'
+            @font_for_content = 'DejaVuSans'
+            @font_for_footer  = 'DejaVuSans'
+          else
+            case pdf_encoding
+            when 'UTF-8'
+              @font_for_content = 'FreeSans'
+              @font_for_footer  = 'FreeSans'
+            when 'CP949'
+              extend(PDF_Korean)
+              AddUHCFont()
+              @font_for_content = 'UHC'
+              @font_for_footer  = 'UHC'
+            when 'CP932', 'SJIS', 'SHIFT_JIS'
+              extend(PDF_Japanese)
+              AddSJISFont()
+              @font_for_content = 'SJIS'
+              @font_for_footer  = 'SJIS'
+            when 'GB18030'
+              extend(PDF_Chinese)
+              AddGBFont()
+              @font_for_content = 'GB'
+              @font_for_footer  = 'GB'
+            when 'BIG5'
+              extend(PDF_Chinese)
+              AddBig5Font()
+              @font_for_content = 'Big5'
+              @font_for_footer  = 'Big5'
+            else
+              @font_for_content = 'Arial'
+              @font_for_footer  = 'Helvetica'
+            end
+          end
+          SetCreator(Redmine::Info.app_name)
+          SetFont(@font_for_content)
+          @outlines = []
+          @outlineRoot = nil
+        end
+
+        def SetFontStyle(style, size)
+          SetFont(@font_for_content, style, size)
+        end
+
+        def SetTitle(txt)
+          txt = begin
+            utf16txt = to_utf16(txt)
+            hextxt = "<FEFF"  # FEFF is BOM
+            hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
+            hextxt << ">"
+          rescue
+            txt
+          end || ''
+          super(txt)
+        end
+
+        def textstring(s)
+          # Format a text string
+          if s =~ /^</  # This means the string is hex-dumped.
+            return s
+          else
+            return '('+escape(s)+')'
+          end
+        end
+
+        def fix_text_encoding(txt)
+          RDMPdfEncoding::rdm_from_utf8(txt, l(:general_pdf_encoding))
+        end
+
+        def formatted_text(text)
+          html = Redmine::WikiFormatting.to_html(Setting.text_formatting, text)
+          # Strip {{toc}} tags
+          html.gsub!(/<p>\{\{([<>]?)toc\}\}<\/p>/i, '')
+          html
+        end
+
+        # Encodes an UTF-8 string to UTF-16BE
+        def to_utf16(str)
+          if str.respond_to?(:encode)
+            str.encode('UTF-16BE')
+          else
+            Iconv.conv('UTF-16BE', 'UTF-8', str)
+          end
+        end
+
+        def RDMCell(w ,h=0, txt='', border=0, ln=0, align='', fill=0, link='')
+          Cell(w, h, fix_text_encoding(txt), border, ln, align, fill, link)
+        end
+
+        def RDMMultiCell(w, h=0, txt='', border=0, align='', fill=0, ln=1)
+          MultiCell(w, h, fix_text_encoding(txt), border, align, fill, ln)
+        end
+
+        def RDMwriteHTMLCell(w, h, x, y, txt='', attachments=[], border=0, ln=1, fill=0)
+          @attachments = attachments
+          writeHTMLCell(w, h, x, y,
+            fix_text_encoding(formatted_text(txt)),
+            border, ln, fill)
+        end
+
+        def getImageFilename(attrname)
+          # attrname: general_pdf_encoding string file/uri name
+          atta = RDMPdfEncoding.attach(@attachments, attrname, l(:general_pdf_encoding))
+          if atta
+            return atta.diskfile
+          else
+            return nil
+          end
+        end
+
+        def Footer
+          SetFont(@font_for_footer, 'I', 8)
+          SetY(-15)
+          SetX(15)
+          RDMCell(0, 5, @footer_date, 0, 0, 'L')
+          SetY(-15)
+          SetX(-30)
+          RDMCell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
+        end
+
+        def Bookmark(txt, level=0, y=0)
+          if (y == -1)
+            y = GetY()
+          end
+          @outlines << {:t => txt, :l => level, :p => PageNo(), :y => (@h - y)*@k}
+        end
+
+        def bookmark_title(txt)
+          txt = begin
+            utf16txt = to_utf16(txt)
+            hextxt = "<FEFF"  # FEFF is BOM
+            hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
+            hextxt << ">"
+          rescue
+            txt
+          end || ''
+        end
+
+        def putbookmarks
+          nb=@outlines.size
+          return if (nb==0)
+          lru=[]
+          level=0
+          @outlines.each_with_index do |o, i|
+            if(o[:l]>0)
+              parent=lru[o[:l]-1]
+              #Set parent and last pointers
+              @outlines[i][:parent]=parent
+              @outlines[parent][:last]=i
+              if (o[:l]>level)
+                #Level increasing: set first pointer
+                @outlines[parent][:first]=i
+              end
+            else
+              @outlines[i][:parent]=nb
+            end
+            if (o[:l]<=level && i>0)
+              #Set prev and next pointers
+              prev=lru[o[:l]]
+              @outlines[prev][:next]=i
+              @outlines[i][:prev]=prev
+            end
+            lru[o[:l]]=i
+            level=o[:l]
+          end
+          #Outline items
+          n=self.n+1
+          @outlines.each_with_index do |o, i|
+            newobj()
+            out('<</Title '+bookmark_title(o[:t]))
+            out("/Parent #{n+o[:parent]} 0 R")
+            if (o[:prev])
+              out("/Prev #{n+o[:prev]} 0 R")
+            end
+            if (o[:next])
+              out("/Next #{n+o[:next]} 0 R")
+            end
+            if (o[:first])
+              out("/First #{n+o[:first]} 0 R")
+            end
+            if (o[:last])
+              out("/Last #{n+o[:last]} 0 R")
+            end
+            out("/Dest [%d 0 R /XYZ 0 %.2f null]" % [1+2*o[:p], o[:y]])
+            out('/Count 0>>')
+            out('endobj')
+          end
+          #Outline root
+          newobj()
+          @outlineRoot=self.n
+          out("<</Type /Outlines /First #{n} 0 R");
+          out("/Last #{n+lru[0]} 0 R>>");
+          out('endobj');
+        end
+
+        def putresources()
+          super
+          putbookmarks()
+        end
+
+        def putcatalog()
+          super
+          if(@outlines.size > 0)
+            out("/Outlines #{@outlineRoot} 0 R");
+            out('/PageMode /UseOutlines');
+          end
+        end
+      end
+
+      # fetch row values
+      def fetch_row_values(issue, query, level)
+        query.inline_columns.collect do |column|
+          s = if column.is_a?(QueryCustomFieldColumn)
+            cv = issue.custom_field_values.detect {|v| v.custom_field_id == column.custom_field.id}
+            show_value(cv)
+          else
+            value = issue.send(column.name)
+            if column.name == :subject
+              value = "  " * level + value
+            end
+            if value.is_a?(Date)
+              format_date(value)
+            elsif value.is_a?(Time)
+              format_time(value)
+            else
+              value
+            end
+          end
+          s.to_s
+        end
+      end
+
+      # calculate columns width
+      def calc_col_width(issues, query, table_width, pdf)
+        # calculate statistics
+        #  by captions
+        pdf.SetFontStyle('B',8)
+        col_padding = pdf.GetStringWidth('OO')
+        col_width_min = query.inline_columns.map {|v| pdf.GetStringWidth(v.caption) + col_padding}
+        col_width_max = Array.new(col_width_min)
+        col_width_avg = Array.new(col_width_min)
+        word_width_max = query.inline_columns.map {|c|
+          n = 10
+          c.caption.split.each {|w|
+            x = pdf.GetStringWidth(w) + col_padding
+            n = x if n < x
+          }
+          n
+        }
+
+        #  by properties of issues
+        pdf.SetFontStyle('',8)
+        col_padding = pdf.GetStringWidth('OO')
+        k = 1
+        issue_list(issues) {|issue, level|
+          k += 1
+          values = fetch_row_values(issue, query, level)
+          values.each_with_index {|v,i|
+            n = pdf.GetStringWidth(v) + col_padding
+            col_width_max[i] = n if col_width_max[i] < n
+            col_width_min[i] = n if col_width_min[i] > n
+            col_width_avg[i] += n
+            v.split.each {|w|
+              x = pdf.GetStringWidth(w) + col_padding
+              word_width_max[i] = x if word_width_max[i] < x
+            }
+          }
+        }
+        col_width_avg.map! {|x| x / k}
+
+        # calculate columns width
+        ratio = table_width / col_width_avg.inject(0) {|s,w| s += w}
+        col_width = col_width_avg.map {|w| w * ratio}
+
+        # correct max word width if too many columns
+        ratio = table_width / word_width_max.inject(0) {|s,w| s += w}
+        word_width_max.map! {|v| v * ratio} if ratio < 1
+
+        # correct and lock width of some columns
+        done = 1
+        col_fix = []
+        col_width.each_with_index do |w,i|
+          if w > col_width_max[i]
+            col_width[i] = col_width_max[i]
+            col_fix[i] = 1
+            done = 0
+          elsif w < word_width_max[i]
+            col_width[i] = word_width_max[i]
+            col_fix[i] = 1
+            done = 0
+          else
+            col_fix[i] = 0
+          end
+        end
+
+        # iterate while need to correct and lock coluns width
+        while done == 0
+          # calculate free & locked columns width
+          done = 1
+          fix_col_width = 0
+          free_col_width = 0
+          col_width.each_with_index do |w,i|
+            if col_fix[i] == 1
+              fix_col_width += w
+            else
+              free_col_width += w
+            end
+          end
+
+          # calculate column normalizing ratio
+          if free_col_width == 0
+            ratio = table_width / col_width.inject(0) {|s,w| s += w}
+          else
+            ratio = (table_width - fix_col_width) / free_col_width
+          end
+
+          # correct columns width
+          col_width.each_with_index do |w,i|
+            if col_fix[i] == 0
+              col_width[i] = w * ratio
+
+              # check if column width less then max word width
+              if col_width[i] < word_width_max[i]
+                col_width[i] = word_width_max[i]
+                col_fix[i] = 1
+                done = 0
+              elsif col_width[i] > col_width_max[i]
+                col_width[i] = col_width_max[i]
+                col_fix[i] = 1
+                done = 0
+              end
+            end
+          end
+        end
+        col_width
+      end
+
+      def render_table_header(pdf, query, col_width, row_height, table_width)
+        # headers
+        pdf.SetFontStyle('B',8)
+        pdf.SetFillColor(230, 230, 230)
+
+        # render it background to find the max height used
+        base_x = pdf.GetX
+        base_y = pdf.GetY
+        max_height = issues_to_pdf_write_cells(pdf, query.inline_columns, col_width, row_height, true)
+        pdf.Rect(base_x, base_y, table_width, max_height, 'FD');
+        pdf.SetXY(base_x, base_y);
+
+        # write the cells on page
+        issues_to_pdf_write_cells(pdf, query.inline_columns, col_width, row_height, true)
+        issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, 0, col_width)
+        pdf.SetY(base_y + max_height);
+
+        # rows
+        pdf.SetFontStyle('',8)
+        pdf.SetFillColor(255, 255, 255)
+      end
+
+      # Returns a PDF string of a list of issues
+      def issues_to_pdf(issues, project, query)
+        pdf = ITCPDF.new(current_language, "L")
+        title = query.new_record? ? l(:label_issue_plural) : query.name
+        title = "#{project} - #{title}" if project
+        pdf.SetTitle(title)
+        pdf.alias_nb_pages
+        pdf.footer_date = format_date(Date.today)
+        pdf.SetAutoPageBreak(false)
+        pdf.AddPage("L")
+
+        # Landscape A4 = 210 x 297 mm
+        page_height   = 210
+        page_width    = 297
+        left_margin   = 10
+        right_margin  = 10
+        bottom_margin = 20
+        row_height    = 4
+
+        # column widths
+        table_width = page_width - right_margin - left_margin
+        col_width = []
+        unless query.inline_columns.empty?
+          col_width = calc_col_width(issues, query, table_width, pdf)
+          table_width = col_width.inject(0) {|s,v| s += v}
+        end
+
+        # use full width if the description is displayed
+        if table_width > 0 && query.has_column?(:description)
+          col_width = col_width.map {|w| w * (page_width - right_margin - left_margin) / table_width}
+          table_width = col_width.inject(0) {|s,v| s += v}
+        end
+
+        # title
+        pdf.SetFontStyle('B',11)
+        pdf.RDMCell(190,10, title)
+        pdf.Ln
+        render_table_header(pdf, query, col_width, row_height, table_width)
+        previous_group = false
+        issue_list(issues) do |issue, level|
+          if query.grouped? &&
+               (group = query.group_by_column.value(issue)) != previous_group
+            pdf.SetFontStyle('B',10)
+            group_label = group.blank? ? 'None' : group.to_s.dup
+            group_label << " (#{query.issue_count_by_group[group]})"
+            pdf.Bookmark group_label, 0, -1
+            pdf.RDMCell(table_width, row_height * 2, group_label, 1, 1, 'L')
+            pdf.SetFontStyle('',8)
+            previous_group = group
+          end
+
+          # fetch row values
+          col_values = fetch_row_values(issue, query, level)
+
+          # render it off-page to find the max height used
+          base_x = pdf.GetX
+          base_y = pdf.GetY
+          pdf.SetY(2 * page_height)
+          max_height = issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
+          pdf.SetXY(base_x, base_y)
+
+          # make new page if it doesn't fit on the current one
+          space_left = page_height - base_y - bottom_margin
+          if max_height > space_left
+            pdf.AddPage("L")
+            render_table_header(pdf, query, col_width, row_height, table_width)
+            base_x = pdf.GetX
+            base_y = pdf.GetY
+          end
+
+          # write the cells on page
+          issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
+          issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, 0, col_width)
+          pdf.SetY(base_y + max_height);
+
+          if query.has_column?(:description) && issue.description?
+            pdf.SetX(10)
+            pdf.SetAutoPageBreak(true, 20)
+            pdf.RDMwriteHTMLCell(0, 5, 10, 0, issue.description.to_s, issue.attachments, "LRBT")
+            pdf.SetAutoPageBreak(false)
+          end
+        end
+
+        if issues.size == Setting.issues_export_limit.to_i
+          pdf.SetFontStyle('B',10)
+          pdf.RDMCell(0, row_height, '...')
+        end
+        pdf.Output
+      end
+
+      # Renders MultiCells and returns the maximum height used
+      def issues_to_pdf_write_cells(pdf, col_values, col_widths,
+                                    row_height, head=false)
+        base_y = pdf.GetY
+        max_height = row_height
+        col_values.each_with_index do |column, i|
+          col_x = pdf.GetX
+          if head == true
+            pdf.RDMMultiCell(col_widths[i], row_height, column.caption, "T", 'L', 1)
+          else
+            pdf.RDMMultiCell(col_widths[i], row_height, column, "T", 'L', 1)
+          end
+          max_height = (pdf.GetY - base_y) if (pdf.GetY - base_y) > max_height
+          pdf.SetXY(col_x + col_widths[i], base_y);
+        end
+        return max_height
+      end
+
+      # Draw lines to close the row (MultiCell border drawing in not uniform)
+      #
+      #  parameter "col_id_width" is not used. it is kept for compatibility.
+      def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y,
+                                     col_id_width, col_widths)
+        col_x = top_x
+        pdf.Line(col_x, top_y, col_x, lower_y)    # id right border
+        col_widths.each do |width|
+          col_x += width
+          pdf.Line(col_x, top_y, col_x, lower_y)  # columns right border
+        end
+        pdf.Line(top_x, top_y, top_x, lower_y)    # left border
+        pdf.Line(top_x, lower_y, col_x, lower_y)  # bottom border
+      end
+
+      # Returns a PDF string of a single issue
+      def issue_to_pdf(issue, assoc={})
+        pdf = ITCPDF.new(current_language)
+        pdf.SetTitle("#{issue.project} - #{issue.tracker} ##{issue.id}")
+        pdf.alias_nb_pages
+        pdf.footer_date = format_date(Date.today)
+        pdf.AddPage
+        pdf.SetFontStyle('B',11)
+        buf = "#{issue.project} - #{issue.tracker} ##{issue.id}"
+        pdf.RDMMultiCell(190, 5, buf)
+        pdf.SetFontStyle('',8)
+        base_x = pdf.GetX
+        i = 1
+        issue.ancestors.visible.each do |ancestor|
+          pdf.SetX(base_x + i)
+          buf = "#{ancestor.tracker} # #{ancestor.id} (#{ancestor.status.to_s}): #{ancestor.subject}"
+          pdf.RDMMultiCell(190 - i, 5, buf)
+          i += 1 if i < 35
+        end
+        pdf.SetFontStyle('B',11)
+        pdf.RDMMultiCell(190 - i, 5, issue.subject.to_s)
+        pdf.SetFontStyle('',8)
+        pdf.RDMMultiCell(190, 5, "#{format_time(issue.created_on)} - #{issue.author}")
+        pdf.Ln
+
+        left = []
+        left << [l(:field_status), issue.status]
+        left << [l(:field_priority), issue.priority]
+        left << [l(:field_assigned_to), issue.assigned_to] unless issue.disabled_core_fields.include?('assigned_to_id')
+        left << [l(:field_category), issue.category] unless issue.disabled_core_fields.include?('category_id')
+        left << [l(:field_fixed_version), issue.fixed_version] unless issue.disabled_core_fields.include?('fixed_version_id')
+
+        right = []
+        right << [l(:field_start_date), format_date(issue.start_date)] unless issue.disabled_core_fields.include?('start_date')
+        right << [l(:field_due_date), format_date(issue.due_date)] unless issue.disabled_core_fields.include?('due_date')
+        right << [l(:field_done_ratio), "#{issue.done_ratio}%"] unless issue.disabled_core_fields.include?('done_ratio')
+        right << [l(:field_estimated_hours), l_hours(issue.estimated_hours)] unless issue.disabled_core_fields.include?('estimated_hours')
+        right << [l(:label_spent_time), l_hours(issue.total_spent_hours)] if User.current.allowed_to?(:view_time_entries, issue.project)
+
+        rows = left.size > right.size ? left.size : right.size
+        while left.size < rows
+          left << nil
+        end
+        while right.size < rows
+          right << nil
+        end
+
+        half = (issue.custom_field_values.size / 2.0).ceil
+        issue.custom_field_values.each_with_index do |custom_value, i|
+          (i < half ? left : right) << [custom_value.custom_field.name, show_value(custom_value)]
+        end
+
+        rows = left.size > right.size ? left.size : right.size
+        rows.times do |i|
+          item = left[i]
+          pdf.SetFontStyle('B',9)
+          pdf.RDMCell(35,5, item ? "#{item.first}:" : "", i == 0 ? "LT" : "L")
+          pdf.SetFontStyle('',9)
+          pdf.RDMCell(60,5, item ? item.last.to_s : "", i == 0 ? "RT" : "R")
+
+          item = right[i]
+          pdf.SetFontStyle('B',9)
+          pdf.RDMCell(35,5, item ? "#{item.first}:" : "", i == 0 ? "LT" : "L")
+          pdf.SetFontStyle('',9)
+          pdf.RDMCell(60,5, item ? item.last.to_s : "", i == 0 ? "RT" : "R")
+          pdf.Ln
+        end
+
+        pdf.SetFontStyle('B',9)
+        pdf.RDMCell(35+155, 5, l(:field_description), "LRT", 1)
+        pdf.SetFontStyle('',9)
+
+        # Set resize image scale
+        pdf.SetImageScale(1.6)
+        pdf.RDMwriteHTMLCell(35+155, 5, 0, 0,
+              issue.description.to_s, issue.attachments, "LRB")
+
+        unless issue.leaf?
+          # for CJK
+          truncate_length = ( l(:general_pdf_encoding).upcase == "UTF-8" ? 90 : 65 )
+
+          pdf.SetFontStyle('B',9)
+          pdf.RDMCell(35+155,5, l(:label_subtask_plural) + ":", "LTR")
+          pdf.Ln
+          issue_list(issue.descendants.visible.sort_by(&:lft)) do |child, level|
+            buf = truncate("#{child.tracker} # #{child.id}: #{child.subject}",
+                           :length => truncate_length)
+            level = 10 if level >= 10
+            pdf.SetFontStyle('',8)
+            pdf.RDMCell(35+135,5, (level >=1 ? "  " * level : "") + buf, "L")
+            pdf.SetFontStyle('B',8)
+            pdf.RDMCell(20,5, child.status.to_s, "R")
+            pdf.Ln
+          end
+        end
+
+        relations = issue.relations.select { |r| r.other_issue(issue).visible? }
+        unless relations.empty?
+          # for CJK
+          truncate_length = ( l(:general_pdf_encoding).upcase == "UTF-8" ? 80 : 60 )
+
+          pdf.SetFontStyle('B',9)
+          pdf.RDMCell(35+155,5, l(:label_related_issues) + ":", "LTR")
+          pdf.Ln
+          relations.each do |relation|
+            buf = ""
+            buf += "#{l(relation.label_for(issue))} "
+            if relation.delay && relation.delay != 0
+              buf += "(#{l('datetime.distance_in_words.x_days', :count => relation.delay)}) "
+            end
+            if Setting.cross_project_issue_relations?
+              buf += "#{relation.other_issue(issue).project} - "
+            end
+            buf += "#{relation.other_issue(issue).tracker}" +
+                   " # #{relation.other_issue(issue).id}: #{relation.other_issue(issue).subject}"
+            buf = truncate(buf, :length => truncate_length)
+            pdf.SetFontStyle('', 8)
+            pdf.RDMCell(35+155-60, 5, buf, "L")
+            pdf.SetFontStyle('B',8)
+            pdf.RDMCell(20,5, relation.other_issue(issue).status.to_s, "")
+            pdf.RDMCell(20,5, format_date(relation.other_issue(issue).start_date), "")
+            pdf.RDMCell(20,5, format_date(relation.other_issue(issue).due_date), "R")
+            pdf.Ln
+          end
+        end
+        pdf.RDMCell(190,5, "", "T")
+        pdf.Ln
+
+        if issue.changesets.any? &&
+             User.current.allowed_to?(:view_changesets, issue.project)
+          pdf.SetFontStyle('B',9)
+          pdf.RDMCell(190,5, l(:label_associated_revisions), "B")
+          pdf.Ln
+          for changeset in issue.changesets
+            pdf.SetFontStyle('B',8)
+            csstr  = "#{l(:label_revision)} #{changeset.format_identifier} - "
+            csstr += format_time(changeset.committed_on) + " - " + changeset.author.to_s
+            pdf.RDMCell(190, 5, csstr)
+            pdf.Ln
+            unless changeset.comments.blank?
+              pdf.SetFontStyle('',8)
+              pdf.RDMwriteHTMLCell(190,5,0,0,
+                    changeset.comments.to_s, issue.attachments, "")
+            end
+            pdf.Ln
+          end
+        end
+
+        if assoc[:journals].present?
+          pdf.SetFontStyle('B',9)
+          pdf.RDMCell(190,5, l(:label_history), "B")
+          pdf.Ln
+          assoc[:journals].each do |journal|
+            pdf.SetFontStyle('B',8)
+            title = "##{journal.indice} - #{format_time(journal.created_on)} - #{journal.user}"
+            title << " (#{l(:field_private_notes)})" if journal.private_notes?
+            pdf.RDMCell(190,5, title)
+            pdf.Ln
+            pdf.SetFontStyle('I',8)
+            details_to_strings(journal.details, true).each do |string|
+              pdf.RDMMultiCell(190,5, "- " + string)
+            end
+            if journal.notes?
+              pdf.Ln unless journal.details.empty?
+              pdf.SetFontStyle('',8)
+              pdf.RDMwriteHTMLCell(190,5,0,0,
+                    journal.notes.to_s, issue.attachments, "")
+            end
+            pdf.Ln
+          end
+        end
+
+        if issue.attachments.any?
+          pdf.SetFontStyle('B',9)
+          pdf.RDMCell(190,5, l(:label_attachment_plural), "B")
+          pdf.Ln
+          for attachment in issue.attachments
+            pdf.SetFontStyle('',8)
+            pdf.RDMCell(80,5, attachment.filename)
+            pdf.RDMCell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
+            pdf.RDMCell(25,5, format_date(attachment.created_on),0,0,"R")
+            pdf.RDMCell(65,5, attachment.author.name,0,0,"R")
+            pdf.Ln
+          end
+        end
+        pdf.Output
+      end
+
+      # Returns a PDF string of a set of wiki pages
+      def wiki_pages_to_pdf(pages, project)
+        pdf = ITCPDF.new(current_language)
+        pdf.SetTitle(project.name)
+        pdf.alias_nb_pages
+        pdf.footer_date = format_date(Date.today)
+        pdf.AddPage
+        pdf.SetFontStyle('B',11)
+        pdf.RDMMultiCell(190,5, project.name)
+        pdf.Ln
+        # Set resize image scale
+        pdf.SetImageScale(1.6)
+        pdf.SetFontStyle('',9)
+        write_page_hierarchy(pdf, pages.group_by(&:parent_id))
+        pdf.Output
+      end
+
+      # Returns a PDF string of a single wiki page
+      def wiki_page_to_pdf(page, project)
+        pdf = ITCPDF.new(current_language)
+        pdf.SetTitle("#{project} - #{page.title}")
+        pdf.alias_nb_pages
+        pdf.footer_date = format_date(Date.today)
+        pdf.AddPage
+        pdf.SetFontStyle('B',11)
+        pdf.RDMMultiCell(190,5,
+             "#{project} - #{page.title} - # #{page.content.version}")
+        pdf.Ln
+        # Set resize image scale
+        pdf.SetImageScale(1.6)
+        pdf.SetFontStyle('',9)
+        write_wiki_page(pdf, page)
+        pdf.Output
+      end
+
+      def write_page_hierarchy(pdf, pages, node=nil, level=0)
+        if pages[node]
+          pages[node].each do |page|
+            if @new_page
+              pdf.AddPage
+            else
+              @new_page = true
+            end
+            pdf.Bookmark page.title, level
+            write_wiki_page(pdf, page)
+            write_page_hierarchy(pdf, pages, page.id, level + 1) if pages[page.id]
+          end
+        end
+      end
+
+      def write_wiki_page(pdf, page)
+        pdf.RDMwriteHTMLCell(190,5,0,0,
+              page.content.text.to_s, page.attachments, 0)
+        if page.attachments.any?
+          pdf.Ln
+          pdf.SetFontStyle('B',9)
+          pdf.RDMCell(190,5, l(:label_attachment_plural), "B")
+          pdf.Ln
+          for attachment in page.attachments
+            pdf.SetFontStyle('',8)
+            pdf.RDMCell(80,5, attachment.filename)
+            pdf.RDMCell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
+            pdf.RDMCell(25,5, format_date(attachment.created_on),0,0,"R")
+            pdf.RDMCell(65,5, attachment.author.name,0,0,"R")
+            pdf.Ln
+          end
+        end
+      end
+
+      class RDMPdfEncoding
+        def self.rdm_from_utf8(txt, encoding)
+          txt ||= ''
+          txt = Redmine::CodesetUtil.from_utf8(txt, encoding)
+          if txt.respond_to?(:force_encoding)
+            txt.force_encoding('ASCII-8BIT')
+          end
+          txt
+        end
+
+        def self.attach(attachments, filename, encoding)
+          filename_utf8 = Redmine::CodesetUtil.to_utf8(filename, encoding)
+          atta = nil
+          if filename_utf8 =~ /^[^\/"]+\.(gif|jpg|jpe|jpeg|png)$/i
+            atta = Attachment.latest_attach(attachments, filename_utf8)
+          end
+          if atta && atta.readable? && atta.visible?
+            return atta
+          else
+            return nil
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/79/791795b2319be82f4ccbdcd799aa17c64410dd34.svn-base
--- /dev/null
+++ b/.svn/pristine/79/791795b2319be82f4ccbdcd799aa17c64410dd34.svn-base
@@ -0,0 +1,126 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+namespace :redmine do
+  namespace :attachments do
+    desc 'Removes uploaded files left unattached after one day.'
+    task :prune => :environment do
+      Attachment.prune
+    end
+
+    desc 'Moves attachments stored at the root of the file directory (ie. created before Redmine 2.3) to their subdirectories'
+    task :move_to_subdirectories => :environment do
+      Attachment.move_from_root_to_target_directory
+    end
+  end
+
+  namespace :tokens do
+    desc 'Removes expired tokens.'
+    task :prune => :environment do
+      Token.destroy_expired
+    end
+  end
+
+  namespace :watchers do
+    desc 'Removes watchers from what they can no longer view.'
+    task :prune => :environment do
+      Watcher.prune
+    end
+  end
+
+  desc 'Fetch changesets from the repositories'
+  task :fetch_changesets => :environment do
+    Repository.fetch_changesets
+  end
+
+  desc 'Migrates and copies plugins assets.'
+  task :plugins do
+    Rake::Task["redmine:plugins:migrate"].invoke
+    Rake::Task["redmine:plugins:assets"].invoke
+  end
+
+  namespace :plugins do
+    desc 'Migrates installed plugins.'
+    task :migrate => :environment do
+      name = ENV['NAME']
+      version = nil
+      version_string = ENV['VERSION']
+      if version_string
+        if version_string =~ /^\d+$/
+          version = version_string.to_i
+          if name.nil?
+            abort "The VERSION argument requires a plugin NAME."
+          end
+        else
+          abort "Invalid VERSION #{version_string} given."
+        end
+      end
+
+      begin
+        Redmine::Plugin.migrate(name, version)
+      rescue Redmine::PluginNotFound
+        abort "Plugin #{name} was not found."
+      end
+
+      Rake::Task["db:schema:dump"].invoke
+    end
+
+    desc 'Copies plugins assets into the public directory.'
+    task :assets => :environment do
+      name = ENV['NAME']
+
+      begin
+        Redmine::Plugin.mirror_assets(name)
+      rescue Redmine::PluginNotFound
+        abort "Plugin #{name} was not found."
+      end
+    end
+
+    desc 'Runs the plugins tests.'
+    task :test do
+      Rake::Task["redmine:plugins:test:units"].invoke
+      Rake::Task["redmine:plugins:test:functionals"].invoke
+      Rake::Task["redmine:plugins:test:integration"].invoke
+    end
+
+    namespace :test do
+      desc 'Runs the plugins unit tests.'
+      Rake::TestTask.new :units => "db:test:prepare" do |t|
+        t.libs << "test"
+        t.verbose = true
+        t.pattern = "plugins/#{ENV['NAME'] || '*'}/test/unit/**/*_test.rb"
+      end
+
+      desc 'Runs the plugins functional tests.'
+      Rake::TestTask.new :functionals => "db:test:prepare" do |t|
+        t.libs << "test"
+        t.verbose = true
+        t.pattern = "plugins/#{ENV['NAME'] || '*'}/test/functional/**/*_test.rb"
+      end
+
+      desc 'Runs the plugins integration tests.'
+      Rake::TestTask.new :integration => "db:test:prepare" do |t|
+        t.libs << "test"
+        t.verbose = true
+        t.pattern = "plugins/#{ENV['NAME'] || '*'}/test/integration/**/*_test.rb"
+      end
+    end
+  end
+end
+
+# Load plugins' rake tasks
+Dir[File.join(Rails.root, "plugins/*/lib/tasks/**/*.rake")].sort.each { |ext| load ext }
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/79/79764e68981f37bed805c67099bd3a957d4119fe.svn-base
--- a/.svn/pristine/79/79764e68981f37bed805c67099bd3a957d4119fe.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-// ** I18N
-
-// Calendar EU language
-// Author: Ales Zabala Alava (Shagi), <shagi@gisa-elkartea.org>
-// 2010-01-25
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Igandea",
- "Astelehena",
- "Asteartea",
- "Asteazkena",
- "Osteguna",
- "Ostirala",
- "Larunbata",
- "Igandea");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Ig.",
- "Al.",
- "Ar.",
- "Az.",
- "Og.",
- "Or.",
- "La.",
- "Ig.");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("Urtarrila",
- "Otsaila",
- "Martxoa",
- "Apirila",
- "Maiatza",
- "Ekaina",
- "Uztaila",
- "Abuztua",
- "Iraila",
- "Urria",
- "Azaroa",
- "Abendua");
-
-// short month names
-Calendar._SMN = new Array
-("Urt",
- "Ots",
- "Mar",
- "Api",
- "Mai",
- "Eka",
- "Uzt",
- "Abu",
- "Ira",
- "Urr",
- "Aza",
- "Abe");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Egutegiari buruz";
-
-Calendar._TT["ABOUT"] =
-"DHTML Data/Ordu Hautatzailea\n" +
-"(c) dynarch.com 2002-2005 / Egilea: Mihai Bazon\n" + // don't translate this this ;-)
-"Azken bertsiorako: http://www.dynarch.com/projects/calendar/\n" +
-"GNU LGPL Lizentziapean banatuta. Ikusi http://gnu.org/licenses/lgpl.html zehaztasunentzako." +
-"\n\n" +
-"Data hautapena:\n" +
-"- Erabili \xab, \xbb botoiak urtea hautatzeko\n" +
-"- Erabili " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " botoiak hilabeteak hautatzeko\n" +
-"- Mantendu saguaren botoia edo goiko edozein botoi hautapena bizkortzeko.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Ordu hautapena:\n" +
-"- Klikatu orduaren edozein zati handitzeko\n" +
-"- edo Shift-klikatu txikiagotzeko\n" +
-"- edo klikatu eta arrastatu hautapena bizkortzeko.";
-
-Calendar._TT["PREV_YEAR"] = "Aurreko urtea (mantendu menuarentzako)";
-Calendar._TT["PREV_MONTH"] = "Aurreko hilabetea (mantendu menuarentzako)";
-Calendar._TT["GO_TODAY"] = "Joan Gaur-era";
-Calendar._TT["NEXT_MONTH"] = "Hurrengo hilabetea (mantendu menuarentzako)";
-Calendar._TT["NEXT_YEAR"] = "Hurrengo urtea (mantendu menuarentzako)";
-Calendar._TT["SEL_DATE"] = "Data hautatu";
-Calendar._TT["DRAG_TO_MOVE"] = "Arrastatu mugitzeko";
-Calendar._TT["PART_TODAY"] = " (gaur)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Erakutsi %s lehenbizi";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Itxi";
-Calendar._TT["TODAY"] = "Gaur";
-Calendar._TT["TIME_PART"] = "(Shift-)Klikatu edo arrastatu balioa aldatzeko";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Ordua:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/79/798951d93ef15b8ef54ff1fdd4cd90be5520c718.svn-base
--- a/.svn/pristine/79/798951d93ef15b8ef54ff1fdd4cd90be5520c718.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-<h2><%=l(:label_information_plural)%></h2>
-
-<p><strong><%= Redmine::Info.versioned_name %></strong> (<%= @db_adapter_name %>)</p>
-
-<table class="list">
-<% @checklist.each do |label, result| %>
-  <tr class="<%= cycle 'odd', 'even' %>">
-    <td><%= l(label) %></td>
-    <td width="30px"><%= image_tag((result ? 'true.png' : 'exclamation.png'),
-                                    :style => "vertical-align:bottom;") %></td>
-  </tr>
-<% end %>
-</table>
-
-<% html_title(l(:label_information_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/79/79c8a939d3701e3feac652838cc1b0649abfd617.svn-base
--- a/.svn/pristine/79/79c8a939d3701e3feac652838cc1b0649abfd617.svn-base
+++ /dev/null
@@ -1,155 +0,0 @@
-<script type="text/javascript">
-//<![CDATA[
-function add_filter() {
-  select = $('add_filter_select');
-  field = select.value
-  Element.show('tr_' +  field);
-  check_box = $('cb_' + field);
-  check_box.checked = true;
-  toggle_filter(field);
-  select.selectedIndex = 0;
-
-  for (i=0; i<select.options.length; i++) {
-    if (select.options[i].value == field) {
-      select.options[i].disabled = true;
-    }
-  }
-}
-
-function toggle_filter(field) {
-  check_box = $('cb_' + field);
-  if (check_box.checked) {
-    Element.show("operators_" + field);
-    Form.Element.enable("operators_" + field);
-    toggle_operator(field);
-  } else {
-    Element.hide("operators_" + field);
-    Form.Element.disable("operators_" + field);
-    enableValues(field, []);
-  }
-}
-
-function enableValues(field, indexes) {
-  var f = $$(".values_" + field);
-  for(var i=0;i<f.length;i++) {
-    if (indexes.include(i)) {
-      Form.Element.enable(f[i]);
-      f[i].up('span').show();
-    } else {
-      f[i].value = '';
-      Form.Element.disable(f[i]);
-      f[i].up('span').hide();
-    }
-  }
-  if (indexes.length > 0) {
-    Element.show("div_values_" + field);
-  } else {
-    Element.hide("div_values_" + field);
-  }
-}
-
-function toggle_operator(field) {
-  operator = $("operators_" + field);
-  switch (operator.value) {
-    case "!*":
-    case "*":
-    case "t":
-    case "w":
-    case "o":
-    case "c":
-      enableValues(field, []);
-      break;
-    case "><":
-      enableValues(field, [0,1]);
-      break;
-    case "<t+":
-    case ">t+":
-    case "t+":
-    case ">t-":
-    case "<t-":
-    case "t-":
-      enableValues(field, [2]);
-      break;
-    default:
-      enableValues(field, [0]);
-      break;
-  }
-}
-
-function toggle_multi_select(el) {
-  var select = $(el);
-  if (select.multiple == true) {
-    select.multiple = false;
-  } else {
-    select.multiple = true;
-  }
-}
-
-function submit_query_form(id) {
-  selectAllOptions("selected_columns");
-  $(id).submit();
-}
-
-function apply_filters_observer() {
-  $$("#query_form input[type=text]").invoke("observe", "keypress", function(e){
-    if(e.keyCode == Event.KEY_RETURN) {
-      submit_query_form("query_form");
-    }
-  });
-}
-Event.observe(document,"dom:loaded", apply_filters_observer);
-//]]>
-</script>
-
-<table width="100%">
-<tr>
-<td>
-<table>
-<% query.available_filters.sort{|a,b| a[1][:order]<=>b[1][:order]}.each do |filter| %>
-    <% field = filter[0]
-       options = filter[1] %>
-    <tr <%= 'style="display:none;"' unless query.has_filter?(field) %> id="tr_<%= field %>" class="filter">
-    <td class="field">
-        <%= check_box_tag 'f[]', field, query.has_filter?(field), :onclick => "toggle_filter('#{field}');", :id => "cb_#{field}" %>
-        <label for="cb_<%= field %>"><%= filter[1][:name] || l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) %></label>
-    </td>
-    <td class="operator">
-        <%= label_tag "op_#{field}", l(:description_filter), :class => "hidden-for-sighted" %>
-        <%= select_tag "op[#{field}]", options_for_select(operators_for_select(options[:type]),
-                        query.operator_for(field)), :id => "operators_#{field}",
-                        :onchange => "toggle_operator('#{field}');" %>
-    </td>
-    <td class="values">
-    <div id="div_values_<%= field %>" style="display:none;">
-    <% case options[:type]
-    when :list, :list_optional, :list_status, :list_subprojects %>
-        <span class="span_values_<%= field %>">
-          <%= select_tag "v[#{field}][]", options_for_select(options[:values], query.values_for(field)), :class => "values_#{field}", :id => "values_#{field}_1", :multiple => (query.values_for(field) && query.values_for(field).length > 1) %>
-          <%= link_to_function image_tag('bullet_toggle_plus.png'), "toggle_multi_select('values_#{field}_1');" %>
-        </span>
-    <% when :date, :date_past %>
-        <span class="span_values_<%= field %>"><%= text_field_tag "v[#{field}][]", query.value_for(field), :size => 10, :class => "values_#{field}", :id => "values_#{field}_1" %> <%= calendar_for "values_#{field}_1" %></span>
-        <span class="span_values_<%= field %>"><%= text_field_tag "v[#{field}][]", query.value_for(field, 1), :size => 10, :class => "values_#{field}", :id => "values_#{field}_2" %> <%= calendar_for "values_#{field}_2" %></span>
-        <span class="span_values_<%= field %>"><%= text_field_tag "v[#{field}][]", query.value_for(field), :size => 3, :class => "values_#{field}" %> <%= l(:label_day_plural) %></span>
-    <% when :string, :text %>
-        <span class="span_values_<%= field %>"><%= text_field_tag "v[#{field}][]", query.value_for(field), :class => "values_#{field}", :id => "values_#{field}", :size => 30 %></span>
-    <% when :integer, :float %>
-        <span class="span_values_<%= field %>"><%= text_field_tag "v[#{field}][]", query.value_for(field), :class => "values_#{field}", :id => "values_#{field}_1", :size => 6 %></span>
-        <span class="span_values_<%= field %>"><%= text_field_tag "v[#{field}][]", query.value_for(field, 1), :class => "values_#{field}", :id => "values_#{field}_2", :size => 6 %></span>
-    <% end %>
-    </div>
-    <script type="text/javascript">toggle_filter('<%= field %>');</script>
-    </td>
-    </tr>
-<% end %>
-</table>
-</td>
-<td class="add-filter">
-<%= label_tag('add_filter_select', l(:label_filter_add)) %>
-<%= select_tag 'add_filter_select', options_for_select([["",""]] + query.available_filters.sort{|a,b| a[1][:order]<=>b[1][:order]}.collect{|field| [ field[1][:name] || l(("field_"+field[0].to_s.gsub(/_id$/, "")).to_sym), field[0]] unless query.has_filter?(field[0])}.compact),
-                                    :onchange => "add_filter();",
-                                    :name => nil %>
-</td>
-</tr>
-</table>
-<%= hidden_field_tag 'f[]', '' %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/79/79e517db7aa41460bc02061dfd2de5b4541e346b.svn-base
--- /dev/null
+++ b/.svn/pristine/79/79e517db7aa41460bc02061dfd2de5b4541e346b.svn-base
@@ -0,0 +1,31 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingSearchTest < ActionController::IntegrationTest
+  def test_search
+    assert_routing(
+        { :method => 'get', :path => "/search" },
+        { :controller => 'search', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/foo/search" },
+        { :controller => 'search', :action => 'index', :id => 'foo' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/79/79ebb49968818fca414e007a7d073ecb0152e756.svn-base
--- a/.svn/pristine/79/79ebb49968818fca414e007a7d073ecb0152e756.svn-base
+++ /dev/null
@@ -1,71 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../../test_helper', __FILE__)
-
-begin
-  require 'mocha'
-
-  class SubversionAdapterTest < ActiveSupport::TestCase
-
-    if repository_configured?('subversion')
-      def setup
-        @adapter = Redmine::Scm::Adapters::SubversionAdapter.new(self.class.subversion_repository_url)
-      end
-
-      def test_client_version
-        v = Redmine::Scm::Adapters::SubversionAdapter.client_version
-        assert v.is_a?(Array)
-      end
-
-      def test_scm_version
-        to_test = { "svn, version 1.6.13 (r1002816)\n"  => [1,6,13],
-                    "svn, versione 1.6.13 (r1002816)\n" => [1,6,13],
-                    "1.6.1\n1.7\n1.8"                   => [1,6,1],
-                    "1.6.2\r\n1.8.1\r\n1.9.1"           => [1,6,2]}
-        to_test.each do |s, v|
-          test_scm_version_for(s, v)
-        end
-      end
-
-      def test_info_not_nil
-        assert_not_nil @adapter.info
-      end
-
-      def test_info_nil
-        adpt = Redmine::Scm::Adapters::SubversionAdapter.new(
-                  "file:///invalid/invalid/"
-                  )
-        assert_nil adpt.info
-      end
-
-      private
-
-      def test_scm_version_for(scm_version, version)
-        @adapter.class.expects(:scm_version_from_command_line).returns(scm_version)
-        assert_equal version, @adapter.class.svn_binary_version
-      end
-    else
-      puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
-      def test_fake; assert true end
-    end
-  end
-rescue LoadError
-  class SubversionMochaFake < ActiveSupport::TestCase
-    def test_fake; assert(false, "Requires mocha to run those tests")  end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7a017fdd06e31fbf6cfa542010617fca4f01cf26.svn-base
--- a/.svn/pristine/7a/7a017fdd06e31fbf6cfa542010617fca4f01cf26.svn-base
+++ /dev/null
@@ -1,88 +0,0 @@
-require 'digest/md5'
-require 'cgi'
-
-module GravatarHelper
-
-  # These are the options that control the default behavior of the public
-  # methods. They can be overridden during the actual call to the helper,
-  # or you can set them in your environment.rb as such:
-  #
-  #   # Allow racier gravatars
-  #   GravatarHelper::DEFAULT_OPTIONS[:rating] = 'R'
-  #
-  DEFAULT_OPTIONS = {
-    # The URL of a default image to display if the given email address does
-    # not have a gravatar.
-    :default => nil,
-    
-    # The default size in pixels for the gravatar image (they're square).
-    :size => 50,
-    
-    # The maximum allowed MPAA rating for gravatars. This allows you to 
-    # exclude gravatars that may be out of character for your site.
-    :rating => 'PG',
-    
-    # The alt text to use in the img tag for the gravatar.  Since it's a
-    # decorational picture, the alt text should be empty according to the
-    # XHTML specs.
-    :alt => '',
-
-    # The title text to use for the img tag for the gravatar.
-    :title => '',
-    
-    # The class to assign to the img tag for the gravatar.
-    :class => 'gravatar',
-    
-    # Whether or not to display the gravatars using HTTPS instead of HTTP
-    :ssl => false,
-  }
-  
-  # The methods that will be made available to your views.
-  module PublicMethods
-  
-    # Return the HTML img tag for the given user's gravatar. Presumes that 
-    # the given user object will respond_to "email", and return the user's
-    # email address.
-    def gravatar_for(user, options={})
-      gravatar(user.email, options)
-    end
-
-    # Return the HTML img tag for the given email address's gravatar.
-    def gravatar(email, options={})
-      src = h(gravatar_url(email, options))
-      options = DEFAULT_OPTIONS.merge(options)
-      [:class, :alt, :size, :title].each { |opt| options[opt] = h(options[opt]) }
-      "<img class=\"#{options[:class]}\" alt=\"#{options[:alt]}\" title=\"#{options[:title]}\" width=\"#{options[:size]}\" height=\"#{options[:size]}\" src=\"#{src}\" />"
-    end
-    
-    # Returns the base Gravatar URL for the given email hash. If ssl evaluates to true,
-    # a secure URL will be used instead. This is required when the gravatar is to be 
-    # displayed on a HTTPS site.
-    def gravatar_api_url(hash, ssl=false)
-      if ssl
-        "https://secure.gravatar.com/avatar/#{hash}"
-      else
-        "http://www.gravatar.com/avatar/#{hash}"
-      end
-    end
-
-    # Return the gravatar URL for the given email address.
-    def gravatar_url(email, options={})
-      email_hash = Digest::MD5.hexdigest(email)
-      options = DEFAULT_OPTIONS.merge(options)
-      options[:default] = CGI::escape(options[:default]) unless options[:default].nil?
-      gravatar_api_url(email_hash, options.delete(:ssl)).tap do |url|
-        opts = []
-        [:rating, :size, :default].each do |opt|
-          unless options[opt].nil?
-            value = h(options[opt])
-            opts << [opt, value].join('=')
-          end
-        end
-        url << "?#{opts.join('&')}" unless opts.empty?
-      end
-    end
-
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7a074cee45b6ea26f101ec0ee24551820d4e929e.svn-base
--- /dev/null
+++ b/.svn/pristine/7a/7a074cee45b6ea26f101ec0ee24551820d4e929e.svn-base
@@ -0,0 +1,176 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class CustomFieldsControllerTest < ActionController::TestCase
+  fixtures :custom_fields, :custom_values, :trackers, :users
+
+  def setup
+    @request.session[:user_id] = 1
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+  end
+
+  def test_new
+    custom_field_classes.each do |klass|
+      get :new, :type => klass.name
+      assert_response :success
+      assert_template 'new'
+      assert_kind_of klass, assigns(:custom_field)
+      assert_select 'form#custom_field_form' do
+        assert_select 'select#custom_field_field_format[name=?]', 'custom_field[field_format]'
+        assert_select 'input[type=hidden][name=type][value=?]', klass.name
+      end
+    end
+  end
+
+  def test_new_issue_custom_field
+    get :new, :type => 'IssueCustomField'
+    assert_response :success
+    assert_template 'new'
+    assert_select 'form#custom_field_form' do
+      assert_select 'select#custom_field_field_format[name=?]', 'custom_field[field_format]' do
+        assert_select 'option[value=user]', :text => 'User'
+        assert_select 'option[value=version]', :text => 'Version'
+      end
+      assert_select 'input[type=hidden][name=type][value=IssueCustomField]'
+    end
+  end
+
+  def test_default_value_should_be_an_input_for_string_custom_field
+    get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'string'}
+    assert_response :success
+    assert_select 'input[name=?]', 'custom_field[default_value]'
+  end
+
+  def test_default_value_should_be_a_textarea_for_text_custom_field
+    get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'text'}
+    assert_response :success
+    assert_select 'textarea[name=?]', 'custom_field[default_value]'
+  end
+
+  def test_default_value_should_be_a_checkbox_for_bool_custom_field
+    get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'bool'}
+    assert_response :success
+    assert_select 'input[name=?][type=checkbox]', 'custom_field[default_value]'
+  end
+
+  def test_default_value_should_not_be_present_for_user_custom_field
+    get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'user'}
+    assert_response :success
+    assert_select '[name=?]', 'custom_field[default_value]', 0
+  end
+
+  def test_new_js
+    get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'list'}, :format => 'js'
+    assert_response :success
+    assert_template 'new'
+    assert_equal 'text/javascript', response.content_type
+
+    field = assigns(:custom_field)
+    assert_equal 'list', field.field_format
+  end
+
+  def test_new_with_invalid_custom_field_class_should_render_404
+    get :new, :type => 'UnknownCustomField'
+    assert_response 404
+  end
+
+  def test_create_list_custom_field
+    assert_difference 'CustomField.count' do
+      post :create, :type => "IssueCustomField",
+                 :custom_field => {:name => "test_post_new_list",
+                                   :default_value => "",
+                                   :min_length => "0",
+                                   :searchable => "0",
+                                   :regexp => "",
+                                   :is_for_all => "1",
+                                   :possible_values => "0.1\n0.2\n",
+                                   :max_length => "0",
+                                   :is_filter => "0",
+                                   :is_required =>"0",
+                                   :field_format => "list",
+                                   :tracker_ids => ["1", ""]}
+    end
+    assert_redirected_to '/custom_fields?tab=IssueCustomField'
+    field = IssueCustomField.find_by_name('test_post_new_list')
+    assert_not_nil field
+    assert_equal ["0.1", "0.2"], field.possible_values
+    assert_equal 1, field.trackers.size
+  end
+
+  def test_create_with_failure
+    assert_no_difference 'CustomField.count' do
+      post :create, :type => "IssueCustomField", :custom_field => {:name => ''}
+    end
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_edit
+    get :edit, :id => 1
+    assert_response :success
+    assert_template 'edit'
+    assert_tag 'input', :attributes => {:name => 'custom_field[name]', :value => 'Database'}
+  end
+
+  def test_edit_invalid_custom_field_should_render_404
+    get :edit, :id => 99
+    assert_response 404
+  end
+
+  def test_update
+    put :update, :id => 1, :custom_field => {:name => 'New name'}
+    assert_redirected_to '/custom_fields?tab=IssueCustomField'
+
+    field = CustomField.find(1)
+    assert_equal 'New name', field.name
+  end
+
+  def test_update_with_failure
+    put :update, :id => 1, :custom_field => {:name => ''}
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_destroy
+    custom_values_count = CustomValue.count(:conditions => {:custom_field_id => 1})
+    assert custom_values_count > 0
+
+    assert_difference 'CustomField.count', -1 do
+      assert_difference 'CustomValue.count', - custom_values_count do
+        delete :destroy, :id => 1
+      end
+    end
+
+    assert_redirected_to '/custom_fields?tab=IssueCustomField'
+    assert_nil CustomField.find_by_id(1)
+    assert_nil CustomValue.find_by_custom_field_id(1)
+  end
+
+  def custom_field_classes
+    files = Dir.glob(File.join(Rails.root, 'app/models/*_custom_field.rb')).map {|f| File.basename(f).sub(/\.rb$/, '') }
+    classes = files.map(&:classify).map(&:constantize)
+    assert classes.size > 0
+    classes
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7a09a663c8bfe9a76d00f982be754422b428c51b.svn-base
--- a/.svn/pristine/7a/7a09a663c8bfe9a76d00f982be754422b428c51b.svn-base
+++ /dev/null
@@ -1,1061 +0,0 @@
-# Korean translations for Ruby on Rails 
-# by Kihyun Yoon(ddumbugie@gmail.com),http://plenum.textcube.com/
-# by John Hwang (jhwang@tavon.org),http://github.com/tavon
-# by Yonghwan SO(please insert your email), last update at 2009-09-11
-# by Ki Won Kim(xyz37@naver.com, http://xyz37.blog.me, https://x10.mine.nu/redmine), last update at 2012-02-01
-# last update at 2012-02-02 by Ki Won Kim
-ko:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y/%m/%d"
-      short: "%m/%d"
-      long: "%Yë…„ %mì›” %dì¼ (%a)"
-      
-    day_names: [ì¼ìš”ì¼, ì›”ìš”ì¼, í™”ìš”ì¼, ìˆ˜ìš”ì¼, ëª©ìš”ì¼, ê¸ˆìš”ì¼, í† ìš”ì¼]
-    abbr_day_names: [ì¼, ì›”, í™”, ìˆ˜, ëª©, ê¸ˆ, í† ]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, 1ì›”, 2ì›”, 3ì›”, 4ì›”, 5ì›”, 6ì›”, 7ì›”, 8ì›”, 9ì›”, 10ì›”, 11ì›”, 12ì›”]
-    abbr_month_names: [~, 1ì›”, 2ì›”, 3ì›”, 4ì›”, 5ì›”, 6ì›”, 7ì›”, 8ì›”, 9ì›”, 10ì›”, 11ì›”, 12ì›”]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%Y/%m/%d %H:%M:%S"
-      time: "%H:%M"
-      short: "%y/%m/%d %H:%M"
-      long: "%Yë…„ %Bì›” %dì¼, %Hì‹œ %Më¶„ %Sì´ˆ %Z"
-    am: "ì˜¤ì „"
-    pm: "ì˜¤í›„"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "30ì´ˆ"
-      less_than_x_seconds:
-        one:   "ì¼ì´ˆ ì´í•˜"
-        other: "%{count}ì´ˆ ì´í•˜"
-      x_seconds:
-        one:   "ì¼ì´ˆ"
-        other: "%{count}ì´ˆ"
-      less_than_x_minutes:
-        one:   "ì¼ë¶„ ì´í•˜"
-        other: "%{count}ë¶„ ì´í•˜"
-      x_minutes:
-        one:   "ì¼ë¶„"
-        other: "%{count}ë¶„"
-      about_x_hours:
-        one:   "ì•½ í•œì‹œê°„"
-        other: "ì•½ %{count}ì‹œê°„"
-      x_days:
-        one:   "í•˜ë£¨"
-        other: "%{count}ì¼"
-      about_x_months:
-        one:   "ì•½ í•œë‹¬"
-        other: "ì•½ %{count}ë‹¬"
-      x_months:
-        one:   "í•œë‹¬"
-        other: "%{count}ë‹¬"
-      about_x_years:
-        one:   "ì•½ ì¼ë…„"
-        other: "ì•½ %{count}ë…„"
-      over_x_years:
-        one:   "ì¼ë…„ ì´ìƒ"
-        other: "%{count}ë…„ ì´ìƒ"
-      almost_x_years:
-        one:   "ì•½ 1ë…„"
-        other: "ì•½ %{count}ë…„"
-    prompts:
-      year:   "ë…„"
-      month:  "ì›”"
-      day:    "ì¼"
-      hour:   "ì‹œ"
-      minute: "ë¶„"
-      second: "ì´ˆ"
-      
-  number:
-    # Used in number_with_delimiter()
-    # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
-    format:
-      # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
-      separator: "."
-      # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
-      delimiter: ","
-      # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
-      precision: 3
-      
-    # Used in number_to_currency()
-    currency:
-      format:
-        # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
-        format: "%u%n"
-        unit: "â‚©"
-        # These three are to override number.format and are optional
-        separator: "."
-        delimiter: ","
-        precision: 0
-        
-    # Used in number_to_percentage()
-    percentage:
-      format:
-        # These three are to override number.format and are optional
-        # separator: 
-        delimiter: ""
-        # precision: 
-        
-    # Used in number_to_precision()
-    precision:
-      format:
-        # These three are to override number.format and are optional
-        # separator:
-        delimiter: ""
-        # precision:
-        
-    # Used in number_to_human_size()
-    human:
-      format:
-        # These three are to override number.format and are optional
-        # separator: 
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-# Used in array.to_sentence.
-  support:
-    array:
-      words_connector: ", "
-      two_words_connector: "ê³¼ "
-      last_word_connector: ", "
-      sentence_connector: "ê·¸ë¦¬ê³ "
-      skip_last_comma: false
-        
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "í•œê°œì˜ ì˜¤ë¥˜ê°€ ë°œìƒí•´ %{model}ì„(ë¥¼) ì €ìž¥í•˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤."
-          other:  "%{count}ê°œì˜ ì˜¤ë¥˜ê°€ ë°œìƒí•´ %{model}ì„(ë¥¼) ì €ìž¥í•˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤."
-        # The variable :count is also available
-        body: "ë‹¤ìŒ í•­ëª©ì— ë¬¸ì œê°€ ë°œê²¬í–ˆìŠµë‹ˆë‹¤:"
-
-      messages:
-        inclusion: "ì€ ëª©ë¡ì— í¬í•¨ë˜ì–´ ìžˆì§€ ì•ŠìŠµë‹ˆë‹¤"
-        exclusion: "ì€ ì˜ˆì•½ë˜ì–´ ìžˆìŠµë‹ˆë‹¤"
-        invalid: "ì€ ìœ íš¨í•˜ì§€ ì•ŠìŠµë‹ˆë‹¤."
-        confirmation: "ì€ í™•ì¸ì´ ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤"
-        accepted: "ì€ ì¸ì •ë˜ì–´ì•¼ í•©ë‹ˆë‹¤"
-        empty: "ì€ ê¸¸ì´ê°€ 0ì´ì–´ì„œëŠ” ì•ˆë©ë‹ˆë‹¤."
-        blank: "ì€ ë¹ˆ ê°’ì´ì–´ì„œëŠ” ì•ˆ ë©ë‹ˆë‹¤"
-        too_long: "ì€ ë„ˆë¬´ ê¹ë‹ˆë‹¤ (ìµœëŒ€ %{count}ìž ê¹Œì§€)"
-        too_short: "ì€ ë„ˆë¬´ ì§§ìŠµë‹ˆë‹¤ (ìµœì†Œ %{count}ìž ê¹Œì§€)"
-        wrong_length: "ì€ ê¸¸ì´ê°€ í‹€ë ¸ìŠµë‹ˆë‹¤ (%{count}ìžì´ì–´ì•¼ í•©ë‹ˆë‹¤.)"
-        taken: "ì€ ì´ë¯¸ ì„ íƒëœ ê²ë‹ˆë‹¤"
-        not_a_number: "ì€ ìˆ«ìžê°€ ì•„ë‹™ë‹ˆë‹¤"
-        greater_than: "ì€ %{count}ë³´ë‹¤ ì»¤ì•¼ í•©ë‹ˆë‹¤."
-        greater_than_or_equal_to: "ì€ %{count}ë³´ë‹¤ í¬ê±°ë‚˜ ê°™ì•„ì•¼ í•©ë‹ˆë‹¤"
-        equal_to: "ì€ %{count}(ì™€)ê³¼ ê°™ì•„ì•¼ í•©ë‹ˆë‹¤"
-        less_than: "ì€ %{count}ë³´ë‹¤ ìž‘ì–´ì•¼ í•©ë‹ˆë‹¤"
-        less_than_or_equal_to: "ì€ %{count}ê³¼ ê°™ê±°ë‚˜ ì´í•˜ì„ ìš”êµ¬í•©ë‹ˆë‹¤"
-        odd: "ì€ í™€ìˆ˜ì—¬ì•¼ í•©ë‹ˆë‹¤"
-        even: "ì€ ì§ìˆ˜ì—¬ì•¼ í•©ë‹ˆë‹¤"
-        greater_than_start_date: "ëŠ” ì‹œìž‘ë‚ ì§œë³´ë‹¤ ì»¤ì•¼ í•©ë‹ˆë‹¤"
-        not_same_project: "ëŠ” ê°™ì€ í”„ë¡œì íŠ¸ì— ì†í•´ ìžˆì§€ ì•ŠìŠµë‹ˆë‹¤"
-        circular_dependency: "ì´ ê´€ê³„ëŠ” ìˆœí™˜ ì˜ì¡´ê´€ê³„ë¥¼ ë§Œë“¤ ìˆ˜ ìžˆìŠµë‹ˆë‹¤"
-        cant_link_an_issue_with_a_descendant: "ì¼ê°ì€ ê·¸ê²ƒì˜ í•˜ìœ„ ì¼ê°ê³¼ ì—°ê²°í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
-
-  actionview_instancetag_blank_option: ì„ íƒí•˜ì„¸ìš”
-  
-  general_text_No: 'ì•„ë‹ˆì˜¤'
-  general_text_Yes: 'ì˜ˆ'
-  general_text_no: 'ì•„ë‹ˆì˜¤'
-  general_text_yes: 'ì˜ˆ'
-  general_lang_name: 'í•œêµ­ì–´(Korean)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: CP949
-  general_pdf_encoding: CP949
-  general_first_day_of_week: '7'
-  
-  notice_account_updated: ê³„ì •ì´ ì„±ê³µì ìœ¼ë¡œ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤.
-  notice_account_invalid_creditentials: ìž˜ëª»ëœ ê³„ì • ë˜ëŠ” ë¹„ë°€ë²ˆí˜¸
-  notice_account_password_updated: ë¹„ë°€ë²ˆí˜¸ê°€ ìž˜ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤.
-  notice_account_wrong_password: ìž˜ëª»ëœ ë¹„ë°€ë²ˆí˜¸
-  notice_account_register_done: ê³„ì •ì´ ìž˜ ë§Œë“¤ì–´ì¡ŒìŠµë‹ˆë‹¤. ê³„ì •ì„ í™œì„±í™”í•˜ì‹œë ¤ë©´ ë°›ì€ ë©”ì¼ì˜ ë§í¬ë¥¼ í´ë¦­í•´ì£¼ì„¸ìš”.
-  notice_account_unknown_email: ì•Œë ¤ì§€ì§€ ì•Šì€ ì‚¬ìš©ìž.
-  notice_can_t_change_password: ì´ ê³„ì •ì€ ì™¸ë¶€ ì¸ì¦ì„ ì´ìš©í•©ë‹ˆë‹¤. ë¹„ë°€ë²ˆí˜¸ë¥¼ ë³€ê²½í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
-  notice_account_lost_email_sent: ìƒˆë¡œìš´ ë¹„ë°€ë²ˆí˜¸ë¥¼ ìœ„í•œ ë©”ì¼ì´ ë°œì†¡ë˜ì—ˆìŠµë‹ˆë‹¤.
-  notice_account_activated: ê³„ì •ì´ í™œì„±í™”ë˜ì—ˆìŠµë‹ˆë‹¤. ì´ì œ ë¡œê·¸ì¸ í•˜ì‹¤ìˆ˜ ìžˆìŠµë‹ˆë‹¤.
-  notice_successful_create: ìƒì„± ì„±ê³µ.
-  notice_successful_update: ë³€ê²½ ì„±ê³µ.
-  notice_successful_delete: ì‚­ì œ ì„±ê³µ.
-  notice_successful_connection: ì—°ê²° ì„±ê³µ.
-  notice_file_not_found: ìš”ì²­í•˜ì‹  íŽ˜ì´ì§€ëŠ” ì‚­ì œë˜ì—ˆê±°ë‚˜ ì˜®ê²¨ì¡ŒìŠµë‹ˆë‹¤.
-  notice_locking_conflict: ë‹¤ë¥¸ ì‚¬ìš©ìžì— ì˜í•´ì„œ ë°ì´í„°ê°€ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤.
-  notice_not_authorized: ì´ íŽ˜ì´ì§€ì— ì ‘ê·¼í•  ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤.
-  notice_email_sent: "%{value}ë‹˜ì—ê²Œ ë©”ì¼ì´ ë°œì†¡ë˜ì—ˆìŠµë‹ˆë‹¤."
-  notice_email_error: "ë©”ì¼ì„ ì „ì†¡í•˜ëŠ” ê³¼ì •ì— ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤. (%{value})"
-  notice_feeds_access_key_reseted: RSSì— ì ‘ê·¼ê°€ëŠ¥í•œ ì—´ì‡ (key)ê°€ ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤.
-  notice_failed_to_save_issues: "ì €ìž¥ì— ì‹¤íŒ¨í•˜ì˜€ìŠµë‹ˆë‹¤: ì‹¤íŒ¨ %{count}(ì„ íƒ %{total}): %{ids}."
-  notice_no_issue_selected: "ì¼ê°ì´ ì„ íƒë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤. ìˆ˜ì •í•˜ê¸° ì›í•˜ëŠ” ì¼ê°ì„ ì„ íƒí•˜ì„¸ìš”"
-  notice_account_pending: "ê³„ì •ì´ ë§Œë“¤ì–´ì¡Œìœ¼ë©° ê´€ë¦¬ìž ìŠ¹ì¸ ëŒ€ê¸°ì¤‘ìž…ë‹ˆë‹¤."
-  notice_default_data_loaded: ê¸°ë³¸ê°’ì„ ì„±ê³µì ìœ¼ë¡œ ì½ì–´ë“¤ì˜€ìŠµë‹ˆë‹¤.
-  notice_unable_delete_version: ì‚­ì œí•  ìˆ˜ ì—†ëŠ” ë²„ì „ìž…ë‹ˆë‹¤.
-  
-  error_can_t_load_default_data: "ê¸°ë³¸ê°’ì„ ì½ì–´ë“¤ì¼ ìˆ˜ ì—†ìŠµë‹ˆë‹¤.: %{value}"
-  error_scm_not_found: í•­ëª©ì´ë‚˜ ë¦¬ë¹„ì ¼ì´ ì €ìž¥ì†Œì— ì¡´ìž¬í•˜ì§€ ì•ŠìŠµë‹ˆë‹¤.
-  error_scm_command_failed: "ì €ìž¥ì†Œì— ì ‘ê·¼í•˜ëŠ” ë„ì¤‘ì— ì˜¤ë¥˜ê°€ ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤.: %{value}"
-  error_scm_annotate: "í•­ëª©ì´ ì—†ê±°ë‚˜ í–‰ë³„ ì´ë ¥ì„ ë³¼ ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
-  error_issue_not_found_in_project: 'ì¼ê°ì´ ì—†ê±°ë‚˜ ì´ í”„ë¡œì íŠ¸ì˜ ê²ƒì´ ì•„ë‹™ë‹ˆë‹¤.'
-
-  warning_attachments_not_saved: "%{count}ê°œ íŒŒì¼ì„ ì €ìž¥í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
-  
-  mail_subject_lost_password: "%{value} ë¹„ë°€ë²ˆí˜¸"
-  mail_body_lost_password: 'ë¹„ë°€ë²ˆí˜¸ë¥¼ ë³€ê²½í•˜ë ¤ë©´ ë‹¤ìŒ ë§í¬ë¥¼ í´ë¦­í•˜ì„¸ìš”.'
-  mail_subject_register: "%{value} ê³„ì • í™œì„±í™”"
-  mail_body_register: 'ê³„ì •ì„ í™œì„±í™”í•˜ë ¤ë©´ ë§í¬ë¥¼ í´ë¦­í•˜ì„¸ìš”.:'
-  mail_body_account_information_external: "ë¡œê·¸ì¸í•  ë•Œ %{value} ê³„ì •ì„ ì‚¬ìš©í•˜ì‹¤ ìˆ˜ ìžˆìŠµë‹ˆë‹¤."
-  mail_body_account_information: ê³„ì • ì •ë³´
-  mail_subject_account_activation_request: "%{value} ê³„ì • í™œì„±í™” ìš”ì²­"
-  mail_body_account_activation_request: "ìƒˆ ì‚¬ìš©ìž(%{value})ê°€ ë“±ë¡ë˜ì—ˆìŠµë‹ˆë‹¤. ê´€ë¦¬ìžë‹˜ì˜ ìŠ¹ì¸ì„ ê¸°ë‹¤ë¦¬ê³  ìžˆìŠµë‹ˆë‹¤.:"
-  mail_body_reminder: "ë‹¹ì‹ ì´ ë§¡ê³  ìžˆëŠ” ì¼ê° %{count}ê°œì˜ ì™„ë£Œ ê¸°í•œì´ %{days}ì¼ í›„ ìž…ë‹ˆë‹¤."
-  mail_subject_reminder: "ë‚´ì¼ì´ ë§Œê¸°ì¸ ì¼ê° %{count}ê°œ (%{days})"
-  mail_subject_wiki_content_added: "ìœ„í‚¤íŽ˜ì´ì§€ '%{id}'ì´(ê°€) ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
-  mail_subject_wiki_content_updated: "'ìœ„í‚¤íŽ˜ì´ì§€ %{id}'ì´(ê°€) ìˆ˜ì •ë˜ì—ˆìŠµë‹ˆë‹¤."
-  mail_body_wiki_content_added: "%{author}ì´(ê°€) ìœ„í‚¤íŽ˜ì´ì§€ '%{id}'ì„(ë¥¼) ì¶”ê°€í•˜ì˜€ìŠµë‹ˆë‹¤."
-  mail_body_wiki_content_updated: "%{author}ì´(ê°€) ìœ„í‚¤íŽ˜ì´ì§€ '%{id}'ì„(ë¥¼) ìˆ˜ì •í•˜ì˜€ìŠµë‹ˆë‹¤."
-  
-  gui_validation_error: ì—ëŸ¬
-  gui_validation_error_plural: "%{count}ê°œ ì—ëŸ¬"
-  
-  field_name: ì´ë¦„
-  field_description: ì„¤ëª…
-  field_summary: ìš”ì•½
-  field_is_required: í•„ìˆ˜
-  field_firstname: ì´ë¦„
-  field_lastname: ì„±
-  field_mail: ë©”ì¼
-  field_filename: íŒŒì¼
-  field_filesize: í¬ê¸°
-  field_downloads: ë‹¤ìš´ë¡œë“œ
-  field_author: ì €ìž
-  field_created_on: ë“±ë¡
-  field_updated_on: ë³€ê²½
-  field_field_format: í˜•ì‹
-  field_is_for_all: ëª¨ë“  í”„ë¡œì íŠ¸
-  field_possible_values: ê°€ëŠ¥í•œ ê°’ë“¤
-  field_regexp: ì •ê·œì‹
-  field_min_length: ìµœì†Œ ê¸¸ì´
-  field_max_length: ìµœëŒ€ ê¸¸ì´
-  field_value: ê°’
-  field_category: ë²”ì£¼
-  field_title: ì œëª©
-  field_project: í”„ë¡œì íŠ¸
-  field_issue: ì¼ê°
-  field_status: ìƒíƒœ
-  field_notes: ë§ê¸€
-  field_is_closed: ì™„ë£Œ ìƒíƒœ
-  field_is_default: ê¸°ë³¸ê°’
-  field_tracker: ìœ í˜•
-  field_subject: ì œëª©
-  field_due_date: ì™„ë£Œ ê¸°í•œ
-  field_assigned_to: ë‹´ë‹¹ìž
-  field_priority: ìš°ì„ ìˆœìœ„
-  field_fixed_version: ëª©í‘œë²„ì „
-  field_user: ì‚¬ìš©ìž
-  field_role: ì—­í• 
-  field_homepage: í™ˆíŽ˜ì´ì§€
-  field_is_public: ê³µê°œ
-  field_parent: ìƒìœ„ í”„ë¡œì íŠ¸
-  field_is_in_roadmap: ë¡œë“œë§µì— í‘œì‹œ
-  field_login: ë¡œê·¸ì¸
-  field_mail_notification: ë©”ì¼ ì•Œë¦¼
-  field_admin: ê´€ë¦¬ìž
-  field_last_login_on: ë§ˆì§€ë§‰ ë¡œê·¸ì¸
-  field_language: ì–¸ì–´
-  field_effective_date: ë‚ ì§œ
-  field_password: ë¹„ë°€ë²ˆí˜¸
-  field_new_password: ìƒˆ ë¹„ë°€ë²ˆí˜¸
-  field_password_confirmation: ë¹„ë°€ë²ˆí˜¸ í™•ì¸
-  field_version: ë²„ì „
-  field_type: ë°©ì‹
-  field_host: í˜¸ìŠ¤íŠ¸
-  field_port: í¬íŠ¸
-  field_account: ê³„ì •
-  field_base_dn: ê¸°ë³¸ DN
-  field_attr_login: ë¡œê·¸ì¸ ì†ì„±
-  field_attr_firstname: ì´ë¦„ ì†ì„±
-  field_attr_lastname: ì„± ì†ì„±
-  field_attr_mail: ë©”ì¼ ì†ì„±
-  field_onthefly: ë™ì  ì‚¬ìš©ìž ìƒì„±
-  field_start_date: ì‹œìž‘ì‹œê°„
-  field_done_ratio: ì§„ì²™ë„
-  field_auth_source: ì¸ì¦ ê³µê¸‰ìž
-  field_hide_mail: ë©”ì¼ ì£¼ì†Œ ìˆ¨ê¸°ê¸°
-  field_comments: ì„¤ëª…
-  field_url: URL
-  field_start_page: ì²« íŽ˜ì´ì§€
-  field_subproject: í•˜ìœ„ í”„ë¡œì íŠ¸
-  field_hours: ì‹œê°„
-  field_activity: ìž‘ì—…ì¢…ë¥˜
-  field_spent_on: ìž‘ì—…ì‹œê°„
-  field_identifier: ì‹ë³„ìž
-  field_is_filter: ê²€ìƒ‰ì¡°ê±´ìœ¼ë¡œ ì‚¬ìš©ë¨
-  field_issue_to_id: ì—°ê´€ëœ ì¼ê°
-  field_delay: ì§€ì—°
-  field_assignable: ì´ ì—­í• ì—ê²Œ ì¼ê°ì„ ë§¡ê¸¸ ìˆ˜ ìžˆìŒ
-  field_redirect_existing_links: ê¸°ì¡´ì˜ ë§í¬ë¡œ ëŒë ¤ë³´ëƒ„(redirect)
-  field_estimated_hours: ì¶”ì •ì‹œê°„
-  field_column_names: ì»¬ëŸ¼
-  field_default_value: ê¸°ë³¸ê°’
-  field_time_zone: ì‹œê°„ëŒ€
-  field_searchable: ê²€ìƒ‰ê°€ëŠ¥
-  field_comments_sorting: ëŒ“ê¸€ ì •ë ¬
-  field_parent_title: ìƒìœ„ ì œëª©
-  field_editable: íŽ¸ì§‘ê°€ëŠ¥
-  field_watcher: ì¼ê°ì§€í‚´ì´
-  field_identity_url: OpenID URL
-  field_content: ë‚´ìš©
-  field_group_by: ê²°ê³¼ë¥¼ ë¬¶ì–´ ë³´ì—¬ì¤„ ê¸°ì¤€
-  
-  setting_app_title: ë ˆë“œë§ˆì¸ ì œëª©
-  setting_app_subtitle: ë ˆë“œë§ˆì¸ ë¶€ì œëª©
-  setting_welcome_text: í™˜ì˜ ë©”ì‹œì§€
-  setting_default_language: ê¸°ë³¸ ì–¸ì–´
-  setting_login_required: ì¸ì¦ì´ í•„ìš”í•¨
-  setting_self_registration: ì‚¬ìš©ìž ì§ì ‘ë“±ë¡
-  setting_attachment_max_size: ìµœëŒ€ ì²¨ë¶€íŒŒì¼ í¬ê¸°
-  setting_issues_export_limit: ì¼ê° ë‚´ë³´ë‚´ê¸° ì œí•œ
-  setting_mail_from: ë°œì‹  ë©”ì¼ ì£¼ì†Œ
-  setting_bcc_recipients: ì°¸ì¡°ìžë“¤ì„ bccë¡œ ìˆ¨ê¸°ê¸°
-  setting_plain_text_mail: í…ìŠ¤íŠ¸ë§Œ (HTML ì—†ì´)
-  setting_host_name: í˜¸ìŠ¤íŠ¸ ì´ë¦„ê³¼ ê²½ë¡œ
-  setting_text_formatting: ë³¸ë¬¸ í˜•ì‹
-  setting_wiki_compression: ìœ„í‚¤ ì´ë ¥ ì••ì¶•
-  setting_feeds_limit: í”¼ë“œì— í¬í•¨í•  í•­ëª©ì˜ ìˆ˜
-  setting_default_projects_public: ìƒˆ í”„ë¡œì íŠ¸ë¥¼ ê³µê°œë¡œ ì„¤ì •
-  setting_autofetch_changesets: ì œì¶œ(commit)ëœ ë³€ê²½ë¬¶ìŒì„ ìžë™ìœ¼ë¡œ ê°€ì ¸ì˜¤ê¸°
-  setting_sys_api_enabled: ì €ìž¥ì†Œ ê´€ë¦¬ì— WSë¥¼ ì‚¬ìš©
-  setting_commit_ref_keywords: ì¼ê° ì°¸ì¡°ì— ì‚¬ìš©í•  í‚¤ì›Œë“œë“¤
-  setting_commit_fix_keywords: ì¼ê° í•´ê²°ì— ì‚¬ìš©í•  í‚¤ì›Œë“œë“¤ 
-  setting_autologin: ìžë™ ë¡œê·¸ì¸
-  setting_date_format: ë‚ ì§œ í˜•ì‹
-  setting_time_format: ì‹œê°„ í˜•ì‹
-  setting_cross_project_issue_relations: ë‹¤ë¥¸ í”„ë¡œì íŠ¸ì˜ ì¼ê°ê³¼ ì—°ê²°í•˜ëŠ” ê²ƒì„ í—ˆìš©
-  setting_issue_list_default_columns: ì¼ê° ëª©ë¡ì— í‘œì‹œí•  í•­ëª© 
-  setting_emails_footer: ë©”ì¼ ê¼¬ë¦¬
-  setting_protocol: í”„ë¡œí† ì½œ
-  setting_per_page_options: ëª©ë¡ì—ì„œ, í•œ íŽ˜ì´ì§€ì— í‘œì‹œí•  í–‰
-  setting_user_format: ì‚¬ìš©ìž í‘œì‹œ í˜•ì‹
-  setting_activity_days_default: í”„ë¡œì íŠ¸ ìž‘ì—…ë‚´ì—­ì— í‘œì‹œí•  ê¸°ê°„
-  setting_display_subprojects_issues: í•˜ìœ„ í”„ë¡œì íŠ¸ì˜ ì¼ê°ì„ í•¨ê»˜ í‘œì‹œ
-  setting_enabled_scm: "ì§€ì›í•  SCM(Source Control Management)"
-  setting_mail_handler_api_enabled: ìˆ˜ì‹  ë©”ì¼ì— WSë¥¼ í—ˆìš©
-  setting_mail_handler_api_key: API í‚¤
-  setting_sequential_project_identifiers: í”„ë¡œì íŠ¸ ì‹ë³„ìžë¥¼ ìˆœì°¨ì ìœ¼ë¡œ ìƒì„±
-  setting_gravatar_enabled: ê·¸ë¼ë°”íƒ€ ì‚¬ìš©ìž ì•„ì´ì½˜ ì‚¬ìš©
-  setting_diff_max_lines_displayed: ì°¨ì´ì (diff) ë³´ê¸°ì— í‘œì‹œí•  ìµœëŒ€ ì¤„ìˆ˜
-  setting_repository_log_display_limit: ì €ìž¥ì†Œ ë³´ê¸°ì— í‘œì‹œí•  ê°œì •íŒ ì´ë ¥ì˜ ìµœëŒ€ ê°¯ìˆ˜
-  setting_file_max_size_displayed: ë°”ë¡œ ë³´ì—¬ì¤„ í…ìŠ¤íŠ¸íŒŒì¼ì˜ ìµœëŒ€ í¬ê¸°
-  setting_openid: OpenID ë¡œê·¸ì¸ê³¼ ë“±ë¡ í—ˆìš©
-  setting_password_min_length: ìµœì†Œ ì•”í˜¸ ê¸¸ì´
-  setting_new_project_user_role_id: í”„ë¡œì íŠ¸ë¥¼ ë§Œë“  ì‚¬ìš©ìžì—ê²Œ ì£¼ì–´ì§ˆ ì—­í• 
-
-  permission_add_project: í”„ë¡œì íŠ¸ ìƒì„±
-  permission_edit_project: í”„ë¡œì íŠ¸ íŽ¸ì§‘
-  permission_select_project_modules: í”„ë¡œì íŠ¸ ëª¨ë“ˆ ì„ íƒ
-  permission_manage_members: êµ¬ì„±ì› ê´€ë¦¬
-  permission_manage_versions: ë²„ì „ ê´€ë¦¬
-  permission_manage_categories: ì¼ê° ë²”ì£¼ ê´€ë¦¬
-  permission_add_issues: ì¼ê° ì¶”ê°€
-  permission_edit_issues: ì¼ê° íŽ¸ì§‘
-  permission_manage_issue_relations: ì¼ê° ê´€ê³„ ê´€ë¦¬
-  permission_add_issue_notes: ë§ê¸€ ì¶”ê°€
-  permission_edit_issue_notes: ë§ê¸€ íŽ¸ì§‘
-  permission_edit_own_issue_notes: ë‚´ ë§ê¸€ íŽ¸ì§‘
-  permission_move_issues: ì¼ê° ì´ë™
-  permission_delete_issues: ì¼ê° ì‚­ì œ
-  permission_manage_public_queries: ê³µìš© ê²€ìƒ‰ì–‘ì‹ ê´€ë¦¬
-  permission_save_queries: ê²€ìƒ‰ì–‘ì‹ ì €ìž¥
-  permission_view_gantt: Ganttì°¨íŠ¸ ë³´ê¸°
-  permission_view_calendar: ë‹¬ë ¥ ë³´ê¸°
-  permission_view_issue_watchers: ì¼ê°ì§€í‚´ì´ ë³´ê¸°
-  permission_add_issue_watchers: ì¼ê°ì§€í‚´ì´ ì¶”ê°€
-  permission_log_time: ìž‘ì—…ì‹œê°„ ê¸°ë¡
-  permission_view_time_entries: ì‹œê°„ìž…ë ¥ ë³´ê¸°
-  permission_edit_time_entries: ì‹œê°„ìž…ë ¥ íŽ¸ì§‘
-  permission_edit_own_time_entries: ë‚´ ì‹œê°„ìž…ë ¥ íŽ¸ì§‘
-  permission_manage_news: ë‰´ìŠ¤ ê´€ë¦¬
-  permission_comment_news: ë‰´ìŠ¤ì— ëŒ“ê¸€ë‹¬ê¸°
-  permission_manage_documents: ë¬¸ì„œ ê´€ë¦¬
-  permission_view_documents: ë¬¸ì„œ ë³´ê¸°
-  permission_manage_files: íŒŒì¼ê´€ë¦¬
-  permission_view_files: íŒŒì¼ë³´ê¸°
-  permission_manage_wiki: ìœ„í‚¤ ê´€ë¦¬
-  permission_rename_wiki_pages: ìœ„í‚¤ íŽ˜ì´ì§€ ì´ë¦„ë³€ê²½
-  permission_delete_wiki_pages: ìœ„ì¹˜ íŽ˜ì´ì§€ ì‚­ì œ
-  permission_view_wiki_pages: ìœ„í‚¤ ë³´ê¸°
-  permission_view_wiki_edits: ìœ„í‚¤ ê¸°ë¡ ë³´ê¸°
-  permission_edit_wiki_pages: ìœ„í‚¤ íŽ˜ì´ì§€ íŽ¸ì§‘
-  permission_delete_wiki_pages_attachments: ì²¨ë¶€íŒŒì¼ ì‚­ì œ
-  permission_protect_wiki_pages: í”„ë¡œì íŠ¸ ìœ„í‚¤ íŽ˜ì´ì§€
-  permission_manage_repository: ì €ìž¥ì†Œ ê´€ë¦¬
-  permission_browse_repository: ì €ìž¥ì†Œ ë‘˜ëŸ¬ë³´ê¸°
-  permission_view_changesets: ë³€ê²½ë¬¶ìŒë³´ê¸°
-  permission_commit_access: ë³€ê²½ë¡œê·¸ ë³´ê¸°
-  permission_manage_boards: ê²Œì‹œíŒ ê´€ë¦¬
-  permission_view_messages: ë©”ì‹œì§€ ë³´ê¸°
-  permission_add_messages: ë©”ì‹œì§€ ì¶”ê°€
-  permission_edit_messages: ë©”ì‹œì§€ íŽ¸ì§‘
-  permission_edit_own_messages: ìžê¸° ë©”ì‹œì§€ íŽ¸ì§‘
-  permission_delete_messages: ë©”ì‹œì§€ ì‚­ì œ
-  permission_delete_own_messages: ìžê¸° ë©”ì‹œì§€ ì‚­ì œ
-
-  project_module_issue_tracking: ì¼ê°ê´€ë¦¬
-  project_module_time_tracking: ì‹œê°„ì¶”ì 
-  project_module_news: ë‰´ìŠ¤
-  project_module_documents: ë¬¸ì„œ
-  project_module_files: íŒŒì¼
-  project_module_wiki: ìœ„í‚¤
-  project_module_repository: ì €ìž¥ì†Œ
-  project_module_boards: ê²Œì‹œíŒ
-  
-  label_user: ì‚¬ìš©ìž
-  label_user_plural: ì‚¬ìš©ìž
-  label_user_new: ìƒˆ ì‚¬ìš©ìž
-  label_project: í”„ë¡œì íŠ¸
-  label_project_new: ìƒˆ í”„ë¡œì íŠ¸
-  label_project_plural: í”„ë¡œì íŠ¸
-  label_x_projects:
-    zero:  ì—†ìŒ
-    one:   "í•œ í”„ë¡œì íŠ¸"
-    other: "%{count}ê°œ í”„ë¡œì íŠ¸"
-  label_project_all: ëª¨ë“  í”„ë¡œì íŠ¸
-  label_project_latest: ìµœê·¼ í”„ë¡œì íŠ¸
-  label_issue: ì¼ê°
-  label_issue_new: ìƒˆ ì¼ê°ë§Œë“¤ê¸°
-  label_issue_plural: ì¼ê°
-  label_issue_view_all: ëª¨ë“  ì¼ê° ë³´ê¸°
-  label_issues_by: "%{value}ë³„ ì¼ê°"
-  label_issue_added: ì¼ê° ì¶”ê°€
-  label_issue_updated: ì¼ê° ìˆ˜ì •
-  label_document: ë¬¸ì„œ
-  label_document_new: ìƒˆ ë¬¸ì„œ
-  label_document_plural: ë¬¸ì„œ
-  label_document_added: ë¬¸ì„œ ì¶”ê°€
-  label_role: ì—­í• 
-  label_role_plural: ì—­í• 
-  label_role_new: ìƒˆ ì—­í• 
-  label_role_and_permissions: ì—­í•  ë° ê¶Œí•œ
-  label_member: ë‹´ë‹¹ìž
-  label_member_new: ìƒˆ ë‹´ë‹¹ìž
-  label_member_plural: ë‹´ë‹¹ìž
-  label_tracker: ì¼ê° ìœ í˜•
-  label_tracker_plural: ì¼ê° ìœ í˜•
-  label_tracker_new: ìƒˆ ì¼ê° ìœ í˜•
-  label_workflow: ì—…ë¬´íë¦„
-  label_issue_status: ì¼ê° ìƒíƒœ
-  label_issue_status_plural: ì¼ê° ìƒíƒœ
-  label_issue_status_new: ìƒˆ ì¼ê° ìƒíƒœ
-  label_issue_category: ì¼ê° ë²”ì£¼
-  label_issue_category_plural: ì¼ê° ë²”ì£¼
-  label_issue_category_new: ìƒˆ ì¼ê° ë²”ì£¼
-  label_custom_field: ì‚¬ìš©ìž ì •ì˜ í•­ëª©
-  label_custom_field_plural: ì‚¬ìš©ìž ì •ì˜ í•­ëª©
-  label_custom_field_new: ìƒˆ ì‚¬ìš©ìž ì •ì˜ í•­ëª©
-  label_enumerations: ì½”ë“œê°’
-  label_enumeration_new: ìƒˆ ì½”ë“œê°’
-  label_information: ì •ë³´
-  label_information_plural: ì •ë³´
-  label_please_login: ë¡œê·¸ì¸í•˜ì„¸ìš”.
-  label_register: ë“±ë¡
-  label_login_with_open_id_option: ë˜ëŠ” OpenIDë¡œ ë¡œê·¸ì¸
-  label_password_lost: ë¹„ë°€ë²ˆí˜¸ ì°¾ê¸°
-  label_home: ì´ˆê¸°í™”ë©´
-  label_my_page: ë‚´ íŽ˜ì´ì§€
-  label_my_account: ë‚´ ê³„ì •
-  label_my_projects: ë‚´ í”„ë¡œì íŠ¸
-  label_administration: ê´€ë¦¬
-  label_login: ë¡œê·¸ì¸
-  label_logout: ë¡œê·¸ì•„ì›ƒ
-  label_help: ë„ì›€ë§
-  label_reported_issues: ë³´ê³ í•œ ì¼ê°
-  label_assigned_to_me_issues: ë‚´ê°€ ë§¡ì€ ì¼ê°
-  label_last_login: ë§ˆì§€ë§‰ ì ‘ì†
-  label_registered_on: ë“±ë¡ì‹œê°
-  label_activity: ìž‘ì—…ë‚´ì—­
-  label_overall_activity: ì „ì²´ ìž‘ì—…ë‚´ì—­
-  label_user_activity: "%{value}ì˜ ìž‘ì—…ë‚´ì—­"
-  label_new: ìƒˆë¡œ ë§Œë“¤ê¸°
-  label_logged_as: 'ë¡œê·¸ì¸ê³„ì •:'
-  label_environment: í™˜ê²½
-  label_authentication: ì¸ì¦
-  label_auth_source: ì¸ì¦ ê³µê¸‰ìž
-  label_auth_source_new: ìƒˆ ì¸ì¦ ê³µê¸‰ìž
-  label_auth_source_plural: ì¸ì¦ ê³µê¸‰ìž
-  label_subproject_plural: í•˜ìœ„ í”„ë¡œì íŠ¸
-  label_and_its_subprojects: "%{value}ì™€ í•˜ìœ„ í”„ë¡œì íŠ¸ë“¤"
-  label_min_max_length: ìµœì†Œ - ìµœëŒ€ ê¸¸ì´
-  label_list: ëª©ë¡
-  label_date: ë‚ ì§œ
-  label_integer: ì •ìˆ˜
-  label_float: ë¶€ë™ì†Œìˆ˜
-  label_boolean: ë¶€ìš¸ë¦°
-  label_string: ë¬¸ìžì—´
-  label_text: í…ìŠ¤íŠ¸
-  label_attribute: ì†ì„±
-  label_attribute_plural: ì†ì„±
-  label_download: "%{count}íšŒ ë‹¤ìš´ë¡œë“œ"
-  label_download_plural: "%{count}íšŒ ë‹¤ìš´ë¡œë“œ"
-  label_no_data: í‘œì‹œí•  ë°ì´í„°ê°€ ì—†ìŠµë‹ˆë‹¤.
-  label_change_status: ìƒíƒœ ë³€ê²½
-  label_history: ì´ë ¥
-  label_attachment: íŒŒì¼
-  label_attachment_new: íŒŒì¼ì¶”ê°€
-  label_attachment_delete: íŒŒì¼ì‚­ì œ
-  label_attachment_plural: íŒŒì¼
-  label_file_added: íŒŒì¼ ì¶”ê°€
-  label_report: ë³´ê³ ì„œ
-  label_report_plural: ë³´ê³ ì„œ
-  label_news: ë‰´ìŠ¤
-  label_news_new: ìƒˆ ë‰´ìŠ¤
-  label_news_plural: ë‰´ìŠ¤
-  label_news_latest: ìµœê·¼ ë‰´ìŠ¤
-  label_news_view_all: ëª¨ë“  ë‰´ìŠ¤
-  label_news_added: ë‰´ìŠ¤ ì¶”ê°€
-  label_settings: ì„¤ì •
-  label_overview: ê°œìš”
-  label_version: ë²„ì „
-  label_version_new: ìƒˆ ë²„ì „
-  label_version_plural: ë²„ì „
-  label_confirmation: í™•ì¸
-  label_export_to: ë‚´ë³´ë‚´ê¸°
-  label_read: ì½ê¸°...
-  label_public_projects: ê³µê°œ í”„ë¡œì íŠ¸
-  label_open_issues: ì§„í–‰ì¤‘
-  label_open_issues_plural: ì§„í–‰ì¤‘
-  label_closed_issues: ì™„ë£Œë¨
-  label_closed_issues_plural: ì™„ë£Œë¨
-  label_x_open_issues_abbr_on_total:
-    zero:  "ì´ %{total} ê±´ ëª¨ë‘ ì™„ë£Œ"
-    one:   "í•œ ê±´ ì§„í–‰ ì¤‘ / ì´ %{total} ê±´ ì¤‘ "
-    other: "%{count} ê±´ ì§„í–‰ ì¤‘ / ì´ %{total} ê±´"
-  label_x_open_issues_abbr:
-    zero:  ëª¨ë‘ ì™„ë£Œ
-    one:   í•œ ê±´ ì§„í–‰ ì¤‘
-    other: "%{count} ê±´ ì§„í–‰ ì¤‘"
-  label_x_closed_issues_abbr:
-    zero:  ëª¨ë‘ ë¯¸ì™„ë£Œ
-    one:   í•œ ê±´ ì™„ë£Œ
-    other: "%{count} ê±´ ì™„ë£Œ"
-  label_total: í•©ê³„
-  label_permissions: ê¶Œí•œ
-  label_current_status: ì¼ê° ìƒíƒœ
-  label_new_statuses_allowed: í—ˆìš©ë˜ëŠ” ì¼ê° ìƒíƒœ
-  label_all: ëª¨ë‘
-  label_none: ì—†ìŒ
-  label_nobody: ë¯¸ì§€ì •
-  label_next: ë‹¤ìŒ
-  label_previous: ë’¤ë¡œ
-  label_used_by: ì‚¬ìš©ë¨
-  label_details: ìžì„¸ížˆ
-  label_add_note: ì¼ê°ë§ê¸€ ì¶”ê°€
-  label_per_page: íŽ˜ì´ì§€ë³„
-  label_calendar: ë‹¬ë ¥
-  label_months_from: ê°œì›” ë™ì•ˆ | ë‹¤ìŒë¶€í„° 
-  label_gantt: Gantt ì± íŠ¸
-  label_internal: ë‚´ë¶€
-  label_last_changes: "ìµœê·¼ %{count}ê°œì˜ ë³€ê²½ì‚¬í•­"
-  label_change_view_all: ëª¨ë“  ë³€ê²½ ë‚´ì—­ ë³´ê¸°
-  label_personalize_page: ìž…ë§›ëŒ€ë¡œ êµ¬ì„±í•˜ê¸°
-  label_comment: ëŒ“ê¸€
-  label_comment_plural: ëŒ“ê¸€
-  label_x_comments:
-    zero: ëŒ“ê¸€ ì—†ìŒ
-    one: í•œ ê°œì˜ ëŒ“ê¸€
-    other: "%{count} ê°œì˜ ëŒ“ê¸€"
-  label_comment_add: ëŒ“ê¸€ ì¶”ê°€
-  label_comment_added: ëŒ“ê¸€ì´ ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤.
-  label_comment_delete: ëŒ“ê¸€ ì‚­ì œ
-  label_query: ê²€ìƒ‰ì–‘ì‹
-  label_query_plural: ê²€ìƒ‰ì–‘ì‹
-  label_query_new: ìƒˆ ê²€ìƒ‰ì–‘ì‹
-  label_filter_add: ê²€ìƒ‰ì¡°ê±´ ì¶”ê°€
-  label_filter_plural: ê²€ìƒ‰ì¡°ê±´
-  label_equals: ì´ë‹¤
-  label_not_equals: ì•„ë‹ˆë‹¤
-  label_in_less_than: ì´ë‚´
-  label_in_more_than: ì´í›„
-  label_greater_or_equal: ">="
-  label_less_or_equal: "<="
-  label_in: ì´ë‚´
-  label_today: ì˜¤ëŠ˜
-  label_all_time: ëª¨ë“  ì‹œê°„
-  label_yesterday: ì–´ì œ
-  label_this_week: ì´ë²ˆì£¼
-  label_last_week: ì§€ë‚œ ì£¼
-  label_last_n_days: "ì§€ë‚œ %{count} ì¼"
-  label_this_month: ì´ë²ˆ ë‹¬
-  label_last_month: ì§€ë‚œ ë‹¬
-  label_this_year: ì˜¬í•´
-  label_date_range: ë‚ ì§œ ë²”ìœ„
-  label_less_than_ago: ì´ì „
-  label_more_than_ago: ì´í›„
-  label_ago: ì¼ ì „
-  label_contains: í¬í•¨ë˜ëŠ” í‚¤ì›Œë“œ
-  label_not_contains: í¬í•¨í•˜ì§€ ì•ŠëŠ” í‚¤ì›Œë“œ
-  label_day_plural: ì¼
-  label_repository: ì €ìž¥ì†Œ
-  label_repository_plural: ì €ìž¥ì†Œ
-  label_browse: ì €ìž¥ì†Œ ë‘˜ëŸ¬ë³´ê¸°
-  label_modification: "%{count} ë³€ê²½"
-  label_modification_plural: "%{count} ë³€ê²½"
-  label_revision: ê°œì •íŒ
-  label_revision_plural: ê°œì •íŒ
-  label_associated_revisions: ê´€ë ¨ëœ ê°œì •íŒë“¤
-  label_added: ì¶”ê°€ë¨
-  label_modified: ë³€ê²½ë¨
-  label_copied: ë³µì‚¬ë¨
-  label_renamed: ì´ë¦„ë°”ë€œ
-  label_deleted: ì‚­ì œë¨
-  label_latest_revision: ìµœê·¼ ê°œì •íŒ
-  label_latest_revision_plural: ìµœê·¼ ê°œì •íŒ
-  label_view_revisions: ê°œì •íŒ ë³´ê¸°
-  label_max_size: ìµœëŒ€ í¬ê¸°
-  label_sort_highest: ë§¨ ìœ„ë¡œ
-  label_sort_higher: ìœ„ë¡œ
-  label_sort_lower: ì•„ëž˜ë¡œ
-  label_sort_lowest: ë§¨ ì•„ëž˜ë¡œ
-  label_roadmap: ë¡œë“œë§µ
-  label_roadmap_due_in: "ê¸°í•œ  %{value}"
-  label_roadmap_overdue: "%{value} ì§€ì—°"
-  label_roadmap_no_issues: ì´ ë²„ì „ì— í•´ë‹¹í•˜ëŠ” ì¼ê° ì—†ìŒ
-  label_search: ê²€ìƒ‰
-  label_result_plural: ê²°ê³¼
-  label_all_words: ëª¨ë“  ë‹¨ì–´
-  label_wiki: ìœ„í‚¤
-  label_wiki_edit: ìœ„í‚¤ íŽ¸ì§‘
-  label_wiki_edit_plural: ìœ„í‚¤ íŽ¸ì§‘
-  label_wiki_page: ìœ„í‚¤ íŽ˜ì´ì§€
-  label_wiki_page_plural: ìœ„í‚¤ íŽ˜ì´ì§€
-  label_index_by_title: ì œëª©ë³„ ìƒ‰ì¸
-  label_index_by_date: ë‚ ì§œë³„ ìƒ‰ì¸
-  label_current_version: í˜„ìž¬ ë²„ì „
-  label_preview: ë¯¸ë¦¬ë³´ê¸°
-  label_feed_plural: í”¼ë“œ(Feeds)
-  label_changes_details: ëª¨ë“  ìƒì„¸ ë³€ê²½ ë‚´ì—­
-  label_issue_tracking: ì¼ê° ì¶”ì 
-  label_spent_time: ì†Œìš” ì‹œê°„
-  label_f_hour: "%{value} ì‹œê°„"
-  label_f_hour_plural: "%{value} ì‹œê°„"
-  label_time_tracking: ì‹œê°„ì¶”ì 
-  label_change_plural: ë³€ê²½ì‚¬í•­ë“¤
-  label_statistics: í†µê³„
-  label_commits_per_month: ì›”ë³„ ì œì¶œ ë‚´ì—­
-  label_commits_per_author: ì €ìžë³„ ì œì¶œ ë‚´ì—­
-  label_view_diff: ì°¨ì´ì  ë³´ê¸°
-  label_diff_inline: í•œì¤„ë¡œ
-  label_diff_side_by_side: ë‘ì¤„ë¡œ
-  label_options: ì˜µì…˜
-  label_copy_workflow_from: ì—…ë¬´íë¦„ ë³µì‚¬í•˜ê¸°
-  label_permissions_report: ê¶Œí•œ ë³´ê³ ì„œ
-  label_watched_issues: ì§€ì¼œë³´ê³  ìžˆëŠ” ì¼ê°
-  label_related_issues: ì—°ê²°ëœ ì¼ê°
-  label_applied_status: ì ìš©ëœ ìƒíƒœ
-  label_loading: ì½ëŠ” ì¤‘...
-  label_relation_new: ìƒˆ ê´€ê³„
-  label_relation_delete: ê´€ê³„ ì§€ìš°ê¸°
-  label_relates_to: "ë‹¤ìŒ ì¼ê°ê³¼ ê´€ë ¨ë¨:"
-  label_duplicates: "ë‹¤ìŒ ì¼ê°ê³¼ ê²¹ì¹¨:"
-  label_duplicated_by: "ë‹¤ìŒ ì¼ê°ê³¼ ê²¹ì¹¨:"
-  label_blocks: "ë‹¤ìŒ ì¼ê°ì˜ í•´ê²°ì„ ë§‰ê³  ìžˆìŒ:"
-  label_blocked_by: "ë‹¤ìŒ ì¼ê°ì—ê²Œ ë§‰í˜€ ìžˆìŒ:"
-  label_precedes: "ë‹¤ìŒì— ì§„í–‰í•  ì¼ê°:"
-  label_follows: "ë‹¤ìŒ ì¼ê°ì„ ìš°ì„  ì§„í–‰:"
-  label_end_to_start: "ëì—ì„œ ì‹œìž‘"
-  label_end_to_end: "ëì—ì„œ ë"
-  label_start_to_start: "ì‹œìž‘ì—ì„œ ì‹œìž‘" 
-  label_start_to_end: "ì‹œìž‘ì—ì„œ ë"
-  label_stay_logged_in: ë¡œê·¸ì¸ ìœ ì§€
-  label_disabled: ë¹„í™œì„±í™”
-  label_show_completed_versions: ì™„ë£Œëœ ë²„ì „ ë³´ê¸°
-  label_me: ë‚˜
-  label_board: ê²Œì‹œíŒ
-  label_board_new: ìƒˆ ê²Œì‹œíŒ
-  label_board_plural: ê²Œì‹œíŒ
-  label_topic_plural: ì£¼ì œ
-  label_message_plural: ê¸€
-  label_message_last: ë§ˆì§€ë§‰ ê¸€
-  label_message_new: ìƒˆê¸€ì“°ê¸°
-  label_message_posted: ê¸€ ì¶”ê°€
-  label_reply_plural: ë‹µê¸€
-  label_send_information: ì‚¬ìš©ìžì—ê²Œ ê³„ì •ì •ë³´ë¥¼ ë³´ë‚´ê¸°
-  label_year: ë…„
-  label_month: ì›”
-  label_week: ì£¼
-  label_date_from: 'ê¸°ê°„:'
-  label_date_to: ' ~ '
-  label_language_based: ì–¸ì–´ì„¤ì •ì— ë”°ë¦„
-  label_sort_by: "%{value}(ìœ¼)ë¡œ ì •ë ¬"
-  label_send_test_email: í…ŒìŠ¤íŠ¸ ë©”ì¼ ë³´ë‚´ê¸°
-  label_feeds_access_key_created_on: "í”¼ë“œ ì ‘ê·¼ í‚¤ê°€ %{value} ì´ì „ì— ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤."
-  label_module_plural: ëª¨ë“ˆ
-  label_added_time_by: "%{author}ì´(ê°€) %{age} ì „ì— ì¶”ê°€í•¨"
-  label_updated_time_by: "%{author}ì´(ê°€) %{age} ì „ì— ë³€ê²½"
-  label_updated_time: "%{value} ì „ì— ìˆ˜ì •ë¨"
-  label_jump_to_a_project: í”„ë¡œì íŠ¸ ë°”ë¡œê°€ê¸°
-  label_file_plural: íŒŒì¼
-  label_changeset_plural: ë³€ê²½ë¬¶ìŒ
-  label_default_columns: ê¸°ë³¸ ì»¬ëŸ¼
-  label_no_change_option: (ìˆ˜ì • ì•ˆí•¨)
-  label_bulk_edit_selected_issues: ì„ íƒëœ ì¼ê°ë“¤ì„ í•œêº¼ë²ˆì— ìˆ˜ì •í•˜ê¸°
-  label_theme: í…Œë§ˆ
-  label_default: ê¸°ë³¸
-  label_search_titles_only: ì œëª©ì—ì„œë§Œ ì°¾ê¸°
-  label_user_mail_option_all: "ë‚´ê°€ ì†í•œ í”„ë¡œì íŠ¸ë¡œë“¤ë¶€í„° ëª¨ë“  ë©”ì¼ ë°›ê¸°"
-  label_user_mail_option_selected: "ì„ íƒí•œ í”„ë¡œì íŠ¸ë“¤ë¡œë¶€í„° ëª¨ë“  ë©”ì¼ ë°›ê¸°.."
-  label_user_mail_no_self_notified: "ë‚´ê°€ ë§Œë“  ë³€ê²½ì‚¬í•­ë“¤ì— ëŒ€í•´ì„œëŠ” ì•Œë¦¼ë©”ì¼ì„ ë°›ì§€ ì•ŠìŠµë‹ˆë‹¤."
-  label_registration_activation_by_email: ë©”ì¼ë¡œ ê³„ì •ì„ í™œì„±í™”í•˜ê¸°
-  label_registration_automatic_activation: ìžë™ ê³„ì • í™œì„±í™”
-  label_registration_manual_activation: ìˆ˜ë™ ê³„ì • í™œì„±í™”
-  label_display_per_page: "íŽ˜ì´ì§€ë‹¹ ì¤„ìˆ˜: %{value}"
-  label_age: ë§ˆì§€ë§‰ ìˆ˜ì •ì¼
-  label_change_properties: ì†ì„± ë³€ê²½
-  label_general: ì¼ë°˜
-  label_more: ì œëª© ë° ì„¤ëª… ìˆ˜ì •
-  label_scm: í˜•ìƒê´€ë¦¬ì‹œìŠ¤í…œ
-  label_plugins: í”ŒëŸ¬ê·¸ì¸
-  label_ldap_authentication: LDAP ì¸ì¦
-  label_downloads_abbr: D/L
-  label_optional_description: ë¶€ê°€ì ì¸ ì„¤ëª…
-  label_add_another_file: ë‹¤ë¥¸ íŒŒì¼ ì¶”ê°€ 
-  label_preferences: ì„¤ì •
-  label_chronological_order: ì‹œê°„ ìˆœìœ¼ë¡œ ì •ë ¬
-  label_reverse_chronological_order: ì‹œê°„ ì—­ìˆœìœ¼ë¡œ ì •ë ¬ 
-  label_planning: í”„ë¡œì íŠ¸ê³„íš
-  label_incoming_emails: ìˆ˜ì‹  ë©”ì¼
-  label_generate_key: í‚¤ ìƒì„±
-  label_issue_watchers: ì¼ê°ì§€í‚´ì´
-  label_example: ì˜ˆ
-  label_display: í‘œì‹œë°©ì‹
-  label_sort: ì •ë ¬
-  label_ascending: ì˜¤ë¦„ì°¨ìˆœ
-  label_descending: ë‚´ë¦¼ì°¨ìˆœ
-  label_date_from_to: "%{start}ë¶€í„° %{end}ê¹Œì§€"
-  label_wiki_content_added: ìœ„í‚¤íŽ˜ì´ì§€ ì¶”ê°€
-  label_wiki_content_updated: ìœ„í‚¤íŽ˜ì´ì§€ ìˆ˜ì •
-
-  button_login: ë¡œê·¸ì¸
-  button_submit: í™•ì¸
-  button_save: ì €ìž¥
-  button_check_all: ëª¨ë‘ì„ íƒ
-  button_uncheck_all: ì„ íƒí•´ì œ
-  button_delete: ì‚­ì œ
-  button_create: ë§Œë“¤ê¸°
-  button_create_and_continue: ë§Œë“¤ê³  ê³„ì†í•˜ê¸°
-  button_test: í…ŒìŠ¤íŠ¸
-  button_edit: íŽ¸ì§‘
-  button_add: ì¶”ê°€
-  button_change: ë³€ê²½
-  button_apply: ì ìš©
-  button_clear: ì§€ìš°ê¸°
-  button_lock: ìž ê¸ˆ
-  button_unlock: ìž ê¸ˆí•´ì œ
-  button_download: ë‹¤ìš´ë¡œë“œ
-  button_list: ëª©ë¡
-  button_view: ë³´ê¸°
-  button_move: ì´ë™
-  button_back: ë’¤ë¡œ
-  button_cancel: ì·¨ì†Œ
-  button_activate: í™œì„±í™”
-  button_sort: ì •ë ¬
-  button_log_time: ìž‘ì—…ì‹œê°„ ê¸°ë¡
-  button_rollback: ì´ ë²„ì „ìœ¼ë¡œ ë˜ëŒë¦¬ê¸°
-  button_watch: ì§€ì¼œë³´ê¸°
-  button_unwatch: ê´€ì‹¬ë„ê¸°
-  button_reply: ë‹µê¸€
-  button_archive: ìž ê¸ˆë³´ê´€
-  button_unarchive: ìž ê¸ˆë³´ê´€í•´ì œ
-  button_reset: ì´ˆê¸°í™”
-  button_rename: ì´ë¦„ë°”ê¾¸ê¸°
-  button_change_password: ë¹„ë°€ë²ˆí˜¸ ë°”ê¾¸ê¸°
-  button_copy: ë³µì‚¬
-  button_annotate: ì´ë ¥í•´ì„¤
-  button_update: ìˆ˜ì •
-  button_configure: ì„¤ì •
-  button_quote: ëŒ“ê¸€ë‹¬ê¸°
-  
-  status_active: ì‚¬ìš©ì¤‘
-  status_registered: ë“±ë¡ëŒ€ê¸°
-  status_locked: ìž ê¹€
-  
-  text_select_mail_notifications: ì•Œë¦¼ë©”ì¼ì´ í•„ìš”í•œ ìž‘ì—…ì„ ì„ íƒí•˜ì„¸ìš”.
-  text_regexp_info: ì˜ˆ) ^[A-Z0-9]+$
-  text_min_max_length_info: 0 ëŠ” ì œí•œì´ ì—†ìŒì„ ì˜ë¯¸í•¨
-  text_project_destroy_confirmation: ì´ í”„ë¡œì íŠ¸ë¥¼ ì‚­ì œí•˜ê³  ëª¨ë“  ë°ì´í„°ë¥¼ ì§€ìš°ì‹œê² ìŠµë‹ˆê¹Œ?
-  text_subprojects_destroy_warning: "í•˜ìœ„ í”„ë¡œì íŠ¸(%{value})ì´(ê°€) ìžë™ìœ¼ë¡œ ì§€ì›Œì§ˆ ê²ƒìž…ë‹ˆë‹¤."
-  text_workflow_edit: ì—…ë¬´íë¦„ ìˆ˜ì •í•˜ë ¤ë©´ ì—­í• ê³¼ ì¼ê°ìœ í˜•ì„ ì„ íƒí•˜ì„¸ìš”.
-  text_are_you_sure: ê³„ì† ì§„í–‰ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?
-  text_tip_issue_begin_day: ì˜¤ëŠ˜ ì‹œìž‘í•˜ëŠ” ì—…ë¬´(task)
-  text_tip_issue_end_day: ì˜¤ëŠ˜ ì¢…ë£Œí•˜ëŠ” ì—…ë¬´(task)
-  text_tip_issue_begin_end_day: ì˜¤ëŠ˜ ì‹œìž‘í•˜ê³  ì¢…ë£Œí•˜ëŠ” ì—…ë¬´(task)
-  text_project_identifier_info: 'ì˜ë¬¸ ì†Œë¬¸ìž(a-z) ë° ìˆ«ìž, ëŒ€ì‰¬(-) ê°€ëŠ¥.<br />ì €ìž¥ëœí›„ì—ëŠ” ì‹ë³„ìž ë³€ê²½ ë¶ˆê°€ëŠ¥.'
-  text_caracters_maximum: "ìµœëŒ€ %{count} ê¸€ìž ê°€ëŠ¥"
-  text_caracters_minimum: "ìµœì†Œí•œ %{count} ê¸€ìž ì´ìƒì´ì–´ì•¼ í•©ë‹ˆë‹¤."
-  text_length_between: "%{min} ì—ì„œ %{max} ê¸€ìž"
-  text_tracker_no_workflow: ì´ ì¼ê° ìœ í˜•ì—ëŠ” ì—…ë¬´íë¦„ì´ ì •ì˜ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤.
-  text_unallowed_characters: í—ˆìš©ë˜ì§€ ì•ŠëŠ” ë¬¸ìžì—´
-  text_comma_separated: "êµ¬ë¶„ìž','ë¥¼ ì´ìš©í•´ì„œ ì—¬ëŸ¬ ê°œì˜ ê°’ì„ ìž…ë ¥í•  ìˆ˜ ìžˆìŠµë‹ˆë‹¤."
-  text_issues_ref_in_commit_messages: ì œì¶œ ë©”ì‹œì§€ì—ì„œ ì¼ê°ì„ ì°¸ì¡°í•˜ê±°ë‚˜ í•´ê²°í•˜ê¸°
-  text_issue_added: "%{author}ì´(ê°€) ì¼ê° %{id}ì„(ë¥¼) ë³´ê³ í•˜ì˜€ìŠµë‹ˆë‹¤."
-  text_issue_updated: "%{author}ì´(ê°€) ì¼ê° %{id}ì„(ë¥¼) ìˆ˜ì •í•˜ì˜€ìŠµë‹ˆë‹¤."
-  text_wiki_destroy_confirmation: ì´ ìœ„í‚¤ì™€ ëª¨ë“  ë‚´ìš©ì„ ì§€ìš°ì‹œê² ìŠµë‹ˆê¹Œ?
-  text_issue_category_destroy_question: "ì¼ë¶€ ì¼ê°ë“¤(%{count}ê°œ)ì´ ì´ ë²”ì£¼ì— ì§€ì •ë˜ì–´ ìžˆìŠµë‹ˆë‹¤. ì–´ë–»ê²Œ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
-  text_issue_category_destroy_assignments: ë²”ì£¼ ì§€ì • ì§€ìš°ê¸°
-  text_issue_category_reassign_to: ì¼ê°ì„ ì´ ë²”ì£¼ì— ë‹¤ì‹œ ì§€ì •í•˜ê¸°
-  text_user_mail_option: "ì„ íƒí•˜ì§€ ì•Šì€ í”„ë¡œì íŠ¸ì—ì„œë„, ì§€ì¼œë³´ëŠ” ì¤‘ì´ê±°ë‚˜ ì†í•´ìžˆëŠ” ì‚¬í•­(ì¼ê°ì„ ë°œí–‰í–ˆê±°ë‚˜ í• ë‹¹ëœ ê²½ìš°)ì´ ìžˆìœ¼ë©´ ì•Œë¦¼ë©”ì¼ì„ ë°›ê²Œ ë©ë‹ˆë‹¤."
-  text_no_configuration_data: "ì—­í• , ì¼ê° ìœ í˜•, ì¼ê° ìƒíƒœë“¤ê³¼ ì—…ë¬´íë¦„ì´ ì•„ì§ ì„¤ì •ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤.\nê¸°ë³¸ ì„¤ì •ì„ ì½ì–´ë“¤ì´ëŠ” ê²ƒì„ ê¶Œìž¥í•©ë‹ˆë‹¤. ì½ì–´ë“¤ì¸ í›„ì— ìˆ˜ì •í•  ìˆ˜ ìžˆìŠµë‹ˆë‹¤."
-  text_load_default_configuration: ê¸°ë³¸ ì„¤ì •ì„ ì½ì–´ë“¤ì´ê¸°
-  text_status_changed_by_changeset: "ë³€ê²½ë¬¶ìŒ %{value}ì— ì˜í•˜ì—¬ ë³€ê²½ë¨"
-  text_issues_destroy_confirmation: 'ì„ íƒí•œ ì¼ê°ì„ ì •ë§ë¡œ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?'
-  text_select_project_modules: 'ì´ í”„ë¡œì íŠ¸ì—ì„œ í™œì„±í™”ì‹œí‚¬ ëª¨ë“ˆì„ ì„ íƒí•˜ì„¸ìš”:'
-  text_default_administrator_account_changed: ê¸°ë³¸ ê´€ë¦¬ìž ê³„ì •ì´ ë³€ê²½
-  text_file_repository_writable: íŒŒì¼ ì €ìž¥ì†Œ ì“°ê¸° ê°€ëŠ¥
-  text_plugin_assets_writable: í”ŒëŸ¬ê·¸ì¸ ì „ìš© ë””ë ‰í† ë¦¬ê°€ ì“°ê¸° ê°€ëŠ¥
-  text_rmagick_available: RMagick ì‚¬ìš© ê°€ëŠ¥ (ì„ íƒì )
-  text_destroy_time_entries_question: ì‚­ì œí•˜ë ¤ëŠ” ì¼ê°ì— %{hours} ì‹œê°„ì´ ë³´ê³ ë˜ì–´ ìžˆìŠµë‹ˆë‹¤. ì–´ë–»ê²Œ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?
-  text_destroy_time_entries: ë³´ê³ ëœ ì‹œê°„ì„ ì‚­ì œí•˜ê¸°
-  text_assign_time_entries_to_project: ë³´ê³ ëœ ì‹œê°„ì„ í”„ë¡œì íŠ¸ì— í• ë‹¹í•˜ê¸°
-  text_reassign_time_entries: 'ì´ ì•Œë¦¼ì— ë³´ê³ ëœ ì‹œê°„ì„ ìž¬í• ë‹¹í•˜ê¸°:'
-  text_user_wrote: "%{value}ì˜ ë§ê¸€:"
-  text_enumeration_category_reassign_to: 'ìƒˆë¡œìš´ ê°’ì„ ì„¤ì •:'
-  text_enumeration_destroy_question: "%{count} ê°œì˜ ì¼ê°ì´ ì´ ê°’ì„ ì‚¬ìš©í•˜ê³  ìžˆìŠµë‹ˆë‹¤."
-  text_email_delivery_not_configured: "ì´ë©”ì¼ ì „ë‹¬ì´ ì„¤ì •ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤. ê·¸ëž˜ì„œ ì•Œë¦¼ì´ ë¹„í™œì„±í™”ë˜ì—ˆìŠµë‹ˆë‹¤.\n SMTPì„œë²„ë¥¼ config/configuration.ymlì—ì„œ ì„¤ì •í•˜ê³  ì–´í”Œë¦¬ì¼€ì´ì…˜ì„ ë‹¤ì‹œ ì‹œìž‘í•˜ì‹­ì‹œì˜¤. ê·¸ëŸ¬ë©´ ë™ìž‘í•©ë‹ˆë‹¤."
-  text_repository_usernames_mapping: "ì €ìž¥ì†Œ ë¡œê·¸ì—ì„œ ë°œê²¬ëœ ê° ì‚¬ìš©ìžì— ë ˆë“œë§ˆì¸ ì‚¬ìš©ìžë¥¼ ì—…ë°ì´íŠ¸í• ë•Œ ì„ íƒí•©ë‹ˆë‹¤.\në ˆë“œë§ˆì¸ê³¼ ì €ìž¥ì†Œì˜ ì´ë¦„ì´ë‚˜ ì´ë©”ì¼ì´ ê°™ì€ ì‚¬ìš©ìžê°€ ìžë™ìœ¼ë¡œ ì—°ê²°ë©ë‹ˆë‹¤."
-  text_diff_truncated: '... ì´ ì°¨ì´ì ì€ í‘œì‹œí•  ìˆ˜ ìžˆëŠ” ìµœëŒ€ ì¤„ìˆ˜ë¥¼ ì´ˆê³¼í•´ì„œ ì´ ì°¨ì´ì ì€ ìž˜ë ¸ìŠµë‹ˆë‹¤.'
-  text_custom_field_possible_values_info: 'ê° ê°’ ë‹¹ í•œ ì¤„'
-  text_wiki_page_destroy_question: ì´ íŽ˜ì´ì§€ëŠ” %{descendants} ê°œì˜ í•˜ìœ„ íŽ˜ì´ì§€ì™€ ê´€ë ¨ ë‚´ìš©ì´ ìžˆìŠµë‹ˆë‹¤. ì´ ë‚´ìš©ì„ ì–´ë–»ê²Œ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?
-  text_wiki_page_nullify_children: í•˜ìœ„ íŽ˜ì´ì§€ë¥¼ ìµœìƒìœ„ íŽ˜ì´ì§€ ì•„ëž˜ë¡œ ì§€ì •
-  text_wiki_page_destroy_children: ëª¨ë“  í•˜ìœ„ íŽ˜ì´ì§€ì™€ ê´€ë ¨ ë‚´ìš©ì„ ì‚­ì œ
-  text_wiki_page_reassign_children: í•˜ìœ„ íŽ˜ì´ì§€ë¥¼ ì´ íŽ˜ì´ì§€ ì•„ëž˜ë¡œ ì§€ì •
-  
-  default_role_manager: ê´€ë¦¬ìž
-  default_role_developer: ê°œë°œìž
-  default_role_reporter: ë³´ê³ ìž
-  default_tracker_bug: ê²°í•¨
-  default_tracker_feature: ìƒˆê¸°ëŠ¥
-  default_tracker_support: ì§€ì›
-  default_issue_status_new: ì‹ ê·œ
-  default_issue_status_in_progress: ì§„í–‰
-  default_issue_status_resolved: í•´ê²°
-  default_issue_status_feedback: ì˜ê²¬
-  default_issue_status_closed: ì™„ë£Œ
-  default_issue_status_rejected: ê±°ì ˆ
-  default_doc_category_user: ì‚¬ìš©ìž ë¬¸ì„œ
-  default_doc_category_tech: ê¸°ìˆ  ë¬¸ì„œ
-  default_priority_low: ë‚®ìŒ
-  default_priority_normal: ë³´í†µ
-  default_priority_high: ë†’ìŒ
-  default_priority_urgent: ê¸´ê¸‰
-  default_priority_immediate: ì¦‰ì‹œ
-  default_activity_design: ì„¤ê³„
-  default_activity_development: ê°œë°œ
-
-  enumeration_issue_priorities: ì¼ê° ìš°ì„ ìˆœìœ„
-  enumeration_doc_categories: ë¬¸ì„œ ë²”ì£¼
-  enumeration_activities: ìž‘ì—…ë¶„ë¥˜(ì‹œê°„ì¶”ì )
-
-  field_issue_to: ê´€ë ¨ ì¼ê°
-  label_view_all_revisions: ëª¨ë“  ê°œì •íŒ í‘œì‹œ
-  label_tag: í‘œì§€(ç¥¨è­˜)ì €ìž¥ì†Œ
-  label_branch: ë¶„ê¸°(åˆ†å²)ì €ìž¥ì†Œ
-  error_no_tracker_in_project: ì‚¬ìš©í•  ìˆ˜ ìžˆë„ë¡ ì„¤ì •ëœ ì¼ê° ìœ í˜•ì´ ì—†ìŠµë‹ˆë‹¤. í”„ë¡œì íŠ¸ ì„¤ì •ì„ í™•ì¸í•˜ì‹­ì‹œì˜¤.
-  error_no_default_issue_status: 'ê¸°ë³¸ ìƒíƒœê°€ ì •í•´ì ¸ ìžˆì§€ ì•ŠìŠµë‹ˆë‹¤. ì„¤ì •ì„ í™•ì¸í•˜ì‹­ì‹œì˜¤. (ì£¼ ë©”ë‰´ì˜ "ê´€ë¦¬" -> "ì¼ê° ìƒíƒœ")'
-  text_journal_changed: "%{label}ì„(ë¥¼) %{old}ì—ì„œ %{new}(ìœ¼)ë¡œ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
-  text_journal_set_to: "%{label}ì„(ë¥¼) %{value}(ìœ¼)ë¡œ ì§€ì •ë˜ì—ˆìŠµë‹ˆë‹¤."
-  text_journal_deleted: "%{label} ê°’ì´ ì§€ì›Œì¡ŒìŠµë‹ˆë‹¤. (%{old})"
-  label_group_plural: ê·¸ë£¹
-  label_group: ê·¸ë£¹
-  label_group_new: ìƒˆ ê·¸ë£¹
-  label_time_entry_plural: ìž‘ì—…ì‹œê°„
-  text_journal_added: "%{label}ì— %{value}ì´(ê°€) ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
-  field_active: ì‚¬ìš©ì¤‘
-  enumeration_system_activity: ì‹œìŠ¤í…œ ìž‘ì—…
-  permission_delete_issue_watchers: ì¼ê°ì§€í‚´ì´ ì§€ìš°ê¸°
-  version_status_closed: ë‹«íž˜
-  version_status_locked: ìž ê¹€
-  version_status_open: ì§„í–‰
-  error_can_not_reopen_issue_on_closed_version: ë‹«ížŒ ë²„ì „ì— í• ë‹¹ëœ ì¼ê°ì€ ë‹¤ì‹œ ìž¬ë°œìƒì‹œí‚¬ ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
-  label_user_anonymous: ì´ë¦„ì—†ìŒ
-  button_move_and_follow: ì´ë™í•˜ê³  ë”°ë¼ê°€ê¸°
-  setting_default_projects_modules: ìƒˆ í”„ë¡œì íŠ¸ì— ê¸°ë³¸ì ìœ¼ë¡œ í™œì„±í™”ë  ëª¨ë“ˆ
-  setting_gravatar_default: ê¸°ë³¸ ê·¸ë¼ë°”íƒ€ ì´ë¯¸ì§€
-  field_sharing: ê³µìœ 
-  label_version_sharing_hierarchy: ìƒìœ„ ë° í•˜ìœ„ í”„ë¡œì íŠ¸
-  label_version_sharing_system: ëª¨ë“  í”„ë¡œì íŠ¸
-  label_version_sharing_descendants: í•˜ìœ„ í”„ë¡œì íŠ¸
-  label_version_sharing_tree: ìµœìƒìœ„ ë° ëª¨ë“  í•˜ìœ„ í”„ë¡œì íŠ¸
-  label_version_sharing_none: ê³µìœ ì—†ìŒ
-  error_can_not_archive_project: ì´ í”„ë¡œì íŠ¸ë¥¼ ìž ê¸ˆë³´ê´€í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
-  button_duplicate: ë³µì œ
-  button_copy_and_follow: ë³µì‚¬í•˜ê³  ë”°ë¼ê°€ê¸°
-  label_copy_source: ì›ë³¸
-  setting_issue_done_ratio: ì¼ê°ì˜ ì§„ì²™ë„ ê³„ì‚°ë°©ë²•
-  setting_issue_done_ratio_issue_status: ì¼ê° ìƒíƒœë¥¼ ì‚¬ìš©í•˜ê¸°
-  error_issue_done_ratios_not_updated: ì¼ê° ì§„ì²™ë„ê°€ ìˆ˜ì •ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤.
-  error_workflow_copy_target: ëŒ€ìƒ ì¼ê°ìœ í˜•ê³¼ ì—­í• ì„ ì„ íƒí•˜ì„¸ìš”.
-  setting_issue_done_ratio_issue_field: ì¼ê° ìˆ˜ì •ì—ì„œ ì§„ì²™ë„ ìž…ë ¥í•˜ê¸°
-  label_copy_same_as_target: ëŒ€ìƒê³¼ ê°™ìŒ.
-  label_copy_target: ëŒ€ìƒ
-  notice_issue_done_ratios_updated: ì¼ê° ì§„ì²™ë„ê°€ ìˆ˜ì •ë˜ì—ˆìŠµë‹ˆë‹¤.
-  error_workflow_copy_source: ì›ë³¸ ì¼ê°ìœ í˜•ì´ë‚˜ ì—­í• ì„ ì„ íƒí•˜ì„¸ìš”.
-  label_update_issue_done_ratios: ëª¨ë“  ì¼ê° ì§„ì²™ë„ ê°±ì‹ í•˜ê¸°
-  setting_start_of_week: ë‹¬ë ¥ ì‹œìž‘ ìš”ì¼
-  permission_view_issues: ì¼ê° ë³´ê¸°
-  label_display_used_statuses_only: ì´ ì¼ê°ìœ í˜•ì—ì„œ ì‚¬ìš©ë˜ëŠ” ìƒíƒœë§Œ ë³´ì—¬ì£¼ê¸°
-  label_revision_id: ê°œì •íŒ %{value}
-  label_api_access_key: API ì ‘ê·¼í‚¤
-  label_api_access_key_created_on: API ì ‘ê·¼í‚¤ê°€ %{value} ì „ì— ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤.
-  label_feeds_access_key: RSS ì ‘ê·¼í‚¤
-  notice_api_access_key_reseted: API ì ‘ê·¼í‚¤ê°€ ì´ˆê¸°í™”ë˜ì—ˆìŠµë‹ˆë‹¤.
-  setting_rest_api_enabled: REST ì›¹ì„œë¹„ìŠ¤ í™œì„±í™”
-  label_missing_api_access_key: API ì ‘ê·¼í‚¤ê°€ ì—†ìŠµë‹ˆë‹¤.
-  label_missing_feeds_access_key: RSS ì ‘ê·¼í‚¤ê°€ ì—†ìŠµë‹ˆë‹¤.
-  button_show: ë³´ê¸°
-  text_line_separated: ì—¬ëŸ¬ ê°’ì´ í—ˆìš©ë¨(ê°’ ë§ˆë‹¤ í•œ ì¤„ì”©)
-  setting_mail_handler_body_delimiters: ë©”ì¼ ë³¸ë¬¸ êµ¬ë¶„ìž
-  permission_add_subprojects: í•˜ìœ„ í”„ë¡œì íŠ¸ ë§Œë“¤ê¸°
-  label_subproject_new: ìƒˆ í•˜ìœ„ í”„ë¡œì íŠ¸
-  text_own_membership_delete_confirmation: |-
-    ê¶Œí•œë“¤ ì¼ë¶€ ë˜ëŠ” ì „ë¶€ë¥¼ ë§‰ ì‚­ì œí•˜ë ¤ê³  í•˜ê³  ìžˆìŠµë‹ˆë‹¤. ê·¸ë ‡ê²Œ ë˜ë©´ ì´ í”„ë¡œì íŠ¸ë¥¼ ë”ì´ìƒ ìˆ˜ì •í•  ìˆ˜ ì—†ê²Œ ë©ë‹ˆë‹¤.
-    ê³„ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?
-  label_close_versions: ì™„ë£Œëœ ë²„ì „ ë‹«ê¸°
-  label_board_sticky: ë¶™ë°•ì´
-  label_board_locked: ìž ê¸ˆ
-  permission_export_wiki_pages: ìœ„í‚¤ íŽ˜ì´ì§€ ë‚´ë³´ë‚´ê¸°
-  setting_cache_formatted_text: í˜•ì‹ì„ ê°€ì§„ í…ìŠ¤íŠ¸ ë¹ ë¥¸ ìž„ì‹œ ê¸°ì–µ
-  permission_manage_project_activities: í”„ë¡œì íŠ¸ ìž‘ì—…ë‚´ì—­ ê´€ë¦¬
-  error_unable_delete_issue_status: ì¼ê° ìƒíƒœë¥¼ ì§€ìš¸ ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
-  label_profile: ì‚¬ìš©ìžì •ë³´
-  permission_manage_subtasks: í•˜ìœ„ ì¼ê° ê´€ë¦¬
-  field_parent_issue: ìƒìœ„ ì¼ê°
-  label_subtask_plural: í•˜ìœ„ ì¼ê°
-  label_project_copy_notifications: í”„ë¡œì íŠ¸ ë³µì‚¬ ì¤‘ì— ì´ë©”ì¼ ì•Œë¦¼ ë³´ë‚´ê¸°
-  error_can_not_delete_custom_field: ì‚¬ìš©ìž ì •ì˜ í•„ë“œë¥¼ ì‚­ì œí•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
-  error_unable_to_connect: ì—°ê²°í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤((%{value})
-  error_can_not_remove_role: ì´ ì—­í• ì€ í˜„ìž¬ ì‚¬ìš© ì¤‘ì´ì´ì„œ ì‚­ì œí•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
-  error_can_not_delete_tracker: ì´ ìœ í˜•ì˜ ì¼ê°ë“¤ì´ ìžˆì–´ì„œ ì‚­ì œí•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
-  field_principal: ì‹ ì›
-  label_my_page_block: ë‚´ íŽ˜ì´ì§€ ì¶œë ¥í™”ë©´
-  notice_failed_to_save_members: "%{errors}:êµ¬ì„±ì›ì„ ì €ìž¥ ì¤‘ ì‹¤íŒ¨í•˜ì˜€ìŠµë‹ˆë‹¤"
-  text_zoom_out: ë” ìž‘ê²Œ
-  text_zoom_in: ë” í¬ê²Œ
-  notice_unable_delete_time_entry: ì‹œê°„ ê¸°ë¡ í•­ëª©ì„ ì‚­ì œí•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
-  label_overall_spent_time: ì´ ì†Œìš”ì‹œê°„
-  field_time_entries: ê¸°ë¡ëœ ì‹œê°„
-  project_module_gantt: Gantt ì± íŠ¸
-  project_module_calendar: ë‹¬ë ¥
-  button_edit_associated_wikipage: "ì—°ê´€ëœ ìœ„í‚¤ íŽ˜ì´ì§€ %{page_title} ìˆ˜ì •"
-  text_are_you_sure_with_children: ì¼ê°ê³¼ ëª¨ë“  í•˜ìœ„ ì¼ê°ë“¤ì„ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?
-  field_text: í…ìŠ¤íŠ¸ ì˜ì—­
-  label_user_mail_option_only_owner: ë‚´ê°€ ì €ìžì¸ ì‚¬í•­ë§Œ
-  setting_default_notification_option: ê¸°ë³¸ ì•Œë¦¼ ì˜µì…˜
-  label_user_mail_option_only_my_events: ë‚´ê°€ ì§€ì¼œë³´ê±°ë‚˜ ì†í•´ìžˆëŠ” ì‚¬í•­ë§Œ
-  label_user_mail_option_only_assigned: ë‚´ì—ê²Œ í• ë‹¹ëœ ì‚¬í•­ë§Œ
-  label_user_mail_option_none: ì•Œë¦¼ ì—†ìŒ
-  field_member_of_group: í• ë‹¹ëœ ì‚¬ëžŒì˜ ê·¸ë£¹
-  field_assigned_to_role: í• ë‹¹ëœ ì‚¬ëžŒì˜ ì—­í• 
-  notice_not_authorized_archived_project: ì ‘ê·¼í•˜ë ¤ëŠ” í”„ë¡œì íŠ¸ëŠ” ì´ë¯¸ ìž ê¸ˆë³´ê´€ë˜ì–´ ìžˆìŠµë‹ˆë‹¤.
-  label_principal_search: "ì‚¬ìš©ìž ë° ê·¸ë£¹ ì°¾ê¸°:"
-  label_user_search: "ì‚¬ìš©ìž ì°¾ê¸°::"
-  field_visible: ë³´ì´ê¸°
-  setting_emails_header: ì´ë©”ì¼ í—¤ë”
-  setting_commit_logtime_activity_id: ê¸°ë¡ëœ ì‹œê°„ì— ì ìš©í•  ìž‘ì—…ë¶„ë¥˜
-  text_time_logged_by_changeset: "ë³€ê²½ë¬¶ìŒ %{value}ì—ì„œ ì ìš©ë˜ì—ˆìŠµë‹ˆë‹¤."
-  setting_commit_logtime_enabled: ì»¤ë°‹ ì‹œì ì— ìž‘ì—… ì‹œê°„ ê¸°ë¡ í™œì„±í™”
-  notice_gantt_chart_truncated: "í‘œì‹œí•  ìˆ˜ ìžˆëŠ” ìµœëŒ€ í•­ëª©ìˆ˜(%{max})ë¥¼ ì´ˆê³¼í•˜ì—¬ ì°¨íŠ¸ê°€ ìž˜ë ¸ìŠµë‹ˆë‹¤."
-  setting_gantt_items_limit: "Gantt ì°¨íŠ¸ì— í‘œì‹œë˜ëŠ” ìµœëŒ€ í•­ëª©ìˆ˜"
-  field_warn_on_leaving_unsaved: "ì €ìž¥í•˜ì§€ ì•Šì€ íŽ˜ì´ì§€ë¥¼ ë¹ ì ¸ë‚˜ê°ˆ ë•Œ ë‚˜ì—ê²Œ ì•Œë¦¼"
-  text_warn_on_leaving_unsaved: "í˜„ìž¬ íŽ˜ì´ì§€ëŠ” ì €ìž¥ë˜ì§€ ì•Šì€ ë¬¸ìžê°€ ìžˆìŠµë‹ˆë‹¤. ì´ íŽ˜ì´ì§€ë¥¼ ë¹ ì ¸ë‚˜ê°€ë©´ ë‚´ìš©ì„ ìžƒì„ê²ƒìž…ë‹ˆë‹¤."
-  label_my_queries: "ë‚´ ê²€ìƒ‰ ì–‘ì‹"
-  text_journal_changed_no_detail: "%{label}ì´ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
-  label_news_comment_added: "ë‰´ìŠ¤ì— ì„¤ëª…ì´ ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
-  button_expand_all: "ëª¨ë‘ í™•ìž¥"
-  button_collapse_all: "ëª¨ë‘ ì¶•ì†Œ"
-  label_additional_workflow_transitions_for_assignee: "ì‚¬ìš©ìžê°€ ìž‘ì—…ìžì¼ ë•Œ í—ˆìš©ë˜ëŠ” ì¶”ê°€ ìƒíƒœ"
-  label_additional_workflow_transitions_for_author: "ì‚¬ìš©ìžê°€ ì €ìžì¼ ë•Œ í—ˆìš©ë˜ëŠ” ì¶”ê°€ ìƒíƒœ"
-  label_bulk_edit_selected_time_entries: "ì„ íƒëœ ì†Œìš” ì‹œê°„ ëŒ€ëŸ‰ íŽ¸ì§‘"
-  text_time_entries_destroy_confirmation: "ì„ íƒí•œ ì†Œìš” ì‹œê°„ í•­ëª©ì„ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: "ë§ê¸€ì´ ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
-  label_issue_status_updated: "ìƒíƒœê°€ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
-  label_issue_priority_updated: "ìš°ì„  ìˆœìœ„ê°€ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
-  label_issues_visibility_own: "ì¼ê°ì„ ìƒì„±í•˜ê±°ë‚˜ í• ë‹¹ëœ ì‚¬ìš©ìž"
-  field_issues_visibility: "ì¼ê° ë³´ìž„"
-  label_issues_visibility_all: "ëª¨ë“  ì¼ê°"
-  permission_set_own_issues_private: "ìžì‹ ì˜ ì¼ê°ì„ ê³µê°œë‚˜ ë¹„ê³µê°œë¡œ ì„¤ì •"
-  field_is_private: "ë¹„ê³µê°œ"
-  permission_set_issues_private: "ì¼ê°ì„ ê³µê°œë‚˜ ë¹„ê³µê°œë¡œ ì„¤ì •"
-  label_issues_visibility_public: "ëª¨ë“  ë¹„ê³µê°œ ì¼ê°"
-  text_issues_destroy_descendants_confirmation: "%{count} ê°œì˜ í•˜ìœ„ ì¼ê°ì„ ì‚­ì œí•  ê²ƒìž…ë‹ˆë‹¤."
-  field_commit_logs_encoding: "ì œì¶œ(commit) ê¸°ë¡ ì¸ì½”ë”©"
-  field_scm_path_encoding: "ê²½ë¡œ ì¸ì½”ë”©"
-  text_scm_path_encoding_note: "ê¸°ë³¸: UTF-8"
-  field_path_to_repository: "ì €ìž¥ì†Œ ê²½ë¡œ"
-  field_root_directory: "ë£¨íŠ¸ ê²½ë¡œ"
-  field_cvs_module: "ëª¨ë“ˆ"
-  field_cvsroot: "CVS ë£¨íŠ¸"
-  text_mercurial_repository_note: "ë¡œì»¬ ì €ìž¥ì†Œ (ì˜ˆ: /hgrepo, c:\hgrepo)"
-  text_scm_command: "ëª…ë ¹"
-  text_scm_command_version: "ë²„ì „"
-  label_git_report_last_commit: "íŒŒì¼ì´ë‚˜ í´ë”ì˜ ë§ˆì§€ë§‰ ì œì¶œ(commit)ì„ ë³´ê³ "
-  text_scm_config: "SCM ëª…ë ¹ì„ config/configuration.ymlì—ì„œ ìˆ˜ì •í•  ìˆ˜ ìžˆìŠµë‹ˆë‹¤. ìˆ˜ì •í›„ì—ëŠ” ìž¬ì‹œìž‘í•˜ì‹­ì‹œì˜¤."
-  text_scm_command_not_available: "SCM ëª…ë ¹ì„ ì‚¬ìš©í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤. ê´€ë¦¬ íŽ˜ì´ì§€ì˜ ì„¤ì •ì„ ê²€ì‚¬í•˜ì‹­ì‹œì˜¤."
-  notice_issue_successful_create: "%{id} ì¼ê°ì´ ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤."
-  label_between: "ì‚¬ì´"
-  setting_issue_group_assignment: "ê·¸ë£¹ì— ì¼ê° í• ë‹¹ í—ˆìš©"
-  label_diff: "ë¹„êµ(diff)"
-  text_git_repository_note: "ì €ìž¥ì†ŒëŠ” ë…¸ì¶œëœ ë¡œì»¬ìž…ë‹ˆë‹¤. (ì˜ˆ: /gitrepo, c:\gitrepo)"
-  description_query_sort_criteria_direction: "ì •ë ¬ ë°©í–¥"
-  description_project_scope: "ê²€ìƒ‰ ë²”ìœ„"
-  description_filter: "ê²€ìƒ‰ ì¡°ê±´"
-  description_user_mail_notification: "ë©”ì¼ ì•Œë¦¼ ì„¤ì •"
-  description_date_from: "ì‹œìž‘ ë‚ ì§œ ìž…ë ¥"
-  description_message_content: "ë©”ì„¸ì§€ ë‚´ìš©"
-  description_available_columns: "ê°€ëŠ¥í•œ ì»¬ëŸ¼"
-  description_date_range_interval: ì‹œìž‘ê³¼ ë ë‚ ì§œë¡œ ë²”ìœ„ë¥¼ ì„ íƒí•˜ì‹­ì‹œì˜¤."
-  description_issue_category_reassign: "ì¼ê° ë²”ì£¼ë¥¼ ì„ íƒí•˜ì‹­ì‹œì˜¤."
-  description_search: "ê²€ìƒ‰í•­ëª©"
-  description_notes: "ë§ê¸€"
-  description_date_range_list: "ëª©ë¡ì—ì„œ ë²”ìœ„ë¥¼ ì„ íƒ í•˜ì‹­ì‹œì˜¤."
-  description_choose_project: "í”„ë¡œì íŠ¸"
-  description_date_to: "ì¢…ë£Œ ë‚ ì§œ ìž…ë ¥"
-  description_query_sort_criteria_attribute: "ì •ë ¬ ì†ì„±"
-  description_wiki_subpages_reassign: "ìƒˆë¡œìš´ ìƒìœ„ íŽ˜ì´ì§€ë¥¼ ì„ íƒí•˜ì‹­ì‹œì˜¤."
-  description_selected_columns: "ì„ íƒëœ ì»¬ëŸ¼"
-  label_parent_revision: "ìƒìœ„"
-  label_child_revision: "í•˜ìœ„"
-  error_scm_annotate_big_text_file: "ìµœëŒ€ í…ìŠ¤íŠ¸ íŒŒì¼ í¬ê¸°ë¥¼ ì´ˆê³¼ í•˜ë©´ í•­ëª©ì€ ì´ë ¥í™” ë  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
-  setting_default_issue_start_date_to_creation_date: "ìƒˆë¡œìš´ ì¼ê°ì˜ ì‹œìž‘ ë‚ ì§œë¡œ ì˜¤ëŠ˜ ë‚ ì§œ ì‚¬ìš©"
-  button_edit_section: "ì´ ë¶€ë¶„ ìˆ˜ì •"
-  setting_repositories_encodings: "ì²¨ë¶€íŒŒì¼ì´ë‚˜ ì €ìž¥ì†Œ ì¸ì½”ë”©"
-  description_all_columns: "ëª¨ë“  ì»¬ëŸ¼"
-  button_export: "ë‚´ë³´ë‚´ê¸°"
-  label_export_options: "ë‚´ë³´ë‚´ê¸° ì˜µì…˜: %{export_format}"
-  error_attachment_too_big: "ì´ íŒŒì¼ì€ ì œí•œëœ í¬ê¸°(%{max_size})ë¥¼ ì´ˆê³¼í•˜ì˜€ê¸° ë•Œë¬¸ì— ì—…ë¡œë“œ í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7a2b37fe2ff5ae9d62a418e469dc500c74dfab37.svn-base
--- a/.svn/pristine/7a/7a2b37fe2ff5ae9d62a418e469dc500c74dfab37.svn-base
+++ /dev/null
@@ -1,85 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class SortHelperTest < ActionView::TestCase
-  include SortHelper
-
-  def setup
-    @session = nil
-    @sort_param = nil
-  end
-
-  def test_default_sort_clause_with_array
-    sort_init 'attr1', 'desc'
-    sort_update(['attr1', 'attr2'])
-
-    assert_equal 'attr1 DESC', sort_clause
-  end
-
-  def test_default_sort_clause_with_hash
-    sort_init 'attr1', 'desc'
-    sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
-
-    assert_equal 'table1.attr1 DESC', sort_clause
-  end
-
-  def test_default_sort_clause_with_multiple_columns
-    sort_init 'attr1', 'desc'
-    sort_update({'attr1' => ['table1.attr1', 'table1.attr2'], 'attr2' => 'table2.attr2'})
-
-    assert_equal 'table1.attr1 DESC, table1.attr2 DESC', sort_clause
-  end
-
-  def test_params_sort
-    @sort_param = 'attr1,attr2:desc'
-
-    sort_init 'attr1', 'desc'
-    sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
-
-    assert_equal 'table1.attr1, table2.attr2 DESC', sort_clause
-    assert_equal 'attr1,attr2:desc', @session['foo_bar_sort']
-  end
-
-  def test_invalid_params_sort
-    @sort_param = 'invalid_key'
-
-    sort_init 'attr1', 'desc'
-    sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
-
-    assert_equal 'table1.attr1 DESC', sort_clause
-    assert_equal 'attr1:desc', @session['foo_bar_sort']
-  end
-
-  def test_invalid_order_params_sort
-    @sort_param = 'attr1:foo:bar,attr2'
-
-    sort_init 'attr1', 'desc'
-    sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
-
-    assert_equal 'table1.attr1, table2.attr2', sort_clause
-    assert_equal 'attr1,attr2', @session['foo_bar_sort']
-  end
-
-  private
-
-  def controller_name; 'foo'; end
-  def action_name; 'bar'; end
-  def params; {:sort => @sort_param}; end
-  def session; @session ||= {}; end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7a370e17f62630071e4722f1f8c066b9cfb99711.svn-base
--- /dev/null
+++ b/.svn/pristine/7a/7a370e17f62630071e4722f1f8c066b9cfb99711.svn-base
@@ -0,0 +1,32 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module WorkflowsHelper
+  def field_required?(field)
+    field.is_a?(CustomField) ? field.is_required? : %w(project_id tracker_id subject priority_id is_private).include?(field)
+  end
+
+  def field_permission_tag(permissions, status, field)
+    name = field.is_a?(CustomField) ? field.id.to_s : field
+    options = [["", ""], [l(:label_readonly), "readonly"]]
+    options << [l(:label_required), "required"] unless field_required?(field)
+
+    select_tag("permissions[#{name}][#{status.id}]", options_for_select(options, permissions[status.id][name]))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7a59e0de6fb3a65fd73a1071a5762041233e7537.svn-base
--- a/.svn/pristine/7a/7a59e0de6fb3a65fd73a1071a5762041233e7537.svn-base
+++ /dev/null
@@ -1,494 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'repositories_controller'
-
-# Re-raise errors caught by the controller.
-class RepositoriesController; def rescue_action(e) raise e end; end
-
-class RepositoriesGitControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles,
-           :repositories, :enabled_modules
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
-  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
-  PRJ_ID     = 3
-  CHAR_1_HEX = "\xc3\x9c"
-  NUM_REV = 21
-
-  ## Git, Mercurial and CVS path encodings are binary.
-  ## Subversion supports URL encoding for path.
-  ## Redmine Mercurial adapter and extension use URL encoding.
-  ## Git accepts only binary path in command line parameter.
-  ## So, there is no way to use binary command line parameter in JRuby.
-  JRUBY_SKIP     = (RUBY_PLATFORM == 'java')
-  JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
-
-  def setup
-    @ruby19_non_utf8_pass =
-      (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8')
-
-    @controller = RepositoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @project    = Project.find(PRJ_ID)
-    @repository = Repository::Git.create(
-                      :project       => @project,
-                      :url           => REPOSITORY_PATH,
-                      :path_encoding => 'ISO-8859-1'
-                      )
-    assert @repository
-    @char_1        = CHAR_1_HEX.dup
-    if @char_1.respond_to?(:force_encoding)
-      @char_1.force_encoding('UTF-8')
-    end
-
-    Setting.default_language = 'en'
-  end
-
-  if File.directory?(REPOSITORY_PATH)
-    def test_browse_root
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :show, :id => PRJ_ID
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal 9, assigns(:entries).size
-      assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'this_is_a_really_long_and_verbose_directory_name' && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
-      assert assigns(:entries).detect {|e| e.name == 'copied_README' && e.kind == 'file'}
-      assert assigns(:entries).detect {|e| e.name == 'new_file.txt' && e.kind == 'file'}
-      assert assigns(:entries).detect {|e| e.name == 'renamed_test.txt' && e.kind == 'file'}
-      assert assigns(:entries).detect {|e| e.name == 'filemane with spaces.txt' && e.kind == 'file'}
-      assert assigns(:entries).detect {|e| e.name == ' filename with a leading space.txt ' && e.kind == 'file'}
-      assert_not_nil assigns(:changesets)
-      assert assigns(:changesets).size > 0
-    end
-
-    def test_browse_branch
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :rev => 'test_branch'
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal 4, assigns(:entries).size
-      assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
-      assert assigns(:entries).detect {|e| e.name == 'test.txt' && e.kind == 'file'}
-      assert_not_nil assigns(:changesets)
-      assert assigns(:changesets).size > 0
-    end
-
-    def test_browse_tag
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-       [
-        "tag00.lightweight",
-        "tag01.annotated",
-       ].each do |t1|
-        get :show, :id => PRJ_ID, :rev => t1
-        assert_response :success
-        assert_template 'show'
-        assert_not_nil assigns(:entries)
-        assert assigns(:entries).size > 0
-        assert_not_nil assigns(:changesets)
-        assert assigns(:changesets).size > 0
-      end
-    end
-
-    def test_browse_directory
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :path => ['images']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['edit.png'], assigns(:entries).collect(&:name)
-      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
-      assert_not_nil entry
-      assert_equal 'file', entry.kind
-      assert_equal 'images/edit.png', entry.path
-      assert_not_nil assigns(:changesets)
-      assert assigns(:changesets).size > 0
-    end
-
-    def test_browse_at_given_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :path => ['images'],
-          :rev => '7234cb2750b63f47bff735edc50a1c0a433c2518'
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['delete.png'], assigns(:entries).collect(&:name)
-      assert_not_nil assigns(:changesets)
-      assert assigns(:changesets).size > 0
-    end
-
-    def test_changes
-      get :changes, :id => PRJ_ID, :path => ['images', 'edit.png']
-      assert_response :success
-      assert_template 'changes'
-      assert_tag :tag => 'h2', :content => 'edit.png'
-    end
-
-    def test_entry_show
-      get :entry, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb']
-      assert_response :success
-      assert_template 'entry'
-      # Line 19
-      assert_tag :tag => 'th',
-                 :content => '11',
-                 :attributes => { :class => 'line-num' },
-                 :sibling => { :tag => 'td', :content => /WITHOUT ANY WARRANTY/ }
-    end
-
-    def test_entry_show_latin_1
-      if @ruby19_non_utf8_pass
-        puts_ruby19_non_utf8_pass()
-      elsif JRUBY_SKIP
-        puts JRUBY_SKIP_STR
-      else
-        with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
-          ['57ca437c', '57ca437c0acbbcb749821fdf3726a1367056d364'].each do |r1|
-            get :entry, :id => PRJ_ID,
-                :path => ['latin-1-dir', "test-#{@char_1}.txt"], :rev => r1
-            assert_response :success
-            assert_template 'entry'
-            assert_tag :tag => 'th',
-                   :content => '1',
-                   :attributes => { :class => 'line-num' },
-                   :sibling => { :tag => 'td',
-                                 :content => /test-#{@char_1}.txt/ }
-          end
-        end
-      end
-    end
-
-    def test_entry_download
-      get :entry, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb'],
-          :format => 'raw'
-      assert_response :success
-      # File content
-      assert @response.body.include?('WITHOUT ANY WARRANTY')
-    end
-
-    def test_directory_entry
-      get :entry, :id => PRJ_ID, :path => ['sources']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entry)
-      assert_equal 'sources', assigns(:entry).name
-    end
-
-    def test_diff
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      # Full diff of changeset 2f9c0091
-      ['inline', 'sbs'].each do |dt|
-        get :diff,
-            :id   => PRJ_ID,
-            :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7',
-            :type => dt
-        assert_response :success
-        assert_template 'diff'
-        # Line 22 removed
-        assert_tag :tag => 'th',
-                   :content => /22/,
-                   :sibling => { :tag => 'td',
-                                 :attributes => { :class => /diff_out/ },
-                                 :content => /def remove/ }
-        assert_tag :tag => 'h2', :content => /2f9c0091/
-      end
-    end
-
-    def test_diff_truncated
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      Setting.diff_max_lines_displayed = 5
-
-      # Truncated diff of changeset 2f9c0091
-      with_cache do
-        get :diff, :id   => PRJ_ID, :type => 'inline',
-            :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
-        assert_response :success
-        assert @response.body.include?("... This diff was truncated")
-
-        Setting.default_language = 'fr'
-        get :diff, :id   => PRJ_ID, :type => 'inline',
-            :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
-        assert_response :success
-        assert ! @response.body.include?("... This diff was truncated")
-        assert @response.body.include?("... Ce diff")
-      end
-    end
-
-    def test_diff_two_revs
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['inline', 'sbs'].each do |dt|
-        get :diff,
-            :id     => PRJ_ID,
-            :rev    => '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
-            :rev_to => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7',
-            :type   => dt
-        assert_response :success
-        assert_template 'diff'
-        diff = assigns(:diff)
-        assert_not_nil diff
-        assert_tag :tag => 'h2', :content => /2f9c0091:61b685fb/
-      end
-    end
-
-    def test_diff_latin_1
-      if @ruby19_non_utf8_pass
-        puts_ruby19_non_utf8_pass()
-      else
-        with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
-          ['57ca437c', '57ca437c0acbbcb749821fdf3726a1367056d364'].each do |r1|
-            ['inline', 'sbs'].each do |dt|
-              get :diff, :id => PRJ_ID, :rev => r1, :type => dt
-              assert_response :success
-              assert_template 'diff'
-              assert_tag :tag => 'thead',
-                         :descendant => {
-                           :tag => 'th',
-                           :attributes => { :class => 'filename' } ,
-                           :content => /latin-1-dir\/test-#{@char_1}.txt/ ,
-                          },
-                         :sibling => {
-                           :tag => 'tbody',
-                           :descendant => {
-                              :tag => 'td',
-                              :attributes => { :class => /diff_in/ },
-                              :content => /test-#{@char_1}.txt/
-                           }
-                         }
-            end
-          end
-        end
-      end
-    end
-
-    def test_save_diff_type
-      @request.session[:user_id] = 1 # admin
-      user = User.find(1)
-      get :diff,
-          :id   => PRJ_ID,
-          :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
-      assert_response :success
-      assert_template 'diff'
-      user.reload
-      assert_equal "inline", user.pref[:diff_type]
-      get :diff,
-          :id   => PRJ_ID,
-          :rev  => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7',
-          :type => 'sbs'
-      assert_response :success
-      assert_template 'diff'
-      user.reload
-      assert_equal "sbs", user.pref[:diff_type]
-    end
-
-    def test_annotate
-      get :annotate, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb']
-      assert_response :success
-      assert_template 'annotate'
-      # Line 24, changeset 2f9c0091
-      assert_tag :tag => 'th', :content => '24',
-                 :sibling => {
-                    :tag => 'td',
-                    :child => {
-                       :tag => 'a',
-                       :content => /2f9c0091/
-                       }
-                    }
-      assert_tag :tag => 'th', :content => '24',
-                 :sibling => { :tag => 'td', :content => /jsmith/ }
-      assert_tag :tag => 'th', :content => '24',
-                 :sibling => {
-                    :tag => 'td',
-                    :child => {
-                       :tag => 'a',
-                       :content => /2f9c0091/
-                       }
-                    }
-      assert_tag :tag => 'th', :content => '24',
-                 :sibling => { :tag => 'td', :content => /watcher =/ }
-    end
-
-    def test_annotate_at_given_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :annotate, :id => PRJ_ID, :rev => 'deff7',
-          :path => ['sources', 'watchers_controller.rb']
-      assert_response :success
-      assert_template 'annotate'
-      assert_tag :tag => 'h2', :content => /@ deff712f/
-    end
-
-    def test_annotate_binary_file
-      get :annotate, :id => PRJ_ID, :path => ['images', 'edit.png']
-      assert_response 500
-      assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ },
-                              :content => /cannot be annotated/
-    end
-
-    def test_annotate_error_when_too_big
-      with_settings :file_max_size_displayed => 1 do
-        get :annotate, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb'], :rev => 'deff712f'
-        assert_response 500
-        assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ },
-                                :content => /exceeds the maximum text file size/
-
-        get :annotate, :id => PRJ_ID, :path => ['README'], :rev => '7234cb2'
-        assert_response :success
-        assert_template 'annotate'
-      end
-    end
-
-    def test_annotate_latin_1
-      if @ruby19_non_utf8_pass
-        puts_ruby19_non_utf8_pass()
-      elsif JRUBY_SKIP
-        puts JRUBY_SKIP_STR
-      else
-        with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
-          ['57ca437c', '57ca437c0acbbcb749821fdf3726a1367056d364'].each do |r1|
-            get :annotate, :id => PRJ_ID,
-                :path => ['latin-1-dir', "test-#{@char_1}.txt"], :rev => r1
-            assert_tag :tag => 'th',
-                       :content => '1',
-                       :attributes => { :class => 'line-num' },
-                       :sibling => { :tag => 'td',
-                                     :content => /test-#{@char_1}.txt/ }
-          end
-        end
-      end
-    end
-
-    def test_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['61b685fbe55ab05b5ac68402d5720c1a6ac973d1', '61b685f'].each do |r|
-        get :revision, :id => PRJ_ID, :rev => r
-        assert_response :success
-        assert_template 'revision'
-      end
-    end
-
-    def test_empty_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['', ' ', nil].each do |r|
-        get :revision, :id => PRJ_ID, :rev => r
-        assert_response 404
-        assert_error_tag :content => /was not found/
-      end
-    end
-
-    def test_destroy_valid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-
-    def test_destroy_invalid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-
-      @repository = Repository::Git.create(
-                      :project       => @project,
-                      :url           => "/invalid",
-                      :path_encoding => 'ISO-8859-1'
-                      )
-      assert @repository
-      @repository.fetch_changesets
-      @repository.reload
-      assert_equal 0, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-
-    private
-
-    def puts_ruby19_non_utf8_pass
-      puts "TODO: This test fails in Ruby 1.9 " +
-           "and Encoding.default_external is not UTF-8. " +
-           "Current value is '#{Encoding.default_external.to_s}'"
-    end
-  else
-    puts "Git test repository NOT FOUND. Skipping functional tests !!!"
-    def test_fake; assert true end
-  end
-
-  private
-  def with_cache(&block)
-    before = ActionController::Base.perform_caching
-    ActionController::Base.perform_caching = true
-    block.call
-    ActionController::Base.perform_caching = before
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7a752fd775f30c709fd8d90851ab52b265da090b.svn-base
--- /dev/null
+++ b/.svn/pristine/7a/7a752fd775f30c709fd8d90851ab52b265da090b.svn-base
@@ -0,0 +1,439 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssuesController < ApplicationController
+  menu_item :new_issue, :only => [:new, :create]
+  default_search_scope :issues
+
+  before_filter :find_issue, :only => [:show, :edit, :update]
+  before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
+  before_filter :find_project, :only => [:new, :create, :update_form]
+  before_filter :authorize, :except => [:index]
+  before_filter :find_optional_project, :only => [:index]
+  before_filter :check_for_default_issue_status, :only => [:new, :create]
+  before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form]
+  accept_rss_auth :index, :show
+  accept_api_auth :index, :show, :create, :update, :destroy
+
+  rescue_from Query::StatementInvalid, :with => :query_statement_invalid
+
+  helper :journals
+  helper :projects
+  include ProjectsHelper
+  helper :custom_fields
+  include CustomFieldsHelper
+  helper :issue_relations
+  include IssueRelationsHelper
+  helper :watchers
+  include WatchersHelper
+  helper :attachments
+  include AttachmentsHelper
+  helper :queries
+  include QueriesHelper
+  helper :repositories
+  include RepositoriesHelper
+  helper :sort
+  include SortHelper
+  include IssuesHelper
+  helper :timelog
+  include Redmine::Export::PDF
+
+  def index
+    retrieve_query
+    sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
+    sort_update(@query.sortable_columns)
+    @query.sort_criteria = sort_criteria.to_a
+
+    if @query.valid?
+      case params[:format]
+      when 'csv', 'pdf'
+        @limit = Setting.issues_export_limit.to_i
+      when 'atom'
+        @limit = Setting.feeds_limit.to_i
+      when 'xml', 'json'
+        @offset, @limit = api_offset_and_limit
+      else
+        @limit = per_page_option
+      end
+
+      @issue_count = @query.issue_count
+      @issue_pages = Paginator.new @issue_count, @limit, params['page']
+      @offset ||= @issue_pages.offset
+      @issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
+                              :order => sort_clause,
+                              :offset => @offset,
+                              :limit => @limit)
+      @issue_count_by_group = @query.issue_count_by_group
+
+      respond_to do |format|
+        format.html { render :template => 'issues/index', :layout => !request.xhr? }
+        format.api  {
+          Issue.load_visible_relations(@issues) if include_in_api_response?('relations')
+        }
+        format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
+        format.csv  { send_data(query_to_csv(@issues, @query, params), :type => 'text/csv; header=present', :filename => 'issues.csv') }
+        format.pdf  { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'issues.pdf') }
+      end
+    else
+      respond_to do |format|
+        format.html { render(:template => 'issues/index', :layout => !request.xhr?) }
+        format.any(:atom, :csv, :pdf) { render(:nothing => true) }
+        format.api { render_validation_errors(@query) }
+      end
+    end
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def show
+    @journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all
+    @journals.each_with_index {|j,i| j.indice = i+1}
+    @journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
+    @journals.reverse! if User.current.wants_comments_in_reverse_order?
+
+    @changesets = @issue.changesets.visible.all
+    @changesets.reverse! if User.current.wants_comments_in_reverse_order?
+
+    @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
+    @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
+    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
+    @priorities = IssuePriority.active
+    @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
+    respond_to do |format|
+      format.html {
+        retrieve_previous_and_next_issue_ids
+        render :template => 'issues/show'
+      }
+      format.api
+      format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' }
+      format.pdf  {
+        pdf = issue_to_pdf(@issue, :journals => @journals)
+        send_data(pdf, :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf")
+      }
+    end
+  end
+
+  # Add a new issue
+  # The new issue will be created from an existing one if copy_from parameter is given
+  def new
+    respond_to do |format|
+      format.html { render :action => 'new', :layout => !request.xhr? }
+    end
+  end
+
+  def create
+    call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue })
+    @issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads]))
+    if @issue.save
+      call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue})
+      respond_to do |format|
+        format.html {
+          render_attachment_warning_if_needed(@issue)
+          flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("##{@issue.id}", issue_path(@issue), :title => @issue.subject))
+          if params[:continue]
+            attrs = {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?}
+            redirect_to new_project_issue_path(@issue.project, :issue => attrs)
+          else
+            redirect_to issue_path(@issue)
+          end
+        }
+        format.api  { render :action => 'show', :status => :created, :location => issue_url(@issue) }
+      end
+      return
+    else
+      respond_to do |format|
+        format.html { render :action => 'new' }
+        format.api  { render_validation_errors(@issue) }
+      end
+    end
+  end
+
+  def edit
+    return unless update_issue_from_params
+
+    respond_to do |format|
+      format.html { }
+      format.xml  { }
+    end
+  end
+
+  def update
+    return unless update_issue_from_params
+    @issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads]))
+    saved = false
+    begin
+      saved = @issue.save_issue_with_child_records(params, @time_entry)
+    rescue ActiveRecord::StaleObjectError
+      @conflict = true
+      if params[:last_journal_id]
+        @conflict_journals = @issue.journals_after(params[:last_journal_id]).all
+        @conflict_journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
+      end
+    end
+
+    if saved
+      render_attachment_warning_if_needed(@issue)
+      flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record?
+
+      respond_to do |format|
+        format.html { redirect_back_or_default issue_path(@issue) }
+        format.api  { render_api_ok }
+      end
+    else
+      respond_to do |format|
+        format.html { render :action => 'edit' }
+        format.api  { render_validation_errors(@issue) }
+      end
+    end
+  end
+
+  # Updates the issue form when changing the project, status or tracker
+  # on issue creation/update
+  def update_form
+  end
+
+  # Bulk edit/copy a set of issues
+  def bulk_edit
+    @issues.sort!
+    @copy = params[:copy].present?
+    @notes = params[:notes]
+
+    if User.current.allowed_to?(:move_issues, @projects)
+      @allowed_projects = Issue.allowed_target_projects_on_move
+      if params[:issue]
+        @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id].to_s}
+        if @target_project
+          target_projects = [@target_project]
+        end
+      end
+    end
+    target_projects ||= @projects
+
+    if @copy
+      @available_statuses = [IssueStatus.default]
+    else
+      @available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
+    end
+    @custom_fields = target_projects.map{|p|p.all_issue_custom_fields}.reduce(:&)
+    @assignables = target_projects.map(&:assignable_users).reduce(:&)
+    @trackers = target_projects.map(&:trackers).reduce(:&)
+    @versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&)
+    @categories = target_projects.map {|p| p.issue_categories}.reduce(:&)
+    if @copy
+      @attachments_present = @issues.detect {|i| i.attachments.any?}.present?
+      @subtasks_present = @issues.detect {|i| !i.leaf?}.present?
+    end
+
+    @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&)
+    render :layout => false if request.xhr?
+  end
+
+  def bulk_update
+    @issues.sort!
+    @copy = params[:copy].present?
+    attributes = parse_params_for_bulk_issue_attributes(params)
+
+    unsaved_issue_ids = []
+    moved_issues = []
+
+    if @copy && params[:copy_subtasks].present?
+      # Descendant issues will be copied with the parent task
+      # Don't copy them twice
+      @issues.reject! {|issue| @issues.detect {|other| issue.is_descendant_of?(other)}}
+    end
+
+    @issues.each do |issue|
+      issue.reload
+      if @copy
+        issue = issue.copy({},
+          :attachments => params[:copy_attachments].present?,
+          :subtasks => params[:copy_subtasks].present?
+        )
+      end
+      journal = issue.init_journal(User.current, params[:notes])
+      issue.safe_attributes = attributes
+      call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
+      if issue.save
+        moved_issues << issue
+      else
+        # Keep unsaved issue ids to display them in flash error
+        unsaved_issue_ids << issue.id
+      end
+    end
+    set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids)
+
+    if params[:follow]
+      if @issues.size == 1 && moved_issues.size == 1
+        redirect_to issue_path(moved_issues.first)
+      elsif moved_issues.map(&:project).uniq.size == 1
+        redirect_to project_issues_path(moved_issues.map(&:project).first)
+      end
+    else
+      redirect_back_or_default _project_issues_path(@project)
+    end
+  end
+
+  def destroy
+    @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f
+    if @hours > 0
+      case params[:todo]
+      when 'destroy'
+        # nothing to do
+      when 'nullify'
+        TimeEntry.update_all('issue_id = NULL', ['issue_id IN (?)', @issues])
+      when 'reassign'
+        reassign_to = @project.issues.find_by_id(params[:reassign_to_id])
+        if reassign_to.nil?
+          flash.now[:error] = l(:error_issue_not_found_in_project)
+          return
+        else
+          TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues])
+        end
+      else
+        # display the destroy form if it's a user request
+        return unless api_request?
+      end
+    end
+    @issues.each do |issue|
+      begin
+        issue.reload.destroy
+      rescue ::ActiveRecord::RecordNotFound # raised by #reload if issue no longer exists
+        # nothing to do, issue was already deleted (eg. by a parent)
+      end
+    end
+    respond_to do |format|
+      format.html { redirect_back_or_default _project_issues_path(@project) }
+      format.api  { render_api_ok }
+    end
+  end
+
+  private
+
+  def find_project
+    project_id = params[:project_id] || (params[:issue] && params[:issue][:project_id])
+    @project = Project.find(project_id)
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def retrieve_previous_and_next_issue_ids
+    retrieve_query_from_session
+    if @query
+      sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
+      sort_update(@query.sortable_columns, 'issues_index_sort')
+      limit = 500
+      issue_ids = @query.issue_ids(:order => sort_clause, :limit => (limit + 1), :include => [:assigned_to, :tracker, :priority, :category, :fixed_version])
+      if (idx = issue_ids.index(@issue.id)) && idx < limit
+        if issue_ids.size < 500
+          @issue_position = idx + 1
+          @issue_count = issue_ids.size
+        end
+        @prev_issue_id = issue_ids[idx - 1] if idx > 0
+        @next_issue_id = issue_ids[idx + 1] if idx < (issue_ids.size - 1)
+      end
+    end
+  end
+
+  # Used by #edit and #update to set some common instance variables
+  # from the params
+  # TODO: Refactor, not everything in here is needed by #edit
+  def update_issue_from_params
+    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
+    @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
+    @time_entry.attributes = params[:time_entry]
+
+    @issue.init_journal(User.current)
+
+    issue_attributes = params[:issue]
+    if issue_attributes && params[:conflict_resolution]
+      case params[:conflict_resolution]
+      when 'overwrite'
+        issue_attributes = issue_attributes.dup
+        issue_attributes.delete(:lock_version)
+      when 'add_notes'
+        issue_attributes = issue_attributes.slice(:notes)
+      when 'cancel'
+        redirect_to issue_path(@issue)
+        return false
+      end
+    end
+    @issue.safe_attributes = issue_attributes
+    @priorities = IssuePriority.active
+    @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
+    true
+  end
+
+  # TODO: Refactor, lots of extra code in here
+  # TODO: Changing tracker on an existing issue should not trigger this
+  def build_new_issue_from_params
+    if params[:id].blank?
+      @issue = Issue.new
+      if params[:copy_from]
+        begin
+          @copy_from = Issue.visible.find(params[:copy_from])
+          @copy_attachments = params[:copy_attachments].present? || request.get?
+          @copy_subtasks = params[:copy_subtasks].present? || request.get?
+          @issue.copy_from(@copy_from, :attachments => @copy_attachments, :subtasks => @copy_subtasks)
+        rescue ActiveRecord::RecordNotFound
+          render_404
+          return
+        end
+      end
+      @issue.project = @project
+    else
+      @issue = @project.issues.visible.find(params[:id])
+    end
+
+    @issue.project = @project
+    @issue.author ||= User.current
+    # Tracker must be set before custom field values
+    @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
+    if @issue.tracker.nil?
+      render_error l(:error_no_tracker_in_project)
+      return false
+    end
+    @issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date?
+    @issue.safe_attributes = params[:issue]
+
+    @priorities = IssuePriority.active
+    @allowed_statuses = @issue.new_statuses_allowed_to(User.current, true)
+    @available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq
+  end
+
+  def check_for_default_issue_status
+    if IssueStatus.default.nil?
+      render_error l(:error_no_default_issue_status)
+      return false
+    end
+  end
+
+  def parse_params_for_bulk_issue_attributes(params)
+    attributes = (params[:issue] || {}).reject {|k,v| v.blank?}
+    attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'}
+    if custom = attributes[:custom_field_values]
+      custom.reject! {|k,v| v.blank?}
+      custom.keys.each do |k|
+        if custom[k].is_a?(Array)
+          custom[k] << '' if custom[k].delete('__none__')
+        else
+          custom[k] = '' if custom[k] == '__none__'
+        end
+      end
+    end
+    attributes
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7a8cd1b0e0860947e389cd0337442e3d3a963523.svn-base
--- a/.svn/pristine/7a/7a8cd1b0e0860947e389cd0337442e3d3a963523.svn-base
+++ /dev/null
@@ -1,1001 +0,0 @@
-ro:
-  direction: ltr
-  date:
-    formats:
-      default: "%d-%m-%Y"
-      short: "%d %b"
-      long: "%d %B %Y"
-      only_day: "%e"
-      
-    day_names: [DuminicÄƒ, Luni, Marti, Miercuri, Joi, Vineri, SÃ¢mbÄƒtÄƒ]
-    abbr_day_names: [Dum, Lun, Mar, Mie, Joi, Vin, SÃ¢m]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Ianuarie, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie]
-    abbr_month_names: [~, Ian, Feb, Mar, Apr, Mai, Iun, Iul, Aug, Sep, Oct, Noi, Dec]
-    # Used in date_select and datime_select.
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%m/%d/%Y %I:%M %p"
-      time: "%I:%M %p"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "am"
-    pm: "pm"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "jumÄƒtate de minut"
-      less_than_x_seconds:
-        one:   "mai puÈ›in de o secundÄƒ"
-        other: "mai puÈ›in de %{count} secunde"
-      x_seconds:
-        one:   "o secundÄƒ"
-        other: "%{count} secunde"
-      less_than_x_minutes:
-        one:   "mai puÈ›in de un minut"
-        other: "mai puÈ›in de %{count} minute"
-      x_minutes:
-        one:   "un minut"
-        other: "%{count} minute"
-      about_x_hours:
-        one:   "aproximativ o orÄƒ"
-        other: "aproximativ %{count} ore"
-      x_days:
-        one:   "o zi"
-        other: "%{count} zile"
-      about_x_months:
-        one:   "aproximativ o lunÄƒ"
-        other: "aproximativ %{count} luni"
-      x_months:
-        one:   "o luna"
-        other: "%{count} luni"
-      about_x_years:
-        one:   "aproximativ un an"
-        other: "aproximativ %{count} ani"
-      over_x_years:
-        one:   "peste un an"
-        other: "peste %{count} ani"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  number: 
-    human: 
-      format: 
-        precision: 1
-        delimiter: ""
-      storage_units: 
-        format: "%n %u"
-        units: 
-          kb: KB
-          tb: TB
-          gb: GB
-          byte: 
-            one: Byte
-            other: Bytes
-          mb: MB
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "È™i"
-      skip_last_comma: true
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "nu este inclus Ã®n listÄƒ"
-        exclusion: "este rezervat"
-        invalid: "nu este valid"
-        confirmation: "nu este identicÄƒ"
-        accepted: "trebuie acceptat"
-        empty: "trebuie completat"
-        blank: "nu poate fi gol"
-        too_long: "este prea lung"
-        too_short: "este prea scurt"
-        wrong_length: "nu are lungimea corectÄƒ"
-        taken: "a fost luat deja"
-        not_a_number: "nu este un numÄƒr"
-        not_a_date: "nu este o datÄƒ validÄƒ"
-        greater_than: "trebuie sÄƒ fie mai mare de %{count}"
-        greater_than_or_equal_to: "trebuie sÄƒ fie mai mare sau egal cu %{count}"
-        equal_to: "trebuie sÄƒ fie egal cu {count}}"
-        less_than: "trebuie sÄƒ fie mai mic decat %{count}"
-        less_than_or_equal_to: "trebuie sÄƒ fie mai mic sau egal cu %{count}"
-        odd: "trebuie sÄƒ fie impar"
-        even: "trebuie sÄƒ fie par"
-        greater_than_start_date: "trebuie sÄƒ fie dupÄƒ data de Ã®nceput"
-        not_same_project: "trebuie sÄƒ aparÈ›inÄƒ aceluiaÈ™i proiect"
-        circular_dependency: "AceastÄƒ relaÈ›ie ar crea o dependenÈ›Äƒ circularÄƒ"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: SelectaÈ›i
-  
-  general_text_No: 'Nu'
-  general_text_Yes: 'Da'
-  general_text_no: 'nu'
-  general_text_yes: 'da'
-  general_lang_name: 'RomÃ¢nÄƒ'
-  general_csv_separator: '.'
-  general_csv_decimal_separator: ','
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '2'
-  
-  notice_account_updated: Cont actualizat.
-  notice_account_invalid_creditentials: Utilizator sau parola nevalidÄƒ
-  notice_account_password_updated: ParolÄƒ actualizatÄƒ.
-  notice_account_wrong_password: ParolÄƒ greÈ™itÄƒ
-  notice_account_register_done: Contul a fost creat. Pentru activare, urmaÈ›i legÄƒtura trimisÄƒ prin email.
-  notice_account_unknown_email: Utilizator necunoscut.
-  notice_can_t_change_password: Acest cont foloseÈ™te o sursÄƒ externÄƒ de autentificare. Nu se poate schimba parola.
-  notice_account_lost_email_sent: S-a trimis un email cu instrucÈ›iuni de schimbare a parolei.
-  notice_account_activated: Contul a fost activat. VÄƒ puteÈ›i autentifica acum.
-  notice_successful_create: Creat.
-  notice_successful_update: Actualizat.
-  notice_successful_delete: È˜ters.
-  notice_successful_connection: Conectat.
-  notice_file_not_found: Pagina pe care doriÈ›i sÄƒ o accesaÈ›i nu existÄƒ sau a fost È™tearsÄƒ.
-  notice_locking_conflict: Datele au fost actualizate de alt utilizator.
-  notice_not_authorized: Nu sunteÈ›i autorizat sa accesaÈ›i aceastÄƒ paginÄƒ.
-  notice_email_sent: "S-a trimis un email cÄƒtre %{value}"
-  notice_email_error: "A intervenit o eroare la trimiterea de email (%{value})"
-  notice_feeds_access_key_reseted: Cheia de acces RSS a fost resetatÄƒ.
-  notice_failed_to_save_issues: "Nu s-au putut salva %{count} tichete din cele %{total} selectate: %{ids}."
-  notice_no_issue_selected: "Niciun tichet selectat! VÄƒ rugÄƒm sÄƒ selectaÈ›i tichetele pe care doriÈ›i sÄƒ le editaÈ›i."
-  notice_account_pending: "Contul dumneavoastrÄƒ a fost creat È™i aÈ™teaptÄƒ aprobarea administratorului."
-  notice_default_data_loaded: S-a Ã®ncÄƒrcat configuraÈ›ia implicitÄƒ.
-  notice_unable_delete_version: Nu se poate È™terge versiunea.
-  
-  error_can_t_load_default_data: "Nu s-a putut Ã®ncÄƒrca configuraÈ›ia implicitÄƒ: %{value}"
-  error_scm_not_found: "Nu s-a gÄƒsit articolul sau revizia Ã®n depozit."
-  error_scm_command_failed: "A intervenit o eroare la accesarea depozitului: %{value}"
-  error_scm_annotate: "Nu existÄƒ sau nu poate fi adnotatÄƒ."
-  error_issue_not_found_in_project: 'Tichetul nu a fost gÄƒsit sau nu aparÈ›ine acestui proiect'
-  
-  warning_attachments_not_saved: "Nu s-au putut salva %{count} fiÈ™iere."
-  
-  mail_subject_lost_password: "Parola dumneavoastrÄƒ: %{value}"
-  mail_body_lost_password: 'Pentru a schimba parola, accesaÈ›i:'
-  mail_subject_register: "Activarea contului %{value}"
-  mail_body_register: 'Pentru activarea contului, accesaÈ›i:'
-  mail_body_account_information_external: "PuteÈ›i folosi contul â€ž{value}}â€ pentru a vÄƒ autentifica."
-  mail_body_account_information: InformaÈ›ii despre contul dumneavoastrÄƒ
-  mail_subject_account_activation_request: "Cerere de activare a contului %{value}"
-  mail_body_account_activation_request: "S-a Ã®nregistrat un utilizator nou (%{value}). Contul aÈ™teaptÄƒ aprobarea dumneavoastrÄƒ:"
-  mail_subject_reminder: "%{count} tichete trebuie rezolvate Ã®n urmÄƒtoarele %{days} zile"
-  mail_body_reminder: "%{count} tichete atribuite dumneavoastrÄƒ trebuie rezolvate Ã®n urmÄƒtoarele %{days} zile:"
-  
-  gui_validation_error: o eroare
-  gui_validation_error_plural: "%{count} erori"
-  
-  field_name: Nume
-  field_description: Descriere
-  field_summary: Rezumat
-  field_is_required: Obligatoriu
-  field_firstname: Prenume
-  field_lastname: Nume
-  field_mail: Email
-  field_filename: FiÈ™ier
-  field_filesize: MÄƒrime
-  field_downloads: DescÄƒrcÄƒri
-  field_author: Autor
-  field_created_on: Creat la
-  field_updated_on: Actualizat la
-  field_field_format: Format
-  field_is_for_all: Pentru toate proiectele
-  field_possible_values: Valori posibile
-  field_regexp: Expresie regularÄƒ
-  field_min_length: lungime minimÄƒ
-  field_max_length: lungime maximÄƒ
-  field_value: Valoare
-  field_category: Categorie
-  field_title: Titlu
-  field_project: Proiect
-  field_issue: Tichet
-  field_status: Stare
-  field_notes: Note
-  field_is_closed: Rezolvat
-  field_is_default: Implicit
-  field_tracker: Tip de tichet
-  field_subject: Subiect
-  field_due_date: Data finalizÄƒrii
-  field_assigned_to: Atribuit
-  field_priority: Prioritate
-  field_fixed_version: Versiune È›intÄƒ
-  field_user: Utilizator
-  field_role: Rol
-  field_homepage: Pagina principalÄƒ
-  field_is_public: Public
-  field_parent: Sub-proiect al
-  field_is_in_roadmap: Tichete afiÈ™ate Ã®n plan
-  field_login: Autentificare
-  field_mail_notification: NotificÄƒri prin e-mail
-  field_admin: Administrator
-  field_last_login_on: Ultima autentificare Ã®n
-  field_language: Limba
-  field_effective_date: Data
-  field_password: Parola
-  field_new_password: Parola nouÄƒ
-  field_password_confirmation: Confirmare
-  field_version: Versiune
-  field_type: Tip
-  field_host: GazdÄƒ
-  field_port: Port
-  field_account: Cont
-  field_base_dn: Base DN
-  field_attr_login: Atribut autentificare
-  field_attr_firstname: Atribut prenume
-  field_attr_lastname: Atribut nume
-  field_attr_mail: Atribut email
-  field_onthefly: Creare utilizator pe loc
-  field_start_date: Data Ã®nceperii
-  field_done_ratio: Realizat (%)
-  field_auth_source: Mod autentificare
-  field_hide_mail: Nu se afiÈ™eazÄƒ adresa de email
-  field_comments: Comentariu
-  field_url: URL
-  field_start_page: Pagina de start
-  field_subproject: Subproiect
-  field_hours: Ore
-  field_activity: Activitate
-  field_spent_on: Data
-  field_identifier: Identificator
-  field_is_filter: Filtru
-  field_issue_to: Tichet asociat
-  field_delay: ÃŽntÃ¢rziere
-  field_assignable: Se pot atribui tichete acestui rol
-  field_redirect_existing_links: RedirecÈ›ioneazÄƒ legÄƒturile existente
-  field_estimated_hours: Timp estimat
-  field_column_names: Coloane
-  field_time_zone: Fus orar
-  field_searchable: CÄƒutare
-  field_default_value: Valoare implicita
-  field_comments_sorting: AfiÈ™eazÄƒ comentarii
-  field_parent_title: Pagina superioara
-  field_editable: Modificabil
-  field_watcher: UrmÄƒreÈ™te
-  field_identity_url: URL OpenID
-  field_content: ConÈ›inut
-  
-  setting_app_title: Titlu aplicaÈ›ie
-  setting_app_subtitle: Subtitlu aplicaÈ›ie
-  setting_welcome_text: Text de Ã®ntÃ¢mpinare
-  setting_default_language: Limba implicita
-  setting_login_required: Necesita autentificare
-  setting_self_registration: ÃŽnregistrare automatÄƒ
-  setting_attachment_max_size: MÄƒrime maxima ataÈ™ament
-  setting_issues_export_limit: LimitÄƒ de tichete exportate
-  setting_mail_from: Adresa de email a expeditorului
-  setting_bcc_recipients: AlÈ›i destinatari pentru email (BCC)
-  setting_plain_text_mail: Mesaje text (fÄƒrÄƒ HTML)
-  setting_host_name: Numele gazdei È™i calea
-  setting_text_formatting: Formatare text
-  setting_wiki_compression: Comprimare istoric Wiki
-  setting_feeds_limit: Limita de actualizÄƒri din feed
-  setting_default_projects_public: Proiectele noi sunt implicit publice
-  setting_autofetch_changesets: Preluare automatÄƒ a modificÄƒrilor din depozit
-  setting_sys_api_enabled: Activare WS pentru gestionat depozitul
-  setting_commit_ref_keywords: Cuvinte cheie pt. referire tichet
-  setting_commit_fix_keywords: Cuvinte cheie pt. rezolvare tichet
-  setting_autologin: Autentificare automatÄƒ
-  setting_date_format: Format datÄƒ
-  setting_time_format: Format orÄƒ
-  setting_cross_project_issue_relations: Permite legÄƒturi de tichete Ã®ntre proiecte
-  setting_issue_list_default_columns: Coloane implicite afiÈ™ate Ã®n lista de tichete
-  setting_emails_footer: Subsol email
-  setting_protocol: Protocol
-  setting_per_page_options: NumÄƒr de obiecte pe paginÄƒ
-  setting_user_format: Stil de afiÈ™are pentru utilizator
-  setting_activity_days_default: Se afiÈ™eazÄƒ zile Ã®n jurnalul proiectului
-  setting_display_subprojects_issues: AfiÈ™eazÄƒ implicit tichetele sub-proiectelor Ã®n proiectele principale
-  setting_enabled_scm: SCM activat
-  setting_mail_handler_api_enabled: Activare WS pentru email primit
-  setting_mail_handler_api_key: cheie API
-  setting_sequential_project_identifiers: GenereazÄƒ secvenÈ›ial identificatoarele de proiect
-  setting_gravatar_enabled: FoloseÈ™te poze Gravatar pentru utilizatori
-  setting_diff_max_lines_displayed: NumÄƒr maxim de linii de diferenÈ›Äƒ afiÈ™ate
-  setting_file_max_size_displayed: NumÄƒr maxim de fiÈ™iere text afiÈ™ate Ã®n paginÄƒ (inline)
-  setting_repository_log_display_limit: NumÄƒr maxim de revizii afiÈ™ate Ã®n istoricul fiÈ™ierului
-  setting_openid: Permite Ã®nregistrare È™i autentificare cu OpenID
-  
-  permission_edit_project: EditeazÄƒ proiectul
-  permission_select_project_modules: Alege module pentru proiect
-  permission_manage_members: EditeazÄƒ membri
-  permission_manage_versions: EditeazÄƒ versiuni
-  permission_manage_categories: EditeazÄƒ categorii
-  permission_add_issues: AdaugÄƒ tichete
-  permission_edit_issues: EditeazÄƒ tichete
-  permission_manage_issue_relations: EditeazÄƒ relaÈ›ii tichete
-  permission_add_issue_notes: AdaugÄƒ note
-  permission_edit_issue_notes: EditeazÄƒ note
-  permission_edit_own_issue_notes: EditeazÄƒ notele proprii
-  permission_move_issues: MutÄƒ tichete
-  permission_delete_issues: È˜terge tichete
-  permission_manage_public_queries: EditeazÄƒ cÄƒutÄƒrile implicite
-  permission_save_queries: SalveazÄƒ cÄƒutÄƒrile
-  permission_view_gantt: AfiÈ™eazÄƒ Gantt
-  permission_view_calendar: AfiÈ™eazÄƒ calendarul
-  permission_view_issue_watchers: AfiÈ™eazÄƒ lista de persoane interesate
-  permission_add_issue_watchers: AdaugÄƒ persoane interesate
-  permission_log_time: ÃŽnregistreazÄƒ timpul de lucru
-  permission_view_time_entries: AfiÈ™eazÄƒ timpul de lucru
-  permission_edit_time_entries: EditeazÄƒ jurnalele cu timp de lucru
-  permission_edit_own_time_entries: EditeazÄƒ jurnalele proprii cu timpul de lucru
-  permission_manage_news: EditeazÄƒ È™tiri
-  permission_comment_news: ComenteazÄƒ È™tirile
-  permission_manage_documents: EditeazÄƒ documente
-  permission_view_documents: AfiÈ™eazÄƒ documente
-  permission_manage_files: EditeazÄƒ fiÈ™iere
-  permission_view_files: AfiÈ™eazÄƒ fiÈ™iere
-  permission_manage_wiki: EditeazÄƒ wiki
-  permission_rename_wiki_pages: RedenumeÈ™te pagini wiki
-  permission_delete_wiki_pages: È˜terge pagini wiki
-  permission_view_wiki_pages: AfiÈ™eazÄƒ wiki
-  permission_view_wiki_edits: AfiÈ™eazÄƒ istoricul wiki
-  permission_edit_wiki_pages: EditeazÄƒ pagini wiki
-  permission_delete_wiki_pages_attachments: È˜terge ataÈ™amente
-  permission_protect_wiki_pages: BlocheazÄƒ pagini wiki
-  permission_manage_repository: GestioneazÄƒ depozitul
-  permission_browse_repository: RÄƒsfoieÈ™te depozitul
-  permission_view_changesets: AfiÈ™eazÄƒ modificÄƒrile din depozit
-  permission_commit_access: Acces commit
-  permission_manage_boards: EditeazÄƒ forum
-  permission_view_messages: AfiÈ™eazÄƒ mesaje
-  permission_add_messages: Scrie mesaje
-  permission_edit_messages: EditeazÄƒ mesaje
-  permission_edit_own_messages: EditeazÄƒ mesajele proprii
-  permission_delete_messages: È˜terge mesaje
-  permission_delete_own_messages: È˜terge mesajele proprii
-  
-  project_module_issue_tracking: Tichete
-  project_module_time_tracking: Timp de lucru
-  project_module_news: È˜tiri
-  project_module_documents: Documente
-  project_module_files: FiÈ™iere
-  project_module_wiki: Wiki
-  project_module_repository: Depozit
-  project_module_boards: Forum
-  
-  label_user: Utilizator
-  label_user_plural: Utilizatori
-  label_user_new: Utilizator nou
-  label_project: Proiect
-  label_project_new: Proiect nou
-  label_project_plural: Proiecte
-  label_x_projects:
-    zero:  niciun proiect
-    one:   un proiect
-    other: "%{count} proiecte"
-  label_project_all: Toate proiectele
-  label_project_latest: Proiecte noi
-  label_issue: Tichet
-  label_issue_new: Tichet nou
-  label_issue_plural: Tichete
-  label_issue_view_all: AfiÈ™eazÄƒ toate tichetele
-  label_issues_by: "SorteazÄƒ dupÄƒ %{value}"
-  label_issue_added: Adaugat
-  label_issue_updated: Actualizat
-  label_document: Document
-  label_document_new: Document nou
-  label_document_plural: Documente
-  label_document_added: AdÄƒugat
-  label_role: Rol
-  label_role_plural: Roluri
-  label_role_new: Rol nou
-  label_role_and_permissions: Roluri È™i permisiuni
-  label_member: Membru
-  label_member_new: membru nou
-  label_member_plural: Membri
-  label_tracker: Tip de tichet
-  label_tracker_plural: Tipuri de tichete
-  label_tracker_new: Tip nou de tichet
-  label_workflow: Mod de lucru
-  label_issue_status: Stare tichet
-  label_issue_status_plural: Stare tichete
-  label_issue_status_new: Stare nouÄƒ
-  label_issue_category: Categorie de tichet
-  label_issue_category_plural: Categorii de tichete
-  label_issue_category_new: Categorie nouÄƒ
-  label_custom_field: CÃ¢mp personalizat
-  label_custom_field_plural: CÃ¢mpuri personalizate
-  label_custom_field_new: CÃ¢mp nou personalizat
-  label_enumerations: EnumerÄƒri
-  label_enumeration_new: Valoare nouÄƒ
-  label_information: InformaÈ›ie
-  label_information_plural: InformaÈ›ii
-  label_please_login: VÄƒ rugÄƒm sÄƒ vÄƒ autentificaÈ›i
-  label_register: ÃŽnregistrare
-  label_login_with_open_id_option: sau autentificare cu OpenID
-  label_password_lost: ParolÄƒ uitatÄƒ
-  label_home: AcasÄƒ
-  label_my_page: Pagina mea
-  label_my_account: Contul meu
-  label_my_projects: Proiectele mele
-  label_administration: Administrare
-  label_login: Autentificare
-  label_logout: IeÈ™ire din cont
-  label_help: Ajutor
-  label_reported_issues: Tichete
-  label_assigned_to_me_issues: Tichetele mele
-  label_last_login: Ultima conectare
-  label_registered_on: ÃŽnregistrat la
-  label_activity: Activitate
-  label_overall_activity: Activitate - vedere de ansamblu
-  label_user_activity: "Activitate %{value}"
-  label_new: Nou
-  label_logged_as: Autentificat ca
-  label_environment: Mediu
-  label_authentication: Autentificare
-  label_auth_source: Mod de autentificare
-  label_auth_source_new: Nou
-  label_auth_source_plural: Moduri de autentificare
-  label_subproject_plural: Sub-proiecte
-  label_and_its_subprojects: "%{value} È™i sub-proiecte"
-  label_min_max_length: lungime min - max
-  label_list: ListÄƒ
-  label_date: DatÄƒ
-  label_integer: ÃŽntreg
-  label_float: Zecimal
-  label_boolean: Valoare logicÄƒ
-  label_string: Text
-  label_text: Text lung
-  label_attribute: Atribut
-  label_attribute_plural: Atribute
-  label_download: "%{count} descÄƒrcare"
-  label_download_plural: "%{count} descÄƒrcÄƒri"
-  label_no_data: Nu existÄƒ date de afiÈ™at
-  label_change_status: SchimbÄƒ starea
-  label_history: Istoric
-  label_attachment: FiÈ™ier
-  label_attachment_new: FiÈ™ier nou
-  label_attachment_delete: È˜terge fiÈ™ier
-  label_attachment_plural: FiÈ™iere
-  label_file_added: AdÄƒugat
-  label_report: Raport
-  label_report_plural: Rapoarte
-  label_news: È˜tiri
-  label_news_new: AdaugÄƒ È™tire
-  label_news_plural: È˜tiri
-  label_news_latest: Ultimele È™tiri
-  label_news_view_all: AfiÈ™eazÄƒ toate È™tirile
-  label_news_added: AdÄƒugat
-  label_settings: SetÄƒri
-  label_overview: PaginÄƒ proiect
-  label_version: Versiune
-  label_version_new: Versiune nouÄƒ
-  label_version_plural: Versiuni
-  label_confirmation: Confirmare
-  label_export_to: 'Disponibil È™i Ã®n:'
-  label_read: CiteÈ™te...
-  label_public_projects: Proiecte publice
-  label_open_issues: deschis
-  label_open_issues_plural: deschise
-  label_closed_issues: Ã®nchis
-  label_closed_issues_plural: Ã®nchise
-  label_x_open_issues_abbr_on_total:
-    zero:  0 deschise / %{total}
-    one:   1 deschis / %{total}
-    other: "%{count} deschise / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 deschise
-    one:   1 deschis
-    other: "%{count} deschise"
-  label_x_closed_issues_abbr:
-    zero:  0 Ã®nchise
-    one:   1 Ã®nchis
-    other: "%{count} Ã®nchise"
-  label_total: Total
-  label_permissions: Permisiuni
-  label_current_status: Stare curentÄƒ
-  label_new_statuses_allowed: StÄƒri noi permise
-  label_all: toate
-  label_none: niciunul
-  label_nobody: nimeni
-  label_next: ÃŽnainte
-  label_previous: ÃŽnapoi
-  label_used_by: Folosit de
-  label_details: Detalii
-  label_add_note: AdaugÄƒ o notÄƒ
-  label_per_page: pe paginÄƒ
-  label_calendar: Calendar
-  label_months_from: luni de la
-  label_gantt: Gantt
-  label_internal: Intern
-  label_last_changes: "ultimele %{count} schimbÄƒri"
-  label_change_view_all: AfiÈ™eazÄƒ toate schimbÄƒrile
-  label_personalize_page: PersonalizeazÄƒ aceasta pagina
-  label_comment: Comentariu
-  label_comment_plural: Comentarii
-  label_x_comments:
-    zero: fara comentarii
-    one: 1 comentariu
-    other: "%{count} comentarii"
-  label_comment_add: AdaugÄƒ un comentariu
-  label_comment_added: AdÄƒugat
-  label_comment_delete: È˜terge comentariul
-  label_query: Cautare personalizata
-  label_query_plural: CÄƒutÄƒri personalizate
-  label_query_new: CÄƒutare nouÄƒ
-  label_filter_add: AdaugÄƒ filtru
-  label_filter_plural: Filtre
-  label_equals: este
-  label_not_equals: nu este
-  label_in_less_than: Ã®n mai puÈ›in de
-  label_in_more_than: Ã®n mai mult de
-  label_in: Ã®n
-  label_today: astÄƒzi
-  label_all_time: oricÃ¢nd
-  label_yesterday: ieri
-  label_this_week: sÄƒptÄƒmÃ¢na aceasta
-  label_last_week: sÄƒptÄƒmÃ¢na trecutÄƒ
-  label_last_n_days: "ultimele %{count} zile"
-  label_this_month: luna aceasta
-  label_last_month: luna trecutÄƒ
-  label_this_year: anul acesta
-  label_date_range: Perioada
-  label_less_than_ago: mai puÈ›in de ... zile
-  label_more_than_ago: mai mult de ... zile
-  label_ago: Ã®n urma
-  label_contains: conÈ›ine
-  label_not_contains: nu conÈ›ine
-  label_day_plural: zile
-  label_repository: Depozit
-  label_repository_plural: Depozite
-  label_browse: AfiÈ™eazÄƒ
-  label_modification: "%{count} schimbare"
-  label_modification_plural: "%{count} schimbÄƒri"
-  label_revision: Revizie
-  label_revision_plural: Revizii
-  label_associated_revisions: Revizii asociate
-  label_added: adaugatÄƒ
-  label_modified: modificatÄƒ
-  label_copied: copiatÄƒ
-  label_renamed: redenumitÄƒ
-  label_deleted: È™tearsÄƒ
-  label_latest_revision: Ultima revizie
-  label_latest_revision_plural: Ultimele revizii
-  label_view_revisions: AfiÈ™eazÄƒ revizii
-  label_max_size: MÄƒrime maximÄƒ
-  label_sort_highest: Prima
-  label_sort_higher: ÃŽn sus
-  label_sort_lower: ÃŽn jos
-  label_sort_lowest: Ultima
-  label_roadmap: Planificare
-  label_roadmap_due_in: "De terminat Ã®n %{value}"
-  label_roadmap_overdue: "ÃŽntÃ¢rziat cu %{value}"
-  label_roadmap_no_issues: Nu existÄƒ tichete pentru aceastÄƒ versiune
-  label_search: CautÄƒ
-  label_result_plural: Rezultate
-  label_all_words: toate cuvintele
-  label_wiki: Wiki
-  label_wiki_edit: Editare Wiki
-  label_wiki_edit_plural: EditÄƒri Wiki
-  label_wiki_page: PaginÄƒ Wiki
-  label_wiki_page_plural: Pagini Wiki
-  label_index_by_title: SorteazÄƒ dupÄƒ titlu
-  label_index_by_date: SorteazÄƒ dupÄƒ datÄƒ
-  label_current_version: Versiunea curentÄƒ
-  label_preview: Previzualizare
-  label_feed_plural: Feed-uri
-  label_changes_details: Detaliile tuturor schimbÄƒrilor
-  label_issue_tracking: UrmÄƒrire tichete
-  label_spent_time: Timp alocat
-  label_f_hour: "%{value} orÄƒ"
-  label_f_hour_plural: "%{value} ore"
-  label_time_tracking: UrmÄƒrire timp de lucru
-  label_change_plural: SchimbÄƒri
-  label_statistics: Statistici
-  label_commits_per_month: Commit pe luna
-  label_commits_per_author: Commit per autor
-  label_view_diff: AfiÈ™eazÄƒ diferenÈ›ele
-  label_diff_inline: Ã®n linie
-  label_diff_side_by_side: una lÃ¢ngÄƒ alta
-  label_options: OpÈ›iuni
-  label_copy_workflow_from: CopiazÄƒ modul de lucru de la
-  label_permissions_report: Permisiuni
-  label_watched_issues: Tichete urmÄƒrite
-  label_related_issues: Tichete asociate
-  label_applied_status: Stare aplicatÄƒ
-  label_loading: ÃŽncarcÄƒ...
-  label_relation_new: Asociere nouÄƒ
-  label_relation_delete: È˜terge asocierea
-  label_relates_to: asociat cu
-  label_duplicates: duplicate
-  label_duplicated_by: la fel ca
-  label_blocks: blocÄƒri
-  label_blocked_by: blocat de
-  label_precedes: precede
-  label_follows: urmeazÄƒ
-  label_end_to_start: de la sfÃ¢rÈ™it la Ã®nceput
-  label_end_to_end: de la sfÃ¢rÈ™it la sfÃ¢rÈ™it
-  label_start_to_start: de la Ã®nceput la Ã®nceput
-  label_start_to_end: de la Ã®nceput la sfÃ¢rÈ™it
-  label_stay_logged_in: PÄƒstreazÄƒ autentificarea
-  label_disabled: dezactivat
-  label_show_completed_versions: AratÄƒ versiunile terminate
-  label_me: eu
-  label_board: Forum
-  label_board_new: Forum nou
-  label_board_plural: Forumuri
-  label_topic_plural: Subiecte
-  label_message_plural: Mesaje
-  label_message_last: Ultimul mesaj
-  label_message_new: Mesaj nou
-  label_message_posted: AdÄƒugat
-  label_reply_plural: RÄƒspunsuri
-  label_send_information: Trimite utilizatorului informaÈ›iile despre cont
-  label_year: An
-  label_month: LunÄƒ
-  label_week: SÄƒptÄƒmÃ¢nÄƒ
-  label_date_from: De la
-  label_date_to: La
-  label_language_based: Un funcÈ›ie de limba de afiÈ™are a utilizatorului
-  label_sort_by: "SorteazÄƒ dupÄƒ %{value}"
-  label_send_test_email: Trimite email de test
-  label_feeds_access_key_created_on: "Cheie de acces creatÄƒ acum %{value}"
-  label_module_plural: Module
-  label_added_time_by: "AdÄƒugat de %{author} acum %{age}"
-  label_updated_time_by: "Actualizat de %{author} acum %{age}"
-  label_updated_time: "Actualizat acum %{value}"
-  label_jump_to_a_project: Alege proiectul...
-  label_file_plural: FiÈ™iere
-  label_changeset_plural: SchimbÄƒri
-  label_default_columns: Coloane implicite
-  label_no_change_option: (fÄƒrÄƒ schimbÄƒri)
-  label_bulk_edit_selected_issues: EditeazÄƒ toate tichetele selectate
-  label_theme: Tema
-  label_default: ImplicitÄƒ
-  label_search_titles_only: CautÄƒ numai Ã®n titluri
-  label_user_mail_option_all: "Pentru orice eveniment, Ã®n toate proiectele mele"
-  label_user_mail_option_selected: " Pentru orice eveniment, Ã®n proiectele selectate..."
-  label_user_mail_no_self_notified: "Nu trimite notificÄƒri pentru modificÄƒrile mele"
-  label_registration_activation_by_email: activare cont prin email
-  label_registration_manual_activation: activare manualÄƒ a contului
-  label_registration_automatic_activation: activare automatÄƒ a contului
-  label_display_per_page: "pe paginÄƒ: %{value}"
-  label_age: vechime
-  label_change_properties: SchimbÄƒ proprietÄƒÈ›ile
-  label_general: General
-  label_more: Mai mult
-  label_scm: SCM
-  label_plugins: Plugin-uri
-  label_ldap_authentication: autentificare LDAP
-  label_downloads_abbr: D/L
-  label_optional_description: Descriere (opÈ›ionalÄƒ)
-  label_add_another_file: AdaugÄƒ alt fiÈ™ier
-  label_preferences: PreferinÈ›e
-  label_chronological_order: Ã®n ordine cronologicÄƒ
-  label_reverse_chronological_order: ÃŽn ordine invers cronologicÄƒ
-  label_planning: Planificare
-  label_incoming_emails: Mesaje primite
-  label_generate_key: GenereazÄƒ o cheie
-  label_issue_watchers: Cine urmÄƒreÈ™te
-  label_example: Exemplu
-  label_display: AfiÈ™eazÄƒ
-  
-  label_sort: SorteazÄƒ
-  label_ascending: CrescÄƒtor
-  label_descending: DescrescÄƒtor
-  label_date_from_to: De la %{start} la %{end}
-
-  
-  button_login: Autentificare
-  button_submit: Trimite
-  button_save: SalveazÄƒ
-  button_check_all: BifeazÄƒ tot
-  button_uncheck_all: DebifeazÄƒ tot
-  button_delete: È˜terge
-  button_create: CreeazÄƒ
-  button_create_and_continue: CreeazÄƒ È™i continua
-  button_test: TesteazÄƒ
-  button_edit: EditeazÄƒ
-  button_add: AdaugÄƒ
-  button_change: ModificÄƒ
-  button_apply: AplicÄƒ
-  button_clear: È˜terge
-  button_lock: BlocheazÄƒ
-  button_unlock: DeblocheazÄƒ
-  button_download: DescarcÄƒ
-  button_list: ListeazÄƒ
-  button_view: AfiÈ™eazÄƒ
-  button_move: MutÄƒ
-  button_back: ÃŽnapoi
-  button_cancel: AnuleazÄƒ
-  button_activate: ActiveazÄƒ
-  button_sort: SorteazÄƒ
-  button_log_time: ÃŽnregistreazÄƒ timpul de lucru
-  button_rollback: Revenire la aceastÄƒ versiune
-  button_watch: UrmÄƒresc
-  button_unwatch: Nu urmÄƒresc
-  button_reply: RÄƒspunde
-  button_archive: ArhiveazÄƒ
-  button_unarchive: DezarhiveazÄƒ
-  button_reset: ReseteazÄƒ
-  button_rename: RedenumeÈ™te
-  button_change_password: Schimbare parolÄƒ
-  button_copy: CopiazÄƒ
-  button_annotate: AdnoteazÄƒ
-  button_update: ActualizeazÄƒ
-  button_configure: ConfigureazÄƒ
-  button_quote: CiteazÄƒ
-  
-  status_active: activ
-  status_registered: Ã®nregistrat
-  status_locked: blocat
-  
-  text_select_mail_notifications: SelectaÈ›i acÈ›iunile notificate prin email.
-  text_regexp_info: ex. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 Ã®nseamnÄƒ fÄƒrÄƒ restricÈ›ii
-  text_project_destroy_confirmation: Sigur doriÈ›i sÄƒ È™tergeÈ›i proiectul È™i toate datele asociate?
-  text_subprojects_destroy_warning: "Se vor È™terge È™i sub-proiectele: %{value}."
-  text_workflow_edit: SelectaÈ›i un rol È™i un tip de tichet pentru a edita modul de lucru
-  text_are_you_sure: SunteÈ›i sigur(Äƒ)?
-  text_tip_issue_begin_day: sarcinÄƒ care Ã®ncepe Ã®n aceastÄƒ zi
-  text_tip_issue_end_day: sarcinÄƒ care se terminÄƒ Ã®n aceastÄƒ zi
-  text_tip_issue_begin_end_day: sarcinÄƒ care Ã®ncepe È™i se terminÄƒ Ã®n aceastÄƒ zi
-  text_project_identifier_info: 'Sunt permise doar litere mici (a-z), numere È™i cratime.<br />OdatÄƒ salvat, identificatorul nu mai poate fi modificat.'
-  text_caracters_maximum: "maxim %{count} caractere."
-  text_caracters_minimum: "Trebuie sÄƒ fie minim %{count} caractere."
-  text_length_between: "Lungime Ã®ntre %{min} È™i %{max} caractere."
-  text_tracker_no_workflow: Nu sunt moduri de lucru pentru acest tip de tichet
-  text_unallowed_characters: Caractere nepermise
-  text_comma_separated: Sunt permise mai multe valori (separate cu virgulÄƒ).
-  text_issues_ref_in_commit_messages: Referire la tichete È™i rezolvare Ã®n textul mesajului
-  text_issue_added: "Tichetul %{id} a fost adÄƒugat de %{author}."
-  text_issue_updated: "Tichetul %{id} a fost actualizat de %{author}."
-  text_wiki_destroy_confirmation: Sigur doriÈ›i È™tergerea Wiki È™i a conÈ›inutului asociat?
-  text_issue_category_destroy_question: "AceastÄƒ categorie conÈ›ine (%{count}) tichete. Ce doriÈ›i sÄƒ faceÈ›i?"
-  text_issue_category_destroy_assignments: È˜terge apartenenÈ›a la categorie.
-  text_issue_category_reassign_to: Atribuie tichetele la aceastÄƒ categorie
-  text_user_mail_option: "Pentru proiectele care nu sunt selectate, veÈ›i primi notificÄƒri doar pentru ceea ce urmÄƒriÈ›i sau Ã®n ce sunteÈ›i implicat (ex: tichete create de dumneavoastrÄƒ sau care vÄƒ sunt atribuite)."
-  text_no_configuration_data: "Nu s-au configurat Ã®ncÄƒ rolurile, stÄƒrile tichetelor È™i modurile de lucru.\nEste recomandat sÄƒ Ã®ncÄƒrcaÈ›i configuraÈ›ia implicitÄƒ. O veÈ›i putea modifica ulterior."
-  text_load_default_configuration: ÃŽncarcÄƒ configuraÈ›ia implicitÄƒ
-  text_status_changed_by_changeset: "Aplicat Ã®n setul %{value}."
-  text_issues_destroy_confirmation: 'Sigur doriÈ›i sÄƒ È™tergeÈ›i tichetele selectate?'
-  text_select_project_modules: 'SelectaÈ›i modulele active pentru acest proiect:'
-  text_default_administrator_account_changed: S-a schimbat contul administratorului implicit
-  text_file_repository_writable: Se poate scrie Ã®n directorul de ataÈ™amente
-  text_plugin_assets_writable: Se poate scrie Ã®n directorul de plugin-uri
-  text_rmagick_available: Este disponibil RMagick (opÈ›ional)
-  text_destroy_time_entries_question: "%{hours} ore sunt Ã®nregistrate la tichetele pe care doriÈ›i sÄƒ le È™tergeÈ›i. Ce doriÈ›i sa faceÈ›i?"
-  text_destroy_time_entries: È˜terge orele Ã®nregistrate
-  text_assign_time_entries_to_project: Atribuie orele la proiect
-  text_reassign_time_entries: 'Atribuie orele Ã®nregistrate la tichetul:'
-  text_user_wrote: "%{value} a scris:"
-  text_enumeration_destroy_question: "AceastÄƒ valoare are %{count} obiecte."
-  text_enumeration_category_reassign_to: 'Atribuie la aceastÄƒ valoare:'
-  text_email_delivery_not_configured: "Trimiterea de emailuri nu este configuratÄƒ È™i ca urmare, notificÄƒrile sunt dezactivate.\nConfiguraÈ›i serverul SMTP Ã®n config/configuration.yml È™i reporniÈ›i aplicaÈ›ia pentru a le activa."
-  text_repository_usernames_mapping: "SelectaÈ›i sau modificaÈ›i contul Redmine echivalent contului din istoricul depozitului.\nUtilizatorii cu un cont (sau e-mail) identic Ã®n Redmine È™i depozit sunt echivalate automat." 
-  text_diff_truncated: '... ComparaÈ›ia a fost trunchiatÄƒ pentru ca depÄƒÈ™eÈ™te lungimea maximÄƒ de text care poate fi afiÈ™at.'
-  text_custom_field_possible_values_info: 'O linie pentru fiecare valoare'
-  
-  default_role_manager: Manager
-  default_role_developer: Dezvoltator
-  default_role_reporter: Creator de rapoarte
-  default_tracker_bug: Defect
-  default_tracker_feature: FuncÈ›ie
-  default_tracker_support: Suport
-  default_issue_status_new: Nou
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: Rezolvat
-  default_issue_status_feedback: AÈ™teaptÄƒ reacÈ›ii
-  default_issue_status_closed: ÃŽnchis
-  default_issue_status_rejected: Respins
-  default_doc_category_user: DocumentaÈ›ie
-  default_doc_category_tech: DocumentaÈ›ie tehnicÄƒ
-  default_priority_low: micÄƒ
-  default_priority_normal: normalÄƒ
-  default_priority_high: mare
-  default_priority_urgent: urgentÄƒ
-  default_priority_immediate: imediatÄƒ
-  default_activity_design: Design
-  default_activity_development: Dezvoltare
-  
-  enumeration_issue_priorities: PrioritÄƒÈ›i tichete
-  enumeration_doc_categories: Categorii documente
-  enumeration_activities: ActivitÄƒÈ›i (timp de lucru)
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: AceastÄƒ paginÄƒ are %{descendants} pagini anterioare È™i descendenÈ›i. Ce doriÈ›i sÄƒ faceÈ›i?
-  text_wiki_page_reassign_children: Atribuie paginile la aceastÄƒ paginÄƒ
-  text_wiki_page_nullify_children: MenÈ›ine paginile ca È™i pagini iniÈ›iale (root)
-  text_wiki_page_destroy_children: È˜terge paginile È™i descendenÈ›ii
-  setting_password_min_length: Lungime minimÄƒ parolÄƒ
-  field_group_by: GrupeazÄƒ dupÄƒ
-  mail_subject_wiki_content_updated: "Pagina wiki '%{id}' a fost actualizatÄƒ"
-  label_wiki_content_added: AdÄƒugat
-  mail_subject_wiki_content_added: "Pagina wiki '%{id}' a fost adÄƒugatÄƒ"
-  mail_body_wiki_content_added: Pagina wiki '%{id}' a fost adÄƒugatÄƒ de %{author}.
-  label_wiki_content_updated: Actualizat
-  mail_body_wiki_content_updated: Pagina wiki '%{id}' a fost actualizatÄƒ de %{author}.
-  permission_add_project: CreazÄƒ proiect
-  setting_new_project_user_role_id: Rol atribuit utilizatorului non-admin care creazÄƒ un proiect.
-  label_view_all_revisions: AratÄƒ toate reviziile
-  label_tag: Tag
-  label_branch: Branch
-  error_no_tracker_in_project: Nu existÄƒ un tracker asociat cu proiectul. VerificaÈ›i vÄƒ rog setÄƒrile proiectului.
-  error_no_default_issue_status: Nu existÄƒ un status implicit al tichetelor. VerificaÈ›i vÄƒ rog configuraÈ›ia (MergeÈ›i la "Administrare -> StÄƒri tichete").
-  text_journal_changed: "%{label} schimbat din %{old} Ã®n %{new}"
-  text_journal_set_to: "%{label} setat ca %{value}"
-  text_journal_deleted: "%{label} È™ters (%{old})"
-  label_group_plural: Grupuri
-  label_group: Grup
-  label_group_new: Grup nou
-  label_time_entry_plural: Timp alocat
-  text_journal_added: "%{label} %{value} added"
-  field_active: Active
-  enumeration_system_activity: System Activity
-  permission_delete_issue_watchers: Delete watchers
-  version_status_closed: closed
-  version_status_locked: locked
-  version_status_open: open
-  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
-  label_user_anonymous: Anonymous
-  button_move_and_follow: Move and follow
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_gravatar_default: Default Gravatar image
-  field_sharing: Sharing
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_system: With all projects
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_tree: With project tree
-  label_version_sharing_none: Not shared
-  error_can_not_archive_project: This project can not be archived
-  button_duplicate: Duplicate
-  button_copy_and_follow: Copy and follow
-  label_copy_source: Source
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Same as target
-  label_copy_target: Target
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  error_workflow_copy_source: Please select a source tracker or role
-  label_update_issue_done_ratios: Update issue done ratios
-  setting_start_of_week: Start calendars on
-  permission_view_issues: View Issues
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API access key
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_missing_api_access_key: Missing an API access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  button_show: Show
-  text_line_separated: Multiple values allowed (one line for each value).
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Codare pentru mesaje
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7acfd8a3d508663aeabae0309fddb7dc899a74cf.svn-base
--- a/.svn/pristine/7a/7acfd8a3d508663aeabae0309fddb7dc899a74cf.svn-base
+++ /dev/null
@@ -1,39 +0,0 @@
-module CodeRay
-module Encoders
-  
-  # Returns the number of tokens.
-  # 
-  # Text and block tokens are counted.
-  class Count < Encoder
-    
-    register_for :count
-    
-  protected
-    
-    def setup options
-      super
-      
-      @count = 0
-    end
-    
-    def finish options
-      output @count
-    end
-    
-  public
-    
-    def text_token text, kind
-      @count += 1
-    end
-    
-    def begin_group kind
-      @count += 1
-    end
-    alias end_group begin_group
-    alias begin_line begin_group
-    alias end_line begin_group
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7a/7ae54c43f56efaece5e4ecd309a31e0849a96145.svn-base
--- /dev/null
+++ b/.svn/pristine/7a/7ae54c43f56efaece5e4ecd309a31e0849a96145.svn-base
@@ -0,0 +1,297 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module RepositoriesHelper
+  def format_revision(revision)
+    if revision.respond_to? :format_identifier
+      revision.format_identifier
+    else
+      revision.to_s
+    end
+  end
+
+  def truncate_at_line_break(text, length = 255)
+    if text
+      text.gsub(%r{^(.{#{length}}[^\n]*)\n.+$}m, '\\1...')
+    end
+  end
+
+  def render_properties(properties)
+    unless properties.nil? || properties.empty?
+      content = ''
+      properties.keys.sort.each do |property|
+        content << content_tag('li', "<b>#{h property}</b>: <span>#{h properties[property]}</span>".html_safe)
+      end
+      content_tag('ul', content.html_safe, :class => 'properties')
+    end
+  end
+
+  def render_changeset_changes
+    changes = @changeset.filechanges.limit(1000).reorder('path').all.collect do |change|
+      case change.action
+      when 'A'
+        # Detects moved/copied files
+        if !change.from_path.blank?
+          change.action =
+             @changeset.filechanges.detect {|c| c.action == 'D' && c.path == change.from_path} ? 'R' : 'C'
+        end
+        change
+      when 'D'
+        @changeset.filechanges.detect {|c| c.from_path == change.path} ? nil : change
+      else
+        change
+      end
+    end.compact
+
+    tree = { }
+    changes.each do |change|
+      p = tree
+      dirs = change.path.to_s.split('/').select {|d| !d.blank?}
+      path = ''
+      dirs.each do |dir|
+        path += '/' + dir
+        p[:s] ||= {}
+        p = p[:s]
+        p[path] ||= {}
+        p = p[path]
+      end
+      p[:c] = change
+    end
+    render_changes_tree(tree[:s])
+  end
+
+  def render_changes_tree(tree)
+    return '' if tree.nil?
+    output = ''
+    output << '<ul>'
+    tree.keys.sort.each do |file|
+      style = 'change'
+      text = File.basename(h(file))
+      if s = tree[file][:s]
+        style << ' folder'
+        path_param = to_path_param(@repository.relative_path(file))
+        text = link_to(h(text), :controller => 'repositories',
+                             :action => 'show',
+                             :id => @project,
+                             :repository_id => @repository.identifier_param,
+                             :path => path_param,
+                             :rev => @changeset.identifier)
+        output << "<li class='#{style}'>#{text}"
+        output << render_changes_tree(s)
+        output << "</li>"
+      elsif c = tree[file][:c]
+        style << " change-#{c.action}"
+        path_param = to_path_param(@repository.relative_path(c.path))
+        text = link_to(h(text), :controller => 'repositories',
+                             :action => 'entry',
+                             :id => @project,
+                             :repository_id => @repository.identifier_param,
+                             :path => path_param,
+                             :rev => @changeset.identifier) unless c.action == 'D'
+        text << " - #{h(c.revision)}" unless c.revision.blank?
+        text << ' ('.html_safe + link_to(l(:label_diff), :controller => 'repositories',
+                                       :action => 'diff',
+                                       :id => @project,
+                                       :repository_id => @repository.identifier_param,
+                                       :path => path_param,
+                                       :rev => @changeset.identifier) + ') '.html_safe if c.action == 'M'
+        text << ' '.html_safe + content_tag('span', h(c.from_path), :class => 'copied-from') unless c.from_path.blank?
+        output << "<li class='#{style}'>#{text}</li>"
+      end
+    end
+    output << '</ul>'
+    output.html_safe
+  end
+
+  def repository_field_tags(form, repository)
+    method = repository.class.name.demodulize.underscore + "_field_tags"
+    if repository.is_a?(Repository) &&
+        respond_to?(method) && method != 'repository_field_tags'
+      send(method, form, repository)
+    end
+  end
+
+  def scm_select_tag(repository)
+    scm_options = [["--- #{l(:actionview_instancetag_blank_option)} ---", '']]
+    Redmine::Scm::Base.all.each do |scm|
+    if Setting.enabled_scm.include?(scm) ||
+          (repository && repository.class.name.demodulize == scm)
+        scm_options << ["Repository::#{scm}".constantize.scm_name, scm]
+      end
+    end
+    select_tag('repository_scm',
+               options_for_select(scm_options, repository.class.name.demodulize),
+               :disabled => (repository && !repository.new_record?),
+               :data => {:remote => true, :method => 'get'})
+  end
+
+  def with_leading_slash(path)
+    path.to_s.starts_with?('/') ? path : "/#{path}"
+  end
+
+  def without_leading_slash(path)
+    path.gsub(%r{^/+}, '')
+  end
+
+  def subversion_field_tags(form, repository)
+      content_tag('p', form.text_field(:url, :size => 60, :required => true,
+                       :disabled => !repository.safe_attribute?('url')) +
+                       '<br />'.html_safe +
+                       '(file:///, http://, https://, svn://, svn+[tunnelscheme]://)') +
+      content_tag('p', form.text_field(:login, :size => 30)) +
+      content_tag('p', form.password_field(
+                            :password, :size => 30, :name => 'ignore',
+                            :value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),
+                            :onfocus => "this.value=''; this.name='repository[password]';",
+                            :onchange => "this.name='repository[password]';"))
+  end
+
+  def darcs_field_tags(form, repository)
+    content_tag('p', form.text_field(
+                     :url, :label => l(:field_path_to_repository),
+                     :size => 60, :required => true,
+                     :disabled => !repository.safe_attribute?('url'))) +
+    content_tag('p', form.select(
+                     :log_encoding, [nil] + Setting::ENCODINGS,
+                     :label => l(:field_commit_logs_encoding), :required => true))
+  end
+
+  def mercurial_field_tags(form, repository)
+    content_tag('p', form.text_field(
+                       :url, :label => l(:field_path_to_repository),
+                       :size => 60, :required => true,
+                       :disabled => !repository.safe_attribute?('url')
+                         ) +
+                     '<br />'.html_safe + l(:text_mercurial_repository_note)) +
+    content_tag('p', form.select(
+                        :path_encoding, [nil] + Setting::ENCODINGS,
+                        :label => l(:field_scm_path_encoding)
+                        ) +
+                     '<br />'.html_safe + l(:text_scm_path_encoding_note))
+  end
+
+  def git_field_tags(form, repository)
+    content_tag('p', form.text_field(
+                       :url, :label => l(:field_path_to_repository),
+                       :size => 60, :required => true,
+                       :disabled => !repository.safe_attribute?('url')
+                         ) +
+                      '<br />'.html_safe +
+                      l(:text_git_repository_note)) +
+    content_tag('p', form.select(
+                        :path_encoding, [nil] + Setting::ENCODINGS,
+                        :label => l(:field_scm_path_encoding)
+                        ) +
+                     '<br />'.html_safe + l(:text_scm_path_encoding_note)) +
+    content_tag('p', form.check_box(
+                        :extra_report_last_commit,
+                        :label => l(:label_git_report_last_commit)
+                         ))
+  end
+
+  def cvs_field_tags(form, repository)
+    content_tag('p', form.text_field(
+                     :root_url,
+                     :label => l(:field_cvsroot),
+                     :size => 60, :required => true,
+                     :disabled => !repository.safe_attribute?('root_url'))) +
+    content_tag('p', form.text_field(
+                     :url,
+                     :label => l(:field_cvs_module),
+                     :size => 30, :required => true,
+                     :disabled => !repository.safe_attribute?('url'))) +
+    content_tag('p', form.select(
+                     :log_encoding, [nil] + Setting::ENCODINGS,
+                     :label => l(:field_commit_logs_encoding), :required => true)) +
+    content_tag('p', form.select(
+                        :path_encoding, [nil] + Setting::ENCODINGS,
+                        :label => l(:field_scm_path_encoding)
+                        ) +
+                     '<br />'.html_safe + l(:text_scm_path_encoding_note))
+  end
+
+  def bazaar_field_tags(form, repository)
+    content_tag('p', form.text_field(
+                     :url, :label => l(:field_path_to_repository),
+                     :size => 60, :required => true,
+                     :disabled => !repository.safe_attribute?('url'))) +
+    content_tag('p', form.select(
+                     :log_encoding, [nil] + Setting::ENCODINGS,
+                     :label => l(:field_commit_logs_encoding), :required => true))
+  end
+
+  def filesystem_field_tags(form, repository)
+    content_tag('p', form.text_field(
+                     :url, :label => l(:field_root_directory),
+                     :size => 60, :required => true,
+                     :disabled => !repository.safe_attribute?('url'))) +
+    content_tag('p', form.select(
+                        :path_encoding, [nil] + Setting::ENCODINGS,
+                        :label => l(:field_scm_path_encoding)
+                        ) +
+                     '<br />'.html_safe + l(:text_scm_path_encoding_note))
+  end
+
+  def index_commits(commits, heads)
+    return nil if commits.nil? or commits.first.parents.nil?
+    refs_map = {}
+    heads.each do |head|
+      refs_map[head.scmid] ||= []
+      refs_map[head.scmid] << head
+    end
+    commits_by_scmid = {}
+    commits.reverse.each_with_index do |commit, commit_index|
+      commits_by_scmid[commit.scmid] = {
+        :parent_scmids => commit.parents.collect { |parent| parent.scmid },
+        :rdmid => commit_index,
+        :refs  => refs_map.include?(commit.scmid) ? refs_map[commit.scmid].join(" ") : nil,
+        :scmid => commit.scmid,
+        :href  => block_given? ? yield(commit.scmid) : commit.scmid
+      }
+    end
+    heads.sort! { |head1, head2| head1.to_s <=> head2.to_s }
+    space = nil  
+    heads.each do |head|
+      if commits_by_scmid.include? head.scmid
+        space = index_head((space || -1) + 1, head, commits_by_scmid)
+      end
+    end
+    # when no head matched anything use first commit
+    space ||= index_head(0, commits.first, commits_by_scmid)
+    return commits_by_scmid, space
+  end
+
+  def index_head(space, commit, commits_by_scmid)
+    stack = [[space, commits_by_scmid[commit.scmid]]]
+    max_space = space
+    until stack.empty?
+      space, commit = stack.pop
+      commit[:space] = space if commit[:space].nil?
+      space -= 1
+      commit[:parent_scmids].each_with_index do |parent_scmid, parent_index|
+        parent_commit = commits_by_scmid[parent_scmid]
+        if parent_commit and parent_commit[:space].nil?
+          stack.unshift [space += 1, parent_commit]
+        end
+      end
+      max_space = space if max_space < space
+    end
+    max_space
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7b/7b0091cb7275a16ba6daf28038e36a659196b7a1.svn-base
--- a/.svn/pristine/7b/7b0091cb7275a16ba6daf28038e36a659196b7a1.svn-base
+++ /dev/null
@@ -1,44 +0,0 @@
-<h2><%=l(:label_register)%> <%=link_to l(:label_login_with_open_id_option), signin_url if Setting.openid? %></h2>
-
-<% form_tag({:action => 'register'}, :class => "tabular") do %>
-<%= error_messages_for 'user' %>
-
-<div class="box">
-<!--[form:user]-->
-<% if @user.auth_source_id.nil? %>
-<p><label for="user_login"><%=l(:field_login)%> <span class="required">*</span></label>
-<%= text_field 'user', 'login', :size => 25 %></p>
-
-<p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label>
-<%= password_field_tag 'password', nil, :size => 25  %><br />
-<em><%= l(:text_caracters_minimum, :count => Setting.password_min_length) %></em></p>
-
-<p><label for="password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
-<%= password_field_tag 'password_confirmation', nil, :size => 25  %></p>
-<% end %>
-
-<p><label for="user_firstname"><%=l(:field_firstname)%> <span class="required">*</span></label>
-<%= text_field 'user', 'firstname'  %></p>
-
-<p><label for="user_lastname"><%=l(:field_lastname)%> <span class="required">*</span></label>
-<%= text_field 'user', 'lastname'  %></p>
-
-<p><label for="user_mail"><%=l(:field_mail)%> <span class="required">*</span></label>
-<%= text_field 'user', 'mail'  %></p>
-
-<p><label for="user_language"><%=l(:field_language)%></label>
-<%= select("user", "language", lang_options_for_select) %></p>
-
-<% if Setting.openid? %>
-<p><label for="user_identity_url"><%=l(:field_identity_url)%></label>
-<%= text_field 'user', 'identity_url'  %></p>
-<% end %>
-
-<% @user.custom_field_values.select {|v| v.editable? || v.required?}.each do |value| %>
-  <p><%= custom_field_tag_with_label :user, value %></p>
-<% end %>
-<!--[eoform:user]-->
-</div>
-
-<%= submit_tag l(:button_submit) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7b/7b4fab45dadc851ece3c8f70d2660b6cfb36eddc.svn-base
--- /dev/null
+++ b/.svn/pristine/7b/7b4fab45dadc851ece3c8f70d2660b6cfb36eddc.svn-base
@@ -0,0 +1,74 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WikiRedirectTest < ActiveSupport::TestCase
+  fixtures :projects, :wikis, :wiki_pages
+
+  def setup
+    @wiki = Wiki.find(1)
+    @original = WikiPage.create(:wiki => @wiki, :title => 'Original title')
+  end
+
+  def test_create_redirect
+    @original.title = 'New title'
+    assert @original.save
+    @original.reload
+
+    assert_equal 'New_title', @original.title
+    assert @wiki.redirects.find_by_title('Original_title')
+    assert @wiki.find_page('Original title')
+    assert @wiki.find_page('ORIGINAL title')
+  end
+
+  def test_update_redirect
+    # create a redirect that point to this page
+    assert WikiRedirect.create(:wiki => @wiki, :title => 'An_old_page', :redirects_to => 'Original_title')
+
+    @original.title = 'New title'
+    @original.save
+    # make sure the old page now points to the new page
+    assert_equal 'New_title', @wiki.find_page('An old page').title
+  end
+
+  def test_reverse_rename
+    # create a redirect that point to this page
+    assert WikiRedirect.create(:wiki => @wiki, :title => 'An_old_page', :redirects_to => 'Original_title')
+
+    @original.title = 'An old page'
+    @original.save
+    assert !@wiki.redirects.find_by_title_and_redirects_to('An_old_page', 'An_old_page')
+    assert @wiki.redirects.find_by_title_and_redirects_to('Original_title', 'An_old_page')
+  end
+
+  def test_rename_to_already_redirected
+    assert WikiRedirect.create(:wiki => @wiki, :title => 'An_old_page', :redirects_to => 'Other_page')
+
+    @original.title = 'An old page'
+    @original.save
+    # this redirect have to be removed since 'An old page' page now exists
+    assert !@wiki.redirects.find_by_title_and_redirects_to('An_old_page', 'Other_page')
+  end
+
+  def test_redirects_removed_when_deleting_page
+    assert WikiRedirect.create(:wiki => @wiki, :title => 'An_old_page', :redirects_to => 'Original_title')
+
+    @original.destroy
+    assert_nil @wiki.redirects.first
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7b/7b54bcb0df97869017d78b50300be1638742d7dc.svn-base
--- /dev/null
+++ b/.svn/pristine/7b/7b54bcb0df97869017d78b50300be1638742d7dc.svn-base
@@ -0,0 +1,208 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/cvs_adapter'
+require 'digest/sha1'
+
+class Repository::Cvs < Repository
+  validates_presence_of :url, :root_url, :log_encoding
+
+  safe_attributes 'root_url',
+    :if => lambda {|repository, user| repository.new_record?}
+
+  def self.human_attribute_name(attribute_key_name, *args)
+    attr_name = attribute_key_name.to_s
+    if attr_name == "root_url"
+      attr_name = "cvsroot"
+    elsif attr_name == "url"
+      attr_name = "cvs_module"
+    end
+    super(attr_name, *args)
+  end
+
+  def self.scm_adapter_class
+    Redmine::Scm::Adapters::CvsAdapter
+  end
+
+  def self.scm_name
+    'CVS'
+  end
+
+  def entry(path=nil, identifier=nil)
+    rev = identifier.nil? ? nil : changesets.find_by_revision(identifier)
+    scm.entry(path, rev.nil? ? nil : rev.committed_on)
+  end
+
+  def entries(path=nil, identifier=nil)
+    rev = nil
+    if ! identifier.nil?
+      rev = changesets.find_by_revision(identifier)
+      return nil if rev.nil?
+    end
+    entries = scm.entries(path, rev.nil? ? nil : rev.committed_on)
+    if entries
+      entries.each() do |entry|
+        if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? )
+          change = filechanges.find_by_revision_and_path(
+                     entry.lastrev.revision,
+                     scm.with_leading_slash(entry.path) )
+          if change
+            entry.lastrev.identifier = change.changeset.revision
+            entry.lastrev.revision   = change.changeset.revision
+            entry.lastrev.author     = change.changeset.committer
+            # entry.lastrev.branch     = change.branch
+          end
+        end
+      end
+    end
+    load_entries_changesets(entries)
+    entries
+  end
+
+  def cat(path, identifier=nil)
+    rev = nil
+    if ! identifier.nil?
+      rev = changesets.find_by_revision(identifier)
+      return nil if rev.nil?
+    end
+    scm.cat(path, rev.nil? ? nil : rev.committed_on)
+  end
+
+  def annotate(path, identifier=nil)
+    rev = nil
+    if ! identifier.nil?
+      rev = changesets.find_by_revision(identifier)
+      return nil if rev.nil?
+    end
+    scm.annotate(path, rev.nil? ? nil : rev.committed_on)
+  end
+
+  def diff(path, rev, rev_to)
+    # convert rev to revision. CVS can't handle changesets here
+    diff=[]
+    changeset_from = changesets.find_by_revision(rev)
+    if rev_to.to_i > 0
+      changeset_to = changesets.find_by_revision(rev_to)
+    end
+    changeset_from.filechanges.each() do |change_from|
+      revision_from = nil
+      revision_to   = nil
+      if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path))
+        revision_from = change_from.revision
+      end
+      if revision_from
+        if changeset_to
+          changeset_to.filechanges.each() do |change_to|
+            revision_to = change_to.revision if change_to.path == change_from.path
+          end
+        end
+        unless revision_to
+          revision_to = scm.get_previous_revision(revision_from)
+        end
+        file_diff = scm.diff(change_from.path, revision_from, revision_to)
+        diff = diff + file_diff unless file_diff.nil?
+      end
+    end
+    return diff
+  end
+
+  def fetch_changesets
+    # some nifty bits to introduce a commit-id with cvs
+    # natively cvs doesn't provide any kind of changesets,
+    # there is only a revision per file.
+    # we now take a guess using the author, the commitlog and the commit-date.
+
+    # last one is the next step to take. the commit-date is not equal for all
+    # commits in one changeset. cvs update the commit-date when the *,v file was touched. so
+    # we use a small delta here, to merge all changes belonging to _one_ changeset
+    time_delta  = 10.seconds
+    fetch_since = latest_changeset ? latest_changeset.committed_on : nil
+    transaction do
+      tmp_rev_num = 1
+      scm.revisions('', fetch_since, nil, :log_encoding => repo_log_encoding) do |revision|
+        # only add the change to the database, if it doen't exists. the cvs log
+        # is not exclusive at all.
+        tmp_time = revision.time.clone
+        unless filechanges.find_by_path_and_revision(
+	                         scm.with_leading_slash(revision.paths[0][:path]),
+	                         revision.paths[0][:revision]
+	                           )
+          cmt = Changeset.normalize_comments(revision.message, repo_log_encoding)
+          author_utf8 = Changeset.to_utf8(revision.author, repo_log_encoding)
+          cs  = changesets.find(
+            :first,
+            :conditions => {
+                :committed_on => tmp_time - time_delta .. tmp_time + time_delta,
+                :committer    => author_utf8,
+                :comments     => cmt
+                }
+             )
+          # create a new changeset....
+          unless cs
+            # we use a temporaray revision number here (just for inserting)
+            # later on, we calculate a continous positive number
+            tmp_time2 = tmp_time.clone.gmtime
+            branch    = revision.paths[0][:branch]
+            scmid     = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S")
+            cs = Changeset.create(:repository   => self,
+                                  :revision     => "tmp#{tmp_rev_num}",
+                                  :scmid        => scmid,
+                                  :committer    => revision.author,
+                                  :committed_on => tmp_time,
+                                  :comments     => revision.message)
+            tmp_rev_num += 1
+          end
+          # convert CVS-File-States to internal Action-abbrevations
+          # default action is (M)odified
+          action = "M"
+          if revision.paths[0][:action] == "Exp" && revision.paths[0][:revision] == "1.1"
+            action = "A" # add-action always at first revision (= 1.1)
+          elsif revision.paths[0][:action] == "dead"
+            action = "D" # dead-state is similar to Delete
+          end
+          Change.create(
+             :changeset => cs,
+             :action    => action,
+             :path      => scm.with_leading_slash(revision.paths[0][:path]),
+             :revision  => revision.paths[0][:revision],
+             :branch    => revision.paths[0][:branch]
+              )
+        end
+      end
+
+      # Renumber new changesets in chronological order
+      Changeset.all(
+              :order => 'committed_on ASC, id ASC',
+              :conditions => ["repository_id = ? AND revision LIKE 'tmp%'", id]
+           ).each do |changeset|
+        changeset.update_attribute :revision, next_revision_number
+      end
+    end # transaction
+    @current_revision_number = nil
+  end
+
+  private
+
+  # Returns the next revision number to assign to a CVS changeset
+  def next_revision_number
+    # Need to retrieve existing revision numbers to sort them as integers
+    sql = "SELECT revision FROM #{Changeset.table_name} "
+    sql << "WHERE repository_id = #{id} AND revision NOT LIKE 'tmp%'"
+    @current_revision_number ||= (connection.select_values(sql).collect(&:to_i).max || 0)
+    @current_revision_number += 1
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7b/7b72cc518aa8eb0a7421ff01464081caccb29686.svn-base
--- /dev/null
+++ b/.svn/pristine/7b/7b72cc518aa8eb0a7421ff01464081caccb29686.svn-base
@@ -0,0 +1,544 @@
+package Apache::Authn::Redmine;
+
+=head1 Apache::Authn::Redmine
+
+Redmine - a mod_perl module to authenticate webdav subversion users
+against redmine database
+
+=head1 SYNOPSIS
+
+This module allow anonymous users to browse public project and
+registred users to browse and commit their project. Authentication is
+done against the redmine database or the LDAP configured in redmine.
+
+This method is far simpler than the one with pam_* and works with all
+database without an hassle but you need to have apache/mod_perl on the
+svn server.
+
+=head1 INSTALLATION
+
+For this to automagically work, you need to have a recent reposman.rb
+(after r860) and if you already use reposman, read the last section to
+migrate.
+
+Sorry ruby users but you need some perl modules, at least mod_perl2,
+DBI and DBD::mysql (or the DBD driver for you database as it should
+work on allmost all databases).
+
+On debian/ubuntu you must do :
+
+  aptitude install libapache-dbi-perl libapache2-mod-perl2 libdbd-mysql-perl
+
+If your Redmine users use LDAP authentication, you will also need
+Authen::Simple::LDAP (and IO::Socket::SSL if LDAPS is used):
+
+  aptitude install libauthen-simple-ldap-perl libio-socket-ssl-perl
+
+=head1 CONFIGURATION
+
+   ## This module has to be in your perl path
+   ## eg:  /usr/lib/perl5/Apache/Authn/Redmine.pm
+   PerlLoadModule Apache::Authn::Redmine
+   <Location /svn>
+     DAV svn
+     SVNParentPath "/var/svn"
+
+     AuthType Basic
+     AuthName redmine
+     Require valid-user
+
+     PerlAccessHandler Apache::Authn::Redmine::access_handler
+     PerlAuthenHandler Apache::Authn::Redmine::authen_handler
+
+     ## for mysql
+     RedmineDSN "DBI:mysql:database=databasename;host=my.db.server"
+     ## for postgres
+     # RedmineDSN "DBI:Pg:dbname=databasename;host=my.db.server"
+
+     RedmineDbUser "redmine"
+     RedmineDbPass "password"
+     ## Optional where clause (fulltext search would be slow and
+     ## database dependant).
+     # RedmineDbWhereClause "and members.role_id IN (1,2)"
+     ## Optional credentials cache size
+     # RedmineCacheCredsMax 50
+  </Location>
+
+To be able to browse repository inside redmine, you must add something
+like that :
+
+   <Location /svn-private>
+     DAV svn
+     SVNParentPath "/var/svn"
+     Order deny,allow
+     Deny from all
+     # only allow reading orders
+     <Limit GET PROPFIND OPTIONS REPORT>
+       Allow from redmine.server.ip
+     </Limit>
+   </Location>
+
+and you will have to use this reposman.rb command line to create repository :
+
+  reposman.rb --redmine my.redmine.server --svn-dir /var/svn --owner www-data -u http://svn.server/svn-private/
+
+=head1 REPOSITORIES NAMING
+
+A projet repository must be named with the projet identifier. In case
+of multiple repositories for the same project, use the project identifier
+and the repository identifier separated with a dot:
+
+  /var/svn/foo
+  /var/svn/foo.otherrepo
+
+=head1 MIGRATION FROM OLDER RELEASES
+
+If you use an older reposman.rb (r860 or before), you need to change
+rights on repositories to allow the apache user to read and write
+S<them :>
+
+  sudo chown -R www-data /var/svn/*
+  sudo chmod -R u+w /var/svn/*
+
+And you need to upgrade at least reposman.rb (after r860).
+
+=head1 GIT SMART HTTP SUPPORT
+
+Git's smart HTTP protocol (available since Git 1.7.0) will not work with the
+above settings. Redmine.pm normally does access control depending on the HTTP
+method used: read-only methods are OK for everyone in public projects and
+members with read rights in private projects. The rest require membership with
+commit rights in the project.
+
+However, this scheme doesn't work for Git's smart HTTP protocol, as it will use
+POST even for a simple clone. Instead, read-only requests must be detected using
+the full URL (including the query string): anything that doesn't belong to the
+git-receive-pack service is read-only.
+
+To activate this mode of operation, add this line inside your <Location /git>
+block:
+
+  RedmineGitSmartHttp yes
+
+Here's a sample Apache configuration which integrates git-http-backend with
+a MySQL database and this new option:
+
+   SetEnv GIT_PROJECT_ROOT /var/www/git/
+   SetEnv GIT_HTTP_EXPORT_ALL
+   ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
+   <Location /git>
+       Order allow,deny
+       Allow from all
+
+       AuthType Basic
+       AuthName Git
+       Require valid-user
+
+       PerlAccessHandler Apache::Authn::Redmine::access_handler
+       PerlAuthenHandler Apache::Authn::Redmine::authen_handler
+       # for mysql
+       RedmineDSN "DBI:mysql:database=redmine;host=127.0.0.1"
+       RedmineDbUser "redmine"
+       RedmineDbPass "xxx"
+       RedmineGitSmartHttp yes
+    </Location>
+
+Make sure that all the names of the repositories under /var/www/git/ have a
+matching identifier for some project: /var/www/git/myproject and
+/var/www/git/myproject.git will work. You can put both bare and non-bare
+repositories in /var/www/git, though bare repositories are strongly
+recommended. You should create them with the rights of the user running Redmine,
+like this:
+
+  cd /var/www/git
+  sudo -u user-running-redmine mkdir myproject
+  cd myproject
+  sudo -u user-running-redmine git init --bare
+
+Once you have activated this option, you have three options when cloning a
+repository:
+
+- Cloning using "http://user@host/git/repo(.git)" works, but will ask for the password
+  all the time.
+
+- Cloning with "http://user:pass@host/git/repo(.git)" does not have this problem, but
+  this could reveal accidentally your password to the console in some versions
+  of Git, and you would have to ensure that .git/config is not readable except
+  by the owner for each of your projects.
+
+- Use "http://host/git/repo(.git)", and store your credentials in the ~/.netrc
+  file. This is the recommended solution, as you only have one file to protect
+  and passwords will not be leaked accidentally to the console.
+
+  IMPORTANT NOTE: It is *very important* that the file cannot be read by other
+  users, as it will contain your password in cleartext. To create the file, you
+  can use the following commands, replacing yourhost, youruser and yourpassword
+  with the right values:
+
+    touch ~/.netrc
+    chmod 600 ~/.netrc
+    echo -e "machine yourhost\nlogin youruser\npassword yourpassword" > ~/.netrc
+
+=cut
+
+use strict;
+use warnings FATAL => 'all', NONFATAL => 'redefine';
+
+use DBI;
+use Digest::SHA;
+# optional module for LDAP authentication
+my $CanUseLDAPAuth = eval("use Authen::Simple::LDAP; 1");
+
+use Apache2::Module;
+use Apache2::Access;
+use Apache2::ServerRec qw();
+use Apache2::RequestRec qw();
+use Apache2::RequestUtil qw();
+use Apache2::Const qw(:common :override :cmd_how);
+use APR::Pool ();
+use APR::Table ();
+
+# use Apache2::Directive qw();
+
+my @directives = (
+  {
+    name => 'RedmineDSN',
+    req_override => OR_AUTHCFG,
+    args_how => TAKE1,
+    errmsg => 'Dsn in format used by Perl DBI. eg: "DBI:Pg:dbname=databasename;host=my.db.server"',
+  },
+  {
+    name => 'RedmineDbUser',
+    req_override => OR_AUTHCFG,
+    args_how => TAKE1,
+  },
+  {
+    name => 'RedmineDbPass',
+    req_override => OR_AUTHCFG,
+    args_how => TAKE1,
+  },
+  {
+    name => 'RedmineDbWhereClause',
+    req_override => OR_AUTHCFG,
+    args_how => TAKE1,
+  },
+  {
+    name => 'RedmineCacheCredsMax',
+    req_override => OR_AUTHCFG,
+    args_how => TAKE1,
+    errmsg => 'RedmineCacheCredsMax must be decimal number',
+  },
+  {
+    name => 'RedmineGitSmartHttp',
+    req_override => OR_AUTHCFG,
+    args_how => TAKE1,
+  },
+);
+
+sub RedmineDSN {
+  my ($self, $parms, $arg) = @_;
+  $self->{RedmineDSN} = $arg;
+  my $query = "SELECT 
+                 users.hashed_password, users.salt, users.auth_source_id, roles.permissions, projects.status
+              FROM projects, users, roles
+              WHERE 
+                users.login=? 
+                AND projects.identifier=?
+                AND users.status=1 
+                AND (
+                  roles.id IN (SELECT member_roles.role_id FROM members, member_roles WHERE members.user_id = users.id AND members.project_id = projects.id AND members.id = member_roles.member_id)
+                  OR
+                  (roles.builtin=1 AND cast(projects.is_public as CHAR) IN ('t', '1'))
+                )
+                AND roles.permissions IS NOT NULL";
+  $self->{RedmineQuery} = trim($query);
+}
+
+sub RedmineDbUser { set_val('RedmineDbUser', @_); }
+sub RedmineDbPass { set_val('RedmineDbPass', @_); }
+sub RedmineDbWhereClause {
+  my ($self, $parms, $arg) = @_;
+  $self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." ");
+}
+
+sub RedmineCacheCredsMax {
+  my ($self, $parms, $arg) = @_;
+  if ($arg) {
+    $self->{RedmineCachePool} = APR::Pool->new;
+    $self->{RedmineCacheCreds} = APR::Table::make($self->{RedmineCachePool}, $arg);
+    $self->{RedmineCacheCredsCount} = 0;
+    $self->{RedmineCacheCredsMax} = $arg;
+  }
+}
+
+sub RedmineGitSmartHttp {
+  my ($self, $parms, $arg) = @_;
+  $arg = lc $arg;
+
+  if ($arg eq "yes" || $arg eq "true") {
+    $self->{RedmineGitSmartHttp} = 1;
+  } else {
+    $self->{RedmineGitSmartHttp} = 0;
+  }
+}
+
+sub trim {
+  my $string = shift;
+  $string =~ s/\s{2,}/ /g;
+  return $string;
+}
+
+sub set_val {
+  my ($key, $self, $parms, $arg) = @_;
+  $self->{$key} = $arg;
+}
+
+Apache2::Module::add(__PACKAGE__, \@directives);
+
+
+my %read_only_methods = map { $_ => 1 } qw/GET HEAD PROPFIND REPORT OPTIONS/;
+
+sub request_is_read_only {
+  my ($r) = @_;
+  my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
+
+  # Do we use Git's smart HTTP protocol, or not?
+  if (defined $cfg->{RedmineGitSmartHttp} and $cfg->{RedmineGitSmartHttp}) {
+    my $uri = $r->unparsed_uri;
+    my $location = $r->location;
+    my $is_read_only = $uri !~ m{^$location/*[^/]+/+(info/refs\?service=)?git\-receive\-pack$}o;
+    return $is_read_only;
+  } else {
+    # Standard behaviour: check the HTTP method
+    my $method = $r->method;
+    return defined $read_only_methods{$method};
+  }
+}
+
+sub access_handler {
+  my $r = shift;
+
+  unless ($r->some_auth_required) {
+      $r->log_reason("No authentication has been configured");
+      return FORBIDDEN;
+  }
+
+  return OK unless request_is_read_only($r);
+
+  my $project_id = get_project_identifier($r);
+
+  $r->set_handlers(PerlAuthenHandler => [\&OK])
+      if is_public_project($project_id, $r) && anonymous_role_allows_browse_repository($r);
+
+  return OK
+}
+
+sub authen_handler {
+  my $r = shift;
+
+  my ($res, $redmine_pass) =  $r->get_basic_auth_pw();
+  return $res unless $res == OK;
+
+  if (is_member($r->user, $redmine_pass, $r)) {
+      return OK;
+  } else {
+      $r->note_auth_failure();
+      return DECLINED;
+  }
+}
+
+# check if authentication is forced
+sub is_authentication_forced {
+  my $r = shift;
+
+  my $dbh = connect_database($r);
+  my $sth = $dbh->prepare(
+    "SELECT value FROM settings where settings.name = 'login_required';"
+  );
+
+  $sth->execute();
+  my $ret = 0;
+  if (my @row = $sth->fetchrow_array) {
+    if ($row[0] eq "1" || $row[0] eq "t") {
+      $ret = 1;
+    }
+  }
+  $sth->finish();
+  undef $sth;
+
+  $dbh->disconnect();
+  undef $dbh;
+
+  $ret;
+}
+
+sub is_public_project {
+    my $project_id = shift;
+    my $r = shift;
+
+    if (is_authentication_forced($r)) {
+      return 0;
+    }
+
+    my $dbh = connect_database($r);
+    my $sth = $dbh->prepare(
+        "SELECT is_public FROM projects WHERE projects.identifier = ? AND projects.status <> 9;"
+    );
+
+    $sth->execute($project_id);
+    my $ret = 0;
+    if (my @row = $sth->fetchrow_array) {
+      if ($row[0] eq "1" || $row[0] eq "t") {
+        $ret = 1;
+      }
+    }
+    $sth->finish();
+    undef $sth;
+    $dbh->disconnect();
+    undef $dbh;
+
+    $ret;
+}
+
+sub anonymous_role_allows_browse_repository {
+  my $r = shift;
+
+  my $dbh = connect_database($r);
+  my $sth = $dbh->prepare(
+      "SELECT permissions FROM roles WHERE builtin = 2;"
+  );
+
+  $sth->execute();
+  my $ret = 0;
+  if (my @row = $sth->fetchrow_array) {
+    if ($row[0] =~ /:browse_repository/) {
+      $ret = 1;
+    }
+  }
+  $sth->finish();
+  undef $sth;
+  $dbh->disconnect();
+  undef $dbh;
+
+  $ret;
+}
+
+# perhaps we should use repository right (other read right) to check public access.
+# it could be faster BUT it doesn't work for the moment.
+# sub is_public_project_by_file {
+#     my $project_id = shift;
+#     my $r = shift;
+
+#     my $tree = Apache2::Directive::conftree();
+#     my $node = $tree->lookup('Location', $r->location);
+#     my $hash = $node->as_hash;
+
+#     my $svnparentpath = $hash->{SVNParentPath};
+#     my $repos_path = $svnparentpath . "/" . $project_id;
+#     return 1 if (stat($repos_path))[2] & 00007;
+# }
+
+sub is_member {
+  my $redmine_user = shift;
+  my $redmine_pass = shift;
+  my $r = shift;
+
+  my $dbh         = connect_database($r);
+  my $project_id  = get_project_identifier($r);
+
+  my $pass_digest = Digest::SHA::sha1_hex($redmine_pass);
+
+  my $access_mode = request_is_read_only($r) ? "R" : "W";
+
+  my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
+  my $usrprojpass;
+  if ($cfg->{RedmineCacheCredsMax}) {
+    $usrprojpass = $cfg->{RedmineCacheCreds}->get($redmine_user.":".$project_id.":".$access_mode);
+    return 1 if (defined $usrprojpass and ($usrprojpass eq $pass_digest));
+  }
+  my $query = $cfg->{RedmineQuery};
+  my $sth = $dbh->prepare($query);
+  $sth->execute($redmine_user, $project_id);
+
+  my $ret;
+  while (my ($hashed_password, $salt, $auth_source_id, $permissions, $project_status) = $sth->fetchrow_array) {
+      if ($project_status eq "9" || ($project_status ne "1" && $access_mode eq "W")) {
+        last;
+      }
+
+      unless ($auth_source_id) {
+          my $method = $r->method;
+          my $salted_password = Digest::SHA::sha1_hex($salt.$pass_digest);
+          if ($hashed_password eq $salted_password && (($access_mode eq "R" && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/) ) {
+              $ret = 1;
+              last;
+          }
+      } elsif ($CanUseLDAPAuth) {
+          my $sthldap = $dbh->prepare(
+              "SELECT host,port,tls,account,account_password,base_dn,attr_login from auth_sources WHERE id = ?;"
+          );
+          $sthldap->execute($auth_source_id);
+          while (my @rowldap = $sthldap->fetchrow_array) {
+            my $bind_as = $rowldap[3] ? $rowldap[3] : "";
+            my $bind_pw = $rowldap[4] ? $rowldap[4] : "";
+            if ($bind_as =~ m/\$login/) {
+              # replace $login with $redmine_user and use $redmine_pass
+              $bind_as =~ s/\$login/$redmine_user/g;
+              $bind_pw = $redmine_pass
+            }
+            my $ldap = Authen::Simple::LDAP->new(
+                host    =>      ($rowldap[2] eq "1" || $rowldap[2] eq "t") ? "ldaps://$rowldap[0]:$rowldap[1]" : $rowldap[0],
+                port    =>      $rowldap[1],
+                basedn  =>      $rowldap[5],
+                binddn  =>      $bind_as,
+                bindpw  =>      $bind_pw,
+                filter  =>      "(".$rowldap[6]."=%s)"
+            );
+            my $method = $r->method;
+            $ret = 1 if ($ldap->authenticate($redmine_user, $redmine_pass) && (($access_mode eq "R" && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/));
+
+          }
+          $sthldap->finish();
+          undef $sthldap;
+      }
+  }
+  $sth->finish();
+  undef $sth;
+  $dbh->disconnect();
+  undef $dbh;
+
+  if ($cfg->{RedmineCacheCredsMax} and $ret) {
+    if (defined $usrprojpass) {
+      $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id.":".$access_mode, $pass_digest);
+    } else {
+      if ($cfg->{RedmineCacheCredsCount} < $cfg->{RedmineCacheCredsMax}) {
+        $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id.":".$access_mode, $pass_digest);
+        $cfg->{RedmineCacheCredsCount}++;
+      } else {
+        $cfg->{RedmineCacheCreds}->clear();
+        $cfg->{RedmineCacheCredsCount} = 0;
+      }
+    }
+  }
+
+  $ret;
+}
+
+sub get_project_identifier {
+    my $r = shift;
+
+    my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
+    my $location = $r->location;
+    $location =~ s/\.git$// if (defined $cfg->{RedmineGitSmartHttp} and $cfg->{RedmineGitSmartHttp});
+    my ($identifier) = $r->uri =~ m{$location/*([^/.]+)};
+    $identifier;
+}
+
+sub connect_database {
+    my $r = shift;
+
+    my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
+    return DBI->connect($cfg->{RedmineDSN}, $cfg->{RedmineDbUser}, $cfg->{RedmineDbPass});
+}
+
+1;
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7b/7b79b629f3da71f401261cf1288a60cb2acf04af.svn-base
--- a/.svn/pristine/7b/7b79b629f3da71f401261cf1288a60cb2acf04af.svn-base
+++ /dev/null
@@ -1,93 +0,0 @@
-# redMine - project management software
-# Copyright (C) 2006-2008  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Acts
-    module ActivityProvider
-      def self.included(base)
-        base.extend ClassMethods
-      end
-
-      module ClassMethods
-        def acts_as_activity_provider(options = {})
-          unless self.included_modules.include?(Redmine::Acts::ActivityProvider::InstanceMethods)
-            cattr_accessor :activity_provider_options
-            send :include, Redmine::Acts::ActivityProvider::InstanceMethods
-          end
-
-          options.assert_valid_keys(:type, :permission, :timestamp, :author_key, :find_options)
-          self.activity_provider_options ||= {}
-          
-          # One model can provide different event types
-          # We store these options in activity_provider_options hash
-          event_type = options.delete(:type) || self.name.underscore.pluralize
-          
-          options[:timestamp] ||= "#{table_name}.created_on"
-          options[:find_options] ||= {}
-          options[:author_key] = "#{table_name}.#{options[:author_key]}" if options[:author_key].is_a?(Symbol)
-          self.activity_provider_options[event_type] = options
-        end
-      end
-
-      module InstanceMethods
-        def self.included(base)
-          base.extend ClassMethods
-        end
-                
-        module ClassMethods
-          # Returns events of type event_type visible by user that occured between from and to
-          def find_events(event_type, user, from, to, options)
-            provider_options = activity_provider_options[event_type]
-            raise "#{self.name} can not provide #{event_type} events." if provider_options.nil?
-            
-            scope_options = {}
-            cond = ARCondition.new
-            if from && to
-              cond.add(["#{provider_options[:timestamp]} BETWEEN ? AND ?", from, to])
-            end
-            
-            if options[:author]
-              return [] if provider_options[:author_key].nil?
-              cond.add(["#{provider_options[:author_key]} = ?", options[:author].id])
-            end
-            
-            if options[:limit]
-              # id and creation time should be in same order in most cases
-              scope_options[:order] = "#{table_name}.id DESC"
-              scope_options[:limit] = options[:limit]
-            end
-            
-            scope = self
-            if provider_options.has_key?(:permission)
-              cond.add(Project.allowed_to_condition(user, provider_options[:permission] || :view_project, options))
-            elsif respond_to?(:visible)
-              scope = scope.visible(user, options)
-            else
-              ActiveSupport::Deprecation.warn "acts_as_activity_provider with implicit :permission option is deprecated. Add a visible scope to the #{self.name} model or use explicit :permission option."
-              cond.add(Project.allowed_to_condition(user, "view_#{self.name.underscore.pluralize}".to_sym, options))
-            end
-            scope_options[:conditions] = cond.conditions
-            
-            with_scope(:find => scope_options) do
-              scope.find(:all, provider_options[:find_options].dup)
-            end
-          end
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7b/7b9a1465ac8385995afb9de947ead6e1c8315950.svn-base
--- /dev/null
+++ b/.svn/pristine/7b/7b9a1465ac8385995afb9de947ead6e1c8315950.svn-base
@@ -0,0 +1,1085 @@
+sq:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%m/%d/%Y"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
+    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%m/%d/%Y %I:%M %p"
+      time: "%I:%M %p"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "half a minute"
+      less_than_x_seconds:
+        one:   "less than 1 second"
+        other: "less than %{count} seconds"
+      x_seconds:
+        one:   "1 second"
+        other: "%{count} seconds"
+      less_than_x_minutes:
+        one:   "less than a minute"
+        other: "less than %{count} minutes"
+      x_minutes:
+        one:   "1 minute"
+        other: "%{count} minutes"
+      about_x_hours:
+        one:   "about 1 hour"
+        other: "about %{count} hours"
+      x_hours:
+        one:   "1 ore"
+        other: "%{count} ore"
+      x_days:
+        one:   "1 day"
+        other: "%{count} days"
+      about_x_months:
+        one:   "about 1 month"
+        other: "about %{count} months"
+      x_months:
+        one:   "1 month"
+        other: "%{count} months"
+      about_x_years:
+        one:   "about 1 year"
+        other: "about %{count} years"
+      over_x_years:
+        one:   "over 1 year"
+        other: "over %{count} years"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "dhe"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 gabim nuk lejon kete %{model} te ruhet"
+          other:  "%{count} gabime nuk lejon kete %{model} te ruhet"
+      messages:
+        inclusion: "nuk eshte perfshire ne liste"
+        exclusion: "eshte i/e rezervuar"
+        invalid: "eshte invalid"
+        confirmation: "nuk perkon me konfirmimin"
+        accepted: "duhet pranuar"
+        empty: "nuk mund te jete bosh"
+        blank: "nuk mund te jete blank"
+        too_long: "eshte shume i gjate (maksimumi eshte %{count} karaktere)"
+        too_short: "eshte shume i gjate (minimumi eshte %{count} karaktere)"
+        wrong_length: "eshte gjatesi e gabuar (duhet te jete %{count} karaktere)"
+        taken: "eshte zene"
+        not_a_number: "nuk eshte numer"
+        not_a_date: "nuk eshte date e vlefshme"
+        greater_than: "duhet te jete me i/e madh(e) se %{count}"
+        greater_than_or_equal_to: "duhet te jete me i/e madh(e) se ose i/e barabarte me %{count}"
+        equal_to: "duhet te jete i/e barabarte me %{count}"
+        less_than: "duhet te jete me i/e vogel se %{count}"
+        less_than_or_equal_to: "duhet te jete me i/e vogel se ose i/e barabarte me %{count}"
+        odd: "duhet te jete tek"
+        even: "duhet te jete cift"
+        greater_than_start_date: "duhet te jete me i/e madh(e) se data e fillimit"
+        not_same_project: "nuk i perket te njejtit projekt"
+        circular_dependency: "Ky relacion do te krijoje nje varesi ciklike (circular dependency)"
+        cant_link_an_issue_with_a_descendant: "Nje ceshtje nuk mund te lidhet me nenceshtje"
+
+  actionview_instancetag_blank_option: Zgjidhni
+
+  general_text_No: 'Jo'
+  general_text_Yes: 'Po'
+  general_text_no: 'jo'
+  general_text_yes: 'po'
+  general_lang_name: 'Albanian (Shqip)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_updated: Llogaria u perditesua me sukses.
+  notice_account_invalid_creditentials: Perdorues ose Fjalekalim i gabuar.
+  notice_account_password_updated: Fjalekalimi u ndryshua me sukses.
+  notice_account_wrong_password: Fjalekalim i gabuar
+  notice_account_register_done: Llogaria u krijua me sukses. Per te aktivizuar Llogarine tuaj, ndiqni link-un e derguar ne email-in tuaj.
+  notice_account_unknown_email: Perdorues i paidentifikuar.
+  notice_can_t_change_password: Kjo Llogari administrohet nga nje server tjeter. E pamundur te ndryshohet Fjalekalimi.
+  notice_account_lost_email_sent: Ju eshte derguar nje email me instruksionet per te zgjedhur nje Fjalekalim te ri.
+  notice_account_activated: Llogaria juaj u Aktivizua. Tani mund te beni Login.
+  notice_successful_create: Krijim me sukses.
+  notice_successful_update: Modifikim me sukses.
+  notice_successful_delete: Fshirje me sukses.
+  notice_successful_connection: Lidhje e suksesshme.
+  notice_file_not_found: Faqja qe po kerkoni te aksesoni nuk ekziston ose eshte shperngulur.
+  notice_locking_conflict: Te dhenat jane modifikuar nga nje Perdorues tjeter.
+  notice_not_authorized: Nuk jeni i autorizuar te aksesoni kete faqe.
+  notice_not_authorized_archived_project: Projekti, qe po tentoni te te aksesoni eshte arkivuar.
+  notice_email_sent: "Nje email eshte derguar ne %{value}"
+  notice_email_error: "Pati nje gabim gjate dergimit te email-it (%{value})"
+  notice_feeds_access_key_reseted: Your RSS access key was reset.
+  notice_api_access_key_reseted: Your API access key was reset.
+  notice_failed_to_save_issues: "Deshtoi ne ruajtjen e %{count} ceshtje(ve) ne %{total} te zgjedhura: %{ids}."
+  notice_failed_to_save_time_entries: "Deshtoi ne ruajtjen e %{count} time entrie(s) ne %{total} te zgjedhura: %{ids}."
+  notice_failed_to_save_members: "Deshtoi ne ruajtjen e member(s): %{errors}."
+  notice_no_issue_selected: "Nuk eshte zgjedhur asnje Ceshtje! Zgjidh Ceshtjen qe deshironi te modifikoni."
+  notice_account_pending: "Llogaria juaj u krijua dhe eshte ne pritje te aprovimit nga nje administrator."
+  notice_default_data_loaded: Konfigurimi i paracaktuar u ngarkua me sukses.
+  notice_unable_delete_version: E pamundur te fshije versionin.
+  notice_unable_delete_time_entry: E pamundur te fshije rekordin e log-ut.
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})"
+  notice_issue_successful_create: "Ceshtja %{id} u krijua."
+  notice_issue_update_conflict: "Ceshtja eshte perditesuar nga Perdorues te tjere nderkohe qe ju po e modifikonit ate."
+  notice_account_deleted: "Llogaria juaj u fshi perfundimisht."
+
+  error_can_t_load_default_data: "Konfigurimi i paracaktuar nuk mund te ngarkohet: %{value}"
+  error_scm_not_found: "The entry or revision was not found in the repository."
+  error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
+  error_scm_annotate: "The entry does not exist or cannot be annotated."
+  error_scm_annotate_big_text_file: "The entry cannot be annotated, as it exceeds the maximum text file size."
+  error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
+  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
+  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_can_not_delete_tracker: "This tracker contains issues and cannot be deleted."
+  error_can_not_remove_role: "This role is in use and cannot be deleted."
+  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version cannot be reopened'
+  error_can_not_archive_project: This project cannot be archived
+  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
+  error_workflow_copy_source: 'Please select a source tracker or role'
+  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
+  error_unable_delete_issue_status: 'Unable to delete issue status'
+  error_unable_to_connect: "Unable to connect (%{value})"
+  error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})"
+  warning_attachments_not_saved: "%{count} file(s) could not be saved."
+
+  mail_subject_lost_password: "Fjalekalimi %{value} i juaj"
+  mail_body_lost_password: 'Per te ndryshuar Fjalekalimin, ndiq link-un ne vijim:'
+  mail_subject_register: "Aktivizimi %{value} i Llogarise tuaj"
+  mail_body_register: 'Per te aktivizuar Llogarine tuaj, ndiqni link-un ne vijim:'
+  mail_body_account_information_external: "Mund te perdorni Llogarine tuaj %{value} per Login."
+  mail_body_account_information: Informacioni i Llogarise suaj
+  mail_subject_account_activation_request: "%{value} kerkesa aktivizimi Llogarije"
+  mail_body_account_activation_request: "Nje Perdorues i ri (%{value}) eshte regjistruar. Llogaria pret aprovimin tuaj:"
+  mail_subject_reminder: "%{count} Ceshtje te pritshme ne %{days} ditet pasardhese"
+  mail_body_reminder: "%{count} Ceshtje qe ju jane caktuar jane te pritshme ne %{days} ditet pasardhese:"
+  mail_subject_wiki_content_added: "'%{id}' wiki page eshte shtuar"
+  mail_body_wiki_content_added: "The '%{id}' wiki page eshte shtuar nga %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' wiki page eshte modifikuar"
+  mail_body_wiki_content_updated: "The '%{id}' wiki page eshte modifikuar nga %{author}."
+
+
+  field_name: Emri
+  field_description: Pershkrimi
+  field_summary: Permbledhje
+  field_is_required: E Detyrueshme
+  field_firstname: Emri
+  field_lastname: Mbiemri
+  field_mail: Email
+  field_filename: File
+  field_filesize: Madhesia
+  field_downloads: Shkarkime
+  field_author: Autori
+  field_created_on: Krijuar me
+  field_updated_on: Perditesuar me
+  field_field_format: Formati
+  field_is_for_all: Per te gjthe Projektet
+  field_possible_values: Vlera e Mundshme
+  field_regexp: Shprehja e Duhur
+  field_min_length: Gjatesia Minimale
+  field_max_length: Gjatesia Maksimale
+  field_value: Vlera
+  field_category: Kategoria
+  field_title: Titulli
+  field_project: Projekti
+  field_issue: Problemi
+  field_status: Statusi
+  field_notes: Shenime
+  field_is_closed: Problemet e Mbyllura
+  field_is_default: Vlera e Paracaktuar
+  field_tracker: Gjurmuesi
+  field_subject: Subjekti
+  field_due_date: Deri me
+  field_assigned_to: I Ngarkuari
+  field_priority: Prioriteti
+  field_fixed_version: Menyra e Etiketimit
+  field_user: Perdoruesi
+  field_principal: Kapitali
+  field_role: Roli
+  field_homepage: Faqja Kryesore
+  field_is_public: Publike
+  field_parent: Nenprojekti i
+  field_is_in_roadmap: Ceshtje e shfaqur ne roadmap
+  field_login: Login
+  field_mail_notification: Njoftim me Email
+  field_admin: Administratori
+  field_last_login_on: Lidhja e Fundit
+  field_language: Gjuha
+  field_effective_date: Data
+  field_password: Fjalekalimi
+  field_new_password: Fjalekalimi i Ri
+  field_password_confirmation: Konfirmim Fjalekalimi
+  field_version: Versioni
+  field_type: Type
+  field_host: Host
+  field_port: Port
+  field_account: Llogaria
+  field_base_dn: Base DN
+  field_attr_login: Login attribute
+  field_attr_firstname: Firstname attribute
+  field_attr_lastname: Lastname attribute
+  field_attr_mail: Email attribute
+  field_onthefly: On-the-fly user creation
+  field_start_date: Start date
+  field_done_ratio: "% Done"
+  field_auth_source: Authentication mode
+  field_hide_mail: Hide my email address
+  field_comments: Comment
+  field_url: URL
+  field_start_page: Start page
+  field_subproject: Subproject
+  field_hours: Hours
+  field_activity: Activity
+  field_spent_on: Date
+  field_identifier: Identifier
+  field_is_filter: Used as a filter
+  field_issue_to: Related issue
+  field_delay: Delay
+  field_assignable: Issues can be assigned to this role
+  field_redirect_existing_links: Redirect existing links
+  field_estimated_hours: Estimated time
+  field_column_names: Columns
+  field_time_entries: Log time
+  field_time_zone: Time zone
+  field_searchable: Searchable
+  field_default_value: Default value
+  field_comments_sorting: Display comments
+  field_parent_title: Parent page
+  field_editable: Editable
+  field_watcher: Watcher
+  field_identity_url: OpenID URL
+  field_content: Content
+  field_group_by: Group results by
+  field_sharing: Sharing
+  field_parent_issue: Parent task
+  field_member_of_group: "Assignee's group"
+  field_assigned_to_role: "Assignee's role"
+  field_text: Text field
+  field_visible: Visible
+  field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text"
+  field_issues_visibility: Issues visibility
+  field_is_private: Private
+  field_commit_logs_encoding: Commit messages encoding
+  field_scm_path_encoding: Path encoding
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvsroot: CVSROOT
+  field_cvs_module: Module
+  field_repository_is_default: Main repository
+  field_multiple: Multiple values
+  field_auth_source_ldap_filter: LDAP filter
+
+  setting_app_title: Application title
+  setting_app_subtitle: Application subtitle
+  setting_welcome_text: Welcome text
+  setting_default_language: Default language
+  setting_login_required: Authentication required
+  setting_self_registration: Self-registration
+  setting_attachment_max_size: Maximum attachment size
+  setting_issues_export_limit: Issues export limit
+  setting_mail_from: Emission email address
+  setting_bcc_recipients: Blind carbon copy recipients (bcc)
+  setting_plain_text_mail: Plain text mail (no HTML)
+  setting_host_name: Host name and path
+  setting_text_formatting: Text formatting
+  setting_wiki_compression: Wiki history compression
+  setting_feeds_limit: Maximum number of items in Atom feeds
+  setting_default_projects_public: New projects are public by default
+  setting_autofetch_changesets: Fetch commits automatically
+  setting_sys_api_enabled: Enable WS for repository management
+  setting_commit_ref_keywords: Referencing keywords
+  setting_commit_fix_keywords: Fixing keywords
+  setting_autologin: Autologin
+  setting_date_format: Date format
+  setting_time_format: Time format
+  setting_cross_project_issue_relations: Allow cross-project issue relations
+  setting_issue_list_default_columns: Default columns displayed on the issue list
+  setting_repositories_encodings: Attachments and repositories encodings
+  setting_protocol: Protocol
+  setting_per_page_options: Objects per page options
+  setting_user_format: Users display format
+  setting_activity_days_default: Days displayed on project activity
+  setting_display_subprojects_issues: Display subprojects issues on main projects by default
+  setting_enabled_scm: Enabled SCM
+  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
+  setting_mail_handler_api_enabled: Enable WS for incoming emails
+  setting_mail_handler_api_key: API key
+  setting_sequential_project_identifiers: Generate sequential project identifiers
+  setting_gravatar_enabled: Use Gravatar user icons
+  setting_gravatar_default: Default Gravatar image
+  setting_diff_max_lines_displayed: Maximum number of diff lines displayed
+  setting_file_max_size_displayed: Maximum size of text files displayed inline
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_openid: Allow OpenID login and registration
+  setting_password_min_length: Minimum password length
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_field: Use the issue field
+  setting_issue_done_ratio_issue_status: Use the issue status
+  setting_start_of_week: Start calendars on
+  setting_rest_api_enabled: Enable REST web service
+  setting_cache_formatted_text: Cache formatted text
+  setting_default_notification_option: Default notification option
+  setting_commit_logtime_enabled: Enable time logging
+  setting_commit_logtime_activity_id: Activity for logged time
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  setting_issue_group_assignment: Allow issue assignment to groups
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  setting_unsubscribe: Allow users to delete their own account
+
+  permission_add_project: Create project
+  permission_add_subprojects: Create subprojects
+  permission_edit_project: Edit project
+  permission_select_project_modules: Select project modules
+  permission_manage_members: Manage members
+  permission_manage_project_activities: Manage project activities
+  permission_manage_versions: Manage versions
+  permission_manage_categories: Manage issue categories
+  permission_view_issues: View Issues
+  permission_add_issues: Add issues
+  permission_edit_issues: Edit issues
+  permission_manage_issue_relations: Manage issue relations
+  permission_set_issues_private: Set issues public or private
+  permission_set_own_issues_private: Set own issues public or private
+  permission_add_issue_notes: Add notes
+  permission_edit_issue_notes: Edit notes
+  permission_edit_own_issue_notes: Edit own notes
+  permission_move_issues: Move issues
+  permission_delete_issues: Delete issues
+  permission_manage_public_queries: Manage public queries
+  permission_save_queries: Save queries
+  permission_view_gantt: View gantt chart
+  permission_view_calendar: View calendar
+  permission_view_issue_watchers: View watchers list
+  permission_add_issue_watchers: Add watchers
+  permission_delete_issue_watchers: Delete watchers
+  permission_log_time: Log spent time
+  permission_view_time_entries: View spent time
+  permission_edit_time_entries: Edit time logs
+  permission_edit_own_time_entries: Edit own time logs
+  permission_manage_news: Manage news
+  permission_comment_news: Comment news
+  permission_view_documents: View documents
+  permission_manage_files: Manage files
+  permission_view_files: View files
+  permission_manage_wiki: Manage wiki
+  permission_rename_wiki_pages: Rename wiki pages
+  permission_delete_wiki_pages: Delete wiki pages
+  permission_view_wiki_pages: View wiki
+  permission_view_wiki_edits: View wiki history
+  permission_edit_wiki_pages: Edit wiki pages
+  permission_delete_wiki_pages_attachments: Delete attachments
+  permission_protect_wiki_pages: Protect wiki pages
+  permission_manage_repository: Manage repository
+  permission_browse_repository: Browse repository
+  permission_view_changesets: View changesets
+  permission_commit_access: Commit access
+  permission_manage_boards: Manage forums
+  permission_view_messages: View messages
+  permission_add_messages: Post messages
+  permission_edit_messages: Edit messages
+  permission_edit_own_messages: Edit own messages
+  permission_delete_messages: Delete messages
+  permission_delete_own_messages: Delete own messages
+  permission_export_wiki_pages: Export wiki pages
+  permission_manage_subtasks: Manage subtasks
+  permission_manage_related_issues: Manage related issues
+
+  project_module_issue_tracking: Issue tracking
+  project_module_time_tracking: Time tracking
+  project_module_news: News
+  project_module_documents: Documents
+  project_module_files: Files
+  project_module_wiki: Wiki
+  project_module_repository: Repository
+  project_module_boards: Forums
+  project_module_calendar: Calendar
+  project_module_gantt: Gantt
+
+  label_user: Perdoruesi
+  label_user_plural: Perdoruesit
+  label_user_new: Perdorues i ri
+  label_user_anonymous: Anonim
+  label_project: Projekt
+  label_project_new: Projekt i ri
+  label_project_plural: Projekte
+  label_x_projects:
+    zero:  asnje projekt
+    one:   1 projekt
+    other: "%{count} projekte"
+  label_project_all: Te gjithe Projektet
+  label_project_latest: Projektet me te fundit
+  label_issue: Ceshtje
+  label_issue_new: Ceshtje e re
+  label_issue_plural: Ceshtjet
+  label_issue_view_all: Shih te gjitha Ceshtjet
+  label_issues_by: "Ceshtje per %{value}"
+  label_issue_added: Ceshtje te shtuara
+  label_issue_updated: Ceshtje te modifikuara
+  label_issue_note_added: Shenime te shtuara
+  label_issue_status_updated: Statusi u modifikua
+  label_issue_priority_updated: Prioriteti u modifikua
+  label_document: Dokument
+  label_document_new: Dokument i ri
+  label_document_plural: Dokumente
+  label_document_added: Dokumente te shtuara
+  label_role: Roli
+  label_role_plural: Role
+  label_role_new: Rol i ri
+  label_role_and_permissions: Role dhe te Drejta
+  label_role_anonymous: Anonim
+  label_role_non_member: Jo Anetar
+  label_member: Anetar
+  label_member_new: Anetar i ri
+  label_member_plural: Anetare
+  label_tracker: Gjurmues
+  label_tracker_plural: Gjurmuesa
+  label_tracker_new: Gjurmues i ri
+  label_workflow: Workflow
+  label_issue_status: Statusi i Ceshtjes
+  label_issue_status_plural: Statuset e Ceshtjeve
+  label_issue_status_new: Statusi i ri
+  label_issue_category: Kategoria e Ceshtjes
+  label_issue_category_plural: Kategorite e Ceshtjeve
+  label_issue_category_new: Kategori e re
+  label_custom_field: Fushe e personalizuar
+  label_custom_field_plural: Fusha te personalizuara
+  label_custom_field_new: Fushe e personalizuar e re
+  label_enumerations: Enumerations
+  label_enumeration_new: Vlere e re
+  label_information: Informacion
+  label_information_plural: Informacione
+  label_please_login: Lutemi login
+  label_register: Regjistrohu
+  label_login_with_open_id_option: ose lidhu me OpenID
+  label_password_lost: Fjalekalim i humbur
+  label_home: Home
+  label_my_page: Faqja ime
+  label_my_account: Llogaria ime
+  label_my_projects: Projektet e mia
+  label_my_page_block: My page block
+  label_administration: Administrim
+  label_login: Login
+  label_logout: Dalje
+  label_help: Ndihme
+  label_reported_issues: Ceshtje te raportuara
+  label_assigned_to_me_issues: Ceshtje te caktuara mua
+  label_last_login: Hyrja e fundit
+  label_registered_on: Regjistruar me
+  label_activity: Aktiviteti
+  label_overall_activity: Aktiviteti i pergjithshem
+  label_user_activity: "Aktiviteti i %{value}"
+  label_new: Shto
+  label_logged_as: Lidhur si
+  label_environment: Ambienti
+  label_authentication: Authentikimi
+  label_auth_source: Menyra e Authentikimit
+  label_auth_source_new: Menyre e re Authentikimi
+  label_auth_source_plural: Menyrat e Authentikimit
+  label_subproject_plural: Nenprojekte
+  label_subproject_new: Nenprojekt i ri
+  label_and_its_subprojects: "%{value} dhe Nenprojektet e vet"
+  label_min_max_length: Gjatesia Min - Max
+  label_list: List
+  label_date: Date
+  label_integer: Integer
+  label_float: Float
+  label_boolean: Boolean
+  label_string: Text
+  label_text: Long text
+  label_attribute: Attribute
+  label_attribute_plural: Attributes
+  label_no_data: No data to display
+  label_change_status: Change status
+  label_history: Histori
+  label_attachment: File
+  label_attachment_new: File i ri
+  label_attachment_delete: Fshi file
+  label_attachment_plural: Files
+  label_file_added: File te shtuar
+  label_report: Raport
+  label_report_plural: Raporte
+  label_news: Lajm
+  label_news_new: Shto Lajm
+  label_news_plural: Lajme
+  label_news_latest: Lajmet e fundit
+  label_news_view_all: Veshtro gjithe Lajmet
+  label_news_added: Lajme te shtuara
+  label_news_comment_added: Komenti iu shtua Lajmeve
+  label_settings: Settings
+  label_overview: Overview
+  label_version: Version
+  label_version_new: Version i ri
+  label_version_plural: Versione
+  label_close_versions: Mbyll Versionet e perfunduara
+  label_confirmation: Konfirmim
+  label_export_to: 'Mund te gjendet gjithashtu ne:'
+  label_read: Lexim...
+  label_public_projects: Projekte publike
+  label_open_issues: e hapur
+  label_open_issues_plural: te hapura
+  label_closed_issues: e mbyllur
+  label_closed_issues_plural: te mbyllura
+  label_x_open_issues_abbr_on_total:
+    zero:  0 te hapura / %{total}
+    one:   1 e hapur / %{total}
+    other: "%{count} te hapura / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 te hapura
+    one:   1 e hapur
+    other: "%{count} te hapura"
+  label_x_closed_issues_abbr:
+    zero:  0 te mbyllura
+    one:   1 e mbyllur
+    other: "%{count} te mbyllura"
+  label_x_issues:
+    zero:  0 ceshtje
+    one:   1 ceshtje
+    other: "%{count} ceshtje"
+  label_total: Total
+  label_permissions: Te drejta
+  label_current_status: Statusi aktual
+  label_new_statuses_allowed: Statuse te reja te lejuara
+  label_all: te gjitha
+  label_none: asnje
+  label_nobody: askush
+  label_next: Pasardhes
+  label_previous: Paraardhes
+  label_used_by: Perdorur nga
+  label_details: Detaje
+  label_add_note: Shto nje Shenim
+  label_per_page: Per Faqe
+  label_calendar: Kalendar
+  label_months_from: muaj nga
+  label_gantt: Gantt
+  label_internal: I brendshem
+  label_last_changes: "%{count} ndryshimet e fundit"
+  label_change_view_all: Shih gjithe ndryshimet
+  label_personalize_page: Personalizo kete Faqe
+  label_comment: Koment
+  label_comment_plural: Komente
+  label_x_comments:
+    zero: asnje koment
+    one: 1 koment
+    other: "%{count} komente"
+  label_comment_add: Shto nje koment
+  label_comment_added: Komenti u shtua
+  label_comment_delete: Fshi komente
+  label_query: Custom query
+  label_query_plural: Custom queries
+  label_query_new: New query
+  label_my_queries: My custom queries
+  label_filter_add: Shto filter
+  label_filter_plural: Filtra
+  label_equals: eshte
+  label_not_equals: nuk eshte
+  label_in_less_than: ne me pak se
+  label_in_more_than: ne me shume se
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_between: ndermjet
+  label_in: ne
+  label_today: sot
+  label_all_time: cdo kohe
+  label_yesterday: dje
+  label_this_week: kete jave
+  label_last_week: javen e kaluar
+  label_last_n_days: "%{count} ditet e fundit"
+  label_this_month: kete muaj
+  label_last_month: muajin e kaluar
+  label_this_year: kete vit
+  label_date_range: Date range
+  label_less_than_ago: me pak se dite para
+  label_more_than_ago: me shume se dite para
+  label_ago: dite para
+  label_contains: permban
+  label_not_contains: nuk permban
+  label_day_plural: dite
+  label_repository: Repository
+  label_repository_new: New repository
+  label_repository_plural: Repositories
+  label_browse: Browse
+  label_branch: Dege
+  label_tag: Tag
+  label_revision: Revizion
+  label_revision_plural: Revizione
+  label_revision_id: "Revizion %{value}"
+  label_associated_revisions: Associated revisions
+  label_added: te shtuara
+  label_modified: te modifikuara
+  label_copied: te kopjuara
+  label_renamed: te riemeruara
+  label_deleted: te fshira
+  label_latest_revision: Revizioni i fundit
+  label_latest_revision_plural: Revizionet e fundit
+  label_view_revisions: Shih Revizionet
+  label_view_all_revisions: Shih te gjitha Revizionet
+  label_max_size: Maximum size
+  label_sort_highest: Coje ne krye
+  label_sort_higher: Coje lart
+  label_sort_lower: Coje poshte
+  label_sort_lowest: Coje ne fund
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "E pritshme ne %{value}"
+  label_roadmap_overdue: "%{value} me vonese"
+  label_roadmap_no_issues: Asnje Ceshtje per kete version
+  label_search: Kerko
+  label_result_plural: Rezultatet
+  label_all_words: Te gjitha fjalet
+  label_wiki: Wiki
+  label_wiki_edit: Wiki edit
+  label_wiki_edit_plural: Wiki edits
+  label_wiki_page: Wiki page
+  label_wiki_page_plural: Wiki pages
+  label_index_by_title: Index by title
+  label_index_by_date: Index by date
+  label_current_version: Current version
+  label_preview: Preview
+  label_feed_plural: Feeds
+  label_changes_details: Details of all changes
+  label_issue_tracking: Issue tracking
+  label_spent_time: Spent time
+  label_overall_spent_time: Overall spent time
+  label_f_hour: "%{value} ore"
+  label_f_hour_plural: "%{value} ore"
+  label_time_tracking: Time tracking
+  label_change_plural: Ndryshimet
+  label_statistics: Statistika
+  label_commits_per_month: Commits per month
+  label_commits_per_author: Commits per author
+  label_diff: diff
+  label_view_diff: View differences
+  label_diff_inline: inline
+  label_diff_side_by_side: side by side
+  label_options: Options
+  label_copy_workflow_from: Copy workflow from
+  label_permissions_report: Permissions report
+  label_watched_issues: Watched issues
+  label_related_issues: Related issues
+  label_applied_status: Applied status
+  label_loading: Loading...
+  label_relation_new: New relation
+  label_relation_delete: Delete relation
+  label_relates_to: related to
+  label_duplicates: duplicates
+  label_duplicated_by: duplicated by
+  label_blocks: blocks
+  label_blocked_by: blocked by
+  label_precedes: precedes
+  label_follows: follows
+  label_end_to_start: end to start
+  label_end_to_end: end to end
+  label_start_to_start: start to start
+  label_start_to_end: start to end
+  label_stay_logged_in: Stay logged in
+  label_disabled: disabled
+  label_show_completed_versions: Show completed versions
+  label_me: me
+  label_board: Forum
+  label_board_new: New forum
+  label_board_plural: Forums
+  label_board_locked: Locked
+  label_board_sticky: Sticky
+  label_topic_plural: Topics
+  label_message_plural: Messages
+  label_message_last: Last message
+  label_message_new: New message
+  label_message_posted: Message added
+  label_reply_plural: Replies
+  label_send_information: Send account information to the user
+  label_year: Year
+  label_month: Month
+  label_week: Week
+  label_date_from: From
+  label_date_to: To
+  label_language_based: Based on user's language
+  label_sort_by: "Sort by %{value}"
+  label_send_test_email: Send a test email
+  label_feeds_access_key: RSS access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  label_feeds_access_key_created_on: "RSS access key created %{value} ago"
+  label_module_plural: Modules
+  label_added_time_by: "Added by %{author} %{age} ago"
+  label_updated_time_by: "Updated by %{author} %{age} ago"
+  label_updated_time: "Updated %{value} ago"
+  label_jump_to_a_project: Jump to a project...
+  label_file_plural: Files
+  label_changeset_plural: Changesets
+  label_default_columns: Default columns
+  label_no_change_option: (No change)
+  label_bulk_edit_selected_issues: Bulk edit selected issues
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  label_theme: Theme
+  label_default: Default
+  label_search_titles_only: Search titles only
+  label_user_mail_option_all: "For any event on all my projects"
+  label_user_mail_option_selected: "For any event on the selected projects only..."
+  label_user_mail_option_none: "No events"
+  label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
+  label_user_mail_option_only_assigned: "Only for things I am assigned to"
+  label_user_mail_option_only_owner: "Only for things I am the owner of"
+  label_user_mail_no_self_notified: "I don't want to be notified of changes that I make myself"
+  label_registration_activation_by_email: account activation by email
+  label_registration_manual_activation: manual account activation
+  label_registration_automatic_activation: automatic account activation
+  label_display_per_page: "Per page: %{value}"
+  label_age: Age
+  label_change_properties: Change properties
+  label_general: General
+  label_more: More
+  label_scm: SCM
+  label_plugins: Plugins
+  label_ldap_authentication: LDAP authentication
+  label_downloads_abbr: D/L
+  label_optional_description: Optional description
+  label_add_another_file: Add another file
+  label_preferences: Preferences
+  label_chronological_order: In chronological order
+  label_reverse_chronological_order: In reverse chronological order
+  label_planning: Planning
+  label_incoming_emails: Incoming emails
+  label_generate_key: Generate a key
+  label_issue_watchers: Watchers
+  label_example: Example
+  label_display: Display
+  label_sort: Sort
+  label_ascending: Ascending
+  label_descending: Descending
+  label_date_from_to: From %{start} to %{end}
+  label_wiki_content_added: Wiki page added
+  label_wiki_content_updated: Wiki page updated
+  label_group: Group
+  label_group_plural: Groups
+  label_group_new: New group
+  label_time_entry_plural: Spent time
+  label_version_sharing_none: Not shared
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_tree: With project tree
+  label_version_sharing_system: With all projects
+  label_update_issue_done_ratios: Update issue done ratios
+  label_copy_source: Source
+  label_copy_target: Target
+  label_copy_same_as_target: Same as target
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_api_access_key: API access key
+  label_missing_api_access_key: Missing an API access key
+  label_api_access_key_created_on: "API access key created %{value} ago"
+  label_profile: Profile
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_issues_visibility_all: All issues
+  label_issues_visibility_public: All non private issues
+  label_issues_visibility_own: Issues created by or assigned to the user
+  label_git_report_last_commit: Report last commit for files and directories
+  label_parent_revision: Parent
+  label_child_revision: Child
+  label_export_options: "%{export_format} export options"
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position} of %{count}"
+  label_completed_versions: Completed versions
+  label_search_for_watchers: Search for watchers to add
+
+  button_login: Login
+  button_submit: Submit
+  button_save: Save
+  button_check_all: Check all
+  button_uncheck_all: Uncheck all
+  button_collapse_all: Collapse all
+  button_expand_all: Expand all
+  button_delete: Delete
+  button_create: Create
+  button_create_and_continue: Create and continue
+  button_test: Test
+  button_edit: Edit
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  button_add: Add
+  button_change: Change
+  button_apply: Apply
+  button_clear: Clear
+  button_lock: Lock
+  button_unlock: Unlock
+  button_download: Download
+  button_list: List
+  button_view: View
+  button_move: Move
+  button_move_and_follow: Move and follow
+  button_back: Back
+  button_cancel: Cancel
+  button_activate: Activate
+  button_sort: Sort
+  button_log_time: Log time
+  button_rollback: Rollback to this version
+  button_watch: Watch
+  button_unwatch: Unwatch
+  button_reply: Reply
+  button_archive: Archive
+  button_unarchive: Unarchive
+  button_reset: Reset
+  button_rename: Rename
+  button_change_password: Change password
+  button_copy: Copy
+  button_copy_and_follow: Copy and follow
+  button_annotate: Annotate
+  button_update: Update
+  button_configure: Configure
+  button_quote: Quote
+  button_duplicate: Duplicate
+  button_show: Show
+  button_edit_section: Edit this section
+  button_export: Export
+  button_delete_my_account: Delete my account
+
+  status_active: active
+  status_registered: registered
+  status_locked: locked
+
+  version_status_open: open
+  version_status_locked: locked
+  version_status_closed: closed
+
+  field_active: Active
+
+  text_select_mail_notifications: Select actions for which email notifications should be sent.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 means no restriction
+  text_project_destroy_confirmation: Are you sure you want to delete this project and related data?
+  text_subprojects_destroy_warning: "Its subproject(s): %{value} will be also deleted."
+  text_workflow_edit: Select a role and a tracker to edit the workflow
+  text_are_you_sure: Are you sure?
+  text_journal_changed: "%{label} changed from %{old} to %{new}"
+  text_journal_changed_no_detail: "%{label} updated"
+  text_journal_set_to: "%{label} set to %{value}"
+  text_journal_deleted: "%{label} deleted (%{old})"
+  text_journal_added: "%{label} %{value} added"
+  text_tip_issue_begin_day: issue beginning this day
+  text_tip_issue_end_day: issue ending this day
+  text_tip_issue_begin_end_day: issue beginning and ending this day
+  text_project_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.'
+  text_caracters_maximum: "%{count} characters maximum."
+  text_caracters_minimum: "Must be at least %{count} characters long."
+  text_length_between: "Length between %{min} and %{max} characters."
+  text_tracker_no_workflow: No workflow defined for this tracker
+  text_unallowed_characters: Unallowed characters
+  text_comma_separated: Multiple values allowed (comma separated).
+  text_line_separated: Multiple values allowed (one line for each value).
+  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
+  text_issue_added: "Issue %{id} has been reported by %{author}."
+  text_issue_updated: "Issue %{id} has been updated by %{author}."
+  text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content?
+  text_issue_category_destroy_question: "Some issues (%{count}) are assigned to this category. What do you want to do?"
+  text_issue_category_destroy_assignments: Remove category assignments
+  text_issue_category_reassign_to: Reassign issues to this category
+  text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
+  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
+  text_load_default_configuration: Load the default configuration
+  text_status_changed_by_changeset: "Applied in changeset %{value}."
+  text_time_logged_by_changeset: "Applied in changeset %{value}."
+  text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?'
+  text_issues_destroy_descendants_confirmation: "This will also delete %{count} subtask(s)."
+  text_time_entries_destroy_confirmation: 'Are you sure you want to delete the selected time entr(y/ies)?'
+  text_select_project_modules: 'Select modules to enable for this project:'
+  text_default_administrator_account_changed: Default administrator account changed
+  text_file_repository_writable: Attachments directory writable
+  text_plugin_assets_writable: Plugin assets directory writable
+  text_rmagick_available: RMagick available (optional)
+  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do?"
+  text_destroy_time_entries: Delete reported hours
+  text_assign_time_entries_to_project: Assign reported hours to the project
+  text_reassign_time_entries: 'Reassign reported hours to this issue:'
+  text_user_wrote: "%{value} wrote:"
+  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
+  text_enumeration_category_reassign_to: 'Reassign them to this value:'
+  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
+  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
+  text_custom_field_possible_values_info: 'One line for each value'
+  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
+  text_wiki_page_nullify_children: "Keep child pages as root pages"
+  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
+  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
+  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
+  text_zoom_in: Zoom in
+  text_zoom_out: Zoom out
+  text_warn_on_leaving_unsaved: "The current page contains unsaved text that will be lost if you leave this page."
+  text_scm_path_encoding_note: "Default: UTF-8"
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  text_issue_conflict_resolution_overwrite: "Apply my changes anyway (previous notes will be kept but some changes may be overwritten)"
+  text_issue_conflict_resolution_add_notes: "Add my notes and discard my other changes"
+  text_issue_conflict_resolution_cancel: "Discard all my changes and redisplay %{link}"
+  text_account_destroy_confirmation: "Are you sure you want to proceed?\nYour account will be permanently deleted, with no way to reactivate it."
+
+  default_role_manager: Manager
+  default_role_developer: Developer
+  default_role_reporter: Reporter
+  default_tracker_bug: Bug
+  default_tracker_feature: Feature
+  default_tracker_support: Support
+  default_issue_status_new: New
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: Resolved
+  default_issue_status_feedback: Feedback
+  default_issue_status_closed: Closed
+  default_issue_status_rejected: Rejected
+  default_doc_category_user: User documentation
+  default_doc_category_tech: Technical documentation
+  default_priority_low: Low
+  default_priority_normal: Normal
+  default_priority_high: High
+  default_priority_urgent: Urgent
+  default_priority_immediate: Immediate
+  default_activity_design: Design
+  default_activity_development: Development
+
+  enumeration_issue_priorities: Issue priorities
+  enumeration_doc_categories: Document categories
+  enumeration_activities: Activities (time tracking)
+  enumeration_system_activity: System Activity
+  description_filter: Filter
+  description_search: Searchfield
+  description_choose_project: Projects
+  description_project_scope: Search scope
+  description_notes: Notes
+  description_message_content: Message content
+  description_query_sort_criteria_attribute: Sort attribute
+  description_query_sort_criteria_direction: Sort direction
+  description_user_mail_notification: Mail notification settings
+  description_available_columns: Available Columns
+  description_selected_columns: Selected Columns
+  description_all_columns: All Columns
+  description_issue_category_reassign: Choose issue category
+  description_wiki_subpages_reassign: Choose new parent page
+  description_date_range_list: Choose range from list
+  description_date_range_interval: Choose range by selecting start and end date
+  description_date_from: Enter start date
+  description_date_to: Enter end date
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.'
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: te gjitha
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_footer: Email footer
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7c/7c0793046e6842f067096f93f3d1b6e963a83b49.svn-base
--- a/.svn/pristine/7c/7c0793046e6842f067096f93f3d1b6e963a83b49.svn-base
+++ /dev/null
@@ -1,33 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Views
-    class OtherFormatsBuilder
-      def initialize(view)
-        @view = view
-      end
-
-      def link_to(name, options={})
-        url = { :format => name.to_s.downcase }.merge(options.delete(:url) || {})
-        caption = options.delete(:caption) || name
-        html_options = { :class => name.to_s.downcase, :rel => 'nofollow' }.merge(options)
-        @view.content_tag('span', @view.link_to(caption, url, html_options))
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7c/7c1301162ea6bb82a007534a13501f191a1f47c9.svn-base
--- a/.svn/pristine/7c/7c1301162ea6bb82a007534a13501f191a1f47c9.svn-base
+++ /dev/null
@@ -1,90 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class JournalTest < ActiveSupport::TestCase
-  fixtures :projects, :issues, :issue_statuses, :journals, :journal_details, :users, :members, :member_roles
-
-  def setup
-    @journal = Journal.find 1
-  end
-
-  def test_journalized_is_an_issue
-    issue = @journal.issue
-    assert_kind_of Issue, issue
-    assert_equal 1, issue.id
-  end
-
-  def test_new_status
-    status = @journal.new_status
-    assert_not_nil status
-    assert_kind_of IssueStatus, status
-    assert_equal 2, status.id
-  end
-
-  def test_create_should_send_email_notification
-    ActionMailer::Base.deliveries.clear
-    issue = Issue.find(:first)
-    user = User.find(:first)
-    journal = issue.init_journal(user, issue)
-
-    assert journal.save
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_visible_scope_for_anonymous
-    # Anonymous user should see issues of public projects only
-    journals = Journal.visible(User.anonymous).all
-    assert journals.any?
-    assert_nil journals.detect {|journal| !journal.issue.project.is_public?}
-    # Anonymous user should not see issues without permission
-    Role.anonymous.remove_permission!(:view_issues)
-    journals = Journal.visible(User.anonymous).all
-    assert journals.empty?
-  end
-
-  def test_visible_scope_for_user
-    user = User.find(9)
-    assert user.projects.empty?
-    # Non member user should see issues of public projects only
-    journals = Journal.visible(user).all
-    assert journals.any?
-    assert_nil journals.detect {|journal| !journal.issue.project.is_public?}
-    # Non member user should not see issues without permission
-    Role.non_member.remove_permission!(:view_issues)
-    user.reload
-    journals = Journal.visible(user).all
-    assert journals.empty?
-    # User should see issues of projects for which he has view_issues permissions only
-    Member.create!(:principal => user, :project_id => 1, :role_ids => [1])
-    user.reload
-    journals = Journal.visible(user).all
-    assert journals.any?
-    assert_nil journals.detect {|journal| journal.issue.project_id != 1}
-  end
-
-  def test_visible_scope_for_admin
-    user = User.find(1)
-    user.members.each(&:destroy)
-    assert user.projects.empty?
-    journals = Journal.visible(user).all
-    assert journals.any?
-    # Admin should see issues on private projects that he does not belong to
-    assert journals.detect {|journal| !journal.issue.project.is_public?}
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7c/7c196d5273bcb940eb10ad58017c16601e771158.svn-base
--- /dev/null
+++ b/.svn/pristine/7c/7c196d5273bcb940eb10ad58017c16601e771158.svn-base
@@ -0,0 +1,18 @@
+<h3><%=l(:label_assigned_to_me_issues)%> (<%= Issue.visible.open.count(:conditions => {:assigned_to_id => ([User.current.id] + User.current.group_ids)})%>)</h3>
+
+<% assigned_issues = issuesassignedtome_items %>
+<%= render :partial => 'issues/list_simple', :locals => { :issues => assigned_issues } %>
+<% if assigned_issues.length > 0 %>
+<p class="small"><%= link_to l(:label_issue_view_all), :controller => 'issues',
+                                                       :action => 'index',
+                                                       :set_filter => 1,
+                                                       :assigned_to_id => 'me',
+                                                       :sort => 'priority:desc,updated_on:desc' %></p>
+<% end %>
+
+<% content_for :header_tags do %>
+<%= auto_discovery_link_tag(:atom,
+                            {:controller => 'issues', :action => 'index', :set_filter => 1,
+                             :assigned_to_id => 'me', :format => 'atom', :key => User.current.rss_key},
+                            {:title => l(:label_assigned_to_me_issues)}) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7c/7c48a2f2c6660008fb7234d1e70560afa7f9be22.svn-base
--- /dev/null
+++ b/.svn/pristine/7c/7c48a2f2c6660008fb7234d1e70560afa7f9be22.svn-base
@@ -0,0 +1,1108 @@
+# Turkish translations for Ruby on Rails
+# by Ozgun Ataman (ozataman@gmail.com)
+# by Burak Yigit Kaya (ben@byk.im)
+
+tr:
+  locale:
+    native_name: TÃ¼rkÃ§e
+    address_separator: " "
+  direction: ltr
+  date:
+    formats:
+      default: "%d.%m.%Y"
+      numeric: "%d.%m.%Y"
+      short: "%e %b"
+      long: "%e %B %Y, %A"
+      only_day: "%e"
+
+    day_names: [Pazar, Pazartesi, SalÄ±, Ã‡arÅŸamba, PerÅŸembe, Cuma, Cumartesi]
+    abbr_day_names: [Pzr, Pzt, Sal, Ã‡rÅŸ, PrÅŸ, Cum, Cts]
+    month_names: [~, Ocak, Åžubat, Mart, Nisan, MayÄ±s, Haziran, Temmuz, AÄŸustos, EylÃ¼l, Ekim, KasÄ±m, AralÄ±k]
+    abbr_month_names: [~, Oca, Åžub, Mar, Nis, May, Haz, Tem, AÄŸu, Eyl, Eki, Kas, Ara]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a %d.%b.%y %H:%M"
+      numeric: "%d.%b.%y %H:%M"
+      short: "%e %B, %H:%M"
+      long: "%e %B %Y, %A, %H:%M"
+      time: "%H:%M"
+
+    am: "Ã¶ÄŸleden Ã¶nce"
+    pm: "Ã¶ÄŸleden sonra"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: 'yarÄ±m dakika'
+      less_than_x_seconds:
+        zero: '1 saniyeden az'
+        one: '1 saniyeden az'
+        other: '%{count} saniyeden az'
+      x_seconds:
+        one: '1 saniye'
+        other: '%{count} saniye'
+      less_than_x_minutes:
+        zero: '1 dakikadan az'
+        one: '1 dakikadan az'
+        other: '%{count} dakikadan az'
+      x_minutes:
+        one: '1 dakika'
+        other: '%{count} dakika'
+      about_x_hours:
+        one: 'yaklaÅŸÄ±k 1 saat'
+        other: 'yaklaÅŸÄ±k %{count} saat'
+      x_hours:
+        one:   "1 saat"
+        other: "%{count} saat"
+      x_days:
+        one: '1 gÃ¼n'
+        other: '%{count} gÃ¼n'
+      about_x_months:
+        one: 'yaklaÅŸÄ±k 1 ay'
+        other: 'yaklaÅŸÄ±k %{count} ay'
+      x_months:
+        one: '1 ay'
+        other: '%{count} ay'
+      about_x_years:
+        one: 'yaklaÅŸÄ±k 1 yÄ±l'
+        other: 'yaklaÅŸÄ±k %{count} yÄ±l'
+      over_x_years:
+        one: '1 yÄ±ldan fazla'
+        other: '%{count} yÄ±ldan fazla'
+      almost_x_years:
+        one:   "neredeyse 1 YÄ±l"
+        other: "neredeyse %{count} yÄ±l"
+
+  number:
+    format:
+      precision: 2
+      separator: ','
+      delimiter: '.'
+    currency:
+      format:
+        unit: 'TRY'
+        format: '%n%u'
+        separator: ','
+        delimiter: '.'
+        precision: 2
+    percentage:
+      format:
+        delimiter: '.'
+        separator: ','
+        precision: 2
+    precision:
+      format:
+        delimiter: '.'
+        separator: ','
+    human:
+      format:
+        delimiter: '.'
+        separator: ','
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Byte"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  support:
+    array:
+      sentence_connector: "ve"
+      skip_last_comma: true
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "%{model} giriÅŸi kaydedilemedi: 1 hata."
+          other:  "%{model} giriÅŸi kadedilemedi: %{count} hata."
+        body: "LÃ¼tfen aÅŸaÄŸÄ±daki hatalarÄ± dÃ¼zeltiniz:"
+
+      messages:
+        inclusion: "kabul edilen bir kelime deÄŸil"
+        exclusion: "kullanÄ±lamaz"
+        invalid: "geÃ§ersiz"
+        confirmation: "teyidi uyuÅŸmamakta"
+        accepted: "kabul edilmeli"
+        empty: "doldurulmalÄ±"
+        blank: "doldurulmalÄ±"
+        too_long: "Ã§ok uzun (en fazla %{count} karakter)"
+        too_short: "Ã§ok kÄ±sa (en az %{count} karakter)"
+        wrong_length: "yanlÄ±ÅŸ uzunlukta (tam olarak %{count} karakter olmalÄ±)"
+        taken: "hali hazÄ±rda kullanÄ±lmakta"
+        not_a_number: "geÃ§erli bir sayÄ± deÄŸil"
+        greater_than: "%{count} sayÄ±sÄ±ndan bÃ¼yÃ¼k olmalÄ±"
+        greater_than_or_equal_to: "%{count} sayÄ±sÄ±na eÅŸit veya bÃ¼yÃ¼k olmalÄ±"
+        equal_to: "tam olarak %{count} olmalÄ±"
+        less_than: "%{count} sayÄ±sÄ±ndan kÃ¼Ã§Ã¼k olmalÄ±"
+        less_than_or_equal_to: "%{count} sayÄ±sÄ±na eÅŸit veya kÃ¼Ã§Ã¼k olmalÄ±"
+        odd: "tek olmalÄ±"
+        even: "Ã§ift olmalÄ±"
+        greater_than_start_date: "baÅŸlangÄ±Ã§ tarihinden bÃ¼yÃ¼k olmalÄ±"
+        not_same_project: "aynÄ± projeye ait deÄŸil"
+        circular_dependency: "Bu iliÅŸki dÃ¶ngÃ¼sel baÄŸÄ±mlÄ±lÄ±k meydana getirecektir"
+        cant_link_an_issue_with_a_descendant: "Bir iÅŸ, alt iÅŸlerinden birine baÄŸlanamaz"
+      models:
+
+  actionview_instancetag_blank_option: LÃ¼tfen SeÃ§in
+
+  general_text_No: 'HayÄ±r'
+  general_text_Yes: 'Evet'
+  general_text_no: 'hayÄ±r'
+  general_text_yes: 'evet'
+  general_lang_name: 'TÃ¼rkÃ§e'
+  general_csv_separator: ','
+  general_csv_encoding: ISO-8859-9
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_updated: Hesap baÅŸarÄ±yla gÃ¼ncelleÅŸtirildi.
+  notice_account_invalid_creditentials: GeÃ§ersiz kullanÄ±cÄ± ya da parola
+  notice_account_password_updated: Parola baÅŸarÄ±yla gÃ¼ncellendi.
+  notice_account_wrong_password: YanlÄ±ÅŸ parola
+  notice_account_register_done: Hesap baÅŸarÄ±yla oluÅŸturuldu. HesabÄ±nÄ±zÄ± etkinleÅŸtirmek iÃ§in, size gÃ¶nderilen e-postadaki baÄŸlantÄ±ya tÄ±klayÄ±n.
+  notice_account_unknown_email: TanÄ±nmayan kullanÄ±cÄ±.
+  notice_can_t_change_password: Bu hesap harici bir denetim kaynaÄŸÄ± kullanÄ±yor. ParolayÄ± deÄŸiÅŸtirmek mÃ¼mkÃ¼n deÄŸil.
+  notice_account_lost_email_sent: Yeni parola seÃ§me talimatlarÄ±nÄ± iÃ§eren e-postanÄ±z gÃ¶nderildi.
+  notice_account_activated: HesabÄ±nÄ±z etkinleÅŸtirildi. Åžimdi giriÅŸ yapabilirsiniz.
+  notice_successful_create: BaÅŸarÄ±yla oluÅŸturuldu.
+  notice_successful_update: BaÅŸarÄ±yla gÃ¼ncellendi.
+  notice_successful_delete: BaÅŸarÄ±yla silindi.
+  notice_successful_connection: BaÄŸlantÄ± baÅŸarÄ±lÄ±.
+  notice_file_not_found: EriÅŸmek istediÄŸiniz sayfa mevcut deÄŸil ya da kaldÄ±rÄ±lmÄ±ÅŸ.
+  notice_locking_conflict: Veri baÅŸka bir kullanÄ±cÄ± tarafÄ±ndan gÃ¼ncellendi.
+  notice_not_authorized: Bu sayfaya eriÅŸme yetkiniz yok.
+  notice_email_sent: "E-posta gÃ¶nderildi %{value}"
+  notice_email_error: "E-posta gÃ¶nderilirken bir hata oluÅŸtu (%{value})"
+  notice_feeds_access_key_reseted: RSS eriÅŸim anahtarÄ±nÄ±z sÄ±fÄ±rlandÄ±.
+  notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
+  notice_no_issue_selected: "SeÃ§ili iÅŸ yok! LÃ¼tfen, dÃ¼zenlemek istediÄŸiniz iÅŸleri iÅŸaretleyin."
+  notice_account_pending: "HesabÄ±nÄ±z oluÅŸturuldu ve yÃ¶netici onayÄ± bekliyor."
+  notice_default_data_loaded: VarasayÄ±lan konfigÃ¼rasyon baÅŸarÄ±lÄ±yla yÃ¼klendi.
+
+  error_can_t_load_default_data: "VarsayÄ±lan konfigÃ¼rasyon yÃ¼klenemedi: %{value}"
+  error_scm_not_found: "Depoda, giriÅŸ ya da deÄŸiÅŸiklik yok."
+  error_scm_command_failed: "Depoya eriÅŸmeye Ã§alÄ±ÅŸÄ±rken bir hata meydana geldi: %{value}"
+  error_scm_annotate: "GiriÅŸ mevcut deÄŸil veya izah edilemedi."
+  error_issue_not_found_in_project: 'Ä°ÅŸ bilgisi bulunamadÄ± veya bu projeye ait deÄŸil'
+
+  mail_subject_lost_password: "ParolanÄ±z %{value}"
+  mail_body_lost_password: 'ParolanÄ±zÄ± deÄŸiÅŸtirmek iÃ§in, aÅŸaÄŸÄ±daki baÄŸlantÄ±ya tÄ±klayÄ±n:'
+  mail_subject_register: "%{value} hesap aktivasyonu"
+  mail_body_register: 'HesabÄ±nÄ±zÄ± etkinleÅŸtirmek iÃ§in, aÅŸaÄŸÄ±daki baÄŸlantÄ±ya tÄ±klayÄ±n:'
+  mail_body_account_information_external: "HesabÄ±nÄ±zÄ± %{value} giriÅŸ yapmak iÃ§in kullanabilirsiniz."
+  mail_body_account_information: Hesap bilgileriniz
+  mail_subject_account_activation_request: "%{value} hesabÄ± etkinleÅŸtirme isteÄŸi"
+  mail_body_account_activation_request: "Yeni bir kullanÄ±cÄ± (%{value}) kaydedildi. Hesap onaylanmayÄ± bekliyor:"
+
+
+  field_name: Ä°sim
+  field_description: Yorum
+  field_summary: Ã–zet
+  field_is_required: Gerekli
+  field_firstname: Ad
+  field_lastname: Soyad
+  field_mail: E-Posta
+  field_filename: Dosya
+  field_filesize: Boyut
+  field_downloads: Ä°ndirilenler
+  field_author: Yazar
+  field_created_on: OluÅŸturulma
+  field_updated_on: GÃ¼ncellenme
+  field_field_format: BiÃ§im
+  field_is_for_all: TÃ¼m projeler iÃ§in
+  field_possible_values: KullanÄ±labilir deÄŸerler
+  field_regexp: DÃ¼zenli ifadeler
+  field_min_length: En az uzunluk
+  field_max_length: En Ã§ok uzunluk
+  field_value: DeÄŸer
+  field_category: Kategori
+  field_title: BaÅŸlÄ±k
+  field_project: Proje
+  field_issue: Ä°ÅŸ
+  field_status: Durum
+  field_notes: Notlar
+  field_is_closed: Ä°ÅŸ kapatÄ±ldÄ±
+  field_is_default: VarsayÄ±lan DeÄŸer
+  field_tracker: Ä°ÅŸ tipi
+  field_subject: Konu
+  field_due_date: BitiÅŸ Tarihi
+  field_assigned_to: Atanan
+  field_priority: Ã–ncelik
+  field_fixed_version: Hedef SÃ¼rÃ¼m
+  field_user: KullanÄ±cÄ±
+  field_role: Rol
+  field_homepage: Anasayfa
+  field_is_public: Genel
+  field_parent: 'Ãœst proje: '
+  field_is_in_roadmap: Yol haritasÄ±nda gÃ¶sterilen iÅŸler
+  field_login: GiriÅŸ
+  field_mail_notification: E-posta uyarÄ±larÄ±
+  field_admin: YÃ¶netici
+  field_last_login_on: Son BaÄŸlantÄ±
+  field_language: Dil
+  field_effective_date: Tarih
+  field_password: Parola
+  field_new_password: Yeni Parola
+  field_password_confirmation: Onay
+  field_version: SÃ¼rÃ¼m
+  field_type: Tip
+  field_host: Host
+  field_port: Port
+  field_account: Hesap
+  field_base_dn: Base DN
+  field_attr_login: GiriÅŸ NiteliÄŸi
+  field_attr_firstname: Ad NiteliÄŸi
+  field_attr_lastname: Soyad NiteliÄŸi
+  field_attr_mail: E-Posta NiteliÄŸi
+  field_onthefly: AnÄ±nda kullanÄ±cÄ± oluÅŸturma
+  field_start_date: BaÅŸlangÄ±Ã§ Tarihi
+  field_done_ratio: Tamamlanma yÃ¼zdesi
+  field_auth_source: Kimlik Denetim Modu
+  field_hide_mail: E-posta adresimi gizle
+  field_comments: Yorumlar
+  field_url: URL
+  field_start_page: BaÅŸlangÄ±Ã§ SayfasÄ±
+  field_subproject: Alt Proje
+  field_hours: Saat
+  field_activity: Etkinlik
+  field_spent_on: Tarih
+  field_identifier: TanÄ±mlayÄ±cÄ±
+  field_is_filter: filtre olarak kullanÄ±lmÄ±ÅŸ
+  field_issue_to: Ä°liÅŸkili iÅŸ
+  field_delay: Gecikme
+  field_assignable: Bu role atanabilecek iÅŸler
+  field_redirect_existing_links: Mevcut baÄŸlantÄ±larÄ± yÃ¶nlendir
+  field_estimated_hours: Kalan zaman
+  field_column_names: SÃ¼tunlar
+  field_time_zone: Saat dilimi
+  field_searchable: Aranabilir
+  field_default_value: VarsayÄ±lan deÄŸer
+  field_comments_sorting: YorumlarÄ± gÃ¶ster
+
+  setting_app_title: Uygulama BaÄŸlÄ±ÄŸÄ±
+  setting_app_subtitle: Uygulama alt baÅŸlÄ±ÄŸÄ±
+  setting_welcome_text: HoÅŸgeldin MesajÄ±
+  setting_default_language: VarsayÄ±lan Dil
+  setting_login_required: Kimlik denetimi gerekli mi
+  setting_self_registration: Otomatik kayÄ±t
+  setting_attachment_max_size: Maksimum ek boyutu
+  setting_issues_export_limit: Ä°ÅŸlerin dÄ±ÅŸa aktarÄ±lma sÄ±nÄ±rÄ±
+  setting_mail_from: GÃ¶nderici e-posta adresi
+  setting_bcc_recipients: AlÄ±cÄ±larÄ± birbirinden gizle (bcc)
+  setting_host_name: Host adÄ±
+  setting_text_formatting: Metin biÃ§imi
+  setting_wiki_compression: Wiki geÃ§miÅŸini sÄ±kÄ±ÅŸtÄ±r
+  setting_feeds_limit: Haber yayÄ±nÄ± iÃ§erik limiti
+  setting_default_projects_public: Yeni projeler varsayÄ±lan olarak herkese aÃ§Ä±k
+  setting_autofetch_changesets: Otomatik gÃ¶nderi al
+  setting_sys_api_enabled: Depo yÃ¶netimi iÃ§in WS'yi etkinleÅŸtir
+  setting_commit_ref_keywords: BaÅŸvuru Kelimeleri
+  setting_commit_fix_keywords: Sabitleme kelimeleri
+  setting_autologin: Otomatik GiriÅŸ
+  setting_date_format: Tarih Formati
+  setting_time_format: Zaman FormatÄ±
+  setting_cross_project_issue_relations: Ã‡apraz-Proje iÅŸ iliÅŸkilendirmesine izin ver
+  setting_issue_list_default_columns: Ä°ÅŸ listesinde gÃ¶sterilen varsayÄ±lan sÃ¼tunlar
+  setting_emails_footer: E-posta dip not
+  setting_protocol: Protokol
+  setting_per_page_options: Sayfada baÅŸÄ±na Ã¶ÄŸe sayÄ±sÄ±
+  setting_user_format: KullanÄ±cÄ± gÃ¶sterim biÃ§imi
+  setting_activity_days_default: Proje etkinliklerinde gÃ¶sterilen gÃ¼n sayÄ±sÄ±
+  setting_display_subprojects_issues: VarsayÄ±lan olarak ana projenin iÅŸ listesinde alt proje iÅŸlerini gÃ¶ster
+
+  project_module_issue_tracking: Ä°ÅŸ Takibi
+  project_module_time_tracking: Zaman Takibi
+  project_module_news: Haberler
+  project_module_documents: Belgeler
+  project_module_files: Dosyalar
+  project_module_wiki: Wiki
+  project_module_repository: Depo
+  project_module_boards: TartÄ±ÅŸma AlanÄ±
+
+  label_user: KullanÄ±cÄ±
+  label_user_plural: KullanÄ±cÄ±lar
+  label_user_new: Yeni KullanÄ±cÄ±
+  label_project: Proje
+  label_project_new: Yeni proje
+  label_project_plural: Projeler
+  label_x_projects:
+    zero:  hiÃ§ proje yok
+    one:   1 proje
+    other: "%{count} proje"
+  label_project_all: TÃ¼m Projeler
+  label_project_latest: En son projeler
+  label_issue: Ä°ÅŸ
+  label_issue_new: Yeni Ä°ÅŸ
+  label_issue_plural: Ä°ÅŸler
+  label_issue_view_all: TÃ¼m iÅŸleri izle
+  label_issues_by: "%{value} tarafÄ±ndan gÃ¶nderilmiÅŸ iÅŸler"
+  label_issue_added: Ä°ÅŸ eklendi
+  label_issue_updated: Ä°ÅŸ gÃ¼ncellendi
+  label_document: Belge
+  label_document_new: Yeni belge
+  label_document_plural: Belgeler
+  label_document_added: Belge eklendi
+  label_role: Rol
+  label_role_plural: Roller
+  label_role_new: Yeni rol
+  label_role_and_permissions: Roller ve izinler
+  label_member: Ãœye
+  label_member_new: Yeni Ã¼ye
+  label_member_plural: Ãœyeler
+  label_tracker: Ä°ÅŸ tipi
+  label_tracker_plural: Ä°ÅŸ tipleri
+  label_tracker_new: Yeni iÅŸ tipi
+  label_workflow: Ä°ÅŸ akÄ±ÅŸÄ±
+  label_issue_status: Ä°ÅŸ durumu
+  label_issue_status_plural: Ä°ÅŸ durumularÄ±
+  label_issue_status_new: Yeni durum
+  label_issue_category: Ä°ÅŸ kategorisi
+  label_issue_category_plural: Ä°ÅŸ kategorileri
+  label_issue_category_new: Yeni kategori
+  label_custom_field: Ã–zel alan
+  label_custom_field_plural: Ã–zel alanlar
+  label_custom_field_new: Yeni Ã¶zel alan
+  label_enumerations: NumaralandÄ±rmalar
+  label_enumeration_new: Yeni deÄŸer
+  label_information: Bilgi
+  label_information_plural: Bilgi
+  label_please_login: LÃ¼tfen giriÅŸ yapÄ±n
+  label_register: KayÄ±t
+  label_password_lost: ParolamÄ± unuttum
+  label_home: Anasayfa
+  label_my_page: KiÅŸisel Sayfam
+  label_my_account: HesabÄ±m
+  label_my_projects: Projelerim
+  label_administration: YÃ¶netim
+  label_login: GiriÅŸ
+  label_logout: Ã‡Ä±kÄ±ÅŸ
+  label_help: YardÄ±m
+  label_reported_issues: Rapor edilmiÅŸ iÅŸler
+  label_assigned_to_me_issues: Bana atanmÄ±ÅŸ iÅŸler
+  label_last_login: Son baÄŸlantÄ±
+  label_registered_on: KayÄ±t tarihi
+  label_activity: Etkinlik
+  label_overall_activity: TÃ¼m etkinlikler
+  label_new: Yeni
+  label_logged_as: "KullanÄ±cÄ± :"
+  label_environment: Ã‡evre
+  label_authentication: Kimlik Denetimi
+  label_auth_source: Kimlik Denetim Modu
+  label_auth_source_new: Yeni Denetim Modu
+  label_auth_source_plural: Denetim ModlarÄ±
+  label_subproject_plural: Alt Projeler
+  label_min_max_length: Min - Maks uzunluk
+  label_list: Liste
+  label_date: Tarih
+  label_integer: Tam sayÄ±
+  label_float: OndalÄ±klÄ± sayÄ±
+  label_boolean: "Evet/HayÄ±r"
+  label_string: Metin
+  label_text: Uzun Metin
+  label_attribute: Nitelik
+  label_attribute_plural: Nitelikler
+  label_no_data: GÃ¶sterilecek veri yok
+  label_change_status: DeÄŸiÅŸim Durumu
+  label_history: GeÃ§miÅŸ
+  label_attachment: Dosya
+  label_attachment_new: Yeni Dosya
+  label_attachment_delete: DosyayÄ± Sil
+  label_attachment_plural: Dosyalar
+  label_file_added: Eklenen Dosyalar
+  label_report: Rapor
+  label_report_plural: Raporlar
+  label_news: Haber
+  label_news_new: Haber ekle
+  label_news_plural: Haber
+  label_news_latest: Son Haberler
+  label_news_view_all: TÃ¼m haberleri oku
+  label_news_added: Haber eklendi
+  label_settings: Ayarlar
+  label_overview: Genel
+  label_version: SÃ¼rÃ¼m
+  label_version_new: Yeni sÃ¼rÃ¼m
+  label_version_plural: SÃ¼rÃ¼mler
+  label_confirmation: DoÄŸrulamama
+  label_export_to: "DiÄŸer uygun kaynaklar:"
+  label_read: "Oku..."
+  label_public_projects: Genel Projeler
+  label_open_issues: aÃ§Ä±k
+  label_open_issues_plural: aÃ§Ä±k
+  label_closed_issues: kapalÄ±
+  label_closed_issues_plural: kapalÄ±
+  label_x_open_issues_abbr_on_total:
+    zero:  tamamÄ± kapalÄ±, toplam %{total}
+    one:   1'i' aÃ§Ä±k, toplam %{total}
+    other: "%{count} aÃ§Ä±k, toplam %{total}"
+  label_x_open_issues_abbr:
+    zero:  hiÃ§ aÃ§Ä±k yok
+    one:   1 aÃ§Ä±k
+    other: "%{count} aÃ§Ä±k"
+  label_x_closed_issues_abbr:
+    zero:  hiÃ§ kapalÄ± yok
+    one:   1 kapalÄ±
+    other: "%{count} kapalÄ±"
+  label_total: Toplam
+  label_permissions: Ä°zinler
+  label_current_status: Mevcut Durum
+  label_new_statuses_allowed: Yeni durumlara izin verildi
+  label_all: Hepsi
+  label_none: HiÃ§biri
+  label_nobody: HiÃ§kimse
+  label_next: Sonraki
+  label_previous: Ã–nceki
+  label_used_by: 'Kullanan: '
+  label_details: AyrÄ±ntÄ±lar
+  label_add_note: Not ekle
+  label_per_page: Sayfa baÅŸÄ±na
+  label_calendar: Takvim
+  label_months_from: ay Ã¶ncesinden itibaren
+  label_gantt: Ä°ÅŸ-Zaman Ã‡izelgesi
+  label_internal: Dahili
+  label_last_changes: "Son %{count} deÄŸiÅŸiklik"
+  label_change_view_all: TÃ¼m DeÄŸiÅŸiklikleri gÃ¶r
+  label_personalize_page: Bu sayfayÄ± kiÅŸiselleÅŸtir
+  label_comment: Yorum
+  label_comment_plural: Yorumlar
+  label_x_comments:
+    zero: hiÃ§ yorum yok
+    one: 1 yorum
+    other: "%{count} yorum"
+  label_comment_add: Yorum Ekle
+  label_comment_added: Yorum Eklendi
+  label_comment_delete: YorumlarÄ± sil
+  label_query: Ã–zel Sorgu
+  label_query_plural: Ã–zel Sorgular
+  label_query_new: Yeni Sorgu
+  label_filter_add: Filtre ekle
+  label_filter_plural: Filtreler
+  label_equals: EÅŸit
+  label_not_equals: EÅŸit deÄŸil
+  label_in_less_than: kÃ¼Ã§Ã¼ktÃ¼r
+  label_in_more_than: bÃ¼yÃ¼ktÃ¼r
+  label_in: iÃ§inde
+  label_today: bugÃ¼n
+  label_all_time: TÃ¼m Zamanlar
+  label_yesterday: DÃ¼n
+  label_this_week: Bu hafta
+  label_last_week: GeÃ§en hafta
+  label_last_n_days: "Son %{count} gÃ¼n"
+  label_this_month: Bu ay
+  label_last_month: GeÃ§en ay
+  label_this_year: Bu yÄ±l
+  label_date_range: Tarih aralÄ±ÄŸÄ±
+  label_less_than_ago: gÃ¼nler Ã¶ncesinden az
+  label_more_than_ago: gÃ¼nler Ã¶ncesinden fazla
+  label_ago: gÃ¼n Ã¶nce
+  label_contains: iÃ§eriyor
+  label_not_contains: iÃ§ermiyor
+  label_day_plural: GÃ¼nler
+  label_repository: Depo
+  label_repository_plural: Depolar
+  label_browse: GÃ¶zat
+  label_revision: DeÄŸiÅŸiklik
+  label_revision_plural: DeÄŸiÅŸiklikler
+  label_associated_revisions: BirleÅŸtirilmiÅŸ deÄŸiÅŸiklikler
+  label_added: eklendi
+  label_modified: gÃ¼ncellendi
+  label_deleted: silindi
+  label_latest_revision: En son deÄŸiÅŸiklik
+  label_latest_revision_plural: En son deÄŸiÅŸiklikler
+  label_view_revisions: DeÄŸiÅŸiklikleri izle
+  label_max_size: En bÃ¼yÃ¼k boyut
+  label_sort_highest: Ãœste taÅŸÄ±
+  label_sort_higher: YukarÄ± taÅŸÄ±
+  label_sort_lower: AÅŸaÄŸÄ± taÅŸÄ±
+  label_sort_lowest: Dibe taÅŸÄ±
+  label_roadmap: Yol HaritasÄ±
+  label_roadmap_due_in: "%{value} iÃ§inde bitmeli"
+  label_roadmap_overdue: "%{value} geÃ§"
+  label_roadmap_no_issues: Bu sÃ¼rÃ¼m iÃ§in iÅŸ yok
+  label_search: Ara
+  label_result_plural: SonuÃ§lar
+  label_all_words: TÃ¼m Kelimeler
+  label_wiki: Wiki
+  label_wiki_edit: Wiki dÃ¼zenleme
+  label_wiki_edit_plural: Wiki dÃ¼zenlemeleri
+  label_wiki_page: Wiki sayfasÄ±
+  label_wiki_page_plural: Wiki sayfalarÄ±
+  label_index_by_title: BaÅŸlÄ±ÄŸa gÃ¶re diz
+  label_index_by_date: Tarihe gÃ¶re diz
+  label_current_version: GÃ¼ncel sÃ¼rÃ¼m
+  label_preview: Ã–nizleme
+  label_feed_plural: Beslemeler
+  label_changes_details: BÃ¼tÃ¼n deÄŸiÅŸikliklerin detaylarÄ±
+  label_issue_tracking: Ä°ÅŸ Takibi
+  label_spent_time: Harcanan zaman
+  label_f_hour: "%{value} saat"
+  label_f_hour_plural: "%{value} saat"
+  label_time_tracking: Zaman Takibi
+  label_change_plural: DeÄŸiÅŸiklikler
+  label_statistics: Ä°statistikler
+  label_commits_per_month: AylÄ±k teslim
+  label_commits_per_author: Yazar baÅŸÄ±na teslim
+  label_view_diff: FarklarÄ± izle
+  label_diff_inline: satÄ±r iÃ§i
+  label_diff_side_by_side: Yan yana
+  label_options: Tercihler
+  label_copy_workflow_from: Ä°ÅŸakÄ±ÅŸÄ± kopyala
+  label_permissions_report: Ä°zin raporu
+  label_watched_issues: Ä°zlenmiÅŸ iÅŸler
+  label_related_issues: Ä°liÅŸkili iÅŸler
+  label_applied_status: uygulanmÄ±ÅŸ iÅŸler
+  label_loading: YÃ¼kleniyor...
+  label_relation_new: Yeni iliÅŸki
+  label_relation_delete: Ä°liÅŸkiyi sil
+  label_relates_to: iliÅŸkili
+  label_duplicates: yinelenmiÅŸ
+  label_blocks: Engeller
+  label_blocked_by: Engelleyen
+  label_precedes: Ã¶nce gelir
+  label_follows: sonra gelir
+  label_end_to_start: sondan baÅŸa
+  label_end_to_end: sondan sona
+  label_start_to_start: baÅŸtan baÅŸa
+  label_start_to_end: baÅŸtan sona
+  label_stay_logged_in: SÃ¼rekli baÄŸlÄ± kal
+  label_disabled: DevredÄ±ÅŸÄ±
+  label_show_completed_versions: TamamlanmÄ±ÅŸ sÃ¼rÃ¼mleri gÃ¶ster
+  label_me: Ben
+  label_board: TartÄ±ÅŸma AlanÄ±
+  label_board_new: Yeni alan
+  label_board_plural: TartÄ±ÅŸma alanlarÄ±
+  label_topic_plural: Konular
+  label_message_plural: Mesajlar
+  label_message_last: Son mesaj
+  label_message_new: Yeni mesaj
+  label_message_posted: Mesaj eklendi
+  label_reply_plural: Cevaplar
+  label_send_information: Hesap bilgisini kullanÄ±cÄ±ya gÃ¶nder
+  label_year: YÄ±l
+  label_month: Ay
+  label_week: Hafta
+  label_date_from: BaÅŸlangÄ±Ã§
+  label_date_to: BitiÅŸ
+  label_language_based: KullanÄ±cÄ± dili bazlÄ±
+  label_sort_by: "%{value} gÃ¶re sÄ±rala"
+  label_send_test_email: Test e-postasÄ± gÃ¶nder
+  label_feeds_access_key_created_on: "RSS eriÅŸim anahtarÄ± %{value} Ã¶nce oluÅŸturuldu"
+  label_module_plural: ModÃ¼ller
+  label_added_time_by: "%{author} tarafÄ±ndan %{age} Ã¶nce eklendi"
+  label_updated_time: "%{value} Ã¶nce gÃ¼ncellendi"
+  label_jump_to_a_project: Projeye git...
+  label_file_plural: Dosyalar
+  label_changeset_plural: DeÄŸiÅŸiklik Listeleri
+  label_default_columns: VarsayÄ±lan SÃ¼tunlar
+  label_no_change_option: (DeÄŸiÅŸiklik yok)
+  label_bulk_edit_selected_issues: SeÃ§ili iÅŸleri toplu olarak dÃ¼zenle
+  label_theme: Tema
+  label_default: VarsayÄ±lan
+  label_search_titles_only: Sadece baÅŸlÄ±klarÄ± ara
+  label_user_mail_option_all: "TÃ¼m projelerimdeki herhangi bir olay iÃ§in"
+  label_user_mail_option_selected: "Sadece seÃ§ili projelerdeki herhangi bir olay iÃ§in"
+  label_user_mail_no_self_notified: "Kendi yaptÄ±ÄŸÄ±m deÄŸiÅŸikliklerden haberdar olmak istemiyorum"
+  label_registration_activation_by_email: e-posta ile hesap etkinleÅŸtirme
+  label_registration_manual_activation: Elle hesap etkinleÅŸtirme
+  label_registration_automatic_activation: Otomatik hesap etkinleÅŸtirme
+  label_display_per_page: "Sayfa baÅŸÄ±na: %{value}"
+  label_age: YaÅŸ
+  label_change_properties: Ã–zellikleri deÄŸiÅŸtir
+  label_general: Genel
+  label_more: Daha fazla
+  label_scm: KY
+  label_plugins: Eklentiler
+  label_ldap_authentication: LDAP Denetimi
+  label_downloads_abbr: D/L
+  label_optional_description: Ä°steÄŸe baÄŸlÄ± aÃ§Ä±klama
+  label_add_another_file: Bir dosya daha ekle
+  label_preferences: Tercihler
+  label_chronological_order: Tarih sÄ±rasÄ±na gÃ¶re
+  label_reverse_chronological_order: Ters tarih sÄ±rasÄ±na gÃ¶re
+  label_planning: PlanlanÄ±yor
+
+  button_login: GiriÅŸ
+  button_submit: GÃ¶nder
+  button_save: Kaydet
+  button_check_all: Hepsini iÅŸaretle
+  button_uncheck_all: TÃ¼m iÅŸaretleri kaldÄ±r
+  button_delete: Sil
+  button_create: OluÅŸtur
+  button_test: SÄ±na
+  button_edit: DÃ¼zenle
+  button_add: Ekle
+  button_change: DeÄŸiÅŸtir
+  button_apply: Uygula
+  button_clear: Temizle
+  button_lock: Kilitle
+  button_unlock: Kilidi aÃ§
+  button_download: Ä°ndir
+  button_list: Listele
+  button_view: Bak
+  button_move: TaÅŸÄ±
+  button_back: Geri
+  button_cancel: Ä°ptal
+  button_activate: EtkinleÅŸtir
+  button_sort: SÄ±rala
+  button_log_time: Zaman kaydÄ±
+  button_rollback: Bu sÃ¼rÃ¼me geri al
+  button_watch: Ä°zle
+  button_unwatch: Ä°zlemeyi iptal et
+  button_reply: Cevapla
+  button_archive: ArÅŸivle
+  button_unarchive: ArÅŸivlemeyi kaldÄ±r
+  button_reset: SÄ±fÄ±rla
+  button_rename: Yeniden adlandÄ±r
+  button_change_password: ParolayÄ± deÄŸiÅŸtir
+  button_copy: Kopyala
+  button_annotate: DeÄŸiÅŸiklik geÃ§miÅŸine gÃ¶re gÃ¶ster
+  button_update: GÃ¼ncelle
+  button_configure: YapÄ±landÄ±r
+
+  status_active: faal
+  status_registered: kayÄ±tlÄ±
+  status_locked: kilitli
+
+  text_select_mail_notifications: GÃ¶nderilecek e-posta uyarÄ±sÄ±na gÃ¶re hareketi seÃ§in.
+  text_regexp_info: Ã¶rn. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 sÄ±nÄ±rlama yok demektir
+  text_project_destroy_confirmation: Bu projeyi ve baÄŸlantÄ±lÄ± verileri silmek istediÄŸinizden emin misiniz?
+  text_subprojects_destroy_warning: "AyrÄ±ca %{value} alt proje silinecek."
+  text_workflow_edit: Ä°ÅŸakÄ±ÅŸÄ±nÄ± dÃ¼zenlemek iÃ§in bir rol ve iÅŸ tipi seÃ§in
+  text_are_you_sure: Emin misiniz ?
+  text_tip_issue_begin_day: BugÃ¼n baÅŸlayan gÃ¶revler
+  text_tip_issue_end_day: BugÃ¼n sona eren gÃ¶revler
+  text_tip_issue_begin_end_day: BugÃ¼n baÅŸlayan ve sona eren gÃ¶revler
+  text_caracters_maximum: "En Ã§ok %{count} karakter."
+  text_caracters_minimum: "En az %{count} karakter uzunluÄŸunda olmalÄ±."
+  text_length_between: "%{min} ve %{max} karakterleri arasÄ±ndaki uzunluk."
+  text_tracker_no_workflow: Bu iÅŸ tipi iÃ§in iÅŸakÄ±ÅŸÄ± tanÄ±mlanmamÄ±ÅŸ
+  text_unallowed_characters: YasaklÄ± karakterler
+  text_comma_separated: Ã‡oklu deÄŸer girilebilir(VirgÃ¼l ile ayrÄ±lmÄ±ÅŸ).
+  text_issues_ref_in_commit_messages: Teslim mesajlarÄ±ndaki iÅŸleri Ã§Ã¶zme ve baÅŸvuruda bulunma
+  text_issue_added: "Ä°ÅŸ %{id}, %{author} tarafÄ±ndan rapor edildi."
+  text_issue_updated: "Ä°ÅŸ %{id}, %{author} tarafÄ±ndan gÃ¼ncellendi."
+  text_wiki_destroy_confirmation: bu wikiyi ve tÃ¼m iÃ§eriÄŸini silmek istediÄŸinizden emin misiniz?
+  text_issue_category_destroy_question: "BazÄ± iÅŸler (%{count}) bu kategoriye atandÄ±. Ne yapmak istersiniz?"
+  text_issue_category_destroy_assignments: Kategori atamalarÄ±nÄ± kaldÄ±r
+  text_issue_category_reassign_to: Ä°ÅŸleri bu kategoriye tekrar ata
+  text_user_mail_option: "SeÃ§ili olmayan projeler iÃ§in, sadece dahil olduÄŸunuz ya da izlediÄŸiniz Ã¶ÄŸeler hakkÄ±nda uyarÄ±lar alacaksÄ±nÄ±z (Ã¶rneÄŸin,yazarÄ± veya atandÄ±ÄŸÄ±nÄ±z iÅŸler)."
+  text_no_configuration_data: "Roller, iÅŸ tipleri, iÅŸ durumlarÄ± ve iÅŸakÄ±ÅŸÄ± henÃ¼z yapÄ±landÄ±rÄ±lmadÄ±.\nVarsayÄ±lan yapÄ±landÄ±rÄ±lmanÄ±n yÃ¼klenmesi ÅŸiddetle tavsiye edilir. Bir kez yÃ¼klendiÄŸinde yapÄ±landÄ±rmayÄ± deÄŸiÅŸtirebileceksiniz."
+  text_load_default_configuration: VarsayÄ±lan yapÄ±landÄ±rmayÄ± yÃ¼kle
+  text_status_changed_by_changeset: "DeÄŸiÅŸiklik listesi %{value} iÃ§inde uygulandÄ±."
+  text_issues_destroy_confirmation: 'SeÃ§ili iÅŸleri silmek istediÄŸinizden emin misiniz ?'
+  text_select_project_modules: 'Bu proje iÃ§in etkinleÅŸtirmek istediÄŸiniz modÃ¼lleri seÃ§in:'
+  text_default_administrator_account_changed: VarsayÄ±lan yÃ¶netici hesabÄ± deÄŸiÅŸti
+  text_file_repository_writable: Dosya deposu yazÄ±labilir
+  text_rmagick_available: RMagick KullanÄ±labilir (isteÄŸe baÄŸlÄ±)
+  text_destroy_time_entries_question: Silmek Ã¼zere olduÄŸunuz iÅŸler Ã¼zerine %{hours} saat raporlandÄ±.Ne yapmak istersiniz ?
+  text_destroy_time_entries: RaporlanmÄ±ÅŸ sÃ¼releri sil
+  text_assign_time_entries_to_project: RaporlanmÄ±ÅŸ sÃ¼releri projeye ata
+  text_reassign_time_entries: 'RaporlanmÄ±ÅŸ sÃ¼releri bu iÅŸe tekrar ata:'
+
+  default_role_manager: YÃ¶netici
+  default_role_developer: GeliÅŸtirici
+  default_role_reporter: RaporlayÄ±cÄ±
+  default_tracker_bug: Hata
+  default_tracker_feature: Ã–zellik
+  default_tracker_support: Destek
+  default_issue_status_new: Yeni
+  default_issue_status_in_progress: YapÄ±lÄ±yor
+  default_issue_status_resolved: Ã‡Ã¶zÃ¼ldÃ¼
+  default_issue_status_feedback: Geribildirim
+  default_issue_status_closed: "KapatÄ±ldÄ±"
+  default_issue_status_rejected: Reddedildi
+  default_doc_category_user: KullanÄ±cÄ± DÃ¶kÃ¼mantasyonu
+  default_doc_category_tech: Teknik DÃ¶kÃ¼mantasyon
+  default_priority_low: DÃ¼ÅŸÃ¼k
+  default_priority_normal: Normal
+  default_priority_high: YÃ¼ksek
+  default_priority_urgent: Acil
+  default_priority_immediate: Derhal
+  default_activity_design: TasarÄ±m
+  default_activity_development: GeliÅŸtirme
+
+  enumeration_issue_priorities: Ä°ÅŸ Ã¶nceliÄŸi
+  enumeration_doc_categories: Belge Kategorileri
+  enumeration_activities: Faaliyetler (zaman takibi)
+  button_quote: AlÄ±ntÄ±
+  setting_enabled_scm: KKY AÃ§Ä±k
+  label_incoming_emails: "Gelen e-postalar"
+  label_generate_key: "Anahtar oluÅŸtur"
+  setting_sequential_project_identifiers: "SÄ±ralÄ± proje tanÄ±mlayÄ±cÄ±larÄ± oluÅŸtur"
+  field_parent_title: Ãœst sayfa
+  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
+  text_enumeration_category_reassign_to: 'Hepsini ÅŸuna Ã§evir:'
+  label_issue_watchers: TakipÃ§iler
+  mail_body_reminder: "Size atanmÄ±ÅŸ olan %{count} iÅŸ %{days} gÃ¼n iÃ§erisinde bitirilmeli:"
+  label_duplicated_by: yineleyen
+  text_enumeration_destroy_question: "Bu nesneye %{count} deÄŸer baÄŸlanmÄ±ÅŸ."
+  text_user_wrote: "%{value} demiÅŸ ki:"
+  setting_mail_handler_api_enabled: Gelen e-postalar iÃ§in WS'yi aÃ§
+  label_and_its_subprojects: "%{value} ve alt projeleri"
+  mail_subject_reminder: "%{count} iÅŸ bir kaÃ§ gÃ¼ne bitecek"
+  setting_mail_handler_api_key: API anahtarÄ±
+  setting_commit_logs_encoding: GÃ¶nderim mesajlarÄ±nÄ±n kodlamasÄ± (UTF-8 vs.)
+  general_csv_decimal_separator: '.'
+  notice_unable_delete_version: SÃ¼rÃ¼m silinemiyor
+  label_renamed: yeniden adlandÄ±rÄ±lmÄ±ÅŸ
+  label_copied: kopyalanmÄ±ÅŸ
+  setting_plain_text_mail: sadece dÃ¼z metin (HTML yok)
+  permission_view_files: DosyalarÄ± gÃ¶rme
+  permission_edit_issues: Ä°ÅŸleri dÃ¼zenleme
+  permission_edit_own_time_entries: Kendi zaman giriÅŸlerini dÃ¼zenleme
+  permission_manage_public_queries: Herkese aÃ§Ä±k sorgularÄ± yÃ¶netme
+  permission_add_issues: Ä°ÅŸ ekleme
+  permission_log_time: Harcanan zamanÄ± kaydetme
+  permission_view_changesets: DeÄŸiÅŸimleri gÃ¶rme(SVN, vs.)
+  permission_view_time_entries: Harcanan zamanÄ± gÃ¶rme
+  permission_manage_versions: SÃ¼rÃ¼mleri yÃ¶netme
+  permission_manage_wiki: Wiki'yi yÃ¶netme
+  permission_manage_categories: Ä°ÅŸ kategorilerini yÃ¶netme
+  permission_protect_wiki_pages: Wiki sayfalarÄ±nÄ± korumaya alma
+  permission_comment_news: Haberlere yorum yapma
+  permission_delete_messages: Mesaj silme
+  permission_select_project_modules: Proje modÃ¼llerini seÃ§me
+  permission_edit_wiki_pages: Wiki sayfalarÄ±nÄ± dÃ¼zenleme
+  permission_add_issue_watchers: TakipÃ§i ekleme
+  permission_view_gantt: Ä°ÅŸ-Zaman Ã§izelgesi gÃ¶rme
+  permission_move_issues: Ä°ÅŸlerin yerini deÄŸiÅŸtirme
+  permission_manage_issue_relations: Ä°ÅŸlerin biribiriyle baÄŸlantÄ±larÄ±nÄ± yÃ¶netme
+  permission_delete_wiki_pages: Wiki sayfalarÄ±nÄ± silme
+  permission_manage_boards: PanolarÄ± yÃ¶netme
+  permission_delete_wiki_pages_attachments: Ekleri silme
+  permission_view_wiki_edits: Wiki geÃ§miÅŸini gÃ¶rme
+  permission_add_messages: Mesaj gÃ¶nderme
+  permission_view_messages: MesajlarÄ± gÃ¶rme
+  permission_manage_files: DosyalarÄ± yÃ¶netme
+  permission_edit_issue_notes: NotlarÄ± dÃ¼zenleme
+  permission_manage_news: Haberleri yÃ¶netme
+  permission_view_calendar: Takvimleri gÃ¶rme
+  permission_manage_members: Ãœyeleri yÃ¶netme
+  permission_edit_messages: MesajlarÄ± dÃ¼zenleme
+  permission_delete_issues: Ä°ÅŸleri silme
+  permission_view_issue_watchers: TakipÃ§i listesini gÃ¶rme
+  permission_manage_repository: Depo yÃ¶netimi
+  permission_commit_access: GÃ¶nderme eriÅŸimi
+  permission_browse_repository: Depoya gÃ¶zatma
+  permission_view_documents: Belgeleri gÃ¶rme
+  permission_edit_project: Projeyi dÃ¼zenleme
+  permission_add_issue_notes: Not ekleme
+  permission_save_queries: Sorgu kaydetme
+  permission_view_wiki_pages: Wiki gÃ¶rme
+  permission_rename_wiki_pages: Wiki sayfasÄ±nÄ±n adÄ±nÄ± deÄŸiÅŸtirme
+  permission_edit_time_entries: Zaman kayÄ±tlarÄ±nÄ± dÃ¼zenleme
+  permission_edit_own_issue_notes: Kendi notlarÄ±nÄ± dÃ¼zenleme
+  setting_gravatar_enabled: KullanÄ±cÄ± resimleri iÃ§in Gravatar kullan
+  label_example: Ã–rnek
+  text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  permission_edit_own_messages: Kendi mesajlarÄ±nÄ± dÃ¼zenleme
+  permission_delete_own_messages: Kendi mesajlarÄ±nÄ± silme
+  label_user_activity: "%{value} kullanÄ±cÄ±sÄ±nÄ±n etkinlikleri"
+  label_updated_time_by: "%{author} tarafÄ±ndan %{age} Ã¶nce gÃ¼ncellendi"
+  text_diff_truncated: '... Bu fark tam olarak gÃ¶sterilemiyor Ã§Ã¼nkÃ¼ gÃ¶sterim iÃ§in ayarlanmÄ±ÅŸ Ã¼st sÄ±nÄ±rÄ± aÅŸÄ±yor.'
+  setting_diff_max_lines_displayed: GÃ¶sterilebilecek maksimumu fark satÄ±rÄ±
+  text_plugin_assets_writable: Eklenti yardÄ±mcÄ± dosya dizini yazÄ±labilir
+  warning_attachments_not_saved: "%{count} adet dosya kaydedilemedi."
+  button_create_and_continue: OluÅŸtur ve devam et
+  text_custom_field_possible_values_info: 'Her deÄŸer iÃ§in bir satÄ±r'
+  label_display: GÃ¶ster
+  field_editable: DÃ¼zenlenebilir
+  setting_repository_log_display_limit: Dosya kaydÄ±nda gÃ¶sterilecek maksimum deÄŸiÅŸim sayÄ±sÄ±
+  setting_file_max_size_displayed: Dahili olarak gÃ¶sterilecek metin dosyalarÄ± iÃ§in maksimum satÄ±r sayÄ±sÄ±
+  field_watcher: TakipÃ§i
+  setting_openid: KayÄ±t ve giriÅŸ iÃ§in OpenID'ye izin ver
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: veya OpenID kullanÄ±n
+  field_content: Ä°Ã§erik
+  label_descending: Azalan
+  label_sort: SÄ±rala
+  label_ascending: Artan
+  label_date_from_to: "%{start} - %{end} arasÄ±"
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Bu sayfanÄ±n %{descendants} adet alt sayfasÄ± var. Ne yapmak istersiniz?
+  text_wiki_page_reassign_children: Alt sayfalarÄ± bu sayfanÄ±n altÄ±na baÄŸla
+  text_wiki_page_nullify_children: Alt sayfalarÄ± ana sayfa olarak sakla
+  text_wiki_page_destroy_children: Alt sayfalarÄ± ve onlarÄ±n alt sayfalarÄ±nÄ± tamamen sil
+  setting_password_min_length: Minimum parola uzunluÄŸu
+  field_group_by: SonuÃ§larÄ± grupla
+  mail_subject_wiki_content_updated: "'%{id}' wiki sayfasÄ± gÃ¼ncellendi"
+  label_wiki_content_added: Wiki sayfasÄ± eklendi
+  mail_subject_wiki_content_added: "'%{id}' wiki sayfasÄ± eklendi"
+  mail_body_wiki_content_added: "'%{id}' wiki sayfasÄ±, %{author} tarafÄ±ndan eklendi."
+  label_wiki_content_updated: Wiki sayfasÄ± gÃ¼ncellendi
+  mail_body_wiki_content_updated: "'%{id}' wiki sayfasÄ±, %{author} tarafÄ±ndan gÃ¼ncellendi."
+  permission_add_project: Proje oluÅŸtur
+  setting_new_project_user_role_id: YÃ¶netici olmayan ancak proje yaratabilen kullanÄ±cÄ±ya verilen rol
+  label_view_all_revisions: TÃ¼m deÄŸiÅŸiklikleri gÃ¶r
+  label_tag: Etiket
+  label_branch: Kol
+  error_no_tracker_in_project: Bu projeye baÄŸlanmÄ±ÅŸ bir iÅŸ tipi yok. LÃ¼tfen proje ayarlarÄ±nÄ± kontrol edin.
+  error_no_default_issue_status: VarsayÄ±lan iÅŸ durumu tanÄ±mlanmamÄ±ÅŸ. LÃ¼tfen ayarlarÄ±nÄ±zÄ± kontrol edin ("YÃ¶netim -> Ä°ÅŸ durumlarÄ±" sayfasÄ±na gidin).
+  label_group_plural: Gruplar
+  label_group: Grup
+  label_group_new: Yeni grup
+  label_time_entry_plural: Harcanan zaman
+  text_journal_changed: "%{label}: %{old} -> %{new}"
+  text_journal_set_to: "%{label} %{value} yapÄ±ldÄ±"
+  text_journal_deleted: "%{label} silindi (%{old})"
+  text_journal_added: "%{label} %{value} eklendi"
+  field_active: Etkin
+  enumeration_system_activity: Sistem Etkinlikleri
+  permission_delete_issue_watchers: Ä°zleyicileri sil
+  version_status_closed: kapalÄ±
+  version_status_locked: kilitli
+  version_status_open: aÃ§Ä±k
+  error_can_not_reopen_issue_on_closed_version: KapatÄ±lmÄ±ÅŸ bir sÃ¼rÃ¼me ait iÅŸler tekrar aÃ§Ä±lamaz
+  label_user_anonymous: Anonim
+  button_move_and_follow: Yerini deÄŸiÅŸtir ve takip et
+  setting_default_projects_modules: Yeni projeler iÃ§in varsayÄ±lan modÃ¼ller
+  setting_gravatar_default: VarsayÄ±lan Gravatar resmi
+  field_sharing: PaylaÅŸÄ±m
+  label_version_sharing_hierarchy: Proje hiyerarÅŸisi ile
+  label_version_sharing_system: TÃ¼m projeler ile
+  label_version_sharing_descendants: Alt projeler ile
+  label_version_sharing_tree: Proje aÄŸacÄ± ile
+  label_version_sharing_none: PaylaÅŸÄ±lmamÄ±ÅŸ
+  error_can_not_archive_project: Bu proje arÅŸivlenemez
+  button_duplicate: Yinele
+  button_copy_and_follow: Kopyala ve takip et
+  label_copy_source: Kaynak
+  setting_issue_done_ratio: Ä°ÅŸ tamamlanma oranÄ±nÄ± ÅŸununla hesapla
+  setting_issue_done_ratio_issue_status: Ä°ÅŸ durumunu kullan
+  error_issue_done_ratios_not_updated: Ä°ÅŸ tamamlanma oranlarÄ± gÃ¼ncellenmedi.
+  error_workflow_copy_target: LÃ¼tfen hedef iÅŸ tipi ve rolleri seÃ§in
+  setting_issue_done_ratio_issue_field: Ä°ÅŸteki alanÄ± kullan
+  label_copy_same_as_target: Hedef ile aynÄ±
+  label_copy_target: Hedef
+  notice_issue_done_ratios_updated: Ä°ÅŸ tamamlanma oranlarÄ± gÃ¼ncellendi.
+  error_workflow_copy_source: LÃ¼tfen kaynak iÅŸ tipi ve rolleri seÃ§in
+  label_update_issue_done_ratios: Ä°ÅŸ tamamlanma oranlarÄ±nÄ± gÃ¼ncelle
+  setting_start_of_week: Takvimleri ÅŸundan baÅŸlat
+  permission_view_issues: Ä°ÅŸleri GÃ¶r
+  label_display_used_statuses_only: Sadece bu iÅŸ tipi tarafÄ±ndan kullanÄ±lan durumlarÄ± gÃ¶ster
+  label_revision_id: DeÄŸiÅŸiklik %{value}
+  label_api_access_key: API eriÅŸim anahtarÄ±
+  label_api_access_key_created_on: API eriÅŸim anahtarÄ± %{value} Ã¶nce oluÅŸturuldu
+  label_feeds_access_key: RSS eriÅŸim anahtarÄ±
+  notice_api_access_key_reseted: API eriÅŸim anahtarÄ±nÄ±z sÄ±fÄ±rlandÄ±.
+  setting_rest_api_enabled: REST web servisini etkinleÅŸtir
+  label_missing_api_access_key: Bir API eriÅŸim anahtarÄ± eksik
+  label_missing_feeds_access_key: Bir RSS eriÅŸim anahtarÄ± eksik
+  button_show: GÃ¶ster
+  text_line_separated: Ã‡oklu deÄŸer girilebilir (her satÄ±ra bir deÄŸer).
+  setting_mail_handler_body_delimiters: Åžu satÄ±rlarÄ±n birinden sonra e-postayÄ± sonlandÄ±r
+  permission_add_subprojects: Alt proje yaratma
+  label_subproject_new: Yeni alt proje
+  text_own_membership_delete_confirmation: "Projeyi daha sonra dÃ¼zenleyememenize sebep olacak bazÄ± yetkilerinizi kaldÄ±rmak Ã¼zeresiniz.\nDevam etmek istediÄŸinize emin misiniz?"
+  label_close_versions: TamamlanmÄ±ÅŸ sÃ¼rÃ¼mleri kapat
+  label_board_sticky: YapÄ±ÅŸkan
+  label_board_locked: Kilitli
+  permission_export_wiki_pages: Wiki sayfalarÄ±nÄ± dÄ±ÅŸarÄ± aktar
+  setting_cache_formatted_text: BiÃ§imlendirilmiÅŸ metni Ã¶nbelleÄŸe al
+  permission_manage_project_activities: Proje etkinliklerini yÃ¶netme
+  error_unable_delete_issue_status: Ä°ÅŸ durumu silinemiyor
+  label_profile: Profil
+  permission_manage_subtasks: Alt iÅŸleri yÃ¶netme
+  field_parent_issue: Ãœst iÅŸ
+  label_subtask_plural: Alt iÅŸler
+  label_project_copy_notifications: Proje kopyalamasÄ± esnasÄ±nda bilgilendirme e-postalarÄ± gÃ¶nder
+  error_can_not_delete_custom_field: Ã–zel alan silinemiyor
+  error_unable_to_connect: BaÄŸlanÄ±lamÄ±yor (%{value})
+  error_can_not_remove_role: Bu rol kullanÄ±mda olduÄŸundan silinemez.
+  error_can_not_delete_tracker: Bu iÅŸ tipi iÃ§erisinde iÅŸ barÄ±ndÄ±rdÄ±ÄŸÄ±ndan silinemiyor.
+  field_principal: Temel
+  label_my_page_block: KiÅŸisel sayfa bloÄŸum
+  notice_failed_to_save_members: "Ãœyeler kaydedilemiyor: %{errors}."
+  text_zoom_out: UzaklaÅŸ
+  text_zoom_in: YakÄ±nlaÅŸ
+  notice_unable_delete_time_entry: Zaman kayÄ±t girdisi silinemiyor.
+  label_overall_spent_time: Toplam harcanan zaman
+  field_time_entries: Zaman KayÄ±tlarÄ±
+  project_module_gantt: Ä°ÅŸ-Zaman Ã‡izelgesi
+  project_module_calendar: Takvim
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Metin alanÄ±
+  label_user_mail_option_only_owner: Sadece sahibi olduÄŸum ÅŸeyler iÃ§in
+  setting_default_notification_option: VarsayÄ±lan bildirim seÃ§eneÄŸi
+  label_user_mail_option_only_my_events: Sadece takip ettiÄŸim ya da iÃ§inde olduÄŸum ÅŸeyler iÃ§in
+  label_user_mail_option_only_assigned: Sadece bana atanan ÅŸeyler iÃ§in
+  label_user_mail_option_none: HiÃ§ bir ÅŸey iÃ§in
+  field_member_of_group: AtananÄ±n grubu
+  field_assigned_to_role: AtananÄ±n rolÃ¼
+  notice_not_authorized_archived_project: EriÅŸmeye Ã§alÄ±ÅŸtÄ±ÄŸÄ±nÄ±z proje arÅŸive kaldÄ±rÄ±lmÄ±ÅŸ.
+  label_principal_search: "KullanÄ±cÄ± ya da grup ara:"
+  label_user_search: "KullanÄ±cÄ± ara:"
+  field_visible: GÃ¶rÃ¼nÃ¼r
+  setting_emails_header: "E-Posta baÅŸlÄ±ÄŸÄ±"
+  setting_commit_logtime_activity_id: Kaydedilen zaman iÃ§in etkinlik
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Zaman kaydÄ±nÄ± etkinleÅŸtir
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Ä°ÅŸ-Zaman Ã§izelgesinde gÃ¶sterilecek en fazla Ã¶ÄŸe sayÄ±sÄ±
+  field_warn_on_leaving_unsaved: KaydedilmemiÅŸ metin bulunan bir sayfadan Ã§Ä±karken beni uyar
+  text_warn_on_leaving_unsaved: Bu sayfada terkettiÄŸiniz takdirde kaybolacak kaydedilmemiÅŸ metinler var.
+  label_my_queries: Ã–zel sorgularÄ±m
+  text_journal_changed_no_detail: "%{label} gÃ¼ncellendi"
+  label_news_comment_added: Bir habere yorum eklendi
+  button_expand_all: TÃ¼mÃ¼nÃ¼ geniÅŸlet
+  button_collapse_all: TÃ¼mÃ¼nÃ¼ daralt
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: SeÃ§ilen zaman kayÄ±tlarÄ±nÄ± toplu olarak dÃ¼zenle
+  text_time_entries_destroy_confirmation: SeÃ§ilen zaman kaydÄ±nÄ±/kayÄ±tlarÄ±nÄ± silmek istediÄŸinize emin misiniz?
+  label_role_anonymous: Anonim
+  label_role_non_member: Ãœye DeÄŸil
+  label_issue_note_added: Not eklendi
+  label_issue_status_updated: Durum gÃ¼ncellendi
+  label_issue_priority_updated: Ã–ncelik gÃ¼ncellendi
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Ä°ÅŸlerin gÃ¶rÃ¼nÃ¼rlÃ¼ÄŸÃ¼
+  label_issues_visibility_all: TÃ¼m iÅŸler
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Ã–zel
+  permission_set_issues_private: Ä°ÅŸleri Ã¶zel ya da genel olarak iÅŸaretleme
+  label_issues_visibility_public: Ã–zel olmayan tÃ¼m iÅŸler
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Commit messages encoding
+  field_scm_path_encoding: Yol kodlamasÄ±(encoding)
+  text_scm_path_encoding_note: "VarsayÄ±lan: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Ana dizin
+  field_cvs_module: ModÃ¼l
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Komut
+  text_scm_command_version: SÃ¼rÃ¼m
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 Ä°ÅŸ
+    one:   1 Ä°ÅŸ
+    other: "%{count} Ä°ÅŸler"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: Hepsi
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Alt projeler ile
+  label_cross_project_tree: Proje aÄŸacÄ± ile
+  label_cross_project_hierarchy: Proje hiyerarÅŸisi ile
+  label_cross_project_system: TÃ¼m projeler ile
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Toplam
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7c/7c8477332553f0c9a3e3cf4a6ba241f56066f91e.svn-base
--- /dev/null
+++ b/.svn/pristine/7c/7c8477332553f0c9a3e3cf4a6ba241f56066f91e.svn-base
@@ -0,0 +1,323 @@
+# Redmine - project management software
+# Copyright (C) 2006  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Setup < ActiveRecord::Migration
+
+  class User < ActiveRecord::Base; end
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    create_table "attachments", :force => true do |t|
+      t.column "container_id", :integer, :default => 0, :null => false
+      t.column "container_type", :string, :limit => 30, :default => "", :null => false
+      t.column "filename", :string, :default => "", :null => false
+      t.column "disk_filename", :string, :default => "", :null => false
+      t.column "filesize", :integer, :default => 0, :null => false
+      t.column "content_type", :string, :limit => 60, :default => ""
+      t.column "digest", :string, :limit => 40, :default => "", :null => false
+      t.column "downloads", :integer, :default => 0, :null => false
+      t.column "author_id", :integer, :default => 0, :null => false
+      t.column "created_on", :timestamp
+    end
+
+    create_table "auth_sources", :force => true do |t|
+      t.column "type", :string, :limit => 30, :default => "", :null => false
+      t.column "name", :string, :limit => 60, :default => "", :null => false
+      t.column "host", :string, :limit => 60
+      t.column "port", :integer
+      t.column "account", :string, :limit => 60
+      t.column "account_password", :string, :limit => 60
+      t.column "base_dn", :string, :limit => 255
+      t.column "attr_login", :string, :limit => 30
+      t.column "attr_firstname", :string, :limit => 30
+      t.column "attr_lastname", :string, :limit => 30
+      t.column "attr_mail", :string, :limit => 30
+      t.column "onthefly_register", :boolean, :default => false, :null => false
+    end
+
+    create_table "custom_fields", :force => true do |t|
+      t.column "type", :string, :limit => 30, :default => "", :null => false
+      t.column "name", :string, :limit => 30, :default => "", :null => false
+      t.column "field_format", :string, :limit => 30, :default => "", :null => false
+      t.column "possible_values", :text
+      t.column "regexp", :string, :default => ""
+      t.column "min_length", :integer, :default => 0, :null => false
+      t.column "max_length", :integer, :default => 0, :null => false
+      t.column "is_required", :boolean, :default => false, :null => false
+      t.column "is_for_all", :boolean, :default => false, :null => false
+    end
+
+    create_table "custom_fields_projects", :id => false, :force => true do |t|
+      t.column "custom_field_id", :integer, :default => 0, :null => false
+      t.column "project_id", :integer, :default => 0, :null => false
+    end
+
+    create_table "custom_fields_trackers", :id => false, :force => true do |t|
+      t.column "custom_field_id", :integer, :default => 0, :null => false
+      t.column "tracker_id", :integer, :default => 0, :null => false
+    end
+
+    create_table "custom_values", :force => true do |t|
+      t.column "customized_type", :string, :limit => 30, :default => "", :null => false
+      t.column "customized_id", :integer, :default => 0, :null => false
+      t.column "custom_field_id", :integer, :default => 0, :null => false
+      t.column "value", :text
+    end
+
+    create_table "documents", :force => true do |t|
+      t.column "project_id", :integer, :default => 0, :null => false
+      t.column "category_id", :integer, :default => 0, :null => false
+      t.column "title", :string, :limit => 60, :default => "", :null => false
+      t.column "description", :text
+      t.column "created_on", :timestamp
+    end
+
+    add_index "documents", ["project_id"], :name => "documents_project_id"
+
+    create_table "enumerations", :force => true do |t|
+      t.column "opt", :string, :limit => 4, :default => "", :null => false
+      t.column "name", :string, :limit => 30, :default => "", :null => false
+    end
+
+    create_table "issue_categories", :force => true do |t|
+      t.column "project_id", :integer, :default => 0, :null => false
+      t.column "name", :string, :limit => 30, :default => "", :null => false
+    end
+
+    add_index "issue_categories", ["project_id"], :name => "issue_categories_project_id"
+
+    create_table "issue_histories", :force => true do |t|
+      t.column "issue_id", :integer, :default => 0, :null => false
+      t.column "status_id", :integer, :default => 0, :null => false
+      t.column "author_id", :integer, :default => 0, :null => false
+      t.column "notes", :text
+      t.column "created_on", :timestamp
+    end
+
+    add_index "issue_histories", ["issue_id"], :name => "issue_histories_issue_id"
+
+    create_table "issue_statuses", :force => true do |t|
+      t.column "name", :string, :limit => 30, :default => "", :null => false
+      t.column "is_closed", :boolean, :default => false, :null => false
+      t.column "is_default", :boolean, :default => false, :null => false
+      t.column "html_color", :string, :limit => 6, :default => "FFFFFF", :null => false
+    end
+
+    create_table "issues", :force => true do |t|
+      t.column "tracker_id", :integer, :default => 0, :null => false
+      t.column "project_id", :integer, :default => 0, :null => false
+      t.column "subject", :string, :default => "", :null => false
+      t.column "description", :text
+      t.column "due_date", :date
+      t.column "category_id", :integer
+      t.column "status_id", :integer, :default => 0, :null => false
+      t.column "assigned_to_id", :integer
+      t.column "priority_id", :integer, :default => 0, :null => false
+      t.column "fixed_version_id", :integer
+      t.column "author_id", :integer, :default => 0, :null => false
+      t.column "lock_version", :integer, :default => 0, :null => false
+      t.column "created_on", :timestamp
+      t.column "updated_on", :timestamp
+    end
+
+    add_index "issues", ["project_id"], :name => "issues_project_id"
+
+    create_table "members", :force => true do |t|
+      t.column "user_id", :integer, :default => 0, :null => false
+      t.column "project_id", :integer, :default => 0, :null => false
+      t.column "role_id", :integer, :default => 0, :null => false
+      t.column "created_on", :timestamp
+    end
+
+    create_table "news", :force => true do |t|
+      t.column "project_id", :integer
+      t.column "title", :string, :limit => 60, :default => "", :null => false
+      t.column "summary", :string, :limit => 255, :default => ""
+      t.column "description", :text
+      t.column "author_id", :integer, :default => 0, :null => false
+      t.column "created_on", :timestamp
+    end
+
+    add_index "news", ["project_id"], :name => "news_project_id"
+
+    create_table "permissions", :force => true do |t|
+      t.column "controller", :string, :limit => 30, :default => "", :null => false
+      t.column "action", :string, :limit => 30, :default => "", :null => false
+      t.column "description", :string, :limit => 60, :default => "", :null => false
+      t.column "is_public", :boolean, :default => false, :null => false
+      t.column "sort", :integer, :default => 0, :null => false
+      t.column "mail_option", :boolean, :default => false, :null => false
+      t.column "mail_enabled", :boolean, :default => false, :null => false
+    end
+
+    create_table "permissions_roles", :id => false, :force => true do |t|
+      t.column "permission_id", :integer, :default => 0, :null => false
+      t.column "role_id", :integer, :default => 0, :null => false
+    end
+
+    add_index "permissions_roles", ["role_id"], :name => "permissions_roles_role_id"
+
+    create_table "projects", :force => true do |t|
+      t.column "name", :string, :limit => 30, :default => "", :null => false
+      t.column "description", :string, :default => "", :null => false
+      t.column "homepage", :string, :limit => 60, :default => ""
+      t.column "is_public", :boolean, :default => true, :null => false
+      t.column "parent_id", :integer
+      t.column "projects_count", :integer, :default => 0
+      t.column "created_on", :timestamp
+      t.column "updated_on", :timestamp
+    end
+
+    create_table "roles", :force => true do |t|
+      t.column "name", :string, :limit => 30, :default => "", :null => false
+    end
+
+    create_table "tokens", :force => true do |t|
+      t.column "user_id", :integer, :default => 0, :null => false
+      t.column "action", :string, :limit => 30, :default => "", :null => false
+      t.column "value", :string, :limit => 40, :default => "", :null => false
+      t.column "created_on", :datetime, :null => false
+    end
+
+    create_table "trackers", :force => true do |t|
+      t.column "name", :string, :limit => 30, :default => "", :null => false
+      t.column "is_in_chlog", :boolean, :default => false, :null => false
+    end
+
+    create_table "users", :force => true do |t|
+      t.column "login", :string, :limit => 30, :default => "", :null => false
+      t.column "hashed_password", :string, :limit => 40, :default => "", :null => false
+      t.column "firstname", :string, :limit => 30, :default => "", :null => false
+      t.column "lastname", :string, :limit => 30, :default => "", :null => false
+      t.column "mail", :string, :limit => 60, :default => "", :null => false
+      t.column "mail_notification", :boolean, :default => true, :null => false
+      t.column "admin", :boolean, :default => false, :null => false
+      t.column "status", :integer, :default => 1, :null => false
+      t.column "last_login_on", :datetime
+      t.column "language", :string, :limit => 2, :default => ""
+      t.column "auth_source_id", :integer
+      t.column "created_on", :timestamp
+      t.column "updated_on", :timestamp
+    end
+
+    create_table "versions", :force => true do |t|
+      t.column "project_id", :integer, :default => 0, :null => false
+      t.column "name", :string, :limit => 30, :default => "", :null => false
+      t.column "description", :string, :default => ""
+      t.column "effective_date", :date
+      t.column "created_on", :timestamp
+      t.column "updated_on", :timestamp
+    end
+
+    add_index "versions", ["project_id"], :name => "versions_project_id"
+
+    create_table "workflows", :force => true do |t|
+      t.column "tracker_id", :integer, :default => 0, :null => false
+      t.column "old_status_id", :integer, :default => 0, :null => false
+      t.column "new_status_id", :integer, :default => 0, :null => false
+      t.column "role_id", :integer, :default => 0, :null => false
+    end
+
+    # project
+    Permission.create :controller => "projects", :action => "show", :description => "label_overview", :sort => 100, :is_public => true
+    Permission.create :controller => "projects", :action => "changelog", :description => "label_change_log", :sort => 105, :is_public => true
+    Permission.create :controller => "reports", :action => "issue_report", :description => "label_report_plural", :sort => 110, :is_public => true
+    Permission.create :controller => "projects", :action => "settings", :description => "label_settings", :sort => 150
+    Permission.create :controller => "projects", :action => "edit", :description => "button_edit", :sort => 151
+    # members
+    Permission.create :controller => "projects", :action => "list_members", :description => "button_list", :sort => 200, :is_public => true
+    Permission.create :controller => "projects", :action => "add_member", :description => "button_add", :sort => 220
+    Permission.create :controller => "members", :action => "edit", :description => "button_edit", :sort => 221
+    Permission.create :controller => "members", :action => "destroy", :description => "button_delete", :sort => 222
+    # versions
+    Permission.create :controller => "projects", :action => "add_version", :description => "button_add", :sort => 320
+    Permission.create :controller => "versions", :action => "edit", :description => "button_edit", :sort => 321
+    Permission.create :controller => "versions", :action => "destroy", :description => "button_delete", :sort => 322
+    # issue categories
+    Permission.create :controller => "projects", :action => "add_issue_category", :description => "button_add", :sort => 420
+    Permission.create :controller => "issue_categories", :action => "edit", :description => "button_edit", :sort => 421
+    Permission.create :controller => "issue_categories", :action => "destroy", :description => "button_delete", :sort => 422
+    # issues
+    Permission.create :controller => "projects", :action => "list_issues", :description => "button_list", :sort => 1000, :is_public => true
+    Permission.create :controller => "projects", :action => "export_issues_csv", :description => "label_export_csv", :sort => 1001, :is_public => true
+    Permission.create :controller => "issues", :action => "show", :description => "button_view", :sort => 1005, :is_public => true
+    Permission.create :controller => "issues", :action => "download", :description => "button_download", :sort => 1010, :is_public => true
+    Permission.create :controller => "projects", :action => "add_issue", :description => "button_add", :sort => 1050, :mail_option => 1, :mail_enabled => 1
+    Permission.create :controller => "issues", :action => "edit", :description => "button_edit", :sort => 1055
+    Permission.create :controller => "issues", :action => "change_status", :description => "label_change_status", :sort => 1060, :mail_option => 1, :mail_enabled => 1
+    Permission.create :controller => "issues", :action => "destroy", :description => "button_delete", :sort => 1065
+    Permission.create :controller => "issues", :action => "add_attachment", :description => "label_attachment_new", :sort => 1070
+    Permission.create :controller => "issues", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1075
+    # news
+    Permission.create :controller => "projects", :action => "list_news", :description => "button_list", :sort => 1100, :is_public => true
+    Permission.create :controller => "news", :action => "show", :description => "button_view", :sort => 1101, :is_public => true
+    Permission.create :controller => "projects", :action => "add_news", :description => "button_add", :sort => 1120
+    Permission.create :controller => "news", :action => "edit", :description => "button_edit", :sort => 1121
+    Permission.create :controller => "news", :action => "destroy", :description => "button_delete", :sort => 1122
+    # documents
+    Permission.create :controller => "projects", :action => "list_documents", :description => "button_list", :sort => 1200, :is_public => true
+    Permission.create :controller => "documents", :action => "show", :description => "button_view", :sort => 1201, :is_public => true
+    Permission.create :controller => "documents", :action => "download", :description => "button_download", :sort => 1202, :is_public => true
+    Permission.create :controller => "projects", :action => "add_document", :description => "button_add", :sort => 1220
+    Permission.create :controller => "documents", :action => "edit", :description => "button_edit", :sort => 1221
+    Permission.create :controller => "documents", :action => "destroy", :description => "button_delete", :sort => 1222
+    Permission.create :controller => "documents", :action => "add_attachment", :description => "label_attachment_new", :sort => 1223
+    Permission.create :controller => "documents", :action => "destroy_attachment", :description => "label_attachment_delete", :sort => 1224
+    # files
+    Permission.create :controller => "projects", :action => "list_files", :description => "button_list", :sort => 1300, :is_public => true
+    Permission.create :controller => "versions", :action => "download", :description => "button_download", :sort => 1301, :is_public => true
+    Permission.create :controller => "projects", :action => "add_file", :description => "button_add", :sort => 1320
+    Permission.create :controller => "versions", :action => "destroy_file", :description => "button_delete", :sort => 1322
+
+    # create default administrator account
+    user = User.create :login => "admin",
+                       :hashed_password => "d033e22ae348aeb5660fc2140aec35850c4da997",
+                       :admin => true,
+                       :firstname => "Redmine",
+                       :lastname => "Admin",
+                       :mail => "admin@example.net",
+                       :mail_notification => true,
+                       :status => 1
+  end
+
+  def self.down
+    drop_table :attachments
+    drop_table :auth_sources
+    drop_table :custom_fields
+    drop_table :custom_fields_projects
+    drop_table :custom_fields_trackers
+    drop_table :custom_values
+    drop_table :documents
+    drop_table :enumerations
+    drop_table :issue_categories
+    drop_table :issue_histories
+    drop_table :issue_statuses
+    drop_table :issues
+    drop_table :members
+    drop_table :news
+    drop_table :permissions
+    drop_table :permissions_roles
+    drop_table :projects
+    drop_table :roles
+    drop_table :trackers
+    drop_table :tokens
+    drop_table :users
+    drop_table :versions
+    drop_table :workflows
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7c/7c8eae02c98b193159d580b9779b53a3e1041ed2.svn-base
--- a/.svn/pristine/7c/7c8eae02c98b193159d580b9779b53a3e1041ed2.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="admin-menu">
-  <ul>
-    <%= render_menu :admin_menu %>
-  </ul>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7c/7ca8a329852a4cbc7fbc376618c93059ca39014d.svn-base
--- /dev/null
+++ b/.svn/pristine/7c/7ca8a329852a4cbc7fbc376618c93059ca39014d.svn-base
@@ -0,0 +1,3 @@
+# English strings go here for Rails i18n
+en:
+  # my_label: "My label"
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7d/7d062943a639ef0006481fe9e87f6780c25c226e.svn-base
--- /dev/null
+++ b/.svn/pristine/7d/7d062943a639ef0006481fe9e87f6780c25c226e.svn-base
@@ -0,0 +1,66 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingMessagesTest < ActionController::IntegrationTest
+  def test_messages
+    assert_routing(
+        { :method => 'get', :path => "/boards/22/topics/2" },
+        { :controller => 'messages', :action => 'show', :id => '2',
+          :board_id => '22' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/boards/lala/topics/new" },
+        { :controller => 'messages', :action => 'new', :board_id => 'lala' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/boards/lala/topics/22/edit" },
+        { :controller => 'messages', :action => 'edit', :id => '22',
+          :board_id => 'lala' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/boards/lala/topics/quote/22" },
+        { :controller => 'messages', :action => 'quote', :id => '22',
+          :board_id => 'lala' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/boards/lala/topics/new" },
+        { :controller => 'messages', :action => 'new', :board_id => 'lala' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/boards/lala/topics/preview" },
+        { :controller => 'messages', :action => 'preview',
+          :board_id => 'lala' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/boards/lala/topics/22/edit" },
+        { :controller => 'messages', :action => 'edit', :id => '22',
+          :board_id => 'lala' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/boards/22/topics/555/replies" },
+        { :controller => 'messages', :action => 'reply', :id => '555',
+          :board_id => '22' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/boards/22/topics/555/destroy" },
+        { :controller => 'messages', :action => 'destroy', :id => '555',
+          :board_id => '22' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7d/7d0c82a8b17bf23c8cab9114300db25398956dda.svn-base
--- a/.svn/pristine/7d/7d0c82a8b17bf23c8cab9114300db25398956dda.svn-base
+++ /dev/null
@@ -1,70 +0,0 @@
-@import url(../../../stylesheets/application.css);
-
-body, #wrapper { background-color:#EEEEEE; }
-#header, #top-menu { margin: 0px 10px 0px 11px; }
-#main { background: #EEEEEE; margin: 8px 10px 0px 10px; }
-#content, #main.nosidebar #content { background: #fff; border-right: 1px solid #bbb; border-bottom: 1px solid #bbb; border-left: 1px solid #d7d7d7; border-top: 1px solid #d7d7d7; }
-#footer { background-color:#EEEEEE; border: 0px; }
-
-/* Headers */
-h2, h3, h4, .wiki h1, .wiki h2, .wiki h3 {border-bottom: 0px;}
-
-/* Menu */
-#main-menu li a { background-color: #507AAA; font-weight: bold;}
-#main-menu li a:hover { background: #507AAA; text-decoration: underline; }
-#main-menu li a.selected, #main-menu li a.selected:hover { background-color:#EEEEEE; }
-
-/* Tables */
-table.list tbody td, table.list tbody tr:hover td { border: solid 1px #d7d7d7; }
-table.list thead th {
-    border-width: 1px;
-    border-style: solid;
-    border-top-color: #d7d7d7;
-    border-right-color: #d7d7d7;
-    border-left-color: #d7d7d7;
-    border-bottom-color: #999999;
-}
-
-/* Issues grid styles by priorities (provided by Wynn Netherland) */
-table.list tr.issue a { color: #666; }
-
-tr.odd.priority-5, table.list tbody tr.odd.priority-5:hover { color: #900; font-weight: bold; }
-tr.odd.priority-5 { background: #ffc4c4; }
-tr.even.priority-5, table.list tbody tr.even.priority-5:hover { color: #900; font-weight: bold; }
-tr.even.priority-5 { background: #ffd4d4; }
-tr.priority-5 a, tr.priority-5:hover a { color: #900; }
-tr.odd.priority-5 td, tr.even.priority-5 td { border-color: #ffb4b4; }
-
-tr.odd.priority-4, table.list tbody tr.odd.priority-4:hover { color: #900; }
-tr.odd.priority-4 { background: #ffc4c4; }
-tr.even.priority-4, table.list tbody tr.even.priority-4:hover { color: #900; }
-tr.even.priority-4 { background: #ffd4d4; }
-tr.priority-4 a { color: #900; }
-tr.odd.priority-4 td, tr.even.priority-4 td { border-color: #ffb4b4; }
-
-tr.odd.priority-3, table.list tbody tr.odd.priority-3:hover { color: #900; }
-tr.odd.priority-3 { background: #fee; }
-tr.even.priority-3, table.list tbody tr.even.priority-3:hover { color: #900; }
-tr.even.priority-3 { background: #fff2f2; }
-tr.priority-3 a { color: #900; }
-tr.odd.priority-3 td, tr.even.priority-3 td { border-color: #fcc; }
-
-tr.odd.priority-1, table.list tbody tr.odd.priority-1:hover { color: #559; }
-tr.odd.priority-1 { background: #eaf7ff; }
-tr.even.priority-1, table.list tbody tr.even.priority-1:hover { color: #559; }
-tr.even.priority-1 { background: #f2faff; }
-tr.priority-1 a { color: #559; }
-tr.odd.priority-1 td, tr.even.priority-1 td { border-color: #add7f3; }
-
-/* Buttons */
-input[type="button"], input[type="submit"], input[type="reset"] { background-color: #f2f2f2; color: #222222; border: 1px outset #cccccc; }
-input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover { background-color: #ccccbb; }
-
-/* Fields */
-input[type="text"], input[type="password"], textarea, select { padding: 2px; border: 1px solid #d7d7d7; }
-input[type="text"], input[type="password"] { padding: 3px; }
-input[type="text"]:focus, input[type="password"]:focus, textarea:focus, select:focus { border: 1px solid #888866; }
-option { border-bottom: 1px dotted #d7d7d7; }
-
-/* Misc */
-.box { background-color: #fcfcfc; }
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7d/7d347f5736383447d929cfa493b44727c73c536a.svn-base
--- /dev/null
+++ b/.svn/pristine/7d/7d347f5736383447d929cfa493b44727c73c536a.svn-base
@@ -0,0 +1,67 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../../test_helper', __FILE__)
+
+class Redmine::Views::Builders::XmlTest < ActiveSupport::TestCase
+
+  def test_hash
+    assert_xml_output('<person><name>Ryan</name><age>32</age></person>') do |b|
+      b.person do
+        b.name 'Ryan'
+        b.age  32
+      end
+    end
+  end
+
+  def test_array
+    assert_xml_output('<books type="array"><book title="Book 1"/><book title="Book 2"/></books>') do |b|
+      b.array :books do |b|
+        b.book :title => 'Book 1'
+        b.book :title => 'Book 2'
+      end
+    end
+  end
+
+  def test_array_with_content_tags
+    assert_xml_output('<books type="array"><book author="B. Smith">Book 1</book><book author="G. Cooper">Book 2</book></books>') do |b|
+      b.array :books do |b|
+        b.book 'Book 1', :author => 'B. Smith'
+        b.book 'Book 2', :author => 'G. Cooper'
+      end
+    end
+  end
+
+  def test_nested_arrays
+    assert_xml_output('<books type="array"><book><authors type="array"><author>B. Smith</author><author>G. Cooper</author></authors></book></books>') do |b|
+      b.array :books do |books|
+        books.book do |book|
+          book.array :authors do |authors|
+            authors.author 'B. Smith'
+            authors.author 'G. Cooper'
+          end
+        end
+      end
+    end
+  end
+
+  def assert_xml_output(expected, &block)
+    builder = Redmine::Views::Builders::Xml.new(ActionDispatch::TestRequest.new, ActionDispatch::TestResponse.new)
+    block.call(builder)
+    assert_equal('<?xml version="1.0" encoding="UTF-8"?>' + expected, builder.output)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7d/7d3ac76c84dee77bab1ef37f05ae263ad699e2b8.svn-base
--- /dev/null
+++ b/.svn/pristine/7d/7d3ac76c84dee77bab1ef37f05ae263ad699e2b8.svn-base
@@ -0,0 +1,264 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoriesControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
+           :repositories, :issues, :issue_statuses, :changesets, :changes,
+           :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
+
+  def setup
+    User.current = nil
+  end
+
+  def test_new
+    @request.session[:user_id] = 1
+    get :new, :project_id => 'subproject1'
+    assert_response :success
+    assert_template 'new'
+    assert_kind_of Repository::Subversion, assigns(:repository)
+    assert assigns(:repository).new_record?
+    assert_tag 'input', :attributes => {:name => 'repository[url]', :disabled => nil}
+  end
+
+  def test_new_should_propose_enabled_scm_only
+    @request.session[:user_id] = 1
+    with_settings :enabled_scm => ['Mercurial', 'Git'] do
+      get :new, :project_id => 'subproject1'
+    end
+    assert_response :success
+    assert_template 'new'
+    assert_kind_of Repository::Mercurial, assigns(:repository)
+    assert_tag 'select', :attributes => {:name => 'repository_scm'},
+      :children => {:count => 3}
+    assert_tag 'select', :attributes => {:name => 'repository_scm'},
+      :child => {:tag => 'option', :attributes => {:value => 'Mercurial', :selected => 'selected'}}
+    assert_tag 'select', :attributes => {:name => 'repository_scm'},
+      :child => {:tag => 'option', :attributes => {:value => 'Git', :selected => nil}}
+  end
+
+  def test_create
+    @request.session[:user_id] = 1
+    assert_difference 'Repository.count' do
+      post :create, :project_id => 'subproject1',
+           :repository_scm => 'Subversion',
+           :repository => {:url => 'file:///test', :is_default => '1', :identifier => ''}
+    end
+    assert_response 302
+    repository = Repository.first(:order => 'id DESC')
+    assert_kind_of Repository::Subversion, repository
+    assert_equal 'file:///test', repository.url
+  end
+
+  def test_create_with_failure
+    @request.session[:user_id] = 1
+    assert_no_difference 'Repository.count' do
+      post :create, :project_id => 'subproject1',
+           :repository_scm => 'Subversion',
+           :repository => {:url => 'invalid'}
+    end
+    assert_response :success
+    assert_template 'new'
+    assert_kind_of Repository::Subversion, assigns(:repository)
+    assert assigns(:repository).new_record?
+  end
+
+  def test_edit
+    @request.session[:user_id] = 1
+    get :edit, :id => 11
+    assert_response :success
+    assert_template 'edit'
+    assert_equal Repository.find(11), assigns(:repository)
+    assert_tag 'input', :attributes => {:name => 'repository[url]', :value => 'svn://localhost/test', :disabled => 'disabled'}
+  end
+
+  def test_update
+    @request.session[:user_id] = 1
+    put :update, :id => 11, :repository => {:password => 'test_update'}
+    assert_response 302
+    assert_equal 'test_update', Repository.find(11).password
+  end
+
+  def test_update_with_failure
+    @request.session[:user_id] = 1
+    put :update, :id => 11, :repository => {:password => 'x'*260}
+    assert_response :success
+    assert_template 'edit'
+    assert_equal Repository.find(11), assigns(:repository)
+  end
+
+  def test_destroy
+    @request.session[:user_id] = 1
+    assert_difference 'Repository.count', -1 do
+      delete :destroy, :id => 11
+    end
+    assert_response 302
+    assert_nil Repository.find_by_id(11)
+  end
+
+  def test_revisions
+    get :revisions, :id => 1
+    assert_response :success
+    assert_template 'revisions'
+    assert_equal Repository.find(10), assigns(:repository)
+    assert_not_nil assigns(:changesets)
+  end
+
+  def test_revisions_for_other_repository
+    repository = Repository::Subversion.create!(:project_id => 1, :identifier => 'foo', :url => 'file:///foo')
+
+    get :revisions, :id => 1, :repository_id => 'foo'
+    assert_response :success
+    assert_template 'revisions'
+    assert_equal repository, assigns(:repository)
+    assert_not_nil assigns(:changesets)
+  end
+
+  def test_revisions_for_invalid_repository
+    get :revisions, :id => 1, :repository_id => 'foo'
+    assert_response 404
+  end
+
+  def test_revision
+    get :revision, :id => 1, :rev => 1
+    assert_response :success
+    assert_not_nil assigns(:changeset)
+    assert_equal "1", assigns(:changeset).revision
+  end
+
+  def test_revision_should_not_change_the_project_menu_link
+    get :revision, :id => 1, :rev => 1
+    assert_response :success
+
+    assert_tag 'a', :attributes => {:href => '/projects/ecookbook/repository', :class => /repository/},
+      :ancestor => {:attributes => {:id => 'main-menu'}}
+  end
+
+  def test_revision_with_before_nil_and_afer_normal
+    get :revision, {:id => 1, :rev => 1}
+    assert_response :success
+    assert_template 'revision'
+    assert_no_tag :tag => "div", :attributes => { :class => "contextual" },
+      :child => { :tag => "a", :attributes => { :href => '/projects/ecookbook/repository/revisions/0'}
+    }
+    assert_tag :tag => "div", :attributes => { :class => "contextual" },
+        :child => { :tag => "a", :attributes => { :href => '/projects/ecookbook/repository/revisions/2'}
+    }
+  end
+
+  def test_add_related_issue
+    @request.session[:user_id] = 2
+    assert_difference 'Changeset.find(103).issues.size' do
+      xhr :post, :add_related_issue, :id => 1, :rev => 4, :issue_id => 2, :format => 'js'
+      assert_response :success
+      assert_template 'add_related_issue'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_equal [2], Changeset.find(103).issue_ids
+    assert_include 'related-issues', response.body
+    assert_include 'Feature request #2', response.body
+  end
+
+  def test_add_related_issue_with_invalid_issue_id
+    @request.session[:user_id] = 2
+    assert_no_difference 'Changeset.find(103).issues.size' do
+      xhr :post, :add_related_issue, :id => 1, :rev => 4, :issue_id => 9999, :format => 'js'
+      assert_response :success
+      assert_template 'add_related_issue'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_include 'alert("Issue is invalid")', response.body
+  end
+
+  def test_remove_related_issue
+    Changeset.find(103).issues << Issue.find(1)
+    Changeset.find(103).issues << Issue.find(2)
+
+    @request.session[:user_id] = 2
+    assert_difference 'Changeset.find(103).issues.size', -1 do
+      xhr :delete, :remove_related_issue, :id => 1, :rev => 4, :issue_id => 2, :format => 'js'
+      assert_response :success
+      assert_template 'remove_related_issue'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_equal [1], Changeset.find(103).issue_ids
+    assert_include 'related-issue-2', response.body
+  end
+
+  def test_graph_commits_per_month
+    # Make sure there's some data to display
+    latest = Project.find(1).repository.changesets.maximum(:commit_date)
+    assert_not_nil latest
+    Date.stubs(:today).returns(latest.to_date + 10)
+
+    get :graph, :id => 1, :graph => 'commits_per_month'
+    assert_response :success
+    assert_equal 'image/svg+xml', @response.content_type
+  end
+
+  def test_graph_commits_per_author
+    get :graph, :id => 1, :graph => 'commits_per_author'
+    assert_response :success
+    assert_equal 'image/svg+xml', @response.content_type
+  end
+
+  def test_get_committers
+    @request.session[:user_id] = 2
+    # add a commit with an unknown user
+    Changeset.create!(
+        :repository => Project.find(1).repository,
+        :committer  => 'foo',
+        :committed_on => Time.now,
+        :revision => 100,
+        :comments => 'Committed by foo.'
+     )
+
+    get :committers, :id => 10
+    assert_response :success
+    assert_template 'committers'
+
+    assert_tag :td, :content => 'dlopper',
+                    :sibling => { :tag => 'td',
+                                  :child => { :tag => 'select', :attributes => { :name => %r{^committers\[\d+\]\[\]$} },
+                                                                :child => { :tag => 'option', :content => 'Dave Lopper',
+                                                                                              :attributes => { :value => '3', :selected => 'selected' }}}}
+    assert_tag :td, :content => 'foo',
+                    :sibling => { :tag => 'td',
+                                  :child => { :tag => 'select', :attributes => { :name => %r{^committers\[\d+\]\[\]$} }}}
+    assert_no_tag :td, :content => 'foo',
+                       :sibling => { :tag => 'td',
+                                     :descendant => { :tag => 'option', :attributes => { :selected => 'selected' }}}
+  end
+
+  def test_post_committers
+    @request.session[:user_id] = 2
+    # add a commit with an unknown user
+    c = Changeset.create!(
+            :repository => Project.find(1).repository,
+            :committer  => 'foo',
+            :committed_on => Time.now,
+            :revision => 100,
+            :comments => 'Committed by foo.'
+          )
+    assert_no_difference "Changeset.count(:conditions => 'user_id = 3')" do
+      post :committers, :id => 10, :committers => { '0' => ['foo', '2'], '1' => ['dlopper', '3']}
+      assert_response 302
+      assert_equal User.find(2), c.reload.user
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7d/7d3cbe14fc84c9fc42efa7908095cf2d1fad9643.svn-base
--- /dev/null
+++ b/.svn/pristine/7d/7d3cbe14fc84c9fc42efa7908095cf2d1fad9643.svn-base
@@ -0,0 +1,94 @@
+var revisionGraph = null;
+
+function drawRevisionGraph(holder, commits_hash, graph_space) {
+    var XSTEP = 20,
+        CIRCLE_INROW_OFFSET = 10;
+    var commits_by_scmid = commits_hash,
+        commits = $.map(commits_by_scmid, function(val,i){return val;});
+    var max_rdmid = commits.length - 1;
+    var commit_table_rows = $('table.changesets tr.changeset');
+
+    // create graph
+    if(revisionGraph != null)
+        revisionGraph.clear();
+    else
+        revisionGraph = Raphael(holder);
+
+    var top = revisionGraph.set();
+    // init dimensions
+    var graph_x_offset = commit_table_rows.first().find('td').first().position().left - $(holder).position().left,
+        graph_y_offset = $(holder).position().top,
+        graph_right_side = graph_x_offset + (graph_space + 1) * XSTEP,
+        graph_bottom = commit_table_rows.last().position().top + commit_table_rows.last().height() - graph_y_offset;
+
+    revisionGraph.setSize(graph_right_side, graph_bottom);
+
+    // init colors
+    var colors = [];
+    Raphael.getColor.reset();
+    for (var k = 0; k <= graph_space; k++) {
+        colors.push(Raphael.getColor());
+    }
+
+    var parent_commit;
+    var x, y, parent_x, parent_y;
+    var path, title;
+    var revision_dot_overlay;
+    $.each(commits, function(index, commit) {
+        if (!commit.hasOwnProperty("space"))
+            commit.space = 0;
+
+        y = commit_table_rows.eq(max_rdmid - commit.rdmid).position().top - graph_y_offset + CIRCLE_INROW_OFFSET;
+        x = graph_x_offset + XSTEP / 2 + XSTEP * commit.space;
+        revisionGraph.circle(x, y, 3)
+            .attr({
+                fill: colors[commit.space],
+                stroke: 'none'
+            }).toFront();
+        // paths to parents
+        $.each(commit.parent_scmids, function(index, parent_scmid) {
+            parent_commit = commits_by_scmid[parent_scmid];
+            if (parent_commit) {
+                if (!parent_commit.hasOwnProperty("space"))
+                    parent_commit.space = 0;
+
+                parent_y = commit_table_rows.eq(max_rdmid - parent_commit.rdmid).position().top - graph_y_offset + CIRCLE_INROW_OFFSET;
+                parent_x = graph_x_offset + XSTEP / 2 + XSTEP * parent_commit.space;
+                if (parent_commit.space == commit.space) {
+                    // vertical path
+                    path = revisionGraph.path([
+                        'M', x, y,
+                        'V', parent_y]);
+                } else {
+                    // path to a commit in a different branch (Bezier curve)
+                    path = revisionGraph.path([
+                        'M', x, y,
+                        'C', x, y, x, y + (parent_y - y) / 2, x + (parent_x - x) / 2, y + (parent_y - y) / 2,
+                        'C', x + (parent_x - x) / 2, y + (parent_y - y) / 2, parent_x, parent_y-(parent_y-y)/2, parent_x, parent_y]);
+                }
+            } else {
+                // vertical path ending at the bottom of the revisionGraph
+                path = revisionGraph.path([
+                    'M', x, y,
+                    'V', graph_bottom]);
+            }
+            path.attr({stroke: colors[commit.space], "stroke-width": 1.5}).toBack();
+        });
+        revision_dot_overlay = revisionGraph.circle(x, y, 10);
+        revision_dot_overlay
+            .attr({
+                fill: '#000',
+                opacity: 0,
+                cursor: 'pointer', 
+                href: commit.href
+            });
+
+        if(commit.refs != null && commit.refs.length > 0) {
+            title = document.createElementNS(revisionGraph.canvas.namespaceURI, 'title');
+            title.appendChild(document.createTextNode(commit.refs));
+            revision_dot_overlay.node.appendChild(title);
+        }
+        top.push(revision_dot_overlay);
+    });
+    top.toFront();
+};
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7d/7d7a63dac05990ebb68fcd3fce0da9965a2d6f7a.svn-base
--- a/.svn/pristine/7d/7d7a63dac05990ebb68fcd3fce0da9965a2d6f7a.svn-base
+++ /dev/null
@@ -1,282 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'repositories_controller'
-
-# Re-raise errors caught by the controller.
-class RepositoriesController; def rescue_action(e) raise e end; end
-
-class RepositoriesCvsControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles,
-           :repositories, :enabled_modules
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s
-  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
-  # CVS module
-  MODULE_NAME = 'test'
-  PRJ_ID = 3
-  NUM_REV = 7
-
-  def setup
-    @controller = RepositoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    Setting.default_language = 'en'
-    User.current = nil
-
-    @project = Project.find(PRJ_ID)
-    @repository  = Repository::Cvs.create(:project      => Project.find(PRJ_ID),
-                                          :root_url     => REPOSITORY_PATH,
-                                          :url          => MODULE_NAME,
-                                          :log_encoding => 'UTF-8')
-    assert @repository
-  end
-
-  if File.directory?(REPOSITORY_PATH)
-    def test_browse_root
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal 3, assigns(:entries).size
-
-      entry = assigns(:entries).detect {|e| e.name == 'images'}
-      assert_equal 'dir', entry.kind
-
-      entry = assigns(:entries).detect {|e| e.name == 'README'}
-      assert_equal 'file', entry.kind
-
-      assert_not_nil assigns(:changesets)
-      assert assigns(:changesets).size > 0
-    end
-
-    def test_browse_directory
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :path => ['images']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['add.png', 'delete.png', 'edit.png'], assigns(:entries).collect(&:name)
-      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
-      assert_not_nil entry
-      assert_equal 'file', entry.kind
-      assert_equal 'images/edit.png', entry.path
-    end
-
-    def test_browse_at_given_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :path => ['images'], :rev => 1
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name)
-    end
-
-    def test_entry
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb']
-      assert_response :success
-      assert_template 'entry'
-      assert_no_tag :tag => 'td',
-                    :attributes => { :class => /line-code/},
-                    :content => /before_filter/
-    end
-
-    def test_entry_at_given_revision
-      # changesets must be loaded
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb'], :rev => 2
-      assert_response :success
-      assert_template 'entry'
-      # this line was removed in r3
-      assert_tag :tag => 'td',
-                 :attributes => { :class => /line-code/},
-                 :content => /before_filter/
-    end
-
-    def test_entry_not_found
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['sources', 'zzz.c']
-      assert_tag :tag => 'p',
-                 :attributes => { :id => /errorExplanation/ },
-                 :content => /The entry or revision was not found in the repository/
-    end
-
-    def test_entry_download
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb'],
-          :format => 'raw'
-      assert_response :success
-    end
-
-    def test_directory_entry
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['sources']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entry)
-      assert_equal 'sources', assigns(:entry).name
-    end
-
-    def test_diff
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['inline', 'sbs'].each do |dt|
-        get :diff, :id => PRJ_ID, :rev => 3, :type => dt
-        assert_response :success
-        assert_template 'diff'
-        assert_tag :tag => 'td', :attributes => { :class => 'line-code diff_out' },
-                                 :content => /before_filter :require_login/
-        assert_tag :tag => 'td', :attributes => { :class => 'line-code diff_in' },
-                                 :content => /with one change/
-      end
-    end
-
-    def test_diff_new_files
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['inline', 'sbs'].each do |dt|
-        get :diff, :id => PRJ_ID, :rev => 1, :type => dt
-        assert_response :success
-        assert_template 'diff'
-        assert_tag :tag => 'td', :attributes => { :class => 'line-code diff_in' },
-                                 :content => /watched.remove_watcher/
-        assert_tag :tag => 'th', :attributes => { :class => 'filename' },
-                                 :content => /test\/README/
-        assert_tag :tag => 'th', :attributes => { :class => 'filename' },
-                                 :content => /test\/images\/delete.png	/
-        assert_tag :tag => 'th', :attributes => { :class => 'filename' },
-                                 :content => /test\/images\/edit.png/
-        assert_tag :tag => 'th', :attributes => { :class => 'filename' },
-                                 :content => /test\/sources\/watchers_controller.rb/
-      end
-    end
-
-    def test_annotate
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :annotate, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb']
-      assert_response :success
-      assert_template 'annotate'
-      # 1.1 line
-      assert_tag :tag => 'th',
-                 :attributes => { :class => 'line-num' },
-                 :content => '18',
-                 :sibling => {
-                   :tag => 'td',
-                   :attributes => { :class => 'revision' },
-                   :content => /1.1/,
-                   :sibling => {
-                      :tag => 'td',
-                      :attributes => { :class => 'author' },
-                      :content => /LANG/
-                        }
-                   }
-      # 1.2 line
-      assert_tag :tag => 'th',
-                 :attributes => { :class => 'line-num' },
-                 :content => '32',
-                 :sibling => {
-                     :tag => 'td',
-                     :attributes => { :class => 'revision' },
-                     :content => /1.2/,
-                     :sibling => {
-                        :tag => 'td',
-                        :attributes => { :class => 'author' },
-                        :content => /LANG/
-                        }
-                   }
-    end
-
-    def test_destroy_valid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-
-    def test_destroy_invalid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-
-      @repository  = Repository::Cvs.create(
-                              :project      => Project.find(PRJ_ID),
-                              :root_url     => "/invalid",
-                              :url          => MODULE_NAME,
-                              :log_encoding => 'UTF-8'
-                              )
-      assert @repository
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal 0, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-  else
-    puts "CVS test repository NOT FOUND. Skipping functional tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7d/7dd0539603ad9e25c32256869656657e4135a1c8.svn-base
--- a/.svn/pristine/7d/7dd0539603ad9e25c32256869656657e4135a1c8.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-<h2><%= link_to l(:label_group_plural), groups_path %> &#187; <%= l(:label_group_new) %></h2>
-
-<% labelled_form_for @group do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<p>
-  <%= f.submit l(:button_create) %>
-  <%= f.submit l(:button_create_and_continue), :name => 'continue' %>
-</p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7d/7dd1b8397e24cced4bd7016e085055ff385a2960.svn-base
--- a/.svn/pristine/7d/7dd1b8397e24cced4bd7016e085055ff385a2960.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-I18n.default_locale = 'en'
-# Adds fallback to default locale for untranslated strings
-I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
-
-require 'redmine'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7e/7e362e9571e296e9ab312aca34fbe7dfde644cd2.svn-base
--- /dev/null
+++ b/.svn/pristine/7e/7e362e9571e296e9ab312aca34fbe7dfde644cd2.svn-base
@@ -0,0 +1,81 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+module RedminePmTest
+  class TestCase < ActiveSupport::TestCase
+    attr_reader :command, :response, :status, :username, :password
+    
+    # Cannot use transactional fixtures here: database
+    # will be accessed from Redmine.pm with its own connection
+    self.use_transactional_fixtures = false
+  
+    def test_dummy
+    end
+  
+    protected
+  
+    def assert_response(expected, msg=nil)
+      case expected
+      when :success
+        assert_equal 0, status,
+          (msg || "The command failed (exit: #{status}):\n  #{command}\nOutput was:\n#{formatted_response}")
+      when :failure
+        assert_not_equal 0, status,
+          (msg || "The command succeed (exit: #{status}):\n  #{command}\nOutput was:\n#{formatted_response}")
+      else
+        assert_equal expected, status, msg
+      end
+    end
+  
+    def assert_success(*args)
+      execute *args
+      assert_response :success
+    end
+  
+    def assert_failure(*args)
+      execute *args
+      assert_response :failure
+    end
+    
+    def with_credentials(username, password)
+      old_username, old_password = @username, @password
+      @username, @password = username, password
+      yield if block_given?
+    ensure
+      @username, @password = old_username, old_password
+    end
+    
+    def execute(*args)
+      @command = args.join(' ')
+      @status = nil
+      IO.popen("#{command} 2>&1") do |io|
+        @response = io.read
+      end
+      @status = $?.exitstatus
+    end
+  
+    def formatted_response
+      "#{'='*40}\n#{response}#{'='*40}"
+    end
+  
+    def random_filename
+      Redmine::Utils.random_hex(16)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7e/7e3d39301783d138f7a6d49cba0462adeb117d57.svn-base
--- a/.svn/pristine/7e/7e3d39301783d138f7a6d49cba0462adeb117d57.svn-base
+++ /dev/null
@@ -1,223 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'account_controller'
-
-# Re-raise errors caught by the controller.
-class AccountController; def rescue_action(e) raise e end; end
-
-class AccountControllerTest < ActionController::TestCase
-  fixtures :users, :roles
-
-  def setup
-    @controller = AccountController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_login_should_redirect_to_back_url_param
-    # request.uri is "test.host" in test environment
-    post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.host%2Fissues%2Fshow%2F1'
-    assert_redirected_to '/issues/show/1'
-  end
-
-  def test_login_should_not_redirect_to_another_host
-    post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.foo%2Ffake'
-    assert_redirected_to '/my/page'
-  end
-
-  def test_login_with_wrong_password
-    post :login, :username => 'admin', :password => 'bad'
-    assert_response :success
-    assert_template 'login'
-    assert_tag 'div',
-               :attributes => { :class => "flash error" },
-               :content => /Invalid user or password/
-  end
-
-  if Object.const_defined?(:OpenID)
-
-  def test_login_with_openid_for_existing_user
-    Setting.self_registration = '3'
-    Setting.openid = '1'
-    existing_user = User.new(:firstname => 'Cool',
-                             :lastname => 'User',
-                             :mail => 'user@somedomain.com',
-                             :identity_url => 'http://openid.example.com/good_user')
-    existing_user.login = 'cool_user'
-    assert existing_user.save!
-
-    post :login, :openid_url => existing_user.identity_url
-    assert_redirected_to '/my/page'
-  end
-
-  def test_login_with_invalid_openid_provider
-    Setting.self_registration = '0'
-    Setting.openid = '1'
-    post :login, :openid_url => 'http;//openid.example.com/good_user'
-    assert_redirected_to home_url
-  end
-
-  def test_login_with_openid_for_existing_non_active_user
-    Setting.self_registration = '2'
-    Setting.openid = '1'
-    existing_user = User.new(:firstname => 'Cool',
-                             :lastname => 'User',
-                             :mail => 'user@somedomain.com',
-                             :identity_url => 'http://openid.example.com/good_user',
-                             :status => User::STATUS_REGISTERED)
-    existing_user.login = 'cool_user'
-    assert existing_user.save!
-
-    post :login, :openid_url => existing_user.identity_url
-    assert_redirected_to '/login'
-  end
-
-  def test_login_with_openid_with_new_user_created
-    Setting.self_registration = '3'
-    Setting.openid = '1'
-    post :login, :openid_url => 'http://openid.example.com/good_user'
-    assert_redirected_to '/my/account'
-    user = User.find_by_login('cool_user')
-    assert user
-    assert_equal 'Cool', user.firstname
-    assert_equal 'User', user.lastname
-  end
-
-  def test_login_with_openid_with_new_user_and_self_registration_off
-    Setting.self_registration = '0'
-    Setting.openid = '1'
-    post :login, :openid_url => 'http://openid.example.com/good_user'
-    assert_redirected_to home_url
-    user = User.find_by_login('cool_user')
-    assert ! user
-  end
-
-  def test_login_with_openid_with_new_user_created_with_email_activation_should_have_a_token
-    Setting.self_registration = '1'
-    Setting.openid = '1'
-    post :login, :openid_url => 'http://openid.example.com/good_user'
-    assert_redirected_to '/login'
-    user = User.find_by_login('cool_user')
-    assert user
-
-    token = Token.find_by_user_id_and_action(user.id, 'register')
-    assert token
-  end
-
-  def test_login_with_openid_with_new_user_created_with_manual_activation
-    Setting.self_registration = '2'
-    Setting.openid = '1'
-    post :login, :openid_url => 'http://openid.example.com/good_user'
-    assert_redirected_to '/login'
-    user = User.find_by_login('cool_user')
-    assert user
-    assert_equal User::STATUS_REGISTERED, user.status
-  end
-
-  def test_login_with_openid_with_new_user_with_conflict_should_register
-    Setting.self_registration = '3'
-    Setting.openid = '1'
-    existing_user = User.new(:firstname => 'Cool', :lastname => 'User', :mail => 'user@somedomain.com')
-    existing_user.login = 'cool_user'
-    assert existing_user.save!
-
-    post :login, :openid_url => 'http://openid.example.com/good_user'
-    assert_response :success
-    assert_template 'register'
-    assert assigns(:user)
-    assert_equal 'http://openid.example.com/good_user', assigns(:user)[:identity_url]
-  end
-
-  def test_setting_openid_should_return_true_when_set_to_true
-    Setting.openid = '1'
-    assert_equal true, Setting.openid?
-  end
-
-  else
-    puts "Skipping openid tests."
-  end
-
-  def test_logout
-    @request.session[:user_id] = 2
-    get :logout
-    assert_redirected_to '/'
-    assert_nil @request.session[:user_id]
-  end
-
-  context "GET #register" do
-    context "with self registration on" do
-      setup do
-        Setting.self_registration = '3'
-        get :register
-      end
-
-      should_respond_with :success
-      should_render_template :register
-      should_assign_to :user
-    end
-
-    context "with self registration off" do
-      setup do
-        Setting.self_registration = '0'
-        get :register
-      end
-
-      should_redirect_to('/') { home_url }
-    end
-  end
-
-  # See integration/account_test.rb for the full test
-  context "POST #register" do
-    context "with self registration on automatic" do
-      setup do
-        Setting.self_registration = '3'
-        post :register, :user => {
-          :login => 'register',
-          :password => 'test',
-          :password_confirmation => 'test',
-          :firstname => 'John',
-          :lastname => 'Doe',
-          :mail => 'register@example.com'
-        }
-      end
-
-      should_respond_with :redirect
-      should_assign_to :user
-      should_redirect_to('my page') { {:controller => 'my', :action => 'account'} }
-
-      should_create_a_new_user { User.last(:conditions => {:login => 'register'}) }
-
-      should 'set the user status to active' do
-        user = User.last(:conditions => {:login => 'register'})
-        assert user
-        assert_equal User::STATUS_ACTIVE, user.status
-      end
-    end
-
-    context "with self registration off" do
-      setup do
-        Setting.self_registration = '0'
-        post :register
-      end
-
-      should_redirect_to('/') { home_url }
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7e/7e3f9cdf448ee38697e8614780073ec72927018c.svn-base
--- a/.svn/pristine/7e/7e3f9cdf448ee38697e8614780073ec72927018c.svn-base
+++ /dev/null
@@ -1,62 +0,0 @@
-<% roles = Role.find_all_givable %>
-<% projects = Project.active.find(:all, :order => 'lft') %>
-
-<div class="splitcontentleft">
-<% if @user.memberships.any? %>
-<table class="list memberships">
-  <thead><tr>
-    <th><%= l(:label_project) %></th>
-    <th><%= l(:label_role_plural) %></th>
-    <th style="width:15%"></th>
-      <%= call_hook(:view_users_memberships_table_header, :user => @user )%>
-  </tr></thead>
-  <tbody>
-  <% @user.memberships.each do |membership| %>
-  <% next if membership.new_record? %>
-  <tr id="member-<%= membership.id %>" class="<%= cycle 'odd', 'even' %> class">
-  <td class="project">
-    <%= link_to_project membership.project %>
-  </td>
-  <td class="roles">
-    <span id="member-<%= membership.id %>-roles"><%=h membership.roles.sort.collect(&:to_s).join(', ') %></span>
-    <% remote_form_for(:membership, :url => { :action => 'edit_membership', :id => @user, :membership_id => membership },
-                                    :html => { :id => "member-#{membership.id}-roles-form", :style => 'display:none;'}) do %>
-        <p><% roles.each do |role| %>
-        <label><%= check_box_tag 'membership[role_ids][]', role.id, membership.roles.include?(role),
-                                                           :disabled => membership.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br />
-        <% end %></p>
-        <%= hidden_field_tag 'membership[role_ids][]', '' %>
-        <p><%= submit_tag l(:button_change) %>
-        <%= link_to_function l(:button_cancel), "$('member-#{membership.id}-roles').show(); $('member-#{membership.id}-roles-form').hide(); return false;" %></p>
-    <% end %>
-  </td>
-  <td class="buttons">
-      <%= link_to_function l(:button_edit), "$('member-#{membership.id}-roles').hide(); $('member-#{membership.id}-roles-form').show(); return false;", :class => 'icon icon-edit' %>
-      <%= link_to_remote(l(:button_delete), { :url => { :controller => 'users', :action => 'destroy_membership', :id => @user, :membership_id => membership },
-                                              :method => :post },
-                                              :class => 'icon icon-del') if membership.deletable? %>
-  </td>
-      <%= call_hook(:view_users_memberships_table_row, :user => @user, :membership => membership, :roles => roles, :projects => projects )%>
-  </tr>
-  <% end; reset_cycle %>
-  </tbody>
-</table>
-<% else %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
-</div>
-
-<div class="splitcontentright">
-<% if projects.any? %>
-<fieldset><legend><%=l(:label_project_new)%></legend>
-<% remote_form_for(:membership, :url => { :action => 'edit_membership', :id => @user }) do %>
-<%= select_tag 'membership[project_id]', options_for_membership_project_select(@user, projects) %>
-<p><%= l(:label_role_plural) %>:
-<% roles.each do |role| %>
-  <label><%= check_box_tag 'membership[role_ids][]', role.id %> <%=h role %></label>
-<% end %></p>
-<p><%= submit_tag l(:button_add) %></p>
-<% end %>
-</fieldset>
-<% end %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7e/7e8e9292e4aaad251a7746c0dc0d152386a542fc.svn-base
--- a/.svn/pristine/7e/7e8e9292e4aaad251a7746c0dc0d152386a542fc.svn-base
+++ /dev/null
@@ -1,96 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class RepositoryDarcsTest < ActiveSupport::TestCase
-  fixtures :projects
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
-  NUM_REV = 6
-
-  def setup
-    @project = Project.find(3)
-    @repository = Repository::Darcs.create(
-                      :project      => @project,
-                      :url          => REPOSITORY_PATH,
-                      :log_encoding => 'UTF-8'
-                      )
-    assert @repository
-  end
-
-  if File.directory?(REPOSITORY_PATH)
-    def test_fetch_changesets_from_scratch
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_equal 13, @repository.changes.count
-      assert_equal "Initial commit.", @repository.changesets.find_by_revision('1').comments
-    end
-
-    def test_fetch_changesets_incremental
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      # Remove changesets with revision > 3
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 3}
-      @project.reload
-      assert_equal 3, @repository.changesets.count
-
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-    end
-
-    def test_entries_invalid_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_nil @repository.entries('', '123')
-    end
-
-    def test_deleted_files_should_not_be_listed
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      entries = @repository.entries('sources')
-      assert entries.detect {|e| e.name == 'watchers_controller.rb'}
-      assert_nil entries.detect {|e| e.name == 'welcome_controller.rb'}
-    end
-
-    def test_cat
-      if @repository.scm.supports_cat?
-        assert_equal 0, @repository.changesets.count
-        @repository.fetch_changesets
-        @project.reload
-        assert_equal NUM_REV, @repository.changesets.count
-        cat = @repository.cat("sources/welcome_controller.rb", 2)
-        assert_not_nil cat
-        assert cat.include?('class WelcomeController < ApplicationController')
-      end
-    end
-  else
-    puts "Darcs test repository NOT FOUND. Skipping unit tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7e/7ea8be01cd62ea12ccab2b959df562421b7f5a7b.svn-base
--- a/.svn/pristine/7e/7ea8be01cd62ea12ccab2b959df562421b7f5a7b.svn-base
+++ /dev/null
@@ -1,29 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class JournalObserver < ActiveRecord::Observer
-  def after_create(journal)
-    if journal.notify? &&
-        (Setting.notified_events.include?('issue_updated') ||
-          (Setting.notified_events.include?('issue_note_added') && journal.notes.present?) ||
-          (Setting.notified_events.include?('issue_status_updated') && journal.new_status.present?) ||
-          (Setting.notified_events.include?('issue_priority_updated') && journal.new_value_for('priority_id').present?)
-        )
-      Mailer.deliver_issue_edit(journal)
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7e/7ee8c8273c1a633a982d9a4836b18c68168b73d6.svn-base
--- /dev/null
+++ b/.svn/pristine/7e/7ee8c8273c1a633a982d9a4836b18c68168b73d6.svn-base
@@ -0,0 +1,108 @@
+<div class="contextual">
+<% if !@query.new_record? && @query.editable_by?(User.current) %>
+  <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %>
+  <%= delete_link query_path(@query) %>
+<% end %>
+</div>
+
+<h2><%= @query.new_record? ? l(:label_issue_plural) : h(@query.name) %></h2>
+<% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %>
+
+<%= form_tag({ :controller => 'issues', :action => 'index', :project_id => @project },
+            :method => :get, :id => 'query_form') do %>
+    <%= hidden_field_tag 'set_filter', '1' %>
+    <div id="query_form_content" class="hide-when-print">
+    <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
+      <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
+      <div style="<%= @query.new_record? ? "" : "display: none;" %>">
+        <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
+      </div>
+    </fieldset>
+    <fieldset class="collapsible collapsed">
+      <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
+      <div style="display: none;">
+        <table>
+          <tr>
+            <td><%= l(:field_column_names) %></td>
+            <td><%= render_query_columns_selection(@query) %></td>
+          </tr>
+          <tr>
+            <td><label for='group_by'><%= l(:field_group_by) %></label></td>
+            <td><%= select_tag('group_by',
+                               options_for_select(
+                                 [[]] + @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]},
+                                 @query.group_by)
+                       ) %></td>
+          </tr>
+          <tr>
+            <td><%= l(:button_show) %></td>
+            <td><%= available_block_columns_tags(@query) %></td>
+          </tr>
+        </table>
+      </div>
+    </fieldset>
+    </div>
+    <p class="buttons hide-when-print">
+
+    <%= link_to_function l(:button_apply), 'submit_query_form("query_form")', :class => 'icon icon-checked' %>
+    <%= link_to l(:button_clear), { :set_filter => 1, :project_id => @project }, :class => 'icon icon-reload'  %>
+    <% if @query.new_record? && User.current.allowed_to?(:save_queries, @project, :global => true) %>
+        <%= link_to_function l(:button_save),
+                             "$('#query_form').attr('action', '#{ @project ? new_project_query_path(@project) : new_query_path }'); submit_query_form('query_form')",
+                             :class => 'icon icon-save' %>
+    <% end %>
+    </p>
+<% end %>
+
+<%= error_messages_for 'query' %>
+<% if @query.valid? %>
+<% if @issues.empty? %>
+<p class="nodata"><%= l(:label_no_data) %></p>
+<% else %>
+<%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
+<p class="pagination"><%= pagination_links_full @issue_pages, @issue_count %></p>
+<% end %>
+
+<% other_formats_links do |f| %>
+  <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %>
+  <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
+  <%= f.link_to 'PDF', :url => params %>
+<% end %>
+
+<div id="csv-export-options" style="display:none;">
+  <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
+  <%= form_tag(params.merge({:format => 'csv',:page=>nil}), :method => :get, :id => 'csv-export-form') do %>
+  <p>
+    <label><%= radio_button_tag 'columns', '', true %> <%= l(:description_selected_columns) %></label><br />
+    <label><%= radio_button_tag 'columns', 'all' %> <%= l(:description_all_columns) %></label>
+  </p>
+  <p>
+    <label><%= check_box_tag 'description', '1', @query.has_column?(:description) %> <%= l(:field_description) %></label>
+  </p>
+  <p class="buttons">
+    <%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);" %>
+    <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
+  </p>
+  <% end %>
+</div>
+
+<% end %>
+<%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %>
+
+<% content_for :sidebar do %>
+    <%= render :partial => 'issues/sidebar' %>
+<% end %>
+
+<% content_for :header_tags do %>
+    <%= auto_discovery_link_tag(:atom,
+                                {:query_id => @query, :format => 'atom',
+                                 :page => nil, :key => User.current.rss_key},
+                                :title => l(:label_issue_plural)) %>
+    <%= auto_discovery_link_tag(:atom,
+                                {:controller => 'journals', :action => 'index',
+                                 :query_id => @query, :format => 'atom',
+                                 :page => nil, :key => User.current.rss_key},
+                                :title => l(:label_changes_details)) %>
+<% end %>
+
+<%= context_menu issues_context_menu_path %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7f/7f29e28dea9f944faa0f0c10063d8ae096007167.svn-base
--- a/.svn/pristine/7f/7f29e28dea9f944faa0f0c10063d8ae096007167.svn-base
+++ /dev/null
@@ -1,1022 +0,0 @@
-#Ernad Husremovic hernad@bring.out.ba
-
-bs:
-  direction: ltr
-  date:
-    formats:
-      default: "%d.%m.%Y"
-      short: "%e. %b"
-      long: "%e. %B %Y"
-      only_day: "%e"
-
-
-    day_names: [Nedjelja, Ponedjeljak, Utorak, Srijeda, ÄŒetvrtak, Petak, Subota]
-    abbr_day_names: [Ned, Pon, Uto, Sri, ÄŒet, Pet, Sub]
-
-    month_names: [~, Januar, Februar, Mart, April, Maj, Jun, Jul, Avgust, Septembar, Oktobar, Novembar, Decembar]
-    abbr_month_names: [~, Jan, Feb, Mar, Apr, Maj, Jun, Jul, Avg, Sep, Okt, Nov, Dec]
-    order:
-      - :day
-      - :month
-      - :year
-  
-  time:
-    formats:
-      default: "%A, %e. %B %Y, %H:%M"
-      short: "%e. %B, %H:%M Uhr"
-      long: "%A, %e. %B %Y, %H:%M"
-      time: "%H:%M"
-
-    am: "prijepodne"
-    pm: "poslijepodne"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "pola minute"
-      less_than_x_seconds:
-        one:   "manje od 1 sekunde"
-        other: "manje od %{count} sekudni"
-      x_seconds:
-        one:   "1 sekunda"
-        other: "%{count} sekundi"
-      less_than_x_minutes:
-        one:   "manje od 1 minute"
-        other: "manje od %{count} minuta"
-      x_minutes:
-        one:   "1 minuta"
-        other: "%{count} minuta"
-      about_x_hours:
-        one:   "oko 1 sahat"
-        other: "oko %{count} sahata"
-      x_days:
-        one:   "1 dan"
-        other: "%{count} dana"
-      about_x_months:
-        one:   "oko 1 mjesec"
-        other: "oko %{count} mjeseci"
-      x_months:
-        one:   "1 mjesec"
-        other: "%{count} mjeseci"
-      about_x_years:
-        one:   "oko 1 godine"
-        other: "oko %{count} godina"
-      over_x_years:
-        one:   "preko 1 godine"
-        other: "preko %{count} godina"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-
-  number:
-    format:
-      precision: 2
-      separator: ','
-      delimiter: '.'
-    currency:
-      format:
-        unit: 'KM'
-        format: '%u %n'
-        separator:
-        delimiter:
-        precision:
-    percentage:
-      format:
-        delimiter: ""
-    precision:
-      format:
-        delimiter: ""
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "i"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "nije ukljuÄeno u listu"
-        exclusion: "je rezervisano"
-        invalid: "nije ispravno"
-        confirmation: "ne odgovara potvrdi"
-        accepted: "mora se prihvatiti"
-        empty: "ne moÅ¾e biti prazno"
-        blank: "ne moÅ¾e biti znak razmaka"
-        too_long: "je predugaÄko"
-        too_short: "je prekratko"
-        wrong_length: "je pogreÅ¡ne duÅ¾ine"
-        taken: "veÄ‡ je zauzeto"
-        not_a_number: "nije broj"
-        not_a_date: "nije ispravan datum"
-        greater_than: "mora bit veÄ‡i od %{count}"
-        greater_than_or_equal_to: "mora bit veÄ‡i ili jednak %{count}"
-        equal_to: "mora biti jednak %{count}"
-        less_than: "mora biti manji od %{count}"
-        less_than_or_equal_to: "mora bit manji ili jednak %{count}"
-        odd: "mora biti neparan"
-        even: "mora biti paran"
-        greater_than_start_date: "mora biti veÄ‡i nego poÄetni datum"
-        not_same_project: "ne pripada istom projektu"
-        circular_dependency: "Ova relacija stvar cirkularnu zavisnost"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: Molimo odaberite
-  
-  general_text_No: 'Da'
-  general_text_Yes: 'Ne'
-  general_text_no: 'ne'
-  general_text_yes: 'da'
-  general_lang_name: 'Bosanski'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '7'
-  
-  notice_account_activated: VaÅ¡ nalog je aktiviran. MoÅ¾ete se prijaviti.
-  notice_account_invalid_creditentials: PogreÅ¡an korisnik ili lozinka
-  notice_account_lost_email_sent: Email sa uputstvima o izboru nove Å¡ifre je poslat na vaÅ¡u adresu.
-  notice_account_password_updated: Lozinka je uspjeÅ¡no promjenjena.
-  notice_account_pending: "VaÅ¡ nalog je kreiran i Äeka odobrenje administratora."
-  notice_account_register_done: Nalog je uspjeÅ¡no kreiran. Da bi ste aktivirali vaÅ¡ nalog kliknite na link koji vam je poslat.
-  notice_account_unknown_email: Nepoznati korisnik.
-  notice_account_updated: Nalog je uspjeÅ¡no promjenen.
-  notice_account_wrong_password: PogreÅ¡na lozinka
-  notice_can_t_change_password: Ovaj nalog koristi eksterni izvor prijavljivanja. Ne mogu da promjenim Å¡ifru.
-  notice_default_data_loaded: Podrazumjevana konfiguracija uspjeÄno uÄitana.
-  notice_email_error: DoÅ¡lo je do greÅ¡ke pri slanju emaila (%{value})
-  notice_email_sent: "Email je poslan %{value}"
-  notice_failed_to_save_issues: "NeuspjeÅ¡no snimanje %{count} aktivnosti na %{total} izabrano: %{ids}."
-  notice_feeds_access_key_reseted: VaÅ¡ RSS pristup je resetovan.
-  notice_file_not_found: Stranica kojoj pokuÅ¡avate da pristupite ne postoji ili je uklonjena.
-  notice_locking_conflict: "Konflikt: podaci su izmjenjeni od strane drugog korisnika."
-  notice_no_issue_selected: "Nijedna aktivnost nije izabrana! Molim, izaberite aktivnosti koje Å¾elite za ispravljate."
-  notice_not_authorized: Niste ovlaÅ¡Ä‡eni da pristupite ovoj stranici.
-  notice_successful_connection: UspjeÅ¡na konekcija.
-  notice_successful_create: UspjeÅ¡no kreiranje.
-  notice_successful_delete: Brisanje izvrÅ¡eno.
-  notice_successful_update: Promjene uspjeÅ¡no izvrÅ¡ene.
-
-  error_can_t_load_default_data: "Podrazumjevane postavke se ne mogu uÄitati %{value}"
-  error_scm_command_failed: "Desila se greÅ¡ka pri pristupu repozitoriju: %{value}"
-  error_scm_not_found: "Unos i/ili revizija ne postoji u repozitoriju."
-
-  error_scm_annotate: "Ova stavka ne postoji ili nije oznaÄena."
-  error_issue_not_found_in_project: 'Aktivnost nije naÄ‘ena ili ne pripada ovom projektu'
-  
-  warning_attachments_not_saved: "%{count} fajl(ovi) ne mogu biti snimljen(i)."
-  
-  mail_subject_lost_password: "VaÅ¡a %{value} lozinka"
-  mail_body_lost_password: 'Za promjenu lozinke, kliknite na sljedeÄ‡i link:'
-  mail_subject_register: "Aktivirajte %{value} vaÅ¡ korisniÄki raÄun"
-  mail_body_register: 'Za aktivaciju vaÅ¡eg korisniÄkog raÄuna, kliknite na sljedeÄ‡i link:'
-  mail_body_account_information_external: "MoÅ¾ete koristiti  vaÅ¡ %{value} korisniÄki raÄun za prijavu na sistem."
-  mail_body_account_information: Informacija o vaÅ¡em korisniÄkom raÄunu
-  mail_subject_account_activation_request: "%{value} zahtjev za aktivaciju korisniÄkog raÄuna"
-  mail_body_account_activation_request: "Novi korisnik (%{value}) se registrovao. KorisniÄki raÄun Äeka vaÅ¡e odobrenje za aktivaciju:"
-  mail_subject_reminder: "%{count} aktivnost(i) u kaÅ¡njenju u narednim %{days} danima"
-  mail_body_reminder: "%{count} aktivnost(i) koje su dodjeljenje vama u narednim %{days} danima:"
-  
-  gui_validation_error: 1 greÅ¡ka
-  gui_validation_error_plural: "%{count} greÅ¡aka"
-  
-  field_name: Ime
-  field_description: Opis
-  field_summary: PojaÅ¡njenje
-  field_is_required: Neophodno popuniti
-  field_firstname: Ime
-  field_lastname: Prezime
-  field_mail: Email
-  field_filename: Fajl
-  field_filesize: VeliÄina
-  field_downloads: Downloadi
-  field_author: Autor
-  field_created_on: Kreirano
-  field_updated_on: Izmjenjeno
-  field_field_format: Format
-  field_is_for_all: Za sve projekte
-  field_possible_values: MoguÄ‡e vrijednosti
-  field_regexp: '"Regularni izraz"'
-  field_min_length: Minimalna veliÄina
-  field_max_length: Maksimalna veliÄina
-  field_value: Vrijednost
-  field_category: Kategorija
-  field_title: Naslov
-  field_project: Projekat
-  field_issue: Aktivnost
-  field_status: Status
-  field_notes: BiljeÅ¡ke
-  field_is_closed: Aktivnost zatvorena
-  field_is_default: Podrazumjevana vrijednost
-  field_tracker: PodruÄje aktivnosti
-  field_subject: Subjekat
-  field_due_date: ZavrÅ¡iti do
-  field_assigned_to: Dodijeljeno
-  field_priority: Prioritet
-  field_fixed_version: Ciljna verzija
-  field_user: Korisnik
-  field_role: Uloga
-  field_homepage: Naslovna strana
-  field_is_public: Javni
-  field_parent: Podprojekt od
-  field_is_in_roadmap: Aktivnosti prikazane u planu realizacije
-  field_login: Prijava
-  field_mail_notification: Email notifikacije
-  field_admin: Administrator
-  field_last_login_on: Posljednja konekcija
-  field_language: Jezik
-  field_effective_date: Datum
-  field_password: Lozinka
-  field_new_password: Nova lozinka
-  field_password_confirmation: Potvrda
-  field_version: Verzija
-  field_type: Tip
-  field_host: Host
-  field_port: Port
-  field_account: KorisniÄki raÄun
-  field_base_dn: Base DN
-  field_attr_login:  Attribut za prijavu
-  field_attr_firstname: Attribut za ime
-  field_attr_lastname: Atribut za prezime
-  field_attr_mail: Atribut za email
-  field_onthefly: 'Kreiranje korisnika "On-the-fly"'
-  field_start_date: PoÄetak
-  field_done_ratio: "% Realizovano"
-  field_auth_source: Mod za authentifikaciju
-  field_hide_mail: Sakrij moju email adresu
-  field_comments: Komentar
-  field_url: URL
-  field_start_page: PoÄetna stranica
-  field_subproject: Podprojekat
-  field_hours: Sahata
-  field_activity: Operacija
-  field_spent_on: Datum
-  field_identifier: Identifikator
-  field_is_filter: KoriÅ¡teno kao filter
-  field_issue_to: Povezana aktivnost
-  field_delay: OdgaÄ‘anje
-  field_assignable: Aktivnosti dodijeljene ovoj ulozi
-  field_redirect_existing_links: IzvrÅ¡i redirekciju postojeÄ‡ih linkova
-  field_estimated_hours: Procjena vremena
-  field_column_names: Kolone
-  field_time_zone: Vremenska zona
-  field_searchable: PretraÅ¾ivo
-  field_default_value: Podrazumjevana vrijednost
-  field_comments_sorting: PrikaÅ¾i komentare
-  field_parent_title: 'Stranica "roditelj"'
-  field_editable: MoÅ¾e se mijenjati
-  field_watcher: PosmatraÄ
-  field_identity_url: OpenID URL
-  field_content: SadrÅ¾aj
-  
-  setting_app_title: Naslov aplikacije
-  setting_app_subtitle: Podnaslov aplikacije
-  setting_welcome_text: Tekst dobrodoÅ¡lice
-  setting_default_language: Podrazumjevani jezik
-  setting_login_required: Authentifikacija neophodna
-  setting_self_registration: Samo-registracija
-  setting_attachment_max_size: Maksimalna veliÄina prikaÄenog fajla
-  setting_issues_export_limit: Limit za eksport aktivnosti
-  setting_mail_from: Mail adresa - poÅ¡aljilac
-  setting_bcc_recipients: '"BCC" (blind carbon copy) primaoci '
-  setting_plain_text_mail: Email sa obiÄnim tekstom (bez HTML-a)
-  setting_host_name: Ime hosta i putanja
-  setting_text_formatting: Formatiranje teksta
-  setting_wiki_compression: Kompresija Wiki istorije
-
-  setting_feeds_limit: 'Limit za "RSS" feed-ove'
-  setting_default_projects_public: Podrazumjeva se da je novi projekat javni
-  setting_autofetch_changesets: 'Automatski kupi "commit"-e'
-  setting_sys_api_enabled: 'OmoguÄ‡i "WS" za upravljanje repozitorijom'
-  setting_commit_ref_keywords: KljuÄne rijeÄi za reference
-  setting_commit_fix_keywords: 'KljuÄne rijeÄi za status "zatvoreno"'
-  setting_autologin: Automatski login
-  setting_date_format: Format datuma
-  setting_time_format: Format vremena
-  setting_cross_project_issue_relations: OmoguÄ‡i relacije izmeÄ‘u aktivnosti na razliÄitim projektima
-  setting_issue_list_default_columns: Podrazumjevane koleone za prikaz na listi aktivnosti
-  setting_emails_footer: Potpis na email-ovima
-  setting_protocol: Protokol
-  setting_per_page_options: Broj objekata po stranici
-  setting_user_format: Format korisniÄkog prikaza
-  setting_activity_days_default: Prikaz promjena na projektu - opseg dana
-  setting_display_subprojects_issues: Prikaz podprojekata na glavnom projektima (podrazumjeva se)
-  setting_enabled_scm: OmoguÄ‡i SCM (source code management)
-  setting_mail_handler_api_enabled: OmoguÄ‡i automatsku obradu ulaznih emailova
-  setting_mail_handler_api_key: API kljuÄ (obrada ulaznih mailova)
-  setting_sequential_project_identifiers: GeneriÅ¡i identifikatore projekta sekvencijalno
-  setting_gravatar_enabled: 'Koristi "gravatar" korisniÄke ikone'
-  setting_diff_max_lines_displayed: Maksimalan broj linija za prikaz razlika izmeÄ‘u dva fajla
-  setting_file_max_size_displayed: Maksimalna veliÄina fajla kod prikaza razlika unutar fajla (inline)
-  setting_repository_log_display_limit: Maksimalna veliÄina revizija prikazanih na log fajlu
-  setting_openid: OmoguÄ‡i OpenID prijavu i registraciju
-  
-  permission_edit_project: Ispravke projekta
-  permission_select_project_modules: Odaberi module projekta
-  permission_manage_members: Upravljanje Älanovima
-  permission_manage_versions: Upravljanje verzijama
-  permission_manage_categories: Upravljanje kategorijama aktivnosti
-  permission_add_issues: Dodaj aktivnosti
-  permission_edit_issues: Ispravka aktivnosti
-  permission_manage_issue_relations: Upravljaj relacijama meÄ‘u aktivnostima
-  permission_add_issue_notes: Dodaj biljeÅ¡ke
-  permission_edit_issue_notes: Ispravi biljeÅ¡ke
-  permission_edit_own_issue_notes: Ispravi sopstvene biljeÅ¡ke
-  permission_move_issues: Pomjeri aktivnosti
-  permission_delete_issues: IzbriÅ¡i aktivnosti
-  permission_manage_public_queries: Upravljaj javnim upitima
-  permission_save_queries: Snimi upite
-  permission_view_gantt: Pregled gantograma
-  permission_view_calendar: Pregled kalendara
-  permission_view_issue_watchers: Pregled liste korisnika koji prate aktivnost
-  permission_add_issue_watchers: Dodaj onoga koji prati aktivnost
-  permission_log_time: Evidentiraj utroÅ¡ak vremena
-  permission_view_time_entries: Pregled utroÅ¡ka vremena
-  permission_edit_time_entries: Ispravka utroÅ¡ka vremena
-  permission_edit_own_time_entries: Ispravka svog utroÅ¡ka vremena
-  permission_manage_news: Upravljaj novostima
-  permission_comment_news: Komentiraj novosti
-  permission_manage_documents: Upravljaj dokumentima
-  permission_view_documents: Pregled dokumenata
-  permission_manage_files: Upravljaj fajlovima
-  permission_view_files: Pregled fajlova
-  permission_manage_wiki: Upravljaj wiki stranicama
-  permission_rename_wiki_pages: Ispravi wiki stranicu
-  permission_delete_wiki_pages: IzbriÅ¡i wiki stranicu
-  permission_view_wiki_pages: Pregled wiki sadrÅ¾aja
-  permission_view_wiki_edits: Pregled wiki istorije
-  permission_edit_wiki_pages: Ispravka wiki stranica
-  permission_delete_wiki_pages_attachments: Brisanje fajlova prikaÄenih wiki-ju
-  permission_protect_wiki_pages: ZaÅ¡titi wiki stranicu
-  permission_manage_repository: Upravljaj repozitorijem
-  permission_browse_repository: Pregled repozitorija
-  permission_view_changesets: Pregled setova promjena
-  permission_commit_access: 'Pristup "commit"-u'
-  permission_manage_boards: Upravljaj forumima
-  permission_view_messages: Pregled poruka
-  permission_add_messages: Å alji poruke
-  permission_edit_messages: Ispravi poruke
-  permission_edit_own_messages: Ispravka sopstvenih poruka
-  permission_delete_messages: Prisanje poruka
-  permission_delete_own_messages: Brisanje sopstvenih poruka
-  
-  project_module_issue_tracking: PraÄ‡enje aktivnosti
-  project_module_time_tracking: PraÄ‡enje vremena
-  project_module_news: Novosti
-  project_module_documents: Dokumenti
-  project_module_files: Fajlovi
-  project_module_wiki: Wiki stranice
-  project_module_repository: Repozitorij
-  project_module_boards: Forumi
-  
-  label_user: Korisnik
-  label_user_plural: Korisnici
-  label_user_new: Novi korisnik
-  label_project: Projekat
-  label_project_new: Novi projekat
-  label_project_plural: Projekti
-  label_x_projects:
-    zero:  0 projekata
-    one:   1 projekat
-    other: "%{count} projekata"
-  label_project_all: Svi projekti
-  label_project_latest: Posljednji projekti
-  label_issue: Aktivnost
-  label_issue_new: Nova aktivnost
-  label_issue_plural: Aktivnosti
-  label_issue_view_all: Vidi sve aktivnosti
-  label_issues_by: "Aktivnosti po %{value}"
-  label_issue_added: Aktivnost je dodana
-  label_issue_updated: Aktivnost je izmjenjena
-  label_document: Dokument
-  label_document_new: Novi dokument
-  label_document_plural: Dokumenti
-  label_document_added: Dokument je dodan
-  label_role: Uloga
-  label_role_plural: Uloge
-  label_role_new: Nove uloge
-  label_role_and_permissions: Uloge i dozvole
-  label_member: IzvrÅ¡ilac
-  label_member_new: Novi izvrÅ¡ilac
-  label_member_plural: IzvrÅ¡ioci
-  label_tracker: PodruÄje aktivnosti
-  label_tracker_plural: PodruÄja aktivnosti
-  label_tracker_new: Novo podruÄje aktivnosti
-  label_workflow: Tok promjena na aktivnosti
-  label_issue_status: Status aktivnosti
-  label_issue_status_plural: Statusi aktivnosti
-  label_issue_status_new: Novi status
-  label_issue_category: Kategorija aktivnosti
-  label_issue_category_plural: Kategorije aktivnosti
-  label_issue_category_new: Nova kategorija
-  label_custom_field: Proizvoljno polje
-  label_custom_field_plural: Proizvoljna polja
-  label_custom_field_new: Novo proizvoljno polje
-  label_enumerations: Enumeracije
-  label_enumeration_new: Nova vrijednost
-  label_information: Informacija
-  label_information_plural: Informacije
-  label_please_login: Molimo prijavite se
-  label_register: Registracija
-  label_login_with_open_id_option: ili prijava sa OpenID-om
-  label_password_lost: Izgubljena lozinka
-  label_home: PoÄetna stranica
-  label_my_page: Moja stranica
-  label_my_account: Moj korisniÄki raÄun
-  label_my_projects: Moji projekti
-  label_administration: Administracija
-  label_login: Prijavi se
-  label_logout: Odjavi se
-  label_help: PomoÄ‡
-  label_reported_issues: Prijavljene aktivnosti
-  label_assigned_to_me_issues: Aktivnosti dodjeljene meni
-  label_last_login: Posljednja konekcija
-  label_registered_on: Registrovan na
-  label_activity_plural: Promjene
-  label_activity: Operacija
-  label_overall_activity: Pregled svih promjena
-  label_user_activity: "Promjene izvrÅ¡ene od: %{value}"
-  label_new: Novi
-  label_logged_as: Prijavljen kao
-  label_environment: Sistemsko okruÅ¾enje
-  label_authentication: Authentifikacija
-  label_auth_source: Mod authentifikacije
-  label_auth_source_new: Novi mod authentifikacije
-  label_auth_source_plural: Modovi authentifikacije
-  label_subproject_plural: Podprojekti
-  label_and_its_subprojects: "%{value} i njegovi podprojekti"
-  label_min_max_length: Min - Maks duÅ¾ina
-  label_list: Lista
-  label_date: Datum
-  label_integer: Cijeli broj
-  label_float: Float
-  label_boolean: LogiÄka varijabla
-  label_string: Tekst
-  label_text: Dugi tekst
-  label_attribute: Atribut
-  label_attribute_plural: Atributi
-  label_download: "%{count} download"
-  label_download_plural: "%{count} download-i"
-  label_no_data: Nema podataka za prikaz
-  label_change_status: Promjeni status
-  label_history: Istorija
-  label_attachment: Fajl
-  label_attachment_new: Novi fajl
-  label_attachment_delete: IzbriÅ¡i fajl
-  label_attachment_plural: Fajlovi
-  label_file_added: Fajl je dodan
-  label_report: IzvjeÅ¡taj
-  label_report_plural: IzvjeÅ¡taji
-  label_news: Novosti
-  label_news_new: Dodaj novosti
-  label_news_plural: Novosti
-  label_news_latest: Posljednje novosti
-  label_news_view_all: Pogledaj sve novosti
-  label_news_added: Novosti su dodane
-  label_settings: Postavke
-  label_overview: Pregled
-  label_version: Verzija
-  label_version_new: Nova verzija
-  label_version_plural: Verzije
-  label_confirmation: Potvrda
-  label_export_to: 'TakoÄ‘e dostupno u:'
-  label_read: ÄŒitaj...
-  label_public_projects: Javni projekti
-  label_open_issues: otvoren
-  label_open_issues_plural: otvoreni
-  label_closed_issues: zatvoren
-  label_closed_issues_plural: zatvoreni
-  label_x_open_issues_abbr_on_total:
-    zero:  0 otvoreno / %{total}
-    one:   1 otvorena / %{total}
-    other: "%{count} otvorene / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 otvoreno
-    one:   1 otvorena
-    other: "%{count} otvorene"
-  label_x_closed_issues_abbr:
-    zero:  0 zatvoreno
-    one:   1 zatvorena
-    other: "%{count} zatvorene"
-  label_total: Ukupno
-  label_permissions: Dozvole
-  label_current_status: TekuÄ‡i status
-  label_new_statuses_allowed: Novi statusi dozvoljeni
-  label_all: sve
-  label_none: niÅ¡ta
-  label_nobody: niko
-  label_next: SljedeÄ‡e
-  label_previous: Predhodno
-  label_used_by: KoriÅ¡teno od
-  label_details: Detalji
-  label_add_note: Dodaj biljeÅ¡ku
-  label_per_page: Po stranici
-  label_calendar: Kalendar
-  label_months_from: mjeseci od
-  label_gantt: Gantt
-  label_internal: Interno
-  label_last_changes: "posljednjih %{count} promjena"
-  label_change_view_all: Vidi sve promjene
-  label_personalize_page: Personaliziraj ovu stranicu
-  label_comment: Komentar
-  label_comment_plural: Komentari
-  label_x_comments:
-    zero: bez komentara
-    one: 1 komentar
-    other: "%{count} komentari"
-  label_comment_add: Dodaj komentar
-  label_comment_added: Komentar je dodan
-  label_comment_delete: IzbriÅ¡i komentar
-  label_query: Proizvoljan upit
-  label_query_plural: Proizvoljni upiti
-  label_query_new: Novi upit
-  label_filter_add: Dodaj filter
-  label_filter_plural: Filteri
-  label_equals: je
-  label_not_equals: nije
-  label_in_less_than: je manji nego
-  label_in_more_than: je viÅ¡e nego
-  label_in: u
-  label_today: danas
-  label_all_time: sve vrijeme
-  label_yesterday: juÄe
-  label_this_week: ova hefta
-  label_last_week: zadnja hefta
-  label_last_n_days: "posljednjih %{count} dana"
-  label_this_month: ovaj mjesec
-  label_last_month: posljednji mjesec
-  label_this_year: ova godina
-  label_date_range: Datumski opseg
-  label_less_than_ago: ranije nego (dana)
-  label_more_than_ago: starije nego (dana)
-  label_ago: prije (dana)
-  label_contains: sadrÅ¾i
-  label_not_contains: ne sadrÅ¾i
-  label_day_plural: dani
-  label_repository: Repozitorij
-  label_repository_plural: Repozitoriji
-  label_browse: Listaj
-  label_modification: "%{count} promjena"
-  label_modification_plural: "%{count} promjene"
-  label_revision: Revizija
-  label_revision_plural: Revizije
-  label_associated_revisions: Doddjeljene revizije
-  label_added: dodano
-  label_modified: izmjenjeno
-  label_copied: kopirano
-  label_renamed: preimenovano
-  label_deleted: izbrisano
-  label_latest_revision: Posljednja revizija
-  label_latest_revision_plural: Posljednje revizije
-  label_view_revisions: Vidi revizije
-  label_max_size: Maksimalna veliÄina
-  label_sort_highest: Pomjeri na vrh
-  label_sort_higher: Pomjeri gore
-  label_sort_lower: Pomjeri dole
-  label_sort_lowest: Pomjeri na dno
-  label_roadmap: Plan realizacije
-  label_roadmap_due_in: "Obavezan do %{value}"
-  label_roadmap_overdue: "%{value} kasni"
-  label_roadmap_no_issues: Nema aktivnosti za ovu verziju
-  label_search: TraÅ¾i
-  label_result_plural: Rezultati
-  label_all_words: Sve rijeÄi
-  label_wiki: Wiki stranice
-  label_wiki_edit: ispravka wiki-ja
-  label_wiki_edit_plural: ispravke wiki-ja
-  label_wiki_page: Wiki stranica
-  label_wiki_page_plural: Wiki stranice
-  label_index_by_title: Indeks prema naslovima
-  label_index_by_date: Indeks po datumima
-  label_current_version: TekuÄ‡a verzija
-  label_preview: Pregled
-  label_feed_plural: Feeds
-  label_changes_details: Detalji svih promjena
-  label_issue_tracking: Evidencija aktivnosti
-  label_spent_time: UtroÅ¡ak vremena
-  label_f_hour: "%{value} sahat"
-  label_f_hour_plural: "%{value} sahata"
-  label_time_tracking: Evidencija vremena
-  label_change_plural: Promjene
-  label_statistics: Statistika
-  label_commits_per_month: '"Commit"-a po mjesecu'
-  label_commits_per_author: '"Commit"-a po autoru'
-  label_view_diff: Pregled razlika
-  label_diff_inline: zajedno
-  label_diff_side_by_side: jedna pored druge
-  label_options: Opcije
-  label_copy_workflow_from: Kopiraj tok promjena statusa iz
-  label_permissions_report: IzvjeÅ¡taj
-  label_watched_issues: Aktivnosti koje pratim
-  label_related_issues: Korelirane aktivnosti
-  label_applied_status: Status je primjenjen
-  label_loading: UÄitavam...
-  label_relation_new: Nova relacija
-  label_relation_delete: IzbriÅ¡i relaciju
-  label_relates_to: korelira sa
-  label_duplicates: duplikat
-  label_duplicated_by: duplicirano od
-  label_blocks: blokira
-  label_blocked_by: blokirano on
-  label_precedes: predhodi
-  label_follows: slijedi
-  label_end_to_start: 'kraj -> poÄetak'
-  label_end_to_end: 'kraja -> kraj'
-  label_start_to_start: 'poÄetak -> poÄetak'
-  label_start_to_end: 'poÄetak -> kraj'
-  label_stay_logged_in: Ostani prijavljen
-  label_disabled: onemoguÄ‡en
-  label_show_completed_versions: PrikaÅ¾i zavrÅ¡ene verzije
-  label_me: ja
-  label_board: Forum
-  label_board_new: Novi forum
-  label_board_plural: Forumi
-  label_topic_plural: Teme
-  label_message_plural: Poruke
-  label_message_last: Posljednja poruka
-  label_message_new: Nova poruka
-  label_message_posted: Poruka je dodana
-  label_reply_plural: Odgovori
-  label_send_information: PoÅ¡alji informaciju o korisniÄkom raÄunu
-  label_year: Godina
-  label_month: Mjesec
-  label_week: Hefta
-  label_date_from: Od
-  label_date_to: Do
-  label_language_based: Bazirano na korisnikovom jeziku
-  label_sort_by: "Sortiraj po %{value}"
-  label_send_test_email: PoÅ¡alji testni email
-  label_feeds_access_key_created_on: "RSS pristupni kljuÄ kreiran prije %{value} dana"
-  label_module_plural: Moduli
-  label_added_time_by: "Dodano od %{author} prije %{age}"
-  label_updated_time_by: "Izmjenjeno od %{author} prije %{age}"
-  label_updated_time: "Izmjenjeno prije %{value}"
-  label_jump_to_a_project: SkoÄi na projekat...
-  label_file_plural: Fajlovi
-  label_changeset_plural: Setovi promjena
-  label_default_columns: Podrazumjevane kolone
-  label_no_change_option: (Bez promjene)
-  label_bulk_edit_selected_issues: Ispravi odjednom odabrane aktivnosti
-  label_theme: Tema
-  label_default: Podrazumjevano
-  label_search_titles_only: PretraÅ¾i samo naslove
-  label_user_mail_option_all: "Za bilo koji dogaÄ‘aj na svim mojim projektima"
-  label_user_mail_option_selected: "Za bilo koji dogaÄ‘aj na odabranim projektima..."
-  label_user_mail_no_self_notified: "Ne Å¾elim notifikaciju za promjene koje sam ja napravio"
-  label_registration_activation_by_email: aktivacija korisniÄkog raÄuna email-om
-  label_registration_manual_activation: ruÄna aktivacija korisniÄkog raÄuna
-  label_registration_automatic_activation: automatska kreacija korisniÄkog raÄuna
-  label_display_per_page: "Po stranici: %{value}"
-  label_age: Starost
-  label_change_properties: Promjena osobina
-  label_general: Generalno
-  label_more: ViÅ¡e
-  label_scm: SCM
-  label_plugins: Plugin-ovi
-  label_ldap_authentication: LDAP authentifikacija
-  label_downloads_abbr: D/L
-  label_optional_description: Opis (opciono)
-  label_add_another_file: Dodaj joÅ¡ jedan fajl
-  label_preferences: Postavke
-  label_chronological_order: HronoloÅ¡ki poredak
-  label_reverse_chronological_order: Reverzni hronoloÅ¡ki poredak
-  label_planning: Planiranje
-  label_incoming_emails: Dolazni email-ovi
-  label_generate_key: GeneriÅ¡i kljuÄ
-  label_issue_watchers: PraÄ‡eno od 
-  label_example: Primjer
-  label_display: Prikaz
-
-  button_apply: Primjeni
-  button_add: Dodaj
-  button_archive: Arhiviranje
-  button_back: Nazad
-  button_cancel: Odustani
-  button_change: Izmjeni
-  button_change_password: Izmjena lozinke
-  button_check_all: OznaÄi sve
-  button_clear: BriÅ¡i
-  button_copy: Kopiraj
-  button_create: Novi
-  button_delete: BriÅ¡i
-  button_download: Download
-  button_edit: Ispravka
-  button_list: Lista
-  button_lock: ZakljuÄaj
-  button_log_time: UtroÅ¡ak vremena
-  button_login: Prijava
-  button_move: Pomjeri
-  button_rename: Promjena imena
-  button_reply: Odgovor
-  button_reset: Resetuj
-  button_rollback: Vrati predhodno stanje
-  button_save: Snimi
-  button_sort: Sortiranje
-  button_submit: PoÅ¡alji
-  button_test: Testiraj
-  button_unarchive: Otpakuj arhivu
-  button_uncheck_all: IskljuÄi sve
-  button_unlock: OtkljuÄaj
-  button_unwatch: Prekini notifikaciju
-  button_update: Promjena na aktivnosti
-  button_view: Pregled
-  button_watch: Notifikacija
-  button_configure: Konfiguracija
-  button_quote: Citat
-  
-  status_active: aktivan
-  status_registered: registrovan
-  status_locked: zakljuÄan
-  
-  text_select_mail_notifications: Odaberi dogaÄ‘aje za koje Ä‡e se slati email notifikacija.
-  text_regexp_info: npr. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 znaÄi bez restrikcije
-  text_project_destroy_confirmation: Sigurno Å¾elite izbrisati ovaj projekat i njegove podatke ?
-  text_subprojects_destroy_warning: "Podprojekt(i): %{value} Ä‡e takoÄ‘e biti izbrisani."
-  text_workflow_edit: Odaberite ulogu i podruÄje aktivnosti za ispravku toka promjena na aktivnosti
-  text_are_you_sure: Da li ste sigurni ?
-  text_tip_issue_begin_day: zadatak poÄinje danas
-  text_tip_issue_end_day: zadatak zavrÅ¡ava danas
-  text_tip_issue_begin_end_day: zadatak zapoÄinje i zavrÅ¡ava danas
-  text_project_identifier_info: 'Samo mala slova (a-z), brojevi i crtice su dozvoljeni.<br />Nakon snimanja, identifikator se ne moÅ¾e mijenjati.'
-  text_caracters_maximum: "maksimum %{count} karaktera."
-  text_caracters_minimum: "DuÅ¾ina mora biti najmanje %{count} znakova."
-  text_length_between: "Broj znakova izmeÄ‘u %{min} i %{max}."
-  text_tracker_no_workflow: Tok statusa nije definisan za ovo podruÄje aktivnosti
-  text_unallowed_characters: Nedozvoljeni znakovi
-  text_comma_separated: ViÅ¡estruke vrijednosti dozvoljene (odvojiti zarezom).
-  text_issues_ref_in_commit_messages: 'Referenciranje i zatvaranje aktivnosti putem "commit" poruka'
-  text_issue_added: "Aktivnost %{id} je prijavljena od %{author}."
-  text_issue_updated: "Aktivnost %{id} je izmjenjena od %{author}."
-  text_wiki_destroy_confirmation: Sigurno Å¾elite izbrisati ovaj wiki i Äitav njegov sadrÅ¾aj ?
-  text_issue_category_destroy_question: "Neke aktivnosti (%{count}) pripadaju ovoj kategoriji. Sigurno to Å¾elite uraditi ?"
-  text_issue_category_destroy_assignments: Ukloni kategoriju
-  text_issue_category_reassign_to: Ponovo dodijeli ovu kategoriju
-  text_user_mail_option: "Za projekte koje niste odabrali, primiÄ‡ete samo notifikacije o stavkama koje pratite ili ste u njih ukljuÄeni (npr. vi ste autor ili su vama dodjeljenje)."
-  text_no_configuration_data: "Uloge, podruÄja aktivnosti, statusi aktivnosti i tok promjena statusa nisu konfigurisane.\nKrajnje je preporuÄeno da uÄitate tekuÄ‘e postavke. Kasnije Ä‡ete ih moÄ‡i mjenjati po svojim potrebama."
-  text_load_default_configuration: UÄitaj tekuÄ‡u konfiguraciju
-  text_status_changed_by_changeset: "Primjenjeno u setu promjena %{value}."
-  text_issues_destroy_confirmation: 'Sigurno Å¾elite izbrisati odabranu/e aktivnost/i ?'
-  text_select_project_modules: 'Odaberi module koje Å¾elite u ovom projektu:'
-  text_default_administrator_account_changed: TekuÄ‡i administratorski raÄun je promjenjen
-  text_file_repository_writable: U direktorij sa fajlovima koji su prilozi se moÅ¾e pisati
-  text_plugin_assets_writable: U direktorij plugin-ova se moÅ¾e pisati
-  text_rmagick_available: RMagick je dostupan (opciono)
-  text_destroy_time_entries_question: "%{hours} sahata je prijavljeno na aktivnostima koje Å¾elite brisati. Å½elite li to uÄiniti ?"
-  text_destroy_time_entries: IzbriÅ¡i prijavljeno vrijeme
-  text_assign_time_entries_to_project: Dodaj prijavljenoo vrijeme projektu
-  text_reassign_time_entries: 'Preraspodjeli prijavljeno vrijeme na ovu aktivnost:'
-  text_user_wrote: "%{value} je napisao/la:"
-  text_enumeration_destroy_question: "Za %{count} objekata je dodjeljenja ova vrijednost."
-  text_enumeration_category_reassign_to: 'Ponovo im dodjeli ovu vrijednost:'
-  text_email_delivery_not_configured: "Email dostava nije konfiguraisana, notifikacija je onemoguÄ‡ena.\nKonfiguriÅ¡i SMTP server u config/configuration.yml i restartuj aplikaciju nakon toga."
-  text_repository_usernames_mapping: "Odaberi ili ispravi redmine korisnika mapiranog za svako korisniÄko ima naÄ‘eno u logu repozitorija.\nKorisnici sa istim imenom u redmineu i u repozitoruju se automatski mapiraju."
-  text_diff_truncated: '... Ovaj prikaz razlike je odsjeÄen poÅ¡to premaÅ¡uje maksimalnu veliÄinu za prikaz'
-  text_custom_field_possible_values_info: 'Jedna linija za svaku vrijednost'
-  
-  default_role_manager: MenadÅ¾er
-  default_role_developer: Programer
-  default_role_reporter: Reporter
-  default_tracker_bug: GreÅ¡ka
-  default_tracker_feature: Nova funkcija
-  default_tracker_support: PodrÅ¡ka
-  default_issue_status_new: Novi
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: RijeÅ¡en
-  default_issue_status_feedback: ÄŒeka se povratna informacija
-  default_issue_status_closed: Zatvoren
-  default_issue_status_rejected: Odbijen
-  default_doc_category_user: KorisniÄka dokumentacija
-  default_doc_category_tech: TehniÄka dokumentacija
-  default_priority_low: Nizak
-  default_priority_normal: Normalan
-  default_priority_high: Visok
-  default_priority_urgent: Urgentno
-  default_priority_immediate: Odmah
-  default_activity_design: Dizajn
-  default_activity_development: Programiranje
-  
-  enumeration_issue_priorities: Prioritet aktivnosti
-  enumeration_doc_categories: Kategorije dokumenata
-  enumeration_activities: Operacije (utroÅ¡ak vremena)
-  notice_unable_delete_version: Ne mogu izbrisati verziju.
-  button_create_and_continue: Kreiraj i nastavi
-  button_annotate: ZabiljeÅ¾i
-  button_activate: Aktiviraj
-  label_sort: Sortiranje
-  label_date_from_to: Od %{start} do %{end}
-  label_ascending: RastuÄ‡e
-  label_descending: OpadajuÄ‡e
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
-  text_wiki_page_reassign_children: Reassign child pages to this parent page
-  text_wiki_page_nullify_children: Keep child pages as root pages
-  text_wiki_page_destroy_children: Delete child pages and all their descendants
-  setting_password_min_length: Minimum password length
-  field_group_by: Group results by
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  label_wiki_content_added: Wiki page added
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
-  label_wiki_content_updated: Wiki page updated
-  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
-  permission_add_project: Create project
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  label_view_all_revisions: View all revisions
-  label_tag: Tag
-  label_branch: Branch
-  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
-  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
-  text_journal_changed: "%{label} changed from %{old} to %{new}"
-  text_journal_set_to: "%{label} set to %{value}"
-  text_journal_deleted: "%{label} deleted (%{old})"
-  label_group_plural: Groups
-  label_group: Group
-  label_group_new: New group
-  label_time_entry_plural: Spent time
-  text_journal_added: "%{label} %{value} added"
-  field_active: Active
-  enumeration_system_activity: System Activity
-  permission_delete_issue_watchers: Delete watchers
-  version_status_closed: closed
-  version_status_locked: locked
-  version_status_open: open
-  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
-  label_user_anonymous: Anonymous
-  button_move_and_follow: Move and follow
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_gravatar_default: Default Gravatar image
-  field_sharing: Sharing
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_system: With all projects
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_tree: With project tree
-  label_version_sharing_none: Not shared
-  error_can_not_archive_project: This project can not be archived
-  button_duplicate: Duplicate
-  button_copy_and_follow: Copy and follow
-  label_copy_source: Source
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Same as target
-  label_copy_target: Target
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  error_workflow_copy_source: Please select a source tracker or role
-  label_update_issue_done_ratios: Update issue done ratios
-  setting_start_of_week: Start calendars on
-  permission_view_issues: View Issues
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API access key
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_missing_api_access_key: Missing an API access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  button_show: Show
-  text_line_separated: Multiple values allowed (one line for each value).
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: 'Enkodiranje "commit" poruka'
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7f/7f4c045aa51ecaded0b2c44282890f940876ab00.svn-base
--- /dev/null
+++ b/.svn/pristine/7f/7f4c045aa51ecaded0b2c44282890f940876ab00.svn-base
@@ -0,0 +1,35 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingFilesTest < ActionController::IntegrationTest
+  def test_files
+    assert_routing(
+        { :method => 'get', :path => "/projects/33/files" },
+        { :controller => 'files', :action => 'index', :project_id => '33' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/33/files/new" },
+        { :controller => 'files', :action => 'new', :project_id => '33' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/33/files" },
+        { :controller => 'files', :action => 'create', :project_id => '33' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7f/7f793d123c11e16acd2d74a86ee6e86fa59cf1d2.svn-base
--- a/.svn/pristine/7f/7f793d123c11e16acd2d74a86ee6e86fa59cf1d2.svn-base
+++ /dev/null
@@ -1,97 +0,0 @@
-== Redmine installation
-
-Redmine - project management software
-Copyright (C) 2006-2011  Jean-Philippe Lang
-http://www.redmine.org/
-
-
-== Requirements
-
-* Ruby 1.8.6 or 1.8.7
-
-* RubyGems 1.3.7
-
-* Ruby on Rails 2.3.14 (official downloadable Redmine releases are packaged with
-  the appropriate Rails version)
-
-* Rack 1.1.2 gem
-
-* Rake 0.9.2 gem
-
-* I18n 0.4.2 gem
-
-* A database:
-  * MySQL (tested with MySQL 5.1)
-  * PostgreSQL (tested with PostgreSQL 8.4)
-  * SQLite3 (tested with SQLite 3.6)
-
-Optional:
-* SCM binaries (e.g. svn), for repository browsing (must be available in PATH)
-* RMagick (to enable Gantt export to png images)
-* Ruby OpenID Library >= version 2 (to enable OpenID support)
-
-== Installation
-
-1. Uncompress the program archive
-
-2. Create an empty database: "redmine" for example
-
-3. Configure the database parameters in config/database.yml
-   for the "production" environment (default database is MySQL)
-
-4. Generate a session store secret
-   
-   Redmine stores session data in cookies by default, which requires
-   a secret to be generated. Under the application main directory run:
-     rake generate_session_store
-
-5. Create the database structure
-   
-   Under the application main directory run:
-     rake db:migrate RAILS_ENV="production"
-   
-   It will create all the tables and an administrator account.
-
-6. Setting up permissions (Windows users have to skip this section)
-   
-   The user who runs Redmine must have write permission on the following
-   subdirectories: files, log, tmp & public/plugin_assets (create the last
-   two if they are not yet present).
-   
-   Assuming you run Redmine with a user named "redmine":
-     mkdir tmp public/plugin_assets
-     sudo chown -R redmine:redmine files log tmp public/plugin_assets
-     sudo chmod -R 755 files log tmp public/plugin_assets
-
-7. Test the installation by running the WEBrick web server
-   
-   Under the main application directory run:
-     ruby script/server -e production
-   
-   Once WEBrick has started, point your browser to http://localhost:3000/
-   You should now see the application welcome page.
-
-8. Use the default administrator account to log in:
-   login: admin
-   password: admin
-   
-   Go to "Administration" to load the default configuration data (roles,
-   trackers, statuses, workflow) and to adjust the application settings
-
-== SMTP server Configuration
-
-Copy config/configuration.yml.example to config/configuration.yml and
-edit this file to adjust your SMTP settings.
-Do not forget to restart the application after any change to this file.
-
-Please do not enter your SMTP settings in environment.rb.
-
-== References
-
-* http://www.redmine.org/wiki/redmine/RedmineInstall
-* http://www.redmine.org/wiki/redmine/EmailConfiguration
-* http://www.redmine.org/wiki/redmine/RedmineSettings
-* http://www.redmine.org/wiki/redmine/RedmineRepositories
-* http://www.redmine.org/wiki/redmine/RedmineReceivingEmails
-* http://www.redmine.org/wiki/redmine/RedmineReminderEmails
-* http://www.redmine.org/wiki/redmine/RedmineLDAP
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/7f/7fd2e45fcd400139b222df563299c0b121c16798.svn-base
--- a/.svn/pristine/7f/7fd2e45fcd400139b222df563299c0b121c16798.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= l(:label_query_new) %></h2>
-
-<% form_tag(@project ? project_queries_path : queries_path, :onsubmit => 'selectAllOptions("selected_columns");') do %>
-  <%= render :partial => 'form', :locals => {:query => @query} %>
-  <%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/80/801b8da4e3d5456a0e7124a4e9736317dd235f5b.svn-base
--- /dev/null
+++ b/.svn/pristine/80/801b8da4e3d5456a0e7124a4e9736317dd235f5b.svn-base
@@ -0,0 +1,377 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoryMercurialTest < ActiveSupport::TestCase
+  fixtures :projects
+
+  include Redmine::I18n
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
+  NUM_REV = 32
+  CHAR_1_HEX = "\xc3\x9c"
+
+  def setup
+    @project    = Project.find(3)
+    @repository = Repository::Mercurial.create(
+                      :project => @project,
+                      :url     => REPOSITORY_PATH,
+                      :path_encoding => 'ISO-8859-1'
+                      )
+    assert @repository
+    @char_1        = CHAR_1_HEX.dup
+    @tag_char_1    = "tag-#{CHAR_1_HEX}-00"
+    @branch_char_0 = "branch-#{CHAR_1_HEX}-00"
+    @branch_char_1 = "branch-#{CHAR_1_HEX}-01"
+    if @char_1.respond_to?(:force_encoding)
+      @char_1.force_encoding('UTF-8')
+      @tag_char_1.force_encoding('UTF-8')
+      @branch_char_0.force_encoding('UTF-8')
+      @branch_char_1.force_encoding('UTF-8')
+    end
+  end
+
+
+  def test_blank_path_to_repository_error_message
+    set_language_if_valid 'en'
+    repo = Repository::Mercurial.new(
+                          :project      => @project,
+                          :identifier   => 'test'
+                        )
+    assert !repo.save
+    assert_include "Path to repository can't be blank",
+                   repo.errors.full_messages
+  end
+
+  def test_blank_path_to_repository_error_message_fr
+    set_language_if_valid 'fr'
+    str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    repo = Repository::Mercurial.new(
+                          :project      => @project,
+                          :url          => "",
+                          :identifier   => 'test',
+                          :path_encoding => ''
+                        )
+    assert !repo.save
+    assert_include str, repo.errors.full_messages
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    def test_scm_available
+      klass = Repository::Mercurial
+      assert_equal "Mercurial", klass.scm_name
+      assert klass.scm_adapter_class
+      assert_not_equal "", klass.scm_command
+      assert_equal true, klass.scm_available
+    end
+
+    def test_entries
+      entries = @repository.entries
+      assert_kind_of Redmine::Scm::Adapters::Entries, entries
+    end
+
+    def test_fetch_changesets_from_scratch
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_equal 46, @repository.filechanges.count
+      assert_equal "Initial import.\nThe repository contains 3 files.",
+                   @repository.changesets.find_by_revision('0').comments
+    end
+
+    def test_fetch_changesets_incremental
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      # Remove changesets with revision > 2
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 2}
+      @project.reload
+      assert_equal 3, @repository.changesets.count
+
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+    end
+
+    def test_isodatesec
+      # Template keyword 'isodatesec' supported in Mercurial 1.0 and higher
+      if @repository.scm.class.client_version_above?([1, 0])
+        assert_equal 0, @repository.changesets.count
+        @repository.fetch_changesets
+        @project.reload
+        assert_equal NUM_REV, @repository.changesets.count
+        rev0_committed_on = Time.gm(2007, 12, 14, 9, 22, 52)
+        assert_equal @repository.changesets.find_by_revision('0').committed_on, rev0_committed_on
+      end
+    end
+
+    def test_changeset_order_by_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      c0 = @repository.latest_changeset
+      c1 = @repository.changesets.find_by_revision('0')
+      # sorted by revision (id), not by date
+      assert c0.revision.to_i > c1.revision.to_i
+      assert c0.committed_on  < c1.committed_on
+    end
+
+    def test_latest_changesets
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      # with_limit
+      changesets = @repository.latest_changesets('', nil, 2)
+      assert_equal %w|31 30|, changesets.collect(&:revision)
+
+      # with_filepath
+      changesets = @repository.latest_changesets(
+                      '/sql_escape/percent%dir/percent%file1.txt', nil)
+      assert_equal %w|30 11 10 9|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets(
+                      '/sql_escape/underscore_dir/understrike_file.txt', nil)
+      assert_equal %w|30 12 9|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README', nil)
+      assert_equal %w|31 30 28 17 8 6 1 0|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README','8')
+      assert_equal %w|8 6 1 0|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('README','8', 2)
+      assert_equal %w|8 6|, changesets.collect(&:revision)
+
+      # with_dirpath
+      changesets = @repository.latest_changesets('images', nil)
+      assert_equal %w|1 0|, changesets.collect(&:revision)
+
+      path = 'sql_escape/percent%dir'
+      changesets = @repository.latest_changesets(path, nil)
+      assert_equal %w|30 13 11 10 9|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets(path, '11')
+      assert_equal %w|11 10 9|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets(path, '11', 2)
+      assert_equal %w|11 10|, changesets.collect(&:revision)
+
+      path = 'sql_escape/underscore_dir'
+      changesets = @repository.latest_changesets(path, nil)
+      assert_equal %w|30 13 12 9|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets(path, '12')
+      assert_equal %w|12 9|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets(path, '12', 1)
+      assert_equal %w|12|, changesets.collect(&:revision)
+
+      # tag
+      changesets = @repository.latest_changesets('', 'tag_test.00')
+      assert_equal %w|5 4 3 2 1 0|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('', 'tag_test.00', 2)
+      assert_equal %w|5 4|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('sources', 'tag_test.00')
+      assert_equal %w|4 3 2 1 0|, changesets.collect(&:revision)
+
+      changesets = @repository.latest_changesets('sources', 'tag_test.00', 2)
+      assert_equal %w|4 3|, changesets.collect(&:revision)
+
+      # named branch
+      if @repository.scm.class.client_version_above?([1, 6])
+        changesets = @repository.latest_changesets('', @branch_char_1)
+        assert_equal %w|27 26|, changesets.collect(&:revision)
+      end
+
+      changesets = @repository.latest_changesets("latin-1-dir/test-#{@char_1}-subdir", @branch_char_1)
+      assert_equal %w|27|, changesets.collect(&:revision)
+    end
+
+    def test_copied_files
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      cs1 = @repository.changesets.find_by_revision('13')
+      assert_not_nil cs1
+      c1  = cs1.filechanges.sort_by(&:path)
+      assert_equal 2, c1.size
+
+      assert_equal 'A', c1[0].action
+      assert_equal '/sql_escape/percent%dir/percentfile1.txt',  c1[0].path
+      assert_equal '/sql_escape/percent%dir/percent%file1.txt', c1[0].from_path
+      assert_equal '3a330eb32958', c1[0].from_revision
+
+      assert_equal 'A', c1[1].action
+      assert_equal '/sql_escape/underscore_dir/understrike-file.txt', c1[1].path
+      assert_equal '/sql_escape/underscore_dir/understrike_file.txt', c1[1].from_path
+
+      cs2 = @repository.changesets.find_by_revision('15')
+      c2  = cs2.filechanges
+      assert_equal 1, c2.size
+
+      assert_equal 'A', c2[0].action
+      assert_equal '/README (1)[2]&,%.-3_4', c2[0].path
+      assert_equal '/README', c2[0].from_path
+      assert_equal '933ca60293d7', c2[0].from_revision
+
+      cs3 = @repository.changesets.find_by_revision('19')
+      c3  = cs3.filechanges
+      assert_equal 1, c3.size
+      assert_equal 'A', c3[0].action
+      assert_equal "/latin-1-dir/test-#{@char_1}-1.txt",  c3[0].path
+      assert_equal "/latin-1-dir/test-#{@char_1}.txt",    c3[0].from_path
+      assert_equal '5d9891a1b425', c3[0].from_revision
+    end
+
+    def test_find_changeset_by_name
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      %w|2 400bb8672109 400|.each do |r|
+        assert_equal '2', @repository.find_changeset_by_name(r).revision
+      end
+    end
+
+    def test_find_changeset_by_invalid_name
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_nil @repository.find_changeset_by_name('100000')
+    end
+
+    def test_identifier
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      c = @repository.changesets.find_by_revision('2')
+      assert_equal c.scmid, c.identifier
+    end
+
+    def test_format_identifier
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      c = @repository.changesets.find_by_revision('2')
+      assert_equal '2:400bb8672109', c.format_identifier
+    end
+
+    def test_find_changeset_by_empty_name
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['', ' ', nil].each do |r|
+        assert_nil @repository.find_changeset_by_name(r)
+      end
+    end
+
+    def test_parents
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      r1 = @repository.changesets.find_by_revision('0')
+      assert_equal [], r1.parents
+      r2 = @repository.changesets.find_by_revision('1')
+      assert_equal 1, r2.parents.length
+      assert_equal "0885933ad4f6",
+                   r2.parents[0].identifier
+      r3 = @repository.changesets.find_by_revision('30')
+      assert_equal 2, r3.parents.length
+      r4 = [r3.parents[0].identifier, r3.parents[1].identifier].sort
+      assert_equal "3a330eb32958", r4[0]
+      assert_equal "a94b0528f24f", r4[1]
+    end
+
+    def test_activities
+      c = Changeset.new(:repository   => @repository,
+                        :committed_on => Time.now,
+                        :revision     => '123',
+                        :scmid        => 'abc400bb8672',
+                        :comments     => 'test')
+      assert c.event_title.include?('123:abc400bb8672:')
+      assert_equal 'abc400bb8672', c.event_url[:rev]
+    end
+
+    def test_previous
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      %w|28 3ae45e2d177d 3ae45|.each do |r1|
+        changeset = @repository.find_changeset_by_name(r1)
+        %w|27 7bbf4c738e71 7bbf|.each do |r2|
+          assert_equal @repository.find_changeset_by_name(r2), changeset.previous
+        end
+      end
+    end
+
+    def test_previous_nil
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      %w|0 0885933ad4f6 0885|.each do |r1|
+        changeset = @repository.find_changeset_by_name(r1)
+        assert_nil changeset.previous
+      end
+    end
+
+    def test_next
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      %w|27 7bbf4c738e71 7bbf|.each do |r2|
+        changeset = @repository.find_changeset_by_name(r2)
+        %w|28 3ae45e2d177d 3ae45|.each do |r1|
+        assert_equal @repository.find_changeset_by_name(r1), changeset.next
+        end
+      end
+    end
+
+    def test_next_nil
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      %w|31 31eeee7395c8 31eee|.each do |r1|
+        changeset = @repository.find_changeset_by_name(r1)
+        assert_nil changeset.next
+      end
+    end
+  else
+    puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/80/8038f5899dbf50a50f4a5b31cb29861746dd574c.svn-base
--- /dev/null
+++ b/.svn/pristine/80/8038f5899dbf50a50f4a5b31cb29861746dd574c.svn-base
@@ -0,0 +1,51 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::TrackersTest < Redmine::ApiTest::Base
+  fixtures :trackers
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "/trackers" do
+    context "GET" do
+
+      should "return trackers" do
+        get '/trackers.xml'
+
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+        assert_tag :tag => 'trackers',
+          :attributes => {:type => 'array'},
+          :child => {
+            :tag => 'tracker',
+            :child => {
+              :tag => 'id',
+              :content => '2',
+              :sibling => {
+                :tag => 'name',
+                :content => 'Feature request'
+              }
+            }
+          }
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/80/803dbec2bea6411200938908113051447e1d81f1.svn-base
--- /dev/null
+++ b/.svn/pristine/80/803dbec2bea6411200938908113051447e1d81f1.svn-base
@@ -0,0 +1,173 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'digest/md5'
+
+module Redmine
+  module WikiFormatting
+    class StaleSectionError < Exception; end
+
+    @@formatters = {}
+
+    class << self
+      def map
+        yield self
+      end
+
+      def register(name, formatter, helper)
+        raise ArgumentError, "format name '#{name}' is already taken" if @@formatters[name.to_s]
+        @@formatters[name.to_s] = {:formatter => formatter, :helper => helper}
+      end
+
+      def formatter
+        formatter_for(Setting.text_formatting)
+      end
+
+      def formatter_for(name)
+        entry = @@formatters[name.to_s]
+        (entry && entry[:formatter]) || Redmine::WikiFormatting::NullFormatter::Formatter
+      end
+
+      def helper_for(name)
+        entry = @@formatters[name.to_s]
+        (entry && entry[:helper]) || Redmine::WikiFormatting::NullFormatter::Helper
+      end
+
+      def format_names
+        @@formatters.keys.map
+      end
+
+      def to_html(format, text, options = {})
+        text = if Setting.cache_formatted_text? && text.size > 2.kilobyte && cache_store && cache_key = cache_key_for(format, text, options[:object], options[:attribute])
+          # Text retrieved from the cache store may be frozen
+          # We need to dup it so we can do in-place substitutions with gsub!
+          cache_store.fetch cache_key do
+            formatter_for(format).new(text).to_html
+          end.dup
+        else
+          formatter_for(format).new(text).to_html
+        end
+        text
+      end
+
+      # Returns true if the text formatter supports single section edit
+      def supports_section_edit?
+        (formatter.instance_methods & ['update_section', :update_section]).any?
+      end
+
+      # Returns a cache key for the given text +format+, +text+, +object+ and +attribute+ or nil if no caching should be done
+      def cache_key_for(format, text, object, attribute)
+        if object && attribute && !object.new_record? && format.present?
+          "formatted_text/#{format}/#{object.class.model_name.cache_key}/#{object.id}-#{attribute}-#{Digest::MD5.hexdigest text}"
+        end
+      end
+
+      # Returns the cache store used to cache HTML output
+      def cache_store
+        ActionController::Base.cache_store
+      end
+    end
+
+    module LinksHelper
+      AUTO_LINK_RE = %r{
+                      (                          # leading text
+                        <\w+.*?>|                # leading HTML tag, or
+                        [\s\(\[,;]|              # leading punctuation, or
+                        ^                        # beginning of line
+                      )
+                      (
+                        (?:https?://)|           # protocol spec, or
+                        (?:s?ftps?://)|
+                        (?:www\.)                # www.*
+                      )
+                      (
+                        ([^<]\S*?)               # url
+                        (\/)?                    # slash
+                      )
+                      ((?:&gt;)?|[^[:alnum:]_\=\/;\(\)]*?)               # post
+                      (?=<|\s|$)
+                     }x unless const_defined?(:AUTO_LINK_RE)
+
+      # Destructively remplaces urls into clickable links
+      def auto_link!(text)
+        text.gsub!(AUTO_LINK_RE) do
+          all, leading, proto, url, post = $&, $1, $2, $3, $6
+          if leading =~ /<a\s/i || leading =~ /![<>=]?/
+            # don't replace URL's that are already linked
+            # and URL's prefixed with ! !> !< != (textile images)
+            all
+          else
+            # Idea below : an URL with unbalanced parethesis and
+            # ending by ')' is put into external parenthesis
+            if ( url[-1]==?) and ((url.count("(") - url.count(")")) < 0 ) )
+              url=url[0..-2] # discard closing parenth from url
+              post = ")"+post # add closing parenth to post
+            end
+            content = proto + url
+            href = "#{proto=="www."?"http://www.":proto}#{url}"
+            %(#{leading}<a class="external" href="#{ERB::Util.html_escape href}">#{ERB::Util.html_escape content}</a>#{post}).html_safe
+          end
+        end
+      end
+
+      # Destructively remplaces email addresses into clickable links
+      def auto_mailto!(text)
+        text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
+          mail = $1
+          if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/)
+            mail
+          else
+            %(<a class="email" href="mailto:#{ERB::Util.html_escape mail}">#{ERB::Util.html_escape mail}</a>).html_safe
+          end
+        end
+      end      
+    end
+
+    # Default formatter module
+    module NullFormatter
+      class Formatter
+        include ActionView::Helpers::TagHelper
+        include ActionView::Helpers::TextHelper
+        include ActionView::Helpers::UrlHelper
+        include Redmine::WikiFormatting::LinksHelper
+
+        def initialize(text)
+          @text = text
+        end
+
+        def to_html(*args)
+          t = CGI::escapeHTML(@text)
+          auto_link!(t)
+          auto_mailto!(t)
+          simple_format(t, {}, :sanitize => false)
+        end
+      end
+
+      module Helper
+        def wikitoolbar_for(field_id)
+        end
+
+        def heads_for_wiki_formatter
+        end
+
+        def initial_page_content(page)
+          page.pretty_title.to_s
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/80/805a8b03f317de442787ef8a23fd231ec228a620.svn-base
--- a/.svn/pristine/80/805a8b03f317de442787ef8a23fd231ec228a620.svn-base
+++ /dev/null
@@ -1,77 +0,0 @@
-# ActsAsWatchable
-module Redmine
-  module Acts
-    module Watchable
-      def self.included(base) 
-        base.extend ClassMethods
-      end 
-
-      module ClassMethods
-        def acts_as_watchable(options = {})
-          return if self.included_modules.include?(Redmine::Acts::Watchable::InstanceMethods)          
-          send :include, Redmine::Acts::Watchable::InstanceMethods
-          
-          class_eval do
-            has_many :watchers, :as => :watchable, :dependent => :delete_all
-            has_many :watcher_users, :through => :watchers, :source => :user, :validate => false
-            
-            named_scope :watched_by, lambda { |user_id|
-              { :include => :watchers,
-                :conditions => ["#{Watcher.table_name}.user_id = ?", user_id] }
-            }
-            attr_protected :watcher_ids, :watcher_user_ids
-          end
-        end
-      end
-
-      module InstanceMethods
-        def self.included(base)
-          base.extend ClassMethods
-        end
-        
-        # Returns an array of users that are proposed as watchers
-        def addable_watcher_users
-          users = self.project.users.sort - self.watcher_users
-          if respond_to?(:visible?)
-            users.reject! {|user| !visible?(user)}
-          end
-          users
-        end
-        
-        # Adds user as a watcher
-        def add_watcher(user)
-          self.watchers << Watcher.new(:user => user)
-        end
-        
-        # Removes user from the watchers list
-        def remove_watcher(user)
-          return nil unless user && user.is_a?(User)
-          Watcher.delete_all "watchable_type = '#{self.class}' AND watchable_id = #{self.id} AND user_id = #{user.id}"
-        end
-        
-        # Adds/removes watcher
-        def set_watcher(user, watching=true)
-          watching ? add_watcher(user) : remove_watcher(user)
-        end
-        
-        # Returns true if object is watched by +user+
-        def watched_by?(user)
-          !!(user && self.watcher_user_ids.detect {|uid| uid == user.id })
-        end
-        
-        # Returns an array of watchers' email addresses
-        def watcher_recipients
-          notified = watcher_users.active
-          notified.reject! {|user| user.mail_notification == 'none'}
-          
-          if respond_to?(:visible?)
-            notified.reject! {|user| !visible?(user)}
-          end
-          notified.collect(&:mail).compact
-        end
-
-        module ClassMethods; end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/80/808c2b8d656d91389ca1e0955ebdc3c622ab9ac0.svn-base
--- a/.svn/pristine/80/808c2b8d656d91389ca1e0955ebdc3c622ab9ac0.svn-base
+++ /dev/null
@@ -1,42 +0,0 @@
-<h2><%= @query.new_record? ? l(:label_calendar) : h(@query.name) %></h2>
-
-<% form_tag({:controller => 'calendars', :action => 'show', :project_id => @project}, :method => :get, :id => 'query_form') do %>
-<%= hidden_field_tag 'set_filter', '1' %>
-<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
-  <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
-  <div style="<%= @query.new_record? ? "" : "display: none;" %>">
-    <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
-  </div>
-</fieldset>
-
-<p style="float:right;">
-  <%= link_to_previous_month(@year, @month) %> | <%= link_to_next_month(@year, @month) %>
-</p>
-
-<p class="buttons">
-<%= label_tag('month', l(:label_month)) %>
-<%= select_month(@month, :prefix => "month", :discard_type => true) %>
-<%= label_tag('year', l(:label_year)) %>
-<%= select_year(@year, :prefix => "year", :discard_type => true) %>
-
-<%= link_to_function l(:button_apply), '$("query_form").submit()', :class => 'icon icon-checked' %>
-<%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 }, :class => 'icon icon-reload' %>
-</p>
-<% end %>
-
-<%= error_messages_for 'query' %>
-<% if @query.valid? %>
-<%= render :partial => 'common/calendar', :locals => {:calendar => @calendar} %>
-
-<p class="legend cal">
-  <span class="starting"><%= l(:text_tip_issue_begin_day) %></span>
-  <span class="ending"><%= l(:text_tip_issue_end_day) %></span>
-  <span class="starting ending"><%= l(:text_tip_issue_begin_end_day) %></span>
-</p>
-<% end %>
-
-<% content_for :sidebar do %>
-    <%= render :partial => 'issues/sidebar' %>
-<% end %>
-
-<% html_title(l(:label_calendar)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/80/80cc012f0ec91e8ef1adc8047efcacc9dac1c803.svn-base
--- a/.svn/pristine/80/80cc012f0ec91e8ef1adc8047efcacc9dac1c803.svn-base
+++ /dev/null
@@ -1,52 +0,0 @@
-<h2><%= link_to l(:label_role_plural), :controller => 'roles', :action => 'index' %> &#187; <%=l(:label_permissions_report)%></h2>
-
-<% form_tag({:action => 'report'}, :id => 'permissions_form') do %>
-<%= hidden_field_tag 'permissions[0]', '', :id => nil %>
-<div class="autoscroll">
-<table class="list">
-<thead>
-    <tr>
-    <th><%=l(:label_permissions)%></th>
-    <% @roles.each do |role| %>
-    <th>
-        <%= content_tag(role.builtin? ? 'em' : 'span', h(role.name)) %>
-        <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('input.role-#{role.id}')",
-                                                            :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
-    </th>
-    <% end %>
-    </tr>
-</thead>
-<tbody>
-<% perms_by_module = @permissions.group_by {|p| p.project_module.to_s} %>
-<% perms_by_module.keys.sort.each do |mod| %>
-    <% unless mod.blank? %>
-        <tr class="group open">
-          <td colspan="<%= @roles.size + 1 %>">
-            <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
-            <%= l_or_humanize(mod, :prefix => 'project_module_') %>
-          </td>
-        </tr>
-    <% end %>
-    <% perms_by_module[mod].each do |permission| %>
-        <tr class="<%= cycle('odd', 'even') %> permission-<%= permission.name %>">
-        <td>
-            <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('.permission-#{permission.name} input')",
-                                                                :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
-            <%= l_or_humanize(permission.name, :prefix => 'permission_') %>
-        </td>
-        <% @roles.each do |role| %>
-        <td align="center">
-        <% if role.setable_permissions.include? permission %>
-          <%= check_box_tag "permissions[#{role.id}][]", permission.name, (role.permissions.include? permission.name), :id => nil, :class => "role-#{role.id}" %>
-        <% end %>
-        </td>
-        <% end %>
-        </tr>
-    <% end %>
-<% end %>
-</tbody>
-</table>
-</div>
-<p><%= check_all_links 'permissions_form' %></p>
-<p><%= submit_tag l(:button_save) %></p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/81/81172b2094c31db1f0abe25641889634ec935550.svn-base
--- a/.svn/pristine/81/81172b2094c31db1f0abe25641889634ec935550.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-<%= javascript_include_tag "raphael.js" %>
-<script type="text/javascript" charset="utf-8">
-  var chunk = {commits:<%= commits.values.to_json %>}
-</script>
-<%= javascript_include_tag "revision_graph.js" %>
-
-<script type="text/javascript">
-  Event.observe(window,"load", function(){
-    branchGraph(document.getElementById("holder"));
-  })
-</script>
-
-<div id="holder" class="graph"></div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/81/811f1ba6d3aa9ff895b79ad6fc02919805520105.svn-base
--- a/.svn/pristine/81/811f1ba6d3aa9ff895b79ad6fc02919805520105.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-# just here so that Rails recognizes this as a plugin
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/81/815073e9f3bcaa80c2a4ee60b82257dc8dc26440.svn-base
--- a/.svn/pristine/81/815073e9f3bcaa80c2a4ee60b82257dc8dc26440.svn-base
+++ /dev/null
@@ -1,1195 +0,0 @@
-#                                vim:ts=4:sw=4:
-# = RedCloth - Textile and Markdown Hybrid for Ruby
-#
-# Homepage::  http://whytheluckystiff.net/ruby/redcloth/
-# Author::    why the lucky stiff (http://whytheluckystiff.net/)
-# Copyright:: (cc) 2004 why the lucky stiff (and his puppet organizations.)
-# License::   BSD
-#
-# (see http://hobix.com/textile/ for a Textile Reference.)
-#
-# Based on (and also inspired by) both:
-#
-# PyTextile: http://diveintomark.org/projects/textile/textile.py.txt
-# Textism for PHP: http://www.textism.com/tools/textile/
-#
-#
-
-# = RedCloth
-#
-# RedCloth is a Ruby library for converting Textile and/or Markdown
-# into HTML.  You can use either format, intermingled or separately.
-# You can also extend RedCloth to honor your own custom text stylings.
-#
-# RedCloth users are encouraged to use Textile if they are generating
-# HTML and to use Markdown if others will be viewing the plain text.
-#
-# == What is Textile?
-#
-# Textile is a simple formatting style for text
-# documents, loosely based on some HTML conventions.
-#
-# == Sample Textile Text
-#
-#  h2. This is a title
-#
-#  h3. This is a subhead
-#
-#  This is a bit of paragraph.
-#
-#  bq. This is a blockquote.
-#
-# = Writing Textile
-#
-# A Textile document consists of paragraphs.  Paragraphs
-# can be specially formatted by adding a small instruction
-# to the beginning of the paragraph.
-#
-#  h[n].   Header of size [n].
-#  bq.     Blockquote.
-#  #       Numeric list.
-#  *       Bulleted list.
-#
-# == Quick Phrase Modifiers
-#
-# Quick phrase modifiers are also included, to allow formatting
-# of small portions of text within a paragraph.
-#
-#  \_emphasis\_
-#  \_\_italicized\_\_
-#  \*strong\*
-#  \*\*bold\*\*
-#  ??citation??
-#  -deleted text-
-#  +inserted text+
-#  ^superscript^
-#  ~subscript~
-#  @code@
-#  %(classname)span%
-#
-#  ==notextile== (leave text alone)
-#
-# == Links
-#
-# To make a hypertext link, put the link text in "quotation 
-# marks" followed immediately by a colon and the URL of the link.
-# 
-# Optional: text in (parentheses) following the link text, 
-# but before the closing quotation mark, will become a Title 
-# attribute for the link, visible as a tool tip when a cursor is above it.
-# 
-# Example:
-#
-#  "This is a link (This is a title) ":http://www.textism.com
-# 
-# Will become:
-# 
-#  <a href="http://www.textism.com" title="This is a title">This is a link</a>
-#
-# == Images
-#
-# To insert an image, put the URL for the image inside exclamation marks.
-#
-# Optional: text that immediately follows the URL in (parentheses) will 
-# be used as the Alt text for the image. Images on the web should always 
-# have descriptive Alt text for the benefit of readers using non-graphical 
-# browsers.
-#
-# Optional: place a colon followed by a URL immediately after the 
-# closing ! to make the image into a link.
-# 
-# Example:
-#
-#  !http://www.textism.com/common/textist.gif(Textist)!
-#
-# Will become:
-#
-#  <img src="http://www.textism.com/common/textist.gif" alt="Textist" />
-#
-# With a link:
-#
-#  !/common/textist.gif(Textist)!:http://textism.com
-#
-# Will become:
-#
-#  <a href="http://textism.com"><img src="/common/textist.gif" alt="Textist" /></a>
-#
-# == Defining Acronyms
-#
-# HTML allows authors to define acronyms via the tag. The definition appears as a 
-# tool tip when a cursor hovers over the acronym. A crucial aid to clear writing, 
-# this should be used at least once for each acronym in documents where they appear.
-#
-# To quickly define an acronym in Textile, place the full text in (parentheses) 
-# immediately following the acronym.
-# 
-# Example:
-#
-#  ACLU(American Civil Liberties Union)
-#
-# Will become:
-#
-#  <acronym title="American Civil Liberties Union">ACLU</acronym>
-#
-# == Adding Tables
-#
-# In Textile, simple tables can be added by seperating each column by
-# a pipe.
-#
-#     |a|simple|table|row|
-#     |And|Another|table|row|
-#
-# Attributes are defined by style definitions in parentheses.
-#
-#     table(border:1px solid black).
-#     (background:#ddd;color:red). |{}| | | |
-#
-# == Using RedCloth
-# 
-# RedCloth is simply an extension of the String class, which can handle
-# Textile formatting.  Use it like a String and output HTML with its
-# RedCloth#to_html method.
-#
-#  doc = RedCloth.new "
-#
-#  h2. Test document
-#
-#  Just a simple test."
-#
-#  puts doc.to_html
-#
-# By default, RedCloth uses both Textile and Markdown formatting, with
-# Textile formatting taking precedence.  If you want to turn off Markdown
-# formatting, to boost speed and limit the processor:
-#
-#  class RedCloth::Textile.new( str )
-
-class RedCloth3 < String
-
-    VERSION = '3.0.4'
-    DEFAULT_RULES = [:textile, :markdown]
-
-    #
-    # Two accessor for setting security restrictions.
-    #
-    # This is a nice thing if you're using RedCloth for
-    # formatting in public places (e.g. Wikis) where you
-    # don't want users to abuse HTML for bad things.
-    #
-    # If +:filter_html+ is set, HTML which wasn't
-    # created by the Textile processor will be escaped.
-    #
-    # If +:filter_styles+ is set, it will also disable
-    # the style markup specifier. ('{color: red}')
-    #
-    attr_accessor :filter_html, :filter_styles
-
-    #
-    # Accessor for toggling hard breaks.
-    #
-    # If +:hard_breaks+ is set, single newlines will
-    # be converted to HTML break tags.  This is the
-    # default behavior for traditional RedCloth.
-    #
-    attr_accessor :hard_breaks
-
-    # Accessor for toggling lite mode.
-    #
-    # In lite mode, block-level rules are ignored.  This means
-    # that tables, paragraphs, lists, and such aren't available.
-    # Only the inline markup for bold, italics, entities and so on.
-    #
-    #   r = RedCloth.new( "And then? She *fell*!", [:lite_mode] )
-    #   r.to_html
-    #   #=> "And then? She <strong>fell</strong>!"
-    #
-    attr_accessor :lite_mode
-
-    #
-    # Accessor for toggling span caps.
-    #
-    # Textile places `span' tags around capitalized
-    # words by default, but this wreaks havoc on Wikis.
-    # If +:no_span_caps+ is set, this will be
-    # suppressed.
-    #
-    attr_accessor :no_span_caps
-
-    #
-    # Establishes the markup predence.  Available rules include:
-    #
-    # == Textile Rules
-    #
-    # The following textile rules can be set individually.  Or add the complete
-    # set of rules with the single :textile rule, which supplies the rule set in
-    # the following precedence:
-    #
-    # refs_textile::          Textile references (i.e. [hobix]http://hobix.com/)
-    # block_textile_table::   Textile table block structures
-    # block_textile_lists::   Textile list structures
-    # block_textile_prefix::  Textile blocks with prefixes (i.e. bq., h2., etc.)
-    # inline_textile_image::  Textile inline images
-    # inline_textile_link::   Textile inline links
-    # inline_textile_span::   Textile inline spans
-    # glyphs_textile:: Textile entities (such as em-dashes and smart quotes)
-    #
-    # == Markdown
-    #
-    # refs_markdown::         Markdown references (for example: [hobix]: http://hobix.com/)
-    # block_markdown_setext:: Markdown setext headers
-    # block_markdown_atx::    Markdown atx headers
-    # block_markdown_rule::   Markdown horizontal rules
-    # block_markdown_bq::     Markdown blockquotes
-    # block_markdown_lists::  Markdown lists
-    # inline_markdown_link::  Markdown links
-    attr_accessor :rules
-
-    # Returns a new RedCloth object, based on _string_ and
-    # enforcing all the included _restrictions_.
-    #
-    #   r = RedCloth.new( "h1. A <b>bold</b> man", [:filter_html] )
-    #   r.to_html
-    #     #=>"<h1>A &lt;b&gt;bold&lt;/b&gt; man</h1>"
-    #
-    def initialize( string, restrictions = [] )
-        restrictions.each { |r| method( "#{ r }=" ).call( true ) }
-        super( string )
-    end
-
-    #
-    # Generates HTML from the Textile contents.
-    #
-    #   r = RedCloth.new( "And then? She *fell*!" )
-    #   r.to_html( true )
-    #     #=>"And then? She <strong>fell</strong>!"
-    #
-    def to_html( *rules )
-        rules = DEFAULT_RULES if rules.empty?
-        # make our working copy
-        text = self.dup
-        
-        @urlrefs = {}
-        @shelf = []
-        textile_rules = [:block_textile_table, :block_textile_lists,
-                         :block_textile_prefix, :inline_textile_image, :inline_textile_link,
-                         :inline_textile_code, :inline_textile_span, :glyphs_textile]
-        markdown_rules = [:refs_markdown, :block_markdown_setext, :block_markdown_atx, :block_markdown_rule,
-                          :block_markdown_bq, :block_markdown_lists, 
-                          :inline_markdown_reflink, :inline_markdown_link]
-        @rules = rules.collect do |rule|
-            case rule
-            when :markdown
-                markdown_rules
-            when :textile
-                textile_rules
-            else
-                rule
-            end
-        end.flatten
-
-        # standard clean up
-        incoming_entities text 
-        clean_white_space text 
-
-        # start processor
-        @pre_list = []
-        rip_offtags text
-        no_textile text
-        escape_html_tags text
-        # need to do this before #hard_break and #blocks
-        block_textile_quotes text unless @lite_mode
-        hard_break text 
-        unless @lite_mode
-            refs text
-            blocks text
-        end
-        inline text
-        smooth_offtags text
-
-        retrieve text
-
-        text.gsub!( /<\/?notextile>/, '' )
-        text.gsub!( /x%x%/, '&#38;' )
-        clean_html text if filter_html
-        text.strip!
-        text
-
-    end
-
-    #######
-    private
-    #######
-    #
-    # Mapping of 8-bit ASCII codes to HTML numerical entity equivalents.
-    # (from PyTextile)
-    #
-    TEXTILE_TAGS =
-
-        [[128, 8364], [129, 0], [130, 8218], [131, 402], [132, 8222], [133, 8230], 
-         [134, 8224], [135, 8225], [136, 710], [137, 8240], [138, 352], [139, 8249], 
-         [140, 338], [141, 0], [142, 0], [143, 0], [144, 0], [145, 8216], [146, 8217], 
-         [147, 8220], [148, 8221], [149, 8226], [150, 8211], [151, 8212], [152, 732], 
-         [153, 8482], [154, 353], [155, 8250], [156, 339], [157, 0], [158, 0], [159, 376]].
-
-        collect! do |a, b|
-            [a.chr, ( b.zero? and "" or "&#{ b };" )]
-        end
-
-    #
-    # Regular expressions to convert to HTML.
-    #
-    A_HLGN = /(?:(?:<>|<|>|\=|[()]+)+)/
-    A_VLGN = /[\-^~]/
-    C_CLAS = '(?:\([^")]+\))'
-    C_LNGE = '(?:\[[^"\[\]]+\])'
-    C_STYL = '(?:\{[^"}]+\})'
-    S_CSPN = '(?:\\\\\d+)'
-    S_RSPN = '(?:/\d+)'
-    A = "(?:#{A_HLGN}?#{A_VLGN}?|#{A_VLGN}?#{A_HLGN}?)"
-    S = "(?:#{S_CSPN}?#{S_RSPN}|#{S_RSPN}?#{S_CSPN}?)"
-    C = "(?:#{C_CLAS}?#{C_STYL}?#{C_LNGE}?|#{C_STYL}?#{C_LNGE}?#{C_CLAS}?|#{C_LNGE}?#{C_STYL}?#{C_CLAS}?)"
-    # PUNCT = Regexp::quote( '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' )
-    PUNCT = Regexp::quote( '!"#$%&\'*+,-./:;=?@\\^_`|~' )
-    PUNCT_NOQ = Regexp::quote( '!"#$&\',./:;=?@\\`|' )
-    PUNCT_Q = Regexp::quote( '*-_+^~%' )
-    HYPERLINK = '(\S+?)([^\w\s/;=\?]*?)(?=\s|<|$)'
-
-    # Text markup tags, don't conflict with block tags
-    SIMPLE_HTML_TAGS = [
-        'tt', 'b', 'i', 'big', 'small', 'em', 'strong', 'dfn', 'code', 
-        'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'a', 'img', 'br',
-        'br', 'map', 'q', 'sub', 'sup', 'span', 'bdo'
-    ]
-
-    QTAGS = [
-        ['**', 'b', :limit],
-        ['*', 'strong', :limit],
-        ['??', 'cite', :limit],
-        ['-', 'del', :limit],
-        ['__', 'i', :limit],
-        ['_', 'em', :limit],
-        ['%', 'span', :limit],
-        ['+', 'ins', :limit],
-        ['^', 'sup', :limit],
-        ['~', 'sub', :limit]
-    ] 
-    QTAGS_JOIN = QTAGS.map {|rc, ht, rtype| Regexp::quote rc}.join('|')
-    
-    QTAGS.collect! do |rc, ht, rtype|
-        rcq = Regexp::quote rc
-        re =
-            case rtype
-            when :limit
-                /(^|[>\s\(])          # sta
-                (?!\-\-)
-                (#{QTAGS_JOIN}|)      # oqs
-                (#{rcq})              # qtag
-                (\w|[^\s].*?[^\s])    # content
-                (?!\-\-)
-                #{rcq}
-                (#{QTAGS_JOIN}|)      # oqa
-                (?=[[:punct:]]|<|\s|\)|$)/x
-            else
-                /(#{rcq})
-                (#{C})
-                (?::(\S+))?
-                (\w|[^\s\-].*?[^\s\-])
-                #{rcq}/xm 
-            end
-        [rc, ht, re, rtype]
-    end
-
-    # Elements to handle
-    GLYPHS = [
-    #   [ /([^\s\[{(>])?\'([dmst]\b|ll\b|ve\b|\s|:|$)/, '\1&#8217;\2' ], # single closing
-    #   [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)\'/, '\1&#8217;' ], # single closing
-    #   [ /\'(?=[#{PUNCT_Q}]*(s\b|[\s#{PUNCT_NOQ}]))/, '&#8217;' ], # single closing
-    #   [ /\'/, '&#8216;' ], # single opening
-    #   [ /</, '&lt;' ], # less-than
-    #   [ />/, '&gt;' ], # greater-than
-    #   [ /([^\s\[{(])?"(\s|:|$)/, '\1&#8221;\2' ], # double closing
-    #   [ /([^\s\[{(>#{PUNCT_Q}][#{PUNCT_Q}]*)"/, '\1&#8221;' ], # double closing
-    #   [ /"(?=[#{PUNCT_Q}]*[\s#{PUNCT_NOQ}])/, '&#8221;' ], # double closing
-    #   [ /"/, '&#8220;' ], # double opening
-    #   [ /\b( )?\.{3}/, '\1&#8230;' ], # ellipsis
-    #   [ /\b([A-Z][A-Z0-9]{2,})\b(?:[(]([^)]*)[)])/, '<acronym title="\2">\1</acronym>' ], # 3+ uppercase acronym
-    #   [ /(^|[^"][>\s])([A-Z][A-Z0-9 ]+[A-Z0-9])([^<A-Za-z0-9]|$)/, '\1<span class="caps">\2</span>\3', :no_span_caps ], # 3+ uppercase caps
-    #   [ /(\.\s)?\s?--\s?/, '\1&#8212;' ], # em dash
-    #   [ /\s->\s/, ' &rarr; ' ], # right arrow
-    #   [ /\s-\s/, ' &#8211; ' ], # en dash
-    #   [ /(\d+) ?x ?(\d+)/, '\1&#215;\2' ], # dimension sign
-    #   [ /\b ?[(\[]TM[\])]/i, '&#8482;' ], # trademark
-    #   [ /\b ?[(\[]R[\])]/i, '&#174;' ], # registered
-    #   [ /\b ?[(\[]C[\])]/i, '&#169;' ] # copyright
-    ]
-
-    H_ALGN_VALS = {
-        '<' => 'left',
-        '=' => 'center',
-        '>' => 'right',
-        '<>' => 'justify'
-    }
-
-    V_ALGN_VALS = {
-        '^' => 'top',
-        '-' => 'middle',
-        '~' => 'bottom'
-    }
-
-    #
-    # Flexible HTML escaping
-    #
-    def htmlesc( str, mode=:Quotes )
-      if str
-        str.gsub!( '&', '&amp;' )
-        str.gsub!( '"', '&quot;' ) if mode != :NoQuotes
-        str.gsub!( "'", '&#039;' ) if mode == :Quotes
-        str.gsub!( '<', '&lt;')
-        str.gsub!( '>', '&gt;')
-      end
-      str
-    end
-
-    # Search and replace for Textile glyphs (quotes, dashes, other symbols)
-    def pgl( text )
-        #GLYPHS.each do |re, resub, tog|
-        #    next if tog and method( tog ).call
-        #    text.gsub! re, resub
-        #end
-        text.gsub!(/\b([A-Z][A-Z0-9]{1,})\b(?:[(]([^)]*)[)])/) do |m|
-          "<acronym title=\"#{htmlesc $2}\">#{$1}</acronym>"
-        end
-    end
-
-    # Parses Textile attribute lists and builds an HTML attribute string
-    def pba( text_in, element = "" )
-        
-        return '' unless text_in
-
-        style = []
-        text = text_in.dup
-        if element == 'td'
-            colspan = $1 if text =~ /\\(\d+)/
-            rowspan = $1 if text =~ /\/(\d+)/
-            style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN
-        end
-
-        style << "#{ htmlesc $1 };" if text.sub!( /\{([^}]*)\}/, '' ) && !filter_styles
-
-        lang = $1 if
-            text.sub!( /\[([^)]+?)\]/, '' )
-
-        cls = $1 if
-            text.sub!( /\(([^()]+?)\)/, '' )
-                        
-        style << "padding-left:#{ $1.length }em;" if
-            text.sub!( /([(]+)/, '' )
-
-        style << "padding-right:#{ $1.length }em;" if text.sub!( /([)]+)/, '' )
-
-        style << "text-align:#{ h_align( $& ) };" if text =~ A_HLGN
-
-        cls, id = $1, $2 if cls =~ /^(.*?)#(.*)$/
-        
-        atts = ''
-        atts << " style=\"#{ style.join }\"" unless style.empty?
-        atts << " class=\"#{ cls }\"" unless cls.to_s.empty?
-        atts << " lang=\"#{ lang }\"" if lang
-        atts << " id=\"#{ id }\"" if id
-        atts << " colspan=\"#{ colspan }\"" if colspan
-        atts << " rowspan=\"#{ rowspan }\"" if rowspan
-        
-        atts
-    end
-
-    TABLE_RE = /^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)(\n\n|\Z)/m
-    
-    # Parses a Textile table block, building HTML from the result.
-    def block_textile_table( text ) 
-        text.gsub!( TABLE_RE ) do |matches|
-
-            tatts, fullrow = $~[1..2]
-            tatts = pba( tatts, 'table' )
-            tatts = shelve( tatts ) if tatts
-            rows = []
-
-            fullrow.each_line do |row|
-                ratts, row = pba( $1, 'tr' ), $2 if row =~ /^(#{A}#{C}\. )(.*)/m
-                cells = []
-                row.split( /(\|)(?![^\[\|]*\]\])/ )[1..-2].each do |cell|
-                    next if cell == '|'
-                    ctyp = 'd'
-                    ctyp = 'h' if cell =~ /^_/
-
-                    catts = ''
-                    catts, cell = pba( $1, 'td' ), $2 if cell =~ /^(_?#{S}#{A}#{C}\. ?)(.*)/
-
-                    catts = shelve( catts ) if catts
-                    cells << "\t\t\t<t#{ ctyp }#{ catts }>#{ cell }</t#{ ctyp }>" 
-                end
-                ratts = shelve( ratts ) if ratts
-                rows << "\t\t<tr#{ ratts }>\n#{ cells.join( "\n" ) }\n\t\t</tr>"
-            end
-            "\t<table#{ tatts }>\n#{ rows.join( "\n" ) }\n\t</table>\n\n"
-        end
-    end
-
-    LISTS_RE = /^([#*]+?#{C} .*?)$(?![^#*])/m
-    LISTS_CONTENT_RE = /^([#*]+)(#{A}#{C}) (.*)$/m
-
-    # Parses Textile lists and generates HTML
-    def block_textile_lists( text ) 
-        text.gsub!( LISTS_RE ) do |match|
-            lines = match.split( /\n/ )
-            last_line = -1
-            depth = []
-            lines.each_with_index do |line, line_id|
-                if line =~ LISTS_CONTENT_RE 
-                    tl,atts,content = $~[1..3]
-                    if depth.last
-                        if depth.last.length > tl.length
-                            (depth.length - 1).downto(0) do |i|
-                                break if depth[i].length == tl.length
-                                lines[line_id - 1] << "</li>\n\t</#{ lT( depth[i] ) }l>\n\t"
-                                depth.pop
-                            end
-                        end
-                        if depth.last and depth.last.length == tl.length
-                            lines[line_id - 1] << '</li>'
-                        end
-                    end
-                    unless depth.last == tl
-                        depth << tl
-                        atts = pba( atts )
-                        atts = shelve( atts ) if atts
-                        lines[line_id] = "\t<#{ lT(tl) }l#{ atts }>\n\t<li>#{ content }"
-                    else
-                        lines[line_id] = "\t\t<li>#{ content }"
-                    end
-                    last_line = line_id
-
-                else
-                    last_line = line_id
-                end
-                if line_id - last_line > 1 or line_id == lines.length - 1
-                    depth.delete_if do |v|
-                        lines[last_line] << "</li>\n\t</#{ lT( v ) }l>"
-                    end
-                end
-            end
-            lines.join( "\n" )
-        end
-    end
-    
-    QUOTES_RE = /(^>+([^\n]*?)(\n|$))+/m
-    QUOTES_CONTENT_RE = /^([> ]+)(.*)$/m
-    
-    def block_textile_quotes( text )
-      text.gsub!( QUOTES_RE ) do |match|
-        lines = match.split( /\n/ )
-        quotes = ''
-        indent = 0
-        lines.each do |line|
-          line =~ QUOTES_CONTENT_RE 
-          bq,content = $1, $2
-          l = bq.count('>')
-          if l != indent
-            quotes << ("\n\n" + (l>indent ? '<blockquote>' * (l-indent) : '</blockquote>' * (indent-l)) + "\n\n")
-            indent = l
-          end
-          quotes << (content + "\n")
-        end
-        quotes << ("\n" + '</blockquote>' * indent + "\n\n")
-        quotes
-      end
-    end
-
-    CODE_RE = /(\W)
-        @
-        (?:\|(\w+?)\|)?
-        (.+?)
-        @
-        (?=\W)/x
-
-    def inline_textile_code( text ) 
-        text.gsub!( CODE_RE ) do |m|
-            before,lang,code,after = $~[1..4]
-            lang = " lang=\"#{ lang }\"" if lang
-            rip_offtags( "#{ before }<code#{ lang }>#{ code }</code>#{ after }", false )
-        end
-    end
-
-    def lT( text ) 
-        text =~ /\#$/ ? 'o' : 'u'
-    end
-
-    def hard_break( text )
-        text.gsub!( /(.)\n(?!\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks
-    end
-
-    BLOCKS_GROUP_RE = /\n{2,}(?! )/m
-
-    def blocks( text, deep_code = false )
-        text.replace( text.split( BLOCKS_GROUP_RE ).collect do |blk|
-            plain = blk !~ /\A[#*> ]/
-
-            # skip blocks that are complex HTML
-            if blk =~ /^<\/?(\w+).*>/ and not SIMPLE_HTML_TAGS.include? $1
-                blk
-            else
-                # search for indentation levels
-                blk.strip!
-                if blk.empty?
-                    blk
-                else
-                    code_blk = nil
-                    blk.gsub!( /((?:\n(?:\n^ +[^\n]*)+)+)/m ) do |iblk|
-                        flush_left iblk
-                        blocks iblk, plain
-                        iblk.gsub( /^(\S)/, "\t\\1" )
-                        if plain
-                            code_blk = iblk; ""
-                        else
-                            iblk
-                        end
-                    end
-
-                    block_applied = 0 
-                    @rules.each do |rule_name|
-                        block_applied += 1 if ( rule_name.to_s.match /^block_/ and method( rule_name ).call( blk ) )
-                    end
-                    if block_applied.zero?
-                        if deep_code
-                            blk = "\t<pre><code>#{ blk }</code></pre>"
-                        else
-                            blk = "\t<p>#{ blk }</p>"
-                        end
-                    end
-                    # hard_break blk
-                    blk + "\n#{ code_blk }"
-                end
-            end
-
-        end.join( "\n\n" ) )
-    end
-
-    def textile_bq( tag, atts, cite, content )
-        cite, cite_title = check_refs( cite )
-        cite = " cite=\"#{ cite }\"" if cite
-        atts = shelve( atts ) if atts
-        "\t<blockquote#{ cite }>\n\t\t<p#{ atts }>#{ content }</p>\n\t</blockquote>"
-    end
-
-    def textile_p( tag, atts, cite, content )
-        atts = shelve( atts ) if atts
-        "\t<#{ tag }#{ atts }>#{ content }</#{ tag }>"
-    end
-
-    alias textile_h1 textile_p
-    alias textile_h2 textile_p
-    alias textile_h3 textile_p
-    alias textile_h4 textile_p
-    alias textile_h5 textile_p
-    alias textile_h6 textile_p
-
-    def textile_fn_( tag, num, atts, cite, content )
-        atts << " id=\"fn#{ num }\" class=\"footnote\""
-        content = "<sup>#{ num }</sup> #{ content }"
-        atts = shelve( atts ) if atts
-        "\t<p#{ atts }>#{ content }</p>"
-    end
-
-    BLOCK_RE = /^(([a-z]+)(\d*))(#{A}#{C})\.(?::(\S+))? (.*)$/m
-
-    def block_textile_prefix( text ) 
-        if text =~ BLOCK_RE
-            tag,tagpre,num,atts,cite,content = $~[1..6]
-            atts = pba( atts )
-
-            # pass to prefix handler
-            replacement = nil
-            if respond_to? "textile_#{ tag }", true
-              replacement = method( "textile_#{ tag }" ).call( tag, atts, cite, content )
-            elsif respond_to? "textile_#{ tagpre }_", true
-              replacement = method( "textile_#{ tagpre }_" ).call( tagpre, num, atts, cite, content )  
-            end
-            text.gsub!( $& ) { replacement } if replacement
-        end
-    end
-    
-    SETEXT_RE = /\A(.+?)\n([=-])[=-]* *$/m
-    def block_markdown_setext( text )
-        if text =~ SETEXT_RE
-            tag = if $2 == "="; "h1"; else; "h2"; end
-            blk, cont = "<#{ tag }>#{ $1 }</#{ tag }>", $'
-            blocks cont
-            text.replace( blk + cont )
-        end
-    end
-
-    ATX_RE = /\A(\#{1,6})  # $1 = string of #'s
-              [ ]*
-              (.+?)       # $2 = Header text
-              [ ]*
-              \#*         # optional closing #'s (not counted)
-              $/x
-    def block_markdown_atx( text )
-        if text =~ ATX_RE
-            tag = "h#{ $1.length }"
-            blk, cont = "<#{ tag }>#{ $2 }</#{ tag }>\n\n", $'
-            blocks cont
-            text.replace( blk + cont )
-        end
-    end
-
-    MARKDOWN_BQ_RE = /\A(^ *> ?.+$(.+\n)*\n*)+/m
-
-    def block_markdown_bq( text )
-        text.gsub!( MARKDOWN_BQ_RE ) do |blk|
-            blk.gsub!( /^ *> ?/, '' )
-            flush_left blk
-            blocks blk
-            blk.gsub!( /^(\S)/, "\t\\1" )
-            "<blockquote>\n#{ blk }\n</blockquote>\n\n"
-        end
-    end
-
-    MARKDOWN_RULE_RE = /^(#{
-        ['*', '-', '_'].collect { |ch| ' ?(' + Regexp::quote( ch ) + ' ?){3,}' }.join( '|' )
-    })$/
-
-    def block_markdown_rule( text )
-        text.gsub!( MARKDOWN_RULE_RE ) do |blk|
-            "<hr />"
-        end
-    end
-
-    # XXX TODO XXX
-    def block_markdown_lists( text )
-    end
-
-    def inline_textile_span( text ) 
-        QTAGS.each do |qtag_rc, ht, qtag_re, rtype|
-            text.gsub!( qtag_re ) do |m|
-             
-                case rtype
-                when :limit
-                    sta,oqs,qtag,content,oqa = $~[1..6]
-                    atts = nil
-                    if content =~ /^(#{C})(.+)$/
-                      atts, content = $~[1..2]
-                    end
-                else
-                    qtag,atts,cite,content = $~[1..4]
-                    sta = ''
-                end
-                atts = pba( atts )
-                atts = shelve( atts ) if atts
-
-                "#{ sta }#{ oqs }<#{ ht }#{ atts }>#{ content }</#{ ht }>#{ oqa }"
-
-            end
-        end
-    end
-
-    LINK_RE = /
-            (
-            ([\s\[{(]|[#{PUNCT}])?     # $pre
-            "                          # start
-            (#{C})                     # $atts
-            ([^"\n]+?)                 # $text
-            \s?
-            (?:\(([^)]+?)\)(?="))?     # $title
-            ":
-            (                          # $url
-            (\/|[a-zA-Z]+:\/\/|www\.|mailto:)  # $proto
-            [\w\/]\S+?
-            )               
-            (\/)?                      # $slash
-            ([^\w\=\/;\(\)]*?)         # $post
-            )
-            (?=<|\s|$)
-        /x 
-#"
-    def inline_textile_link( text ) 
-        text.gsub!( LINK_RE ) do |m|
-          all,pre,atts,text,title,url,proto,slash,post = $~[1..9]
-          if text.include?('<br />')
-            all
-          else
-            url, url_title = check_refs( url )
-            title ||= url_title
-            
-            # Idea below : an URL with unbalanced parethesis and
-            # ending by ')' is put into external parenthesis
-            if ( url[-1]==?) and ((url.count("(") - url.count(")")) < 0 ) )
-              url=url[0..-2] # discard closing parenth from url
-              post = ")"+post # add closing parenth to post
-            end
-            atts = pba( atts )
-            atts = " href=\"#{ htmlesc url }#{ slash }\"#{ atts }"
-            atts << " title=\"#{ htmlesc title }\"" if title
-            atts = shelve( atts ) if atts
-            
-            external = (url =~ /^https?:\/\//) ? ' class="external"' : ''
-            
-            "#{ pre }<a#{ atts }#{ external }>#{ text }</a>#{ post }"
-          end
-        end
-    end
-
-    MARKDOWN_REFLINK_RE = /
-            \[([^\[\]]+)\]      # $text
-            [ ]?                # opt. space
-            (?:\n[ ]*)?         # one optional newline followed by spaces
-            \[(.*?)\]           # $id
-        /x 
-
-    def inline_markdown_reflink( text ) 
-        text.gsub!( MARKDOWN_REFLINK_RE ) do |m|
-            text, id = $~[1..2]
-
-            if id.empty?
-                url, title = check_refs( text )
-            else
-                url, title = check_refs( id )
-            end
-            
-            atts = " href=\"#{ url }\""
-            atts << " title=\"#{ title }\"" if title
-            atts = shelve( atts )
-            
-            "<a#{ atts }>#{ text }</a>"
-        end
-    end
-
-    MARKDOWN_LINK_RE = /
-            \[([^\[\]]+)\]      # $text
-            \(                  # open paren
-            [ \t]*              # opt space
-            <?(.+?)>?           # $href
-            [ \t]*              # opt space
-            (?:                 # whole title
-            (['"])              # $quote
-            (.*?)               # $title
-            \3                  # matching quote
-            )?                  # title is optional
-            \)
-        /x 
-
-    def inline_markdown_link( text ) 
-        text.gsub!( MARKDOWN_LINK_RE ) do |m|
-            text, url, quote, title = $~[1..4]
-
-            atts = " href=\"#{ url }\""
-            atts << " title=\"#{ title }\"" if title
-            atts = shelve( atts )
-            
-            "<a#{ atts }>#{ text }</a>"
-        end
-    end
-
-    TEXTILE_REFS_RE =  /(^ *)\[([^\[\n]+?)\](#{HYPERLINK})(?=\s|$)/
-    MARKDOWN_REFS_RE = /(^ *)\[([^\n]+?)\]:\s+<?(#{HYPERLINK})>?(?:\s+"((?:[^"]|\\")+)")?(?=\s|$)/m
-
-    def refs( text )
-        @rules.each do |rule_name|
-            method( rule_name ).call( text ) if rule_name.to_s.match /^refs_/
-        end
-    end
-
-    def refs_textile( text ) 
-        text.gsub!( TEXTILE_REFS_RE ) do |m|
-            flag, url = $~[2..3]
-            @urlrefs[flag.downcase] = [url, nil]
-            nil
-        end
-    end
-    
-    def refs_markdown( text )
-        text.gsub!( MARKDOWN_REFS_RE ) do |m|
-            flag, url = $~[2..3]
-            title = $~[6]
-            @urlrefs[flag.downcase] = [url, title]
-            nil
-        end
-    end
-
-    def check_refs( text ) 
-        ret = @urlrefs[text.downcase] if text
-        ret || [text, nil]
-    end
-
-    IMAGE_RE = /
-            (>|\s|^)           # start of line?
-            \!                   # opening
-            (\<|\=|\>)?          # optional alignment atts
-            (#{C})               # optional style,class atts
-            (?:\. )?             # optional dot-space
-            ([^\s(!]+?)          # presume this is the src
-            \s?                  # optional space
-            (?:\(((?:[^\(\)]|\([^\)]+\))+?)\))?   # optional title
-            \!                   # closing
-            (?::#{ HYPERLINK })? # optional href
-        /x 
-
-    def inline_textile_image( text ) 
-        text.gsub!( IMAGE_RE )  do |m|
-            stln,algn,atts,url,title,href,href_a1,href_a2 = $~[1..8]
-            htmlesc title
-            atts = pba( atts )
-            atts = " src=\"#{ htmlesc url.dup }\"#{ atts }"
-            atts << " title=\"#{ title }\"" if title
-            atts << " alt=\"#{ title }\"" 
-            # size = @getimagesize($url);
-            # if($size) $atts.= " $size[3]";
-
-            href, alt_title = check_refs( href ) if href
-            url, url_title = check_refs( url )
-
-            out = ''
-            out << "<a#{ shelve( " href=\"#{ href }\"" ) }>" if href
-            out << "<img#{ shelve( atts ) } />"
-            out << "</a>#{ href_a1 }#{ href_a2 }" if href
-            
-            if algn 
-                algn = h_align( algn )
-                if stln == "<p>"
-                    out = "<p style=\"float:#{ algn }\">#{ out }"
-                else
-                    out = "#{ stln }<div style=\"float:#{ algn }\">#{ out }</div>"
-                end
-            else
-                out = stln + out
-            end
-
-            out
-        end
-    end
-
-    def shelve( val ) 
-        @shelf << val
-        " :redsh##{ @shelf.length }:"
-    end
-    
-    def retrieve( text ) 
-        @shelf.each_with_index do |r, i|
-            text.gsub!( " :redsh##{ i + 1 }:", r )
-        end
-    end
-
-    def incoming_entities( text ) 
-        ## turn any incoming ampersands into a dummy character for now.
-        ## This uses a negative lookahead for alphanumerics followed by a semicolon,
-        ## implying an incoming html entity, to be skipped
-
-        text.gsub!( /&(?![#a-z0-9]+;)/i, "x%x%" )
-    end
-
-    def no_textile( text ) 
-        text.gsub!( /(^|\s)==([^=]+.*?)==(\s|$)?/,
-            '\1<notextile>\2</notextile>\3' )
-        text.gsub!( /^ *==([^=]+.*?)==/m,
-            '\1<notextile>\2</notextile>\3' )
-    end
-
-    def clean_white_space( text ) 
-        # normalize line breaks
-        text.gsub!( /\r\n/, "\n" )
-        text.gsub!( /\r/, "\n" )
-        text.gsub!( /\t/, '    ' )
-        text.gsub!( /^ +$/, '' )
-        text.gsub!( /\n{3,}/, "\n\n" )
-        text.gsub!( /"$/, "\" " )
-
-        # if entire document is indented, flush
-        # to the left side
-        flush_left text
-    end
-
-    def flush_left( text )
-        indt = 0
-        if text =~ /^ /
-            while text !~ /^ {#{indt}}\S/
-                indt += 1
-            end unless text.empty?
-            if indt.nonzero?
-                text.gsub!( /^ {#{indt}}/, '' )
-            end
-        end
-    end
-
-    def footnote_ref( text ) 
-        text.gsub!( /\b\[([0-9]+?)\](\s)?/,
-            '<sup><a href="#fn\1">\1</a></sup>\2' )
-    end
-    
-    OFFTAGS = /(code|pre|kbd|notextile)/
-    OFFTAG_MATCH = /(?:(<\/#{ OFFTAGS }>)|(<#{ OFFTAGS }[^>]*>))(.*?)(?=<\/?#{ OFFTAGS }\W|\Z)/mi
-    OFFTAG_OPEN = /<#{ OFFTAGS }/
-    OFFTAG_CLOSE = /<\/?#{ OFFTAGS }/
-    HASTAG_MATCH = /(<\/?\w[^\n]*?>)/m
-    ALLTAG_MATCH = /(<\/?\w[^\n]*?>)|.*?(?=<\/?\w[^\n]*?>|$)/m
-
-    def glyphs_textile( text, level = 0 )
-        if text !~ HASTAG_MATCH
-            pgl text
-            footnote_ref text
-        else
-            codepre = 0
-            text.gsub!( ALLTAG_MATCH ) do |line|
-                ## matches are off if we're between <code>, <pre> etc.
-                if $1
-                    if line =~ OFFTAG_OPEN
-                        codepre += 1
-                    elsif line =~ OFFTAG_CLOSE
-                        codepre -= 1
-                        codepre = 0 if codepre < 0
-                    end 
-                elsif codepre.zero?
-                    glyphs_textile( line, level + 1 )
-                else
-                    htmlesc( line, :NoQuotes )
-                end
-                # p [level, codepre, line]
-
-                line
-            end
-        end
-    end
-
-    def rip_offtags( text, escape_aftertag=true, escape_line=true )
-        if text =~ /<.*>/
-            ## strip and encode <pre> content
-            codepre, used_offtags = 0, {}
-            text.gsub!( OFFTAG_MATCH ) do |line|
-                if $3
-                    first, offtag, aftertag = $3, $4, $5
-                    codepre += 1
-                    used_offtags[offtag] = true
-                    if codepre - used_offtags.length > 0
-                        htmlesc( line, :NoQuotes ) if escape_line
-                        @pre_list.last << line
-                        line = ""
-                    else
-                        ### htmlesc is disabled between CODE tags which will be parsed with highlighter
-                        ### Regexp in formatter.rb is : /<code\s+class="(\w+)">\s?(.+)/m
-                        ### NB: some changes were made not to use $N variables, because we use "match"
-                        ###   and it breaks following lines
-                        htmlesc( aftertag, :NoQuotes ) if aftertag && escape_aftertag && !first.match(/<code\s+class="(\w+)">/)
-                        line = "<redpre##{ @pre_list.length }>"
-                        first.match(/<#{ OFFTAGS }([^>]*)>/)
-                        tag = $1
-                        $2.to_s.match(/(class\=("[^"]+"|'[^']+'))/i)
-                        tag << " #{$1}" if $1
-                        @pre_list << "<#{ tag }>#{ aftertag }"
-                    end
-                elsif $1 and codepre > 0
-                    if codepre - used_offtags.length > 0
-                        htmlesc( line, :NoQuotes ) if escape_line
-                        @pre_list.last << line
-                        line = ""
-                    end
-                    codepre -= 1 unless codepre.zero?
-                    used_offtags = {} if codepre.zero?
-                end 
-                line
-            end
-        end
-        text
-    end
-
-    def smooth_offtags( text )
-        unless @pre_list.empty?
-            ## replace <pre> content
-            text.gsub!( /<redpre#(\d+)>/ ) { @pre_list[$1.to_i] }
-        end
-    end
-
-    def inline( text ) 
-        [/^inline_/, /^glyphs_/].each do |meth_re|
-            @rules.each do |rule_name|
-                method( rule_name ).call( text ) if rule_name.to_s.match( meth_re )
-            end
-        end
-    end
-
-    def h_align( text ) 
-        H_ALGN_VALS[text]
-    end
-
-    def v_align( text ) 
-        V_ALGN_VALS[text]
-    end
-
-    def textile_popup_help( name, windowW, windowH )
-        ' <a target="_blank" href="http://hobix.com/textile/#' + helpvar + '" onclick="window.open(this.href, \'popupwindow\', \'width=' + windowW + ',height=' + windowH + ',scrollbars,resizable\'); return false;">' + name + '</a><br />'
-    end
-
-    # HTML cleansing stuff
-    BASIC_TAGS = {
-        'a' => ['href', 'title'],
-        'img' => ['src', 'alt', 'title'],
-        'br' => [],
-        'i' => nil,
-        'u' => nil, 
-        'b' => nil,
-        'pre' => nil,
-        'kbd' => nil,
-        'code' => ['lang'],
-        'cite' => nil,
-        'strong' => nil,
-        'em' => nil,
-        'ins' => nil,
-        'sup' => nil,
-        'sub' => nil,
-        'del' => nil,
-        'table' => nil,
-        'tr' => nil,
-        'td' => ['colspan', 'rowspan'],
-        'th' => nil,
-        'ol' => nil,
-        'ul' => nil,
-        'li' => nil,
-        'p' => nil,
-        'h1' => nil,
-        'h2' => nil,
-        'h3' => nil,
-        'h4' => nil,
-        'h5' => nil,
-        'h6' => nil, 
-        'blockquote' => ['cite']
-    }
-
-    def clean_html( text, tags = BASIC_TAGS )
-        text.gsub!( /<!\[CDATA\[/, '' )
-        text.gsub!( /<(\/*)(\w+)([^>]*)>/ ) do
-            raw = $~
-            tag = raw[2].downcase
-            if tags.has_key? tag
-                pcs = [tag]
-                tags[tag].each do |prop|
-                    ['"', "'", ''].each do |q|
-                        q2 = ( q != '' ? q : '\s' )
-                        if raw[3] =~ /#{prop}\s*=\s*#{q}([^#{q2}]+)#{q}/i
-                            attrv = $1
-                            next if prop == 'src' and attrv =~ %r{^(?!http)\w+:}
-                            pcs << "#{prop}=\"#{$1.gsub('"', '\\"')}\""
-                            break
-                        end
-                    end
-                end if tags[tag]
-                "<#{raw[1]}#{pcs.join " "}>"
-            else
-                " "
-            end
-        end
-    end
-    
-    ALLOWED_TAGS = %w(redpre pre code notextile)
-    
-    def escape_html_tags(text)
-      text.gsub!(%r{<(\/?([!\w]+)[^<>\n]*)(>?)}) {|m| ALLOWED_TAGS.include?($2) ? "<#{$1}#{$3}" : "&lt;#{$1}#{'&gt;' unless $3.blank?}" }
-    end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/81/8152a8429a670810e05571a0d05bddd66f5b7e5e.svn-base
--- a/.svn/pristine/81/8152a8429a670810e05571a0d05bddd66f5b7e5e.svn-base
+++ /dev/null
@@ -1,40 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class PatchesTest < ActiveSupport::TestCase
-  include Redmine::I18n
-
-  context "ActiveRecord::Base.human_attribute_name" do
-    setup do
-      Setting.default_language = 'en'
-    end
-
-    should "transform name to field_name" do
-      assert_equal l('field_last_login_on'), ActiveRecord::Base.human_attribute_name('last_login_on')
-    end
-
-    should "cut extra _id suffix for better validation" do
-      assert_equal l('field_last_login_on'), ActiveRecord::Base.human_attribute_name('last_login_on_id')
-    end
-
-    should "default to humanized value if no translation has been found (useful for custom fields)" do
-      assert_equal 'Patch name', ActiveRecord::Base.human_attribute_name('Patch name')
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/81/81609ac3f30763970c764d86e00b3512d937facd.svn-base
--- /dev/null
+++ b/.svn/pristine/81/81609ac3f30763970c764d86e00b3512d937facd.svn-base
@@ -0,0 +1,76 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../test_helper', __FILE__)
+
+class Redmine::Utils::DateCalculationTest < ActiveSupport::TestCase
+  include Redmine::Utils::DateCalculation
+
+  def test_working_days_without_non_working_week_days
+    with_settings :non_working_week_days => [] do
+      assert_working_days 18, '2012-10-09', '2012-10-27'
+      assert_working_days  6, '2012-10-09', '2012-10-15'
+      assert_working_days  5, '2012-10-09', '2012-10-14'
+      assert_working_days  3, '2012-10-09', '2012-10-12'
+      assert_working_days  3, '2012-10-14', '2012-10-17'
+      assert_working_days 16, '2012-10-14', '2012-10-30'
+    end
+  end
+
+  def test_working_days_with_non_working_week_days
+    with_settings :non_working_week_days => %w(6 7) do
+      assert_working_days 14, '2012-10-09', '2012-10-27'
+      assert_working_days  4, '2012-10-09', '2012-10-15'
+      assert_working_days  4, '2012-10-09', '2012-10-14'
+      assert_working_days  3, '2012-10-09', '2012-10-12'
+      assert_working_days  8, '2012-10-09', '2012-10-19'
+      assert_working_days  8, '2012-10-11', '2012-10-23'
+      assert_working_days  2, '2012-10-14', '2012-10-17'
+      assert_working_days 11, '2012-10-14', '2012-10-30'
+    end
+  end
+
+  def test_add_working_days_without_non_working_week_days
+    with_settings :non_working_week_days => [] do
+      assert_add_working_days '2012-10-10', '2012-10-10', 0
+      assert_add_working_days '2012-10-11', '2012-10-10', 1
+      assert_add_working_days '2012-10-12', '2012-10-10', 2
+      assert_add_working_days '2012-10-13', '2012-10-10', 3
+      assert_add_working_days '2012-10-25', '2012-10-10', 15
+    end
+  end
+
+  def test_add_working_days_with_non_working_week_days
+    with_settings :non_working_week_days => %w(6 7) do
+      assert_add_working_days '2012-10-10', '2012-10-10', 0
+      assert_add_working_days '2012-10-11', '2012-10-10', 1
+      assert_add_working_days '2012-10-12', '2012-10-10', 2
+      assert_add_working_days '2012-10-15', '2012-10-10', 3
+      assert_add_working_days '2012-10-31', '2012-10-10', 15
+      assert_add_working_days '2012-10-19', '2012-10-09', 8
+      assert_add_working_days '2012-10-23', '2012-10-11', 8
+    end
+  end
+
+  def assert_working_days(expected_days, from, to)
+    assert_equal expected_days, working_days(from.to_date, to.to_date)
+  end
+
+  def assert_add_working_days(expected_date, from, working_days)
+    assert_equal expected_date.to_date, add_working_days(from.to_date, working_days)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/81/817f1955c70c5e3d4e1883912d5c54dd05bb15de.svn-base
Binary file .svn/pristine/81/817f1955c70c5e3d4e1883912d5c54dd05bb15de.svn-base has changed
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/81/81b5162180e7da6eba9eec12f7d1c6c77f6bbb3a.svn-base
--- /dev/null
+++ b/.svn/pristine/81/81b5162180e7da6eba9eec12f7d1c6c77f6bbb3a.svn-base
@@ -0,0 +1,158 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::VersionsTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :versions
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "/projects/:project_id/versions" do
+    context "GET" do
+      should "return project versions" do
+        get '/projects/1/versions.xml'
+
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+        assert_tag :tag => 'versions',
+          :attributes => {:type => 'array'},
+          :child => {
+            :tag => 'version',
+            :child => {
+              :tag => 'id',
+              :content => '2',
+              :sibling => {
+                :tag => 'name',
+                :content => '1.0'
+              }
+            }
+          }
+      end
+    end
+
+    context "POST" do
+      should "create the version" do
+        assert_difference 'Version.count' do
+          post '/projects/1/versions.xml', {:version => {:name => 'API test'}}, credentials('jsmith')
+        end
+
+        version = Version.first(:order => 'id DESC')
+        assert_equal 'API test', version.name
+
+        assert_response :created
+        assert_equal 'application/xml', @response.content_type
+        assert_tag 'version', :child => {:tag => 'id', :content => version.id.to_s}
+      end
+
+      should "create the version with due date" do
+        assert_difference 'Version.count' do
+          post '/projects/1/versions.xml', {:version => {:name => 'API test', :due_date => '2012-01-24'}}, credentials('jsmith')
+        end
+
+        version = Version.first(:order => 'id DESC')
+        assert_equal 'API test', version.name
+        assert_equal Date.parse('2012-01-24'), version.due_date
+
+        assert_response :created
+        assert_equal 'application/xml', @response.content_type
+        assert_tag 'version', :child => {:tag => 'id', :content => version.id.to_s}
+      end
+
+      should "create the version with custom fields" do
+        field = VersionCustomField.generate!
+
+        assert_difference 'Version.count' do
+          post '/projects/1/versions.xml', {
+              :version => {
+                :name => 'API test',
+                :custom_fields => [
+                  {'id' => field.id.to_s, 'value' => 'Some value'}
+                ]
+              }
+            }, credentials('jsmith')
+        end
+
+        version = Version.first(:order => 'id DESC')
+        assert_equal 'API test', version.name
+        assert_equal 'Some value', version.custom_field_value(field)
+
+        assert_response :created
+        assert_equal 'application/xml', @response.content_type
+        assert_select 'version>custom_fields>custom_field[id=?]>value', field.id.to_s, 'Some value'
+      end
+
+      context "with failure" do
+        should "return the errors" do
+          assert_no_difference('Version.count') do
+            post '/projects/1/versions.xml', {:version => {:name => ''}}, credentials('jsmith')
+          end
+
+          assert_response :unprocessable_entity
+          assert_tag :errors, :child => {:tag => 'error', :content => "Name can't be blank"}
+        end
+      end
+    end
+  end
+
+  context "/versions/:id" do
+    context "GET" do
+      should "return the version" do
+        get '/versions/2.xml'
+
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+        assert_select 'version' do
+          assert_select 'id', :text => '2'
+          assert_select 'name', :text => '1.0'
+          assert_select 'sharing', :text => 'none'
+        end
+      end
+    end
+
+    context "PUT" do
+      should "update the version" do
+        put '/versions/2.xml', {:version => {:name => 'API update'}}, credentials('jsmith')
+
+        assert_response :ok
+        assert_equal '', @response.body
+        assert_equal 'API update', Version.find(2).name
+      end
+    end
+
+    context "DELETE" do
+      should "destroy the version" do
+        assert_difference 'Version.count', -1 do
+          delete '/versions/3.xml', {}, credentials('jsmith')
+        end
+
+        assert_response :ok
+        assert_equal '', @response.body
+        assert_nil Version.find_by_id(3)
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/81/81cd3726ba1b626ac8fe2e786c213679ee3b4319.svn-base
--- a/.svn/pristine/81/81cd3726ba1b626ac8fe2e786c213679ee3b4319.svn-base
+++ /dev/null
@@ -1,24 +0,0 @@
-module CodeRay
-module Scanners
-  
-  map \
-    :'c++'       => :cpp,
-    :cplusplus   => :cpp,
-    :ecmascript  => :java_script,
-    :ecma_script => :java_script,
-    :rhtml       => :erb,
-    :eruby       => :erb,
-    :irb         => :ruby,
-    :javascript  => :java_script,
-    :js          => :java_script,
-    :pascal      => :delphi,
-    :patch       => :diff,
-    :plain       => :text,
-    :plaintext   => :text,
-    :xhtml       => :html,
-    :yml         => :yaml
-  
-  default :text
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/82/821d4ef82eeed4cbb18ce34368856a650d31c2d8.svn-base
--- /dev/null
+++ b/.svn/pristine/82/821d4ef82eeed4cbb18ce34368856a650d31c2d8.svn-base
@@ -0,0 +1,79 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingTrackersTest < ActionController::IntegrationTest
+  def test_trackers
+    assert_routing(
+        { :method => 'get', :path => "/trackers" },
+        { :controller => 'trackers', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/trackers.xml" },
+        { :controller => 'trackers', :action => 'index', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/trackers" },
+        { :controller => 'trackers', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/trackers.xml" },
+        { :controller => 'trackers', :action => 'create', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/trackers/new" },
+        { :controller => 'trackers', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/trackers/new.xml" },
+        { :controller => 'trackers', :action => 'new', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/trackers/1/edit" },
+        { :controller => 'trackers', :action => 'edit', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/trackers/1" },
+        { :controller => 'trackers', :action => 'update',
+          :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/trackers/1.xml" },
+        { :controller => 'trackers', :action => 'update',
+          :format => 'xml', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/trackers/1" },
+        { :controller => 'trackers', :action => 'destroy',
+          :id => '1' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/trackers/1.xml" },
+        { :controller => 'trackers', :action => 'destroy',
+          :format => 'xml', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/trackers/fields" },
+        { :controller => 'trackers', :action => 'fields' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/trackers/fields" },
+        { :controller => 'trackers', :action => 'fields' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/82/822a99f6cd2f033a4f1b9b05b78b77e54640f573.svn-base
--- /dev/null
+++ b/.svn/pristine/82/822a99f6cd2f033a4f1b9b05b78b77e54640f573.svn-base
@@ -0,0 +1,31 @@
+<%= form_tag({:action => 'edit', :tab => 'issues'}, :onsubmit => 'selectAllOptions("selected_columns");') do %>
+
+<div class="box tabular settings">
+<p><%= setting_check_box :cross_project_issue_relations %></p>
+
+<p><%= setting_select :cross_project_subtasks, cross_project_subtasks_options %></p>
+
+<p><%= setting_check_box :issue_group_assignment %></p>
+
+<p><%= setting_check_box :default_issue_start_date_to_creation_date %></p>
+
+<p><%= setting_check_box :display_subprojects_issues %></p>
+
+<p><%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %></p>
+
+<p><%= setting_multiselect :non_working_week_days, (1..7).map {|d| [day_name(d), d.to_s]}, :inline => true %></p>
+
+<p><%= setting_text_field :issues_export_limit, :size => 6 %></p>
+
+<p><%= setting_text_field :gantt_items_limit, :size => 6 %></p>
+</div>
+
+<fieldset class="box">
+	<legend><%= l(:setting_issue_list_default_columns) %></legend>
+  <%= render_query_columns_selection(
+        IssueQuery.new(:column_names => Setting.issue_list_default_columns),
+        :name => 'settings[issue_list_default_columns]') %>
+</fieldset>
+
+<%= submit_tag l(:button_save) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/82/822b75d0bb3697ed3dee9071dcf61cf8a7528ac2.svn-base
--- a/.svn/pristine/82/822b75d0bb3697ed3dee9071dcf61cf8a7528ac2.svn-base
+++ /dev/null
@@ -1,168 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class MessageTest < ActiveSupport::TestCase
-  fixtures :projects, :roles, :members, :member_roles, :boards, :messages, :users, :watchers
-
-  def setup
-    @board = Board.find(1)
-    @user = User.find(1)
-  end
-
-  def test_create
-    topics_count = @board.topics_count
-    messages_count = @board.messages_count
-
-    message = Message.new(:board => @board, :subject => 'Test message',
-                          :content => 'Test message content',
-                          :author => @user)
-    assert message.save
-    @board.reload
-    # topics count incremented
-    assert_equal topics_count+1, @board[:topics_count]
-    # messages count incremented
-    assert_equal messages_count+1, @board[:messages_count]
-    assert_equal message, @board.last_message
-    # author should be watching the message
-    assert message.watched_by?(@user)
-  end
-
-  def test_reply
-    topics_count = @board.topics_count
-    messages_count = @board.messages_count
-    @message = Message.find(1)
-    replies_count = @message.replies_count
-
-    reply_author = User.find(2)
-    reply = Message.new(:board => @board, :subject => 'Test reply',
-                        :content => 'Test reply content',
-                        :parent => @message, :author => reply_author)
-    assert reply.save
-    @board.reload
-    # same topics count
-    assert_equal topics_count, @board[:topics_count]
-    # messages count incremented
-    assert_equal messages_count+1, @board[:messages_count]
-    assert_equal reply, @board.last_message
-    @message.reload
-    # replies count incremented
-    assert_equal replies_count+1, @message[:replies_count]
-    assert_equal reply, @message.last_reply
-    # author should be watching the message
-    assert @message.watched_by?(reply_author)
-  end
-
-  def test_cannot_reply_to_locked_topic
-    topics_count = @board.topics_count
-    messages_count = @board.messages_count
-    @message = Message.find(1)
-    replies_count = @message.replies_count
-    assert_equal false, @message.locked
-    @message.locked = true
-    assert @message.save
-    assert_equal true, @message.locked
-
-    reply_author = User.find(2)
-    reply = Message.new(:board => @board, :subject => 'Test reply',
-                        :content => 'Test reply content',
-                        :parent => @message, :author => reply_author)
-    reply.save
-    assert_equal 1, reply.errors.count
-  end
-
-  def test_moving_message_should_update_counters
-    @message = Message.find(1)
-    assert_no_difference 'Message.count' do
-      # Previous board
-      assert_difference 'Board.find(1).topics_count', -1 do
-        assert_difference 'Board.find(1).messages_count', -(1 + @message.replies_count) do
-          # New board
-          assert_difference 'Board.find(2).topics_count' do
-            assert_difference 'Board.find(2).messages_count', (1 + @message.replies_count) do
-              @message.update_attributes(:board_id => 2)
-            end
-          end
-        end
-      end
-    end
-  end
-
-  def test_destroy_topic
-    message = Message.find(1)
-    board = message.board
-    topics_count, messages_count = board.topics_count, board.messages_count
-
-    assert_difference('Watcher.count', -1) do
-      assert message.destroy
-    end
-    board.reload
-
-    # Replies deleted
-    assert Message.find_all_by_parent_id(1).empty?
-    # Checks counters
-    assert_equal topics_count - 1, board.topics_count
-    assert_equal messages_count - 3, board.messages_count
-    # Watchers removed
-  end
-
-  def test_destroy_reply
-    message = Message.find(5)
-    board = message.board
-    topics_count, messages_count = board.topics_count, board.messages_count
-    assert message.destroy
-    board.reload
-
-    # Checks counters
-    assert_equal topics_count, board.topics_count
-    assert_equal messages_count - 1, board.messages_count
-  end
-
-  def test_editable_by
-    message = Message.find(6)
-    author = message.author
-    assert message.editable_by?(author)
-
-    author.roles_for_project(message.project).first.remove_permission!(:edit_own_messages)
-    assert !message.reload.editable_by?(author.reload)
-  end
-
-  def test_destroyable_by
-    message = Message.find(6)
-    author = message.author
-    assert message.destroyable_by?(author)
-
-    author.roles_for_project(message.project).first.remove_permission!(:delete_own_messages)
-    assert !message.reload.destroyable_by?(author.reload)
-  end
-
-  def test_set_sticky
-    message = Message.new
-    assert_equal 0, message.sticky
-    message.sticky = nil
-    assert_equal 0, message.sticky
-    message.sticky = false
-    assert_equal 0, message.sticky
-    message.sticky = true
-    assert_equal 1, message.sticky
-    message.sticky = '0'
-    assert_equal 0, message.sticky
-    message.sticky = '1'
-    assert_equal 1, message.sticky
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/82/8291420c5b3c01d90eab90ab6db0630cf31b5fe0.svn-base
--- a/.svn/pristine/82/8291420c5b3c01d90eab90ab6db0630cf31b5fe0.svn-base
+++ /dev/null
@@ -1,1012 +0,0 @@
-# Update to 1.1 by Michal Gebauer <mishak@mishak.net>
-# Updated by Josef LiÅ¡ka <jl@chl.cz>
-# CZ translation by Maxim KruÅ¡ina | Massimo Filippi, s.r.o. | maxim@mxm.cz
-# Based on original CZ translation by Jan KadleÄek
-cs:
-  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y-%m-%d"
-      short: "%b %d"
-      long: "%B %d, %Y"
-      
-    day_names: [NedÄ›le, PondÄ›lÃ­, ÃšterÃ½, StÅ™eda, ÄŒtvrtek, PÃ¡tek, Sobota]
-    abbr_day_names: [Ne, Po, Ãšt, St, ÄŒt, PÃ¡, So]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Leden, Ãšnor, BÅ™ezen, Duben, KvÄ›ten, ÄŒerven, ÄŒervenec, Srpen, ZÃ¡Å™Ã­, Å˜Ã­jen, Listopad, Prosinec]
-    abbr_month_names: [~, Led, Ãšno, BÅ™e, Dub, KvÄ›, ÄŒer, ÄŒec, Srp, ZÃ¡Å™, Å˜Ã­j, Lis, Pro]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%a, %d %b %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "dop."
-    pm: "odp."
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "pÅ¯l minuty"
-      less_than_x_seconds:
-        one:   "mÃ©nÄ› neÅ¾ sekunda"
-        other: "mÃ©nÄ› neÅ¾ %{count} sekund"
-      x_seconds:
-        one:   "1 sekunda"
-        other: "%{count} sekund"
-      less_than_x_minutes:
-        one:   "mÃ©nÄ› neÅ¾ minuta"
-        other: "mÃ©nÄ› neÅ¾ %{count} minut"
-      x_minutes:
-        one:   "1 minuta"
-        other: "%{count} minut"
-      about_x_hours:
-        one:   "asi 1 hodina"
-        other: "asi %{count} hodin"
-      x_days:
-        one:   "1 den"
-        other: "%{count} dnÅ¯"
-      about_x_months:
-        one:   "asi 1 mÄ›sÃ­c"
-        other: "asi %{count} mÄ›sÃ­cÅ¯"
-      x_months:
-        one:   "1 mÄ›sÃ­c"
-        other: "%{count} mÄ›sÃ­cÅ¯"
-      about_x_years:
-        one:   "asi 1 rok"
-        other: "asi %{count} let"
-      over_x_years:
-        one:   "vÃ­ce neÅ¾ 1 rok"
-        other: "vÃ­ce neÅ¾ %{count} roky"
-      almost_x_years:
-        one:   "tÃ©meÅ™ 1 rok"
-        other: "tÃ©mÄ›Å™ %{count} roky"
-
-  number:
-    # VÃ½chozÃ­ formÃ¡t pro ÄÃ­sla
-    format:
-      separator: "." 
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Bajt"
-            other: "BajtÅ¯"
-          kb: "kB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "a"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 chyba zabrÃ¡nila uloÅ¾enÃ­ %{model}"
-          other:  "%{count} chyb zabrÃ¡nilo uloÅ¾enÃ­ %{model}"
-      messages:
-        inclusion: "nenÃ­ zahrnuto v seznamu"
-        exclusion: "je rezervovÃ¡no"
-        invalid: "je neplatnÃ©"
-        confirmation: "se neshoduje s potvrzenÃ­m"
-        accepted: "musÃ­ bÃ½t akceptovÃ¡no"
-        empty: "nemÅ¯Å¾e bÃ½t prÃ¡zdnÃ½"
-        blank: "nemÅ¯Å¾e bÃ½t prÃ¡zdnÃ½"
-        too_long: "je pÅ™Ã­liÅ¡ dlouhÃ½"
-        too_short: "je pÅ™Ã­liÅ¡ krÃ¡tkÃ½"
-        wrong_length: "mÃ¡ chybnou dÃ©lku"
-        taken: "je jiÅ¾ pouÅ¾ito"
-        not_a_number: "nenÃ­ ÄÃ­slo"
-        not_a_date: "nenÃ­ platnÃ© datum"
-        greater_than: "musÃ­ bÃ½t vÄ›tÅ¡Ã­ neÅ¾ %{count}"
-        greater_than_or_equal_to: "musÃ­ bÃ½t vÄ›tÅ¡Ã­ nebo rovno %{count}"
-        equal_to: "musÃ­ bÃ½t pÅ™esnÄ› %{count}"
-        less_than: "musÃ­ bÃ½t mÃ©nÄ› neÅ¾ %{count}"
-        less_than_or_equal_to: "musÃ­ bÃ½t mÃ©nÄ› nebo rovno %{count}"
-        odd: "musÃ­ bÃ½t lichÃ©"
-        even: "musÃ­ bÃ½t sudÃ©"
-        greater_than_start_date: "musÃ­ bÃ½t vÄ›tÅ¡Ã­ neÅ¾ poÄÃ¡teÄnÃ­ datum"
-        not_same_project: "nepatÅ™Ã­ stejnÃ©mu projektu"
-        circular_dependency: "Tento vztah by vytvoÅ™il cyklickou zÃ¡vislost"
-        cant_link_an_issue_with_a_descendant: "Ãškol nemÅ¯Å¾e bÃ½t spojen s jednÃ­m z jeho dÃ­lÄÃ­ch ÃºkolÅ¯"
-
-  actionview_instancetag_blank_option: ProsÃ­m vyberte
-  
-  general_text_No: 'Ne'
-  general_text_Yes: 'Ano'
-  general_text_no: 'ne'
-  general_text_yes: 'ano'
-  general_lang_name: 'ÄŒeÅ¡tina'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: ÃšÄet byl ÃºspÄ›Å¡nÄ› zmÄ›nÄ›n.
-  notice_account_invalid_creditentials: ChybnÃ© jmÃ©no nebo heslo
-  notice_account_password_updated: Heslo bylo ÃºspÄ›Å¡nÄ› zmÄ›nÄ›no.
-  notice_account_wrong_password: ChybnÃ© heslo
-  notice_account_register_done: ÃšÄet byl ÃºspÄ›Å¡nÄ› vytvoÅ™en. Pro aktivaci ÃºÄtu kliknÄ›te na odkaz v emailu, kterÃ½ vÃ¡m byl zaslÃ¡n.
-  notice_account_unknown_email: NeznÃ¡mÃ½ uÅ¾ivatel.
-  notice_can_t_change_password: Tento ÃºÄet pouÅ¾Ã­vÃ¡ externÃ­ autentifikaci. Zde heslo zmÄ›nit nemÅ¯Å¾ete.
-  notice_account_lost_email_sent: Byl vÃ¡m zaslÃ¡n email s intrukcemi jak si nastavÃ­te novÃ© heslo.
-  notice_account_activated: VÃ¡Å¡ ÃºÄet byl aktivovÃ¡n. NynÃ­ se mÅ¯Å¾ete pÅ™ihlÃ¡sit.
-  notice_successful_create: ÃšspÄ›Å¡nÄ› vytvoÅ™eno.
-  notice_successful_update: ÃšspÄ›Å¡nÄ› aktualizovÃ¡no.
-  notice_successful_delete: ÃšspÄ›Å¡nÄ› odstranÄ›no.
-  notice_successful_connection: ÃšspÄ›Å¡nÃ© pÅ™ipojenÃ­.
-  notice_file_not_found: StrÃ¡nka na kterou se snaÅ¾Ã­te zobrazit neexistuje nebo byla smazÃ¡na.
-  notice_locking_conflict: Ãšdaje byly zmÄ›nÄ›ny jinÃ½m uÅ¾ivatelem.
-  notice_not_authorized: NemÃ¡te dostateÄnÃ¡ prÃ¡va pro zobrazenÃ­ tÃ©to strÃ¡nky.
-  notice_not_authorized_archived_project: Projekt ke kterÃ©mu se snaÅ¾Ã­te pÅ™istupovat byl archivovÃ¡n.
-  notice_email_sent: "Na adresu %{value} byl odeslÃ¡n email"
-  notice_email_error: "PÅ™i odesÃ­lÃ¡nÃ­ emailu nastala chyba (%{value})"
-  notice_feeds_access_key_reseted: VÃ¡Å¡ klÃ­Ä pro pÅ™Ã­stup k RSS byl resetovÃ¡n.
-  notice_api_access_key_reseted: VÃ¡Å¡ API pÅ™Ã­stupovÃ½ klÃ­Ä byl resetovÃ¡n.
-  notice_failed_to_save_issues: "Chyba pÅ™i uloÅ¾enÃ­ %{count} Ãºkolu(Å¯) z %{total} vybranÃ½ch: %{ids}."
-  notice_failed_to_save_members: "NepodaÅ™ilo se uloÅ¾it Älena(y): %{errors}."
-  notice_no_issue_selected: "Nebyl zvolen Å¾Ã¡dnÃ½ Ãºkol. ProsÃ­m, zvolte Ãºkoly, kterÃ© chcete editovat"
-  notice_account_pending: "VÃ¡Å¡ ÃºÄet byl vytvoÅ™en, nynÃ­ ÄekÃ¡ na schvÃ¡lenÃ­ administrÃ¡torem."
-  notice_default_data_loaded: VÃ½chozÃ­ konfigurace ÃºspÄ›Å¡nÄ› nahrÃ¡na.
-  notice_unable_delete_version: Nemohu odstanit verzi
-  notice_unable_delete_time_entry: Nelze smazat Äas ze zÃ¡znamu.
-  notice_issue_done_ratios_updated: Koeficienty dokonÄenÃ­ Ãºkolu byly aktualizovÃ¡ny.
-  notice_gantt_chart_truncated: Graf byl oÅ™Ã­znut, poÄet poloÅ¾ek pÅ™esÃ¡hl limit pro zobrazenÃ­ (%{max})
-  
-  error_can_t_load_default_data: "VÃ½chozÃ­ konfigurace nebyla nahrÃ¡na: %{value}"
-  error_scm_not_found: "PoloÅ¾ka a/nebo revize neexistujÃ­ v repozitÃ¡Å™i."
-  error_scm_command_failed: "PÅ™i pokusu o pÅ™Ã­stup k repozitÃ¡Å™i doÅ¡lo k chybÄ›: %{value}"
-  error_scm_annotate: "PoloÅ¾ka neexistuje nebo nemÅ¯Å¾e bÃ½t komentovÃ¡na."
-  error_issue_not_found_in_project: 'Ãškol nebyl nalezen nebo nepatÅ™Ã­ k tomuto projektu'
-  error_no_tracker_in_project: Å½Ã¡dnÃ¡ fronta nebyla pÅ™iÅ™azena tomuto projektu. ProsÃ­m zkontroluje nastavenÃ­ projektu.
-  error_no_default_issue_status: NenÃ­ nastaven vÃ½chozÃ­ stav Ãºkolu. ProsÃ­m zkontrolujte nastavenÃ­ ("Administrace -> Stavy ÃºkolÅ¯").
-  error_can_not_delete_custom_field: Nelze smazat volitelnÃ© pole
-  error_can_not_delete_tracker: Tato fronta obsahuje Ãºkoly a nemÅ¯Å¾e bÃ½t smazÃ¡n.
-  error_can_not_remove_role: Tato role je prÃ¡vÄ› pouÅ¾Ã­vanÃ¡ a nelze ji smazat.
-  error_can_not_reopen_issue_on_closed_version: Ãškol pÅ™iÅ™azenÃ½ k uzavÅ™enÃ© verzi nemÅ¯Å¾e bÃ½t znovu otevÅ™en
-  error_can_not_archive_project: Tento projekt nemÅ¯Å¾e bÃ½t archivovÃ¡n
-  error_issue_done_ratios_not_updated: Koeficient dokonÄenÃ­ Ãºkolu nebyl aktualizovÃ¡n.
-  error_workflow_copy_source: ProsÃ­m vyberte zdrojovou frontu nebo roly
-  error_workflow_copy_target: ProsÃ­m vyberte cÃ­lovou frontu(y) a roly(e)
-  error_unable_delete_issue_status: Nelze smazat stavy ÃºkolÅ¯
-  error_unable_to_connect: Nelze se pÅ™ipojit (%{value})
-  warning_attachments_not_saved: "%{count} soubor(Å¯) nebylo moÅ¾nÃ© uloÅ¾it."
-  
-  mail_subject_lost_password: "VaÅ¡e heslo (%{value})"
-  mail_body_lost_password: 'Pro zmÄ›nu vaÅ¡eho hesla kliknÄ›te na nÃ¡sledujÃ­cÃ­ odkaz:'
-  mail_subject_register: "Aktivace ÃºÄtu (%{value})"
-  mail_body_register: 'Pro aktivaci vaÅ¡eho ÃºÄtu kliknÄ›te na nÃ¡sledujÃ­cÃ­ odkaz:'
-  mail_body_account_information_external: "PomocÃ­ vaÅ¡eho ÃºÄtu %{value} se mÅ¯Å¾ete pÅ™ihlÃ¡sit."
-  mail_body_account_information: Informace o vaÅ¡em ÃºÄtu
-  mail_subject_account_activation_request: "Aktivace %{value} ÃºÄtu"
-  mail_body_account_activation_request: "Byl zaregistrovÃ¡n novÃ½ uÅ¾ivatel %{value}. Aktivace jeho ÃºÄtu zÃ¡visÃ­ na vaÅ¡em potvrzenÃ­."
-  mail_subject_reminder: "%{count} Ãºkol(Å¯) mÃ¡ termÃ­n bÄ›hem nÄ›kolik dnÃ­ (%{days})"
-  mail_body_reminder: "%{count} Ãºkol(Å¯), kterÃ© mÃ¡te pÅ™iÅ™azeny mÃ¡ termÃ­n bÄ›hem nÄ›kolik dnÃ­ (%{days}):"
-  mail_subject_wiki_content_added: "'%{id}' Wiki strÃ¡nka byla pÅ™idÃ¡na"
-  mail_body_wiki_content_added: "'%{id}' Wiki strÃ¡nka byla pÅ™idÃ¡na od %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' Wiki strÃ¡nka byla aktualizovÃ¡na"
-  mail_body_wiki_content_updated: "'%{id}' Wiki strÃ¡nka byla aktualizovÃ¡na od %{author}."
-  
-  gui_validation_error: 1 chyba
-  gui_validation_error_plural: "%{count} chyb(y)"
-  
-  field_name: NÃ¡zev
-  field_description: Popis
-  field_summary: PÅ™ehled
-  field_is_required: PovinnÃ© pole
-  field_firstname: JmÃ©no
-  field_lastname: PÅ™Ã­jmenÃ­
-  field_mail: Email
-  field_filename: Soubor
-  field_filesize: Velikost
-  field_downloads: StaÅ¾eno
-  field_author: Autor
-  field_created_on: VytvoÅ™eno
-  field_updated_on: AktualizovÃ¡no
-  field_field_format: FormÃ¡t
-  field_is_for_all: Pro vÅ¡echny projekty
-  field_possible_values: MoÅ¾nÃ© hodnoty
-  field_regexp: RegulÃ¡rnÃ­ vÃ½raz
-  field_min_length: MinimÃ¡lnÃ­ dÃ©lka
-  field_max_length: MaximÃ¡lnÃ­ dÃ©lka
-  field_value: Hodnota
-  field_category: Kategorie
-  field_title: NÃ¡zev
-  field_project: Projekt
-  field_issue: Ãškol
-  field_status: Stav
-  field_notes: PoznÃ¡mka
-  field_is_closed: Ãškol uzavÅ™en
-  field_is_default: VÃ½chozÃ­ stav
-  field_tracker: Fronta
-  field_subject: PÅ™edmÄ›t
-  field_due_date: UzavÅ™Ã­t do
-  field_assigned_to: PÅ™iÅ™azeno
-  field_priority: Priorita
-  field_fixed_version: CÃ­lovÃ¡ verze
-  field_user: UÅ¾ivatel
-  field_principal: HlavnÃ­
-  field_role: Role
-  field_homepage: DomovskÃ¡ strÃ¡nka
-  field_is_public: VeÅ™ejnÃ½
-  field_parent: NadÅ™azenÃ½ projekt
-  field_is_in_roadmap: Ãškoly zobrazenÃ© v plÃ¡nu
-  field_login: PÅ™ihlÃ¡Å¡enÃ­
-  field_mail_notification: EmailovÃ¡ oznÃ¡menÃ­
-  field_admin: AdministrÃ¡tor
-  field_last_login_on: PoslednÃ­ pÅ™ihlÃ¡Å¡enÃ­
-  field_language: Jazyk
-  field_effective_date: Datum
-  field_password: Heslo
-  field_new_password: NovÃ© heslo
-  field_password_confirmation: PotvrzenÃ­
-  field_version: Verze
-  field_type: Typ
-  field_host: Host
-  field_port: Port
-  field_account: ÃšÄet
-  field_base_dn: Base DN
-  field_attr_login: PÅ™ihlÃ¡Å¡enÃ­ (atribut)
-  field_attr_firstname: JmÃ©no (atribut)
-  field_attr_lastname: PÅ™Ã­jemnÃ­ (atribut)
-  field_attr_mail: Email (atribut)
-  field_onthefly: AutomatickÃ© vytvÃ¡Å™enÃ­ uÅ¾ivatelÅ¯
-  field_start_date: ZaÄÃ¡tek
-  field_done_ratio: "% Hotovo"
-  field_auth_source: AutentifikaÄnÃ­ mÃ³d
-  field_hide_mail: Nezobrazovat mÅ¯j email
-  field_comments: KomentÃ¡Å™
-  field_url: URL
-  field_start_page: VÃ½chozÃ­ strÃ¡nka
-  field_subproject: Podprojekt
-  field_hours: Hodiny
-  field_activity: Aktivita
-  field_spent_on: Datum
-  field_identifier: IdentifikÃ¡tor
-  field_is_filter: PouÅ¾Ã­t jako filtr
-  field_issue_to: SouvisejÃ­cÃ­ Ãºkol
-  field_delay: ZpoÅ¾dÄ›nÃ­
-  field_assignable: Ãškoly mohou bÃ½t pÅ™iÅ™azeny tÃ©to roli
-  field_redirect_existing_links: PÅ™esmÄ›rovat stvÃ¡vajÃ­cÃ­ odkazy
-  field_estimated_hours: OdhadovanÃ¡ doba
-  field_column_names: Sloupce
-  field_time_entries: ZaznamenanÃ½ Äas
-  field_time_zone: ÄŒasovÃ© pÃ¡smo
-  field_searchable: UmoÅ¾nit vyhledÃ¡vÃ¡nÃ­
-  field_default_value: VÃ½chozÃ­ hodnota
-  field_comments_sorting: Zobrazit komentÃ¡Å™e
-  field_parent_title: RodiÄovskÃ¡ strÃ¡nka
-  field_editable: EditovatelnÃ½
-  field_watcher: Sleduje
-  field_identity_url: OpenID URL
-  field_content: Obsah
-  field_group_by: Seskupovat vÃ½sledky podle
-  field_sharing: SdÃ­lenÃ­
-  field_parent_issue: RodiÄovskÃ½ Ãºkol
-  field_member_of_group: Skupina pÅ™iÅ™aditele
-  field_assigned_to_role: Role pÅ™iÅ™aditele
-  field_text: TextovÃ© pole
-  field_visible: ViditelnÃ½
-  
-  setting_app_title: NÃ¡zev aplikace
-  setting_app_subtitle: Podtitulek aplikace
-  setting_welcome_text: UvÃ­tacÃ­ text
-  setting_default_language: VÃ½chozÃ­ jazyk
-  setting_login_required: Autentifikace vyÅ¾adovÃ¡na
-  setting_self_registration: Povolena automatickÃ¡ registrace
-  setting_attachment_max_size: MaximÃ¡lnÃ­ velikost pÅ™Ã­lohy
-  setting_issues_export_limit: Limit pro export ÃºkolÅ¯
-  setting_mail_from: OdesÃ­lat emaily z adresy
-  setting_bcc_recipients: PÅ™Ã­jemci skrytÃ© kopie (bcc)
-  setting_plain_text_mail: pouze prostÃ½ text (ne HTML)
-  setting_host_name: JmÃ©no serveru
-  setting_text_formatting: FormÃ¡tovÃ¡nÃ­ textu
-  setting_wiki_compression: Komprese historie Wiki
-  setting_feeds_limit: Limit obsahu pÅ™Ã­spÄ›vkÅ¯
-  setting_default_projects_public: NovÃ© projekty nastavovat jako veÅ™ejnÃ©
-  setting_autofetch_changesets: Automaticky stahovat commity
-  setting_sys_api_enabled: Povolit WS pro sprÃ¡vu repozitory
-  setting_commit_ref_keywords: KlÃ­ÄovÃ¡ slova pro odkazy
-  setting_commit_fix_keywords: KlÃ­ÄovÃ¡ slova pro uzavÅ™enÃ­
-  setting_autologin: AutomatickÃ© pÅ™ihlaÅ¡ovÃ¡nÃ­
-  setting_date_format: FormÃ¡t data
-  setting_time_format: FormÃ¡t Äasu
-  setting_cross_project_issue_relations: Povolit vazby ÃºkolÅ¯ napÅ™Ã­Ä projekty
-  setting_issue_list_default_columns: VÃ½chozÃ­ sloupce zobrazenÃ© v seznamu ÃºkolÅ¯
-  setting_emails_header: HlaviÄka emailÅ¯
-  setting_emails_footer: PatiÄka emailÅ¯
-  setting_protocol: Protokol
-  setting_per_page_options: PovolenÃ© poÄty Å™Ã¡dkÅ¯ na strÃ¡nce
-  setting_user_format: FormÃ¡t zobrazenÃ­ uÅ¾ivatele
-  setting_activity_days_default: Dny zobrazenÃ© v Äinnosti projektu
-  setting_display_subprojects_issues: Automaticky zobrazit Ãºkoly podprojektu v hlavnÃ­m projektu
-  setting_enabled_scm: PovolenÃ© SCM
-  setting_mail_handler_body_delimiters: ZkrÃ¡tit e-maily po jednom z tÄ›chto Å™Ã¡dkÅ¯
-  setting_mail_handler_api_enabled: Povolit WS pro pÅ™Ã­chozÃ­ e-maily
-  setting_mail_handler_api_key: API klÃ­Ä
-  setting_sequential_project_identifiers: Generovat sekvenÄnÃ­ identifikÃ¡tory projektÅ¯
-  setting_gravatar_enabled: PouÅ¾Ã­t uÅ¾ivatelskÃ© ikony Gravatar
-  setting_gravatar_default: VÃ½chozÃ­ Gravatar
-  setting_diff_max_lines_displayed: MaximÃ¡lnÃ­ poÄet zobrazenÃ½ch Å™Ã¡dkÅ¯ rozdÃ­lÅ¯
-  setting_file_max_size_displayed: MaximÃ¡lnÃ­ velikost textovÃ½ch souborÅ¯ zobrazenÃ½ch pÅ™Ã­mo na strÃ¡nce
-  setting_repository_log_display_limit: MaximÃ¡lnÃ­ poÄet revizÃ­ zobrazenÃ½ch v logu souboru
-  setting_openid: UmoÅ¾nit pÅ™ihlaÅ¡ovÃ¡nÃ­ a registrace s OpenID
-  setting_password_min_length: MinimÃ¡lnÃ­ dÃ©lka hesla
-  setting_new_project_user_role_id: Role pÅ™iÅ™azenÃ¡ uÅ¾ivateli bez prÃ¡v administrÃ¡tora, kterÃ½ projekt vytvoÅ™il
-  setting_default_projects_modules: VÃ½chozÃ­ zapnutnÃ© moduly pro novÃ½ projekt
-  setting_issue_done_ratio: SpoÄÃ­tat koeficient dokonÄenÃ­ Ãºkolu s
-  setting_issue_done_ratio_issue_field: PouÅ¾Ã­t pole Ãºkolu
-  setting_issue_done_ratio_issue_status: PouÅ¾Ã­t stav Ãºkolu
-  setting_start_of_week: ZaÄÃ­nat kalendÃ¡Å™e
-  setting_rest_api_enabled: Zapnout sluÅ¾bu REST
-  setting_cache_formatted_text: UklÃ¡dat formÃ¡tovanÃ½ text do vyrovnÃ¡vacÃ­ pamÄ›ti
-  setting_default_notification_option: VÃ½chozÃ­ nastavenÃ­ oznÃ¡menÃ­
-  setting_commit_logtime_enabled: Povolit zapisovÃ¡nÃ­ Äasu
-  setting_commit_logtime_activity_id: Aktivita pro zapsanÃ½ Äas
-  setting_gantt_items_limit: MaximÃ¡lnÃ­ poÄet poloÅ¾ek zobrazenÃ½ na ganttovÄ› grafu
-  
-  permission_add_project: VytvoÅ™it projekt
-  permission_add_subprojects: VytvoÅ™it podprojekty
-  permission_edit_project: Ãšprava projektÅ¯
-  permission_select_project_modules: VÃ½bÄ›r modulÅ¯ projektu
-  permission_manage_members: SpravovÃ¡nÃ­ ÄlenstvÃ­
-  permission_manage_project_activities: Spravovat aktivity projektu
-  permission_manage_versions: SpravovÃ¡nÃ­ verzÃ­
-  permission_manage_categories: SpravovÃ¡nÃ­ kategoriÃ­ ÃºkolÅ¯
-  permission_view_issues: Zobrazit Ãºkoly
-  permission_add_issues: PÅ™idÃ¡vÃ¡nÃ­ ÃºkolÅ¯
-  permission_edit_issues: UpravovÃ¡nÃ­ ÃºkolÅ¯
-  permission_manage_issue_relations: SpravovÃ¡nÃ­ vztahÅ¯ mezi Ãºkoly
-  permission_add_issue_notes: PÅ™idÃ¡vÃ¡nÃ­ poznÃ¡mek
-  permission_edit_issue_notes: UpravovÃ¡nÃ­ poznÃ¡mek
-  permission_edit_own_issue_notes: UpravovÃ¡nÃ­ vlastnÃ­ch poznÃ¡mek
-  permission_move_issues: PÅ™esouvÃ¡nÃ­ ÃºkolÅ¯
-  permission_delete_issues: MazÃ¡nÃ­ ÃºkolÅ¯
-  permission_manage_public_queries: SprÃ¡va veÅ™ejnÃ½ch dotazÅ¯
-  permission_save_queries: UklÃ¡dÃ¡nÃ­ dotazÅ¯
-  permission_view_gantt: ZobrazenÃ© Ganttova diagramu
-  permission_view_calendar: ProhlÃ­Å¾enÃ­ kalendÃ¡Å™e
-  permission_view_issue_watchers: ZobrazenÃ­ seznamu sledujÃ­cÃ­h uÅ¾ivatelÅ¯
-  permission_add_issue_watchers: PÅ™idÃ¡nÃ­ sledujÃ­cÃ­ch uÅ¾ivatelÅ¯
-  permission_delete_issue_watchers: Smazat pÅ™ihlÃ­Å¾ejÃ­cÃ­
-  permission_log_time: ZaznamenÃ¡vÃ¡nÃ­ strÃ¡venÃ©ho Äasu
-  permission_view_time_entries: ZobrazenÃ­ strÃ¡venÃ©ho Äasu
-  permission_edit_time_entries: UpravovÃ¡nÃ­ zÃ¡znamÅ¯ o strÃ¡venÃ©m Äasu
-  permission_edit_own_time_entries: UpravovÃ¡nÃ­ vlastnÃ­ch zÃ¡zamÅ¯ o strÃ¡venÃ©m Äase
-  permission_manage_news: SpravovÃ¡nÃ­ novinek
-  permission_comment_news: KomentovÃ¡nÃ­ novinek
-  permission_manage_documents: SprÃ¡va dokumentÅ¯
-  permission_view_documents: ProhlÃ­Å¾enÃ­ dokumentÅ¯
-  permission_manage_files: SpravovÃ¡nÃ­ souborÅ¯
-  permission_view_files: ProhlÃ­Å¾enÃ­ souborÅ¯
-  permission_manage_wiki: SpravovÃ¡nÃ­ Wiki
-  permission_rename_wiki_pages: PÅ™ejmenovÃ¡vÃ¡nÃ­ Wiki strÃ¡nek
-  permission_delete_wiki_pages: MazÃ¡nÃ­ strÃ¡nek na Wiki
-  permission_view_wiki_pages: ProhlÃ­Å¾enÃ­ Wiki
-  permission_view_wiki_edits: ProhlÃ­Å¾enÃ­ historie Wiki
-  permission_edit_wiki_pages: UpravovÃ¡nÃ­ strÃ¡nek Wiki
-  permission_delete_wiki_pages_attachments: MazÃ¡nÃ­ pÅ™Ã­loh
-  permission_protect_wiki_pages: ZabezpeÄenÃ­ Wiki strÃ¡nek
-  permission_manage_repository: SpravovÃ¡nÃ­ repozitÃ¡Å™e
-  permission_browse_repository: ProchÃ¡zenÃ­ repozitÃ¡Å™e
-  permission_view_changesets: ZobrazovÃ¡nÃ­ sady zmÄ›n
-  permission_commit_access: Commit pÅ™Ã­stup
-  permission_manage_boards: SprÃ¡va diskusnÃ­ch fÃ³r
-  permission_view_messages: ProhlÃ­Å¾enÃ­ zprÃ¡v
-  permission_add_messages: PosÃ­lÃ¡nÃ­ zprÃ¡v
-  permission_edit_messages: UpravovÃ¡nÃ­ zprÃ¡v
-  permission_edit_own_messages: Upravit vlastnÃ­ zprÃ¡vy
-  permission_delete_messages: MazÃ¡nÃ­ zprÃ¡v
-  permission_delete_own_messages: Smazat vlastnÃ­ zprÃ¡vy
-  permission_export_wiki_pages: Exportovat Wiki strÃ¡nky
-  permission_manage_subtasks: Spravovat podÃºkoly
-  
-  project_module_issue_tracking: SledovÃ¡nÃ­ ÃºkolÅ¯
-  project_module_time_tracking: SledovÃ¡nÃ­ Äasu
-  project_module_news: Novinky
-  project_module_documents: Dokumenty
-  project_module_files: Soubory
-  project_module_wiki: Wiki
-  project_module_repository: RepozitÃ¡Å™
-  project_module_boards: Diskuse
-  project_module_calendar: KalendÃ¡Å™
-  project_module_gantt: Gantt
-  
-  label_user: UÅ¾ivatel
-  label_user_plural: UÅ¾ivatelÃ©
-  label_user_new: NovÃ½ uÅ¾ivatel
-  label_user_anonymous: AnonymnÃ­
-  label_project: Projekt
-  label_project_new: NovÃ½ projekt
-  label_project_plural: Projekty
-  label_x_projects:
-    zero:  Å¾Ã¡dnÃ© projekty
-    one:   1 projekt
-    other: "%{count} projekty(Å¯)"
-  label_project_all: VÅ¡echny projekty
-  label_project_latest: PoslednÃ­ projekty
-  label_issue: Ãškol
-  label_issue_new: NovÃ½ Ãºkol
-  label_issue_plural: Ãškoly
-  label_issue_view_all: VÅ¡echny Ãºkoly
-  label_issues_by: "Ãškoly podle %{value}"
-  label_issue_added: Ãškol pÅ™idÃ¡n
-  label_issue_updated: Ãškol aktualizovÃ¡n
-  label_document: Dokument
-  label_document_new: NovÃ½ dokument
-  label_document_plural: Dokumenty
-  label_document_added: Dokument pÅ™idÃ¡n
-  label_role: Role
-  label_role_plural: Role
-  label_role_new: NovÃ¡ role
-  label_role_and_permissions: Role a prÃ¡va
-  label_member: ÄŒlen
-  label_member_new: NovÃ½ Älen
-  label_member_plural: ÄŒlenovÃ©
-  label_tracker: Fronta
-  label_tracker_plural: Fronty
-  label_tracker_new: NovÃ¡ fronta
-  label_workflow: PrÅ¯bÄ›h prÃ¡ce
-  label_issue_status: Stav Ãºkolu
-  label_issue_status_plural: Stavy ÃºkolÅ¯
-  label_issue_status_new: NovÃ½ stav
-  label_issue_category: Kategorie Ãºkolu
-  label_issue_category_plural: Kategorie ÃºkolÅ¯
-  label_issue_category_new: NovÃ¡ kategorie
-  label_custom_field: UÅ¾ivatelskÃ© pole
-  label_custom_field_plural: UÅ¾ivatelskÃ¡ pole
-  label_custom_field_new: NovÃ© uÅ¾ivatelskÃ© pole
-  label_enumerations: Seznamy
-  label_enumeration_new: NovÃ¡ hodnota
-  label_information: Informace
-  label_information_plural: Informace
-  label_please_login: ProsÃ­m pÅ™ihlaÅ¡te se
-  label_register: Registrovat
-  label_login_with_open_id_option: nebo se pÅ™ihlaÅ¡te s OpenID
-  label_password_lost: ZapomenutÃ© heslo
-  label_home: ÃšvodnÃ­
-  label_my_page: Moje strÃ¡nka
-  label_my_account: MÅ¯j ÃºÄet
-  label_my_projects: Moje projekty
-  label_my_page_block: Bloky na mÃ© strÃ¡nce
-  label_administration: Administrace
-  label_login: PÅ™ihlÃ¡Å¡enÃ­
-  label_logout: OdhlÃ¡Å¡enÃ­
-  label_help: NÃ¡povÄ›da
-  label_reported_issues: NahlÃ¡Å¡enÃ© Ãºkoly
-  label_assigned_to_me_issues: MÃ© Ãºkoly
-  label_last_login: PoslednÃ­ pÅ™ihlÃ¡Å¡enÃ­
-  label_registered_on: RegistrovÃ¡n
-  label_activity: Aktivita
-  label_overall_activity: CelkovÃ¡ aktivita
-  label_user_activity: "Aktivita uÅ¾ivatele: %{value}"
-  label_new: NovÃ½
-  label_logged_as: PÅ™ihlÃ¡Å¡en jako
-  label_environment: ProstÅ™edÃ­
-  label_authentication: Autentifikace
-  label_auth_source: MÃ³d autentifikace
-  label_auth_source_new: NovÃ½ mÃ³d autentifikace
-  label_auth_source_plural: MÃ³dy autentifikace
-  label_subproject_plural: Podprojekty
-  label_subproject_new: NovÃ½ podprojekt
-  label_and_its_subprojects: "%{value} a jeho  podprojekty"
-  label_min_max_length: Min - Max dÃ©lka
-  label_list: Seznam
-  label_date: Datum
-  label_integer: CelÃ© ÄÃ­slo
-  label_float: DesetinnÃ© ÄÃ­slo
-  label_boolean: Ano/Ne
-  label_string: Text
-  label_text: DlouhÃ½ text
-  label_attribute: Atribut
-  label_attribute_plural: Atributy
-  label_download: "%{count} staÅ¾enÃ­"
-  label_download_plural: "%{count} staÅ¾enÃ­"
-  label_no_data: Å½Ã¡dnÃ© poloÅ¾ky
-  label_change_status: ZmÄ›nit stav
-  label_history: Historie
-  label_attachment: Soubor
-  label_attachment_new: NovÃ½ soubor
-  label_attachment_delete: Odstranit soubor
-  label_attachment_plural: Soubory
-  label_file_added: Soubor pÅ™idÃ¡n
-  label_report: PÅ™ehled
-  label_report_plural: PÅ™ehledy
-  label_news: Novinky
-  label_news_new: PÅ™idat novinku
-  label_news_plural: Novinky
-  label_news_latest: PoslednÃ­ novinky
-  label_news_view_all: Zobrazit vÅ¡echny novinky
-  label_news_added: Novinka pÅ™idÃ¡na
-  label_settings: NastavenÃ­
-  label_overview: PÅ™ehled
-  label_version: Verze
-  label_version_new: NovÃ¡ verze
-  label_version_plural: Verze
-  label_close_versions: ZavÅ™Ã­t dokonÄenÃ© verze
-  label_confirmation: PotvrzenÃ­
-  label_export_to: 'TakÃ© k dispozici:'
-  label_read: NaÄÃ­tÃ¡ se...
-  label_public_projects: VeÅ™ejnÃ© projekty
-  label_open_issues: otevÅ™enÃ½
-  label_open_issues_plural: otevÅ™enÃ©
-  label_closed_issues: uzavÅ™enÃ½
-  label_closed_issues_plural: uzavÅ™enÃ©
-  label_x_open_issues_abbr_on_total:
-    zero:  0 otevÅ™enÃ½ch / %{total}
-    one:   1 otevÅ™enÃ½ / %{total}
-    other: "%{count} otevÅ™enÃ½ch / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 otevÅ™enÃ½ch
-    one:   1 otevÅ™enÃ½
-    other: "%{count} otevÅ™enÃ½ch"
-  label_x_closed_issues_abbr:
-    zero:  0 uzavÅ™enÃ½ch
-    one:   1 uzavÅ™enÃ½
-    other: "%{count} uzavÅ™enÃ½ch"
-  label_total: Celkem
-  label_permissions: PrÃ¡va
-  label_current_status: AktuÃ¡lnÃ­ stav
-  label_new_statuses_allowed: NovÃ© povolenÃ© stavy
-  label_all: vÅ¡e
-  label_none: nic
-  label_nobody: nikdo
-  label_next: DalÅ¡Ã­
-  label_previous: PÅ™edchozÃ­
-  label_used_by: PouÅ¾ito
-  label_details: Detaily
-  label_add_note: PÅ™idat poznÃ¡mku
-  label_per_page: Na strÃ¡nku
-  label_calendar: KalendÃ¡Å™
-  label_months_from: mÄ›sÃ­cÅ¯ od
-  label_gantt: GanttÅ¯v graf
-  label_internal: InternÃ­
-  label_last_changes: "poslednÃ­ch %{count} zmÄ›n"
-  label_change_view_all: Zobrazit vÅ¡echny zmÄ›ny
-  label_personalize_page: PÅ™izpÅ¯sobit tuto strÃ¡nku
-  label_comment: KomentÃ¡Å™
-  label_comment_plural: KomentÃ¡Å™e
-  label_x_comments:
-    zero: Å¾Ã¡dnÃ© komentÃ¡Å™e
-    one: 1 komentÃ¡Å™
-    other: "%{count} komentÃ¡Å™Å¯"
-  label_comment_add: PÅ™idat komentÃ¡Å™e
-  label_comment_added: KomentÃ¡Å™ pÅ™idÃ¡n
-  label_comment_delete: Odstranit komentÃ¡Å™
-  label_query: UÅ¾ivatelskÃ½ dotaz
-  label_query_plural: UÅ¾ivatelskÃ© dotazy
-  label_query_new: NovÃ½ dotaz
-  label_filter_add: PÅ™idat filtr
-  label_filter_plural: Filtry
-  label_equals: je
-  label_not_equals: nenÃ­
-  label_in_less_than: je mÄ›Å¡Ã­ neÅ¾
-  label_in_more_than: je vÄ›tÅ¡Ã­ neÅ¾
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: v
-  label_today: dnes
-  label_all_time: vÅ¡e
-  label_yesterday: vÄera
-  label_this_week: tento tÃ½den
-  label_last_week: minulÃ½ tÃ½den
-  label_last_n_days: "poslednÃ­ch %{count} dnÅ¯"
-  label_this_month: tento mÄ›sÃ­c
-  label_last_month: minulÃ½ mÄ›sÃ­c
-  label_this_year: tento rok
-  label_date_range: ÄŒasovÃ½ rozsah
-  label_less_than_ago: pÅ™ed mÃ©nÄ› jak (dny)
-  label_more_than_ago: pÅ™ed vÃ­ce jak (dny)
-  label_ago: pÅ™ed (dny)
-  label_contains: obsahuje
-  label_not_contains: neobsahuje
-  label_day_plural: dny
-  label_repository: RepozitÃ¡Å™
-  label_repository_plural: RepozitÃ¡Å™e
-  label_browse: ProchÃ¡zet
-  label_modification: "%{count} zmÄ›na"
-  label_modification_plural: "%{count} zmÄ›n"
-  label_branch: VÄ›tev
-  label_tag: Tag
-  label_revision: Revize
-  label_revision_plural: RevizÃ­
-  label_revision_id: "Revize %{value}"
-  label_associated_revisions: SouvisejÃ­cÃ­ verze
-  label_added: pÅ™idÃ¡no
-  label_modified: zmÄ›nÄ›no
-  label_copied: zkopÃ­rovÃ¡no
-  label_renamed: pÅ™ejmenovÃ¡no
-  label_deleted: odstranÄ›no
-  label_latest_revision: PoslednÃ­ revize
-  label_latest_revision_plural: PoslednÃ­ revize
-  label_view_revisions: Zobrazit revize
-  label_view_all_revisions: Zobrazit vÅ¡echny revize
-  label_max_size: MaximÃ¡lnÃ­ velikost
-  label_sort_highest: PÅ™esunout na zaÄÃ¡tek
-  label_sort_higher: PÅ™esunout nahoru
-  label_sort_lower: PÅ™esunout dolÅ¯
-  label_sort_lowest: PÅ™esunout na konec
-  label_roadmap: PlÃ¡n
-  label_roadmap_due_in: "ZbÃ½vÃ¡ %{value}"
-  label_roadmap_overdue: "%{value} pozdÄ›"
-  label_roadmap_no_issues: Pro tuto verzi nejsou Å¾Ã¡dnÃ© Ãºkoly
-  label_search: Hledat
-  label_result_plural: VÃ½sledky
-  label_all_words: VÅ¡echna slova
-  label_wiki: Wiki
-  label_wiki_edit: Wiki Ãºprava
-  label_wiki_edit_plural: Wiki Ãºpravy
-  label_wiki_page: Wiki strÃ¡nka
-  label_wiki_page_plural: Wiki strÃ¡nky
-  label_index_by_title: Index dle nÃ¡zvu
-  label_index_by_date: Index dle data
-  label_current_version: AktuÃ¡lnÃ­ verze
-  label_preview: NÃ¡hled
-  label_feed_plural: PÅ™Ã­spÄ›vky
-  label_changes_details: Detail vÅ¡ech zmÄ›n
-  label_issue_tracking: SledovÃ¡nÃ­ ÃºkolÅ¯
-  label_spent_time: StrÃ¡venÃ½ Äas
-  label_overall_spent_time: Celkem strÃ¡venÃ½ Äas
-  label_f_hour: "%{value} hodina"
-  label_f_hour_plural: "%{value} hodin"
-  label_time_tracking: SledovÃ¡nÃ­ Äasu
-  label_change_plural: ZmÄ›ny
-  label_statistics: Statistiky
-  label_commits_per_month: CommitÅ¯ za mÄ›sÃ­c
-  label_commits_per_author: CommitÅ¯ za autora
-  label_view_diff: Zobrazit rozdÃ­ly
-  label_diff_inline: uvnitÅ™
-  label_diff_side_by_side: vedle sebe
-  label_options: NastavenÃ­
-  label_copy_workflow_from: KopÃ­rovat prÅ¯bÄ›h prÃ¡ce z
-  label_permissions_report: PÅ™ehled prÃ¡v
-  label_watched_issues: SledovanÃ© Ãºkoly
-  label_related_issues: SouvisejÃ­cÃ­ Ãºkoly
-  label_applied_status: PouÅ¾itÃ½ stav
-  label_loading: NahrÃ¡vÃ¡m...
-  label_relation_new: NovÃ¡ souvislost
-  label_relation_delete: Odstranit souvislost
-  label_relates_to: souvisejÃ­cÃ­ s
-  label_duplicates: duplikuje
-  label_duplicated_by: zduplikovÃ¡n
-  label_blocks: blokuje
-  label_blocked_by: zablokovÃ¡n
-  label_precedes: pÅ™edchÃ¡zÃ­
-  label_follows: nÃ¡sleduje
-  label_end_to_start: od konce do zaÄÃ¡tku
-  label_end_to_end: od konce do konce
-  label_start_to_start: od zaÄÃ¡tku do zaÄÃ¡tku
-  label_start_to_end: od zaÄÃ¡tku do konce
-  label_stay_logged_in: ZÅ¯stat pÅ™ihlÃ¡Å¡enÃ½
-  label_disabled: zakÃ¡zÃ¡n
-  label_show_completed_versions: UkÃ¡zat dokonÄenÃ© verze
-  label_me: jÃ¡
-  label_board: FÃ³rum
-  label_board_new: NovÃ© fÃ³rum
-  label_board_plural: FÃ³ra
-  label_board_locked: UzamÄeno
-  label_board_sticky: NÃ¡lepka
-  label_topic_plural: TÃ©mata
-  label_message_plural: ZprÃ¡vy
-  label_message_last: PoslednÃ­ zprÃ¡va
-  label_message_new: NovÃ¡ zprÃ¡va
-  label_message_posted: ZprÃ¡va pÅ™idÃ¡na
-  label_reply_plural: OdpovÄ›di
-  label_send_information: Zaslat informace o ÃºÄtu uÅ¾ivateli
-  label_year: Rok
-  label_month: MÄ›sÃ­c
-  label_week: TÃ½den
-  label_date_from: Od
-  label_date_to: Do
-  label_language_based: Podle vÃ½chozÃ­ho jazyku
-  label_sort_by: "SeÅ™adit podle %{value}"
-  label_send_test_email: Poslat testovacÃ­ email
-  label_feeds_access_key: PÅ™Ã­stupovÃ½ klÃ­Ä pro RSS
-  label_missing_feeds_access_key: PostrÃ¡dÃ¡ pÅ™Ã­stupovÃ½ klÃ­Ä pro RSS
-  label_feeds_access_key_created_on: "PÅ™Ã­stupovÃ½ klÃ­Ä pro RSS byl vytvoÅ™en pÅ™ed %{value}"
-  label_module_plural: Moduly
-  label_added_time_by: "PÅ™idÃ¡no uÅ¾ivatelem %{author} pÅ™ed %{age}"
-  label_updated_time_by: "AktualizovÃ¡no uÅ¾ivatelem %{author} pÅ™ed %{age}"
-  label_updated_time: "AktualizovÃ¡no pÅ™ed %{value}"
-  label_jump_to_a_project: Vyberte projekt...
-  label_file_plural: Soubory
-  label_changeset_plural: Changesety
-  label_default_columns: VÃ½chozÃ­ sloupce
-  label_no_change_option: (beze zmÄ›ny)
-  label_bulk_edit_selected_issues: HromadnÃ¡ Ãºprava vybranÃ½ch ÃºkolÅ¯
-  label_theme: TÃ©ma
-  label_default: VÃ½chozÃ­
-  label_search_titles_only: VyhledÃ¡vat pouze v nÃ¡zvech
-  label_user_mail_option_all: "Pro vÅ¡echny udÃ¡losti vÅ¡ech mÃ½ch projektÅ¯"
-  label_user_mail_option_selected: "Pro vÅ¡echny udÃ¡losti vybranÃ½ch projektÅ¯..."
-  label_user_mail_option_none: "Å½Ã¡dnÃ© udÃ¡losti"
-  label_user_mail_option_only_my_events: "Jen pro vÄ›ci co sleduji nebo jsem v nich zapojen"
-  label_user_mail_option_only_assigned: "Jen pro vÅ¡eci kterÃ½m sem pÅ™iÅ™azen"
-  label_user_mail_option_only_owner: "Jen pro vÄ›ci kterÃ© vlastnÃ­m"
-  label_user_mail_no_self_notified: "NezasÃ­lat informace o mnou vytvoÅ™enÃ½ch zmÄ›nÃ¡ch"
-  label_registration_activation_by_email: aktivace ÃºÄtu emailem
-  label_registration_manual_activation: manuÃ¡lnÃ­ aktivace ÃºÄtu
-  label_registration_automatic_activation: automatickÃ¡ aktivace ÃºÄtu
-  label_display_per_page: "%{value} na strÃ¡nku"
-  label_age: VÄ›k
-  label_change_properties: ZmÄ›nit vlastnosti
-  label_general: ObecnÃ©
-  label_more: VÃ­ce
-  label_scm: SCM
-  label_plugins: DoplÅˆky
-  label_ldap_authentication: Autentifikace LDAP
-  label_downloads_abbr: StaÅ¾.
-  label_optional_description: VolitelnÃ½ popis
-  label_add_another_file: PÅ™idat dalÅ¡Ã­ soubor
-  label_preferences: NastavenÃ­
-  label_chronological_order: V chronologickÃ©m poÅ™adÃ­
-  label_reverse_chronological_order: V obrÃ¡canÃ©m chronologickÃ©m poÅ™adÃ­
-  label_planning: PlÃ¡novÃ¡nÃ­
-  label_incoming_emails: PÅ™Ã­chozÃ­ e-maily
-  label_generate_key: Generovat klÃ­Ä
-  label_issue_watchers: SledovÃ¡nÃ­
-  label_example: PÅ™Ã­klad
-  label_display: Zobrazit
-  label_sort: Å˜azenÃ­
-  label_ascending: VzestupnÄ›
-  label_descending: SestupnÄ›
-  label_date_from_to: Od %{start} do %{end}
-  label_wiki_content_added: Wiki strÃ¡nka pÅ™idÃ¡na
-  label_wiki_content_updated: Wiki strÃ¡nka aktualizovÃ¡na
-  label_group: Skupina
-  label_group_plural: Skupiny
-  label_group_new: NovÃ¡ skupina
-  label_time_entry_plural: StrÃ¡venÃ½ Äas
-  label_version_sharing_none: NesdÃ­leno
-  label_version_sharing_descendants: S podprojekty
-  label_version_sharing_hierarchy: S hierarchiÃ­ projektu
-  label_version_sharing_tree: Se stromem projektu
-  label_version_sharing_system: Se vÅ¡emi projekty
-  label_update_issue_done_ratios: Aktualizovat koeficienty dokonÄenÃ­ ÃºkolÅ¯
-  label_copy_source: Zdroj
-  label_copy_target: CÃ­l
-  label_copy_same_as_target: StejnÃ½ jako cÃ­l
-  label_display_used_statuses_only: Zobrazit pouze stavy kterÃ© jsou pouÅ¾itÃ© touto frontou
-  label_api_access_key: API pÅ™Ã­stupovÃ½ klÃ­Ä
-  label_missing_api_access_key: ChybÄ›jÃ­cÃ­ pÅ™Ã­stupovÃ½ klÃ­Ä API
-  label_api_access_key_created_on: API pÅ™Ã­stupovÃ½ klÃ­Ä vytvoÅ™en %{value} 
-  label_profile: Profil
-  label_subtask_plural: PodÃºkol
-  label_project_copy_notifications: Odeslat email oznÃ¡menÃ­ v prÅ¯bÄ›hu kopie projektu
-  label_principal_search: "Hledat uÅ¾ivatele nebo skupinu:"
-  label_user_search: "Hledat uÅ¾ivatele:"
-  
-  button_login: PÅ™ihlÃ¡sit
-  button_submit: Potvrdit
-  button_save: UloÅ¾it
-  button_check_all: ZaÅ¡rtnout vÅ¡e
-  button_uncheck_all: OdÅ¡rtnout vÅ¡e
-  button_delete: Odstranit
-  button_create: VytvoÅ™it
-  button_create_and_continue: VytvoÅ™it a pokraÄovat
-  button_test: Testovat
-  button_edit: Upravit
-  button_edit_associated_wikipage: "Upravit pÅ™iÅ™azenou Wiki strÃ¡nku: %{page_title}"
-  button_add: PÅ™idat
-  button_change: ZmÄ›nit
-  button_apply: PouÅ¾Ã­t
-  button_clear: Smazat
-  button_lock: Zamknout
-  button_unlock: Odemknout
-  button_download: StÃ¡hnout
-  button_list: Vypsat
-  button_view: Zobrazit
-  button_move: PÅ™esunout
-  button_move_and_follow: PÅ™esunout a nÃ¡sledovat
-  button_back: ZpÄ›t
-  button_cancel: Storno
-  button_activate: Aktivovat
-  button_sort: SeÅ™adit
-  button_log_time: PÅ™idat Äas
-  button_rollback: ZpÄ›t k tÃ©to verzi
-  button_watch: Sledovat
-  button_unwatch: Nesledovat
-  button_reply: OdpovÄ›dÄ›t
-  button_archive: Archivovat
-  button_unarchive: Odarchivovat
-  button_reset: Resetovat
-  button_rename: PÅ™ejmenovat
-  button_change_password: ZmÄ›nit heslo
-  button_copy: KopÃ­rovat
-  button_copy_and_follow: KopÃ­rovat a nÃ¡sledovat
-  button_annotate: Komentovat
-  button_update: Aktualizovat
-  button_configure: Konfigurovat
-  button_quote: Citovat
-  button_duplicate: Duplikovat
-  button_show: Zobrazit
-  
-  status_active: aktivnÃ­
-  status_registered: registrovanÃ½
-  status_locked: uzamÄenÃ½
-  
-  version_status_open: otevÅ™enÃ½
-  version_status_locked: uzamÄenÃ½
-  version_status_closed: zavÅ™enÃ½
-  
-  field_active: AktivnÃ­
-  
-  text_select_mail_notifications: Vyberte akci pÅ™i kterÃ© bude zaslÃ¡no upozornÄ›nÃ­ emailem.
-  text_regexp_info: napÅ™. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 znamenÃ¡ bez limitu
-  text_project_destroy_confirmation: Jste si jisti, Å¾e chcete odstranit tento projekt a vÅ¡echna souvisejÃ­cÃ­ data ?
-  text_subprojects_destroy_warning: "Jeho podprojek(y): %{value} budou takÃ© smazÃ¡ny."
-  text_workflow_edit: Vyberte roli a frontu k editaci prÅ¯bÄ›hu prÃ¡ce
-  text_are_you_sure: Jste si jisti?
-  text_are_you_sure_with_children: Smazat Ãºkol vÄetnÄ› vÅ¡ech podÃºkolÅ¯?
-  text_journal_changed: "%{label} zmÄ›nÄ›n z %{old} na %{new}"
-  text_journal_set_to: "%{label} nastaven na %{value}"
-  text_journal_deleted: "%{label} smazÃ¡n (%{old})"
-  text_journal_added: "%{label} %{value} pÅ™idÃ¡n"
-  text_tip_issue_begin_day: Ãºkol zaÄÃ­nÃ¡ v tento den
-  text_tip_issue_end_day: Ãºkol konÄÃ­ v tento den
-  text_tip_issue_begin_end_day: Ãºkol zaÄÃ­nÃ¡ a konÄÃ­ v tento den
-  text_project_identifier_info: 'Jsou povolena malÃ¡ pÃ­smena (a-z), ÄÃ­sla a pomlÄky.<br />Po uloÅ¾enÃ­ jiÅ¾ nenÃ­ moÅ¾nÃ© identifikÃ¡tor zmÄ›nit.'
-  text_caracters_maximum: "%{count} znakÅ¯ maximÃ¡lnÄ›."
-  text_caracters_minimum: "MusÃ­ bÃ½t alespoÅˆ %{count} znakÅ¯ dlouhÃ©."
-  text_length_between: "DÃ©lka mezi %{min} a %{max} znaky."
-  text_tracker_no_workflow: Pro tuto frontu nenÃ­ definovÃ¡n Å¾Ã¡dnÃ½ prÅ¯bÄ›h prÃ¡ce
-  text_unallowed_characters: NepovolenÃ© znaky
-  text_comma_separated: Povoleno vÃ­ce hodnot (oddÄ›lÄ›nÃ© ÄÃ¡rkou).
-  text_line_separated: VÃ­ce hodnot povoleno (jeden Å™Ã¡dek pro kaÅ¾dou hodnotu).
-  text_issues_ref_in_commit_messages: OdkazovÃ¡nÃ­ a opravovÃ¡nÃ­ ÃºkolÅ¯ ve zprÃ¡vÃ¡ch commitÅ¯
-  text_issue_added: "Ãškol %{id} byl vytvoÅ™en uÅ¾ivatelem %{author}."
-  text_issue_updated: "Ãškol %{id} byl aktualizovÃ¡n uÅ¾ivatelem %{author}."
-  text_wiki_destroy_confirmation: Opravdu si pÅ™ejete odstranit tuto Wiki a celÃ½ jejÃ­ obsah?
-  text_issue_category_destroy_question: "NÄ›kterÃ© Ãºkoly (%{count}) jsou pÅ™iÅ™azeny k tÃ©to kategorii. Co s nimi chtete udÄ›lat?"
-  text_issue_category_destroy_assignments: ZruÅ¡it pÅ™iÅ™azenÃ­ ke kategorii
-  text_issue_category_reassign_to: PÅ™iÅ™adit Ãºkoly do tÃ©to kategorie
-  text_user_mail_option: "U projektÅ¯, kterÃ© nebyly vybrÃ¡ny, budete dostÃ¡vat oznÃ¡menÃ­ pouze o vaÅ¡ich Äi o sledovanÃ½ch poloÅ¾kÃ¡ch (napÅ™. o poloÅ¾kÃ¡ch jejichÅ¾ jste autor nebo ke kterÃ½m jste pÅ™iÅ™azen(a))."
-  text_no_configuration_data: "Role, fronty, stavy ÃºkolÅ¯ ani prÅ¯bÄ›h prÃ¡ce nebyly zatÃ­m nakonfigurovÃ¡ny.\nVelice doporuÄujeme nahrÃ¡t vÃ½chozÃ­ konfiguraci. Po tÃ© si mÅ¯Å¾ete vÅ¡e upravit"
-  text_load_default_configuration: NahrÃ¡t vÃ½chozÃ­ konfiguraci
-  text_status_changed_by_changeset: "PouÅ¾ito v changesetu %{value}."
-  text_time_logged_by_changeset: AplikovÃ¡no v changesetu %{value}.
-  text_issues_destroy_confirmation: 'Opravdu si pÅ™ejete odstranit vÅ¡echny zvolenÃ© Ãºkoly?'
-  text_select_project_modules: 'AktivnÃ­ moduly v tomto projektu:'
-  text_default_administrator_account_changed: VÃ½chozÃ­ nastavenÃ­ administrÃ¡torskÃ©ho ÃºÄtu zmÄ›nÄ›no
-  text_file_repository_writable: Povolen zÃ¡pis do adresÃ¡Å™e uklÃ¡dÃ¡nÃ­ souborÅ¯
-  text_plugin_assets_writable: MoÅ¾nost zÃ¡pisu do adresÃ¡Å™e plugin assets
-  text_rmagick_available: RMagick k dispozici (volitelnÃ©)
-  text_destroy_time_entries_question: "U ÃºkolÅ¯, kterÃ© chcete odstranit je evidovÃ¡no %{hours} prÃ¡ce. Co chete udÄ›lat?"
-  text_destroy_time_entries: Odstranit evidovanÃ© hodiny.
-  text_assign_time_entries_to_project: PÅ™iÅ™adit evidovanÃ© hodiny projektu
-  text_reassign_time_entries: 'PÅ™eÅ™adit evidovanÃ© hodiny k tomuto Ãºkolu:'
-  text_user_wrote: "%{value} napsal:"
-  text_enumeration_destroy_question: "NÄ›kolik (%{count}) objektÅ¯ je pÅ™iÅ™azeno k tÃ©to hodnotÄ›."
-  text_enumeration_category_reassign_to: 'PÅ™eÅ™adit je do tÃ©to:'
-  text_email_delivery_not_configured: "DoruÄovÃ¡nÃ­ e-mailÅ¯ nenÃ­ nastaveno a odesÃ­lÃ¡nÃ­ notifikacÃ­ je zakÃ¡zÃ¡no.\nNastavte VÃ¡Å¡ SMTP server v souboru config/configuration.yml a restartujte aplikaci."
-  text_repository_usernames_mapping: "Vybrat nebo upravit mapovÃ¡nÃ­ mezi Redmine uÅ¾ivateli a uÅ¾ivatelskÃ½mi jmÃ©ny nalezenÃ½mi v logu repozitÃ¡Å™e.\nUÅ¾ivatelÃ© se shodnÃ½m Redmine uÅ¾ivatelskÃ½m jmÃ©nem a uÅ¾ivatelskÃ½m jmÃ©nem v repozitÃ¡Å™i jsou mapovanÃ­ automaticky."
-  text_diff_truncated: '... RozdÃ­lovÃ½ soubor je zkrÃ¡cen, protoÅ¾e jeho dÃ©lka pÅ™esahuje max. limit.'
-  text_custom_field_possible_values_info: 'KaÅ¾dÃ¡ hodnota na novÃ©m Å™Ã¡dku'
-  text_wiki_page_destroy_question: Tato strÃ¡nka mÃ¡ %{descendants} podstrÃ¡nek a potomkÅ¯. Co chcete udÄ›lat?
-  text_wiki_page_nullify_children: Ponechat podstrÃ¡nky jako koÅ™enovÃ© strÃ¡nky
-  text_wiki_page_destroy_children: Smazat podstrÃ¡nky a vÅ¡echny jejich potomky
-  text_wiki_page_reassign_children: PÅ™iÅ™adit podstrÃ¡nky k tomuto rodiÄi
-  text_own_membership_delete_confirmation: "ChystÃ¡te se odebrat si nÄ›kterÃ¡ nebo vÅ¡echny svÃ¡ oprÃ¡vnÄ›nÃ­ a potom jiÅ¾ nemusÃ­te bÃ½t schopni upravit tento projekt.\nOpravdu chcete pokraÄovat?"
-  text_zoom_in: PÅ™iblÃ­Å¾it
-  text_zoom_out: OddÃ¡lit
-  
-  default_role_manager: ManaÅ¾er
-  default_role_developer: VÃ½vojÃ¡Å™
-  default_role_reporter: ReportÃ©r
-  default_tracker_bug: Chyba
-  default_tracker_feature: PoÅ¾adavek
-  default_tracker_support: Podpora
-  default_issue_status_new: NovÃ½
-  default_issue_status_in_progress: Ve vÃ½voji
-  default_issue_status_resolved: VyÅ™eÅ¡enÃ½
-  default_issue_status_feedback: ÄŒekÃ¡ se
-  default_issue_status_closed: UzavÅ™enÃ½
-  default_issue_status_rejected: OdmÃ­tnutÃ½
-  default_doc_category_user: UÅ¾ivatelskÃ¡ dokumentace
-  default_doc_category_tech: TechnickÃ¡ dokumentace
-  default_priority_low: NÃ­zkÃ¡
-  default_priority_normal: NormÃ¡lnÃ­
-  default_priority_high: VysokÃ¡
-  default_priority_urgent: UrgentnÃ­
-  default_priority_immediate: OkamÅ¾itÃ¡
-  default_activity_design: NÃ¡vhr
-  default_activity_development: VÃ½voj
-  
-  enumeration_issue_priorities: Priority ÃºkolÅ¯
-  enumeration_doc_categories: Kategorie dokumentÅ¯
-  enumeration_activities: Aktivity (sledovÃ¡nÃ­ Äasu)
-  enumeration_system_activity: SystÃ©movÃ¡ aktivita
-
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: KÃ³dovÃ¡nÃ­ zprÃ¡v pÅ™i commitu
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/82/82b21e972ba488af04b89b832125d370772e13c3.svn-base
--- a/.svn/pristine/82/82b21e972ba488af04b89b832125d370772e13c3.svn-base
+++ /dev/null
@@ -1,187 +0,0 @@
-<% @gantt.view = self %>
-<h2><%= @query.new_record? ? l(:label_gantt) : h(@query.name) %></h2>
-
-<% form_tag({:controller => 'gantts', :action => 'show', :project_id => @project, :month => params[:month], :year => params[:year], :months => params[:months]}, :method => :get, :id => 'query_form') do %>
-<%= hidden_field_tag 'set_filter', '1' %>
-<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
-  <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
-  <div style="<%= @query.new_record? ? "" : "display: none;" %>">
-    <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
-  </div>
-</fieldset>
-
-<p class="contextual">
-  <%= gantt_zoom_link(@gantt, :in) %>
-  <%= gantt_zoom_link(@gantt, :out) %>
-</p>
-
-<p class="buttons">
-<%= text_field_tag 'months', @gantt.months, :size => 2 %>
-<%= l(:label_months_from) %>
-<%= select_month(@gantt.month_from, :prefix => "month", :discard_type => true) %>
-<%= select_year(@gantt.year_from, :prefix => "year", :discard_type => true) %>
-<%= hidden_field_tag 'zoom', @gantt.zoom %>
-
-<%= link_to_function l(:button_apply), '$("query_form").submit()', :class => 'icon icon-checked' %>
-<%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 }, :class => 'icon icon-reload' %>
-</p>
-<% end %>
-
-<%= error_messages_for 'query' %>
-<% if @query.valid? %>
-<% zoom = 1
-@gantt.zoom.times { zoom = zoom * 2 }
-
-subject_width = 330
-header_heigth = 18
-
-headers_height = header_heigth
-show_weeks = false
-show_days = false
-
-if @gantt.zoom >1
-    show_weeks = true
-    headers_height = 2*header_heigth
-    if @gantt.zoom > 2
-        show_days = true
-        headers_height = 3*header_heigth
-    end
-end
-
-# Width of the entire chart
-g_width = (@gantt.date_to - @gantt.date_from + 1)*zoom
-
-@gantt.render(:top => headers_height + 8, :zoom => zoom, :g_width => g_width, :subject_width => subject_width)
-
-g_height = [(20 * (@gantt.number_of_rows + 6))+150, 206].max
-t_height = g_height + headers_height
-
-
-%>
-
-<% if @gantt.truncated %>
-  <p class="warning"><%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %></p>
-<% end %>
-
-<table width="100%" style="border:0; border-collapse: collapse;">
-<tr>
-<td style="width:<%= subject_width %>px; padding:0px;">
-
-<div style="position:relative;height:<%= t_height + 24 %>px;width:<%= subject_width + 1 %>px;">
-<div style="right:-2px;width:<%= subject_width %>px;height:<%= headers_height %>px;background: #eee;" class="gantt_hdr"></div>
-<div style="right:-2px;width:<%= subject_width %>px;height:<%= t_height %>px;border-left: 1px solid #c0c0c0;overflow:hidden;" class="gantt_hdr"></div>
-
-<div class="gantt_subjects">
-<%= @gantt.subjects.html_safe %>
-</div>
-
-</div>
-</td>
-<td>
-
-<div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;">
-<div style="width:<%= g_width-1 %>px;height:<%= headers_height %>px;background: #eee;" class="gantt_hdr">&nbsp;</div>
-<%
-#
-# Months headers
-#
-month_f = @gantt.date_from
-left = 0
-height = (show_weeks ? header_heigth : header_heigth + g_height)
-@gantt.months.times do
-  width = ((month_f >> 1) - month_f) * zoom - 1
-  %>
-  <div style="left:<%= left %>px;width:<%= width %>px;height:<%= height %>px;" class="gantt_hdr">
-  <%= link_to h("#{month_f.year}-#{month_f.month}"), @gantt.params.merge(:year => month_f.year, :month => month_f.month), :title => "#{month_name(month_f.month)} #{month_f.year}"%>
-  </div>
-  <%
-  left = left + width + 1
-  month_f = month_f >> 1
-end %>
-
-<%
-#
-# Weeks headers
-#
-if show_weeks
-  left = 0
-  height = (show_days ? header_heigth-1 : header_heigth-1 + g_height)
-  if @gantt.date_from.cwday == 1
-      # @date_from is monday
-        week_f = @gantt.date_from
-  else
-      # find next monday after @date_from
-    week_f = @gantt.date_from + (7 - @gantt.date_from.cwday + 1)
-    width = (7 - @gantt.date_from.cwday + 1) * zoom-1
-    %>
-    <div style="left:<%= left %>px;top:19px;width:<%= width %>px;height:<%= height %>px;" class="gantt_hdr">&nbsp;</div>
-    <%
-    left = left + width+1
-  end %>
-  <%
-  while week_f <= @gantt.date_to
-    width = (week_f + 6 <= @gantt.date_to) ? 7 * zoom -1 : (@gantt.date_to - week_f + 1) * zoom-1
-    %>
-    <div style="left:<%= left %>px;top:19px;width:<%= width %>px;height:<%= height %>px;" class="gantt_hdr">
-    <small><%= week_f.cweek if width >= 16 %></small>
-    </div>
-    <%
-    left = left + width+1
-    week_f = week_f+7
-  end
-end %>
-
-<%
-#
-# Days headers
-#
-if show_days
-  left = 0
-  height = g_height + header_heigth - 1
-  wday = @gantt.date_from.cwday
-  (@gantt.date_to - @gantt.date_from + 1).to_i.times do
-  width =  zoom - 1
-  %>
-  <div style="left:<%= left %>px;top:37px;width:<%= width %>px;height:<%= height %>px;font-size:0.7em;<%= "background:#f1f1f1;" if wday > 5 %>" class="gantt_hdr">
-  <%= day_name(wday).first %>
-  </div>
-  <%
-  left = left + width+1
-  wday = wday + 1
-  wday = 1 if wday > 7
-  end
-end %>
-
-<%= @gantt.lines.html_safe %>
-
-<%
-#
-# Today red line (excluded from cache)
-#
-if Date.today >= @gantt.date_from and Date.today <= @gantt.date_to %>
-    <div style="position: absolute;height:<%= g_height %>px;top:<%= headers_height + 1 %>px;left:<%= ((Date.today-@gantt.date_from+1)*zoom).floor()-1 %>px;width:10px;border-left: 1px dashed red;">&nbsp;</div>
-<% end %>
-
-</div>
-</td>
-</tr>
-</table>
-
-<table width="100%">
-<tr>
-<td align="left"><%= link_to_content_update("\xc2\xab " + l(:label_previous), params.merge(@gantt.params_previous)) %></td>
-<td align="right"><%= link_to_content_update(l(:label_next) + " \xc2\xbb", params.merge(@gantt.params_next)) %></td>
-</tr>
-</table>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'PDF', :url => params.merge(@gantt.params) %>
-  <%= f.link_to('PNG', :url => params.merge(@gantt.params)) if @gantt.respond_to?('to_image') %>
-<% end %>
-<% end # query.valid? %>
-
-<% content_for :sidebar do %>
-    <%= render :partial => 'issues/sidebar' %>
-<% end %>
-
-<% html_title(l(:label_gantt)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/82/82bbb606607aa23e8d3efe2e04412a3682e044fa.svn-base
--- a/.svn/pristine/82/82bbb606607aa23e8d3efe2e04412a3682e044fa.svn-base
+++ /dev/null
@@ -1,64 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class SettingsController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin
-
-  def index
-    edit
-    render :action => 'edit'
-  end
-
-  def edit
-    @notifiables = Redmine::Notifiable.all
-    if request.post? && params[:settings] && params[:settings].is_a?(Hash)
-      settings = (params[:settings] || {}).dup.symbolize_keys
-      settings.each do |name, value|
-        # remove blank values in array settings
-        value.delete_if {|v| v.blank? } if value.is_a?(Array)
-        Setting[name] = value
-      end
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'edit', :tab => params[:tab]
-    else
-      @options = {}
-      @options[:user_format] = User::USER_FORMATS.keys.collect {|f| [User.current.name(f), f.to_s] }
-      @deliveries = ActionMailer::Base.perform_deliveries
-
-      @guessed_host_and_path = request.host_with_port.dup
-      @guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank?
-
-      Redmine::Themes.rescan
-    end
-  end
-
-  def plugin
-    @plugin = Redmine::Plugin.find(params[:id])
-    if request.post?
-      Setting["plugin_#{@plugin.id}"] = params[:settings]
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'plugin', :id => @plugin.id
-    else
-      @partial = @plugin.settings[:partial]
-      @settings = Setting["plugin_#{@plugin.id}"]
-    end
-  rescue Redmine::PluginNotFound
-    render_404
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/82/82e1b9240931979d108e36ebeb7d4ae4ea18f145.svn-base
--- /dev/null
+++ b/.svn/pristine/82/82e1b9240931979d108e36ebeb7d4ae4ea18f145.svn-base
@@ -0,0 +1,41 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class JournalDetail < ActiveRecord::Base
+  belongs_to :journal
+  before_save :normalize_values
+
+  private
+
+  def normalize_values
+    self.value = normalize(value)
+    self.old_value = normalize(old_value)
+  end
+
+  def normalize(v)
+    case v
+    when true
+      "1"
+    when false
+      "0"
+    when Date
+      v.strftime("%Y-%m-%d")
+    else
+      v
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/83/831d3316fec7fbf223f78f9fec03d2284831a5d0.svn-base
--- /dev/null
+++ b/.svn/pristine/83/831d3316fec7fbf223f78f9fec03d2284831a5d0.svn-base
@@ -0,0 +1,358 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssueNestedSetTest < ActiveSupport::TestCase
+  fixtures :projects, :users, :roles,
+           :trackers, :projects_trackers,
+           :issue_statuses, :issue_categories, :issue_relations,
+           :enumerations,
+           :issues
+
+  def test_create_root_issue
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+    issue1.reload
+    issue2.reload
+
+    assert_equal [issue1.id, nil, 1, 2], [issue1.root_id, issue1.parent_id, issue1.lft, issue1.rgt]
+    assert_equal [issue2.id, nil, 1, 2], [issue2.root_id, issue2.parent_id, issue2.lft, issue2.rgt]
+  end
+
+  def test_create_child_issue
+    parent = Issue.generate!
+    child =  Issue.generate!(:parent_issue_id => parent.id)
+    parent.reload
+    child.reload
+
+    assert_equal [parent.id, nil, 1, 4], [parent.root_id, parent.parent_id, parent.lft, parent.rgt]
+    assert_equal [parent.id, parent.id, 2, 3], [child.root_id, child.parent_id, child.lft, child.rgt]
+  end
+
+  def test_creating_a_child_in_a_subproject_should_validate
+    issue = Issue.generate!
+    child = Issue.new(:project_id => 3, :tracker_id => 2, :author_id => 1,
+                      :subject => 'child', :parent_issue_id => issue.id)
+    assert_save child
+    assert_equal issue, child.reload.parent
+  end
+
+  def test_creating_a_child_in_an_invalid_project_should_not_validate
+    issue = Issue.generate!
+    child = Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
+                      :subject => 'child', :parent_issue_id => issue.id)
+    assert !child.save
+    assert_not_nil child.errors[:parent_issue_id]
+  end
+
+  def test_move_a_root_to_child
+    parent1 = Issue.generate!
+    parent2 = Issue.generate!
+    child = Issue.generate!(:parent_issue_id => parent1.id)
+
+    parent2.parent_issue_id = parent1.id
+    parent2.save!
+    child.reload
+    parent1.reload
+    parent2.reload
+
+    assert_equal [parent1.id, 1, 6], [parent1.root_id, parent1.lft, parent1.rgt]
+    assert_equal [parent1.id, 4, 5], [parent2.root_id, parent2.lft, parent2.rgt]
+    assert_equal [parent1.id, 2, 3], [child.root_id, child.lft, child.rgt]
+  end
+
+  def test_move_a_child_to_root
+    parent1 = Issue.generate!
+    parent2 = Issue.generate!
+    child =   Issue.generate!(:parent_issue_id => parent1.id)
+
+    child.parent_issue_id = nil
+    child.save!
+    child.reload
+    parent1.reload
+    parent2.reload
+
+    assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt]
+    assert_equal [parent2.id, 1, 2], [parent2.root_id, parent2.lft, parent2.rgt]
+    assert_equal [child.id, 1, 2], [child.root_id, child.lft, child.rgt]
+  end
+
+  def test_move_a_child_to_another_issue
+    parent1 = Issue.generate!
+    parent2 = Issue.generate!
+    child =   Issue.generate!(:parent_issue_id => parent1.id)
+
+    child.parent_issue_id = parent2.id
+    child.save!
+    child.reload
+    parent1.reload
+    parent2.reload
+
+    assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt]
+    assert_equal [parent2.id, 1, 4], [parent2.root_id, parent2.lft, parent2.rgt]
+    assert_equal [parent2.id, 2, 3], [child.root_id, child.lft, child.rgt]
+  end
+
+  def test_move_a_child_with_descendants_to_another_issue
+    parent1 = Issue.generate!
+    parent2 = Issue.generate!
+    child =   Issue.generate!(:parent_issue_id => parent1.id)
+    grandchild = Issue.generate!(:parent_issue_id => child.id)
+
+    parent1.reload
+    parent2.reload
+    child.reload
+    grandchild.reload
+
+    assert_equal [parent1.id, 1, 6], [parent1.root_id, parent1.lft, parent1.rgt]
+    assert_equal [parent2.id, 1, 2], [parent2.root_id, parent2.lft, parent2.rgt]
+    assert_equal [parent1.id, 2, 5], [child.root_id, child.lft, child.rgt]
+    assert_equal [parent1.id, 3, 4], [grandchild.root_id, grandchild.lft, grandchild.rgt]
+
+    child.reload.parent_issue_id = parent2.id
+    child.save!
+    child.reload
+    grandchild.reload
+    parent1.reload
+    parent2.reload
+
+    assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt]
+    assert_equal [parent2.id, 1, 6], [parent2.root_id, parent2.lft, parent2.rgt]
+    assert_equal [parent2.id, 2, 5], [child.root_id, child.lft, child.rgt]
+    assert_equal [parent2.id, 3, 4], [grandchild.root_id, grandchild.lft, grandchild.rgt]
+  end
+
+  def test_move_a_child_with_descendants_to_another_project
+    parent1 = Issue.generate!
+    child =   Issue.generate!(:parent_issue_id => parent1.id)
+    grandchild = Issue.generate!(:parent_issue_id => child.id)
+
+    child.reload
+    child.project = Project.find(2)
+    assert child.save
+    child.reload
+    grandchild.reload
+    parent1.reload
+
+    assert_equal [1, parent1.id, 1, 2], [parent1.project_id, parent1.root_id, parent1.lft, parent1.rgt]
+    assert_equal [2, child.id, 1, 4], [child.project_id, child.root_id, child.lft, child.rgt]
+    assert_equal [2, child.id, 2, 3], [grandchild.project_id, grandchild.root_id, grandchild.lft, grandchild.rgt]
+  end
+
+  def test_moving_an_issue_to_a_descendant_should_not_validate
+    parent1 = Issue.generate!
+    parent2 = Issue.generate!
+    child =   Issue.generate!(:parent_issue_id => parent1.id)
+    grandchild = Issue.generate!(:parent_issue_id => child.id)
+
+    child.reload
+    child.parent_issue_id = grandchild.id
+    assert !child.save
+    assert_not_nil child.errors[:parent_issue_id]
+  end
+
+  def test_destroy_should_destroy_children
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+    issue3 = Issue.generate!(:parent_issue_id => issue2.id)
+    issue4 = Issue.generate!(:parent_issue_id => issue1.id)
+
+    issue3.init_journal(User.find(2))
+    issue3.subject = 'child with journal'
+    issue3.save!
+
+    assert_difference 'Issue.count', -2 do
+      assert_difference 'Journal.count', -1 do
+        assert_difference 'JournalDetail.count', -1 do
+          Issue.find(issue2.id).destroy
+        end
+      end
+    end
+
+    issue1.reload
+    issue4.reload
+    assert !Issue.exists?(issue2.id)
+    assert !Issue.exists?(issue3.id)
+    assert_equal [issue1.id, 1, 4], [issue1.root_id, issue1.lft, issue1.rgt]
+    assert_equal [issue1.id, 2, 3], [issue4.root_id, issue4.lft, issue4.rgt]
+  end
+  
+  def test_destroy_child_should_update_parent
+    issue = Issue.generate!
+    child1 = Issue.generate!(:parent_issue_id => issue.id)
+    child2 = Issue.generate!(:parent_issue_id => issue.id)
+    
+    issue.reload
+    assert_equal [issue.id, 1, 6], [issue.root_id, issue.lft, issue.rgt]
+    
+    child2.reload.destroy
+    
+    issue.reload
+    assert_equal [issue.id, 1, 4], [issue.root_id, issue.lft, issue.rgt]
+  end
+
+  def test_destroy_parent_issue_updated_during_children_destroy
+    parent = Issue.generate!
+    Issue.generate!(:start_date => Date.today, :parent_issue_id => parent.id)
+    Issue.generate!(:start_date => 2.days.from_now, :parent_issue_id => parent.id)
+
+    assert_difference 'Issue.count', -3 do
+      Issue.find(parent.id).destroy
+    end
+  end
+
+  def test_destroy_child_issue_with_children
+    root = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'root')
+    child = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => root.id)
+    leaf = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'leaf', :parent_issue_id => child.id)
+    leaf.init_journal(User.find(2))
+    leaf.subject = 'leaf with journal'
+    leaf.save!
+
+    assert_difference 'Issue.count', -2 do
+      assert_difference 'Journal.count', -1 do
+        assert_difference 'JournalDetail.count', -1 do
+          Issue.find(child.id).destroy
+        end
+      end
+    end
+
+    root = Issue.find(root.id)
+    assert root.leaf?, "Root issue is not a leaf (lft: #{root.lft}, rgt: #{root.rgt})"
+  end
+
+  def test_destroy_issue_with_grand_child
+    parent = Issue.generate!
+    issue = Issue.generate!(:parent_issue_id => parent.id)
+    child = Issue.generate!(:parent_issue_id => issue.id)
+    grandchild1 = Issue.generate!(:parent_issue_id => child.id)
+    grandchild2 = Issue.generate!(:parent_issue_id => child.id)
+
+    assert_difference 'Issue.count', -4 do
+      Issue.find(issue.id).destroy
+      parent.reload
+      assert_equal [1, 2], [parent.lft, parent.rgt]
+    end
+  end
+
+  def test_parent_priority_should_be_the_highest_child_priority
+    parent = Issue.generate!(:priority => IssuePriority.find_by_name('Normal'))
+    # Create children
+    child1 = Issue.generate!(:priority => IssuePriority.find_by_name('High'), :parent_issue_id => parent.id)
+    assert_equal 'High', parent.reload.priority.name
+    child2 = Issue.generate!(:priority => IssuePriority.find_by_name('Immediate'), :parent_issue_id => child1.id)
+    assert_equal 'Immediate', child1.reload.priority.name
+    assert_equal 'Immediate', parent.reload.priority.name
+    child3 = Issue.generate!(:priority => IssuePriority.find_by_name('Low'), :parent_issue_id => parent.id)
+    assert_equal 'Immediate', parent.reload.priority.name
+    # Destroy a child
+    child1.destroy
+    assert_equal 'Low', parent.reload.priority.name
+    # Update a child
+    child3.reload.priority = IssuePriority.find_by_name('Normal')
+    child3.save!
+    assert_equal 'Normal', parent.reload.priority.name
+  end
+
+  def test_parent_dates_should_be_lowest_start_and_highest_due_dates
+    parent = Issue.generate!
+    Issue.generate!(:start_date => '2010-01-25', :due_date => '2010-02-15', :parent_issue_id => parent.id)
+    Issue.generate!(                             :due_date => '2010-02-13', :parent_issue_id => parent.id)
+    Issue.generate!(:start_date => '2010-02-01', :due_date => '2010-02-22', :parent_issue_id => parent.id)
+    parent.reload
+    assert_equal Date.parse('2010-01-25'), parent.start_date
+    assert_equal Date.parse('2010-02-22'), parent.due_date
+  end
+
+  def test_parent_done_ratio_should_be_average_done_ratio_of_leaves
+    parent = Issue.generate!
+    Issue.generate!(:done_ratio => 20, :parent_issue_id => parent.id)
+    assert_equal 20, parent.reload.done_ratio
+    Issue.generate!(:done_ratio => 70, :parent_issue_id => parent.id)
+    assert_equal 45, parent.reload.done_ratio
+
+    child = Issue.generate!(:done_ratio => 0, :parent_issue_id => parent.id)
+    assert_equal 30, parent.reload.done_ratio
+
+    Issue.generate!(:done_ratio => 30, :parent_issue_id => child.id)
+    assert_equal 30, child.reload.done_ratio
+    assert_equal 40, parent.reload.done_ratio
+  end
+
+  def test_parent_done_ratio_should_be_weighted_by_estimated_times_if_any
+    parent = Issue.generate!
+    Issue.generate!(:estimated_hours => 10, :done_ratio => 20, :parent_issue_id => parent.id)
+    assert_equal 20, parent.reload.done_ratio
+    Issue.generate!(:estimated_hours => 20, :done_ratio => 50, :parent_issue_id => parent.id)
+    assert_equal (50 * 20 + 20 * 10) / 30, parent.reload.done_ratio
+  end
+
+  def test_parent_estimate_should_be_sum_of_leaves
+    parent = Issue.generate!
+    Issue.generate!(:estimated_hours => nil, :parent_issue_id => parent.id)
+    assert_equal nil, parent.reload.estimated_hours
+    Issue.generate!(:estimated_hours => 5, :parent_issue_id => parent.id)
+    assert_equal 5, parent.reload.estimated_hours
+    Issue.generate!(:estimated_hours => 7, :parent_issue_id => parent.id)
+    assert_equal 12, parent.reload.estimated_hours
+  end
+
+  def test_move_parent_updates_old_parent_attributes
+    first_parent = Issue.generate!
+    second_parent = Issue.generate!
+    child = Issue.generate!(:estimated_hours => 5, :parent_issue_id => first_parent.id)
+    assert_equal 5, first_parent.reload.estimated_hours
+    child.update_attributes(:estimated_hours => 7, :parent_issue_id => second_parent.id)
+    assert_equal 7, second_parent.reload.estimated_hours
+    assert_nil first_parent.reload.estimated_hours
+  end
+
+  def test_reschuling_a_parent_should_reschedule_subtasks
+    parent = Issue.generate!
+    c1 = Issue.generate!(:start_date => '2010-05-12', :due_date => '2010-05-18', :parent_issue_id => parent.id)
+    c2 = Issue.generate!(:start_date => '2010-06-03', :due_date => '2010-06-10', :parent_issue_id => parent.id)
+    parent.reload
+    parent.reschedule_on!(Date.parse('2010-06-02'))
+    c1.reload
+    assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-08')], [c1.start_date, c1.due_date]
+    c2.reload
+    assert_equal [Date.parse('2010-06-03'), Date.parse('2010-06-10')], [c2.start_date, c2.due_date] # no change
+    parent.reload
+    assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-10')], [parent.start_date, parent.due_date]
+  end
+
+  def test_project_copy_should_copy_issue_tree
+    p = Project.create!(:name => 'Tree copy', :identifier => 'tree-copy', :tracker_ids => [1, 2])
+    i1 = Issue.generate!(:project => p, :subject => 'i1')
+    i2 = Issue.generate!(:project => p, :subject => 'i2', :parent_issue_id => i1.id)
+    i3 = Issue.generate!(:project => p, :subject => 'i3', :parent_issue_id => i1.id)
+    i4 = Issue.generate!(:project => p, :subject => 'i4', :parent_issue_id => i2.id)
+    i5 = Issue.generate!(:project => p, :subject => 'i5')
+    c = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1, 2])
+    c.copy(p, :only => 'issues')
+    c.reload
+
+    assert_equal 5, c.issues.count
+    ic1, ic2, ic3, ic4, ic5 = c.issues.order('subject').all
+    assert ic1.root?
+    assert_equal ic1, ic2.parent
+    assert_equal ic1, ic3.parent
+    assert_equal ic2, ic4.parent
+    assert ic5.root?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/83/834d9cf4dced150304b5d64254144f6c7a1f3283.svn-base
--- a/.svn/pristine/83/834d9cf4dced150304b5d64254144f6c7a1f3283.svn-base
+++ /dev/null
@@ -1,107 +0,0 @@
-<script language="JavaScript">
-//<![CDATA[
-function recreateSortables() {
-    Sortable.destroy('list-top');
-    Sortable.destroy('list-left');
-    Sortable.destroy('list-right');
-
-  Sortable.create("list-top", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('<%= url_for(:controller => 'my', :action => 'order_blocks', :group => 'top') %>', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("list-top")})}, only:'mypage-box', tag:'div'})
-  Sortable.create("list-left", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('<%= url_for(:controller => 'my', :action => 'order_blocks', :group => 'left') %>', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("list-left")})}, only:'mypage-box', tag:'div'})
-  Sortable.create("list-right", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('<%= url_for(:controller => 'my', :action => 'order_blocks', :group => 'right') %>', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("list-right")})}, only:'mypage-box', tag:'div'})
-}
-
-function updateSelect() {
-    s = $('block-select')
-    for (var i = 0; i < s.options.length; i++) {
-        if ($('block_' + s.options[i].value)) {
-            s.options[i].disabled = true;
-        } else {
-            s.options[i].disabled = false;
-        }
-    }
-    s.options[0].selected = true;
-}
-
-function afterAddBlock() {
-    recreateSortables();
-    updateSelect();
-}
-
-function removeBlock(block) {
-    Effect.DropOut(block);
-    updateSelect();
-}
-//]]>
-</script>
-
-<div class="contextual">
-<% form_tag({:action => "add_block"}, :id => "block-form") do %>
-<%= label_tag('block-select', l(:label_my_page_block)) %>:
-<%= select_tag 'block', "<option></option>" + options_for_select(@block_options), :id => "block-select" %>
-<%= link_to_remote l(:button_add),
-           {:url => { :action => "add_block" },
-            :with => "Form.serialize('block-form')",
-            :update => "list-top",
-            :position => :top,
-            :complete => "afterAddBlock();"
-           }, :class => 'icon icon-add'
-             %>
-<% end %>
-<%= link_to l(:button_back), {:action => 'page'}, :class => 'icon icon-cancel' %>
-</div>
-
-<h2><%=l(:label_my_page)%></h2>
-
-<div id="list-top" class="block-receiver">
-  <% @blocks['top'].each do |b|
-     next unless MyController::BLOCKS.keys.include? b %>
-  <%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %>
-  <% end if @blocks['top'] %>
-</div>
-
-<div id="list-left" class="splitcontentleft block-receiver">
-  <% @blocks['left'].each do |b|
-     next unless MyController::BLOCKS.keys.include? b %>
-  <%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %>
-  <% end if @blocks['left'] %>
-</div>
-
-<div id="list-right" class="splitcontentright block-receiver">
-  <% @blocks['right'].each do |b|
-     next unless MyController::BLOCKS.keys.include? b %>
-  <%= render :partial => 'block', :locals => {:user => @user, :block_name => b} %>
-  <% end if @blocks['right'] %>
-</div>
-
-<%= sortable_element 'list-top',
-      :tag => 'div',
-      :only => 'mypage-box',
-      :handle => "handle",
-      :dropOnEmpty => true,
-      :containment => ['list-top', 'list-left', 'list-right'],
-      :constraint => false,
-      :url => { :action => "order_blocks", :group => "top" }
-       %>
-
-<%= sortable_element 'list-left',
-      :tag => 'div',
-      :only => 'mypage-box',
-      :handle => "handle",
-      :dropOnEmpty => true,
-      :containment => ['list-top', 'list-left', 'list-right'],
-      :constraint => false,
-      :url => { :action => "order_blocks", :group => "left" }
-       %>
-
-<%= sortable_element 'list-right',
-      :tag => 'div',
-      :only => 'mypage-box',
-      :handle => "handle",
-      :dropOnEmpty => true,
-      :containment => ['list-top', 'list-left', 'list-right'],
-      :constraint => false,
-      :url => { :action => "order_blocks", :group => "right" }
-       %>
-
-<%= javascript_tag "updateSelect()" %>
-<% html_title(l(:label_my_page)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/83/8360f4a19732e489ca5ff590b12c243a5092c5f6.svn-base
--- a/.svn/pristine/83/8360f4a19732e489ca5ff590b12c243a5092c5f6.svn-base
+++ /dev/null
@@ -1,56 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module SyntaxHighlighting
-
-    class << self
-      attr_reader :highlighter
-      delegate :highlight_by_filename, :highlight_by_language, :to => :highlighter
-
-      def highlighter=(name)
-        if name.is_a?(Module)
-          @highlighter = name
-        else
-          @highlighter = const_get(name)
-        end
-      end
-    end
-
-    module CodeRay
-      require 'coderay'
-      require 'coderay/helpers/file_type'
-
-      class << self
-        # Highlights +text+ as the content of +filename+
-        # Should not return line numbers nor outer pre tag
-        def highlight_by_filename(text, filename)
-          language = ::CodeRay::FileType[filename]
-          language ? ::CodeRay.scan(text, language).html : ERB::Util.h(text)
-        end
-
-        # Highlights +text+ using +language+ syntax
-        # Should not return outer pre tag
-        def highlight_by_language(text, language)
-          ::CodeRay.scan(text, language).html(:line_numbers => :inline, :line_number_anchors => false, :wrap => :span)
-        end
-      end
-    end
-  end
-
-  SyntaxHighlighting.highlighter = 'CodeRay'
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/83/83a71fa0994c919b743d5f425de3265db363c4cc.svn-base
--- a/.svn/pristine/83/83a71fa0994c919b743d5f425de3265db363c4cc.svn-base
+++ /dev/null
@@ -1,28 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Views
-    class ApiTemplateHandler < ActionView::TemplateHandler
-      include ActionView::TemplateHandlers::Compilable
-
-      def compile(template)
-        "Redmine::Views::Builders.for(params[:format]) do |api|; #{template.source}; self.output_buffer = api.output; end"
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/83/83aea0eb2f9d845231bab48205698f5fdab2c21a.svn-base
--- /dev/null
+++ b/.svn/pristine/83/83aea0eb2f9d845231bab48205698f5fdab2c21a.svn-base
@@ -0,0 +1,7 @@
+<h2><%=l(:label_auth_source_new)%> (<%= h(@auth_source.auth_method_name) %>)</h2>
+
+<%= labelled_form_for @auth_source, :as => :auth_source, :url => auth_sources_path, :html => {:id => 'auth_source_form'} do |f| %>
+  <%= hidden_field_tag 'type', @auth_source.type %>
+  <%= render :partial => auth_source_partial_name(@auth_source), :locals => { :f => f } %>
+  <%= submit_tag l(:button_create) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/83/83b13898f7eab0943573424303e9d171d7a1a13a.svn-base
--- a/.svn/pristine/83/83b13898f7eab0943573424303e9d171d7a1a13a.svn-base
+++ /dev/null
@@ -1,58 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class DocumentTest < ActiveSupport::TestCase
-  fixtures :projects, :enumerations, :documents, :attachments
-
-  def test_create
-    doc = Document.new(:project => Project.find(1), :title => 'New document', :category => Enumeration.find_by_name('User documentation'))
-    assert doc.save
-  end
-
-  def test_create_should_send_email_notification
-    ActionMailer::Base.deliveries.clear
-    Setting.notified_events << 'document_added'
-    doc = Document.new(:project => Project.find(1), :title => 'New document', :category => Enumeration.find_by_name('User documentation'))
-
-    assert doc.save
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_create_with_default_category
-    # Sets a default category
-    e = Enumeration.find_by_name('Technical documentation')
-    e.update_attributes(:is_default => true)
-
-    doc = Document.new(:project => Project.find(1), :title => 'New document')
-    assert_equal e, doc.category
-    assert doc.save
-  end
-
-  def test_updated_on_with_attachments
-    d = Document.find(1)
-    assert d.attachments.any?
-    assert_equal d.attachments.map(&:created_on).max, d.updated_on
-  end
-
-  def test_updated_on_without_attachments
-    d = Document.find(2)
-    assert d.attachments.empty?
-    assert_equal d.created_on, d.updated_on
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/83/83c3e4ac7042c55f0008c2a13f02fb3cd6cd5e71.svn-base
--- a/.svn/pristine/83/83c3e4ac7042c55f0008c2a13f02fb3cd6cd5e71.svn-base
+++ /dev/null
@@ -1,140 +0,0 @@
-# Taken from Rails 2.1
-module CollectiveIdea #:nodoc:
-  module NamedScope #:nodoc:
-    # All subclasses of ActiveRecord::Base have two named_scopes:
-    # * <tt>all</tt>, which is similar to a <tt>find(:all)</tt> query, and
-    # * <tt>scoped</tt>, which allows for the creation of anonymous scopes, on the fly:
-    #
-    #   Shirt.scoped(:conditions => {:color => 'red'}).scoped(:include => :washing_instructions)
-    #
-    # These anonymous scopes tend to be useful when procedurally generating complex queries, where passing
-    # intermediate values (scopes) around as first-class objects is convenient.
-    def self.included(base)
-      base.class_eval do
-        extend ClassMethods
-        named_scope :scoped, lambda { |scope| scope }
-      end
-    end
-
-    module ClassMethods #:nodoc:
-      def scopes
-        read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
-      end
-
-      # Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query,
-      # such as <tt>:conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions</tt>.
-      #
-      #   class Shirt < ActiveRecord::Base
-      #     named_scope :red, :conditions => {:color => 'red'}
-      #     named_scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true]
-      #   end
-      # 
-      # The above calls to <tt>named_scope</tt> define class methods <tt>Shirt.red</tt> and <tt>Shirt.dry_clean_only</tt>. <tt>Shirt.red</tt>, 
-      # in effect, represents the query <tt>Shirt.find(:all, :conditions => {:color => 'red'})</tt>.
-      #
-      # Unlike Shirt.find(...), however, the object returned by <tt>Shirt.red</tt> is not an Array; it resembles the association object
-      # constructed by a <tt>has_many</tt> declaration. For instance, you can invoke <tt>Shirt.red.find(:first)</tt>, <tt>Shirt.red.count</tt>,
-      # <tt>Shirt.red.find(:all, :conditions => {:size => 'small'})</tt>. Also, just
-      # as with the association objects, name scopes acts like an Array, implementing Enumerable; <tt>Shirt.red.each(&block)</tt>,
-      # <tt>Shirt.red.first</tt>, and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if Shirt.red really were an Array.
-      #
-      # These named scopes are composable. For instance, <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are both red and dry clean only.
-      # Nested finds and calculations also work with these compositions: <tt>Shirt.red.dry_clean_only.count</tt> returns the number of garments
-      # for which these criteria obtain. Similarly with <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>.
-      #
-      # All scopes are available as class methods on the ActiveRecord descendent upon which the scopes were defined. But they are also available to
-      # <tt>has_many</tt> associations. If,
-      #
-      #   class Person < ActiveRecord::Base
-      #     has_many :shirts
-      #   end
-      #
-      # then <tt>elton.shirts.red.dry_clean_only</tt> will return all of Elton's red, dry clean
-      # only shirts.
-      #
-      # Named scopes can also be procedural.
-      #
-      #   class Shirt < ActiveRecord::Base
-      #     named_scope :colored, lambda { |color|
-      #       { :conditions => { :color => color } }
-      #     }
-      #   end
-      #
-      # In this example, <tt>Shirt.colored('puce')</tt> finds all puce shirts.
-      #
-      # Named scopes can also have extensions, just as with <tt>has_many</tt> declarations:
-      #
-      #   class Shirt < ActiveRecord::Base
-      #     named_scope :red, :conditions => {:color => 'red'} do
-      #       def dom_id
-      #         'red_shirts'
-      #       end
-      #     end
-      #   end
-      #
-      #
-      # For testing complex named scopes, you can examine the scoping options using the
-      # <tt>proxy_options</tt> method on the proxy itself.
-      #
-      #   class Shirt < ActiveRecord::Base
-      #     named_scope :colored, lambda { |color|
-      #       { :conditions => { :color => color } }
-      #     }
-      #   end
-      #
-      #   expected_options = { :conditions => { :colored => 'red' } }
-      #   assert_equal expected_options, Shirt.colored('red').proxy_options
-      def named_scope(name, options = {}, &block)
-        scopes[name] = lambda do |parent_scope, *args|
-          Scope.new(parent_scope, case options
-            when Hash
-              options
-            when Proc
-              options.call(*args)
-          end, &block)
-        end
-        (class << self; self end).instance_eval do
-          define_method name do |*args|
-            scopes[name].call(self, *args)
-          end
-        end
-      end
-    end
-
-    class Scope #:nodoc:
-      attr_reader :proxy_scope, :proxy_options
-      [].methods.each { |m| delegate m, :to => :proxy_found unless m =~ /(^__|^nil\?|^send|class|extend|find|count|sum|average|maximum|minimum|paginate)/ }
-      delegate :scopes, :with_scope, :to => :proxy_scope
-
-      def initialize(proxy_scope, options, &block)
-        [options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
-        extend Module.new(&block) if block_given?
-        @proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
-      end
-
-      def reload
-        load_found; self
-      end
-
-      protected
-      def proxy_found
-        @found || load_found
-      end
-
-      private
-      def method_missing(method, *args, &block)
-        if scopes.include?(method)
-          scopes[method].call(self, *args)
-        else
-          with_scope :find => proxy_options do
-            proxy_scope.send(method, *args, &block)
-          end
-        end
-      end
-
-      def load_found
-        @found = find(:all)
-      end
-    end
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/83/83e9bc8b42104b913718f6e8799f58710545ff76.svn-base
--- /dev/null
+++ b/.svn/pristine/83/83e9bc8b42104b913718f6e8799f58710545ff76.svn-base
@@ -0,0 +1,58 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingDocumentsTest < ActionController::IntegrationTest
+  def test_documents_scoped_under_project
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/documents" },
+        { :controller => 'documents', :action => 'index', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/documents/new" },
+        { :controller => 'documents', :action => 'new', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/567/documents" },
+        { :controller => 'documents', :action => 'create', :project_id => '567' }
+      )
+  end
+
+  def test_documents
+    assert_routing(
+        { :method => 'get', :path => "/documents/22" },
+        { :controller => 'documents', :action => 'show', :id => '22' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/documents/22/edit" },
+        { :controller => 'documents', :action => 'edit', :id => '22' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/documents/22" },
+        { :controller => 'documents', :action => 'update', :id => '22' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/documents/22" },
+        { :controller => 'documents', :action => 'destroy', :id => '22' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/documents/22/add_attachment" },
+        { :controller => 'documents', :action => 'add_attachment', :id => '22' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/84/84091f2a3428fd01f5592918d3e84fd8efa86bdf.svn-base
--- /dev/null
+++ b/.svn/pristine/84/84091f2a3428fd01f5592918d3e84fd8efa86bdf.svn-base
@@ -0,0 +1,40 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class DocumentCategory < Enumeration
+  has_many :documents, :foreign_key => 'category_id'
+
+  OptionName = :enumeration_doc_categories
+
+  def option_name
+    OptionName
+  end
+
+  def objects_count
+    documents.count
+  end
+
+  def transfer_relations(to)
+    documents.update_all("category_id = #{to.id}")
+  end
+
+  def self.default
+    d = super
+    d = first if d.nil?
+    d
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/84/841186dcecffe41ae1f674267a63d3d2f8a4647b.svn-base
--- /dev/null
+++ b/.svn/pristine/84/841186dcecffe41ae1f674267a63d3d2f8a4647b.svn-base
@@ -0,0 +1,61 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingWatchersTest < ActionController::IntegrationTest
+  def test_watchers
+    assert_routing(
+        { :method => 'get', :path => "/watchers/new" },
+        { :controller => 'watchers', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/watchers/append" },
+        { :controller => 'watchers', :action => 'append' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/watchers" },
+        { :controller => 'watchers', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/watchers" },
+        { :controller => 'watchers', :action => 'destroy' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/watchers/autocomplete_for_user" },
+        { :controller => 'watchers', :action => 'autocomplete_for_user' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/watchers/watch" },
+        { :controller => 'watchers', :action => 'watch' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/watchers/watch" },
+        { :controller => 'watchers', :action => 'unwatch' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issues/12/watchers.xml" },
+        { :controller => 'watchers', :action => 'create',
+          :object_type => 'issue', :object_id => '12', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/issues/12/watchers/3.xml" },
+        { :controller => 'watchers', :action => 'destroy',
+          :object_type => 'issue', :object_id => '12', :user_id => '3', :format => 'xml'}
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/84/842d236f9067b05ac81fdd2d952a30deb65e8f8c.svn-base
--- a/.svn/pristine/84/842d236f9067b05ac81fdd2d952a30deb65e8f8c.svn-base
+++ /dev/null
@@ -1,1049 +0,0 @@
-# Swedish translation for Ruby on Rails
-# by Johan LundstrÃ¶m (johanlunds@gmail.com),
-# with parts taken from http://github.com/daniel/swe_rails
-
-sv:
-  number:
-    # Used in number_with_delimiter()
-    # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
-    format:
-      # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
-      separator: ","
-      # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
-      delimiter: "."
-      # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
-      precision: 2
-      
-    # Used in number_to_currency()
-    currency:
-      format:
-        # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
-        format: "%n %u"
-        unit: "kr"
-        # These three are to override number.format and are optional
-        # separator: "."
-        # delimiter: ","
-        # precision: 2
-        
-    # Used in number_to_percentage()
-    percentage:
-      format:
-        # These three are to override number.format and are optional
-        # separator: 
-        delimiter: ""
-        # precision: 
-        
-    # Used in number_to_precision()
-    precision:
-      format:
-        # These three are to override number.format and are optional
-        # separator:
-        delimiter: ""
-        # precision:
-        
-    # Used in number_to_human_size()
-    human:
-      format:
-        # These three are to override number.format and are optional
-        # separator: 
-        delimiter: ""
-        # precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "kB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
-  datetime:
-    distance_in_words:
-      half_a_minute: "en halv minut"
-      less_than_x_seconds:
-        one:   "mindre Ã¤n en sekund"
-        other: "mindre Ã¤n %{count} sekunder"
-      x_seconds:
-        one:   "en sekund"
-        other: "%{count} sekunder"
-      less_than_x_minutes:
-        one:   "mindre Ã¤n en minut"
-        other: "mindre Ã¤n %{count} minuter"
-      x_minutes:
-        one:   "en minut"
-        other: "%{count} minuter"
-      about_x_hours:
-        one:   "ungefÃ¤r en timme"
-        other: "ungefÃ¤r %{count} timmar"
-      x_days:
-        one:   "en dag"
-        other: "%{count} dagar"
-      about_x_months:
-        one:   "ungefÃ¤r en mÃ¥nad"
-        other: "ungefÃ¤r %{count} mÃ¥nader"
-      x_months:
-        one:   "en mÃ¥nad"
-        other: "%{count} mÃ¥nader"
-      about_x_years:
-        one:   "ungefÃ¤r ett Ã¥r"
-        other: "ungefÃ¤r %{count} Ã¥r"
-      over_x_years:
-        one:   "mer Ã¤n ett Ã¥r"
-        other: "mer Ã¤n %{count} Ã¥r"
-      almost_x_years:
-        one:   "nÃ¤stan 1 Ã¥r"
-        other: "nÃ¤stan %{count} Ã¥r"
-        
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "Ett fel fÃ¶rhindrade denna %{model} frÃ¥n att sparas"
-          other:  "%{count} fel fÃ¶rhindrade denna %{model} frÃ¥n att sparas"
-        # The variable :count is also available
-        body: "Det var problem med fÃ¶ljande fÃ¤lt:"
-      # The values :model, :attribute and :value are always available for interpolation
-      # The value :count is available when applicable. Can be used for pluralization.
-      messages:
-        inclusion: "finns inte i listan"
-        exclusion: "Ã¤r reserverat"
-        invalid: "Ã¤r ogiltigt"
-        confirmation: "stÃ¤mmer inte Ã¶verens"
-        accepted : "mÃ¥ste vara accepterad"
-        empty: "fÃ¥r ej vara tom"
-        blank: "mÃ¥ste anges"
-        too_long: "Ã¤r fÃ¶r lÃ¥ng (maximum Ã¤r %{count} tecken)"
-        too_short: "Ã¤r fÃ¶r kort (minimum Ã¤r %{count} tecken)"
-        wrong_length: "har fel lÃ¤ngd (ska vara %{count} tecken)"
-        taken: "har redan tagits"
-        not_a_number: "Ã¤r inte ett nummer"
-        greater_than: "mÃ¥ste vara stÃ¶rre Ã¤n %{count}"
-        greater_than_or_equal_to: "mÃ¥ste vara stÃ¶rre Ã¤n eller lika med %{count}"
-        equal_to: "mÃ¥ste vara samma som"
-        less_than: "mÃ¥ste vara mindre Ã¤n %{count}"
-        less_than_or_equal_to: "mÃ¥ste vara mindre Ã¤n eller lika med %{count}"
-        odd: "mÃ¥ste vara udda"
-        even: "mÃ¥ste vara jÃ¤mnt"
-        greater_than_start_date: "mÃ¥ste vara senare Ã¤n startdatumet"
-        not_same_project: "tillhÃ¶r inte samma projekt"
-        circular_dependency: "Denna relation skulle skapa ett cirkulÃ¤rt beroende"
-        cant_link_an_issue_with_a_descendant: "Ett Ã¤rende kan inte lÃ¤nkas till ett av dess underÃ¤renden"
-
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y-%m-%d"
-      short: "%e %b"
-      long: "%e %B, %Y"
-      
-    day_names: [sÃ¶ndag, mÃ¥ndag, tisdag, onsdag, torsdag, fredag, lÃ¶rdag]
-    abbr_day_names: [sÃ¶n, mÃ¥n, tis, ons, tor, fre, lÃ¶r]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, januari, februari, mars, april, maj, juni, juli, augusti, september, oktober, november, december]
-    abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, dec]
-    # Used in date_select and datime_select.
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%Y-%m-%d %H:%M"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%d %B, %Y %H:%M"
-    am: ""
-    pm: ""
-      
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "och"
-      skip_last_comma: true
-
-  actionview_instancetag_blank_option: Var god vÃ¤lj
-  
-  general_text_No: 'Nej'
-  general_text_Yes: 'Ja'
-  general_text_no: 'nej'
-  general_text_yes: 'ja'
-  general_lang_name: 'Svenska'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: Kontot har uppdaterats
-  notice_account_invalid_creditentials: Fel anvÃ¤ndarnamn eller lÃ¶senord
-  notice_account_password_updated: LÃ¶senordet har uppdaterats
-  notice_account_wrong_password: Fel lÃ¶senord
-  notice_account_register_done: Kontot har skapats. FÃ¶r att aktivera kontot, klicka pÃ¥ lÃ¤nken i mailet som skickades till dig.
-  notice_account_unknown_email: OkÃ¤nd anvÃ¤ndare.
-  notice_can_t_change_password: Detta konto anvÃ¤nder en extern autentiseringskÃ¤lla. Det gÃ¥r inte att byta lÃ¶senord.
-  notice_account_lost_email_sent: Ett mail med instruktioner om hur man vÃ¤ljer ett nytt lÃ¶senord har skickats till dig.
-  notice_account_activated: Ditt konto har blivit aktiverat. Du kan nu logga in.
-  notice_successful_create: Skapades korrekt.
-  notice_successful_update: Uppdatering lyckades.
-  notice_successful_delete: Borttagning lyckades.
-  notice_successful_connection: Uppkoppling lyckades.
-  notice_file_not_found: Sidan du fÃ¶rsÃ¶kte komma Ã¥t existerar inte eller Ã¤r borttagen.
-  notice_locking_conflict: Data har uppdaterats av en annan anvÃ¤ndare.
-  notice_not_authorized: Du saknar behÃ¶righet att komma Ã¥t den hÃ¤r sidan.
-  notice_not_authorized_archived_project: Projektet du fÃ¶rsÃ¶ker komma Ã¥t har arkiverats.
-  notice_email_sent: "Ett mail skickades till %{value}"
-  notice_email_error: "Ett fel intrÃ¤ffade nÃ¤r mail skickades (%{value})"
-  notice_feeds_access_key_reseted: Din RSS-nyckel Ã¥terstÃ¤lldes.
-  notice_api_access_key_reseted: Din API-nyckel Ã¥terstÃ¤lldes.
-  notice_failed_to_save_issues: "Misslyckades med att spara %{count} Ã¤rende(n) pÃ¥ %{total} valt: %{ids}."
-  notice_failed_to_save_members: "Misslyckades med att spara medlem(mar): %{errors}."
-  notice_no_issue_selected: "Inget Ã¤rende Ã¤r markerat! Var vÃ¤nlig, markera de Ã¤renden du vill Ã¤ndra."
-  notice_account_pending: "Ditt konto skapades och avvaktar nu administratÃ¶rens godkÃ¤nnande."
-  notice_default_data_loaded: Standardkonfiguration inlÃ¤st.
-  notice_unable_delete_version: Denna version var inte mÃ¶jlig att ta bort.
-  notice_unable_delete_time_entry: Tidloggning kunde inte tas bort.
-  notice_issue_done_ratios_updated: "% klart uppdaterade."
-  notice_gantt_chart_truncated: "Schemat fÃ¶rminskades eftersom det Ã¶verskrider det maximala antalet aktiviteter som fÃ¥r visas (%{max})"
-  notice_issue_successful_create: Ã„rende %{id} skapades.
-  
-  error_can_t_load_default_data: "Standardkonfiguration gick inte att lÃ¤sa in: %{value}"
-  error_scm_not_found: "InlÃ¤gg och/eller revision finns inte i detta versionsarkiv."
-  error_scm_command_failed: "Ett fel intrÃ¤ffade vid fÃ¶rsÃ¶k att nÃ¥ versionsarkivet: %{value}"
-  error_scm_annotate: "InlÃ¤gget existerar inte eller kan inte kommenteras."
-  error_issue_not_found_in_project: 'Ã„rendet hittades inte eller sÃ¥ tillhÃ¶r det inte detta projekt'
-  error_no_tracker_in_project: 'Ingen Ã¤rendetyp Ã¤r associerad med projektet. VÃ¤nligen kontrollera projektinstÃ¤llningarna.'
-  error_no_default_issue_status: 'Ingen status Ã¤r definierad som standard fÃ¶r nya Ã¤renden. VÃ¤nligen kontrollera din konfiguration (GÃ¥ till "Administration -> Ã„rendestatus").'
-  error_can_not_delete_custom_field: Kan inte ta bort anvÃ¤ndardefinerat fÃ¤lt
-  error_can_not_delete_tracker: "Det finns Ã¤renden av denna typ och den Ã¤r dÃ¤rfÃ¶r inte mÃ¶jlig att ta bort."
-  error_can_not_remove_role: "Denna roll anvÃ¤nds och den Ã¤r dÃ¤rfÃ¶r inte mÃ¶jlig att ta bort."
-  error_can_not_reopen_issue_on_closed_version: 'Ett Ã¤rende tilldelat en stÃ¤ngd version kan inte Ã¶ppnas pÃ¥ nytt'
-  error_can_not_archive_project: Detta projekt kan inte arkiveras
-  error_issue_done_ratios_not_updated: "% klart inte uppdaterade."
-  error_workflow_copy_source: 'VÃ¤nligen vÃ¤lj kÃ¤llans Ã¤rendetyp eller roll'
-  error_workflow_copy_target: 'VÃ¤nligen vÃ¤lj Ã¤rendetyp(er) och roll(er) fÃ¶r mÃ¥l'
-  error_unable_delete_issue_status: 'Ã„rendestatus kunde inte tas bort'
-  error_unable_to_connect: "Kan inte ansluta (%{value})"
-  
-  warning_attachments_not_saved: "%{count} fil(er) kunde inte sparas."
-  
-  mail_subject_lost_password: "Ditt %{value} lÃ¶senord"
-  mail_body_lost_password: 'FÃ¶r att Ã¤ndra ditt lÃ¶senord, klicka pÃ¥ fÃ¶ljande lÃ¤nk:'
-  mail_subject_register: "Din %{value} kontoaktivering"
-  mail_body_register: 'FÃ¶r att aktivera ditt konto, klicka pÃ¥ fÃ¶ljande lÃ¤nk:'
-  mail_body_account_information_external: "Du kan anvÃ¤nda ditt %{value}-konto fÃ¶r att logga in."
-  mail_body_account_information: Din kontoinformation
-  mail_subject_account_activation_request: "%{value} begÃ¤ran om kontoaktivering"
-  mail_body_account_activation_request: "En ny anvÃ¤ndare (%{value}) har registrerat sig och avvaktar ditt godkÃ¤nnande:"
-  mail_subject_reminder: "%{count} Ã¤rende(n) har deadline under de kommande %{days} dagarna"
-  mail_body_reminder: "%{count} Ã¤rende(n) som Ã¤r tilldelat dig har deadline under de %{days} dagarna:"
-  mail_subject_wiki_content_added: "'%{id}' wikisida has lagts till"
-  mail_body_wiki_content_added: "The '%{id}' wikisida has lagts till av %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' wikisida har uppdaterats"
-  mail_body_wiki_content_updated: "The '%{id}' wikisida har uppdaterats av %{author}."
-  
-  gui_validation_error: 1 fel
-  gui_validation_error_plural: "%{count} fel"
-  
-  field_name: Namn
-  field_description: Beskrivning
-  field_summary: Sammanfattning
-  field_is_required: Obligatorisk
-  field_firstname: FÃ¶rnamn
-  field_lastname: Efternamn
-  field_mail: Mail
-  field_filename: Fil
-  field_filesize: Storlek
-  field_downloads: Nerladdningar
-  field_author: FÃ¶rfattare
-  field_created_on: Skapad
-  field_updated_on: Uppdaterad
-  field_field_format: Format
-  field_is_for_all: FÃ¶r alla projekt
-  field_possible_values: MÃ¶jliga vÃ¤rden
-  field_regexp: ReguljÃ¤rt uttryck
-  field_min_length: MinimilÃ¤ngd
-  field_max_length: MaxlÃ¤ngd
-  field_value: VÃ¤rde
-  field_category: Kategori
-  field_title: Titel
-  field_project: Projekt
-  field_issue: Ã„rende
-  field_status: Status
-  field_notes: Anteckningar
-  field_is_closed: Ã„rendet Ã¤r stÃ¤ngt
-  field_is_default: StandardvÃ¤rde
-  field_tracker: Ã„rendetyp
-  field_subject: Ã„mne
-  field_due_date: Deadline
-  field_assigned_to: Tilldelad till
-  field_priority: Prioritet
-  field_fixed_version: VersionsmÃ¥l
-  field_user: AnvÃ¤ndare
-  field_principal: Principal
-  field_role: Roll
-  field_homepage: Hemsida
-  field_is_public: Publik
-  field_parent: Underprojekt till
-  field_is_in_roadmap: Visa Ã¤renden i roadmap
-  field_login: AnvÃ¤ndarnamn
-  field_mail_notification: Mailnotifieringar
-  field_admin: AdministratÃ¶r
-  field_last_login_on: Senaste inloggning
-  field_language: SprÃ¥k
-  field_effective_date: Datum
-  field_password: LÃ¶senord
-  field_new_password: Nytt lÃ¶senord
-  field_password_confirmation: BekrÃ¤fta lÃ¶senord
-  field_version: Version
-  field_type: Typ
-  field_host: VÃ¤rddator
-  field_port: Port
-  field_account: Konto
-  field_base_dn: Bas-DN
-  field_attr_login: Inloggningsattribut
-  field_attr_firstname: FÃ¶rnamnsattribut
-  field_attr_lastname: Efternamnsattribut
-  field_attr_mail: Mailattribut
-  field_onthefly: Skapa anvÃ¤ndare on-the-fly
-  field_start_date: Startdatum
-  field_done_ratio: "% Klart"
-  field_auth_source: AutentiseringslÃ¤ge
-  field_hide_mail: DÃ¶lj min mailadress
-  field_comments: Kommentar
-  field_url: URL
-  field_start_page: Startsida
-  field_subproject: Underprojekt
-  field_hours: Timmar
-  field_activity: Aktivitet
-  field_spent_on: Datum
-  field_identifier: Identifierare
-  field_is_filter: AnvÃ¤nd som filter
-  field_issue_to: Relaterade Ã¤renden
-  field_delay: FÃ¶rdrÃ¶jning
-  field_assignable: Ã„renden kan tilldelas denna roll
-  field_redirect_existing_links: Omdirigera existerande lÃ¤nkar
-  field_estimated_hours: Estimerad tid
-  field_column_names: Kolumner
-  field_time_entries: Spenderad tid
-  field_time_zone: Tidszon
-  field_searchable: SÃ¶kbar
-  field_default_value: StandardvÃ¤rde
-  field_comments_sorting: Visa kommentarer
-  field_parent_title: FÃ¶rÃ¤ldersida
-  field_editable: Redigerbar
-  field_watcher: Bevakare  
-  field_identity_url: OpenID URL
-  field_content: InnehÃ¥ll
-  field_group_by: Gruppera resultat efter
-  field_sharing: Delning
-  field_parent_issue: FÃ¶rÃ¤lderaktivitet
-  field_member_of_group: "Tilldelad anvÃ¤ndares grupp"
-  field_assigned_to_role: "Tilldelad anvÃ¤ndares roll"
-  field_text: TextfÃ¤lt
-  field_visible: Synlig
-  field_warn_on_leaving_unsaved: Varna om jag lÃ¤mnar en sida med osparad text
-  field_issues_visibility: Ã„rendesynlighet
-  field_is_private: Privat
-  field_commit_logs_encoding: TeckenuppsÃ¤ttning fÃ¶r commit-meddelanden
-  field_scm_path_encoding: SÃ¶kvÃ¤gskodning
-  field_path_to_repository: SÃ¶kvÃ¤g till versionsarkiv
-  field_root_directory: Rotmapp
-  field_cvsroot: CVSROOT
-  field_cvs_module: Modul
-  
-  setting_app_title: Applikationsrubrik
-  setting_app_subtitle: Applikationsunderrubrik
-  setting_welcome_text: VÃ¤lkomsttext
-  setting_default_language: StandardsprÃ¥k
-  setting_login_required: KrÃ¤ver inloggning
-  setting_self_registration: SjÃ¤lvregistrering
-  setting_attachment_max_size: Maxstorlek pÃ¥ bilaga
-  setting_issues_export_limit: ExportgrÃ¤ns fÃ¶r Ã¤renden
-  setting_mail_from: AvsÃ¤ndaradress
-  setting_bcc_recipients: Hemlig kopia (bcc) till mottagare
-  setting_plain_text_mail: Oformaterad text i mail (ingen HTML)
-  setting_host_name: VÃ¤rddatornamn
-  setting_text_formatting: Textformatering
-  setting_wiki_compression: Komprimering av wikihistorik
-  setting_feeds_limit: InnehÃ¥llsgrÃ¤ns fÃ¶r Feed
-  setting_default_projects_public: Nya projekt Ã¤r publika
-  setting_autofetch_changesets: Automatisk hÃ¤mtning av commits
-  setting_sys_api_enabled: Aktivera WS fÃ¶r versionsarkivhantering
-  setting_commit_ref_keywords: Referens-nyckelord
-  setting_commit_fix_keywords: Fix-nyckelord
-  setting_autologin: Automatisk inloggning
-  setting_date_format: Datumformat
-  setting_time_format: Tidsformat
-  setting_cross_project_issue_relations: TillÃ¥t Ã¤renderelationer mellan projekt
-  setting_issue_list_default_columns: Standardkolumner i Ã¤rendelistan
-  setting_emails_header: Mail-header
-  setting_emails_footer: Signatur
-  setting_protocol: Protokoll
-  setting_per_page_options: Alternativ, objekt per sida
-  setting_user_format: Visningsformat fÃ¶r anvÃ¤ndare
-  setting_activity_days_default: Dagar som visas pÃ¥ projektaktivitet
-  setting_display_subprojects_issues: Visa Ã¤renden frÃ¥n underprojekt i huvudprojekt
-  setting_enabled_scm: Aktivera SCM
-  setting_mail_handler_body_delimiters: "Trunkera mail efter en av fÃ¶ljande rader"
-  setting_mail_handler_api_enabled: Aktivera WS fÃ¶r inkommande mail
-  setting_mail_handler_api_key: API-nyckel
-  setting_sequential_project_identifiers: Generera projektidentifierare sekventiellt
-  setting_gravatar_enabled: AnvÃ¤nd Gravatar-avatarer
-  setting_gravatar_default: FÃ¶rvald Gravatar-bild
-  setting_diff_max_lines_displayed: Maximalt antal synliga rader i diff
-  setting_file_max_size_displayed: Maxstorlek pÃ¥ textfiler som visas inline
-  setting_repository_log_display_limit: Maximalt antal revisioner i filloggen
-  setting_openid: TillÃ¥t inloggning och registrering med OpenID
-  setting_password_min_length: Minsta tillÃ¥tna lÃ¶senordslÃ¤ngd
-  setting_new_project_user_role_id: Tilldelad roll fÃ¶r en icke-administratÃ¶r som skapar ett projekt
-  setting_default_projects_modules: Aktiverade moduler fÃ¶r nya projekt
-  setting_issue_done_ratio: BerÃ¤kna % klart med
-  setting_issue_done_ratio_issue_field: AnvÃ¤nd Ã¤rendefÃ¤ltet
-  setting_issue_done_ratio_issue_status: AnvÃ¤nd Ã¤rendestatus
-  setting_start_of_week: FÃ¶rsta dagen i veckan
-  setting_rest_api_enabled: Aktivera REST webbtjÃ¤nst
-  setting_cache_formatted_text: Cacha formaterad text
-  setting_default_notification_option: Standard notifieringsalternativ
-  setting_commit_logtime_enabled: Aktivera tidloggning
-  setting_commit_logtime_activity_id: Aktivitet fÃ¶r loggad tid
-  setting_gantt_items_limit: Maximalt antal aktiviteter som visas i gantt-schemat
-  setting_issue_group_assignment: TillÃ¥t att Ã¤renden tilldelas till grupper
-  
-  permission_add_project: Skapa projekt
-  permission_add_subprojects: Skapa underprojekt
-  permission_edit_project: Ã„ndra projekt
-  permission_select_project_modules: VÃ¤lja projektmoduler
-  permission_manage_members: Hantera medlemmar
-  permission_manage_project_activities: Hantera projektaktiviteter
-  permission_manage_versions: Hantera versioner
-  permission_manage_categories: Hantera Ã¤rendekategorier
-  permission_add_issues: LÃ¤gga till Ã¤renden
-  permission_edit_issues: Ã„ndra Ã¤renden
-  permission_view_issues: Visa Ã¤renden
-  permission_manage_issue_relations: Hantera Ã¤renderelationer
-  permission_set_issues_private: SÃ¤tta Ã¤renden publika eller privata
-  permission_set_own_issues_private: SÃ¤tta egna Ã¤renden publika eller privata
-  permission_add_issue_notes: LÃ¤gga till Ã¤rendenotering
-  permission_edit_issue_notes: Ã„ndra Ã¤rendenoteringar
-  permission_edit_own_issue_notes: Ã„ndra egna Ã¤rendenoteringar
-  permission_move_issues: Flytta Ã¤renden
-  permission_delete_issues: Ta bort Ã¤renden
-  permission_manage_public_queries: Hantera publika frÃ¥gor
-  permission_save_queries: Spara frÃ¥gor
-  permission_view_gantt: Visa Gantt-schema
-  permission_view_calendar: Visa kalender
-  permission_view_issue_watchers: Visa bevakarlista
-  permission_add_issue_watchers: LÃ¤gga till bevakare
-  permission_delete_issue_watchers: Ta bort bevakare
-  permission_log_time: Logga spenderad tid
-  permission_view_time_entries: Visa spenderad tid
-  permission_edit_time_entries: Ã„ndra tidloggningar
-  permission_edit_own_time_entries: Ã„ndra egna tidloggningar
-  permission_manage_news: Hantera nyheter
-  permission_comment_news: Kommentera nyheter
-  permission_manage_documents: Hantera dokument
-  permission_view_documents: Visa dokument
-  permission_manage_files: Hantera filer
-  permission_view_files: Visa filer
-  permission_manage_wiki: Hantera wiki
-  permission_rename_wiki_pages: Byta namn pÃ¥ wikisidor
-  permission_delete_wiki_pages: Ta bort wikisidor
-  permission_view_wiki_pages: Visa wiki
-  permission_view_wiki_edits: Visa wikihistorik
-  permission_edit_wiki_pages: Ã„ndra wikisidor
-  permission_delete_wiki_pages_attachments: Ta bort bilagor
-  permission_protect_wiki_pages: Skydda wikisidor
-  permission_manage_repository: Hantera versionsarkiv
-  permission_browse_repository: BlÃ¤ddra i versionsarkiv
-  permission_view_changesets: Visa changesets
-  permission_commit_access: Commit-Ã¥tkomst
-  permission_manage_boards: Hantera forum
-  permission_view_messages: Visa meddelanden
-  permission_add_messages: LÃ¤gg till meddelanden
-  permission_edit_messages: Ã„ndra meddelanden
-  permission_edit_own_messages: Ã„ndra egna meddelanden
-  permission_delete_messages: Ta bort meddelanden
-  permission_delete_own_messages: Ta bort egna meddelanden
-  permission_export_wiki_pages: Exportera wikisidor
-  permission_manage_subtasks: Hantera underaktiviteter
-  
-  project_module_issue_tracking: Ã„rendeuppfÃ¶ljning
-  project_module_time_tracking: TidsuppfÃ¶ljning
-  project_module_news: Nyheter
-  project_module_documents: Dokument
-  project_module_files: Filer
-  project_module_wiki: Wiki
-  project_module_repository: Versionsarkiv
-  project_module_boards: Forum
-  project_module_calendar: Kalender
-  project_module_gantt: Gantt
-  
-  label_user: AnvÃ¤ndare
-  label_user_plural: AnvÃ¤ndare
-  label_user_new: Ny anvÃ¤ndare
-  label_user_anonymous: Anonym
-  label_project: Projekt
-  label_project_new: Nytt projekt
-  label_project_plural: Projekt
-  label_x_projects:
-    zero:  inga projekt
-    one:   1 projekt
-    other: "%{count} projekt"
-  label_project_all: Alla projekt
-  label_project_latest: Senaste projekt
-  label_issue: Ã„rende
-  label_issue_new: Nytt Ã¤rende
-  label_issue_plural: Ã„renden
-  label_issue_view_all: Visa alla Ã¤renden
-  label_issues_by: "Ã„renden %{value}"
-  label_issue_added: Ã„rende tillagt
-  label_issue_updated: Ã„rende uppdaterat
-  label_issue_note_added: Anteckning tillagd
-  label_issue_status_updated: Status uppdaterad
-  label_issue_priority_updated: Prioritet uppdaterad
-  label_document: Dokument
-  label_document_new: Nytt dokument
-  label_document_plural: Dokument
-  label_document_added: Dokument tillagt
-  label_role: Roll
-  label_role_plural: Roller
-  label_role_new: Ny roll
-  label_role_and_permissions: Roller och behÃ¶righeter
-  label_role_anonymous: Anonym
-  label_role_non_member: Icke-medlem
-  label_member: Medlem
-  label_member_new: Ny medlem
-  label_member_plural: Medlemmar
-  label_tracker: Ã„rendetyp
-  label_tracker_plural: Ã„rendetyper
-  label_tracker_new: Ny Ã¤rendetyp
-  label_workflow: ArbetsflÃ¶de
-  label_issue_status: Ã„rendestatus
-  label_issue_status_plural: Ã„rendestatus
-  label_issue_status_new: Ny status
-  label_issue_category: Ã„rendekategori
-  label_issue_category_plural: Ã„rendekategorier
-  label_issue_category_new: Ny kategori
-  label_custom_field: AnvÃ¤ndardefinerat fÃ¤lt
-  label_custom_field_plural: AnvÃ¤ndardefinerade fÃ¤lt
-  label_custom_field_new: Nytt anvÃ¤ndardefinerat fÃ¤lt
-  label_enumerations: UpprÃ¤kningar
-  label_enumeration_new: Nytt vÃ¤rde
-  label_information: Information
-  label_information_plural: Information
-  label_please_login: Var god logga in
-  label_register: Registrera
-  label_login_with_open_id_option: eller logga in med OpenID
-  label_password_lost: GlÃ¶mt lÃ¶senord
-  label_home: Hem
-  label_my_page: Min sida
-  label_my_account: Mitt konto
-  label_my_projects: Mina projekt
-  label_my_page_block: '"Min sida"-block'
-  label_administration: Administration
-  label_login: Logga in
-  label_logout: Logga ut
-  label_help: HjÃ¤lp
-  label_reported_issues: Rapporterade Ã¤renden
-  label_assigned_to_me_issues: Ã„renden tilldelade till mig
-  label_last_login: Senaste inloggning
-  label_registered_on: Registrerad
-  label_activity: Aktivitet
-  label_overall_activity: All aktivitet
-  label_user_activity: "Aktiviteter fÃ¶r %{value}"
-  label_new: Ny
-  label_logged_as: Inloggad som
-  label_environment: MiljÃ¶
-  label_authentication: Autentisering
-  label_auth_source: AutentiseringslÃ¤ge
-  label_auth_source_new: Nytt autentiseringslÃ¤ge
-  label_auth_source_plural: AutentiseringslÃ¤gen
-  label_subproject_plural: Underprojekt
-  label_subproject_new: Nytt underprojekt
-  label_and_its_subprojects: "%{value} och dess underprojekt"
-  label_min_max_length: Min./Max.-lÃ¤ngd
-  label_list: Lista
-  label_date: Datum
-  label_integer: Heltal
-  label_float: Flyttal
-  label_boolean: Boolean
-  label_string: Text
-  label_text: LÃ¥ng text
-  label_attribute: Attribut
-  label_attribute_plural: Attribut
-  label_download: "%{count} Nerladdning"
-  label_download_plural: "%{count} Nerladdningar"
-  label_no_data: Ingen data att visa
-  label_change_status: Ã„ndra status
-  label_history: Historia
-  label_attachment: Fil
-  label_attachment_new: Ny fil
-  label_attachment_delete: Ta bort fil
-  label_attachment_plural: Filer
-  label_file_added: Fil tillagd
-  label_report: Rapport
-  label_report_plural: Rapporter
-  label_news: Nyhet
-  label_news_new: LÃ¤gg till nyhet
-  label_news_plural: Nyheter
-  label_news_latest: Senaste nyheterna
-  label_news_view_all: Visa alla nyheter
-  label_news_added: Nyhet tillagd
-  label_news_comment_added: Kommentar tillagd till en nyhet
-  label_settings: InstÃ¤llningar
-  label_overview: Ã–versikt
-  label_version: Version
-  label_version_new: Ny version
-  label_version_plural: Versioner
-  label_close_versions: StÃ¤ng klara versioner
-  label_confirmation: BekrÃ¤ftelse
-  label_export_to: 'Finns Ã¤ven som:'
-  label_read: LÃ¤s...
-  label_public_projects: Publika projekt
-  label_open_issues: Ã¶ppen
-  label_open_issues_plural: Ã¶ppna
-  label_closed_issues: stÃ¤ngd
-  label_closed_issues_plural: stÃ¤ngda
-  label_x_open_issues_abbr_on_total:
-    zero:  0 Ã¶ppna av %{total}
-    one:   1 Ã¶ppen av %{total}
-    other: "%{count} Ã¶ppna av %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 Ã¶ppna
-    one:   1 Ã¶ppen
-    other: "%{count} Ã¶ppna"
-  label_x_closed_issues_abbr:
-    zero:  0 stÃ¤ngda
-    one:   1 stÃ¤ngd
-    other: "%{count} stÃ¤ngda"
-  label_total: Total
-  label_permissions: BehÃ¶righeter
-  label_current_status: Nuvarande status
-  label_new_statuses_allowed: Nya tillÃ¥tna statusvÃ¤rden
-  label_all: alla
-  label_none: ingen
-  label_nobody: ingen
-  label_next: NÃ¤sta
-  label_previous: FÃ¶regÃ¥ende
-  label_used_by: AnvÃ¤nd av
-  label_details: Detaljer
-  label_add_note: LÃ¤gg till anteckning
-  label_per_page: Per sida
-  label_calendar: Kalender
-  label_months_from: mÃ¥nader frÃ¥n
-  label_gantt: Gantt
-  label_internal: Intern
-  label_last_changes: "senaste %{count} Ã¤ndringar"
-  label_change_view_all: Visa alla Ã¤ndringar
-  label_personalize_page: Anpassa denna sida
-  label_comment: Kommentar
-  label_comment_plural: Kommentarer
-  label_x_comments:
-    zero: inga kommentarer
-    one: 1 kommentar
-    other: "%{count} kommentarer"
-  label_comment_add: LÃ¤gg till kommentar
-  label_comment_added: Kommentar tillagd
-  label_comment_delete: Ta bort kommentar
-  label_query: AnvÃ¤ndardefinerad frÃ¥ga
-  label_query_plural: AnvÃ¤ndardefinerade frÃ¥gor
-  label_query_new: Ny frÃ¥ga
-  label_my_queries: Mina egna frÃ¥gor
-  label_filter_add: LÃ¤gg till filter
-  label_filter_plural: Filter
-  label_equals: Ã¤r
-  label_not_equals: Ã¤r inte
-  label_in_less_than: om mindre Ã¤n
-  label_in_more_than: om mer Ã¤n
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_between: mellan
-  label_in: om
-  label_today: idag
-  label_all_time: nÃ¤rsom
-  label_yesterday: igÃ¥r
-  label_this_week: denna vecka
-  label_last_week: senaste veckan
-  label_last_n_days: "senaste %{count} dagarna"
-  label_this_month: denna mÃ¥nad
-  label_last_month: senaste mÃ¥naden
-  label_this_year: detta Ã¥ret
-  label_date_range: Datumintervall
-  label_less_than_ago: mindre Ã¤n dagar sedan
-  label_more_than_ago: mer Ã¤n dagar sedan
-  label_ago: dagar sedan
-  label_contains: innehÃ¥ller
-  label_not_contains: innehÃ¥ller inte
-  label_day_plural: dagar
-  label_repository: Versionsarkiv
-  label_repository_plural: Versionsarkiv
-  label_browse: BlÃ¤ddra
-  label_modification: "%{count} Ã¤ndring"
-  label_modification_plural: "%{count} Ã¤ndringar"
-  label_branch: Branch
-  label_tag: Tag
-  label_revision: Revision
-  label_revision_plural: Revisioner
-  label_revision_id: "Revision %{value}"
-  label_associated_revisions: Associerade revisioner
-  label_added: tillagd
-  label_modified: modifierad
-  label_copied: kopierad
-  label_renamed: omdÃ¶pt
-  label_deleted: borttagen
-  label_latest_revision: Senaste revisionen
-  label_latest_revision_plural: Senaste revisionerna
-  label_view_revisions: Visa revisioner
-  label_view_all_revisions: Visa alla revisioner
-  label_max_size: Maxstorlek
-  label_sort_highest: Flytta till toppen
-  label_sort_higher: Flytta upp
-  label_sort_lower: Flytta ner
-  label_sort_lowest: Flytta till botten
-  label_roadmap: Roadmap
-  label_roadmap_due_in: "FÃ¤rdig om %{value}"
-  label_roadmap_overdue: "%{value} sen"
-  label_roadmap_no_issues: Inga Ã¤renden fÃ¶r denna version
-  label_search: SÃ¶k
-  label_result_plural: Resultat
-  label_all_words: Alla ord
-  label_wiki: Wiki
-  label_wiki_edit: WikiÃ¤ndring
-  label_wiki_edit_plural: WikiÃ¤ndringar
-  label_wiki_page: Wikisida
-  label_wiki_page_plural: Wikisidor
-  label_index_by_title: InnehÃ¥ll efter titel
-  label_index_by_date: InnehÃ¥ll efter datum
-  label_current_version: Nuvarande version
-  label_preview: FÃ¶rhandsgranska
-  label_feed_plural: Feeds
-  label_changes_details: Detaljer om alla Ã¤ndringar
-  label_issue_tracking: Ã„rendeuppfÃ¶ljning
-  label_spent_time: Spenderad tid
-  label_overall_spent_time: Total tid spenderad
-  label_f_hour: "%{value} timme"
-  label_f_hour_plural: "%{value} timmar"
-  label_time_tracking: TidsuppfÃ¶ljning
-  label_change_plural: Ã„ndringar
-  label_statistics: Statistik
-  label_commits_per_month: Commits per mÃ¥nad
-  label_commits_per_author: Commits per fÃ¶rfattare
-  label_view_diff: Visa skillnader
-  label_diff_inline: i texten
-  label_diff_side_by_side: sida vid sida
-  label_options: InstÃ¤llningar
-  label_copy_workflow_from: Kopiera arbetsflÃ¶de frÃ¥n
-  label_permissions_report: BehÃ¶righetsrapport
-  label_watched_issues: Bevakade Ã¤renden
-  label_related_issues: Relaterade Ã¤renden
-  label_applied_status: Tilldelad status
-  label_loading: Laddar...
-  label_relation_new: Ny relation
-  label_relation_delete: Ta bort relation
-  label_relates_to: relaterar till
-  label_duplicates: kopierar
-  label_duplicated_by: kopierad av
-  label_blocks: blockerar
-  label_blocked_by: blockerad av
-  label_precedes: kommer fÃ¶re
-  label_follows: fÃ¶ljer
-  label_end_to_start: slut till start
-  label_end_to_end: slut till slut
-  label_start_to_start: start till start
-  label_start_to_end: start till slut
-  label_stay_logged_in: FÃ¶rbli inloggad
-  label_disabled: inaktiverad
-  label_show_completed_versions: Visa fÃ¤rdiga versioner
-  label_me: mig
-  label_board: Forum
-  label_board_new: Nytt forum
-  label_board_plural: Forum
-  label_board_locked: LÃ¥st
-  label_board_sticky: Sticky
-  label_topic_plural: Ã„mnen
-  label_message_plural: Meddelanden
-  label_message_last: Senaste meddelande
-  label_message_new: Nytt meddelande
-  label_message_posted: Meddelande tillagt
-  label_reply_plural: Svar
-  label_send_information: Skicka kontoinformation till anvÃ¤ndaren
-  label_year: Ã…r
-  label_month: MÃ¥nad
-  label_week: Vecka
-  label_date_from: FrÃ¥n
-  label_date_to: Till
-  label_language_based: SprÃ¥kbaserad
-  label_sort_by: "Sortera pÃ¥ %{value}"
-  label_send_test_email: Skicka testmail
-  label_feeds_access_key: RSS-nyckel
-  label_missing_feeds_access_key: Saknar en RSS-nyckel
-  label_feeds_access_key_created_on: "RSS-nyckel skapad fÃ¶r %{value} sedan"
-  label_module_plural: Moduler
-  label_added_time_by: "Tillagd av %{author} fÃ¶r %{age} sedan"
-  label_updated_time_by: "Uppdaterad av %{author} fÃ¶r %{age} sedan"
-  label_updated_time: "Uppdaterad fÃ¶r %{value} sedan"
-  label_jump_to_a_project: GÃ¥ till projekt...
-  label_file_plural: Filer
-  label_changeset_plural: Changesets
-  label_default_columns: Standardkolumner
-  label_no_change_option: (Ingen Ã¤ndring)
-  label_bulk_edit_selected_issues: Gemensam Ã¤ndring av markerade Ã¤renden
-  label_bulk_edit_selected_time_entries: Gruppredigera valda tidloggningar
-  label_theme: Tema
-  label_default: Standard
-  label_search_titles_only: SÃ¶k endast i titlar
-  label_user_mail_option_all: "FÃ¶r alla hÃ¤ndelser i mina projekt"
-  label_user_mail_option_selected: "FÃ¶r alla hÃ¤ndelser i markerade projekt..."
-  label_user_mail_option_none: "Inga hÃ¤ndelser"
-  label_user_mail_option_only_my_events: "Endast fÃ¶r saker jag bevakar eller Ã¤r inblandad i"
-  label_user_mail_option_only_assigned: "Endast fÃ¶r saker jag Ã¤r tilldelad"
-  label_user_mail_option_only_owner: "Endast fÃ¶r saker jag Ã¤ger"
-  label_user_mail_no_self_notified: "Jag vill inte bli underrÃ¤ttad om Ã¤ndringar som jag har gjort"
-  label_registration_activation_by_email: kontoaktivering med mail
-  label_registration_manual_activation: manuell kontoaktivering
-  label_registration_automatic_activation: automatisk kontoaktivering
-  label_display_per_page: "Per sida: %{value}"
-  label_age: Ã…lder
-  label_change_properties: Ã„ndra instÃ¤llningar
-  label_general: AllmÃ¤nt
-  label_more: Mer
-  label_scm: SCM
-  label_plugins: TillÃ¤gg
-  label_ldap_authentication: LDAP-autentisering
-  label_downloads_abbr: Nerl.
-  label_optional_description: Valfri beskrivning
-  label_add_another_file: LÃ¤gg till ytterligare en fil
-  label_preferences: AnvÃ¤ndarinstÃ¤llningar
-  label_chronological_order: I kronologisk ordning
-  label_reverse_chronological_order: I omvÃ¤nd kronologisk ordning
-  label_planning: Planering
-  label_incoming_emails: Inkommande mail
-  label_generate_key: Generera en nyckel
-  label_issue_watchers: Bevakare
-  label_example: Exempel
-  label_display: Visa
-  label_sort: Sortera
-  label_descending: Fallande
-  label_ascending: Stigande
-  label_date_from_to: FrÃ¥n %{start} till %{end}
-  label_wiki_content_added: Wikisida tillagd
-  label_wiki_content_updated: Wikisida uppdaterad
-  label_group: Grupp
-  label_group_plural: Grupper
-  label_group_new: Ny grupp
-  label_time_entry_plural: Spenderad tid
-  label_version_sharing_none: Inte delad
-  label_version_sharing_descendants: Med underprojekt
-  label_version_sharing_hierarchy: Med projekthierarki
-  label_version_sharing_tree: Med projekttrÃ¤d
-  label_version_sharing_system: Med alla projekt
-  label_update_issue_done_ratios: Uppdatera % klart
-  label_copy_source: KÃ¤lla
-  label_copy_target: MÃ¥l
-  label_copy_same_as_target: Samma som mÃ¥l
-  label_display_used_statuses_only: Visa endast status som anvÃ¤nds av denna Ã¤rendetyp
-  label_api_access_key: API-nyckel
-  label_missing_api_access_key: Saknar en API-nyckel
-  label_api_access_key_created_on: "API-nyckel skapad fÃ¶r %{value} sedan"
-  label_profile: Profil
-  label_subtask_plural: Underaktiviteter
-  label_project_copy_notifications: Skicka mailnotifieringar nÃ¤r projektet kopieras
-  label_principal_search: "SÃ¶k efter anvÃ¤ndare eller grupp:"
-  label_user_search: "SÃ¶k efter anvÃ¤ndare:"
-  label_additional_workflow_transitions_for_author: Ytterligare Ã¶vergÃ¥ngar tillÃ¥tna nÃ¤r anvÃ¤ndaren Ã¤r den som skapat Ã¤rendet
-  label_additional_workflow_transitions_for_assignee: Ytterligare Ã¶vergÃ¥ngar tillÃ¥tna nÃ¤r anvÃ¤ndaren Ã¤r den som tilldelats Ã¤rendet
-  label_issues_visibility_all: Alla Ã¤renden
-  label_issues_visibility_public: Alla icke-privata Ã¤renden
-  label_issues_visibility_own: Ã„renden skapade av eller tilldelade till anvÃ¤ndaren
-  label_git_report_last_commit: Rapportera senaste commit av filer och mappar
-  
-  button_login: Logga in
-  button_submit: Skicka
-  button_save: Spara
-  button_check_all: Markera alla
-  button_uncheck_all: Avmarkera alla
-  button_collapse_all: Kollapsa alla
-  button_expand_all: Expandera alla
-  button_delete: Ta bort
-  button_create: Skapa
-  button_create_and_continue: Skapa och fortsÃ¤tt
-  button_test: Testa
-  button_edit: Ã„ndra
-  button_edit_associated_wikipage: "Ã„ndra associerad Wikisida: %{page_title}"
-  button_add: LÃ¤gg till
-  button_change: Ã„ndra
-  button_apply: VerkstÃ¤ll
-  button_clear: Ã…terstÃ¤ll
-  button_lock: LÃ¥s
-  button_unlock: LÃ¥s upp
-  button_download: Ladda ner
-  button_list: Lista
-  button_view: Visa
-  button_move: Flytta
-  button_move_and_follow: Flytta och fÃ¶lj efter
-  button_back: Tillbaka
-  button_cancel: Avbryt
-  button_activate: Aktivera
-  button_sort: Sortera
-  button_log_time: Logga tid
-  button_rollback: Ã…terstÃ¤ll till denna version
-  button_watch: Bevaka
-  button_unwatch: Stoppa bevakning
-  button_reply: Svara
-  button_archive: Arkivera
-  button_unarchive: Ta bort frÃ¥n arkiv
-  button_reset: Ã…terstÃ¤ll
-  button_rename: Byt namn
-  button_change_password: Ã„ndra lÃ¶senord
-  button_copy: Kopiera
-  button_copy_and_follow: Kopiera och fÃ¶lj efter
-  button_annotate: Kommentera
-  button_update: Uppdatera
-  button_configure: Konfigurera
-  button_quote: Citera
-  button_duplicate: Duplicera
-  button_show: Visa
-  
-  status_active: aktiv
-  status_registered: registrerad
-  status_locked: lÃ¥st
-  
-  version_status_open: Ã¶ppen
-  version_status_locked: lÃ¥st
-  version_status_closed: stÃ¤ngd
-  
-  field_active: Aktiv
-  
-  text_select_mail_notifications: VÃ¤lj fÃ¶r vilka hÃ¤ndelser mail ska skickas.
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 betyder ingen grÃ¤ns
-  text_project_destroy_confirmation: Ã„r du sÃ¤ker pÃ¥ att du vill ta bort detta projekt och all relaterad data?
-  text_subprojects_destroy_warning: "Alla underprojekt: %{value} kommer ocksÃ¥ tas bort."
-  text_workflow_edit: VÃ¤lj en roll och en Ã¤rendetyp fÃ¶r att Ã¤ndra arbetsflÃ¶de
-  text_are_you_sure: Ã„r du sÃ¤ker ?
-  text_are_you_sure_with_children: Ta bort Ã¤rende och alla underÃ¤renden?
-  text_journal_changed: "%{label} Ã¤ndrad frÃ¥n %{old} till %{new}"
-  text_journal_changed_no_detail: "%{label} uppdaterad"
-  text_journal_set_to: "%{label} satt till %{value}"
-  text_journal_deleted: "%{label} borttagen (%{old})"
-  text_journal_added: "%{label} %{value} tillagd"
-  text_tip_issue_begin_day: Ã¤rende som bÃ¶rjar denna dag
-  text_tip_issue_end_day: Ã¤rende som slutar denna dag
-  text_tip_issue_begin_end_day: Ã¤rende som bÃ¶rjar och slutar denna dag
-  text_project_identifier_info: 'SmÃ¥ bokstÃ¤ver (a-z), siffror och streck tillÃ¥tna.<br />NÃ¤r den Ã¤r sparad kan identifieraren inte Ã¤ndras.'
-  text_caracters_maximum: "max %{count} tecken."
-  text_caracters_minimum: "MÃ¥ste vara minst %{count} tecken lÃ¥ng."
-  text_length_between: "LÃ¤ngd mellan %{min} och %{max} tecken."
-  text_tracker_no_workflow: Inget arbetsflÃ¶de definerat fÃ¶r denna Ã¤rendetyp
-  text_unallowed_characters: OtillÃ¥tna tecken
-  text_comma_separated: Flera vÃ¤rden tillÃ¥tna (kommaseparerade).
-  text_line_separated: Flera vÃ¤rden tillÃ¥tna (ett vÃ¤rde per rad).
-  text_issues_ref_in_commit_messages: Referera och fixa Ã¤renden i commit-meddelanden
-  text_issue_added: "Ã„rende %{id} har rapporterats (av %{author})."
-  text_issue_updated: "Ã„rende %{id} har uppdaterats (av %{author})."
-  text_wiki_destroy_confirmation: Ã„r du sÃ¤ker pÃ¥ att du vill ta bort denna wiki och allt dess innehÃ¥ll ?
-  text_issue_category_destroy_question: "NÃ¥gra Ã¤renden (%{count}) Ã¤r tilldelade till denna kategori. Vad vill du gÃ¶ra ?"
-  text_issue_category_destroy_assignments: Ta bort kategoritilldelningar
-  text_issue_category_reassign_to: Ã…tertilldela Ã¤renden till denna kategori
-  text_user_mail_option: "FÃ¶r omarkerade projekt kommer du bara bli underrÃ¤ttad om saker du bevakar eller Ã¤r inblandad i (T.ex. Ã¤renden du skapat eller tilldelats)."
-  text_no_configuration_data: "Roller, Ã¤rendetyper, Ã¤rendestatus och arbetsflÃ¶den har inte konfigurerats Ã¤nnu.\nDet rekommenderas att lÃ¤sa in standardkonfigurationen. Du kommer att kunna gÃ¶ra Ã¤ndringar efter att den blivit inlÃ¤st."
-  text_load_default_configuration: LÃ¤s in standardkonfiguration
-  text_status_changed_by_changeset: "Tilldelad i changeset %{value}."
-  text_time_logged_by_changeset: "Tilldelad i changeset %{value}."
-  text_issues_destroy_confirmation: 'Ã„r du sÃ¤ker pÃ¥ att du vill radera markerade Ã¤rende(n) ?'
-  text_issues_destroy_descendants_confirmation: Detta kommer Ã¤ven ta bort %{count} underaktivitet(er).
-  text_time_entries_destroy_confirmation: Ã„r du sÃ¤ker pÃ¥ att du vill ta bort valda tidloggningar?
-  text_select_project_modules: 'VÃ¤lj vilka moduler som ska vara aktiva fÃ¶r projektet:'
-  text_default_administrator_account_changed: StandardadministratÃ¶rens konto Ã¤ndrat
-  text_file_repository_writable: Arkivet fÃ¶r bifogade filer Ã¤r skrivbart
-  text_plugin_assets_writable: Arkivet fÃ¶r plug-ins Ã¤r skrivbart
-  text_rmagick_available: RMagick tillgÃ¤ngligt (ej obligatoriskt)
-  text_destroy_time_entries_question: "%{hours} timmar har rapporterats pÃ¥ Ã¤rendena du Ã¤r pÃ¥ vÃ¤g att ta bort. Vad vill du gÃ¶ra ?"
-  text_destroy_time_entries: Ta bort rapporterade timmar
-  text_assign_time_entries_to_project: Tilldela rapporterade timmar till projektet
-  text_reassign_time_entries: 'Ã…tertilldela rapporterade timmar till detta Ã¤rende:'
-  text_user_wrote: "%{value} skrev:"
-  text_enumeration_destroy_question: "%{count} objekt Ã¤r tilldelade till detta vÃ¤rde."
-  text_enumeration_category_reassign_to: 'Ã…tertilldela till detta vÃ¤rde:'
-  text_email_delivery_not_configured: "Mailfunktionen har inte konfigurerats, och notifieringar via mail kan dÃ¤rfÃ¶r inte skickas.\nKonfigurera din SMTP-server i config/configuration.yml och starta om applikationen fÃ¶r att aktivera dem."
-  text_repository_usernames_mapping: "VÃ¤lj eller uppdatera den Redmine-anvÃ¤ndare som Ã¤r mappad till varje anvÃ¤ndarnamn i versionarkivloggen.\nAnvÃ¤ndare med samma anvÃ¤ndarnamn eller mailadress i bÃ¥de Redmine och versionsarkivet mappas automatiskt."
-  text_diff_truncated: '... Denna diff har fÃ¶rminskats eftersom den Ã¶verskrider den maximala storlek som kan visas.'
-  text_custom_field_possible_values_info: 'Ett vÃ¤rde per rad'
-  text_wiki_page_destroy_question: "Denna sida har %{descendants} underliggande sidor. Vad vill du gÃ¶ra?"
-  text_wiki_page_nullify_children: "BehÃ¥ll undersidor som rotsidor"
-  text_wiki_page_destroy_children: "Ta bort alla underliggande sidor"
-  text_wiki_page_reassign_children: "Flytta undersidor till denna fÃ¶rÃ¤ldersida"
-  text_own_membership_delete_confirmation: "NÃ¥gra av, eller alla, dina behÃ¶righeter kommer att tas bort och du kanske inte lÃ¤ngre kommer kunna gÃ¶ra Ã¤ndringar i det hÃ¤r projektet.\nVill du verkligen fortsÃ¤tta?"
-  text_zoom_out: Zooma ut
-  text_zoom_in: Zooma in
-  text_warn_on_leaving_unsaved: Nuvarande sida innehÃ¥ller osparad text som kommer fÃ¶rsvinna om du lÃ¤mnar sidan.
-  text_scm_path_encoding_note: "Standard: UTF-8"
-  text_mercurial_repository_note: Lokalt versionsarkiv (t.ex. /hgrepo, c:\hgrepo)
-  text_scm_command: Kommando
-  text_scm_command_version: Version
-  text_scm_config: Du kan konfigurera dina scm-kommando i config/configuration.yml. VÃ¤nligen starta om applikationen nÃ¤r Ã¤ndringar gjorts.
-  text_scm_command_not_available: Scm-kommando Ã¤r inte tillgÃ¤ngligt. VÃ¤nligen kontrollera instÃ¤llningarna i administratÃ¶rspanelen.
-  
-  default_role_manager: Projektledare
-  default_role_developer: Utvecklare
-  default_role_reporter: RapportÃ¶r
-  default_tracker_bug: Bugg
-  default_tracker_feature: Funktionalitet
-  default_tracker_support: Support
-  default_issue_status_new: Ny
-  default_issue_status_in_progress: PÃ¥gÃ¥r
-  default_issue_status_resolved: LÃ¶st
-  default_issue_status_feedback: Ã…terkoppling
-  default_issue_status_closed: StÃ¤ngd
-  default_issue_status_rejected: Avslagen
-  default_doc_category_user: AnvÃ¤ndardokumentation
-  default_doc_category_tech: Teknisk dokumentation
-  default_priority_low: LÃ¥g
-  default_priority_normal: Normal
-  default_priority_high: HÃ¶g
-  default_priority_urgent: BrÃ¥dskande
-  default_priority_immediate: Omedelbar
-  default_activity_design: Design
-  default_activity_development: Utveckling
-  
-  enumeration_issue_priorities: Ã„rendeprioriteter
-  enumeration_doc_categories: Dokumentkategorier
-  enumeration_activities: Aktiviteter (tidsuppfÃ¶ljning)
-  enumeration_system_activity: Systemaktivitet
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/84/842d23caf63cf174cbb0a8bccbdb2b32e5fa17e5.svn-base
--- a/.svn/pristine/84/842d23caf63cf174cbb0a8bccbdb2b32e5fa17e5.svn-base
+++ /dev/null
@@ -1,248 +0,0 @@
-Return-Path: <jsmith@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sat, 21 Jun 2008 15:53:25 +0200
-Message-ID: <002301c8d3a6$2cdf6950$0a00a8c0@osiris>
-From: "John Smith" <jsmith@somenet.foo>
-To: <redmine@somenet.foo>
-Subject: Ticket created by email with attachment
-Date: Sat, 21 Jun 2008 15:53:25 +0200
-MIME-Version: 1.0
-Content-Type: multipart/mixed;
-	boundary="----=_NextPart_000_001F_01C8D3B6.F05C5270"
-X-Priority: 3
-X-MSMail-Priority: Normal
-X-Mailer: Microsoft Outlook Express 6.00.2900.2869
-X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
-
-This is a multi-part message in MIME format.
-
-------=_NextPart_000_001F_01C8D3B6.F05C5270
-Content-Type: multipart/alternative;
-	boundary="----=_NextPart_001_0020_01C8D3B6.F05C5270"
-
-
-------=_NextPart_001_0020_01C8D3B6.F05C5270
-Content-Type: text/plain;
-	charset="iso-8859-1"
-Content-Transfer-Encoding: quoted-printable
-
-This is  a new ticket with attachments
-------=_NextPart_001_0020_01C8D3B6.F05C5270
-Content-Type: text/html;
-	charset="iso-8859-1"
-Content-Transfer-Encoding: quoted-printable
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML><HEAD>
-<META http-equiv=3DContent-Type content=3D"text/html; =
-charset=3Diso-8859-1">
-<META content=3D"MSHTML 6.00.2900.2883" name=3DGENERATOR>
-<STYLE></STYLE>
-</HEAD>
-<BODY bgColor=3D#ffffff>
-<DIV><FONT face=3DArial size=3D2>This is&nbsp; a new ticket with=20
-attachments</FONT></DIV></BODY></HTML>
-
-------=_NextPart_001_0020_01C8D3B6.F05C5270--
-
-------=_NextPart_000_001F_01C8D3B6.F05C5270
-Content-Type: image/jpeg;
-	name="Paella.jpg"
-Content-Transfer-Encoding: base64
-Content-Disposition: attachment;
-	filename="Paella.jpg"
-
-/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcU
-FhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgo
-KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCACmAMgDASIA
-AhEBAxEB/8QAHQAAAgMBAQEBAQAAAAAAAAAABQYABAcDCAIBCf/EADsQAAEDAwMCBQIDBQcFAQAA
-AAECAwQABREGEiExQQcTIlFhcYEUMpEVI0Kh0QhSYrHB4fAWJCUzQ3L/xAAaAQADAQEBAQAAAAAA
-AAAAAAADBAUCAQYA/8QAKhEAAgIBBAICAgIDAAMAAAAAAQIAAxEEEiExIkEFE1FhMnFCkaEjwdH/
-2gAMAwEAAhEDEQA/ACTUdSsdhRCNE54GTRaBaXHiBtNOVo0wEpSt8BKfmpWCZRPHcVbdZ3X1J9Jx
-Tla9OBpIU8Noo7Gjx4qdrCBkfxGupUSck13GJjeT1ObEdthOG04/zpX8SNXjR1njym46ZMmQ+llp
-pStuc9T9hRq/X22afhKl3iazEYHdxWCfgDqT9K83eKfiFG1RfIEi3tuC3W9KlNh0YLqyeuO3QV0D
-MznM9O2uai4QI8psYQ8gLA9virY615P034xX+zNNslLDsMKOG1J5HuAa3nQPiBZ9WtpUy4lmcE4U
-ypXP2rmMHmcI/EealD7te7ZZ2S7dLhGiN9cvOBP+dIF18btHw3C1DkSbi7nATGZJBPwTitTIyZp9
-SsCun9oJaEFUDTy0oyQFyXSOfoB/rQOL466huE9LIagxW1A48tkuKJxwBlQrm4YzNhGPE9Mmua8Y
-JrzsrXPiQ42y7+KtsZt4kpS8ltK0p91J5IzXGFr3xFef8pMqE4vJABZT6se3FDNyEZzNCh89Tfbv
-aoV2iKj3GO2+0eyh0+h7VkWq/CqTDUqXpp0uJHPkKOFj6HofvQRzxZ1bbwFTG7c+jO0lKeh+cGi8
-bxrebZZVMtjDqljKgw4Rt9uuea5vEIEceoL09ZnHQoyGy3KaOFhxO0j6g0J8QNPr3tzorHmsJSUv
-NgdQeprTIuqbfqdtD7MRxh7HO/H6ZHWlnW0e5tQnv2WgupAyEg8p9xUl7WGowpzKCoDXyJ5nvMdK
-Uuho4bSv057CqK2stIWrgEZp2kWtE+O5+MC0OKUchHFCbnaWVNeW1KU3tTtwtAUkj6jkfpXoK7gQ
-AZLsqYEmJ0mUBlLeCfeqHKl5PqJopNhriupQWyoqPpKeQfpTXYPDW+3ZlEhTTcVpXI8w+oj6Cmty
-qMxTazHAi1ZLG/PXuKClv3Ip7t2n4yI3lKZSsEc7hmicXwfu5ThN22fCUH+tXB4QX1KdzN6WVjth
-Q/1oDuG/yjCIV/xgWLouQFfiLK/5LqejbnKT9D1FStX05DRaYrTN8K232wEl1aMJV856VKF9hPc3
-9QPM32HEjxEjykBSh/ERSd4s61uGjLbBnQrcie2t4pfClEFKAM8Y704uvtsMrdfcQ20gZUtZAAHu
-SawHxt8V7PKt/wCytPp/aLrToW7JAPlNkAjAPfOfpQ0JY4E42B3Nf09ruwXvTQvjM9lmGkfvvOWE
-llXdKvn/ADrONZeNwU28zo2Ml1tHpXc5Y2spP+EHlR/5ivOzYkPPKdjMechRDjrCUHy1Ec9Aa1Lw
-l0VF10pcy4XJC0RlbTFTgKbHwnokfSibFXkzAJbiJ0tN81jc1yHXplzkEEqkPA7UjvtR2H1/SrOl
-rGu6NvP7Q8yhaWkDruVj/n616Lvl20n4Z2cpeS02tSfRHbAU69/t8nivOGoNXzNQSVRbFAbtsFal
-FESEjBOepUR1rBs3D8CFVMHjmXNYW+wWtsMrlMvyyOW4h3FB9irpn70lx7k9AeDttW4w70DgWd3+
-1NmlvDi7XpL0iShcWG0dqllO5SlHsB35NG7l4PSRG823z0YbGFqkDaFK+MZx7d6XOu09Z2M8MKHb
-OBM1vBuAkJcuUgyHXRu3KfDp+5ycVTaeU36kKUlYOQQcEVrehvC5l1Mh/VClISHFMttIVgL45VnH
-TkEH4rQbjpHTbyGWVQIzL7bYabc2AnaMfYnAxk0K35Smo7e/2IRdC7eXUwfT5m6pfbtC/wARIlLW
-VNu7yoN9MlQ9h3NO+n9Cwo8rzZU1Sm2Mlx9YLaUkHjaOv3Nc7zd7FoyY5D07HR56SfMl7961ZGNo
-9gKXrtd77dnkssoSwt7K9rZG8jHU44Tkc9q0rvbyvipnNgT9kTRLvqKy2JDgS/8AiH3hjecKXjv2
-/SkG8akmRyhqG+hKSQ4dpyofBxxV2w+Hkuda27pMW5tcSpWxati1HJGQTkYp70xoS2MW1pp+ImXN
-koJLi+UtfP1FAt1dFPHcPXQ9nPUy+/3pu4usrYZS16MOKCAkuLJypRxX5aG5ExX4VlfC/Vt98e3z
-WvL8M9NsNMtyFyVyGx6h5uPMPyMcV9Q9HQbbdWwzHQGFHKVhStw+uTQTr6tu1IQad85M46baVarV
-uVkJ/mDVCVqWUll59t4FxlW0ocOA4k+1P8uLGU35UgAhQ2kgdRWUeIMi2WyKqASFLJJbWchQI7Ul
-pWWyw5GSYZ1IXA4Ez7U12mR7q95jCWgTuCQeoPsaGqntylbCpIdxnaSM/wBK56lujtydZS4UkNIw
-CBzQO4RURywWnUupcQF7knoT1BHYg5r0lFY2DIwZKvYq5x1DjUo26WzJKEuIQoFSFDIP+9bzaL0x
-+HZcZcQpC0ggewIrzYzNJQGpGVt+/cUw2PU8+0vqWEJnW8q/9KzgpHslXb6UV6yw4gBZg8z1NZbj
-Ek43LQDjkZFMLbkMcJW3+orKvDq86T1SUssrEef3iPq2rz8f3vtTZrtizaR0pOvD8XephOG2959a
-ycJH60HBBxDBhjMB+L9/RY7WpT7jam3kkNNJwSs+/NSss0Bpi4+Jmpfxl7kPOQ2k7iCfyI/hQOwz
-/vUroqrUnceZ8LnIG2Cdaa61Dq54i7SVJi5ymGwdjSf/ANe/86s6W0TLvkNySp5pcVjBUy0oAD5x
-1P1NbDbPALTQjp/aC5bj+OS27tH+VOmjPDqw6QEv9lNPFcpIQ4p5zeSB0A/WtNYoXCwK1nOWgjwk
-sFrg2wuJjtKl5IJUBwPakLxDXbNI6/alaGW6b87uL1vjJCmAogjcvHTrnb8DpVnxj1q1oOS7b9PP
-j9qSEErA58gHuf8AF7CsStOurpBjKZioQqS6sqU+vlayepPvQytu3cgz/fEPWaXfFjYEfLlo5+bM
-/aurr+X33vW6lIJUD/dyen2p80zboMNG6NBEGOygJLy04cdAGRjjn5NYRD1NcjMMme8XpST6Q4Mp
-H0HStstF4kO2lMS5vAlTfq9O04PQZ+KifILaqg3PnPodS5o0S3I0q4x2T3Kr+obzH1HsjuFFpeUU
-B5s5Snck4ST0z0p502w5HZW86qW5lXLbpSeMfHFZH4gpFutbDlrmNtujlxvzc705HAHfB5qknVSI
-VliuWK7STcHVBL7Ticc8c8f70IaMaipWq4z+oo6jT2sr8ma3qCfBky48be4zvcAOB6gR/CMd6EXF
-m9EPKhx3Vx92EJdADmOmQKJ2y5xVpiJlW+OzPSj1LbSBtURyoGjFzWqPbHljClFBLbiBnHHUmpeT
-WdqiPISuDM/e0bark4YzkEJkJ9RebGF7u+T/AKVeg6DbVdXHJ6U/hi35KAlRGU44zj/WrtpdfSlt
-D7m54jKznr/WnOAVKa9Y7cGtDVWodhaH1WnVlD7cZxPhq3NMobbeBeZQnalKlZ47cUQDSGtvlqwn
-GEp7AVQdbddWQHkp2dOea6qWHQlPmJSscEE9aET/AJCK/X+JFxUtuKecHnKxx8VXRKiBSkuKII55
-PSvq4yUQmf3qspxwc8is71fqZMeKtTO0AHn3V8UaitrDgdmcdtoyZ215q1USShq0bZClghTYPqFL
-Vr0xH1otbt1XKZkpT6cccfOaF6SZkz7q7dZYWHjz0ykJp2Yvi4YaYVHdUXjs2eSUlR7HPt89KoW5
-p8af5D3OVLldz9GLmsNLR1WZiI+oJlRB5aHgBuKe2cdaxd5tVsuy0OJbdWwvkKGUq+or0PqiyXVy
-IJ7za1NlIJbz6m/fgdv61lN000qWJ09EWQ8++6lqM01k8geokY5p/wCK1RXK2Nn/AOz75PS1vStt
-Y594iCUnOauWi5SLXMDzIQ4g8ONOp3IcT7KHcVduWn7nbWg5OgSI6SopBcQUjPtzXK1RX1OqkMtb
-0xcPO9PSkHrzV0WKRkHM86a2BwZqFm0da9c2pdw0asM3JgBT9qdd2uNH+8y51x7A/rSjrXUmq129
-Om9TuyvKhu70NyUYd4GBlX8QofG1hcLbrBF/tZ/DvtqGEDhJQONpA6gjrXq61f8AS/jDo9mXNhNu
-nGxxPR2O5jkBXX+tY3bcFhPtoPAin4H6gsMTQgLEhtM7eoyGioBYI4Tx7Yx+pqUr668ILjZXDOtS
-XZsdvlMiGkJlND/GgYDg+Rg1KwUDHIM2r7Bgiei5NwiQo635cllllAypbiwAPvWO678c4UJuRH0y
-gSHkDBkrHpz2CR3+prHbXJ1L4o6matwkKaYP7xzkhthsdVEf8NLWrzbo94fh2RKjAjqLSHFnKniO
-Cs/X/KuLSAcN3OfYW5HUD3SXJutxfnTnVOyn1lbi1HJJNPnh9otyfbJF5lLabjpJQ0FjlZHUis9C
-lDOO9bdHkS4WkbXBlIMdaGUnyhwkjqFfU5pf5K566gqe+I98TpBqb9pnB/Q9wu7kdyOGUNNp3oWp
-Owq7+3P1r9uQmqllqS+S+ghClFWR+vtT/Z7goWGOopbjodwEltQOcdR16/WrcrTFmW4tyYZHmuDc
-dhwkDHSvNvq2BC2+up6PThdIzDvMypelJN2lI8+M9JKxsZS1/Cfcn2+tF9K6Oh6ZeW5fYS5VwKgl
-locpR3Cvk0+zJTdtioi2htDe5OVL/KAPcn3r5j3ZtdmkrKFTFJ3EDG7BAzgH9a+XX2sNi8CJXaZW
-c3GIN7u0u931+KwhaGGspKQMKcKepVV5UmU1DZZtzspMVKQXm3F5B+gHIH0zQCBImKuiJMeCuEH1
-YCfVkjv+bqSKr6t1U7a7uxEgurS0yMLBASc/arlenBULiSGtOSSY6WKJKXckJU2tplSt6FA7gfvW
-gxA/sUBggDGSayGya5ed8tkNqSlXVYOVVpEZydIablRFF6ORgjGFJPyKga3Tuj5Il2rVC6sKT1L9
-tiuPTnDI3eSfc/lqrqWOuHFK4qlF1HIX7j2NWIkyQ8XEApSUcD/Ea5TmZj2SggqUMKSrp9KUByQM
-T45U5mSS9UzJMtMZ93GFcqJ7UL8Q3UOOww24Bx6h3V8/Sqev0sx7u4IqkB5w8tJ4KFfNBXG3Fuo/
-FPqLxA3FXXHtXp9PQiBXXiTGZrmIjTo68qh+Y2ygPhYSAlXIBz1rYHp04RkNRnWDOA5KyEgDrgVh
-mmSmPcCfQpWCACnINFdRXOW3GQ4+60GgcJKDgr+R70lqdP8AZaAvuUK3woDY4mqyrjeFWppZZUXW
-lnzUlYCVp+K+LLeYEoLLG5lGdxQk4wcfyrOourlyIzbDhcKVNhHB7e9XYlxatbam0dVDOAOT96Rf
-TEDBHMMpU9dTQpVxiTWXGUqDy1n0hxCSAPvXnfWVtnWO9TI8lpLHnZOGxhKkE54+K1K1XhLj4S4j
-GOnxX5qiNZ7wlpd1Di30ZS0hKtu4kdCaN8fqG0luxhwYtrdOtqZXsTA1dTWh+B+unNG6tbTIWTap
-hDUhGeE56L+oP8qSbtBXDnyWSB+7WUnadwH3rgYT6IQmEpS0VbU5WNyj8DrXr/F1/ueXIZT1P6Hh
-aVoSpJBSoZBB4IqVjPgP4ii72eHZLsSJrCPKadP8YA4B+cfrUpMgg4jK8jMybw5vUfT/AIXatujD
-iRc5S24DX95KVAkn/P8ASstODk9asPSXvwZbUEoQpzhtIwkYHt9z1q3NZiO2uNMhFLbif3chkryc
-9lAHsabbAbP5i6DI/qctPSokW9w3p0cvsIcBLY7+2fituuVxYvDbAMZ2VIUkeX5I5x3Tgdqznwz0
-xbb/ADZQuy3w2y2FISycHJz3+MVtWnNLwNMb3G0SZDvlgb3DlWPgf86V5/5e+oOAc7l/9y18WLK/
-IdH/AHB+l23bLPLMl0RkyQS22r1eWQO/tR178NEju3GS8ZahyVIc7ewA4qpKKfxzTMOGHCsBZSob
-ueveitut+XGo8tpDacEp2DAP69ahNYHO4yo1rMxJgt22RLy0l5bYQ04jckLWfM+o7frVPUMpdg0a
-65EfXvaX5XOArnp9hTtGgRbcyhL6PPbaG1ClnJAPvWeeMl0FogwnWGYkqKHSFxnUkpSojgkD79aJ
-pQbblr9ZgNRcAhMzli9zZYfS27NkPBIKAFKVnnkn2pf1PaZbMNm4PpkDzeV+c0UEK+p6/WtX8H5M
-GXDm3OS22Jq3P/W2AlIHwOgFVPF+VBfjqKi4sEHBKSAVfFegXWsmo+pV4zJZ0wareTFbw71Y1Ab/
-AAjbcNh1Q/8Ae9yaYU33VESW5KdK1wucuMpwgj3FYq4S456E7VDjimGHqa6wYqIS5HmMq42LOQBT
-Wo0AYll5z+YCjV7MA+puVmuDkgh7evZt3bsdK46s1uiNZSY6iHwSj82CPnFC7PcbdbdOxkPTiqaB
-5iQlXCf61mV9uC79dn39oDIVztGAajafRK9pPoSrZezKAOzKclyXcLgue8VLUo7sHrUaVIfeCloG
-T0Uo9qstKdbcBLZUg9DiuzkbY4VDIBGQkdBVkuBxOrRtAwf7naKlyMoqQ4pRI9RHH2qtc1/i/KS+
-p3yWchtKwcIzX7HnoQv1nbgYUR7+9NESXCmR1xdjexxOXCTg9ODSzO1bBiJvCsCBFu3eahwltCnA
-O6ATj6082K2rlltyXGSsIGEhzPP1xQa1QJNngLmMuNPMrPKE5BwKuzrw6Yu6JJVGWkZSkHIXn274
-pe8m0+H+51G2DBlu4J/DzFKbWhICiS2EgH7H2FD3JTMuclt7B2ArBzgJPvQNF1lSUFoON5JyST1P
-tmgEu5yY0wgJ2uoUd27nPtRKdEzHk8xezVLUnHudtXsRYc4rt8pxZdKvMSpWcH60M07a03W5JZcW
-UtgFSj8Dt96orKnVKUQVK6nv966R5b0dCksLLe4gkp68dOatKjBNgPMiM4Z9xHE1fwCkQx4pqYdC
-vJcC1RwT0WkZH8s1KVPDm+Psa208ogAtysqWOqyo4JP2qUtanPM2jDEL+OWn49u8R5UK0MbGClDg
-bSOApYyQPvSzM0rKt9qiXCRs8uSSlCeQoHnII+1aJ/aAZWjxImL3FILTSwR/+RX7bhqJ561XC5Jj
-O20pSnyFYJWMZypJ6djWLdSa1BzxDUaYWnaOzH/RlmZ0nYWPJab9SQqS5t/eLV2+wzj7UfZmouM8
-MNtlsNoKlFZAV8H4FULPfmrmtyCtwJfQjKggFIVx2orHsbUZ1TzCktFwfvVKJJUB05968jqHaxyz
-y3t+sBeiJJTLSXA6hAWscFSTjke561yfkAlte4h88BIJwB3q5Hjx297RUpWfUD+YYqs5Gjx3HJJK
-ywRylIGM+/vShBMIrDMtpKiyVKcWtvaP3aRnn3HevOfi9eZM/UEiEv8A7eOHgkhfT0jg4+5r0JJu
-ENLad0plpWM9c8dqUtTaMtGoJS37gyXH3UANyEHH6iqXx99entD2CK31m1CqmZZomd+HjORbXte8
-hOVLSk4USeTRm4xrvqbTjseUGmozTmVPLH5fgfNNNhYtWmJardbw3tf59XqIwepNM2poyJVpdKEt
-+SRuCR/EfemLdWou3oO/cJXVmsI08z3BiFp7UakMuonR0jk47+31oG7iTM/dkNoWvCdx/KCe9P8A
-dIzR1PAZfjtI3gx3QsAJHznFKOqbfbbXKSzbriZrwJ8390UJRjpgnrXpdNeLAM9kSDqKDWT+AYcu
-1ivcK2x1KdiyYSejrCgSnPZXehTLqou7cghKRkgd6Px9SWp2xsMT23HF7QgpaOCFDoaCxFee4UKC
-gCT14P3oKs5B+xccx+kIpG0wlaJKZLB9KglB5Uo9KsLeDj2GzjI+1AjmPLH4ZzCVEApPAIopGCFR
-1rSpW4naaFbWB5DqUabMnaYEuTGyc40le4deO1fMZam17krwAOua7yYjyZCiG8hZ65ya57WW3W2y
-lS3FDkFW0CmgdygdydZ4MT1HezzUy4iCwVKLKcFtSuD74r9uVtRJabLZ8obckpTlP60ItSLXOeDT
-KlR1spG9W7clw/ejN4mXa0MDYA9FLn7olIxtxyFCprVkWbU7/cY+0FNx6/UU70GYDBQw6FrUcAgH
-ke9Lq3FHkkk980xXedHuYWt6D5L4A2rQrCQO4xV+yaaiTrW5JL29GRgflUCOoJ5wPmqaOKUy/cl3
-Zufw6itbriuAJHloSVPNlvJ/hB61RCwVAKPHc1YubQZmvNpSlKUqIACtwH371Tzk/FOKAeR7ibEj
-g+o06QWy7riziG2pDf4lsJCjknnrUrv4TtIe1/ZQ50Q+Fk/TkfzxUpW7ggQ1a7xmbF/aGsKEX83N
-U4IU8wFJZWMbtvBwf04pOieITadOMxXmWRJR6CsD1HHTH2xWx/2irAu9aJTIjJJkQXgsYHJSrg/6
-V5os1rjsynVXOQY8uMsER1t8r+M9j0pSymu1P/J6j+ktatxtE23QtvmwYar3cX0JjyE+hhQ9ROeC
-a0CJJaLTe+Uhfm/l7/YUhWKUxfbKxCztdQkJStWdySf7o/rTHZLC7bW3g5M819Y2pLiPy/TmvLak
-AsSeCPUp7i1hB6h+Ytbnl+US2AfVx/nXyWg4kpeOQ4CPT2FVX0JacS6qWpASnC0qIINDLlKKGyGp
-QaLmADgYA74xzSY7zDpWW4Eq2e0N2yXMdmKS6twlCUO4IQj3+po86RGWzGjtNgO4AATwlPXNAmPK
-dLanH15K04SEE5x7GrsGWLnclJ9SHGuCrOCU+1E2s5zNfSE/7mJniFFciyHJ6XEktoIylWBjPPHv
-SnC1HKlFK25Kls7cBpSvy4PtWwXHSsCXIUqUt15Tg2qStfpx7kUIc0JZIqHlpGwqTgFJxgZzx809
-XfWE22DJgwQD49TGr0pN2nlL7i2JKjvC1DCc9qUtRR47sjLQWiYkYdbX0PyDWwax09bZpcZtpdbl
-FJO5aztJxkD46Vl83TclMT8SlDjh28lIJwfY/NXdDqK8Ag4iGsosYHK8QVKiRIztv/BqccWUhT6l
-jASruBVpEoKkOAYLhJO0D9KGIUoqQ2vucYPaidptb0i6lCMNt8lSlq/N8VRcDblz1J9Tbf4CEGYb
-rzbjiEBLqQQAtQAzUs7jrqnGFNJy0fUMcA/WjlutUySrLT0dLGw5C08hQ6fbNCrTBuVlubjjkJ58
-pJwU5Lef72B1pQMLFYZGY0bHQggS7KYUw35ivUlXU9xSfdCp5QWltSUp/iPfNaBLtv4KGiVOkYcf
-X5imS2dyE9uM8DvjrQc2hyYsg+WGSfSQKxRatfJMLepvXA7iilxtKmlMJcQ4nlSlKzn7U4wbou7Y
-RK9SGeUpzjJPciuLmi5ayDF8t3nsrHFfFx0lcbeSptYWhKUlS0EjBP8ADR2votx5DMSFF1eRjiGF
-OWuK4mO+y2lTyFIWpw5SCeivgZpNuCzBU4zEmBbTnUtq4UP+ZoxaNIXG6So5ebX5C3NillXQd/pV
-zWlmYtEJmEiARLz6XEerf78jrXy3VK4XO4mDsSzbwMYiQI8iQlx5tpa2kfmWBwK4BKVdDiicpq5t
-NGItl1DbbYdUgDgAjO40JZSpxwBA5zVBDnn1EnGD+5rn9n+1pXeZlzcQFIYbCEEjoo9x9galN/hp
-BFn06wwQA89+9cPfJ7fpUpG072zHql2Libtf225NukRX+WnWyhX0Iry9drM3ar2i4XN0h6BKS28r
-O5TiByleD8Yr0ldJyHWtyOD0UKzHW9taloXM8jzkhBbkN4yVt+4HunqPvQXBxkTqH1E2dck2u5wp
-9rUW0yiVPKCdwQgkYJx361pca9NSGG3C5kIR6nkD0g/Ws5uMMT4DJtFyZTCdSlAjlsJKTnHpP+hr
-hapk+yxP2fNW7+DeSrAIyN3uP0qJfQtij8/9lPTlkznmPNwdh3FgILzgcK/3bqSfUfZQpW1BMuNr
-hKeeQlCyrCWeu0DjdXL9oW2NAadjuLbdj4UFBQIWoe6Scg/NEo5cu81h+5JAQtvcgdE++Tmlvr+o
-5YZEbpvstyvRlPSGtFvNJjzox4JKHknHP0pq03c2GlTAp5j8Spw7d5CVEYHANL9xsrTbMibHUCUJ
-IKEt8JPvxSey4ZylLX/8yOSMbqIK67stXwIT0NxyZubSDKUX1lbawkAZ9u+KHXeez5ja3HwhpPxy
-D2HNZu1rG7W5zeqS0EgbUggHA+nvVaNqOXdr5HVNcQhCV71BKQNx7ZzxQxoW7PUIgGcmNs6SqW+W
-2hvdc53qRgkHgc0YsdpVGgluSGygrUdqQClJ+TXVu2sSSu4x3PxD20qDa14yccAe2KruPvNw23Lg
-z+HDytqh1Chjoo9utAJ9LC22h0CqMRc15omyXhCnLc0mLc0c7mcBKiBnCk/PuKy646YvkCU0qLuL
-iWylQUPyE9cH5/WtkRLs0VhTLzqW22sEqLm5xXPTjtV2bLt88sttrCSpQxsOSCPeqGn191ACnyH7
-k27RI/K8TFdFOOYcTcAWENqIcUpJBz23DvTqvWMRElm3uQiUpIQ08BgJV259qdFWjzorsd8RXQ7k
-KJHCh7E9yBWWatszVpmsKRuCRgJTn0g5P9KKt9WrtJYYM+q07IgQGWpsNN/lsTH5W7yF7H22+Nqc
-ZJz84r8sMda284IRztBHal19yRbslgltMjKVA01abvCmLamK6AprbtGeoo1ysKwF5Eao0TsxK9xu
-03BS6hS9gU4DzkUWj26G4osKbSpRysBQJGaE2W822NHDbyngM7s4wM/avmZqdhrelhorSoEbxknn
-5qVtctnEOdLZnkQvKjIhuNojNZyraQMYTx1PtXzeYMZtDS30IS4lQWhWMkH4+tIxvz8GT5iQt1Bz
-vSoHBPbNVjPvGo33HWnSEsgqTgcE9NtMJpWyGJwJ9dQVGOxAGt9QruazbYxQGMAOOjBUo9hn4pf0
-vYiu7AvEKQ0rcQOh9hX47bJMW5qjlrCyohKSoEgfOKboflWmIhhsb5S+Sfk16SsCmsLX1PLWoXsz
-Z2I6QZ3kBKc5dPGPapSw28qMn1q3PK/Mc9PipQ4YVMwyJt2oHV2uZuGVML/mKoKWlwbkHchQ4qkN
-ZaevsQxzcmQsj0byUkH71TgOvRVqbeG6Ks+l5PqSD9RXxBioihqTS8Vm7JlNyHGIqlZWWujDmQQr
-H9339q/bihUVLqVvh1ak7S6g8KHwO1OshQIIUAoHg96z7VdpkxIEw2chTDqTmOr/AOZ90Ht9KWv0
-7WkYMf0Oqr075sXIgLTkZl7Uy1zZCQhpsuDOOuQOa05NvYkS0J8h1UUDd5w5UOOAfisK026yJZj3
-YOR3i56XRzkn+EitUsN4uEvEeCpDCGlEOL67ldMikfk6HUg54Ef02pS9i6jEcLpcGUMLSW9iU43J
-6EjH+VZ9NuLDmQqCIsdxR7e30rQWNPKaebmOTVrdXysq5C+OhFfcm129Y/7ptghJ3JKU8j6VLqtS
-rvmNFNx4mNXGMy6jEQqeUF5V8D2oS63JalpaQdrhxjdyQK2O6Ls8SOGm0hO7ohKeVH2FIl205Pdd
-cmMskrICkNg+pIz0IqrptWGGDwP3M3VhFye4w2hmVGYaUmUUsrwcpOSn5xTpcpUJu1vOmQpwObUK
-S6njfnjjtzWOu6iu3luRnIhQGTtJHBB/pRq1u3G5hhKFlIVneVdz9+lKXaRgdzkCdRxYMg9S9qB+
-A/MS0tpYIVudaZTgOqwAPtUdjTkORXGmhHbKgltKVBJSMd+9Mtv/ABrcWRFLUdxATl0lGFlWOx7/
-AAaEOJhuLZipYdksr6BokraVnnd7VhbOl7xBfWwctnj8T9m39strVFa9aMggZKlK+lLGpXLhc47d
-smsKjlSgpJWg5A65B7dfrWk2vTdus8p+clS1vYyEurB2H+pqs9erVc32zJIbeZXtS2oZO8fH+tap
-sVH3VrnHucXftIeZf/0zdZDYbKlPlpJWVnkZ7D704WLRhTbkOzg6XVpxsB2+Wfr3p0hzIylPPtth
-KEr2uFQxuI7ChV61IhaTGay24okBST0J6GutrLLPACMJY6DxMze/Ldtdzcik7gnlJ+DVJF2KTlVO
-0O2M3WK8mQ0h5/HoIOFdepPalq5aTuapziQhptrPUkHA609VZW3i3cbHyRVfKU03RLishXIpfVqe
-Q2lyJC/dZWQpfzmqF5f/AGdcSw08hwJxnb3V7CqcNl5qWp6U2lKRnYnOefeqlOjQDcw4kX5D5g2Y
-Wn13GOKsQklxR8yU51UecUSt+5GX3vU8rue1CbeypxfnO/YUWB9jRGIHAiVNZc72lgLJVzzUrmg1
-KFiOjjqIwUpPKSR96KWnUl1tLoXCmOt+4CuD9qFlOe9fm3nrT5wexPN5I6msWHxHjzili+Nhlw4A
-faGBn5HSmicCI6X2loeiufkeb5Sf6GvPqknrTJpPVs2wPbMh+EvhxhzlKh9KA1XtYZbM9xj1Laos
-/K1ICHv74/1qnbryuwBtCIYQgDatbayQv5wehpnu8NiXaBebK6X7csgOIPK4yj/Cr49jSbJXwQel
-BesWLseGrsNTbkjx/wBWQ4FvYfdntLW8NwZC8qT9RQ9Gq3bo8ERlBDajgrJ/KPekB1ltLqZCAlK0
-HcCUgjP0NfIuy1Tg+yw2y4kEL8kYSv52nj9KSPxNQ/jyZRr+UYfyGJt+nm7Kje95pflEAFxR6H/C
-DQW+OSocpBjL/EFZOHmzyR7GkzSl9ZLr5uE2LFBOPLWlWSPccYFaxpS8WZlP4aEpDri8OKO4KBP+
-lTL9NZQ/kMxg21agBi3MXo9ulOvB1uC8p0j1LV0PH86JQ7QpiSh94mO3tUFBSeMn2zTsJjKFrde8
-g8DbsIJA78VzbuEd6MVLaSWFZSCUZI985pRnJjCviI2nbncJNzXDUhL7aSU5C8J2/OKcbTaodsU7
-K8hLL6zuUndkA/GaU7tM/ZUlQjBlu3bdzbkdHKTnkE+59qU77q+4zISmGY8lbyVH96hKjlPHHFGG
-me0+HAM7bcmMxv1V/wCQkLFvcdxzktd6RbNDC71lDgbS2dy3F9sHmh8PVF5ZQtEdteFDar0eof0o
-8q7abXHYNxdDEhgYUUnYpffkdxmqFelspGMZz+Io2qQ+51v9/wDw7KkwZflxlElIKgTnPJNcH7mz
-Asjbi1smU8QouE/PBH2pd1DreyOwnojMGPIK8+tLe3HGAfrSE9cVrjtJjFfozwv1bfpnj+VOaf40
-so3DETv+RReF5m53LUNis0Bp9ExK3QkAoQ5nPfisq1druXd3CmMVtsDITlXOPn3pcMGS/HW84VKd
-zwF9SKFKCs7T27U/pvjqaju7Mm6jW2uMdCE4tsukyI5cmY77sdtYSt4DICuoBNMFoWiapJcVhY6o
-V7138N9XK0/JWw42l+BIT5cmMv8AK6jv9COxpi1XpBtE2LctJvfi7bOBdbAI8xrH5krHYj370zaf
-R4gqCQwxzOCMJGE9K6A4rm20ttnDysuJ4OBxmq0uWllv08rNIjyOBPRsCg5GJLnODDZQg+s/yqUs
-zJKlqUVHJNSmkqGOZOt1TBvGfZIxkVwWsg1KlaEmT8DhxX7u3dqlStTka/D3Ur2nrylKkfiIEr9z
-IjK/K4g9fvR/xBsyLDqF+IwsrjqSl5rd1CFjcAfkZqVKHYIZOonyclpZz0oeygoUpWetSpWVmz1O
-c6Ol9o9lDoaBIkPMOZS4obTg4URUqUzWAeDE7SVPEYrXrSZb30ORGwhwDG4rUr/M0SXri+SpYcYu
-EiMMcJbVx9alSgtpad27aMw6ai0pjdKFz1nqJuSn/wAtIJIznj+lfQu11VueVdJm9weohwjNSpWj
-UigYAmfsck8wPPlPKz5jzyz33LJoOt1SieSB7VKlGQQDk5n2w35qwCaYLbEQEBwgY7CpUrlphaAC
-3MIkBKc0DuUUKC5CcJIPI96lSh18GH1AyINiI8x9CM4x3Fat4f6okWOY0qKkFv8AKpCgCFp75qVK
-xqfUY+MUENmMmv7bHbDV5tqPJjTFcsK6pVgE4+Kz68xy41vZUEKPvUqUovDyufKjmfrVmYbiHd6n
-cbis+/WpUqUcMZKdF44n/9k=
-
-------=_NextPart_000_001F_01C8D3B6.F05C5270--
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/84/844e1f7efcdb7d2e09fc680929a5a6cad80561f3.svn-base
--- /dev/null
+++ b/.svn/pristine/84/844e1f7efcdb7d2e09fc680929a5a6cad80561f3.svn-base
@@ -0,0 +1,141 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AuthSourceLdapTest < ActiveSupport::TestCase
+  include Redmine::I18n
+  fixtures :auth_sources
+
+  def setup
+  end
+
+  def test_create
+    a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName')
+    assert a.save
+  end
+
+  def test_should_strip_ldap_attributes
+    a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName',
+                           :attr_firstname => 'givenName ')
+    assert a.save
+    assert_equal 'givenName', a.reload.attr_firstname
+  end
+
+  def test_replace_port_zero_to_389
+    a = AuthSourceLdap.new(
+           :name => 'My LDAP', :host => 'ldap.example.net', :port => 0,
+           :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName',
+           :attr_firstname => 'givenName ')
+    assert a.save
+    assert_equal 389, a.port
+  end
+
+  def test_filter_should_be_validated
+    set_language_if_valid 'en'
+
+    a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :attr_login => 'sn')
+    a.filter = "(mail=*@redmine.org"
+    assert !a.valid?
+    assert_include "LDAP filter is invalid", a.errors.full_messages
+
+    a.filter = "(mail=*@redmine.org)"
+    assert a.valid?
+  end
+
+  if ldap_configured?
+    test '#authenticate with a valid LDAP user should return the user attributes' do
+      auth = AuthSourceLdap.find(1)
+      auth.update_attribute :onthefly_register, true
+
+      attributes =  auth.authenticate('example1','123456')
+      assert attributes.is_a?(Hash), "An hash was not returned"
+      assert_equal 'Example', attributes[:firstname]
+      assert_equal 'One', attributes[:lastname]
+      assert_equal 'example1@redmine.org', attributes[:mail]
+      assert_equal auth.id, attributes[:auth_source_id]
+      attributes.keys.each do |attribute|
+        assert User.new.respond_to?("#{attribute}="), "Unexpected :#{attribute} attribute returned"
+      end
+    end
+
+    test '#authenticate with an invalid LDAP user should return nil' do
+      auth = AuthSourceLdap.find(1)
+      assert_equal nil, auth.authenticate('nouser','123456')
+    end
+
+    test '#authenticate without a login should return nil' do
+      auth = AuthSourceLdap.find(1)
+      assert_equal nil, auth.authenticate('','123456')
+    end
+
+    test '#authenticate without a password should return nil' do
+      auth = AuthSourceLdap.find(1)
+      assert_equal nil, auth.authenticate('edavis','')
+    end
+
+    test '#authenticate without filter should return any user' do
+      auth = AuthSourceLdap.find(1)
+      assert auth.authenticate('example1','123456')
+      assert auth.authenticate('edavis', '123456')
+    end
+
+    test '#authenticate with filter should return user who matches the filter only' do
+      auth = AuthSourceLdap.find(1)
+      auth.filter = "(mail=*@redmine.org)"
+
+      assert auth.authenticate('example1','123456')
+      assert_nil auth.authenticate('edavis', '123456')
+    end
+
+    def test_authenticate_should_timeout
+      auth_source = AuthSourceLdap.find(1)
+      auth_source.timeout = 1
+      def auth_source.initialize_ldap_con(*args); sleep(5); end
+
+      assert_raise AuthSourceTimeoutException do
+        auth_source.authenticate 'example1', '123456'
+      end
+    end
+
+    def test_search_should_return_matching_entries
+      results = AuthSource.search("exa")
+      assert_equal 1, results.size
+      result = results.first
+      assert_kind_of Hash, result
+      assert_equal "example1", result[:login]
+      assert_equal "Example", result[:firstname]
+      assert_equal "One", result[:lastname]
+      assert_equal "example1@redmine.org", result[:mail]
+      assert_equal 1, result[:auth_source_id]
+    end
+
+    def test_search_with_no_match_should_return_an_empty_array
+      results = AuthSource.search("wro")
+      assert_equal [], results
+    end
+
+    def test_search_with_exception_should_return_an_empty_array
+      Net::LDAP.stubs(:new).raises(Net::LDAP::LdapError, 'Cannot connect')
+
+      results = AuthSource.search("exa")
+      assert_equal [], results
+    end
+  else
+    puts '(Test LDAP server not configured)'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/84/84675d4c5913f4d4787034973ce3aa888eb2ae42.svn-base
--- /dev/null
+++ b/.svn/pristine/84/84675d4c5913f4d4787034973ce3aa888eb2ae42.svn-base
@@ -0,0 +1,36 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class WikisController < ApplicationController
+  menu_item :settings
+  before_filter :find_project, :authorize
+
+  # Create or update a project's wiki
+  def edit
+    @wiki = @project.wiki || Wiki.new(:project => @project)
+    @wiki.safe_attributes = params[:wiki]
+    @wiki.save if request.post?
+  end
+
+  # Delete a project's wiki
+  def destroy
+    if request.post? && params[:confirm] && @project.wiki
+      @project.wiki.destroy
+      redirect_to settings_project_path(@project, :tab => 'wiki')
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/84/849f87222b3ad4c6513f88d2c270ccbbefd56465.svn-base
--- /dev/null
+++ b/.svn/pristine/84/849f87222b3ad4c6513f88d2c270ccbbefd56465.svn-base
@@ -0,0 +1,86 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+module RedmineMenuTestHelper
+  # Assertions
+  def assert_number_of_items_in_menu(menu_name, count)
+    assert Redmine::MenuManager.items(menu_name).size >= count, "Menu has less than #{count} items"
+  end
+
+  def assert_menu_contains_item_named(menu_name, item_name)
+    assert Redmine::MenuManager.items(menu_name).collect(&:name).include?(item_name.to_sym), "Menu did not have an item named #{item_name}"
+  end
+
+  # Helpers
+  def get_menu_item(menu_name, item_name)
+    Redmine::MenuManager.items(menu_name).find {|item| item.name == item_name.to_sym}
+  end
+end
+
+class RedmineTest < ActiveSupport::TestCase
+  include RedmineMenuTestHelper
+
+  def test_top_menu
+    assert_number_of_items_in_menu :top_menu, 5
+    assert_menu_contains_item_named :top_menu, :home
+    assert_menu_contains_item_named :top_menu, :my_page
+    assert_menu_contains_item_named :top_menu, :projects
+    assert_menu_contains_item_named :top_menu, :administration
+    assert_menu_contains_item_named :top_menu, :help
+  end
+
+  def test_account_menu
+    assert_number_of_items_in_menu :account_menu, 4
+    assert_menu_contains_item_named :account_menu, :login
+    assert_menu_contains_item_named :account_menu, :register
+    assert_menu_contains_item_named :account_menu, :my_account
+    assert_menu_contains_item_named :account_menu, :logout
+  end
+
+  def test_application_menu
+    assert_number_of_items_in_menu :application_menu, 0
+  end
+
+  def test_admin_menu
+    assert_number_of_items_in_menu :admin_menu, 0
+  end
+
+  def test_project_menu
+    assert_number_of_items_in_menu :project_menu, 14
+    assert_menu_contains_item_named :project_menu, :overview
+    assert_menu_contains_item_named :project_menu, :activity
+    assert_menu_contains_item_named :project_menu, :roadmap
+    assert_menu_contains_item_named :project_menu, :issues
+    assert_menu_contains_item_named :project_menu, :new_issue
+    assert_menu_contains_item_named :project_menu, :calendar
+    assert_menu_contains_item_named :project_menu, :gantt
+    assert_menu_contains_item_named :project_menu, :news
+    assert_menu_contains_item_named :project_menu, :documents
+    assert_menu_contains_item_named :project_menu, :wiki
+    assert_menu_contains_item_named :project_menu, :boards
+    assert_menu_contains_item_named :project_menu, :files
+    assert_menu_contains_item_named :project_menu, :repository
+    assert_menu_contains_item_named :project_menu, :settings
+  end
+
+  def test_new_issue_should_have_root_as_a_parent
+    new_issue = get_menu_item(:project_menu, :new_issue)
+    assert_equal :root, new_issue.parent.name
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/84/84aef8daed0663b1abb2c50b1715fa8c859e4a68.svn-base
--- a/.svn/pristine/84/84aef8daed0663b1abb2c50b1715fa8c859e4a68.svn-base
+++ /dev/null
@@ -1,512 +0,0 @@
-# redMine - project management software
-# Copyright (C) 2006-2007  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-desc 'Mantis migration script'
-
-require 'active_record'
-require 'iconv'
-require 'pp'
-
-namespace :redmine do
-task :migrate_from_mantis => :environment do
-  
-  module MantisMigrate
-   
-      DEFAULT_STATUS = IssueStatus.default
-      assigned_status = IssueStatus.find_by_position(2)
-      resolved_status = IssueStatus.find_by_position(3)
-      feedback_status = IssueStatus.find_by_position(4)
-      closed_status = IssueStatus.find :first, :conditions => { :is_closed => true }
-      STATUS_MAPPING = {10 => DEFAULT_STATUS,  # new
-                        20 => feedback_status, # feedback
-                        30 => DEFAULT_STATUS,  # acknowledged
-                        40 => DEFAULT_STATUS,  # confirmed
-                        50 => assigned_status, # assigned
-                        80 => resolved_status, # resolved
-                        90 => closed_status    # closed
-                        }
-                        
-      priorities = IssuePriority.all
-      DEFAULT_PRIORITY = priorities[2]
-      PRIORITY_MAPPING = {10 => priorities[1], # none
-                          20 => priorities[1], # low
-                          30 => priorities[2], # normal
-                          40 => priorities[3], # high
-                          50 => priorities[4], # urgent
-                          60 => priorities[5]  # immediate
-                          }
-    
-      TRACKER_BUG = Tracker.find_by_position(1)
-      TRACKER_FEATURE = Tracker.find_by_position(2)
-      
-      roles = Role.find(:all, :conditions => {:builtin => 0}, :order => 'position ASC')
-      manager_role = roles[0]
-      developer_role = roles[1]
-      DEFAULT_ROLE = roles.last
-      ROLE_MAPPING = {10 => DEFAULT_ROLE,   # viewer
-                      25 => DEFAULT_ROLE,   # reporter
-                      40 => DEFAULT_ROLE,   # updater
-                      55 => developer_role, # developer
-                      70 => manager_role,   # manager
-                      90 => manager_role    # administrator
-                      }
-      
-      CUSTOM_FIELD_TYPE_MAPPING = {0 => 'string', # String
-                                   1 => 'int',    # Numeric
-                                   2 => 'int',    # Float
-                                   3 => 'list',   # Enumeration
-                                   4 => 'string', # Email
-                                   5 => 'bool',   # Checkbox
-                                   6 => 'list',   # List
-                                   7 => 'list',   # Multiselection list
-                                   8 => 'date',   # Date
-                                   }
-                                   
-      RELATION_TYPE_MAPPING = {1 => IssueRelation::TYPE_RELATES,    # related to
-                               2 => IssueRelation::TYPE_RELATES,    # parent of
-                               3 => IssueRelation::TYPE_RELATES,    # child of
-                               0 => IssueRelation::TYPE_DUPLICATES, # duplicate of
-                               4 => IssueRelation::TYPE_DUPLICATES  # has duplicate
-                               }
-                                                                   
-    class MantisUser < ActiveRecord::Base
-      set_table_name :mantis_user_table
-      
-      def firstname
-        @firstname = realname.blank? ? username : realname.split.first[0..29]
-        @firstname
-      end
-      
-      def lastname
-        @lastname = realname.blank? ? '-' : realname.split[1..-1].join(' ')[0..29]
-        @lastname = '-' if @lastname.blank?
-        @lastname
-      end
-      
-      def email
-        if read_attribute(:email).match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i) &&
-             !User.find_by_mail(read_attribute(:email))
-          @email = read_attribute(:email)
-        else
-          @email = "#{username}@foo.bar"
-        end
-      end
-      
-      def username
-        read_attribute(:username)[0..29].gsub(/[^a-zA-Z0-9_\-@\.]/, '-')
-      end
-    end
-    
-    class MantisProject < ActiveRecord::Base
-      set_table_name :mantis_project_table
-      has_many :versions, :class_name => "MantisVersion", :foreign_key => :project_id
-      has_many :categories, :class_name => "MantisCategory", :foreign_key => :project_id
-      has_many :news, :class_name => "MantisNews", :foreign_key => :project_id
-      has_many :members, :class_name => "MantisProjectUser", :foreign_key => :project_id
-      
-      def identifier
-        read_attribute(:name).gsub(/[^a-z0-9\-]+/, '-').slice(0, Project::IDENTIFIER_MAX_LENGTH)
-      end
-    end
-    
-    class MantisVersion < ActiveRecord::Base
-      set_table_name :mantis_project_version_table
-      
-      def version
-        read_attribute(:version)[0..29]
-      end
-      
-      def description
-        read_attribute(:description)[0..254]
-      end
-    end
-    
-    class MantisCategory < ActiveRecord::Base
-      set_table_name :mantis_project_category_table
-    end
-    
-    class MantisProjectUser < ActiveRecord::Base
-      set_table_name :mantis_project_user_list_table
-    end
-    
-    class MantisBug < ActiveRecord::Base
-      set_table_name :mantis_bug_table
-      belongs_to :bug_text, :class_name => "MantisBugText", :foreign_key => :bug_text_id
-      has_many :bug_notes, :class_name => "MantisBugNote", :foreign_key => :bug_id
-      has_many :bug_files, :class_name => "MantisBugFile", :foreign_key => :bug_id
-      has_many :bug_monitors, :class_name => "MantisBugMonitor", :foreign_key => :bug_id
-    end
-    
-    class MantisBugText < ActiveRecord::Base
-      set_table_name :mantis_bug_text_table
-      
-      # Adds Mantis steps_to_reproduce and additional_information fields
-      # to description if any
-      def full_description
-        full_description = description
-        full_description += "\n\n*Steps to reproduce:*\n\n#{steps_to_reproduce}" unless steps_to_reproduce.blank?
-        full_description += "\n\n*Additional information:*\n\n#{additional_information}" unless additional_information.blank?
-        full_description
-      end
-    end
-    
-    class MantisBugNote < ActiveRecord::Base
-      set_table_name :mantis_bugnote_table
-      belongs_to :bug, :class_name => "MantisBug", :foreign_key => :bug_id
-      belongs_to :bug_note_text, :class_name => "MantisBugNoteText", :foreign_key => :bugnote_text_id
-    end
-    
-    class MantisBugNoteText < ActiveRecord::Base
-      set_table_name :mantis_bugnote_text_table
-    end
-    
-    class MantisBugFile < ActiveRecord::Base
-      set_table_name :mantis_bug_file_table
-      
-      def size
-        filesize
-      end
-      
-      def original_filename
-        MantisMigrate.encode(filename)
-      end
-      
-      def content_type
-        file_type
-      end
-      
-      def read(*args)
-      	if @read_finished
-      		nil
-      	else
-      		@read_finished = true
-      		content
-      	end
-      end
-    end
-    
-    class MantisBugRelationship < ActiveRecord::Base
-      set_table_name :mantis_bug_relationship_table
-    end
-    
-    class MantisBugMonitor < ActiveRecord::Base
-      set_table_name :mantis_bug_monitor_table
-    end
-    
-    class MantisNews < ActiveRecord::Base
-      set_table_name :mantis_news_table
-    end
-    
-    class MantisCustomField < ActiveRecord::Base
-      set_table_name :mantis_custom_field_table
-      set_inheritance_column :none  
-      has_many :values, :class_name => "MantisCustomFieldString", :foreign_key => :field_id
-      has_many :projects, :class_name => "MantisCustomFieldProject", :foreign_key => :field_id
-      
-      def format
-        read_attribute :type
-      end
-      
-      def name
-        read_attribute(:name)[0..29]
-      end
-    end
-    
-    class MantisCustomFieldProject < ActiveRecord::Base
-      set_table_name :mantis_custom_field_project_table  
-    end
-    
-    class MantisCustomFieldString < ActiveRecord::Base
-      set_table_name :mantis_custom_field_string_table  
-    end
-  
-  
-    def self.migrate
-          
-      # Users
-      print "Migrating users"
-      User.delete_all "login <> 'admin'"
-      users_map = {}
-      users_migrated = 0
-      MantisUser.find(:all).each do |user|
-    	u = User.new :firstname => encode(user.firstname), 
-    				 :lastname => encode(user.lastname),
-    				 :mail => user.email,
-    				 :last_login_on => user.last_visit
-    	u.login = user.username
-    	u.password = 'mantis'
-    	u.status = User::STATUS_LOCKED if user.enabled != 1
-    	u.admin = true if user.access_level == 90
-    	next unless u.save!
-    	users_migrated += 1
-    	users_map[user.id] = u.id
-    	print '.'
-      end
-      puts
-    
-      # Projects
-      print "Migrating projects"
-      Project.destroy_all
-      projects_map = {}
-      versions_map = {}
-      categories_map = {}
-      MantisProject.find(:all).each do |project|
-    	p = Project.new :name => encode(project.name), 
-                        :description => encode(project.description)
-    	p.identifier = project.identifier
-    	next unless p.save
-    	projects_map[project.id] = p.id
-    	p.enabled_module_names = ['issue_tracking', 'news', 'wiki']
-        p.trackers << TRACKER_BUG
-        p.trackers << TRACKER_FEATURE
-    	print '.'
-    	
-    	# Project members
-    	project.members.each do |member|
-          m = Member.new :user => User.find_by_id(users_map[member.user_id]),
-    	                   :roles => [ROLE_MAPPING[member.access_level] || DEFAULT_ROLE]
-    	  m.project = p
-    	  m.save
-    	end	
-    	
-    	# Project versions
-    	project.versions.each do |version|
-          v = Version.new :name => encode(version.version),
-                          :description => encode(version.description),
-                          :effective_date => (version.date_order ? version.date_order.to_date : nil)
-          v.project = p
-          v.save
-          versions_map[version.id] = v.id
-    	end
-    	
-    	# Project categories
-    	project.categories.each do |category|
-          g = IssueCategory.new :name => category.category[0,30]
-          g.project = p
-          g.save
-          categories_map[category.category] = g.id
-    	end
-      end	
-      puts	
-    
-      # Bugs
-      print "Migrating bugs"
-      Issue.destroy_all
-      issues_map = {}
-      keep_bug_ids = (Issue.count == 0)
-      MantisBug.find_each(:batch_size => 200) do |bug|
-        next unless projects_map[bug.project_id] && users_map[bug.reporter_id]
-    	i = Issue.new :project_id => projects_map[bug.project_id], 
-                      :subject => encode(bug.summary),
-                      :description => encode(bug.bug_text.full_description),
-                      :priority => PRIORITY_MAPPING[bug.priority] || DEFAULT_PRIORITY,
-                      :created_on => bug.date_submitted,
-                      :updated_on => bug.last_updated
-    	i.author = User.find_by_id(users_map[bug.reporter_id])
-    	i.category = IssueCategory.find_by_project_id_and_name(i.project_id, bug.category[0,30]) unless bug.category.blank?
-    	i.fixed_version = Version.find_by_project_id_and_name(i.project_id, bug.fixed_in_version) unless bug.fixed_in_version.blank?
-    	i.status = STATUS_MAPPING[bug.status] || DEFAULT_STATUS
-    	i.tracker = (bug.severity == 10 ? TRACKER_FEATURE : TRACKER_BUG)
-    	i.id = bug.id if keep_bug_ids
-    	next unless i.save
-    	issues_map[bug.id] = i.id
-    	print '.'
-      STDOUT.flush
-
-        # Assignee
-        # Redmine checks that the assignee is a project member
-        if (bug.handler_id && users_map[bug.handler_id])
-          i.assigned_to = User.find_by_id(users_map[bug.handler_id])
-          i.save_with_validation(false)
-        end        
-    	
-    	# Bug notes
-    	bug.bug_notes.each do |note|
-    	  next unless users_map[note.reporter_id]
-          n = Journal.new :notes => encode(note.bug_note_text.note),
-                          :created_on => note.date_submitted
-          n.user = User.find_by_id(users_map[note.reporter_id])
-          n.journalized = i
-          n.save
-    	end
-    	
-        # Bug files
-        bug.bug_files.each do |file|
-          a = Attachment.new :created_on => file.date_added
-          a.file = file
-          a.author = User.find :first
-          a.container = i
-          a.save
-        end
-        
-        # Bug monitors
-        bug.bug_monitors.each do |monitor|
-          next unless users_map[monitor.user_id]
-          i.add_watcher(User.find_by_id(users_map[monitor.user_id]))
-        end
-      end
-      
-      # update issue id sequence if needed (postgresql)
-      Issue.connection.reset_pk_sequence!(Issue.table_name) if Issue.connection.respond_to?('reset_pk_sequence!')
-      puts
-      
-      # Bug relationships
-      print "Migrating bug relations"
-      MantisBugRelationship.find(:all).each do |relation|
-        next unless issues_map[relation.source_bug_id] && issues_map[relation.destination_bug_id]
-        r = IssueRelation.new :relation_type => RELATION_TYPE_MAPPING[relation.relationship_type]
-        r.issue_from = Issue.find_by_id(issues_map[relation.source_bug_id])
-        r.issue_to = Issue.find_by_id(issues_map[relation.destination_bug_id])
-        pp r unless r.save
-        print '.'
-        STDOUT.flush
-      end
-      puts
-      
-      # News
-      print "Migrating news"
-      News.destroy_all
-      MantisNews.find(:all, :conditions => 'project_id > 0').each do |news|
-        next unless projects_map[news.project_id]
-        n = News.new :project_id => projects_map[news.project_id],
-                     :title => encode(news.headline[0..59]),
-                     :description => encode(news.body),
-                     :created_on => news.date_posted
-        n.author = User.find_by_id(users_map[news.poster_id])
-        n.save
-        print '.'
-        STDOUT.flush
-      end
-      puts
-      
-      # Custom fields
-      print "Migrating custom fields"
-      IssueCustomField.destroy_all
-      MantisCustomField.find(:all).each do |field|
-        f = IssueCustomField.new :name => field.name[0..29],
-                                 :field_format => CUSTOM_FIELD_TYPE_MAPPING[field.format],
-                                 :min_length => field.length_min,
-                                 :max_length => field.length_max,
-                                 :regexp => field.valid_regexp,
-                                 :possible_values => field.possible_values.split('|'),
-                                 :is_required => field.require_report?
-        next unless f.save
-        print '.'
-        STDOUT.flush
-        # Trackers association
-        f.trackers = Tracker.find :all
-        
-        # Projects association
-        field.projects.each do |project|
-          f.projects << Project.find_by_id(projects_map[project.project_id]) if projects_map[project.project_id]
-        end
-        
-        # Values
-        field.values.each do |value|
-          v = CustomValue.new :custom_field_id => f.id,
-                              :value => value.value
-          v.customized = Issue.find_by_id(issues_map[value.bug_id]) if issues_map[value.bug_id]
-          v.save
-        end unless f.new_record?
-      end
-      puts
-    
-      puts
-      puts "Users:           #{users_migrated}/#{MantisUser.count}"
-      puts "Projects:        #{Project.count}/#{MantisProject.count}"
-      puts "Memberships:     #{Member.count}/#{MantisProjectUser.count}"
-      puts "Versions:        #{Version.count}/#{MantisVersion.count}"
-      puts "Categories:      #{IssueCategory.count}/#{MantisCategory.count}"
-      puts "Bugs:            #{Issue.count}/#{MantisBug.count}"
-      puts "Bug notes:       #{Journal.count}/#{MantisBugNote.count}"
-      puts "Bug files:       #{Attachment.count}/#{MantisBugFile.count}"
-      puts "Bug relations:   #{IssueRelation.count}/#{MantisBugRelationship.count}"
-      puts "Bug monitors:    #{Watcher.count}/#{MantisBugMonitor.count}"
-      puts "News:            #{News.count}/#{MantisNews.count}"
-      puts "Custom fields:   #{IssueCustomField.count}/#{MantisCustomField.count}"
-    end
-  
-    def self.encoding(charset)
-      @ic = Iconv.new('UTF-8', charset)
-    rescue Iconv::InvalidEncoding
-      return false      
-    end
-    
-    def self.establish_connection(params)
-      constants.each do |const|
-        klass = const_get(const)
-        next unless klass.respond_to? 'establish_connection'
-        klass.establish_connection params
-      end
-    end
-    
-    def self.encode(text)
-      @ic.iconv text
-    rescue
-      text
-    end
-  end
-  
-  puts
-  if Redmine::DefaultData::Loader.no_data?
-    puts "Redmine configuration need to be loaded before importing data."
-    puts "Please, run this first:"
-    puts
-    puts "  rake redmine:load_default_data RAILS_ENV=\"#{ENV['RAILS_ENV']}\""
-    exit
-  end
-  
-  puts "WARNING: Your Redmine data will be deleted during this process."
-  print "Are you sure you want to continue ? [y/N] "
-  STDOUT.flush
-  break unless STDIN.gets.match(/^y$/i)
-  
-  # Default Mantis database settings
-  db_params = {:adapter => 'mysql', 
-               :database => 'bugtracker', 
-               :host => 'localhost', 
-               :username => 'root', 
-               :password => '' }
-
-  puts				
-  puts "Please enter settings for your Mantis database"  
-  [:adapter, :host, :database, :username, :password].each do |param|
-    print "#{param} [#{db_params[param]}]: "
-    value = STDIN.gets.chomp!
-    db_params[param] = value unless value.blank?
-  end
-    
-  while true
-    print "encoding [UTF-8]: "
-    STDOUT.flush
-    encoding = STDIN.gets.chomp!
-    encoding = 'UTF-8' if encoding.blank?
-    break if MantisMigrate.encoding encoding
-    puts "Invalid encoding!"
-  end
-  puts
-  
-  # Make sure bugs can refer bugs in other projects
-  Setting.cross_project_issue_relations = 1 if Setting.respond_to? 'cross_project_issue_relations'
-  
-  # Turn off email notifications
-  Setting.notified_events = []
-  
-  MantisMigrate.establish_connection db_params
-  MantisMigrate.migrate
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/84/84bb124f9c56a0e127eefcadf426b28c77093316.svn-base
--- a/.svn/pristine/84/84bb124f9c56a0e127eefcadf426b28c77093316.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%=l(:label_version_new)%></h2>
-
-<% labelled_tabular_form_for @version, :url => project_versions_path(@project) do |f| %>
-<%= render :partial => 'versions/form', :locals => { :f => f } %>
-<%= submit_tag l(:button_create) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/85/856339cef1bdf5f11b116c77c2ac5a76171899ce.svn-base
--- /dev/null
+++ b/.svn/pristine/85/856339cef1bdf5f11b116c77c2ac5a76171899ce.svn-base
@@ -0,0 +1,165 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoriesDarcsControllerTest < ActionController::TestCase
+  tests RepositoriesController
+
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :repositories, :enabled_modules
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
+  PRJ_ID = 3
+  NUM_REV = 6
+
+  def setup
+    User.current = nil
+    @project = Project.find(PRJ_ID)
+    @repository = Repository::Darcs.create(
+                        :project      => @project,
+                        :url          => REPOSITORY_PATH,
+                        :log_encoding => 'UTF-8'
+                        )
+    assert @repository
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    def test_get_new
+      @request.session[:user_id] = 1
+      @project.repository.destroy
+      get :new, :project_id => 'subproject1', :repository_scm => 'Darcs'
+      assert_response :success
+      assert_template 'new'
+      assert_kind_of Repository::Darcs, assigns(:repository)
+      assert assigns(:repository).new_record?
+    end
+
+    def test_browse_root
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal 3, assigns(:entries).size
+      assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
+    end
+
+    def test_browse_directory
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['images'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name)
+      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
+      assert_not_nil entry
+      assert_equal 'file', entry.kind
+      assert_equal 'images/edit.png', entry.path
+    end
+
+    def test_browse_at_given_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['images'])[:param],
+          :rev => 1
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['delete.png'], assigns(:entries).collect(&:name)
+    end
+
+    def test_changes
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :changes, :id => PRJ_ID,
+          :path => repository_path_hash(['images', 'edit.png'])[:param]
+      assert_response :success
+      assert_template 'changes'
+      assert_tag :tag => 'h2', :content => 'edit.png'
+    end
+
+    def test_diff
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      # Full diff of changeset 5
+      ['inline', 'sbs'].each do |dt|
+        get :diff, :id => PRJ_ID, :rev => 5, :type => dt
+        assert_response :success
+        assert_template 'diff'
+        # Line 22 removed
+        assert_tag :tag => 'th',
+                   :content => '22',
+                   :sibling => { :tag => 'td',
+                                 :attributes => { :class => /diff_out/ },
+                                 :content => /def remove/ }
+      end
+    end
+
+    def test_destroy_valid_repository
+      @request.session[:user_id] = 1 # admin
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+
+    def test_destroy_invalid_repository
+      @request.session[:user_id] = 1 # admin
+      @project.repository.destroy
+      @repository = Repository::Darcs.create!(
+                        :project      => @project,
+                        :url          => "/invalid",
+                        :log_encoding => 'UTF-8'
+                        )
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal 0, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+  else
+    puts "Darcs test repository NOT FOUND. Skipping functional tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/85/85848dd34249f60ad32d28944cb4a9546d489175.svn-base
--- a/.svn/pristine/85/85848dd34249f60ad32d28944cb4a9546d489175.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-require File.dirname(__FILE__) + '/string/conversions'
-require File.dirname(__FILE__) + '/string/inflections'
-
-class String #:nodoc:
-  include Redmine::CoreExtensions::String::Conversions
-  include Redmine::CoreExtensions::String::Inflections
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/85/85f72634b1fa7115c56cde5496c8d210d2e64d32.svn-base
--- /dev/null
+++ b/.svn/pristine/85/85f72634b1fa7115c56cde5496c8d210d2e64d32.svn-base
@@ -0,0 +1,36 @@
+api.user do
+  api.id         @user.id
+  api.login      @user.login if User.current.admin? || (User.current == @user)
+  api.firstname  @user.firstname
+  api.lastname   @user.lastname
+  api.mail       @user.mail if User.current.admin? || !@user.pref.hide_mail
+  api.created_on @user.created_on
+  api.last_login_on @user.last_login_on
+  api.api_key    @user.api_key if User.current.admin? || (User.current == @user)
+
+  render_api_custom_values @user.visible_custom_field_values, api
+
+  api.array :groups do |groups|
+    @user.groups.each do |group|
+      api.group :id => group.id, :name => group.name
+    end
+  end if User.current.admin? && include_in_api_response?('groups')
+
+  api.array :memberships do
+    @memberships.each do |membership|
+      api.membership do
+        api.id membership.id
+        api.project :id => membership.project.id, :name => membership.project.name
+        api.array :roles do
+          membership.member_roles.each do |member_role|
+            if member_role.role
+              attrs = {:id => member_role.role.id, :name => member_role.role.name}
+              attrs.merge!(:inherited => true) if member_role.inherited_from.present?
+              api.role attrs
+            end 
+          end
+        end
+      end if membership.project
+    end
+  end if include_in_api_response?('memberships') && @memberships
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/86/860e2f012a8a16391f9ed2054fc730df3d67d9c9.svn-base
--- /dev/null
+++ b/.svn/pristine/86/860e2f012a8a16391f9ed2054fc730df3d67d9c9.svn-base
@@ -0,0 +1,27 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module AdminHelper
+  def project_status_options_for_select(selected)
+    options_for_select([[l(:label_all), ''],
+                        [l(:project_status_active), '1'],
+                        [l(:project_status_closed), '5'],
+                        [l(:project_status_archived), '9']], selected.to_s)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/86/86143f66fe1f5d10a7a618e2496577aaa346c237.svn-base
--- /dev/null
+++ b/.svn/pristine/86/86143f66fe1f5d10a7a618e2496577aaa346c237.svn-base
@@ -0,0 +1,33 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingProjectEnumerationsTest < ActionController::IntegrationTest
+  def test_project_enumerations
+    assert_routing(
+        { :method => 'put', :path => "/projects/64/enumerations" },
+        { :controller => 'project_enumerations', :action => 'update',
+          :project_id => '64' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/projects/64/enumerations" },
+        { :controller => 'project_enumerations', :action => 'destroy',
+          :project_id => '64' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/86/8626420aabc42f1c5c5c9fca490181efb3ed2f66.svn-base
--- a/.svn/pristine/86/8626420aabc42f1c5c5c9fca490181efb3ed2f66.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-# Settings specified here will take precedence over those in config/environment.rb
-
-# The production environment is meant for finished, "live" apps.
-# Code is not reloaded between requests
-config.cache_classes = true
-
-#####
-# Customize the default logger (http://ruby-doc.org/core/classes/Logger.html)
-#
-# Use a different logger for distributed setups
-# config.logger        = SyslogLogger.new
-#
-# Rotate logs bigger than 1MB, keeps no more than 7 rotated logs around.
-# When setting a new Logger, make sure to set it's log level too.
-#
-# config.logger = Logger.new(config.log_path, 7, 1048576)
-# config.logger.level = Logger::INFO
-
-# Full error reports are disabled and caching is turned on
-config.action_controller.consider_all_requests_local = false
-config.action_controller.perform_caching             = true
-
-# Enable serving of images, stylesheets, and javascripts from an asset server
-# config.action_controller.asset_host                  = "http://assets.example.com"
-
-# Disable delivery errors if you bad email addresses should just be ignored
-config.action_mailer.raise_delivery_errors = false
-
-# No email in production log
-config.action_mailer.logger = nil
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/86/862a776ed4eda62592dadbb92180115063e923b2.svn-base
--- /dev/null
+++ b/.svn/pristine/86/862a776ed4eda62592dadbb92180115063e923b2.svn-base
@@ -0,0 +1,115 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::CodesetUtilTest < ActiveSupport::TestCase
+
+  def test_to_utf8_by_setting_from_latin1
+    with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
+      s1 = "Texte encod\xc3\xa9"
+      s2 = "Texte encod\xe9"
+      s3 = s2.dup
+      if s1.respond_to?(:force_encoding)
+        s1.force_encoding("UTF-8")
+        s2.force_encoding("ASCII-8BIT")
+        s3.force_encoding("UTF-8")
+      end
+      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2)
+      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3)
+    end
+  end
+
+  def test_to_utf8_by_setting_from_euc_jp
+    with_settings :repositories_encodings => 'UTF-8,EUC-JP' do
+      s1 = "\xe3\x83\xac\xe3\x83\x83\xe3\x83\x89\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\xb3"
+      s2 = "\xa5\xec\xa5\xc3\xa5\xc9\xa5\xde\xa5\xa4\xa5\xf3"
+      s3 = s2.dup
+      if s1.respond_to?(:force_encoding)
+        s1.force_encoding("UTF-8")
+        s2.force_encoding("ASCII-8BIT")
+        s3.force_encoding("UTF-8")
+      end
+      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2)
+      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3)
+    end
+  end
+
+  def test_to_utf8_by_setting_should_be_converted_all_latin1
+    with_settings :repositories_encodings => 'ISO-8859-1' do
+      s1 = "\xc3\x82\xc2\x80"
+      s2 = "\xC2\x80"
+      s3 = s2.dup
+      if s1.respond_to?(:force_encoding)
+        s1.force_encoding("UTF-8")
+        s2.force_encoding("ASCII-8BIT")
+        s3.force_encoding("UTF-8")
+      end
+      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2)
+      assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3)
+    end
+  end
+
+  def test_to_utf8_by_setting_blank_string
+    assert_equal "",  Redmine::CodesetUtil.to_utf8_by_setting("")
+    assert_equal nil, Redmine::CodesetUtil.to_utf8_by_setting(nil)
+  end
+
+  def test_to_utf8_by_setting_returns_ascii_as_utf8
+    s1 = "ASCII"
+    s2 = s1.dup
+    if s1.respond_to?(:force_encoding)
+      s1.force_encoding("UTF-8")
+      s2.force_encoding("ISO-8859-1")
+    end
+    str1 = Redmine::CodesetUtil.to_utf8_by_setting(s1)
+    str2 = Redmine::CodesetUtil.to_utf8_by_setting(s2)
+    assert_equal s1, str1
+    assert_equal s1, str2
+    if s1.respond_to?(:force_encoding)
+      assert_equal "UTF-8", str1.encoding.to_s
+      assert_equal "UTF-8", str2.encoding.to_s
+    end
+  end
+
+  def test_to_utf8_by_setting_invalid_utf8_sequences_should_be_stripped
+    with_settings :repositories_encodings => '' do
+      # s1 = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
+      s1 = "Texte encod\xe9 en ISO-8859-1."
+      s1.force_encoding("ASCII-8BIT") if s1.respond_to?(:force_encoding)
+      str = Redmine::CodesetUtil.to_utf8_by_setting(s1)
+      if str.respond_to?(:force_encoding)
+        assert str.valid_encoding?
+        assert_equal "UTF-8", str.encoding.to_s
+      end
+      assert_equal "Texte encod? en ISO-8859-1.", str
+    end
+  end
+
+  def test_to_utf8_by_setting_invalid_utf8_sequences_should_be_stripped_ja_jis
+    with_settings :repositories_encodings => 'ISO-2022-JP' do
+      s1 = "test\xb5\xfetest\xb5\xfe"
+      s1.force_encoding("ASCII-8BIT") if s1.respond_to?(:force_encoding)
+      str = Redmine::CodesetUtil.to_utf8_by_setting(s1)
+      if str.respond_to?(:force_encoding)
+        assert str.valid_encoding?
+        assert_equal "UTF-8", str.encoding.to_s
+      end
+      assert_equal "test??test??", str
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/86/863064fb5000e258cd2d7b4e4e73c65dd4fbbfc5.svn-base
--- a/.svn/pristine/86/863064fb5000e258cd2d7b4e4e73c65dd4fbbfc5.svn-base
+++ /dev/null
@@ -1,190 +0,0 @@
-# $Id: testldap.rb 65 2006-04-23 01:17:49Z blackhedd $
-#
-#
-
-
-$:.unshift "lib"
-
-require 'test/unit'
-
-require 'net/ldap'
-require 'stringio'
-
-
-class TestLdapClient < Test::Unit::TestCase
-
-  # TODO: these tests crash and burn if the associated
-  # LDAP testserver isn't up and running.
-  # We rely on being able to read a file with test data
-  # in LDIF format.
-  # TODO, WARNING: for the moment, this data is in a file
-  # whose name and location are HARDCODED into the
-  # instance method load_test_data.
-
-  def setup
-    @host = "127.0.0.1"
-    @port = 3890
-    @auth = {
-      :method => :simple,
-      :username => "cn=bigshot,dc=bayshorenetworks,dc=com",
-      :password => "opensesame"
-    }
-
-    @ldif = load_test_data
-  end
-
-
-
-  # Get some test data which will be used to validate
-  # the responses from the test LDAP server we will
-  # connect to.
-  # TODO, Bogus: we are HARDCODING the location of the file for now.
-  #
-  def load_test_data
-    ary = File.readlines( "tests/testdata.ldif" )
-    hash = {}
-    while line = ary.shift and line.chomp!
-      if line =~ /^dn:[\s]*/i
-        dn = $'
-        hash[dn] = {}
-        while attr = ary.shift and attr.chomp! and attr =~ /^([\w]+)[\s]*:[\s]*/
-          hash[dn][$1.downcase.intern] ||= []
-          hash[dn][$1.downcase.intern] << $'
-        end
-      end
-    end
-    hash
-  end
-
-
-
-  # Binding tests.
-  # Need tests for all kinds of network failures and incorrect auth.
-  # TODO: Implement a class-level timeout for operations like bind.
-  # Search has a timeout defined at the protocol level, other ops do not.
-  # TODO, use constants for the LDAP result codes, rather than hardcoding them.
-  def test_bind
-    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
-    assert_equal( true, ldap.bind )
-    assert_equal( 0, ldap.get_operation_result.code )
-    assert_equal( "Success", ldap.get_operation_result.message )
-
-    bad_username = @auth.merge( {:username => "cn=badguy,dc=imposters,dc=com"} )
-    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => bad_username
-    assert_equal( false, ldap.bind )
-    assert_equal( 48, ldap.get_operation_result.code )
-    assert_equal( "Inappropriate Authentication", ldap.get_operation_result.message )
-
-    bad_password = @auth.merge( {:password => "cornhusk"} )
-    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => bad_password
-    assert_equal( false, ldap.bind )
-    assert_equal( 49, ldap.get_operation_result.code )
-    assert_equal( "Invalid Credentials", ldap.get_operation_result.message )
-  end
-
-
-
-  def test_search
-    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
-
-    search = {:base => "dc=smalldomain,dc=com"}
-    assert_equal( false, ldap.search( search ))
-    assert_equal( 32, ldap.get_operation_result.code )
-    
-    search = {:base => "dc=bayshorenetworks,dc=com"}
-    assert_equal( true, ldap.search( search ))
-    assert_equal( 0, ldap.get_operation_result.code )
-    
-    ldap.search( search ) {|res|
-      assert_equal( res, @ldif )
-    }
-  end
-    
-
-
-
-  # This is a helper routine for test_search_attributes.
-  def internal_test_search_attributes attrs_to_search
-    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
-    assert( ldap.bind )
-
-    search = {
-      :base => "dc=bayshorenetworks,dc=com",
-      :attributes => attrs_to_search
-    }
-
-    ldif = @ldif
-    ldif.each {|dn,entry|
-      entry.delete_if {|attr,value|
-        ! attrs_to_search.include?(attr)
-      }
-    }
-  
-    assert_equal( true, ldap.search( search ))
-    ldap.search( search ) {|res|
-      res_keys = res.keys.sort
-      ldif_keys = ldif.keys.sort
-      assert( res_keys, ldif_keys )
-      res.keys.each {|rk|
-        assert( res[rk], ldif[rk] )
-      }
-    }
-  end
-
-
-  def test_search_attributes
-    internal_test_search_attributes [:mail]
-    internal_test_search_attributes [:cn]
-    internal_test_search_attributes [:ou]
-    internal_test_search_attributes [:hasaccessprivilege]
-    internal_test_search_attributes ["mail"]
-    internal_test_search_attributes ["cn"]
-    internal_test_search_attributes ["ou"]
-    internal_test_search_attributes ["hasaccessrole"]
-
-    internal_test_search_attributes [:mail, :cn, :ou, :hasaccessrole]
-    internal_test_search_attributes [:mail, "cn", :ou, "hasaccessrole"]
-  end
-
-
-  def test_search_filters
-    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
-    search = {
-      :base => "dc=bayshorenetworks,dc=com",
-      :filter => Net::LDAP::Filter.eq( "sn", "Fosse" )
-    }
-
-    ldap.search( search ) {|res|
-      p res
-    }
-  end
-
-
-
-  def test_open
-    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
-    ldap.open {|ldap|
-      10.times {
-        rc = ldap.search( :base => "dc=bayshorenetworks,dc=com" )
-        assert_equal( true, rc )
-      }
-    }
-  end
-
-
-  def test_ldap_open
-    Net::LDAP.open( :host => @host, :port => @port, :auth => @auth ) {|ldap|
-      10.times {
-        rc = ldap.search( :base => "dc=bayshorenetworks,dc=com" )
-        assert_equal( true, rc )
-      }
-    }
-  end
-
-
-
-
-
-end
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/86/86cf2abe4f8b8142381e7211a838d3b30b929a54.svn-base
--- a/.svn/pristine/86/86cf2abe4f8b8142381e7211a838d3b30b929a54.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("ì¼ìš”ì¼",
- "ì›”ìš”ì¼",
- "í™”ìš”ì¼",
- "ìˆ˜ìš”ì¼",
- "ëª©ìš”ì¼",
- "ê¸ˆìš”ì¼",
- "í† ìš”ì¼",
- "ì¼ìš”ì¼");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("ì¼",
- "ì›”",
- "í™”",
- "ìˆ˜",
- "ëª©",
- "ê¸ˆ",
- "í† ",
- "ì¼");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("1ì›”",
- "2ì›”",
- "3ì›”",
- "4ì›”",
- "5ì›”",
- "6ì›”",
- "7ì›”",
- "8ì›”",
- "9ì›”",
- "10ì›”",
- "11ì›”",
- "12ì›”");
-
-// short month names
-Calendar._SMN = new Array
-("1ì›”",
- "2ì›”",
- "3ì›”",
- "4ì›”",
- "5ì›”",
- "6ì›”",
- "7ì›”",
- "8ì›”",
- "9ì›”",
- "10ì›”",
- "11ì›”",
- "12ì›”");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "ì´ ë‹¬ë ¥ì€ ... & ë„ì›€ë§";
-
-Calendar._TT["ABOUT"] =
-"DHTML ë‚ ì§œ/ì‹œê°„ ì„ íƒê¸°\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"ìµœì‹  ë²„ì „ì„ êµ¬í•˜ë ¤ë©´ ì—¬ê¸°ë¡œ: http://www.dynarch.com/projects/calendar/\n" +
-"ë°°í¬ë¼ì´ì„¼ìŠ¤:GNU LGPL.  ì°¸ì¡°:http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"ë‚ ì§œ ì„ íƒ:\n" +
-"- í•´ë¥¼ ì„ íƒí•˜ë ¤ë©´ \xab, \xbb ë²„íŠ¼ì„ ì‚¬ìš©í•˜ì„¸ìš”.\n" +
-"- ë‹¬ì„ ì„ íƒí•˜ë ¤ë©´ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ë²„íŠ¼ì„ ì‚¬ìš©í•˜ì„¸ìš”.\n" +
-"- ì¢€ ë” ë¹ ë¥´ê²Œ ì„ íƒí•˜ë ¤ë©´ ìœ„ì˜ ë²„íŠ¼ì„ ê¾¹ ëˆŒëŸ¬ì£¼ì„¸ìš”.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"ì‹œê°„ ì„ íƒ:\n" +
-"- ì‹œ, ë¶„ì„ ë”í•˜ë ¤ë©´ í´ë¦­í•˜ì„¸ìš”.\n" +
-"- ì‹œ, ë¶„ì„ ë¹¼ë ¤ë©´  ì‰¬í”„íŠ¸ ëˆ„ë¥´ê³  í´ë¦­í•˜ì„¸ìš”.\n" +
-"- ì¢€ ë” ë¹ ë¥´ê²Œ ì„ íƒí•˜ë ¤ë©´ í´ë¦­í•˜ê³  ë“œëž˜ê·¸í•˜ì„¸ìš”.";
-
-Calendar._TT["PREV_YEAR"] = "ì´ì „ í•´";
-Calendar._TT["PREV_MONTH"] = "ì´ì „ ë‹¬";
-Calendar._TT["GO_TODAY"] = "ì˜¤ëŠ˜ë¡œ ì´ë™";
-Calendar._TT["NEXT_MONTH"] = "ë‹¤ìŒ ë‹¬";
-Calendar._TT["NEXT_YEAR"] = "ë‹¤ìŒ í•´";
-Calendar._TT["SEL_DATE"] = "ë‚ ì§œ ì„ íƒ";
-Calendar._TT["DRAG_TO_MOVE"] = "ì´ë™(ë“œëž˜ê·¸)";
-Calendar._TT["PART_TODAY"] = " (ì˜¤ëŠ˜)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "[%s]ì„ ì²˜ìŒìœ¼ë¡œ";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "ë‹«ê¸°";
-Calendar._TT["TODAY"] = "ì˜¤ëŠ˜";
-Calendar._TT["TIME_PART"] = "í´ë¦­(+),ì‰¬í”„íŠ¸+í´ë¦­(-),ë“œëž˜ê·¸";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "ì£¼";
-Calendar._TT["TIME"] = "ì‹œê°„:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/86/86d46b11f53bf924d634fb6a310d55c059a3a986.svn-base
--- a/.svn/pristine/86/86d46b11f53bf924d634fb6a310d55c059a3a986.svn-base
+++ /dev/null
@@ -1,42 +0,0 @@
-<div class="contextual">
-<%= link_to l(:label_issue_status_new), new_issue_status_path, :class => 'icon icon-add' %>
-<%= link_to(l(:label_update_issue_done_ratios), update_issue_done_ratio_issue_statuses_path, :class => 'icon icon-multiple', :method => 'post', :confirm => l(:text_are_you_sure)) if Issue.use_status_for_done_ratio? %>
-</div>
-
-<h2><%=l(:label_issue_status_plural)%></h2>
-
-<table class="list">
-  <thead><tr>
-  <th><%=l(:field_status)%></th>
-  <% if Issue.use_status_for_done_ratio? %>
-  <th><%=l(:field_done_ratio)%></th>
-  <% end %>
-  <th><%=l(:field_is_default)%></th>
-  <th><%=l(:field_is_closed)%></th>
-  <th><%=l(:button_sort)%></th>
-  <th></th>
-  </tr></thead>
-  <tbody>
-<% for status in @issue_statuses %>
-  <tr class="<%= cycle("odd", "even") %>">
-  <td><%= link_to h(status.name), edit_issue_status_path(status) %></td>
-  <% if Issue.use_status_for_done_ratio? %>
-  <td align="center"><%= h status.default_done_ratio %></td>
-  <% end %>
-  <td align="center"><%= checked_image status.is_default? %></td>
-  <td align="center"><%= checked_image status.is_closed? %></td>
-  <td align="center" style="width:15%;"><%= reorder_links('issue_status', {:action => 'update', :id => status}, :put) %></td>
-  <td class="buttons">
-    <%= link_to(l(:button_delete), issue_status_path(status),
-                                   :method => :delete,
-                                   :confirm => l(:text_are_you_sure),
-                                   :class => 'icon icon-del') %>
-  </td>
-  </tr>
-<% end %>
-  </tbody>
-</table>
-
-<p class="pagination"><%= pagination_links_full @issue_status_pages %></p>
-
-<% html_title(l(:label_issue_status_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/86/86f993136841831dd0360fe42ff275f20185c30f.svn-base
--- a/.svn/pristine/86/86f993136841831dd0360fe42ff275f20185c30f.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%=l(:label_issue_category)%></h2>
-
-<% labelled_tabular_form_for :issue_category, @category, :url => issue_category_path(@category), :html => {:method => :put} do |f| %>
-<%= render :partial => 'issue_categories/form', :locals => { :f => f } %>
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/87/8719788cc5feae1f6d13316748ca22d737c8a820.svn-base
--- a/.svn/pristine/87/8719788cc5feae1f6d13316748ca22d737c8a820.svn-base
+++ /dev/null
@@ -1,18 +0,0 @@
-<div class="attachments">
-<% for attachment in attachments %>
-<p><%= link_to_attachment attachment, :class => 'icon icon-attachment' -%>
-<%= h(" - #{attachment.description}") unless attachment.description.blank? %>
-  <span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
-  <% if options[:deletable] %>
-    <%= link_to image_tag('delete.png'), attachment_path(attachment),
-                                         :confirm => l(:text_are_you_sure),
-                                         :method => :delete,
-                                         :class => 'delete',
-                                         :title => l(:button_delete) %>
-  <% end %>
-  <% if options[:author] %>
-    <span class="author"><%= h(attachment.author) %>, <%= format_time(attachment.created_on) %></span>
-  <% end %>
-  </p>
-<% end %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/87/871ab69c9430fd870a684b73b2e5c6c68ed7f0f1.svn-base
--- /dev/null
+++ b/.svn/pristine/87/871ab69c9430fd870a684b73b2e5c6c68ed7f0f1.svn-base
@@ -0,0 +1,58 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module CalendarsHelper
+  def link_to_previous_month(year, month, options={})
+    target_year, target_month = if month == 1
+                                  [year - 1, 12]
+                                else
+                                  [year, month - 1]
+                                end
+
+    name = if target_month == 12
+             "#{month_name(target_month)} #{target_year}"
+           else
+             "#{month_name(target_month)}"
+           end
+
+    # \xc2\xab(utf-8) = &#171;
+    link_to_month(("\xc2\xab " + name), target_year, target_month, options)
+  end
+
+  def link_to_next_month(year, month, options={})
+    target_year, target_month = if month == 12
+                                  [year + 1, 1]
+                                else
+                                  [year, month + 1]
+                                end
+
+    name = if target_month == 1
+             "#{month_name(target_month)} #{target_year}"
+           else
+             "#{month_name(target_month)}"
+           end
+
+    # \xc2\xbb(utf-8) = &#187;
+    link_to_month((name + " \xc2\xbb"), target_year, target_month, options)
+  end
+
+  def link_to_month(link_name, year, month, options={})
+    link_to_content_update(h(link_name), params.merge(:year => year, :month => month))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/87/87b8296b76d4848fd3e88cf880e805a657f96574.svn-base
--- a/.svn/pristine/87/87b8296b76d4848fd3e88cf880e805a657f96574.svn-base
+++ /dev/null
@@ -1,48 +0,0 @@
-Return-Path: <JSmith@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
-Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
-In-Reply-To: <redmine.issue-2.20060719210421@osiris>
-From: "John Smith" <JSmith@somenet.foo>
-To: <redmine@somenet.foo>
-Subject: Re: update to issue 2
-Date: Sun, 22 Jun 2008 12:28:07 +0200
-MIME-Version: 1.0
-Content-Type: text/plain;
-	format=flowed;
-	charset="iso-8859-1";
-	reply-type=original
-Content-Transfer-Encoding: 7bit
-X-Priority: 3
-X-MSMail-Priority: Normal
-X-Mailer: Microsoft Outlook Express 6.00.2900.2869
-X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
-
-An update to the issue by the sender.
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet 
-turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus 
-blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti 
-sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In 
-in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras 
-sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum 
-id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus 
-eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique 
-sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et 
-malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
-platea dictumst.
-
->> > --- Reply above. Do not remove this line. ---
->> > 
->> > Issue #6779 has been updated by Eric Davis.
->> > 
->> > Subject changed from Projects with JSON to Project JSON API
->> > Status changed from New to Assigned
->> > Assignee set to Eric Davis
->> > Priority changed from Low to Normal
->> > Estimated time deleted (1.00)
->> > 
->> > Looks like the JSON api for projects was missed. I'm going to be
->> > reviewing the existing APIs and trying to clean them up over the next
->> > few weeks.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/87/87cf5e349a5bc29bdc53d5a9546c92b6fc428743.svn-base
--- a/.svn/pristine/87/87cf5e349a5bc29bdc53d5a9546c92b6fc428743.svn-base
+++ /dev/null
@@ -1,1031 +0,0 @@
-pt-BR:
-  # formatos de data e hora
-  direction: ltr
-  date:
-    formats:
-      default: "%d/%m/%Y"
-      short: "%d de %B"
-      long: "%d de %B de %Y"
-      only_day: "%d"
-
-    day_names: [Domingo, Segunda, TerÃ§a, Quarta, Quinta, Sexta, SÃ¡bado]
-    abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, SÃ¡b]
-    month_names: [~, Janeiro, Fevereiro, MarÃ§o, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro]
-    abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%A, %d de %B de %Y, %H:%M hs"
-      time: "%H:%M hs"
-      short: "%d/%m, %H:%M hs"
-      long: "%A, %d de %B de %Y, %H:%M hs"
-      only_second: "%S"
-      datetime:
-        formats:
-          default: "%Y-%m-%dT%H:%M:%S%Z"
-    am: ''
-    pm: ''
-
-  # date helper distancia em palavras
-  datetime:
-    distance_in_words:
-      half_a_minute: 'meio minuto'
-      less_than_x_seconds:
-        one: 'menos de 1 segundo'
-        other: 'menos de %{count} segundos'
-
-      x_seconds:
-        one: '1 segundo'
-        other: '%{count} segundos'
-
-      less_than_x_minutes:
-        one: 'menos de um minuto'
-        other: 'menos de %{count} minutos'
-
-      x_minutes:
-        one: '1 minuto'
-        other: '%{count} minutos'
-
-      about_x_hours:
-        one: 'aproximadamente 1 hora'
-        other: 'aproximadamente %{count} horas'
-
-      x_days:
-        one: '1 dia'
-        other: '%{count} dias'
-
-      about_x_months:
-        one: 'aproximadamente 1 mÃªs'
-        other: 'aproximadamente %{count} meses'
-
-      x_months:
-        one: '1 mÃªs'
-        other: '%{count} meses'
-
-      about_x_years:
-        one: 'aproximadamente 1 ano'
-        other: 'aproximadamente %{count} anos'
-
-      over_x_years:
-        one: 'mais de 1 ano'
-        other: 'mais de %{count} anos'
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  # numeros
-  number:
-    format:
-      precision: 3
-      separator: ','
-      delimiter: '.'
-    currency:
-      format:
-        unit: 'R$'
-        precision: 2
-        format: '%u %n'
-        separator: ','
-        delimiter: '.'
-    percentage:
-      format:
-        delimiter: '.'
-    precision:
-      format:
-        delimiter: '.'
-    human:
-      format:
-        precision: 1
-        delimiter: '.'
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-  support:
-    array:
-      sentence_connector: "e"
-      skip_last_comma: true
-
-  # Active Record
-  activerecord:
-    errors:
-      template:
-        header:
-          one: "model nÃ£o pode ser salvo: 1 erro"
-          other: "model nÃ£o pode ser salvo: %{count} erros."
-        body: "Por favor, verifique os seguintes campos:"
-      messages:
-        inclusion: "nÃ£o estÃ¡ incluso na lista"
-        exclusion: "nÃ£o estÃ¡ disponÃ­vel"
-        invalid: "nÃ£o Ã© vÃ¡lido"
-        confirmation: "nÃ£o estÃ¡ de acordo com a confirmaÃ§Ã£o"
-        accepted: "precisa ser aceito"
-        empty: "nÃ£o pode ficar vazio"
-        blank: "nÃ£o pode ficar vazio"
-        too_long: "Ã© muito longo (mÃ¡ximo: %{count} caracteres)"
-        too_short: "Ã© muito curto (mÃ­nimon: %{count} caracteres)"
-        wrong_length: "deve ter %{count} caracteres"
-        taken: "nÃ£o estÃ¡ disponÃ­vel"
-        not_a_number: "nÃ£o Ã© um nÃºmero"
-        greater_than: "precisa ser maior do que %{count}"
-        greater_than_or_equal_to: "precisa ser maior ou igual a %{count}"
-        equal_to: "precisa ser igual a %{count}"
-        less_than: "precisa ser menor do que %{count}"
-        less_than_or_equal_to: "precisa ser menor ou igual a %{count}"
-        odd: "precisa ser Ã­mpar"
-        even: "precisa ser par"
-        greater_than_start_date: "deve ser maior que a data inicial"
-        not_same_project: "nÃ£o pertence ao mesmo projeto"
-        circular_dependency: "Esta relaÃ§Ã£o geraria uma dependÃªncia circular"
-        cant_link_an_issue_with_a_descendant: "Uma tarefa nÃ£o pode ser relaciona a uma de suas subtarefas"
-
-  actionview_instancetag_blank_option: Selecione
-
-  general_text_No: 'NÃ£o'
-  general_text_Yes: 'Sim'
-  general_text_no: 'nÃ£o'
-  general_text_yes: 'sim'
-  general_lang_name: 'PortuguÃªs(Brasil)'
-  general_csv_separator: ';'
-  general_csv_decimal_separator: ','
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: Conta atualizada com sucesso.
-  notice_account_invalid_creditentials: UsuÃ¡rio ou senha invÃ¡lido.
-  notice_account_password_updated: Senha alterada com sucesso.
-  notice_account_wrong_password: Senha invÃ¡lida.
-  notice_account_register_done: Conta criada com sucesso. Para ativar sua conta, clique no link que lhe foi enviado por e-mail.
-  notice_account_unknown_email: UsuÃ¡rio desconhecido.
-  notice_can_t_change_password: Esta conta utiliza autenticaÃ§Ã£o externa. NÃ£o Ã© possÃ­vel alterar a senha.
-  notice_account_lost_email_sent: Um e-mail com instruÃ§Ãµes para escolher uma nova senha foi enviado para vocÃª.
-  notice_account_activated: Sua conta foi ativada. VocÃª pode acessÃ¡-la agora.
-  notice_successful_create: Criado com sucesso.
-  notice_successful_update: Alterado com sucesso.
-  notice_successful_delete: ExcluÃ­do com sucesso.
-  notice_successful_connection: Conectado com sucesso.
-  notice_file_not_found: A pÃ¡gina que vocÃª estÃ¡ tentando acessar nÃ£o existe ou foi excluÃ­da.
-  notice_locking_conflict: Os dados foram atualizados por outro usuÃ¡rio.
-  notice_not_authorized: VocÃª nÃ£o estÃ¡ autorizado a acessar esta pÃ¡gina.
-  notice_email_sent: "Um e-mail foi enviado para %{value}"
-  notice_email_error: "Ocorreu um erro ao enviar o e-mail (%{value})"
-  notice_feeds_access_key_reseted: Sua chave RSS foi reconfigurada.
-  notice_failed_to_save_issues: "Problema ao salvar %{count} tarefa(s) de %{total} selecionadas: %{ids}."
-  notice_no_issue_selected: "Nenhuma tarefa selecionada! Por favor, marque as tarefas que vocÃª deseja editar."
-  notice_account_pending: "Sua conta foi criada e estÃ¡ aguardando aprovaÃ§Ã£o do administrador."
-  notice_default_data_loaded: ConfiguraÃ§Ã£o padrÃ£o carregada com sucesso.
-
-  error_can_t_load_default_data: "A configuraÃ§Ã£o padrÃ£o nÃ£o pode ser carregada: %{value}"
-  error_scm_not_found: "A entrada e/ou a revisÃ£o nÃ£o existe no repositÃ³rio."
-  error_scm_command_failed: "Ocorreu um erro ao tentar acessar o repositÃ³rio: %{value}"
-  error_scm_annotate: "Esta entrada nÃ£o existe ou nÃ£o pode ser anotada."
-  error_issue_not_found_in_project: 'A tarefa nÃ£o foi encontrada ou nÃ£o pertence a este projeto'
-  error_no_tracker_in_project: 'NÃ£o hÃ¡ um tipo de tarefa associado a este projeto. Favor verificar as configuraÃ§Ãµes do projeto.'
-  error_no_default_issue_status: 'A situaÃ§Ã£o padrÃ£o para tarefa nÃ£o estÃ¡ definida. Favor verificar sua configuraÃ§Ã£o (VÃ¡ em "AdministraÃ§Ã£o -> SituaÃ§Ã£o da tarefa").'
-
-  mail_subject_lost_password: "Sua senha do %{value}."
-  mail_body_lost_password: 'Para mudar sua senha, clique no link abaixo:'
-  mail_subject_register: "AtivaÃ§Ã£o de conta do %{value}."
-  mail_body_register: 'Para ativar sua conta, clique no link abaixo:'
-  mail_body_account_information_external: "VocÃª pode usar sua conta do %{value} para entrar."
-  mail_body_account_information: InformaÃ§Ãµes sobre sua conta
-  mail_subject_account_activation_request: "%{value} - RequisiÃ§Ã£o de ativaÃ§Ã£o de conta"
-  mail_body_account_activation_request: "Um novo usuÃ¡rio (%{value}) se registrou. A conta estÃ¡ aguardando sua aprovaÃ§Ã£o:"
-  mail_subject_reminder: "%{count} tarefa(s) com data prevista para os prÃ³ximos %{days} dias"
-  mail_body_reminder: "%{count} tarefa(s) para vocÃª com data prevista para os prÃ³ximos %{days} dias:"
-
-  gui_validation_error: 1 erro
-  gui_validation_error_plural: "%{count} erros"
-
-  field_name: Nome
-  field_description: DescriÃ§Ã£o
-  field_summary: Resumo
-  field_is_required: ObrigatÃ³rio
-  field_firstname: Nome
-  field_lastname: Sobrenome
-  field_mail: E-mail
-  field_filename: Arquivo
-  field_filesize: Tamanho
-  field_downloads: Downloads
-  field_author: Autor
-  field_created_on: Criado em
-  field_updated_on: Alterado em
-  field_field_format: Formato
-  field_is_for_all: Para todos os projetos
-  field_possible_values: PossÃ­veis valores
-  field_regexp: ExpressÃ£o regular
-  field_min_length: Tamanho mÃ­nimo
-  field_max_length: Tamanho mÃ¡ximo
-  field_value: Valor
-  field_category: Categoria
-  field_title: TÃ­tulo
-  field_project: Projeto
-  field_issue: Tarefa
-  field_status: SituaÃ§Ã£o
-  field_notes: Notas
-  field_is_closed: Tarefa fechada
-  field_is_default: SituaÃ§Ã£o padrÃ£o
-  field_tracker: Tipo
-  field_subject: TÃ­tulo
-  field_due_date: Data prevista
-  field_assigned_to: AtribuÃ­do para
-  field_priority: Prioridade
-  field_fixed_version: VersÃ£o
-  field_user: UsuÃ¡rio
-  field_role: Cargo
-  field_homepage: PÃ¡gina do projeto
-  field_is_public: PÃºblico
-  field_parent: Sub-projeto de
-  field_is_in_roadmap: Exibir no planejamento
-  field_login: UsuÃ¡rio
-  field_mail_notification: NotificaÃ§Ãµes por e-mail
-  field_admin: Administrador
-  field_last_login_on: Ãšltima conexÃ£o
-  field_language: Idioma
-  field_effective_date: Data
-  field_password: Senha
-  field_new_password: Nova senha
-  field_password_confirmation: ConfirmaÃ§Ã£o
-  field_version: VersÃ£o
-  field_type: Tipo
-  field_host: Servidor
-  field_port: Porta
-  field_account: Conta
-  field_base_dn: DN Base
-  field_attr_login: Atributo para nome de usuÃ¡rio
-  field_attr_firstname: Atributo para nome
-  field_attr_lastname: Atributo para sobrenome
-  field_attr_mail: Atributo para e-mail
-  field_onthefly: Criar usuÃ¡rios dinamicamente ("on-the-fly")
-  field_start_date: InÃ­cio
-  field_done_ratio: "% Terminado"
-  field_auth_source: Modo de autenticaÃ§Ã£o
-  field_hide_mail: Ocultar meu e-mail
-  field_comments: ComentÃ¡rio
-  field_url: URL
-  field_start_page: PÃ¡gina inicial
-  field_subproject: Sub-projeto
-  field_hours: Horas
-  field_activity: Atividade
-  field_spent_on: Data
-  field_identifier: Identificador
-  field_is_filter: Ã‰ um filtro
-  field_issue_to: Tarefa relacionada
-  field_delay: Atraso
-  field_assignable: Tarefas podem ser atribuÃ­das a este papel
-  field_redirect_existing_links: Redirecionar links existentes
-  field_estimated_hours: Tempo estimado
-  field_column_names: Colunas
-  field_time_zone: Fuso-horÃ¡rio
-  field_searchable: PesquisÃ¡vel
-  field_default_value: PadrÃ£o
-  field_comments_sorting: Visualizar comentÃ¡rios
-  field_parent_title: PÃ¡gina pai
-
-  setting_app_title: TÃ­tulo da aplicaÃ§Ã£o
-  setting_app_subtitle: Sub-tÃ­tulo da aplicaÃ§Ã£o
-  setting_welcome_text: Texto de boas-vindas
-  setting_default_language: Idioma padrÃ£o
-  setting_login_required: Exigir autenticaÃ§Ã£o
-  setting_self_registration: Permitido Auto-registro
-  setting_attachment_max_size: Tamanho mÃ¡ximo do anexo
-  setting_issues_export_limit: Limite de exportaÃ§Ã£o das tarefas
-  setting_mail_from: E-mail enviado de
-  setting_bcc_recipients: Enviar com cÃ³pia oculta (cco)
-  setting_host_name: Nome do Servidor e subdomÃ­nio
-  setting_text_formatting: FormataÃ§Ã£o do texto
-  setting_wiki_compression: CompactaÃ§Ã£o de histÃ³rico do Wiki
-  setting_feeds_limit: NÃºmero de registros por Feed
-  setting_default_projects_public: Novos projetos sÃ£o pÃºblicos por padrÃ£o
-  setting_autofetch_changesets: Obter commits automaticamente
-  setting_sys_api_enabled: Ativa WS para gerenciamento do repositÃ³rio (SVN)
-  setting_commit_ref_keywords: Palavras de referÃªncia
-  setting_commit_fix_keywords: Palavras de fechamento
-  setting_autologin: Auto-login
-  setting_date_format: Formato da data
-  setting_time_format: Formato de hora
-  setting_cross_project_issue_relations: Permitir relacionar tarefas entre projetos
-  setting_issue_list_default_columns: Colunas padrÃ£o visÃ­veis na lista de tarefas
-  setting_emails_footer: RodapÃ© do e-mail
-  setting_protocol: Protocolo
-  setting_per_page_options: NÃºmero de itens exibidos por pÃ¡gina
-  setting_user_format: Formato de exibiÃ§Ã£o de nome de usuÃ¡rio
-  setting_activity_days_default: Dias visualizados na atividade do projeto
-  setting_display_subprojects_issues: Visualizar tarefas dos subprojetos nos projetos principais por padrÃ£o
-  setting_enabled_scm: SCM habilitados
-  setting_mail_handler_api_enabled: Habilitar WS para e-mails de entrada
-  setting_mail_handler_api_key: Chave de API
-  setting_sequential_project_identifiers: Gerar identificadores sequenciais de projeto
-
-  project_module_issue_tracking: Gerenciamento de Tarefas
-  project_module_time_tracking: Gerenciamento de tempo
-  project_module_news: NotÃ­cias
-  project_module_documents: Documentos
-  project_module_files: Arquivos
-  project_module_wiki: Wiki
-  project_module_repository: RepositÃ³rio
-  project_module_boards: FÃ³runs
-
-  label_user: UsuÃ¡rio
-  label_user_plural: UsuÃ¡rios
-  label_user_new: Novo usuÃ¡rio
-  label_project: Projeto
-  label_project_new: Novo projeto
-  label_project_plural: Projetos
-  label_x_projects:
-    zero:  nenhum projeto
-    one:   1 projeto
-    other: "%{count} projetos"
-  label_project_all: Todos os projetos
-  label_project_latest: Ãšltimos projetos
-  label_issue: Tarefa
-  label_issue_new: Nova tarefa
-  label_issue_plural: Tarefas
-  label_issue_view_all: Ver todas as tarefas
-  label_issues_by: "Tarefas por %{value}"
-  label_issue_added: Tarefa adicionada
-  label_issue_updated: Tarefa atualizada
-  label_issue_note_added: Nota adicionada
-  label_issue_status_updated: SituaÃ§Ã£o atualizada
-  label_issue_priority_updated: Prioridade atualizada
-  label_document: Documento
-  label_document_new: Novo documento
-  label_document_plural: Documentos
-  label_document_added: Documento adicionado
-  label_role: Papel
-  label_role_plural: PapÃ©is
-  label_role_new: Novo papel
-  label_role_and_permissions: PapÃ©is e permissÃµes
-  label_member: Membro
-  label_member_new: Novo membro
-  label_member_plural: Membros
-  label_tracker: Tipo de tarefa
-  label_tracker_plural: Tipos de tarefas
-  label_tracker_new: Novo tipo
-  label_workflow: Fluxo de trabalho
-  label_issue_status: SituaÃ§Ã£o da tarefa
-  label_issue_status_plural: SituaÃ§Ã£o das tarefas
-  label_issue_status_new: Nova situaÃ§Ã£o
-  label_issue_category: Categoria da tarefa
-  label_issue_category_plural: Categorias das tarefas
-  label_issue_category_new: Nova categoria
-  label_custom_field: Campo personalizado
-  label_custom_field_plural: Campos personalizados
-  label_custom_field_new: Novo campo personalizado
-  label_enumerations: 'Tipos & Categorias'
-  label_enumeration_new: Novo
-  label_information: InformaÃ§Ã£o
-  label_information_plural: InformaÃ§Ãµes
-  label_please_login: Efetue o login
-  label_register: Cadastre-se
-  label_password_lost: Perdi minha senha
-  label_home: PÃ¡gina inicial
-  label_my_page: Minha pÃ¡gina
-  label_my_account: Minha conta
-  label_my_projects: Meus projetos
-  label_administration: AdministraÃ§Ã£o
-  label_login: Entrar
-  label_logout: Sair
-  label_help: Ajuda
-  label_reported_issues: Tarefas reportadas
-  label_assigned_to_me_issues: Minhas tarefas
-  label_last_login: Ãšltima conexÃ£o
-  label_registered_on: Registrado em
-  label_activity: Atividade
-  label_overall_activity: Atividades gerais
-  label_new: Novo
-  label_logged_as: "Acessando como:"
-  label_environment: Ambiente
-  label_authentication: AutenticaÃ§Ã£o
-  label_auth_source: Modo de autenticaÃ§Ã£o
-  label_auth_source_new: Novo modo de autenticaÃ§Ã£o
-  label_auth_source_plural: Modos de autenticaÃ§Ã£o
-  label_subproject_plural: Sub-projetos
-  label_and_its_subprojects: "%{value} e seus sub-projetos"
-  label_min_max_length: Tamanho mÃ­n-mÃ¡x
-  label_list: Lista
-  label_date: Data
-  label_integer: Inteiro
-  label_float: Decimal
-  label_boolean: Boleano
-  label_string: Texto
-  label_text: Texto longo
-  label_attribute: Atributo
-  label_attribute_plural: Atributos
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
-  label_no_data: Nenhuma informaÃ§Ã£o disponÃ­vel
-  label_change_status: Alterar situaÃ§Ã£o
-  label_history: HistÃ³rico
-  label_attachment: Arquivo
-  label_attachment_new: Novo arquivo
-  label_attachment_delete: Excluir arquivo
-  label_attachment_plural: Arquivos
-  label_file_added: Arquivo adicionado
-  label_report: RelatÃ³rio
-  label_report_plural: RelatÃ³rio
-  label_news: NotÃ­cia
-  label_news_new: Adicionar notÃ­cia
-  label_news_plural: NotÃ­cias
-  label_news_latest: Ãšltimas notÃ­cias
-  label_news_view_all: Ver todas as notÃ­cias
-  label_news_added: NotÃ­cia adicionada
-  label_settings: ConfiguraÃ§Ãµes
-  label_overview: VisÃ£o geral
-  label_version: VersÃ£o
-  label_version_new: Nova versÃ£o
-  label_version_plural: VersÃµes
-  label_confirmation: ConfirmaÃ§Ã£o
-  label_export_to: Exportar para
-  label_read: Ler...
-  label_public_projects: Projetos pÃºblicos
-  label_open_issues: Aberta
-  label_open_issues_plural: Abertas
-  label_closed_issues: Fechada
-  label_closed_issues_plural: Fechadas
-  label_x_open_issues_abbr_on_total:
-    zero:  0 aberta / %{total}
-    one:   1 aberta / %{total}
-    other: "%{count} abertas / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 aberta
-    one:   1 aberta
-    other: "%{count} abertas"
-  label_x_closed_issues_abbr:
-    zero:  0 fechada
-    one:   1 fechada
-    other: "%{count} fechadas"
-  label_total: Total
-  label_permissions: PermissÃµes
-  label_current_status: SituaÃ§Ã£o atual
-  label_new_statuses_allowed: Nova situaÃ§Ã£o permitida
-  label_all: todos
-  label_none: nenhum
-  label_nobody: ninguÃ©m
-  label_next: PrÃ³ximo
-  label_previous: Anterior
-  label_used_by: Usado por
-  label_details: Detalhes
-  label_add_note: Adicionar nota
-  label_per_page: Por pÃ¡gina
-  label_calendar: CalendÃ¡rio
-  label_months_from: meses a partir de
-  label_gantt: Gantt
-  label_internal: Interno
-  label_last_changes: "Ãºltimas %{count} alteraÃ§Ãµes"
-  label_change_view_all: Mostrar todas as alteraÃ§Ãµes
-  label_personalize_page: Personalizar esta pÃ¡gina
-  label_comment: ComentÃ¡rio
-  label_comment_plural: ComentÃ¡rios
-  label_x_comments:
-    zero: nenhum comentÃ¡rio
-    one: 1 comentÃ¡rio
-    other: "%{count} comentÃ¡rios"
-  label_comment_add: Adicionar comentÃ¡rio
-  label_comment_added: ComentÃ¡rio adicionado
-  label_comment_delete: Excluir comentÃ¡rio
-  label_query: Consulta personalizada
-  label_query_plural: Consultas personalizadas
-  label_query_new: Nova consulta
-  label_filter_add: Adicionar filtro
-  label_filter_plural: Filtros
-  label_equals: igual a
-  label_not_equals: diferente de
-  label_in_less_than: maior que
-  label_in_more_than: menor que
-  label_in: em
-  label_today: hoje
-  label_all_time: tudo
-  label_yesterday: ontem
-  label_this_week: esta semana
-  label_last_week: Ãºltima semana
-  label_last_n_days: "Ãºltimos %{count} dias"
-  label_this_month: este mÃªs
-  label_last_month: Ãºltimo mÃªs
-  label_this_year: este ano
-  label_date_range: PerÃ­odo
-  label_less_than_ago: menos de
-  label_more_than_ago: mais de
-  label_ago: dias atrÃ¡s
-  label_contains: contÃ©m
-  label_not_contains: nÃ£o contÃ©m
-  label_day_plural: dias
-  label_repository: RepositÃ³rio
-  label_repository_plural: RepositÃ³rios
-  label_browse: Procurar
-  label_modification: "%{count} alteraÃ§Ã£o"
-  label_modification_plural: "%{count} alteraÃ§Ãµes"
-  label_revision: RevisÃ£o
-  label_revision_plural: RevisÃµes
-  label_associated_revisions: RevisÃµes associadas
-  label_added: adicionada
-  label_modified: alterada
-  label_deleted: excluÃ­da
-  label_latest_revision: Ãšltima revisÃ£o
-  label_latest_revision_plural: Ãšltimas revisÃµes
-  label_view_revisions: Ver revisÃµes
-  label_max_size: Tamanho mÃ¡ximo
-  label_sort_highest: Mover para o inÃ­cio
-  label_sort_higher: Mover para cima
-  label_sort_lower: Mover para baixo
-  label_sort_lowest: Mover para o fim
-  label_roadmap: Planejamento
-  label_roadmap_due_in: "Previsto para %{value}"
-  label_roadmap_overdue: "%{value} atrasado"
-  label_roadmap_no_issues: Sem tarefas para esta versÃ£o
-  label_search: Busca
-  label_result_plural: Resultados
-  label_all_words: Todas as palavras
-  label_wiki: Wiki
-  label_wiki_edit: Editar Wiki
-  label_wiki_edit_plural: EdiÃ§Ãµes Wiki
-  label_wiki_page: PÃ¡gina Wiki
-  label_wiki_page_plural: pÃ¡ginas Wiki
-  label_index_by_title: Ãndice por tÃ­tulo
-  label_index_by_date: Ãndice por data
-  label_current_version: VersÃ£o atual
-  label_preview: PrÃ©-visualizar
-  label_feed_plural: Feeds
-  label_changes_details: Detalhes de todas as alteraÃ§Ãµes
-  label_issue_tracking: Tarefas
-  label_spent_time: Tempo gasto
-  label_f_hour: "%{value} hora"
-  label_f_hour_plural: "%{value} horas"
-  label_time_tracking: Registro de horas
-  label_change_plural: AlteraÃ§Ãµes
-  label_statistics: EstatÃ­sticas
-  label_commits_per_month: Commits por mÃªs
-  label_commits_per_author: Commits por autor
-  label_view_diff: Ver diferenÃ§as
-  label_diff_inline: inline
-  label_diff_side_by_side: lado a lado
-  label_options: OpÃ§Ãµes
-  label_copy_workflow_from: Copiar fluxo de trabalho de
-  label_permissions_report: RelatÃ³rio de permissÃµes
-  label_watched_issues: Tarefas observadas
-  label_related_issues: Tarefas relacionadas
-  label_applied_status: SituaÃ§Ã£o alterada
-  label_loading: Carregando...
-  label_relation_new: Nova relaÃ§Ã£o
-  label_relation_delete: Excluir relaÃ§Ã£o
-  label_relates_to: relacionado a
-  label_duplicates: duplica
-  label_duplicated_by: duplicado por
-  label_blocks: bloqueia
-  label_blocked_by: bloqueado por
-  label_precedes: precede
-  label_follows: segue
-  label_end_to_start: fim para o inÃ­cio
-  label_end_to_end: fim para fim
-  label_start_to_start: inÃ­cio para inÃ­cio
-  label_start_to_end: inÃ­cio para fim
-  label_stay_logged_in: Permanecer logado
-  label_disabled: desabilitado
-  label_show_completed_versions: Exibir versÃµes completas
-  label_me: mim
-  label_board: FÃ³rum
-  label_board_new: Novo fÃ³rum
-  label_board_plural: FÃ³runs
-  label_topic_plural: TÃ³picos
-  label_message_plural: Mensagens
-  label_message_last: Ãšltima mensagem
-  label_message_new: Nova mensagem
-  label_message_posted: Mensagem enviada
-  label_reply_plural: Respostas
-  label_send_information: Enviar informaÃ§Ã£o da nova conta para o usuÃ¡rio
-  label_year: Ano
-  label_month: MÃªs
-  label_week: Semana
-  label_date_from: De
-  label_date_to: Para
-  label_language_based: Com base no idioma do usuÃ¡rio
-  label_sort_by: "Ordenar por %{value}"
-  label_send_test_email: Enviar um e-mail de teste
-  label_feeds_access_key_created_on: "chave de acesso RSS criada %{value} atrÃ¡s"
-  label_module_plural: MÃ³dulos
-  label_added_time_by: "Adicionado por %{author} %{age} atrÃ¡s"
-  label_updated_time: "Atualizado %{value} atrÃ¡s"
-  label_jump_to_a_project: Ir para o projeto...
-  label_file_plural: Arquivos
-  label_changeset_plural: Changesets
-  label_default_columns: Colunas padrÃ£o
-  label_no_change_option: (Sem alteraÃ§Ã£o)
-  label_bulk_edit_selected_issues: EdiÃ§Ã£o em massa das tarefas selecionados.
-  label_theme: Tema
-  label_default: PadrÃ£o
-  label_search_titles_only: Pesquisar somente tÃ­tulos
-  label_user_mail_option_all: "Para qualquer evento em todos os meus projetos"
-  label_user_mail_option_selected: "Para qualquer evento somente no(s) projeto(s) selecionado(s)..."
-  label_user_mail_no_self_notified: "Eu nÃ£o quero ser notificado de minhas prÃ³prias modificaÃ§Ãµes"
-  label_registration_activation_by_email: ativaÃ§Ã£o de conta por e-mail
-  label_registration_manual_activation: ativaÃ§Ã£o manual de conta
-  label_registration_automatic_activation: ativaÃ§Ã£o automÃ¡tica de conta
-  label_display_per_page: "Por pÃ¡gina: %{value}"
-  label_age: Idade
-  label_change_properties: Alterar propriedades
-  label_general: Geral
-  label_more: Mais
-  label_scm: 'Controle de versÃ£o:'
-  label_plugins: Plugins
-  label_ldap_authentication: AutenticaÃ§Ã£o LDAP
-  label_downloads_abbr: D/L
-  label_optional_description: DescriÃ§Ã£o opcional
-  label_add_another_file: Adicionar outro arquivo
-  label_preferences: PreferÃªncias
-  label_chronological_order: Em ordem cronolÃ³gica
-  label_reverse_chronological_order: Em ordem cronolÃ³gica inversa
-  label_planning: Planejamento
-  label_incoming_emails: E-mails recebidos
-  label_generate_key: Gerar uma chave
-  label_issue_watchers: Observadores
-
-  button_login: Entrar
-  button_submit: Enviar
-  button_save: Salvar
-  button_check_all: Marcar todos
-  button_uncheck_all: Desmarcar todos
-  button_delete: Excluir
-  button_create: Criar
-  button_test: Testar
-  button_edit: Editar
-  button_add: Adicionar
-  button_change: Alterar
-  button_apply: Aplicar
-  button_clear: Limpar
-  button_lock: Bloquear
-  button_unlock: Desbloquear
-  button_download: Baixar
-  button_list: Listar
-  button_view: Ver
-  button_move: Mover
-  button_back: Voltar
-  button_cancel: Cancelar
-  button_activate: Ativar
-  button_sort: Ordenar
-  button_log_time: Tempo de trabalho
-  button_rollback: Voltar para esta versÃ£o
-  button_watch: Observar
-  button_unwatch: Parar de observar
-  button_reply: Responder
-  button_archive: Arquivar
-  button_unarchive: Desarquivar
-  button_reset: Redefinir
-  button_rename: Renomear
-  button_change_password: Alterar senha
-  button_copy: Copiar
-  button_annotate: Anotar
-  button_update: Atualizar
-  button_configure: Configurar
-  button_quote: Responder
-
-  status_active: ativo
-  status_registered: registrado
-  status_locked: bloqueado
-
-  text_select_mail_notifications: AÃ§Ãµes a serem notificadas por e-mail
-  text_regexp_info: ex. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 = sem restriÃ§Ã£o
-  text_project_destroy_confirmation: VocÃª tem certeza que deseja excluir este projeto e todos os dados relacionados?
-  text_subprojects_destroy_warning: "Seu(s) subprojeto(s): %{value} tambÃ©m serÃ£o excluÃ­dos."
-  text_workflow_edit: Selecione um papel e um tipo de tarefa para editar o fluxo de trabalho
-  text_are_you_sure: VocÃª tem certeza?
-  text_tip_issue_begin_day: tarefa inicia neste dia
-  text_tip_issue_end_day: tarefa termina neste dia
-  text_tip_issue_begin_end_day: tarefa inicia e termina neste dia
-  text_project_identifier_info: 'Letras minÃºsculas (a-z), nÃºmeros e hÃ­fens permitidos.<br />Uma vez salvo, o identificador nÃ£o poderÃ¡ ser alterado.'
-  text_caracters_maximum: "mÃ¡ximo %{count} caracteres"
-  text_caracters_minimum: "deve ter ao menos %{count} caracteres."
-  text_length_between: "deve ter entre %{min} e %{max} caracteres."
-  text_tracker_no_workflow: Sem fluxo de trabalho definido para este tipo.
-  text_unallowed_characters: Caracteres nÃ£o permitidos
-  text_comma_separated: MÃºltiplos valores sÃ£o permitidos (separados por vÃ­rgula).
-  text_issues_ref_in_commit_messages: Referenciando tarefas nas mensagens de commit
-  text_issue_added: "Tarefa %{id} incluÃ­da (por %{author})."
-  text_issue_updated: "Tarefa %{id} alterada (por %{author})."
-  text_wiki_destroy_confirmation: VocÃª tem certeza que deseja excluir este wiki e TODO o seu conteÃºdo?
-  text_issue_category_destroy_question: "Algumas tarefas (%{count}) estÃ£o atribuÃ­das a esta categoria. O que vocÃª deseja fazer?"
-  text_issue_category_destroy_assignments: Remover atribuiÃ§Ãµes da categoria
-  text_issue_category_reassign_to: Redefinir tarefas para esta categoria
-  text_user_mail_option: "Para projetos (nÃ£o selecionados), vocÃª somente receberÃ¡ notificaÃ§Ãµes sobre o que vocÃª estÃ¡ observando ou estÃ¡ envolvido (ex. tarefas das quais vocÃª Ã© o autor ou que estÃ£o atribuÃ­das a vocÃª)"
-  text_no_configuration_data: "Os PapÃ©is, tipos de tarefas, situaÃ§Ã£o de tarefas e fluxos de trabalho nÃ£o foram configurados ainda.\nÃ‰ altamente recomendado carregar as configuraÃ§Ãµes padrÃ£o. VocÃª poderÃ¡ modificar estas configuraÃ§Ãµes assim que carregadas."
-  text_load_default_configuration: Carregar a configuraÃ§Ã£o padrÃ£o
-  text_status_changed_by_changeset: "Aplicado no changeset %{value}."
-  text_issues_destroy_confirmation: 'VocÃª tem certeza que deseja excluir a(s) tarefa(s) selecionada(s)?'
-  text_select_project_modules: 'Selecione mÃ³dulos para habilitar para este projeto:'
-  text_default_administrator_account_changed: Conta padrÃ£o do administrador alterada
-  text_file_repository_writable: RepositÃ³rio com permissÃ£o de escrita
-  text_rmagick_available: RMagick disponÃ­vel (opcional)
-  text_destroy_time_entries_question: "%{hours} horas de trabalho foram registradas nas tarefas que vocÃª estÃ¡ excluindo. O que vocÃª deseja fazer?"
-  text_destroy_time_entries: Excluir horas de trabalho
-  text_assign_time_entries_to_project: Atribuir estas horas de trabalho para outro projeto
-  text_reassign_time_entries: 'Atribuir horas reportadas para esta tarefa:'
-  text_user_wrote: "%{value} escreveu:"
-  text_enumeration_destroy_question: "%{count} objetos estÃ£o atribuÃ­dos a este valor."
-  text_enumeration_category_reassign_to: 'ReatribuÃ­-los ao valor:'
-  text_email_delivery_not_configured: "O envio de e-mail nÃ£o estÃ¡ configurado, e as notificaÃ§Ãµes estÃ£o inativas.\nConfigure seu servidor SMTP no arquivo config/configuration.yml e reinicie a aplicaÃ§Ã£o para ativÃ¡-las."
-
-  default_role_manager: Gerente
-  default_role_developer: Desenvolvedor
-  default_role_reporter: Informante
-  default_tracker_bug: Defeito
-  default_tracker_feature: Funcionalidade
-  default_tracker_support: Suporte
-  default_issue_status_new: Nova
-  default_issue_status_in_progress: Em andamento
-  default_issue_status_resolved: Resolvida
-  default_issue_status_feedback: Feedback
-  default_issue_status_closed: Fechada
-  default_issue_status_rejected: Rejeitada
-  default_doc_category_user: DocumentaÃ§Ã£o do usuÃ¡rio
-  default_doc_category_tech: DocumentaÃ§Ã£o tÃ©cnica
-  default_priority_low: Baixa
-  default_priority_normal: Normal
-  default_priority_high: Alta
-  default_priority_urgent: Urgente
-  default_priority_immediate: Imediata
-  default_activity_design: Design
-  default_activity_development: Desenvolvimento
-
-  enumeration_issue_priorities: Prioridade das tarefas
-  enumeration_doc_categories: Categorias de documento
-  enumeration_activities: Atividades (registro de horas)
-  notice_unable_delete_version: NÃ£o foi possÃ­vel excluir a versÃ£o
-  label_renamed: renomeado
-  label_copied: copiado
-  setting_plain_text_mail: Usar mensagem sem formataÃ§Ã£o HTML
-  permission_view_files: Ver arquivos
-  permission_edit_issues: Editar tarefas
-  permission_edit_own_time_entries: Editar o prÃ³prio tempo de trabalho
-  permission_manage_public_queries: Gerenciar consultas publicas
-  permission_add_issues: Adicionar tarefas
-  permission_log_time: Adicionar tempo gasto
-  permission_view_changesets: Ver changesets
-  permission_view_time_entries: Ver tempo gasto
-  permission_manage_versions: Gerenciar versÃµes
-  permission_manage_wiki: Gerenciar wiki
-  permission_manage_categories: Gerenciar categorias de tarefas
-  permission_protect_wiki_pages: Proteger pÃ¡ginas wiki
-  permission_comment_news: Comentar notÃ­cias
-  permission_delete_messages: Excluir mensagens
-  permission_select_project_modules: Selecionar mÃ³dulos de projeto
-  permission_manage_documents: Gerenciar documentos
-  permission_edit_wiki_pages: Editar pÃ¡ginas wiki
-  permission_add_issue_watchers: Adicionar observadores
-  permission_view_gantt: Ver grÃ¡fico gantt
-  permission_move_issues: Mover tarefas
-  permission_manage_issue_relations: Gerenciar relacionamentos de tarefas
-  permission_delete_wiki_pages: Excluir pÃ¡ginas wiki
-  permission_manage_boards: Gerenciar fÃ³runs
-  permission_delete_wiki_pages_attachments: Excluir anexos
-  permission_view_wiki_edits: Ver histÃ³rico do wiki
-  permission_add_messages: Postar mensagens
-  permission_view_messages: Ver mensagens
-  permission_manage_files: Gerenciar arquivos
-  permission_edit_issue_notes: Editar notas
-  permission_manage_news: Gerenciar notÃ­cias
-  permission_view_calendar: Ver calendÃ¡rio
-  permission_manage_members: Gerenciar membros
-  permission_edit_messages: Editar mensagens
-  permission_delete_issues: Excluir tarefas
-  permission_view_issue_watchers: Ver lista de observadores
-  permission_manage_repository: Gerenciar repositÃ³rio
-  permission_commit_access: Acesso de commit
-  permission_browse_repository: Pesquisar repositÃ³rio
-  permission_view_documents: Ver documentos
-  permission_edit_project: Editar projeto
-  permission_add_issue_notes: Adicionar notas
-  permission_save_queries: Salvar consultas
-  permission_view_wiki_pages: Ver wiki
-  permission_rename_wiki_pages: Renomear pÃ¡ginas wiki
-  permission_edit_time_entries: Editar tempo gasto
-  permission_edit_own_issue_notes: Editar suas prÃ³prias notas
-  setting_gravatar_enabled: Usar Ã­cones do Gravatar
-  label_example: Exemplo
-  text_repository_usernames_mapping: "Seleciona ou atualiza os usuÃ¡rios do Redmine mapeando para cada usuÃ¡rio encontrado no log do repositÃ³rio.\nUsuÃ¡rios com o mesmo login ou e-mail no Redmine e no repositÃ³rio serÃ£o mapeados automaticamente."
-  permission_edit_own_messages: Editar prÃ³prias mensagens
-  permission_delete_own_messages: Excluir prÃ³prias mensagens
-  label_user_activity: "Atividade de %{value}"
-  label_updated_time_by: "Atualizado por %{author} hÃ¡ %{age}"
-  text_diff_truncated: '... Este diff foi truncado porque excede o tamanho mÃ¡ximo que pode ser exibido.'
-  setting_diff_max_lines_displayed: NÃºmero mÃ¡ximo de linhas exibidas no diff
-  text_plugin_assets_writable: DiretÃ³rio de plugins gravÃ¡vel
-  warning_attachments_not_saved: "%{count} arquivo(s) nÃ£o puderam ser salvo(s)."
-  button_create_and_continue: Criar e continuar
-  text_custom_field_possible_values_info: 'Uma linha para cada valor'
-  label_display: ExibiÃ§Ã£o
-  field_editable: EditÃ¡vel
-  setting_repository_log_display_limit: NÃºmero mÃ¡ximo de revisÃµes exibidas no arquivo de log
-  setting_file_max_size_displayed: Tamanho mÃ¡ximo dos arquivos textos exibidos inline
-  field_identity_urler: Observador
-  setting_openid: Permitir Login e Registro via OpenID
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: ou use o OpenID
-  field_content: ConteÃºdo
-  label_descending: Descendente
-  label_sort: Ordenar
-  label_ascending: Ascendente
-  label_date_from_to: De %{start} atÃ© %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: Esta pÃ¡gina tem %{descendants} pÃ¡gina(s) filha(s) e descendente(s). O que vocÃª quer fazer?
-  text_wiki_page_reassign_children: Reatribuir pÃ¡ginas filhas para esta pÃ¡gina pai
-  text_wiki_page_nullify_children: Manter as pÃ¡ginas filhas como pÃ¡ginas raÃ­zes
-  text_wiki_page_destroy_children: Excluir pÃ¡ginas filhas e todas suas descendentes
-  setting_password_min_length: Comprimento mÃ­nimo para senhas
-  field_group_by: Agrupar por
-  mail_subject_wiki_content_updated: "A pÃ¡gina wiki '%{id}' foi atualizada"
-  label_wiki_content_added: PÃ¡gina wiki adicionada
-  mail_subject_wiki_content_added: "A pÃ¡gina wiki '%{id}' foi adicionada"
-  mail_body_wiki_content_added: A pÃ¡gina wiki '%{id}' foi adicionada por %{author}.
-  label_wiki_content_updated: PÃ¡gina wiki atualizada
-  mail_body_wiki_content_updated: A pÃ¡gina wiki '%{id}' foi atualizada por %{author}.
-  permission_add_project: Criar projeto
-  setting_new_project_user_role_id: Papel atribuÃ­do a um usuÃ¡rio nÃ£o-administrador que cria um projeto
-  label_view_all_revisions: Ver todas as revisÃµes
-  label_tag: Etiqueta
-  label_branch: Ramo
-  text_journal_changed: "%{label} alterado de %{old} para %{new}"
-  text_journal_set_to: "%{label} ajustado para %{value}"
-  text_journal_deleted: "%{label} excluÃ­do (%{old})"
-  label_group_plural: Grupos
-  label_group: Grupo
-  label_group_new: Novo grupo
-  label_time_entry_plural: Tempos gastos
-  text_journal_added: "%{label} %{value} adicionado"
-  field_active: Ativo
-  enumeration_system_activity: Atividade do sistema
-  permission_delete_issue_watchers: Excluir observadores
-  version_status_closed: fechado
-  version_status_locked: travado
-  version_status_open: aberto
-  error_can_not_reopen_issue_on_closed_version: Uma tarefa atribuÃ­da a uma versÃ£o fechada nÃ£o pode ser reaberta
-  label_user_anonymous: AnÃ´nimo
-  button_move_and_follow: Mover e seguir
-  setting_default_projects_modules: MÃ³dulos habilitados por padrÃ£o para novos projetos
-  setting_gravatar_default: Imagem-padrÃ£o de Gravatar
-  field_sharing: Compartilhamento
-  label_version_sharing_hierarchy: Com a hierarquia do projeto
-  label_version_sharing_system: Com todos os projetos
-  label_version_sharing_descendants: Com sub-projetos
-  label_version_sharing_tree: Com a Ã¡rvore do projeto
-  label_version_sharing_none: Sem compartilhamento
-  error_can_not_archive_project: Este projeto nÃ£o pode ser arquivado
-  button_duplicate: Duplicar
-  button_copy_and_follow: Copiar e seguir
-  label_copy_source: Origem
-  setting_issue_done_ratio: Calcular o percentual de conclusÃ£o da tarefa
-  setting_issue_done_ratio_issue_status: Usar a situaÃ§Ã£o da tarefa
-  error_issue_done_ratios_not_updated: O pecentual de conclusÃ£o das tarefas nÃ£o foi atualizado.
-  error_workflow_copy_target: Por favor, selecione os tipos de tarefa e os papÃ©is alvo
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Mesmo alvo
-  label_copy_target: Alvo
-  notice_issue_done_ratios_updated: Percentual de conslusÃ£o atualizados.
-  error_workflow_copy_source: Por favor, selecione um tipo de tarefa e papel de origem
-  label_update_issue_done_ratios: Atualizar percentual de conclusÃ£o das tarefas
-  setting_start_of_week: InÃ­cio da semana
-  field_watcher: Observador
-  permission_view_issues: Ver tarefas
-  label_display_used_statuses_only: Somente exibir situaÃ§Ãµes que sÃ£o usadas por este tipo de tarefa
-  label_revision_id: RevisÃ£o %{value}
-  label_api_access_key: Chave de acesso a API
-  button_show: Exibir
-  label_api_access_key_created_on: Chave de acesso a API criado a %{value} atrÃ¡s
-  label_feeds_access_key: Chave de acesso ao RSS
-  notice_api_access_key_reseted: Sua chave de acesso a API foi redefinida.
-  setting_rest_api_enabled: Habilitar REST web service
-  label_missing_api_access_key: Chave de acesso a API faltando
-  label_missing_feeds_access_key: Chave de acesso ao RSS faltando
-  text_line_separated: MÃºltiplos valores permitidos (uma linha para cada valor).
-  setting_mail_handler_body_delimiters: Truncar e-mails apÃ³s uma destas linhas
-  permission_add_subprojects: Criar subprojetos
-  label_subproject_new: Novo subprojeto
-  text_own_membership_delete_confirmation: |-
-    VocÃª estÃ¡ para excluir algumas de suas prÃ³prias permissÃµes e pode nÃ£o mais estar apto a editar este projeto apÃ³s esta operaÃ§Ã£o.
-    VocÃª tem certeza que deseja continuar?
-  label_close_versions: Fechar versÃµes concluÃ­das
-  label_board_sticky: Marcado
-  label_board_locked: Travado
-  label_change_log: Registro de alteraÃ§Ãµes
-  permission_export_wiki_pages: Exportar pÃ¡ginas wiki
-  setting_cache_formatted_text: Realizar cache de texto formatado
-  permission_manage_project_activities: Gerenciar atividades do projeto
-  error_unable_delete_issue_status: NÃ£o foi possÃ­vel excluir situaÃ§Ã£o da tarefa
-  label_profile: Perfil
-  permission_manage_subtasks: Gerenciar subtarefas
-  field_parent_issue: Tarefa pai
-  label_subtask_plural: Subtarefas
-  label_project_copy_notifications: Enviar notificaÃ§Ãµes por e-mail ao copiar projeto
-  error_can_not_delete_custom_field: NÃ£o foi possÃ­vel excluir o campo personalizado
-  error_unable_to_connect: NÃ£o foi possÃ­vel conectar (%{value})
-  error_can_not_remove_role: Este papel estÃ¡ em uso e nÃ£o pode ser excluÃ­do.
-  error_can_not_delete_tracker: Este tipo de tarefa estÃ¡ atribuÃ­do a alguma(s) tarefa(s) e nÃ£o pode ser excluÃ­do.
-  field_principal: Principal
-  label_my_page_block: Meu bloco de pÃ¡gina
-  notice_failed_to_save_members: "Falha ao gravar membro(s): %{errors}."
-  text_zoom_out: Afastar zoom
-  text_zoom_in: Aproximar zoom
-  notice_unable_delete_time_entry: NÃ£o foi possÃ­vel excluir a entrada no registro de horas trabalhadas.
-  label_overall_spent_time: Tempo gasto geral
-  field_time_entries: Registro de horas
-  project_module_gantt: Gantt
-  project_module_calendar: CalendÃ¡rio
-  button_edit_associated_wikipage: "Editar pÃ¡gina wiki relacionada: %{page_title}"
-  text_are_you_sure_with_children: Excluir a tarefa e suas subtarefas?
-  field_text: Campo de texto
-  label_user_mail_option_only_owner: Somente para as coisas que eu criei
-  setting_default_notification_option: OpÃ§Ã£o padrÃ£o de notificaÃ§Ã£o
-  label_user_mail_option_only_my_events: Somente para as coisas que eu esteja observando ou esteja envolvido
-  label_user_mail_option_only_assigned: Somente para as coisas que estejam atribuÃ­das a mim
-  label_user_mail_option_none: Sem eventos
-  field_member_of_group: Grupo do responsÃ¡vel
-  field_assigned_to_role: Papel do responsÃ¡vel
-  notice_not_authorized_archived_project: O projeto que vocÃª estÃ¡ tentando acessar foi arquivado.
-  label_principal_search: "Pesquisar por usuÃ¡rios ou grupos:"
-  label_user_search: "Pesquisar por usuÃ¡rio:"
-  field_visible: VisÃ­vel
-  setting_emails_header: CabeÃ§alho do e-mail
-  setting_commit_logtime_activity_id: Atividade para registrar horas
-  text_time_logged_by_changeset: Aplicado no changeset %{value}.
-  setting_commit_logtime_enabled: Habilitar registro de horas
-  notice_gantt_chart_truncated: O grÃ¡fico foi cortado por exceder o tamanho mÃ¡ximo de linhas que podem ser exibidas (%{max})
-  setting_gantt_items_limit: NÃºmero mÃ¡ximo de itens exibidos no grÃ¡fico gatt
-  field_warn_on_leaving_unsaved: Alertar-me ao sair de uma pÃ¡gina sem salvar o texto
-  text_warn_on_leaving_unsaved: A pÃ¡gina atual contem texto que nÃ£o foi salvo e serÃ¡ perdido se vocÃª sair desta pÃ¡gina.
-  label_my_queries: Minhas consultas personalizadas
-  text_journal_changed_no_detail: "%{label} atualizado(a)"
-  label_news_comment_added: NotÃ­cia recebeu um comentÃ¡rio
-  button_expand_all: Expandir tudo
-  button_collapse_all: Recolher tudo
-  label_additional_workflow_transitions_for_assignee: TransiÃ§Ãµes adicionais permitidas quando o usuÃ¡rio Ã© o responsÃ¡vel pela tarefa
-  label_additional_workflow_transitions_for_author: TransiÃ§Ãµes adicionais permitidas quando o usuÃ¡rio Ã© o autor
-
-  label_bulk_edit_selected_time_entries: AlteraÃ§Ã£o em massa do registro de horas
-  text_time_entries_destroy_confirmation: Tem certeza que quer excluir o(s) registro(s) de horas selecionado(s)?
-  label_role_anonymous: AnÃ´nimo
-  label_role_non_member: NÃ£o Membro
-  label_issues_visibility_own: Tarefas criadas ou atribuÃ­das ao usuÃ¡rio
-  field_issues_visibility: Visibilidade das tarefas
-  label_issues_visibility_all: Todas as tarefas
-  permission_set_own_issues_private: Alterar as prÃ³prias tarefas para pÃºblicas ou privadas
-  field_is_private: Privado
-  permission_set_issues_private: Alterar tarefas para pÃºblicas ou privadas
-  label_issues_visibility_public: Todas as tarefas nÃ£o privadas
-  text_issues_destroy_descendants_confirmation: Isto tambÃ©m irÃ¡ excluir %{count} subtarefa(s).
-  field_commit_logs_encoding: CodificaÃ§Ã£o das mensagens de commit
-  field_scm_path_encoding: CodificaÃ§Ã£o do caminho
-  text_scm_path_encoding_note: "PadrÃ£o: UTF-8"
-  field_path_to_repository: Caminho para o repositÃ³rio
-  field_root_directory: DiretÃ³rio raiz
-  field_cvs_module: MÃ³dulo
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: "RepositÃ³rio local (ex.: /hgrepo, c:\\hgrepo)"
-  text_scm_command: Comando
-  text_scm_command_version: VersÃ£o
-  label_git_report_last_commit: Relatar Ãºltima alteraÃ§Ã£o para arquivos e diretÃ³rios
-  text_scm_config: VocÃª pode configurar seus comandos de versionamento em config/configurations.yml. Por favor reinicie a aplicaÃ§Ã£o apÃ³s alterÃ¡-lo.
-  text_scm_command_not_available: Comando de versionamento nÃ£o disponÃ­vel. Por favor verifique as configuraÃ§Ãµes no painel de administraÃ§Ã£o.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Escopo da pesquisa
-  description_filter: Filtro
-  description_user_mail_notification: ConfiguraÃ§Ã£o de notificaÃ§Ãµes por e-mail
-  description_date_from: Digita a data inicial
-  description_message_content: ConteÃºdo da mensagem
-  description_available_columns: Colunas disponÃ­veis
-  description_date_range_interval: Escolha um perÃ­odo selecionando a data de inÃ­cio e fim
-  description_issue_category_reassign: Escolha uma categoria de tarefas
-  description_search: Searchfield
-  description_notes: Notas
-  description_date_range_list: Escolha um perÃ­odo a partira da lista
-  description_choose_project: Projetos
-  description_date_to: Digite a data final
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Escolha uma nova pÃ¡gina pai
-  description_selected_columns: Colunas selecionadas
-
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Usar data corrente como data inicial para novas tarefas
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/89021103ecb16e23dc5cc611fa652e5e895e947c.svn-base
--- a/.svn/pristine/89/89021103ecb16e23dc5cc611fa652e5e895e947c.svn-base
+++ /dev/null
@@ -1,86 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-module RedmineMenuTestHelper
-  # Assertions
-  def assert_number_of_items_in_menu(menu_name, count)
-    assert Redmine::MenuManager.items(menu_name).size >= count, "Menu has less than #{count} items"
-  end
-
-  def assert_menu_contains_item_named(menu_name, item_name)
-    assert Redmine::MenuManager.items(menu_name).collect(&:name).include?(item_name.to_sym), "Menu did not have an item named #{item_name}"
-  end
-
-  # Helpers
-  def get_menu_item(menu_name, item_name)
-    Redmine::MenuManager.items(menu_name).find {|item| item.name == item_name.to_sym}
-  end
-end
-
-class RedmineTest < ActiveSupport::TestCase
-  include RedmineMenuTestHelper
-
-  def test_top_menu
-    assert_number_of_items_in_menu :top_menu, 5
-    assert_menu_contains_item_named :top_menu, :home
-    assert_menu_contains_item_named :top_menu, :my_page
-    assert_menu_contains_item_named :top_menu, :projects
-    assert_menu_contains_item_named :top_menu, :administration
-    assert_menu_contains_item_named :top_menu, :help
-  end
-
-  def test_account_menu
-    assert_number_of_items_in_menu :account_menu, 4
-    assert_menu_contains_item_named :account_menu, :login
-    assert_menu_contains_item_named :account_menu, :register
-    assert_menu_contains_item_named :account_menu, :my_account
-    assert_menu_contains_item_named :account_menu, :logout
-  end
-
-  def test_application_menu
-    assert_number_of_items_in_menu :application_menu, 0
-  end
-
-  def test_admin_menu
-    assert_number_of_items_in_menu :admin_menu, 0
-  end
-
-  def test_project_menu
-    assert_number_of_items_in_menu :project_menu, 14
-    assert_menu_contains_item_named :project_menu, :overview
-    assert_menu_contains_item_named :project_menu, :activity
-    assert_menu_contains_item_named :project_menu, :roadmap
-    assert_menu_contains_item_named :project_menu, :issues
-    assert_menu_contains_item_named :project_menu, :new_issue
-    assert_menu_contains_item_named :project_menu, :calendar
-    assert_menu_contains_item_named :project_menu, :gantt
-    assert_menu_contains_item_named :project_menu, :news
-    assert_menu_contains_item_named :project_menu, :documents
-    assert_menu_contains_item_named :project_menu, :wiki
-    assert_menu_contains_item_named :project_menu, :boards
-    assert_menu_contains_item_named :project_menu, :files
-    assert_menu_contains_item_named :project_menu, :repository
-    assert_menu_contains_item_named :project_menu, :settings
-  end
-
-  def test_new_issue_should_have_root_as_a_parent
-    new_issue = get_menu_item(:project_menu, :new_issue)
-    assert_equal :root, new_issue.parent.name
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/8937afa1653ec0053686c11b0489477d9550a47d.svn-base
--- /dev/null
+++ b/.svn/pristine/89/8937afa1653ec0053686c11b0489477d9550a47d.svn-base
@@ -0,0 +1,39 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class WorkflowTransition < WorkflowRule
+  validates_presence_of :new_status
+
+  # Returns workflow transitions count by tracker and role
+  def self.count_by_tracker_and_role
+    counts = connection.select_all("SELECT role_id, tracker_id, count(id) AS c FROM #{table_name} WHERE type = 'WorkflowTransition' GROUP BY role_id, tracker_id")
+    roles = Role.sorted.all
+    trackers = Tracker.sorted.all
+
+    result = []
+    trackers.each do |tracker|
+      t = []
+      roles.each do |role|
+        row = counts.detect {|c| c['role_id'].to_s == role.id.to_s && c['tracker_id'].to_s == tracker.id.to_s}
+        t << [role, (row.nil? ? 0 : row['c'].to_i)]
+      end
+      result << [tracker, t]
+    end
+
+    result
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/894f61e1593e5111f70c0b60e768f70d33aa6d50.svn-base
--- a/.svn/pristine/89/894f61e1593e5111f70c0b60e768f70d33aa6d50.svn-base
+++ /dev/null
@@ -1,221 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class RepositorySubversionTest < ActiveSupport::TestCase
-  fixtures :projects, :repositories, :enabled_modules, :users, :roles
-
-  NUM_REV = 11
-
-  def setup
-    @project = Project.find(3)
-    @repository = Repository::Subversion.create(:project => @project,
-             :url => self.class.subversion_repository_url)
-    assert @repository
-  end
-
-  if repository_configured?('subversion')
-    def test_fetch_changesets_from_scratch
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_equal 20, @repository.changes.count
-      assert_equal 'Initial import.', @repository.changesets.find_by_revision('1').comments
-    end
-
-    def test_fetch_changesets_incremental
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      # Remove changesets with revision > 5
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 5}
-      @project.reload
-      assert_equal 5, @repository.changesets.count
-
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-    end
-
-    def test_latest_changesets
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      # with limit
-      changesets = @repository.latest_changesets('', nil, 2)
-      assert_equal 2, changesets.size
-      assert_equal @repository.latest_changesets('', nil).slice(0,2), changesets
-
-      # with path
-      changesets = @repository.latest_changesets('subversion_test/folder', nil)
-      assert_equal ["10", "9", "7", "6", "5", "2"], changesets.collect(&:revision)
-
-      # with path and revision
-      changesets = @repository.latest_changesets('subversion_test/folder', 8)
-      assert_equal ["7", "6", "5", "2"], changesets.collect(&:revision)
-    end
-
-    def test_directory_listing_with_square_brackets_in_path
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      entries = @repository.entries('subversion_test/[folder_with_brackets]')
-      assert_not_nil entries, 'Expect to find entries in folder_with_brackets'
-      assert_equal 1, entries.size, 'Expect one entry in folder_with_brackets'
-      assert_equal 'README.txt', entries.first.name
-    end
-
-    def test_directory_listing_with_square_brackets_in_base
-      @project = Project.find(3)
-      @repository = Repository::Subversion.create(
-                          :project => @project,
-                          :url => "file:///#{self.class.repository_path('subversion')}/subversion_test/[folder_with_brackets]")
-
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-
-      assert_equal 1, @repository.changesets.count, 'Expected to see 1 revision'
-      assert_equal 2, @repository.changes.count, 'Expected to see 2 changes, dir add and file add'
-
-      entries = @repository.entries('')
-      assert_not_nil entries, 'Expect to find entries'
-      assert_equal 1, entries.size, 'Expect a single entry'
-      assert_equal 'README.txt', entries.first.name
-    end
-
-    def test_identifier
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      c = @repository.changesets.find_by_revision('1')
-      assert_equal c.revision, c.identifier
-    end
-
-    def test_find_changeset_by_empty_name
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['', ' ', nil].each do |r|
-        assert_nil @repository.find_changeset_by_name(r)
-      end
-    end
-
-    def test_identifier_nine_digit
-      c = Changeset.new(:repository => @repository, :committed_on => Time.now,
-                        :revision => '123456789', :comments => 'test')
-      assert_equal c.identifier, c.revision
-    end
-
-    def test_format_identifier
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      c = @repository.changesets.find_by_revision('1')
-      assert_equal c.format_identifier, c.revision
-    end
-
-    def test_format_identifier_nine_digit
-      c = Changeset.new(:repository => @repository, :committed_on => Time.now,
-                        :revision => '123456789', :comments => 'test')
-      assert_equal c.format_identifier, c.revision
-    end
-
-    def test_activities
-      c = Changeset.new(:repository => @repository, :committed_on => Time.now,
-                        :revision => '1', :comments => 'test')
-      assert c.event_title.include?('1:')
-      assert_equal '1', c.event_url[:rev]
-    end
-
-    def test_activities_nine_digit
-      c = Changeset.new(:repository => @repository, :committed_on => Time.now,
-                        :revision => '123456789', :comments => 'test')
-      assert c.event_title.include?('123456789:')
-      assert_equal '123456789', c.event_url[:rev]
-    end
-
-    def test_log_encoding_ignore_setting
-      with_settings :commit_logs_encoding => 'windows-1252' do
-        s1 = "\xC2\x80"
-        s2 = "\xc3\x82\xc2\x80"
-        if s1.respond_to?(:force_encoding)
-          s1.force_encoding('ISO-8859-1')
-          s2.force_encoding('UTF-8')
-          assert_equal s1.encode('UTF-8'), s2
-        end
-        c = Changeset.new(:repository => @repository,
-                          :comments   => s2,
-                          :revision   => '123',
-                          :committed_on => Time.now)
-        assert c.save
-        assert_equal s2, c.comments
-      end
-    end
-
-    def test_previous
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      changeset = @repository.find_changeset_by_name('3')
-      assert_equal @repository.find_changeset_by_name('2'), changeset.previous
-    end
-
-    def test_previous_nil
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      changeset = @repository.find_changeset_by_name('1')
-      assert_nil changeset.previous
-    end
-
-    def test_next
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      changeset = @repository.find_changeset_by_name('2')
-      assert_equal @repository.find_changeset_by_name('3'), changeset.next
-    end
-
-    def test_next_nil
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      changeset = @repository.find_changeset_by_name('11')
-      assert_nil changeset.next
-    end
-  else
-    puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/896d2497486a7dfbefa5146aaa83a0fc9dd4aa0c.svn-base
--- a/.svn/pristine/89/896d2497486a7dfbefa5146aaa83a0fc9dd4aa0c.svn-base
+++ /dev/null
@@ -1,179 +0,0 @@
-module CodeRay
-  module Encoders
-    
-    # Outputs code highlighted for a color terminal.
-    # 
-    # Note: This encoder is in beta. It currently doesn't use the Styles.
-    # 
-    # Alias: +term+
-    # 
-    # == Authors & License
-    # 
-    # By Rob Aldred (http://robaldred.co.uk)
-    # 
-    # Based on idea by Nathan Weizenbaum (http://nex-3.com)
-    # 
-    # MIT License (http://www.opensource.org/licenses/mit-license.php)
-    class Terminal < Encoder
-      
-      register_for :terminal
-      
-      TOKEN_COLORS = {
-        :annotation => '35',
-        :attribute_name => '33',
-        :attribute_value => '31',
-        :binary => '1;35',
-        :char => {
-          :self => '36', :delimiter => '34'
-        },
-        :class => '1;35',
-        :class_variable => '36',
-        :color => '32',
-        :comment => '37',
-        :complex => '34',
-        :constant => ['34', '4'],
-        :decoration => '35',
-        :definition => '1;32',
-        :directive => ['32', '4'],
-        :doc => '46',
-        :doctype => '1;30',
-        :doc_string => ['31', '4'],
-        :entity => '33',
-        :error => ['1;33', '41'],
-        :exception => '1;31',
-        :float => '1;35',
-        :function => '1;34',
-        :global_variable => '42',
-        :hex => '1;36',
-        :include => '33',
-        :integer => '1;34',
-        :key => '35',
-        :label => '1;15',
-        :local_variable => '33',
-        :octal => '1;35',
-        :operator_name => '1;29',
-        :predefined_constant => '1;36',
-        :predefined_type => '1;30',
-        :predefined => ['4', '1;34'],
-        :preprocessor => '36',
-        :pseudo_class => '34',
-        :regexp => {
-          :self => '31',
-          :content => '31',
-          :delimiter => '1;29',
-          :modifier => '35',
-          :function => '1;29'
-        },
-        :reserved => '1;31',
-        :shell => {
-          :self => '42',
-          :content => '1;29',
-          :delimiter => '37',
-        },
-        :string => {
-          :self => '32',
-          :modifier => '1;32',
-          :escape => '1;36',
-          :delimiter => '1;32',
-        },
-        :symbol => '1;32',
-        :tag => '34',
-        :type => '1;34',
-        :value => '36',
-        :variable => '34',
-        
-        :insert => '42',
-        :delete => '41',
-        :change => '44',
-        :head => '45'
-      }
-      TOKEN_COLORS[:keyword] = TOKEN_COLORS[:reserved]
-      TOKEN_COLORS[:method] = TOKEN_COLORS[:function]
-      TOKEN_COLORS[:imaginary] = TOKEN_COLORS[:complex]
-      TOKEN_COLORS[:begin_group] = TOKEN_COLORS[:end_group] =
-        TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter]
-      
-    protected
-      
-      def setup(options)
-        super
-        @opened = []
-        @subcolors = nil
-      end
-      
-    public
-      
-      def text_token text, kind
-        if color = (@subcolors || TOKEN_COLORS)[kind]
-          if Hash === color
-            if color[:self]
-              color = color[:self]
-            else
-              @out << text
-              return
-            end
-          end
-          
-          @out << ansi_colorize(color)
-          @out << text.gsub("\n", ansi_clear + "\n" + ansi_colorize(color))
-          @out << ansi_clear
-          @out << ansi_colorize(@subcolors[:self]) if @subcolors && @subcolors[:self]
-        else
-          @out << text
-        end
-      end
-      
-      def begin_group kind
-        @opened << kind
-        @out << open_token(kind)
-      end
-      alias begin_line begin_group
-      
-      def end_group kind
-        if @opened.empty?
-          # nothing to close
-        else
-          @opened.pop
-          @out << ansi_clear
-          @out << open_token(@opened.last)
-        end
-      end
-      
-      def end_line kind
-        if @opened.empty?
-          # nothing to close
-        else
-          @opened.pop
-          # whole lines to be highlighted,
-          # eg. added/modified/deleted lines in a diff
-          @out << "\t" * 100 + ansi_clear
-          @out << open_token(@opened.last)
-        end
-      end
-      
-    private
-      
-      def open_token kind
-        if color = TOKEN_COLORS[kind]
-          if Hash === color
-            @subcolors = color
-            ansi_colorize(color[:self]) if color[:self]
-          else
-            @subcolors = {}
-            ansi_colorize(color)
-          end
-        else
-          @subcolors = nil
-          ''
-        end
-      end
-      
-      def ansi_colorize(color)
-        Array(color).map { |c| "\e[#{c}m" }.join
-      end
-      def ansi_clear
-        ansi_colorize(0)
-      end
-    end
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/899fc5d76ba5b79062018e92150433654216dd83.svn-base
--- a/.svn/pristine/89/899fc5d76ba5b79062018e92150433654216dd83.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-module CodeRay
-  VERSION = '1.0.0'
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/89a6f5df70247b9cdb732addfa4529a1a5a8007f.svn-base
--- /dev/null
+++ b/.svn/pristine/89/89a6f5df70247b9cdb732addfa4529a1a5a8007f.svn-base
@@ -0,0 +1,43 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module ReportsHelper
+
+  def aggregate(data, criteria)
+    a = 0
+    data.each { |row|
+      match = 1
+      criteria.each { |k, v|
+        match = 0 unless (row[k].to_s == v.to_s) || (k == 'closed' && row[k] == (v == 0 ? "f" : "t"))
+      } unless criteria.nil?
+      a = a + row["total"].to_i if match == 1
+    } unless data.nil?
+    a
+  end
+
+  def aggregate_link(data, criteria, *args)
+    a = aggregate data, criteria
+    a > 0 ? link_to(h(a), *args) : '-'
+  end
+
+  def aggregate_path(project, field, row, options={})
+    parameters = {:set_filter => 1, :subproject_id => '!*', field => row.id}.merge(options)
+    project_issues_path(row.is_a?(Project) ? row : project, parameters)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/89cb2d66d28a3e37299698980c2cd1f25e832b60.svn-base
--- /dev/null
+++ b/.svn/pristine/89/89cb2d66d28a3e37299698980c2cd1f25e832b60.svn-base
@@ -0,0 +1,108 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Message < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  belongs_to :board
+  belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+  acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC"
+  acts_as_attachable
+  belongs_to :last_reply, :class_name => 'Message', :foreign_key => 'last_reply_id'
+
+  acts_as_searchable :columns => ['subject', 'content'],
+                     :include => {:board => :project},
+                     :project_key => "#{Board.table_name}.project_id",
+                     :date_column => "#{table_name}.created_on"
+  acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"},
+                :description => :content,
+                :group => :parent,
+                :type => Proc.new {|o| o.parent_id.nil? ? 'message' : 'reply'},
+                :url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id}.merge(o.parent_id.nil? ? {:id => o.id} :
+                                                                                                                                       {:id => o.parent_id, :r => o.id, :anchor => "message-#{o.id}"})}
+
+  acts_as_activity_provider :find_options => {:include => [{:board => :project}, :author]},
+                            :author_key => :author_id
+  acts_as_watchable
+
+  validates_presence_of :board, :subject, :content
+  validates_length_of :subject, :maximum => 255
+  validate :cannot_reply_to_locked_topic, :on => :create
+
+  after_create :add_author_as_watcher, :reset_counters!
+  after_update :update_messages_board
+  after_destroy :reset_counters!
+
+  scope :visible, lambda {|*args|
+    includes(:board => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
+  }
+
+  safe_attributes 'subject', 'content'
+  safe_attributes 'locked', 'sticky', 'board_id',
+    :if => lambda {|message, user|
+      user.allowed_to?(:edit_messages, message.project)
+    }
+
+  def visible?(user=User.current)
+    !user.nil? && user.allowed_to?(:view_messages, project)
+  end
+
+  def cannot_reply_to_locked_topic
+    # Can not reply to a locked topic
+    errors.add :base, 'Topic is locked' if root.locked? && self != root
+  end
+
+  def update_messages_board
+    if board_id_changed?
+      Message.update_all({:board_id => board_id}, ["id = ? OR parent_id = ?", root.id, root.id])
+      Board.reset_counters!(board_id_was)
+      Board.reset_counters!(board_id)
+    end
+  end
+
+  def reset_counters!
+    if parent && parent.id
+      Message.update_all({:last_reply_id => parent.children.maximum(:id)}, {:id => parent.id})
+    end
+    board.reset_counters!
+  end
+
+  def sticky=(arg)
+    write_attribute :sticky, (arg == true || arg.to_s == '1' ? 1 : 0)
+  end
+
+  def sticky?
+    sticky == 1
+  end
+
+  def project
+    board.project
+  end
+
+  def editable_by?(usr)
+    usr && usr.logged? && (usr.allowed_to?(:edit_messages, project) || (self.author == usr && usr.allowed_to?(:edit_own_messages, project)))
+  end
+
+  def destroyable_by?(usr)
+    usr && usr.logged? && (usr.allowed_to?(:delete_messages, project) || (self.author == usr && usr.allowed_to?(:delete_own_messages, project)))
+  end
+
+  private
+
+  def add_author_as_watcher
+    Watcher.create(:watchable => self.root, :user => author)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/89d051df634d7daf82a0124fc1261d1139a675b3.svn-base
--- /dev/null
+++ b/.svn/pristine/89/89d051df634d7daf82a0124fc1261d1139a675b3.svn-base
@@ -0,0 +1,26 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Comment < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  belongs_to :commented, :polymorphic => true, :counter_cache => true
+  belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+
+  validates_presence_of :commented, :author, :comments
+
+  safe_attributes 'comments'
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/89f2f1de1b0c1a744af1b4d7a2c5c156ca193d25.svn-base
--- /dev/null
+++ b/.svn/pristine/89/89f2f1de1b0c1a744af1b4d7a2c5c156ca193d25.svn-base
@@ -0,0 +1,90 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Board < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  belongs_to :project
+  has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
+  has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC"
+  belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id
+  acts_as_tree :dependent => :nullify
+  acts_as_list :scope => '(project_id = #{project_id} AND parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"})'
+  acts_as_watchable
+
+  validates_presence_of :name, :description
+  validates_length_of :name, :maximum => 30
+  validates_length_of :description, :maximum => 255
+  validate :validate_board
+
+  scope :visible, lambda {|*args|
+    includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
+  }
+
+  safe_attributes 'name', 'description', 'parent_id', 'move_to'
+
+  def visible?(user=User.current)
+    !user.nil? && user.allowed_to?(:view_messages, project)
+  end
+
+  def reload(*args)
+    @valid_parents = nil
+    super
+  end
+
+  def to_s
+    name
+  end
+
+  def valid_parents
+    @valid_parents ||= project.boards - self_and_descendants
+  end
+
+  def reset_counters!
+    self.class.reset_counters!(id)
+  end
+
+  # Updates topics_count, messages_count and last_message_id attributes for +board_id+
+  def self.reset_counters!(board_id)
+    board_id = board_id.to_i
+    update_all("topics_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id} AND parent_id IS NULL)," +
+               " messages_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id})," +
+               " last_message_id = (SELECT MAX(id) FROM #{Message.table_name} WHERE board_id=#{board_id})",
+               ["id = ?", board_id])
+  end
+
+  def self.board_tree(boards, parent_id=nil, level=0)
+    tree = []
+    boards.select {|board| board.parent_id == parent_id}.sort_by(&:position).each do |board|
+      tree << [board, level]
+      tree += board_tree(boards, board.id, level+1)
+    end
+    if block_given?
+      tree.each do |board, level|
+        yield board, level
+      end
+    end
+    tree
+  end
+
+  protected
+
+  def validate_board
+    if parent_id && parent_id_changed?
+      errors.add(:parent_id, :invalid) unless valid_parents.include?(parent)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/89/89f5504f7426bd8b866f9fb941e83b8b3b055e7a.svn-base
--- a/.svn/pristine/89/89f5504f7426bd8b866f9fb941e83b8b3b055e7a.svn-base
+++ /dev/null
@@ -1,104 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  class CustomFieldFormat
-    include Redmine::I18n
-
-    cattr_accessor :available
-    @@available = {}
-
-    attr_accessor :name, :order, :label, :edit_as, :class_names
-
-    def initialize(name, options={})
-      self.name = name
-      self.label = options[:label]
-      self.order = options[:order]
-      self.edit_as = options[:edit_as] || name
-      self.class_names = options[:only]
-    end
-
-    def format(value)
-      send "format_as_#{name}", value
-    end
-
-    def format_as_date(value)
-      begin; format_date(value.to_date); rescue; value end
-    end
-
-    def format_as_bool(value)
-      l(value == "1" ? :general_text_Yes : :general_text_No)
-    end
-
-    ['string','text','int','float','list'].each do |name|
-      define_method("format_as_#{name}") {|value|
-        return value
-      }
-    end
-
-    ['user', 'version'].each do |name|
-      define_method("format_as_#{name}") {|value|
-        return value.blank? ? "" : name.classify.constantize.find_by_id(value.to_i).to_s
-      }
-    end
-
-    class << self
-      def map(&block)
-        yield self
-      end
-
-      # Registers a custom field format
-      def register(custom_field_format, options={})
-        @@available[custom_field_format.name] = custom_field_format unless @@available.keys.include?(custom_field_format.name)
-      end
-
-      def available_formats
-        @@available.keys
-      end
-
-      def find_by_name(name)
-        @@available[name.to_s]
-      end
-
-      def label_for(name)
-        format = @@available[name.to_s]
-        format.label if format
-      end
-
-      # Return an array of custom field formats which can be used in select_tag
-      def as_select(class_name=nil)
-        fields = @@available.values
-        fields = fields.select {|field| field.class_names.nil? || field.class_names.include?(class_name)}
-        fields.sort {|a,b|
-          a.order <=> b.order
-        }.collect {|custom_field_format|
-          [ l(custom_field_format.label), custom_field_format.name ]
-        }
-      end
-
-      def format_value(value, field_format)
-        return "" unless value && !value.empty?
-
-        if format_type = find_by_name(field_format)
-          format_type.format(value)
-        else
-          value
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8a22be8cc9fbaa89ce238ad133a0232eb8b7d395.svn-base
--- /dev/null
+++ b/.svn/pristine/8a/8a22be8cc9fbaa89ce238ad133a0232eb8b7d395.svn-base
@@ -0,0 +1,84 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class CalendarsControllerTest < ActionController::TestCase
+  fixtures :projects,
+           :trackers,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  def test_show
+    get :show, :project_id => 1
+    assert_response :success
+    assert_template 'calendar'
+    assert_not_nil assigns(:calendar)
+  end
+
+  def test_show_should_run_custom_queries
+    @query = IssueQuery.create!(:name => 'Calendar', :is_public => true)
+
+    get :show, :query_id => @query.id
+    assert_response :success
+  end
+
+  def test_cross_project_calendar
+    get :show
+    assert_response :success
+    assert_template 'calendar'
+    assert_not_nil assigns(:calendar)
+  end
+
+  def test_week_number_calculation
+    Setting.start_of_week = 7
+
+    get :show, :month => '1', :year => '2010'
+    assert_response :success
+
+    assert_select 'tr' do
+      assert_select 'td.week-number', :text => '53'
+      assert_select 'td.odd', :text => '27'
+      assert_select 'td.even', :text => '2'
+    end
+
+    assert_select 'tr' do
+      assert_select 'td.week-number', :text => '1'
+      assert_select 'td.odd', :text => '3'
+      assert_select 'td.even', :text => '9'
+    end
+
+    Setting.start_of_week = 1
+    get :show, :month => '1', :year => '2010'
+    assert_response :success
+
+    assert_select 'tr' do
+      assert_select 'td.week-number', :text => '53'
+      assert_select 'td.even', :text => '28'
+      assert_select 'td.even', :text => '3'
+    end
+
+    assert_select 'tr' do
+      assert_select 'td.week-number', :text => '1'
+      assert_select 'td.even', :text => '4'
+      assert_select 'td.even', :text => '10'
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8a339bcd7d20e6ca60eea513a81446d12d132459.svn-base
--- /dev/null
+++ b/.svn/pristine/8a/8a339bcd7d20e6ca60eea513a81446d12d132459.svn-base
@@ -0,0 +1,25 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module IssueRelationsHelper
+  def collection_for_relation_type_select
+    values = IssueRelation::TYPES
+    values.keys.sort{|x,y| values[x][:order] <=> values[y][:order]}.collect{|k| [l(values[k][:name]), k]}
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8a4b8b250e38c9c5c65661973d49cb661d84e614.svn-base
--- a/.svn/pristine/8a/8a4b8b250e38c9c5c65661973d49cb661d84e614.svn-base
+++ /dev/null
@@ -1,158 +0,0 @@
-module CodeRay
-module Encoders
-
-  class HTML
-
-    # This module is included in the output String of the HTML Encoder.
-    #
-    # It provides methods like wrap, div, page etc.
-    #
-    # Remember to use #clone instead of #dup to keep the modules the object was
-    # extended with.
-    #
-    # TODO: Rewrite this without monkey patching.
-    module Output
-
-      attr_accessor :css
-
-      class << self
-
-        # Raises an exception if an object that doesn't respond to to_str is extended by Output,
-        # to prevent users from misuse. Use Module#remove_method to disable.
-        def extended o  # :nodoc:
-          warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str
-        end
-
-        def make_stylesheet css, in_tag = false  # :nodoc:
-          sheet = css.stylesheet
-          sheet = <<-'CSS' if in_tag
-<style type="text/css">
-#{sheet}
-</style>
-          CSS
-          sheet
-        end
-
-        def page_template_for_css css  # :nodoc:
-          sheet = make_stylesheet css
-          PAGE.apply 'CSS', sheet
-        end
-
-      end
-
-      def wrapped_in? element
-        wrapped_in == element
-      end
-
-      def wrapped_in
-        @wrapped_in ||= nil
-      end
-      attr_writer :wrapped_in
-
-      def wrap_in! template
-        Template.wrap! self, template, 'CONTENT'
-        self
-      end
-      
-      def apply_title! title
-        self.sub!(/(<title>)(<\/title>)/) { $1 + title + $2 }
-        self
-      end
-
-      def wrap! element, *args
-        return self if not element or element == wrapped_in
-        case element
-        when :div
-          raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
-          wrap_in! DIV
-        when :span
-          raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
-          wrap_in! SPAN
-        when :page
-          wrap! :div if wrapped_in? nil
-          raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div
-          wrap_in! Output.page_template_for_css(@css)
-          if args.first.is_a?(Hash) && title = args.first[:title]
-            apply_title! title
-          end
-          self
-        when nil
-          return self
-        else
-          raise "Unknown value %p for :wrap" % element
-        end
-        @wrapped_in = element
-        self
-      end
-
-      def stylesheet in_tag = false
-        Output.make_stylesheet @css, in_tag
-      end
-
-#-- don't include the templates in docu
-
-      class Template < String  # :nodoc:
-
-        def self.wrap! str, template, target
-          target = Regexp.new(Regexp.escape("<%#{target}%>"))
-          if template =~ target
-            str[0,0] = $`
-            str << $'
-          else
-            raise "Template target <%%%p%%> not found" % target
-          end
-        end
-
-        def apply target, replacement
-          target = Regexp.new(Regexp.escape("<%#{target}%>"))
-          if self =~ target
-            Template.new($` + replacement + $')
-          else
-            raise "Template target <%%%p%%> not found" % target
-          end
-        end
-
-      end
-
-      SPAN = Template.new '<span class="CodeRay"><%CONTENT%></span>'
-
-      DIV = Template.new <<-DIV
-<div class="CodeRay">
-  <div class="code"><pre><%CONTENT%></pre></div>
-</div>
-      DIV
-
-      TABLE = Template.new <<-TABLE
-<table class="CodeRay"><tr>
-  <td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><%LINE_NUMBERS%></pre></td>
-  <td class="code"><pre><%CONTENT%></pre></td>
-</tr></table>
-      TABLE
-
-      PAGE = Template.new <<-PAGE
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-  <title></title>
-  <style type="text/css">
-.CodeRay .line-numbers a {
-  text-decoration: inherit;
-  color: inherit;
-}
-<%CSS%>
-  </style>
-</head>
-<body style="background-color: white;">
-
-<%CONTENT%>
-</body>
-</html>
-      PAGE
-
-    end
-
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8a5fb0079b7bc3191dfd37b1677f3f459fe6d66e.svn-base
--- a/.svn/pristine/8a/8a5fb0079b7bc3191dfd37b1677f3f459fe6d66e.svn-base
+++ /dev/null
@@ -1,241 +0,0 @@
-require 'SVG/Graph/Plot'
-require 'parsedate'
-
-module SVG
-  module Graph
-    # === For creating SVG plots of scalar temporal data
-    # 
-    # = Synopsis
-    # 
-    #   require 'SVG/Graph/TimeSeriess'
-    # 
-    #   # Data sets are x,y pairs
-    #   data1 = ["6/17/72", 11,    "1/11/72", 7,    "4/13/04 17:31", 11, 
-    #           "9/11/01", 9,    "9/1/85", 2,    "9/1/88", 1,    "1/15/95", 13]
-    #   data2 = ["8/1/73", 18,    "3/1/77", 15,    "10/1/98", 4, 
-    #           "5/1/02", 14,    "3/1/95", 6,    "8/1/91", 12,    "12/1/87", 6, 
-    #           "5/1/84", 17,    "10/1/80", 12]
-    #
-    #   graph = SVG::Graph::TimeSeries.new( {
-    #     :width => 640,
-    #     :height => 480,
-    #     :graph_title => title,
-    #     :show_graph_title => true,
-    #     :no_css => true,
-    #     :key => true,
-    #     :scale_x_integers => true,
-    #     :scale_y_integers => true,
-    #     :min_x_value => 0,
-    #     :min_y_value => 0,
-    #     :show_data_labels => true,
-    #     :show_x_guidelines => true,
-    #     :show_x_title => true,
-    #     :x_title => "Time",
-    #     :show_y_title => true,
-    #     :y_title => "Ice Cream Cones",
-    #     :y_title_text_direction => :bt,
-    #     :stagger_x_labels => true,
-    #     :x_label_format => "%m/%d/%y",
-    #   })
-    #   
-    #   graph.add_data({
-    #   	:data => projection
-    # 	  :title => 'Projected',
-    #   })
-    # 
-    #   graph.add_data({
-    #   	:data => actual,
-    # 	  :title => 'Actual',
-    #   })
-    #   
-    #   print graph.burn()
-    #
-    # = Description
-    # 
-    # Produces a graph of temporal scalar data.
-    # 
-    # = Examples
-    #
-    # http://www.germane-software/repositories/public/SVG/test/timeseries.rb
-    # 
-    # = Notes
-    # 
-    # The default stylesheet handles upto 10 data sets, if you
-    # use more you must create your own stylesheet and add the
-    # additional settings for the extra data sets. You will know
-    # if you go over 10 data sets as they will have no style and
-    # be in black.
-    #
-    # Unlike the other types of charts, data sets must contain x,y pairs:
-    #
-    #   [ "12:30", 2 ]          # A data set with 1 point: ("12:30",2)
-    #   [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and 
-    #                           #                           ("14:20",6)  
-    #
-    # Note that multiple data sets within the same chart can differ in length, 
-    # and that the data in the datasets needn't be in order; they will be ordered
-    # by the plot along the X-axis.
-    # 
-    # The dates must be parseable by ParseDate, but otherwise can be
-    # any order of magnitude (seconds within the hour, or years)
-    # 
-    # = See also
-    # 
-    # * SVG::Graph::Graph
-    # * SVG::Graph::BarHorizontal
-    # * SVG::Graph::Bar
-    # * SVG::Graph::Line
-    # * SVG::Graph::Pie
-    # * SVG::Graph::Plot
-    #
-    # == Author
-    #
-    # Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
-    #
-    # Copyright 2004 Sean E. Russell
-    # This software is available under the Ruby license[LICENSE.txt]
-    #
-    class TimeSeries < Plot
-      # In addition to the defaults set by Graph::initialize and
-      # Plot::set_defaults, sets:
-      # [x_label_format] '%Y-%m-%d %H:%M:%S'
-      # [popup_format]  '%Y-%m-%d %H:%M:%S'
-      def set_defaults
-        super
-        init_with(
-          #:max_time_span     => '',
-          :x_label_format     => '%Y-%m-%d %H:%M:%S',
-          :popup_format       => '%Y-%m-%d %H:%M:%S'
-        )
-      end
-
-      # The format string use do format the X axis labels.
-      # See Time::strformat
-      attr_accessor :x_label_format
-      # Use this to set the spacing between dates on the axis.  The value
-      # must be of the form 
-      # "\d+ ?(days|weeks|months|years|hours|minutes|seconds)?"
-      # 
-      # EG:
-      #
-      #   graph.timescale_divisions = "2 weeks"
-      #
-      # will cause the chart to try to divide the X axis up into segments of
-      # two week periods.
-      attr_accessor :timescale_divisions
-      # The formatting used for the popups.  See x_label_format
-      attr_accessor :popup_format
-
-      # Add data to the plot.
-      #
-      #   d1 = [ "12:30", 2 ]          # A data set with 1 point: ("12:30",2)
-      #   d2 = [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and 
-      #                                #                           ("14:20",6)  
-      #   graph.add_data( 
-      #     :data => d1,
-      #     :title => 'One'
-      #   )
-      #   graph.add_data(
-      #     :data => d2,
-      #     :title => 'Two'
-      #   )
-      #
-      # Note that the data must be in time,value pairs, and that the date format
-      # may be any date that is parseable by ParseDate.
-      def add_data data
-        @data = [] unless @data
-       
-        raise "No data provided by #{@data.inspect}" unless data[:data] and
-                                                    data[:data].kind_of? Array
-        raise "Data supplied must be x,y pairs!  "+
-          "The data provided contained an odd set of "+
-          "data points" unless data[:data].length % 2 == 0
-        return if data[:data].length == 0
-
-
-        x = []
-        y = []
-        data[:data].each_index {|i|
-          if i%2 == 0
-            arr = ParseDate.parsedate( data[:data][i] )
-            t = Time.local( *arr[0,6].compact )
-            x << t.to_i
-          else
-            y << data[:data][i]
-          end
-        }
-        sort( x, y )
-        data[:data] = [x,y]
-        @data << data
-      end
-
-
-      protected
-
-      def min_x_value=(value)
-        arr = ParseDate.parsedate( value )
-        @min_x_value = Time.local( *arr[0,6].compact ).to_i
-      end
-
-
-      def format x, y
-        Time.at( x ).strftime( popup_format )
-      end
-
-      def get_x_labels
-        get_x_values.collect { |v| Time.at(v).strftime( x_label_format ) }
-      end
-      
-      private
-      def get_x_values
-        rv = []
-        min, max, scale_division = x_range
-        if timescale_divisions
-          timescale_divisions =~ /(\d+) ?(day|week|month|year|hour|minute|second)?/
-          division_units = $2 ? $2 : "day"
-          amount = $1.to_i
-          if amount
-            step =  nil
-            case division_units
-            when "month"
-              cur = min
-              while cur < max
-                rv << cur
-                arr = Time.at( cur ).to_a
-                arr[4] += amount
-                if arr[4] > 12
-                  arr[5] += (arr[4] / 12).to_i
-                  arr[4] = (arr[4] % 12)
-                end
-                cur = Time.local(*arr).to_i
-              end
-            when "year"
-              cur = min
-              while cur < max
-                rv << cur
-                arr = Time.at( cur ).to_a
-                arr[5] += amount
-                cur = Time.local(*arr).to_i
-              end
-            when "week"
-              step = 7 * 24 * 60 * 60 * amount
-            when "day"
-              step = 24 * 60 * 60 * amount
-            when "hour"
-              step = 60 * 60 * amount
-            when "minute"
-              step = 60 * amount
-            when "second"
-              step = amount
-            end
-            min.step( max, step ) {|v| rv << v} if step
-
-            return rv
-          end
-        end
-        min.step( max, scale_division ) {|v| rv << v}
-        return rv
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8a773d20103a10a7c96107249009800080c2940c.svn-base
--- /dev/null
+++ b/.svn/pristine/8a/8a773d20103a10a7c96107249009800080c2940c.svn-base
@@ -0,0 +1,4349 @@
+#============================================================+
+# File name   : tcpdf.rb
+# Begin       : 2002-08-03
+# Last Update : 2007-03-20
+# Author      : Nicola Asuni
+# Version     : 1.53.0.TC031
+# License     : GNU LGPL (http://www.gnu.org/copyleft/lesser.html)
+#
+# Description : This is a Ruby class for generating PDF files 
+#               on-the-fly without requiring external 
+#               extensions.
+#
+# IMPORTANT:
+# This class is an extension and improvement of the Public Domain 
+# FPDF class by Olivier Plathey (http://www.fpdf.org).
+#
+# Main changes by Nicola Asuni:
+#    Ruby porting;
+#    UTF-8 Unicode support;
+#    code refactoring;
+#    source code clean up;
+#    code style and formatting;
+#    source code documentation using phpDocumentor (www.phpdoc.org);
+#    All ISO page formats were included;
+#    image scale factor;
+#    includes methods to parse and printsome XHTML code, supporting the following elements: h1, h2, h3, h4, h5, h6, b, u, i, a, img, p, br, strong, em, font, blockquote, li, ul, ol, hr, td, th, tr, table, sup, sub, small;
+#    includes a method to print various barcode formats using an improved version of "Generic Barcode Render Class" by Karim Mribti (http://www.mribti.com/barcode/) (require GD library: http://www.boutell.com/gd/);
+#    defines standard Header() and Footer() methods.
+#
+#   Ported to Ruby by Ed Moss 2007-08-06
+#
+#============================================================+
+
+require 'tempfile'
+require 'core/rmagick'
+
+#
+# TCPDF Class.
+# @package com.tecnick.tcpdf
+#
+ 
+PDF_PRODUCER = 'TCPDF via RFPDF 1.53.0.TC031 (http://tcpdf.sourceforge.net)'
+
+module TCPDFFontDescriptor
+  @@descriptors = { 'freesans' => {} }
+  @@font_name = 'freesans'
+
+  def self.font(font_name)
+    @@descriptors[font_name.gsub(".rb", "")]
+  end
+
+  def self.define(font_name = 'freesans')
+    @@descriptors[font_name] ||= {}
+    yield @@descriptors[font_name]
+  end
+end
+
+# This is a Ruby class for generating PDF files on-the-fly without requiring external extensions.<br>
+# This class is an extension and improvement of the FPDF class by Olivier Plathey (http://www.fpdf.org).<br>
+# This version contains some changes: [porting to Ruby, support for UTF-8 Unicode, code style and formatting, php documentation (www.phpdoc.org), ISO page formats, minor improvements, image scale factor]<br>
+# TCPDF project (http://tcpdf.sourceforge.net) is based on the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org).<br>
+# To add your own TTF fonts please read /fonts/README.TXT
+# @name TCPDF
+# @package com.tecnick.tcpdf
+# @@version 1.53.0.TC031
+# @author Nicola Asuni
+# @link http://tcpdf.sourceforge.net
+# @license http://www.gnu.org/copyleft/lesser.html LGPL
+#
+class TCPDF
+  include RFPDF
+  include Core::RFPDF
+  include RFPDF::Math
+  
+  def logger
+    Rails.logger
+  end
+
+  @@version = "1.53.0.TC031"
+  @@fpdf_charwidths = {}
+
+  cattr_accessor :k_cell_height_ratio
+  @@k_cell_height_ratio = 1.25
+
+  cattr_accessor :k_blank_image
+  @@k_blank_image = ""
+  
+  cattr_accessor :k_small_ratio  
+  @@k_small_ratio = 2/3.0
+  
+  cattr_accessor :k_path_cache
+  @@k_path_cache = Rails.root.join('tmp')
+  
+  cattr_accessor :k_path_url_cache
+  @@k_path_url_cache = Rails.root.join('tmp')
+  
+	attr_accessor :barcode
+	
+	attr_accessor :buffer
+	
+	attr_accessor :diffs
+	
+	attr_accessor :color_flag
+	
+	attr_accessor :default_table_columns
+
+	attr_accessor :max_table_columns
+	
+	attr_accessor :default_font
+
+	attr_accessor :draw_color
+	
+	attr_accessor :encoding
+	
+	attr_accessor :fill_color
+	
+	attr_accessor :fonts
+	
+	attr_accessor :font_family
+	
+	attr_accessor :font_files
+	
+	cattr_accessor :font_path
+	
+	attr_accessor :font_style
+	
+	attr_accessor :font_size_pt
+	
+	attr_accessor :header_width
+	
+	attr_accessor :header_logo
+	
+	attr_accessor :header_logo_width
+	
+	attr_accessor :header_title
+	
+	attr_accessor :header_string
+	
+	attr_accessor :images
+	
+	attr_accessor :img_scale
+	
+	attr_accessor :in_footer
+	
+	attr_accessor :is_unicode
+
+	attr_accessor :lasth
+	
+	attr_accessor :links
+	
+	attr_accessor :list_ordered
+	
+	attr_accessor :list_count
+	
+	attr_accessor :li_spacer
+	
+	attr_accessor :n
+	
+	attr_accessor :offsets
+	
+	attr_accessor :orientation_changes
+	
+	attr_accessor :page
+	
+	attr_accessor :page_links
+	
+	attr_accessor :pages
+	
+	attr_accessor :pdf_version
+	
+	attr_accessor :prevfill_color
+	
+	attr_accessor :prevtext_color
+	
+	attr_accessor :print_header
+	
+	attr_accessor :print_footer
+	
+	attr_accessor :state
+	
+	attr_accessor :tableborder
+	
+	attr_accessor :tdbegin
+	
+	attr_accessor :tdwidth
+	
+	attr_accessor :tdheight
+	
+	attr_accessor :tdalign
+	
+	attr_accessor :tdfill
+	
+	attr_accessor :tempfontsize
+	
+	attr_accessor :text_color
+	
+	attr_accessor :underline
+	
+	attr_accessor :ws
+	
+	#
+	# This is the class constructor. 
+	# It allows to set up the page format, the orientation and 
+	# the measure unit used in all the methods (except for the font sizes).
+	# @since 1.0
+	# @param string :orientation page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li></ul>
+	# @param string :unit User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.
+	# @param mixed :format The format used for pages. It can be either one of the following values (case insensitive) or a custom format in the form of a two-element array containing the width and the height (expressed in the unit given by unit).<ul><li>4A0</li><li>2A0</li><li>A0</li><li>A1</li><li>A2</li><li>A3</li><li>A4 (default)</li><li>A5</li><li>A6</li><li>A7</li><li>A8</li><li>A9</li><li>A10</li><li>B0</li><li>B1</li><li>B2</li><li>B3</li><li>B4</li><li>B5</li><li>B6</li><li>B7</li><li>B8</li><li>B9</li><li>B10</li><li>C0</li><li>C1</li><li>C2</li><li>C3</li><li>C4</li><li>C5</li><li>C6</li><li>C7</li><li>C8</li><li>C9</li><li>C10</li><li>RA0</li><li>RA1</li><li>RA2</li><li>RA3</li><li>RA4</li><li>SRA0</li><li>SRA1</li><li>SRA2</li><li>SRA3</li><li>SRA4</li><li>LETTER</li><li>LEGAL</li><li>EXECUTIVE</li><li>FOLIO</li></ul>
+	# @param boolean :unicode TRUE means that the input text is unicode (default = true)
+	# @param String :encoding charset encoding; default is UTF-8
+	#
+	def initialize(orientation = 'P',  unit = 'mm', format = 'A4', unicode = true, encoding = "UTF-8")
+		
+		# Set internal character encoding to ASCII#
+		#FIXME 2007-05-25 (EJM) Level=0 - 
+		# if (respond_to?("mb_internal_encoding") and mb_internal_encoding())
+		# 	@internal_encoding = mb_internal_encoding();
+		# 	mb_internal_encoding("ASCII");
+		# }
+			
+		#Some checks
+		dochecks();
+		
+		#Initialization of properties
+  	@barcode ||= false
+		@buffer ||= ''
+		@diffs ||= []
+		@color_flag ||= false
+  	@default_table_columns ||= 4
+  	@table_columns ||= 0
+  	@max_table_columns ||= []
+  	@tr_id ||= 0
+  	@max_td_page ||= []
+  	@max_td_y ||= []
+  	@t_columns ||= 0
+  	@default_font ||= "FreeSans" if unicode
+  	@default_font ||= "Helvetica"
+		@draw_color ||= '0 G'
+  	@encoding ||= "UTF-8"
+		@fill_color ||= '0 g'
+		@fonts ||= {}
+		@font_family ||= ''
+		@font_files ||= {}
+		@font_style ||= ''
+		@font_size ||= 12
+		@font_size_pt ||= 12
+  	@header_width ||= 0
+  	@header_logo ||= ""
+  	@header_logo_width ||= 30
+  	@header_title ||= ""
+  	@header_string ||= ""
+		@images ||= {}
+  	@img_scale ||= 1
+		@in_footer ||= false
+		@is_unicode = unicode
+		@lasth ||= 0
+		@links ||= []
+  	@list_ordered ||= []
+  	@list_count ||= []
+  	@li_spacer ||= ""
+  	@li_count ||= 0
+  	@spacer ||= ""
+  	@quote_count ||= 0
+  	@prevquote_count ||= 0
+  	@quote_top ||= []
+  	@quote_page ||= []
+		@n ||= 2
+		@offsets ||= []
+		@orientation_changes ||= []
+		@page ||= 0
+		@page_links ||= {}
+		@pages ||= []
+  	@pdf_version ||= "1.3"
+  	@prevfill_color ||= [255,255,255]
+  	@prevtext_color ||= [0,0,0]
+  	@print_header ||= false
+  	@print_footer ||= false
+		@state ||= 0
+  	@tableborder ||= 0
+  	@tdbegin ||= false
+	@tdtext ||= ''
+  	@tdwidth ||= 0
+  	@tdheight ||= 0
+  	@tdalign ||= "L"
+  	@tdfill ||= 0
+  	@tempfontsize ||= 10
+		@text_color ||= '0 g'
+		@underline ||= false
+		@deleted ||= false
+		@ws ||= 0
+		
+		#Standard Unicode fonts
+		@core_fonts = {
+		'courier'=>'Courier',
+		'courierB'=>'Courier-Bold',
+		'courierI'=>'Courier-Oblique',
+		'courierBI'=>'Courier-BoldOblique',
+		'helvetica'=>'Helvetica',
+		'helveticaB'=>'Helvetica-Bold',
+		'helveticaI'=>'Helvetica-Oblique',
+		'helveticaBI'=>'Helvetica-BoldOblique',
+		'times'=>'Times-Roman',
+		'timesB'=>'Times-Bold',
+		'timesI'=>'Times-Italic',
+		'timesBI'=>'Times-BoldItalic',
+		'symbol'=>'Symbol',
+		'zapfdingbats'=>'ZapfDingbats'}
+
+		#Scale factor
+		case unit.downcase
+			when 'pt' ; @k=1
+			when 'mm' ; @k=72/25.4
+			when 'cm' ; @k=72/2.54
+			when 'in' ; @k=72
+			else Error("Incorrect unit: #{unit}")
+		end
+
+		#Page format
+		if format.is_a?(String)
+			# Page formats (45 standard ISO paper formats and 4 american common formats).
+			# Paper cordinates are calculated in this way: (inches# 72) where (1 inch = 2.54 cm)
+			case (format.upcase)
+				when  '4A0' ; format = [4767.87,6740.79]
+				when  '2A0' ; format = [3370.39,4767.87]
+				when  'A0' ; format = [2383.94,3370.39]
+				when  'A1' ; format = [1683.78,2383.94]
+				when  'A2' ; format = [1190.55,1683.78]
+				when  'A3' ; format = [841.89,1190.55]
+				when  'A4' ; format = [595.28,841.89] # ; default
+				when  'A5' ; format = [419.53,595.28]
+				when  'A6' ; format = [297.64,419.53]
+				when  'A7' ; format = [209.76,297.64]
+				when  'A8' ; format = [147.40,209.76]
+				when  'A9' ; format = [104.88,147.40]
+				when  'A10' ; format = [73.70,104.88]
+				when  'B0' ; format = [2834.65,4008.19]
+				when  'B1' ; format = [2004.09,2834.65]
+				when  'B2' ; format = [1417.32,2004.09]
+				when  'B3' ; format = [1000.63,1417.32]
+				when  'B4' ; format = [708.66,1000.63]
+				when  'B5' ; format = [498.90,708.66]
+				when  'B6' ; format = [354.33,498.90]
+				when  'B7' ; format = [249.45,354.33]
+				when  'B8' ; format = [175.75,249.45]
+				when  'B9' ; format = [124.72,175.75]
+				when  'B10' ; format = [87.87,124.72]
+				when  'C0' ; format = [2599.37,3676.54]
+				when  'C1' ; format = [1836.85,2599.37]
+				when  'C2' ; format = [1298.27,1836.85]
+				when  'C3' ; format = [918.43,1298.27]
+				when  'C4' ; format = [649.13,918.43]
+				when  'C5' ; format = [459.21,649.13]
+				when  'C6' ; format = [323.15,459.21]
+				when  'C7' ; format = [229.61,323.15]
+				when  'C8' ; format = [161.57,229.61]
+				when  'C9' ; format = [113.39,161.57]
+				when  'C10' ; format = [79.37,113.39]
+				when  'RA0' ; format = [2437.80,3458.27]
+				when  'RA1' ; format = [1729.13,2437.80]
+				when  'RA2' ; format = [1218.90,1729.13]
+				when  'RA3' ; format = [864.57,1218.90]
+				when  'RA4' ; format = [609.45,864.57]
+				when  'SRA0' ; format = [2551.18,3628.35]
+				when  'SRA1' ; format = [1814.17,2551.18]
+				when  'SRA2' ; format = [1275.59,1814.17]
+				when  'SRA3' ; format = [907.09,1275.59]
+				when  'SRA4' ; format = [637.80,907.09]
+				when  'LETTER' ; format = [612.00,792.00]
+				when  'LEGAL' ; format = [612.00,1008.00]
+				when  'EXECUTIVE' ; format = [521.86,756.00]
+				when  'FOLIO' ; format = [612.00,936.00]
+				#else then Error("Unknown page format: #{format}"
+			end
+			@fw_pt = format[0]
+			@fh_pt = format[1]
+		else
+			@fw_pt = format[0]*@k
+			@fh_pt = format[1]*@k
+		end
+
+		@fw = @fw_pt/@k
+		@fh = @fh_pt/@k
+
+		#Page orientation
+		orientation = orientation.downcase
+		if orientation == 'p' or orientation == 'portrait'
+			@def_orientation = 'P'
+			@w_pt = @fw_pt
+			@h_pt = @fh_pt
+		elsif orientation == 'l' or orientation == 'landscape'
+			@def_orientation = 'L'
+			@w_pt = @fh_pt
+			@h_pt = @fw_pt
+		else
+			Error("Incorrect orientation: #{orientation}")
+		end
+
+    @fw = @w_pt/@k
+    @fh = @h_pt/@k
+    
+		@cur_orientation = @def_orientation
+		@w = @w_pt/@k
+		@h = @h_pt/@k
+		#Page margins (1 cm)
+		margin = 28.35/@k
+		SetMargins(margin, margin)
+		#Interior cell margin (1 mm)
+		@c_margin = margin / 10
+		#Line width (0.2 mm)
+		@line_width = 0.567 / @k
+		#Automatic page break
+		SetAutoPageBreak(true, 2 * margin)
+		#Full width display mode
+		SetDisplayMode('fullwidth')
+		#Compression
+		SetCompression(true)
+		#Set default PDF version number
+		@pdf_version = "1.3"
+		
+		@encoding = encoding
+		@b = 0
+		@i = 0
+		@u = 0
+		@href = ''
+		@fontlist = ["arial", "times", "courier", "helvetica", "symbol"]
+		@issetfont = false
+		@issetcolor = false
+	
+		SetFillColor(200, 200, 200, true)
+		SetTextColor(0, 0, 0, true)
+	end
+	
+	#
+	# Set the image scale.
+	# @param float :scale image scale.
+	# @author Nicola Asuni
+	# @since 1.5.2
+	#
+	def SetImageScale(scale)
+		@img_scale = scale;
+	end
+  alias_method :set_image_scale, :SetImageScale
+	
+	#
+	# Returns the image scale.
+	# @return float image scale.
+	# @author Nicola Asuni
+	# @since 1.5.2
+	#
+	def GetImageScale()
+		return @img_scale;
+	end
+  alias_method :get_image_scale, :GetImageScale
+  
+	#
+	# Returns the page width in units.
+	# @return int page width.
+	# @author Nicola Asuni
+	# @since 1.5.2
+	#
+	def GetPageWidth()
+		return @w;
+	end
+  alias_method :get_page_width, :GetPageWidth
+  
+	#
+	# Returns the page height in units.
+	# @return int page height.
+	# @author Nicola Asuni
+	# @since 1.5.2
+	#
+	def GetPageHeight()
+		return @h;
+	end
+  alias_method :get_page_height, :GetPageHeight
+  
+	#
+	# Returns the page break margin.
+	# @return int page break margin.
+	# @author Nicola Asuni
+	# @since 1.5.2
+	#
+	def GetBreakMargin()
+		return @b_margin;
+	end
+  alias_method :get_break_margin, :GetBreakMargin
+
+	#
+	# Returns the scale factor (number of points in user unit).
+	# @return int scale factor.
+	# @author Nicola Asuni
+	# @since 1.5.2
+	#
+	def GetScaleFactor()
+		return @k;
+	end
+  alias_method :get_scale_factor, :GetScaleFactor
+
+	#
+	# Defines the left, top and right margins. By default, they equal 1 cm. Call this method to change them.
+	# @param float :left Left margin.
+	# @param float :top Top margin.
+	# @param float :right Right margin. Default value is the left one.
+	# @since 1.0
+	# @see SetLeftMargin(), SetTopMargin(), SetRightMargin(), SetAutoPageBreak()
+	#
+	def SetMargins(left, top, right=-1)
+		#Set left, top and right margins
+		@l_margin = left
+		@t_margin = top
+		if (right == -1)
+			right = left
+		end
+		@r_margin = right
+	end
+  alias_method :set_margins, :SetMargins
+
+	#
+	# Defines the left margin. The method can be called before creating the first page. If the current abscissa gets out of page, it is brought back to the margin.
+	# @param float :margin The margin.
+	# @since 1.4
+	# @see SetTopMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
+	#
+	def SetLeftMargin(margin)
+		#Set left margin
+		@l_margin = margin
+		if ((@page>0) and (@x < margin))
+			@x = margin
+		end
+	end
+  alias_method :set_left_margin, :SetLeftMargin
+
+	#
+	# Defines the top margin. The method can be called before creating the first page.
+	# @param float :margin The margin.
+	# @since 1.5
+	# @see SetLeftMargin(), SetRightMargin(), SetAutoPageBreak(), SetMargins()
+	#
+	def SetTopMargin(margin)
+		#Set top margin
+		@t_margin = margin
+	end
+  alias_method :set_top_margin, :SetTopMargin
+
+	#
+	# Defines the right margin. The method can be called before creating the first page.
+	# @param float :margin The margin.
+	# @since 1.5
+	# @see SetLeftMargin(), SetTopMargin(), SetAutoPageBreak(), SetMargins()
+	#
+	def SetRightMargin(margin)
+		#Set right margin
+		@r_margin = margin
+	end
+  alias_method :set_right_margin, :SetRightMargin
+
+	#
+	# Enables or disables the automatic page breaking mode. When enabling, the second parameter is the distance from the bottom of the page that defines the triggering limit. By default, the mode is on and the margin is 2 cm.
+	# @param boolean :auto Boolean indicating if mode should be on or off.
+	# @param float :margin Distance from the bottom of the page.
+	# @since 1.0
+	# @see Cell(), MultiCell(), AcceptPageBreak()
+	#
+	def SetAutoPageBreak(auto, margin=0)
+		#Set auto page break mode and triggering margin
+		@auto_page_break = auto
+		@b_margin = margin
+		@page_break_trigger = @h - margin
+	end
+  alias_method :set_auto_page_break, :SetAutoPageBreak
+
+	#
+	# Defines the way the document is to be displayed by the viewer. The zoom level can be set: pages can be displayed entirely on screen, occupy the full width of the window, use real size, be scaled by a specific zooming factor or use viewer default (configured in the Preferences menu of Acrobat). The page layout can be specified too: single at once, continuous display, two columns or viewer default. By default, documents use the full width mode with continuous display.
+	# @param mixed :zoom The zoom to use. It can be one of the following string values or a number indicating the zooming factor to use. <ul><li>fullpage: displays the entire page on screen </li><li>fullwidth: uses maximum width of window</li><li>real: uses real size (equivalent to 100% zoom)</li><li>default: uses viewer default mode</li></ul>
+	# @param string :layout The page layout. Possible values are:<ul><li>single: displays one page at once</li><li>continuous: displays pages continuously (default)</li><li>two: displays two pages on two columns</li><li>default: uses viewer default mode</li></ul>
+	# @since 1.2
+	#
+	def SetDisplayMode(zoom, layout = 'continuous')
+		#Set display mode in viewer
+		if (zoom == 'fullpage' or zoom == 'fullwidth' or zoom == 'real' or zoom == 'default' or !zoom.is_a?(String))
+			@zoom_mode = zoom
+		else
+			Error("Incorrect zoom display mode: #{zoom}")
+		end
+		if (layout == 'single' or layout == 'continuous' or layout == 'two' or layout == 'default')
+			@layout_mode = layout
+		else
+			Error("Incorrect layout display mode: #{layout}")
+		end
+	end
+  alias_method :set_display_mode, :SetDisplayMode
+
+	#
+	# Activates or deactivates page compression. When activated, the internal representation of each page is compressed, which leads to a compression ratio of about 2 for the resulting document. Compression is on by default.
+	# Note: the Zlib extension is required for this feature. If not present, compression will be turned off.
+	# @param boolean :compress Boolean indicating if compression must be enabled.
+	# @since 1.4
+	#
+	def SetCompression(compress)
+		#Set page compression
+		if (respond_to?('gzcompress'))
+			@compress = compress
+		else
+			@compress = false
+		end
+	end
+  alias_method :set_compression, :SetCompression
+
+	#
+	# Defines the title of the document.
+	# @param string :title The title.
+	# @since 1.2
+	# @see SetAuthor(), SetCreator(), SetKeywords(), SetSubject()
+	#
+	def SetTitle(title)
+		#Title of document
+		@title = title
+	end
+  alias_method :set_title, :SetTitle
+
+	#
+	# Defines the subject of the document.
+	# @param string :subject The subject.
+	# @since 1.2
+	# @see SetAuthor(), SetCreator(), SetKeywords(), SetTitle()
+	#
+	def SetSubject(subject)
+		#Subject of document
+		@subject = subject
+	end
+  alias_method :set_subject, :SetSubject
+
+	#
+	# Defines the author of the document.
+	# @param string :author The name of the author.
+	# @since 1.2
+	# @see SetCreator(), SetKeywords(), SetSubject(), SetTitle()
+	#
+	def SetAuthor(author)
+		#Author of document
+		@author = author
+	end
+  alias_method :set_author, :SetAuthor
+
+	#
+	# Associates keywords with the document, generally in the form 'keyword1 keyword2 ...'.
+	# @param string :keywords The list of keywords.
+	# @since 1.2
+	# @see SetAuthor(), SetCreator(), SetSubject(), SetTitle()
+	#
+	def SetKeywords(keywords)
+		#Keywords of document
+		@keywords = keywords
+	end
+  alias_method :set_keywords, :SetKeywords
+
+	#
+	# Defines the creator of the document. This is typically the name of the application that generates the PDF.
+	# @param string :creator The name of the creator.
+	# @since 1.2
+	# @see SetAuthor(), SetKeywords(), SetSubject(), SetTitle()
+	#
+	def SetCreator(creator)
+		#Creator of document
+		@creator = creator
+	end
+  alias_method :set_creator, :SetCreator
+
+	#
+	# Defines an alias for the total number of pages. It will be substituted as the document is closed.<br />
+	# <b>Example:</b><br />
+	# <pre>
+	# class PDF extends TCPDF {
+	# 	def Footer()
+	# 		#Go to 1.5 cm from bottom
+	# 		SetY(-15);
+	# 		#Select Arial italic 8
+	# 		SetFont('Arial','I',8);
+	# 		#Print current and total page numbers
+	# 		Cell(0,10,'Page '.PageNo().'/{nb}',0,0,'C');
+	# 	end
+	# }
+	# :pdf=new PDF();
+	# :pdf->alias_nb_pages();
+	# </pre>
+	# @param string :alias The alias. Default valuenb}.
+	# @since 1.4
+	# @see PageNo(), Footer()
+	#
+	def AliasNbPages(alias_nb ='{nb}')
+		#Define an alias for total number of pages
+		@alias_nb_pages = escapetext(alias_nb)
+	end
+	alias_method :alias_nb_pages, :AliasNbPages
+
+	#
+	# This method is automatically called in case of fatal error; it simply outputs the message and halts the execution. An inherited class may override it to customize the error handling but should always halt the script, or the resulting document would probably be invalid.
+	# 2004-06-11 :: Nicola Asuni : changed bold tag with strong
+	# @param string :msg The error message
+	# @since 1.0
+	#
+	def Error(msg)
+		#Fatal error
+		raise ("TCPDF error: #{msg}")
+	end
+  alias_method :error, :Error
+
+	#
+	# This method begins the generation of the PDF document. It is not necessary to call it explicitly because AddPage() does it automatically.
+	# Note: no page is created by this method
+	# @since 1.0
+	# @see AddPage(), Close()
+	#
+	def Open()
+		#Begin document
+		@state = 1
+	end
+  # alias_method :open, :Open
+
+	#
+	# Terminates the PDF document. It is not necessary to call this method explicitly because Output() does it automatically. If the document contains no page, AddPage() is called to prevent from getting an invalid document.
+	# @since 1.0
+	# @see Open(), Output()
+	#
+	def Close()
+		#Terminate document
+		if (@state==3)
+			return;
+		end
+		if (@page==0)
+			AddPage();
+		end
+		#Page footer
+		@in_footer=true;
+		Footer();
+		@in_footer=false;
+		#Close page
+		endpage();
+		#Close document
+		enddoc();
+	end
+  # alias_method :close, :Close
+
+	#
+	# Adds a new page to the document. If a page is already present, the Footer() method is called first to output the footer. Then the page is added, the current position set to the top-left corner according to the left and top margins, and Header() is called to display the header.
+	# The font which was set before calling is automatically restored. There is no need to call SetFont() again if you want to continue with the same font. The same is true for colors and line width.
+	# The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards.
+	# @param string :orientation Page orientation. Possible values are (case insensitive):<ul><li>P or Portrait</li><li>L or Landscape</li></ul> The default value is the one passed to the constructor.
+	# @since 1.0
+	# @see TCPDF(), Header(), Footer(), SetMargins()
+	#
+	def AddPage(orientation='')
+		#Start a new page
+		if (@state==0)
+			Open();
+		end
+		family=@font_family;
+		style=@font_style + (@underline ? 'U' : '') + (@deleted ? 'D' : '');
+		size=@font_size_pt;
+		lw=@line_width;
+		dc=@draw_color;
+		fc=@fill_color;
+		tc=@text_color;
+		cf=@color_flag;
+		if (@page>0)
+			#Page footer
+			@in_footer=true;
+			Footer();
+			@in_footer=false;
+			#Close page
+			endpage();
+		end
+		#Start new page
+		beginpage(orientation);
+		#Set line cap style to square
+		out('2 J');
+		#Set line width
+		@line_width = lw;
+		out(sprintf('%.2f w', lw*@k));
+		#Set font
+		if (family)
+			SetFont(family, style, size);
+		end
+		#Set colors
+		@draw_color = dc;
+		if (dc!='0 G')
+			out(dc);
+		end
+		@fill_color = fc;
+		if (fc!='0 g')
+			out(fc);
+		end
+		@text_color = tc;
+		@color_flag = cf;
+		#Page header
+		Header();
+		#Restore line width
+		if (@line_width != lw)
+			@line_width = lw;
+			out(sprintf('%.2f w', lw*@k));
+		end
+		#Restore font
+		if (family)
+			SetFont(family, style, size);
+		end
+		#Restore colors
+		if (@draw_color != dc)
+			@draw_color = dc;
+			out(dc);
+		end
+		if (@fill_color != fc)
+			@fill_color = fc;
+			out(fc);
+		end
+		@text_color = tc;
+		@color_flag = cf;
+	end
+	  alias_method :add_page, :AddPage
+	
+  #
+  # Rotate object.
+  # @param float :angle angle in degrees for counter-clockwise rotation
+  # @param int :x abscissa of the rotation center. Default is current x position
+  # @param int :y ordinate of the rotation center. Default is current y position
+  #
+  def Rotate(angle, x="", y="")
+
+  	if (x == '')
+  		x = @x;
+  	end
+  	
+  	if (y == '')
+  		y = @y;
+  	end
+  	
+  	if (@rtl)
+  		x = @w - x;
+  		angle = -@angle;
+  	end
+  	
+  	y = (@h - y) * @k;
+  	x *= @k;
+
+  	# calculate elements of transformation matrix
+  	tm = []
+  	tm[0] = ::Math::cos(deg2rad(angle));
+  	tm[1] = ::Math::sin(deg2rad(angle));
+  	tm[2] = -tm[1];
+  	tm[3] = tm[0];
+  	tm[4] = x + tm[1] * y - tm[0] * x;
+  	tm[5] = y - tm[0] * y - tm[1] * x;
+
+  	# generate the transformation matrix
+  	Transform(tm);
+  end
+    alias_method :rotate, :Rotate
+  
+  #
+	# Starts a 2D tranformation saving current graphic state.
+	# This function must be called before scaling, mirroring, translation, rotation and skewing.
+	# Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior.
+	#
+	def StartTransform
+		out('q');
+	end
+	  alias_method :start_transform, :StartTransform
+	
+	#
+	# Stops a 2D tranformation restoring previous graphic state.
+	# This function must be called after scaling, mirroring, translation, rotation and skewing.
+	# Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior.
+	#
+	def StopTransform
+		out('Q');
+	end
+	  alias_method :stop_transform, :StopTransform
+	
+  #
+	# Apply graphic transformations.
+	# @since 2.1.000 (2008-01-07)
+	# @see StartTransform(), StopTransform()
+	#
+	def Transform(tm)
+		x = out(sprintf('%.3f %.3f %.3f %.3f %.3f %.3f cm', tm[0], tm[1], tm[2], tm[3], tm[4], tm[5]));
+	end
+	  alias_method :transform, :Transform
+		
+	#
+ 	# Set header data.
+	# @param string :ln header image logo
+	# @param string :lw header image logo width in mm
+	# @param string :ht string to print as title on document header
+	# @param string :hs string to print on document header
+	#
+	def SetHeaderData(ln="", lw=0, ht="", hs="")
+		@header_logo = ln || ""
+		@header_logo_width = lw || 0
+		@header_title = ht || ""
+		@header_string = hs || ""
+	end
+	  alias_method :set_header_data, :SetHeaderData
+	
+	#
+ 	# Set header margin.
+	# (minimum distance between header and top page margin)
+	# @param int :hm distance in millimeters
+	#
+	def SetHeaderMargin(hm=10)
+		@header_margin = hm;
+	end
+	  alias_method :set_header_margin, :SetHeaderMargin
+	
+	#
+ 	# Set footer margin.
+	# (minimum distance between footer and bottom page margin)
+	# @param int :fm distance in millimeters
+	#
+	def SetFooterMargin(fm=10)
+		@footer_margin = fm;
+	end
+	  alias_method :set_footer_margin, :SetFooterMargin
+	
+	#
+ 	# Set a flag to print page header.
+	# @param boolean :val set to true to print the page header (default), false otherwise. 
+	#
+	def SetPrintHeader(val=true)
+		@print_header = val;
+	end
+	  alias_method :set_print_header, :SetPrintHeader
+	
+	#
+ 	# Set a flag to print page footer.
+	# @param boolean :value set to true to print the page footer (default), false otherwise. 
+	#
+	def SetPrintFooter(val=true)
+		@print_footer = val;
+	end
+	  alias_method :set_print_footer, :SetPrintFooter
+	
+	#
+ 	# This method is used to render the page header.
+ 	# It is automatically called by AddPage() and could be overwritten in your own inherited class.
+	#
+	def Header()
+		if (@print_header)
+			if (@original_l_margin.nil?)
+				@original_l_margin = @l_margin;
+			end
+			if (@original_r_margin.nil?)
+				@original_r_margin = @r_margin;
+			end
+			
+			#set current position
+			SetXY(@original_l_margin, @header_margin);
+			
+			if ((@header_logo) and (@header_logo != @@k_blank_image))
+				Image(@header_logo, @original_l_margin, @header_margin, @header_logo_width);
+			else
+				@img_rb_y = GetY();
+			end
+			
+			cell_height = ((@@k_cell_height_ratio * @header_font[2]) / @k).round(2)
+			
+			header_x = @original_l_margin + (@header_logo_width * 1.05); #set left margin for text data cell
+			
+			# header title
+			SetFont(@header_font[0], 'B', @header_font[2] + 1);
+			SetX(header_x);
+			Cell(@header_width, cell_height, @header_title, 0, 1, 'L'); 
+			
+			# header string
+			SetFont(@header_font[0], @header_font[1], @header_font[2]);
+			SetX(header_x);
+			MultiCell(@header_width, cell_height, @header_string, 0, 'L', 0);
+			
+			# print an ending header line
+			if (@header_width)
+				#set style for cell border
+				SetLineWidth(0.3);
+				SetDrawColor(0, 0, 0);
+				SetY(1 + (@img_rb_y > GetY() ? @img_rb_y : GetY()));
+				SetX(@original_l_margin);
+				Cell(0, 0, '', 'T', 0, 'C'); 
+			end
+			
+			#restore position
+			SetXY(@original_l_margin, @t_margin);
+		end
+	end
+	  alias_method :header, :Header
+	
+	#
+ 	# This method is used to render the page footer. 
+ 	# It is automatically called by AddPage() and could be overwritten in your own inherited class.
+	#
+	def Footer()
+		if (@print_footer)
+			
+			if (@original_l_margin.nil?)
+				@original_l_margin = @l_margin;
+			end
+			if (@original_r_margin.nil?)
+				@original_r_margin = @r_margin;
+			end
+			
+			#set font
+			SetFont(@footer_font[0], @footer_font[1] , @footer_font[2]);
+			#set style for cell border
+			line_width = 0.3;
+			SetLineWidth(line_width);
+			SetDrawColor(0, 0, 0);
+			
+			footer_height = ((@@k_cell_height_ratio * @footer_font[2]) / @k).round; #footer height, was , 2)
+			#get footer y position
+			footer_y = @h - @footer_margin - footer_height;
+			#set current position
+			SetXY(@original_l_margin, footer_y); 
+			
+			#print document barcode
+			if (@barcode)
+				Ln();
+				barcode_width = ((@w - @original_l_margin - @original_r_margin)).round; #max width
+				writeBarcode(@original_l_margin, footer_y + line_width, barcode_width, footer_height - line_width, "C128B", false, false, 2, @barcode);
+			end
+			
+			SetXY(@original_l_margin, footer_y); 
+			
+			#Print page number
+			Cell(0, footer_height, @l['w_page'] + " " + PageNo().to_s + ' / {nb}', 'T', 0, 'R'); 
+		end
+	end
+	  alias_method :footer, :Footer
+	
+	#
+	# Returns the current page number.
+	# @return int page number
+	# @since 1.0
+	# @see alias_nb_pages()
+	#
+	def PageNo()
+		#Get current page number
+		return @page;
+	end
+  alias_method :page_no, :PageNo
+
+	#
+	# Defines the color used for all drawing operations (lines, rectangles and cell borders). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
+	# @param int :r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
+	# @param int :g Green component (between 0 and 255)
+	# @param int :b Blue component (between 0 and 255)
+	# @since 1.3
+	# @see SetFillColor(), SetTextColor(), Line(), Rect(), Cell(), MultiCell()
+	#
+	def SetDrawColor(r, g=-1, b=-1)
+		#Set color for all stroking operations
+		if ((r==0 and g==0 and b==0) or g==-1)
+			@draw_color=sprintf('%.3f G', r/255.0);
+		else
+			@draw_color=sprintf('%.3f %.3f %.3f RG', r/255.0, g/255.0, b/255.0);
+		end
+		if (@page>0)
+			out(@draw_color);
+		end
+	end
+  alias_method :set_draw_color, :SetDrawColor
+
+	#
+	# Defines the color used for all filling operations (filled rectangles and cell backgrounds). It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
+	# @param int :r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
+	# @param int :g Green component (between 0 and 255)
+	# @param int :b Blue component (between 0 and 255)
+	# @param boolean :storeprev if true stores the RGB array on :prevfill_color variable.
+	# @since 1.3
+	# @see SetDrawColor(), SetTextColor(), Rect(), Cell(), MultiCell()
+	#
+	def SetFillColor(r, g=-1, b=-1, storeprev=false)
+		#Set color for all filling operations
+		if ((r==0 and g==0 and b==0) or g==-1)
+			@fill_color=sprintf('%.3f g', r/255.0);
+		else
+			@fill_color=sprintf('%.3f %.3f %.3f rg', r/255.0, g/255.0, b/255.0);
+		end
+		@color_flag=(@fill_color!=@text_color);
+		if (@page>0)
+			out(@fill_color);
+		end
+		if (storeprev)
+			# store color as previous value
+			@prevfill_color = [r, g, b]
+		end
+	end
+  alias_method :set_fill_color, :SetFillColor
+
+  # This hasn't been ported from tcpdf, it's a variation on SetTextColor for setting cmyk colors
+	def SetCmykFillColor(c, m, y, k, storeprev=false)
+		#Set color for all filling operations
+		@fill_color=sprintf('%.3f %.3f %.3f %.3f k', c, m, y, k);
+		@color_flag=(@fill_color!=@text_color);
+		if (storeprev)
+			# store color as previous value
+			@prevtext_color = [c, m, y, k]
+		end
+		if (@page>0)
+			out(@fill_color);
+		end
+	end
+  alias_method :set_cmyk_fill_color, :SetCmykFillColor
+
+	#
+	# Defines the color used for text. It can be expressed in RGB components or gray scale. The method can be called before the first page is created and the value is retained from page to page.
+	# @param int :r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255
+	# @param int :g Green component (between 0 and 255)
+	# @param int :b Blue component (between 0 and 255)
+	# @param boolean :storeprev if true stores the RGB array on :prevtext_color variable.
+	# @since 1.3
+	# @see SetDrawColor(), SetFillColor(), Text(), Cell(), MultiCell()
+	#
+	def SetTextColor(r, g=-1, b=-1, storeprev=false)
+		#Set color for text
+		if ((r==0 and :g==0 and :b==0) or :g==-1)
+			@text_color=sprintf('%.3f g', r/255.0);
+		else
+			@text_color=sprintf('%.3f %.3f %.3f rg', r/255.0, g/255.0, b/255.0);
+		end
+		@color_flag=(@fill_color!=@text_color);
+		if (storeprev)
+			# store color as previous value
+			@prevtext_color = [r, g, b]
+		end
+	end
+  alias_method :set_text_color, :SetTextColor
+
+  # This hasn't been ported from tcpdf, it's a variation on SetTextColor for setting cmyk colors
+	def SetCmykTextColor(c, m, y, k, storeprev=false)
+		#Set color for text
+		@text_color=sprintf('%.3f %.3f %.3f %.3f k', c, m, y, k);
+		@color_flag=(@fill_color!=@text_color);
+		if (storeprev)
+			# store color as previous value
+			@prevtext_color = [c, m, y, k]
+		end
+	end
+  alias_method :set_cmyk_text_color, :SetCmykTextColor
+  
+	#
+	# Returns the length of a string in user unit. A font must be selected.<br>
+	# Support UTF-8 Unicode [Nicola Asuni, 2005-01-02]
+	# @param string :s The string whose length is to be computed
+	# @return int
+	# @since 1.2
+	#
+	def GetStringWidth(s)
+		#Get width of a string in the current font
+		s = s.to_s;
+		cw = @current_font['cw']
+		w = 0;
+		if (@is_unicode)
+      unicode = UTF8StringToArray(s);
+      unicode.each do |char|
+				if (!cw[char].nil?)
+					w += cw[char];
+				# This should not happen. UTF8StringToArray should guarentee the array is ascii values.
+        # elsif (c!cw[char[0]].nil?)
+        #   w += cw[char[0]];
+        #         elsif (!cw[char.chr].nil?)
+        #           w += cw[char.chr];
+				elsif (!@current_font['desc']['MissingWidth'].nil?)
+					w += @current_font['desc']['MissingWidth']; # set default size
+				else
+					w += 500;
+				end
+			end
+		else
+		  s.each_byte do |c|
+				if cw[c.chr]
+					w += cw[c.chr];
+				elsif cw[?c.chr]
+					w += cw[?c.chr]
+				end
+			end
+		end
+		return (w * @font_size / 1000.0);
+	end
+  alias_method :get_string_width, :GetStringWidth
+
+	#
+	# Defines the line width. By default, the value equals 0.2 mm. The method can be called before the first page is created and the value is retained from page to page.
+	# @param float :width The width.
+	# @since 1.0
+	# @see Line(), Rect(), Cell(), MultiCell()
+	#
+	def SetLineWidth(width)
+		#Set line width
+		@line_width = width;
+		if (@page>0)
+			out(sprintf('%.2f w', width*@k));
+		end
+	end
+  alias_method :set_line_width, :SetLineWidth
+
+	#
+	# Draws a line between two points.
+	# @param float :x1 Abscissa of first point
+	# @param float :y1 Ordinate of first point
+	# @param float :x2 Abscissa of second point
+	# @param float :y2 Ordinate of second point
+	# @since 1.0
+	# @see SetLineWidth(), SetDrawColor()
+	#
+	def Line(x1, y1, x2, y2)
+		#Draw a line
+		out(sprintf('%.2f %.2f m %.2f %.2f l S', x1 * @k, (@h - y1) * @k, x2 * @k, (@h - y2) * @k));
+	end
+  alias_method :line, :Line
+
+  def Circle(mid_x, mid_y, radius, style='')
+    mid_y = (@h-mid_y)*@k
+    out(sprintf("q\n")) # postscript content in pdf
+    # init line type etc. with /GSD gs G g (grey) RG rg (RGB) w=line witdh etc. 
+    out(sprintf("1 j\n")) # line join
+    # translate ("move") circle to mid_y, mid_y
+    out(sprintf("1 0 0 1 %f %f cm", mid_x, mid_y))
+    kappa = 0.5522847498307933984022516322796
+    # Quadrant 1 
+    x_s = 0.0 # 12 o'clock 
+    y_s = 0.0 + radius
+    x_e = 0.0 + radius # 3 o'clock 
+    y_e = 0.0
+    out(sprintf("%f %f m\n", x_s, y_s)) # move to 12 o'clock 
+    # cubic bezier control point 1, start height and kappa * radius to the right 
+    bx_e1 = x_s + (radius * kappa)
+    by_e1 = y_s
+    # cubic bezier control point 2, end and kappa * radius above 
+    bx_e2 = x_e
+    by_e2 = y_e + (radius * kappa)
+    # draw cubic bezier from current point to x_e/y_e with bx_e1/by_e1 and bx_e2/by_e2 as bezier control points
+    out(sprintf("%f %f %f %f %f %f c\n", bx_e1, by_e1, bx_e2, by_e2, x_e, y_e))
+    # Quadrant 2 
+    x_s = x_e 
+    y_s = y_e # 3 o'clock 
+    x_e = 0.0 
+    y_e = 0.0 - radius # 6 o'clock 
+    bx_e1 = x_s # cubic bezier point 1 
+    by_e1 = y_s - (radius * kappa)
+    bx_e2 = x_e + (radius * kappa) # cubic bezier point 2 
+    by_e2 = y_e
+    out(sprintf("%f %f %f %f %f %f c\n", bx_e1, by_e1, bx_e2, by_e2, x_e, y_e))
+    # Quadrant 3 
+    x_s = x_e 
+    y_s = y_e # 6 o'clock 
+    x_e = 0.0 - radius
+    y_e = 0.0 # 9 o'clock 
+    bx_e1 = x_s - (radius * kappa) # cubic bezier point 1 
+    by_e1 = y_s
+    bx_e2 = x_e # cubic bezier point 2 
+    by_e2 = y_e - (radius * kappa)
+    out(sprintf("%f %f %f %f %f %f c\n", bx_e1, by_e1, bx_e2, by_e2, x_e, y_e))
+    # Quadrant 4 
+    x_s = x_e 
+    y_s = y_e # 9 o'clock 
+    x_e = 0.0 
+    y_e = 0.0 + radius # 12 o'clock 
+    bx_e1 = x_s # cubic bezier point 1 
+    by_e1 = y_s + (radius * kappa)
+    bx_e2 = x_e - (radius * kappa) # cubic bezier point 2 
+    by_e2 = y_e
+    out(sprintf("%f %f %f %f %f %f c\n", bx_e1, by_e1, bx_e2, by_e2, x_e, y_e))
+    if style=='F'
+        op='f'
+    elsif style=='FD' or style=='DF'
+        op='b'
+    else
+        op='s'
+    end
+    out(sprintf("#{op}\n")) # stroke circle, do not fill and close path 
+    # for filling etc. b, b*, f, f*
+    out(sprintf("Q\n")) # finish postscript in PDF
+  end
+  alias_method :circle, :Circle
+
+	#
+	# Outputs a rectangle. It can be drawn (border only), filled (with no border) or both.
+	# @param float :x Abscissa of upper-left corner
+	# @param float :y Ordinate of upper-left corner
+	# @param float :w Width
+	# @param float :h Height
+	# @param string :style Style of rendering. Possible values are:<ul><li>D or empty string: draw (default)</li><li>F: fill</li><li>DF or FD: draw and fill</li></ul>
+	# @since 1.0
+	# @see SetLineWidth(), SetDrawColor(), SetFillColor()
+	#
+	def Rect(x, y, w, h, style='')
+		#Draw a rectangle
+		if (style=='F')
+			op='f';
+		elsif (style=='FD' or style=='DF')
+			op='B';
+		else
+			op='S';
+		end
+		out(sprintf('%.2f %.2f %.2f %.2f re %s', x * @k, (@h - y) * @k, w * @k, -h * @k, op));
+	end
+  alias_method :rect, :Rect
+
+	#
+	# Imports a TrueType or Type1 font and makes it available. It is necessary to generate a font definition file first with the makefont.rb utility. The definition file (and the font file itself when embedding) must be present either in the current directory or in the one indicated by FPDF_FONTPATH if the constant is defined. If it could not be found, the error "Could not include font definition file" is generated.
+	# Support UTF-8 Unicode [Nicola Asuni, 2005-01-02].
+	# <b>Example</b>:<br />
+	# <pre>
+	# :pdf->AddFont('Comic','I');
+	# # is equivalent to:
+	# :pdf->AddFont('Comic','I','comici.rb');
+	# </pre>
+	# @param string :family Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font.
+	# @param string :style Font style. Possible values are (case insensitive):<ul><li>empty string: regular (default)</li><li>B: bold</li><li>I: italic</li><li>BI or IB: bold italic</li></ul>
+	# @param string :file The font definition file. By default, the name is built from the family and style, in lower case with no space.
+	# @since 1.5
+	# @see SetFont()
+	#
+	def AddFont(family, style='', file='')
+		if (family.empty?)
+			return;
+		end
+
+		#Add a TrueType or Type1 font
+		family = family.downcase
+		if ((!@is_unicode) and (family == 'arial'))
+			family = 'helvetica';
+		end
+
+		style=style.upcase
+		style=style.gsub('U','');
+		style=style.gsub('D','');
+		if (style == 'IB')
+			style = 'BI';
+		end
+
+		fontkey = family + style;
+		# check if the font has been already added
+		if !@fonts[fontkey].nil?
+			return;
+		end
+
+		if (file=='')
+			file = family.gsub(' ', '') + style.downcase + '.rb';
+		end
+		font_file_name = getfontpath(file)
+		if (font_file_name.nil?)
+			# try to load the basic file without styles
+			file = family.gsub(' ', '') + '.rb';
+  		font_file_name = getfontpath(file)
+		end
+    if font_file_name.nil?
+			Error("Could not find font #{file}.")
+    end
+		require(getfontpath(file))
+		font_desc = TCPDFFontDescriptor.font(file)
+
+		if (font_desc[:name].nil? and @@fpdf_charwidths.nil?)
+			Error('Could not include font definition file');
+		end
+
+		i = @fonts.length+1;
+		if (@is_unicode)
+			@fonts[fontkey] = {'i' => i, 'type' => font_desc[:type], 'name' => font_desc[:name], 'desc' => font_desc[:desc], 'up' => font_desc[:up], 'ut' => font_desc[:ut], 'cw' => font_desc[:cw], 'enc' => font_desc[:enc], 'file' => font_desc[:file], 'ctg' => font_desc[:ctg], 'cMap' => font_desc[:cMap], 'registry' => font_desc[:registry]}
+			@@fpdf_charwidths[fontkey] = font_desc[:cw];
+		else
+			@fonts[fontkey]={'i' => i, 'type'=>'core', 'name'=>@core_fonts[fontkey], 'up'=>-100, 'ut'=>50, 'cw' => font_desc[:cw]}
+			@@fpdf_charwidths[fontkey] = font_desc[:cw];
+		end
+
+		if (!font_desc[:diff].nil? and (!font_desc[:diff].empty?))
+			#Search existing encodings
+			d=0;
+			nb=@diffs.length;
+			1.upto(nb) do |i|
+				if (@diffs[i]== font_desc[:diff])
+					d = i;
+					break;
+				end
+			end
+			if (d==0)
+				d = nb+1;
+				@diffs[d] = font_desc[:diff];
+			end
+			@fonts[fontkey]['diff'] = d;
+		end
+		if (font_desc[:file] and font_desc[:file].length > 0)
+			if (font_desc[:type] == "TrueType") or (font_desc[:type] == "TrueTypeUnicode")
+				@font_files[font_desc[:file]] = {'length1' => font_desc[:originalsize]}
+			else
+				@font_files[font_desc[:file]] = {'length1' => font_desc[:size1], 'length2' => font_desc[:size2]}
+			end
+		end
+	end
+  alias_method :add_font, :AddFont
+
+	#
+	# Sets the font used to print character strings. It is mandatory to call this method at least once before printing text or the resulting document would not be valid.
+	# The font can be either a standard one or a font added via the AddFont() method. Standard fonts use Windows encoding cp1252 (Western Europe).
+	# The method can be called before the first page is created and the font is retained from page to page.
+	# If you just wish to change the current font size, it is simpler to call SetFontSize().
+	# Note: for the standard fonts, the font metric files must be accessible. There are three possibilities for this:<ul><li>They are in the current directory (the one where the running script lies)</li><li>They are in one of the directories defined by the include_path parameter</li><li>They are in the directory defined by the FPDF_FONTPATH constant</li></ul><br />
+	# Example for the last case (note the trailing slash):<br />
+	# <pre>
+	# define('FPDF_FONTPATH','/home/www/font/');
+	# require('tcpdf.rb');
+	#
+	# #Times regular 12
+	# :pdf->SetFont('Times');
+	# #Arial bold 14
+	# :pdf->SetFont('Arial','B',14);
+	# #Removes bold
+	# :pdf->SetFont('');
+	# #Times bold, italic and underlined 14
+	# :pdf->SetFont('Times','BIUD');
+	# </pre><br />
+	# If the file corresponding to the requested font is not found, the error "Could not include font metric file" is generated.
+	# @param string :family Family font. It can be either a name defined by AddFont() or one of the standard families (case insensitive):<ul><li>Courier (fixed-width)</li><li>Helvetica or Arial (synonymous; sans serif)</li><li>Times (serif)</li><li>Symbol (symbolic)</li><li>ZapfDingbats (symbolic)</li></ul>It is also possible to pass an empty string. In that case, the current family is retained.
+	# @param string :style Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li></ul>or any combination. The default value is regular. Bold and italic styles do not apply to Symbol and ZapfDingbats
+	# @param float :size Font size in points. The default value is the current size. If no size has been specified since the beginning of the document, the value taken is 12
+	# @since 1.0
+	# @see AddFont(), SetFontSize(), Cell(), MultiCell(), Write()
+	#
+	def SetFont(family, style='', size=0)
+		# save previous values
+		@prevfont_family = @font_family;
+		@prevfont_style = @font_style;
+
+		family=family.downcase;
+		if (family=='')
+			family=@font_family;
+		end
+		if ((!@is_unicode) and (family == 'arial'))
+			family = 'helvetica';
+		elsif ((family=="symbol") or (family=="zapfdingbats"))
+			style='';
+		end
+		
+		style=style.upcase;
+
+		if (style.include?('U'))
+			@underline=true;
+			style= style.gsub('U','');
+		else
+			@underline=false;
+		end
+		if (style.include?('D'))
+			@deleted=true;
+			style= style.gsub('D','');
+		else
+			@deleted=false;
+		end
+		if (style=='IB')
+			style='BI';
+		end
+		if (size==0)
+			size=@font_size_pt;
+		end
+
+		# try to add font (if not already added)
+		AddFont(family, style);
+		
+		#Test if font is already selected
+		if ((@font_family == family) and (@font_style == style) and (@font_size_pt == size))
+			return;
+		end
+		
+		fontkey = family + style;
+		style = '' if (@fonts[fontkey].nil? and !@fonts[family].nil?)
+    
+		#Test if used for the first time
+		if (@fonts[fontkey].nil?)
+			#Check if one of the standard fonts
+			if (!@core_fonts[fontkey].nil?)
+				if @@fpdf_charwidths[fontkey].nil?
+					#Load metric file
+					file = family;
+					if ((family!='symbol') and (family!='zapfdingbats'))
+						file += style.downcase;
+					end
+					if (getfontpath(file + '.rb').nil?)
+						# try to load the basic file without styles
+						file = family;
+						fontkey = family;
+					end
+					require(getfontpath(file + '.rb'));
+      		font_desc = TCPDFFontDescriptor.font(file)
+					if ((@is_unicode and ctg.nil?) or ((!@is_unicode) and (@@fpdf_charwidths[fontkey].nil?)) )
+						Error("Could not include font metric file [" + fontkey + "]: " + getfontpath(file + ".rb"));
+					end
+				end
+				i = @fonts.length + 1;
+
+				if (@is_unicode)
+					@fonts[fontkey] = {'i' => i, 'type' => font_desc[:type], 'name' => font_desc[:name], 'desc' => font_desc[:desc], 'up' => font_desc[:up], 'ut' => font_desc[:ut], 'cw' => font_desc[:cw], 'enc' => font_desc[:enc], 'file' => font_desc[:file], 'ctg' => font_desc[:ctg]}
+					@@fpdf_charwidths[fontkey] = font_desc[:cw];
+				else
+					@fonts[fontkey] = {'i' => i, 'type'=>'core', 'name'=>@core_fonts[fontkey], 'up'=>-100, 'ut'=>50, 'cw' => font_desc[:cw]}
+					@@fpdf_charwidths[fontkey] = font_desc[:cw];
+				end
+			else
+				Error('Undefined font: ' + family + ' ' + style);
+			end
+		end
+		#Select it
+		@font_family = family;
+		@font_style = style;
+		@font_size_pt = size;
+		@font_size = size / @k;
+		@current_font = @fonts[fontkey]; # was & may need deep copy?
+		if (@page>0)
+			out(sprintf('BT /F%d %.2f Tf ET', @current_font['i'], @font_size_pt));
+		end
+	end
+  alias_method :set_font, :SetFont
+
+	#
+	# Defines the size of the current font.
+	# @param float :size The size (in points)
+	# @since 1.0
+	# @see SetFont()
+	#
+	def SetFontSize(size)
+		#Set font size in points
+		if (@font_size_pt== size)
+			return;
+		end
+		@font_size_pt = size;
+		@font_size = size.to_f / @k;
+		if (@page > 0)
+			out(sprintf('BT /F%d %.2f Tf ET', @current_font['i'], @font_size_pt));
+		end
+	end
+  alias_method :set_font_size, :SetFontSize
+
+	#
+	# Creates a new internal link and returns its identifier. An internal link is a clickable area which directs to another place within the document.<br />
+	# The identifier can then be passed to Cell(), Write(), Image() or Link(). The destination is defined with SetLink().
+	# @since 1.5
+	# @see Cell(), Write(), Image(), Link(), SetLink()
+	#
+	def AddLink()
+		#Create a new internal link
+		n=@links.length+1;
+		@links[n]=[0,0];
+		return n;
+	end
+  alias_method :add_link, :AddLink
+
+	#
+	# Defines the page and position a link points to
+	# @param int :link The link identifier returned by AddLink()
+	# @param float :y Ordinate of target position; -1 indicates the current position. The default value is 0 (top of page)
+	# @param int :page Number of target page; -1 indicates the current page. This is the default value
+	# @since 1.5
+	# @see AddLink()
+	#
+	def SetLink(link, y=0, page=-1)
+		#Set destination of internal link
+		if (y==-1)
+			y=@y;
+		end
+		if (page==-1)
+			page=@page;
+		end
+		@links[link] = [page, y]
+	end
+  alias_method :set_link, :SetLink
+
+	#
+	# Puts a link on a rectangular area of the page. Text or image links are generally put via Cell(), Write() or Image(), but this method can be useful for instance to define a clickable area inside an image.
+	# @param float :x Abscissa of the upper-left corner of the rectangle
+	# @param float :y Ordinate of the upper-left corner of the rectangle
+	# @param float :w Width of the rectangle
+	# @param float :h Height of the rectangle
+	# @param mixed :link URL or identifier returned by AddLink()
+	# @since 1.5
+	# @see AddLink(), Cell(), Write(), Image()
+	#
+	def Link(x, y, w, h, link)
+		#Put a link on the page
+    @page_links ||= Array.new
+    @page_links[@page] ||= Array.new
+    @page_links[@page].push([x * @k, @h_pt - y * @k, w * @k, h*@k, link]);
+	end
+  alias_method :link, :Link
+
+	#
+	# Prints a character string. The origin is on the left of the first charcter, on the baseline. This method allows to place a string precisely on the page, but it is usually easier to use Cell(), MultiCell() or Write() which are the standard methods to print text.
+	# @param float :x Abscissa of the origin
+	# @param float :y Ordinate of the origin
+	# @param string :txt String to print
+	# @since 1.0
+	# @see SetFont(), SetTextColor(), Cell(), MultiCell(), Write()
+	#
+	def Text(x, y, txt)
+		#Output a string
+		s=sprintf('BT %.2f %.2f Td (%s) Tj ET', x * @k, (@h-y) * @k, escapetext(txt));
+		if (@underline and (txt!=''))
+			s += ' ' + dolinetxt(x, y, txt);
+		end
+		if (@color_flag)
+			s='q ' + @text_color + ' ' + s + ' Q';
+		end
+		out(s);
+	end
+  alias_method :text, :Text
+
+	#
+	# Whenever a page break condition is met, the method is called, and the break is issued or not depending on the returned value. The default implementation returns a value according to the mode selected by SetAutoPageBreak().<br />
+	# This method is called automatically and should not be called directly by the application.<br />
+	# <b>Example:</b><br />
+	# The method is overriden in an inherited class in order to obtain a 3 column layout:<br />
+	# <pre>
+	# class PDF extends TCPDF {
+	# 	var :col=0;
+	#
+	# 	def SetCol(col)
+	# 		#Move position to a column
+	# 		@col = col;
+	# 		:x=10+:col*65;
+	# 		SetLeftMargin(x);
+	# 		SetX(x);
+	# 	end
+	#
+	# 	def AcceptPageBreak()
+	# 		if (@col<2)
+	# 			#Go to next column
+	# 			SetCol(@col+1);
+	# 			SetY(10);
+	# 			return false;
+	# 		end
+	# 		else
+	# 			#Go back to first column and issue page break
+	# 			SetCol(0);
+	# 			return true;
+	# 		end
+	# 	end
+	# }
+	#
+	# :pdf=new PDF();
+	# :pdf->Open();
+	# :pdf->AddPage();
+	# :pdf->SetFont('Arial','',12);
+	# for(i=1;:i<=300;:i++)
+	#     :pdf->Cell(0,5,"Line :i",0,1);
+	# }
+	# :pdf->Output();
+	# </pre>
+	# @return boolean
+	# @since 1.4
+	# @see SetAutoPageBreak()
+	#
+	def AcceptPageBreak()
+		#Accept automatic page break or not
+		return @auto_page_break;
+	end
+  alias_method :accept_page_break, :AcceptPageBreak
+
+  def BreakThePage?(h)
+		if ((@y + h) > @page_break_trigger and !@in_footer and AcceptPageBreak())
+      true
+    else
+      false
+    end
+  end
+  alias_method :break_the_page?, :BreakThePage?
+	#
+	# Prints a cell (rectangular area) with optional borders, background color and character string. The upper-left corner of the cell corresponds to the current position. The text can be aligned or centered. After the call, the current position moves to the right or to the next line. It is possible to put a link on the text.<br />
+	# If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.
+	# @param float :w Cell width. If 0, the cell extends up to the right margin.
+	# @param float :h Cell height. Default value: 0.
+	# @param string :txt String to print. Default value: empty string.
+	# @param mixed :border Indicates if borders must be drawn around the cell. The value can be either a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul>
+	# @param int :ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>
+	# Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
+	# @param string :align Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align (default value)</li><li>C: center</li><li>R: right align</li></ul>
+	# @param int :fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
+	# @param mixed :link URL or identifier returned by AddLink().
+	# @since 1.0
+	# @see SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), AddLink(), Ln(), MultiCell(), Write(), SetAutoPageBreak()
+	#
+	def Cell(w, h=0, txt='', border=0, ln=0, align='', fill=0, link=nil)
+		#Output a cell
+		k=@k;
+		if ((@y + h) > @page_break_trigger and !@in_footer and AcceptPageBreak())
+			#Automatic page break
+			if @pages[@page+1].nil?
+				x = @x;
+				ws = @ws;
+				if (ws > 0)
+					@ws = 0;
+					out('0 Tw');
+				end
+				AddPage(@cur_orientation);
+				@x = x;
+				if (ws > 0)
+					@ws = ws;
+					out(sprintf('%.3f Tw', ws * k));
+				end
+			else
+				@page += 1;
+				@y=@t_margin;
+			end
+		end
+
+		if (w == 0)
+			w = @w - @r_margin - @x;
+		end
+		s = '';
+		if ((fill.to_i == 1) or (border.to_i == 1))
+			if (fill.to_i == 1)
+				op = (border.to_i == 1) ? 'B' : 'f';
+			else
+				op = 'S';
+			end
+			s = sprintf('%.2f %.2f %.2f %.2f re %s ', @x * k, (@h - @y) * k, w * k, -h * k, op);
+		end
+		if (border.is_a?(String))
+			x=@x;
+			y=@y;
+			if (border.include?('L'))
+				s<<sprintf('%.2f %.2f m %.2f %.2f l S ', x*k,(@h-y)*k, x*k,(@h-(y+h))*k);
+			end
+			if (border.include?('T'))
+				s<<sprintf('%.2f %.2f m %.2f %.2f l S ', x*k,(@h-y)*k,(x+w)*k,(@h-y)*k);
+			end
+			if (border.include?('R'))
+				s<<sprintf('%.2f %.2f m %.2f %.2f l S ',(x+w)*k,(@h-y)*k,(x+w)*k,(@h-(y+h))*k);
+			end
+			if (border.include?('B'))
+				s<<sprintf('%.2f %.2f m %.2f %.2f l S ', x*k,(@h-(y+h))*k,(x+w)*k,(@h-(y+h))*k);
+			end
+		end
+		if (txt != '')
+			width = GetStringWidth(txt);
+			if (align == 'R' || align == 'right')
+				dx = w - @c_margin - width;
+			elsif (align=='C' || align == 'center')
+				dx = (w - width)/2;
+			else
+				dx = @c_margin;
+			end
+			if (@color_flag)
+				s << 'q ' + @text_color + ' ';
+			end
+			txt2 = escapetext(txt);
+			s<<sprintf('BT %.2f %.2f Td (%s) Tj ET', (@x + dx) * k, (@h - (@y + 0.5 * h + 0.3 * @font_size)) * k, txt2);
+			if (@underline)
+				s<<' ' + dolinetxt(@x + dx, @y + 0.5 * h + 0.3 * @font_size, txt);
+			end
+			if (@deleted)
+				s<<' ' + dolinetxt(@x + dx, @y + 0.3 * h + 0.2 * @font_size, txt);
+			end
+			if (@color_flag)
+				s<<' Q';
+			end
+			if link && !link.empty?
+				Link(@x + dx, @y + 0.5 * h - 0.5 * @font_size, width, @font_size, link);
+			end
+		end
+		if (s)
+			out(s);
+		end
+		@lasth = h;
+		if (ln.to_i>0)
+			# Go to next line
+			@y += h;
+			if (ln == 1)
+				@x = @l_margin;
+			end
+		else
+			@x += w;
+		end
+	end
+  alias_method :cell, :Cell
+
+	#
+	# This method allows printing text with line breaks. They can be automatic (as soon as the text reaches the right border of the cell) or explicit (via the \n character). As many cells as necessary are output, one below the other.<br />
+	# Text can be aligned, centered or justified. The cell block can be framed and the background painted.
+	# @param float :w Width of cells. If 0, they extend up to the right margin of the page.
+	# @param float :h Height of cells.
+	# @param string :txt String to print
+	# @param mixed :border Indicates if borders must be drawn around the cell block. The value can be either a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul>
+	# @param string :align Allows to center or align the text. Possible values are:<ul><li>L or empty string: left align</li><li>C: center</li><li>R: right align</li><li>J: justification (default value)</li></ul>
+	# @param int :fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
+	# @param int :ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right</li><li>1: to the beginning of the next line [DEFAULT]</li><li>2: below</li></ul>
+	# @since 1.3
+	# @see SetFont(), SetDrawColor(), SetFillColor(), SetTextColor(), SetLineWidth(), Cell(), Write(), SetAutoPageBreak()
+	#
+	def MultiCell(w, h, txt, border=0, align='J', fill=0, ln=1)
+		
+		# save current position
+		prevx = @x;
+		prevy = @y;
+		prevpage = @page;
+		 
+		#Output text with automatic or explicit line breaks
+
+		if (w == 0)
+			w = @w - @r_margin - @x;
+		end
+
+		wmax = (w - 3 * @c_margin);
+
+		s = txt.gsub("\r", ''); # remove carriage returns
+		nb = s.length;
+
+		b=0;
+		if (border)
+			if (border==1)
+				border='LTRB';
+				b='LRT';
+				b2='LR';
+			elsif border.is_a?(String)
+				b2='';
+				if (border.include?('L'))
+					b2<<'L';
+				end
+				if (border.include?('R'))
+					b2<<'R';
+				end
+				b=(border.include?('T')) ? b2 + 'T' : b2;
+			end
+		end
+		sep=-1;
+		to_index=0;
+		from_j=0;
+		l=0;
+		ns=0;
+		nl=1;
+		
+		while to_index < nb
+			#Get next character
+			c = s[to_index];
+			if c == "\n"[0]
+				#Explicit line break
+				if @ws > 0
+					@ws = 0
+					out('0 Tw')
+				end
+        #Ed Moss - change begin            
+        end_i = to_index == 0 ? 0 : to_index - 1
+        # Changed from s[from_j..to_index] to fix bug reported by Hans Allis.
+        from_j = to_index == 0 ? 1 : from_j 
+        Cell(w, h, s[from_j..end_i], b, 2, align, fill) 
+        #change end
+				to_index += 1
+				sep=-1
+        from_j=to_index
+				l=0
+				ns=0
+				nl += 1
+				b = b2 if border and nl==2
+				next
+			end
+			if (c == " "[0])
+				sep = to_index;
+				ls = l;
+				ns += 1;
+			end
+
+			l = GetStringWidth(s[from_j, to_index - from_j]);
+
+			if (l > wmax)
+				#Automatic line break
+				if (sep == -1)
+					if (to_index == from_j)
+						to_index += 1;
+					end
+					if (@ws > 0)
+						@ws = 0;
+						out('0 Tw');
+					end
+          Cell(w, h, s[from_j..to_index-1], b, 2, align, fill) # my FPDF version
+				else
+					if (align=='J' || align=='justify' || align=='justified')
+						@ws = (ns>1) ? (wmax-ls)/(ns-1) : 0;
+						out(sprintf('%.3f Tw', @ws * @k));
+					end
+					Cell(w, h, s[from_j..sep], b, 2, align, fill);
+					to_index = sep + 1;
+				end
+				sep=-1;
+				from_j = to_index;
+				l=0;
+				ns=0;
+				nl += 1;
+				if (border and (nl==2))
+					b = b2;
+				end
+			else
+				to_index += 1;
+			end
+		end
+		#Last chunk
+		if (@ws>0)
+			@ws=0;
+			out('0 Tw');
+		end
+		if (border.is_a?(String) and border.include?('B'))
+			b<<'B';
+		end
+		Cell(w, h, s[from_j, to_index-from_j], b, 2, align, fill);
+		
+		# move cursor to specified position
+		# since 2007-03-03
+		if (ln == 1)
+			# go to the beginning of the next line
+			@x = @l_margin;
+		elsif (ln == 0)
+			# go to the top-right of the cell
+			@page = prevpage;
+			@y = prevy;
+			@x = prevx + w;
+		elsif (ln == 2)
+			# go to the bottom-left of the cell
+			@x = prevx;
+		end
+	end
+  alias_method :multi_cell, :MultiCell
+
+	#
+	# This method prints text from the current position. When the right margin is reached (or the \n character is met) a line break occurs and text continues from the left margin. Upon method exit, the current position is left just at the end of the text. It is possible to put a link on the text.<br />
+	# <b>Example:</b><br />
+	# <pre>
+	# #Begin with regular font
+	# :pdf->SetFont('Arial','',14);
+	# :pdf->Write(5,'Visit ');
+	# #Then put a blue underlined link
+	# :pdf->SetTextColor(0,0,255);
+	# :pdf->SetFont('','U');
+	# :pdf->Write(5,'www.tecnick.com','http://www.tecnick.com');
+	# </pre>
+	# @param float :h Line height
+	# @param string :txt String to print
+	# @param mixed :link URL or identifier returned by AddLink()
+	# @param int :fill Indicates if the background must be painted (1) or transparent (0). Default value: 0.
+	# @since 1.5
+	# @see SetFont(), SetTextColor(), AddLink(), MultiCell(), SetAutoPageBreak()
+	#
+	def Write(h, txt, link=nil, fill=0)
+
+		#Output text in flowing mode
+		w = @w - @r_margin - @x;
+		wmax = (w - 3 * @c_margin);
+    
+		s = txt.gsub("\r", '');
+		nb = s.length;
+
+		# handle single space character
+		if ((nb==1) and (s == " "))
+			@x += GetStringWidth(s);
+			return;
+		end
+
+		sep=-1;
+		i=0;
+		j=0;
+		l=0;
+		nl=1;
+		while(i<nb)
+			#Get next character
+			c = s[i];
+			if (c == "\n"[0])
+				#Explicit line break
+				Cell(w, h, s[j,i-j], 0, 2, '', fill, link);
+				i += 1;
+				sep = -1;
+				j = i;
+				l = 0;
+				if (nl == 1)
+					@x = @l_margin;
+					w = @w - @r_margin - @x;
+					wmax = (w - 3 * @c_margin);
+				end
+				nl += 1;
+				next
+			end
+			if (c == " "[0])
+				sep= i;
+			end
+			l = GetStringWidth(s[j, i - j]);
+			if (l > wmax)
+				#Automatic line break (word wrapping)
+				if (sep == -1)
+					if (@x > @l_margin)
+						#Move to next line
+						@x = @l_margin;
+						@y += h;
+						w=@w - @r_margin - @x;
+						wmax=(w - 3 * @c_margin);
+						i += 1
+						nl += 1
+						next
+					end
+					if (i == j)
+						i += 1
+					end
+					Cell(w, h, s[j, (i-1)], 0, 2, '', fill, link);
+				else
+					Cell(w, h, s[j, (sep-j)], 0, 2, '', fill, link);
+					i = sep+1;
+				end
+				sep = -1;
+				j = i;
+				l = 0;
+				if (nl==1)
+					@x = @l_margin;
+					w = @w - @r_margin - @x;
+					wmax = (w - 3 * @c_margin);
+				end
+				nl += 1;
+			else
+				i += 1;
+			end
+		end
+		#Last chunk
+		if (i != j)
+			Cell(GetStringWidth(s[j..i]), h, s[j..i], 0, 0, '', fill, link);
+		end
+	end
+  alias_method :write, :Write
+
+	#
+	# Puts an image in the page. The upper-left corner must be given. The dimensions can be specified in different ways:<ul><li>explicit width and height (expressed in user unit)</li><li>one explicit dimension, the other being calculated automatically in order to keep the original proportions</li><li>no explicit dimension, in which case the image is put at 72 dpi</li></ul>
+	# Supported formats are JPEG and PNG.
+	# For JPEG, all flavors are allowed:<ul><li>gray scales</li><li>true colors (24 bits)</li><li>CMYK (32 bits)</li></ul>
+	# For PNG, are allowed:<ul><li>gray scales on at most 8 bits (256 levels)</li><li>indexed colors</li><li>true colors (24 bits)</li></ul>
+	# but are not supported:<ul><li>Interlacing</li><li>Alpha channel</li></ul>
+	# If a transparent color is defined, it will be taken into account (but will be only interpreted by Acrobat 4 and above).<br />
+	# The format can be specified explicitly or inferred from the file extension.<br />
+	# It is possible to put a link on the image.<br />
+	# Remark: if an image is used several times, only one copy will be embedded in the file.<br />
+	# @param string :file Name of the file containing the image.
+	# @param float :x Abscissa of the upper-left corner.
+	# @param float :y Ordinate of the upper-left corner.
+	# @param float :w Width of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	# @param float :h Height of the image in the page. If not specified or equal to zero, it is automatically calculated.
+	# @param string :type Image format. Possible values are (case insensitive): JPG, JPEG, PNG. If not specified, the type is inferred from the file extension.
+	# @param mixed :link URL or identifier returned by AddLink().
+	# @since 1.1
+	# @see AddLink()
+	#
+	def Image(file, x, y, w=0, h=0, type='', link=nil)
+		#Put an image on the page
+		if (@images[file].nil?)
+			#First use of image, get info
+			if (type == '')
+				pos = File::basename(file).rindex('.');
+				if (pos.nil? or pos == 0)
+					Error('Image file has no extension and no type was specified: ' + file);
+				end
+				pos = file.rindex('.');
+				type = file[pos+1..-1];
+			end
+			type.downcase!
+			if (type == 'jpg' or type == 'jpeg')
+				info=parsejpg(file);
+			elsif (type == 'png')
+				info=parsepng(file);
+			elsif (type == 'gif')
+			  tmpFile = imageToPNG(file);
+				info=parsepng(tmpFile.path);
+				tmpFile.delete
+			else
+				#Allow for additional formats
+				mtd='parse' + type;
+				if (!self.respond_to?(mtd))
+					Error('Unsupported image type: ' + type);
+				end
+				info=send(mtd, file);
+			end
+			info['i']=@images.length+1;
+			@images[file] = info;
+		else
+			info=@images[file];
+		end
+		#Automatic width and height calculation if needed
+		if ((w == 0) and (h == 0))
+			rescale_x = (@w - @r_margin - x) / (info['w'] / (@img_scale * @k)) 
+			rescale_x = 1 if rescale_x >= 1 
+			if (y + info['h'] * rescale_x / (@img_scale * @k) > @page_break_trigger and !@in_footer and AcceptPageBreak())
+				#Automatic page break
+				if @pages[@page+1].nil?
+					ws = @ws;
+					if (ws > 0)
+						@ws = 0;
+						out('0 Tw');
+					end
+					AddPage(@cur_orientation);
+					if (ws > 0)
+						@ws = ws;
+						out(sprintf('%.3f Tw', ws * @k));
+					end
+				else
+					@page += 1;
+				end
+				y=@t_margin;
+			end
+			rescale_y = (@page_break_trigger - y) / (info['h'] / (@img_scale * @k)) 
+			rescale_y = 1 if rescale_y >= 1 
+			rescale = rescale_y >= rescale_x ? rescale_x : rescale_y
+
+			#Put image at 72 dpi
+			# 2004-06-14 :: Nicola Asuni, scale factor where added
+			w = info['w'] * rescale / (@img_scale * @k);
+			h = info['h'] * rescale / (@img_scale * @k);
+		elsif (w == 0)
+			w = h * info['w'] / info['h'];
+		elsif (h == 0)
+			h = w * info['h'] / info['w'];
+		end
+		out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q', w*@k, h*@k, x*@k, (@h-(y+h))*@k, info['i']));
+		if (link)
+			Link(x, y, w, h, link);
+		end
+
+		#2002-07-31 - Nicola Asuni
+		# set right-bottom corner coordinates
+		@img_rb_x = x + w;
+		@img_rb_y = y + h;
+	end
+  alias_method :image, :Image
+
+	#
+	# Performs a line break. The current abscissa goes back to the left margin and the ordinate increases by the amount passed in parameter.
+	# @param float :h The height of the break. By default, the value equals the height of the last printed cell.
+	# @since 1.0
+	# @see Cell()
+	#
+	def Ln(h='')
+		#Line feed; default value is last cell height
+		@x=@l_margin;
+		if (h.is_a?(String))
+			@y += @lasth;
+		else
+			@y += h;
+		end
+
+		k=@k;
+		if (@y > @page_break_trigger and !@in_footer and AcceptPageBreak())
+			#Automatic page break
+			if @pages[@page+1].nil?
+				x = @x;
+				ws = @ws;
+				if (ws > 0)
+					@ws = 0;
+					out('0 Tw');
+				end
+				AddPage(@cur_orientation);
+				@x = x;
+				if (ws > 0)
+					@ws = ws;
+					out(sprintf('%.3f Tw', ws * k));
+				end
+			else
+				@page += 1;
+				@y=@t_margin;
+			end
+		end
+
+	end
+  alias_method :ln, :Ln
+
+	#
+	# Returns the abscissa of the current position.
+	# @return float
+	# @since 1.2
+	# @see SetX(), GetY(), SetY()
+	#
+	def GetX()
+		#Get x position
+		return @x;
+	end
+  alias_method :get_x, :GetX
+
+	#
+	# Defines the abscissa of the current position. If the passed value is negative, it is relative to the right of the page.
+	# @param float :x The value of the abscissa.
+	# @since 1.2
+	# @see GetX(), GetY(), SetY(), SetXY()
+	#
+	def SetX(x)
+		#Set x position
+		if (x>=0)
+			@x = x;
+		else
+			@x=@w+x;
+		end
+	end
+  alias_method :set_x, :SetX
+
+	#
+	# Returns the ordinate of the current position.
+	# @return float
+	# @since 1.0
+	# @see SetY(), GetX(), SetX()
+	#
+	def GetY()
+		#Get y position
+		return @y;
+	end
+  alias_method :get_y, :GetY
+
+	#
+	# Moves the current abscissa back to the left margin and sets the ordinate. If the passed value is negative, it is relative to the bottom of the page.
+	# @param float :y The value of the ordinate.
+	# @since 1.0
+	# @see GetX(), GetY(), SetY(), SetXY()
+	#
+	def SetY(y)
+		#Set y position and reset x
+		@x=@l_margin;
+		if (y>=0)
+			@y = y;
+		else
+			@y=@h+y;
+		end
+	end
+  alias_method :set_y, :SetY
+
+	#
+	# Defines the abscissa and ordinate of the current position. If the passed values are negative, they are relative respectively to the right and bottom of the page.
+	# @param float :x The value of the abscissa
+	# @param float :y The value of the ordinate
+	# @since 1.2
+	# @see SetX(), SetY()
+	#
+	def SetXY(x, y)
+		#Set x and y positions
+		SetY(y);
+		SetX(x);
+	end
+  alias_method :set_xy, :SetXY
+
+	#
+	# Send the document to a given destination: string, local file or browser. In the last case, the plug-in may be used (if present) or a download ("Save as" dialog box) may be forced.<br />
+	# The method first calls Close() if necessary to terminate the document.
+	# @param string :name The name of the file. If not given, the document will be sent to the browser (destination I) with the name doc.pdf.
+	# @param string :dest Destination where to send the document. It can take one of the following values:<ul><li>I: send the file inline to the browser. The plug-in is used if available. The name given by name is used when one selects the "Save as" option on the link generating the PDF.</li><li>D: send to the browser and force a file download with the name given by name.</li><li>F: save to a local file with the name given by name.</li><li>S: return the document as a string. name is ignored.</li></ul>If the parameter is not specified but a name is given, destination is F. If no parameter is specified at all, destination is I.<br />
+	# @since 1.0
+	# @see Close()
+	#
+	def Output(name='', dest='')
+		#Output PDF to some destination
+		#Finish document if necessary
+		if (@state < 3)
+			Close();
+		end
+		#Normalize parameters
+		# Boolean no longer supported
+		# if (dest.is_a?(Boolean))
+		# 	dest = dest ? 'D' : 'F';
+		# end
+		dest = dest.upcase
+		if (dest=='')
+			if (name=='')
+				name='doc.pdf';
+				dest='I';
+			else
+				dest='F';
+			end
+		end
+		case (dest)
+			when 'I'
+			  # This is PHP specific code
+				##Send to standard output
+				# if (ob_get_contents())
+				# 	Error('Some data has already been output, can\'t send PDF file');
+				# end
+				# if (php_sapi_name()!='cli')
+				# 	#We send to a browser
+				# 	header('Content-Type: application/pdf');
+				# 	if (headers_sent())
+				# 		Error('Some data has already been output to browser, can\'t send PDF file');
+				# 	end
+				# 	header('Content-Length: ' + @buffer.length);
+				# 	header('Content-disposition: inline; filename="' + name + '"');
+				# end
+				return @buffer;
+				
+			when 'D'
+			  # PHP specific
+				#Download file
+				# if (ob_get_contents())
+				# 	Error('Some data has already been output, can\'t send PDF file');
+				# end
+				# if (!_SERVER['HTTP_USER_AGENT'].nil? && SERVER['HTTP_USER_AGENT'].include?('MSIE'))
+				# 	header('Content-Type: application/force-download');
+				# else
+				# 	header('Content-Type: application/octet-stream');
+				# end
+				# if (headers_sent())
+				# 	Error('Some data has already been output to browser, can\'t send PDF file');
+				# end
+				# header('Content-Length: '+ @buffer.length);
+				# header('Content-disposition: attachment; filename="' + name + '"');
+				return @buffer;
+				
+			when 'F'
+        open(name,'wb') do |f|
+          f.write(@buffer)
+        end
+			   # PHP code
+			   # 				#Save to local file
+			   # 				f=open(name,'wb');
+			   # 				if (!f)
+			   # 					Error('Unable to create output file: ' + name);
+			   # 				end
+			   # 				fwrite(f,@buffer,@buffer.length);
+			   # 				f.close
+				
+			when 'S'
+				#Return as a string
+				return @buffer;
+			else
+				Error('Incorrect output destination: ' + dest);
+			
+		end
+		return '';
+	end
+  alias_method :output, :Output
+
+	# Protected methods
+
+	#
+	# Check for locale-related bug
+	# @access protected
+	#
+	def dochecks()
+		#Check for locale-related bug
+		if (1.1==1)
+			Error('Don\'t alter the locale before including class file');
+		end
+		#Check for decimal separator
+		if (sprintf('%.1f',1.0)!='1.0')
+			setlocale(LC_NUMERIC,'C');
+		end
+	end
+
+	#
+	# Return fonts path
+	# @access protected
+	#
+	def getfontpath(file)
+    # Is it in the @@font_path?
+    if @@font_path
+  		fpath = File.join @@font_path, file
+  	  if File.exists?(fpath)
+  	    return fpath
+      end
+    end
+    # Is it in this plugin's font folder?
+		fpath = File.join File.dirname(__FILE__), 'fonts', file
+	  if File.exists?(fpath)
+	    return fpath
+    end
+    # Could not find it.
+    nil
+	end
+
+	#
+	# Start document
+	# @access protected
+	#
+	def begindoc()
+		#Start document
+		@state=1;
+		out('%PDF-1.3');
+	end
+
+	#
+	# putpages
+	# @access protected
+	#
+	def putpages()
+		nb = @page;
+		if (@alias_nb_pages)
+			nbstr = UTF8ToUTF16BE(nb.to_s, false);
+			#Replace number of pages
+			1.upto(nb) do |n|
+				@pages[n].gsub!(@alias_nb_pages, nbstr)
+			end
+		end
+		if @def_orientation=='P'
+			w_pt=@fw_pt
+			h_pt=@fh_pt
+		else
+			w_pt=@fh_pt
+			h_pt=@fw_pt
+		end
+		filter=(@compress) ? '/Filter /FlateDecode ' : ''
+		1.upto(nb) do |n|
+			#Page
+			newobj
+			out('<</Type /Page')
+			out('/Parent 1 0 R')
+			unless @orientation_changes[n].nil?
+				out(sprintf('/MediaBox [0 0 %.2f %.2f]', h_pt, w_pt))
+			end
+			out('/Resources 2 0 R')
+			if @page_links[n]
+				#Links
+				annots='/Annots ['
+				@page_links[n].each do |pl|
+					rect=sprintf('%.2f %.2f %.2f %.2f', pl[0], pl[1], pl[0]+pl[2], pl[1]-pl[3]);
+					annots<<'<</Type /Annot /Subtype /Link /Rect [' + rect + '] /Border [0 0 0] ';
+					if (pl[4].is_a?(String))
+						annots<<'/A <</S /URI /URI (' + escape(pl[4]) + ')>>>>';
+					else
+						l=@links[pl[4]];
+						h=!@orientation_changes[l[0]].nil? ? w_pt : h_pt;
+						annots<<sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*l[0], h-l[1]*@k);
+					end
+				end
+				out(annots + ']');
+			end
+			out('/Contents ' + (@n+1).to_s + ' 0 R>>');
+			out('endobj');
+			#Page content
+			p=(@compress) ? gzcompress(@pages[n]) : @pages[n];
+			newobj();
+			out('<<' + filter + '/Length '+ p.length.to_s + '>>');
+			putstream(p);
+			out('endobj');
+		end
+		#Pages root
+		@offsets[1]=@buffer.length;
+		out('1 0 obj');
+		out('<</Type /Pages');
+		kids='/Kids [';
+		0.upto(nb) do |i|
+			kids<<(3+2*i).to_s + ' 0 R ';
+		end
+		out(kids + ']');
+		out('/Count ' + nb.to_s);
+		out(sprintf('/MediaBox [0 0 %.2f %.2f]', w_pt, h_pt));
+		out('>>');
+		out('endobj');
+	end
+
+	#
+	# Adds fonts
+	# putfonts
+	# @access protected
+	#
+	def putfonts()
+		nf=@n;
+		@diffs.each do |diff|
+			#Encodings
+			newobj();
+			out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [' + diff + ']>>');
+			out('endobj');
+		end
+		@font_files.each do |file, info|
+			#Font file embedding
+			newobj();
+			@font_files[file]['n']=@n;
+			font='';
+			open(getfontpath(file),'rb') do |f|
+				font = f.read();
+			end
+			compressed=(file[-2,2]=='.z');
+			if (!compressed && !info['length2'].nil?)
+				header=((font[0][0])==128);
+				if (header)
+					#Strip first binary header
+					font=font[6];
+				end
+				if header && (font[info['length1']][0] == 128)
+					#Strip second binary header
+					font=font[0..info['length1']] + font[info['length1']+6];
+				end
+			end
+			out('<</Length '+ font.length.to_s);
+			if (compressed)
+				out('/Filter /FlateDecode');
+			end
+			out('/Length1 ' + info['length1'].to_s);
+			if (!info['length2'].nil?)
+				out('/Length2 ' + info['length2'].to_s + ' /Length3 0');
+			end
+			out('>>');
+			open(getfontpath(file),'rb') do |f|
+        putstream(font)
+      end
+			out('endobj');
+		end
+		@fonts.each do |k, font|
+			#Font objects
+			@fonts[k]['n']=@n+1;
+			type = font['type'];
+			name = font['name'];
+			if (type=='core')
+				#Standard font
+				newobj();
+				out('<</Type /Font');
+				out('/BaseFont /' + name);
+				out('/Subtype /Type1');
+				if (name!='Symbol' && name!='ZapfDingbats')
+					out('/Encoding /WinAnsiEncoding');
+				end
+				out('>>');
+				out('endobj');
+    	elsif type == 'Type0'
+    		putType0(font)
+			elsif (type=='Type1' || type=='TrueType')
+				#Additional Type1 or TrueType font
+				newobj();
+				out('<</Type /Font');
+				out('/BaseFont /' + name);
+				out('/Subtype /' + type);
+				out('/FirstChar 32 /LastChar 255');
+				out('/Widths ' + (@n+1).to_s + ' 0 R');
+				out('/FontDescriptor ' + (@n+2).to_s + ' 0 R');
+				if (font['enc'])
+					if (!font['diff'].nil?)
+						out('/Encoding ' + (nf+font['diff']).to_s + ' 0 R');
+					else
+						out('/Encoding /WinAnsiEncoding');
+					end
+				end
+				out('>>');
+				out('endobj');
+				#Widths
+				newobj();
+				cw=font['cw']; # &
+				s='[';
+				32.upto(255) do |i|
+					s << cw[i.chr] + ' ';
+				end
+				out(s + ']');
+				out('endobj');
+				#Descriptor
+				newobj();
+				s='<</Type /FontDescriptor /FontName /' + name;
+				font['desc'].each do |k, v|
+					s<<' /' + k + ' ' + v;
+				end
+				file = font['file'];
+				if (file)
+					s<<' /FontFile' + (type=='Type1' ? '' : '2') + ' ' + @font_files[file]['n'] + ' 0 R';
+				end
+				out(s + '>>');
+				out('endobj');
+			else
+				#Allow for additional types
+				mtd='put' + type.downcase;
+				if (!self.respond_to?(mtd))
+					Error('Unsupported font type: ' + type)
+				else
+  				self.send(mtd,font)
+				end
+			end
+		end
+	end
+
+  def putType0(font)
+  	#Type0
+		newobj();
+		out('<</Type /Font')
+  	out('/Subtype /Type0')
+  	out('/BaseFont /'+font['name']+'-'+font['cMap'])
+  	out('/Encoding /'+font['cMap'])
+  	out('/DescendantFonts ['+(@n+1).to_s+' 0 R]')
+  	out('>>')
+  	out('endobj')
+  	#CIDFont
+  	newobj()
+  	out('<</Type /Font')
+  	out('/Subtype /CIDFontType0')
+  	out('/BaseFont /'+font['name'])
+  	out('/CIDSystemInfo <</Registry (Adobe) /Ordering ('+font['registry']['ordering']+') /Supplement '+font['registry']['supplement'].to_s+'>>')
+  	out('/FontDescriptor '+(@n+1).to_s+' 0 R')
+  	w='/W [1 ['
+		font['cw'].keys.sort.each {|key|
+		  w+=font['cw'][key].to_s + " "
+# ActionController::Base::logger.debug key.to_s
+# ActionController::Base::logger.debug font['cw'][key].to_s
+		}
+  	out(w+'] 231 325 500 631 [500] 326 389 500]')
+  	out('>>')
+  	out('endobj')
+  	#Font descriptor
+  	newobj()
+  	out('<</Type /FontDescriptor')
+  	out('/FontName /'+font['name'])
+  	out('/Flags 6')
+  	out('/FontBBox [0 -200 1000 900]')
+  	out('/ItalicAngle 0')
+  	out('/Ascent 800')
+  	out('/Descent -200')
+  	out('/CapHeight 800')
+  	out('/StemV 60')
+  	out('>>')
+  	out('endobj')
+  end
+
+	#
+	# putimages
+	# @access protected
+	#
+	def putimages()
+		filter=(@compress) ? '/Filter /FlateDecode ' : '';
+		@images.each do |file, info| # was while(list(file, info)=each(@images))
+			newobj();
+			@images[file]['n']=@n;
+			out('<</Type /XObject');
+			out('/Subtype /Image');
+			out('/Width ' + info['w'].to_s);
+			out('/Height ' + info['h'].to_s);
+			if (info['cs']=='Indexed')
+				out('/ColorSpace [/Indexed /DeviceRGB ' + (info['pal'].length/3-1).to_s + ' ' + (@n+1).to_s + ' 0 R]');
+			else
+				out('/ColorSpace /' + info['cs']);
+				if (info['cs']=='DeviceCMYK')
+					out('/Decode [1 0 1 0 1 0 1 0]');
+				end
+			end
+			out('/BitsPerComponent ' + info['bpc'].to_s);
+			if (!info['f'].nil?)
+				out('/Filter /' + info['f']);
+			end
+			if (!info['parms'].nil?)
+				out(info['parms']);
+			end
+			if (!info['trns'].nil? and info['trns'].kind_of?(Array))
+				trns='';
+				0.upto(info['trns'].length) do |i|
+					trns << ("#{info['trns'][i]} " * 2);
+				end
+				out('/Mask [' + trns + ']');
+			end
+			out('/Length ' + info['data'].length.to_s + '>>');
+			putstream(info['data']);
+      @images[file]['data']=nil
+			out('endobj');
+			#Palette
+			if (info['cs']=='Indexed')
+				newobj();
+				pal=(@compress) ? gzcompress(info['pal']) : info['pal'];
+				out('<<' + filter + '/Length ' + pal.length.to_s + '>>');
+				putstream(pal);
+				out('endobj');
+			end
+		end
+	end
+
+	#
+	# putxobjectdict
+	# @access protected
+	#
+	def putxobjectdict()
+		@images.each_value do |image|
+			out('/I' + image['i'].to_s + ' ' + image['n'].to_s + ' 0 R');
+		end
+	end
+
+	#
+	# putresourcedict
+	# @access protected
+	#
+	def putresourcedict()
+		out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
+		out('/Font <<');
+		@fonts.each_value do |font|
+			out('/F' + font['i'].to_s + ' ' + font['n'].to_s + ' 0 R');
+		end
+		out('>>');
+		out('/XObject <<');
+		putxobjectdict();
+		out('>>');
+	end
+
+	#
+	# putresources
+	# @access protected
+	#
+	def putresources()
+		putfonts();
+		putimages();
+		#Resource dictionary
+		@offsets[2]=@buffer.length;
+		out('2 0 obj');
+		out('<<');
+		putresourcedict();
+		out('>>');
+		out('endobj');
+	end
+	
+	#
+	# putinfo
+	# @access protected
+	#
+	def putinfo()
+		out('/Producer ' + textstring(PDF_PRODUCER));
+		if (!@title.nil?)
+			out('/Title ' + textstring(@title));
+		end
+		if (!@subject.nil?)
+			out('/Subject ' + textstring(@subject));
+		end
+		if (!@author.nil?)
+			out('/Author ' + textstring(@author));
+		end
+		if (!@keywords.nil?)
+			out('/Keywords ' + textstring(@keywords));
+		end
+		if (!@creator.nil?)
+			out('/Creator ' + textstring(@creator));
+		end
+		out('/CreationDate ' + textstring('D:' + Time.now.strftime('%Y%m%d%H%M%S')));
+	end
+
+	#
+	# putcatalog
+	# @access protected
+	#
+	def putcatalog()
+		out('/Type /Catalog');
+		out('/Pages 1 0 R');
+		if (@zoom_mode=='fullpage')
+			out('/OpenAction [3 0 R /Fit]');
+		elsif (@zoom_mode=='fullwidth')
+			out('/OpenAction [3 0 R /FitH null]');
+		elsif (@zoom_mode=='real')
+			out('/OpenAction [3 0 R /XYZ null null 1]');
+		elsif (!@zoom_mode.is_a?(String))
+			out('/OpenAction [3 0 R /XYZ null null ' + (@zoom_mode/100) + ']');
+		end
+		if (@layout_mode=='single')
+			out('/PageLayout /SinglePage');
+		elsif (@layout_mode=='continuous')
+			out('/PageLayout /OneColumn');
+		elsif (@layout_mode=='two')
+			out('/PageLayout /TwoColumnLeft');
+		end
+	end
+
+	#
+	# puttrailer
+	# @access protected
+	#
+	def puttrailer()
+		out('/Size ' + (@n+1).to_s);
+		out('/Root ' + @n.to_s + ' 0 R');
+		out('/Info ' + (@n-1).to_s + ' 0 R');
+	end
+
+	#
+	# putheader
+	# @access protected
+	#
+	def putheader()
+		out('%PDF-' + @pdf_version);
+	end
+
+	#
+	# enddoc
+	# @access protected
+	#
+	def enddoc()
+		putheader();
+		putpages();
+		putresources();
+		#Info
+		newobj();
+		out('<<');
+		putinfo();
+		out('>>');
+		out('endobj');
+		#Catalog
+		newobj();
+		out('<<');
+		putcatalog();
+		out('>>');
+		out('endobj');
+		#Cross-ref
+		o=@buffer.length;
+		out('xref');
+		out('0 ' + (@n+1).to_s);
+		out('0000000000 65535 f ');
+		1.upto(@n) do |i|
+			out(sprintf('%010d 00000 n ',@offsets[i]));
+		end
+		#Trailer
+		out('trailer');
+		out('<<');
+		puttrailer();
+		out('>>');
+		out('startxref');
+		out(o);
+		out('%%EOF');
+		@state=3;
+	end
+
+	#
+	# beginpage
+	# @access protected
+	#
+	def beginpage(orientation)
+		@page += 1;
+		@pages[@page]='';
+		@state=2;
+		@x=@l_margin;
+		@y=@t_margin;
+		@font_family='';
+		#Page orientation
+		if (orientation.empty?)
+			orientation=@def_orientation;
+		else
+			orientation.upcase!
+			if (orientation!=@def_orientation)
+				@orientation_changes[@page]=true;
+			end
+		end
+		if (orientation!=@cur_orientation)
+			#Change orientation
+			if (orientation=='P')
+				@w_pt=@fw_pt;
+				@h_pt=@fh_pt;
+				@w=@fw;
+				@h=@fh;
+			else
+				@w_pt=@fh_pt;
+				@h_pt=@fw_pt;
+				@w=@fh;
+				@h=@fw;
+			end
+			@page_break_trigger=@h-@b_margin;
+			@cur_orientation = orientation;
+		end
+	end
+
+	#
+	# End of page contents
+	# @access protected
+	#
+	def endpage()
+		@state=1;
+	end
+
+	#
+	# Begin a new object
+	# @access protected
+	#
+	def newobj()
+		@n += 1;
+		@offsets[@n]=@buffer.length;
+		out(@n.to_s + ' 0 obj');
+	end
+
+	#
+	# Underline and Deleted text
+	# @access protected
+	#
+	def dolinetxt(x, y, txt)
+		up = @current_font['up'];
+		ut = @current_font['ut'];
+		w = GetStringWidth(txt) + @ws * txt.count(' ');
+		sprintf('%.2f %.2f %.2f %.2f re f', x * @k, (@h - (y - up / 1000.0 * @font_size)) * @k, w * @k, -ut / 1000.0 * @font_size_pt);
+	end
+
+	#
+	# Extract info from a JPEG file
+	# @access protected
+	#
+	def parsejpg(file)
+		a=getimagesize(file);
+		if (a.empty?)
+			Error('Missing or incorrect image file: ' + file);
+		end
+		if (!a[2].nil? and a[2]!='JPEG')
+			Error('Not a JPEG file: ' + file);
+		end
+		if (a['channels'].nil? or a['channels']==3)
+			colspace='DeviceRGB';
+		elsif (a['channels']==4)
+			colspace='DeviceCMYK';
+		else
+			colspace='DeviceGray';
+		end
+		bpc=!a['bits'].nil? ? a['bits'] : 8;
+		#Read whole file
+		data='';
+
+		open(file,'rb') do |f|
+			data<<f.read();
+		end
+
+		return {'w' => a[0],'h' => a[1],'cs' => colspace,'bpc' => bpc,'f'=>'DCTDecode','data' => data}
+	end
+
+	def imageToPNG(file)
+		return unless Object.const_defined?(:Magick)
+
+		img = Magick::ImageList.new(file)
+		img.format = 'PNG'	 # convert to PNG from gif 
+		img.opacity = 0			 # PNG alpha channel delete
+
+		#use a temporary file....
+		tmpFile = Tempfile.new(['', '_' + File::basename(file) + '.png'], @@k_path_cache);
+		tmpFile.binmode
+		tmpFile.print img.to_blob
+		tmpFile
+	ensure
+		tmpFile.close
+	end
+
+	#
+	# Extract info from a PNG file
+	# @access protected
+	#
+	def parsepng(file)
+		f=open(file,'rb');
+		#Check signature
+		if (f.read(8)!=137.chr + 'PNG' + 13.chr + 10.chr + 26.chr + 10.chr)
+			Error('Not a PNG file: ' + file);
+		end
+		#Read header chunk
+		f.read(4);
+		if (f.read(4)!='IHDR')
+			Error('Incorrect PNG file: ' + file);
+		end
+		w=freadint(f);
+		h=freadint(f);
+		bpc=f.read(1).unpack('C')[0];
+		if (bpc>8)
+			Error('16-bit depth not supported: ' + file);
+		end
+		ct=f.read(1).unpack('C')[0];
+		if (ct==0)
+			colspace='DeviceGray';
+		elsif (ct==2)
+			colspace='DeviceRGB';
+		elsif (ct==3)
+			colspace='Indexed';
+		else
+			Error('Alpha channel not supported: ' + file);
+		end
+		if (f.read(1).unpack('C')[0] != 0)
+			Error('Unknown compression method: ' + file);
+		end
+		if (f.read(1).unpack('C')[0] != 0)
+			Error('Unknown filter method: ' + file);
+		end
+		if (f.read(1).unpack('C')[0] != 0)
+			Error('Interlacing not supported: ' + file);
+		end
+		f.read(4);
+		parms='/DecodeParms <</Predictor 15 /Colors ' + (ct==2 ? 3 : 1).to_s + ' /BitsPerComponent ' + bpc.to_s + ' /Columns ' + w.to_s + '>>';
+		#Scan chunks looking for palette, transparency and image data
+		pal='';
+		trns='';
+		data='';
+		begin
+			n=freadint(f);
+			type=f.read(4);
+			if (type=='PLTE')
+				#Read palette
+				pal=f.read( n);
+				f.read(4);
+			elsif (type=='tRNS')
+				#Read transparency info
+				t=f.read( n);
+				if (ct==0)
+					trns = t[1].unpack('C')[0]
+				elsif (ct==2)
+					trns = t[[1].unpack('C')[0], t[3].unpack('C')[0], t[5].unpack('C')[0]]
+				else
+					pos=t.index(0.chr);
+					unless (pos.nil?)
+						trns = [pos]
+					end
+				end
+				f.read(4);
+			elsif (type=='IDAT')
+				#Read image data block
+				data<<f.read( n);
+				f.read(4);
+			elsif (type=='IEND')
+				break;
+			else
+				f.read( n+4);
+			end
+		end while(n)
+		if (colspace=='Indexed' and pal.empty?)
+			Error('Missing palette in ' + file);
+		end
+		return {'w' => w, 'h' => h, 'cs' => colspace, 'bpc' => bpc, 'f'=>'FlateDecode', 'parms' => parms, 'pal' => pal, 'trns' => trns, 'data' => data}
+	ensure
+		f.close
+	end
+
+	#
+	# Read a 4-byte integer from file
+	# @access protected
+	#
+	def freadint(f)
+    # Read a 4-byte integer from file
+    a = f.read(4).unpack('N')
+    return a[0]
+	end
+
+	#
+	# Format a text string
+	# @access protected
+	#
+	def textstring(s)
+		if (@is_unicode)
+			#Convert string to UTF-16BE
+			s = UTF8ToUTF16BE(s, true);
+		end
+		return '(' +  escape(s) + ')';
+	end
+
+	#
+	# Format a text string
+	# @access protected
+	#
+	def escapetext(s)
+		if (@is_unicode)
+			#Convert string to UTF-16BE
+			s = UTF8ToUTF16BE(s, false);
+		end
+		return escape(s);
+	end
+
+	#
+	# Add \ before \, ( and )
+	# @access protected
+	#
+	def escape(s)
+    # Add \ before \, ( and )
+    s.gsub('\\','\\\\\\').gsub('(','\\(').gsub(')','\\)').gsub(13.chr, '\r')
+	end
+
+	#
+	#
+	# @access protected
+	#
+	def putstream(s)
+		out('stream');
+		out(s);
+		out('endstream');
+	end
+
+	#
+	# Add a line to the document
+	# @access protected
+	#
+	def out(s)
+		if (@state==2)
+			@pages[@page] << s.to_s + "\n";
+		else
+			@buffer << s.to_s + "\n";
+		end
+	end
+
+	#
+	# Adds unicode fonts.<br>
+	# Based on PDF Reference 1.3 (section 5)
+	# @access protected
+	# @author Nicola Asuni
+	# @since 1.52.0.TC005 (2005-01-05)
+	#
+	def puttruetypeunicode(font)
+		# Type0 Font
+		# A composite font composed of other fonts, organized hierarchically
+		newobj();
+		out('<</Type /Font');
+		out('/Subtype /Type0');
+		out('/BaseFont /' + font['name'] + '');
+		out('/Encoding /Identity-H'); #The horizontal identity mapping for 2-byte CIDs; may be used with CIDFonts using any Registry, Ordering, and Supplement values.
+		out('/DescendantFonts [' + (@n + 1).to_s + ' 0 R]');
+		out('/ToUnicode ' + (@n + 2).to_s + ' 0 R');
+		out('>>');
+		out('endobj');
+		
+		# CIDFontType2
+		# A CIDFont whose glyph descriptions are based on TrueType font technology
+		newobj();
+		out('<</Type /Font');
+		out('/Subtype /CIDFontType2');
+		out('/BaseFont /' + font['name'] + '');
+		out('/CIDSystemInfo ' + (@n + 2).to_s + ' 0 R'); 
+		out('/FontDescriptor ' + (@n + 3).to_s + ' 0 R');
+		if (!font['desc']['MissingWidth'].nil?)
+			out('/DW ' + font['desc']['MissingWidth'].to_s + ''); # The default width for glyphs in the CIDFont MissingWidth
+		end
+		w = "";
+		font['cw'].each do |cid, width|
+			w << '' + cid.to_s + ' [' + width.to_s + '] '; # define a specific width for each individual CID
+		end
+		out('/W [' + w + ']'); # A description of the widths for the glyphs in the CIDFont
+		out('/CIDToGIDMap ' + (@n + 4).to_s + ' 0 R');
+		out('>>');
+		out('endobj');
+		
+		# ToUnicode
+		# is a stream object that contains the definition of the CMap
+		# (PDF Reference 1.3 chap. 5.9)
+		newobj();
+		out('<</Length 383>>');
+		out('stream');
+		out('/CIDInit /ProcSet findresource begin');
+		out('12 dict begin');
+		out('begincmap');
+		out('/CIDSystemInfo');
+		out('<</Registry (Adobe)');
+		out('/Ordering (UCS)');
+		out('/Supplement 0');
+		out('>> def');
+		out('/CMapName /Adobe-Identity-UCS def');
+		out('/CMapType 2 def');
+		out('1 begincodespacerange');
+		out('<0000> <FFFF>');
+		out('endcodespacerange');
+		out('1 beginbfrange');
+		out('<0000> <FFFF> <0000>');
+		out('endbfrange');
+		out('endcmap');
+		out('CMapName currentdict /CMap defineresource pop');
+		out('end');
+		out('end');
+		out('endstream');
+		out('endobj');
+		
+		# CIDSystemInfo dictionary
+		# A dictionary containing entries that define the character collection of the CIDFont.
+		newobj();
+		out('<</Registry (Adobe)'); # A string identifying an issuer of character collections
+		out('/Ordering (UCS)'); # A string that uniquely names a character collection issued by a specific registry
+		out('/Supplement 0'); # The supplement number of the character collection.
+		out('>>');
+		out('endobj');
+		
+		# Font descriptor
+		# A font descriptor describing the CIDFont default metrics other than its glyph widths
+		newobj();
+		out('<</Type /FontDescriptor');
+		out('/FontName /' + font['name']);
+		font['desc'].each do |key, value|
+			out('/' + key.to_s + ' ' + value.to_s);
+		end
+		if (font['file'])
+			# A stream containing a TrueType font program
+			out('/FontFile2 ' + @font_files[font['file']]['n'].to_s + ' 0 R');
+		end
+		out('>>');
+		out('endobj');
+
+		# Embed CIDToGIDMap
+		# A specification of the mapping from CIDs to glyph indices
+		newobj();
+		ctgfile = getfontpath(font['ctg'])
+		if (!ctgfile)
+			Error('Font file not found: ' + ctgfile);
+		end
+		size = File.size(ctgfile);
+		out('<</Length ' + size.to_s + '');
+		if (ctgfile[-2,2] == '.z') # check file extension
+			# Decompresses data encoded using the public-domain 
+			# zlib/deflate compression method, reproducing the 
+			# original text or binary data#
+			out('/Filter /FlateDecode');
+		end
+		out('>>');
+    open(ctgfile, "rb") do |f|
+      putstream(f.read())
+    end
+		out('endobj');
+	end
+
+	 #
+	# Converts UTF-8 strings to codepoints array.<br>
+	# Invalid byte sequences will be replaced with 0xFFFD (replacement character)<br>
+	# Based on: http://www.faqs.org/rfcs/rfc3629.html
+	# <pre>
+	# 	  Char. number range  |        UTF-8 octet sequence
+	#       (hexadecimal)    |              (binary)
+	#    --------------------+-----------------------------------------------
+	#    0000 0000-0000 007F | 0xxxxxxx
+	#    0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+	#    0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+	#    0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+	#    ---------------------------------------------------------------------
+	#
+	#   ABFN notation:
+	#   ---------------------------------------------------------------------
+	#   UTF8-octets =#( UTF8-char )
+	#   UTF8-char   = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
+	#   UTF8-1      = %x00-7F
+	#   UTF8-2      = %xC2-DF UTF8-tail
+	#
+	#   UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
+	#                 %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
+	#   UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
+	#                 %xF4 %x80-8F 2( UTF8-tail )
+	#   UTF8-tail   = %x80-BF
+	#   ---------------------------------------------------------------------
+	# </pre>
+	# @param string :str string to process.
+	# @return array containing codepoints (UTF-8 characters values)
+	# @access protected
+	# @author Nicola Asuni
+	# @since 1.53.0.TC005 (2005-01-05)
+	#
+	def UTF8StringToArray(str)
+		if (!@is_unicode)
+			return str; # string is not in unicode
+		end
+
+		unicode = [] # array containing unicode values
+		bytes  = [] # array containing single character byte sequences
+		numbytes  = 1; # number of octetc needed to represent the UTF-8 character
+
+		str = str.to_s; # force :str to be a string
+		
+		str.each_byte do |char|
+			if (bytes.length == 0) # get starting octect
+				if (char <= 0x7F)
+					unicode << char # use the character "as is" because is ASCII
+					numbytes = 1
+				elsif ((char >> 0x05) == 0x06) # 2 bytes character (0x06 = 110 BIN)
+					bytes << ((char - 0xC0) << 0x06) 
+					numbytes = 2
+				elsif ((char >> 0x04) == 0x0E) # 3 bytes character (0x0E = 1110 BIN)
+					bytes << ((char - 0xE0) << 0x0C) 
+					numbytes = 3
+				elsif ((char >> 0x03) == 0x1E) # 4 bytes character (0x1E = 11110 BIN)
+					bytes << ((char - 0xF0) << 0x12)
+					numbytes = 4
+				else
+					# use replacement character for other invalid sequences
+					unicode << 0xFFFD
+					bytes = []
+					numbytes = 1
+				end
+			elsif ((char >> 0x06) == 0x02) # bytes 2, 3 and 4 must start with 0x02 = 10 BIN
+				bytes << (char - 0x80)
+				if (bytes.length == numbytes)
+					# compose UTF-8 bytes to a single unicode value
+					char = bytes[0]
+					1.upto(numbytes-1) do |j|
+						char += (bytes[j] << ((numbytes - j - 1) * 0x06))
+					end
+					if (((char >= 0xD800) and (char <= 0xDFFF)) or (char >= 0x10FFFF))
+						# The definition of UTF-8 prohibits encoding character numbers between
+						# U+D800 and U+DFFF, which are reserved for use with the UTF-16
+						# encoding form (as surrogate pairs) and do not directly represent
+						# characters
+						unicode << 0xFFFD; # use replacement character
+  				else
+  					unicode << char; # add char to array
+					end
+  				# reset data for next char
+  				bytes = []
+  				numbytes = 1;
+				end
+			else
+				# use replacement character for other invalid sequences
+				unicode << 0xFFFD;
+				bytes = []
+				numbytes = 1;
+			end
+		end
+		return unicode;
+	end
+	
+	#
+	# Converts UTF-8 strings to UTF16-BE.<br>
+	# Based on: http://www.faqs.org/rfcs/rfc2781.html
+ 	# <pre>
+	#   Encoding UTF-16:
+	# 
+		#   Encoding of a single character from an ISO 10646 character value to
+	#    UTF-16 proceeds as follows. Let U be the character number, no greater
+	#    than 0x10FFFF.
+	# 
+	#    1) If U < 0x10000, encode U as a 16-bit unsigned integer and
+	#       terminate.
+	# 
+	#    2) Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF,
+	#       U' must be less than or equal to 0xFFFFF. That is, U' can be
+	#       represented in 20 bits.
+	# 
+	#    3) Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and
+	#       0xDC00, respectively. These integers each have 10 bits free to
+	#       encode the character value, for a total of 20 bits.
+	# 
+	#    4) Assign the 10 high-order bits of the 20-bit U' to the 10 low-order
+	#       bits of W1 and the 10 low-order bits of U' to the 10 low-order
+	#       bits of W2. Terminate.
+	# 
+	#    Graphically, steps 2 through 4 look like:
+	#    U' = yyyyyyyyyyxxxxxxxxxx
+	#    W1 = 110110yyyyyyyyyy
+	#    W2 = 110111xxxxxxxxxx
+	# </pre>
+	# @param string :str string to process.
+	# @param boolean :setbom if true set the Byte Order Mark (BOM = 0xFEFF)
+	# @return string
+	# @access protected
+	# @author Nicola Asuni
+	# @since 1.53.0.TC005 (2005-01-05)
+	# @uses UTF8StringToArray
+	#
+	def UTF8ToUTF16BE(str, setbom=true)
+		if (!@is_unicode)
+			return str; # string is not in unicode
+		end
+		outstr = ""; # string to be returned
+		unicode = UTF8StringToArray(str); # array containing UTF-8 unicode values
+		numitems = unicode.length;
+		
+		if (setbom)
+			outstr << "\xFE\xFF"; # Byte Order Mark (BOM)
+		end
+		unicode.each do |char|
+			if (char == 0xFFFD)
+				outstr << "\xFF\xFD"; # replacement character
+			elsif (char < 0x10000)
+				outstr << (char >> 0x08).chr;
+				outstr << (char & 0xFF).chr;
+			else
+				char -= 0x10000;
+				w1 = 0xD800 | (char >> 0x10);
+				w2 = 0xDC00 | (char & 0x3FF);	
+				outstr << (w1 >> 0x08).chr;
+				outstr << (w1 & 0xFF).chr;
+				outstr << (w2 >> 0x08).chr;
+				outstr << (w2 & 0xFF).chr;
+			end
+		end
+		return outstr;
+	end
+	
+	# ====================================================
+	
+	#
+ 	# Set header font.
+	# @param array :font font
+	# @since 1.1
+	#
+	def SetHeaderFont(font)
+		@header_font = font;
+	end
+	alias_method :set_header_font, :SetHeaderFont
+	
+	#
+ 	# Set footer font.
+	# @param array :font font
+	# @since 1.1
+	#
+	def SetFooterFont(font)
+		@footer_font = font;
+	end
+	alias_method :set_footer_font, :SetFooterFont
+	
+	#
+ 	# Set language array.
+	# @param array :language
+	# @since 1.1
+	#
+	def SetLanguageArray(language)
+		@l = language;
+	end
+	alias_method :set_language_array, :SetLanguageArray
+	#
+ 	# Set document barcode.
+	# @param string :bc barcode
+	#
+	def SetBarcode(bc="")
+		@barcode = bc;
+	end
+	
+	#
+ 	# Print Barcode.
+	# @param int :x x position in user units
+	# @param int :y y position in user units
+	# @param int :w width in user units
+	# @param int :h height position in user units
+	# @param string :type type of barcode (I25, C128A, C128B, C128C, C39)
+	# @param string :style barcode style
+	# @param string :font font for text
+	# @param int :xres x resolution
+	# @param string :code code to print
+	#
+	def writeBarcode(x, y, w, h, type, style, font, xres, code)
+		require(File.dirname(__FILE__) + "/barcode/barcode.rb");
+		require(File.dirname(__FILE__) + "/barcode/i25object.rb");
+		require(File.dirname(__FILE__) + "/barcode/c39object.rb");
+		require(File.dirname(__FILE__) + "/barcode/c128aobject.rb");
+		require(File.dirname(__FILE__) + "/barcode/c128bobject.rb");
+		require(File.dirname(__FILE__) + "/barcode/c128cobject.rb");
+		
+		if (code.empty?)
+			return;
+		end
+		
+		if (style.empty?)
+			style  = BCS_ALIGN_LEFT;
+			style |= BCS_IMAGE_PNG;
+			style |= BCS_TRANSPARENT;
+			#:style |= BCS_BORDER;
+			#:style |= BCS_DRAW_TEXT;
+			#:style |= BCS_STRETCH_TEXT;
+			#:style |= BCS_REVERSE_COLOR;
+		end
+		if (font.empty?) then font = BCD_DEFAULT_FONT; end
+		if (xres.empty?) then xres = BCD_DEFAULT_XRES; end
+		
+		scale_factor = 1.5 * xres * @k;
+		bc_w = (w * scale_factor).round #width in points
+		bc_h = (h * scale_factor).round #height in points
+		
+		case (type.upcase)
+			when "I25"
+				obj = I25Object.new(bc_w, bc_h, style, code);
+			when "C128A"
+				obj = C128AObject.new(bc_w, bc_h, style, code);
+			when "C128B"
+				obj = C128BObject.new(bc_w, bc_h, style, code);
+			when "C128C"
+				obj = C128CObject.new(bc_w, bc_h, style, code);
+			when "C39"
+				obj = C39Object.new(bc_w, bc_h, style, code);
+		end
+		
+		obj.SetFont(font);   
+		obj.DrawObject(xres);
+		
+		#use a temporary file....
+		tmpName = tempnam(@@k_path_cache,'img');
+		imagepng(obj.getImage(), tmpName);
+		Image(tmpName, x, y, w, h, 'png');
+		obj.DestroyObject();
+		obj = nil
+		unlink(tmpName);
+	end
+	
+	#
+ 	# Returns the PDF data.
+	#
+	def GetPDFData()
+		if (@state < 3)
+			Close();
+		end
+		return @buffer;
+	end
+	
+	# --- HTML PARSER FUNCTIONS ---
+	
+	#
+	# Allows to preserve some HTML formatting.<br />
+	# Supports: h1, h2, h3, h4, h5, h6, b, u, i, a, img, p, br, strong, em, ins, del, font, blockquote, li, ul, ol, hr, td, th, tr, table, sup, sub, small
+	# @param string :html text to display
+	# @param boolean :ln if true add a new line after text (default = true)
+	# @param int :fill Indicates if the background must be painted (1) or transparent (0). Default value: 0.
+	#
+	def writeHTML(html, ln=true, fill=0, h=0)
+    
+    @lasth = h if h > 0
+		if (@lasth == 0)
+			#set row height
+			@lasth = @font_size * @@k_cell_height_ratio; 
+		end
+		
+    @href = nil
+    @style = "";
+    @t_cells =  [[]];
+    @table_id = 0;
+
+    # pre calculate
+    html.split(/(<[^>]+>)/).each do |element|
+      if "<" == element[0,1]
+        #Tag
+        if (element[1, 1] == '/')
+					closedHTMLTagCalc(element[2..-2].downcase);
+        else
+					#Extract attributes
+					# get tag name
+					tag = element.scan(/([a-zA-Z0-9]*)/).flatten.delete_if {|x| x.length == 0}
+					tag = tag[0].to_s.downcase;
+					
+					# get attributes
+					attr_array = element.scan(/([^=\s]*)=["\']?([^"\']*)["\']?/)
+          attrs = {}
+          attr_array.each do |name, value|
+    			  attrs[name.downcase] = value;
+    		  end
+					openHTMLTagCalc(tag, attrs);
+				end
+			end
+		end
+		@table_id = 0;
+				
+    html.split(/(<[A-Za-z!?\/][^>]*?>)/).each do |element|
+      if "<" == element[0,1]
+        #Tag
+        if (element[1, 1] == '/')
+					closedHTMLTagHandler(element[2..-2].downcase);
+        else
+					#Extract attributes
+					# get tag name
+					tag = element.scan(/([a-zA-Z0-9]*)/).flatten.delete_if {|x| x.length == 0}
+					tag = tag[0].to_s.downcase;
+					
+					# get attributes
+					attr_array = element.scan(/([^=\s]*)=["\']?([^"\']*)["\']?/)
+          attrs = {}
+          attr_array.each do |name, value|
+    			  attrs[name.downcase] = value;
+    		  end
+					openHTMLTagHandler(tag, attrs, fill);
+				end
+				
+      else
+        #Text
+				if (@tdbegin)
+					element.gsub!(/[\t\r\n\f]/, "");
+					@tdtext << element.gsub(/&nbsp;/, " ");
+				elsif (@href)
+					element.gsub!(/[\t\r\n\f]/, "");
+					addHtmlLink(@href, element, fill);
+				elsif (@pre_state == true and element.length > 0)
+					Write(@lasth, unhtmlentities(element), '', fill);
+				elsif (element.strip.length > 0)
+					element.gsub!(/[\t\r\n\f]/, "");
+					element.gsub!(/&nbsp;/, " ");
+					Write(@lasth, unhtmlentities(element), '', fill);
+				end
+      end
+    end
+    
+		if (ln)
+			Ln(@lasth);
+		end
+	end
+  alias_method :write_html, :writeHTML
+
+	#
+	# Prints a cell (rectangular area) with optional borders, background color and html text string. The upper-left corner of the cell corresponds to the current position. After the call, the current position moves to the right or to the next line.<br />
+	# If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.
+	# @param float :w Cell width. If 0, the cell extends up to the right margin.
+	# @param float :h Cell minimum height. The cell extends automatically if needed.
+	# @param float :x upper-left corner X coordinate
+	# @param float :y upper-left corner Y coordinate
+	# @param string :html html text to print. Default value: empty string.
+	# @param mixed :border Indicates if borders must be drawn around the cell. The value can be either a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul>
+	# @param int :ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>
+# Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
+	# @param int :fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
+	# @see Cell()
+	#
+	def writeHTMLCell(w, h, x, y, html='', border=0, ln=1, fill=0)
+		
+		if (@lasth == 0)
+			#set row height
+			@lasth = @font_size * @@k_cell_height_ratio; 
+		end
+		
+		if (x == 0)
+			x = GetX();
+		end
+		if (y == 0)
+			y = GetY();
+		end
+		
+		# get current page number
+		pagenum = @page;
+		
+		SetX(x);
+		SetY(y);
+				
+		if (w == 0)
+			w = @fw - x - @r_margin;
+		end
+		
+		b=0;
+		if (border)
+			if (border==1)
+				border='LTRB';
+				b='LRT';
+				b2='LR';
+			elsif border.is_a?(String)
+				b2='';
+				if (border.include?('L'))
+					b2<<'L';
+				end
+				if (border.include?('R'))
+					b2<<'R';
+				end
+				b=(border.include?('T')) ? b2 + 'T' : b2;
+			end
+		end
+		
+		# store original margin values
+		l_margin = @l_margin;
+		r_margin = @r_margin;
+		
+		# set new margin values
+		SetLeftMargin(x);
+		SetRightMargin(@fw - x - w);
+				
+		# calculate remaining vertical space on page
+		restspace = GetPageHeight() - GetY() - GetBreakMargin();
+		
+		writeHTML(html, true, fill); # write html text
+    SetX(x)
+		
+		currentY =  GetY();
+		@auto_page_break = false;
+		# check if a new page has been created
+		if (@page > pagenum)
+			# design a cell around the text on first page
+			currentpage = @page;
+			@page = pagenum;
+			SetY(GetPageHeight() - restspace - GetBreakMargin());
+      SetX(x)
+			Cell(w, restspace - 1, "", b, 0, 'L', 0);
+			b = b2;
+			@page += 1;
+			while @page < currentpage
+				SetY(@t_margin); # put cursor at the beginning of text
+        SetX(x)
+				Cell(w, @page_break_trigger - @t_margin, "", b, 0, 'L', 0);
+				@page += 1;
+			end
+			if (border.is_a?(String) and border.include?('B'))
+				b<<'B';
+			end
+			# design a cell around the text on last page
+			SetY(@t_margin); # put cursor at the beginning of text
+      SetX(x)
+			Cell(w, currentY - @t_margin, "", b, 0, 'L', 0);
+		else
+			SetY(y); # put cursor at the beginning of text
+			# design a cell around the text
+      SetX(x)
+			Cell(w, [h, (currentY - y)].max, "", border, 0, 'L', 0);
+		end
+		@auto_page_break = true;
+		
+		# restore original margin values
+		SetLeftMargin(l_margin);
+		SetRightMargin(r_margin);
+		
+		@lasth = h
+
+		# move cursor to specified position
+		if (ln == 0)
+			# go to the top-right of the cell
+			@x = x + w;
+			@y = y;
+		elsif (ln == 1)
+			# go to the beginning of the next line
+			@x = @l_margin;
+			@y = currentY;
+		elsif (ln == 2)
+			# go to the bottom-left of the cell (below)
+			@x = x;
+			@y = currentY;
+		end
+	end
+  alias_method :write_html_cell, :writeHTMLCell
+
+	#
+	# Check html table tag position.
+	#
+	# @param array :table potision array
+	# @param int :current tr tag id number
+	# @param int :current td tag id number
+	# @access private
+	# @return int : next td_id position.
+	#               value 0 mean that can use position.
+	#
+	def checkTableBlockingCellPosition(table, tr_id, td_id )
+		0.upto(tr_id) do |j|
+			0.upto(@t_cells[table][j].size - 1) do |i|
+				if @t_cells[table][j][i]['i0'] <= td_id and td_id <= @t_cells[table][j][i]['i1']
+					if @t_cells[table][j][i]['j0'] <= tr_id and tr_id <= @t_cells[table][j][i]['j1']
+						return @t_cells[table][j][i]['i1'] - td_id + 1;
+					end
+				end
+			end
+		end
+		return 0;
+	end
+
+	#
+	# Calculate opening tags.
+	#
+	# html table cell array : @t_cells
+	#
+	#  i0: table cell start position
+	#  i1: table cell end position
+	#  j0: table row start position
+	#  j1: table row end position
+	#
+	#  +------+
+	#  |i0,j0 |
+	#  | i1,j1|
+	#  +------+
+	#
+	#  example html:
+	#  <table>
+	#    <tr><td></td><td></td><td></td></tr>
+	#    <tr><td colspan=2></td><td></td></tr>
+	#    <tr><td rowspan=2></td><td></td><td></td></tr>
+	#    <tr><td></td><td></td></tr>
+	#  </table>
+	#
+	#   i: 0    1    2
+	#  j+----+----+----+
+	#  :|0,0 |1,0 |2,0 |
+	#  0| 0,0| 1,0| 2,0|
+	#   +----+----+----+
+	#   |0,1      |2,1 |
+	#  1|      1,1| 2,1|
+	#   +----+----+----+
+	#   |0,2 |1,2 |2,2 |
+	#  2|    | 1,2| 2,2|
+	#   +    +----+----+
+	#   |    |1,3 |2,3 |
+	#  3| 0,3| 1,3| 2,3|
+	#   +----+----+----+
+	#
+	#  html table cell array :
+	#  [[[i0=>0,j0=>0,i1=>0,j1=>0],[i0=>1,j0=>0,i1=>1,j1=>0],[i0=>2,j0=>0,i1=>2,j1=>0]],
+	#   [[i0=>0,j0=>1,i1=>1,j1=>1],[i0=>2,j0=>1,i1=>2,j1=>1]],
+	#   [[i0=>0,j0=>2,i1=>0,j1=>3],[i0=>1,j0=>2,i1=>1,j1=>2],[i0=>2,j0=>2,i1=>2,j1=>2]]
+	#   [[i0=>1,j0=>3,i1=>1,j1=>3],[i0=>2,j0=>3,i1=>2,j1=>3]]]
+	#
+	# @param string :tag tag name (in upcase)
+	# @param string :attr tag attribute (in upcase)
+	# @access private
+	#
+	def openHTMLTagCalc(tag, attrs)
+		#Opening tag
+		case (tag)
+			when 'table'
+				@max_table_columns[@table_id] = 0;
+				@t_columns = 0;
+				@tr_id = -1;
+			when 'tr'
+				if @max_table_columns[@table_id] < @t_columns
+					@max_table_columns[@table_id] = @t_columns;
+				end
+				@t_columns = 0;
+				@tr_id +=  1;
+				@td_id =  -1;
+				@t_cells[@table_id].push []
+			when 'td', 'th'
+				@td_id +=  1;
+				if attrs['colspan'].nil? or attrs['colspan'] == ''
+					colspan = 1;
+				else
+					colspan = attrs['colspan'].to_i;
+				end
+				if attrs['rowspan'].nil? or attrs['rowspan'] == ''
+					rowspan = 1;
+				else
+					rowspan = attrs['rowspan'].to_i;
+				end
+
+				i = 0;
+				while true
+					next_i_distance = checkTableBlockingCellPosition(@table_id, @tr_id, @td_id + i);
+					if next_i_distance == 0
+						@t_cells[@table_id][@tr_id].push "i0"=>@td_id + i, "j0"=>@tr_id, "i1"=>(@td_id + i + colspan - 1), "j1"=>@tr_id + rowspan - 1
+						break;
+					end
+					i += next_i_distance;
+				end
+
+				@t_columns += colspan;
+		end
+	end
+
+	#
+	# Calculate closing tags.
+	# @param string :tag tag name (in upcase)
+	# @access private
+	#
+	def closedHTMLTagCalc(tag)
+		#Closing tag
+		case (tag)
+			when 'table'
+				if @max_table_columns[@table_id] < @t_columns
+					@max_table_columns[@table_id] = @t_columns;
+				end
+				@table_id += 1;
+				@t_cells.push []
+		end
+	end
+
+	#
+	# Convert to accessible file path
+	# @param string :attrname image file name
+	#
+	def getImageFilename( attrname )
+		nil
+	end
+
+	#
+	# Process opening tags.
+	# @param string :tag tag name (in upcase)
+	# @param string :attr tag attribute (in upcase)
+	# @param int :fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
+	# @access private
+	#
+	def openHTMLTagHandler(tag, attrs, fill=0)
+		#Opening tag
+		case (tag)
+			when 'pre'
+				@pre_state = true;
+				@l_margin += 5;	
+				@r_margin += 5;	
+				@x += 5;	
+
+			when 'table'
+				Ln();
+				if @default_table_columns < @max_table_columns[@table_id]
+					@table_columns = @max_table_columns[@table_id];
+				else
+					@table_columns = @default_table_columns;
+				end
+				@l_margin += 5;	
+				@r_margin += 5;	
+				@x += 5;	
+
+				if attrs['border'].nil? or attrs['border'] == ''
+					@tableborder = 0;
+				else
+					@tableborder = attrs['border'];
+				end
+				@tr_id        = -1;
+				@max_td_page[0] = @page;
+				@max_td_y[0]    = @y;
+
+			when 'tr', 'td', 'th'
+				if tag == 'th'
+					SetStyle('b', true);
+					@tdalign = "C";
+				end
+				if ((!attrs['width'].nil?) and (attrs['width'] != ''))
+					@tdwidth = (attrs['width'].to_i/4);
+				else
+					@tdwidth = ((@w - @l_margin - @r_margin) / @table_columns);
+				end
+
+				if tag == 'tr'
+					@tr_id +=  1;
+					@td_id  = -1;
+				else
+					@td_id +=  1;
+					@x =  @l_margin + @tdwidth * @t_cells[@table_id][@tr_id][@td_id]['i0'];
+				end
+
+				if attrs['colspan'].nil? or attrs['border'] == ''
+					@colspan = 1;
+				else
+					@colspan = attrs['colspan'].to_i;
+				end
+				@tdwidth *= @colspan;
+				if ((!attrs['height'].nil?) and (attrs['height'] != ''))
+					@tdheight=(attrs['height'].to_i / @k);
+				else
+					@tdheight = @lasth;
+				end
+				if ((!attrs['align'].nil?) and (attrs['align'] != ''))
+					case (attrs['align'])
+						when 'center'
+							@tdalign = "C";
+						when 'right'
+							@tdalign = "R";
+						when 'left'
+							@tdalign = "L";
+					end
+				end
+				if ((!attrs['bgcolor'].nil?) and (attrs['bgcolor'] != ''))
+					coul = convertColorHexToDec(attrs['bgcolor']);
+					SetFillColor(coul['R'], coul['G'], coul['B']);
+					@tdfill=1;
+				end
+				@tdbegin=true;
+				
+			when 'hr'
+				margin = 1;
+				if ((!attrs['width'].nil?) and (attrs['width'] != ''))
+					hrWidth = attrs['width'];
+				else
+					hrWidth = @w - @l_margin - @r_margin - margin;
+				end
+				SetLineWidth(0.2);
+				Line(@x + margin, @y, @x + hrWidth, @y);
+				Ln();
+				
+			when 'strong'
+				SetStyle('b', true);
+				
+			when 'em'
+				SetStyle('i', true);
+				
+			when 'ins'
+				SetStyle('u', true);
+				
+			when 'del'
+				SetStyle('d', true);
+				
+			when 'b', 'i', 'u'
+				SetStyle(tag, true);
+				
+			when 'a'
+				@href = attrs['href'];
+				
+			when 'img'
+				if (!attrs['src'].nil?)
+					# Don't generates image inside table tag
+					if (@tdbegin)
+						@tdtext << attrs['src'];
+						return
+					end
+					# Only generates image include a pdf if RMagick is avalaible
+					unless Object.const_defined?(:Magick)
+						Write(@lasth, attrs['src'], '', fill);
+						return
+					end
+					file = getImageFilename(attrs['src'])
+					if (file.nil?)
+						Write(@lasth, attrs['src'], '', fill);
+						return
+					end
+
+					if (attrs['width'].nil?)
+						attrs['width'] = 0;
+					end
+					if (attrs['height'].nil?)
+						attrs['height'] = 0;
+					end
+					
+					begin
+						Image(file, GetX(),GetY(), pixelsToMillimeters(attrs['width']), pixelsToMillimeters(attrs['height']));
+						#SetX(@img_rb_x);
+						SetY(@img_rb_y);
+					rescue => err
+						logger.error "pdf: Image: error: #{err.message}"
+						Write(@lasth, attrs['src'], '', fill);
+					end
+				end
+				
+			when 'ul', 'ol'
+				if @li_count == 0
+					Ln() if @prevquote_count == @quote_count; # insert Ln for keeping quote lines
+					@prevquote_count = @quote_count;
+				end
+				if @li_state == true
+					Ln();
+			  	@li_state = false;
+				end
+				if tag == 'ul'
+					@list_ordered[@li_count] = false;
+				else
+					@list_ordered[@li_count] = true;
+				end
+				@list_count[@li_count] = 0;
+				@li_count += 1
+				
+			when 'li'
+				Ln() if @li_state == true
+				if (@list_ordered[@li_count - 1])
+					@list_count[@li_count - 1] += 1;
+					@li_spacer = "    " * @li_count + (@list_count[@li_count - 1]).to_s + ". ";
+				else
+					#unordered list simbol
+					@li_spacer = "    " * @li_count + "-  ";
+				end
+				Write(@lasth, @spacer + @li_spacer, '', fill);
+				@li_state = true;
+
+			when 'blockquote'
+				if (@quote_count == 0)
+					SetStyle('i', true);
+					@l_margin += 5;	
+				else
+					@l_margin += 5 / 2;	
+				end
+				@x = @l_margin;	
+				@quote_top[@quote_count]  = @y;
+				@quote_page[@quote_count] = @page;
+				@quote_count += 1
+			when 'br'
+				if @tdbegin
+					@tdtext << "\n"
+					return
+				end
+				Ln();
+
+				if (@li_spacer.length > 0)
+					@x += GetStringWidth(@li_spacer);
+				end
+				
+			when 'p'
+				Ln();
+				0.upto(@quote_count - 1) do |i|
+			  	if @quote_page[i] == @page;
+			  		if @quote_top[i] == @y - @lasth; # fix start line
+			  			@quote_top[i] = @y;
+						end
+					else
+			  		if @quote_page[i] == @page - 1;
+			  			@quote_page[i] = @page; # fix start line
+			  			@quote_top[i] = @t_margin;
+						end
+					end
+				end
+				
+			when 'sup'
+				currentfont_size = @font_size;
+				@tempfontsize = @font_size_pt;
+				SetFontSize(@font_size_pt * @@k_small_ratio);
+				SetXY(GetX(), GetY() - ((currentfont_size - @font_size)*(@@k_small_ratio)));
+				
+			when 'sub'
+				currentfont_size = @font_size;
+				@tempfontsize = @font_size_pt;
+				SetFontSize(@font_size_pt * @@k_small_ratio);
+				SetXY(GetX(), GetY() + ((currentfont_size - @font_size)*(@@k_small_ratio)));
+				
+			when 'small'
+				currentfont_size = @font_size;
+				@tempfontsize = @font_size_pt;
+				SetFontSize(@font_size_pt * @@k_small_ratio);
+				SetXY(GetX(), GetY() + ((currentfont_size - @font_size)/3));
+				
+			when 'font'
+				if (!attrs['color'].nil? and attrs['color']!='')
+					coul = convertColorHexToDec(attrs['color']);
+					SetTextColor(coul['R'], coul['G'], coul['B']);
+					@issetcolor=true;
+				end
+				if (!attrs['face'].nil? and @fontlist.include?(attrs['face'].downcase))
+					SetFont(attrs['face'].downcase);
+					@issetfont=true;
+				end
+				if (!attrs['size'].nil?)
+					headsize = attrs['size'].to_i;
+				else
+					headsize = 0;
+				end
+				currentfont_size = @font_size;
+				@tempfontsize = @font_size_pt;
+				SetFontSize(@font_size_pt + headsize);
+				@lasth = @font_size * @@k_cell_height_ratio;
+				
+			when 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
+				Ln();
+				headsize = (4 - tag[1,1].to_f) * 2
+				@tempfontsize = @font_size_pt;
+				SetFontSize(@font_size_pt + headsize);
+				SetStyle('b', true);
+				@lasth = @font_size * @@k_cell_height_ratio;
+				
+		end
+	end
+  
+	#
+	# Process closing tags.
+	# @param string :tag tag name (in upcase)
+	# @access private
+	#
+	def closedHTMLTagHandler(tag)
+		#Closing tag
+		case (tag)
+			when 'pre'
+				@pre_state = false;
+				@l_margin -= 5;
+				@r_margin -= 5;
+				@x = @l_margin;
+				Ln();
+
+			when 'td','th'
+				base_page = @page;
+				base_x = @x;
+				base_y = @y;
+
+				MultiCell(@tdwidth, @tdheight, unhtmlentities(@tdtext.strip), @tableborder, @tdalign, @tdfill, 1);
+				tr_end = @t_cells[@table_id][@tr_id][@td_id]['j1'] + 1;
+				if @max_td_page[tr_end].nil?  or (@max_td_page[tr_end] < @page)
+					@max_td_page[tr_end] = @page
+					@max_td_y[tr_end] = @y
+				elsif (@max_td_page[tr_end] == @page)
+					@max_td_y[tr_end] = @y if @max_td_y[tr_end].nil? or (@max_td_y[tr_end] < @y) 
+				end
+
+				@page = base_page;
+				@x = base_x + @tdwidth;
+				@y = base_y;
+				@tdtext = '';
+				@tdbegin = false;
+				@tdwidth = 0;
+				@tdheight = 0;
+				@tdalign = "L";
+				SetStyle('b', false);
+				@tdfill = 0;
+				SetFillColor(@prevfill_color[0], @prevfill_color[1], @prevfill_color[2]);
+				
+			when 'tr'
+				@y = @max_td_y[@tr_id + 1];
+				@x = @l_margin;
+				@page = @max_td_page[@tr_id + 1];
+				
+			when 'table'
+				# Write Table Line
+				width = (@w - @l_margin - @r_margin) / @table_columns;
+				0.upto(@t_cells[@table_id].size - 1) do |j|
+					0.upto(@t_cells[@table_id][j].size - 1) do |i|
+						@page = @max_td_page[j]
+						i0=@t_cells[@table_id][j][i]['i0'];
+						j0=@t_cells[@table_id][j][i]['j0'];
+						i1=@t_cells[@table_id][j][i]['i1'];
+						j1=@t_cells[@table_id][j][i]['j1'];
+
+						Line(@l_margin + width * i0,     @max_td_y[j0],   @l_margin + width * (i1+1), @max_td_y[j0])   # top
+						if ( @page == @max_td_page[j1 + 1])
+							Line(@l_margin + width * i0,     @max_td_y[j0],   @l_margin + width * i0,     @max_td_y[j1+1]) # left
+							Line(@l_margin + width * (i1+1), @max_td_y[j0],   @l_margin + width * (i1+1), @max_td_y[j1+1]) # right
+						else
+							Line(@l_margin + width * i0,     @max_td_y[j0],   @l_margin + width * i0,     @page_break_trigger) # left
+							Line(@l_margin + width * (i1+1), @max_td_y[j0],   @l_margin + width * (i1+1), @page_break_trigger) # right
+							@page += 1;
+							while @page < @max_td_page[j1 + 1]
+								Line(@l_margin + width * i0,     @t_margin,   @l_margin + width * i0,     @page_break_trigger) # left
+								Line(@l_margin + width * (i1+1), @t_margin,   @l_margin + width * (i1+1), @page_break_trigger) # right
+								@page += 1;
+							end
+							Line(@l_margin + width * i0,     @t_margin,   @l_margin + width * i0,     @max_td_y[j1+1]) # left
+							Line(@l_margin + width * (i1+1), @t_margin,   @l_margin + width * (i1+1), @max_td_y[j1+1]) # right
+						end
+						Line(@l_margin + width * i0,     @max_td_y[j1+1], @l_margin + width * (i1+1), @max_td_y[j1+1]) # bottom
+					end
+				end
+
+				@l_margin -= 5;
+				@r_margin -= 5;
+				@tableborder=0;
+				@table_id += 1;
+				
+			when 'strong'
+				SetStyle('b', false);
+				
+			when 'em'
+				SetStyle('i', false);
+				
+			when 'ins'
+				SetStyle('u', false);
+				
+			when 'del'
+				SetStyle('d', false);
+				
+			when 'b', 'i', 'u'
+				SetStyle(tag, false);
+				
+			when 'a'
+				@href = nil;
+				
+			when 'p'
+				Ln();
+				
+			when 'sup'
+				currentfont_size = @font_size;
+				SetFontSize(@tempfontsize);
+				@tempfontsize = @font_size_pt;
+				SetXY(GetX(), GetY() - ((currentfont_size - @font_size)*(@@k_small_ratio)));
+				
+			when 'sub'
+				currentfont_size = @font_size;
+				SetFontSize(@tempfontsize);
+				@tempfontsize = @font_size_pt;
+				SetXY(GetX(), GetY() + ((currentfont_size - @font_size)*(@@k_small_ratio)));
+				
+			when 'small'
+				currentfont_size = @font_size;
+				SetFontSize(@tempfontsize);
+				@tempfontsize = @font_size_pt;
+				SetXY(GetX(), GetY() - ((@font_size - currentfont_size)/3));
+				
+			when 'font'
+				if (@issetcolor == true)
+					SetTextColor(@prevtext_color[0], @prevtext_color[1], @prevtext_color[2]);
+				end
+				if (@issetfont)
+					@font_family = @prevfont_family;
+					@font_style = @prevfont_style;
+					SetFont(@font_family);
+					@issetfont = false;
+				end
+				currentfont_size = @font_size;
+				SetFontSize(@tempfontsize);
+				@tempfontsize = @font_size_pt;
+				#@text_color = @prevtext_color;
+				@lasth = @font_size * @@k_cell_height_ratio;
+				
+			when 'blockquote'
+			  @quote_count -= 1
+				if (@quote_page[@quote_count] == @page)
+					Line(@l_margin - 1, @quote_top[@quote_count], @l_margin - 1, @y)  # quoto line
+				else
+					cur_page = @page;
+					cur_y = @y;
+					@page = @quote_page[@quote_count];
+					if (@quote_top[@quote_count] < @page_break_trigger)
+						Line(@l_margin - 1, @quote_top[@quote_count], @l_margin - 1, @page_break_trigger)  # quoto line
+					end
+					@page += 1;
+					while @page < cur_page
+						Line(@l_margin - 1, @t_margin, @l_margin - 1, @page_break_trigger)  # quoto line
+						@page += 1;
+					end
+					@y = cur_y;
+					Line(@l_margin - 1, @t_margin, @l_margin - 1, @y)  # quoto line
+				end
+				if (@quote_count <= 0)
+					SetStyle('i', false);
+					@l_margin -= 5;
+				else
+					@l_margin -= 5 / 2;
+				end
+				@x = @l_margin;
+				Ln() if @quote_count == 0
+
+			when 'ul', 'ol'
+			  @li_count -= 1
+				if @li_state == true
+					Ln();
+			  	@li_state = false;
+				end
+				
+			when 'li'
+				@li_spacer = "";
+				if @li_state == true
+					Ln();
+			  	@li_state = false;
+				end
+				
+			when 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
+				SetFontSize(@tempfontsize);
+				@tempfontsize = @font_size_pt;
+				SetStyle('b', false);
+				Ln();
+				@lasth = @font_size * @@k_cell_height_ratio;
+				
+				if tag == 'h1' or tag == 'h2' or tag == 'h3' or tag == 'h4'
+					margin = 1;
+					hrWidth = @w - @l_margin - @r_margin - margin;
+					if tag == 'h1' or tag == 'h2'
+						SetLineWidth(0.2);
+					else
+						SetLineWidth(0.1);
+					end
+					Line(@x + margin, @y, @x + hrWidth, @y);
+				end
+		end
+	end
+	
+	#
+	# Sets font style.
+	# @param string :tag tag name (in lowercase)
+	# @param boolean :enable
+	# @access private
+	#
+	def SetStyle(tag, enable)
+		#Modify style and select corresponding font
+		['b', 'i', 'u', 'd'].each do |s|
+			if tag.downcase == s
+				if enable
+					@style << s if ! @style.include?(s)
+				else
+					@style = @style.gsub(s,'')
+				end
+			end
+		end
+		SetFont('', @style);
+	end
+	
+	#
+	# Output anchor link.
+	# @param string :url link URL
+	# @param string :name link name
+	# @param int :fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
+	# @access public
+	#
+	def addHtmlLink(url, name, fill=0)
+		#Put a hyperlink
+		SetTextColor(0, 0, 255);
+		SetStyle('u', true);
+		Write(@lasth, name, url, fill);
+		SetStyle('u', false);
+		SetTextColor(0);
+	end
+	
+	#
+	# Returns an associative array (keys: R,G,B) from 
+	# a hex html code (e.g. #3FE5AA).
+	# @param string :color hexadecimal html color [#rrggbb]
+	# @return array
+	# @access private
+	#
+	def convertColorHexToDec(color = "#000000")
+		tbl_color = {}
+		tbl_color['R'] = color[1,2].hex.to_i;
+		tbl_color['G'] = color[3,2].hex.to_i;
+		tbl_color['B'] = color[5,2].hex.to_i;
+		return tbl_color;
+	end
+	
+	#
+	# Converts pixels to millimeters in 72 dpi.
+	# @param int :px pixels
+	# @return float millimeters
+	# @access private
+	#
+	def pixelsToMillimeters(px)
+		return px.to_f * 25.4 / 72;
+	end
+		
+	#
+	# Reverse function for htmlentities.
+	# Convert entities in UTF-8.
+	#
+	# @param :text_to_convert Text to convert.
+	# @return string converted
+	#
+	def unhtmlentities(string)
+      CGI.unescapeHTML(string)
+  end
+  
+end # END OF CLASS
+
+#TODO 2007-05-25 (EJM) Level=0 - 
+#Handle special IE contype request
+# if (!_SERVER['HTTP_USER_AGENT'].nil? and (_SERVER['HTTP_USER_AGENT']=='contype'))
+# 	header('Content-Type: application/pdf');
+# 	exit;
+# }
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8a838241ecb1de57abec573d9ab086b1b83f3ab1.svn-base
--- a/.svn/pristine/8a/8a838241ecb1de57abec573d9ab086b1b83f3ab1.svn-base
+++ /dev/null
@@ -1,174 +0,0 @@
-module CodeRay module Scanners
-  
-  # by Josh Goebel
-  class SQL < Scanner
-
-    register_for :sql
-    
-    KEYWORDS = %w(
-      all and any as before begin between by case check collate
-      each else end exists
-      for foreign from full group having if in inner is join
-      like not of on or order outer over references
-      then to union using values when where
-      left right distinct
-    )
-    
-    OBJECTS = %w(
-      database databases table tables column columns fields index constraint
-      constraints transaction function procedure row key view trigger
-    )
-    
-    COMMANDS = %w(
-      add alter comment create delete drop grant insert into select update set
-      show prompt begin commit rollback replace truncate
-    )
-    
-    PREDEFINED_TYPES = %w(
-      char varchar varchar2 enum binary text tinytext mediumtext
-      longtext blob tinyblob mediumblob longblob timestamp
-      date time datetime year double decimal float int
-      integer tinyint mediumint bigint smallint unsigned bit
-      bool boolean hex bin oct
-    )
-    
-    PREDEFINED_FUNCTIONS = %w( sum cast substring abs pi count min max avg now )
-    
-    DIRECTIVES = %w( 
-      auto_increment unique default charset initially deferred
-      deferrable cascade immediate read write asc desc after
-      primary foreign return engine
-    )
-    
-    PREDEFINED_CONSTANTS = %w( null true false )
-    
-    IDENT_KIND = WordList::CaseIgnoring.new(:ident).
-      add(KEYWORDS, :keyword).
-      add(OBJECTS, :type).
-      add(COMMANDS, :class).
-      add(PREDEFINED_TYPES, :predefined_type).
-      add(PREDEFINED_CONSTANTS, :predefined_constant).
-      add(PREDEFINED_FUNCTIONS, :predefined).
-      add(DIRECTIVES, :directive)
-    
-    ESCAPE = / [rbfntv\n\\\/'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | . /mx
-    UNICODE_ESCAPE =  / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
-    
-    STRING_PREFIXES = /[xnb]|_\w+/i
-    
-    def scan_tokens encoder, options
-      
-      state = :initial
-      string_type = nil
-      string_content = ''
-      name_expected = false
-      
-      until eos?
-        
-        if state == :initial
-          
-          if match = scan(/ \s+ | \\\n /x)
-            encoder.text_token match, :space
-          
-          elsif match = scan(/(?:--\s?|#).*/)
-            encoder.text_token match, :comment
-            
-          elsif match = scan(%r( /\* (!)? (?: .*? \*/ | .* ) )mx)
-            encoder.text_token match, self[1] ? :directive : :comment
-            
-          elsif match = scan(/ [*\/=<>:;,!&^|()\[\]{}~%] | [-+\.](?!\d) /x)
-            name_expected = true if match == '.' && check(/[A-Za-z_]/)
-            encoder.text_token match, :operator
-            
-          elsif match = scan(/(#{STRING_PREFIXES})?([`"'])/o)
-            prefix = self[1]
-            string_type = self[2]
-            encoder.begin_group :string
-            encoder.text_token prefix, :modifier if prefix
-            match = string_type
-            state = :string
-            encoder.text_token match, :delimiter
-            
-          elsif match = scan(/ @? [A-Za-z_][A-Za-z_0-9]* /x)
-            encoder.text_token match, name_expected ? :ident : (match[0] == ?@ ? :variable : IDENT_KIND[match])
-            name_expected = false
-            
-          elsif match = scan(/0[xX][0-9A-Fa-f]+/)
-            encoder.text_token match, :hex
-            
-          elsif match = scan(/0[0-7]+(?![89.eEfF])/)
-            encoder.text_token match, :octal
-            
-          elsif match = scan(/[-+]?(?>\d+)(?![.eEfF])/)
-            encoder.text_token match, :integer
-            
-          elsif match = scan(/[-+]?(?:\d[fF]|\d*\.\d+(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+)/)
-            encoder.text_token match, :float
-          
-          elsif match = scan(/\\N/)
-            encoder.text_token match, :predefined_constant
-            
-          else
-            encoder.text_token getch, :error
-            
-          end
-          
-        elsif state == :string
-          if match = scan(/[^\\"'`]+/)
-            string_content << match
-            next
-          elsif match = scan(/["'`]/)
-            if string_type == match
-              if peek(1) == string_type  # doubling means escape
-                string_content << string_type << getch
-                next
-              end
-              unless string_content.empty?
-                encoder.text_token string_content, :content
-                string_content = ''
-              end
-              encoder.text_token match, :delimiter
-              encoder.end_group :string
-              state = :initial
-              string_type = nil
-            else
-              string_content << match
-            end
-          elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
-            unless string_content.empty?
-              encoder.text_token string_content, :content
-              string_content = ''
-            end
-            encoder.text_token match, :char
-          elsif match = scan(/ \\ . /mox)
-            string_content << match
-            next
-          elsif match = scan(/ \\ | $ /x)
-            unless string_content.empty?
-              encoder.text_token string_content, :content
-              string_content = ''
-            end
-            encoder.text_token match, :error
-            state = :initial
-          else
-            raise "else case \" reached; %p not handled." % peek(1), encoder
-          end
-          
-        else
-          raise 'else-case reached', encoder
-          
-        end
-        
-      end
-      
-      if state == :string
-        encoder.end_group state
-      end
-      
-      encoder
-      
-    end
-    
-  end
-  
-end end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8a9427066e2d6e798584d5fb43dde42f7e5a0ae0.svn-base
--- a/.svn/pristine/8a/8a9427066e2d6e798584d5fb43dde42f7e5a0ae0.svn-base
+++ /dev/null
@@ -1,18 +0,0 @@
-module CodeRay
-module Encoders
-  
-  # = Null Encoder
-  #
-  # Does nothing and returns an empty string.
-  class Null < Encoder
-    
-    register_for :null
-    
-    def text_token text, kind
-      # do nothing
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8aaabf0921abadbc953f9bb52b798cfb728da0d6.svn-base
--- /dev/null
+++ b/.svn/pristine/8a/8aaabf0921abadbc953f9bb52b798cfb728da0d6.svn-base
@@ -0,0 +1,14 @@
+class ExportPdf < ActiveRecord::Migration
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    Permission.create :controller => "projects", :action => "export_issues_pdf", :description => "label_export_pdf", :sort => 1002, :is_public => true, :mail_option => 0, :mail_enabled => 0
+    Permission.create :controller => "issues", :action => "export_pdf", :description => "label_export_pdf", :sort => 1015, :is_public => true, :mail_option => 0, :mail_enabled => 0
+  end
+
+  def self.down
+    Permission.where("controller=? and action=?", 'projects', 'export_issues_pdf').first.destroy
+    Permission.where("controller=? and action=?", 'issues', 'export_pdf').first.destroy
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8ab4630ebd77e09c1eecc6ce7e00d173fda9baab.svn-base
--- /dev/null
+++ b/.svn/pristine/8a/8ab4630ebd77e09c1eecc6ce7e00d173fda9baab.svn-base
@@ -0,0 +1,54 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::HttpBasicLoginTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  def setup
+    Setting.rest_api_enabled = '1'
+    Setting.login_required = '1'
+  end
+
+  def teardown
+    Setting.rest_api_enabled = '0'
+    Setting.login_required = '0'
+  end
+
+  # Using the NewsController because it's a simple API.
+  context "get /news" do
+    setup do
+      project = Project.find('onlinestore')
+      EnabledModule.create(:project => project, :name => 'news')
+    end
+
+    context "in :xml format" do
+      should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.xml")
+    end
+
+    context "in :json format" do
+      should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.json")
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8ac2d7f20aa45eda756c0873b6a4368ace36d01a.svn-base
--- /dev/null
+++ b/.svn/pristine/8a/8ac2d7f20aa45eda756c0873b6a4368ace36d01a.svn-base
@@ -0,0 +1,9 @@
+class AddIssuesClosedOn < ActiveRecord::Migration
+  def up
+    add_column :issues, :closed_on, :datetime, :default => nil
+  end
+
+  def down
+    remove_column :issues, :closed_on
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8a/8adb47a9617850b441bd264fdfaa485feeb05a17.svn-base
--- a/.svn/pristine/8a/8adb47a9617850b441bd264fdfaa485feeb05a17.svn-base
+++ /dev/null
@@ -1,26 +0,0 @@
-class ProjectEnumerationsController < ApplicationController
-  before_filter :find_project_by_project_id
-  before_filter :authorize
-
-  def update
-    if request.put? && params[:enumerations]
-      Project.transaction do
-        params[:enumerations].each do |id, activity|
-          @project.update_or_create_time_entry_activity(id, activity)
-        end
-      end
-      flash[:notice] = l(:notice_successful_update)
-    end
-
-    redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project
-  end
-
-  def destroy
-    @project.time_entry_activities.each do |time_entry_activity|
-      time_entry_activity.destroy(time_entry_activity.parent)
-    end
-    flash[:notice] = l(:notice_successful_update)
-    redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8b/8b0c72afd0d7787739416aa1510d0e28d12a95ed.svn-base
--- a/.svn/pristine/8b/8b0c72afd0d7787739416aa1510d0e28d12a95ed.svn-base
+++ /dev/null
@@ -1,63 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-require 'rails_generator'
-require 'rails_generator/scripts/generate'
-
-class MigrationsTest < Test::Unit::TestCase
-  
-  @@migration_dir = "#{RAILS_ROOT}/db/migrate"
-
-  def setup
-    ActiveRecord::Migration.verbose = false
-    Engines.plugins[:test_migration].migrate(0)
-  end
-  
-  def teardown
-    FileUtils.rm_r(@@migration_dir) if File.exist?(@@migration_dir)
-  end
-  
-  def test_engine_migrations_can_run_down
-    assert !table_exists?('tests'), ActiveRecord::Base.connection.tables.inspect
-    assert !table_exists?('others'), ActiveRecord::Base.connection.tables.inspect
-    assert !table_exists?('extras'), ActiveRecord::Base.connection.tables.inspect
-  end
-    
-  def test_engine_migrations_can_run_up
-    Engines.plugins[:test_migration].migrate(3)
-    assert table_exists?('tests')
-    assert table_exists?('others')
-    assert table_exists?('extras')
-  end
-  
-  def test_engine_migrations_can_upgrade_incrementally
-    Engines.plugins[:test_migration].migrate(1)
-    assert table_exists?('tests')
-    assert !table_exists?('others')
-    assert !table_exists?('extras')
-    assert_equal 1, Engines::Plugin::Migrator.current_version(Engines.plugins[:test_migration])
-    
-    
-    Engines.plugins[:test_migration].migrate(2)
-    assert table_exists?('others')
-    assert_equal 2, Engines::Plugin::Migrator.current_version(Engines.plugins[:test_migration])
-    
-    
-    Engines.plugins[:test_migration].migrate(3)
-    assert table_exists?('extras')
-    assert_equal 3, Engines::Plugin::Migrator.current_version(Engines.plugins[:test_migration])
-  end
-    
-  def test_generator_creates_plugin_migration_file
-    Rails::Generator::Scripts::Generate.new.run(['plugin_migration', 'test_migration'], :quiet => true)
-    assert migration_file, "migration file is missing"
-  end
-  
-  private
-  
-  def table_exists?(table)
-    ActiveRecord::Base.connection.tables.include?(table)
-  end
-  
-  def migration_file
-    Dir["#{@@migration_dir}/*test_migration_to_version_3.rb"][0]
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8b/8b34b320f3a3448ad5019fb625383697dc8a3c95.svn-base
--- a/.svn/pristine/8b/8b34b320f3a3448ad5019fb625383697dc8a3c95.svn-base
+++ /dev/null
@@ -1,395 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class IssueNestedSetTest < ActiveSupport::TestCase
-  fixtures :projects, :users, :members, :member_roles, :roles,
-           :trackers, :projects_trackers,
-           :versions,
-           :issue_statuses, :issue_categories, :issue_relations, :workflows,
-           :enumerations,
-           :issues,
-           :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
-           :time_entries
-
-  self.use_transactional_fixtures = false
-
-  def test_create_root_issue
-    issue1 = create_issue!
-    issue2 = create_issue!
-    issue1.reload
-    issue2.reload
-
-    assert_equal [issue1.id, nil, 1, 2], [issue1.root_id, issue1.parent_id, issue1.lft, issue1.rgt]
-    assert_equal [issue2.id, nil, 1, 2], [issue2.root_id, issue2.parent_id, issue2.lft, issue2.rgt]
-  end
-
-  def test_create_child_issue
-    parent = create_issue!
-    child =  create_issue!(:parent_issue_id => parent.id)
-    parent.reload
-    child.reload
-
-    assert_equal [parent.id, nil, 1, 4], [parent.root_id, parent.parent_id, parent.lft, parent.rgt]
-    assert_equal [parent.id, parent.id, 2, 3], [child.root_id, child.parent_id, child.lft, child.rgt]
-  end
-
-  def test_creating_a_child_in_different_project_should_not_validate
-    issue = create_issue!
-    child = Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
-                      :subject => 'child', :parent_issue_id => issue.id)
-    assert !child.save
-    assert_not_nil child.errors[:parent_issue_id]
-  end
-
-  def test_move_a_root_to_child
-    parent1 = create_issue!
-    parent2 = create_issue!
-    child = create_issue!(:parent_issue_id => parent1.id)
-
-    parent2.parent_issue_id = parent1.id
-    parent2.save!
-    child.reload
-    parent1.reload
-    parent2.reload
-
-    assert_equal [parent1.id, 1, 6], [parent1.root_id, parent1.lft, parent1.rgt]
-    assert_equal [parent1.id, 4, 5], [parent2.root_id, parent2.lft, parent2.rgt]
-    assert_equal [parent1.id, 2, 3], [child.root_id, child.lft, child.rgt]
-  end
-
-  def test_move_a_child_to_root
-    parent1 = create_issue!
-    parent2 = create_issue!
-    child =   create_issue!(:parent_issue_id => parent1.id)
-
-    child.parent_issue_id = nil
-    child.save!
-    child.reload
-    parent1.reload
-    parent2.reload
-
-    assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt]
-    assert_equal [parent2.id, 1, 2], [parent2.root_id, parent2.lft, parent2.rgt]
-    assert_equal [child.id, 1, 2], [child.root_id, child.lft, child.rgt]
-  end
-
-  def test_move_a_child_to_another_issue
-    parent1 = create_issue!
-    parent2 = create_issue!
-    child =   create_issue!(:parent_issue_id => parent1.id)
-
-    child.parent_issue_id = parent2.id
-    child.save!
-    child.reload
-    parent1.reload
-    parent2.reload
-
-    assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt]
-    assert_equal [parent2.id, 1, 4], [parent2.root_id, parent2.lft, parent2.rgt]
-    assert_equal [parent2.id, 2, 3], [child.root_id, child.lft, child.rgt]
-  end
-
-  def test_move_a_child_with_descendants_to_another_issue
-    parent1 = create_issue!
-    parent2 = create_issue!
-    child =   create_issue!(:parent_issue_id => parent1.id)
-    grandchild = create_issue!(:parent_issue_id => child.id)
-
-    parent1.reload
-    parent2.reload
-    child.reload
-    grandchild.reload
-
-    assert_equal [parent1.id, 1, 6], [parent1.root_id, parent1.lft, parent1.rgt]
-    assert_equal [parent2.id, 1, 2], [parent2.root_id, parent2.lft, parent2.rgt]
-    assert_equal [parent1.id, 2, 5], [child.root_id, child.lft, child.rgt]
-    assert_equal [parent1.id, 3, 4], [grandchild.root_id, grandchild.lft, grandchild.rgt]
-
-    child.reload.parent_issue_id = parent2.id
-    child.save!
-    child.reload
-    grandchild.reload
-    parent1.reload
-    parent2.reload
-
-    assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt]
-    assert_equal [parent2.id, 1, 6], [parent2.root_id, parent2.lft, parent2.rgt]
-    assert_equal [parent2.id, 2, 5], [child.root_id, child.lft, child.rgt]
-    assert_equal [parent2.id, 3, 4], [grandchild.root_id, grandchild.lft, grandchild.rgt]
-  end
-
-  def test_move_a_child_with_descendants_to_another_project
-    parent1 = create_issue!
-    child =   create_issue!(:parent_issue_id => parent1.id)
-    grandchild = create_issue!(:parent_issue_id => child.id)
-
-    assert child.reload.move_to_project(Project.find(2))
-    child.reload
-    grandchild.reload
-    parent1.reload
-
-    assert_equal [1, parent1.id, 1, 2], [parent1.project_id, parent1.root_id, parent1.lft, parent1.rgt]
-    assert_equal [2, child.id, 1, 4], [child.project_id, child.root_id, child.lft, child.rgt]
-    assert_equal [2, child.id, 2, 3], [grandchild.project_id, grandchild.root_id, grandchild.lft, grandchild.rgt]
-  end
-
-  def test_invalid_move_to_another_project
-    parent1 = create_issue!
-    child =   create_issue!(:parent_issue_id => parent1.id)
-    grandchild = create_issue!(:parent_issue_id => child.id, :tracker_id => 2)
-    Project.find(2).tracker_ids = [1]
-
-    parent1.reload
-    assert_equal [1, parent1.id, 1, 6], [parent1.project_id, parent1.root_id, parent1.lft, parent1.rgt]
-
-    # child can not be moved to Project 2 because its child is on a disabled tracker
-    assert_equal false, Issue.find(child.id).move_to_project(Project.find(2))
-    child.reload
-    grandchild.reload
-    parent1.reload
-
-    # no change
-    assert_equal [1, parent1.id, 1, 6], [parent1.project_id, parent1.root_id, parent1.lft, parent1.rgt]
-    assert_equal [1, parent1.id, 2, 5], [child.project_id, child.root_id, child.lft, child.rgt]
-    assert_equal [1, parent1.id, 3, 4], [grandchild.project_id, grandchild.root_id, grandchild.lft, grandchild.rgt]
-  end
-
-  def test_moving_an_issue_to_a_descendant_should_not_validate
-    parent1 = create_issue!
-    parent2 = create_issue!
-    child =   create_issue!(:parent_issue_id => parent1.id)
-    grandchild = create_issue!(:parent_issue_id => child.id)
-
-    child.reload
-    child.parent_issue_id = grandchild.id
-    assert !child.save
-    assert_not_nil child.errors[:parent_issue_id]
-  end
-
-  def test_moving_an_issue_should_keep_valid_relations_only
-    issue1 = create_issue!
-    issue2 = create_issue!
-    issue3 = create_issue!(:parent_issue_id => issue2.id)
-    issue4 = create_issue!
-    r1 = IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
-    r2 = IssueRelation.create!(:issue_from => issue1, :issue_to => issue3, :relation_type => IssueRelation::TYPE_PRECEDES)
-    r3 = IssueRelation.create!(:issue_from => issue2, :issue_to => issue4, :relation_type => IssueRelation::TYPE_PRECEDES)
-    issue2.reload
-    issue2.parent_issue_id = issue1.id
-    issue2.save!
-    assert !IssueRelation.exists?(r1.id)
-    assert !IssueRelation.exists?(r2.id)
-    assert IssueRelation.exists?(r3.id)
-  end
-
-  def test_destroy_should_destroy_children
-    issue1 = create_issue!
-    issue2 = create_issue!
-    issue3 = create_issue!(:parent_issue_id => issue2.id)
-    issue4 = create_issue!(:parent_issue_id => issue1.id)
-
-    issue3.init_journal(User.find(2))
-    issue3.subject = 'child with journal'
-    issue3.save!
-
-    assert_difference 'Issue.count', -2 do
-      assert_difference 'Journal.count', -1 do
-        assert_difference 'JournalDetail.count', -1 do
-          Issue.find(issue2.id).destroy
-        end
-      end
-    end
-
-    issue1.reload
-    issue4.reload
-    assert !Issue.exists?(issue2.id)
-    assert !Issue.exists?(issue3.id)
-    assert_equal [issue1.id, 1, 4], [issue1.root_id, issue1.lft, issue1.rgt]
-    assert_equal [issue1.id, 2, 3], [issue4.root_id, issue4.lft, issue4.rgt]
-  end
-  
-  def test_destroy_child_should_update_parent
-    issue = create_issue!
-    child1 = create_issue!(:parent_issue_id => issue.id)
-    child2 = create_issue!(:parent_issue_id => issue.id)
-    
-    issue.reload
-    assert_equal [issue.id, 1, 6], [issue.root_id, issue.lft, issue.rgt]
-    
-    child2.reload.destroy
-    
-    issue.reload
-    assert_equal [issue.id, 1, 4], [issue.root_id, issue.lft, issue.rgt]
-  end
-
-  def test_destroy_parent_issue_updated_during_children_destroy
-    parent = create_issue!
-    create_issue!(:start_date => Date.today, :parent_issue_id => parent.id)
-    create_issue!(:start_date => 2.days.from_now, :parent_issue_id => parent.id)
-
-    assert_difference 'Issue.count', -3 do
-      Issue.find(parent.id).destroy
-    end
-  end
-
-  def test_destroy_child_issue_with_children
-    root = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'root')
-    child = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => root.id)
-    leaf = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'leaf', :parent_issue_id => child.id)
-    leaf.init_journal(User.find(2))
-    leaf.subject = 'leaf with journal'
-    leaf.save!
-
-    assert_difference 'Issue.count', -2 do
-      assert_difference 'Journal.count', -1 do
-        assert_difference 'JournalDetail.count', -1 do
-          Issue.find(child.id).destroy
-        end
-      end
-    end
-
-    root = Issue.find(root.id)
-    assert root.leaf?, "Root issue is not a leaf (lft: #{root.lft}, rgt: #{root.rgt})"
-  end
-
-  def test_destroy_issue_with_grand_child
-    parent = create_issue!
-    issue = create_issue!(:parent_issue_id => parent.id)
-    child = create_issue!(:parent_issue_id => issue.id)
-    grandchild1 = create_issue!(:parent_issue_id => child.id)
-    grandchild2 = create_issue!(:parent_issue_id => child.id)
-
-    assert_difference 'Issue.count', -4 do
-      Issue.find(issue.id).destroy
-      parent.reload
-      assert_equal [1, 2], [parent.lft, parent.rgt]
-    end
-  end
-
-  def test_parent_priority_should_be_the_highest_child_priority
-    parent = create_issue!(:priority => IssuePriority.find_by_name('Normal'))
-    # Create children
-    child1 = create_issue!(:priority => IssuePriority.find_by_name('High'), :parent_issue_id => parent.id)
-    assert_equal 'High', parent.reload.priority.name
-    child2 = create_issue!(:priority => IssuePriority.find_by_name('Immediate'), :parent_issue_id => child1.id)
-    assert_equal 'Immediate', child1.reload.priority.name
-    assert_equal 'Immediate', parent.reload.priority.name
-    child3 = create_issue!(:priority => IssuePriority.find_by_name('Low'), :parent_issue_id => parent.id)
-    assert_equal 'Immediate', parent.reload.priority.name
-    # Destroy a child
-    child1.destroy
-    assert_equal 'Low', parent.reload.priority.name
-    # Update a child
-    child3.reload.priority = IssuePriority.find_by_name('Normal')
-    child3.save!
-    assert_equal 'Normal', parent.reload.priority.name
-  end
-
-  def test_parent_dates_should_be_lowest_start_and_highest_due_dates
-    parent = create_issue!
-    create_issue!(:start_date => '2010-01-25', :due_date => '2010-02-15', :parent_issue_id => parent.id)
-    create_issue!(                             :due_date => '2010-02-13', :parent_issue_id => parent.id)
-    create_issue!(:start_date => '2010-02-01', :due_date => '2010-02-22', :parent_issue_id => parent.id)
-    parent.reload
-    assert_equal Date.parse('2010-01-25'), parent.start_date
-    assert_equal Date.parse('2010-02-22'), parent.due_date
-  end
-
-  def test_parent_done_ratio_should_be_average_done_ratio_of_leaves
-    parent = create_issue!
-    create_issue!(:done_ratio => 20, :parent_issue_id => parent.id)
-    assert_equal 20, parent.reload.done_ratio
-    create_issue!(:done_ratio => 70, :parent_issue_id => parent.id)
-    assert_equal 45, parent.reload.done_ratio
-
-    child = create_issue!(:done_ratio => 0, :parent_issue_id => parent.id)
-    assert_equal 30, parent.reload.done_ratio
-
-    create_issue!(:done_ratio => 30, :parent_issue_id => child.id)
-    assert_equal 30, child.reload.done_ratio
-    assert_equal 40, parent.reload.done_ratio
-  end
-
-  def test_parent_done_ratio_should_be_weighted_by_estimated_times_if_any
-    parent = create_issue!
-    create_issue!(:estimated_hours => 10, :done_ratio => 20, :parent_issue_id => parent.id)
-    assert_equal 20, parent.reload.done_ratio
-    create_issue!(:estimated_hours => 20, :done_ratio => 50, :parent_issue_id => parent.id)
-    assert_equal (50 * 20 + 20 * 10) / 30, parent.reload.done_ratio
-  end
-
-  def test_parent_estimate_should_be_sum_of_leaves
-    parent = create_issue!
-    create_issue!(:estimated_hours => nil, :parent_issue_id => parent.id)
-    assert_equal nil, parent.reload.estimated_hours
-    create_issue!(:estimated_hours => 5, :parent_issue_id => parent.id)
-    assert_equal 5, parent.reload.estimated_hours
-    create_issue!(:estimated_hours => 7, :parent_issue_id => parent.id)
-    assert_equal 12, parent.reload.estimated_hours
-  end
-
-  def test_move_parent_updates_old_parent_attributes
-    first_parent = create_issue!
-    second_parent = create_issue!
-    child = create_issue!(:estimated_hours => 5, :parent_issue_id => first_parent.id)
-    assert_equal 5, first_parent.reload.estimated_hours
-    child.update_attributes(:estimated_hours => 7, :parent_issue_id => second_parent.id)
-    assert_equal 7, second_parent.reload.estimated_hours
-    assert_nil first_parent.reload.estimated_hours
-  end
-
-  def test_reschuling_a_parent_should_reschedule_subtasks
-    parent = create_issue!
-    c1 = create_issue!(:start_date => '2010-05-12', :due_date => '2010-05-18', :parent_issue_id => parent.id)
-    c2 = create_issue!(:start_date => '2010-06-03', :due_date => '2010-06-10', :parent_issue_id => parent.id)
-    parent.reload
-    parent.reschedule_after(Date.parse('2010-06-02'))
-    c1.reload
-    assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-08')], [c1.start_date, c1.due_date]
-    c2.reload
-    assert_equal [Date.parse('2010-06-03'), Date.parse('2010-06-10')], [c2.start_date, c2.due_date] # no change
-    parent.reload
-    assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-10')], [parent.start_date, parent.due_date]
-  end
-
-  def test_project_copy_should_copy_issue_tree
-    p = Project.create!(:name => 'Tree copy', :identifier => 'tree-copy', :tracker_ids => [1, 2])
-    i1 = create_issue!(:project_id => p.id, :subject => 'i1')
-    i2 = create_issue!(:project_id => p.id, :subject => 'i2', :parent_issue_id => i1.id)
-    i3 = create_issue!(:project_id => p.id, :subject => 'i3', :parent_issue_id => i1.id)
-    i4 = create_issue!(:project_id => p.id, :subject => 'i4', :parent_issue_id => i2.id)
-    i5 = create_issue!(:project_id => p.id, :subject => 'i5')
-    c = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1, 2])
-    c.copy(p, :only => 'issues')
-    c.reload
-
-    assert_equal 5, c.issues.count
-    ic1, ic2, ic3, ic4, ic5 = c.issues.find(:all, :order => 'subject')
-    assert ic1.root?
-    assert_equal ic1, ic2.parent
-    assert_equal ic1, ic3.parent
-    assert_equal ic2, ic4.parent
-    assert ic5.root?
-  end
-
-  # Helper that creates an issue with default attributes
-  def create_issue!(attributes={})
-    Issue.create!({:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'test'}.merge(attributes))
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8b/8b54895a280a4b6be2315b819f9e36a6caaa65f2.svn-base
--- /dev/null
+++ b/.svn/pristine/8b/8b54895a280a4b6be2315b819f9e36a6caaa65f2.svn-base
@@ -0,0 +1,23 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class TimeEntryCustomField < CustomField
+  def type_name
+    :label_spent_time
+  end
+end
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8b/8b6b9cb4de924997fd5c8d066cf49e5fb943de93.svn-base
--- /dev/null
+++ b/.svn/pristine/8b/8b6b9cb4de924997fd5c8d066cf49e5fb943de93.svn-base
@@ -0,0 +1,56 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class CalendarsController < ApplicationController
+  menu_item :calendar
+  before_filter :find_optional_project
+
+  rescue_from Query::StatementInvalid, :with => :query_statement_invalid
+
+  helper :issues
+  helper :projects
+  helper :queries
+  include QueriesHelper
+  helper :sort
+  include SortHelper
+
+  def show
+    if params[:year] and params[:year].to_i > 1900
+      @year = params[:year].to_i
+      if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
+        @month = params[:month].to_i
+      end
+    end
+    @year ||= Date.today.year
+    @month ||= Date.today.month
+
+    @calendar = Redmine::Helpers::Calendar.new(Date.civil(@year, @month, 1), current_language, :month)
+    retrieve_query
+    @query.group_by = nil
+    if @query.valid?
+      events = []
+      events += @query.issues(:include => [:tracker, :assigned_to, :priority],
+                              :conditions => ["((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?))", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt]
+                              )
+      events += @query.versions(:conditions => ["effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt])
+
+      @calendar.events = events
+    end
+
+    render :action => 'show', :layout => false if request.xhr?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8b/8b8a4a4fb98bb4ad97ae1d153aef221af93fc010.svn-base
--- /dev/null
+++ b/.svn/pristine/8b/8b8a4a4fb98bb4ad97ae1d153aef221af93fc010.svn-base
@@ -0,0 +1,43 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+desc <<-END_DESC
+Send reminders about issues due in the next days.
+
+Available options:
+  * days     => number of days to remind about (defaults to 7)
+  * tracker  => id of tracker (defaults to all trackers)
+  * project  => id or identifier of project (defaults to all projects)
+  * users    => comma separated list of user/group ids who should be reminded
+
+Example:
+  rake redmine:send_reminders days=7 users="1,23, 56" RAILS_ENV="production"
+END_DESC
+
+namespace :redmine do
+  task :send_reminders => :environment do
+    options = {}
+    options[:days] = ENV['days'].to_i if ENV['days']
+    options[:project] = ENV['project'] if ENV['project']
+    options[:tracker] = ENV['tracker'].to_i if ENV['tracker']
+    options[:users] = (ENV['users'] || '').split(',').each(&:strip!)
+
+    Mailer.with_synched_deliveries do
+      Mailer.reminders(options)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8b/8b8ba498cf3cdcb76cdc45e1ecf9d424b5e9b3cc.svn-base
--- /dev/null
+++ b/.svn/pristine/8b/8b8ba498cf3cdcb76cdc45e1ecf9d424b5e9b3cc.svn-base
@@ -0,0 +1,71 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module MyHelper
+  def calendar_items(startdt, enddt)
+    Issue.visible.
+      where(:project_id => User.current.projects.map(&:id)).
+      where("(start_date>=? and start_date<=?) or (due_date>=? and due_date<=?)", startdt, enddt, startdt, enddt).
+      includes(:project, :tracker, :priority, :assigned_to).
+      all
+  end
+
+  def documents_items
+    Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).all
+  end
+
+  def issuesassignedtome_items
+    Issue.visible.open.
+      where(:assigned_to_id => ([User.current.id] + User.current.group_ids)).
+      limit(10).
+      includes(:status, :project, :tracker, :priority).
+      order("#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC").
+      all
+  end
+
+  def issuesreportedbyme_items
+    Issue.visible.
+      where(:author_id => User.current.id).
+      limit(10).
+      includes(:status, :project, :tracker).
+      order("#{Issue.table_name}.updated_on DESC").
+      all
+  end
+
+  def issueswatched_items
+    Issue.visible.on_active_project.watched_by(User.current.id).recently_updated.limit(10).all
+  end
+
+  def news_items
+    News.visible.
+      where(:project_id => User.current.projects.map(&:id)).
+      limit(10).
+      includes(:project, :author).
+      order("#{News.table_name}.created_on DESC").
+      all
+  end
+
+  def timelog_items
+    TimeEntry.
+      where("#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", User.current.id, Date.today - 6, Date.today).
+      includes(:activity, :project, {:issue => [:tracker, :status]}).
+      order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC").
+      all
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8b/8bb9ae19f70bfe10707fcbca8e4a7cb4cc52174d.svn-base
--- a/.svn/pristine/8b/8bb9ae19f70bfe10707fcbca8e4a7cb4cc52174d.svn-base
+++ /dev/null
@@ -1,44 +0,0 @@
-<%= error_messages_for 'auth_source' %>
-
-<div class="box">
-<!--[form:auth_source]-->
-<p><label for="auth_source_name"><%=l(:field_name)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'name'  %></p>
-
-<p><label for="auth_source_host"><%=l(:field_host)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'host'  %></p>
-
-<p><label for="auth_source_port"><%=l(:field_port)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'port', :size => 6 %> <%= check_box 'auth_source', 'tls'  %> LDAPS</p>
-
-<p><label for="auth_source_account"><%=l(:field_account)%></label>
-<%= text_field 'auth_source', 'account'  %></p>
-
-<p><label for="auth_source_account_password"><%=l(:field_password)%></label>
-<%= password_field 'auth_source', 'account_password', :name => 'ignore',
-                                           :value => ((@auth_source.new_record? || @auth_source.account_password.blank?) ? '' : ('x'*15)),
-                                           :onfocus => "this.value=''; this.name='auth_source[account_password]';",
-                                           :onchange => "this.name='auth_source[account_password]';" %></p>
-
-<p><label for="auth_source_base_dn"><%=l(:field_base_dn)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'base_dn', :size => 60 %></p>
-
-<p><label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label>
-<%= check_box 'auth_source', 'onthefly_register' %></p>
-</div>
-
-<fieldset class="box"><legend><%=l(:label_attribute_plural)%></legend>
-<p><label for="auth_source_attr_login"><%=l(:field_login)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'attr_login', :size => 20  %></p>
-
-<p><label for="auth_source_attr_firstname"><%=l(:field_firstname)%></label>
-<%= text_field 'auth_source', 'attr_firstname', :size => 20  %></p>
-
-<p><label for="auth_source_attr_lastname"><%=l(:field_lastname)%></label>
-<%= text_field 'auth_source', 'attr_lastname', :size => 20  %></p>
-
-<p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label>
-<%= text_field 'auth_source', 'attr_mail', :size => 20  %></p>
-</fieldset>
-<!--[eoform:auth_source]-->
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8b/8bc1e7aab7b493f12083c3af8e8303e9dd4b73f1.svn-base
--- /dev/null
+++ b/.svn/pristine/8b/8bc1e7aab7b493f12083c3af8e8303e9dd4b73f1.svn-base
@@ -0,0 +1,269 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::I18nTest < ActiveSupport::TestCase
+  include Redmine::I18n
+  include ActionView::Helpers::NumberHelper
+
+  def setup
+    User.current.language = nil
+  end
+
+  def teardown
+    set_language_if_valid 'en'
+  end
+
+  def test_date_format_default
+    set_language_if_valid 'en'
+    today = Date.today
+    Setting.date_format = ''
+    assert_equal I18n.l(today), format_date(today)
+  end
+
+  def test_date_format
+    set_language_if_valid 'en'
+    today = Date.today
+    Setting.date_format = '%d %m %Y'
+    assert_equal today.strftime('%d %m %Y'), format_date(today)
+  end
+
+  def test_date_format_default_with_user_locale
+    set_language_if_valid 'es'
+    today = now = Time.parse('2011-02-20 14:00:00')
+    Setting.date_format = '%d %B %Y'
+    User.current.language = 'fr'
+    s1 = "20 f\xc3\xa9vrier 2011"
+    s1.force_encoding("UTF-8") if s1.respond_to?(:force_encoding)
+    assert_equal s1, format_date(today)
+    User.current.language = nil
+    assert_equal '20 Febrero 2011', format_date(today)
+  end
+
+  def test_date_and_time_for_each_language
+    Setting.date_format = ''
+    valid_languages.each do |lang|
+      set_language_if_valid lang
+      assert_nothing_raised "#{lang} failure" do
+        format_date(Date.today)
+        format_time(Time.now)
+        format_time(Time.now, false)
+        assert_not_equal 'default', ::I18n.l(Date.today, :format => :default),
+                         "date.formats.default missing in #{lang}"
+        assert_not_equal 'time',    ::I18n.l(Time.now, :format => :time),
+                         "time.formats.time missing in #{lang}"
+      end
+      assert l('date.day_names').is_a?(Array)
+      assert_equal 7, l('date.day_names').size
+
+      assert l('date.month_names').is_a?(Array)
+      assert_equal 13, l('date.month_names').size
+    end
+  end
+
+  def test_time_for_each_zone
+    ActiveSupport::TimeZone.all.each do |zone|
+      User.current.stubs(:time_zone).returns(zone.name)
+      assert_nothing_raised "#{zone} failure" do
+        format_time(Time.now)
+      end
+    end
+  end
+
+  def test_time_format
+    set_language_if_valid 'en'
+    now = Time.parse('2011-02-20 15:45:22')
+    with_settings :time_format => '%H:%M' do
+      with_settings :date_format => '' do
+        assert_equal '02/20/2011 15:45', format_time(now)
+        assert_equal '15:45', format_time(now, false)
+      end
+      with_settings :date_format => '%Y-%m-%d' do
+        assert_equal '2011-02-20 15:45', format_time(now)
+        assert_equal '15:45', format_time(now, false)
+      end
+    end
+  end
+
+  def test_time_format_default
+    set_language_if_valid 'en'
+    now = Time.parse('2011-02-20 15:45:22')
+    with_settings :time_format => '' do
+      with_settings :date_format => '' do
+        assert_equal '02/20/2011 03:45 pm', format_time(now)
+        assert_equal '03:45 pm', format_time(now, false)
+      end
+      with_settings :date_format => '%Y-%m-%d' do
+        assert_equal '2011-02-20 03:45 pm', format_time(now)
+        assert_equal '03:45 pm', format_time(now, false)
+      end
+    end
+  end
+
+  def test_time_format_default_with_user_locale
+    set_language_if_valid 'en'
+    User.current.language = 'fr'
+    now = Time.parse('2011-02-20 15:45:22')
+    with_settings :time_format => '' do
+      with_settings :date_format => '' do
+        assert_equal '20/02/2011 15:45', format_time(now)
+        assert_equal '15:45', format_time(now, false)
+      end
+      with_settings :date_format => '%Y-%m-%d' do
+        assert_equal '2011-02-20 15:45', format_time(now)
+        assert_equal '15:45', format_time(now, false)
+      end
+    end
+  end
+
+  def test_time_format
+    set_language_if_valid 'en'
+    now = Time.now
+    Setting.date_format = '%d %m %Y'
+    Setting.time_format = '%H %M'
+    assert_equal now.strftime('%d %m %Y %H %M'), format_time(now)
+    assert_equal now.strftime('%H %M'), format_time(now, false)
+  end
+
+  def test_utc_time_format
+    set_language_if_valid 'en'
+    now = Time.now
+    Setting.date_format = '%d %m %Y'
+    Setting.time_format = '%H %M'
+    assert_equal now.strftime('%d %m %Y %H %M'), format_time(now.utc)
+    assert_equal now.strftime('%H %M'), format_time(now.utc, false)
+  end
+
+  def test_number_to_human_size_for_each_language
+    valid_languages.each do |lang|
+      set_language_if_valid lang
+      assert_nothing_raised "#{lang} failure" do
+        size = number_to_human_size(257024)
+        assert_match /251/, size
+      end
+    end
+  end
+
+  def test_day_name
+    set_language_if_valid 'fr'
+    assert_equal 'dimanche', day_name(0)
+    assert_equal 'jeudi', day_name(4)
+  end
+
+  def test_day_letter
+    set_language_if_valid 'fr'
+    assert_equal 'd', day_letter(0)
+    assert_equal 'j', day_letter(4)
+  end
+
+  def test_number_to_currency_for_each_language
+    valid_languages.each do |lang|
+      set_language_if_valid lang
+      assert_nothing_raised "#{lang} failure" do
+        number_to_currency(-1000.2)
+      end
+    end
+  end
+
+  def test_number_to_currency_default
+    set_language_if_valid 'bs'
+    assert_equal "KM -1000,20", number_to_currency(-1000.2)
+    set_language_if_valid 'de'
+    euro_sign = "\xe2\x82\xac"
+    euro_sign.force_encoding('UTF-8') if euro_sign.respond_to?(:force_encoding)
+    assert_equal "-1000,20 #{euro_sign}", number_to_currency(-1000.2)
+  end
+
+  def test_valid_languages
+    assert valid_languages.is_a?(Array)
+    assert valid_languages.first.is_a?(Symbol)
+  end
+
+  def test_languages_options
+    options = languages_options
+
+    assert options.is_a?(Array)
+    assert_equal valid_languages.size, options.size
+    assert_nil options.detect {|option| !option.is_a?(Array)}
+    assert_nil options.detect {|option| option.size != 2}
+    assert_nil options.detect {|option| !option.first.is_a?(String) || !option.last.is_a?(String)}
+    assert_include ["English", "en"], options
+  end
+
+  def test_locales_validness
+    lang_files_count = Dir["#{Rails.root}/config/locales/*.yml"].size
+    assert_equal lang_files_count, valid_languages.size
+    valid_languages.each do |lang|
+      assert set_language_if_valid(lang)
+    end
+    set_language_if_valid('en')
+  end
+
+  def test_valid_language
+    to_test = {'fr' => :fr,
+               'Fr' => :fr,
+               'zh' => :zh,
+               'zh-tw' => :"zh-TW",
+               'zh-TW' => :"zh-TW",
+               'zh-ZZ' => nil }
+    to_test.each {|lang, expected| assert_equal expected, find_language(lang)}
+  end
+
+  def test_fallback
+    ::I18n.backend.store_translations(:en, {:untranslated => "Untranslated string"})
+    ::I18n.locale = 'en'
+    assert_equal "Untranslated string", l(:untranslated)
+    ::I18n.locale = 'fr'
+    assert_equal "Untranslated string", l(:untranslated)
+
+    ::I18n.backend.store_translations(:fr, {:untranslated => "Pas de traduction"})
+    ::I18n.locale = 'en'
+    assert_equal "Untranslated string", l(:untranslated)
+    ::I18n.locale = 'fr'
+    assert_equal "Pas de traduction", l(:untranslated)
+  end
+
+  def test_utf8
+    set_language_if_valid 'ja'
+    str_ja_yes  = "\xe3\x81\xaf\xe3\x81\x84"
+    i18n_ja_yes = l(:general_text_Yes)
+    if str_ja_yes.respond_to?(:force_encoding)
+      str_ja_yes.force_encoding('UTF-8')
+      assert_equal "UTF-8", i18n_ja_yes.encoding.to_s
+    end
+    assert_equal str_ja_yes, i18n_ja_yes
+  end
+
+  def test_traditional_chinese_locale
+    set_language_if_valid 'zh-TW'
+    str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
+    if str_tw.respond_to?(:force_encoding)
+      str_tw.force_encoding('UTF-8')
+    end
+    assert_equal str_tw, l(:general_lang_name)
+  end
+
+  def test_french_locale
+    set_language_if_valid 'fr'
+    str_fr = "Fran\xc3\xa7ais"
+    if str_fr.respond_to?(:force_encoding)
+      str_fr.force_encoding('UTF-8')
+    end
+    assert_equal str_fr, l(:general_lang_name)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8b/8bccd0624e4f8225c7389853d52b177216bc29f0.svn-base
--- /dev/null
+++ b/.svn/pristine/8b/8bccd0624e4f8225c7389853d52b177216bc29f0.svn-base
@@ -0,0 +1,89 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class ContextMenusController < ApplicationController
+  helper :watchers
+  helper :issues
+
+  def issues
+    @issues = Issue.visible.all(:conditions => {:id => params[:ids]}, :include => :project)
+    (render_404; return) unless @issues.present?
+    if (@issues.size == 1)
+      @issue = @issues.first
+    end
+    @issue_ids = @issues.map(&:id).sort
+
+    @allowed_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
+    @projects = @issues.collect(&:project).compact.uniq
+    @project = @projects.first if @projects.size == 1
+
+    @can = {:edit => User.current.allowed_to?(:edit_issues, @projects),
+            :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
+            :update => (User.current.allowed_to?(:edit_issues, @projects) || (User.current.allowed_to?(:change_status, @projects) && !@allowed_statuses.blank?)),
+            :move => (@project && User.current.allowed_to?(:move_issues, @project)),
+            :copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
+            :delete => User.current.allowed_to?(:delete_issues, @projects)
+            }
+    if @project
+      if @issue
+        @assignables = @issue.assignable_users
+      else
+        @assignables = @project.assignable_users
+      end
+      @trackers = @project.trackers
+    else
+      #when multiple projects, we only keep the intersection of each set
+      @assignables = @projects.map(&:assignable_users).reduce(:&)
+      @trackers = @projects.map(&:trackers).reduce(:&)
+    end
+    @versions = @projects.map {|p| p.shared_versions.open}.reduce(:&)
+
+    @priorities = IssuePriority.active.reverse
+    @back = back_url
+
+    @options_by_custom_field = {}
+    if @can[:edit]
+      custom_fields = @issues.map(&:available_custom_fields).reduce(:&).select do |f|
+        %w(bool list user version).include?(f.field_format) && !f.multiple?
+      end
+      custom_fields.each do |field|
+        values = field.possible_values_options(@projects)
+        if values.any?
+          @options_by_custom_field[field] = values
+        end
+      end
+    end
+
+    @safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&)
+    render :layout => false
+  end
+
+  def time_entries
+    @time_entries = TimeEntry.all(
+       :conditions => {:id => params[:ids]}, :include => :project)
+    (render_404; return) unless @time_entries.present?
+
+    @projects = @time_entries.collect(&:project).compact.uniq
+    @project = @projects.first if @projects.size == 1
+    @activities = TimeEntryActivity.shared.active
+    @can = {:edit   => User.current.allowed_to?(:edit_time_entries, @projects),
+            :delete => User.current.allowed_to?(:edit_time_entries, @projects)
+            }
+    @back = back_url
+    render :layout => false
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8c/8c1d2e96303e1f62e53705f1a07477a847f9fb94.svn-base
--- /dev/null
+++ b/.svn/pristine/8c/8c1d2e96303e1f62e53705f1a07477a847f9fb94.svn-base
@@ -0,0 +1,135 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class TimeEntryTest < ActiveSupport::TestCase
+  fixtures :issues, :projects, :users, :time_entries,
+           :members, :roles, :member_roles,
+           :trackers, :issue_statuses,
+           :projects_trackers,
+           :journals, :journal_details,
+           :issue_categories, :enumerations,
+           :groups_users,
+           :enabled_modules
+
+  def test_hours_format
+    assertions = { "2"      => 2.0,
+                   "21.1"   => 21.1,
+                   "2,1"    => 2.1,
+                   "1,5h"   => 1.5,
+                   "7:12"   => 7.2,
+                   "10h"    => 10.0,
+                   "10 h"   => 10.0,
+                   "45m"    => 0.75,
+                   "45 m"   => 0.75,
+                   "3h15"   => 3.25,
+                   "3h 15"  => 3.25,
+                   "3 h 15"   => 3.25,
+                   "3 h 15m"  => 3.25,
+                   "3 h 15 m" => 3.25,
+                   "3 hours"  => 3.0,
+                   "12min"    => 0.2,
+                   "12 Min"    => 0.2,
+                  }
+
+    assertions.each do |k, v|
+      t = TimeEntry.new(:hours => k)
+      assert_equal v, t.hours, "Converting #{k} failed:"
+    end
+  end
+
+  def test_hours_should_default_to_nil
+    assert_nil TimeEntry.new.hours
+  end
+
+  def test_spent_on_with_blank
+    c = TimeEntry.new
+    c.spent_on = ''
+    assert_nil c.spent_on
+  end
+
+  def test_spent_on_with_nil
+    c = TimeEntry.new
+    c.spent_on = nil
+    assert_nil c.spent_on
+  end
+
+  def test_spent_on_with_string
+    c = TimeEntry.new
+    c.spent_on = "2011-01-14"
+    assert_equal Date.parse("2011-01-14"), c.spent_on
+  end
+
+  def test_spent_on_with_invalid_string
+    c = TimeEntry.new
+    c.spent_on = "foo"
+    assert_nil c.spent_on
+  end
+
+  def test_spent_on_with_date
+    c = TimeEntry.new
+    c.spent_on = Date.today
+    assert_equal Date.today, c.spent_on
+  end
+
+  def test_spent_on_with_time
+    c = TimeEntry.new
+    c.spent_on = Time.now
+    assert_equal Date.today, c.spent_on
+  end
+
+  def test_validate_time_entry
+    anon     = User.anonymous
+    project  = Project.find(1)
+    issue    = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => anon.id, :status_id => 1,
+                         :priority => IssuePriority.all.first, :subject => 'test_create',
+                         :description => 'IssueTest#test_create', :estimated_hours => '1:30')
+    assert issue.save
+    activity = TimeEntryActivity.find_by_name('Design')
+    te = TimeEntry.create(:spent_on => '2010-01-01',
+                          :hours    => 100000,
+                          :issue    => issue,
+                          :project  => project,
+                          :user     => anon,
+                          :activity => activity)
+    assert_equal 1, te.errors.count
+  end
+
+  def test_spent_on_with_2_digits_year_should_not_be_valid
+    entry = TimeEntry.new(:project => Project.find(1), :user => User.find(1), :activity => TimeEntryActivity.first, :hours => 1)
+    entry.spent_on = "09-02-04"
+    assert !entry.valid?
+    assert_include I18n.translate('activerecord.errors.messages.not_a_date'), entry.errors[:spent_on]
+  end
+
+  def test_set_project_if_nil
+    anon     = User.anonymous
+    project  = Project.find(1)
+    issue    = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => anon.id, :status_id => 1,
+                         :priority => IssuePriority.all.first, :subject => 'test_create',
+                         :description => 'IssueTest#test_create', :estimated_hours => '1:30')
+    assert issue.save
+    activity = TimeEntryActivity.find_by_name('Design')
+    te = TimeEntry.create(:spent_on => '2010-01-01',
+                          :hours    => 10,
+                          :issue    => issue,
+                          :user     => anon,
+                          :activity => activity)
+    assert_equal project.id, te.project.id
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8c/8c336a0caf0b197036e75f77b3fda9e373c1dbe0.svn-base
--- /dev/null
+++ b/.svn/pristine/8c/8c336a0caf0b197036e75f77b3fda9e373c1dbe0.svn-base
@@ -0,0 +1,1125 @@
+# Spanish translations for Rails
+# by Francisco Fernando GarcÃ­a Nieto (ffgarcianieto@gmail.com)
+# Redmine spanish translation:
+# by J. Cayetano Delgado (Cayetano _dot_ Delgado _at_ ioko _dot_ com)
+
+es:
+  number:
+    # Used in number_with_delimiter()
+    # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+    format:
+      # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+      separator: ","
+      # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
+      delimiter: "."
+      # Number of decimals, behind the separator (1 with a precision of 2 gives: 1.00)
+      precision: 3
+
+    # Used in number_to_currency()
+    currency:
+      format:
+        # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+        format: "%n %u"
+        unit: "â‚¬"
+        # These three are to override number.format and are optional
+        separator: ","
+        delimiter: "."
+        precision: 2
+
+    # Used in number_to_percentage()
+    percentage:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # Used in number_to_precision()
+    precision:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # Used in number_to_human_size()
+    human:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+  datetime:
+    distance_in_words:
+      half_a_minute: "medio minuto"
+      less_than_x_seconds:
+        one:  "menos de 1 segundo"
+        other: "menos de %{count} segundos"
+      x_seconds:
+        one:  "1 segundo"
+        other: "%{count} segundos"
+      less_than_x_minutes:
+        one:  "menos de 1 minuto"
+        other: "menos de %{count} minutos"
+      x_minutes:
+        one:  "1 minuto"
+        other: "%{count} minutos"
+      about_x_hours:
+        one:  "alrededor de 1 hora"
+        other: "alrededor de %{count} horas"
+      x_hours:
+        one:   "1 hora"
+        other: "%{count} horas"
+      x_days:
+        one:  "1 dÃ­a"
+        other: "%{count} dÃ­as"
+      about_x_months:
+        one:  "alrededor de 1 mes"
+        other: "alrededor de %{count} meses"
+      x_months:
+        one:  "1 mes"
+        other: "%{count} meses"
+      about_x_years:
+        one:  "alrededor de 1 aÃ±o"
+        other: "alrededor de %{count} aÃ±os"
+      over_x_years:
+        one:  "mÃ¡s de 1 aÃ±o"
+        other: "mÃ¡s de %{count} aÃ±os"
+      almost_x_years:
+        one:   "casi 1 aÃ±o"
+        other: "casi %{count} aÃ±os"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:   "no se pudo guardar este %{model} porque se encontrÃ³ 1 error"
+          other:  "no se pudo guardar este %{model} porque se encontraron %{count} errores"
+        # The variable :count is also available
+        body: "Se encontraron problemas con los siguientes campos:"
+
+      # The values :model, :attribute and :value are always available for interpolation
+      # The value :count is available when applicable. Can be used for pluralization.
+      messages:
+        inclusion: "no estÃ¡ incluido en la lista"
+        exclusion: "estÃ¡ reservado"
+        invalid: "no es vÃ¡lido"
+        confirmation: "no coincide con la confirmaciÃ³n"
+        accepted: "debe ser aceptado"
+        empty: "no puede estar vacÃ­o"
+        blank: "no puede estar en blanco"
+        too_long: "es demasiado largo (%{count} caracteres mÃ¡ximo)"
+        too_short: "es demasiado corto (%{count} caracteres mÃ­nimo)"
+        wrong_length: "no tiene la longitud correcta (%{count} caracteres exactos)"
+        taken: "ya estÃ¡ en uso"
+        not_a_number: "no es un nÃºmero"
+        greater_than: "debe ser mayor que %{count}"
+        greater_than_or_equal_to: "debe ser mayor que o igual a %{count}"
+        equal_to: "debe ser igual a %{count}"
+        less_than: "debe ser menor que %{count}"
+        less_than_or_equal_to: "debe ser menor que o igual a %{count}"
+        odd: "debe ser impar"
+        even: "debe ser par"
+        greater_than_start_date: "debe ser posterior a la fecha de comienzo"
+        not_same_project: "no pertenece al mismo proyecto"
+        circular_dependency: "Esta relaciÃ³n podrÃ­a crear una dependencia circular"
+        cant_link_an_issue_with_a_descendant: "Esta peticiÃ³n no puede ser ligada a una de estas tareas"
+
+        # Append your own errors here or at the model/attributes scope.
+
+      models:
+        # Overrides default messages
+
+      attributes:
+        # Overrides model and default messages.
+
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%d de %b"
+      long: "%d de %B de %Y"
+
+    day_names: [Domingo, Lunes, Martes, MiÃ©rcoles, Jueves, Viernes, SÃ¡bado]
+    abbr_day_names: [Dom, Lun, Mar, Mie, Jue, Vie, Sab]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre]
+    abbr_month_names: [~, Ene, Feb, Mar, Abr, May, Jun, Jul, Ago, Sep, Oct, Nov, Dic]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%A, %d de %B de %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d de %b %H:%M"
+      long: "%d de %B de %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "y"
+
+  actionview_instancetag_blank_option: Por favor seleccione
+
+  button_activate: Activar
+  button_add: AÃ±adir
+  button_annotate: Anotar
+  button_apply: Aceptar
+  button_archive: Archivar
+  button_back: AtrÃ¡s
+  button_cancel: Cancelar
+  button_change: Cambiar
+  button_change_password: Cambiar contraseÃ±a
+  button_check_all: Seleccionar todo
+  button_clear: Anular
+  button_configure: Configurar
+  button_copy: Copiar
+  button_create: Crear
+  button_delete: Borrar
+  button_download: Descargar
+  button_edit: Modificar
+  button_list: Listar
+  button_lock: Bloquear
+  button_log_time: Tiempo dedicado
+  button_login: Acceder
+  button_move: Mover
+  button_quote: Citar
+  button_rename: Renombrar
+  button_reply: Responder
+  button_reset: Reestablecer
+  button_rollback: Volver a esta versiÃ³n
+  button_save: Guardar
+  button_sort: Ordenar
+  button_submit: Aceptar
+  button_test: Probar
+  button_unarchive: Desarchivar
+  button_uncheck_all: No seleccionar nada
+  button_unlock: Desbloquear
+  button_unwatch: No monitorizar
+  button_update: Actualizar
+  button_view: Ver
+  button_watch: Monitorizar
+  default_activity_design: DiseÃ±o
+  default_activity_development: Desarrollo
+  default_doc_category_tech: DocumentaciÃ³n tÃ©cnica
+  default_doc_category_user: DocumentaciÃ³n de usuario
+  default_issue_status_in_progress: En curso
+  default_issue_status_closed: Cerrada
+  default_issue_status_feedback: Comentarios
+  default_issue_status_new: Nueva
+  default_issue_status_rejected: Rechazada
+  default_issue_status_resolved: Resuelta
+  default_priority_high: Alta
+  default_priority_immediate: Inmediata
+  default_priority_low: Baja
+  default_priority_normal: Normal
+  default_priority_urgent: Urgente
+  default_role_developer: Desarrollador
+  default_role_manager: Jefe de proyecto
+  default_role_reporter: Informador
+  default_tracker_bug: Errores
+  default_tracker_feature: Tareas
+  default_tracker_support: Soporte
+  enumeration_activities: Actividades (tiempo dedicado)
+  enumeration_doc_categories: CategorÃ­as del documento
+  enumeration_issue_priorities: Prioridad de las peticiones
+  error_can_t_load_default_data: "No se ha podido cargar la configuraciÃ³n por defecto: %{value}"
+  error_issue_not_found_in_project: 'La peticiÃ³n no se encuentra o no estÃ¡ asociada a este proyecto'
+  error_scm_annotate: "No existe la entrada o no ha podido ser anotada"
+  error_scm_annotate_big_text_file: "La entrada no puede anotarse, al superar el tamaÃ±o mÃ¡ximo para ficheros de texto."
+  error_scm_command_failed: "Se produjo un error al acceder al repositorio: %{value}"
+  error_scm_not_found: "La entrada y/o la revisiÃ³n no existe en el repositorio."
+  field_account: Cuenta
+  field_activity: Actividad
+  field_admin: Administrador
+  field_assignable: Se pueden asignar peticiones a este perfil
+  field_assigned_to: Asignado a
+  field_attr_firstname: Cualidad del nombre
+  field_attr_lastname: Cualidad del apellido
+  field_attr_login: Cualidad del identificador
+  field_attr_mail: Cualidad del Email
+  field_auth_source: Modo de identificaciÃ³n
+  field_author: Autor
+  field_base_dn: DN base
+  field_category: CategorÃ­a
+  field_column_names: Columnas
+  field_comments: Comentario
+  field_comments_sorting: Mostrar comentarios
+  field_created_on: Creado
+  field_default_value: Estado por defecto
+  field_delay: Retraso
+  field_description: DescripciÃ³n
+  field_done_ratio: "% Realizado"
+  field_downloads: Descargas
+  field_due_date: Fecha fin
+  field_effective_date: Fecha
+  field_estimated_hours: Tiempo estimado
+  field_field_format: Formato
+  field_filename: Fichero
+  field_filesize: TamaÃ±o
+  field_firstname: Nombre
+  field_fixed_version: VersiÃ³n prevista
+  field_hide_mail: Ocultar mi direcciÃ³n de correo
+  field_homepage: Sitio web
+  field_host: AnfitriÃ³n
+  field_hours: Horas
+  field_identifier: Identificador
+  field_is_closed: PeticiÃ³n resuelta
+  field_is_default: Estado por defecto
+  field_is_filter: Usado como filtro
+  field_is_for_all: Para todos los proyectos
+  field_is_in_roadmap: Consultar las peticiones en la planificaciÃ³n
+  field_is_public: PÃºblico
+  field_is_required: Obligatorio
+  field_issue: PeticiÃ³n
+  field_issue_to: PeticiÃ³n relacionada
+  field_language: Idioma
+  field_last_login_on: Ãšltima conexiÃ³n
+  field_lastname: Apellido
+  field_login: Identificador
+  field_mail: Correo electrÃ³nico
+  field_mail_notification: Notificaciones por correo
+  field_max_length: Longitud mÃ¡xima
+  field_min_length: Longitud mÃ­nima
+  field_name: Nombre
+  field_new_password: Nueva contraseÃ±a
+  field_notes: Notas
+  field_onthefly: CreaciÃ³n del usuario "al vuelo"
+  field_parent: Proyecto padre
+  field_parent_title: PÃ¡gina padre
+  field_password: ContraseÃ±a
+  field_password_confirmation: ConfirmaciÃ³n
+  field_port: Puerto
+  field_possible_values: Valores posibles
+  field_priority: Prioridad
+  field_project: Proyecto
+  field_redirect_existing_links: Redireccionar enlaces existentes
+  field_regexp: ExpresiÃ³n regular
+  field_role: Perfil
+  field_searchable: Incluir en las bÃºsquedas
+  field_spent_on: Fecha
+  field_start_date: Fecha de inicio
+  field_start_page: PÃ¡gina principal
+  field_status: Estado
+  field_subject: Asunto
+  field_subproject: Proyecto secundario
+  field_summary: Resumen
+  field_time_zone: Zona horaria
+  field_title: TÃ­tulo
+  field_tracker: Tipo
+  field_type: Tipo
+  field_updated_on: Actualizado
+  field_url: URL
+  field_user: Usuario
+  field_value: Valor
+  field_version: VersiÃ³n
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-15
+  general_csv_separator: ';'
+  general_first_day_of_week: '1'
+  general_lang_name: 'EspaÃ±ol'
+  general_pdf_encoding: UTF-8
+  general_text_No: 'No'
+  general_text_Yes: 'SÃ­'
+  general_text_no: 'no'
+  general_text_yes: 'sÃ­'
+  label_activity: Actividad
+  label_add_another_file: AÃ±adir otro fichero
+  label_add_note: AÃ±adir una nota
+  label_added: aÃ±adido
+  label_added_time_by: "AÃ±adido por %{author} hace %{age}"
+  label_administration: AdministraciÃ³n
+  label_age: Edad
+  label_ago: hace
+  label_all: todos
+  label_all_time: todo el tiempo
+  label_all_words: Todas las palabras
+  label_and_its_subprojects: "%{value} y proyectos secundarios"
+  label_applied_status: Aplicar estado
+  label_assigned_to_me_issues: Peticiones que me estÃ¡n asignadas
+  label_associated_revisions: Revisiones asociadas
+  label_attachment: Fichero
+  label_attachment_delete: Borrar el fichero
+  label_attachment_new: Nuevo fichero
+  label_attachment_plural: Ficheros
+  label_attribute: Cualidad
+  label_attribute_plural: Cualidades
+  label_auth_source: Modo de autenticaciÃ³n
+  label_auth_source_new: Nuevo modo de autenticaciÃ³n
+  label_auth_source_plural: Modos de autenticaciÃ³n
+  label_authentication: AutenticaciÃ³n
+  label_blocked_by: bloqueado por
+  label_blocks: bloquea a
+  label_board: Foro
+  label_board_new: Nuevo foro
+  label_board_plural: Foros
+  label_boolean: Booleano
+  label_browse: Hojear
+  label_bulk_edit_selected_issues: Editar las peticiones seleccionadas
+  label_calendar: Calendario
+  label_change_plural: Cambios
+  label_change_properties: Cambiar propiedades
+  label_change_status: Cambiar el estado
+  label_change_view_all: Ver todos los cambios
+  label_changes_details: Detalles de todos los cambios
+  label_changeset_plural: Cambios
+  label_chronological_order: En orden cronolÃ³gico
+  label_closed_issues: cerrada
+  label_closed_issues_plural: cerradas
+  label_x_open_issues_abbr_on_total:
+    zero:  0 abiertas / %{total}
+    one:   1 abierta / %{total}
+    other: "%{count} abiertas / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 abiertas
+    one:   1 abierta
+    other: "%{count} abiertas"
+  label_x_closed_issues_abbr:
+    zero:  0 cerradas
+    one:   1 cerrada
+    other: "%{count} cerradas"
+  label_comment: Comentario
+  label_comment_add: AÃ±adir un comentario
+  label_comment_added: Comentario aÃ±adido
+  label_comment_delete: Borrar comentarios
+  label_comment_plural: Comentarios
+  label_x_comments:
+    zero: sin comentarios
+    one: 1 comentario
+    other: "%{count} comentarios"
+  label_commits_per_author: Commits por autor
+  label_commits_per_month: Commits por mes
+  label_confirmation: ConfirmaciÃ³n
+  label_contains: contiene
+  label_copied: copiado
+  label_copy_workflow_from: Copiar flujo de trabajo desde
+  label_current_status: Estado actual
+  label_current_version: VersiÃ³n actual
+  label_custom_field: Campo personalizado
+  label_custom_field_new: Nuevo campo personalizado
+  label_custom_field_plural: Campos personalizados
+  label_date: Fecha
+  label_date_from: Desde
+  label_date_range: Rango de fechas
+  label_date_to: Hasta
+  label_day_plural: dÃ­as
+  label_default: Por defecto
+  label_default_columns: Columnas por defecto
+  label_deleted: suprimido
+  label_details: Detalles
+  label_diff_inline: en lÃ­nea
+  label_diff_side_by_side: cara a cara
+  label_disabled: deshabilitado
+  label_display_per_page: "Por pÃ¡gina: %{value}"
+  label_document: Documento
+  label_document_added: Documento aÃ±adido
+  label_document_new: Nuevo documento
+  label_document_plural: Documentos
+  label_downloads_abbr: D/L
+  label_duplicated_by: duplicada por
+  label_duplicates: duplicada de
+  label_end_to_end: fin a fin
+  label_end_to_start: fin a principio
+  label_enumeration_new: Nuevo valor
+  label_enumerations: Listas de valores
+  label_environment: Entorno
+  label_equals: igual
+  label_example: Ejemplo
+  label_export_to: 'Exportar a:'
+  label_f_hour: "%{value} hora"
+  label_f_hour_plural: "%{value} horas"
+  label_feed_plural: Feeds
+  label_feeds_access_key_created_on: "Clave de acceso por RSS creada hace %{value}"
+  label_file_added: Fichero aÃ±adido
+  label_file_plural: Archivos
+  label_filter_add: AÃ±adir el filtro
+  label_filter_plural: Filtros
+  label_float: Flotante
+  label_follows: posterior a
+  label_gantt: Gantt
+  label_general: General
+  label_generate_key: Generar clave
+  label_help: Ayuda
+  label_history: HistÃ³rico
+  label_home: Inicio
+  label_in: en
+  label_in_less_than: en menos que
+  label_in_more_than: en mÃ¡s que
+  label_incoming_emails: Correos entrantes
+  label_index_by_date: Ãndice por fecha
+  label_index_by_title: Ãndice por tÃ­tulo
+  label_information: InformaciÃ³n
+  label_information_plural: InformaciÃ³n
+  label_integer: NÃºmero
+  label_internal: Interno
+  label_issue: PeticiÃ³n
+  label_issue_added: PeticiÃ³n aÃ±adida
+  label_issue_category: CategorÃ­a de las peticiones
+  label_issue_category_new: Nueva categorÃ­a
+  label_issue_category_plural: CategorÃ­as de las peticiones
+  label_issue_new: Nueva peticiÃ³n
+  label_issue_plural: Peticiones
+  label_issue_status: Estado de la peticiÃ³n
+  label_issue_status_new: Nuevo estado
+  label_issue_status_plural: Estados de las peticiones
+  label_issue_tracking: Peticiones
+  label_issue_updated: PeticiÃ³n actualizada
+  label_issue_view_all: Ver todas las peticiones
+  label_issue_watchers: Seguidores
+  label_issues_by: "Peticiones por %{value}"
+  label_jump_to_a_project: Ir al proyecto...
+  label_language_based: Basado en el idioma
+  label_last_changes: "Ãºltimos %{count} cambios"
+  label_last_login: Ãšltima conexiÃ³n
+  label_last_month: Ãºltimo mes
+  label_last_n_days: "Ãºltimos %{count} dÃ­as"
+  label_last_week: Ãºltima semana
+  label_latest_revision: Ãšltima revisiÃ³n
+  label_latest_revision_plural: Ãšltimas revisiones
+  label_ldap_authentication: AutenticaciÃ³n LDAP
+  label_less_than_ago: hace menos de
+  label_list: Lista
+  label_loading: Cargando...
+  label_logged_as: Conectado como
+  label_login: Iniciar sesiÃ³n
+  label_logout: Terminar sesiÃ³n
+  label_max_size: TamaÃ±o mÃ¡ximo
+  label_me: yo mismo
+  label_member: Miembro
+  label_member_new: Nuevo miembro
+  label_member_plural: Miembros
+  label_message_last: Ãšltimo mensaje
+  label_message_new: Nuevo mensaje
+  label_message_plural: Mensajes
+  label_message_posted: Mensaje aÃ±adido
+  label_min_max_length: Longitud mÃ­n - mÃ¡x
+  label_modified: modificado
+  label_module_plural: MÃ³dulos
+  label_month: Mes
+  label_months_from: meses de
+  label_more: MÃ¡s
+  label_more_than_ago: hace mÃ¡s de
+  label_my_account: Mi cuenta
+  label_my_page: Mi pÃ¡gina
+  label_my_projects: Mis proyectos
+  label_new: Nuevo
+  label_new_statuses_allowed: Nuevos estados autorizados
+  label_news: Noticia
+  label_news_added: Noticia aÃ±adida
+  label_news_latest: Ãšltimas noticias
+  label_news_new: Nueva noticia
+  label_news_plural: Noticias
+  label_news_view_all: Ver todas las noticias
+  label_next: Siguiente
+  label_no_change_option: (Sin cambios)
+  label_no_data: NingÃºn dato disponible
+  label_nobody: nadie
+  label_none: ninguno
+  label_not_contains: no contiene
+  label_not_equals: no igual
+  label_open_issues: abierta
+  label_open_issues_plural: abiertas
+  label_optional_description: DescripciÃ³n opcional
+  label_options: Opciones
+  label_overall_activity: Actividad global
+  label_overview: Vistazo
+  label_password_lost: Â¿Olvidaste la contraseÃ±a?
+  label_per_page: Por pÃ¡gina
+  label_permissions: Permisos
+  label_permissions_report: Informe de permisos
+  label_personalize_page: Personalizar esta pÃ¡gina
+  label_planning: PlanificaciÃ³n
+  label_please_login: Por favor, inicie sesiÃ³n
+  label_plugins: Extensiones
+  label_precedes: anterior a
+  label_preferences: Preferencias
+  label_preview: Previsualizar
+  label_previous: Anterior
+  label_project: Proyecto
+  label_project_all: Todos los proyectos
+  label_project_latest: Ãšltimos proyectos
+  label_project_new: Nuevo proyecto
+  label_project_plural: Proyectos
+  label_x_projects:
+    zero:  sin proyectos
+    one:   1 proyecto
+    other: "%{count} proyectos"
+  label_public_projects: Proyectos pÃºblicos
+  label_query: Consulta personalizada
+  label_query_new: Nueva consulta
+  label_query_plural: Consultas personalizadas
+  label_read: Leer...
+  label_register: Registrar
+  label_registered_on: Inscrito el
+  label_registration_activation_by_email: activaciÃ³n de cuenta por correo
+  label_registration_automatic_activation: activaciÃ³n automÃ¡tica de cuenta
+  label_registration_manual_activation: activaciÃ³n manual de cuenta
+  label_related_issues: Peticiones relacionadas
+  label_relates_to: relacionada con
+  label_relation_delete: Eliminar relaciÃ³n
+  label_relation_new: Nueva relaciÃ³n
+  label_renamed: renombrado
+  label_reply_plural: Respuestas
+  label_report: Informe
+  label_report_plural: Informes
+  label_reported_issues: Peticiones registradas por mÃ­
+  label_repository: Repositorio
+  label_repository_plural: Repositorios
+  label_result_plural: Resultados
+  label_reverse_chronological_order: En orden cronolÃ³gico inverso
+  label_revision: RevisiÃ³n
+  label_revision_plural: Revisiones
+  label_roadmap: PlanificaciÃ³n
+  label_roadmap_due_in: "Finaliza en %{value}"
+  label_roadmap_no_issues: No hay peticiones para esta versiÃ³n
+  label_roadmap_overdue: "%{value} tarde"
+  label_role: Perfil
+  label_role_and_permissions: Perfiles y permisos
+  label_role_new: Nuevo perfil
+  label_role_plural: Perfiles
+  label_scm: SCM
+  label_search: BÃºsqueda
+  label_search_titles_only: Buscar sÃ³lo en tÃ­tulos
+  label_send_information: Enviar informaciÃ³n de la cuenta al usuario
+  label_send_test_email: Enviar un correo de prueba
+  label_settings: ConfiguraciÃ³n
+  label_show_completed_versions: Muestra las versiones terminadas
+  label_sort_by: "Ordenar por %{value}"
+  label_sort_higher: Subir
+  label_sort_highest: Primero
+  label_sort_lower: Bajar
+  label_sort_lowest: Ãšltimo
+  label_spent_time: Tiempo dedicado
+  label_start_to_end: principio a fin
+  label_start_to_start: principio a principio
+  label_statistics: EstadÃ­sticas
+  label_stay_logged_in: Mantener la sesiÃ³n abierta
+  label_string: Texto
+  label_subproject_plural: Proyectos secundarios
+  label_text: Texto largo
+  label_theme: Tema
+  label_this_month: este mes
+  label_this_week: esta semana
+  label_this_year: este aÃ±o
+  label_time_tracking: Control de tiempo
+  label_today: hoy
+  label_topic_plural: Temas
+  label_total: Total
+  label_tracker: Tipo
+  label_tracker_new: Nuevo tipo
+  label_tracker_plural: Tipos de peticiones
+  label_updated_time: "Actualizado hace %{value}"
+  label_updated_time_by: "Actualizado por %{author} hace %{age}"
+  label_used_by: Utilizado por
+  label_user: Usuario
+  label_user_activity: "Actividad de %{value}"
+  label_user_mail_no_self_notified: "No quiero ser avisado de cambios hechos por mÃ­"
+  label_user_mail_option_all: "Para cualquier evento en todos mis proyectos"
+  label_user_mail_option_selected: "Para cualquier evento de los proyectos seleccionados..."
+  label_user_new: Nuevo usuario
+  label_user_plural: Usuarios
+  label_version: VersiÃ³n
+  label_version_new: Nueva versiÃ³n
+  label_version_plural: Versiones
+  label_view_diff: Ver diferencias
+  label_view_revisions: Ver las revisiones
+  label_watched_issues: Peticiones monitorizadas
+  label_week: Semana
+  label_wiki: Wiki
+  label_wiki_edit: ModificaciÃ³n Wiki
+  label_wiki_edit_plural: Modificaciones Wiki
+  label_wiki_page: PÃ¡gina Wiki
+  label_wiki_page_plural: PÃ¡ginas Wiki
+  label_workflow: Flujo de trabajo
+  label_year: AÃ±o
+  label_yesterday: ayer
+  mail_body_account_activation_request: "Se ha inscrito un nuevo usuario (%{value}). La cuenta estÃ¡ pendiende de aprobaciÃ³n:"
+  mail_body_account_information: InformaciÃ³n sobre su cuenta
+  mail_body_account_information_external: "Puede usar su cuenta %{value} para conectarse."
+  mail_body_lost_password: 'Para cambiar su contraseÃ±a, haga clic en el siguiente enlace:'
+  mail_body_register: 'Para activar su cuenta, haga clic en el siguiente enlace:'
+  mail_body_reminder: "%{count} peticion(es) asignadas a tÃ­ finalizan en los prÃ³ximos %{days} dÃ­as:"
+  mail_subject_account_activation_request: "PeticiÃ³n de activaciÃ³n de cuenta %{value}"
+  mail_subject_lost_password: "Tu contraseÃ±a del %{value}"
+  mail_subject_register: "ActivaciÃ³n de la cuenta del %{value}"
+  mail_subject_reminder: "%{count} peticion(es) finalizan en los prÃ³ximos %{days} dÃ­as"
+  notice_account_activated: Su cuenta ha sido activada. Ya puede conectarse.
+  notice_account_invalid_creditentials: Usuario o contraseÃ±a invÃ¡lido.
+  notice_account_lost_email_sent: Se le ha enviado un correo con instrucciones para elegir una nueva contraseÃ±a.
+  notice_account_password_updated: ContraseÃ±a modificada correctamente.
+  notice_account_pending: "Su cuenta ha sido creada y estÃ¡ pendiende de la aprobaciÃ³n por parte del administrador."
+  notice_account_register_done: Cuenta creada correctamente. Para activarla, haga clic sobre el enlace que le ha sido enviado por correo.
+  notice_account_unknown_email: Usuario desconocido.
+  notice_account_updated: Cuenta actualizada correctamente.
+  notice_account_wrong_password: ContraseÃ±a incorrecta.
+  notice_can_t_change_password: Esta cuenta utiliza una fuente de autenticaciÃ³n externa. No es posible cambiar la contraseÃ±a.
+  notice_default_data_loaded: ConfiguraciÃ³n por defecto cargada correctamente.
+  notice_email_error: "Ha ocurrido un error mientras enviando el correo (%{value})"
+  notice_email_sent: "Se ha enviado un correo a %{value}"
+  notice_failed_to_save_issues: "Imposible grabar %{count} peticion(es) de %{total} seleccionada(s): %{ids}."
+  notice_feeds_access_key_reseted: Su clave de acceso para RSS ha sido reiniciada.
+  notice_file_not_found: La pÃ¡gina a la que intenta acceder no existe.
+  notice_locking_conflict: Los datos han sido modificados por otro usuario.
+  notice_no_issue_selected: "Ninguna peticiÃ³n seleccionada. Por favor, compruebe la peticiÃ³n que quiere modificar"
+  notice_not_authorized: No tiene autorizaciÃ³n para acceder a esta pÃ¡gina.
+  notice_successful_connection: ConexiÃ³n correcta.
+  notice_successful_create: CreaciÃ³n correcta.
+  notice_successful_delete: Borrado correcto.
+  notice_successful_update: ModificaciÃ³n correcta.
+  notice_unable_delete_version: No se puede borrar la versiÃ³n
+  permission_add_issue_notes: AÃ±adir notas
+  permission_add_issue_watchers: AÃ±adir seguidores
+  permission_add_issues: AÃ±adir peticiones
+  permission_add_messages: Enviar mensajes
+  permission_browse_repository: Hojear repositiorio
+  permission_comment_news: Comentar noticias
+  permission_commit_access: Acceso de escritura
+  permission_delete_issues: Borrar peticiones
+  permission_delete_messages: Borrar mensajes
+  permission_delete_own_messages: Borrar mensajes propios
+  permission_delete_wiki_pages: Borrar pÃ¡ginas wiki
+  permission_delete_wiki_pages_attachments: Borrar ficheros
+  permission_edit_issue_notes: Modificar notas
+  permission_edit_issues: Modificar peticiones
+  permission_edit_messages: Modificar mensajes
+  permission_edit_own_issue_notes: Modificar notas propias
+  permission_edit_own_messages: Editar mensajes propios
+  permission_edit_own_time_entries: Modificar tiempos dedicados propios
+  permission_edit_project: Modificar proyecto
+  permission_edit_time_entries: Modificar tiempos dedicados
+  permission_edit_wiki_pages: Modificar pÃ¡ginas wiki
+  permission_log_time: Anotar tiempo dedicado
+  permission_manage_boards: Administrar foros
+  permission_manage_categories: Administrar categorÃ­as de peticiones
+  permission_manage_files: Administrar ficheros
+  permission_manage_issue_relations: Administrar relaciÃ³n con otras peticiones
+  permission_manage_members: Administrar miembros
+  permission_manage_news: Administrar noticias
+  permission_manage_public_queries: Administrar consultas pÃºblicas
+  permission_manage_repository: Administrar repositorio
+  permission_manage_versions: Administrar versiones
+  permission_manage_wiki: Administrar wiki
+  permission_move_issues: Mover peticiones
+  permission_protect_wiki_pages: Proteger pÃ¡ginas wiki
+  permission_rename_wiki_pages: Renombrar pÃ¡ginas wiki
+  permission_save_queries: Grabar consultas
+  permission_select_project_modules: Seleccionar mÃ³dulos del proyecto
+  permission_view_calendar: Ver calendario
+  permission_view_changesets: Ver cambios
+  permission_view_documents: Ver documentos
+  permission_view_files: Ver ficheros
+  permission_view_gantt: Ver diagrama de Gantt
+  permission_view_issue_watchers: Ver lista de seguidores
+  permission_view_messages: Ver mensajes
+  permission_view_time_entries: Ver tiempo dedicado
+  permission_view_wiki_edits: Ver histÃ³rico del wiki
+  permission_view_wiki_pages: Ver wiki
+  project_module_boards: Foros
+  project_module_documents: Documentos
+  project_module_files: Ficheros
+  project_module_issue_tracking: Peticiones
+  project_module_news: Noticias
+  project_module_repository: Repositorio
+  project_module_time_tracking: Control de tiempo
+  project_module_wiki: Wiki
+  setting_activity_days_default: DÃ­as a mostrar en la actividad de proyecto
+  setting_app_subtitle: SubtÃ­tulo de la aplicaciÃ³n
+  setting_app_title: TÃ­tulo de la aplicaciÃ³n
+  setting_attachment_max_size: TamaÃ±o mÃ¡ximo del fichero
+  setting_autofetch_changesets: Autorellenar los commits del repositorio
+  setting_autologin: Inicio de sesiÃ³n automÃ¡tico
+  setting_bcc_recipients: Ocultar las copias de carbÃ³n (bcc)
+  setting_commit_fix_keywords: Palabras clave para la correcciÃ³n
+  setting_commit_ref_keywords: Palabras clave para la referencia
+  setting_cross_project_issue_relations: Permitir relacionar peticiones de distintos proyectos
+  setting_date_format: Formato de fecha
+  setting_default_language: Idioma por defecto
+  setting_default_projects_public: Los proyectos nuevos son pÃºblicos por defecto
+  setting_diff_max_lines_displayed: NÃºmero mÃ¡ximo de diferencias mostradas
+  setting_display_subprojects_issues: Mostrar por defecto peticiones de proy. secundarios en el principal
+  setting_emails_footer: Pie de mensajes
+  setting_enabled_scm: Activar SCM
+  setting_feeds_limit: LÃ­mite de contenido para sindicaciÃ³n
+  setting_gravatar_enabled: Usar iconos de usuario (Gravatar)
+  setting_host_name: Nombre y ruta del servidor
+  setting_issue_list_default_columns: Columnas por defecto para la lista de peticiones
+  setting_issues_export_limit: LÃ­mite de exportaciÃ³n de peticiones
+  setting_login_required: Se requiere identificaciÃ³n
+  setting_mail_from: Correo desde el que enviar mensajes
+  setting_mail_handler_api_enabled: Activar SW para mensajes entrantes
+  setting_mail_handler_api_key: Clave de la API
+  setting_per_page_options: Objetos por pÃ¡gina
+  setting_plain_text_mail: sÃ³lo texto plano (no HTML)
+  setting_protocol: Protocolo
+  setting_self_registration: Registro permitido
+  setting_sequential_project_identifiers: Generar identificadores de proyecto
+  setting_sys_api_enabled: Habilitar SW para la gestiÃ³n del repositorio
+  setting_text_formatting: Formato de texto
+  setting_time_format: Formato de hora
+  setting_user_format: Formato de nombre de usuario
+  setting_welcome_text: Texto de bienvenida
+  setting_wiki_compression: CompresiÃ³n del historial del Wiki
+  status_active: activo
+  status_locked: bloqueado
+  status_registered: registrado
+  text_are_you_sure: Â¿EstÃ¡ seguro?
+  text_assign_time_entries_to_project: Asignar las horas al proyecto
+  text_caracters_maximum: "%{count} caracteres como mÃ¡ximo."
+  text_caracters_minimum: "%{count} caracteres como mÃ­nimo."
+  text_comma_separated: MÃºltiples valores permitidos (separados por coma).
+  text_default_administrator_account_changed: Cuenta de administrador por defecto modificada
+  text_destroy_time_entries: Borrar las horas
+  text_destroy_time_entries_question: Existen %{hours} horas asignadas a la peticiÃ³n que quiere borrar. Â¿QuÃ© quiere hacer?
+  text_diff_truncated: '... Diferencia truncada por exceder el mÃ¡ximo tamaÃ±o visualizable.'
+  text_email_delivery_not_configured: "Las notificaciones estÃ¡n desactivadas porque el servidor de correo no estÃ¡ configurado.\nConfigure el servidor de SMTP en config/configuration.yml y reinicie la aplicaciÃ³n para activar los cambios."
+  text_enumeration_category_reassign_to: 'Reasignar al siguiente valor:'
+  text_enumeration_destroy_question: "%{count} objetos con este valor asignado."
+  text_file_repository_writable: Se puede escribir en el repositorio
+  text_issue_added: "PeticiÃ³n %{id} aÃ±adida por %{author}."
+  text_issue_category_destroy_assignments: Dejar las peticiones sin categorÃ­a
+  text_issue_category_destroy_question: "Algunas peticiones (%{count}) estÃ¡n asignadas a esta categorÃ­a. Â¿QuÃ© desea hacer?"
+  text_issue_category_reassign_to: Reasignar las peticiones a la categorÃ­a
+  text_issue_updated: "La peticiÃ³n %{id} ha sido actualizada por %{author}."
+  text_issues_destroy_confirmation: 'Â¿Seguro que quiere borrar las peticiones seleccionadas?'
+  text_issues_ref_in_commit_messages: Referencia y peticiÃ³n de correcciÃ³n en los mensajes
+  text_length_between: "Longitud entre %{min} y %{max} caracteres."
+  text_load_default_configuration: Cargar la configuraciÃ³n por defecto
+  text_min_max_length_info: 0 para ninguna restricciÃ³n
+  text_no_configuration_data: "TodavÃ­a no se han configurado perfiles, ni tipos, estados y flujo de trabajo asociado a peticiones. Se recomiendo encarecidamente cargar la configuraciÃ³n por defecto. Una vez cargada, podrÃ¡ modificarla."
+  text_project_destroy_confirmation: Â¿EstÃ¡s seguro de querer eliminar el proyecto?
+  text_reassign_time_entries: 'Reasignar las horas a esta peticiÃ³n:'
+  text_regexp_info: ej. ^[A-Z0-9]+$
+  text_repository_usernames_mapping: "Establezca la correspondencia entre los usuarios de Redmine y los presentes en el log del repositorio.\nLos usuarios con el mismo nombre o correo en Redmine y en el repositorio serÃ¡n asociados automÃ¡ticamente."
+  text_rmagick_available: RMagick disponible (opcional)
+  text_select_mail_notifications: Seleccionar los eventos a notificar
+  text_select_project_modules: 'Seleccione los mÃ³dulos a activar para este proyecto:'
+  text_status_changed_by_changeset: "Aplicado en los cambios %{value}"
+  text_subprojects_destroy_warning: "Los proyectos secundarios: %{value} tambiÃ©n se eliminarÃ¡n"
+  text_tip_issue_begin_day: tarea que comienza este dÃ­a
+  text_tip_issue_begin_end_day: tarea que comienza y termina este dÃ­a
+  text_tip_issue_end_day: tarea que termina este dÃ­a
+  text_tracker_no_workflow: No hay ningÃºn flujo de trabajo definido para este tipo de peticiÃ³n
+  text_unallowed_characters: Caracteres no permitidos
+  text_user_mail_option: "De los proyectos no seleccionados, sÃ³lo recibirÃ¡ notificaciones sobre elementos monitorizados o elementos en los que estÃ© involucrado (por ejemplo, peticiones de las que usted sea autor o asignadas a usted)."
+  text_user_wrote: "%{value} escribiÃ³:"
+  text_wiki_destroy_confirmation: Â¿Seguro que quiere borrar el wiki y todo su contenido?
+  text_workflow_edit: Seleccionar un flujo de trabajo para actualizar
+  text_plugin_assets_writable: Se puede escribir en el directorio pÃºblico de las extensiones
+  warning_attachments_not_saved: "No se han podido grabar %{count} ficheros."
+  button_create_and_continue: Crear y continuar
+  text_custom_field_possible_values_info: 'Un valor en cada lÃ­nea'
+  label_display: Mostrar
+  field_editable: Modificable
+  setting_repository_log_display_limit: NÃºmero mÃ¡ximo de revisiones mostradas en el fichero de trazas
+  setting_file_max_size_displayed: TamaÃ±o mÃ¡ximo de los ficheros de texto mostrados
+  field_watcher: Seguidor
+  setting_openid: Permitir identificaciÃ³n y registro por OpenID
+  field_identity_url: URL de OpenID
+  label_login_with_open_id_option: o identifÃ­quese con OpenID
+  field_content: Contenido
+  label_descending: Descendente
+  label_sort: Ordenar
+  label_ascending: Ascendente
+  label_date_from_to: Desde %{start} hasta %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Esta pÃ¡gina tiene %{descendants} pÃ¡gina(s) hija(s) y descendiente(s). Â¿QuÃ© desea hacer?
+  text_wiki_page_reassign_children: Reasignar pÃ¡ginas hijas a esta pÃ¡gina
+  text_wiki_page_nullify_children: Dejar pÃ¡ginas hijas como pÃ¡ginas raÃ­z
+  text_wiki_page_destroy_children: Eliminar pÃ¡ginas hijas y todos sus descendientes
+  setting_password_min_length: Longitud mÃ­nima de la contraseÃ±a
+  field_group_by: Agrupar resultados por
+  mail_subject_wiki_content_updated: "La pÃ¡gina wiki '%{id}' ha sido actualizada"
+  label_wiki_content_added: PÃ¡gina wiki aÃ±adida
+  mail_subject_wiki_content_added: "Se ha aÃ±adido la pÃ¡gina wiki '%{id}'."
+  mail_body_wiki_content_added: "%{author} ha aÃ±adido la pÃ¡gina wiki '%{id}'."
+  label_wiki_content_updated: PÃ¡gina wiki actualizada
+  mail_body_wiki_content_updated: La pÃ¡gina wiki '%{id}' ha sido actualizada por %{author}.
+  permission_add_project: Crear proyecto
+  setting_new_project_user_role_id: Permiso asignado a un usuario no-administrador para crear proyectos
+  label_view_all_revisions: Ver todas las revisiones
+  label_tag: Etiqueta
+  label_branch: Rama
+  error_no_tracker_in_project: Este proyecto no tiene asociados tipos de peticiones. Por favor, revise la configuraciÃ³n.
+  error_no_default_issue_status: No se ha definido un estado de peticiÃ³n por defecto. Por favor, revise la configuraciÃ³n (en "AdministraciÃ³n" -> "Estados de las peticiones").
+  text_journal_changed: "%{label} cambiado %{old} por %{new}"
+  text_journal_set_to: "%{label} establecido a %{value}"
+  text_journal_deleted: "%{label} eliminado (%{old})"
+  label_group_plural: Grupos
+  label_group: Grupo
+  label_group_new: Nuevo grupo
+  label_time_entry_plural: Tiempo dedicado
+  text_journal_added: "AÃ±adido %{label} %{value}"
+  field_active: Activo
+  enumeration_system_activity: Actividad del sistema
+  permission_delete_issue_watchers: Borrar seguidores
+  version_status_closed: cerrado
+  version_status_locked: bloqueado
+  version_status_open: abierto
+  error_can_not_reopen_issue_on_closed_version: No se puede reabrir una peticiÃ³n asignada a una versiÃ³n cerrada
+
+  label_user_anonymous: AnÃ³nimo
+  button_move_and_follow: Mover y seguir
+  setting_default_projects_modules: MÃ³dulos activados por defecto en proyectos nuevos
+  setting_gravatar_default: Imagen Gravatar por defecto
+  field_sharing: Compartir
+  button_copy_and_follow: Copiar y seguir
+  label_version_sharing_hierarchy: Con la jerarquÃ­a del proyecto
+  label_version_sharing_tree: Con el Ã¡rbol del proyecto
+  label_version_sharing_descendants: Con proyectos hijo
+  label_version_sharing_system: Con todos los proyectos
+  label_version_sharing_none: No compartir
+  button_duplicate: Duplicar
+  error_can_not_archive_project: Este proyecto no puede ser archivado
+  label_copy_source: Fuente
+  setting_issue_done_ratio: Calcular el ratio de tareas realizadas con
+  setting_issue_done_ratio_issue_status: Usar el estado de tareas
+  error_issue_done_ratios_not_updated: Ratios de tareas realizadas no actualizado.
+  error_workflow_copy_target: Por favor, elija categorÃ­a(s) y perfil(es) destino
+  setting_issue_done_ratio_issue_field: Utilizar el campo de peticiÃ³n
+  label_copy_same_as_target: El mismo que el destino
+  label_copy_target: Destino
+  notice_issue_done_ratios_updated: Ratios de tareas realizadas actualizados.
+  error_workflow_copy_source: Por favor, elija una categorÃ­a o rol de origen
+  label_update_issue_done_ratios: Actualizar ratios de tareas realizadas
+  setting_start_of_week: Comenzar las semanas en
+  permission_view_issues: Ver peticiones
+  label_display_used_statuses_only: SÃ³lo mostrar los estados usados por este tipo de peticiÃ³n
+  label_revision_id: RevisiÃ³n %{value}
+  label_api_access_key: Clave de acceso de la API
+  label_api_access_key_created_on: Clave de acceso de la API creada hace %{value}
+  label_feeds_access_key: Clave de acceso RSS
+  notice_api_access_key_reseted: Clave de acceso a la API regenerada.
+  setting_rest_api_enabled: Activar servicio web REST
+  label_missing_api_access_key: Clave de acceso a la API ausente
+  label_missing_feeds_access_key: Clave de accesso RSS ausente
+  button_show: Mostrar
+  text_line_separated: MÃºltiples valores permitidos (un valor en cada lÃ­nea).
+  setting_mail_handler_body_delimiters: Truncar correos tras una de estas lÃ­neas
+  permission_add_subprojects: Crear subproyectos
+  label_subproject_new: Nuevo subproyecto
+  text_own_membership_delete_confirmation: |-
+    EstÃ¡ a punto de eliminar algÃºn o todos sus permisos y podrÃ­a perder la posibilidad de modificar este proyecto tras hacerlo.
+    Â¿EstÃ¡ seguro de querer continuar?
+  label_close_versions: Cerrar versiones completadas
+  label_board_sticky: Pegajoso
+  label_board_locked: Bloqueado
+  permission_export_wiki_pages: Exportar pÃ¡ginas wiki
+  setting_cache_formatted_text: Cachear texto formateado
+  permission_manage_project_activities: Gestionar actividades del proyecto
+  error_unable_delete_issue_status: Fue imposible eliminar el estado de la peticiÃ³n
+  label_profile: Perfil
+  permission_manage_subtasks: Gestionar subtareas
+  field_parent_issue: Tarea padre
+  label_subtask_plural: Subtareas
+  label_project_copy_notifications: Enviar notificaciones por correo electrÃ³nico durante la copia del proyecto
+  error_can_not_delete_custom_field: Fue imposible eliminar el campo personalizado
+  error_unable_to_connect: Fue imposible conectar con (%{value})
+  error_can_not_remove_role: Este rol estÃ¡ en uso y no puede ser eliminado.
+  error_can_not_delete_tracker: Este tipo contiene peticiones y no puede ser eliminado.
+  field_principal: Principal
+  label_my_page_block: Bloque Mi pÃ¡gina
+  notice_failed_to_save_members: "Fallo al guardar miembro(s): %{errors}."
+  text_zoom_out: Alejar
+  text_zoom_in: Acercar
+  notice_unable_delete_time_entry: Fue imposible eliminar la entrada de tiempo dedicado.
+  label_overall_spent_time: Tiempo total dedicado
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendario
+  button_edit_associated_wikipage: "Editar paginas Wiki asociadas: %{page_title}"
+  field_text: Campo de texto
+  label_user_mail_option_only_owner: Solo para objetos que soy propietario
+  setting_default_notification_option: Opcion de notificacion por defecto
+  label_user_mail_option_only_my_events: Solo para objetos que soy seguidor o estoy involucrado
+  label_user_mail_option_only_assigned: Solo para objetos que estoy asignado
+  label_user_mail_option_none: Sin eventos
+  field_member_of_group: Asignado al grupo
+  field_assigned_to_role: Asignado al perfil
+  notice_not_authorized_archived_project: El proyecto al que intenta acceder ha sido archivado.
+  label_principal_search: "Buscar por usuario o grupo:"
+  label_user_search: "Buscar por usuario:"
+  field_visible: Visible
+  setting_emails_header: Encabezado de Correos
+
+  setting_commit_logtime_activity_id: Actividad de los tiempos registrados
+  text_time_logged_by_changeset: Aplicado en los cambios %{value}.
+  setting_commit_logtime_enabled: Habilitar registro de horas
+  notice_gantt_chart_truncated: Se recortÃ³ el diagrama porque excede el nÃºmero mÃ¡ximo de elementos que pueden ser mostrados (%{max})
+  setting_gantt_items_limit: NÃºmero mÃ¡ximo de elementos mostrados en el diagrama de Gantt
+  field_warn_on_leaving_unsaved: Avisarme cuando vaya a abandonar una pÃ¡gina con texto no guardado
+  text_warn_on_leaving_unsaved: Esta pÃ¡gina contiene texto no guardado y si la abandona sus cambios se perderÃ¡n
+  label_my_queries: Mis consultas personalizadas
+  text_journal_changed_no_detail: "Se actualizÃ³ %{label}"
+  label_news_comment_added: Comentario aÃ±adido a noticia
+  button_expand_all: Expandir todo
+  button_collapse_all: Contraer todo
+  label_additional_workflow_transitions_for_assignee: Transiciones adicionales permitidas cuando la peticiÃ³n estÃ¡ asignada al usuario
+  label_additional_workflow_transitions_for_author: Transiciones adicionales permitidas cuando el usuario es autor de la peticiÃ³n
+  label_bulk_edit_selected_time_entries: Editar en bloque las horas seleccionadas
+  text_time_entries_destroy_confirmation: Â¿EstÃ¡ seguro de querer eliminar (la hora seleccionada/las horas seleccionadas)?
+  label_role_anonymous: AnÃ³nimo
+  label_role_non_member: No miembro
+  label_issue_note_added: Nota aÃ±adida
+  label_issue_status_updated: Estado actualizado
+  label_issue_priority_updated: Prioridad actualizada
+  label_issues_visibility_own: Peticiones creadas por el usuario o asignadas a Ã©l
+  field_issues_visibility: Visibilidad de las peticiones
+  label_issues_visibility_all: Todas las peticiones
+  permission_set_own_issues_private: Poner las peticiones propias como pÃºblicas o privadas
+  field_is_private: Privada
+  permission_set_issues_private: Poner peticiones como pÃºblicas o privadas
+  label_issues_visibility_public: Todas las peticiones no privadas
+  text_issues_destroy_descendants_confirmation: Se procederÃ¡ a borrar tambiÃ©n %{count} subtarea(s).
+  field_commit_logs_encoding: CodificaciÃ³n de los mensajes de commit
+  field_scm_path_encoding: CodificaciÃ³n de las rutas
+  text_scm_path_encoding_note: "Por defecto: UTF-8"
+  field_path_to_repository: Ruta al repositorio
+  field_root_directory: Directorio raÃ­z
+  field_cvs_module: MÃ³dulo
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Repositorio local (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Orden
+  text_scm_command_version: VersiÃ³n
+  label_git_report_last_commit: Informar del Ãºltimo commit para ficheros y directorios
+  text_scm_config: Puede configurar las Ã³rdenes de cada scm en configuration/configuration.yml. Por favor, reinicie la aplicaciÃ³n despuÃ©s de editarlo
+  text_scm_command_not_available: La orden para el Scm no estÃ¡ disponible. Por favor, compruebe la configuraciÃ³n en el panel de administraciÃ³n.
+  notice_issue_successful_create: PeticiÃ³n %{id} creada.
+  label_between: entre
+  setting_issue_group_assignment: Permitir asignar peticiones a grupos
+  label_diff: diferencias
+  text_git_repository_note: El repositorio es bÃ¡sico y local (p.e. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: DirecciÃ³n de ordenaciÃ³n
+  description_project_scope: Ãmbito de bÃºsqueda
+  description_filter: Filtro
+  description_user_mail_notification: ConfiguraciÃ³n de notificaciones por correo
+  description_date_from: Introduzca la fecha de inicio
+  description_message_content: Contenido del mensaje
+  description_available_columns: Columnas disponibles
+  description_date_range_interval: Elija el rango seleccionando la fecha de inicio y fin
+  description_issue_category_reassign: Elija la categorÃ­a de la peticiÃ³n
+  description_search: Campo de bÃºsqueda
+  description_notes: Notas
+  description_date_range_list: Elija el rango en la lista
+  description_choose_project: Proyectos
+  description_date_to: Introduzca la fecha fin
+  description_query_sort_criteria_attribute: Atributo de ordenaciÃ³n
+  description_wiki_subpages_reassign: Elija la nueva pÃ¡gina padre
+  description_selected_columns: Columnas seleccionadas
+  label_parent_revision: Padre
+  label_child_revision: Hijo
+  setting_default_issue_start_date_to_creation_date: Utilizar la fecha actual como fecha de inicio para nuevas peticiones
+  button_edit_section: Editar esta secciÃ³n
+  setting_repositories_encodings: CodificaciÃ³n de adjuntos y repositorios
+  description_all_columns: Todas las columnas
+  button_export: Exportar
+  label_export_options: "%{export_format} opciones de exportaciÃ³n"
+  error_attachment_too_big: Este fichero no se puede adjuntar porque excede el tamaÃ±o mÃ¡ximo de fichero (%{max_size})
+  notice_failed_to_save_time_entries: "Error al guardar %{count} entradas de tiempo de las %{total} seleccionadas: %{ids}."
+  label_x_issues:
+    zero:  0 peticiÃ³n
+    one:   1 peticiÃ³n
+    other: "%{count} peticiones"
+  label_repository_new: Nuevo repositorio
+  field_repository_is_default: Repositorio principal
+  label_copy_attachments: Copiar adjuntos
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Versiones completadas
+  text_project_identifier_info: Solo se permiten letras en minÃºscula (a-z), nÃºmeros, guiones y barras bajas.<br />Una vez guardado, el identificador no se puede cambiar.
+  field_multiple: Valores mÃºltiples
+  setting_commit_cross_project_ref: Permitir referenciar y resolver peticiones de todos los demÃ¡s proyectos
+  text_issue_conflict_resolution_add_notes: AÃ±adir mis notas y descartar mis otros cambios
+  text_issue_conflict_resolution_overwrite: Aplicar mis campos de todas formas (las notas anteriores se mantendrÃ¡n pero algunos cambios podrÃ­an ser sobreescritos)
+  notice_issue_update_conflict: La peticiÃ³n ha sido actualizada por otro usuario mientras la editaba.
+  text_issue_conflict_resolution_cancel: Descartar todos mis cambios y mostrar de nuevo %{link}
+  permission_manage_related_issues: Gestionar peticiones relacionadas
+  field_auth_source_ldap_filter: Filtro LDAP
+  label_search_for_watchers: Buscar seguidores para aÃ±adirlos
+  notice_account_deleted: Su cuenta ha sido eliminada
+  setting_unsubscribe: Permitir a los usuarios borrar sus propias cuentas
+  button_delete_my_account: Borrar mi cuenta
+  text_account_destroy_confirmation: |-
+    Â¿EstÃ¡ seguro de querer proceder?
+    Su cuenta quedarÃ¡ borrada permanentemente, sin la posibilidad de reactivarla.
+  error_session_expired: Su sesiÃ³n ha expirado. Por favor, vuelva a identificarse.
+  text_session_expiration_settings: "Advertencia: el cambio de estas opciones podrÃ­a hacer expirar las sesiones activas, incluyendo la suya."
+  setting_session_lifetime: Tiempo de vida mÃ¡ximo de las sesiones
+  setting_session_timeout: Tiempo mÃ¡ximo de inactividad de las sesiones
+  label_session_expiration: ExpiraciÃ³n de sesiones
+  permission_close_project: Cerrar / reabrir el proyecto
+  label_show_closed_projects: Ver proyectos cerrados
+  button_close: Cerrar
+  button_reopen: Reabrir
+  project_status_active: activo
+  project_status_closed: cerrado
+  project_status_archived: archivado
+  text_project_closed: Este proyecto estÃ¡ cerrado y es de sÃ³lo lectura
+  notice_user_successful_create: Usuario %{id} creado.
+  field_core_fields: Campos bÃ¡sicos
+  field_timeout: Tiempo de inactividad (en segundos)
+  setting_thumbnails_enabled: Mostrar miniaturas de los adjuntos
+  setting_thumbnails_size: TamaÃ±o de las miniaturas (en pÃ­xeles)
+  label_status_transitions: Transiciones de estado
+  label_fields_permissions: Permisos sobre los campos
+  label_readonly: SÃ³lo lectura
+  label_required: Requerido
+  text_repository_identifier_info: Solo se permiten letras en minÃºscula (a-z), nÃºmeros, guiones y barras bajas.<br />Una vez guardado, el identificador no se puede cambiar.
+  field_board_parent: Foro padre
+  label_attribute_of_project: "%{name} del proyecto"
+  label_attribute_of_author: "%{name} del autor"
+  label_attribute_of_assigned_to: "%{name} de la persona asignada"
+  label_attribute_of_fixed_version: "%{name} de la versiÃ³n indicada"
+  label_copy_subtasks: Copiar subtareas
+  label_copied_to: copiada a
+  label_copied_from: copiada desde
+  label_any_issues_in_project: cualquier peticiÃ³n del proyecto
+  label_any_issues_not_in_project: cualquier peticiÃ³n que no sea del proyecto
+  field_private_notes: Notas privadas
+  permission_view_private_notes: Ver notas privadas
+  permission_set_notes_private: Poner notas como privadas
+  label_no_issues_in_project: no hay peticiones en el proyecto
+  label_any: todos
+  label_last_n_weeks: en las Ãºltimas %{count} semanas
+  setting_cross_project_subtasks: Permitir subtareas cruzadas entre proyectos
+  label_cross_project_descendants: Con proyectos hijo
+  label_cross_project_tree: Con el Ã¡rbol del proyecto
+  label_cross_project_hierarchy: Con la jerarquÃ­a del proyecto
+  label_cross_project_system: Con todos los proyectos
+  button_hide: Ocultar
+  setting_non_working_week_days: DÃ­as no laborables
+  label_in_the_next_days: en los prÃ³ximos
+  label_in_the_past_days: en los anteriores
+  label_attribute_of_user: "%{name} del usuario"
+  text_turning_multiple_off: Si desactiva los valores mÃºltiples, Ã©stos serÃ¡n eliminados para dejar un Ãºnico valor por elemento.
+  label_attribute_of_issue: "%{name} de la peticiÃ³n"
+  permission_add_documents: AÃ±adir documentos
+  permission_edit_documents: Editar documentos
+  permission_delete_documents: Borrar documentos
+  label_gantt_progress_line: LÃ­nea de progreso
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8c/8c4fab1287b72e3f74cffb8a1dd8ba6c360dd802.svn-base
--- a/.svn/pristine/8c/8c4fab1287b72e3f74cffb8a1dd8ba6c360dd802.svn-base
+++ /dev/null
@@ -1,110 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class QueriesController < ApplicationController
-  menu_item :issues
-  before_filter :find_query, :except => [:new, :create, :index]
-  before_filter :find_optional_project, :only => [:new, :create]
-
-  accept_api_auth :index
-
-  include QueriesHelper
-
-  def index
-    case params[:format]
-    when 'xml', 'json'
-      @offset, @limit = api_offset_and_limit
-    else
-      @limit = per_page_option
-    end
-
-    @query_count = Query.visible.count
-    @query_pages = Paginator.new self, @query_count, @limit, params['page']
-    @queries = Query.visible.all(:limit => @limit, :offset => @offset, :order => "#{Query.table_name}.name")
-
-    respond_to do |format|
-      format.html { render :nothing => true }
-      format.api
-    end
-  end
-
-  def new
-    @query = Query.new
-    @query.user = User.current
-    @query.project = @project
-    @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
-    build_query_from_params
-  end
-
-  verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
-  def create
-    @query = Query.new(params[:query])
-    @query.user = User.current
-    @query.project = params[:query_is_for_all] ? nil : @project
-    @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
-    build_query_from_params
-    @query.column_names = nil if params[:default_columns]
-
-    if @query.save
-      flash[:notice] = l(:notice_successful_create)
-      redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
-    else
-      render :action => 'new', :layout => !request.xhr?
-    end
-  end
-
-  def edit
-  end
-
-  verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
-  def update
-    @query.attributes = params[:query]
-    @query.project = nil if params[:query_is_for_all]
-    @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
-    build_query_from_params
-    @query.column_names = nil if params[:default_columns]
-
-    if @query.save
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
-    else
-      render :action => 'edit'
-    end
-  end
-
-  verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
-  def destroy
-    @query.destroy
-    redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1
-  end
-
-private
-  def find_query
-    @query = Query.find(params[:id])
-    @project = @query.project
-    render_403 unless @query.editable_by?(User.current)
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  def find_optional_project
-    @project = Project.find(params[:project_id]) if params[:project_id]
-    render_403 unless User.current.allowed_to?(:save_queries, @project, :global => true)
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8c/8c8f1143f138ce617f21f89790a7e1f8a60e4e92.svn-base
--- a/.svn/pristine/8c/8c8f1143f138ce617f21f89790a7e1f8a60e4e92.svn-base
+++ /dev/null
@@ -1,21 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module AuthSourcesHelper
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8c/8c9985bb9b23719d27561e0988a8665ae9ec3fc9.svn-base
--- a/.svn/pristine/8c/8c9985bb9b23719d27561e0988a8665ae9ec3fc9.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= link_to l(@enumeration.option_name), :controller => 'enumerations', :action => 'index' %> &#187; <%=h @enumeration %></h2>
-
-<% form_tag({:action => 'update', :id => @enumeration}, :class => "tabular") do %>
-  <%= render :partial => 'form' %>
-  <%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8c/8cc3b49fb336589b0c77ad88bf1cb1e4d4cc2b4b.svn-base
--- a/.svn/pristine/8c/8cc3b49fb336589b0c77ad88bf1cb1e4d4cc2b4b.svn-base
+++ /dev/null
@@ -1,215 +0,0 @@
-#!/usr/bin/env ruby
-require 'coderay'
-
-$options, args = ARGV.partition { |arg| arg[/^-[hv]$|--\w+/] }
-subcommand = args.first if /^\w/ === args.first
-subcommand = nil if subcommand && File.exist?(subcommand)
-args.delete subcommand
-
-def option? *options
-  !($options & options).empty?
-end
-
-def tty?
-  $stdout.tty? || option?('--tty')
-end
-
-def version
-  puts <<-USAGE
-CodeRay #{CodeRay::VERSION}
-  USAGE
-end
-
-def help
-  puts <<-HELP
-This is CodeRay #{CodeRay::VERSION}, a syntax highlighting tool for selected languages.
-
-usage:
-  coderay [-language] [input] [-format] [output]
-  
-defaults:
-  language   detect from input file name or shebang; fall back to plain text
-  input      STDIN
-  format     detect from output file name or use terminal; fall back to HTML
-  output     STDOUT
-
-common:
-  coderay file.rb                      # highlight file to terminal
-  coderay file.rb > file.html          # highlight file to HTML page
-  coderay file.rb -div > file.html     # highlight file to HTML snippet
-
-configure output:
-  coderay file.py output.json          # output tokens as JSON
-  coderay file.py -loc                 # count lines of code in Python file
-
-configure input:
-  coderay -python file                 # specify the input language
-  coderay -ruby                        # take input from STDIN
-
-more:
-  coderay stylesheet [style]           # print CSS stylesheet
-  HELP
-end
-
-def commands
-  puts <<-COMMANDS
-  general:
-    highlight   code highlighting (default command, optional)
-    stylesheet  print the CSS stylesheet with the given name (aliases: style, css)
-  
-  about:
-    list [of]   list all available plugins (or just the scanners|encoders|styles|filetypes)
-    commands    print this list
-    help        show some help
-    version     print CodeRay version
-  COMMANDS
-end
-
-def print_list_of plugin_host
-  plugins = plugin_host.all_plugins.map do |plugin|
-    info = "  #{plugin.plugin_id}: #{plugin.title}"
-    
-    aliases = (plugin.aliases - [:default]).map { |key| "-#{key}" }.sort_by { |key| key.size }
-    if plugin.respond_to?(:file_extension) || !aliases.empty?
-      additional_info = []
-      additional_info << aliases.join(', ') unless aliases.empty?
-      info << " (#{additional_info.join('; ')})"
-    end
-    
-    info << '  <-- default' if plugin.aliases.include? :default
-    
-    info
-  end
-  puts plugins.sort
-end
-
-if option? '-v', '--version'
-  version
-end
-
-if option? '-h', '--help'
-  help
-end
-
-case subcommand
-when 'highlight', nil
-  if ARGV.empty?
-    version
-    help
-  else
-    signature = args.map { |arg| arg[/^-/] ? '-' : 'f' }.join
-    names     = args.map { |arg| arg.sub(/^-/, '') }
-    case signature
-    when /^$/
-      exit
-    when /^ff?$/
-      input_file, output_file, = *names
-    when /^f-f?$/
-      input_file, output_format, output_file, = *names
-    when /^-ff?$/
-      input_lang, input_file, output_file, = *names
-    when /^-f-f?$/
-      input_lang, input_file, output_format, output_file, = *names
-    when /^--?f?$/
-      input_lang, output_format, output_file, = *names
-    else
-      $stdout = $stderr
-      help
-      puts
-      puts "Unknown parameter order: #{args.join ' '}, expected: [-language] [input] [-format] [output]"
-      exit 1
-    end
-    
-    if input_file
-      input_lang ||= CodeRay::FileType.fetch input_file, :text, true
-    end
-    
-    if output_file
-      output_format ||= CodeRay::FileType[output_file]
-    else
-      output_format ||= :terminal
-    end
-    
-    output_format = :page if output_format.to_s == 'html'
-    
-    if input_file
-      input = File.read input_file
-    else
-      input = $stdin.read
-    end
-    
-    begin
-      file =
-        if output_file
-          File.open output_file, 'w'
-        else
-          $stdout.sync = true
-          $stdout
-        end
-      CodeRay.encode(input, input_lang, output_format, :out => file)
-      file.puts
-    rescue CodeRay::PluginHost::PluginNotFound => boom
-      $stdout = $stderr
-      if boom.message[/CodeRay::(\w+)s could not load plugin :?(.*?): /]
-        puts "I don't know the #$1 \"#$2\"."
-      else
-        puts boom.message
-      end
-      # puts "I don't know this plugin: #{boom.message[/Could not load plugin (.*?): /, 1]}."
-    rescue CodeRay::Scanners::Scanner::ScanError  # FIXME: rescue Errno::EPIPE
-      # this is sometimes raised by pagers; ignore [TODO: wtf?]
-    ensure
-      file.close if output_file
-    end
-  end
-when 'li', 'list'
-  arg = args.first && args.first.downcase
-  if [nil, 's', 'sc', 'scanner', 'scanners'].include? arg
-    puts 'input languages (Scanners):'
-    print_list_of CodeRay::Scanners
-  end
-  
-  if [nil, 'e', 'en', 'enc', 'encoder', 'encoders'].include? arg
-    puts 'output formats (Encoders):'
-    print_list_of CodeRay::Encoders
-  end
-  
-  if [nil, 'st', 'style', 'styles'].include? arg
-    puts 'CSS themes for HTML output (Styles):'
-    print_list_of CodeRay::Styles
-  end
-  
-  if [nil, 'f', 'ft', 'file', 'filetype', 'filetypes'].include? arg
-    puts 'recognized file types:'
-    
-    filetypes = Hash.new { |h, k| h[k] = [] }
-    CodeRay::FileType::TypeFromExt.inject filetypes do |types, (ext, type)|
-      types[type.to_s] << ".#{ext}"
-      types
-    end
-    CodeRay::FileType::TypeFromName.inject filetypes do |types, (name, type)|
-      types[type.to_s] << name
-      types
-    end
-    
-    filetypes.sort.each do |type, exts|
-      puts "  #{type}: #{exts.sort_by { |ext| ext.size }.join(', ')}"
-    end
-  end
-when 'stylesheet', 'style', 'css'
-  puts CodeRay::Encoders[:html]::CSS.new(args.first).stylesheet
-when 'commands'
-  commands
-when 'help'
-  help
-else
-  $stdout = $stderr
-  help
-  puts
-  if subcommand[/\A\w+\z/]
-    puts "Unknown command: #{subcommand}"
-  else
-    puts "File not found: #{subcommand}"
-  end
-  exit 1
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8d/8d030bdcda347746d48417b7db44c0048d96bb66.svn-base
--- /dev/null
+++ b/.svn/pristine/8d/8d030bdcda347746d48417b7db44c0048d96bb66.svn-base
@@ -0,0 +1,1138 @@
+# Korean translations for Ruby on Rails
+ko:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y/%m/%d"
+      short: "%m/%d"
+      long: "%Yë…„ %mì›” %dì¼ (%a)"
+
+    day_names: [ì¼ìš”ì¼, ì›”ìš”ì¼, í™”ìš”ì¼, ìˆ˜ìš”ì¼, ëª©ìš”ì¼, ê¸ˆìš”ì¼, í† ìš”ì¼]
+    abbr_day_names: [ì¼, ì›”, í™”, ìˆ˜, ëª©, ê¸ˆ, í† ]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, 1ì›”, 2ì›”, 3ì›”, 4ì›”, 5ì›”, 6ì›”, 7ì›”, 8ì›”, 9ì›”, 10ì›”, 11ì›”, 12ì›”]
+    abbr_month_names: [~, 1ì›”, 2ì›”, 3ì›”, 4ì›”, 5ì›”, 6ì›”, 7ì›”, 8ì›”, 9ì›”, 10ì›”, 11ì›”, 12ì›”]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%Y/%m/%d %H:%M:%S"
+      time: "%H:%M"
+      short: "%y/%m/%d %H:%M"
+      long: "%Yë…„ %Bì›” %dì¼, %Hì‹œ %Më¶„ %Sì´ˆ %Z"
+    am: "ì˜¤ì „"
+    pm: "ì˜¤í›„"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "30ì´ˆ"
+      less_than_x_seconds:
+        one:   "ì¼ì´ˆ ì´í•˜"
+        other: "%{count}ì´ˆ ì´í•˜"
+      x_seconds:
+        one:   "ì¼ì´ˆ"
+        other: "%{count}ì´ˆ"
+      less_than_x_minutes:
+        one:   "ì¼ë¶„ ì´í•˜"
+        other: "%{count}ë¶„ ì´í•˜"
+      x_minutes:
+        one:   "ì¼ë¶„"
+        other: "%{count}ë¶„"
+      about_x_hours:
+        one:   "ì•½ í•œì‹œê°„"
+        other: "ì•½ %{count}ì‹œê°„"
+      x_hours:
+        one:   "1 ì‹œê°„"
+        other: "%{count} ì‹œê°„"
+      x_days:
+        one:   "í•˜ë£¨"
+        other: "%{count}ì¼"
+      about_x_months:
+        one:   "ì•½ í•œë‹¬"
+        other: "ì•½ %{count}ë‹¬"
+      x_months:
+        one:   "í•œë‹¬"
+        other: "%{count}ë‹¬"
+      about_x_years:
+        one:   "ì•½ ì¼ë…„"
+        other: "ì•½ %{count}ë…„"
+      over_x_years:
+        one:   "ì¼ë…„ ì´ìƒ"
+        other: "%{count}ë…„ ì´ìƒ"
+      almost_x_years:
+        one:   "ì•½ 1ë…„"
+        other: "ì•½ %{count}ë…„"
+    prompts:
+      year:   "ë…„"
+      month:  "ì›”"
+      day:    "ì¼"
+      hour:   "ì‹œ"
+      minute: "ë¶„"
+      second: "ì´ˆ"
+
+  number:
+    # Used in number_with_delimiter()
+    # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+    format:
+      # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+      separator: "."
+      # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
+      delimiter: ","
+      # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
+      precision: 3
+
+    # Used in number_to_currency()
+    currency:
+      format:
+        # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+        format: "%u%n"
+        unit: "â‚©"
+        # These three are to override number.format and are optional
+        separator: "."
+        delimiter: ","
+        precision: 0
+
+    # Used in number_to_percentage()
+    percentage:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # Used in number_to_precision()
+    precision:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # Used in number_to_human_size()
+    human:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      words_connector: ", "
+      two_words_connector: "ê³¼ "
+      last_word_connector: ", "
+      sentence_connector: "ê·¸ë¦¬ê³ "
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "í•œê°œì˜ ì˜¤ë¥˜ê°€ ë°œìƒí•´ %{model}ì„(ë¥¼) ì €ìž¥í•˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤."
+          other:  "%{count}ê°œì˜ ì˜¤ë¥˜ê°€ ë°œìƒí•´ %{model}ì„(ë¥¼) ì €ìž¥í•˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤."
+        # The variable :count is also available
+        body: "ë‹¤ìŒ í•­ëª©ì— ë¬¸ì œê°€ ë°œê²¬í–ˆìŠµë‹ˆë‹¤:"
+
+      messages:
+        inclusion: "ì€ ëª©ë¡ì— í¬í•¨ë˜ì–´ ìžˆì§€ ì•ŠìŠµë‹ˆë‹¤"
+        exclusion: "ì€ ì˜ˆì•½ë˜ì–´ ìžˆìŠµë‹ˆë‹¤"
+        invalid: "ì€ ìœ íš¨í•˜ì§€ ì•ŠìŠµë‹ˆë‹¤."
+        confirmation: "ì€ í™•ì¸ì´ ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤"
+        accepted: "ì€ ì¸ì •ë˜ì–´ì•¼ í•©ë‹ˆë‹¤"
+        empty: "ì€ ê¸¸ì´ê°€ 0ì´ì–´ì„œëŠ” ì•ˆë©ë‹ˆë‹¤."
+        blank: "ì€ ë¹ˆ ê°’ì´ì–´ì„œëŠ” ì•ˆ ë©ë‹ˆë‹¤"
+        too_long: "ì€ ë„ˆë¬´ ê¹ë‹ˆë‹¤ (ìµœëŒ€ %{count}ìž ê¹Œì§€)"
+        too_short: "ì€ ë„ˆë¬´ ì§§ìŠµë‹ˆë‹¤ (ìµœì†Œ %{count}ìž ê¹Œì§€)"
+        wrong_length: "ì€ ê¸¸ì´ê°€ í‹€ë ¸ìŠµë‹ˆë‹¤ (%{count}ìžì´ì–´ì•¼ í•©ë‹ˆë‹¤.)"
+        taken: "ì€ ì´ë¯¸ ì„ íƒëœ ê²ë‹ˆë‹¤"
+        not_a_number: "ì€ ìˆ«ìžê°€ ì•„ë‹™ë‹ˆë‹¤"
+        greater_than: "ì€ %{count}ë³´ë‹¤ ì»¤ì•¼ í•©ë‹ˆë‹¤."
+        greater_than_or_equal_to: "ì€ %{count}ë³´ë‹¤ í¬ê±°ë‚˜ ê°™ì•„ì•¼ í•©ë‹ˆë‹¤"
+        equal_to: "ì€ %{count}(ì™€)ê³¼ ê°™ì•„ì•¼ í•©ë‹ˆë‹¤"
+        less_than: "ì€ %{count}ë³´ë‹¤ ìž‘ì–´ì•¼ í•©ë‹ˆë‹¤"
+        less_than_or_equal_to: "ì€ %{count}ê³¼ ê°™ê±°ë‚˜ ì´í•˜ì„ ìš”êµ¬í•©ë‹ˆë‹¤"
+        odd: "ì€ í™€ìˆ˜ì—¬ì•¼ í•©ë‹ˆë‹¤"
+        even: "ì€ ì§ìˆ˜ì—¬ì•¼ í•©ë‹ˆë‹¤"
+        greater_than_start_date: "ëŠ” ì‹œìž‘ë‚ ì§œë³´ë‹¤ ì»¤ì•¼ í•©ë‹ˆë‹¤"
+        not_same_project: "ëŠ” ê°™ì€ í”„ë¡œì íŠ¸ì— ì†í•´ ìžˆì§€ ì•ŠìŠµë‹ˆë‹¤"
+        circular_dependency: "ì´ ê´€ê³„ëŠ” ìˆœí™˜ ì˜ì¡´ê´€ê³„ë¥¼ ë§Œë“¤ ìˆ˜ ìžˆìŠµë‹ˆë‹¤"
+        cant_link_an_issue_with_a_descendant: "ì¼ê°ì€ í•˜ìœ„ ì¼ê°ê³¼ ì—°ê²°í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
+
+  actionview_instancetag_blank_option: ì„ íƒí•˜ì„¸ìš”
+
+  general_text_No: 'ì•„ë‹ˆì˜¤'
+  general_text_Yes: 'ì˜ˆ'
+  general_text_no: 'ì•„ë‹ˆì˜¤'
+  general_text_yes: 'ì˜ˆ'
+  general_lang_name: 'Korean (í•œêµ­ì–´)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: CP949
+  general_pdf_encoding: CP949
+  general_first_day_of_week: '7'
+
+  notice_account_updated: ê³„ì •ì´ ì„±ê³µì ìœ¼ë¡œ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤.
+  notice_account_invalid_creditentials: ìž˜ëª»ëœ ê³„ì • ë˜ëŠ” ë¹„ë°€ë²ˆí˜¸
+  notice_account_password_updated: ë¹„ë°€ë²ˆí˜¸ê°€ ìž˜ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤.
+  notice_account_wrong_password: ìž˜ëª»ëœ ë¹„ë°€ë²ˆí˜¸
+  notice_account_register_done: ê³„ì •ì´ ìž˜ ë§Œë“¤ì–´ì¡ŒìŠµë‹ˆë‹¤. ê³„ì •ì„ í™œì„±í™”í•˜ì‹œë ¤ë©´ ë°›ì€ ë©”ì¼ì˜ ë§í¬ë¥¼ í´ë¦­í•´ì£¼ì„¸ìš”.
+  notice_account_unknown_email: ì•Œë ¤ì§€ì§€ ì•Šì€ ì‚¬ìš©ìž.
+  notice_can_t_change_password: ì´ ê³„ì •ì€ ì™¸ë¶€ ì¸ì¦ì„ ì´ìš©í•©ë‹ˆë‹¤. ë¹„ë°€ë²ˆí˜¸ë¥¼ ë³€ê²½í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
+  notice_account_lost_email_sent: ìƒˆë¡œìš´ ë¹„ë°€ë²ˆí˜¸ë¥¼ ìœ„í•œ ë©”ì¼ì´ ë°œì†¡ë˜ì—ˆìŠµë‹ˆë‹¤.
+  notice_account_activated: ê³„ì •ì´ í™œì„±í™”ë˜ì—ˆìŠµë‹ˆë‹¤. ì´ì œ ë¡œê·¸ì¸ í•˜ì‹¤ìˆ˜ ìžˆìŠµë‹ˆë‹¤.
+  notice_successful_create: ìƒì„± ì„±ê³µ.
+  notice_successful_update: ë³€ê²½ ì„±ê³µ.
+  notice_successful_delete: ì‚­ì œ ì„±ê³µ.
+  notice_successful_connection: ì—°ê²° ì„±ê³µ.
+  notice_file_not_found: ìš”ì²­í•˜ì‹  íŽ˜ì´ì§€ëŠ” ì‚­ì œë˜ì—ˆê±°ë‚˜ ì˜®ê²¨ì¡ŒìŠµë‹ˆë‹¤.
+  notice_locking_conflict: ë‹¤ë¥¸ ì‚¬ìš©ìžì— ì˜í•´ì„œ ë°ì´í„°ê°€ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤.
+  notice_not_authorized: ì´ íŽ˜ì´ì§€ì— ì ‘ê·¼í•  ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤.
+  notice_email_sent: "%{value}ë‹˜ì—ê²Œ ë©”ì¼ì´ ë°œì†¡ë˜ì—ˆìŠµë‹ˆë‹¤."
+  notice_email_error: "ë©”ì¼ì„ ì „ì†¡í•˜ëŠ” ê³¼ì •ì— ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤. (%{value})"
+  notice_feeds_access_key_reseted: RSSì— ì ‘ê·¼ê°€ëŠ¥í•œ ì—´ì‡ (key)ê°€ ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤.
+  notice_failed_to_save_issues: "ì €ìž¥ì— ì‹¤íŒ¨í•˜ì˜€ìŠµë‹ˆë‹¤: ì‹¤íŒ¨ %{count}(ì„ íƒ %{total}): %{ids}."
+  notice_no_issue_selected: "ì¼ê°ì´ ì„ íƒë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤. ìˆ˜ì •í•˜ê¸° ì›í•˜ëŠ” ì¼ê°ì„ ì„ íƒí•˜ì„¸ìš”"
+  notice_account_pending: "ê³„ì •ì´ ë§Œë“¤ì–´ì¡Œìœ¼ë©° ê´€ë¦¬ìž ìŠ¹ì¸ ëŒ€ê¸°ì¤‘ìž…ë‹ˆë‹¤."
+  notice_default_data_loaded: ê¸°ë³¸ê°’ì„ ì„±ê³µì ìœ¼ë¡œ ì½ì–´ë“¤ì˜€ìŠµë‹ˆë‹¤.
+  notice_unable_delete_version: ì‚­ì œí•  ìˆ˜ ì—†ëŠ” ë²„ì „ìž…ë‹ˆë‹¤.
+
+  error_can_t_load_default_data: "ê¸°ë³¸ê°’ì„ ì½ì–´ë“¤ì¼ ìˆ˜ ì—†ìŠµë‹ˆë‹¤.: %{value}"
+  error_scm_not_found: í•­ëª©ì´ë‚˜ ë¦¬ë¹„ì ¼ì´ ì €ìž¥ì†Œì— ì¡´ìž¬í•˜ì§€ ì•ŠìŠµë‹ˆë‹¤.
+  error_scm_command_failed: "ì €ìž¥ì†Œì— ì ‘ê·¼í•˜ëŠ” ë„ì¤‘ì— ì˜¤ë¥˜ê°€ ë°œìƒí•˜ì˜€ìŠµë‹ˆë‹¤.: %{value}"
+  error_scm_annotate: "í•­ëª©ì´ ì—†ê±°ë‚˜ í–‰ë³„ ì´ë ¥ì„ ë³¼ ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
+  error_issue_not_found_in_project: 'ì¼ê°ì´ ì—†ê±°ë‚˜ ì´ í”„ë¡œì íŠ¸ì˜ ê²ƒì´ ì•„ë‹™ë‹ˆë‹¤.'
+
+  warning_attachments_not_saved: "%{count}ê°œ íŒŒì¼ì„ ì €ìž¥í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
+
+  mail_subject_lost_password: "%{value} ë¹„ë°€ë²ˆí˜¸"
+  mail_body_lost_password: 'ë¹„ë°€ë²ˆí˜¸ë¥¼ ë³€ê²½í•˜ë ¤ë©´ ë‹¤ìŒ ë§í¬ë¥¼ í´ë¦­í•˜ì„¸ìš”.'
+  mail_subject_register: "%{value} ê³„ì • í™œì„±í™”"
+  mail_body_register: 'ê³„ì •ì„ í™œì„±í™”í•˜ë ¤ë©´ ë§í¬ë¥¼ í´ë¦­í•˜ì„¸ìš”.:'
+  mail_body_account_information_external: "ë¡œê·¸ì¸í•  ë•Œ %{value} ê³„ì •ì„ ì‚¬ìš©í•˜ì‹¤ ìˆ˜ ìžˆìŠµë‹ˆë‹¤."
+  mail_body_account_information: ê³„ì • ì •ë³´
+  mail_subject_account_activation_request: "%{value} ê³„ì • í™œì„±í™” ìš”ì²­"
+  mail_body_account_activation_request: "ìƒˆ ì‚¬ìš©ìž(%{value})ê°€ ë“±ë¡ë˜ì—ˆìŠµë‹ˆë‹¤. ê´€ë¦¬ìžë‹˜ì˜ ìŠ¹ì¸ì„ ê¸°ë‹¤ë¦¬ê³  ìžˆìŠµë‹ˆë‹¤.:"
+  mail_body_reminder: "ë‹¹ì‹ ì´ ë§¡ê³  ìžˆëŠ” ì¼ê° %{count}ê°œì˜ ì™„ë£Œê¸°í•œì´ %{days}ì¼ í›„ ìž…ë‹ˆë‹¤."
+  mail_subject_reminder: "ë‚´ì¼ì´ ë§Œê¸°ì¸ ì¼ê° %{count}ê°œ (%{days})"
+  mail_subject_wiki_content_added: "ìœ„í‚¤íŽ˜ì´ì§€ '%{id}'ì´(ê°€) ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
+  mail_subject_wiki_content_updated: "'ìœ„í‚¤íŽ˜ì´ì§€ %{id}'ì´(ê°€) ìˆ˜ì •ë˜ì—ˆìŠµë‹ˆë‹¤."
+  mail_body_wiki_content_added: "%{author}ì´(ê°€) ìœ„í‚¤íŽ˜ì´ì§€ '%{id}'ì„(ë¥¼) ì¶”ê°€í•˜ì˜€ìŠµë‹ˆë‹¤."
+  mail_body_wiki_content_updated: "%{author}ì´(ê°€) ìœ„í‚¤íŽ˜ì´ì§€ '%{id}'ì„(ë¥¼) ìˆ˜ì •í•˜ì˜€ìŠµë‹ˆë‹¤."
+
+
+  field_name: ì´ë¦„
+  field_description: ì„¤ëª…
+  field_summary: ìš”ì•½
+  field_is_required: í•„ìˆ˜
+  field_firstname: ì´ë¦„
+  field_lastname: ì„±
+  field_mail: ë©”ì¼
+  field_filename: íŒŒì¼
+  field_filesize: í¬ê¸°
+  field_downloads: ë‹¤ìš´ë¡œë“œ
+  field_author: ì €ìž
+  field_created_on: ë“±ë¡
+  field_updated_on: ë³€ê²½
+  field_field_format: í˜•ì‹
+  field_is_for_all: ëª¨ë“  í”„ë¡œì íŠ¸
+  field_possible_values: ê°€ëŠ¥í•œ ê°’ë“¤
+  field_regexp: ì •ê·œì‹
+  field_min_length: ìµœì†Œ ê¸¸ì´
+  field_max_length: ìµœëŒ€ ê¸¸ì´
+  field_value: ê°’
+  field_category: ë²”ì£¼
+  field_title: ì œëª©
+  field_project: í”„ë¡œì íŠ¸
+  field_issue: ì¼ê°
+  field_status: ìƒíƒœ
+  field_notes: ë§ê¸€
+  field_is_closed: ì™„ë£Œ ìƒíƒœ
+  field_is_default: ê¸°ë³¸ê°’
+  field_tracker: ìœ í˜•
+  field_subject: ì œëª©
+  field_due_date: ì™„ë£Œê¸°í•œ
+  field_assigned_to: ë‹´ë‹¹ìž
+  field_priority: ìš°ì„ ìˆœìœ„
+  field_fixed_version: ëª©í‘œë²„ì „
+  field_user: ì‚¬ìš©ìž
+  field_role: ì—­í• 
+  field_homepage: í™ˆíŽ˜ì´ì§€
+  field_is_public: ê³µê°œ
+  field_parent: ìƒìœ„ í”„ë¡œì íŠ¸
+  field_is_in_roadmap: ë¡œë“œë§µì— í‘œì‹œ
+  field_login: ë¡œê·¸ì¸
+  field_mail_notification: ë©”ì¼ ì•Œë¦¼
+  field_admin: ê´€ë¦¬ìž
+  field_last_login_on: ë§ˆì§€ë§‰ ë¡œê·¸ì¸
+  field_language: ì–¸ì–´
+  field_effective_date: ë‚ ì§œ
+  field_password: ë¹„ë°€ë²ˆí˜¸
+  field_new_password: ìƒˆ ë¹„ë°€ë²ˆí˜¸
+  field_password_confirmation: ë¹„ë°€ë²ˆí˜¸ í™•ì¸
+  field_version: ë²„ì „
+  field_type: ë°©ì‹
+  field_host: í˜¸ìŠ¤íŠ¸
+  field_port: í¬íŠ¸
+  field_account: ê³„ì •
+  field_base_dn: ê¸°ë³¸ DN
+  field_attr_login: ë¡œê·¸ì¸ ì†ì„±
+  field_attr_firstname: ì´ë¦„ ì†ì„±
+  field_attr_lastname: ì„± ì†ì„±
+  field_attr_mail: ë©”ì¼ ì†ì„±
+  field_onthefly: ë™ì  ì‚¬ìš©ìž ìƒì„±
+  field_start_date: ì‹œìž‘ì‹œê°„
+  field_done_ratio: ì§„ì²™ë„
+  field_auth_source: ì¸ì¦ ê³µê¸‰ìž
+  field_hide_mail: ë©”ì¼ ì£¼ì†Œ ìˆ¨ê¸°ê¸°
+  field_comments: ì„¤ëª…
+  field_url: URL
+  field_start_page: ì²« íŽ˜ì´ì§€
+  field_subproject: í•˜ìœ„ í”„ë¡œì íŠ¸
+  field_hours: ì‹œê°„
+  field_activity: ìž‘ì—…ì¢…ë¥˜
+  field_spent_on: ìž‘ì—…ì‹œê°„
+  field_identifier: ì‹ë³„ìž
+  field_is_filter: ê²€ìƒ‰ì¡°ê±´ìœ¼ë¡œ ì‚¬ìš©ë¨
+  field_issue_to_id: ì—°ê´€ëœ ì¼ê°
+  field_delay: ì§€ì—°
+  field_assignable: ì´ ì—­í• ì—ê²Œ ì¼ê°ì„ ë§¡ê¸¸ ìˆ˜ ìžˆìŒ
+  field_redirect_existing_links: ê¸°ì¡´ì˜ ë§í¬ë¡œ ëŒë ¤ë³´ëƒ„(redirect)
+  field_estimated_hours: ì¶”ì •ì‹œê°„
+  field_column_names: ì»¬ëŸ¼
+  field_default_value: ê¸°ë³¸ê°’
+  field_time_zone: ì‹œê°„ëŒ€
+  field_searchable: ê²€ìƒ‰ê°€ëŠ¥
+  field_comments_sorting: ëŒ“ê¸€ ì •ë ¬
+  field_parent_title: ìƒìœ„ ì œëª©
+  field_editable: íŽ¸ì§‘ê°€ëŠ¥
+  field_watcher: ì¼ê°ê´€ëžŒìž
+  field_identity_url: OpenID URL
+  field_content: ë‚´ìš©
+  field_group_by: ê²°ê³¼ë¥¼ ë¬¶ì–´ ë³´ì—¬ì¤„ ê¸°ì¤€
+
+  setting_app_title: ë ˆë“œë§ˆì¸ ì œëª©
+  setting_app_subtitle: ë ˆë“œë§ˆì¸ ë¶€ì œëª©
+  setting_welcome_text: í™˜ì˜ ë©”ì‹œì§€
+  setting_default_language: ê¸°ë³¸ ì–¸ì–´
+  setting_login_required: ì¸ì¦ì´ í•„ìš”í•¨
+  setting_self_registration: ì‚¬ìš©ìž ì§ì ‘ë“±ë¡
+  setting_attachment_max_size: ìµœëŒ€ ì²¨ë¶€íŒŒì¼ í¬ê¸°
+  setting_issues_export_limit: ì¼ê° ë‚´ë³´ë‚´ê¸° ì œí•œ
+  setting_mail_from: ë°œì‹  ë©”ì¼ ì£¼ì†Œ
+  setting_bcc_recipients: ì°¸ì¡°ìžë“¤ì„ bccë¡œ ìˆ¨ê¸°ê¸°
+  setting_plain_text_mail: í…ìŠ¤íŠ¸ë§Œ (HTML ì—†ì´)
+  setting_host_name: í˜¸ìŠ¤íŠ¸ ì´ë¦„ê³¼ ê²½ë¡œ
+  setting_text_formatting: ë³¸ë¬¸ í˜•ì‹
+  setting_wiki_compression: ìœ„í‚¤ ì´ë ¥ ì••ì¶•
+  setting_feeds_limit: í”¼ë“œì— í¬í•¨í•  í•­ëª©ì˜ ìˆ˜
+  setting_default_projects_public: ìƒˆ í”„ë¡œì íŠ¸ë¥¼ ê³µê°œë¡œ ì„¤ì •
+  setting_autofetch_changesets: ì»¤ë°‹(commit)ëœ ë³€ê²½ë¬¶ìŒì„ ìžë™ìœ¼ë¡œ ê°€ì ¸ì˜¤ê¸°
+  setting_sys_api_enabled: ì €ìž¥ì†Œ ê´€ë¦¬ì— WSë¥¼ ì‚¬ìš©
+  setting_commit_ref_keywords: ì¼ê° ì°¸ì¡°ì— ì‚¬ìš©í•  í‚¤ì›Œë“œë“¤
+  setting_commit_fix_keywords: ì¼ê° í•´ê²°ì— ì‚¬ìš©í•  í‚¤ì›Œë“œë“¤
+  setting_autologin: ìžë™ ë¡œê·¸ì¸
+  setting_date_format: ë‚ ì§œ í˜•ì‹
+  setting_time_format: ì‹œê°„ í˜•ì‹
+  setting_cross_project_issue_relations: ë‹¤ë¥¸ í”„ë¡œì íŠ¸ì˜ ì¼ê°ê³¼ ì—°ê²°í•˜ëŠ” ê²ƒì„ í—ˆìš©
+  setting_issue_list_default_columns: ì¼ê° ëª©ë¡ì— í‘œì‹œí•  í•­ëª©
+  setting_emails_footer: ë©”ì¼ ê¼¬ë¦¬
+  setting_protocol: í”„ë¡œí† ì½œ
+  setting_per_page_options: ëª©ë¡ì—ì„œ, í•œ íŽ˜ì´ì§€ì— í‘œì‹œí•  í–‰
+  setting_user_format: ì‚¬ìš©ìž í‘œì‹œ í˜•ì‹
+  setting_activity_days_default: í”„ë¡œì íŠ¸ ìž‘ì—…ë‚´ì—­ì— í‘œì‹œí•  ê¸°ê°„
+  setting_display_subprojects_issues: í•˜ìœ„ í”„ë¡œì íŠ¸ì˜ ì¼ê°ì„ í•¨ê»˜ í‘œì‹œ
+  setting_enabled_scm: "ì§€ì›í•  SCM(Source Control Management)"
+  setting_mail_handler_api_enabled: ìˆ˜ì‹  ë©”ì¼ì— WSë¥¼ í—ˆìš©
+  setting_mail_handler_api_key: API í‚¤
+  setting_sequential_project_identifiers: í”„ë¡œì íŠ¸ ì‹ë³„ìžë¥¼ ìˆœì°¨ì ìœ¼ë¡œ ìƒì„±
+  setting_gravatar_enabled: ê·¸ë¼ë°”íƒ€ ì‚¬ìš©ìž ì•„ì´ì½˜ ì‚¬ìš©
+  setting_diff_max_lines_displayed: ì°¨ì´ì (diff) ë³´ê¸°ì— í‘œì‹œí•  ìµœëŒ€ ì¤„ìˆ˜
+  setting_repository_log_display_limit: ì €ìž¥ì†Œ ë³´ê¸°ì— í‘œì‹œí•  ê°œì •íŒ ì´ë ¥ì˜ ìµœëŒ€ ê°¯ìˆ˜
+  setting_file_max_size_displayed: ë°”ë¡œ ë³´ì—¬ì¤„ í…ìŠ¤íŠ¸íŒŒì¼ì˜ ìµœëŒ€ í¬ê¸°
+  setting_openid: OpenID ë¡œê·¸ì¸ê³¼ ë“±ë¡ í—ˆìš©
+  setting_password_min_length: ìµœì†Œ ì•”í˜¸ ê¸¸ì´
+  setting_new_project_user_role_id: í”„ë¡œì íŠ¸ë¥¼ ë§Œë“  ì‚¬ìš©ìžì—ê²Œ ì£¼ì–´ì§ˆ ì—­í• 
+
+  permission_add_project: í”„ë¡œì íŠ¸ ìƒì„±
+  permission_edit_project: í”„ë¡œì íŠ¸ íŽ¸ì§‘
+  permission_select_project_modules: í”„ë¡œì íŠ¸ ëª¨ë“ˆ ì„ íƒ
+  permission_manage_members: êµ¬ì„±ì› ê´€ë¦¬
+  permission_manage_versions: ë²„ì „ ê´€ë¦¬
+  permission_manage_categories: ì¼ê° ë²”ì£¼ ê´€ë¦¬
+  permission_add_issues: ì¼ê° ì¶”ê°€
+  permission_edit_issues: ì¼ê° íŽ¸ì§‘
+  permission_manage_issue_relations: ì¼ê° ê´€ê³„ ê´€ë¦¬
+  permission_add_issue_notes: ë§ê¸€ ì¶”ê°€
+  permission_edit_issue_notes: ë§ê¸€ íŽ¸ì§‘
+  permission_edit_own_issue_notes: ë‚´ ë§ê¸€ íŽ¸ì§‘
+  permission_move_issues: ì¼ê° ì´ë™
+  permission_delete_issues: ì¼ê° ì‚­ì œ
+  permission_manage_public_queries: ê³µìš© ê²€ìƒ‰ì–‘ì‹ ê´€ë¦¬
+  permission_save_queries: ê²€ìƒ‰ì–‘ì‹ ì €ìž¥
+  permission_view_gantt: Ganttì°¨íŠ¸ ë³´ê¸°
+  permission_view_calendar: ë‹¬ë ¥ ë³´ê¸°
+  permission_view_issue_watchers: ì¼ê°ê´€ëžŒìž ë³´ê¸°
+  permission_add_issue_watchers: ì¼ê°ê´€ëžŒìž ì¶”ê°€
+  permission_log_time: ìž‘ì—…ì‹œê°„ ê¸°ë¡
+  permission_view_time_entries: ì‹œê°„ìž…ë ¥ ë³´ê¸°
+  permission_edit_time_entries: ì‹œê°„ìž…ë ¥ íŽ¸ì§‘
+  permission_edit_own_time_entries: ë‚´ ì‹œê°„ìž…ë ¥ íŽ¸ì§‘
+  permission_manage_news: ë‰´ìŠ¤ ê´€ë¦¬
+  permission_comment_news: ë‰´ìŠ¤ì— ëŒ“ê¸€ë‹¬ê¸°
+  permission_view_documents: ë¬¸ì„œ ë³´ê¸°
+  permission_manage_files: íŒŒì¼ê´€ë¦¬
+  permission_view_files: íŒŒì¼ë³´ê¸°
+  permission_manage_wiki: ìœ„í‚¤ ê´€ë¦¬
+  permission_rename_wiki_pages: ìœ„í‚¤ íŽ˜ì´ì§€ ì´ë¦„ë³€ê²½
+  permission_delete_wiki_pages: ìœ„ì¹˜ íŽ˜ì´ì§€ ì‚­ì œ
+  permission_view_wiki_pages: ìœ„í‚¤ ë³´ê¸°
+  permission_view_wiki_edits: ìœ„í‚¤ ê¸°ë¡ ë³´ê¸°
+  permission_edit_wiki_pages: ìœ„í‚¤ íŽ˜ì´ì§€ íŽ¸ì§‘
+  permission_delete_wiki_pages_attachments: ì²¨ë¶€íŒŒì¼ ì‚­ì œ
+  permission_protect_wiki_pages: í”„ë¡œì íŠ¸ ìœ„í‚¤ íŽ˜ì´ì§€
+  permission_manage_repository: ì €ìž¥ì†Œ ê´€ë¦¬
+  permission_browse_repository: ì €ìž¥ì†Œ ë‘˜ëŸ¬ë³´ê¸°
+  permission_view_changesets: ë³€ê²½ë¬¶ìŒë³´ê¸°
+  permission_commit_access: ë³€ê²½ë¡œê·¸ ë³´ê¸°
+  permission_manage_boards: ê²Œì‹œíŒ ê´€ë¦¬
+  permission_view_messages: ë©”ì‹œì§€ ë³´ê¸°
+  permission_add_messages: ë©”ì‹œì§€ ì¶”ê°€
+  permission_edit_messages: ë©”ì‹œì§€ íŽ¸ì§‘
+  permission_edit_own_messages: ìžê¸° ë©”ì‹œì§€ íŽ¸ì§‘
+  permission_delete_messages: ë©”ì‹œì§€ ì‚­ì œ
+  permission_delete_own_messages: ìžê¸° ë©”ì‹œì§€ ì‚­ì œ
+
+  project_module_issue_tracking: ì¼ê°ê´€ë¦¬
+  project_module_time_tracking: ì‹œê°„ì¶”ì 
+  project_module_news: ë‰´ìŠ¤
+  project_module_documents: ë¬¸ì„œ
+  project_module_files: íŒŒì¼
+  project_module_wiki: ìœ„í‚¤
+  project_module_repository: ì €ìž¥ì†Œ
+  project_module_boards: ê²Œì‹œíŒ
+
+  label_user: ì‚¬ìš©ìž
+  label_user_plural: ì‚¬ìš©ìž
+  label_user_new: ìƒˆ ì‚¬ìš©ìž
+  label_project: í”„ë¡œì íŠ¸
+  label_project_new: ìƒˆ í”„ë¡œì íŠ¸
+  label_project_plural: í”„ë¡œì íŠ¸
+  label_x_projects:
+    zero:  ì—†ìŒ
+    one:   "í•œ í”„ë¡œì íŠ¸"
+    other: "%{count}ê°œ í”„ë¡œì íŠ¸"
+  label_project_all: ëª¨ë“  í”„ë¡œì íŠ¸
+  label_project_latest: ìµœê·¼ í”„ë¡œì íŠ¸
+  label_issue: ì¼ê°
+  label_issue_new: ìƒˆ ì¼ê°ë§Œë“¤ê¸°
+  label_issue_plural: ì¼ê°
+  label_issue_view_all: ëª¨ë“  ì¼ê° ë³´ê¸°
+  label_issues_by: "%{value}ë³„ ì¼ê°"
+  label_issue_added: ì¼ê° ì¶”ê°€
+  label_issue_updated: ì¼ê° ìˆ˜ì •
+  label_document: ë¬¸ì„œ
+  label_document_new: ìƒˆ ë¬¸ì„œ
+  label_document_plural: ë¬¸ì„œ
+  label_document_added: ë¬¸ì„œ ì¶”ê°€
+  label_role: ì—­í• 
+  label_role_plural: ì—­í• 
+  label_role_new: ìƒˆ ì—­í• 
+  label_role_and_permissions: ì—­í•  ë° ê¶Œí•œ
+  label_member: êµ¬ì„±ì›
+  label_member_new: ìƒˆ êµ¬ì„±ì›
+  label_member_plural: êµ¬ì„±ì›
+  label_tracker: ì¼ê° ìœ í˜•
+  label_tracker_plural: ì¼ê° ìœ í˜•
+  label_tracker_new: ìƒˆ ì¼ê° ìœ í˜•
+  label_workflow: ì—…ë¬´íë¦„
+  label_issue_status: ì¼ê° ìƒíƒœ
+  label_issue_status_plural: ì¼ê° ìƒíƒœ
+  label_issue_status_new: ìƒˆ ì¼ê° ìƒíƒœ
+  label_issue_category: ì¼ê° ë²”ì£¼
+  label_issue_category_plural: ì¼ê° ë²”ì£¼
+  label_issue_category_new: ìƒˆ ì¼ê° ë²”ì£¼
+  label_custom_field: ì‚¬ìš©ìž ì •ì˜ í•­ëª©
+  label_custom_field_plural: ì‚¬ìš©ìž ì •ì˜ í•­ëª©
+  label_custom_field_new: ìƒˆ ì‚¬ìš©ìž ì •ì˜ í•­ëª©
+  label_enumerations: ì½”ë“œê°’
+  label_enumeration_new: ìƒˆ ì½”ë“œê°’
+  label_information: ì •ë³´
+  label_information_plural: ì •ë³´
+  label_please_login: ë¡œê·¸ì¸í•˜ì„¸ìš”.
+  label_register: ë“±ë¡
+  label_login_with_open_id_option: ë˜ëŠ” OpenIDë¡œ ë¡œê·¸ì¸
+  label_password_lost: ë¹„ë°€ë²ˆí˜¸ ì°¾ê¸°
+  label_home: ì´ˆê¸°í™”ë©´
+  label_my_page: ë‚´ íŽ˜ì´ì§€
+  label_my_account: ë‚´ ê³„ì •
+  label_my_projects: ë‚´ í”„ë¡œì íŠ¸
+  label_administration: ê´€ë¦¬
+  label_login: ë¡œê·¸ì¸
+  label_logout: ë¡œê·¸ì•„ì›ƒ
+  label_help: ë„ì›€ë§
+  label_reported_issues: ë³´ê³ í•œ ì¼ê°
+  label_assigned_to_me_issues: ë‚´ê°€ ë§¡ì€ ì¼ê° 
+  label_last_login: ë§ˆì§€ë§‰ ì ‘ì†
+  label_registered_on: ë“±ë¡ì‹œê°
+  label_activity: ìž‘ì—…ë‚´ì—­
+  label_overall_activity: ì „ì²´ ìž‘ì—…ë‚´ì—­
+  label_user_activity: "%{value}ì˜ ìž‘ì—…ë‚´ì—­"
+  label_new: ìƒˆë¡œ ë§Œë“¤ê¸°
+  label_logged_as: 'ë¡œê·¸ì¸ê³„ì •:'
+  label_environment: í™˜ê²½
+  label_authentication: ì¸ì¦
+  label_auth_source: ì¸ì¦ ê³µê¸‰ìž
+  label_auth_source_new: ìƒˆ ì¸ì¦ ê³µê¸‰ìž
+  label_auth_source_plural: ì¸ì¦ ê³µê¸‰ìž
+  label_subproject_plural: í•˜ìœ„ í”„ë¡œì íŠ¸
+  label_and_its_subprojects: "%{value}ì™€ í•˜ìœ„ í”„ë¡œì íŠ¸ë“¤"
+  label_min_max_length: ìµœì†Œ - ìµœëŒ€ ê¸¸ì´
+  label_list: ëª©ë¡
+  label_date: ë‚ ì§œ
+  label_integer: ì •ìˆ˜
+  label_float: ë¶€ë™ì†Œìˆ˜
+  label_boolean: ë¶€ìš¸ë¦°
+  label_string: ë¬¸ìžì—´
+  label_text: í…ìŠ¤íŠ¸
+  label_attribute: ì†ì„±
+  label_attribute_plural: ì†ì„±
+  label_no_data: í‘œì‹œí•  ë°ì´í„°ê°€ ì—†ìŠµë‹ˆë‹¤.
+  label_change_status: ìƒíƒœ ë³€ê²½
+  label_history: ì´ë ¥
+  label_attachment: íŒŒì¼
+  label_attachment_new: íŒŒì¼ì¶”ê°€
+  label_attachment_delete: íŒŒì¼ì‚­ì œ
+  label_attachment_plural: íŒŒì¼
+  label_file_added: íŒŒì¼ ì¶”ê°€
+  label_report: ë³´ê³ ì„œ
+  label_report_plural: ë³´ê³ ì„œ
+  label_news: ë‰´ìŠ¤
+  label_news_new: ìƒˆ ë‰´ìŠ¤
+  label_news_plural: ë‰´ìŠ¤
+  label_news_latest: ìµœê·¼ ë‰´ìŠ¤
+  label_news_view_all: ëª¨ë“  ë‰´ìŠ¤
+  label_news_added: ë‰´ìŠ¤ ì¶”ê°€
+  label_settings: ì„¤ì •
+  label_overview: ê°œìš”
+  label_version: ë²„ì „
+  label_version_new: ìƒˆ ë²„ì „
+  label_version_plural: ë²„ì „
+  label_confirmation: í™•ì¸
+  label_export_to: ë‚´ë³´ë‚´ê¸°
+  label_read: ì½ê¸°...
+  label_public_projects: ê³µê°œ í”„ë¡œì íŠ¸
+  label_open_issues: ì§„í–‰ì¤‘
+  label_open_issues_plural: ì§„í–‰ì¤‘
+  label_closed_issues: ì™„ë£Œë¨
+  label_closed_issues_plural: ì™„ë£Œë¨
+  label_x_open_issues_abbr_on_total:
+    zero:  "ì´ %{total} ê±´ ëª¨ë‘ ì™„ë£Œ"
+    one:   "í•œ ê±´ ì§„í–‰ ì¤‘ / ì´ %{total} ê±´ ì¤‘ "
+    other: "%{count} ê±´ ì§„í–‰ ì¤‘ / ì´ %{total} ê±´"
+  label_x_open_issues_abbr:
+    zero:  ëª¨ë‘ ì™„ë£Œ
+    one:   í•œ ê±´ ì§„í–‰ ì¤‘
+    other: "%{count} ê±´ ì§„í–‰ ì¤‘"
+  label_x_closed_issues_abbr:
+    zero:  ëª¨ë‘ ë¯¸ì™„ë£Œ
+    one:   í•œ ê±´ ì™„ë£Œ
+    other: "%{count} ê±´ ì™„ë£Œ"
+  label_total: í•©ê³„
+  label_permissions: ê¶Œí•œ
+  label_current_status: ì¼ê° ìƒíƒœ
+  label_new_statuses_allowed: í—ˆìš©ë˜ëŠ” ì¼ê° ìƒíƒœ
+  label_all: ëª¨ë‘
+  label_none: ì—†ìŒ
+  label_nobody: ë¯¸ì§€ì •
+  label_next: ë‹¤ìŒ
+  label_previous: ë’¤ë¡œ
+  label_used_by: ì‚¬ìš©ë¨
+  label_details: ìžì„¸ížˆ
+  label_add_note: ì¼ê°ë§ê¸€ ì¶”ê°€
+  label_per_page: íŽ˜ì´ì§€ë³„
+  label_calendar: ë‹¬ë ¥
+  label_months_from: ê°œì›” ë™ì•ˆ | ë‹¤ìŒë¶€í„°
+  label_gantt: Gantt ì± íŠ¸
+  label_internal: ë‚´ë¶€
+  label_last_changes: "ìµœê·¼ %{count}ê°œì˜ ë³€ê²½ì‚¬í•­"
+  label_change_view_all: ëª¨ë“  ë³€ê²½ ë‚´ì—­ ë³´ê¸°
+  label_personalize_page: ìž…ë§›ëŒ€ë¡œ êµ¬ì„±í•˜ê¸°
+  label_comment: ëŒ“ê¸€
+  label_comment_plural: ëŒ“ê¸€
+  label_x_comments:
+    zero: ëŒ“ê¸€ ì—†ìŒ
+    one: í•œ ê°œì˜ ëŒ“ê¸€
+    other: "%{count} ê°œì˜ ëŒ“ê¸€"
+  label_comment_add: ëŒ“ê¸€ ì¶”ê°€
+  label_comment_added: ëŒ“ê¸€ì´ ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤.
+  label_comment_delete: ëŒ“ê¸€ ì‚­ì œ
+  label_query: ê²€ìƒ‰ì–‘ì‹
+  label_query_plural: ê²€ìƒ‰ì–‘ì‹
+  label_query_new: ìƒˆ ê²€ìƒ‰ì–‘ì‹
+  label_filter_add: ê²€ìƒ‰ì¡°ê±´ ì¶”ê°€
+  label_filter_plural: ê²€ìƒ‰ì¡°ê±´
+  label_equals: ì´ë‹¤
+  label_not_equals: ì•„ë‹ˆë‹¤
+  label_in_less_than: ì´ë‚´
+  label_in_more_than: ì´í›„
+  label_greater_or_equal: ">="
+  label_less_or_equal: "<="
+  label_in: ì´ë‚´
+  label_today: ì˜¤ëŠ˜
+  label_all_time: ëª¨ë“  ì‹œê°„
+  label_yesterday: ì–´ì œ
+  label_this_week: ì´ë²ˆì£¼
+  label_last_week: ì§€ë‚œ ì£¼
+  label_last_n_days: "ì§€ë‚œ %{count} ì¼"
+  label_this_month: ì´ë²ˆ ë‹¬
+  label_last_month: ì§€ë‚œ ë‹¬
+  label_this_year: ì˜¬í•´
+  label_date_range: ë‚ ì§œ ë²”ìœ„
+  label_less_than_ago: ì´ì „
+  label_more_than_ago: ì´í›„
+  label_ago: ì¼ ì „
+  label_contains: í¬í•¨ë˜ëŠ” í‚¤ì›Œë“œ
+  label_not_contains: í¬í•¨í•˜ì§€ ì•ŠëŠ” í‚¤ì›Œë“œ
+  label_day_plural: ì¼
+  label_repository: ì €ìž¥ì†Œ
+  label_repository_plural: ì €ìž¥ì†Œ
+  label_browse: ì €ìž¥ì†Œ ë‘˜ëŸ¬ë³´ê¸°
+  label_revision: ê°œì •íŒ
+  label_revision_plural: ê°œì •íŒ
+  label_associated_revisions: ê´€ë ¨ëœ ê°œì •íŒë“¤
+  label_added: ì¶”ê°€ë¨
+  label_modified: ë³€ê²½ë¨
+  label_copied: ë³µì‚¬ë¨
+  label_renamed: ì´ë¦„ë°”ë€œ
+  label_deleted: ì‚­ì œë¨
+  label_latest_revision: ìµœê·¼ ê°œì •íŒ
+  label_latest_revision_plural: ìµœê·¼ ê°œì •íŒ
+  label_view_revisions: ê°œì •íŒ ë³´ê¸°
+  label_max_size: ìµœëŒ€ í¬ê¸°
+  label_sort_highest: ë§¨ ìœ„ë¡œ
+  label_sort_higher: ìœ„ë¡œ
+  label_sort_lower: ì•„ëž˜ë¡œ
+  label_sort_lowest: ë§¨ ì•„ëž˜ë¡œ
+  label_roadmap: ë¡œë“œë§µ
+  label_roadmap_due_in: "ê¸°í•œ  %{value}"
+  label_roadmap_overdue: "%{value} ì§€ì—°"
+  label_roadmap_no_issues: ì´ ë²„ì „ì— í•´ë‹¹í•˜ëŠ” ì¼ê° ì—†ìŒ
+  label_search: ê²€ìƒ‰
+  label_result_plural: ê²°ê³¼
+  label_all_words: ëª¨ë“  ë‹¨ì–´
+  label_wiki: ìœ„í‚¤
+  label_wiki_edit: ìœ„í‚¤ íŽ¸ì§‘
+  label_wiki_edit_plural: ìœ„í‚¤ íŽ¸ì§‘
+  label_wiki_page: ìœ„í‚¤ íŽ˜ì´ì§€
+  label_wiki_page_plural: ìœ„í‚¤ íŽ˜ì´ì§€
+  label_index_by_title: ì œëª©ë³„ ìƒ‰ì¸
+  label_index_by_date: ë‚ ì§œë³„ ìƒ‰ì¸
+  label_current_version: í˜„ìž¬ ë²„ì „
+  label_preview: ë¯¸ë¦¬ë³´ê¸°
+  label_feed_plural: í”¼ë“œ(Feeds)
+  label_changes_details: ëª¨ë“  ìƒì„¸ ë³€ê²½ ë‚´ì—­
+  label_issue_tracking: ì¼ê° ì¶”ì 
+  label_spent_time: ì†Œìš” ì‹œê°„
+  label_f_hour: "%{value} ì‹œê°„"
+  label_f_hour_plural: "%{value} ì‹œê°„"
+  label_time_tracking: ì‹œê°„ì¶”ì 
+  label_change_plural: ë³€ê²½ì‚¬í•­ë“¤
+  label_statistics: í†µê³„
+  label_commits_per_month: ì›”ë³„ ì»¤ë°‹ ë‚´ì—­
+  label_commits_per_author: ì €ìžë³„ ì»¤ë°‹ ë‚´ì—­
+  label_view_diff: ì°¨ì´ì  ë³´ê¸°
+  label_diff_inline: ë‘ì¤„ë¡œ
+  label_diff_side_by_side: í•œì¤„ë¡œ
+  label_options: ì˜µì…˜
+  label_copy_workflow_from: ì—…ë¬´íë¦„ ë³µì‚¬í•˜ê¸°
+  label_permissions_report: ê¶Œí•œ ë³´ê³ ì„œ
+  label_watched_issues: ì§€ì¼œë³´ê³  ìžˆëŠ” ì¼ê° 
+  label_related_issues: ì—°ê²°ëœ ì¼ê°
+  label_applied_status: ì ìš©ëœ ìƒíƒœ
+  label_loading: ì½ëŠ” ì¤‘...
+  label_relation_new: ìƒˆ ê´€ê³„
+  label_relation_delete: ê´€ê³„ ì§€ìš°ê¸°
+  label_relates_to: "ë‹¤ìŒ ì¼ê°ê³¼ ê´€ë ¨ë¨:"
+  label_duplicates: "ë‹¤ìŒ ì¼ê°ì— ì¤‘ë³µë¨:"
+  label_duplicated_by: "ì¤‘ë³µëœ ì¼ê°:"
+  label_blocks: "ë‹¤ìŒ ì¼ê°ì˜ í•´ê²°ì„ ë§‰ê³  ìžˆìŒ:"
+  label_blocked_by: "ë‹¤ìŒ ì¼ê°ì—ê²Œ ë§‰í˜€ ìžˆìŒ:"
+  label_precedes: "ë‹¤ìŒì— ì§„í–‰í•  ì¼ê°:"
+  label_follows: "ë‹¤ìŒ ì¼ê°ì„ ìš°ì„  ì§„í–‰:"
+  label_end_to_start: "ëì—ì„œ ì‹œìž‘"
+  label_end_to_end: "ëì—ì„œ ë"
+  label_start_to_start: "ì‹œìž‘ì—ì„œ ì‹œìž‘" 
+  label_start_to_end: "ì‹œìž‘ì—ì„œ ë"
+  label_stay_logged_in: ë¡œê·¸ì¸ ìœ ì§€
+  label_disabled: ë¹„í™œì„±í™”
+  label_show_completed_versions: ì™„ë£Œëœ ë²„ì „ ë³´ê¸°
+  label_me: ë‚˜
+  label_board: ê²Œì‹œíŒ
+  label_board_new: ìƒˆ ê²Œì‹œíŒ
+  label_board_plural: ê²Œì‹œíŒ
+  label_topic_plural: ì£¼ì œ
+  label_message_plural: ê¸€
+  label_message_last: ë§ˆì§€ë§‰ ê¸€
+  label_message_new: ìƒˆê¸€ì“°ê¸°
+  label_message_posted: ê¸€ ì¶”ê°€
+  label_reply_plural: ë‹µê¸€
+  label_send_information: ì‚¬ìš©ìžì—ê²Œ ê³„ì •ì •ë³´ë¥¼ ë³´ë‚´ê¸°
+  label_year: ë…„
+  label_month: ì›”
+  label_week: ì£¼
+  label_date_from: 'ê¸°ê°„:'
+  label_date_to: ' ~ '
+  label_language_based: ì–¸ì–´ì„¤ì •ì— ë”°ë¦„
+  label_sort_by: "%{value}(ìœ¼)ë¡œ ì •ë ¬"
+  label_send_test_email: í…ŒìŠ¤íŠ¸ ë©”ì¼ ë³´ë‚´ê¸°
+  label_feeds_access_key_created_on: "í”¼ë“œ ì ‘ê·¼ í‚¤ê°€ %{value} ì´ì „ì— ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤."
+  label_module_plural: ëª¨ë“ˆ
+  label_added_time_by: "%{author}ì´(ê°€) %{age} ì „ì— ì¶”ê°€í•¨"
+  label_updated_time_by: "%{author}ì´(ê°€) %{age} ì „ì— ë³€ê²½"
+  label_updated_time: "%{value} ì „ì— ìˆ˜ì •ë¨"
+  label_jump_to_a_project: í”„ë¡œì íŠ¸ ë°”ë¡œê°€ê¸°
+  label_file_plural: íŒŒì¼
+  label_changeset_plural: ë³€ê²½ë¬¶ìŒ
+  label_default_columns: ê¸°ë³¸ ì»¬ëŸ¼
+  label_no_change_option: (ìˆ˜ì • ì•ˆí•¨)
+  label_bulk_edit_selected_issues: ì„ íƒí•œ ì¼ê°ë“¤ì„ í•œêº¼ë²ˆì— ìˆ˜ì •í•˜ê¸°
+  label_theme: í…Œë§ˆ
+  label_default: ê¸°ë³¸
+  label_search_titles_only: ì œëª©ì—ì„œë§Œ ì°¾ê¸°
+  label_user_mail_option_all: "ë‚´ê°€ ì†í•œ í”„ë¡œì íŠ¸ë¡œë“¤ë¶€í„° ëª¨ë“  ë©”ì¼ ë°›ê¸°"
+  label_user_mail_option_selected: "ì„ íƒí•œ í”„ë¡œì íŠ¸ë“¤ë¡œë¶€í„° ëª¨ë“  ë©”ì¼ ë°›ê¸°.."
+  label_user_mail_no_self_notified: "ë‚´ê°€ ë§Œë“  ë³€ê²½ì‚¬í•­ë“¤ì— ëŒ€í•´ì„œëŠ” ì•Œë¦¼ë©”ì¼ì„ ë°›ì§€ ì•ŠìŠµë‹ˆë‹¤."
+  label_registration_activation_by_email: ë©”ì¼ë¡œ ê³„ì •ì„ í™œì„±í™”í•˜ê¸°
+  label_registration_automatic_activation: ìžë™ ê³„ì • í™œì„±í™”
+  label_registration_manual_activation: ìˆ˜ë™ ê³„ì • í™œì„±í™”
+  label_display_per_page: "íŽ˜ì´ì§€ë‹¹ ì¤„ìˆ˜: %{value}"
+  label_age: ë§ˆì§€ë§‰ ìˆ˜ì •ì¼
+  label_change_properties: ì†ì„± ë³€ê²½
+  label_general: ì¼ë°˜
+  label_more: ì œëª© ë° ì„¤ëª… ìˆ˜ì •
+  label_scm: í˜•ìƒê´€ë¦¬ì‹œìŠ¤í…œ
+  label_plugins: í”ŒëŸ¬ê·¸ì¸
+  label_ldap_authentication: LDAP ì¸ì¦
+  label_downloads_abbr: D/L
+  label_optional_description: ë¶€ê°€ì ì¸ ì„¤ëª…
+  label_add_another_file: ë‹¤ë¥¸ íŒŒì¼ ì¶”ê°€
+  label_preferences: ì„¤ì •
+  label_chronological_order: ì‹œê°„ ìˆœìœ¼ë¡œ ì •ë ¬
+  label_reverse_chronological_order: ì‹œê°„ ì—­ìˆœìœ¼ë¡œ ì •ë ¬
+  label_planning: í”„ë¡œì íŠ¸ê³„íš
+  label_incoming_emails: ìˆ˜ì‹  ë©”ì¼
+  label_generate_key: í‚¤ ìƒì„±
+  label_issue_watchers: ì¼ê°ê´€ëžŒìž
+  label_example: ì˜ˆ
+  label_display: í‘œì‹œë°©ì‹
+  label_sort: ì •ë ¬
+  label_ascending: ì˜¤ë¦„ì°¨ìˆœ
+  label_descending: ë‚´ë¦¼ì°¨ìˆœ
+  label_date_from_to: "%{start}ë¶€í„° %{end}ê¹Œì§€"
+  label_wiki_content_added: ìœ„í‚¤íŽ˜ì´ì§€ ì¶”ê°€
+  label_wiki_content_updated: ìœ„í‚¤íŽ˜ì´ì§€ ìˆ˜ì •
+
+  button_login: ë¡œê·¸ì¸
+  button_submit: í™•ì¸
+  button_save: ì €ìž¥
+  button_check_all: ëª¨ë‘ì„ íƒ
+  button_uncheck_all: ì„ íƒí•´ì œ
+  button_delete: ì‚­ì œ
+  button_create: ë§Œë“¤ê¸°
+  button_create_and_continue: ë§Œë“¤ê³  ê³„ì†í•˜ê¸°
+  button_test: í…ŒìŠ¤íŠ¸
+  button_edit: íŽ¸ì§‘
+  button_add: ì¶”ê°€
+  button_change: ë³€ê²½
+  button_apply: ì ìš©
+  button_clear: ì§€ìš°ê¸°
+  button_lock: ìž ê¸ˆ
+  button_unlock: ìž ê¸ˆí•´ì œ
+  button_download: ë‹¤ìš´ë¡œë“œ
+  button_list: ëª©ë¡
+  button_view: ë³´ê¸°
+  button_move: ì´ë™
+  button_back: ë’¤ë¡œ
+  button_cancel: ì·¨ì†Œ
+  button_activate: í™œì„±í™”
+  button_sort: ì •ë ¬
+  button_log_time: ìž‘ì—…ì‹œê°„ ê¸°ë¡
+  button_rollback: ì´ ë²„ì „ìœ¼ë¡œ ë˜ëŒë¦¬ê¸°
+  button_watch: ì§€ì¼œë³´ê¸°
+  button_unwatch: ê´€ì‹¬ë„ê¸°
+  button_reply: ë‹µê¸€
+  button_archive: ìž ê¸ˆë³´ê´€
+  button_unarchive: ìž ê¸ˆë³´ê´€í•´ì œ
+  button_reset: ì´ˆê¸°í™”
+  button_rename: ì´ë¦„ë°”ê¾¸ê¸°
+  button_change_password: ë¹„ë°€ë²ˆí˜¸ ë°”ê¾¸ê¸°
+  button_copy: ë³µì‚¬
+  button_annotate: ì´ë ¥í•´ì„¤
+  button_update: ì—…ë°ì´íŠ¸
+  button_configure: ì„¤ì •
+  button_quote: ëŒ“ê¸€ë‹¬ê¸°
+
+  status_active: ì‚¬ìš©ì¤‘
+  status_registered: ë“±ë¡ëŒ€ê¸°
+  status_locked: ìž ê¹€
+
+  text_select_mail_notifications: ì•Œë¦¼ë©”ì¼ì´ í•„ìš”í•œ ìž‘ì—…ì„ ì„ íƒí•˜ì„¸ìš”.
+  text_regexp_info: ì˜ˆ) ^[A-Z0-9]+$
+  text_min_max_length_info: 0 ëŠ” ì œí•œì´ ì—†ìŒì„ ì˜ë¯¸í•¨
+  text_project_destroy_confirmation: ì´ í”„ë¡œì íŠ¸ë¥¼ ì‚­ì œí•˜ê³  ëª¨ë“  ë°ì´í„°ë¥¼ ì§€ìš°ì‹œê² ìŠµë‹ˆê¹Œ?
+  text_subprojects_destroy_warning: "í•˜ìœ„ í”„ë¡œì íŠ¸(%{value})ì´(ê°€) ìžë™ìœ¼ë¡œ ì§€ì›Œì§ˆ ê²ƒìž…ë‹ˆë‹¤."
+  text_workflow_edit: ì—…ë¬´íë¦„ì„ ìˆ˜ì •í•˜ë ¤ë©´ ì—­í• ê³¼ ì¼ê° ìœ í˜•ì„ ì„ íƒí•˜ì„¸ìš”.
+  text_are_you_sure: ê³„ì† ì§„í–‰ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?
+  text_tip_issue_begin_day: ì˜¤ëŠ˜ ì‹œìž‘í•˜ëŠ” ì—…ë¬´(task)
+  text_tip_issue_end_day: ì˜¤ëŠ˜ ì¢…ë£Œí•˜ëŠ” ì—…ë¬´(task)
+  text_tip_issue_begin_end_day: ì˜¤ëŠ˜ ì‹œìž‘í•˜ê³  ì¢…ë£Œí•˜ëŠ” ì—…ë¬´(task)
+  text_caracters_maximum: "ìµœëŒ€ %{count} ê¸€ìž ê°€ëŠ¥"
+  text_caracters_minimum: "ìµœì†Œí•œ %{count} ê¸€ìž ì´ìƒì´ì–´ì•¼ í•©ë‹ˆë‹¤."
+  text_length_between: "%{min} ì—ì„œ %{max} ê¸€ìž"
+  text_tracker_no_workflow: ì´ ì¼ê° ìœ í˜•ì—ëŠ” ì—…ë¬´íë¦„ì´ ì •ì˜ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤.
+  text_unallowed_characters: í—ˆìš©ë˜ì§€ ì•ŠëŠ” ë¬¸ìžì—´
+  text_comma_separated: "êµ¬ë¶„ìž','ë¥¼ ì´ìš©í•´ì„œ ì—¬ëŸ¬ ê°œì˜ ê°’ì„ ìž…ë ¥í•  ìˆ˜ ìžˆìŠµë‹ˆë‹¤."
+  text_issues_ref_in_commit_messages: ì»¤ë°‹ ë©”ì‹œì§€ì—ì„œ ì¼ê°ì„ ì°¸ì¡°í•˜ê±°ë‚˜ í•´ê²°í•˜ê¸°
+  text_issue_added: "%{author}ì´(ê°€) ì¼ê° %{id}ì„(ë¥¼) ë³´ê³ í•˜ì˜€ìŠµë‹ˆë‹¤."
+  text_issue_updated: "%{author}ì´(ê°€) ì¼ê° %{id}ì„(ë¥¼) ìˆ˜ì •í•˜ì˜€ìŠµë‹ˆë‹¤."
+  text_wiki_destroy_confirmation: ì´ ìœ„í‚¤ì™€ ëª¨ë“  ë‚´ìš©ì„ ì§€ìš°ì‹œê² ìŠµë‹ˆê¹Œ?
+  text_issue_category_destroy_question: "ì¼ë¶€ ì¼ê°ë“¤(%{count}ê°œ)ì´ ì´ ë²”ì£¼ì— ì§€ì •ë˜ì–´ ìžˆìŠµë‹ˆë‹¤. ì–´ë–»ê²Œ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
+  text_issue_category_destroy_assignments: ë²”ì£¼ ì§€ì • ì§€ìš°ê¸°
+  text_issue_category_reassign_to: ì¼ê°ì„ ì´ ë²”ì£¼ì— ë‹¤ì‹œ ì§€ì •í•˜ê¸°
+  text_user_mail_option: "ì„ íƒí•˜ì§€ ì•Šì€ í”„ë¡œì íŠ¸ì—ì„œë„, ì§€ì¼œë³´ëŠ” ì¤‘ì´ê±°ë‚˜ ì†í•´ìžˆëŠ” ì‚¬í•­(ì¼ê°ë¥¼ ë°œí–‰í–ˆê±°ë‚˜ í• ë‹¹ëœ ê²½ìš°)ì´ ìžˆìœ¼ë©´ ì•Œë¦¼ë©”ì¼ì„ ë°›ê²Œ ë©ë‹ˆë‹¤."
+  text_no_configuration_data: "ì—­í• , ì¼ê° ìœ í˜•, ì¼ê° ìƒíƒœë“¤ê³¼ ì—…ë¬´íë¦„ì´ ì•„ì§ ì„¤ì •ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤.\nê¸°ë³¸ ì„¤ì •ì„ ì½ì–´ë“¤ì´ëŠ” ê²ƒì„ ê¶Œìž¥í•©ë‹ˆë‹¤. ì½ì–´ë“¤ì¸ í›„ì— ìˆ˜ì •í•  ìˆ˜ ìžˆìŠµë‹ˆë‹¤."
+  text_load_default_configuration: ê¸°ë³¸ ì„¤ì •ì„ ì½ì–´ë“¤ì´ê¸°
+  text_status_changed_by_changeset: "ë³€ê²½ë¬¶ìŒ %{value}ì— ì˜í•˜ì—¬ ë³€ê²½ë¨"
+  text_issues_destroy_confirmation: 'ì„ íƒí•œ ì¼ê°ë¥¼ ì •ë§ë¡œ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?'
+  text_select_project_modules: 'ì´ í”„ë¡œì íŠ¸ì—ì„œ í™œì„±í™”ì‹œí‚¬ ëª¨ë“ˆì„ ì„ íƒí•˜ì„¸ìš”:'
+  text_default_administrator_account_changed: ê¸°ë³¸ ê´€ë¦¬ìž ê³„ì •ì´ ë³€ê²½
+  text_file_repository_writable: íŒŒì¼ ì €ìž¥ì†Œ ì“°ê¸° ê°€ëŠ¥
+  text_plugin_assets_writable: í”ŒëŸ¬ê·¸ì¸ ì „ìš© ë””ë ‰í† ë¦¬ê°€ ì“°ê¸° ê°€ëŠ¥
+  text_rmagick_available: RMagick ì‚¬ìš© ê°€ëŠ¥ (ì„ íƒì )
+  text_destroy_time_entries_question: ì‚­ì œí•˜ë ¤ëŠ” ì¼ê°ì— %{hours} ì‹œê°„ì´ ë³´ê³ ë˜ì–´ ìžˆìŠµë‹ˆë‹¤. ì–´ë–»ê²Œ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?
+  text_destroy_time_entries: ë³´ê³ ëœ ì‹œê°„ì„ ì‚­ì œí•˜ê¸°
+  text_assign_time_entries_to_project: ë³´ê³ ëœ ì‹œê°„ì„ í”„ë¡œì íŠ¸ì— í• ë‹¹í•˜ê¸°
+  text_reassign_time_entries: 'ì´ ì•Œë¦¼ì— ë³´ê³ ëœ ì‹œê°„ì„ ìž¬í• ë‹¹í•˜ê¸°:'
+  text_user_wrote: "%{value}ì˜ ë§ê¸€:"
+  text_enumeration_category_reassign_to: 'ìƒˆë¡œìš´ ê°’ì„ ì„¤ì •:'
+  text_enumeration_destroy_question: "%{count} ê°œì˜ ì¼ê°ì´ ì´ ê°’ì„ ì‚¬ìš©í•˜ê³  ìžˆìŠµë‹ˆë‹¤."
+  text_email_delivery_not_configured: "ì´ë©”ì¼ ì „ë‹¬ì´ ì„¤ì •ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤. ê·¸ëž˜ì„œ ì•Œë¦¼ì´ ë¹„í™œì„±í™”ë˜ì—ˆìŠµë‹ˆë‹¤.\n SMTPì„œë²„ë¥¼ config/configuration.ymlì—ì„œ ì„¤ì •í•˜ê³  ì–´í”Œë¦¬ì¼€ì´ì…˜ì„ ë‹¤ì‹œ ì‹œìž‘í•˜ì‹­ì‹œì˜¤. ê·¸ëŸ¬ë©´ ë™ìž‘í•©ë‹ˆë‹¤."
+  text_repository_usernames_mapping: "ì €ìž¥ì†Œ ë¡œê·¸ì—ì„œ ë°œê²¬ëœ ê° ì‚¬ìš©ìžì— ë ˆë“œë§ˆì¸ ì‚¬ìš©ìžë¥¼ ì—…ë°ì´íŠ¸í• ë•Œ ì„ íƒí•©ë‹ˆë‹¤.\në ˆë“œë§ˆì¸ê³¼ ì €ìž¥ì†Œì˜ ì´ë¦„ì´ë‚˜ ì´ë©”ì¼ì´ ê°™ì€ ì‚¬ìš©ìžê°€ ìžë™ìœ¼ë¡œ ì—°ê²°ë©ë‹ˆë‹¤."
+  text_diff_truncated: '... ì´ ì°¨ì´ì ì€ í‘œì‹œí•  ìˆ˜ ìžˆëŠ” ìµœëŒ€ ì¤„ìˆ˜ë¥¼ ì´ˆê³¼í•´ì„œ ì´ ì°¨ì´ì ì€ ìž˜ë ¸ìŠµë‹ˆë‹¤.'
+  text_custom_field_possible_values_info: 'ê° ê°’ ë‹¹ í•œ ì¤„'
+  text_wiki_page_destroy_question: ì´ íŽ˜ì´ì§€ëŠ” %{descendants} ê°œì˜ í•˜ìœ„ íŽ˜ì´ì§€ì™€ ê´€ë ¨ ë‚´ìš©ì´ ìžˆìŠµë‹ˆë‹¤. ì´ ë‚´ìš©ì„ ì–´ë–»ê²Œ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?
+  text_wiki_page_nullify_children: í•˜ìœ„ íŽ˜ì´ì§€ë¥¼ ìµœìƒìœ„ íŽ˜ì´ì§€ ì•„ëž˜ë¡œ ì§€ì •
+  text_wiki_page_destroy_children: ëª¨ë“  í•˜ìœ„ íŽ˜ì´ì§€ì™€ ê´€ë ¨ ë‚´ìš©ì„ ì‚­ì œ
+  text_wiki_page_reassign_children: í•˜ìœ„ íŽ˜ì´ì§€ë¥¼ ì´ íŽ˜ì´ì§€ ì•„ëž˜ë¡œ ì§€ì •
+
+  default_role_manager: ê´€ë¦¬ìž
+  default_role_developer: ê°œë°œìž
+  default_role_reporter: ë³´ê³ ìž
+  default_tracker_bug: ê²°í•¨
+  default_tracker_feature: ìƒˆê¸°ëŠ¥
+  default_tracker_support: ì§€ì›
+  default_issue_status_new: ì‹ ê·œ
+  default_issue_status_in_progress: ì§„í–‰
+  default_issue_status_resolved: í•´ê²°
+  default_issue_status_feedback: ì˜ê²¬
+  default_issue_status_closed: ì™„ë£Œ
+  default_issue_status_rejected: ê±°ì ˆ
+  default_doc_category_user: ì‚¬ìš©ìž ë¬¸ì„œ
+  default_doc_category_tech: ê¸°ìˆ  ë¬¸ì„œ
+  default_priority_low: ë‚®ìŒ
+  default_priority_normal: ë³´í†µ
+  default_priority_high: ë†’ìŒ
+  default_priority_urgent: ê¸´ê¸‰
+  default_priority_immediate: ì¦‰ì‹œ
+  default_activity_design: ì„¤ê³„
+  default_activity_development: ê°œë°œ
+
+  enumeration_issue_priorities: ì¼ê° ìš°ì„ ìˆœìœ„
+  enumeration_doc_categories: ë¬¸ì„œ ë²”ì£¼
+  enumeration_activities: ìž‘ì—…ë¶„ë¥˜(ì‹œê°„ì¶”ì )
+
+  field_issue_to: ê´€ë ¨ ì¼ê° 
+  label_view_all_revisions: ëª¨ë“  ê°œì •íŒ í‘œì‹œ
+  label_tag: íƒœê·¸(Tag)
+  label_branch: ë¸Œëžœì¹˜(Branch)
+  error_no_tracker_in_project: ì‚¬ìš©í•  ìˆ˜ ìžˆë„ë¡ ì„¤ì •ëœ ì¼ê° ìœ í˜•ì´ ì—†ìŠµë‹ˆë‹¤. í”„ë¡œì íŠ¸ ì„¤ì •ì„ í™•ì¸í•˜ì‹­ì‹œì˜¤.
+  error_no_default_issue_status: 'ê¸°ë³¸ ìƒíƒœê°€ ì •í•´ì ¸ ìžˆì§€ ì•ŠìŠµë‹ˆë‹¤. ì„¤ì •ì„ í™•ì¸í•˜ì‹­ì‹œì˜¤. (ì£¼ ë©”ë‰´ì˜ "ê´€ë¦¬" -> "ì¼ê° ìƒíƒœ")'
+  text_journal_changed: "%{label}ì„(ë¥¼) %{old}ì—ì„œ %{new}(ìœ¼)ë¡œ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
+  text_journal_set_to: "%{label}ì„(ë¥¼) %{value}(ìœ¼)ë¡œ ì§€ì •ë˜ì—ˆìŠµë‹ˆë‹¤."
+  text_journal_deleted: "%{label} ê°’ì´ ì§€ì›Œì¡ŒìŠµë‹ˆë‹¤. (%{old})"
+  label_group_plural: ê·¸ë£¹
+  label_group: ê·¸ë£¹
+  label_group_new: ìƒˆ ê·¸ë£¹
+  label_time_entry_plural: ìž‘ì—…ì‹œê°„
+  text_journal_added: "%{label}ì— %{value}ì´(ê°€) ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
+  field_active: ì‚¬ìš©ì¤‘
+  enumeration_system_activity: ì‹œìŠ¤í…œ ìž‘ì—…
+  permission_delete_issue_watchers: ì¼ê°ê´€ëžŒìž ì§€ìš°ê¸°
+  version_status_closed: ë‹«íž˜
+  version_status_locked: ìž ê¹€
+  version_status_open: ì§„í–‰
+  error_can_not_reopen_issue_on_closed_version: ë‹«ížŒ ë²„ì „ì— í• ë‹¹ëœ ì¼ê°ì€ ë‹¤ì‹œ ìž¬ë°œìƒì‹œí‚¬ ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
+  label_user_anonymous: ì´ë¦„ì—†ìŒ
+  button_move_and_follow: ì´ë™í•˜ê³  ë”°ë¼ê°€ê¸°
+  setting_default_projects_modules: ìƒˆ í”„ë¡œì íŠ¸ì— ê¸°ë³¸ì ìœ¼ë¡œ í™œì„±í™”ë  ëª¨ë“ˆ
+  setting_gravatar_default: ê¸°ë³¸ ê·¸ë¼ë°”íƒ€ ì´ë¯¸ì§€
+  field_sharing: ê³µìœ 
+  label_version_sharing_hierarchy: ìƒìœ„ ë° í•˜ìœ„ í”„ë¡œì íŠ¸
+  label_version_sharing_system: ëª¨ë“  í”„ë¡œì íŠ¸
+  label_version_sharing_descendants: í•˜ìœ„ í”„ë¡œì íŠ¸
+  label_version_sharing_tree: ìµœìƒìœ„ ë° ëª¨ë“  í•˜ìœ„ í”„ë¡œì íŠ¸
+  label_version_sharing_none: ê³µìœ ì—†ìŒ
+  error_can_not_archive_project: ì´ í”„ë¡œì íŠ¸ë¥¼ ìž ê¸ˆë³´ê´€í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
+  button_duplicate: ë³µì œ
+  button_copy_and_follow: ë³µì‚¬í•˜ê³  ë”°ë¼ê°€ê¸°
+  label_copy_source: ì›ë³¸
+  setting_issue_done_ratio: ì¼ê°ì˜ ì§„ì²™ë„ ê³„ì‚°ë°©ë²•
+  setting_issue_done_ratio_issue_status: ì¼ê° ìƒíƒœë¥¼ ì‚¬ìš©í•˜ê¸°
+  error_issue_done_ratios_not_updated: ì¼ê° ì§„ì²™ë„ê°€ ìˆ˜ì •ë˜ì§€ ì•Šì•˜ìŠµë‹ˆë‹¤.
+  error_workflow_copy_target: ëŒ€ìƒ ì¼ê°ì˜ ìœ í˜•ê³¼ ì—­í• ì„ ì„ íƒí•˜ì„¸ìš”.
+  setting_issue_done_ratio_issue_field: ì¼ê° ìˆ˜ì •ì—ì„œ ì§„ì²™ë„ ìž…ë ¥í•˜ê¸°
+  label_copy_same_as_target: ëŒ€ìƒê³¼ ê°™ìŒ.
+  label_copy_target: ëŒ€ìƒ
+  notice_issue_done_ratios_updated: ì¼ê° ì§„ì²™ë„ê°€ ìˆ˜ì •ë˜ì—ˆìŠµë‹ˆë‹¤.
+  error_workflow_copy_source: ì›ë³¸ ì¼ê°ì˜ ìœ í˜•ì´ë‚˜ ì—­í• ì„ ì„ íƒí•˜ì„¸ìš”.
+  label_update_issue_done_ratios: ëª¨ë“  ì¼ê° ì§„ì²™ë„ ê°±ì‹ í•˜ê¸°
+  setting_start_of_week: ë‹¬ë ¥ ì‹œìž‘ ìš”ì¼
+  permission_view_issues: ì¼ê° ë³´ê¸°
+  label_display_used_statuses_only: ì´ ì¼ê° ìœ í˜•ì—ì„œ ì‚¬ìš©ë˜ëŠ” ìƒíƒœë§Œ ë³´ì—¬ì£¼ê¸°
+  label_revision_id: ê°œì •íŒ %{value}
+  label_api_access_key: API ì ‘ê·¼í‚¤
+  label_api_access_key_created_on: API ì ‘ê·¼í‚¤ê°€ %{value} ì „ì— ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤.
+  label_feeds_access_key: RSS ì ‘ê·¼í‚¤
+  notice_api_access_key_reseted: API ì ‘ê·¼í‚¤ê°€ ì´ˆê¸°í™”ë˜ì—ˆìŠµë‹ˆë‹¤.
+  setting_rest_api_enabled: REST ì›¹ì„œë¹„ìŠ¤ í™œì„±í™”
+  label_missing_api_access_key: API ì ‘ê·¼í‚¤ê°€ ì—†ìŠµë‹ˆë‹¤.
+  label_missing_feeds_access_key: RSS ì ‘ê·¼í‚¤ê°€ ì—†ìŠµë‹ˆë‹¤.
+  button_show: ë³´ê¸°
+  text_line_separated: ì—¬ëŸ¬ ê°’ì´ í—ˆìš©ë¨(ê°’ ë§ˆë‹¤ í•œ ì¤„ì”©)
+  setting_mail_handler_body_delimiters: ë©”ì¼ ë³¸ë¬¸ êµ¬ë¶„ìž
+  permission_add_subprojects: í•˜ìœ„ í”„ë¡œì íŠ¸ ë§Œë“¤ê¸°
+  label_subproject_new: ìƒˆ í•˜ìœ„ í”„ë¡œì íŠ¸
+  text_own_membership_delete_confirmation: |-
+    ê¶Œí•œë“¤ ì¼ë¶€ ë˜ëŠ” ì „ë¶€ë¥¼ ë§‰ ì‚­ì œí•˜ë ¤ê³  í•˜ê³  ìžˆìŠµë‹ˆë‹¤. ê·¸ë ‡ê²Œ ë˜ë©´ ì´ í”„ë¡œì íŠ¸ë¥¼ ë”ì´ìƒ ìˆ˜ì •í•  ìˆ˜ ì—†ê²Œ ë©ë‹ˆë‹¤.
+    ê³„ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?
+  label_close_versions: ì™„ë£Œëœ ë²„ì „ ë‹«ê¸°
+  label_board_sticky: ë¶™ë°•ì´
+  label_board_locked: ìž ê¸ˆ
+  permission_export_wiki_pages: ìœ„í‚¤ íŽ˜ì´ì§€ ë‚´ë³´ë‚´ê¸°
+  setting_cache_formatted_text: í˜•ì‹ì„ ê°€ì§„ í…ìŠ¤íŠ¸ ë¹ ë¥¸ ìž„ì‹œ ê¸°ì–µ
+  permission_manage_project_activities: í”„ë¡œì íŠ¸ ìž‘ì—…ë‚´ì—­ ê´€ë¦¬
+  error_unable_delete_issue_status: ì¼ê° ìƒíƒœë¥¼ ì§€ìš¸ ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
+  label_profile: ì‚¬ìš©ìžì •ë³´
+  permission_manage_subtasks: í•˜ìœ„ ì¼ê° ê´€ë¦¬
+  field_parent_issue: ìƒìœ„ ì¼ê°
+  label_subtask_plural: í•˜ìœ„ ì¼ê°
+  label_project_copy_notifications: í”„ë¡œì íŠ¸ ë³µì‚¬ ì¤‘ì— ì´ë©”ì¼ ì•Œë¦¼ ë³´ë‚´ê¸°
+  error_can_not_delete_custom_field: ì‚¬ìš©ìž ì •ì˜ í•„ë“œë¥¼ ì‚­ì œí•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
+  error_unable_to_connect: ì—°ê²°í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤((%{value})
+  error_can_not_remove_role: ì´ ì—­í• ì€ í˜„ìž¬ ì‚¬ìš© ì¤‘ì´ì´ì„œ ì‚­ì œí•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
+  error_can_not_delete_tracker: ì´ ìœ í˜•ì˜ ì¼ê°ë“¤ì´ ìžˆì–´ì„œ ì‚­ì œí•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
+  field_principal: ì‹ ì›
+  label_my_page_block: ë‚´ íŽ˜ì´ì§€ ì¶œë ¥í™”ë©´
+  notice_failed_to_save_members: "%{errors}:êµ¬ì„±ì›ì„ ì €ìž¥ ì¤‘ ì‹¤íŒ¨í•˜ì˜€ìŠµë‹ˆë‹¤"
+  text_zoom_out: ë” ìž‘ê²Œ
+  text_zoom_in: ë” í¬ê²Œ
+  notice_unable_delete_time_entry: ì‹œê°„ ê¸°ë¡ í•­ëª©ì„ ì‚­ì œí•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
+  label_overall_spent_time: ì´ ì†Œìš”ì‹œê°„
+  field_time_entries: ê¸°ë¡ëœ ì‹œê°„
+  project_module_gantt: Gantt ì± íŠ¸
+  project_module_calendar: ë‹¬ë ¥
+  button_edit_associated_wikipage: "ì—°ê´€ëœ ìœ„í‚¤ íŽ˜ì´ì§€ %{page_title} ìˆ˜ì •"
+  field_text: í…ìŠ¤íŠ¸ ì˜ì—­
+  label_user_mail_option_only_owner: ë‚´ê°€ ì €ìžì¸ ì‚¬í•­ë§Œ
+  setting_default_notification_option: ê¸°ë³¸ ì•Œë¦¼ ì˜µì…˜
+  label_user_mail_option_only_my_events: ë‚´ê°€ ì§€ì¼œë³´ê±°ë‚˜ ì†í•´ìžˆëŠ” ì‚¬í•­ë§Œ
+  label_user_mail_option_only_assigned: ë‚´ì—ê²Œ í• ë‹¹ëœ ì‚¬í•­ë§Œ
+  label_user_mail_option_none: ì•Œë¦¼ ì—†ìŒ
+  field_member_of_group: í• ë‹¹ëœ ì‚¬ëžŒì˜ ê·¸ë£¹
+  field_assigned_to_role: í• ë‹¹ëœ ì‚¬ëžŒì˜ ì—­í• 
+  notice_not_authorized_archived_project: ì ‘ê·¼í•˜ë ¤ëŠ” í”„ë¡œì íŠ¸ëŠ” ì´ë¯¸ ìž ê¸ˆë³´ê´€ë˜ì–´ ìžˆìŠµë‹ˆë‹¤.
+  label_principal_search: "ì‚¬ìš©ìž ë° ê·¸ë£¹ ì°¾ê¸°:"
+  label_user_search: "ì‚¬ìš©ìž ì°¾ê¸°::"
+  field_visible: ë³´ì´ê¸°
+  setting_emails_header: ì´ë©”ì¼ í—¤ë”
+  setting_commit_logtime_activity_id: ê¸°ë¡ëœ ì‹œê°„ì— ì ìš©í•  ìž‘ì—…ë¶„ë¥˜
+  text_time_logged_by_changeset: "ë³€ê²½ë¬¶ìŒ %{value}ì—ì„œ ì ìš©ë˜ì—ˆìŠµë‹ˆë‹¤."
+  setting_commit_logtime_enabled: ì»¤ë°‹ ì‹œì ì— ìž‘ì—… ì‹œê°„ ê¸°ë¡ í™œì„±í™”
+  notice_gantt_chart_truncated: "í‘œì‹œí•  ìˆ˜ ìžˆëŠ” ìµœëŒ€ í•­ëª©ìˆ˜(%{max})ë¥¼ ì´ˆê³¼í•˜ì—¬ ì°¨íŠ¸ê°€ ìž˜ë ¸ìŠµë‹ˆë‹¤."
+  setting_gantt_items_limit: "Gantt ì°¨íŠ¸ì— í‘œì‹œë˜ëŠ” ìµœëŒ€ í•­ëª©ìˆ˜"
+  field_warn_on_leaving_unsaved: "ì €ìž¥í•˜ì§€ ì•Šì€ íŽ˜ì´ì§€ë¥¼ ë¹ ì ¸ë‚˜ê°ˆ ë•Œ ë‚˜ì—ê²Œ ì•Œë¦¼"
+  text_warn_on_leaving_unsaved: "í˜„ìž¬ íŽ˜ì´ì§€ëŠ” ì €ìž¥ë˜ì§€ ì•Šì€ ë¬¸ìžê°€ ìžˆìŠµë‹ˆë‹¤. ì´ íŽ˜ì´ì§€ë¥¼ ë¹ ì ¸ë‚˜ê°€ë©´ ë‚´ìš©ì„ ìžƒì„ê²ƒìž…ë‹ˆë‹¤."
+  label_my_queries: "ë‚´ ê²€ìƒ‰ ì–‘ì‹"
+  text_journal_changed_no_detail: "%{label}ì´ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
+  label_news_comment_added: "ë‰´ìŠ¤ì— ì„¤ëª…ì´ ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
+  button_expand_all: "ëª¨ë‘ í™•ìž¥"
+  button_collapse_all: "ëª¨ë‘ ì¶•ì†Œ"
+  label_additional_workflow_transitions_for_assignee: "ì‚¬ìš©ìžê°€ ìž‘ì—…ìžì¼ ë•Œ í—ˆìš©ë˜ëŠ” ì¶”ê°€ ìƒíƒœ"
+  label_additional_workflow_transitions_for_author: "ì‚¬ìš©ìžê°€ ì €ìžì¼ ë•Œ í—ˆìš©ë˜ëŠ” ì¶”ê°€ ìƒíƒœ"
+  label_bulk_edit_selected_time_entries: "ì„ íƒëœ ì†Œìš” ì‹œê°„ ëŒ€ëŸ‰ íŽ¸ì§‘"
+  text_time_entries_destroy_confirmation: "ì„ íƒí•œ ì†Œìš” ì‹œê°„ í•­ëª©ì„ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+
+  label_issue_note_added: "ë§ê¸€ì´ ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
+  label_issue_status_updated: "ìƒíƒœê°€ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
+  label_issue_priority_updated: "ìš°ì„  ìˆœìœ„ê°€ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤."
+  label_issues_visibility_own: "ì¼ê°ì„ ìƒì„±í•˜ê±°ë‚˜ ë§¡ì€ ì‚¬ìš©ìž"
+  field_issues_visibility: "ì¼ê° ë³´ìž„"
+  label_issues_visibility_all: "ëª¨ë“  ì¼ê°"
+  permission_set_own_issues_private: "ìžì‹ ì˜ ì¼ê°ì„ ê³µê°œë‚˜ ë¹„ê³µê°œë¡œ ì„¤ì •"
+  field_is_private: "ë¹„ê³µê°œ"
+  permission_set_issues_private: "ì¼ê°ì„ ê³µê°œë‚˜ ë¹„ê³µê°œë¡œ ì„¤ì •"
+  label_issues_visibility_public: "ë¹„ê³µê°œ ì¼ê° ì œì™¸"
+  text_issues_destroy_descendants_confirmation: "%{count} ê°œì˜ í•˜ìœ„ ì¼ê°ì„ ì‚­ì œí•  ê²ƒìž…ë‹ˆë‹¤."
+  field_commit_logs_encoding: "ì»¤ë°‹(commit) ê¸°ë¡ ì¸ì½”ë”©"
+  field_scm_path_encoding: "ê²½ë¡œ ì¸ì½”ë”©"
+  text_scm_path_encoding_note: "ê¸°ë³¸: UTF-8"
+  field_path_to_repository: "ì €ìž¥ì†Œ ê²½ë¡œ"
+  field_root_directory: "ë£¨íŠ¸ ê²½ë¡œ"
+  field_cvs_module: "ëª¨ë“ˆ"
+  field_cvsroot: "CVS ë£¨íŠ¸"
+  text_mercurial_repository_note: "ë¡œì»¬ ì €ìž¥ì†Œ (ì˜ˆ: /hgrepo, c:\\hgrepo)"
+  text_scm_command: "ëª…ë ¹"
+  text_scm_command_version: "ë²„ì „"
+  label_git_report_last_commit: "íŒŒì¼ì´ë‚˜ í´ë”ì˜ ë§ˆì§€ë§‰ ì»¤ë°‹(commit)ì„ ë³´ê³ "
+  text_scm_config: "SCM ëª…ë ¹ì„ config/configuration.ymlì—ì„œ ìˆ˜ì •í•  ìˆ˜ ìžˆìŠµë‹ˆë‹¤. ìˆ˜ì •í›„ì—ëŠ” ìž¬ì‹œìž‘í•˜ì‹­ì‹œì˜¤."
+  text_scm_command_not_available: "SCM ëª…ë ¹ì„ ì‚¬ìš©í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤. ê´€ë¦¬ íŽ˜ì´ì§€ì˜ ì„¤ì •ì„ ê²€ì‚¬í•˜ì‹­ì‹œì˜¤."
+  notice_issue_successful_create: "%{id} ì¼ê°ì´ ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤."
+  label_between: "ì‚¬ì´"
+  setting_issue_group_assignment: "ê·¸ë£¹ì— ì¼ê° í• ë‹¹ í—ˆìš©"
+  label_diff: "ë¹„êµ(diff)"
+  text_git_repository_note: "ë¡œì»¬ì˜ bare ì €ìž¥ì†Œ (ì˜ˆ: /gitrepo, c:\\gitrepo)"
+  description_query_sort_criteria_direction: "ì •ë ¬ ë°©í–¥"
+  description_project_scope: "ê²€ìƒ‰ ë²”ìœ„"
+  description_filter: "ê²€ìƒ‰ ì¡°ê±´"
+  description_user_mail_notification: "ë©”ì¼ ì•Œë¦¼ ì„¤ì •"
+  description_date_from: "ì‹œìž‘ ë‚ ì§œ ìž…ë ¥"
+  description_message_content: "ë©”ì„¸ì§€ ë‚´ìš©"
+  description_available_columns: "ê°€ëŠ¥í•œ ì»¬ëŸ¼"
+  description_date_range_interval: "ì‹œìž‘ê³¼ ë ë‚ ì§œë¡œ ë²”ìœ„ë¥¼ ì„ íƒí•˜ì‹­ì‹œì˜¤."
+  description_issue_category_reassign: "ì¼ê° ë²”ì£¼ë¥¼ ì„ íƒí•˜ì‹­ì‹œì˜¤."
+  description_search: "ê²€ìƒ‰í•­ëª©"
+  description_notes: "ë§ê¸€"
+  description_date_range_list: "ëª©ë¡ì—ì„œ ë²”ìœ„ë¥¼ ì„ íƒ í•˜ì‹­ì‹œì˜¤."
+  description_choose_project: "í”„ë¡œì íŠ¸"
+  description_date_to: "ì¢…ë£Œ ë‚ ì§œ ìž…ë ¥"
+  description_query_sort_criteria_attribute: "ì •ë ¬ ì†ì„±"
+  description_wiki_subpages_reassign: "ìƒˆë¡œìš´ ìƒìœ„ íŽ˜ì´ì§€ë¥¼ ì„ íƒí•˜ì‹­ì‹œì˜¤."
+  description_selected_columns: "ì„ íƒëœ ì»¬ëŸ¼"
+  label_parent_revision: "ìƒìœ„"
+  label_child_revision: "í•˜ìœ„"
+  error_scm_annotate_big_text_file: "ìµœëŒ€ í…ìŠ¤íŠ¸ íŒŒì¼ í¬ê¸°ë¥¼ ì´ˆê³¼ í•˜ë©´ í•­ëª©ì€ ì´ë ¥í™” ë  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
+  setting_default_issue_start_date_to_creation_date: "ìƒˆë¡œìš´ ì¼ê°ì˜ ì‹œìž‘ ë‚ ì§œë¡œ ì˜¤ëŠ˜ ë‚ ì§œ ì‚¬ìš©"
+  button_edit_section: "ì´ ë¶€ë¶„ ìˆ˜ì •"
+  setting_repositories_encodings: "ì²¨ë¶€íŒŒì¼ì´ë‚˜ ì €ìž¥ì†Œ ì¸ì½”ë”©"
+  description_all_columns: "ëª¨ë“  ì»¬ëŸ¼"
+  button_export: "ë‚´ë³´ë‚´ê¸°"
+  label_export_options: "ë‚´ë³´ë‚´ê¸° ì˜µì…˜: %{export_format}"
+  error_attachment_too_big: "ì´ íŒŒì¼ì€ ì œí•œëœ í¬ê¸°(%{max_size})ë¥¼ ì´ˆê³¼í•˜ì˜€ê¸° ë•Œë¬¸ì— ì—…ë¡œë“œ í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
+
+  notice_failed_to_save_time_entries: "%{total} ê°œì˜ ì‹œê°„ìž…ë ¥ì¤‘ ë‹¤ìŒ %{count} ê°œì˜ ì €ìž¥ì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤:: %{ids}."
+  label_x_issues:
+    zero:  0 ì¼ê°
+    one:   1 ì¼ê° 
+    other: "%{count} ì¼ê°"
+  label_repository_new: ì €ìž¥ì†Œ ì¶”ê°€
+  field_repository_is_default: ì£¼ ì €ìž¥ì†Œ
+  label_copy_attachments: ì²¨ë¶€íŒŒì¼ ë³µì‚¬
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: ì™„ë£Œ ë²„ì „
+  text_project_identifier_info: "ì†Œë¬¸ìž(a-z),ìˆ«ìž,ëŒ€ì‰¬(-)ì™€ ë°‘ì¤„(_)ë§Œ ê°€ëŠ¥í•©ë‹ˆë‹¤.<br />ì‹ë³„ìžëŠ” ì €ìž¥í›„ì—ëŠ” ìˆ˜ì •í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
+  field_multiple: ë³µìˆ˜ì„ íƒê°€ëŠ¥
+  setting_commit_cross_project_ref: ë‹¤ë¥¸ í”„ë¡œì íŠ¸ì˜ ì¼ê° ì°¸ì¡° ë° ìˆ˜ì • í—ˆìš©
+  text_issue_conflict_resolution_add_notes: ë³€ê²½ë‚´ìš©ì€ ì·¨ì†Œí•˜ê³  ë§ê¸€ë§Œ ì¶”ê°€
+  text_issue_conflict_resolution_overwrite: ë³€ê²½ë‚´ìš© ê°•ì œì ìš© (ì´ì „ ë§ê¸€ì„ ì œì™¸í•˜ê³  ë®ì–´ ì”ë‹ˆë‹¤)
+  notice_issue_update_conflict: ì¼ê°ì´ ìˆ˜ì •ë˜ëŠ” ë™ì•ˆ ë‹¤ë¥¸ ì‚¬ìš©ìžì— ì˜í•´ì„œ ë³€ê²½ë˜ì—ˆìŠµë‹ˆë‹¤.
+  text_issue_conflict_resolution_cancel: "ë³€ê²½ë‚´ìš©ì„ ë˜ëŒë¦¬ê³  ë‹¤ì‹œ í‘œì‹œ %{link}"
+  permission_manage_related_issues: ì—°ê²°ëœ ì¼ê° ê´€ë¦¬
+  field_auth_source_ldap_filter: LDAP í•„í„°
+  label_search_for_watchers: ì¶”ê°€í•  ì¼ê°ê´€ëžŒìž ê²€ìƒ‰
+  notice_account_deleted: ë‹¹ì‹ ì˜ ê³„ì •ì´ ì™„ì „ížˆ ì‚­ì œë˜ì—ˆìŠµë‹ˆë‹¤.
+  setting_unsubscribe: ì‚¬ìš©ìžë“¤ì´ ìžì‹ ì˜ ê³„ì •ì„ ì‚­ì œí† ë¡ í—ˆìš©
+  button_delete_my_account: ë‚˜ì˜ ê³„ì • ì‚­ì œ
+  text_account_destroy_confirmation: |-
+        ê³„ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?
+        ê³„ì •ì´ ì‚­ì œë˜ë©´ ë³µêµ¬í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤.
+  error_session_expired: ë‹¹ì‹ ì˜ ì„¸ì…˜ì´ ë§Œë£Œë˜ì—ˆìŠµë‹ˆë‹¤. ë‹¤ì‹œ ë¡œê·¸ì¸í•˜ì„¸ìš”.
+  text_session_expiration_settings: "ê²½ê³ : ì´ ì„¤ì •ì„ ë°”ê¾¸ë©´ ë‹¹ì‹ ì„ í¬í•¨í•˜ì—¬ í˜„ìž¬ì˜ ì„¸ì…˜ë“¤ì„ ë§Œë£Œì‹œí‚¬ ìˆ˜ ìžˆìŠµë‹ˆë‹¤."
+  setting_session_lifetime: ì„¸ì…˜ ìµœëŒ€ ì‹œê°„
+  setting_session_timeout: ì„¸ì…˜ ë¹„í™œì„±í™” íƒ€ìž„ì•„ì›ƒ
+  label_session_expiration: ì„¸ì…˜ ë§Œë£Œ
+  permission_close_project: í”„ë¡œì íŠ¸ë¥¼ ë‹«ê±°ë‚˜ ë‹¤ì‹œ ì—´ê¸°
+  label_show_closed_projects: ë‹«ížŒ í”„ë¡œì íŠ¸ ë³´ê¸°
+  button_close: ë‹«ê¸°
+  button_reopen: ë‹¤ì‹œ ì—´ê¸°
+  project_status_active: ì‚¬ìš©ì¤‘
+  project_status_closed: ë‹«íž˜
+  project_status_archived: ìž ê¸ˆë³´ê´€
+  text_project_closed: ì´ í”„ë¡œì íŠ¸ëŠ” ë‹«í˜€ ìžˆìœ¼ë©° ì½ê¸° ì „ìš©ìž…ë‹ˆë‹¤.
+  notice_user_successful_create: ì‚¬ìš©ìž %{id} ì´(ê°€) ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤.
+  field_core_fields: í‘œì¤€ í•­ëª©ë“¤
+  field_timeout: íƒ€ìž„ì•„ì›ƒ (ì´ˆ)
+  setting_thumbnails_enabled: ì²¨ë¶€íŒŒì¼ì˜ ì¸ë„¤ì¼ì„ ë³´ì—¬ì¤Œ
+  setting_thumbnails_size: ì¸ë„¤ì¼ í¬ê¸° (í”½ì…€)
+  label_status_transitions: ì¼ê° ìƒíƒœ ë³€ê²½
+  label_fields_permissions: í•­ëª© íŽ¸ì§‘ ê¶Œí•œ
+  label_readonly: ì½ê¸° ì „ìš©
+  label_required: í•„ìˆ˜
+  text_repository_identifier_info: "ì†Œë¬¸ìž(a-z),ìˆ«ìž,ëŒ€ì‰¬(-)ì™€ ë°‘ì¤„(_)ë§Œ ê°€ëŠ¥í•©ë‹ˆë‹¤.<br />ì‹ë³„ìžëŠ” ì €ìž¥í›„ì—ëŠ” ìˆ˜ì •í•  ìˆ˜ ì—†ìŠµë‹ˆë‹¤."
+  field_board_parent: Parent forum
+  label_attribute_of_project: "í”„ë¡œì íŠ¸ì˜ %{name}"
+  label_attribute_of_author: "ì €ìžì˜ %{name}"
+  label_attribute_of_assigned_to: "ë‹´ë‹¹ìžì˜ %{name}"
+  label_attribute_of_fixed_version: "ëª©í‘œë²„ì „ì˜ %{name}"
+  label_copy_subtasks: í•˜ìœ„ ì¼ê°ë“¤ì„ ë³µì‚¬
+  label_copied_to: "ë‹¤ìŒ ì¼ê°ìœ¼ë¡œ ë³µì‚¬ë¨:"
+  label_copied_from: "ë‹¤ìŒ ì¼ê°ìœ¼ë¡œë¶€í„° ë³µì‚¬ë¨:"
+  label_any_issues_in_project: ë‹¤ìŒ í”„ë¡œì íŠ¸ì— ì†í•œ ì•„ë¬´ ì¼ê°
+  label_any_issues_not_in_project: ë‹¤ìŒ í”„ë¡œì íŠ¸ì— ì†í•˜ì§€ ì•Šì€ ì•„ë¬´ ì¼ê°
+  field_private_notes: ë¹„ê³µê°œ ë§ê¸€
+  permission_view_private_notes: ë¹„ê³µê°œ ë§ê¸€ ë³´ê¸°
+  permission_set_notes_private: ë§ê¸€ì„ ë¹„ê³µê°œë¡œ ì„¤ì •
+  label_no_issues_in_project: ë‹¤ìŒ í”„ë¡œì íŠ¸ì˜ ì¼ê° ì œì™¸
+  label_any: ëª¨ë‘
+  label_last_n_weeks: ìµœê·¼ %{count} ì£¼
+  setting_cross_project_subtasks: ë‹¤ë¥¸ í”„ë¡œì íŠ¸ì˜ ì¼ê°ì„ ìƒìœ„ ì¼ê°ìœ¼ë¡œ ì§€ì •í•˜ëŠ” ê²ƒì„ í—ˆìš©
+  label_cross_project_descendants: í•˜ìœ„ í”„ë¡œì íŠ¸
+  label_cross_project_tree: ìµœìƒìœ„ ë° ëª¨ë“  í•˜ìœ„ í”„ë¡œì íŠ¸
+  label_cross_project_hierarchy: ìƒìœ„ ë° í•˜ìœ„ í”„ë¡œì íŠ¸
+  label_cross_project_system: ëª¨ë“  í”„ë¡œì íŠ¸
+  button_hide: ìˆ¨ê¸°ê¸°
+  setting_non_working_week_days: ë¹„ê·¼ë¬´ì¼ (non-working days)
+  label_in_the_next_days: ë‹¤ìŒ
+  label_in_the_past_days: ì§€ë‚œ
+  label_attribute_of_user: "ì‚¬ìš©ìžì˜ %{name}"
+  text_turning_multiple_off: ë³µìˆ˜ì„ íƒì„ ë¹„í™œì„±í™”í•˜ë©´, í•˜ë‚˜ì˜ ê°’ì„ ì œì™¸í•œ ë‚˜ë¨¸ì§€ ê°’ë“¤ì´ ì§€ì›Œì§‘ë‹ˆë‹¤.
+  label_attribute_of_issue: "ì¼ê°ì˜ %{name}"
+  permission_add_documents: ë¬¸ì„œ ì¶”ê°€
+  permission_edit_documents: ë¬¸ì„œ íŽ¸ì§‘
+  permission_delete_documents: ë¬¸ì„œ ì‚­ì œ
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: JSONP í—ˆìš©
+  field_inherit_members: ìƒìœ„ í”„ë¡œì íŠ¸ë¡œë¶€í„° êµ¬ì„±ì›ì„ ìƒì†
+  field_closed_on: ì™„ë£Œì¼
+  setting_default_projects_tracker_ids: ìƒˆ í”„ë¡œì íŠ¸ì— ê¸°ë³¸ì ìœ¼ë¡œ ì¶”ê°€í•  ì¼ê° ìœ í˜•
+  label_total_time: í•©ê³„
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8d/8d137ddbd4cf6f8f24fe80f23c9c81f3f5e0f6a8.svn-base
--- a/.svn/pristine/8d/8d137ddbd4cf6f8f24fe80f23c9c81f3f5e0f6a8.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Themes
-
-    # Return an array of installed themes
-    def self.themes
-      @@installed_themes ||= scan_themes
-    end
-
-    # Rescan themes directory
-    def self.rescan
-      @@installed_themes = scan_themes
-    end
-
-    # Return theme for given id, or nil if it's not found
-    def self.theme(id, options={})
-      return nil if id.blank?
-
-      found = themes.find {|t| t.id == id}
-      if found.nil? && options[:rescan] != false
-        rescan
-        found = theme(id, :rescan => false)
-      end
-      found
-    end
-
-    # Class used to represent a theme
-    class Theme
-      attr_reader :path, :name, :dir
-
-      def initialize(path)
-        @path = path
-        @dir = File.basename(path)
-        @name = @dir.humanize
-        @stylesheets = nil
-        @javascripts = nil
-      end
-
-      # Directory name used as the theme id
-      def id; dir end
-
-      def ==(theme)
-        theme.is_a?(Theme) && theme.dir == dir
-      end
-
-      def <=>(theme)
-        name <=> theme.name
-      end
-
-      def stylesheets
-        @stylesheets ||= assets("stylesheets", "css")
-      end
-
-      def javascripts
-        @javascripts ||= assets("javascripts", "js")
-      end
-
-      def stylesheet_path(source)
-        "/themes/#{dir}/stylesheets/#{source}"
-      end
-
-      def javascript_path(source)
-        "/themes/#{dir}/javascripts/#{source}"
-      end
-
-      private
-
-      def assets(dir, ext)
-        Dir.glob("#{path}/#{dir}/*.#{ext}").collect {|f| File.basename(f).gsub(/\.#{ext}$/, '')}
-      end
-    end
-
-    private
-
-    def self.scan_themes
-      dirs = Dir.glob("#{Rails.public_path}/themes/*").select do |f|
-        # A theme should at least override application.css
-        File.directory?(f) && File.exist?("#{f}/stylesheets/application.css")
-      end
-      dirs.collect {|dir| Theme.new(dir)}.sort
-    end
-  end
-end
-
-module ApplicationHelper
-  def current_theme
-    unless instance_variable_defined?(:@current_theme)
-      @current_theme = Redmine::Themes.theme(Setting.ui_theme)
-    end
-    @current_theme
-  end
-
-  def stylesheet_path(source)
-    if current_theme && current_theme.stylesheets.include?(source)
-      super current_theme.stylesheet_path(source)
-    else
-      super
-    end
-  end
-
-  def path_to_stylesheet(source)
-    stylesheet_path source
-  end
-
-  # Returns the header tags for the current theme
-  def heads_for_theme
-    if current_theme && current_theme.javascripts.include?('theme')
-      javascript_include_tag current_theme.javascript_path('theme')
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8d/8d16ae55d2f1c008a010086c27548d8733c4f49f.svn-base
--- a/.svn/pristine/8d/8d16ae55d2f1c008a010086c27548d8733c4f49f.svn-base
+++ /dev/null
@@ -1,82 +0,0 @@
-var NS4 = (navigator.appName == "Netscape" && parseInt(navigator.appVersion) < 5);
-
-function addOption(theSel, theText, theValue)
-{
-  var newOpt = new Option(theText, theValue);
-  var selLength = theSel.length;
-  theSel.options[selLength] = newOpt;
-}
-
-function swapOptions(theSel, index1, index2)
-{
-	var text, value;
-  text = theSel.options[index1].text;
-  value = theSel.options[index1].value;
-  theSel.options[index1].text = theSel.options[index2].text;
-  theSel.options[index1].value = theSel.options[index2].value;
-  theSel.options[index2].text = text;
-  theSel.options[index2].value = value;
-}
-
-function deleteOption(theSel, theIndex)
-{ 
-  var selLength = theSel.length;
-  if(selLength>0)
-  {
-    theSel.options[theIndex] = null;
-  }
-}
-
-function moveOptions(theSelFrom, theSelTo)
-{
-  
-  var selLength = theSelFrom.length;
-  var selectedText = new Array();
-  var selectedValues = new Array();
-  var selectedCount = 0;
-  
-  var i;
-  
-  for(i=selLength-1; i>=0; i--)
-  {
-    if(theSelFrom.options[i].selected)
-    {
-      selectedText[selectedCount] = theSelFrom.options[i].text;
-      selectedValues[selectedCount] = theSelFrom.options[i].value;
-      deleteOption(theSelFrom, i);
-      selectedCount++;
-    }
-  }
-  
-  for(i=selectedCount-1; i>=0; i--)
-  {
-    addOption(theSelTo, selectedText[i], selectedValues[i]);
-  }
-  
-  if(NS4) history.go(0);
-}
-
-function moveOptionUp(theSel) {
-	var index = theSel.selectedIndex;
-	if (index > 0) {
-		swapOptions(theSel, index-1, index);
-  	theSel.selectedIndex = index-1;
-	}
-}
-
-function moveOptionDown(theSel) {
-	var index = theSel.selectedIndex;
-	if (index < theSel.length - 1) {
-		swapOptions(theSel, index, index+1);
-  	theSel.selectedIndex = index+1;
-	}
-}
-
-function selectAllOptions(id)
-{
-  var select = $(id);
-  for (var i=0; i<select.options.length; i++) {
-    select.options[i].selected = true;
-  }
-}
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8d/8d38ea6537066d667e6cd4ba48775a84cbef2093.svn-base
--- a/.svn/pristine/8d/8d38ea6537066d667e6cd4ba48775a84cbef2093.svn-base
+++ /dev/null
@@ -1,998 +0,0 @@
-# Norwegian, norsk bokmÃ¥l, by irb.no
-"no":
-  support:
-    array:
-      sentence_connector: "og"
-  direction: ltr
-  date:
-    formats:
-      default: "%d.%m.%Y"
-      short: "%e. %b"
-      long: "%e. %B %Y"
-    day_names: [sÃ¸ndag, mandag, tirsdag, onsdag, torsdag, fredag, lÃ¸rdag]
-    abbr_day_names: [sÃ¸n, man, tir, ons, tor, fre, lÃ¸r]
-    month_names: [~, januar, februar, mars, april, mai, juni, juli, august, september, oktober, november, desember]
-    abbr_month_names: [~, jan, feb, mar, apr, mai, jun, jul, aug, sep, okt, nov, des]
-    order:
-      - :day
-      - :month
-      - :year
-  time:
-    formats:
-      default: "%A, %e. %B %Y, %H:%M"
-      time: "%H:%M"
-      short: "%e. %B, %H:%M"
-      long: "%A, %e. %B %Y, %H:%M"
-    am: ""
-    pm: ""
-  datetime:
-    distance_in_words:
-      half_a_minute: "et halvt minutt"
-      less_than_x_seconds:
-        one: "mindre enn 1 sekund"
-        other: "mindre enn %{count} sekunder"
-      x_seconds:
-        one: "1 sekund"
-        other: "%{count} sekunder"
-      less_than_x_minutes:
-        one: "mindre enn 1 minutt"
-        other: "mindre enn %{count} minutter"
-      x_minutes:
-        one: "1 minutt"
-        other: "%{count} minutter"
-      about_x_hours:
-        one: "rundt 1 time"
-        other: "rundt %{count} timer"
-      x_days:
-        one: "1 dag"
-        other: "%{count} dager"
-      about_x_months:
-        one: "rundt 1 mÃ¥ned"
-        other: "rundt %{count} mÃ¥neder"
-      x_months:
-        one: "1 mÃ¥ned"
-        other: "%{count} mÃ¥neder"
-      about_x_years:
-        one: "rundt 1 Ã¥r"
-        other: "rundt %{count} Ã¥r"
-      over_x_years:
-        one: "over 1 Ã¥r"
-        other: "over %{count} Ã¥r"
-      almost_x_years:
-        one:   "nesten 1 Ã¥r"
-        other: "nesten %{count} Ã¥r"
-  number:
-    format:
-      precision: 2
-      separator: "."
-      delimiter: ","
-    currency:
-      format:
-        unit: "kr"
-        format: "%n %u"
-    precision:
-      format:
-        delimiter: ""
-        precision: 4
-    human:
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  activerecord:
-    errors:
-      template:
-        header: "kunne ikke lagre %{model} pÃ¥ grunn av %{count} feil."
-        body: "det oppstod problemer i fÃ¸lgende felt:"
-      messages:
-        inclusion: "er ikke inkludert i listen"
-        exclusion: "er reservert"
-        invalid: "er ugyldig"
-        confirmation: "passer ikke bekreftelsen"
-        accepted: "mÃ¥ vÃ¦re akseptert"
-        empty: "kan ikke vÃ¦re tom"
-        blank: "kan ikke vÃ¦re blank"
-        too_long: "er for lang (maksimum %{count} tegn)"
-        too_short: "er for kort (minimum %{count} tegn)"
-        wrong_length: "er av feil lengde (maksimum %{count} tegn)"
-        taken: "er allerede i bruk"
-        not_a_number: "er ikke et tall"
-        greater_than: "mÃ¥ vÃ¦re stÃ¸rre enn %{count}"
-        greater_than_or_equal_to: "mÃ¥ vÃ¦re stÃ¸rre enn eller lik %{count}"
-        equal_to: "mÃ¥ vÃ¦re lik %{count}"
-        less_than: "mÃ¥ vÃ¦re mindre enn %{count}"
-        less_than_or_equal_to: "mÃ¥ vÃ¦re mindre enn eller lik %{count}"
-        odd: "mÃ¥ vÃ¦re oddetall"
-        even: "mÃ¥ vÃ¦re partall"
-        greater_than_start_date: "mÃ¥ vÃ¦re stÃ¸rre enn startdato"
-        not_same_project: "hÃ¸rer ikke til samme prosjekt"
-        circular_dependency: "Denne relasjonen ville lagd en sirkulÃ¦r avhengighet"
-        cant_link_an_issue_with_a_descendant: "En sak kan ikke kobles mot en av sine undersaker"
-
-
-  actionview_instancetag_blank_option: Vennligst velg
-
-  general_text_No: 'Nei'
-  general_text_Yes: 'Ja'
-  general_text_no: 'nei'
-  general_text_yes: 'ja'
-  general_lang_name: 'Norwegian (Norsk bokmÃ¥l)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: Kontoen er oppdatert.
-  notice_account_invalid_creditentials: Feil brukernavn eller passord
-  notice_account_password_updated: Passordet er oppdatert.
-  notice_account_wrong_password: Feil passord
-  notice_account_register_done: Kontoen er opprettet. Klikk lenken som er sendt deg i e-post for Ã¥ aktivere kontoen.
-  notice_account_unknown_email: Ukjent bruker.
-  notice_can_t_change_password: Denne kontoen bruker ekstern godkjenning. Passordet kan ikke endres.
-  notice_account_lost_email_sent: En e-post med instruksjoner for Ã¥ velge et nytt passord er sendt til deg.
-  notice_account_activated: Din konto er aktivert. Du kan nÃ¥ logge inn.
-  notice_successful_create: Opprettet.
-  notice_successful_update: Oppdatert.
-  notice_successful_delete: Slettet.
-  notice_successful_connection: Koblet opp.
-  notice_file_not_found: Siden du forsÃ¸kte Ã¥ vise eksisterer ikke, eller er slettet.
-  notice_locking_conflict: Data har blitt oppdatert av en annen bruker.
-  notice_not_authorized: Du har ikke adgang til denne siden.
-  notice_email_sent: "En e-post er sendt til %{value}"
-  notice_email_error: "En feil oppstod under sending av e-post (%{value})"
-  notice_feeds_access_key_reseted: Din RSS-tilgangsnÃ¸kkel er nullstilt.
-  notice_failed_to_save_issues: "Lykkes ikke Ã¥ lagre %{count} sak(er) pÃ¥ %{total} valgt: %{ids}."
-  notice_no_issue_selected: "Ingen sak valgt! Vennligst merk sakene du vil endre."
-  notice_account_pending: "Din konto ble opprettet og avventer nÃ¥ administrativ godkjenning."
-  notice_default_data_loaded: Standardkonfigurasjonen lastet inn.
-
-  error_can_t_load_default_data: "Standardkonfigurasjonen kunne ikke lastes inn: %{value}"
-  error_scm_not_found: "Elementet og/eller revisjonen eksisterer ikke i depoet."
-  error_scm_command_failed: "En feil oppstod under tilkobling til depoet: %{value}"
-  error_scm_annotate: "Elementet eksisterer ikke, eller kan ikke noteres."
-  error_issue_not_found_in_project: 'Saken eksisterer ikke, eller hÃ¸rer ikke til dette prosjektet'
-
-  mail_subject_lost_password: "Ditt %{value} passord"
-  mail_body_lost_password: 'Klikk fÃ¸lgende lenke for Ã¥ endre ditt passord:'
-  mail_subject_register: "%{value} kontoaktivering"
-  mail_body_register: 'Klikk fÃ¸lgende lenke for Ã¥ aktivere din konto:'
-  mail_body_account_information_external: "Du kan bruke din %{value}-konto for Ã¥ logge inn."
-  mail_body_account_information: Informasjon om din konto
-  mail_subject_account_activation_request: "%{value} kontoaktivering"
-  mail_body_account_activation_request: "En ny bruker (%{value}) er registrert, og avventer din godkjenning:"
-  mail_subject_reminder: "%{count} sak(er) har frist de kommende %{days} dagene"
-  mail_body_reminder: "%{count} sak(er) som er tildelt deg har frist de kommende %{days} dager:"
-
-  gui_validation_error: 1 feil
-  gui_validation_error_plural: "%{count} feil"
-
-  field_name: Navn
-  field_description: Beskrivelse
-  field_summary: Oppsummering
-  field_is_required: Kreves
-  field_firstname: Fornavn
-  field_lastname: Etternavn
-  field_mail: E-post
-  field_filename: Fil
-  field_filesize: StÃ¸rrelse
-  field_downloads: Nedlastinger
-  field_author: Forfatter
-  field_created_on: Opprettet
-  field_updated_on: Oppdatert
-  field_field_format: Format
-  field_is_for_all: For alle prosjekter
-  field_possible_values: Lovlige verdier
-  field_regexp: Regular expression
-  field_min_length: Minimum lengde
-  field_max_length: Maksimum lengde
-  field_value: Verdi
-  field_category: Kategori
-  field_title: Tittel
-  field_project: Prosjekt
-  field_issue: Sak
-  field_status: Status
-  field_notes: Notater
-  field_is_closed: Lukker saken
-  field_is_default: Standardverdi
-  field_tracker: Sakstype
-  field_subject: Emne
-  field_due_date: Frist
-  field_assigned_to: Tildelt til
-  field_priority: Prioritet
-  field_fixed_version: MÃ¥l-versjon
-  field_user: Bruker
-  field_role: Rolle
-  field_homepage: Hjemmeside
-  field_is_public: Offentlig
-  field_parent: Underprosjekt av
-  field_is_in_roadmap: Vises i veikart
-  field_login: Brukernavn
-  field_mail_notification: E-post-varsling
-  field_admin: Administrator
-  field_last_login_on: Sist innlogget
-  field_language: SprÃ¥k
-  field_effective_date: Dato
-  field_password: Passord
-  field_new_password: Nytt passord
-  field_password_confirmation: Bekreft passord
-  field_version: Versjon
-  field_type: Type
-  field_host: Vert
-  field_port: Port
-  field_account: Konto
-  field_base_dn: Base DN
-  field_attr_login: Brukernavnsattributt
-  field_attr_firstname: Fornavnsattributt
-  field_attr_lastname: Etternavnsattributt
-  field_attr_mail: E-post-attributt
-  field_onthefly: On-the-fly brukeropprettelse
-  field_start_date: Start
-  field_done_ratio: "% Ferdig"
-  field_auth_source: Autentiseringskilde
-  field_hide_mail: Skjul min epost-adresse
-  field_comments: Kommentarer
-  field_url: URL
-  field_start_page: Startside
-  field_subproject: Underprosjekt
-  field_hours: Timer
-  field_activity: Aktivitet
-  field_spent_on: Dato
-  field_identifier: Identifikasjon
-  field_is_filter: Brukes som filter
-  field_issue_to: Relaterte saker
-  field_delay: Forsinkelse
-  field_assignable: Saker kan tildeles denne rollen
-  field_redirect_existing_links: Viderekoble eksisterende lenker
-  field_estimated_hours: Estimert tid
-  field_column_names: Kolonner
-  field_time_zone: Tidssone
-  field_searchable: SÃ¸kbar
-  field_default_value: Standardverdi
-  field_comments_sorting: Vis kommentarer
-
-  setting_app_title: Applikasjonstittel
-  setting_app_subtitle: Applikasjonens undertittel
-  setting_welcome_text: Velkomsttekst
-  setting_default_language: StandardsprÃ¥k
-  setting_login_required: Krever innlogging
-  setting_self_registration: Selvregistrering
-  setting_attachment_max_size: Maks. stÃ¸rrelse vedlegg
-  setting_issues_export_limit: Eksportgrense for saker
-  setting_mail_from: Avsenders epost
-  setting_bcc_recipients: Blindkopi (bcc) til mottakere
-  setting_host_name: Vertsnavn
-  setting_text_formatting: Tekstformattering
-  setting_wiki_compression: Komprimering av Wiki-historikk
-  setting_feeds_limit: Innholdsgrense for Feed
-  setting_default_projects_public: Nye prosjekter er offentlige som standard
-  setting_autofetch_changesets: Autohenting av endringssett
-  setting_sys_api_enabled: Aktiver webservice for depot-administrasjon
-  setting_commit_ref_keywords: NÃ¸kkelord for referanse
-  setting_commit_fix_keywords: NÃ¸kkelord for retting
-  setting_autologin: Autoinnlogging
-  setting_date_format: Datoformat
-  setting_time_format: Tidsformat
-  setting_cross_project_issue_relations: Tillat saksrelasjoner pÃ¥ kryss av prosjekter
-  setting_issue_list_default_columns: Standardkolonner vist i sakslisten
-  setting_emails_footer: Epost-signatur
-  setting_protocol: Protokoll
-  setting_per_page_options: Alternativer, objekter pr. side
-  setting_user_format: Visningsformat, brukere
-  setting_activity_days_default: Dager vist pÃ¥ prosjektaktivitet
-  setting_display_subprojects_issues: Vis saker fra underprosjekter pÃ¥ hovedprosjekt som standard
-  setting_enabled_scm: Aktiviserte SCM
-
-  project_module_issue_tracking: SakshÃ¥ndtering
-  project_module_time_tracking: Tidsregistrering
-  project_module_news: Nyheter
-  project_module_documents: Dokumenter
-  project_module_files: Filer
-  project_module_wiki: Wiki
-  project_module_repository: Depot
-  project_module_boards: Forumer
-
-  label_user: Bruker
-  label_user_plural: Brukere
-  label_user_new: Ny bruker
-  label_project: Prosjekt
-  label_project_new: Nytt prosjekt
-  label_project_plural: Prosjekter
-  label_x_projects:
-    zero:  ingen prosjekter
-    one:   1 prosjekt
-    other: "%{count} prosjekter"
-  label_project_all: Alle prosjekter
-  label_project_latest: Siste prosjekter
-  label_issue: Sak
-  label_issue_new: Ny sak
-  label_issue_plural: Saker
-  label_issue_view_all: Vis alle saker
-  label_issues_by: "Saker etter %{value}"
-  label_issue_added: Sak lagt til
-  label_issue_updated: Sak oppdatert
-  label_document: Dokument
-  label_document_new: Nytt dokument
-  label_document_plural: Dokumenter
-  label_document_added: Dokument lagt til
-  label_role: Rolle
-  label_role_plural: Roller
-  label_role_new: Ny rolle
-  label_role_and_permissions: Roller og rettigheter
-  label_member: Medlem
-  label_member_new: Nytt medlem
-  label_member_plural: Medlemmer
-  label_tracker: Sakstype
-  label_tracker_plural: Sakstyper
-  label_tracker_new: Ny sakstype
-  label_workflow: Arbeidsflyt
-  label_issue_status: Saksstatus
-  label_issue_status_plural: Saksstatuser
-  label_issue_status_new: Ny status
-  label_issue_category: Sakskategori
-  label_issue_category_plural: Sakskategorier
-  label_issue_category_new: Ny kategori
-  label_custom_field: Eget felt
-  label_custom_field_plural: Egne felt
-  label_custom_field_new: Nytt eget felt
-  label_enumerations: Listeverdier
-  label_enumeration_new: Ny verdi
-  label_information: Informasjon
-  label_information_plural: Informasjon
-  label_please_login: Vennlist logg inn
-  label_register: Registrer
-  label_password_lost: Mistet passord
-  label_home: Hjem
-  label_my_page: Min side
-  label_my_account: Min konto
-  label_my_projects: Mine prosjekter
-  label_administration: Administrasjon
-  label_login: Logg inn
-  label_logout: Logg ut
-  label_help: Hjelp
-  label_reported_issues: Rapporterte saker
-  label_assigned_to_me_issues: Saker tildelt meg
-  label_last_login: Sist innlogget
-  label_registered_on: Registrert
-  label_activity: Aktivitet
-  label_overall_activity: All aktivitet
-  label_new: Ny
-  label_logged_as: Innlogget som
-  label_environment: MiljÃ¸
-  label_authentication: Autentisering
-  label_auth_source: Autentiseringskilde
-  label_auth_source_new: Ny autentiseringskilde
-  label_auth_source_plural: Autentiseringskilder
-  label_subproject_plural: Underprosjekter
-  label_and_its_subprojects: "%{value} og dets underprosjekter"
-  label_min_max_length: Min.-maks. lengde
-  label_list: Liste
-  label_date: Dato
-  label_integer: Heltall
-  label_float: Kommatall
-  label_boolean: Sann/usann
-  label_string: Tekst
-  label_text: Lang tekst
-  label_attribute: Attributt
-  label_attribute_plural: Attributter
-  label_download: "%{count} Nedlasting"
-  label_download_plural: "%{count} Nedlastinger"
-  label_no_data: Ingen data Ã¥ vise
-  label_change_status: Endre status
-  label_history: Historikk
-  label_attachment: Fil
-  label_attachment_new: Ny fil
-  label_attachment_delete: Slett fil
-  label_attachment_plural: Filer
-  label_file_added: Fil lagt til
-  label_report: Rapport
-  label_report_plural: Rapporter
-  label_news: Nyheter
-  label_news_new: Legg til nyhet
-  label_news_plural: Nyheter
-  label_news_latest: Siste nyheter
-  label_news_view_all: Vis alle nyheter
-  label_news_added: Nyhet lagt til
-  label_settings: Innstillinger
-  label_overview: Oversikt
-  label_version: Versjon
-  label_version_new: Ny versjon
-  label_version_plural: Versjoner
-  label_confirmation: Bekreftelse
-  label_export_to: Eksporter til
-  label_read: Leser...
-  label_public_projects: Offentlige prosjekt
-  label_open_issues: Ã¥pen
-  label_open_issues_plural: Ã¥pne
-  label_closed_issues: lukket
-  label_closed_issues_plural: lukkede
-  label_x_open_issues_abbr_on_total:
-    zero:  0 Ã¥pne / %{total}
-    one:   1 Ã¥pen / %{total}
-    other: "%{count} Ã¥pne / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 Ã¥pne
-    one:   1 Ã¥pen
-    other: "%{count} Ã¥pne"
-  label_x_closed_issues_abbr:
-    zero:  0 lukket
-    one:   1 lukket
-    other: "%{count} lukket"
-  label_total: Totalt
-  label_permissions: Rettigheter
-  label_current_status: NÃ¥vÃ¦rende status
-  label_new_statuses_allowed: Tillate nye statuser
-  label_all: alle
-  label_none: ingen
-  label_nobody: ingen
-  label_next: Neste
-  label_previous: Forrige
-  label_used_by: Brukt av
-  label_details: Detaljer
-  label_add_note: Legg til notat
-  label_per_page: Pr. side
-  label_calendar: Kalender
-  label_months_from: mÃ¥neder fra
-  label_gantt: Gantt
-  label_internal: Intern
-  label_last_changes: "siste %{count} endringer"
-  label_change_view_all: Vis alle endringer
-  label_personalize_page: Tilpass denne siden
-  label_comment: Kommentar
-  label_comment_plural: Kommentarer
-  label_x_comments:
-    zero: ingen kommentarer
-    one: 1 kommentar
-    other: "%{count} kommentarer"
-  label_comment_add: Legg til kommentar
-  label_comment_added: Kommentar lagt til
-  label_comment_delete: Slett kommentar
-  label_query: Egen spÃ¸rring
-  label_query_plural: Egne spÃ¸rringer
-  label_query_new: Ny spÃ¸rring
-  label_filter_add: Legg til filter
-  label_filter_plural: Filtre
-  label_equals: er
-  label_not_equals: er ikke
-  label_in_less_than: er mindre enn
-  label_in_more_than: in mer enn
-  label_in: i
-  label_today: idag
-  label_all_time: all tid
-  label_yesterday: i gÃ¥r
-  label_this_week: denne uken
-  label_last_week: sist uke
-  label_last_n_days: "siste %{count} dager"
-  label_this_month: denne mÃ¥neden
-  label_last_month: siste mÃ¥ned
-  label_this_year: dette Ã¥ret
-  label_date_range: Dato-spenn
-  label_less_than_ago: mindre enn dager siden
-  label_more_than_ago: mer enn dager siden
-  label_ago: dager siden
-  label_contains: inneholder
-  label_not_contains: ikke inneholder
-  label_day_plural: dager
-  label_repository: Depot
-  label_repository_plural: Depoter
-  label_browse: Utforsk
-  label_modification: "%{count} endring"
-  label_modification_plural: "%{count} endringer"
-  label_revision: Revisjon
-  label_revision_plural: Revisjoner
-  label_associated_revisions: Assosierte revisjoner
-  label_added: lagt til
-  label_modified: endret
-  label_deleted: slettet
-  label_latest_revision: Siste revisjon
-  label_latest_revision_plural: Siste revisjoner
-  label_view_revisions: Vis revisjoner
-  label_max_size: Maksimum stÃ¸rrelse
-  label_sort_highest: Flytt til toppen
-  label_sort_higher: Flytt opp
-  label_sort_lower: Flytt ned
-  label_sort_lowest: Flytt til bunnen
-  label_roadmap: Veikart
-  label_roadmap_due_in: "Frist om %{value}"
-  label_roadmap_overdue: "%{value} over fristen"
-  label_roadmap_no_issues: Ingen saker for denne versjonen
-  label_search: SÃ¸k
-  label_result_plural: Resultater
-  label_all_words: Alle ord
-  label_wiki: Wiki
-  label_wiki_edit: Wiki endring
-  label_wiki_edit_plural: Wiki endringer
-  label_wiki_page: Wiki-side
-  label_wiki_page_plural: Wiki-sider
-  label_index_by_title: Indekser etter tittel
-  label_index_by_date: Indekser etter dato
-  label_current_version: Gjeldende versjon
-  label_preview: ForhÃ¥ndsvis
-  label_feed_plural: Feeder
-  label_changes_details: Detaljer om alle endringer
-  label_issue_tracking: SakshÃ¥ndtering
-  label_spent_time: Brukt tid
-  label_f_hour: "%{value} time"
-  label_f_hour_plural: "%{value} timer"
-  label_time_tracking: Tidsregistrering
-  label_change_plural: Endringer
-  label_statistics: Statistikk
-  label_commits_per_month: Innsendinger pr. mÃ¥ned
-  label_commits_per_author: Innsendinger pr. forfatter
-  label_view_diff: Vis forskjeller
-  label_diff_inline: i teksten
-  label_diff_side_by_side: side ved side
-  label_options: Alternativer
-  label_copy_workflow_from: Kopier arbeidsflyt fra
-  label_permissions_report: Rettighetsrapport
-  label_watched_issues: OvervÃ¥kede saker
-  label_related_issues: Relaterte saker
-  label_applied_status: Gitt status
-  label_loading: Laster...
-  label_relation_new: Ny relasjon
-  label_relation_delete: Slett relasjon
-  label_relates_to: relatert til
-  label_duplicates: dupliserer
-  label_duplicated_by: duplisert av
-  label_blocks: blokkerer
-  label_blocked_by: blokkert av
-  label_precedes: kommer fÃ¸r
-  label_follows: fÃ¸lger
-  label_end_to_start: slutt til start
-  label_end_to_end: slutt til slutt
-  label_start_to_start: start til start
-  label_start_to_end: start til slutt
-  label_stay_logged_in: Hold meg innlogget
-  label_disabled: avslÃ¥tt
-  label_show_completed_versions: Vis ferdige versjoner
-  label_me: meg
-  label_board: Forum
-  label_board_new: Nytt forum
-  label_board_plural: Forumer
-  label_topic_plural: Emner
-  label_message_plural: Meldinger
-  label_message_last: Siste melding
-  label_message_new: Ny melding
-  label_message_posted: Melding lagt til
-  label_reply_plural: Svar
-  label_send_information: Send kontoinformasjon til brukeren
-  label_year: Ã…r
-  label_month: MÃ¥ned
-  label_week: Uke
-  label_date_from: Fra
-  label_date_to: Til
-  label_language_based: Basert pÃ¥ brukerens sprÃ¥k
-  label_sort_by: "Sorter etter %{value}"
-  label_send_test_email: Send en epost-test
-  label_feeds_access_key_created_on: "RSS tilgangsnÃ¸kkel opprettet for %{value} siden"
-  label_module_plural: Moduler
-  label_added_time_by: "Lagt til av %{author} for %{age} siden"
-  label_updated_time: "Oppdatert for %{value} siden"
-  label_jump_to_a_project: GÃ¥ til et prosjekt...
-  label_file_plural: Filer
-  label_changeset_plural: Endringssett
-  label_default_columns: Standardkolonner
-  label_no_change_option: (Ingen endring)
-  label_bulk_edit_selected_issues: Samlet endring av valgte saker
-  label_theme: Tema
-  label_default: Standard
-  label_search_titles_only: SÃ¸k bare i titler
-  label_user_mail_option_all: "For alle hendelser pÃ¥ mine prosjekter"
-  label_user_mail_option_selected: "For alle hendelser pÃ¥ valgte prosjekt..."
-  label_user_mail_no_self_notified: "Jeg vil ikke bli varslet om endringer jeg selv gjÃ¸r"
-  label_registration_activation_by_email: kontoaktivering pr. e-post
-  label_registration_manual_activation: manuell kontoaktivering
-  label_registration_automatic_activation: automatisk kontoaktivering
-  label_display_per_page: "Pr. side: %{value}"
-  label_age: Alder
-  label_change_properties: Endre egenskaper
-  label_general: Generell
-  label_more: Mer
-  label_scm: SCM
-  label_plugins: Tillegg
-  label_ldap_authentication: LDAP-autentisering
-  label_downloads_abbr: Nedl.
-  label_optional_description: Valgfri beskrivelse
-  label_add_another_file: Legg til en fil til
-  label_preferences: Brukerinnstillinger
-  label_chronological_order: I kronologisk rekkefÃ¸lge
-  label_reverse_chronological_order: I omvendt kronologisk rekkefÃ¸lge
-  label_planning: Planlegging
-
-  button_login: Logg inn
-  button_submit: Send
-  button_save: Lagre
-  button_check_all: Merk alle
-  button_uncheck_all: Avmerk alle
-  button_delete: Slett
-  button_create: Opprett
-  button_test: Test
-  button_edit: Endre
-  button_add: Legg til
-  button_change: Endre
-  button_apply: Bruk
-  button_clear: Nullstill
-  button_lock: LÃ¥s
-  button_unlock: LÃ¥s opp
-  button_download: Last ned
-  button_list: Liste
-  button_view: Vis
-  button_move: Flytt
-  button_back: Tilbake
-  button_cancel: Avbryt
-  button_activate: Aktiver
-  button_sort: Sorter
-  button_log_time: Logg tid
-  button_rollback: Rull tilbake til denne versjonen
-  button_watch: OvervÃ¥k
-  button_unwatch: Stopp overvÃ¥kning
-  button_reply: Svar
-  button_archive: Arkiver
-  button_unarchive: GjÃ¸r om arkivering
-  button_reset: Nullstill
-  button_rename: Endre navn
-  button_change_password: Endre passord
-  button_copy: Kopier
-  button_annotate: NotÃ©r
-  button_update: Oppdater
-  button_configure: Konfigurer
-
-  status_active: aktiv
-  status_registered: registrert
-  status_locked: lÃ¥st
-
-  text_select_mail_notifications: Velg hendelser som skal varsles med e-post.
-  text_regexp_info: f.eks. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 betyr ingen begrensning
-  text_project_destroy_confirmation: Er du sikker pÃ¥ at du vil slette dette prosjekter og alle relatert data ?
-  text_subprojects_destroy_warning: "Underprojekt(ene): %{value} vil ogsÃ¥ bli slettet."
-  text_workflow_edit: Velg en rolle og en sakstype for Ã¥ endre arbeidsflyten
-  text_are_you_sure: Er du sikker ?
-  text_tip_issue_begin_day: oppgaven starter denne dagen
-  text_tip_issue_end_day: oppgaven avsluttes denne dagen
-  text_tip_issue_begin_end_day: oppgaven starter og avsluttes denne dagen
-  text_project_identifier_info: 'SmÃ¥ bokstaver (a-z), nummer og bindestrek tillatt.<br />Identifikatoren kan ikke endres etter den er lagret.'
-  text_caracters_maximum: "%{count} tegn maksimum."
-  text_caracters_minimum: "MÃ¥ vÃ¦re minst %{count} tegn langt."
-  text_length_between: "Lengde mellom %{min} og %{max} tegn."
-  text_tracker_no_workflow: Ingen arbeidsflyt definert for denne sakstypen
-  text_unallowed_characters: Ugyldige tegn
-  text_comma_separated: Flere verdier tillat (kommaseparert).
-  text_issues_ref_in_commit_messages: Referering og retting av saker i innsendingsmelding
-  text_issue_added: "Sak %{id} er innrapportert av %{author}."
-  text_issue_updated: "Sak %{id} er oppdatert av %{author}."
-  text_wiki_destroy_confirmation: Er du sikker pÃ¥ at du vil slette denne wikien og alt innholdet ?
-  text_issue_category_destroy_question: "Noen saker (%{count}) er lagt til i denne kategorien. Hva vil du gjÃ¸re ?"
-  text_issue_category_destroy_assignments: Fjern bruk av kategorier
-  text_issue_category_reassign_to: OverfÃ¸r sakene til denne kategorien
-  text_user_mail_option: "For ikke-valgte prosjekter vil du bare motta varsling om ting du overvÃ¥ker eller er involveret i (eks. saker du er forfatter av eller er tildelt)."
-  text_no_configuration_data: "Roller, arbeidsflyt, sakstyper og -statuser er ikke konfigurert enda.\nDet anbefales sterkt Ã¥ laste inn standardkonfigurasjonen. Du vil kunne endre denne etter den er innlastet."
-  text_load_default_configuration: Last inn standardkonfigurasjonen
-  text_status_changed_by_changeset: "Brukt i endringssett %{value}."
-  text_issues_destroy_confirmation: 'Er du sikker pÃ¥ at du vil slette valgte sak(er) ?'
-  text_select_project_modules: 'Velg moduler du vil aktivere for dette prosjektet:'
-  text_default_administrator_account_changed: Standard administrator-konto er endret
-  text_file_repository_writable: Fil-arkivet er skrivbart
-  text_rmagick_available: RMagick er tilgjengelig (valgfritt)
-  text_destroy_time_entries_question: "%{hours} timer er fÃ¸rt pÃ¥ sakene du er i ferd med Ã¥ slette. Hva vil du gjÃ¸re ?"
-  text_destroy_time_entries: Slett fÃ¸rte timer
-  text_assign_time_entries_to_project: OverfÃ¸r fÃ¸rte timer til prosjektet
-  text_reassign_time_entries: 'OverfÃ¸r fÃ¸rte timer til denne saken:'
-  text_user_wrote: "%{value} skrev:"
-
-  default_role_manager: Leder
-  default_role_developer: Utvikler
-  default_role_reporter: RapportÃ¸r
-  default_tracker_bug: Feil
-  default_tracker_feature: Funksjon
-  default_tracker_support: Support
-  default_issue_status_new: Ny
-  default_issue_status_in_progress: PÃ¥gÃ¥r
-  default_issue_status_resolved: Avklart
-  default_issue_status_feedback: Tilbakemelding
-  default_issue_status_closed: Lukket
-  default_issue_status_rejected: Avvist
-  default_doc_category_user: Brukerdokumentasjon
-  default_doc_category_tech: Teknisk dokumentasjon
-  default_priority_low: Lav
-  default_priority_normal: Normal
-  default_priority_high: HÃ¸y
-  default_priority_urgent: Haster
-  default_priority_immediate: OmgÃ¥ende
-  default_activity_design: Design
-  default_activity_development: Utvikling
-
-  enumeration_issue_priorities: Sakssprioriteringer
-  enumeration_doc_categories: Dokumentkategorier
-  enumeration_activities: Aktiviteter (tidsregistrering)
-  text_enumeration_category_reassign_to: 'Endre dem til denne verdien:'
-  text_enumeration_destroy_question: "%{count} objekter er endret til denne verdien."
-  label_incoming_emails: Innkommende e-post
-  label_generate_key: Generer en nÃ¸kkel
-  setting_mail_handler_api_enabled: Skru pÃ¥ WS for innkommende epost
-  setting_mail_handler_api_key: API-nÃ¸kkel
-  text_email_delivery_not_configured: "Levering av epost er ikke satt opp, og varsler er skrudd av.\nStill inn din SMTP-tjener i config/configuration.yml og start programmet pÃ¥ nytt for Ã¥ skru det pÃ¥."
-  field_parent_title: Overordnet side
-  label_issue_watchers: OvervÃ¥kere
-  button_quote: Sitat
-  setting_sequential_project_identifiers: Generer sekvensielle prosjekt-IDer
-  notice_unable_delete_version: Kan ikke slette versjonen
-  label_renamed: gitt nytt navn
-  label_copied: kopiert
-  setting_plain_text_mail: kun ren tekst (ikke HTML)
-  permission_view_files: Vise filer
-  permission_edit_issues: Redigere saker
-  permission_edit_own_time_entries: Redigere egne timelister
-  permission_manage_public_queries: Administrere delte sÃ¸k
-  permission_add_issues: Legge inn saker
-  permission_log_time: LoggfÃ¸re timer
-  permission_view_changesets: Vise endringssett
-  permission_view_time_entries: Vise brukte timer
-  permission_manage_versions: Administrere versjoner
-  permission_manage_wiki: Administrere wiki
-  permission_manage_categories: Administrere kategorier for saker
-  permission_protect_wiki_pages: Beskytte wiki-sider
-  permission_comment_news: Kommentere nyheter
-  permission_delete_messages: Slette meldinger
-  permission_select_project_modules: Velge prosjektmoduler
-  permission_manage_documents: Administrere dokumenter
-  permission_edit_wiki_pages: Redigere wiki-sider
-  permission_add_issue_watchers: Legge til overvÃ¥kere
-  permission_view_gantt: Vise gantt-diagram
-  permission_move_issues: Flytte saker
-  permission_manage_issue_relations: Administrere saksrelasjoner
-  permission_delete_wiki_pages: Slette wiki-sider
-  permission_manage_boards: Administrere forum
-  permission_delete_wiki_pages_attachments: Slette vedlegg
-  permission_view_wiki_edits: Vise wiki-historie
-  permission_add_messages: Sende meldinger
-  permission_view_messages: Vise meldinger
-  permission_manage_files: Administrere filer
-  permission_edit_issue_notes: Redigere notater
-  permission_manage_news: Administrere nyheter
-  permission_view_calendar: Vise kalender
-  permission_manage_members: Administrere medlemmer
-  permission_edit_messages: Redigere meldinger
-  permission_delete_issues: Slette saker
-  permission_view_issue_watchers: Vise liste over overvÃ¥kere
-  permission_manage_repository: Administrere depot
-  permission_commit_access: Tilgang til innsending
-  permission_browse_repository: Bla gjennom depot
-  permission_view_documents: Vise dokumenter
-  permission_edit_project: Redigere prosjekt
-  permission_add_issue_notes: Legge til notater
-  permission_save_queries: Lagre sÃ¸k
-  permission_view_wiki_pages: Vise wiki
-  permission_rename_wiki_pages: Gi wiki-sider nytt navn
-  permission_edit_time_entries: Redigere timelister
-  permission_edit_own_issue_notes: Redigere egne notater
-  setting_gravatar_enabled: Bruk Gravatar-brukerikoner
-  label_example: Eksempel
-  text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
-  permission_edit_own_messages: Rediger egne meldinger
-  permission_delete_own_messages: Slett egne meldinger
-  label_user_activity: "%{value}s aktivitet"
-  label_updated_time_by: "Oppdatert av %{author} for %{age} siden"
-  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
-  setting_diff_max_lines_displayed: Max number of diff lines displayed
-  text_plugin_assets_writable: Plugin assets directory writable
-  warning_attachments_not_saved: "%{count} fil(er) kunne ikke lagres."
-  button_create_and_continue: Opprett og fortsett
-  text_custom_field_possible_values_info: 'En linje for hver verdi'
-  label_display: Visning
-  field_editable: Redigerbar
-  setting_repository_log_display_limit: Maks antall revisjoner vist i fil-loggen
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  field_watcher: OvervÃ¥ker
-  setting_openid: Tillat OpenID innlogging og registrering
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: eller logg inn med OpenID
-  field_content: Innhold
-  label_descending: Synkende
-  label_sort: Sorter
-  label_ascending: Stigende
-  label_date_from_to: Fra %{start} til %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: Denne siden har %{descendants} underside(r). Hva Ã¸nsker du Ã¥ gjÃ¸re?
-  text_wiki_page_reassign_children: Tilknytt undersider til denne overordnede siden
-  text_wiki_page_nullify_children: Behold undersider som rotsider
-  text_wiki_page_destroy_children: Slett undersider og alle deres underliggende sider
-  setting_password_min_length: Minimum passordlengde
-  field_group_by: Grupper resultater etter
-  mail_subject_wiki_content_updated: "Wiki-side '%{id}' er oppdatert"
-  label_wiki_content_added: Wiki-side opprettet
-  mail_subject_wiki_content_added: "Wiki-side '%{id}' er opprettet"
-  mail_body_wiki_content_added: Wiki-siden '%{id}' ble opprettet av %{author}.
-  label_wiki_content_updated: Wiki-side oppdatert
-  mail_body_wiki_content_updated: Wiki-siden '%{id}' ble oppdatert av %{author}.
-  permission_add_project: Opprett prosjekt
-  setting_new_project_user_role_id: Rolle gitt en ikke-administratorbruker som oppretter et prosjekt
-  label_view_all_revisions: Se alle revisjoner
-  label_tag: Tag
-  label_branch: Gren
-  error_no_tracker_in_project: Ingen sakstyper er tilknyttet dette prosjektet. Vennligst kontroller prosjektets innstillinger.
-  error_no_default_issue_status: Ingen standard saksstatus er angitt. Vennligst kontroller konfigurasjonen (GÃ¥ til "Administrasjon -> Saksstatuser").
-  text_journal_changed: "%{label} endret fra %{old} til %{new}"
-  text_journal_set_to: "%{label} satt til %{value}"
-  text_journal_deleted: "%{label} slettet (%{old})"
-  label_group_plural: Grupper
-  label_group: Gruppe
-  label_group_new: Ny gruppe
-  label_time_entry_plural: Brukt tid
-  text_journal_added: "%{label} %{value} lagt til"
-  field_active: Aktiv
-  enumeration_system_activity: Systemaktivitet
-  permission_delete_issue_watchers: Slett overvÃ¥kere
-  version_status_closed: stengt
-  version_status_locked: lÃ¥st
-  version_status_open: Ã¥pen
-  error_can_not_reopen_issue_on_closed_version: En sak tilknyttet en stengt versjon kan ikke gjenÃ¥pnes.
-  label_user_anonymous: Anonym
-  button_move_and_follow: Flytt og fÃ¸lg etter
-  setting_default_projects_modules: Standard aktiverte moduler for nye prosjekter
-  setting_gravatar_default: Standard Gravatar-bilde
-  field_sharing: Deling
-  label_version_sharing_hierarchy: Med prosjekt-hierarki
-  label_version_sharing_system: Med alle prosjekter
-  label_version_sharing_descendants: Med underprosjekter
-  label_version_sharing_tree: Med prosjekt-tre
-  label_version_sharing_none: Ikke delt
-  error_can_not_archive_project: Dette prosjektet kan ikke arkiveres
-  button_duplicate: Duplikat
-  button_copy_and_follow: Kopier og fÃ¸lg etter
-  label_copy_source: Kilde
-  setting_issue_done_ratio: Kalkuler ferdigstillingsprosent ut i fra
-  setting_issue_done_ratio_issue_status: Bruk saksstatuser
-  error_issue_done_ratios_not_updated: Ferdigstillingsprosent oppdateres ikke.
-  error_workflow_copy_target: Vennligst velg sakstype(r) og rolle(r)
-  setting_issue_done_ratio_issue_field: Bruk felt fra saker
-  label_copy_same_as_target: Samme som mÃ¥l
-  label_copy_target: MÃ¥l
-  notice_issue_done_ratios_updated: Ferdigstillingsprosent oppdatert.
-  error_workflow_copy_source: Vennligst velg en kilde-sakstype eller rolle.
-  label_update_issue_done_ratios: Oppdatert ferdigstillingsprosent
-  setting_start_of_week: Start kalender pÃ¥
-  permission_view_issues: Se pÃ¥ saker
-  label_display_used_statuses_only: Vis kun statuser som brukes av denne sakstypen
-  label_revision_id: Revision %{value}
-  label_api_access_key: API tilgangsnÃ¸kkel
-  label_api_access_key_created_on: API tilgangsnÃ¸kkel opprettet for %{value} siden
-  label_feeds_access_key: RSS tilgangsnÃ¸kkel
-  notice_api_access_key_reseted: Din API tilgangsnÃ¸kkel ble resatt.
-  setting_rest_api_enabled: Aktiver REST webservice
-  label_missing_api_access_key: Mangler en API tilgangsnÃ¸kkel
-  label_missing_feeds_access_key: Mangler en RSS tilgangsnÃ¸kkel
-  button_show: Vis
-  text_line_separated: Flere verdier er tillatt (en linje per verdi).
-  setting_mail_handler_body_delimiters: Avkort epost etter en av disse linjene
-  permission_add_subprojects: Opprett underprosjekt
-  label_subproject_new: Nytt underprosjekt
-  text_own_membership_delete_confirmation: |-
-    Du er i ferd med Ã¥ fjerne noen eller alle rettigheter og vil kanskje ikke vÃ¦re i stand til Ã¥ redigere dette prosjektet etterpÃ¥.
-    Er du sikker pÃ¥ at du vil fortsette?
-  label_close_versions: Steng fullfÃ¸rte versjoner
-  label_board_sticky: Fast
-  label_board_locked: LÃ¥st
-  permission_export_wiki_pages: Eksporter wiki-sider
-  setting_cache_formatted_text: Mellomlagre formattert tekst
-  permission_manage_project_activities: Administrere prosjektaktiviteter
-  error_unable_delete_issue_status: Kan ikke slette saksstatus
-  label_profile: Profil
-  permission_manage_subtasks: Administrere undersaker
-  field_parent_issue: Overordnet sak
-  label_subtask_plural: Undersaker
-  label_project_copy_notifications: Send epost-varslinger under prosjektkopiering
-  error_can_not_delete_custom_field: Kan ikke slette eget felt
-  error_unable_to_connect: Kunne ikke koble til (%{value})
-  error_can_not_remove_role: Denne rollen er i bruk og kan ikke slettes.
-  error_can_not_delete_tracker: Denne sakstypen inneholder saker og kan ikke slettes.
-  field_principal: Principal
-  label_my_page_block: Min side felt
-  notice_failed_to_save_members: "Feil ved lagring av medlem(mer): %{errors}."
-  text_zoom_out: Zoom ut
-  text_zoom_in: Zoom inn
-  notice_unable_delete_time_entry: Kan ikke slette oppfÃ¸ring fra timeliste.
-  label_overall_spent_time: All tidsbruk
-  field_time_entries: LoggfÃ¸r tid
-  project_module_gantt: Gantt
-  project_module_calendar: Kalender
-  button_edit_associated_wikipage: "Rediger tilhÃ¸rende Wiki-side: %{page_title}"
-  text_are_you_sure_with_children: Slett sak og alle undersaker?
-  field_text: Tekstfelt
-  label_user_mail_option_only_owner: Kun for ting jeg eier
-  setting_default_notification_option: Standardvalg for varslinger
-  label_user_mail_option_only_my_events: Kun for ting jeg overvÃ¥ker eller er involvert i
-  label_user_mail_option_only_assigned: Kun for ting jeg er tildelt
-  label_user_mail_option_none: Ingen hendelser
-  field_member_of_group: Den tildeltes gruppe
-  field_assigned_to_role: Den tildeltes rolle
-  notice_not_authorized_archived_project: Prosjektet du forsÃ¸ker Ã¥ Ã¥pne er blitt arkivert.
-  label_principal_search: "SÃ¸k etter bruker eller gruppe:"
-  label_user_search: "SÃ¸k etter bruker:"
-  field_visible: Synlig
-  setting_emails_header: Eposthode
-  setting_commit_logtime_activity_id: Aktivitet for logget tid.
-  text_time_logged_by_changeset: Lagt til i endringssett %{value}.
-  setting_commit_logtime_enabled: MuliggjÃ¸r loggfÃ¸ring av tid
-  notice_gantt_chart_truncated: Diagrammet ble avkortet fordi det overstiger det maksimale antall elementer som kan vises (%{max})
-  setting_gantt_items_limit: Maksimalt antall elementer vist pÃ¥ gantt-diagrammet
-  field_warn_on_leaving_unsaved: Vis meg en advarsel nÃ¥r jeg forlater en side med ikke lagret tekst
-  text_warn_on_leaving_unsaved: Den gjeldende siden inneholder tekst som ikke er lagret, som vil bli tapt hvis du forlater denne siden.
-  label_my_queries: Mine egne spÃ¸rringer
-  text_journal_changed_no_detail: "%{label} oppdatert"
-  label_news_comment_added: Kommentar lagt til en nyhet
-  button_expand_all: Utvid alle
-  button_collapse_all: Kollaps alle
-  label_additional_workflow_transitions_for_assignee: Ytterligere overganger tillatt nÃ¥r brukeren er sakens tildelte
-  label_additional_workflow_transitions_for_author: Ytterligere overganger tillatt nÃ¥r brukeren er den som har opprettet saken
-  label_bulk_edit_selected_time_entries: Masserediger valgte timeliste-oppfÃ¸ringer
-  text_time_entries_destroy_confirmation: Er du sikker pÃ¥ du vil slette de(n) valgte timeliste-oppfÃ¸ringen(e)?
-  label_role_anonymous: Anonym
-  label_role_non_member: Ikke medlem
-  label_issue_note_added: Notat lagt til
-  label_issue_status_updated: Status oppdatert
-  label_issue_priority_updated: Prioritet oppdatert
-  label_issues_visibility_own: Saker opprettet av eller tildelt brukeren
-  field_issues_visibility: Synlighet pÃ¥ saker
-  label_issues_visibility_all: Alle saker
-  permission_set_own_issues_private: GjÃ¸r egne saker offentlige eller private
-  field_is_private: Privat
-  permission_set_issues_private: GjÃ¸r saker offentlige eller private
-  label_issues_visibility_public: Alle ikke-private saker
-  text_issues_destroy_descendants_confirmation: Dette vil ogsÃ¥ slette %{count} undersak(er).
-  field_commit_logs_encoding: Tegnkoding for innsendingsmeldinger
-  field_scm_path_encoding: Koding av sti
-  text_scm_path_encoding_note: "Standard: UTF-8"
-  field_path_to_repository: Sti til depot
-  field_root_directory: Rotkatalog
-  field_cvs_module: Modul
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Lokalt depot (f.eks. /hgrepo, c:\hgrepo)
-  text_scm_command: Kommando
-  text_scm_command_version: Versjon
-  label_git_report_last_commit: Rapporter siste innsending for filer og kataloger
-  text_scm_config: Du kan konfigurere scm kommandoer i config/configuration.yml. Vennligst restart applikasjonen etter Ã¥ ha redigert filen.
-  text_scm_command_not_available: Scm kommando er ikke tilgjengelig. Vennligst kontroller innstillingene i administrasjonspanelet.
-
-  text_git_repository_note: Depot er bart og lokalt (f.eks. /gitrepo, c:\gitrepo)
-
-  notice_issue_successful_create: Sak %{id} opprettet.
-  label_between: mellom
-  setting_issue_group_assignment: Tillat tildeling av saker til grupper
-  label_diff: diff
-
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8d/8d49dae3dcbe3c33e8ba68468bf87f82d0d0b226.svn-base
--- /dev/null
+++ b/.svn/pristine/8d/8d49dae3dcbe3c33e8ba68468bf87f82d0d0b226.svn-base
@@ -0,0 +1,111 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class MembersControllerTest < ActionController::TestCase
+  fixtures :projects, :members, :member_roles, :roles, :users
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 2
+  end
+
+  def test_create
+    assert_difference 'Member.count' do
+      post :create, :project_id => 1, :membership => {:role_ids => [1], :user_id => 7}
+    end
+    assert_redirected_to '/projects/ecookbook/settings/members'
+    assert User.find(7).member_of?(Project.find(1))
+  end
+
+  def test_create_multiple
+    assert_difference 'Member.count', 3 do
+      post :create, :project_id => 1, :membership => {:role_ids => [1], :user_ids => [7, 8, 9]}
+    end
+    assert_redirected_to '/projects/ecookbook/settings/members'
+    assert User.find(7).member_of?(Project.find(1))
+  end
+
+  def test_xhr_create
+    assert_difference 'Member.count', 3 do
+      xhr :post, :create, :project_id => 1, :membership => {:role_ids => [1], :user_ids => [7, 8, 9]}
+      assert_response :success
+      assert_template 'create'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert User.find(7).member_of?(Project.find(1))
+    assert User.find(8).member_of?(Project.find(1))
+    assert User.find(9).member_of?(Project.find(1))
+    assert_include 'tab-content-members', response.body
+  end
+
+  def test_xhr_create_with_failure
+    assert_no_difference 'Member.count' do
+      xhr :post, :create, :project_id => 1, :membership => {:role_ids => [], :user_ids => [7, 8, 9]}
+      assert_response :success
+      assert_template 'create'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_match /alert/, response.body, "Alert message not sent"
+  end
+
+  def test_edit
+    assert_no_difference 'Member.count' do
+      put :update, :id => 2, :membership => {:role_ids => [1], :user_id => 3}
+    end
+    assert_redirected_to '/projects/ecookbook/settings/members'
+  end
+
+  def test_xhr_edit
+    assert_no_difference 'Member.count' do
+      xhr :put, :update, :id => 2, :membership => {:role_ids => [1], :user_id => 3}
+      assert_response :success
+      assert_template 'update'
+      assert_equal 'text/javascript', response.content_type
+    end
+    member = Member.find(2)
+    assert_equal [1], member.role_ids
+    assert_equal 3, member.user_id
+    assert_include 'tab-content-members', response.body
+  end
+
+  def test_destroy
+    assert_difference 'Member.count', -1 do
+      delete :destroy, :id => 2
+    end
+    assert_redirected_to '/projects/ecookbook/settings/members'
+    assert !User.find(3).member_of?(Project.find(1))
+  end
+
+  def test_xhr_destroy
+    assert_difference 'Member.count', -1 do
+      xhr :delete, :destroy, :id => 2
+      assert_response :success
+      assert_template 'destroy'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_nil Member.find_by_id(2)
+    assert_include 'tab-content-members', response.body
+  end
+
+  def test_autocomplete
+    get :autocomplete, :project_id => 1, :q => 'mis', :format => 'js'
+    assert_response :success
+    assert_include 'User Misc', response.body
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8d/8d646867ca13f3417cfc72ec4e7ed07e69398fdb.svn-base
--- /dev/null
+++ b/.svn/pristine/8d/8d646867ca13f3417cfc72ec4e7ed07e69398fdb.svn-base
@@ -0,0 +1,19 @@
+class RemoveIssuesDefaultFkValues < ActiveRecord::Migration
+  def up
+    change_column_default :issues, :tracker_id, nil
+    change_column_default :issues, :project_id, nil
+    change_column_default :issues, :status_id, nil
+    change_column_default :issues, :assigned_to_id, nil
+    change_column_default :issues, :priority_id, nil
+    change_column_default :issues, :author_id, nil
+  end
+
+  def down
+    change_column_default :issues, :tracker_id, 0
+    change_column_default :issues, :project_id, 0
+    change_column_default :issues, :status_id, 0
+    change_column_default :issues, :assigned_to_id, 0
+    change_column_default :issues, :priority_id, 0
+    change_column_default :issues, :author_id, 0
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8e3a1cce1761039cfaa74854eab700c58025e356.svn-base
--- a/.svn/pristine/8e/8e3a1cce1761039cfaa74854eab700c58025e356.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-<%= f.error_messages %>
-
-<div class="box tabular">
-  <p><%= f.text_field :lastname, :label => :field_name %></p>
-  <% @group.custom_field_values.each do |value| %>
-    <p><%= custom_field_tag_with_label :group, value %></p>
-  <% end %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8e4c7afc7109386dd42e0a86c04a6247a9bd537e.svn-base
--- a/.svn/pristine/8e/8e4c7afc7109386dd42e0a86c04a6247a9bd537e.svn-base
+++ /dev/null
@@ -1,343 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../test_helper', __FILE__)
-require 'digest/md5'
-
-class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase
-
-  def setup
-    @formatter = Redmine::WikiFormatting::Textile::Formatter
-  end
-
-  MODIFIERS = {
-    "*" => 'strong', # bold
-    "_" => 'em',     # italic
-    "+" => 'ins',    # underline
-    "-" => 'del',    # deleted
-    "^" => 'sup',    # superscript
-    "~" => 'sub'     # subscript
-  }
-
-  def test_modifiers
-    assert_html_output(
-      '*bold*'                => '<strong>bold</strong>',
-      'before *bold*'         => 'before <strong>bold</strong>',
-      '*bold* after'          => '<strong>bold</strong> after',
-      '*two words*'           => '<strong>two words</strong>',
-      '*two*words*'           => '<strong>two*words</strong>',
-      '*two * words*'         => '<strong>two * words</strong>',
-      '*two* *words*'         => '<strong>two</strong> <strong>words</strong>',
-      '*(two)* *(words)*'     => '<strong>(two)</strong> <strong>(words)</strong>',
-      # with class
-      '*(foo)two words*'      => '<strong class="foo">two words</strong>'
-    )
-  end
-
-  def test_modifiers_combination
-    MODIFIERS.each do |m1, tag1|
-      MODIFIERS.each do |m2, tag2|
-        next if m1 == m2
-        text = "#{m2}#{m1}Phrase modifiers#{m1}#{m2}"
-        html = "<#{tag2}><#{tag1}>Phrase modifiers</#{tag1}></#{tag2}>"
-        assert_html_output text => html
-      end
-    end
-  end
-
-  def test_inline_code
-    assert_html_output(
-      'this is @some code@'      => 'this is <code>some code</code>',
-      '@<Location /redmine>@'    => '<code>&lt;Location /redmine&gt;</code>'
-    )
-  end
-
-  def test_escaping
-    assert_html_output(
-      'this is a <script>'      => 'this is a &lt;script&gt;'
-    )
-  end
-
-  def test_use_of_backslashes_followed_by_numbers_in_headers
-    assert_html_output({
-      'h1. 2009\02\09'      => '<h1>2009\02\09</h1>'
-    }, false)
-  end
-
-  def test_double_dashes_should_not_strikethrough
-    assert_html_output(
-      'double -- dashes -- test'  => 'double -- dashes -- test',
-      'double -- *dashes* -- test'  => 'double -- <strong>dashes</strong> -- test'
-    )
-  end
-
-  def test_acronyms
-    assert_html_output(
-      'this is an acronym: GPL(General Public License)' => 'this is an acronym: <acronym title="General Public License">GPL</acronym>',
-      '2 letters JP(Jean-Philippe) acronym' => '2 letters <acronym title="Jean-Philippe">JP</acronym> acronym',
-      'GPL(This is a double-quoted "title")' => '<acronym title="This is a double-quoted &quot;title&quot;">GPL</acronym>'
-    )
-  end
-
-  def test_blockquote
-    # orig raw text
-    raw = <<-RAW
-John said:
-> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
-> Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
-> * Donec odio lorem,
-> * sagittis ac,
-> * malesuada in,
-> * adipiscing eu, dolor.
->
-> >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
-> Proin a tellus. Nam vel neque.
-
-He's right.
-RAW
-
-    # expected html
-    expected = <<-EXPECTED
-<p>John said:</p>
-<blockquote>
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.<br />
-Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
-<ul>
-  <li>Donec odio lorem,</li>
-  <li>sagittis ac,</li>
-  <li>malesuada in,</li>
-  <li>adipiscing eu, dolor.</li>
-</ul>
-<blockquote>
-<p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
-</blockquote>
-<p>Proin a tellus. Nam vel neque.</p>
-</blockquote>
-<p>He's right.</p>
-EXPECTED
-
-    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
-  end
-
-  def test_table
-    raw = <<-RAW
-This is a table with empty cells:
-
-|cell11|cell12||
-|cell21||cell23|
-|cell31|cell32|cell33|
-RAW
-
-    expected = <<-EXPECTED
-<p>This is a table with empty cells:</p>
-
-<table>
-  <tr><td>cell11</td><td>cell12</td><td></td></tr>
-  <tr><td>cell21</td><td></td><td>cell23</td></tr>
-  <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
-</table>
-EXPECTED
-
-    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
-  end
-
-  def test_table_with_line_breaks
-    raw = <<-RAW
-This is a table with line breaks:
-
-|cell11
-continued|cell12||
-|-cell21-||cell23
-cell23 line2
-cell23 *line3*|
-|cell31|cell32
-cell32 line2|cell33|
-
-RAW
-
-    expected = <<-EXPECTED
-<p>This is a table with line breaks:</p>
-
-<table>
-  <tr>
-    <td>cell11<br />continued</td>
-    <td>cell12</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td><del>cell21</del></td>
-    <td></td>
-    <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
-  </tr>
-  <tr>
-    <td>cell31</td>
-    <td>cell32<br/>cell32 line2</td>
-    <td>cell33</td>
-  </tr>
-</table>
-EXPECTED
-
-    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
-  end
-
-  def test_textile_should_not_mangle_brackets
-    assert_equal '<p>[msg1][msg2]</p>', to_html('[msg1][msg2]')
-  end
-
-  def test_textile_should_escape_image_urls
-    # this is onclick="alert('XSS');" in encoded form
-    raw = '!/images/comment.png"onclick=&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x27;&#x58;&#x53;&#x53;&#x27;&#x29;;&#x22;!'
-    expected = '<p><img src="/images/comment.png&quot;onclick=&amp;#x61;&amp;#x6c;&amp;#x65;&amp;#x72;&amp;#x74;&amp;#x28;&amp;#x27;&amp;#x58;&amp;#x53;&amp;#x53;&amp;#x27;&amp;#x29;;&amp;#x22;" alt="" /></p>'
-    assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
-  end
-  
-  
-  STR_WITHOUT_PRE = [
-  # 0
-"h1. Title
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
-  # 1
-"h2. Heading 2
-
-Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in.
-
-Cras ipsum felis, ultrices at porttitor vel, faucibus eu nunc.",
-  # 2
-"h2. Heading 2
-
-Morbi facilisis accumsan orci non pharetra.
-
-h3. Heading 3
-
-Nulla nunc nisi, egestas in ornare vel, posuere ac libero.",
-  # 3
-"h3. Heading 3
-
-Praesent eget turpis nibh, a lacinia nulla.",
-  # 4
-"h2. Heading 2
-
-Ut rhoncus elementum adipiscing."]
-
-  TEXT_WITHOUT_PRE = STR_WITHOUT_PRE.join("\n\n").freeze
-  
-  def test_get_section_should_return_the_requested_section_and_its_hash
-    assert_section_with_hash STR_WITHOUT_PRE[1], TEXT_WITHOUT_PRE, 2
-    assert_section_with_hash STR_WITHOUT_PRE[2..3].join("\n\n"), TEXT_WITHOUT_PRE, 3
-    assert_section_with_hash STR_WITHOUT_PRE[3], TEXT_WITHOUT_PRE, 5
-    assert_section_with_hash STR_WITHOUT_PRE[4], TEXT_WITHOUT_PRE, 6
-    
-    assert_section_with_hash '', TEXT_WITHOUT_PRE, 0
-    assert_section_with_hash '', TEXT_WITHOUT_PRE, 10
-  end
-  
-  def test_update_section_should_update_the_requested_section
-    replacement = "New text"
-    
-    assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement)
-    assert_equal [STR_WITHOUT_PRE[0..1], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(3, replacement)
-    assert_equal [STR_WITHOUT_PRE[0..2], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(5, replacement)
-    assert_equal [STR_WITHOUT_PRE[0..3], replacement].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(6, replacement)
-    
-    assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(0, replacement)
-    assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(10, replacement)
-  end
-  
-  def test_update_section_with_hash_should_update_the_requested_section
-    replacement = "New text"
-    
-    assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"),
-      @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement, Digest::MD5.hexdigest(STR_WITHOUT_PRE[1]))
-  end
-  
-  def test_update_section_with_wrong_hash_should_raise_an_error
-    assert_raise Redmine::WikiFormatting::StaleSectionError do
-      @formatter.new(TEXT_WITHOUT_PRE).update_section(2, "New text", Digest::MD5.hexdigest("Old text"))
-    end
-  end
-
-  STR_WITH_PRE = [
-  # 0
-"h1. Title
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
-  # 1
-"h2. Heading 2
-
-<pre><code class=\"ruby\">
-  def foo
-  end
-</code></pre>
-
-<pre><code><pre><code class=\"ruby\">
-  Place your code here.
-</code></pre>
-</code></pre>
-
-Morbi facilisis accumsan orci non pharetra.
-
-<pre>
-Pre Content:
-
-h2. Inside pre
-
-<tag> inside pre block
-
-Morbi facilisis accumsan orci non pharetra.
-</pre>",
-  # 2
-"h3. Heading 3
-
-Nulla nunc nisi, egestas in ornare vel, posuere ac libero."]
-
-  def test_get_section_should_ignore_pre_content
-    text = STR_WITH_PRE.join("\n\n")
-
-    assert_section_with_hash STR_WITH_PRE[1..2].join("\n\n"), text, 2
-    assert_section_with_hash STR_WITH_PRE[2], text, 3
-  end
-
-  def test_update_section_should_not_escape_pre_content_outside_section
-    text = STR_WITH_PRE.join("\n\n")
-    replacement = "New text"
-    
-    assert_equal [STR_WITH_PRE[0..1], "New text"].flatten.join("\n\n"),
-      @formatter.new(text).update_section(3, replacement)
-  end
-
-  private
-
-  def assert_html_output(to_test, expect_paragraph = true)
-    to_test.each do |text, expected|
-      assert_equal(( expect_paragraph ? "<p>#{expected}</p>" : expected ), @formatter.new(text).to_html, "Formatting the following text failed:\n===\n#{text}\n===\n")
-    end
-  end
-
-  def to_html(text)
-    @formatter.new(text).to_html
-  end
-  
-  def assert_section_with_hash(expected, text, index)
-    result = @formatter.new(text).get_section(index)
-    
-    assert_kind_of Array, result
-    assert_equal 2, result.size
-    assert_equal expected, result.first, "section content did not match"
-    assert_equal Digest::MD5.hexdigest(expected), result.last, "section hash did not match"
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8e5c0db7b703cf6a4ad1247955b7ea8792cd025e.svn-base
--- /dev/null
+++ b/.svn/pristine/8e/8e5c0db7b703cf6a4ad1247955b7ea8792cd025e.svn-base
@@ -0,0 +1,590 @@
+/* Redmine - project management software
+   Copyright (C) 2006-2013  Jean-Philippe Lang */
+
+function checkAll(id, checked) {
+  if (checked) {
+    $('#'+id).find('input[type=checkbox]').attr('checked', true);
+  } else {
+    $('#'+id).find('input[type=checkbox]').removeAttr('checked');
+  }
+}
+
+function toggleCheckboxesBySelector(selector) {
+  var all_checked = true;
+  $(selector).each(function(index) {
+    if (!$(this).is(':checked')) { all_checked = false; }
+  });
+  $(selector).attr('checked', !all_checked);
+}
+
+function showAndScrollTo(id, focus) {
+  $('#'+id).show();
+  if (focus !== null) {
+    $('#'+focus).focus();
+  }
+  $('html, body').animate({scrollTop: $('#'+id).offset().top}, 100);
+}
+
+function toggleRowGroup(el) {
+  var tr = $(el).parents('tr').first();
+  var n = tr.next();
+  tr.toggleClass('open');
+  while (n.length && !n.hasClass('group')) {
+    n.toggle();
+    n = n.next('tr');
+  }
+}
+
+function collapseAllRowGroups(el) {
+  var tbody = $(el).parents('tbody').first();
+  tbody.children('tr').each(function(index) {
+    if ($(this).hasClass('group')) {
+      $(this).removeClass('open');
+    } else {
+      $(this).hide();
+    }
+  });
+}
+
+function expandAllRowGroups(el) {
+  var tbody = $(el).parents('tbody').first();
+  tbody.children('tr').each(function(index) {
+    if ($(this).hasClass('group')) {
+      $(this).addClass('open');
+    } else {
+      $(this).show();
+    }
+  });
+}
+
+function toggleAllRowGroups(el) {
+  var tr = $(el).parents('tr').first();
+  if (tr.hasClass('open')) {
+    collapseAllRowGroups(el);
+  } else {
+    expandAllRowGroups(el);
+  }
+}
+
+function toggleFieldset(el) {
+  var fieldset = $(el).parents('fieldset').first();
+  fieldset.toggleClass('collapsed');
+  fieldset.children('div').toggle();
+}
+
+function hideFieldset(el) {
+  var fieldset = $(el).parents('fieldset').first();
+  fieldset.toggleClass('collapsed');
+  fieldset.children('div').hide();
+}
+
+function initFilters(){
+  $('#add_filter_select').change(function(){
+    addFilter($(this).val(), '', []);
+  });
+  $('#filters-table td.field input[type=checkbox]').each(function(){
+    toggleFilter($(this).val());
+  });
+  $('#filters-table td.field input[type=checkbox]').live('click',function(){
+    toggleFilter($(this).val());
+  });
+  $('#filters-table .toggle-multiselect').live('click',function(){
+    toggleMultiSelect($(this).siblings('select'));
+  });
+  $('#filters-table input[type=text]').live('keypress', function(e){
+    if (e.keyCode == 13) submit_query_form("query_form");
+  });
+}
+
+function addFilter(field, operator, values) {
+  var fieldId = field.replace('.', '_');
+  var tr = $('#tr_'+fieldId);
+  if (tr.length > 0) {
+    tr.show();
+  } else {
+    buildFilterRow(field, operator, values);
+  }
+  $('#cb_'+fieldId).attr('checked', true);
+  toggleFilter(field);
+  $('#add_filter_select').val('').children('option').each(function(){
+    if ($(this).attr('value') == field) {
+      $(this).attr('disabled', true);
+    }
+  });
+}
+
+function buildFilterRow(field, operator, values) {
+  var fieldId = field.replace('.', '_');
+  var filterTable = $("#filters-table");
+  var filterOptions = availableFilters[field];
+  var operators = operatorByType[filterOptions['type']];
+  var filterValues = filterOptions['values'];
+  var i, select;
+
+  var tr = $('<tr class="filter">').attr('id', 'tr_'+fieldId).html(
+    '<td class="field"><input checked="checked" id="cb_'+fieldId+'" name="f[]" value="'+field+'" type="checkbox"><label for="cb_'+fieldId+'"> '+filterOptions['name']+'</label></td>' +
+    '<td class="operator"><select id="operators_'+fieldId+'" name="op['+field+']"></td>' +
+    '<td class="values"></td>'
+  );
+  filterTable.append(tr);
+
+  select = tr.find('td.operator select');
+  for (i=0;i<operators.length;i++){
+    var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]);
+    if (operators[i] == operator) { option.attr('selected', true); }
+    select.append(option);
+  }
+  select.change(function(){ toggleOperator(field); });
+
+  switch (filterOptions['type']){
+  case "list":
+  case "list_optional":
+  case "list_status":
+  case "list_subprojects":
+    tr.find('td.values').append(
+      '<span style="display:none;"><select class="value" id="values_'+fieldId+'_1" name="v['+field+'][]"></select>' +
+      ' <span class="toggle-multiselect">&nbsp;</span></span>'
+    );
+    select = tr.find('td.values select');
+    if (values.length > 1) { select.attr('multiple', true); }
+    for (i=0;i<filterValues.length;i++){
+      var filterValue = filterValues[i];
+      var option = $('<option>');
+      if ($.isArray(filterValue)) {
+        option.val(filterValue[1]).text(filterValue[0]);
+        if ($.inArray(filterValue[1], values) > -1) {option.attr('selected', true);}
+      } else {
+        option.val(filterValue).text(filterValue);
+        if ($.inArray(filterValue, values) > -1) {option.attr('selected', true);}
+      }
+      select.append(option);
+    }
+    break;
+  case "date":
+  case "date_past":
+    tr.find('td.values').append(
+      '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="10" class="value date_value" /></span>' +
+      ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="10" class="value date_value" /></span>' +
+      ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="3" class="value" /> '+labelDayPlural+'</span>'
+    );
+    $('#values_'+fieldId+'_1').val(values[0]).datepicker(datepickerOptions);
+    $('#values_'+fieldId+'_2').val(values[1]).datepicker(datepickerOptions);
+    $('#values_'+fieldId).val(values[0]);
+    break;
+  case "string":
+  case "text":
+    tr.find('td.values').append(
+      '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="30" class="value" /></span>'
+    );
+    $('#values_'+fieldId).val(values[0]);
+    break;
+  case "relation":
+    tr.find('td.values').append(
+      '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="6" class="value" /></span>' +
+      '<span style="display:none;"><select class="value" name="v['+field+'][]" id="values_'+fieldId+'_1"></select></span>'
+    );
+    $('#values_'+fieldId).val(values[0]);
+    select = tr.find('td.values select');
+    for (i=0;i<allProjects.length;i++){
+      var filterValue = allProjects[i];
+      var option = $('<option>');
+      option.val(filterValue[1]).text(filterValue[0]);
+      if (values[0] == filterValue[1]) { option.attr('selected', true); }
+      select.append(option);
+    }
+  case "integer":
+  case "float":
+    tr.find('td.values').append(
+      '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' +
+      ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>'
+    );
+    $('#values_'+fieldId+'_1').val(values[0]);
+    $('#values_'+fieldId+'_2').val(values[1]);
+    break;
+  }
+}
+
+function toggleFilter(field) {
+  var fieldId = field.replace('.', '_');
+  if ($('#cb_' + fieldId).is(':checked')) {
+    $("#operators_" + fieldId).show().removeAttr('disabled');
+    toggleOperator(field);
+  } else {
+    $("#operators_" + fieldId).hide().attr('disabled', true);
+    enableValues(field, []);
+  }
+}
+
+function enableValues(field, indexes) {
+  var fieldId = field.replace('.', '_');
+  $('#tr_'+fieldId+' td.values .value').each(function(index) {
+    if ($.inArray(index, indexes) >= 0) {
+      $(this).removeAttr('disabled');
+      $(this).parents('span').first().show();
+    } else {
+      $(this).val('');
+      $(this).attr('disabled', true);
+      $(this).parents('span').first().hide();
+    }
+
+    if ($(this).hasClass('group')) {
+      $(this).addClass('open');
+    } else {
+      $(this).show();
+    }
+  });
+}
+
+function toggleOperator(field) {
+  var fieldId = field.replace('.', '_');
+  var operator = $("#operators_" + fieldId);
+  switch (operator.val()) {
+    case "!*":
+    case "*":
+    case "t":
+    case "ld":
+    case "w":
+    case "lw":
+    case "l2w":
+    case "m":
+    case "lm":
+    case "y":
+    case "o":
+    case "c":
+      enableValues(field, []);
+      break;
+    case "><":
+      enableValues(field, [0,1]);
+      break;
+    case "<t+":
+    case ">t+":
+    case "><t+":
+    case "t+":
+    case ">t-":
+    case "<t-":
+    case "><t-":
+    case "t-":
+      enableValues(field, [2]);
+      break;
+    case "=p":
+    case "=!p":
+    case "!p":
+      enableValues(field, [1]);
+      break;
+    default:
+      enableValues(field, [0]);
+      break;
+  }
+}
+
+function toggleMultiSelect(el) {
+  if (el.attr('multiple')) {
+    el.removeAttr('multiple');
+  } else {
+    el.attr('multiple', true);
+  }
+}
+
+function submit_query_form(id) {
+  selectAllOptions("selected_columns");
+  $('#'+id).submit();
+}
+
+function showTab(name) {
+  $('div#content .tab-content').hide();
+  $('div.tabs a').removeClass('selected');
+  $('#tab-content-' + name).show();
+  $('#tab-' + name).addClass('selected');
+  return false;
+}
+
+function moveTabRight(el) {
+  var lis = $(el).parents('div.tabs').first().find('ul').children();
+  var tabsWidth = 0;
+  var i = 0;
+  lis.each(function(){
+    if ($(this).is(':visible')) {
+      tabsWidth += $(this).width() + 6;
+    }
+  });
+  if (tabsWidth < $(el).parents('div.tabs').first().width() - 60) { return; }
+  while (i<lis.length && !lis.eq(i).is(':visible')) { i++; }
+  lis.eq(i).hide();
+}
+
+function moveTabLeft(el) {
+  var lis = $(el).parents('div.tabs').first().find('ul').children();
+  var i = 0;
+  while (i<lis.length && !lis.eq(i).is(':visible')) { i++; }
+  if (i>0) {
+    lis.eq(i-1).show();
+  }
+}
+
+function displayTabsButtons() {
+  var lis;
+  var tabsWidth = 0;
+  var el;
+  $('div.tabs').each(function() {
+    el = $(this);
+    lis = el.find('ul').children();
+    lis.each(function(){
+      if ($(this).is(':visible')) {
+        tabsWidth += $(this).width() + 6;
+      }
+    });
+    if ((tabsWidth < el.width() - 60) && (lis.first().is(':visible'))) {
+      el.find('div.tabs-buttons').hide();
+    } else {
+      el.find('div.tabs-buttons').show();
+    }
+  });
+}
+
+function setPredecessorFieldsVisibility() {
+  var relationType = $('#relation_relation_type');
+  if (relationType.val() == "precedes" || relationType.val() == "follows") {
+    $('#predecessor_fields').show();
+  } else {
+    $('#predecessor_fields').hide();
+  }
+}
+
+function showModal(id, width) {
+  var el = $('#'+id).first();
+  if (el.length === 0 || el.is(':visible')) {return;}
+  var title = el.find('h3.title').text();
+  el.dialog({
+    width: width,
+    modal: true,
+    resizable: false,
+    dialogClass: 'modal',
+    title: title
+  });
+  el.find("input[type=text], input[type=submit]").first().focus();
+}
+
+function hideModal(el) {
+  var modal;
+  if (el) {
+    modal = $(el).parents('.ui-dialog-content');
+  } else {
+    modal = $('#ajax-modal');
+  }
+  modal.dialog("close");
+}
+
+function submitPreview(url, form, target) {
+  $.ajax({
+    url: url,
+    type: 'post',
+    data: $('#'+form).serialize(),
+    success: function(data){
+      $('#'+target).html(data);
+    }
+  });
+}
+
+function collapseScmEntry(id) {
+  $('.'+id).each(function() {
+    if ($(this).hasClass('open')) {
+      collapseScmEntry($(this).attr('id'));
+    }
+    $(this).hide();
+  });
+  $('#'+id).removeClass('open');
+}
+
+function expandScmEntry(id) {
+  $('.'+id).each(function() {
+    $(this).show();
+    if ($(this).hasClass('loaded') && !$(this).hasClass('collapsed')) {
+      expandScmEntry($(this).attr('id'));
+    }
+  });
+  $('#'+id).addClass('open');
+}
+
+function scmEntryClick(id, url) {
+    el = $('#'+id);
+    if (el.hasClass('open')) {
+        collapseScmEntry(id);
+        el.addClass('collapsed');
+        return false;
+    } else if (el.hasClass('loaded')) {
+        expandScmEntry(id);
+        el.removeClass('collapsed');
+        return false;
+    }
+    if (el.hasClass('loading')) {
+        return false;
+    }
+    el.addClass('loading');
+    $.ajax({
+      url: url,
+      success: function(data){
+        el.after(data);
+        el.addClass('open').addClass('loaded').removeClass('loading');
+      }
+    });
+    return true;
+}
+
+function randomKey(size) {
+  var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
+  var key = '';
+  for (i = 0; i < size; i++) {
+    key += chars[Math.floor(Math.random() * chars.length)];
+  }
+  return key;
+}
+
+// Can't use Rails' remote select because we need the form data
+function updateIssueFrom(url) {
+  $.ajax({
+    url: url,
+    type: 'post',
+    data: $('#issue-form').serialize()
+  });
+}
+
+function updateBulkEditFrom(url) {
+  $.ajax({
+    url: url,
+    type: 'post',
+    data: $('#bulk_edit_form').serialize()
+  });
+}
+
+function observeAutocompleteField(fieldId, url, options) {
+  $(document).ready(function() {
+    $('#'+fieldId).autocomplete($.extend({
+      source: url,
+      minLength: 2,
+      search: function(){$('#'+fieldId).addClass('ajax-loading');},
+      response: function(){$('#'+fieldId).removeClass('ajax-loading');}
+    }, options));
+    $('#'+fieldId).addClass('autocomplete');
+  });
+}
+
+function observeSearchfield(fieldId, targetId, url) {
+  $('#'+fieldId).each(function() {
+    var $this = $(this);
+    $this.addClass('autocomplete');
+    $this.attr('data-value-was', $this.val());
+    var check = function() {
+      var val = $this.val();
+      if ($this.attr('data-value-was') != val){
+        $this.attr('data-value-was', val);
+        $.ajax({
+          url: url,
+          type: 'get',
+          data: {q: $this.val()},
+          success: function(data){ if(targetId) $('#'+targetId).html(data); },
+          beforeSend: function(){ $this.addClass('ajax-loading'); },
+          complete: function(){ $this.removeClass('ajax-loading'); }
+        });
+      }
+    };
+    var reset = function() {
+      if (timer) {
+        clearInterval(timer);
+        timer = setInterval(check, 300);
+      }
+    };
+    var timer = setInterval(check, 300);
+    $this.bind('keyup click mousemove', reset);
+  });
+}
+
+function observeProjectModules() {
+  var f = function() {
+    /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
+    if ($('#project_enabled_module_names_issue_tracking').attr('checked')) {
+      $('#project_trackers').show();
+    }else{
+      $('#project_trackers').hide();
+    }
+  };
+
+  $(window).load(f);
+  $('#project_enabled_module_names_issue_tracking').change(f);
+}
+
+function initMyPageSortable(list, url) {
+  $('#list-'+list).sortable({
+    connectWith: '.block-receiver',
+    tolerance: 'pointer',
+    update: function(){
+      $.ajax({
+        url: url,
+        type: 'post',
+        data: {'blocks': $.map($('#list-'+list).children(), function(el){return $(el).attr('id');})}
+      });
+    }
+  });
+  $("#list-top, #list-left, #list-right").disableSelection();
+}
+
+var warnLeavingUnsavedMessage;
+function warnLeavingUnsaved(message) {
+  warnLeavingUnsavedMessage = message;
+
+  $('form').submit(function(){
+    $('textarea').removeData('changed');
+  });
+  $('textarea').change(function(){
+    $(this).data('changed', 'changed');
+  });
+  window.onbeforeunload = function(){
+    var warn = false;
+    $('textarea').blur().each(function(){
+      if ($(this).data('changed')) {
+        warn = true;
+      }
+    });
+    if (warn) {return warnLeavingUnsavedMessage;}
+  };
+}
+
+function setupAjaxIndicator() {
+
+  $('#ajax-indicator').bind('ajaxSend', function(event, xhr, settings) {
+  
+    if ($('.ajax-loading').length === 0 && settings.contentType != 'application/octet-stream') {
+      $('#ajax-indicator').show();
+    }
+  });
+  
+  $('#ajax-indicator').bind('ajaxStop', function() {
+    $('#ajax-indicator').hide();
+  });
+}
+
+function hideOnLoad() {
+  $('.hol').hide();
+}
+
+function addFormObserversForDoubleSubmit() {
+  $('form[method=post]').each(function() {
+    if (!$(this).hasClass('multiple-submit')) {
+      $(this).submit(function(form_submission) {
+        if ($(form_submission.target).attr('data-submitted')) {
+          form_submission.preventDefault();
+        } else {
+          $(form_submission.target).attr('data-submitted', true);
+        }
+      });
+    }
+  });
+}
+
+function blockEventPropagation(event) {
+  event.stopPropagation();
+  event.preventDefault();
+}
+
+$(document).ready(setupAjaxIndicator);
+$(document).ready(hideOnLoad);
+$(document).ready(addFormObserversForDoubleSubmit);
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8e63ae23737dec9c540cc473f907c317622679da.svn-base
--- /dev/null
+++ b/.svn/pristine/8e/8e63ae23737dec9c540cc473f907c317622679da.svn-base
@@ -0,0 +1,74 @@
+api.issue do
+  api.id @issue.id
+  api.project(:id => @issue.project_id, :name => @issue.project.name) unless @issue.project.nil?
+  api.tracker(:id => @issue.tracker_id, :name => @issue.tracker.name) unless @issue.tracker.nil?
+  api.status(:id => @issue.status_id, :name => @issue.status.name) unless @issue.status.nil?
+  api.priority(:id => @issue.priority_id, :name => @issue.priority.name) unless @issue.priority.nil?
+  api.author(:id => @issue.author_id, :name => @issue.author.name) unless @issue.author.nil?
+  api.assigned_to(:id => @issue.assigned_to_id, :name => @issue.assigned_to.name) unless @issue.assigned_to.nil?
+  api.category(:id => @issue.category_id, :name => @issue.category.name) unless @issue.category.nil?
+  api.fixed_version(:id => @issue.fixed_version_id, :name => @issue.fixed_version.name) unless @issue.fixed_version.nil?
+  api.parent(:id => @issue.parent_id) unless @issue.parent.nil?
+
+  api.subject @issue.subject
+  api.description @issue.description
+  api.start_date @issue.start_date
+  api.due_date @issue.due_date
+  api.done_ratio @issue.done_ratio
+  api.estimated_hours @issue.estimated_hours
+  api.spent_hours(@issue.spent_hours) if User.current.allowed_to?(:view_time_entries, @project)
+
+  render_api_custom_values @issue.custom_field_values, api
+
+  api.created_on @issue.created_on
+  api.updated_on @issue.updated_on
+  api.closed_on @issue.closed_on
+
+  render_api_issue_children(@issue, api) if include_in_api_response?('children')
+
+  api.array :attachments do
+    @issue.attachments.each do |attachment|
+      render_api_attachment(attachment, api)
+    end
+  end if include_in_api_response?('attachments')
+
+  api.array :relations do
+    @relations.each do |relation|
+      api.relation(:id => relation.id, :issue_id => relation.issue_from_id, :issue_to_id => relation.issue_to_id, :relation_type => relation.relation_type, :delay => relation.delay)
+    end
+  end if include_in_api_response?('relations') && @relations.present?
+
+  api.array :changesets do
+    @issue.changesets.each do |changeset|
+      api.changeset :revision => changeset.revision do
+        api.user(:id => changeset.user_id, :name => changeset.user.name) unless changeset.user.nil?
+        api.comments changeset.comments
+        api.committed_on changeset.committed_on
+      end
+    end
+  end if include_in_api_response?('changesets') && User.current.allowed_to?(:view_changesets, @project)
+
+  api.array :journals do
+    @journals.each do |journal|
+      api.journal :id => journal.id do
+        api.user(:id => journal.user_id, :name => journal.user.name) unless journal.user.nil?
+        api.notes journal.notes
+        api.created_on journal.created_on
+        api.array :details do
+          journal.details.each do |detail|
+            api.detail :property => detail.property, :name => detail.prop_key do
+              api.old_value detail.old_value
+              api.new_value detail.value
+            end
+          end
+        end
+      end
+    end
+  end if include_in_api_response?('journals')
+
+  api.array :watchers do
+    @issue.watcher_users.each do |user|
+      api.user :id => user.id, :name => user.name
+    end
+  end if include_in_api_response?('watchers') && User.current.allowed_to?(:view_issue_watchers, @issue.project)
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8e87d45a1944e77c75639604c040e7c63aafef04.svn-base
--- /dev/null
+++ b/.svn/pristine/8e/8e87d45a1944e77c75639604c040e7c63aafef04.svn-base
@@ -0,0 +1,10 @@
+<h2><%= l(:label_settings) %>: <%=h @plugin.name %></h2>
+
+<div id="settings">
+<%= form_tag({:action => 'plugin'}) do %>
+<div class="box tabular settings">
+<%= render :partial => @partial, :locals => {:settings => @settings}%>
+</div>
+<%= submit_tag l(:button_apply) %>
+<% end %>
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8e8e8287a74b0335843089c614a9c33ed22e75db.svn-base
--- /dev/null
+++ b/.svn/pristine/8e/8e8e8287a74b0335843089c614a9c33ed22e75db.svn-base
@@ -0,0 +1,54 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssueCategoryTest < ActiveSupport::TestCase
+  fixtures :issue_categories, :issues, :users, :groups_users
+
+  def setup
+    @category = IssueCategory.find(1)
+  end
+
+  def test_create
+    assert IssueCategory.new(:project_id => 2, :name => 'New category').save
+    category = IssueCategory.first(:order => 'id DESC')
+    assert_equal 'New category', category.name
+  end
+
+  def test_create_with_group_assignment
+    assert IssueCategory.new(:project_id => 2, :name => 'Group assignment', :assigned_to_id => 11).save
+    category = IssueCategory.first(:order => 'id DESC')
+    assert_kind_of Group, category.assigned_to
+    assert_equal Group.find(11), category.assigned_to
+  end
+
+  def test_destroy
+    issue = @category.issues.first
+    @category.destroy
+    # Make sure the category was nullified on the issue
+    assert_nil issue.reload.category
+  end
+
+  def test_destroy_with_reassign
+    issue = @category.issues.first
+    reassign_to = IssueCategory.find(2)
+    @category.destroy(reassign_to)
+    # Make sure the issue was reassigned
+    assert_equal reassign_to, issue.reload.category
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8ea06d22d8f2b1998d7e2d84f7804f12208c49ad.svn-base
--- /dev/null
+++ b/.svn/pristine/8e/8ea06d22d8f2b1998d7e2d84f7804f12208c49ad.svn-base
@@ -0,0 +1,43 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module ContextMenusHelper
+  def context_menu_link(name, url, options={})
+    options[:class] ||= ''
+    if options.delete(:selected)
+      options[:class] << ' icon-checked disabled'
+      options[:disabled] = true
+    end
+    if options.delete(:disabled)
+      options.delete(:method)
+      options.delete(:data)
+      options[:onclick] = 'return false;'
+      options[:class] << ' disabled'
+      url = '#'
+    end
+    link_to h(name), url, options
+  end
+
+  def bulk_update_custom_field_context_menu_link(field, text, value)
+    context_menu_link h(text),
+      bulk_update_issues_path(:ids => @issue_ids, :issue => {'custom_field_values' => {field.id => value}}, :back_url => @back),
+      :method => :post,
+      :selected => (@issue && @issue.custom_field_value(field) == value)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8ea0bc80173488b475728a1210d5a4e2c04acfe7.svn-base
Binary file .svn/pristine/8e/8ea0bc80173488b475728a1210d5a4e2c04acfe7.svn-base has changed
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8ea72f11aca3633b56300020cda571d3f13b20ac.svn-base
--- a/.svn/pristine/8e/8ea72f11aca3633b56300020cda571d3f13b20ac.svn-base
+++ /dev/null
@@ -1,323 +0,0 @@
-#!/usr/bin/env ruby
-
-# == Synopsis
-#
-# reposman: manages your repositories with Redmine
-#
-# == Usage
-#
-#    reposman [OPTIONS...] -s [DIR] -r [HOST]
-#
-#  Examples:
-#    reposman --svn-dir=/var/svn --redmine-host=redmine.example.net --scm subversion
-#    reposman -s /var/git -r redmine.example.net -u http://svn.example.net --scm git
-#
-# == Arguments (mandatory)
-#
-#   -s, --svn-dir=DIR         use DIR as base directory for svn repositories
-#   -r, --redmine-host=HOST   assume Redmine is hosted on HOST. Examples:
-#                             -r redmine.example.net
-#                             -r http://redmine.example.net
-#                             -r https://example.net/redmine
-#   -k, --key=KEY             use KEY as the Redmine API key (you can use the
-#                             --key-file option as an alternative)
-#
-# == Options
-#
-#   -o, --owner=OWNER         owner of the repository. using the rails login
-#                             allow user to browse the repository within
-#                             Redmine even for private project. If you want to
-#                             share repositories through Redmine.pm, you need
-#                             to use the apache owner.
-#   -g, --group=GROUP         group of the repository. (default: root)
-#   --scm=SCM                 the kind of SCM repository you want to create (and
-#                             register) in Redmine (default: Subversion).
-#                             reposman is able to create Git and Subversion
-#                             repositories. For all other kind, you must specify
-#                             a --command option
-#   -u, --url=URL             the base url Redmine will use to access your
-#                             repositories. This option is used to automatically
-#                             register the repositories in Redmine. The project
-#                             identifier will be appended to this url. Examples:
-#                             -u https://example.net/svn
-#                             -u file:///var/svn/
-#                             if this option isn't set, reposman won't register
-#                             the repositories in Redmine
-#   -c, --command=COMMAND     use this command instead of "svnadmin create" to
-#                             create a repository. This option can be used to
-#                             create repositories other than subversion and git
-#                             kind.
-#                             This command override the default creation for git
-#                             and subversion.
-#   -f, --force               force repository creation even if the project
-#                             repository is already declared in Redmine
-#       --key-file=PATH       path to a file that contains the Redmine API key
-#                             (use this option instead of --key if you don't 
-#                             the key to appear in the command line)
-#   -t, --test                only show what should be done
-#   -h, --help                show help and exit
-#   -v, --verbose             verbose
-#   -V, --version             print version and exit
-#   -q, --quiet               no log
-#
-# == References
-#
-# You can find more information on the redmine's wiki : http://www.redmine.org/wiki/redmine/HowTos
-
-
-require 'getoptlong'
-require 'rdoc/usage'
-require 'find'
-require 'etc'
-
-Version = "1.3"
-SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem )
-
-opts = GetoptLong.new(
-                      ['--svn-dir',      '-s', GetoptLong::REQUIRED_ARGUMENT],
-                      ['--redmine-host', '-r', GetoptLong::REQUIRED_ARGUMENT],
-                      ['--key',          '-k', GetoptLong::REQUIRED_ARGUMENT],
-                      ['--key-file',           GetoptLong::REQUIRED_ARGUMENT],
-                      ['--owner',        '-o', GetoptLong::REQUIRED_ARGUMENT],
-                      ['--group',        '-g', GetoptLong::REQUIRED_ARGUMENT],
-                      ['--url',          '-u', GetoptLong::REQUIRED_ARGUMENT],
-                      ['--command' ,     '-c', GetoptLong::REQUIRED_ARGUMENT],
-                      ['--scm',                GetoptLong::REQUIRED_ARGUMENT],
-                      ['--test',         '-t', GetoptLong::NO_ARGUMENT],
-                      ['--force',        '-f', GetoptLong::NO_ARGUMENT],
-                      ['--verbose',      '-v', GetoptLong::NO_ARGUMENT],
-                      ['--version',      '-V', GetoptLong::NO_ARGUMENT],
-                      ['--help'   ,      '-h', GetoptLong::NO_ARGUMENT],
-                      ['--quiet'  ,      '-q', GetoptLong::NO_ARGUMENT]
-                      )
-
-$verbose      = 0
-$quiet        = false
-$redmine_host = ''
-$repos_base   = ''
-$svn_owner    = 'root'
-$svn_group    = 'root'
-$use_groupid  = true
-$svn_url      = false
-$test         = false
-$force        = false
-$scm          = 'Subversion'
-
-def log(text, options={})
-  level = options[:level] || 0
-  puts text unless $quiet or level > $verbose
-  exit 1 if options[:exit]
-end
-
-def system_or_raise(command)
-  raise "\"#{command}\" failed" unless system command
-end
-
-module SCM
-
-  module Subversion
-    def self.create(path)
-      system_or_raise "svnadmin create #{path}"
-    end
-  end
-
-  module Git
-    def self.create(path)
-      Dir.mkdir path
-      Dir.chdir(path) do
-        system_or_raise "git --bare init --shared"
-        system_or_raise "git update-server-info"
-      end
-    end
-  end
-
-end
-
-begin
-  opts.each do |opt, arg|
-    case opt
-    when '--svn-dir';        $repos_base   = arg.dup
-    when '--redmine-host';   $redmine_host = arg.dup
-    when '--key';            $api_key      = arg.dup
-    when '--key-file'
-      begin
-        $api_key = File.read(arg).strip
-      rescue Exception => e
-        $stderr.puts "Unable to read the key from #{arg}: #{e.message}"
-        exit 1
-      end
-    when '--owner';          $svn_owner    = arg.dup; $use_groupid = false;
-    when '--group';          $svn_group    = arg.dup; $use_groupid = false;
-    when '--url';            $svn_url      = arg.dup
-    when '--scm';            $scm          = arg.dup.capitalize; log("Invalid SCM: #{$scm}", :exit => true) unless SUPPORTED_SCM.include?($scm)
-    when '--command';        $command =      arg.dup
-    when '--verbose';        $verbose += 1
-    when '--test';           $test = true
-    when '--force';          $force = true
-    when '--version';        puts Version; exit
-    when '--help';           RDoc::usage
-    when '--quiet';          $quiet = true
-    end
-  end
-rescue
-  exit 1
-end
-
-if $test
-  log("running in test mode")
-end
-
-# Make sure command is overridden if SCM vendor is not handled internally (for the moment Subversion and Git)
-if $command.nil?
-  begin
-    scm_module = SCM.const_get($scm)
-  rescue
-    log("Please use --command option to specify how to create a #{$scm} repository.", :exit => true)
-  end
-end
-
-$svn_url += "/" if $svn_url and not $svn_url.match(/\/$/)
-
-if ($redmine_host.empty? or $repos_base.empty?)
-  RDoc::usage
-end
-
-unless File.directory?($repos_base)
-  log("directory '#{$repos_base}' doesn't exists", :exit => true)
-end
-
-begin
-  require 'active_resource'
-rescue LoadError
-  log("This script requires activeresource.\nRun 'gem install activeresource' to install it.", :exit => true)
-end
-
-class Project < ActiveResource::Base
-  self.headers["User-agent"] = "Redmine repository manager/#{Version}"
-  self.format = :xml
-end
-
-log("querying Redmine for projects...", :level => 1);
-
-$redmine_host.gsub!(/^/, "http://") unless $redmine_host.match("^https?://")
-$redmine_host.gsub!(/\/$/, '')
-
-Project.site = "#{$redmine_host}/sys";
-
-begin
-  # Get all active projects that have the Repository module enabled
-  projects = Project.find(:all, :params => {:key => $api_key})
-rescue ActiveResource::ForbiddenAccess
-  log("Request was denied by your Redmine server. Make sure that 'WS for repository management' is enabled in application settings and that you provided the correct API key.")
-rescue => e
-  log("Unable to connect to #{Project.site}: #{e}", :exit => true)
-end
-
-if projects.nil?
-  log('No project found, perhaps you forgot to "Enable WS for repository management"', :exit => true)
-end
-
-log("retrieved #{projects.size} projects", :level => 1)
-
-def set_owner_and_rights(project, repos_path, &block)
-  if mswin?
-    yield if block_given?
-  else
-    uid, gid = Etc.getpwnam($svn_owner).uid, ($use_groupid ? Etc.getgrnam(project.identifier).gid : Etc.getgrnam($svn_group).gid)
-    right = project.is_public ? 0775 : 0770
-    yield if block_given?
-    Find.find(repos_path) do |f|
-      File.chmod right, f
-      File.chown uid, gid, f
-    end
-  end
-end
-
-def other_read_right?(file)
-  (File.stat(file).mode & 0007).zero? ? false : true
-end
-
-def owner_name(file)
-  mswin? ?
-    $svn_owner :
-    Etc.getpwuid( File.stat(file).uid ).name
-end
-
-def mswin?
-  (RUBY_PLATFORM =~ /(:?mswin|mingw)/) || (RUBY_PLATFORM == 'java' && (ENV['OS'] || ENV['os']) =~ /windows/i)
-end
-
-projects.each do |project|
-  log("treating project #{project.name}", :level => 1)
-
-  if project.identifier.empty?
-    log("\tno identifier for project #{project.name}")
-    next
-  elsif not project.identifier.match(/^[a-z0-9\-]+$/)
-    log("\tinvalid identifier for project #{project.name} : #{project.identifier}");
-    next;
-  end
-
-  repos_path = File.join($repos_base, project.identifier).gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
-
-  if File.directory?(repos_path)
-    # we must verify that repository has the good owner and the good
-    # rights before leaving
-    other_read = other_read_right?(repos_path)
-    owner      = owner_name(repos_path)
-    next if project.is_public == other_read and owner == $svn_owner
-
-    if $test
-      log("\tchange mode on #{repos_path}")
-      next
-    end
-
-    begin
-      set_owner_and_rights(project, repos_path)
-    rescue Errno::EPERM => e
-      log("\tunable to change mode on #{repos_path} : #{e}\n")
-      next
-    end
-
-    log("\tmode change on #{repos_path}");
-
-  else
-    # if repository is already declared in redmine, we don't create
-    # unless user use -f with reposman
-    if $force == false and project.respond_to?(:repository)
-      log("\trepository for project #{project.identifier} already exists in Redmine", :level => 1)
-      next
-    end
-
-    project.is_public ? File.umask(0002) : File.umask(0007)
-
-    if $test
-      log("\tcreate repository #{repos_path}")
-      log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}") if $svn_url;
-      next
-    end
-
-    begin
-      set_owner_and_rights(project, repos_path) do
-        if scm_module.nil?
-          system_or_raise "#{$command} #{repos_path}"
-        else
-          scm_module.create(repos_path)
-        end
-      end
-    rescue => e
-      log("\tunable to create #{repos_path} : #{e}\n")
-      next
-    end
-
-    if $svn_url
-      begin
-        project.post(:repository, :vendor => $scm, :repository => {:url => "#{$svn_url}#{project.identifier}"}, :key => $api_key)
-        log("\trepository #{repos_path} registered in Redmine with url #{$svn_url}#{project.identifier}");
-      rescue => e
-        log("\trepository #{repos_path} not registered in Redmine: #{e.message}");
-      end
-    end
-    log("\trepository #{repos_path} created");
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8eb3da3ac94d3ec30a1122590be0b6f235d41250.svn-base
--- a/.svn/pristine/8e/8eb3da3ac94d3ec30a1122590be0b6f235d41250.svn-base
+++ /dev/null
@@ -1,118 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'repositories_controller'
-
-# Re-raise errors caught by the controller.
-class RepositoriesController; def rescue_action(e) raise e end; end
-
-class RepositoriesControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles,
-           :repositories, :issues, :issue_statuses, :changesets, :changes,
-           :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
-
-  def setup
-    @controller = RepositoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_revisions
-    get :revisions, :id => 1
-    assert_response :success
-    assert_template 'revisions'
-    assert_not_nil assigns(:changesets)
-  end
-
-  def test_revision
-    get :revision, :id => 1, :rev => 1
-    assert_response :success
-    assert_not_nil assigns(:changeset)
-    assert_equal "1", assigns(:changeset).revision
-  end
-
-  def test_revision_with_before_nil_and_afer_normal
-    get :revision, {:id => 1, :rev => 1}
-    assert_response :success
-    assert_template 'revision'
-    assert_no_tag :tag => "div", :attributes => { :class => "contextual" },
-      :child => { :tag => "a", :attributes => { :href => '/projects/ecookbook/repository/revisions/0'}
-    }
-    assert_tag :tag => "div", :attributes => { :class => "contextual" },
-        :child => { :tag => "a", :attributes => { :href => '/projects/ecookbook/repository/revisions/2'}
-    }
-  end
-
-  def test_graph_commits_per_month
-    get :graph, :id => 1, :graph => 'commits_per_month'
-    assert_response :success
-    assert_equal 'image/svg+xml', @response.content_type
-  end
-
-  def test_graph_commits_per_author
-    get :graph, :id => 1, :graph => 'commits_per_author'
-    assert_response :success
-    assert_equal 'image/svg+xml', @response.content_type
-  end
-
-  def test_committers
-    @request.session[:user_id] = 2
-    # add a commit with an unknown user
-    Changeset.create!(
-        :repository => Project.find(1).repository,
-        :committer  => 'foo',
-        :committed_on => Time.now,
-        :revision => 100,
-        :comments => 'Committed by foo.'
-     )
-
-    get :committers, :id => 1
-    assert_response :success
-    assert_template 'committers'
-
-    assert_tag :td, :content => 'dlopper',
-                    :sibling => { :tag => 'td',
-                                  :child => { :tag => 'select', :attributes => { :name => %r{^committers\[\d+\]\[\]$} },
-                                                                :child => { :tag => 'option', :content => 'Dave Lopper',
-                                                                                              :attributes => { :value => '3', :selected => 'selected' }}}}
-    assert_tag :td, :content => 'foo',
-                    :sibling => { :tag => 'td',
-                                  :child => { :tag => 'select', :attributes => { :name => %r{^committers\[\d+\]\[\]$} }}}
-    assert_no_tag :td, :content => 'foo',
-                       :sibling => { :tag => 'td',
-                                     :descendant => { :tag => 'option', :attributes => { :selected => 'selected' }}}
-  end
-
-  def test_map_committers
-    @request.session[:user_id] = 2
-    # add a commit with an unknown user
-    c = Changeset.create!(
-            :repository => Project.find(1).repository,
-            :committer  => 'foo',
-            :committed_on => Time.now,
-            :revision => 100,
-            :comments => 'Committed by foo.'
-          )
-    assert_no_difference "Changeset.count(:conditions => 'user_id = 3')" do
-      post :committers, :id => 1, :committers => { '0' => ['foo', '2'], '1' => ['dlopper', '3']}
-      assert_redirected_to '/projects/ecookbook/repository/committers'
-      assert_equal User.find(2), c.reload.user
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8e/8ecc0cc6fb65096c2310818a0a3c62cfcc13f191.svn-base
--- a/.svn/pristine/8e/8ecc0cc6fb65096c2310818a0a3c62cfcc13f191.svn-base
+++ /dev/null
@@ -1,1006 +0,0 @@
-en:
-  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%m/%d/%Y"
-      short: "%b %d"
-      long: "%B %d, %Y"
-
-    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
-    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
-    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%m/%d/%Y %I:%M %p"
-      time: "%I:%M %p"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "am"
-    pm: "pm"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "half a minute"
-      less_than_x_seconds:
-        one:   "less than 1 second"
-        other: "less than %{count} seconds"
-      x_seconds:
-        one:   "1 second"
-        other: "%{count} seconds"
-      less_than_x_minutes:
-        one:   "less than a minute"
-        other: "less than %{count} minutes"
-      x_minutes:
-        one:   "1 minute"
-        other: "%{count} minutes"
-      about_x_hours:
-        one:   "about 1 hour"
-        other: "about %{count} hours"
-      x_days:
-        one:   "1 day"
-        other: "%{count} days"
-      about_x_months:
-        one:   "about 1 month"
-        other: "about %{count} months"
-      x_months:
-        one:   "1 month"
-        other: "%{count} months"
-      about_x_years:
-        one:   "about 1 year"
-        other: "about %{count} years"
-      over_x_years:
-        one:   "over 1 year"
-        other: "over %{count} years"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "kB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "and"
-      skip_last_comma: false
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "is not included in the list"
-        exclusion: "is reserved"
-        invalid: "is invalid"
-        confirmation: "doesn't match confirmation"
-        accepted: "must be accepted"
-        empty: "can't be empty"
-        blank: "can't be blank"
-        too_long: "is too long (maximum is %{count} characters)"
-        too_short: "is too short (minimum is %{count} characters)"
-        wrong_length: "is the wrong length (should be %{count} characters)"
-        taken: "has already been taken"
-        not_a_number: "is not a number"
-        not_a_date: "is not a valid date"
-        greater_than: "must be greater than %{count}"
-        greater_than_or_equal_to: "must be greater than or equal to %{count}"
-        equal_to: "must be equal to %{count}"
-        less_than: "must be less than %{count}"
-        less_than_or_equal_to: "must be less than or equal to %{count}"
-        odd: "must be odd"
-        even: "must be even"
-        greater_than_start_date: "must be greater than start date"
-        not_same_project: "doesn't belong to the same project"
-        circular_dependency: "This relation would create a circular dependency"
-        cant_link_an_issue_with_a_descendant: "An issue cannot be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: Please select
-
-  general_text_No: 'No'
-  general_text_Yes: 'Yes'
-  general_text_no: 'no'
-  general_text_yes: 'yes'
-  general_lang_name: 'English'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '7'
-
-  notice_account_updated: Account was successfully updated.
-  notice_account_invalid_creditentials: Invalid user or password
-  notice_account_password_updated: Password was successfully updated.
-  notice_account_wrong_password: Wrong password
-  notice_account_register_done: Account was successfully created. To activate your account, click on the link that was emailed to you.
-  notice_account_unknown_email: Unknown user.
-  notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
-  notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
-  notice_account_activated: Your account has been activated. You can now log in.
-  notice_successful_create: Successful creation.
-  notice_successful_update: Successful update.
-  notice_successful_delete: Successful deletion.
-  notice_successful_connection: Successful connection.
-  notice_file_not_found: The page you were trying to access doesn't exist or has been removed.
-  notice_locking_conflict: Data has been updated by another user.
-  notice_not_authorized: You are not authorized to access this page.
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  notice_email_sent: "An email was sent to %{value}"
-  notice_email_error: "An error occurred while sending mail (%{value})"
-  notice_feeds_access_key_reseted: Your RSS access key was reset.
-  notice_api_access_key_reseted: Your API access key was reset.
-  notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
-  notice_account_pending: "Your account was created and is now pending administrator approval."
-  notice_default_data_loaded: Default configuration successfully loaded.
-  notice_unable_delete_version: Unable to delete version.
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})"
-  notice_issue_successful_create: "Issue %{id} created."
-
-  error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
-  error_scm_not_found: "The entry or revision was not found in the repository."
-  error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
-  error_scm_annotate: "The entry does not exist or cannot be annotated."
-  error_scm_annotate_big_text_file: "The entry cannot be annotated, as it exceeds the maximum text file size."
-  error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
-  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
-  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_can_not_delete_tracker: "This tracker contains issues and cannot be deleted."
-  error_can_not_remove_role: "This role is in use and cannot be deleted."
-  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version cannot be reopened'
-  error_can_not_archive_project: This project cannot be archived
-  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
-  error_workflow_copy_source: 'Please select a source tracker or role'
-  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
-  error_unable_delete_issue_status: 'Unable to delete issue status'
-  error_unable_to_connect: "Unable to connect (%{value})"
-  error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})"
-  warning_attachments_not_saved: "%{count} file(s) could not be saved."
-
-  mail_subject_lost_password: "Your %{value} password"
-  mail_body_lost_password: 'To change your password, click on the following link:'
-  mail_subject_register: "Your %{value} account activation"
-  mail_body_register: 'To activate your account, click on the following link:'
-  mail_body_account_information_external: "You can use your %{value} account to log in."
-  mail_body_account_information: Your account information
-  mail_subject_account_activation_request: "%{value} account activation request"
-  mail_body_account_activation_request: "A new user (%{value}) has registered. The account is pending your approval:"
-  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
-  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
-
-  gui_validation_error: 1 error
-  gui_validation_error_plural: "%{count} errors"
-
-  field_name: Name
-  field_description: Description
-  field_summary: Summary
-  field_is_required: Required
-  field_firstname: First name
-  field_lastname: Last name
-  field_mail: Email
-  field_filename: File
-  field_filesize: Size
-  field_downloads: Downloads
-  field_author: Author
-  field_created_on: Created
-  field_updated_on: Updated
-  field_field_format: Format
-  field_is_for_all: For all projects
-  field_possible_values: Possible values
-  field_regexp: Regular expression
-  field_min_length: Minimum length
-  field_max_length: Maximum length
-  field_value: Value
-  field_category: Category
-  field_title: Title
-  field_project: Project
-  field_issue: Issue
-  field_status: Status
-  field_notes: Notes
-  field_is_closed: Issue closed
-  field_is_default: Default value
-  field_tracker: Tracker
-  field_subject: Subject
-  field_due_date: Due date
-  field_assigned_to: Assignee
-  field_priority: Priority
-  field_fixed_version: Target version
-  field_user: User
-  field_principal: Principal
-  field_role: Role
-  field_homepage: Homepage
-  field_is_public: Public
-  field_parent: Subproject of
-  field_is_in_roadmap: Issues displayed in roadmap
-  field_login: Login
-  field_mail_notification: Email notifications
-  field_admin: Administrator
-  field_last_login_on: Last connection
-  field_language: Language
-  field_effective_date: Date
-  field_password: Password
-  field_new_password: New password
-  field_password_confirmation: Confirmation
-  field_version: Version
-  field_type: Type
-  field_host: Host
-  field_port: Port
-  field_account: Account
-  field_base_dn: Base DN
-  field_attr_login: Login attribute
-  field_attr_firstname: Firstname attribute
-  field_attr_lastname: Lastname attribute
-  field_attr_mail: Email attribute
-  field_onthefly: On-the-fly user creation
-  field_start_date: Start date
-  field_done_ratio: "% Done"
-  field_auth_source: Authentication mode
-  field_hide_mail: Hide my email address
-  field_comments: Comment
-  field_url: URL
-  field_start_page: Start page
-  field_subproject: Subproject
-  field_hours: Hours
-  field_activity: Activity
-  field_spent_on: Date
-  field_identifier: Identifier
-  field_is_filter: Used as a filter
-  field_issue_to: Related issue
-  field_delay: Delay
-  field_assignable: Issues can be assigned to this role
-  field_redirect_existing_links: Redirect existing links
-  field_estimated_hours: Estimated time
-  field_column_names: Columns
-  field_time_entries: Log time
-  field_time_zone: Time zone
-  field_searchable: Searchable
-  field_default_value: Default value
-  field_comments_sorting: Display comments
-  field_parent_title: Parent page
-  field_editable: Editable
-  field_watcher: Watcher
-  field_identity_url: OpenID URL
-  field_content: Content
-  field_group_by: Group results by
-  field_sharing: Sharing
-  field_parent_issue: Parent task
-  field_member_of_group: "Assignee's group"
-  field_assigned_to_role: "Assignee's role"
-  field_text: Text field
-  field_visible: Visible
-  field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text"
-  field_issues_visibility: Issues visibility
-  field_is_private: Private
-  field_commit_logs_encoding: Commit messages encoding
-  field_scm_path_encoding: Path encoding
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvsroot: CVSROOT
-  field_cvs_module: Module
-
-  setting_app_title: Application title
-  setting_app_subtitle: Application subtitle
-  setting_welcome_text: Welcome text
-  setting_default_language: Default language
-  setting_login_required: Authentication required
-  setting_self_registration: Self-registration
-  setting_attachment_max_size: Maximum attachment size
-  setting_issues_export_limit: Issues export limit
-  setting_mail_from: Emission email address
-  setting_bcc_recipients: Blind carbon copy recipients (bcc)
-  setting_plain_text_mail: Plain text mail (no HTML)
-  setting_host_name: Host name and path
-  setting_text_formatting: Text formatting
-  setting_wiki_compression: Wiki history compression
-  setting_feeds_limit: Maximum number of items in Atom feeds
-  setting_default_projects_public: New projects are public by default
-  setting_autofetch_changesets: Fetch commits automatically
-  setting_sys_api_enabled: Enable WS for repository management
-  setting_commit_ref_keywords: Referencing keywords
-  setting_commit_fix_keywords: Fixing keywords
-  setting_autologin: Autologin
-  setting_date_format: Date format
-  setting_time_format: Time format
-  setting_cross_project_issue_relations: Allow cross-project issue relations
-  setting_issue_list_default_columns: Default columns displayed on the issue list
-  setting_repositories_encodings: Attachments and repositories encodings
-  setting_emails_header: Emails header
-  setting_emails_footer: Emails footer
-  setting_protocol: Protocol
-  setting_per_page_options: Objects per page options
-  setting_user_format: Users display format
-  setting_activity_days_default: Days displayed on project activity
-  setting_display_subprojects_issues: Display subprojects issues on main projects by default
-  setting_enabled_scm: Enabled SCM
-  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
-  setting_mail_handler_api_enabled: Enable WS for incoming emails
-  setting_mail_handler_api_key: API key
-  setting_sequential_project_identifiers: Generate sequential project identifiers
-  setting_gravatar_enabled: Use Gravatar user icons
-  setting_gravatar_default: Default Gravatar image
-  setting_diff_max_lines_displayed: Maximum number of diff lines displayed
-  setting_file_max_size_displayed: Maximum size of text files displayed inline
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_openid: Allow OpenID login and registration
-  setting_password_min_length: Minimum password length
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_field: Use the issue field
-  setting_issue_done_ratio_issue_status: Use the issue status
-  setting_start_of_week: Start calendars on
-  setting_rest_api_enabled: Enable REST web service
-  setting_cache_formatted_text: Cache formatted text
-  setting_default_notification_option: Default notification option
-  setting_commit_logtime_enabled: Enable time logging
-  setting_commit_logtime_activity_id: Activity for logged time
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  setting_issue_group_assignment: Allow issue assignment to groups
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-
-  permission_add_project: Create project
-  permission_add_subprojects: Create subprojects
-  permission_edit_project: Edit project
-  permission_select_project_modules: Select project modules
-  permission_manage_members: Manage members
-  permission_manage_project_activities: Manage project activities
-  permission_manage_versions: Manage versions
-  permission_manage_categories: Manage issue categories
-  permission_view_issues: View Issues
-  permission_add_issues: Add issues
-  permission_edit_issues: Edit issues
-  permission_manage_issue_relations: Manage issue relations
-  permission_set_issues_private: Set issues public or private
-  permission_set_own_issues_private: Set own issues public or private
-  permission_add_issue_notes: Add notes
-  permission_edit_issue_notes: Edit notes
-  permission_edit_own_issue_notes: Edit own notes
-  permission_move_issues: Move issues
-  permission_delete_issues: Delete issues
-  permission_manage_public_queries: Manage public queries
-  permission_save_queries: Save queries
-  permission_view_gantt: View gantt chart
-  permission_view_calendar: View calendar
-  permission_view_issue_watchers: View watchers list
-  permission_add_issue_watchers: Add watchers
-  permission_delete_issue_watchers: Delete watchers
-  permission_log_time: Log spent time
-  permission_view_time_entries: View spent time
-  permission_edit_time_entries: Edit time logs
-  permission_edit_own_time_entries: Edit own time logs
-  permission_manage_news: Manage news
-  permission_comment_news: Comment news
-  permission_manage_documents: Manage documents
-  permission_view_documents: View documents
-  permission_manage_files: Manage files
-  permission_view_files: View files
-  permission_manage_wiki: Manage wiki
-  permission_rename_wiki_pages: Rename wiki pages
-  permission_delete_wiki_pages: Delete wiki pages
-  permission_view_wiki_pages: View wiki
-  permission_view_wiki_edits: View wiki history
-  permission_edit_wiki_pages: Edit wiki pages
-  permission_delete_wiki_pages_attachments: Delete attachments
-  permission_protect_wiki_pages: Protect wiki pages
-  permission_manage_repository: Manage repository
-  permission_browse_repository: Browse repository
-  permission_view_changesets: View changesets
-  permission_commit_access: Commit access
-  permission_manage_boards: Manage forums
-  permission_view_messages: View messages
-  permission_add_messages: Post messages
-  permission_edit_messages: Edit messages
-  permission_edit_own_messages: Edit own messages
-  permission_delete_messages: Delete messages
-  permission_delete_own_messages: Delete own messages
-  permission_export_wiki_pages: Export wiki pages
-  permission_manage_subtasks: Manage subtasks
-
-  project_module_issue_tracking: Issue tracking
-  project_module_time_tracking: Time tracking
-  project_module_news: News
-  project_module_documents: Documents
-  project_module_files: Files
-  project_module_wiki: Wiki
-  project_module_repository: Repository
-  project_module_boards: Forums
-  project_module_calendar: Calendar
-  project_module_gantt: Gantt
-
-  label_user: User
-  label_user_plural: Users
-  label_user_new: New user
-  label_user_anonymous: Anonymous
-  label_project: Project
-  label_project_new: New project
-  label_project_plural: Projects
-  label_x_projects:
-    zero:  no projects
-    one:   1 project
-    other: "%{count} projects"
-  label_project_all: All Projects
-  label_project_latest: Latest projects
-  label_issue: Issue
-  label_issue_new: New issue
-  label_issue_plural: Issues
-  label_issue_view_all: View all issues
-  label_issues_by: "Issues by %{value}"
-  label_issue_added: Issue added
-  label_issue_updated: Issue updated
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_document: Document
-  label_document_new: New document
-  label_document_plural: Documents
-  label_document_added: Document added
-  label_role: Role
-  label_role_plural: Roles
-  label_role_new: New role
-  label_role_and_permissions: Roles and permissions
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_member: Member
-  label_member_new: New member
-  label_member_plural: Members
-  label_tracker: Tracker
-  label_tracker_plural: Trackers
-  label_tracker_new: New tracker
-  label_workflow: Workflow
-  label_issue_status: Issue status
-  label_issue_status_plural: Issue statuses
-  label_issue_status_new: New status
-  label_issue_category: Issue category
-  label_issue_category_plural: Issue categories
-  label_issue_category_new: New category
-  label_custom_field: Custom field
-  label_custom_field_plural: Custom fields
-  label_custom_field_new: New custom field
-  label_enumerations: Enumerations
-  label_enumeration_new: New value
-  label_information: Information
-  label_information_plural: Information
-  label_please_login: Please log in
-  label_register: Register
-  label_login_with_open_id_option: or login with OpenID
-  label_password_lost: Lost password
-  label_home: Home
-  label_my_page: My page
-  label_my_account: My account
-  label_my_projects: My projects
-  label_my_page_block: My page block
-  label_administration: Administration
-  label_login: Sign in
-  label_logout: Sign out
-  label_help: Help
-  label_reported_issues: Reported issues
-  label_assigned_to_me_issues: Issues assigned to me
-  label_last_login: Last connection
-  label_registered_on: Registered on
-  label_activity: Activity
-  label_overall_activity: Overall activity
-  label_user_activity: "%{value}'s activity"
-  label_new: New
-  label_logged_as: Logged in as
-  label_environment: Environment
-  label_authentication: Authentication
-  label_auth_source: Authentication mode
-  label_auth_source_new: New authentication mode
-  label_auth_source_plural: Authentication modes
-  label_subproject_plural: Subprojects
-  label_subproject_new: New subproject
-  label_and_its_subprojects: "%{value} and its subprojects"
-  label_min_max_length: Min - Max length
-  label_list: List
-  label_date: Date
-  label_integer: Integer
-  label_float: Float
-  label_boolean: Boolean
-  label_string: Text
-  label_text: Long text
-  label_attribute: Attribute
-  label_attribute_plural: Attributes
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
-  label_no_data: No data to display
-  label_change_status: Change status
-  label_history: History
-  label_attachment: File
-  label_attachment_new: New file
-  label_attachment_delete: Delete file
-  label_attachment_plural: Files
-  label_file_added: File added
-  label_report: Report
-  label_report_plural: Reports
-  label_news: News
-  label_news_new: Add news
-  label_news_plural: News
-  label_news_latest: Latest news
-  label_news_view_all: View all news
-  label_news_added: News added
-  label_news_comment_added: Comment added to a news
-  label_settings: Settings
-  label_overview: Overview
-  label_version: Version
-  label_version_new: New version
-  label_version_plural: Versions
-  label_close_versions: Close completed versions
-  label_confirmation: Confirmation
-  label_export_to: 'Also available in:'
-  label_read: Read...
-  label_public_projects: Public projects
-  label_open_issues: open
-  label_open_issues_plural: open
-  label_closed_issues: closed
-  label_closed_issues_plural: closed
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_total: Total
-  label_permissions: Permissions
-  label_current_status: Current status
-  label_new_statuses_allowed: New statuses allowed
-  label_all: all
-  label_none: none
-  label_nobody: nobody
-  label_next: Next
-  label_previous: Previous
-  label_used_by: Used by
-  label_details: Details
-  label_add_note: Add a note
-  label_per_page: Per page
-  label_calendar: Calendar
-  label_months_from: months from
-  label_gantt: Gantt
-  label_internal: Internal
-  label_last_changes: "last %{count} changes"
-  label_change_view_all: View all changes
-  label_personalize_page: Personalize this page
-  label_comment: Comment
-  label_comment_plural: Comments
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_comment_add: Add a comment
-  label_comment_added: Comment added
-  label_comment_delete: Delete comments
-  label_query: Custom query
-  label_query_plural: Custom queries
-  label_query_new: New query
-  label_my_queries: My custom queries
-  label_filter_add: Add filter
-  label_filter_plural: Filters
-  label_equals: is
-  label_not_equals: is not
-  label_in_less_than: in less than
-  label_in_more_than: in more than
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_between: between
-  label_in: in
-  label_today: today
-  label_all_time: all time
-  label_yesterday: yesterday
-  label_this_week: this week
-  label_last_week: last week
-  label_last_n_days: "last %{count} days"
-  label_this_month: this month
-  label_last_month: last month
-  label_this_year: this year
-  label_date_range: Date range
-  label_less_than_ago: less than days ago
-  label_more_than_ago: more than days ago
-  label_ago: days ago
-  label_contains: contains
-  label_not_contains: doesn't contain
-  label_day_plural: days
-  label_repository: Repository
-  label_repository_plural: Repositories
-  label_browse: Browse
-  label_modification: "%{count} change"
-  label_modification_plural: "%{count} changes"
-  label_branch: Branch
-  label_tag: Tag
-  label_revision: Revision
-  label_revision_plural: Revisions
-  label_revision_id: "Revision %{value}"
-  label_associated_revisions: Associated revisions
-  label_added: added
-  label_modified: modified
-  label_copied: copied
-  label_renamed: renamed
-  label_deleted: deleted
-  label_latest_revision: Latest revision
-  label_latest_revision_plural: Latest revisions
-  label_view_revisions: View revisions
-  label_view_all_revisions: View all revisions
-  label_max_size: Maximum size
-  label_sort_highest: Move to top
-  label_sort_higher: Move up
-  label_sort_lower: Move down
-  label_sort_lowest: Move to bottom
-  label_roadmap: Roadmap
-  label_roadmap_due_in: "Due in %{value}"
-  label_roadmap_overdue: "%{value} late"
-  label_roadmap_no_issues: No issues for this version
-  label_search: Search
-  label_result_plural: Results
-  label_all_words: All words
-  label_wiki: Wiki
-  label_wiki_edit: Wiki edit
-  label_wiki_edit_plural: Wiki edits
-  label_wiki_page: Wiki page
-  label_wiki_page_plural: Wiki pages
-  label_index_by_title: Index by title
-  label_index_by_date: Index by date
-  label_current_version: Current version
-  label_preview: Preview
-  label_feed_plural: Feeds
-  label_changes_details: Details of all changes
-  label_issue_tracking: Issue tracking
-  label_spent_time: Spent time
-  label_overall_spent_time: Overall spent time
-  label_f_hour: "%{value} hour"
-  label_f_hour_plural: "%{value} hours"
-  label_time_tracking: Time tracking
-  label_change_plural: Changes
-  label_statistics: Statistics
-  label_commits_per_month: Commits per month
-  label_commits_per_author: Commits per author
-  label_diff: diff
-  label_view_diff: View differences
-  label_diff_inline: inline
-  label_diff_side_by_side: side by side
-  label_options: Options
-  label_copy_workflow_from: Copy workflow from
-  label_permissions_report: Permissions report
-  label_watched_issues: Watched issues
-  label_related_issues: Related issues
-  label_applied_status: Applied status
-  label_loading: Loading...
-  label_relation_new: New relation
-  label_relation_delete: Delete relation
-  label_relates_to: related to
-  label_duplicates: duplicates
-  label_duplicated_by: duplicated by
-  label_blocks: blocks
-  label_blocked_by: blocked by
-  label_precedes: precedes
-  label_follows: follows
-  label_end_to_start: end to start
-  label_end_to_end: end to end
-  label_start_to_start: start to start
-  label_start_to_end: start to end
-  label_stay_logged_in: Stay logged in
-  label_disabled: disabled
-  label_show_completed_versions: Show completed versions
-  label_me: me
-  label_board: Forum
-  label_board_new: New forum
-  label_board_plural: Forums
-  label_board_locked: Locked
-  label_board_sticky: Sticky
-  label_topic_plural: Topics
-  label_message_plural: Messages
-  label_message_last: Last message
-  label_message_new: New message
-  label_message_posted: Message added
-  label_reply_plural: Replies
-  label_send_information: Send account information to the user
-  label_year: Year
-  label_month: Month
-  label_week: Week
-  label_date_from: From
-  label_date_to: To
-  label_language_based: Based on user's language
-  label_sort_by: "Sort by %{value}"
-  label_send_test_email: Send a test email
-  label_feeds_access_key: RSS access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  label_feeds_access_key_created_on: "RSS access key created %{value} ago"
-  label_module_plural: Modules
-  label_added_time_by: "Added by %{author} %{age} ago"
-  label_updated_time_by: "Updated by %{author} %{age} ago"
-  label_updated_time: "Updated %{value} ago"
-  label_jump_to_a_project: Jump to a project...
-  label_file_plural: Files
-  label_changeset_plural: Changesets
-  label_default_columns: Default columns
-  label_no_change_option: (No change)
-  label_bulk_edit_selected_issues: Bulk edit selected issues
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  label_theme: Theme
-  label_default: Default
-  label_search_titles_only: Search titles only
-  label_user_mail_option_all: "For any event on all my projects"
-  label_user_mail_option_selected: "For any event on the selected projects only..."
-  label_user_mail_option_none: "No events"
-  label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
-  label_user_mail_option_only_assigned: "Only for things I am assigned to"
-  label_user_mail_option_only_owner: "Only for things I am the owner of"
-  label_user_mail_no_self_notified: "I don't want to be notified of changes that I make myself"
-  label_registration_activation_by_email: account activation by email
-  label_registration_manual_activation: manual account activation
-  label_registration_automatic_activation: automatic account activation
-  label_display_per_page: "Per page: %{value}"
-  label_age: Age
-  label_change_properties: Change properties
-  label_general: General
-  label_more: More
-  label_scm: SCM
-  label_plugins: Plugins
-  label_ldap_authentication: LDAP authentication
-  label_downloads_abbr: D/L
-  label_optional_description: Optional description
-  label_add_another_file: Add another file
-  label_preferences: Preferences
-  label_chronological_order: In chronological order
-  label_reverse_chronological_order: In reverse chronological order
-  label_planning: Planning
-  label_incoming_emails: Incoming emails
-  label_generate_key: Generate a key
-  label_issue_watchers: Watchers
-  label_example: Example
-  label_display: Display
-  label_sort: Sort
-  label_ascending: Ascending
-  label_descending: Descending
-  label_date_from_to: From %{start} to %{end}
-  label_wiki_content_added: Wiki page added
-  label_wiki_content_updated: Wiki page updated
-  label_group: Group
-  label_group_plural: Groups
-  label_group_new: New group
-  label_time_entry_plural: Spent time
-  label_version_sharing_none: Not shared
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_tree: With project tree
-  label_version_sharing_system: With all projects
-  label_update_issue_done_ratios: Update issue done ratios
-  label_copy_source: Source
-  label_copy_target: Target
-  label_copy_same_as_target: Same as target
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_api_access_key: API access key
-  label_missing_api_access_key: Missing an API access key
-  label_api_access_key_created_on: "API access key created %{value} ago"
-  label_profile: Profile
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_issues_visibility_all: All issues
-  label_issues_visibility_public: All non private issues
-  label_issues_visibility_own: Issues created by or assigned to the user
-  label_git_report_last_commit: Report last commit for files and directories
-  label_parent_revision: Parent
-  label_child_revision: Child
-  label_export_options: %{export_format} export options
-
-  button_login: Login
-  button_submit: Submit
-  button_save: Save
-  button_check_all: Check all
-  button_uncheck_all: Uncheck all
-  button_collapse_all: Collapse all
-  button_expand_all: Expand all
-  button_delete: Delete
-  button_create: Create
-  button_create_and_continue: Create and continue
-  button_test: Test
-  button_edit: Edit
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  button_add: Add
-  button_change: Change
-  button_apply: Apply
-  button_clear: Clear
-  button_lock: Lock
-  button_unlock: Unlock
-  button_download: Download
-  button_list: List
-  button_view: View
-  button_move: Move
-  button_move_and_follow: Move and follow
-  button_back: Back
-  button_cancel: Cancel
-  button_activate: Activate
-  button_sort: Sort
-  button_log_time: Log time
-  button_rollback: Rollback to this version
-  button_watch: Watch
-  button_unwatch: Unwatch
-  button_reply: Reply
-  button_archive: Archive
-  button_unarchive: Unarchive
-  button_reset: Reset
-  button_rename: Rename
-  button_change_password: Change password
-  button_copy: Copy
-  button_copy_and_follow: Copy and follow
-  button_annotate: Annotate
-  button_update: Update
-  button_configure: Configure
-  button_quote: Quote
-  button_duplicate: Duplicate
-  button_show: Show
-  button_edit_section: Edit this section
-  button_export: Export
-
-  status_active: active
-  status_registered: registered
-  status_locked: locked
-
-  version_status_open: open
-  version_status_locked: locked
-  version_status_closed: closed
-
-  field_active: Active
-
-  text_select_mail_notifications: Select actions for which email notifications should be sent.
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 means no restriction
-  text_project_destroy_confirmation: Are you sure you want to delete this project and related data?
-  text_subprojects_destroy_warning: "Its subproject(s): %{value} will be also deleted."
-  text_workflow_edit: Select a role and a tracker to edit the workflow
-  text_are_you_sure: Are you sure?
-  text_are_you_sure_with_children: "Delete issue and all child issues?"
-  text_journal_changed: "%{label} changed from %{old} to %{new}"
-  text_journal_changed_no_detail: "%{label} updated"
-  text_journal_set_to: "%{label} set to %{value}"
-  text_journal_deleted: "%{label} deleted (%{old})"
-  text_journal_added: "%{label} %{value} added"
-  text_tip_issue_begin_day: issue beginning this day
-  text_tip_issue_end_day: issue ending this day
-  text_tip_issue_begin_end_day: issue beginning and ending this day
-  text_project_identifier_info: 'Only lower case letters (a-z), numbers and dashes are allowed.<br />Once saved, the identifier cannot be changed.'
-  text_caracters_maximum: "%{count} characters maximum."
-  text_caracters_minimum: "Must be at least %{count} characters long."
-  text_length_between: "Length between %{min} and %{max} characters."
-  text_tracker_no_workflow: No workflow defined for this tracker
-  text_unallowed_characters: Unallowed characters
-  text_comma_separated: Multiple values allowed (comma separated).
-  text_line_separated: Multiple values allowed (one line for each value).
-  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
-  text_issue_added: "Issue %{id} has been reported by %{author}."
-  text_issue_updated: "Issue %{id} has been updated by %{author}."
-  text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content?
-  text_issue_category_destroy_question: "Some issues (%{count}) are assigned to this category. What do you want to do?"
-  text_issue_category_destroy_assignments: Remove category assignments
-  text_issue_category_reassign_to: Reassign issues to this category
-  text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
-  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
-  text_load_default_configuration: Load the default configuration
-  text_status_changed_by_changeset: "Applied in changeset %{value}."
-  text_time_logged_by_changeset: "Applied in changeset %{value}."
-  text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?'
-  text_issues_destroy_descendants_confirmation: "This will also delete %{count} subtask(s)."
-  text_time_entries_destroy_confirmation: 'Are you sure you want to delete the selected time entr(y/ies)?'
-  text_select_project_modules: 'Select modules to enable for this project:'
-  text_default_administrator_account_changed: Default administrator account changed
-  text_file_repository_writable: Attachments directory writable
-  text_plugin_assets_writable: Plugin assets directory writable
-  text_rmagick_available: RMagick available (optional)
-  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do?"
-  text_destroy_time_entries: Delete reported hours
-  text_assign_time_entries_to_project: Assign reported hours to the project
-  text_reassign_time_entries: 'Reassign reported hours to this issue:'
-  text_user_wrote: "%{value} wrote:"
-  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
-  text_enumeration_category_reassign_to: 'Reassign them to this value:'
-  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
-  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
-  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
-  text_custom_field_possible_values_info: 'One line for each value'
-  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
-  text_wiki_page_nullify_children: "Keep child pages as root pages"
-  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
-  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
-  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
-  text_zoom_in: Zoom in
-  text_zoom_out: Zoom out
-  text_warn_on_leaving_unsaved: "The current page contains unsaved text that will be lost if you leave this page."
-  text_scm_path_encoding_note: "Default: UTF-8"
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-
-  default_role_manager: Manager
-  default_role_developer: Developer
-  default_role_reporter: Reporter
-  default_tracker_bug: Bug
-  default_tracker_feature: Feature
-  default_tracker_support: Support
-  default_issue_status_new: New
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: Resolved
-  default_issue_status_feedback: Feedback
-  default_issue_status_closed: Closed
-  default_issue_status_rejected: Rejected
-  default_doc_category_user: User documentation
-  default_doc_category_tech: Technical documentation
-  default_priority_low: Low
-  default_priority_normal: Normal
-  default_priority_high: High
-  default_priority_urgent: Urgent
-  default_priority_immediate: Immediate
-  default_activity_design: Design
-  default_activity_development: Development
-
-  enumeration_issue_priorities: Issue priorities
-  enumeration_doc_categories: Document categories
-  enumeration_activities: Activities (time tracking)
-  enumeration_system_activity: System Activity
-  description_filter: Filter
-  description_search: Searchfield
-  description_choose_project: Projects
-  description_project_scope: Search scope
-  description_notes: Notes
-  description_message_content: Message content
-  description_query_sort_criteria_attribute: Sort attribute
-  description_query_sort_criteria_direction: Sort direction
-  description_user_mail_notification: Mail notification settings
-  description_available_columns: Available Columns
-  description_selected_columns: Selected Columns
-  description_all_columns: All Columns
-  description_issue_category_reassign: Choose issue category
-  description_wiki_subpages_reassign: Choose new parent page
-  description_date_range_list: Choose range from list
-  description_date_range_interval: Choose range by selecting start and end date
-  description_date_from: Enter start date
-  description_date_to: Enter end date
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8f/8f432f3794bad71b8b15d0a2b9eb0bdfa9179a1e.svn-base
--- /dev/null
+++ b/.svn/pristine/8f/8f432f3794bad71b8b15d0a2b9eb0bdfa9179a1e.svn-base
@@ -0,0 +1,13 @@
+class SerializePossiblesValues < ActiveRecord::Migration
+  def self.up
+    CustomField.all.each do |field|
+      if field.possible_values and field.possible_values.is_a? String
+        field.possible_values = field.possible_values.split('|')
+        field.save
+      end
+    end
+  end
+
+  def self.down
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8f/8f5abebaf46b05ea9363b87c5e571fe76d603cd6.svn-base
--- a/.svn/pristine/8f/8f5abebaf46b05ea9363b87c5e571fe76d603cd6.svn-base
+++ /dev/null
@@ -1,272 +0,0 @@
-              GNU GENERAL PUBLIC LICENSE
-                Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street,
-Fifth Floor, Boston, MA  02110-1301  USA Everyone is permitted to copy and
-distribute verbatim copies of this license document, but changing it is not
-allowed.
-
-               Preamble
-
-The licenses for most software are designed to take away your freedom to
-share and change it.  By contrast, the GNU General Public License is
-intended to guarantee your freedom to share and change free software--to
-make sure the software is free for all its users.  This General Public
-License applies to most of the Free Software Foundation's software and to
-any other program whose authors commit to using it.  (Some other Free
-Software Foundation software is covered by the GNU Lesser General Public
-License instead.)  You can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price.  Our
-General Public Licenses are designed to make sure that you have the freedom
-to distribute copies of free software (and charge for this service if you
-wish), that you receive source code or can get it if you want it, that you
-can change the software or use pieces of it in new free programs; and that
-you know you can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to
-deny you these rights or to ask you to surrender the rights. These
-restrictions translate to certain responsibilities for you if you distribute
-copies of the software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or
-for a fee, you must give the recipients all the rights that you have.  You
-must make sure that they, too, receive or can get the source code.  And you
-must show them these terms so they know their rights.
-
-We protect your rights with two steps: (1) copyright the software, and (2)
-offer you this license which gives you legal permission to copy, distribute
-and/or modify the software.
-
-Also, for each author's protection and ours, we want to make certain that
-everyone understands that there is no warranty for this free software.  If
-the software is modified by someone else and passed on, we want its
-recipients to know that what they have is not the original, so that any
-problems introduced by others will not reflect on the original authors'
-reputations.
-
-Finally, any free program is threatened constantly by software patents.  We
-wish to avoid the danger that redistributors of a free program will
-individually obtain patent licenses, in effect making the program
-proprietary. To prevent this, we have made it clear that any patent must be
-licensed for everyone's free use or not licensed at all.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
-           GNU GENERAL PUBLIC LICENSE
-  TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
-   placed by the copyright holder saying it may be distributed under the
-   terms of this General Public License.  The "Program", below, refers to
-   any such program or work, and a "work based on the Program" means either
-   the Program or any derivative work under copyright law: that is to say, a
-   work containing the Program or a portion of it, either verbatim or with
-   modifications and/or translated into another language.  (Hereinafter,
-   translation is included without limitation in the term "modification".)
-   Each licensee is addressed as "you".
-
-   Activities other than copying, distribution and modification are not
-   covered by this License; they are outside its scope.  The act of running
-   the Program is not restricted, and the output from the Program is covered
-   only if its contents constitute a work based on the Program (independent
-   of having been made by running the Program). Whether that is true depends
-   on what the Program does.
-
-1. You may copy and distribute verbatim copies of the Program's source code
-   as you receive it, in any medium, provided that you conspicuously and
-   appropriately publish on each copy an appropriate copyright notice and
-   disclaimer of warranty; keep intact all the notices that refer to this
-   License and to the absence of any warranty; and give any other recipients
-   of the Program a copy of this License along with the Program.
-
-   You may charge a fee for the physical act of transferring a copy, and you
-   may at your option offer warranty protection in exchange for a fee.
-
-2. You may modify your copy or copies of the Program or any portion of it,
-   thus forming a work based on the Program, and copy and distribute such
-   modifications or work under the terms of Section 1 above, provided that
-   you also meet all of these conditions:
-
-   a) You must cause the modified files to carry prominent notices stating
-      that you changed the files and the date of any change.
-
-   b) You must cause any work that you distribute or publish, that in whole
-      or in part contains or is derived from the Program or any part
-      thereof, to be licensed as a whole at no charge to all third parties
-      under the terms of this License.
-
-   c) If the modified program normally reads commands interactively when
-      run, you must cause it, when started running for such interactive use
-      in the most ordinary way, to print or display an announcement
-      including an appropriate copyright notice and a notice that there is
-      no warranty (or else, saying that you provide a warranty) and that
-      users may redistribute the program under these conditions, and telling
-      the user how to view a copy of this License.  (Exception: if the
-      Program itself is interactive but does not normally print such an
-      announcement, your work based on the Program is not required to print
-      an announcement.)
-
-   These requirements apply to the modified work as a whole.  If
-   identifiable sections of that work are not derived from the Program, and
-   can be reasonably considered independent and separate works in
-   themselves, then this License, and its terms, do not apply to those
-   sections when you distribute them as separate works.  But when you
-   distribute the same sections as part of a whole which is a work based on
-   the Program, the distribution of the whole must be on the terms of this
-   License, whose permissions for other licensees extend to the entire
-   whole, and thus to each and every part regardless of who wrote it.
-
-   Thus, it is not the intent of this section to claim rights or contest
-   your rights to work written entirely by you; rather, the intent is to
-   exercise the right to control the distribution of derivative or
-   collective works based on the Program.
-
-   In addition, mere aggregation of another work not based on the Program
-   with the Program (or with a work based on the Program) on a volume of a
-   storage or distribution medium does not bring the other work under the
-   scope of this License.
-
-3. You may copy and distribute the Program (or a work based on it, under
-   Section 2) in object code or executable form under the terms of Sections
-   1 and 2 above provided that you also do one of the following:
-
-   a) Accompany it with the complete corresponding machine-readable source
-      code, which must be distributed under the terms of Sections 1 and 2
-      above on a medium customarily used for software interchange; or,
-
-   b) Accompany it with a written offer, valid for at least three years, to
-      give any third party, for a charge no more than your cost of
-      physically performing source distribution, a complete machine-readable
-      copy of the corresponding source code, to be distributed under the
-      terms of Sections 1 and 2 above on a medium customarily used for
-      software interchange; or,
-
-   c) Accompany it with the information you received as to the offer to
-      distribute corresponding source code.  (This alternative is allowed
-      only for noncommercial distribution and only if you received the
-      program in object code or executable form with such an offer, in
-      accord with Subsection b above.)
-
-   The source code for a work means the preferred form of the work for
-   making modifications to it.  For an executable work, complete source code
-   means all the source code for all modules it contains, plus any
-   associated interface definition files, plus the scripts used to control
-   compilation and installation of the executable.  However, as a special
-   exception, the source code distributed need not include anything that is
-   normally distributed (in either source or binary form) with the major
-   components (compiler, kernel, and so on) of the operating system on which
-   the executable runs, unless that component itself accompanies the
-   executable.
-
-   If distribution of executable or object code is made by offering access
-   to copy from a designated place, then offering equivalent access to copy
-   the source code from the same place counts as distribution of the source
-   code, even though third parties are not compelled to copy the source
-   along with the object code.
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
-   expressly provided under this License.  Any attempt otherwise to copy,
-   modify, sublicense or distribute the Program is void, and will
-   automatically terminate your rights under this License. However, parties
-   who have received copies, or rights, from you under this License will not
-   have their licenses terminated so long as such parties remain in full
-   compliance.
-
-5. You are not required to accept this License, since you have not signed
-   it.  However, nothing else grants you permission to modify or distribute
-   the Program or its derivative works.  These actions are prohibited by law
-   if you do not accept this License.  Therefore, by modifying or
-   distributing the Program (or any work based on the Program), you indicate
-   your acceptance of this License to do so, and all its terms and
-   conditions for copying, distributing or modifying the Program or works
-   based on it.
-
-6. Each time you redistribute the Program (or any work based on the
-   Program), the recipient automatically receives a license from the
-   original licensor to copy, distribute or modify the Program subject to
-   these terms and conditions.  You may not impose any further restrictions
-   on the recipients' exercise of the rights granted herein. You are not
-   responsible for enforcing compliance by third parties to this License.
-
-7. If, as a consequence of a court judgment or allegation of patent
-   infringement or for any other reason (not limited to patent issues),
-   conditions are imposed on you (whether by court order, agreement or
-   otherwise) that contradict the conditions of this License, they do not
-   excuse you from the conditions of this License.  If you cannot distribute
-   so as to satisfy simultaneously your obligations under this License and
-   any other pertinent obligations, then as a consequence you may not
-   distribute the Program at all.  For example, if a patent license would
-   not permit royalty-free redistribution of the Program by all those who
-   receive copies directly or indirectly through you, then the only way you
-   could satisfy both it and this License would be to refrain entirely from
-   distribution of the Program.
-
-   If any portion of this section is held invalid or unenforceable under any
-   particular circumstance, the balance of the section is intended to apply
-   and the section as a whole is intended to apply in other circumstances.
-
-   It is not the purpose of this section to induce you to infringe any
-   patents or other property right claims or to contest validity of any such
-   claims; this section has the sole purpose of protecting the integrity of
-   the free software distribution system, which is implemented by public
-   license practices.  Many people have made generous contributions to the
-   wide range of software distributed through that system in reliance on
-   consistent application of that system; it is up to the author/donor to
-   decide if he or she is willing to distribute software through any other
-   system and a licensee cannot impose that choice.
-
-   This section is intended to make thoroughly clear what is believed to be
-   a consequence of the rest of this License.
-
-8. If the distribution and/or use of the Program is restricted in certain
-   countries either by patents or by copyrighted interfaces, the original
-   copyright holder who places the Program under this License may add an
-   explicit geographical distribution limitation excluding those countries,
-   so that distribution is permitted only in or among countries not thus
-   excluded. In such case, this License incorporates the limitation as if
-   written in the body of this License.
-
-9. The Free Software Foundation may publish revised and/or new versions of
-   the General Public License from time to time.  Such new versions will be
-   similar in spirit to the present version, but may differ in detail to
-   address new problems or concerns.
-
-   Each version is given a distinguishing version number.  If the Program
-   specifies a version number of this License which applies to it and "any
-   later version", you have the option of following the terms and conditions
-   either of that version or of any later version published by the Free
-   Software Foundation.  If the Program does not specify a version number of
-   this License, you may choose any version ever published by the Free
-   Software Foundation.
-
-10. If you wish to incorporate parts of the Program into other free programs
-    whose distribution conditions are different, write to the author to ask
-    for permission.  For software which is copyrighted by the Free Software
-    Foundation, write to the Free Software Foundation; we sometimes make
-    exceptions for this.  Our decision will be guided by the two goals of
-    preserving the free status of all derivatives of our free software and
-    of promoting the sharing and reuse of software generally.
-
-                     NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
-    THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-    OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-    PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
-    EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE
-    ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
-    YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
-    NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-    REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
-    DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
-    DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
-    (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
-    INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
-    THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
-    OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8f/8fab8bad5548597e2bb52ca9f6f7be91ab5dd36f.svn-base
--- a/.svn/pristine/8f/8fab8bad5548597e2bb52ca9f6f7be91ab5dd36f.svn-base
+++ /dev/null
@@ -1,41 +0,0 @@
-Return-Path: <jsmith@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
-Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
-From: "John Smith" <jsmith@somenet.foo>
-To: <redmine@somenet.foo>
-Subject: New ticket with custom field values
-Date: Sun, 22 Jun 2008 12:28:07 +0200
-MIME-Version: 1.0
-Content-Type: text/plain;
-	format=flowed;
-	charset="iso-8859-1";
-	reply-type=original
-Content-Transfer-Encoding: 7bit
-X-Priority: 3
-X-MSMail-Priority: Normal
-X-Mailer: Microsoft Outlook Express 6.00.2900.2869
-X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet 
-turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus 
-blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti 
-sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In 
-in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras 
-sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum 
-id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus 
-eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique 
-sed, mauris. Pellentesque habitant morbi tristique senectus et netus et 
-malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
-platea dictumst.
-
-Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque 
-sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. 
-Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, 
-dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed, 
-massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo 
-pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
-
-category: Stock management
-searchable field: Value for a custom field
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8f/8fb8c91bbe844bae557a6ef1733a0e0c0a18defa.svn-base
--- a/.svn/pristine/8f/8fb8c91bbe844bae557a6ef1733a0e0c0a18defa.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class Namespace::AppAndPluginController < ApplicationController
-  def an_action
-    render_class_and_action 'from alpha_plugin'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8f/8fbc301faf7d97e6e0f02d9274582bd98672c254.svn-base
--- /dev/null
+++ b/.svn/pristine/8f/8fbc301faf7d97e6e0f02d9274582bd98672c254.svn-base
@@ -0,0 +1,598 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../../test_helper', __FILE__)
+begin
+  require 'mocha'
+
+  class GitAdapterTest < ActiveSupport::TestCase
+    REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
+
+    FELIX_HEX  = "Felix Sch\xC3\xA4fer"
+    CHAR_1_HEX = "\xc3\x9c"
+
+    ## Git, Mercurial and CVS path encodings are binary.
+    ## Subversion supports URL encoding for path.
+    ## Redmine Mercurial adapter and extension use URL encoding.
+    ## Git accepts only binary path in command line parameter.
+    ## So, there is no way to use binary command line parameter in JRuby.
+    JRUBY_SKIP     = (RUBY_PLATFORM == 'java')
+    JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
+
+    if File.directory?(REPOSITORY_PATH)
+      ## Ruby uses ANSI api to fork a process on Windows.
+      ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
+      ## and these are incompatible with ASCII.
+      ## Git for Windows (msysGit) changed internal API from ANSI to Unicode in 1.7.10
+      ## http://code.google.com/p/msysgit/issues/detail?id=80
+      ## So, Latin-1 path tests fail on Japanese Windows
+      WINDOWS_PASS = (Redmine::Platform.mswin? &&
+                      Redmine::Scm::Adapters::GitAdapter.client_version_above?([1, 7, 10]))
+      WINDOWS_SKIP_STR = "TODO: This test fails in Git for Windows above 1.7.10"
+
+      def setup
+        adapter_class = Redmine::Scm::Adapters::GitAdapter
+        assert adapter_class
+        assert adapter_class.client_command
+        assert_equal true, adapter_class.client_available
+        assert_equal true, adapter_class.client_version_above?([1])
+        assert_equal true, adapter_class.client_version_above?([1, 0])
+
+        @adapter = Redmine::Scm::Adapters::GitAdapter.new(
+                      REPOSITORY_PATH,
+                      nil,
+                      nil,
+                      nil,
+                      'ISO-8859-1'
+                   )
+        assert @adapter
+        @char_1 = CHAR_1_HEX.dup
+        if @char_1.respond_to?(:force_encoding)
+          @char_1.force_encoding('UTF-8')
+        end
+      end
+
+      def test_scm_version
+        to_test = { "git version 1.7.3.4\n"             => [1,7,3,4],
+                    "1.6.1\n1.7\n1.8"                   => [1,6,1],
+                    "1.6.2\r\n1.8.1\r\n1.9.1"           => [1,6,2]}
+        to_test.each do |s, v|
+          test_scm_version_for(s, v)
+        end
+      end
+
+      def test_branches
+        brs = []
+        @adapter.branches.each do |b|
+          brs << b
+        end
+        assert_equal 6, brs.length
+        br_issue_8857 = brs[0]
+        assert_equal 'issue-8857', br_issue_8857.to_s 
+        assert_equal '2a682156a3b6e77a8bf9cd4590e8db757f3c6c78', br_issue_8857.revision
+        assert_equal br_issue_8857.scmid, br_issue_8857.revision
+        assert_equal false, br_issue_8857.is_default
+        br_latin_1_path = brs[1]
+        assert_equal 'latin-1-path-encoding', br_latin_1_path.to_s 
+        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', br_latin_1_path.revision
+        assert_equal br_latin_1_path.scmid, br_latin_1_path.revision
+        assert_equal false, br_latin_1_path.is_default
+        br_master = brs[2]
+        assert_equal 'master', br_master.to_s
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', br_master.revision
+        assert_equal br_master.scmid, br_master.revision
+        assert_equal false, br_master.is_default
+        br_master_20120212 = brs[3]
+        assert_equal 'master-20120212', br_master_20120212.to_s
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', br_master_20120212.revision
+        assert_equal br_master_20120212.scmid, br_master_20120212.revision
+        assert_equal true, br_master_20120212.is_default
+        br_latin_1 = brs[-2]
+        assert_equal 'test-latin-1', br_latin_1.to_s
+        assert_equal '67e7792ce20ccae2e4bb73eed09bb397819c8834', br_latin_1.revision
+        assert_equal br_latin_1.scmid, br_latin_1.revision
+        assert_equal false, br_latin_1.is_default
+        br_test = brs[-1]
+        assert_equal 'test_branch', br_test.to_s
+        assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', br_test.revision
+        assert_equal br_test.scmid, br_test.revision
+        assert_equal false, br_test.is_default
+      end
+
+      def test_default_branch
+        assert_equal 'master-20120212', @adapter.default_branch
+      end
+
+      def test_tags
+        assert_equal  [
+              "tag00.lightweight",
+              "tag01.annotated",
+            ], @adapter.tags
+      end
+
+      def test_revisions_master_all
+        revs1 = []
+        @adapter.revisions('', nil, "master",{}) do |rev|
+          revs1 << rev
+        end
+        assert_equal 15, revs1.length
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 0].identifier
+        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier
+
+        revs2 = []
+        @adapter.revisions('', nil, "master",
+                           {:reverse => true}) do |rev|
+          revs2 << rev
+        end
+        assert_equal 15, revs2.length
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier
+        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier
+      end
+
+      def test_revisions_master_merged_rev
+        revs1 = []
+        @adapter.revisions('',
+                           "713f4944648826f558cf548222f813dabe7cbb04",
+                           "master",
+                           {:reverse => true}) do |rev|
+          revs1 << rev
+        end
+        assert_equal 8, revs1.length
+        assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', revs1[ 0].identifier
+        assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 1].identifier
+        # 4a07fe31b is not a child of 713f49446
+        assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 2].identifier
+        # Merged revision
+        assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 3].identifier
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier
+
+        revs2 = []
+        @adapter.revisions('',
+                           "fba357b886984ee71185ad2065e65fc0417d9b92",
+                           "master",
+                           {:reverse => true}) do |rev|
+          revs2 << rev
+        end
+        assert_equal 7, revs2.length
+        assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs2[ 0].identifier
+        # 4a07fe31b is not a child of fba357b8869
+        assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs2[ 1].identifier
+        # Merged revision
+        assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs2[ 2].identifier
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier
+      end
+
+      def test_revisions_branch_latin_1_path_encoding_all
+        revs1 = []
+        @adapter.revisions('', nil, "latin-1-path-encoding",{}) do |rev|
+          revs1 << rev
+        end
+        assert_equal 8, revs1.length
+        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[ 0].identifier
+        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier
+
+        revs2 = []
+        @adapter.revisions('', nil, "latin-1-path-encoding",
+                           {:reverse => true}) do |rev|
+          revs2 << rev
+        end
+        assert_equal 8, revs2.length
+        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier
+        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier
+      end
+
+      def test_revisions_branch_latin_1_path_encoding_with_rev
+        revs1 = []
+        @adapter.revisions('',
+                           '7234cb2750b63f47bff735edc50a1c0a433c2518',
+                           "latin-1-path-encoding",
+                           {:reverse => true}) do |rev|
+          revs1 << rev
+        end
+        assert_equal 7, revs1.length
+        assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 0].identifier
+        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier
+
+        revs2 = []
+        @adapter.revisions('',
+                           '57ca437c0acbbcb749821fdf3726a1367056d364',
+                           "latin-1-path-encoding",
+                           {:reverse => true}) do |rev|
+          revs2 << rev
+        end
+        assert_equal 3, revs2.length
+        assert_equal '4fc55c43bf3d3dc2efb66145365ddc17639ce81e', revs2[ 0].identifier
+        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier
+      end
+
+      def test_revisions_invalid_rev
+        assert_equal [], @adapter.revisions('', '1234abcd', "master")
+        assert_raise Redmine::Scm::Adapters::CommandFailed do
+          revs1 = []
+          @adapter.revisions('',
+                           '1234abcd',
+                           "master",
+                           {:reverse => true}) do |rev|
+            revs1 << rev
+          end
+        end
+      end
+
+      def test_revisions_includes_master_two_revs
+        revs1 = []
+        @adapter.revisions('', nil, nil,
+                           {:reverse => true,
+                            :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'],
+                            :excludes => ['4f26664364207fa8b1af9f8722647ab2d4ac5d43']}) do |rev|
+          revs1 << rev
+        end
+        assert_equal 2, revs1.length
+        assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier
+      end
+
+      def test_revisions_includes_master_two_revs_from_origin
+        revs1 = []
+        @adapter.revisions('', nil, nil,
+                           {:reverse => true,
+                            :includes => ['899a15dba03a3b350b89c3f537e4bbe02a03cdc9'],
+                            :excludes => []}) do |rev|
+          revs1 << rev
+        end
+        assert_equal 2, revs1.length
+        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[ 0].identifier
+        assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 1].identifier
+      end
+
+      def test_revisions_includes_merged_revs
+        revs1 = []
+        @adapter.revisions('', nil, nil,
+                           {:reverse => true,
+                            :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'],
+                            :excludes => ['fba357b886984ee71185ad2065e65fc0417d9b92']}) do |rev|
+          revs1 << rev
+        end
+        assert_equal 7, revs1.length
+        assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 0].identifier
+        assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 1].identifier
+        assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 2].identifier
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier
+      end
+
+      def test_revisions_includes_two_heads
+        revs1 = []
+        @adapter.revisions('', nil, nil,
+                           {:reverse => true,
+                            :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c',
+                                          '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127'],
+                            :excludes => ['4f26664364207fa8b1af9f8722647ab2d4ac5d43',
+                                          '4fc55c43bf3d3dc2efb66145365ddc17639ce81e']}) do |rev|
+          revs1 << rev
+        end
+        assert_equal 4, revs1.length
+        assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 1].identifier
+        assert_equal '64f1f3e89ad1cb57976ff0ad99a107012ba3481d', revs1[-2].identifier
+        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier
+      end
+
+      def test_revisions_disjointed_histories_revisions
+        revs1 = []
+        @adapter.revisions('', nil, nil,
+                           {:reverse => true,
+                            :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c',
+                                          '92397af84d22f27389c822848ecd5b463c181583'],
+                            :excludes => ['95488a44bc25f7d1f97d775a31359539ff333a63',
+                                          '4f26664364207fa8b1af9f8722647ab2d4ac5d43'] }) do |rev|
+          revs1 << rev
+        end
+        assert_equal 4, revs1.length
+        assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier
+        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 1].identifier
+        assert_equal 'bc201c95999c4f10d018b0aa03b541cd6a2ff0ee', revs1[-2].identifier
+        assert_equal '92397af84d22f27389c822848ecd5b463c181583', revs1[-1].identifier
+      end
+
+      def test_revisions_invalid_rev_excludes
+        assert_equal [],
+                     @adapter.revisions('', nil, nil,
+                                        {:reverse => true,
+                                         :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'],
+                                         :excludes => ['0123abcd4567']})
+        assert_raise Redmine::Scm::Adapters::CommandFailed do
+          revs1 = []
+          @adapter.revisions('', nil, nil,
+                             {:reverse => true,
+                              :includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'],
+                              :excludes => ['0123abcd4567']}) do |rev|
+            revs1 << rev
+          end
+        end
+      end
+
+      def test_getting_revisions_with_spaces_in_filename
+        assert_equal 1, @adapter.revisions("filemane with spaces.txt",
+                                           nil, "master").length
+      end
+
+      def test_parents
+        revs1 = []
+        @adapter.revisions('',
+                           nil,
+                           "master",
+                           {:reverse => true}) do |rev|
+          revs1 << rev
+        end
+        assert_equal 15, revs1.length
+        assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
+                     revs1[0].identifier
+        assert_equal nil, revs1[0].parents
+        assert_equal "899a15dba03a3b350b89c3f537e4bbe02a03cdc9",
+                     revs1[1].identifier
+        assert_equal 1, revs1[1].parents.length
+        assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
+                     revs1[1].parents[0]
+        assert_equal "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
+                     revs1[10].identifier
+        assert_equal 2, revs1[10].parents.length
+        assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8",
+                     revs1[10].parents[0]
+        assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da",
+                     revs1[10].parents[1]
+      end
+
+      def test_getting_revisions_with_leading_and_trailing_spaces_in_filename
+        assert_equal " filename with a leading space.txt ",
+           @adapter.revisions(" filename with a leading space.txt ",
+                               nil, "master")[0].paths[0][:path]
+      end
+
+      def test_getting_entries_with_leading_and_trailing_spaces_in_filename
+        assert_equal " filename with a leading space.txt ",
+           @adapter.entries('',
+                   '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c')[3].name
+      end
+
+      def test_annotate
+        annotate = @adapter.annotate('sources/watchers_controller.rb')
+        assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
+        assert_equal 41, annotate.lines.size
+        assert_equal "# This program is free software; you can redistribute it and/or",
+                     annotate.lines[4].strip
+        assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
+                      annotate.revisions[4].identifier
+        assert_equal "jsmith", annotate.revisions[4].author
+      end
+
+      def test_annotate_moved_file
+        annotate = @adapter.annotate('renamed_test.txt')
+        assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
+        assert_equal 2, annotate.lines.size
+      end
+
+      def test_last_rev
+        last_rev = @adapter.lastrev("README",
+                                    "4f26664364207fa8b1af9f8722647ab2d4ac5d43")
+        assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.scmid
+        assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.identifier
+        assert_equal "Adam Soltys <asoltys@gmail.com>", last_rev.author
+        assert_equal "2009-06-24 05:27:38".to_time, last_rev.time
+      end
+
+      def test_last_rev_with_spaces_in_filename
+        last_rev = @adapter.lastrev("filemane with spaces.txt",
+                                    "ed5bb786bbda2dee66a2d50faf51429dbc043a7b")
+        str_felix_hex  = FELIX_HEX.dup
+        last_rev_author = last_rev.author
+        if last_rev_author.respond_to?(:force_encoding)
+          str_felix_hex.force_encoding('ASCII-8BIT')
+        end
+        assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.scmid
+        assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.identifier
+        assert_equal "#{str_felix_hex} <felix@fachschaften.org>",
+                       last_rev.author
+        assert_equal "2010-09-18 19:59:46".to_time, last_rev.time
+      end
+
+      def test_latin_1_path
+        if WINDOWS_PASS
+          puts WINDOWS_SKIP_STR
+        elsif JRUBY_SKIP
+          puts JRUBY_SKIP_STR
+        else
+          p2 = "latin-1-dir/test-#{@char_1}-2.txt"
+          ['4fc55c43bf3d3dc2efb66145365ddc17639ce81e', '4fc55c43bf3'].each do |r1|
+            assert @adapter.diff(p2, r1)
+            assert @adapter.cat(p2, r1)
+            assert_equal 1, @adapter.annotate(p2, r1).lines.length
+            ['64f1f3e89ad1cb57976ff0ad99a107012ba3481d', '64f1f3e89ad1cb5797'].each do |r2|
+              assert @adapter.diff(p2, r1, r2)
+            end
+          end
+        end
+      end
+
+      def test_entries_tag
+        entries1 = @adapter.entries(nil, 'tag01.annotated',
+                                    options = {:report_last_commit => true})
+        assert entries1
+        assert_equal 3, entries1.size
+        assert_equal 'sources', entries1[1].name
+        assert_equal 'sources', entries1[1].path
+        assert_equal 'dir', entries1[1].kind
+        readme = entries1[2]
+        assert_equal 'README', readme.name
+        assert_equal 'README', readme.path
+        assert_equal 'file', readme.kind
+        assert_equal 27, readme.size
+        assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', readme.lastrev.identifier
+        assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time
+      end
+
+      def test_entries_branch
+        entries1 = @adapter.entries(nil, 'test_branch',
+                                    options = {:report_last_commit => true})
+        assert entries1
+        assert_equal 4, entries1.size
+        assert_equal 'sources', entries1[1].name
+        assert_equal 'sources', entries1[1].path
+        assert_equal 'dir', entries1[1].kind
+        readme = entries1[2]
+        assert_equal 'README', readme.name
+        assert_equal 'README', readme.path
+        assert_equal 'file', readme.kind
+        assert_equal 159, readme.size
+        assert_equal '713f4944648826f558cf548222f813dabe7cbb04', readme.lastrev.identifier
+        assert_equal Time.gm(2009, 6, 19, 4, 37, 23), readme.lastrev.time
+      end
+
+      def test_entries_wrong_path_encoding
+        adpt = Redmine::Scm::Adapters::GitAdapter.new(
+                      REPOSITORY_PATH,
+                      nil,
+                      nil,
+                      nil,
+                      'EUC-JP'
+                   )
+        entries1 = adpt.entries('latin-1-dir', '64f1f3e8')
+        assert entries1
+        assert_equal 3, entries1.size
+        f1 = entries1[1]
+        assert_equal nil, f1.name
+        assert_equal nil, f1.path
+        assert_equal 'file', f1.kind
+      end
+
+      def test_entries_latin_1_files
+        entries1 = @adapter.entries('latin-1-dir', '64f1f3e8')
+        assert entries1
+        assert_equal 3, entries1.size
+        f1 = entries1[1]
+        assert_equal "test-#{@char_1}-2.txt", f1.name
+        assert_equal "latin-1-dir/test-#{@char_1}-2.txt", f1.path
+        assert_equal 'file', f1.kind
+      end
+
+      def test_entries_latin_1_dir
+        if WINDOWS_PASS
+          puts WINDOWS_SKIP_STR
+        elsif JRUBY_SKIP
+          puts JRUBY_SKIP_STR
+        else
+          entries1 = @adapter.entries("latin-1-dir/test-#{@char_1}-subdir",
+                                      '1ca7f5ed')
+          assert entries1
+          assert_equal 3, entries1.size
+          f1 = entries1[1]
+          assert_equal "test-#{@char_1}-2.txt", f1.name
+          assert_equal "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-2.txt", f1.path
+          assert_equal 'file', f1.kind
+        end
+      end
+
+      def test_entry
+        entry = @adapter.entry()
+        assert_equal "", entry.path
+        assert_equal "dir", entry.kind
+        entry = @adapter.entry('')
+        assert_equal "", entry.path
+        assert_equal "dir", entry.kind
+        assert_nil @adapter.entry('invalid')
+        assert_nil @adapter.entry('/invalid')
+        assert_nil @adapter.entry('/invalid/')
+        assert_nil @adapter.entry('invalid/invalid')
+        assert_nil @adapter.entry('invalid/invalid/')
+        assert_nil @adapter.entry('/invalid/invalid')
+        assert_nil @adapter.entry('/invalid/invalid/')
+        ["README", "/README"].each do |path|
+          entry = @adapter.entry(path, '7234cb2750b63f')
+          assert_equal "README", entry.path
+          assert_equal "file", entry.kind
+        end
+        ["sources", "/sources", "/sources/"].each do |path|
+          entry = @adapter.entry(path, '7234cb2750b63f')
+          assert_equal "sources", entry.path
+          assert_equal "dir", entry.kind
+        end
+        ["sources/watchers_controller.rb", "/sources/watchers_controller.rb"].each do |path|
+          entry = @adapter.entry(path, '7234cb2750b63f')
+          assert_equal "sources/watchers_controller.rb", entry.path
+          assert_equal "file", entry.kind
+        end
+      end
+
+      def test_path_encoding_default_utf8
+        adpt1 = Redmine::Scm::Adapters::GitAdapter.new(
+                                  REPOSITORY_PATH
+                                )
+        assert_equal "UTF-8", adpt1.path_encoding
+        adpt2 = Redmine::Scm::Adapters::GitAdapter.new(
+                                  REPOSITORY_PATH,
+                                  nil,
+                                  nil,
+                                  nil,
+                                  ""
+                                )
+        assert_equal "UTF-8", adpt2.path_encoding
+      end
+
+      def test_cat_path_invalid
+        assert_nil @adapter.cat('invalid')
+      end
+
+      def test_cat_revision_invalid
+        assert     @adapter.cat('README')
+        assert_nil @adapter.cat('README', '1234abcd5678')
+      end
+
+      def test_diff_path_invalid
+        assert_equal [], @adapter.diff('invalid', '713f4944648826f5')
+      end
+
+      def test_diff_revision_invalid
+        assert_nil @adapter.diff(nil, '1234abcd5678')
+        assert_nil @adapter.diff(nil, '713f4944648826f5', '1234abcd5678')
+        assert_nil @adapter.diff(nil, '1234abcd5678', '713f4944648826f5')
+      end
+
+      def test_annotate_path_invalid
+        assert_nil @adapter.annotate('invalid')
+      end
+
+      def test_annotate_revision_invalid
+        assert     @adapter.annotate('README')
+        assert_nil @adapter.annotate('README', '1234abcd5678')
+      end
+
+      private
+
+      def test_scm_version_for(scm_command_version, version)
+        @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
+        assert_equal version, @adapter.class.scm_command_version
+      end
+
+    else
+      puts "Git test repository NOT FOUND. Skipping unit tests !!!"
+      def test_fake; assert true end
+    end
+  end
+
+rescue LoadError
+  class GitMochaFake < ActiveSupport::TestCase
+    def test_fake; assert(false, "Requires mocha to run those tests")  end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/8f/8ff149ff1d20e6444addb19f8ffbc048ac4ee186.svn-base
--- a/.svn/pristine/8f/8ff149ff1d20e6444addb19f8ffbc048ac4ee186.svn-base
+++ /dev/null
@@ -1,10 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class <%= class_name %>Test < ActiveSupport::TestCase
-  fixtures :<%= table_name %>
-
-  # Replace this with your real tests.
-  def test_truth
-    assert true
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/90/90192eda43870194632f3513168a40626db1c032.svn-base
--- a/.svn/pristine/90/90192eda43870194632f3513168a40626db1c032.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-class CreateExtras < ActiveRecord::Migration
-  def self.up
-    create_table 'extras' do |t|
-      t.column 'name', :string
-    end
-  end
-
-  def self.down
-    drop_table 'extras'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/90/90614dcc50db90b38ba908659a9cd6e4367e61ab.svn-base
--- /dev/null
+++ b/.svn/pristine/90/90614dcc50db90b38ba908659a9cd6e4367e61ab.svn-base
@@ -0,0 +1,62 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'net/pop'
+
+module Redmine
+  module POP3
+    class << self
+      def check(pop_options={}, options={})
+        host = pop_options[:host] || '127.0.0.1'
+        port = pop_options[:port] || '110'
+        apop = (pop_options[:apop].to_s == '1')
+        delete_unprocessed = (pop_options[:delete_unprocessed].to_s == '1')
+
+        pop = Net::POP3.APOP(apop).new(host,port)
+        logger.debug "Connecting to #{host}..." if logger && logger.debug?
+        pop.start(pop_options[:username], pop_options[:password]) do |pop_session|
+          if pop_session.mails.empty?
+            logger.debug "No email to process" if logger && logger.debug?
+          else
+            logger.debug "#{pop_session.mails.size} email(s) to process..." if logger && logger.debug?
+            pop_session.each_mail do |msg|
+              message = msg.pop
+              message_id = (message =~ /^Message-I[dD]: (.*)/ ? $1 : '').strip
+              if MailHandler.receive(message, options)
+                msg.delete
+                logger.debug "--> Message #{message_id} processed and deleted from the server" if logger && logger.debug?
+              else
+                if delete_unprocessed
+                  msg.delete
+                  logger.debug "--> Message #{message_id} NOT processed and deleted from the server" if logger && logger.debug?
+                else
+                  logger.debug "--> Message #{message_id} NOT processed and left on the server" if logger && logger.debug?
+                end
+              end
+            end
+          end
+        end
+      end
+
+      private
+
+      def logger
+        ::Rails.logger
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/90/908fcd6bc49463f5895a572d6459e39dd9b6f64e.svn-base
--- /dev/null
+++ b/.svn/pristine/90/908fcd6bc49463f5895a572d6459e39dd9b6f64e.svn-base
@@ -0,0 +1,468 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#require 'shoulda'
+ENV["RAILS_ENV"] = "test"
+require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
+require 'rails/test_help'
+require Rails.root.join('test', 'mocks', 'open_id_authentication_mock.rb').to_s
+
+require File.expand_path(File.dirname(__FILE__) + '/object_helpers')
+include ObjectHelpers
+
+class ActiveSupport::TestCase
+  include ActionDispatch::TestProcess
+
+  self.use_transactional_fixtures = true
+  self.use_instantiated_fixtures  = false
+
+  def log_user(login, password)
+    User.anonymous
+    get "/login"
+    assert_equal nil, session[:user_id]
+    assert_response :success
+    assert_template "account/login"
+    post "/login", :username => login, :password => password
+    assert_equal login, User.find(session[:user_id]).login
+  end
+
+  def uploaded_test_file(name, mime)
+    fixture_file_upload("files/#{name}", mime, true)
+  end
+
+  def credentials(user, password=nil)
+    {'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)}
+  end
+
+  # Mock out a file
+  def self.mock_file
+    file = 'a_file.png'
+    file.stubs(:size).returns(32)
+    file.stubs(:original_filename).returns('a_file.png')
+    file.stubs(:content_type).returns('image/png')
+    file.stubs(:read).returns(false)
+    file
+  end
+
+  def mock_file
+    self.class.mock_file
+  end
+
+  def mock_file_with_options(options={})
+    file = ''
+    file.stubs(:size).returns(32)
+    original_filename = options[:original_filename] || nil
+    file.stubs(:original_filename).returns(original_filename)
+    content_type = options[:content_type] || nil
+    file.stubs(:content_type).returns(content_type)
+    file.stubs(:read).returns(false)
+    file
+  end
+
+  # Use a temporary directory for attachment related tests
+  def set_tmp_attachments_directory
+    Dir.mkdir "#{Rails.root}/tmp/test" unless File.directory?("#{Rails.root}/tmp/test")
+    unless File.directory?("#{Rails.root}/tmp/test/attachments")
+      Dir.mkdir "#{Rails.root}/tmp/test/attachments"
+    end
+    Attachment.storage_path = "#{Rails.root}/tmp/test/attachments"
+  end
+
+  def set_fixtures_attachments_directory
+    Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
+  end
+
+  def with_settings(options, &block)
+    saved_settings = options.keys.inject({}) do |h, k|
+      h[k] = case Setting[k]
+        when Symbol, false, true, nil
+          Setting[k]
+        else
+          Setting[k].dup
+        end
+      h
+    end
+    options.each {|k, v| Setting[k] = v}
+    yield
+  ensure
+    saved_settings.each {|k, v| Setting[k] = v} if saved_settings
+  end
+
+  # Yields the block with user as the current user
+  def with_current_user(user, &block)
+    saved_user = User.current
+    User.current = user
+    yield
+  ensure
+    User.current = saved_user
+  end
+
+  def change_user_password(login, new_password)
+    user = User.first(:conditions => {:login => login})
+    user.password, user.password_confirmation = new_password, new_password
+    user.save!
+  end
+
+  def self.ldap_configured?
+    @test_ldap = Net::LDAP.new(:host => '127.0.0.1', :port => 389)
+    return @test_ldap.bind
+  rescue Exception => e
+    # LDAP is not listening
+    return nil
+  end
+
+  def self.convert_installed?
+    Redmine::Thumbnail.convert_available?
+  end
+
+  # Returns the path to the test +vendor+ repository
+  def self.repository_path(vendor)
+    Rails.root.join("tmp/test/#{vendor.downcase}_repository").to_s
+  end
+
+  # Returns the url of the subversion test repository
+  def self.subversion_repository_url
+    path = repository_path('subversion')
+    path = '/' + path unless path.starts_with?('/')
+    "file://#{path}"
+  end
+
+  # Returns true if the +vendor+ test repository is configured
+  def self.repository_configured?(vendor)
+    File.directory?(repository_path(vendor))
+  end
+
+  def repository_path_hash(arr)
+    hs = {}
+    hs[:path]  = arr.join("/")
+    hs[:param] = arr.join("/")
+    hs
+  end
+
+  def assert_save(object)
+    saved = object.save
+    message = "#{object.class} could not be saved"
+    errors = object.errors.full_messages.map {|m| "- #{m}"}
+    message << ":\n#{errors.join("\n")}" if errors.any?
+    assert_equal true, saved, message
+  end
+
+  def assert_error_tag(options={})
+    assert_tag({:attributes => { :id => 'errorExplanation' }}.merge(options))
+  end
+
+  def assert_include(expected, s, message=nil)
+    assert s.include?(expected), (message || "\"#{expected}\" not found in \"#{s}\"")
+  end
+
+  def assert_not_include(expected, s)
+    assert !s.include?(expected), "\"#{expected}\" found in \"#{s}\""
+  end
+
+  def assert_select_in(text, *args, &block)
+    d = HTML::Document.new(CGI::unescapeHTML(String.new(text))).root
+    assert_select(d, *args, &block)
+  end
+
+  def assert_mail_body_match(expected, mail)
+    if expected.is_a?(String)
+      assert_include expected, mail_body(mail)
+    else
+      assert_match expected, mail_body(mail)
+    end
+  end
+
+  def assert_mail_body_no_match(expected, mail)
+    if expected.is_a?(String)
+      assert_not_include expected, mail_body(mail)
+    else
+      assert_no_match expected, mail_body(mail)
+    end
+  end
+
+  def mail_body(mail)
+    mail.parts.first.body.encoded
+  end
+end
+
+module Redmine
+  module ApiTest
+    # Base class for API tests
+    class Base < ActionDispatch::IntegrationTest
+      # Test that a request allows the three types of API authentication
+      #
+      # * HTTP Basic with username and password
+      # * HTTP Basic with an api key for the username
+      # * Key based with the key=X parameter
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_api_authentication(http_method, url, parameters={}, options={})
+        should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters, options)
+        should_allow_http_basic_auth_with_key(http_method, url, parameters, options)
+        should_allow_key_based_auth(http_method, url, parameters, options)
+      end
+    
+      # Test that a request allows the username and password for HTTP BASIC
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters={}, options={})
+        success_code = options[:success_code] || :success
+        failure_code = options[:failure_code] || :unauthorized
+    
+        context "should allow http basic auth using a username and password for #{http_method} #{url}" do
+          context "with a valid HTTP authentication" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+                user.password = 'my_password'
+              end
+              send(http_method, url, parameters, credentials(@user.login, 'my_password'))
+            end
+    
+            should_respond_with success_code
+            should_respond_with_content_type_based_on_url(url)
+            should "login as the user" do
+              assert_equal @user, User.current
+            end
+          end
+    
+          context "with an invalid HTTP authentication" do
+            setup do
+              @user = User.generate!
+              send(http_method, url, parameters, credentials(@user.login, 'wrong_password'))
+            end
+    
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "not login as the user" do
+              assert_equal User.anonymous, User.current
+            end
+          end
+    
+          context "without credentials" do
+            setup do
+              send(http_method, url, parameters)
+            end
+    
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "include_www_authenticate_header" do
+              assert @controller.response.headers.has_key?('WWW-Authenticate')
+            end
+          end
+        end
+      end
+    
+      # Test that a request allows the API key with HTTP BASIC
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_http_basic_auth_with_key(http_method, url, parameters={}, options={})
+        success_code = options[:success_code] || :success
+        failure_code = options[:failure_code] || :unauthorized
+    
+        context "should allow http basic auth with a key for #{http_method} #{url}" do
+          context "with a valid HTTP authentication using the API token" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+              end
+              @token = Token.create!(:user => @user, :action => 'api')
+              send(http_method, url, parameters, credentials(@token.value, 'X'))
+            end
+            should_respond_with success_code
+            should_respond_with_content_type_based_on_url(url)
+            should_be_a_valid_response_string_based_on_url(url)
+            should "login as the user" do
+              assert_equal @user, User.current
+            end
+          end
+    
+          context "with an invalid HTTP authentication" do
+            setup do
+              @user = User.generate!
+              @token = Token.create!(:user => @user, :action => 'feeds')
+              send(http_method, url, parameters, credentials(@token.value, 'X'))
+            end
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "not login as the user" do
+              assert_equal User.anonymous, User.current
+            end
+          end
+        end
+      end
+    
+      # Test that a request allows full key authentication
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url, without the key=ZXY parameter
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_key_based_auth(http_method, url, parameters={}, options={})
+        success_code = options[:success_code] || :success
+        failure_code = options[:failure_code] || :unauthorized
+    
+        context "should allow key based auth using key=X for #{http_method} #{url}" do
+          context "with a valid api token" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+              end
+              @token = Token.create!(:user => @user, :action => 'api')
+              # Simple url parse to add on ?key= or &key=
+              request_url = if url.match(/\?/)
+                              url + "&key=#{@token.value}"
+                            else
+                              url + "?key=#{@token.value}"
+                            end
+              send(http_method, request_url, parameters)
+            end
+            should_respond_with success_code
+            should_respond_with_content_type_based_on_url(url)
+            should_be_a_valid_response_string_based_on_url(url)
+            should "login as the user" do
+              assert_equal @user, User.current
+            end
+          end
+    
+          context "with an invalid api token" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+              end
+              @token = Token.create!(:user => @user, :action => 'feeds')
+              # Simple url parse to add on ?key= or &key=
+              request_url = if url.match(/\?/)
+                              url + "&key=#{@token.value}"
+                            else
+                              url + "?key=#{@token.value}"
+                            end
+              send(http_method, request_url, parameters)
+            end
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "not login as the user" do
+              assert_equal User.anonymous, User.current
+            end
+          end
+        end
+    
+        context "should allow key based auth using X-Redmine-API-Key header for #{http_method} #{url}" do
+          setup do
+            @user = User.generate! do |user|
+              user.admin = true
+            end
+            @token = Token.create!(:user => @user, :action => 'api')
+            send(http_method, url, parameters, {'X-Redmine-API-Key' => @token.value.to_s})
+          end
+          should_respond_with success_code
+          should_respond_with_content_type_based_on_url(url)
+          should_be_a_valid_response_string_based_on_url(url)
+          should "login as the user" do
+            assert_equal @user, User.current
+          end
+        end
+      end
+    
+      # Uses should_respond_with_content_type based on what's in the url:
+      #
+      # '/project/issues.xml' => should_respond_with_content_type :xml
+      # '/project/issues.json' => should_respond_with_content_type :json
+      #
+      # @param [String] url Request
+      def self.should_respond_with_content_type_based_on_url(url)
+        case
+        when url.match(/xml/i)
+          should "respond with XML" do
+            assert_equal 'application/xml', @response.content_type
+          end
+        when url.match(/json/i)
+          should "respond with JSON" do
+            assert_equal 'application/json', @response.content_type
+          end
+        else
+          raise "Unknown content type for should_respond_with_content_type_based_on_url: #{url}"
+        end
+      end
+    
+      # Uses the url to assert which format the response should be in
+      #
+      # '/project/issues.xml' => should_be_a_valid_xml_string
+      # '/project/issues.json' => should_be_a_valid_json_string
+      #
+      # @param [String] url Request
+      def self.should_be_a_valid_response_string_based_on_url(url)
+        case
+        when url.match(/xml/i)
+          should_be_a_valid_xml_string
+        when url.match(/json/i)
+          should_be_a_valid_json_string
+        else
+          raise "Unknown content type for should_be_a_valid_response_based_on_url: #{url}"
+        end
+      end
+    
+      # Checks that the response is a valid JSON string
+      def self.should_be_a_valid_json_string
+        should "be a valid JSON string (or empty)" do
+          assert(response.body.blank? || ActiveSupport::JSON.decode(response.body))
+        end
+      end
+    
+      # Checks that the response is a valid XML string
+      def self.should_be_a_valid_xml_string
+        should "be a valid XML string" do
+          assert REXML::Document.new(response.body)
+        end
+      end
+    
+      def self.should_respond_with(status)
+        should "respond with #{status}" do
+          assert_response status
+        end
+      end
+    end
+  end
+end
+
+# URL helpers do not work with config.threadsafe!
+# https://github.com/rspec/rspec-rails/issues/476#issuecomment-4705454
+ActionView::TestCase::TestController.instance_eval do
+  helper Rails.application.routes.url_helpers
+end
+ActionView::TestCase::TestController.class_eval do
+  def _routes
+    Rails.application.routes
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/90/90c3161ff42555f1df222a4b974da7fd497f306d.svn-base
--- /dev/null
+++ b/.svn/pristine/90/90c3161ff42555f1df222a4b974da7fd497f306d.svn-base
@@ -0,0 +1,45 @@
+<div class="contextual">
+<%= link_to l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add' %>
+</div>
+
+<h2><%=l(:label_project_plural)%></h2>
+
+<%= form_tag({}, :method => :get) do %>
+<fieldset><legend><%= l(:label_filter_plural) %></legend>
+<label for='status'><%= l(:field_status) %> :</label>
+<%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;"  %>
+<label for='name'><%= l(:label_project) %>:</label>
+<%= text_field_tag 'name', params[:name], :size => 30 %>
+<%= submit_tag l(:button_apply), :class => "small", :name => nil %>
+<%= link_to l(:button_clear), {:controller => 'admin', :action => 'projects'}, :class => 'icon icon-reload' %>
+</fieldset>
+<% end %>
+&nbsp;
+
+<div class="autoscroll">
+<table class="list">
+  <thead><tr>
+  <th><%=l(:label_project)%></th>
+  <th><%=l(:field_is_public)%></th>
+  <th><%=l(:field_created_on)%></th>
+  <th></th>
+  </tr></thead>
+  <tbody>
+<% project_tree(@projects) do |project, level| %>
+  <tr class="<%= cycle("odd", "even") %> <%= project.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
+  <td class="name"><span><%= link_to_project_settings(project, {}, :title => project.short_description) %></span></td>
+  <td align="center"><%= checked_image project.is_public? %></td>
+  <td align="center"><%= format_date(project.created_on) %></td>
+  <td class="buttons">
+    <%= link_to(l(:button_archive), { :controller => 'projects', :action => 'archive', :id => project, :status => params[:status] }, :data => {:confirm => l(:text_are_you_sure)}, :method => :post, :class => 'icon icon-lock') unless project.archived? %>
+    <%= link_to(l(:button_unarchive), { :controller => 'projects', :action => 'unarchive', :id => project, :status => params[:status] }, :method => :post, :class => 'icon icon-unlock') if project.archived? && (project.parent.nil? || !project.parent.archived?) %>
+    <%= link_to(l(:button_copy), { :controller => 'projects', :action => 'copy', :id => project }, :class => 'icon icon-copy') %>
+    <%= link_to(l(:button_delete), project_path(project), :method => :delete, :class => 'icon icon-del') %>
+  </td>
+  </tr>
+<% end %>
+  </tbody>
+</table>
+</div>
+
+<% html_title(l(:label_project_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/91/9146de93165521f3efeb21d02742083a254d1a64.svn-base
--- a/.svn/pristine/91/9146de93165521f3efeb21d02742083a254d1a64.svn-base
+++ /dev/null
@@ -1,27 +0,0 @@
-class AutoCompletesController < ApplicationController
-  before_filter :find_project
-
-  def issues
-    @issues = []
-    q = params[:q].to_s
-    query = (params[:scope] == "all" && Setting.cross_project_issue_relations?) ? Issue : @project.issues
-    if q.match(/^\d+$/)
-      @issues << query.visible.find_by_id(q.to_i)
-    end
-    unless q.blank?
-      @issues += query.visible.find(:all, :conditions => ["LOWER(#{Issue.table_name}.subject) LIKE ?", "%#{q.downcase}%"], :limit => 10)
-    end
-    @issues.compact!
-    render :layout => false
-  end
-
-  private
-
-  def find_project
-    project_id = (params[:issue] && params[:issue][:project_id]) || params[:project_id]
-    @project = Project.find(project_id)
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/91/91d9fbac0c2d5034a6e6f8ad43bba0ff8ff79e87.svn-base
--- a/.svn/pristine/91/91d9fbac0c2d5034a6e6f8ad43bba0ff8ff79e87.svn-base
+++ /dev/null
@@ -1,110 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::IssueRelationsTest < ActionController::IntegrationTest
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :issue_relations
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "/issues/:issue_id/relations" do
-    context "GET" do
-      should "return issue relations" do
-        get '/issues/9/relations.xml', {}, :authorization => credentials('jsmith')
-
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-
-        assert_tag :tag => 'relations',
-          :attributes => { :type => 'array' },
-          :child => {
-            :tag => 'relation',
-            :child => {
-              :tag => 'id',
-              :content => '1'
-            }
-          }
-      end
-    end
-
-    context "POST" do
-      should "create a relation" do
-        assert_difference('IssueRelation.count') do
-          post '/issues/2/relations.xml', {:relation => {:issue_to_id => 7, :relation_type => 'relates'}}, :authorization => credentials('jsmith')
-        end
-
-        relation = IssueRelation.first(:order => 'id DESC')
-        assert_equal 2, relation.issue_from_id
-        assert_equal 7, relation.issue_to_id
-        assert_equal 'relates', relation.relation_type
-
-        assert_response :created
-        assert_equal 'application/xml', @response.content_type
-        assert_tag 'relation', :child => {:tag => 'id', :content => relation.id.to_s}
-      end
-
-      context "with failure" do
-        should "return the errors" do
-          assert_no_difference('IssueRelation.count') do
-            post '/issues/2/relations.xml', {:relation => {:issue_to_id => 7, :relation_type => 'foo'}}, :authorization => credentials('jsmith')
-          end
-
-          assert_response :unprocessable_entity
-          assert_tag :errors, :child => {:tag => 'error', :content => 'relation_type is not included in the list'}
-        end
-      end
-    end
-  end
-
-  context "/relations/:id" do
-    context "GET" do
-      should "return the relation" do
-        get '/relations/2.xml', {}, :authorization => credentials('jsmith')
-
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-        assert_tag 'relation', :child => {:tag => 'id', :content => '2'}
-      end
-    end
-
-    context "DELETE" do
-      should "delete the relation" do
-        assert_difference('IssueRelation.count', -1) do
-          delete '/relations/2.xml', {}, :authorization => credentials('jsmith')
-        end
-
-        assert_response :ok
-        assert_nil IssueRelation.find_by_id(2)
-      end
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/91/91db92d5f8c4cd8c1392a3d4def27437c7f826a5.svn-base
--- /dev/null
+++ b/.svn/pristine/91/91db92d5f8c4cd8c1392a3d4def27437c7f826a5.svn-base
@@ -0,0 +1,277 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AccountControllerTest < ActionController::TestCase
+  fixtures :users, :roles
+
+  def setup
+    User.current = nil
+  end
+
+  def test_get_login
+    get :login
+    assert_response :success
+    assert_template 'login'
+
+    assert_select 'input[name=username]'
+    assert_select 'input[name=password]'
+  end
+
+  def test_get_login_while_logged_in_should_redirect_to_home
+    @request.session[:user_id] = 2
+
+    get :login
+    assert_redirected_to '/'
+    assert_equal 2, @request.session[:user_id]
+  end
+
+  def test_login_should_redirect_to_back_url_param
+    # request.uri is "test.host" in test environment
+    post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http://test.host/issues/show/1'
+    assert_redirected_to '/issues/show/1'
+  end
+
+  def test_login_should_not_redirect_to_another_host
+    post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http://test.foo/fake'
+    assert_redirected_to '/my/page'
+  end
+
+  def test_login_with_wrong_password
+    post :login, :username => 'admin', :password => 'bad'
+    assert_response :success
+    assert_template 'login'
+
+    assert_select 'div.flash.error', :text => /Invalid user or password/
+    assert_select 'input[name=username][value=admin]'
+    assert_select 'input[name=password]'
+    assert_select 'input[name=password][value]', 0
+  end
+
+  def test_login_should_rescue_auth_source_exception
+    source = AuthSource.create!(:name => 'Test')
+    User.find(2).update_attribute :auth_source_id, source.id
+    AuthSource.any_instance.stubs(:authenticate).raises(AuthSourceException.new("Something wrong"))
+
+    post :login, :username => 'jsmith', :password => 'jsmith'
+    assert_response 500
+    assert_error_tag :content => /Something wrong/
+  end
+
+  def test_login_should_reset_session
+    @controller.expects(:reset_session).once
+
+    post :login, :username => 'jsmith', :password => 'jsmith'
+    assert_response 302
+  end
+
+  def test_get_logout_should_not_logout
+    @request.session[:user_id] = 2
+    get :logout
+    assert_response :success
+    assert_template 'logout'
+
+    assert_equal 2, @request.session[:user_id]
+  end
+
+  def test_logout
+    @request.session[:user_id] = 2
+    post :logout
+    assert_redirected_to '/'
+    assert_nil @request.session[:user_id]
+  end
+
+  def test_logout_should_reset_session
+    @controller.expects(:reset_session).once
+
+    @request.session[:user_id] = 2
+    post :logout
+    assert_response 302
+  end
+
+  def test_get_register_with_registration_on
+    with_settings :self_registration => '3' do
+      get :register
+      assert_response :success
+      assert_template 'register'
+      assert_not_nil assigns(:user)
+
+      assert_select 'input[name=?]', 'user[password]'
+      assert_select 'input[name=?]', 'user[password_confirmation]'
+    end
+  end
+
+  def test_get_register_should_detect_user_language
+    with_settings :self_registration => '3' do
+      @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
+      get :register
+      assert_response :success
+      assert_not_nil assigns(:user)
+      assert_equal 'fr', assigns(:user).language
+      assert_select 'select[name=?]', 'user[language]' do
+        assert_select 'option[value=fr][selected=selected]'
+      end
+    end
+  end
+
+  def test_get_register_with_registration_off_should_redirect
+    with_settings :self_registration => '0' do
+      get :register
+      assert_redirected_to '/'
+    end
+  end
+
+  # See integration/account_test.rb for the full test
+  def test_post_register_with_registration_on
+    with_settings :self_registration => '3' do
+      assert_difference 'User.count' do
+        post :register, :user => {
+          :login => 'register',
+          :password => 'secret123',
+          :password_confirmation => 'secret123',
+          :firstname => 'John',
+          :lastname => 'Doe',
+          :mail => 'register@example.com'
+        }
+        assert_redirected_to '/my/account'
+      end
+      user = User.first(:order => 'id DESC')
+      assert_equal 'register', user.login
+      assert_equal 'John', user.firstname
+      assert_equal 'Doe', user.lastname
+      assert_equal 'register@example.com', user.mail
+      assert user.check_password?('secret123')
+      assert user.active?
+    end
+  end
+  
+  def test_post_register_with_registration_off_should_redirect
+    with_settings :self_registration => '0' do
+      assert_no_difference 'User.count' do
+        post :register, :user => {
+          :login => 'register',
+          :password => 'test',
+          :password_confirmation => 'test',
+          :firstname => 'John',
+          :lastname => 'Doe',
+          :mail => 'register@example.com'
+        }
+        assert_redirected_to '/'
+      end
+    end
+  end
+
+  def test_get_lost_password_should_display_lost_password_form
+    get :lost_password
+    assert_response :success
+    assert_select 'input[name=mail]'
+  end
+
+  def test_lost_password_for_active_user_should_create_a_token
+    Token.delete_all
+    ActionMailer::Base.deliveries.clear
+    assert_difference 'ActionMailer::Base.deliveries.size' do
+      assert_difference 'Token.count' do
+        with_settings :host_name => 'mydomain.foo', :protocol => 'http' do
+          post :lost_password, :mail => 'JSmith@somenet.foo'
+          assert_redirected_to '/login'
+        end
+      end
+    end
+
+    token = Token.order('id DESC').first
+    assert_equal User.find(2), token.user
+    assert_equal 'recovery', token.action
+
+    assert_select_email do
+      assert_select "a[href=?]", "http://mydomain.foo/account/lost_password?token=#{token.value}"
+    end
+  end
+
+  def test_lost_password_for_unknown_user_should_fail
+    Token.delete_all
+    assert_no_difference 'Token.count' do
+      post :lost_password, :mail => 'invalid@somenet.foo'
+      assert_response :success
+    end
+  end
+
+  def test_lost_password_for_non_active_user_should_fail
+    Token.delete_all
+    assert User.find(2).lock!
+
+    assert_no_difference 'Token.count' do
+      post :lost_password, :mail => 'JSmith@somenet.foo'
+      assert_response :success
+    end
+  end
+
+  def test_get_lost_password_with_token_should_display_the_password_recovery_form
+    user = User.find(2)
+    token = Token.create!(:action => 'recovery', :user => user)
+
+    get :lost_password, :token => token.value
+    assert_response :success
+    assert_template 'password_recovery'
+
+    assert_select 'input[type=hidden][name=token][value=?]', token.value
+  end
+
+  def test_get_lost_password_with_invalid_token_should_redirect
+    get :lost_password, :token => "abcdef"
+    assert_redirected_to '/'
+  end
+
+  def test_post_lost_password_with_token_should_change_the_user_password
+    user = User.find(2)
+    token = Token.create!(:action => 'recovery', :user => user)
+
+    post :lost_password, :token => token.value, :new_password => 'newpass123', :new_password_confirmation => 'newpass123'
+    assert_redirected_to '/login'
+    user.reload
+    assert user.check_password?('newpass123')
+    assert_nil Token.find_by_id(token.id), "Token was not deleted"
+  end
+
+  def test_post_lost_password_with_token_for_non_active_user_should_fail
+    user = User.find(2)
+    token = Token.create!(:action => 'recovery', :user => user)
+    user.lock!
+
+    post :lost_password, :token => token.value, :new_password => 'newpass123', :new_password_confirmation => 'newpass123'
+    assert_redirected_to '/'
+    assert ! user.check_password?('newpass123')
+  end
+
+  def test_post_lost_password_with_token_and_password_confirmation_failure_should_redisplay_the_form
+    user = User.find(2)
+    token = Token.create!(:action => 'recovery', :user => user)
+
+    post :lost_password, :token => token.value, :new_password => 'newpass', :new_password_confirmation => 'wrongpass'
+    assert_response :success
+    assert_template 'password_recovery'
+    assert_not_nil Token.find_by_id(token.id), "Token was deleted"
+
+    assert_select 'input[type=hidden][name=token][value=?]', token.value
+  end
+
+  def test_post_lost_password_with_invalid_token_should_redirect
+    post :lost_password, :token => "abcdef", :new_password => 'newpass', :new_password_confirmation => 'newpass'
+    assert_redirected_to '/'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/91/91e3e07929a847cdafd555b268505df4f7f49393.svn-base
--- /dev/null
+++ b/.svn/pristine/91/91e3e07929a847cdafd555b268505df4f7f49393.svn-base
@@ -0,0 +1,81 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueStatusesController < ApplicationController
+  layout 'admin'
+
+  before_filter :require_admin, :except => :index
+  before_filter :require_admin_or_api_request, :only => :index
+  accept_api_auth :index
+
+  def index
+    respond_to do |format|
+      format.html {
+        @issue_status_pages, @issue_statuses = paginate IssueStatus.sorted, :per_page => 25
+        render :action => "index", :layout => false if request.xhr?
+      }
+      format.api {
+        @issue_statuses = IssueStatus.all(:order => 'position')
+      }
+    end
+  end
+
+  def new
+    @issue_status = IssueStatus.new
+  end
+
+  def create
+    @issue_status = IssueStatus.new(params[:issue_status])
+    if request.post? && @issue_status.save
+      flash[:notice] = l(:notice_successful_create)
+      redirect_to issue_statuses_path
+    else
+      render :action => 'new'
+    end
+  end
+
+  def edit
+    @issue_status = IssueStatus.find(params[:id])
+  end
+
+  def update
+    @issue_status = IssueStatus.find(params[:id])
+    if request.put? && @issue_status.update_attributes(params[:issue_status])
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to issue_statuses_path
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def destroy
+    IssueStatus.find(params[:id]).destroy
+    redirect_to issue_statuses_path
+  rescue
+    flash[:error] = l(:error_unable_delete_issue_status)
+    redirect_to issue_statuses_path
+  end
+
+  def update_issue_done_ratio
+    if request.post? && IssueStatus.update_issue_done_ratios
+      flash[:notice] = l(:notice_issue_done_ratios_updated)
+    else
+      flash[:error] =  l(:error_issue_done_ratios_not_updated)
+    end
+    redirect_to issue_statuses_path
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/91/91efe5b9e5cae373a7c0bac712c0297ba5e571fd.svn-base
--- /dev/null
+++ b/.svn/pristine/91/91efe5b9e5cae373a7c0bac712c0297ba5e571fd.svn-base
@@ -0,0 +1,41 @@
+<%= form_tag({}) do -%>
+<%= hidden_field_tag 'back_url', url_for(params) %>
+<div class="autoscroll">
+<table class="list time-entries">
+<thead>
+  <tr>
+    <th class="checkbox hide-when-print">
+      <%= link_to image_tag('toggle_check.png'),
+        {},
+        :onclick => 'toggleIssuesSelection(this); return false;',
+        :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
+    </th>
+    <% @query.inline_columns.each do |column| %>
+      <%= column_header(column) %>
+    <% end %>
+    <th></th>
+  </tr>
+</thead>
+<tbody>
+<% entries.each do |entry| -%>
+  <tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
+    <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
+    <%= raw @query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, entry)}</td>"}.join %>
+    <td align="center">
+    <% if entry.editable_by?(User.current) -%>
+        <%= link_to image_tag('edit.png'), edit_time_entry_path(entry),
+                                           :title => l(:button_edit) %>
+        <%= link_to image_tag('delete.png'), time_entry_path(entry),
+                                             :data => {:confirm => l(:text_are_you_sure)},
+                                             :method => :delete,
+                                             :title => l(:button_delete) %>
+    <% end -%>
+    </td>
+  </tr>
+<% end -%>
+</tbody>
+</table>
+</div>
+<% end -%>
+
+<%= context_menu time_entries_context_menu_path %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/92/920e44593cf3222faff5a7cfd3f7e7c40685f47d.svn-base
--- a/.svn/pristine/92/920e44593cf3222faff5a7cfd3f7e7c40685f47d.svn-base
+++ /dev/null
@@ -1,20 +0,0 @@
-= 0.5.2 / 2007-12-21
-
-* Added more test cases and enabled ZenTest compatibility for the test case
-  names.
-
-= 0.5.1 / 2007-12-20
-
-* Minor code refactoring.
-
-= 0.5.0 / 2007-12-18
-
-* Fixed the marshalling code to correctly handle non-string content.
-
-= 0.4.3 / 2007-10-09
-
-* Changes to the build mechanism (now uses Hoe).
-
-= 0.4.2 / 2007-10-01
-
-* Minor code refactoring. Changes in the Rakefile.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/92/92b4f5732f182d4998155cf0aa9e5c1d67828523.svn-base
--- /dev/null
+++ b/.svn/pristine/92/92b4f5732f182d4998155cf0aa9e5c1d67828523.svn-base
@@ -0,0 +1,97 @@
+<div class="contextual">
+  <% if User.current.allowed_to?(:add_subprojects, @project) %>
+    <%= link_to l(:label_subproject_new), new_project_path(:parent_id => @project), :class => 'icon icon-add' %>
+  <% end %>
+  <% if User.current.allowed_to?(:close_project, @project) %>
+    <% if @project.active? %>
+      <%= link_to l(:button_close), close_project_path(@project), :data => {:confirm => l(:text_are_you_sure)}, :method => :post, :class => 'icon icon-lock' %>
+    <% else %>
+      <%= link_to l(:button_reopen), reopen_project_path(@project), :data => {:confirm => l(:text_are_you_sure)}, :method => :post, :class => 'icon icon-unlock' %>
+    <% end %>
+  <% end %>
+</div>
+
+<h2><%=l(:label_overview)%></h2>
+
+<% unless @project.active? %>
+  <p class="warning"><span class="icon icon-lock"><%= l(:text_project_closed) %></span></p>
+<% end %>
+
+<div class="splitcontentleft">
+  <% if @project.description.present? %>
+  <div class="wiki">
+    <%= textilizable @project.description %>
+  </div>
+  <% end %>
+  <ul>
+  <% unless @project.homepage.blank? %>
+    <li><%=l(:field_homepage)%>: <%= link_to h(@project.homepage), @project.homepage %></li>
+  <% end %>
+  <% if @subprojects.any? %>
+    <li><%=l(:label_subproject_plural)%>:
+      <%= @subprojects.collect{|p| link_to p, project_path(p)}.join(", ").html_safe %></li>
+  <% end %>
+  <% @project.visible_custom_field_values.each do |custom_value| %>
+  <% if !custom_value.value.blank? %>
+     <li><%=h custom_value.custom_field.name %>: <%=h show_value(custom_value) %></li>
+  <% end %>
+  <% end %>
+  </ul>
+
+  <% if User.current.allowed_to?(:view_issues, @project) %>
+  <div class="issues box">
+    <h3><%=l(:label_issue_tracking)%></h3>
+    <ul>
+    <% for tracker in @trackers %>
+      <li><%= link_to h(tracker.name), project_issues_path(@project, :set_filter => 1, :tracker_id => tracker.id) %>:
+          <%= l(:label_x_open_issues_abbr_on_total, :count => @open_issues_by_tracker[tracker].to_i,
+                                                    :total => @total_issues_by_tracker[tracker].to_i) %>
+      </li>
+    <% end %>
+    </ul>
+    <p>
+      <%= link_to l(:label_issue_view_all), project_issues_path(@project, :set_filter => 1) %>
+      <% if User.current.allowed_to?(:view_calendar, @project, :global => true) %>
+        | <%= link_to l(:label_calendar), project_calendar_path(@project) %>
+      <% end %>
+      <% if User.current.allowed_to?(:view_gantt, @project, :global => true) %>
+        | <%= link_to l(:label_gantt), project_gantt_path(@project) %>
+      <% end %>
+    </p>
+  </div>
+  <% end %>
+  <%= call_hook(:view_projects_show_left, :project => @project) %>
+</div>
+
+<div class="splitcontentright">
+  <%= render :partial => 'members_box' %>
+
+  <% if @news.any? && authorize_for('news', 'index') %>
+  <div class="news box">
+    <h3><%=l(:label_news_latest)%></h3>
+    <%= render :partial => 'news/news', :collection => @news %>
+    <p><%= link_to l(:label_news_view_all), project_news_index_path(@project) %></p>
+  </div>
+  <% end %>
+  <%= call_hook(:view_projects_show_right, :project => @project) %>
+</div>
+
+<% content_for :sidebar do %>
+    <% if @total_hours.present? %>
+    <h3><%= l(:label_spent_time) %></h3>
+    <p><span class="icon icon-time"><%= l_hours(@total_hours) %></span></p>
+    <p>
+    <% if User.current.allowed_to?(:log_time, @project) %>
+      <%= link_to l(:button_log_time), new_project_time_entry_path(@project) %> |
+    <% end %>
+    <%= link_to(l(:label_details), project_time_entries_path(@project)) %> |
+    <%= link_to(l(:label_report), report_project_time_entries_path(@project)) %></p>
+    <% end %>
+    <%= call_hook(:view_projects_show_sidebar_bottom, :project => @project) %>
+<% end %>
+
+<% content_for :header_tags do %>
+<%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :id => @project, :format => 'atom', :key => User.current.rss_key}) %>
+<% end %>
+
+<% html_title(l(:label_overview)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/92/92b92918eb7020ef6c81dcf481e4849ccd703276.svn-base
--- a/.svn/pristine/92/92b92918eb7020ef6c81dcf481e4849ccd703276.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-# This is only here to allow for backwards compability with Engines that
-# have been implemented based on Engines for Rails 1.2. It is preferred that
-# the plugin list be accessed via Engines.plugins.
-
-module Rails
-  # Returns the Engines::Plugin::List from Engines.plugins. It is preferable to
-  # access Engines.plugins directly.
-  def self.plugins
-    Engines.plugins
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/92/92e79cf48ee767b10d559c8d0bc187ea50742a7c.svn-base
--- /dev/null
+++ b/.svn/pristine/92/92e79cf48ee767b10d559c8d0bc187ea50742a7c.svn-base
@@ -0,0 +1,81 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingIssueRelationsTest < ActionController::IntegrationTest
+  def test_issue_relations
+    assert_routing(
+        { :method => 'get', :path => "/issues/1/relations" },
+        { :controller => 'issue_relations', :action => 'index',
+          :issue_id => '1' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/1/relations.xml" },
+        { :controller => 'issue_relations', :action => 'index',
+          :issue_id => '1', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/1/relations.json" },
+        { :controller => 'issue_relations', :action => 'index',
+          :issue_id => '1', :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issues/1/relations" },
+        { :controller => 'issue_relations', :action => 'create',
+          :issue_id => '1' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issues/1/relations.xml" },
+        { :controller => 'issue_relations', :action => 'create',
+          :issue_id => '1', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issues/1/relations.json" },
+        { :controller => 'issue_relations', :action => 'create',
+          :issue_id => '1', :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/relations/23" },
+        { :controller => 'issue_relations', :action => 'show', :id => '23' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/relations/23.xml" },
+        { :controller => 'issue_relations', :action => 'show', :id => '23',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/relations/23.json" },
+        { :controller => 'issue_relations', :action => 'show', :id => '23',
+          :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/relations/23" },
+        { :controller => 'issue_relations', :action => 'destroy', :id => '23' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/relations/23.xml" },
+        { :controller => 'issue_relations', :action => 'destroy', :id => '23',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/relations/23.json" },
+        { :controller => 'issue_relations', :action => 'destroy', :id => '23',
+          :format => 'json' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/92/92f553d621df97e2801a8f829698de1d6ffc2a82.svn-base
--- /dev/null
+++ b/.svn/pristine/92/92f553d621df97e2801a8f829698de1d6ffc2a82.svn-base
@@ -0,0 +1,1118 @@
+# Japanese translations for Ruby on Rails
+# by Akira Matsuda (ronnie@dio.jp)
+# AR error messages are basically taken from Ruby-GetText-Package. Thanks to Masao Mutoh.
+
+ja:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y/%m/%d"
+      short: "%m/%d"
+      long: "%Yå¹´%mæœˆ%dæ—¥(%a)"
+
+    day_names: [æ—¥æ›œæ—¥, æœˆæ›œæ—¥, ç«æ›œæ—¥, æ°´æ›œæ—¥, æœ¨æ›œæ—¥, é‡‘æ›œæ—¥, åœŸæ›œæ—¥]
+    abbr_day_names: [æ—¥, æœˆ, ç«, æ°´, æœ¨, é‡‘, åœŸ]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, 1æœˆ, 2æœˆ, 3æœˆ, 4æœˆ, 5æœˆ, 6æœˆ, 7æœˆ, 8æœˆ, 9æœˆ, 10æœˆ, 11æœˆ, 12æœˆ]
+    abbr_month_names: [~, 1æœˆ, 2æœˆ, 3æœˆ, 4æœˆ, 5æœˆ, 6æœˆ, 7æœˆ, 8æœˆ, 9æœˆ, 10æœˆ, 11æœˆ, 12æœˆ]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%Y/%m/%d %H:%M:%S"
+      time: "%H:%M"
+      short: "%y/%m/%d %H:%M"
+      long: "%Yå¹´%mæœˆ%dæ—¥(%a) %Hæ™‚%Måˆ†%Sç§’ %Z"
+    am: "åˆå‰"
+    pm: "åˆå¾Œ"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "30ç§’å‰å¾Œ"
+      less_than_x_seconds:
+        one:   "1ç§’ä»¥å†…"
+        other: "%{count}ç§’ä»¥å†…"
+      x_seconds:
+        one:   "1ç§’"
+        other: "%{count}ç§’"
+      less_than_x_minutes:
+        one:   "1åˆ†ä»¥å†…"
+        other: "%{count}åˆ†ä»¥å†…"
+      x_minutes:
+        one:   "1åˆ†"
+        other: "%{count}åˆ†"
+      about_x_hours:
+        one:   "ç´„1æ™‚é–“"
+        other: "ç´„%{count}æ™‚é–“"
+      x_hours:
+        one:   "1æ™‚é–“"
+        other: "%{count}æ™‚é–“"
+      x_days:
+        one:   "1æ—¥"
+        other: "%{count}æ—¥"
+      about_x_months:
+        one:   "ç´„1ãƒ¶æœˆ"
+        other: "ç´„%{count}ãƒ¶æœˆ"
+      x_months:
+        one:   "1ãƒ¶æœˆ"
+        other: "%{count}ãƒ¶æœˆ"
+      about_x_years:
+        one:   "ç´„1å¹´"
+        other: "ç´„%{count}å¹´"
+      over_x_years:
+        one:   "1å¹´ä»¥ä¸Š"
+        other: "%{count}å¹´ä»¥ä¸Š"
+      almost_x_years:
+        one:   "ã»ã¼1å¹´"
+        other: "ã»ã¼%{count}å¹´"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ","
+      precision: 3
+
+    currency:
+      format:
+        format: "%n%u"
+        unit: "å††"
+        separator: "."
+        delimiter: ","
+        precision: 0
+
+    percentage:
+      format:
+        delimiter: ""
+
+    precision:
+      format:
+        delimiter: ""
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "åŠã³"
+      skip_last_comma: true
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:   "%{model} ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+          other: "%{model} ã« %{count} ã¤ã®ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+        body: "æ¬¡ã®é …ç›®ã‚’ç¢ºèªã—ã¦ãã ã•ã„ã€‚"
+
+      messages:
+        inclusion: "ã¯ä¸€è¦§ã«ã‚ã‚Šã¾ã›ã‚“ã€‚"
+        exclusion: "ã¯äºˆç´„ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+        invalid: "ã¯ä¸æ­£ãªå€¤ã§ã™ã€‚"
+        confirmation: "ãŒä¸€è‡´ã—ã¾ã›ã‚“ã€‚"
+        accepted: "ã‚’å—è«¾ã—ã¦ãã ã•ã„ã€‚"
+        empty: "ã‚’å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
+        blank: "ã‚’å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
+        too_long: "ã¯%{count}æ–‡å­—ä»¥å†…ã§å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
+        too_short: "ã¯%{count}æ–‡å­—ä»¥ä¸Šã§å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
+        wrong_length: "ã¯%{count}æ–‡å­—ã§å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
+        taken: "ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚"
+        not_a_number: "ã¯æ•°å€¤ã§å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
+        not_a_date: "ã¯æ—¥ä»˜ã‚’å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
+        greater_than: "ã¯%{count}ã‚ˆã‚Šå¤§ãã„å€¤ã«ã—ã¦ãã ã•ã„ã€‚"
+        greater_than_or_equal_to: "ã¯%{count}ä»¥ä¸Šã®å€¤ã«ã—ã¦ãã ã•ã„ã€‚"
+        equal_to: "ã¯%{count}ã«ã—ã¦ãã ã•ã„ã€‚"
+        less_than: "ã¯%{count}ã‚ˆã‚Šå°ã•ã„å€¤ã«ã—ã¦ãã ã•ã„ã€‚"
+        less_than_or_equal_to: "ã¯%{count}ä»¥ä¸‹ã®å€¤ã«ã—ã¦ãã ã•ã„ã€‚"
+        odd: "ã¯å¥‡æ•°ã«ã—ã¦ãã ã•ã„ã€‚"
+        even: "ã¯å¶æ•°ã«ã—ã¦ãã ã•ã„ã€‚"
+        greater_than_start_date: "ã‚’é–‹å§‹æ—¥ã‚ˆã‚Šå¾Œã«ã—ã¦ãã ã•ã„"
+        not_same_project: "åŒã˜ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«å±žã—ã¦ã„ã¾ã›ã‚“"
+        circular_dependency: "ã“ã®é–¢ä¿‚ã§ã¯ã€å¾ªç’°ä¾å­˜ã«ãªã‚Šã¾ã™"
+        cant_link_an_issue_with_a_descendant: "æŒ‡å®šã—ãŸãƒã‚±ãƒƒãƒˆã¨ã¯è¦ªå­é–¢ä¿‚ã«ãªã£ã¦ã„ã‚‹ãŸã‚é–¢é€£ã¥ã‘ã‚‰ã‚Œã¾ã›ã‚“"
+
+  actionview_instancetag_blank_option: é¸ã‚“ã§ãã ã•ã„
+
+  general_text_No: 'ã„ã„ãˆ'
+  general_text_Yes: 'ã¯ã„'
+  general_text_no: 'ã„ã„ãˆ'
+  general_text_yes: 'ã¯ã„'
+  general_lang_name: 'Japanese (æ—¥æœ¬èªž)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: CP932
+  ## Redmine 1.2.0 ç¾åœ¨ã€ã“ã®å€¤ã«ã‚ˆã£ã¦ã€pdfã®å‡ºåŠ›ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’åˆ‡ã‚Šæ›¿ãˆã¦ã„ã¾ã™ã€‚
+  ## CRuby ã§ã¯ CP932 ã«ã—ã¦ãã ã•ã„ã€‚
+  ## JRuby 1.6.2 (ruby-1.8.7-p330) ã§ã¯ã€CP932 ã§ã™ã¨
+  ## Iconv::InvalidEncodingä¾‹å¤–ãŒç™ºç”Ÿã—ã¾ã™ã€‚
+  ## JRuby ã§ã¯ã€SJIS ã‹ Shift_JIS ã«ã—ã¦ãã ã•ã„ã€‚
+  ## ã”å­˜çŸ¥ã®é€šã‚Šã€CP932 ã¨ SJIS ã¯åˆ¥ç‰©ã§ã™ãŒã€
+  ## ãã“ã¾ã§ã®æ¤œè¨¼ã¯ã—ã¦ã„ã¾ã›ã‚“ã€‚
+  # general_pdf_encoding: SJIS
+  general_pdf_encoding: CP932
+  general_first_day_of_week: '7'
+
+  notice_account_updated: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚
+  notice_account_invalid_creditentials: ãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚‚ã—ãã¯ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒç„¡åŠ¹ã§ã™
+  notice_account_password_updated: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚
+  notice_account_wrong_password: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒé•ã„ã¾ã™
+  notice_account_register_done: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚æœ‰åŠ¹ã«ã™ã‚‹ã«ã¯é€ä¿¡ã—ãŸãƒ¡ãƒ¼ãƒ«ã«ã‚ã‚‹ãƒªãƒ³ã‚¯ã‚’ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„ã€‚
+  notice_account_unknown_email: ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒå­˜åœ¨ã—ã¾ã›ã‚“ã€‚
+  notice_can_t_change_password: ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§ã¯å¤–éƒ¨èªè¨¼ã‚’ä½¿ã£ã¦ã„ã¾ã™ã€‚ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã¯å¤‰æ›´ã§ãã¾ã›ã‚“ã€‚
+  notice_account_lost_email_sent: æ–°ã—ã„ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã—ãŸã€‚
+  notice_account_activated: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒæœ‰åŠ¹ã«ãªã‚Šã¾ã—ãŸã€‚ãƒ­ã‚°ã‚¤ãƒ³ã§ãã¾ã™ã€‚
+  notice_successful_create: ä½œæˆã—ã¾ã—ãŸã€‚
+  notice_successful_update: æ›´æ–°ã—ã¾ã—ãŸã€‚
+  notice_successful_delete: å‰Šé™¤ã—ã¾ã—ãŸã€‚
+  notice_successful_connection: æŽ¥ç¶šã—ã¾ã—ãŸã€‚
+  notice_file_not_found: ã‚¢ã‚¯ã‚»ã‚¹ã—ã‚ˆã†ã¨ã—ãŸãƒšãƒ¼ã‚¸ã¯å­˜åœ¨ã—ãªã„ã‹å‰Šé™¤ã•ã‚Œã¦ã„ã¾ã™ã€‚
+  notice_locking_conflict: åˆ¥ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒãƒ‡ãƒ¼ã‚¿ã‚’æ›´æ–°ã—ã¦ã„ã¾ã™ã€‚
+  notice_not_authorized: ã“ã®ãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯èªè¨¼ãŒå¿…è¦ã§ã™ã€‚
+  notice_not_authorized_archived_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¯ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•ã‚Œã¦ã„ã¾ã™ã€‚
+  notice_email_sent: "%{value} å®›ã«ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã—ãŸã€‚"
+  notice_email_error: "ãƒ¡ãƒ¼ãƒ«é€ä¿¡ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ (%{value})"
+  notice_feeds_access_key_reseted: RSSã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã‚’åˆæœŸåŒ–ã—ã¾ã—ãŸã€‚
+  notice_api_access_key_reseted: APIã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã‚’åˆæœŸåŒ–ã—ã¾ã—ãŸã€‚
+  notice_failed_to_save_issues: "å…¨%{total}ä»¶ä¸­%{count}ä»¶ã®ãƒã‚±ãƒƒãƒˆãŒä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %{ids}."
+  notice_failed_to_save_members: "ãƒ¡ãƒ³ãƒãƒ¼ã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸ: %{errors}."
+  notice_no_issue_selected: "ãƒã‚±ãƒƒãƒˆãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“! æ›´æ–°å¯¾è±¡ã®ãƒã‚±ãƒƒãƒˆã‚’é¸æŠžã—ã¦ãã ã•ã„ã€‚"
+  notice_account_pending: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯ä½œæˆæ¸ˆã¿ã§ã€ã‚·ã‚¹ãƒ†ãƒ ç®¡ç†è€…ã®æ‰¿èªå¾…ã¡ã§ã™ã€‚
+  notice_default_data_loaded: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®šã‚’ãƒ­ãƒ¼ãƒ‰ã—ã¾ã—ãŸã€‚
+  notice_unable_delete_version: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’å‰Šé™¤ã§ãã¾ã›ã‚“
+  notice_unable_delete_time_entry: ä½œæ¥­æ™‚é–“ã‚’å‰Šé™¤ã§ãã¾ã›ã‚“
+  notice_issue_done_ratios_updated: ãƒã‚±ãƒƒãƒˆã®é€²æ—ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚
+  notice_gantt_chart_truncated: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆã¯ã€æœ€å¤§è¡¨ç¤ºé …ç›®æ•°(%{max})ã‚’è¶…ãˆãŸãŸãŸã‚åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚
+
+  error_can_t_load_default_data: "ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®šãŒãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ: %{value}"
+  error_scm_not_found: ãƒªãƒã‚¸ãƒˆãƒªã«ã€ã‚¨ãƒ³ãƒˆãƒª/ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒå­˜åœ¨ã—ã¾ã›ã‚“ã€‚
+  error_scm_command_failed: "ãƒªãƒã‚¸ãƒˆãƒªã¸ã‚¢ã‚¯ã‚»ã‚¹ã—ã‚ˆã†ã¨ã—ã¦ã‚¨ãƒ©ãƒ¼ã«ãªã‚Šã¾ã—ãŸ: %{value}"
+  error_scm_annotate: "ã‚¨ãƒ³ãƒˆãƒªãŒå­˜åœ¨ã—ãªã„ã€ã‚‚ã—ãã¯ã‚¢ãƒŽãƒ†ãƒ¼ãƒˆã§ãã¾ã›ã‚“ã€‚"
+  error_issue_not_found_in_project: 'ãƒã‚±ãƒƒãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€ã‚‚ã—ãã¯ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«å±žã—ã¦ã„ã¾ã›ã‚“'
+  error_unable_delete_issue_status: "ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’å‰Šé™¤ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+  error_no_tracker_in_project: 'ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«ã¯ãƒˆãƒ©ãƒƒã‚«ãƒ¼ãŒç™»éŒ²ã•ã‚Œã¦ã„ã¾ã›ã‚“ã€‚ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆè¨­å®šã‚’ç¢ºèªã—ã¦ãã ã•ã„ã€‚'
+  error_no_default_issue_status: 'ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒã‚±ãƒƒãƒˆã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“ã€‚è¨­å®šã‚’ç¢ºèªã—ã¦ãã ã•ã„ï¼ˆç®¡ç†â†’ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ï¼‰ã€‚'
+  error_can_not_delete_custom_field: 'ã‚«ã‚¹ã‚¿ãƒ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’å‰Šé™¤ã§ãã¾ã›ã‚“ã€‚'
+  error_unable_to_connect: "æŽ¥ç¶šã§ãã¾ã›ã‚“ã€‚ (%{value})"
+  error_can_not_remove_role: 'ã“ã®ãƒ­ãƒ¼ãƒ«ã¯ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚å‰Šé™¤ã§ãã¾ã›ã‚“ã€‚'
+  error_can_not_reopen_issue_on_closed_version: 'çµ‚äº†ã—ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã²ã‚‚ä»˜ã‘ã•ã‚ŒãŸãƒã‚±ãƒƒãƒˆã®å†ã‚ªãƒ¼ãƒ—ãƒ³ã¯ã§ãã¾ã›ã‚“ã€‚'
+  error_can_not_archive_project: ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¯ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã§ãã¾ã›ã‚“
+  error_issue_done_ratios_not_updated: "ãƒã‚±ãƒƒãƒˆã®é€²æ—ãŒæ›´æ–°ã§ãã¾ã›ã‚“ã€‚"
+  error_workflow_copy_source: 'ã‚³ãƒ”ãƒ¼å…ƒã¨ãªã‚‹ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã¾ãŸã¯ãƒ­ãƒ¼ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„'
+  error_workflow_copy_target: 'ã‚³ãƒ”ãƒ¼å…ˆã¨ãªã‚‹ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã¨ãƒ­ãƒ¼ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„'
+  error_can_not_delete_tracker: 'ã“ã®ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã¯ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚å‰Šé™¤ã§ãã¾ã›ã‚“ã€‚'
+
+  warning_attachments_not_saved: "%{count}å€‹ã®æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ãŒä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+  mail_subject_lost_password: "%{value} ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰å†ç™ºè¡Œ"
+  mail_body_lost_password: 'ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã‚’å¤‰æ›´ã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®ãƒªãƒ³ã‚¯ã‚’ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„:'
+  mail_subject_register: "%{value} ã‚¢ã‚«ã‚¦ãƒ³ãƒˆç™»éŒ²ã®ç¢ºèª"
+  mail_body_register: 'ã‚¢ã‚«ã‚¦ãƒ³ãƒˆç™»éŒ²ã‚’å®Œäº†ã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„:'
+  mail_body_account_information_external: "%{value} ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’ä½¿ã£ã¦ã«ãƒ­ã‚°ã‚¤ãƒ³ã§ãã¾ã™ã€‚"
+  mail_body_account_information: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆæƒ…å ±
+  mail_subject_account_activation_request: "%{value} ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®æ‰¿èªè¦æ±‚"
+  mail_body_account_activation_request: "æ–°ã—ã„ãƒ¦ãƒ¼ã‚¶ãƒ¼ %{value} ãŒç™»éŒ²ã•ã‚Œã¾ã—ãŸã€‚ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯ã‚ãªãŸã®æ‰¿èªå¾…ã¡ã§ã™ï¼š"
+  mail_subject_reminder: "%{count}ä»¶ã®ãƒã‚±ãƒƒãƒˆã®æœŸæ—¥ãŒ%{days}æ—¥ä»¥å†…ã«åˆ°æ¥ã—ã¾ã™"
+  mail_body_reminder: "%{count}ä»¶ã®æ‹…å½“ãƒã‚±ãƒƒãƒˆã®æœŸæ—¥ãŒ%{days}æ—¥ä»¥å†…ã«åˆ°æ¥ã—ã¾ã™:"
+  mail_subject_wiki_content_added: "Wikiãƒšãƒ¼ã‚¸ %{id} ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ"
+  mail_body_wiki_content_added: "%{author} ã«ã‚ˆã£ã¦Wikiãƒšãƒ¼ã‚¸ %{id} ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚"
+  mail_subject_wiki_content_updated: "Wikiãƒšãƒ¼ã‚¸ %{id} ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ"
+  mail_body_wiki_content_updated: "%{author} ã«ã‚ˆã£ã¦Wikiãƒšãƒ¼ã‚¸ %{id} ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
+
+
+  field_name: åç§°
+  field_description: èª¬æ˜Ž
+  field_summary: ã‚µãƒžãƒªãƒ¼
+  field_is_required: å¿…é ˆ
+  field_firstname: åå‰
+  field_lastname: è‹—å­—
+  field_mail: ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹
+  field_filename: ãƒ•ã‚¡ã‚¤ãƒ«
+  field_filesize: ã‚µã‚¤ã‚º
+  field_downloads: ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰
+  field_author: ä½œæˆè€…
+  field_created_on: ä½œæˆæ—¥
+  field_updated_on: æ›´æ–°æ—¥
+  field_field_format: æ›¸å¼
+  field_is_for_all: å…¨ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå‘ã‘
+  field_possible_values: é¸æŠžè‚¢
+  field_regexp: æ­£è¦è¡¨ç¾
+  field_min_length: æœ€å°å€¤
+  field_max_length: æœ€å¤§å€¤
+  field_value: å€¤
+  field_category: ã‚«ãƒ†ã‚´ãƒª
+  field_title: ã‚¿ã‚¤ãƒˆãƒ«
+  field_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  field_issue: ãƒã‚±ãƒƒãƒˆ
+  field_status: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
+  field_notes: æ³¨è¨˜
+  field_is_closed: çµ‚äº†ã—ãŸãƒã‚±ãƒƒãƒˆ
+  field_is_default: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤
+  field_tracker: ãƒˆãƒ©ãƒƒã‚«ãƒ¼
+  field_subject: é¡Œå
+  field_due_date: æœŸæ—¥
+  field_assigned_to: æ‹…å½“è€…
+  field_priority: å„ªå…ˆåº¦
+  field_fixed_version: å¯¾è±¡ãƒãƒ¼ã‚¸ãƒ§ãƒ³
+  field_user: ãƒ¦ãƒ¼ã‚¶ãƒ¼
+  field_principal: ä¸»ä½“
+  field_role: ãƒ­ãƒ¼ãƒ«
+  field_homepage: ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸
+  field_is_public: å…¬é–‹
+  field_parent: è¦ªãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå
+  field_is_in_roadmap: ãƒã‚±ãƒƒãƒˆã‚’ãƒ­ãƒ¼ãƒ‰ãƒžãƒƒãƒ—ã«è¡¨ç¤ºã™ã‚‹
+  field_login: ãƒ­ã‚°ã‚¤ãƒ³
+  field_mail_notification: ãƒ¡ãƒ¼ãƒ«é€šçŸ¥
+  field_admin: ã‚·ã‚¹ãƒ†ãƒ ç®¡ç†è€…
+  field_last_login_on: æœ€çµ‚æŽ¥ç¶šæ—¥
+  field_language: è¨€èªž
+  field_effective_date: æœŸæ—¥
+  field_password: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰
+  field_new_password: æ–°ã—ã„ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰
+  field_password_confirmation: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®ç¢ºèª
+  field_version: ãƒãƒ¼ã‚¸ãƒ§ãƒ³
+  field_type: ã‚¿ã‚¤ãƒ—
+  field_host: ãƒ›ã‚¹ãƒˆ
+  field_port: ãƒãƒ¼ãƒˆ
+  field_account: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆ
+  field_base_dn: æ¤œç´¢ç¯„å›²
+  field_attr_login: ãƒ­ã‚°ã‚¤ãƒ³åå±žæ€§
+  field_attr_firstname: åå‰å±žæ€§
+  field_attr_lastname: è‹—å­—å±žæ€§
+  field_attr_mail: ãƒ¡ãƒ¼ãƒ«å±žæ€§
+  field_onthefly: ã‚ã‚ã›ã¦ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’ä½œæˆ
+  field_start_date: é–‹å§‹æ—¥
+  field_done_ratio: é€²æ— %
+  field_auth_source: èªè¨¼æ–¹å¼
+  field_hide_mail: ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’éš ã™
+  field_comments: ã‚³ãƒ¡ãƒ³ãƒˆ
+  field_url: URL
+  field_start_page: ãƒ¡ã‚¤ãƒ³ãƒšãƒ¼ã‚¸
+  field_subproject: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  field_hours: æ™‚é–“
+  field_activity: æ´»å‹•
+  field_spent_on: æ—¥ä»˜
+  field_identifier: è­˜åˆ¥å­
+  field_is_filter: ãƒ•ã‚£ãƒ«ã‚¿ã¨ã—ã¦ä½¿ã†
+  field_issue_to: é–¢é€£ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
+  field_delay: é…å»¶
+  field_assignable: ã“ã®ãƒ­ãƒ¼ãƒ«ã«ãƒã‚±ãƒƒãƒˆã‚’å‰²ã‚Šå½“ã¦å¯èƒ½
+  field_redirect_existing_links: æ—¢å­˜ã®ãƒªãƒ³ã‚¯ã‚’ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã™ã‚‹
+  field_estimated_hours: äºˆå®šå·¥æ•°
+  field_column_names: é …ç›®
+  field_time_entries: æ™‚é–“ã‚’è¨˜éŒ²
+  field_time_zone: ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³
+  field_searchable: æ¤œç´¢æ¡ä»¶ã«è¨­å®šå¯èƒ½ã¨ã™ã‚‹
+  field_default_value: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤
+  field_comments_sorting: ã‚³ãƒ¡ãƒ³ãƒˆã®è¡¨ç¤ºé †
+  field_parent_title: è¦ªãƒšãƒ¼ã‚¸
+  field_editable: ç·¨é›†å¯èƒ½
+  field_watcher: ã‚¦ã‚©ãƒƒãƒãƒ£ãƒ¼
+  field_identity_url: OpenID URL
+  field_content: å†…å®¹
+  field_group_by: ã‚°ãƒ«ãƒ¼ãƒ—æ¡ä»¶
+  field_sharing: å…±æœ‰
+  field_parent_issue: è¦ªãƒã‚±ãƒƒãƒˆ
+  field_member_of_group: æ‹…å½“è€…ã®ã‚°ãƒ«ãƒ¼ãƒ—
+  field_assigned_to_role: æ‹…å½“è€…ã®ãƒ­ãƒ¼ãƒ«
+  field_text: ãƒ†ã‚­ã‚¹ãƒˆ
+  field_visible: è¡¨ç¤º
+  field_warn_on_leaving_unsaved: ãƒ‡ãƒ¼ã‚¿ã‚’ä¿å­˜ã›ãšã«ãƒšãƒ¼ã‚¸ã‹ã‚‰ç§»å‹•ã™ã‚‹ã¨ãã«è­¦å‘Š
+  field_commit_logs_encoding: ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°
+  field_scm_path_encoding: ãƒ‘ã‚¹ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°
+  field_path_to_repository: ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ‘ã‚¹
+  field_root_directory: ãƒ«ãƒ¼ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª
+  field_cvsroot: CVSROOT
+  field_cvs_module: ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«
+
+  setting_app_title: ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚¿ã‚¤ãƒˆãƒ«
+  setting_app_subtitle: ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚µãƒ–ã‚¿ã‚¤ãƒˆãƒ«
+  setting_welcome_text: ã‚¦ã‚§ãƒ«ã‚«ãƒ ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
+  setting_default_language: æ—¢å®šã®è¨€èªž
+  setting_login_required: èªè¨¼ãŒå¿…è¦
+  setting_self_registration: ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã‚ˆã‚‹ã‚¢ã‚«ã‚¦ãƒ³ãƒˆç™»éŒ²
+  setting_attachment_max_size: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ä¸Šé™
+  setting_issues_export_limit: ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã™ã‚‹ãƒã‚±ãƒƒãƒˆæ•°ã®ä¸Šé™
+  setting_mail_from: é€ä¿¡å…ƒãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹
+  setting_bcc_recipients: ãƒ–ãƒ©ã‚¤ãƒ³ãƒ‰ã‚«ãƒ¼ãƒœãƒ³ã‚³ãƒ”ãƒ¼ã§å—ä¿¡(bcc)
+  setting_plain_text_mail: ãƒ—ãƒ¬ã‚¤ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®ã¿(HTMLãªã—)
+  setting_host_name: ãƒ›ã‚¹ãƒˆå
+  setting_text_formatting: ãƒ†ã‚­ã‚¹ãƒˆã®æ›¸å¼
+  setting_cache_formatted_text: æ›¸å¼åŒ–ã•ã‚ŒãŸãƒ†ã‚­ã‚¹ãƒˆã‚’ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã™ã‚‹
+  setting_wiki_compression: Wikiå±¥æ­´ã‚’åœ§ç¸®ã™ã‚‹
+  setting_feeds_limit: ãƒ•ã‚£ãƒ¼ãƒ‰å†…å®¹ã®ä¸Šé™
+  setting_default_projects_public: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§æ–°ã—ã„ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¯å…¬é–‹ã«ã™ã‚‹
+  setting_autofetch_changesets: ã‚³ãƒŸãƒƒãƒˆã‚’è‡ªå‹•å–å¾—ã™ã‚‹
+  setting_sys_api_enabled: ãƒªãƒã‚¸ãƒˆãƒªç®¡ç†ç”¨ã®Webã‚µãƒ¼ãƒ“ã‚¹ã‚’æœ‰åŠ¹ã«ã™ã‚‹
+  setting_commit_ref_keywords: å‚ç…§ç”¨ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰
+  setting_commit_fix_keywords: ä¿®æ­£ç”¨ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰
+  setting_autologin: è‡ªå‹•ãƒ­ã‚°ã‚¤ãƒ³
+  setting_date_format: æ—¥ä»˜ã®å½¢å¼
+  setting_time_format: æ™‚åˆ»ã®å½¢å¼
+  setting_cross_project_issue_relations: ç•°ãªã‚‹ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ãƒã‚±ãƒƒãƒˆé–“ã§é–¢é€£ã®è¨­å®šã‚’è¨±å¯
+  setting_issue_list_default_columns: ãƒã‚±ãƒƒãƒˆã®ä¸€è¦§ã§è¡¨ç¤ºã™ã‚‹é …ç›®
+  setting_repositories_encodings: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒªãƒã‚¸ãƒˆãƒªã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°
+  setting_emails_header: ãƒ¡ãƒ¼ãƒ«ã®ãƒ˜ãƒƒãƒ€
+  setting_emails_footer: ãƒ¡ãƒ¼ãƒ«ã®ãƒ•ãƒƒã‚¿
+  setting_protocol: ãƒ—ãƒ­ãƒˆã‚³ãƒ«
+  setting_per_page_options: ãƒšãƒ¼ã‚¸æ¯Žã®è¡¨ç¤ºä»¶æ•°
+  setting_user_format: ãƒ¦ãƒ¼ã‚¶ãƒ¼åã®è¡¨ç¤ºæ›¸å¼
+  setting_activity_days_default: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®æ´»å‹•ãƒšãƒ¼ã‚¸ã«è¡¨ç¤ºã•ã‚Œã‚‹æ—¥æ•°
+  setting_display_subprojects_issues: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ãƒã‚±ãƒƒãƒˆã‚’ãƒ¡ã‚¤ãƒ³ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«è¡¨ç¤ºã™ã‚‹
+  setting_enabled_scm: ä½¿ç”¨ã™ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã‚·ã‚¹ãƒ†ãƒ 
+  setting_mail_handler_body_delimiters: "ãƒ¡ãƒ¼ãƒ«æœ¬æ–‡ã‹ã‚‰ä¸€è‡´ã™ã‚‹è¡Œä»¥é™ã‚’åˆ‡ã‚Šå–ã‚‹"
+  setting_mail_handler_api_enabled: å—ä¿¡ãƒ¡ãƒ¼ãƒ«ç”¨ã®Webã‚µãƒ¼ãƒ“ã‚¹ã‚’æœ‰åŠ¹ã«ã™ã‚‹
+  setting_mail_handler_api_key: APIã‚­ãƒ¼
+  setting_sequential_project_identifiers: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆè­˜åˆ¥å­ã‚’é€£ç•ªã§ç”Ÿæˆã™ã‚‹
+  setting_gravatar_enabled: Gravatarã®ã‚¢ã‚¤ã‚³ãƒ³ã‚’ä½¿ç”¨ã™ã‚‹
+  setting_gravatar_default: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®Gravatarã‚¢ã‚¤ã‚³ãƒ³
+  setting_diff_max_lines_displayed: å·®åˆ†ã®è¡¨ç¤ºè¡Œæ•°ã®ä¸Šé™
+  setting_file_max_size_displayed: ç”»é¢è¡¨ç¤ºã™ã‚‹ãƒ†ã‚­ã‚¹ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ä¸Šé™
+  setting_repository_log_display_limit: ãƒ•ã‚¡ã‚¤ãƒ«ã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³è¡¨ç¤ºæ•°ã®ä¸Šé™
+  setting_openid: OpenIDã«ã‚ˆã‚‹ãƒ­ã‚°ã‚¤ãƒ³ã¨ç™»éŒ²
+  setting_password_min_length: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®æœ€ä½Žå¿…è¦æ–‡å­—æ•°
+  setting_new_project_user_role_id: ã‚·ã‚¹ãƒ†ãƒ ç®¡ç†è€…ä»¥å¤–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒä½œæˆã—ãŸãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«è¨­å®šã™ã‚‹ãƒ­ãƒ¼ãƒ«
+  setting_default_projects_modules: æ–°è¦ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«ãŠã„ã¦ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§æœ‰åŠ¹ã«ãªã‚‹ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«
+  setting_issue_done_ratio: é€²æ—ã®ç®—å‡ºæ–¹æ³•
+  setting_issue_done_ratio_issue_field: å„ãƒã‚±ãƒƒãƒˆã«ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ç”¨æ„ã™ã‚‹
+  setting_issue_done_ratio_issue_status: ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’ä½¿ç”¨ã™ã‚‹
+  setting_start_of_week: é€±ã®é–‹å§‹æ›œæ—¥
+  setting_rest_api_enabled: RESTã«ã‚ˆã‚‹Webã‚µãƒ¼ãƒ“ã‚¹ã‚’æœ‰åŠ¹ã«ã™ã‚‹
+  setting_default_notification_option: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã‚ªãƒ—ã‚·ãƒ§ãƒ³
+  setting_commit_logtime_enabled: ã‚³ãƒŸãƒƒãƒˆæ™‚ã«ä½œæ¥­æ™‚é–“ã‚’è¨˜éŒ²ã™ã‚‹
+  setting_commit_logtime_activity_id: ä½œæ¥­æ™‚é–“ã®ä½œæ¥­åˆ†é¡ž
+  setting_gantt_items_limit: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆæœ€å¤§è¡¨ç¤ºé …ç›®æ•°
+  setting_default_projects_tracker_ids: æ–°è¦ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«ãŠã„ã¦ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§æœ‰åŠ¹ã«ãªã‚‹ãƒˆãƒ©ãƒƒã‚«ãƒ¼
+
+  permission_add_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®è¿½åŠ 
+  permission_add_subprojects: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®è¿½åŠ 
+  permission_edit_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ç·¨é›†
+  permission_select_project_modules: ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã®é¸æŠž
+  permission_manage_members: ãƒ¡ãƒ³ãƒãƒ¼ã®ç®¡ç†
+  permission_manage_versions: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ç®¡ç†
+  permission_manage_categories: ãƒã‚±ãƒƒãƒˆã®ã‚«ãƒ†ã‚´ãƒªã®ç®¡ç†
+  permission_view_issues: ãƒã‚±ãƒƒãƒˆã®é–²è¦§
+  permission_add_issues: ãƒã‚±ãƒƒãƒˆã®è¿½åŠ 
+  permission_edit_issues: ãƒã‚±ãƒƒãƒˆã®ç·¨é›†
+  permission_manage_issue_relations: é–¢é€£ã™ã‚‹ãƒã‚±ãƒƒãƒˆã®ç®¡ç†
+  permission_add_issue_notes: æ³¨è¨˜ã®è¿½åŠ 
+  permission_edit_issue_notes: æ³¨è¨˜ã®ç·¨é›†
+  permission_edit_own_issue_notes: è‡ªèº«ãŒè¨˜å…¥ã—ãŸæ³¨è¨˜ã®ç·¨é›†
+  permission_move_issues: ãƒã‚±ãƒƒãƒˆã®ç§»å‹•
+  permission_delete_issues: ãƒã‚±ãƒƒãƒˆã®å‰Šé™¤
+  permission_manage_public_queries: å…¬é–‹ã‚¯ã‚¨ãƒªã®ç®¡ç†
+  permission_save_queries: ã‚¯ã‚¨ãƒªã®ä¿å­˜
+  permission_view_gantt: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆã®é–²è¦§
+  permission_view_calendar: ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼ã®é–²è¦§
+  permission_view_issue_watchers: ã‚¦ã‚©ãƒƒãƒãƒ£ãƒ¼ä¸€è¦§ã®é–²è¦§
+  permission_add_issue_watchers: ã‚¦ã‚©ãƒƒãƒãƒ£ãƒ¼ã®è¿½åŠ 
+  permission_delete_issue_watchers: ã‚¦ã‚©ãƒƒãƒãƒ£ãƒ¼ã®å‰Šé™¤
+  permission_log_time: ä½œæ¥­æ™‚é–“ã®è¨˜å…¥
+  permission_view_time_entries: ä½œæ¥­æ™‚é–“ã®é–²è¦§
+  permission_edit_time_entries: ä½œæ¥­æ™‚é–“ã®ç·¨é›†
+  permission_edit_own_time_entries: è‡ªèº«ãŒè¨˜å…¥ã—ãŸä½œæ¥­æ™‚é–“ã®ç·¨é›†
+  permission_manage_project_activities: ä½œæ¥­åˆ†é¡ž (æ™‚é–“ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°) ã®ç®¡ç†
+  permission_manage_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã®ç®¡ç†
+  permission_comment_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã¸ã®ã‚³ãƒ¡ãƒ³ãƒˆ
+  permission_view_documents: æ–‡æ›¸ã®é–²è¦§
+  permission_manage_files: ãƒ•ã‚¡ã‚¤ãƒ«ã®ç®¡ç†
+  permission_view_files: ãƒ•ã‚¡ã‚¤ãƒ«ã®é–²è¦§
+  permission_manage_wiki: Wikiã®ç®¡ç†
+  permission_rename_wiki_pages: Wikiãƒšãƒ¼ã‚¸åã®å¤‰æ›´
+  permission_delete_wiki_pages: Wikiãƒšãƒ¼ã‚¸ã®å‰Šé™¤
+  permission_view_wiki_pages: Wikiã®é–²è¦§
+  permission_export_wiki_pages: Wikiãƒšãƒ¼ã‚¸ã‚’ä»–ã®å½¢å¼ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ
+  permission_view_wiki_edits: Wikiå±¥æ­´ã®é–²è¦§
+  permission_edit_wiki_pages: Wikiãƒšãƒ¼ã‚¸ã®ç·¨é›†
+  permission_delete_wiki_pages_attachments: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã®å‰Šé™¤
+  permission_protect_wiki_pages: Wikiãƒšãƒ¼ã‚¸ã®å‡çµ
+  permission_manage_repository: ãƒªãƒã‚¸ãƒˆãƒªã®ç®¡ç†
+  permission_browse_repository: ãƒªãƒã‚¸ãƒˆãƒªã®é–²è¦§
+  permission_view_changesets: æ›´æ–°å±¥æ­´ã®é–²è¦§
+  permission_commit_access: ã‚³ãƒŸãƒƒãƒˆæ¨©é™
+  permission_manage_boards: ãƒ•ã‚©ãƒ¼ãƒ©ãƒ ã®ç®¡ç†
+  permission_view_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®é–²è¦§
+  permission_add_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®è¿½åŠ 
+  permission_edit_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ç·¨é›†
+  permission_edit_own_messages: è‡ªèº«ãŒè¨˜å…¥ã—ãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ç·¨é›†
+  permission_delete_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®å‰Šé™¤
+  permission_delete_own_messages: è‡ªèº«ãŒè¨˜å…¥ã—ãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®å‰Šé™¤
+  permission_manage_subtasks: å­ãƒã‚±ãƒƒãƒˆã®ç®¡ç†
+
+  project_module_issue_tracking: ãƒã‚±ãƒƒãƒˆãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°
+  project_module_time_tracking: æ™‚é–“ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°
+  project_module_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹
+  project_module_documents: æ–‡æ›¸
+  project_module_files: ãƒ•ã‚¡ã‚¤ãƒ«
+  project_module_wiki: Wiki
+  project_module_repository: ãƒªãƒã‚¸ãƒˆãƒª
+  project_module_boards: ãƒ•ã‚©ãƒ¼ãƒ©ãƒ 
+  project_module_gantt: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆ
+  project_module_calendar: ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼
+
+  label_user: ãƒ¦ãƒ¼ã‚¶ãƒ¼
+  label_user_plural: ãƒ¦ãƒ¼ã‚¶ãƒ¼
+  label_user_new: æ–°ã—ã„ãƒ¦ãƒ¼ã‚¶ãƒ¼
+  label_user_anonymous: åŒ¿åãƒ¦ãƒ¼ã‚¶ãƒ¼
+  label_profile: ãƒ—ãƒ­ãƒ•ã‚£ãƒ¼ãƒ«
+  label_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_project_new: æ–°ã—ã„ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_project_plural: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_x_projects:
+    zero:  ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“
+    one:   1ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+    other: "%{count}ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ"
+  label_project_all: å…¨ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_project_latest: æœ€è¿‘ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_issue: ãƒã‚±ãƒƒãƒˆ
+  label_issue_new: æ–°ã—ã„ãƒã‚±ãƒƒãƒˆ
+  label_issue_plural: ãƒã‚±ãƒƒãƒˆ
+  label_issue_view_all: ã™ã¹ã¦ã®ãƒã‚±ãƒƒãƒˆã‚’è¦‹ã‚‹
+  label_issues_by: "%{value} åˆ¥ã®ãƒã‚±ãƒƒãƒˆ"
+  label_issue_added: ãƒã‚±ãƒƒãƒˆãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
+  label_issue_updated: ãƒã‚±ãƒƒãƒˆãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ
+  label_document: æ–‡æ›¸
+  label_document_new: æ–°ã—ã„æ–‡æ›¸
+  label_document_plural: æ–‡æ›¸
+  label_document_added: æ–‡æ›¸ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
+  label_role: ãƒ­ãƒ¼ãƒ«
+  label_role_plural: ãƒ­ãƒ¼ãƒ«
+  label_role_new: æ–°ã—ã„ãƒ­ãƒ¼ãƒ«
+  label_role_and_permissions: ãƒ­ãƒ¼ãƒ«ã¨æ¨©é™
+  label_member: ãƒ¡ãƒ³ãƒãƒ¼
+  label_member_new: æ–°ã—ã„ãƒ¡ãƒ³ãƒãƒ¼
+  label_member_plural: ãƒ¡ãƒ³ãƒãƒ¼
+  label_tracker: ãƒˆãƒ©ãƒƒã‚«ãƒ¼
+  label_tracker_plural: ãƒˆãƒ©ãƒƒã‚«ãƒ¼
+  label_tracker_new: æ–°ã—ã„ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã‚’ä½œæˆ
+  label_workflow: ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼
+  label_issue_status: ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
+  label_issue_status_plural: ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
+  label_issue_status_new: æ–°ã—ã„ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
+  label_issue_category: ãƒã‚±ãƒƒãƒˆã®ã‚«ãƒ†ã‚´ãƒª
+  label_issue_category_plural: ãƒã‚±ãƒƒãƒˆã®ã‚«ãƒ†ã‚´ãƒª
+  label_issue_category_new: æ–°ã—ã„ã‚«ãƒ†ã‚´ãƒª
+  label_custom_field: ã‚«ã‚¹ã‚¿ãƒ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰
+  label_custom_field_plural: ã‚«ã‚¹ã‚¿ãƒ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰
+  label_custom_field_new: æ–°ã—ã„ã‚«ã‚¹ã‚¿ãƒ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ä½œæˆ
+  label_enumerations: åˆ—æŒ™é …ç›®
+  label_enumeration_new: æ–°ã—ã„å€¤
+  label_information: æƒ…å ±
+  label_information_plural: æƒ…å ±
+  label_please_login: ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ãã ã•ã„
+  label_register: ç™»éŒ²ã™ã‚‹
+  label_login_with_open_id_option: ã¾ãŸã¯OpenIDã§ãƒ­ã‚°ã‚¤ãƒ³ã™ã‚‹
+  label_password_lost: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®å†ç™ºè¡Œ
+  label_home: ãƒ›ãƒ¼ãƒ 
+  label_my_page: ãƒžã‚¤ãƒšãƒ¼ã‚¸
+  label_my_account: å€‹äººè¨­å®š
+  label_my_projects: ãƒžã‚¤ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_my_page_block: ãƒžã‚¤ãƒšãƒ¼ã‚¸ãƒ‘ãƒ¼ãƒ„
+  label_administration: ç®¡ç†
+  label_login: ãƒ­ã‚°ã‚¤ãƒ³
+  label_logout: ãƒ­ã‚°ã‚¢ã‚¦ãƒˆ
+  label_help: ãƒ˜ãƒ«ãƒ—
+  label_reported_issues: å ±å‘Šã—ãŸãƒã‚±ãƒƒãƒˆ
+  label_assigned_to_me_issues: æ‹…å½“ã—ã¦ã„ã‚‹ãƒã‚±ãƒƒãƒˆ
+  label_last_login: æœ€è¿‘ã®æŽ¥ç¶š
+  label_registered_on: ç™»éŒ²æ—¥
+  label_activity: æ´»å‹•
+  label_overall_activity: ã™ã¹ã¦ã®æ´»å‹•
+  label_user_activity: "%{value} ã®æ´»å‹•"
+  label_new: æ–°ã—ãä½œæˆ
+  label_logged_as: ãƒ­ã‚°ã‚¤ãƒ³ä¸­ï¼š
+  label_environment: ç’°å¢ƒ
+  label_authentication: èªè¨¼
+  label_auth_source: èªè¨¼æ–¹å¼
+  label_auth_source_new: æ–°ã—ã„èªè¨¼æ–¹å¼
+  label_auth_source_plural: èªè¨¼æ–¹å¼
+  label_subproject_plural: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_subproject_new: æ–°ã—ã„ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_and_its_subprojects: "%{value} ã¨ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ"
+  label_min_max_length: æœ€å°å€¤ - æœ€å¤§å€¤ã®é•·ã•
+  label_list: ãƒªã‚¹ãƒˆã‹ã‚‰é¸æŠž
+  label_date: æ—¥ä»˜
+  label_integer: æ•´æ•°
+  label_float: å°æ•°
+  label_boolean: çœŸå½å€¤
+  label_string: ãƒ†ã‚­ã‚¹ãƒˆ
+  label_text: é•·ã„ãƒ†ã‚­ã‚¹ãƒˆ
+  label_attribute: å±žæ€§
+  label_attribute_plural: å±žæ€§
+  label_no_data: è¡¨ç¤ºã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãŒã‚ã‚Šã¾ã›ã‚“
+  label_change_status: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®å¤‰æ›´
+  label_history: å±¥æ­´
+  label_attachment: ãƒ•ã‚¡ã‚¤ãƒ«
+  label_attachment_new: æ–°ã—ã„ãƒ•ã‚¡ã‚¤ãƒ«
+  label_attachment_delete: ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å‰Šé™¤
+  label_attachment_plural: ãƒ•ã‚¡ã‚¤ãƒ«
+  label_file_added: ãƒ•ã‚¡ã‚¤ãƒ«ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
+  label_report: ãƒ¬ãƒãƒ¼ãƒˆ
+  label_report_plural: ãƒ¬ãƒãƒ¼ãƒˆ
+  label_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹
+  label_news_new: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã‚’è¿½åŠ 
+  label_news_plural: ãƒ‹ãƒ¥ãƒ¼ã‚¹
+  label_news_latest: æœ€æ–°ãƒ‹ãƒ¥ãƒ¼ã‚¹
+  label_news_view_all: ã™ã¹ã¦ã®ãƒ‹ãƒ¥ãƒ¼ã‚¹ã‚’è¦‹ã‚‹
+  label_news_added: ãƒ‹ãƒ¥ãƒ¼ã‚¹ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
+  label_news_comment_added: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã«ã‚³ãƒ¡ãƒ³ãƒˆãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
+  label_settings: è¨­å®š
+  label_overview: æ¦‚è¦
+  label_version: ãƒãƒ¼ã‚¸ãƒ§ãƒ³
+  label_version_new: æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³
+  label_version_plural: ãƒãƒ¼ã‚¸ãƒ§ãƒ³
+  label_confirmation: ç¢ºèª
+  label_close_versions: å®Œäº†ã—ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’çµ‚äº†ã«ã™ã‚‹
+  label_export_to: 'ä»–ã®å½¢å¼ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ:'
+  label_read: èª­ã‚€...
+  label_public_projects: å…¬é–‹ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_open_issues: æœªå®Œäº†
+  label_open_issues_plural: æœªå®Œäº†
+  label_closed_issues: å®Œäº†
+  label_closed_issues_plural: å®Œäº†
+  label_x_open_issues_abbr_on_total:
+    zero:  0ä»¶æœªå®Œäº† / å…¨%{total}ä»¶
+    one:   1ä»¶æœªå®Œäº† / å…¨%{total}ä»¶
+    other: "%{count}ä»¶æœªå®Œäº† / å…¨%{total}ä»¶"
+  label_x_open_issues_abbr:
+    zero:  0ä»¶æœªå®Œäº†
+    one:   1ä»¶æœªå®Œäº†
+    other: "%{count}ä»¶æœªå®Œäº†"
+  label_x_closed_issues_abbr:
+    zero:  0ä»¶å®Œäº†
+    one:   1ä»¶å®Œäº†
+    other: "%{count}ä»¶å®Œäº†"
+  label_total: åˆè¨ˆ
+  label_permissions: æ¨©é™
+  label_current_status: ç¾åœ¨ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
+  label_new_statuses_allowed: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®ç§»è¡Œå…ˆ
+  label_all: ã™ã¹ã¦
+  label_none: ãªã—
+  label_nobody: ç„¡è¨˜å
+  label_next: æ¬¡
+  label_previous: å‰
+  label_used_by: ä½¿ç”¨ä¸­
+  label_details: è©³ç´°
+  label_add_note: æ³¨è¨˜ã‚’è¿½åŠ 
+  label_per_page: ãƒšãƒ¼ã‚¸æ¯Ž
+  label_calendar: ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼
+  label_months_from: ãƒ¶æœˆåˆ†
+  label_gantt: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆ
+  label_internal: å†…éƒ¨
+  label_last_changes: "æœ€æ–°ã®å¤‰æ›´ %{count}ä»¶"
+  label_change_view_all: ã™ã¹ã¦ã®å¤‰æ›´ã‚’è¦‹ã‚‹
+  label_personalize_page: ã“ã®ãƒšãƒ¼ã‚¸ã‚’ãƒ‘ãƒ¼ã‚½ãƒŠãƒ©ã‚¤ã‚ºã™ã‚‹
+  label_comment: ã‚³ãƒ¡ãƒ³ãƒˆ
+  label_comment_plural: ã‚³ãƒ¡ãƒ³ãƒˆ
+  label_x_comments:
+    zero: ã‚³ãƒ¡ãƒ³ãƒˆãŒã‚ã‚Šã¾ã›ã‚“
+    one: 1ã‚³ãƒ¡ãƒ³ãƒˆ
+    other: "%{count}ã‚³ãƒ¡ãƒ³ãƒˆ"
+  label_comment_add: ã‚³ãƒ¡ãƒ³ãƒˆè¿½åŠ 
+  label_comment_added: è¿½åŠ ã•ã‚ŒãŸã‚³ãƒ¡ãƒ³ãƒˆ
+  label_comment_delete: ã‚³ãƒ¡ãƒ³ãƒˆå‰Šé™¤
+  label_query: ã‚«ã‚¹ã‚¿ãƒ ã‚¯ã‚¨ãƒª
+  label_query_plural: ã‚«ã‚¹ã‚¿ãƒ ã‚¯ã‚¨ãƒª
+  label_query_new: æ–°ã—ã„ã‚¯ã‚¨ãƒª
+  label_my_queries: ãƒžã‚¤ã‚«ã‚¹ã‚¿ãƒ ã‚¯ã‚¨ãƒª
+  label_filter_add: ãƒ•ã‚£ãƒ«ã‚¿è¿½åŠ 
+  label_filter_plural: ãƒ•ã‚£ãƒ«ã‚¿
+  label_equals: ç­‰ã—ã„
+  label_not_equals: ç­‰ã—ããªã„
+  label_in_less_than: ä»Šæ—¥ã‹ã‚‰â—‹æ—¥å¾Œä»¥å‰
+  label_in_more_than: ä»Šæ—¥ã‹ã‚‰â—‹æ—¥å¾Œä»¥é™
+  label_greater_or_equal: ä»¥ä¸Š
+  label_less_or_equal: ä»¥ä¸‹
+  label_in: ä»Šæ—¥ã‹ã‚‰â—‹æ—¥å¾Œ
+  label_today: ä»Šæ—¥
+  label_all_time: å…¨æœŸé–“
+  label_yesterday: æ˜¨æ—¥
+  label_this_week: ä»Šé€±
+  label_last_week: å…ˆé€±
+  label_last_n_days: "ç›´è¿‘%{count}æ—¥é–“"
+  label_this_month: ä»Šæœˆ
+  label_last_month: å…ˆæœˆ
+  label_this_year: ä»Šå¹´
+  label_date_range: æœŸé–“
+  label_less_than_ago: ä»Šæ—¥ã‚ˆã‚Šâ—‹æ—¥å‰ä»¥é™
+  label_more_than_ago: ä»Šæ—¥ã‚ˆã‚Šâ—‹æ—¥å‰ä»¥å‰
+  label_ago: â—‹æ—¥å‰
+  label_contains: å«ã‚€
+  label_not_contains: å«ã¾ãªã„
+  label_day_plural: æ—¥
+  label_repository: ãƒªãƒã‚¸ãƒˆãƒª
+  label_repository_plural: ãƒªãƒã‚¸ãƒˆãƒª
+  label_browse: ãƒ–ãƒ©ã‚¦ã‚º
+  label_branch: ãƒ–ãƒ©ãƒ³ãƒ
+  label_tag: ã‚¿ã‚°
+  label_revision: ãƒªãƒ“ã‚¸ãƒ§ãƒ³
+  label_revision_plural: ãƒªãƒ“ã‚¸ãƒ§ãƒ³
+  label_revision_id: ãƒªãƒ“ã‚¸ãƒ§ãƒ³ %{value}
+  label_associated_revisions: é–¢ä¿‚ã—ã¦ã„ã‚‹ãƒªãƒ“ã‚¸ãƒ§ãƒ³
+  label_added: è¿½åŠ 
+  label_modified: å¤‰æ›´
+  label_copied: ã‚³ãƒ”ãƒ¼
+  label_renamed: åç§°å¤‰æ›´
+  label_deleted: å‰Šé™¤
+  label_latest_revision: æœ€æ–°ãƒªãƒ“ã‚¸ãƒ§ãƒ³
+  label_latest_revision_plural: æœ€æ–°ãƒªãƒ“ã‚¸ãƒ§ãƒ³
+  label_view_revisions: ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã‚’è¦‹ã‚‹
+  label_view_all_revisions: ã™ã¹ã¦ã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã‚’è¦‹ã‚‹
+  label_max_size: ã‚µã‚¤ã‚ºã®ä¸Šé™
+  label_sort_highest: ä¸€ç•ªä¸Šã¸
+  label_sort_higher: ä¸Šã¸
+  label_sort_lower: ä¸‹ã¸
+  label_sort_lowest: ä¸€ç•ªä¸‹ã¸
+  label_roadmap: ãƒ­ãƒ¼ãƒ‰ãƒžãƒƒãƒ—
+  label_roadmap_due_in: "æœŸæ—¥ã¾ã§ %{value}"
+  label_roadmap_overdue: "%{value} é…ã‚Œ"
+  label_roadmap_no_issues: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«é–¢ã™ã‚‹ãƒã‚±ãƒƒãƒˆã¯ã‚ã‚Šã¾ã›ã‚“
+  label_search: æ¤œç´¢
+  label_result_plural: çµæžœ
+  label_all_words: ã™ã¹ã¦ã®å˜èªž
+  label_wiki: Wiki
+  label_wiki_edit: Wikiç·¨é›†
+  label_wiki_edit_plural: Wikiç·¨é›†
+  label_wiki_page: Wikiãƒšãƒ¼ã‚¸
+  label_wiki_page_plural: Wikiãƒšãƒ¼ã‚¸
+  label_index_by_title: ç´¢å¼•(åå‰é †)
+  label_index_by_date: ç´¢å¼•(æ—¥ä»˜é †)
+  label_current_version: æœ€æ–°ç‰ˆ
+  label_preview: ãƒ—ãƒ¬ãƒ“ãƒ¥ãƒ¼
+  label_feed_plural: ãƒ•ã‚£ãƒ¼ãƒ‰
+  label_changes_details: å…¨å¤‰æ›´ã®è©³ç´°
+  label_issue_tracking: ãƒã‚±ãƒƒãƒˆãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°
+  label_spent_time: ä½œæ¥­æ™‚é–“ã®è¨˜éŒ²
+  label_overall_spent_time: ã™ã¹ã¦ã®ä½œæ¥­æ™‚é–“ã®è¨˜éŒ²
+  label_f_hour: "%{value}æ™‚é–“"
+  label_f_hour_plural: "%{value}æ™‚é–“"
+  label_time_tracking: æ™‚é–“ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°
+  label_change_plural: å¤‰æ›´
+  label_statistics: çµ±è¨ˆ
+  label_commits_per_month: æœˆåˆ¥ã®ã‚³ãƒŸãƒƒãƒˆ
+  label_commits_per_author: èµ·ç¥¨è€…åˆ¥ã®ã‚³ãƒŸãƒƒãƒˆ
+  label_diff: å·®åˆ†
+  label_view_diff: å·®åˆ†ã‚’è¦‹ã‚‹
+  label_diff_inline: ã‚¤ãƒ³ãƒ©ã‚¤ãƒ³
+  label_diff_side_by_side: æ¨ªã«ä¸¦ã¹ã‚‹
+  label_options: ã‚ªãƒ—ã‚·ãƒ§ãƒ³
+  label_copy_workflow_from: ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼ã‚’ã“ã“ã‹ã‚‰ã‚³ãƒ”ãƒ¼
+  label_permissions_report: æ¨©é™ãƒ¬ãƒãƒ¼ãƒˆ
+  label_watched_issues: ã‚¦ã‚©ãƒƒãƒã—ã¦ã„ã‚‹ãƒã‚±ãƒƒãƒˆ
+  label_related_issues: é–¢é€£ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
+  label_applied_status: é©ç”¨ã•ã‚Œã‚‹ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
+  label_loading: ãƒ­ãƒ¼ãƒ‰ä¸­...
+  label_relation_new: æ–°ã—ã„é–¢é€£
+  label_relation_delete: é–¢é€£ã®å‰Šé™¤
+  label_relates_to: é–¢é€£ã—ã¦ã„ã‚‹
+  label_duplicates: æ¬¡ã®ãƒã‚±ãƒƒãƒˆã¨é‡è¤‡
+  label_duplicated_by: æ¬¡ã®ãƒã‚±ãƒƒãƒˆãŒé‡è¤‡
+  label_blocks: ãƒ–ãƒ­ãƒƒã‚¯ã—ã¦ã„ã‚‹
+  label_blocked_by: ãƒ–ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã‚‹
+  label_precedes: æ¬¡ã®ãƒã‚±ãƒƒãƒˆã«å…ˆè¡Œ
+  label_follows: æ¬¡ã®ãƒã‚±ãƒƒãƒˆã«å¾Œç¶š
+  label_end_to_start: æœ€å¾Œ-æœ€åˆ
+  label_end_to_end: æœ€å¾Œ-æœ€å¾Œ
+  label_start_to_start: æœ€åˆ-æœ€åˆ
+  label_start_to_end: æœ€åˆ-æœ€å¾Œ
+  label_stay_logged_in: ãƒ­ã‚°ã‚¤ãƒ³ã‚’ç¶­æŒ
+  label_disabled: ç„¡åŠ¹
+  label_show_completed_versions: å®Œäº†ã—ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’è¡¨ç¤º
+  label_me: è‡ªåˆ†
+  label_board: ãƒ•ã‚©ãƒ¼ãƒ©ãƒ 
+  label_board_new: æ–°ã—ã„ãƒ•ã‚©ãƒ¼ãƒ©ãƒ 
+  label_board_plural: ãƒ•ã‚©ãƒ¼ãƒ©ãƒ 
+  label_board_sticky: ã‚¹ãƒ†ã‚£ãƒƒã‚­ãƒ¼
+  label_board_locked: ãƒ­ãƒƒã‚¯
+  label_topic_plural: ãƒˆãƒ”ãƒƒã‚¯
+  label_message_plural: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
+  label_message_last: æœ€æ–°ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
+  label_message_new: æ–°ã—ã„ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
+  label_message_posted: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
+  label_reply_plural: è¿”ç­”
+  label_send_information: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆæƒ…å ±ã‚’ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«é€ä¿¡
+  label_year: å¹´
+  label_month: æœˆ
+  label_week: é€±
+  label_date_from: "æ—¥ä»˜æŒ‡å®š: "
+  label_date_to: ã‹ã‚‰
+  label_language_based: ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®è¨€èªžã®è¨­å®šã«å¾“ã†
+  label_sort_by: "ä¸¦ã³æ›¿ãˆ %{value}"
+  label_send_test_email: ãƒ†ã‚¹ãƒˆãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡
+  label_feeds_access_key: RSSã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼
+  label_missing_feeds_access_key: RSSã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“
+  label_feeds_access_key_created_on: "RSSã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã¯%{value}å‰ã«ä½œæˆã•ã‚Œã¾ã—ãŸ"
+  label_module_plural: ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«
+  label_added_time_by: "%{author} ãŒ%{age}å‰ã«è¿½åŠ "
+  label_updated_time_by: "%{author} ãŒ%{age}å‰ã«æ›´æ–°"
+  label_updated_time: "%{value}å‰ã«æ›´æ–°"
+  label_jump_to_a_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¸ç§»å‹•...
+  label_file_plural: ãƒ•ã‚¡ã‚¤ãƒ«
+  label_changeset_plural: æ›´æ–°å±¥æ­´
+  label_default_columns: æ—¢å®šã®é …ç›®
+  label_no_change_option: (å¤‰æ›´ç„¡ã—)
+  label_bulk_edit_selected_issues: ãƒã‚±ãƒƒãƒˆã®ä¸€æ‹¬ç·¨é›†
+  label_theme: ãƒ†ãƒ¼ãƒž
+  label_default: æ—¢å®š
+  label_search_titles_only: ã‚¿ã‚¤ãƒˆãƒ«ã®ã¿
+  label_user_mail_option_all: "å‚åŠ ã—ã¦ã„ã‚‹ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ã™ã¹ã¦ã®é€šçŸ¥"
+  label_user_mail_option_selected: "é¸æŠžã—ãŸãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ã™ã¹ã¦ã®é€šçŸ¥..."
+  label_user_mail_option_none: "é€šçŸ¥ã—ãªã„"
+  label_user_mail_option_only_my_events: "ã‚¦ã‚©ãƒƒãƒã¾ãŸã¯é–¢ä¿‚ã—ã¦ã„ã‚‹äº‹æŸ„ã®ã¿"
+  label_user_mail_option_only_assigned: "è‡ªåˆ†ãŒæ‹…å½“ã—ã¦ã„ã‚‹äº‹æŸ„ã®ã¿"
+  label_user_mail_option_only_owner: "è‡ªåˆ†ãŒä½œæˆã—ãŸäº‹æŸ„ã®ã¿"
+  label_user_mail_no_self_notified: è‡ªåˆ†è‡ªèº«ã«ã‚ˆã‚‹å¤‰æ›´ã®é€šçŸ¥ã¯ä¸è¦
+  label_registration_activation_by_email: ãƒ¡ãƒ¼ãƒ«ã§ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’æœ‰åŠ¹åŒ–
+  label_registration_manual_activation: æ‰‹å‹•ã§ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’æœ‰åŠ¹åŒ–
+  label_registration_automatic_activation: è‡ªå‹•ã§ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’æœ‰åŠ¹åŒ–
+  label_display_per_page: "1ãƒšãƒ¼ã‚¸ã«: %{value}"
+  label_age: å¹´é½¢
+  label_change_properties: ãƒ—ãƒ­ãƒ‘ãƒ†ã‚£ã®å¤‰æ›´
+  label_general: å…¨èˆ¬
+  label_more: ç¶šã
+  label_scm: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã‚·ã‚¹ãƒ†ãƒ 
+  label_plugins: ãƒ—ãƒ©ã‚°ã‚¤ãƒ³
+  label_ldap_authentication: LDAPèªè¨¼
+  label_downloads_abbr: DL
+  label_optional_description: ä»»æ„ã®ã‚³ãƒ¡ãƒ³ãƒˆ
+  label_add_another_file: åˆ¥ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’è¿½åŠ 
+  label_preferences: è¨­å®š
+  label_chronological_order: å¤ã„é †
+  label_reverse_chronological_order: æ–°ã—ã„é †
+  label_planning: è¨ˆç”»
+  label_incoming_emails: å—ä¿¡ãƒ¡ãƒ¼ãƒ«
+  label_generate_key: ã‚­ãƒ¼ã®ç”Ÿæˆ
+  label_issue_watchers: ãƒã‚±ãƒƒãƒˆã®ã‚¦ã‚©ãƒƒãƒãƒ£ãƒ¼
+  label_example: ä¾‹
+  label_display: è¡¨ç¤º
+  label_sort: ã‚½ãƒ¼ãƒˆæ¡ä»¶
+  label_ascending: æ˜‡é †
+  label_descending: é™é †
+  label_date_from_to: "%{start}ã‹ã‚‰%{end}ã¾ã§"
+  label_wiki_content_added: Wikiãƒšãƒ¼ã‚¸ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
+  label_wiki_content_updated: Wikiãƒšãƒ¼ã‚¸ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ
+  label_group: ã‚°ãƒ«ãƒ¼ãƒ—
+  label_group_plural: ã‚°ãƒ«ãƒ¼ãƒ—
+  label_group_new: æ–°ã—ã„ã‚°ãƒ«ãƒ¼ãƒ—
+  label_time_entry_plural: ä½œæ¥­æ™‚é–“ã®è¨˜éŒ²
+  label_version_sharing_none: å…±æœ‰ã—ãªã„
+  label_version_sharing_descendants: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå˜ä½
+  label_version_sharing_hierarchy: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆéšŽå±¤å˜ä½
+  label_version_sharing_tree: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆãƒ„ãƒªãƒ¼å˜ä½
+  label_version_sharing_system: ã™ã¹ã¦ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  label_update_issue_done_ratios: é€²æ—ã®æ›´æ–°
+  label_copy_source: ã‚³ãƒ”ãƒ¼å…ƒ
+  label_copy_target: ã‚³ãƒ”ãƒ¼å…ˆ
+  label_copy_same_as_target: åŒã˜ã‚³ãƒ”ãƒ¼å…ˆ
+  label_display_used_statuses_only: ã“ã®ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã§ä½¿ã‚ã‚Œã¦ã„ã‚‹ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®ã¿è¡¨ç¤ºã™ã‚‹
+  label_api_access_key: APIã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼
+  label_missing_api_access_key: APIã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“
+  label_api_access_key_created_on: "APIã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã¯%{value}å‰ã«ä½œæˆã•ã‚Œã¾ã—ãŸ"
+  label_subtask_plural: å­ãƒã‚±ãƒƒãƒˆ
+  label_project_copy_notifications: ã‚³ãƒ”ãƒ¼ã—ãŸãƒã‚±ãƒƒãƒˆã®ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã‚’é€ä¿¡ã™ã‚‹
+  label_principal_search: "ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¾ãŸã¯ã‚°ãƒ«ãƒ¼ãƒ—ã®æ¤œç´¢:"
+  label_user_search: "ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®æ¤œç´¢:"
+  label_git_report_last_commit: ãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®æœ€æ–°ã‚³ãƒŸãƒƒãƒˆã‚’è¡¨ç¤ºã™ã‚‹
+  label_parent_revision: è¦ª
+  label_child_revision: å­
+  label_gantt_progress_line: ã‚¤ãƒŠã‚ºãƒžç·š
+
+  button_login: ãƒ­ã‚°ã‚¤ãƒ³
+  button_submit: é€ä¿¡
+  button_save: ä¿å­˜
+  button_check_all: ã™ã¹ã¦ã«ãƒã‚§ãƒƒã‚¯ã‚’ã¤ã‘ã‚‹
+  button_uncheck_all: ã™ã¹ã¦ã®ãƒã‚§ãƒƒã‚¯ã‚’å¤–ã™
+  button_expand_all: å±•é–‹
+  button_collapse_all: æŠ˜ã‚ŠãŸãŸã¿
+  button_delete: å‰Šé™¤
+  button_create: ä½œæˆ
+  button_create_and_continue: é€£ç¶šä½œæˆ
+  button_test: ãƒ†ã‚¹ãƒˆ
+  button_edit: ç·¨é›†
+  button_edit_associated_wikipage: "é–¢é€£ã™ã‚‹Wikiãƒšãƒ¼ã‚¸ã‚’ç·¨é›†: %{page_title}"
+  button_add: è¿½åŠ 
+  button_change: å¤‰æ›´
+  button_apply: é©ç”¨
+  button_clear: ã‚¯ãƒªã‚¢
+  button_lock: ãƒ­ãƒƒã‚¯
+  button_unlock: ã‚¢ãƒ³ãƒ­ãƒƒã‚¯
+  button_download: ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰
+  button_list: ä¸€è¦§
+  button_view: è¡¨ç¤º
+  button_move: ç§»å‹•
+  button_move_and_follow: ç§»å‹•å¾Œè¡¨ç¤º
+  button_back: æˆ»ã‚‹
+  button_cancel: ã‚­ãƒ£ãƒ³ã‚»ãƒ«
+  button_activate: æœ‰åŠ¹ã«ã™ã‚‹
+  button_sort: ã‚½ãƒ¼ãƒˆ
+  button_log_time: æ™‚é–“ã‚’è¨˜éŒ²
+  button_rollback: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯
+  button_watch: ã‚¦ã‚©ãƒƒãƒ
+  button_unwatch: ã‚¦ã‚©ãƒƒãƒã‚’ã‚„ã‚ã‚‹
+  button_reply: è¿”ç­”
+  button_archive: ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–
+  button_unarchive: ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–è§£é™¤
+  button_reset: ãƒªã‚»ãƒƒãƒˆ
+  button_rename: åå‰å¤‰æ›´
+  button_change_password: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰å¤‰æ›´
+  button_copy: ã‚³ãƒ”ãƒ¼
+  button_copy_and_follow: ã‚³ãƒ”ãƒ¼å¾Œè¡¨ç¤º
+  button_annotate: ã‚¢ãƒŽãƒ†ãƒ¼ãƒˆ
+  button_update: æ›´æ–°
+  button_configure: è¨­å®š
+  button_quote: å¼•ç”¨
+  button_duplicate: è¤‡è£½
+  button_show: è¡¨ç¤º
+
+  status_active: æœ‰åŠ¹
+  status_registered: ç™»éŒ²
+  status_locked: ãƒ­ãƒƒã‚¯
+
+  version_status_open: é€²è¡Œä¸­
+  version_status_locked: ãƒ­ãƒƒã‚¯ä¸­
+  version_status_closed: çµ‚äº†
+
+  field_active: æœ‰åŠ¹
+
+  text_select_mail_notifications: ã©ã®ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã‚’é€ä¿¡ã™ã‚‹ã‹ã€ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’é¸æŠžã—ã¦ãã ã•ã„ã€‚
+  text_regexp_info: ä¾‹) ^[A-Z0-9]+$
+  text_min_max_length_info: 0ã ã¨ç„¡åˆ¶é™ã«ãªã‚Šã¾ã™
+  text_project_destroy_confirmation: æœ¬å½“ã«ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¨é–¢é€£ãƒ‡ãƒ¼ã‚¿ã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
+  text_subprojects_destroy_warning: "ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ %{value} ã‚‚å‰Šé™¤ã•ã‚Œã¾ã™ã€‚"
+  text_workflow_edit: ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼ã‚’ç·¨é›†ã™ã‚‹ãƒ­ãƒ¼ãƒ«ã¨ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã‚’é¸ã‚“ã§ãã ã•ã„
+  text_are_you_sure: ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ
+  text_journal_changed: "%{label} ã‚’ %{old} ã‹ã‚‰ %{new} ã«å¤‰æ›´"
+  text_journal_changed_no_detail: "%{label} ã‚’æ›´æ–°"
+  text_journal_set_to: "%{label} ã‚’ %{value} ã«ã‚»ãƒƒãƒˆ"
+  text_journal_deleted: "%{label} ã‚’å‰Šé™¤ (%{old})"
+  text_journal_added: "%{label} %{value} ã‚’è¿½åŠ "
+  text_tip_issue_begin_day: ã“ã®æ—¥ã«é–‹å§‹ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
+  text_tip_issue_end_day: ã“ã®æ—¥ã«çµ‚äº†ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
+  text_tip_issue_begin_end_day: ã“ã®æ—¥ã«é–‹å§‹ãƒ»çµ‚äº†ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
+  text_caracters_maximum: "æœ€å¤§%{count}æ–‡å­—ã§ã™ã€‚"
+  text_caracters_minimum: "æœ€ä½Ž%{count}æ–‡å­—ã®é•·ã•ãŒå¿…è¦ã§ã™"
+  text_length_between: "é•·ã•ã¯%{min}ã‹ã‚‰%{max}æ–‡å­—ã¾ã§ã§ã™ã€‚"
+  text_tracker_no_workflow: ã“ã®ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã«ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“
+  text_unallowed_characters: æ¬¡ã®æ–‡å­—ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“
+  text_comma_separated: (ã‚«ãƒ³ãƒžã§åŒºåˆ‡ã‚‹ã“ã¨ã§)è¤‡æ•°ã®å€¤ã‚’è¨­å®šã§ãã¾ã™ã€‚
+  text_line_separated: (1è¡Œã”ã¨ã«æ›¸ãã“ã¨ã§)è¤‡æ•°ã®å€¤ã‚’è¨­å®šã§ãã¾ã™ã€‚
+  text_issues_ref_in_commit_messages: ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸å†…ã§ãƒã‚±ãƒƒãƒˆã®å‚ç…§/ä¿®æ­£
+  text_issue_added: "ãƒã‚±ãƒƒãƒˆ %{id} ãŒ %{author} ã«ã‚ˆã£ã¦å ±å‘Šã•ã‚Œã¾ã—ãŸã€‚"
+  text_issue_updated: "ãƒã‚±ãƒƒãƒˆ %{id} ãŒ %{author} ã«ã‚ˆã£ã¦æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
+  text_wiki_destroy_confirmation: æœ¬å½“ã«ã“ã®wikiã¨ãã®å†…å®¹ã®ã™ã¹ã¦ã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
+  text_issue_category_destroy_question: "%{count}ä»¶ã®ãƒã‚±ãƒƒãƒˆãŒã“ã®ã‚«ãƒ†ã‚´ãƒªã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚"
+  text_issue_category_destroy_assignments: ã‚«ãƒ†ã‚´ãƒªã®å‰²ã‚Šå½“ã¦ã‚’å‰Šé™¤ã™ã‚‹
+  text_issue_category_reassign_to: ãƒã‚±ãƒƒãƒˆã‚’ã“ã®ã‚«ãƒ†ã‚´ãƒªã«å†å‰²ã‚Šå½“ã¦ã™ã‚‹
+  text_user_mail_option: "æœªé¸æŠžã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã§ã¯ã€ã‚¦ã‚©ãƒƒãƒã¾ãŸã¯é–¢ä¿‚ã—ã¦ã„ã‚‹äº‹æŸ„(ä¾‹: è‡ªåˆ†ãŒå ±å‘Šè€…ã‚‚ã—ãã¯æ‹…å½“è€…ã§ã‚ã‚‹ãƒã‚±ãƒƒãƒˆ)ã®ã¿ãƒ¡ãƒ¼ãƒ«ãŒé€ä¿¡ã•ã‚Œã¾ã™ã€‚"
+  text_no_configuration_data: "ãƒ­ãƒ¼ãƒ«ã€ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã€ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã€ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼ãŒã¾ã è¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“ã€‚\nãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®šã®ãƒ­ãƒ¼ãƒ‰ã‚’å¼·ããŠå‹§ã‚ã—ã¾ã™ã€‚ãƒ­ãƒ¼ãƒ‰ã—ãŸå¾Œã€ãã‚Œã‚’ä¿®æ­£ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+  text_load_default_configuration: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®šã‚’ãƒ­ãƒ¼ãƒ‰
+  text_status_changed_by_changeset: "æ›´æ–°å±¥æ­´ %{value} ã§é©ç”¨ã•ã‚Œã¾ã—ãŸã€‚"
+  text_time_logged_by_changeset: "æ›´æ–°å±¥æ­´ %{value} ã§é©ç”¨ã•ã‚Œã¾ã—ãŸã€‚"
+  text_issues_destroy_confirmation: 'æœ¬å½“ã«é¸æŠžã—ãŸãƒã‚±ãƒƒãƒˆã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ'
+  text_select_project_modules: 'ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã§ä½¿ç”¨ã™ã‚‹ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„:'
+  text_default_administrator_account_changed: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆç®¡ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¤‰æ›´æ¸ˆ
+  text_file_repository_writable: ãƒ•ã‚¡ã‚¤ãƒ«ãƒªãƒã‚¸ãƒˆãƒªã«æ›¸ãè¾¼ã¿å¯èƒ½
+  text_plugin_assets_writable: Plugin assetsãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ›¸ãè¾¼ã¿å¯èƒ½
+  text_rmagick_available: RMagickãŒä½¿ç”¨å¯èƒ½ (ã‚ªãƒ—ã‚·ãƒ§ãƒ³)
+  text_destroy_time_entries_question: ã“ã®ãƒã‚±ãƒƒãƒˆã®%{hours}æ™‚é–“åˆ†ã®ä½œæ¥­è¨˜éŒ²ã®æ‰±ã„ã‚’é¸æŠžã—ã¦ãã ã•ã„ã€‚
+  text_destroy_time_entries: è¨˜éŒ²ã•ã‚ŒãŸä½œæ¥­æ™‚é–“ã‚’å«ã‚ã¦å‰Šé™¤
+  text_assign_time_entries_to_project: è¨˜éŒ²ã•ã‚ŒãŸä½œæ¥­æ™‚é–“ã‚’ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆè‡ªä½“ã«å‰²ã‚Šå½“ã¦
+  text_reassign_time_entries: 'è¨˜éŒ²ã•ã‚ŒãŸä½œæ¥­æ™‚é–“ã‚’ã“ã®ãƒã‚±ãƒƒãƒˆã«å†å‰²ã‚Šå½“ã¦ï¼š'
+  text_user_wrote: "%{value} ã¯æ›¸ãã¾ã—ãŸ:"
+  text_enumeration_destroy_question: "%{count}å€‹ã®ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒã“ã®å€¤ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚"
+  text_enumeration_category_reassign_to: 'æ¬¡ã®å€¤ã«å‰²ã‚Šå½“ã¦ç›´ã™:'
+  text_email_delivery_not_configured: "ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã™ã‚‹ãŸã‚ã«å¿…è¦ãªè¨­å®šãŒè¡Œã‚ã‚Œã¦ã„ãªã„ãŸã‚ã€ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“ã€‚\nconfig/configuration.ymlã§SMTPã‚µãƒ¼ãƒã®è¨­å®šã‚’è¡Œã„ã€ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„ã€‚"
+  text_repository_usernames_mapping: "ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ­ã‚°ã‹ã‚‰æ¤œå‡ºã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚’ã©ã®Redmineãƒ¦ãƒ¼ã‚¶ãƒ¼ã«é–¢é€£ã¥ã‘ã‚‹ã®ã‹é¸æŠžã—ã¦ãã ã•ã„ã€‚\nãƒ­ã‚°ä¸Šã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åã¾ãŸã¯ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒRedmineã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¨ä¸€è‡´ã™ã‚‹å ´åˆã¯è‡ªå‹•çš„ã«é–¢é€£ã¥ã‘ã‚‰ã‚Œã¾ã™ã€‚"
+  text_diff_truncated: '... å·®åˆ†ã®è¡Œæ•°ãŒè¡¨ç¤ºå¯èƒ½ãªä¸Šé™ã‚’è¶…ãˆã¾ã—ãŸã€‚è¶…éŽåˆ†ã¯è¡¨ç¤ºã—ã¾ã›ã‚“ã€‚'
+  text_custom_field_possible_values_info: 'é¸æŠžè‚¢ã®å€¤ã¯1è¡Œã«1å€‹ãšã¤è¨˜è¿°ã—ã¦ãã ã•ã„ã€‚'
+  text_wiki_page_destroy_question: "ã“ã®è¦ªãƒšãƒ¼ã‚¸ã®é…ä¸‹ã«%{descendants}ãƒšãƒ¼ã‚¸ã®å­å­«ãƒšãƒ¼ã‚¸ãŒã‚ã‚Šã¾ã™ã€‚"
+  text_wiki_page_nullify_children: "å­ãƒšãƒ¼ã‚¸ã‚’ãƒ¡ã‚¤ãƒ³ãƒšãƒ¼ã‚¸é…ä¸‹ã«ç§»å‹•ã™ã‚‹"
+  text_wiki_page_destroy_children: "é…ä¸‹ã®å­å­«ãƒšãƒ¼ã‚¸ã‚‚å‰Šé™¤ã™ã‚‹"
+  text_wiki_page_reassign_children: "å­ãƒšãƒ¼ã‚¸ã‚’æ¬¡ã®è¦ªãƒšãƒ¼ã‚¸ã®é…ä¸‹ã«ç§»å‹•ã™ã‚‹"
+  text_own_membership_delete_confirmation: "ä¸€éƒ¨ã¾ãŸã¯ã™ã¹ã¦ã®æ¨©é™ã‚’è‡ªåˆ†è‡ªèº«ã‹ã‚‰å‰¥å¥ªã—ã‚ˆã†ã¨ã—ã¦ã„ã‚‹ãŸã‚ã€ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã‚’ç·¨é›†ã§ããªããªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚\næœ¬å½“ã«ç¶šã‘ã¾ã™ã‹ï¼Ÿ"
+  text_zoom_in: æ‹¡å¤§
+  text_zoom_out: ç¸®å°
+  text_warn_on_leaving_unsaved: ã“ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰ç§»å‹•ã™ã‚‹ã¨ã€ä¿å­˜ã•ã‚Œã¦ã„ãªã„ãƒ‡ãƒ¼ã‚¿ãŒå¤±ã‚ã‚Œã¾ã™ã€‚
+  text_scm_path_encoding_note: "ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆ: UTF-8"
+  text_mercurial_repository_note: "ãƒ­ãƒ¼ã‚«ãƒ«ãƒªãƒã‚¸ãƒˆãƒª (ä¾‹: /hgrepo, c:\\hgrepo)"
+  text_git_repository_note: "Bareã€ã‹ã¤ã€ãƒ­ãƒ¼ã‚«ãƒ«ãƒªãƒã‚¸ãƒˆãƒª (ä¾‹: /gitrepo, c:\\gitrepo)"
+  text_scm_command: ã‚³ãƒžãƒ³ãƒ‰
+  text_scm_command_version: ãƒãƒ¼ã‚¸ãƒ§ãƒ³
+  text_scm_config: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã‚·ã‚¹ãƒ†ãƒ ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’config/configuration.ymlã§è¨­å®šã§ãã¾ã™ã€‚è¨­å®šå¾Œã€Redmineã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„ã€‚
+  text_scm_command_not_available: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã‚·ã‚¹ãƒ†ãƒ ã®ã‚³ãƒžãƒ³ãƒ‰ãŒåˆ©ç”¨ã§ãã¾ã›ã‚“ã€‚ç®¡ç†ç”»é¢ã«ã¦è¨­å®šã‚’ç¢ºèªã—ã¦ãã ã•ã„ã€‚
+
+  default_role_manager: ç®¡ç†è€…
+  default_role_developer: é–‹ç™ºè€…
+  default_role_reporter: å ±å‘Šè€…
+  default_tracker_bug: ãƒã‚°
+  default_tracker_feature: æ©Ÿèƒ½
+  default_tracker_support: ã‚µãƒãƒ¼ãƒˆ
+  default_issue_status_new: æ–°è¦
+  default_issue_status_in_progress: é€²è¡Œä¸­
+  default_issue_status_resolved: è§£æ±º
+  default_issue_status_feedback: ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯
+  default_issue_status_closed: çµ‚äº†
+  default_issue_status_rejected: å´ä¸‹
+  default_doc_category_user: ãƒ¦ãƒ¼ã‚¶ãƒ¼æ–‡æ›¸
+  default_doc_category_tech: æŠ€è¡“æ–‡æ›¸
+  default_priority_low: ä½Žã‚
+  default_priority_normal: é€šå¸¸
+  default_priority_high: é«˜ã‚
+  default_priority_urgent: æ€¥ã„ã§
+  default_priority_immediate: ä»Šã™ã
+  default_activity_design: è¨­è¨ˆä½œæ¥­
+  default_activity_development: é–‹ç™ºä½œæ¥­
+
+  enumeration_issue_priorities: ãƒã‚±ãƒƒãƒˆã®å„ªå…ˆåº¦
+  enumeration_doc_categories: æ–‡æ›¸ã‚«ãƒ†ã‚´ãƒª
+  enumeration_activities: ä½œæ¥­åˆ†é¡ž (æ™‚é–“ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°)
+  enumeration_system_activity: ã‚·ã‚¹ãƒ†ãƒ ä½œæ¥­åˆ†é¡ž
+  label_additional_workflow_transitions_for_assignee: ãƒã‚±ãƒƒãƒˆæ‹…å½“è€…ã«è¿½åŠ ã§è¨±å¯ã™ã‚‹é·ç§»
+  label_additional_workflow_transitions_for_author: ãƒã‚±ãƒƒãƒˆä½œæˆè€…ã«è¿½åŠ ã§è¨±å¯ã™ã‚‹é·ç§»
+  label_bulk_edit_selected_time_entries: ä½œæ¥­æ™‚é–“ã®ä¸€æ‹¬ç·¨é›†
+  text_time_entries_destroy_confirmation: æœ¬å½“ã«é¸æŠžã—ãŸä½œæ¥­æ™‚é–“ã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
+
+  label_role_anonymous: åŒ¿åãƒ¦ãƒ¼ã‚¶ãƒ¼
+  label_role_non_member: éžãƒ¡ãƒ³ãƒãƒ¼
+
+  label_issue_note_added: æ³¨è¨˜ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
+  label_issue_status_updated: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ
+  label_issue_priority_updated: å„ªå…ˆåº¦ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ
+  label_issues_visibility_own: ä½œæˆè€…ã‹æ‹…å½“è€…ã§ã‚ã‚‹ãƒã‚±ãƒƒãƒˆ
+  field_issues_visibility: è¡¨ç¤ºã§ãã‚‹ãƒã‚±ãƒƒãƒˆ
+  label_issues_visibility_all: ã™ã¹ã¦ã®ãƒã‚±ãƒƒãƒˆ
+  permission_set_own_issues_private: è‡ªåˆ†ã®ãƒã‚±ãƒƒãƒˆã‚’ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆã«è¨­å®š
+  field_is_private: ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆ
+  permission_set_issues_private: ãƒã‚±ãƒƒãƒˆã‚’ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆã«è¨­å®š
+  label_issues_visibility_public: ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆãƒã‚±ãƒƒãƒˆä»¥å¤–
+  text_issues_destroy_descendants_confirmation: "%{count}å€‹ã®å­ãƒã‚±ãƒƒãƒˆã‚‚å‰Šé™¤ã•ã‚Œã¾ã™ã€‚"
+  notice_issue_successful_create: ãƒã‚±ãƒƒãƒˆ %{id} ãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚
+  label_between: æ¬¡ã®ç¯„å›²å†…
+  setting_issue_group_assignment: ã‚°ãƒ«ãƒ¼ãƒ—ã¸ã®ãƒã‚±ãƒƒãƒˆå‰²ã‚Šå½“ã¦ã‚’è¨±å¯
+  description_query_sort_criteria_direction: é †åº
+  description_project_scope: æ¤œç´¢ç¯„å›²
+  description_filter: Filter
+  description_user_mail_notification: ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã®è¨­å®š
+  description_date_from: é–‹å§‹æ—¥
+  description_message_content: å†…å®¹
+  description_available_columns: åˆ©ç”¨ã§ãã‚‹é …ç›®
+  description_date_range_interval: æ—¥ä»˜ã§æŒ‡å®š
+  description_issue_category_reassign: æ–°ã—ã„ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã¦ãã ã•ã„
+  description_search: æ¤œç´¢ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰
+  description_notes: æ³¨è¨˜
+  description_date_range_list: ä¸€è¦§ã‹ã‚‰é¸æŠž
+  description_choose_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  description_date_to: çµ‚äº†æ—¥
+  description_query_sort_criteria_attribute: é …ç›®
+  description_wiki_subpages_reassign: æ–°ã—ã„è¦ªãƒšãƒ¼ã‚¸ã‚’é¸æŠžã—ã¦ãã ã•ã„
+  description_selected_columns: é¸æŠžã•ã‚ŒãŸé …ç›®
+  error_scm_annotate_big_text_file: ãƒ†ã‚­ã‚¹ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ä¸Šé™ã‚’è¶…ãˆã¦ã„ã‚‹ãŸã‚ã‚¢ãƒŽãƒ†ãƒ¼ãƒˆã§ãã¾ã›ã‚“ã€‚
+  setting_default_issue_start_date_to_creation_date: ç¾åœ¨ã®æ—¥ä»˜ã‚’æ–°ã—ã„ãƒã‚±ãƒƒãƒˆã®é–‹å§‹æ—¥ã¨ã™ã‚‹
+  button_edit_section: ã“ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’ç·¨é›†
+  description_all_columns: ã™ã¹ã¦ã®é …ç›®
+  button_export: ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ
+  label_export_options: "%{export_format} ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆè¨­å®š"
+  error_attachment_too_big: ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã‚¢ãƒƒãƒ—ãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã€‚æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ä¸Šé™(%{max_size})ã‚’è¶…ãˆã¦ã„ã¾ã™ã€‚
+  notice_failed_to_save_time_entries: "å…¨%{total}ä»¶ä¸­%{count}ä»¶ã®ä½œæ¥­æ™‚é–“ãŒä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %{ids}."
+  label_x_issues:
+    zero:  0 ãƒã‚±ãƒƒãƒˆ
+    one:   1 ãƒã‚±ãƒƒãƒˆ
+    other: "%{count} ãƒã‚±ãƒƒãƒˆ"
+  label_repository_new: æ–°ã—ã„ãƒªãƒã‚¸ãƒˆãƒª
+  field_repository_is_default: ãƒ¡ã‚¤ãƒ³ãƒªãƒã‚¸ãƒˆãƒª
+  label_copy_attachments: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ã‚³ãƒ”ãƒ¼
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: å®Œäº†ã—ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³
+  text_project_identifier_info: ã‚¢ãƒ«ãƒ•ã‚¡ãƒ™ãƒƒãƒˆå°æ–‡å­—(a-z)ãƒ»æ•°å­—ãƒ»ãƒã‚¤ãƒ•ãƒ³ãƒ»ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢ãŒä½¿ãˆã¾ã™ã€‚æœ€åˆã®æ–‡å­—ã¯ã‚¢ãƒ«ãƒ•ã‚¡ãƒ™ãƒƒãƒˆã®å°æ–‡å­—ã«ã—ã¦ãã ã•ã„ã€‚<br />è­˜åˆ¥å­ã¯å¾Œã§å¤‰æ›´ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã€‚
+  field_multiple: è¤‡æ•°é¸æŠžå¯
+  setting_commit_cross_project_ref: ç•°ãªã‚‹ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ãƒã‚±ãƒƒãƒˆã®å‚ç…§/ä¿®æ­£ã‚’è¨±å¯
+  text_issue_conflict_resolution_add_notes: è‡ªåˆ†ã®ç·¨é›†å†…å®¹ã‚’ç ´æ£„ã—æ³¨è¨˜ã®ã¿è¿½åŠ 
+  text_issue_conflict_resolution_overwrite: è‡ªåˆ†ã®ç·¨é›†å†…å®¹ã®ä¿å­˜ã‚’å¼·è¡Œ (ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®æ›´æ–°å†…å®¹ã¯æ³¨è¨˜ã‚’é™¤ãä¸Šæ›¸ãã•ã‚Œã¾ã™)
+  notice_issue_update_conflict: ã“ã®ãƒã‚±ãƒƒãƒˆã‚’ç·¨é›†ä¸­ã«ä»–ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒæ›´æ–°ã—ã¾ã—ãŸã€‚
+  text_issue_conflict_resolution_cancel: è‡ªåˆ†ã®ç·¨é›†å†…å®¹ã‚’ç ´æ£„ã— %{link} ã‚’å†è¡¨ç¤º
+  permission_manage_related_issues: é–¢é€£ã™ã‚‹ãƒã‚±ãƒƒãƒˆã®ç®¡ç†
+  field_auth_source_ldap_filter: LDAPãƒ•ã‚£ãƒ«ã‚¿
+  label_search_for_watchers: ã‚¦ã‚©ãƒƒãƒãƒ£ãƒ¼ã‚’æ¤œç´¢ã—ã¦è¿½åŠ 
+  notice_account_deleted: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚
+  setting_unsubscribe: ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã‚ˆã‚‹ã‚¢ã‚«ã‚¦ãƒ³ãƒˆå‰Šé™¤ã‚’è¨±å¯
+  button_delete_my_account: è‡ªåˆ†ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’å‰Šé™¤
+  text_account_destroy_confirmation: |-
+    æœ¬å½“ã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
+    ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯æ’ä¹…çš„ã«å‰Šé™¤ã•ã‚Œã¾ã™ã€‚å‰Šé™¤å¾Œã«å†åº¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’æœ‰åŠ¹ã«ã™ã‚‹æ‰‹æ®µã¯ã‚ã‚Šã¾ã›ã‚“ã€‚
+  error_session_expired: ã‚»ãƒƒã‚·ãƒ§ãƒ³ãŒå¤±åŠ¹ã—ã¾ã—ãŸã€‚ãƒ­ã‚°ã‚¤ãƒ³ã—ç›´ã—ã¦ãã ã•ã„ã€‚
+  text_session_expiration_settings: "è­¦å‘Š: ã“ã®è¨­å®šã‚’å¤‰æ›´ã™ã‚‹ã¨ç¾åœ¨æœ‰åŠ¹ãªã‚»ãƒƒã‚·ãƒ§ãƒ³ãŒå¤±åŠ¹ã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚"
+  setting_session_lifetime: æœ‰åŠ¹æœŸé–“ã®æœ€å¤§å€¤
+  setting_session_timeout: ç„¡æ“ä½œã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆ
+  label_session_expiration: ã‚»ãƒƒã‚·ãƒ§ãƒ³æœ‰åŠ¹æœŸé–“
+  permission_close_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®çµ‚äº†/å†é–‹
+  label_show_closed_projects: çµ‚äº†ã—ãŸãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã‚’è¡¨ç¤º
+  button_close: çµ‚äº†
+  button_reopen: å†é–‹
+  project_status_active: æœ‰åŠ¹
+  project_status_closed: çµ‚äº†
+  project_status_archived: ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–
+  text_project_closed: ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¯çµ‚äº†ã—ã¦ã„ã‚‹ãŸã‚èª­ã¿å–ã‚Šå°‚ç”¨ã§ã™ã€‚
+  notice_user_successful_create: ãƒ¦ãƒ¼ã‚¶ãƒ¼ %{id} ã‚’ä½œæˆã—ã¾ã—ãŸã€‚
+  field_core_fields: æ¨™æº–ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰
+  field_timeout: ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆ(ç§’å˜ä½)
+  setting_thumbnails_enabled: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚µãƒ ãƒã‚¤ãƒ«ç”»åƒã‚’è¡¨ç¤º
+  setting_thumbnails_size: ã‚µãƒ ãƒã‚¤ãƒ«ç”»åƒã®å¤§ãã•(ãƒ”ã‚¯ã‚»ãƒ«å˜ä½)
+  label_status_transitions: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®é·ç§»
+  label_fields_permissions: ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«å¯¾ã™ã‚‹æ¨©é™
+  label_readonly: èª­ã¿å–ã‚Šå°‚ç”¨
+  label_required: å¿…é ˆ
+  text_repository_identifier_info: ã‚¢ãƒ«ãƒ•ã‚¡ãƒ™ãƒƒãƒˆå°æ–‡å­—(a-z)ãƒ»æ•°å­—ãƒ»ãƒã‚¤ãƒ•ãƒ³ãƒ»ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢ãŒä½¿ãˆã¾ã™ã€‚<br />è­˜åˆ¥å­ã¯å¾Œã§å¤‰æ›´ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã€‚
+  field_board_parent: è¦ªãƒ•ã‚©ãƒ¼ãƒ©ãƒ 
+  label_attribute_of_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã® %{name}
+  label_attribute_of_author: ä½œæˆè€…ã® %{name}
+  label_attribute_of_assigned_to: æ‹…å½“è€…ã® %{name}
+  label_attribute_of_fixed_version: å¯¾è±¡ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® %{name}
+  label_copy_subtasks: å­ãƒã‚±ãƒƒãƒˆã‚’ã‚³ãƒ”ãƒ¼
+  label_copied_to: ã‚³ãƒ”ãƒ¼å…ˆ
+  label_copied_from: ã‚³ãƒ”ãƒ¼å…ƒ
+  label_any_issues_in_project: æ¬¡ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå†…ã®ãƒã‚±ãƒƒãƒˆ
+  label_any_issues_not_in_project: æ¬¡ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå¤–ã®ãƒã‚±ãƒƒãƒˆ
+  field_private_notes: ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆæ³¨è¨˜
+  permission_view_private_notes: ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆæ³¨è¨˜ã®é–²è¦§
+  permission_set_notes_private: æ³¨è¨˜ã‚’ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆã«è¨­å®š
+  label_no_issues_in_project: æ¬¡ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå†…ã®ãƒã‚±ãƒƒãƒˆã‚’é™¤ã
+  label_any: ã™ã¹ã¦
+  label_last_n_weeks: ç›´è¿‘%{count}é€±é–“
+  setting_cross_project_subtasks: ç•°ãªã‚‹ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ãƒã‚±ãƒƒãƒˆé–“ã®è¦ªå­é–¢ä¿‚ã‚’è¨±å¯
+  label_cross_project_descendants: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå˜ä½
+  label_cross_project_tree: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆãƒ„ãƒªãƒ¼å˜ä½
+  label_cross_project_hierarchy: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆéšŽå±¤å˜ä½
+  label_cross_project_system: ã™ã¹ã¦ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
+  button_hide: éš ã™
+  setting_non_working_week_days: ä¼‘æ¥­æ—¥
+  label_in_the_next_days: ä»Šå¾Œâ—‹æ—¥
+  label_in_the_past_days: éŽåŽ»â—‹æ—¥
+  label_attribute_of_user: ãƒ¦ãƒ¼ã‚¶ãƒ¼ã® %{name}
+  text_turning_multiple_off: ã“ã®è¨­å®šã‚’ç„¡åŠ¹ã«ã™ã‚‹ã¨ã€è¤‡æ•°é¸æŠžã•ã‚Œã¦ã„ã‚‹å€¤ã®ã†ã¡1å€‹ã ã‘ãŒä¿æŒã•ã‚Œæ®‹ã‚Šã¯é¸æŠžè§£é™¤ã•ã‚Œã¾ã™ã€‚
+  label_attribute_of_issue: ãƒã‚±ãƒƒãƒˆã® %{name}
+  permission_add_documents: æ–‡æ›¸ã®è¿½åŠ 
+  permission_edit_documents: æ–‡æ›¸ã®ç·¨é›†
+  permission_delete_documents: æ–‡æ›¸ã®å‰Šé™¤
+  setting_jsonp_enabled: JSONPã‚’æœ‰åŠ¹ã«ã™ã‚‹
+  field_inherit_members: ãƒ¡ãƒ³ãƒãƒ¼ã‚’ç¶™æ‰¿
+  field_closed_on: çµ‚äº†æ—¥
+  label_total_time: åˆè¨ˆ
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/92/92f7e489a9a504398a914cb36be2e56610b8c39b.svn-base
--- a/.svn/pristine/92/92f7e489a9a504398a914cb36be2e56610b8c39b.svn-base
+++ /dev/null
@@ -1,116 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'issue_relations_controller'
-
-# Re-raise errors caught by the controller.
-class IssueRelationsController; def rescue_action(e) raise e end; end
-
-
-class IssueRelationsControllerTest < ActionController::TestCase
-  fixtures :projects,
-           :users,
-           :roles,
-           :members,
-           :member_roles,
-           :issues,
-           :issue_statuses,
-           :issue_relations,
-           :enabled_modules,
-           :enumerations,
-           :trackers
-
-  def setup
-    @controller = IssueRelationsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_create
-    assert_difference 'IssueRelation.count' do
-      @request.session[:user_id] = 3
-      post :create, :issue_id => 1,
-                 :relation => {:issue_to_id => '2', :relation_type => 'relates', :delay => ''}
-    end
-  end
-
-  def test_create_xhr
-    assert_difference 'IssueRelation.count' do
-      @request.session[:user_id] = 3
-      xhr :post, :create,
-        :issue_id => 3,
-        :relation => {:issue_to_id => '1', :relation_type => 'relates', :delay => ''}
-      assert_select_rjs 'relations' do
-        assert_select 'table', 1
-        assert_select 'tr', 2 # relations
-      end
-    end
-  end
-
-  def test_create_should_accept_id_with_hash
-    assert_difference 'IssueRelation.count' do
-      @request.session[:user_id] = 3
-      post :create, :issue_id => 1,
-                 :relation => {:issue_to_id => '#2', :relation_type => 'relates', :delay => ''}
-    end
-  end
-
-  def test_create_should_not_break_with_non_numerical_id
-    assert_no_difference 'IssueRelation.count' do
-      assert_nothing_raised do
-        @request.session[:user_id] = 3
-        post :create, :issue_id => 1,
-                   :relation => {:issue_to_id => 'foo', :relation_type => 'relates', :delay => ''}
-      end
-    end
-  end
-
-  def test_should_create_relations_with_visible_issues_only
-    Setting.cross_project_issue_relations = '1'
-    assert_nil Issue.visible(User.find(3)).find_by_id(4)
-
-    assert_no_difference 'IssueRelation.count' do
-      @request.session[:user_id] = 3
-      post :create, :issue_id => 1,
-                 :relation => {:issue_to_id => '4', :relation_type => 'relates', :delay => ''}
-    end
-  end
-
-  should "prevent relation creation when there's a circular dependency"
-
-  def test_destroy
-    assert_difference 'IssueRelation.count', -1 do
-      @request.session[:user_id] = 3
-      delete :destroy, :id => '2'
-    end
-  end
-
-  def test_destroy_xhr
-    IssueRelation.create!(:relation_type => IssueRelation::TYPE_RELATES) do |r|
-      r.issue_from_id = 3
-      r.issue_to_id = 1
-    end
-
-    assert_difference 'IssueRelation.count', -1 do
-      @request.session[:user_id] = 3
-      xhr :delete, :destroy, :id => '2'
-      assert_select_rjs  :remove, 'relation-2'
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/92/92fabf9be5baabfa4c984a0b601e89006d8efda3.svn-base
--- a/.svn/pristine/92/92fabf9be5baabfa4c984a0b601e89006d8efda3.svn-base
+++ /dev/null
@@ -1,111 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2008  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class EnumerationTest < ActiveSupport::TestCase
-  fixtures :enumerations, :issues, :custom_fields, :custom_values
-
-  def setup
-  end
-
-  def test_objects_count
-    # low priority
-    assert_equal 6, Enumeration.find(4).objects_count
-    # urgent
-    assert_equal 0, Enumeration.find(7).objects_count
-  end
-
-  def test_in_use
-    # low priority
-    assert Enumeration.find(4).in_use?
-    # urgent
-    assert !Enumeration.find(7).in_use?
-  end
-
-  def test_default
-    e = Enumeration.default
-    assert e.is_a?(Enumeration)
-    assert e.is_default?
-    assert_equal 'Default Enumeration', e.name
-  end
-
-  def test_create
-    e = Enumeration.new(:name => 'Not default', :is_default => false)
-    e.type = 'Enumeration'
-    assert e.save
-    assert_equal 'Default Enumeration', Enumeration.default.name
-  end
-
-  def test_create_as_default
-    e = Enumeration.new(:name => 'Very urgent', :is_default => true)
-    e.type = 'Enumeration'
-    assert e.save
-    assert_equal e, Enumeration.default
-  end
-
-  def test_update_default
-    e = Enumeration.default
-    e.update_attributes(:name => 'Changed', :is_default => true)
-    assert_equal e, Enumeration.default
-  end
-
-  def test_update_default_to_non_default
-    e = Enumeration.default
-    e.update_attributes(:name => 'Changed', :is_default => false)
-    assert_nil Enumeration.default
-  end
-
-  def test_change_default
-    e = Enumeration.find_by_name('Default Enumeration')
-    e.update_attributes(:name => 'Changed Enumeration', :is_default => true)
-    assert_equal e, Enumeration.default
-  end
-
-  def test_destroy_with_reassign
-    Enumeration.find(4).destroy(Enumeration.find(6))
-    assert_nil Issue.find(:first, :conditions => {:priority_id => 4})
-    assert_equal 6, Enumeration.find(6).objects_count
-  end
-
-  def test_should_be_customizable
-    assert Enumeration.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
-  end
-
-  def test_should_belong_to_a_project
-    association = Enumeration.reflect_on_association(:project)
-    assert association, "No Project association found"
-    assert_equal :belongs_to, association.macro
-  end
-
-  def test_should_act_as_tree
-    enumeration = Enumeration.find(4)
-
-    assert enumeration.respond_to?(:parent)
-    assert enumeration.respond_to?(:children)
-  end
-
-  def test_is_override
-    # Defaults to off
-    enumeration = Enumeration.find(4)
-    assert !enumeration.is_override?
-
-    # Setup as an override
-    enumeration.parent = Enumeration.find(5)
-    assert enumeration.is_override?
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/93/932a59fb40eeb6d431a4cc52686573d7b9f38be6.svn-base
--- a/.svn/pristine/93/932a59fb40eeb6d431a4cc52686573d7b9f38be6.svn-base
+++ /dev/null
@@ -1,212 +0,0 @@
-# Rakefile
-#
-# $Revision: 1.27 $ by $Author: anupamsg $
-# $Name:  $
-#
-# Copyright (c) 2006, 2007 Anupam Sengupta
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# - Redistributions of source code must retain the above copyright notice, this
-#   list of conditions and the following disclaimer.
-#
-# - Redistributions in binary form must reproduce the above copyright notice, this
-#   list of conditions and the following disclaimer in the documentation and/or
-#   other materials provided with the distribution.
-#
-# - Neither the name of the organization nor the names of its contributors may
-#   be used to endorse or promote products derived from this software without
-#   specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-require 'rubygems'
-require 'rake/gempackagetask'
-
-require 'rake/clean'
-require 'rake/packagetask'
-require 'rake/testtask'
-require 'rake/rdoctask'
-
-require 'fileutils'
-
-# General Stuff ####################################################
-
-$:.insert 0, File.expand_path( File.join( File.dirname(__FILE__), 'lib' ) )
-require 'tree'         # To read the version information.
-
-PKG_NAME        = "rubytree"
-PKG_VERSION     = Tree::VERSION
-PKG_FULLNAME    = PKG_NAME + "-" + PKG_VERSION
-PKG_SUMMARY     = "Ruby implementation of the Tree data structure."
-PKG_DESCRIPTION = <<-END
-    Provides a generic tree data-structure with ability to
-    store keyed node-elements in the tree. The implementation
-    mixes in the Enumerable module.
-
-    Website:  http://rubytree.rubyforge.org/
-    END
-
-PKG_FILES = FileList[
-                     '[A-Z]*',
-                     '*.rb',
-                     'lib/**/*.rb',
-                     'test/**/*.rb'
-                    ]
-
-# Default is to create a rubygem.
-desc "Default Task"
-task :default => :gem
-
-begin                           # Try loading hoe
-  require 'hoe'
-  # If Hoe is found, use it to define tasks
-  # =======================================
-  Hoe.new(PKG_NAME, PKG_VERSION) do |p|
-    p.rubyforge_name = PKG_NAME
-    p.author = "Anupam Sengupta"
-    p.email = "anupamsg@gmail.com"
-    p.summary = PKG_SUMMARY
-    p.description = PKG_DESCRIPTION
-    p.url = "http://rubytree.rubyforge.org/"
-    p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
-    p.remote_rdoc_dir = 'rdoc'
-    p.need_tar = true
-    p.need_zip = true
-    p.test_globs = ['test/test_*.rb']
-    p.spec_extras = {
-      :has_rdoc => true,
-      :platform => Gem::Platform::RUBY,
-      :has_rdoc => true,
-      :extra_rdoc_files => ['README', 'COPYING', 'ChangeLog', 'History.txt'],
-      :rdoc_options => ['--main', 'README'],
-      :autorequire => 'tree'
-    }
-  end
-
-rescue LoadError                # If Hoe is not found
-  # If Hoe is not found, then use the usual Gemspec based Rake tasks
-  # ================================================================
-  spec = Gem::Specification.new do |s|
-    s.name = PKG_NAME
-    s.version = PKG_VERSION
-    s.platform = Gem::Platform::RUBY
-    s.author = "Anupam Sengupta"
-    s.email = "anupamsg@gmail.com"
-    s.homepage = "http://rubytree.rubyforge.org/"
-    s.rubyforge_project = 'rubytree'
-    s.summary = PKG_SUMMARY
-    s.add_dependency('rake', '>= 0.7.2')
-    s.description = PKG_DESCRIPTION
-    s.has_rdoc = true
-    s.extra_rdoc_files = ['README', 'COPYING', 'ChangeLog']
-    s.autorequire = "tree"
-    s.files = PKG_FILES.to_a
-    s.test_files = Dir.glob('test/test*.rb')
-  end
-
-  desc "Prepares for installation"
-  task :prepare do
-    ruby "setup.rb config"
-    ruby "setup.rb setup"
-  end
-
-  desc "Installs the package #{PKG_NAME}"
-  task :install => [:prepare] do
-    ruby "setup.rb install"
-  end
-
-  Rake::GemPackageTask.new(spec) do |pkg|
-    pkg.need_zip = true
-    pkg.need_tar = true
-  end
-
-  Rake::TestTask.new do |t|
-    t.libs << "test"
-    t.test_files = FileList['test/test*.rb']
-    t.verbose = true
-  end
-
-end                            # End loading Hoerc
-# ================================================================
-
-
-# The following tasks are loaded independently of Hoe
-
-# Hoe's rdoc task is ugly.
-Rake::RDocTask.new(:docs) do |rd|
-  rd.rdoc_files.include("README", "COPYING", "ChangeLog", "lib/**/*.rb")
-  rd.rdoc_dir = 'doc'
-  rd.title = "#{PKG_FULLNAME} Documentation"
-
-  # Use the template only if it is present, otherwise, the standard template is
-  # used.
-  template = "../allison/allison.rb"
-  rd.template = template if File.file?(template)
-
-  rd.options << '--line-numbers' << '--inline-source'
-end
-
-# Optional TAGS Task.
-# Needs https://rubyforge.org/projects/rtagstask/
-begin
-  require 'rtagstask'
-  RTagsTask.new do |rd|
-    rd.vi = false
-  end
-rescue LoadError
-end
-
-# Optional RCOV Task
-# Needs http://eigenclass.org/hiki/rcov
-begin
-  require 'rcov/rcovtask'
-  Rcov::RcovTask.new do |t|
-    t.test_files = FileList['test/test*.rb']
-    t.rcov_opts << "--exclude 'rcov.rb'" # rcov itself should not be profiled
-    # t.verbose = true     # uncomment to see the executed commands
-  end
-rescue LoadError
-end
-
-#Rakefile,v $
-# Revision 1.21  2007/07/21 05:14:43  anupamsg
-# Added a VERSION constant to the Tree module,
-# and using the same in the Rakefile.
-#
-# Revision 1.20  2007/07/21 03:24:25  anupamsg
-# Minor edits to parameter names. User visible functionality does not change.
-#
-# Revision 1.19  2007/07/19 02:16:01  anupamsg
-# Release 0.4.0 (and minor fix in Rakefile).
-#
-# Revision 1.18  2007/07/18 20:15:06  anupamsg
-# Added two predicate methods in BinaryTreeNode to determine whether a node
-# is a left or a right node.
-#
-# Revision 1.17  2007/07/18 07:17:34  anupamsg
-# Fixed a  issue where TreeNode.ancestors was shadowing Module.ancestors. This method
-# has been renamed to TreeNode.parentage.
-#
-# Revision 1.16  2007/07/17 05:34:03  anupamsg
-# Added an optional tags Rake-task for generating the TAGS file for Emacs.
-#
-# Revision 1.15  2007/07/17 04:42:45  anupamsg
-# Minor fixes to the Rakefile.
-#
-# Revision 1.14  2007/07/17 03:39:28  anupamsg
-# Moved the CVS Log keyword to end of the files.
-#
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/93/9336dd9f83163193267ea9ef9db5758abbb674d8.svn-base
--- a/.svn/pristine/93/9336dd9f83163193267ea9ef9db5758abbb674d8.svn-base
+++ /dev/null
@@ -1,10 +0,0 @@
-class AddRolePosition < ActiveRecord::Migration
-  def self.up
-    add_column :roles, :position, :integer, :default => 1
-    Role.find(:all).each_with_index {|role, i| role.update_attribute(:position, i+1)}
-  end
-
-  def self.down
-    remove_column :roles, :position
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/93/934588808c4b5bf65db5122ae7ec3bfd1957c33d.svn-base
--- a/.svn/pristine/93/934588808c4b5bf65db5122ae7ec3bfd1957c33d.svn-base
+++ /dev/null
@@ -1,48 +0,0 @@
-Return-Path: <JSmith@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
-Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
-In-Reply-To: <redmine.issue-2.20060719210421@osiris>
-From: "John Smith" <JSmith@somenet.foo>
-To: <redmine@somenet.foo>
-Subject: Re: update to issue 2
-Date: Sun, 22 Jun 2008 12:28:07 +0200
-MIME-Version: 1.0
-Content-Type: text/plain;
-	format=flowed;
-	charset="iso-8859-1";
-	reply-type=original
-Content-Transfer-Encoding: 7bit
-X-Priority: 3
-X-MSMail-Priority: Normal
-X-Mailer: Microsoft Outlook Express 6.00.2900.2869
-X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
-
-An update to the issue by the sender.
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet 
-turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus 
-blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti 
-sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In 
-in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras 
-sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum 
-id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus 
-eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique 
-sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et 
-malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
-platea dictumst.
-
-> --- Reply above. Do not remove this line. ---
-> 
-> Issue #6779 has been updated by Eric Davis.
-> 
-> Subject changed from Projects with JSON to Project JSON API
-> Status changed from New to Assigned
-> Assignee set to Eric Davis
-> Priority changed from Low to Normal
-> Estimated time deleted (1.00)
-> 
-> Looks like the JSON api for projects was missed. I'm going to be
-> reviewing the existing APIs and trying to clean them up over the next
-> few weeks.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/93/93670bab9f61b2b691063ad9fe7c015dfa58e59c.svn-base
--- /dev/null
+++ b/.svn/pristine/93/93670bab9f61b2b691063ad9fe7c015dfa58e59c.svn-base
@@ -0,0 +1,61 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::MimeTypeTest < ActiveSupport::TestCase
+
+  def test_of
+    to_test = {'test.unk' => nil,
+               'test.txt' => 'text/plain',
+               'test.c' => 'text/x-c',
+               }
+    to_test.each do |name, expected|
+      assert_equal expected, Redmine::MimeType.of(name)
+    end
+  end
+
+  def test_css_class_of
+    to_test = {'test.unk' => nil,
+               'test.txt' => 'text-plain',
+               'test.c' => 'text-x-c',
+               }
+    to_test.each do |name, expected|
+      assert_equal expected, Redmine::MimeType.css_class_of(name)
+    end
+  end
+
+  def test_main_mimetype_of
+    to_test = {'test.unk' => nil,
+               'test.txt' => 'text',
+               'test.c' => 'text',
+               }
+    to_test.each do |name, expected|
+      assert_equal expected, Redmine::MimeType.main_mimetype_of(name)
+    end
+  end
+
+  def test_is_type
+    to_test = {['text', 'test.unk'] => false,
+               ['text', 'test.txt'] => true,
+               ['text', 'test.c'] => true,
+               }
+    to_test.each do |args, expected|
+      assert_equal expected, Redmine::MimeType.is_type?(*args)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/93/939cceaf70f6f951d3ca40822110175a73d3a953.svn-base
--- /dev/null
+++ b/.svn/pristine/93/939cceaf70f6f951d3ca40822110175a73d3a953.svn-base
@@ -0,0 +1,92 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingNewsTest < ActionController::IntegrationTest
+  def test_news_index
+    assert_routing(
+        { :method => 'get', :path => "/news" },
+        { :controller => 'news', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/news.atom" },
+        { :controller => 'news', :action => 'index', :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/news.xml" },
+        { :controller => 'news', :action => 'index', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/news.json" },
+        { :controller => 'news', :action => 'index', :format => 'json' }
+      )
+  end
+
+  def test_news
+    assert_routing(
+        { :method => 'get', :path => "/news/2" },
+        { :controller => 'news', :action => 'show', :id => '2' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/news/234" },
+        { :controller => 'news', :action => 'show', :id => '234' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/news/567/edit" },
+        { :controller => 'news', :action => 'edit', :id => '567' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/news/567" },
+        { :controller => 'news', :action => 'update', :id => '567' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/news/567" },
+        { :controller => 'news', :action => 'destroy', :id => '567' }
+      )
+  end
+
+  def test_news_scoped_under_project
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/news" },
+        { :controller => 'news', :action => 'index', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/news.atom" },
+        { :controller => 'news', :action => 'index', :format => 'atom',
+          :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/news.xml" },
+        { :controller => 'news', :action => 'index', :format => 'xml',
+          :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/news.json" },
+        { :controller => 'news', :action => 'index', :format => 'json',
+          :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/news/new" },
+        { :controller => 'news', :action => 'new', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/567/news" },
+        { :controller => 'news', :action => 'create', :project_id => '567' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/93/93a376c27a710917c3458387b07a830523557ad3.svn-base
--- /dev/null
+++ b/.svn/pristine/93/93a376c27a710917c3458387b07a830523557ad3.svn-base
@@ -0,0 +1,40 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingSettingsTest < ActionController::IntegrationTest
+  def test_settings
+    assert_routing(
+        { :method => 'get', :path => "/settings" },
+        { :controller => 'settings', :action => 'index' }
+      )
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/settings/edit" },
+          { :controller => 'settings', :action => 'edit' }
+        )
+    end
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/settings/plugin/testid" },
+          { :controller => 'settings', :action => 'plugin',
+            :id => 'testid' }
+        )
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/93/93a94b9c693f6056ccf4667ad0ada99ff3b3a622.svn-base
--- a/.svn/pristine/93/93a94b9c693f6056ccf4667ad0ada99ff3b3a622.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-<p class="icon icon-example-works"><%= l(:text_say_goodbye) %></p>
-
-<% content_for :header_tags do %>
-  <%= stylesheet_link_tag "example.css", :plugin => "sample_plugin", :media => "screen" %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/93/93ca6805a3251b8650538af46c102f977fd67603.svn-base
--- /dev/null
+++ b/.svn/pristine/93/93ca6805a3251b8650538af46c102f977fd67603.svn-base
@@ -0,0 +1,12 @@
+class EnableCalendarAndGanttModulesWhereAppropriate < ActiveRecord::Migration
+  def self.up
+    EnabledModule.where(:name => 'issue_tracking').all.each do |e|
+      EnabledModule.create(:name => 'calendar', :project_id => e.project_id)
+      EnabledModule.create(:name => 'gantt', :project_id => e.project_id)
+    end
+  end
+
+  def self.down
+    EnabledModule.delete_all("name = 'calendar' OR name = 'gantt'")
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/93/93f85fbfa5d1803a533dc2903452408ac582b22a.svn-base
--- /dev/null
+++ b/.svn/pristine/93/93f85fbfa5d1803a533dc2903452408ac582b22a.svn-base
@@ -0,0 +1,94 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::PaginationTest < ActiveSupport::TestCase
+
+  def setup
+    @klass = Redmine::Pagination::Paginator
+  end
+
+  def test_count_is_zero
+    p = @klass.new 0, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    %w(first_page previous_page next_page last_page).each do |method|
+      assert_nil p.send(method), "#{method} was not nil"
+    end
+    assert_equal 0, p.first_item
+    assert_equal 0, p.last_item
+    assert_equal [], p.linked_pages
+  end
+
+  def test_count_is_less_than_per_page
+    p = @klass.new 7, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    assert_equal 1, p.first_page
+    assert_nil p.previous_page
+    assert_nil p.next_page
+    assert_equal 1, p.last_page
+    assert_equal 1, p.first_item
+    assert_equal 7, p.last_item
+    assert_equal [], p.linked_pages
+  end
+
+  def test_count_is_equal_to_per_page
+    p = @klass.new 10, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    assert_equal 1, p.first_page
+    assert_nil p.previous_page
+    assert_nil p.next_page
+    assert_equal 1, p.last_page
+    assert_equal 1, p.first_item
+    assert_equal 10, p.last_item
+    assert_equal [], p.linked_pages
+  end
+
+  def test_2_pages
+    p = @klass.new 16, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    assert_equal 1, p.first_page
+    assert_nil p.previous_page
+    assert_equal 2, p.next_page
+    assert_equal 2, p.last_page
+    assert_equal 1, p.first_item
+    assert_equal 10, p.last_item
+    assert_equal [1, 2], p.linked_pages
+  end
+
+  def test_many_pages
+    p = @klass.new 155, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    assert_equal 1, p.first_page
+    assert_nil p.previous_page
+    assert_equal 2, p.next_page
+    assert_equal 16, p.last_page
+    assert_equal 1, p.first_item
+    assert_equal 10, p.last_item
+    assert_equal [1, 2, 3, 16], p.linked_pages
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/94/942055183e0bb7ba0406288302813ecd7b3360c5.svn-base
--- a/.svn/pristine/94/942055183e0bb7ba0406288302813ecd7b3360c5.svn-base
+++ /dev/null
@@ -1,57 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class RepositoryFilesystemTest < ActiveSupport::TestCase
-  fixtures :projects
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/filesystem_repository').to_s
-
-  def setup
-    @project = Project.find(3)
-    Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
-    @repository = Repository::Filesystem.create(
-                               :project => @project,
-                               :url     => REPOSITORY_PATH
-                                 )
-    assert @repository
-  end
-
-  if File.directory?(REPOSITORY_PATH)
-    def test_fetch_changesets
-      assert_equal 0, @repository.changesets.count
-      assert_equal 0, @repository.changes.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal 0, @repository.changesets.count
-      assert_equal 0, @repository.changes.count
-    end
-
-    def test_entries
-      assert_equal 3, @repository.entries("", 2).size
-      assert_equal 2, @repository.entries("dir", 3).size
-    end
-
-    def test_cat
-      assert_equal "TEST CAT\n", @repository.scm.cat("test")
-    end
-  else
-    puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/94/9430aa85788ebdba5f87faaba28140f73390ecbb.svn-base
--- a/.svn/pristine/94/9430aa85788ebdba5f87faaba28140f73390ecbb.svn-base
+++ /dev/null
@@ -1,130 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'net/ldap'
-require 'iconv'
-
-class AuthSourceLdap < AuthSource
-  validates_presence_of :host, :port, :attr_login
-  validates_length_of :name, :host, :maximum => 60, :allow_nil => true
-  validates_length_of :account, :account_password, :base_dn, :maximum => 255, :allow_nil => true
-  validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
-  validates_numericality_of :port, :only_integer => true
-
-  before_validation :strip_ldap_attributes
-
-  def after_initialize
-    self.port = 389 if self.port == 0
-  end
-
-  def authenticate(login, password)
-    return nil if login.blank? || password.blank?
-    attrs = get_user_dn(login)
-
-    if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password)
-      logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
-      return attrs.except(:dn)
-    end
-  rescue  Net::LDAP::LdapError => text
-    raise "LdapError: " + text
-  end
-
-  # test the connection to the LDAP
-  def test_connection
-    ldap_con = initialize_ldap_con(self.account, self.account_password)
-    ldap_con.open { }
-  rescue  Net::LDAP::LdapError => text
-    raise "LdapError: " + text
-  end
-
-  def auth_method_name
-    "LDAP"
-  end
-
-  private
-
-  def strip_ldap_attributes
-    [:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr|
-      write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil?
-    end
-  end
-
-  def initialize_ldap_con(ldap_user, ldap_password)
-    options = { :host => self.host,
-                :port => self.port,
-                :encryption => (self.tls ? :simple_tls : nil)
-              }
-    options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
-    Net::LDAP.new options
-  end
-
-  def get_user_attributes_from_ldap_entry(entry)
-    {
-     :dn => entry.dn,
-     :firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
-     :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
-     :mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
-     :auth_source_id => self.id
-    }
-  end
-
-  # Return the attributes needed for the LDAP search.  It will only
-  # include the user attributes if on-the-fly registration is enabled
-  def search_attributes
-    if onthefly_register?
-      ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]
-    else
-      ['dn']
-    end
-  end
-
-  # Check if a DN (user record) authenticates with the password
-  def authenticate_dn(dn, password)
-    if dn.present? && password.present?
-      initialize_ldap_con(dn, password).bind
-    end
-  end
-
-  # Get the user's dn and any attributes for them, given their login
-  def get_user_dn(login)
-    ldap_con = initialize_ldap_con(self.account, self.account_password)
-    login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
-    object_filter = Net::LDAP::Filter.eq( "objectClass", "*" )
-    attrs = {}
-
-    ldap_con.search( :base => self.base_dn,
-                     :filter => object_filter & login_filter,
-                     :attributes=> search_attributes) do |entry|
-
-      if onthefly_register?
-        attrs = get_user_attributes_from_ldap_entry(entry)
-      else
-        attrs = {:dn => entry.dn}
-      end
-
-      logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug?
-    end
-
-    attrs
-  end
-
-  def self.get_attr(entry, attr_name)
-    if !attr_name.blank?
-      entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/94/9454c5a721334fadcdfa52b4317f98fb945144cd.svn-base
--- a/.svn/pristine/94/9454c5a721334fadcdfa52b4317f98fb945144cd.svn-base
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2007 [name of plugin creator]
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/94/9469fb967423feaea0c5d791773613a06264d078.svn-base
--- a/.svn/pristine/94/9469fb967423feaea0c5d791773613a06264d078.svn-base
+++ /dev/null
@@ -1,163 +0,0 @@
-2007-12-21  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* Rakefile: Added the rcov option to exclude rcov itself from
-	coverage reports.
-
-	* lib/tree.rb: Minor comment changes.
-
-	* test/test_tree.rb: Added the TestTree enclosing module, and
-	renamed tests to meet ZenTest requirements. Also added a few
-	missing test cases.
-
-	* test/test_binarytree.rb: Added the TestTree enclosing Module,
-	and renamed the tests to meet ZenTest requirements.
-
-2007-12-19  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* README (Module): Modified the install instructions from source.
-
-	* lib/tree.rb (Tree::TreeNode::initialize): Removed the
-	unnecessary self_initialize method.
-	(Tree::TreeNode): Removed the spurious self_initialize from the
-	protected list.
-	(Module): Updated the minor version number.
-
-	* Rakefile: Fixed a problem with reading the Tree::VERSION for the
-	gem packaging, if any prior version of the gem is already installed.
-
-2007-12-18  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* lib/tree.rb: Updated the marshalling logic to correctly handle
-	non-string content.
-	(Tree::TreeNode::createDumpRep): Minor code change to use symbols
-	instead of string key names.
-	(Tree): Version number change to 0.5.0
-	(Tree::TreeNode::hasContent): Minor fix to the comments.
-
-	* test/test_tree.rb (TC_TreeTest::test_breadth_each): Updated test
-	cases for the marshalling logic.
-
-2007-11-12  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* test/test_binarytree.rb: Minor documentation correction.
-
-	* lib/tree/binarytree.rb (Tree::BinaryTreeNode::isRightChild):
-	Minor documentation change.
-
-2007-10-10  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* README: Restructured the format.
-
-	* Rakefile: Added Hoe related logic. If not present, the Rakefile
-	will default to old behavior.
-
-2007-10-09  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* Rakefile: Added setup.rb related tasks. Also added the setup.rb in the PKG_FILES list.
-
-2007-10-01  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* Rakefile: Added an optional task for rcov code coverage.
-	  Added a dependency for rake in the Gem Specification.
-
-	* test/test_binarytree.rb: Removed the unnecessary dependency on "Person" class.
-
-	* test/test_tree.rb: Removed dependency on the redundant "Person" class.
-	(TC_TreeTest::test_comparator): Added a new test for the spaceship operator.
-	(TC_TreeTest::test_hasContent): Added tests for hasContent? and length methods.
-
-2007-08-30  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* test/test_tree.rb (TC_TreeTest::test_preordered_each, TC_TreeTest::test_breadth_each, TC_TreeTest::test_detached_copy):
-	Added new tests for the new functions added to tree.rb.
-
-	* lib/tree.rb (Tree::TreeNode::detached_copy, Tree::TreeNode::preordered_each, Tree::TreeNode::breadth_each):
-	Added new functions for returning a detached copy of the node and
-	for performing breadth first traversal. Also added the pre-ordered
-	traversal function which is an alias of the existing 'each' method.
-
-	* test/test_binarytree.rb (TC_BinaryTreeTest::test_swap_children):
-	Added a test case for the children swap function.
-
-	* lib/tree/binarytree.rb (Tree::BinaryTreeNode::swap_children):
-	Added new function to swap the children. Other minor changes in
-	comments and code.
-
-2007-07-18  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* lib/tree/binarytree.rb (Tree::BinaryTreeNode::leftChild /
-	rightChild): Minor cosmetic change on the parameter name.
-
-	* test/testbinarytree.rb (TC_BinaryTreeTest::test_isLeftChild):
-	Minor syntax correction.
-
-	* lib/tree.rb (Tree::TreeNode::depth): Added a tree depth
-	computation method.
-	(Tree::TreeNode::breadth): Added a tree breadth method.
-
-	* test/testtree.rb (TC_TreeTest::test_depth/test_breadth): Added a
-	test for the depth and breadth method.
-
-	* lib/tree/binarytree.rb (Tree::BinaryTreeNode::is*Child):
-	Added tests for determining whether a node is a left or right
-	child.
-
-	* test/testbinarytree.rb: Added the test cases for the binary tree
-	implementation.
-	(TC_BinaryTreeTest::test_is*Child): Added tests for right or left
-	childs.
-
-	* lib/tree/binarytree.rb: Added the binary tree implementation.
-
-2007-07-17  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* lib/tree.rb (Tree::TreeNode::parentage): Renamed 'ancestors'
-	method to 'parentage' to avoid clobbering Module.ancestors
-
-2007-07-16  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* Rakefile: Added an optional rtags task to generate TAGS file for
-	Emacs.
-
-	* lib/tree.rb (Tree::TreeNode): Added navigation methods for
-	siblings and children. Also added some convenience methods.
-
-2007-07-08  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* Rakefile: Added a developer target for generating rdoc for the
-	website.
-
-2007-06-24  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* test/testtree.rb, lib/tree.rb: Added the each_leaf traversal method.
-
-	* README: Replaced all occurrances of LICENSE with COPYING
-	and lowercased all instances of the word 'RubyTree'.
-
-	* Rakefile: Replaced all occurrances of LICENSE with COPYING
-
-2007-06-23  Anupam Sengupta  <anupamsg@gmail.com>
-
-	* lib/tree.rb (Tree::TreeNode::isLeaf): Added a isLeaf? method.
-
-	* test/testtree.rb (TC_TreeTest::test_removeFromParent): Added
-	test for isLeaf? method
-
-	* Rakefile: Added the LICENSE and ChangeLog to the extra RDoc files.
-
-	* lib/tree.rb: Minor updates to the comments.
-
-	* test/testtree.rb: Added the Copyright and License header.
-
-	* test/person.rb: Added the Copyright and License header.
-
-	* lib/tree.rb: Added the Copyright and License header.
-
-	* Rakefile: Added the LICENSE and Changelog to be part of the RDoc task.
-
-	* README: Added documentation in the README, including install
-	instructions and an example.
-
-	* LICENSE: Added the BSD LICENSE file.
-
-	* Changelog: Added the Changelog file.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/94/94850f049cba8fd1d7b631af60e061c441dc4401.svn-base
--- /dev/null
+++ b/.svn/pristine/94/94850f049cba8fd1d7b631af60e061c441dc4401.svn-base
@@ -0,0 +1,385 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AttachmentsControllerTest < ActionController::TestCase
+  fixtures :users, :projects, :roles, :members, :member_roles,
+           :enabled_modules, :issues, :trackers, :attachments,
+           :versions, :wiki_pages, :wikis, :documents
+
+  def setup
+    User.current = nil
+    set_fixtures_attachments_directory
+  end
+
+  def teardown
+    set_tmp_attachments_directory
+  end
+
+  def test_show_diff
+    ['inline', 'sbs'].each do |dt|
+      # 060719210727_changeset_utf8.diff
+      get :show, :id => 14, :type => dt
+      assert_response :success
+      assert_template 'diff'
+      assert_equal 'text/html', @response.content_type
+      assert_tag 'th',
+        :attributes => {:class => /filename/},
+        :content => /issues_controller.rb\t\(rÃ©vision 1484\)/
+      assert_tag 'td',
+        :attributes => {:class => /line-code/},
+        :content => /Demande crÃ©Ã©e avec succÃ¨s/
+    end
+    set_tmp_attachments_directory
+  end
+
+  def test_show_diff_replace_cannot_convert_content
+    with_settings :repositories_encodings => 'UTF-8' do
+      ['inline', 'sbs'].each do |dt|
+        # 060719210727_changeset_iso8859-1.diff
+        get :show, :id => 5, :type => dt
+        assert_response :success
+        assert_template 'diff'
+        assert_equal 'text/html', @response.content_type
+        assert_tag 'th',
+          :attributes => {:class => "filename"},
+          :content => /issues_controller.rb\t\(r\?vision 1484\)/
+        assert_tag 'td',
+          :attributes => {:class => /line-code/},
+          :content => /Demande cr\?\?e avec succ\?s/
+      end
+    end
+    set_tmp_attachments_directory
+  end
+
+  def test_show_diff_latin_1
+    with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
+      ['inline', 'sbs'].each do |dt|
+        # 060719210727_changeset_iso8859-1.diff
+        get :show, :id => 5, :type => dt
+        assert_response :success
+        assert_template 'diff'
+        assert_equal 'text/html', @response.content_type
+        assert_tag 'th',
+          :attributes => {:class => "filename"},
+          :content => /issues_controller.rb\t\(rÃ©vision 1484\)/
+        assert_tag 'td',
+          :attributes => {:class => /line-code/},
+          :content => /Demande crÃ©Ã©e avec succÃ¨s/
+      end
+    end
+    set_tmp_attachments_directory
+  end
+
+  def test_save_diff_type
+    user1 = User.find(1)
+    user1.pref[:diff_type] = nil
+    user1.preference.save
+    user = User.find(1)
+    assert_nil user.pref[:diff_type]
+
+    @request.session[:user_id] = 1 # admin
+    get :show, :id => 5
+    assert_response :success
+    assert_template 'diff'
+    user.reload
+    assert_equal "inline", user.pref[:diff_type]
+    get :show, :id => 5, :type => 'sbs'
+    assert_response :success
+    assert_template 'diff'
+    user.reload
+    assert_equal "sbs", user.pref[:diff_type]
+  end
+
+  def test_diff_show_filename_in_mercurial_export
+    set_tmp_attachments_directory
+    a = Attachment.new(:container => Issue.find(1),
+                       :file => uploaded_test_file("hg-export.diff", "text/plain"),
+                       :author => User.find(1))
+    assert a.save
+    assert_equal 'hg-export.diff', a.filename
+
+    get :show, :id => a.id, :type => 'inline'
+    assert_response :success
+    assert_template 'diff'
+    assert_equal 'text/html', @response.content_type
+    assert_select 'th.filename', :text => 'test1.txt'
+  end
+
+  def test_show_text_file
+    get :show, :id => 4
+    assert_response :success
+    assert_template 'file'
+    assert_equal 'text/html', @response.content_type
+    set_tmp_attachments_directory
+  end
+
+  def test_show_text_file_utf_8
+    set_tmp_attachments_directory
+    a = Attachment.new(:container => Issue.find(1),
+                       :file => uploaded_test_file("japanese-utf-8.txt", "text/plain"),
+                       :author => User.find(1))
+    assert a.save
+    assert_equal 'japanese-utf-8.txt', a.filename
+
+    str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
+    str_japanese.force_encoding('UTF-8') if str_japanese.respond_to?(:force_encoding)
+
+    get :show, :id => a.id
+    assert_response :success
+    assert_template 'file'
+    assert_equal 'text/html', @response.content_type
+    assert_tag :tag => 'th',
+               :content => '1',
+               :attributes => { :class => 'line-num' },
+               :sibling => { :tag => 'td', :content => /#{str_japanese}/ }
+  end
+
+  def test_show_text_file_replace_cannot_convert_content
+    set_tmp_attachments_directory
+    with_settings :repositories_encodings => 'UTF-8' do
+      a = Attachment.new(:container => Issue.find(1),
+                         :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
+                         :author => User.find(1))
+      assert a.save
+      assert_equal 'iso8859-1.txt', a.filename
+
+      get :show, :id => a.id
+      assert_response :success
+      assert_template 'file'
+      assert_equal 'text/html', @response.content_type
+      assert_tag :tag => 'th',
+                 :content => '7',
+                 :attributes => { :class => 'line-num' },
+                 :sibling => { :tag => 'td', :content => /Demande cr\?\?e avec succ\?s/ }
+    end
+  end
+
+  def test_show_text_file_latin_1
+    set_tmp_attachments_directory
+    with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
+      a = Attachment.new(:container => Issue.find(1),
+                         :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
+                         :author => User.find(1))
+      assert a.save
+      assert_equal 'iso8859-1.txt', a.filename
+
+      get :show, :id => a.id
+      assert_response :success
+      assert_template 'file'
+      assert_equal 'text/html', @response.content_type
+      assert_tag :tag => 'th',
+                 :content => '7',
+                 :attributes => { :class => 'line-num' },
+                 :sibling => { :tag => 'td', :content => /Demande crÃ©Ã©e avec succÃ¨s/ }
+      end
+  end
+
+  def test_show_text_file_should_send_if_too_big
+    Setting.file_max_size_displayed = 512
+    Attachment.find(4).update_attribute :filesize, 754.kilobyte
+
+    get :show, :id => 4
+    assert_response :success
+    assert_equal 'application/x-ruby', @response.content_type
+    set_tmp_attachments_directory
+  end
+
+  def test_show_other
+    get :show, :id => 6
+    assert_response :success
+    assert_equal 'application/octet-stream', @response.content_type
+    set_tmp_attachments_directory
+  end
+
+  def test_show_file_from_private_issue_without_permission
+    get :show, :id => 15
+    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2F15'
+    set_tmp_attachments_directory
+  end
+
+  def test_show_file_from_private_issue_with_permission
+    @request.session[:user_id] = 2
+    get :show, :id => 15
+    assert_response :success
+    assert_tag 'h2', :content => /private.diff/
+    set_tmp_attachments_directory
+  end
+
+  def test_show_file_without_container_should_be_allowed_to_author
+    set_tmp_attachments_directory
+    attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
+
+    @request.session[:user_id] = 2
+    get :show, :id => attachment.id
+    assert_response 200
+  end
+
+  def test_show_file_without_container_should_be_denied_to_other_users
+    set_tmp_attachments_directory
+    attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
+
+    @request.session[:user_id] = 3
+    get :show, :id => attachment.id
+    assert_response 403
+  end
+
+  def test_show_invalid_should_respond_with_404
+    get :show, :id => 999
+    assert_response 404
+  end
+
+  def test_download_text_file
+    get :download, :id => 4
+    assert_response :success
+    assert_equal 'application/x-ruby', @response.content_type
+    set_tmp_attachments_directory
+  end
+
+  def test_download_version_file_with_issue_tracking_disabled
+    Project.find(1).disable_module! :issue_tracking
+    get :download, :id => 9
+    assert_response :success
+  end
+
+  def test_download_should_assign_content_type_if_blank
+    Attachment.find(4).update_attribute(:content_type, '')
+
+    get :download, :id => 4
+    assert_response :success
+    assert_equal 'text/x-ruby', @response.content_type
+    set_tmp_attachments_directory
+  end
+
+  def test_download_missing_file
+    get :download, :id => 2
+    assert_response 404
+    set_tmp_attachments_directory
+  end
+
+  def test_download_should_be_denied_without_permission
+    get :download, :id => 7
+    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdownload%2F7'
+    set_tmp_attachments_directory
+  end
+
+  if convert_installed?
+    def test_thumbnail
+      Attachment.clear_thumbnails
+      @request.session[:user_id] = 2
+
+      get :thumbnail, :id => 16
+      assert_response :success
+      assert_equal 'image/png', response.content_type
+    end
+
+    def test_thumbnail_should_not_exceed_maximum_size
+      Redmine::Thumbnail.expects(:generate).with {|source, target, size| size == 800}
+
+      @request.session[:user_id] = 2
+      get :thumbnail, :id => 16, :size => 2000
+    end
+
+    def test_thumbnail_should_round_size
+      Redmine::Thumbnail.expects(:generate).with {|source, target, size| size == 250}
+
+      @request.session[:user_id] = 2
+      get :thumbnail, :id => 16, :size => 260
+    end
+
+    def test_thumbnail_should_return_404_for_non_image_attachment
+      @request.session[:user_id] = 2
+
+      get :thumbnail, :id => 15
+      assert_response 404
+    end
+
+    def test_thumbnail_should_return_404_if_thumbnail_generation_failed
+      Attachment.any_instance.stubs(:thumbnail).returns(nil)
+      @request.session[:user_id] = 2
+
+      get :thumbnail, :id => 16
+      assert_response 404
+    end
+
+    def test_thumbnail_should_be_denied_without_permission
+      get :thumbnail, :id => 16
+      assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fthumbnail%2F16'
+    end
+  else
+    puts '(ImageMagick convert not available)'
+  end
+
+  def test_destroy_issue_attachment
+    set_tmp_attachments_directory
+    issue = Issue.find(3)
+    @request.session[:user_id] = 2
+
+    assert_difference 'issue.attachments.count', -1 do
+      assert_difference 'Journal.count' do
+        delete :destroy, :id => 1
+        assert_redirected_to '/projects/ecookbook'
+      end
+    end
+    assert_nil Attachment.find_by_id(1)
+    j = Journal.first(:order => 'id DESC')
+    assert_equal issue, j.journalized
+    assert_equal 'attachment', j.details.first.property
+    assert_equal '1', j.details.first.prop_key
+    assert_equal 'error281.txt', j.details.first.old_value
+    assert_equal User.find(2), j.user
+  end
+
+  def test_destroy_wiki_page_attachment
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+    assert_difference 'Attachment.count', -1 do
+      delete :destroy, :id => 3
+      assert_response 302
+    end
+  end
+
+  def test_destroy_project_attachment
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+    assert_difference 'Attachment.count', -1 do
+      delete :destroy, :id => 8
+      assert_response 302
+    end
+  end
+
+  def test_destroy_version_attachment
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+    assert_difference 'Attachment.count', -1 do
+      delete :destroy, :id => 9
+      assert_response 302
+    end
+  end
+
+  def test_destroy_without_permission
+    set_tmp_attachments_directory
+    assert_no_difference 'Attachment.count' do
+      delete :destroy, :id => 3
+    end
+    assert_response 302
+    assert Attachment.find_by_id(3)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/94/94b0a87688b1d61b6fb66241d11ae9e0ee65fa3e.svn-base
--- /dev/null
+++ b/.svn/pristine/94/94b0a87688b1d61b6fb66241d11ae9e0ee65fa3e.svn-base
@@ -0,0 +1,79 @@
+== Redmine upgrade
+
+Redmine - project management software
+Copyright (C) 2006-2013  Jean-Philippe Lang
+http://www.redmine.org/
+
+
+== Upgrading
+
+1. Uncompress the program archive in a new directory
+
+2. Copy your database settings (RAILS_ROOT/config/database.yml)
+   and your configuration file (RAILS_ROOT/config/configuration.yml)
+   into the new config directory
+   Note: before Redmine 1.2, SMTP configuration was stored in
+   config/email.yml. It should now be stored in config/configuration.yml. 
+
+3. Copy the RAILS_ROOT/files directory content into your new installation
+   This directory contains all the attached files.
+
+4. Copy the folders of the installed plugins and themes into new installation
+   Plugins must be stored in the [redmine_root]/plugins directory
+   Themes must be stored in the [redmine_root]/public/themes directory
+
+   WARNING: plugins from your previous Redmine version may not be compatible
+   with the Redmine version you're upgrading to.
+
+5. Install the required gems by running:
+     bundle install --without development test
+
+   If ImageMagick is not installed on your system, you should skip the installation
+   of the rmagick gem using:
+     bundle install --without development test rmagick
+
+   Only the gems that are needed by the adapters you've specified in your database
+   configuration file are actually installed (eg. if your config/database.yml
+   uses the 'mysql2' adapter, then only the mysql2 gem will be installed). Don't
+   forget to re-run `bundle install` when you change config/database.yml for using
+   other database adapters.
+
+   If you need to load some gems that are not required by Redmine core (eg. fcgi),
+   you can create a file named Gemfile.local at the root of your redmine directory.
+   It will be loaded automatically when running `bundle install`.
+
+6. Generate a session store secret
+   
+   Redmine stores session data in cookies by default, which requires
+   a secret to be generated. Under the new application directory run:
+     rake generate_secret_token
+   
+   DO NOT REPLACE OR EDIT ANY OTHER FILES.
+
+7. Migrate your database
+
+   If you are upgrading to Rails 2.3.14 as part of this migration, you
+   need to upgrade the plugin migrations before running the plugin migrations
+   using:
+     rake db:migrate:upgrade_plugin_migrations RAILS_ENV="production"
+   
+   Please make a backup before doing this! Under the new application
+   directory run:
+     rake db:migrate RAILS_ENV="production"
+   
+   If you have installed any plugins, you should also run their database
+   migrations using:
+     rake db:migrate_plugins RAILS_ENV="production"
+   
+8. Clear the cache and the existing sessions by running:
+     rake tmp:cache:clear
+     rake tmp:sessions:clear
+
+9. Restart the application server (e.g. mongrel, thin, passenger)
+
+10. Finally go to "Administration -> Roles & permissions" to check/set permissions
+    for new features, if any
+
+== References
+
+* http://www.redmine.org/wiki/redmine/RedmineUpgrade
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/94/94d984cee201aee41be7087194e529a50fa4d99c.svn-base
--- a/.svn/pristine/94/94d984cee201aee41be7087194e529a50fa4d99c.svn-base
+++ /dev/null
@@ -1,24 +0,0 @@
-api.user do
-  api.id         @user.id
-  api.login      @user.login if User.current.admin?
-  api.firstname  @user.firstname
-  api.lastname   @user.lastname
-  api.mail       @user.mail if User.current.admin? || !@user.pref.hide_mail
-  api.created_on @user.created_on
-  api.last_login_on @user.last_login_on
-
-  render_api_custom_values @user.visible_custom_field_values, api
-
-  api.array :memberships do
-    @memberships.each do |membership|
-      api.membership do
-        api.project :id => membership.project.id, :name => membership.project.name
-        api.array :roles do
-          membership.roles.each do |role|
-            api.role :id => role.id, :name => role.name
-          end
-        end
-      end if membership.project
-    end
-  end if include_in_api_response?('memberships') && @memberships
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/94/94fbb6c1644f4c725051e15f5540168eaf5441e9.svn-base
--- /dev/null
+++ b/.svn/pristine/94/94fbb6c1644f4c725051e15f5540168eaf5441e9.svn-base
@@ -0,0 +1,1095 @@
+# Portuguese localization for Ruby on Rails
+# by Ricardo Otero <oterosantos@gmail.com>
+# by Alberto Ferreira <toraxic@gmail.com>
+# by Rui Rebelo <rmrebelo@ua.pt>
+pt:
+  support:
+    array:
+      sentence_connector: "e"
+      skip_last_comma: true
+
+  direction: ltr
+  date:
+    formats:
+      default: "%d/%m/%Y"
+      short: "%d de %B"
+      long: "%d de %B de %Y"
+      only_day: "%d"
+    day_names: [Domingo, Segunda, TerÃ§a, Quarta, Quinta, Sexta, SÃ¡bado]
+    abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, SÃ¡b]
+    month_names: [~, Janeiro, Fevereiro, MarÃ§o, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro]
+    abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%A, %d de %B de %Y, %H:%Mh"
+      time: "%H:%M"
+      short: "%d/%m, %H:%M hs"
+      long: "%A, %d de %B de %Y, %H:%Mh"
+    am: ''
+    pm: ''
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "meio minuto"
+      less_than_x_seconds:
+        one: "menos de 1 segundo"
+        other: "menos de %{count} segundos"
+      x_seconds:
+        one: "1 segundo"
+        other: "%{count} segundos"
+      less_than_x_minutes:
+        one: "menos de um minuto"
+        other: "menos de %{count} minutos"
+      x_minutes:
+        one: "1 minuto"
+        other: "%{count} minutos"
+      about_x_hours:
+        one: "aproximadamente 1 hora"
+        other: "aproximadamente %{count} horas"
+      x_hours:
+        one:   "1 hora"
+        other: "%{count} horas"
+      x_days:
+        one: "1 dia"
+        other: "%{count} dias"
+      about_x_months:
+        one: "aproximadamente 1 mÃªs"
+        other: "aproximadamente %{count} meses"
+      x_months:
+        one: "1 mÃªs"
+        other: "%{count} meses"
+      about_x_years:
+        one: "aproximadamente 1 ano"
+        other: "aproximadamente %{count} anos"
+      over_x_years:
+        one: "mais de 1 ano"
+        other: "mais de %{count} anos"
+      almost_x_years:
+        one:   "quase 1 ano"
+        other: "quase %{count} anos"
+
+  number:
+    format:
+      precision: 3
+      separator: ','
+      delimiter: '.'
+    currency:
+      format:
+        unit: 'â‚¬'
+        precision: 2
+        format: "%u %n"
+        separator: ','
+        delimiter: '.'
+    percentage:
+      format:
+        delimiter: ''
+    precision:
+      format:
+        delimiter: ''
+    human:
+      format:
+        precision: 3
+        delimiter: ''
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one: "NÃ£o foi possÃ­vel guardar %{model}: 1 erro"
+          other: "NÃ£o foi possÃ­vel guardar %{model}: %{count} erros"
+        body: "Por favor, verifique os seguintes campos:"
+      messages:
+        inclusion: "nÃ£o estÃ¡ incluÃ­do na lista"
+        exclusion: "nÃ£o estÃ¡ disponÃ­vel"
+        invalid: "nÃ£o Ã© vÃ¡lido"
+        confirmation: "nÃ£o estÃ¡ de acordo com a confirmaÃ§Ã£o"
+        accepted:  "precisa de ser aceite"
+        empty: "nÃ£o pode estar em branco"
+        blank: "nÃ£o pode estar em branco"
+        too_long: "tem demasiados caracteres (mÃ¡ximo: %{count} caracteres)"
+        too_short: "tem poucos caracteres (mÃ­nimo: %{count} caracteres)"
+        wrong_length: "nÃ£o Ã© do tamanho correcto (necessita de ter %{count} caracteres)"
+        taken: "nÃ£o estÃ¡ disponÃ­vel"
+        not_a_number: "nÃ£o Ã© um nÃºmero"
+        greater_than: "tem de ser maior do que %{count}"
+        greater_than_or_equal_to: "tem de ser maior ou igual a %{count}"
+        equal_to: "tem de ser igual a %{count}"
+        less_than: "tem de ser menor do que %{count}"
+        less_than_or_equal_to: "tem de ser menor ou igual a %{count}"
+        odd: "tem de ser Ã­mpar"
+        even: "tem de ser par"
+        greater_than_start_date: "deve ser maior que a data inicial"
+        not_same_project: "nÃ£o pertence ao mesmo projecto"
+        circular_dependency: "Esta relaÃ§Ã£o iria criar uma dependÃªncia circular"
+        cant_link_an_issue_with_a_descendant: "NÃ£o Ã© possÃ­vel ligar uma tarefa a uma sub-tarefa que lhe Ã© pertencente"
+
+  ## Translated by: Pedro AraÃºjo <phcrva19@hotmail.com>
+  actionview_instancetag_blank_option: Seleccione
+
+  general_text_No: 'NÃ£o'
+  general_text_Yes: 'Sim'
+  general_text_no: 'nÃ£o'
+  general_text_yes: 'sim'
+  general_lang_name: 'PortuguÃªs'
+  general_csv_separator: ';'
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-15
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: A conta foi actualizada com sucesso.
+  notice_account_invalid_creditentials: Utilizador ou palavra-chave invÃ¡lidos.
+  notice_account_password_updated: A palavra-chave foi alterada com sucesso.
+  notice_account_wrong_password: Palavra-chave errada.
+  notice_account_register_done: A conta foi criada com sucesso.
+  notice_account_unknown_email: Utilizador desconhecido.
+  notice_can_t_change_password: Esta conta utiliza uma fonte de autenticaÃ§Ã£o externa. NÃ£o Ã© possÃ­vel alterar a palavra-chave.
+  notice_account_lost_email_sent: Foi-lhe enviado um e-mail com as instruÃ§Ãµes para escolher uma nova palavra-chave.
+  notice_account_activated: A sua conta foi activada. Ã‰ agora possÃ­vel autenticar-se.
+  notice_successful_create: Criado com sucesso.
+  notice_successful_update: Alterado com sucesso.
+  notice_successful_delete: Apagado com sucesso.
+  notice_successful_connection: Ligado com sucesso.
+  notice_file_not_found: A pÃ¡gina que estÃ¡ a tentar aceder nÃ£o existe ou foi removida.
+  notice_locking_conflict: Os dados foram actualizados por outro utilizador.
+  notice_not_authorized: NÃ£o estÃ¡ autorizado a visualizar esta pÃ¡gina.
+  notice_email_sent: "Foi enviado um e-mail para %{value}"
+  notice_email_error: "Ocorreu um erro ao enviar o e-mail (%{value})"
+  notice_feeds_access_key_reseted: A sua chave de RSS foi inicializada.
+  notice_failed_to_save_issues: "NÃ£o foi possÃ­vel guardar %{count} tarefa(s) das %{total} seleccionadas: %{ids}."
+  notice_no_issue_selected: "Nenhuma tarefa seleccionada! Por favor, seleccione as tarefas que quer editar."
+  notice_account_pending: "A sua conta foi criada e estÃ¡ agora Ã  espera de aprovaÃ§Ã£o do administrador."
+  notice_default_data_loaded: ConfiguraÃ§Ã£o padrÃ£o carregada com sucesso.
+  notice_unable_delete_version: NÃ£o foi possÃ­vel apagar a versÃ£o.
+
+  error_can_t_load_default_data: "NÃ£o foi possÃ­vel carregar a configuraÃ§Ã£o padrÃ£o: %{value}"
+  error_scm_not_found: "A entrada ou revisÃ£o nÃ£o foi encontrada no repositÃ³rio."
+  error_scm_command_failed: "Ocorreu um erro ao tentar aceder ao repositÃ³rio: %{value}"
+  error_scm_annotate: "A entrada nÃ£o existe ou nÃ£o pode ser anotada."
+  error_issue_not_found_in_project: 'A tarefa nÃ£o foi encontrada ou nÃ£o pertence a este projecto.'
+
+  mail_subject_lost_password: "Palavra-chave de %{value}"
+  mail_body_lost_password: 'Para mudar a sua palavra-chave, clique na ligaÃ§Ã£o abaixo:'
+  mail_subject_register: "ActivaÃ§Ã£o de conta de %{value}"
+  mail_body_register: 'Para activar a sua conta, clique na ligaÃ§Ã£o abaixo:'
+  mail_body_account_information_external: "Pode utilizar a conta %{value} para autenticar-se."
+  mail_body_account_information: InformaÃ§Ã£o da sua conta
+  mail_subject_account_activation_request: "Pedido de activaÃ§Ã£o da conta %{value}"
+  mail_body_account_activation_request: "Um novo utilizador (%{value}) registou-se. A sua conta estÃ¡ Ã  espera de aprovaÃ§Ã£o:"
+  mail_subject_reminder: "%{count} tarefa(s) para entregar nos prÃ³ximos %{days} dias"
+  mail_body_reminder: "%{count} tarefa(s) que estÃ£o atribuÃ­das a si estÃ£o agendadas para estarem completas nos prÃ³ximos %{days} dias:"
+
+
+  field_name: Nome
+  field_description: DescriÃ§Ã£o
+  field_summary: SumÃ¡rio
+  field_is_required: ObrigatÃ³rio
+  field_firstname: Nome
+  field_lastname: Apelido
+  field_mail: E-mail
+  field_filename: Ficheiro
+  field_filesize: Tamanho
+  field_downloads: Downloads
+  field_author: Autor
+  field_created_on: Criado
+  field_updated_on: Alterado
+  field_field_format: Formato
+  field_is_for_all: Para todos os projectos
+  field_possible_values: Valores possÃ­veis
+  field_regexp: ExpressÃ£o regular
+  field_min_length: Tamanho mÃ­nimo
+  field_max_length: Tamanho mÃ¡ximo
+  field_value: Valor
+  field_category: Categoria
+  field_title: TÃ­tulo
+  field_project: Projecto
+  field_issue: Tarefa
+  field_status: Estado
+  field_notes: Notas
+  field_is_closed: Tarefa fechada
+  field_is_default: Valor por omissÃ£o
+  field_tracker: Tipo
+  field_subject: Assunto
+  field_due_date: Data fim
+  field_assigned_to: AtribuÃ­do a
+  field_priority: Prioridade
+  field_fixed_version: VersÃ£o
+  field_user: Utilizador
+  field_role: FunÃ§Ã£o
+  field_homepage: PÃ¡gina
+  field_is_public: PÃºblico
+  field_parent: Sub-projecto de
+  field_is_in_roadmap: Tarefas mostradas no mapa de planificaÃ§Ã£o
+  field_login: Nome de utilizador
+  field_mail_notification: NotificaÃ§Ãµes por e-mail
+  field_admin: Administrador
+  field_last_login_on: Ãšltima visita
+  field_language: LÃ­ngua
+  field_effective_date: Data
+  field_password: Palavra-chave
+  field_new_password: Nova palavra-chave
+  field_password_confirmation: ConfirmaÃ§Ã£o
+  field_version: VersÃ£o
+  field_type: Tipo
+  field_host: Servidor
+  field_port: Porta
+  field_account: Conta
+  field_base_dn: Base DN
+  field_attr_login: Atributo utilizador
+  field_attr_firstname: Atributo nome prÃ³prio
+  field_attr_lastname: Atributo Ãºltimo nome
+  field_attr_mail: Atributo e-mail
+  field_onthefly: CriaÃ§Ã£o imediata de utilizadores
+  field_start_date: Data inÃ­cio
+  field_done_ratio: "% Completo"
+  field_auth_source: Modo de autenticaÃ§Ã£o
+  field_hide_mail: Esconder endereÃ§o de e-mail
+  field_comments: ComentÃ¡rio
+  field_url: URL
+  field_start_page: PÃ¡gina inicial
+  field_subproject: Subprojecto
+  field_hours: Horas
+  field_activity: Actividade
+  field_spent_on: Data
+  field_identifier: Identificador
+  field_is_filter: Usado como filtro
+  field_issue_to: Tarefa relacionada
+  field_delay: Atraso
+  field_assignable: As tarefas podem ser associadas a esta funÃ§Ã£o
+  field_redirect_existing_links: Redireccionar ligaÃ§Ãµes existentes
+  field_estimated_hours: Tempo estimado
+  field_column_names: Colunas
+  field_time_zone: Fuso horÃ¡rio
+  field_searchable: ProcurÃ¡vel
+  field_default_value: Valor por omissÃ£o
+  field_comments_sorting: Mostrar comentÃ¡rios
+  field_parent_title: PÃ¡gina pai
+
+  setting_app_title: TÃ­tulo da aplicaÃ§Ã£o
+  setting_app_subtitle: Sub-tÃ­tulo da aplicaÃ§Ã£o
+  setting_welcome_text: Texto de boas vindas
+  setting_default_language: LÃ­ngua por omissÃ£o
+  setting_login_required: AutenticaÃ§Ã£o obrigatÃ³ria
+  setting_self_registration: Auto-registo
+  setting_attachment_max_size: Tamanho mÃ¡ximo do anexo
+  setting_issues_export_limit: Limite de exportaÃ§Ã£o das tarefas
+  setting_mail_from: E-mail enviado de
+  setting_bcc_recipients: Recipientes de BCC
+  setting_host_name: Hostname
+  setting_text_formatting: FormataÃ§Ã£o do texto
+  setting_wiki_compression: CompressÃ£o do histÃ³rico do Wiki
+  setting_feeds_limit: Limite de conteÃºdo do feed
+  setting_default_projects_public: Projectos novos sÃ£o pÃºblicos por omissÃ£o
+  setting_autofetch_changesets: Buscar automaticamente commits
+  setting_sys_api_enabled: Activar Web Service para gestÃ£o do repositÃ³rio
+  setting_commit_ref_keywords: Palavras-chave de referÃªncia
+  setting_commit_fix_keywords: Palavras-chave de fecho
+  setting_autologin: Login automÃ¡tico
+  setting_date_format: Formato da data
+  setting_time_format: Formato do tempo
+  setting_cross_project_issue_relations: Permitir relaÃ§Ãµes entre tarefas de projectos diferentes
+  setting_issue_list_default_columns: Colunas na lista de tarefas por omissÃ£o
+  setting_emails_footer: RodapÃ© do e-mails
+  setting_protocol: Protocolo
+  setting_per_page_options: OpÃ§Ãµes de objectos por pÃ¡gina
+  setting_user_format: Formato de apresentaÃ£o de utilizadores
+  setting_activity_days_default: Dias mostrados na actividade do projecto
+  setting_display_subprojects_issues: Mostrar as tarefas dos sub-projectos nos projectos principais
+  setting_enabled_scm: Activar SCM
+  setting_mail_handler_api_enabled: Activar Web Service para e-mails recebidos
+  setting_mail_handler_api_key: Chave da API
+  setting_sequential_project_identifiers: Gerar identificadores de projecto sequÃªnciais
+
+  project_module_issue_tracking: Tarefas
+  project_module_time_tracking: Registo de tempo
+  project_module_news: NotÃ­cias
+  project_module_documents: Documentos
+  project_module_files: Ficheiros
+  project_module_wiki: Wiki
+  project_module_repository: RepositÃ³rio
+  project_module_boards: Forum
+
+  label_user: Utilizador
+  label_user_plural: Utilizadores
+  label_user_new: Novo utilizador
+  label_project: Projecto
+  label_project_new: Novo projecto
+  label_project_plural: Projectos
+  label_x_projects:
+    zero:  no projects
+    one:   1 project
+    other: "%{count} projects"
+  label_project_all: Todos os projectos
+  label_project_latest: Ãšltimos projectos
+  label_issue: Tarefa
+  label_issue_new: Nova tarefa
+  label_issue_plural: Tarefas
+  label_issue_view_all: Ver todas as tarefas
+  label_issues_by: "Tarefas por %{value}"
+  label_issue_added: Tarefa adicionada
+  label_issue_updated: Tarefa actualizada
+  label_document: Documento
+  label_document_new: Novo documento
+  label_document_plural: Documentos
+  label_document_added: Documento adicionado
+  label_role: FunÃ§Ã£o
+  label_role_plural: FunÃ§Ãµes
+  label_role_new: Nova funÃ§Ã£o
+  label_role_and_permissions: FunÃ§Ãµes e permissÃµes
+  label_member: Membro
+  label_member_new: Novo membro
+  label_member_plural: Membros
+  label_tracker: Tipo
+  label_tracker_plural: Tipos
+  label_tracker_new: Novo tipo
+  label_workflow: Fluxo de trabalho
+  label_issue_status: Estado da tarefa
+  label_issue_status_plural: Estados da tarefa
+  label_issue_status_new: Novo estado
+  label_issue_category: Categoria de tarefa
+  label_issue_category_plural: Categorias de tarefa
+  label_issue_category_new: Nova categoria
+  label_custom_field: Campo personalizado
+  label_custom_field_plural: Campos personalizados
+  label_custom_field_new: Novo campo personalizado
+  label_enumerations: EnumeraÃ§Ãµes
+  label_enumeration_new: Novo valor
+  label_information: InformaÃ§Ã£o
+  label_information_plural: InformaÃ§Ãµes
+  label_please_login: Por favor autentique-se
+  label_register: Registar
+  label_password_lost: Perdi a palavra-chave
+  label_home: PÃ¡gina Inicial
+  label_my_page: PÃ¡gina Pessoal
+  label_my_account: Minha conta
+  label_my_projects: Meus projectos
+  label_administration: AdministraÃ§Ã£o
+  label_login: Entrar
+  label_logout: Sair
+  label_help: Ajuda
+  label_reported_issues: Tarefas criadas
+  label_assigned_to_me_issues: Tarefas atribuÃ­das a mim
+  label_last_login: Ãšltimo acesso
+  label_registered_on: Registado em
+  label_activity: Actividade
+  label_overall_activity: Actividade geral
+  label_new: Novo
+  label_logged_as: Ligado como
+  label_environment: Ambiente
+  label_authentication: AutenticaÃ§Ã£o
+  label_auth_source: Modo de autenticaÃ§Ã£o
+  label_auth_source_new: Novo modo de autenticaÃ§Ã£o
+  label_auth_source_plural: Modos de autenticaÃ§Ã£o
+  label_subproject_plural: Sub-projectos
+  label_and_its_subprojects: "%{value} e sub-projectos"
+  label_min_max_length: Tamanho mÃ­nimo-mÃ¡ximo
+  label_list: Lista
+  label_date: Data
+  label_integer: Inteiro
+  label_float: Decimal
+  label_boolean: Booleano
+  label_string: Texto
+  label_text: Texto longo
+  label_attribute: Atributo
+  label_attribute_plural: Atributos
+  label_no_data: Sem dados para mostrar
+  label_change_status: Mudar estado
+  label_history: HistÃ³rico
+  label_attachment: Ficheiro
+  label_attachment_new: Novo ficheiro
+  label_attachment_delete: Apagar ficheiro
+  label_attachment_plural: Ficheiros
+  label_file_added: Ficheiro adicionado
+  label_report: RelatÃ³rio
+  label_report_plural: RelatÃ³rios
+  label_news: NotÃ­cia
+  label_news_new: Nova notÃ­cia
+  label_news_plural: NotÃ­cias
+  label_news_latest: Ãšltimas notÃ­cias
+  label_news_view_all: Ver todas as notÃ­cias
+  label_news_added: NotÃ­cia adicionada
+  label_settings: ConfiguraÃ§Ãµes
+  label_overview: VisÃ£o geral
+  label_version: VersÃ£o
+  label_version_new: Nova versÃ£o
+  label_version_plural: VersÃµes
+  label_confirmation: ConfirmaÃ§Ã£o
+  label_export_to: 'TambÃ©m disponÃ­vel em:'
+  label_read: Ler...
+  label_public_projects: Projectos pÃºblicos
+  label_open_issues: aberto
+  label_open_issues_plural: abertos
+  label_closed_issues: fechado
+  label_closed_issues_plural: fechados
+  label_x_open_issues_abbr_on_total:
+    zero:  0 abertas / %{total}
+    one:   1 aberta / %{total}
+    other: "%{count} abertas / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 abertas
+    one:   1 aberta
+    other: "%{count} abertas"
+  label_x_closed_issues_abbr:
+    zero:  0 fechadas
+    one:   1 fechada
+    other: "%{count} fechadas"
+  label_total: Total
+  label_permissions: PermissÃµes
+  label_current_status: Estado actual
+  label_new_statuses_allowed: Novos estados permitidos
+  label_all: todos
+  label_none: nenhum
+  label_nobody: ninguÃ©m
+  label_next: PrÃ³ximo
+  label_previous: Anterior
+  label_used_by: Usado por
+  label_details: Detalhes
+  label_add_note: Adicionar nota
+  label_per_page: Por pÃ¡gina
+  label_calendar: CalendÃ¡rio
+  label_months_from: meses de
+  label_gantt: Gantt
+  label_internal: Interno
+  label_last_changes: "Ãºltimas %{count} alteraÃ§Ãµes"
+  label_change_view_all: Ver todas as alteraÃ§Ãµes
+  label_personalize_page: Personalizar esta pÃ¡gina
+  label_comment: ComentÃ¡rio
+  label_comment_plural: ComentÃ¡rios
+  label_x_comments:
+    zero: sem comentÃ¡rios
+    one: 1 comentÃ¡rio
+    other: "%{count} comentÃ¡rios"
+  label_comment_add: Adicionar comentÃ¡rio
+  label_comment_added: ComentÃ¡rio adicionado
+  label_comment_delete: Apagar comentÃ¡rios
+  label_query: Consulta personalizada
+  label_query_plural: Consultas personalizadas
+  label_query_new: Nova consulta
+  label_filter_add: Adicionar filtro
+  label_filter_plural: Filtros
+  label_equals: Ã©
+  label_not_equals: nÃ£o Ã©
+  label_in_less_than: em menos de
+  label_in_more_than: em mais de
+  label_in: em
+  label_today: hoje
+  label_all_time: sempre
+  label_yesterday: ontem
+  label_this_week: esta semana
+  label_last_week: semana passada
+  label_last_n_days: "Ãºltimos %{count} dias"
+  label_this_month: este mÃªs
+  label_last_month: mÃªs passado
+  label_this_year: este ano
+  label_date_range: Date range
+  label_less_than_ago: menos de dias atrÃ¡s
+  label_more_than_ago: mais de dias atrÃ¡s
+  label_ago: dias atrÃ¡s
+  label_contains: contÃ©m
+  label_not_contains: nÃ£o contÃ©m
+  label_day_plural: dias
+  label_repository: RepositÃ³rio
+  label_repository_plural: RepositÃ³rios
+  label_browse: Navegar
+  label_revision: RevisÃ£o
+  label_revision_plural: RevisÃµes
+  label_associated_revisions: RevisÃµes associadas
+  label_added: adicionado
+  label_modified: modificado
+  label_copied: copiado
+  label_renamed: renomeado
+  label_deleted: apagado
+  label_latest_revision: Ãšltima revisÃ£o
+  label_latest_revision_plural: Ãšltimas revisÃµes
+  label_view_revisions: Ver revisÃµes
+  label_max_size: Tamanho mÃ¡ximo
+  label_sort_highest: Mover para o inÃ­cio
+  label_sort_higher: Mover para cima
+  label_sort_lower: Mover para baixo
+  label_sort_lowest: Mover para o fim
+  label_roadmap: PlanificaÃ§Ã£o
+  label_roadmap_due_in: "Termina em %{value}"
+  label_roadmap_overdue: "Atrasado %{value}"
+  label_roadmap_no_issues: Sem tarefas para esta versÃ£o
+  label_search: Procurar
+  label_result_plural: Resultados
+  label_all_words: Todas as palavras
+  label_wiki: Wiki
+  label_wiki_edit: EdiÃ§Ã£o da Wiki
+  label_wiki_edit_plural: EdiÃ§Ãµes da Wiki
+  label_wiki_page: PÃ¡gina da Wiki
+  label_wiki_page_plural: PÃ¡ginas da Wiki
+  label_index_by_title: Ãndice por tÃ­tulo
+  label_index_by_date: Ãndice por data
+  label_current_version: VersÃ£o actual
+  label_preview: PrÃ©-visualizar
+  label_feed_plural: Feeds
+  label_changes_details: Detalhes de todas as mudanÃ§as
+  label_issue_tracking: Tarefas
+  label_spent_time: Tempo gasto
+  label_f_hour: "%{value} hora"
+  label_f_hour_plural: "%{value} horas"
+  label_time_tracking: Registo de tempo
+  label_change_plural: MudanÃ§as
+  label_statistics: EstatÃ­sticas
+  label_commits_per_month: Commits por mÃªs
+  label_commits_per_author: Commits por autor
+  label_view_diff: Ver diferenÃ§as
+  label_diff_inline: inline
+  label_diff_side_by_side: lado a lado
+  label_options: OpÃ§Ãµes
+  label_copy_workflow_from: Copiar fluxo de trabalho de
+  label_permissions_report: RelatÃ³rio de permissÃµes
+  label_watched_issues: Tarefas observadas
+  label_related_issues: Tarefas relacionadas
+  label_applied_status: Estado aplicado
+  label_loading: A carregar...
+  label_relation_new: Nova relaÃ§Ã£o
+  label_relation_delete: Apagar relaÃ§Ã£o
+  label_relates_to: relacionado a
+  label_duplicates: duplica
+  label_duplicated_by: duplicado por
+  label_blocks: bloqueia
+  label_blocked_by: bloqueado por
+  label_precedes: precede
+  label_follows: segue
+  label_end_to_start: fim a inÃ­cio
+  label_end_to_end: fim a fim
+  label_start_to_start: inÃ­cio a inÃ­cio
+  label_start_to_end: inÃ­cio a fim
+  label_stay_logged_in: Guardar sessÃ£o
+  label_disabled: desactivado
+  label_show_completed_versions: Mostrar versÃµes acabadas
+  label_me: eu
+  label_board: Forum
+  label_board_new: Novo forum
+  label_board_plural: Forums
+  label_topic_plural: TÃ³picos
+  label_message_plural: Mensagens
+  label_message_last: Ãšltima mensagem
+  label_message_new: Nova mensagem
+  label_message_posted: Mensagem adicionada
+  label_reply_plural: Respostas
+  label_send_information: Enviar dados da conta para o utilizador
+  label_year: Ano
+  label_month: mÃªs
+  label_week: Semana
+  label_date_from: De
+  label_date_to: Para
+  label_language_based: Baseado na lÃ­ngua do utilizador
+  label_sort_by: "Ordenar por %{value}"
+  label_send_test_email: enviar um e-mail de teste
+  label_feeds_access_key_created_on: "Chave RSS criada hÃ¡ %{value} atrÃ¡s"
+  label_module_plural: MÃ³dulos
+  label_added_time_by: "Adicionado por %{author} hÃ¡ %{age} atrÃ¡s"
+  label_updated_time: "Alterado hÃ¡ %{value} atrÃ¡s"
+  label_jump_to_a_project: Ir para o projecto...
+  label_file_plural: Ficheiros
+  label_changeset_plural: Changesets
+  label_default_columns: Colunas por omissÃ£o
+  label_no_change_option: (sem alteraÃ§Ã£o)
+  label_bulk_edit_selected_issues: Editar tarefas seleccionadas em conjunto
+  label_theme: Tema
+  label_default: PadrÃ£o
+  label_search_titles_only: Procurar apenas em tÃ­tulos
+  label_user_mail_option_all: "Para qualquer evento em todos os meus projectos"
+  label_user_mail_option_selected: "Para qualquer evento apenas nos projectos seleccionados..."
+  label_user_mail_no_self_notified: "NÃ£o quero ser notificado de alteraÃ§Ãµes feitas por mim"
+  label_registration_activation_by_email: ActivaÃ§Ã£o da conta por e-mail
+  label_registration_manual_activation: ActivaÃ§Ã£o manual da conta
+  label_registration_automatic_activation: ActivaÃ§Ã£o automÃ¡tica da conta
+  label_display_per_page: "Por pÃ¡gina: %{value}"
+  label_age: Idade
+  label_change_properties: Mudar propriedades
+  label_general: Geral
+  label_more: Mais
+  label_scm: SCM
+  label_plugins: ExtensÃµes
+  label_ldap_authentication: AutenticaÃ§Ã£o LDAP
+  label_downloads_abbr: D/L
+  label_optional_description: DescriÃ§Ã£o opcional
+  label_add_another_file: Adicionar outro ficheiro
+  label_preferences: PreferÃªncias
+  label_chronological_order: Em ordem cronolÃ³gica
+  label_reverse_chronological_order: Em ordem cronolÃ³gica inversa
+  label_planning: Planeamento
+  label_incoming_emails: E-mails a chegar
+  label_generate_key: Gerar uma chave
+  label_issue_watchers: Observadores
+
+  button_login: Entrar
+  button_submit: Submeter
+  button_save: Guardar
+  button_check_all: Marcar tudo
+  button_uncheck_all: Desmarcar tudo
+  button_delete: Apagar
+  button_create: Criar
+  button_test: Testar
+  button_edit: Editar
+  button_add: Adicionar
+  button_change: Alterar
+  button_apply: Aplicar
+  button_clear: Limpar
+  button_lock: Bloquear
+  button_unlock: Desbloquear
+  button_download: Download
+  button_list: Listar
+  button_view: Ver
+  button_move: Mover
+  button_back: Voltar
+  button_cancel: Cancelar
+  button_activate: Activar
+  button_sort: Ordenar
+  button_log_time: Tempo de trabalho
+  button_rollback: Voltar para esta versÃ£o
+  button_watch: Observar
+  button_unwatch: Deixar de observar
+  button_reply: Responder
+  button_archive: Arquivar
+  button_unarchive: Desarquivar
+  button_reset: Reinicializar
+  button_rename: Renomear
+  button_change_password: Mudar palavra-chave
+  button_copy: Copiar
+  button_annotate: Anotar
+  button_update: Actualizar
+  button_configure: Configurar
+  button_quote: Citar
+
+  status_active: activo
+  status_registered: registado
+  status_locked: bloqueado
+
+  text_select_mail_notifications: Seleccionar as acÃ§Ãµes que originam uma notificaÃ§Ã£o por e-mail.
+  text_regexp_info: ex. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 siginifica sem restriÃ§Ã£o
+  text_project_destroy_confirmation: Tem a certeza que deseja apagar o projecto e todos os dados relacionados?
+  text_subprojects_destroy_warning: "O(s) seu(s) sub-projecto(s): %{value} tambÃ©m serÃ¡/serÃ£o apagado(s)."
+  text_workflow_edit: Seleccione uma funÃ§Ã£o e um tipo de tarefa para editar o fluxo de trabalho
+  text_are_you_sure: Tem a certeza?
+  text_tip_issue_begin_day: tarefa a comeÃ§ar neste dia
+  text_tip_issue_end_day: tarefa a acabar neste dia
+  text_tip_issue_begin_end_day: tarefa a comeÃ§ar e acabar neste dia
+  text_caracters_maximum: "mÃ¡ximo %{count} caracteres."
+  text_caracters_minimum: "Deve ter pelo menos %{count} caracteres."
+  text_length_between: "Deve ter entre %{min} e %{max} caracteres."
+  text_tracker_no_workflow: Sem fluxo de trabalho definido para este tipo de tarefa.
+  text_unallowed_characters: Caracteres nÃ£o permitidos
+  text_comma_separated: Permitidos mÃºltiplos valores (separados por vÃ­rgula).
+  text_issues_ref_in_commit_messages: Referenciando e fechando tarefas em mensagens de commit
+  text_issue_added: "Tarefa %{id} foi criada por %{author}."
+  text_issue_updated: "Tarefa %{id} foi actualizada por %{author}."
+  text_wiki_destroy_confirmation: Tem a certeza que deseja apagar este wiki e todo o seu conteÃºdo?
+  text_issue_category_destroy_question: "Algumas tarefas (%{count}) estÃ£o atribuÃ­das a esta categoria. O que quer fazer?"
+  text_issue_category_destroy_assignments: Remover as atribuiÃ§Ãµes Ã  categoria
+  text_issue_category_reassign_to: Re-atribuir as tarefas para esta categoria
+  text_user_mail_option: "Para projectos nÃ£o seleccionados, apenas receberÃ¡ notificaÃ§Ãµes acerca de coisas que estÃ¡ a observar ou estÃ¡ envolvido (ex. tarefas das quais foi o criador ou lhes foram atribuÃ­das)."
+  text_no_configuration_data: "Perfis, tipos de tarefas, estados das tarefas e workflows ainda nÃ£o foram configurados.\nÃ‰ extremamente recomendado carregar as configuraÃ§Ãµes padrÃ£o. SerÃ¡ capaz de as modificar depois de estarem carregadas."
+  text_load_default_configuration: Carregar as configuraÃ§Ãµes padrÃ£o
+  text_status_changed_by_changeset: "Aplicado no changeset %{value}."
+  text_issues_destroy_confirmation: 'Tem a certeza que deseja apagar a(s) tarefa(s) seleccionada(s)?'
+  text_select_project_modules: 'Seleccione os mÃ³dulos a activar para este projecto:'
+  text_default_administrator_account_changed: Conta default de administrador alterada.
+  text_file_repository_writable: RepositÃ³rio de ficheiros com permissÃµes de escrita
+  text_rmagick_available: RMagick disponÃ­vel (opcional)
+  text_destroy_time_entries_question: "%{hours} horas de trabalho foram atribuÃ­das a estas tarefas que vai apagar. O que deseja fazer?"
+  text_destroy_time_entries: Apagar as horas
+  text_assign_time_entries_to_project: Atribuir as horas ao projecto
+  text_reassign_time_entries: 'Re-atribuir as horas para esta tarefa:'
+  text_user_wrote: "%{value} escreveu:"
+  text_enumeration_destroy_question: "%{count} objectos estÃ£o atribuÃ­dos a este valor."
+  text_enumeration_category_reassign_to: 'Re-atribuÃ­-los para este valor:'
+  text_email_delivery_not_configured: "Entrega por e-mail nÃ£o estÃ¡ configurada, e as notificaÃ§Ã£o estÃ£o desactivadas.\nConfigure o seu servidor de SMTP em config/configuration.yml e reinicie a aplicaÃ§Ã£o para activar estas funcionalidades."
+
+  default_role_manager: Gestor
+  default_role_developer: Programador
+  default_role_reporter: RepÃ³rter
+  default_tracker_bug: Bug
+  default_tracker_feature: Funcionalidade
+  default_tracker_support: Suporte
+  default_issue_status_new: Novo
+  default_issue_status_in_progress: Em curso
+  default_issue_status_resolved: Resolvido
+  default_issue_status_feedback: Feedback
+  default_issue_status_closed: Fechado
+  default_issue_status_rejected: Rejeitado
+  default_doc_category_user: DocumentaÃ§Ã£o de utilizador
+  default_doc_category_tech: DocumentaÃ§Ã£o tÃ©cnica
+  default_priority_low: Baixa
+  default_priority_normal: Normal
+  default_priority_high: Alta
+  default_priority_urgent: Urgente
+  default_priority_immediate: Imediata
+  default_activity_design: Planeamento
+  default_activity_development: Desenvolvimento
+
+  enumeration_issue_priorities: Prioridade de tarefas
+  enumeration_doc_categories: Categorias de documentos
+  enumeration_activities: Actividades (Registo de tempo)
+  setting_plain_text_mail: Apenas texto simples (sem HTML)
+  permission_view_files: Ver ficheiros
+  permission_edit_issues: Editar tarefas
+  permission_edit_own_time_entries: Editar horas pessoais
+  permission_manage_public_queries: Gerir queries pÃºblicas
+  permission_add_issues: Adicionar tarefas
+  permission_log_time: Registar tempo gasto
+  permission_view_changesets: Ver changesets
+  permission_view_time_entries: Ver tempo gasto
+  permission_manage_versions: Gerir versÃµes
+  permission_manage_wiki: Gerir wiki
+  permission_manage_categories: Gerir categorias de tarefas
+  permission_protect_wiki_pages: Proteger pÃ¡ginas de wiki
+  permission_comment_news: Comentar notÃ­cias
+  permission_delete_messages: Apagar mensagens
+  permission_select_project_modules: Seleccionar mÃ³dulos do projecto
+  permission_edit_wiki_pages: Editar pÃ¡ginas de wiki
+  permission_add_issue_watchers: Adicionar observadores
+  permission_view_gantt: ver diagrama de Gantt
+  permission_move_issues: Mover tarefas
+  permission_manage_issue_relations: Gerir relaÃ§Ãµes de tarefas
+  permission_delete_wiki_pages: Apagar pÃ¡ginas de wiki
+  permission_manage_boards: Gerir forums
+  permission_delete_wiki_pages_attachments: Apagar anexos
+  permission_view_wiki_edits: Ver histÃ³rico da wiki
+  permission_add_messages: Submeter mensagens
+  permission_view_messages: Ver mensagens
+  permission_manage_files: Gerir ficheiros
+  permission_edit_issue_notes: Editar notas de tarefas
+  permission_manage_news: Gerir notÃ­cias
+  permission_view_calendar: Ver calendÃ¡rio
+  permission_manage_members: Gerir membros
+  permission_edit_messages: Editar mensagens
+  permission_delete_issues: Apagar tarefas
+  permission_view_issue_watchers: Ver lista de observadores
+  permission_manage_repository: Gerir repositÃ³rio
+  permission_commit_access: Acesso a submissÃ£o
+  permission_browse_repository: Navegar em repositÃ³rio
+  permission_view_documents: Ver documentos
+  permission_edit_project: Editar projecto
+  permission_add_issue_notes: Adicionar notas a tarefas
+  permission_save_queries: Guardar queries
+  permission_view_wiki_pages: Ver wiki
+  permission_rename_wiki_pages: Renomear pÃ¡ginas de wiki
+  permission_edit_time_entries: Editar entradas de tempo
+  permission_edit_own_issue_notes: Editar as prÃ³rpias notas
+  setting_gravatar_enabled: Utilizar Ã­cones Gravatar
+  label_example: Exemplo
+  text_repository_usernames_mapping: "Seleccionar ou actualizar o utilizador de Redmine mapeado a cada nome de utilizador encontrado no repositÃ³rio.\nUtilizadores com o mesmo nome de utilizador ou email no Redmine e no repositÃ³rio sÃ£o mapeados automaticamente."
+  permission_edit_own_messages: Editar as prÃ³prias mensagens
+  permission_delete_own_messages: Apagar as prÃ³prias mensagens
+  label_user_activity: "Actividade de %{value}"
+  label_updated_time_by: "Actualizado por %{author} hÃ¡ %{age}"
+  text_diff_truncated: '... Este diff foi truncado porque excede o tamanho mÃ¡ximo que pode ser mostrado.'
+  setting_diff_max_lines_displayed: NÃºmero mÃ¡ximo de linhas de diff mostradas
+  text_plugin_assets_writable: Escrita na pasta de activos dos mÃ³dulos de extensÃ£o possÃ­vel
+  warning_attachments_not_saved: "NÃ£o foi possÃ­vel gravar %{count} ficheiro(s) ."
+  button_create_and_continue: Criar e continuar
+  text_custom_field_possible_values_info: 'Uma linha para cada valor'
+  label_display: Mostrar
+  field_editable: EditÃ¡vel
+  setting_repository_log_display_limit: NÃºmero mÃ¡ximo de revisÃµes exibido no relatÃ³rio de ficheiro
+  setting_file_max_size_displayed: Tamanho mÃ¡ximo dos ficheiros de texto exibidos inline
+  field_watcher: Observador
+  setting_openid: Permitir inÃ­cio de sessÃ£o e registo com OpenID
+  field_identity_url: URL do OpenID
+  label_login_with_open_id_option: ou inÃ­cio de sessÃ£o com OpenID
+  field_content: ConteÃºdo
+  label_descending: Descendente
+  label_sort: Ordenar
+  label_ascending: Ascendente
+  label_date_from_to: De %{start} a %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Esta pÃ¡gina tem %{descendants} pÃ¡gina(s) subordinada(s) e descendente(s). O que deseja fazer?
+  text_wiki_page_reassign_children: Reatribuir pÃ¡ginas subordinadas a esta pÃ¡gina principal
+  text_wiki_page_nullify_children: Manter pÃ¡ginas subordinadas como pÃ¡ginas raÃ­z
+  text_wiki_page_destroy_children: Apagar as pÃ¡ginas subordinadas e todos os seus descendentes
+  setting_password_min_length: Tamanho mÃ­nimo de palavra-chave
+  field_group_by: Agrupar resultados por
+  mail_subject_wiki_content_updated: "A pÃ¡gina Wiki '%{id}' foi actualizada"
+  label_wiki_content_added: PÃ¡gina Wiki adicionada
+  mail_subject_wiki_content_added: "A pÃ¡gina Wiki '%{id}' foi adicionada"
+  mail_body_wiki_content_added: A pÃ¡gina Wiki '%{id}' foi adicionada por %{author}.
+  label_wiki_content_updated: PÃ¡gina Wiki actualizada
+  mail_body_wiki_content_updated: A pÃ¡gina Wiki '%{id}' foi actualizada por %{author}.
+  permission_add_project: Criar projecto
+  setting_new_project_user_role_id: FunÃ§Ã£o atribuÃ­da a um utilizador nÃ£o-administrador que cria um projecto
+  label_view_all_revisions: Ver todas as revisÃµes
+  label_tag: Etiqueta
+  label_branch: Ramo
+  error_no_tracker_in_project: Este projecto nÃ£o tem associado nenhum tipo de tarefas. Verifique as definiÃ§Ãµes do projecto.
+  error_no_default_issue_status: NÃ£o estÃ¡ definido um estado padrÃ£o para as tarefas. Verifique a sua configuraÃ§Ã£o (dirija-se a "AdministraÃ§Ã£o -> Estados da tarefa").
+  label_group_plural: Grupos
+  label_group: Grupo
+  label_group_new: Novo grupo
+  label_time_entry_plural: Tempo registado
+  text_journal_changed: "%{label} alterado de %{old} para %{new}"
+  text_journal_set_to: "%{label} configurado como %{value}"
+  text_journal_deleted: "%{label} apagou (%{old})"
+  text_journal_added: "%{label} %{value} adicionado"
+  field_active: Activo
+  enumeration_system_activity: Actividade de sistema
+  permission_delete_issue_watchers: Apagar observadores
+  version_status_closed: fechado
+  version_status_locked: protegido
+  version_status_open: aberto
+  error_can_not_reopen_issue_on_closed_version: NÃ£o Ã© possÃ­vel voltar a abrir uma tarefa atribuÃ­da a uma versÃ£o fechada
+  label_user_anonymous: AnÃ³nimo
+  button_move_and_follow: Mover e seguir
+  setting_default_projects_modules: MÃ³dulos activos por predefiniÃ§Ã£o para novos projectos
+  setting_gravatar_default: Imagem Gravatar predefinida
+  field_sharing: Partilha
+  label_version_sharing_hierarchy: Com hierarquia do projecto
+  label_version_sharing_system: Com todos os projectos
+  label_version_sharing_descendants: Com os sub-projectos
+  label_version_sharing_tree: Com Ã¡rvore do projecto
+  label_version_sharing_none: NÃ£o partilhado
+  error_can_not_archive_project: NÃ£o Ã© possÃ­vel arquivar este projecto
+  button_duplicate: Duplicar
+  button_copy_and_follow: Copiar e seguir
+  label_copy_source: Origem
+  setting_issue_done_ratio: Calcular a percentagem de progresso da tarefa
+  setting_issue_done_ratio_issue_status: AtravÃ©s do estado da tarefa
+  error_issue_done_ratios_not_updated: Percentagens de progresso da tarefa nÃ£o foram actualizadas.
+  error_workflow_copy_target: Seleccione os tipos de tarefas e funÃ§Ãµes desejadas
+  setting_issue_done_ratio_issue_field: AtravÃ©s do campo da tarefa
+  label_copy_same_as_target: Mesmo que o alvo
+  label_copy_target: Alvo
+  notice_issue_done_ratios_updated: Percentagens de progresso da tarefa actualizadas.
+  error_workflow_copy_source: Seleccione um tipo de tarefa ou funÃ§Ã£o de origem
+  label_update_issue_done_ratios: Actualizar percentagens de progresso da tarefa
+  setting_start_of_week: Iniciar calendÃ¡rios a
+  permission_view_issues: Ver tarefas
+  label_display_used_statuses_only: SÃ³ exibir estados empregues por este tipo de tarefa
+  label_revision_id: RevisÃ£o %{value}
+  label_api_access_key: Chave de acesso API
+  label_api_access_key_created_on: Chave de acesso API criada hÃ¡ %{value}
+  label_feeds_access_key: Chave de acesso RSS
+  notice_api_access_key_reseted: A sua chave de acesso API foi reinicializada.
+  setting_rest_api_enabled: Activar serviÃ§o Web REST
+  label_missing_api_access_key: Chave de acesso API em falta
+  label_missing_feeds_access_key: Chave de acesso RSS em falta
+  button_show: Mostrar
+  text_line_separated: VÃ¡rios valores permitidos (uma linha para cada valor).
+  setting_mail_handler_body_delimiters: Truncar mensagens de correio electrÃ³nico apÃ³s uma destas linhas
+  permission_add_subprojects: Criar sub-projectos
+  label_subproject_new: Novo sub-projecto
+  text_own_membership_delete_confirmation: |-
+    EstÃ¡ prestes a eliminar parcial ou totalmente as suas permissÃµes. Ã‰ possÃ­vel que nÃ£o possa editar o projecto apÃ³s esta acÃ§Ã£o.
+    Tem a certeza de que deseja continuar?
+  label_close_versions: Fechar versÃµes completas
+  label_board_sticky: Fixar mensagem
+  label_board_locked: Proteger
+  permission_export_wiki_pages: Exportar pÃ¡ginas Wiki
+  setting_cache_formatted_text: Colocar formataÃ§Ã£o do texto na memÃ³ria cache
+  permission_manage_project_activities: Gerir actividades do projecto
+  error_unable_delete_issue_status: NÃ£o foi possÃ­vel apagar o estado da tarefa
+  label_profile: Perfil
+  permission_manage_subtasks: Gerir sub-tarefas
+  field_parent_issue: Tarefa principal
+  label_subtask_plural: Sub-tarefa
+  label_project_copy_notifications: Enviar notificaÃ§Ãµes por e-mail durante a cÃ³pia do projecto
+  error_can_not_delete_custom_field: NÃ£o foi possÃ­vel apagar o campo personalizado
+  error_unable_to_connect: NÃ£o foi possÃ­vel ligar (%{value})
+  error_can_not_remove_role: Esta funÃ§Ã£o estÃ¡ actualmente em uso e nÃ£o pode ser apagada.
+  error_can_not_delete_tracker: Existem ainda tarefas nesta categoria. NÃ£o Ã© possÃ­vel apagar este tipo de tarefa.
+  field_principal: Principal
+  label_my_page_block: Bloco da minha pÃ¡gina
+  notice_failed_to_save_members: "Erro ao guardar o(s) membro(s): %{errors}."
+  text_zoom_out: Ampliar
+  text_zoom_in: Reduzir
+  notice_unable_delete_time_entry: NÃ£o foi possÃ­vel apagar a entrada de tempo registado.
+  label_overall_spent_time: Total de tempo registado
+  field_time_entries: Tempo registado
+  project_module_gantt: Gantt
+  project_module_calendar: CalendÃ¡rio
+  button_edit_associated_wikipage: "Editar pÃ¡gina Wiki associada: %{page_title}"
+  field_text: Campo de texto
+  label_user_mail_option_only_owner: Apenas para tarefas das quais sou proprietÃ¡rio
+  setting_default_notification_option: OpÃ§Ã£o predefinida de notificaÃ§Ã£o
+  label_user_mail_option_only_my_events: Apenas para tarefas que observo ou em que estou envolvido
+  label_user_mail_option_only_assigned: Apenas para tarefas que me foram atribuÃ­das
+  label_user_mail_option_none: Sem eventos
+  field_member_of_group: Grupo do detentor de atribuiÃ§Ã£o
+  field_assigned_to_role: Papel do detentor de atribuiÃ§Ã£o
+  notice_not_authorized_archived_project: O projecto a que tentou aceder foi arquivado.
+  label_principal_search: "Procurar utilizador ou grupo:"
+  label_user_search: "Procurar utilizador:"
+  field_visible: VisÃ­vel
+  setting_emails_header: CabeÃ§alho dos e-mails
+  setting_commit_logtime_activity_id: Actividade para tempo registado
+  text_time_logged_by_changeset: Aplicado no conjunto de alteraÃ§Ãµes %{value}.
+  setting_commit_logtime_enabled: Activar registo de tempo
+  notice_gantt_chart_truncated: O grÃ¡fico foi truncado porque excede o nÃºmero mÃ¡ximo de itens visÃ­veis (%{max.})
+  setting_gantt_items_limit: NÃºmero mÃ¡ximo de itens exibidos no grÃ¡fico Gantt
+  field_warn_on_leaving_unsaved: Avisar-me quando deixar uma pÃ¡gina com texto por salvar
+  text_warn_on_leaving_unsaved: A pÃ¡gina actual contÃ©m texto por salvar que serÃ¡ perdido caso saia desta pÃ¡gina.
+  label_my_queries: As minhas consultas
+  text_journal_changed_no_detail: "%{label} actualizada"
+  label_news_comment_added: ComentÃ¡rio adicionado a uma notÃ­cia
+  button_expand_all: Expandir todos
+  button_collapse_all: Minimizar todos
+  label_additional_workflow_transitions_for_assignee: TransiÃ§Ãµes adicionais permitidas quando a tarefa estÃ¡ atribuida ao utilizador
+  label_additional_workflow_transitions_for_author: TransiÃ§Ãµes adicionais permitidas quando o utilizador Ã© o autor da tarefa
+  label_bulk_edit_selected_time_entries: EdiÃ§Ã£o em massa de registos de tempo
+  text_time_entries_destroy_confirmation: TÃªm a certeza que pretende apagar o(s) registo(s) de tempo selecionado(s)?
+  label_role_anonymous: AnÃ³nimo
+  label_role_non_member: NÃ£o membro
+  label_issue_note_added: Nota adicionada
+  label_issue_status_updated: Estado actualizado
+  label_issue_priority_updated: Prioridade adicionada
+  label_issues_visibility_own: Tarefas criadas ou atribuÃ­das ao utilizador
+  field_issues_visibility: Visibilidade das tarefas
+  label_issues_visibility_all: Todas as tarefas
+  permission_set_own_issues_private: Configurar as suas tarefas como pÃºblicas ou privadas
+  field_is_private: Privado
+  permission_set_issues_private: Configurar tarefas como pÃºblicas ou privadas
+  label_issues_visibility_public: Todas as tarefas pÃºblicas
+  text_issues_destroy_descendants_confirmation: IrÃ¡ apagar tambÃ©m %{count} subtarefa(s).
+  field_commit_logs_encoding: CodificaÃ§Ã£o das mensagens de commit
+  field_scm_path_encoding: CodificaÃ§Ã£o do caminho
+  text_scm_path_encoding_note: "Por omissÃ£o: UTF-8"
+  field_path_to_repository: Caminho para o repositÃ³rio
+  field_root_directory: RaÃ­z do directÃ³rio
+  field_cvs_module: MÃ³dulo
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: "RepositÃ³rio local (ex: /hgrepo, c:\\hgrepo)"
+  text_scm_command: Comando
+  text_scm_command_version: VersÃ£o
+  label_git_report_last_commit: Analisar Ãºltimo commit por ficheiros e pastas
+  text_scm_config: Pode configurar os comando SCM em config/configuration.yml. Por favor reinicie a aplicaÃ§Ã£o depois de alterar o ficheiro.
+  text_scm_command_not_available: O comando SCM nÃ£o estÃ¡ disponÃ­vel. Por favor verifique as configuraÃ§Ãµes no painel de administraÃ§Ã£o.
+  notice_issue_successful_create: Tarefa %{id} criada.
+  label_between: entre
+  setting_issue_group_assignment: Permitir atribuir tarefas a grupos
+  label_diff: diferenÃ§a
+  text_git_repository_note: O repositÃ³rio Ã© local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: DirecÃ§Ã£o da ordenaÃ§Ã£o
+  description_project_scope: Ã‚mbito da pesquisa
+  description_filter: Filtro
+  description_user_mail_notification: ConfiguraÃ§Ãµes das notificaÃ§Ãµes por email
+  description_date_from: Introduza data de inÃ­cio
+  description_message_content: ConteÃºdo da mensagem
+  description_available_columns: Colunas disponÃ­veis
+  description_date_range_interval: Escolha o intervalo seleccionando a data de inÃ­cio e de fim
+  description_issue_category_reassign: Escolha a categoria da tarefa
+  description_search: Campo de pesquisa
+  description_notes: Notas
+  description_date_range_list: Escolha o intervalo da lista
+  description_choose_project: Projecto
+  description_date_to: Introduza data de fim
+  description_query_sort_criteria_attribute: Ordenar atributos
+  description_wiki_subpages_reassign: Escolha nova pÃ¡gina pai
+  description_selected_columns: Colunas seleccionadas
+  label_parent_revision: Pai
+  label_child_revision: Filha
+  error_scm_annotate_big_text_file: Esta entrada nÃ£o pode ser anotada, excede o tamanha mÃ¡ximo.
+  setting_default_issue_start_date_to_creation_date: Utilizar a data actual como data de inÃ­cio para novas tarefas
+  button_edit_section: Editar esta secÃ§Ã£o
+  setting_repositories_encodings: CodificaÃ§Ã£o dos anexos e repositÃ³rios
+  description_all_columns: Todas as colunas
+  button_export: Exportar
+  label_export_options: "%{export_format} opÃ§Ãµes de exportaÃ§Ã£o"
+  error_attachment_too_big: Este ficheiro nÃ£o pode ser carregado pois excede o tamanho mÃ¡ximo permitido por ficheiro (%{max_size})
+  notice_failed_to_save_time_entries: "Falha ao guardar %{count} registo(s) de tempo dos %{total} seleccionados: %{ids}."
+  label_x_issues:
+    zero:  0 tarefas
+    one:   1 tarefa
+    other: "%{count} tarefas"
+  label_repository_new: Novo repositÃ³rio
+  field_repository_is_default: RepositÃ³rio principal
+  label_copy_attachments: Copiar anexos
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: VersÃµes completas
+  text_project_identifier_info: Apenas letras minÃºsculas (a-z), nÃºmeros, traÃ§os e sublinhados sÃ£o permitidos.<br />Depois de guardar nÃ£o Ã© possÃ­vel alterar.
+  field_multiple: MÃºltiplos valores
+  setting_commit_cross_project_ref: Permitir que tarefas dos restantes projectos sejam referenciadas e resolvidas
+  text_issue_conflict_resolution_add_notes: Adicionar as minhas notas e descartar as minhas restantes alteraÃ§Ãµes
+  text_issue_conflict_resolution_overwrite: Aplicar as minhas alteraÃ§Ãµes (notas antigas serÃ£o mantidas mas algumas alteraÃ§Ãµes podem se perder)
+  notice_issue_update_conflict: Esta tarefa foi actualizada por outro utilizador enquanto estava a edita-la.
+  text_issue_conflict_resolution_cancel: Descartar todas as minhas alteraÃ§Ãµes e actualizar %{link}
+  permission_manage_related_issues: Gerir tarefas relacionadas
+  field_auth_source_ldap_filter: Filtro LDAP
+  label_search_for_watchers: Pesquisar por observadores para adicionar
+  notice_account_deleted: A sua conta foi apagada permanentemente.
+  setting_unsubscribe: Permitir aos utilizadores apagarem a sua prÃ³pria conta
+  button_delete_my_account: Apagar a minha conta
+  text_account_destroy_confirmation: |-
+    TÃªm a certeza que pretende avanÃ§ar?
+    A sua conta vai ser permanentemente apagada, nÃ£o serÃ¡ possÃ­vel recupera-la.
+  error_session_expired: A sua sessÃ£o expirou. Por-favor autentique-se novamente.
+  text_session_expiration_settings: "AtenÃ§Ã£o: alterar estas configuraÃ§Ãµes pode fazer expirar as sessÃµes em curso, incluÃ­ndo a sua."
+  setting_session_lifetime: DuraÃ§Ã£o mÃ¡xima da sessÃ£o
+  setting_session_timeout: Tempo limite de inactividade da sessÃ£o
+  label_session_expiration: ExpiraÃ§Ã£o da sessÃ£o
+  permission_close_project: Fechar / re-abrir o projecto
+  label_show_closed_projects: Ver os projectos fechados
+  button_close: Fechar
+  button_reopen: Re-abrir
+  project_status_active: activo
+  project_status_closed: fechado
+  project_status_archived: arquivado
+  text_project_closed: Este projecto estÃ¡ fechado e Ã© apenas de leitura.
+  notice_user_successful_create: Utilizador %{id} criado.
+  field_core_fields: Campos padrÃ£o
+  field_timeout: Tempo limite (em segundos)
+  setting_thumbnails_enabled: Apresentar miniaturas dos anexos
+  setting_thumbnails_size: Tamanho das miniaturas (em pixeis)
+  label_status_transitions: Estado das transiÃ§Ãµes
+  label_fields_permissions: PermissÃµes do campo
+  label_readonly: Apenas de leitura
+  label_required: ObrigatÃ³rio
+  text_repository_identifier_info: Apenas letras minÃºsculas (a-z), nÃºmeros, traÃ§os e sublinhados sÃ£o permitidos.<br />Depois de guardar nÃ£o Ã© possÃ­vel alterar.
+  field_board_parent: FÃ³rum pai
+  label_attribute_of_project: "%{name} do Projecto"
+  label_attribute_of_author: "%{name} do Autor"
+  label_attribute_of_assigned_to: "%{name} do atribuÃ­do"
+  label_attribute_of_fixed_version: "%{name} da VersÃ£o"
+  label_copy_subtasks: Copiar sub-tarefas
+  label_copied_to: copiado para
+  label_copied_from: copiado de
+  label_any_issues_in_project: tarefas do projecto
+  label_any_issues_not_in_project: tarefas sem projecto
+  field_private_notes: Notas privadas
+  permission_view_private_notes: Ver notas privadas
+  permission_set_notes_private: Configurar notas como privadas
+  label_no_issues_in_project: sem tarefas no projecto
+  label_any: todos
+  label_last_n_weeks: Ãºltimas %{count} semanas
+  setting_cross_project_subtasks: Permitir sub-tarefas entre projectos
+  label_cross_project_descendants: Com os sub-projectos
+  label_cross_project_tree: Com Ã¡rvore do projecto
+  label_cross_project_hierarchy: Com hierarquia do projecto
+  label_cross_project_system: Com todos os projectos
+  button_hide: Esconder
+  setting_non_working_week_days: Dias nÃ£o Ãºteis
+  label_in_the_next_days: no futuro
+  label_in_the_past_days: no passado
+  label_attribute_of_user: Do utilizador %{name}
+  text_turning_multiple_off: Se desactivar a escolha mÃºltipla,
+    a escolha mÃºltipla serÃ¡ apagada de modo a manter apenas um valor por item.
+  label_attribute_of_issue: Tarefa de %{name}
+  permission_add_documents: Adicionar documentos
+  permission_edit_documents: Editar documentos
+  permission_delete_documents: Apagar documentos
+  label_gantt_progress_line: Barra de progresso
+  setting_jsonp_enabled: Activar suporte JSONP
+  field_inherit_members: Herdar membros
+  field_closed_on: Fechado
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/95/950437adc2699c368f2494322635c7283f1e4dcf.svn-base
--- /dev/null
+++ b/.svn/pristine/95/950437adc2699c368f2494322635c7283f1e4dcf.svn-base
@@ -0,0 +1,251 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'diff'
+require 'enumerator'
+
+class WikiPage < ActiveRecord::Base
+  include Redmine::SafeAttributes
+
+  belongs_to :wiki
+  has_one :content, :class_name => 'WikiContent', :foreign_key => 'page_id', :dependent => :destroy
+  acts_as_attachable :delete_permission => :delete_wiki_pages_attachments
+  acts_as_tree :dependent => :nullify, :order => 'title'
+
+  acts_as_watchable
+  acts_as_event :title => Proc.new {|o| "#{l(:label_wiki)}: #{o.title}"},
+                :description => :text,
+                :datetime => :created_on,
+                :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.wiki.project, :id => o.title}}
+
+  acts_as_searchable :columns => ['title', "#{WikiContent.table_name}.text"],
+                     :include => [{:wiki => :project}, :content],
+                     :permission => :view_wiki_pages,
+                     :project_key => "#{Wiki.table_name}.project_id"
+
+  attr_accessor :redirect_existing_links
+
+  validates_presence_of :title
+  validates_format_of :title, :with => /\A[^,\.\/\?\;\|\s]*\z/
+  validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false
+  validates_associated :content
+
+  validate :validate_parent_title
+  before_destroy :remove_redirects
+  before_save    :handle_redirects
+
+  # eager load information about last updates, without loading text
+  scope :with_updated_on, lambda {
+    select("#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on, #{WikiContent.table_name}.version").
+      joins("LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id")
+  }
+
+  # Wiki pages that are protected by default
+  DEFAULT_PROTECTED_PAGES = %w(sidebar)
+
+  safe_attributes 'parent_id', 'parent_title',
+    :if => lambda {|page, user| page.new_record? || user.allowed_to?(:rename_wiki_pages, page.project)}
+
+  def initialize(attributes=nil, *args)
+    super
+    if new_record? && DEFAULT_PROTECTED_PAGES.include?(title.to_s.downcase)
+      self.protected = true
+    end
+  end
+
+  def visible?(user=User.current)
+    !user.nil? && user.allowed_to?(:view_wiki_pages, project)
+  end
+
+  def title=(value)
+    value = Wiki.titleize(value)
+    @previous_title = read_attribute(:title) if @previous_title.blank?
+    write_attribute(:title, value)
+  end
+
+  def handle_redirects
+    self.title = Wiki.titleize(title)
+    # Manage redirects if the title has changed
+    if !@previous_title.blank? && (@previous_title != title) && !new_record?
+      # Update redirects that point to the old title
+      wiki.redirects.find_all_by_redirects_to(@previous_title).each do |r|
+        r.redirects_to = title
+        r.title == r.redirects_to ? r.destroy : r.save
+      end
+      # Remove redirects for the new title
+      wiki.redirects.find_all_by_title(title).each(&:destroy)
+      # Create a redirect to the new title
+      wiki.redirects << WikiRedirect.new(:title => @previous_title, :redirects_to => title) unless redirect_existing_links == "0"
+      @previous_title = nil
+    end
+  end
+
+  def remove_redirects
+    # Remove redirects to this page
+    wiki.redirects.find_all_by_redirects_to(title).each(&:destroy)
+  end
+
+  def pretty_title
+    WikiPage.pretty_title(title)
+  end
+
+  def content_for_version(version=nil)
+    result = content.versions.find_by_version(version.to_i) if version
+    result ||= content
+    result
+  end
+
+  def diff(version_to=nil, version_from=nil)
+    version_to = version_to ? version_to.to_i : self.content.version
+    content_to = content.versions.find_by_version(version_to)
+    content_from = version_from ? content.versions.find_by_version(version_from.to_i) : content_to.try(:previous)
+    return nil unless content_to && content_from
+
+    if content_from.version > content_to.version
+      content_to, content_from = content_from, content_to
+    end
+
+    (content_to && content_from) ? WikiDiff.new(content_to, content_from) : nil
+  end
+
+  def annotate(version=nil)
+    version = version ? version.to_i : self.content.version
+    c = content.versions.find_by_version(version)
+    c ? WikiAnnotate.new(c) : nil
+  end
+
+  def self.pretty_title(str)
+    (str && str.is_a?(String)) ? str.tr('_', ' ') : str
+  end
+
+  def project
+    wiki.project
+  end
+
+  def text
+    content.text if content
+  end
+
+  def updated_on
+    unless @updated_on
+      if time = read_attribute(:updated_on)
+        # content updated_on was eager loaded with the page
+        begin
+          @updated_on = (self.class.default_timezone == :utc ? Time.parse(time.to_s).utc : Time.parse(time.to_s).localtime)
+        rescue
+        end
+      else
+        @updated_on = content && content.updated_on
+      end
+    end
+    @updated_on
+  end
+
+  # Returns true if usr is allowed to edit the page, otherwise false
+  def editable_by?(usr)
+    !protected? || usr.allowed_to?(:protect_wiki_pages, wiki.project)
+  end
+
+  def attachments_deletable?(usr=User.current)
+    editable_by?(usr) && super(usr)
+  end
+
+  def parent_title
+    @parent_title || (self.parent && self.parent.pretty_title)
+  end
+
+  def parent_title=(t)
+    @parent_title = t
+    parent_page = t.blank? ? nil : self.wiki.find_page(t)
+    self.parent = parent_page
+  end
+
+  # Saves the page and its content if text was changed
+  def save_with_content
+    ret = nil
+    transaction do
+      if new_record?
+        # Rails automatically saves associated content
+        ret = save
+      else
+        ret = save && (content.text_changed? ? content.save : true)
+      end
+      raise ActiveRecord::Rollback unless ret
+    end
+    ret
+  end
+
+  protected
+
+  def validate_parent_title
+    errors.add(:parent_title, :invalid) if !@parent_title.blank? && parent.nil?
+    errors.add(:parent_title, :circular_dependency) if parent && (parent == self || parent.ancestors.include?(self))
+    errors.add(:parent_title, :not_same_project) if parent && (parent.wiki_id != wiki_id)
+  end
+end
+
+class WikiDiff < Redmine::Helpers::Diff
+  attr_reader :content_to, :content_from
+
+  def initialize(content_to, content_from)
+    @content_to = content_to
+    @content_from = content_from
+    super(content_to.text, content_from.text)
+  end
+end
+
+class WikiAnnotate
+  attr_reader :lines, :content
+
+  def initialize(content)
+    @content = content
+    current = content
+    current_lines = current.text.split(/\r?\n/)
+    @lines = current_lines.collect {|t| [nil, nil, t]}
+    positions = []
+    current_lines.size.times {|i| positions << i}
+    while (current.previous)
+      d = current.previous.text.split(/\r?\n/).diff(current.text.split(/\r?\n/)).diffs.flatten
+      d.each_slice(3) do |s|
+        sign, line = s[0], s[1]
+        if sign == '+' && positions[line] && positions[line] != -1
+          if @lines[positions[line]][0].nil?
+            @lines[positions[line]][0] = current.version
+            @lines[positions[line]][1] = current.author
+          end
+        end
+      end
+      d.each_slice(3) do |s|
+        sign, line = s[0], s[1]
+        if sign == '-'
+          positions.insert(line, -1)
+        else
+          positions[line] = nil
+        end
+      end
+      positions.compact!
+      # Stop if every line is annotated
+      break unless @lines.detect { |line| line[0].nil? }
+      current = current.previous
+    end
+    @lines.each { |line|
+      line[0] ||= current.version
+      # if the last known version is > 1 (eg. history was cleared), we don't know the author
+      line[1] ||= current.author if current.version == 1
+    }
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/95/9518b4c165dbfab5f7a31a09b585b6cec17723f3.svn-base
--- a/.svn/pristine/95/9518b4c165dbfab5f7a31a09b585b6cec17723f3.svn-base
+++ /dev/null
@@ -1,33 +0,0 @@
-class RedminePluginGenerator < Rails::Generator::NamedBase
-  attr_reader :plugin_path, :plugin_name, :plugin_pretty_name
-  
-  def initialize(runtime_args, runtime_options = {})
-    super
-    @plugin_name = "redmine_#{file_name.underscore}"
-    @plugin_pretty_name = plugin_name.titleize
-    @plugin_path = "vendor/plugins/#{plugin_name}"
-  end
-  
-  def manifest
-    record do |m|
-      m.directory "#{plugin_path}/app/controllers"
-      m.directory "#{plugin_path}/app/helpers"
-      m.directory "#{plugin_path}/app/models"
-      m.directory "#{plugin_path}/app/views"
-      m.directory "#{plugin_path}/db/migrate"
-      m.directory "#{plugin_path}/lib/tasks"
-      m.directory "#{plugin_path}/assets/images"
-      m.directory "#{plugin_path}/assets/javascripts"
-      m.directory "#{plugin_path}/assets/stylesheets"
-      m.directory "#{plugin_path}/lang"
-      m.directory "#{plugin_path}/config/locales"
-      m.directory "#{plugin_path}/test"
-      
-      m.template 'README.rdoc',    "#{plugin_path}/README.rdoc"
-      m.template 'init.rb.erb',   "#{plugin_path}/init.rb"
-      m.template 'en.yml',    "#{plugin_path}/lang/en.yml"
-      m.template 'en_rails_i18n.yml',    "#{plugin_path}/config/locales/en.yml"
-      m.template 'test_helper.rb.erb',    "#{plugin_path}/test/test_helper.rb"
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/95/954503d8b00c9c216119d7e8717102d3c9f6c727.svn-base
--- /dev/null
+++ b/.svn/pristine/95/954503d8b00c9c216119d7e8717102d3c9f6c727.svn-base
@@ -0,0 +1,168 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Acts
+    module Customizable
+      def self.included(base)
+        base.extend ClassMethods
+      end
+
+      module ClassMethods
+        def acts_as_customizable(options = {})
+          return if self.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
+          cattr_accessor :customizable_options
+          self.customizable_options = options
+          has_many :custom_values, :as => :customized,
+                                   :include => :custom_field,
+                                   :order => "#{CustomField.table_name}.position",
+                                   :dependent => :delete_all,
+                                   :validate => false
+
+          send :include, Redmine::Acts::Customizable::InstanceMethods
+          validate :validate_custom_field_values
+          after_save :save_custom_field_values
+        end
+      end
+
+      module InstanceMethods
+        def self.included(base)
+          base.extend ClassMethods
+          base.send :alias_method_chain, :reload, :custom_fields
+        end
+
+        def available_custom_fields
+          CustomField.where("type = '#{self.class.name}CustomField'").sorted.all
+        end
+
+        # Sets the values of the object's custom fields
+        # values is an array like [{'id' => 1, 'value' => 'foo'}, {'id' => 2, 'value' => 'bar'}]
+        def custom_fields=(values)
+          values_to_hash = values.inject({}) do |hash, v|
+            v = v.stringify_keys
+            if v['id'] && v.has_key?('value')
+              hash[v['id']] = v['value']
+            end
+            hash
+          end
+          self.custom_field_values = values_to_hash
+        end
+
+        # Sets the values of the object's custom fields
+        # values is a hash like {'1' => 'foo', 2 => 'bar'}
+        def custom_field_values=(values)
+          values = values.stringify_keys
+
+          custom_field_values.each do |custom_field_value|
+            key = custom_field_value.custom_field_id.to_s
+            if values.has_key?(key)
+              value = values[key]
+              if value.is_a?(Array)
+                value = value.reject(&:blank?).uniq
+                if value.empty?
+                  value << ''
+                end
+              end
+              custom_field_value.value = value
+            end
+          end
+          @custom_field_values_changed = true
+        end
+
+        def custom_field_values
+          @custom_field_values ||= available_custom_fields.collect do |field|
+            x = CustomFieldValue.new
+            x.custom_field = field
+            x.customized = self
+            if field.multiple?
+              values = custom_values.select { |v| v.custom_field == field }
+              if values.empty?
+                values << custom_values.build(:customized => self, :custom_field => field, :value => nil)
+              end
+              x.value = values.map(&:value)
+            else
+              cv = custom_values.detect { |v| v.custom_field == field }
+              cv ||= custom_values.build(:customized => self, :custom_field => field, :value => nil)
+              x.value = cv.value
+            end
+            x
+          end
+        end
+
+        def visible_custom_field_values
+          custom_field_values.select(&:visible?)
+        end
+
+        def custom_field_values_changed?
+          @custom_field_values_changed == true
+        end
+
+        def custom_value_for(c)
+          field_id = (c.is_a?(CustomField) ? c.id : c.to_i)
+          custom_values.detect {|v| v.custom_field_id == field_id }
+        end
+
+        def custom_field_value(c)
+          field_id = (c.is_a?(CustomField) ? c.id : c.to_i)
+          custom_field_values.detect {|v| v.custom_field_id == field_id }.try(:value)
+        end
+
+        def validate_custom_field_values
+          if new_record? || custom_field_values_changed?
+            custom_field_values.each(&:validate_value)
+          end
+        end
+
+        def save_custom_field_values
+          target_custom_values = []
+          custom_field_values.each do |custom_field_value|
+            if custom_field_value.value.is_a?(Array)
+              custom_field_value.value.each do |v|
+                target = custom_values.detect {|cv| cv.custom_field == custom_field_value.custom_field && cv.value == v}
+                target ||= custom_values.build(:customized => self, :custom_field => custom_field_value.custom_field, :value => v)
+                target_custom_values << target
+              end
+            else
+              target = custom_values.detect {|cv| cv.custom_field == custom_field_value.custom_field}
+              target ||= custom_values.build(:customized => self, :custom_field => custom_field_value.custom_field)
+              target.value = custom_field_value.value
+              target_custom_values << target
+            end
+          end
+          self.custom_values = target_custom_values
+          custom_values.each(&:save)
+          @custom_field_values_changed = false
+          true
+        end
+
+        def reset_custom_values!
+          @custom_field_values = nil
+          @custom_field_values_changed = true
+        end
+
+        def reload_with_custom_fields(*args)
+          @custom_field_values = nil
+          @custom_field_values_changed = false
+          reload_without_custom_fields(*args)
+        end
+
+        module ClassMethods
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/95/95576475379988cb708306b5306f5542cfdb7f66.svn-base
--- a/.svn/pristine/95/95576475379988cb708306b5306f5542cfdb7f66.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-class AppAndPluginModel < ActiveRecord::Base
-  def self.report_location; TestHelper::report_location(__FILE__); end
-
-  def defined_only_in_alpha_plugin_version
-    # should not be defined as the model in app/models takes precedence
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/95/957a35283c86613cfdffafbc41af0c7fb0f88eb4.svn-base
--- a/.svn/pristine/95/957a35283c86613cfdffafbc41af0c7fb0f88eb4.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-class Developer < ActiveRecord::Base
-  has_and_belongs_to_many :projects
-end
-
-class DeVeLoPeR < ActiveRecord::Base
-  set_table_name "developers"
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/95/95b614690d7d185bcf90aab8549c761a73f9e992.svn-base
--- a/.svn/pristine/95/95b614690d7d185bcf90aab8549c761a73f9e992.svn-base
+++ /dev/null
@@ -1,154 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'versions_controller'
-
-# Re-raise errors caught by the controller.
-class VersionsController; def rescue_action(e) raise e end; end
-
-class VersionsControllerTest < ActionController::TestCase
-  fixtures :projects, :versions, :issues, :users, :roles, :members, :member_roles, :enabled_modules, :issue_statuses
-
-  def setup
-    @controller = VersionsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_index
-    get :index, :project_id => 1
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:versions)
-    # Version with no date set appears
-    assert assigns(:versions).include?(Version.find(3))
-    # Completed version doesn't appear
-    assert !assigns(:versions).include?(Version.find(1))
-    # Context menu on issues
-    assert_select "script", :text => Regexp.new(Regexp.escape("new ContextMenu('/issues/context_menu')"))
-  end
-
-  def test_index_with_completed_versions
-    get :index, :project_id => 1, :completed => 1
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:versions)
-    # Version with no date set appears
-    assert assigns(:versions).include?(Version.find(3))
-    # Completed version appears
-    assert assigns(:versions).include?(Version.find(1))
-  end
-
-  def test_index_showing_subprojects_versions
-    @subproject_version = Version.generate!(:project => Project.find(3))
-    get :index, :project_id => 1, :with_subprojects => 1
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:versions)
-
-    assert assigns(:versions).include?(Version.find(4)), "Shared version not found"
-    assert assigns(:versions).include?(@subproject_version), "Subproject version not found"
-  end
-
-  def test_show
-    get :show, :id => 2
-    assert_response :success
-    assert_template 'show'
-    assert_not_nil assigns(:version)
-
-    assert_tag :tag => 'h2', :content => /1.0/
-  end
-
-  def test_create
-    @request.session[:user_id] = 2 # manager
-    assert_difference 'Version.count' do
-      post :create, :project_id => '1', :version => {:name => 'test_add_version'}
-    end
-    assert_redirected_to '/projects/ecookbook/settings/versions'
-    version = Version.find_by_name('test_add_version')
-    assert_not_nil version
-    assert_equal 1, version.project_id
-  end
-
-  def test_create_from_issue_form
-    @request.session[:user_id] = 2 # manager
-    assert_difference 'Version.count' do
-      xhr :post, :create, :project_id => '1', :version => {:name => 'test_add_version_from_issue_form'}
-    end
-    assert_response :success
-    assert_select_rjs :replace, 'issue_fixed_version_id'
-    version = Version.find_by_name('test_add_version_from_issue_form')
-    assert_not_nil version
-    assert_equal 1, version.project_id
-  end
-
-  def test_get_edit
-    @request.session[:user_id] = 2
-    get :edit, :id => 2
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_close_completed
-    Version.update_all("status = 'open'")
-    @request.session[:user_id] = 2
-    put :close_completed, :project_id => 'ecookbook'
-    assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
-    assert_not_nil Version.find_by_status('closed')
-  end
-
-  def test_post_update
-    @request.session[:user_id] = 2
-    put :update, :id => 2,
-                :version => { :name => 'New version name',
-                              :effective_date => Date.today.strftime("%Y-%m-%d")}
-    assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
-    version = Version.find(2)
-    assert_equal 'New version name', version.name
-    assert_equal Date.today, version.effective_date
-  end
-
-  def test_post_update_with_validation_failure
-    @request.session[:user_id] = 2
-    put :update, :id => 2,
-                 :version => { :name => '',
-                               :effective_date => Date.today.strftime("%Y-%m-%d")}
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_destroy
-    @request.session[:user_id] = 2
-    delete :destroy, :id => 3
-    assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
-    assert_nil Version.find_by_id(3)
-  end
-
-  def test_issue_status_by
-    xhr :get, :status_by, :id => 2
-    assert_response :success
-    assert_template '_issue_counts'
-  end
-
-  def test_issue_status_by_status
-    xhr :get, :status_by, :id => 2, :status_by => 'status'
-    assert_response :success
-    assert_template '_issue_counts'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/95/95e5fe4878d8a6d94689580f3933c62eb34e4ceb.svn-base
--- a/.svn/pristine/95/95e5fe4878d8a6d94689580f3933c62eb34e4ceb.svn-base
+++ /dev/null
@@ -1,1016 +0,0 @@
-# Indonesian translations 
-# by Raden Prabowo (cakbowo@gmail.com)
-
-id:
-  direction: ltr
-  date:
-    formats:
-      default: "%d-%m-%Y"
-      short: "%d %b"
-      long: "%d %B %Y"
-      
-    day_names: [Minggu, Senin, Selasa, Rabu, Kamis, Jumat, Sabtu]
-    abbr_day_names: [Ming, Sen, Sel, Rab, Kam, Jum, Sab]
-      
-    month_names: [~, Januari, Februari, Maret, April, Mei, Juni, Juli, Agustus, September, Oktober, November, Desember]
-    abbr_month_names: [~, Jan, Feb, Mar, Apr, Mei, Jun, Jul, Agu, Sep, Okt, Nov, Des]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%a %d %b %Y, %H:%M:%S"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%d %B %Y %H:%M"
-    am: "am"
-    pm: "pm"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "setengah menit"
-      less_than_x_seconds:
-        one:   "kurang dari sedetik"
-        other: "kurang dari %{count} detik"
-      x_seconds:
-        one:   "sedetik"
-        other: "%{count} detik"
-      less_than_x_minutes:
-        one:   "kurang dari semenit"
-        other: "kurang dari %{count} menit"
-      x_minutes:
-        one:   "semenit"
-        other: "%{count} menit"
-      about_x_hours:
-        one:   "sekitar sejam"
-        other: "sekitar %{count} jam"
-      x_days:
-        one:   "sehari"
-        other: "%{count} hari"
-      about_x_months:
-        one:   "sekitar sebulan"
-        other: "sekitar %{count} bulan"
-      x_months:
-        one:   "sebulan"
-        other: "%{count} bulan"
-      about_x_years:
-        one:   "sekitar setahun"
-        other: "sekitar %{count} tahun"
-      over_x_years:
-        one:   "lebih dari setahun"
-        other: "lebih dari %{count} tahun"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  number:
-    format:
-      precision: 3
-      separator: ','
-      delimiter: '.'
-    currency:
-      format:
-        unit: 'Rp'
-        precision: 2
-        format: '%n %u'
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-        
-  support:
-    array:
-      sentence_connector: "dan"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "tidak termasuk dalam daftar"
-        exclusion: "sudah dicadangkan"
-        invalid: "salah"
-        confirmation: "tidak sesuai konfirmasi"
-        accepted: "harus disetujui"
-        empty: "tidak boleh kosong"
-        blank: "tidak boleh kosong"
-        too_long: "terlalu panjang (maksimum %{count} karakter)"
-        too_short: "terlalu pendek (minimum %{count} karakter)"
-        wrong_length: "panjangnya salah (seharusnya %{count} karakter)"
-        taken: "sudah diambil"
-        not_a_number: "bukan angka"
-        not_a_date: "bukan tanggal"
-        greater_than: "harus lebih besar dari %{count}"
-        greater_than_or_equal_to: "harus lebih besar atau sama dengan %{count}"
-        equal_to: "harus sama dengan %{count}"
-        less_than: "harus kurang dari %{count}"
-        less_than_or_equal_to: "harus kurang atau sama dengan %{count}"
-        odd: "harus ganjil"
-        even: "harus genap"
-        greater_than_start_date: "harus lebih besar dari tanggal mulai"
-        not_same_project: "tidak tergabung dalam proyek yang sama"
-        circular_dependency: "kaitan ini akan menghasilkan circular dependency"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: Silakan pilih
-  
-  general_text_No: 'Tidak'
-  general_text_Yes: 'Ya'
-  general_text_no: 'tidak'
-  general_text_yes: 'ya'
-  general_lang_name: 'Indonesia'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '7'
-  
-  notice_account_updated: Akun sudah berhasil diperbarui.
-  notice_account_invalid_creditentials: Pengguna atau kata sandi salah
-  notice_account_password_updated: Kata sandi sudah berhasil diperbarui.
-  notice_account_wrong_password: Kata sandi salah.
-  notice_account_register_done: Akun sudah berhasil dibuat. Untuk mengaktifkan akun anda, silakan klik tautan (link) yang dikirim kepada anda melalui e-mail.
-  notice_account_unknown_email: Pengguna tidak dikenal.
-  notice_can_t_change_password: Akun ini menggunakan sumber otentikasi eksternal yang tidak dikenal. Kata sandi tidak bisa diubah.
-  notice_account_lost_email_sent: Email berisi instruksi untuk memilih kata sandi baru sudah dikirimkan kepada anda.
-  notice_account_activated: Akun anda sudah diaktifasi. Sekarang anda bisa login.
-  notice_successful_create: Berhasil dibuat.
-  notice_successful_update: Berhasil diperbarui.
-  notice_successful_delete: Berhasil dihapus.
-  notice_successful_connection: Berhasil terhubung.
-  notice_file_not_found: Berkas yang anda buka tidak ada atau sudah dihapus.
-  notice_locking_conflict: Data sudah diubah oleh pengguna lain.
-  notice_not_authorized: Anda tidak memiliki akses ke halaman ini.
-  notice_email_sent: "Email sudah dikirim ke %{value}"
-  notice_email_error: "Terjadi kesalahan pada saat pengiriman email (%{value})"
-  notice_feeds_access_key_reseted: RSS access key anda sudah direset.
-  notice_failed_to_save_issues: "Gagal menyimpan %{count} masalah dari %{total} yang dipilih: %{ids}."
-  notice_no_issue_selected: "Tidak ada masalah yang dipilih! Silakan pilih masalah yang akan anda sunting."
-  notice_account_pending: "Akun anda sudah dibuat dan sekarang sedang menunggu persetujuan administrator."
-  notice_default_data_loaded: Konfigurasi default sudah berhasil dimuat.
-  notice_unable_delete_version: Tidak bisa menghapus versi.
-  
-  error_can_t_load_default_data: "Konfigurasi default tidak bisa dimuat: %{value}"
-  error_scm_not_found: "Entri atau revisi tidak terdapat pada repositori."
-  error_scm_command_failed: "Terjadi kesalahan pada saat mengakses repositori: %{value}"
-  error_scm_annotate: "Entri tidak ada, atau tidak dapat di anotasi."
-  error_issue_not_found_in_project: 'Masalah tidak ada atau tidak tergabung dalam proyek ini.'
-  error_no_tracker_in_project: 'Tidak ada pelacak yang diasosiasikan pada proyek ini. Silakan pilih Pengaturan Proyek.'
-  error_no_default_issue_status: 'Nilai default untuk Status masalah belum didefinisikan. Periksa kembali konfigurasi anda (Pilih "Administrasi --> Status masalah").'
-  error_can_not_reopen_issue_on_closed_version: 'Masalah yang ditujukan pada versi tertutup tidak bisa dibuka kembali'
-  error_can_not_archive_project: Proyek ini tidak bisa diarsipkan
-  
-  warning_attachments_not_saved: "%{count} berkas tidak bisa disimpan."
-  
-  mail_subject_lost_password: "Kata sandi %{value} anda"
-  mail_body_lost_password: 'Untuk mengubah kata sandi anda, klik tautan berikut::'
-  mail_subject_register: "Aktivasi akun %{value} anda"
-  mail_body_register: 'Untuk mengaktifkan akun anda, klik tautan berikut:'
-  mail_body_account_information_external: "Anda dapat menggunakan akun %{value} anda untuk login."
-  mail_body_account_information: Informasi akun anda
-  mail_subject_account_activation_request: "Permintaan aktivasi akun %{value} "
-  mail_body_account_activation_request: "Pengguna baru (%{value}) sudan didaftarkan. Akun tersebut menunggu persetujuan anda:"
-  mail_subject_reminder: "%{count} masalah harus selesai pada hari berikutnya (%{days})"
-  mail_body_reminder: "%{count} masalah yang ditugaskan pada anda harus selesai dalam %{days} hari kedepan:"
-  mail_subject_wiki_content_added: "'%{id}' halaman wiki sudah ditambahkan"
-  mail_body_wiki_content_added: "The '%{id}' halaman wiki sudah ditambahkan oleh %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' halaman wiki sudah diperbarui"
-  mail_body_wiki_content_updated: "The '%{id}' halaman wiki sudah diperbarui oleh %{author}."
-  
-  gui_validation_error: 1 kesalahan
-  gui_validation_error_plural: "%{count} kesalahan"
-
-  
-  field_name: Nama
-  field_description: Deskripsi
-  field_summary: Ringkasan
-  field_is_required: Dibutuhkan
-  field_firstname: Nama depan
-  field_lastname: Nama belakang
-  field_mail: Email
-  field_filename: Berkas
-  field_filesize: Ukuran
-  field_downloads: Unduhan
-  field_author: Pengarang
-  field_created_on: Dibuat
-  field_updated_on: Diperbarui
-  field_field_format: Format
-  field_is_for_all: Untuk semua proyek
-  field_possible_values: Nilai yang mungkin
-  field_regexp: Regular expression
-  field_min_length: Panjang minimum 
-  field_max_length: Panjang maksimum
-  field_value: Nilai
-  field_category: Kategori
-  field_title: Judul
-  field_project: Proyek
-  field_issue: Masalah
-  field_status: Status
-  field_notes: Catatan
-  field_is_closed: Masalah ditutup
-  field_is_default: Nilai default
-  field_tracker: Pelacak
-  field_subject: Perihal
-  field_due_date: Harus selesai
-  field_assigned_to: Ditugaskan ke
-  field_priority: Prioritas
-  field_fixed_version: Versi target
-  field_user: Pengguna
-  field_role: Peran
-  field_homepage: Halaman web
-  field_is_public: Publik
-  field_parent: Subproyek dari
-  field_is_in_chlog: Masalah ditampilkan di log perubahan
-  field_is_in_roadmap: Masalah ditampilkan di rencana kerja
-  field_login: Login
-  field_mail_notification: Notifikasi email
-  field_admin: Administrator
-  field_last_login_on: Terakhir login
-  field_language: Bahasa
-  field_effective_date: Tanggal
-  field_password: Kata sandi
-  field_new_password: Kata sandi baru
-  field_password_confirmation: Konfirmasi
-  field_version: Versi
-  field_type: Tipe
-  field_host: Host
-  field_port: Port
-  field_account: Akun
-  field_base_dn: Base DN
-  field_attr_login: Atribut login
-  field_attr_firstname: Atribut nama depan
-  field_attr_lastname: Atribut nama belakang
-  field_attr_mail: Atribut email
-  field_onthefly: Pembuatan pengguna seketika
-  field_start_date: Mulai
-  field_done_ratio: "% Selesai"
-  field_auth_source: Mode otentikasi
-  field_hide_mail: Sembunyikan email saya
-  field_comments: Komentar
-  field_url: URL
-  field_start_page: Halaman awal
-  field_subproject: Subproyek
-  field_hours: Jam
-  field_activity: Kegiatan
-  field_spent_on: Tanggal
-  field_identifier: Pengenal
-  field_is_filter: Digunakan sebagai penyaring
-  field_issue_to: Masalah terkait
-  field_delay: Tertunday
-  field_assignable: Masalah dapat ditugaskan pada peran ini
-  field_redirect_existing_links: Alihkan tautan yang ada
-  field_estimated_hours: Perkiraan waktu
-  field_column_names: Kolom
-  field_time_zone: Zona waktu
-  field_searchable: Dapat dicari
-  field_default_value: Nilai default
-  field_comments_sorting: Tampilkan komentar
-  field_parent_title: Halaman induk
-  field_editable: Dapat disunting
-  field_watcher: Pemantau
-  field_identity_url: OpenID URL
-  field_content: Isi
-  field_group_by: Dikelompokkan berdasar 
-  field_sharing: Berbagi
-  
-  setting_app_title: Judul aplikasi
-  setting_app_subtitle: Subjudul aplikasi
-  setting_welcome_text: Teks sambutan
-  setting_default_language: Bahasa Default
-  setting_login_required: Butuhkan otentikasi
-  setting_self_registration: Swa-pendaftaran
-  setting_attachment_max_size: Ukuran maksimum untuk lampiran
-  setting_issues_export_limit: Batasan ukuran export masalah
-  setting_mail_from: Emisi alamat email
-  setting_bcc_recipients: Blind carbon copy recipients (bcc)
-  setting_plain_text_mail: Plain text mail (no HTML)
-  setting_host_name: Nama host dan path
-  setting_text_formatting: Format teks
-  setting_wiki_compression: Kompresi untuk riwayat wiki
-  setting_feeds_limit: Batasan isi feed
-  setting_default_projects_public: Proyek baru defaultnya adalah publik
-  setting_autofetch_changesets: Autofetch commits
-  setting_sys_api_enabled: Aktifkan WS untuk pengaturan repositori
-  setting_commit_ref_keywords: Referensi kaca kunci
-  setting_commit_fix_keywords: Pembetulan kaca kunci
-  setting_autologin: Autologin
-  setting_date_format: Format tanggal
-  setting_time_format: Format waktu
-  setting_cross_project_issue_relations: Perbolehkan kaitan masalah proyek berbeda
-  setting_issue_list_default_columns: Kolom default ditampilkan di daftar masalah
-  setting_emails_footer: Footer untuk email
-  setting_protocol: Protokol
-  setting_per_page_options: Pilihan obyek per halaman
-  setting_user_format: Format tampilan untuk pengguna
-  setting_activity_days_default: Hari tertampil pada kegiatan proyek
-  setting_display_subprojects_issues: Secara default, tampilkan masalah subproyek pada proyek utama
-  setting_enabled_scm: Enabled SCM
-  setting_mail_handler_api_enabled: Enable WS for incoming emails
-  setting_mail_handler_api_key: API key
-  setting_sequential_project_identifiers: Buat pengenal proyek terurut
-  setting_gravatar_enabled: Gunakan icon pengguna dari Gravatar 
-  setting_gravatar_default: Gambar default untuk Gravatar 
-  setting_diff_max_lines_displayed: Maksimum perbedaan baris tertampil
-  setting_file_max_size_displayed: Maksimum berkas tertampil secara inline
-  setting_repository_log_display_limit: Nilai maksimum dari revisi ditampilkan di log berkas
-  setting_openid: Perbolehkan Login dan pendaftaran melalui OpenID
-  setting_password_min_length: Panjang minimum untuk kata sandi
-  setting_new_project_user_role_id: Peran diberikan pada pengguna non-admin yang membuat proyek
-  setting_default_projects_modules: Modul yang diaktifkan pada proyek baru
-  
-  permission_add_project: Tambahkan proyek
-  permission_edit_project: Sunting proyek
-  permission_select_project_modules: Pilih modul proyek
-  permission_manage_members: Atur anggota
-  permission_manage_versions: Atur versi
-  permission_manage_categories: Atur kategori masalah
-  permission_add_issues: Tambahkan masalah
-  permission_edit_issues: Sunting masalah
-  permission_manage_issue_relations: Atur kaitan masalah
-  permission_add_issue_notes: Tambahkan catatan
-  permission_edit_issue_notes: Sunting catatan
-  permission_edit_own_issue_notes: Sunting catatan saya
-  permission_move_issues: Pindahkan masalah
-  permission_delete_issues: Hapus masalah
-  permission_manage_public_queries: Atur query publik
-  permission_save_queries: Simpan query
-  permission_view_gantt: Tampilkan gantt chart
-  permission_view_calendar: Tampilkan kalender
-  permission_view_issue_watchers: Tampilkan daftar pemantau
-  permission_add_issue_watchers: Tambahkan pemantau
-  permission_delete_issue_watchers: Hapus pemantau
-  permission_log_time: Log waktu terpakai
-  permission_view_time_entries: Tampilkan waktu terpakai
-  permission_edit_time_entries: Sunting catatan waktu
-  permission_edit_own_time_entries: Sunting catatan waktu saya
-  permission_manage_news: Atur berita
-  permission_comment_news: Komentari berita
-  permission_manage_documents: Atur dokumen
-  permission_view_documents: Tampilkan dokumen
-  permission_manage_files: Atur berkas
-  permission_view_files: Tampilkan berkas
-  permission_manage_wiki: Atur wiki
-  permission_rename_wiki_pages: Ganti nama halaman wiki
-  permission_delete_wiki_pages: Hapus halaman wiki
-  permission_view_wiki_pages: Tampilkan wiki
-  permission_view_wiki_edits: Tampilkan riwayat wiki
-  permission_edit_wiki_pages: Sunting halaman wiki
-  permission_delete_wiki_pages_attachments: Hapus lampiran
-  permission_protect_wiki_pages: Proteksi halaman wiki
-  permission_manage_repository: Atur repositori
-  permission_browse_repository: Jelajah repositori
-  permission_view_changesets: Tampilkan set perubahan
-  permission_commit_access: Commit akses
-  permission_manage_boards: Atur forum
-  permission_view_messages: Tampilkan pesan
-  permission_add_messages: Tambahkan pesan
-  permission_edit_messages: Sunting pesan
-  permission_edit_own_messages: Sunting pesan saya
-  permission_delete_messages: Hapus pesan
-  permission_delete_own_messages: Hapus pesan saya
-  
-  project_module_issue_tracking: Pelacak masalah
-  project_module_time_tracking: Pelacak waktu
-  project_module_news: Berita
-  project_module_documents: Dokumen
-  project_module_files: Berkas
-  project_module_wiki: Wiki
-  project_module_repository: Repositori
-  project_module_boards: Forum
-  
-  label_user: Pengguna
-  label_user_plural: Pengguna
-  label_user_new: Pengguna baru
-  label_user_anonymous: Anonymous
-  label_project: Proyek
-  label_project_new: Proyek baru
-  label_project_plural: Proyek 
-  label_x_projects:
-    zero:  tidak ada proyek 
-    one:   1 proyek 
-    other: "%{count} proyek"
-  label_project_all: Semua Proyek 
-  label_project_latest: Proyek terakhir
-  label_issue: Masalah
-  label_issue_new: Masalah baru
-  label_issue_plural: Masalah
-  label_issue_view_all: tampilkan semua masalah
-  label_issues_by: "Masalah ditambahkan oleh %{value}"
-  label_issue_added: Masalah ditambahan
-  label_issue_updated: Masalah diperbarui
-  label_document: Dokumen
-  label_document_new: Dokumen baru
-  label_document_plural: Dokumen
-  label_document_added: Dokumen ditambahkan
-  label_role: Peran
-  label_role_plural: Peran
-  label_role_new: Peran baru
-  label_role_and_permissions: Peran dan perijinan
-  label_member: Anggota
-  label_member_new: Anggota baru
-  label_member_plural: Anggota
-  label_tracker: Pelacak
-  label_tracker_plural: Pelacak
-  label_tracker_new: Pelacak baru
-  label_workflow: Alur kerja
-  label_issue_status: Status masalah
-  label_issue_status_plural: Status masalah
-  label_issue_status_new: Status baru
-  label_issue_category: Kategori masalah
-  label_issue_category_plural: Kategori masalah
-  label_issue_category_new: Kategori baru
-  label_custom_field: Field kustom
-  label_custom_field_plural: Field kustom
-  label_custom_field_new: Field kustom
-  label_enumerations: Enumerasi
-  label_enumeration_new: Buat baru
-  label_information: Informasi
-  label_information_plural: Informasi
-  label_please_login: Silakan login
-  label_register: mendaftar
-  label_login_with_open_id_option: atau login menggunakan OpenID
-  label_password_lost: Lupa password
-  label_home: Halaman depan
-  label_my_page: Beranda
-  label_my_account: Akun saya
-  label_my_projects: Proyek saya
-  label_administration: Administrasi
-  label_login: Login
-  label_logout: Keluar
-  label_help: Bantuan
-  label_reported_issues: Masalah terlapor
-  label_assigned_to_me_issues: Masalah yang ditugaskan pada saya
-  label_last_login: Terakhir login
-  label_registered_on: Terdaftar pada
-  label_activity: Kegiatan
-  label_overall_activity: Kegiatan umum
-  label_user_activity: "kegiatan %{value}"
-  label_new: Baru
-  label_logged_as: Login sebagai
-  label_environment: Lingkungan
-  label_authentication: Otentikasi
-  label_auth_source: Mode Otentikasi
-  label_auth_source_new: Mode otentikasi baru
-  label_auth_source_plural: Mode Otentikasi
-  label_subproject_plural: Subproyek
-  label_and_its_subprojects: "%{value} dan subproyeknya"
-  label_min_max_length: Panjang Min - Maks
-  label_list: Daftar
-  label_date: Tanggal
-  label_integer: Integer
-  label_float: Float
-  label_boolean: Boolean
-  label_string: Text
-  label_text: Long text
-  label_attribute: Atribut
-  label_attribute_plural: Atribut
-  label_download: "%{count} Unduhan"
-  label_download_plural: "%{count} Unduhan"
-  label_no_data: Tidak ada data untuk ditampilkan
-  label_change_status: Status perubahan
-  label_history: Riwayat
-  label_attachment: Berkas
-  label_attachment_new: Berkas baru
-  label_attachment_delete: Hapus Berkas
-  label_attachment_plural: Berkas
-  label_file_added: Berkas ditambahkan
-  label_report: Laporan
-  label_report_plural: Laporan
-  label_news: Berita
-  label_news_new: Tambahkan berita
-  label_news_plural: Berita
-  label_news_latest: Berita terakhir
-  label_news_view_all: Tampilkan semua berita
-  label_news_added: Berita ditambahkan
-  label_change_log: Log perubahan
-  label_settings: Pengaturan
-  label_overview: Umum
-  label_version: Versi
-  label_version_new: Versi baru
-  label_version_plural: Versi
-  label_confirmation: Konfirmasi
-  label_export_to: 'Juga tersedia dalam:'
-  label_read: Baca...
-  label_public_projects: Proyek publik
-  label_open_issues: belum selesai
-  label_open_issues_plural: belum selesai
-  label_closed_issues: selesai
-  label_closed_issues_plural: selesai
-  label_x_open_issues_abbr_on_total:
-    zero:  0 belum selesai / %{total}
-    one:   1 belum selesai / %{total}
-    other: "%{count} terbuka / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 belum selesai
-    one:   1 belum selesai
-    other: "%{count} belum selesai"
-  label_x_closed_issues_abbr:
-    zero:  0 selesai
-    one:   1 selesai
-    other: "%{count} selesai"
-  label_total: Total
-  label_permissions: Perijinan
-  label_current_status: Status sekarang
-  label_new_statuses_allowed: Status baru yang diijinkan
-  label_all: semua
-  label_none: tidak ada
-  label_nobody: tidak ada
-  label_next: Berikut
-  label_previous: Sebelum
-  label_used_by: Digunakan oleh
-  label_details: Rincian
-  label_add_note: Tambahkan catatan
-  label_per_page: Per halaman
-  label_calendar: Kalender
-  label_months_from: dari bulan
-  label_gantt: Gantt
-  label_internal: Internal
-  label_last_changes: "%{count} perubahan terakhir"
-  label_change_view_all: Tampilkan semua perubahan
-  label_personalize_page: Personalkan halaman ini
-  label_comment: Komentar
-  label_comment_plural: Komentar
-  label_x_comments:
-    zero: tak ada komentar
-    one: 1 komentar
-    other: "%{count} komentar"
-  label_comment_add: Tambahkan komentar
-  label_comment_added: Komentar ditambahkan
-  label_comment_delete: Hapus komentar
-  label_query: Custom query
-  label_query_plural: Custom queries
-  label_query_new: Query baru
-  label_filter_add: Tambahkan filter
-  label_filter_plural: Filter
-  label_equals: sama dengan
-  label_not_equals: tidak sama dengan
-  label_in_less_than: kurang dari
-  label_in_more_than: lebih dari
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: pada
-  label_today: hari ini
-  label_all_time: semua waktu
-  label_yesterday: kemarin
-  label_this_week: minggu ini
-  label_last_week: minggu lalu
-  label_last_n_days: "%{count} hari terakhir"
-  label_this_month: bulan ini
-  label_last_month: bulan lalu
-  label_this_year: this year
-  label_date_range: Jangkauan tanggal
-  label_less_than_ago: kurang dari hari yang lalu
-  label_more_than_ago: lebih dari hari yang lalu
-  label_ago: hari yang lalu
-  label_contains: berisi
-  label_not_contains: tidak berisi
-  label_day_plural: hari
-  label_repository: Repositori
-  label_repository_plural: Repositori
-  label_browse: Jelajah
-  label_modification: "%{count} perubahan"
-  label_modification_plural: "%{count} perubahan"
-  label_branch: Cabang
-  label_tag: Tag 
-  label_revision: Revisi
-  label_revision_plural: Revisi
-  label_associated_revisions: Revisi terkait
-  label_added: ditambahkan
-  label_modified: diubah
-  label_copied: disalin
-  label_renamed: diganti nama
-  label_deleted: dihapus
-  label_latest_revision: Revisi terakhir
-  label_latest_revision_plural: Revisi terakhir
-  label_view_revisions: Tampilkan revisi
-  label_view_all_revisions: Tampilkan semua revisi
-  label_max_size: Ukuran maksimum
-  label_sort_highest: Ke paling atas
-  label_sort_higher: Ke atas
-  label_sort_lower: Ke bawah
-  label_sort_lowest: Ke paling bawah
-  label_roadmap: Rencana kerja
-  label_roadmap_due_in: "Harus selesai dalam %{value}"
-  label_roadmap_overdue: "%{value} terlambat"
-  label_roadmap_no_issues: Tak ada masalah pada versi ini
-  label_search: Cari
-  label_result_plural: Hasil
-  label_all_words: Semua kata
-  label_wiki: Wiki
-  label_wiki_edit: Sunting wiki 
-  label_wiki_edit_plural: Sunting wiki 
-  label_wiki_page: Halaman wiki 
-  label_wiki_page_plural: Halaman wiki
-  label_index_by_title: Indeks menurut judul
-  label_index_by_date: Indeks menurut tanggal
-  label_current_version: Versi sekarang
-  label_preview: Tinjauan
-  label_feed_plural: Feeds
-  label_changes_details: Rincian semua perubahan
-  label_issue_tracking: Pelacak masalah
-  label_spent_time: Waktu terpakai
-  label_f_hour: "%{value} jam"
-  label_f_hour_plural: "%{value} jam"
-  label_time_tracking: Pelacak waktu
-  label_change_plural: Perubahan
-  label_statistics: Statistik
-  label_commits_per_month: Komit per bulan
-  label_commits_per_author: Komit per pengarang
-  label_view_diff: Tampilkan perbedaan
-  label_diff_inline: inline
-  label_diff_side_by_side: berdampingan
-  label_options: Pilihan
-  label_copy_workflow_from: Salin alur kerja dari
-  label_permissions_report: Laporan perijinan
-  label_watched_issues: Masalah terpantau
-  label_related_issues: Masalah terkait
-  label_applied_status: Status teraplikasi
-  label_loading: Memuat...
-  label_relation_new: Kaitan baru
-  label_relation_delete: Hapus kaitan
-  label_relates_to: terkait pada
-  label_duplicates: salinan
-  label_duplicated_by: disalin oleh
-  label_blocks: blok
-  label_blocked_by: diblok oleh
-  label_precedes: mendahului
-  label_follows: mengikuti
-  label_end_to_start: akhir ke awal
-  label_end_to_end: akhir ke akhir
-  label_start_to_start: awal ke awal
-  label_start_to_end: awal ke akhir
-  label_stay_logged_in: Tetap login
-  label_disabled: tidak diaktifkan
-  label_show_completed_versions: Tampilkan versi lengkap
-  label_me: saya
-  label_board: Forum
-  label_board_new: Forum baru
-  label_board_plural: Forum
-  label_topic_plural: Topik
-  label_message_plural: Pesan
-  label_message_last: Pesan terakhir
-  label_message_new: Pesan baru
-  label_message_posted: Pesan ditambahkan
-  label_reply_plural: Balasan
-  label_send_information: Kirim informasi akun ke pengguna
-  label_year: Tahun
-  label_month: Bulan
-  label_week: Minggu
-  label_date_from: Dari
-  label_date_to: Sampai
-  label_language_based: Berdasarkan bahasa pengguna
-  label_sort_by: "Urut berdasarkan %{value}"
-  label_send_test_email: Kirim email percobaan
-  label_feeds_access_key_created_on: "RSS access key dibuat %{value} yang lalu"
-  label_module_plural: Modul
-  label_added_time_by: "Ditambahkan oleh %{author} %{age} yang lalu"
-  label_updated_time_by: "Diperbarui oleh %{author} %{age} yang lalu"
-  label_updated_time: "Diperbarui oleh %{value} yang lalu"
-  label_jump_to_a_project: Pilih proyek...
-  label_file_plural: Berkas
-  label_changeset_plural: Set perubahan
-  label_default_columns: Kolom default 
-  label_no_change_option: (Tak ada perubahan)
-  label_bulk_edit_selected_issues: Ubah masalah terpilih secara masal
-  label_theme: Tema
-  label_default: Default
-  label_search_titles_only: Cari judul saja
-  label_user_mail_option_all: "Untuk semua kejadian pada semua proyek saya"
-  label_user_mail_option_selected: "Hanya untuk semua kejadian pada proyek yang saya pilih ..."
-  label_user_mail_no_self_notified: "Saya tak ingin diberitahu untuk perubahan yang saya buat sendiri"
-  label_user_mail_assigned_only_mail_notification: "Kirim email hanya bila saya ditugaskan untuk masalah terkait"
-  label_user_mail_block_mail_notification: "Saya tidak ingin menerima email. Terima kasih."  
-  label_registration_activation_by_email: aktivasi akun melalui email
-  label_registration_manual_activation: aktivasi akun secara manual
-  label_registration_automatic_activation: aktivasi akun secara otomatis
-  label_display_per_page: "Per halaman: %{value}"
-  label_age: Umur
-  label_change_properties: Rincian perubahan
-  label_general: Umum
-  label_more: Lanjut
-  label_scm: SCM
-  label_plugins: Plugin
-  label_ldap_authentication: Otentikasi LDAP
-  label_downloads_abbr: Unduh
-  label_optional_description: Deskripsi optional
-  label_add_another_file: Tambahkan berkas lain
-  label_preferences: Preferensi
-  label_chronological_order: Urut sesuai kronologis
-  label_reverse_chronological_order: Urut dari yang terbaru
-  label_planning: Perencanaan
-  label_incoming_emails: Email masuk
-  label_generate_key: Buat kunci
-  label_issue_watchers: Pemantau
-  label_example: Contoh
-  label_display: Tampilan
-  label_sort: Urut
-  label_ascending: Menaik
-  label_descending: Menurun
-  label_date_from_to: Dari %{start} sampai %{end}
-  label_wiki_content_added: Halaman wiki ditambahkan
-  label_wiki_content_updated: Halaman wiki diperbarui
-  label_group: Kelompok
-  label_group_plural: Kelompok
-  label_group_new: Kelompok baru
-  label_time_entry_plural: Waktu terpakai
-  label_version_sharing_none: Tidak dibagi
-  label_version_sharing_descendants: Dengan subproyek
-  label_version_sharing_hierarchy: Dengan hirarki proyek
-  label_version_sharing_tree: Dengan pohon proyek
-  label_version_sharing_system: Dengan semua proyek
-
-
-  button_login: Login
-  button_submit: Kirim
-  button_save: Simpan
-  button_check_all: Contreng semua
-  button_uncheck_all: Hilangkan semua contreng
-  button_delete: Hapus
-  button_create: Buat
-  button_create_and_continue: Buat dan lanjutkan
-  button_test: Test
-  button_edit: Sunting
-  button_add: Tambahkan
-  button_change: Ubah
-  button_apply: Terapkan
-  button_clear: Bersihkan
-  button_lock: Kunci
-  button_unlock: Buka kunci
-  button_download: Unduh
-  button_list: Daftar
-  button_view: Tampilkan
-  button_move: Pindah
-  button_move_and_follow: Pindah dan ikuti
-  button_back: Kembali
-  button_cancel: Batal
-  button_activate: Aktifkan
-  button_sort: Urut
-  button_log_time: Rekam waktu
-  button_rollback: Kembali ke versi ini
-  button_watch: Pantau
-  button_unwatch: Tidak Memantau
-  button_reply: Balas
-  button_archive: Arsip
-  button_unarchive: Batalkan arsip
-  button_reset: Reset
-  button_rename: Ganti nama
-  button_change_password: Ubah kata sandi
-  button_copy: Salin
-  button_copy_and_follow: Salin dan ikuti
-  button_annotate: Anotasi
-  button_update: Perbarui
-  button_configure: Konfigur
-  button_quote: Kutip
-  button_duplicate: Duplikat
-  
-  status_active: aktif
-  status_registered: terdaftar
-  status_locked: terkunci
-  
-  version_status_open: terbuka
-  version_status_locked: terkunci
-  version_status_closed: tertutup
-
-  field_active: Aktif
-  
-  text_select_mail_notifications: Pilih aksi dimana email notifikasi akan dikirimkan.
-  text_regexp_info: mis. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 berarti tidak ada pembatasan
-  text_project_destroy_confirmation: Apakah anda benar-benar akan menghapus proyek ini beserta data terkait ?
-  text_subprojects_destroy_warning: "Subproyek: %{value} juga akan dihapus."
-  text_workflow_edit: Pilih peran dan pelacak untuk menyunting alur kerja
-  text_are_you_sure: Anda yakin ?
-  text_journal_changed: "%{label} berubah dari %{old} menjadi %{new}"
-  text_journal_set_to: "%{label} di set ke %{value}"
-  text_journal_deleted: "%{label} dihapus (%{old})"
-  text_journal_added: "%{label} %{value} ditambahkan"
-  text_tip_issue_begin_day: tugas dimulai hari itu
-  text_tip_issue_end_day: tugas berakhir hari itu
-  text_tip_issue_begin_end_day: tugas dimulai dan berakhir hari itu
-  text_project_identifier_info: 'Yang diijinkan hanya huruf kecil (a-z), angka dan tanda minus.<br />Sekali disimpan, pengenal tidak bisa diubah.'
-  text_caracters_maximum: "maximum %{count} karakter."
-  text_caracters_minimum: "Setidaknya harus sepanjang %{count} karakter."
-  text_length_between: "Panjang diantara %{min} dan %{max} karakter."
-  text_tracker_no_workflow: Tidak ada alur kerja untuk pelacak ini
-  text_unallowed_characters: Karakter tidak diperbolehkan
-  text_comma_separated: Beberapa nilai diperbolehkan (dipisahkan koma).
-  text_issues_ref_in_commit_messages: Mereferensikan dan membetulkan masalah pada pesan komit
-  text_issue_added: "Masalah %{id} sudah dilaporkan oleh %{author}."
-  text_issue_updated: "Masalah %{id} sudah diperbarui oleh %{author}."
-  text_wiki_destroy_confirmation: Apakah anda benar-benar akan menghapus wiki ini beserta semua isinya ?
-  text_issue_category_destroy_question: "Beberapa masalah (%{count}) ditugaskan pada kategori ini. Apa yang anda lakukan ?"
-  text_issue_category_destroy_assignments: Hapus kategori penugasan
-  text_issue_category_reassign_to: Tugaskan kembali masalah untuk kategori ini
-  text_user_mail_option: "Untuk proyek yang tidak dipilih, anda hanya akan menerima notifikasi hal-hal yang anda pantau atau anda terlibat di dalamnya (misalnya masalah yang anda tulis atau ditugaskan pada anda)."
-  text_no_configuration_data: "Peran, pelacak, status masalah dan alur kerja belum dikonfigur.\nSangat disarankan untuk memuat konfigurasi default. Anda akan bisa mengubahnya setelah konfigurasi dimuat."
-  text_load_default_configuration: Muat konfigurasi default
-  text_status_changed_by_changeset: "Diterapkan di set perubahan %{value}."
-  text_issues_destroy_confirmation: 'Apakah anda yakin untuk menghapus masalah terpilih ?'
-  text_select_project_modules: 'Pilih modul untuk diaktifkan pada proyek ini:'
-  text_default_administrator_account_changed: Akun administrator default sudah berubah
-  text_file_repository_writable: Direktori yang bisa ditulisi untuk lampiran
-  text_plugin_assets_writable: Direktori yang bisa ditulisi untuk plugin asset
-  text_rmagick_available: RMagick tersedia (optional)
-  text_destroy_time_entries_question: "%{hours} jam sudah dilaporkan pada masalah yang akan anda hapus. Apa yang akan anda lakukan ?"
-  text_destroy_time_entries: Hapus jam yang terlapor
-  text_assign_time_entries_to_project: Tugaskan jam terlapor pada proyek
-  text_reassign_time_entries: 'Tugaskan kembali jam terlapor pada masalah ini:'
-  text_user_wrote: "%{value} menulis:"
-  text_enumeration_destroy_question: "%{count} obyek ditugaskan untuk nilai ini."
-  text_enumeration_category_reassign_to: 'Tugaskan kembali untuk nilai ini:'
-  text_email_delivery_not_configured: "Pengiriman email belum dikonfigurasi, notifikasi tidak diaktifkan.\nAnda harus mengkonfigur SMTP server anda pada config/configuration.yml dan restart kembali aplikasi untuk mengaktifkan."
-  text_repository_usernames_mapping: "Pilih atau perbarui pengguna Redmine yang terpetakan ke setiap nama pengguna yang ditemukan di log repositori.\nPengguna dengan nama pengguna dan repositori atau email yang sama  secara otomasit akan dipetakan."
-  text_diff_truncated: '... Perbedaan terpotong karena melebihi batas maksimum yang bisa ditampilkan.'
-  text_custom_field_possible_values_info: 'Satu baris untuk setiap nilai'
-  text_wiki_page_destroy_question: "Halaman ini mempunyai %{descendants} halaman anak dan turunannya. Apa yang akan anda lakukan ?"
-  text_wiki_page_nullify_children: "Biarkan halaman anak sebagai halaman teratas (root)"
-  text_wiki_page_destroy_children: "Hapus halaman anak dan semua turunannya"
-  text_wiki_page_reassign_children: "Tujukan halaman anak ke halaman induk yang ini"
-  
-  default_role_manager: Manager
-  default_role_developer: Pengembang
-  default_role_reporter: Pelapor
-  default_tracker_bug: Bug
-  default_tracker_feature: Fitur
-  default_tracker_support: Dukungan
-  default_issue_status_new: Baru
-  default_issue_status_in_progress: Dalam proses
-  default_issue_status_resolved: Resolved
-  default_issue_status_feedback: Umpan balik
-  default_issue_status_closed: Ditutup
-  default_issue_status_rejected: Ditolak
-  default_doc_category_user: Dokumentasi pengguna
-  default_doc_category_tech: Dokumentasi teknis
-  default_priority_low: Rendah
-  default_priority_normal: Normal
-  default_priority_high: Tinggi
-  default_priority_urgent: Penting
-  default_priority_immediate: Segera
-  default_activity_design: Rancangan
-  default_activity_development: Pengembangan
-  
-  enumeration_issue_priorities: Prioritas masalah
-  enumeration_doc_categories: Kategori dokumen
-  enumeration_activities: Kegiatan
-  enumeration_system_activity: Kegiatan Sistem
-  label_copy_source: Source
-  label_update_issue_done_ratios: Update issue done ratios
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  label_api_access_key: API access key
-  text_line_separated: Multiple values allowed (one line for each value).
-  label_revision_id: Revision %{value}
-  permission_view_issues: View Issues
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_copy_same_as_target: Same as target
-  button_show: Show
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_missing_api_access_key: Missing an API access key
-  label_copy_target: Target
-  label_missing_feeds_access_key: Missing a RSS access key
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  error_workflow_copy_source: Please select a source tracker or role
-  setting_start_of_week: Start calendars on
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Commit messages encoding
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/96/963773853bda74793bf9bb1d78dc3aeab16e404f.svn-base
--- a/.svn/pristine/96/963773853bda74793bf9bb1d78dc3aeab16e404f.svn-base
+++ /dev/null
@@ -1,50 +0,0 @@
-autoload :YAML, 'yaml'
-
-module CodeRay
-module Encoders
-  
-  # = YAML Encoder
-  #
-  # Slow.
-  class YAML < Encoder
-    
-    register_for :yaml
-    
-    FILE_EXTENSION = 'yaml'
-    
-  protected
-    def setup options
-      super
-      
-      @data = []
-    end
-    
-    def finish options
-      output ::YAML.dump(@data)
-    end
-    
-  public
-    def text_token text, kind
-      @data << [text, kind]
-    end
-    
-    def begin_group kind
-      @data << [:begin_group, kind]
-    end
-    
-    def end_group kind
-      @data << [:end_group, kind]
-    end
-    
-    def begin_line kind
-      @data << [:begin_line, kind]
-    end
-    
-    def end_line kind
-      @data << [:end_line, kind]
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/96/96404659ec418cc105ea9a468be16d3044c14ca3.svn-base
--- a/.svn/pristine/96/96404659ec418cc105ea9a468be16d3044c14ca3.svn-base
+++ /dev/null
@@ -1,14 +0,0 @@
-<div id="block_<%= block_name.dasherize %>" class="mypage-box">
-
-    <div style="float:right;margin-right:16px;z-index:500;">
-    <%= link_to_remote "", {
-        :url => { :action => "remove_block", :block => block_name },
-        :complete => "removeBlock('block_#{block_name.dasherize}')" },
-        :class => "close-icon"
-         %>
-    </div>
-
-    <div class="handle">
-    <%= render :partial => "my/blocks/#{block_name}", :locals => { :user => user } %>
-    </div>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/96/96fbf269ff62a61582508d4f1cf1cc972ae3970e.svn-base
--- a/.svn/pristine/96/96fbf269ff62a61582508d4f1cf1cc972ae3970e.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-<%= f.error_messages %>
-<div class="box tabular">
-<p><%= f.text_field :title, :required => true, :size => 60 %></p>
-<p><%= f.text_area :summary, :cols => 60, :rows => 2 %></p>
-<p><%= f.text_area :description, :required => true, :cols => 60, :rows => 15, :class => 'wiki-edit' %></p>
-</div>
-
-<%= wikitoolbar_for 'news_description' %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/97/970ec132b01c46c5cc9737caeb7a09d5cec9754a.svn-base
--- /dev/null
+++ b/.svn/pristine/97/970ec132b01c46c5cc9737caeb7a09d5cec9754a.svn-base
@@ -0,0 +1,29 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class JournalObserver < ActiveRecord::Observer
+  def after_create(journal)
+    if journal.notify? &&
+        (Setting.notified_events.include?('issue_updated') ||
+          (Setting.notified_events.include?('issue_note_added') && journal.notes.present?) ||
+          (Setting.notified_events.include?('issue_status_updated') && journal.new_status.present?) ||
+          (Setting.notified_events.include?('issue_priority_updated') && journal.new_value_for('priority_id').present?)
+        )
+      Mailer.issue_edit(journal).deliver
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/97/97126ffed7592bf8645e6694bd3d5dcb0d4c24c2.svn-base
--- a/.svn/pristine/97/97126ffed7592bf8645e6694bd3d5dcb0d4c24c2.svn-base
+++ /dev/null
@@ -1,1005 +0,0 @@
-uk:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y-%m-%d"
-      short: "%b %d"
-      long: "%B %d, %Y"
-
-    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
-    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
-    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%a, %d %b %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "am"
-    pm: "pm"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "half a minute"
-      less_than_x_seconds:
-        one:   "less than 1 second"
-        other: "less than %{count} seconds"
-      x_seconds:
-        one:   "1 second"
-        other: "%{count} seconds"
-      less_than_x_minutes:
-        one:   "less than a minute"
-        other: "less than %{count} minutes"
-      x_minutes:
-        one:   "1 minute"
-        other: "%{count} minutes"
-      about_x_hours:
-        one:   "about 1 hour"
-        other: "about %{count} hours"
-      x_days:
-        one:   "1 day"
-        other: "%{count} days"
-      about_x_months:
-        one:   "about 1 month"
-        other: "about %{count} months"
-      x_months:
-        one:   "1 month"
-        other: "%{count} months"
-      about_x_years:
-        one:   "about 1 year"
-        other: "about %{count} years"
-      over_x_years:
-        one:   "over 1 year"
-        other: "over %{count} years"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        precision: 1
-        delimiter: ""
-      storage_units:
-        format: "%n %u"
-        units:
-          kb: KB
-          tb: TB
-          gb: GB
-          byte:
-            one: Byte
-            other: Bytes
-          mb: MB
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "and"
-      skip_last_comma: false
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "Ð½ÐµÐ¼Ð°Ñ” Ð² ÑÐ¿Ð¸ÑÐºÑƒ"
-        exclusion: "Ð·Ð°Ñ€ÐµÐ·ÐµÑ€Ð²Ð¾Ð²Ð°Ð½Ð¾"
-        invalid: "Ð½ÐµÐ²Ñ–Ñ€Ð½Ðµ"
-        confirmation: "Ð½Ðµ Ð·Ð±Ñ–Ð³Ð°Ñ”Ñ‚ÑŒÑÑ Ð· Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½ÑÐ¼"
-        accepted: "Ð½ÐµÐ¾Ð±Ñ…Ñ–Ð´Ð½Ð¾ Ð¿Ñ€Ð¸Ð¹Ð½ÑÑ‚Ð¸"
-        empty: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±ÑƒÑ‚Ð¸ Ð¿Ð¾Ñ€Ð¾Ð¶Ð½Ñ–Ð¼"
-        blank: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±ÑƒÑ‚Ð¸ Ð½ÐµÐ·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð¸Ð¼"
-        too_long: "Ð´ÑƒÐ¶Ðµ Ð´Ð¾Ð²Ð³Ðµ"
-        too_short: "Ð´ÑƒÐ¶Ðµ ÐºÐ¾Ñ€Ð¾Ñ‚ÐºÐµ"
-        wrong_length: "Ð½Ðµ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð°Ñ” Ð´Ð¾Ð²Ð¶Ð¸Ð½Ñ–"
-        taken: "Ð²Ð¶Ðµ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÑ”Ñ‚ÑŒÑÑ"
-        not_a_number: "Ð½Ðµ Ñ” Ñ‡Ð¸ÑÐ»Ð¾Ð¼"
-        not_a_date: "Ñ” Ð½ÐµÐ´Ñ–Ð¹ÑÐ½Ð¾ÑŽ Ð´Ð°Ñ‚Ð¾ÑŽ"
-        greater_than: "must be greater than %{count}"
-        greater_than_or_equal_to: "must be greater than or equal to %{count}"
-        equal_to: "must be equal to %{count}"
-        less_than: "must be less than %{count}"
-        less_than_or_equal_to: "must be less than or equal to %{count}"
-        odd: "must be odd"
-        even: "must be even"
-        greater_than_start_date: "Ð¿Ð¾Ð²Ð¸Ð½Ð½Ð° Ð±ÑƒÑ‚Ð¸ Ð¿Ñ–Ð·Ð½Ñ–ÑˆÐ° Ð·Ð° Ð´Ð°Ñ‚Ñƒ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ"
-        not_same_project: "Ð½Ðµ Ð²Ñ–Ð´Ð½Ð¾ÑÑÑ‚ÑŒÑÑ Ð´Ð¾ Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ"
-        circular_dependency: "Ð¢Ð°ÐºÐ¸Ð¹ Ð·Ð²'ÑÐ·Ð¾Ðº Ð¿Ñ€Ð¸Ð²ÐµÐ´Ðµ Ð´Ð¾ Ñ†Ð¸ÐºÐ»Ñ–Ñ‡Ð½Ð¾Ñ— Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾ÑÑ‚Ñ–"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: ÐžÐ±ÐµÑ€Ñ–Ñ‚ÑŒ
-
-  general_text_No: 'ÐÑ–'
-  general_text_Yes: 'Ð¢Ð°Ðº'
-  general_text_no: 'ÐÑ–'
-  general_text_yes: 'Ð¢Ð°Ðº'
-  general_lang_name: 'Ukrainian (Ð£ÐºÑ€Ð°Ñ—Ð½ÑÑŒÐºÐ°)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: ÐžÐ±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¹.
-  notice_account_invalid_creditentials: ÐÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ðµ Ñ–Ð¼'Ñ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð° Ð°Ð±Ð¾ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
-  notice_account_password_updated: ÐŸÐ°Ñ€Ð¾Ð»ÑŒ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¹.
-  notice_account_wrong_password: ÐÐµÐ²Ñ–Ñ€Ð½Ð¸Ð¹ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
-  notice_account_register_done: ÐžÐ±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ð¹. Ð”Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— Ð’Ð°ÑˆÐ¾Ð³Ð¾ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ Ð·Ð°Ð¹Ð´Ñ–Ñ‚ÑŒ Ð¿Ð¾ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½ÑŽ, ÑÐºÐµ Ð²Ñ–Ð´Ñ–ÑÐ»Ð°Ð½Ðµ Ð²Ð°Ð¼ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ Ð¿Ð¾ÑˆÑ‚Ð¾ÑŽ.
-  notice_account_unknown_email: ÐÐµÐ²Ñ–Ð´Ð¾Ð¼Ð¸Ð¹ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡.
-  notice_can_t_change_password: Ð”Ð»Ñ Ð´Ð°Ð½Ð¾Ð³Ð¾ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÑ”Ñ‚ÑŒÑÑ Ð´Ð¶ÐµÑ€ÐµÐ»Ð¾ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ñ— Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—. ÐÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ.
-  notice_account_lost_email_sent: Ð’Ð°Ð¼ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ð¹ Ð»Ð¸ÑÑ‚ Ð· Ñ–Ð½ÑÑ‚Ñ€ÑƒÐºÑ†Ñ–ÑÐ¼Ð¸ Ð¿Ð¾ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ð¿Ð°Ñ€Ð¾Ð»Ñ.
-  notice_account_activated: Ð’Ð°Ñˆ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ Ð°ÐºÑ‚Ð¸Ð²Ð¾Ð²Ð°Ð½Ð¸Ð¹. Ð’Ð¸ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ ÑƒÐ²Ñ–Ð¹Ñ‚Ð¸.
-  notice_successful_create: Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ðµ.
-  notice_successful_update: ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ðµ.
-  notice_successful_delete: Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ðµ.
-  notice_successful_connection: ÐŸÑ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ðµ.
-  notice_file_not_found: Ð¡Ñ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°, Ð½Ð° ÑÐºÑƒ Ð²Ð¸ Ð½Ð°Ð¼Ð°Ð³Ð°Ñ”Ñ‚ÐµÑÑ Ð·Ð°Ð¹Ñ‚Ð¸, Ð½Ðµ Ñ–ÑÐ½ÑƒÑ” Ð°Ð±Ð¾ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð°.
-  notice_locking_conflict: Ð”Ð°Ð½Ñ– Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾ Ñ–Ð½ÑˆÐ¸Ð¼ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡ÐµÐ¼.
-  notice_scm_error: Ð—Ð°Ð¿Ð¸ÑÑƒ Ñ‚Ð°/Ð°Ð±Ð¾ Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð½ÐµÐ¼Ð°Ñ” Ð² Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ—.
-  notice_not_authorized: Ð£ Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” Ð¿Ñ€Ð°Ð² Ð´Ð»Ñ Ð²Ñ–Ð´Ð²Ñ–Ð´Ð¸Ð½Ð¸ Ð´Ð°Ð½Ð¾Ñ— ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ¸.
-  notice_email_sent: "Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¾ Ð»Ð¸ÑÑ‚Ð° %{value}"
-  notice_email_error: "ÐŸÑ–Ð´ Ñ‡Ð°Ñ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²ÐºÐ¸ Ð»Ð¸ÑÑ‚Ð° Ð²Ñ–Ð´Ð±ÑƒÐ»Ð°ÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° (%{value})"
-  notice_feeds_access_key_reseted: Ð’Ð°Ñˆ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ RSS Ð±ÑƒÐ»Ð¾ ÑÐºÐ¸Ð½ÑƒÑ‚Ð¾.
-  notice_failed_to_save_issues: "ÐÐµ Ð²Ð´Ð°Ð»Ð¾ÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ %{count} Ð¿ÑƒÐ½ÐºÑ‚(Ñ–Ð²) Ð· %{total} Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¸Ñ…: %{ids}."
-  notice_no_issue_selected: "ÐÐµ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾ Ð¶Ð¾Ð´Ð½Ð¾Ñ— Ð·Ð°Ð´Ð°Ñ‡Ñ–! Ð‘ÑƒÐ´ÑŒ Ð»Ð°ÑÐºÐ°, Ð²Ñ–Ð´Ð·Ð½Ð°Ñ‡Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ñƒ, ÑÐºÑƒ Ð²Ð¸ Ñ…Ð¾Ñ‡ÐµÑ‚Ðµ Ð²Ñ–Ð´Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸."
-  notice_account_pending: "Ð’Ð°Ñˆ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð¾ Ñ– Ð²Ñ–Ð½ Ñ‡ÐµÐºÐ°Ñ” Ð½Ð° Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð¼."
-
-  mail_subject_lost_password: "Ð’Ð°Ñˆ %{value} Ð¿Ð°Ñ€Ð¾Ð»ÑŒ"
-  mail_body_lost_password: 'Ð”Ð»Ñ Ð·Ð¼Ñ–Ð½Ð¸ Ð¿Ð°Ñ€Ð¾Ð»Ñ, Ð·Ð°Ð¹Ð´Ñ–Ñ‚ÑŒ Ð·Ð° Ð½Ð°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ð¼ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½ÑÐ¼:'
-  mail_subject_register: "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ %{value}"
-  mail_body_register: 'Ð”Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ, Ð·Ð°Ð¹Ð´Ñ–Ñ‚ÑŒ Ð·Ð° Ð½Ð°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ð¼ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½ÑÐ¼:'
-  mail_body_account_information_external: "Ð’Ð¸ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÐ²Ð°Ñ‚Ð¸ Ð²Ð°Ñˆ %{value} Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ."
-  mail_body_account_information: Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ð¾ Ð’Ð°ÑˆÐ¾Ð¼Ñƒ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð¼Ñƒ Ð·Ð°Ð¿Ð¸ÑÑƒ
-  mail_subject_account_activation_request: "Ð—Ð°Ð¿Ð¸Ñ‚ Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–ÑŽ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ %{value}"
-  mail_body_account_activation_request: "ÐÐ¾Ð²Ð¸Ð¹ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡ (%{value}) Ð·Ð°Ñ€ÐµÑ”ÑÑ‚Ñ€ÑƒÐ²Ð°Ð²ÑÑ. Ð™Ð¾Ð³Ð¾ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ Ñ‡ÐµÐºÐ°Ñ” Ð½Ð° Ð²Ð°ÑˆÐµ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ:"
-
-  gui_validation_error: 1 Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°
-  gui_validation_error_plural: "%{count} Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸(Ð¾Ðº)"
-
-  field_name: Ð†Ð¼'Ñ
-  field_description: ÐžÐ¿Ð¸Ñ
-  field_summary: ÐšÐ¾Ñ€Ð¾Ñ‚ÐºÐ¸Ð¹ Ð¾Ð¿Ð¸Ñ
-  field_is_required: ÐÐµÐ¾Ð±Ñ…Ñ–Ð´Ð½Ð¾
-  field_firstname: Ð†Ð¼'Ñ
-  field_lastname: ÐŸÑ€Ñ–Ð·Ð²Ð¸Ñ‰Ðµ
-  field_mail: Ð•Ð». Ð¿Ð¾ÑˆÑ‚Ð°
-  field_filename: Ð¤Ð°Ð¹Ð»
-  field_filesize: Ð Ð¾Ð·Ð¼Ñ–Ñ€
-  field_downloads: Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ
-  field_author: ÐÐ²Ñ‚Ð¾Ñ€
-  field_created_on: Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¾
-  field_updated_on: ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð¾
-  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
-  field_is_for_all: Ð”Ð»Ñ ÑƒÑÑ–Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ–Ð²
-  field_possible_values: ÐœÐ¾Ð¶Ð»Ð¸Ð²Ñ– Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ
-  field_regexp: Ð ÐµÐ³ÑƒÐ»ÑÑ€Ð½Ð¸Ð¹ Ð²Ð¸Ñ€Ð°Ð·
-  field_min_length: ÐœÑ–Ð½Ñ–Ð¼Ð°Ð»ÑŒÐ½Ð° Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð°
-  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð° Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð°
-  field_value: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ
-  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ
-  field_title: ÐÐ°Ð·Ð²Ð°
-  field_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
-  field_issue: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ
-  field_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ
-  field_notes: ÐŸÑ€Ð¸Ð¼Ñ–Ñ‚ÐºÐ¸
-  field_is_closed: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¾
-  field_is_default: Ð¢Ð¸Ð¿Ð¾Ð²Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ
-  field_tracker: ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€
-  field_subject: Ð¢ÐµÐ¼Ð°
-  field_due_date: Ð”Ð°Ñ‚Ð° Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ
-  field_assigned_to: ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð° Ð´Ð¾
-  field_priority: ÐŸÑ€Ñ–Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
-  field_fixed_version: Target version
-  field_user: ÐšÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡
-  field_role: Ð Ð¾Ð»ÑŒ
-  field_homepage: Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°
-  field_is_public: ÐŸÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð¸Ð¹
-  field_parent: ÐŸÑ–Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  field_is_in_roadmap: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ, Ñ‰Ð¾ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶Ð°ÑŽÑ‚ÑŒÑÑ Ð² Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ð¾Ð¼Ñƒ Ð¿Ð»Ð°Ð½Ñ–
-  field_login: Ð’Ñ…Ñ–Ð´
-  field_mail_notification: ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð° ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ Ð¿Ð¾ÑˆÑ‚Ð¾ÑŽ
-  field_admin: ÐÐ´Ð¼Ñ–Ð½Ñ–ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
-  field_last_login_on: ÐžÑÑ‚Ð°Ð½Ð½Ñ” Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ
-  field_language: ÐœÐ¾Ð²Ð°
-  field_effective_date: Ð”Ð°Ñ‚Ð°
-  field_password: ÐŸÐ°Ñ€Ð¾Ð»ÑŒ
-  field_new_password: ÐÐ¾Ð²Ð¸Ð¹ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
-  field_password_confirmation: ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ
-  field_version: Ð’ÐµÑ€ÑÑ–Ñ
-  field_type: Ð¢Ð¸Ð¿
-  field_host: ÐœÐ°ÑˆÐ¸Ð½Ð°
-  field_port: ÐŸÐ¾Ñ€Ñ‚
-  field_account: ÐžÐ±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ
-  field_base_dn: Ð‘Ð°Ð·Ð¾Ð²Ðµ Ð²Ñ–Ð´Ð¼Ñ–Ñ‚Ð½Ðµ Ñ–Ð¼'Ñ
-  field_attr_login: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð ÐµÑ”ÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ
-  field_attr_firstname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð†Ð¼'Ñ
-  field_attr_lastname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ ÐŸÑ€Ñ–Ð·Ð²Ð¸Ñ‰Ðµ
-  field_attr_mail: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Email
-  field_onthefly: Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð° Ð½Ð° Ð»ÑŒÐ¾Ñ‚Ñƒ
-  field_start_date: ÐŸÐ¾Ñ‡Ð°Ñ‚Ð¾Ðº
-  field_done_ratio: "% Ð·Ñ€Ð¾Ð±Ð»ÐµÐ½Ð¾"
-  field_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—
-  field_hide_mail: ÐŸÑ€Ð¸Ñ…Ð¾Ð²ÑƒÐ²Ð°Ñ‚Ð¸ Ð¼Ñ–Ð¹ email
-  field_comments: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  field_url: URL
-  field_start_page: Ð¡Ñ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð° ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°
-  field_subproject: ÐŸÑ–Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  field_hours: Ð“Ð¾Ð´Ð¸Ð½(Ð¸/Ð°)
-  field_activity: Ð”Ñ–ÑÐ»ÑŒÐ½Ñ–ÑÑ‚ÑŒ
-  field_spent_on: Ð”Ð°Ñ‚Ð°
-  field_identifier: Ð†Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ‚Ð¾Ñ€
-  field_is_filter: Ð’Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÑ”Ñ‚ÑŒÑÑ ÑÐº Ñ„Ñ–Ð»ÑŒÑ‚Ñ€
-  field_issue_to: Ð—Ð²'ÑÐ·Ð°Ð½Ñ– Ð·Ð°Ð´Ð°Ñ‡Ñ–
-  field_delay: Ð’Ñ–Ð´ÐºÐ»Ð°ÑÑ‚Ð¸
-  field_assignable: Ð—Ð°Ð´Ð°Ñ‡Ð° Ð¼Ð¾Ð¶Ðµ Ð±ÑƒÑ‚Ð¸ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð° Ñ†Ñ–Ð¹ Ñ€Ð¾Ð»Ñ–
-  field_redirect_existing_links: ÐŸÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸ Ñ–ÑÐ½ÑƒÑŽÑ‡Ñ– Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ
-  field_estimated_hours: ÐžÑ†Ñ–Ð½Ð½Ð¸Ð¹ Ñ‡Ð°Ñ
-  field_column_names: ÐšÐ¾Ð»Ð¾Ð½ÐºÐ¸
-  field_time_zone: Ð§Ð°ÑÐ¾Ð²Ð¸Ð¹ Ð¿Ð¾ÑÑ
-  field_searchable: Ð’Ð¶Ð¸Ð²Ð°Ñ”Ñ‚ÑŒÑÑ Ñƒ Ð¿Ð¾ÑˆÑƒÐºÑƒ
-
-  setting_app_title: ÐÐ°Ð·Ð²Ð° Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ
-  setting_app_subtitle: ÐŸÑ–Ð´Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ
-  setting_welcome_text: Ð¢ÐµÐºÑÑ‚ Ð¿Ñ€Ð¸Ð²Ñ–Ñ‚Ð°Ð½Ð½Ñ
-  setting_default_language: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð° Ð¼Ð¾Ð²Ð°
-  setting_login_required: ÐÐµÐ¾Ð±Ñ…Ñ–Ð´Ð½Ð° Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ
-  setting_self_registration: ÐœÐ¾Ð¶Ð»Ð¸Ð²Ð° ÑÐ°Ð¼Ð¾-Ñ€ÐµÑ”ÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ
-  setting_attachment_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¸Ð¹ Ñ€Ð°Ð·Ð¼Ñ–Ñ€ Ð²ÐºÐ»Ð°Ð´ÐµÐ½Ð½Ñ
-  setting_issues_export_limit: ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾ Ð·Ð°Ð´Ð°Ñ‡Ð°Ñ…, Ñ‰Ð¾ ÐµÐºÑÐ¿Ð¾Ñ€Ñ‚ÑƒÑŽÑ‚ÑŒÑÑ
-  setting_mail_from: email Ð°Ð´Ñ€ÐµÑÐ° Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ñ– Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
-  setting_bcc_recipients: ÐžÑ‚Ñ€Ð¸Ð¼ÑƒÐ²Ð°Ñ‡Ñ– ÑÐ»Ñ–Ð¿Ð¾Ñ— ÐºÐ¾Ð¿Ñ–Ñ— (bcc)
-  setting_host_name: Ð˜Ð¼'Ñ Ð¼Ð°ÑˆÐ¸Ð½Ð¸
-  setting_text_formatting: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÑÑ‚Ñƒ
-  setting_wiki_compression: Ð¡Ñ‚Ð¸ÑÐ½ÐµÐ½Ð½Ñ Ñ–ÑÑ‚Ð¾Ñ€Ñ–Ñ— Wiki
-  setting_feeds_limit: ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–ÑÑ‚Ñƒ Ð¿Ð¾Ð´Ð°Ñ‡Ñ–
-  setting_autofetch_changesets: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾ Ð´Ð¾ÑÑ‚Ð°Ð²Ð°Ñ‚Ð¸ Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ
-  setting_sys_api_enabled: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ‚Ð¸ WS Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ”Ð¼
-  setting_commit_ref_keywords: ÐšÐ»ÑŽÑ‡Ð¾Ð²Ñ– ÑÐ»Ð¾Ð²Ð° Ð´Ð»Ñ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ
-  setting_commit_fix_keywords: ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¸Ñ… ÑÐ»Ñ–Ð²
-  setting_autologin: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¸Ð¹ Ð²Ñ…Ñ–Ð´
-  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð´Ð°Ñ‚Ð¸
-  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ñ‡Ð°ÑÑƒ
-  setting_cross_project_issue_relations: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ‚Ð¸ Ð¼Ñ–Ð¶Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ñ– Ð²Ñ–Ð´Ð½Ð¾ÑÐ¸Ð½Ð¸ Ð¼Ñ–Ð¶ Ð¿Ð¸Ñ‚Ð°Ð½Ð½ÑÐ¼Ð¸
-  setting_issue_list_default_columns: ÐšÐ¾Ð»Ð¾Ð½ÐºÐ¸, Ñ‰Ð¾ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶Ð°ÑŽÑ‚ÑŒÑÑ Ð·Ð° ÑƒÐ¼Ð¾Ð²Ñ‡Ð°Ð½Ð½ÑÐ¼ Ð² ÑÐ¿Ð¸ÑÐºÑƒ Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
-  setting_emails_footer: ÐŸÑ–Ð´Ð¿Ð¸Ñ Ð´Ð¾ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— Ð¿Ð¾ÑˆÑ‚Ð¸
-  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
-
-  label_user: ÐšÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡
-  label_user_plural: ÐšÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ñ–
-  label_user_new: ÐÐ¾Ð²Ð¸Ð¹ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡
-  label_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
-  label_project_new: ÐÐ¾Ð²Ð¸Ð¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚
-  label_project_plural: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸
-  label_x_projects:
-    zero:  no projects
-    one:   1 project
-    other: "%{count} projects"
-  label_project_all: Ð£ÑÑ– Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_project_latest: ÐžÑÑ‚Ð°Ð½Ð½Ñ– Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_issue: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ
-  label_issue_new: ÐÐ¾Ð²Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
-  label_issue_plural: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ
-  label_issue_view_all: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸ Ð²ÑÑ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
-  label_issues_by: "ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ð° %{value}"
-  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_new: ÐÐ¾Ð²Ð¸Ð¹ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
-  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
-  label_role: Ð Ð¾Ð»ÑŒ
-  label_role_plural: Ð Ð¾Ð»Ñ–
-  label_role_new: ÐÐ¾Ð²Ð° Ñ€Ð¾Ð»ÑŒ
-  label_role_and_permissions: Ð Ð¾Ð»Ñ– Ñ– Ð¿Ñ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ
-  label_member: Ð£Ñ‡Ð°ÑÐ½Ð¸Ðº
-  label_member_new: ÐÐ¾Ð²Ð¸Ð¹ ÑƒÑ‡Ð°ÑÐ½Ð¸Ðº
-  label_member_plural: Ð£Ñ‡Ð°ÑÐ½Ð¸ÐºÐ¸
-  label_tracker: ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€
-  label_tracker_plural: ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€Ð¸
-  label_tracker_new: ÐÐ¾Ð²Ð¸Ð¹ ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€
-  label_workflow: ÐŸÐ¾ÑÐ»Ñ–Ð´Ð¾Ð²Ð½Ñ–ÑÑ‚ÑŒ Ð´Ñ–Ð¹
-  label_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
-  label_issue_status_plural: Ð¡Ñ‚Ð°Ñ‚ÑƒÑÐ¸ Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
-  label_issue_status_new: ÐÐ¾Ð²Ð¸Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
-  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ— Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
-  label_issue_category_new: ÐÐ¾Ð²Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ
-  label_custom_field: ÐŸÐ¾Ð»Ðµ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð°
-  label_custom_field_plural: ÐŸÐ¾Ð»Ñ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð°
-  label_custom_field_new: ÐÐ¾Ð²Ðµ Ð¿Ð¾Ð»Ðµ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð°
-  label_enumerations: Ð”Ð¾Ð²Ñ–Ð´Ð½Ð¸ÐºÐ¸
-  label_enumeration_new: ÐÐ¾Ð²Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ
-  label_information: Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ
-  label_information_plural: Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ
-  label_please_login: Ð‘ÑƒÐ´ÑŒ Ð»Ð°ÑÐºÐ°, ÑƒÐ²Ñ–Ð¹Ð´Ñ–Ñ‚ÑŒ
-  label_register: Ð—Ð°Ñ€ÐµÑ”ÑÑ‚Ñ€ÑƒÐ²Ð°Ñ‚Ð¸ÑÑ
-  label_password_lost: Ð—Ð°Ð±ÑƒÐ»Ð¸ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
-  label_home: Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°
-  label_my_page: ÐœÐ¾Ñ ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°
-  label_my_account: ÐœÑ–Ð¹ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ
-  label_my_projects: ÐœÐ¾Ñ— Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_administration: ÐÐ´Ð¼Ñ–Ð½Ñ–ÑÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ
-  label_login: Ð£Ð²Ñ–Ð¹Ñ‚Ð¸
-  label_logout: Ð’Ð¸Ð¹Ñ‚Ð¸
-  label_help: Ð”Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð°
-  label_reported_issues: Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
-  label_assigned_to_me_issues: ÐœÐ¾Ñ— Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
-  label_last_login: ÐžÑÑ‚Ð°Ð½Ð½Ñ” Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ
-  label_registered_on: Ð—Ð°Ñ€ÐµÑ”ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½Ð¸Ð¹(Ð°)
-  label_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ñ–ÑÑ‚ÑŒ
-  label_new: ÐÐ¾Ð²Ð¸Ð¹
-  label_logged_as: Ð£Ð²Ñ–Ð¹ÑˆÐ¾Ð² ÑÐº
-  label_environment: ÐžÑ‚Ð¾Ñ‡ÐµÐ½Ð½Ñ
-  label_authentication: ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ
-  label_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—
-  label_auth_source_new: ÐÐ¾Ð²Ð¸Ð¹ Ñ€ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—
-  label_auth_source_plural: Ð ÐµÐ¶Ð¸Ð¼Ð¸ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—
-  label_subproject_plural: ÐŸÑ–Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_min_max_length: ÐœÑ–Ð½Ñ–Ð¼Ð°Ð»ÑŒÐ½Ð° - Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð° Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð°
-  label_list: Ð¡Ð¿Ð¸ÑÐ¾Ðº
-  label_date: Ð”Ð°Ñ‚Ð°
-  label_integer: Ð¦Ñ–Ð»Ð¸Ð¹
-  label_float: Ð— Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‡Ð¾ÑŽ ÐºÑ€Ð°Ð¿ÐºÐ¾ÑŽ
-  label_boolean: Ð›Ð¾Ð³Ñ–Ñ‡Ð½Ð¸Ð¹
-  label_string: Ð¢ÐµÐºÑÑ‚
-  label_text: Ð”Ð¾Ð²Ð³Ð¸Ð¹ Ñ‚ÐµÐºÑÑ‚
-  label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
-  label_attribute_plural: Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸
-  label_download: "%{count} Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð¾"
-  label_download_plural: "%{count} Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½ÑŒ"
-  label_no_data: ÐÐµÐ¼Ð°Ñ” Ð´Ð°Ð½Ð¸Ñ… Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ
-  label_change_status: Ð—Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_history: Ð†ÑÑ‚Ð¾Ñ€Ñ–Ñ
-  label_attachment: Ð¤Ð°Ð¹Ð»
-  label_attachment_new: ÐÐ¾Ð²Ð¸Ð¹ Ñ„Ð°Ð¹Ð»
-  label_attachment_delete: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ñ„Ð°Ð¹Ð»
-  label_attachment_plural: Ð¤Ð°Ð¹Ð»Ð¸
-  label_report: Ð—Ð²Ñ–Ñ‚
-  label_report_plural: Ð—Ð²Ñ–Ñ‚Ð¸
-  label_news: ÐÐ¾Ð²Ð¸Ð½Ð¸
-  label_news_new: Ð”Ð¾Ð´Ð°Ñ‚Ð¸ Ð½Ð¾Ð²Ð¸Ð½Ñƒ
-  label_news_plural: ÐÐ¾Ð²Ð¸Ð½Ð¸
-  label_news_latest: ÐžÑÑ‚Ð°Ð½Ð½Ñ– Ð½Ð¾Ð²Ð¸Ð½Ð¸
-  label_news_view_all: ÐŸÐ¾Ð´Ð¸Ð²Ð¸Ñ‚Ð¸ÑÑ Ð²ÑÑ– Ð½Ð¾Ð²Ð¸Ð½Ð¸
-  label_settings: ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ
-  label_overview: ÐŸÐµÑ€ÐµÐ³Ð»ÑÐ´
-  label_version: Ð’ÐµÑ€ÑÑ–Ñ
-  label_version_new: ÐÐ¾Ð²Ð° Ð²ÐµÑ€ÑÑ–Ñ
-  label_version_plural: Ð’ÐµÑ€ÑÑ–Ñ—
-  label_confirmation: ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ
-  label_export_to: Ð•ÐºÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸ Ð²
-  label_read: Ð§Ð¸Ñ‚Ð°Ð½Ð½Ñ...
-  label_public_projects: ÐŸÑƒÐ±Ð»Ñ–Ñ‡Ð½Ñ– Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
-  label_open_issues: Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ðµ
-  label_open_issues_plural: Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ–
-  label_closed_issues: Ð·Ð°ÐºÑ€Ð¸Ñ‚Ðµ
-  label_closed_issues_plural: Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ–
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_total: Ð’ÑÑŒÐ¾Ð³Ð¾
-  label_permissions: ÐŸÑ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ
-  label_current_status: ÐŸÐ¾Ñ‚Ð¾Ñ‡Ð½Ð¸Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_new_statuses_allowed: Ð”Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ñ– Ð½Ð¾Ð²Ñ– ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸
-  label_all: Ð£ÑÑ–
-  label_none: ÐÑ–ÐºÐ¾Ð¼Ñƒ
-  label_nobody: ÐÑ–Ñ…Ñ‚Ð¾
-  label_next: ÐÐ°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ð¹
-  label_previous: ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ–Ð¹
-  label_used_by: Ð’Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÑ”Ñ‚ÑŒÑÑ
-  label_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð¸Ñ†Ñ–
-  label_add_note: Ð”Ð¾Ð´Ð°Ñ‚Ð¸ Ð·Ð°ÑƒÐ²Ð°Ð¶ÐµÐ½Ð½Ñ
-  label_per_page: ÐÐ° ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÑƒ
-  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
-  label_months_from: Ð¼Ñ–ÑÑÑ†Ñ–Ð²(Ñ†Ñ) Ð·
-  label_gantt: Ð”Ñ–Ð°Ð³Ñ€Ð°Ð¼Ð° Ð“Ð°Ð½Ñ‚Ð°
-  label_internal: Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ–Ð¹
-  label_last_changes: "Ð¾ÑÑ‚Ð°Ð½Ð½Ñ– %{count} Ð·Ð¼Ñ–Ð½"
-  label_change_view_all: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸ Ð²ÑÑ– Ð·Ð¼Ñ–Ð½Ð¸
-  label_personalize_page: ÐŸÐµÑ€ÑÐ¾Ð½Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ Ñ†ÑŽ ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÑƒ
-  label_comment: ÐšÐ¾Ð¼ÐµÐ½Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸
-  label_comment_plural: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ–
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_comment_add: Ð—Ð°Ð»Ð¸ÑˆÐ¸Ñ‚Ð¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
-  label_comment_added: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€ Ð´Ð¾Ð´Ð°Ð½Ð¾
-  label_comment_delete: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ–
-  label_query: Ð—Ð°Ð¿Ð¸Ñ‚ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð°
-  label_query_plural: Ð—Ð°Ð¿Ð¸Ñ‚Ð¸ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ñ–Ð²
-  label_query_new: ÐÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ‚
-  label_filter_add: Ð”Ð¾Ð´Ð°Ñ‚Ð¸ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€
-  label_filter_plural: Ð¤Ñ–Ð»ÑŒÑ‚Ñ€Ð¸
-  label_equals: Ñ”
-  label_not_equals: Ð½ÐµÐ¼Ð°Ñ”
-  label_in_less_than: Ð¼ÐµÐ½Ñˆ Ð½Ñ–Ð¶
-  label_in_more_than: Ð±Ñ–Ð»ÑŒÑˆ Ð½Ñ–Ð¶
-  label_in: Ñƒ
-  label_today: ÑÑŒÐ¾Ð³Ð¾Ð´Ð½Ñ–
-  label_this_week: Ñ†ÑŒÐ¾Ð³Ð¾ Ñ‚Ð¸Ð¶Ð½Ñ
-  label_less_than_ago: Ð¼ÐµÐ½Ñˆ Ð½Ñ–Ð¶ Ð´Ð½Ñ–Ð²(Ñ) Ð½Ð°Ð·Ð°Ð´
-  label_more_than_ago: Ð±Ñ–Ð»ÑŒÑˆ Ð½Ñ–Ð¶ Ð´Ð½Ñ–Ð²(Ñ) Ð½Ð°Ð·Ð°Ð´
-  label_ago: Ð´Ð½Ñ–Ð²(Ñ) Ð½Ð°Ð·Ð°Ð´
-  label_contains: Ð¼Ñ–ÑÑ‚Ð¸Ñ‚ÑŒ
-  label_not_contains: Ð½Ðµ Ð¼Ñ–ÑÑ‚Ð¸Ñ‚ÑŒ
-  label_day_plural: Ð´Ð½Ñ–Ð²(Ñ)
-  label_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ð¹
-  label_browse: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸
-  label_modification: "%{count} Ð·Ð¼Ñ–Ð½Ð°"
-  label_modification_plural: "%{count} Ð·Ð¼Ñ–Ð½"
-  label_revision: Ð’ÐµÑ€ÑÑ–Ñ
-  label_revision_plural: Ð’ÐµÑ€ÑÑ–Ð¹
-  label_added: Ð´Ð¾Ð´Ð°Ð½Ð¾
-  label_modified: Ð·Ð¼Ñ–Ð½ÐµÐ½Ðµ
-  label_deleted: Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð¾
-  label_latest_revision: ÐžÑÑ‚Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñ
-  label_latest_revision_plural: ÐžÑÑ‚Ð°Ð½Ð½Ñ– Ð²ÐµÑ€ÑÑ–Ñ—
-  label_view_revisions: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸ Ð²ÐµÑ€ÑÑ–Ñ—
-  label_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¸Ð¹ Ñ€Ð¾Ð·Ð¼Ñ–Ñ€
-  label_sort_highest: Ð£ Ð¿Ð¾Ñ‡Ð°Ñ‚Ð¾Ðº
-  label_sort_higher: Ð’Ð³Ð¾Ñ€Ñƒ
-  label_sort_lower: Ð’Ð½Ð¸Ð·
-  label_sort_lowest: Ð£ ÐºÑ–Ð½ÐµÑ†ÑŒ
-  label_roadmap: ÐžÐ¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ð¸Ð¹ Ð¿Ð»Ð°Ð½
-  label_roadmap_due_in: "Ð¡Ñ‚Ñ€Ð¾Ðº %{value}"
-  label_roadmap_overdue: "%{value} Ð·Ð°Ð¿Ñ–Ð·Ð½ÐµÐ½Ð½Ñ"
-  label_roadmap_no_issues: ÐÐµÐ¼Ð°Ñ” Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ Ð´Ð»Ñ Ð´Ð°Ð½Ð¾Ñ— Ð²ÐµÑ€ÑÑ–Ñ—
-  label_search: ÐŸÐ¾ÑˆÑƒÐº
-  label_result_plural: Ð ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¸
-  label_all_words: Ð’ÑÑ– ÑÐ»Ð¾Ð²Ð°
-  label_wiki: Wiki
-  label_wiki_edit: Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Wiki
-  label_wiki_edit_plural: Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Wiki
-  label_wiki_page: Ð¡Ñ‚Ð¾Ñ€Ñ–Ð½ÐºÐ° Wiki
-  label_wiki_page_plural: Ð¡Ñ‚Ð¾Ñ€Ñ–Ð½ÐºÐ¸ Wiki
-  label_index_by_title: Ð†Ð½Ð´ÐµÐºÑ Ð·Ð° Ð½Ð°Ð·Ð²Ð¾ÑŽ
-  label_index_by_date: Ð†Ð½Ð´ÐµÐºÑ Ð·Ð° Ð´Ð°Ñ‚Ð¾ÑŽ
-  label_current_version: ÐŸÐ¾Ñ‚Ð¾Ñ‡Ð½Ð° Ð²ÐµÑ€ÑÑ–Ñ
-  label_preview: ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ–Ð¹ Ð¿ÐµÑ€ÐµÐ³Ð»ÑÐ´
-  label_feed_plural: ÐŸÐ¾Ð´Ð°Ð½Ð½Ñ
-  label_changes_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð¸Ñ†Ñ– Ð¿Ð¾ Ð²ÑÑ–Ñ… Ð·Ð¼Ñ–Ð½Ð°Ñ…
-  label_issue_tracking: ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ†Ñ–Ñ Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
-  label_spent_time: Ð’Ð¸Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð¸Ð¹ Ñ‡Ð°Ñ
-  label_f_hour: "%{value} Ð³Ð¾Ð´Ð¸Ð½Ð°"
-  label_f_hour_plural: "%{value} Ð³Ð¾Ð´Ð¸Ð½(Ð¸)"
-  label_time_tracking: ÐžÐ±Ð»Ñ–Ðº Ñ‡Ð°ÑÑƒ
-  label_change_plural: Ð—Ð¼Ñ–Ð½Ð¸
-  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ°
-  label_commits_per_month: ÐŸÐ¾Ð´Ð°Ð½ÑŒ Ð½Ð° Ð¼Ñ–ÑÑÑ†ÑŒ
-  label_commits_per_author: ÐŸÐ¾Ð´Ð°Ð½ÑŒ Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð°
-  label_view_diff: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸ Ð²Ñ–Ð´Ð¼Ñ–Ð½Ð½Ð¾ÑÑ‚Ñ–
-  label_diff_inline: Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹
-  label_diff_side_by_side: Ð¿Ð¾Ñ€ÑÐ´
-  label_options: ÐžÐ¿Ñ†Ñ–Ñ—
-  label_copy_workflow_from: Ð¡ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ñ‚Ð¸ Ð¿Ð¾ÑÐ»Ñ–Ð´Ð¾Ð²Ð½Ñ–ÑÑ‚ÑŒ Ð´Ñ–Ð¹ Ð·
-  label_permissions_report: Ð—Ð²Ñ–Ñ‚ Ð¿Ñ€Ð¾ Ð¿Ñ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ
-  label_watched_issues: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
-  label_related_issues: Ð—Ð²'ÑÐ·Ð°Ð½Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
-  label_applied_status: Ð—Ð°ÑÑ‚Ð¾ÑÐ¾Ð²Ð½Ð¸Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
-  label_loading: Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ...
-  label_relation_new: ÐÐ¾Ð²Ð¸Ð¹ Ð·Ð²'ÑÐ·Ð¾Ðº
-  label_relation_delete: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ð·Ð²'ÑÐ·Ð¾Ðº
-  label_relates_to: Ð¿Ð¾Ð²'ÑÐ·Ð°Ð½Ðµ Ð·
-  label_duplicates: Ð´ÑƒÐ±Ð»ÑŽÑ”
-  label_blocks: Ð±Ð»Ð¾ÐºÑƒÑ”
-  label_blocked_by: Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ðµ
-  label_precedes: Ð¿ÐµÑ€ÐµÐ´ÑƒÑ”
-  label_follows: Ð½Ð°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ð¹ Ð·Ð°
-  label_end_to_start: Ð· ÐºÑ–Ð½Ñ†Ñ Ð´Ð¾ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ
-  label_end_to_end: Ð· ÐºÑ–Ð½Ñ†Ñ Ð´Ð¾ ÐºÑ–Ð½Ñ†Ñ
-  label_start_to_start: Ð· Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ Ð´Ð¾ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ
-  label_start_to_end: Ð· Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ Ð´Ð¾ ÐºÑ–Ð½Ñ†Ñ
-  label_stay_logged_in: Ð—Ð°Ð»Ð¸ÑˆÐ°Ñ‚Ð¸ÑÑ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ñ–
-  label_disabled: Ð²Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹
-  label_show_completed_versions: ÐŸÐ¾ÐºÐ°Ð·Ð°Ñ‚Ð¸ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ñ– Ð²ÐµÑ€ÑÑ–Ñ—
-  label_me: Ð¼ÐµÐ½Ðµ
-  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
-  label_board_new: ÐÐ¾Ð²Ð¸Ð¹ Ñ„Ð¾Ñ€ÑƒÐ¼
-  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
-  label_topic_plural: Ð¢ÐµÐ¼Ð¸
-  label_message_plural: ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ
-  label_message_last: ÐžÑÑ‚Ð°Ð½Ð½Ñ” Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ
-  label_message_new: ÐÐ¾Ð²Ðµ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ
-  label_reply_plural: Ð’Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ñ–
-  label_send_information: Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡ÐµÐ²Ñ– Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–ÑŽ Ð· Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ
-  label_year: Ð Ñ–Ðº
-  label_month: ÐœÑ–ÑÑÑ†ÑŒ
-  label_week: ÐÐµÐ´Ñ–Ð»Ñ
-  label_date_from: Ð—
-  label_date_to: ÐšÐ¾Ð¼Ñƒ
-  label_language_based: ÐÐ° Ð¾ÑÐ½Ð¾Ð²Ñ– Ð¼Ð¾Ð²Ð¸ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð°
-  label_sort_by: "Ð¡Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸ Ð·Ð° %{value}"
-  label_send_test_email: ÐŸÐ¾ÑÐ»Ð°Ñ‚Ð¸ email Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸
-  label_feeds_access_key_created_on: "ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ RSS ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ð¹ %{value} Ð½Ð°Ð·Ð°Ð´ "
-  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ñ–
-  label_added_time_by: "Ð”Ð¾Ð´Ð°Ð½Ð¸Ð¹ %{author} %{age} Ð½Ð°Ð·Ð°Ð´"
-  label_updated_time: "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¹ %{value} Ð½Ð°Ð·Ð°Ð´"
-  label_jump_to_a_project: ÐŸÐµÑ€ÐµÐ¹Ñ‚Ð¸ Ð´Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ...
-  label_file_plural: Ð¤Ð°Ð¹Ð»Ð¸
-  label_changeset_plural: ÐÐ°Ð±Ð¾Ñ€Ð¸ Ð·Ð¼Ñ–Ð½
-  label_default_columns: Ð¢Ð¸Ð¿Ð¾Ð²Ñ– ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸
-  label_no_change_option: (ÐÐµÐ¼Ð°Ñ” Ð·Ð¼Ñ–Ð½)
-  label_bulk_edit_selected_issues: Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸ Ð²ÑÑ– Ð²Ð¸Ð±Ñ€Ð°Ð½Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
-  label_theme: Ð¢ÐµÐ¼Ð°
-  label_default: Ð¢Ð¸Ð¿Ð¾Ð²Ð¸Ð¹
-  label_search_titles_only: Ð¨ÑƒÐºÐ°Ñ‚Ð¸ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ð² Ð½Ð°Ð·Ð²Ð°Ñ…
-  label_user_mail_option_all: "Ð”Ð»Ñ Ð²ÑÑ–Ñ… Ð¿Ð¾Ð´Ñ–Ð¹ Ñƒ Ð²ÑÑ–Ñ… Ð¼Ð¾Ñ—Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ñ…"
-  label_user_mail_option_selected: "Ð”Ð»Ñ Ð²ÑÑ–Ñ… Ð¿Ð¾Ð´Ñ–Ð¹ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ñƒ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð¼Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ–..."
-  label_user_mail_no_self_notified: "ÐÐµ ÑÐ¿Ð¾Ð²Ñ–Ñ‰Ð°Ñ‚Ð¸ Ð¿Ñ€Ð¾ Ð·Ð¼Ñ–Ð½Ð¸, ÑÐºÑ– Ñ Ð·Ñ€Ð¾Ð±Ð¸Ð² ÑÐ°Ð¼"
-  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ Ð¿Ð¾ÑˆÑ‚Ð¾ÑŽ
-  label_registration_manual_activation: Ñ€ÑƒÑ‡Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ
-  label_registration_automatic_activation: Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ð±Ð»Ñ‹ÐºÐ¾Ð²Ð¾Ð³Ð¾
-  label_my_time_report: ÐœÑ–Ð¹ Ð·Ð²Ñ–Ñ‚ Ð²Ð¸Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ Ñ‡Ð°ÑÑƒ
-
-  button_login: Ð’Ñ…Ñ–Ð´
-  button_submit: Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸
-  button_save: Ð—Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸
-  button_check_all: Ð’Ñ–Ð´Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ Ð²ÑÐµ
-  button_uncheck_all: ÐžÑ‡Ð¸ÑÑ‚Ð¸Ñ‚Ð¸
-  button_delete: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸
-  button_create: Ð¡Ñ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸
-  button_test: ÐŸÐµÑ€ÐµÐ²Ñ–Ñ€Ð¸Ñ‚Ð¸
-  button_edit: Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸
-  button_add: Ð”Ð¾Ð´Ð°Ñ‚Ð¸
-  button_change: Ð—Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸
-  button_apply: Ð—Ð°ÑÑ‚Ð¾ÑÑƒÐ²Ð°Ñ‚Ð¸
-  button_clear: ÐžÑ‡Ð¸ÑÑ‚Ð¸Ñ‚Ð¸
-  button_lock: Ð—Ð°Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ñ‚Ð¸
-  button_unlock: Ð Ð°Ð·Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ñ‚Ð¸
-  button_download: Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸
-  button_list: Ð¡Ð¿Ð¸ÑÐ¾Ðº
-  button_view: ÐŸÐµÑ€ÐµÐ³Ð»ÑÐ½ÑƒÑ‚Ð¸
-  button_move: ÐŸÐµÑ€ÐµÐ¼Ñ–ÑÑ‚Ð¸Ñ‚Ð¸
-  button_back: ÐÐ°Ð·Ð°Ð´
-  button_cancel: Ð’Ñ–Ð´Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸
-  button_activate: ÐÐºÑ‚Ð¸Ð²ÑƒÐ²Ð°Ñ‚Ð¸
-  button_sort: Ð¡Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸
-  button_log_time: Ð—Ð°Ð¿Ð¸ÑÐ°Ñ‚Ð¸ Ñ‡Ð°Ñ
-  button_rollback: Ð’Ñ–Ð´ÐºÐ¾Ñ‚Ð¸Ñ‚Ð¸ Ð´Ð¾ Ð´Ð°Ð½Ð¾Ñ— Ð²ÐµÑ€ÑÑ–Ñ—
-  button_watch: Ð”Ð¸Ð²Ð¸Ñ‚Ð¸ÑÑ
-  button_unwatch: ÐÐµ Ð´Ð¸Ð²Ð¸Ñ‚Ð¸ÑÑ
-  button_reply: Ð’Ñ–Ð´Ð¿Ð¾Ð²Ñ–ÑÑ‚Ð¸
-  button_archive: ÐÑ€Ñ…Ñ–Ð²ÑƒÐ²Ð°Ñ‚Ð¸
-  button_unarchive: Ð Ð¾Ð·Ð°Ñ€Ñ…Ñ–Ð²ÑƒÐ²Ð°Ñ‚Ð¸
-  button_reset: ÐŸÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑÑ‚Ð¸Ñ‚Ð¸
-  button_rename: ÐŸÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸
-  button_change_password: Ð—Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
-  button_copy: ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ñ‚Ð¸
-  button_annotate: ÐÐ½Ð¾Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸
-
-  status_active: ÐÐºÑ‚Ð¸Ð²Ð½Ð¸Ð¹
-  status_registered: Ð—Ð°Ñ€ÐµÑ”ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½Ð¸Ð¹
-  status_locked: Ð—Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð¸Ð¹
-
-  text_select_mail_notifications: Ð’Ð¸Ð±ÐµÑ€Ñ–Ñ‚ÑŒ Ð´Ñ–Ñ—, Ð½Ð° ÑÐºÑ– Ð²Ñ–Ð´ÑÐ¸Ð»Ð°Ñ‚Ð¸Ð¼ÐµÑ‚ÑŒÑÑ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð½Ð° ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ñƒ Ð¿Ð¾ÑˆÑ‚Ñƒ.
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 Ð¾Ð·Ð½Ð°Ñ‡Ð°Ñ” Ð²Ñ–Ð´ÑÑƒÑ‚Ð½Ñ–ÑÑ‚ÑŒ Ð·Ð°Ð±Ð¾Ñ€Ð¾Ð½
-  text_project_destroy_confirmation: Ð’Ð¸ Ð½Ð°Ð¿Ð¾Ð»ÑÐ³Ð°Ñ”Ñ‚Ðµ Ð½Ð° Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ– Ñ†ÑŒÐ¾Ð³Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ Ñ– Ð²ÑÑ–Ñ”Ñ— Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—, Ñ‰Ð¾ Ð²Ñ–Ð´Ð½Ð¾ÑÐ¸Ñ‚ÑŒÑÑ Ð´Ð¾ Ð½ÑŒÐ¾Ð³Ð¾?
-  text_workflow_edit: Ð’Ð¸Ð±ÐµÑ€Ñ–Ñ‚ÑŒ Ñ€Ð¾Ð»ÑŒ Ñ– ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€ Ð´Ð»Ñ Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÑÐ»Ñ–Ð´Ð¾Ð²Ð½Ð¾ÑÑ‚Ñ– Ð´Ñ–Ð¹
-  text_are_you_sure: Ð’Ð¸ Ð²Ð¿ÐµÐ²Ð½ÐµÐ½Ñ–?
-  text_tip_issue_begin_day: Ð´ÐµÐ½ÑŒ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ Ð·Ð°Ð´Ð°Ñ‡Ñ–
-  text_tip_issue_end_day: Ð´ÐµÐ½ÑŒ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ñ‡Ñ–
-  text_tip_issue_begin_end_day: Ð¿Ð¾Ñ‡Ð°Ñ‚Ð¾Ðº Ð·Ð°Ð´Ð°Ñ‡Ñ– Ñ– Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ð´Ð½Ñ
-  text_project_identifier_info: 'Ð ÑÐ´ÐºÐ¾Ð²Ñ– Ð±ÑƒÐºÐ²Ð¸ (a-z), Ð´Ð¾Ð¿ÑƒÑÑ‚Ð¸Ð¼Ñ– Ñ†Ð¸Ñ„Ñ€Ð¸ Ñ– Ð´ÐµÑ„Ñ–Ñ.<br />Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð¸Ð¹ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ‚Ð¾Ñ€ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±ÑƒÑ‚Ð¸ Ð·Ð¼Ñ–Ð½ÐµÐ½Ð¸Ð¹.'
-  text_caracters_maximum: "%{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ–Ð²(Ð°) Ð¼Ð°ÐºÑÐ¸Ð¼ÑƒÐ¼."
-  text_caracters_minimum: "ÐŸÐ¾Ð²Ð¸Ð½Ð½Ð¾ Ð¼Ð°Ñ‚Ð¸ ÑÐºÐ½Ð°Ð¹Ð¼ÐµÐ½ÑˆÐµ  %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ–Ð²(Ð°) Ñƒ Ð´Ð¾Ð²Ð¶Ð¸Ð½Ñƒ."
-  text_length_between: "Ð”Ð¾Ð²Ð¶Ð¸Ð½Ð° Ð¼Ñ–Ð¶ %{min} Ñ– %{max} ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ–Ð²."
-  text_tracker_no_workflow: Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€Ð° Ð¿Ð¾ÑÐ»Ñ–Ð´Ð¾Ð²Ð½Ñ–ÑÑ‚ÑŒ Ð´Ñ–Ð¹ Ð½Ðµ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð°
-  text_unallowed_characters: Ð—Ð°Ð±Ð¾Ñ€Ð¾Ð½ÐµÐ½Ñ– ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¸
-  text_comma_separated: Ð”Ð¾Ð¿ÑƒÑÑ‚Ð¸Ð¼Ñ– Ð´ÐµÐºÑ–Ð»ÑŒÐºÐ° Ð·Ð½Ð°Ñ‡ÐµÐ½ÑŒ (Ñ€Ð¾Ð·Ð´Ñ–Ð»ÐµÐ½Ñ– ÐºÐ¾Ð¼Ð¾ÑŽ).
-  text_issues_ref_in_commit_messages: ÐŸÐ¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñ‚Ð° Ð·Ð¼Ñ–Ð½Ð° Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ Ñƒ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½ÑÑ… Ð´Ð¾ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½ÑŒ
-  text_issue_added: "Issue %{id} has been reported by %{author}."
-  text_issue_updated: "Issue %{id} has been updated by %{author}."
-  text_wiki_destroy_confirmation: Ð’Ð¸ Ð²Ð¿ÐµÐ²Ð½ÐµÐ½Ñ–, Ñ‰Ð¾ Ñ…Ð¾Ñ‡ÐµÑ‚Ðµ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ñ†ÑŽ wiki Ñ– Ð²ÐµÑÑŒ Ð·Ð¼Ñ–ÑÑ‚?
-  text_issue_category_destroy_question: "Ð”ÐµÐºÑ–Ð»ÑŒÐºÐ° Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ (%{count}) Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾ Ð² Ñ†ÑŽ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–ÑŽ. Ð©Ð¾ Ð²Ð¸ Ñ…Ð¾Ñ‡ÐµÑ‚Ðµ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸?"
-  text_issue_category_destroy_assignments: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ—
-  text_issue_category_reassign_to: ÐŸÐµÑ€ÐµÐ¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ñ– Ð´Ð¾ Ð´Ð°Ð½Ð¾Ñ— ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ—
-  text_user_mail_option: "Ð”Ð»Ñ Ð½ÐµÐ²Ð¸Ð±Ñ€Ð°Ð½Ð¸Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ–Ð² Ð²Ð¸ Ð¾Ñ‚Ñ€Ð¸Ð¼ÑƒÐ²Ð°Ñ‚Ð¸Ð¼ÐµÑ‚Ðµ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ð¿Ñ€Ð¾ Ñ‚Ðµ, Ñ‰Ð¾ Ð¿Ñ€Ð¾Ð³Ð»ÑÐ´Ð°Ñ”Ñ‚Ðµ Ð°Ð±Ð¾ Ð² Ñ‡Ð¾Ð¼Ñƒ Ð±ÐµÑ€ÐµÑ‚Ðµ ÑƒÑ‡Ð°ÑÑ‚ÑŒ (Ð½Ð°Ð¿Ñ€Ð¸ÐºÐ»Ð°Ð´, Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼ ÑÐºÐ¸Ñ… Ð²Ð¸ Ñ” Ð°Ð±Ð¾ ÑÐºÑ– Ð²Ð°Ð¼ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ñ–)."
-
-  default_role_manager: ÐœÐµÐ½ÐµÐ´Ð¶ÐµÑ€
-  default_role_developer: Ð Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸Ðº
-  default_role_reporter: Ð ÐµÐ¿Ð¾Ñ€Ñ‚ÐµÑ€
-  # default_tracker_bug: Bug
-  # Ð·Ð²Ñ–Ñ‚Ñ–Ð² default_tracker_bug: ÐŸÐ¾Ð¼Ð¸Ð»ÐºÐ°
-  default_tracker_bug: ÐŸÐ¾Ð¼Ð¸Ð»ÐºÐ°
-  default_tracker_feature: Ð’Ð»Ð°ÑÑ‚Ð¸Ð²Ñ–ÑÑ‚ÑŒ
-  default_tracker_support: ÐŸÑ–Ð´Ñ‚Ñ€Ð¸Ð¼ÐºÐ°
-  default_issue_status_new: ÐÐ¾Ð²Ð¸Ð¹
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: Ð’Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð¾
-  default_issue_status_feedback: Ð—Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¸Ð¹ Ð·Ð²'ÑÐ·Ð¾Ðº
-  default_issue_status_closed: Ð—Ð°Ñ‡Ð¸Ð½ÐµÐ½Ð¾
-  default_issue_status_rejected: Ð’Ñ–Ð´Ð¼Ð¾Ð²Ð»ÐµÐ½Ð¾
-  default_doc_category_user: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð°
-  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ñ–Ñ‡Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ
-  default_priority_low: ÐÐ¸Ð·ÑŒÐºÐ¸Ð¹
-  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ð¸Ð¹
-  default_priority_high: Ð’Ð¸ÑÐ¾ÐºÐ¸Ð¹
-  default_priority_urgent: Ð¢ÐµÑ€Ð¼Ñ–Ð½Ð¾Ð²Ð¸Ð¹
-  default_priority_immediate: ÐÐµÐ³Ð°Ð¹Ð½Ð¸Ð¹
-  default_activity_design: ÐŸÑ€Ð¾ÐµÐºÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ
-  default_activity_development: Ð Ð¾Ð·Ñ€Ð¾Ð±ÐºÐ°
-
-  enumeration_issue_priorities: ÐŸÑ€Ñ–Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¸ Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
-  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ— Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ–Ð²
-  enumeration_activities: Ð”Ñ–Ñ— (Ð¾Ð±Ð»Ñ–Ðº Ñ‡Ð°ÑÑƒ)
-  text_status_changed_by_changeset: "Applied in changeset %{value}."
-  label_display_per_page: "Per page: %{value}"
-  label_issue_added: Issue added
-  label_issue_updated: Issue updated
-  setting_per_page_options: Objects per page options
-  notice_default_data_loaded: Default configuration successfully loaded.
-  error_scm_not_found: "Entry and/or revision doesn't exist in the repository."
-  label_associated_revisions: Associated revisions
-  label_document_added: Document added
-  label_message_posted: Message added
-  text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s) ?'
-  error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
-  setting_user_format: Users display format
-  label_age: Age
-  label_file_added: File added
-  label_more: More
-  field_default_value: Default value
-  label_scm: SCM
-  label_general: General
-  button_update: Update
-  text_select_project_modules: 'Select modules to enable for this project:'
-  label_change_properties: Change properties
-  text_load_default_configuration: Load the default configuration
-  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
-  label_news_added: News added
-  label_repository_plural: Repositories
-  error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
-  project_module_boards: Boards
-  project_module_issue_tracking: Issue tracking
-  project_module_wiki: Wiki
-  project_module_files: Files
-  project_module_documents: Documents
-  project_module_repository: Repository
-  project_module_news: News
-  project_module_time_tracking: Time tracking
-  text_file_repository_writable: File repository writable
-  text_default_administrator_account_changed: Default administrator account changed
-  text_rmagick_available: RMagick available (optional)
-  button_configure: Configure
-  label_plugins: Plugins
-  label_ldap_authentication: LDAP authentication
-  label_downloads_abbr: D/L
-  label_this_month: this month
-  label_last_n_days: "last %{count} days"
-  label_all_time: all time
-  label_this_year: this year
-  label_date_range: Date range
-  label_last_week: last week
-  label_yesterday: yesterday
-  label_last_month: last month
-  label_add_another_file: Add another file
-  label_optional_description: Optional description
-  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do ?"
-  error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
-  text_assign_time_entries_to_project: Assign reported hours to the project
-  text_destroy_time_entries: Delete reported hours
-  text_reassign_time_entries: 'Reassign reported hours to this issue:'
-  setting_activity_days_default: Days displayed on project activity
-  label_chronological_order: In chronological order
-  field_comments_sorting: Display comments
-  label_reverse_chronological_order: In reverse chronological order
-  label_preferences: Preferences
-  setting_display_subprojects_issues: Display subprojects issues on main projects by default
-  label_overall_activity: Overall activity
-  setting_default_projects_public: New projects are public by default
-  error_scm_annotate: "The entry does not exist or can not be annotated."
-  label_planning: Planning
-  text_subprojects_destroy_warning: "Its subproject(s): %{value} will be also deleted."
-  label_and_its_subprojects: "%{value} and its subprojects"
-  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
-  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
-  text_user_wrote: "%{value} wrote:"
-  label_duplicated_by: duplicated by
-  setting_enabled_scm: Enabled SCM
-  text_enumeration_category_reassign_to: 'Reassign them to this value:'
-  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
-  label_incoming_emails: Incoming emails
-  label_generate_key: Generate a key
-  setting_mail_handler_api_enabled: Enable WS for incoming emails
-  setting_mail_handler_api_key: API key
-  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
-  field_parent_title: Parent page
-  label_issue_watchers: Watchers
-  button_quote: Quote
-  setting_sequential_project_identifiers: Generate sequential project identifiers
-  notice_unable_delete_version: Unable to delete version
-  label_renamed: renamed
-  label_copied: copied
-  setting_plain_text_mail: plain text only (no HTML)
-  permission_view_files: View files
-  permission_edit_issues: Edit issues
-  permission_edit_own_time_entries: Edit own time logs
-  permission_manage_public_queries: Manage public queries
-  permission_add_issues: Add issues
-  permission_log_time: Log spent time
-  permission_view_changesets: View changesets
-  permission_view_time_entries: View spent time
-  permission_manage_versions: Manage versions
-  permission_manage_wiki: Manage wiki
-  permission_manage_categories: Manage issue categories
-  permission_protect_wiki_pages: Protect wiki pages
-  permission_comment_news: Comment news
-  permission_delete_messages: Delete messages
-  permission_select_project_modules: Select project modules
-  permission_manage_documents: Manage documents
-  permission_edit_wiki_pages: Edit wiki pages
-  permission_add_issue_watchers: Add watchers
-  permission_view_gantt: View gantt chart
-  permission_move_issues: Move issues
-  permission_manage_issue_relations: Manage issue relations
-  permission_delete_wiki_pages: Delete wiki pages
-  permission_manage_boards: Manage boards
-  permission_delete_wiki_pages_attachments: Delete attachments
-  permission_view_wiki_edits: View wiki history
-  permission_add_messages: Post messages
-  permission_view_messages: View messages
-  permission_manage_files: Manage files
-  permission_edit_issue_notes: Edit notes
-  permission_manage_news: Manage news
-  permission_view_calendar: View calendrier
-  permission_manage_members: Manage members
-  permission_edit_messages: Edit messages
-  permission_delete_issues: Delete issues
-  permission_view_issue_watchers: View watchers list
-  permission_manage_repository: Manage repository
-  permission_commit_access: Commit access
-  permission_browse_repository: Browse repository
-  permission_view_documents: View documents
-  permission_edit_project: Edit project
-  permission_add_issue_notes: Add notes
-  permission_save_queries: Save queries
-  permission_view_wiki_pages: View wiki
-  permission_rename_wiki_pages: Rename wiki pages
-  permission_edit_time_entries: Edit time logs
-  permission_edit_own_issue_notes: Edit own notes
-  setting_gravatar_enabled: Use Gravatar user icons
-  label_example: Example
-  text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
-  permission_edit_own_messages: Edit own messages
-  permission_delete_own_messages: Delete own messages
-  label_user_activity: "%{value}'s activity"
-  label_updated_time_by: "Updated by %{author} %{age} ago"
-  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
-  setting_diff_max_lines_displayed: Max number of diff lines displayed
-  text_plugin_assets_writable: Plugin assets directory writable
-  warning_attachments_not_saved: "%{count} file(s) could not be saved."
-  button_create_and_continue: Create and continue
-  text_custom_field_possible_values_info: 'One line for each value'
-  label_display: Display
-  field_editable: Editable
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  field_watcher: Watcher
-  setting_openid: Allow OpenID login and registration
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: or login with OpenID
-  field_content: Content
-  label_descending: Descending
-  label_sort: Sort
-  label_ascending: Ascending
-  label_date_from_to: From %{start} to %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
-  text_wiki_page_reassign_children: Reassign child pages to this parent page
-  text_wiki_page_nullify_children: Keep child pages as root pages
-  text_wiki_page_destroy_children: Delete child pages and all their descendants
-  setting_password_min_length: Minimum password length
-  field_group_by: Group results by
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  label_wiki_content_added: Wiki page added
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
-  label_wiki_content_updated: Wiki page updated
-  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
-  permission_add_project: Create project
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  label_view_all_revisions: View all revisions
-  label_tag: Tag
-  label_branch: Branch
-  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
-  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
-  text_journal_changed: "%{label} changed from %{old} to %{new}"
-  text_journal_set_to: "%{label} set to %{value}"
-  text_journal_deleted: "%{label} deleted (%{old})"
-  label_group_plural: Groups
-  label_group: Group
-  label_group_new: New group
-  label_time_entry_plural: Spent time
-  text_journal_added: "%{label} %{value} added"
-  field_active: Active
-  enumeration_system_activity: System Activity
-  permission_delete_issue_watchers: Delete watchers
-  version_status_closed: closed
-  version_status_locked: locked
-  version_status_open: open
-  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
-  label_user_anonymous: Anonymous
-  button_move_and_follow: Move and follow
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_gravatar_default: Default Gravatar image
-  field_sharing: Sharing
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_system: With all projects
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_tree: With project tree
-  label_version_sharing_none: Not shared
-  error_can_not_archive_project: This project can not be archived
-  button_duplicate: Duplicate
-  button_copy_and_follow: Copy and follow
-  label_copy_source: Source
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Same as target
-  label_copy_target: Target
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  error_workflow_copy_source: Please select a source tracker or role
-  label_update_issue_done_ratios: Update issue done ratios
-  setting_start_of_week: Start calendars on
-  permission_view_issues: View Issues
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API access key
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_missing_api_access_key: Missing an API access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  button_show: Show
-  text_line_separated: Multiple values allowed (one line for each value).
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Commit messages encoding
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/97/971a5fcfc90df0e8a64970c648410721b14a9fc9.svn-base
--- /dev/null
+++ b/.svn/pristine/97/971a5fcfc90df0e8a64970c648410721b14a9fc9.svn-base
@@ -0,0 +1,525 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoriesMercurialControllerTest < ActionController::TestCase
+  tests RepositoriesController
+
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :repositories, :enabled_modules
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
+  CHAR_1_HEX = "\xc3\x9c"
+  PRJ_ID     = 3
+  NUM_REV    = 32
+
+  ruby19_non_utf8_pass =
+     (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8')
+
+  def setup
+    User.current = nil
+    @project    = Project.find(PRJ_ID)
+    @repository = Repository::Mercurial.create(
+                      :project => @project,
+                      :url     => REPOSITORY_PATH,
+                      :path_encoding => 'ISO-8859-1'
+                      )
+    assert @repository
+    @diff_c_support = true
+    @char_1        = CHAR_1_HEX.dup
+    @tag_char_1    = "tag-#{CHAR_1_HEX}-00"
+    @branch_char_0 = "branch-#{CHAR_1_HEX}-00"
+    @branch_char_1 = "branch-#{CHAR_1_HEX}-01"
+    if @char_1.respond_to?(:force_encoding)
+      @char_1.force_encoding('UTF-8')
+      @tag_char_1.force_encoding('UTF-8')
+      @branch_char_0.force_encoding('UTF-8')
+      @branch_char_1.force_encoding('UTF-8')
+    end
+  end
+
+  if ruby19_non_utf8_pass
+    puts "TODO: Mercurial functional test fails in Ruby 1.9 " +
+         "and Encoding.default_external is not UTF-8. " +
+         "Current value is '#{Encoding.default_external.to_s}'"
+    def test_fake; assert true end
+  elsif File.directory?(REPOSITORY_PATH)
+
+    def test_get_new
+      @request.session[:user_id] = 1
+      @project.repository.destroy
+      get :new, :project_id => 'subproject1', :repository_scm => 'Mercurial'
+      assert_response :success
+      assert_template 'new'
+      assert_kind_of Repository::Mercurial, assigns(:repository)
+      assert assigns(:repository).new_record?
+    end
+
+    def test_show_root
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal 4, assigns(:entries).size
+      assert assigns(:entries).detect {|e| e.name == 'images'  && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'README'  && e.kind == 'file'}
+      assert_not_nil assigns(:changesets)
+      assert assigns(:changesets).size > 0
+    end
+
+    def test_show_directory
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['images'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name)
+      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
+      assert_not_nil entry
+      assert_equal 'file', entry.kind
+      assert_equal 'images/edit.png', entry.path
+      assert_not_nil assigns(:changesets)
+      assert assigns(:changesets).size > 0
+    end
+
+    def test_show_at_given_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      [0, '0', '0885933ad4f6'].each do |r1|
+        get :show, :id => PRJ_ID, :path => repository_path_hash(['images'])[:param],
+            :rev => r1
+        assert_response :success
+        assert_template 'show'
+        assert_not_nil assigns(:entries)
+        assert_equal ['delete.png'], assigns(:entries).collect(&:name)
+        assert_not_nil assigns(:changesets)
+        assert assigns(:changesets).size > 0
+      end
+    end
+
+    def test_show_directory_sql_escape_percent
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      [13, '13', '3a330eb32958'].each do |r1|
+        get :show, :id => PRJ_ID,
+            :path => repository_path_hash(['sql_escape', 'percent%dir'])[:param],
+            :rev => r1
+        assert_response :success
+        assert_template 'show'
+
+        assert_not_nil assigns(:entries)
+        assert_equal ['percent%file1.txt', 'percentfile1.txt'],
+                     assigns(:entries).collect(&:name)
+        changesets = assigns(:changesets)
+        assert_not_nil changesets
+        assert assigns(:changesets).size > 0
+        assert_equal %w(13 11 10 9), changesets.collect(&:revision)
+      end
+    end
+
+    def test_show_directory_latin_1_path
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      [21, '21', 'adf805632193'].each do |r1|
+        get :show, :id => PRJ_ID,
+            :path => repository_path_hash(['latin-1-dir'])[:param],
+            :rev => r1
+        assert_response :success
+        assert_template 'show'
+
+        assert_not_nil assigns(:entries)
+        assert_equal ["make-latin-1-file.rb",
+                      "test-#{@char_1}-1.txt",
+                      "test-#{@char_1}-2.txt",
+                      "test-#{@char_1}.txt"], assigns(:entries).collect(&:name)
+        changesets = assigns(:changesets)
+        assert_not_nil changesets
+        assert_equal %w(21 20 19 18 17), changesets.collect(&:revision)
+      end
+    end
+
+    def show_should_show_branch_selection_form
+      @repository.fetch_changesets
+      @project.reload
+      get :show, :id => PRJ_ID
+      assert_tag 'form', :attributes => {:id => 'revision_selector', :action => '/projects/subproject1/repository/show'}
+      assert_tag 'select', :attributes => {:name => 'branch'},
+        :child => {:tag => 'option', :attributes => {:value => 'test-branch-01'}},
+        :parent => {:tag => 'form', :attributes => {:id => 'revision_selector'}}
+    end
+
+    def test_show_branch
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+       [
+          'default',
+          @branch_char_1,
+          'branch (1)[2]&,%.-3_4',
+          @branch_char_0,
+          'test_branch.latin-1',
+          'test-branch-00',
+      ].each do |bra|
+        get :show, :id => PRJ_ID, :rev => bra
+        assert_response :success
+        assert_template 'show'
+        assert_not_nil assigns(:entries)
+        assert assigns(:entries).size > 0
+        assert_not_nil assigns(:changesets)
+        assert assigns(:changesets).size > 0
+      end
+    end
+
+    def test_show_tag
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+       [
+        @tag_char_1,
+        'tag_test.00',
+        'tag-init-revision'
+      ].each do |tag|
+        get :show, :id => PRJ_ID, :rev => tag
+        assert_response :success
+        assert_template 'show'
+        assert_not_nil assigns(:entries)
+        assert assigns(:entries).size > 0
+        assert_not_nil assigns(:changesets)
+        assert assigns(:changesets).size > 0
+      end
+    end
+
+    def test_changes
+      get :changes, :id => PRJ_ID,
+          :path => repository_path_hash(['images', 'edit.png'])[:param]
+      assert_response :success
+      assert_template 'changes'
+      assert_tag :tag => 'h2', :content => 'edit.png'
+    end
+
+    def test_entry_show
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param]
+      assert_response :success
+      assert_template 'entry'
+      # Line 10
+      assert_tag :tag => 'th',
+                 :content => '10',
+                 :attributes => { :class => 'line-num' },
+                 :sibling => { :tag => 'td', :content => /WITHOUT ANY WARRANTY/ }
+    end
+
+    def test_entry_show_latin_1_path
+      [21, '21', 'adf805632193'].each do |r1|
+        get :entry, :id => PRJ_ID,
+            :path => repository_path_hash(['latin-1-dir', "test-#{@char_1}-2.txt"])[:param],
+            :rev => r1
+        assert_response :success
+        assert_template 'entry'
+        assert_tag :tag => 'th',
+                 :content => '1',
+                 :attributes => { :class => 'line-num' },
+                 :sibling => { :tag => 'td',
+                               :content => /Mercurial is a distributed version control system/ }
+      end
+    end
+
+    def test_entry_show_latin_1_contents
+      with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
+        [27, '27', '7bbf4c738e71'].each do |r1|
+          get :entry, :id => PRJ_ID,
+              :path => repository_path_hash(['latin-1-dir', "test-#{@char_1}.txt"])[:param],
+              :rev => r1
+          assert_response :success
+          assert_template 'entry'
+          assert_tag :tag => 'th',
+                 :content => '1',
+                 :attributes => { :class => 'line-num' },
+                 :sibling => { :tag => 'td',
+                               :content => /test-#{@char_1}.txt/ }
+        end
+      end
+    end
+
+    def test_entry_download
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param],
+          :format => 'raw'
+      assert_response :success
+      # File content
+      assert @response.body.include?('WITHOUT ANY WARRANTY')
+    end
+
+    def test_entry_binary_force_download
+      get :entry, :id => PRJ_ID, :rev => 1,
+          :path => repository_path_hash(['images', 'edit.png'])[:param]
+      assert_response :success
+      assert_equal 'image/png', @response.content_type
+    end
+
+    def test_directory_entry
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entry)
+      assert_equal 'sources', assigns(:entry).name
+    end
+
+    def test_diff
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      [4, '4', 'def6d2f1254a'].each do |r1|
+        # Full diff of changeset 4
+        ['inline', 'sbs'].each do |dt|
+          get :diff, :id => PRJ_ID, :rev => r1, :type => dt
+          assert_response :success
+          assert_template 'diff'
+          if @diff_c_support
+            # Line 22 removed
+            assert_tag :tag => 'th',
+                       :content => '22',
+                       :sibling => { :tag => 'td',
+                                     :attributes => { :class => /diff_out/ },
+                                     :content => /def remove/ }
+            assert_tag :tag => 'h2', :content => /4:def6d2f1254a/
+          end
+        end
+      end
+    end
+
+    def test_diff_two_revs
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      [2, '400bb8672109', '400', 400].each do |r1|
+        [4, 'def6d2f1254a'].each do |r2|
+          ['inline', 'sbs'].each do |dt|
+            get :diff,
+                :id     => PRJ_ID,
+                :rev    => r1,
+                :rev_to => r2,
+                :type => dt
+            assert_response :success
+            assert_template 'diff'
+            diff = assigns(:diff)
+            assert_not_nil diff
+            assert_tag :tag => 'h2',
+                       :content => /4:def6d2f1254a 2:400bb8672109/
+          end
+        end
+      end
+    end
+
+    def test_diff_latin_1_path
+      with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
+        [21, 'adf805632193'].each do |r1|
+          ['inline', 'sbs'].each do |dt|
+            get :diff, :id => PRJ_ID, :rev => r1, :type => dt
+            assert_response :success
+            assert_template 'diff'
+            assert_tag :tag => 'thead',
+                       :descendant => {
+                         :tag => 'th',
+                         :attributes => { :class => 'filename' } ,
+                         :content => /latin-1-dir\/test-#{@char_1}-2.txt/ ,
+                        },
+                       :sibling => {
+                         :tag => 'tbody',
+                         :descendant => {
+                            :tag => 'td',
+                            :attributes => { :class => /diff_in/ },
+                            :content => /It is written in Python/
+                         }
+                       }
+          end
+        end
+      end
+    end
+
+    def test_diff_should_show_modified_filenames
+      get :diff, :id => PRJ_ID, :rev => '400bb8672109', :type => 'inline'
+      assert_response :success
+      assert_template 'diff'
+      assert_select 'th.filename', :text => 'sources/watchers_controller.rb'
+    end
+
+    def test_diff_should_show_deleted_filenames
+      get :diff, :id => PRJ_ID, :rev => 'b3a615152df8', :type => 'inline'
+      assert_response :success
+      assert_template 'diff'
+      assert_select 'th.filename', :text => 'sources/welcome_controller.rb'
+    end
+
+    def test_annotate
+      get :annotate, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param]
+      assert_response :success
+      assert_template 'annotate'
+
+      # Line 22, revision 4:def6d2f1254a
+      assert_select 'tr' do
+        assert_select 'th.line-num', :text => '22'
+        assert_select 'td.revision', :text => '4:def6d2f1254a'
+        assert_select 'td.author', :text => 'jsmith'
+        assert_select 'td', :text => /remove_watcher/
+      end
+    end
+
+    def test_annotate_not_in_tip
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :annotate, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'welcome_controller.rb'])[:param]
+      assert_response 404
+      assert_error_tag :content => /was not found/
+    end
+
+    def test_annotate_at_given_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      [2, '400bb8672109', '400', 400].each do |r1|
+        get :annotate, :id => PRJ_ID, :rev => r1,
+            :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param]
+        assert_response :success
+        assert_template 'annotate'
+        assert_tag :tag => 'h2', :content => /@ 2:400bb8672109/
+      end
+    end
+
+    def test_annotate_latin_1_path
+      [21, '21', 'adf805632193'].each do |r1|
+        get :annotate, :id => PRJ_ID,
+            :path => repository_path_hash(['latin-1-dir', "test-#{@char_1}-2.txt"])[:param],
+            :rev => r1
+        assert_response :success
+        assert_template 'annotate'
+        assert_tag :tag => 'th',
+                 :content => '1',
+                 :attributes => { :class => 'line-num' },
+                 :sibling =>
+                       {
+                         :tag => 'td',
+                         :attributes => { :class => 'revision' },
+                         :child => { :tag => 'a', :content => '20:709858aafd1b' }
+                       }
+        assert_tag :tag => 'th',
+                 :content => '1',
+                 :attributes => { :class => 'line-num' },
+                 :sibling =>
+                       {
+                          :tag     => 'td'    ,
+                          :content => 'jsmith' ,
+                          :attributes => { :class   => 'author' },
+                        }
+        assert_tag :tag => 'th',
+                 :content => '1',
+                 :attributes => { :class => 'line-num' },
+                 :sibling => { :tag => 'td',
+                               :content => /Mercurial is a distributed version control system/ }
+
+      end
+    end
+
+    def test_annotate_latin_1_contents
+      with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
+        [27, '7bbf4c738e71'].each do |r1|
+          get :annotate, :id => PRJ_ID,
+              :path => repository_path_hash(['latin-1-dir', "test-#{@char_1}.txt"])[:param],
+              :rev => r1
+          assert_tag :tag => 'th',
+                     :content => '1',
+                     :attributes => { :class => 'line-num' },
+                     :sibling => { :tag => 'td',
+                                   :content => /test-#{@char_1}.txt/ }
+        end
+      end
+    end
+
+    def test_empty_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['', ' ', nil].each do |r|
+        get :revision, :id => PRJ_ID, :rev => r
+        assert_response 404
+        assert_error_tag :content => /was not found/
+      end
+    end
+
+    def test_destroy_valid_repository
+      @request.session[:user_id] = 1 # admin
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      assert_equal NUM_REV, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+
+    def test_destroy_invalid_repository
+      @request.session[:user_id] = 1 # admin
+      @project.repository.destroy
+      @repository = Repository::Mercurial.create!(
+                      :project => Project.find(PRJ_ID),
+                      :url     => "/invalid",
+                      :path_encoding => 'ISO-8859-1'
+                      )
+      @repository.fetch_changesets
+      assert_equal 0, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+  else
+    puts "Mercurial test repository NOT FOUND. Skipping functional tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/97/972ebe702c3563a70215eddbffbce5d35137072c.svn-base
--- a/.svn/pristine/97/972ebe702c3563a70215eddbffbce5d35137072c.svn-base
+++ /dev/null
@@ -1,177 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class MyController < ApplicationController
-  before_filter :require_login
-
-  helper :issues
-  helper :users
-  helper :custom_fields
-
-  BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
-             'issuesreportedbyme' => :label_reported_issues,
-             'issueswatched' => :label_watched_issues,
-             'news' => :label_news_latest,
-             'calendar' => :label_calendar,
-             'documents' => :label_document_plural,
-             'timelog' => :label_spent_time
-           }.merge(Redmine::Views::MyPage::Block.additional_blocks).freeze
-
-  DEFAULT_LAYOUT = {  'left' => ['issuesassignedtome'],
-                      'right' => ['issuesreportedbyme']
-                   }.freeze
-
-  verify :xhr => true,
-         :only => [:add_block, :remove_block, :order_blocks]
-
-  def index
-    page
-    render :action => 'page'
-  end
-
-  # Show user's page
-  def page
-    @user = User.current
-    @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT
-  end
-
-  # Edit user's account
-  def account
-    @user = User.current
-    @pref = @user.pref
-    if request.post?
-      @user.safe_attributes = params[:user]
-      @user.pref.attributes = params[:pref]
-      @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
-      if @user.save
-        @user.pref.save
-        @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
-        set_language_if_valid @user.language
-        flash[:notice] = l(:notice_account_updated)
-        redirect_to :action => 'account'
-        return
-      end
-    end
-  end
-
-  # Manage user's password
-  def password
-    @user = User.current
-    unless @user.change_password_allowed?
-      flash[:error] = l(:notice_can_t_change_password)
-      redirect_to :action => 'account'
-      return
-    end
-    if request.post?
-      if @user.check_password?(params[:password])
-        @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
-        if @user.save
-          flash[:notice] = l(:notice_account_password_updated)
-          redirect_to :action => 'account'
-        end
-      else
-        flash[:error] = l(:notice_account_wrong_password)
-      end
-    end
-  end
-
-  # Create a new feeds key
-  def reset_rss_key
-    if request.post?
-      if User.current.rss_token
-        User.current.rss_token.destroy
-        User.current.reload
-      end
-      User.current.rss_key
-      flash[:notice] = l(:notice_feeds_access_key_reseted)
-    end
-    redirect_to :action => 'account'
-  end
-
-  # Create a new API key
-  def reset_api_key
-    if request.post?
-      if User.current.api_token
-        User.current.api_token.destroy
-        User.current.reload
-      end
-      User.current.api_key
-      flash[:notice] = l(:notice_api_access_key_reseted)
-    end
-    redirect_to :action => 'account'
-  end
-
-  # User's page layout configuration
-  def page_layout
-    @user = User.current
-    @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup
-    @block_options = []
-    BLOCKS.each {|k, v| @block_options << [l("my.blocks.#{v}", :default => [v, v.to_s.humanize]), k.dasherize]}
-  end
-
-  # Add a block to user's page
-  # The block is added on top of the page
-  # params[:block] : id of the block to add
-  def add_block
-    block = params[:block].to_s.underscore
-    (render :nothing => true; return) unless block && (BLOCKS.keys.include? block)
-    @user = User.current
-    layout = @user.pref[:my_page_layout] || {}
-    # remove if already present in a group
-    %w(top left right).each {|f| (layout[f] ||= []).delete block }
-    # add it on top
-    layout['top'].unshift block
-    @user.pref[:my_page_layout] = layout
-    @user.pref.save
-    render :partial => "block", :locals => {:user => @user, :block_name => block}
-  end
-
-  # Remove a block to user's page
-  # params[:block] : id of the block to remove
-  def remove_block
-    block = params[:block].to_s.underscore
-    @user = User.current
-    # remove block in all groups
-    layout = @user.pref[:my_page_layout] || {}
-    %w(top left right).each {|f| (layout[f] ||= []).delete block }
-    @user.pref[:my_page_layout] = layout
-    @user.pref.save
-    render :nothing => true
-  end
-
-  # Change blocks order on user's page
-  # params[:group] : group to order (top, left or right)
-  # params[:list-(top|left|right)] : array of block ids of the group
-  def order_blocks
-    group = params[:group]
-    @user = User.current
-    if group.is_a?(String)
-      group_items = (params["list-#{group}"] || []).collect(&:underscore)
-      if group_items and group_items.is_a? Array
-        layout = @user.pref[:my_page_layout] || {}
-        # remove group blocks if they are presents in other groups
-        %w(top left right).each {|f|
-          layout[f] = (layout[f] || []) - group_items
-        }
-        layout[group] = group_items
-        @user.pref[:my_page_layout] = layout
-        @user.pref.save
-      end
-    end
-    render :nothing => true
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/97/974cf973fb6190d37c5771be66a30e7428cae84a.svn-base
--- a/.svn/pristine/97/974cf973fb6190d37c5771be66a30e7428cae84a.svn-base
+++ /dev/null
@@ -1,119 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class RepositoryBazaarTest < ActiveSupport::TestCase
-  fixtures :projects
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository/trunk').to_s
-  REPOSITORY_PATH.gsub!(/\/+/, '/')
-  NUM_REV = 4
-
-  def setup
-    @project = Project.find(3)
-    @repository = Repository::Bazaar.create(
-              :project => @project, :url => "file:///#{REPOSITORY_PATH}",
-              :log_encoding => 'UTF-8')
-    assert @repository
-  end
-
-  if File.directory?(REPOSITORY_PATH)
-    def test_fetch_changesets_from_scratch
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_equal 9, @repository.changes.count
-      assert_equal 'Initial import', @repository.changesets.find_by_revision('1').comments
-    end
-
-    def test_fetch_changesets_incremental
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      # Remove changesets with revision > 5
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 2}
-      @project.reload
-      assert_equal 2, @repository.changesets.count
-
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-    end
-
-    def test_entries
-      entries = @repository.entries
-      assert_equal 2, entries.size
-
-      assert_equal 'dir', entries[0].kind
-      assert_equal 'directory', entries[0].name
-
-      assert_equal 'file', entries[1].kind
-      assert_equal 'doc-mkdir.txt', entries[1].name
-    end
-
-    def test_entries_in_subdirectory
-      entries = @repository.entries('directory')
-      assert_equal 3, entries.size
-
-      assert_equal 'file', entries.last.kind
-      assert_equal 'edit.png', entries.last.name
-    end
-
-    def test_previous
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      changeset = @repository.find_changeset_by_name('3')
-      assert_equal @repository.find_changeset_by_name('2'), changeset.previous
-    end
-
-    def test_previous_nil
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      changeset = @repository.find_changeset_by_name('1')
-      assert_nil changeset.previous
-    end
-
-    def test_next
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      changeset = @repository.find_changeset_by_name('2')
-      assert_equal @repository.find_changeset_by_name('3'), changeset.next
-    end
-
-    def test_next_nil
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      changeset = @repository.find_changeset_by_name('4')
-      assert_nil changeset.next
-    end
-  else
-    puts "Bazaar test repository NOT FOUND. Skipping unit tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/97/978f900709ed8de466a8e142aefeff25cb8293df.svn-base
--- /dev/null
+++ b/.svn/pristine/97/978f900709ed8de466a8e142aefeff25cb8293df.svn-base
@@ -0,0 +1,70 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module SearchHelper
+  def highlight_tokens(text, tokens)
+    return text unless text && tokens && !tokens.empty?
+    re_tokens = tokens.collect {|t| Regexp.escape(t)}
+    regexp = Regexp.new "(#{re_tokens.join('|')})", Regexp::IGNORECASE
+    result = ''
+    text.split(regexp).each_with_index do |words, i|
+      if result.length > 1200
+        # maximum length of the preview reached
+        result << '...'
+        break
+      end
+      words = words.mb_chars
+      if i.even?
+        result << h(words.length > 100 ? "#{words.slice(0..44)} ... #{words.slice(-45..-1)}" : words)
+      else
+        t = (tokens.index(words.downcase) || 0) % 4
+        result << content_tag('span', h(words), :class => "highlight token-#{t}")
+      end
+    end
+    result.html_safe
+  end
+
+  def type_label(t)
+    l("label_#{t.singularize}_plural", :default => t.to_s.humanize)
+  end
+
+  def project_select_tag
+    options = [[l(:label_project_all), 'all']]
+    options << [l(:label_my_projects), 'my_projects'] unless User.current.memberships.empty?
+    options << [l(:label_and_its_subprojects, @project.name), 'subprojects'] unless @project.nil? || @project.descendants.active.empty?
+    options << [@project.name, ''] unless @project.nil?
+    label_tag("scope", l(:description_project_scope), :class => "hidden-for-sighted") +
+    select_tag('scope', options_for_select(options, params[:scope].to_s)) if options.size > 1
+  end
+
+  def render_results_by_type(results_by_type)
+    links = []
+    # Sorts types by results count
+    results_by_type.keys.sort {|a, b| results_by_type[b] <=> results_by_type[a]}.each do |t|
+      c = results_by_type[t]
+      next if c == 0
+      text = "#{type_label(t)} (#{c})"
+      links << link_to(h(text), :q => params[:q], :titles_only => params[:titles_only],
+                       :all_words => params[:all_words], :scope => params[:scope], t => 1)
+    end
+    ('<ul>'.html_safe +
+        links.map {|link| content_tag('li', link)}.join(' ').html_safe + 
+        '</ul>'.html_safe) unless links.empty?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/97/97df7b6827e22c2665eace13dd5952db27af0ff3.svn-base
--- /dev/null
+++ b/.svn/pristine/97/97df7b6827e22c2665eace13dd5952db27af0ff3.svn-base
@@ -0,0 +1,123 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssueStatusesControllerTest < ActionController::TestCase
+  fixtures :issue_statuses, :issues, :users
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 1 # admin
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+  end
+  
+  def test_index_by_anonymous_should_redirect_to_login_form
+    @request.session[:user_id] = nil
+    get :index
+    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fissue_statuses'
+  end
+  
+  def test_index_by_user_should_respond_with_406
+    @request.session[:user_id] = 2
+    get :index
+    assert_response 406
+  end
+
+  def test_new
+    get :new
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_create
+    assert_difference 'IssueStatus.count' do
+      post :create, :issue_status => {:name => 'New status'}
+    end
+    assert_redirected_to :action => 'index'
+    status = IssueStatus.order('id DESC').first
+    assert_equal 'New status', status.name
+  end
+
+  def test_create_with_failure
+    post :create, :issue_status => {:name => ''}
+    assert_response :success
+    assert_template 'new'
+    assert_error_tag :content => /name can&#x27;t be blank/i
+  end
+
+  def test_edit
+    get :edit, :id => '3'
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_update
+    put :update, :id => '3', :issue_status => {:name => 'Renamed status'}
+    assert_redirected_to :action => 'index'
+    status = IssueStatus.find(3)
+    assert_equal 'Renamed status', status.name
+  end
+
+  def test_update_with_failure
+    put :update, :id => '3', :issue_status => {:name => ''}
+    assert_response :success
+    assert_template 'edit'
+    assert_error_tag :content => /name can&#x27;t be blank/i
+  end
+
+  def test_destroy
+    Issue.delete_all("status_id = 1")
+
+    assert_difference 'IssueStatus.count', -1 do
+      delete :destroy, :id => '1'
+    end
+    assert_redirected_to :action => 'index'
+    assert_nil IssueStatus.find_by_id(1)
+  end
+
+  def test_destroy_should_block_if_status_in_use
+    assert_not_nil Issue.find_by_status_id(1)
+
+    assert_no_difference 'IssueStatus.count' do
+      delete :destroy, :id => '1'
+    end
+    assert_redirected_to :action => 'index'
+    assert_not_nil IssueStatus.find_by_id(1)
+  end
+
+  def test_update_issue_done_ratio_with_issue_done_ratio_set_to_issue_field
+    with_settings :issue_done_ratio => 'issue_field' do
+      post :update_issue_done_ratio
+      assert_match /not updated/, flash[:error].to_s
+      assert_redirected_to '/issue_statuses'
+    end
+  end
+
+  def test_update_issue_done_ratio_with_issue_done_ratio_set_to_issue_status
+    with_settings :issue_done_ratio => 'issue_status' do
+      post :update_issue_done_ratio
+      assert_match /Issue done ratios updated/, flash[:notice].to_s
+      assert_redirected_to '/issue_statuses'
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/97/97e5af17b0ff620e9c12200e0ea40a146395b3bd.svn-base
--- /dev/null
+++ b/.svn/pristine/97/97e5af17b0ff620e9c12200e0ea40a146395b3bd.svn-base
@@ -0,0 +1,68 @@
+<% diff = Redmine::UnifiedDiff.new(
+            diff, :type => diff_type,
+            :max_lines => Setting.diff_max_lines_displayed.to_i,
+            :style => diff_style) -%>
+
+<% diff.each do |table_file| -%>
+<div class="autoscroll">
+<% if diff.diff_type == 'sbs' -%>
+<table class="filecontent">
+<thead>
+<tr>
+  <th colspan="4" class="filename">
+    <%= table_file.file_name %>
+  </th>
+</tr>
+</thead>
+<tbody>
+<% table_file.each_line do |spacing, line| -%>
+<% if spacing -%>
+<tr class="spacing">
+  <th class="line-num">...</th><td></td><th class="line-num">...</th><td></td>
+</tr>
+<% end -%>
+<tr>
+  <th class="line-num"><%= line.nb_line_left %></th>
+  <td class="line-code <%= line.type_diff_left %>">
+    <pre><%= line.html_line_left.html_safe %></pre>
+  </td>
+  <th class="line-num"><%= line.nb_line_right %></th>
+  <td class="line-code <%= line.type_diff_right %>">
+    <pre><%= line.html_line_right.html_safe %></pre>
+  </td>
+</tr>
+<% end -%>
+</tbody>
+</table>
+
+<% else -%>
+<table class="filecontent">
+<thead>
+  <tr>
+    <th colspan="3" class="filename">
+      <%= table_file.file_name %>
+    </th>
+  </tr>
+</thead>
+<tbody>
+<% table_file.each_line do |spacing, line| %>
+<% if spacing -%>
+<tr class="spacing">
+  <th class="line-num">...</th><th class="line-num">...</th><td></td>
+</tr>
+<% end -%>
+<tr>
+  <th class="line-num"><%= line.nb_line_left %></th>
+  <th class="line-num"><%= line.nb_line_right %></th>
+  <td class="line-code <%= line.type_diff %>">
+    <pre><%= line.html_line.html_safe %></pre>
+  </td>
+</tr>
+<% end -%>
+</tbody>
+</table>
+<% end -%>
+</div>
+<% end -%>
+
+<%= l(:text_diff_truncated) if diff.truncated? %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/97/97f9ea0ada27476051514e5aebe9f3fa15fc996b.svn-base
--- a/.svn/pristine/97/97f9ea0ada27476051514e5aebe9f3fa15fc996b.svn-base
+++ /dev/null
@@ -1,123 +0,0 @@
-= CodeRay
-
-Tired of blue'n'gray? Try the original version of this documentation on
-coderay.rubychan.de[http://coderay.rubychan.de/doc/] :-)
-
-== About
-
-CodeRay is a Ruby library for syntax highlighting.
-
-You put your code in, and you get it back colored; Keywords, strings,
-floats, comments - all in different colors. And with line numbers.
-
-*Syntax* *Highlighting*...
-* makes code easier to read and maintain
-* lets you detect syntax errors faster
-* helps you to understand the syntax of a language
-* looks nice
-* is what everybody wants to have on their website
-* solves all your problems and makes the girls run after you
-
-
-== Installation
-
- % gem install coderay
-
-
-=== Dependencies
-
-CodeRay needs Ruby 1.8.7+ or 1.9.2+. It also runs on Rubinius and JRuby.
-
-
-== Example Usage
-
- require 'coderay'
- 
- html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table)
-
-
-== Documentation
-
-See CodeRay.
-
-
-== Credits
-
-=== Special Thanks to
-
-* licenser (Heinz N. Gies) for ending my QBasic career, inventing the Coder
-  project and the input/output plugin system.
-  CodeRay would not exist without him.
-* bovi (Daniel Bovensiepen) for helping me out on various occasions.
-
-=== Thanks to
-
-* Caleb Clausen for writing RubyLexer (see
-  http://rubyforge.org/projects/rubylexer) and lots of very interesting mail
-  traffic
-* birkenfeld (Georg Brandl) and mitsuhiku (Arnim Ronacher) for PyKleur, now pygments.
-  You guys rock!
-* Jamis Buck for writing Syntax (see http://rubyforge.org/projects/syntax)
-  I got some useful ideas from it.
-* Doug Kearns and everyone else who worked on ruby.vim - it not only helped me
-  coding CodeRay, but also gave me a wonderful target to reach for the Ruby
-  scanner.
-* everyone who uses CodeBB on http://www.rubyforen.de and http://www.python-forum.de
-* iGEL, magichisoka, manveru, WoNÃ¡Do and everyone I forgot from rubyforen.de
-* Dethix from ruby-mine.de
-* zickzackw
-* Dookie (who is no longer with us...) and Leonidas from http://www.python-forum.de
-* Andreas Schwarz for finding out that CaseIgnoringWordList was not case
-  ignoring! Such things really make you write tests.
-* closure for the first version of the Scheme scanner.
-* Stefan Walk for the first version of the JavaScript and PHP scanners.
-* Josh Goebel for another version of the JavaScript scanner, a SQL and a Diff scanner.
-* Jonathan Younger for pointing out the licence confusion caused by wrong LICENSE file.
-* Jeremy Hinegardner for finding the shebang-on-empty-file bug in FileType.
-* Charles Oliver Nutter and Yehuda Katz for helping me benchmark CodeRay on JRuby.
-* Andreas Neuhaus for pointing out a markup bug in coderay/for_redcloth.
-* 0xf30fc7 for the FileType patch concerning Delphi file extensions.
-* The folks at redmine.org - thank you for using and fixing CodeRay!
-* Keith Pitt for his SQL scanners
-* Rob Aldred for the terminal encoder
-* Trans for pointing out $DEBUG dependencies
-* Flameeyes for finding that Term::ANSIColor was obsolete
-* matz and all Ruby gods and gurus
-* The inventors of: the computer, the internet, the true color display, HTML &
-  CSS, VIM, Ruby, pizza, microwaves, guitars, scouting, programming, anime, 
-  manga, coke and green ice tea.
-
-Where would we be without all those people?
-
-=== Created using
-
-* Ruby[http://ruby-lang.org/]
-* Chihiro (my Sony VAIO laptop); Henrietta (my old MacBook);
-  Triella, born Rico (my new MacBook); as well as
-  Seras and Hikari (my PCs)
-* RDE[http://homepage2.nifty.com/sakazuki/rde_e.html],
-  VIM[http://vim.org] and TextMate[http://macromates.com]
-* Subversion[http://subversion.tigris.org/]
-* Redmine[http://redmine.org/]
-* Firefox[http://www.mozilla.org/products/firefox/],
-  Firebug[http://getfirebug.com/], Safari[http://www.apple.com/safari/], and
-  Thunderbird[http://www.mozilla.org/products/thunderbird/]
-* RubyGems[http://docs.rubygems.org/] and Rake[http://rake.rubyforge.org/]
-* TortoiseSVN[http://tortoisesvn.tigris.org/] using Apache via
-  XAMPP[http://www.apachefriends.org/en/xampp.html]
-* RDoc (though I'm quite unsatisfied with it)
-* Microsoft Windows (yes, I confess!) and MacOS X
-* GNUWin32, MinGW and some other tools to make the shell under windows a bit
-  less useless
-* Term::ANSIColor[http://term-ansicolor.rubyforge.org/]
-* PLEAC[http://pleac.sourceforge.net/] code examples
-* Github
-* Travis CI (http://travis-ci.org/rubychan/github)
-
-=== Free
-
-* As you can see, CodeRay was created under heavy use of *free* software.
-* So CodeRay is also *free*.
-* If you use CodeRay to create software, think about making this software
-  *free*, too.
-* Thanks :)
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/98/9804b3e3abfd00a58dec9be4b531677efbf34d66.svn-base
--- /dev/null
+++ b/.svn/pristine/98/9804b3e3abfd00a58dec9be4b531677efbf34d66.svn-base
@@ -0,0 +1,76 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class MenuManagerTest < ActionController::IntegrationTest
+  include Redmine::I18n
+
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  def test_project_menu_with_specific_locale
+    get 'projects/ecookbook/issues', { }, 'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
+
+    assert_tag :div, :attributes => { :id => 'main-menu' },
+                     :descendant => { :tag => 'li', :child => { :tag => 'a', :content => ll('fr', :label_activity),
+                                                                             :attributes => { :href => '/projects/ecookbook/activity',
+                                                                                              :class => 'activity' } } }
+    assert_tag :div, :attributes => { :id => 'main-menu' },
+                     :descendant => { :tag => 'li', :child => { :tag => 'a', :content => ll('fr', :label_issue_plural),
+                                                                             :attributes => { :href => '/projects/ecookbook/issues',
+                                                                                              :class => 'issues selected' } } }
+  end
+
+  def test_project_menu_with_additional_menu_items
+    Setting.default_language = 'en'
+    assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do
+      Redmine::MenuManager.map :project_menu do |menu|
+        menu.push :foo, { :controller => 'projects', :action => 'show' }, :caption => 'Foo'
+        menu.push :bar, { :controller => 'projects', :action => 'show' }, :before => :activity
+        menu.push :hello, { :controller => 'projects', :action => 'show' }, :caption => Proc.new {|p| p.name.upcase }, :after => :bar
+      end
+
+      get 'projects/ecookbook'
+      assert_tag :div, :attributes => { :id => 'main-menu' },
+                       :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Foo',
+                                                                               :attributes => { :class => 'foo' } } }
+
+      assert_tag :div, :attributes => { :id => 'main-menu' },
+                       :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Bar',
+                                                                               :attributes => { :class => 'bar' } },
+                                                      :before => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' } } }
+
+      assert_tag :div, :attributes => { :id => 'main-menu' },
+                       :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK',
+                                                                               :attributes => { :class => 'hello' } },
+                                                      :before => { :tag => 'li', :child => { :tag => 'a', :content => 'Activity' } } }
+
+      # Remove the menu items
+      Redmine::MenuManager.map :project_menu do |menu|
+        menu.delete :foo
+        menu.delete :bar
+        menu.delete :hello
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/98/9854c7d9b7d9f49fb2310cc42c6a24b76ec835ef.svn-base
--- a/.svn/pristine/98/9854c7d9b7d9f49fb2310cc42c6a24b76ec835ef.svn-base
+++ /dev/null
@@ -1,130 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// Translator: Raden Prabowo, <cakbowo@gmail.com> 
-
-// full day names
-Calendar._DN = new Array
-("Minggu",
- "Senin",
- "Selasa",
- "Rabu",
- "Kamis",
- "Jumat",
- "Sabtu",
- "Minggu");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Ming",
- "Sen",
- "Sel",
- "Rab",
- "Kam",
- "Jum",
- "Sab",
- "Ming");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("Januari",
- "Februari",
- "Maret",
- "April",
- "Mei",
- "Juni",
- "Juli",
- "Agustus",
- "September",
- "Oktober",
- "November",
- "Desember");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "Mar",
- "Apr",
- "Mei",
- "Jun",
- "Jul",
- "Agu",
- "Sep",
- "Okt",
- "Nov",
- "Des");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Mengenai kalender";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"Versi terbaru terdapat di: http://www.dynarch.com/projects/calendar/\n" +
-"Disebarkan dibawah lisensi GNU LGPL.  Lihat http://gnu.org/licenses/lgpl.html untuk detil." +
-"\n\n" +
-"Pemilihan tanggal:\n" +
-"- Gunakan tombol \xab, \xbb untuk memilih tahun\n" +
-"- Gunakan tombol " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " untuk memilih bulan\n" +
-"- Tekan terus tombol kanan pada mouse atau salah satu tombol diatas untuk memilih lebih cepat.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Pemilihan waktu:\n" +
-"- Klik bagian waktu untuk menaikkan\n" +
-"- atau Shift-klick untuk menurunkan\n" +
-"- atau klik dan geser untuk pemilihan yang lebih cepat.";
-
-Calendar._TT["PREV_YEAR"] = "Tahun sebelumnya. (tekan terus untuk menu)";
-Calendar._TT["PREV_MONTH"] = "Bulan sebelumnya. (tekan terus untuk menu)";
-Calendar._TT["GO_TODAY"] = "Ke Hari ini";
-Calendar._TT["NEXT_MONTH"] = "Bulan berikutnya. (tekan terus untuk menu)";
-Calendar._TT["NEXT_YEAR"] = "Tahun berikutnya. (tekan terus untuk menu)";
-Calendar._TT["SEL_DATE"] = "Pilih tanggal";
-Calendar._TT["DRAG_TO_MOVE"] = "Geser untuk menggerakkan";
-Calendar._TT["PART_TODAY"] = " (hari ini)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Tampilkan %s lebih dulu";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Tutup";
-Calendar._TT["TODAY"] = "Hari ini";
-Calendar._TT["TIME_PART"] = "(Shift-)Click atau geser untuk mengubah nilai";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
-//Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b";
-
-Calendar._TT["WK"] = "mg";
-Calendar._TT["TIME"] = "Waktu:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/98/9881063ed20b5e2fe47d9d6b91d54ab72efcf5ef.svn-base
--- a/.svn/pristine/98/9881063ed20b5e2fe47d9d6b91d54ab72efcf5ef.svn-base
+++ /dev/null
@@ -1,40 +0,0 @@
-<% form_tag({:action => 'edit'}) do %>
-
-<div class="box tabular settings">
-<p><%= setting_text_field :app_title, :size => 30 %></p>
-
-<p><%= setting_text_area :welcome_text, :cols => 60, :rows => 5, :class => 'wiki-edit' %></p>
-<%= wikitoolbar_for 'settings_welcome_text' %>
-
-<p><%= setting_text_field :attachment_max_size, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %></p>
-
-<p><%= setting_text_field :per_page_options, :size => 20 %><br />
-<em><%= l(:text_comma_separated) %></em></p>
-
-<p><%= setting_text_field :activity_days_default, :size => 6 %> <%= l(:label_day_plural) %></p>
-
-<p><%= setting_text_field :host_name, :size => 60 %><br />
-<em><%= l(:label_example) %>: <%= @guessed_host_and_path %></em></p>
-
-<p><%= setting_select :protocol, [['HTTP', 'http'], ['HTTPS', 'https']] %></p>
-
-<p><%= setting_select :text_formatting, Redmine::WikiFormatting.format_names.collect{|name| [name, name.to_s]}, :blank => :label_none %></p>
-
-<p><%= setting_check_box :cache_formatted_text %></p>
-
-<p><%= setting_select :wiki_compression, [['Gzip', 'gzip']], :blank => :label_none %></p>
-
-<p><%= setting_text_field :feeds_limit, :size => 6 %></p>
-
-<p><%= setting_text_field :file_max_size_displayed, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %></p>
-
-<p><%= setting_text_field :diff_max_lines_displayed, :size => 6 %></p>
-
-<p><%= setting_text_field :repositories_encodings, :size => 60 %><br />
-<em><%= l(:text_comma_separated) %></em></p>
-
-<%= call_hook(:view_settings_general_form) %>
-</div>
-
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/98/98b811f67a44ae39c8e831638539d7d2ea512b45.svn-base
--- a/.svn/pristine/98/98b811f67a44ae39c8e831638539d7d2ea512b45.svn-base
+++ /dev/null
@@ -1,57 +0,0 @@
-<% roles = Role.find_all_givable %>
-<% projects = Project.active.find(:all, :order => 'lft') %>
-
-<div class="splitcontentleft">
-<% if @group.memberships.any? %>
-<table class="list memberships">
-  <thead><tr>
-    <th><%= l(:label_project) %></th>
-    <th><%= l(:label_role_plural) %></th>
-    <th style="width:15%"></th>
-  </tr></thead>
-  <tbody>
-  <% @group.memberships.each do |membership| %>
-  <% next if membership.new_record? %>
-  <tr id="member-<%= membership.id %>" class="<%= cycle 'odd', 'even' %> class">
-  <td class="project"><%=h membership.project %></td>
-  <td class="roles">
-    <span id="member-<%= membership.id %>-roles"><%=h membership.roles.sort.collect(&:to_s).join(', ') %></span>
-    <% remote_form_for(:membership, :url => { :action => 'edit_membership', :id => @group, :membership_id => membership },
-                                    :html => { :id => "member-#{membership.id}-roles-form", :style => 'display:none;'}) do %>
-        <p><% roles.each do |role| %>
-        <label><%= check_box_tag 'membership[role_ids][]', role.id, membership.roles.include?(role) %> <%=h role %></label><br />
-        <% end %></p>
-        <p><%= submit_tag l(:button_change) %>
-        <%= link_to_function l(:button_cancel), "$('member-#{membership.id}-roles').show(); $('member-#{membership.id}-roles-form').hide(); return false;" %></p>
-    <% end %>
-  </td>
-  <td class="buttons">
-      <%= link_to_function l(:button_edit), "$('member-#{membership.id}-roles').hide(); $('member-#{membership.id}-roles-form').show(); return false;", :class => 'icon icon-edit' %>
-      <%= link_to_remote l(:button_delete), { :url => { :controller => 'groups', :action => 'destroy_membership', :id => @group, :membership_id => membership },
-                                              :method => :post },
-                                            :class => 'icon icon-del' %>
-  </td>
-  </tr>
-<% end; reset_cycle %>
-  </tbody>
-</table>
-<% else %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
-</div>
-
-<div class="splitcontentright">
-<% if projects.any? %>
-<fieldset><legend><%=l(:label_project_new)%></legend>
-<% remote_form_for(:membership, :url => { :action => 'edit_membership', :id => @group }) do %>
-<%= label_tag "membership_project_id", l(:description_choose_project), :class => "hidden-for-sighted" %>
-<%= select_tag 'membership[project_id]', options_for_membership_project_select(@group, projects) %>
-<p><%= l(:label_role_plural) %>:
-<% roles.each do |role| %>
-  <label><%= check_box_tag 'membership[role_ids][]', role.id %> <%=h role %></label>
-<% end %></p>
-<p><%= submit_tag l(:button_add) %></p>
-<% end %>
-</fieldset>
-<% end %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/99/993669603cb0d8da03a8d1aab8b814b747a7d19c.svn-base
--- a/.svn/pristine/99/993669603cb0d8da03a8d1aab8b814b747a7d19c.svn-base
+++ /dev/null
@@ -1,63 +0,0 @@
-== Redmine upgrade
-
-Redmine - project management software
-Copyright (C) 2006-2011  Jean-Philippe Lang
-http://www.redmine.org/
-
-
-== Upgrading
-
-1. Uncompress the program archive in a new directory
-
-2. Copy your database settings (RAILS_ROOT/config/database.yml)
-   and your configuration file (RAILS_ROOT/config/configuration.yml)
-   into the new config directory
-   Note: before Redmine 1.2, SMTP configuration was stored in
-   config/email.yml. It should now be stored in config/configuration.yml. 
-
-3. Copy the RAILS_ROOT/files directory content into your new installation
-   This directory contains all the attached files.
-
-4. Copy the folders of the installed plugins and themes into new installation
-
-5. Generate a session store secret
-   
-   Redmine stores session data in cookies by default, which requires
-   a secret to be generated. Under the new application directory run:
-     rake generate_session_store
-   
-   DO NOT REPLACE OR EDIT ANY OTHER FILES.
-
-6. Migrate your database
-
-   If you are upgrading to Rails 2.3.14 as part of this migration, you
-   need to upgrade the plugin migrations before running the plugin migrations
-   using:
-     rake db:migrate:upgrade_plugin_migrations RAILS_ENV="production"
-   
-   Please make a backup before doing this! Under the new application
-   directory run:
-     rake db:migrate RAILS_ENV="production"
-   
-   If you have installed any plugins, you should also run their database
-   migrations using:
-     rake db:migrate_plugins RAILS_ENV="production"
-   
-7. Clean up
-   
-   Clear the cache and the existing sessions by running:
-     rake tmp:cache:clear
-     rake tmp:sessions:clear
-
-8. Restart the application server (e.g. mongrel, thin, passenger)
-
-9. Finally go to "Administration -> Roles & permissions" to check/set permissions
-   for new features, if any
-
-== Notes
-
-* Rails 2.3.14 is required for versions 1.3.x.
-
-== References
-
-* http://www.redmine.org/wiki/redmine/RedmineUpgrade
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/99/994c6e124b87f66f87d072585f0635b097da8f7b.svn-base
--- /dev/null
+++ b/.svn/pristine/99/994c6e124b87f66f87d072585f0635b097da8f7b.svn-base
@@ -0,0 +1,125 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class SysControllerTest < ActionController::TestCase
+  fixtures :projects, :repositories, :enabled_modules
+
+  def setup
+    Setting.sys_api_enabled = '1'
+    Setting.enabled_scm = %w(Subversion Git)
+  end
+
+  def teardown
+    Setting.clear_cache
+  end
+
+  def test_projects_with_repository_enabled
+    get :projects
+    assert_response :success
+    assert_equal 'application/xml', @response.content_type
+    with_options :tag => 'projects' do |test|
+      test.assert_tag :children => { :count  => Project.active.has_module(:repository).count }
+      test.assert_tag 'project', :child => {:tag => 'identifier', :sibling => {:tag => 'is-public'}}
+    end
+    assert_no_tag 'extra-info'
+    assert_no_tag 'extra_info'
+  end
+
+  def test_create_project_repository
+    assert_nil Project.find(4).repository
+
+    post :create_project_repository, :id => 4,
+                                     :vendor => 'Subversion',
+                                     :repository => { :url => 'file:///create/project/repository/subproject2'}
+    assert_response :created
+    assert_equal 'application/xml', @response.content_type
+
+    r = Project.find(4).repository
+    assert r.is_a?(Repository::Subversion)
+    assert_equal 'file:///create/project/repository/subproject2', r.url
+    
+    assert_tag 'repository-subversion',
+      :child => {
+        :tag => 'id', :content => r.id.to_s,
+        :sibling => {:tag => 'url', :content => r.url}
+      }
+    assert_no_tag 'extra-info'
+    assert_no_tag 'extra_info'
+  end
+
+  def test_create_already_existing
+    post :create_project_repository, :id => 1,
+      :vendor => 'Subversion',
+      :repository => { :url => 'file:///create/project/repository/subproject2'}
+
+    assert_response :conflict
+  end
+
+  def test_create_with_failure
+    post :create_project_repository, :id => 4,
+      :vendor => 'Subversion',
+      :repository => { :url => 'invalid url'}
+
+    assert_response :unprocessable_entity
+  end
+
+  def test_fetch_changesets
+    Repository::Subversion.any_instance.expects(:fetch_changesets).twice.returns(true)
+    get :fetch_changesets
+    assert_response :success
+  end
+
+  def test_fetch_changesets_one_project_by_identifier
+    Repository::Subversion.any_instance.expects(:fetch_changesets).once.returns(true)
+    get :fetch_changesets, :id => 'ecookbook'
+    assert_response :success
+  end
+
+  def test_fetch_changesets_one_project_by_id
+    Repository::Subversion.any_instance.expects(:fetch_changesets).once.returns(true)
+    get :fetch_changesets, :id => '1'
+    assert_response :success
+  end
+
+  def test_fetch_changesets_unknown_project
+    get :fetch_changesets, :id => 'unknown'
+    assert_response 404
+  end
+
+  def test_disabled_ws_should_respond_with_403_error
+    with_settings :sys_api_enabled => '0' do
+      get :projects
+      assert_response 403
+    end
+  end
+
+  def test_api_key
+    with_settings :sys_api_key => 'my_secret_key' do
+      get :projects, :key => 'my_secret_key'
+      assert_response :success
+    end
+  end
+
+  def test_wrong_key_should_respond_with_403_error
+    with_settings :sys_api_enabled => 'my_secret_key' do
+      get :projects, :key => 'wrong_key'
+      assert_response 403
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/99/996c22938816a74506394630187f1f58ba63cc3d.svn-base
--- a/.svn/pristine/99/996c22938816a74506394630187f1f58ba63cc3d.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= link_to l(:label_role_plural), :controller => 'roles', :action => 'index' %> &#187; <%=h @role.name %></h2>
-
-<% labelled_tabular_form_for :role, @role, :url => { :action => 'edit' }, :html => {:id => 'role_form'} do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/99/996e7697ae354745ef1ba467604214fe6324888a.svn-base
--- a/.svn/pristine/99/996e7697ae354745ef1ba467604214fe6324888a.svn-base
+++ /dev/null
@@ -1,17 +0,0 @@
-<% form_tag({:action => 'edit', :tab => 'projects'}) do %>
-
-<div class="box tabular settings">
-<p><%= setting_check_box :default_projects_public %></p>
-
-<p><%= setting_multiselect(:default_projects_modules,
-        Redmine::AccessControl.available_project_modules.collect {|m| [l_or_humanize(m, :prefix => "project_module_"), m.to_s]}) %></p>
-
-<p><%= setting_check_box :sequential_project_identifiers %></p>
-
-<p><%= setting_select :new_project_user_role_id,
-                      Role.find_all_givable.collect {|r| [r.name, r.id.to_s]},
-                      :blank => "--- #{l(:actionview_instancetag_blank_option)} ---" %></p>
-</div>
-
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/99/999df512aeb4c0876f1878f63f27c75b32797102.svn-base
--- /dev/null
+++ b/.svn/pristine/99/999df512aeb4c0876f1878f63f27c75b32797102.svn-base
@@ -0,0 +1,71 @@
+<div class="contextual">
+<% if @editable %>
+<% if @content.current_version? %>
+  <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %>
+  <%= watcher_link(@page, User.current) %>
+  <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
+  <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
+  <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') %>
+  <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') %>
+<% else %>
+  <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') %>
+<% end %>
+<% end %>
+<%= link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %>
+</div>
+
+<%= wiki_page_breadcrumb(@page) %>
+
+<% unless @content.current_version? %>
+    <p>
+    <%= link_to(("\xc2\xab " + l(:label_previous)),
+                :action => 'show', :id => @page.title, :project_id => @page.project,
+                :version => @content.previous.version) + " - " if @content.previous %>
+    <%= "#{l(:label_version)} #{@content.version}/#{@page.content.version}" %>
+    <%= '('.html_safe + link_to(l(:label_diff), :controller => 'wiki', :action => 'diff',
+                      :id => @page.title, :project_id => @page.project,
+                      :version => @content.version) + ')'.html_safe if @content.previous %> - 
+    <%= link_to((l(:label_next) + " \xc2\xbb"), :action => 'show',
+                :id => @page.title, :project_id => @page.project,
+                :version => @content.next.version) + " - " if @content.next %>
+    <%= link_to(l(:label_current_version), :action => 'show', :id => @page.title, :project_id => @page.project, :version => nil) %>
+    <br />
+    <em><%= @content.author ? link_to_user(@content.author) : l(:label_user_anonymous)
+         %>, <%= format_time(@content.updated_on) %> </em><br />
+    <%=h @content.comments %>
+    </p>
+    <hr />
+<% end %>
+
+<%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
+
+<%= link_to_attachments @page %>
+
+<% if @editable && authorize_for('wiki', 'add_attachment') %>
+<div id="wiki_add_attachment">
+<p><%= link_to l(:label_attachment_new), {}, :onclick => "$('#add_attachment_form').show(); return false;",
+                                             :id => 'attach_files_link' %></p>
+<%= form_tag({:controller => 'wiki', :action => 'add_attachment',
+              :project_id => @project, :id => @page.title},
+             :multipart => true, :id => "add_attachment_form",
+             :style => "display:none;") do %>
+  <div class="box">
+  <p><%= render :partial => 'attachments/form' %></p>
+  </div>
+<%= submit_tag l(:button_add) %>
+<%= link_to l(:button_cancel), {}, :onclick => "$('#add_attachment_form').hide(); return false;" %>
+<% end %>
+</div>
+<% end %>
+
+<% other_formats_links do |f| %>
+  <%= f.link_to 'PDF', :url => {:id => @page.title, :version => params[:version]} %>
+  <%= f.link_to 'HTML', :url => {:id => @page.title, :version => params[:version]} %>
+  <%= f.link_to 'TXT', :url => {:id => @page.title, :version => params[:version]} %>
+<% end if User.current.allowed_to?(:export_wiki_pages, @project) %>
+
+<% content_for :sidebar do %>
+  <%= render :partial => 'sidebar' %>
+<% end %>
+
+<% html_title @page.pretty_title %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/99/99a414efabab7887994595b321f5356fb075fb31.svn-base
--- a/.svn/pristine/99/99a414efabab7887994595b321f5356fb075fb31.svn-base
+++ /dev/null
@@ -1,31 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module AccessKeys
-    ACCESSKEYS = {:edit => 'e',
-                  :preview => 'r',
-                  :quick_search => 'f',
-                  :search => '4',
-                  :new_issue => '7'
-                 }.freeze unless const_defined?(:ACCESSKEYS)
-
-    def self.key_for(action)
-      ACCESSKEYS[action]
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/99/99b146981da48793424f86a46fec5e069034bf88.svn-base
--- /dev/null
+++ b/.svn/pristine/99/99b146981da48793424f86a46fec5e069034bf88.svn-base
@@ -0,0 +1,198 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class MyController < ApplicationController
+  before_filter :require_login
+
+  helper :issues
+  helper :users
+  helper :custom_fields
+
+  BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
+             'issuesreportedbyme' => :label_reported_issues,
+             'issueswatched' => :label_watched_issues,
+             'news' => :label_news_latest,
+             'calendar' => :label_calendar,
+             'documents' => :label_document_plural,
+             'timelog' => :label_spent_time
+           }.merge(Redmine::Views::MyPage::Block.additional_blocks).freeze
+
+  DEFAULT_LAYOUT = {  'left' => ['issuesassignedtome'],
+                      'right' => ['issuesreportedbyme']
+                   }.freeze
+
+  def index
+    page
+    render :action => 'page'
+  end
+
+  # Show user's page
+  def page
+    @user = User.current
+    @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT
+  end
+
+  # Edit user's account
+  def account
+    @user = User.current
+    @pref = @user.pref
+    if request.post?
+      @user.safe_attributes = params[:user]
+      @user.pref.attributes = params[:pref]
+      @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
+      if @user.save
+        @user.pref.save
+        @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
+        set_language_if_valid @user.language
+        flash[:notice] = l(:notice_account_updated)
+        redirect_to my_account_path
+        return
+      end
+    end
+  end
+
+  # Destroys user's account
+  def destroy
+    @user = User.current
+    unless @user.own_account_deletable?
+      redirect_to my_account_path
+      return
+    end
+
+    if request.post? && params[:confirm]
+      @user.destroy
+      if @user.destroyed?
+        logout_user
+        flash[:notice] = l(:notice_account_deleted)
+      end
+      redirect_to home_path
+    end
+  end
+
+  # Manage user's password
+  def password
+    @user = User.current
+    unless @user.change_password_allowed?
+      flash[:error] = l(:notice_can_t_change_password)
+      redirect_to my_account_path
+      return
+    end
+    if request.post?
+      if @user.check_password?(params[:password])
+        @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
+        if @user.save
+          flash[:notice] = l(:notice_account_password_updated)
+          redirect_to my_account_path
+        end
+      else
+        flash[:error] = l(:notice_account_wrong_password)
+      end
+    end
+  end
+
+  # Create a new feeds key
+  def reset_rss_key
+    if request.post?
+      if User.current.rss_token
+        User.current.rss_token.destroy
+        User.current.reload
+      end
+      User.current.rss_key
+      flash[:notice] = l(:notice_feeds_access_key_reseted)
+    end
+    redirect_to my_account_path
+  end
+
+  # Create a new API key
+  def reset_api_key
+    if request.post?
+      if User.current.api_token
+        User.current.api_token.destroy
+        User.current.reload
+      end
+      User.current.api_key
+      flash[:notice] = l(:notice_api_access_key_reseted)
+    end
+    redirect_to my_account_path
+  end
+
+  # User's page layout configuration
+  def page_layout
+    @user = User.current
+    @blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup
+    @block_options = []
+    BLOCKS.each do |k, v|
+      unless %w(top left right).detect {|f| (@blocks[f] ||= []).include?(k)}
+        @block_options << [l("my.blocks.#{v}", :default => [v, v.to_s.humanize]), k.dasherize]
+      end
+    end
+  end
+
+  # Add a block to user's page
+  # The block is added on top of the page
+  # params[:block] : id of the block to add
+  def add_block
+    block = params[:block].to_s.underscore
+    if block.present? && BLOCKS.key?(block)
+      @user = User.current
+      layout = @user.pref[:my_page_layout] || {}
+      # remove if already present in a group
+      %w(top left right).each {|f| (layout[f] ||= []).delete block }
+      # add it on top
+      layout['top'].unshift block
+      @user.pref[:my_page_layout] = layout
+      @user.pref.save
+    end
+    redirect_to my_page_layout_path
+  end
+
+  # Remove a block to user's page
+  # params[:block] : id of the block to remove
+  def remove_block
+    block = params[:block].to_s.underscore
+    @user = User.current
+    # remove block in all groups
+    layout = @user.pref[:my_page_layout] || {}
+    %w(top left right).each {|f| (layout[f] ||= []).delete block }
+    @user.pref[:my_page_layout] = layout
+    @user.pref.save
+    redirect_to my_page_layout_path
+  end
+
+  # Change blocks order on user's page
+  # params[:group] : group to order (top, left or right)
+  # params[:list-(top|left|right)] : array of block ids of the group
+  def order_blocks
+    group = params[:group]
+    @user = User.current
+    if group.is_a?(String)
+      group_items = (params["blocks"] || []).collect(&:underscore)
+      group_items.each {|s| s.sub!(/^block_/, '')}
+      if group_items and group_items.is_a? Array
+        layout = @user.pref[:my_page_layout] || {}
+        # remove group blocks if they are presents in other groups
+        %w(top left right).each {|f|
+          layout[f] = (layout[f] || []) - group_items
+        }
+        layout[group] = group_items
+        @user.pref[:my_page_layout] = layout
+        @user.pref.save
+      end
+    end
+    render :nothing => true
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/99/99c710840ac1685d172c3ffd9c93f67d6b1292b0.svn-base
--- a/.svn/pristine/99/99c710840ac1685d172c3ffd9c93f67d6b1292b0.svn-base
+++ /dev/null
@@ -1,133 +0,0 @@
-# Contains the enhancements to Rails' migrations system to support the 
-# Engines::Plugin::Migrator. See Engines::RailsExtensions::Migrations for more
-# information.
-
-require "engines/plugin/migrator"
-
-# = Plugins and Migrations: Background
-#
-# Rails uses migrations to describe changes to the databases as your application
-# evolves. Each change to your application - adding and removing models, most
-# commonly - might require tweaks to your schema in the form of new tables, or new
-# columns on existing tables, or possibly the removal of tables or columns. Migrations
-# can even include arbitrary code to *transform* data as the underlying schema
-# changes.
-# 
-# The point is that at any particular stage in your application's development, 
-# migrations serve to transform the database into a state where it is compatible
-# and appropriate at that time.
-# 
-# == What about plugins?
-# 
-# If you want to share models using plugins, chances are that you might also
-# want to include the corresponding migrations to create tables for those models.
-# With the engines plugin installed, plugins can carry migration data easily:
-# 
-#   vendor/
-#     |
-#     plugins/
-#       |
-#       my_plugin/
-#         |- init.rb
-#         |- lib/
-#         |- db/
-#             |-migrate/
-#                 |- 20081105123419_add_some_new_feature.rb
-#                 |- 20081107144959_and_something_else.rb
-#                 |- ...
-# 
-# When you install a plugin which contains migrations, you are undertaking a
-# further step in the development of your application, the same as the addition
-# of any other code. With this in mind, you may want to 'roll back' the
-# installation of this plugin at some point, and the database should be able
-# to migrate back to the point without this plugin in it too.
-#
-# == An example
-#
-# For example, our current application is at version 20081106164503 (according to the
-# +schema_migrations+ table), when we decide that we want to add a tagging plugin. The
-# tagging plugin chosen includes migrations to create the tables it requires
-# (say, _tags_ and _taggings_, for instance), along with the models and helpers
-# one might expect.
-#
-# After installing this plugin, these tables should be created in our database.
-# Rather than running the migrations directly from the plugin, they should be
-# integrated into our main migration stream in order to accurately reflect the
-# state of our application's database *at this moment in time*.
-#
-#   $ script/generate plugin_migration
-#         exists  db/migrate
-#         create  db/migrate/20081108120415_my_plugin_to_version_20081107144959.rb
-#
-# This migration will take our application to version 20081108120415, and contains the 
-# following, typical migration code:
-# 
-#   class TaggingToVersion20081107144959 < ActiveRecord::Migration
-#     def self.up
-#       Engines.plugins[:tagging].migrate(20081107144959)
-#     end
-#     def self.down
-#       Engines.plugins[:tagging].migrate(0)
-#     end
-#   end
-#
-# When we migrate our application up, using <tt>rake db:migrate</tt> as normal,
-# the plugin will be migrated up to its latest version (20081108120415 in this example). If we
-# ever decide to migrate the application back to the state it was in at version 20081106164503,
-# the plugin migrations will be taken back down to version 0 (which, typically,
-# would remove all tables the plugin migrations define).
-#
-# == Upgrading plugins
-#
-# It might happen that later in an application's life, we update to a new version of
-# the tagging plugin which requires some changes to our database. The tagging plugin
-# provides these changes in the form of its own migrations. 
-#
-# In this case, we just need to re-run the plugin_migration generator to create a 
-# new migration from the current revision to the newest one:
-#
-#   $ script/generate plugin_migration
-#        exists db/migrate
-#        create db/migrate/20081210131437_tagging_to_version_20081201172034.rb
-#
-# The contents of this migration are:
-#
-#   class TaggingToVersion20081108120415 < ActiveRecord::Migration
-#     def self.up
-#       Engines.plugins[:tagging].migrate(20081201172034)
-#     end
-#     def self.down
-#       Engines.plugins[:tagging].migrate(20081107144959)
-#     end
-#   end
-#
-# Notice that if we were to migrate down to revision 20081108120415 or lower, the tagging plugin
-# will be migrated back down to version 20081107144959 - the version we were previously at.
-#
-#
-# = Creating migrations in plugins
-#
-# In order to use the plugin migration functionality that engines provides, a plugin 
-# only needs to provide regular migrations in a <tt>db/migrate</tt> folder within it.
-#
-# = Explicitly migrating plugins
-#
-# It's possible to migrate plugins within your own migrations, or any other code.
-# Simply get the Plugin instance, and its Plugin#migrate method with the version
-# you wish to end up at:
-#
-#   Engines.plugins[:whatever].migrate(version)
-#
-#
-# = Upgrading from previous versions of the engines plugin
-#
-# Thanks to the tireless work of the plugin developer community, we can now relying on the migration 
-# mechanism in Rails 2.1+ to do much of the plugin migration work for us. This also means that we
-# don't need a seperate schema_info table for plugins.
-#
-# To update your application, run
-#
-#   rake db:migrate:upgrade_plugin_migrations
-#
-# This will ensure that migration information is carried over into the main schema_migrations table.
-# 
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9a/9a3f0af8445b88db6572d7d1dbbde88890b69226.svn-base
--- /dev/null
+++ b/.svn/pristine/9a/9a3f0af8445b88db6572d7d1dbbde88890b69226.svn-base
@@ -0,0 +1,43 @@
+--- 
+journal_details_001: 
+  old_value: "1"
+  property: attr
+  id: 1
+  value: "2"
+  prop_key: status_id
+  journal_id: 1
+journal_details_002: 
+  old_value: "40"
+  property: attr
+  id: 2
+  value: "30"
+  prop_key: done_ratio
+  journal_id: 1
+journal_details_003:
+  old_value:
+  property: attr
+  id: 3
+  value: "6"
+  prop_key: fixed_version_id
+  journal_id: 4
+journal_details_004:
+  old_value: "This word was removed and an other was"
+  property: attr
+  id: 4
+  value: "This word was and an other was added"
+  prop_key: description
+  journal_id: 3
+journal_details_005:
+  old_value: Old value
+  property: cf
+  id: 5
+  value: New value
+  prop_key: 2
+  journal_id: 3
+journal_details_006:
+  old_value:
+  property: attachment
+  id: 6
+  value: 060719210727_picture.jpg
+  prop_key: 4
+  journal_id: 3
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9a/9a40b8d61a3b252d9bf2afe70d0ed928e7cbe617.svn-base
--- /dev/null
+++ b/.svn/pristine/9a/9a40b8d61a3b252d9bf2afe70d0ed928e7cbe617.svn-base
@@ -0,0 +1,26 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Views
+    class ApiTemplateHandler
+      def self.call(template)
+        "Redmine::Views::Builders.for(params[:format], request, response) do |api|; #{template.source}; self.output_buffer = api.output; end"
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9a/9a4ce39d0950186e276d1ae1cbcd63d09e749eb5.svn-base
--- /dev/null
+++ b/.svn/pristine/9a/9a4ce39d0950186e276d1ae1cbcd63d09e749eb5.svn-base
@@ -0,0 +1,1199 @@
+# Russian localization for Ruby on Rails 2.2+
+# by Yaroslav Markin <yaroslav@markin.net>
+#
+# Be sure to check out "russian" gem (http://github.com/yaroslav/russian) for
+# full Russian language support in Rails (month names, pluralization, etc).
+# The following is an excerpt from that gem.
+#
+# Ð”Ð»Ñ Ð¿Ð¾Ð»Ð½Ð¾Ñ†ÐµÐ½Ð½Ð¾Ð¹ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ Ñ€ÑƒÑÑÐºÐ¾Ð³Ð¾ ÑÐ·Ñ‹ÐºÐ° (Ð²Ð°Ñ€Ð¸Ð°Ð½Ñ‚Ñ‹ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ð¹ Ð¼ÐµÑÑÑ†ÐµÐ²,
+# Ð¿Ð»ÑŽÑ€Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¸ Ñ‚Ð°Ðº Ð´Ð°Ð»ÐµÐµ) Ð² Rails 2.2 Ð½ÑƒÐ¶Ð½Ð¾ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÑŒ gem "russian"
+# (http://github.com/yaroslav/russian). Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð¸Ðµ Ð´Ð°Ð½Ð½Ñ‹Ðµ -- Ð²Ñ‹Ð´ÐµÑ€Ð¶ÐºÐ° Ð¸Ñ… Ð½ÐµÐ³Ð¾, Ñ‡Ñ‚Ð¾Ð±Ñ‹
+# Ð±Ñ‹Ð»Ð° Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ÑŒ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ð¹ Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ð° Ñ€ÑƒÑÑÐºÐ¸Ð¹ ÑÐ·Ñ‹Ðº.
+
+ru:
+  direction: ltr
+  date:
+    formats:
+      default: "%d.%m.%Y"
+      short: "%d %b"
+      long: "%d %B %Y"
+
+    day_names: [Ð²Ð¾ÑÐºÑ€ÐµÑÐµÐ½ÑŒÐµ, Ð¿Ð¾Ð½ÐµÐ´ÐµÐ»ÑŒÐ½Ð¸Ðº, Ð²Ñ‚Ð¾Ñ€Ð½Ð¸Ðº, ÑÑ€ÐµÐ´Ð°, Ñ‡ÐµÑ‚Ð²ÐµÑ€Ð³, Ð¿ÑÑ‚Ð½Ð¸Ñ†Ð°, ÑÑƒÐ±Ð±Ð¾Ñ‚Ð°]
+    standalone_day_names: [Ð’Ð¾ÑÐºÑ€ÐµÑÐµÐ½ÑŒÐµ, ÐŸÐ¾Ð½ÐµÐ´ÐµÐ»ÑŒÐ½Ð¸Ðº, Ð’Ñ‚Ð¾Ñ€Ð½Ð¸Ðº, Ð¡Ñ€ÐµÐ´Ð°, Ð§ÐµÑ‚Ð²ÐµÑ€Ð³, ÐŸÑÑ‚Ð½Ð¸Ñ†Ð°, Ð¡ÑƒÐ±Ð±Ð¾Ñ‚Ð°]
+    abbr_day_names: [Ð’Ñ, ÐŸÐ½, Ð’Ñ‚, Ð¡Ñ€, Ð§Ñ‚, ÐŸÑ‚, Ð¡Ð±]
+
+    month_names: [~, ÑÐ½Ð²Ð°Ñ€Ñ, Ñ„ÐµÐ²Ñ€Ð°Ð»Ñ, Ð¼Ð°Ñ€Ñ‚Ð°, Ð°Ð¿Ñ€ÐµÐ»Ñ, Ð¼Ð°Ñ, Ð¸ÑŽÐ½Ñ, Ð¸ÑŽÐ»Ñ, Ð°Ð²Ð³ÑƒÑÑ‚Ð°, ÑÐµÐ½Ñ‚ÑÐ±Ñ€Ñ, Ð¾ÐºÑ‚ÑÐ±Ñ€Ñ, Ð½Ð¾ÑÐ±Ñ€Ñ, Ð´ÐµÐºÐ°Ð±Ñ€Ñ]
+    # see russian gem for info on "standalone" day names
+    standalone_month_names: [~, Ð¯Ð½Ð²Ð°Ñ€ÑŒ, Ð¤ÐµÐ²Ñ€Ð°Ð»ÑŒ, ÐœÐ°Ñ€Ñ‚, ÐÐ¿Ñ€ÐµÐ»ÑŒ, ÐœÐ°Ð¹, Ð˜ÑŽÐ½ÑŒ, Ð˜ÑŽÐ»ÑŒ, ÐÐ²Ð³ÑƒÑÑ‚, Ð¡ÐµÐ½Ñ‚ÑÐ±Ñ€ÑŒ, ÐžÐºÑ‚ÑÐ±Ñ€ÑŒ, ÐÐ¾ÑÐ±Ñ€ÑŒ, Ð”ÐµÐºÐ°Ð±Ñ€ÑŒ]
+    abbr_month_names: [~, ÑÐ½Ð²., Ñ„ÐµÐ²Ñ€., Ð¼Ð°Ñ€Ñ‚Ð°, Ð°Ð¿Ñ€., Ð¼Ð°Ñ, Ð¸ÑŽÐ½Ñ, Ð¸ÑŽÐ»Ñ, Ð°Ð²Ð³., ÑÐµÐ½Ñ‚., Ð¾ÐºÑ‚., Ð½Ð¾ÑÐ±., Ð´ÐµÐº.]
+    standalone_abbr_month_names: [~, ÑÐ½Ð²., Ñ„ÐµÐ²Ñ€., Ð¼Ð°Ñ€Ñ‚, Ð°Ð¿Ñ€., Ð¼Ð°Ð¹, Ð¸ÑŽÐ½ÑŒ, Ð¸ÑŽÐ»ÑŒ, Ð°Ð²Ð³., ÑÐµÐ½Ñ‚., Ð¾ÐºÑ‚., Ð½Ð¾ÑÐ±., Ð´ÐµÐº.]
+
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a, %d %b %Y, %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b, %H:%M"
+      long: "%d %B %Y, %H:%M"
+
+    am: "ÑƒÑ‚Ñ€Ð°"
+    pm: "Ð²ÐµÑ‡ÐµÑ€Ð°"
+
+  number:
+    format:
+      separator: ","
+      delimiter: " "
+      precision: 3
+
+    currency:
+      format:
+        format: "%n %u"
+        unit: "Ñ€ÑƒÐ±."
+        separator: "."
+        delimiter: " "
+        precision: 2
+
+    percentage:
+      format:
+        delimiter: ""
+
+    precision:
+      format:
+        delimiter: ""
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      # Rails 2.2
+      # storage_units: [Ð±Ð°Ð¹Ñ‚, ÐšÐ‘, ÐœÐ‘, Ð“Ð‘, Ð¢Ð‘]
+
+      # Rails 2.3
+      storage_units:
+        # Storage units output formatting.
+        # %u is the storage unit, %n is the number (default: 2 MB)
+        format: "%n %u"
+        units:
+          byte:
+            one:   "Ð±Ð°Ð¹Ñ‚"
+            few:   "Ð±Ð°Ð¹Ñ‚Ð°"
+            many:  "Ð±Ð°Ð¹Ñ‚"
+            other: "Ð±Ð°Ð¹Ñ‚Ð°"
+          kb: "ÐšÐ‘"
+          mb: "ÐœÐ‘"
+          gb: "Ð“Ð‘"
+          tb: "Ð¢Ð‘"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "Ð¼ÐµÐ½ÑŒÑˆÐµ Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
+      less_than_x_seconds:
+        one:   "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐµÐºÑƒÐ½Ð´Ñ‹"
+        few:   "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐµÐºÑƒÐ½Ð´"
+        many:  "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐµÐºÑƒÐ½Ð´"
+        other: "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐµÐºÑƒÐ½Ð´Ñ‹"
+      x_seconds:
+        one:   "%{count} ÑÐµÐºÑƒÐ½Ð´Ð°"
+        few:   "%{count} ÑÐµÐºÑƒÐ½Ð´Ñ‹"
+        many:  "%{count} ÑÐµÐºÑƒÐ½Ð´"
+        other: "%{count} ÑÐµÐºÑƒÐ½Ð´Ñ‹"
+      less_than_x_minutes:
+        one:   "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
+        few:   "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} Ð¼Ð¸Ð½ÑƒÑ‚"
+        many:  "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} Ð¼Ð¸Ð½ÑƒÑ‚"
+        other: "Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
+      x_minutes:
+        one:   "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñƒ"
+        few:   "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
+        many:  "%{count} Ð¼Ð¸Ð½ÑƒÑ‚"
+        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ñ‹"
+      about_x_hours:
+        one:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
+        few:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
+        many:  "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
+        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
+      x_hours:
+        one:   "%{count} Ñ‡Ð°Ñ"
+        few:   "%{count} Ñ‡Ð°ÑÐ°"
+        many:  "%{count} Ñ‡Ð°ÑÐ¾Ð²"
+        other: "%{count} Ñ‡Ð°ÑÐ°"
+      x_days:
+        one:   "%{count} Ð´ÐµÐ½ÑŒ"
+        few:   "%{count} Ð´Ð½Ñ"
+        many:  "%{count} Ð´Ð½ÐµÐ¹"
+        other: "%{count} Ð´Ð½Ñ"
+      about_x_months:
+        one:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÑÑ†Ð°"
+        few:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÑÑ†ÐµÐ²"
+        many:  "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÑÑ†ÐµÐ²"
+        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð¼ÐµÑÑÑ†Ð°"
+      x_months:
+        one:   "%{count} Ð¼ÐµÑÑÑ†"
+        few:   "%{count} Ð¼ÐµÑÑÑ†Ð°"
+        many:  "%{count} Ð¼ÐµÑÑÑ†ÐµÐ²"
+        other: "%{count} Ð¼ÐµÑÑÑ†Ð°"
+      about_x_years:
+        one:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð³Ð¾Ð´Ð°"
+        few:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð»ÐµÑ‚"
+        many:  "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð»ÐµÑ‚"
+        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ð»ÐµÑ‚"
+      over_x_years:
+        one:   "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð³Ð¾Ð´Ð°"
+        few:   "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð»ÐµÑ‚"
+        many:  "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð»ÐµÑ‚"
+        other: "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð»ÐµÑ‚"
+      almost_x_years:
+        one:   "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´"
+        few:   "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´Ð°"
+        many:  "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð»ÐµÑ‚"
+        other: "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´Ð°"
+    prompts:
+      year: "Ð“Ð¾Ð´"
+      month: "ÐœÐµÑÑÑ†"
+      day: "Ð”ÐµÐ½ÑŒ"
+      hour: "Ð§Ð°ÑÐ¾Ð²"
+      minute: "ÐœÐ¸Ð½ÑƒÑ‚"
+      second: "Ð¡ÐµÐºÑƒÐ½Ð´"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:   "%{model}: ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð½Ðµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ Ð¸Ð·-Ð·Ð° %{count} Ð¾ÑˆÐ¸Ð±ÐºÐ¸"
+          few:   "%{model}: ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð½Ðµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ Ð¸Ð·-Ð·Ð° %{count} Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
+          many:  "%{model}: ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð½Ðµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ Ð¸Ð·-Ð·Ð° %{count} Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
+          other: "%{model}: ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð½Ðµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ Ð¸Ð·-Ð·Ð° %{count} Ð¾ÑˆÐ¸Ð±ÐºÐ¸"
+
+        body: "ÐŸÑ€Ð¾Ð±Ð»ÐµÐ¼Ñ‹ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ»Ð¸ ÑÐ¾ ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð¸Ð¼Ð¸ Ð¿Ð¾Ð»ÑÐ¼Ð¸:"
+
+      messages:
+        inclusion: "Ð¸Ð¼ÐµÐµÑ‚ Ð½ÐµÐ¿Ñ€ÐµÐ´ÑƒÑÐ¼Ð¾Ñ‚Ñ€ÐµÐ½Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
+        exclusion: "Ð¸Ð¼ÐµÐµÑ‚ Ð·Ð°Ñ€ÐµÐ·ÐµÑ€Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
+        invalid: "Ð¸Ð¼ÐµÐµÑ‚ Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
+        confirmation: "Ð½Ðµ ÑÐ¾Ð²Ð¿Ð°Ð´Ð°ÐµÑ‚ Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸ÐµÐ¼"
+        accepted: "Ð½ÑƒÐ¶Ð½Ð¾ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¸Ñ‚ÑŒ"
+        empty: "Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¿ÑƒÑÑ‚Ñ‹Ð¼"
+        blank: "Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¿ÑƒÑÑ‚Ñ‹Ð¼"
+        too_long:
+          one:   "ÑÐ»Ð¸ÑˆÐºÐ¾Ð¼ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñ‡ÐµÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»)"
+          few:   "ÑÐ»Ð¸ÑˆÐºÐ¾Ð¼ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñ‡ÐµÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
+          many:  "ÑÐ»Ð¸ÑˆÐºÐ¾Ð¼ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñ‡ÐµÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²)"
+          other: "ÑÐ»Ð¸ÑˆÐºÐ¾Ð¼ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñ‡ÐµÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
+        too_short:
+          one:   "Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ‚Ð¾Ñ‡Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
+          few:   "Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ‚Ð¾Ñ‡Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²)"
+          many:  "Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ‚Ð¾Ñ‡Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²)"
+          other: "Ð½ÐµÐ´Ð¾ÑÑ‚Ð°Ñ‚Ð¾Ñ‡Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¼ÐµÐ½ÑŒÑˆÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
+        wrong_length:
+          one:   "Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð´Ð»Ð¸Ð½Ð¾Ð¹ Ñ€Ð¾Ð²Ð½Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»)"
+          few:   "Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð´Ð»Ð¸Ð½Ð¾Ð¹ Ñ€Ð¾Ð²Ð½Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
+          many:  "Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð´Ð»Ð¸Ð½Ð¾Ð¹ Ñ€Ð¾Ð²Ð½Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²)"
+          other: "Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ Ð´Ð»Ð¸Ð½Ñ‹ (Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð´Ð»Ð¸Ð½Ð¾Ð¹ Ñ€Ð¾Ð²Ð½Ð¾ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð°)"
+        taken: "ÑƒÐ¶Ðµ ÑÑƒÑ‰ÐµÑÑ‚Ð²ÑƒÐµÑ‚"
+        not_a_number: "Ð½Ðµ ÑÐ²Ð»ÑÐµÑ‚ÑÑ Ñ‡Ð¸ÑÐ»Ð¾Ð¼"
+        greater_than: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð±Ð¾Ð»ÑŒÑˆÐµÐµ %{count}"
+        greater_than_or_equal_to: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð±Ð¾Ð»ÑŒÑˆÐµÐµ Ð¸Ð»Ð¸ Ñ€Ð°Ð²Ð½Ð¾Ðµ %{count}"
+        equal_to: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð»Ð¸ÑˆÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ, Ñ€Ð°Ð²Ð½Ð¾Ðµ %{count}"
+        less_than: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð¼ÐµÐ½ÑŒÑˆÐµÐµ Ñ‡ÐµÐ¼ %{count}"
+        less_than_or_equal_to: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð¼ÐµÐ½ÑŒÑˆÐµÐµ Ð¸Ð»Ð¸ Ñ€Ð°Ð²Ð½Ð¾Ðµ %{count}"
+        odd: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð»Ð¸ÑˆÑŒ Ð½ÐµÑ‡ÐµÑ‚Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
+        even: "Ð¼Ð¾Ð¶ÐµÑ‚ Ð¸Ð¼ÐµÑ‚ÑŒ Ð»Ð¸ÑˆÑŒ Ñ‡ÐµÑ‚Ð½Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ"
+        greater_than_start_date: "Ð´Ð¾Ð»Ð¶Ð½Ð° Ð±Ñ‹Ñ‚ÑŒ Ð¿Ð¾Ð·Ð´Ð½ÐµÐµ Ð´Ð°Ñ‚Ñ‹ Ð½Ð°Ñ‡Ð°Ð»Ð°"
+        not_same_project: "Ð½Ðµ Ð¾Ñ‚Ð½Ð¾ÑÐ¸Ñ‚ÑÑ Ðº Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ"
+        circular_dependency: "Ð¢Ð°ÐºÐ°Ñ ÑÐ²ÑÐ·ÑŒ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÑ‚ Ðº Ñ†Ð¸ÐºÐ»Ð¸Ñ‡ÐµÑÐºÐ¾Ð¹ Ð·Ð°Ð²Ð¸ÑÐ¸Ð¼Ð¾ÑÑ‚Ð¸"
+        cant_link_an_issue_with_a_descendant: "Ð—Ð°Ð´Ð°Ñ‡Ð° Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ ÑÐ²ÑÐ·Ð°Ð½Ð° ÑÐ¾ ÑÐ²Ð¾ÐµÐ¹ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡ÐµÐ¹"
+
+  support:
+    array:
+      # Rails 2.2
+      sentence_connector: "Ð¸"
+      skip_last_comma: true
+
+      # Rails 2.3
+      words_connector: ", "
+      two_words_connector: " Ð¸ "
+      last_word_connector: " Ð¸ "
+
+  actionview_instancetag_blank_option: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ
+
+  button_activate: ÐÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_add: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ
+  button_annotate: ÐÐ²Ñ‚Ð¾Ñ€ÑÑ‚Ð²Ð¾
+  button_apply: ÐŸÑ€Ð¸Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ
+  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_back: ÐÐ°Ð·Ð°Ð´
+  button_cancel: ÐžÑ‚Ð¼ÐµÐ½Ð°
+  button_change_password: Ð˜Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
+  button_change: Ð˜Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ
+  button_check_all: ÐžÑ‚Ð¼ÐµÑ‚Ð¸Ñ‚ÑŒ Ð²ÑÐµ
+  button_clear: ÐžÑ‡Ð¸ÑÑ‚Ð¸Ñ‚ÑŒ
+  button_configure: ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹
+  button_copy: ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_create: Ð¡Ð¾Ð·Ð´Ð°Ñ‚ÑŒ
+  button_create_and_continue: Ð¡Ð¾Ð·Ð´Ð°Ñ‚ÑŒ Ð¸ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÑŒ
+  button_delete: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ
+  button_download: Ð—Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ
+  button_edit: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_edit_associated_wikipage: "Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ ÑÐ²ÑÐ·Ð°Ð½Ð½ÑƒÑŽ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ: %{page_title}"
+  button_list: Ð¡Ð¿Ð¸ÑÐ¾Ðº
+  button_lock: Ð—Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_login: Ð’Ñ…Ð¾Ð´
+  button_log_time: Ð—Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
+  button_move: ÐŸÐµÑ€ÐµÐ¼ÐµÑÑ‚Ð¸Ñ‚ÑŒ
+  button_quote: Ð¦Ð¸Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_rename: ÐŸÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_reply: ÐžÑ‚Ð²ÐµÑ‚Ð¸Ñ‚ÑŒ
+  button_reset: Ð¡Ð±Ñ€Ð¾ÑÐ¸Ñ‚ÑŒ
+  button_rollback: Ð’ÐµÑ€Ð½ÑƒÑ‚ÑŒÑÑ Ðº Ð´Ð°Ð½Ð½Ð¾Ð¹ Ð²ÐµÑ€ÑÐ¸Ð¸
+  button_save: Ð¡Ð¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ
+  button_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_submit: ÐŸÑ€Ð¸Ð½ÑÑ‚ÑŒ
+  button_test: ÐŸÑ€Ð¾Ð²ÐµÑ€Ð¸Ñ‚ÑŒ
+  button_unarchive: Ð Ð°Ð·Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_uncheck_all: ÐžÑ‡Ð¸ÑÑ‚Ð¸Ñ‚ÑŒ
+  button_unlock: Ð Ð°Ð·Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_unwatch: ÐÐµ ÑÐ»ÐµÐ´Ð¸Ñ‚ÑŒ
+  button_update: ÐžÐ±Ð½Ð¾Ð²Ð¸Ñ‚ÑŒ
+  button_view: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ
+  button_watch: Ð¡Ð»ÐµÐ´Ð¸Ñ‚ÑŒ
+
+  default_activity_design: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ
+  default_activity_development: Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ°
+  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸Ñ‡ÐµÑÐºÐ°Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ
+  default_doc_category_user: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑÐºÐ°Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ
+  default_issue_status_in_progress: Ð’ Ñ€Ð°Ð±Ð¾Ñ‚Ðµ
+  default_issue_status_closed: Ð—Ð°ÐºÑ€Ñ‹Ñ‚Ð°
+  default_issue_status_feedback: ÐžÐ±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑÐ²ÑÐ·ÑŒ
+  default_issue_status_new: ÐÐ¾Ð²Ð°Ñ
+  default_issue_status_rejected: ÐžÑ‚ÐºÐ»Ð¾Ð½ÐµÐ½Ð°
+  default_issue_status_resolved: Ð ÐµÑˆÐµÐ½Ð°
+  default_priority_high: Ð’Ñ‹ÑÐ¾ÐºÐ¸Ð¹
+  default_priority_immediate: ÐÐµÐ¼ÐµÐ´Ð»ÐµÐ½Ð½Ñ‹Ð¹
+  default_priority_low: ÐÐ¸Ð·ÐºÐ¸Ð¹
+  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹
+  default_priority_urgent: Ð¡Ñ€Ð¾Ñ‡Ð½Ñ‹Ð¹
+  default_role_developer: Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸Ðº
+  default_role_manager: ÐœÐµÐ½ÐµÐ´Ð¶ÐµÑ€
+  default_role_reporter: Ð ÐµÐ¿Ð¾Ñ€Ñ‚Ñ‘Ñ€
+  default_tracker_bug: ÐžÑˆÐ¸Ð±ÐºÐ°
+  default_tracker_feature: Ð£Ð»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ðµ
+  default_tracker_support: ÐŸÐ¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ°
+
+  enumeration_activities: Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ (ÑƒÑ‡Ñ‘Ñ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸)
+  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ð²
+  enumeration_issue_priorities: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ñ‹ Ð·Ð°Ð´Ð°Ñ‡
+
+  error_can_not_remove_role: Ð­Ñ‚Ð° Ñ€Ð¾Ð»ÑŒ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÑ‚ÑÑ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ ÑƒÐ´Ð°Ð»ÐµÐ½Ð°.
+  error_can_not_delete_custom_field: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð½Ð°ÑÑ‚Ñ€Ð°Ð¸Ð²Ð°ÐµÐ¼Ð¾Ðµ Ð¿Ð¾Ð»Ðµ
+  error_can_not_delete_tracker: Ð­Ñ‚Ð¾Ñ‚ Ñ‚Ñ€ÐµÐºÐµÑ€ ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ ÑƒÐ´Ð°Ð»ÐµÐ½.
+  error_can_t_load_default_data: "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ Ð½Ðµ Ð±Ñ‹Ð»Ð° Ð·Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð°: %{value}"
+  error_issue_not_found_in_project: Ð—Ð°Ð´Ð°Ñ‡Ð° Ð½Ðµ Ð±Ñ‹Ð»Ð° Ð½Ð°Ð¹Ð´ÐµÐ½Ð° Ð¸Ð»Ð¸ Ð½Ðµ Ð¿Ñ€Ð¸ÐºÑ€ÐµÐ¿Ð»ÐµÐ½Ð° Ðº ÑÑ‚Ð¾Ð¼Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ
+  error_scm_annotate: "Ð”Ð°Ð½Ð½Ñ‹Ðµ Ð¾Ñ‚ÑÑƒÑ‚ÑÑ‚Ð²ÑƒÑŽÑ‚ Ð¸Ð»Ð¸ Ð½Ðµ Ð¼Ð¾Ð³ÑƒÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐ°Ð½Ñ‹."
+  error_scm_command_failed: "ÐžÑˆÐ¸Ð±ÐºÐ° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ñƒ: %{value}"
+  error_scm_not_found: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ Ð½Ðµ ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð¸/Ð¸Ð»Ð¸ Ð¸ÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ.
+  error_unable_to_connect: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒÑÑ (%{value})
+  error_unable_delete_issue_status: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+
+  field_account: Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ
+  field_activity: Ð”ÐµÑÑ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ
+  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
+  field_assignable: Ð—Ð°Ð´Ð°Ñ‡Ð° Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð° ÑÑ‚Ð¾Ð¹ Ñ€Ð¾Ð»Ð¸
+  field_assigned_to: ÐÐ°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð°
+  field_attr_firstname: Ð˜Ð¼Ñ
+  field_attr_lastname: Ð¤Ð°Ð¼Ð¸Ð»Ð¸Ñ
+  field_attr_login: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Login
+  field_attr_mail: email
+  field_author: ÐÐ²Ñ‚Ð¾Ñ€
+  field_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸
+  field_base_dn: BaseDN
+  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
+  field_column_names: Ð¡Ñ‚Ð¾Ð»Ð±Ñ†Ñ‹
+  field_comments: ÐšÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹
+  field_comments_sorting: ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²
+  field_content: Content
+  field_created_on: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¾
+  field_default_value: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  field_delay: ÐžÑ‚Ð»Ð¾Ð¶Ð¸Ñ‚ÑŒ
+  field_description: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ
+  field_done_ratio: Ð“Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ
+  field_downloads: Ð—Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸
+  field_due_date: Ð”Ð°Ñ‚Ð° Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ
+  field_editable: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€ÑƒÐµÐ¼Ð¾Ðµ
+  field_effective_date: Ð”Ð°Ñ‚Ð°
+  field_estimated_hours: ÐžÑ†ÐµÐ½ÐºÐ° Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
+  field_filename: Ð¤Ð°Ð¹Ð»
+  field_filesize: Ð Ð°Ð·Ð¼ÐµÑ€
+  field_firstname: Ð˜Ð¼Ñ
+  field_fixed_version: Ð’ÐµÑ€ÑÐ¸Ñ
+  field_hide_mail: Ð¡ÐºÑ€Ñ‹Ð²Ð°Ñ‚ÑŒ Ð¼Ð¾Ð¹ email
+  field_homepage: Ð¡Ñ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð°Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  field_host: ÐšÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€
+  field_hours: Ñ‡Ð°Ñ(Ð°,Ð¾Ð²)
+  field_identifier: Ð£Ð½Ð¸ÐºÐ°Ð»ÑŒÐ½Ñ‹Ð¹ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€
+  field_identity_url: OpenID URL
+  field_is_closed: Ð—Ð°Ð´Ð°Ñ‡Ð° Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð°
+  field_is_default: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  field_is_filter: Ð˜ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÑ‚ÑÑ Ð² ÐºÐ°Ñ‡ÐµÑÑ‚Ð²Ðµ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð°
+  field_is_for_all: Ð”Ð»Ñ Ð²ÑÐµÑ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  field_is_in_roadmap: Ð—Ð°Ð´Ð°Ñ‡Ð¸, Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ðµ Ð² Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ð¾Ð¼ Ð¿Ð»Ð°Ð½Ðµ
+  field_is_public: ÐžÐ±Ñ‰ÐµÐ´Ð¾ÑÑ‚ÑƒÐ¿Ð½Ñ‹Ð¹
+  field_is_required: ÐžÐ±ÑÐ·Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ðµ
+  field_issue_to: Ð¡Ð²ÑÐ·Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  field_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
+  field_language: Ð¯Ð·Ñ‹Ðº
+  field_last_login_on: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½ÐµÐµ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ
+  field_lastname: Ð¤Ð°Ð¼Ð¸Ð»Ð¸Ñ
+  field_login: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ
+  field_mail: Email
+  field_mail_notification: Ð£Ð²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ email
+  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°
+  field_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°
+  field_name: Ð˜Ð¼Ñ
+  field_new_password: ÐÐ¾Ð²Ñ‹Ð¹ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
+  field_notes: ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ
+  field_onthefly: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ð° Ð»ÐµÑ‚Ñƒ
+  field_parent_title: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑÐºÐ°Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  field_parent: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑÐºÐ¸Ð¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  field_parent_issue: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑÐºÐ°Ñ Ð·Ð°Ð´Ð°Ñ‡Ð°
+  field_password_confirmation: ÐŸÐ¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ðµ
+  field_password: ÐŸÐ°Ñ€Ð¾Ð»ÑŒ
+  field_port: ÐŸÐ¾Ñ€Ñ‚
+  field_possible_values: Ð’Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ‹Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ
+  field_priority: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
+  field_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
+  field_redirect_existing_links: ÐŸÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÑŒ ÑÑƒÑ‰ÐµÑÑ‚Ð²ÑƒÑŽÑ‰Ð¸Ðµ ÑÑÑ‹Ð»ÐºÐ¸
+  field_regexp: Ð ÐµÐ³ÑƒÐ»ÑÑ€Ð½Ð¾Ðµ Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ
+  field_role: Ð Ð¾Ð»ÑŒ
+  field_searchable: Ð”Ð¾ÑÑ‚ÑƒÐ¿Ð½Ð¾ Ð´Ð»Ñ Ð¿Ð¾Ð¸ÑÐºÐ°
+  field_spent_on: Ð”Ð°Ñ‚Ð°
+  field_start_date: ÐÐ°Ñ‡Ð°Ñ‚Ð°
+  field_start_page: Ð¡Ñ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð°Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  field_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ
+  field_subject: Ð¢ÐµÐ¼Ð°
+  field_subproject: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  field_summary: ÐšÑ€Ð°Ñ‚ÐºÐ¾Ðµ Ð¾Ð¿Ð¸ÑÐ°Ð½Ð¸Ðµ
+  field_text: Ð¢ÐµÐºÑÑ‚Ð¾Ð²Ð¾Ðµ Ð¿Ð¾Ð»Ðµ
+  field_time_entries: Ð—Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
+  field_time_zone: Ð§Ð°ÑÐ¾Ð²Ð¾Ð¹ Ð¿Ð¾ÑÑ
+  field_title: Ð—Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº
+  field_tracker: Ð¢Ñ€ÐµÐºÐµÑ€
+  field_type: Ð¢Ð¸Ð¿
+  field_updated_on: ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾
+  field_url: URL
+  field_user: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ
+  field_value: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ
+  field_version: Ð’ÐµÑ€ÑÐ¸Ñ
+  field_watcher: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»ÑŒ
+
+  general_csv_decimal_separator: ','
+  general_csv_encoding: UTF-8
+  general_csv_separator: ';'
+  general_first_day_of_week: '1'
+  general_lang_name: 'Russian (Ð ÑƒÑÑÐºÐ¸Ð¹)'
+  general_pdf_encoding: UTF-8
+  general_text_no: 'Ð½ÐµÑ‚'
+  general_text_No: 'ÐÐµÑ‚'
+  general_text_yes: 'Ð´Ð°'
+  general_text_Yes: 'Ð”Ð°'
+
+  label_activity: Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ
+  label_add_another_file: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ ÐµÑ‰Ñ‘ Ð¾Ð´Ð¸Ð½ Ñ„Ð°Ð¹Ð»
+  label_added_time_by: "Ð”Ð¾Ð±Ð°Ð²Ð¸Ð»(Ð°) %{author} %{age} Ð½Ð°Ð·Ð°Ð´"
+  label_added: Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¾
+  label_add_note: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ðµ
+  label_administration: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ
+  label_age: Ð’Ð¾Ð·Ñ€Ð°ÑÑ‚
+  label_ago: Ð´Ð½ÐµÐ¹(Ñ) Ð½Ð°Ð·Ð°Ð´
+  label_all_time: Ð²ÑÑ‘ Ð²Ñ€ÐµÐ¼Ñ
+  label_all_words: Ð’ÑÐµ ÑÐ»Ð¾Ð²Ð°
+  label_all: Ð²ÑÐµ
+  label_and_its_subprojects: "%{value} Ð¸ Ð²ÑÐµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹"
+  label_applied_status: ÐŸÑ€Ð¸Ð¼ÐµÐ½Ð¸Ð¼Ñ‹Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_ascending: ÐŸÐ¾ Ð²Ð¾Ð·Ñ€Ð°ÑÑ‚Ð°Ð½Ð¸ÑŽ
+  label_assigned_to_me_issues: ÐœÐ¾Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_associated_revisions: Ð¡Ð²ÑÐ·Ð°Ð½Ð½Ñ‹Ðµ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
+  label_attachment: Ð¤Ð°Ð¹Ð»
+  label_attachment_delete: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ñ„Ð°Ð¹Ð»
+  label_attachment_new: ÐÐ¾Ð²Ñ‹Ð¹ Ñ„Ð°Ð¹Ð»
+  label_attachment_plural: Ð¤Ð°Ð¹Ð»Ñ‹
+  label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
+  label_attribute_plural: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚Ñ‹
+  label_authentication: ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ
+  label_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸
+  label_auth_source_new: ÐÐ¾Ð²Ñ‹Ð¹ Ñ€ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸
+  label_auth_source_plural: Ð ÐµÐ¶Ð¸Ð¼Ñ‹ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸
+  label_blocked_by: Ð±Ð»Ð¾ÐºÐ¸Ñ€ÑƒÐµÑ‚ÑÑ
+  label_blocks: Ð±Ð»Ð¾ÐºÐ¸Ñ€ÑƒÐµÑ‚
+  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
+  label_board_new: ÐÐ¾Ð²Ñ‹Ð¹ Ñ„Ð¾Ñ€ÑƒÐ¼
+  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ñ‹
+  label_boolean: Ð›Ð¾Ð³Ð¸Ñ‡ÐµÑÐºÐ¸Ð¹
+  label_browse: ÐžÐ±Ð·Ð¾Ñ€
+  label_bulk_edit_selected_issues: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð²ÑÐµ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€ÑŒ
+  label_calendar_filter: Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ
+  label_calendar_no_assigned: Ð½Ðµ Ð¼Ð¾Ð¸
+  label_change_plural: ÐŸÑ€Ð°Ð²ÐºÐ¸
+  label_change_properties: Ð˜Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ ÑÐ²Ð¾Ð¹ÑÑ‚Ð²Ð°
+  label_change_status: Ð˜Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_change_view_all: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ð²ÑÐµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ
+  label_changes_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð¾ÑÑ‚Ð¸ Ð¿Ð¾ Ð²ÑÐµÐ¼ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸ÑÐ¼
+  label_changeset_plural: Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ
+  label_chronological_order: Ð’ Ñ…Ñ€Ð¾Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑÐºÐ¾Ð¼ Ð¿Ð¾Ñ€ÑÐ´ÐºÐµ
+  label_closed_issues: Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾
+  label_closed_issues_plural: Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾
+  label_closed_issues_plural2: Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾
+  label_closed_issues_plural5: Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾
+  label_comment: ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹
+  label_comment_add: ÐžÑÑ‚Ð°Ð²Ð¸Ñ‚ÑŒ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹
+  label_comment_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð½Ñ‹Ð¹ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹
+  label_comment_delete: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¸
+  label_comment_plural: ÐšÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¸
+  label_comment_plural2: ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ
+  label_comment_plural5: ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²
+  label_commits_per_author: Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ð½Ð° Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ
+  label_commits_per_month: Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ð² Ð¼ÐµÑÑÑ†
+  label_confirmation: ÐŸÐ¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ðµ
+  label_contains: ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚
+  label_copied: ÑÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¾
+  label_copy_workflow_from: Ð¡ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹ Ð¸Ð·
+  label_current_status: Ð¢ÐµÐºÑƒÑ‰Ð¸Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_current_version: Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ
+  label_custom_field: ÐÐ°ÑÑ‚Ñ€Ð°Ð¸Ð²Ð°ÐµÐ¼Ð¾Ðµ Ð¿Ð¾Ð»Ðµ
+  label_custom_field_new: ÐÐ¾Ð²Ð¾Ðµ Ð½Ð°ÑÑ‚Ñ€Ð°Ð¸Ð²Ð°ÐµÐ¼Ð¾Ðµ Ð¿Ð¾Ð»Ðµ
+  label_custom_field_plural: ÐÐ°ÑÑ‚Ñ€Ð°Ð¸Ð²Ð°ÐµÐ¼Ñ‹Ðµ Ð¿Ð¾Ð»Ñ
+  label_date_from: Ð¡
+  label_date_from_to: Ð¡ %{start} Ð¿Ð¾ %{end}
+  label_date_range: Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð¹ Ð¸Ð½Ñ‚ÐµÑ€Ð²Ð°Ð»
+  label_date_to: Ð¿Ð¾
+  label_date: Ð”Ð°Ñ‚Ð°
+  label_day_plural: Ð´Ð½ÐµÐ¹(Ñ)
+  label_default: ÐŸÐ¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  label_default_columns: Ð¡Ñ‚Ð¾Ð»Ð±Ñ†Ñ‹ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  label_deleted: ÑƒÐ´Ð°Ð»ÐµÐ½Ð¾
+  label_descending: ÐŸÐ¾ ÑƒÐ±Ñ‹Ð²Ð°Ð½Ð¸ÑŽ
+  label_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð¾ÑÑ‚Ð¸
+  label_diff_inline: Ð² Ñ‚ÐµÐºÑÑ‚Ðµ
+  label_diff_side_by_side: Ñ€ÑÐ´Ð¾Ð¼
+  label_disabled: Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¾
+  label_display: ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ
+  label_display_per_page: "ÐÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ: %{value}"
+  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
+  label_downloads_abbr: Ð¡ÐºÐ°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ð¹
+  label_duplicated_by: Ð´ÑƒÐ±Ð»Ð¸Ñ€ÑƒÐµÑ‚ÑÑ
+  label_duplicates: Ð´ÑƒÐ±Ð»Ð¸Ñ€ÑƒÐµÑ‚
+  label_end_to_end: Ñ ÐºÐ¾Ð½Ñ†Ð° Ðº ÐºÐ¾Ð½Ñ†Ñƒ
+  label_end_to_start: Ñ ÐºÐ¾Ð½Ñ†Ð° Ðº Ð½Ð°Ñ‡Ð°Ð»Ñƒ
+  label_enumeration_new: ÐÐ¾Ð²Ð¾Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ
+  label_enumerations: Ð¡Ð¿Ð¸ÑÐºÐ¸ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹
+  label_environment: ÐžÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ðµ
+  label_equals: ÑÐ¾Ð¾Ñ‚Ð²ÐµÑ‚ÑÑ‚Ð²ÑƒÐµÑ‚
+  label_example: ÐŸÑ€Ð¸Ð¼ÐµÑ€
+  label_export_to: Ð­ÐºÑÐ¿Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð²
+  label_feed_plural: RSS
+  label_feeds_access_key_created_on: "ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° RSS ÑÐ¾Ð·Ð´Ð°Ð½ %{value} Ð½Ð°Ð·Ð°Ð´"
+  label_f_hour: "%{value} Ñ‡Ð°Ñ"
+  label_f_hour_plural: "%{value} Ñ‡Ð°ÑÐ¾Ð²"
+  label_file_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ Ñ„Ð°Ð¹Ð»
+  label_file_plural: Ð¤Ð°Ð¹Ð»Ñ‹
+  label_filter_add: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€
+  label_filter_plural: Ð¤Ð¸Ð»ÑŒÑ‚Ñ€Ñ‹
+  label_float: Ð¡ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ Ñ‚Ð¾Ñ‡ÐºÐ¾Ð¹
+  label_follows: Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ
+  label_gantt: Ð”Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ð° Ð“Ð°Ð½Ñ‚Ð°
+  label_general: ÐžÐ±Ñ‰ÐµÐµ
+  label_generate_key: Ð¡Ð³ÐµÐ½ÐµÑ€Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ ÐºÐ»ÑŽÑ‡
+  label_greater_or_equal: ">="
+  label_help: ÐŸÐ¾Ð¼Ð¾Ñ‰ÑŒ
+  label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ
+  label_home: Ð”Ð¾Ð¼Ð°ÑˆÐ½ÑÑ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  label_incoming_emails: ÐŸÑ€Ð¸Ñ‘Ð¼ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+  label_index_by_date: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
+  label_index_by_title: ÐžÐ³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ
+  label_information_plural: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
+  label_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ
+  label_in_less_than: Ð¼ÐµÐ½ÐµÐµ Ñ‡ÐµÐ¼
+  label_in_more_than: Ð±Ð¾Ð»ÐµÐµ Ñ‡ÐµÐ¼
+  label_integer: Ð¦ÐµÐ»Ñ‹Ð¹
+  label_internal: Ð’Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½Ð¸Ð¹
+  label_in: Ð²
+  label_issue: Ð—Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_category_new: ÐÐ¾Ð²Ð°Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ
+  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_new: ÐÐ¾Ð²Ð°Ñ Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_plural: Ð—Ð°Ð´Ð°Ñ‡Ð¸
+  label_issues_by: "Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ %{value}"
+  label_issue_status_new: ÐÐ¾Ð²Ñ‹Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_issue_status_plural: Ð¡Ñ‚Ð°Ñ‚ÑƒÑÑ‹ Ð·Ð°Ð´Ð°Ñ‡
+  label_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_tracking: Ð—Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_updated: ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
+  label_issue_view_all: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ð²ÑÐµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_issue_watchers: ÐÐ°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»Ð¸
+  label_jump_to_a_project: ÐŸÐµÑ€ÐµÐ¹Ñ‚Ð¸ Ðº Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ...
+  label_language_based: ÐÐ° Ð¾ÑÐ½Ð¾Ð²Ðµ ÑÐ·Ñ‹ÐºÐ°
+  label_last_changes: "Ð¼ÐµÐ½ÐµÐµ %{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹"
+  label_last_login: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½ÐµÐµ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ
+  label_last_month: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ð¹ Ð¼ÐµÑÑÑ†
+  label_last_n_days: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ %{count} Ð´Ð½ÐµÐ¹"
+  label_last_week: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½ÑÑ Ð½ÐµÐ´ÐµÐ»Ñ
+  label_latest_revision: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½ÑÑ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ñ
+  label_latest_revision_plural: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
+  label_ldap_authentication: ÐÐ²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ LDAP
+  label_less_or_equal: <=
+  label_less_than_ago: Ð¼ÐµÐ½ÐµÐµ, Ñ‡ÐµÐ¼ Ð´Ð½ÐµÐ¹(Ñ) Ð½Ð°Ð·Ð°Ð´
+  label_list: Ð¡Ð¿Ð¸ÑÐ¾Ðº
+  label_loading: Ð—Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°...
+  label_logged_as: Ð’Ð¾ÑˆÐ»Ð¸ ÐºÐ°Ðº
+  label_login: Ð’Ð¾Ð¹Ñ‚Ð¸
+  label_login_with_open_id_option: Ð¸Ð»Ð¸ Ð²Ð¾Ð¹Ñ‚Ð¸ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ OpenID
+  label_logout: Ð’Ñ‹Ð¹Ñ‚Ð¸
+  label_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ Ñ€Ð°Ð·Ð¼ÐµÑ€
+  label_member_new: ÐÐ¾Ð²Ñ‹Ð¹ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸Ðº
+  label_member: Ð£Ñ‡Ð°ÑÑ‚Ð½Ð¸Ðº
+  label_member_plural: Ð£Ñ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ¸
+  label_message_last: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½ÐµÐµ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
+  label_message_new: ÐÐ¾Ð²Ð¾Ðµ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
+  label_message_plural: Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ
+  label_message_posted: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¾ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
+  label_me: Ð¼Ð½Ðµ
+  label_min_max_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ - Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°
+  label_modified: Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¾
+  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ð¸
+  label_months_from: Ð¼ÐµÑÑÑ†ÐµÐ²(Ñ†Ð°) Ñ
+  label_month: ÐœÐµÑÑÑ†
+  label_more_than_ago: Ð±Ð¾Ð»ÐµÐµ, Ñ‡ÐµÐ¼ Ð´Ð½ÐµÐ¹(Ñ) Ð½Ð°Ð·Ð°Ð´
+  label_more: Ð‘Ð¾Ð»ÑŒÑˆÐµ
+  label_my_account: ÐœÐ¾Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ
+  label_my_page: ÐœÐ¾Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  label_my_page_block: Ð‘Ð»Ð¾Ðº Ð¼Ð¾ÐµÐ¹ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹
+  label_my_projects: ÐœÐ¾Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
+  label_new: ÐÐ¾Ð²Ñ‹Ð¹
+  label_new_statuses_allowed: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð½Ñ‹Ðµ Ð½Ð¾Ð²Ñ‹Ðµ ÑÑ‚Ð°Ñ‚ÑƒÑÑ‹
+  label_news_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð° Ð½Ð¾Ð²Ð¾ÑÑ‚ÑŒ
+  label_news_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
+  label_news_new: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ð½Ð¾Ð²Ð¾ÑÑ‚ÑŒ
+  label_news_plural: ÐÐ¾Ð²Ð¾ÑÑ‚Ð¸
+  label_news_view_all: ÐŸÐ¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ð²ÑÐµ Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
+  label_news: ÐÐ¾Ð²Ð¾ÑÑ‚Ð¸
+  label_next: Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰ÐµÐµ
+  label_nobody: Ð½Ð¸ÐºÑ‚Ð¾
+  label_no_change_option: (ÐÐµÑ‚ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹)
+  label_no_data: ÐÐµÑ‚ Ð´Ð°Ð½Ð½Ñ‹Ñ… Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ
+  label_none: Ð¾Ñ‚ÑÑƒÑ‚ÑÑ‚Ð²ÑƒÐµÑ‚
+  label_not_contains: Ð½Ðµ ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚
+  label_not_equals: Ð½Ðµ ÑÐ¾Ð¾Ñ‚Ð²ÐµÑ‚ÑÑ‚Ð²ÑƒÐµÑ‚
+  label_open_issues: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾
+  label_open_issues_plural: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾
+  label_open_issues_plural2: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾
+  label_open_issues_plural5: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾
+  label_optional_description: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ (Ð½ÐµÐ¾Ð±ÑÐ·Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾)
+  label_options: ÐžÐ¿Ñ†Ð¸Ð¸
+  label_overall_activity: Ð¡Ð²Ð¾Ð´Ð½Ñ‹Ð¹ Ð¾Ñ‚Ñ‡Ñ‘Ñ‚ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹
+  label_overview: ÐžÐ±Ð·Ð¾Ñ€
+  label_password_lost: Ð’Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¿Ð°Ñ€Ð¾Ð»Ñ
+  label_permissions_report: ÐžÑ‚Ñ‡Ñ‘Ñ‚ Ð¿Ð¾ Ð¿Ñ€Ð°Ð²Ð°Ð¼ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð°
+  label_permissions: ÐŸÑ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð°
+  label_per_page: ÐÐ° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ
+  label_personalize_page: ÐŸÐµÑ€ÑÐ¾Ð½Ð°Ð»Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð´Ð°Ð½Ð½ÑƒÑŽ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ
+  label_planning: ÐŸÐ»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ
+  label_please_login: ÐŸÐ¾Ð¶Ð°Ð»ÑƒÐ¹ÑÑ‚Ð°, Ð²Ð¾Ð¹Ð´Ð¸Ñ‚Ðµ.
+  label_plugins: ÐœÐ¾Ð´ÑƒÐ»Ð¸
+  label_precedes: ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ
+  label_preferences: ÐŸÑ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ
+  label_preview: ÐŸÑ€ÐµÐ´Ð¿Ñ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€
+  label_previous: ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰ÐµÐµ
+  label_profile: ÐŸÑ€Ð¾Ñ„Ð¸Ð»ÑŒ
+  label_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
+  label_project_all: Ð’ÑÐµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
+  label_project_copy_notifications: ÐžÑ‚Ð¿Ñ€Ð°Ð²Ð»ÑÑ‚ÑŒ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ð¹ Ð¿Ð¾Ñ‡Ñ‚Ðµ Ð¿Ñ€Ð¸ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
+  label_project_latest: ÐŸÐ¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
+  label_project_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_project_plural: ÐŸÑ€Ð¾ÐµÐºÑ‚Ñ‹
+  label_project_plural2: Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
+  label_project_plural5: Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  label_public_projects: ÐžÐ±Ñ‰Ð¸Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
+  label_query: Ð¡Ð¾Ñ…Ñ€Ð°Ð½Ñ‘Ð½Ð½Ñ‹Ð¹ Ð·Ð°Ð¿Ñ€Ð¾Ñ
+  label_query_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð·Ð°Ð¿Ñ€Ð¾Ñ
+  label_query_plural: Ð¡Ð¾Ñ…Ñ€Ð°Ð½Ñ‘Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð¿Ñ€Ð¾ÑÑ‹
+  label_read: Ð§Ñ‚ÐµÐ½Ð¸Ðµ...
+  label_register: Ð ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
+  label_registered_on: Ð—Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½(Ð°)
+  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ñ‹Ñ… Ð·Ð°Ð¿Ð¸ÑÐµÐ¹ Ð¿Ð¾ email
+  label_registration_automatic_activation: Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑÐºÐ°Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ñ‹Ñ… Ð·Ð°Ð¿Ð¸ÑÐµÐ¹
+  label_registration_manual_activation: Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ ÑƒÑ‡Ñ‘Ñ‚Ð½Ñ‹Ðµ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ
+  label_related_issues: Ð¡Ð²ÑÐ·Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_relates_to: ÑÐ²ÑÐ·Ð°Ð½Ð° Ñ
+  label_relation_delete: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ ÑÐ²ÑÐ·ÑŒ
+  label_relation_new: ÐÐ¾Ð²Ð¾Ðµ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ðµ
+  label_renamed: Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¾
+  label_reply_plural: ÐžÑ‚Ð²ÐµÑ‚Ñ‹
+  label_report: ÐžÑ‚Ñ‡Ñ‘Ñ‚
+  label_report_plural: ÐžÑ‚Ñ‡Ñ‘Ñ‚Ñ‹
+  label_reported_issues: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_repository: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  label_repository_plural: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
+  label_result_plural: Ð ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ‹
+  label_reverse_chronological_order: Ð’ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾Ð¼ Ð¿Ð¾Ñ€ÑÐ´ÐºÐµ
+  label_revision: Ð ÐµÐ´Ð°ÐºÑ†Ð¸Ñ
+  label_revision_plural: Ð ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
+  label_roadmap: ÐžÐ¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ñ‹Ð¹ Ð¿Ð»Ð°Ð½
+  label_roadmap_due_in: "Ð’ ÑÑ€Ð¾Ðº %{value}"
+  label_roadmap_no_issues: ÐÐµÑ‚ Ð·Ð°Ð´Ð°Ñ‡ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ Ð²ÐµÑ€ÑÐ¸Ð¸
+  label_roadmap_overdue: "Ð¾Ð¿Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ %{value}"
+  label_role: Ð Ð¾Ð»ÑŒ
+  label_role_and_permissions: Ð Ð¾Ð»Ð¸ Ð¸ Ð¿Ñ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð°
+  label_role_new: ÐÐ¾Ð²Ð°Ñ Ñ€Ð¾Ð»ÑŒ
+  label_role_plural: Ð Ð¾Ð»Ð¸
+  label_scm: Ð¢Ð¸Ð¿ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
+  label_search: ÐŸÐ¾Ð¸ÑÐº
+  label_search_titles_only: Ð˜ÑÐºÐ°Ñ‚ÑŒ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð² Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÑÑ…
+  label_send_information: ÐžÑ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÑŒ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŽ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÑŽ Ð¿Ð¾ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸
+  label_send_test_email: ÐŸÐ¾ÑÐ»Ð°Ñ‚ÑŒ email Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸
+  label_settings: ÐÐ°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸
+  label_show_completed_versions: ÐŸÐ¾ÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ Ð·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½Ð½Ñ‹Ðµ Ð²ÐµÑ€ÑÐ¸Ð¸
+  label_sort: Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  label_sort_by: "Ð¡Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ %{value}"
+  label_sort_higher: Ð’Ð²ÐµÑ€Ñ…
+  label_sort_highest: Ð’ Ð½Ð°Ñ‡Ð°Ð»Ð¾
+  label_sort_lower: Ð’Ð½Ð¸Ð·
+  label_sort_lowest: Ð’ ÐºÐ¾Ð½ÐµÑ†
+  label_spent_time: Ð—Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
+  label_start_to_end: Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° Ðº ÐºÐ¾Ð½Ñ†Ñƒ
+  label_start_to_start: Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° Ðº Ð½Ð°Ñ‡Ð°Ð»Ñƒ
+  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ°
+  label_stay_logged_in: ÐžÑÑ‚Ð°Ð²Ð°Ñ‚ÑŒÑÑ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ðµ
+  label_string: Ð¢ÐµÐºÑÑ‚
+  label_subproject_plural: ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
+  label_subtask_plural: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_text: Ð”Ð»Ð¸Ð½Ð½Ñ‹Ð¹ Ñ‚ÐµÐºÑÑ‚
+  label_theme: Ð¢ÐµÐ¼Ð°
+  label_this_month: ÑÑ‚Ð¾Ñ‚ Ð¼ÐµÑÑÑ†
+  label_this_week: Ð½Ð° ÑÑ‚Ð¾Ð¹ Ð½ÐµÐ´ÐµÐ»Ðµ
+  label_this_year: ÑÑ‚Ð¾Ñ‚ Ð³Ð¾Ð´
+  label_time_tracking: Ð£Ñ‡Ñ‘Ñ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  label_timelog_today: Ð Ð°ÑÑ…Ð¾Ð´ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ Ð½Ð° ÑÐµÐ³Ð¾Ð´Ð½Ñ
+  label_today: ÑÐµÐ³Ð¾Ð´Ð½Ñ
+  label_topic_plural: Ð¢ÐµÐ¼Ñ‹
+  label_total: Ð’ÑÐµÐ³Ð¾
+  label_tracker: Ð¢Ñ€ÐµÐºÐµÑ€
+  label_tracker_new: ÐÐ¾Ð²Ñ‹Ð¹ Ñ‚Ñ€ÐµÐºÐµÑ€
+  label_tracker_plural: Ð¢Ñ€ÐµÐºÐµÑ€Ñ‹
+  label_updated_time: "ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾ %{value} Ð½Ð°Ð·Ð°Ð´"
+  label_updated_time_by: "ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾ %{author} %{age} Ð½Ð°Ð·Ð°Ð´"
+  label_used_by: Ð˜ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÑ‚ÑÑ
+  label_user: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ
+  label_user_activity: "Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %{value}"
+  label_user_mail_no_self_notified: "ÐÐµ Ð¸Ð·Ð²ÐµÑ‰Ð°Ñ‚ÑŒ Ð¾Ð± Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸ÑÑ…, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ñ ÑÐ´ÐµÐ»Ð°Ð» ÑÐ°Ð¼"
+  label_user_mail_option_all: "Ðž Ð²ÑÐµÑ… ÑÐ¾Ð±Ñ‹Ñ‚Ð¸ÑÑ… Ð²Ð¾ Ð²ÑÐµÑ… Ð¼Ð¾Ð¸Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ñ…"
+  label_user_mail_option_selected: "Ðž Ð²ÑÐµÑ… ÑÐ¾Ð±Ñ‹Ñ‚Ð¸ÑÑ… Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð² Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð¾Ð¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ðµ..."
+  label_user_mail_option_only_owner: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð², Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… Ñ ÑÐ²Ð»ÑÑŽÑÑŒ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼
+  label_user_mail_option_only_my_events: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð², ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ñ Ð¾Ñ‚ÑÐ»ÐµÐ¶Ð¸Ð²Ð°ÑŽ Ð¸Ð»Ð¸ Ð² ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… ÑƒÑ‡Ð°ÑÑ‚Ð²ÑƒÑŽ
+  label_user_mail_option_only_assigned: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð², ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ñ‹ Ð¼Ð½Ðµ
+  label_user_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ
+  label_user_plural: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ð¸
+  label_version: Ð’ÐµÑ€ÑÐ¸Ñ
+  label_version_new: ÐÐ¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ
+  label_version_plural: Ð’ÐµÑ€ÑÐ¸Ð¸
+  label_view_diff: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ð¾Ñ‚Ð»Ð¸Ñ‡Ð¸Ñ
+  label_view_revisions: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ÐµÑ‚ÑŒ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸
+  label_watched_issues: ÐžÑ‚ÑÐ»ÐµÐ¶Ð¸Ð²Ð°ÐµÐ¼Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_week: ÐÐµÐ´ÐµÐ»Ñ
+  label_wiki: Wiki
+  label_wiki_edit: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Wiki
+  label_wiki_edit_plural: Wiki
+  label_wiki_page: Ð¡Ñ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Wiki
+  label_wiki_page_plural: Ð¡Ñ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Wiki
+  label_workflow: ÐŸÐ¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹
+  label_x_closed_issues_abbr:
+    zero:  "0 Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾"
+    one:   "1 Ð·Ð°ÐºÑ€Ñ‹Ñ‚"
+    few:   "%{count} Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾"
+    many:  "%{count} Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾"
+    other: "%{count} Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾"
+  label_x_comments:
+    zero:  "Ð½ÐµÑ‚ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²"
+    one:   "1 ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹"
+    few:   "%{count} ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ"
+    many:  "%{count} ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²"
+    other: "%{count} ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²"
+  label_x_open_issues_abbr:
+    zero:  "0 Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾"
+    one:   "1 Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚"
+    few:   "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾"
+    many:  "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾"
+    other: "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾"
+  label_x_open_issues_abbr_on_total:
+    zero:  "0 Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾ / %{total}"
+    one:   "1 Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ / %{total}"
+    few:   "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾ / %{total}"
+    many:  "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾ / %{total}"
+    other: "%{count} Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¾ / %{total}"
+  label_x_projects:
+    zero:  "Ð½ÐµÑ‚ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²"
+    one:   "1 Ð¿Ñ€Ð¾ÐµÐºÑ‚"
+    few:   "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°"
+    many:  "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²"
+    other: "%{count} Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²"
+  label_year: Ð“Ð¾Ð´
+  label_yesterday: Ð²Ñ‡ÐµÑ€Ð°
+
+  mail_body_account_activation_request: "Ð—Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½ Ð½Ð¾Ð²Ñ‹Ð¹ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ (%{value}). Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ‚ Ð’Ð°ÑˆÐµÐ³Ð¾ ÑƒÑ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ:"
+  mail_body_account_information: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ Ð’Ð°ÑˆÐµÐ¹ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸
+  mail_body_account_information_external: "Ð’Ñ‹ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÑŒ Ð’Ð°ÑˆÑƒ %{value} ÑƒÑ‡Ñ‘Ñ‚Ð½ÑƒÑŽ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð°."
+  mail_body_lost_password: 'Ð”Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð¿Ñ€Ð¾Ð¹Ð´Ð¸Ñ‚Ðµ Ð¿Ð¾ ÑÐ»ÐµÐ´ÑƒÑŽÑ‰ÐµÐ¹ ÑÑÑ‹Ð»ÐºÐµ:'
+  mail_body_register: 'Ð”Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ð¸ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð¿Ñ€Ð¾Ð¹Ð´Ð¸Ñ‚Ðµ Ð¿Ð¾ ÑÐ»ÐµÐ´ÑƒÑŽÑ‰ÐµÐ¹ ÑÑÑ‹Ð»ÐºÐµ:'
+  mail_body_reminder: "%{count} Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ‹Ñ… Ð½Ð° Ð’Ð°Ñ Ð·Ð°Ð´Ð°Ñ‡ Ð½Ð° ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð¸Ðµ %{days} Ð´Ð½ÐµÐ¹:"
+  mail_subject_account_activation_request: "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸ÑŽ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ðµ %{value}"
+  mail_subject_lost_password: "Ð’Ð°Ñˆ %{value} Ð¿Ð°Ñ€Ð¾Ð»ÑŒ"
+  mail_subject_register: "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ %{value}"
+  mail_subject_reminder: "%{count} Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ‹Ñ… Ð½Ð° Ð’Ð°Ñ Ð·Ð°Ð´Ð°Ñ‡ Ð² Ð±Ð»Ð¸Ð¶Ð°Ð¹ÑˆÐ¸Ðµ %{days} Ð´Ð½ÐµÐ¹"
+
+  notice_account_activated: Ð’Ð°ÑˆÐ° ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð°. Ð’Ñ‹ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð²Ð¾Ð¹Ñ‚Ð¸.
+  notice_account_invalid_creditentials: ÐÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ðµ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
+  notice_account_lost_email_sent: Ð’Ð°Ð¼ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¾ Ð¿Ð¸ÑÑŒÐ¼Ð¾ Ñ Ð¸Ð½ÑÑ‚Ñ€ÑƒÐºÑ†Ð¸ÑÐ¼Ð¸ Ð¿Ð¾ Ð²Ñ‹Ð±Ð¾Ñ€Ñƒ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ð¿Ð°Ñ€Ð¾Ð»Ñ.
+  notice_account_password_updated: ÐŸÐ°Ñ€Ð¾Ð»ÑŒ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð¾Ð±Ð½Ð¾Ð²Ð»Ñ‘Ð½.
+  notice_account_pending: "Ð’Ð°ÑˆÐ° ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ ÑÐ¾Ð·Ð´Ð°Ð½Ð° Ð¸ Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ‚ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð°."
+  notice_account_register_done: Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑÐ¾Ð·Ð´Ð°Ð½Ð°. Ð”Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ð¸ Ð’Ð°ÑˆÐµÐ¹ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð¿Ñ€Ð¾Ð¹Ð´Ð¸Ñ‚Ðµ Ð¿Ð¾ ÑÑÑ‹Ð»ÐºÐµ, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð²Ñ‹ÑÐ»Ð°Ð½Ð° Ð’Ð°Ð¼ Ð¿Ð¾ ÑÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ð¹ Ð¿Ð¾Ñ‡Ñ‚Ðµ.
+  notice_account_unknown_email: ÐÐµÐ¸Ð·Ð²ÐµÑÑ‚Ð½Ñ‹Ð¹ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ.
+  notice_account_updated: Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð°.
+  notice_account_wrong_password: ÐÐµÐ²ÐµÑ€Ð½Ñ‹Ð¹ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
+  notice_can_t_change_password: Ð”Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÑ‚ÑÑ Ð¸ÑÑ‚Ð¾Ñ‡Ð½Ð¸Ðº Ð²Ð½ÐµÑˆÐ½ÐµÐ¹ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸. ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ.
+  notice_default_data_loaded: Ð‘Ñ‹Ð»Ð° Ð·Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð° ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ.
+  notice_email_error: "Ð’Ð¾ Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ Ð¿Ð¸ÑÑŒÐ¼Ð° Ð¿Ñ€Ð¾Ð¸Ð·Ð¾ÑˆÐ»Ð° Ð¾ÑˆÐ¸Ð±ÐºÐ° (%{value})"
+  notice_email_sent: "ÐžÑ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¾ Ð¿Ð¸ÑÑŒÐ¼Ð¾ %{value}"
+  notice_failed_to_save_issues: "ÐÐµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ ÑÐ¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ %{count} Ð¿ÑƒÐ½ÐºÑ‚(Ð¾Ð²) Ð¸Ð· %{total} Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ…: %{ids}."
+  notice_failed_to_save_members: "ÐÐµ ÑƒÐ´Ð°Ð»Ð¾ÑÑŒ ÑÐ¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ°(Ð¾Ð²): %{errors}."
+  notice_feeds_access_key_reseted: Ð’Ð°Ñˆ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° RSS Ð±Ñ‹Ð» ÑÐ±Ñ€Ð¾ÑˆÐµÐ½.
+  notice_file_not_found: Ð¡Ñ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°, Ð½Ð° ÐºÐ¾Ñ‚Ð¾Ñ€ÑƒÑŽ Ð’Ñ‹ Ð¿Ñ‹Ñ‚Ð°ÐµÑ‚ÐµÑÑŒ Ð·Ð°Ð¹Ñ‚Ð¸, Ð½Ðµ ÑÑƒÑ‰ÐµÑÑ‚Ð²ÑƒÐµÑ‚ Ð¸Ð»Ð¸ ÑƒÐ´Ð°Ð»ÐµÐ½Ð°.
+  notice_locking_conflict: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð° Ð´Ñ€ÑƒÐ³Ð¸Ð¼ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¼.
+  notice_no_issue_selected: "ÐÐµ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð¾ Ð½Ð¸ Ð¾Ð´Ð½Ð¾Ð¹ Ð·Ð°Ð´Ð°Ñ‡Ð¸! ÐŸÐ¾Ð¶Ð°Ð»ÑƒÐ¹ÑÑ‚Ð°, Ð¾Ñ‚Ð¼ÐµÑ‚ÑŒÑ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð’Ñ‹ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ Ð¾Ñ‚Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ."
+  notice_not_authorized: Ð£ Ð’Ð°Ñ Ð½ÐµÑ‚ Ð¿Ñ€Ð°Ð² Ð´Ð»Ñ Ð¿Ð¾ÑÐµÑ‰ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹.
+  notice_successful_connection: ÐŸÐ¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾ ÑƒÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾.
+  notice_successful_create: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
+  notice_successful_delete: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
+  notice_successful_update: ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ ÑƒÑÐ¿ÐµÑˆÐ½Ð¾.
+  notice_unable_delete_version: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð²ÐµÑ€ÑÐ¸ÑŽ.
+
+  permission_add_issues: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡
+  permission_add_issue_notes: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ð¹
+  permission_add_issue_watchers: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»ÐµÐ¹
+  permission_add_messages: ÐžÑ‚Ð¿Ñ€Ð°Ð²ÐºÐ° ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+  permission_browse_repository: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
+  permission_comment_news: ÐšÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ð½Ð¾Ð²Ð¾ÑÑ‚ÐµÐ¹
+  permission_commit_access: Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ Ñ„Ð°Ð¹Ð»Ð¾Ð² Ð² Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  permission_delete_issues: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡
+  permission_delete_messages: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+  permission_delete_own_messages: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ñ… ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+  permission_delete_wiki_pages: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
+  permission_delete_wiki_pages_attachments: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ Ð¿Ñ€Ð¸ÐºÑ€ÐµÐ¿Ð»Ñ‘Ð½Ð½Ñ‹Ñ… Ñ„Ð°Ð¹Ð»Ð¾Ð²
+  permission_edit_issue_notes: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ð¹
+  permission_edit_issues: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡
+  permission_edit_messages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+  permission_edit_own_issue_notes: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ñ… Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ð¹
+  permission_edit_own_messages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ñ… ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+  permission_edit_own_time_entries: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ð¾Ð³Ð¾ ÑƒÑ‡Ñ‘Ñ‚Ð° Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  permission_edit_project: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  permission_edit_time_entries: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑƒÑ‡Ñ‘Ñ‚Ð° Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  permission_edit_wiki_pages: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
+  permission_export_wiki_pages: Ð­ÐºÑÐ¿Ð¾Ñ€Ñ‚ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
+  permission_log_time: Ð£Ñ‡Ñ‘Ñ‚ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  permission_view_changesets: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
+  permission_view_time_entries: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  permission_manage_project_activities: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ‚Ð¸Ð¿Ð°Ð¼Ð¸ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹ Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
+  permission_manage_boards: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ„Ð¾Ñ€ÑƒÐ¼Ð°Ð¼Ð¸
+  permission_manage_categories: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸ÑÐ¼Ð¸ Ð·Ð°Ð´Ð°Ñ‡
+  permission_manage_files: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸
+  permission_manage_issue_relations: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑÐ²ÑÐ·Ñ‹Ð²Ð°Ð½Ð¸ÐµÐ¼ Ð·Ð°Ð´Ð°Ñ‡
+  permission_manage_members: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ°Ð¼Ð¸
+  permission_manage_news: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð¾Ð²Ð¾ÑÑ‚ÑÐ¼Ð¸
+  permission_manage_public_queries: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¾Ð±Ñ‰Ð¸Ð¼Ð¸ Ð·Ð°Ð¿Ñ€Ð¾ÑÐ°Ð¼Ð¸
+  permission_manage_repository: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÐ¼
+  permission_manage_subtasks: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð°Ð¼Ð¸
+  permission_manage_versions: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð²ÐµÑ€ÑÐ¸ÑÐ¼Ð¸
+  permission_manage_wiki: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Wiki
+  permission_move_issues: ÐŸÐµÑ€ÐµÐ½Ð¾Ñ Ð·Ð°Ð´Ð°Ñ‡
+  permission_protect_wiki_pages: Ð‘Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
+  permission_rename_wiki_pages: ÐŸÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ðµ wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†
+  permission_save_queries: Ð¡Ð¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ðµ Ð·Ð°Ð¿Ñ€Ð¾ÑÐ¾Ð²
+  permission_select_project_modules: Ð’Ñ‹Ð±Ð¾Ñ€ Ð¼Ð¾Ð´ÑƒÐ»ÐµÐ¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
+  permission_view_calendar: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ
+  permission_view_documents: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ð²
+  permission_view_files: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ñ„Ð°Ð¹Ð»Ð¾Ð²
+  permission_view_gantt: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ñ‹ Ð“Ð°Ð½Ñ‚Ð°
+  permission_view_issue_watchers: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ ÑÐ¿Ð¸ÑÐºÐ° Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»ÐµÐ¹
+  permission_view_messages: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+  permission_view_wiki_edits: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ð¸ Wiki
+  permission_view_wiki_pages: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Wiki
+
+  project_module_boards: Ð¤Ð¾Ñ€ÑƒÐ¼Ñ‹
+  project_module_documents: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
+  project_module_files: Ð¤Ð°Ð¹Ð»Ñ‹
+  project_module_issue_tracking: Ð—Ð°Ð´Ð°Ñ‡Ð¸
+  project_module_news: ÐÐ¾Ð²Ð¾ÑÑ‚Ð¸
+  project_module_repository: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  project_module_time_tracking: Ð£Ñ‡Ñ‘Ñ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  project_module_wiki: Wiki
+  project_module_gantt: Ð”Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ð° Ð“Ð°Ð½Ñ‚Ð°
+  project_module_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€ÑŒ
+
+  setting_activity_days_default: ÐšÐ¾Ð»Ð¸Ñ‡ÐµÑÑ‚Ð²Ð¾ Ð´Ð½ÐµÐ¹, Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ñ… Ð² Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸ÑÑ…
+  setting_app_subtitle: ÐŸÐ¾Ð´Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ
+  setting_app_title: ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ðµ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ
+  setting_attachment_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ
+  setting_autofetch_changesets: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑÐºÐ¸ ÑÐ»ÐµÐ´Ð¸Ñ‚ÑŒ Ð·Ð° Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸ÑÐ¼Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
+  setting_autologin: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑÐºÐ¸Ð¹ Ð²Ñ…Ð¾Ð´
+  setting_bcc_recipients: Ð˜ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÑŒ ÑÐºÑ€Ñ‹Ñ‚Ñ‹Ðµ ÐºÐ¾Ð¿Ð¸Ð¸ (BCC)
+  setting_cache_formatted_text: ÐšÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ñ‹Ð¹ Ñ‚ÐµÐºÑÑ‚
+  setting_commit_fix_keywords: ÐÐ°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… ÑÐ»Ð¾Ð²
+  setting_commit_ref_keywords: ÐšÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ðµ ÑÐ»Ð¾Ð²Ð° Ð´Ð»Ñ Ð¿Ð¾Ð¸ÑÐºÐ°
+  setting_cross_project_issue_relations: Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð¿ÐµÑ€ÐµÑÐµÑ‡ÐµÐ½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡ Ð¿Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼
+  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð´Ð°Ñ‚Ñ‹
+  setting_default_language: Ð¯Ð·Ñ‹Ðº Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  setting_default_notification_option: Ð¡Ð¿Ð¾ÑÐ¾Ð± Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  setting_default_projects_public: ÐÐ¾Ð²Ñ‹Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹ ÑÐ²Ð»ÑÑŽÑ‚ÑÑ Ð¾Ð±Ñ‰ÐµÐ´Ð¾ÑÑ‚ÑƒÐ¿Ð½Ñ‹Ð¼Ð¸
+  setting_diff_max_lines_displayed: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ðµ Ñ‡Ð¸ÑÐ»Ð¾ ÑÑ‚Ñ€Ð¾Ðº Ð´Ð»Ñ diff
+  setting_display_subprojects_issues: ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð² Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  setting_emails_footer: ÐŸÐ¾Ð´ÑÑ‚Ñ€Ð¾Ñ‡Ð½Ñ‹Ðµ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð¿Ð¸ÑÑŒÐ¼Ð°
+  setting_enabled_scm: Ð’ÐºÐ»ÑŽÑ‡Ñ‘Ð½Ð½Ñ‹Ðµ SCM
+  setting_feeds_limit: ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ðµ ÐºÐ¾Ð»Ð¸Ñ‡ÐµÑÑ‚Ð²Ð° Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð² Ð´Ð»Ñ RSS Ð¿Ð¾Ñ‚Ð¾ÐºÐ°
+  setting_file_max_size_displayed: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ñ‚ÐµÐºÑÑ‚Ð¾Ð²Ð¾Ð³Ð¾ Ñ„Ð°Ð¹Ð»Ð° Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ
+  setting_gravatar_enabled: Ð˜ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÑŒ Ð°Ð²Ð°Ñ‚Ð°Ñ€ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð· Gravatar
+  setting_host_name: Ð˜Ð¼Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð°
+  setting_issue_list_default_columns: Ð¡Ñ‚Ð¾Ð»Ð±Ñ†Ñ‹, Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ðµ Ð² ÑÐ¿Ð¸ÑÐºÐµ Ð·Ð°Ð´Ð°Ñ‡ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  setting_issues_export_limit: ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ðµ Ð¿Ð¾ ÑÐºÑÐ¿Ð¾Ñ€Ñ‚Ð¸Ñ€ÑƒÐµÐ¼Ñ‹Ð¼ Ð·Ð°Ð´Ð°Ñ‡Ð°Ð¼
+  setting_login_required: ÐÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð° Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ
+  setting_mail_from: Ð˜ÑÑ…Ð¾Ð´ÑÑ‰Ð¸Ð¹ email Ð°Ð´Ñ€ÐµÑ
+  setting_mail_handler_api_enabled: Ð’ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ð²ÐµÐ±-ÑÐµÑ€Ð²Ð¸Ñ Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´ÑÑ‰Ð¸Ñ… ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+  setting_mail_handler_api_key: API ÐºÐ»ÑŽÑ‡
+  setting_openid: Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ OpenID Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° Ð¸ Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ð¸
+  setting_per_page_options: ÐšÐ¾Ð»Ð¸Ñ‡ÐµÑÑ‚Ð²Ð¾ Ð·Ð°Ð¿Ð¸ÑÐµÐ¹ Ð½Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ
+  setting_plain_text_mail: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð¿Ñ€Ð¾ÑÑ‚Ð¾Ð¹ Ñ‚ÐµÐºÑÑ‚ (Ð±ÐµÐ· HTML)
+  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
+  setting_repository_log_display_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ðµ ÐºÐ¾Ð»Ð¸Ñ‡ÐµÑÑ‚Ð²Ð¾ Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¹, Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ñ… Ð² Ð¶ÑƒÑ€Ð½Ð°Ð»Ðµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹
+  setting_self_registration: Ð¡Ð°Ð¼Ð¾Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ
+  setting_sequential_project_identifiers: Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ðµ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ñ‹ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  setting_sys_api_enabled: Ð’ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ð²ÐµÐ±-ÑÐµÑ€Ð²Ð¸Ñ Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÐ¼
+  setting_text_formatting: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ Ñ‚ÐµÐºÑÑ‚Ð°
+  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  setting_user_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐ½Ð¸
+  setting_welcome_text: Ð¢ÐµÐºÑÑ‚ Ð¿Ñ€Ð¸Ð²ÐµÑ‚ÑÑ‚Ð²Ð¸Ñ
+  setting_wiki_compression: Ð¡Ð¶Ð°Ñ‚Ð¸Ðµ Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ð¸ Wiki
+
+  status_active: Ð°ÐºÑ‚Ð¸Ð²ÐµÐ½
+  status_locked: Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½
+  status_registered: Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½
+
+  text_are_you_sure: Ð’Ñ‹ ÑƒÐ²ÐµÑ€ÐµÐ½Ñ‹?
+  text_assign_time_entries_to_project: ÐŸÑ€Ð¸ÐºÑ€ÐµÐ¿Ð¸Ñ‚ÑŒ Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ Ðº Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ
+  text_caracters_maximum: "ÐœÐ°ÐºÑÐ¸Ð¼ÑƒÐ¼ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²(Ð°)."
+  text_caracters_minimum: "Ð”Ð¾Ð»Ð¶Ð½Ð¾ Ð±Ñ‹Ñ‚ÑŒ Ð½Ðµ Ð¼ÐµÐ½ÐµÐµ %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²."
+  text_comma_separated: Ð”Ð¾Ð¿ÑƒÑÑ‚Ð¸Ð¼Ñ‹ Ð½ÐµÑÐºÐ¾Ð»ÑŒÐºÐ¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ (Ñ‡ÐµÑ€ÐµÐ· Ð·Ð°Ð¿ÑÑ‚ÑƒÑŽ).
+  text_custom_field_possible_values_info: 'ÐŸÐ¾ Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÑŽ Ð² ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑ‚Ñ€Ð¾ÐºÐµ'
+  text_default_administrator_account_changed: Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð° Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð°
+  text_destroy_time_entries_question: "ÐÐ° ÑÑ‚Ñƒ Ð·Ð°Ð´Ð°Ñ‡Ñƒ Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¾ %{hours} Ñ‡Ð°ÑÐ°(Ð¾Ð²) Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸. Ð§Ñ‚Ð¾ Ð’Ñ‹ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¸Ð½ÑÑ‚ÑŒ?"
+  text_destroy_time_entries: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
+  text_diff_truncated: '... Ð­Ñ‚Ð¾Ñ‚ diff Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½, Ñ‚Ð°Ðº ÐºÐ°Ðº Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐ°ÐµÑ‚ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ð¹ Ñ€Ð°Ð·Ð¼ÐµÑ€.'
+  text_email_delivery_not_configured: "ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð¿Ð¾Ñ‡Ñ‚Ð¾Ð²Ñ‹Ð¼ ÑÐµÑ€Ð²ÐµÑ€Ð¾Ð¼ Ð½Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾ÐµÐ½Ñ‹ Ð¸ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ email Ð½Ðµ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð°.\nÐÐ°ÑÑ‚Ñ€Ð¾Ð¸Ñ‚ÑŒ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹ Ð´Ð»Ñ Ð’Ð°ÑˆÐµÐ³Ð¾ SMTP-ÑÐµÑ€Ð²ÐµÑ€Ð° Ð’Ñ‹ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð² Ñ„Ð°Ð¹Ð»Ðµ config/configuration.yml. Ð”Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑÑ‚Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ."
+  text_enumeration_category_reassign_to: 'ÐÐ°Ð·Ð½Ð°Ñ‡Ð¸Ñ‚ÑŒ Ð¸Ð¼ ÑÐ»ÐµÐ´ÑƒÑŽÑ‰ÐµÐµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ:'
+  text_enumeration_destroy_question: "%{count} Ð¾Ð±ÑŠÐµÐºÑ‚(Ð°,Ð¾Ð²) ÑÐ²ÑÐ·Ð°Ð½Ñ‹ Ñ ÑÑ‚Ð¸Ð¼ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÐµÐ¼."
+  text_file_repository_writable: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ Ñ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð¾Ð¼ Ð½Ð° Ð·Ð°Ð¿Ð¸ÑÑŒ
+  text_issue_added: "Ð¡Ð¾Ð·Ð´Ð°Ð½Ð° Ð½Ð¾Ð²Ð°Ñ Ð·Ð°Ð´Ð°Ñ‡Ð° %{id} (%{author})."
+  text_issue_category_destroy_assignments: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸
+  text_issue_category_destroy_question: "ÐÐµÑÐºÐ¾Ð»ÑŒÐºÐ¾ Ð·Ð°Ð´Ð°Ñ‡ (%{count}) Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾ Ð² Ð´Ð°Ð½Ð½ÑƒÑŽ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸ÑŽ. Ð§Ñ‚Ð¾ Ð’Ñ‹ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¸Ð½ÑÑ‚ÑŒ?"
+  text_issue_category_reassign_to: ÐŸÐµÑ€ÐµÐ½Ð°Ð·Ð½Ð°Ñ‡Ð¸Ñ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸
+  text_issues_destroy_confirmation: 'Ð’Ñ‹ ÑƒÐ²ÐµÑ€ÐµÐ½Ñ‹, Ñ‡Ñ‚Ð¾ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸?'
+  text_issues_ref_in_commit_messages: Ð¡Ð¾Ð¿Ð¾ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð¸ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ ÑÑ‚Ð°Ñ‚ÑƒÑÐ° Ð·Ð°Ð´Ð°Ñ‡ Ð¸ÑÑ…Ð¾Ð´Ñ Ð¸Ð· Ñ‚ÐµÐºÑÑ‚Ð° ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ð¹
+  text_issue_updated: "Ð—Ð°Ð´Ð°Ñ‡Ð° %{id} Ð±Ñ‹Ð»Ð° Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð° (%{author})."
+  text_journal_changed: "ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ %{label} Ð¸Ð·Ð¼ÐµÐ½Ð¸Ð»ÑÑ Ñ %{old} Ð½Ð° %{new}"
+  text_journal_deleted: "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ %{old} Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° %{label} ÑƒÐ´Ð°Ð»ÐµÐ½Ð¾"
+  text_journal_set_to: "ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ %{label} Ð¸Ð·Ð¼ÐµÐ½Ð¸Ð»ÑÑ Ð½Ð° %{value}"
+  text_length_between: "Ð”Ð»Ð¸Ð½Ð° Ð¼ÐµÐ¶Ð´Ñƒ %{min} Ð¸ %{max} ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¾Ð²."
+  text_load_default_configuration: Ð—Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸ÑŽ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  text_min_max_length_info: 0 Ð¾Ð·Ð½Ð°Ñ‡Ð°ÐµÑ‚ Ð¾Ñ‚ÑÑƒÑ‚ÑÑ‚Ð²Ð¸Ðµ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ð¹
+  text_no_configuration_data: "Ð Ð¾Ð»Ð¸, Ñ‚Ñ€ÐµÐºÐµÑ€Ñ‹, ÑÑ‚Ð°Ñ‚ÑƒÑÑ‹ Ð·Ð°Ð´Ð°Ñ‡ Ð¸ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ñ‹Ð¹ Ð¿Ð»Ð°Ð½ Ð½Ðµ Ð±Ñ‹Ð»Ð¸ ÑÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ñ‹.\nÐÐ°ÑÑ‚Ð¾ÑÑ‚ÐµÐ»ÑŒÐ½Ð¾ Ñ€ÐµÐºÐ¾Ð¼ÐµÐ½Ð´ÑƒÐµÑ‚ÑÑ Ð·Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸ÑŽ Ð¿Ð¾-ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ. Ð’Ñ‹ ÑÐ¼Ð¾Ð¶ÐµÑ‚Ðµ ÐµÑ‘ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð¿Ð¾Ñ‚Ð¾Ð¼."
+  text_plugin_assets_writable: ÐšÐ°Ñ‚Ð°Ð»Ð¾Ð³ Ð¼Ð¾Ð´ÑƒÐ»ÐµÐ¹ Ð´Ð¾ÑÑ‚ÑƒÐ¿ÐµÐ½ Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸ÑÐ¸
+  text_project_destroy_confirmation: Ð’Ñ‹ Ð½Ð°ÑÑ‚Ð°Ð¸Ð²Ð°ÐµÑ‚Ðµ Ð½Ð° ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ð¸ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð° Ð¸ Ð²ÑÐµÐ¹ Ð¾Ñ‚Ð½Ð¾ÑÑÑ‰ÐµÐ¹ÑÑ Ðº Ð½ÐµÐ¼Ñƒ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸?
+  text_reassign_time_entries: 'ÐŸÐµÑ€ÐµÐ½ÐµÑÑ‚Ð¸ Ð·Ð°Ñ€ÐµÐ³Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ Ð½Ð° ÑÐ»ÐµÐ´ÑƒÑŽÑ‰ÑƒÑŽ Ð·Ð°Ð´Ð°Ñ‡Ñƒ:'
+  text_regexp_info: "Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€: ^[A-Z0-9]+$"
+  text_repository_usernames_mapping: "Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¸Ð»Ð¸ Ð¾Ð±Ð½Ð¾Ð²Ð¸Ñ‚Ðµ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Redmine, ÑÐ²ÑÐ·Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñ Ð½Ð°Ð¹Ð´ÐµÐ½Ð½Ñ‹Ð¼Ð¸ Ð¸Ð¼ÐµÐ½Ð°Ð¼Ð¸ Ð² Ð¶ÑƒÑ€Ð½Ð°Ð»Ðµ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°.\nÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ð¸ Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼Ð¸ Ð¸Ð¼ÐµÐ½Ð°Ð¼Ð¸ Ð¸Ð»Ð¸ email Ð² Redmine Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ ÑÐ²ÑÐ·Ñ‹Ð²Ð°ÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑÐºÐ¸."
+  text_rmagick_available: Ð”Ð¾ÑÑ‚ÑƒÐ¿Ð½Ð¾ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ðµ RMagick (Ð¾Ð¿Ñ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ð¾)
+  text_select_mail_notifications: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ, Ð¿Ñ€Ð¸ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… Ð±ÑƒÐ´ÐµÑ‚ Ð¾Ñ‚ÑÑ‹Ð»Ð°Ñ‚ÑŒÑÑ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° ÑÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½ÑƒÑŽ Ð¿Ð¾Ñ‡Ñ‚Ñƒ.
+  text_select_project_modules: 'Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¼Ð¾Ð´ÑƒÐ»Ð¸, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð±ÑƒÐ´ÑƒÑ‚ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ñ‹ Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚Ðµ:'
+  text_status_changed_by_changeset: "Ð ÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ð¾ Ð² %{value} Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸."
+  text_subprojects_destroy_warning: "ÐŸÐ¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹: %{value} Ñ‚Ð°ÐºÐ¶Ðµ Ð±ÑƒÐ´ÑƒÑ‚ ÑƒÐ´Ð°Ð»ÐµÐ½Ñ‹."
+  text_tip_issue_begin_day: Ð´Ð°Ñ‚Ð° Ð½Ð°Ñ‡Ð°Ð»Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  text_tip_issue_begin_end_day: Ð½Ð°Ñ‡Ð°Ð»Ð¾ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¸ Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ðµ ÐµÑ‘ Ð² ÑÑ‚Ð¾Ñ‚ Ð¶Ðµ Ð´ÐµÐ½ÑŒ
+  text_tip_issue_end_day: Ð´Ð°Ñ‚Ð° Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  text_tracker_no_workflow: Ð”Ð»Ñ ÑÑ‚Ð¾Ð³Ð¾ Ñ‚Ñ€ÐµÐºÐµÑ€Ð° Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹ Ð½Ðµ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð°
+  text_unallowed_characters: Ð—Ð°Ð¿Ñ€ÐµÑ‰ÐµÐ½Ð½Ñ‹Ðµ ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ‹
+  text_user_mail_option: "Ð”Ð»Ñ Ð½ÐµÐ²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð², Ð’Ñ‹ Ð±ÑƒÐ´ÐµÑ‚Ðµ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÑŒ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð¾ Ñ‚Ð¾Ð¼, Ñ‡Ñ‚Ð¾ Ð¿Ñ€Ð¾ÑÐ¼Ð°Ñ‚Ñ€Ð¸Ð²Ð°ÐµÑ‚Ðµ Ð¸Ð»Ð¸ Ð² Ñ‡ÐµÐ¼ ÑƒÑ‡Ð°ÑÑ‚Ð²ÑƒÐµÑ‚Ðµ (Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€, Ð·Ð°Ð´Ð°Ñ‡Ð¸, Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… Ð’Ñ‹ ÑÐ²Ð»ÑÐµÑ‚ÐµÑÑŒ, Ð¸Ð»Ð¸ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð’Ð°Ð¼ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ñ‹)."
+  text_user_wrote: "%{value} Ð¿Ð¸ÑÐ°Ð»(Ð°):"
+  text_wiki_destroy_confirmation: Ð’Ñ‹ ÑƒÐ²ÐµÑ€ÐµÐ½Ñ‹, Ñ‡Ñ‚Ð¾ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð´Ð°Ð½Ð½ÑƒÑŽ Wiki Ð¸ Ð²ÑÐµ ÐµÑ‘ ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ð¼Ð¾Ðµ?
+  text_workflow_edit: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ñ€Ð¾Ð»ÑŒ Ð¸ Ñ‚Ñ€ÐµÐºÐµÑ€ Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚Ð¸ ÑÐ¾ÑÑ‚Ð¾ÑÐ½Ð¸Ð¹
+
+  warning_attachments_not_saved: "%{count} Ñ„Ð°Ð¹Ð»(Ð¾Ð²) Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑÐ¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ."
+  text_wiki_page_destroy_question: Ð­Ñ‚Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° Ð¸Ð¼ÐµÐµÑ‚ %{descendants} Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ñ… ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ† Ð¸ Ð¸Ñ… Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ¾Ð². Ð§Ñ‚Ð¾ Ð²Ñ‹ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¸Ð½ÑÑ‚ÑŒ?
+  text_wiki_page_reassign_children: ÐŸÐµÑ€ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Ð½Ð° Ñ‚ÐµÐºÑƒÑ‰ÑƒÑŽ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ
+  text_wiki_page_nullify_children: Ð¡Ð´ÐµÐ»Ð°Ñ‚ÑŒ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Ð³Ð»Ð°Ð²Ð½Ñ‹Ð¼Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ð¼Ð¸
+  text_wiki_page_destroy_children: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ðµ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Ð¸ Ð²ÑÐµÑ… Ð¸Ñ… Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ¾Ð²
+  setting_password_min_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° Ð¿Ð°Ñ€Ð¾Ð»Ñ
+  field_group_by: Ð“Ñ€ÑƒÐ¿Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ‹ Ð¿Ð¾
+  mail_subject_wiki_content_updated: "Wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° '%{id}' Ð±Ñ‹Ð»Ð° Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð°"
+  label_wiki_content_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð° wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  mail_subject_wiki_content_added: "Wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°  '%{id}' Ð±Ñ‹Ð»Ð° Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð°"
+  mail_body_wiki_content_added: "%{author} Ð´Ð¾Ð±Ð°Ð²Ð¸Ð»(Ð°) wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ '%{id}'."
+  label_wiki_content_updated: ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð° wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°
+  mail_body_wiki_content_updated: "%{author} Ð¾Ð±Ð½Ð¾Ð²Ð¸Ð»(Ð°) wiki-ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ '%{id}'."
+  permission_add_project: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
+  setting_new_project_user_role_id: Ð Ð¾Ð»ÑŒ, Ð½Ð°Ð·Ð½Ð°Ñ‡Ð°ÐµÐ¼Ð°Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŽ, ÑÐ¾Ð·Ð´Ð°Ð²ÑˆÐµÐ¼Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_view_all_revisions: ÐŸÐ¾ÐºÐ°Ð·Ð°Ñ‚ÑŒ Ð²ÑÐµ Ñ€ÐµÐ²Ð¸Ð·Ð¸Ð¸
+  label_tag: ÐœÐµÑ‚ÐºÐ°
+  label_branch: Ð’ÐµÑ‚Ð²ÑŒ
+  error_no_tracker_in_project: Ð¡ ÑÑ‚Ð¸Ð¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð¼ Ð½Ðµ Ð°ÑÑÐ¾Ñ†Ð¸Ð¸Ñ€Ð¾Ð²Ð°Ð½ Ð½Ð¸ Ð¾Ð´Ð¸Ð½ Ñ‚Ñ€ÐµÐºÐµÑ€. ÐŸÑ€Ð¾Ð²ÐµÑ€ÑŒÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°.
+  error_no_default_issue_status: ÐÐµ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½ ÑÑ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð´Ð°Ñ‡ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ. ÐŸÑ€Ð¾Ð²ÐµÑ€ÑŒÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸ (ÑÐ¼. "ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ -> Ð¡Ñ‚Ð°Ñ‚ÑƒÑÑ‹ Ð·Ð°Ð´Ð°Ñ‡").
+  label_group_plural: Ð“Ñ€ÑƒÐ¿Ð¿Ñ‹
+  label_group: Ð“Ñ€ÑƒÐ¿Ð¿Ð°
+  label_group_new: ÐÐ¾Ð²Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð°
+  label_time_entry_plural: Ð—Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ
+  text_journal_added: "%{label} %{value} Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½"
+  field_active: ÐÐºÑ‚Ð¸Ð²Ð½Ð¾
+  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð½Ð¾Ðµ
+  permission_delete_issue_watchers: Ð£Ð´Ð°Ð»ÐµÐ½Ð¸Ðµ Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»ÐµÐ¹
+  version_status_closed: Ð·Ð°ÐºÑ€Ñ‹Ñ‚
+  version_status_locked: Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½
+  version_status_open: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚
+  error_can_not_reopen_issue_on_closed_version: Ð—Ð°Ð´Ð°Ñ‡Ð°, Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ð°Ñ Ðº Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¾Ð¹ Ð²ÐµÑ€ÑÐ¸Ð¸, Ð½Ðµ ÑÐ¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð° ÑÐ½Ð¾Ð²Ð°
+  label_user_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼
+  button_move_and_follow: ÐŸÐµÑ€ÐµÐ¼ÐµÑÑ‚Ð¸Ñ‚ÑŒ Ð¸ Ð¿ÐµÑ€ÐµÐ¹Ñ‚Ð¸
+  setting_default_projects_modules: Ð’ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ‹Ðµ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ Ð¼Ð¾Ð´ÑƒÐ»Ð¸ Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  setting_gravatar_default: Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ Gravatar Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  field_sharing: Ð¡Ð¾Ð²Ð¼ÐµÑÑ‚Ð½Ð¾Ðµ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ðµ
+  label_version_sharing_hierarchy: Ð¡ Ð¸ÐµÑ€Ð°Ñ€Ñ…Ð¸ÐµÐ¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  label_version_sharing_system: Ð¡Ð¾ Ð²ÑÐµÐ¼Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
+  label_version_sharing_descendants: Ð¡ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
+  label_version_sharing_tree: Ð¡ Ð´ÐµÑ€ÐµÐ²Ð¾Ð¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  label_version_sharing_none: Ð‘ÐµÐ· ÑÐ¾Ð²Ð¼ÐµÑÑ‚Ð½Ð¾Ð³Ð¾ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ
+  error_can_not_archive_project: Ð­Ñ‚Ð¾Ñ‚ Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð·Ð°Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½
+  button_duplicate: Ð”ÑƒÐ±Ð»Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ
+  button_copy_and_follow: ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¸ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÑŒ
+  label_copy_source: Ð˜ÑÑ‚Ð¾Ñ‡Ð½Ð¸Ðº
+  setting_issue_done_ratio:  Ð Ð°ÑÑÑ‡Ð¸Ñ‚Ñ‹Ð²Ð°Ñ‚ÑŒ Ð³Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ð¿Ð¾Ð»Ñ
+  setting_issue_done_ratio_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  error_issue_done_ratios_not_updated: ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ Ð³Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡ Ð½Ðµ Ð¾Ð±Ð½Ð¾Ð²Ð»Ñ‘Ð½
+  error_workflow_copy_target: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ñ†ÐµÐ»ÐµÐ²Ñ‹Ðµ Ñ‚Ñ€ÐµÐºÐµÑ€Ñ‹ Ð¸ Ñ€Ð¾Ð»Ð¸
+  setting_issue_done_ratio_issue_field: Ð“Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_copy_same_as_target: Ð¢Ð¾ Ð¶Ðµ, Ñ‡Ñ‚Ð¾ Ð¸ Ñƒ Ñ†ÐµÐ»Ð¸
+  label_copy_target: Ð¦ÐµÐ»ÑŒ
+  notice_issue_done_ratios_updated: ÐŸÐ°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ &laquo;Ð³Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ&raquo; Ð¾Ð±Ð½Ð¾Ð²Ð»Ñ‘Ð½.
+  error_workflow_copy_source: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð¸ÑÑ…Ð¾Ð´Ð½Ñ‹Ð¹ Ñ‚Ñ€ÐµÐºÐµÑ€ Ð¸Ð»Ð¸ Ñ€Ð¾Ð»ÑŒ
+  label_update_issue_done_ratios: ÐžÐ±Ð½Ð¾Ð²Ð¸Ñ‚ÑŒ Ð³Ð¾Ñ‚Ð¾Ð²Ð½Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡
+  setting_start_of_week: Ð”ÐµÐ½ÑŒ Ð½Ð°Ñ‡Ð°Ð»Ð° Ð½ÐµÐ´ÐµÐ»Ð¸
+  label_api_access_key: ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº API
+  text_line_separated: Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¾ Ð½ÐµÑÐºÐ¾Ð»ÑŒÐºÐ¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ (Ð¿Ð¾ Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÑŽ Ð² ÑÑ‚Ñ€Ð¾ÐºÑƒ).
+  label_revision_id: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ %{value}
+  permission_view_issues: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð·Ð°Ð´Ð°Ñ‡
+  label_display_used_statuses_only: ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°Ñ‚ÑŒ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ‚Ðµ ÑÑ‚Ð°Ñ‚ÑƒÑÑ‹, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑŽÑ‚ÑÑ Ð² ÑÑ‚Ð¾Ð¼ Ñ‚Ñ€ÐµÐºÐµÑ€Ðµ
+  label_api_access_key_created_on: ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿ Ðº API Ð±Ñ‹Ð» ÑÐ¾Ð·Ð´Ð°Ð½ %{value} Ð½Ð°Ð·Ð°Ð´
+  label_feeds_access_key: ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº RSS
+  notice_api_access_key_reseted: Ð’Ð°Ñˆ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº API Ð±Ñ‹Ð» ÑÐ±Ñ€Ð¾ÑˆÐµÐ½.
+  setting_rest_api_enabled: Ð’ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ð²ÐµÐ±-ÑÐµÑ€Ð²Ð¸Ñ REST
+  button_show: ÐŸÐ¾ÐºÐ°Ð·Ð°Ñ‚ÑŒ
+  label_missing_api_access_key: ÐžÑ‚ÑÑƒÑ‚ÑÑ‚Ð²ÑƒÐµÑ‚ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº API
+  label_missing_feeds_access_key: ÐžÑ‚ÑÑƒÑ‚ÑÑ‚Ð²ÑƒÐµÑ‚ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ð° Ðº RSS
+  setting_mail_handler_body_delimiters: Ð£Ñ€ÐµÐ·Ð°Ñ‚ÑŒ Ð¿Ð¸ÑÑŒÐ¼Ð¾ Ð¿Ð¾ÑÐ»Ðµ Ð¾Ð´Ð½Ð¾Ð¹ Ð¸Ð· ÑÑ‚Ð¸Ñ… ÑÑ‚Ñ€Ð¾Ðº
+  permission_add_subprojects: Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ðµ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  label_subproject_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  text_own_membership_delete_confirmation: |-
+    Ð’Ñ‹ ÑÐ¾Ð±Ð¸Ñ€Ð°ÐµÑ‚ÐµÑÑŒ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð¸Ð»Ð¸ Ð²ÑÐµ Ð¿Ñ€Ð°Ð²Ð°, Ð¸Ð·-Ð·Ð° Ñ‡ÐµÐ³Ð¾ Ð¼Ð¾Ð³ÑƒÑ‚ Ð¿Ñ€Ð¾Ð¿Ð°ÑÑ‚ÑŒ Ð¿Ñ€Ð°Ð²Ð° Ð½Ð° Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ðµ ÑÑ‚Ð¾Ð³Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°.
+    ÐŸÑ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÑŒ?
+  label_close_versions: Ð—Ð°ÐºÑ€Ñ‹Ñ‚ÑŒ Ð·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½Ð½Ñ‹Ðµ Ð²ÐµÑ€ÑÐ¸Ð¸
+  label_board_sticky: ÐŸÑ€Ð¸ÐºÑ€ÐµÐ¿Ð»ÐµÐ½Ð°
+  label_board_locked: Ð—Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð°
+  field_principal: Ð˜Ð¼Ñ
+  text_zoom_out: ÐžÑ‚Ð´Ð°Ð»Ð¸Ñ‚ÑŒ
+  text_zoom_in: ÐŸÑ€Ð¸Ð±Ð»Ð¸Ð·Ð¸Ñ‚ÑŒ
+  notice_unable_delete_time_entry: ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð°.
+  label_overall_spent_time: Ð’ÑÐµÐ³Ð¾ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  label_user_mail_option_none: ÐÐµÑ‚ ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ð¹
+  field_member_of_group: Ð“Ñ€ÑƒÐ¿Ð¿Ð° Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾
+  field_assigned_to_role: Ð Ð¾Ð»ÑŒ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾
+  notice_not_authorized_archived_project: Ð—Ð°Ð¿Ñ€Ð°ÑˆÐ¸Ð²Ð°ÐµÐ¼Ñ‹Ð¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ð±Ñ‹Ð» Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½.
+  label_principal_search: "ÐÐ°Ð¹Ñ‚Ð¸ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð»Ð¸ Ð³Ñ€ÑƒÐ¿Ð¿Ñƒ:"
+  label_user_search: "ÐÐ°Ð¹Ñ‚Ð¸ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ:"
+  field_visible: Ð’Ð¸Ð´Ð¸Ð¼Ð¾Ðµ
+  setting_emails_header: Ð—Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Ð¿Ð¸ÑÑŒÐ¼Ð°
+
+  setting_commit_logtime_activity_id: Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸Ðµ Ð´Ð»Ñ ÑƒÑ‡Ñ‘Ñ‚Ð° Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  text_time_logged_by_changeset: Ð£Ñ‡Ñ‚ÐµÐ½Ð¾ Ð² Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ð¸ %{value}.
+  setting_commit_logtime_enabled: Ð’ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ ÑƒÑ‡Ñ‘Ñ‚ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  notice_gantt_chart_truncated: Ð”Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ð° Ð±ÑƒÐ´ÐµÑ‚ ÑƒÑÐµÑ‡ÐµÐ½Ð°, Ð¿Ð¾ÑÐºÐ¾Ð»ÑŒÐºÑƒ Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐµÐ½Ð¾ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ðµ ÐºÐ¾Ð»-Ð²Ð¾ ÑÐ»ÐµÐ¼ÐµÐ½Ñ‚Ð¾Ð², ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð¼Ð¾Ð³ÑƒÑ‚ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°Ñ‚ÑŒÑÑ (%{max})
+  setting_gantt_items_limit: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ðµ ÐºÐ¾Ð»-Ð²Ð¾ ÑÐ»ÐµÐ¼ÐµÐ½Ñ‚Ð¾Ð² Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ñ‹Ñ… Ð½Ð° Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ð¼Ðµ Ð“Ð°Ð½Ñ‚Ð°
+  field_warn_on_leaving_unsaved: ÐŸÑ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´Ð°Ñ‚ÑŒ Ð¿Ñ€Ð¸ Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¸Ð¸ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ Ñ Ð½ÐµÑÐ¾Ñ…Ñ€Ð°Ð½Ñ‘Ð½Ð½Ñ‹Ð¼ Ñ‚ÐµÐºÑÑ‚Ð¾Ð¼
+  text_warn_on_leaving_unsaved: Ð¢ÐµÐºÑƒÑ‰Ð°Ñ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° ÑÐ¾Ð´ÐµÑ€Ð¶Ð¸Ñ‚ Ð½ÐµÑÐ¾Ñ…Ñ€Ð°Ð½Ñ‘Ð½Ð½Ñ‹Ð¹ Ñ‚ÐµÐºÑÑ‚, ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¹ Ð±ÑƒÐ´ÐµÑ‚ Ð¿Ð¾Ñ‚ÐµÑ€ÑÐ½, ÐµÑÐ»Ð¸ Ð²Ñ‹ Ð¿Ð¾ÐºÐ¸Ð½ÐµÑ‚Ðµ ÑÑ‚Ñƒ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ.
+  label_my_queries: ÐœÐ¾Ð¸ ÑÐ¾Ñ…Ñ€Ð°Ð½Ñ‘Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð¿Ñ€Ð¾ÑÑ‹
+  text_journal_changed_no_detail: "%{label} Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾"
+  label_news_comment_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹ Ðº Ð½Ð¾Ð²Ð¾ÑÑ‚Ð¸
+  button_expand_all: Ð Ð°Ð·Ð²ÐµÑ€Ð½ÑƒÑ‚ÑŒ Ð²ÑÐµ
+  button_collapse_all: Ð¡Ð²ÐµÑ€Ð½ÑƒÑ‚ÑŒ Ð²ÑÐµ
+  label_additional_workflow_transitions_for_assignee: Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ðµ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ñ‹, ÐºÐ¾Ð³Ð´Ð° Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ ÑÐ²Ð»ÑÐµÑ‚ÑÑ Ð¸ÑÐ¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÐµÐ¼
+  label_additional_workflow_transitions_for_author: Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ðµ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ñ‹, ÐºÐ¾Ð³Ð´Ð° Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ ÑÐ²Ð»ÑÐµÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼
+  label_bulk_edit_selected_time_entries: ÐœÐ°ÑÑÐ¾Ð²Ð¾Ðµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ… Ð·Ð°Ð¿Ð¸ÑÐµÐ¹ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸
+  text_time_entries_destroy_confirmation: Ð’Ñ‹ ÑƒÐ²ÐµÑ€ÐµÐ½Ñ‹ Ñ‡Ñ‚Ð¾ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ðµ Ð·Ð°Ð¿Ð¸ÑÐ¸ Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸?
+  label_role_anonymous: ÐÐ½Ð¾Ð½Ð¸Ð¼
+  label_role_non_member: ÐÐµ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸Ðº
+  label_issue_note_added: ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ðµ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¾
+  label_issue_status_updated: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¾Ð±Ð½Ð¾Ð²Ð»Ñ‘Ð½
+  label_issue_priority_updated: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚ Ð¾Ð±Ð½Ð¾Ð²Ð»Ñ‘Ð½
+  label_issues_visibility_own: Ð—Ð°Ð´Ð°Ñ‡Ð¸ ÑÐ¾Ð·Ð´Ð°Ð½Ð½Ñ‹Ðµ Ð¸Ð»Ð¸ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ‹Ðµ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŽ
+  field_issues_visibility: Ð’Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡
+  label_issues_visibility_all: Ð’ÑÐµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  permission_set_own_issues_private: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚Ð¸ (Ð¾Ð±Ñ‰Ð°Ñ/Ñ‡Ð°ÑÑ‚Ð½Ð°Ñ) Ð´Ð»Ñ ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ñ… Ð·Ð°Ð´Ð°Ñ‡
+  field_is_private: Ð§Ð°ÑÑ‚Ð½Ð°Ñ
+  permission_set_issues_private: Ð£ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚Ð¸ (Ð¾Ð±Ñ‰Ð°Ñ/Ñ‡Ð°ÑÑ‚Ð½Ð°Ñ) Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ñ‡
+  label_issues_visibility_public: Ð¢Ð¾Ð»ÑŒÐºÐ¾ Ð¾Ð±Ñ‰Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  text_issues_destroy_descendants_confirmation: Ð¢Ð°Ðº Ð¶Ðµ Ð±ÑƒÐ´ÐµÑ‚ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¾ %{count} Ð·Ð°Ð´Ð°Ñ‡(Ð¸).
+  field_commit_logs_encoding: ÐšÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ² Ð² Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  field_scm_path_encoding: ÐšÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° Ð¿ÑƒÑ‚Ð¸
+  text_scm_path_encoding_note: "ÐŸÐ¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ: UTF-8"
+  field_path_to_repository: ÐŸÑƒÑ‚ÑŒ Ðº Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ñƒ
+  field_root_directory: ÐšÐ¾Ñ€Ð½ÐµÐ²Ð°Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ
+  field_cvs_module: ÐœÐ¾Ð´ÑƒÐ»ÑŒ
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ðµ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ (Ð½Ð°Ð¿Ñ€Ð¸Ð¼ÐµÑ€, /hgrepo, c:\hgrepo)
+  text_scm_command: ÐšÐ¾Ð¼Ð°Ð½Ð´Ð°
+  text_scm_command_version: Ð’ÐµÑ€ÑÐ¸Ñ
+  label_git_report_last_commit: Ð£ÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾ÑÐ»ÐµÐ´Ð½ÐµÐµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð² Ð¸ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ð¹
+  text_scm_config: Ð’Ñ‹ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¸Ñ‚ÑŒ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ‹ SCM Ð² Ñ„Ð°Ð¹Ð»Ðµ config/configuration.yml. ÐŸÐ¾Ð¶Ð°Ð»ÑƒÐ¹ÑÑ‚Ð°, Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑÑ‚Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ Ð¿Ð¾ÑÐ»Ðµ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑ‚Ð¾Ð³Ð¾ Ñ„Ð°Ð¹Ð»Ð°.
+  text_scm_command_not_available: ÐšÐ¾Ð¼Ð°Ð½Ð´Ð° ÑÐ¸ÑÑ‚ÐµÐ¼Ñ‹ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»Ñ Ð²ÐµÑ€ÑÐ¸Ð¹ Ð½ÐµÐ´Ð¾ÑÑ‚ÑƒÐ¿Ð½Ð°. ÐŸÐ¾Ð¶Ð°Ð»ÑƒÐ¹ÑÑ‚Ð°, Ð¿Ñ€Ð¾Ð²ÐµÑ€ÑŒÑ‚Ðµ Ð½Ð°ÑÑ‚Ñ€Ð¾Ð¹ÐºÐ¸ Ð² Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¸Ð²Ð½Ð¾Ð¹ Ð¿Ð°Ð½ÐµÐ»Ð¸.
+  notice_issue_successful_create: Ð—Ð°Ð´Ð°Ñ‡Ð° %{id} ÑÐ¾Ð·Ð´Ð°Ð½Ð°.
+  label_between: Ð¼ÐµÐ¶Ð´Ñƒ
+  setting_issue_group_assignment: Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ Ð·Ð°Ð´Ð°Ñ‡ Ð³Ñ€ÑƒÐ¿Ð¿Ð°Ð¼ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹
+  label_diff: Ð Ð°Ð·Ð½Ð¸Ñ†Ð°(diff)
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: ÐŸÐ¾Ñ€ÑÐ´Ð¾Ðº ÑÐ¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²ÐºÐ¸
+  description_project_scope: Search scope
+  description_filter: Ð¤Ð¸Ð»ÑŒÑ‚Ñ€
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ
+  description_date_range_list: Ð’Ñ‹Ð±ÐµÑ€Ð¸Ñ‚Ðµ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ Ð¸Ð· ÑÐ¿Ð¸ÑÐºÐ°
+  description_choose_project: ÐŸÑ€Ð¾ÐµÐºÑ‚Ñ‹
+  description_date_to: Ð’Ð²ÐµÐ´Ð¸Ñ‚Ðµ Ð´Ð°Ñ‚Ñƒ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ
+  description_query_sort_criteria_attribute: ÐšÑ€Ð¸Ñ‚ÐµÑ€Ð¸Ð¹ ÑÐ¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²ÐºÐ¸
+  description_wiki_subpages_reassign: Ð’Ñ‹Ð±Ñ€Ð°Ñ‚ÑŒ Ð½Ð¾Ð²ÑƒÑŽ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑÐºÑƒÑŽ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ
+  description_selected_columns: Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ðµ ÑÑ‚Ð¾Ð»Ð±Ñ†Ñ‹
+  label_parent_revision: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑÐºÐ¸Ð¹
+  label_child_revision: Ð”Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ð¹
+  error_scm_annotate_big_text_file: ÐšÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶ÐµÐ½ Ð¸Ð·-Ð·Ð° Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° Ñ‚ÐµÐºÑÑ‚Ð¾Ð²Ð¾Ð³Ð¾ Ñ„Ð°Ð¹Ð»Ð°.
+  setting_default_issue_start_date_to_creation_date: Ð˜ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÑŒ Ñ‚ÐµÐºÑƒÑ‰ÑƒÑŽ Ð´Ð°Ñ‚Ñƒ Ð² ÐºÐ°Ñ‡ÐµÑÑ‚Ð²Ðµ Ð´Ð°Ñ‚Ñ‹ Ð½Ð°Ñ‡Ð°Ð»Ð° Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… Ð·Ð°Ð´Ð°Ñ‡
+  button_edit_section: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ ÑÑ‚Ñƒ ÑÐµÐºÑ†Ð¸ÑŽ
+  setting_repositories_encodings: ÐšÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ð¹ Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰
+  description_all_columns: Ð’ÑÐµ ÑÑ‚Ð¾Ð»Ð±Ñ†Ñ‹
+  button_export: Ð­ÐºÑÐ¿Ð¾Ñ€Ñ‚
+  label_export_options: "%{export_format} Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹ ÑÐºÑÐ¿Ð¾Ñ€Ñ‚Ð°"
+  error_attachment_too_big: Ð­Ñ‚Ð¾Ñ‚ Ñ„Ð°Ð¹Ð» Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ Ð¸Ð·-Ð·Ð° Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° Ñ„Ð°Ð¹Ð»Ð° (%{max_size})
+  notice_failed_to_save_time_entries: "ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑÐ¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ %{count} Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ Ð´Ð»Ñ %{total} Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ…: %{ids}."
+  label_x_issues:
+    one:   "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð°"
+    few:   "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸"
+    many:  "%{count} Ð·Ð°Ð´Ð°Ñ‡"
+    other: "%{count} Ð—Ð°Ð´Ð°Ñ‡Ð¸"
+  label_repository_new: ÐÐ¾Ð²Ð¾Ðµ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
+  field_repository_is_default: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
+  label_copy_attachments: ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Ð—Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ‹Ðµ Ð²ÐµÑ€ÑÐ¸Ð¸
+  text_project_identifier_info: Ð”Ð¾Ð¿ÑƒÑÐºÐ°ÑŽÑ‚ÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ ÑÑ‚Ñ€Ð¾Ñ‡Ð½Ñ‹Ðµ Ð»Ð°Ñ‚Ð¸Ð½ÑÐºÐ¸Ðµ Ð±ÑƒÐºÐ²Ñ‹ (a-z), Ñ†Ð¸Ñ„Ñ€Ñ‹, Ñ‚Ð¸Ñ€Ðµ Ð¸ Ð¿Ð¾Ð´Ñ‡ÐµÑ€ÐºÐ¸Ð²Ð°Ð½Ð¸Ñ.<br />ÐŸÐ¾ÑÐ»Ðµ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð½ÐµÐ»ÑŒÐ·Ñ.
+  field_multiple: ÐœÐ½Ð¾Ð¶ÐµÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ
+  setting_commit_cross_project_ref: Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ ÑÑÑ‹Ð»Ð°Ñ‚ÑŒÑÑ Ð¸ Ð¸ÑÐ¿Ñ€Ð°Ð²Ð»ÑÑ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð²Ð¾ Ð²ÑÐµÑ… Ð¾ÑÑ‚Ð°Ð»ÑŒÐ½Ñ‹Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ñ…
+  text_issue_conflict_resolution_add_notes: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ð¼Ð¾Ð¸ Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð¸ Ð¾Ñ‚ÐºÐ°Ð·Ð°Ñ‚ÑŒÑÑ Ð¾Ñ‚ Ð¼Ð¾Ð¸Ñ… Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹
+  text_issue_conflict_resolution_overwrite: ÐŸÑ€Ð¸Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð¼Ð¾Ð¸ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ (Ð²ÑÐµ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð¸Ðµ Ð·Ð°Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ñ‹, Ð½Ð¾ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ Ð±Ñ‹Ñ‚ÑŒ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿Ð¸ÑÐ°Ð½Ñ‹)
+  notice_issue_update_conflict: ÐšÑ‚Ð¾-Ñ‚Ð¾ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ð» Ð·Ð°Ð´Ð°Ñ‡Ñƒ, Ð¿Ð¾ÐºÐ° Ð²Ñ‹ ÐµÐµ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð»Ð¸.
+  text_issue_conflict_resolution_cancel: ÐžÑ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð¼Ð¾Ð¸ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸ Ð¿Ð¾ÐºÐ°Ð·Ð°Ñ‚ÑŒ Ð·Ð°Ð´Ð°Ñ‡Ñƒ Ð·Ð°Ð½Ð¾Ð²Ð¾ %{link}
+  permission_manage_related_issues: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑÐ²ÑÐ·Ð°Ð½Ð½Ñ‹Ð¼Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ð°Ð¼Ð¸
+  field_auth_source_ldap_filter: Ð¤Ð¸Ð»ÑŒÑ‚Ñ€ LDAP
+  label_search_for_watchers: ÐÐ°Ð¹Ñ‚Ð¸ Ð½Ð°Ð±Ð»ÑŽÐ´Ð°Ñ‚ÐµÐ»ÐµÐ¹
+  notice_account_deleted: "Ð’Ð°ÑˆÐ° ÑƒÑ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð¿Ð¾Ð»Ð½Ð¾ÑÑ‚ÑŒÑŽ ÑƒÐ´Ð°Ð»ÐµÐ½Ð°" 
+  setting_unsubscribe: "Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑÐ¼ ÑƒÐ´Ð°Ð»ÑÑ‚ÑŒ ÑÐ²Ð¾Ð¸ ÑƒÑ‡ÐµÑ‚Ð½Ñ‹Ðµ Ð·Ð°Ð¿Ð¸ÑÐ¸" 
+  button_delete_my_account: "Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð¼Ð¾ÑŽ ÑƒÑ‡ÐµÑ‚Ð½ÑƒÑŽ Ð·Ð°Ð¿Ð¸ÑÑŒ" 
+  text_account_destroy_confirmation: "Ð’Ð°ÑˆÐ° ÑƒÑ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ Ð±ÑƒÐ´ÐµÑ‚ Ð¿Ð¾Ð»Ð½Ð¾ÑÑ‚ÑŒÑŽ ÑƒÐ´Ð°Ð»ÐµÐ½Ð° Ð±ÐµÐ· Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚Ð¸ Ð²Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ.\nÐ’Ñ‹ ÑƒÐ²ÐµÑ€ÐµÐ½Ñ‹, Ñ‡Ñ‚Ð¾ Ñ…Ð¾Ñ‚Ð¸Ñ‚Ðµ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÑŒ?" 
+  error_session_expired: Ð¡Ñ€Ð¾Ðº Ð²Ð°ÑˆÐµÐ¹ ÑÐµÑÑÐ¸Ð¸ Ð¸ÑÑ‚ÐµÐº. ÐŸÐ¾Ð¶Ð°Ð»ÑƒÐ¹ÑÑ‚Ð° Ð²Ð¾Ð¹Ð´Ð¸Ñ‚Ðµ ÐµÑ‰Ðµ Ñ€Ð°Ð·
+  text_session_expiration_settings: "Ð’Ð½Ð¸Ð¼Ð°Ð½Ð¸Ðµ! Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ ÑÑ‚Ð¸Ñ… Ð½Ð°ÑÑ‚Ñ€Ð¾ÐµÐº Ð¼Ð¾Ð¶ÐµÑ‚ Ð¿Ñ€Ð¸Ð²ÐµÑÑ‚Ð¸ Ðº Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸ÑŽ Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ… ÑÐµÑÑÐ¸Ð¹, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð²Ð°ÑˆÑƒ."
+  setting_session_lifetime: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ ÑÐµÑÑÐ¸Ð¸
+  setting_session_timeout: Ð¢Ð°Ð¹Ð¼ÑƒÑ‚ ÑÐµÑÑÐ¸Ð¸ 
+  label_session_expiration: Ð¡Ñ€Ð¾Ðº Ð¸ÑÑ‚ÐµÑ‡ÐµÐ½Ð¸Ñ ÑÐµÑÑÐ¸Ð¸
+  permission_close_project: Ð—Ð°ÐºÑ€Ñ‹Ð²Ð°Ñ‚ÑŒ / Ð¾Ñ‚ÐºÑ€Ñ‹Ð²Ð°Ñ‚ÑŒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
+  label_show_closed_projects: ÐŸÑ€Ð¾ÑÐ¼Ð°Ñ‚Ñ€Ð¸Ð²Ð°Ñ‚ÑŒ Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ñ‹Ðµ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ‹
+  button_close: Ð¡Ð´ÐµÐ»Ð°Ñ‚ÑŒ Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼
+  button_reopen: Ð¡Ð´ÐµÐ»Ð°Ñ‚ÑŒ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼
+  project_status_active: Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ðµ
+  project_status_closed: Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ñ‹Ðµ
+  project_status_archived: Ð°Ñ€Ñ…Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ñ‹Ðµ
+  text_project_closed: ÐŸÑ€Ð¾ÐµÐºÑ‚ Ð·Ð°ÐºÑ€Ñ‹Ñ‚ Ð¸ Ð½Ð°Ñ…Ð¾Ð´Ð¸Ñ‚ÑŒÑÑ Ð² Ñ€ÐµÐ¶Ð¸Ð¼Ðµ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ.
+  notice_user_successful_create: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ %{id} ÑÐ¾Ð·Ð´Ð°Ð½.
+  field_core_fields: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ñ‹Ðµ Ð¿Ð¾Ð»Ñ
+  field_timeout: Ð¢Ð°Ð¹Ð¼Ð°ÑƒÑ‚ (Ð² ÑÐµÐºÑƒÐ½Ð´Ð°Ñ…)
+  setting_thumbnails_enabled: ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°Ñ‚ÑŒ Ð¿Ñ€ÐµÐ²ÑŒÑŽ Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ð¹
+  setting_thumbnails_size: Ð Ð°Ð·Ð¼ÐµÑ€ Ð¿ÐµÑ€Ð²ÑŒÑŽ (Ð² Ð¿Ð¸ÐºÑÐµÐ»ÑÑ…)
+  label_status_transitions: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ-Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ñ‹
+  label_fields_permissions: ÐŸÑ€Ð°Ð²Ð° Ð½Ð° Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ¹
+  label_readonly: ÐÐµ Ð¸Ð·Ð¼ÐµÐ½ÑÐµÑ‚ÑÑ
+  label_required: ÐžÐ±ÑÐ·Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ðµ
+  text_repository_identifier_info: Ð”Ð¾Ð¿ÑƒÑÐºÐ°ÑŽÑ‚ÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ ÑÑ‚Ñ€Ð¾Ñ‡Ð½Ñ‹Ðµ Ð»Ð°Ñ‚Ð¸Ð½ÑÐºÐ¸Ðµ Ð±ÑƒÐºÐ²Ñ‹ (a-z), Ñ†Ð¸Ñ„Ñ€Ñ‹, Ñ‚Ð¸Ñ€Ðµ Ð¸ Ð¿Ð¾Ð´Ñ‡ÐµÑ€ÐºÐ¸Ð²Ð°Ð½Ð¸Ñ.<br />ÐŸÐ¾ÑÐ»Ðµ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ Ð½ÐµÐ»ÑŒÐ·Ñ.
+  field_board_parent: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÑÐºÐ¸Ð¹ Ñ„Ð¾Ñ€ÑƒÐ¼
+  label_attribute_of_project: ÐŸÑ€Ð¾ÐµÐºÑ‚ %{name}
+  label_attribute_of_author: Ð˜Ð¼Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð° %{name}
+  label_attribute_of_assigned_to: ÐÐ°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð° %{name}
+  label_attribute_of_fixed_version: Ð’ÐµÑ€ÑÐ¸Ñ %{name}
+  label_copy_subtasks: ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸
+  label_copied_to: ÑÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð° Ð²
+  label_copied_from: ÑÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð° Ñ
+  label_any_issues_in_project: Ð»ÑŽÐ±Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚Ðµ
+  label_any_issues_not_in_project: Ð»ÑŽÐ±Ñ‹Ðµ Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð½Ðµ Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚Ðµ
+  field_private_notes: ÐŸÑ€Ð¸Ð²Ð°Ñ‚Ð½Ñ‹Ð¹ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ð¹
+  permission_view_private_notes: ÐŸÑ€Ð¾ÑÐ¼Ð¾Ñ‚Ñ€ Ð¿Ñ€Ð¸Ð²Ð°Ñ‚Ð½Ñ‹Ñ… ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²
+  permission_set_notes_private: Ð Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ðµ Ð¿Ñ€Ð¸Ð²Ð°Ñ‚Ð½Ñ‹Ñ… ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²
+  label_no_issues_in_project: Ð½ÐµÑ‚ Ð·Ð°Ð´Ð°Ñ‡ Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚Ðµ
+  label_any: Ð²ÑÐµ
+  label_last_n_weeks:
+    one:   "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½ÑÑ %{count} Ð½ÐµÐ´ÐµÐ»Ñ"
+    few:   "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ %{count} Ð½ÐµÐ´ÐµÐ»Ð¸"
+    many:  "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ %{count} Ð½ÐµÐ´ÐµÐ»ÑŒ"
+    other: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ %{count} Ð½ÐµÐ´ÐµÐ»Ð¸"
+  setting_cross_project_subtasks: Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð² Ð¼ÐµÐ¶Ð´Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
+  label_cross_project_descendants: Ð¡ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
+  label_cross_project_tree: Ð¡ Ð´ÐµÑ€ÐµÐ²Ð¾Ð¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  label_cross_project_hierarchy: Ð¡ Ð¸ÐµÑ€Ð°Ñ€Ñ…Ð¸ÐµÐ¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  label_cross_project_system: Ð¡Ð¾ Ð²ÑÐµÐ¼Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
+  button_hide: Ð¡ÐºÑ€Ñ‹Ñ‚ÑŒ
+  setting_non_working_week_days: ÐÐµÑ€Ð°Ð±Ð¾Ñ‡Ð¸Ðµ Ð´Ð½Ð¸
+  label_in_the_next_days: Ð² ÑÑ€ÐµÐ´ÑƒÑŽÑ‰Ð¸Ðµ Ð´Ð½Ð¸
+  label_in_the_past_days: Ð² Ð¿Ñ€Ð¾ÑˆÐ»Ñ‹Ðµ Ð´Ð½Ð¸
+  label_attribute_of_user: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ %{name}
+  text_turning_multiple_off: Ð•ÑÐ»Ð¸ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ð¼Ð½Ð¾Ð¶ÐµÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ, Ð»Ð¸ÑˆÐ½Ð¸Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ð· ÑÐ¿Ð¸ÑÐºÐ° Ð±ÑƒÐ´ÑƒÑ‚ ÑƒÐ´Ð°Ð»ÐµÐ½Ñ‹, Ñ‡Ñ‚Ð¾Ð±Ñ‹ Ð¾ÑÑ‚Ð°Ð»Ð¾ÑÑŒ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð¿Ð¾ Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÑŽ.
+  label_attribute_of_issue: Ð—Ð°Ð´Ð°Ñ‡Ð° %{name}
+  permission_add_documents: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
+  permission_edit_documents: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
+  permission_delete_documents: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
+  label_gantt_progress_line: Ð›Ð¸Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð³Ñ€ÐµÑÑÐ°
+  setting_jsonp_enabled: ÐŸÐ¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ° JSONP
+  field_inherit_members: ÐÐ°ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÑŒ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ¾Ð²
+  field_closed_on: Ð—Ð°ÐºÑ€Ñ‹Ñ‚Ð°
+  setting_default_projects_tracker_ids: Ð¢Ñ€ÐµÐºÐµÑ€Ñ‹ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  label_total_time: ÐžÐ±Ñ‰ÐµÐµ Ð²Ñ€ÐµÐ¼Ñ
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9a/9a6d307936e0e3f18679eabcd2eab7934463b58c.svn-base
--- a/.svn/pristine/9a/9a6d307936e0e3f18679eabcd2eab7934463b58c.svn-base
+++ /dev/null
@@ -1,116 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'issue_categories_controller'
-
-# Re-raise errors caught by the controller.
-class IssueCategoriesController; def rescue_action(e) raise e end; end
-
-class IssueCategoriesControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, :issue_categories
-
-  def setup
-    @controller = IssueCategoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @request.session[:user_id] = 2
-  end
-
-  def test_new
-    @request.session[:user_id] = 2 # manager
-    get :new, :project_id => '1'
-    assert_response :success
-    assert_template 'new'
-  end
-
-  def test_create
-    @request.session[:user_id] = 2 # manager
-    assert_difference 'IssueCategory.count' do
-      post :create, :project_id => '1', :issue_category => {:name => 'New category'}
-    end
-    assert_redirected_to '/projects/ecookbook/settings/categories'
-    category = IssueCategory.find_by_name('New category')
-    assert_not_nil category
-    assert_equal 1, category.project_id
-  end
-
-  def test_create_failure
-    @request.session[:user_id] = 2
-    post :create, :project_id => '1', :issue_category => {:name => ''}
-    assert_response :success
-    assert_template 'new'
-  end
-
-  def test_edit
-    @request.session[:user_id] = 2
-    get :edit, :id => 2
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_update
-    assert_no_difference 'IssueCategory.count' do
-      put :update, :id => 2, :issue_category => { :name => 'Testing' }
-    end
-    assert_redirected_to '/projects/ecookbook/settings/categories'
-    assert_equal 'Testing', IssueCategory.find(2).name
-  end
-
-  def test_update_failure
-    put :update, :id => 2, :issue_category => { :name => '' }
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_update_not_found
-    put :update, :id => 97, :issue_category => { :name => 'Testing' }
-    assert_response 404
-  end
-
-  def test_destroy_category_not_in_use
-    delete :destroy, :id => 2
-    assert_redirected_to '/projects/ecookbook/settings/categories'
-    assert_nil IssueCategory.find_by_id(2)
-  end
-
-  def test_destroy_category_in_use
-    delete :destroy, :id => 1
-    assert_response :success
-    assert_template 'destroy'
-    assert_not_nil IssueCategory.find_by_id(1)
-  end
-
-  def test_destroy_category_in_use_with_reassignment
-    issue = Issue.find(:first, :conditions => {:category_id => 1})
-    delete :destroy, :id => 1, :todo => 'reassign', :reassign_to_id => 2
-    assert_redirected_to '/projects/ecookbook/settings/categories'
-    assert_nil IssueCategory.find_by_id(1)
-    # check that the issue was reassign
-    assert_equal 2, issue.reload.category_id
-  end
-
-  def test_destroy_category_in_use_without_reassignment
-    issue = Issue.find(:first, :conditions => {:category_id => 1})
-    delete :destroy, :id => 1, :todo => 'nullify'
-    assert_redirected_to '/projects/ecookbook/settings/categories'
-    assert_nil IssueCategory.find_by_id(1)
-    # check that the issue category was nullified
-    assert_nil issue.reload.category_id
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9a/9a7627fe987e905eafd1b8c598387e304dd9ec66.svn-base
--- a/.svn/pristine/9a/9a7627fe987e905eafd1b8c598387e304dd9ec66.svn-base
+++ /dev/null
@@ -1,28 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::MenuManagerTest < ActiveSupport::TestCase
-  context "MenuManager#map" do
-    should "be tested"
-  end
-
-  context "MenuManager#items" do
-    should "be tested"
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9a/9a804621a7d8ed558b0c781c5e65d653f4285bc3.svn-base
--- a/.svn/pristine/9a/9a804621a7d8ed558b0c781c5e65d653f4285bc3.svn-base
+++ /dev/null
@@ -1,24 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class CommentObserver < ActiveRecord::Observer
-  def after_create(comment)
-    if comment.commented.is_a?(News) && Setting.notified_events.include?('news_comment_added')
-      Mailer.deliver_news_comment_added(comment)
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9a/9a917eda86235e54b9616e9bfd78037a8e9ecb46.svn-base
--- a/.svn/pristine/9a/9a917eda86235e54b9616e9bfd78037a8e9ecb46.svn-base
+++ /dev/null
@@ -1,47 +0,0 @@
-Return-Path: <jsmith@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
-Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
-From: "John Smith" <jsmith@somenet.foo>
-To: <redmine@somenet.foo>
-Subject: New ticket on a given project
-Date: Sun, 22 Jun 2008 12:28:07 +0200
-MIME-Version: 1.0
-Content-Type: text/plain;
-	format=flowed;
-	charset="iso-8859-1";
-	reply-type=original
-Content-Transfer-Encoding: 7bit
-X-Priority: 3
-X-MSMail-Priority: Normal
-X-Mailer: Microsoft Outlook Express 6.00.2900.2869
-X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet 
-turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus 
-blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti 
-sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In 
-in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras 
-sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum 
-id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus 
-eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique 
-sed, mauris. Pellentesque habitant morbi tristique senectus et netus et 
-malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse 
-platea dictumst.
-
-Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque 
-sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. 
-Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, 
-dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed, 
-massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo 
-pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
-
-Project: onlinestore
-Tracker: Feature request
-category: Stock management
-assigned to: miscuser9@foo.bar
-priority: foo
-done ratio: x
-start date: some day 
-due date: never
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9a/9acee3f273053af6824f9d963f851333a4619eb2.svn-base
--- /dev/null
+++ b/.svn/pristine/9a/9acee3f273053af6824f9d963f851333a4619eb2.svn-base
@@ -0,0 +1,47 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class DocumentCategoryTest < ActiveSupport::TestCase
+  fixtures :enumerations, :documents, :issues
+
+  def test_should_be_an_enumeration
+    assert DocumentCategory.ancestors.include?(Enumeration)
+  end
+
+  def test_objects_count
+    assert_equal 2, DocumentCategory.find_by_name("Uncategorized").objects_count
+    assert_equal 0, DocumentCategory.find_by_name("User documentation").objects_count
+  end
+
+  def test_option_name
+    assert_equal :enumeration_doc_categories, DocumentCategory.new.option_name
+  end
+
+  def test_default
+    assert_nil DocumentCategory.where(:is_default => true).first
+    e = Enumeration.find_by_name('Technical documentation')
+    e.update_attributes(:is_default => true)
+    assert_equal 3, DocumentCategory.default.id
+  end
+
+  def test_force_default
+    assert_nil DocumentCategory.where(:is_default => true).first
+    assert_equal 1, DocumentCategory.default.id
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9a/9af49165fac122637d3fa15ff2333d3fdc06effe.svn-base
--- a/.svn/pristine/9a/9af49165fac122637d3fa15ff2333d3fdc06effe.svn-base
+++ /dev/null
@@ -1,36 +0,0 @@
-<div class="contextual">
-    <%= link_to l(:label_personalize_page), :action => 'page_layout' %>
-</div>
-
-<h2><%=l(:label_my_page)%></h2>
-
-<div id="list-top">
-  <% @blocks['top'].each do |b|
-     next unless MyController::BLOCKS.keys.include? b  %>
-  <div class="mypage-box">
-    <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %>
-  </div>
-  <% end if @blocks['top'] %>
-</div>
-
-<div id="list-left" class="splitcontentleft">
-  <% @blocks['left'].each do |b|
-     next unless MyController::BLOCKS.keys.include? b %>
-  <div class="mypage-box">
-    <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %>
-  </div>
-  <% end if @blocks['left'] %>
-</div>
-
-<div id="list-right" class="splitcontentright">
-  <% @blocks['right'].each do |b|
-     next unless MyController::BLOCKS.keys.include? b %>
-  <div class="mypage-box">
-    <%= render :partial => "my/blocks/#{b}", :locals => { :user => @user } %>
-  </div>
-  <% end if @blocks['right'] %>
-</div>
-
-<%= context_menu :controller => 'issues', :action => 'context_menu' %>
-
-<% html_title(l(:label_my_page)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9b/9b1f5b5bd07f84713d7062a0c2027d1968060778.svn-base
--- a/.svn/pristine/9b/9b1f5b5bd07f84713d7062a0c2027d1968060778.svn-base
+++ /dev/null
@@ -1,68 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class PreviewsControllerTest < ActionController::TestCase
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :journals, :journal_details
-
-  def test_preview_new_issue
-    @request.session[:user_id] = 2
-    post :issue, :project_id => '1', :issue => {:description => 'Foo'}
-    assert_response :success
-    assert_template 'preview'
-    assert_not_nil assigns(:description)
-  end
-
-  def test_preview_issue_notes
-    @request.session[:user_id] = 2
-    post :issue, :project_id => '1', :id => 1,
-         :issue => {:description => Issue.find(1).description},
-         :notes => 'Foo'
-    assert_response :success
-    assert_template 'preview'
-    assert_not_nil assigns(:notes)
-  end
-
-  def test_preview_journal_notes_for_update
-    @request.session[:user_id] = 2
-    post :issue, :project_id => '1', :id => 1, :notes => 'Foo'
-    assert_response :success
-    assert_template 'preview'
-    assert_not_nil assigns(:notes)
-    assert_tag :p, :content => 'Foo'
-  end
-
-  def test_news
-    get :news, :project_id => 1,
-                  :news => {:title => '',
-                            :description => 'News description',
-                            :summary => ''}
-    assert_response :success
-    assert_template 'common/_preview'
-    assert_tag :tag => 'fieldset', :attributes => { :class => 'preview' },
-                                   :content => /News description/
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9b/9b78d70dc9c6735d019be6a62f572ddbb49ef10e.svn-base
--- a/.svn/pristine/9b/9b78d70dc9c6735d019be6a62f572ddbb49ef10e.svn-base
+++ /dev/null
@@ -1,101 +0,0 @@
-# $Id: testdata.ldif 50 2006-04-17 17:57:33Z blackhedd $
-#
-# This is test-data for an LDAP server in LDIF format.
-#
-dn: dc=bayshorenetworks,dc=com
-objectClass: dcObject
-objectClass: organization
-o: Bayshore Networks LLC
-dc: bayshorenetworks
-
-dn: cn=Manager,dc=bayshorenetworks,dc=com
-objectClass: organizationalrole
-cn: Manager
-
-dn: ou=people,dc=bayshorenetworks,dc=com
-objectClass: organizationalunit
-ou: people
-
-dn: ou=privileges,dc=bayshorenetworks,dc=com
-objectClass: organizationalunit
-ou: privileges
-
-dn: ou=roles,dc=bayshorenetworks,dc=com
-objectClass: organizationalunit
-ou: roles
-
-dn: ou=office,dc=bayshorenetworks,dc=com
-objectClass: organizationalunit
-ou: office
-
-dn: mail=nogoodnik@steamheat.net,ou=people,dc=bayshorenetworks,dc=com
-cn: Bob Fosse
-mail: nogoodnik@steamheat.net
-sn: Fosse
-ou: people
-objectClass: top
-objectClass: inetorgperson
-objectClass: authorizedperson
-hasAccessRole: uniqueIdentifier=engineer,ou=roles
-hasAccessRole: uniqueIdentifier=ldapadmin,ou=roles
-hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles
-hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles
-hasAccessRole: uniqueIdentifier=ogilvy_eagle_user,ou=roles
-hasAccessRole: uniqueIdentifier=greenplug_user,ou=roles
-hasAccessRole: uniqueIdentifier=brandplace_logging_user,ou=roles
-hasAccessRole: uniqueIdentifier=brandplace_report_user,ou=roles
-hasAccessRole: uniqueIdentifier=workorder_user,ou=roles
-hasAccessRole: uniqueIdentifier=bayshore_eagle_user,ou=roles
-hasAccessRole: uniqueIdentifier=bayshore_eagle_superuser,ou=roles
-hasAccessRole: uniqueIdentifier=kledaras_user,ou=roles
-
-dn: mail=elephant@steamheat.net,ou=people,dc=bayshorenetworks,dc=com
-cn: Gwen Verdon
-mail: elephant@steamheat.net
-sn: Verdon
-ou: people
-objectClass: top
-objectClass: inetorgperson
-objectClass: authorizedperson
-hasAccessRole: uniqueIdentifier=brandplace_report_user,ou=roles
-hasAccessRole: uniqueIdentifier=engineer,ou=roles
-hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles
-hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles
-hasAccessRole: uniqueIdentifier=ldapadmin,ou=roles
-
-dn: uniqueIdentifier=engineering,ou=privileges,dc=bayshorenetworks,dc=com
-uniqueIdentifier: engineering
-ou: privileges
-objectClass: accessPrivilege
-
-dn: uniqueIdentifier=engineer,ou=roles,dc=bayshorenetworks,dc=com
-uniqueIdentifier: engineer
-ou: roles
-objectClass: accessRole
-hasAccessPrivilege: uniqueIdentifier=engineering,ou=privileges
-
-dn: uniqueIdentifier=ldapadmin,ou=roles,dc=bayshorenetworks,dc=com
-uniqueIdentifier: ldapadmin
-ou: roles
-objectClass: accessRole
-
-dn: uniqueIdentifier=ldapsuperadmin,ou=roles,dc=bayshorenetworks,dc=com
-uniqueIdentifier: ldapsuperadmin
-ou: roles
-objectClass: accessRole
-
-dn: mail=catperson@steamheat.net,ou=people,dc=bayshorenetworks,dc=com
-cn: Sid Sorokin
-mail: catperson@steamheat.net
-sn: Sorokin
-ou: people
-objectClass: top
-objectClass: inetorgperson
-objectClass: authorizedperson
-hasAccessRole: uniqueIdentifier=engineer,ou=roles
-hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles
-hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles
-hasAccessRole: uniqueIdentifier=ogilvy_eagle_user,ou=roles
-hasAccessRole: uniqueIdentifier=greenplug_user,ou=roles
-hasAccessRole: uniqueIdentifier=workorder_user,ou=roles
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9b/9bcbcb6cd03a6fef4b0b266553f676db60208801.svn-base
--- a/.svn/pristine/9b/9bcbcb6cd03a6fef4b0b266553f676db60208801.svn-base
+++ /dev/null
@@ -1,4 +0,0 @@
-<% labelled_tabular_form_for @project do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9b/9bfe3004372f8803340b8718f85aeaf1a4b54da6.svn-base
--- a/.svn/pristine/9b/9bfe3004372f8803340b8718f85aeaf1a4b54da6.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/performance/request'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9c/9c29f1b6dc547473ab1c34c645fabf4dd7aa8716.svn-base
--- /dev/null
+++ b/.svn/pristine/9c/9c29f1b6dc547473ab1c34c645fabf4dd7aa8716.svn-base
@@ -0,0 +1,262 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class ProjectsController < ApplicationController
+  menu_item :overview
+  menu_item :roadmap, :only => :roadmap
+  menu_item :settings, :only => :settings
+
+  before_filter :find_project, :except => [ :index, :list, :new, :create, :copy ]
+  before_filter :authorize, :except => [ :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy]
+  before_filter :authorize_global, :only => [:new, :create]
+  before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
+  accept_rss_auth :index
+  accept_api_auth :index, :show, :create, :update, :destroy
+
+  after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller|
+    if controller.request.post?
+      controller.send :expire_action, :controller => 'welcome', :action => 'robots'
+    end
+  end
+
+  helper :sort
+  include SortHelper
+  helper :custom_fields
+  include CustomFieldsHelper
+  helper :issues
+  helper :queries
+  include QueriesHelper
+  helper :repositories
+  include RepositoriesHelper
+  include ProjectsHelper
+  helper :members
+
+  # Lists visible projects
+  def index
+    respond_to do |format|
+      format.html {
+        scope = Project
+        unless params[:closed]
+          scope = scope.active
+        end
+        @projects = scope.visible.order('lft').all
+      }
+      format.api  {
+        @offset, @limit = api_offset_and_limit
+        @project_count = Project.visible.count
+        @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all
+      }
+      format.atom {
+        projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all
+        render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}")
+      }
+    end
+  end
+
+  def new
+    @issue_custom_fields = IssueCustomField.sorted.all
+    @trackers = Tracker.sorted.all
+    @project = Project.new
+    @project.safe_attributes = params[:project]
+  end
+
+  def create
+    @issue_custom_fields = IssueCustomField.sorted.all
+    @trackers = Tracker.sorted.all
+    @project = Project.new
+    @project.safe_attributes = params[:project]
+
+    if validate_parent_id && @project.save
+      @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
+      # Add current user as a project member if he is not admin
+      unless User.current.admin?
+        r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first
+        m = Member.new(:user => User.current, :roles => [r])
+        @project.members << m
+      end
+      respond_to do |format|
+        format.html {
+          flash[:notice] = l(:notice_successful_create)
+          if params[:continue]
+            attrs = {:parent_id => @project.parent_id}.reject {|k,v| v.nil?}
+            redirect_to new_project_path(attrs)
+          else
+            redirect_to settings_project_path(@project)
+          end
+        }
+        format.api  { render :action => 'show', :status => :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) }
+      end
+    else
+      respond_to do |format|
+        format.html { render :action => 'new' }
+        format.api  { render_validation_errors(@project) }
+      end
+    end
+  end
+
+  def copy
+    @issue_custom_fields = IssueCustomField.sorted.all
+    @trackers = Tracker.sorted.all
+    @source_project = Project.find(params[:id])
+    if request.get?
+      @project = Project.copy_from(@source_project)
+      @project.identifier = Project.next_identifier if Setting.sequential_project_identifiers?
+    else
+      Mailer.with_deliveries(params[:notifications] == '1') do
+        @project = Project.new
+        @project.safe_attributes = params[:project]
+        if validate_parent_id && @project.copy(@source_project, :only => params[:only])
+          @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
+          flash[:notice] = l(:notice_successful_create)
+          redirect_to settings_project_path(@project)
+        elsif !@project.new_record?
+          # Project was created
+          # But some objects were not copied due to validation failures
+          # (eg. issues from disabled trackers)
+          # TODO: inform about that
+          redirect_to settings_project_path(@project)
+        end
+      end
+    end
+  rescue ActiveRecord::RecordNotFound
+    # source_project not found
+    render_404
+  end
+
+  # Show @project
+  def show
+    # try to redirect to the requested menu item
+    if params[:jump] && redirect_to_project_menu_item(@project, params[:jump])
+      return
+    end
+
+    @users_by_role = @project.users_by_role
+    @subprojects = @project.children.visible.all
+    @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").all
+    @trackers = @project.rolled_up_trackers
+
+    cond = @project.project_condition(Setting.display_subprojects_issues?)
+
+    @open_issues_by_tracker = Issue.visible.open.where(cond).count(:group => :tracker)
+    @total_issues_by_tracker = Issue.visible.where(cond).count(:group => :tracker)
+
+    if User.current.allowed_to?(:view_time_entries, @project)
+      @total_hours = TimeEntry.visible.sum(:hours, :include => :project, :conditions => cond).to_f
+    end
+
+    @key = User.current.rss_key
+
+    respond_to do |format|
+      format.html
+      format.api
+    end
+  end
+
+  def settings
+    @issue_custom_fields = IssueCustomField.sorted.all
+    @issue_category ||= IssueCategory.new
+    @member ||= @project.members.new
+    @trackers = Tracker.sorted.all
+    @wiki ||= @project.wiki
+  end
+
+  def edit
+  end
+
+  def update
+    @project.safe_attributes = params[:project]
+    if validate_parent_id && @project.save
+      @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
+      respond_to do |format|
+        format.html {
+          flash[:notice] = l(:notice_successful_update)
+          redirect_to settings_project_path(@project)
+        }
+        format.api  { render_api_ok }
+      end
+    else
+      respond_to do |format|
+        format.html {
+          settings
+          render :action => 'settings'
+        }
+        format.api  { render_validation_errors(@project) }
+      end
+    end
+  end
+
+  def modules
+    @project.enabled_module_names = params[:enabled_module_names]
+    flash[:notice] = l(:notice_successful_update)
+    redirect_to settings_project_path(@project, :tab => 'modules')
+  end
+
+  def archive
+    if request.post?
+      unless @project.archive
+        flash[:error] = l(:error_can_not_archive_project)
+      end
+    end
+    redirect_to admin_projects_path(:status => params[:status])
+  end
+
+  def unarchive
+    @project.unarchive if request.post? && !@project.active?
+    redirect_to admin_projects_path(:status => params[:status])
+  end
+
+  def close
+    @project.close
+    redirect_to project_path(@project)
+  end
+
+  def reopen
+    @project.reopen
+    redirect_to project_path(@project)
+  end
+
+  # Delete @project
+  def destroy
+    @project_to_destroy = @project
+    if api_request? || params[:confirm]
+      @project_to_destroy.destroy
+      respond_to do |format|
+        format.html { redirect_to admin_projects_path }
+        format.api  { render_api_ok }
+      end
+    end
+    # hide project in layout
+    @project = nil
+  end
+
+  private
+
+  # Validates parent_id param according to user's permissions
+  # TODO: move it to Project model in a validation that depends on User.current
+  def validate_parent_id
+    return true if User.current.admin?
+    parent_id = params[:project] && params[:project][:parent_id]
+    if parent_id || @project.new_record?
+      parent = parent_id.blank? ? nil : Project.find_by_id(parent_id.to_i)
+      unless @project.allowed_parents.include?(parent)
+        @project.errors.add :parent_id, :invalid
+        return false
+      end
+    end
+    true
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9c/9c3af39547b04b7831f942c7b6b88179c7934a14.svn-base
--- a/.svn/pristine/9c/9c3af39547b04b7831f942c7b6b88179c7934a14.svn-base
+++ /dev/null
@@ -1,81 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class CalendarsControllerTest < ActionController::TestCase
-  fixtures :projects,
-           :trackers,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :auth_sources,
-           :enabled_modules
-
-  def test_calendar
-    get :show, :project_id => 1
-    assert_response :success
-    assert_template 'calendar'
-    assert_not_nil assigns(:calendar)
-  end
-
-  def test_cross_project_calendar
-    get :show
-    assert_response :success
-    assert_template 'calendar'
-    assert_not_nil assigns(:calendar)
-  end
-
-  context "GET :show" do
-    should "run custom queries" do
-      @query = Query.generate_default!(:is_public => true)
-
-      get :show, :query_id => @query.id
-      assert_response :success
-    end
-
-  end
-
-  def test_week_number_calculation
-    Setting.start_of_week = 7
-
-    get :show, :month => '1', :year => '2010'
-    assert_response :success
-
-    assert_tag :tag => 'tr',
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'week-number'}, :content => '53'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'odd'}, :content => '27'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '2'}
-
-    assert_tag :tag => 'tr',
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'week-number'}, :content => '1'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'odd'}, :content => '3'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '9'}
-
-
-    Setting.start_of_week = 1
-    get :show, :month => '1', :year => '2010'
-    assert_response :success
-
-    assert_tag :tag => 'tr',
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'week-number'}, :content => '53'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '28'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '3'}
-
-    assert_tag :tag => 'tr',
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'week-number'}, :content => '1'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '4'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '10'}
-
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9c/9c8281962b9cfd931f9c0e3d460c0770102a1d50.svn-base
--- /dev/null
+++ b/.svn/pristine/9c/9c8281962b9cfd931f9c0e3d460c0770102a1d50.svn-base
@@ -0,0 +1,26 @@
+<div class="contextual">
+<%= link_to l(:label_group_new), new_group_path, :class => 'icon icon-add' %>
+</div>
+
+<h2><%= l(:label_group_plural) %></h2>
+
+<% if @groups.any? %>
+<table class="list groups">
+  <thead><tr>
+  <th><%=l(:label_group)%></th>
+  <th><%=l(:label_user_plural)%></th>
+  <th></th>
+  </tr></thead>
+  <tbody>
+<% @groups.each do |group| %>
+  <tr class="<%= cycle 'odd', 'even' %>">
+    <td><%= link_to h(group), edit_group_path(group) %></td>
+    <td align="center"><%= group.users.size %></td>
+    <td class="buttons"><%= delete_link group %></td>
+  </tr>
+<% end %>
+  </tbody>
+</table>
+<% else %>
+<p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9c/9c9aeef26ca0ef44d1a985d89461dafc7a3e74a3.svn-base
--- a/.svn/pristine/9c/9c9aeef26ca0ef44d1a985d89461dafc7a3e74a3.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::IssueCategoriesTest < ActionController::IntegrationTest
-  fixtures :projects, :users, :issue_categories, :issues,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "GET /projects/:project_id/issue_categories.xml" do
-    should "return issue categories" do
-      get '/projects/1/issue_categories.xml', {}, :authorization => credentials('jsmith')
-      assert_response :success
-      assert_equal 'application/xml', @response.content_type
-      assert_tag :tag => 'issue_categories',
-        :child => {:tag => 'issue_category', :child => {:tag => 'id', :content => '2'}}
-    end
-  end
-
-  context "GET /issue_categories/2.xml" do
-    should "return requested issue category" do
-      get '/issue_categories/2.xml', {}, :authorization => credentials('jsmith')
-      assert_response :success
-      assert_equal 'application/xml', @response.content_type
-      assert_tag :tag => 'issue_category',
-        :child => {:tag => 'id', :content => '2'}
-    end
-  end
-
-  context "POST /projects/:project_id/issue_categories.xml" do
-    should "return create issue category" do
-      assert_difference 'IssueCategory.count' do
-        post '/projects/1/issue_categories.xml', {:issue_category => {:name => 'API'}}, :authorization => credentials('jsmith')
-      end
-      assert_response :created
-      assert_equal 'application/xml', @response.content_type
-
-      category = IssueCategory.first(:order => 'id DESC')
-      assert_equal 'API', category.name
-      assert_equal 1, category.project_id
-    end
-
-    context "with invalid parameters" do
-      should "return errors" do
-        assert_no_difference 'IssueCategory.count' do
-          post '/projects/1/issue_categories.xml', {:issue_category => {:name => ''}}, :authorization => credentials('jsmith')
-        end
-        assert_response :unprocessable_entity
-        assert_equal 'application/xml', @response.content_type
-
-        assert_tag 'errors', :child => {:tag => 'error', :content => "Name can't be blank"}
-      end
-    end
-  end
-
-  context "PUT /issue_categories/2.xml" do
-    context "with valid parameters" do
-      should "update issue category" do
-        assert_no_difference 'IssueCategory.count' do
-          put '/issue_categories/2.xml', {:issue_category => {:name => 'API Update'}}, :authorization => credentials('jsmith')
-        end
-        assert_response :ok
-        assert_equal 'API Update', IssueCategory.find(2).name
-      end
-    end
-
-    context "with invalid parameters" do
-      should "return errors" do
-        assert_no_difference 'IssueCategory.count' do
-          put '/issue_categories/2.xml', {:issue_category => {:name => ''}}, :authorization => credentials('jsmith')
-        end
-        assert_response :unprocessable_entity
-        assert_equal 'application/xml', @response.content_type
-
-        assert_tag 'errors', :child => {:tag => 'error', :content => "Name can't be blank"}
-      end
-    end
-  end
-
-  context "DELETE /issue_categories/1.xml" do
-    should "destroy issue categories" do
-      assert_difference 'IssueCategory.count', -1 do
-        delete '/issue_categories/1.xml', {}, :authorization => credentials('jsmith')
-      end
-      assert_response :ok
-      assert_nil IssueCategory.find_by_id(1)
-    end
-    
-    should "reassign issues with :reassign_to_id param" do
-      issue_count = Issue.count(:conditions => {:category_id => 1})
-      assert issue_count > 0
-
-      assert_difference 'IssueCategory.count', -1 do
-        assert_difference 'Issue.count(:conditions => {:category_id => 2})', 3 do
-          delete '/issue_categories/1.xml', {:reassign_to_id => 2}, :authorization => credentials('jsmith')
-        end
-      end
-      assert_response :ok
-      assert_nil IssueCategory.find_by_id(1)
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9c/9cc9a2ea51ca07fe0569f1c3d1472f322c6a7d0e.svn-base
--- /dev/null
+++ b/.svn/pristine/9c/9cc9a2ea51ca07fe0569f1c3d1472f322c6a7d0e.svn-base
@@ -0,0 +1,18 @@
+<%= form_for @project,
+            :url => { :action => 'modules', :id => @project },
+            :html => {:id => 'modules-form',
+                      :method => :post} do |f| %>
+
+<fieldset class="box">
+<legend><%= l(:text_select_project_modules) %></legend>
+
+<% Redmine::AccessControl.available_project_modules.each do |m| %>
+<p><label><%= check_box_tag 'enabled_module_names[]', m, @project.module_enabled?(m) -%>
+ <%= l_or_humanize(m, :prefix => "project_module_") %></label></p>
+<% end %>
+</fieldset>
+<p><%= check_all_links 'modules-form' %></p>
+
+<p><%= submit_tag l(:button_save) %></p>
+
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9c/9ccedbf66a9f47b4ce6ada31cc7d30c26f464002.svn-base
--- /dev/null
+++ b/.svn/pristine/9c/9ccedbf66a9f47b4ce6ada31cc7d30c26f464002.svn-base
@@ -0,0 +1,40 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingActivitiesTest < ActionController::IntegrationTest
+  def test_activities
+    assert_routing(
+           { :method => 'get', :path => "/activity" },
+           { :controller => 'activities', :action => 'index' }
+        )
+    assert_routing(
+           { :method => 'get', :path => "/activity.atom" },
+           { :controller => 'activities', :action => 'index', :format => 'atom' }
+        )
+    assert_routing(
+        { :method => 'get', :path => "/projects/33/activity" },
+        { :controller => 'activities', :action => 'index', :id => '33' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/33/activity.atom" },
+        { :controller => 'activities', :action => 'index', :id => '33',
+          :format => 'atom' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9c/9cd7e94ac195fc7d935cfe5b519a4f1a68e73a19.svn-base
--- a/.svn/pristine/9c/9cd7e94ac195fc7d935cfe5b519a4f1a68e73a19.svn-base
+++ /dev/null
@@ -1,541 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class MailHandlerTest < ActiveSupport::TestCase
-  fixtures :users, :projects,
-                   :enabled_modules,
-                   :roles,
-                   :members,
-                   :member_roles,
-                   :users,
-                   :issues,
-                   :issue_statuses,
-                   :workflows,
-                   :trackers,
-                   :projects_trackers,
-                   :versions,
-                   :enumerations,
-                   :issue_categories,
-                   :custom_fields,
-                   :custom_fields_trackers,
-                   :custom_fields_projects,
-                   :boards,
-                   :messages
-
-  FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
-
-  def setup
-    ActionMailer::Base.deliveries.clear
-    Setting.notified_events = Redmine::Notifiable.all.collect(&:name)
-  end
-
-  def test_add_issue
-    ActionMailer::Base.deliveries.clear
-    # This email contains: 'Project: onlinestore'
-    issue = submit_email('ticket_on_given_project.eml')
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal Project.find(2), issue.project
-    assert_equal issue.project.trackers.first, issue.tracker
-    assert_equal 'New ticket on a given project', issue.subject
-    assert_equal User.find_by_login('jsmith'), issue.author
-    assert_equal IssueStatus.find_by_name('Resolved'), issue.status
-    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
-    assert_equal '2010-01-01', issue.start_date.to_s
-    assert_equal '2010-12-31', issue.due_date.to_s
-    assert_equal User.find_by_login('jsmith'), issue.assigned_to
-    assert_equal Version.find_by_name('Alpha'), issue.fixed_version
-    assert_equal 2.5, issue.estimated_hours
-    assert_equal 30, issue.done_ratio
-    assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
-    # keywords should be removed from the email body
-    assert !issue.description.match(/^Project:/i)
-    assert !issue.description.match(/^Status:/i)
-    assert !issue.description.match(/^Start Date:/i)
-    # Email notification should be sent
-    mail = ActionMailer::Base.deliveries.last
-    assert_not_nil mail
-    assert mail.subject.include?('New ticket on a given project')
-  end
-
-  def test_add_issue_with_default_tracker
-    # This email contains: 'Project: onlinestore'
-    issue = submit_email('ticket_on_given_project.eml', :issue => {:tracker => 'Support request'})
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal 'Support request', issue.tracker.name
-  end
-
-  def test_add_issue_with_status
-    # This email contains: 'Project: onlinestore' and 'Status: Resolved'
-    issue = submit_email('ticket_on_given_project.eml')
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal Project.find(2), issue.project
-    assert_equal IssueStatus.find_by_name("Resolved"), issue.status
-  end
-
-  def test_add_issue_with_attributes_override
-    issue = submit_email('ticket_with_attributes.eml', :allow_override => 'tracker,category,priority')
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal 'New ticket on a given project', issue.subject
-    assert_equal User.find_by_login('jsmith'), issue.author
-    assert_equal Project.find(2), issue.project
-    assert_equal 'Feature request', issue.tracker.to_s
-    assert_equal 'Stock management', issue.category.to_s
-    assert_equal 'Urgent', issue.priority.to_s
-    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
-  end
-
-  def test_add_issue_with_group_assignment
-    with_settings :issue_group_assignment => '1' do
-      issue = submit_email('ticket_on_given_project.eml') do |email|
-        email.gsub!('Assigned to: John Smith', 'Assigned to: B Team')
-      end
-      assert issue.is_a?(Issue)
-      assert !issue.new_record?
-      issue.reload
-      assert_equal Group.find(11), issue.assigned_to
-    end
-  end
-
-  def test_add_issue_with_partial_attributes_override
-    issue = submit_email('ticket_with_attributes.eml', :issue => {:priority => 'High'}, :allow_override => ['tracker'])
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal 'New ticket on a given project', issue.subject
-    assert_equal User.find_by_login('jsmith'), issue.author
-    assert_equal Project.find(2), issue.project
-    assert_equal 'Feature request', issue.tracker.to_s
-    assert_nil issue.category
-    assert_equal 'High', issue.priority.to_s
-    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
-  end
-
-  def test_add_issue_with_spaces_between_attribute_and_separator
-    issue = submit_email('ticket_with_spaces_between_attribute_and_separator.eml', :allow_override => 'tracker,category,priority')
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal 'New ticket on a given project', issue.subject
-    assert_equal User.find_by_login('jsmith'), issue.author
-    assert_equal Project.find(2), issue.project
-    assert_equal 'Feature request', issue.tracker.to_s
-    assert_equal 'Stock management', issue.category.to_s
-    assert_equal 'Urgent', issue.priority.to_s
-    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
-  end
-
-  def test_add_issue_with_attachment_to_specific_project
-    issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal 'Ticket created by email with attachment', issue.subject
-    assert_equal User.find_by_login('jsmith'), issue.author
-    assert_equal Project.find(2), issue.project
-    assert_equal 'This is  a new ticket with attachments', issue.description
-    # Attachment properties
-    assert_equal 1, issue.attachments.size
-    assert_equal 'Paella.jpg', issue.attachments.first.filename
-    assert_equal 'image/jpeg', issue.attachments.first.content_type
-    assert_equal 10790, issue.attachments.first.filesize
-  end
-
-  def test_add_issue_with_custom_fields
-    issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'onlinestore'})
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal 'New ticket with custom field values', issue.subject
-    assert_equal 'Value for a custom field', issue.custom_value_for(CustomField.find_by_name('Searchable field')).value
-    assert !issue.description.match(/^searchable field:/i)
-  end
-
-  def test_add_issue_with_cc
-    issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'})
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert issue.watched_by?(User.find_by_mail('dlopper@somenet.foo'))
-    assert_equal 1, issue.watcher_user_ids.size
-  end
-
-  def test_add_issue_by_unknown_user
-    assert_no_difference 'User.count' do
-      assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'})
-    end
-  end
-
-  def test_add_issue_by_anonymous_user
-    Role.anonymous.add_permission!(:add_issues)
-    assert_no_difference 'User.count' do
-      issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept')
-      assert issue.is_a?(Issue)
-      assert issue.author.anonymous?
-    end
-  end
-
-  def test_add_issue_by_anonymous_user_with_no_from_address
-    Role.anonymous.add_permission!(:add_issues)
-    assert_no_difference 'User.count' do
-      issue = submit_email('ticket_by_empty_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept')
-      assert issue.is_a?(Issue)
-      assert issue.author.anonymous?
-    end
-  end
-
-  def test_add_issue_by_anonymous_user_on_private_project
-    Role.anonymous.add_permission!(:add_issues)
-    assert_no_difference 'User.count' do
-      assert_no_difference 'Issue.count' do
-        assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :unknown_user => 'accept')
-      end
-    end
-  end
-
-  def test_add_issue_by_anonymous_user_on_private_project_without_permission_check
-    assert_no_difference 'User.count' do
-      assert_difference 'Issue.count' do
-        issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :no_permission_check => '1', :unknown_user => 'accept')
-        assert issue.is_a?(Issue)
-        assert issue.author.anonymous?
-        assert !issue.project.is_public?
-        assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
-      end
-    end
-  end
-
-  def test_add_issue_by_created_user
-    Setting.default_language = 'en'
-    assert_difference 'User.count' do
-      issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create')
-      assert issue.is_a?(Issue)
-      assert issue.author.active?
-      assert_equal 'john.doe@somenet.foo', issue.author.mail
-      assert_equal 'John', issue.author.firstname
-      assert_equal 'Doe', issue.author.lastname
-
-      # account information
-      email = ActionMailer::Base.deliveries.first
-      assert_not_nil email
-      assert email.subject.include?('account activation')
-      login = email.body.match(/\* Login: (.*)$/)[1]
-      password = email.body.match(/\* Password: (.*)$/)[1]
-      assert_equal issue.author, User.try_to_login(login, password)
-    end
-  end
-
-  def test_add_issue_without_from_header
-    Role.anonymous.add_permission!(:add_issues)
-    assert_equal false, submit_email('ticket_without_from_header.eml')
-  end
-
-  def test_add_issue_with_invalid_attributes
-    issue = submit_email('ticket_with_invalid_attributes.eml', :allow_override => 'tracker,category,priority')
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_nil issue.assigned_to
-    assert_nil issue.start_date
-    assert_nil issue.due_date
-    assert_equal 0, issue.done_ratio
-    assert_equal 'Normal', issue.priority.to_s
-    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
-  end
-
-  def test_add_issue_with_localized_attributes
-    User.find_by_mail('jsmith@somenet.foo').update_attribute 'language', 'fr'
-    issue = submit_email('ticket_with_localized_attributes.eml', :allow_override => 'tracker,category,priority')
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal 'New ticket on a given project', issue.subject
-    assert_equal User.find_by_login('jsmith'), issue.author
-    assert_equal Project.find(2), issue.project
-    assert_equal 'Feature request', issue.tracker.to_s
-    assert_equal 'Stock management', issue.category.to_s
-    assert_equal 'Urgent', issue.priority.to_s
-    assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
-  end
-
-  def test_add_issue_with_japanese_keywords
-    tracker = Tracker.create!(:name => 'é–‹ç™º')
-    Project.find(1).trackers << tracker
-    issue = submit_email('japanese_keywords_iso_2022_jp.eml', :issue => {:project => 'ecookbook'}, :allow_override => 'tracker')
-    assert_kind_of Issue, issue
-    assert_equal tracker, issue.tracker
-  end
-
-  def test_add_issue_from_apple_mail
-    issue = submit_email('apple_mail_with_attachment.eml', :issue => {:project => 'ecookbook'})
-    assert_kind_of Issue, issue
-    assert_equal 1, issue.attachments.size
-
-    attachment = issue.attachments.first
-    assert_equal 'paella.jpg', attachment.filename
-    assert_equal 10790, attachment.filesize
-  end
-
-  def test_should_ignore_emails_from_emission_address
-    Role.anonymous.add_permission!(:add_issues)
-    assert_no_difference 'User.count' do
-      assert_equal false, submit_email('ticket_from_emission_address.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create')
-    end
-  end
-
-  def test_add_issue_should_send_email_notification
-    Setting.notified_events = ['issue_added']
-    ActionMailer::Base.deliveries.clear
-    # This email contains: 'Project: onlinestore'
-    issue = submit_email('ticket_on_given_project.eml')
-    assert issue.is_a?(Issue)
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_update_issue
-    journal = submit_email('ticket_reply.eml')
-    assert journal.is_a?(Journal)
-    assert_equal User.find_by_login('jsmith'), journal.user
-    assert_equal Issue.find(2), journal.journalized
-    assert_match /This is reply/, journal.notes
-    assert_equal 'Feature request', journal.issue.tracker.name
-  end
-
-  def test_update_issue_with_attribute_changes
-    # This email contains: 'Status: Resolved'
-    journal = submit_email('ticket_reply_with_status.eml')
-    assert journal.is_a?(Journal)
-    issue = Issue.find(journal.issue.id)
-    assert_equal User.find_by_login('jsmith'), journal.user
-    assert_equal Issue.find(2), journal.journalized
-    assert_match /This is reply/, journal.notes
-    assert_equal 'Feature request', journal.issue.tracker.name
-    assert_equal IssueStatus.find_by_name("Resolved"), issue.status
-    assert_equal '2010-01-01', issue.start_date.to_s
-    assert_equal '2010-12-31', issue.due_date.to_s
-    assert_equal User.find_by_login('jsmith'), issue.assigned_to
-    assert_equal "52.6", issue.custom_value_for(CustomField.find_by_name('Float field')).value
-    # keywords should be removed from the email body
-    assert !journal.notes.match(/^Status:/i)
-    assert !journal.notes.match(/^Start Date:/i)
-  end
-
-  def test_update_issue_with_attachment
-    assert_difference 'Journal.count' do
-      assert_difference 'JournalDetail.count' do
-        assert_difference 'Attachment.count' do
-          assert_no_difference 'Issue.count' do
-            journal = submit_email('ticket_with_attachment.eml') do |raw|
-              raw.gsub! /^Subject: .*$/, 'Subject: Re: [Cookbook - Feature #2] (New) Add ingredients categories'
-            end
-          end
-        end
-      end
-    end
-    journal = Journal.first(:order => 'id DESC')
-    assert_equal Issue.find(2), journal.journalized
-    assert_equal 1, journal.details.size
-
-    detail = journal.details.first
-    assert_equal 'attachment', detail.property
-    assert_equal 'Paella.jpg', detail.value
-  end
-
-  def test_update_issue_should_send_email_notification
-    ActionMailer::Base.deliveries.clear
-    journal = submit_email('ticket_reply.eml')
-    assert journal.is_a?(Journal)
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_update_issue_should_not_set_defaults
-    journal = submit_email('ticket_reply.eml', :issue => {:tracker => 'Support request', :priority => 'High'})
-    assert journal.is_a?(Journal)
-    assert_match /This is reply/, journal.notes
-    assert_equal 'Feature request', journal.issue.tracker.name
-    assert_equal 'Normal', journal.issue.priority.name
-  end
-
-  def test_reply_to_a_message
-    m = submit_email('message_reply.eml')
-    assert m.is_a?(Message)
-    assert !m.new_record?
-    m.reload
-    assert_equal 'Reply via email', m.subject
-    # The email replies to message #2 which is part of the thread of message #1
-    assert_equal Message.find(1), m.parent
-  end
-
-  def test_reply_to_a_message_by_subject
-    m = submit_email('message_reply_by_subject.eml')
-    assert m.is_a?(Message)
-    assert !m.new_record?
-    m.reload
-    assert_equal 'Reply to the first post', m.subject
-    assert_equal Message.find(1), m.parent
-  end
-
-  def test_should_strip_tags_of_html_only_emails
-    issue = submit_email('ticket_html_only.eml', :issue => {:project => 'ecookbook'})
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-    assert_equal 'HTML email', issue.subject
-    assert_equal 'This is a html-only email.', issue.description
-  end
-
-  context "truncate emails based on the Setting" do
-    context "with no setting" do
-      setup do
-        Setting.mail_handler_body_delimiters = ''
-      end
-
-      should "add the entire email into the issue" do
-        issue = submit_email('ticket_on_given_project.eml')
-        assert_issue_created(issue)
-        assert issue.description.include?('---')
-        assert issue.description.include?('This paragraph is after the delimiter')
-      end
-    end
-
-    context "with a single string" do
-      setup do
-        Setting.mail_handler_body_delimiters = '---'
-      end
-      should "truncate the email at the delimiter for the issue" do
-        issue = submit_email('ticket_on_given_project.eml')
-        assert_issue_created(issue)
-        assert issue.description.include?('This paragraph is before delimiters')
-        assert issue.description.include?('--- This line starts with a delimiter')
-        assert !issue.description.match(/^---$/)
-        assert !issue.description.include?('This paragraph is after the delimiter')
-      end
-    end
-
-    context "with a single quoted reply (e.g. reply to a Redmine email notification)" do
-      setup do
-        Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
-      end
-      should "truncate the email at the delimiter with the quoted reply symbols (>)" do
-        journal = submit_email('issue_update_with_quoted_reply_above.eml')
-        assert journal.is_a?(Journal)
-        assert journal.notes.include?('An update to the issue by the sender.')
-        assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
-        assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
-      end
-    end
-
-    context "with multiple quoted replies (e.g. reply to a reply of a Redmine email notification)" do
-      setup do
-        Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
-      end
-      should "truncate the email at the delimiter with the quoted reply symbols (>)" do
-        journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml')
-        assert journal.is_a?(Journal)
-        assert journal.notes.include?('An update to the issue by the sender.')
-        assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
-        assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
-      end
-    end
-
-    context "with multiple strings" do
-      setup do
-        Setting.mail_handler_body_delimiters = "---\nBREAK"
-      end
-      should "truncate the email at the first delimiter found (BREAK)" do
-        issue = submit_email('ticket_on_given_project.eml')
-        assert_issue_created(issue)
-        assert issue.description.include?('This paragraph is before delimiters')
-        assert !issue.description.include?('BREAK')
-        assert !issue.description.include?('This paragraph is between delimiters')
-        assert !issue.description.match(/^---$/)
-        assert !issue.description.include?('This paragraph is after the delimiter')
-      end
-    end
-  end
-
-  def test_email_with_long_subject_line
-    issue = submit_email('ticket_with_long_subject.eml')
-    assert issue.is_a?(Issue)
-    assert_equal issue.subject, 'New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...'[0,255]
-  end
-
-  def test_new_user_from_attributes_should_return_valid_user
-    to_test = {
-      # [address, name] => [login, firstname, lastname]
-      ['jsmith@example.net', nil] => ['jsmith@example.net', 'jsmith', '-'],
-      ['jsmith@example.net', 'John'] => ['jsmith@example.net', 'John', '-'],
-      ['jsmith@example.net', 'John Smith'] => ['jsmith@example.net', 'John', 'Smith'],
-      ['jsmith@example.net', 'John Paul Smith'] => ['jsmith@example.net', 'John', 'Paul Smith'],
-      ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsTheMaximumLength Smith'] => ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsT', 'Smith'],
-      ['jsmith@example.net', 'John AVeryLongLastnameThatExceedsTheMaximumLength'] => ['jsmith@example.net', 'John', 'AVeryLongLastnameThatExceedsTh'],
-      ['alongemailaddressthatexceedsloginlength@example.net', 'John Smith'] => ['alongemailaddressthatexceedslo', 'John', 'Smith']
-    }
-
-    to_test.each do |attrs, expected|
-      user = MailHandler.new_user_from_attributes(attrs.first, attrs.last)
-
-      assert user.valid?
-      assert_equal attrs.first, user.mail
-      assert_equal expected[0], user.login
-      assert_equal expected[1], user.firstname
-      assert_equal expected[2], user.lastname
-    end
-  end
-
-  def test_new_user_from_attributes_should_respect_minimum_password_length
-    with_settings :password_min_length => 15 do
-      user = MailHandler.new_user_from_attributes('jsmith@example.net')
-      assert user.valid?
-      assert user.password.length >= 15
-    end
-  end
- 
-  def test_new_user_from_attributes_should_use_default_login_if_invalid
-    MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-1@example.net').save!
-
-    # another long address that would result in duplicate login
-    user = MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-2@example.net')
-    assert user.valid?
-    assert user.login =~ /^user[a-f0-9]+$/
-  end
-
-  private
-
-  def submit_email(filename, options={})
-    raw = IO.read(File.join(FIXTURES_PATH, filename))
-    yield raw if block_given?
-    MailHandler.receive(raw, options)
-  end
-
-  def assert_issue_created(issue)
-    assert issue.is_a?(Issue)
-    assert !issue.new_record?
-    issue.reload
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9d/9d0bd051174c188e1084c470e35e435886bd6bff.svn-base
--- a/.svn/pristine/9d/9d0bd051174c188e1084c470e35e435886bd6bff.svn-base
+++ /dev/null
@@ -1,295 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'attachments_controller'
-
-# Re-raise errors caught by the controller.
-class AttachmentsController; def rescue_action(e) raise e end; end
-
-class AttachmentsControllerTest < ActionController::TestCase
-  fixtures :users, :projects, :roles, :members, :member_roles,
-           :enabled_modules, :issues, :trackers, :attachments,
-           :versions, :wiki_pages, :wikis, :documents
-
-  def setup
-    @controller = AttachmentsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
-    User.current = nil
-  end
-
-  def test_show_diff
-    ['inline', 'sbs'].each do |dt|
-      # 060719210727_changeset_utf8.diff
-      get :show, :id => 14, :type => dt
-      assert_response :success
-      assert_template 'diff'
-      assert_equal 'text/html', @response.content_type
-      assert_tag 'th',
-        :attributes => {:class => /filename/},
-        :content => /issues_controller.rb\t\(rÃ©vision 1484\)/
-      assert_tag 'td',
-        :attributes => {:class => /line-code/},
-        :content => /Demande crÃ©Ã©e avec succÃ¨s/
-    end
-    set_tmp_attachments_directory
-  end
-
-  def test_show_diff_replcace_cannot_convert_content
-    with_settings :repositories_encodings => 'UTF-8' do
-      ['inline', 'sbs'].each do |dt|
-        # 060719210727_changeset_iso8859-1.diff
-        get :show, :id => 5, :type => dt
-        assert_response :success
-        assert_template 'diff'
-        assert_equal 'text/html', @response.content_type
-        assert_tag 'th',
-          :attributes => {:class => "filename"},
-          :content => /issues_controller.rb\t\(r\?vision 1484\)/
-        assert_tag 'td',
-          :attributes => {:class => /line-code/},
-          :content => /Demande cr\?\?e avec succ\?s/
-      end
-    end
-    set_tmp_attachments_directory
-  end
-
-  def test_show_diff_latin_1
-    with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
-      ['inline', 'sbs'].each do |dt|
-        # 060719210727_changeset_iso8859-1.diff
-        get :show, :id => 5, :type => dt
-        assert_response :success
-        assert_template 'diff'
-        assert_equal 'text/html', @response.content_type
-        assert_tag 'th',
-          :attributes => {:class => "filename"},
-          :content => /issues_controller.rb\t\(rÃ©vision 1484\)/
-        assert_tag 'td',
-          :attributes => {:class => /line-code/},
-          :content => /Demande crÃ©Ã©e avec succÃ¨s/
-      end
-    end
-    set_tmp_attachments_directory
-  end
-
-  def test_save_diff_type
-    @request.session[:user_id] = 1 # admin
-    user = User.find(1)
-    get :show, :id => 5
-    assert_response :success
-    assert_template 'diff'
-    user.reload
-    assert_equal "inline", user.pref[:diff_type]
-    get :show, :id => 5, :type => 'sbs'
-    assert_response :success
-    assert_template 'diff'
-    user.reload
-    assert_equal "sbs", user.pref[:diff_type]
-  end
-
-  def test_show_text_file
-    get :show, :id => 4
-    assert_response :success
-    assert_template 'file'
-    assert_equal 'text/html', @response.content_type
-    set_tmp_attachments_directory
-  end
-
-  def test_show_text_file_utf_8
-    set_tmp_attachments_directory
-    a = Attachment.new(:container => Issue.find(1),
-                       :file => uploaded_test_file("japanese-utf-8.txt", "text/plain"),
-                       :author => User.find(1))
-    assert a.save
-    assert_equal 'japanese-utf-8.txt', a.filename
-
-    str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
-    str_japanese.force_encoding('UTF-8') if str_japanese.respond_to?(:force_encoding)
-
-    get :show, :id => a.id
-    assert_response :success
-    assert_template 'file'
-    assert_equal 'text/html', @response.content_type
-    assert_tag :tag => 'th',
-               :content => '1',
-               :attributes => { :class => 'line-num' },
-               :sibling => { :tag => 'td', :content => /#{str_japanese}/ }
-  end
-
-  def test_show_text_file_replcace_cannot_convert_content
-    set_tmp_attachments_directory
-    with_settings :repositories_encodings => 'UTF-8' do
-      a = Attachment.new(:container => Issue.find(1),
-                         :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
-                         :author => User.find(1))
-      assert a.save
-      assert_equal 'iso8859-1.txt', a.filename
-
-      get :show, :id => a.id
-      assert_response :success
-      assert_template 'file'
-      assert_equal 'text/html', @response.content_type
-      assert_tag :tag => 'th',
-                 :content => '7',
-                 :attributes => { :class => 'line-num' },
-                 :sibling => { :tag => 'td', :content => /Demande cr\?\?e avec succ\?s/ }
-    end
-  end
-
-  def test_show_text_file_latin_1
-    set_tmp_attachments_directory
-    with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
-      a = Attachment.new(:container => Issue.find(1),
-                         :file => uploaded_test_file("iso8859-1.txt", "text/plain"),
-                         :author => User.find(1))
-      assert a.save
-      assert_equal 'iso8859-1.txt', a.filename
-
-      get :show, :id => a.id
-      assert_response :success
-      assert_template 'file'
-      assert_equal 'text/html', @response.content_type
-      assert_tag :tag => 'th',
-                 :content => '7',
-                 :attributes => { :class => 'line-num' },
-                 :sibling => { :tag => 'td', :content => /Demande crÃ©Ã©e avec succÃ¨s/ }
-      end
-  end
-
-  def test_show_text_file_should_send_if_too_big
-    Setting.file_max_size_displayed = 512
-    Attachment.find(4).update_attribute :filesize, 754.kilobyte
-
-    get :show, :id => 4
-    assert_response :success
-    assert_equal 'application/x-ruby', @response.content_type
-    set_tmp_attachments_directory
-  end
-
-  def test_show_other
-    get :show, :id => 6
-    assert_response :success
-    assert_equal 'application/octet-stream', @response.content_type
-    set_tmp_attachments_directory
-  end
-
-  def test_show_file_from_private_issue_without_permission
-    get :show, :id => 15
-    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2F15'
-    set_tmp_attachments_directory
-  end
-
-  def test_show_file_from_private_issue_with_permission
-    @request.session[:user_id] = 2
-    get :show, :id => 15
-    assert_response :success
-    assert_tag 'h2', :content => /private.diff/
-    set_tmp_attachments_directory
-  end
-
-  def test_download_text_file
-    get :download, :id => 4
-    assert_response :success
-    assert_equal 'application/x-ruby', @response.content_type
-    set_tmp_attachments_directory
-  end
-
-  def test_download_version_file_with_issue_tracking_disabled
-    Project.find(1).disable_module! :issue_tracking
-    get :download, :id => 9
-    assert_response :success
-  end
-
-  def test_download_should_assign_content_type_if_blank
-    Attachment.find(4).update_attribute(:content_type, '')
-
-    get :download, :id => 4
-    assert_response :success
-    assert_equal 'text/x-ruby', @response.content_type
-    set_tmp_attachments_directory
-  end
-
-  def test_download_missing_file
-    get :download, :id => 2
-    assert_response 404
-    set_tmp_attachments_directory
-  end
-
-  def test_anonymous_on_private_private
-    get :download, :id => 7
-    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdownload%2F7'
-    set_tmp_attachments_directory
-  end
-
-  def test_destroy_issue_attachment
-    set_tmp_attachments_directory
-    issue = Issue.find(3)
-    @request.session[:user_id] = 2
-
-    assert_difference 'issue.attachments.count', -1 do
-      delete :destroy, :id => 1
-    end
-    # no referrer
-    assert_redirected_to '/projects/ecookbook'
-    assert_nil Attachment.find_by_id(1)
-    j = issue.journals.find(:first, :order => 'created_on DESC')
-    assert_equal 'attachment', j.details.first.property
-    assert_equal '1', j.details.first.prop_key
-    assert_equal 'error281.txt', j.details.first.old_value
-  end
-
-  def test_destroy_wiki_page_attachment
-    set_tmp_attachments_directory
-    @request.session[:user_id] = 2
-    assert_difference 'Attachment.count', -1 do
-      delete :destroy, :id => 3
-      assert_response 302
-    end
-  end
-
-  def test_destroy_project_attachment
-    set_tmp_attachments_directory
-    @request.session[:user_id] = 2
-    assert_difference 'Attachment.count', -1 do
-      delete :destroy, :id => 8
-      assert_response 302
-    end
-  end
-
-  def test_destroy_version_attachment
-    set_tmp_attachments_directory
-    @request.session[:user_id] = 2
-    assert_difference 'Attachment.count', -1 do
-      delete :destroy, :id => 9
-      assert_response 302
-    end
-  end
-
-  def test_destroy_without_permission
-    set_tmp_attachments_directory
-    assert_no_difference 'Attachment.count' do
-      delete :destroy, :id => 3
-    end
-    assert_response 302
-    assert Attachment.find_by_id(3)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9d/9d187222c850f9174b08bb5b8db4565b6a8d62a8.svn-base
--- a/.svn/pristine/9d/9d187222c850f9174b08bb5b8db4565b6a8d62a8.svn-base
+++ /dev/null
@@ -1,379 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'repositories_controller'
-
-# Re-raise errors caught by the controller.
-class RepositoriesController; def rescue_action(e) raise e end; end
-
-class RepositoriesSubversionControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
-           :repositories, :issues, :issue_statuses, :changesets, :changes,
-           :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
-
-  PRJ_ID = 3
-  NUM_REV = 11
-
-  def setup
-    @controller = RepositoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    Setting.default_language = 'en'
-    User.current = nil
-
-    @project = Project.find(PRJ_ID)
-    @repository = Repository::Subversion.create(:project => @project,
-               :url => self.class.subversion_repository_url)
-    assert @repository
-  end
-
-  if repository_configured?('subversion')
-    def test_show
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_not_nil assigns(:changesets)
-    end
-
-    def test_browse_root
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      entry = assigns(:entries).detect {|e| e.name == 'subversion_test'}
-      assert_equal 'dir', entry.kind
-    end
-
-    def test_browse_directory
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :path => ['subversion_test']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal [
-           '[folder_with_brackets]', 'folder', '.project',
-           'helloworld.c', 'textfile.txt'
-         ],
-        assigns(:entries).collect(&:name)
-      entry = assigns(:entries).detect {|e| e.name == 'helloworld.c'}
-      assert_equal 'file', entry.kind
-      assert_equal 'subversion_test/helloworld.c', entry.path
-      assert_tag :a, :content => 'helloworld.c', :attributes => { :class => /text\-x\-c/ }
-    end
-
-    def test_browse_at_given_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :path => ['subversion_test'], :rev => 4
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['folder', '.project', 'helloworld.c', 'helloworld.rb', 'textfile.txt'],
-                   assigns(:entries).collect(&:name)
-    end
-
-    def test_file_changes
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :changes, :id => PRJ_ID, :path => ['subversion_test', 'folder', 'helloworld.rb' ]
-      assert_response :success
-      assert_template 'changes'
-
-      changesets = assigns(:changesets)
-      assert_not_nil changesets
-      assert_equal %w(6 3 2), changesets.collect(&:revision)
-
-      # svn properties displayed with svn >= 1.5 only
-      if Redmine::Scm::Adapters::SubversionAdapter.client_version_above?([1, 5, 0])
-        assert_not_nil assigns(:properties)
-        assert_equal 'native', assigns(:properties)['svn:eol-style']
-        assert_tag :ul,
-                   :child => { :tag => 'li',
-                               :child => { :tag => 'b', :content => 'svn:eol-style' },
-                               :child => { :tag => 'span', :content => 'native' } }
-      end
-    end
-
-    def test_directory_changes
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :changes, :id => PRJ_ID, :path => ['subversion_test', 'folder' ]
-      assert_response :success
-      assert_template 'changes'
-
-      changesets = assigns(:changesets)
-      assert_not_nil changesets
-      assert_equal %w(10 9 7 6 5 2), changesets.collect(&:revision)
-    end
-
-    def test_entry
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['subversion_test', 'helloworld.c']
-      assert_response :success
-      assert_template 'entry'
-    end
-
-    def test_entry_should_send_if_too_big
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      # no files in the test repo is larger than 1KB...
-      with_settings :file_max_size_displayed => 0 do
-        get :entry, :id => PRJ_ID, :path => ['subversion_test', 'helloworld.c']
-        assert_response :success
-        assert_template ''
-        assert_equal 'attachment; filename="helloworld.c"',
-                     @response.headers['Content-Disposition']
-      end
-    end
-
-    def test_entry_at_given_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['subversion_test', 'helloworld.rb'], :rev => 2
-      assert_response :success
-      assert_template 'entry'
-      # this line was removed in r3 and file was moved in r6
-      assert_tag :tag => 'td', :attributes => { :class => /line-code/},
-                               :content => /Here's the code/
-    end
-
-    def test_entry_not_found
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['subversion_test', 'zzz.c']
-      assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ },
-                                :content => /The entry or revision was not found in the repository/
-    end
-
-    def test_entry_download
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['subversion_test', 'helloworld.c'], :format => 'raw'
-      assert_response :success
-      assert_template ''
-      assert_equal 'attachment; filename="helloworld.c"', @response.headers['Content-Disposition']
-    end
-
-    def test_directory_entry
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :entry, :id => PRJ_ID, :path => ['subversion_test', 'folder']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entry)
-      assert_equal 'folder', assigns(:entry).name
-    end
-
-    # TODO: this test needs fixtures.
-    def test_revision
-      get :revision, :id => 1, :rev => 2
-      assert_response :success
-      assert_template 'revision'
-      assert_tag :tag => 'ul',
-                 :child => { :tag => 'li',
-                             # link to the entry at rev 2
-                             :child => { :tag => 'a',
-                                         :attributes => {:href => '/projects/ecookbook/repository/revisions/2/entry/test/some/path/in/the/repo'},
-                                         :content => 'repo',
-                                         # link to partial diff
-                                         :sibling =>  { :tag => 'a',
-                                                        :attributes => { :href => '/projects/ecookbook/repository/revisions/2/diff/test/some/path/in/the/repo' }
-                                                       }
-                                        }
-                            }
-    end
-
-    def test_invalid_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :revision, :id => PRJ_ID, :rev => 'something_weird'
-      assert_response 404
-      assert_error_tag :content => /was not found/
-    end
-
-    def test_invalid_revision_diff
-      get :diff, :id => PRJ_ID, :rev => '1', :rev_to => 'something_weird'
-      assert_response 404
-      assert_error_tag :content => /was not found/
-    end
-
-    def test_empty_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['', ' ', nil].each do |r|
-        get :revision, :id => PRJ_ID, :rev => r
-        assert_response 404
-        assert_error_tag :content => /was not found/
-      end
-    end
-
-    # TODO: this test needs fixtures.
-    def test_revision_with_repository_pointing_to_a_subdirectory
-      r = Project.find(1).repository
-      # Changes repository url to a subdirectory
-      r.update_attribute :url, (r.url + '/test/some')
-
-      get :revision, :id => 1, :rev => 2
-      assert_response :success
-      assert_template 'revision'
-      assert_tag :tag => 'ul',
-                 :child => { :tag => 'li',
-                             # link to the entry at rev 2
-                             :child => { :tag => 'a',
-                                         :attributes => {:href => '/projects/ecookbook/repository/revisions/2/entry/path/in/the/repo'},
-                                         :content => 'repo',
-                                         # link to partial diff
-                                         :sibling =>  { :tag => 'a',
-                                                        :attributes => { :href => '/projects/ecookbook/repository/revisions/2/diff/path/in/the/repo' }
-                                                       }
-                                        }
-                            }
-    end
-
-    def test_revision_diff
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['inline', 'sbs'].each do |dt|
-        get :diff, :id => PRJ_ID, :rev => 3, :type => dt
-        assert_response :success
-        assert_template 'diff'
-        assert_tag :tag => 'h2',
-                   :content => / 3/
-      end
-    end
-
-    def test_directory_diff
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['inline', 'sbs'].each do |dt|
-        get :diff, :id => PRJ_ID, :rev => 6, :rev_to => 2,
-            :path => ['subversion_test', 'folder'], :type => dt
-        assert_response :success
-        assert_template 'diff'
-
-        diff = assigns(:diff)
-        assert_not_nil diff
-        # 2 files modified
-        assert_equal 2, Redmine::UnifiedDiff.new(diff).size
-        assert_tag :tag => 'h2', :content => /2:6/
-      end
-    end
-
-    def test_annotate
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :annotate, :id => PRJ_ID, :path => ['subversion_test', 'helloworld.c']
-      assert_response :success
-      assert_template 'annotate'
-    end
-
-    def test_annotate_at_given_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :annotate, :id => PRJ_ID, :rev => 8, :path => ['subversion_test', 'helloworld.c']
-      assert_response :success
-      assert_template 'annotate'
-      assert_tag :tag => 'h2', :content => /@ 8/
-    end
-
-    def test_destroy_valid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-
-    def test_destroy_invalid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-
-      @repository = Repository::Subversion.create(
-                       :project => @project,
-                       :url     => "file:///invalid")
-      assert @repository
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal 0, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-  else
-    puts "Subversion test repository NOT FOUND. Skipping functional tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9d/9d2c4df03fbe565f55ddf5ab2dee0edf7d1b9256.svn-base
--- a/.svn/pristine/9d/9d2c4df03fbe565f55ddf5ab2dee0edf7d1b9256.svn-base
+++ /dev/null
@@ -1,85 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class TimeEntryActivityTest < ActiveSupport::TestCase
-  fixtures :enumerations, :time_entries
-
-  def test_should_be_an_enumeration
-    assert TimeEntryActivity.ancestors.include?(Enumeration)
-  end
-
-  def test_objects_count
-    assert_equal 3, TimeEntryActivity.find_by_name("Design").objects_count
-    assert_equal 2, TimeEntryActivity.find_by_name("Development").objects_count
-  end
-
-  def test_option_name
-    assert_equal :enumeration_activities, TimeEntryActivity.new.option_name
-  end
-
-  def test_create_with_custom_field
-    field = TimeEntryActivityCustomField.find_by_name('Billable')
-    e = TimeEntryActivity.new(:name => 'Custom Data')
-    e.custom_field_values = {field.id => "1"}
-    assert e.save
-
-    e.reload
-    assert_equal "1", e.custom_value_for(field).value
-  end
-
-  def test_create_without_required_custom_field_should_fail
-    field = TimeEntryActivityCustomField.find_by_name('Billable')
-    field.update_attribute(:is_required, true)
-
-    e = TimeEntryActivity.new(:name => 'Custom Data')
-    assert !e.save
-    assert_equal I18n.translate('activerecord.errors.messages.invalid'), e.errors.on(:custom_values)
-  end
-
-  def test_create_with_required_custom_field_should_succeed
-    field = TimeEntryActivityCustomField.find_by_name('Billable')
-    field.update_attribute(:is_required, true)
-
-    e = TimeEntryActivity.new(:name => 'Custom Data')
-    e.custom_field_values = {field.id => "1"}
-    assert e.save
-  end
-
-  def test_update_issue_with_required_custom_field_change
-    field = TimeEntryActivityCustomField.find_by_name('Billable')
-    field.update_attribute(:is_required, true)
-
-    e = TimeEntryActivity.find(10)
-    assert e.available_custom_fields.include?(field)
-    # No change to custom field, record can be saved
-    assert e.save
-    # Blanking custom field, save should fail
-    e.custom_field_values = {field.id => ""}
-    assert !e.save
-    assert e.errors[:custom_values]
-
-    # Update custom field to valid value, save should succeed
-    e.custom_field_values = {field.id => "0"}
-    assert e.save
-    e.reload
-    assert_equal "0", e.custom_value_for(field).value
-  end
-
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9d/9d330d1b77b8a18674a908abae00bf4199e02763.svn-base
--- a/.svn/pristine/9d/9d330d1b77b8a18674a908abae00bf4199e02763.svn-base
+++ /dev/null
@@ -1,21 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module MessagesHelper
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9d/9d877c8347c80eb0a2dfdf19e1809ccce67984a2.svn-base
--- a/.svn/pristine/9d/9d877c8347c80eb0a2dfdf19e1809ccce67984a2.svn-base
+++ /dev/null
@@ -1,66 +0,0 @@
-<%= breadcrumb link_to(l(:label_board_plural), {:controller => 'boards', :action => 'index', :project_id => @project}),
-               link_to(h(@board.name), {:controller => 'boards', :action => 'show', :project_id => @project, :id => @board}) %>
-
-<div class="contextual">
-    <%= watcher_tag(@topic, User.current) %>
-    <%= link_to_remote_if_authorized(l(:button_quote), { :url => {:action => 'quote', :id => @topic} }, :class => 'icon icon-comment') unless @topic.locked? %>
-    <%= link_to(l(:button_edit), {:action => 'edit', :id => @topic}, :class => 'icon icon-edit') if @message.editable_by?(User.current) %>
-    <%= link_to(l(:button_delete), {:action => 'destroy', :id => @topic}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') if @message.destroyable_by?(User.current) %>
-</div>
-
-<h2><%= avatar(@topic.author, :size => "24") %><%=h @topic.subject %></h2>
-
-<div class="message">
-<p><span class="author"><%= authoring @topic.created_on, @topic.author %></span></p>
-<div class="wiki">
-<%= textilizable(@topic.content, :attachments => @topic.attachments) %>
-</div>
-<%= link_to_attachments @topic, :author => false %>
-</div>
-<br />
-
-<% unless @replies.empty? %>
-<h3 class="comments"><%= l(:label_reply_plural) %> (<%= @reply_count %>)</h3>
-<% @replies.each do |message| %>
-  <div class="message reply" id="<%= "message-#{message.id}" %>">
-    <div class="contextual">
-      <%= link_to_remote_if_authorized(image_tag('comment.png'), { :url => {:action => 'quote', :id => message} }, :title => l(:button_quote)) unless @topic.locked? %>
-      <%= link_to(image_tag('edit.png'), {:action => 'edit', :id => message}, :title => l(:button_edit)) if message.editable_by?(User.current) %>
-      <%= link_to(image_tag('delete.png'), {:action => 'destroy', :id => message}, :method => :post, :confirm => l(:text_are_you_sure), :title => l(:button_delete)) if message.destroyable_by?(User.current) %>
-    </div>
-  <h4>
-    <%= avatar(message.author, :size => "24") %>
-    <%= link_to h(message.subject), { :controller => 'messages', :action => 'show', :board_id => @board, :id => @topic, :r => message, :anchor => "message-#{message.id}" } %>
-    -
-    <%= authoring message.created_on, message.author %>
-  </h4>
-  <div class="wiki"><%= textilizable message, :content, :attachments => message.attachments %></div>
-  <%= link_to_attachments message, :author => false %>
-  </div>
-<% end %>
-<p class="pagination"><%= pagination_links_full @reply_pages, @reply_count, :per_page_links => false %></p>
-<% end %>
-
-<% if !@topic.locked? && authorize_for('messages', 'reply') %>
-<p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p>
-<div id="reply" style="display:none;">
-<% form_for :reply, @reply, :url => {:action => 'reply', :id => @topic}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
-  <%= render :partial => 'form', :locals => {:f => f, :replying => true} %>
-  <%= submit_tag l(:button_submit) %>
-  <%= link_to_remote l(:label_preview),
-                     { :url => { :controller => 'messages', :action => 'preview', :board_id => @board },
-                       :method => 'post',
-                       :update => 'preview',
-                       :with => "Form.serialize('message-form')",
-                       :complete => "Element.scrollTo('preview')"
-                     }, :accesskey => accesskey(:preview) %>
-<% end %>
-<div id="preview" class="wiki"></div>
-</div>
-<% end %>
-
-<% content_for :header_tags do %>
-  <%= stylesheet_link_tag 'scm' %>
-<% end %>
-
-<% html_title @topic.subject %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9d/9dc877e22163cfba0e0ecab2db123574b64de75c.svn-base
--- a/.svn/pristine/9d/9dc877e22163cfba0e0ecab2db123574b64de75c.svn-base
+++ /dev/null
@@ -1,222 +0,0 @@
-# redminehelper: Redmine helper extension for Mercurial
-#
-# Copyright 2010 Alessio Franceschelli (alefranz.net)
-# Copyright 2010-2011 Yuya Nishihara <yuya@tcha.org>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-"""helper commands for Redmine to reduce the number of hg calls
-
-To test this extension, please try::
-
-    $ hg --config extensions.redminehelper=redminehelper.py rhsummary
-
-I/O encoding:
-
-:file path: urlencoded, raw string
-:tag name: utf-8
-:branch name: utf-8
-:node: 12-digits (short) hex string
-
-Output example of rhsummary::
-
-    <?xml version="1.0"?>
-    <rhsummary>
-      <repository root="/foo/bar">
-        <tip revision="1234" node="abcdef0123..."/>
-        <tag revision="123" node="34567abc..." name="1.1.1"/>
-        <branch .../>
-        ...
-      </repository>
-    </rhsummary>
-
-Output example of rhmanifest::
-
-    <?xml version="1.0"?>
-    <rhmanifest>
-      <repository root="/foo/bar">
-        <manifest revision="1234" path="lib">
-          <file name="diff.rb" revision="123" node="34567abc..." time="12345"
-                 size="100"/>
-          ...
-          <dir name="redmine"/>
-          ...
-        </manifest>
-      </repository>
-    </rhmanifest>
-"""
-import re, time, cgi, urllib
-from mercurial import cmdutil, commands, node, error, hg
-
-_x = cgi.escape
-_u = lambda s: cgi.escape(urllib.quote(s))
-
-def _tip(ui, repo):
-    # see mercurial/commands.py:tip
-    def tiprev():
-        try:
-            return len(repo) - 1
-        except TypeError:  # Mercurial < 1.1
-            return repo.changelog.count() - 1
-    tipctx = repo.changectx(tiprev())
-    ui.write('<tip revision="%d" node="%s"/>\n'
-             % (tipctx.rev(), _x(node.short(tipctx.node()))))
-
-_SPECIAL_TAGS = ('tip',)
-
-def _tags(ui, repo):
-    # see mercurial/commands.py:tags
-    for t, n in reversed(repo.tagslist()):
-        if t in _SPECIAL_TAGS:
-            continue
-        try:
-            r = repo.changelog.rev(n)
-        except error.LookupError:
-            continue
-        ui.write('<tag revision="%d" node="%s" name="%s"/>\n'
-                 % (r, _x(node.short(n)), _x(t)))
-
-def _branches(ui, repo):
-    # see mercurial/commands.py:branches
-    def iterbranches():
-        for t, n in repo.branchtags().iteritems():
-            yield t, n, repo.changelog.rev(n)
-    def branchheads(branch):
-        try:
-            return repo.branchheads(branch, closed=False)
-        except TypeError:  # Mercurial < 1.2
-            return repo.branchheads(branch)
-    for t, n, r in sorted(iterbranches(), key=lambda e: e[2], reverse=True):
-        if repo.lookup(r) in branchheads(t):
-            ui.write('<branch revision="%d" node="%s" name="%s"/>\n'
-                     % (r, _x(node.short(n)), _x(t)))
-
-def _manifest(ui, repo, path, rev):
-    ctx = repo.changectx(rev)
-    ui.write('<manifest revision="%d" path="%s">\n'
-             % (ctx.rev(), _u(path)))
-
-    known = set()
-    pathprefix = (path.rstrip('/') + '/').lstrip('/')
-    for f, n in sorted(ctx.manifest().iteritems(), key=lambda e: e[0]):
-        if not f.startswith(pathprefix):
-            continue
-        name = re.sub(r'/.*', '/', f[len(pathprefix):])
-        if name in known:
-            continue
-        known.add(name)
-
-        if name.endswith('/'):
-            ui.write('<dir name="%s"/>\n'
-                     % _x(urllib.quote(name[:-1])))
-        else:
-            fctx = repo.filectx(f, fileid=n)
-            tm, tzoffset = fctx.date()
-            ui.write('<file name="%s" revision="%d" node="%s" '
-                     'time="%d" size="%d"/>\n'
-                     % (_u(name), fctx.rev(), _x(node.short(fctx.node())),
-                        tm, fctx.size(), ))
-
-    ui.write('</manifest>\n')
-
-def rhannotate(ui, repo, *pats, **opts):
-    rev = urllib.unquote_plus(opts.pop('rev', None))
-    opts['rev'] = rev
-    return commands.annotate(ui, repo, *map(urllib.unquote_plus, pats), **opts)
-
-def rhcat(ui, repo, file1, *pats, **opts):
-    rev = urllib.unquote_plus(opts.pop('rev', None))
-    opts['rev'] = rev
-    return commands.cat(ui, repo, urllib.unquote_plus(file1), *map(urllib.unquote_plus, pats), **opts)
-
-def rhdiff(ui, repo, *pats, **opts):
-    """diff repository (or selected files)"""
-    change = opts.pop('change', None)
-    if change:  # add -c option for Mercurial<1.1
-        base = repo.changectx(change).parents()[0].rev()
-        opts['rev'] = [str(base), change]
-    opts['nodates'] = True
-    return commands.diff(ui, repo, *map(urllib.unquote_plus, pats), **opts)
-
-def rhlog(ui, repo, *pats, **opts):
-    rev      = opts.pop('rev')
-    bra0     = opts.pop('branch')
-    from_rev = urllib.unquote_plus(opts.pop('from', None))
-    to_rev   = urllib.unquote_plus(opts.pop('to'  , None))
-    bra      = urllib.unquote_plus(opts.pop('rhbranch', None))
-    from_rev = from_rev.replace('"', '\\"')
-    to_rev   = to_rev.replace('"', '\\"')
-    if hg.util.version() >= '1.6':
-      opts['rev'] = ['"%s":"%s"' % (from_rev, to_rev)]
-    else:
-      opts['rev'] = ['%s:%s' % (from_rev, to_rev)]
-    opts['branch'] = [bra]
-    return commands.log(ui, repo, *map(urllib.unquote_plus, pats), **opts)
-
-def rhmanifest(ui, repo, path='', **opts):
-    """output the sub-manifest of the specified directory"""
-    ui.write('<?xml version="1.0"?>\n')
-    ui.write('<rhmanifest>\n')
-    ui.write('<repository root="%s">\n' % _u(repo.root))
-    try:
-        _manifest(ui, repo, urllib.unquote_plus(path), urllib.unquote_plus(opts.get('rev')))
-    finally:
-        ui.write('</repository>\n')
-        ui.write('</rhmanifest>\n')
-
-def rhsummary(ui, repo, **opts):
-    """output the summary of the repository"""
-    ui.write('<?xml version="1.0"?>\n')
-    ui.write('<rhsummary>\n')
-    ui.write('<repository root="%s">\n' % _u(repo.root))
-    try:
-        _tip(ui, repo)
-        _tags(ui, repo)
-        _branches(ui, repo)
-        # TODO: bookmarks in core (Mercurial>=1.8)
-    finally:
-        ui.write('</repository>\n')
-        ui.write('</rhsummary>\n')
-
-# This extension should be compatible with Mercurial 0.9.5.
-# Note that Mercurial 0.9.5 doesn't have extensions.wrapfunction().
-cmdtable = {
-    'rhannotate': (rhannotate,
-         [('r', 'rev', '', 'revision'),
-          ('u', 'user', None, 'list the author (long with -v)'),
-          ('n', 'number', None, 'list the revision number (default)'),
-          ('c', 'changeset', None, 'list the changeset'),
-         ],
-         'hg rhannotate [-r REV] [-u] [-n] [-c] FILE...'),
-    'rhcat': (rhcat,
-               [('r', 'rev', '', 'revision')],
-               'hg rhcat ([-r REV] ...) FILE...'),
-    'rhdiff': (rhdiff,
-               [('r', 'rev', [], 'revision'),
-                ('c', 'change', '', 'change made by revision')],
-               'hg rhdiff ([-c REV] | [-r REV] ...) [FILE]...'),
-    'rhlog': (rhlog,
-                   [
-                    ('r', 'rev', [], 'show the specified revision'),
-                    ('b', 'branch', [],
-                       'show changesets within the given named branch'),
-                    ('l', 'limit', '',
-                         'limit number of changes displayed'),
-                    ('d', 'date', '',
-                         'show revisions matching date spec'),
-                    ('u', 'user', [],
-                      'revisions committed by user'),
-                    ('', 'from', '',
-                      ''),
-                    ('', 'to', '',
-                      ''),
-                    ('', 'rhbranch', '',
-                      ''),
-                    ('', 'template', '',
-                       'display with template')],
-                   'hg rhlog [OPTION]... [FILE]'),
-    'rhmanifest': (rhmanifest,
-                   [('r', 'rev', '', 'show the specified revision')],
-                   'hg rhmanifest [-r REV] [PATH]'),
-    'rhsummary': (rhsummary, [], 'hg rhsummary'),
-}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9d/9dfdd30448c50440943e2323c996a4238da2a4ec.svn-base
--- a/.svn/pristine/9d/9dfdd30448c50440943e2323c996a4238da2a4ec.svn-base
+++ /dev/null
@@ -1,79 +0,0 @@
-<h2><%= @copy ? l(:button_copy) : l(:button_move) %></h2>
-
-<ul>
-<% @issues.each do |issue| -%>
-  <li><%= link_to_issue issue %></li>
-<% end -%>
-</ul>
-
-<% form_tag({:action => 'create'}, :id => 'move_form') do %>
-<%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join %>
-
-<div class="box tabular">
-<fieldset class="attributes">
-<legend><%= l(:label_change_properties) %></legend>
-
-<div class="splitcontentleft">
-<p><label for="new_project_id"><%=l(:field_project)%>:</label>
-<%= select_tag "new_project_id",
-               project_tree_options_for_select(@allowed_projects, :selected => @target_project),
-               :onchange => remote_function(:url => { :action => 'new' },
-                                            :method => :get,
-                                            :update => 'content',
-                                            :with => "Form.serialize('move_form')") %></p>
-
-<p><label for="new_tracker_id"><%=l(:field_tracker)%>:</label>
-<%= select_tag "new_tracker_id", "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@trackers, "id", "name") %></p>
-
-<p>
-  <label for='status_id'><%= l(:field_status) %></label>
-  <%= select_tag('status_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@available_statuses, :id, :name)) %>
-</p>
-
-<p>
-  <label for='priority_id'><%= l(:field_priority) %></label>
-  <%= select_tag('priority_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(IssuePriority.active, :id, :name)) %>
-</p>
-
-<p>
-  <label for='assigned_to_id'><%= l(:field_assigned_to) %></label>
-  <%= select_tag('assigned_to_id', content_tag('option', l(:label_no_change_option), :value => '') +
-                                   content_tag('option', l(:label_nobody), :value => 'none') +
-                                   principals_options_for_select(@target_project.assignable_users)) %>
-</p>
-</div>
-
-<div class="splitcontentright">
-<p>
-  <label for='start_date'><%= l(:field_start_date) %></label>
-  <%= text_field_tag 'start_date', '', :size => 10 %><%= calendar_for('start_date') %>
-</p>
-
-<p>
-  <label for='due_date'><%= l(:field_due_date) %></label>
-  <%= text_field_tag 'due_date', '', :size => 10 %><%= calendar_for('due_date') %>
-</p>
-</div>
-
-</fieldset>
-
-<fieldset><legend><%= l(:field_notes) %></legend>
-<%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %>
-<%= wikitoolbar_for 'notes' %>
-</fieldset>
-
-<%= call_hook(:view_issues_move_bottom, :issues => @issues, :target_project => @target_project, :copy => !!@copy) %>
-</div>
-
-<% if @copy %>
-  <%= hidden_field_tag("copy_options[copy]", "1") %>
-  <%= submit_tag l(:button_copy) %>
-  <%= submit_tag l(:button_copy_and_follow), :name => 'follow' %>
-<% else %>
-  <%= submit_tag l(:button_move) %>
-  <%= submit_tag l(:button_move_and_follow), :name => 'follow' %>
-<% end %>
-<% end %>
-<% content_for :header_tags do %>
-  <%= robot_exclusion_tag %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9e/9e492bc877f0e8064bb3d1d9a63c5fdec355074e.svn-base
--- a/.svn/pristine/9e/9e492bc877f0e8064bb3d1d9a63c5fdec355074e.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%=l(:label_issue_category_new)%></h2>
-
-<% labelled_tabular_form_for :issue_category, @category, :url => project_issue_categories_path(@project) do |f| %>
-<%= render :partial => 'issue_categories/form', :locals => { :f => f } %>
-<%= submit_tag l(:button_create) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9e/9e8144e3e4fb00d017fa913ce7482336770ceb85.svn-base
--- /dev/null
+++ b/.svn/pristine/9e/9e8144e3e4fb00d017fa913ce7482336770ceb85.svn-base
@@ -0,0 +1,111 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class BoardsController < ApplicationController
+  default_search_scope :messages
+  before_filter :find_project_by_project_id, :find_board_if_available, :authorize
+  accept_rss_auth :index, :show
+
+  helper :sort
+  include SortHelper
+  helper :watchers
+
+  def index
+    @boards = @project.boards.includes(:last_message => :author).all
+    # show the board if there is only one
+    if @boards.size == 1
+      @board = @boards.first
+      show
+    end
+  end
+
+  def show
+    respond_to do |format|
+      format.html {
+        sort_init 'updated_on', 'desc'
+        sort_update 'created_on' => "#{Message.table_name}.created_on",
+                    'replies' => "#{Message.table_name}.replies_count",
+                    'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)"
+
+        @topic_count = @board.topics.count
+        @topic_pages = Paginator.new @topic_count, per_page_option, params['page']
+        @topics =  @board.topics.
+          reorder("#{Message.table_name}.sticky DESC").
+          includes(:last_reply).
+          limit(@topic_pages.per_page).
+          offset(@topic_pages.offset).
+          order(sort_clause).
+          preload(:author, {:last_reply => :author}).
+          all
+        @message = Message.new(:board => @board)
+        render :action => 'show', :layout => !request.xhr?
+      }
+      format.atom {
+        @messages = @board.messages.
+          reorder('created_on DESC').
+          includes(:author, :board).
+          limit(Setting.feeds_limit.to_i).
+          all
+        render_feed(@messages, :title => "#{@project}: #{@board}")
+      }
+    end
+  end
+
+  def new
+    @board = @project.boards.build
+    @board.safe_attributes = params[:board]
+  end
+
+  def create
+    @board = @project.boards.build
+    @board.safe_attributes = params[:board]
+    if @board.save
+      flash[:notice] = l(:notice_successful_create)
+      redirect_to_settings_in_projects
+    else
+      render :action => 'new'
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    @board.safe_attributes = params[:board]
+    if @board.save
+      redirect_to_settings_in_projects
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def destroy
+    @board.destroy
+    redirect_to_settings_in_projects
+  end
+
+private
+  def redirect_to_settings_in_projects
+    redirect_to settings_project_path(@project, :tab => 'boards')
+  end
+
+  def find_board_if_available
+    @board = @project.boards.find(params[:id]) if params[:id]
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9e/9ef9d001fab3e27db69ad84d6d28e74243cc2720.svn-base
--- a/.svn/pristine/9e/9ef9d001fab3e27db69ad84d6d28e74243cc2720.svn-base
+++ /dev/null
@@ -1,46 +0,0 @@
-<div class="contextual">
-<%= link_to(l(:label_attachment_new), new_project_file_path(@project), :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %>
-</div>
-
-<h2><%=l(:label_attachment_plural)%></h2>
-
-<% delete_allowed = User.current.allowed_to?(:manage_files, @project) %>
-
-<table class="list files">
-  <thead><tr>
-    <%= sort_header_tag('filename', :caption => l(:field_filename)) %>
-    <%= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc') %>
-    <%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc') %>
-    <%= sort_header_tag('downloads', :caption => l(:label_downloads_abbr), :default_order => 'desc') %>
-    <th>MD5</th>
-    <th></th>
-  </tr></thead>
-  <tbody>
-<% @containers.each do |container| %>
-  <% next if container.attachments.empty? -%>
-  <% if container.is_a?(Version) -%>
-  <tr>
-    <th colspan="6" align="left">
-      <%= link_to(h(container), {:controller => 'versions', :action => 'show', :id => container}, :class => "icon icon-package") %>
-    </th>
-  </tr>
-  <% end -%>
-  <% container.attachments.each do |file| %>
-  <tr class="file <%= cycle("odd", "even") %>">
-    <td class="filename"><%= link_to_attachment file, :download => true, :title => file.description %></td>
-    <td class="created_on"><%= format_time(file.created_on) %></td>
-    <td class="filesize"><%= number_to_human_size(file.filesize) %></td>
-    <td class="downloads"><%= file.downloads %></td>
-    <td class="digest"><%= file.digest %></td>
-    <td align="center">
-    <%= link_to(image_tag('delete.png'), attachment_path(file),
-                                         :confirm => l(:text_are_you_sure), :method => :delete) if delete_allowed %>
-    </td>
-  </tr>
-  <% end
-  reset_cycle %>
-<% end %>
-  </tbody>
-</table>
-
-<% html_title(l(:label_attachment_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9f/9f106590ed8f3dcdf19bc14492bdda86842723cc.svn-base
--- a/.svn/pristine/9f/9f106590ed8f3dcdf19bc14492bdda86842723cc.svn-base
+++ /dev/null
@@ -1,32 +0,0 @@
-= Net::LDAP for Ruby
-Net::LDAP is an LDAP support library written in pure Ruby. It supports all
-LDAP client features, and a subset of server features as well.
-
-Homepage::  http://rubyforge.org/projects/net-ldap/
-Copyright:: (C) 2006 by Francis Cianfrocca
-
-Original developer: Francis Cianfrocca
-Contributions by Austin Ziegler gratefully acknowledged.
-
-== LICENCE NOTES
-Please read the file LICENCE for licensing restrictions on this library. In
-the simplest terms, this library is available under the same terms as Ruby
-itself.
-
-== Requirements
-Net::LDAP requires Ruby 1.8.2 or better.
-
-== Documentation
-See Net::LDAP for documentation and usage samples.
-
-#--
-# Net::LDAP for Ruby.
-#   http://rubyforge.org/projects/net-ldap/
-#   Copyright (C) 2006 by Francis Cianfrocca
-#
-#   Available under the same terms as Ruby. See LICENCE in the main
-#   distribution for full licensing information.
-#
-# $Id: README 141 2006-07-12 10:37:37Z blackhedd $
-#++
-# vim: sts=2 sw=2 ts=4 et ai tw=77
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9f/9f357f2c7eb1d40e687170aa6fbdfe3424f380b0.svn-base
--- a/.svn/pristine/9f/9f357f2c7eb1d40e687170aa6fbdfe3424f380b0.svn-base
+++ /dev/null
@@ -1,14 +0,0 @@
-<h2><%=l(:label_news_new)%></h2>
-
-<% labelled_tabular_form_for @news, :url => project_news_index_path(@project),
-                                           :html => { :id => 'news-form' } do |f| %>
-	<%= render :partial => 'news/form', :locals => { :f => f } %>
-	<%= submit_tag l(:button_create) %>
-	<%= link_to_remote l(:label_preview),
-	                   { :url => preview_news_path(:project_id => @project),
-	                     :method => 'get',
-	                     :update => 'preview',
-	                     :with => "Form.serialize('news-form')"
-	                   }, :accesskey => accesskey(:preview) %>
-<% end %>
-<div id="preview" class="wiki"></div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9f/9f44559d5cb4835c8cd9811f25c24d3967bf7369.svn-base
--- a/.svn/pristine/9f/9f44559d5cb4835c8cd9811f25c24d3967bf7369.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Change < ActiveRecord::Base
-  belongs_to :changeset
-
-  validates_presence_of :changeset_id, :action, :path
-  before_save :init_path
-  before_validation :replace_invalid_utf8_of_path
-
-  def relative_path
-    changeset.repository.relative_path(path)
-  end
-
-  def replace_invalid_utf8_of_path
-    self.path      = Redmine::CodesetUtil.replace_invalid_utf8(self.path)
-    self.from_path = Redmine::CodesetUtil.replace_invalid_utf8(self.from_path)
-  end
-
-  def init_path
-    self.path ||= ""
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9f/9f598a80182c833aaaa4c4d79b0ff6c92372cd6b.svn-base
--- a/.svn/pristine/9f/9f598a80182c833aaaa4c4d79b0ff6c92372cd6b.svn-base
+++ /dev/null
@@ -1,77 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class CustomFieldUserFormatTest < ActiveSupport::TestCase
-  fixtures :custom_fields, :projects, :members, :users, :member_roles, :trackers, :issues
-
-  def setup
-    @field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user')
-  end
-
-  def test_possible_values_with_no_arguments
-    assert_equal [], @field.possible_values
-    assert_equal [], @field.possible_values(nil)
-  end
-
-  def test_possible_values_with_project_resource
-    project = Project.find(1)
-    possible_values = @field.possible_values(project.issues.first)
-    assert possible_values.any?
-    assert_equal project.users.sort.collect(&:id).map(&:to_s), possible_values
-  end
-
-  def test_possible_values_with_nil_project_resource
-    project = Project.find(1)
-    assert_equal [], @field.possible_values(Issue.new)
-  end
-
-  def test_possible_values_options_with_no_arguments
-    assert_equal [], @field.possible_values_options
-    assert_equal [], @field.possible_values_options(nil)
-  end
-
-  def test_possible_values_options_with_project_resource
-    project = Project.find(1)
-    possible_values_options = @field.possible_values_options(project.issues.first)
-    assert possible_values_options.any?
-    assert_equal project.users.sort.map {|u| [u.name, u.id.to_s]}, possible_values_options
-  end
-
-  def test_possible_values_options_with_array
-    projects = Project.find([1, 2])
-    possible_values_options = @field.possible_values_options(projects)
-    assert possible_values_options.any?
-    assert_equal (projects.first.users & projects.last.users).sort.map {|u| [u.name, u.id.to_s]}, possible_values_options
-  end
-
-  def test_cast_blank_value
-    assert_equal nil, @field.cast_value(nil)
-    assert_equal nil, @field.cast_value("")
-  end
-
-  def test_cast_valid_value
-    user = @field.cast_value("2")
-    assert_kind_of User, user
-    assert_equal User.find(2), user
-  end
-
-  def test_cast_invalid_value
-    assert_equal nil, @field.cast_value("187")
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9f/9f81d7ae18ecd7486949ec6aa773ac587ff1d491.svn-base
--- /dev/null
+++ b/.svn/pristine/9f/9f81d7ae18ecd7486949ec6aa773ac587ff1d491.svn-base
@@ -0,0 +1,607 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'uri'
+require 'cgi'
+
+class Unauthorized < Exception; end
+
+class ApplicationController < ActionController::Base
+  include Redmine::I18n
+  include Redmine::Pagination
+  include RoutesHelper
+  helper :routes
+
+  class_attribute :accept_api_auth_actions
+  class_attribute :accept_rss_auth_actions
+  class_attribute :model_object
+
+  layout 'base'
+
+  protect_from_forgery
+  def handle_unverified_request
+    super
+    cookies.delete(autologin_cookie_name)
+  end
+
+  before_filter :session_expiration, :user_setup, :check_if_login_required, :set_localization
+
+  rescue_from ActionController::InvalidAuthenticityToken, :with => :invalid_authenticity_token
+  rescue_from ::Unauthorized, :with => :deny_access
+  rescue_from ::ActionView::MissingTemplate, :with => :missing_template
+
+  include Redmine::Search::Controller
+  include Redmine::MenuManager::MenuController
+  helper Redmine::MenuManager::MenuHelper
+
+  def session_expiration
+    if session[:user_id]
+      if session_expired? && !try_to_autologin
+        reset_session
+        flash[:error] = l(:error_session_expired)
+        redirect_to signin_url
+      else
+        session[:atime] = Time.now.utc.to_i
+      end
+    end
+  end
+
+  def session_expired?
+    if Setting.session_lifetime?
+      unless session[:ctime] && (Time.now.utc.to_i - session[:ctime].to_i <= Setting.session_lifetime.to_i * 60)
+        return true
+      end
+    end
+    if Setting.session_timeout?
+      unless session[:atime] && (Time.now.utc.to_i - session[:atime].to_i <= Setting.session_timeout.to_i * 60)
+        return true
+      end
+    end
+    false
+  end
+
+  def start_user_session(user)
+    session[:user_id] = user.id
+    session[:ctime] = Time.now.utc.to_i
+    session[:atime] = Time.now.utc.to_i
+  end
+
+  def user_setup
+    # Check the settings cache for each request
+    Setting.check_cache
+    # Find the current user
+    User.current = find_current_user
+    logger.info("  Current user: " + (User.current.logged? ? "#{User.current.login} (id=#{User.current.id})" : "anonymous")) if logger
+  end
+
+  # Returns the current user or nil if no user is logged in
+  # and starts a session if needed
+  def find_current_user
+    user = nil
+    unless api_request?
+      if session[:user_id]
+        # existing session
+        user = (User.active.find(session[:user_id]) rescue nil)
+      elsif autologin_user = try_to_autologin
+        user = autologin_user
+      elsif params[:format] == 'atom' && params[:key] && request.get? && accept_rss_auth?
+        # RSS key authentication does not start a session
+        user = User.find_by_rss_key(params[:key])
+      end
+    end
+    if user.nil? && Setting.rest_api_enabled? && accept_api_auth?
+      if (key = api_key_from_request)
+        # Use API key
+        user = User.find_by_api_key(key)
+      else
+        # HTTP Basic, either username/password or API key/random
+        authenticate_with_http_basic do |username, password|
+          user = User.try_to_login(username, password) || User.find_by_api_key(username)
+        end
+      end
+      # Switch user if requested by an admin user
+      if user && user.admin? && (username = api_switch_user_from_request)
+        su = User.find_by_login(username)
+        if su && su.active?
+          logger.info("  User switched by: #{user.login} (id=#{user.id})") if logger
+          user = su
+        else
+          render_error :message => 'Invalid X-Redmine-Switch-User header', :status => 412
+        end
+      end
+    end
+    user
+  end
+
+  def autologin_cookie_name
+    Redmine::Configuration['autologin_cookie_name'].presence || 'autologin'
+  end
+
+  def try_to_autologin
+    if cookies[autologin_cookie_name] && Setting.autologin?
+      # auto-login feature starts a new session
+      user = User.try_to_autologin(cookies[autologin_cookie_name])
+      if user
+        reset_session
+        start_user_session(user)
+      end
+      user
+    end
+  end
+
+  # Sets the logged in user
+  def logged_user=(user)
+    reset_session
+    if user && user.is_a?(User)
+      User.current = user
+      start_user_session(user)
+    else
+      User.current = User.anonymous
+    end
+  end
+
+  # Logs out current user
+  def logout_user
+    if User.current.logged?
+      cookies.delete(autologin_cookie_name)
+      Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
+      self.logged_user = nil
+    end
+  end
+
+  # check if login is globally required to access the application
+  def check_if_login_required
+    # no check needed if user is already logged in
+    return true if User.current.logged?
+    require_login if Setting.login_required?
+  end
+
+  def set_localization
+    lang = nil
+    if User.current.logged?
+      lang = find_language(User.current.language)
+    end
+    if lang.nil? && request.env['HTTP_ACCEPT_LANGUAGE']
+      accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first
+      if !accept_lang.blank?
+        accept_lang = accept_lang.downcase
+        lang = find_language(accept_lang) || find_language(accept_lang.split('-').first)
+      end
+    end
+    lang ||= Setting.default_language
+    set_language_if_valid(lang)
+  end
+
+  def require_login
+    if !User.current.logged?
+      # Extract only the basic url parameters on non-GET requests
+      if request.get?
+        url = url_for(params)
+      else
+        url = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id], :project_id => params[:project_id])
+      end
+      respond_to do |format|
+        format.html { redirect_to :controller => "account", :action => "login", :back_url => url }
+        format.atom { redirect_to :controller => "account", :action => "login", :back_url => url }
+        format.xml  { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
+        format.js   { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
+        format.json { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
+      end
+      return false
+    end
+    true
+  end
+
+  def require_admin
+    return unless require_login
+    if !User.current.admin?
+      render_403
+      return false
+    end
+    true
+  end
+
+  def deny_access
+    User.current.logged? ? render_403 : require_login
+  end
+
+  # Authorize the user for the requested action
+  def authorize(ctrl = params[:controller], action = params[:action], global = false)
+    allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project || @projects, :global => global)
+    if allowed
+      true
+    else
+      if @project && @project.archived?
+        render_403 :message => :notice_not_authorized_archived_project
+      else
+        deny_access
+      end
+    end
+  end
+
+  # Authorize the user for the requested action outside a project
+  def authorize_global(ctrl = params[:controller], action = params[:action], global = true)
+    authorize(ctrl, action, global)
+  end
+
+  # Find project of id params[:id]
+  def find_project
+    @project = Project.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  # Find project of id params[:project_id]
+  def find_project_by_project_id
+    @project = Project.find(params[:project_id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  # Find a project based on params[:project_id]
+  # TODO: some subclasses override this, see about merging their logic
+  def find_optional_project
+    @project = Project.find(params[:project_id]) unless params[:project_id].blank?
+    allowed = User.current.allowed_to?({:controller => params[:controller], :action => params[:action]}, @project, :global => true)
+    allowed ? true : deny_access
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  # Finds and sets @project based on @object.project
+  def find_project_from_association
+    render_404 unless @object.present?
+
+    @project = @object.project
+  end
+
+  def find_model_object
+    model = self.class.model_object
+    if model
+      @object = model.find(params[:id])
+      self.instance_variable_set('@' + controller_name.singularize, @object) if @object
+    end
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def self.model_object(model)
+    self.model_object = model
+  end
+
+  # Find the issue whose id is the :id parameter
+  # Raises a Unauthorized exception if the issue is not visible
+  def find_issue
+    # Issue.visible.find(...) can not be used to redirect user to the login form
+    # if the issue actually exists but requires authentication
+    @issue = Issue.find(params[:id])
+    raise Unauthorized unless @issue.visible?
+    @project = @issue.project
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  # Find issues with a single :id param or :ids array param
+  # Raises a Unauthorized exception if one of the issues is not visible
+  def find_issues
+    @issues = Issue.find_all_by_id(params[:id] || params[:ids])
+    raise ActiveRecord::RecordNotFound if @issues.empty?
+    raise Unauthorized unless @issues.all?(&:visible?)
+    @projects = @issues.collect(&:project).compact.uniq
+    @project = @projects.first if @projects.size == 1
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def find_attachments
+    if (attachments = params[:attachments]).present?
+      att = attachments.values.collect do |attachment|
+        Attachment.find_by_token( attachment[:token] ) if attachment[:token].present?
+      end
+      att.compact!
+    end
+    @attachments = att || []
+  end
+
+  # make sure that the user is a member of the project (or admin) if project is private
+  # used as a before_filter for actions that do not require any particular permission on the project
+  def check_project_privacy
+    if @project && !@project.archived?
+      if @project.visible?
+        true
+      else
+        deny_access
+      end
+    else
+      @project = nil
+      render_404
+      false
+    end
+  end
+
+  def back_url
+    url = params[:back_url]
+    if url.nil? && referer = request.env['HTTP_REFERER']
+      url = CGI.unescape(referer.to_s)
+    end
+    url
+  end
+
+  def redirect_back_or_default(default)
+    back_url = params[:back_url].to_s
+    if back_url.present?
+      begin
+        uri = URI.parse(back_url)
+        # do not redirect user to another host or to the login or register page
+        if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
+          redirect_to(back_url)
+          return
+        end
+      rescue URI::InvalidURIError
+        logger.warn("Could not redirect to invalid URL #{back_url}")
+        # redirect to default
+      end
+    end
+    redirect_to default
+    false
+  end
+
+  # Redirects to the request referer if present, redirects to args or call block otherwise.
+  def redirect_to_referer_or(*args, &block)
+    redirect_to :back
+  rescue ::ActionController::RedirectBackError
+    if args.any?
+      redirect_to *args
+    elsif block_given?
+      block.call
+    else
+      raise "#redirect_to_referer_or takes arguments or a block"
+    end
+  end
+
+  def render_403(options={})
+    @project = nil
+    render_error({:message => :notice_not_authorized, :status => 403}.merge(options))
+    return false
+  end
+
+  def render_404(options={})
+    render_error({:message => :notice_file_not_found, :status => 404}.merge(options))
+    return false
+  end
+
+  # Renders an error response
+  def render_error(arg)
+    arg = {:message => arg} unless arg.is_a?(Hash)
+
+    @message = arg[:message]
+    @message = l(@message) if @message.is_a?(Symbol)
+    @status = arg[:status] || 500
+
+    respond_to do |format|
+      format.html {
+        render :template => 'common/error', :layout => use_layout, :status => @status
+      }
+      format.any { head @status }
+    end
+  end
+
+  # Handler for ActionView::MissingTemplate exception
+  def missing_template
+    logger.warn "Missing template, responding with 404"
+    @project = nil
+    render_404
+  end
+
+  # Filter for actions that provide an API response
+  # but have no HTML representation for non admin users
+  def require_admin_or_api_request
+    return true if api_request?
+    if User.current.admin?
+      true
+    elsif User.current.logged?
+      render_error(:status => 406)
+    else
+      deny_access
+    end
+  end
+
+  # Picks which layout to use based on the request
+  #
+  # @return [boolean, string] name of the layout to use or false for no layout
+  def use_layout
+    request.xhr? ? false : 'base'
+  end
+
+  def invalid_authenticity_token
+    if api_request?
+      logger.error "Form authenticity token is missing or is invalid. API calls must include a proper Content-type header (text/xml or text/json)."
+    end
+    render_error "Invalid form authenticity token."
+  end
+
+  def render_feed(items, options={})
+    @items = items || []
+    @items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
+    @items = @items.slice(0, Setting.feeds_limit.to_i)
+    @title = options[:title] || Setting.app_title
+    render :template => "common/feed", :formats => [:atom], :layout => false,
+           :content_type => 'application/atom+xml'
+  end
+
+  def self.accept_rss_auth(*actions)
+    if actions.any?
+      self.accept_rss_auth_actions = actions
+    else
+      self.accept_rss_auth_actions || []
+    end
+  end
+
+  def accept_rss_auth?(action=action_name)
+    self.class.accept_rss_auth.include?(action.to_sym)
+  end
+
+  def self.accept_api_auth(*actions)
+    if actions.any?
+      self.accept_api_auth_actions = actions
+    else
+      self.accept_api_auth_actions || []
+    end
+  end
+
+  def accept_api_auth?(action=action_name)
+    self.class.accept_api_auth.include?(action.to_sym)
+  end
+
+  # Returns the number of objects that should be displayed
+  # on the paginated list
+  def per_page_option
+    per_page = nil
+    if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
+      per_page = params[:per_page].to_s.to_i
+      session[:per_page] = per_page
+    elsif session[:per_page]
+      per_page = session[:per_page]
+    else
+      per_page = Setting.per_page_options_array.first || 25
+    end
+    per_page
+  end
+
+  # Returns offset and limit used to retrieve objects
+  # for an API response based on offset, limit and page parameters
+  def api_offset_and_limit(options=params)
+    if options[:offset].present?
+      offset = options[:offset].to_i
+      if offset < 0
+        offset = 0
+      end
+    end
+    limit = options[:limit].to_i
+    if limit < 1
+      limit = 25
+    elsif limit > 100
+      limit = 100
+    end
+    if offset.nil? && options[:page].present?
+      offset = (options[:page].to_i - 1) * limit
+      offset = 0 if offset < 0
+    end
+    offset ||= 0
+
+    [offset, limit]
+  end
+
+  # qvalues http header parser
+  # code taken from webrick
+  def parse_qvalues(value)
+    tmp = []
+    if value
+      parts = value.split(/,\s*/)
+      parts.each {|part|
+        if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
+          val = m[1]
+          q = (m[2] or 1).to_f
+          tmp.push([val, q])
+        end
+      }
+      tmp = tmp.sort_by{|val, q| -q}
+      tmp.collect!{|val, q| val}
+    end
+    return tmp
+  rescue
+    nil
+  end
+
+  # Returns a string that can be used as filename value in Content-Disposition header
+  def filename_for_content_disposition(name)
+    request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
+  end
+
+  def api_request?
+    %w(xml json).include? params[:format]
+  end
+
+  # Returns the API key present in the request
+  def api_key_from_request
+    if params[:key].present?
+      params[:key].to_s
+    elsif request.headers["X-Redmine-API-Key"].present?
+      request.headers["X-Redmine-API-Key"].to_s
+    end
+  end
+
+  # Returns the API 'switch user' value if present
+  def api_switch_user_from_request
+    request.headers["X-Redmine-Switch-User"].to_s.presence
+  end
+
+  # Renders a warning flash if obj has unsaved attachments
+  def render_attachment_warning_if_needed(obj)
+    flash[:warning] = l(:warning_attachments_not_saved, obj.unsaved_attachments.size) if obj.unsaved_attachments.present?
+  end
+
+  # Sets the `flash` notice or error based the number of issues that did not save
+  #
+  # @param [Array, Issue] issues all of the saved and unsaved Issues
+  # @param [Array, Integer] unsaved_issue_ids the issue ids that were not saved
+  def set_flash_from_bulk_issue_save(issues, unsaved_issue_ids)
+    if unsaved_issue_ids.empty?
+      flash[:notice] = l(:notice_successful_update) unless issues.empty?
+    else
+      flash[:error] = l(:notice_failed_to_save_issues,
+                        :count => unsaved_issue_ids.size,
+                        :total => issues.size,
+                        :ids => '#' + unsaved_issue_ids.join(', #'))
+    end
+  end
+
+  # Rescues an invalid query statement. Just in case...
+  def query_statement_invalid(exception)
+    logger.error "Query::StatementInvalid: #{exception.message}" if logger
+    session.delete(:query)
+    sort_clear if respond_to?(:sort_clear)
+    render_error "An error occurred while executing the query and has been logged. Please report this error to your Redmine administrator."
+  end
+
+  # Renders a 200 response for successfull updates or deletions via the API
+  def render_api_ok
+    render_api_head :ok
+  end
+
+  # Renders a head API response
+  def render_api_head(status)
+    # #head would return a response body with one space
+    render :text => '', :status => status, :layout => nil
+  end
+
+  # Renders API response on validation failure
+  def render_validation_errors(objects)
+    if objects.is_a?(Array)
+      @error_messages = objects.map {|object| object.errors.full_messages}.flatten
+    else
+      @error_messages = objects.errors.full_messages
+    end
+    render :template => 'common/error_messages.api', :status => :unprocessable_entity, :layout => nil
+  end
+
+  # Overrides #_include_layout? so that #render with no arguments
+  # doesn't use the layout for api requests
+  def _include_layout?(*args)
+    api_request? ? false : super
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9f/9fbac0459fe6cdaf55fb0e58852e9a45b0b0309f.svn-base
--- a/.svn/pristine/9f/9fbac0459fe6cdaf55fb0e58852e9a45b0b0309f.svn-base
+++ /dev/null
@@ -1,100 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Workflow < ActiveRecord::Base
-  belongs_to :role
-  belongs_to :old_status, :class_name => 'IssueStatus', :foreign_key => 'old_status_id'
-  belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
-
-  validates_presence_of :role, :old_status, :new_status
-
-  # Returns workflow transitions count by tracker and role
-  def self.count_by_tracker_and_role
-    counts = connection.select_all("SELECT role_id, tracker_id, count(id) AS c FROM #{Workflow.table_name} GROUP BY role_id, tracker_id")
-    roles = Role.find(:all, :order => 'builtin, position')
-    trackers = Tracker.find(:all, :order => 'position')
-
-    result = []
-    trackers.each do |tracker|
-      t = []
-      roles.each do |role|
-        row = counts.detect {|c| c['role_id'].to_s == role.id.to_s && c['tracker_id'].to_s == tracker.id.to_s}
-        t << [role, (row.nil? ? 0 : row['c'].to_i)]
-      end
-      result << [tracker, t]
-    end
-
-    result
-  end
-
-  # Find potential statuses the user could be allowed to switch issues to
-  def self.available_statuses(project, user=User.current)
-    Workflow.find(:all,
-                  :include => :new_status,
-                  :conditions => {:role_id => user.roles_for_project(project).collect(&:id)}).
-      collect(&:new_status).
-      compact.
-      uniq.
-      sort
-  end
-
-  # Copies workflows from source to targets
-  def self.copy(source_tracker, source_role, target_trackers, target_roles)
-    unless source_tracker.is_a?(Tracker) || source_role.is_a?(Role)
-      raise ArgumentError.new("source_tracker or source_role must be specified")
-    end
-
-    target_trackers = [target_trackers].flatten.compact
-    target_roles = [target_roles].flatten.compact
-
-    target_trackers = Tracker.all if target_trackers.empty?
-    target_roles = Role.all if target_roles.empty?
-
-    target_trackers.each do |target_tracker|
-      target_roles.each do |target_role|
-        copy_one(source_tracker || target_tracker,
-                   source_role || target_role,
-                   target_tracker,
-                   target_role)
-      end
-    end
-  end
-
-  # Copies a single set of workflows from source to target
-  def self.copy_one(source_tracker, source_role, target_tracker, target_role)
-    unless source_tracker.is_a?(Tracker) && !source_tracker.new_record? &&
-      source_role.is_a?(Role) && !source_role.new_record? &&
-      target_tracker.is_a?(Tracker) && !target_tracker.new_record? &&
-      target_role.is_a?(Role) && !target_role.new_record?
-
-      raise ArgumentError.new("arguments can not be nil or unsaved objects")
-    end
-
-    if source_tracker == target_tracker && source_role == target_role
-      false
-    else
-      transaction do
-        delete_all :tracker_id => target_tracker.id, :role_id => target_role.id
-        connection.insert "INSERT INTO #{Workflow.table_name} (tracker_id, role_id, old_status_id, new_status_id, author, assignee)" +
-                          " SELECT #{target_tracker.id}, #{target_role.id}, old_status_id, new_status_id, author, assignee" +
-                          " FROM #{Workflow.table_name}" +
-                          " WHERE tracker_id = #{source_tracker.id} AND role_id = #{source_role.id}"
-      end
-      true
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/9f/9fe49ff20a0c8ecd14e659372d7a203dcafd42f7.svn-base
--- /dev/null
+++ b/.svn/pristine/9f/9fe49ff20a0c8ecd14e659372d7a203dcafd42f7.svn-base
@@ -0,0 +1,76 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class ProjectsHelperTest < ActionView::TestCase
+  include ApplicationHelper
+  include ProjectsHelper
+  include ERB::Util
+
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :versions,
+           :projects_trackers,
+           :member_roles,
+           :members,
+           :groups_users,
+           :enabled_modules
+
+  def setup
+    super
+    set_language_if_valid('en')
+    User.current = nil
+  end
+
+  def test_link_to_version_within_project
+    @project = Project.find(2)
+    User.current = User.find(1)
+    assert_equal '<a href="/versions/5">Alpha</a>', link_to_version(Version.find(5))
+  end
+
+  def test_link_to_version
+    User.current = User.find(1)
+    assert_equal '<a href="/versions/5">OnlineStore - Alpha</a>', link_to_version(Version.find(5))
+  end
+
+  def test_link_to_private_version
+    assert_equal 'OnlineStore - Alpha', link_to_version(Version.find(5))
+  end
+
+  def test_link_to_version_invalid_version
+    assert_equal '', link_to_version(Object)
+  end
+
+  def test_format_version_name_within_project
+    @project = Project.find(1)
+    assert_equal "0.1", format_version_name(Version.find(1))
+  end
+
+  def test_format_version_name
+    assert_equal "eCookbook - 0.1", format_version_name(Version.find(1))
+  end
+
+  def test_format_version_name_for_system_version
+    assert_equal "OnlineStore - Systemwide visible version", format_version_name(Version.find(7))
+  end
+
+  def test_version_options_for_select_with_no_versions
+    assert_equal '', version_options_for_select([])
+    assert_equal '', version_options_for_select([], Version.find(1))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a0/a0257239a9302c2535d1514d0ba72fba07b7dfdf.svn-base
--- a/.svn/pristine/a0/a0257239a9302c2535d1514d0ba72fba07b7dfdf.svn-base
+++ /dev/null
@@ -1,125 +0,0 @@
-// Calendar AR language
-// Author: SmartData.com.sa
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Ø§Ù„Ø§Ø­Ø¯",
- "Ø§Ù„Ø§Ø«Ù†ÙŠÙ†",
- "Ø§Ù„Ø«Ù„Ø§Ø«Ø§Ø¡",
- "Ø§Ù„Ø§Ø±Ø¨Ø¹Ø§Ø¡",
- "Ø§Ù„Ø®Ù…ÙŠØ³",
- "Ø§Ù„Ø¬Ù…Ø¹Ø©",
- "Ø§Ù„Ø³Ø¨Øª",
- "Ø§Ù„Ø§Ø­Ø¯");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Ø£Ø­",
- "Ø¥Ø«",
- "Ø«",
- "Ø£Ø±",
- "Ø®",
- "Ø¬",
- "Ø³",
- "Ø£Ø­");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ",
- "Ø´Ø¨Ø§Ø·",
- "Ø­Ø²ÙŠØ±Ø§Ù†",
- "Ø¢Ø°Ø§Ø±",
- "Ø£ÙŠØ§Ø±",
- "Ù†ÙŠØ³Ø§Ù†",
- "ØªÙ…ÙˆØ²",
- "Ø¢Ø¨",
- "Ø£ÙŠÙ„ÙˆÙ„",
- "ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø§ÙˆÙ„",
- "ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ",
- "ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø§ÙˆÙ„");
-
-// short month names
-Calendar._SMN = new Array
-("ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ",
- "Ø´Ø¨Ø§Ø·",
- "Ø­Ø²ÙŠØ±Ø§Ù†",
- "Ø¢Ø°Ø§Ø±",
- "Ø£ÙŠØ§Ø±",
- "Ù†ÙŠØ³Ø§Ù†",
- "ØªÙ…ÙˆØ²",
- "Ø¢Ø¨",
- "Ø£ÙŠÙ„ÙˆÙ„",
- "ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø§ÙˆÙ„",
- "ØªØ´Ø±ÙŠÙ† Ø§Ù„Ø«Ø§Ù†ÙŠ",
- "ÙƒØ§Ù†ÙˆÙ† Ø§Ù„Ø§ÙˆÙ„");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Ø­ÙˆÙ„ Ø§Ù„ØªÙ‚ÙˆÙŠÙ…";
-
-Calendar._TT["ABOUT"] =
-"Ø§Ø®ØªÙŠØ§Ø± Ø§Ù„ÙˆÙ‚Øª ÙˆØ§Ù„ØªØ§Ø±ÙŠØ®\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Ø§Ø®ØªÙŠØ§Ø± Ø§Ù„ØªØ§Ø±ÙŠØ®:\n" +
-"- Ø§Ø³ØªØ®Ø¯Ù… Ù‡Ø°Ù‡ Ø§Ù„Ø§Ø²Ø±Ø§Ø± \xab, \xbb Ù„Ø§Ø®ØªÙŠØ§Ø± Ø§Ù„Ø³Ù†Ø©\n" +
-"- Ø§Ø³ØªØ®Ø¯Ù… Ù‡Ø°Ù‡ Ø§Ù„Ø§Ø²Ø±Ø§Ø± " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Ù„Ø§Ø®ØªÙŠØ§Ø± Ø§Ù„Ø´Ù‡Ø±\n" +
-"- Ø§Ø³ØªÙ…Ø± ÙÙŠ Ø§Ù„Ù†Ù‚Ø± ÙÙˆÙ‚ Ø§Ù„Ø§Ø²Ø±Ø§Ø± Ù„Ù„ØªØ¸Ù„ÙŠÙ„ Ø§Ù„Ø³Ø±ÙŠØ¹.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Ø§Ø®ØªÙŠØ§Ø± Ø§Ù„ÙˆÙ‚Øª:\n" +
-"- Ø§Ù†Ù‚Ø± Ø¹Ù„Ù‰ Ø§ÙŠ Ø¬Ø²Ø¡ Ù…Ù† Ø§Ø¬Ø²Ø§Ø¡ Ø§Ù„ÙˆÙ‚Øª Ù„Ø²ÙŠØ§Ø¯ØªÙ‡\n" +
-"-  Ù„Ø§Ù†Ù‚Ø§ØµÙ‡ShiftØ§Ùˆ Ø§Ù†Ù‚Ø± Ù…Ø¹ Ø§Ù„Ø¶ØºØ· Ø¹Ù„Ù‰ Ù…ÙØªØ§Ø­  \n" +
-"- Ø§Ùˆ Ø§Ù†Ù‚Ø± ÙˆØ§Ø³Ø­Ø¨ Ù„Ù„ØªØ¸Ù„ÙŠÙ„ Ø§Ù„Ø³Ø±ÙŠØ¹.";
-
-Calendar._TT["PREV_YEAR"] = "Ø§Ù„Ø³Ù†Ø© Ø§Ù„Ø³Ø§Ø¨Ù‚Ø©";
-Calendar._TT["PREV_MONTH"] = "Ø§Ù„Ø´Ù‡Ø± Ø§Ù„Ø³Ø§Ø¨Ù‚";
-Calendar._TT["GO_TODAY"] = "Ø§Ø°Ù‡Ø¨ Ù„Ù„ÙŠÙˆÙ…";
-Calendar._TT["NEXT_MONTH"] = "Ø§Ù„Ø´Ù‡Ø± Ø§Ù„Ù‚Ø§Ø¯Ù…";
-Calendar._TT["NEXT_YEAR"] = "Ø§Ù„Ø³Ù†Ø© Ø§Ù„Ù‚Ø§Ø¯Ù…Ø©";
-Calendar._TT["SEL_DATE"] = "Ø§Ø®ØªØ± Ø§Ù„ØªØ§Ø±ÙŠØ®";
-Calendar._TT["DRAG_TO_MOVE"] = "Ø§Ø³Ø­Ø¨ Ù„Ù„ØªØªØ­Ø±Ùƒ";
-Calendar._TT["PART_TODAY"] = "Ø§Ù„ÙŠÙˆÙ…";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = " Ø§ÙˆÙ„Ø§%sØ§Ø¹Ø±Ø¶ ";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "5,6";
-
-Calendar._TT["CLOSE"] = "Ù…ØºÙ„Ù‚";
-Calendar._TT["TODAY"] = "Ø§Ù„ÙŠÙˆÙ…";
-Calendar._TT["TIME_PART"] = "Ø§Ù†Ù‚Ø± Ø§Ùˆ Ø§Ø³Ø­Ø¨ Ù„ØªØºÙŠØ± Ø§Ù„Ù‚ÙŠÙ…Ø©";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "Ø±Ù‚Ù… Ø§Ù„Ø§Ø³Ø¨ÙˆØ¹";
-Calendar._TT["TIME"] = "Ø§Ù„ÙˆÙ‚Øª:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a0/a031ba3671a49b989b6b3f05b2432855669191cf.svn-base
--- /dev/null
+++ b/.svn/pristine/a0/a031ba3671a49b989b6b3f05b2432855669191cf.svn-base
@@ -0,0 +1,114 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class PrincipalTest < ActiveSupport::TestCase
+  fixtures :users, :projects, :members, :member_roles
+
+  def test_active_scope_should_return_groups_and_active_users
+    result = Principal.active.all
+    assert_include Group.first, result
+    assert_not_nil result.detect {|p| p.is_a?(User)}
+    assert_nil result.detect {|p| p.is_a?(User) && !p.active?}
+    assert_nil result.detect {|p| p.is_a?(AnonymousUser)}
+  end
+
+  def test_member_of_scope_should_return_the_union_of_all_members
+    projects = Project.find_all_by_id(1, 2)
+    assert_equal projects.map(&:principals).flatten.sort, Principal.member_of(projects).sort
+  end
+
+  def test_member_of_scope_should_be_empty_for_no_projects
+    assert_equal [], Principal.member_of([]).sort
+  end
+
+  def test_not_member_of_scope_should_return_users_that_have_no_memberships
+    projects = Project.find_all_by_id(1, 2)
+    expected = (Principal.all - projects.map(&:memberships).flatten.map(&:principal)).sort
+    assert_equal expected, Principal.not_member_of(projects).sort
+  end
+
+  def test_not_member_of_scope_should_be_empty_for_no_projects
+    assert_equal [], Principal.not_member_of([]).sort
+  end
+
+  def test_sorted_scope_should_sort_users_before_groups
+    scope = Principal.where("type <> ?", 'AnonymousUser')
+    expected_order = scope.all.sort do |a, b|
+      if a.is_a?(User) && b.is_a?(Group)
+        -1
+      elsif a.is_a?(Group) && b.is_a?(User)
+        1
+      else
+        a.name.downcase <=> b.name.downcase
+      end
+    end
+    assert_equal expected_order.map(&:name).map(&:downcase), scope.sorted.all.map(&:name).map(&:downcase)
+  end
+
+  test "like scope should search login" do
+    results = Principal.like('jsmi')
+
+    assert results.any?
+    assert results.all? {|u| u.login.match(/jsmi/i) }
+  end
+
+  test "like scope should search firstname" do
+    results = Principal.like('john')
+
+    assert results.any?
+    assert results.all? {|u| u.firstname.match(/john/i) }
+  end
+
+  test "like scope should search lastname" do
+    results = Principal.like('smi')
+
+    assert results.any?
+    assert results.all? {|u| u.lastname.match(/smi/i) }
+  end
+
+  test "like scope should search mail" do
+    results = Principal.like('somenet')
+
+    assert results.any?
+    assert results.all? {|u| u.mail.match(/somenet/i) }
+  end
+
+  test "like scope should search firstname and lastname" do
+    results = Principal.like('john smi')
+
+    assert_equal 1, results.count
+    assert_equal User.find(2), results.first
+  end
+
+  test "like scope should search lastname and firstname" do
+    results = Principal.like('smith joh')
+
+    assert_equal 1, results.count
+    assert_equal User.find(2), results.first
+  end
+
+  def test_like_scope_with_cyrillic_name
+    user = User.generate!(:firstname => 'Ð¡Ð¾Ð±Ð¾Ð»ÐµÐ²', :lastname => 'Ð”ÐµÐ½Ð¸Ñ')
+    results = Principal.like('Ð¡Ð¾Ð±Ð¾')
+    assert_equal 1, results.count
+    assert_equal user, results.first
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a0/a05ab868ad3b19d5316c0626acc00885ad376f65.svn-base
--- a/.svn/pristine/a0/a05ab868ad3b19d5316c0626acc00885ad376f65.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-the html part of the email <%= do_something_helpful("semaj") %>
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a0/a06bd0e55ce970d54bb6d369cc24705f44d92b5d.svn-base
--- a/.svn/pristine/a0/a06bd0e55ce970d54bb6d369cc24705f44d92b5d.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-<h2><%=h @status %></h2>
-
-<% if @message.present? %>
-  <p id="errorExplanation"><%=h @message %></p>
-<% end %>
-<p><a href="javascript:history.back()">Back</a></p>
-
-<% html_title @status %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a0/a08d9efaa1fdce6da7c3589a96b91c744a36f751.svn-base
--- /dev/null
+++ b/.svn/pristine/a0/a08d9efaa1fdce6da7c3589a96b91c744a36f751.svn-base
@@ -0,0 +1,1084 @@
+uk:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
+    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "half a minute"
+      less_than_x_seconds:
+        one:   "less than 1 second"
+        other: "less than %{count} seconds"
+      x_seconds:
+        one:   "1 second"
+        other: "%{count} seconds"
+      less_than_x_minutes:
+        one:   "less than a minute"
+        other: "less than %{count} minutes"
+      x_minutes:
+        one:   "1 minute"
+        other: "%{count} minutes"
+      about_x_hours:
+        one:   "about 1 hour"
+        other: "about %{count} hours"
+      x_hours:
+        one:   "1 hour"
+        other: "%{count} hours"
+      x_days:
+        one:   "1 day"
+        other: "%{count} days"
+      about_x_months:
+        one:   "about 1 month"
+        other: "about %{count} months"
+      x_months:
+        one:   "1 month"
+        other: "%{count} months"
+      about_x_years:
+        one:   "about 1 year"
+        other: "about %{count} years"
+      over_x_years:
+        one:   "over 1 year"
+        other: "over %{count} years"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        precision: 3
+        delimiter: ""
+      storage_units:
+        format: "%n %u"
+        units:
+          kb: KB
+          tb: TB
+          gb: GB
+          byte:
+            one: Byte
+            other: Bytes
+          mb: MB
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "and"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "Ð½ÐµÐ¼Ð°Ñ” Ð² ÑÐ¿Ð¸ÑÐºÑƒ"
+        exclusion: "Ð·Ð°Ñ€ÐµÐ·ÐµÑ€Ð²Ð¾Ð²Ð°Ð½Ð¾"
+        invalid: "Ð½ÐµÐ²Ñ–Ñ€Ð½Ðµ"
+        confirmation: "Ð½Ðµ Ð·Ð±Ñ–Ð³Ð°Ñ”Ñ‚ÑŒÑÑ Ð· Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½ÑÐ¼"
+        accepted: "Ð½ÐµÐ¾Ð±Ñ…Ñ–Ð´Ð½Ð¾ Ð¿Ñ€Ð¸Ð¹Ð½ÑÑ‚Ð¸"
+        empty: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±ÑƒÑ‚Ð¸ Ð¿Ð¾Ñ€Ð¾Ð¶Ð½Ñ–Ð¼"
+        blank: "Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±ÑƒÑ‚Ð¸ Ð½ÐµÐ·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð¸Ð¼"
+        too_long: "Ð´ÑƒÐ¶Ðµ Ð´Ð¾Ð²Ð³Ðµ"
+        too_short: "Ð´ÑƒÐ¶Ðµ ÐºÐ¾Ñ€Ð¾Ñ‚ÐºÐµ"
+        wrong_length: "Ð½Ðµ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð°Ñ” Ð´Ð¾Ð²Ð¶Ð¸Ð½Ñ–"
+        taken: "Ð²Ð¶Ðµ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÑ”Ñ‚ÑŒÑÑ"
+        not_a_number: "Ð½Ðµ Ñ” Ñ‡Ð¸ÑÐ»Ð¾Ð¼"
+        not_a_date: "Ñ” Ð½ÐµÐ´Ñ–Ð¹ÑÐ½Ð¾ÑŽ Ð´Ð°Ñ‚Ð¾ÑŽ"
+        greater_than: "must be greater than %{count}"
+        greater_than_or_equal_to: "must be greater than or equal to %{count}"
+        equal_to: "must be equal to %{count}"
+        less_than: "must be less than %{count}"
+        less_than_or_equal_to: "must be less than or equal to %{count}"
+        odd: "must be odd"
+        even: "must be even"
+        greater_than_start_date: "Ð¿Ð¾Ð²Ð¸Ð½Ð½Ð° Ð±ÑƒÑ‚Ð¸ Ð¿Ñ–Ð·Ð½Ñ–ÑˆÐ° Ð·Ð° Ð´Ð°Ñ‚Ñƒ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ"
+        not_same_project: "Ð½Ðµ Ð²Ñ–Ð´Ð½Ð¾ÑÑÑ‚ÑŒÑÑ Ð´Ð¾ Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ"
+        circular_dependency: "Ð¢Ð°ÐºÐ¸Ð¹ Ð·Ð²'ÑÐ·Ð¾Ðº Ð¿Ñ€Ð¸Ð²ÐµÐ´Ðµ Ð´Ð¾ Ñ†Ð¸ÐºÐ»Ñ–Ñ‡Ð½Ð¾Ñ— Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾ÑÑ‚Ñ–"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: ÐžÐ±ÐµÑ€Ñ–Ñ‚ÑŒ
+
+  general_text_No: 'ÐÑ–'
+  general_text_Yes: 'Ð¢Ð°Ðº'
+  general_text_no: 'ÐÑ–'
+  general_text_yes: 'Ð¢Ð°Ðº'
+  general_lang_name: 'Ukrainian (Ð£ÐºÑ€Ð°Ñ—Ð½ÑÑŒÐºÐ°)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: ÐžÐ±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¹.
+  notice_account_invalid_creditentials: ÐÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ðµ Ñ–Ð¼'Ñ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð° Ð°Ð±Ð¾ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
+  notice_account_password_updated: ÐŸÐ°Ñ€Ð¾Ð»ÑŒ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¹.
+  notice_account_wrong_password: ÐÐµÐ²Ñ–Ñ€Ð½Ð¸Ð¹ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
+  notice_account_register_done: ÐžÐ±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ð¹. Ð”Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— Ð’Ð°ÑˆÐ¾Ð³Ð¾ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ Ð·Ð°Ð¹Ð´Ñ–Ñ‚ÑŒ Ð¿Ð¾ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½ÑŽ, ÑÐºÐµ Ð²Ñ–Ð´Ñ–ÑÐ»Ð°Ð½Ðµ Ð²Ð°Ð¼ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ Ð¿Ð¾ÑˆÑ‚Ð¾ÑŽ.
+  notice_account_unknown_email: ÐÐµÐ²Ñ–Ð´Ð¾Ð¼Ð¸Ð¹ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡.
+  notice_can_t_change_password: Ð”Ð»Ñ Ð´Ð°Ð½Ð¾Ð³Ð¾ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÑ”Ñ‚ÑŒÑÑ Ð´Ð¶ÐµÑ€ÐµÐ»Ð¾ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ñ— Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—. ÐÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ.
+  notice_account_lost_email_sent: Ð’Ð°Ð¼ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ð¹ Ð»Ð¸ÑÑ‚ Ð· Ñ–Ð½ÑÑ‚Ñ€ÑƒÐºÑ†Ñ–ÑÐ¼Ð¸ Ð¿Ð¾ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ð¿Ð°Ñ€Ð¾Ð»Ñ.
+  notice_account_activated: Ð’Ð°Ñˆ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ Ð°ÐºÑ‚Ð¸Ð²Ð¾Ð²Ð°Ð½Ð¸Ð¹. Ð’Ð¸ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ ÑƒÐ²Ñ–Ð¹Ñ‚Ð¸.
+  notice_successful_create: Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ðµ.
+  notice_successful_update: ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ðµ.
+  notice_successful_delete: Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ðµ.
+  notice_successful_connection: ÐŸÑ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ ÑƒÑÐ¿Ñ–ÑˆÐ½Ð¾ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ðµ.
+  notice_file_not_found: Ð¡Ñ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°, Ð½Ð° ÑÐºÑƒ Ð²Ð¸ Ð½Ð°Ð¼Ð°Ð³Ð°Ñ”Ñ‚ÐµÑÑ Ð·Ð°Ð¹Ñ‚Ð¸, Ð½Ðµ Ñ–ÑÐ½ÑƒÑ” Ð°Ð±Ð¾ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð°.
+  notice_locking_conflict: Ð”Ð°Ð½Ñ– Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾ Ñ–Ð½ÑˆÐ¸Ð¼ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡ÐµÐ¼.
+  notice_scm_error: Ð—Ð°Ð¿Ð¸ÑÑƒ Ñ‚Ð°/Ð°Ð±Ð¾ Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð½ÐµÐ¼Ð°Ñ” Ð² Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ—.
+  notice_not_authorized: Ð£ Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” Ð¿Ñ€Ð°Ð² Ð´Ð»Ñ Ð²Ñ–Ð´Ð²Ñ–Ð´Ð¸Ð½Ð¸ Ð´Ð°Ð½Ð¾Ñ— ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ¸.
+  notice_email_sent: "Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¾ Ð»Ð¸ÑÑ‚Ð° %{value}"
+  notice_email_error: "ÐŸÑ–Ð´ Ñ‡Ð°Ñ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²ÐºÐ¸ Ð»Ð¸ÑÑ‚Ð° Ð²Ñ–Ð´Ð±ÑƒÐ»Ð°ÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° (%{value})"
+  notice_feeds_access_key_reseted: Ð’Ð°Ñˆ ÐºÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ RSS Ð±ÑƒÐ»Ð¾ ÑÐºÐ¸Ð½ÑƒÑ‚Ð¾.
+  notice_failed_to_save_issues: "ÐÐµ Ð²Ð´Ð°Ð»Ð¾ÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ %{count} Ð¿ÑƒÐ½ÐºÑ‚(Ñ–Ð²) Ð· %{total} Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¸Ñ…: %{ids}."
+  notice_no_issue_selected: "ÐÐµ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾ Ð¶Ð¾Ð´Ð½Ð¾Ñ— Ð·Ð°Ð´Ð°Ñ‡Ñ–! Ð‘ÑƒÐ´ÑŒ Ð»Ð°ÑÐºÐ°, Ð²Ñ–Ð´Ð·Ð½Ð°Ñ‡Ñ‚Ðµ Ð·Ð°Ð´Ð°Ñ‡Ñƒ, ÑÐºÑƒ Ð²Ð¸ Ñ…Ð¾Ñ‡ÐµÑ‚Ðµ Ð²Ñ–Ð´Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸."
+  notice_account_pending: "Ð’Ð°Ñˆ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð¾ Ñ– Ð²Ñ–Ð½ Ñ‡ÐµÐºÐ°Ñ” Ð½Ð° Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð¼."
+
+  mail_subject_lost_password: "Ð’Ð°Ñˆ %{value} Ð¿Ð°Ñ€Ð¾Ð»ÑŒ"
+  mail_body_lost_password: 'Ð”Ð»Ñ Ð·Ð¼Ñ–Ð½Ð¸ Ð¿Ð°Ñ€Ð¾Ð»Ñ, Ð·Ð°Ð¹Ð´Ñ–Ñ‚ÑŒ Ð·Ð° Ð½Ð°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ð¼ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½ÑÐ¼:'
+  mail_subject_register: "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ %{value}"
+  mail_body_register: 'Ð”Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ, Ð·Ð°Ð¹Ð´Ñ–Ñ‚ÑŒ Ð·Ð° Ð½Ð°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ð¼ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½ÑÐ¼:'
+  mail_body_account_information_external: "Ð’Ð¸ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÐ²Ð°Ñ‚Ð¸ Ð²Ð°Ñˆ %{value} Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ñƒ."
+  mail_body_account_information: Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ð¾ Ð’Ð°ÑˆÐ¾Ð¼Ñƒ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð¼Ñƒ Ð·Ð°Ð¿Ð¸ÑÑƒ
+  mail_subject_account_activation_request: "Ð—Ð°Ð¿Ð¸Ñ‚ Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–ÑŽ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ %{value}"
+  mail_body_account_activation_request: "ÐÐ¾Ð²Ð¸Ð¹ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡ (%{value}) Ð·Ð°Ñ€ÐµÑ”ÑÑ‚Ñ€ÑƒÐ²Ð°Ð²ÑÑ. Ð™Ð¾Ð³Ð¾ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ Ñ‡ÐµÐºÐ°Ñ” Ð½Ð° Ð²Ð°ÑˆÐµ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ:"
+
+
+  field_name: Ð†Ð¼'Ñ
+  field_description: ÐžÐ¿Ð¸Ñ
+  field_summary: ÐšÐ¾Ñ€Ð¾Ñ‚ÐºÐ¸Ð¹ Ð¾Ð¿Ð¸Ñ
+  field_is_required: ÐÐµÐ¾Ð±Ñ…Ñ–Ð´Ð½Ð¾
+  field_firstname: Ð†Ð¼'Ñ
+  field_lastname: ÐŸÑ€Ñ–Ð·Ð²Ð¸Ñ‰Ðµ
+  field_mail: Ð•Ð». Ð¿Ð¾ÑˆÑ‚Ð°
+  field_filename: Ð¤Ð°Ð¹Ð»
+  field_filesize: Ð Ð¾Ð·Ð¼Ñ–Ñ€
+  field_downloads: Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ
+  field_author: ÐÐ²Ñ‚Ð¾Ñ€
+  field_created_on: Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð¾
+  field_updated_on: ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð¾
+  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
+  field_is_for_all: Ð”Ð»Ñ ÑƒÑÑ–Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ–Ð²
+  field_possible_values: ÐœÐ¾Ð¶Ð»Ð¸Ð²Ñ– Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ
+  field_regexp: Ð ÐµÐ³ÑƒÐ»ÑÑ€Ð½Ð¸Ð¹ Ð²Ð¸Ñ€Ð°Ð·
+  field_min_length: ÐœÑ–Ð½Ñ–Ð¼Ð°Ð»ÑŒÐ½Ð° Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð°
+  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð° Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð°
+  field_value: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ
+  field_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ
+  field_title: ÐÐ°Ð·Ð²Ð°
+  field_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
+  field_issue: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ
+  field_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ
+  field_notes: ÐŸÑ€Ð¸Ð¼Ñ–Ñ‚ÐºÐ¸
+  field_is_closed: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¾
+  field_is_default: Ð¢Ð¸Ð¿Ð¾Ð²Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ
+  field_tracker: ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€
+  field_subject: Ð¢ÐµÐ¼Ð°
+  field_due_date: Ð”Ð°Ñ‚Ð° Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ
+  field_assigned_to: ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð° Ð´Ð¾
+  field_priority: ÐŸÑ€Ñ–Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
+  field_fixed_version: Target version
+  field_user: ÐšÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡
+  field_role: Ð Ð¾Ð»ÑŒ
+  field_homepage: Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°
+  field_is_public: ÐŸÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð¸Ð¹
+  field_parent: ÐŸÑ–Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  field_is_in_roadmap: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ, Ñ‰Ð¾ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶Ð°ÑŽÑ‚ÑŒÑÑ Ð² Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ð¾Ð¼Ñƒ Ð¿Ð»Ð°Ð½Ñ–
+  field_login: Ð’Ñ…Ñ–Ð´
+  field_mail_notification: ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð° ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ Ð¿Ð¾ÑˆÑ‚Ð¾ÑŽ
+  field_admin: ÐÐ´Ð¼Ñ–Ð½Ñ–ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
+  field_last_login_on: ÐžÑÑ‚Ð°Ð½Ð½Ñ” Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ
+  field_language: ÐœÐ¾Ð²Ð°
+  field_effective_date: Ð”Ð°Ñ‚Ð°
+  field_password: ÐŸÐ°Ñ€Ð¾Ð»ÑŒ
+  field_new_password: ÐÐ¾Ð²Ð¸Ð¹ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
+  field_password_confirmation: ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ
+  field_version: Ð’ÐµÑ€ÑÑ–Ñ
+  field_type: Ð¢Ð¸Ð¿
+  field_host: ÐœÐ°ÑˆÐ¸Ð½Ð°
+  field_port: ÐŸÐ¾Ñ€Ñ‚
+  field_account: ÐžÐ±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ
+  field_base_dn: Ð‘Ð°Ð·Ð¾Ð²Ðµ Ð²Ñ–Ð´Ð¼Ñ–Ñ‚Ð½Ðµ Ñ–Ð¼'Ñ
+  field_attr_login: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð ÐµÑ”ÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ
+  field_attr_firstname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Ð†Ð¼'Ñ
+  field_attr_lastname: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ ÐŸÑ€Ñ–Ð·Ð²Ð¸Ñ‰Ðµ
+  field_attr_mail: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚ Email
+  field_onthefly: Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð° Ð½Ð° Ð»ÑŒÐ¾Ñ‚Ñƒ
+  field_start_date: ÐŸÐ¾Ñ‡Ð°Ñ‚Ð¾Ðº
+  field_done_ratio: "% Ð·Ñ€Ð¾Ð±Ð»ÐµÐ½Ð¾"
+  field_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—
+  field_hide_mail: ÐŸÑ€Ð¸Ñ…Ð¾Ð²ÑƒÐ²Ð°Ñ‚Ð¸ Ð¼Ñ–Ð¹ email
+  field_comments: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  field_url: URL
+  field_start_page: Ð¡Ñ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð° ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°
+  field_subproject: ÐŸÑ–Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  field_hours: Ð“Ð¾Ð´Ð¸Ð½(Ð¸/Ð°)
+  field_activity: Ð”Ñ–ÑÐ»ÑŒÐ½Ñ–ÑÑ‚ÑŒ
+  field_spent_on: Ð”Ð°Ñ‚Ð°
+  field_identifier: Ð†Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ‚Ð¾Ñ€
+  field_is_filter: Ð’Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÑ”Ñ‚ÑŒÑÑ ÑÐº Ñ„Ñ–Ð»ÑŒÑ‚Ñ€
+  field_issue_to: Ð—Ð²'ÑÐ·Ð°Ð½Ñ– Ð·Ð°Ð´Ð°Ñ‡Ñ–
+  field_delay: Ð’Ñ–Ð´ÐºÐ»Ð°ÑÑ‚Ð¸
+  field_assignable: Ð—Ð°Ð´Ð°Ñ‡Ð° Ð¼Ð¾Ð¶Ðµ Ð±ÑƒÑ‚Ð¸ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð° Ñ†Ñ–Ð¹ Ñ€Ð¾Ð»Ñ–
+  field_redirect_existing_links: ÐŸÐµÑ€ÐµÐ½Ð°Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸ Ñ–ÑÐ½ÑƒÑŽÑ‡Ñ– Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ
+  field_estimated_hours: ÐžÑ†Ñ–Ð½Ð½Ð¸Ð¹ Ñ‡Ð°Ñ
+  field_column_names: ÐšÐ¾Ð»Ð¾Ð½ÐºÐ¸
+  field_time_zone: Ð§Ð°ÑÐ¾Ð²Ð¸Ð¹ Ð¿Ð¾ÑÑ
+  field_searchable: Ð’Ð¶Ð¸Ð²Ð°Ñ”Ñ‚ÑŒÑÑ Ñƒ Ð¿Ð¾ÑˆÑƒÐºÑƒ
+
+  setting_app_title: ÐÐ°Ð·Ð²Ð° Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ
+  setting_app_subtitle: ÐŸÑ–Ð´Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ
+  setting_welcome_text: Ð¢ÐµÐºÑÑ‚ Ð¿Ñ€Ð¸Ð²Ñ–Ñ‚Ð°Ð½Ð½Ñ
+  setting_default_language: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð° Ð¼Ð¾Ð²Ð°
+  setting_login_required: ÐÐµÐ¾Ð±Ñ…Ñ–Ð´Ð½Ð° Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ
+  setting_self_registration: ÐœÐ¾Ð¶Ð»Ð¸Ð²Ð° ÑÐ°Ð¼Ð¾-Ñ€ÐµÑ”ÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ
+  setting_attachment_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¸Ð¹ Ñ€Ð°Ð·Ð¼Ñ–Ñ€ Ð²ÐºÐ»Ð°Ð´ÐµÐ½Ð½Ñ
+  setting_issues_export_limit: ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾ Ð·Ð°Ð´Ð°Ñ‡Ð°Ñ…, Ñ‰Ð¾ ÐµÐºÑÐ¿Ð¾Ñ€Ñ‚ÑƒÑŽÑ‚ÑŒÑÑ
+  setting_mail_from: email Ð°Ð´Ñ€ÐµÑÐ° Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ñ– Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—
+  setting_bcc_recipients: ÐžÑ‚Ñ€Ð¸Ð¼ÑƒÐ²Ð°Ñ‡Ñ– ÑÐ»Ñ–Ð¿Ð¾Ñ— ÐºÐ¾Ð¿Ñ–Ñ— (bcc)
+  setting_host_name: Ð˜Ð¼'Ñ Ð¼Ð°ÑˆÐ¸Ð½Ð¸
+  setting_text_formatting: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÑÑ‚Ñƒ
+  setting_wiki_compression: Ð¡Ñ‚Ð¸ÑÐ½ÐµÐ½Ð½Ñ Ñ–ÑÑ‚Ð¾Ñ€Ñ–Ñ— Wiki
+  setting_feeds_limit: ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–ÑÑ‚Ñƒ Ð¿Ð¾Ð´Ð°Ñ‡Ñ–
+  setting_autofetch_changesets: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾ Ð´Ð¾ÑÑ‚Ð°Ð²Ð°Ñ‚Ð¸ Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ
+  setting_sys_api_enabled: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ‚Ð¸ WS Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ”Ð¼
+  setting_commit_ref_keywords: ÐšÐ»ÑŽÑ‡Ð¾Ð²Ñ– ÑÐ»Ð¾Ð²Ð° Ð´Ð»Ñ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ
+  setting_commit_fix_keywords: ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¸Ñ… ÑÐ»Ñ–Ð²
+  setting_autologin: ÐÐ²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¸Ð¹ Ð²Ñ…Ñ–Ð´
+  setting_date_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð´Ð°Ñ‚Ð¸
+  setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ñ‡Ð°ÑÑƒ
+  setting_cross_project_issue_relations: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ‚Ð¸ Ð¼Ñ–Ð¶Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ñ– Ð²Ñ–Ð´Ð½Ð¾ÑÐ¸Ð½Ð¸ Ð¼Ñ–Ð¶ Ð¿Ð¸Ñ‚Ð°Ð½Ð½ÑÐ¼Ð¸
+  setting_issue_list_default_columns: ÐšÐ¾Ð»Ð¾Ð½ÐºÐ¸, Ñ‰Ð¾ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶Ð°ÑŽÑ‚ÑŒÑÑ Ð·Ð° ÑƒÐ¼Ð¾Ð²Ñ‡Ð°Ð½Ð½ÑÐ¼ Ð² ÑÐ¿Ð¸ÑÐºÑƒ Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
+  setting_emails_footer: ÐŸÑ–Ð´Ð¿Ð¸Ñ Ð´Ð¾ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— Ð¿Ð¾ÑˆÑ‚Ð¸
+  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
+
+  label_user: ÐšÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡
+  label_user_plural: ÐšÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ñ–
+  label_user_new: ÐÐ¾Ð²Ð¸Ð¹ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡
+  label_project: ÐŸÑ€Ð¾ÐµÐºÑ‚
+  label_project_new: ÐÐ¾Ð²Ð¸Ð¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚
+  label_project_plural: ÐŸÑ€Ð¾ÐµÐºÑ‚Ð¸
+  label_x_projects:
+    zero:  no projects
+    one:   1 project
+    other: "%{count} projects"
+  label_project_all: Ð£ÑÑ– Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_project_latest: ÐžÑÑ‚Ð°Ð½Ð½Ñ– Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_issue: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ
+  label_issue_new: ÐÐ¾Ð²Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
+  label_issue_plural: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ
+  label_issue_view_all: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸ Ð²ÑÑ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
+  label_issues_by: "ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ð° %{value}"
+  label_document: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_new: ÐÐ¾Ð²Ð¸Ð¹ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
+  label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  label_role: Ð Ð¾Ð»ÑŒ
+  label_role_plural: Ð Ð¾Ð»Ñ–
+  label_role_new: ÐÐ¾Ð²Ð° Ñ€Ð¾Ð»ÑŒ
+  label_role_and_permissions: Ð Ð¾Ð»Ñ– Ñ– Ð¿Ñ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ
+  label_member: Ð£Ñ‡Ð°ÑÐ½Ð¸Ðº
+  label_member_new: ÐÐ¾Ð²Ð¸Ð¹ ÑƒÑ‡Ð°ÑÐ½Ð¸Ðº
+  label_member_plural: Ð£Ñ‡Ð°ÑÐ½Ð¸ÐºÐ¸
+  label_tracker: ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€
+  label_tracker_plural: ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€Ð¸
+  label_tracker_new: ÐÐ¾Ð²Ð¸Ð¹ ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€
+  label_workflow: ÐŸÐ¾ÑÐ»Ñ–Ð´Ð¾Ð²Ð½Ñ–ÑÑ‚ÑŒ Ð´Ñ–Ð¹
+  label_issue_status: Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
+  label_issue_status_plural: Ð¡Ñ‚Ð°Ñ‚ÑƒÑÐ¸ Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
+  label_issue_status_new: ÐÐ¾Ð²Ð¸Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_issue_category: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
+  label_issue_category_plural: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ— Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
+  label_issue_category_new: ÐÐ¾Ð²Ð° ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ
+  label_custom_field: ÐŸÐ¾Ð»Ðµ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð°
+  label_custom_field_plural: ÐŸÐ¾Ð»Ñ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð°
+  label_custom_field_new: ÐÐ¾Ð²Ðµ Ð¿Ð¾Ð»Ðµ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð°
+  label_enumerations: Ð”Ð¾Ð²Ñ–Ð´Ð½Ð¸ÐºÐ¸
+  label_enumeration_new: ÐÐ¾Ð²Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ
+  label_information: Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ
+  label_information_plural: Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ
+  label_please_login: Ð‘ÑƒÐ´ÑŒ Ð»Ð°ÑÐºÐ°, ÑƒÐ²Ñ–Ð¹Ð´Ñ–Ñ‚ÑŒ
+  label_register: Ð—Ð°Ñ€ÐµÑ”ÑÑ‚Ñ€ÑƒÐ²Ð°Ñ‚Ð¸ÑÑ
+  label_password_lost: Ð—Ð°Ð±ÑƒÐ»Ð¸ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
+  label_home: Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°
+  label_my_page: ÐœÐ¾Ñ ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÐ°
+  label_my_account: ÐœÑ–Ð¹ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ
+  label_my_projects: ÐœÐ¾Ñ— Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_administration: ÐÐ´Ð¼Ñ–Ð½Ñ–ÑÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ
+  label_login: Ð£Ð²Ñ–Ð¹Ñ‚Ð¸
+  label_logout: Ð’Ð¸Ð¹Ñ‚Ð¸
+  label_help: Ð”Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð°
+  label_reported_issues: Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
+  label_assigned_to_me_issues: ÐœÐ¾Ñ— Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
+  label_last_login: ÐžÑÑ‚Ð°Ð½Ð½Ñ” Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ
+  label_registered_on: Ð—Ð°Ñ€ÐµÑ”ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½Ð¸Ð¹(Ð°)
+  label_activity: ÐÐºÑ‚Ð¸Ð²Ð½Ñ–ÑÑ‚ÑŒ
+  label_new: ÐÐ¾Ð²Ð¸Ð¹
+  label_logged_as: Ð£Ð²Ñ–Ð¹ÑˆÐ¾Ð² ÑÐº
+  label_environment: ÐžÑ‚Ð¾Ñ‡ÐµÐ½Ð½Ñ
+  label_authentication: ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ
+  label_auth_source: Ð ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—
+  label_auth_source_new: ÐÐ¾Ð²Ð¸Ð¹ Ñ€ÐµÐ¶Ð¸Ð¼ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—
+  label_auth_source_plural: Ð ÐµÐ¶Ð¸Ð¼Ð¸ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—
+  label_subproject_plural: ÐŸÑ–Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_min_max_length: ÐœÑ–Ð½Ñ–Ð¼Ð°Ð»ÑŒÐ½Ð° - Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð° Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð°
+  label_list: Ð¡Ð¿Ð¸ÑÐ¾Ðº
+  label_date: Ð”Ð°Ñ‚Ð°
+  label_integer: Ð¦Ñ–Ð»Ð¸Ð¹
+  label_float: Ð— Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‡Ð¾ÑŽ ÐºÑ€Ð°Ð¿ÐºÐ¾ÑŽ
+  label_boolean: Ð›Ð¾Ð³Ñ–Ñ‡Ð½Ð¸Ð¹
+  label_string: Ð¢ÐµÐºÑÑ‚
+  label_text: Ð”Ð¾Ð²Ð³Ð¸Ð¹ Ñ‚ÐµÐºÑÑ‚
+  label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
+  label_attribute_plural: Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸
+  label_no_data: ÐÐµÐ¼Ð°Ñ” Ð´Ð°Ð½Ð¸Ñ… Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ
+  label_change_status: Ð—Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_history: Ð†ÑÑ‚Ð¾Ñ€Ñ–Ñ
+  label_attachment: Ð¤Ð°Ð¹Ð»
+  label_attachment_new: ÐÐ¾Ð²Ð¸Ð¹ Ñ„Ð°Ð¹Ð»
+  label_attachment_delete: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ñ„Ð°Ð¹Ð»
+  label_attachment_plural: Ð¤Ð°Ð¹Ð»Ð¸
+  label_report: Ð—Ð²Ñ–Ñ‚
+  label_report_plural: Ð—Ð²Ñ–Ñ‚Ð¸
+  label_news: ÐÐ¾Ð²Ð¸Ð½Ð¸
+  label_news_new: Ð”Ð¾Ð´Ð°Ñ‚Ð¸ Ð½Ð¾Ð²Ð¸Ð½Ñƒ
+  label_news_plural: ÐÐ¾Ð²Ð¸Ð½Ð¸
+  label_news_latest: ÐžÑÑ‚Ð°Ð½Ð½Ñ– Ð½Ð¾Ð²Ð¸Ð½Ð¸
+  label_news_view_all: ÐŸÐ¾Ð´Ð¸Ð²Ð¸Ñ‚Ð¸ÑÑ Ð²ÑÑ– Ð½Ð¾Ð²Ð¸Ð½Ð¸
+  label_settings: ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ
+  label_overview: ÐŸÐµÑ€ÐµÐ³Ð»ÑÐ´
+  label_version: Ð’ÐµÑ€ÑÑ–Ñ
+  label_version_new: ÐÐ¾Ð²Ð° Ð²ÐµÑ€ÑÑ–Ñ
+  label_version_plural: Ð’ÐµÑ€ÑÑ–Ñ—
+  label_confirmation: ÐŸÑ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ
+  label_export_to: Ð•ÐºÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸ Ð²
+  label_read: Ð§Ð¸Ñ‚Ð°Ð½Ð½Ñ...
+  label_public_projects: ÐŸÑƒÐ±Ð»Ñ–Ñ‡Ð½Ñ– Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_open_issues: Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ðµ
+  label_open_issues_plural: Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ–
+  label_closed_issues: Ð·Ð°ÐºÑ€Ð¸Ñ‚Ðµ
+  label_closed_issues_plural: Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ–
+  label_x_open_issues_abbr_on_total:
+    zero:  0 open / %{total}
+    one:   1 open / %{total}
+    other: "%{count} open / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 open
+    one:   1 open
+    other: "%{count} open"
+  label_x_closed_issues_abbr:
+    zero:  0 closed
+    one:   1 closed
+    other: "%{count} closed"
+  label_total: Ð’ÑÑŒÐ¾Ð³Ð¾
+  label_permissions: ÐŸÑ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ
+  label_current_status: ÐŸÐ¾Ñ‚Ð¾Ñ‡Ð½Ð¸Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_new_statuses_allowed: Ð”Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ñ– Ð½Ð¾Ð²Ñ– ÑÑ‚Ð°Ñ‚ÑƒÑÐ¸
+  label_all: Ð£ÑÑ–
+  label_none: ÐÑ–ÐºÐ¾Ð¼Ñƒ
+  label_nobody: ÐÑ–Ñ…Ñ‚Ð¾
+  label_next: ÐÐ°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ð¹
+  label_previous: ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ–Ð¹
+  label_used_by: Ð’Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð¾Ð²ÑƒÑ”Ñ‚ÑŒÑÑ
+  label_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð¸Ñ†Ñ–
+  label_add_note: Ð”Ð¾Ð´Ð°Ñ‚Ð¸ Ð·Ð°ÑƒÐ²Ð°Ð¶ÐµÐ½Ð½Ñ
+  label_per_page: ÐÐ° ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÑƒ
+  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€
+  label_months_from: Ð¼Ñ–ÑÑÑ†Ñ–Ð²(Ñ†Ñ) Ð·
+  label_gantt: Ð”Ñ–Ð°Ð³Ñ€Ð°Ð¼Ð° Ð“Ð°Ð½Ñ‚Ð°
+  label_internal: Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ–Ð¹
+  label_last_changes: "Ð¾ÑÑ‚Ð°Ð½Ð½Ñ– %{count} Ð·Ð¼Ñ–Ð½"
+  label_change_view_all: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸ Ð²ÑÑ– Ð·Ð¼Ñ–Ð½Ð¸
+  label_personalize_page: ÐŸÐµÑ€ÑÐ¾Ð½Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ Ñ†ÑŽ ÑÑ‚Ð¾Ñ€Ñ–Ð½ÐºÑƒ
+  label_comment: ÐšÐ¾Ð¼ÐµÐ½Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸
+  label_comment_plural: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ–
+  label_x_comments:
+    zero: no comments
+    one: 1 comment
+    other: "%{count} comments"
+  label_comment_add: Ð—Ð°Ð»Ð¸ÑˆÐ¸Ñ‚Ð¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€
+  label_comment_added: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€ Ð´Ð¾Ð´Ð°Ð½Ð¾
+  label_comment_delete: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ–
+  label_query: Ð—Ð°Ð¿Ð¸Ñ‚ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ð°
+  label_query_plural: Ð—Ð°Ð¿Ð¸Ñ‚Ð¸ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ñ–Ð²
+  label_query_new: ÐÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ‚
+  label_filter_add: Ð”Ð¾Ð´Ð°Ñ‚Ð¸ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€
+  label_filter_plural: Ð¤Ñ–Ð»ÑŒÑ‚Ñ€Ð¸
+  label_equals: Ñ”
+  label_not_equals: Ð½ÐµÐ¼Ð°Ñ”
+  label_in_less_than: Ð¼ÐµÐ½Ñˆ Ð½Ñ–Ð¶
+  label_in_more_than: Ð±Ñ–Ð»ÑŒÑˆ Ð½Ñ–Ð¶
+  label_in: Ñƒ
+  label_today: ÑÑŒÐ¾Ð³Ð¾Ð´Ð½Ñ–
+  label_this_week: Ñ†ÑŒÐ¾Ð³Ð¾ Ñ‚Ð¸Ð¶Ð½Ñ
+  label_less_than_ago: Ð¼ÐµÐ½Ñˆ Ð½Ñ–Ð¶ Ð´Ð½Ñ–Ð²(Ñ) Ð½Ð°Ð·Ð°Ð´
+  label_more_than_ago: Ð±Ñ–Ð»ÑŒÑˆ Ð½Ñ–Ð¶ Ð´Ð½Ñ–Ð²(Ñ) Ð½Ð°Ð·Ð°Ð´
+  label_ago: Ð´Ð½Ñ–Ð²(Ñ) Ð½Ð°Ð·Ð°Ð´
+  label_contains: Ð¼Ñ–ÑÑ‚Ð¸Ñ‚ÑŒ
+  label_not_contains: Ð½Ðµ Ð¼Ñ–ÑÑ‚Ð¸Ñ‚ÑŒ
+  label_day_plural: Ð´Ð½Ñ–Ð²(Ñ)
+  label_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ð¹
+  label_browse: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸
+  label_revision: Ð’ÐµÑ€ÑÑ–Ñ
+  label_revision_plural: Ð’ÐµÑ€ÑÑ–Ð¹
+  label_added: Ð´Ð¾Ð´Ð°Ð½Ð¾
+  label_modified: Ð·Ð¼Ñ–Ð½ÐµÐ½Ðµ
+  label_deleted: Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð¾
+  label_latest_revision: ÐžÑÑ‚Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñ
+  label_latest_revision_plural: ÐžÑÑ‚Ð°Ð½Ð½Ñ– Ð²ÐµÑ€ÑÑ–Ñ—
+  label_view_revisions: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸ Ð²ÐµÑ€ÑÑ–Ñ—
+  label_max_size: ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¸Ð¹ Ñ€Ð¾Ð·Ð¼Ñ–Ñ€
+  label_sort_highest: Ð£ Ð¿Ð¾Ñ‡Ð°Ñ‚Ð¾Ðº
+  label_sort_higher: Ð’Ð³Ð¾Ñ€Ñƒ
+  label_sort_lower: Ð’Ð½Ð¸Ð·
+  label_sort_lowest: Ð£ ÐºÑ–Ð½ÐµÑ†ÑŒ
+  label_roadmap: ÐžÐ¿ÐµÑ€Ð°Ñ‚Ð¸Ð²Ð½Ð¸Ð¹ Ð¿Ð»Ð°Ð½
+  label_roadmap_due_in: "Ð¡Ñ‚Ñ€Ð¾Ðº %{value}"
+  label_roadmap_overdue: "%{value} Ð·Ð°Ð¿Ñ–Ð·Ð½ÐµÐ½Ð½Ñ"
+  label_roadmap_no_issues: ÐÐµÐ¼Ð°Ñ” Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ Ð´Ð»Ñ Ð´Ð°Ð½Ð¾Ñ— Ð²ÐµÑ€ÑÑ–Ñ—
+  label_search: ÐŸÐ¾ÑˆÑƒÐº
+  label_result_plural: Ð ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¸
+  label_all_words: Ð’ÑÑ– ÑÐ»Ð¾Ð²Ð°
+  label_wiki: Wiki
+  label_wiki_edit: Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Wiki
+  label_wiki_edit_plural: Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Wiki
+  label_wiki_page: Ð¡Ñ‚Ð¾Ñ€Ñ–Ð½ÐºÐ° Wiki
+  label_wiki_page_plural: Ð¡Ñ‚Ð¾Ñ€Ñ–Ð½ÐºÐ¸ Wiki
+  label_index_by_title: Ð†Ð½Ð´ÐµÐºÑ Ð·Ð° Ð½Ð°Ð·Ð²Ð¾ÑŽ
+  label_index_by_date: Ð†Ð½Ð´ÐµÐºÑ Ð·Ð° Ð´Ð°Ñ‚Ð¾ÑŽ
+  label_current_version: ÐŸÐ¾Ñ‚Ð¾Ñ‡Ð½Ð° Ð²ÐµÑ€ÑÑ–Ñ
+  label_preview: ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ–Ð¹ Ð¿ÐµÑ€ÐµÐ³Ð»ÑÐ´
+  label_feed_plural: ÐŸÐ¾Ð´Ð°Ð½Ð½Ñ
+  label_changes_details: ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð¸Ñ†Ñ– Ð¿Ð¾ Ð²ÑÑ–Ñ… Ð·Ð¼Ñ–Ð½Ð°Ñ…
+  label_issue_tracking: ÐšÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ†Ñ–Ñ Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
+  label_spent_time: Ð’Ð¸Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð¸Ð¹ Ñ‡Ð°Ñ
+  label_f_hour: "%{value} Ð³Ð¾Ð´Ð¸Ð½Ð°"
+  label_f_hour_plural: "%{value} Ð³Ð¾Ð´Ð¸Ð½(Ð¸)"
+  label_time_tracking: ÐžÐ±Ð»Ñ–Ðº Ñ‡Ð°ÑÑƒ
+  label_change_plural: Ð—Ð¼Ñ–Ð½Ð¸
+  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸ÐºÐ°
+  label_commits_per_month: ÐŸÐ¾Ð´Ð°Ð½ÑŒ Ð½Ð° Ð¼Ñ–ÑÑÑ†ÑŒ
+  label_commits_per_author: ÐŸÐ¾Ð´Ð°Ð½ÑŒ Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð°
+  label_view_diff: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸ Ð²Ñ–Ð´Ð¼Ñ–Ð½Ð½Ð¾ÑÑ‚Ñ–
+  label_diff_inline: Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹
+  label_diff_side_by_side: Ð¿Ð¾Ñ€ÑÐ´
+  label_options: ÐžÐ¿Ñ†Ñ–Ñ—
+  label_copy_workflow_from: Ð¡ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ñ‚Ð¸ Ð¿Ð¾ÑÐ»Ñ–Ð´Ð¾Ð²Ð½Ñ–ÑÑ‚ÑŒ Ð´Ñ–Ð¹ Ð·
+  label_permissions_report: Ð—Ð²Ñ–Ñ‚ Ð¿Ñ€Ð¾ Ð¿Ñ€Ð°Ð²Ð° Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ
+  label_watched_issues: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
+  label_related_issues: Ð—Ð²'ÑÐ·Ð°Ð½Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
+  label_applied_status: Ð—Ð°ÑÑ‚Ð¾ÑÐ¾Ð²Ð½Ð¸Ð¹ ÑÑ‚Ð°Ñ‚ÑƒÑ
+  label_loading: Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ...
+  label_relation_new: ÐÐ¾Ð²Ð¸Ð¹ Ð·Ð²'ÑÐ·Ð¾Ðº
+  label_relation_delete: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ð·Ð²'ÑÐ·Ð¾Ðº
+  label_relates_to: Ð¿Ð¾Ð²'ÑÐ·Ð°Ð½Ðµ Ð·
+  label_duplicates: Ð´ÑƒÐ±Ð»ÑŽÑ”
+  label_blocks: Ð±Ð»Ð¾ÐºÑƒÑ”
+  label_blocked_by: Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ðµ
+  label_precedes: Ð¿ÐµÑ€ÐµÐ´ÑƒÑ”
+  label_follows: Ð½Ð°ÑÑ‚ÑƒÐ¿Ð½Ð¸Ð¹ Ð·Ð°
+  label_end_to_start: Ð· ÐºÑ–Ð½Ñ†Ñ Ð´Ð¾ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ
+  label_end_to_end: Ð· ÐºÑ–Ð½Ñ†Ñ Ð´Ð¾ ÐºÑ–Ð½Ñ†Ñ
+  label_start_to_start: Ð· Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ Ð´Ð¾ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ
+  label_start_to_end: Ð· Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ Ð´Ð¾ ÐºÑ–Ð½Ñ†Ñ
+  label_stay_logged_in: Ð—Ð°Ð»Ð¸ÑˆÐ°Ñ‚Ð¸ÑÑ Ð² ÑÐ¸ÑÑ‚ÐµÐ¼Ñ–
+  label_disabled: Ð²Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹
+  label_show_completed_versions: ÐŸÐ¾ÐºÐ°Ð·Ð°Ñ‚Ð¸ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ñ– Ð²ÐµÑ€ÑÑ–Ñ—
+  label_me: Ð¼ÐµÐ½Ðµ
+  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
+  label_board_new: ÐÐ¾Ð²Ð¸Ð¹ Ñ„Ð¾Ñ€ÑƒÐ¼
+  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼Ð¸
+  label_topic_plural: Ð¢ÐµÐ¼Ð¸
+  label_message_plural: ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ
+  label_message_last: ÐžÑÑ‚Ð°Ð½Ð½Ñ” Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ
+  label_message_new: ÐÐ¾Ð²Ðµ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ
+  label_reply_plural: Ð’Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ñ–
+  label_send_information: Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡ÐµÐ²Ñ– Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–ÑŽ Ð· Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ
+  label_year: Ð Ñ–Ðº
+  label_month: ÐœÑ–ÑÑÑ†ÑŒ
+  label_week: ÐÐµÐ´Ñ–Ð»Ñ
+  label_date_from: Ð—
+  label_date_to: ÐšÐ¾Ð¼Ñƒ
+  label_language_based: ÐÐ° Ð¾ÑÐ½Ð¾Ð²Ñ– Ð¼Ð¾Ð²Ð¸ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð°
+  label_sort_by: "Ð¡Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸ Ð·Ð° %{value}"
+  label_send_test_email: ÐŸÐ¾ÑÐ»Ð°Ñ‚Ð¸ email Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸
+  label_feeds_access_key_created_on: "ÐšÐ»ÑŽÑ‡ Ð´Ð¾ÑÑ‚ÑƒÐ¿Ñƒ RSS ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð¸Ð¹ %{value} Ð½Ð°Ð·Ð°Ð´ "
+  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ñ–
+  label_added_time_by: "Ð”Ð¾Ð´Ð°Ð½Ð¸Ð¹ %{author} %{age} Ð½Ð°Ð·Ð°Ð´"
+  label_updated_time: "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¹ %{value} Ð½Ð°Ð·Ð°Ð´"
+  label_jump_to_a_project: ÐŸÐµÑ€ÐµÐ¹Ñ‚Ð¸ Ð´Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ...
+  label_file_plural: Ð¤Ð°Ð¹Ð»Ð¸
+  label_changeset_plural: ÐÐ°Ð±Ð¾Ñ€Ð¸ Ð·Ð¼Ñ–Ð½
+  label_default_columns: Ð¢Ð¸Ð¿Ð¾Ð²Ñ– ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸
+  label_no_change_option: (ÐÐµÐ¼Ð°Ñ” Ð·Ð¼Ñ–Ð½)
+  label_bulk_edit_selected_issues: Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸ Ð²ÑÑ– Ð²Ð¸Ð±Ñ€Ð°Ð½Ñ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ
+  label_theme: Ð¢ÐµÐ¼Ð°
+  label_default: Ð¢Ð¸Ð¿Ð¾Ð²Ð¸Ð¹
+  label_search_titles_only: Ð¨ÑƒÐºÐ°Ñ‚Ð¸ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ð² Ð½Ð°Ð·Ð²Ð°Ñ…
+  label_user_mail_option_all: "Ð”Ð»Ñ Ð²ÑÑ–Ñ… Ð¿Ð¾Ð´Ñ–Ð¹ Ñƒ Ð²ÑÑ–Ñ… Ð¼Ð¾Ñ—Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ñ…"
+  label_user_mail_option_selected: "Ð”Ð»Ñ Ð²ÑÑ–Ñ… Ð¿Ð¾Ð´Ñ–Ð¹ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ñƒ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð¼Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ–..."
+  label_user_mail_no_self_notified: "ÐÐµ ÑÐ¿Ð¾Ð²Ñ–Ñ‰Ð°Ñ‚Ð¸ Ð¿Ñ€Ð¾ Ð·Ð¼Ñ–Ð½Ð¸, ÑÐºÑ– Ñ Ð·Ñ€Ð¾Ð±Ð¸Ð² ÑÐ°Ð¼"
+  label_registration_activation_by_email: Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ Ð¿Ð¾ÑˆÑ‚Ð¾ÑŽ
+  label_registration_manual_activation: Ñ€ÑƒÑ‡Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ
+  label_registration_automatic_activation: Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ð±Ð»Ñ‹ÐºÐ¾Ð²Ð¾Ð³Ð¾
+  label_my_time_report: ÐœÑ–Ð¹ Ð·Ð²Ñ–Ñ‚ Ð²Ð¸Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ Ñ‡Ð°ÑÑƒ
+
+  button_login: Ð’Ñ…Ñ–Ð´
+  button_submit: Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸
+  button_save: Ð—Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸
+  button_check_all: Ð’Ñ–Ð´Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ Ð²ÑÐµ
+  button_uncheck_all: ÐžÑ‡Ð¸ÑÑ‚Ð¸Ñ‚Ð¸
+  button_delete: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸
+  button_create: Ð¡Ñ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸
+  button_test: ÐŸÐµÑ€ÐµÐ²Ñ–Ñ€Ð¸Ñ‚Ð¸
+  button_edit: Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸
+  button_add: Ð”Ð¾Ð´Ð°Ñ‚Ð¸
+  button_change: Ð—Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸
+  button_apply: Ð—Ð°ÑÑ‚Ð¾ÑÑƒÐ²Ð°Ñ‚Ð¸
+  button_clear: ÐžÑ‡Ð¸ÑÑ‚Ð¸Ñ‚Ð¸
+  button_lock: Ð—Ð°Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ñ‚Ð¸
+  button_unlock: Ð Ð°Ð·Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ñ‚Ð¸
+  button_download: Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸
+  button_list: Ð¡Ð¿Ð¸ÑÐ¾Ðº
+  button_view: ÐŸÐµÑ€ÐµÐ³Ð»ÑÐ½ÑƒÑ‚Ð¸
+  button_move: ÐŸÐµÑ€ÐµÐ¼Ñ–ÑÑ‚Ð¸Ñ‚Ð¸
+  button_back: ÐÐ°Ð·Ð°Ð´
+  button_cancel: Ð’Ñ–Ð´Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸
+  button_activate: ÐÐºÑ‚Ð¸Ð²ÑƒÐ²Ð°Ñ‚Ð¸
+  button_sort: Ð¡Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸
+  button_log_time: Ð—Ð°Ð¿Ð¸ÑÐ°Ñ‚Ð¸ Ñ‡Ð°Ñ
+  button_rollback: Ð’Ñ–Ð´ÐºÐ¾Ñ‚Ð¸Ñ‚Ð¸ Ð´Ð¾ Ð´Ð°Ð½Ð¾Ñ— Ð²ÐµÑ€ÑÑ–Ñ—
+  button_watch: Ð”Ð¸Ð²Ð¸Ñ‚Ð¸ÑÑ
+  button_unwatch: ÐÐµ Ð´Ð¸Ð²Ð¸Ñ‚Ð¸ÑÑ
+  button_reply: Ð’Ñ–Ð´Ð¿Ð¾Ð²Ñ–ÑÑ‚Ð¸
+  button_archive: ÐÑ€Ñ…Ñ–Ð²ÑƒÐ²Ð°Ñ‚Ð¸
+  button_unarchive: Ð Ð¾Ð·Ð°Ñ€Ñ…Ñ–Ð²ÑƒÐ²Ð°Ñ‚Ð¸
+  button_reset: ÐŸÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑÑ‚Ð¸Ñ‚Ð¸
+  button_rename: ÐŸÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸
+  button_change_password: Ð—Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ
+  button_copy: ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ñ‚Ð¸
+  button_annotate: ÐÐ½Ð¾Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸
+
+  status_active: ÐÐºÑ‚Ð¸Ð²Ð½Ð¸Ð¹
+  status_registered: Ð—Ð°Ñ€ÐµÑ”ÑÑ‚Ñ€Ð¾Ð²Ð°Ð½Ð¸Ð¹
+  status_locked: Ð—Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð¸Ð¹
+
+  text_select_mail_notifications: Ð’Ð¸Ð±ÐµÑ€Ñ–Ñ‚ÑŒ Ð´Ñ–Ñ—, Ð½Ð° ÑÐºÑ– Ð²Ñ–Ð´ÑÐ¸Ð»Ð°Ñ‚Ð¸Ð¼ÐµÑ‚ÑŒÑÑ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð½Ð° ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ñƒ Ð¿Ð¾ÑˆÑ‚Ñƒ.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 Ð¾Ð·Ð½Ð°Ñ‡Ð°Ñ” Ð²Ñ–Ð´ÑÑƒÑ‚Ð½Ñ–ÑÑ‚ÑŒ Ð·Ð°Ð±Ð¾Ñ€Ð¾Ð½
+  text_project_destroy_confirmation: Ð’Ð¸ Ð½Ð°Ð¿Ð¾Ð»ÑÐ³Ð°Ñ”Ñ‚Ðµ Ð½Ð° Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ– Ñ†ÑŒÐ¾Ð³Ð¾ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ Ñ– Ð²ÑÑ–Ñ”Ñ— Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ—, Ñ‰Ð¾ Ð²Ñ–Ð´Ð½Ð¾ÑÐ¸Ñ‚ÑŒÑÑ Ð´Ð¾ Ð½ÑŒÐ¾Ð³Ð¾?
+  text_workflow_edit: Ð’Ð¸Ð±ÐµÑ€Ñ–Ñ‚ÑŒ Ñ€Ð¾Ð»ÑŒ Ñ– ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€ Ð´Ð»Ñ Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÑÐ»Ñ–Ð´Ð¾Ð²Ð½Ð¾ÑÑ‚Ñ– Ð´Ñ–Ð¹
+  text_are_you_sure: Ð’Ð¸ Ð²Ð¿ÐµÐ²Ð½ÐµÐ½Ñ–?
+  text_tip_issue_begin_day: Ð´ÐµÐ½ÑŒ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ Ð·Ð°Ð´Ð°Ñ‡Ñ–
+  text_tip_issue_end_day: Ð´ÐµÐ½ÑŒ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ñ‡Ñ–
+  text_tip_issue_begin_end_day: Ð¿Ð¾Ñ‡Ð°Ñ‚Ð¾Ðº Ð·Ð°Ð´Ð°Ñ‡Ñ– Ñ– Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ð´Ð½Ñ
+  text_caracters_maximum: "%{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ–Ð²(Ð°) Ð¼Ð°ÐºÑÐ¸Ð¼ÑƒÐ¼."
+  text_caracters_minimum: "ÐŸÐ¾Ð²Ð¸Ð½Ð½Ð¾ Ð¼Ð°Ñ‚Ð¸ ÑÐºÐ½Ð°Ð¹Ð¼ÐµÐ½ÑˆÐµ  %{count} ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ–Ð²(Ð°) Ñƒ Ð´Ð¾Ð²Ð¶Ð¸Ð½Ñƒ."
+  text_length_between: "Ð”Ð¾Ð²Ð¶Ð¸Ð½Ð° Ð¼Ñ–Ð¶ %{min} Ñ– %{max} ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ–Ð²."
+  text_tracker_no_workflow: Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð¾Ñ€Ð° Ð¿Ð¾ÑÐ»Ñ–Ð´Ð¾Ð²Ð½Ñ–ÑÑ‚ÑŒ Ð´Ñ–Ð¹ Ð½Ðµ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð°
+  text_unallowed_characters: Ð—Ð°Ð±Ð¾Ñ€Ð¾Ð½ÐµÐ½Ñ– ÑÐ¸Ð¼Ð²Ð¾Ð»Ð¸
+  text_comma_separated: Ð”Ð¾Ð¿ÑƒÑÑ‚Ð¸Ð¼Ñ– Ð´ÐµÐºÑ–Ð»ÑŒÐºÐ° Ð·Ð½Ð°Ñ‡ÐµÐ½ÑŒ (Ñ€Ð¾Ð·Ð´Ñ–Ð»ÐµÐ½Ñ– ÐºÐ¾Ð¼Ð¾ÑŽ).
+  text_issues_ref_in_commit_messages: ÐŸÐ¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñ‚Ð° Ð·Ð¼Ñ–Ð½Ð° Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ Ñƒ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½ÑÑ… Ð´Ð¾ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½ÑŒ
+  text_issue_added: "Issue %{id} has been reported by %{author}."
+  text_issue_updated: "Issue %{id} has been updated by %{author}."
+  text_wiki_destroy_confirmation: Ð’Ð¸ Ð²Ð¿ÐµÐ²Ð½ÐµÐ½Ñ–, Ñ‰Ð¾ Ñ…Ð¾Ñ‡ÐµÑ‚Ðµ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ñ†ÑŽ wiki Ñ– Ð²ÐµÑÑŒ Ð·Ð¼Ñ–ÑÑ‚?
+  text_issue_category_destroy_question: "Ð”ÐµÐºÑ–Ð»ÑŒÐºÐ° Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ (%{count}) Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾ Ð² Ñ†ÑŽ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–ÑŽ. Ð©Ð¾ Ð²Ð¸ Ñ…Ð¾Ñ‡ÐµÑ‚Ðµ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸?"
+  text_issue_category_destroy_assignments: Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ—
+  text_issue_category_reassign_to: ÐŸÐµÑ€ÐµÐ¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ Ð·Ð°Ð´Ð°Ñ‡Ñ– Ð´Ð¾ Ð´Ð°Ð½Ð¾Ñ— ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ—
+  text_user_mail_option: "Ð”Ð»Ñ Ð½ÐµÐ²Ð¸Ð±Ñ€Ð°Ð½Ð¸Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñ–Ð² Ð²Ð¸ Ð¾Ñ‚Ñ€Ð¸Ð¼ÑƒÐ²Ð°Ñ‚Ð¸Ð¼ÐµÑ‚Ðµ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ð¿Ñ€Ð¾ Ñ‚Ðµ, Ñ‰Ð¾ Ð¿Ñ€Ð¾Ð³Ð»ÑÐ´Ð°Ñ”Ñ‚Ðµ Ð°Ð±Ð¾ Ð² Ñ‡Ð¾Ð¼Ñƒ Ð±ÐµÑ€ÐµÑ‚Ðµ ÑƒÑ‡Ð°ÑÑ‚ÑŒ (Ð½Ð°Ð¿Ñ€Ð¸ÐºÐ»Ð°Ð´, Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼ ÑÐºÐ¸Ñ… Ð²Ð¸ Ñ” Ð°Ð±Ð¾ ÑÐºÑ– Ð²Ð°Ð¼ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ñ–)."
+
+  default_role_manager: ÐœÐµÐ½ÐµÐ´Ð¶ÐµÑ€
+  default_role_developer: Ð Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸Ðº
+  default_role_reporter: Ð ÐµÐ¿Ð¾Ñ€Ñ‚ÐµÑ€
+  # default_tracker_bug: Bug
+  # Ð·Ð²Ñ–Ñ‚Ñ–Ð² default_tracker_bug: ÐŸÐ¾Ð¼Ð¸Ð»ÐºÐ°
+  default_tracker_bug: ÐŸÐ¾Ð¼Ð¸Ð»ÐºÐ°
+  default_tracker_feature: Ð’Ð»Ð°ÑÑ‚Ð¸Ð²Ñ–ÑÑ‚ÑŒ
+  default_tracker_support: ÐŸÑ–Ð´Ñ‚Ñ€Ð¸Ð¼ÐºÐ°
+  default_issue_status_new: ÐÐ¾Ð²Ð¸Ð¹
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: Ð’Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð¾
+  default_issue_status_feedback: Ð—Ð²Ð¾Ñ€Ð¾Ñ‚Ð½Ð¸Ð¹ Ð·Ð²'ÑÐ·Ð¾Ðº
+  default_issue_status_closed: Ð—Ð°Ñ‡Ð¸Ð½ÐµÐ½Ð¾
+  default_issue_status_rejected: Ð’Ñ–Ð´Ð¼Ð¾Ð²Ð»ÐµÐ½Ð¾
+  default_doc_category_user: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð°
+  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ñ–Ñ‡Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ
+  default_priority_low: ÐÐ¸Ð·ÑŒÐºÐ¸Ð¹
+  default_priority_normal: ÐÐ¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ð¸Ð¹
+  default_priority_high: Ð’Ð¸ÑÐ¾ÐºÐ¸Ð¹
+  default_priority_urgent: Ð¢ÐµÑ€Ð¼Ñ–Ð½Ð¾Ð²Ð¸Ð¹
+  default_priority_immediate: ÐÐµÐ³Ð°Ð¹Ð½Ð¸Ð¹
+  default_activity_design: ÐŸÑ€Ð¾ÐµÐºÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ
+  default_activity_development: Ð Ð¾Ð·Ñ€Ð¾Ð±ÐºÐ°
+
+  enumeration_issue_priorities: ÐŸÑ€Ñ–Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¸ Ð¿Ð¸Ñ‚Ð°Ð½ÑŒ
+  enumeration_doc_categories: ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ— Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ–Ð²
+  enumeration_activities: Ð”Ñ–Ñ— (Ð¾Ð±Ð»Ñ–Ðº Ñ‡Ð°ÑÑƒ)
+  text_status_changed_by_changeset: "Applied in changeset %{value}."
+  label_display_per_page: "Per page: %{value}"
+  label_issue_added: Issue added
+  label_issue_updated: Issue updated
+  setting_per_page_options: Objects per page options
+  notice_default_data_loaded: Default configuration successfully loaded.
+  error_scm_not_found: "Entry and/or revision doesn't exist in the repository."
+  label_associated_revisions: Associated revisions
+  label_document_added: Document added
+  label_message_posted: Message added
+  text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s) ?'
+  error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
+  setting_user_format: Users display format
+  label_age: Age
+  label_file_added: File added
+  label_more: More
+  field_default_value: Default value
+  label_scm: SCM
+  label_general: General
+  button_update: Update
+  text_select_project_modules: 'Select modules to enable for this project:'
+  label_change_properties: Change properties
+  text_load_default_configuration: Load the default configuration
+  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
+  label_news_added: News added
+  label_repository_plural: Repositories
+  error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
+  project_module_boards: Boards
+  project_module_issue_tracking: Issue tracking
+  project_module_wiki: Wiki
+  project_module_files: Files
+  project_module_documents: Documents
+  project_module_repository: Repository
+  project_module_news: News
+  project_module_time_tracking: Time tracking
+  text_file_repository_writable: File repository writable
+  text_default_administrator_account_changed: Default administrator account changed
+  text_rmagick_available: RMagick available (optional)
+  button_configure: Configure
+  label_plugins: Plugins
+  label_ldap_authentication: LDAP authentication
+  label_downloads_abbr: D/L
+  label_this_month: this month
+  label_last_n_days: "last %{count} days"
+  label_all_time: all time
+  label_this_year: this year
+  label_date_range: Date range
+  label_last_week: last week
+  label_yesterday: yesterday
+  label_last_month: last month
+  label_add_another_file: Add another file
+  label_optional_description: Optional description
+  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do ?"
+  error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
+  text_assign_time_entries_to_project: Assign reported hours to the project
+  text_destroy_time_entries: Delete reported hours
+  text_reassign_time_entries: 'Reassign reported hours to this issue:'
+  setting_activity_days_default: Days displayed on project activity
+  label_chronological_order: In chronological order
+  field_comments_sorting: Display comments
+  label_reverse_chronological_order: In reverse chronological order
+  label_preferences: Preferences
+  setting_display_subprojects_issues: Display subprojects issues on main projects by default
+  label_overall_activity: Overall activity
+  setting_default_projects_public: New projects are public by default
+  error_scm_annotate: "The entry does not exist or can not be annotated."
+  label_planning: Planning
+  text_subprojects_destroy_warning: "Its subproject(s): %{value} will be also deleted."
+  label_and_its_subprojects: "%{value} and its subprojects"
+  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
+  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
+  text_user_wrote: "%{value} wrote:"
+  label_duplicated_by: duplicated by
+  setting_enabled_scm: Enabled SCM
+  text_enumeration_category_reassign_to: 'Reassign them to this value:'
+  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
+  label_incoming_emails: Incoming emails
+  label_generate_key: Generate a key
+  setting_mail_handler_api_enabled: Enable WS for incoming emails
+  setting_mail_handler_api_key: API key
+  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
+  field_parent_title: Parent page
+  label_issue_watchers: Watchers
+  button_quote: Quote
+  setting_sequential_project_identifiers: Generate sequential project identifiers
+  notice_unable_delete_version: Unable to delete version
+  label_renamed: renamed
+  label_copied: copied
+  setting_plain_text_mail: plain text only (no HTML)
+  permission_view_files: View files
+  permission_edit_issues: Edit issues
+  permission_edit_own_time_entries: Edit own time logs
+  permission_manage_public_queries: Manage public queries
+  permission_add_issues: Add issues
+  permission_log_time: Log spent time
+  permission_view_changesets: View changesets
+  permission_view_time_entries: View spent time
+  permission_manage_versions: Manage versions
+  permission_manage_wiki: Manage wiki
+  permission_manage_categories: Manage issue categories
+  permission_protect_wiki_pages: Protect wiki pages
+  permission_comment_news: Comment news
+  permission_delete_messages: Delete messages
+  permission_select_project_modules: Select project modules
+  permission_edit_wiki_pages: Edit wiki pages
+  permission_add_issue_watchers: Add watchers
+  permission_view_gantt: View gantt chart
+  permission_move_issues: Move issues
+  permission_manage_issue_relations: Manage issue relations
+  permission_delete_wiki_pages: Delete wiki pages
+  permission_manage_boards: Manage boards
+  permission_delete_wiki_pages_attachments: Delete attachments
+  permission_view_wiki_edits: View wiki history
+  permission_add_messages: Post messages
+  permission_view_messages: View messages
+  permission_manage_files: Manage files
+  permission_edit_issue_notes: Edit notes
+  permission_manage_news: Manage news
+  permission_view_calendar: View calendrier
+  permission_manage_members: Manage members
+  permission_edit_messages: Edit messages
+  permission_delete_issues: Delete issues
+  permission_view_issue_watchers: View watchers list
+  permission_manage_repository: Manage repository
+  permission_commit_access: Commit access
+  permission_browse_repository: Browse repository
+  permission_view_documents: View documents
+  permission_edit_project: Edit project
+  permission_add_issue_notes: Add notes
+  permission_save_queries: Save queries
+  permission_view_wiki_pages: View wiki
+  permission_rename_wiki_pages: Rename wiki pages
+  permission_edit_time_entries: Edit time logs
+  permission_edit_own_issue_notes: Edit own notes
+  setting_gravatar_enabled: Use Gravatar user icons
+  label_example: Example
+  text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  permission_edit_own_messages: Edit own messages
+  permission_delete_own_messages: Delete own messages
+  label_user_activity: "%{value}'s activity"
+  label_updated_time_by: "Updated by %{author} %{age} ago"
+  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
+  setting_diff_max_lines_displayed: Max number of diff lines displayed
+  text_plugin_assets_writable: Plugin assets directory writable
+  warning_attachments_not_saved: "%{count} file(s) could not be saved."
+  button_create_and_continue: Create and continue
+  text_custom_field_possible_values_info: 'One line for each value'
+  label_display: Display
+  field_editable: Editable
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_file_max_size_displayed: Max size of text files displayed inline
+  field_watcher: Watcher
+  setting_openid: Allow OpenID login and registration
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: or login with OpenID
+  field_content: Content
+  label_descending: Descending
+  label_sort: Sort
+  label_ascending: Ascending
+  label_date_from_to: From %{start} to %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
+  text_wiki_page_reassign_children: Reassign child pages to this parent page
+  text_wiki_page_nullify_children: Keep child pages as root pages
+  text_wiki_page_destroy_children: Delete child pages and all their descendants
+  setting_password_min_length: Minimum password length
+  field_group_by: Group results by
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  label_wiki_content_added: Wiki page added
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
+  label_wiki_content_updated: Wiki page updated
+  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
+  permission_add_project: Create project
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  label_view_all_revisions: View all revisions
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
+  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
+  text_journal_changed: "%{label} changed from %{old} to %{new}"
+  text_journal_set_to: "%{label} set to %{value}"
+  text_journal_deleted: "%{label} deleted (%{old})"
+  label_group_plural: Groups
+  label_group: Group
+  label_group_new: New group
+  label_time_entry_plural: Spent time
+  text_journal_added: "%{label} %{value} added"
+  field_active: Active
+  enumeration_system_activity: System Activity
+  permission_delete_issue_watchers: Delete watchers
+  version_status_closed: closed
+  version_status_locked: locked
+  version_status_open: open
+  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
+  label_user_anonymous: Anonymous
+  button_move_and_follow: Move and follow
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_gravatar_default: Default Gravatar image
+  field_sharing: Sharing
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_system: With all projects
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_tree: With project tree
+  label_version_sharing_none: Not shared
+  error_can_not_archive_project: This project can not be archived
+  button_duplicate: Duplicate
+  button_copy_and_follow: Copy and follow
+  label_copy_source: Source
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_status: Use the issue status
+  error_issue_done_ratios_not_updated: Issue done ratios not updated.
+  error_workflow_copy_target: Please select target tracker(s) and role(s)
+  setting_issue_done_ratio_issue_field: Use the issue field
+  label_copy_same_as_target: Same as target
+  label_copy_target: Target
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  error_workflow_copy_source: Please select a source tracker or role
+  label_update_issue_done_ratios: Update issue done ratios
+  setting_start_of_week: Start calendars on
+  permission_view_issues: View Issues
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_revision_id: Revision %{value}
+  label_api_access_key: API access key
+  label_api_access_key_created_on: API access key created %{value} ago
+  label_feeds_access_key: RSS access key
+  notice_api_access_key_reseted: Your API access key was reset.
+  setting_rest_api_enabled: Enable REST web service
+  label_missing_api_access_key: Missing an API access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  button_show: Show
+  text_line_separated: Multiple values allowed (one line for each value).
+  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
+  permission_add_subprojects: Create subprojects
+  label_subproject_new: New subproject
+  text_own_membership_delete_confirmation: |-
+    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
+    Are you sure you want to continue?
+  label_close_versions: Close completed versions
+  label_board_sticky: Sticky
+  label_board_locked: Locked
+  permission_export_wiki_pages: Export wiki pages
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: Manage project activities
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_profile: Profile
+  permission_manage_subtasks: Manage subtasks
+  field_parent_issue: Parent task
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Commit messages encoding
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ
+    one:   1 ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ
+    other: "%{count} ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: "Ð’Ð°Ñˆ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ñ–Ð¹ Ð·Ð°Ð¿Ð¸Ñ Ð¿Ð¾Ð²Ð½Ñ–ÑÑ‚ÑŽ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð¸Ð¹" 
+  setting_unsubscribe: "Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ‚Ð¸ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð°Ð¼ Ð²Ð¸Ð´Ð°Ð»ÑÑ‚Ð¸ ÑÐ²Ð¾Ñ— Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ñ– Ð·Ð°Ð¿Ð¸ÑÐ¸" 
+  button_delete_my_account: "Ð’Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Ð¼Ñ–Ð¹ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ" 
+  text_account_destroy_confirmation: "Ð’Ð°Ñˆ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ Ð±ÑƒÐ´Ðµ Ð¿Ð¾Ð²Ð½Ñ–ÑÑ‚ÑŽ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð¸Ð¹ Ð±ÐµÐ· Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑ‚Ñ– Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ.\nÐ’Ð¸ Ð¿ÐµÐ²Ð½Ñ–, Ñ‡Ñ‚Ð¾ Ð±Ð°Ð¶Ð°ÐµÑ‚Ðµ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶Ð¸Ñ‚Ð¸?" 
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: Ð£ÑÑ–
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ð’ÑÑŒÐ¾Ð³Ð¾
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a0/a09484e1097f8accbdefa8e7a4676655267614f3.svn-base
--- a/.svn/pristine/a0/a09484e1097f8accbdefa8e7a4676655267614f3.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-class CreateOthers < ActiveRecord::Migration
-  def self.up
-    create_table 'others' do |t|
-      t.column 'name', :string
-    end
-  end
-
-  def self.down
-    drop_table 'others'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a0/a0ccce3410ac9ce9a1553a5a5d9bf73a1ad41f93.svn-base
--- a/.svn/pristine/a0/a0ccce3410ac9ce9a1553a5a5d9bf73a1ad41f93.svn-base
+++ /dev/null
@@ -1,64 +0,0 @@
-<%= error_messages_for 'project' %>
-
-<div class="box">
-<!--[form:project]-->
-<p><%= f.text_field :name, :required => true, :size => 60 %></p>
-
-<% unless @project.allowed_parents.compact.empty? %>
-    <p><%= label(:project, :parent_id, l(:field_parent)) %><%= parent_project_select_tag(@project) %></p>
-<% end %>
-
-<p><%= f.text_area :description, :rows => 5, :class => 'wiki-edit' %></p>
-<p><%= f.text_field :identifier, :required => true, :size => 60, :disabled => @project.identifier_frozen? %>
-<% unless @project.identifier_frozen? %>
-<br /><em><%= l(:text_length_between, :min => 1, :max => Project::IDENTIFIER_MAX_LENGTH) %> <%= l(:text_project_identifier_info).html_safe %></em>
-<% end %></p>
-<p><%= f.text_field :homepage, :size => 60 %></p>
-<p><%= f.check_box :is_public %></p>
-<%= wikitoolbar_for 'project_description' %>
-
-<% @project.custom_field_values.each do |value| %>
-  <p><%= custom_field_tag_with_label :project, value %></p>
-<% end %>
-<%= call_hook(:view_projects_form, :project => @project, :form => f) %>
-</div>
-
-<% if @project.new_record? %>
-<fieldset class="box"><legend><%= l(:label_module_plural) %></legend>
-<% Redmine::AccessControl.available_project_modules.each do |m| %>
-    <label class="floating">
-    <%= check_box_tag 'project[enabled_module_names][]', m, @project.module_enabled?(m), :id => "project_enabled_module_names_#{m}" %>
-    <%= l_or_humanize(m, :prefix => "project_module_") %>
-    </label>
-<% end %>
-<%= hidden_field_tag 'project[enabled_module_names][]', '' %>
-<%= javascript_tag 'observeProjectModules()' %>
-</fieldset>
-<% end %>
-
-<% if @project.new_record? || @project.module_enabled?('issue_tracking') %>
-<% unless @trackers.empty? %>
-<fieldset class="box" id="project_trackers"><legend><%=l(:label_tracker_plural)%></legend>
-<% @trackers.each do |tracker| %>
-    <label class="floating">
-    <%= check_box_tag 'project[tracker_ids][]', tracker.id, @project.trackers.include?(tracker) %>
-    <%=h tracker %>
-    </label>
-<% end %>
-<%= hidden_field_tag 'project[tracker_ids][]', '' %>
-</fieldset>
-<% end %>
-
-<% unless @issue_custom_fields.empty? %>
-<fieldset class="box" id="project_issue_custom_fields"><legend><%=l(:label_custom_field_plural)%></legend>
-<% @issue_custom_fields.each do |custom_field| %>
-    <label class="floating">
-  <%= check_box_tag 'project[issue_custom_field_ids][]', custom_field.id, (@project.all_issue_custom_fields.include? custom_field), (custom_field.is_for_all? ? {:disabled => "disabled"} : {}) %>
-  <%=h custom_field.name %>
-  </label>
-<% end %>
-<%= hidden_field_tag 'project[issue_custom_field_ids][]', '' %>
-</fieldset>
-<% end %>
-<% end %>
-<!--[eoform:project]-->
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a0/a0e32e2a6eec71e9da13861adc671e42ba3333c5.svn-base
--- a/.svn/pristine/a0/a0e32e2a6eec71e9da13861adc671e42ba3333c5.svn-base
+++ /dev/null
@@ -1,153 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'repositories_controller'
-
-# Re-raise errors caught by the controller.
-class RepositoriesController; def rescue_action(e) raise e end; end
-
-class RepositoriesFilesystemControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles,
-           :repositories, :enabled_modules
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/filesystem_repository').to_s
-  PRJ_ID = 3
-
-  def setup
-    @ruby19_non_utf8_pass =
-        (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8')
-    @controller = RepositoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
-    @project = Project.find(PRJ_ID)
-    @repository = Repository::Filesystem.create(
-                      :project       => @project,
-                      :url           => REPOSITORY_PATH,
-                      :path_encoding => ''
-                      )
-    assert @repository
-  end
-
-  if File.directory?(REPOSITORY_PATH)
-    def test_browse_root
-      @repository.fetch_changesets
-      @repository.reload
-      get :show, :id => PRJ_ID
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert assigns(:entries).size > 0
-      assert_not_nil assigns(:changesets)
-      assert assigns(:changesets).size == 0
-    end
-
-    def test_show_no_extension
-      get :entry, :id => PRJ_ID, :path => ['test']
-      assert_response :success
-      assert_template 'entry'
-      assert_tag :tag => 'th',
-                 :content => '1',
-                 :attributes => { :class => 'line-num' },
-                 :sibling => { :tag => 'td', :content => /TEST CAT/ }
-    end
-
-    def test_entry_download_no_extension
-      get :entry, :id => PRJ_ID, :path => ['test'], :format => 'raw'
-      assert_response :success
-      assert_equal 'application/octet-stream', @response.content_type
-    end
-
-    def test_show_non_ascii_contents
-      with_settings :repositories_encodings => 'UTF-8,EUC-JP' do
-        get :entry, :id => PRJ_ID, :path => ['japanese', 'euc-jp.txt']
-        assert_response :success
-        assert_template 'entry'
-        assert_tag :tag => 'th',
-                   :content => '2',
-                   :attributes => { :class => 'line-num' },
-                   :sibling => { :tag => 'td', :content => /japanese/ }
-        if @ruby19_non_utf8_pass
-          puts "TODO: show repository file contents test fails in Ruby 1.9 " +
-               "and Encoding.default_external is not UTF-8. " +
-               "Current value is '#{Encoding.default_external.to_s}'"
-        else
-          str_japanese = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
-          str_japanese.force_encoding('UTF-8') if str_japanese.respond_to?(:force_encoding)
-          assert_tag :tag => 'th',
-                     :content => '3',
-                     :attributes => { :class => 'line-num' },
-                     :sibling => { :tag => 'td', :content => /#{str_japanese}/ }
-        end
-      end
-    end
-
-    def test_show_utf16
-      with_settings :repositories_encodings => 'UTF-16' do
-        get :entry, :id => PRJ_ID, :path => ['japanese', 'utf-16.txt']
-        assert_response :success
-        assert_tag :tag => 'th',
-                   :content => '2',
-                   :attributes => { :class => 'line-num' },
-                   :sibling => { :tag => 'td', :content => /japanese/ }
-      end
-    end
-
-    def test_show_text_file_should_send_if_too_big
-      with_settings :file_max_size_displayed => 1 do
-        get :entry, :id => PRJ_ID, :path => ['japanese', 'big-file.txt']
-        assert_response :success
-        assert_equal 'text/plain', @response.content_type
-      end
-    end
-
-    def test_destroy_valid_repository
-      @request.session[:user_id] = 1 # admin
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-
-    def test_destroy_invalid_repository
-      @request.session[:user_id] = 1 # admin
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-
-      @repository = Repository::Filesystem.create(
-                      :project       => Project.find(PRJ_ID),
-                      :url           => "/invalid",
-                      :path_encoding => ''
-                      )
-      assert @repository
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-  else
-    puts "Filesystem test repository NOT FOUND. Skipping functional tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a1/a15d9bfda43cfa6e2187209eede29e4da50c47f3.svn-base
--- a/.svn/pristine/a1/a15d9bfda43cfa6e2187209eede29e4da50c47f3.svn-base
+++ /dev/null
@@ -1,91 +0,0 @@
-# redMine - project management software
-# Copyright (C) 2006-2007  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Acts
-    module Event
-      def self.included(base)
-        base.extend ClassMethods
-      end
-
-      module ClassMethods
-        def acts_as_event(options = {})
-          return if self.included_modules.include?(Redmine::Acts::Event::InstanceMethods)
-          default_options = { :datetime => :created_on,
-                              :title => :title,
-                              :description => :description,
-                              :author => :author,
-                              :url => {:controller => 'welcome'},
-                              :type => self.name.underscore.dasherize }
-                              
-          cattr_accessor :event_options
-          self.event_options = default_options.merge(options)
-          send :include, Redmine::Acts::Event::InstanceMethods
-        end
-      end
-
-      module InstanceMethods
-        def self.included(base)
-          base.extend ClassMethods
-        end
-        
-        %w(datetime title description author type).each do |attr|
-          src = <<-END_SRC
-            def event_#{attr}
-              option = event_options[:#{attr}]
-              if option.is_a?(Proc)
-                option.call(self)
-              elsif option.is_a?(Symbol)
-                send(option)
-              else
-                option
-              end
-            end
-          END_SRC
-          class_eval src, __FILE__, __LINE__
-        end
-        
-        def event_date
-          event_datetime.to_date
-        end
-        
-        def event_url(options = {})
-          option = event_options[:url]
-          if option.is_a?(Proc)
-            option.call(self).merge(options)
-          elsif option.is_a?(Hash)
-            option.merge(options)
-          elsif option.is_a?(Symbol)
-            send(option).merge(options)
-          else
-            option
-          end
-        end
-
-        # Returns the mail adresses of users that should be notified
-        def recipients
-          notified = project.notified_users
-          notified.reject! {|user| !visible?(user)}
-          notified.collect(&:mail)
-        end
-
-        module ClassMethods
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a1/a15efc0a7b7f938a7d937205168f8739fcc6338f.svn-base
--- /dev/null
+++ b/.svn/pristine/a1/a15efc0a7b7f938a7d937205168f8739fcc6338f.svn-base
@@ -0,0 +1,68 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WikiContentVersionTest < ActiveSupport::TestCase
+  fixtures :projects, :users, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
+
+  def setup
+  end
+
+  def test_destroy
+    v = WikiContent::Version.find(2)
+
+    assert_difference 'WikiContent::Version.count', -1 do
+      v.destroy
+    end
+  end
+
+  def test_destroy_last_version_should_revert_content
+    v = WikiContent::Version.find(3)
+
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_difference 'WikiContent::Version.count', -1 do
+          assert v.destroy
+        end
+      end
+    end
+    c = WikiContent.find(1)
+    v = c.versions.last
+    assert_equal 2, c.version
+    assert_equal v.version, c.version
+    assert_equal v.comments, c.comments
+    assert_equal v.text, c.text
+    assert_equal v.author, c.author
+    assert_equal v.updated_on, c.updated_on
+  end
+
+  def test_destroy_all_versions_should_delete_page
+    WikiContent::Version.find(1).destroy
+    WikiContent::Version.find(2).destroy
+    v = WikiContent::Version.find(3)
+
+    assert_difference 'WikiPage.count', -1 do
+      assert_difference 'WikiContent.count', -1 do
+        assert_difference 'WikiContent::Version.count', -1 do
+          assert v.destroy
+        end
+      end
+    end
+    assert_nil WikiPage.find_by_id(1)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a1/a17cb23221bb655c00d6b0ce4ed2209575037f95.svn-base
--- a/.svn/pristine/a1/a17cb23221bb655c00d6b0ce4ed2209575037f95.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-# Redmine sample plugin
-require 'redmine'
-
-RAILS_DEFAULT_LOGGER.info 'Starting Example plugin for RedMine'
-
-Redmine::Plugin.register :sample_plugin do
-  name 'Example plugin'
-  author 'Author name'
-  description 'This is a sample plugin for Redmine'
-  version '0.0.1'
-  settings :default => {'sample_setting' => 'value', 'foo'=>'bar'}, :partial => 'settings/sample_plugin_settings'
-
-  # This plugin adds a project module
-  # It can be enabled/disabled at project level (Project settings -> Modules)
-  project_module :example_module do
-    # A public action
-    permission :example_say_hello, {:example => [:say_hello]}, :public => true
-    # This permission has to be explicitly given
-    # It will be listed on the permissions screen
-    permission :example_say_goodbye, {:example => [:say_goodbye]}
-    # This permission can be given to project members only
-    permission :view_meetings, {:meetings => [:index, :show]}, :require => :member
-  end
-
-  # A new item is added to the project menu
-  menu :project_menu, :sample_plugin, { :controller => 'example', :action => 'say_hello' }, :caption => 'Sample'
-  
-  # Meetings are added to the activity view
-  activity_provider :meetings
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a1/a17e85541ced0de37f4c279c99198e91fbe8ecd9.svn-base
--- /dev/null
+++ b/.svn/pristine/a1/a17e85541ced0de37f4c279c99198e91fbe8ecd9.svn-base
@@ -0,0 +1,241 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+require 'pp'
+class RepositoryCvsTest < ActiveSupport::TestCase
+  fixtures :projects
+
+  include Redmine::I18n
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s
+  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
+  # CVS module
+  MODULE_NAME    = 'test'
+  CHANGESETS_NUM = 7
+
+  def setup
+    @project = Project.find(3)
+    @repository = Repository::Cvs.create(:project  => @project,
+                                         :root_url => REPOSITORY_PATH,
+                                         :url      => MODULE_NAME,
+                                         :log_encoding => 'UTF-8')
+    assert @repository
+  end
+
+  def test_blank_module_error_message
+    set_language_if_valid 'en'
+    repo = Repository::Cvs.new(
+                          :project      => @project,
+                          :identifier   => 'test',
+                          :log_encoding => 'UTF-8',
+                          :root_url     => REPOSITORY_PATH
+                        )
+    assert !repo.save
+    assert_include "Module can't be blank",
+                   repo.errors.full_messages
+  end
+
+  def test_blank_module_error_message_fr
+    set_language_if_valid 'fr'
+    str = "Module doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    repo = Repository::Cvs.new(
+                          :project       => @project,
+                          :identifier    => 'test',
+                          :log_encoding  => 'UTF-8',
+                          :path_encoding => '',
+                          :url           => '',
+                          :root_url      => REPOSITORY_PATH
+                        )
+    assert !repo.save
+    assert_include str, repo.errors.full_messages
+  end
+
+  def test_blank_cvsroot_error_message
+    set_language_if_valid 'en'
+    repo = Repository::Cvs.new(
+                          :project      => @project,
+                          :identifier   => 'test',
+                          :log_encoding => 'UTF-8',
+                          :url          => MODULE_NAME
+                        )
+    assert !repo.save
+    assert_include "CVSROOT can't be blank",
+                   repo.errors.full_messages
+  end
+
+  def test_blank_cvsroot_error_message_fr
+    set_language_if_valid 'fr'
+    str = "CVSROOT doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    repo = Repository::Cvs.new(
+                          :project       => @project,
+                          :identifier    => 'test',
+                          :log_encoding  => 'UTF-8',
+                          :path_encoding => '',
+                          :url           => MODULE_NAME,
+                          :root_url      => ''
+                        )
+    assert !repo.save
+    assert_include str, repo.errors.full_messages
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    def test_fetch_changesets_from_scratch
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+
+      assert_equal CHANGESETS_NUM, @repository.changesets.count
+      assert_equal 16, @repository.filechanges.count
+      assert_not_nil @repository.changesets.find_by_comments('Two files changed')
+
+      r2 = @repository.changesets.find_by_revision('2')
+      assert_equal 'v1-20071213-162510', r2.scmid
+    end
+
+    def test_fetch_changesets_incremental
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal CHANGESETS_NUM, @repository.changesets.count
+
+      # Remove changesets with revision > 3
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 3}
+      @project.reload
+      assert_equal 3, @repository.changesets.count
+      assert_equal %w|3 2 1|, @repository.changesets.all.collect(&:revision)
+
+      rev3_commit = @repository.changesets.reorder('committed_on DESC').first
+      assert_equal '3', rev3_commit.revision
+       # 2007-12-14 01:27:22 +0900
+      rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
+      assert_equal 'HEAD-20071213-162722', rev3_commit.scmid
+      assert_equal rev3_committed_on, rev3_commit.committed_on
+      latest_rev = @repository.latest_changeset
+      assert_equal rev3_committed_on, latest_rev.committed_on
+
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal CHANGESETS_NUM, @repository.changesets.count
+      assert_equal %w|7 6 5 4 3 2 1|, @repository.changesets.all.collect(&:revision)
+      rev5_commit = @repository.changesets.find_by_revision('5')
+      assert_equal 'HEAD-20071213-163001', rev5_commit.scmid
+       # 2007-12-14 01:30:01 +0900
+      rev5_committed_on = Time.gm(2007, 12, 13, 16, 30, 1)
+      assert_equal rev5_committed_on, rev5_commit.committed_on
+    end
+
+    def test_deleted_files_should_not_be_listed
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal CHANGESETS_NUM, @repository.changesets.count
+
+      entries = @repository.entries('sources')
+      assert entries.detect {|e| e.name == 'watchers_controller.rb'}
+      assert_nil entries.detect {|e| e.name == 'welcome_controller.rb'}
+    end
+
+    def test_entries_rev3
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal CHANGESETS_NUM, @repository.changesets.count
+      entries = @repository.entries('', '3')
+      assert_kind_of Redmine::Scm::Adapters::Entries, entries
+      assert_equal 3, entries.size
+      assert_equal entries[2].name, "README"
+      assert_equal entries[2].lastrev.time, Time.gm(2007, 12, 13, 16, 27, 22)
+      assert_equal entries[2].lastrev.identifier, '3'
+      assert_equal entries[2].lastrev.revision, '3'
+      assert_equal entries[2].lastrev.author, 'LANG'
+    end
+
+    def test_entries_invalid_path
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal CHANGESETS_NUM, @repository.changesets.count
+      assert_nil @repository.entries('missing')
+      assert_nil @repository.entries('missing', '3')
+    end
+
+    def test_entries_invalid_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal CHANGESETS_NUM, @repository.changesets.count
+      assert_nil @repository.entries('', '123')
+    end
+
+    def test_cat
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal CHANGESETS_NUM, @repository.changesets.count
+      buf = @repository.cat('README')
+      assert buf
+      lines = buf.split("\n")
+      assert_equal 3, lines.length
+      buf = lines[1].gsub(/\r$/, "")
+      assert_equal 'with one change', buf
+      buf = @repository.cat('README', '1')
+      assert buf
+      lines = buf.split("\n")
+      assert_equal 1, lines.length
+      buf = lines[0].gsub(/\r$/, "")
+      assert_equal 'CVS test repository', buf
+      assert_nil @repository.cat('missing.rb')
+
+      # sources/welcome_controller.rb is removed at revision 5.
+      assert @repository.cat('sources/welcome_controller.rb', '4')
+      assert @repository.cat('sources/welcome_controller.rb', '5').blank?
+
+      # invalid revision
+      assert @repository.cat('README', '123').blank?
+    end
+
+    def test_annotate
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal CHANGESETS_NUM, @repository.changesets.count
+      ann = @repository.annotate('README')
+      assert ann
+      assert_equal 3, ann.revisions.length
+      assert_equal '1.2', ann.revisions[1].revision
+      assert_equal 'LANG', ann.revisions[1].author
+      assert_equal 'with one change', ann.lines[1]
+
+      ann = @repository.annotate('README', '1')
+      assert ann
+      assert_equal 1, ann.revisions.length
+      assert_equal '1.1', ann.revisions[0].revision
+      assert_equal 'LANG', ann.revisions[0].author
+      assert_equal 'CVS test repository', ann.lines[0]
+
+     # invalid revision
+     assert_nil @repository.annotate('README', '123')
+   end
+
+  else
+    puts "CVS test repository NOT FOUND. Skipping unit tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a1/a194f771cf0697754774b1fd566535421f7cd91f.svn-base
--- a/.svn/pristine/a1/a194f771cf0697754774b1fd566535421f7cd91f.svn-base
+++ /dev/null
@@ -1,215 +0,0 @@
-module CodeRay
-module Scanners
-
-  # Scanner for C++.
-  # 
-  # Aliases: +cplusplus+, c++
-  class CPlusPlus < Scanner
-
-    register_for :cpp
-    file_extension 'cpp'
-    title 'C++'
-    
-    #-- http://www.cppreference.com/wiki/keywords/start
-    KEYWORDS = [
-      'and', 'and_eq', 'asm', 'bitand', 'bitor', 'break',
-      'case', 'catch', 'class', 'compl', 'const_cast',
-      'continue', 'default', 'delete', 'do', 'dynamic_cast', 'else',
-      'enum', 'export', 'for', 'goto', 'if', 'namespace', 'new',
-      'not', 'not_eq', 'or', 'or_eq', 'reinterpret_cast', 'return',
-      'sizeof', 'static_cast', 'struct', 'switch', 'template',
-      'throw', 'try', 'typedef', 'typeid', 'typename', 'union',
-      'while', 'xor', 'xor_eq',
-    ]  # :nodoc:
-    
-    PREDEFINED_TYPES = [
-      'bool', 'char', 'double', 'float', 'int', 'long',
-      'short', 'signed', 'unsigned', 'wchar_t', 'string',
-    ]  # :nodoc:
-    PREDEFINED_CONSTANTS = [
-      'false', 'true',
-      'EOF', 'NULL',
-    ]  # :nodoc:
-    PREDEFINED_VARIABLES = [
-      'this',
-    ]  # :nodoc:
-    DIRECTIVES = [
-      'auto', 'const', 'explicit', 'extern', 'friend', 'inline', 'mutable', 'operator',
-      'private', 'protected', 'public', 'register', 'static', 'using', 'virtual', 'void',
-      'volatile',
-    ]  # :nodoc:
-    
-    IDENT_KIND = WordList.new(:ident).
-      add(KEYWORDS, :keyword).
-      add(PREDEFINED_TYPES, :predefined_type).
-      add(PREDEFINED_VARIABLES, :local_variable).
-      add(DIRECTIVES, :directive).
-      add(PREDEFINED_CONSTANTS, :predefined_constant)  # :nodoc:
-
-    ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x  # :nodoc:
-    UNICODE_ESCAPE =  / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x  # :nodoc:
-    
-  protected
-    
-    def scan_tokens encoder, options
-
-      state = :initial
-      label_expected = true
-      case_expected = false
-      label_expected_before_preproc_line = nil
-      in_preproc_line = false
-
-      until eos?
-
-        case state
-
-        when :initial
-
-          if match = scan(/ \s+ | \\\n /x)
-            if in_preproc_line && match != "\\\n" && match.index(?\n)
-              in_preproc_line = false
-              label_expected = label_expected_before_preproc_line
-            end
-            encoder.text_token match, :space
-
-          elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
-            encoder.text_token match, :comment
-
-          elsif match = scan(/ \# \s* if \s* 0 /x)
-            match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos?
-            encoder.text_token match, :comment
-
-          elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x)
-            label_expected = match =~ /[;\{\}]/
-            if case_expected
-              label_expected = true if match == ':'
-              case_expected = false
-            end
-            encoder.text_token match, :operator
-
-          elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
-            kind = IDENT_KIND[match]
-            if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/)
-              kind = :label
-              match << matched
-            else
-              label_expected = false
-              if kind == :keyword
-                case match
-                when 'class'
-                  state = :class_name_expected
-                when 'case', 'default'
-                  case_expected = true
-                end
-              end
-            end
-            encoder.text_token match, kind
-
-          elsif match = scan(/\$/)
-            encoder.text_token match, :ident
-          
-          elsif match = scan(/L?"/)
-            encoder.begin_group :string
-            if match[0] == ?L
-              encoder.text_token match, 'L', :modifier
-              match = '"'
-            end
-            state = :string
-            encoder.text_token match, :delimiter
-
-          elsif match = scan(/#[ \t]*(\w*)/)
-            encoder.text_token match, :preprocessor
-            in_preproc_line = true
-            label_expected_before_preproc_line = label_expected
-            state = :include_expected if self[1] == 'include'
-
-          elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
-            label_expected = false
-            encoder.text_token match, :char
-
-          elsif match = scan(/0[xX][0-9A-Fa-f]+/)
-            label_expected = false
-            encoder.text_token match, :hex
-
-          elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/)
-            label_expected = false
-            encoder.text_token match, :octal
-
-          elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/)
-            label_expected = false
-            encoder.text_token match, :integer
-
-          elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
-            label_expected = false
-            encoder.text_token match, :float
-
-          else
-            encoder.text_token getch, :error
-
-          end
-
-        when :string
-          if match = scan(/[^\\"]+/)
-            encoder.text_token match, :content
-          elsif match = scan(/"/)
-            encoder.text_token match, :delimiter
-            encoder.end_group :string
-            state = :initial
-            label_expected = false
-          elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
-            encoder.text_token match, :char
-          elsif match = scan(/ \\ | $ /x)
-            encoder.end_group :string
-            encoder.text_token match, :error
-            state = :initial
-            label_expected = false
-          else
-            raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
-          end
-
-        when :include_expected
-          if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/)
-            encoder.text_token match, :include
-            state = :initial
-
-          elsif match = scan(/\s+/)
-            encoder.text_token match, :space
-            state = :initial if match.index ?\n
-
-          else
-            state = :initial
-
-          end
-        
-        when :class_name_expected
-          if match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
-            encoder.text_token match, :class
-            state = :initial
-
-          elsif match = scan(/\s+/)
-            encoder.text_token match, :space
-
-          else
-            encoder.text_token getch, :error
-            state = :initial
-
-          end
-          
-        else
-          raise_inspect 'Unknown state', encoder
-
-        end
-
-      end
-
-      if state == :string
-        encoder.end_group :string
-      end
-
-      encoder
-    end
-
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a1/a1b6cd426ff4438995b01b95b9d9cc2d93c15fb8.svn-base
--- a/.svn/pristine/a1/a1b6cd426ff4438995b01b95b9d9cc2d93c15fb8.svn-base
+++ /dev/null
@@ -1,187 +0,0 @@
-
-table.revision-info td {
-    margin:  0px;
-    padding: 0px;
-}
-
-div.changeset-changes ul { margin: 0; padding: 0; }
-div.changeset-changes ul > ul { margin-left: 18px; padding: 0; }
-
-li.change {
-    list-style-type:none;
-    background-image: url(../images/bullet_black.png);
-    background-position: 1px 1px;
-    background-repeat: no-repeat;
-    padding-top: 1px;
-    padding-bottom: 1px;
-    padding-left: 20px;
-    margin: 0;
-}
-li.change.folder { background-image: url(../images/folder_open.png); }
-li.change.folder.change-A { background-image: url(../images/folder_open_add.png); }
-li.change.folder.change-M { background-image: url(../images/folder_open_orange.png); }
-li.change.change-A { background-image: url(../images/bullet_add.png); }
-li.change.change-M { background-image: url(../images/bullet_orange.png); }
-li.change.change-C { background-image: url(../images/bullet_blue.png); }
-li.change.change-R { background-image: url(../images/bullet_purple.png); }
-li.change.change-D { background-image: url(../images/bullet_delete.png); }
-
-li.change .copied-from { font-style: italic; color: #999; font-size: 0.9em; }
-li.change .copied-from:before { content: " - "}
-
-#changes-legend { float: right; font-size: 0.8em; margin: 0; }
-#changes-legend li { float: left; background-position: 5px 0; }
-
-table.filecontent { border: 1px solid #ccc;  border-collapse: collapse; width:98%; background-color: #fafafa; }
-table.filecontent th { border: 1px solid #ccc; background-color: #eee; }
-table.filecontent th.filename { background-color: #e4e4d4; text-align: left; padding: 0.2em;}
-table.filecontent tr.spacing th { text-align:center; }
-table.filecontent tr.spacing td { height: 0.4em; background: #EAF2F5;}
-table.filecontent th.line-num {
-    border: 1px solid #d7d7d7;
-    font-size: 0.8em;
-    text-align: right;
-    width: 2%;
-    padding-right: 3px;
-    color: #999;
-}
-table.filecontent th.line-num a {
-    text-decoration: none;
-    color: inherit;
-}
-table.filecontent td.line-code pre {
-    margin: 0px;
-    white-space: pre-wrap;
-}
-
-/* 12 different colors for the annonate view */
-table.annotate tr.bloc-0 {background: #FFFFBF;}
-table.annotate tr.bloc-1 {background: #EABFFF;}
-table.annotate tr.bloc-2 {background: #BFFFFF;}
-table.annotate tr.bloc-3 {background: #FFD9BF;}
-table.annotate tr.bloc-4 {background: #E6FFBF;}
-table.annotate tr.bloc-5 {background: #BFCFFF;}
-table.annotate tr.bloc-6 {background: #FFBFEF;}
-table.annotate tr.bloc-7 {background: #FFE6BF;}
-table.annotate tr.bloc-8 {background: #FFE680;}
-table.annotate tr.bloc-9 {background: #AA80FF;}
-table.annotate tr.bloc-10 {background: #FFBFDC;}
-table.annotate tr.bloc-11 {background: #BFE4FF;}
-
-table.annotate td.revision {
-    text-align: center;
-    width: 2%;
-    padding-left: 1em;
-    background: inherit;
-}
-
-table.annotate td.author {
-    text-align: center;
-    border-right: 1px solid #d7d7d7;
-    white-space: nowrap;
-    padding-left: 1em;
-    padding-right: 1em;
-    width: 3%;
-    background: inherit;
-    font-size: 90%;
-}
-
-table.annotate td.line-code { background-color: #fafafa; }
-
-div.action_M { background: #fd8 }
-div.action_D { background: #f88 }
-div.action_A { background: #bfb }
-
-/************* CodeRay styles *************/
-.syntaxhl div {display: inline;}
-.syntaxhl .line-numbers { padding: 2px 4px 2px 4px; background-color: #eee; margin:0px 5px 0px 0px; }
-.syntaxhl .code pre { overflow: auto }
-.syntaxhl .debug { color:white ! important; background:blue ! important; }
-
-.syntaxhl .attribute-name { color:#b48 }
-.syntaxhl .annotation { color:#007 }
-.syntaxhl .attribute-value { color:#700 }
-.syntaxhl .binary { color:#509 }
-
-.syntaxhl .comment { color:#777 }
-.syntaxhl .comment .char { color:#444 }
-.syntaxhl .comment .delimiter { color:#444 }
-
-.syntaxhl .char { color:#D20 }
-.syntaxhl .char .content { color:#D20 }
-.syntaxhl .char .delimiter { color:#710 }
-
-.syntaxhl .class { color:#B06; font-weight:bold }
-.syntaxhl .complex { color:#A08 }
-.syntaxhl .constant { color:#036; font-weight:bold }
-.syntaxhl .color { color:#0A0 }
-.syntaxhl .class-variable { color:#369 }
-.syntaxhl .decorator { color:#B0B }
-.syntaxhl .definition { color:#099; font-weight:bold }
-.syntaxhl .directive { color:#088; font-weight:bold }
-.syntaxhl .delimiter { color:black }
-.syntaxhl .doc { color:#970 }
-.syntaxhl .doctype { color:#34b }
-.syntaxhl .doc-string { color:#D42; font-weight:bold }
-.syntaxhl .escape  { color:#666 }
-.syntaxhl .entity { color:#800; font-weight:bold }
-.syntaxhl .error { color:#F00; background-color:#FAA }
-.syntaxhl .exception { color:#C00; font-weight:bold }
-.syntaxhl .float { color:#60E }
-.syntaxhl .function { color:#06B; font-weight:bold }
-.syntaxhl .global-variable { color:#d70 }
-.syntaxhl .hex { color:#02b }
-.syntaxhl .integer  { color:#00D }
-.syntaxhl .include { color:#B44; font-weight:bold }
-.syntaxhl .imaginary { color:#f00 }
-
-.syntaxhl .inline { background-color: hsla(0,0%,0%,0.07); color: black }
-.syntaxhl .inline-delimiter { font-weight: bold; color: #666 }
-
-.syntaxhl .instance-variable { color:#33B }
-.syntaxhl .label { color:#970; font-weight:bold }
-.syntaxhl .local-variable { color:#963 }
-.syntaxhl .namespace { color:#707; font-weight:bold }
-.syntaxhl .octal { color:#40E }
-.syntaxhl .operator { }
-.syntaxhl .predefined-constant { color:#069 }
-.syntaxhl .predefined { color:#369; font-weight:bold }
-.syntaxhl .predefined-type { color:#0a5; font-weight:bold }
-.syntaxhl .preprocessor { color:#579 }
-.syntaxhl .pseudo-class { color:#00C; font-weight:bold }
-.syntaxhl .reserved { color:#080; font-weight:bold }
-
-.syntaxhl .key .char { color: #60f }
-.syntaxhl .key .delimiter { color: #404 }
-.syntaxhl .key { color: #606 }
-.syntaxhl .keyword { color:#080; font-weight:bold }
-
-.syntaxhl .regexp { background-color:hsla(300,100%,50%,0.06); }
-.syntaxhl .regexp .content { color:#808 }
-.syntaxhl .regexp .delimiter { color:#404 }
-.syntaxhl .regexp .modifier { color:#C2C }
-
-.syntaxhl .string { background-color:hsla(0,100%,50%,0.05); }
-.syntaxhl .string .content { color: #D20 }
-.syntaxhl .string .char { color: #b0b }
-.syntaxhl .string .delimiter { color: #710 }
-.syntaxhl .string .modifier { color: #E40 }
-
-.syntaxhl .shell { background-color:hsla(120,100%,50%,0.06); }
-.syntaxhl .shell .content { color:#2B2 }
-.syntaxhl .shell .delimiter { color:#161 }
-
-.syntaxhl .symbol { color:#A60 }
-.syntaxhl .symbol .content { color:#A60 }
-.syntaxhl .symbol .delimiter { color:#630 }
-
-.syntaxhl .tag { color:#070 }
-.syntaxhl .type { color:#339; font-weight:bold }
-.syntaxhl .value { color: #088; }
-.syntaxhl .variable  { color:#037 }
-
-.syntaxhl .insert { background: hsla(120,100%,50%,0.12) }
-.syntaxhl .delete { background: hsla(0,100%,50%,0.12) }
-.syntaxhl .change { color: #bbf; background: #007; }
-.syntaxhl .head { color: #f8f; background: #505 }
-.syntaxhl .head .filename { color: white; }
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a2/a21c63a09deaaaafb3f8c5146b4ab9dceda78e34.svn-base
--- a/.svn/pristine/a2/a21c63a09deaaaafb3f8c5146b4ab9dceda78e34.svn-base
+++ /dev/null
@@ -1,1027 +0,0 @@
-# Hungarian translations for Ruby on Rails
-# by Richard Abonyi (richard.abonyi@gmail.com)
-# thanks to KKata, replaced and #hup.hu
-# Cleaned up by LÃ¡szlÃ³ BÃ¡csi (http://lackac.hu)
-# updated by kfl62 kfl62g@gmail.com
-# updated by GÃ¡bor TakÃ¡cs (taky77@gmail.com)
-
-"hu":
-  direction: ltr
-  date:
-    formats:
-      default: "%Y.%m.%d."
-      short: "%b %e."
-      long: "%Y. %B %e."
-    day_names: [vasÃ¡rnap, hÃ©tfÅ‘, kedd, szerda, csÃ¼tÃ¶rtÃ¶k, pÃ©ntek, szombat]
-    abbr_day_names: [v., h., k., sze., cs., p., szo.]
-    month_names: [~, januÃ¡r, februÃ¡r, mÃ¡rcius, Ã¡prilis, mÃ¡jus, jÃºnius, jÃºlius, augusztus, szeptember, oktÃ³ber, november, december]
-    abbr_month_names: [~, jan., febr., mÃ¡rc., Ã¡pr., mÃ¡j., jÃºn., jÃºl., aug., szept., okt., nov., dec.]
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%Y. %b %d., %H:%M"
-      time: "%H:%M"
-      short: "%b %e., %H:%M"
-      long: "%Y. %B %e., %A, %H:%M"
-    am: "de."
-    pm: "du."
-
-  datetime:
-    distance_in_words:
-      half_a_minute: 'fÃ©l perc'
-      less_than_x_seconds:
-#        zero: 'kevesebb, mint 1 mÃ¡sodperce'
-        one: 'kevesebb, mint 1 mÃ¡sodperce'
-        other: 'kevesebb, mint %{count} mÃ¡sodperce'
-      x_seconds:
-        one: '1 mÃ¡sodperce'
-        other: '%{count} mÃ¡sodperce'
-      less_than_x_minutes:
-#        zero: 'kevesebb, mint 1 perce'
-        one: 'kevesebb, mint 1 perce'
-        other: 'kevesebb, mint %{count} perce'
-      x_minutes:
-        one: '1 perce'
-        other: '%{count} perce'
-      about_x_hours:
-        one: 'csaknem 1 Ã³rÃ¡ja'
-        other: 'csaknem %{count} Ã³rÃ¡ja'
-      x_days:
-        one: '1 napja'
-        other: '%{count} napja'
-      about_x_months:
-        one: 'csaknem 1 hÃ³napja'
-        other: 'csaknem %{count} hÃ³napja'
-      x_months:
-        one: '1 hÃ³napja'
-        other: '%{count} hÃ³napja'
-      about_x_years:
-        one: 'csaknem 1 Ã©ve'
-        other: 'csaknem %{count} Ã©ve'
-      over_x_years:
-        one: 'tÃ¶bb, mint 1 Ã©ve'
-        other: 'tÃ¶bb, mint %{count} Ã©ve'
-      almost_x_years:
-        one:   "csaknem 1 Ã©ve"
-        other: "csaknem %{count} Ã©ve"
-    prompts:
-      year:   "Ã‰v"
-      month:  "HÃ³nap"
-      day:    "Nap"
-      hour:   "Ã“ra"
-      minute: "Perc"
-      second: "MÃ¡sodperc"
-
-  number:
-    format:
-      precision: 2
-      separator: ','
-      delimiter: ' '
-    currency:
-      format:
-        unit: 'Ft'
-        precision: 0
-        format: '%n %u'
-        separator: ","
-        delimiter: ""
-    percentage:
-      format:
-        delimiter: ""
-    precision:
-      format:
-        delimiter: ""
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "bÃ¡jt"
-            other: "bÃ¡jt"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  support:
-    array:
-#      sentence_connector: "Ã©s"
-#      skip_last_comma: true
-      words_connector: ", "
-      two_words_connector: " Ã©s "
-      last_word_connector: " Ã©s "
-  activerecord:
-    errors:
-      template:
-        header:
-          one: "1 hiba miatt nem menthetÅ‘ a kÃ¶vetkezÅ‘: %{model}"
-          other: "%{count} hiba miatt nem menthetÅ‘ a kÃ¶vetkezÅ‘: %{model}"
-        body: "ProblÃ©mÃ¡s mezÅ‘k:"
-      messages:
-        inclusion: "nincs a listÃ¡ban"
-        exclusion: "nem elÃ©rhetÅ‘"
-        invalid: "nem megfelelÅ‘"
-        confirmation: "nem egyezik"
-        accepted: "nincs elfogadva"
-        empty: "nincs megadva"
-        blank: "nincs megadva"
-        too_long: "tÃºl hosszÃº (nem lehet tÃ¶bb %{count} karakternÃ©l)"
-        too_short: "tÃºl rÃ¶vid (legalÃ¡bb %{count} karakter kell legyen)"
-        wrong_length: "nem megfelelÅ‘ hosszÃºsÃ¡gÃº (%{count} karakter szÃ¼ksÃ©ges)"
-        taken: "mÃ¡r foglalt"
-        not_a_number: "nem szÃ¡m"
-        greater_than: "nagyobb kell legyen, mint %{count}"
-        greater_than_or_equal_to: "legalÃ¡bb %{count} kell legyen"
-        equal_to: "pontosan %{count} kell legyen"
-        less_than: "kevesebb, mint %{count} kell legyen"
-        less_than_or_equal_to: "legfeljebb %{count} lehet"
-        odd: "pÃ¡ratlan kell legyen"
-        even: "pÃ¡ros kell legyen"
-        greater_than_start_date: "nagyobbnak kell lennie, mint az indÃ­tÃ¡s dÃ¡tuma"
-        not_same_project: "nem azonos projekthez tartozik"
-        circular_dependency: "Ez a kapcsolat egy kÃ¶rkÃ¶rÃ¶s fÃ¼ggÅ‘sÃ©get eredmÃ©nyez"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: KÃ©rem vÃ¡lasszon
-
-  general_text_No: 'Nem'
-  general_text_Yes: 'Igen'
-  general_text_no: 'nem'
-  general_text_yes: 'igen'
-  general_lang_name: 'Magyar'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: ISO-8859-2
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: A fiÃ³k adatai sikeresen frissÃ­tve.
-  notice_account_invalid_creditentials: HibÃ¡s felhasznÃ¡lÃ³i nÃ©v, vagy jelszÃ³
-  notice_account_password_updated: A jelszÃ³ mÃ³dosÃ­tÃ¡sa megtÃ¶rtÃ©nt.
-  notice_account_wrong_password: HibÃ¡s jelszÃ³
-  notice_account_register_done: A fiÃ³k sikeresen lÃ©trehozva. AktivÃ¡lÃ¡sÃ¡hoz kattints az e-mailben kapott linkre
-  notice_account_unknown_email: Ismeretlen felhasznÃ¡lÃ³.
-  notice_can_t_change_password: A fiÃ³k kÃ¼lsÅ‘ azonosÃ­tÃ¡si forrÃ¡st hasznÃ¡l. A jelszÃ³ megvÃ¡ltoztatÃ¡sa nem lehetsÃ©ges.
-  notice_account_lost_email_sent: Egy e-mail Ã¼zenetben postÃ¡ztunk Ã–nnek egy leÃ­rÃ¡st az Ãºj jelszÃ³ beÃ¡llÃ­tÃ¡sÃ¡rÃ³l.
-  notice_account_activated: FiÃ³kjÃ¡t aktivÃ¡ltuk. Most mÃ¡r be tud jelentkezni a rendszerbe.
-  notice_successful_create: Sikeres lÃ©trehozÃ¡s.
-  notice_successful_update: Sikeres mÃ³dosÃ­tÃ¡s.
-  notice_successful_delete: Sikeres tÃ¶rlÃ©s.
-  notice_successful_connection: Sikeres bejelentkezÃ©s.
-  notice_file_not_found: Az oldal, amit meg szeretne nÃ©zni nem talÃ¡lhatÃ³, vagy Ã¡tkerÃ¼lt egy mÃ¡sik helyre.
-  notice_locking_conflict: Az adatot egy mÃ¡sik felhasznÃ¡lÃ³ idÅ‘ kÃ¶zben mÃ³dosÃ­totta.
-  notice_not_authorized: Nincs hozzÃ¡fÃ©rÃ©si engedÃ©lye ehhez az oldalhoz.
-  notice_email_sent: "Egy e-mail Ã¼zenetet kÃ¼ldtÃ¼nk a kÃ¶vetkezÅ‘ cÃ­mre %{value}"
-  notice_email_error: "Hiba tÃ¶rtÃ©nt a levÃ©l kÃ¼ldÃ©se kÃ¶zben (%{value})"
-  notice_feeds_access_key_reseted: Az RSS hozzÃ¡fÃ©rÃ©si kulcsÃ¡t Ãºjra generÃ¡ltuk.
-  notice_failed_to_save_issues: "Nem sikerÃ¼lt a %{count} feladat(ok) mentÃ©se a %{total} -ban kivÃ¡lasztva: %{ids}."
-  notice_no_issue_selected: "Nincs feladat kivÃ¡lasztva! KÃ©rem jelÃ¶lje meg melyik feladatot szeretnÃ© szerkeszteni!"
-  notice_account_pending: "A fiÃ³kja lÃ©trejÃ¶tt, Ã©s adminisztrÃ¡tori jÃ³vÃ¡hagyÃ¡sra vÃ¡r."
-  notice_default_data_loaded: Az alapÃ©rtelmezett konfigurÃ¡ciÃ³ betÃ¶ltÃ©se sikeresen megtÃ¶rtÃ©nt.
-
-  error_can_t_load_default_data: "Az alapÃ©rtelmezett konfigurÃ¡ciÃ³ betÃ¶ltÃ©se nem lehetsÃ©ges: %{value}"
-  error_scm_not_found: "A bejegyzÃ©s, vagy revÃ­ziÃ³ nem talÃ¡lhatÃ³ a tÃ¡rolÃ³ban."
-  error_scm_command_failed: "A tÃ¡rolÃ³ elÃ©rÃ©se kÃ¶zben hiba lÃ©pett fel: %{value}"
-  error_scm_annotate: "A bejegyzÃ©s nem lÃ©tezik, vagy nics jegyzetekkel ellÃ¡tva."
-  error_issue_not_found_in_project: 'A feladat nem talÃ¡lhatÃ³, vagy nem ehhez a projekthez tartozik'
-
-  mail_subject_lost_password: Az Ã–n Redmine jelszava
-  mail_body_lost_password: 'A Redmine jelszÃ³ megvÃ¡ltoztatÃ¡sÃ¡hoz, kattintson a kÃ¶vetkezÅ‘ linkre:'
-  mail_subject_register: Redmine azonosÃ­tÃ³ aktivÃ¡lÃ¡sa
-  mail_body_register: 'A Redmine azonosÃ­tÃ³ja aktivÃ¡lÃ¡sÃ¡hoz, kattintson a kÃ¶vetkezÅ‘ linkre:'
-  mail_body_account_information_external: "A %{value} azonosÃ­tÃ³ hasznÃ¡latÃ¡val bejelentkezhet a Redmine-ba."
-  mail_body_account_information: Az Ã–n Redmine azonosÃ­tÃ³jÃ¡nak informÃ¡ciÃ³i
-  mail_subject_account_activation_request: Redmine azonosÃ­tÃ³ aktivÃ¡lÃ¡si kÃ©relem
-  mail_body_account_activation_request: "Egy Ãºj felhasznÃ¡lÃ³ (%{value}) regisztrÃ¡lt, azonosÃ­tÃ³ja jÃ³vÃ¡hasgyÃ¡sra vÃ¡rakozik:"
-
-  gui_validation_error: 1 hiba
-  gui_validation_error_plural: "%{count} hiba"
-
-  field_name: NÃ©v
-  field_description: LeÃ­rÃ¡s
-  field_summary: Ã–sszegzÃ©s
-  field_is_required: KÃ¶telezÅ‘
-  field_firstname: KeresztnÃ©v
-  field_lastname: VezetÃ©knÃ©v
-  field_mail: E-mail
-  field_filename: FÃ¡jl
-  field_filesize: MÃ©ret
-  field_downloads: LetÃ¶ltÃ©sek
-  field_author: SzerzÅ‘
-  field_created_on: LÃ©trehozva
-  field_updated_on: MÃ³dosÃ­tva
-  field_field_format: FormÃ¡tum
-  field_is_for_all: Minden projekthez
-  field_possible_values: LehetsÃ©ges Ã©rtÃ©kek
-  field_regexp: RegulÃ¡ris kifejezÃ©s
-  field_min_length: Minimum hossz
-  field_max_length: Maximum hossz
-  field_value: Ã‰rtÃ©k
-  field_category: KategÃ³ria
-  field_title: CÃ­m
-  field_project: Projekt
-  field_issue: Feladat
-  field_status: StÃ¡tusz
-  field_notes: FeljegyzÃ©sek
-  field_is_closed: Feladat lezÃ¡rva
-  field_is_default: AlapÃ©rtelmezett Ã©rtÃ©k
-  field_tracker: TÃ­pus
-  field_subject: TÃ¡rgy
-  field_due_date: BefejezÃ©s dÃ¡tuma
-  field_assigned_to: FelelÅ‘s
-  field_priority: PrioritÃ¡s
-  field_fixed_version: CÃ©l verziÃ³
-  field_user: FelhasznÃ¡lÃ³
-  field_role: SzerepkÃ¶r
-  field_homepage: Weboldal
-  field_is_public: NyilvÃ¡nos
-  field_parent: SzÃ¼lÅ‘ projekt
-  field_is_in_roadmap: Feladatok lÃ¡tszanak az Ã©letÃºtban
-  field_login: AzonosÃ­tÃ³
-  field_mail_notification: E-mail Ã©rtesÃ­tÃ©sek
-  field_admin: AdminisztrÃ¡tor
-  field_last_login_on: UtolsÃ³ bejelentkezÃ©s
-  field_language: Nyelv
-  field_effective_date: DÃ¡tum
-  field_password: JelszÃ³
-  field_new_password: Ãšj jelszÃ³
-  field_password_confirmation: MegerÅ‘sÃ­tÃ©s
-  field_version: VerziÃ³
-  field_type: TÃ­pus
-  field_host: KiszolgÃ¡lÃ³
-  field_port: Port
-  field_account: FelhasznÃ¡lÃ³i fiÃ³k
-  field_base_dn: Base DN
-  field_attr_login: BejelentkezÃ©si tulajdonsÃ¡g
-  field_attr_firstname: KeresztnÃ©v
-  field_attr_lastname: VezetÃ©knÃ©v
-  field_attr_mail: E-mail
-  field_onthefly: On-the-fly felhasznÃ¡lÃ³ lÃ©trehozÃ¡s
-  field_start_date: KezdÃ©s dÃ¡tuma
-  field_done_ratio: KÃ©szÃ¼ltsÃ©g (%)
-  field_auth_source: AzonosÃ­tÃ¡si mÃ³d
-  field_hide_mail: Rejtse el az e-mail cÃ­mem
-  field_comments: MegjegyzÃ©s
-  field_url: URL
-  field_start_page: KezdÅ‘lap
-  field_subproject: Alprojekt
-  field_hours: Ã“ra
-  field_activity: AktivitÃ¡s
-  field_spent_on: DÃ¡tum
-  field_identifier: AzonosÃ­tÃ³
-  field_is_filter: SzÅ±rÅ‘kÃ©nt hasznÃ¡lhatÃ³
-  field_issue_to: KapcsolÃ³dÃ³ feladat
-  field_delay: KÃ©sÃ©s
-  field_assignable: Feladat rendelhetÅ‘ ehhez a szerepkÃ¶rhÃ¶z
-  field_redirect_existing_links: LÃ©tezÅ‘ linkek Ã¡tirÃ¡nyÃ­tÃ¡sa
-  field_estimated_hours: BecsÃ¼lt idÅ‘igÃ©ny
-  field_column_names: Oszlopok
-  field_time_zone: IdÅ‘zÃ³na
-  field_searchable: KereshetÅ‘
-  field_default_value: AlapÃ©rtelmezett Ã©rtÃ©k
-  field_comments_sorting: FeljegyzÃ©sek megjelenÃ­tÃ©se
-
-  setting_app_title: AlkalmazÃ¡s cÃ­me
-  setting_app_subtitle: AlkalmazÃ¡s alcÃ­me
-  setting_welcome_text: ÃœdvÃ¶zlÅ‘ Ã¼zenet
-  setting_default_language: AlapÃ©rtelmezett nyelv
-  setting_login_required: AzonosÃ­tÃ¡s szÃ¼ksÃ©ges
-  setting_self_registration: RegisztrÃ¡ciÃ³
-  setting_attachment_max_size: MellÃ©klet max. mÃ©rete
-  setting_issues_export_limit: Feladatok exportÃ¡lÃ¡sÃ¡nak korlÃ¡tja
-  setting_mail_from: KibocsÃ¡tÃ³ e-mail cÃ­me
-  setting_bcc_recipients: Titkos mÃ¡solat cÃ­mzet (bcc)
-  setting_host_name: KiszolgÃ¡lÃ³ neve
-  setting_text_formatting: SzÃ¶veg formÃ¡zÃ¡s
-  setting_wiki_compression: Wiki tÃ¶rtÃ©net tÃ¶mÃ¶rÃ­tÃ©s
-  setting_feeds_limit: RSS tartalom korlÃ¡t
-  setting_default_projects_public: Az Ãºj projektek alapÃ©rtelmezÃ©s szerint nyilvÃ¡nosak
-  setting_autofetch_changesets: Commitok automatikus lehÃºzÃ¡sa
-  setting_sys_api_enabled: WS engedÃ©lyezÃ©se a tÃ¡rolÃ³k kezelÃ©sÃ©hez
-  setting_commit_ref_keywords: HivatkozÃ³ kulcsszavak
-  setting_commit_fix_keywords: JavÃ­tÃ¡sok kulcsszavai
-  setting_autologin: Automatikus bejelentkezÃ©s
-  setting_date_format: DÃ¡tum formÃ¡tum
-  setting_time_format: IdÅ‘ formÃ¡tum
-  setting_cross_project_issue_relations: Kereszt-projekt feladat hivatkozÃ¡sok engedÃ©lyezÃ©se
-  setting_issue_list_default_columns: Az alapÃ©rtelmezÃ©skÃ©nt megjelenÃ­tett oszlopok a feladat listÃ¡ban
-  setting_emails_footer: E-mail lÃ¡blÃ©c
-  setting_protocol: Protokol
-  setting_per_page_options: Objektum / oldal opciÃ³k
-  setting_user_format: FelhasznÃ¡lÃ³k megjelenÃ­tÃ©sÃ©nek formÃ¡ja
-  setting_activity_days_default: Napok megjelenÃ­tÃ©se a project aktivitÃ¡snÃ¡l
-  setting_display_subprojects_issues: AlapÃ©rtelmezettkÃ©nt mutassa az alprojektek feladatait is a projekteken
-  setting_start_of_week: A hÃ©t elsÅ‘ napja
-
-  project_module_issue_tracking: Feladat kÃ¶vetÃ©s
-  project_module_time_tracking: IdÅ‘ rÃ¶gzÃ­tÃ©s
-  project_module_news: HÃ­rek
-  project_module_documents: Dokumentumok
-  project_module_files: FÃ¡jlok
-  project_module_wiki: Wiki
-  project_module_repository: ForrÃ¡skÃ³d
-  project_module_boards: FÃ³rumok
-
-  label_user: FelhasznÃ¡lÃ³
-  label_user_plural: FelhasznÃ¡lÃ³k
-  label_user_new: Ãšj felhasznÃ¡lÃ³
-  label_project: Projekt
-  label_project_new: Ãšj projekt
-  label_project_plural: Projektek
-  label_x_projects:
-    zero:  nincsenek projektek
-    one:   1 projekt
-    other: "%{count} projekt"
-  label_project_all: Az Ã¶sszes projekt
-  label_project_latest: LegutÃ³bbi projektek
-  label_issue: Feladat
-  label_issue_new: Ãšj feladat
-  label_issue_plural: Feladatok
-  label_issue_view_all: Minden feladat
-  label_issues_by: "%{value} feladatai"
-  label_issue_added: Feladat hozzÃ¡adva
-  label_issue_updated: Feladat frissÃ­tve
-  label_document: Dokumentum
-  label_document_new: Ãšj dokumentum
-  label_document_plural: Dokumentumok
-  label_document_added: Dokumentum hozzÃ¡adva
-  label_role: SzerepkÃ¶r
-  label_role_plural: SzerepkÃ¶rÃ¶k
-  label_role_new: Ãšj szerepkÃ¶r
-  label_role_and_permissions: SzerepkÃ¶rÃ¶k, Ã©s jogosultsÃ¡gok
-  label_member: RÃ©sztvevÅ‘
-  label_member_new: Ãšj rÃ©sztvevÅ‘
-  label_member_plural: RÃ©sztvevÅ‘k
-  label_tracker: Feladat tÃ­pus
-  label_tracker_plural: Feladat tÃ­pusok
-  label_tracker_new: Ãšj feladat tÃ­pus
-  label_workflow: Workflow
-  label_issue_status: Feladat stÃ¡tusz
-  label_issue_status_plural: Feladat stÃ¡tuszok
-  label_issue_status_new: Ãšj stÃ¡tusz
-  label_issue_category: Feladat kategÃ³ria
-  label_issue_category_plural: Feladat kategÃ³riÃ¡k
-  label_issue_category_new: Ãšj kategÃ³ria
-  label_custom_field: EgyÃ©ni mezÅ‘
-  label_custom_field_plural: EgyÃ©ni mezÅ‘k
-  label_custom_field_new: Ãšj egyÃ©ni mezÅ‘
-  label_enumerations: FelsorolÃ¡sok
-  label_enumeration_new: Ãšj Ã©rtÃ©k
-  label_information: InformÃ¡ciÃ³
-  label_information_plural: InformÃ¡ciÃ³k
-  label_please_login: Jelentkezzen be
-  label_register: RegisztrÃ¡ljon
-  label_password_lost: Elfelejtett jelszÃ³
-  label_home: KezdÅ‘lap
-  label_my_page: SajÃ¡t kezdÅ‘lapom
-  label_my_account: FiÃ³kom adatai
-  label_my_projects: SajÃ¡t projektem
-  label_administration: AdminisztrÃ¡ciÃ³
-  label_login: BejelentkezÃ©s
-  label_logout: KijelentkezÃ©s
-  label_help: SÃºgÃ³
-  label_reported_issues: Bejelentett feladatok
-  label_assigned_to_me_issues: A nekem kiosztott feladatok
-  label_last_login: UtolsÃ³ bejelentkezÃ©s
-  label_registered_on: RegisztrÃ¡lt
-  label_activity: TÃ¶rtÃ©nÃ©sek
-  label_overall_activity: Teljes aktivitÃ¡s
-  label_new: Ãšj
-  label_logged_as: Bejelentkezve, mint
-  label_environment: KÃ¶rnyezet
-  label_authentication: AzonosÃ­tÃ¡s
-  label_auth_source: AzonosÃ­tÃ¡s mÃ³dja
-  label_auth_source_new: Ãšj azonosÃ­tÃ¡si mÃ³d
-  label_auth_source_plural: AzonosÃ­tÃ¡si mÃ³dok
-  label_subproject_plural: Alprojektek
-  label_and_its_subprojects: "%{value} Ã©s alprojektjei"
-  label_min_max_length: Min - Max hossz
-  label_list: Lista
-  label_date: DÃ¡tum
-  label_integer: EgÃ©sz
-  label_float: LebegÅ‘pontos
-  label_boolean: Logikai
-  label_string: SzÃ¶veg
-  label_text: HosszÃº szÃ¶veg
-  label_attribute: TulajdonsÃ¡g
-  label_attribute_plural: TulajdonsÃ¡gok
-  label_download: "%{count} LetÃ¶ltÃ©s"
-  label_download_plural: "%{count} LetÃ¶ltÃ©s"
-  label_no_data: Nincs megjelenÃ­thetÅ‘ adat
-  label_change_status: StÃ¡tusz mÃ³dosÃ­tÃ¡sa
-  label_history: TÃ¶rtÃ©net
-  label_attachment: FÃ¡jl
-  label_attachment_new: Ãšj fÃ¡jl
-  label_attachment_delete: FÃ¡jl tÃ¶rlÃ©se
-  label_attachment_plural: FÃ¡jlok
-  label_file_added: FÃ¡jl hozzÃ¡adva
-  label_report: JelentÃ©s
-  label_report_plural: JelentÃ©sek
-  label_news: HÃ­rek
-  label_news_new: HÃ­r hozzÃ¡adÃ¡sa
-  label_news_plural: HÃ­rek
-  label_news_latest: LegutÃ³bbi hÃ­rek
-  label_news_view_all: Minden hÃ­r megtekintÃ©se
-  label_news_added: HÃ­r hozzÃ¡adva
-  label_settings: BeÃ¡llÃ­tÃ¡sok
-  label_overview: ÃttekintÃ©s
-  label_version: VerziÃ³
-  label_version_new: Ãšj verziÃ³
-  label_version_plural: VerziÃ³k
-  label_confirmation: JÃ³vÃ¡hagyÃ¡s
-  label_export_to: ExportÃ¡lÃ¡s
-  label_read: Olvas...
-  label_public_projects: NyilvÃ¡nos projektek
-  label_open_issues: nyitott
-  label_open_issues_plural: nyitott
-  label_closed_issues: lezÃ¡rt
-  label_closed_issues_plural: lezÃ¡rt
-  label_x_open_issues_abbr_on_total:
-    zero:  nyitott 0 / %{total}
-    one:   nyitott 1 / %{total}
-    other: "nyitott %{count} / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 nyitott
-    one:   1 nyitott
-    other: "%{count} nyitott"
-  label_x_closed_issues_abbr:
-    zero:  0 lezÃ¡rt
-    one:   1 lezÃ¡rt
-    other: "%{count} lezÃ¡rt"
-  label_total: Ã–sszesen
-  label_permissions: JogosultsÃ¡gok
-  label_current_status: Jelenlegi stÃ¡tusz
-  label_new_statuses_allowed: StÃ¡tusz vÃ¡ltoztatÃ¡sok engedÃ©lyei
-  label_all: mind
-  label_none: nincs
-  label_nobody: senki
-  label_next: KÃ¶vetkezÅ‘
-  label_previous: ElÅ‘zÅ‘
-  label_used_by: HasznÃ¡lja
-  label_details: RÃ©szletek
-  label_add_note: Jegyzet hozzÃ¡adÃ¡sa
-  label_per_page: OldalankÃ©nt
-  label_calendar: NaptÃ¡r
-  label_months_from: hÃ³nap, kezdve
-  label_gantt: Gantt
-  label_internal: BelsÅ‘
-  label_last_changes: "utolsÃ³ %{count} vÃ¡ltozÃ¡s"
-  label_change_view_all: Minden vÃ¡ltozÃ¡s megtekintÃ©se
-  label_personalize_page: Az oldal testreszabÃ¡sa
-  label_comment: MegjegyzÃ©s
-  label_comment_plural: MegjegyzÃ©s
-  label_x_comments:
-    zero: nincs megjegyzÃ©s
-    one: 1 megjegyzÃ©s
-    other: "%{count} megjegyzÃ©s"
-  label_comment_add: MegjegyzÃ©s hozzÃ¡adÃ¡sa
-  label_comment_added: MegjegyzÃ©s hozzÃ¡adva
-  label_comment_delete: MegjegyzÃ©sek tÃ¶rlÃ©se
-  label_query: EgyÃ©ni lekÃ©rdezÃ©s
-  label_query_plural: EgyÃ©ni lekÃ©rdezÃ©sek
-  label_query_new: Ãšj lekÃ©rdezÃ©s
-  label_filter_add: SzÅ±rÅ‘ hozzÃ¡adÃ¡sa
-  label_filter_plural: SzÅ±rÅ‘k
-  label_equals: egyenlÅ‘
-  label_not_equals: nem egyenlÅ‘
-  label_in_less_than: kevesebb, mint
-  label_in_more_than: tÃ¶bb, mint
-  label_in: in
-  label_today: ma
-  label_all_time: mindenkor
-  label_yesterday: tegnap
-  label_this_week: aktuÃ¡lis hÃ©t
-  label_last_week: mÃºlt hÃ©t
-  label_last_n_days: "az elmÃºlt %{count} nap"
-  label_this_month: aktuÃ¡lis hÃ³nap
-  label_last_month: mÃºlt hÃ³nap
-  label_this_year: aktuÃ¡lis Ã©v
-  label_date_range: DÃ¡tum intervallum
-  label_less_than_ago: kevesebb, mint nappal ezelÅ‘tt
-  label_more_than_ago: tÃ¶bb, mint nappal ezelÅ‘tt
-  label_ago: nappal ezelÅ‘tt
-  label_contains: tartalmazza
-  label_not_contains: nem tartalmazza
-  label_day_plural: nap
-  label_repository: ForrÃ¡skÃ³d
-  label_repository_plural: ForrÃ¡skÃ³dok
-  label_browse: TallÃ³z
-  label_modification: "%{count} vÃ¡ltozÃ¡s"
-  label_modification_plural: "%{count} vÃ¡ltozÃ¡s"
-  label_revision: RevÃ­ziÃ³
-  label_revision_plural: RevÃ­ziÃ³k
-  label_associated_revisions: Kapcsolt revÃ­ziÃ³k
-  label_added: hozzÃ¡adva
-  label_modified: mÃ³dosÃ­tva
-  label_deleted: tÃ¶rÃ¶lve
-  label_latest_revision: LegutolsÃ³ revÃ­ziÃ³
-  label_latest_revision_plural: LegutolsÃ³ revÃ­ziÃ³k
-  label_view_revisions: RevÃ­ziÃ³k megtekintÃ©se
-  label_max_size: MaximÃ¡lis mÃ©ret
-  label_sort_highest: Az elejÃ©re
-  label_sort_higher: Eggyel feljebb
-  label_sort_lower: Eggyel lejjebb
-  label_sort_lowest: Az aljÃ¡ra
-  label_roadmap: Ã‰letÃºt
-  label_roadmap_due_in: "ElkÃ©szÃ¼ltÃ©ig vÃ¡rhatÃ³an mÃ©g %{value}"
-  label_roadmap_overdue: "%{value} kÃ©sÃ©sben"
-  label_roadmap_no_issues: Nincsenek feladatok ehhez a verziÃ³hoz
-  label_search: KeresÃ©s
-  label_result_plural: TalÃ¡latok
-  label_all_words: Minden szÃ³
-  label_wiki: Wiki
-  label_wiki_edit: Wiki szerkesztÃ©s
-  label_wiki_edit_plural: Wiki szerkesztÃ©sek
-  label_wiki_page: Wiki oldal
-  label_wiki_page_plural: Wiki oldalak
-  label_index_by_title: CÃ­m szerint indexelve
-  label_index_by_date: DÃ¡tum szerint indexelve
-  label_current_version: Jelenlegi verziÃ³
-  label_preview: ElÅ‘nÃ©zet
-  label_feed_plural: VisszajelzÃ©sek
-  label_changes_details: VÃ¡ltozÃ¡sok rÃ©szletei
-  label_issue_tracking: Feladat kÃ¶vetÃ©s
-  label_spent_time: RÃ¡fordÃ­tott idÅ‘
-  label_f_hour: "%{value} Ã³ra"
-  label_f_hour_plural: "%{value} Ã³ra"
-  label_time_tracking: IdÅ‘ rÃ¶gzÃ­tÃ©s
-  label_change_plural: VÃ¡ltozÃ¡sok
-  label_statistics: StatisztikÃ¡k
-  label_commits_per_month: Commitok havonta
-  label_commits_per_author: Commitok szerzÅ‘nkÃ©nt
-  label_view_diff: KÃ¼lÃ¶nbsÃ©gek megtekintÃ©se
-  label_diff_inline: soronkÃ©nt
-  label_diff_side_by_side: egymÃ¡s mellett
-  label_options: OpciÃ³k
-  label_copy_workflow_from: Workflow mÃ¡solÃ¡sa innen
-  label_permissions_report: JogosultsÃ¡gi riport
-  label_watched_issues: Megfigyelt feladatok
-  label_related_issues: KapcsolÃ³dÃ³ feladatok
-  label_applied_status: AlkalmazandÃ³ stÃ¡tusz
-  label_loading: BetÃ¶ltÃ©s...
-  label_relation_new: Ãšj kapcsolat
-  label_relation_delete: Kapcsolat tÃ¶rlÃ©se
-  label_relates_to: kapcsolÃ³dik
-  label_duplicates: duplikÃ¡lja
-  label_blocks: zÃ¡rolja
-  label_blocked_by: zÃ¡rolta
-  label_precedes: megelÅ‘zi
-  label_follows: kÃ¶veti
-  label_end_to_start: vÃ©gÃ©tÅ‘l indulÃ¡sig
-  label_end_to_end: vÃ©gÃ©tÅ‘l vÃ©gÃ©ig
-  label_start_to_start: indulÃ¡stÃ³l indulÃ¡sig
-  label_start_to_end: indulÃ¡stÃ³l vÃ©gÃ©ig
-  label_stay_logged_in: EmlÃ©kezzen rÃ¡m
-  label_disabled: kikapcsolva
-  label_show_completed_versions: A kÃ©sz verziÃ³k mutatÃ¡sa
-  label_me: Ã©n
-  label_board: FÃ³rum
-  label_board_new: Ãšj fÃ³rum
-  label_board_plural: FÃ³rumok
-  label_topic_plural: TÃ©mÃ¡k
-  label_message_plural: Ãœzenetek
-  label_message_last: UtolsÃ³ Ã¼zenet
-  label_message_new: Ãšj Ã¼zenet
-  label_message_posted: Ãœzenet hozzÃ¡adva
-  label_reply_plural: VÃ¡laszok
-  label_send_information: FiÃ³k infomÃ¡ciÃ³k kÃ¼ldÃ©se a felhasznÃ¡lÃ³nak
-  label_year: Ã‰v
-  label_month: HÃ³nap
-  label_week: HÃ©t
-  label_date_from: 'Kezdet:'
-  label_date_to: 'VÃ©ge:'
-  label_language_based: A felhasznÃ¡lÃ³ nyelve alapjÃ¡n
-  label_sort_by: "%{value} szerint rendezve"
-  label_send_test_email: Teszt e-mail kÃ¼ldÃ©se
-  label_feeds_access_key_created_on: "RSS hozzÃ¡fÃ©rÃ©si kulcs lÃ©trehozva %{value}"
-  label_module_plural: Modulok
-  label_added_time_by: "%{author} adta hozzÃ¡ %{age}"
-  label_updated_time: "UtolsÃ³ mÃ³dosÃ­tÃ¡s %{value}"
-  label_jump_to_a_project: UgrÃ¡s projekthez...
-  label_file_plural: FÃ¡jlok
-  label_changeset_plural: Changesets
-  label_default_columns: AlapÃ©rtelmezett oszlopok
-  label_no_change_option: (Nincs vÃ¡ltozÃ¡s)
-  label_bulk_edit_selected_issues: A kivÃ¡lasztott feladatok kÃ¶tegelt szerkesztÃ©se
-  label_theme: TÃ©ma
-  label_default: AlapÃ©rtelmezett
-  label_search_titles_only: KeresÃ©s csak a cÃ­mekben
-  label_user_mail_option_all: "Minden esemÃ©nyrÅ‘l minden sajÃ¡t projektemben"
-  label_user_mail_option_selected: "Minden esemÃ©nyrÅ‘l a kivÃ¡lasztott projektekben..."
-  label_user_mail_no_self_notified: "Nem kÃ©rek Ã©rtesÃ­tÃ©st az Ã¡ltalam vÃ©gzett mÃ³dosÃ­tÃ¡sokrÃ³l"
-  label_registration_activation_by_email: FiÃ³k aktivÃ¡lÃ¡sa e-mailben
-  label_registration_manual_activation: ManuÃ¡lis fiÃ³k aktivÃ¡lÃ¡s
-  label_registration_automatic_activation: Automatikus fiÃ³k aktivÃ¡lÃ¡s
-  label_display_per_page: "OldalankÃ©nt: %{value}"
-  label_age: Kor
-  label_change_properties: TulajdonsÃ¡gok vÃ¡ltoztatÃ¡sa
-  label_general: ÃltalÃ¡nos
-  label_more: tovÃ¡bbiak
-  label_scm: SCM
-  label_plugins: Pluginek
-  label_ldap_authentication: LDAP azonosÃ­tÃ¡s
-  label_downloads_abbr: D/L
-  label_optional_description: OpcionÃ¡lis leÃ­rÃ¡s
-  label_add_another_file: Ãšjabb fÃ¡jl hozzÃ¡adÃ¡sa
-  label_preferences: TulajdonsÃ¡gok
-  label_chronological_order: IdÅ‘rendben
-  label_reverse_chronological_order: FordÃ­tott idÅ‘rendben
-  label_planning: TervezÃ©s
-
-  button_login: BejelentkezÃ©s
-  button_submit: Elfogad
-  button_save: MentÃ©s
-  button_check_all: Mindent kijelÃ¶l
-  button_uncheck_all: KijelÃ¶lÃ©s tÃ¶rlÃ©se
-  button_delete: TÃ¶rÃ¶l
-  button_create: LÃ©trehoz
-  button_test: Teszt
-  button_edit: Szerkeszt
-  button_add: HozzÃ¡ad
-  button_change: VÃ¡ltoztat
-  button_apply: Alkalmaz
-  button_clear: TÃ¶rÃ¶l
-  button_lock: ZÃ¡rol
-  button_unlock: Felold
-  button_download: LetÃ¶ltÃ©s
-  button_list: Lista
-  button_view: MegnÃ©z
-  button_move: Mozgat
-  button_back: Vissza
-  button_cancel: MÃ©gse
-  button_activate: AktivÃ¡l
-  button_sort: RendezÃ©s
-  button_log_time: IdÅ‘ rÃ¶gzÃ­tÃ©s
-  button_rollback: VisszaÃ¡ll erre a verziÃ³ra
-  button_watch: Megfigyel
-  button_unwatch: MegfigyelÃ©s tÃ¶rlÃ©se
-  button_reply: VÃ¡lasz
-  button_archive: ArchivÃ¡l
-  button_unarchive: DearchivÃ¡l
-  button_reset: Reset
-  button_rename: Ãtnevez
-  button_change_password: JelszÃ³ megvÃ¡ltoztatÃ¡sa
-  button_copy: MÃ¡sol
-  button_annotate: Jegyzetel
-  button_update: MÃ³dosÃ­t
-  button_configure: KonfigurÃ¡l
-
-  status_active: aktÃ­v
-  status_registered: regisztrÃ¡lt
-  status_locked: zÃ¡rolt
-
-  text_select_mail_notifications: VÃ¡lasszon esemÃ©nyeket, amelyekrÅ‘l e-mail Ã©rtesÃ­tÃ©st kell kÃ¼ldeni.
-  text_regexp_info: pl. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 = nincs korlÃ¡tozÃ¡s
-  text_project_destroy_confirmation: Biztosan tÃ¶rÃ¶lni szeretnÃ© a projektet Ã©s vele egyÃ¼tt minden kapcsolÃ³dÃ³ adatot ?
-  text_subprojects_destroy_warning: "Az alprojekt(ek): %{value} szintÃ©n tÃ¶rlÃ©sre kerÃ¼lnek."
-  text_workflow_edit: VÃ¡lasszon egy szerepkÃ¶rt, Ã©s egy feladat tÃ­pust a workflow szerkesztÃ©sÃ©hez
-  text_are_you_sure: Biztos benne ?
-  text_tip_issue_begin_day: a feladat ezen a napon kezdÅ‘dik
-  text_tip_issue_end_day: a feladat ezen a napon Ã©r vÃ©get
-  text_tip_issue_begin_end_day: a feladat ezen a napon kezdÅ‘dik Ã©s Ã©r vÃ©get
-  text_project_identifier_info: 'Kis betÅ±k (a-z), szÃ¡mok Ã©s kÃ¶tÅ‘jel megengedett.<br />MentÃ©s utÃ¡n az azonosÃ­tÃ³t megvÃ¡ltoztatni nem lehet.'
-  text_caracters_maximum: "maximum %{count} karakter."
-  text_caracters_minimum: "Legkevesebb %{count} karakter hosszÃºnek kell lennie."
-  text_length_between: "LegalÃ¡bb %{min} Ã©s legfeljebb %{max} hosszÃº karakter."
-  text_tracker_no_workflow: Nincs workflow definiÃ¡lva ehhez a feladat tÃ­pushoz
-  text_unallowed_characters: Tiltott karakterek
-  text_comma_separated: TÃ¶bb Ã©rtÃ©k megengedett (vesszÅ‘vel elvÃ¡lasztva)
-  text_issues_ref_in_commit_messages: HivatkozÃ¡s feladatokra, feladatok javÃ­tÃ¡sa a commit Ã¼zenetekben
-  text_issue_added: "%{author} Ãºj feladatot hozott lÃ©tre %{id} sorszÃ¡mmal."
-  text_issue_updated: "%{author} mÃ³dosÃ­totta a %{id} sorszÃ¡mÃº feladatot."
-  text_wiki_destroy_confirmation: Biztosan tÃ¶rÃ¶lni szeretnÃ© ezt a wiki-t minden tartalmÃ¡val egyÃ¼tt ?
-  text_issue_category_destroy_question: "NÃ©hÃ¡ny feladat (%{count}) hozzÃ¡ van rendelve ehhez a kategÃ³riÃ¡hoz. Mit szeretne tenni?"
-  text_issue_category_destroy_assignments: KategÃ³ria hozzÃ¡rendelÃ©s megszÃ¼ntetÃ©se
-  text_issue_category_reassign_to: Feladatok Ãºjra hozzÃ¡rendelÃ©se mÃ¡sik kategÃ³riÃ¡hoz
-  text_user_mail_option: "A nem kivÃ¡lasztott projektekrÅ‘l csak akkor kap Ã©rtesÃ­tÃ©st, ha figyelÃ©st kÃ©r rÃ¡, vagy rÃ©szt vesz benne (pl. Ã–n a lÃ©trehozÃ³, vagy a hozzÃ¡rendelÅ‘)"
-  text_no_configuration_data: "SzerepkÃ¶rÃ¶k, feladat tÃ­pusok, feladat stÃ¡tuszok, Ã©s workflow adatok mÃ©g nincsenek konfigurÃ¡lva.\nErÅ‘sen ajÃ¡nlott, az alapÃ©rtelmezett konfigurÃ¡ciÃ³ betÃ¶ltÃ©se, Ã©s utÃ¡na mÃ³dosÃ­thatja azt."
-  text_load_default_configuration: AlapÃ©rtelmezett konfigurÃ¡ciÃ³ betÃ¶ltÃ©se
-  text_status_changed_by_changeset: "Applied in changeset %{value}."
-  text_issues_destroy_confirmation: 'Biztos benne, hogy tÃ¶rÃ¶lni szeretnÃ© a kijelÃ¶lt feladato(ka)t ?'
-  text_select_project_modules: 'VÃ¡lassza ki az engedÃ©lyezett modulokat ehhez a projekthez:'
-  text_default_administrator_account_changed: AlapÃ©rtelmezett adminisztrÃ¡tor fiÃ³k megvÃ¡ltoztatva
-  text_file_repository_writable: FÃ¡jl tÃ¡rolÃ³ Ã­rhatÃ³
-  text_rmagick_available: RMagick elÃ©rhetÅ‘ (nem kÃ¶telezÅ‘)
-  text_destroy_time_entries_question: "%{hours} Ã³rÃ¡nyi munka van rÃ¶gzÃ­tve a feladatokon, amiket tÃ¶rÃ¶lni szeretne. Mit szeretne tenni?"
-  text_destroy_time_entries: A rÃ¶gzÃ­tett Ã³rÃ¡k tÃ¶rlÃ©se
-  text_assign_time_entries_to_project: A rÃ¶gzÃ­tett Ã³rÃ¡k hozzÃ¡rendelÃ©se a projekthez
-  text_reassign_time_entries: 'A rÃ¶gzÃ­tett Ã³rÃ¡k Ãºjra hozzÃ¡rendelÃ©se mÃ¡sik feladathoz:'
-
-  default_role_manager: VezetÅ‘
-  default_role_developer: FejlesztÅ‘
-  default_role_reporter: BejelentÅ‘
-  default_tracker_bug: Hiba
-  default_tracker_feature: FejlesztÃ©s
-  default_tracker_support: TÃ¡mogatÃ¡s
-  default_issue_status_new: Ãšj
-  default_issue_status_in_progress: Folyamatban
-  default_issue_status_resolved: Megoldva
-  default_issue_status_feedback: VisszajelzÃ©s
-  default_issue_status_closed: LezÃ¡rt
-  default_issue_status_rejected: ElutasÃ­tott
-  default_doc_category_user: FelhasznÃ¡lÃ³i dokumentÃ¡ciÃ³
-  default_doc_category_tech: Technikai dokumentÃ¡ciÃ³
-  default_priority_low: Alacsony
-  default_priority_normal: NormÃ¡l
-  default_priority_high: Magas
-  default_priority_urgent: SÃ¼rgÅ‘s
-  default_priority_immediate: Azonnal
-  default_activity_design: TervezÃ©s
-  default_activity_development: FejlesztÃ©s
-
-  enumeration_issue_priorities: Feladat prioritÃ¡sok
-  enumeration_doc_categories: Dokumentum kategÃ³riÃ¡k
-  enumeration_activities: TevÃ©kenysÃ©gek (idÅ‘ rÃ¶gzÃ­tÃ©s)
-  mail_body_reminder: "%{count} neked kiosztott feladat hatÃ¡ridÅ‘s az elkÃ¶vetkezÅ‘ %{days} napban:"
-  mail_subject_reminder: "%{count} feladat hatÃ¡ridÅ‘s az elkÃ¶vetkezÅ‘ %{days} napban"
-  text_user_wrote: "%{value} Ã­rta:"
-  label_duplicated_by: duplikÃ¡lta
-  setting_enabled_scm: ForrÃ¡skÃ³dkezelÅ‘ (SCM) engedÃ©lyezÃ©se
-  text_enumeration_category_reassign_to: 'Ãšjra hozzÃ¡rendelÃ©s ehhez:'
-  text_enumeration_destroy_question: "%{count} objektum van hozzÃ¡rendelve ehhez az Ã©rtÃ©khez."
-  label_incoming_emails: BeÃ©rkezett levelek
-  label_generate_key: Kulcs generÃ¡lÃ¡sa
-  setting_mail_handler_api_enabled: Web Service engedÃ©lyezÃ©se a beÃ©rkezett levelekhez
-  setting_mail_handler_api_key: API kulcs
-  text_email_delivery_not_configured: "Az E-mail kÃ¼ldÃ©s nincs konfigurÃ¡lva, Ã©s az Ã©rtesÃ­tÃ©sek ki vannak kapcsolva.\nÃllÃ­tsd be az SMTP szervert a config/configuration.yml fÃ¡jlban Ã©s indÃ­tsd Ãºjra az alkalmazÃ¡st, hogy Ã©rvÃ©nybe lÃ©pjen."
-  field_parent_title: SzÃ¼lÅ‘ oldal
-  label_issue_watchers: MegfigyelÅ‘k
-  button_quote: HozzÃ¡szÃ³lÃ¡s / IdÃ©zet
-  setting_sequential_project_identifiers: SzekvenciÃ¡lis projekt azonosÃ­tÃ³k generÃ¡lÃ¡sa
-  notice_unable_delete_version: A verziÃ³t nem lehet tÃ¶rÃ¶lni
-  label_renamed: Ã¡tnevezve
-  label_copied: lemÃ¡solva
-  setting_plain_text_mail: csak szÃ¶veg (nem HTML)
-  permission_view_files: FÃ¡jlok megtekintÃ©se
-  permission_edit_issues: Feladatok szerkesztÃ©se
-  permission_edit_own_time_entries: SajÃ¡t idÅ‘naplÃ³ szerkesztÃ©se
-  permission_manage_public_queries: NyilvÃ¡nos kÃ©rÃ©sek kezelÃ©se
-  permission_add_issues: Feladat felvÃ©tele
-  permission_log_time: IdÅ‘ rÃ¶gzÃ­tÃ©se
-  permission_view_changesets: VÃ¡ltozÃ¡skÃ¶tegek megtekintÃ©se
-  permission_view_time_entries: IdÅ‘rÃ¶gzÃ­tÃ©sek megtekintÃ©se
-  permission_manage_versions: VerziÃ³k kezelÃ©se
-  permission_manage_wiki: Wiki kezelÃ©se
-  permission_manage_categories: Feladat kategÃ³riÃ¡k kezelÃ©se
-  permission_protect_wiki_pages: Wiki oldalak vÃ©delme
-  permission_comment_news: HÃ­rek kommentelÃ©se
-  permission_delete_messages: Ãœzenetek tÃ¶rlÃ©se
-  permission_select_project_modules: Projekt modulok kezelÃ©se
-  permission_manage_documents: Dokumentumok kezelÃ©se
-  permission_edit_wiki_pages: Wiki oldalak szerkesztÃ©se
-  permission_add_issue_watchers: MegfigyelÅ‘k felvÃ©tele
-  permission_view_gantt: Gannt diagramm megtekintÃ©se
-  permission_move_issues: Feladatok mozgatÃ¡sa
-  permission_manage_issue_relations: Feladat kapcsolatok kezelÃ©se
-  permission_delete_wiki_pages: Wiki oldalak tÃ¶rlÃ©se
-  permission_manage_boards: FÃ³rumok kezelÃ©se
-  permission_delete_wiki_pages_attachments: CsatolmÃ¡nyok tÃ¶rlÃ©se
-  permission_view_wiki_edits: Wiki tÃ¶rtÃ©net megtekintÃ©se
-  permission_add_messages: Ãœzenet bekÃ¼ldÃ©se
-  permission_view_messages: Ãœzenetek megtekintÃ©se
-  permission_manage_files: FÃ¡jlok kezelÃ©se
-  permission_edit_issue_notes: Jegyzetek szerkesztÃ©se
-  permission_manage_news: HÃ­rek kezelÃ©se
-  permission_view_calendar: NaptÃ¡r megtekintÃ©se
-  permission_manage_members: Tagok kezelÃ©se
-  permission_edit_messages: Ãœzenetek szerkesztÃ©se
-  permission_delete_issues: Feladatok tÃ¶rlÃ©se
-  permission_view_issue_watchers: MegfigyelÅ‘k listÃ¡zÃ¡sa
-  permission_manage_repository: TÃ¡rolÃ³k kezelÃ©se
-  permission_commit_access: Commit hozzÃ¡fÃ©rÃ©s
-  permission_browse_repository: TÃ¡rolÃ³ bÃ¶ngÃ©szÃ©se
-  permission_view_documents: Dokumetumok megtekintÃ©se
-  permission_edit_project: Projekt szerkesztÃ©se
-  permission_add_issue_notes: Jegyzet rÃ¶gzÃ­tÃ©se
-  permission_save_queries: KÃ©rÃ©sek mentÃ©se
-  permission_view_wiki_pages: Wiki megtekintÃ©se
-  permission_rename_wiki_pages: Wiki oldalak Ã¡tnevezÃ©se
-  permission_edit_time_entries: IdÅ‘naplÃ³k szerkesztÃ©se
-  permission_edit_own_issue_notes: SajÃ¡t jegyzetek szerkesztÃ©se
-  setting_gravatar_enabled: FelhasznÃ¡lÃ³i fÃ©nykÃ©pek engedÃ©lyezÃ©se
-  label_example: PÃ©lda
-  text_repository_usernames_mapping: "ÃllÃ­tsd be a felhasznÃ¡lÃ³ Ã¶sszerendelÃ©seket a Redmine, Ã©s a tÃ¡rolÃ³ logban talÃ¡lhatÃ³ felhasznÃ¡lÃ³k kÃ¶zÃ¶tt.\nAz azonos felhasznÃ¡lÃ³ nevek Ã¶sszerendelÃ©se automatikusan megtÃ¶rtÃ©nik."
-  permission_edit_own_messages: SajÃ¡t Ã¼zenetek szerkesztÃ©se
-  permission_delete_own_messages: SajÃ¡t Ã¼zenetek tÃ¶rlÃ©se
-  label_user_activity: "%{value} tevÃ©kenysÃ©gei"
-  label_updated_time_by: "MÃ³dosÃ­totta %{author} %{age}"
-  text_diff_truncated: '... A diff fÃ¡jl vÃ©ge nem jelenik meg, mert hosszab, mint a megjelenÃ­thetÅ‘ sorok szÃ¡ma.'
-  setting_diff_max_lines_displayed: A megjelenÃ­tendÅ‘ sorok szÃ¡ma (maximum) a diff fÃ¡jloknÃ¡l
-  text_plugin_assets_writable: Plugin eszkÃ¶zÃ¶k kÃ¶nyvtÃ¡r Ã­rhatÃ³
-  warning_attachments_not_saved: "%{count} fÃ¡jl mentÃ©se nem sikerÃ¼lt."
-  button_create_and_continue: LÃ©trehozÃ¡s Ã©s folytatÃ¡s
-  text_custom_field_possible_values_info: 'Ã‰rtÃ©kenkÃ©nt egy sor'
-  label_display: Megmutat
-  field_editable: SzerkeszthetÅ‘
-  setting_repository_log_display_limit: Maximum hÃ¡ny revÃ­ziÃ³t mutasson meg a log megjelenÃ­tÃ©sekor
-  setting_file_max_size_displayed: Maximum mekkora szÃ¶vegfÃ¡jlokat jelenÃ­tsen meg soronkÃ©nti Ã¶sszehasonlÃ­tÃ¡snÃ¡l
-  field_watcher: MegfigyelÅ‘
-  setting_openid: OpenID regisztrÃ¡ciÃ³ Ã©s bejelentkezÃ©s engedÃ©lyezÃ©se
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: bejelentkezÃ©s OpenID hasznÃ¡latÃ¡val
-  field_content: Tartalom
-  label_descending: CsÃ¶kkenÅ‘
-  label_sort: RendezÃ©s
-  label_ascending: NÃ¶vekvÅ‘
-  label_date_from_to: "%{start} -tÃ³l %{end} -ig"
-  label_greater_or_equal: ">="
-  label_less_or_equal: "<="
-  text_wiki_page_destroy_question: Ennek az oldalnak %{descendants} gyermek-, Ã©s leszÃ¡rmazott oldala van. Mit szeretne tenni?
-  text_wiki_page_reassign_children: Aloldalak hozzÃ¡rendelÃ©se ehhez a szÃ¼lÅ‘ oldalhoz
-  text_wiki_page_nullify_children: Aloldalak Ã¡talakÃ­tÃ¡sa fÅ‘oldallÃ¡
-  text_wiki_page_destroy_children: Minden aloldal Ã©s leszÃ¡rmazottjÃ¡nak tÃ¶rlÃ©se
-  setting_password_min_length: Minimum jelszÃ³ hosszÃºsÃ¡g
-  field_group_by: Szerint csoportosÃ­tva
-  mail_subject_wiki_content_updated: "'%{id}' wiki oldal frissÃ­tve"
-  label_wiki_content_added: Wiki oldal hozzÃ¡adva
-  mail_subject_wiki_content_added: "Ãšj wiki oldal: '%{id}'"
-  mail_body_wiki_content_added: "%{author} lÃ©trehozta a '%{id}' wiki oldalt."
-  label_wiki_content_updated: Wiki oldal frissÃ­tve
-  mail_body_wiki_content_updated: "%{author} frissÃ­tette a '%{id}' wiki oldalt."
-  permission_add_project: Projekt lÃ©trehozÃ¡sa
-  setting_new_project_user_role_id: Projekt lÃ©trehozÃ¡si jog nem adminisztrÃ¡tor felhasznÃ¡lÃ³knak
-  label_view_all_revisions: Ã–sszes verziÃ³
-  label_tag: Tag
-  label_branch: Branch
-  error_no_tracker_in_project: Nincs feladat tÃ­pus hozzÃ¡rendelve ehhez a projekthez. KÃ©rem ellenÅ‘rizze a projekt beÃ¡llÃ­tÃ¡sait.
-  error_no_default_issue_status: Nincs alapÃ©rtelmezett feladat stÃ¡tusz beÃ¡llÃ­tva. KÃ©rem ellenÅ‘rizze a beÃ¡llÃ­tÃ¡sokat (Itt talÃ¡lja "AdminisztrÃ¡ciÃ³ -> Feladat stÃ¡tuszok").
-  text_journal_changed: "%{label} megvÃ¡ltozott, %{old} helyett %{new} lett"
-  text_journal_set_to: "%{label} Ãºj Ã©rtÃ©ke: %{value}"
-  text_journal_deleted: "%{label} tÃ¶rÃ¶lve lett (%{old})"
-  label_group_plural: Csoportok
-  label_group: Csoport
-  label_group_new: Ãšj csoport
-  label_time_entry_plural: IdÅ‘rÃ¡fordÃ­tÃ¡s
-  text_journal_added: "%{label} %{value} hozzÃ¡adva"
-  field_active: AktÃ­v
-  enumeration_system_activity: RendszertevÃ©kenysÃ©g
-  permission_delete_issue_watchers: MegfigyelÅ‘k tÃ¶rlÃ©se
-  version_status_closed: lezÃ¡rt
-  version_status_locked: zÃ¡rolt
-  version_status_open: nyitott
-  error_can_not_reopen_issue_on_closed_version: LezÃ¡rt verziÃ³hoz rendelt feladatot nem lehet Ãºjranyitni
-  label_user_anonymous: NÃ©vtelen
-  button_move_and_follow: MozgatÃ¡s Ã©s kÃ¶vetÃ©s
-  setting_default_projects_modules: AlapÃ©rtelmezett modulok az Ãºj projektekhez
-  setting_gravatar_default: AlapÃ©rtelmezett Gravatar kÃ©p
-  field_sharing: MegosztÃ¡s
-  label_version_sharing_hierarchy: Projekt hierarchiÃ¡val
-  label_version_sharing_system: Minden projekttel
-  label_version_sharing_descendants: Alprojektekkel
-  label_version_sharing_tree: Projekt fÃ¡val
-  label_version_sharing_none: Nincs megosztva
-  error_can_not_archive_project: A projektet nem lehet archivÃ¡lni
-  button_duplicate: DuplikÃ¡lÃ¡s
-  button_copy_and_follow: MÃ¡solÃ¡s Ã©s kÃ¶vetÃ©s
-  label_copy_source: ForrÃ¡s
-  setting_issue_done_ratio: Feladat kÃ©szÃ¼ltsÃ©gi szint szÃ¡molÃ¡sa a kÃ¶vetkezÅ‘ alapjÃ¡n
-  setting_issue_done_ratio_issue_status: Feladat stÃ¡tusz alapjÃ¡n
-  error_issue_done_ratios_not_updated: A feladat kÃ©szÃ¼ltsÃ©gi szintek nem lettek frissÃ­tve.
-  error_workflow_copy_target: KÃ©rem vÃ¡lasszon cÃ©l feladat tÃ­pus(oka)t Ã©s szerepkÃ¶r(Ã¶ke)t.
-  setting_issue_done_ratio_issue_field: A feladat mezÅ‘ alapjÃ¡n
-  label_copy_same_as_target: A cÃ©llal egyezÅ‘
-  label_copy_target: CÃ©l
-  notice_issue_done_ratios_updated: Feladat kÃ©szÃ¼ltsÃ©gi szintek frissÃ­tve.
-  error_workflow_copy_source: KÃ©rem vÃ¡lasszon forrÃ¡s feladat tÃ­pust vagy szerepkÃ¶rt
-  label_update_issue_done_ratios: Feladat kÃ©szÃ¼ltsÃ©gi szintek frissÃ­tÃ©se
-  setting_start_of_week: A hÃ©t elsÅ‘ napja
-  permission_view_issues: Feladatok megtekintÃ©se
-  label_display_used_statuses_only: Csak olyan feladat stÃ¡tuszok megjelenÃ­tÃ©se, amit ez a feladat tÃ­pus hasznÃ¡l
-  label_revision_id: RevÃ­ziÃ³ %{value}
-  label_api_access_key: API hozzÃ¡fÃ©rÃ©si kulcs
-  label_api_access_key_created_on: API hozzÃ¡fÃ©rÃ©si kulcs lÃ©trehozva %{value} ezelÅ‘tt
-  label_feeds_access_key: RSS hozzÃ¡fÃ©rÃ©si kulcs
-  notice_api_access_key_reseted: Az API hozzÃ¡fÃ©rÃ©si kulcsa ÃºjragenerÃ¡lva.
-  setting_rest_api_enabled: REST web service engedÃ©lyezÃ©se
-  label_missing_api_access_key: Egy API hozzÃ¡fÃ©rÃ©si kulcs hiÃ¡nyzik
-  label_missing_feeds_access_key: RSS hozzÃ¡fÃ©rÃ©si kulcs hiÃ¡nyzik
-  button_show: Megmutat
-  text_line_separated: TÃ¶bb Ã©rtÃ©k megadÃ¡sa lehetsÃ©ges (soronkÃ©nt 1 Ã©rtÃ©k).
-  setting_mail_handler_body_delimiters: E-mailek levÃ¡gÃ¡sa a kÃ¶vetkezÅ‘ sorok valamelyike esetÃ©n
-  permission_add_subprojects: Alprojektek lÃ©trehozÃ¡sa
-  label_subproject_new: Ãšj alprojekt
-  text_own_membership_delete_confirmation: |-
-    Arra kÃ©szÃ¼l, hogy eltÃ¡volÃ­tja egyes vagy minden jogosultsÃ¡gÃ¡t! Ezt kÃ¶vetÅ‘en lehetsÃ©ges, hogy nem fogja tudni szerkeszteni ezt a projektet!
-    Biztosan folyatni szeretnÃ©?
-  label_close_versions: KÃ©sz verziÃ³k lezÃ¡rÃ¡sa
-  label_board_sticky: Sticky
-  setting_cache_formatted_text: FormÃ¡zott szÃ¶veg gyorsÃ­tÃ³tÃ¡razÃ¡sa (Cache)
-  permission_export_wiki_pages: Wiki oldalak exportÃ¡lÃ¡sa
-  permission_manage_project_activities: Projekt tevÃ©kenysÃ©gek kezelÃ©se
-  label_board_locked: ZÃ¡rolt
-  error_can_not_delete_custom_field: Nem lehet tÃ¶rÃ¶lni az egyÃ©ni mezÅ‘t
-  permission_manage_subtasks: Alfeladatok kezelÃ©se
-  label_profile: Profil
-  error_unable_to_connect: Nem lehet csatlakozni (%{value})
-  error_can_not_remove_role: Ez a szerepkÃ¶r hasznÃ¡latban van Ã©s ezÃ©rt nem tÃ¶rÃ¶lhetÅ‘-
-  field_parent_issue: SzÃ¼lÅ‘ feladat
-  error_unable_delete_issue_status: Nem lehet tÃ¶rÃ¶lni a feladat Ã¡llapotÃ¡t
-  label_subtask_plural: Alfeladatok
-  error_can_not_delete_tracker: Ebbe a kategÃ³riÃ¡ba feladatok tartoznak Ã©s ezÃ©rt nem tÃ¶rÃ¶lhetÅ‘.
-  label_project_copy_notifications: KÃ¼ldjÃ¶n e-mail Ã©rtesÃ­tÃ©seket projektmÃ¡solÃ¡s kÃ¶zben.
-  field_principal: FelelÅ‘s
-  label_my_page_block: SajÃ¡t kezdÅ‘lap-blokk
-  notice_failed_to_save_members: "Nem sikerÃ¼lt menteni a tago(ka)t: %{errors}."
-  text_zoom_out: KicsinyÃ­t
-  text_zoom_in: NagyÃ­t
-  notice_unable_delete_time_entry: Az idÅ‘rÃ¶gzÃ­tÃ©s nem tÃ¶rÃ¶lhetÅ‘
-  label_overall_spent_time: Ã–sszes rÃ¡fordÃ­tott idÅ‘
-  field_time_entries: IdÅ‘ rÃ¶gzÃ­tÃ©s
-  project_module_gantt: Gantt
-  project_module_calendar: NaptÃ¡r
-  button_edit_associated_wikipage: "HozzÃ¡rendelt Wiki oldal szerkesztÃ©se: %{page_title}"
-  text_are_you_sure_with_children: A feladat tÃ¶rlÃ©se az Ã¶sszes alfeladattal egyÃ¼tt?
-  field_text: SzÃ¶veg mezÅ‘
-  label_user_mail_option_only_owner: Csak arrÃ³l, aminek Ã©n vagyok a tulajdonosa
-  setting_default_notification_option: AlapÃ©rtelmezett Ã©rtesÃ­tÃ©si beÃ¡llÃ­tÃ¡sok
-  label_user_mail_option_only_my_events: Csak az Ã¡ltalam megfigyelt dolgokrÃ³l vagy amiben rÃ©szt veszek
-  label_user_mail_option_only_assigned: Csak a hozzÃ¡mrendelt dolgokrÃ³l
-  label_user_mail_option_none: Semilyen esemÃ©nyrÅ‘l
-  field_member_of_group: HozzÃ¡rendelt csoport
-  field_assigned_to_role: HozzÃ¡rendelt szerepkÃ¶r
-  notice_not_authorized_archived_project: A projekt, amihez hozzÃ¡ szeretnÃ©l fÃ©rni archivÃ¡lva lett.
-  label_principal_search: "FelhasznÃ¡lÃ³ vagy csoport keresÃ©se:"
-  label_user_search: "FelhasznÃ¡lÃ³ keresÃ©se:"
-  field_visible: LÃ¡thatÃ³
-  setting_emails_header: Emailek fejlÃ©ce
-  setting_commit_logtime_activity_id: A rÃ¶gzÃ­tett idÅ‘hÃ¶z tartozÃ³ tevÃ©kenysÃ©g
-  text_time_logged_by_changeset: Alkalmazva a %{value} changeset-ben.
-  setting_commit_logtime_enabled: IdÅ‘rÃ¶gzÃ­tÃ©s engedÃ©lyezÃ©se
-  notice_gantt_chart_truncated: A diagram le lett vÃ¡gva, mert elÃ©rte a maximÃ¡lisan megjelenÃ­thetÅ‘ elemek szÃ¡mÃ¡t (%{max})
-  setting_gantt_items_limit: A gantt diagrammon megjelenÃ­thetÅ‘ maximÃ¡lis elemek szÃ¡ma
-  field_warn_on_leaving_unsaved: Figyelmeztessen, nem mentett mÃ³dosÃ­tÃ¡sokat tartalmazÃ³ oldal elhagyÃ¡sakor
-  text_warn_on_leaving_unsaved: A jelenlegi oldal nem mentett mÃ³dosÃ­tÃ¡sokat tartalmaz, ami elvÃ©sz, ha elhagyja az oldalt.
-  label_my_queries: EgyÃ©ni lekÃ©rdezÃ©seim
-  text_journal_changed_no_detail: "%{label} mÃ³dosÃ­tva"
-  label_news_comment_added: MegjegyzÃ©s hozzÃ¡adva a hÃ­rhez
-  button_expand_all: Mindet kibont
-  button_collapse_all: Mindet Ã¶sszecsuk
-  label_additional_workflow_transitions_for_assignee: TovÃ¡bbi Ã¡tmenetek engedÃ©lyezettek, ha a felhasznÃ¡lÃ³ a hozzÃ¡rendelt
-  label_additional_workflow_transitions_for_author: TovÃ¡bbi Ã¡tmenetek engedÃ©lyezettek, ha a felhasznÃ¡lÃ³ a szerzÅ‘
-  label_bulk_edit_selected_time_entries: A kivÃ¡lasztott idÅ‘ bejegyzÃ©sek csoportos szerkesztÃ©se
-  text_time_entries_destroy_confirmation: Biztos benne, hogy tÃ¶rÃ¶lni szeretnÃ© a kivÃ¡lasztott idÅ‘ bejegyzÃ©s(eke)t?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Nem tag
-  label_issue_note_added: Jegyzet hozzÃ¡adva
-  label_issue_status_updated: Ãllapot mÃ³dosÃ­tva
-  label_issue_priority_updated: PrioritÃ¡s mÃ³dosÃ­tva
-  label_issues_visibility_own: A felhasznÃ¡lÃ³ Ã¡ltal lÃ©trehozott vagy hozzÃ¡rendelt feladatok
-  field_issues_visibility: Feladatok lÃ¡thatÃ³sÃ¡ga
-  label_issues_visibility_all: Minden feladat
-  permission_set_own_issues_private: SajÃ¡t feladatok beÃ¡llÃ­tÃ¡sa nyilvÃ¡nosra vagy privÃ¡tra
-  field_is_private: PrivÃ¡t
-  permission_set_issues_private: Feladatok beÃ¡llÃ­tÃ¡sa nyilvÃ¡nosra vagy privÃ¡tra
-  label_issues_visibility_public: Minden nem privÃ¡t feladat
-  text_issues_destroy_descendants_confirmation: Ezzel tÃ¶rÃ¶lni fog %{count} alfeladatot is.
-  field_commit_logs_encoding: Commit Ã¼zenetek kÃ³dlapja
-  field_scm_path_encoding: ElÃ©rÃ©si Ãºtvonal kÃ³dlapja
-  text_scm_path_encoding_note: "AlapÃ©rtelmezett: UTF-8"
-  field_path_to_repository: A repository elÃ©rÃ©si Ãºtja
-  field_root_directory: GyÃ¶kÃ©r kÃ¶nyvtÃ¡r
-  field_cvs_module: Modul
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Helyi repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Parancs
-  text_scm_command_version: VerziÃ³
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a2/a22c9b7663ad593c48eebef0aad08af8d08a2dc8.svn-base
--- /dev/null
+++ b/.svn/pristine/a2/a22c9b7663ad593c48eebef0aad08af8d08a2dc8.svn-base
@@ -0,0 +1,106 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::IssueRelationsTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :issue_relations
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "/issues/:issue_id/relations" do
+    context "GET" do
+      should "return issue relations" do
+        get '/issues/9/relations.xml', {}, credentials('jsmith')
+
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+
+        assert_tag :tag => 'relations',
+          :attributes => { :type => 'array' },
+          :child => {
+            :tag => 'relation',
+            :child => {
+              :tag => 'id',
+              :content => '1'
+            }
+          }
+      end
+    end
+
+    context "POST" do
+      should "create a relation" do
+        assert_difference('IssueRelation.count') do
+          post '/issues/2/relations.xml', {:relation => {:issue_to_id => 7, :relation_type => 'relates'}}, credentials('jsmith')
+        end
+
+        relation = IssueRelation.first(:order => 'id DESC')
+        assert_equal 2, relation.issue_from_id
+        assert_equal 7, relation.issue_to_id
+        assert_equal 'relates', relation.relation_type
+
+        assert_response :created
+        assert_equal 'application/xml', @response.content_type
+        assert_tag 'relation', :child => {:tag => 'id', :content => relation.id.to_s}
+      end
+
+      context "with failure" do
+        should "return the errors" do
+          assert_no_difference('IssueRelation.count') do
+            post '/issues/2/relations.xml', {:relation => {:issue_to_id => 7, :relation_type => 'foo'}}, credentials('jsmith')
+          end
+
+          assert_response :unprocessable_entity
+          assert_tag :errors, :child => {:tag => 'error', :content => /relation_type is not included in the list/}
+        end
+      end
+    end
+  end
+
+  context "/relations/:id" do
+    context "GET" do
+      should "return the relation" do
+        get '/relations/2.xml', {}, credentials('jsmith')
+
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+        assert_tag 'relation', :child => {:tag => 'id', :content => '2'}
+      end
+    end
+
+    context "DELETE" do
+      should "delete the relation" do
+        assert_difference('IssueRelation.count', -1) do
+          delete '/relations/2.xml', {}, credentials('jsmith')
+        end
+
+        assert_response :ok
+        assert_equal '', @response.body
+        assert_nil IssueRelation.find_by_id(2)
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a2/a24374b3618d9455812155a3976144150853b3fd.svn-base
--- a/.svn/pristine/a2/a24374b3618d9455812155a3976144150853b3fd.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-<h2><%=l(:label_document_new)%></h2>
-
-<% form_tag({:controller => 'documents', :action => 'new', :project_id => @project}, :class => "tabular", :multipart => true) do %>
-<%= render :partial => 'documents/form' %>
-
-<div class="box">
-<p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
-</div>
-
-<%= submit_tag l(:button_create) %>
-<% end %>
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a2/a27c3b5814ea1895f7ea3d02838df38fe1a7358a.svn-base
--- a/.svn/pristine/a2/a27c3b5814ea1895f7ea3d02838df38fe1a7358a.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-<div class="nodata">
-<% form_tag({:action => 'default_configuration'}) do %>
-    <%= simple_format(l(:text_no_configuration_data)) %>
-    <p><%= l(:field_language) %>:
-    <%= select_tag 'lang', options_for_select(lang_options_for_select(false), current_language.to_s) %>
-    <%= submit_tag l(:text_load_default_configuration) %></p>
-<% end %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a2/a287706354ad35bfd9b7a22dc5edd1bfb0f897d3.svn-base
--- /dev/null
+++ b/.svn/pristine/a2/a287706354ad35bfd9b7a22dc5edd1bfb0f897d3.svn-base
@@ -0,0 +1,74 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class MailHandlerControllerTest < ActionController::TestCase
+  fixtures :users, :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :issue_statuses,
+           :trackers, :projects_trackers, :enumerations
+
+  FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
+
+  def setup
+    User.current = nil
+  end
+
+  def test_should_create_issue
+    # Enable API and set a key
+    Setting.mail_handler_api_enabled = 1
+    Setting.mail_handler_api_key = 'secret'
+
+    assert_difference 'Issue.count' do
+      post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
+    end
+    assert_response 201
+  end
+
+  def test_should_respond_with_422_if_not_created
+    Project.find('onlinestore').destroy
+
+    Setting.mail_handler_api_enabled = 1
+    Setting.mail_handler_api_key = 'secret'
+
+    assert_no_difference 'Issue.count' do
+      post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
+    end
+    assert_response 422
+  end
+
+  def test_should_not_allow_with_api_disabled
+    # Disable API
+    Setting.mail_handler_api_enabled = 0
+    Setting.mail_handler_api_key = 'secret'
+
+    assert_no_difference 'Issue.count' do
+      post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
+    end
+    assert_response 403
+  end
+
+  def test_should_not_allow_with_wrong_key
+    # Disable API
+    Setting.mail_handler_api_enabled = 1
+    Setting.mail_handler_api_key = 'secret'
+
+    assert_no_difference 'Issue.count' do
+      post :index, :key => 'wrong', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
+    end
+    assert_response 403
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a2/a2c9e135b5c07d36380e77abbbd164596d15660d.svn-base
--- /dev/null
+++ b/.svn/pristine/a2/a2c9e135b5c07d36380e77abbbd164596d15660d.svn-base
@@ -0,0 +1,100 @@
+.jstEditor {
+    padding-left: 0px;
+}
+.jstEditor textarea, .jstEditor iframe {
+    margin: 0;
+}
+
+.jstHandle {
+    height: 10px;
+    font-size: 0.1em;
+    cursor: s-resize;
+    /*background: transparent url(img/resizer.png) no-repeat 45% 50%;*/
+}
+
+.jstElements {
+    padding: 3px 3px 3px 0;
+}
+
+.jstElements button {
+    margin-right: 4px;
+    width : 24px;
+    height: 24px;
+    padding: 4px;
+    border-style: solid;
+    border-width: 1px;
+    border-color: #ddd;
+    background-color : #f7f7f7;
+    background-position : 50% 50%;
+    background-repeat: no-repeat;
+}
+.jstElements button:hover {
+    border-color: #bbb;
+  background-color: #e5e5e5;
+}
+.jstElements button span {
+    display : none;	
+}
+.jstElements span {
+    display : inline;
+}
+
+.jstSpacer {
+    width : 0px;
+    font-size: 1px;
+    margin-right: 6px;
+}
+
+.jstElements .help { float: right; margin-right: 0.5em; padding-top: 8px; font-size: 0.9em; }
+.jstElements .help a {padding: 2px 0 2px 20px; background: url(../images/help.png) no-repeat 0 50%;}
+
+/* Buttons
+-------------------------------------------------------- */
+.jstb_strong {
+    background-image: url(../images/jstoolbar/bt_strong.png);
+}
+.jstb_em {
+    background-image: url(../images/jstoolbar/bt_em.png);
+}
+.jstb_ins {
+    background-image: url(../images/jstoolbar/bt_ins.png);
+}
+.jstb_del {
+    background-image: url(../images/jstoolbar/bt_del.png);
+}
+.jstb_code {
+    background-image: url(../images/jstoolbar/bt_code.png);
+}
+.jstb_h1 {
+    background-image: url(../images/jstoolbar/bt_h1.png);
+}
+.jstb_h2 {
+    background-image: url(../images/jstoolbar/bt_h2.png);
+}
+.jstb_h3 {
+    background-image: url(../images/jstoolbar/bt_h3.png);
+}
+.jstb_ul {
+    background-image: url(../images/jstoolbar/bt_ul.png);
+}
+.jstb_ol {
+    background-image: url(../images/jstoolbar/bt_ol.png);
+}
+.jstb_bq {
+    background-image: url(../images/jstoolbar/bt_bq.png);
+}
+.jstb_unbq {
+    background-image: url(../images/jstoolbar/bt_bq_remove.png);
+}
+.jstb_pre {
+    background-image: url(../images/jstoolbar/bt_pre.png);
+}
+.jstb_link {
+    background-image: url(../images/jstoolbar/bt_link.png);
+}
+.jstb_img {
+    background-image: url(../images/jstoolbar/bt_img.png);
+}
+.jstb_help {
+    background-image: url(../images/help.png);
+}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a2/a2f5d2cfdb3401fa081b47084d01e011e03ca83c.svn-base
--- /dev/null
+++ b/.svn/pristine/a2/a2f5d2cfdb3401fa081b47084d01e011e03ca83c.svn-base
@@ -0,0 +1,11 @@
+<% if @notes %>
+  <fieldset class="preview"><legend><%= l(:field_notes) %></legend>
+    <%= textilizable @notes, :attachments => @attachments, :object => @issue %>
+  </fieldset>
+<% end %>
+
+<% if @description %>
+  <fieldset class="preview"><legend><%= l(:field_description) %></legend>
+    <%= textilizable @description, :attachments => @attachments, :object => @issue %>
+  </fieldset>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a3/a30059c9223b592d756029845dc7d985a8e70d73.svn-base
--- a/.svn/pristine/a3/a30059c9223b592d756029845dc7d985a8e70d73.svn-base
+++ /dev/null
@@ -1,68 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class SysController < ActionController::Base
-  before_filter :check_enabled
-
-  def projects
-    p = Project.active.has_module(:repository).find(:all, :include => :repository, :order => 'identifier')
-    # extra_info attribute from repository breaks activeresource client
-    render :xml => p.to_xml(:only => [:id, :identifier, :name, :is_public, :status], :include => {:repository => {:only => [:id, :url]}})
-  end
-
-  def create_project_repository
-    project = Project.find(params[:id])
-    if project.repository
-      render :nothing => true, :status => 409
-    else
-      logger.info "Repository for #{project.name} was reported to be created by #{request.remote_ip}."
-      project.repository = Repository.factory(params[:vendor], params[:repository])
-      if project.repository && project.repository.save
-        render :xml => project.repository.to_xml(:only => [:id, :url]), :status => 201
-      else
-        render :nothing => true, :status => 422
-      end
-    end
-  end
-
-  def fetch_changesets
-    projects = []
-    if params[:id]
-      projects << Project.active.has_module(:repository).find(params[:id])
-    else
-      projects = Project.active.has_module(:repository).find(:all, :include => :repository)
-    end
-    projects.each do |project|
-      if project.repository
-        project.repository.fetch_changesets
-      end
-    end
-    render :nothing => true, :status => 200
-  rescue ActiveRecord::RecordNotFound
-    render :nothing => true, :status => 404
-  end
-
-  protected
-
-  def check_enabled
-    User.current = nil
-    unless Setting.sys_api_enabled? && params[:key].to_s == Setting.sys_api_key
-      render :text => 'Access denied. Repository management WS is disabled or key is invalid.', :status => 403
-      return false
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a3/a345da33b5d730db2fa4453ba2e9a3bfdd694d8f.svn-base
--- a/.svn/pristine/a3/a345da33b5d730db2fa4453ba2e9a3bfdd694d8f.svn-base
+++ /dev/null
@@ -1,65 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Acts
-    module Attachable
-      def self.included(base)
-        base.extend ClassMethods
-      end
-
-      module ClassMethods
-        def acts_as_attachable(options = {})
-          cattr_accessor :attachable_options
-          self.attachable_options = {}
-          attachable_options[:view_permission] = options.delete(:view_permission) || "view_#{self.name.pluralize.underscore}".to_sym
-          attachable_options[:delete_permission] = options.delete(:delete_permission) || "edit_#{self.name.pluralize.underscore}".to_sym
-          
-          has_many :attachments, options.merge(:as => :container,
-                                               :order => "#{Attachment.table_name}.created_on",
-                                               :dependent => :destroy)
-          attr_accessor :unsaved_attachments
-          after_initialize :initialize_unsaved_attachments
-          send :include, Redmine::Acts::Attachable::InstanceMethods
-        end
-      end
-
-      module InstanceMethods
-        def self.included(base)
-          base.extend ClassMethods
-        end
-        
-        def attachments_visible?(user=User.current)
-          (respond_to?(:visible?) ? visible?(user) : true) &&
-            user.allowed_to?(self.class.attachable_options[:view_permission], self.project)
-        end
-        
-        def attachments_deletable?(user=User.current)
-          (respond_to?(:visible?) ? visible?(user) : true) &&
-            user.allowed_to?(self.class.attachable_options[:delete_permission], self.project)
-        end
-
-        def initialize_unsaved_attachments
-          @unsaved_attachments ||= []
-        end
-
-        module ClassMethods
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a3/a363794048b21aea80eb83bb41f65aa9764ee31a.svn-base
--- /dev/null
+++ b/.svn/pristine/a3/a363794048b21aea80eb83bb41f65aa9764ee31a.svn-base
@@ -0,0 +1,61 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingRolesTest < ActionController::IntegrationTest
+  def test_roles
+    assert_routing(
+        { :method => 'get', :path => "/roles" },
+        { :controller => 'roles', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/roles.xml" },
+        { :controller => 'roles', :action => 'index', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/roles/2.xml" },
+        { :controller => 'roles', :action => 'show', :id => '2', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/roles/new" },
+        { :controller => 'roles', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/roles" },
+        { :controller => 'roles', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/roles/2/edit" },
+        { :controller => 'roles', :action => 'edit', :id => '2' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/roles/2" },
+        { :controller => 'roles', :action => 'update', :id => '2' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/roles/2" },
+        { :controller => 'roles', :action => 'destroy', :id => '2' }
+      )
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/roles/permissions" },
+          { :controller => 'roles', :action => 'permissions' }
+        )
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a3/a364456950eb9dddb03948fc2af9610fa32b4fac.svn-base
--- /dev/null
+++ b/.svn/pristine/a3/a364456950eb9dddb03948fc2af9610fa32b4fac.svn-base
@@ -0,0 +1,13 @@
+class AddDeleteWikiPagesAttachmentsPermission < ActiveRecord::Migration
+  def self.up
+    Role.all.each do |r|
+      r.add_permission!(:delete_wiki_pages_attachments) if r.has_permission?(:edit_wiki_pages)
+    end
+  end
+
+  def self.down
+    Role.all.each do |r|
+      r.remove_permission!(:delete_wiki_pages_attachments)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a3/a39dfd4bdc71ffef44da946a57f879f5baad33bc.svn-base
--- /dev/null
+++ b/.svn/pristine/a3/a39dfd4bdc71ffef44da946a57f879f5baad33bc.svn-base
@@ -0,0 +1,831 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class QueryColumn
+  attr_accessor :name, :sortable, :groupable, :default_order
+  include Redmine::I18n
+
+  def initialize(name, options={})
+    self.name = name
+    self.sortable = options[:sortable]
+    self.groupable = options[:groupable] || false
+    if groupable == true
+      self.groupable = name.to_s
+    end
+    self.default_order = options[:default_order]
+    @inline = options.key?(:inline) ? options[:inline] : true
+    @caption_key = options[:caption] || "field_#{name}".to_sym
+    @frozen = options[:frozen]
+  end
+
+  def caption
+    @caption_key.is_a?(Symbol) ? l(@caption_key) : @caption_key
+  end
+
+  # Returns true if the column is sortable, otherwise false
+  def sortable?
+    !@sortable.nil?
+  end
+
+  def sortable
+    @sortable.is_a?(Proc) ? @sortable.call : @sortable
+  end
+
+  def inline?
+    @inline
+  end
+
+  def frozen?
+    @frozen
+  end
+
+  def value(object)
+    object.send name
+  end
+
+  def css_classes
+    name
+  end
+end
+
+class QueryCustomFieldColumn < QueryColumn
+
+  def initialize(custom_field)
+    self.name = "cf_#{custom_field.id}".to_sym
+    self.sortable = custom_field.order_statement || false
+    self.groupable = custom_field.group_statement || false
+    @inline = true
+    @cf = custom_field
+  end
+
+  def caption
+    @cf.name
+  end
+
+  def custom_field
+    @cf
+  end
+
+  def value(object)
+    cv = object.custom_values.select {|v| v.custom_field_id == @cf.id}.collect {|v| @cf.cast_value(v.value)}
+    cv.size > 1 ? cv.sort {|a,b| a.to_s <=> b.to_s} : cv.first
+  end
+
+  def css_classes
+    @css_classes ||= "#{name} #{@cf.field_format}"
+  end
+end
+
+class QueryAssociationCustomFieldColumn < QueryCustomFieldColumn
+
+  def initialize(association, custom_field)
+    super(custom_field)
+    self.name = "#{association}.cf_#{custom_field.id}".to_sym
+    # TODO: support sorting/grouping by association custom field
+    self.sortable = false
+    self.groupable = false
+    @association = association
+  end
+
+  def value(object)
+    if assoc = object.send(@association)
+      super(assoc)
+    end
+  end
+
+  def css_classes
+    @css_classes ||= "#{@association}_cf_#{@cf.id} #{@cf.field_format}"
+  end
+end
+
+class Query < ActiveRecord::Base
+  class StatementInvalid < ::ActiveRecord::StatementInvalid
+  end
+
+  belongs_to :project
+  belongs_to :user
+  serialize :filters
+  serialize :column_names
+  serialize :sort_criteria, Array
+
+  attr_protected :project_id, :user_id
+
+  validates_presence_of :name
+  validates_length_of :name, :maximum => 255
+  validate :validate_query_filters
+
+  class_attribute :operators
+  self.operators = {
+    "="   => :label_equals,
+    "!"   => :label_not_equals,
+    "o"   => :label_open_issues,
+    "c"   => :label_closed_issues,
+    "!*"  => :label_none,
+    "*"   => :label_any,
+    ">="  => :label_greater_or_equal,
+    "<="  => :label_less_or_equal,
+    "><"  => :label_between,
+    "<t+" => :label_in_less_than,
+    ">t+" => :label_in_more_than,
+    "><t+"=> :label_in_the_next_days,
+    "t+"  => :label_in,
+    "t"   => :label_today,
+    "ld"  => :label_yesterday,
+    "w"   => :label_this_week,
+    "lw"  => :label_last_week,
+    "l2w" => [:label_last_n_weeks, {:count => 2}],
+    "m"   => :label_this_month,
+    "lm"  => :label_last_month,
+    "y"   => :label_this_year,
+    ">t-" => :label_less_than_ago,
+    "<t-" => :label_more_than_ago,
+    "><t-"=> :label_in_the_past_days,
+    "t-"  => :label_ago,
+    "~"   => :label_contains,
+    "!~"  => :label_not_contains,
+    "=p"  => :label_any_issues_in_project,
+    "=!p" => :label_any_issues_not_in_project,
+    "!p"  => :label_no_issues_in_project
+  }
+
+  class_attribute :operators_by_filter_type
+  self.operators_by_filter_type = {
+    :list => [ "=", "!" ],
+    :list_status => [ "o", "=", "!", "c", "*" ],
+    :list_optional => [ "=", "!", "!*", "*" ],
+    :list_subprojects => [ "*", "!*", "=" ],
+    :date => [ "=", ">=", "<=", "><", "<t+", ">t+", "><t+", "t+", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", ">t-", "<t-", "><t-", "t-", "!*", "*" ],
+    :date_past => [ "=", ">=", "<=", "><", ">t-", "<t-", "><t-", "t-", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "!*", "*" ],
+    :string => [ "=", "~", "!", "!~", "!*", "*" ],
+    :text => [  "~", "!~", "!*", "*" ],
+    :integer => [ "=", ">=", "<=", "><", "!*", "*" ],
+    :float => [ "=", ">=", "<=", "><", "!*", "*" ],
+    :relation => ["=", "=p", "=!p", "!p", "!*", "*"]
+  }
+
+  class_attribute :available_columns
+  self.available_columns = []
+
+  class_attribute :queried_class
+
+  def queried_table_name
+    @queried_table_name ||= self.class.queried_class.table_name
+  end
+
+  def initialize(attributes=nil, *args)
+    super attributes
+    @is_for_all = project.nil?
+  end
+
+  # Builds the query from the given params
+  def build_from_params(params)
+    if params[:fields] || params[:f]
+      self.filters = {}
+      add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v])
+    else
+      available_filters.keys.each do |field|
+        add_short_filter(field, params[field]) if params[field]
+      end
+    end
+    self.group_by = params[:group_by] || (params[:query] && params[:query][:group_by])
+    self.column_names = params[:c] || (params[:query] && params[:query][:column_names])
+    self
+  end
+
+  # Builds a new query from the given params and attributes
+  def self.build_from_params(params, attributes={})
+    new(attributes).build_from_params(params)
+  end
+
+  def validate_query_filters
+    filters.each_key do |field|
+      if values_for(field)
+        case type_for(field)
+        when :integer
+          add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+$/) }
+        when :float
+          add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+(\.\d*)?$/) }
+        when :date, :date_past
+          case operator_for(field)
+          when "=", ">=", "<=", "><"
+            add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && (!v.match(/^\d{4}-\d{2}-\d{2}$/) || (Date.parse(v) rescue nil).nil?) }
+          when ">t-", "<t-", "t-", ">t+", "<t+", "t+", "><t+", "><t-"
+            add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+$/) }
+          end
+        end
+      end
+
+      add_filter_error(field, :blank) unless
+          # filter requires one or more values
+          (values_for(field) and !values_for(field).first.blank?) or
+          # filter doesn't require any value
+          ["o", "c", "!*", "*", "t", "ld", "w", "lw", "l2w", "m", "lm", "y"].include? operator_for(field)
+    end if filters
+  end
+
+  def add_filter_error(field, message)
+    m = label_for(field) + " " + l(message, :scope => 'activerecord.errors.messages')
+    errors.add(:base, m)
+  end
+
+  def editable_by?(user)
+    return false unless user
+    # Admin can edit them all and regular users can edit their private queries
+    return true if user.admin? || (!is_public && self.user_id == user.id)
+    # Members can not edit public queries that are for all project (only admin is allowed to)
+    is_public && !@is_for_all && user.allowed_to?(:manage_public_queries, project)
+  end
+
+  def trackers
+    @trackers ||= project.nil? ? Tracker.sorted.all : project.rolled_up_trackers
+  end
+
+  # Returns a hash of localized labels for all filter operators
+  def self.operators_labels
+    operators.inject({}) {|h, operator| h[operator.first] = l(*operator.last); h}
+  end
+
+  # Returns a representation of the available filters for JSON serialization
+  def available_filters_as_json
+    json = {}
+    available_filters.each do |field, options|
+      json[field] = options.slice(:type, :name, :values).stringify_keys
+    end
+    json
+  end
+
+  def all_projects
+    @all_projects ||= Project.visible.all
+  end
+
+  def all_projects_values
+    return @all_projects_values if @all_projects_values
+
+    values = []
+    Project.project_tree(all_projects) do |p, level|
+      prefix = (level > 0 ? ('--' * level + ' ') : '')
+      values << ["#{prefix}#{p.name}", p.id.to_s]
+    end
+    @all_projects_values = values
+  end
+
+  # Adds available filters
+  def initialize_available_filters
+    # implemented by sub-classes
+  end
+  protected :initialize_available_filters
+
+  # Adds an available filter
+  def add_available_filter(field, options)
+    @available_filters ||= ActiveSupport::OrderedHash.new
+    @available_filters[field] = options
+    @available_filters
+  end
+
+  # Removes an available filter
+  def delete_available_filter(field)
+    if @available_filters
+      @available_filters.delete(field)
+    end
+  end
+
+  # Return a hash of available filters
+  def available_filters
+    unless @available_filters
+      initialize_available_filters
+      @available_filters.each do |field, options|
+        options[:name] ||= l(options[:label] || "field_#{field}".gsub(/_id$/, ''))
+      end
+    end
+    @available_filters
+  end
+
+  def add_filter(field, operator, values=nil)
+    # values must be an array
+    return unless values.nil? || values.is_a?(Array)
+    # check if field is defined as an available filter
+    if available_filters.has_key? field
+      filter_options = available_filters[field]
+      filters[field] = {:operator => operator, :values => (values || [''])}
+    end
+  end
+
+  def add_short_filter(field, expression)
+    return unless expression && available_filters.has_key?(field)
+    field_type = available_filters[field][:type]
+    operators_by_filter_type[field_type].sort.reverse.detect do |operator|
+      next unless expression =~ /^#{Regexp.escape(operator)}(.*)$/
+      values = $1
+      add_filter field, operator, values.present? ? values.split('|') : ['']
+    end || add_filter(field, '=', expression.split('|'))
+  end
+
+  # Add multiple filters using +add_filter+
+  def add_filters(fields, operators, values)
+    if fields.is_a?(Array) && operators.is_a?(Hash) && (values.nil? || values.is_a?(Hash))
+      fields.each do |field|
+        add_filter(field, operators[field], values && values[field])
+      end
+    end
+  end
+
+  def has_filter?(field)
+    filters and filters[field]
+  end
+
+  def type_for(field)
+    available_filters[field][:type] if available_filters.has_key?(field)
+  end
+
+  def operator_for(field)
+    has_filter?(field) ? filters[field][:operator] : nil
+  end
+
+  def values_for(field)
+    has_filter?(field) ? filters[field][:values] : nil
+  end
+
+  def value_for(field, index=0)
+    (values_for(field) || [])[index]
+  end
+
+  def label_for(field)
+    label = available_filters[field][:name] if available_filters.has_key?(field)
+    label ||= l("field_#{field.to_s.gsub(/_id$/, '')}", :default => field)
+  end
+
+  def self.add_available_column(column)
+    self.available_columns << (column) if column.is_a?(QueryColumn)
+  end
+
+  # Returns an array of columns that can be used to group the results
+  def groupable_columns
+    available_columns.select {|c| c.groupable}
+  end
+
+  # Returns a Hash of columns and the key for sorting
+  def sortable_columns
+    available_columns.inject({}) {|h, column|
+      h[column.name.to_s] = column.sortable
+      h
+    }
+  end
+
+  def columns
+    # preserve the column_names order
+    cols = (has_default_columns? ? default_columns_names : column_names).collect do |name|
+       available_columns.find { |col| col.name == name }
+    end.compact
+    available_columns.select(&:frozen?) | cols
+  end
+
+  def inline_columns
+    columns.select(&:inline?)
+  end
+
+  def block_columns
+    columns.reject(&:inline?)
+  end
+
+  def available_inline_columns
+    available_columns.select(&:inline?)
+  end
+
+  def available_block_columns
+    available_columns.reject(&:inline?)
+  end
+
+  def default_columns_names
+    []
+  end
+
+  def column_names=(names)
+    if names
+      names = names.select {|n| n.is_a?(Symbol) || !n.blank? }
+      names = names.collect {|n| n.is_a?(Symbol) ? n : n.to_sym }
+      # Set column_names to nil if default columns
+      if names == default_columns_names
+        names = nil
+      end
+    end
+    write_attribute(:column_names, names)
+  end
+
+  def has_column?(column)
+    column_names && column_names.include?(column.is_a?(QueryColumn) ? column.name : column)
+  end
+
+  def has_default_columns?
+    column_names.nil? || column_names.empty?
+  end
+
+  def sort_criteria=(arg)
+    c = []
+    if arg.is_a?(Hash)
+      arg = arg.keys.sort.collect {|k| arg[k]}
+    end
+    c = arg.select {|k,o| !k.to_s.blank?}.slice(0,3).collect {|k,o| [k.to_s, (o == 'desc' || o == false) ? 'desc' : 'asc']}
+    write_attribute(:sort_criteria, c)
+  end
+
+  def sort_criteria
+    read_attribute(:sort_criteria) || []
+  end
+
+  def sort_criteria_key(arg)
+    sort_criteria && sort_criteria[arg] && sort_criteria[arg].first
+  end
+
+  def sort_criteria_order(arg)
+    sort_criteria && sort_criteria[arg] && sort_criteria[arg].last
+  end
+
+  def sort_criteria_order_for(key)
+    sort_criteria.detect {|k, order| key.to_s == k}.try(:last)
+  end
+
+  # Returns the SQL sort order that should be prepended for grouping
+  def group_by_sort_order
+    if grouped? && (column = group_by_column)
+      order = sort_criteria_order_for(column.name) || column.default_order
+      column.sortable.is_a?(Array) ?
+        column.sortable.collect {|s| "#{s} #{order}"}.join(',') :
+        "#{column.sortable} #{order}"
+    end
+  end
+
+  # Returns true if the query is a grouped query
+  def grouped?
+    !group_by_column.nil?
+  end
+
+  def group_by_column
+    groupable_columns.detect {|c| c.groupable && c.name.to_s == group_by}
+  end
+
+  def group_by_statement
+    group_by_column.try(:groupable)
+  end
+
+  def project_statement
+    project_clauses = []
+    if project && !project.descendants.active.empty?
+      ids = [project.id]
+      if has_filter?("subproject_id")
+        case operator_for("subproject_id")
+        when '='
+          # include the selected subprojects
+          ids += values_for("subproject_id").each(&:to_i)
+        when '!*'
+          # main project only
+        else
+          # all subprojects
+          ids += project.descendants.collect(&:id)
+        end
+      elsif Setting.display_subprojects_issues?
+        ids += project.descendants.collect(&:id)
+      end
+      project_clauses << "#{Project.table_name}.id IN (%s)" % ids.join(',')
+    elsif project
+      project_clauses << "#{Project.table_name}.id = %d" % project.id
+    end
+    project_clauses.any? ? project_clauses.join(' AND ') : nil
+  end
+
+  def statement
+    # filters clauses
+    filters_clauses = []
+    filters.each_key do |field|
+      next if field == "subproject_id"
+      v = values_for(field).clone
+      next unless v and !v.empty?
+      operator = operator_for(field)
+
+      # "me" value subsitution
+      if %w(assigned_to_id author_id user_id watcher_id).include?(field)
+        if v.delete("me")
+          if User.current.logged?
+            v.push(User.current.id.to_s)
+            v += User.current.group_ids.map(&:to_s) if field == 'assigned_to_id'
+          else
+            v.push("0")
+          end
+        end
+      end
+
+      if field == 'project_id'
+        if v.delete('mine')
+          v += User.current.memberships.map(&:project_id).map(&:to_s)
+        end
+      end
+
+      if field =~ /cf_(\d+)$/
+        # custom field
+        filters_clauses << sql_for_custom_field(field, operator, v, $1)
+      elsif respond_to?("sql_for_#{field}_field")
+        # specific statement
+        filters_clauses << send("sql_for_#{field}_field", field, operator, v)
+      else
+        # regular field
+        filters_clauses << '(' + sql_for_field(field, operator, v, queried_table_name, field) + ')'
+      end
+    end if filters and valid?
+
+    filters_clauses << project_statement
+    filters_clauses.reject!(&:blank?)
+
+    filters_clauses.any? ? filters_clauses.join(' AND ') : nil
+  end
+
+  private
+
+  def sql_for_custom_field(field, operator, value, custom_field_id)
+    db_table = CustomValue.table_name
+    db_field = 'value'
+    filter = @available_filters[field]
+    return nil unless filter
+    if filter[:format] == 'user'
+      if value.delete('me')
+        value.push User.current.id.to_s
+      end
+    end
+    not_in = nil
+    if operator == '!'
+      # Makes ! operator work for custom fields with multiple values
+      operator = '='
+      not_in = 'NOT'
+    end
+    customized_key = "id"
+    customized_class = queried_class
+    if field =~ /^(.+)\.cf_/
+      assoc = $1
+      customized_key = "#{assoc}_id"
+      customized_class = queried_class.reflect_on_association(assoc.to_sym).klass.base_class rescue nil
+      raise "Unknown #{queried_class.name} association #{assoc}" unless customized_class
+    end
+    where = sql_for_field(field, operator, value, db_table, db_field, true)
+    if operator =~ /[<>]/
+      where = "(#{where}) AND #{db_table}.#{db_field} <> ''"
+    end
+    "#{queried_table_name}.#{customized_key} #{not_in} IN (SELECT #{customized_class.table_name}.id FROM #{customized_class.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='#{customized_class}' AND #{db_table}.customized_id=#{customized_class.table_name}.id AND #{db_table}.custom_field_id=#{custom_field_id} WHERE #{where})"
+  end
+
+  # Helper method to generate the WHERE sql for a +field+, +operator+ and a +value+
+  def sql_for_field(field, operator, value, db_table, db_field, is_custom_filter=false)
+    sql = ''
+    case operator
+    when "="
+      if value.any?
+        case type_for(field)
+        when :date, :date_past
+          sql = date_clause(db_table, db_field, (Date.parse(value.first) rescue nil), (Date.parse(value.first) rescue nil))
+        when :integer
+          if is_custom_filter
+            sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) = #{value.first.to_i})"
+          else
+            sql = "#{db_table}.#{db_field} = #{value.first.to_i}"
+          end
+        when :float
+          if is_custom_filter
+            sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5})"
+          else
+            sql = "#{db_table}.#{db_field} BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5}"
+          end
+        else
+          sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")"
+        end
+      else
+        # IN an empty set
+        sql = "1=0"
+      end
+    when "!"
+      if value.any?
+        sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))"
+      else
+        # NOT IN an empty set
+        sql = "1=1"
+      end
+    when "!*"
+      sql = "#{db_table}.#{db_field} IS NULL"
+      sql << " OR #{db_table}.#{db_field} = ''" if is_custom_filter
+    when "*"
+      sql = "#{db_table}.#{db_field} IS NOT NULL"
+      sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter
+    when ">="
+      if [:date, :date_past].include?(type_for(field))
+        sql = date_clause(db_table, db_field, (Date.parse(value.first) rescue nil), nil)
+      else
+        if is_custom_filter
+          sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) >= #{value.first.to_f})"
+        else
+          sql = "#{db_table}.#{db_field} >= #{value.first.to_f}"
+        end
+      end
+    when "<="
+      if [:date, :date_past].include?(type_for(field))
+        sql = date_clause(db_table, db_field, nil, (Date.parse(value.first) rescue nil))
+      else
+        if is_custom_filter
+          sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) <= #{value.first.to_f})"
+        else
+          sql = "#{db_table}.#{db_field} <= #{value.first.to_f}"
+        end
+      end
+    when "><"
+      if [:date, :date_past].include?(type_for(field))
+        sql = date_clause(db_table, db_field, (Date.parse(value[0]) rescue nil), (Date.parse(value[1]) rescue nil))
+      else
+        if is_custom_filter
+          sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) BETWEEN #{value[0].to_f} AND #{value[1].to_f})"
+        else
+          sql = "#{db_table}.#{db_field} BETWEEN #{value[0].to_f} AND #{value[1].to_f}"
+        end
+      end
+    when "o"
+      sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_false})" if field == "status_id"
+    when "c"
+      sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_true})" if field == "status_id"
+    when "><t-"
+      # between today - n days and today
+      sql = relative_date_clause(db_table, db_field, - value.first.to_i, 0)
+    when ">t-"
+      # >= today - n days
+      sql = relative_date_clause(db_table, db_field, - value.first.to_i, nil)
+    when "<t-"
+      # <= today - n days
+      sql = relative_date_clause(db_table, db_field, nil, - value.first.to_i)
+    when "t-"
+      # = n days in past
+      sql = relative_date_clause(db_table, db_field, - value.first.to_i, - value.first.to_i)
+    when "><t+"
+      # between today and today + n days
+      sql = relative_date_clause(db_table, db_field, 0, value.first.to_i)
+    when ">t+"
+      # >= today + n days
+      sql = relative_date_clause(db_table, db_field, value.first.to_i, nil)
+    when "<t+"
+      # <= today + n days
+      sql = relative_date_clause(db_table, db_field, nil, value.first.to_i)
+    when "t+"
+      # = today + n days
+      sql = relative_date_clause(db_table, db_field, value.first.to_i, value.first.to_i)
+    when "t"
+      # = today
+      sql = relative_date_clause(db_table, db_field, 0, 0)
+    when "ld"
+      # = yesterday
+      sql = relative_date_clause(db_table, db_field, -1, -1)
+    when "w"
+      # = this week
+      first_day_of_week = l(:general_first_day_of_week).to_i
+      day_of_week = Date.today.cwday
+      days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
+      sql = relative_date_clause(db_table, db_field, - days_ago, - days_ago + 6)
+    when "lw"
+      # = last week
+      first_day_of_week = l(:general_first_day_of_week).to_i
+      day_of_week = Date.today.cwday
+      days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
+      sql = relative_date_clause(db_table, db_field, - days_ago - 7, - days_ago - 1)
+    when "l2w"
+      # = last 2 weeks
+      first_day_of_week = l(:general_first_day_of_week).to_i
+      day_of_week = Date.today.cwday
+      days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
+      sql = relative_date_clause(db_table, db_field, - days_ago - 14, - days_ago - 1)
+    when "m"
+      # = this month
+      date = Date.today
+      sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month)
+    when "lm"
+      # = last month
+      date = Date.today.prev_month
+      sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month)
+    when "y"
+      # = this year
+      date = Date.today
+      sql = date_clause(db_table, db_field, date.beginning_of_year, date.end_of_year)
+    when "~"
+      sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
+    when "!~"
+      sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
+    else
+      raise "Unknown query operator #{operator}"
+    end
+
+    return sql
+  end
+
+  def add_custom_fields_filters(custom_fields, assoc=nil)
+    return unless custom_fields.present?
+
+    custom_fields.select(&:is_filter?).sort.each do |field|
+      case field.field_format
+      when "text"
+        options = { :type => :text }
+      when "list"
+        options = { :type => :list_optional, :values => field.possible_values }
+      when "date"
+        options = { :type => :date }
+      when "bool"
+        options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]] }
+      when "int"
+        options = { :type => :integer }
+      when "float"
+        options = { :type => :float }
+      when "user", "version"
+        next unless project
+        values = field.possible_values_options(project)
+        if User.current.logged? && field.field_format == 'user'
+          values.unshift ["<< #{l(:label_me)} >>", "me"]
+        end
+        options = { :type => :list_optional, :values => values }
+      else
+        options = { :type => :string }
+      end
+      filter_id = "cf_#{field.id}"
+      filter_name = field.name
+      if assoc.present?
+        filter_id = "#{assoc}.#{filter_id}"
+        filter_name = l("label_attribute_of_#{assoc}", :name => filter_name)
+      end
+      add_available_filter filter_id, options.merge({
+               :name => filter_name,
+               :format => field.field_format,
+               :field => field
+             })
+    end
+  end
+
+  def add_associations_custom_fields_filters(*associations)
+    fields_by_class = CustomField.where(:is_filter => true).group_by(&:class)
+    associations.each do |assoc|
+      association_klass = queried_class.reflect_on_association(assoc).klass
+      fields_by_class.each do |field_class, fields|
+        if field_class.customized_class <= association_klass
+          add_custom_fields_filters(fields, assoc)
+        end
+      end
+    end
+  end
+
+  # Returns a SQL clause for a date or datetime field.
+  def date_clause(table, field, from, to)
+    s = []
+    if from
+      from_yesterday = from - 1
+      from_yesterday_time = Time.local(from_yesterday.year, from_yesterday.month, from_yesterday.day)
+      if self.class.default_timezone == :utc
+        from_yesterday_time = from_yesterday_time.utc
+      end
+      s << ("#{table}.#{field} > '%s'" % [connection.quoted_date(from_yesterday_time.end_of_day)])
+    end
+    if to
+      to_time = Time.local(to.year, to.month, to.day)
+      if self.class.default_timezone == :utc
+        to_time = to_time.utc
+      end
+      s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date(to_time.end_of_day)])
+    end
+    s.join(' AND ')
+  end
+
+  # Returns a SQL clause for a date or datetime field using relative dates.
+  def relative_date_clause(table, field, days_from, days_to)
+    date_clause(table, field, (days_from ? Date.today + days_from : nil), (days_to ? Date.today + days_to : nil))
+  end
+
+  # Additional joins required for the given sort options
+  def joins_for_order_statement(order_options)
+    joins = []
+
+    if order_options
+      if order_options.include?('authors')
+        joins << "LEFT OUTER JOIN #{User.table_name} authors ON authors.id = #{queried_table_name}.author_id"
+      end
+      order_options.scan(/cf_\d+/).uniq.each do |name|
+        column = available_columns.detect {|c| c.name.to_s == name}
+        join = column && column.custom_field.join_for_order_statement
+        if join
+          joins << join
+        end
+      end
+    end
+
+    joins.any? ? joins.join(' ') : nil
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a3/a3b7c4372735e48e9ede0b15120e9d79060eed4d.svn-base
--- /dev/null
+++ b/.svn/pristine/a3/a3b7c4372735e48e9ede0b15120e9d79060eed4d.svn-base
@@ -0,0 +1,12 @@
+class IssueMove < ActiveRecord::Migration
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    Permission.create :controller => "projects", :action => "move_issues", :description => "button_move", :sort => 1061, :mail_option => 0, :mail_enabled => 0
+  end
+
+  def self.down
+    Permission.where("controller=? and action=?", 'projects', 'move_issues').first.destroy
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a4/a4231cb7c3e5093a8d0531af16c4a7d140780541.svn-base
--- a/.svn/pristine/a4/a4231cb7c3e5093a8d0531af16c4a7d140780541.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-page.hide "journal-#{@journal.id}-notes"
-page.insert_html :after, "journal-#{@journal.id}-notes",
-                 :partial => 'notes_form'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a4/a4243acdb4189cebe80aac893898227b027c45ce.svn-base
--- a/.svn/pristine/a4/a4243acdb4189cebe80aac893898227b027c45ce.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-class AppAndPluginLibModel < ActiveRecord::Base
-  def self.report_location; TestHelper::report_location(__FILE__); end
-
-  def defined_only_in_alpha_plugin_version
-    # should not be defined
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a4/a494e5a07ce50a0c4f746379917023ec9e432959.svn-base
--- a/.svn/pristine/a4/a494e5a07ce50a0c4f746379917023ec9e432959.svn-base
+++ /dev/null
@@ -1,241 +0,0 @@
-require 'uri'
-require 'openid/extensions/sreg'
-require 'openid/extensions/ax'
-require 'openid/store/filesystem'
-
-require File.dirname(__FILE__) + '/open_id_authentication/db_store'
-require File.dirname(__FILE__) + '/open_id_authentication/mem_cache_store'
-require File.dirname(__FILE__) + '/open_id_authentication/request'
-require File.dirname(__FILE__) + '/open_id_authentication/timeout_fixes' if OpenID::VERSION == "2.0.4"
-
-module OpenIdAuthentication
-  OPEN_ID_AUTHENTICATION_DIR = RAILS_ROOT + "/tmp/openids"
-
-  def self.store
-    @@store
-  end
-
-  def self.store=(*store_option)
-    store, *parameters = *([ store_option ].flatten)
-
-    @@store = case store
-    when :db
-      OpenIdAuthentication::DbStore.new
-    when :mem_cache
-      OpenIdAuthentication::MemCacheStore.new(*parameters)
-    when :file
-      OpenID::Store::Filesystem.new(OPEN_ID_AUTHENTICATION_DIR)
-    else
-      raise "Unknown store: #{store}"
-    end
-  end
-
-  self.store = :db
-
-  class InvalidOpenId < StandardError
-  end
-
-  class Result
-    ERROR_MESSAGES = {
-      :missing      => "Sorry, the OpenID server couldn't be found",
-      :invalid      => "Sorry, but this does not appear to be a valid OpenID",
-      :canceled     => "OpenID verification was canceled",
-      :failed       => "OpenID verification failed",
-      :setup_needed => "OpenID verification needs setup"
-    }
-
-    def self.[](code)
-      new(code)
-    end
-
-    def initialize(code)
-      @code = code
-    end
-
-    def status
-      @code
-    end
-
-    ERROR_MESSAGES.keys.each { |state| define_method("#{state}?") { @code == state } }
-
-    def successful?
-      @code == :successful
-    end
-
-    def unsuccessful?
-      ERROR_MESSAGES.keys.include?(@code)
-    end
-
-    def message
-      ERROR_MESSAGES[@code]
-    end
-  end
-
-  # normalizes an OpenID according to http://openid.net/specs/openid-authentication-2_0.html#normalization
-  def self.normalize_identifier(identifier)
-    # clean up whitespace
-    identifier = identifier.to_s.strip
-
-    # if an XRI has a prefix, strip it.
-    identifier.gsub!(/xri:\/\//i, '')
-
-    # dodge XRIs -- TODO: validate, don't just skip.
-    unless ['=', '@', '+', '$', '!', '('].include?(identifier.at(0))
-      # does it begin with http?  if not, add it.
-      identifier = "http://#{identifier}" unless identifier =~ /^http/i
-
-      # strip any fragments
-      identifier.gsub!(/\#(.*)$/, '')
-
-      begin
-        uri = URI.parse(identifier)
-        uri.scheme = uri.scheme.downcase if uri.scheme # URI should do this
-        identifier = uri.normalize.to_s
-      rescue URI::InvalidURIError
-        raise InvalidOpenId.new("#{identifier} is not an OpenID identifier")
-      end
-    end
-
-    return identifier
-  end
-
-  # deprecated for OpenID 2.0, where not all OpenIDs are URLs
-  def self.normalize_url(url)
-    ActiveSupport::Deprecation.warn "normalize_url has been deprecated, use normalize_identifier instead"
-    self.normalize_identifier(url)
-  end
-
-  protected
-    def normalize_url(url)
-      OpenIdAuthentication.normalize_url(url)
-    end
-
-    def normalize_identifier(url)
-      OpenIdAuthentication.normalize_identifier(url)
-    end
-
-    # The parameter name of "openid_identifier" is used rather than the Rails convention "open_id_identifier"
-    # because that's what the specification dictates in order to get browser auto-complete working across sites
-    def using_open_id?(identity_url = nil) #:doc:
-      identity_url ||= params[:openid_identifier] || params[:openid_url]
-      !identity_url.blank? || params[:open_id_complete]
-    end
-
-    def authenticate_with_open_id(identity_url = nil, options = {}, &block) #:doc:
-      identity_url ||= params[:openid_identifier] || params[:openid_url]
-
-      if params[:open_id_complete].nil?
-        begin_open_id_authentication(identity_url, options, &block)
-      else
-        complete_open_id_authentication(&block)
-      end
-    end
-
-  private
-    def begin_open_id_authentication(identity_url, options = {})
-      identity_url = normalize_identifier(identity_url)
-      return_to    = options.delete(:return_to)
-      method       = options.delete(:method)
-      
-      options[:required] ||= []  # reduces validation later
-      options[:optional] ||= []
-
-      open_id_request = open_id_consumer.begin(identity_url)
-      add_simple_registration_fields(open_id_request, options)
-      add_ax_fields(open_id_request, options)
-      redirect_to(open_id_redirect_url(open_id_request, return_to, method))
-    rescue OpenIdAuthentication::InvalidOpenId => e
-      yield Result[:invalid], identity_url, nil
-    rescue OpenID::OpenIDError, Timeout::Error => e
-      logger.error("[OPENID] #{e}")
-      yield Result[:missing], identity_url, nil
-    end
-
-    def complete_open_id_authentication
-      params_with_path = params.reject { |key, value| request.path_parameters[key] }
-      params_with_path.delete(:format)
-      open_id_response = timeout_protection_from_identity_server { open_id_consumer.complete(params_with_path, requested_url) }
-      identity_url     = normalize_identifier(open_id_response.display_identifier) if open_id_response.display_identifier
-
-      case open_id_response.status
-      when OpenID::Consumer::SUCCESS
-        profile_data = {}
-
-        # merge the SReg data and the AX data into a single hash of profile data
-        [ OpenID::SReg::Response, OpenID::AX::FetchResponse ].each do |data_response|
-          if data_response.from_success_response( open_id_response )
-            profile_data.merge! data_response.from_success_response( open_id_response ).data
-          end
-        end
-        
-        yield Result[:successful], identity_url, profile_data
-      when OpenID::Consumer::CANCEL
-        yield Result[:canceled], identity_url, nil
-      when OpenID::Consumer::FAILURE
-        yield Result[:failed], identity_url, nil
-      when OpenID::Consumer::SETUP_NEEDED
-        yield Result[:setup_needed], open_id_response.setup_url, nil
-      end
-    end
-
-    def open_id_consumer
-      OpenID::Consumer.new(session, OpenIdAuthentication.store)
-    end
-
-    def add_simple_registration_fields(open_id_request, fields)
-      sreg_request = OpenID::SReg::Request.new
-      
-      # filter out AX identifiers (URIs)
-      required_fields = fields[:required].collect { |f| f.to_s unless f =~ /^https?:\/\// }.compact
-      optional_fields = fields[:optional].collect { |f| f.to_s unless f =~ /^https?:\/\// }.compact
-      
-      sreg_request.request_fields(required_fields, true) unless required_fields.blank?
-      sreg_request.request_fields(optional_fields, false) unless optional_fields.blank?
-      sreg_request.policy_url = fields[:policy_url] if fields[:policy_url]
-      open_id_request.add_extension(sreg_request)
-    end
-    
-    def add_ax_fields( open_id_request, fields )
-      ax_request = OpenID::AX::FetchRequest.new
-      
-      # look through the :required and :optional fields for URIs (AX identifiers)
-      fields[:required].each do |f|
-        next unless f =~ /^https?:\/\//
-        ax_request.add( OpenID::AX::AttrInfo.new( f, nil, true ) )
-      end
-
-      fields[:optional].each do |f|
-        next unless f =~ /^https?:\/\//
-        ax_request.add( OpenID::AX::AttrInfo.new( f, nil, false ) )
-      end
-      
-      open_id_request.add_extension( ax_request )
-    end
-        
-    def open_id_redirect_url(open_id_request, return_to = nil, method = nil)
-      open_id_request.return_to_args['_method'] = (method || request.method).to_s
-      open_id_request.return_to_args['open_id_complete'] = '1'
-      open_id_request.redirect_url(root_url, return_to || requested_url)
-    end
-
-    def requested_url
-      relative_url_root = self.class.respond_to?(:relative_url_root) ?
-        self.class.relative_url_root.to_s :
-        request.relative_url_root
-      "#{request.protocol}#{request.host_with_port}#{relative_url_root}#{request.path}"
-    end
-
-    def timeout_protection_from_identity_server
-      yield
-    rescue Timeout::Error
-      Class.new do
-        def status
-          OpenID::FAILURE
-        end
-
-        def msg
-          "Identity server timed out"
-        end
-      end.new
-    end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a4/a4b306b7b7bfa99b0d494098e7c07938749fdf68.svn-base
--- a/.svn/pristine/a4/a4b306b7b7bfa99b0d494098e7c07938749fdf68.svn-base
+++ /dev/null
@@ -1,213 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # Scanner for JavaScript.
-  # 
-  # Aliases: +ecmascript+, +ecma_script+, +javascript+
-  class JavaScript < Scanner
-    
-    register_for :java_script
-    file_extension 'js'
-    
-    # The actual JavaScript keywords.
-    KEYWORDS = %w[
-      break case catch continue default delete do else
-      finally for function if in instanceof new
-      return switch throw try typeof var void while with
-    ]  # :nodoc:
-    PREDEFINED_CONSTANTS = %w[
-      false null true undefined NaN Infinity
-    ]  # :nodoc:
-    
-    MAGIC_VARIABLES = %w[ this arguments ]  # :nodoc: arguments was introduced in JavaScript 1.4
-    
-    KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[
-      case delete in instanceof new return throw typeof with
-    ]  # :nodoc:
-    
-    # Reserved for future use.
-    RESERVED_WORDS = %w[
-      abstract boolean byte char class debugger double enum export extends
-      final float goto implements import int interface long native package
-      private protected public short static super synchronized throws transient
-      volatile
-    ]  # :nodoc:
-    
-    IDENT_KIND = WordList.new(:ident).
-      add(RESERVED_WORDS, :reserved).
-      add(PREDEFINED_CONSTANTS, :predefined_constant).
-      add(MAGIC_VARIABLES, :local_variable).
-      add(KEYWORDS, :keyword)  # :nodoc:
-    
-    ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x  # :nodoc:
-    UNICODE_ESCAPE =  / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x  # :nodoc:
-    REGEXP_ESCAPE =  / [bBdDsSwW] /x  # :nodoc:
-    STRING_CONTENT_PATTERN = {
-      "'" => /[^\\']+/,
-      '"' => /[^\\"]+/,
-      '/' => /[^\\\/]+/,
-    }  # :nodoc:
-    KEY_CHECK_PATTERN = {
-      "'" => / (?> [^\\']* (?: \\. [^\\']* )* ) ' \s* : /mx,
-      '"' => / (?> [^\\"]* (?: \\. [^\\"]* )* ) " \s* : /mx,
-    }  # :nodoc:
-    
-  protected
-    
-    def scan_tokens encoder, options
-      
-      state = :initial
-      string_delimiter = nil
-      value_expected = true
-      key_expected = false
-      function_expected = false
-      
-      until eos?
-        
-        case state
-          
-        when :initial
-          
-          if match = scan(/ \s+ | \\\n /x)
-            value_expected = true if !value_expected && match.index(?\n)
-            encoder.text_token match, :space
-            
-          elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
-            value_expected = true
-            encoder.text_token match, :comment
-            
-          elsif check(/\.?\d/)
-            key_expected = value_expected = false
-            if match = scan(/0[xX][0-9A-Fa-f]+/)
-              encoder.text_token match, :hex
-            elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/)
-              encoder.text_token match, :octal
-            elsif match = scan(/\d+[fF]|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
-              encoder.text_token match, :float
-            elsif match = scan(/\d+/)
-              encoder.text_token match, :integer
-            end
-            
-          elsif value_expected && match = scan(/<([[:alpha:]]\w*) (?: [^\/>]*\/> | .*?<\/\1>)/xim)
-            # TODO: scan over nested tags
-            xml_scanner.tokenize match, :tokens => encoder
-            value_expected = false
-            next
-            
-          elsif match = scan(/ [-+*=<>?:;,!&^|(\[{~%]+ | \.(?!\d) /x)
-            value_expected = true
-            last_operator = match[-1]
-            key_expected = (last_operator == ?{) || (last_operator == ?,)
-            function_expected = false
-            encoder.text_token match, :operator
-            
-          elsif match = scan(/ [)\]}]+ /x)
-            function_expected = key_expected = value_expected = false
-            encoder.text_token match, :operator
-            
-          elsif match = scan(/ [$a-zA-Z_][A-Za-z_0-9$]* /x)
-            kind = IDENT_KIND[match]
-            value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match]
-            # TODO: labels
-            if kind == :ident
-              if match.index(?$)  # $ allowed inside an identifier
-                kind = :predefined
-              elsif function_expected
-                kind = :function
-              elsif check(/\s*[=:]\s*function\b/)
-                kind = :function
-              elsif key_expected && check(/\s*:/)
-                kind = :key
-              end
-            end
-            function_expected = (kind == :keyword) && (match == 'function')
-            key_expected = false
-            encoder.text_token match, kind
-            
-          elsif match = scan(/["']/)
-            if key_expected && check(KEY_CHECK_PATTERN[match])
-              state = :key
-            else
-              state = :string
-            end
-            encoder.begin_group state
-            string_delimiter = match
-            encoder.text_token match, :delimiter
-            
-          elsif value_expected && (match = scan(/\//))
-            encoder.begin_group :regexp
-            state = :regexp
-            string_delimiter = '/'
-            encoder.text_token match, :delimiter
-            
-          elsif match = scan(/ \/ /x)
-            value_expected = true
-            key_expected = false
-            encoder.text_token match, :operator
-            
-          else
-            encoder.text_token getch, :error
-            
-          end
-          
-        when :string, :regexp, :key
-          if match = scan(STRING_CONTENT_PATTERN[string_delimiter])
-            encoder.text_token match, :content
-          elsif match = scan(/["'\/]/)
-            encoder.text_token match, :delimiter
-            if state == :regexp
-              modifiers = scan(/[gim]+/)
-              encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty?
-            end
-            encoder.end_group state
-            string_delimiter = nil
-            key_expected = value_expected = false
-            state = :initial
-          elsif state != :regexp && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
-            if string_delimiter == "'" && !(match == "\\\\" || match == "\\'")
-              encoder.text_token match, :content
-            else
-              encoder.text_token match, :char
-            end
-          elsif state == :regexp && match = scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
-            encoder.text_token match, :char
-          elsif match = scan(/\\./m)
-            encoder.text_token match, :content
-          elsif match = scan(/ \\ | $ /x)
-            encoder.end_group state
-            encoder.text_token match, :error
-            key_expected = value_expected = false
-            state = :initial
-          else
-            raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
-          end
-          
-        else
-          raise_inspect 'Unknown state', encoder
-          
-        end
-        
-      end
-      
-      if [:string, :regexp].include? state
-        encoder.end_group state
-      end
-      
-      encoder
-    end
-    
-  protected
-    
-    def reset_instance
-      super
-      @xml_scanner.reset if defined? @xml_scanner
-    end
-    
-    def xml_scanner
-      @xml_scanner ||= CodeRay.scanner :xml, :tokens => @tokens, :keep_tokens => true, :keep_state => false
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a4/a4f25290059e703adadabbe9e41df4b78b4f4c6b.svn-base
--- a/.svn/pristine/a4/a4f25290059e703adadabbe9e41df4b78b4f4c6b.svn-base
+++ /dev/null
@@ -1,41 +0,0 @@
-<% if @project.shared_versions.any? %>
-<table class="list versions">
-  <thead><tr>
-    <th><%= l(:label_version) %></th>
-    <th><%= l(:field_effective_date) %></th>
-    <th><%= l(:field_description) %></th>
-    <th><%= l(:field_status) %></th>
-    <th><%= l(:field_sharing) %></th>
-    <th><%= l(:label_wiki_page) %></th>
-    <th style="width:15%"></th>
-    </tr></thead>
-  <tbody>
-<% for version in @project.shared_versions.sort %>
-    <tr class="version <%= cycle 'odd', 'even' %> <%=h version.status %> <%= 'shared' if version.project != @project %>">
-    <td class="name"><%= link_to_version version %></td>
-    <td class="date"><%= format_date(version.effective_date) %></td>
-    <td class="description"><%=h version.description %></td>
-    <td class="status"><%= l("version_status_#{version.status}") %></td>
-    <td class="sharing"><%=h format_version_sharing(version.sharing) %></td>
-    <td><%= link_to_if_authorized(h(version.wiki_page_title), {:controller => 'wiki', :action => 'show', :project_id => version.project, :id => Wiki.titleize(version.wiki_page_title)}) || h(version.wiki_page_title) unless version.wiki_page_title.blank? || version.project.wiki.nil? %></td>
-    <td class="buttons">
-      <% if version.project == @project && User.current.allowed_to?(:manage_versions, @project) %>
-        <%= link_to l(:button_edit), edit_version_path(version), :class => 'icon icon-edit' %>
-        <%= link_to l(:button_delete), version_path(version), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
-      <% end %>
-     </td>
-    </tr>
-<% end; reset_cycle %>
-    </tbody>
-</table>
-<% else %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
-
-<div class="contextual">
-<% if @project.versions.any? %>
-  <%= link_to l(:label_close_versions), close_completed_project_versions_path(@project), :method => :put %>
-<% end %>
-</div>
-
-<p><%= link_to l(:label_version_new), new_project_version_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_versions, @project) %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a5/a50b7b77054746ae04a29c1d25d50e5dbb10bf4e.svn-base
--- /dev/null
+++ b/.svn/pristine/a5/a50b7b77054746ae04a29c1d25d50e5dbb10bf4e.svn-base
@@ -0,0 +1,1089 @@
+# Greek translations for Ruby on Rails
+# by Vaggelis Typaldos (vtypal@gmail.com),  Spyros Raptis (spirosrap@gmail.com)
+
+el:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%m/%d/%Y"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [ÎšÏ…ÏÎ¹Î±ÎºÎ®, Î”ÎµÏ…Ï„Î­ÏÎ±, Î¤ÏÎ¯Ï„Î·, Î¤ÎµÏ„Î¬ÏÏ„Î·, Î Î­Î¼Ï€Ï„Î·, Î Î±ÏÎ±ÏƒÎºÎµÏ…Î®, Î£Î¬Î²Î²Î±Ï„Î¿]
+    abbr_day_names: [ÎšÏ…Ï, Î”ÎµÏ…, Î¤ÏÎ¹, Î¤ÎµÏ„, Î ÎµÎ¼, Î Î±Ï, Î£Î±Î²]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Î™Î±Î½Î¿Ï…Î¬ÏÎ¹Î¿Ï‚, Î¦ÎµÎ²ÏÎ¿Ï…Î¬ÏÎ¹Î¿Ï‚, ÎœÎ¬ÏÏ„Î¹Î¿Ï‚, Î‘Ï€ÏÎ¯Î»Î¹Î¿Ï‚, ÎœÎ¬ÏŠÎ¿Ï‚, Î™Î¿ÏÎ½Î¹Î¿Ï‚, Î™Î¿ÏÎ»Î¹Î¿Ï‚, Î‘ÏÎ³Î¿Ï…ÏƒÏ„Î¿Ï‚, Î£ÎµÏ€Ï„Î­Î¼Î²ÏÎ¹Î¿Ï‚, ÎŸÎºÏ„ÏŽÎ²ÏÎ¹Î¿Ï‚, ÎÎ¿Î­Î¼Î²ÏÎ¹Î¿Ï‚, Î”ÎµÎºÎ­Î¼Î²ÏÎ¹Î¿Ï‚]
+    abbr_month_names: [~, Î™Î±Î½, Î¦ÎµÎ², ÎœÎ±Ï, Î‘Ï€Ï, ÎœÎ±ÏŠ, Î™Î¿Î½, Î™Î¿Î», Î‘Ï…Î³, Î£ÎµÏ€, ÎŸÎºÏ„, ÎÎ¿Îµ, Î”ÎµÎº]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%m/%d/%Y %I:%M %p"
+      time: "%I:%M %p"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "Ï€Î¼"
+    pm: "Î¼Î¼"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "Î¼Î¹ÏƒÏŒ Î»ÎµÏ€Ï„ÏŒ"
+      less_than_x_seconds:
+        one:   "Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ 1 Î´ÎµÏ…Ï„ÎµÏÏŒÎ»ÎµÏ€Ï„Î¿"
+        other: "Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ %{count} Î´ÎµÏ…Ï„ÎµÏÏŒÎ»ÎµÏ€Ï„Î±"
+      x_seconds:
+        one:   "1 Î´ÎµÏ…Ï„ÎµÏÏŒÎ»ÎµÏ€Ï„Î¿"
+        other: "%{count} Î´ÎµÏ…Ï„ÎµÏÏŒÎ»ÎµÏ€Ï„Î±"
+      less_than_x_minutes:
+        one:   "Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î­Î½Î± Î»ÎµÏ€Ï„ÏŒ"
+        other: "Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ %{count} Î»ÎµÏ€Ï„Î¬"
+      x_minutes:
+        one:   "1 Î»ÎµÏ€Ï„ÏŒ"
+        other: "%{count} Î»ÎµÏ€Ï„Î¬"
+      about_x_hours:
+        one:   "Ï€ÎµÏÎ¯Ï€Î¿Ï… 1 ÏŽÏÎ±"
+        other: "Ï€ÎµÏÎ¯Ï€Î¿Ï… %{count} ÏŽÏÎµÏ‚"
+      x_hours:
+        one:   "1 ÏŽÏÎ±"
+        other: "%{count} ÏŽÏÎµÏ‚"
+      x_days:
+        one:   "1 Î·Î¼Î­ÏÎ±"
+        other: "%{count} Î·Î¼Î­ÏÎµÏ‚"
+      about_x_months:
+        one:   "Ï€ÎµÏÎ¯Ï€Î¿Ï… 1 Î¼Î®Î½Î±"
+        other: "Ï€ÎµÏÎ¯Ï€Î¿Ï… %{count} Î¼Î®Î½ÎµÏ‚"
+      x_months:
+        one:   "1 Î¼Î®Î½Î±"
+        other: "%{count} Î¼Î®Î½ÎµÏ‚"
+      about_x_years:
+        one:   "Ï€ÎµÏÎ¯Ï€Î¿Ï… 1 Ï‡ÏÏŒÎ½Î¿"
+        other: "Ï€ÎµÏÎ¯Ï€Î¿Ï… %{count} Ï‡ÏÏŒÎ½Î¹Î±"
+      over_x_years:
+        one:   "Ï€Î¬Î½Ï‰ Î±Ï€ÏŒ 1 Ï‡ÏÏŒÎ½Î¿"
+        other: "Ï€Î¬Î½Ï‰ Î±Ï€ÏŒ %{count} Ï‡ÏÏŒÎ½Î¹Î±"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        precision: 3
+        delimiter: ""
+      storage_units:
+        format: "%n %u"
+        units:
+          kb: KB
+          tb: TB
+          gb: GB
+          byte:
+            one: Byte
+            other: Bytes
+          mb: MB
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "and"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "Î´ÎµÎ½ Ï€ÎµÏÎ¹Î­Ï‡ÎµÏ„Î±Î¹ ÏƒÏ„Î· Î»Î¯ÏƒÏ„Î±"
+        exclusion: "Î­Ï‡ÎµÎ¹ ÎºÎ±Ï„Î¿Ï‡Ï…ÏÏ‰Î¸ÎµÎ¯"
+        invalid: "ÎµÎ¯Î½Î±Î¹ Î¬ÎºÏ…ÏÎ¿"
+        confirmation: "Î´ÎµÎ½ Î±Î½Ï„Î¹ÏƒÏ„Î¿Î¹Ï‡ÎµÎ¯ Î¼Îµ Ï„Î·Î½ ÎµÏ€Î¹Î²ÎµÎ²Î±Î¯Ï‰ÏƒÎ·"
+        accepted: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± Î³Î¯Î½ÎµÎ¹ Î±Ï€Î¿Î´Î¿Ï‡Î®"
+        empty: "Î´Îµ Î¼Ï€Î¿ÏÎµÎ¯ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¬Î´ÎµÎ¹Î¿"
+        blank: "Î´Îµ Î¼Ï€Î¿ÏÎµÎ¯ Î½Î± ÎµÎ¯Î½Î±Î¹ ÎºÎµÎ½ÏŒ"
+        too_long: "Î­Ï‡ÎµÎ¹ Ï€Î¿Î»Î»Î¿ÏÏ‚ (Î¼Î­Î³.ÎµÏ€Î¹Ï„Ï. %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚)"
+        too_short: "Î­Ï‡ÎµÎ¹ Î»Î¯Î³Î¿Ï…Ï‚ (ÎµÎ»Î¬Ï‡.ÎµÏ€Î¹Ï„Ï. %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚)"
+        wrong_length: "Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ ÏƒÏ‰ÏƒÏ„ÏŒÏ‚ Î¿ Î±ÏÎ¹Î¸Î¼ÏŒÏ‚ Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÏ‰Î½ (Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± Î­Ï‡ÎµÎ¹ %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚)"
+        taken: "Î­Ï‡ÎµÎ¹ Î®Î´Î· ÎºÎ±Ï„Î¿Ï‡Ï…ÏÏ‰Î¸ÎµÎ¯"
+        not_a_number: "Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ Î±ÏÎ¹Î¸Î¼ÏŒÏ‚"
+        not_a_date: "Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ ÏƒÏ‰ÏƒÏ„Î® Î·Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±"
+        greater_than: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼ÎµÎ³Î±Î»ÏÏ„ÎµÏÎ¿ Î±Ï€ÏŒ %{count}"
+        greater_than_or_equal_to: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼ÎµÎ³Î±Î»ÏÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î® Î¯ÏƒÎ¿ Î¼Îµ %{count}"
+        equal_to: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¯ÏƒÎ¿Î½ Î¼Îµ %{count}"
+        less_than: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼Î¹ÎºÏÏŒÏ„ÎµÏÎ· Î±Ï€ÏŒ %{count}"
+        less_than_or_equal_to: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼Î¹ÎºÏÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î® Î¯ÏƒÎ¿ Î¼Îµ  %{count}"
+        odd: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¼Î¿Î½ÏŒÏ‚"
+        even: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î¶Ï…Î³ÏŒÏ‚"
+        greater_than_start_date: "Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± ÎµÎ¯Î½Î±Î¹ Î±ÏÎ³ÏŒÏ„ÎµÏÎ± Î±Ï€ÏŒ Ï„Î·Î½ Î·Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î± Î­Î½Î±ÏÎ¾Î·Ï‚"
+        not_same_project: "Î´ÎµÎ½ Î±Î½Î®ÎºÎµÎ¹ ÏƒÏ„Î¿ Î¯Î´Î¹Î¿ Î­ÏÎ³Î¿"
+        circular_dependency: "Î‘Ï…Ï„Î® Î· ÏƒÏ‡Î­ÏƒÎ· Î¸Î± Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î®ÏƒÎµÎ¹ ÎºÏ…ÎºÎ»Î¹ÎºÎ­Ï‚ ÎµÎ¾Î±ÏÏ„Î®ÏƒÎµÎ¹Ï‚"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: Î Î±ÏÎ±ÎºÎ±Î»ÏŽ ÎµÏ€Î¹Î»Î­Î¾Ï„Îµ
+
+  general_text_No: 'ÎŒÏ‡Î¹'
+  general_text_Yes: 'ÎÎ±Î¹'
+  general_text_no: 'ÏŒÏ‡Î¹'
+  general_text_yes: 'Î½Î±Î¹'
+  general_lang_name: 'Greek (Î•Î»Î»Î·Î½Î¹ÎºÎ¬)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_updated: ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ ÎµÏ€Î¹Ï„Ï…Ï‡ÏŽÏ‚.
+  notice_account_invalid_creditentials: Î†ÎºÏ…ÏÎ¿ ÏŒÎ½Î¿Î¼Î± Ï‡ÏÎ®ÏƒÏ„Î· Î® ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
+  notice_account_password_updated: ÎŸ ÎºÏ‰Î´Î¹ÎºÏŒÏ‚ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ ÎµÏ€Î¹Ï„Ï…Ï‡ÏŽÏ‚.
+  notice_account_wrong_password: Î›Î¬Î¸Î¿Ï‚ ÎºÏ‰Î´Î¹ÎºÏŒÏ‚ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
+  notice_account_register_done: ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î®Î¸Î·ÎºÎµ ÎµÏ€Î¹Ï„Ï…Ï‡ÏŽÏ‚. Î“Î¹Î± Î½Î± ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Ï„Î¿ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒ ÏƒÎ±Ï‚, Ï€Î±Ï„Î®ÏƒÏ„Îµ Ï„Î¿ ÏƒÏÎ½Î´ÎµÏƒÎ¼Î¿ Ï€Î¿Ï… ÏƒÎ±Ï‚ Î­Ï‡ÎµÎ¹ Î±Ï€Î¿ÏƒÏ„Î±Î»ÎµÎ¯ Î¼Îµ email.
+  notice_account_unknown_email: Î†Î³Î½Ï‰ÏƒÏ„Î¿Ï‚ Ï‡ÏÎ®ÏƒÏ„Î·Ï‚.
+  notice_can_t_change_password: Î‘Ï…Ï„ÏŒÏ‚ Î¿ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ Ï‡ÏÎ·ÏƒÎ¹Î¼Î¿Ï€Î¿Î¹ÎµÎ¯ ÎµÎ¾Ï‰Ï„ÎµÏÎ¹ÎºÎ® Ï€Î·Î³Î® Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚. Î”ÎµÎ½ ÎµÎ¯Î½Î±Î¹ Î´Ï…Î½Î±Ï„ÏŒÎ½ Î½Î± Î±Î»Î»Î¬Î¾ÎµÏ„Îµ Ï„Î¿Î½ ÎºÏ‰Î´Î¹ÎºÏŒ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚.
+  notice_account_lost_email_sent: Î£Î±Ï‚ Î­Ï‡ÎµÎ¹ Î±Ï€Î¿ÏƒÏ„Î±Î»ÎµÎ¯ email Î¼Îµ Î¿Î´Î·Î³Î¯ÎµÏ‚ Î³Î¹Î± Ï„Î·Î½ ÎµÏ€Î¹Î»Î¿Î³Î® Î½Î­Î¿Ï… ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚.
+  notice_account_activated: ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ ÏƒÎ±Ï‚ Î­Ï‡ÎµÎ¹ ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î·Î¸ÎµÎ¯. Î¤ÏŽÏÎ± Î¼Ï€Î¿ÏÎµÎ¯Ï„Îµ Î½Î± ÏƒÏ…Î½Î´ÎµÎ¸ÎµÎ¯Ï„Îµ.
+  notice_successful_create: Î•Ï€Î¹Ï„Ï…Ï‡Î®Ï‚ Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î±.
+  notice_successful_update: Î•Ï€Î¹Ï„Ï…Ï‡Î®Ï‚ ÎµÎ½Î·Î¼Î­ÏÏ‰ÏƒÎ·.
+  notice_successful_delete: Î•Ï€Î¹Ï„Ï…Ï‡Î®Ï‚ Î´Î¹Î±Î³ÏÎ±Ï†Î®.
+  notice_successful_connection: Î•Ï€Î¹Ï„Ï…Ï‡Î®Ï‚ ÏƒÏÎ½Î´ÎµÏƒÎ·.
+  notice_file_not_found: Î— ÏƒÎµÎ»Î¯Î´Î± Ï€Î¿Ï… Î¶Î·Ï„Î®ÏƒÎ±Ï„Îµ Î´ÎµÎ½ Ï…Ï€Î¬ÏÏ‡ÎµÎ¹ Î® Î­Ï‡ÎµÎ¹ Î±Ï†Î±Î¹ÏÎµÎ¸ÎµÎ¯.
+  notice_locking_conflict: Î¤Î± Î´ÎµÎ´Î¿Î¼Î­Î½Î± Î­Ï‡Î¿Ï…Î½ ÎµÎ½Î·Î¼ÎµÏÏ‰Î¸ÎµÎ¯ Î±Ï€ÏŒ Î¬Î»Î»Î¿ Ï‡ÏÎ®ÏƒÏ„Î·.
+  notice_not_authorized: Î”ÎµÎ½ Î­Ï‡ÎµÏ„Îµ Î´Î¹ÎºÎ±Î¯Ï‰Î¼Î± Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î· ÏƒÎµÎ»Î¯Î´Î±.
+  notice_email_sent: "ÎˆÎ½Î± Î¼Î®Î½Ï…Î¼Î± Î·Î»ÎµÎºÏ„ÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´ÏÎ¿Î¼ÎµÎ¯Î¿Ï… ÎµÏƒÏ„Î¬Î»Î· ÏƒÏ„Î¿ %{value}"
+  notice_email_error: "Î£Ï†Î¬Î»Î¼Î± ÎºÎ±Ï„Î¬ Ï„Î·Î½ Î±Ï€Î¿ÏƒÏ„Î¿Î»Î® Ï„Î¿Ï… Î¼Î·Î½ÏÎ¼Î±Ï„Î¿Ï‚ ÏƒÏ„Î¿ (%{value})"
+  notice_feeds_access_key_reseted:  ÎˆÎ³Î¹Î½Îµ ÎµÏ€Î±Î½Î±Ï†Î¿ÏÎ¬ ÏƒÏ„Î¿ ÎºÎ»ÎµÎ¹Î´Î¯ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ RSS.
+  notice_failed_to_save_issues: "Î‘Ï€Î¿Ï„Ï…Ï‡Î¯Î± Î±Ï€Î¿Î¸Î®ÎºÎµÏ…ÏƒÎ·Ï‚ %{count} Î¸ÎµÎ¼Î±(Ï„Ï‰Î½) Î±Ï€ÏŒ Ï„Î± %{total} ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î±: %{ids}."
+  notice_no_issue_selected: "ÎšÎ±Î½Î­Î½Î± Î¸Î­Î¼Î± Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î¿! Î Î±ÏÎ±ÎºÎ±Î»Î¿ÏÎ¼Îµ, ÎµÎ»Î­Î³Î¾Ï„Îµ Ï„Î± Î¸Î­Î¼Î±Ï„Î± Ï€Î¿Ï… Î¸Î­Î»ÎµÏ„Îµ Î½Î± ÎµÏ€ÎµÎ¾ÎµÏÎ³Î±ÏƒÏ„ÎµÎ¯Ï„Îµ."
+  notice_account_pending: "ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ ÏƒÎ±Ï‚ Î­Ï‡ÎµÎ¹ Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î·Î¸ÎµÎ¯ ÎºÎ±Î¹ ÎµÎ¯Î½Î±Î¹ ÏƒÎµ ÏƒÏ„Î¬Î´Î¹Î¿ Î­Î³ÎºÏÎ¹ÏƒÎ·Ï‚ Î±Ï€ÏŒ Ï„Î¿Î½ Î´Î¹Î±Ï‡ÎµÎ¹ÏÎ¹ÏƒÏ„Î®."
+  notice_default_data_loaded: ÎŸÎ¹ Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½ÎµÏ‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ Ï†Î¿ÏÏ„ÏŽÎ¸Î·ÎºÎ±Î½ ÎµÏ€Î¹Ï„Ï…Ï‡ÏŽÏ‚.
+  notice_unable_delete_version: Î‘Î´ÏÎ½Î±Ï„Î¿Î½ Î½Î± Î´Î¹Î±Î³ÏÎ±Ï†ÎµÎ¯ Î· Î­ÎºÎ´Î¿ÏƒÎ·.
+
+  error_can_t_load_default_data: "ÎŸÎ¹ Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½ÎµÏ‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ Î´ÎµÎ½ Î¼Ï€ÏŒÏÎµÏƒÎ±Î½ Î½Î± Ï†Î¿ÏÏ„Ï‰Î¸Î¿ÏÎ½:: %{value}"
+  error_scm_not_found: "Î— ÎµÎ³Î³ÏÎ±Ï†Î® Î® Î· Î±Î½Î±Î¸ÎµÏŽÏÎ·ÏƒÎ· Î´ÎµÎ½ Î²ÏÎ­Î¸Î·ÎºÎµ ÏƒÏ„Î¿ Î±Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î¿."
+  error_scm_command_failed: "Î Î±ÏÎ¿Ï…ÏƒÎ¹Î¬ÏƒÏ„Î·ÎºÎµ ÏƒÏ†Î¬Î»Î¼Î± ÎºÎ±Ï„Î¬ Ï„Î·Î½ Ï€ÏÎ¿ÏƒÏ€Î¬Î¸ÎµÎ¹Î± Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ ÏƒÏ„Î¿ Î±Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î¿: %{value}"
+  error_scm_annotate: "Î— ÎºÎ±Ï„Î±Ï‡ÏŽÏÎ¹ÏƒÎ· Î´ÎµÎ½ Ï…Ï€Î¬ÏÏ‡ÎµÎ¹ Î® Î´ÎµÎ½ Î¼Ï€Î¿ÏÎµÎ¯ Î½Î± ÏƒÏ‡Î¿Î»Î¹Î±ÏƒÏ„ÎµÎ¯."
+  error_issue_not_found_in_project: 'Î¤Î¿ Î¸Î­Î¼Î± Î´ÎµÎ½ Î²ÏÎ­Î¸Î·ÎºÎµ Î® Î´ÎµÎ½ Î±Î½Î®ÎºÎµÎ¹ ÏƒÎµ Î±Ï…Ï„ÏŒ Ï„Î¿ Î­ÏÎ³Î¿'
+  error_no_tracker_in_project: 'Î”ÎµÎ½ Ï…Ï€Î¬ÏÏ‡ÎµÎ¹ Î±Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®Ï‚ Î³Î¹Î± Î±Ï…Ï„ÏŒ Ï„Î¿ Î­ÏÎ³Î¿. Î Î±ÏÎ±ÎºÎ±Î»ÏŽ ÎµÎ»Î­Î³Î¾Ï„Îµ Ï„Î¹Ï‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ Ï„Î¿Ï… Î­ÏÎ³Î¿Ï….'
+  error_no_default_issue_status: 'Î”ÎµÎ½ Î­Ï‡ÎµÎ¹ Î¿ÏÎ¹ÏƒÏ„ÎµÎ¯ Î· Ï€ÏÎ¿ÎµÏ€Î¹Î»Î¿Î³Î®  ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·Ï‚ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½. Î Î±ÏÎ±ÎºÎ±Î»ÏŽ ÎµÎ»Î­Î³Î¾Ï„Îµ Ï„Î¹Ï‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ ÏƒÎ±Ï‚ (ÎœÎµÏ„Î±Î²ÎµÎ¯Ï„Îµ ÏƒÏ„Î·Î½  "Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· -> ÎšÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½").'
+
+  warning_attachments_not_saved: "%{count} Î±ÏÏ‡ÎµÎ¯Î¿(Î±) Î´Îµ Î¼Ï€Î¿ÏÎ¿ÏÎ½ Î½Î± Î±Ï€Î¿Î¸Î·ÎºÎµÏ…Ï„Î¿ÏÎ½."
+
+  mail_subject_lost_password: "ÎŸ ÎºÏ‰Î´Î¹ÎºÏŒÏ‚ ÏƒÎ±Ï‚ %{value}"
+  mail_body_lost_password: 'Î“Î¹Î± Î½Î± Î±Î»Î»Î¬Î¾ÎµÏ„Îµ Ï„Î¿Î½ ÎºÏ‰Î´Î¹ÎºÏŒ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚, Ï€Î±Ï„Î®ÏƒÏ„Îµ Ï„Î¿Î½ Î±ÎºÏŒÎ»Î¿Ï…Î¸Î¿ ÏƒÏÎ½Î´ÎµÏƒÎ¼Î¿:'
+  mail_subject_register: "Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· Ï„Î¿Ï… Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï Ï‡ÏÎ®ÏƒÏ„Î· %{value} "
+  mail_body_register: 'Î“Î¹Î± Î½Î± ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Ï„Î¿ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒ ÏƒÎ±Ï‚, ÎµÏ€Î¹Î»Î­Î¾Ï„Îµ Ï„Î¿Î½ Î±ÎºÏŒÎ»Î¿Ï…Î¸Î¿ ÏƒÏÎ½Î´ÎµÏƒÎ¼Î¿:'
+  mail_body_account_information_external: "ÎœÏ€Î¿ÏÎµÎ¯Ï„Îµ Î½Î± Ï‡ÏÎ·ÏƒÎ¹Î¼Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Ï„Î¿Î½ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒ %{value} Î³Î¹Î± Î½Î± ÏƒÏ…Î½Î´ÎµÎ¸ÎµÎ¯Ï„Îµ."
+  mail_body_account_information: Î Î»Î·ÏÎ¿Ï†Î¿ÏÎ¯ÎµÏ‚ Ï„Î¿Ï… Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÎ±Ï‚
+  mail_subject_account_activation_request: "Î±Î¯Ï„Î·Î¼Î± ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï %{value}"
+  mail_body_account_activation_request: "'ÎˆÎ½Î±Ï‚ Î½Î­Î¿Ï‚ Ï‡ÏÎ®ÏƒÏ„Î·Ï‚ (%{value}) Î­Ï‡ÎµÎ¹ ÎµÎ³Î³ÏÎ±Ï†ÎµÎ¯. ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ ÎµÎ¯Î½Î±Î¹ ÏƒÎµ ÏƒÏ„Î¬Î´Î¹Î¿ Î±Î½Î±Î¼Î¿Î½Î®Ï‚ Ï„Î·Ï‚ Î­Î³ÎºÏÎ¹ÏƒÎ·Ï‚ ÏƒÎ±Ï‚:"
+  mail_subject_reminder: "%{count} Î¸Î­Î¼Î±(Ï„Î±) Î¼Îµ Ï€ÏÎ¿Î¸ÎµÏƒÎ¼Î¯Î± ÏƒÏ„Î¹Ï‚ ÎµÏ€ÏŒÎ¼ÎµÎ½ÎµÏ‚ %{days} Î·Î¼Î­ÏÎµÏ‚"
+  mail_body_reminder: "%{count}Î¸Î­Î¼Î±(Ï„Î±)  Ï€Î¿Ï… Î­Ï‡Î¿Ï…Î½ Î±Î½Î±Ï„ÎµÎ¸ÎµÎ¯ ÏƒÎµ ÏƒÎ±Ï‚, Î¼Îµ Ï€ÏÎ¿Î¸ÎµÏƒÎ¼Î¯Î± ÏƒÏ„Î¹Ï‚ ÎµÏ€ÏŒÎ¼ÎµÎ½ÎµÏ‚ %{days} Î·Î¼Î­ÏÎµÏ‚:"
+  mail_subject_wiki_content_added: "'Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ Î· ÏƒÎµÎ»Î¯Î´Î± wiki %{id}' "
+  mail_body_wiki_content_added: "Î— ÏƒÎµÎ»Î¯Î´Î± wiki '%{id}' Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author}."
+  mail_subject_wiki_content_updated: "'ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î· ÏƒÎµÎ»Î¯Î´Î± wiki %{id}' "
+  mail_body_wiki_content_updated: "Î— ÏƒÎµÎ»Î¯Î´Î± wiki  '%{id}' ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author}."
+
+
+  field_name: ÎŒÎ½Î¿Î¼Î±
+  field_description: Î ÎµÏÎ¹Î³ÏÎ±Ï†Î®
+  field_summary: Î£Ï…Î½Î¿Ï€Ï„Î¹ÎºÎ¬
+  field_is_required: Î‘Ï€Î±Î¹Ï„ÎµÎ¯Ï„Î±Î¹
+  field_firstname: ÎŒÎ½Î¿Î¼Î±
+  field_lastname: Î•Ï€ÏŽÎ½Ï…Î¼Î¿
+  field_mail: Email
+  field_filename: Î‘ÏÏ‡ÎµÎ¯Î¿
+  field_filesize: ÎœÎ­Î³ÎµÎ¸Î¿Ï‚
+  field_downloads: ÎœÎµÏ„Î±Ï†Î¿ÏÏ„ÏŽÏƒÎµÎ¹Ï‚
+  field_author: Î£Ï…Î³Î³ÏÎ±Ï†Î­Î±Ï‚
+  field_created_on: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î®Î¸Î·ÎºÎµ
+  field_updated_on: Î•Î½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ
+  field_field_format: ÎœÎ¿ÏÏ†Î¿Ï€Î¿Î¯Î·ÏƒÎ·
+  field_is_for_all: Î“Î¹Î± ÏŒÎ»Î± Ï„Î± Î­ÏÎ³Î±
+  field_possible_values: Î Î¹Î¸Î±Î½Î­Ï‚ Ï„Î¹Î¼Î­Ï‚
+  field_regexp: ÎšÎ±Î½Î¿Î½Î¹ÎºÎ® Ï€Î±ÏÎ¬ÏƒÏ„Î±ÏƒÎ·
+  field_min_length: Î•Î»Î¬Ï‡Î¹ÏƒÏ„Î¿ Î¼Î®ÎºÎ¿Ï‚
+  field_max_length: ÎœÎ­Î³Î¹ÏƒÏ„Î¿ Î¼Î®ÎºÎ¿Ï‚
+  field_value: Î¤Î¹Î¼Î®
+  field_category: ÎšÎ±Ï„Î·Î³Î¿ÏÎ¯Î±
+  field_title: Î¤Î¯Ï„Î»Î¿Ï‚
+  field_project: ÎˆÏÎ³Î¿
+  field_issue: Î˜Î­Î¼Î±
+  field_status: ÎšÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·
+  field_notes: Î£Î·Î¼ÎµÎ¹ÏŽÏƒÎµÎ¹Ï‚
+  field_is_closed: ÎšÎ»ÎµÎ¹ÏƒÏ„Î¬ Î¸Î­Î¼Î±Ï„Î±
+  field_is_default: Î ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î· Ï„Î¹Î¼Î®
+  field_tracker: Î‘Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®Ï‚
+  field_subject: Î˜Î­Î¼Î±
+  field_due_date: Î ÏÎ¿Î¸ÎµÏƒÎ¼Î¯Î±
+  field_assigned_to: Î‘Î½Î¬Î¸ÎµÏƒÎ· ÏƒÎµ
+  field_priority: Î ÏÎ¿Ï„ÎµÏÎ±Î¹ÏŒÏ„Î·Ï„Î±
+  field_fixed_version: Î£Ï„ÏŒÏ‡Î¿Ï‚ Î­ÎºÎ´Î¿ÏƒÎ·Ï‚
+  field_user: Î§ÏÎ®ÏƒÏ„Î·Ï‚
+  field_role: Î¡ÏŒÎ»Î¿Ï‚
+  field_homepage: Î‘ÏÏ‡Î¹ÎºÎ® ÏƒÎµÎ»Î¯Î´Î±
+  field_is_public: Î”Î·Î¼ÏŒÏƒÎ¹Î¿
+  field_parent: Î•Ï€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î¿ Ï„Î¿Ï…
+  field_is_in_roadmap: Î ÏÎ¿Î²Î¿Î»Î® Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÏƒÏ„Î¿ Ï‡Î¬ÏÏ„Î· Ï€Î¿ÏÎµÎ¯Î±Ï‚
+  field_login: ÎŒÎ½Î¿Î¼Î± Ï‡ÏÎ®ÏƒÏ„Î·
+  field_mail_notification: Î•Î¹Î´Î¿Ï€Î¿Î¹Î®ÏƒÎµÎ¹Ï‚ email
+  field_admin: Î”Î¹Î±Ï‡ÎµÎ¹ÏÎ¹ÏƒÏ„Î®Ï‚
+  field_last_login_on: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± ÏƒÏÎ½Î´ÎµÏƒÎ·
+  field_language: Î“Î»ÏŽÏƒÏƒÎ±
+  field_effective_date: Î—Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±
+  field_password: ÎšÏ‰Î´Î¹ÎºÏŒÏ‚ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
+  field_new_password: ÎÎ­Î¿Ï‚ ÎºÏ‰Î´Î¹ÎºÏŒÏ‚ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
+  field_password_confirmation: Î•Ï€Î¹Î²ÎµÎ²Î±Î¯Ï‰ÏƒÎ·
+  field_version: ÎˆÎºÎ´Î¿ÏƒÎ·
+  field_type: Î¤ÏÏ€Î¿Ï‚
+  field_host: ÎšÏŒÎ¼Î²Î¿Ï‚
+  field_port: Î˜ÏÏÎ±
+  field_account: Î›Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚
+  field_base_dn: Î’Î¬ÏƒÎ· DN
+  field_attr_login: Î™Î´Î¹ÏŒÏ„Î·Ï„Î± ÎµÎ¹ÏƒÏŒÎ´Î¿Ï…
+  field_attr_firstname: Î™Î´Î¹ÏŒÏ„Î·Ï„Î± Î¿Î½ÏŒÎ¼Î±Ï„Î¿Ï‚
+  field_attr_lastname:  Î™Î´Î¹ÏŒÏ„Î·Ï„Î± ÎµÏ€Ï‰Î½ÏÎ¼Î¿Ï…
+  field_attr_mail: Î™Î´Î¹ÏŒÏ„Î·Ï„Î± email
+  field_onthefly: Î†Î¼ÎµÏƒÎ· Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± Ï‡ÏÎ®ÏƒÏ„Î·
+  field_start_date: Î•ÎºÎºÎ¯Î½Î·ÏƒÎ·
+  field_done_ratio: "% ÎµÏ€Î¹Ï„ÎµÏÏ‡Î¸Î·"
+  field_auth_source: Î¤ÏÏŒÏ€Î¿Ï‚ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚
+  field_hide_mail: Î‘Ï€ÏŒÎºÏÏ…ÏˆÎ· Î´Î¹ÎµÏÎ¸Ï…Î½ÏƒÎ·Ï‚ email
+  field_comments: Î£Ï‡ÏŒÎ»Î¹Î¿
+  field_url: URL
+  field_start_page: Î ÏÏŽÏ„Î· ÏƒÎµÎ»Î¯Î´Î±
+  field_subproject: Î•Ï€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î¿
+  field_hours: ÎÏÎµÏ‚
+  field_activity: Î”ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î±
+  field_spent_on: Î—Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±
+  field_identifier: Î£Ï„Î¿Î¹Ï‡ÎµÎ¯Î¿ Î±Î½Î±Î³Î½ÏŽÏÎ¹ÏƒÎ·Ï‚
+  field_is_filter: Î§ÏÎ®ÏƒÎ· Ï‰Ï‚ Ï†Î¯Î»Ï„ÏÎ¿
+  field_issue_to: Î£Ï‡ÎµÏ„Î¹ÎºÎ¬ Î¸Î­Î¼Î±Ï„Î±
+  field_delay: ÎšÎ±Î¸Ï…ÏƒÏ„Î­ÏÎ·ÏƒÎ·
+  field_assignable: Î˜Î­Î¼Î±Ï„Î± Ï€Î¿Ï… Î¼Ï€Î¿ÏÎ¿ÏÎ½ Î½Î± Î±Î½Î±Ï„ÎµÎ¸Î¿ÏÎ½ ÏƒÎµ Î±Ï…Ï„ÏŒ Ï„Î¿ ÏÏŒÎ»Î¿
+  field_redirect_existing_links: Î‘Î½Î±ÎºÎ±Ï„ÎµÏÎ¸Ï…Î½ÏƒÎ· Ï„Ï‰Î½ Ï„ÏÎµÏ‡ÏŒÎ½Ï„Ï‰Î½ ÏƒÏ…Î½Î´Î­ÏƒÎ¼Ï‰Î½
+  field_estimated_hours: Î•ÎºÏ„Î¹Î¼ÏŽÎ¼ÎµÎ½Î¿Ï‚ Ï‡ÏÏŒÎ½Î¿Ï‚
+  field_column_names: Î£Ï„Î®Î»ÎµÏ‚
+  field_time_zone: Î©ÏÎ¹Î±Î¯Î± Î¶ÏŽÎ½Î·
+  field_searchable: Î•ÏÎµÏ…Î½Î®ÏƒÎ¹Î¼Î¿
+  field_default_value: Î ÏÎ¿ÎºÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼Î­Î½Î· Ï„Î¹Î¼Î®
+  field_comments_sorting: Î ÏÎ¿Î²Î¿Î»Î® ÏƒÏ‡Î¿Î»Î¯Ï‰Î½
+  field_parent_title: Î“Î¿Î½Î¹ÎºÎ® ÏƒÎµÎ»Î¯Î´Î±
+  field_editable: Î•Ï€ÎµÎ¾ÎµÏÎ³Î¬ÏƒÎ¹Î¼Î¿
+  field_watcher: Î Î±ÏÎ±Ï„Î·ÏÎ·Ï„Î®Ï‚
+  field_identity_url: OpenID URL
+  field_content: Î ÎµÏÎ¹ÎµÏ‡ÏŒÎ¼ÎµÎ½Î¿
+  field_group_by: ÎŸÎ¼Î±Î´Î¹ÎºÎ¬ Î±Ï€Î¿Ï„ÎµÎ»Î­ÏƒÎ¼Î±Ï„Î± Î±Ï€ÏŒ
+
+  setting_app_title: Î¤Î¯Ï„Î»Î¿Ï‚ ÎµÏ†Î±ÏÎ¼Î¿Î³Î®Ï‚
+  setting_app_subtitle: Î¥Ï€ÏŒÏ„Î¹Ï„Î»Î¿Ï‚ ÎµÏ†Î±ÏÎ¼Î¿Î³Î®Ï‚
+  setting_welcome_text: ÎšÎµÎ¯Î¼ÎµÎ½Î¿ Ï…Ï€Î¿Î´Î¿Ï‡Î®Ï‚
+  setting_default_language: Î ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î· Î³Î»ÏŽÏƒÏƒÎ±
+  setting_login_required: Î‘Ï€Î±Î¹Ï„ÎµÎ¯Ï„Î±Î¹ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·
+  setting_self_registration: Î‘Ï…Ï„Î¿-ÎµÎ³Î³ÏÎ±Ï†Î®
+  setting_attachment_max_size: ÎœÎ­Î³. Î¼Î­Î³ÎµÎ¸Î¿Ï‚ ÏƒÏ…Î½Î·Î¼Î¼Î­Î½Î¿Ï…
+  setting_issues_export_limit: Î˜Î­Î¼Î±Ï„Î± Ï€ÎµÏÎ¹Î¿ÏÎ¹ÏƒÎ¼Î¿Ï ÎµÎ¾Î±Î³Ï‰Î³Î®Ï‚
+  setting_mail_from: ÎœÎµÏ„Î¬Î´Î¿ÏƒÎ· Î´Î¹ÎµÏÎ¸Ï…Î½ÏƒÎ·Ï‚ email
+  setting_bcc_recipients: Î‘Ï€Î¿Î´Î­ÎºÏ„ÎµÏ‚ ÎºÏÏ…Ï†Î®Ï‚ ÎºÎ¿Î¹Î½Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚ (bcc)
+  setting_plain_text_mail: Email Î±Ï€Î»Î¿Ï ÎºÎµÎ¹Î¼Î­Î½Î¿Ï… (ÏŒÏ‡Î¹ HTML)
+  setting_host_name: ÎŒÎ½Î¿Î¼Î± ÎºÏŒÎ¼Î²Î¿Ï… ÎºÎ±Î¹ Î´Î¹Î±Î´ÏÎ¿Î¼Î®
+  setting_text_formatting: ÎœÎ¿ÏÏ†Î¿Ï€Î¿Î¯Î·ÏƒÎ· ÎºÎµÎ¹Î¼Î­Î½Î¿Ï…
+  setting_wiki_compression: Î£Ï…Î¼Ï€Î¯ÎµÏƒÎ· Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÎ¿Ï wiki
+  setting_feeds_limit: Feed Ï€ÎµÏÎ¹Î¿ÏÎ¹ÏƒÎ¼Î¿Ï Ï€ÎµÏÎ¹ÎµÏ‡Î¿Î¼Î­Î½Î¿Ï…
+  setting_default_projects_public: Î¤Î± Î½Î­Î± Î­ÏÎ³Î± Î­Ï‡Î¿Ï…Î½ Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³ÎµÎ¯ Ï‰Ï‚ Î´Î·Î¼ÏŒÏƒÎ¹Î±
+  setting_autofetch_changesets: Î‘Ï…Ï„ÏŒÎ¼Î±Ï„Î· Î»Î®ÏˆÎ· commits
+  setting_sys_api_enabled: Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· WS Î³Î¹Î± Î´Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î±Ï€Î¿Î¸ÎµÏ„Î·ÏÎ¯Î¿Ï…
+  setting_commit_ref_keywords: Î‘Î½Î±Ï†Î¿ÏÎ¬ ÏƒÎµ Î»Î­Î¾ÎµÎ¹Ï‚-ÎºÎ»ÎµÎ¹Î´Î¹Î¬
+  setting_commit_fix_keywords: ÎšÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼ÏŒÏ‚ ÏƒÎµ Î»Î­Î¾ÎµÎ¹Ï‚-ÎºÎ»ÎµÎ¹Î´Î¹Î¬
+  setting_autologin: Î‘Ï…Ï„ÏŒÎ¼Î±Ï„Î· ÏƒÏÎ½Î´ÎµÏƒÎ·
+  setting_date_format: ÎœÎ¿ÏÏ†Î® Î·Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±Ï‚
+  setting_time_format: ÎœÎ¿ÏÏ†Î® ÏŽÏÎ±Ï‚
+  setting_cross_project_issue_relations: Î•Ï€Î¹Ï„ÏÎ­ÏˆÏ„Îµ ÏƒÏ…ÏƒÏ‡ÎµÏ„Î¹ÏƒÎ¼ÏŒ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÏƒÎµ Î´Î¹Î±ÏƒÏ„Î±ÏÏÏ‰ÏƒÎ·-Î­ÏÎ³Ï‰Î½
+  setting_issue_list_default_columns: Î ÏÎ¿ÎºÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼Î­Î½ÎµÏ‚ ÎµÎ¼Ï†Î±Î½Î¹Î¶ÏŒÎ¼ÎµÎ½ÎµÏ‚ ÏƒÏ„Î®Î»ÎµÏ‚ ÏƒÏ„Î· Î»Î¯ÏƒÏ„Î± Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  setting_emails_footer: Î¥Ï€Î¿ÏƒÎ­Î»Î¹Î´Î¿ ÏƒÏ„Î± email
+  setting_protocol: Î ÏÏ‰Ï„ÏŒÎºÎ¿Î»Î¿
+  setting_per_page_options: Î‘Î½Ï„Î¹ÎºÎµÎ¯Î¼ÎµÎ½Î± Î±Î½Î¬ ÏƒÎµÎ»Î¯Î´Î± ÎµÏ€Î¹Î»Î¿Î³ÏŽÎ½
+  setting_user_format: ÎœÎ¿ÏÏ†Î® ÎµÎ¼Ï†Î¬Î½Î¹ÏƒÎ·Ï‚ Ï‡ÏÎ·ÏƒÏ„ÏŽÎ½
+  setting_activity_days_default: Î—Î¼Î­ÏÎµÏ‚ Ï€Î¿Ï… ÎµÎ¼Ï†Î±Î½Î¯Î¶ÎµÏ„Î±Î¹ ÏƒÏ„Î· Î´ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î± Î­ÏÎ³Î¿Ï…
+  setting_display_subprojects_issues: Î•Î¼Ï†Î¬Î½Î¹ÏƒÎ· Î±Ï€ÏŒ Ï€ÏÎ¿ÎµÏ€Î¹Î»Î¿Î³Î® Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÎµÏ€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Ï‰Î½ ÏƒÏ„Î± ÎºÏÏÎ¹Î± Î­ÏÎ³Î±
+  setting_enabled_scm: Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· SCM
+  setting_mail_handler_api_enabled: Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· WS Î³Î¹Î± ÎµÎ¹ÏƒÎµÏÏ‡ÏŒÎ¼ÎµÎ½Î± email
+  setting_mail_handler_api_key: ÎºÎ»ÎµÎ¹Î´Î¯ API
+  setting_sequential_project_identifiers: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± Î´Î¹Î±Î´Î¿Ï‡Î¹ÎºÏŽÎ½ Î±Î½Î±Î³Î½Ï‰ÏÎ¹ÏƒÏ„Î¹ÎºÏŽÎ½ Î­ÏÎ³Î¿Ï…
+  setting_gravatar_enabled: Î§ÏÎ®ÏƒÎ· Gravatar ÎµÎ¹ÎºÎ¿Î½Î¹Î´Î¯Ï‰Î½ Ï‡ÏÎ·ÏƒÏ„ÏŽÎ½
+  setting_diff_max_lines_displayed: ÎœÎµÎ³.Î±ÏÎ¹Î¸Î¼ÏŒÏ‚ ÎµÎ¼Ï†Î¬Î½Î¹ÏƒÎ·Ï‚ Î³ÏÎ±Î¼Î¼ÏŽÎ½ diff
+  setting_file_max_size_displayed: ÎœÎµÎ³.Î¼Î­Î³ÎµÎ¸Î¿Ï‚ Ï„Ï‰Î½ Î±ÏÏ‡ÎµÎ¯Ï‰Î½ Î±Ï€Î»Î¿Ï ÎºÎµÎ¹Î¼Î­Î½Î¿Ï… Ï€Î¿Ï… ÎµÎ¼Ï†Î±Î½Î¯Î¶Î¿Î½Ï„Î±Î¹ ÏƒÎµ ÏƒÎµÎ¹ÏÎ¬
+  setting_repository_log_display_limit: ÎœÎ­Î³Î¹ÏƒÏ„Î¿Ï‚ Î±ÏÎ¹Î¸Î¼ÏŒÏ‚ Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÏ‰Î½ Ï€Î¿Ï… ÎµÎ¼Ï†Î±Î½Î¯Î¶Î¿Î½Ï„Î±Î¹ ÏƒÏ„Î¿ Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ Î±ÏÏ‡ÎµÎ¯Î¿Ï…
+  setting_openid: Î•Ï€Î¹Ï„ÏÎ­ÏˆÏ„Îµ ÏƒÏ…Î½Î´Î­ÏƒÎµÎ¹Ï‚ OpenID ÎºÎ±Î¹ ÎµÎ³Î³ÏÎ±Ï†Î®
+  setting_password_min_length: Î•Î»Î¬Ï‡Î¹ÏƒÏ„Î¿ Î¼Î®ÎºÎ¿Ï‚ ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
+  setting_new_project_user_role_id: Î‘Ï€ÏŒÎ´Î¿ÏƒÎ· ÏÏŒÎ»Î¿Ï… ÏƒÎµ Ï‡ÏÎ®ÏƒÏ„Î· Î¼Î·-Î´Î¹Î±Ï‡ÎµÎ¹ÏÎ¹ÏƒÏ„Î® ÏŒÏ„Î±Î½ Î´Î·Î¼Î¹Î¿Ï…ÏÎ³ÎµÎ¯ Î­Î½Î± Î­ÏÎ³Î¿
+
+  permission_add_project: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± Î­ÏÎ³Î¿Ï…
+  permission_edit_project: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î­ÏÎ³Î¿Ï…
+  permission_select_project_modules: Î•Ï€Î¹Î»Î¿Î³Î® Î¼Î¿Î½Î¬Î´Ï‰Î½ Î­ÏÎ³Î¿Ï…
+  permission_manage_members: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î¼ÎµÎ»ÏŽÎ½
+  permission_manage_versions: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÎµÎºÎ´ÏŒÏƒÎµÏ‰Î½
+  permission_manage_categories: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÎºÎ±Ï„Î·Î³Î¿ÏÎ¹ÏŽÎ½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  permission_add_issues: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  permission_edit_issues: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  permission_manage_issue_relations: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÏƒÏ…ÏƒÏ‡ÎµÏ„Î¹ÏƒÎ¼ÏŽÎ½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  permission_add_issue_notes: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· ÏƒÎ·Î¼ÎµÎ¹ÏŽÏƒÎµÏ‰Î½
+  permission_edit_issue_notes: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± ÏƒÎ·Î¼ÎµÎ¹ÏŽÏƒÎµÏ‰Î½
+  permission_edit_own_issue_notes: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î´Î¹ÎºÏŽÎ½ Î¼Î¿Ï… ÏƒÎ·Î¼ÎµÎ¹ÏŽÏƒÎµÏ‰Î½
+  permission_move_issues: ÎœÎµÏ„Î±Ï†Î¿ÏÎ¬ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  permission_delete_issues: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  permission_manage_public_queries: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î´Î·Î¼ÏŒÏƒÎ¹Ï‰Î½ Î±Î½Î±Î¶Î·Ï„Î®ÏƒÎµÏ‰Î½
+  permission_save_queries: Î‘Ï€Î¿Î¸Î®ÎºÎµÏ…ÏƒÎ· Î±Î½Î±Î¶Î·Ï„Î®ÏƒÎµÏ‰Î½
+  permission_view_gantt: Î ÏÎ¿Î²Î¿Î»Î® Î´Î¹Î±Î³ÏÎ¬Î¼Î¼Î±Ï„Î¿Ï‚ gantt
+  permission_view_calendar: Î ÏÎ¿Î²Î¿Î»Î® Î·Î¼ÎµÏÎ¿Î»Î¿Î³Î¯Î¿Ï…
+  permission_view_issue_watchers: Î ÏÎ¿Î²Î¿Î»Î® Î»Î¯ÏƒÏ„Î±Ï‚ Ï€Î±ÏÎ±Ï„Î·ÏÎ·Ï„ÏŽÎ½
+  permission_add_issue_watchers: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Ï€Î±ÏÎ±Ï„Î·ÏÎ·Ï„ÏŽÎ½
+  permission_log_time: Î™ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ Ï‡ÏÏŒÎ½Î¿Ï… Ï€Î¿Ï… Î´Î±Ï€Î±Î½Î®Î¸Î·ÎºÎµ
+  permission_view_time_entries: Î ÏÎ¿Î²Î¿Î»Î® Ï‡ÏÏŒÎ½Î¿Ï… Ï€Î¿Ï… Î´Î±Ï€Î±Î½Î®Î¸Î·ÎºÎµ
+  permission_edit_time_entries: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÎ¿Ï Ï‡ÏÏŒÎ½Î¿Ï…
+  permission_edit_own_time_entries: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î´Î¹ÎºÎ¿Ï Î¼Î¿Ï… Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÎ¿Ï Ï‡ÏÏŒÎ½Î¿Ï…
+  permission_manage_news: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î½Î­Ï‰Î½
+  permission_comment_news: Î£Ï‡Î¿Î»Î¹Î±ÏƒÎ¼ÏŒÏ‚ Î½Î­Ï‰Î½
+  permission_view_documents: Î ÏÎ¿Î²Î¿Î»Î® ÎµÎ³Î³ÏÎ¬Ï†Ï‰Î½
+  permission_manage_files: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î±ÏÏ‡ÎµÎ¯Ï‰Î½
+  permission_view_files: Î ÏÎ¿Î²Î¿Î»Î® Î±ÏÏ‡ÎµÎ¯Ï‰Î½
+  permission_manage_wiki: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· wiki
+  permission_rename_wiki_pages: ÎœÎµÏ„Î¿Î½Î¿Î¼Î±ÏƒÎ¯Î± ÏƒÎµÎ»Î¯Î´Ï‰Î½ wiki
+  permission_delete_wiki_pages: Î”Î¹Î±Î³ÏÎ±Ï†Î® ÏƒÎµÎ»Î¯Î´Ï‰Î½ wiki
+  permission_view_wiki_pages: Î ÏÎ¿Î²Î¿Î»Î® wiki
+  permission_view_wiki_edits: Î ÏÎ¿Î²Î¿Î»Î® Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÎ¿Ï wiki
+  permission_edit_wiki_pages: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± ÏƒÎµÎ»Î¯Î´Ï‰Î½ wiki
+  permission_delete_wiki_pages_attachments: Î”Î¹Î±Î³ÏÎ±Ï†Î® ÏƒÏ…Î½Î·Î¼Î¼Î­Î½Ï‰Î½
+  permission_protect_wiki_pages: Î ÏÎ¿ÏƒÏ„Î±ÏƒÎ¯Î± ÏƒÎµÎ»Î¯Î´Ï‰Î½ wiki
+  permission_manage_repository: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î±Ï€Î¿Î¸ÎµÏ„Î·ÏÎ¯Î¿Ï…
+  permission_browse_repository: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÎµÎ³Î³ÏÎ¬Ï†Ï‰Î½
+  permission_view_changesets: Î ÏÎ¿Î²Î¿Î»Î® changesets
+  permission_commit_access: Î ÏÏŒÏƒÎ²Î±ÏƒÎ· commit
+  permission_manage_boards: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Ï€Î¹Î½Î¬ÎºÏ‰Î½ ÏƒÏ…Î¶Î·Ï„Î®ÏƒÎµÏ‰Î½
+  permission_view_messages: Î ÏÎ¿Î²Î¿Î»Î® Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
+  permission_add_messages: Î‘Ï€Î¿ÏƒÏ„Î¿Î»Î® Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
+  permission_edit_messages: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
+  permission_edit_own_messages: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î´Î¹ÎºÏŽÎ½ Î¼Î¿Ï… Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
+  permission_delete_messages: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
+  permission_delete_own_messages: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î´Î¹ÎºÏŽÎ½ Î¼Î¿Ï… Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½
+
+  project_module_issue_tracking: Î‘Î½Î¯Ï‡Î½ÎµÏ…ÏƒÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  project_module_time_tracking: Î‘Î½Î¯Ï‡Î½ÎµÏ…ÏƒÎ· Ï‡ÏÏŒÎ½Î¿Ï…
+  project_module_news: ÎÎ­Î±
+  project_module_documents: ÎˆÎ³Î³ÏÎ±Ï†Î±
+  project_module_files: Î‘ÏÏ‡ÎµÎ¯Î±
+  project_module_wiki: Wiki
+  project_module_repository: Î‘Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î¿
+  project_module_boards: Î Î¯Î½Î±ÎºÎµÏ‚ ÏƒÏ…Î¶Î·Ï„Î®ÏƒÎµÏ‰Î½
+
+  label_user: Î§ÏÎ®ÏƒÏ„Î·Ï‚
+  label_user_plural: Î§ÏÎ®ÏƒÏ„ÎµÏ‚
+  label_user_new: ÎÎ­Î¿Ï‚ Î§ÏÎ®ÏƒÏ„Î·Ï‚
+  label_project: ÎˆÏÎ³Î¿
+  label_project_new: ÎÎ­Î¿ Î­ÏÎ³Î¿
+  label_project_plural: ÎˆÏÎ³Î±
+  label_x_projects:
+    zero:  ÎºÎ±Î½Î­Î½Î± Î­ÏÎ³Î¿
+    one:   1 Î­ÏÎ³Î¿
+    other: "%{count} Î­ÏÎ³Î±"
+  label_project_all: ÎŒÎ»Î± Ï„Î± Î­ÏÎ³Î±
+  label_project_latest: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± Î­ÏÎ³Î±
+  label_issue: Î˜Î­Î¼Î±
+  label_issue_new: ÎÎ­Î¿ Î¸Î­Î¼Î±
+  label_issue_plural: Î˜Î­Î¼Î±Ï„Î±
+  label_issue_view_all: Î ÏÎ¿Î²Î¿Î»Î® ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  label_issues_by: "Î˜Î­Î¼Î±Ï„Î± Ï„Î¿Ï…  %{value}"
+  label_issue_added: Î¤Î¿ Î¸Î­Î¼Î± Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
+  label_issue_updated: Î¤Î¿ Î¸Î­Î¼Î± ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ
+  label_document: ÎˆÎ³Î³ÏÎ±Ï†Î¿
+  label_document_new: ÎÎ­Î¿ Î­Î³Î³ÏÎ±Ï†Î¿
+  label_document_plural: ÎˆÎ³Î³ÏÎ±Ï†Î±
+  label_document_added: ÎˆÎ³Î³ÏÎ±Ï†Î¿ Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
+  label_role: Î¡ÏŒÎ»Î¿Ï‚
+  label_role_plural: Î¡ÏŒÎ»Î¿Î¹
+  label_role_new: ÎÎ­Î¿Ï‚ ÏÏŒÎ»Î¿Ï‚
+  label_role_and_permissions: Î¡ÏŒÎ»Î¿Î¹ ÎºÎ±Î¹ Î¬Î´ÎµÎ¹ÎµÏ‚
+  label_member: ÎœÎ­Î»Î¿Ï‚
+  label_member_new: ÎÎ­Î¿ Î¼Î­Î»Î¿Ï‚
+  label_member_plural: ÎœÎ­Î»Î·
+  label_tracker: Î‘Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®Ï‚
+  label_tracker_plural: Î‘Î½Î¹Ï‡Î½ÎµÏ…Ï„Î­Ï‚
+  label_tracker_new: ÎÎ­Î¿Ï‚ Î‘Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®Ï‚
+  label_workflow: Î¡Î¿Î® ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚
+  label_issue_status: ÎšÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ· Î¸Î­Î¼Î±Ï„Î¿Ï‚
+  label_issue_status_plural: ÎšÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ· Î¸Î­Î¼Î±Ï„Î¿Ï‚
+  label_issue_status_new: ÎÎ­Î± ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·
+  label_issue_category: ÎšÎ±Ï„Î·Î³Î¿ÏÎ¯Î± Î¸Î­Î¼Î±Ï„Î¿Ï‚
+  label_issue_category_plural: ÎšÎ±Ï„Î·Î³Î¿ÏÎ¯ÎµÏ‚ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  label_issue_category_new: ÎÎ­Î± ÎºÎ±Ï„Î·Î³Î¿ÏÎ¯Î±
+  label_custom_field: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½Î¿ Ï€ÎµÎ´Î¯Î¿
+  label_custom_field_plural: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½Î± Ï€ÎµÎ´Î¯Î±
+  label_custom_field_new: ÎÎ­Î¿ Ï€ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½Î¿ Ï€ÎµÎ´Î¯Î¿
+  label_enumerations: Î‘Ï€Î±ÏÎ¹Î¸Î¼Î®ÏƒÎµÎ¹Ï‚
+  label_enumeration_new: ÎÎ­Î± Ï„Î¹Î¼Î®
+  label_information: Î Î»Î·ÏÎ¿Ï†Î¿ÏÎ¯Î±
+  label_information_plural: Î Î»Î·ÏÎ¿Ï†Î¿ÏÎ¯ÎµÏ‚
+  label_please_login: Î Î±ÏÎ±ÎºÎ±Î»ÏŽ ÏƒÏ…Î½Î´ÎµÎ¸ÎµÎ¯Ï„Îµ
+  label_register: Î•Î³Î³ÏÎ±Ï†Î®
+  label_login_with_open_id_option: Î® ÏƒÏ…Î½Î´ÎµÎ¸ÎµÎ¯Ï„Îµ Î¼Îµ OpenID
+  label_password_lost: Î‘Î½Î¬ÎºÏ„Î·ÏƒÎ· ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
+  label_home: Î‘ÏÏ‡Î¹ÎºÎ® ÏƒÎµÎ»Î¯Î´Î±
+  label_my_page: Î— ÏƒÎµÎ»Î¯Î´Î± Î¼Î¿Ï…
+  label_my_account: ÎŸ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ Î¼Î¿Ï…
+  label_my_projects: Î¤Î± Î­ÏÎ³Î± Î¼Î¿Ï…
+  label_administration: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ·
+  label_login: Î£ÏÎ½Î´ÎµÏƒÎ·
+  label_logout: Î‘Ï€Î¿ÏƒÏÎ½Î´ÎµÏƒÎ·
+  label_help: Î’Î¿Î®Î¸ÎµÎ¹Î±
+  label_reported_issues: Î•Î¹ÏƒÎ·Î³Î¼Î­Î½Î± Î¸Î­Î¼Î±Ï„Î±
+  label_assigned_to_me_issues: Î˜Î­Î¼Î±Ï„Î± Ï€Î¿Ï… Î­Ï‡Î¿Ï…Î½ Î±Î½Î±Ï„ÎµÎ¸ÎµÎ¯ ÏƒÎµ Î¼Î­Î½Î±
+  label_last_login: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± ÏƒÏÎ½Î´ÎµÏƒÎ·
+  label_registered_on: Î•Î³Î³ÏÎ¬Ï†Î·ÎºÎµ Ï„Î·Î½
+  label_activity: Î”ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î±
+  label_overall_activity: Î£Ï…Î½Î¿Î»Î¹ÎºÎ® Î´ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î±
+  label_user_activity: "Î´ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„Î± Ï„Î¿Ï… %{value}"
+  label_new: ÎÎ­Î¿
+  label_logged_as: Î£ÏÎ½Î´ÎµÎ´ÎµÎ¼Î­Î½Î¿Ï‚ Ï‰Ï‚
+  label_environment: Î ÎµÏÎ¹Î²Î¬Î»Î»Î¿Î½
+  label_authentication: Î Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·
+  label_auth_source: Î¤ÏÏŒÏ€Î¿Ï‚ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚
+  label_auth_source_new: ÎÎ­Î¿Ï‚ Ï„ÏÏŒÏ€Î¿Ï‚ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚
+  label_auth_source_plural: Î¤ÏÏŒÏ€Î¿Î¹ Ï€Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ·Ï‚
+  label_subproject_plural: Î•Ï€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î±
+  label_and_its_subprojects: "%{value} ÎºÎ±Î¹ Ï„Î± ÎµÏ€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î± Ï„Î¿Ï…"
+  label_min_max_length: Î•Î»Î¬Ï‡. - ÎœÎ­Î³. Î¼Î®ÎºÎ¿Ï‚
+  label_list: Î›Î¯ÏƒÏ„Î±
+  label_date: Î—Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±
+  label_integer: Î‘ÎºÎ­ÏÎ±Î¹Î¿Ï‚
+  label_float: Î‘ÏÎ¹Î¸Î¼ÏŒÏ‚ ÎºÎ¹Î½Î·Ï„Î®Ï‚ Ï…Ï€Î¿Î´Î¹Î±ÏƒÏ„Î¿Î»Î®Ï‚
+  label_boolean: Î›Î¿Î³Î¹ÎºÏŒÏ‚
+  label_string: ÎšÎµÎ¯Î¼ÎµÎ½Î¿
+  label_text: ÎœÎ±ÎºÏÎ¿ÏƒÎºÎµÎ»Î­Ï‚ ÎºÎµÎ¯Î¼ÎµÎ½Î¿
+  label_attribute: Î™Î´Î¹ÏŒÏ„Î·Ï„Î±
+  label_attribute_plural: Î™Î´Î¹ÏŒÏ„Î·Ï„ÎµÏ‚
+  label_no_data: Î”ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ Î´ÎµÎ´Î¿Î¼Î­Î½Î±
+  label_change_status: Î‘Î»Î»Î±Î³Î® ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·Ï‚
+  label_history: Î™ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ
+  label_attachment: Î‘ÏÏ‡ÎµÎ¯Î¿
+  label_attachment_new: ÎÎ­Î¿ Î±ÏÏ‡ÎµÎ¯Î¿
+  label_attachment_delete: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î±ÏÏ‡ÎµÎ¯Î¿Ï…
+  label_attachment_plural: Î‘ÏÏ‡ÎµÎ¯Î±
+  label_file_added: Î¤Î¿ Î±ÏÏ‡ÎµÎ¯Î¿ Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
+  label_report: Î‘Î½Î±Ï†Î¿ÏÎ¬
+  label_report_plural: Î‘Î½Î±Ï†Î¿ÏÎ­Ï‚
+  label_news: ÎÎ­Î±
+  label_news_new: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Î½Î­Ï‰Î½
+  label_news_plural: ÎÎ­Î±
+  label_news_latest: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± Î½Î­Î±
+  label_news_view_all: Î ÏÎ¿Î²Î¿Î»Î® ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î½Î­Ï‰Î½
+  label_news_added: Î¤Î± Î½Î­Î± Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎ±Î½
+  label_settings: Î¡Ï…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚
+  label_overview: Î•Ï€Î¹ÏƒÎºÏŒÏ€Î·ÏƒÎ·
+  label_version: ÎˆÎºÎ´Î¿ÏƒÎ·
+  label_version_new: ÎÎ­Î± Î­ÎºÎ´Î¿ÏƒÎ·
+  label_version_plural: Î•ÎºÎ´ÏŒÏƒÎµÎ¹Ï‚
+  label_confirmation: Î•Ï€Î¹Î²ÎµÎ²Î±Î¯Ï‰ÏƒÎ·
+  label_export_to: 'Î•Ï€Î¯ÏƒÎ·Ï‚ Î´Î¹Î±Î¸Î­ÏƒÎ¹Î¼Î¿ ÏƒÎµ:'
+  label_read: Î”Î¹Î¬Î²Î±ÏƒÎµ...
+  label_public_projects: Î”Î·Î¼ÏŒÏƒÎ¹Î± Î­ÏÎ³Î±
+  label_open_issues: Î‘Î½Î¿Î¹ÎºÏ„ÏŒ
+  label_open_issues_plural: Î‘Î½Î¿Î¹ÎºÏ„Î¬
+  label_closed_issues: ÎšÎ»ÎµÎ¹ÏƒÏ„ÏŒ
+  label_closed_issues_plural: ÎšÎ»ÎµÎ¹ÏƒÏ„Î¬
+  label_x_open_issues_abbr_on_total:
+    zero:  0 Î±Î½Î¿Î¹ÎºÏ„Î¬ / %{total}
+    one:   1 Î±Î½Î¿Î¹ÎºÏ„ÏŒ / %{total}
+    other: "%{count} Î±Î½Î¿Î¹ÎºÏ„Î¬ / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 Î±Î½Î¿Î¹ÎºÏ„Î¬
+    one:   1 Î±Î½Î¿Î¹ÎºÏ„ÏŒ
+    other: "%{count} Î±Î½Î¿Î¹ÎºÏ„Î¬"
+  label_x_closed_issues_abbr:
+    zero:  0 ÎºÎ»ÎµÎ¹ÏƒÏ„Î¬
+    one:   1 ÎºÎ»ÎµÎ¹ÏƒÏ„ÏŒ
+    other: "%{count} ÎºÎ»ÎµÎ¹ÏƒÏ„Î¬"
+  label_total: Î£ÏÎ½Î¿Î»Î¿
+  label_permissions: Î†Î´ÎµÎ¹ÎµÏ‚
+  label_current_status: Î¤ÏÎ­Ï‡Î¿Ï…ÏƒÎ± ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·
+  label_new_statuses_allowed: ÎÎ­ÎµÏ‚ ÎºÎ±Ï„Î±ÏƒÏ„Î¬ÏƒÎµÎ¹Ï‚ ÎµÏ€Î¹Ï„ÏÎ­Ï€Î¿Î½Ï„Î±Î¹
+  label_all: ÏŒÎ»Î±
+  label_none: ÎºÎ±Î½Î­Î½Î±
+  label_nobody: ÎºÎ±Î½ÎµÎ¯Ï‚
+  label_next: Î•Ï€ÏŒÎ¼ÎµÎ½Î¿
+  label_previous: Î ÏÎ¿Î·Î³Î¿ÏÎ¼ÎµÎ½Î¿
+  label_used_by: Î§ÏÎ·ÏƒÎ¹Î¼Î¿Ï€Î¿Î¹Î®Î¸Î·ÎºÎµ Î±Ï€ÏŒ
+  label_details: Î›ÎµÏ€Ï„Î¿Î¼Î­ÏÎµÎ¹ÎµÏ‚
+  label_add_note: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· ÏƒÎ·Î¼ÎµÎ¯Ï‰ÏƒÎ·Ï‚
+  label_per_page: Î‘Î½Î¬ ÏƒÎµÎ»Î¯Î´Î±
+  label_calendar: Î—Î¼ÎµÏÎ¿Î»ÏŒÎ³Î¹Î¿
+  label_months_from: Î¼Î·Î½ÏŽÎ½ Î±Ï€ÏŒ
+  label_gantt: Gantt
+  label_internal: Î•ÏƒÏ‰Ï„ÎµÏÎ¹ÎºÏŒ
+  label_last_changes: "Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯ÎµÏ‚ %{count} Î±Î»Î»Î±Î³Î­Ï‚"
+  label_change_view_all: Î ÏÎ¿Î²Î¿Î»Î® ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î±Î»Î»Î±Î³ÏŽÎ½
+  label_personalize_page: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿Î³Î® ÏƒÎµÎ»Î¯Î´Î±Ï‚
+  label_comment: Î£Ï‡ÏŒÎ»Î¹Î¿
+  label_comment_plural: Î£Ï‡ÏŒÎ»Î¹Î±
+  label_x_comments:
+    zero: Î´ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ ÏƒÏ‡ÏŒÎ»Î¹Î±
+    one: 1 ÏƒÏ‡ÏŒÎ»Î¹Î¿
+    other: "%{count} ÏƒÏ‡ÏŒÎ»Î¹Î±"
+  label_comment_add: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· ÏƒÏ‡Î¿Î»Î¯Î¿Ï…
+  label_comment_added: Î¤Î± ÏƒÏ‡ÏŒÎ»Î¹Î± Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎ±Î½
+  label_comment_delete: Î”Î¹Î±Î³ÏÎ±Ï†Î® ÏƒÏ‡Î¿Î»Î¯Ï‰Î½
+  label_query: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½Î· Î±Î½Î±Î¶Î®Ï„Î·ÏƒÎ·
+  label_query_plural: Î ÏÎ¿ÏƒÎ±ÏÎ¼Î¿ÏƒÎ¼Î­Î½ÎµÏ‚ Î±Î½Î±Î¶Î·Ï„Î®ÏƒÎµÎ¹Ï‚
+  label_query_new: ÎÎ­Î± Î±Î½Î±Î¶Î®Ï„Î·ÏƒÎ·
+  label_filter_add: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Ï†Î¯Î»Ï„ÏÎ¿Ï…
+  label_filter_plural: Î¦Î¯Î»Ï„ÏÎ±
+  label_equals: ÎµÎ¯Î½Î±Î¹
+  label_not_equals: Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹
+  label_in_less_than: Î¼Î¹ÎºÏÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ
+  label_in_more_than: Ï€ÎµÏÎ¹ÏƒÏƒÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: ÏƒÎµ
+  label_today: ÏƒÎ®Î¼ÎµÏÎ±
+  label_all_time: ÏƒÏ…Î½Î­Ï‡ÎµÎ¹Î±
+  label_yesterday: Ï‡Î¸ÎµÏ‚
+  label_this_week: Î±Ï…Ï„Î® Ï„Î·Î½ ÎµÎ²Î´Î¿Î¼Î¬Î´Î±
+  label_last_week: Ï„Î·Î½ Ï€ÏÎ¿Î·Î³Î¿ÏÎ¼ÎµÎ½Î· ÎµÎ²Î´Î¿Î¼Î¬Î´Î±
+  label_last_n_days: "Ï„ÎµÎ»ÎµÏ…Ï„Î±Î¯ÎµÏ‚ %{count} Î¼Î­ÏÎµÏ‚"
+  label_this_month: Î±Ï…Ï„ÏŒ Ï„Î¿ Î¼Î®Î½Î±
+  label_last_month: Ï„Î¿Î½ Ï€ÏÎ¿Î·Î³Î¿ÏÎ¼ÎµÎ½Î¿ Î¼Î®Î½Î±
+  label_this_year: Î±Ï…Ï„ÏŒ Ï„Î¿ Ï‡ÏÏŒÎ½Î¿
+  label_date_range: Î§ÏÎ¿Î½Î¹ÎºÏŒ Î´Î¹Î¬ÏƒÏ„Î·Î¼Î±
+  label_less_than_ago: ÏƒÎµ Î»Î¹Î³ÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î·Î¼Î­ÏÎµÏ‚ Ï€ÏÎ¹Î½
+  label_more_than_ago: ÏƒÎµ Ï€ÎµÏÎ¹ÏƒÏƒÏŒÏ„ÎµÏÎ¿ Î±Ï€ÏŒ Î·Î¼Î­ÏÎµÏ‚ Ï€ÏÎ¹Î½
+  label_ago: Î·Î¼Î­ÏÎµÏ‚ Ï€ÏÎ¹Î½
+  label_contains: Ï€ÎµÏÎ¹Î­Ï‡ÎµÎ¹
+  label_not_contains: Î´ÎµÎ½ Ï€ÎµÏÎ¹Î­Ï‡ÎµÎ¹
+  label_day_plural: Î¼Î­ÏÎµÏ‚
+  label_repository: Î‘Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î¿
+  label_repository_plural: Î‘Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î±
+  label_browse: Î Î»Î¿Î®Î³Î·ÏƒÎ·
+  label_branch: Branch
+  label_tag: Tag
+  label_revision: Î‘Î½Î±Î¸ÎµÏŽÏÎ·ÏƒÎ·
+  label_revision_plural: Î‘Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÎ¹Ï‚
+  label_associated_revisions: Î£Ï…Î½ÎµÏ„Î±Î¹ÏÎ¹ÎºÎ­Ï‚ Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÎ¹Ï‚
+  label_added: Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
+  label_modified: Ï„ÏÎ¿Ï€Î¿Ï€Î¿Î¹Î®Î¸Î·ÎºÎµ
+  label_copied: Î±Î½Ï„Î¹Î³ÏÎ¬Ï†Î·ÎºÎµ
+  label_renamed: Î¼ÎµÏ„Î¿Î½Î¿Î¼Î¬ÏƒÏ„Î·ÎºÎµ
+  label_deleted: Î´Î¹Î±Î³ÏÎ¬Ï†Î·ÎºÎµ
+  label_latest_revision: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î± Î±Î½Î±Î¸ÎµÏŽÏÎ¹ÏƒÎ·
+  label_latest_revision_plural: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯ÎµÏ‚ Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÎ¹Ï‚
+  label_view_revisions: Î ÏÎ¿Î²Î¿Î»Î® Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÏ‰Î½
+  label_view_all_revisions: Î ÏÎ¿Î²Î¿Î»Î® ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î±Î½Î±Î¸ÎµÏ‰ÏÎ®ÏƒÎµÏ‰Î½
+  label_max_size: ÎœÎ­Î³Î¹ÏƒÏ„Î¿ Î¼Î­Î³ÎµÎ¸Î¿Ï‚
+  label_sort_highest: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ· ÏƒÏ„Î·Î½ ÎºÎ¿ÏÏ…Ï†Î®
+  label_sort_higher: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ· Ï€ÏÎ¿Ï‚ Ï„Î± Ï€Î¬Î½Ï‰
+  label_sort_lower: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ· Ï€ÏÎ¿Ï‚ Ï„Î± ÎºÎ¬Ï„Ï‰
+  label_sort_lowest: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ· ÏƒÏ„Î¿ ÎºÎ±Ï„ÏŽÏ„Î±Ï„Î¿ Î¼Î­ÏÎ¿Ï‚
+  label_roadmap: Î§Î¬ÏÏ„Î·Ï‚ Ï€Î¿ÏÎµÎ¯Î±Ï‚
+  label_roadmap_due_in: "Î ÏÎ¿Î¸ÎµÏƒÎ¼Î¯Î± ÏƒÎµ %{value}"
+  label_roadmap_overdue: "%{value} ÎºÎ±Î¸Ï…ÏƒÏ„ÎµÏÎ·Î¼Î­Î½Î¿"
+  label_roadmap_no_issues: Î”ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ Î¸Î­Î¼Î±Ï„Î± Î³Î¹Î± Î±Ï…Ï„Î® Ï„Î·Î½ Î­ÎºÎ´Î¿ÏƒÎ·
+  label_search: Î‘Î½Î±Î¶Î®Ï„Î·ÏƒÎ·
+  label_result_plural: Î‘Ï€Î¿Ï„ÎµÎ»Î­ÏƒÎ¼Î±Ï„Î±
+  label_all_words:  ÎŒÎ»ÎµÏ‚ Î¿Î¹ Î»Î­Î¾ÎµÎ¹Ï‚
+  label_wiki: Wiki
+  label_wiki_edit: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± wiki
+  label_wiki_edit_plural: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± wiki
+  label_wiki_page: Î£ÎµÎ»Î¯Î´Î± Wiki
+  label_wiki_page_plural: Î£ÎµÎ»Î¯Î´ÎµÏ‚ Wiki
+  label_index_by_title: Î”ÎµÎ¯ÎºÏ„Î·Ï‚ Î±Î½Î¬ Ï„Î¯Ï„Î»Î¿
+  label_index_by_date: Î”ÎµÎ¯ÎºÏ„Î·Ï‚ Î±Î½Î¬ Î·Î¼ÎµÏÎ¿Î¼Î·Î½Î¯Î±
+  label_current_version: Î¤ÏÎ­Ï‡Î¿Ï…ÏƒÎ± Î­ÎºÎ´Î¿ÏƒÎ·
+  label_preview: Î ÏÎ¿ÎµÏ€Î¹ÏƒÎºÏŒÏ€Î·ÏƒÎ·
+  label_feed_plural: Feeds
+  label_changes_details: Î›ÎµÏ€Ï„Î¿Î¼Î­ÏÎµÎ¹ÎµÏ‚ ÏŒÎ»Ï‰Î½ Ï„Ï‰Î½ Î±Î»Î»Î±Î³ÏŽÎ½
+  label_issue_tracking: Î‘Î½Î¯Ï‡Î½ÎµÏ…ÏƒÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  label_spent_time: Î”Î±Ï€Î±Î½Î·Î¼Î­Î½Î¿Ï‚ Ï‡ÏÏŒÎ½Î¿Ï‚
+  label_f_hour: "%{value} ÏŽÏÎ±"
+  label_f_hour_plural: "%{value} ÏŽÏÎµÏ‚"
+  label_time_tracking: Î‘Î½Î¯Ï‡Î½ÎµÏ…ÏƒÎ· Ï‡ÏÏŒÎ½Î¿Ï…
+  label_change_plural: Î‘Î»Î»Î±Î³Î­Ï‚
+  label_statistics: Î£Ï„Î±Ï„Î¹ÏƒÏ„Î¹ÎºÎ¬
+  label_commits_per_month: Commits Î±Î½Î¬ Î¼Î®Î½Î±
+  label_commits_per_author: Commits Î±Î½Î¬ ÏƒÏ…Î³Î³ÏÎ±Ï†Î­Î±
+  label_view_diff: Î ÏÎ¿Î²Î¿Î»Î® Î´Î¹Î±Ï†Î¿ÏÏŽÎ½
+  label_diff_inline: ÏƒÎµ ÏƒÎµÎ¹ÏÎ¬
+  label_diff_side_by_side: Î±Î½Ï„Î¹ÎºÏÏ…ÏƒÏ„Î¬
+  label_options: Î•Ï€Î¹Î»Î¿Î³Î­Ï‚
+  label_copy_workflow_from: Î‘Î½Ï„Î¹Î³ÏÎ±Ï†Î® ÏÎ¿Î®Ï‚ ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚ Î±Ï€ÏŒ
+  label_permissions_report: Î£Ï…Î½Î¿Ï€Ï„Î¹ÎºÏŒÏ‚ Ï€Î¯Î½Î±ÎºÎ±Ï‚ Î±Î´ÎµÎ¹ÏŽÎ½
+  label_watched_issues: Î˜Î­Î¼Î±Ï„Î± Ï…Ï€ÏŒ Ï€Î±ÏÎ±ÎºÎ¿Î»Î¿ÏÎ¸Î·ÏƒÎ·
+  label_related_issues: Î£Ï‡ÎµÏ„Î¹ÎºÎ¬ Î¸Î­Î¼Î±Ï„Î±
+  label_applied_status: Î•Ï†Î±ÏÎ¼Î¿Î³Î® ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·Ï‚
+  label_loading: Î¦Î¿ÏÏ„ÏŽÎ½ÎµÏ„Î±Î¹...
+  label_relation_new: ÎÎ­Î± ÏƒÏ…ÏƒÏ‡Î­Ï„Î¹ÏƒÎ·
+  label_relation_delete: Î”Î¹Î±Î³ÏÎ±Ï†Î® ÏƒÏ…ÏƒÏ‡Î­Ï„Î¹ÏƒÎ·Ï‚
+  label_relates_to: ÏƒÏ‡ÎµÏ„Î¹ÎºÏŒ Î¼Îµ
+  label_duplicates: Î±Î½Ï„Î¯Î³ÏÎ±Ï†Î±
+  label_duplicated_by: Î±Î½Ï„Î¹Î³ÏÎ¬Ï†Î·ÎºÎµ Î±Ï€ÏŒ
+  label_blocks: Ï†ÏÎ±Î³Î­Ï‚
+  label_blocked_by: Ï†ÏÎ±Î³Î® Î±Ï€ÏŒ Ï„Î¿Î½
+  label_precedes: Ï€ÏÎ¿Î·Î³ÎµÎ¯Ï„Î±Î¹
+  label_follows: Î±ÎºÎ¿Î»Î¿Ï…Î¸ÎµÎ¯
+  label_end_to_start: Î±Ï€ÏŒ Ï„Î¿ Ï„Î­Î»Î¿Ï‚ ÏƒÏ„Î·Î½ Î±ÏÏ‡Î®
+  label_end_to_end: Î±Ï€ÏŒ Ï„Î¿ Ï„Î­Î»Î¿Ï‚ ÏƒÏ„Î¿ Ï„Î­Î»Î¿Ï‚
+  label_start_to_start: Î±Ï€ÏŒ Ï„Î·Î½ Î±ÏÏ‡Î® ÏƒÏ„Î·Î½ Î±ÏÏ‡Î®
+  label_start_to_end: Î±Ï€ÏŒ Ï„Î·Î½ Î±ÏÏ‡Î® ÏƒÏ„Î¿ Ï„Î­Î»Î¿Ï‚
+  label_stay_logged_in: Î Î±ÏÎ±Î¼Î¿Î½Î® ÏƒÏÎ½Î´ÎµÏƒÎ·Ï‚
+  label_disabled: Î±Ï€ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î·Î¼Î­Î½Î·
+  label_show_completed_versions: Î ÏÎ¿Î²Î¿Î»Î® Î¿Î»Î¿ÎºÎ»Î·ÏÏ‰Î¼Î­Î½Ï‰Î½ ÎµÎºÎ´ÏŒÏƒÎµÏ‰Î½
+  label_me: ÎµÎ³ÏŽ
+  label_board: Î¦ÏŒÏÎ¿Ï…Î¼
+  label_board_new: ÎÎ­Î¿ Ï†ÏŒÏÎ¿Ï…Î¼
+  label_board_plural: Î¦ÏŒÏÎ¿Ï…Î¼
+  label_topic_plural: Î˜Î­Î¼Î±Ï„Î±
+  label_message_plural: ÎœÎ·Î½ÏÎ¼Î±Ï„Î±
+  label_message_last: Î¤ÎµÎ»ÎµÏ…Ï„Î±Î¯Î¿ Î¼Î®Î½Ï…Î¼Î±
+  label_message_new: ÎÎ­Î¿ Î¼Î®Î½Ï…Î¼Î±
+  label_message_posted: Î¤Î¿ Î¼Î®Î½Ï…Î¼Î± Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
+  label_reply_plural: Î‘Ï€Î±Î½Ï„Î®ÏƒÎµÎ¹Ï‚
+  label_send_information: Î‘Ï€Î¿ÏƒÏ„Î¿Î»Î® Ï€Î»Î·ÏÎ¿Ï†Î¿ÏÎ¹ÏŽÎ½ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÏ„Î¿ Ï‡ÏÎ®ÏƒÏ„Î·
+  label_year: ÎˆÏ„Î¿Ï‚
+  label_month: ÎœÎ®Î½Î±Ï‚
+  label_week: Î•Î²Î´Î¿Î¼Î¬Î´Î±
+  label_date_from: Î‘Ï€ÏŒ
+  label_date_to:  ÎˆÏ‰Ï‚
+  label_language_based: ÎœÎµ Î²Î¬ÏƒÎ· Ï„Î· Î³Î»ÏŽÏƒÏƒÎ± Ï„Î¿Ï… Ï‡ÏÎ®ÏƒÏ„Î·
+  label_sort_by: "Î¤Î±Î¾Î¹Î½ÏŒÎ¼Î·ÏƒÎ· Î±Î½Î¬ %{value}"
+  label_send_test_email: Î‘Ï€Î¿ÏƒÏ„Î¿Î»Î® Î´Î¿ÎºÎ¹Î¼Î±ÏƒÏ„Î¹ÎºÎ¿Ï email
+  label_feeds_access_key_created_on: "Ï„Î¿ ÎºÎ»ÎµÎ¹Î´Î¯ Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚ RSS Î´Î·Î¼Î¹Î¿Ï…ÏÎ³Î®Î¸Î·ÎºÎµ Ï€ÏÎ¹Î½ Î±Ï€ÏŒ %{value}"
+  label_module_plural: ÎœÎ¿Î½Î¬Î´ÎµÏ‚
+  label_added_time_by: "Î ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author} Ï€ÏÎ¹Î½ Î±Ï€ÏŒ %{age}"
+  label_updated_time_by: "Î•Î½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author} Ï€ÏÎ¹Î½ Î±Ï€ÏŒ %{age}"
+  label_updated_time: "Î•Î½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Ï€ÏÎ¹Î½ Î±Ï€ÏŒ %{value}"
+  label_jump_to_a_project: ÎœÎµÏ„Î±Î²ÎµÎ¯Ï„Îµ ÏƒÎµ Î­Î½Î± Î­ÏÎ³Î¿...
+  label_file_plural: Î‘ÏÏ‡ÎµÎ¯Î±
+  label_changeset_plural: Changesets
+  label_default_columns: Î ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½ÎµÏ‚ ÏƒÏ„Î®Î»ÎµÏ‚
+  label_no_change_option: (Î”ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ Î±Î»Î»Î±Î³Î­Ï‚)
+  label_bulk_edit_selected_issues: ÎœÎ±Î¶Î¹ÎºÎ® ÎµÏ€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Ï‰Î½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½
+  label_theme: Î˜Î­Î¼Î±
+  label_default: Î ÏÎ¿ÎµÏ€Î¹Î»Î¿Î³Î®
+  label_search_titles_only: Î‘Î½Î±Î¶Î®Ï„Î·ÏƒÎ· Ï„Î¯Ï„Î»Ï‰Î½ Î¼ÏŒÎ½Î¿
+  label_user_mail_option_all: "Î“Î¹Î± ÏŒÎ»ÎµÏ‚ Ï„Î¹Ï‚ ÎµÎ¾ÎµÎ»Î¯Î¾ÎµÎ¹Ï‚ ÏƒÎµ ÏŒÎ»Î± Ï„Î± Î­ÏÎ³Î± Î¼Î¿Ï…"
+  label_user_mail_option_selected: "Î“Î¹Î± ÏŒÎ»ÎµÏ‚ Ï„Î¹Ï‚ ÎµÎ¾ÎµÎ»Î¯Î¾ÎµÎ¹Ï‚ Î¼ÏŒÎ½Î¿ ÏƒÏ„Î± ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î± Î­ÏÎ³Î±..."
+  label_user_mail_no_self_notified: "Î”ÎµÎ½ Î¸Î­Î»Ï‰ Î½Î± ÎµÎ¹Î´Î¿Ï€Î¿Î¹Î¿ÏÎ¼Î±Î¹ Î³Î¹Î± Ï„Î¹Ï‚ Î´Î¹ÎºÎ­Ï‚ Î¼Î¿Ï… Î±Î»Î»Î±Î³Î­Ï‚"
+  label_registration_activation_by_email: ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï Î¼Îµ email
+  label_registration_manual_activation: Ï‡ÎµÎ¹ÏÎ¿ÎºÎ¯Î½Î·Ï„Î· ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï
+  label_registration_automatic_activation: Î±Ï…Ï„ÏŒÎ¼Î±Ï„Î· ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ· Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼Î¿Ï
+  label_display_per_page: "Î‘Î½Î¬ ÏƒÎµÎ»Î¯Î´Î±: %{value}"
+  label_age: Î—Î»Î¹ÎºÎ¯Î±
+  label_change_properties: Î‘Î»Î»Î±Î³Î® Î¹Î´Î¹Î¿Ï„Î®Ï„Ï‰Î½
+  label_general: Î“ÎµÎ½Î¹ÎºÎ¬
+  label_more: Î ÎµÏÎ¹ÏƒÏƒÏŒÏ„ÎµÏÎ±
+  label_scm: SCM
+  label_plugins: Plugins
+  label_ldap_authentication: Î Î¹ÏƒÏ„Î¿Ï€Î¿Î¯Î·ÏƒÎ· LDAP
+  label_downloads_abbr: Îœ/Î¦
+  label_optional_description: Î ÏÎ¿Î±Î¹ÏÎµÏ„Î¹ÎºÎ® Ï€ÎµÏÎ¹Î³ÏÎ±Ï†Î®
+  label_add_another_file: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ· Î¬Î»Î»Î¿Ï… Î±ÏÏ‡ÎµÎ¯Î¿Ï…
+  label_preferences: Î ÏÎ¿Ï„Î¹Î¼Î®ÏƒÎµÎ¹Ï‚
+  label_chronological_order: ÎšÎ±Ï„Î¬ Ï‡ÏÎ¿Î½Î¿Î»Î¿Î³Î¹ÎºÎ® ÏƒÎµÎ¹ÏÎ¬
+  label_reverse_chronological_order: ÎšÎ±Ï„Î¬ Î±Î½Ï„Î¯ÏƒÏ„ÏÎ¿Ï†Î· Ï‡ÏÎ¿Î½Î¿Î»Î¿Î³Î¹ÎºÎ® ÏƒÎµÎ¹ÏÎ¬
+  label_planning: Î£Ï‡ÎµÎ´Î¹Î±ÏƒÎ¼ÏŒÏ‚
+  label_incoming_emails: Î•Î¹ÏƒÎµÏÏ‡ÏŒÎ¼ÎµÎ½Î± email
+  label_generate_key: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï
+  label_issue_watchers: Î Î±ÏÎ±Ï„Î·ÏÎ·Ï„Î­Ï‚
+  label_example: Î Î±ÏÎ¬Î´ÎµÎ¹Î³Î¼Î±
+  label_display: Î ÏÎ¿Î²Î¿Î»Î®
+  label_sort: Î¤Î±Î¾Î¹Î½ÏŒÎ¼Î·ÏƒÎ·
+  label_ascending: Î‘ÏÎ¾Î¿Ï…ÏƒÎ±
+  label_descending: Î¦Î¸Î¯Î½Î¿Ï…ÏƒÎ±
+  label_date_from_to: Î‘Ï€ÏŒ %{start} Î­Ï‰Ï‚ %{end}
+  label_wiki_content_added: Î— ÏƒÎµÎ»Î¯Î´Î± Wiki Ï€ÏÎ¿ÏƒÏ„Î­Î¸Î·ÎºÎµ
+  label_wiki_content_updated: Î— ÏƒÎµÎ»Î¯Î´Î± Wiki ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ
+
+  button_login: Î£ÏÎ½Î´ÎµÏƒÎ·
+  button_submit: Î‘Ï€Î¿ÏƒÏ„Î¿Î»Î®
+  button_save: Î‘Ï€Î¿Î¸Î®ÎºÎµÏ…ÏƒÎ·
+  button_check_all: Î•Ï€Î¹Î»Î¿Î³Î® ÏŒÎ»Ï‰Î½
+  button_uncheck_all: Î‘Ï€Î¿ÎµÏ€Î¹Î»Î¿Î³Î® ÏŒÎ»Ï‰Î½
+  button_delete: Î”Î¹Î±Î³ÏÎ±Ï†Î®
+  button_create: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î±
+  button_create_and_continue: Î”Î·Î¼Î¹Î¿Ï…ÏÎ³Î¯Î± ÎºÎ±Î¹ ÏƒÏ…Î½Î­Ï‡ÎµÎ¹Î±
+  button_test: Î¤ÎµÏƒÏ„
+  button_edit: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î±
+  button_add: Î ÏÎ¿ÏƒÎ¸Î®ÎºÎ·
+  button_change: Î‘Î»Î»Î±Î³Î®
+  button_apply: Î•Ï†Î±ÏÎ¼Î¿Î³Î®
+  button_clear: ÎšÎ±Î¸Î±ÏÎ¹ÏƒÎ¼ÏŒÏ‚
+  button_lock: ÎšÎ»ÎµÎ¯Î´Ï‰Î¼Î±
+  button_unlock: ÎžÎµÎºÎ»ÎµÎ¯Î´Ï‰Î¼Î±
+  button_download: ÎœÎµÏ„Î±Ï†ÏŒÏÏ„Ï‰ÏƒÎ·
+  button_list: Î›Î¯ÏƒÏ„Î±
+  button_view: Î ÏÎ¿Î²Î¿Î»Î®
+  button_move: ÎœÎµÏ„Î±ÎºÎ¯Î½Î·ÏƒÎ·
+  button_back: Î Î¯ÏƒÏ‰
+  button_cancel: Î‘ÎºÏÏÏ‰ÏƒÎ·
+  button_activate: Î•Î½ÎµÏÎ³Î¿Ï€Î¿Î¯Î·ÏƒÎ·
+  button_sort: Î¤Î±Î¾Î¹Î½ÏŒÎ¼Î·ÏƒÎ·
+  button_log_time: Î™ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ Ï‡ÏÏŒÎ½Î¿Ï…
+  button_rollback: Î•Ï€Î±Î½Î±Ï†Î¿ÏÎ¬ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î·Î½ Î­ÎºÎ´Î¿ÏƒÎ·
+  button_watch: Î Î±ÏÎ±ÎºÎ¿Î»Î¿ÏÎ¸Î·ÏƒÎ·
+  button_unwatch: Î‘Î½Î±Î¯ÏÎµÏƒÎ· Ï€Î±ÏÎ±ÎºÎ¿Î»Î¿ÏÎ¸Î·ÏƒÎ·Ï‚
+  button_reply: Î‘Ï€Î¬Î½Ï„Î·ÏƒÎ·
+  button_archive: Î‘ÏÏ‡ÎµÎ¹Î¿Î¸Î­Ï„Î·ÏƒÎ·
+  button_unarchive: Î‘Î½Î±Î¯ÏÎµÏƒÎ· Î±ÏÏ‡ÎµÎ¹Î¿Î¸Î­Ï„Î·ÏƒÎ·Ï‚
+  button_reset: Î•Ï€Î±Î½Î±Ï†Î¿ÏÎ¬
+  button_rename: ÎœÎµÏ„Î¿Î½Î¿Î¼Î±ÏƒÎ¯Î±
+  button_change_password: Î‘Î»Î»Î±Î³Î® ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï€ÏÏŒÏƒÎ²Î±ÏƒÎ·Ï‚
+  button_copy: Î‘Î½Ï„Î¹Î³ÏÎ±Ï†Î®
+  button_annotate: Î£Ï‡Î¿Î»Î¹Î±ÏƒÎ¼ÏŒÏ‚
+  button_update: Î•Î½Î·Î¼Î­ÏÏ‰ÏƒÎ·
+  button_configure: Î¡ÏÎ¸Î¼Î¹ÏƒÎ·
+  button_quote: Î Î±ÏÎ¬Î¸ÎµÏƒÎ·
+
+  status_active: ÎµÎ½ÎµÏÎ³ÏŒ(Ï‚)/Î®
+  status_registered: ÎµÎ³ÎµÎ³Î³ÏÎ±Î¼Î¼Î­Î½Î¿(Ï‚)/Î·
+  status_locked: ÎºÎ»ÎµÎ¹Î´Ï‰Î¼Î­Î½Î¿(Ï‚)/Î·
+
+  text_select_mail_notifications: Î•Ï€Î¹Î»Î¿Î³Î® ÎµÎ½ÎµÏÎ³ÎµÎ¹ÏŽÎ½ Î³Î¹Î± Ï„Î¹Ï‚ Î¿Ï€Î¿Î¯ÎµÏ‚ Î¸Î± Ï€ÏÎ­Ï€ÎµÎ¹ Î½Î± Î±Ï€Î¿ÏƒÏ„Î±Î»ÎµÎ¯ ÎµÎ¹Î´Î¿Ï€Î¿Î¯Î·ÏƒÎ· Î¼Îµ email.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 ÏƒÎ·Î¼Î±Î¯Î½ÎµÎ¹ ÏŒÏ„Î¹ Î´ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ Ï€ÎµÏÎ¹Î¿ÏÎ¹ÏƒÎ¼Î¿Î¯
+  text_project_destroy_confirmation: Î•Î¯ÏƒÏ„Îµ ÏƒÎ¯Î³Î¿Ï…ÏÎ¿Î¹ ÏŒÏ„Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± Î´Î¹Î±Î³ÏÎ¬ÏˆÎµÏ„Îµ Î±Ï…Ï„ÏŒ Ï„Î¿ Î­ÏÎ³Î¿ ÎºÎ±Î¹ Ï„Î± ÏƒÏ‡ÎµÏ„Î¹ÎºÎ¬ Î´ÎµÎ´Î¿Î¼Î­Î½Î± Ï„Î¿Ï…;
+  text_subprojects_destroy_warning: "Î•Ï€Î¯ÏƒÎ·Ï‚ Ï„Î¿(Î±) ÎµÏ€Î¹Î¼Î­ÏÎ¿Ï…Ï‚ Î­ÏÎ³Î¿(Î±): %{value}  Î¸Î± Î´Î¹Î±Î³ÏÎ±Ï†Î¿ÏÎ½."
+  text_workflow_edit: Î•Ï€Î¹Î»Î­Î¾Ï„Îµ Î­Î½Î± ÏÏŒÎ»Î¿ ÎºÎ±Î¹ Î­Î½Î±Î½ Î±Î½Î¹Ï‡Î½ÎµÏ…Ï„Î® Î³Î¹Î± Î½Î± ÎµÏ€ÎµÎ¾ÎµÏÎ³Î±ÏƒÏ„ÎµÎ¯Ï„Îµ  Ï„Î· ÏÎ¿Î® ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚
+  text_are_you_sure: Î•Î¯ÏƒÏ„Îµ ÏƒÎ¯Î³Î¿Ï…ÏÎ¿Ï‚ ;
+  text_tip_issue_begin_day: ÎºÎ±Î¸Î®ÎºÎ¿Î½Ï„Î± Ï€Î¿Ï… Î¾ÎµÎºÎ¹Î½Î¬Î½Îµ ÏƒÎ®Î¼ÎµÏÎ±
+  text_tip_issue_end_day: ÎºÎ±Î¸Î®ÎºÎ¿Î½Ï„Î± Ï€Î¿Ï… Ï„ÎµÎ»ÎµÎ¹ÏŽÎ½Î¿Ï…Î½ ÏƒÎ®Î¼ÎµÏÎ±
+  text_tip_issue_begin_end_day: ÎºÎ±Î¸Î®ÎºÎ¿Î½Ï„Î± Ï€Î¿Ï… Î¾ÎµÎºÎ¹Î½Î¬Î½Îµ ÎºÎ±Î¹ Ï„ÎµÎ»ÎµÎ¹ÏŽÎ½Î¿Ï…Î½ ÏƒÎ®Î¼ÎµÏÎ±
+  text_caracters_maximum: "Î¼Î­Î³Î¹ÏƒÏ„Î¿Ï‚ Î±ÏÎ¹Î¸Î¼ÏŒÏ‚ %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚."
+  text_caracters_minimum: "Î ÏÎ­Ï€ÎµÎ¹ Î½Î± Ï€ÎµÏÎ¹Î­Ï‡ÎµÎ¹ Ï„Î¿Ï…Î»Î¬Ï‡Î¹ÏƒÏ„Î¿Î½ %{count} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚."
+  text_length_between: "ÎœÎ®ÎºÎ¿Ï‚ Î¼ÎµÏ„Î±Î¾Ï %{min} ÎºÎ±Î¹ %{max} Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚."
+  text_tracker_no_workflow: Î”ÎµÎ½ Î­Ï‡ÎµÎ¹ Î¿ÏÎ¹ÏƒÏ„ÎµÎ¯ ÏÎ¿Î® ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚ Î³Î¹Î± Î±Ï…Ï„ÏŒ Ï„Î¿Î½ Î±Î½Î¹Ï‡Î½ÎµÏ…Ï„Î®
+  text_unallowed_characters: ÎœÎ· ÎµÏ€Î¹Ï„ÏÎµÏ€ÏŒÎ¼ÎµÎ½Î¿Î¹ Ï‡Î±ÏÎ±ÎºÏ„Î®ÏÎµÏ‚
+  text_comma_separated: Î•Ï€Î¹Ï„ÏÎ­Ï€Î¿Î½Ï„Î±Î¹ Ï€Î¿Î»Î»Î±Ï€Î»Î­Ï‚ Ï„Î¹Î¼Î­Ï‚ (Ï‡Ï‰ÏÎ¹ÏƒÎ¼Î­Î½ÎµÏ‚ Î¼Îµ ÎºÏŒÎ¼Î¼Î±).
+  text_issues_ref_in_commit_messages: Î‘Î½Î±Ï†Î¿ÏÎ¬ ÎºÎ±Î¹ ÎºÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼ÏŒÏ‚ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÏƒÎµ Î¼Î·Î½ÏÎ¼Î±Ï„Î± commit
+  text_issue_added: "Î¤Î¿ Î¸Î­Î¼Î± %{id} Ï€Î±ÏÎ¿Ï…ÏƒÎ¹Î¬ÏƒÏ„Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author}."
+  text_issue_updated: "Î¤Î¿ Î¸Î­Î¼Î± %{id} ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author}."
+  text_wiki_destroy_confirmation: Î•Î¯ÏƒÏ„Îµ ÏƒÎ¯Î³Î¿Ï…ÏÎ¿Î¹ ÏŒÏ„Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± Î´Î¹Î±Î³ÏÎ¬ÏˆÎµÏ„Îµ Î±Ï…Ï„ÏŒ Ï„Î¿ wiki ÎºÎ±Î¹ ÏŒÎ»Î¿ Ï„Î¿ Ï€ÎµÏÎ¹ÎµÏ‡ÏŒÎ¼ÎµÎ½Î¿ Ï„Î¿Ï… ;
+  text_issue_category_destroy_question: "ÎšÎ¬Ï€Î¿Î¹Î± Î¸Î­Î¼Î±Ï„Î± (%{count}) Î­Ï‡Î¿Ï…Î½ ÎµÎºÏ‡Ï‰ÏÎ·Î¸ÎµÎ¯ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î·Î½ ÎºÎ±Ï„Î·Î³Î¿ÏÎ¯Î±. Î¤Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± ÎºÎ¬Î½ÎµÏ„Îµ ;"
+  text_issue_category_destroy_assignments: Î‘Ï†Î±Î¯ÏÎµÏƒÎ· ÎµÎºÏ‡Ï‰ÏÎ®ÏƒÎµÏ‰Î½ ÎºÎ±Ï„Î·Î³Î¿ÏÎ¯Î±Ï‚
+  text_issue_category_reassign_to: Î•Ï€Î±Î½ÎµÎºÏ‡ÏŽÏÎ·ÏƒÎ· Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î·Î½ ÎºÎ±Ï„Î·Î³Î¿ÏÎ¯Î±
+  text_user_mail_option: "Î“Î¹Î± Î¼Î· ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î± Î­ÏÎ³Î±, Î¸Î± Î»Î¬Î²ÎµÏ„Îµ ÎµÎ¹Î´Î¿Ï€Î¿Î¹Î®ÏƒÎµÎ¹Ï‚ Î¼ÏŒÎ½Î¿ Î³Î¹Î± Ï€ÏÎ¬Î³Î¼Î±Ï„Î± Ï€Î¿Ï… Ï€Î±ÏÎ±ÎºÎ¿Î»Î¿Ï…Î¸ÎµÎ¯Ï„Îµ Î® ÏƒÏ„Î± Î¿Ï€Î¿Î¯Î± ÏƒÏ…Î¼Î¼ÎµÏ„Î­Ï‡Ï‰ ÎµÎ½ÎµÏÎ³Î¬ (Ï€.Ï‡. Î¸Î­Î¼Î±Ï„Î± Ï„Ï‰Î½ Î¿Ï€Î¿Î¯Ï‰Î½ ÎµÎ¯ÏƒÏ„Îµ ÏƒÏ…Î³Î³ÏÎ±Ï†Î­Î±Ï‚ Î® ÏƒÎ±Ï‚ Î­Ï‡Î¿Ï…Î½ Î±Î½Î±Ï„ÎµÎ¸ÎµÎ¯)."
+  text_no_configuration_data: "ÎŸÎ¹ ÏÏŒÎ»Î¿Î¹, Î¿Î¹ Î±Î½Î¹Ï‡Î½ÎµÏ…Ï„Î­Ï‚, Î· ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ· Ï„Ï‰Î½ Î¸ÎµÎ¼Î¬Ï„Ï‰Î½ ÎºÎ±Î¹ Î· ÏÎ¿Î® ÎµÏÎ³Î±ÏƒÎ¯Î±Ï‚ Î´ÎµÎ½ Î­Ï‡Î¿Ï…Î½ ÏÏ…Î¸Î¼Î¹ÏƒÏ„ÎµÎ¯ Î±ÎºÏŒÎ¼Î±.\nÎ£Ï…Î½Î¹ÏƒÏ„Î¬Ï„Î±Î¹ Î¹Î´Î¹Î±Î¯Ï„ÎµÏÎ± Î½Î± Ï†Î¿ÏÏ„ÏŽÏƒÎµÏ„Îµ Ï„Î¹Ï‚ Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½ÎµÏ‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚. Î˜Î± ÎµÎ¯ÏƒÏ„Îµ ÏƒÎµ Î¸Î­ÏƒÎ· Î½Î± Ï„Î¹Ï‚ Ï„ÏÎ¿Ï€Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Î¼ÎµÏ„Î¬ Ï„Î· Ï†ÏŒÏÏ„Ï‰ÏƒÎ· Ï„Î¿Ï…Ï‚."
+  text_load_default_configuration: Î¦ÏŒÏÏ„Ï‰ÏƒÎ· Ï€ÏÎ¿ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Ï‰Î½ ÏÏ…Î¸Î¼Î¯ÏƒÎµÏ‰Î½
+  text_status_changed_by_changeset: "Î•Ï†Î±ÏÎ¼ÏŒÏƒÏ„Î·ÎºÎµ ÏƒÏ„Î¿ changeset %{value}."
+  text_issues_destroy_confirmation: 'Î•Î¯ÏƒÏ„Îµ ÏƒÎ¯Î³Î¿Ï…ÏÎ¿Ï‚ ÏŒÏ„Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± Î´Î¹Î±Î³ÏÎ¬ÏˆÎµÏ„Îµ Ï„Î¿ ÎµÏ€Î¹Î»ÎµÎ³Î¼Î­Î½Î¿ Î¸Î­Î¼Î±(Ï„Î±);'
+  text_select_project_modules: 'Î•Ï€Î¹Î»Î­Î¾Ï„Îµ Ï€Î¿Î¹ÎµÏ‚ Î¼Î¿Î½Î¬Î´ÎµÏ‚ Î¸Î± ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î®ÏƒÎµÏ„Îµ Î³Î¹Î± Î±Ï…Ï„ÏŒ Ï„Î¿ Î­ÏÎ³Î¿:'
+  text_default_administrator_account_changed: ÎŸ Ï€ÏÎ¿ÎºÎ±Î¸Î¿ÏÎ¹ÏƒÎ¼Î­Î½Î¿Ï‚ Î»Î¿Î³Î±ÏÎ¹Î±ÏƒÎ¼ÏŒÏ‚ Ï„Î¿Ï… Î´Î¹Î±Ï‡ÎµÎ¹ÏÎ¹ÏƒÏ„Î® Î¬Î»Î»Î±Î¾Îµ
+  text_file_repository_writable: Î•Î³Î³ÏÎ¬ÏˆÎ¹Î¼Î¿Ï‚ ÎºÎ±Ï„Î¬Î»Î¿Î³Î¿Ï‚ ÏƒÏ…Î½Î·Î¼Î¼Î­Î½Ï‰Î½
+  text_plugin_assets_writable: Î•Î³Î³ÏÎ¬ÏˆÎ¹Î¼Î¿Ï‚ ÎºÎ±Ï„Î¬Î»Î¿Î³Î¿Ï‚ plugin assets
+  text_rmagick_available: Î”Î¹Î±Î¸Î­ÏƒÎ¹Î¼Î¿ RMagick (Ï€ÏÎ¿Î±Î¹ÏÎµÏ„Î¹ÎºÏŒ)
+  text_destroy_time_entries_question: "%{hours} Î´Î±Ï€Î±Î½Î®Î¸Î·ÎºÎ±Î½ ÏƒÏ‡ÎµÏ„Î¹ÎºÎ¬ Î¼Îµ Ï„Î± Î¸Î­Î¼Î±Ï„Î± Ï€Î¿Ï… Ï€ÏÏŒÎºÎµÎ¹Ï„Î±Î¹ Î½Î± Î´Î¹Î±Î³ÏÎ¬ÏˆÎµÏ„Îµ. Î¤Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± ÎºÎ¬Î½ÎµÏ„Îµ ;"
+  text_destroy_time_entries: Î”Î¹Î±Î³ÏÎ±Ï†Î® Î±Î½Î±Ï†ÎµÏÏŒÎ¼ÎµÎ½Ï‰Î½ Ï‰ÏÏŽÎ½
+  text_assign_time_entries_to_project: Î‘Î½Î¬Î¸ÎµÏƒÎ· Î±Î½Î±Ï†ÎµÏÏŒÎ¼ÎµÎ½Ï‰Î½ Ï‰ÏÏŽÎ½ ÏƒÏ„Î¿ Î­ÏÎ³Î¿
+  text_reassign_time_entries: 'Î‘Î½Î¬Î¸ÎµÏƒÎ· ÎµÎº Î½Î­Î¿Ï… Ï„Ï‰Î½ Î±Î½Î±Ï†ÎµÏÏŒÎ¼ÎµÎ½Ï‰Î½ Ï‰ÏÏŽÎ½ ÏƒÏ„Î¿ Î¸Î­Î¼Î±:'
+  text_user_wrote: "%{value} Î­Î³ÏÎ±ÏˆÎµ:"
+  text_enumeration_destroy_question: "%{count} Î±Î½Ï„Î¹ÎºÎµÎ¯Î¼ÎµÎ½Î± Î­Ï‡Î¿Ï…Î½ Ï„ÎµÎ¸ÎµÎ¯ ÏƒÎµ Î±Ï…Ï„Î® Ï„Î·Î½ Ï„Î¹Î¼Î®."
+  text_enumeration_category_reassign_to: 'Î•Ï€Î±Î½ÎµÎºÏ‡ÏŽÏÎ·ÏƒÎ· Ï„Î¿Ï…Ï‚ ÏƒÏ„Î·Î½ Ï€Î±ÏÎ¿ÏÏƒÎ± Î±Î¾Î¯Î±:'
+  text_email_delivery_not_configured: "Î”ÎµÎ½ Î­Ï‡Î¿Ï…Î½ Î³Î¯Î½ÎµÎ¹ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚ Ï€Î±ÏÎ¬Î´Î¿ÏƒÎ·Ï‚ email, ÎºÎ±Î¹ Î¿Î¹ ÎµÎ¹Î´Î¿Ï€Î¿Î¹Î®ÏƒÎµÎ¹Ï‚ ÎµÎ¯Î½Î±Î¹ Î±Ï€ÎµÎ½ÎµÏÎ³Î¿Ï€Î¿Î¹Î·Î¼Î­Î½ÎµÏ‚.\nÎ”Î·Î»ÏŽÏƒÏ„Îµ Ï„Î¿Î½ ÎµÎ¾Ï…Ï€Î·ÏÎµÏ„Î·Ï„Î® SMTP ÏƒÏ„Î¿ config/configuration.yml ÎºÎ±Î¹ ÎºÎ¬Î½Ï„Îµ ÎµÏ€Î±Î½Î±ÎºÎºÎ¯Î½Î·ÏƒÎ· Ï„Î·Î½ ÎµÏ†Î±ÏÎ¼Î¿Î³Î® Î³Î¹Î± Î½Î± Ï„Î¹Ï‚ ÏÏ…Î¸Î¼Î¯ÏƒÎµÎ¹Ï‚."
+  text_repository_usernames_mapping: "Î•Ï€Î¹Î»Î­Î¾Ï„Îµ Î® ÎµÎ½Î·Î¼ÎµÏÏŽÏƒÏ„Îµ Ï„Î¿Î½ Ï‡ÏÎ®ÏƒÏ„Î· Redmine Ï€Î¿Ï… Î±Î½Ï„Î¹ÏƒÏ„Î¿Î¹Ï‡ÎµÎ¯ ÏƒÎµ ÎºÎ¬Î¸Îµ ÏŒÎ½Î¿Î¼Î± Ï‡ÏÎ®ÏƒÏ„Î·  ÏƒÏ„Î¿ Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ Ï„Î¿Ï… Î±Ï€Î¿Î¸ÎµÏ„Î·ÏÎ¯Î¿Ï….\nÎ§ÏÎ®ÏƒÏ„ÎµÏ‚ Î¼Îµ Ï„Î¿ Î¯Î´Î¹Î¿ ÏŒÎ½Î¿Î¼Î± Ï‡ÏÎ®ÏƒÏ„Î· Î® email ÏƒÏ„Î¿ Redmine ÎºÎ±Î¹ ÏƒÏ„Î¿ Î±Ï€Î¿Î¸ÎµÏ„Î·ÏÎ¯Î¿ Î±Î½Ï„Î¹ÏƒÏ„Î¿Î¹Ï‡Î¯Î¶Î¿Î½Ï„Î±Î¹ Î±Ï…Ï„ÏŒÎ¼Î±Ï„Î±."
+  text_diff_truncated: '... Î‘Ï…Ï„ÏŒ Ï„Î¿ diff ÎµÏ‡ÎµÎ¯ ÎºÎ¿Ï€ÎµÎ¯ ÎµÏ€ÎµÎ¹Î´Î® Ï…Ï€ÎµÏÎ²Î±Î¯Î½ÎµÎ¹ Ï„Î¿ Î¼Î­Î³Î¹ÏƒÏ„Î¿ Î¼Î­Î³ÎµÎ¸Î¿Ï‚ Ï€Î¿Ï… Î¼Ï€Î¿ÏÎµÎ¯ Î½Î± Ï€ÏÎ¿Î²Î»Î·Î¸ÎµÎ¯.'
+  text_custom_field_possible_values_info: 'ÎœÎ¯Î± Î³ÏÎ±Î¼Î¼Î® Î³Î¹Î± ÎºÎ¬Î¸Îµ Ï„Î¹Î¼Î®'
+  text_wiki_page_destroy_question: "Î‘Ï…Ï„Î® Î· ÏƒÎµÎ»Î¯Î´Î± Î­Ï‡ÎµÎ¹ %{descendants} ÏƒÎµÎ»Î¯Î´ÎµÏ‚ Ï„Î­ÎºÎ½Ï‰Î½ ÎºÎ±Î¹ Î±Ï€Î¿Î³ÏŒÎ½Ï‰Î½. Î¤Î¹ Î¸Î­Î»ÎµÏ„Îµ Î½Î± ÎºÎ¬Î½ÎµÏ„Îµ ;"
+  text_wiki_page_nullify_children: "Î”Î¹Î±Ï„Î·ÏÎ®ÏƒÏ„Îµ Ï„Î¹Ï‚ ÏƒÎµÎ»Î¯Î´ÎµÏ‚ Ï„Î­ÎºÎ½Ï‰Î½ Ï‰Ï‚ ÏƒÎµÎ»Î¯Î´ÎµÏ‚ root"
+  text_wiki_page_destroy_children: "Î”Î¹Î±Î³ÏÎ¬ÏˆÏ„Îµ ÏŒÎ»ÎµÏ‚ Ï„Î¹Ï‚ ÏƒÎµÎ»Î¯Î´ÎµÏ‚ Ï„Î­ÎºÎ½Ï‰Î½ ÎºÎ±Î¹ Ï„Ï‰Î½ Î±Ï€Î¿Î³ÏŒÎ½Ï‰Î½ Ï„Î¿Ï…Ï‚"
+  text_wiki_page_reassign_children: "Î•Ï€Î±Î½ÎµÎºÏ‡ÏŽÏÎ¹ÏƒÎ· Ï„Ï‰Î½ ÏƒÎµÎ»Î¯Î´Ï‰Î½ Ï„Î­ÎºÎ½Ï‰Î½ ÏƒÏ„Î· Î³Î¿Î½Î¹ÎºÎ® ÏƒÎµÎ»Î¯Î´Î±"
+
+  default_role_manager: Manager
+  default_role_developer: Developer
+  default_role_reporter: Reporter
+  default_tracker_bug: Î£Ï†Î¬Î»Î¼Î±Ï„Î±
+  default_tracker_feature: Î›ÎµÎ¹Ï„Î¿Ï…ÏÎ³Î¯ÎµÏ‚
+  default_tracker_support: Î¥Ï€Î¿ÏƒÏ„Î®ÏÎ¹Î¾Î·
+  default_issue_status_new: ÎÎ­Î±
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: Î•Ï€Î¹Î»Ï…Î¼Î­Î½Î¿
+  default_issue_status_feedback: Î£Ï‡ÏŒÎ»Î¹Î±
+  default_issue_status_closed: ÎšÎ»ÎµÎ¹ÏƒÏ„ÏŒ
+  default_issue_status_rejected: Î‘Ï€Î¿ÏÏÎ¹Ï€Ï„Î­Î¿
+  default_doc_category_user: Î¤ÎµÎºÎ¼Î·ÏÎ¯Ï‰ÏƒÎ· Ï‡ÏÎ®ÏƒÏ„Î·
+  default_doc_category_tech: Î¤ÎµÏ‡Î½Î¹ÎºÎ® Ï„ÎµÎºÎ¼Î·ÏÎ¯Ï‰ÏƒÎ·
+  default_priority_low: Î§Î±Î¼Î·Î»Î®
+  default_priority_normal: ÎšÎ±Î½Î¿Î½Î¹ÎºÎ®
+  default_priority_high: Î¥ÏˆÎ·Î»Î®
+  default_priority_urgent: Î•Ï€ÎµÎ¯Î³Î¿Î½
+  default_priority_immediate: Î†Î¼ÎµÏƒÎ·
+  default_activity_design: Î£Ï‡ÎµÎ´Î¹Î±ÏƒÎ¼ÏŒÏ‚
+  default_activity_development: Î‘Î½Î¬Ï€Ï„Ï…Î¾Î·
+
+  enumeration_issue_priorities: Î ÏÎ¿Ï„ÎµÏÎ±Î¹ÏŒÏ„Î·Ï„Î± Î¸Î­Î¼Î±Ï„Î¿Ï‚
+  enumeration_doc_categories: ÎšÎ±Ï„Î·Î³Î¿ÏÎ¯Î± ÎµÎ³Î³ÏÎ¬Ï†Ï‰Î½
+  enumeration_activities: Î”ÏÎ±ÏƒÏ„Î·ÏÎ¹ÏŒÏ„Î·Ï„ÎµÏ‚ (ÎºÎ±Ï„Î±ÎºÎµÏÎ¼Î±Ï„Î¹ÏƒÎ¼ÏŒÏ‚ Ï‡ÏÏŒÎ½Î¿Ï…)
+  text_journal_changed: "%{label} Î¬Î»Î»Î±Î¾Îµ Î±Ï€ÏŒ %{old} ÏƒÎµ %{new}"
+  text_journal_set_to: "%{label} Î¿ÏÎ¯Î¶ÎµÏ„Î±Î¹ ÏƒÎµ %{value}"
+  text_journal_deleted: "%{label} Î´Î¹Î±Î³ÏÎ¬Ï†Î·ÎºÎµ (%{old})"
+  label_group_plural: ÎŸÎ¼Î¬Î´ÎµÏ‚
+  label_group: ÎŸÎ¼Î¬Î´Î±
+  label_group_new: ÎÎ­Î± Î¿Î¼Î¬Î´Î±
+  label_time_entry_plural: Î§ÏÏŒÎ½Î¿Ï‚ Ï€Î¿Ï… Î´Î±Ï€Î±Î½Î®Î¸Î·ÎºÎµ
+  text_journal_added: "%{label} %{value} added"
+  field_active: Active
+  enumeration_system_activity: System Activity
+  permission_delete_issue_watchers: Delete watchers
+  version_status_closed: closed
+  version_status_locked: locked
+  version_status_open: open
+  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
+  label_user_anonymous: Anonymous
+  button_move_and_follow: Move and follow
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_gravatar_default: Default Gravatar image
+  field_sharing: Sharing
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_system: With all projects
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_tree: With project tree
+  label_version_sharing_none: Not shared
+  error_can_not_archive_project: This project can not be archived
+  button_duplicate: Duplicate
+  button_copy_and_follow: Copy and follow
+  label_copy_source: Source
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_status: Use the issue status
+  error_issue_done_ratios_not_updated: Issue done ratios not updated.
+  error_workflow_copy_target: Please select target tracker(s) and role(s)
+  setting_issue_done_ratio_issue_field: Use the issue field
+  label_copy_same_as_target: Same as target
+  label_copy_target: Target
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  error_workflow_copy_source: Please select a source tracker or role
+  label_update_issue_done_ratios: Update issue done ratios
+  setting_start_of_week: Start calendars on
+  permission_view_issues: View Issues
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_revision_id: Revision %{value}
+  label_api_access_key: API access key
+  label_api_access_key_created_on: API access key created %{value} ago
+  label_feeds_access_key: RSS access key
+  notice_api_access_key_reseted: Your API access key was reset.
+  setting_rest_api_enabled: Enable REST web service
+  label_missing_api_access_key: Missing an API access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  button_show: Show
+  text_line_separated: Multiple values allowed (one line for each value).
+  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
+  permission_add_subprojects: Create subprojects
+  label_subproject_new: New subproject
+  text_own_membership_delete_confirmation: |-
+    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
+    Are you sure you want to continue?
+  label_close_versions: Close completed versions
+  label_board_sticky: Sticky
+  label_board_locked: Locked
+  permission_export_wiki_pages: Export wiki pages
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: Manage project activities
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_profile: Profile
+  permission_manage_subtasks: Manage subtasks
+  field_parent_issue: Parent task
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: ÎšÏ‰Î´Î¹ÎºÎ¿Ï€Î¿Î¯Î·ÏƒÎ· Î¼Î·Î½Ï…Î¼Î¬Ï„Ï‰Î½ commit
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 Î˜Î­Î¼Î±
+    one:   1 Î˜Î­Î¼Î±
+    other: "%{count} Î˜Î­Î¼Î±Ï„Î±"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: ÏŒÎ»Î±
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Î£ÏÎ½Î¿Î»Î¿
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a5/a58853dd4ead2341935313f54ac169192e2f2345.svn-base
--- /dev/null
+++ b/.svn/pristine/a5/a58853dd4ead2341935313f54ac169192e2f2345.svn-base
@@ -0,0 +1,231 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositorySubversionTest < ActiveSupport::TestCase
+  fixtures :projects, :repositories, :enabled_modules, :users, :roles
+
+  NUM_REV = 11
+
+  def setup
+    @project = Project.find(3)
+    @repository = Repository::Subversion.create(:project => @project,
+             :url => self.class.subversion_repository_url)
+    assert @repository
+  end
+
+  if repository_configured?('subversion')
+    def test_fetch_changesets_from_scratch
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_equal 20, @repository.filechanges.count
+      assert_equal 'Initial import.', @repository.changesets.find_by_revision('1').comments
+    end
+
+    def test_fetch_changesets_incremental
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      # Remove changesets with revision > 5
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 5}
+      @project.reload
+      assert_equal 5, @repository.changesets.count
+
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+    end
+
+    def test_entries
+      entries = @repository.entries
+      assert_kind_of Redmine::Scm::Adapters::Entries, entries
+    end
+
+    def test_entries_for_invalid_path_should_return_nil
+      entries = @repository.entries('invalid_path')
+      assert_nil entries
+    end
+
+    def test_latest_changesets
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      # with limit
+      changesets = @repository.latest_changesets('', nil, 2)
+      assert_equal 2, changesets.size
+      assert_equal @repository.latest_changesets('', nil).slice(0,2), changesets
+
+      # with path
+      changesets = @repository.latest_changesets('subversion_test/folder', nil)
+      assert_equal ["10", "9", "7", "6", "5", "2"], changesets.collect(&:revision)
+
+      # with path and revision
+      changesets = @repository.latest_changesets('subversion_test/folder', 8)
+      assert_equal ["7", "6", "5", "2"], changesets.collect(&:revision)
+    end
+
+    def test_directory_listing_with_square_brackets_in_path
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      entries = @repository.entries('subversion_test/[folder_with_brackets]')
+      assert_not_nil entries, 'Expect to find entries in folder_with_brackets'
+      assert_equal 1, entries.size, 'Expect one entry in folder_with_brackets'
+      assert_equal 'README.txt', entries.first.name
+    end
+
+    def test_directory_listing_with_square_brackets_in_base
+      @project = Project.find(3)
+      @repository = Repository::Subversion.create(
+                          :project => @project,
+                          :url => "file:///#{self.class.repository_path('subversion')}/subversion_test/[folder_with_brackets]")
+
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+
+      assert_equal 1, @repository.changesets.count, 'Expected to see 1 revision'
+      assert_equal 2, @repository.filechanges.count, 'Expected to see 2 changes, dir add and file add'
+
+      entries = @repository.entries('')
+      assert_not_nil entries, 'Expect to find entries'
+      assert_equal 1, entries.size, 'Expect a single entry'
+      assert_equal 'README.txt', entries.first.name
+    end
+
+    def test_identifier
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      c = @repository.changesets.find_by_revision('1')
+      assert_equal c.revision, c.identifier
+    end
+
+    def test_find_changeset_by_empty_name
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['', ' ', nil].each do |r|
+        assert_nil @repository.find_changeset_by_name(r)
+      end
+    end
+
+    def test_identifier_nine_digit
+      c = Changeset.new(:repository => @repository, :committed_on => Time.now,
+                        :revision => '123456789', :comments => 'test')
+      assert_equal c.identifier, c.revision
+    end
+
+    def test_format_identifier
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      c = @repository.changesets.find_by_revision('1')
+      assert_equal c.format_identifier, c.revision
+    end
+
+    def test_format_identifier_nine_digit
+      c = Changeset.new(:repository => @repository, :committed_on => Time.now,
+                        :revision => '123456789', :comments => 'test')
+      assert_equal c.format_identifier, c.revision
+    end
+
+    def test_activities
+      c = Changeset.new(:repository => @repository, :committed_on => Time.now,
+                        :revision => '1', :comments => 'test')
+      assert c.event_title.include?('1:')
+      assert_equal '1', c.event_url[:rev]
+    end
+
+    def test_activities_nine_digit
+      c = Changeset.new(:repository => @repository, :committed_on => Time.now,
+                        :revision => '123456789', :comments => 'test')
+      assert c.event_title.include?('123456789:')
+      assert_equal '123456789', c.event_url[:rev]
+    end
+
+    def test_log_encoding_ignore_setting
+      with_settings :commit_logs_encoding => 'windows-1252' do
+        s1 = "\xC2\x80"
+        s2 = "\xc3\x82\xc2\x80"
+        if s1.respond_to?(:force_encoding)
+          s1.force_encoding('ISO-8859-1')
+          s2.force_encoding('UTF-8')
+          assert_equal s1.encode('UTF-8'), s2
+        end
+        c = Changeset.new(:repository => @repository,
+                          :comments   => s2,
+                          :revision   => '123',
+                          :committed_on => Time.now)
+        assert c.save
+        assert_equal s2, c.comments
+      end
+    end
+
+    def test_previous
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      changeset = @repository.find_changeset_by_name('3')
+      assert_equal @repository.find_changeset_by_name('2'), changeset.previous
+    end
+
+    def test_previous_nil
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      changeset = @repository.find_changeset_by_name('1')
+      assert_nil changeset.previous
+    end
+
+    def test_next
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      changeset = @repository.find_changeset_by_name('2')
+      assert_equal @repository.find_changeset_by_name('3'), changeset.next
+    end
+
+    def test_next_nil
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      changeset = @repository.find_changeset_by_name('11')
+      assert_nil changeset.next
+    end
+  else
+    puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a5/a58efa2a2f9081ae3e36afe873bd32ea87248ab4.svn-base
--- a/.svn/pristine/a5/a58efa2a2f9081ae3e36afe873bd32ea87248ab4.svn-base
+++ /dev/null
@@ -1,144 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # Scanner for the Delphi language (Object Pascal).
-  # 
-  # Alias: +pascal+
-  class Delphi < Scanner
-    
-    register_for :delphi
-    file_extension 'pas'
-    
-    KEYWORDS = [
-      'and', 'array', 'as', 'at', 'asm', 'at', 'begin', 'case', 'class',
-      'const', 'constructor', 'destructor', 'dispinterface', 'div', 'do',
-      'downto', 'else', 'end', 'except', 'exports', 'file', 'finalization',
-      'finally', 'for', 'function', 'goto', 'if', 'implementation', 'in',
-      'inherited', 'initialization', 'inline', 'interface', 'is', 'label',
-      'library', 'mod', 'nil', 'not', 'object', 'of', 'or', 'out', 'packed',
-      'procedure', 'program', 'property', 'raise', 'record', 'repeat',
-      'resourcestring', 'set', 'shl', 'shr', 'string', 'then', 'threadvar',
-      'to', 'try', 'type', 'unit', 'until', 'uses', 'var', 'while', 'with',
-      'xor', 'on',
-    ]  # :nodoc:
-    
-    DIRECTIVES = [
-      'absolute', 'abstract', 'assembler', 'at', 'automated', 'cdecl',
-      'contains', 'deprecated', 'dispid', 'dynamic', 'export',
-      'external', 'far', 'forward', 'implements', 'local', 
-      'near', 'nodefault', 'on', 'overload', 'override',
-      'package', 'pascal', 'platform', 'private', 'protected', 'public',
-      'published', 'read', 'readonly', 'register', 'reintroduce',
-      'requires', 'resident', 'safecall', 'stdcall', 'stored', 'varargs',
-      'virtual', 'write', 'writeonly',
-    ]  # :nodoc:
-    
-    IDENT_KIND = WordList::CaseIgnoring.new(:ident).
-      add(KEYWORDS, :keyword).
-      add(DIRECTIVES, :directive)  # :nodoc:
-    
-    NAME_FOLLOWS = WordList::CaseIgnoring.new(false).
-      add(%w(procedure function .))  # :nodoc:
-    
-  protected
-    
-    def scan_tokens encoder, options
-      
-      state = :initial
-      last_token = ''
-      
-      until eos?
-        
-        if state == :initial
-          
-          if match = scan(/ \s+ /x)
-            encoder.text_token match, :space
-            next
-            
-          elsif match = scan(%r! \{ \$ [^}]* \}? | \(\* \$ (?: .*? \*\) | .* ) !mx)
-            encoder.text_token match, :preprocessor
-            next
-            
-          elsif match = scan(%r! // [^\n]* | \{ [^}]* \}? | \(\* (?: .*? \*\) | .* ) !mx)
-            encoder.text_token match, :comment
-            next
-            
-          elsif match = scan(/ <[>=]? | >=? | :=? | [-+=*\/;,@\^|\(\)\[\]] | \.\. /x)
-            encoder.text_token match, :operator
-          
-          elsif match = scan(/\./)
-            encoder.text_token match, :operator
-            next if last_token == 'end'
-            
-          elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
-            encoder.text_token match, NAME_FOLLOWS[last_token] ? :ident : IDENT_KIND[match]
-            
-          elsif match = skip(/ ' ( [^\n']|'' ) (?:'|$) /x)
-            encoder.begin_group :char
-            encoder.text_token "'", :delimiter
-            encoder.text_token self[1], :content
-            encoder.text_token "'", :delimiter
-            encoder.end_group :char
-            next
-            
-          elsif match = scan(/ ' /x)
-            encoder.begin_group :string
-            encoder.text_token match, :delimiter
-            state = :string
-            
-          elsif match = scan(/ \# (?: \d+ | \$[0-9A-Fa-f]+ ) /x)
-            encoder.text_token match, :char
-            
-          elsif match = scan(/ \$ [0-9A-Fa-f]+ /x)
-            encoder.text_token match, :hex
-            
-          elsif match = scan(/ (?: \d+ ) (?![eE]|\.[^.]) /x)
-            encoder.text_token match, :integer
-            
-          elsif match = scan(/ \d+ (?: \.\d+ (?: [eE][+-]? \d+ )? | [eE][+-]? \d+ ) /x)
-            encoder.text_token match, :float
-            
-          else
-            encoder.text_token getch, :error
-            next
-            
-          end
-          
-        elsif state == :string
-          if match = scan(/[^\n']+/)
-            encoder.text_token match, :content
-          elsif match = scan(/''/)
-            encoder.text_token match, :char
-          elsif match = scan(/'/)
-            encoder.text_token match, :delimiter
-            encoder.end_group :string
-            state = :initial
-            next
-          elsif match = scan(/\n/)
-            encoder.end_group :string
-            encoder.text_token match, :space
-            state = :initial
-          else
-            raise "else case \' reached; %p not handled." % peek(1), encoder
-          end
-          
-        else
-          raise 'else-case reached', encoder
-          
-        end
-        
-        last_token = match
-        
-      end
-      
-      if state == :string
-        encoder.end_group state
-      end
-      
-      encoder
-    end
-
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a5/a5a2bdba2e1db7153d66f6307d6658c7a79bbbc2.svn-base
--- /dev/null
+++ b/.svn/pristine/a5/a5a2bdba2e1db7153d66f6307d6658c7a79bbbc2.svn-base
@@ -0,0 +1,412 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/abstract_adapter'
+
+module Redmine
+  module Scm
+    module Adapters
+      class GitAdapter < AbstractAdapter
+
+        # Git executable name
+        GIT_BIN = Redmine::Configuration['scm_git_command'] || "git"
+
+        class GitBranch < Branch 
+          attr_accessor :is_default
+        end
+
+        class << self
+          def client_command
+            @@bin    ||= GIT_BIN
+          end
+
+          def sq_bin
+            @@sq_bin ||= shell_quote_command
+          end
+
+          def client_version
+            @@client_version ||= (scm_command_version || [])
+          end
+
+          def client_available
+            !client_version.empty?
+          end
+
+          def scm_command_version
+            scm_version = scm_version_from_command_line.dup
+            if scm_version.respond_to?(:force_encoding)
+              scm_version.force_encoding('ASCII-8BIT')
+            end
+            if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
+              m[2].scan(%r{\d+}).collect(&:to_i)
+            end
+          end
+
+          def scm_version_from_command_line
+            shellout("#{sq_bin} --version --no-color") { |io| io.read }.to_s
+          end
+        end
+
+        def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil)
+          super
+          @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
+        end
+
+        def path_encoding
+          @path_encoding
+        end
+
+        def info
+          begin
+            Info.new(:root_url => url, :lastrev => lastrev('',nil))
+          rescue
+            nil
+          end
+        end
+
+        def branches
+          return @branches if @branches
+          @branches = []
+          cmd_args = %w|branch --no-color --verbose --no-abbrev|
+          git_cmd(cmd_args) do |io|
+            io.each_line do |line|
+              branch_rev = line.match('\s*(\*?)\s*(.*?)\s*([0-9a-f]{40}).*$')
+              bran = GitBranch.new(branch_rev[2])
+              bran.revision =  branch_rev[3]
+              bran.scmid    =  branch_rev[3]
+              bran.is_default = ( branch_rev[1] == '*' )
+              @branches << bran
+            end
+          end
+          @branches.sort!
+        rescue ScmCommandAborted
+          nil
+        end
+
+        def tags
+          return @tags if @tags
+          cmd_args = %w|tag|
+          git_cmd(cmd_args) do |io|
+            @tags = io.readlines.sort!.map{|t| t.strip}
+          end
+        rescue ScmCommandAborted
+          nil
+        end
+
+        def default_branch
+          bras = self.branches
+          return nil if bras.nil?
+          default_bras = bras.select{|x| x.is_default == true}
+          return default_bras.first.to_s if ! default_bras.empty?
+          master_bras = bras.select{|x| x.to_s == 'master'}
+          master_bras.empty? ? bras.first.to_s : 'master' 
+        end
+
+        def entry(path=nil, identifier=nil)
+          parts = path.to_s.split(%r{[\/\\]}).select {|n| !n.blank?}
+          search_path = parts[0..-2].join('/')
+          search_name = parts[-1]
+          if search_path.blank? && search_name.blank?
+            # Root entry
+            Entry.new(:path => '', :kind => 'dir')
+          else
+            # Search for the entry in the parent directory
+            es = entries(search_path, identifier,
+                         options = {:report_last_commit => false})
+            es ? es.detect {|e| e.name == search_name} : nil
+          end
+        end
+
+        def entries(path=nil, identifier=nil, options={})
+          path ||= ''
+          p = scm_iconv(@path_encoding, 'UTF-8', path)
+          entries = Entries.new
+          cmd_args = %w|ls-tree -l|
+          cmd_args << "HEAD:#{p}"          if identifier.nil?
+          cmd_args << "#{identifier}:#{p}" if identifier
+          git_cmd(cmd_args) do |io|
+            io.each_line do |line|
+              e = line.chomp.to_s
+              if e =~ /^\d+\s+(\w+)\s+([0-9a-f]{40})\s+([0-9-]+)\t(.+)$/
+                type = $1
+                sha  = $2
+                size = $3
+                name = $4
+                if name.respond_to?(:force_encoding)
+                  name.force_encoding(@path_encoding)
+                end
+                full_path = p.empty? ? name : "#{p}/#{name}"
+                n      = scm_iconv('UTF-8', @path_encoding, name)
+                full_p = scm_iconv('UTF-8', @path_encoding, full_path)
+                entries << Entry.new({:name => n,
+                 :path => full_p,
+                 :kind => (type == "tree") ? 'dir' : 'file',
+                 :size => (type == "tree") ? nil : size,
+                 :lastrev => options[:report_last_commit] ?
+                                 lastrev(full_path, identifier) : Revision.new
+                }) unless entries.detect{|entry| entry.name == name}
+              end
+            end
+          end
+          entries.sort_by_name
+        rescue ScmCommandAborted
+          nil
+        end
+
+        def lastrev(path, rev)
+          return nil if path.nil?
+          cmd_args = %w|log --no-color --encoding=UTF-8 --date=iso --pretty=fuller --no-merges -n 1|
+          cmd_args << rev if rev
+          cmd_args << "--" << path unless path.empty?
+          lines = []
+          git_cmd(cmd_args) { |io| lines = io.readlines }
+          begin
+              id = lines[0].split[1]
+              author = lines[1].match('Author:\s+(.*)$')[1]
+              time = Time.parse(lines[4].match('CommitDate:\s+(.*)$')[1])
+
+              Revision.new({
+                :identifier => id,
+                :scmid      => id,
+                :author     => author,
+                :time       => time,
+                :message    => nil,
+                :paths      => nil
+                })
+          rescue NoMethodError => e
+              logger.error("The revision '#{path}' has a wrong format")
+              return nil
+          end
+        rescue ScmCommandAborted
+          nil
+        end
+
+        def revisions(path, identifier_from, identifier_to, options={})
+          revs = Revisions.new
+          cmd_args = %w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller --parents --stdin|
+          cmd_args << "--reverse" if options[:reverse]
+          cmd_args << "-n" << "#{options[:limit].to_i}" if options[:limit]
+          cmd_args << "--" << scm_iconv(@path_encoding, 'UTF-8', path) if path && !path.empty?
+          revisions = []
+          if identifier_from || identifier_to
+            revisions << ""
+            revisions[0] << "#{identifier_from}.." if identifier_from
+            revisions[0] << "#{identifier_to}" if identifier_to
+          else
+            unless options[:includes].blank?
+              revisions += options[:includes]
+            end
+            unless options[:excludes].blank?
+              revisions += options[:excludes].map{|r| "^#{r}"}
+            end
+          end
+
+          git_cmd(cmd_args, {:write_stdin => true}) do |io|
+            io.binmode
+            io.puts(revisions.join("\n"))
+            io.close_write
+            files=[]
+            changeset = {}
+            parsing_descr = 0  #0: not parsing desc or files, 1: parsing desc, 2: parsing files
+
+            io.each_line do |line|
+              if line =~ /^commit ([0-9a-f]{40})(( [0-9a-f]{40})*)$/
+                key = "commit"
+                value = $1
+                parents_str = $2
+                if (parsing_descr == 1 || parsing_descr == 2)
+                  parsing_descr = 0
+                  revision = Revision.new({
+                    :identifier => changeset[:commit],
+                    :scmid      => changeset[:commit],
+                    :author     => changeset[:author],
+                    :time       => Time.parse(changeset[:date]),
+                    :message    => changeset[:description],
+                    :paths      => files,
+                    :parents    => changeset[:parents]
+                  })
+                  if block_given?
+                    yield revision
+                  else
+                    revs << revision
+                  end
+                  changeset = {}
+                  files = []
+                end
+                changeset[:commit] = $1
+                unless parents_str.nil? or parents_str == ""
+                  changeset[:parents] = parents_str.strip.split(' ')
+                end
+              elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/
+                key = $1
+                value = $2
+                if key == "Author"
+                  changeset[:author] = value
+                elsif key == "CommitDate"
+                  changeset[:date] = value
+                end
+              elsif (parsing_descr == 0) && line.chomp.to_s == ""
+                parsing_descr = 1
+                changeset[:description] = ""
+              elsif (parsing_descr == 1 || parsing_descr == 2) \
+                  && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\t(.+)$/
+                parsing_descr = 2
+                fileaction    = $1
+                filepath      = $2
+                p = scm_iconv('UTF-8', @path_encoding, filepath)
+                files << {:action => fileaction, :path => p}
+              elsif (parsing_descr == 1 || parsing_descr == 2) \
+                  && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\d+\s+(\S+)\t(.+)$/
+                parsing_descr = 2
+                fileaction    = $1
+                filepath      = $3
+                p = scm_iconv('UTF-8', @path_encoding, filepath)
+                files << {:action => fileaction, :path => p}
+              elsif (parsing_descr == 1) && line.chomp.to_s == ""
+                parsing_descr = 2
+              elsif (parsing_descr == 1)
+                changeset[:description] << line[4..-1]
+              end
+            end
+
+            if changeset[:commit]
+              revision = Revision.new({
+                :identifier => changeset[:commit],
+                :scmid      => changeset[:commit],
+                :author     => changeset[:author],
+                :time       => Time.parse(changeset[:date]),
+                :message    => changeset[:description],
+                :paths      => files,
+                :parents    => changeset[:parents]
+                 })
+              if block_given?
+                yield revision
+              else
+                revs << revision
+              end
+            end
+          end
+          revs
+        rescue ScmCommandAborted => e
+          err_msg = "git log error: #{e.message}"
+          logger.error(err_msg)
+          if block_given?
+            raise CommandFailed, err_msg
+          else
+            revs
+          end
+        end
+
+        def diff(path, identifier_from, identifier_to=nil)
+          path ||= ''
+          cmd_args = []
+          if identifier_to
+            cmd_args << "diff" << "--no-color" <<  identifier_to << identifier_from
+          else
+            cmd_args << "show" << "--no-color" << identifier_from
+          end
+          cmd_args << "--" <<  scm_iconv(@path_encoding, 'UTF-8', path) unless path.empty?
+          diff = []
+          git_cmd(cmd_args) do |io|
+            io.each_line do |line|
+              diff << line
+            end
+          end
+          diff
+        rescue ScmCommandAborted
+          nil
+        end
+
+        def annotate(path, identifier=nil)
+          identifier = 'HEAD' if identifier.blank?
+          cmd_args = %w|blame|
+          cmd_args << "-p" << identifier << "--" <<  scm_iconv(@path_encoding, 'UTF-8', path)
+          blame = Annotate.new
+          content = nil
+          git_cmd(cmd_args) { |io| io.binmode; content = io.read }
+          # git annotates binary files
+          return nil if content.is_binary_data?
+          identifier = ''
+          # git shows commit author on the first occurrence only
+          authors_by_commit = {}
+          content.split("\n").each do |line|
+            if line =~ /^([0-9a-f]{39,40})\s.*/
+              identifier = $1
+            elsif line =~ /^author (.+)/
+              authors_by_commit[identifier] = $1.strip
+            elsif line =~ /^\t(.*)/
+              blame.add_line($1, Revision.new(
+                                    :identifier => identifier,
+                                    :revision   => identifier,
+                                    :scmid      => identifier,
+                                    :author     => authors_by_commit[identifier]
+                                    ))
+              identifier = ''
+              author = ''
+            end
+          end
+          blame
+        rescue ScmCommandAborted
+          nil
+        end
+
+        def cat(path, identifier=nil)
+          if identifier.nil?
+            identifier = 'HEAD'
+          end
+          cmd_args = %w|show --no-color|
+          cmd_args << "#{identifier}:#{scm_iconv(@path_encoding, 'UTF-8', path)}"
+          cat = nil
+          git_cmd(cmd_args) do |io|
+            io.binmode
+            cat = io.read
+          end
+          cat
+        rescue ScmCommandAborted
+          nil
+        end
+
+        class Revision < Redmine::Scm::Adapters::Revision
+          # Returns the readable identifier
+          def format_identifier
+            identifier[0,8]
+          end
+        end
+
+        def git_cmd(args, options = {}, &block)
+          repo_path = root_url || url
+          full_args = ['--git-dir', repo_path]
+          if self.class.client_version_above?([1, 7, 2])
+            full_args << '-c' << 'core.quotepath=false'
+            full_args << '-c' << 'log.decorate=no'
+          end
+          full_args += args
+          ret = shellout(
+                   self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
+                   options,
+                   &block
+                   )
+          if $? && $?.exitstatus != 0
+            raise ScmCommandAborted, "git exited with non-zero status: #{$?.exitstatus}"
+          end
+          ret
+        end
+        private :git_cmd
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a5/a5c130bb9c2df01fd9aed379af31f013bd32b083.svn-base
--- a/.svn/pristine/a5/a5c130bb9c2df01fd9aed379af31f013bd32b083.svn-base
+++ /dev/null
@@ -1,312 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'users_controller'
-
-# Re-raise errors caught by the controller.
-class UsersController; def rescue_action(e) raise e end; end
-
-class UsersControllerTest < ActionController::TestCase
-  include Redmine::I18n
-
-  fixtures :users, :projects, :members, :member_roles, :roles, :auth_sources, :custom_fields, :custom_values, :groups_users
-
-  def setup
-    @controller = UsersController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @request.session[:user_id] = 1 # admin
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:users)
-    # active users only
-    assert_nil assigns(:users).detect {|u| !u.active?}
-  end
-
-  def test_index_with_name_filter
-    get :index, :name => 'john'
-    assert_response :success
-    assert_template 'index'
-    users = assigns(:users)
-    assert_not_nil users
-    assert_equal 1, users.size
-    assert_equal 'John', users.first.firstname
-  end
-
-  def test_index_with_group_filter
-    get :index, :group_id => '10'
-    assert_response :success
-    assert_template 'index'
-    users = assigns(:users)
-    assert users.any?
-    assert_equal([], (users - Group.find(10).users))
-  end
-
-  def test_show
-    @request.session[:user_id] = nil
-    get :show, :id => 2
-    assert_response :success
-    assert_template 'show'
-    assert_not_nil assigns(:user)
-
-    assert_tag 'li', :content => /Phone number/
-  end
-
-  def test_show_should_not_display_hidden_custom_fields
-    @request.session[:user_id] = nil
-    UserCustomField.find_by_name('Phone number').update_attribute :visible, false
-    get :show, :id => 2
-    assert_response :success
-    assert_template 'show'
-    assert_not_nil assigns(:user)
-
-    assert_no_tag 'li', :content => /Phone number/
-  end
-
-  def test_show_should_not_fail_when_custom_values_are_nil
-    user = User.find(2)
-
-    # Create a custom field to illustrate the issue
-    custom_field = CustomField.create!(:name => 'Testing', :field_format => 'text')
-    custom_value = user.custom_values.build(:custom_field => custom_field).save!
-
-    get :show, :id => 2
-    assert_response :success
-  end
-
-  def test_show_inactive
-    @request.session[:user_id] = nil
-    get :show, :id => 5
-    assert_response 404
-  end
-
-  def test_show_should_not_reveal_users_with_no_visible_activity_or_project
-    @request.session[:user_id] = nil
-    get :show, :id => 9
-    assert_response 404
-  end
-
-  def test_show_inactive_by_admin
-    @request.session[:user_id] = 1
-    get :show, :id => 5
-    assert_response 200
-    assert_not_nil assigns(:user)
-  end
-
-  def test_show_displays_memberships_based_on_project_visibility
-    @request.session[:user_id] = 1
-    get :show, :id => 2
-    assert_response :success
-    memberships = assigns(:memberships)
-    assert_not_nil memberships
-    project_ids = memberships.map(&:project_id)
-    assert project_ids.include?(2) #private project admin can see
-  end
-
-  def test_show_current_should_require_authentication
-    @request.session[:user_id] = nil
-    get :show, :id => 'current'
-    assert_response 302
-  end
-
-  def test_show_current
-    @request.session[:user_id] = 2
-    get :show, :id => 'current'
-    assert_response :success
-    assert_template 'show'
-    assert_equal User.find(2), assigns(:user)
-  end
-
-  def test_new
-    get :new
-
-    assert_response :success
-    assert_template :new
-    assert assigns(:user)
-  end
-
-  def test_create
-    Setting.bcc_recipients = '1'
-
-    assert_difference 'User.count' do
-      assert_difference 'ActionMailer::Base.deliveries.size' do
-        post :create,
-          :user => {
-            :firstname => 'John',
-            :lastname => 'Doe',
-            :login => 'jdoe',
-            :password => 'secret',
-            :password_confirmation => 'secret',
-            :mail => 'jdoe@gmail.com',
-            :mail_notification => 'none'
-          },
-          :send_information => '1'
-      end
-    end
-
-    user = User.first(:order => 'id DESC')
-    assert_redirected_to :controller => 'users', :action => 'edit', :id => user.id
-
-    assert_equal 'John', user.firstname
-    assert_equal 'Doe', user.lastname
-    assert_equal 'jdoe', user.login
-    assert_equal 'jdoe@gmail.com', user.mail
-    assert_equal 'none', user.mail_notification
-    assert user.check_password?('secret')
-
-    mail = ActionMailer::Base.deliveries.last
-    assert_not_nil mail
-    assert_equal [user.mail], mail.bcc
-    assert mail.body.include?('secret')
-  end
-
-  def test_create_with_failure
-    assert_no_difference 'User.count' do
-      post :create, :user => {}
-    end
-
-    assert_response :success
-    assert_template 'new'
-  end
-
-  def test_edit
-    get :edit, :id => 2
-
-    assert_response :success
-    assert_template 'edit'
-    assert_equal User.find(2), assigns(:user)
-  end
-
-  def test_update
-    ActionMailer::Base.deliveries.clear
-    put :update, :id => 2, :user => {:firstname => 'Changed', :mail_notification => 'only_assigned'}, :pref => {:hide_mail => '1', :comments_sorting => 'desc'}
-
-    user = User.find(2)
-    assert_equal 'Changed', user.firstname
-    assert_equal 'only_assigned', user.mail_notification
-    assert_equal true, user.pref[:hide_mail]
-    assert_equal 'desc', user.pref[:comments_sorting]
-    assert ActionMailer::Base.deliveries.empty?
-  end
-
-  def test_update_with_failure
-    assert_no_difference 'User.count' do
-      put :update, :id => 2, :user => {:firstname => ''}
-    end
-
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_update_with_group_ids_should_assign_groups
-    put :update, :id => 2, :user => {:group_ids => ['10']}
-
-    user = User.find(2)
-    assert_equal [10], user.group_ids
-  end
-
-  def test_update_with_activation_should_send_a_notification
-    u = User.new(:firstname => 'Foo', :lastname => 'Bar', :mail => 'foo.bar@somenet.foo', :language => 'fr')
-    u.login = 'foo'
-    u.status = User::STATUS_REGISTERED
-    u.save!
-    ActionMailer::Base.deliveries.clear
-    Setting.bcc_recipients = '1'
-
-    put :update, :id => u.id, :user => {:status => User::STATUS_ACTIVE}
-    assert u.reload.active?
-    mail = ActionMailer::Base.deliveries.last
-    assert_not_nil mail
-    assert_equal ['foo.bar@somenet.foo'], mail.bcc
-    assert mail.body.include?(ll('fr', :notice_account_activated))
-  end
-
-  def test_update_with_password_change_should_send_a_notification
-    ActionMailer::Base.deliveries.clear
-    Setting.bcc_recipients = '1'
-
-    put :update, :id => 2, :user => {:password => 'newpass', :password_confirmation => 'newpass'}, :send_information => '1'
-    u = User.find(2)
-    assert u.check_password?('newpass')
-
-    mail = ActionMailer::Base.deliveries.last
-    assert_not_nil mail
-    assert_equal [u.mail], mail.bcc
-    assert mail.body.include?('newpass')
-  end
-
-  test "put :update with a password change to an AuthSource user switching to Internal authentication" do
-    # Configure as auth source
-    u = User.find(2)
-    u.auth_source = AuthSource.find(1)
-    u.save!
-
-    put :update, :id => u.id, :user => {:auth_source_id => '', :password => 'newpass'}, :password_confirmation => 'newpass'
-
-    assert_equal nil, u.reload.auth_source
-    assert u.check_password?('newpass')
-  end
-
-  def test_destroy
-    assert_difference 'User.count', -1 do
-      delete :destroy, :id => 2
-    end
-    assert_redirected_to '/users'
-    assert_nil User.find_by_id(2)
-  end
-
-  def test_destroy_should_not_accept_get_requests
-    assert_no_difference 'User.count' do
-      get :destroy, :id => 2
-    end
-    assert_response 405
-  end
-
-  def test_destroy_should_be_denied_for_non_admin_users
-    @request.session[:user_id] = 3
-
-    assert_no_difference 'User.count' do
-      get :destroy, :id => 2
-    end
-    assert_response 403
-  end
-
-  def test_edit_membership
-    post :edit_membership, :id => 2, :membership_id => 1,
-                           :membership => { :role_ids => [2]}
-    assert_redirected_to :action => 'edit', :id => '2', :tab => 'memberships'
-    assert_equal [2], Member.find(1).role_ids
-  end
-
-  def test_destroy_membership
-    post :destroy_membership, :id => 2, :membership_id => 1
-    assert_redirected_to :action => 'edit', :id => '2', :tab => 'memberships'
-    assert_nil Member.find_by_id(1)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a6/a641079848577543d266682bf453b7b61dd4c321.svn-base
--- a/.svn/pristine/a6/a641079848577543d266682bf453b7b61dd4c321.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class BoardTest < ActiveSupport::TestCase
-  fixtures :projects, :boards, :messages, :attachments, :watchers
-
-  def setup
-    @project = Project.find(1)
-  end
-
-  def test_create
-    board = Board.new(:project => @project, :name => 'Test board', :description => 'Test board description')
-    assert board.save
-    board.reload
-    assert_equal 'Test board', board.name
-    assert_equal 'Test board description', board.description
-    assert_equal @project, board.project
-    assert_equal 0, board.topics_count
-    assert_equal 0, board.messages_count
-    assert_nil board.last_message
-    # last position
-    assert_equal @project.boards.size, board.position
-  end
-
-  def test_destroy
-    board = Board.find(1)
-    assert_difference 'Message.count', -6 do
-      assert_difference 'Attachment.count', -1 do
-        assert_difference 'Watcher.count', -1 do
-          assert board.destroy
-        end
-      end
-    end
-    assert_equal 0, Message.count(:conditions => {:board_id => 1})
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a6/a647c278df16babe24b2e16fd778a23d11d7be0d.svn-base
--- a/.svn/pristine/a6/a647c278df16babe24b2e16fd778a23d11d7be0d.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/process/reaper'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a6/a649e6e13fa94c6da3001118983e1f589fe01ce6.svn-base
--- /dev/null
+++ b/.svn/pristine/a6/a649e6e13fa94c6da3001118983e1f589fe01ce6.svn-base
@@ -0,0 +1,328 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WorkflowsControllerTest < ActionController::TestCase
+  fixtures :roles, :trackers, :workflows, :users, :issue_statuses
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 1 # admin
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+
+    count = WorkflowTransition.count(:all, :conditions => 'role_id = 1 AND tracker_id = 2')
+    assert_tag :tag => 'a', :content => count.to_s,
+                            :attributes => { :href => '/workflows/edit?role_id=1&amp;tracker_id=2' }
+  end
+
+  def test_get_edit
+    get :edit
+    assert_response :success
+    assert_template 'edit'
+    assert_not_nil assigns(:roles)
+    assert_not_nil assigns(:trackers)
+  end
+
+  def test_get_edit_with_role_and_tracker
+    WorkflowTransition.delete_all
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
+    WorkflowTransition.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
+
+    get :edit, :role_id => 2, :tracker_id => 1
+    assert_response :success
+    assert_template 'edit'
+
+    # used status only
+    assert_not_nil assigns(:statuses)
+    assert_equal [2, 3, 5], assigns(:statuses).collect(&:id)
+
+    # allowed transitions
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'issue_status[3][5][]',
+                                                 :value => 'always',
+                                                 :checked => 'checked' }
+    # not allowed
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'issue_status[3][2][]',
+                                                 :value => 'always',
+                                                 :checked => nil }
+    # unused
+    assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                    :name => 'issue_status[1][1][]' }
+  end
+
+  def test_get_edit_with_role_and_tracker_and_all_statuses
+    WorkflowTransition.delete_all
+
+    get :edit, :role_id => 2, :tracker_id => 1, :used_statuses_only => '0'
+    assert_response :success
+    assert_template 'edit'
+
+    assert_not_nil assigns(:statuses)
+    assert_equal IssueStatus.count, assigns(:statuses).size
+
+    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
+                                                 :name => 'issue_status[1][1][]',
+                                                 :value => 'always',
+                                                 :checked => nil }
+  end
+
+  def test_post_edit
+    post :edit, :role_id => 2, :tracker_id => 1,
+      :issue_status => {
+        '4' => {'5' => ['always']},
+        '3' => {'1' => ['always'], '2' => ['always']}
+      }
+    assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
+
+    assert_equal 3, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
+    assert_not_nil  WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
+    assert_nil      WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4).first
+  end
+
+  def test_post_edit_with_additional_transitions
+    post :edit, :role_id => 2, :tracker_id => 1,
+      :issue_status => {
+        '4' => {'5' => ['always']},
+        '3' => {'1' => ['author'], '2' => ['assignee'], '4' => ['author', 'assignee']}
+      }
+    assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
+
+    assert_equal 4, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
+
+    w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5).first
+    assert ! w.author
+    assert ! w.assignee
+    w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1).first
+    assert w.author
+    assert ! w.assignee
+    w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
+    assert ! w.author
+    assert w.assignee
+    w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4).first
+    assert w.author
+    assert w.assignee
+  end
+
+  def test_clear_workflow
+    assert WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2}) > 0
+
+    post :edit, :role_id => 2, :tracker_id => 1
+    assert_equal 0, WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2})
+  end
+
+  def test_get_permissions
+    get :permissions
+
+    assert_response :success
+    assert_template 'permissions'
+    assert_not_nil assigns(:roles)
+    assert_not_nil assigns(:trackers)
+  end
+
+  def test_get_permissions_with_role_and_tracker
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'assigned_to_id', :rule => 'required')
+    WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
+    WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 3, :field_name => 'fixed_version_id', :rule => 'readonly')
+
+    get :permissions, :role_id => 1, :tracker_id => 2
+    assert_response :success
+    assert_template 'permissions'
+
+    assert_select 'input[name=role_id][value=1]'
+    assert_select 'input[name=tracker_id][value=2]'
+
+    # Required field
+    assert_select 'select[name=?]', 'permissions[assigned_to_id][2]' do
+      assert_select 'option[value=]'
+      assert_select 'option[value=][selected=selected]', 0
+      assert_select 'option[value=readonly]', :text => 'Read-only'
+      assert_select 'option[value=readonly][selected=selected]', 0
+      assert_select 'option[value=required]', :text => 'Required'
+      assert_select 'option[value=required][selected=selected]'
+    end
+
+    # Read-only field
+    assert_select 'select[name=?]', 'permissions[fixed_version_id][3]' do
+      assert_select 'option[value=]'
+      assert_select 'option[value=][selected=selected]', 0
+      assert_select 'option[value=readonly]', :text => 'Read-only'
+      assert_select 'option[value=readonly][selected=selected]'
+      assert_select 'option[value=required]', :text => 'Required'
+      assert_select 'option[value=required][selected=selected]', 0
+    end
+
+    # Other field
+    assert_select 'select[name=?]', 'permissions[due_date][3]' do
+      assert_select 'option[value=]'
+      assert_select 'option[value=][selected=selected]', 0
+      assert_select 'option[value=readonly]', :text => 'Read-only'
+      assert_select 'option[value=readonly][selected=selected]', 0
+      assert_select 'option[value=required]', :text => 'Required'
+      assert_select 'option[value=required][selected=selected]', 0
+    end
+  end
+
+  def test_get_permissions_with_required_custom_field_should_not_show_required_option
+    cf = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :tracker_ids => [1], :is_required => true)
+
+    get :permissions, :role_id => 1, :tracker_id => 1
+    assert_response :success
+    assert_template 'permissions'
+
+    # Custom field that is always required
+    # The default option is "(Required)"
+    assert_select 'select[name=?]', "permissions[#{cf.id}][3]" do
+      assert_select 'option[value=]'
+      assert_select 'option[value=readonly]', :text => 'Read-only'
+      assert_select 'option[value=required]', 0
+    end
+  end
+
+  def test_get_permissions_with_role_and_tracker_and_all_statuses
+    WorkflowTransition.delete_all
+
+    get :permissions, :role_id => 1, :tracker_id => 2, :used_statuses_only => '0'
+    assert_response :success
+    assert_equal IssueStatus.sorted.all, assigns(:statuses)
+  end
+
+  def test_post_permissions
+    WorkflowPermission.delete_all
+
+    post :permissions, :role_id => 1, :tracker_id => 2, :permissions => {
+      'assigned_to_id' => {'1' => '', '2' => 'readonly', '3' => ''},
+      'fixed_version_id' => {'1' => 'required', '2' => 'readonly', '3' => ''},
+      'due_date' => {'1' => '', '2' => '', '3' => ''},
+    }
+    assert_redirected_to '/workflows/permissions?role_id=1&tracker_id=2'
+
+    workflows = WorkflowPermission.all
+    assert_equal 3, workflows.size
+    workflows.each do |workflow|
+      assert_equal 1, workflow.role_id
+      assert_equal 2, workflow.tracker_id
+    end
+    assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'assigned_to_id' && wf.rule == 'readonly'}
+    assert workflows.detect {|wf| wf.old_status_id == 1 && wf.field_name == 'fixed_version_id' && wf.rule == 'required'}
+    assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'fixed_version_id' && wf.rule == 'readonly'}
+  end
+
+  def test_post_permissions_should_clear_permissions
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'assigned_to_id', :rule => 'required')
+    WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
+    wf1 = WorkflowPermission.create!(:role_id => 1, :tracker_id => 3, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
+    wf2 = WorkflowPermission.create!(:role_id => 2, :tracker_id => 2, :old_status_id => 3, :field_name => 'fixed_version_id', :rule => 'readonly')
+
+    post :permissions, :role_id => 1, :tracker_id => 2
+    assert_redirected_to '/workflows/permissions?role_id=1&tracker_id=2'
+
+    workflows = WorkflowPermission.all
+    assert_equal 2, workflows.size
+    assert wf1.reload
+    assert wf2.reload
+  end
+
+  def test_get_copy
+    get :copy
+    assert_response :success
+    assert_template 'copy'
+    assert_select 'select[name=source_tracker_id]' do
+      assert_select 'option[value=1]', :text => 'Bug'
+    end
+    assert_select 'select[name=source_role_id]' do
+      assert_select 'option[value=2]', :text => 'Developer'
+    end
+    assert_select 'select[name=?]', 'target_tracker_ids[]' do
+      assert_select 'option[value=3]', :text => 'Support request'
+    end
+    assert_select 'select[name=?]', 'target_role_ids[]' do
+      assert_select 'option[value=1]', :text => 'Manager'
+    end
+  end
+
+  def test_post_copy_one_to_one
+    source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
+
+    post :copy, :source_tracker_id => '1', :source_role_id => '2',
+                :target_tracker_ids => ['3'], :target_role_ids => ['1']
+    assert_response 302
+    assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
+  end
+
+  def test_post_copy_one_to_many
+    source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
+
+    post :copy, :source_tracker_id => '1', :source_role_id => '2',
+                :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
+    assert_response 302
+    assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 1)
+    assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
+    assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 3)
+    assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 3)
+  end
+
+  def test_post_copy_many_to_many
+    source_t2 = status_transitions(:tracker_id => 2, :role_id => 2)
+    source_t3 = status_transitions(:tracker_id => 3, :role_id => 2)
+
+    post :copy, :source_tracker_id => 'any', :source_role_id => '2',
+                :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
+    assert_response 302
+    assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 1)
+    assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 1)
+    assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 3)
+    assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 3)
+  end
+
+  def test_post_copy_with_incomplete_source_specification_should_fail
+    assert_no_difference 'WorkflowRule.count' do
+      post :copy,
+        :source_tracker_id => '', :source_role_id => '2',
+        :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
+      assert_response 200
+      assert_select 'div.flash.error', :text => 'Please select a source tracker or role' 
+    end
+  end
+
+  def test_post_copy_with_incomplete_target_specification_should_fail
+    assert_no_difference 'WorkflowRule.count' do
+      post :copy,
+        :source_tracker_id => '1', :source_role_id => '2',
+        :target_tracker_ids => ['2', '3']
+      assert_response 200
+      assert_select 'div.flash.error', :text => 'Please select target tracker(s) and role(s)'
+    end
+  end
+
+  # Returns an array of status transitions that can be compared
+  def status_transitions(conditions)
+    WorkflowTransition.
+      where(conditions).
+      order('tracker_id, role_id, old_status_id, new_status_id').
+      all.
+      collect {|w| [w.old_status, w.new_status_id]}
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a6/a6c2d0d0b8c42346610cefc80f58028a31c51655.svn-base
--- /dev/null
+++ b/.svn/pristine/a6/a6c2d0d0b8c42346610cefc80f58028a31c51655.svn-base
@@ -0,0 +1,71 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class MemberRole < ActiveRecord::Base
+  belongs_to :member
+  belongs_to :role
+
+  after_destroy :remove_member_if_empty
+
+  after_create :add_role_to_group_users, :add_role_to_subprojects
+  after_destroy :remove_inherited_roles
+
+  validates_presence_of :role
+  validate :validate_role_member
+
+  def validate_role_member
+    errors.add :role_id, :invalid if role && !role.member?
+  end
+
+  def inherited?
+    !inherited_from.nil?
+  end
+
+  private
+
+  def remove_member_if_empty
+    if member.roles.empty?
+      member.destroy
+    end
+  end
+
+  def add_role_to_group_users
+    if member.principal.is_a?(Group) && !inherited?
+      member.principal.users.each do |user|
+        user_member = Member.find_or_new(member.project_id, user.id)
+        user_member.member_roles << MemberRole.new(:role => role, :inherited_from => id)
+        user_member.save!
+      end
+    end
+  end
+
+  def add_role_to_subprojects
+    member.project.children.each do |subproject|
+      if subproject.inherit_members?
+        child_member = Member.find_or_new(subproject.id, member.user_id)
+        child_member.member_roles << MemberRole.new(:role => role, :inherited_from => id)
+        child_member.save!
+      end
+    end
+  end
+
+  def remove_inherited_roles
+    MemberRole.where(:inherited_from => id).all.group_by(&:member).each do |member, member_roles|
+      member_roles.each(&:destroy)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a6/a6de88a15e59e4df51a2d2faaac586d8b466d19f.svn-base
--- /dev/null
+++ b/.svn/pristine/a6/a6de88a15e59e4df51a2d2faaac586d8b466d19f.svn-base
@@ -0,0 +1,12 @@
+class AddRoadmapPermission < ActiveRecord::Migration
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    Permission.create :controller => "projects", :action => "roadmap", :description => "label_roadmap", :sort => 107, :is_public => true, :mail_option => 0, :mail_enabled => 0
+  end
+
+  def self.down
+    Permission.where("controller=? and action=?", 'projects', 'roadmap').first.destroy
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a721194edc0ad6c9bca0a4d91b6d230d7af19812.svn-base
--- a/.svn/pristine/a7/a721194edc0ad6c9bca0a4d91b6d230d7af19812.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-html template
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a728943093f6831306c2b123cde489f05fdadba9.svn-base
--- a/.svn/pristine/a7/a728943093f6831306c2b123cde489f05fdadba9.svn-base
+++ /dev/null
@@ -1,45 +0,0 @@
-module CodeRay
-module Encoders
-  
-  # Counts the LoC (Lines of Code). Returns an Integer >= 0.
-  # 
-  # Alias: +loc+
-  # 
-  # Everything that is not comment, markup, doctype/shebang, or an empty line,
-  # is considered to be code.
-  # 
-  # For example,
-  # * HTML files not containing JavaScript have 0 LoC
-  # * in a Java class without comments, LoC is the number of non-empty lines
-  # 
-  # A Scanner class should define the token kinds that are not code in the
-  # KINDS_NOT_LOC constant, which defaults to [:comment, :doctype].
-  class LinesOfCode < TokenKindFilter
-    
-    register_for :lines_of_code
-    
-    NON_EMPTY_LINE = /^\s*\S.*$/
-    
-  protected
-    
-    def setup options
-      if scanner
-        kinds_not_loc = scanner.class::KINDS_NOT_LOC
-      else
-        warn "Tokens have no associated scanner, counting all nonempty lines." if $VERBOSE
-        kinds_not_loc = CodeRay::Scanners::Scanner::KINDS_NOT_LOC
-      end
-      
-      options[:exclude] = kinds_not_loc
-      
-      super options
-    end
-    
-    def finish options
-      output @tokens.text.scan(NON_EMPTY_LINE).size
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a757b81e7f3e085496f4684df875891a66fc60e7.svn-base
--- /dev/null
+++ b/.svn/pristine/a7/a757b81e7f3e085496f4684df875891a66fc60e7.svn-base
@@ -0,0 +1,304 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class AccountController < ApplicationController
+  helper :custom_fields
+  include CustomFieldsHelper
+
+  # prevents login action to be filtered by check_if_login_required application scope filter
+  skip_before_filter :check_if_login_required
+
+  # Login request and validation
+  def login
+    if request.get?
+      if User.current.logged?
+        redirect_to home_url
+      end
+    else
+      authenticate_user
+    end
+  rescue AuthSourceException => e
+    logger.error "An error occured when authenticating #{params[:username]}: #{e.message}"
+    render_error :message => e.message
+  end
+
+  # Log out current user and redirect to welcome page
+  def logout
+    if User.current.anonymous?
+      redirect_to home_url
+    elsif request.post?
+      logout_user
+      redirect_to home_url
+    end
+    # display the logout form
+  end
+
+  # Lets user choose a new password
+  def lost_password
+    (redirect_to(home_url); return) unless Setting.lost_password?
+    if params[:token]
+      @token = Token.find_token("recovery", params[:token].to_s)
+      if @token.nil? || @token.expired?
+        redirect_to home_url
+        return
+      end
+      @user = @token.user
+      unless @user && @user.active?
+        redirect_to home_url
+        return
+      end
+      if request.post?
+        @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
+        if @user.save
+          @token.destroy
+          flash[:notice] = l(:notice_account_password_updated)
+          redirect_to signin_path
+          return
+        end
+      end
+      render :template => "account/password_recovery"
+      return
+    else
+      if request.post?
+        user = User.find_by_mail(params[:mail].to_s)
+        # user not found or not active
+        unless user && user.active?
+          flash.now[:error] = l(:notice_account_unknown_email)
+          return
+        end
+        # user cannot change its password
+        unless user.change_password_allowed?
+          flash.now[:error] = l(:notice_can_t_change_password)
+          return
+        end
+        # create a new token for password recovery
+        token = Token.new(:user => user, :action => "recovery")
+        if token.save
+          Mailer.lost_password(token).deliver
+          flash[:notice] = l(:notice_account_lost_email_sent)
+          redirect_to signin_path
+          return
+        end
+      end
+    end
+  end
+
+  # User self-registration
+  def register
+    (redirect_to(home_url); return) unless Setting.self_registration? || session[:auth_source_registration]
+    if request.get?
+      session[:auth_source_registration] = nil
+      @user = User.new(:language => current_language.to_s)
+    else
+      user_params = params[:user] || {}
+      @user = User.new
+      @user.safe_attributes = user_params
+      @user.admin = false
+      @user.register
+      if session[:auth_source_registration]
+        @user.activate
+        @user.login = session[:auth_source_registration][:login]
+        @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
+        if @user.save
+          session[:auth_source_registration] = nil
+          self.logged_user = @user
+          flash[:notice] = l(:notice_account_activated)
+          redirect_to my_account_path
+        end
+      else
+        @user.login = params[:user][:login]
+        unless user_params[:identity_url].present? && user_params[:password].blank? && user_params[:password_confirmation].blank?
+          @user.password, @user.password_confirmation = user_params[:password], user_params[:password_confirmation]
+        end
+
+        case Setting.self_registration
+        when '1'
+          register_by_email_activation(@user)
+        when '3'
+          register_automatically(@user)
+        else
+          register_manually_by_administrator(@user)
+        end
+      end
+    end
+  end
+
+  # Token based account activation
+  def activate
+    (redirect_to(home_url); return) unless Setting.self_registration? && params[:token].present?
+    token = Token.find_token('register', params[:token].to_s)
+    (redirect_to(home_url); return) unless token and !token.expired?
+    user = token.user
+    (redirect_to(home_url); return) unless user.registered?
+    user.activate
+    if user.save
+      token.destroy
+      flash[:notice] = l(:notice_account_activated)
+    end
+    redirect_to signin_path
+  end
+
+  private
+
+  def authenticate_user
+    if Setting.openid? && using_open_id?
+      open_id_authenticate(params[:openid_url])
+    else
+      password_authentication
+    end
+  end
+
+  def password_authentication
+    user = User.try_to_login(params[:username], params[:password])
+
+    if user.nil?
+      invalid_credentials
+    elsif user.new_record?
+      onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
+    else
+      # Valid user
+      successful_authentication(user)
+    end
+  end
+
+  def open_id_authenticate(openid_url)
+    back_url = signin_url(:autologin => params[:autologin])
+
+    authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => back_url, :method => :post) do |result, identity_url, registration|
+      if result.successful?
+        user = User.find_or_initialize_by_identity_url(identity_url)
+        if user.new_record?
+          # Self-registration off
+          (redirect_to(home_url); return) unless Setting.self_registration?
+
+          # Create on the fly
+          user.login = registration['nickname'] unless registration['nickname'].nil?
+          user.mail = registration['email'] unless registration['email'].nil?
+          user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
+          user.random_password
+          user.register
+
+          case Setting.self_registration
+          when '1'
+            register_by_email_activation(user) do
+              onthefly_creation_failed(user)
+            end
+          when '3'
+            register_automatically(user) do
+              onthefly_creation_failed(user)
+            end
+          else
+            register_manually_by_administrator(user) do
+              onthefly_creation_failed(user)
+            end
+          end
+        else
+          # Existing record
+          if user.active?
+            successful_authentication(user)
+          else
+            account_pending
+          end
+        end
+      end
+    end
+  end
+
+  def successful_authentication(user)
+    logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}"
+    # Valid user
+    self.logged_user = user
+    # generate a key and set cookie if autologin
+    if params[:autologin] && Setting.autologin?
+      set_autologin_cookie(user)
+    end
+    call_hook(:controller_account_success_authentication_after, {:user => user })
+    redirect_back_or_default my_page_path
+  end
+
+  def set_autologin_cookie(user)
+    token = Token.create(:user => user, :action => 'autologin')
+    cookie_options = {
+      :value => token.value,
+      :expires => 1.year.from_now,
+      :path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
+      :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
+      :httponly => true
+    }
+    cookies[autologin_cookie_name] = cookie_options
+  end
+
+  # Onthefly creation failed, display the registration form to fill/fix attributes
+  def onthefly_creation_failed(user, auth_source_options = { })
+    @user = user
+    session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
+    render :action => 'register'
+  end
+
+  def invalid_credentials
+    logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
+    flash.now[:error] = l(:notice_account_invalid_creditentials)
+  end
+
+  # Register a user for email activation.
+  #
+  # Pass a block for behavior when a user fails to save
+  def register_by_email_activation(user, &block)
+    token = Token.new(:user => user, :action => "register")
+    if user.save and token.save
+      Mailer.register(token).deliver
+      flash[:notice] = l(:notice_account_register_done)
+      redirect_to signin_path
+    else
+      yield if block_given?
+    end
+  end
+
+  # Automatically register a user
+  #
+  # Pass a block for behavior when a user fails to save
+  def register_automatically(user, &block)
+    # Automatic activation
+    user.activate
+    user.last_login_on = Time.now
+    if user.save
+      self.logged_user = user
+      flash[:notice] = l(:notice_account_activated)
+      redirect_to my_account_path
+    else
+      yield if block_given?
+    end
+  end
+
+  # Manual activation by the administrator
+  #
+  # Pass a block for behavior when a user fails to save
+  def register_manually_by_administrator(user, &block)
+    if user.save
+      # Sends an email to the administrators
+      Mailer.account_activation_request(user).deliver
+      account_pending
+    else
+      yield if block_given?
+    end
+  end
+
+  def account_pending
+    flash[:notice] = l(:notice_account_pending)
+    redirect_to signin_path
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a7710803d5ef1ace984d544cc34e7fc655530e5c.svn-base
--- a/.svn/pristine/a7/a7710803d5ef1ace984d544cc34e7fc655530e5c.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-module CodeRay
-module Encoders
-  
-  load :html
-  
-  # Wraps HTML output into a SPAN element, using inline styles by default.
-  # 
-  # See Encoders::HTML for available options.
-  class Span < HTML
-    
-    FILE_EXTENSION = 'span.html'
-    
-    register_for :span
-    
-    DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
-      :css          => :style,
-      :wrap         => :span,
-      :line_numbers => false
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a771ea7eb3927275538eba94b36787bbcd868180.svn-base
--- a/.svn/pristine/a7/a771ea7eb3927275538eba94b36787bbcd868180.svn-base
+++ /dev/null
@@ -1,718 +0,0 @@
-#!/usr/bin/env ruby
-
-# testtree.rb
-#
-# $Revision: 1.6 $ by $Author: anupamsg $
-# $Name:  $
-#
-# Copyright (c) 2006, 2007 Anupam Sengupta
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# - Redistributions of source code must retain the above copyright notice, this
-#   list of conditions and the following disclaimer.
-#
-# - Redistributions in binary form must reproduce the above copyright notice, this
-#   list of conditions and the following disclaimer in the documentation and/or
-#   other materials provided with the distribution.
-#
-# - Neither the name of the organization nor the names of its contributors may
-#   be used to endorse or promote products derived from this software without
-#   specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-require 'test/unit'
-require 'tree'
-
-module TestTree
-  # Test class for the Tree node.
-  class TestTreeNode < Test::Unit::TestCase
-
-    Person = Struct::new(:First, :last)
-
-    def setup
-      @root = Tree::TreeNode.new("ROOT", "Root Node")
-
-      @child1 = Tree::TreeNode.new("Child1", "Child Node 1")
-      @child2 = Tree::TreeNode.new("Child2", "Child Node 2")
-      @child3 = Tree::TreeNode.new("Child3", "Child Node 3")
-      @child4 = Tree::TreeNode.new("Child31", "Grand Child 1")
-
-    end
-
-    # Create this structure for the tests
-    #
-    #          +----------+
-    #          |  ROOT    |
-    #          +-+--------+
-    #            |
-    #            |    +---------------+
-    #            +----+  CHILD1       |
-    #            |    +---------------+
-    #            |
-    #            |    +---------------+
-    #            +----+  CHILD2       |
-    #            |    +---------------+
-    #            |
-    #            |    +---------------+   +------------------+
-    #            +----+  CHILD3       +---+  CHILD4          |
-    #                 +---------------+   +------------------+
-    #
-    def loadChildren
-      @root << @child1
-      @root << @child2
-      @root << @child3 << @child4
-    end
-
-    def teardown
-      @root = nil
-    end
-
-    def test_root_setup
-      assert_not_nil(@root, "Root cannot be nil")
-      assert_nil(@root.parent, "Parent of root node should be nil")
-      assert_not_nil(@root.name, "Name should not be nil")
-      assert_equal("ROOT", @root.name, "Name should be 'ROOT'")
-      assert_equal("Root Node", @root.content, "Content should be 'Root Node'")
-      assert(@root.isRoot?, "Should identify as root")
-      assert(!@root.hasChildren?, "Cannot have any children")
-      assert(@root.hasContent?, "This root should have content")
-      assert_equal(1, @root.size, "Number of nodes should be one")
-      assert_nil(@root.siblings, "Root cannot have any children")
-
-      assert_raise(RuntimeError) { Tree::TreeNode.new(nil) }
-    end
-
-    def test_root
-      loadChildren
-
-      assert_same(@root, @root.root, "Root's root is self")
-      assert_same(@root, @child1.root, "Root should be ROOT")
-      assert_same(@root, @child4.root, "Root should be ROOT")
-    end
-
-    def test_hasContent_eh
-      aNode = Tree::TreeNode.new("A Node")
-      assert_nil(aNode.content, "The node should not have content")
-      assert(!aNode.hasContent?, "The node should not have content")
-
-      aNode.content = "Something"
-      assert_not_nil(aNode.content, "The node should now have content")
-      assert(aNode.hasContent?, "The node should now have content")
-    end
-
-    def test_length
-      loadChildren
-      assert_equal(@root.size, @root.length, "Length and size methods should return the same result")
-    end
-
-    def test_spaceship          # Test the <=> operator.
-      firstNode  = Tree::TreeNode.new(1)
-      secondNode = Tree::TreeNode.new(2)
-
-      assert_equal(firstNode <=> nil, +1)
-      assert_equal(firstNode <=> secondNode, -1)
-
-      secondNode = Tree::TreeNode.new(1)
-      assert_equal(firstNode <=> secondNode, 0)
-
-      firstNode  = Tree::TreeNode.new("ABC")
-      secondNode = Tree::TreeNode.new("XYZ")
-
-      assert_equal(firstNode <=> nil, +1)
-      assert_equal(firstNode <=> secondNode, -1)
-
-      secondNode = Tree::TreeNode.new("ABC")
-      assert_equal(firstNode <=> secondNode, 0)
-    end
-
-    def test_to_s
-      aNode = Tree::TreeNode.new("A Node", "Some Content")
-
-      expectedString = "Node Name: A Node Content: Some Content Parent: <None> Children: 0 Total Nodes: 1"
-
-      assert_equal(expectedString, aNode.to_s, "The string representation should be same")
-    end
-
-    def test_firstSibling
-      loadChildren
-
-      assert_same(@root, @root.firstSibling, "Root's first sibling is itself")
-      assert_same(@child1, @child1.firstSibling, "Child1's first sibling is itself")
-      assert_same(@child1, @child2.firstSibling, "Child2's first sibling should be child1")
-      assert_same(@child1, @child3.firstSibling, "Child3's first sibling should be child1")
-      assert_not_same(@child1, @child4.firstSibling, "Child4's first sibling is itself")
-    end
-
-    def test_isFirstSibling_eh
-      loadChildren
-
-      assert(@root.isFirstSibling?, "Root's first sibling is itself")
-      assert( @child1.isFirstSibling?, "Child1's first sibling is itself")
-      assert(!@child2.isFirstSibling?, "Child2 is not the first sibling")
-      assert(!@child3.isFirstSibling?, "Child3 is not the first sibling")
-      assert( @child4.isFirstSibling?, "Child4's first sibling is itself")
-    end
-
-    def test_isLastSibling_eh
-      loadChildren
-
-      assert(@root.isLastSibling?, "Root's last sibling is itself")
-      assert(!@child1.isLastSibling?, "Child1 is not the last sibling")
-      assert(!@child2.isLastSibling?, "Child2 is not the last sibling")
-      assert( @child3.isLastSibling?, "Child3's last sibling is itself")
-      assert( @child4.isLastSibling?, "Child4's last sibling is itself")
-    end
-
-    def test_lastSibling
-      loadChildren
-
-      assert_same(@root, @root.lastSibling, "Root's last sibling is itself")
-      assert_same(@child3, @child1.lastSibling, "Child1's last sibling should be child3")
-      assert_same(@child3, @child2.lastSibling, "Child2's last sibling should be child3")
-      assert_same(@child3, @child3.lastSibling, "Child3's last sibling should be itself")
-      assert_not_same(@child3, @child4.lastSibling, "Child4's last sibling is itself")
-    end
-
-    def test_siblings
-      loadChildren
-
-      siblings = []
-      @child1.siblings { |sibling| siblings << sibling}
-      assert_equal(2, siblings.length, "Should have two siblings")
-      assert(siblings.include?(@child2), "Should have 2nd child as sibling")
-      assert(siblings.include?(@child3), "Should have 3rd child as sibling")
-
-      siblings.clear
-      siblings = @child1.siblings
-      assert_equal(2, siblings.length, "Should have two siblings")
-
-      siblings.clear
-      @child4.siblings {|sibling| siblings << sibling}
-      assert(siblings.empty?, "Should not have any children")
-
-    end
-
-    def test_isOnlyChild_eh
-      loadChildren
-
-      assert(!@child1.isOnlyChild?, "Child1 is not the only child")
-      assert(!@child2.isOnlyChild?, "Child2 is not the only child")
-      assert(!@child3.isOnlyChild?, "Child3 is not the only child")
-      assert( @child4.isOnlyChild?, "Child4 is not the only child")
-    end
-
-    def test_nextSibling
-      loadChildren
-
-      assert_equal(@child2, @child1.nextSibling, "Child1's next sibling is Child2")
-      assert_equal(@child3, @child2.nextSibling, "Child2's next sibling is Child3")
-      assert_nil(@child3.nextSibling, "Child3 does not have a next sibling")
-      assert_nil(@child4.nextSibling, "Child4 does not have a next sibling")
-    end
-
-    def test_previousSibling
-      loadChildren
-
-      assert_nil(@child1.previousSibling, "Child1 does not have previous sibling")
-      assert_equal(@child1, @child2.previousSibling, "Child2's previous sibling is Child1")
-      assert_equal(@child2, @child3.previousSibling, "Child3's previous sibling is Child2")
-      assert_nil(@child4.previousSibling, "Child4 does not have a previous sibling")
-    end
-
-    def test_add
-      assert(!@root.hasChildren?, "Should not have any children")
-
-      @root.add(@child1)
-
-      @root << @child2
-
-      assert(@root.hasChildren?, "Should have children")
-      assert_equal(3, @root.size, "Should have three nodes")
-
-      @root << @child3 << @child4
-
-      assert_equal(5, @root.size, "Should have five nodes")
-      assert_equal(2, @child3.size, "Should have two nodes")
-
-      assert_raise(RuntimeError) { @root.add(Tree::TreeNode.new(@child1.name)) }
-
-    end
-
-    def test_remove_bang
-      @root << @child1
-      @root << @child2
-
-      assert(@root.hasChildren?, "Should have children")
-      assert_equal(3, @root.size, "Should have three nodes")
-
-      @root.remove!(@child1)
-      assert_equal(2, @root.size, "Should have two nodes")
-      @root.remove!(@child2)
-
-      assert(!@root.hasChildren?, "Should have no children")
-      assert_equal(1, @root.size, "Should have one node")
-
-      @root << @child1
-      @root << @child2
-
-      assert(@root.hasChildren?, "Should have children")
-      assert_equal(3, @root.size, "Should have three nodes")
-
-      @root.removeAll!
-
-      assert(!@root.hasChildren?, "Should have no children")
-      assert_equal(1, @root.size, "Should have one node")
-
-    end
-
-    def test_removeAll_bang
-      loadChildren
-      assert(@root.hasChildren?, "Should have children")
-      @root.removeAll!
-
-      assert(!@root.hasChildren?, "Should have no children")
-      assert_equal(1, @root.size, "Should have one node")
-    end
-
-    def test_removeFromParent_bang
-      loadChildren
-      assert(@root.hasChildren?, "Should have children")
-      assert(!@root.isLeaf?, "Root is not a leaf here")
-
-      child1 = @root[0]
-      assert_not_nil(child1, "Child 1 should exist")
-      assert_same(@root, child1.root, "Child 1's root should be ROOT")
-      assert(@root.include?(child1), "root should have child1")
-      child1.removeFromParent!
-      assert_same(child1, child1.root, "Child 1's root should be self")
-      assert(!@root.include?(child1), "root should not have child1")
-
-      child1.removeFromParent!
-      assert_same(child1, child1.root, "Child 1's root should still be self")
-    end
-
-    def test_children
-      loadChildren
-
-      assert(@root.hasChildren?, "Should have children")
-      assert_equal(5, @root.size, "Should have four nodes")
-      assert(@child3.hasChildren?, "Should have children")
-      assert(!@child3.isLeaf?, "Should not be a leaf")
-
-      children = []
-      for child in @root.children
-        children << child
-      end
-
-      assert_equal(3, children.length, "Should have three direct children")
-      assert(!children.include?(@root), "Should not have root")
-      assert(children.include?(@child1), "Should have child 1")
-      assert(children.include?(@child2), "Should have child 2")
-      assert(children.include?(@child3), "Should have child 3")
-      assert(!children.include?(@child4), "Should not have child 4")
-
-      children.clear
-      children = @root.children
-      assert_equal(3, children.length, "Should have three children")
-
-    end
-
-    def test_firstChild
-      loadChildren
-
-      assert_equal(@child1, @root.firstChild, "Root's first child is Child1")
-      assert_nil(@child1.firstChild, "Child1 does not have any children")
-      assert_equal(@child4, @child3.firstChild, "Child3's first child is Child4")
-
-    end
-
-    def test_lastChild
-      loadChildren
-
-      assert_equal(@child3, @root.lastChild, "Root's last child is Child3")
-      assert_nil(@child1.lastChild, "Child1 does not have any children")
-      assert_equal(@child4, @child3.lastChild, "Child3's last child is Child4")
-
-    end
-
-    def test_find
-      loadChildren
-      foundNode = @root.find { |node| node == @child2}
-      assert_same(@child2, foundNode, "The node should be Child 2")
-
-      foundNode = @root.find { |node| node == @child4}
-      assert_same(@child4, foundNode, "The node should be Child 4")
-
-      foundNode = @root.find { |node| node.name == "Child31" }
-      assert_same(@child4, foundNode, "The node should be Child 4")
-      foundNode = @root.find { |node| node.name == "NOT PRESENT" }
-      assert_nil(foundNode, "The node should not be found")
-    end
-
-    def test_parentage
-      loadChildren
-
-      assert_nil(@root.parentage, "Root does not have any parentage")
-      assert_equal([@root], @child1.parentage, "Child1 has Root as its parent")
-      assert_equal([@child3, @root], @child4.parentage, "Child4 has Child3 and Root as ancestors")
-    end
-
-    def test_each
-      loadChildren
-      assert(@root.hasChildren?, "Should have children")
-      assert_equal(5, @root.size, "Should have five nodes")
-      assert(@child3.hasChildren?, "Should have children")
-
-      nodes = []
-      @root.each { |node| nodes << node }
-
-      assert_equal(5, nodes.length, "Should have FIVE NODES")
-      assert(nodes.include?(@root), "Should have root")
-      assert(nodes.include?(@child1), "Should have child 1")
-      assert(nodes.include?(@child2), "Should have child 2")
-      assert(nodes.include?(@child3), "Should have child 3")
-      assert(nodes.include?(@child4), "Should have child 4")
-    end
-
-    def test_each_leaf
-      loadChildren
-
-      nodes = []
-      @root.each_leaf { |node| nodes << node }
-
-      assert_equal(3, nodes.length, "Should have THREE LEAF NODES")
-      assert(!nodes.include?(@root), "Should not have root")
-      assert(nodes.include?(@child1), "Should have child 1")
-      assert(nodes.include?(@child2), "Should have child 2")
-      assert(!nodes.include?(@child3), "Should not have child 3")
-      assert(nodes.include?(@child4), "Should have child 4")
-    end
-
-    def test_parent
-      loadChildren
-      assert_nil(@root.parent, "Root's parent should be nil")
-      assert_equal(@root, @child1.parent, "Parent should be root")
-      assert_equal(@root, @child3.parent, "Parent should be root")
-      assert_equal(@child3, @child4.parent, "Parent should be child3")
-      assert_equal(@root, @child4.parent.parent, "Parent should be root")
-    end
-
-    def test_indexed_access
-      loadChildren
-      assert_equal(@child1, @root[0], "Should be the first child")
-      assert_equal(@child4, @root[2][0], "Should be the grandchild")
-      assert_nil(@root["TEST"], "Should be nil")
-      assert_raise(RuntimeError) { @root[nil] }
-    end
-
-    def test_printTree
-      loadChildren
-      #puts
-      #@root.printTree
-    end
-
-    # Tests the binary dumping mechanism with an Object content node
-    def test_marshal_dump
-      # Setup Test Data
-      test_root = Tree::TreeNode.new("ROOT", "Root Node")
-      test_content = {"KEY1" => "Value1", "KEY2" => "Value2" }
-      test_child      = Tree::TreeNode.new("Child", test_content)
-      test_content2 = ["AValue1", "AValue2", "AValue3"]
-      test_grand_child = Tree::TreeNode.new("Grand Child 1", test_content2)
-      test_root << test_child << test_grand_child
-
-      # Perform the test operation
-      data = Marshal.dump(test_root) # Marshal
-      new_root = Marshal.load(data)  # And unmarshal
-
-      # Test the root node
-      assert_equal(test_root.name, new_root.name, "Must identify as ROOT")
-      assert_equal(test_root.content, new_root.content, "Must have root's content")
-      assert(new_root.isRoot?, "Must be the ROOT node")
-      assert(new_root.hasChildren?, "Must have a child node")
-
-      # Test the child node
-      new_child = new_root[test_child.name]
-      assert_equal(test_child.name, new_child.name, "Must have child 1")
-      assert(new_child.hasContent?, "Child must have content")
-      assert(new_child.isOnlyChild?, "Child must be the only child")
-
-      new_child_content = new_child.content
-      assert_equal(Hash, new_child_content.class, "Class of child's content should be a hash")
-      assert_equal(test_child.content.size, new_child_content.size, "The content should have same size")
-
-      # Test the grand-child node
-      new_grand_child = new_child[test_grand_child.name]
-      assert_equal(test_grand_child.name, new_grand_child.name, "Must have grand child")
-      assert(new_grand_child.hasContent?, "Grand-child must have content")
-      assert(new_grand_child.isOnlyChild?, "Grand-child must be the only child")
-
-      new_grand_child_content = new_grand_child.content
-      assert_equal(Array, new_grand_child_content.class, "Class of grand-child's content should be an Array")
-      assert_equal(test_grand_child.content.size, new_grand_child_content.size, "The content should have same size")
-    end
-
-    # marshal_load and marshal_dump are symmetric methods
-    # This alias is for satisfying ZenTest
-    alias test_marshal_load test_marshal_dump
-
-    # Test the collect method from the mixed-in Enumerable functionality.
-    def test_collect
-      loadChildren
-      collectArray = @root.collect do |node|
-        node.content = "abc"
-        node
-      end
-      collectArray.each {|node| assert_equal("abc", node.content, "Should be 'abc'")}
-    end
-
-    # Test freezing the tree
-    def test_freezeTree_bang
-      loadChildren
-      @root.content = "ABC"
-      assert_equal("ABC", @root.content, "Content should be 'ABC'")
-      @root.freezeTree!
-      assert_raise(TypeError) {@root.content = "123"}
-      assert_raise(TypeError) {@root[0].content = "123"}
-    end
-
-    # Test whether the content is accesible
-    def test_content
-      pers = Person::new("John", "Doe")
-      @root.content = pers
-      assert_same(pers, @root.content, "Content should be the same")
-    end
-
-    # Test the depth computation algorithm
-    def test_depth
-      assert_equal(1, @root.depth, "A single node's depth is 1")
-
-      @root << @child1
-      assert_equal(2, @root.depth, "This should be of depth 2")
-
-      @root << @child2
-      assert_equal(2, @root.depth, "This should be of depth 2")
-
-      @child2 << @child3
-      assert_equal(3, @root.depth, "This should be of depth 3")
-      assert_equal(2, @child2.depth, "This should be of depth 2")
-
-      @child3 << @child4
-      assert_equal(4, @root.depth, "This should be of depth 4")
-    end
-
-    # Test the breadth computation algorithm
-    def test_breadth
-      assert_equal(1, @root.breadth, "A single node's breadth is 1")
-
-      @root << @child1
-      assert_equal(1, @root.breadth, "This should be of breadth 1")
-
-      @root << @child2
-      assert_equal(2, @child1.breadth, "This should be of breadth 2")
-      assert_equal(2, @child2.breadth, "This should be of breadth 2")
-
-      @root << @child3
-      assert_equal(3, @child1.breadth, "This should be of breadth 3")
-      assert_equal(3, @child2.breadth, "This should be of breadth 3")
-
-      @child3 << @child4
-      assert_equal(1, @child4.breadth, "This should be of breadth 1")
-    end
-
-    # Test the breadth for each
-    def test_breadth_each
-      j = Tree::TreeNode.new("j")
-      f = Tree::TreeNode.new("f")
-      k = Tree::TreeNode.new("k")
-      a = Tree::TreeNode.new("a")
-      d = Tree::TreeNode.new("d")
-      h = Tree::TreeNode.new("h")
-      z = Tree::TreeNode.new("z")
-
-      # The expected order of response
-      expected_array = [j,
-                        f, k,
-                        a, h, z,
-                        d]
-
-      # Create the following Tree
-      #        j         <-- level 0 (Root)
-      #      /   \
-      #     f      k     <-- level 1
-      #   /   \      \
-      #  a     h      z  <-- level 2
-      #   \
-      #    d             <-- level 3
-      j << f << a << d
-      f << h
-      j << k << z
-
-      # Create the response
-      result_array = Array.new
-      j.breadth_each { |node| result_array << node.detached_copy }
-
-      expected_array.each_index do |i|
-        assert_equal(expected_array[i].name, result_array[i].name)      # Match only the names.
-      end
-    end
-
-
-    def test_preordered_each
-      j = Tree::TreeNode.new("j")
-      f = Tree::TreeNode.new("f")
-      k = Tree::TreeNode.new("k")
-      a = Tree::TreeNode.new("a")
-      d = Tree::TreeNode.new("d")
-      h = Tree::TreeNode.new("h")
-      z = Tree::TreeNode.new("z")
-
-      # The expected order of response
-      expected_array = [j, f, a, d, h, k, z]
-
-      # Create the following Tree
-      #        j         <-- level 0 (Root)
-      #      /   \
-      #     f      k     <-- level 1
-      #   /   \      \
-      #  a     h      z  <-- level 2
-      #   \
-      #    d             <-- level 3
-      j << f << a << d
-      f << h
-      j << k << z
-
-      result_array = []
-      j.preordered_each { |node| result_array << node.detached_copy}
-
-      expected_array.each_index do |i|
-        # Match only the names.
-        assert_equal(expected_array[i].name, result_array[i].name)
-      end
-    end
-
-    def test_detached_copy
-      loadChildren
-
-      assert(@root.hasChildren?, "The root should have children")
-      copy_of_root = @root.detached_copy
-      assert(!copy_of_root.hasChildren?, "The copy should not have children")
-      assert_equal(@root.name, copy_of_root.name, "The names should be equal")
-
-      # Try the same test with a child node
-      assert(!@child3.isRoot?, "Child 3 is not a root")
-      assert(@child3.hasChildren?, "Child 3 has children")
-      copy_of_child3 = @child3.detached_copy
-      assert(copy_of_child3.isRoot?, "Child 3's copy is a root")
-      assert(!copy_of_child3.hasChildren?, "Child 3's copy does not have children")
-    end
-
-    def test_hasChildren_eh
-      loadChildren
-      assert(@root.hasChildren?, "The Root node MUST have children")
-    end
-
-    def test_isLeaf_eh
-      loadChildren
-      assert(!@child3.isLeaf?, "Child 3 is not a leaf node")
-      assert(@child4.isLeaf?, "Child 4 is a leaf node")
-    end
-
-    def test_isRoot_eh
-      loadChildren
-      assert(@root.isRoot?, "The ROOT node must respond as the root node")
-    end
-
-    def test_content_equals
-      @root.content = nil
-      assert_nil(@root.content, "Root's content should be nil")
-      @root.content = "ABCD"
-      assert_equal("ABCD", @root.content, "Root's content should now be 'ABCD'")
-    end
-
-    def test_size
-      assert_equal(1, @root.size, "Root's size should be 1")
-      loadChildren
-      assert_equal(5, @root.size, "Root's size should be 5")
-      assert_equal(2, @child3.size, "Child 3's size should be 2")
-    end
-
-    def test_lt2                # Test the << method
-      @root << @child1
-      @root << @child2
-      @root << @child3 << @child4
-      assert_not_nil(@root['Child1'], "Child 1 should have been added to Root")
-      assert_not_nil(@root['Child2'], "Child 2 should have been added to Root")
-      assert_not_nil(@root['Child3'], "Child 3 should have been added to Root")
-      assert_not_nil(@child3['Child31'], "Child 31 should have been added to Child3")
-    end
-
-    def test_index              #  Test the [] method
-      assert_raise(RuntimeError) {@root[nil]}
-
-      @root << @child1
-      @root << @child2
-      assert_equal(@child1.name, @root['Child1'].name, "Child 1 should be returned")
-      assert_equal(@child1.name, @root[0].name, "Child 1 should be returned")
-      assert_equal(@child2.name, @root['Child2'].name, "Child 2 should be returned")
-      assert_equal(@child2.name, @root[1].name, "Child 2 should be returned")
-
-      assert_nil(@root['Some Random Name'], "Should return nil")
-      assert_nil(@root[99], "Should return nil")
-    end
-  end
-end
-
-__END__
-
-# $Log: test_tree.rb,v $
-# Revision 1.6  2007/12/22 00:28:59  anupamsg
-# Added more test cases, and enabled ZenTest compatibility.
-#
-# Revision 1.5  2007/12/19 02:24:18  anupamsg
-# Updated the marshalling logic to handle non-string contents on the nodes.
-#
-# Revision 1.4  2007/10/02 03:38:11  anupamsg
-# Removed dependency on the redundant "Person" class.
-# (TC_TreeTest::test_comparator): Added a new test for the spaceship operator.
-# (TC_TreeTest::test_hasContent): Added tests for hasContent? and length methods.
-#
-# Revision 1.3  2007/10/02 03:07:30  anupamsg
-# * Rakefile: Added an optional task for rcov code coverage.
-#
-# * test/test_binarytree.rb: Removed the unnecessary dependency on "Person" class.
-#
-# * test/test_tree.rb: Removed dependency on the redundant "Person" class.
-#
-# Revision 1.2  2007/08/31 01:16:28  anupamsg
-# Added breadth and pre-order traversals for the tree. Also added a method
-# to return the detached copy of a node from the tree.
-#
-# Revision 1.1  2007/07/21 04:52:38  anupamsg
-# Renamed the test files.
-#
-# Revision 1.13  2007/07/18 22:11:50  anupamsg
-# Added depth and breadth methods for the TreeNode.
-#
-# Revision 1.12  2007/07/18 07:17:34  anupamsg
-# Fixed a  issue where TreeNode.ancestors was shadowing Module.ancestors. This method
-# has been renamed to TreeNode.parentage.
-#
-# Revision 1.11  2007/07/17 03:39:29  anupamsg
-# Moved the CVS Log keyword to end of the files.
-#
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a78d8c38b2c0e165e9024e9e381ec35f7932fcbf.svn-base
--- a/.svn/pristine/a7/a78d8c38b2c0e165e9024e9e381ec35f7932fcbf.svn-base
+++ /dev/null
@@ -1,1027 +0,0 @@
-# Turkish translations for Ruby on Rails
-# by Ozgun Ataman (ozataman@gmail.com)
-# by Burak Yigit Kaya (ben@byk.im)
-
-tr:
-  locale:
-    native_name: TÃ¼rkÃ§e
-    address_separator: " "
-  direction: ltr
-  date:
-    formats:
-      default: "%d.%m.%Y"
-      numeric: "%d.%m.%Y"
-      short: "%e %b"
-      long: "%e %B %Y, %A"
-      only_day: "%e"
-
-    day_names: [Pazar, Pazartesi, SalÄ±, Ã‡arÅŸamba, PerÅŸembe, Cuma, Cumartesi]
-    abbr_day_names: [Pzr, Pzt, Sal, Ã‡rÅŸ, PrÅŸ, Cum, Cts]
-    month_names: [~, Ocak, Åžubat, Mart, Nisan, MayÄ±s, Haziran, Temmuz, AÄŸustos, EylÃ¼l, Ekim, KasÄ±m, AralÄ±k]
-    abbr_month_names: [~, Oca, Åžub, Mar, Nis, May, Haz, Tem, AÄŸu, Eyl, Eki, Kas, Ara]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%a %d.%b.%y %H:%M"
-      numeric: "%d.%b.%y %H:%M"
-      short: "%e %B, %H:%M"
-      long: "%e %B %Y, %A, %H:%M"
-      time: "%H:%M"
-
-    am: "Ã¶ÄŸleden Ã¶nce"
-    pm: "Ã¶ÄŸleden sonra"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: 'yarÄ±m dakika'
-      less_than_x_seconds:
-        zero: '1 saniyeden az'
-        one: '1 saniyeden az'
-        other: '%{count} saniyeden az'
-      x_seconds:
-        one: '1 saniye'
-        other: '%{count} saniye'
-      less_than_x_minutes:
-        zero: '1 dakikadan az'
-        one: '1 dakikadan az'
-        other: '%{count} dakikadan az'
-      x_minutes:
-        one: '1 dakika'
-        other: '%{count} dakika'
-      about_x_hours:
-        one: 'yaklaÅŸÄ±k 1 saat'
-        other: 'yaklaÅŸÄ±k %{count} saat'
-      x_days:
-        one: '1 gÃ¼n'
-        other: '%{count} gÃ¼n'
-      about_x_months:
-        one: 'yaklaÅŸÄ±k 1 ay'
-        other: 'yaklaÅŸÄ±k %{count} ay'
-      x_months:
-        one: '1 ay'
-        other: '%{count} ay'
-      about_x_years:
-        one: 'yaklaÅŸÄ±k 1 yÄ±l'
-        other: 'yaklaÅŸÄ±k %{count} yÄ±l'
-      over_x_years:
-        one: '1 yÄ±ldan fazla'
-        other: '%{count} yÄ±ldan fazla'
-      almost_x_years:
-        one:   "neredeyse 1 YÄ±l"
-        other: "neredeyse %{count} yÄ±l"
-
-  number:
-    format:
-      precision: 2
-      separator: ','
-      delimiter: '.'
-    currency:
-      format:
-        unit: 'TRY'
-        format: '%n%u'
-        separator: ','
-        delimiter: '.'
-        precision: 2
-    percentage:
-      format:
-        delimiter: '.'
-        separator: ','
-        precision: 2
-    precision:
-      format:
-        delimiter: '.'
-        separator: ','
-    human:
-      format:
-        delimiter: '.'
-        separator: ','
-        precision: 2
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Byte"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  support:
-    array:
-      sentence_connector: "ve"
-      skip_last_comma: true
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "%{model} giriÅŸi kaydedilemedi: 1 hata."
-          other:  "%{model} giriÅŸi kadedilemedi: %{count} hata."
-        body: "LÃ¼tfen aÅŸaÄŸÄ±daki hatalarÄ± dÃ¼zeltiniz:"
-
-      messages:
-        inclusion: "kabul edilen bir kelime deÄŸil"
-        exclusion: "kullanÄ±lamaz"
-        invalid: "geÃ§ersiz"
-        confirmation: "teyidi uyuÅŸmamakta"
-        accepted: "kabul edilmeli"
-        empty: "doldurulmalÄ±"
-        blank: "doldurulmalÄ±"
-        too_long: "Ã§ok uzun (en fazla %{count} karakter)"
-        too_short: "Ã§ok kÄ±sa (en az %{count} karakter)"
-        wrong_length: "yanlÄ±ÅŸ uzunlukta (tam olarak %{count} karakter olmalÄ±)"
-        taken: "hali hazÄ±rda kullanÄ±lmakta"
-        not_a_number: "geÃ§erli bir sayÄ± deÄŸil"
-        greater_than: "%{count} sayÄ±sÄ±ndan bÃ¼yÃ¼k olmalÄ±"
-        greater_than_or_equal_to: "%{count} sayÄ±sÄ±na eÅŸit veya bÃ¼yÃ¼k olmalÄ±"
-        equal_to: "tam olarak %{count} olmalÄ±"
-        less_than: "%{count} sayÄ±sÄ±ndan kÃ¼Ã§Ã¼k olmalÄ±"
-        less_than_or_equal_to: "%{count} sayÄ±sÄ±na eÅŸit veya kÃ¼Ã§Ã¼k olmalÄ±"
-        odd: "tek olmalÄ±"
-        even: "Ã§ift olmalÄ±"
-        greater_than_start_date: "baÅŸlangÄ±Ã§ tarihinden bÃ¼yÃ¼k olmalÄ±"
-        not_same_project: "aynÄ± projeye ait deÄŸil"
-        circular_dependency: "Bu iliÅŸki dÃ¶ngÃ¼sel baÄŸÄ±mlÄ±lÄ±k meydana getirecektir"
-        cant_link_an_issue_with_a_descendant: "Bir iÅŸ, alt iÅŸlerinden birine baÄŸlanamaz"
-      models:
-
-  actionview_instancetag_blank_option: LÃ¼tfen SeÃ§in
-
-  general_text_No: 'HayÄ±r'
-  general_text_Yes: 'Evet'
-  general_text_no: 'hayÄ±r'
-  general_text_yes: 'evet'
-  general_lang_name: 'TÃ¼rkÃ§e'
-  general_csv_separator: ','
-  general_csv_encoding: ISO-8859-9
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '7'
-
-  notice_account_updated: Hesap baÅŸarÄ±yla gÃ¼ncelleÅŸtirildi.
-  notice_account_invalid_creditentials: GeÃ§ersiz kullanÄ±cÄ± ya da parola
-  notice_account_password_updated: Parola baÅŸarÄ±yla gÃ¼ncellendi.
-  notice_account_wrong_password: YanlÄ±ÅŸ parola
-  notice_account_register_done: Hesap baÅŸarÄ±yla oluÅŸturuldu. HesabÄ±nÄ±zÄ± etkinleÅŸtirmek iÃ§in, size gÃ¶nderilen e-postadaki baÄŸlantÄ±ya tÄ±klayÄ±n.
-  notice_account_unknown_email: TanÄ±nmayan kullanÄ±cÄ±.
-  notice_can_t_change_password: Bu hesap harici bir denetim kaynaÄŸÄ± kullanÄ±yor. ParolayÄ± deÄŸiÅŸtirmek mÃ¼mkÃ¼n deÄŸil.
-  notice_account_lost_email_sent: Yeni parola seÃ§me talimatlarÄ±nÄ± iÃ§eren e-postanÄ±z gÃ¶nderildi.
-  notice_account_activated: HesabÄ±nÄ±z etkinleÅŸtirildi. Åžimdi giriÅŸ yapabilirsiniz.
-  notice_successful_create: BaÅŸarÄ±yla oluÅŸturuldu.
-  notice_successful_update: BaÅŸarÄ±yla gÃ¼ncellendi.
-  notice_successful_delete: BaÅŸarÄ±yla silindi.
-  notice_successful_connection: BaÄŸlantÄ± baÅŸarÄ±lÄ±.
-  notice_file_not_found: EriÅŸmek istediÄŸiniz sayfa mevcut deÄŸil ya da kaldÄ±rÄ±lmÄ±ÅŸ.
-  notice_locking_conflict: Veri baÅŸka bir kullanÄ±cÄ± tarafÄ±ndan gÃ¼ncellendi.
-  notice_not_authorized: Bu sayfaya eriÅŸme yetkiniz yok.
-  notice_email_sent: "E-posta gÃ¶nderildi %{value}"
-  notice_email_error: "E-posta gÃ¶nderilirken bir hata oluÅŸtu (%{value})"
-  notice_feeds_access_key_reseted: RSS eriÅŸim anahtarÄ±nÄ±z sÄ±fÄ±rlandÄ±.
-  notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
-  notice_no_issue_selected: "SeÃ§ili iÅŸ yok! LÃ¼tfen, dÃ¼zenlemek istediÄŸiniz iÅŸleri iÅŸaretleyin."
-  notice_account_pending: "HesabÄ±nÄ±z oluÅŸturuldu ve yÃ¶netici onayÄ± bekliyor."
-  notice_default_data_loaded: VarasayÄ±lan konfigÃ¼rasyon baÅŸarÄ±lÄ±yla yÃ¼klendi.
-
-  error_can_t_load_default_data: "VarsayÄ±lan konfigÃ¼rasyon yÃ¼klenemedi: %{value}"
-  error_scm_not_found: "Depoda, giriÅŸ ya da deÄŸiÅŸiklik yok."
-  error_scm_command_failed: "Depoya eriÅŸmeye Ã§alÄ±ÅŸÄ±rken bir hata meydana geldi: %{value}"
-  error_scm_annotate: "GiriÅŸ mevcut deÄŸil veya izah edilemedi."
-  error_issue_not_found_in_project: 'Ä°ÅŸ bilgisi bulunamadÄ± veya bu projeye ait deÄŸil'
-
-  mail_subject_lost_password: "ParolanÄ±z %{value}"
-  mail_body_lost_password: 'ParolanÄ±zÄ± deÄŸiÅŸtirmek iÃ§in, aÅŸaÄŸÄ±daki baÄŸlantÄ±ya tÄ±klayÄ±n:'
-  mail_subject_register: "%{value} hesap aktivasyonu"
-  mail_body_register: 'HesabÄ±nÄ±zÄ± etkinleÅŸtirmek iÃ§in, aÅŸaÄŸÄ±daki baÄŸlantÄ±ya tÄ±klayÄ±n:'
-  mail_body_account_information_external: "HesabÄ±nÄ±zÄ± %{value} giriÅŸ yapmak iÃ§in kullanabilirsiniz."
-  mail_body_account_information: Hesap bilgileriniz
-  mail_subject_account_activation_request: "%{value} hesabÄ± etkinleÅŸtirme isteÄŸi"
-  mail_body_account_activation_request: "Yeni bir kullanÄ±cÄ± (%{value}) kaydedildi. Hesap onaylanmayÄ± bekliyor:"
-
-  gui_validation_error: 1 hata
-  gui_validation_error_plural: "%{count} hata"
-
-  field_name: Ä°sim
-  field_description: Yorum
-  field_summary: Ã–zet
-  field_is_required: Gerekli
-  field_firstname: Ad
-  field_lastname: Soyad
-  field_mail: E-Posta
-  field_filename: Dosya
-  field_filesize: Boyut
-  field_downloads: Ä°ndirilenler
-  field_author: Yazar
-  field_created_on: OluÅŸturulma
-  field_updated_on: GÃ¼ncellenme
-  field_field_format: BiÃ§im
-  field_is_for_all: TÃ¼m projeler iÃ§in
-  field_possible_values: KullanÄ±labilir deÄŸerler
-  field_regexp: DÃ¼zenli ifadeler
-  field_min_length: En az uzunluk
-  field_max_length: En Ã§ok uzunluk
-  field_value: DeÄŸer
-  field_category: Kategori
-  field_title: BaÅŸlÄ±k
-  field_project: Proje
-  field_issue: Ä°ÅŸ
-  field_status: Durum
-  field_notes: Notlar
-  field_is_closed: Ä°ÅŸ kapatÄ±ldÄ±
-  field_is_default: VarsayÄ±lan DeÄŸer
-  field_tracker: Ä°ÅŸ tipi
-  field_subject: Konu
-  field_due_date: BitiÅŸ Tarihi
-  field_assigned_to: Atanan
-  field_priority: Ã–ncelik
-  field_fixed_version: Hedef SÃ¼rÃ¼m
-  field_user: KullanÄ±cÄ±
-  field_role: Rol
-  field_homepage: Anasayfa
-  field_is_public: Genel
-  field_parent: 'Ãœst proje: '
-  field_is_in_roadmap: Yol haritasÄ±nda gÃ¶sterilen iÅŸler
-  field_login: GiriÅŸ
-  field_mail_notification: E-posta uyarÄ±larÄ±
-  field_admin: YÃ¶netici
-  field_last_login_on: Son BaÄŸlantÄ±
-  field_language: Dil
-  field_effective_date: Tarih
-  field_password: Parola
-  field_new_password: Yeni Parola
-  field_password_confirmation: Onay
-  field_version: SÃ¼rÃ¼m
-  field_type: Tip
-  field_host: Host
-  field_port: Port
-  field_account: Hesap
-  field_base_dn: Base DN
-  field_attr_login: GiriÅŸ NiteliÄŸi
-  field_attr_firstname: Ad NiteliÄŸi
-  field_attr_lastname: Soyad NiteliÄŸi
-  field_attr_mail: E-Posta NiteliÄŸi
-  field_onthefly: AnÄ±nda kullanÄ±cÄ± oluÅŸturma
-  field_start_date: BaÅŸlangÄ±Ã§ Tarihi
-  field_done_ratio: Tamamlanma yÃ¼zdesi
-  field_auth_source: Kimlik Denetim Modu
-  field_hide_mail: E-posta adresimi gizle
-  field_comments: Yorumlar
-  field_url: URL
-  field_start_page: BaÅŸlangÄ±Ã§ SayfasÄ±
-  field_subproject: Alt Proje
-  field_hours: Saat
-  field_activity: Etkinlik
-  field_spent_on: Tarih
-  field_identifier: TanÄ±mlayÄ±cÄ±
-  field_is_filter: filtre olarak kullanÄ±lmÄ±ÅŸ
-  field_issue_to: Ä°liÅŸkili iÅŸ
-  field_delay: Gecikme
-  field_assignable: Bu role atanabilecek iÅŸler
-  field_redirect_existing_links: Mevcut baÄŸlantÄ±larÄ± yÃ¶nlendir
-  field_estimated_hours: Kalan zaman
-  field_column_names: SÃ¼tunlar
-  field_time_zone: Saat dilimi
-  field_searchable: Aranabilir
-  field_default_value: VarsayÄ±lan deÄŸer
-  field_comments_sorting: YorumlarÄ± gÃ¶ster
-
-  setting_app_title: Uygulama BaÄŸlÄ±ÄŸÄ±
-  setting_app_subtitle: Uygulama alt baÅŸlÄ±ÄŸÄ±
-  setting_welcome_text: HoÅŸgeldin MesajÄ±
-  setting_default_language: VarsayÄ±lan Dil
-  setting_login_required: Kimlik denetimi gerekli mi
-  setting_self_registration: Otomatik kayÄ±t
-  setting_attachment_max_size: Maksimum ek boyutu
-  setting_issues_export_limit: Ä°ÅŸlerin dÄ±ÅŸa aktarÄ±lma sÄ±nÄ±rÄ±
-  setting_mail_from: GÃ¶nderici e-posta adresi
-  setting_bcc_recipients: AlÄ±cÄ±larÄ± birbirinden gizle (bcc)
-  setting_host_name: Host adÄ±
-  setting_text_formatting: Metin biÃ§imi
-  setting_wiki_compression: Wiki geÃ§miÅŸini sÄ±kÄ±ÅŸtÄ±r
-  setting_feeds_limit: Haber yayÄ±nÄ± iÃ§erik limiti
-  setting_default_projects_public: Yeni projeler varsayÄ±lan olarak herkese aÃ§Ä±k
-  setting_autofetch_changesets: Otomatik gÃ¶nderi al
-  setting_sys_api_enabled: Depo yÃ¶netimi iÃ§in WS'yi etkinleÅŸtir
-  setting_commit_ref_keywords: BaÅŸvuru Kelimeleri
-  setting_commit_fix_keywords: Sabitleme kelimeleri
-  setting_autologin: Otomatik GiriÅŸ
-  setting_date_format: Tarih Formati
-  setting_time_format: Zaman FormatÄ±
-  setting_cross_project_issue_relations: Ã‡apraz-Proje iÅŸ iliÅŸkilendirmesine izin ver
-  setting_issue_list_default_columns: Ä°ÅŸ listesinde gÃ¶sterilen varsayÄ±lan sÃ¼tunlar
-  setting_emails_footer: E-posta dip not
-  setting_protocol: Protokol
-  setting_per_page_options: Sayfada baÅŸÄ±na Ã¶ÄŸe sayÄ±sÄ±
-  setting_user_format: KullanÄ±cÄ± gÃ¶sterim biÃ§imi
-  setting_activity_days_default: Proje etkinliklerinde gÃ¶sterilen gÃ¼n sayÄ±sÄ±
-  setting_display_subprojects_issues: VarsayÄ±lan olarak ana projenin iÅŸ listesinde alt proje iÅŸlerini gÃ¶ster
-
-  project_module_issue_tracking: Ä°ÅŸ Takibi
-  project_module_time_tracking: Zaman Takibi
-  project_module_news: Haberler
-  project_module_documents: Belgeler
-  project_module_files: Dosyalar
-  project_module_wiki: Wiki
-  project_module_repository: Depo
-  project_module_boards: TartÄ±ÅŸma AlanÄ±
-
-  label_user: KullanÄ±cÄ±
-  label_user_plural: KullanÄ±cÄ±lar
-  label_user_new: Yeni KullanÄ±cÄ±
-  label_project: Proje
-  label_project_new: Yeni proje
-  label_project_plural: Projeler
-  label_x_projects:
-    zero:  hiÃ§ proje yok
-    one:   1 proje
-    other: "%{count} proje"
-  label_project_all: TÃ¼m Projeler
-  label_project_latest: En son projeler
-  label_issue: Ä°ÅŸ
-  label_issue_new: Yeni Ä°ÅŸ
-  label_issue_plural: Ä°ÅŸler
-  label_issue_view_all: TÃ¼m iÅŸleri izle
-  label_issues_by: "%{value} tarafÄ±ndan gÃ¶nderilmiÅŸ iÅŸler"
-  label_issue_added: Ä°ÅŸ eklendi
-  label_issue_updated: Ä°ÅŸ gÃ¼ncellendi
-  label_document: Belge
-  label_document_new: Yeni belge
-  label_document_plural: Belgeler
-  label_document_added: Belge eklendi
-  label_role: Rol
-  label_role_plural: Roller
-  label_role_new: Yeni rol
-  label_role_and_permissions: Roller ve izinler
-  label_member: Ãœye
-  label_member_new: Yeni Ã¼ye
-  label_member_plural: Ãœyeler
-  label_tracker: Ä°ÅŸ tipi
-  label_tracker_plural: Ä°ÅŸ tipleri
-  label_tracker_new: Yeni iÅŸ tipi
-  label_workflow: Ä°ÅŸ akÄ±ÅŸÄ±
-  label_issue_status: Ä°ÅŸ durumu
-  label_issue_status_plural: Ä°ÅŸ durumularÄ±
-  label_issue_status_new: Yeni durum
-  label_issue_category: Ä°ÅŸ kategorisi
-  label_issue_category_plural: Ä°ÅŸ kategorileri
-  label_issue_category_new: Yeni kategori
-  label_custom_field: Ã–zel alan
-  label_custom_field_plural: Ã–zel alanlar
-  label_custom_field_new: Yeni Ã¶zel alan
-  label_enumerations: NumaralandÄ±rmalar
-  label_enumeration_new: Yeni deÄŸer
-  label_information: Bilgi
-  label_information_plural: Bilgi
-  label_please_login: LÃ¼tfen giriÅŸ yapÄ±n
-  label_register: KayÄ±t
-  label_password_lost: ParolamÄ± unuttum
-  label_home: Anasayfa
-  label_my_page: KiÅŸisel Sayfam
-  label_my_account: HesabÄ±m
-  label_my_projects: Projelerim
-  label_administration: YÃ¶netim
-  label_login: GiriÅŸ
-  label_logout: Ã‡Ä±kÄ±ÅŸ
-  label_help: YardÄ±m
-  label_reported_issues: Rapor edilmiÅŸ iÅŸler
-  label_assigned_to_me_issues: Bana atanmÄ±ÅŸ iÅŸler
-  label_last_login: Son baÄŸlantÄ±
-  label_registered_on: KayÄ±t tarihi
-  label_activity: Etkinlik
-  label_overall_activity: TÃ¼m etkinlikler
-  label_new: Yeni
-  label_logged_as: "KullanÄ±cÄ± :"
-  label_environment: Ã‡evre
-  label_authentication: Kimlik Denetimi
-  label_auth_source: Kimlik Denetim Modu
-  label_auth_source_new: Yeni Denetim Modu
-  label_auth_source_plural: Denetim ModlarÄ±
-  label_subproject_plural: Alt Projeler
-  label_min_max_length: Min - Maks uzunluk
-  label_list: Liste
-  label_date: Tarih
-  label_integer: Tam sayÄ±
-  label_float: OndalÄ±klÄ± sayÄ±
-  label_boolean: "Evet/HayÄ±r"
-  label_string: Metin
-  label_text: Uzun Metin
-  label_attribute: Nitelik
-  label_attribute_plural: Nitelikler
-  label_download: "%{count} indirme"
-  label_download_plural: "%{count} indirme"
-  label_no_data: GÃ¶sterilecek veri yok
-  label_change_status: DeÄŸiÅŸim Durumu
-  label_history: GeÃ§miÅŸ
-  label_attachment: Dosya
-  label_attachment_new: Yeni Dosya
-  label_attachment_delete: DosyayÄ± Sil
-  label_attachment_plural: Dosyalar
-  label_file_added: Eklenen Dosyalar
-  label_report: Rapor
-  label_report_plural: Raporlar
-  label_news: Haber
-  label_news_new: Haber ekle
-  label_news_plural: Haber
-  label_news_latest: Son Haberler
-  label_news_view_all: TÃ¼m haberleri oku
-  label_news_added: Haber eklendi
-  label_settings: Ayarlar
-  label_overview: Genel
-  label_version: SÃ¼rÃ¼m
-  label_version_new: Yeni sÃ¼rÃ¼m
-  label_version_plural: SÃ¼rÃ¼mler
-  label_confirmation: DoÄŸrulamama
-  label_export_to: "DiÄŸer uygun kaynaklar:"
-  label_read: "Oku..."
-  label_public_projects: Genel Projeler
-  label_open_issues: aÃ§Ä±k
-  label_open_issues_plural: aÃ§Ä±k
-  label_closed_issues: kapalÄ±
-  label_closed_issues_plural: kapalÄ±
-  label_x_open_issues_abbr_on_total:
-    zero:  tamamÄ± kapalÄ±, toplam %{total}
-    one:   1'i' aÃ§Ä±k, toplam %{total}
-    other: "%{count} aÃ§Ä±k, toplam %{total}"
-  label_x_open_issues_abbr:
-    zero:  hiÃ§ aÃ§Ä±k yok
-    one:   1 aÃ§Ä±k
-    other: "%{count} aÃ§Ä±k"
-  label_x_closed_issues_abbr:
-    zero:  hiÃ§ kapalÄ± yok
-    one:   1 kapalÄ±
-    other: "%{count} kapalÄ±"
-  label_total: Toplam
-  label_permissions: Ä°zinler
-  label_current_status: Mevcut Durum
-  label_new_statuses_allowed: Yeni durumlara izin verildi
-  label_all: Hepsi
-  label_none: HiÃ§biri
-  label_nobody: HiÃ§kimse
-  label_next: Sonraki
-  label_previous: Ã–nceki
-  label_used_by: 'Kullanan: '
-  label_details: AyrÄ±ntÄ±lar
-  label_add_note: Not ekle
-  label_per_page: Sayfa baÅŸÄ±na
-  label_calendar: Takvim
-  label_months_from: ay Ã¶ncesinden itibaren
-  label_gantt: Ä°ÅŸ-Zaman Ã‡izelgesi
-  label_internal: Dahili
-  label_last_changes: "Son %{count} deÄŸiÅŸiklik"
-  label_change_view_all: TÃ¼m DeÄŸiÅŸiklikleri gÃ¶r
-  label_personalize_page: Bu sayfayÄ± kiÅŸiselleÅŸtir
-  label_comment: Yorum
-  label_comment_plural: Yorumlar
-  label_x_comments:
-    zero: hiÃ§ yorum yok
-    one: 1 yorum
-    other: "%{count} yorum"
-  label_comment_add: Yorum Ekle
-  label_comment_added: Yorum Eklendi
-  label_comment_delete: YorumlarÄ± sil
-  label_query: Ã–zel Sorgu
-  label_query_plural: Ã–zel Sorgular
-  label_query_new: Yeni Sorgu
-  label_filter_add: Filtre ekle
-  label_filter_plural: Filtreler
-  label_equals: EÅŸit
-  label_not_equals: EÅŸit deÄŸil
-  label_in_less_than: kÃ¼Ã§Ã¼ktÃ¼r
-  label_in_more_than: bÃ¼yÃ¼ktÃ¼r
-  label_in: iÃ§inde
-  label_today: bugÃ¼n
-  label_all_time: TÃ¼m Zamanlar
-  label_yesterday: DÃ¼n
-  label_this_week: Bu hafta
-  label_last_week: GeÃ§en hafta
-  label_last_n_days: "Son %{count} gÃ¼n"
-  label_this_month: Bu ay
-  label_last_month: GeÃ§en ay
-  label_this_year: Bu yÄ±l
-  label_date_range: Tarih aralÄ±ÄŸÄ±
-  label_less_than_ago: gÃ¼nler Ã¶ncesinden az
-  label_more_than_ago: gÃ¼nler Ã¶ncesinden fazla
-  label_ago: gÃ¼n Ã¶nce
-  label_contains: iÃ§eriyor
-  label_not_contains: iÃ§ermiyor
-  label_day_plural: GÃ¼nler
-  label_repository: Depo
-  label_repository_plural: Depolar
-  label_browse: GÃ¶zat
-  label_modification: "%{count} deÄŸiÅŸim"
-  label_modification_plural: "%{count} deÄŸiÅŸim"
-  label_revision: DeÄŸiÅŸiklik
-  label_revision_plural: DeÄŸiÅŸiklikler
-  label_associated_revisions: BirleÅŸtirilmiÅŸ deÄŸiÅŸiklikler
-  label_added: eklendi
-  label_modified: gÃ¼ncellendi
-  label_deleted: silindi
-  label_latest_revision: En son deÄŸiÅŸiklik
-  label_latest_revision_plural: En son deÄŸiÅŸiklikler
-  label_view_revisions: DeÄŸiÅŸiklikleri izle
-  label_max_size: En bÃ¼yÃ¼k boyut
-  label_sort_highest: Ãœste taÅŸÄ±
-  label_sort_higher: YukarÄ± taÅŸÄ±
-  label_sort_lower: AÅŸaÄŸÄ± taÅŸÄ±
-  label_sort_lowest: Dibe taÅŸÄ±
-  label_roadmap: Yol HaritasÄ±
-  label_roadmap_due_in: "%{value} iÃ§inde bitmeli"
-  label_roadmap_overdue: "%{value} geÃ§"
-  label_roadmap_no_issues: Bu sÃ¼rÃ¼m iÃ§in iÅŸ yok
-  label_search: Ara
-  label_result_plural: SonuÃ§lar
-  label_all_words: TÃ¼m Kelimeler
-  label_wiki: Wiki
-  label_wiki_edit: Wiki dÃ¼zenleme
-  label_wiki_edit_plural: Wiki dÃ¼zenlemeleri
-  label_wiki_page: Wiki sayfasÄ±
-  label_wiki_page_plural: Wiki sayfalarÄ±
-  label_index_by_title: BaÅŸlÄ±ÄŸa gÃ¶re diz
-  label_index_by_date: Tarihe gÃ¶re diz
-  label_current_version: GÃ¼ncel sÃ¼rÃ¼m
-  label_preview: Ã–nizleme
-  label_feed_plural: Beslemeler
-  label_changes_details: BÃ¼tÃ¼n deÄŸiÅŸikliklerin detaylarÄ±
-  label_issue_tracking: Ä°ÅŸ Takibi
-  label_spent_time: Harcanan zaman
-  label_f_hour: "%{value} saat"
-  label_f_hour_plural: "%{value} saat"
-  label_time_tracking: Zaman Takibi
-  label_change_plural: DeÄŸiÅŸiklikler
-  label_statistics: Ä°statistikler
-  label_commits_per_month: AylÄ±k teslim
-  label_commits_per_author: Yazar baÅŸÄ±na teslim
-  label_view_diff: FarklarÄ± izle
-  label_diff_inline: satÄ±r iÃ§i
-  label_diff_side_by_side: Yan yana
-  label_options: Tercihler
-  label_copy_workflow_from: Ä°ÅŸakÄ±ÅŸÄ± kopyala
-  label_permissions_report: Ä°zin raporu
-  label_watched_issues: Ä°zlenmiÅŸ iÅŸler
-  label_related_issues: Ä°liÅŸkili iÅŸler
-  label_applied_status: uygulanmÄ±ÅŸ iÅŸler
-  label_loading: YÃ¼kleniyor...
-  label_relation_new: Yeni iliÅŸki
-  label_relation_delete: Ä°liÅŸkiyi sil
-  label_relates_to: iliÅŸkili
-  label_duplicates: yinelenmiÅŸ
-  label_blocks: Engeller
-  label_blocked_by: Engelleyen
-  label_precedes: Ã¶nce gelir
-  label_follows: sonra gelir
-  label_end_to_start: sondan baÅŸa
-  label_end_to_end: sondan sona
-  label_start_to_start: baÅŸtan baÅŸa
-  label_start_to_end: baÅŸtan sona
-  label_stay_logged_in: SÃ¼rekli baÄŸlÄ± kal
-  label_disabled: DevredÄ±ÅŸÄ±
-  label_show_completed_versions: TamamlanmÄ±ÅŸ sÃ¼rÃ¼mleri gÃ¶ster
-  label_me: Ben
-  label_board: TartÄ±ÅŸma AlanÄ±
-  label_board_new: Yeni alan
-  label_board_plural: TartÄ±ÅŸma alanlarÄ±
-  label_topic_plural: Konular
-  label_message_plural: Mesajlar
-  label_message_last: Son mesaj
-  label_message_new: Yeni mesaj
-  label_message_posted: Mesaj eklendi
-  label_reply_plural: Cevaplar
-  label_send_information: Hesap bilgisini kullanÄ±cÄ±ya gÃ¶nder
-  label_year: YÄ±l
-  label_month: Ay
-  label_week: Hafta
-  label_date_from: BaÅŸlangÄ±Ã§
-  label_date_to: BitiÅŸ
-  label_language_based: KullanÄ±cÄ± dili bazlÄ±
-  label_sort_by: "%{value} gÃ¶re sÄ±rala"
-  label_send_test_email: Test e-postasÄ± gÃ¶nder
-  label_feeds_access_key_created_on: "RSS eriÅŸim anahtarÄ± %{value} Ã¶nce oluÅŸturuldu"
-  label_module_plural: ModÃ¼ller
-  label_added_time_by: "%{author} tarafÄ±ndan %{age} Ã¶nce eklendi"
-  label_updated_time: "%{value} Ã¶nce gÃ¼ncellendi"
-  label_jump_to_a_project: Projeye git...
-  label_file_plural: Dosyalar
-  label_changeset_plural: DeÄŸiÅŸiklik Listeleri
-  label_default_columns: VarsayÄ±lan SÃ¼tunlar
-  label_no_change_option: (DeÄŸiÅŸiklik yok)
-  label_bulk_edit_selected_issues: SeÃ§ili iÅŸleri toplu olarak dÃ¼zenle
-  label_theme: Tema
-  label_default: VarsayÄ±lan
-  label_search_titles_only: Sadece baÅŸlÄ±klarÄ± ara
-  label_user_mail_option_all: "TÃ¼m projelerimdeki herhangi bir olay iÃ§in"
-  label_user_mail_option_selected: "Sadece seÃ§ili projelerdeki herhangi bir olay iÃ§in"
-  label_user_mail_no_self_notified: "Kendi yaptÄ±ÄŸÄ±m deÄŸiÅŸikliklerden haberdar olmak istemiyorum"
-  label_registration_activation_by_email: e-posta ile hesap etkinleÅŸtirme
-  label_registration_manual_activation: Elle hesap etkinleÅŸtirme
-  label_registration_automatic_activation: Otomatik hesap etkinleÅŸtirme
-  label_display_per_page: "Sayfa baÅŸÄ±na: %{value}"
-  label_age: YaÅŸ
-  label_change_properties: Ã–zellikleri deÄŸiÅŸtir
-  label_general: Genel
-  label_more: Daha fazla
-  label_scm: KY
-  label_plugins: Eklentiler
-  label_ldap_authentication: LDAP Denetimi
-  label_downloads_abbr: D/L
-  label_optional_description: Ä°steÄŸe baÄŸlÄ± aÃ§Ä±klama
-  label_add_another_file: Bir dosya daha ekle
-  label_preferences: Tercihler
-  label_chronological_order: Tarih sÄ±rasÄ±na gÃ¶re
-  label_reverse_chronological_order: Ters tarih sÄ±rasÄ±na gÃ¶re
-  label_planning: PlanlanÄ±yor
-
-  button_login: GiriÅŸ
-  button_submit: GÃ¶nder
-  button_save: Kaydet
-  button_check_all: Hepsini iÅŸaretle
-  button_uncheck_all: TÃ¼m iÅŸaretleri kaldÄ±r
-  button_delete: Sil
-  button_create: OluÅŸtur
-  button_test: SÄ±na
-  button_edit: DÃ¼zenle
-  button_add: Ekle
-  button_change: DeÄŸiÅŸtir
-  button_apply: Uygula
-  button_clear: Temizle
-  button_lock: Kilitle
-  button_unlock: Kilidi aÃ§
-  button_download: Ä°ndir
-  button_list: Listele
-  button_view: Bak
-  button_move: TaÅŸÄ±
-  button_back: Geri
-  button_cancel: Ä°ptal
-  button_activate: EtkinleÅŸtir
-  button_sort: SÄ±rala
-  button_log_time: Zaman kaydÄ±
-  button_rollback: Bu sÃ¼rÃ¼me geri al
-  button_watch: Ä°zle
-  button_unwatch: Ä°zlemeyi iptal et
-  button_reply: Cevapla
-  button_archive: ArÅŸivle
-  button_unarchive: ArÅŸivlemeyi kaldÄ±r
-  button_reset: SÄ±fÄ±rla
-  button_rename: Yeniden adlandÄ±r
-  button_change_password: ParolayÄ± deÄŸiÅŸtir
-  button_copy: Kopyala
-  button_annotate: DeÄŸiÅŸiklik geÃ§miÅŸine gÃ¶re gÃ¶ster
-  button_update: GÃ¼ncelle
-  button_configure: YapÄ±landÄ±r
-
-  status_active: faal
-  status_registered: kayÄ±tlÄ±
-  status_locked: kilitli
-
-  text_select_mail_notifications: GÃ¶nderilecek e-posta uyarÄ±sÄ±na gÃ¶re hareketi seÃ§in.
-  text_regexp_info: Ã¶rn. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 sÄ±nÄ±rlama yok demektir
-  text_project_destroy_confirmation: Bu projeyi ve baÄŸlantÄ±lÄ± verileri silmek istediÄŸinizden emin misiniz?
-  text_subprojects_destroy_warning: "AyrÄ±ca %{value} alt proje silinecek."
-  text_workflow_edit: Ä°ÅŸakÄ±ÅŸÄ±nÄ± dÃ¼zenlemek iÃ§in bir rol ve iÅŸ tipi seÃ§in
-  text_are_you_sure: Emin misiniz ?
-  text_tip_issue_begin_day: BugÃ¼n baÅŸlayan gÃ¶revler
-  text_tip_issue_end_day: BugÃ¼n sona eren gÃ¶revler
-  text_tip_issue_begin_end_day: BugÃ¼n baÅŸlayan ve sona eren gÃ¶revler
-  text_project_identifier_info: 'KÃ¼Ã§Ã¼k harfler (a-z), sayÄ±lar ve noktalar kabul edilir.<br />Bir kere kaydedildiÄŸinde,tanÄ±mlayÄ±cÄ± deÄŸiÅŸtirilemez.'
-  text_caracters_maximum: "En Ã§ok %{count} karakter."
-  text_caracters_minimum: "En az %{count} karakter uzunluÄŸunda olmalÄ±."
-  text_length_between: "%{min} ve %{max} karakterleri arasÄ±ndaki uzunluk."
-  text_tracker_no_workflow: Bu iÅŸ tipi iÃ§in iÅŸakÄ±ÅŸÄ± tanÄ±mlanmamÄ±ÅŸ
-  text_unallowed_characters: YasaklÄ± karakterler
-  text_comma_separated: Ã‡oklu deÄŸer girilebilir(VirgÃ¼l ile ayrÄ±lmÄ±ÅŸ).
-  text_issues_ref_in_commit_messages: Teslim mesajlarÄ±ndaki iÅŸleri Ã§Ã¶zme ve baÅŸvuruda bulunma
-  text_issue_added: "Ä°ÅŸ %{id}, %{author} tarafÄ±ndan rapor edildi."
-  text_issue_updated: "Ä°ÅŸ %{id}, %{author} tarafÄ±ndan gÃ¼ncellendi."
-  text_wiki_destroy_confirmation: bu wikiyi ve tÃ¼m iÃ§eriÄŸini silmek istediÄŸinizden emin misiniz?
-  text_issue_category_destroy_question: "BazÄ± iÅŸler (%{count}) bu kategoriye atandÄ±. Ne yapmak istersiniz?"
-  text_issue_category_destroy_assignments: Kategori atamalarÄ±nÄ± kaldÄ±r
-  text_issue_category_reassign_to: Ä°ÅŸleri bu kategoriye tekrar ata
-  text_user_mail_option: "SeÃ§ili olmayan projeler iÃ§in, sadece dahil olduÄŸunuz ya da izlediÄŸiniz Ã¶ÄŸeler hakkÄ±nda uyarÄ±lar alacaksÄ±nÄ±z (Ã¶rneÄŸin,yazarÄ± veya atandÄ±ÄŸÄ±nÄ±z iÅŸler)."
-  text_no_configuration_data: "Roller, iÅŸ tipleri, iÅŸ durumlarÄ± ve iÅŸakÄ±ÅŸÄ± henÃ¼z yapÄ±landÄ±rÄ±lmadÄ±.\nVarsayÄ±lan yapÄ±landÄ±rÄ±lmanÄ±n yÃ¼klenmesi ÅŸiddetle tavsiye edilir. Bir kez yÃ¼klendiÄŸinde yapÄ±landÄ±rmayÄ± deÄŸiÅŸtirebileceksiniz."
-  text_load_default_configuration: VarsayÄ±lan yapÄ±landÄ±rmayÄ± yÃ¼kle
-  text_status_changed_by_changeset: "DeÄŸiÅŸiklik listesi %{value} iÃ§inde uygulandÄ±."
-  text_issues_destroy_confirmation: 'SeÃ§ili iÅŸleri silmek istediÄŸinizden emin misiniz ?'
-  text_select_project_modules: 'Bu proje iÃ§in etkinleÅŸtirmek istediÄŸiniz modÃ¼lleri seÃ§in:'
-  text_default_administrator_account_changed: VarsayÄ±lan yÃ¶netici hesabÄ± deÄŸiÅŸti
-  text_file_repository_writable: Dosya deposu yazÄ±labilir
-  text_rmagick_available: RMagick KullanÄ±labilir (isteÄŸe baÄŸlÄ±)
-  text_destroy_time_entries_question: Silmek Ã¼zere olduÄŸunuz iÅŸler Ã¼zerine %{hours} saat raporlandÄ±.Ne yapmak istersiniz ?
-  text_destroy_time_entries: RaporlanmÄ±ÅŸ sÃ¼releri sil
-  text_assign_time_entries_to_project: RaporlanmÄ±ÅŸ sÃ¼releri projeye ata
-  text_reassign_time_entries: 'RaporlanmÄ±ÅŸ sÃ¼releri bu iÅŸe tekrar ata:'
-
-  default_role_manager: YÃ¶netici
-  default_role_developer: GeliÅŸtirici
-  default_role_reporter: RaporlayÄ±cÄ±
-  default_tracker_bug: Hata
-  default_tracker_feature: Ã–zellik
-  default_tracker_support: Destek
-  default_issue_status_new: Yeni
-  default_issue_status_in_progress: YapÄ±lÄ±yor
-  default_issue_status_resolved: Ã‡Ã¶zÃ¼ldÃ¼
-  default_issue_status_feedback: Geribildirim
-  default_issue_status_closed: "KapatÄ±ldÄ±"
-  default_issue_status_rejected: Reddedildi
-  default_doc_category_user: KullanÄ±cÄ± DÃ¶kÃ¼mantasyonu
-  default_doc_category_tech: Teknik DÃ¶kÃ¼mantasyon
-  default_priority_low: DÃ¼ÅŸÃ¼k
-  default_priority_normal: Normal
-  default_priority_high: YÃ¼ksek
-  default_priority_urgent: Acil
-  default_priority_immediate: Derhal
-  default_activity_design: TasarÄ±m
-  default_activity_development: GeliÅŸtirme
-
-  enumeration_issue_priorities: Ä°ÅŸ Ã¶nceliÄŸi
-  enumeration_doc_categories: Belge Kategorileri
-  enumeration_activities: Faaliyetler (zaman takibi)
-  button_quote: AlÄ±ntÄ±
-  setting_enabled_scm: KKY AÃ§Ä±k
-  label_incoming_emails: "Gelen e-postalar"
-  label_generate_key: "Anahtar oluÅŸtur"
-  setting_sequential_project_identifiers: "SÄ±ralÄ± proje tanÄ±mlayÄ±cÄ±larÄ± oluÅŸtur"
-  field_parent_title: Ãœst sayfa
-  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
-  text_enumeration_category_reassign_to: 'Hepsini ÅŸuna Ã§evir:'
-  label_issue_watchers: TakipÃ§iler
-  mail_body_reminder: "Size atanmÄ±ÅŸ olan %{count} iÅŸ %{days} gÃ¼n iÃ§erisinde bitirilmeli:"
-  label_duplicated_by: yineleyen
-  text_enumeration_destroy_question: "Bu nesneye %{count} deÄŸer baÄŸlanmÄ±ÅŸ."
-  text_user_wrote: "%{value} demiÅŸ ki:"
-  setting_mail_handler_api_enabled: Gelen e-postalar iÃ§in WS'yi aÃ§
-  label_and_its_subprojects: "%{value} ve alt projeleri"
-  mail_subject_reminder: "%{count} iÅŸ bir kaÃ§ gÃ¼ne bitecek"
-  setting_mail_handler_api_key: API anahtarÄ±
-  setting_commit_logs_encoding: GÃ¶nderim mesajlarÄ±nÄ±n kodlamasÄ± (UTF-8 vs.)
-  general_csv_decimal_separator: '.'
-  notice_unable_delete_version: SÃ¼rÃ¼m silinemiyor
-  label_renamed: yeniden adlandÄ±rÄ±lmÄ±ÅŸ
-  label_copied: kopyalanmÄ±ÅŸ
-  setting_plain_text_mail: sadece dÃ¼z metin (HTML yok)
-  permission_view_files: DosyalarÄ± gÃ¶rme
-  permission_edit_issues: Ä°ÅŸleri dÃ¼zenleme
-  permission_edit_own_time_entries: Kendi zaman giriÅŸlerini dÃ¼zenleme
-  permission_manage_public_queries: Herkese aÃ§Ä±k sorgularÄ± yÃ¶netme
-  permission_add_issues: Ä°ÅŸ ekleme
-  permission_log_time: Harcanan zamanÄ± kaydetme
-  permission_view_changesets: DeÄŸiÅŸimleri gÃ¶rme(SVN, vs.)
-  permission_view_time_entries: Harcanan zamanÄ± gÃ¶rme
-  permission_manage_versions: SÃ¼rÃ¼mleri yÃ¶netme
-  permission_manage_wiki: Wiki'yi yÃ¶netme
-  permission_manage_categories: Ä°ÅŸ kategorilerini yÃ¶netme
-  permission_protect_wiki_pages: Wiki sayfalarÄ±nÄ± korumaya alma
-  permission_comment_news: Haberlere yorum yapma
-  permission_delete_messages: Mesaj silme
-  permission_select_project_modules: Proje modÃ¼llerini seÃ§me
-  permission_manage_documents: Belgeleri yÃ¶netme
-  permission_edit_wiki_pages: Wiki sayfalarÄ±nÄ± dÃ¼zenleme
-  permission_add_issue_watchers: TakipÃ§i ekleme
-  permission_view_gantt: Ä°ÅŸ-Zaman Ã§izelgesi gÃ¶rme
-  permission_move_issues: Ä°ÅŸlerin yerini deÄŸiÅŸtirme
-  permission_manage_issue_relations: Ä°ÅŸlerin biribiriyle baÄŸlantÄ±larÄ±nÄ± yÃ¶netme
-  permission_delete_wiki_pages: Wiki sayfalarÄ±nÄ± silme
-  permission_manage_boards: PanolarÄ± yÃ¶netme
-  permission_delete_wiki_pages_attachments: Ekleri silme
-  permission_view_wiki_edits: Wiki geÃ§miÅŸini gÃ¶rme
-  permission_add_messages: Mesaj gÃ¶nderme
-  permission_view_messages: MesajlarÄ± gÃ¶rme
-  permission_manage_files: DosyalarÄ± yÃ¶netme
-  permission_edit_issue_notes: NotlarÄ± dÃ¼zenleme
-  permission_manage_news: Haberleri yÃ¶netme
-  permission_view_calendar: Takvimleri gÃ¶rme
-  permission_manage_members: Ãœyeleri yÃ¶netme
-  permission_edit_messages: MesajlarÄ± dÃ¼zenleme
-  permission_delete_issues: Ä°ÅŸleri silme
-  permission_view_issue_watchers: TakipÃ§i listesini gÃ¶rme
-  permission_manage_repository: Depo yÃ¶netimi
-  permission_commit_access: GÃ¶nderme eriÅŸimi
-  permission_browse_repository: Depoya gÃ¶zatma
-  permission_view_documents: Belgeleri gÃ¶rme
-  permission_edit_project: Projeyi dÃ¼zenleme
-  permission_add_issue_notes: Not ekleme
-  permission_save_queries: Sorgu kaydetme
-  permission_view_wiki_pages: Wiki gÃ¶rme
-  permission_rename_wiki_pages: Wiki sayfasÄ±nÄ±n adÄ±nÄ± deÄŸiÅŸtirme
-  permission_edit_time_entries: Zaman kayÄ±tlarÄ±nÄ± dÃ¼zenleme
-  permission_edit_own_issue_notes: Kendi notlarÄ±nÄ± dÃ¼zenleme
-  setting_gravatar_enabled: KullanÄ±cÄ± resimleri iÃ§in Gravatar kullan
-  label_example: Ã–rnek
-  text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
-  permission_edit_own_messages: Kendi mesajlarÄ±nÄ± dÃ¼zenleme
-  permission_delete_own_messages: Kendi mesajlarÄ±nÄ± silme
-  label_user_activity: "%{value} kullanÄ±cÄ±sÄ±nÄ±n etkinlikleri"
-  label_updated_time_by: "%{author} tarafÄ±ndan %{age} Ã¶nce gÃ¼ncellendi"
-  text_diff_truncated: '... Bu fark tam olarak gÃ¶sterilemiyor Ã§Ã¼nkÃ¼ gÃ¶sterim iÃ§in ayarlanmÄ±ÅŸ Ã¼st sÄ±nÄ±rÄ± aÅŸÄ±yor.'
-  setting_diff_max_lines_displayed: GÃ¶sterilebilecek maksimumu fark satÄ±rÄ±
-  text_plugin_assets_writable: Eklenti yardÄ±mcÄ± dosya dizini yazÄ±labilir
-  warning_attachments_not_saved: "%{count} adet dosya kaydedilemedi."
-  button_create_and_continue: OluÅŸtur ve devam et
-  text_custom_field_possible_values_info: 'Her deÄŸer iÃ§in bir satÄ±r'
-  label_display: GÃ¶ster
-  field_editable: DÃ¼zenlenebilir
-  setting_repository_log_display_limit: Dosya kaydÄ±nda gÃ¶sterilecek maksimum deÄŸiÅŸim sayÄ±sÄ±
-  setting_file_max_size_displayed: Dahili olarak gÃ¶sterilecek metin dosyalarÄ± iÃ§in maksimum satÄ±r sayÄ±sÄ±
-  field_watcher: TakipÃ§i
-  setting_openid: KayÄ±t ve giriÅŸ iÃ§in OpenID'ye izin ver
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: veya OpenID kullanÄ±n
-  field_content: Ä°Ã§erik
-  label_descending: Azalan
-  label_sort: SÄ±rala
-  label_ascending: Artan
-  label_date_from_to: "%{start} - %{end} arasÄ±"
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: Bu sayfanÄ±n %{descendants} adet alt sayfasÄ± var. Ne yapmak istersiniz?
-  text_wiki_page_reassign_children: Alt sayfalarÄ± bu sayfanÄ±n altÄ±na baÄŸla
-  text_wiki_page_nullify_children: Alt sayfalarÄ± ana sayfa olarak sakla
-  text_wiki_page_destroy_children: Alt sayfalarÄ± ve onlarÄ±n alt sayfalarÄ±nÄ± tamamen sil
-  setting_password_min_length: Minimum parola uzunluÄŸu
-  field_group_by: SonuÃ§larÄ± grupla
-  mail_subject_wiki_content_updated: "'%{id}' wiki sayfasÄ± gÃ¼ncellendi"
-  label_wiki_content_added: Wiki sayfasÄ± eklendi
-  mail_subject_wiki_content_added: "'%{id}' wiki sayfasÄ± eklendi"
-  mail_body_wiki_content_added: "'%{id}' wiki sayfasÄ±, %{author} tarafÄ±ndan eklendi."
-  label_wiki_content_updated: Wiki sayfasÄ± gÃ¼ncellendi
-  mail_body_wiki_content_updated: "'%{id}' wiki sayfasÄ±, %{author} tarafÄ±ndan gÃ¼ncellendi."
-  permission_add_project: Proje oluÅŸtur
-  setting_new_project_user_role_id: YÃ¶netici olmayan ancak proje yaratabilen kullanÄ±cÄ±ya verilen rol
-  label_view_all_revisions: TÃ¼m deÄŸiÅŸiklikleri gÃ¶r
-  label_tag: Etiket
-  label_branch: Kol
-  error_no_tracker_in_project: Bu projeye baÄŸlanmÄ±ÅŸ bir iÅŸ tipi yok. LÃ¼tfen proje ayarlarÄ±nÄ± kontrol edin.
-  error_no_default_issue_status: VarsayÄ±lan iÅŸ durumu tanÄ±mlanmamÄ±ÅŸ. LÃ¼tfen ayarlarÄ±nÄ±zÄ± kontrol edin ("YÃ¶netim -> Ä°ÅŸ durumlarÄ±" sayfasÄ±na gidin).
-  label_group_plural: Gruplar
-  label_group: Grup
-  label_group_new: Yeni grup
-  label_time_entry_plural: Harcanan zaman
-  text_journal_changed: "%{label}: %{old} -> %{new}"
-  text_journal_set_to: "%{label} %{value} yapÄ±ldÄ±"
-  text_journal_deleted: "%{label} silindi (%{old})"
-  text_journal_added: "%{label} %{value} eklendi"
-  field_active: Etkin
-  enumeration_system_activity: Sistem Etkinlikleri
-  permission_delete_issue_watchers: Ä°zleyicileri sil
-  version_status_closed: kapalÄ±
-  version_status_locked: kilitli
-  version_status_open: aÃ§Ä±k
-  error_can_not_reopen_issue_on_closed_version: KapatÄ±lmÄ±ÅŸ bir sÃ¼rÃ¼me ait iÅŸler tekrar aÃ§Ä±lamaz
-  label_user_anonymous: Anonim
-  button_move_and_follow: Yerini deÄŸiÅŸtir ve takip et
-  setting_default_projects_modules: Yeni projeler iÃ§in varsayÄ±lan modÃ¼ller
-  setting_gravatar_default: VarsayÄ±lan Gravatar resmi
-  field_sharing: PaylaÅŸÄ±m
-  label_version_sharing_hierarchy: Proje hiyerarÅŸisi ile
-  label_version_sharing_system: TÃ¼m projeler ile
-  label_version_sharing_descendants: Alt projeler ile
-  label_version_sharing_tree: Proje aÄŸacÄ± ile
-  label_version_sharing_none: PaylaÅŸÄ±lmamÄ±ÅŸ
-  error_can_not_archive_project: Bu proje arÅŸivlenemez
-  button_duplicate: Yinele
-  button_copy_and_follow: Kopyala ve takip et
-  label_copy_source: Kaynak
-  setting_issue_done_ratio: Ä°ÅŸ tamamlanma oranÄ±nÄ± ÅŸununla hesapla
-  setting_issue_done_ratio_issue_status: Ä°ÅŸ durumunu kullan
-  error_issue_done_ratios_not_updated: Ä°ÅŸ tamamlanma oranlarÄ± gÃ¼ncellenmedi.
-  error_workflow_copy_target: LÃ¼tfen hedef iÅŸ tipi ve rolleri seÃ§in
-  setting_issue_done_ratio_issue_field: Ä°ÅŸteki alanÄ± kullan
-  label_copy_same_as_target: Hedef ile aynÄ±
-  label_copy_target: Hedef
-  notice_issue_done_ratios_updated: Ä°ÅŸ tamamlanma oranlarÄ± gÃ¼ncellendi.
-  error_workflow_copy_source: LÃ¼tfen kaynak iÅŸ tipi ve rolleri seÃ§in
-  label_update_issue_done_ratios: Ä°ÅŸ tamamlanma oranlarÄ±nÄ± gÃ¼ncelle
-  setting_start_of_week: Takvimleri ÅŸundan baÅŸlat
-  permission_view_issues: Ä°ÅŸleri GÃ¶r
-  label_display_used_statuses_only: Sadece bu iÅŸ tipi tarafÄ±ndan kullanÄ±lan durumlarÄ± gÃ¶ster
-  label_revision_id: DeÄŸiÅŸiklik %{value}
-  label_api_access_key: API eriÅŸim anahtarÄ±
-  label_api_access_key_created_on: API eriÅŸim anahtarÄ± %{value} Ã¶nce oluÅŸturuldu
-  label_feeds_access_key: RSS eriÅŸim anahtarÄ±
-  notice_api_access_key_reseted: API eriÅŸim anahtarÄ±nÄ±z sÄ±fÄ±rlandÄ±.
-  setting_rest_api_enabled: REST web servisini etkinleÅŸtir
-  label_missing_api_access_key: Bir API eriÅŸim anahtarÄ± eksik
-  label_missing_feeds_access_key: Bir RSS eriÅŸim anahtarÄ± eksik
-  button_show: GÃ¶ster
-  text_line_separated: Ã‡oklu deÄŸer girilebilir (her satÄ±ra bir deÄŸer).
-  setting_mail_handler_body_delimiters: Åžu satÄ±rlarÄ±n birinden sonra e-postayÄ± sonlandÄ±r
-  permission_add_subprojects: Alt proje yaratma
-  label_subproject_new: Yeni alt proje
-  text_own_membership_delete_confirmation: "Projeyi daha sonra dÃ¼zenleyememenize sebep olacak bazÄ± yetkilerinizi kaldÄ±rmak Ã¼zeresiniz.\nDevam etmek istediÄŸinize emin misiniz?"
-  label_close_versions: TamamlanmÄ±ÅŸ sÃ¼rÃ¼mleri kapat
-  label_board_sticky: YapÄ±ÅŸkan
-  label_board_locked: Kilitli
-  permission_export_wiki_pages: Wiki sayfalarÄ±nÄ± dÄ±ÅŸarÄ± aktar
-  setting_cache_formatted_text: BiÃ§imlendirilmiÅŸ metni Ã¶nbelleÄŸe al
-  permission_manage_project_activities: Proje etkinliklerini yÃ¶netme
-  error_unable_delete_issue_status: Ä°ÅŸ durumu silinemiyor
-  label_profile: Profil
-  permission_manage_subtasks: Alt iÅŸleri yÃ¶netme
-  field_parent_issue: Ãœst iÅŸ
-  label_subtask_plural: Alt iÅŸler
-  label_project_copy_notifications: Proje kopyalamasÄ± esnasÄ±nda bilgilendirme e-postalarÄ± gÃ¶nder
-  error_can_not_delete_custom_field: Ã–zel alan silinemiyor
-  error_unable_to_connect: BaÄŸlanÄ±lamÄ±yor (%{value})
-  error_can_not_remove_role: Bu rol kullanÄ±mda olduÄŸundan silinemez.
-  error_can_not_delete_tracker: Bu iÅŸ tipi iÃ§erisinde iÅŸ barÄ±ndÄ±rdÄ±ÄŸÄ±ndan silinemiyor.
-  field_principal: Temel
-  label_my_page_block: KiÅŸisel sayfa bloÄŸum
-  notice_failed_to_save_members: "Ãœyeler kaydedilemiyor: %{errors}."
-  text_zoom_out: UzaklaÅŸ
-  text_zoom_in: YakÄ±nlaÅŸ
-  notice_unable_delete_time_entry: Zaman kayÄ±t girdisi silinemiyor.
-  label_overall_spent_time: Toplam harcanan zaman
-  field_time_entries: Zaman KayÄ±tlarÄ±
-  project_module_gantt: Ä°ÅŸ-Zaman Ã‡izelgesi
-  project_module_calendar: Takvim
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Ä°ÅŸ, tÃ¼m alt iÅŸlerle birlikte silinsin mi?
-  field_text: Metin alanÄ±
-  label_user_mail_option_only_owner: Sadece sahibi olduÄŸum ÅŸeyler iÃ§in
-  setting_default_notification_option: VarsayÄ±lan bildirim seÃ§eneÄŸi
-  label_user_mail_option_only_my_events: Sadece takip ettiÄŸim ya da iÃ§inde olduÄŸum ÅŸeyler iÃ§in
-  label_user_mail_option_only_assigned: Sadece bana atanan ÅŸeyler iÃ§in
-  label_user_mail_option_none: HiÃ§ bir ÅŸey iÃ§in
-  field_member_of_group: AtananÄ±n grubu
-  field_assigned_to_role: AtananÄ±n rolÃ¼
-  notice_not_authorized_archived_project: EriÅŸmeye Ã§alÄ±ÅŸtÄ±ÄŸÄ±nÄ±z proje arÅŸive kaldÄ±rÄ±lmÄ±ÅŸ.
-  label_principal_search: "KullanÄ±cÄ± ya da grup ara:"
-  label_user_search: "KullanÄ±cÄ± ara:"
-  field_visible: GÃ¶rÃ¼nÃ¼r
-  setting_emails_header: "E-Posta baÅŸlÄ±ÄŸÄ±"
-  setting_commit_logtime_activity_id: Kaydedilen zaman iÃ§in etkinlik
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Zaman kaydÄ±nÄ± etkinleÅŸtir
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Ä°ÅŸ-Zaman Ã§izelgesinde gÃ¶sterilecek en fazla Ã¶ÄŸe sayÄ±sÄ±
-  field_warn_on_leaving_unsaved: KaydedilmemiÅŸ metin bulunan bir sayfadan Ã§Ä±karken beni uyar
-  text_warn_on_leaving_unsaved: Bu sayfada terkettiÄŸiniz takdirde kaybolacak kaydedilmemiÅŸ metinler var.
-  label_my_queries: Ã–zel sorgularÄ±m
-  text_journal_changed_no_detail: "%{label} gÃ¼ncellendi"
-  label_news_comment_added: Bir habere yorum eklendi
-  button_expand_all: TÃ¼mÃ¼nÃ¼ geniÅŸlet
-  button_collapse_all: TÃ¼mÃ¼nÃ¼ daralt
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: SeÃ§ilen zaman kayÄ±tlarÄ±nÄ± toplu olarak dÃ¼zenle
-  text_time_entries_destroy_confirmation: SeÃ§ilen zaman kaydÄ±nÄ±/kayÄ±tlarÄ±nÄ± silmek istediÄŸinize emin misiniz?
-  label_role_anonymous: Anonim
-  label_role_non_member: Ãœye DeÄŸil
-  label_issue_note_added: Not eklendi
-  label_issue_status_updated: Durum gÃ¼ncellendi
-  label_issue_priority_updated: Ã–ncelik gÃ¼ncellendi
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Ä°ÅŸlerin gÃ¶rÃ¼nÃ¼rlÃ¼ÄŸÃ¼
-  label_issues_visibility_all: TÃ¼m iÅŸler
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Ã–zel
-  permission_set_issues_private: Ä°ÅŸleri Ã¶zel ya da genel olarak iÅŸaretleme
-  label_issues_visibility_public: Ã–zel olmayan tÃ¼m iÅŸler
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Commit messages encoding
-  field_scm_path_encoding: Yol kodlamasÄ±(encoding)
-  text_scm_path_encoding_note: "VarsayÄ±lan: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Ana dizin
-  field_cvs_module: ModÃ¼l
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Komut
-  text_scm_command_version: SÃ¼rÃ¼m
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a7a4ecfdf630f58f27285c261cd0c6397a1be2a3.svn-base
--- a/.svn/pristine/a7/a7a4ecfdf630f58f27285c261cd0c6397a1be2a3.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= TestHelper.view_path_for __FILE__ %> (from beta_plugin)
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a7c522fa48845e70c7a7bc89a951a0055cb1f96f.svn-base
--- /dev/null
+++ b/.svn/pristine/a7/a7c522fa48845e70c7a7bc89a951a0055cb1f96f.svn-base
@@ -0,0 +1,2104 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssueTest < ActiveSupport::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles,
+           :groups_users,
+           :trackers, :projects_trackers,
+           :enabled_modules,
+           :versions,
+           :issue_statuses, :issue_categories, :issue_relations, :workflows,
+           :enumerations,
+           :issues, :journals, :journal_details,
+           :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
+           :time_entries
+
+  include Redmine::I18n
+
+  def teardown
+    User.current = nil
+  end
+
+  def test_initialize
+    issue = Issue.new
+
+    assert_nil issue.project_id
+    assert_nil issue.tracker_id
+    assert_nil issue.author_id
+    assert_nil issue.assigned_to_id
+    assert_nil issue.category_id
+
+    assert_equal IssueStatus.default, issue.status
+    assert_equal IssuePriority.default, issue.priority
+  end
+
+  def test_create
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
+                      :status_id => 1, :priority => IssuePriority.all.first,
+                      :subject => 'test_create',
+                      :description => 'IssueTest#test_create', :estimated_hours => '1:30')
+    assert issue.save
+    issue.reload
+    assert_equal 1.5, issue.estimated_hours
+  end
+
+  def test_create_minimal
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
+                      :status_id => 1, :priority => IssuePriority.all.first,
+                      :subject => 'test_create')
+    assert issue.save
+    assert issue.description.nil?
+    assert_nil issue.estimated_hours
+  end
+
+  def test_start_date_format_should_be_validated
+    set_language_if_valid 'en'
+    ['2012', 'ABC', '2012-15-20'].each do |invalid_date|
+      issue = Issue.new(:start_date => invalid_date)
+      assert !issue.valid?
+      assert_include 'Start date is not a valid date', issue.errors.full_messages, "No error found for invalid date #{invalid_date}"
+    end
+  end
+
+  def test_due_date_format_should_be_validated
+    set_language_if_valid 'en'
+    ['2012', 'ABC', '2012-15-20'].each do |invalid_date|
+      issue = Issue.new(:due_date => invalid_date)
+      assert !issue.valid?
+      assert_include 'Due date is not a valid date', issue.errors.full_messages, "No error found for invalid date #{invalid_date}"
+    end
+  end
+
+  def test_due_date_lesser_than_start_date_should_not_validate
+    set_language_if_valid 'en'
+    issue = Issue.new(:start_date => '2012-10-06', :due_date => '2012-10-02')
+    assert !issue.valid?
+    assert_include 'Due date must be greater than start date', issue.errors.full_messages
+  end
+
+  def test_estimated_hours_should_be_validated
+    set_language_if_valid 'en'
+    ['-2'].each do |invalid|
+      issue = Issue.new(:estimated_hours => invalid)
+      assert !issue.valid?
+      assert_include 'Estimated time is invalid', issue.errors.full_messages
+    end
+  end
+
+  def test_create_with_required_custom_field
+    set_language_if_valid 'en'
+    field = IssueCustomField.find_by_name('Database')
+    field.update_attribute(:is_required, true)
+
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
+                      :status_id => 1, :subject => 'test_create',
+                      :description => 'IssueTest#test_create_with_required_custom_field')
+    assert issue.available_custom_fields.include?(field)
+    # No value for the custom field
+    assert !issue.save
+    assert_equal ["Database can't be blank"], issue.errors.full_messages
+    # Blank value
+    issue.custom_field_values = { field.id => '' }
+    assert !issue.save
+    assert_equal ["Database can't be blank"], issue.errors.full_messages
+    # Invalid value
+    issue.custom_field_values = { field.id => 'SQLServer' }
+    assert !issue.save
+    assert_equal ["Database is not included in the list"], issue.errors.full_messages
+    # Valid value
+    issue.custom_field_values = { field.id => 'PostgreSQL' }
+    assert issue.save
+    issue.reload
+    assert_equal 'PostgreSQL', issue.custom_value_for(field).value
+  end
+
+  def test_create_with_group_assignment
+    with_settings :issue_group_assignment => '1' do
+      assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
+                       :subject => 'Group assignment',
+                       :assigned_to_id => 11).save
+      issue = Issue.first(:order => 'id DESC')
+      assert_kind_of Group, issue.assigned_to
+      assert_equal Group.find(11), issue.assigned_to
+    end
+  end
+
+  def test_create_with_parent_issue_id
+    issue = Issue.new(:project_id => 1, :tracker_id => 1,
+                      :author_id => 1, :subject => 'Group assignment',
+                      :parent_issue_id => 1)
+    assert_save issue
+    assert_equal 1, issue.parent_issue_id
+    assert_equal Issue.find(1), issue.parent
+  end
+
+  def test_create_with_sharp_parent_issue_id
+    issue = Issue.new(:project_id => 1, :tracker_id => 1,
+                      :author_id => 1, :subject => 'Group assignment',
+                      :parent_issue_id => "#1")
+    assert_save issue
+    assert_equal 1, issue.parent_issue_id
+    assert_equal Issue.find(1), issue.parent
+  end
+
+  def test_create_with_invalid_parent_issue_id
+    set_language_if_valid 'en'
+    issue = Issue.new(:project_id => 1, :tracker_id => 1,
+                      :author_id => 1, :subject => 'Group assignment',
+                      :parent_issue_id => '01ABC')
+    assert !issue.save
+    assert_equal '01ABC', issue.parent_issue_id
+    assert_include 'Parent task is invalid', issue.errors.full_messages
+  end
+
+  def test_create_with_invalid_sharp_parent_issue_id
+    set_language_if_valid 'en'
+    issue = Issue.new(:project_id => 1, :tracker_id => 1,
+                      :author_id => 1, :subject => 'Group assignment',
+                      :parent_issue_id => '#01ABC')
+    assert !issue.save
+    assert_equal '#01ABC', issue.parent_issue_id
+    assert_include 'Parent task is invalid', issue.errors.full_messages
+  end
+
+  def assert_visibility_match(user, issues)
+    assert_equal issues.collect(&:id).sort, Issue.all.select {|issue| issue.visible?(user)}.collect(&:id).sort
+  end
+
+  def test_visible_scope_for_anonymous
+    # Anonymous user should see issues of public projects only
+    issues = Issue.visible(User.anonymous).all
+    assert issues.any?
+    assert_nil issues.detect {|issue| !issue.project.is_public?}
+    assert_nil issues.detect {|issue| issue.is_private?}
+    assert_visibility_match User.anonymous, issues
+  end
+
+  def test_visible_scope_for_anonymous_without_view_issues_permissions
+    # Anonymous user should not see issues without permission
+    Role.anonymous.remove_permission!(:view_issues)
+    issues = Issue.visible(User.anonymous).all
+    assert issues.empty?
+    assert_visibility_match User.anonymous, issues
+  end
+
+  def test_anonymous_should_not_see_private_issues_with_issues_visibility_set_to_default
+    assert Role.anonymous.update_attribute(:issues_visibility, 'default')
+    issue = Issue.generate!(:author => User.anonymous, :assigned_to => User.anonymous, :is_private => true)
+    assert_nil Issue.where(:id => issue.id).visible(User.anonymous).first
+    assert !issue.visible?(User.anonymous)
+  end
+
+  def test_anonymous_should_not_see_private_issues_with_issues_visibility_set_to_own
+    assert Role.anonymous.update_attribute(:issues_visibility, 'own')
+    issue = Issue.generate!(:author => User.anonymous, :assigned_to => User.anonymous, :is_private => true)
+    assert_nil Issue.where(:id => issue.id).visible(User.anonymous).first
+    assert !issue.visible?(User.anonymous)
+  end
+
+  def test_visible_scope_for_non_member
+    user = User.find(9)
+    assert user.projects.empty?
+    # Non member user should see issues of public projects only
+    issues = Issue.visible(user).all
+    assert issues.any?
+    assert_nil issues.detect {|issue| !issue.project.is_public?}
+    assert_nil issues.detect {|issue| issue.is_private?}
+    assert_visibility_match user, issues
+  end
+
+  def test_visible_scope_for_non_member_with_own_issues_visibility
+    Role.non_member.update_attribute :issues_visibility, 'own'
+    Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 9, :subject => 'Issue by non member')
+    user = User.find(9)
+
+    issues = Issue.visible(user).all
+    assert issues.any?
+    assert_nil issues.detect {|issue| issue.author != user}
+    assert_visibility_match user, issues
+  end
+
+  def test_visible_scope_for_non_member_without_view_issues_permissions
+    # Non member user should not see issues without permission
+    Role.non_member.remove_permission!(:view_issues)
+    user = User.find(9)
+    assert user.projects.empty?
+    issues = Issue.visible(user).all
+    assert issues.empty?
+    assert_visibility_match user, issues
+  end
+
+  def test_visible_scope_for_member
+    user = User.find(9)
+    # User should see issues of projects for which he has view_issues permissions only
+    Role.non_member.remove_permission!(:view_issues)
+    Member.create!(:principal => user, :project_id => 3, :role_ids => [2])
+    issues = Issue.visible(user).all
+    assert issues.any?
+    assert_nil issues.detect {|issue| issue.project_id != 3}
+    assert_nil issues.detect {|issue| issue.is_private?}
+    assert_visibility_match user, issues
+  end
+
+  def test_visible_scope_for_member_with_groups_should_return_assigned_issues
+    user = User.find(8)
+    assert user.groups.any?
+    Member.create!(:principal => user.groups.first, :project_id => 1, :role_ids => [2])
+    Role.non_member.remove_permission!(:view_issues)
+    
+    issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
+      :status_id => 1, :priority => IssuePriority.all.first,
+      :subject => 'Assignment test',
+      :assigned_to => user.groups.first,
+      :is_private => true)
+    
+    Role.find(2).update_attribute :issues_visibility, 'default'
+    issues = Issue.visible(User.find(8)).all
+    assert issues.any?
+    assert issues.include?(issue)
+    
+    Role.find(2).update_attribute :issues_visibility, 'own'
+    issues = Issue.visible(User.find(8)).all
+    assert issues.any?
+    assert issues.include?(issue)
+  end
+
+  def test_visible_scope_for_admin
+    user = User.find(1)
+    user.members.each(&:destroy)
+    assert user.projects.empty?
+    issues = Issue.visible(user).all
+    assert issues.any?
+    # Admin should see issues on private projects that he does not belong to
+    assert issues.detect {|issue| !issue.project.is_public?}
+    # Admin should see private issues of other users
+    assert issues.detect {|issue| issue.is_private? && issue.author != user}
+    assert_visibility_match user, issues
+  end
+
+  def test_visible_scope_with_project
+    project = Project.find(1)
+    issues = Issue.visible(User.find(2), :project => project).all
+    projects = issues.collect(&:project).uniq
+    assert_equal 1, projects.size
+    assert_equal project, projects.first
+  end
+
+  def test_visible_scope_with_project_and_subprojects
+    project = Project.find(1)
+    issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all
+    projects = issues.collect(&:project).uniq
+    assert projects.size > 1
+    assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)}
+  end
+
+  def test_visible_and_nested_set_scopes
+    assert_equal 0, Issue.find(1).descendants.visible.all.size
+  end
+
+  def test_open_scope
+    issues = Issue.open.all
+    assert_nil issues.detect(&:closed?)
+  end
+
+  def test_open_scope_with_arg
+    issues = Issue.open(false).all
+    assert_equal issues, issues.select(&:closed?)
+  end
+
+  def test_fixed_version_scope_with_a_version_should_return_its_fixed_issues
+    version = Version.find(2)
+    assert version.fixed_issues.any?
+    assert_equal version.fixed_issues.to_a.sort, Issue.fixed_version(version).to_a.sort
+  end
+
+  def test_fixed_version_scope_with_empty_array_should_return_no_result
+    assert_equal 0, Issue.fixed_version([]).count
+  end
+
+  def test_errors_full_messages_should_include_custom_fields_errors
+    field = IssueCustomField.find_by_name('Database')
+
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
+                      :status_id => 1, :subject => 'test_create',
+                      :description => 'IssueTest#test_create_with_required_custom_field')
+    assert issue.available_custom_fields.include?(field)
+    # Invalid value
+    issue.custom_field_values = { field.id => 'SQLServer' }
+
+    assert !issue.valid?
+    assert_equal 1, issue.errors.full_messages.size
+    assert_equal "Database #{I18n.translate('activerecord.errors.messages.inclusion')}",
+                 issue.errors.full_messages.first
+  end
+
+  def test_update_issue_with_required_custom_field
+    field = IssueCustomField.find_by_name('Database')
+    field.update_attribute(:is_required, true)
+
+    issue = Issue.find(1)
+    assert_nil issue.custom_value_for(field)
+    assert issue.available_custom_fields.include?(field)
+    # No change to custom values, issue can be saved
+    assert issue.save
+    # Blank value
+    issue.custom_field_values = { field.id => '' }
+    assert !issue.save
+    # Valid value
+    issue.custom_field_values = { field.id => 'PostgreSQL' }
+    assert issue.save
+    issue.reload
+    assert_equal 'PostgreSQL', issue.custom_value_for(field).value
+  end
+
+  def test_should_not_update_attributes_if_custom_fields_validation_fails
+    issue = Issue.find(1)
+    field = IssueCustomField.find_by_name('Database')
+    assert issue.available_custom_fields.include?(field)
+
+    issue.custom_field_values = { field.id => 'Invalid' }
+    issue.subject = 'Should be not be saved'
+    assert !issue.save
+
+    issue.reload
+    assert_equal "Can't print recipes", issue.subject
+  end
+
+  def test_should_not_recreate_custom_values_objects_on_update
+    field = IssueCustomField.find_by_name('Database')
+
+    issue = Issue.find(1)
+    issue.custom_field_values = { field.id => 'PostgreSQL' }
+    assert issue.save
+    custom_value = issue.custom_value_for(field)
+    issue.reload
+    issue.custom_field_values = { field.id => 'MySQL' }
+    assert issue.save
+    issue.reload
+    assert_equal custom_value.id, issue.custom_value_for(field).id
+  end
+
+  def test_should_not_update_custom_fields_on_changing_tracker_with_different_custom_fields
+    issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1,
+                          :status_id => 1, :subject => 'Test',
+                          :custom_field_values => {'2' => 'Test'})
+    assert !Tracker.find(2).custom_field_ids.include?(2)
+
+    issue = Issue.find(issue.id)
+    issue.attributes = {:tracker_id => 2, :custom_field_values => {'1' => ''}}
+
+    issue = Issue.find(issue.id)
+    custom_value = issue.custom_value_for(2)
+    assert_not_nil custom_value
+    assert_equal 'Test', custom_value.value
+  end
+
+  def test_assigning_tracker_id_should_reload_custom_fields_values
+    issue = Issue.new(:project => Project.find(1))
+    assert issue.custom_field_values.empty?
+    issue.tracker_id = 1
+    assert issue.custom_field_values.any?
+  end
+
+  def test_assigning_attributes_should_assign_project_and_tracker_first
+    seq = sequence('seq')
+    issue = Issue.new
+    issue.expects(:project_id=).in_sequence(seq)
+    issue.expects(:tracker_id=).in_sequence(seq)
+    issue.expects(:subject=).in_sequence(seq)
+    issue.attributes = {:tracker_id => 2, :project_id => 1, :subject => 'Test'}
+  end
+
+  def test_assigning_tracker_and_custom_fields_should_assign_custom_fields
+    attributes = ActiveSupport::OrderedHash.new
+    attributes['custom_field_values'] = { '1' => 'MySQL' }
+    attributes['tracker_id'] = '1'
+    issue = Issue.new(:project => Project.find(1))
+    issue.attributes = attributes
+    assert_equal 'MySQL', issue.custom_field_value(1)
+  end
+
+  def test_reload_should_reload_custom_field_values
+    issue = Issue.generate!
+    issue.custom_field_values = {'2' => 'Foo'}
+    issue.save!
+
+    issue = Issue.order('id desc').first
+    assert_equal 'Foo', issue.custom_field_value(2)
+
+    issue.custom_field_values = {'2' => 'Bar'}
+    assert_equal 'Bar', issue.custom_field_value(2)
+
+    issue.reload
+    assert_equal 'Foo', issue.custom_field_value(2)
+  end
+
+  def test_should_update_issue_with_disabled_tracker
+    p = Project.find(1)
+    issue = Issue.find(1)
+
+    p.trackers.delete(issue.tracker)
+    assert !p.trackers.include?(issue.tracker)
+
+    issue.reload
+    issue.subject = 'New subject'
+    assert issue.save
+  end
+
+  def test_should_not_set_a_disabled_tracker
+    p = Project.find(1)
+    p.trackers.delete(Tracker.find(2))
+
+    issue = Issue.find(1)
+    issue.tracker_id = 2
+    issue.subject = 'New subject'
+    assert !issue.save
+    assert_not_nil issue.errors[:tracker_id]
+  end
+
+  def test_category_based_assignment
+    issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
+                         :status_id => 1, :priority => IssuePriority.all.first,
+                         :subject => 'Assignment test',
+                         :description => 'Assignment test', :category_id => 1)
+    assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
+  end
+
+  def test_new_statuses_allowed_to
+    WorkflowTransition.delete_all
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
+                               :old_status_id => 1, :new_status_id => 2,
+                               :author => false, :assignee => false)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
+                               :old_status_id => 1, :new_status_id => 3,
+                               :author => true, :assignee => false)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1,
+                               :new_status_id => 4, :author => false,
+                               :assignee => true)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
+                               :old_status_id => 1, :new_status_id => 5,
+                               :author => true, :assignee => true)
+    status = IssueStatus.find(1)
+    role = Role.find(1)
+    tracker = Tracker.find(1)
+    user = User.find(2)
+
+    issue = Issue.generate!(:tracker => tracker, :status => status,
+                            :project_id => 1, :author_id => 1)
+    assert_equal [1, 2], issue.new_statuses_allowed_to(user).map(&:id)
+
+    issue = Issue.generate!(:tracker => tracker, :status => status,
+                            :project_id => 1, :author => user)
+    assert_equal [1, 2, 3, 5], issue.new_statuses_allowed_to(user).map(&:id)
+
+    issue = Issue.generate!(:tracker => tracker, :status => status,
+                            :project_id => 1, :author_id => 1,
+                            :assigned_to => user)
+    assert_equal [1, 2, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
+
+    issue = Issue.generate!(:tracker => tracker, :status => status,
+                            :project_id => 1, :author => user,
+                            :assigned_to => user)
+    assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
+  end
+
+  def test_new_statuses_allowed_to_should_return_all_transitions_for_admin
+    admin = User.find(1)
+    issue = Issue.find(1)
+    assert !admin.member_of?(issue.project)
+    expected_statuses = [issue.status] + 
+                            WorkflowTransition.find_all_by_old_status_id(
+                                issue.status_id).map(&:new_status).uniq.sort
+    assert_equal expected_statuses, issue.new_statuses_allowed_to(admin)
+  end
+
+  def test_new_statuses_allowed_to_should_return_default_and_current_status_when_copying
+    issue = Issue.find(1).copy
+    assert_equal [1], issue.new_statuses_allowed_to(User.find(2)).map(&:id)
+
+    issue = Issue.find(2).copy
+    assert_equal [1, 2], issue.new_statuses_allowed_to(User.find(2)).map(&:id)
+  end
+
+  def test_safe_attributes_names_should_not_include_disabled_field
+    tracker = Tracker.new(:core_fields => %w(assigned_to_id fixed_version_id))
+
+    issue = Issue.new(:tracker => tracker)
+    assert_include 'tracker_id', issue.safe_attribute_names
+    assert_include 'status_id', issue.safe_attribute_names
+    assert_include 'subject', issue.safe_attribute_names
+    assert_include 'description', issue.safe_attribute_names
+    assert_include 'custom_field_values', issue.safe_attribute_names
+    assert_include 'custom_fields', issue.safe_attribute_names
+    assert_include 'lock_version', issue.safe_attribute_names
+
+    tracker.core_fields.each do |field|
+      assert_include field, issue.safe_attribute_names
+    end
+
+    tracker.disabled_core_fields.each do |field|
+      assert_not_include field, issue.safe_attribute_names
+    end
+  end
+
+  def test_safe_attributes_should_ignore_disabled_fields
+    tracker = Tracker.find(1)
+    tracker.core_fields = %w(assigned_to_id due_date)
+    tracker.save!
+
+    issue = Issue.new(:tracker => tracker)
+    issue.safe_attributes = {'start_date' => '2012-07-14', 'due_date' => '2012-07-14'}
+    assert_nil issue.start_date
+    assert_equal Date.parse('2012-07-14'), issue.due_date
+  end
+
+  def test_safe_attributes_should_accept_target_tracker_enabled_fields
+    source = Tracker.find(1)
+    source.core_fields = []
+    source.save!
+    target = Tracker.find(2)
+    target.core_fields = %w(assigned_to_id due_date)
+    target.save!
+
+    issue = Issue.new(:tracker => source)
+    issue.safe_attributes = {'tracker_id' => 2, 'due_date' => '2012-07-14'}
+    assert_equal target, issue.tracker
+    assert_equal Date.parse('2012-07-14'), issue.due_date
+  end
+
+  def test_safe_attributes_should_not_include_readonly_fields
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'due_date',
+                               :rule => 'readonly')
+    user = User.find(2)
+
+    issue = Issue.new(:project_id => 1, :tracker_id => 1)
+    assert_equal %w(due_date), issue.read_only_attribute_names(user)
+    assert_not_include 'due_date', issue.safe_attribute_names(user)
+
+    issue.send :safe_attributes=, {'start_date' => '2012-07-14', 'due_date' => '2012-07-14'}, user
+    assert_equal Date.parse('2012-07-14'), issue.start_date
+    assert_nil issue.due_date
+  end
+
+  def test_safe_attributes_should_not_include_readonly_custom_fields
+    cf1 = IssueCustomField.create!(:name => 'Writable field',
+                                   :field_format => 'string',
+                                   :is_for_all => true, :tracker_ids => [1])
+    cf2 = IssueCustomField.create!(:name => 'Readonly field',
+                                   :field_format => 'string',
+                                   :is_for_all => true, :tracker_ids => [1])
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => cf2.id.to_s,
+                               :rule => 'readonly')
+    user = User.find(2)
+    issue = Issue.new(:project_id => 1, :tracker_id => 1)
+    assert_equal [cf2.id.to_s], issue.read_only_attribute_names(user)
+    assert_not_include cf2.id.to_s, issue.safe_attribute_names(user)
+
+    issue.send :safe_attributes=, {'custom_field_values' => {
+                                       cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'
+                                     }}, user
+    assert_equal 'value1', issue.custom_field_value(cf1)
+    assert_nil issue.custom_field_value(cf2)
+
+    issue.send :safe_attributes=, {'custom_fields' => [
+                                      {'id' => cf1.id.to_s, 'value' => 'valuea'},
+                                      {'id' => cf2.id.to_s, 'value' => 'valueb'}
+                                    ]}, user
+    assert_equal 'valuea', issue.custom_field_value(cf1)
+    assert_nil issue.custom_field_value(cf2)
+  end
+
+  def test_editable_custom_field_values_should_return_non_readonly_custom_values
+    cf1 = IssueCustomField.create!(:name => 'Writable field', :field_format => 'string',
+                                   :is_for_all => true, :tracker_ids => [1, 2])
+    cf2 = IssueCustomField.create!(:name => 'Readonly field', :field_format => 'string',
+                                   :is_for_all => true, :tracker_ids => [1, 2])
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1,
+                               :field_name => cf2.id.to_s, :rule => 'readonly')
+    user = User.find(2)
+
+    issue = Issue.new(:project_id => 1, :tracker_id => 1)
+    values = issue.editable_custom_field_values(user)
+    assert values.detect {|value| value.custom_field == cf1}
+    assert_nil values.detect {|value| value.custom_field == cf2}
+
+    issue.tracker_id = 2
+    values = issue.editable_custom_field_values(user)
+    assert values.detect {|value| value.custom_field == cf1}
+    assert values.detect {|value| value.custom_field == cf2}
+  end
+
+  def test_safe_attributes_should_accept_target_tracker_writable_fields
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'due_date',
+                               :rule => 'readonly')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2,
+                               :role_id => 1, :field_name => 'start_date',
+                               :rule => 'readonly')
+    user = User.find(2)
+
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
+
+    issue.send :safe_attributes=, {'start_date' => '2012-07-12',
+                                   'due_date' => '2012-07-14'}, user
+    assert_equal Date.parse('2012-07-12'), issue.start_date
+    assert_nil issue.due_date
+
+    issue.send :safe_attributes=, {'start_date' => '2012-07-15',
+                                   'due_date' => '2012-07-16',
+                                   'tracker_id' => 2}, user
+    assert_equal Date.parse('2012-07-12'), issue.start_date
+    assert_equal Date.parse('2012-07-16'), issue.due_date
+  end
+
+  def test_safe_attributes_should_accept_target_status_writable_fields
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'due_date',
+                               :rule => 'readonly')
+    WorkflowPermission.create!(:old_status_id => 2, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'start_date',
+                               :rule => 'readonly')
+    user = User.find(2)
+
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
+
+    issue.send :safe_attributes=, {'start_date' => '2012-07-12',
+                                   'due_date' => '2012-07-14'},
+                                   user
+    assert_equal Date.parse('2012-07-12'), issue.start_date
+    assert_nil issue.due_date
+
+    issue.send :safe_attributes=, {'start_date' => '2012-07-15',
+                                    'due_date' => '2012-07-16',
+                                    'status_id' => 2},
+                                  user
+    assert_equal Date.parse('2012-07-12'), issue.start_date
+    assert_equal Date.parse('2012-07-16'), issue.due_date
+  end
+
+  def test_required_attributes_should_be_validated
+    cf = IssueCustomField.create!(:name => 'Foo', :field_format => 'string',
+                                  :is_for_all => true, :tracker_ids => [1, 2])
+
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'due_date',
+                               :rule => 'required')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'category_id',
+                               :rule => 'required')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => cf.id.to_s,
+                               :rule => 'required')
+
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2,
+                               :role_id => 1, :field_name => 'start_date',
+                               :rule => 'required')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2,
+                               :role_id => 1, :field_name => cf.id.to_s,
+                               :rule => 'required')
+    user = User.find(2)
+
+    issue = Issue.new(:project_id => 1, :tracker_id => 1,
+                      :status_id => 1, :subject => 'Required fields',
+                      :author => user)
+    assert_equal [cf.id.to_s, "category_id", "due_date"],
+                 issue.required_attribute_names(user).sort
+    assert !issue.save, "Issue was saved"
+    assert_equal ["Category can't be blank", "Due date can't be blank", "Foo can't be blank"],
+                  issue.errors.full_messages.sort
+
+    issue.tracker_id = 2
+    assert_equal [cf.id.to_s, "start_date"], issue.required_attribute_names(user).sort
+    assert !issue.save, "Issue was saved"
+    assert_equal ["Foo can't be blank", "Start date can't be blank"],
+                 issue.errors.full_messages.sort
+
+    issue.start_date = Date.today
+    issue.custom_field_values = {cf.id.to_s => 'bar'}
+    assert issue.save
+  end
+
+  def test_required_attribute_names_for_multiple_roles_should_intersect_rules
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'due_date',
+                               :rule => 'required')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'start_date',
+                               :rule => 'required')
+    user = User.find(2)
+    member = Member.find(1)
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
+
+    assert_equal %w(due_date start_date), issue.required_attribute_names(user).sort
+
+    member.role_ids = [1, 2]
+    member.save!
+    assert_equal [], issue.required_attribute_names(user.reload)
+
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 2, :field_name => 'due_date',
+                               :rule => 'required')
+    assert_equal %w(due_date), issue.required_attribute_names(user)
+
+    member.role_ids = [1, 2, 3]
+    member.save!
+    assert_equal [], issue.required_attribute_names(user.reload)
+
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 2, :field_name => 'due_date',
+                               :rule => 'readonly')
+    # required + readonly => required
+    assert_equal %w(due_date), issue.required_attribute_names(user)
+  end
+
+  def test_read_only_attribute_names_for_multiple_roles_should_intersect_rules
+    WorkflowPermission.delete_all
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'due_date',
+                               :rule => 'readonly')
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                               :role_id => 1, :field_name => 'start_date',
+                               :rule => 'readonly')
+    user = User.find(2)
+    member = Member.find(1)
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
+
+    assert_equal %w(due_date start_date), issue.read_only_attribute_names(user).sort
+
+    member.role_ids = [1, 2]
+    member.save!
+    assert_equal [], issue.read_only_attribute_names(user.reload)
+
+    WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
+                              :role_id => 2, :field_name => 'due_date',
+                              :rule => 'readonly')
+    assert_equal %w(due_date), issue.read_only_attribute_names(user)
+  end
+
+  def test_copy
+    issue = Issue.new.copy_from(1)
+    assert issue.copy?
+    assert issue.save
+    issue.reload
+    orig = Issue.find(1)
+    assert_equal orig.subject, issue.subject
+    assert_equal orig.tracker, issue.tracker
+    assert_equal "125", issue.custom_value_for(2).value
+  end
+
+  def test_copy_should_copy_status
+    orig = Issue.find(8)
+    assert orig.status != IssueStatus.default
+
+    issue = Issue.new.copy_from(orig)
+    assert issue.save
+    issue.reload
+    assert_equal orig.status, issue.status
+  end
+
+  def test_copy_should_add_relation_with_copied_issue
+    copied = Issue.find(1)
+    issue = Issue.new.copy_from(copied)
+    assert issue.save
+    issue.reload
+
+    assert_equal 1, issue.relations.size
+    relation = issue.relations.first
+    assert_equal 'copied_to', relation.relation_type
+    assert_equal copied, relation.issue_from
+    assert_equal issue, relation.issue_to
+  end
+
+  def test_copy_should_copy_subtasks
+    issue = Issue.generate_with_descendants!
+
+    copy = issue.reload.copy
+    copy.author = User.find(7)
+    assert_difference 'Issue.count', 1+issue.descendants.count do
+      assert copy.save
+    end
+    copy.reload
+    assert_equal %w(Child1 Child2), copy.children.map(&:subject).sort
+    child_copy = copy.children.detect {|c| c.subject == 'Child1'}
+    assert_equal %w(Child11), child_copy.children.map(&:subject).sort
+    assert_equal copy.author, child_copy.author
+  end
+
+  def test_copy_as_a_child_of_copied_issue_should_not_copy_itself
+    parent = Issue.generate!
+    child1 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 1')
+    child2 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 2')
+
+    copy = parent.reload.copy
+    copy.parent_issue_id = parent.id
+    copy.author = User.find(7)
+    assert_difference 'Issue.count', 3 do
+      assert copy.save
+    end
+    parent.reload
+    copy.reload
+    assert_equal parent, copy.parent
+    assert_equal 3, parent.children.count
+    assert_equal 5, parent.descendants.count
+    assert_equal 2, copy.children.count
+    assert_equal 2, copy.descendants.count
+  end
+
+  def test_copy_as_a_descendant_of_copied_issue_should_not_copy_itself
+    parent = Issue.generate!
+    child1 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 1')
+    child2 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 2')
+
+    copy = parent.reload.copy
+    copy.parent_issue_id = child1.id
+    copy.author = User.find(7)
+    assert_difference 'Issue.count', 3 do
+      assert copy.save
+    end
+    parent.reload
+    child1.reload
+    copy.reload
+    assert_equal child1, copy.parent
+    assert_equal 2, parent.children.count
+    assert_equal 5, parent.descendants.count
+    assert_equal 1, child1.children.count
+    assert_equal 3, child1.descendants.count
+    assert_equal 2, copy.children.count
+    assert_equal 2, copy.descendants.count
+  end
+
+  def test_copy_should_copy_subtasks_to_target_project
+    issue = Issue.generate_with_descendants!
+
+    copy = issue.copy(:project_id => 3)
+    assert_difference 'Issue.count', 1+issue.descendants.count do
+      assert copy.save
+    end
+    assert_equal [3], copy.reload.descendants.map(&:project_id).uniq
+  end
+
+  def test_copy_should_not_copy_subtasks_twice_when_saving_twice
+    issue = Issue.generate_with_descendants!
+
+    copy = issue.reload.copy
+    assert_difference 'Issue.count', 1+issue.descendants.count do
+      assert copy.save
+      assert copy.save
+    end
+  end
+
+  def test_should_not_call_after_project_change_on_creation
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1,
+                      :subject => 'Test', :author_id => 1)
+    issue.expects(:after_project_change).never
+    issue.save!
+  end
+
+  def test_should_not_call_after_project_change_on_update
+    issue = Issue.find(1)
+    issue.project = Project.find(1)
+    issue.subject = 'No project change'
+    issue.expects(:after_project_change).never
+    issue.save!
+  end
+
+  def test_should_call_after_project_change_on_project_change
+    issue = Issue.find(1)
+    issue.project = Project.find(2)
+    issue.expects(:after_project_change).once
+    issue.save!
+  end
+
+  def test_adding_journal_should_update_timestamp
+    issue = Issue.find(1)
+    updated_on_was = issue.updated_on
+
+    issue.init_journal(User.first, "Adding notes")
+    assert_difference 'Journal.count' do
+      assert issue.save
+    end
+    issue.reload
+
+    assert_not_equal updated_on_was, issue.updated_on
+  end
+
+  def test_should_close_duplicates
+    # Create 3 issues
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+    issue3 = Issue.generate!
+
+    # 2 is a dupe of 1
+    IssueRelation.create!(:issue_from => issue2, :issue_to => issue1,
+                          :relation_type => IssueRelation::TYPE_DUPLICATES)
+    # And 3 is a dupe of 2
+    IssueRelation.create!(:issue_from => issue3, :issue_to => issue2,
+                          :relation_type => IssueRelation::TYPE_DUPLICATES)
+    # And 3 is a dupe of 1 (circular duplicates)
+    IssueRelation.create!(:issue_from => issue3, :issue_to => issue1,
+                          :relation_type => IssueRelation::TYPE_DUPLICATES)
+
+    assert issue1.reload.duplicates.include?(issue2)
+
+    # Closing issue 1
+    issue1.init_journal(User.first, "Closing issue1")
+    issue1.status = IssueStatus.where(:is_closed => true).first
+    assert issue1.save
+    # 2 and 3 should be also closed
+    assert issue2.reload.closed?
+    assert issue3.reload.closed?
+  end
+
+  def test_should_not_close_duplicated_issue
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+
+    # 2 is a dupe of 1
+    IssueRelation.create(:issue_from => issue2, :issue_to => issue1,
+                         :relation_type => IssueRelation::TYPE_DUPLICATES)
+    # 2 is a dup of 1 but 1 is not a duplicate of 2
+    assert !issue2.reload.duplicates.include?(issue1)
+
+    # Closing issue 2
+    issue2.init_journal(User.first, "Closing issue2")
+    issue2.status = IssueStatus.where(:is_closed => true).first
+    assert issue2.save
+    # 1 should not be also closed
+    assert !issue1.reload.closed?
+  end
+
+  def test_assignable_versions
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
+                      :status_id => 1, :fixed_version_id => 1,
+                      :subject => 'New issue')
+    assert_equal ['open'], issue.assignable_versions.collect(&:status).uniq
+  end
+
+  def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
+                      :status_id => 1, :fixed_version_id => 1,
+                      :subject => 'New issue')
+    assert !issue.save
+    assert_not_nil issue.errors[:fixed_version_id]
+  end
+
+  def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
+                      :status_id => 1, :fixed_version_id => 2,
+                      :subject => 'New issue')
+    assert !issue.save
+    assert_not_nil issue.errors[:fixed_version_id]
+  end
+
+  def test_should_be_able_to_assign_a_new_issue_to_an_open_version
+    issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
+                      :status_id => 1, :fixed_version_id => 3,
+                      :subject => 'New issue')
+    assert issue.save
+  end
+
+  def test_should_be_able_to_update_an_issue_assigned_to_a_closed_version
+    issue = Issue.find(11)
+    assert_equal 'closed', issue.fixed_version.status
+    issue.subject = 'Subject changed'
+    assert issue.save
+  end
+
+  def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
+    issue = Issue.find(11)
+    issue.status_id = 1
+    assert !issue.save
+    assert_not_nil issue.errors[:base]
+  end
+
+  def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
+    issue = Issue.find(11)
+    issue.status_id = 1
+    issue.fixed_version_id = 3
+    assert issue.save
+  end
+
+  def test_should_be_able_to_reopen_an_issue_assigned_to_a_locked_version
+    issue = Issue.find(12)
+    assert_equal 'locked', issue.fixed_version.status
+    issue.status_id = 1
+    assert issue.save
+  end
+
+  def test_should_not_be_able_to_keep_unshared_version_when_changing_project
+    issue = Issue.find(2)
+    assert_equal 2, issue.fixed_version_id
+    issue.project_id = 3
+    assert_nil issue.fixed_version_id
+    issue.fixed_version_id = 2
+    assert !issue.save
+    assert_include 'Target version is not included in the list', issue.errors.full_messages
+  end
+
+  def test_should_keep_shared_version_when_changing_project
+    Version.find(2).update_attribute :sharing, 'tree'
+ 
+    issue = Issue.find(2)
+    assert_equal 2, issue.fixed_version_id
+    issue.project_id = 3
+    assert_equal 2, issue.fixed_version_id
+    assert issue.save
+  end
+
+  def test_allowed_target_projects_on_move_should_include_projects_with_issue_tracking_enabled
+    assert_include Project.find(2), Issue.allowed_target_projects_on_move(User.find(2))
+  end
+
+  def test_allowed_target_projects_on_move_should_not_include_projects_with_issue_tracking_disabled
+    Project.find(2).disable_module! :issue_tracking
+    assert_not_include Project.find(2), Issue.allowed_target_projects_on_move(User.find(2))
+  end
+
+  def test_move_to_another_project_with_same_category
+    issue = Issue.find(1)
+    issue.project = Project.find(2)
+    assert issue.save
+    issue.reload
+    assert_equal 2, issue.project_id
+    # Category changes
+    assert_equal 4, issue.category_id
+    # Make sure time entries were move to the target project
+    assert_equal 2, issue.time_entries.first.project_id
+  end
+
+  def test_move_to_another_project_without_same_category
+    issue = Issue.find(2)
+    issue.project = Project.find(2)
+    assert issue.save
+    issue.reload
+    assert_equal 2, issue.project_id
+    # Category cleared
+    assert_nil issue.category_id
+  end
+
+  def test_move_to_another_project_should_clear_fixed_version_when_not_shared
+    issue = Issue.find(1)
+    issue.update_attribute(:fixed_version_id, 1)
+    issue.project = Project.find(2)
+    assert issue.save
+    issue.reload
+    assert_equal 2, issue.project_id
+    # Cleared fixed_version
+    assert_equal nil, issue.fixed_version
+  end
+
+  def test_move_to_another_project_should_keep_fixed_version_when_shared_with_the_target_project
+    issue = Issue.find(1)
+    issue.update_attribute(:fixed_version_id, 4)
+    issue.project = Project.find(5)
+    assert issue.save
+    issue.reload
+    assert_equal 5, issue.project_id
+    # Keep fixed_version
+    assert_equal 4, issue.fixed_version_id
+  end
+
+  def test_move_to_another_project_should_clear_fixed_version_when_not_shared_with_the_target_project
+    issue = Issue.find(1)
+    issue.update_attribute(:fixed_version_id, 1)
+    issue.project = Project.find(5)
+    assert issue.save
+    issue.reload
+    assert_equal 5, issue.project_id
+    # Cleared fixed_version
+    assert_equal nil, issue.fixed_version
+  end
+
+  def test_move_to_another_project_should_keep_fixed_version_when_shared_systemwide
+    issue = Issue.find(1)
+    issue.update_attribute(:fixed_version_id, 7)
+    issue.project = Project.find(2)
+    assert issue.save
+    issue.reload
+    assert_equal 2, issue.project_id
+    # Keep fixed_version
+    assert_equal 7, issue.fixed_version_id
+  end
+
+  def test_move_to_another_project_should_keep_parent_if_valid
+    issue = Issue.find(1)
+    issue.update_attribute(:parent_issue_id, 2)
+    issue.project = Project.find(3)
+    assert issue.save
+    issue.reload
+    assert_equal 2, issue.parent_id
+  end
+
+  def test_move_to_another_project_should_clear_parent_if_not_valid
+    issue = Issue.find(1)
+    issue.update_attribute(:parent_issue_id, 2)
+    issue.project = Project.find(2)
+    assert issue.save
+    issue.reload
+    assert_nil issue.parent_id
+  end
+
+  def test_move_to_another_project_with_disabled_tracker
+    issue = Issue.find(1)
+    target = Project.find(2)
+    target.tracker_ids = [3]
+    target.save
+    issue.project = target
+    assert issue.save
+    issue.reload
+    assert_equal 2, issue.project_id
+    assert_equal 3, issue.tracker_id
+  end
+
+  def test_copy_to_the_same_project
+    issue = Issue.find(1)
+    copy = issue.copy
+    assert_difference 'Issue.count' do
+      copy.save!
+    end
+    assert_kind_of Issue, copy
+    assert_equal issue.project, copy.project
+    assert_equal "125", copy.custom_value_for(2).value
+  end
+
+  def test_copy_to_another_project_and_tracker
+    issue = Issue.find(1)
+    copy = issue.copy(:project_id => 3, :tracker_id => 2)
+    assert_difference 'Issue.count' do
+      copy.save!
+    end
+    copy.reload
+    assert_kind_of Issue, copy
+    assert_equal Project.find(3), copy.project
+    assert_equal Tracker.find(2), copy.tracker
+    # Custom field #2 is not associated with target tracker
+    assert_nil copy.custom_value_for(2)
+  end
+
+  test "#copy should not create a journal" do
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
+    copy.save!
+    assert_equal 0, copy.reload.journals.size
+  end
+
+  test "#copy should allow assigned_to changes" do
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
+    assert_equal 3, copy.assigned_to_id
+  end
+
+  test "#copy should allow status changes" do
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :status_id => 2)
+    assert_equal 2, copy.status_id
+  end
+
+  test "#copy should allow start date changes" do
+    date = Date.today
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :start_date => date)
+    assert_equal date, copy.start_date
+  end
+
+  test "#copy should allow due date changes" do
+    date = Date.today
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :due_date => date)
+    assert_equal date, copy.due_date
+  end
+
+  test "#copy should set current user as author" do
+    User.current = User.find(9)
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2)
+    assert_equal User.current, copy.author
+  end
+
+  test "#copy should create a journal with notes" do
+    date = Date.today
+    notes = "Notes added when copying"
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :start_date => date)
+    copy.init_journal(User.current, notes)
+    copy.save!
+
+    assert_equal 1, copy.journals.size
+    journal = copy.journals.first
+    assert_equal 0, journal.details.size
+    assert_equal notes, journal.notes
+  end
+
+  def test_valid_parent_project
+    issue = Issue.find(1)
+    issue_in_same_project = Issue.find(2)
+    issue_in_child_project = Issue.find(5)
+    issue_in_grandchild_project = Issue.generate!(:project_id => 6, :tracker_id => 1)
+    issue_in_other_child_project = Issue.find(6)
+    issue_in_different_tree = Issue.find(4)
+
+    with_settings :cross_project_subtasks => '' do
+      assert_equal true, issue.valid_parent_project?(issue_in_same_project)
+      assert_equal false, issue.valid_parent_project?(issue_in_child_project)
+      assert_equal false, issue.valid_parent_project?(issue_in_grandchild_project)
+      assert_equal false, issue.valid_parent_project?(issue_in_different_tree)
+    end
+
+    with_settings :cross_project_subtasks => 'system' do
+      assert_equal true, issue.valid_parent_project?(issue_in_same_project)
+      assert_equal true, issue.valid_parent_project?(issue_in_child_project)
+      assert_equal true, issue.valid_parent_project?(issue_in_different_tree)
+    end
+
+    with_settings :cross_project_subtasks => 'tree' do
+      assert_equal true, issue.valid_parent_project?(issue_in_same_project)
+      assert_equal true, issue.valid_parent_project?(issue_in_child_project)
+      assert_equal true, issue.valid_parent_project?(issue_in_grandchild_project)
+      assert_equal false, issue.valid_parent_project?(issue_in_different_tree)
+
+      assert_equal true, issue_in_child_project.valid_parent_project?(issue_in_same_project)
+      assert_equal true, issue_in_child_project.valid_parent_project?(issue_in_other_child_project)
+    end
+
+    with_settings :cross_project_subtasks => 'descendants' do
+      assert_equal true, issue.valid_parent_project?(issue_in_same_project)
+      assert_equal false, issue.valid_parent_project?(issue_in_child_project)
+      assert_equal false, issue.valid_parent_project?(issue_in_grandchild_project)
+      assert_equal false, issue.valid_parent_project?(issue_in_different_tree)
+
+      assert_equal true, issue_in_child_project.valid_parent_project?(issue)
+      assert_equal false, issue_in_child_project.valid_parent_project?(issue_in_other_child_project)
+    end
+  end
+
+  def test_recipients_should_include_previous_assignee
+    user = User.find(3)
+    user.members.update_all ["mail_notification = ?", false]
+    user.update_attribute :mail_notification, 'only_assigned'
+
+    issue = Issue.find(2)
+    issue.assigned_to = nil
+    assert_include user.mail, issue.recipients
+    issue.save!
+    assert !issue.recipients.include?(user.mail)
+  end
+
+  def test_recipients_should_not_include_users_that_cannot_view_the_issue
+    issue = Issue.find(12)
+    assert issue.recipients.include?(issue.author.mail)
+    # copy the issue to a private project
+    copy  = issue.copy(:project_id => 5, :tracker_id => 2)
+    # author is not a member of project anymore
+    assert !copy.recipients.include?(copy.author.mail)
+  end
+
+  def test_recipients_should_include_the_assigned_group_members
+    group_member = User.generate!
+    group = Group.generate!
+    group.users << group_member
+
+    issue = Issue.find(12)
+    issue.assigned_to = group
+    assert issue.recipients.include?(group_member.mail)
+  end
+
+  def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
+    user = User.find(3)
+    issue = Issue.find(9)
+    Watcher.create!(:user => user, :watchable => issue)
+    assert issue.watched_by?(user)
+    assert !issue.watcher_recipients.include?(user.mail)
+  end
+
+  def test_issue_destroy
+    Issue.find(1).destroy
+    assert_nil Issue.find_by_id(1)
+    assert_nil TimeEntry.find_by_issue_id(1)
+  end
+
+  def test_destroying_a_deleted_issue_should_not_raise_an_error
+    issue = Issue.find(1)
+    Issue.find(1).destroy
+
+    assert_nothing_raised do
+      assert_no_difference 'Issue.count' do
+        issue.destroy
+      end
+      assert issue.destroyed?
+    end
+  end
+
+  def test_destroying_a_stale_issue_should_not_raise_an_error
+    issue = Issue.find(1)
+    Issue.find(1).update_attribute :subject, "Updated"
+
+    assert_nothing_raised do
+      assert_difference 'Issue.count', -1 do
+        issue.destroy
+      end
+      assert issue.destroyed?
+    end
+  end
+
+  def test_blocked
+    blocked_issue = Issue.find(9)
+    blocking_issue = Issue.find(10)
+
+    assert blocked_issue.blocked?
+    assert !blocking_issue.blocked?
+  end
+
+  def test_blocked_issues_dont_allow_closed_statuses
+    blocked_issue = Issue.find(9)
+
+    allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002))
+    assert !allowed_statuses.empty?
+    closed_statuses = allowed_statuses.select {|st| st.is_closed?}
+    assert closed_statuses.empty?
+  end
+
+  def test_unblocked_issues_allow_closed_statuses
+    blocking_issue = Issue.find(10)
+
+    allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002))
+    assert !allowed_statuses.empty?
+    closed_statuses = allowed_statuses.select {|st| st.is_closed?}
+    assert !closed_statuses.empty?
+  end
+
+  def test_reschedule_an_issue_without_dates
+    with_settings :non_working_week_days => [] do
+      issue = Issue.new(:start_date => nil, :due_date => nil)
+      issue.reschedule_on '2012-10-09'.to_date
+      assert_equal '2012-10-09'.to_date, issue.start_date
+      assert_equal '2012-10-09'.to_date, issue.due_date
+    end
+
+    with_settings :non_working_week_days => %w(6 7) do
+      issue = Issue.new(:start_date => nil, :due_date => nil)
+      issue.reschedule_on '2012-10-09'.to_date
+      assert_equal '2012-10-09'.to_date, issue.start_date
+      assert_equal '2012-10-09'.to_date, issue.due_date
+
+      issue = Issue.new(:start_date => nil, :due_date => nil)
+      issue.reschedule_on '2012-10-13'.to_date
+      assert_equal '2012-10-15'.to_date, issue.start_date
+      assert_equal '2012-10-15'.to_date, issue.due_date
+    end
+  end
+
+  def test_reschedule_an_issue_with_start_date
+    with_settings :non_working_week_days => [] do
+      issue = Issue.new(:start_date => '2012-10-09', :due_date => nil)
+      issue.reschedule_on '2012-10-13'.to_date
+      assert_equal '2012-10-13'.to_date, issue.start_date
+      assert_equal '2012-10-13'.to_date, issue.due_date
+    end
+
+    with_settings :non_working_week_days => %w(6 7) do
+      issue = Issue.new(:start_date => '2012-10-09', :due_date => nil)
+      issue.reschedule_on '2012-10-11'.to_date
+      assert_equal '2012-10-11'.to_date, issue.start_date
+      assert_equal '2012-10-11'.to_date, issue.due_date
+
+      issue = Issue.new(:start_date => '2012-10-09', :due_date => nil)
+      issue.reschedule_on '2012-10-13'.to_date
+      assert_equal '2012-10-15'.to_date, issue.start_date
+      assert_equal '2012-10-15'.to_date, issue.due_date
+    end
+  end
+
+  def test_reschedule_an_issue_with_start_and_due_dates
+    with_settings :non_working_week_days => [] do
+      issue = Issue.new(:start_date => '2012-10-09', :due_date => '2012-10-15')
+      issue.reschedule_on '2012-10-13'.to_date
+      assert_equal '2012-10-13'.to_date, issue.start_date
+      assert_equal '2012-10-19'.to_date, issue.due_date
+    end
+
+    with_settings :non_working_week_days => %w(6 7) do
+      issue = Issue.new(:start_date => '2012-10-09', :due_date => '2012-10-19') # 8 working days
+      issue.reschedule_on '2012-10-11'.to_date
+      assert_equal '2012-10-11'.to_date, issue.start_date
+      assert_equal '2012-10-23'.to_date, issue.due_date
+
+      issue = Issue.new(:start_date => '2012-10-09', :due_date => '2012-10-19')
+      issue.reschedule_on '2012-10-13'.to_date
+      assert_equal '2012-10-15'.to_date, issue.start_date
+      assert_equal '2012-10-25'.to_date, issue.due_date
+    end
+  end
+
+  def test_rescheduling_an_issue_to_a_later_due_date_should_reschedule_following_issue
+    issue1 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
+    issue2 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2,
+                          :relation_type => IssueRelation::TYPE_PRECEDES)
+    assert_equal Date.parse('2012-10-18'), issue2.reload.start_date
+
+    issue1.due_date = '2012-10-23'
+    issue1.save!
+    issue2.reload
+    assert_equal Date.parse('2012-10-24'), issue2.start_date
+    assert_equal Date.parse('2012-10-26'), issue2.due_date
+  end
+
+  def test_rescheduling_an_issue_to_an_earlier_due_date_should_reschedule_following_issue
+    issue1 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
+    issue2 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2,
+                          :relation_type => IssueRelation::TYPE_PRECEDES)
+    assert_equal Date.parse('2012-10-18'), issue2.reload.start_date
+
+    issue1.start_date = '2012-09-17'
+    issue1.due_date = '2012-09-18'
+    issue1.save!
+    issue2.reload
+    assert_equal Date.parse('2012-09-19'), issue2.start_date
+    assert_equal Date.parse('2012-09-21'), issue2.due_date
+  end
+
+  def test_rescheduling_reschedule_following_issue_earlier_should_consider_other_preceding_issues
+    issue1 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
+    issue2 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
+    issue3 = Issue.generate!(:start_date => '2012-10-01', :due_date => '2012-10-02')
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2,
+                          :relation_type => IssueRelation::TYPE_PRECEDES)
+    IssueRelation.create!(:issue_from => issue3, :issue_to => issue2,
+                          :relation_type => IssueRelation::TYPE_PRECEDES)
+    assert_equal Date.parse('2012-10-18'), issue2.reload.start_date
+
+    issue1.start_date = '2012-09-17'
+    issue1.due_date = '2012-09-18'
+    issue1.save!
+    issue2.reload
+    # Issue 2 must start after Issue 3
+    assert_equal Date.parse('2012-10-03'), issue2.start_date
+    assert_equal Date.parse('2012-10-05'), issue2.due_date
+  end
+
+  def test_rescheduling_a_stale_issue_should_not_raise_an_error
+    with_settings :non_working_week_days => [] do
+      stale = Issue.find(1)
+      issue = Issue.find(1)
+      issue.subject = "Updated"
+      issue.save!
+      date = 10.days.from_now.to_date
+      assert_nothing_raised do
+        stale.reschedule_on!(date)
+      end
+      assert_equal date, stale.reload.start_date
+    end
+  end
+
+  def test_child_issue_should_consider_parent_soonest_start_on_create
+    set_language_if_valid 'en'
+    issue1 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
+    issue2 = Issue.generate!(:start_date => '2012-10-18', :due_date => '2012-10-20')
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2,
+                          :relation_type => IssueRelation::TYPE_PRECEDES)
+    issue1.reload
+    issue2.reload
+    assert_equal Date.parse('2012-10-18'), issue2.start_date
+
+    child = Issue.new(:parent_issue_id => issue2.id, :start_date => '2012-10-16',
+      :project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Child', :author_id => 1)
+    assert !child.valid?
+    assert_include 'Start date is invalid', child.errors.full_messages
+    assert_equal Date.parse('2012-10-18'), child.soonest_start
+    child.start_date = '2012-10-18'
+    assert child.save
+  end
+
+  def test_setting_parent_to_a_dependent_issue_should_not_validate
+    set_language_if_valid 'en'
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+    issue3 = Issue.generate!
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
+    IssueRelation.create!(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_PRECEDES)
+    issue3.reload
+    issue3.parent_issue_id = issue2.id
+    assert !issue3.valid?
+    assert_include 'Parent task is invalid', issue3.errors.full_messages
+  end
+
+  def test_setting_parent_should_not_allow_circular_dependency
+    set_language_if_valid 'en'
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
+    issue3 = Issue.generate!
+    issue2.reload
+    issue2.parent_issue_id = issue3.id
+    issue2.save!
+    issue4 = Issue.generate!
+    IssueRelation.create!(:issue_from => issue3, :issue_to => issue4, :relation_type => IssueRelation::TYPE_PRECEDES)
+    issue4.reload
+    issue4.parent_issue_id = issue1.id
+    assert !issue4.valid?
+    assert_include 'Parent task is invalid', issue4.errors.full_messages
+  end
+
+  def test_overdue
+    assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
+    assert !Issue.new(:due_date => Date.today).overdue?
+    assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
+    assert !Issue.new(:due_date => nil).overdue?
+    assert !Issue.new(:due_date => 1.day.ago.to_date,
+                      :status => IssueStatus.where(:is_closed => true).first
+                      ).overdue?
+  end
+
+  test "#behind_schedule? should be false if the issue has no start_date" do
+    assert !Issue.new(:start_date => nil,
+                      :due_date => 1.day.from_now.to_date,
+                      :done_ratio => 0).behind_schedule?
+  end
+
+  test "#behind_schedule? should be false if the issue has no end_date" do
+    assert !Issue.new(:start_date => 1.day.from_now.to_date,
+                      :due_date => nil,
+                      :done_ratio => 0).behind_schedule?
+  end
+
+  test "#behind_schedule? should be false if the issue has more done than it's calendar time" do
+    assert !Issue.new(:start_date => 50.days.ago.to_date,
+                      :due_date => 50.days.from_now.to_date,
+                      :done_ratio => 90).behind_schedule?
+  end
+
+  test "#behind_schedule? should be true if the issue hasn't been started at all" do
+    assert Issue.new(:start_date => 1.day.ago.to_date,
+                     :due_date => 1.day.from_now.to_date,
+                     :done_ratio => 0).behind_schedule?
+  end
+
+  test "#behind_schedule? should be true if the issue has used more calendar time than it's done ratio" do
+    assert Issue.new(:start_date => 100.days.ago.to_date,
+                     :due_date => Date.today,
+                     :done_ratio => 90).behind_schedule?
+  end
+
+  test "#assignable_users should be Users" do
+    assert_kind_of User, Issue.find(1).assignable_users.first
+  end
+
+  test "#assignable_users should include the issue author" do
+    non_project_member = User.generate!
+    issue = Issue.generate!(:author => non_project_member)
+
+    assert issue.assignable_users.include?(non_project_member)
+  end
+
+  test "#assignable_users should include the current assignee" do
+    user = User.generate!
+    issue = Issue.generate!(:assigned_to => user)
+    user.lock!
+
+    assert Issue.find(issue.id).assignable_users.include?(user)
+  end
+
+  test "#assignable_users should not show the issue author twice" do
+    assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
+    assert_equal 2, assignable_user_ids.length
+
+    assignable_user_ids.each do |user_id|
+      assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length,
+                   "User #{user_id} appears more or less than once"
+    end
+  end
+
+  test "#assignable_users with issue_group_assignment should include groups" do
+    issue = Issue.new(:project => Project.find(2))
+
+    with_settings :issue_group_assignment => '1' do
+      assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
+      assert issue.assignable_users.include?(Group.find(11))
+    end
+  end
+
+  test "#assignable_users without issue_group_assignment should not include groups" do
+    issue = Issue.new(:project => Project.find(2))
+
+    with_settings :issue_group_assignment => '0' do
+      assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
+      assert !issue.assignable_users.include?(Group.find(11))
+    end
+  end
+
+  def test_create_should_send_email_notification
+    ActionMailer::Base.deliveries.clear
+    issue = Issue.new(:project_id => 1, :tracker_id => 1,
+                      :author_id => 3, :status_id => 1,
+                      :priority => IssuePriority.all.first,
+                      :subject => 'test_create', :estimated_hours => '1:30')
+
+    assert issue.save
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_stale_issue_should_not_send_email_notification
+    ActionMailer::Base.deliveries.clear
+    issue = Issue.find(1)
+    stale = Issue.find(1)
+
+    issue.init_journal(User.find(1))
+    issue.subject = 'Subjet update'
+    assert issue.save
+    assert_equal 1, ActionMailer::Base.deliveries.size
+    ActionMailer::Base.deliveries.clear
+
+    stale.init_journal(User.find(1))
+    stale.subject = 'Another subjet update'
+    assert_raise ActiveRecord::StaleObjectError do
+      stale.save
+    end
+    assert ActionMailer::Base.deliveries.empty?
+  end
+
+  def test_journalized_description
+    IssueCustomField.delete_all
+
+    i = Issue.first
+    old_description = i.description
+    new_description = "This is the new description"
+
+    i.init_journal(User.find(2))
+    i.description = new_description
+    assert_difference 'Journal.count', 1 do
+      assert_difference 'JournalDetail.count', 1 do
+        i.save!
+      end
+    end
+
+    detail = JournalDetail.first(:order => 'id DESC')
+    assert_equal i, detail.journal.journalized
+    assert_equal 'attr', detail.property
+    assert_equal 'description', detail.prop_key
+    assert_equal old_description, detail.old_value
+    assert_equal new_description, detail.value
+  end
+
+  def test_blank_descriptions_should_not_be_journalized
+    IssueCustomField.delete_all
+    Issue.update_all("description = NULL", "id=1")
+
+    i = Issue.find(1)
+    i.init_journal(User.find(2))
+    i.subject = "blank description"
+    i.description = "\r\n"
+
+    assert_difference 'Journal.count', 1 do
+      assert_difference 'JournalDetail.count', 1 do
+        i.save!
+      end
+    end
+  end
+
+  def test_journalized_multi_custom_field
+    field = IssueCustomField.create!(:name => 'filter', :field_format => 'list',
+                                     :is_filter => true, :is_for_all => true,
+                                     :tracker_ids => [1],
+                                     :possible_values => ['value1', 'value2', 'value3'],
+                                     :multiple => true)
+
+    issue = Issue.create!(:project_id => 1, :tracker_id => 1,
+                          :subject => 'Test', :author_id => 1)
+
+    assert_difference 'Journal.count' do
+      assert_difference 'JournalDetail.count' do
+        issue.init_journal(User.first)
+        issue.custom_field_values = {field.id => ['value1']}
+        issue.save!
+      end
+      assert_difference 'JournalDetail.count' do
+        issue.init_journal(User.first)
+        issue.custom_field_values = {field.id => ['value1', 'value2']}
+        issue.save!
+      end
+      assert_difference 'JournalDetail.count', 2 do
+        issue.init_journal(User.first)
+        issue.custom_field_values = {field.id => ['value3', 'value2']}
+        issue.save!
+      end
+      assert_difference 'JournalDetail.count', 2 do
+        issue.init_journal(User.first)
+        issue.custom_field_values = {field.id => nil}
+        issue.save!
+      end
+    end
+  end
+
+  def test_description_eol_should_be_normalized
+    i = Issue.new(:description => "CR \r LF \n CRLF \r\n")
+    assert_equal "CR \r\n LF \r\n CRLF \r\n", i.description
+  end
+
+  def test_saving_twice_should_not_duplicate_journal_details
+    i = Issue.first
+    i.init_journal(User.find(2), 'Some notes')
+    # initial changes
+    i.subject = 'New subject'
+    i.done_ratio = i.done_ratio + 10
+    assert_difference 'Journal.count' do
+      assert i.save
+    end
+    # 1 more change
+    i.priority = IssuePriority.where("id <> ?", i.priority_id).first
+    assert_no_difference 'Journal.count' do
+      assert_difference 'JournalDetail.count', 1 do
+        i.save
+      end
+    end
+    # no more change
+    assert_no_difference 'Journal.count' do
+      assert_no_difference 'JournalDetail.count' do
+        i.save
+      end
+    end
+  end
+
+  def test_all_dependent_issues
+    IssueRelation.delete_all
+    assert IssueRelation.create!(:issue_from => Issue.find(1),
+                                 :issue_to   => Issue.find(2),
+                                 :relation_type => IssueRelation::TYPE_PRECEDES)
+    assert IssueRelation.create!(:issue_from => Issue.find(2),
+                                 :issue_to   => Issue.find(3),
+                                 :relation_type => IssueRelation::TYPE_PRECEDES)
+    assert IssueRelation.create!(:issue_from => Issue.find(3),
+                                 :issue_to   => Issue.find(8),
+                                 :relation_type => IssueRelation::TYPE_PRECEDES)
+
+    assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
+  end
+
+  def test_all_dependent_issues_with_persistent_circular_dependency
+    IssueRelation.delete_all
+    assert IssueRelation.create!(:issue_from => Issue.find(1),
+                                 :issue_to   => Issue.find(2),
+                                 :relation_type => IssueRelation::TYPE_PRECEDES)
+    assert IssueRelation.create!(:issue_from => Issue.find(2),
+                                 :issue_to   => Issue.find(3),
+                                 :relation_type => IssueRelation::TYPE_PRECEDES)
+
+    r = IssueRelation.create!(:issue_from => Issue.find(3),
+                             :issue_to   => Issue.find(7),
+                             :relation_type => IssueRelation::TYPE_PRECEDES)
+    IssueRelation.update_all("issue_to_id = 1", ["id = ?", r.id])
+    
+    assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort
+  end
+
+  def test_all_dependent_issues_with_persistent_multiple_circular_dependencies
+    IssueRelation.delete_all
+    assert IssueRelation.create!(:issue_from => Issue.find(1),
+                                 :issue_to   => Issue.find(2),
+                                 :relation_type => IssueRelation::TYPE_RELATES)
+    assert IssueRelation.create!(:issue_from => Issue.find(2),
+                                 :issue_to   => Issue.find(3),
+                                 :relation_type => IssueRelation::TYPE_RELATES)
+    assert IssueRelation.create!(:issue_from => Issue.find(3),
+                                 :issue_to   => Issue.find(8),
+                                 :relation_type => IssueRelation::TYPE_RELATES)
+
+    r = IssueRelation.create!(:issue_from => Issue.find(8),
+                             :issue_to   => Issue.find(7),
+                             :relation_type => IssueRelation::TYPE_RELATES)
+    IssueRelation.update_all("issue_to_id = 2", ["id = ?", r.id])
+    
+    r = IssueRelation.create!(:issue_from => Issue.find(3),
+                             :issue_to   => Issue.find(7),
+                             :relation_type => IssueRelation::TYPE_RELATES)
+    IssueRelation.update_all("issue_to_id = 1", ["id = ?", r.id])
+
+    assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
+  end
+
+  test "#done_ratio should use the issue_status according to Setting.issue_done_ratio" do
+    @issue = Issue.find(1)
+    @issue_status = IssueStatus.find(1)
+    @issue_status.update_attribute(:default_done_ratio, 50)
+    @issue2 = Issue.find(2)
+    @issue_status2 = IssueStatus.find(2)
+    @issue_status2.update_attribute(:default_done_ratio, 0)
+
+    with_settings :issue_done_ratio => 'issue_field' do
+      assert_equal 0, @issue.done_ratio
+      assert_equal 30, @issue2.done_ratio
+    end
+
+    with_settings :issue_done_ratio => 'issue_status' do
+      assert_equal 50, @issue.done_ratio
+      assert_equal 0, @issue2.done_ratio
+    end
+  end
+
+  test "#update_done_ratio_from_issue_status should update done_ratio according to Setting.issue_done_ratio" do
+    @issue = Issue.find(1)
+    @issue_status = IssueStatus.find(1)
+    @issue_status.update_attribute(:default_done_ratio, 50)
+    @issue2 = Issue.find(2)
+    @issue_status2 = IssueStatus.find(2)
+    @issue_status2.update_attribute(:default_done_ratio, 0)
+
+    with_settings :issue_done_ratio => 'issue_field' do
+      @issue.update_done_ratio_from_issue_status
+      @issue2.update_done_ratio_from_issue_status
+
+      assert_equal 0, @issue.read_attribute(:done_ratio)
+      assert_equal 30, @issue2.read_attribute(:done_ratio)
+    end
+
+    with_settings :issue_done_ratio => 'issue_status' do
+      @issue.update_done_ratio_from_issue_status
+      @issue2.update_done_ratio_from_issue_status
+
+      assert_equal 50, @issue.read_attribute(:done_ratio)
+      assert_equal 0, @issue2.read_attribute(:done_ratio)
+    end
+  end
+
+  test "#by_tracker" do
+    User.current = User.anonymous
+    groups = Issue.by_tracker(Project.find(1))
+    assert_equal 3, groups.size
+    assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
+  end
+
+  test "#by_version" do
+    User.current = User.anonymous
+    groups = Issue.by_version(Project.find(1))
+    assert_equal 3, groups.size
+    assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
+  end
+
+  test "#by_priority" do
+    User.current = User.anonymous
+    groups = Issue.by_priority(Project.find(1))
+    assert_equal 4, groups.size
+    assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
+  end
+
+  test "#by_category" do
+    User.current = User.anonymous
+    groups = Issue.by_category(Project.find(1))
+    assert_equal 2, groups.size
+    assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
+  end
+
+  test "#by_assigned_to" do
+    User.current = User.anonymous
+    groups = Issue.by_assigned_to(Project.find(1))
+    assert_equal 2, groups.size
+    assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
+  end
+
+  test "#by_author" do
+    User.current = User.anonymous
+    groups = Issue.by_author(Project.find(1))
+    assert_equal 4, groups.size
+    assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
+  end
+
+  test "#by_subproject" do
+    User.current = User.anonymous
+    groups = Issue.by_subproject(Project.find(1))
+    # Private descendant not visible
+    assert_equal 1, groups.size
+    assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
+  end
+
+  def test_recently_updated_scope
+    #should return the last updated issue
+    assert_equal Issue.reorder("updated_on DESC").first, Issue.recently_updated.limit(1).first
+  end
+
+  def test_on_active_projects_scope
+    assert Project.find(2).archive
+
+    before = Issue.on_active_project.length
+    # test inclusion to results
+    issue = Issue.generate!(:tracker => Project.find(2).trackers.first)
+    assert_equal before + 1, Issue.on_active_project.length
+
+    # Move to an archived project
+    issue.project = Project.find(2)
+    assert issue.save
+    assert_equal before, Issue.on_active_project.length
+  end
+
+  test "Issue#recipients should include project recipients" do
+    issue = Issue.generate!
+    assert issue.project.recipients.present?
+    issue.project.recipients.each do |project_recipient|
+      assert issue.recipients.include?(project_recipient)
+    end
+  end
+
+  test "Issue#recipients should include the author if the author is active" do
+    issue = Issue.generate!(:author => User.generate!)
+    assert issue.author, "No author set for Issue"
+    assert issue.recipients.include?(issue.author.mail)
+  end
+
+  test "Issue#recipients should include the assigned to user if the assigned to user is active" do
+    issue = Issue.generate!(:assigned_to => User.generate!)
+    assert issue.assigned_to, "No assigned_to set for Issue"
+    assert issue.recipients.include?(issue.assigned_to.mail)
+  end
+
+  test "Issue#recipients should not include users who opt out of all email" do
+    issue = Issue.generate!(:author => User.generate!)
+    issue.author.update_attribute(:mail_notification, :none)
+    assert !issue.recipients.include?(issue.author.mail)
+  end
+
+  test "Issue#recipients should not include the issue author if they are only notified of assigned issues" do
+    issue = Issue.generate!(:author => User.generate!)
+    issue.author.update_attribute(:mail_notification, :only_assigned)
+    assert !issue.recipients.include?(issue.author.mail)
+  end
+
+  test "Issue#recipients should not include the assigned user if they are only notified of owned issues" do
+    issue = Issue.generate!(:assigned_to => User.generate!)
+    issue.assigned_to.update_attribute(:mail_notification, :only_owner)
+    assert !issue.recipients.include?(issue.assigned_to.mail)
+  end
+
+  def test_last_journal_id_with_journals_should_return_the_journal_id
+    assert_equal 2, Issue.find(1).last_journal_id
+  end
+
+  def test_last_journal_id_without_journals_should_return_nil
+    assert_nil Issue.find(3).last_journal_id
+  end
+
+  def test_journals_after_should_return_journals_with_greater_id
+    assert_equal [Journal.find(2)], Issue.find(1).journals_after('1')
+    assert_equal [], Issue.find(1).journals_after('2')
+  end
+
+  def test_journals_after_with_blank_arg_should_return_all_journals
+    assert_equal [Journal.find(1), Journal.find(2)], Issue.find(1).journals_after('')
+  end
+
+  def test_css_classes_should_include_tracker
+    issue = Issue.new(:tracker => Tracker.find(2))
+    classes = issue.css_classes.split(' ')
+    assert_include 'tracker-2', classes
+  end
+
+  def test_css_classes_should_include_priority
+    issue = Issue.new(:priority => IssuePriority.find(8))
+    classes = issue.css_classes.split(' ')
+    assert_include 'priority-8', classes
+    assert_include 'priority-highest', classes
+  end
+
+  def test_save_attachments_with_hash_should_save_attachments_in_keys_order
+    set_tmp_attachments_directory
+    issue = Issue.generate!
+    issue.save_attachments({
+      'p0' => {'file' => mock_file_with_options(:original_filename => 'upload')},
+      '3' => {'file' => mock_file_with_options(:original_filename => 'bar')},
+      '1' => {'file' => mock_file_with_options(:original_filename => 'foo')}
+    })
+    issue.attach_saved_attachments
+
+    assert_equal 3, issue.reload.attachments.count
+    assert_equal %w(upload foo bar), issue.attachments.map(&:filename)
+  end
+
+  def test_closed_on_should_be_nil_when_creating_an_open_issue
+    issue = Issue.generate!(:status_id => 1).reload
+    assert !issue.closed?
+    assert_nil issue.closed_on
+  end
+
+  def test_closed_on_should_be_set_when_creating_a_closed_issue
+    issue = Issue.generate!(:status_id => 5).reload
+    assert issue.closed?
+    assert_not_nil issue.closed_on
+    assert_equal issue.updated_on, issue.closed_on
+    assert_equal issue.created_on, issue.closed_on
+  end
+
+  def test_closed_on_should_be_nil_when_updating_an_open_issue
+    issue = Issue.find(1)
+    issue.subject = 'Not closed yet'
+    issue.save!
+    issue.reload
+    assert_nil issue.closed_on
+  end
+
+  def test_closed_on_should_be_set_when_closing_an_open_issue
+    issue = Issue.find(1)
+    issue.subject = 'Now closed'
+    issue.status_id = 5
+    issue.save!
+    issue.reload
+    assert_not_nil issue.closed_on
+    assert_equal issue.updated_on, issue.closed_on
+  end
+
+  def test_closed_on_should_not_be_updated_when_updating_a_closed_issue
+    issue = Issue.open(false).first
+    was_closed_on = issue.closed_on
+    assert_not_nil was_closed_on
+    issue.subject = 'Updating a closed issue'
+    issue.save!
+    issue.reload
+    assert_equal was_closed_on, issue.closed_on
+  end
+
+  def test_closed_on_should_be_preserved_when_reopening_a_closed_issue
+    issue = Issue.open(false).first
+    was_closed_on = issue.closed_on
+    assert_not_nil was_closed_on
+    issue.subject = 'Reopening a closed issue'
+    issue.status_id = 1
+    issue.save!
+    issue.reload
+    assert !issue.closed?
+    assert_equal was_closed_on, issue.closed_on
+  end
+
+  def test_status_was_should_return_nil_for_new_issue
+    issue = Issue.new
+    assert_nil issue.status_was
+  end
+
+  def test_status_was_should_return_status_before_change
+    issue = Issue.find(1)
+    issue.status = IssueStatus.find(2)
+    assert_equal IssueStatus.find(1), issue.status_was
+  end
+
+  def test_status_was_should_be_reset_on_save
+    issue = Issue.find(1)
+    issue.status = IssueStatus.find(2)
+    assert_equal IssueStatus.find(1), issue.status_was
+    assert issue.save!
+    assert_equal IssueStatus.find(2), issue.status_was
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a7c6b64e7ff32670d95a0267494d6a79be487e89.svn-base
--- /dev/null
+++ b/.svn/pristine/a7/a7c6b64e7ff32670d95a0267494d6a79be487e89.svn-base
@@ -0,0 +1,1109 @@
+pt-BR:
+  direction: ltr
+  date:
+    formats:
+      default: "%d/%m/%Y"
+      short: "%d de %B"
+      long: "%d de %B de %Y"
+      only_day: "%d"
+
+    day_names: [Domingo, Segunda, TerÃ§a, Quarta, Quinta, Sexta, SÃ¡bado]
+    abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, SÃ¡b]
+    month_names: [~, Janeiro, Fevereiro, MarÃ§o, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro]
+    abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%A, %d de %B de %Y, %H:%M h"
+      time: "%H:%M h"
+      short: "%d/%m, %H:%M h"
+      long: "%A, %d de %B de %Y, %H:%M h"
+      only_second: "%S"
+      datetime:
+        formats:
+          default: "%Y-%m-%dT%H:%M:%S%Z"
+    am: ''
+    pm: ''
+
+  # date helper distancia em palavras
+  datetime:
+    distance_in_words:
+      half_a_minute: 'meio minuto'
+      less_than_x_seconds:
+        one: 'menos de 1 segundo'
+        other: 'menos de %{count} segundos'
+
+      x_seconds:
+        one: '1 segundo'
+        other: '%{count} segundos'
+
+      less_than_x_minutes:
+        one: 'menos de um minuto'
+        other: 'menos de %{count} minutos'
+
+      x_minutes:
+        one: '1 minuto'
+        other: '%{count} minutos'
+
+      about_x_hours:
+        one: 'aproximadamente 1 hora'
+        other: 'aproximadamente %{count} horas'
+      x_hours:
+        one:   "1 hora"
+        other: "%{count} horas"
+
+      x_days:
+        one: '1 dia'
+        other: '%{count} dias'
+
+      about_x_months:
+        one: 'aproximadamente 1 mÃªs'
+        other: 'aproximadamente %{count} meses'
+
+      x_months:
+        one: '1 mÃªs'
+        other: '%{count} meses'
+
+      about_x_years:
+        one: 'aproximadamente 1 ano'
+        other: 'aproximadamente %{count} anos'
+
+      over_x_years:
+        one: 'mais de 1 ano'
+        other: 'mais de %{count} anos'
+      almost_x_years:
+        one:   "quase 1 ano"
+        other: "quase %{count} anos"
+
+  # numeros
+  number:
+    format:
+      precision: 3
+      separator: ','
+      delimiter: '.'
+    currency:
+      format:
+        unit: 'R$'
+        precision: 2
+        format: '%u %n'
+        separator: ','
+        delimiter: '.'
+    percentage:
+      format:
+        delimiter: '.'
+    precision:
+      format:
+        delimiter: '.'
+    human:
+      format:
+        precision: 3
+        delimiter: '.'
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+  support:
+    array:
+      sentence_connector: "e"
+      skip_last_comma: true
+
+  # Active Record
+  activerecord:
+    errors:
+      template:
+        header:
+          one: "modelo nÃ£o pode ser salvo: 1 erro"
+          other: "modelo nÃ£o pode ser salvo: %{count} erros."
+        body: "Por favor, verifique os seguintes campos:"
+      messages:
+        inclusion: "nÃ£o estÃ¡ incluso na lista"
+        exclusion: "nÃ£o estÃ¡ disponÃ­vel"
+        invalid: "nÃ£o Ã© vÃ¡lido"
+        confirmation: "nÃ£o estÃ¡ de acordo com a confirmaÃ§Ã£o"
+        accepted: "precisa ser aceito"
+        empty: "nÃ£o pode ficar vazio"
+        blank: "nÃ£o pode ficar vazio"
+        too_long: "Ã© muito longo (mÃ¡ximo: %{count} caracteres)"
+        too_short: "Ã© muito curto (mÃ­nimo: %{count} caracteres)"
+        wrong_length: "deve ter %{count} caracteres"
+        taken: "nÃ£o estÃ¡ disponÃ­vel"
+        not_a_number: "nÃ£o Ã© um nÃºmero"
+        greater_than: "precisa ser maior do que %{count}"
+        greater_than_or_equal_to: "precisa ser maior ou igual a %{count}"
+        equal_to: "precisa ser igual a %{count}"
+        less_than: "precisa ser menor do que %{count}"
+        less_than_or_equal_to: "precisa ser menor ou igual a %{count}"
+        odd: "precisa ser Ã­mpar"
+        even: "precisa ser par"
+        greater_than_start_date: "deve ser maior que a data inicial"
+        not_same_project: "nÃ£o pertence ao mesmo projeto"
+        circular_dependency: "Esta relaÃ§Ã£o geraria uma dependÃªncia circular"
+        cant_link_an_issue_with_a_descendant: "Uma tarefa nÃ£o pode ser relaciona a uma de suas subtarefas"
+
+  actionview_instancetag_blank_option: Selecione
+
+  general_text_No: 'NÃ£o'
+  general_text_Yes: 'Sim'
+  general_text_no: 'nÃ£o'
+  general_text_yes: 'sim'
+  general_lang_name: 'PortuguÃªs(Brasil)'
+  general_csv_separator: ';'
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Conta atualizada com sucesso.
+  notice_account_invalid_creditentials: UsuÃ¡rio ou senha invÃ¡lido.
+  notice_account_password_updated: Senha alterada com sucesso.
+  notice_account_wrong_password: Senha invÃ¡lida.
+  notice_account_register_done: Conta criada com sucesso. Para ativar sua conta, clique no link que lhe foi enviado por e-mail.
+  notice_account_unknown_email: UsuÃ¡rio desconhecido.
+  notice_can_t_change_password: Esta conta utiliza autenticaÃ§Ã£o externa. NÃ£o Ã© possÃ­vel alterar a senha.
+  notice_account_lost_email_sent: Um e-mail com instruÃ§Ãµes para escolher uma nova senha foi enviado para vocÃª.
+  notice_account_activated: Sua conta foi ativada. VocÃª pode acessÃ¡-la agora.
+  notice_successful_create: Criado com sucesso.
+  notice_successful_update: Alterado com sucesso.
+  notice_successful_delete: ExcluÃ­do com sucesso.
+  notice_successful_connection: Conectado com sucesso.
+  notice_file_not_found: A pÃ¡gina que vocÃª estÃ¡ tentando acessar nÃ£o existe ou foi excluÃ­da.
+  notice_locking_conflict: Os dados foram atualizados por outro usuÃ¡rio.
+  notice_not_authorized: VocÃª nÃ£o estÃ¡ autorizado a acessar esta pÃ¡gina.
+  notice_email_sent: "Um e-mail foi enviado para %{value}"
+  notice_email_error: "Ocorreu um erro ao enviar o e-mail (%{value})"
+  notice_feeds_access_key_reseted: Sua chave RSS foi reconfigurada.
+  notice_failed_to_save_issues: "Problema ao salvar %{count} tarefa(s) de %{total} selecionadas: %{ids}."
+  notice_no_issue_selected: "Nenhuma tarefa selecionada! Por favor, marque as tarefas que vocÃª deseja editar."
+  notice_account_pending: "Sua conta foi criada e estÃ¡ aguardando aprovaÃ§Ã£o do administrador."
+  notice_default_data_loaded: ConfiguraÃ§Ã£o padrÃ£o carregada com sucesso.
+
+  error_can_t_load_default_data: "A configuraÃ§Ã£o padrÃ£o nÃ£o pode ser carregada: %{value}"
+  error_scm_not_found: "A entrada e/ou a revisÃ£o nÃ£o existe no repositÃ³rio."
+  error_scm_command_failed: "Ocorreu um erro ao tentar acessar o repositÃ³rio: %{value}"
+  error_scm_annotate: "Esta entrada nÃ£o existe ou nÃ£o pode ser anotada."
+  error_issue_not_found_in_project: 'A tarefa nÃ£o foi encontrada ou nÃ£o pertence a este projeto'
+  error_no_tracker_in_project: 'NÃ£o hÃ¡ um tipo de tarefa associado a este projeto. Favor verificar as configuraÃ§Ãµes do projeto.'
+  error_no_default_issue_status: 'A situaÃ§Ã£o padrÃ£o para tarefa nÃ£o estÃ¡ definida. Favor verificar sua configuraÃ§Ã£o (VÃ¡ em "AdministraÃ§Ã£o -> SituaÃ§Ã£o da tarefa").'
+
+  mail_subject_lost_password: "Sua senha do %{value}."
+  mail_body_lost_password: 'Para mudar sua senha, clique no link abaixo:'
+  mail_subject_register: "AtivaÃ§Ã£o de conta do %{value}."
+  mail_body_register: 'Para ativar sua conta, clique no link abaixo:'
+  mail_body_account_information_external: "VocÃª pode usar sua conta do %{value} para entrar."
+  mail_body_account_information: InformaÃ§Ãµes sobre sua conta
+  mail_subject_account_activation_request: "%{value} - RequisiÃ§Ã£o de ativaÃ§Ã£o de conta"
+  mail_body_account_activation_request: "Um novo usuÃ¡rio (%{value}) se registrou. A conta estÃ¡ aguardando sua aprovaÃ§Ã£o:"
+  mail_subject_reminder: "%{count} tarefa(s) com data prevista para os prÃ³ximos %{days} dias"
+  mail_body_reminder: "%{count} tarefa(s) para vocÃª com data prevista para os prÃ³ximos %{days} dias:"
+
+
+  field_name: Nome
+  field_description: DescriÃ§Ã£o
+  field_summary: Resumo
+  field_is_required: ObrigatÃ³rio
+  field_firstname: Nome
+  field_lastname: Sobrenome
+  field_mail: E-mail
+  field_filename: Arquivo
+  field_filesize: Tamanho
+  field_downloads: Downloads
+  field_author: Autor
+  field_created_on: Criado em
+  field_updated_on: Alterado em
+  field_field_format: Formato
+  field_is_for_all: Para todos os projetos
+  field_possible_values: PossÃ­veis valores
+  field_regexp: ExpressÃ£o regular
+  field_min_length: Tamanho mÃ­nimo
+  field_max_length: Tamanho mÃ¡ximo
+  field_value: Valor
+  field_category: Categoria
+  field_title: TÃ­tulo
+  field_project: Projeto
+  field_issue: Tarefa
+  field_status: SituaÃ§Ã£o
+  field_notes: Notas
+  field_is_closed: Tarefa fechada
+  field_is_default: SituaÃ§Ã£o padrÃ£o
+  field_tracker: Tipo
+  field_subject: TÃ­tulo
+  field_due_date: Data prevista
+  field_assigned_to: AtribuÃ­do para
+  field_priority: Prioridade
+  field_fixed_version: VersÃ£o
+  field_user: UsuÃ¡rio
+  field_role: Cargo
+  field_homepage: PÃ¡gina do projeto
+  field_is_public: PÃºblico
+  field_parent: Sub-projeto de
+  field_is_in_roadmap: Exibir no planejamento
+  field_login: UsuÃ¡rio
+  field_mail_notification: NotificaÃ§Ãµes por e-mail
+  field_admin: Administrador
+  field_last_login_on: Ãšltima conexÃ£o
+  field_language: Idioma
+  field_effective_date: Data
+  field_password: Senha
+  field_new_password: Nova senha
+  field_password_confirmation: ConfirmaÃ§Ã£o
+  field_version: VersÃ£o
+  field_type: Tipo
+  field_host: Servidor
+  field_port: Porta
+  field_account: Conta
+  field_base_dn: DN Base
+  field_attr_login: Atributo para nome de usuÃ¡rio
+  field_attr_firstname: Atributo para nome
+  field_attr_lastname: Atributo para sobrenome
+  field_attr_mail: Atributo para e-mail
+  field_onthefly: Criar usuÃ¡rios dinamicamente ("on-the-fly")
+  field_start_date: InÃ­cio
+  field_done_ratio: "% Terminado"
+  field_auth_source: Modo de autenticaÃ§Ã£o
+  field_hide_mail: Ocultar meu e-mail
+  field_comments: ComentÃ¡rio
+  field_url: URL
+  field_start_page: PÃ¡gina inicial
+  field_subproject: Sub-projeto
+  field_hours: Horas
+  field_activity: Atividade
+  field_spent_on: Data
+  field_identifier: Identificador
+  field_is_filter: Ã‰ um filtro
+  field_issue_to: Tarefa relacionada
+  field_delay: Atraso
+  field_assignable: Tarefas podem ser atribuÃ­das a este papel
+  field_redirect_existing_links: Redirecionar links existentes
+  field_estimated_hours: Tempo estimado
+  field_column_names: Colunas
+  field_time_zone: Fuso-horÃ¡rio
+  field_searchable: PesquisÃ¡vel
+  field_default_value: PadrÃ£o
+  field_comments_sorting: Visualizar comentÃ¡rios
+  field_parent_title: PÃ¡gina pai
+
+  setting_app_title: TÃ­tulo da aplicaÃ§Ã£o
+  setting_app_subtitle: Sub-tÃ­tulo da aplicaÃ§Ã£o
+  setting_welcome_text: Texto de boas-vindas
+  setting_default_language: Idioma padrÃ£o
+  setting_login_required: Exigir autenticaÃ§Ã£o
+  setting_self_registration: Permitido Auto-registro
+  setting_attachment_max_size: Tamanho mÃ¡ximo do anexo
+  setting_issues_export_limit: Limite de exportaÃ§Ã£o das tarefas
+  setting_mail_from: E-mail enviado de
+  setting_bcc_recipients: Enviar com cÃ³pia oculta (cco)
+  setting_host_name: Nome do Servidor e subdomÃ­nio
+  setting_text_formatting: FormataÃ§Ã£o do texto
+  setting_wiki_compression: CompactaÃ§Ã£o de histÃ³rico do Wiki
+  setting_feeds_limit: NÃºmero de registros por Feed
+  setting_default_projects_public: Novos projetos sÃ£o pÃºblicos por padrÃ£o
+  setting_autofetch_changesets: Obter commits automaticamente
+  setting_sys_api_enabled: Ativa WS para gerenciamento do repositÃ³rio (SVN)
+  setting_commit_ref_keywords: Palavras de referÃªncia
+  setting_commit_fix_keywords: Palavras de fechamento
+  setting_autologin: Auto-login
+  setting_date_format: Formato da data
+  setting_time_format: Formato de hora
+  setting_cross_project_issue_relations: Permitir relacionar tarefas entre projetos
+  setting_issue_list_default_columns: Colunas padrÃ£o visÃ­veis na lista de tarefas
+  setting_emails_footer: RodapÃ© do e-mail
+  setting_protocol: Protocolo
+  setting_per_page_options: NÃºmero de itens exibidos por pÃ¡gina
+  setting_user_format: Formato de exibiÃ§Ã£o de nome de usuÃ¡rio
+  setting_activity_days_default: Dias visualizados na atividade do projeto
+  setting_display_subprojects_issues: Visualizar tarefas dos subprojetos nos projetos principais por padrÃ£o
+  setting_enabled_scm: SCM habilitados
+  setting_mail_handler_api_enabled: Habilitar WS para e-mails de entrada
+  setting_mail_handler_api_key: Chave de API
+  setting_sequential_project_identifiers: Gerar identificadores sequenciais de projeto
+
+  project_module_issue_tracking: Gerenciamento de Tarefas
+  project_module_time_tracking: Gerenciamento de tempo
+  project_module_news: NotÃ­cias
+  project_module_documents: Documentos
+  project_module_files: Arquivos
+  project_module_wiki: Wiki
+  project_module_repository: RepositÃ³rio
+  project_module_boards: FÃ³runs
+
+  label_user: UsuÃ¡rio
+  label_user_plural: UsuÃ¡rios
+  label_user_new: Novo usuÃ¡rio
+  label_project: Projeto
+  label_project_new: Novo projeto
+  label_project_plural: Projetos
+  label_x_projects:
+    zero:  nenhum projeto
+    one:   1 projeto
+    other: "%{count} projetos"
+  label_project_all: Todos os projetos
+  label_project_latest: Ãšltimos projetos
+  label_issue: Tarefa
+  label_issue_new: Nova tarefa
+  label_issue_plural: Tarefas
+  label_issue_view_all: Ver todas as tarefas
+  label_issues_by: "Tarefas por %{value}"
+  label_issue_added: Tarefa adicionada
+  label_issue_updated: Tarefa atualizada
+  label_issue_note_added: Nota adicionada
+  label_issue_status_updated: SituaÃ§Ã£o atualizada
+  label_issue_priority_updated: Prioridade atualizada
+  label_document: Documento
+  label_document_new: Novo documento
+  label_document_plural: Documentos
+  label_document_added: Documento adicionado
+  label_role: Papel
+  label_role_plural: PapÃ©is
+  label_role_new: Novo papel
+  label_role_and_permissions: PapÃ©is e permissÃµes
+  label_member: Membro
+  label_member_new: Novo membro
+  label_member_plural: Membros
+  label_tracker: Tipo de tarefa
+  label_tracker_plural: Tipos de tarefas
+  label_tracker_new: Novo tipo
+  label_workflow: Fluxo de trabalho
+  label_issue_status: SituaÃ§Ã£o da tarefa
+  label_issue_status_plural: SituaÃ§Ã£o das tarefas
+  label_issue_status_new: Nova situaÃ§Ã£o
+  label_issue_category: Categoria da tarefa
+  label_issue_category_plural: Categorias das tarefas
+  label_issue_category_new: Nova categoria
+  label_custom_field: Campo personalizado
+  label_custom_field_plural: Campos personalizados
+  label_custom_field_new: Novo campo personalizado
+  label_enumerations: 'Tipos & Categorias'
+  label_enumeration_new: Novo
+  label_information: InformaÃ§Ã£o
+  label_information_plural: InformaÃ§Ãµes
+  label_please_login: Efetue o login
+  label_register: Cadastre-se
+  label_password_lost: Perdi minha senha
+  label_home: PÃ¡gina inicial
+  label_my_page: Minha pÃ¡gina
+  label_my_account: Minha conta
+  label_my_projects: Meus projetos
+  label_administration: AdministraÃ§Ã£o
+  label_login: Entrar
+  label_logout: Sair
+  label_help: Ajuda
+  label_reported_issues: Tarefas reportadas
+  label_assigned_to_me_issues: Minhas tarefas
+  label_last_login: Ãšltima conexÃ£o
+  label_registered_on: Registrado em
+  label_activity: Atividade
+  label_overall_activity: Atividades gerais
+  label_new: Novo
+  label_logged_as: "Acessando como:"
+  label_environment: Ambiente
+  label_authentication: AutenticaÃ§Ã£o
+  label_auth_source: Modo de autenticaÃ§Ã£o
+  label_auth_source_new: Novo modo de autenticaÃ§Ã£o
+  label_auth_source_plural: Modos de autenticaÃ§Ã£o
+  label_subproject_plural: Sub-projetos
+  label_and_its_subprojects: "%{value} e seus sub-projetos"
+  label_min_max_length: Tamanho mÃ­n-mÃ¡x
+  label_list: Lista
+  label_date: Data
+  label_integer: Inteiro
+  label_float: Decimal
+  label_boolean: Boleano
+  label_string: Texto
+  label_text: Texto longo
+  label_attribute: Atributo
+  label_attribute_plural: Atributos
+  label_no_data: Nenhuma informaÃ§Ã£o disponÃ­vel
+  label_change_status: Alterar situaÃ§Ã£o
+  label_history: HistÃ³rico
+  label_attachment: Arquivo
+  label_attachment_new: Novo arquivo
+  label_attachment_delete: Excluir arquivo
+  label_attachment_plural: Arquivos
+  label_file_added: Arquivo adicionado
+  label_report: RelatÃ³rio
+  label_report_plural: RelatÃ³rio
+  label_news: NotÃ­cia
+  label_news_new: Adicionar notÃ­cia
+  label_news_plural: NotÃ­cias
+  label_news_latest: Ãšltimas notÃ­cias
+  label_news_view_all: Ver todas as notÃ­cias
+  label_news_added: NotÃ­cia adicionada
+  label_settings: ConfiguraÃ§Ãµes
+  label_overview: VisÃ£o geral
+  label_version: VersÃ£o
+  label_version_new: Nova versÃ£o
+  label_version_plural: VersÃµes
+  label_confirmation: ConfirmaÃ§Ã£o
+  label_export_to: Exportar para
+  label_read: Ler...
+  label_public_projects: Projetos pÃºblicos
+  label_open_issues: Aberta
+  label_open_issues_plural: Abertas
+  label_closed_issues: Fechada
+  label_closed_issues_plural: Fechadas
+  label_x_open_issues_abbr_on_total:
+    zero:  0 aberta / %{total}
+    one:   1 aberta / %{total}
+    other: "%{count} abertas / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 aberta
+    one:   1 aberta
+    other: "%{count} abertas"
+  label_x_closed_issues_abbr:
+    zero:  0 fechada
+    one:   1 fechada
+    other: "%{count} fechadas"
+  label_total: Total
+  label_permissions: PermissÃµes
+  label_current_status: SituaÃ§Ã£o atual
+  label_new_statuses_allowed: Nova situaÃ§Ã£o permitida
+  label_all: todos
+  label_none: nenhum
+  label_nobody: ninguÃ©m
+  label_next: PrÃ³ximo
+  label_previous: Anterior
+  label_used_by: Usado por
+  label_details: Detalhes
+  label_add_note: Adicionar nota
+  label_per_page: Por pÃ¡gina
+  label_calendar: CalendÃ¡rio
+  label_months_from: meses a partir de
+  label_gantt: Gantt
+  label_internal: Interno
+  label_last_changes: "Ãºltimas %{count} alteraÃ§Ãµes"
+  label_change_view_all: Mostrar todas as alteraÃ§Ãµes
+  label_personalize_page: Personalizar esta pÃ¡gina
+  label_comment: ComentÃ¡rio
+  label_comment_plural: ComentÃ¡rios
+  label_x_comments:
+    zero: nenhum comentÃ¡rio
+    one: 1 comentÃ¡rio
+    other: "%{count} comentÃ¡rios"
+  label_comment_add: Adicionar comentÃ¡rio
+  label_comment_added: ComentÃ¡rio adicionado
+  label_comment_delete: Excluir comentÃ¡rio
+  label_query: Consulta personalizada
+  label_query_plural: Consultas personalizadas
+  label_query_new: Nova consulta
+  label_filter_add: Adicionar filtro
+  label_filter_plural: Filtros
+  label_equals: igual a
+  label_not_equals: diferente de
+  label_in_less_than: maior que
+  label_in_more_than: menor que
+  label_in: em
+  label_today: hoje
+  label_all_time: tudo
+  label_yesterday: ontem
+  label_this_week: esta semana
+  label_last_week: Ãºltima semana
+  label_last_n_days: "Ãºltimos %{count} dias"
+  label_this_month: este mÃªs
+  label_last_month: Ãºltimo mÃªs
+  label_this_year: este ano
+  label_date_range: PerÃ­odo
+  label_less_than_ago: menos de
+  label_more_than_ago: mais de
+  label_ago: dias atrÃ¡s
+  label_contains: contÃ©m
+  label_not_contains: nÃ£o contÃ©m
+  label_day_plural: dias
+  label_repository: RepositÃ³rio
+  label_repository_plural: RepositÃ³rios
+  label_browse: Procurar
+  label_revision: RevisÃ£o
+  label_revision_plural: RevisÃµes
+  label_associated_revisions: RevisÃµes associadas
+  label_added: adicionada
+  label_modified: alterada
+  label_deleted: excluÃ­da
+  label_latest_revision: Ãšltima revisÃ£o
+  label_latest_revision_plural: Ãšltimas revisÃµes
+  label_view_revisions: Ver revisÃµes
+  label_max_size: Tamanho mÃ¡ximo
+  label_sort_highest: Mover para o inÃ­cio
+  label_sort_higher: Mover para cima
+  label_sort_lower: Mover para baixo
+  label_sort_lowest: Mover para o fim
+  label_roadmap: Planejamento
+  label_roadmap_due_in: "Previsto para %{value}"
+  label_roadmap_overdue: "%{value} atrasado"
+  label_roadmap_no_issues: Sem tarefas para esta versÃ£o
+  label_search: Busca
+  label_result_plural: Resultados
+  label_all_words: Todas as palavras
+  label_wiki: Wiki
+  label_wiki_edit: Editar Wiki
+  label_wiki_edit_plural: EdiÃ§Ãµes Wiki
+  label_wiki_page: PÃ¡gina Wiki
+  label_wiki_page_plural: pÃ¡ginas Wiki
+  label_index_by_title: Ãndice por tÃ­tulo
+  label_index_by_date: Ãndice por data
+  label_current_version: VersÃ£o atual
+  label_preview: PrÃ©-visualizar
+  label_feed_plural: Feeds
+  label_changes_details: Detalhes de todas as alteraÃ§Ãµes
+  label_issue_tracking: Tarefas
+  label_spent_time: Tempo gasto
+  label_f_hour: "%{value} hora"
+  label_f_hour_plural: "%{value} horas"
+  label_time_tracking: Registro de horas
+  label_change_plural: AlteraÃ§Ãµes
+  label_statistics: EstatÃ­sticas
+  label_commits_per_month: Commits por mÃªs
+  label_commits_per_author: Commits por autor
+  label_view_diff: Ver diferenÃ§as
+  label_diff_inline: inline
+  label_diff_side_by_side: lado a lado
+  label_options: OpÃ§Ãµes
+  label_copy_workflow_from: Copiar fluxo de trabalho de
+  label_permissions_report: RelatÃ³rio de permissÃµes
+  label_watched_issues: Tarefas observadas
+  label_related_issues: Tarefas relacionadas
+  label_applied_status: SituaÃ§Ã£o alterada
+  label_loading: Carregando...
+  label_relation_new: Nova relaÃ§Ã£o
+  label_relation_delete: Excluir relaÃ§Ã£o
+  label_relates_to: relacionado a
+  label_duplicates: duplica
+  label_duplicated_by: duplicado por
+  label_blocks: bloqueia
+  label_blocked_by: bloqueado por
+  label_precedes: precede
+  label_follows: segue
+  label_end_to_start: fim para o inÃ­cio
+  label_end_to_end: fim para fim
+  label_start_to_start: inÃ­cio para inÃ­cio
+  label_start_to_end: inÃ­cio para fim
+  label_stay_logged_in: Permanecer logado
+  label_disabled: desabilitado
+  label_show_completed_versions: Exibir versÃµes completas
+  label_me: mim
+  label_board: FÃ³rum
+  label_board_new: Novo fÃ³rum
+  label_board_plural: FÃ³runs
+  label_topic_plural: TÃ³picos
+  label_message_plural: Mensagens
+  label_message_last: Ãšltima mensagem
+  label_message_new: Nova mensagem
+  label_message_posted: Mensagem enviada
+  label_reply_plural: Respostas
+  label_send_information: Enviar informaÃ§Ã£o da nova conta para o usuÃ¡rio
+  label_year: Ano
+  label_month: MÃªs
+  label_week: Semana
+  label_date_from: De
+  label_date_to: Para
+  label_language_based: Com base no idioma do usuÃ¡rio
+  label_sort_by: "Ordenar por %{value}"
+  label_send_test_email: Enviar um e-mail de teste
+  label_feeds_access_key_created_on: "chave de acesso RSS criada %{value} atrÃ¡s"
+  label_module_plural: MÃ³dulos
+  label_added_time_by: "Adicionado por %{author} %{age} atrÃ¡s"
+  label_updated_time: "Atualizado %{value} atrÃ¡s"
+  label_jump_to_a_project: Ir para o projeto...
+  label_file_plural: Arquivos
+  label_changeset_plural: Changesets
+  label_default_columns: Colunas padrÃ£o
+  label_no_change_option: (Sem alteraÃ§Ã£o)
+  label_bulk_edit_selected_issues: EdiÃ§Ã£o em massa das tarefas selecionados.
+  label_theme: Tema
+  label_default: PadrÃ£o
+  label_search_titles_only: Pesquisar somente tÃ­tulos
+  label_user_mail_option_all: "Para qualquer evento em todos os meus projetos"
+  label_user_mail_option_selected: "Para qualquer evento somente no(s) projeto(s) selecionado(s)..."
+  label_user_mail_no_self_notified: "Eu nÃ£o quero ser notificado de minhas prÃ³prias modificaÃ§Ãµes"
+  label_registration_activation_by_email: ativaÃ§Ã£o de conta por e-mail
+  label_registration_manual_activation: ativaÃ§Ã£o manual de conta
+  label_registration_automatic_activation: ativaÃ§Ã£o automÃ¡tica de conta
+  label_display_per_page: "Por pÃ¡gina: %{value}"
+  label_age: Idade
+  label_change_properties: Alterar propriedades
+  label_general: Geral
+  label_more: Mais
+  label_scm: 'Controle de versÃ£o:'
+  label_plugins: Plugins
+  label_ldap_authentication: AutenticaÃ§Ã£o LDAP
+  label_downloads_abbr: D/L
+  label_optional_description: DescriÃ§Ã£o opcional
+  label_add_another_file: Adicionar outro arquivo
+  label_preferences: PreferÃªncias
+  label_chronological_order: Em ordem cronolÃ³gica
+  label_reverse_chronological_order: Em ordem cronolÃ³gica inversa
+  label_planning: Planejamento
+  label_incoming_emails: E-mails recebidos
+  label_generate_key: Gerar uma chave
+  label_issue_watchers: Observadores
+
+  button_login: Entrar
+  button_submit: Enviar
+  button_save: Salvar
+  button_check_all: Marcar todos
+  button_uncheck_all: Desmarcar todos
+  button_delete: Excluir
+  button_create: Criar
+  button_test: Testar
+  button_edit: Editar
+  button_add: Adicionar
+  button_change: Alterar
+  button_apply: Aplicar
+  button_clear: Limpar
+  button_lock: Bloquear
+  button_unlock: Desbloquear
+  button_download: Baixar
+  button_list: Listar
+  button_view: Ver
+  button_move: Mover
+  button_back: Voltar
+  button_cancel: Cancelar
+  button_activate: Ativar
+  button_sort: Ordenar
+  button_log_time: Tempo de trabalho
+  button_rollback: Voltar para esta versÃ£o
+  button_watch: Observar
+  button_unwatch: Parar de observar
+  button_reply: Responder
+  button_archive: Arquivar
+  button_unarchive: Desarquivar
+  button_reset: Redefinir
+  button_rename: Renomear
+  button_change_password: Alterar senha
+  button_copy: Copiar
+  button_annotate: Anotar
+  button_update: Atualizar
+  button_configure: Configurar
+  button_quote: Responder
+
+  status_active: ativo
+  status_registered: registrado
+  status_locked: bloqueado
+
+  text_select_mail_notifications: AÃ§Ãµes a serem notificadas por e-mail
+  text_regexp_info: ex. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 = sem restriÃ§Ã£o
+  text_project_destroy_confirmation: VocÃª tem certeza que deseja excluir este projeto e todos os dados relacionados?
+  text_subprojects_destroy_warning: "Seu(s) subprojeto(s): %{value} tambÃ©m serÃ£o excluÃ­dos."
+  text_workflow_edit: Selecione um papel e um tipo de tarefa para editar o fluxo de trabalho
+  text_are_you_sure: VocÃª tem certeza?
+  text_tip_issue_begin_day: tarefa inicia neste dia
+  text_tip_issue_end_day: tarefa termina neste dia
+  text_tip_issue_begin_end_day: tarefa inicia e termina neste dia
+  text_caracters_maximum: "mÃ¡ximo %{count} caracteres"
+  text_caracters_minimum: "deve ter ao menos %{count} caracteres."
+  text_length_between: "deve ter entre %{min} e %{max} caracteres."
+  text_tracker_no_workflow: Sem fluxo de trabalho definido para este tipo.
+  text_unallowed_characters: Caracteres nÃ£o permitidos
+  text_comma_separated: MÃºltiplos valores sÃ£o permitidos (separados por vÃ­rgula).
+  text_issues_ref_in_commit_messages: Referenciando tarefas nas mensagens de commit
+  text_issue_added: "Tarefa %{id} incluÃ­da (por %{author})."
+  text_issue_updated: "Tarefa %{id} alterada (por %{author})."
+  text_wiki_destroy_confirmation: VocÃª tem certeza que deseja excluir este wiki e TODO o seu conteÃºdo?
+  text_issue_category_destroy_question: "Algumas tarefas (%{count}) estÃ£o atribuÃ­das a esta categoria. O que vocÃª deseja fazer?"
+  text_issue_category_destroy_assignments: Remover atribuiÃ§Ãµes da categoria
+  text_issue_category_reassign_to: Redefinir tarefas para esta categoria
+  text_user_mail_option: "Para projetos (nÃ£o selecionados), vocÃª somente receberÃ¡ notificaÃ§Ãµes sobre o que vocÃª estÃ¡ observando ou estÃ¡ envolvido (ex. tarefas das quais vocÃª Ã© o autor ou que estÃ£o atribuÃ­das a vocÃª)"
+  text_no_configuration_data: "Os PapÃ©is, tipos de tarefas, situaÃ§Ã£o de tarefas e fluxos de trabalho nÃ£o foram configurados ainda.\nÃ‰ altamente recomendado carregar as configuraÃ§Ãµes padrÃ£o. VocÃª poderÃ¡ modificar estas configuraÃ§Ãµes assim que carregadas."
+  text_load_default_configuration: Carregar a configuraÃ§Ã£o padrÃ£o
+  text_status_changed_by_changeset: "Aplicado no changeset %{value}."
+  text_issues_destroy_confirmation: 'VocÃª tem certeza que deseja excluir a(s) tarefa(s) selecionada(s)?'
+  text_select_project_modules: 'Selecione mÃ³dulos para habilitar para este projeto:'
+  text_default_administrator_account_changed: Conta padrÃ£o do administrador alterada
+  text_file_repository_writable: RepositÃ³rio com permissÃ£o de escrita
+  text_rmagick_available: RMagick disponÃ­vel (opcional)
+  text_destroy_time_entries_question: "%{hours} horas de trabalho foram registradas nas tarefas que vocÃª estÃ¡ excluindo. O que vocÃª deseja fazer?"
+  text_destroy_time_entries: Excluir horas de trabalho
+  text_assign_time_entries_to_project: Atribuir estas horas de trabalho para outro projeto
+  text_reassign_time_entries: 'Atribuir horas reportadas para esta tarefa:'
+  text_user_wrote: "%{value} escreveu:"
+  text_enumeration_destroy_question: "%{count} objetos estÃ£o atribuÃ­dos a este valor."
+  text_enumeration_category_reassign_to: 'ReatribuÃ­-los ao valor:'
+  text_email_delivery_not_configured: "O envio de e-mail nÃ£o estÃ¡ configurado, e as notificaÃ§Ãµes estÃ£o inativas.\nConfigure seu servidor SMTP no arquivo config/configuration.yml e reinicie a aplicaÃ§Ã£o para ativÃ¡-las."
+
+  default_role_manager: Gerente
+  default_role_developer: Desenvolvedor
+  default_role_reporter: Informante
+  default_tracker_bug: Defeito
+  default_tracker_feature: Funcionalidade
+  default_tracker_support: Suporte
+  default_issue_status_new: Nova
+  default_issue_status_in_progress: Em andamento
+  default_issue_status_resolved: Resolvida
+  default_issue_status_feedback: Feedback
+  default_issue_status_closed: Fechada
+  default_issue_status_rejected: Rejeitada
+  default_doc_category_user: DocumentaÃ§Ã£o do usuÃ¡rio
+  default_doc_category_tech: DocumentaÃ§Ã£o tÃ©cnica
+  default_priority_low: Baixa
+  default_priority_normal: Normal
+  default_priority_high: Alta
+  default_priority_urgent: Urgente
+  default_priority_immediate: Imediata
+  default_activity_design: Design
+  default_activity_development: Desenvolvimento
+
+  enumeration_issue_priorities: Prioridade das tarefas
+  enumeration_doc_categories: Categorias de documento
+  enumeration_activities: Atividades (registro de horas)
+  notice_unable_delete_version: NÃ£o foi possÃ­vel excluir a versÃ£o
+  label_renamed: renomeado
+  label_copied: copiado
+  setting_plain_text_mail: Usar mensagem sem formataÃ§Ã£o HTML
+  permission_view_files: Ver arquivos
+  permission_edit_issues: Editar tarefas
+  permission_edit_own_time_entries: Editar o prÃ³prio tempo de trabalho
+  permission_manage_public_queries: Gerenciar consultas publicas
+  permission_add_issues: Adicionar tarefas
+  permission_log_time: Adicionar tempo gasto
+  permission_view_changesets: Ver changesets
+  permission_view_time_entries: Ver tempo gasto
+  permission_manage_versions: Gerenciar versÃµes
+  permission_manage_wiki: Gerenciar wiki
+  permission_manage_categories: Gerenciar categorias de tarefas
+  permission_protect_wiki_pages: Proteger pÃ¡ginas wiki
+  permission_comment_news: Comentar notÃ­cias
+  permission_delete_messages: Excluir mensagens
+  permission_select_project_modules: Selecionar mÃ³dulos de projeto
+  permission_edit_wiki_pages: Editar pÃ¡ginas wiki
+  permission_add_issue_watchers: Adicionar observadores
+  permission_view_gantt: Ver grÃ¡fico gantt
+  permission_move_issues: Mover tarefas
+  permission_manage_issue_relations: Gerenciar relacionamentos de tarefas
+  permission_delete_wiki_pages: Excluir pÃ¡ginas wiki
+  permission_manage_boards: Gerenciar fÃ³runs
+  permission_delete_wiki_pages_attachments: Excluir anexos
+  permission_view_wiki_edits: Ver histÃ³rico do wiki
+  permission_add_messages: Postar mensagens
+  permission_view_messages: Ver mensagens
+  permission_manage_files: Gerenciar arquivos
+  permission_edit_issue_notes: Editar notas
+  permission_manage_news: Gerenciar notÃ­cias
+  permission_view_calendar: Ver calendÃ¡rio
+  permission_manage_members: Gerenciar membros
+  permission_edit_messages: Editar mensagens
+  permission_delete_issues: Excluir tarefas
+  permission_view_issue_watchers: Ver lista de observadores
+  permission_manage_repository: Gerenciar repositÃ³rio
+  permission_commit_access: Acesso de commit
+  permission_browse_repository: Pesquisar repositÃ³rio
+  permission_view_documents: Ver documentos
+  permission_edit_project: Editar projeto
+  permission_add_issue_notes: Adicionar notas
+  permission_save_queries: Salvar consultas
+  permission_view_wiki_pages: Ver wiki
+  permission_rename_wiki_pages: Renomear pÃ¡ginas wiki
+  permission_edit_time_entries: Editar tempo gasto
+  permission_edit_own_issue_notes: Editar suas prÃ³prias notas
+  setting_gravatar_enabled: Usar Ã­cones do Gravatar
+  label_example: Exemplo
+  text_repository_usernames_mapping: "Seleciona ou atualiza os usuÃ¡rios do Redmine mapeando para cada usuÃ¡rio encontrado no log do repositÃ³rio.\nUsuÃ¡rios com o mesmo login ou e-mail no Redmine e no repositÃ³rio serÃ£o mapeados automaticamente."
+  permission_edit_own_messages: Editar prÃ³prias mensagens
+  permission_delete_own_messages: Excluir prÃ³prias mensagens
+  label_user_activity: "Atividade de %{value}"
+  label_updated_time_by: "Atualizado por %{author} hÃ¡ %{age}"
+  text_diff_truncated: '... Este diff foi truncado porque excede o tamanho mÃ¡ximo que pode ser exibido.'
+  setting_diff_max_lines_displayed: NÃºmero mÃ¡ximo de linhas exibidas no diff
+  text_plugin_assets_writable: DiretÃ³rio de plugins gravÃ¡vel
+  warning_attachments_not_saved: "%{count} arquivo(s) nÃ£o puderam ser salvo(s)."
+  button_create_and_continue: Criar e continuar
+  text_custom_field_possible_values_info: 'Uma linha para cada valor'
+  label_display: ExibiÃ§Ã£o
+  field_editable: EditÃ¡vel
+  setting_repository_log_display_limit: NÃºmero mÃ¡ximo de revisÃµes exibidas no arquivo de log
+  setting_file_max_size_displayed: Tamanho mÃ¡ximo dos arquivos textos exibidos inline
+  field_identity_urler: Observador
+  setting_openid: Permitir Login e Registro via OpenID
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: ou use o OpenID
+  field_content: ConteÃºdo
+  label_descending: Descendente
+  label_sort: Ordenar
+  label_ascending: Ascendente
+  label_date_from_to: De %{start} atÃ© %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Esta pÃ¡gina tem %{descendants} pÃ¡gina(s) filha(s) e descendente(s). O que vocÃª quer fazer?
+  text_wiki_page_reassign_children: Reatribuir pÃ¡ginas filhas para esta pÃ¡gina pai
+  text_wiki_page_nullify_children: Manter as pÃ¡ginas filhas como pÃ¡ginas raÃ­zes
+  text_wiki_page_destroy_children: Excluir pÃ¡ginas filhas e todas suas descendentes
+  setting_password_min_length: Comprimento mÃ­nimo para senhas
+  field_group_by: Agrupar por
+  mail_subject_wiki_content_updated: "A pÃ¡gina wiki '%{id}' foi atualizada"
+  label_wiki_content_added: PÃ¡gina wiki adicionada
+  mail_subject_wiki_content_added: "A pÃ¡gina wiki '%{id}' foi adicionada"
+  mail_body_wiki_content_added: A pÃ¡gina wiki '%{id}' foi adicionada por %{author}.
+  label_wiki_content_updated: PÃ¡gina wiki atualizada
+  mail_body_wiki_content_updated: A pÃ¡gina wiki '%{id}' foi atualizada por %{author}.
+  permission_add_project: Criar projeto
+  setting_new_project_user_role_id: Papel atribuÃ­do a um usuÃ¡rio nÃ£o-administrador que cria um projeto
+  label_view_all_revisions: Ver todas as revisÃµes
+  label_tag: Etiqueta
+  label_branch: Ramo
+  text_journal_changed: "%{label} alterado de %{old} para %{new}"
+  text_journal_set_to: "%{label} ajustado para %{value}"
+  text_journal_deleted: "%{label} excluÃ­do (%{old})"
+  label_group_plural: Grupos
+  label_group: Grupo
+  label_group_new: Novo grupo
+  label_time_entry_plural: Tempos gastos
+  text_journal_added: "%{label} %{value} adicionado"
+  field_active: Ativo
+  enumeration_system_activity: Atividade do sistema
+  permission_delete_issue_watchers: Excluir observadores
+  version_status_closed: fechado
+  version_status_locked: travado
+  version_status_open: aberto
+  error_can_not_reopen_issue_on_closed_version: Uma tarefa atribuÃ­da a uma versÃ£o fechada nÃ£o pode ser reaberta
+  label_user_anonymous: AnÃ´nimo
+  button_move_and_follow: Mover e seguir
+  setting_default_projects_modules: MÃ³dulos habilitados por padrÃ£o para novos projetos
+  setting_gravatar_default: Imagem-padrÃ£o de Gravatar
+  field_sharing: Compartilhamento
+  label_version_sharing_hierarchy: Com a hierarquia do projeto
+  label_version_sharing_system: Com todos os projetos
+  label_version_sharing_descendants: Com sub-projetos
+  label_version_sharing_tree: Com a Ã¡rvore do projeto
+  label_version_sharing_none: Sem compartilhamento
+  error_can_not_archive_project: Este projeto nÃ£o pode ser arquivado
+  button_duplicate: Duplicar
+  button_copy_and_follow: Copiar e seguir
+  label_copy_source: Origem
+  setting_issue_done_ratio: Calcular o percentual de conclusÃ£o da tarefa
+  setting_issue_done_ratio_issue_status: Usar a situaÃ§Ã£o da tarefa
+  error_issue_done_ratios_not_updated: O percentual de conclusÃ£o das tarefas nÃ£o foi atualizado.
+  error_workflow_copy_target: Por favor, selecione os tipos de tarefa e os papÃ©is alvo
+  setting_issue_done_ratio_issue_field: Use o campo da tarefa
+  label_copy_same_as_target: Mesmo alvo
+  label_copy_target: Alvo
+  notice_issue_done_ratios_updated: Percentual de conclusÃ£o atualizados.
+  error_workflow_copy_source: Por favor, selecione um tipo de tarefa e papel de origem
+  label_update_issue_done_ratios: Atualizar percentual de conclusÃ£o das tarefas
+  setting_start_of_week: InÃ­cio da semana
+  field_watcher: Observador
+  permission_view_issues: Ver tarefas
+  label_display_used_statuses_only: Somente exibir situaÃ§Ãµes que sÃ£o usadas por este tipo de tarefa
+  label_revision_id: RevisÃ£o %{value}
+  label_api_access_key: Chave de acesso a API
+  button_show: Exibir
+  label_api_access_key_created_on: Chave de acesso a API criado a %{value} atrÃ¡s
+  label_feeds_access_key: Chave de acesso ao RSS
+  notice_api_access_key_reseted: Sua chave de acesso a API foi redefinida.
+  setting_rest_api_enabled: Habilitar a api REST
+  label_missing_api_access_key: Chave de acesso a API faltando
+  label_missing_feeds_access_key: Chave de acesso ao RSS faltando
+  text_line_separated: MÃºltiplos valores permitidos (uma linha para cada valor).
+  setting_mail_handler_body_delimiters: Truncar e-mails apÃ³s uma destas linhas
+  permission_add_subprojects: Criar subprojetos
+  label_subproject_new: Novo subprojeto
+  text_own_membership_delete_confirmation: |-
+    VocÃª estÃ¡ para excluir algumas de suas prÃ³prias permissÃµes e pode nÃ£o mais estar apto a editar este projeto apÃ³s esta operaÃ§Ã£o.
+    VocÃª tem certeza que deseja continuar?
+  label_close_versions: Fechar versÃµes concluÃ­das
+  label_board_sticky: Marcado
+  label_board_locked: Travado
+  permission_export_wiki_pages: Exportar pÃ¡ginas wiki
+  setting_cache_formatted_text: Realizar cache de texto formatado
+  permission_manage_project_activities: Gerenciar atividades do projeto
+  error_unable_delete_issue_status: NÃ£o foi possÃ­vel excluir situaÃ§Ã£o da tarefa
+  label_profile: Perfil
+  permission_manage_subtasks: Gerenciar sub-tarefas
+  field_parent_issue: Tarefa pai
+  label_subtask_plural: Subtarefas
+  label_project_copy_notifications: Enviar notificaÃ§Ãµes por e-mail ao copiar projeto
+  error_can_not_delete_custom_field: NÃ£o foi possÃ­vel excluir o campo personalizado
+  error_unable_to_connect: NÃ£o foi possÃ­vel conectar (%{value})
+  error_can_not_remove_role: Este papel estÃ¡ em uso e nÃ£o pode ser excluÃ­do.
+  error_can_not_delete_tracker: Este tipo de tarefa estÃ¡ atribuÃ­do a alguma(s) tarefa(s) e nÃ£o pode ser excluÃ­do.
+  field_principal: Principal
+  label_my_page_block: Meu bloco de pÃ¡gina
+  notice_failed_to_save_members: "Falha ao gravar membro(s): %{errors}."
+  text_zoom_out: Afastar zoom
+  text_zoom_in: Aproximar zoom
+  notice_unable_delete_time_entry: NÃ£o foi possÃ­vel excluir a entrada no registro de horas trabalhadas.
+  label_overall_spent_time: Tempo gasto geral
+  field_time_entries: Registro de horas
+  project_module_gantt: Gantt
+  project_module_calendar: CalendÃ¡rio
+  button_edit_associated_wikipage: "Editar pÃ¡gina wiki relacionada: %{page_title}"
+  field_text: Campo de texto
+  label_user_mail_option_only_owner: Somente para as coisas que eu criei
+  setting_default_notification_option: OpÃ§Ã£o padrÃ£o de notificaÃ§Ã£o
+  label_user_mail_option_only_my_events: Somente para as coisas que eu esteja observando ou esteja envolvido
+  label_user_mail_option_only_assigned: Somente para as coisas que estejam atribuÃ­das a mim
+  label_user_mail_option_none: Sem eventos
+  field_member_of_group: Grupo do responsÃ¡vel
+  field_assigned_to_role: Papel do responsÃ¡vel
+  notice_not_authorized_archived_project: O projeto que vocÃª estÃ¡ tentando acessar foi arquivado.
+  label_principal_search: "Pesquisar por usuÃ¡rios ou grupos:"
+  label_user_search: "Pesquisar por usuÃ¡rio:"
+  field_visible: VisÃ­vel
+  setting_emails_header: CabeÃ§alho do e-mail
+  setting_commit_logtime_activity_id: Atividade para registrar horas
+  text_time_logged_by_changeset: Aplicado no changeset %{value}.
+  setting_commit_logtime_enabled: Habilitar registro de horas
+  notice_gantt_chart_truncated: O grÃ¡fico foi cortado por exceder o tamanho mÃ¡ximo de linhas que podem ser exibidas (%{max})
+  setting_gantt_items_limit: NÃºmero mÃ¡ximo de itens exibidos no grÃ¡fico gatt
+  field_warn_on_leaving_unsaved: Alertar-me ao sair de uma pÃ¡gina sem salvar o texto
+  text_warn_on_leaving_unsaved: A pÃ¡gina atual contem texto que nÃ£o foi salvo e serÃ¡ perdido se vocÃª sair desta pÃ¡gina.
+  label_my_queries: Minhas consultas personalizadas
+  text_journal_changed_no_detail: "%{label} atualizado(a)"
+  label_news_comment_added: NotÃ­cia recebeu um comentÃ¡rio
+  button_expand_all: Expandir tudo
+  button_collapse_all: Recolher tudo
+  label_additional_workflow_transitions_for_assignee: TransiÃ§Ãµes adicionais permitidas quando o usuÃ¡rio Ã© o responsÃ¡vel pela tarefa
+  label_additional_workflow_transitions_for_author: TransiÃ§Ãµes adicionais permitidas quando o usuÃ¡rio Ã© o autor
+
+  label_bulk_edit_selected_time_entries: AlteraÃ§Ã£o em massa do registro de horas
+  text_time_entries_destroy_confirmation: Tem certeza que quer excluir o(s) registro(s) de horas selecionado(s)?
+  label_role_anonymous: AnÃ´nimo
+  label_role_non_member: NÃ£o Membro
+  label_issues_visibility_own: Tarefas criadas ou atribuÃ­das ao usuÃ¡rio
+  field_issues_visibility: Visibilidade das tarefas
+  label_issues_visibility_all: Todas as tarefas
+  permission_set_own_issues_private: Alterar as prÃ³prias tarefas para pÃºblicas ou privadas
+  field_is_private: Privado
+  permission_set_issues_private: Alterar tarefas para pÃºblicas ou privadas
+  label_issues_visibility_public: Todas as tarefas nÃ£o privadas
+  text_issues_destroy_descendants_confirmation: Isto tambÃ©m irÃ¡ excluir %{count} subtarefa(s).
+  field_commit_logs_encoding: CodificaÃ§Ã£o das mensagens de commit
+  field_scm_path_encoding: CodificaÃ§Ã£o do caminho
+  text_scm_path_encoding_note: "PadrÃ£o: UTF-8"
+  field_path_to_repository: Caminho para o repositÃ³rio
+  field_root_directory: DiretÃ³rio raiz
+  field_cvs_module: MÃ³dulo
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: "RepositÃ³rio local (ex.: /hgrepo, c:\\hgrepo)"
+  text_scm_command: Comando
+  text_scm_command_version: VersÃ£o
+  label_git_report_last_commit: Relatar Ãºltima alteraÃ§Ã£o para arquivos e diretÃ³rios
+  text_scm_config: VocÃª pode configurar seus comandos de versionamento em config/configurations.yml. Por favor reinicie a aplicaÃ§Ã£o apÃ³s alterÃ¡-lo.
+  text_scm_command_not_available: Comando de versionamento nÃ£o disponÃ­vel. Por favor verifique as configuraÃ§Ãµes no painel de administraÃ§Ã£o.
+  notice_issue_successful_create: Tarefa %{id} criada.
+  label_between: entre
+  setting_issue_group_assignment: Permitir atribuiÃ§Ãµes de tarefas a grupos
+  label_diff: diff
+  text_git_repository_note: "RepositÃ³rio esta vazio e Ã© local (ex: /gitrepo, c:\\gitrepo)"
+
+  description_query_sort_criteria_direction: DireÃ§Ã£o da ordenaÃ§Ã£o
+  description_project_scope: Escopo da pesquisa
+  description_filter: Filtro
+  description_user_mail_notification: ConfiguraÃ§Ã£o de notificaÃ§Ãµes por e-mail
+  description_date_from: Digita a data inicial
+  description_message_content: ConteÃºdo da mensagem
+  description_available_columns: Colunas disponÃ­veis
+  description_date_range_interval: Escolha um perÃ­odo selecionando a data de inÃ­cio e fim
+  description_issue_category_reassign: Escolha uma categoria de tarefas
+  description_search: Searchfield
+  description_notes: Notas
+  description_date_range_list: Escolha um perÃ­odo a partira da lista
+  description_choose_project: Projetos
+  description_date_to: Digite a data final
+  description_query_sort_criteria_attribute: Atributo de ordenaÃ§Ã£o
+  description_wiki_subpages_reassign: Escolha uma nova pÃ¡gina pai
+  description_selected_columns: Colunas selecionadas
+
+  label_parent_revision: Pais
+  label_child_revision: Filhos
+  error_scm_annotate_big_text_file: A entrada nÃ£o pode ser anotada, pois excede o tamanho mÃ¡ximo do arquivo de texto.
+  setting_default_issue_start_date_to_creation_date: Usar data corrente como data inicial para novas tarefas
+  button_edit_section: Editar esta seÃ§Ã£o
+  setting_repositories_encodings: Encoding dos repositÃ³rios e anexos
+  description_all_columns: Todas as colunas
+  button_export: Exportar
+  label_export_options: "OpÃ§Ãµes de exportaÃ§Ã£o %{export_format}"
+  error_attachment_too_big: Este arquivo nÃ£o pode ser enviado porque excede o tamanho mÃ¡ximo permitido (%{max_size})
+  notice_failed_to_save_time_entries: "Falha ao salvar %{count} de %{total} horas trabalhadas: %{ids}."
+  label_x_issues:
+    zero:  0 tarefa
+    one:   1 tarefa
+    other: "%{count} tarefas"
+  label_repository_new: Novo repositÃ³rio
+  field_repository_is_default: RepositÃ³rio principal
+  label_copy_attachments: Copiar anexos
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: VersÃµes completadas
+  text_project_identifier_info: Somente letras minÃºsculas (az), nÃºmeros, traÃ§os e sublinhados sÃ£o permitidos. <br /> Uma vez salvo, o identificador nÃ£o pode ser alterado.
+  field_multiple: Multiplos valores
+  setting_commit_cross_project_ref: Permitir que tarefas de todos os outros projetos sejam refenciadas e resolvidas
+  text_issue_conflict_resolution_add_notes: Adicione minhas anotaÃ§Ãµes e descartar minhas outras mudanÃ§as
+  text_issue_conflict_resolution_overwrite: Aplicar as minhas alteraÃ§Ãµes de qualquer maneira (notas anteriores serÃ£o mantidos, mas algumas mudanÃ§as podem ser substituÃ­dos)
+  notice_issue_update_conflict: A tarefa foi atualizada por um outro usuÃ¡rio, enquanto vocÃª estava editando.
+  text_issue_conflict_resolution_cancel: Descartar todas as minhas mudanÃ§as e re-exibir %{link}
+  permission_manage_related_issues: Gerenciar tarefas relacionadas
+  field_auth_source_ldap_filter: Filtro LDAP
+  label_search_for_watchers: Procurar por outros observadores para adiconar
+  notice_account_deleted: Sua conta foi excluÃ­da permanentemente.
+  setting_unsubscribe: Permitir aos usuÃ¡rios excluir sua conta prÃ³pria
+  button_delete_my_account: Excluir minha conta
+  text_account_destroy_confirmation: |-
+    Tem certeza de que quer continuar?
+    Sua conta serÃ¡ excluÃ­da permanentemente, sem qualquer forma de reativÃ¡-lo.
+  error_session_expired: A sua sessÃ£o expirou. Por favor, faÃ§a login novamente.
+  text_session_expiration_settings: "Aviso: a alteraÃ§Ã£o dessas configuraÃ§Ãµes pode expirar as sessÃµes atuais, incluindo a sua."
+  setting_session_lifetime: duraÃ§Ã£o mÃ¡xima da sessÃ£o
+  setting_session_timeout: tempo limite de inatividade da sessÃ£o
+  label_session_expiration: "ExpiraÃ§Ã£o da sessÃ£o"
+  permission_close_project: Fechar / reabrir o projeto
+  label_show_closed_projects: VisualizaÃ§Ã£o de projetos fechados
+  button_close: Fechar
+  button_reopen: Reabrir
+  project_status_active: ativo
+  project_status_closed: fechado
+  project_status_archived: arquivado
+  text_project_closed: Este projeto Ã© fechado e somente leitura.
+  notice_user_successful_create: UsuÃ¡rio %{id} criado.
+  field_core_fields: campos padrÃ£o
+  field_timeout: Tempo de espera (em segundos)
+  setting_thumbnails_enabled: Exibir miniaturas de anexos
+  setting_thumbnails_size: Tamanho das miniaturas (em pixels)
+  label_status_transitions: Estados das transiÃ§Ãµes
+  label_fields_permissions: PermissÃµes de campos
+  label_readonly: somente leitura
+  label_required: ObrigatÃ³rio
+  text_repository_identifier_info: Somente letras minÃºsculas (az), nÃºmeros, traÃ§os e sublinhados sÃ£o permitidos <br/> Uma vez salvo, o identificador nÃ£o pode ser alterado.
+  field_board_parent: FÃ³rum Pai
+  label_attribute_of_project: "Projeto %{name}"
+  label_attribute_of_author: "autor %{name}"
+  label_attribute_of_assigned_to: "atribuÃ­do %{name}"
+  label_attribute_of_fixed_version: "versÃ£o alvo %{name}"
+  label_copy_subtasks: Copiar sub-tarefas
+  label_copied_to: copiada
+  label_copied_from: copiado
+  label_any_issues_in_project: quaisquer problemas em projeto
+  label_any_issues_not_in_project: todas as questÃµes que nÃ£o estÃ£o em projeto
+  field_private_notes: notas privadas
+  permission_view_private_notes: Ver notas privadas
+  permission_set_notes_private: Permitir alterar notas para privada
+  label_no_issues_in_project: sem problemas em projeto
+  label_any: todos
+  label_last_n_weeks: "Ãºltimas %{count} semanas"
+  setting_cross_project_subtasks: Permitir cruzamento de sub-tarefas entre projetos
+  label_cross_project_descendants: com sub-Projetos
+  label_cross_project_tree: Com uma Ãrvore fazer o Projeto
+  label_cross_project_hierarchy: Com uma hierarquia fazer o Projeto
+  label_cross_project_system: Com de Todos os Projetos
+  button_hide: Esconder
+  setting_non_working_week_days: dias nÃ£o Ãºteis
+  label_in_the_next_days: na prÃ³xima
+  label_in_the_past_days: no passado
+  label_attribute_of_user: UsuÃ¡rio %{name}
+  text_turning_multiple_off: Se vocÃª desativar vÃ¡rios valores, vÃ¡rios valores serÃ£o removidas, a fim de preservar a somente um valor por item.
+  label_attribute_of_issue: EmissÃ£o de %{name}
+  permission_add_documents: Adicionar documentos
+  permission_edit_documents: Editar documentos
+  permission_delete_documents: excluir documentos
+  label_gantt_progress_line: Linha de progresso
+  setting_jsonp_enabled: Ativar suporte JSONP
+  field_inherit_members: Herdar membros
+  field_closed_on: Fechado
+  setting_default_projects_tracker_ids: Tipos padrÃµes para novos projeto
+  label_total_time: Total
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a7e0872672382ac6b3b6af1d8757b85565e0f850.svn-base
--- a/.svn/pristine/a7/a7e0872672382ac6b3b6af1d8757b85565e0f850.svn-base
+++ /dev/null
@@ -1,21 +0,0 @@
-Copyright (c) 2008 James Adam
-
-The MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a7/a7f9a5a10472a6b42b368a1289f25463a8c4b622.svn-base
--- /dev/null
+++ b/.svn/pristine/a7/a7f9a5a10472a6b42b368a1289f25463a8c4b622.svn-base
@@ -0,0 +1,10 @@
+class AddIssueStatusPosition < ActiveRecord::Migration
+  def self.up
+    add_column :issue_statuses, :position, :integer, :default => 1
+    IssueStatus.all.each_with_index {|status, i| status.update_attribute(:position, i+1)}
+  end
+
+  def self.down
+    remove_column :issue_statuses, :position
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a8/a89c2391944884496b2422d8187b6c5f71ac2c07.svn-base
--- a/.svn/pristine/a8/a89c2391944884496b2422d8187b6c5f71ac2c07.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-class AddWorkflowsAssigneeAndAuthor < ActiveRecord::Migration
-  def self.up
-    add_column :workflows, :assignee, :boolean, :null => false, :default => false
-    add_column :workflows, :author, :boolean, :null => false, :default => false
-    Workflow.update_all("assignee = #{Workflow.connection.quoted_false}")
-    Workflow.update_all("author = #{Workflow.connection.quoted_false}")
-  end
-
-  def self.down
-    remove_column :workflows, :assignee
-    remove_column :workflows, :author
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a8/a8aa1c2321ca25de25fb93436b542852bd6be325.svn-base
--- a/.svn/pristine/a8/a8aa1c2321ca25de25fb93436b542852bd6be325.svn-base
+++ /dev/null
@@ -1,104 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssueStatus < ActiveRecord::Base
-  before_destroy :check_integrity
-  has_many :workflows, :foreign_key => "old_status_id"
-  acts_as_list
-
-  before_destroy :delete_workflows
-  after_save     :update_default
-
-  validates_presence_of :name
-  validates_uniqueness_of :name
-  validates_length_of :name, :maximum => 30
-  validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true
-
-  named_scope :named, lambda {|arg| { :conditions => ["LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip]}}
-
-  def update_default
-    IssueStatus.update_all("is_default=#{connection.quoted_false}", ['id <> ?', id]) if self.is_default?
-  end
-
-  # Returns the default status for new issues
-  def self.default
-    find(:first, :conditions =>["is_default=?", true])
-  end
-
-  # Update all the +Issues+ setting their done_ratio to the value of their +IssueStatus+
-  def self.update_issue_done_ratios
-    if Issue.use_status_for_done_ratio?
-      IssueStatus.find(:all, :conditions => ["default_done_ratio >= 0"]).each do |status|
-        Issue.update_all(["done_ratio = ?", status.default_done_ratio],
-                         ["status_id = ?", status.id])
-      end
-    end
-
-    return Issue.use_status_for_done_ratio?
-  end
-
-  # Returns an array of all statuses the given role can switch to
-  # Uses association cache when called more than one time
-  def new_statuses_allowed_to(roles, tracker, author=false, assignee=false)
-    if roles && tracker
-      role_ids = roles.collect(&:id)
-      transitions = workflows.select do |w|
-        role_ids.include?(w.role_id) &&
-        w.tracker_id == tracker.id &&
-        ((!w.author && !w.assignee) || (author && w.author) || (assignee && w.assignee))
-      end
-      transitions.collect{|w| w.new_status}.compact.sort
-    else
-      []
-    end
-  end
-
-  # Same thing as above but uses a database query
-  # More efficient than the previous method if called just once
-  def find_new_statuses_allowed_to(roles, tracker, author=false, assignee=false)
-    if roles.present? && tracker
-      conditions = "(author = :false AND assignee = :false)"
-      conditions << " OR author = :true" if author
-      conditions << " OR assignee = :true" if assignee
-
-      workflows.find(:all,
-        :include => :new_status,
-        :conditions => ["role_id IN (:role_ids) AND tracker_id = :tracker_id AND (#{conditions})",
-          {:role_ids => roles.collect(&:id), :tracker_id => tracker.id, :true => true, :false => false}
-          ]
-        ).collect{|w| w.new_status}.compact.sort
-    else
-      []
-    end
-  end
-
-  def <=>(status)
-    position <=> status.position
-  end
-
-  def to_s; name end
-
-private
-  def check_integrity
-    raise "Can't delete status" if Issue.find(:first, :conditions => ["status_id=?", self.id])
-  end
-
-  # Deletes associated workflows
-  def delete_workflows
-    Workflow.delete_all(["old_status_id = :id OR new_status_id = :id", {:id => id}])
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a8/a8c0a5144ee8295ec7a40a346451914977e1f40d.svn-base
--- a/.svn/pristine/a8/a8c0a5144ee8295ec7a40a346451914977e1f40d.svn-base
+++ /dev/null
@@ -1,21 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module NewsHelper
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a8/a8e5c6393341a001c62733de1b51c76eb2b10fe6.svn-base
--- /dev/null
+++ b/.svn/pristine/a8/a8e5c6393341a001c62733de1b51c76eb2b10fe6.svn-base
@@ -0,0 +1,23 @@
+class SplitDocumentsPermissions < ActiveRecord::Migration
+  def up
+    # :manage_documents permission split into 3 permissions:
+    # :add_documents, :edit_documents and :delete_documents
+    Role.all.each do |role|
+      if role.has_permission?(:manage_documents)
+        role.add_permission! :add_documents, :edit_documents, :delete_documents
+        role.remove_permission! :manage_documents
+      end
+    end
+  end
+
+  def down
+    Role.all.each do |role|
+      if role.has_permission?(:add_documents) ||
+          role.has_permission?(:edit_documents) ||
+          role.has_permission?(:delete_documents)
+        role.remove_permission! :add_documents, :edit_documents, :delete_documents
+        role.add_permission! :manage_documents
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a8/a8fc14f9eb6b10ebe9da4200ebea010b2daee352.svn-base
--- /dev/null
+++ b/.svn/pristine/a8/a8fc14f9eb6b10ebe9da4200ebea010b2daee352.svn-base
@@ -0,0 +1,450 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'cgi'
+
+if RUBY_VERSION < '1.9'
+  require 'iconv'
+end
+
+module Redmine
+  module Scm
+    module Adapters
+      class CommandFailed < StandardError #:nodoc:
+      end
+
+      class AbstractAdapter #:nodoc:
+
+        # raised if scm command exited with error, e.g. unknown revision.
+        class ScmCommandAborted < CommandFailed; end
+
+        class << self
+          def client_command
+            ""
+          end
+
+          def shell_quote_command
+            if Redmine::Platform.mswin? && RUBY_PLATFORM == 'java'
+              client_command
+            else
+              shell_quote(client_command)
+            end
+          end
+
+          # Returns the version of the scm client
+          # Eg: [1, 5, 0] or [] if unknown
+          def client_version
+            []
+          end
+
+          # Returns the version string of the scm client
+          # Eg: '1.5.0' or 'Unknown version' if unknown
+          def client_version_string
+            v = client_version || 'Unknown version'
+            v.is_a?(Array) ? v.join('.') : v.to_s
+          end
+
+          # Returns true if the current client version is above
+          # or equals the given one
+          # If option is :unknown is set to true, it will return
+          # true if the client version is unknown
+          def client_version_above?(v, options={})
+            ((client_version <=> v) >= 0) || (client_version.empty? && options[:unknown])
+          end
+
+          def client_available
+            true
+          end
+
+          def shell_quote(str)
+            if Redmine::Platform.mswin?
+              '"' + str.gsub(/"/, '\\"') + '"'
+            else
+              "'" + str.gsub(/'/, "'\"'\"'") + "'"
+            end
+          end
+        end
+
+        def initialize(url, root_url=nil, login=nil, password=nil,
+                       path_encoding=nil)
+          @url = url
+          @login = login if login && !login.empty?
+          @password = (password || "") if @login
+          @root_url = root_url.blank? ? retrieve_root_url : root_url
+        end
+
+        def adapter_name
+          'Abstract'
+        end
+
+        def supports_cat?
+          true
+        end
+
+        def supports_annotate?
+          respond_to?('annotate')
+        end
+
+        def root_url
+          @root_url
+        end
+
+        def url
+          @url
+        end
+
+        def path_encoding
+          nil
+        end
+
+        # get info about the svn repository
+        def info
+          return nil
+        end
+
+        # Returns the entry identified by path and revision identifier
+        # or nil if entry doesn't exist in the repository
+        def entry(path=nil, identifier=nil)
+          parts = path.to_s.split(%r{[\/\\]}).select {|n| !n.blank?}
+          search_path = parts[0..-2].join('/')
+          search_name = parts[-1]
+          if search_path.blank? && search_name.blank?
+            # Root entry
+            Entry.new(:path => '', :kind => 'dir')
+          else
+            # Search for the entry in the parent directory
+            es = entries(search_path, identifier)
+            es ? es.detect {|e| e.name == search_name} : nil
+          end
+        end
+
+        # Returns an Entries collection
+        # or nil if the given path doesn't exist in the repository
+        def entries(path=nil, identifier=nil, options={})
+          return nil
+        end
+
+        def branches
+          return nil
+        end
+
+        def tags
+          return nil
+        end
+
+        def default_branch
+          return nil
+        end
+
+        def properties(path, identifier=nil)
+          return nil
+        end
+
+        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
+          return nil
+        end
+
+        def diff(path, identifier_from, identifier_to=nil)
+          return nil
+        end
+
+        def cat(path, identifier=nil)
+          return nil
+        end
+
+        def with_leading_slash(path)
+          path ||= ''
+          (path[0,1]!="/") ? "/#{path}" : path
+        end
+
+        def with_trailling_slash(path)
+          path ||= ''
+          (path[-1,1] == "/") ? path : "#{path}/"
+        end
+
+        def without_leading_slash(path)
+          path ||= ''
+          path.gsub(%r{^/+}, '')
+        end
+
+        def without_trailling_slash(path)
+          path ||= ''
+          (path[-1,1] == "/") ? path[0..-2] : path
+         end
+
+        def shell_quote(str)
+          self.class.shell_quote(str)
+        end
+
+      private
+        def retrieve_root_url
+          info = self.info
+          info ? info.root_url : nil
+        end
+
+        def target(path, sq=true)
+          path ||= ''
+          base = path.match(/^\//) ? root_url : url
+          str = "#{base}/#{path}".gsub(/[?<>\*]/, '')
+          if sq
+            str = shell_quote(str)
+          end
+          str
+        end
+
+        def logger
+          self.class.logger
+        end
+
+        def shellout(cmd, options = {}, &block)
+          self.class.shellout(cmd, options, &block)
+        end
+
+        def self.logger
+          Rails.logger
+        end
+
+        # Path to the file where scm stderr output is logged
+        # Returns nil if the log file is not writable
+        def self.stderr_log_file
+          if @stderr_log_file.nil?
+            writable = false
+            path = Redmine::Configuration['scm_stderr_log_file'].presence
+            path ||= Rails.root.join("log/#{Rails.env}.scm.stderr.log").to_s
+            if File.exists?(path)
+              if File.file?(path) && File.writable?(path) 
+                writable = true
+              else
+                logger.warn("SCM log file (#{path}) is not writable")
+              end
+            else
+              begin
+                File.open(path, "w") {}
+                writable = true
+              rescue => e
+                logger.warn("SCM log file (#{path}) cannot be created: #{e.message}")
+              end
+            end
+            @stderr_log_file = writable ? path : false
+          end
+          @stderr_log_file || nil
+        end
+
+        def self.shellout(cmd, options = {}, &block)
+          if logger && logger.debug?
+            logger.debug "Shelling out: #{strip_credential(cmd)}"
+            # Capture stderr in a log file
+            if stderr_log_file
+              cmd = "#{cmd} 2>>#{shell_quote(stderr_log_file)}"
+            end
+          end
+          begin
+            mode = "r+"
+            IO.popen(cmd, mode) do |io|
+              io.set_encoding("ASCII-8BIT") if io.respond_to?(:set_encoding)
+              io.close_write unless options[:write_stdin]
+              block.call(io) if block_given?
+            end
+          ## If scm command does not exist,
+          ## Linux JRuby 1.6.2 (ruby-1.8.7-p330) raises java.io.IOException
+          ## in production environment.
+          # rescue Errno::ENOENT => e
+          rescue Exception => e
+            msg = strip_credential(e.message)
+            # The command failed, log it and re-raise
+            logmsg = "SCM command failed, "
+            logmsg += "make sure that your SCM command (e.g. svn) is "
+            logmsg += "in PATH (#{ENV['PATH']})\n"
+            logmsg += "You can configure your scm commands in config/configuration.yml.\n"
+            logmsg += "#{strip_credential(cmd)}\n"
+            logmsg += "with: #{msg}"
+            logger.error(logmsg)
+            raise CommandFailed.new(msg)
+          end
+        end
+
+        # Hides username/password in a given command
+        def self.strip_credential(cmd)
+          q = (Redmine::Platform.mswin? ? '"' : "'")
+          cmd.to_s.gsub(/(\-\-(password|username))\s+(#{q}[^#{q}]+#{q}|[^#{q}]\S+)/, '\\1 xxxx')
+        end
+
+        def strip_credential(cmd)
+          self.class.strip_credential(cmd)
+        end
+
+        def scm_iconv(to, from, str)
+          return nil if str.nil?
+          return str if to == from
+          if str.respond_to?(:force_encoding)
+            str.force_encoding(from)
+            begin
+              str.encode(to)
+            rescue Exception => err
+              logger.error("failed to convert from #{from} to #{to}. #{err}")
+              nil
+            end
+          else
+            begin
+              Iconv.conv(to, from, str)
+            rescue Iconv::Failure => err
+              logger.error("failed to convert from #{from} to #{to}. #{err}")
+              nil
+            end
+          end
+        end
+
+        def parse_xml(xml)
+          if RUBY_PLATFORM == 'java'
+            xml = xml.sub(%r{<\?xml[^>]*\?>}, '')
+          end
+          ActiveSupport::XmlMini.parse(xml)
+        end
+      end
+
+      class Entries < Array
+        def sort_by_name
+          dup.sort! {|x,y|
+            if x.kind == y.kind
+              x.name.to_s <=> y.name.to_s
+            else
+              x.kind <=> y.kind
+            end
+          }
+        end
+
+        def revisions
+          revisions ||= Revisions.new(collect{|entry| entry.lastrev}.compact)
+        end
+      end
+
+      class Info
+        attr_accessor :root_url, :lastrev
+        def initialize(attributes={})
+          self.root_url = attributes[:root_url] if attributes[:root_url]
+          self.lastrev = attributes[:lastrev]
+        end
+      end
+
+      class Entry
+        attr_accessor :name, :path, :kind, :size, :lastrev, :changeset
+
+        def initialize(attributes={})
+          self.name = attributes[:name] if attributes[:name]
+          self.path = attributes[:path] if attributes[:path]
+          self.kind = attributes[:kind] if attributes[:kind]
+          self.size = attributes[:size].to_i if attributes[:size]
+          self.lastrev = attributes[:lastrev]
+        end
+
+        def is_file?
+          'file' == self.kind
+        end
+
+        def is_dir?
+          'dir' == self.kind
+        end
+
+        def is_text?
+          Redmine::MimeType.is_type?('text', name)
+        end
+
+        def author
+          if changeset
+            changeset.author.to_s
+          elsif lastrev
+            Redmine::CodesetUtil.replace_invalid_utf8(lastrev.author.to_s.split('<').first)
+          end
+        end
+      end
+
+      class Revisions < Array
+        def latest
+          sort {|x,y|
+            unless x.time.nil? or y.time.nil?
+              x.time <=> y.time
+            else
+              0
+            end
+          }.last
+        end
+      end
+
+      class Revision
+        attr_accessor :scmid, :name, :author, :time, :message,
+                      :paths, :revision, :branch, :identifier,
+                      :parents
+
+        def initialize(attributes={})
+          self.identifier = attributes[:identifier]
+          self.scmid      = attributes[:scmid]
+          self.name       = attributes[:name] || self.identifier
+          self.author     = attributes[:author]
+          self.time       = attributes[:time]
+          self.message    = attributes[:message] || ""
+          self.paths      = attributes[:paths]
+          self.revision   = attributes[:revision]
+          self.branch     = attributes[:branch]
+          self.parents    = attributes[:parents]
+        end
+
+        # Returns the readable identifier.
+        def format_identifier
+          self.identifier.to_s
+        end
+
+        def ==(other)
+          if other.nil?
+            false
+          elsif scmid.present?
+            scmid == other.scmid
+          elsif identifier.present?
+            identifier == other.identifier
+          elsif revision.present?
+            revision == other.revision
+          end
+        end
+      end
+
+      class Annotate
+        attr_reader :lines, :revisions
+
+        def initialize
+          @lines = []
+          @revisions = []
+        end
+
+        def add_line(line, revision)
+          @lines << line
+          @revisions << revision
+        end
+
+        def content
+          content = lines.join("\n")
+        end
+
+        def empty?
+          lines.empty?
+        end
+      end
+
+      class Branch < String
+        attr_accessor :revision, :scmid
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a9/a912667150d22dbe4bd798c3e7e202b84644fb93.svn-base
--- /dev/null
+++ b/.svn/pristine/a9/a912667150d22dbe4bd798c3e7e202b84644fb93.svn-base
@@ -0,0 +1,74 @@
+<div class="contextual">
+<%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
+</div>
+
+<%= render_timelog_breadcrumb %>
+
+<h2><%= l(:label_spent_time) %></h2>
+
+<%= form_tag({:controller => 'timelog', :action => 'report',
+              :project_id => @project, :issue_id => @issue},
+            :method => :get, :id => 'query_form') do %>
+  <% @report.criteria.each do |criterion| %>
+    <%= hidden_field_tag 'criteria[]', criterion, :id => nil %>
+  <% end %>
+  <%= render :partial => 'timelog/date_range' %>
+
+  <p><label for='columns'><%= l(:label_details) %></label>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'],
+                                                                            [l(:label_month), 'month'],
+                                                                            [l(:label_week), 'week'],
+                                                                            [l(:label_day_plural).titleize, 'day']], @report.columns),
+                                                        :onchange => "this.form.submit();" %>
+
+  <label for='criterias'><%= l(:button_add) %></label>: <%= select_tag('criteria[]', options_for_select([[]] + (@report.available_criteria.keys - @report.criteria).collect{|k| [l_or_humanize(@report.available_criteria[k][:label]), k]}),
+                                                          :onchange => "this.form.submit();",
+                                                          :style => 'width: 200px',
+                                                          :id => nil,
+                                                          :disabled => (@report.criteria.length >= 3), :id => "criterias") %>
+     <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @report.columns}, :class => 'icon icon-reload' %></p>
+<% end %>
+
+<% unless @report.criteria.empty? %>
+<div class="total-hours">
+<p><%= l(:label_total_time) %>: <%= html_hours(l_hours(@report.total_hours)) %></p>
+</div>
+
+<% unless @report.hours.empty? %>
+<div class="autoscroll">
+<table class="list" id="time-report">
+<thead>
+<tr>
+<% @report.criteria.each do |criteria| %>
+  <th><%= l_or_humanize(@report.available_criteria[criteria][:label]) %></th>
+<% end %>
+<% columns_width = (40 / (@report.periods.length+1)).to_i %>
+<% @report.periods.each do |period| %>
+  <th class="period" width="<%= columns_width %>%"><%= period %></th>
+<% end %>
+  <th class="total" width="<%= columns_width %>%"><%= l(:label_total_time) %></th>
+</tr>
+</thead>
+<tbody>
+<%= render :partial => 'report_criteria', :locals => {:criterias => @report.criteria, :hours => @report.hours, :level => 0} %>
+  <tr class="total">
+  <td><%= l(:label_total_time) %></td>
+  <%= ('<td></td>' * (@report.criteria.size - 1)).html_safe %>
+  <% total = 0 -%>
+  <% @report.periods.each do |period| -%>
+    <% sum = sum_hours(select_hours(@report.hours, @report.columns, period.to_s)); total += sum -%>
+    <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
+  <% end -%>
+  <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
+  </tr>
+</tbody>
+</table>
+</div>
+
+<% other_formats_links do |f| %>
+  <%= f.link_to 'CSV', :url => params %>
+<% end %>
+<% end %>
+<% end %>
+
+<% html_title l(:label_spent_time), l(:label_report) %>
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a9/a9144938df8568206092af8b2736e7164e1c6392.svn-base
--- a/.svn/pristine/a9/a9144938df8568206092af8b2736e7164e1c6392.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar NL language
-// Author: Linda van den Brink, <linda@dynasol.nl>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Zondag",
- "Maandag",
- "Dinsdag",
- "Woensdag",
- "Donderdag",
- "Vrijdag",
- "Zaterdag",
- "Zondag");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Zo",
- "Ma",
- "Di",
- "Wo",
- "Do",
- "Vr",
- "Za",
- "Zo");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("Januari",
- "Februari",
- "Maart",
- "April",
- "Mei",
- "Juni",
- "Juli",
- "Augustus",
- "September",
- "Oktober",
- "November",
- "December");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "Maa",
- "Apr",
- "Mei",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Okt",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Over de kalender";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Datum selectie:\n" +
-"- Gebruik de \xab, \xbb knoppen om het jaar te selecteren\n" +
-"- Gebruik de " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " knoppen om de maand te selecteren\n" +
-"- Houd de muisknop ingedrukt op een van de knoppen voor snellere selectie.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Tijd selectie:\n" +
-"- Klik op een deel van de tijd om het te verhogen\n" +
-"- of Shift-click om het te verlagen\n" +
-"- of klik en sleep voor snellere selectie.";
-
-Calendar._TT["PREV_YEAR"] = "Vorig jaar (vasthouden voor menu)";
-Calendar._TT["PREV_MONTH"] = "Vorige maand (vasthouden voor menu)";
-Calendar._TT["GO_TODAY"] = "Ga naar vandaag";
-Calendar._TT["NEXT_MONTH"] = "Volgende maand (vasthouden voor menu)";
-Calendar._TT["NEXT_YEAR"] = "Volgend jaar(vasthouden voor menu)";
-Calendar._TT["SEL_DATE"] = "Selecteer datum";
-Calendar._TT["DRAG_TO_MOVE"] = "Sleep om te verplaatsen";
-Calendar._TT["PART_TODAY"] = " (vandaag)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Toon %s eerst";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Sluiten";
-Calendar._TT["TODAY"] = "Vandaag";
-Calendar._TT["TIME_PART"] = "(Shift-)klik of sleep om waarde te wijzigen";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Tijd:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a9/a9ab7e6c66164bb7bdc084f9bdf8c8f5056b877b.svn-base
--- a/.svn/pristine/a9/a9ab7e6c66164bb7bdc084f9bdf8c8f5056b877b.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'blankslate'
-
-module Redmine
-  module Views
-    module Builders
-      class Json < Structure
-        def output
-          @struct.first.to_json
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/a9/a9efaf1639993585b08f796d4994f7cfff12bb4e.svn-base
--- /dev/null
+++ b/.svn/pristine/a9/a9efaf1639993585b08f796d4994f7cfff12bb4e.svn-base
@@ -0,0 +1,109 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class WatchersController < ApplicationController
+  before_filter :require_login, :find_watchables, :only => [:watch, :unwatch]
+
+  def watch
+    set_watcher(@watchables, User.current, true)
+  end
+
+  def unwatch
+    set_watcher(@watchables, User.current, false)
+  end
+
+  before_filter :find_project, :authorize, :only => [:new, :create, :append, :destroy, :autocomplete_for_user]
+  accept_api_auth :create, :destroy
+
+  def new
+  end
+
+  def create
+    user_ids = []
+    if params[:watcher].is_a?(Hash)
+      user_ids << (params[:watcher][:user_ids] || params[:watcher][:user_id])
+    else
+      user_ids << params[:user_id]
+    end
+    user_ids.flatten.compact.uniq.each do |user_id|
+      Watcher.create(:watchable => @watched, :user_id => user_id)
+    end
+    respond_to do |format|
+      format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}}
+      format.js
+      format.api { render_api_ok }
+    end
+  end
+
+  def append
+    if params[:watcher].is_a?(Hash)
+      user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]]
+      @users = User.active.find_all_by_id(user_ids)
+    end
+  end
+
+  def destroy
+    @watched.set_watcher(User.find(params[:user_id]), false)
+    respond_to do |format|
+      format.html { redirect_to :back }
+      format.js
+      format.api { render_api_ok }
+    end
+  end
+
+  def autocomplete_for_user
+    @users = User.active.sorted.like(params[:q]).limit(100).all
+    if @watched
+      @users -= @watched.watcher_users
+    end
+    render :layout => false
+  end
+
+  private
+
+  def find_project
+    if params[:object_type] && params[:object_id]
+      klass = Object.const_get(params[:object_type].camelcase)
+      return false unless klass.respond_to?('watched_by')
+      @watched = klass.find(params[:object_id])
+      @project = @watched.project
+    elsif params[:project_id]
+      @project = Project.visible.find_by_param(params[:project_id])
+    end
+  rescue
+    render_404
+  end
+
+  def find_watchables
+    klass = Object.const_get(params[:object_type].camelcase) rescue nil
+    if klass && klass.respond_to?('watched_by')
+      @watchables = klass.find_all_by_id(Array.wrap(params[:object_id]))
+      raise Unauthorized if @watchables.any? {|w| w.respond_to?(:visible?) && !w.visible?}
+    end
+    render_404 unless @watchables.present?
+  end
+
+  def set_watcher(watchables, user, watching)
+    watchables.each do |watchable|
+      watchable.set_watcher(user, watching)
+    end
+    respond_to do |format|
+      format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}}
+      format.js { render :partial => 'set_watcher', :locals => {:user => user, :watched => watchables} }
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/aa/aa4319d8f7d992a29eec92a78f6cd5cf0f5f274a.svn-base
--- /dev/null
+++ b/.svn/pristine/aa/aa4319d8f7d992a29eec92a78f6cd5cf0f5f274a.svn-base
@@ -0,0 +1,31 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module AccessKeys
+    ACCESSKEYS = {:edit => 'e',
+                  :preview => 'r',
+                  :quick_search => 'f',
+                  :search => '4',
+                  :new_issue => '7'
+                 }.freeze unless const_defined?(:ACCESSKEYS)
+
+    def self.key_for(action)
+      ACCESSKEYS[action]
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/aa/aa5fa7df3d91739b6bac9d62c91f04e7ca038236.svn-base
--- a/.svn/pristine/aa/aa5fa7df3d91739b6bac9d62c91f04e7ca038236.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-<% if @user.auth_source %>
-<p><%= l(:mail_body_account_information_external, h(@user.auth_source.name)) %></p>
-<% else %>
-<p><%= l(:mail_body_account_information) %>:</p>
-<ul>
-    <li><%= l(:field_login) %>: <%=h @user.login %></li>
-    <li><%= l(:field_password) %>: <%=h @password %></li>
-</ul>
-<% end %>
-
-<p><%= l(:label_login) %>: <%= auto_link(@login_url) %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/aa/aa83ac24d27425c9b1e6b5d12c9f1c8532ff39ae.svn-base
--- a/.svn/pristine/aa/aa83ac24d27425c9b1e6b5d12c9f1c8532ff39ae.svn-base
+++ /dev/null
@@ -1,146 +0,0 @@
-desc 'Updates and checks locales against en.yml'
-task :locales do
-  %w(locales:update locales:check_interpolation).collect do |task|
-    Rake::Task[task].invoke
-  end
-end
-
-namespace :locales do
-  desc 'Updates language files based on en.yml content (only works for new top level keys).'
-  task :update do
-    dir = ENV['DIR'] || './config/locales'
-
-    en_strings = YAML.load(File.read(File.join(dir,'en.yml')))['en']
-
-    files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
-    files.each do |file|
-      puts "Updating file #{file}"
-      file_strings = YAML.load(File.read(file))
-      file_strings = file_strings[file_strings.keys.first]
-
-      missing_keys = en_strings.keys - file_strings.keys
-      next if missing_keys.empty?
-
-      puts "==> Missing #{missing_keys.size} keys (#{missing_keys.join(', ')})"
-      lang = File.open(file, 'a')
-
-      missing_keys.each do |key|
-        {key => en_strings[key]}.to_yaml.each_line do |line|
-          next if line =~ /^---/ || line.empty?
-          puts "  #{line}"
-          lang << "  #{line}"
-        end
-      end
-
-      lang.close
-    end
-  end
-
-  desc 'Checks interpolation arguments in locals against en.yml'
-  task :check_interpolation do
-    dir = ENV['DIR'] || './config/locales'
-    en_strings = YAML.load(File.read(File.join(dir,'en.yml')))['en']
-    files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
-    files.each do |file|
-      file_strings = YAML.load(File.read(file))
-      file_strings = file_strings[file_strings.keys.first]
-
-      file_strings.each do |key, string|
-        next unless string.is_a?(String)
-        string.scan /%\{\w+\}/ do |match|
-          unless en_strings[key].nil? || en_strings[key].include?(match)
-            puts "#{file}: #{key} uses #{match} not found in en.yml"
-          end
-        end
-      end
-    end
-  end
-
-  desc <<-END_DESC
-Removes a translation string from all locale file (only works for top-level childless non-multiline keys, probably doesn\'t work on windows).
-
-This task does not work on Ruby 1.8.6.
-You need to use Ruby 1.8.7 or later.
-
-Options:
-  key=key_1,key_2    Comma-separated list of keys to delete
-  skip=en,de         Comma-separated list of locale files to ignore (filename without extension)
-END_DESC
-
-  task :remove_key do
-    dir = ENV['DIR'] || './config/locales'
-    files = Dir.glob(File.join(dir,'*.yml'))
-    skips = ENV['skip'] ? Regexp.union(ENV['skip'].split(',')) : nil
-    deletes = ENV['key'] ? Regexp.union(ENV['key'].split(',')) : nil
-    # Ignore multiline keys (begin with | or >) and keys with children (nothing meaningful after :)
-    delete_regex = /\A  #{deletes}: +[^\|>\s#].*\z/
-
-    files.each do |path|
-      # Skip certain locales
-      (puts "Skipping #{path}"; next) if File.basename(path, ".yml") =~ skips
-      puts "Deleting selected keys from #{path}"
-      orig_content = File.open(path, 'r') {|file| file.read}
-      File.open(path, 'w') {|file| orig_content.each_line {|line| file.puts line unless line.chomp =~ delete_regex}}
-    end
-  end
-
-  desc <<-END_DESC
-Adds a new top-level translation string to all locale file (only works for childless keys, probably doesn\'t work on windows, doesn't check for duplicates).
-
-Options:
-  key="some_key=foo"
-  key1="another_key=bar"
-  key_fb="foo=bar"         Keys to add in the form key=value, every option of the form key[,\\d,_*] will be recognised
-  skip=en,de               Comma-separated list of locale files to ignore (filename without extension)
-END_DESC
-
-  task :add_key do
-    dir = ENV['DIR'] || './config/locales'
-    files = Dir.glob(File.join(dir,'*.yml'))
-    skips = ENV['skip'] ? Regexp.union(ENV['skip'].split(',')) : nil
-    keys_regex = /\Akey(\d+|_.+)?\z/
-    adds = ENV.reject {|k,v| !(k =~ keys_regex)}.values.collect {|v| Array.new v.split("=",2)}
-    key_list = adds.collect {|v| v[0]}.join(", ")
-
-    files.each do |path|
-      # Skip certain locales
-      (puts "Skipping #{path}"; next) if File.basename(path, ".yml") =~ skips
-      # TODO: Check for dupliate/existing keys
-      puts "Adding #{key_list} to #{path}"
-      File.open(path, 'a') do |file|
-        adds.each do |kv|
-          Hash[*kv].to_yaml.each_line do |line|
-            file.puts "  #{line}" unless (line =~ /^---/ || line.empty?)
-          end
-        end
-      end
-    end
-  end
-
-  desc 'Check parsing yaml by psych library on Ruby 1.9.'
-
-  # On Fedora 12 and 13, if libyaml-devel is available,
-  # in case of installing by rvm,
-  # Ruby 1.9 default yaml library is psych.
-
-  task :check_parsing_by_psych do
-    begin
-      require 'psych'
-      parser = Psych::Parser.new
-      dir = ENV['DIR'] || './config/locales'
-      files = Dir.glob(File.join(dir,'*.yml'))
-      files.each do |filename|
-        next if File.directory? filename
-        puts "parsing #{filename}..."
-        begin
-          parser.parse File.open(filename)
-        rescue Exception => e1
-          puts(e1.message)
-          puts("")
-        end
-      end
-    rescue Exception => e
-      puts(e.message)
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/aa/aaf62c9f3ca1b6132c157b80510087adff469138.svn-base
--- a/.svn/pristine/aa/aaf62c9f3ca1b6132c157b80510087adff469138.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-desc 'Removes watchers from what they can no longer view.'
-
-namespace :redmine do
-  namespace :watchers do
-    task :prune => :environment do
-      Watcher.prune
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/ab057f25c21b7df0687551bcc5efdab05be328b5.svn-base
--- a/.svn/pristine/ab/ab057f25c21b7df0687551bcc5efdab05be328b5.svn-base
+++ /dev/null
@@ -1,768 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'active_record'
-require 'iconv'
-require 'pp'
-
-namespace :redmine do
-  desc 'Trac migration script'
-  task :migrate_from_trac => :environment do
-
-    module TracMigrate
-        TICKET_MAP = []
-
-        DEFAULT_STATUS = IssueStatus.default
-        assigned_status = IssueStatus.find_by_position(2)
-        resolved_status = IssueStatus.find_by_position(3)
-        feedback_status = IssueStatus.find_by_position(4)
-        closed_status = IssueStatus.find :first, :conditions => { :is_closed => true }
-        STATUS_MAPPING = {'new' => DEFAULT_STATUS,
-                          'reopened' => feedback_status,
-                          'assigned' => assigned_status,
-                          'closed' => closed_status
-                          }
-
-        priorities = IssuePriority.all
-        DEFAULT_PRIORITY = priorities[0]
-        PRIORITY_MAPPING = {'lowest' => priorities[0],
-                            'low' => priorities[0],
-                            'normal' => priorities[1],
-                            'high' => priorities[2],
-                            'highest' => priorities[3],
-                            # ---
-                            'trivial' => priorities[0],
-                            'minor' => priorities[1],
-                            'major' => priorities[2],
-                            'critical' => priorities[3],
-                            'blocker' => priorities[4]
-                            }
-
-        TRACKER_BUG = Tracker.find_by_position(1)
-        TRACKER_FEATURE = Tracker.find_by_position(2)
-        DEFAULT_TRACKER = TRACKER_BUG
-        TRACKER_MAPPING = {'defect' => TRACKER_BUG,
-                           'enhancement' => TRACKER_FEATURE,
-                           'task' => TRACKER_FEATURE,
-                           'patch' =>TRACKER_FEATURE
-                           }
-
-        roles = Role.find(:all, :conditions => {:builtin => 0}, :order => 'position ASC')
-        manager_role = roles[0]
-        developer_role = roles[1]
-        DEFAULT_ROLE = roles.last
-        ROLE_MAPPING = {'admin' => manager_role,
-                        'developer' => developer_role
-                        }
-
-      class ::Time
-        class << self
-          alias :real_now :now
-          def now
-            real_now - @fake_diff.to_i
-          end
-          def fake(time)
-            @fake_diff = real_now - time
-            res = yield
-            @fake_diff = 0
-           res
-          end
-        end
-      end
-
-      class TracComponent < ActiveRecord::Base
-        set_table_name :component
-      end
-
-      class TracMilestone < ActiveRecord::Base
-        set_table_name :milestone
-        # If this attribute is set a milestone has a defined target timepoint
-        def due
-          if read_attribute(:due) && read_attribute(:due) > 0
-            Time.at(read_attribute(:due)).to_date
-          else
-            nil
-          end
-        end
-        # This is the real timepoint at which the milestone has finished.
-        def completed
-          if read_attribute(:completed) && read_attribute(:completed) > 0
-            Time.at(read_attribute(:completed)).to_date
-          else
-            nil
-          end
-        end
-
-        def description
-          # Attribute is named descr in Trac v0.8.x
-          has_attribute?(:descr) ? read_attribute(:descr) : read_attribute(:description)
-        end
-      end
-
-      class TracTicketCustom < ActiveRecord::Base
-        set_table_name :ticket_custom
-      end
-
-      class TracAttachment < ActiveRecord::Base
-        set_table_name :attachment
-        set_inheritance_column :none
-
-        def time; Time.at(read_attribute(:time)) end
-
-        def original_filename
-          filename
-        end
-
-        def content_type
-          ''
-        end
-
-        def exist?
-          File.file? trac_fullpath
-        end
-
-        def open
-          File.open("#{trac_fullpath}", 'rb') {|f|
-            @file = f
-            yield self
-          }
-        end
-
-        def read(*args)
-          @file.read(*args)
-        end
-
-        def description
-          read_attribute(:description).to_s.slice(0,255)
-        end
-
-      private
-        def trac_fullpath
-          attachment_type = read_attribute(:type)
-          trac_file = filename.gsub( /[^a-zA-Z0-9\-_\.!~*']/n ) {|x| sprintf('%%%02x', x[0]) }
-          "#{TracMigrate.trac_attachments_directory}/#{attachment_type}/#{id}/#{trac_file}"
-        end
-      end
-
-      class TracTicket < ActiveRecord::Base
-        set_table_name :ticket
-        set_inheritance_column :none
-
-        # ticket changes: only migrate status changes and comments
-        has_many :changes, :class_name => "TracTicketChange", :foreign_key => :ticket
-        has_many :attachments, :class_name => "TracAttachment",
-                               :finder_sql => "SELECT DISTINCT attachment.* FROM #{TracMigrate::TracAttachment.table_name}" +
-                                              " WHERE #{TracMigrate::TracAttachment.table_name}.type = 'ticket'" +
-                                              ' AND #{TracMigrate::TracAttachment.table_name}.id = \'#{TracMigrate::TracAttachment.connection.quote_string(id.to_s)}\''
-        has_many :customs, :class_name => "TracTicketCustom", :foreign_key => :ticket
-
-        def ticket_type
-          read_attribute(:type)
-        end
-
-        def summary
-          read_attribute(:summary).blank? ? "(no subject)" : read_attribute(:summary)
-        end
-
-        def description
-          read_attribute(:description).blank? ? summary : read_attribute(:description)
-        end
-
-        def time; Time.at(read_attribute(:time)) end
-        def changetime; Time.at(read_attribute(:changetime)) end
-      end
-
-      class TracTicketChange < ActiveRecord::Base
-        set_table_name :ticket_change
-
-        def time; Time.at(read_attribute(:time)) end
-      end
-
-      TRAC_WIKI_PAGES = %w(InterMapTxt InterTrac InterWiki RecentChanges SandBox TracAccessibility TracAdmin TracBackup TracBrowser TracCgi TracChangeset \
-                           TracEnvironment TracFastCgi TracGuide TracImport TracIni TracInstall TracInterfaceCustomization \
-                           TracLinks TracLogging TracModPython TracNotification TracPermissions TracPlugins TracQuery \
-                           TracReports TracRevisionLog TracRoadmap TracRss TracSearch TracStandalone TracSupport TracSyntaxColoring TracTickets \
-                           TracTicketsCustomFields TracTimeline TracUnicode TracUpgrade TracWiki WikiDeletePage WikiFormatting \
-                           WikiHtml WikiMacros WikiNewPage WikiPageNames WikiProcessors WikiRestructuredText WikiRestructuredTextLinks \
-                           CamelCase TitleIndex)
-
-      class TracWikiPage < ActiveRecord::Base
-        set_table_name :wiki
-        set_primary_key :name
-
-        has_many :attachments, :class_name => "TracAttachment",
-                               :finder_sql => "SELECT DISTINCT attachment.* FROM #{TracMigrate::TracAttachment.table_name}" +
-                                      " WHERE #{TracMigrate::TracAttachment.table_name}.type = 'wiki'" +
-                                      ' AND #{TracMigrate::TracAttachment.table_name}.id = \'#{TracMigrate::TracAttachment.connection.quote_string(id.to_s)}\''
-
-        def self.columns
-          # Hides readonly Trac field to prevent clash with AR readonly? method (Rails 2.0)
-          super.select {|column| column.name.to_s != 'readonly'}
-        end
-
-        def time; Time.at(read_attribute(:time)) end
-      end
-
-      class TracPermission < ActiveRecord::Base
-        set_table_name :permission
-      end
-
-      class TracSessionAttribute < ActiveRecord::Base
-        set_table_name :session_attribute
-      end
-
-      def self.find_or_create_user(username, project_member = false)
-        return User.anonymous if username.blank?
-
-        u = User.find_by_login(username)
-        if !u
-          # Create a new user if not found
-          mail = username[0,limit_for(User, 'mail')]
-          if mail_attr = TracSessionAttribute.find_by_sid_and_name(username, 'email')
-            mail = mail_attr.value
-          end
-          mail = "#{mail}@foo.bar" unless mail.include?("@")
-
-          name = username
-          if name_attr = TracSessionAttribute.find_by_sid_and_name(username, 'name')
-            name = name_attr.value
-          end
-          name =~ (/(.*)(\s+\w+)?/)
-          fn = $1.strip
-          ln = ($2 || '-').strip
-
-          u = User.new :mail => mail.gsub(/[^-@a-z0-9\.]/i, '-'),
-                       :firstname => fn[0, limit_for(User, 'firstname')],
-                       :lastname => ln[0, limit_for(User, 'lastname')]
-
-          u.login = username[0,limit_for(User, 'login')].gsub(/[^a-z0-9_\-@\.]/i, '-')
-          u.password = 'trac'
-          u.admin = true if TracPermission.find_by_username_and_action(username, 'admin')
-          # finally, a default user is used if the new user is not valid
-          u = User.find(:first) unless u.save
-        end
-        # Make sure he is a member of the project
-        if project_member && !u.member_of?(@target_project)
-          role = DEFAULT_ROLE
-          if u.admin
-            role = ROLE_MAPPING['admin']
-          elsif TracPermission.find_by_username_and_action(username, 'developer')
-            role = ROLE_MAPPING['developer']
-          end
-          Member.create(:user => u, :project => @target_project, :roles => [role])
-          u.reload
-        end
-        u
-      end
-
-      # Basic wiki syntax conversion
-      def self.convert_wiki_text(text)
-        # Titles
-        text = text.gsub(/^(\=+)\s(.+)\s(\=+)/) {|s| "\nh#{$1.length}. #{$2}\n"}
-        # External Links
-        text = text.gsub(/\[(http[^\s]+)\s+([^\]]+)\]/) {|s| "\"#{$2}\":#{$1}"}
-        # Ticket links:
-        #      [ticket:234 Text],[ticket:234 This is a test]
-        text = text.gsub(/\[ticket\:([^\ ]+)\ (.+?)\]/, '"\2":/issues/show/\1')
-        #      ticket:1234
-        #      #1 is working cause Redmine uses the same syntax.
-        text = text.gsub(/ticket\:([^\ ]+)/, '#\1')
-        # Milestone links:
-        #      [milestone:"0.1.0 Mercury" Milestone 0.1.0 (Mercury)]
-        #      The text "Milestone 0.1.0 (Mercury)" is not converted,
-        #      cause Redmine's wiki does not support this.
-        text = text.gsub(/\[milestone\:\"([^\"]+)\"\ (.+?)\]/, 'version:"\1"')
-        #      [milestone:"0.1.0 Mercury"]
-        text = text.gsub(/\[milestone\:\"([^\"]+)\"\]/, 'version:"\1"')
-        text = text.gsub(/milestone\:\"([^\"]+)\"/, 'version:"\1"')
-        #      milestone:0.1.0
-        text = text.gsub(/\[milestone\:([^\ ]+)\]/, 'version:\1')
-        text = text.gsub(/milestone\:([^\ ]+)/, 'version:\1')
-        # Internal Links
-        text = text.gsub(/\[\[BR\]\]/, "\n") # This has to go before the rules below
-        text = text.gsub(/\[\"(.+)\".*\]/) {|s| "[[#{$1.delete(',./?;|:')}]]"}
-        text = text.gsub(/\[wiki:\"(.+)\".*\]/) {|s| "[[#{$1.delete(',./?;|:')}]]"}
-        text = text.gsub(/\[wiki:\"(.+)\".*\]/) {|s| "[[#{$1.delete(',./?;|:')}]]"}
-        text = text.gsub(/\[wiki:([^\s\]]+)\]/) {|s| "[[#{$1.delete(',./?;|:')}]]"}
-        text = text.gsub(/\[wiki:([^\s\]]+)\s(.*)\]/) {|s| "[[#{$1.delete(',./?;|:')}|#{$2.delete(',./?;|:')}]]"}
-
-  # Links to pages UsingJustWikiCaps
-  text = text.gsub(/([^!]|^)(^| )([A-Z][a-z]+[A-Z][a-zA-Z]+)/, '\\1\\2[[\3]]')
-  # Normalize things that were supposed to not be links
-  # like !NotALink
-  text = text.gsub(/(^| )!([A-Z][A-Za-z]+)/, '\1\2')
-        # Revisions links
-        text = text.gsub(/\[(\d+)\]/, 'r\1')
-        # Ticket number re-writing
-        text = text.gsub(/#(\d+)/) do |s|
-          if $1.length < 10
-#            TICKET_MAP[$1.to_i] ||= $1
-            "\##{TICKET_MAP[$1.to_i] || $1}"
-          else
-            s
-          end
-        end
-        # We would like to convert the Code highlighting too
-        # This will go into the next line.
-        shebang_line = false
-        # Reguar expression for start of code
-        pre_re = /\{\{\{/
-        # Code hightlighing...
-        shebang_re = /^\#\!([a-z]+)/
-        # Regular expression for end of code
-        pre_end_re = /\}\}\}/
-
-        # Go through the whole text..extract it line by line
-        text = text.gsub(/^(.*)$/) do |line|
-          m_pre = pre_re.match(line)
-          if m_pre
-            line = '<pre>'
-          else
-            m_sl = shebang_re.match(line)
-            if m_sl
-              shebang_line = true
-              line = '<code class="' + m_sl[1] + '">'
-            end
-            m_pre_end = pre_end_re.match(line)
-            if m_pre_end
-              line = '</pre>'
-              if shebang_line
-                line = '</code>' + line
-              end
-            end
-          end
-          line
-        end
-
-        # Highlighting
-        text = text.gsub(/'''''([^\s])/, '_*\1')
-        text = text.gsub(/([^\s])'''''/, '\1*_')
-        text = text.gsub(/'''/, '*')
-        text = text.gsub(/''/, '_')
-        text = text.gsub(/__/, '+')
-        text = text.gsub(/~~/, '-')
-        text = text.gsub(/`/, '@')
-        text = text.gsub(/,,/, '~')
-        # Lists
-        text = text.gsub(/^([ ]+)\* /) {|s| '*' * $1.length + " "}
-
-        text
-      end
-
-      def self.migrate
-        establish_connection
-
-        # Quick database test
-        TracComponent.count
-
-        migrated_components = 0
-        migrated_milestones = 0
-        migrated_tickets = 0
-        migrated_custom_values = 0
-        migrated_ticket_attachments = 0
-        migrated_wiki_edits = 0
-        migrated_wiki_attachments = 0
-
-        #Wiki system initializing...
-        @target_project.wiki.destroy if @target_project.wiki
-        @target_project.reload
-        wiki = Wiki.new(:project => @target_project, :start_page => 'WikiStart')
-        wiki_edit_count = 0
-
-        # Components
-        print "Migrating components"
-        issues_category_map = {}
-        TracComponent.find(:all).each do |component|
-        print '.'
-        STDOUT.flush
-          c = IssueCategory.new :project => @target_project,
-                                :name => encode(component.name[0, limit_for(IssueCategory, 'name')])
-        next unless c.save
-        issues_category_map[component.name] = c
-        migrated_components += 1
-        end
-        puts
-
-        # Milestones
-        print "Migrating milestones"
-        version_map = {}
-        TracMilestone.find(:all).each do |milestone|
-          print '.'
-          STDOUT.flush
-          # First we try to find the wiki page...
-          p = wiki.find_or_new_page(milestone.name.to_s)
-          p.content = WikiContent.new(:page => p) if p.new_record?
-          p.content.text = milestone.description.to_s
-          p.content.author = find_or_create_user('trac')
-          p.content.comments = 'Milestone'
-          p.save
-
-          v = Version.new :project => @target_project,
-                          :name => encode(milestone.name[0, limit_for(Version, 'name')]),
-                          :description => nil,
-                          :wiki_page_title => milestone.name.to_s,
-                          :effective_date => milestone.completed
-
-          next unless v.save
-          version_map[milestone.name] = v
-          migrated_milestones += 1
-        end
-        puts
-
-        # Custom fields
-        # TODO: read trac.ini instead
-        print "Migrating custom fields"
-        custom_field_map = {}
-        TracTicketCustom.find_by_sql("SELECT DISTINCT name FROM #{TracTicketCustom.table_name}").each do |field|
-          print '.'
-          STDOUT.flush
-          # Redmine custom field name
-          field_name = encode(field.name[0, limit_for(IssueCustomField, 'name')]).humanize
-          # Find if the custom already exists in Redmine
-          f = IssueCustomField.find_by_name(field_name)
-          # Or create a new one
-          f ||= IssueCustomField.create(:name => encode(field.name[0, limit_for(IssueCustomField, 'name')]).humanize,
-                                        :field_format => 'string')
-
-          next if f.new_record?
-          f.trackers = Tracker.find(:all)
-          f.projects << @target_project
-          custom_field_map[field.name] = f
-        end
-        puts
-
-        # Trac 'resolution' field as a Redmine custom field
-        r = IssueCustomField.find(:first, :conditions => { :name => "Resolution" })
-        r = IssueCustomField.new(:name => 'Resolution',
-                                 :field_format => 'list',
-                                 :is_filter => true) if r.nil?
-        r.trackers = Tracker.find(:all)
-        r.projects << @target_project
-        r.possible_values = (r.possible_values + %w(fixed invalid wontfix duplicate worksforme)).flatten.compact.uniq
-        r.save!
-        custom_field_map['resolution'] = r
-
-        # Tickets
-        print "Migrating tickets"
-          TracTicket.find_each(:batch_size => 200) do |ticket|
-          print '.'
-          STDOUT.flush
-          i = Issue.new :project => @target_project,
-                          :subject => encode(ticket.summary[0, limit_for(Issue, 'subject')]),
-                          :description => convert_wiki_text(encode(ticket.description)),
-                          :priority => PRIORITY_MAPPING[ticket.priority] || DEFAULT_PRIORITY,
-                          :created_on => ticket.time
-          i.author = find_or_create_user(ticket.reporter)
-          i.category = issues_category_map[ticket.component] unless ticket.component.blank?
-          i.fixed_version = version_map[ticket.milestone] unless ticket.milestone.blank?
-          i.status = STATUS_MAPPING[ticket.status] || DEFAULT_STATUS
-          i.tracker = TRACKER_MAPPING[ticket.ticket_type] || DEFAULT_TRACKER
-          i.id = ticket.id unless Issue.exists?(ticket.id)
-          next unless Time.fake(ticket.changetime) { i.save }
-          TICKET_MAP[ticket.id] = i.id
-          migrated_tickets += 1
-
-          # Owner
-            unless ticket.owner.blank?
-              i.assigned_to = find_or_create_user(ticket.owner, true)
-              Time.fake(ticket.changetime) { i.save }
-            end
-
-          # Comments and status/resolution changes
-          ticket.changes.group_by(&:time).each do |time, changeset|
-              status_change = changeset.select {|change| change.field == 'status'}.first
-              resolution_change = changeset.select {|change| change.field == 'resolution'}.first
-              comment_change = changeset.select {|change| change.field == 'comment'}.first
-
-              n = Journal.new :notes => (comment_change ? convert_wiki_text(encode(comment_change.newvalue)) : ''),
-                              :created_on => time
-              n.user = find_or_create_user(changeset.first.author)
-              n.journalized = i
-              if status_change &&
-                   STATUS_MAPPING[status_change.oldvalue] &&
-                   STATUS_MAPPING[status_change.newvalue] &&
-                   (STATUS_MAPPING[status_change.oldvalue] != STATUS_MAPPING[status_change.newvalue])
-                n.details << JournalDetail.new(:property => 'attr',
-                                               :prop_key => 'status_id',
-                                               :old_value => STATUS_MAPPING[status_change.oldvalue].id,
-                                               :value => STATUS_MAPPING[status_change.newvalue].id)
-              end
-              if resolution_change
-                n.details << JournalDetail.new(:property => 'cf',
-                                               :prop_key => custom_field_map['resolution'].id,
-                                               :old_value => resolution_change.oldvalue,
-                                               :value => resolution_change.newvalue)
-              end
-              n.save unless n.details.empty? && n.notes.blank?
-          end
-
-          # Attachments
-          ticket.attachments.each do |attachment|
-            next unless attachment.exist?
-              attachment.open {
-                a = Attachment.new :created_on => attachment.time
-                a.file = attachment
-                a.author = find_or_create_user(attachment.author)
-                a.container = i
-                a.description = attachment.description
-                migrated_ticket_attachments += 1 if a.save
-              }
-          end
-
-          # Custom fields
-          custom_values = ticket.customs.inject({}) do |h, custom|
-            if custom_field = custom_field_map[custom.name]
-              h[custom_field.id] = custom.value
-              migrated_custom_values += 1
-            end
-            h
-          end
-          if custom_field_map['resolution'] && !ticket.resolution.blank?
-            custom_values[custom_field_map['resolution'].id] = ticket.resolution
-          end
-          i.custom_field_values = custom_values
-          i.save_custom_field_values
-        end
-
-        # update issue id sequence if needed (postgresql)
-        Issue.connection.reset_pk_sequence!(Issue.table_name) if Issue.connection.respond_to?('reset_pk_sequence!')
-        puts
-
-        # Wiki
-        print "Migrating wiki"
-        if wiki.save
-          TracWikiPage.find(:all, :order => 'name, version').each do |page|
-            # Do not migrate Trac manual wiki pages
-            next if TRAC_WIKI_PAGES.include?(page.name)
-            wiki_edit_count += 1
-            print '.'
-            STDOUT.flush
-            p = wiki.find_or_new_page(page.name)
-            p.content = WikiContent.new(:page => p) if p.new_record?
-            p.content.text = page.text
-            p.content.author = find_or_create_user(page.author) unless page.author.blank? || page.author == 'trac'
-            p.content.comments = page.comment
-            Time.fake(page.time) { p.new_record? ? p.save : p.content.save }
-
-            next if p.content.new_record?
-            migrated_wiki_edits += 1
-
-            # Attachments
-            page.attachments.each do |attachment|
-              next unless attachment.exist?
-              next if p.attachments.find_by_filename(attachment.filename.gsub(/^.*(\\|\/)/, '').gsub(/[^\w\.\-]/,'_')) #add only once per page
-              attachment.open {
-                a = Attachment.new :created_on => attachment.time
-                a.file = attachment
-                a.author = find_or_create_user(attachment.author)
-                a.description = attachment.description
-                a.container = p
-                migrated_wiki_attachments += 1 if a.save
-              }
-            end
-          end
-
-          wiki.reload
-          wiki.pages.each do |page|
-            page.content.text = convert_wiki_text(page.content.text)
-            Time.fake(page.content.updated_on) { page.content.save }
-          end
-        end
-        puts
-
-        puts
-        puts "Components:      #{migrated_components}/#{TracComponent.count}"
-        puts "Milestones:      #{migrated_milestones}/#{TracMilestone.count}"
-        puts "Tickets:         #{migrated_tickets}/#{TracTicket.count}"
-        puts "Ticket files:    #{migrated_ticket_attachments}/" + TracAttachment.count(:conditions => {:type => 'ticket'}).to_s
-        puts "Custom values:   #{migrated_custom_values}/#{TracTicketCustom.count}"
-        puts "Wiki edits:      #{migrated_wiki_edits}/#{wiki_edit_count}"
-        puts "Wiki files:      #{migrated_wiki_attachments}/" + TracAttachment.count(:conditions => {:type => 'wiki'}).to_s
-      end
-
-      def self.limit_for(klass, attribute)
-        klass.columns_hash[attribute.to_s].limit
-      end
-
-      def self.encoding(charset)
-        @ic = Iconv.new('UTF-8', charset)
-      rescue Iconv::InvalidEncoding
-        puts "Invalid encoding!"
-        return false
-      end
-
-      def self.set_trac_directory(path)
-        @@trac_directory = path
-        raise "This directory doesn't exist!" unless File.directory?(path)
-        raise "#{trac_attachments_directory} doesn't exist!" unless File.directory?(trac_attachments_directory)
-        @@trac_directory
-      rescue Exception => e
-        puts e
-        return false
-      end
-
-      def self.trac_directory
-        @@trac_directory
-      end
-
-      def self.set_trac_adapter(adapter)
-        return false if adapter.blank?
-        raise "Unknown adapter: #{adapter}!" unless %w(sqlite sqlite3 mysql postgresql).include?(adapter)
-        # If adapter is sqlite or sqlite3, make sure that trac.db exists
-        raise "#{trac_db_path} doesn't exist!" if %w(sqlite sqlite3).include?(adapter) && !File.exist?(trac_db_path)
-        @@trac_adapter = adapter
-      rescue Exception => e
-        puts e
-        return false
-      end
-
-      def self.set_trac_db_host(host)
-        return nil if host.blank?
-        @@trac_db_host = host
-      end
-
-      def self.set_trac_db_port(port)
-        return nil if port.to_i == 0
-        @@trac_db_port = port.to_i
-      end
-
-      def self.set_trac_db_name(name)
-        return nil if name.blank?
-        @@trac_db_name = name
-      end
-
-      def self.set_trac_db_username(username)
-        @@trac_db_username = username
-      end
-
-      def self.set_trac_db_password(password)
-        @@trac_db_password = password
-      end
-
-      def self.set_trac_db_schema(schema)
-        @@trac_db_schema = schema
-      end
-
-      mattr_reader :trac_directory, :trac_adapter, :trac_db_host, :trac_db_port, :trac_db_name, :trac_db_schema, :trac_db_username, :trac_db_password
-
-      def self.trac_db_path; "#{trac_directory}/db/trac.db" end
-      def self.trac_attachments_directory; "#{trac_directory}/attachments" end
-
-      def self.target_project_identifier(identifier)
-        project = Project.find_by_identifier(identifier)
-        if !project
-          # create the target project
-          project = Project.new :name => identifier.humanize,
-                                :description => ''
-          project.identifier = identifier
-          puts "Unable to create a project with identifier '#{identifier}'!" unless project.save
-          # enable issues and wiki for the created project
-          project.enabled_module_names = ['issue_tracking', 'wiki']
-        else
-          puts
-          puts "This project already exists in your Redmine database."
-          print "Are you sure you want to append data to this project ? [Y/n] "
-          STDOUT.flush
-          exit if STDIN.gets.match(/^n$/i)
-        end
-        project.trackers << TRACKER_BUG unless project.trackers.include?(TRACKER_BUG)
-        project.trackers << TRACKER_FEATURE unless project.trackers.include?(TRACKER_FEATURE)
-        @target_project = project.new_record? ? nil : project
-        @target_project.reload
-      end
-
-      def self.connection_params
-        if %w(sqlite sqlite3).include?(trac_adapter)
-          {:adapter => trac_adapter,
-           :database => trac_db_path}
-        else
-          {:adapter => trac_adapter,
-           :database => trac_db_name,
-           :host => trac_db_host,
-           :port => trac_db_port,
-           :username => trac_db_username,
-           :password => trac_db_password,
-           :schema_search_path => trac_db_schema
-          }
-        end
-      end
-
-      def self.establish_connection
-        constants.each do |const|
-          klass = const_get(const)
-          next unless klass.respond_to? 'establish_connection'
-          klass.establish_connection connection_params
-        end
-      end
-
-    private
-      def self.encode(text)
-        @ic.iconv text
-      rescue
-        text
-      end
-    end
-
-    puts
-    if Redmine::DefaultData::Loader.no_data?
-      puts "Redmine configuration need to be loaded before importing data."
-      puts "Please, run this first:"
-      puts
-      puts "  rake redmine:load_default_data RAILS_ENV=\"#{ENV['RAILS_ENV']}\""
-      exit
-    end
-
-    puts "WARNING: a new project will be added to Redmine during this process."
-    print "Are you sure you want to continue ? [y/N] "
-    STDOUT.flush
-    break unless STDIN.gets.match(/^y$/i)
-    puts
-
-    def prompt(text, options = {}, &block)
-      default = options[:default] || ''
-      while true
-        print "#{text} [#{default}]: "
-        STDOUT.flush
-        value = STDIN.gets.chomp!
-        value = default if value.blank?
-        break if yield value
-      end
-    end
-
-    DEFAULT_PORTS = {'mysql' => 3306, 'postgresql' => 5432}
-
-    prompt('Trac directory') {|directory| TracMigrate.set_trac_directory directory.strip}
-    prompt('Trac database adapter (sqlite, sqlite3, mysql, postgresql)', :default => 'sqlite') {|adapter| TracMigrate.set_trac_adapter adapter}
-    unless %w(sqlite sqlite3).include?(TracMigrate.trac_adapter)
-      prompt('Trac database host', :default => 'localhost') {|host| TracMigrate.set_trac_db_host host}
-      prompt('Trac database port', :default => DEFAULT_PORTS[TracMigrate.trac_adapter]) {|port| TracMigrate.set_trac_db_port port}
-      prompt('Trac database name') {|name| TracMigrate.set_trac_db_name name}
-      prompt('Trac database schema', :default => 'public') {|schema| TracMigrate.set_trac_db_schema schema}
-      prompt('Trac database username') {|username| TracMigrate.set_trac_db_username username}
-      prompt('Trac database password') {|password| TracMigrate.set_trac_db_password password}
-    end
-    prompt('Trac database encoding', :default => 'UTF-8') {|encoding| TracMigrate.encoding encoding}
-    prompt('Target project identifier') {|identifier| TracMigrate.target_project_identifier identifier}
-    puts
-
-    # Turn off email notifications
-    Setting.notified_events = []
-
-    TracMigrate.migrate
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/ab06de66fee50f24871dafa010661fea7e1b86f1.svn-base
--- /dev/null
+++ b/.svn/pristine/ab/ab06de66fee50f24871dafa010661fea7e1b86f1.svn-base
@@ -0,0 +1,182 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class VersionsController < ApplicationController
+  menu_item :roadmap
+  model_object Version
+  before_filter :find_model_object, :except => [:index, :new, :create, :close_completed]
+  before_filter :find_project_from_association, :except => [:index, :new, :create, :close_completed]
+  before_filter :find_project_by_project_id, :only => [:index, :new, :create, :close_completed]
+  before_filter :authorize
+
+  accept_api_auth :index, :show, :create, :update, :destroy
+
+  helper :custom_fields
+  helper :projects
+
+  def index
+    respond_to do |format|
+      format.html {
+        @trackers = @project.trackers.sorted.all
+        retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?})
+        @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
+        project_ids = @with_subprojects ? @project.self_and_descendants.collect(&:id) : [@project.id]
+
+        @versions = @project.shared_versions || []
+        @versions += @project.rolled_up_versions.visible if @with_subprojects
+        @versions = @versions.uniq.sort
+        unless params[:completed]
+          @completed_versions = @versions.select {|version| version.closed? || version.completed? }
+          @versions -= @completed_versions
+        end
+
+        @issues_by_version = {}
+        if @selected_tracker_ids.any? && @versions.any?
+          issues = Issue.visible.all(
+            :include => [:project, :status, :tracker, :priority, :fixed_version],
+            :conditions => {:tracker_id => @selected_tracker_ids, :project_id => project_ids, :fixed_version_id => @versions.map(&:id)},
+            :order => "#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id"
+          )
+          @issues_by_version = issues.group_by(&:fixed_version)
+        end
+        @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?}
+      }
+      format.api {
+        @versions = @project.shared_versions.all
+      }
+    end
+  end
+
+  def show
+    respond_to do |format|
+      format.html {
+        @issues = @version.fixed_issues.visible.
+          includes(:status, :tracker, :priority).
+          reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id").
+          all
+      }
+      format.api
+    end
+  end
+
+  def new
+    @version = @project.versions.build
+    @version.safe_attributes = params[:version]
+
+    respond_to do |format|
+      format.html
+      format.js
+    end
+  end
+
+  def create
+    @version = @project.versions.build
+    if params[:version]
+      attributes = params[:version].dup
+      attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
+      @version.safe_attributes = attributes
+    end
+
+    if request.post?
+      if @version.save
+        respond_to do |format|
+          format.html do
+            flash[:notice] = l(:notice_successful_create)
+            redirect_back_or_default settings_project_path(@project, :tab => 'versions')
+          end
+          format.js
+          format.api do
+            render :action => 'show', :status => :created, :location => version_url(@version)
+          end
+        end
+      else
+        respond_to do |format|
+          format.html { render :action => 'new' }
+          format.js   { render :action => 'new' }
+          format.api  { render_validation_errors(@version) }
+        end
+      end
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    if request.put? && params[:version]
+      attributes = params[:version].dup
+      attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing'])
+      @version.safe_attributes = attributes
+      if @version.save
+        respond_to do |format|
+          format.html {
+            flash[:notice] = l(:notice_successful_update)
+            redirect_back_or_default settings_project_path(@project, :tab => 'versions')
+          }
+          format.api  { render_api_ok }
+        end
+      else
+        respond_to do |format|
+          format.html { render :action => 'edit' }
+          format.api  { render_validation_errors(@version) }
+        end
+      end
+    end
+  end
+
+  def close_completed
+    if request.put?
+      @project.close_completed_versions
+    end
+    redirect_to settings_project_path(@project, :tab => 'versions')
+  end
+
+  def destroy
+    if @version.fixed_issues.empty?
+      @version.destroy
+      respond_to do |format|
+        format.html { redirect_back_or_default settings_project_path(@project, :tab => 'versions') }
+        format.api  { render_api_ok }
+      end
+    else
+      respond_to do |format|
+        format.html {
+          flash[:error] = l(:notice_unable_delete_version)
+          redirect_to settings_project_path(@project, :tab => 'versions')
+        }
+        format.api  { head :unprocessable_entity }
+      end
+    end
+  end
+
+  def status_by
+    respond_to do |format|
+      format.html { render :action => 'show' }
+      format.js
+    end
+  end
+
+  private
+
+  def retrieve_selected_tracker_ids(selectable_trackers, default_trackers=nil)
+    if ids = params[:tracker_ids]
+      @selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s }
+    else
+      @selected_tracker_ids = (default_trackers || selectable_trackers).collect {|t| t.id.to_s }
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/ab156aa2c7565b3643e7e22abe62eb929613e670.svn-base
--- a/.svn/pristine/ab/ab156aa2c7565b3643e7e22abe62eb929613e670.svn-base
+++ /dev/null
@@ -1,52 +0,0 @@
-<%= error_messages_for 'query' %>
-
-<div class="box">
-<div class="tabular">
-<p><label for="query_name"><%=l(:field_name)%></label>
-<%= text_field 'query', 'name', :size => 80 %></p>
-
-<% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @project) %>
-<p><label for="query_is_public"><%=l(:field_is_public)%></label>
-<%= check_box 'query', 'is_public',
-      :onchange => (User.current.admin? ? nil : 'if (this.checked) {$("query_is_for_all").checked = false; $("query_is_for_all").disabled = true;} else {$("query_is_for_all").disabled = false;}') %></p>
-<% end %>
-
-<p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label>
-<%= check_box_tag 'query_is_for_all', 1, @query.project.nil?,
-      :disabled => (!@query.new_record? && (@query.project.nil? || (@query.is_public? && !User.current.admin?))) %></p>
-
-<p><label for="query_default_columns"><%=l(:label_default_columns)%></label>
-<%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns',
-      :onclick => 'if (this.checked) {Element.hide("columns")} else {Element.show("columns")}' %></p>
-
-<p><label for="query_group_by"><%= l(:field_group_by) %></label>
-<%= select 'query', 'group_by', @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, :include_blank => true %></p>
-</div>
-
-<fieldset><legend><%= l(:label_filter_plural) %></legend>
-<%= render :partial => 'queries/filters', :locals => {:query => query}%>
-</fieldset>
-
-<fieldset><legend><%= l(:label_sort) %></legend>
-<% 3.times do |i| %>
-<%= i+1 %>: 
-<%= label_tag "query_sort_criteria_attribute_" + i.to_s,
-              l(:description_query_sort_criteria_attribute), :class => "hidden-for-sighted" %>
-<%= select_tag("query[sort_criteria][#{i}][]",
-               options_for_select([[]] + query.available_columns.select(&:sortable?).collect {|column| [column.caption, column.name.to_s]}, @query.sort_criteria_key(i)),
-               :id => "query_sort_criteria_attribute_" + i.to_s)%>
-<%= label_tag "query_sort_criteria_direction_" + i.to_s,
-              l(:description_query_sort_criteria_direction), :class => "hidden-for-sighted" %>
-<%= select_tag("query[sort_criteria][#{i}][]",
-                options_for_select([[], [l(:label_ascending), 'asc'], [l(:label_descending), 'desc']], @query.sort_criteria_order(i)),
-                :id => "query_sort_criteria_direction_" + i.to_s) %>
-<br />
-<% end %>
-</fieldset>
-
-<% content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %>
-<legend><%= l(:field_column_names) %></legend>
-<%= render :partial => 'queries/columns', :locals => {:query => query}%>
-<% end %>
-
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/ab219cc423e55ab4791b83323c88cebbfd8a0fc8.svn-base
--- /dev/null
+++ b/.svn/pristine/ab/ab219cc423e55ab4791b83323c88cebbfd8a0fc8.svn-base
@@ -0,0 +1,116 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/subversion_adapter'
+
+class Repository::Subversion < Repository
+  attr_protected :root_url
+  validates_presence_of :url
+  validates_format_of :url, :with => /\A(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
+
+  def self.scm_adapter_class
+    Redmine::Scm::Adapters::SubversionAdapter
+  end
+
+  def self.scm_name
+    'Subversion'
+  end
+
+  def supports_directory_revisions?
+    true
+  end
+
+  def repo_log_encoding
+    'UTF-8'
+  end
+
+  def latest_changesets(path, rev, limit=10)
+    revisions = scm.revisions(path, rev, nil, :limit => limit)
+    if revisions
+      identifiers = revisions.collect(&:identifier).compact
+      changesets.where(:revision => identifiers).reorder("committed_on DESC").includes(:repository, :user).all
+    else
+      []
+    end
+  end
+
+  # Returns a path relative to the url of the repository
+  def relative_path(path)
+    path.gsub(Regexp.new("^\/?#{Regexp.escape(relative_url)}"), '')
+  end
+
+  def fetch_changesets
+    scm_info = scm.info
+    if scm_info
+      # latest revision found in database
+      db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
+      # latest revision in the repository
+      scm_revision = scm_info.lastrev.identifier.to_i
+      if db_revision < scm_revision
+        logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
+        identifier_from = db_revision + 1
+        while (identifier_from <= scm_revision)
+          # loads changesets by batches of 200
+          identifier_to = [identifier_from + 199, scm_revision].min
+          revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
+          revisions.reverse_each do |revision|
+            transaction do
+              changeset = Changeset.create(:repository   => self,
+                                           :revision     => revision.identifier,
+                                           :committer    => revision.author,
+                                           :committed_on => revision.time,
+                                           :comments     => revision.message)
+
+              revision.paths.each do |change|
+                changeset.create_change(change)
+              end unless changeset.new_record?
+            end
+          end unless revisions.nil?
+          identifier_from = identifier_to + 1
+        end
+      end
+    end
+  end
+
+  protected
+
+  def load_entries_changesets(entries)
+    return unless entries
+
+    entries_with_identifier = entries.select {|entry| entry.lastrev && entry.lastrev.identifier.present?}
+    identifiers = entries_with_identifier.map {|entry| entry.lastrev.identifier}.compact.uniq
+
+    if identifiers.any?
+      changesets_by_identifier = changesets.where(:revision => identifiers).includes(:user, :repository).all.group_by(&:revision)
+      entries_with_identifier.each do |entry|
+        if m = changesets_by_identifier[entry.lastrev.identifier]
+          entry.changeset = m.first
+        end
+      end
+    end
+  end
+
+  private
+
+  # Returns the relative url of the repository
+  # Eg: root_url = file:///var/svn/foo
+  #     url      = file:///var/svn/foo/bar
+  #     => returns /bar
+  def relative_url
+    @relative_url ||= url.gsub(Regexp.new("^#{Regexp.escape(root_url || scm.root_url)}", Regexp::IGNORECASE), '')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/ab3ccb1256c2398242468237819b498aec32eb54.svn-base
--- /dev/null
+++ b/.svn/pristine/ab/ab3ccb1256c2398242468237819b498aec32eb54.svn-base
@@ -0,0 +1,27 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueCustomField < CustomField
+  has_and_belongs_to_many :projects, :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :foreign_key => "custom_field_id"
+  has_and_belongs_to_many :trackers, :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :foreign_key => "custom_field_id"
+  has_many :issues, :through => :issue_custom_values
+
+  def type_name
+    :label_issue_plural
+  end
+end
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/ab489d78995ff1723e6c18bbc50248d8f1734a92.svn-base
--- /dev/null
+++ b/.svn/pristine/ab/ab489d78995ff1723e6c18bbc50248d8f1734a92.svn-base
@@ -0,0 +1,78 @@
+// Automatic project identifier generation
+
+function generateProjectIdentifier(identifier, maxlength) {
+  var diacriticsMap = [
+    {'base':'a', 'letters':/[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g},
+    {'base':'aa','letters':/[\uA733\uA732]/g},
+    {'base':'ae','letters':/[\u00E4\u00E6\u01FD\u01E3\u00C4\u00C6\u01FC\u01E2]/g},
+    {'base':'ao','letters':/[\uA735\uA734]/g},
+    {'base':'au','letters':/[\uA737\uA736]/g},
+    {'base':'av','letters':/[\uA739\uA73B\uA738\uA73A]/g},
+    {'base':'ay','letters':/[\uA73D\uA73C]/g},
+    {'base':'b', 'letters':/[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g},
+    {'base':'c', 'letters':/[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g},
+    {'base':'d', 'letters':/[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g},
+    {'base':'dz','letters':/[\u01F3\u01C6\u01F1\u01C4\u01F2\u01C5]/g},
+    {'base':'e', 'letters':/[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g},
+    {'base':'f', 'letters':/[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g},
+    {'base':'g', 'letters':/[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g},
+    {'base':'h', 'letters':/[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g},
+    {'base':'hv','letters':/[\u0195]/g},
+    {'base':'i', 'letters':/[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g},
+    {'base':'j', 'letters':/[\u006A\u24D9\uFF4A\u0135\u01F0\u0249\u004A\u24BF\uFF2A\u0134\u0248]/g},
+    {'base':'k', 'letters':/[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g},
+    {'base':'l', 'letters':/[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g},
+    {'base':'lj','letters':/[\u01C9\u01C7\u01C8]/g},
+    {'base':'m', 'letters':/[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g},
+    {'base':'n', 'letters':/[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g},
+    {'base':'nj','letters':/[\u01CC\u01CA\u01CB]/g},
+    {'base':'o', 'letters':/[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g},
+    {'base':'oe','letters': /[\u00F6\u0153\u00D6\u0152]/g},
+    {'base':'oi','letters':/[\u01A3\u01A2]/g},
+    {'base':'ou','letters':/[\u0223\u0222]/g},
+    {'base':'oo','letters':/[\uA74F\uA74E]/g},
+    {'base':'p','letters':/[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g},
+    {'base':'q','letters':/[\u0071\u24E0\uFF51\u024B\uA757\uA759\u0051\u24C6\uFF31\uA756\uA758\u024A]/g},
+    {'base':'r','letters':/[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g},
+    {'base':'s','letters':/[\u0073\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g},
+    {'base':'ss','letters':/[\u00DF]/g},
+    {'base':'t','letters':/[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g},
+    {'base':'tz','letters':/[\uA729\uA728]/g},
+    {'base':'u','letters':/[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g},
+    {'base':'ue','letters':/[\u00FC\u00DC]/g},
+    {'base':'v','letters':/[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g},
+    {'base':'vy','letters':/[\uA761\uA760]/g},
+    {'base':'w','letters':/[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g},
+    {'base':'x','letters':/[\u0078\u24E7\uFF58\u1E8B\u1E8D\u0058\u24CD\uFF38\u1E8A\u1E8C]/g},
+    {'base':'y','letters':/[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g},
+    {'base':'z','letters':/[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g}
+  ];
+
+  for(var i=0; i<diacriticsMap.length; i++) {
+    identifier = identifier.replace(diacriticsMap[i].letters, diacriticsMap[i].base);
+  }
+  identifier = identifier.replace(/[^a-z0-9_]+/gi, '-'); // remaining non-alphanumeric => hyphen
+  identifier = identifier.replace(/^[-_\d]*|[-_]*$/g, ''); // remove hyphens/underscores and numbers at beginning and hyphens/underscores at end
+  identifier = identifier.toLowerCase(); // to lower
+  identifier = identifier.substr(0, maxlength); // max characters
+  return identifier;
+}
+
+function autoFillProjectIdentifier() {
+  var locked = ($('#project_identifier').val() != '');
+  var maxlength = parseInt($('#project_identifier').attr('maxlength'));
+
+  $('#project_name').keyup(function(){
+    if(!locked) {
+      $('#project_identifier').val(generateProjectIdentifier($('#project_name').val(), maxlength));
+    }
+  });
+
+  $('#project_identifier').keyup(function(){
+    locked = ($('#project_identifier').val() != '' && $('#project_identifier').val() != generateProjectIdentifier($('#project_name').val(), maxlength));
+  });
+}
+
+$(document).ready(function(){
+  autoFillProjectIdentifier();
+});
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/ab6ce3c805128861a981af4815e85be081e803b8.svn-base
--- /dev/null
+++ b/.svn/pristine/ab/ab6ce3c805128861a981af4815e85be081e803b8.svn-base
@@ -0,0 +1,45 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingWorkflowsTest < ActionController::IntegrationTest
+  def test_workflows
+    assert_routing(
+        { :method => 'get', :path => "/workflows" },
+        { :controller => 'workflows', :action => 'index' }
+      )
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/workflows/edit" },
+          { :controller => 'workflows', :action => 'edit' }
+        )
+    end
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/workflows/permissions" },
+          { :controller => 'workflows', :action => 'permissions' }
+        )
+    end
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/workflows/copy" },
+          { :controller => 'workflows', :action => 'copy' }
+        )
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/aba2cd51a5b23e23b844b712e307db11aefced78.svn-base
--- /dev/null
+++ b/.svn/pristine/ab/aba2cd51a5b23e23b844b712e307db11aefced78.svn-base
@@ -0,0 +1,19 @@
+<h3><%=l(:label_reported_issues)%> (<%= Issue.visible.count(:conditions => { :author_id => User.current.id }) %>)</h3>
+
+<% reported_issues = issuesreportedbyme_items %>
+<%= render :partial => 'issues/list_simple', :locals => { :issues => reported_issues } %>
+<% if reported_issues.length > 0 %>
+<p class="small"><%= link_to l(:label_issue_view_all), :controller => 'issues',
+                                                       :action => 'index',
+                                                       :set_filter => 1,
+                                                       :status_id => '*',
+                                                       :author_id => 'me',
+                                                       :sort => 'updated_on:desc' %></p>
+<% end %>
+
+<% content_for :header_tags do %>
+<%= auto_discovery_link_tag(:atom,
+                            {:controller => 'issues', :action => 'index', :set_filter => 1,
+                             :author_id => 'me', :format => 'atom', :key => User.current.rss_key},
+                            {:title => l(:label_reported_issues)}) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/abd41c366830b89376b6f4eb97ae64f91cc84a62.svn-base
--- a/.svn/pristine/ab/abd41c366830b89376b6f4eb97ae64f91cc84a62.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-ï»¿// ** I18N
-
-// Calendar SR language
-// Author: Dragan Matic, <kkid@panforma.co.yu>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("nedelja",
- "ponedeljak",
- "utorak",
- "sreda",
- "Äetvrtak",
- "petak",
- "subota",
- "nedelja");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("ned",
- "pon",
- "uto",
- "sre",
- "Äet",
- "pet",
- "sub",
- "ned");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("januar",
- "februar",
- "mart",
- "april",
- "maj",
- "jun",
- "jul",
- "avgust",
- "septembar",
- "oktobar",
- "novembar",
- "decembar");
-
-// short month names
-Calendar._SMN = new Array
-("jan",
- "feb",
- "mar",
- "apr",
- "maj",
- "jun",
- "jul",
- "avg",
- "sep",
- "okt",
- "nov",
- "dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "O kalendaru";
-
-Calendar._TT["ABOUT"] =
-"DHTML biraÄ datuma/vremena\n" +
-"(c) dynarch.com 2002-2005 / Autor: Mihai Bazon\n" + // don't translate this this ;-)
-"Za noviju verziju posetite: http://www.dynarch.com/projects/calendar/\n" +
-"Distribuira se pod GNU LGPL.  Pogledajte http://gnu.org/licenses/lgpl.html za detalje." +
-"\n\n" +
-"Izbor datuma:\n" +
-"- Koristite \xab, \xbb tastere za izbor godine\n" +
-"- Koristite " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " tastere za izbor meseca\n" +
-"- ZadrÅ¾ite taster miÅ¡a na bilo kom tasteru iznad za brÅ¾i izbor.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Izbor vremena:\n" +
-"- Kliknite na bilo koji deo vremena za poveÄ‡anje\n" +
-"- ili Shift-klik za umanjenje\n" +
-"- ili kliknite i prevucite za brÅ¾i odabir.";
-
-Calendar._TT["PREV_YEAR"] = "Prethodna godina (zadrÅ¾ati za meni)";
-Calendar._TT["PREV_MONTH"] = "Prethodni mesec (zadrÅ¾ati za meni)";
-Calendar._TT["GO_TODAY"] = "Na danaÅ¡nji dan";
-Calendar._TT["NEXT_MONTH"] = "Naredni mesec (zadrÅ¾ati za meni)";
-Calendar._TT["NEXT_YEAR"] = "Naredna godina (zadrÅ¾ati za meni)";
-Calendar._TT["SEL_DATE"] = "Izbor datuma";
-Calendar._TT["DRAG_TO_MOVE"] = "Prevucite za premeÅ¡tanje";
-Calendar._TT["PART_TODAY"] = " (danas)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "%s kao prvi dan u sedmici";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "6,7";
-
-Calendar._TT["CLOSE"] = "Zatvori";
-Calendar._TT["TODAY"] = "Danas";
-Calendar._TT["TIME_PART"] = "(Shift-) klik ili prevlaÄenje za izmenu vrednosti";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y.";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %e. %b";
-
-Calendar._TT["WK"] = "sed.";
-Calendar._TT["TIME"] = "Vreme:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/abd5fdb1f4d3a8db5bc870f482b9f0ab10c084c0.svn-base
--- /dev/null
+++ b/.svn/pristine/ab/abd5fdb1f4d3a8db5bc870f482b9f0ab10c084c0.svn-base
@@ -0,0 +1,105 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class JournalsController < ApplicationController
+  before_filter :find_journal, :only => [:edit, :diff]
+  before_filter :find_issue, :only => [:new]
+  before_filter :find_optional_project, :only => [:index]
+  before_filter :authorize, :only => [:new, :edit, :diff]
+  accept_rss_auth :index
+  menu_item :issues
+
+  helper :issues
+  helper :custom_fields
+  helper :queries
+  include QueriesHelper
+  helper :sort
+  include SortHelper
+
+  def index
+    retrieve_query
+    sort_init 'id', 'desc'
+    sort_update(@query.sortable_columns)
+
+    if @query.valid?
+      @journals = @query.journals(:order => "#{Journal.table_name}.created_on DESC",
+                                  :limit => 25)
+    end
+    @title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name)
+    render :layout => false, :content_type => 'application/atom+xml'
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def diff
+    @issue = @journal.issue
+    if params[:detail_id].present?
+      @detail = @journal.details.find_by_id(params[:detail_id])
+    else
+      @detail = @journal.details.detect {|d| d.prop_key == 'description'}
+    end
+    (render_404; return false) unless @issue && @detail
+    @diff = Redmine::Helpers::Diff.new(@detail.value, @detail.old_value)
+  end
+
+  def new
+    @journal = Journal.visible.find(params[:journal_id]) if params[:journal_id]
+    if @journal
+      user = @journal.user
+      text = @journal.notes
+    else
+      user = @issue.author
+      text = @issue.description
+    end
+    # Replaces pre blocks with [...]
+    text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]')
+    @content = "#{ll(Setting.default_language, :text_user_wrote, user)}\n> "
+    @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def edit
+    (render_403; return false) unless @journal.editable_by?(User.current)
+    if request.post?
+      @journal.update_attributes(:notes => params[:notes]) if params[:notes]
+      @journal.destroy if @journal.details.empty? && @journal.notes.blank?
+      call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params})
+      respond_to do |format|
+        format.html { redirect_to issue_path(@journal.journalized) }
+        format.js { render :action => 'update' }
+      end
+    else
+      respond_to do |format|
+        format.html {
+          # TODO: implement non-JS journal update
+          render :nothing => true
+        }
+        format.js
+      end
+    end
+  end
+
+  private
+
+  def find_journal
+    @journal = Journal.visible.find(params[:id])
+    @project = @journal.journalized.project
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ab/abe7e77a0d76e76319267bad195691117c061ef5.svn-base
--- a/.svn/pristine/ab/abe7e77a0d76e76319267bad195691117c061ef5.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("DuminicÄƒ",
- "Luni",
- "MarÈ›i",
- "Miercuri",
- "Joi",
- "Vineri",
- "SÃ¢mbÄƒtÄƒ",
- "DuminicÄƒ");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Dum",
- "Lun",
- "Mar",
- "Mie",
- "Joi",
- "Vin",
- "SÃ¢m",
- "Dum");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Ianuarie",
- "Februarie",
- "Martie",
- "Aprilie",
- "Mai",
- "Iunie",
- "Iulie",
- "August",
- "Septembrie",
- "Octombrie",
- "Noiembrie",
- "Decembrie");
-
-// short month names
-Calendar._SMN = new Array
-("Ian",
- "Feb",
- "Mar",
- "Apr",
- "Mai",
- "Iun",
- "Iul",
- "Aug",
- "Sep",
- "Oct",
- "Noi",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Despre calendar";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Selectare data:\n" +
-"- Folositi butoanele \xab, \xbb pentru a selecta anul\n" +
-"- Folositi butoanele " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pentru a selecta luna\n" +
-"- Lasati apasat butonul pentru o selectie mai rapida.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Selectare timp:\n" +
-"- Click pe campul de timp pentru a majora timpul\n" +
-"- sau Shift-Click pentru a micsora\n" +
-"- sau click si drag pentru manipulare rapida.";
-
-Calendar._TT["PREV_YEAR"] = "Anul precedent (apasati pentru meniu)";
-Calendar._TT["PREV_MONTH"] = "Luna precedenta (apasati pentru meniu)";
-Calendar._TT["GO_TODAY"] = "Astazi";
-Calendar._TT["NEXT_MONTH"] = "Luna viitoare (apasati pentru meniu)";
-Calendar._TT["NEXT_YEAR"] = "Anul viitor (apasati pentru meniu)";
-Calendar._TT["SEL_DATE"] = "Selecteaza data";
-Calendar._TT["DRAG_TO_MOVE"] = "Drag pentru a muta";
-Calendar._TT["PART_TODAY"] = " (azi)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "VizualizeazÄƒ %s prima";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "ÃŽnchide";
-Calendar._TT["TODAY"] = "Azi";
-Calendar._TT["TIME_PART"] = "(Shift-)Click sau drag pentru a schimba valoarea";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%A-%l-%z";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "sÄƒpt";
-Calendar._TT["TIME"] = "Ora:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ac/ac29f2ab2461516f86b651fe368aa1f1f715c245.svn-base
--- a/.svn/pristine/ac/ac29f2ab2461516f86b651fe368aa1f1f715c245.svn-base
+++ /dev/null
@@ -1,114 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class SearchController < ApplicationController
-  before_filter :find_optional_project
-
-  helper :messages
-  include MessagesHelper
-
-  def index
-    @question = params[:q] || ""
-    @question.strip!
-    @all_words = params[:all_words] ? params[:all_words].present? : true
-    @titles_only = params[:titles_only] ? params[:titles_only].present? : false
-
-    projects_to_search =
-      case params[:scope]
-      when 'all'
-        nil
-      when 'my_projects'
-        User.current.memberships.collect(&:project)
-      when 'subprojects'
-        @project ? (@project.self_and_descendants.active) : nil
-      else
-        @project
-      end
-
-    offset = nil
-    begin; offset = params[:offset].to_time if params[:offset]; rescue; end
-
-    # quick jump to an issue
-    if @question.match(/^#?(\d+)$/) && Issue.visible.find_by_id($1.to_i)
-      redirect_to :controller => "issues", :action => "show", :id => $1
-      return
-    end
-
-    @object_types = Redmine::Search.available_search_types.dup
-    if projects_to_search.is_a? Project
-      # don't search projects
-      @object_types.delete('projects')
-      # only show what the user is allowed to view
-      @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
-    end
-
-    @scope = @object_types.select {|t| params[t]}
-    @scope = @object_types if @scope.empty?
-
-    # extract tokens from the question
-    # eg. hello "bye bye" => ["hello", "bye bye"]
-    @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
-    # tokens must be at least 2 characters long
-    @tokens = @tokens.uniq.select {|w| w.length > 1 }
-
-    if !@tokens.empty?
-      # no more than 5 tokens to search for
-      @tokens.slice! 5..-1 if @tokens.size > 5
-
-      @results = []
-      @results_by_type = Hash.new {|h,k| h[k] = 0}
-
-      limit = 10
-      @scope.each do |s|
-        r, c = s.singularize.camelcase.constantize.search(@tokens, projects_to_search,
-          :all_words => @all_words,
-          :titles_only => @titles_only,
-          :limit => (limit+1),
-          :offset => offset,
-          :before => params[:previous].nil?)
-        @results += r
-        @results_by_type[s] += c
-      end
-      @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
-      if params[:previous].nil?
-        @pagination_previous_date = @results[0].event_datetime if offset && @results[0]
-        if @results.size > limit
-          @pagination_next_date = @results[limit-1].event_datetime
-          @results = @results[0, limit]
-        end
-      else
-        @pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
-        if @results.size > limit
-          @pagination_previous_date = @results[-(limit)].event_datetime
-          @results = @results[-(limit), limit]
-        end
-      end
-    else
-      @question = ""
-    end
-    render :layout => false if request.xhr?
-  end
-
-private
-  def find_optional_project
-    return true unless params[:id]
-    @project = Project.find(params[:id])
-    check_project_privacy
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ac/ac319deb1c64f0f2b18947928e8e2b43b56a5313.svn-base
--- a/.svn/pristine/ac/ac319deb1c64f0f2b18947928e8e2b43b56a5313.svn-base
+++ /dev/null
@@ -1,278 +0,0 @@
-# encoding: utf-8
-# Encoding.default_internal = 'UTF-8'
-
-# = CodeRay Library
-#
-# CodeRay is a Ruby library for syntax highlighting.
-#
-# I try to make CodeRay easy to use and intuitive, but at the same time fully
-# featured, complete, fast and efficient.
-# 
-# See README.
-# 
-# It consists mainly of
-# * the main engine: CodeRay (Scanners::Scanner, Tokens, Encoders::Encoder)
-# * the plugin system: PluginHost, Plugin
-# * the scanners in CodeRay::Scanners
-# * the encoders in CodeRay::Encoders
-# * the styles in CodeRay::Styles
-# 
-# Here's a fancy graphic to light up this gray docu:
-# 
-# http://cycnus.de/raindark/coderay/scheme.png
-# 
-# == Documentation
-#
-# See CodeRay, Encoders, Scanners, Tokens.
-#
-# == Usage
-#
-# Remember you need RubyGems to use CodeRay, unless you have it in your load
-# path. Run Ruby with -rubygems option if required.
-#
-# === Highlight Ruby code in a string as html
-# 
-#   require 'coderay'
-#   print CodeRay.scan('puts "Hello, world!"', :ruby).html
-#
-#   # prints something like this:
-#   puts <span class="s">&quot;Hello, world!&quot;</span>
-# 
-# 
-# === Highlight C code from a file in a html div
-# 
-#   require 'coderay'
-#   print CodeRay.scan(File.read('ruby.h'), :c).div
-#   print CodeRay.scan_file('ruby.h').html.div
-# 
-# You can include this div in your page. The used CSS styles can be printed with
-# 
-#   % coderay_stylesheet
-# 
-# === Highlight without typing too much
-# 
-# If you are one of the hasty (or lazy, or extremely curious) people, just run this file:
-# 
-#   % ruby -rubygems /path/to/coderay/coderay.rb > example.html
-# 
-# and look at the file it created in your browser.
-# 
-# = CodeRay Module
-#
-# The CodeRay module provides convenience methods for the engine.
-#
-# * The +lang+ and +format+ arguments select Scanner and Encoder to use. These are
-#   simply lower-case symbols, like <tt>:python</tt> or <tt>:html</tt>.
-# * All methods take an optional hash as last parameter, +options+, that is send to
-#   the Encoder / Scanner.
-# * Input and language are always sorted in this order: +code+, +lang+.
-#   (This is in alphabetical order, if you need a mnemonic ;)
-# 
-# You should be able to highlight everything you want just using these methods;
-# so there is no need to dive into CodeRay's deep class hierarchy.
-#
-# The examples in the demo directory demonstrate common cases using this interface.
-#  
-# = Basic Access Ways
-#
-# Read this to get a general view what CodeRay provides.
-# 
-# == Scanning
-#  
-#  Scanning means analysing an input string, splitting it up into Tokens.
-#  Each Token knows about what type it is: string, comment, class name, etc.
-#
-#  Each +lang+ (language) has its own Scanner; for example, <tt>:ruby</tt> code is
-#  handled by CodeRay::Scanners::Ruby.
-# 
-# CodeRay.scan:: Scan a string in a given language into Tokens.
-#                This is the most common method to use.
-# CodeRay.scan_file:: Scan a file and guess the language using FileType.
-# 
-# The Tokens object you get from these methods can encode itself; see Tokens.
-# 
-# == Encoding
-#
-# Encoding means compiling Tokens into an output. This can be colored HTML or
-# LaTeX, a textual statistic or just the number of non-whitespace tokens.
-# 
-# Each Encoder provides output in a specific +format+, so you select Encoders via
-# formats like <tt>:html</tt> or <tt>:statistic</tt>.
-# 
-# CodeRay.encode:: Scan and encode a string in a given language.
-# CodeRay.encode_tokens:: Encode the given tokens.
-# CodeRay.encode_file:: Scan a file, guess the language using FileType and encode it.
-#
-# == All-in-One Encoding
-#
-# CodeRay.encode:: Highlight a string with a given input and output format.
-#
-# == Instanciating
-#
-# You can use an Encoder instance to highlight multiple inputs. This way, the setup
-# for this Encoder must only be done once.
-#
-# CodeRay.encoder:: Create an Encoder instance with format and options.
-# CodeRay.scanner:: Create an Scanner instance for lang, with '' as default code.
-#
-# To make use of CodeRay.scanner, use CodeRay::Scanner::code=.
-#
-# The scanning methods provide more flexibility; we recommend to use these.
-# 
-# == Reusing Scanners and Encoders
-# 
-# If you want to re-use scanners and encoders (because that is faster), see
-# CodeRay::Duo for the most convenient (and recommended) interface.
-module CodeRay
-  
-  $CODERAY_DEBUG ||= false
-  
-  require 'coderay/version'
-  
-  # helpers
-  autoload :FileType, 'coderay/helpers/file_type'
-  
-  # Tokens
-  autoload :Tokens, 'coderay/tokens'
-  autoload :TokensProxy, 'coderay/tokens_proxy'
-  autoload :TokenKinds, 'coderay/token_kinds'
-  
-  # Plugin system
-  autoload :PluginHost, 'coderay/helpers/plugin'
-  autoload :Plugin, 'coderay/helpers/plugin'
-  
-  # Plugins
-  autoload :Scanners, 'coderay/scanner'
-  autoload :Encoders, 'coderay/encoder'
-  autoload :Styles, 'coderay/style'
-  
-  # Convenience access and reusable Encoder/Scanner pair
-  autoload :Duo, 'coderay/duo'
-  
-  class << self
-    
-    # Scans the given +code+ (a String) with the Scanner for +lang+.
-    #
-    # This is a simple way to use CodeRay. Example:
-    #  require 'coderay'
-    #  page = CodeRay.scan("puts 'Hello, world!'", :ruby).html
-    #
-    # See also demo/demo_simple.
-    def scan code, lang, options = {}, &block
-      # FIXME: return a proxy for direct-stream encoding
-      TokensProxy.new code, lang, options, block
-    end
-    
-    # Scans +filename+ (a path to a code file) with the Scanner for +lang+.
-    #
-    # If +lang+ is :auto or omitted, the CodeRay::FileType module is used to
-    # determine it. If it cannot find out what type it is, it uses
-    # CodeRay::Scanners::Text.
-    #
-    # Calls CodeRay.scan.
-    #
-    # Example:
-    #  require 'coderay'
-    #  page = CodeRay.scan_file('some_c_code.c').html
-    def scan_file filename, lang = :auto, options = {}, &block
-      lang = FileType.fetch filename, :text, true if lang == :auto
-      code = File.read filename
-      scan code, lang, options, &block
-    end
-    
-    # Encode a string.
-    #
-    # This scans +code+ with the the Scanner for +lang+ and then
-    # encodes it with the Encoder for +format+.
-    # +options+ will be passed to the Encoder.
-    #
-    # See CodeRay::Encoder.encode.
-    def encode code, lang, format, options = {}
-      encoder(format, options).encode code, lang, options
-    end
-    
-    # Encode pre-scanned Tokens.
-    # Use this together with CodeRay.scan:
-    #
-    #  require 'coderay'
-    #  
-    #  # Highlight a short Ruby code example in a HTML span
-    #  tokens = CodeRay.scan '1 + 2', :ruby
-    #  puts CodeRay.encode_tokens(tokens, :span)
-    #
-    def encode_tokens tokens, format, options = {}
-      encoder(format, options).encode_tokens tokens, options
-    end
-    
-    # Encodes +filename+ (a path to a code file) with the Scanner for +lang+.
-    #
-    # See CodeRay.scan_file.
-    # Notice that the second argument is the output +format+, not the input language.
-    #
-    # Example:
-    #  require 'coderay'
-    #  page = CodeRay.encode_file 'some_c_code.c', :html
-    def encode_file filename, format, options = {}
-      tokens = scan_file filename, :auto, get_scanner_options(options)
-      encode_tokens tokens, format, options
-    end
-    
-    # Highlight a string into a HTML <div>.
-    #
-    # CSS styles use classes, so you have to include a stylesheet
-    # in your output.
-    #
-    # See encode.
-    def highlight code, lang, options = { :css => :class }, format = :div
-      encode code, lang, format, options
-    end
-    
-    # Highlight a file into a HTML <div>.
-    #
-    # CSS styles use classes, so you have to include a stylesheet
-    # in your output.
-    #
-    # See encode.
-    def highlight_file filename, options = { :css => :class }, format = :div
-      encode_file filename, format, options
-    end
-    
-    # Finds the Encoder class for +format+ and creates an instance, passing
-    # +options+ to it.
-    #
-    # Example:
-    #  require 'coderay'
-    #  
-    #  stats = CodeRay.encoder(:statistic)
-    #  stats.encode("puts 17 + 4\n", :ruby)
-    #  
-    #  puts '%d out of %d tokens have the kind :integer.' % [
-    #    stats.type_stats[:integer].count,
-    #    stats.real_token_count
-    #  ]
-    #  #-> 2 out of 4 tokens have the kind :integer.
-    def encoder format, options = {}
-      Encoders[format].new options
-    end
-    
-    # Finds the Scanner class for +lang+ and creates an instance, passing
-    # +options+ to it.
-    #
-    # See Scanner.new.
-    def scanner lang, options = {}, &block
-      Scanners[lang].new '', options, &block
-    end
-    
-    # Extract the options for the scanner from the +options+ hash.
-    #
-    # Returns an empty Hash if <tt>:scanner_options</tt> is not set.
-    #
-    # This is used if a method like CodeRay.encode has to provide options
-    # for Encoder _and_ scanner.
-    def get_scanner_options options
-      options.fetch :scanner_options, {}
-    end
-    
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ac/ac3d46576ac0d49645b8babc84dcdd0e6f305a12.svn-base
--- /dev/null
+++ b/.svn/pristine/ac/ac3d46576ac0d49645b8babc84dcdd0e6f305a12.svn-base
@@ -0,0 +1,145 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RoleTest < ActiveSupport::TestCase
+  fixtures :roles, :workflows, :trackers
+
+  def test_sorted_scope
+    assert_equal Role.all.sort, Role.sorted.all
+  end
+
+  def test_givable_scope
+    assert_equal Role.all.reject(&:builtin?).sort, Role.givable.all
+  end
+
+  def test_builtin_scope
+    assert_equal Role.all.select(&:builtin?).sort, Role.builtin(true).all.sort
+    assert_equal Role.all.reject(&:builtin?).sort, Role.builtin(false).all.sort
+  end
+
+  def test_copy_from
+    role = Role.find(1)
+    copy = Role.new.copy_from(role)
+
+    assert_nil copy.id
+    assert_equal '', copy.name
+    assert_equal role.permissions, copy.permissions
+
+    copy.name = 'Copy'
+    assert copy.save
+  end
+
+  def test_copy_workflows
+    source = Role.find(1)
+    assert_equal 90, source.workflow_rules.size
+
+    target = Role.new(:name => 'Target')
+    assert target.save
+    target.workflow_rules.copy(source)
+    target.reload
+    assert_equal 90, target.workflow_rules.size
+  end
+
+  def test_permissions_should_be_unserialized_with_its_coder
+    Role::PermissionsAttributeCoder.expects(:load).once
+    Role.find(1).permissions
+  end
+
+  def test_add_permission
+    role = Role.find(1)
+    size = role.permissions.size
+    role.add_permission!("apermission", "anotherpermission")
+    role.reload
+    assert role.permissions.include?(:anotherpermission)
+    assert_equal size + 2, role.permissions.size
+  end
+
+  def test_remove_permission
+    role = Role.find(1)
+    size = role.permissions.size
+    perm = role.permissions[0..1]
+    role.remove_permission!(*perm)
+    role.reload
+    assert ! role.permissions.include?(perm[0])
+    assert_equal size - 2, role.permissions.size
+  end
+
+  def test_name
+    I18n.locale = 'fr'
+    assert_equal 'Manager', Role.find(1).name
+    assert_equal 'Anonyme', Role.anonymous.name
+    assert_equal 'Non membre', Role.non_member.name
+  end
+
+  def test_find_all_givable
+    assert_equal Role.all.reject(&:builtin?).sort, Role.find_all_givable
+  end
+
+  context "#anonymous" do
+    should "return the anonymous role" do
+      role = Role.anonymous
+      assert role.builtin?
+      assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
+    end
+
+    context "with a missing anonymous role" do
+      setup do
+        Role.delete_all("builtin = #{Role::BUILTIN_ANONYMOUS}")
+      end
+
+      should "create a new anonymous role" do
+        assert_difference('Role.count') do
+          Role.anonymous
+        end
+      end
+
+      should "return the anonymous role" do
+        role = Role.anonymous
+        assert role.builtin?
+        assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
+      end
+    end
+  end
+
+  context "#non_member" do
+    should "return the non-member role" do
+      role = Role.non_member
+      assert role.builtin?
+      assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
+    end
+
+    context "with a missing non-member role" do
+      setup do
+        Role.delete_all("builtin = #{Role::BUILTIN_NON_MEMBER}")
+      end
+
+      should "create a new non-member role" do
+        assert_difference('Role.count') do
+          Role.non_member
+        end
+      end
+
+      should "return the non-member role" do
+        role = Role.non_member
+        assert role.builtin?
+        assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ac/ac72e9b13ee621269bf022e0045e469b2cf12b1b.svn-base
--- a/.svn/pristine/ac/ac72e9b13ee621269bf022e0045e469b2cf12b1b.svn-base
+++ /dev/null
@@ -1,107 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class IssueRelationTest < ActiveSupport::TestCase
-  fixtures :issue_relations, :issues
-
-  def test_create
-    from = Issue.find(1)
-    to = Issue.find(2)
-
-    relation = IssueRelation.new :issue_from => from, :issue_to => to,
-                                 :relation_type => IssueRelation::TYPE_PRECEDES
-    assert relation.save
-    relation.reload
-    assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type
-    assert_equal from, relation.issue_from
-    assert_equal to, relation.issue_to
-  end
-
-  def test_create_minimum
-    relation = IssueRelation.new :issue_from => Issue.find(1), :issue_to => Issue.find(2)
-    assert relation.save
-    assert_equal IssueRelation::TYPE_RELATES, relation.relation_type
-  end
-
-  def test_follows_relation_should_be_reversed
-    from = Issue.find(1)
-    to = Issue.find(2)
-
-    relation = IssueRelation.new :issue_from => from, :issue_to => to,
-                                 :relation_type => IssueRelation::TYPE_FOLLOWS
-    assert relation.save
-    relation.reload
-    assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type
-    assert_equal to, relation.issue_from
-    assert_equal from, relation.issue_to
-  end
-
-  def test_follows_relation_should_not_be_reversed_if_validation_fails
-    from = Issue.find(1)
-    to = Issue.find(2)
-
-    relation = IssueRelation.new :issue_from => from, :issue_to => to,
-                                 :relation_type => IssueRelation::TYPE_FOLLOWS,
-                                 :delay => 'xx'
-    assert !relation.save
-    assert_equal IssueRelation::TYPE_FOLLOWS, relation.relation_type
-    assert_equal from, relation.issue_from
-    assert_equal to, relation.issue_to
-  end
-
-  def test_relation_type_for
-    from = Issue.find(1)
-    to = Issue.find(2)
-
-    relation = IssueRelation.new :issue_from => from, :issue_to => to,
-                                 :relation_type => IssueRelation::TYPE_PRECEDES
-    assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type_for(from)
-    assert_equal IssueRelation::TYPE_FOLLOWS, relation.relation_type_for(to)
-  end
-
-  def test_set_issue_to_dates_without_issue_to
-    r = IssueRelation.new(:issue_from => Issue.new(:start_date => Date.today),
-                          :relation_type => IssueRelation::TYPE_PRECEDES,
-                          :delay => 1)
-    assert_nil r.set_issue_to_dates
-  end
-
-  def test_set_issue_to_dates_without_issues
-    r = IssueRelation.new(:relation_type => IssueRelation::TYPE_PRECEDES, :delay => 1)
-    assert_nil r.set_issue_to_dates
-  end
-
-  def test_validates_circular_dependency
-    IssueRelation.delete_all
-    assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => IssueRelation::TYPE_PRECEDES)
-    assert IssueRelation.create!(:issue_from => Issue.find(2), :issue_to => Issue.find(3), :relation_type => IssueRelation::TYPE_PRECEDES)
-    r = IssueRelation.new(:issue_from => Issue.find(3), :issue_to => Issue.find(1), :relation_type => IssueRelation::TYPE_PRECEDES)
-    assert !r.save
-    assert_not_nil r.errors[:base]
-  end
-
-  def test_validates_circular_dependency_on_reverse_relations
-    IssueRelation.delete_all
-    assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(3), :relation_type => IssueRelation::TYPE_BLOCKS)
-    assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => IssueRelation::TYPE_BLOCKED)
-    r = IssueRelation.new(:issue_from => Issue.find(2), :issue_to => Issue.find(1), :relation_type => IssueRelation::TYPE_BLOCKED)
-    assert !r.save
-    assert_not_nil r.errors[:base]
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ac/accbe6c3f56b6ae9aeb14045d52050541c5be4d0.svn-base
--- a/.svn/pristine/ac/accbe6c3f56b6ae9aeb14045d52050541c5be4d0.svn-base
+++ /dev/null
@@ -1,174 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # Scanner for Java.
-  class Java < Scanner
-    
-    register_for :java
-    
-    autoload :BuiltinTypes, 'coderay/scanners/java/builtin_types'
-    
-    # http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
-    KEYWORDS = %w[
-      assert break case catch continue default do else
-      finally for if instanceof import new package
-      return switch throw try typeof while
-      debugger export
-    ]  # :nodoc:
-    RESERVED = %w[ const goto ]  # :nodoc:
-    CONSTANTS = %w[ false null true ]  # :nodoc:
-    MAGIC_VARIABLES = %w[ this super ]  # :nodoc:
-    TYPES = %w[
-      boolean byte char class double enum float int interface long
-      short void
-    ] << '[]'  # :nodoc: because int[] should be highlighted as a type
-    DIRECTIVES = %w[
-      abstract extends final implements native private protected public
-      static strictfp synchronized throws transient volatile
-    ]  # :nodoc:
-    
-    IDENT_KIND = WordList.new(:ident).
-      add(KEYWORDS, :keyword).
-      add(RESERVED, :reserved).
-      add(CONSTANTS, :predefined_constant).
-      add(MAGIC_VARIABLES, :local_variable).
-      add(TYPES, :type).
-      add(BuiltinTypes::List, :predefined_type).
-      add(BuiltinTypes::List.select { |builtin| builtin[/(Error|Exception)$/] }, :exception).
-      add(DIRECTIVES, :directive)  # :nodoc:
-
-    ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x  # :nodoc:
-    UNICODE_ESCAPE =  / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x  # :nodoc:
-    STRING_CONTENT_PATTERN = {
-      "'" => /[^\\']+/,
-      '"' => /[^\\"]+/,
-      '/' => /[^\\\/]+/,
-    }  # :nodoc:
-    IDENT = /[a-zA-Z_][A-Za-z_0-9]*/  # :nodoc:
-    
-  protected
-    
-    def scan_tokens encoder, options
-
-      state = :initial
-      string_delimiter = nil
-      package_name_expected = false
-      class_name_follows = false
-      last_token_dot = false
-
-      until eos?
-
-        case state
-
-        when :initial
-
-          if match = scan(/ \s+ | \\\n /x)
-            encoder.text_token match, :space
-            next
-          
-          elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
-            encoder.text_token match, :comment
-            next
-          
-          elsif package_name_expected && match = scan(/ #{IDENT} (?: \. #{IDENT} )* /ox)
-            encoder.text_token match, package_name_expected
-          
-          elsif match = scan(/ #{IDENT} | \[\] /ox)
-            kind = IDENT_KIND[match]
-            if last_token_dot
-              kind = :ident
-            elsif class_name_follows
-              kind = :class
-              class_name_follows = false
-            else
-              case match
-              when 'import'
-                package_name_expected = :include
-              when 'package'
-                package_name_expected = :namespace
-              when 'class', 'interface'
-                class_name_follows = true
-              end
-            end
-            encoder.text_token match, kind
-          
-          elsif match = scan(/ \.(?!\d) | [,?:()\[\]}] | -- | \+\+ | && | \|\| | \*\*=? | [-+*\/%^~&|<>=!]=? | <<<?=? | >>>?=? /x)
-            encoder.text_token match, :operator
-          
-          elsif match = scan(/;/)
-            package_name_expected = false
-            encoder.text_token match, :operator
-          
-          elsif match = scan(/\{/)
-            class_name_follows = false
-            encoder.text_token match, :operator
-          
-          elsif check(/[\d.]/)
-            if match = scan(/0[xX][0-9A-Fa-f]+/)
-              encoder.text_token match, :hex
-            elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/)
-              encoder.text_token match, :octal
-            elsif match = scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/)
-              encoder.text_token match, :float
-            elsif match = scan(/\d+[lL]?/)
-              encoder.text_token match, :integer
-            end
-
-          elsif match = scan(/["']/)
-            state = :string
-            encoder.begin_group state
-            string_delimiter = match
-            encoder.text_token match, :delimiter
-
-          elsif match = scan(/ @ #{IDENT} /ox)
-            encoder.text_token match, :annotation
-
-          else
-            encoder.text_token getch, :error
-
-          end
-
-        when :string
-          if match = scan(STRING_CONTENT_PATTERN[string_delimiter])
-            encoder.text_token match, :content
-          elsif match = scan(/["'\/]/)
-            encoder.text_token match, :delimiter
-            encoder.end_group state
-            state = :initial
-            string_delimiter = nil
-          elsif state == :string && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
-            if string_delimiter == "'" && !(match == "\\\\" || match == "\\'")
-              encoder.text_token match, :content
-            else
-              encoder.text_token match, :char
-            end
-          elsif match = scan(/\\./m)
-            encoder.text_token match, :content
-          elsif match = scan(/ \\ | $ /x)
-            encoder.end_group state
-            state = :initial
-            encoder.text_token match, :error
-          else
-            raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
-          end
-
-        else
-          raise_inspect 'Unknown state', encoder
-
-        end
-        
-        last_token_dot = match == '.'
-        
-      end
-
-      if state == :string
-        encoder.end_group state
-      end
-
-      encoder
-    end
-
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ac/acfa71d8220cd97a490ff32c8179207841225f4e.svn-base
--- a/.svn/pristine/ac/acfa71d8220cd97a490ff32c8179207841225f4e.svn-base
+++ /dev/null
@@ -1,258 +0,0 @@
-ActionController::Routing::Routes.draw do |map|
-  # Add your own custom routes here.
-  # The priority is based upon order of creation: first created -> highest priority.
-
-  # Here's a sample route:
-  # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
-  # Keep in mind you can assign values other than :controller and :action
-
-  map.home '', :controller => 'welcome'
-
-  map.signin 'login', :controller => 'account', :action => 'login'
-  map.signout 'logout', :controller => 'account', :action => 'logout'
-
-  map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
-  map.connect 'help/:ctrl/:page', :controller => 'help'
-
-  map.with_options :controller => 'time_entry_reports', :action => 'report',:conditions => {:method => :get} do |time_report|
-    time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report'
-    time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report.:format'
-    time_report.connect 'projects/:project_id/time_entries/report'
-    time_report.connect 'projects/:project_id/time_entries/report.:format'
-    time_report.connect 'time_entries/report'
-    time_report.connect 'time_entries/report.:format'
-  end
-
-  map.bulk_edit_time_entry 'time_entries/bulk_edit',
-                   :controller => 'timelog', :action => 'bulk_edit', :conditions => { :method => :get }
-  map.bulk_update_time_entry 'time_entries/bulk_edit',
-                   :controller => 'timelog', :action => 'bulk_update', :conditions => { :method => :post }
-  map.time_entries_context_menu '/time_entries/context_menu',
-                   :controller => 'context_menus', :action => 'time_entries'
-  # TODO: wasteful since this is also nested under issues, projects, and projects/issues
-  map.resources :time_entries, :controller => 'timelog'
-
-  map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
-  map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
-  map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
-
-  map.with_options :controller => 'messages' do |messages_routes|
-    messages_routes.with_options :conditions => {:method => :get} do |messages_views|
-      messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
-      messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
-      messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
-    end
-    messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
-      messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
-      messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
-      messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
-    end
-  end
-
-  map.with_options :controller => 'boards' do |board_routes|
-    board_routes.with_options :conditions => {:method => :get} do |board_views|
-      board_views.connect 'projects/:project_id/boards', :action => 'index'
-      board_views.connect 'projects/:project_id/boards/new', :action => 'new'
-      board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
-      board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
-      board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
-    end
-    board_routes.with_options :conditions => {:method => :post} do |board_actions|
-      board_actions.connect 'projects/:project_id/boards', :action => 'new'
-      board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
-    end
-  end
-
-  map.with_options :controller => 'documents' do |document_routes|
-    document_routes.with_options :conditions => {:method => :get} do |document_views|
-      document_views.connect 'projects/:project_id/documents', :action => 'index'
-      document_views.connect 'projects/:project_id/documents/new', :action => 'new'
-      document_views.connect 'documents/:id', :action => 'show'
-      document_views.connect 'documents/:id/edit', :action => 'edit'
-    end
-    document_routes.with_options :conditions => {:method => :post} do |document_actions|
-      document_actions.connect 'projects/:project_id/documents', :action => 'new'
-      document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
-    end
-  end
-
-  map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
-  map.resources :queries, :except => [:show]
-
-  # Misc issue routes. TODO: move into resources
-  map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues', :conditions => { :method => :get }
-  map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
-  map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
-  map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
-  map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
-  map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
-  map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
-  map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
-
-  map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
-    gantts_routes.connect '/projects/:project_id/issues/gantt'
-    gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
-    gantts_routes.connect '/issues/gantt.:format'
-  end
-
-  map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
-    calendars_routes.connect '/projects/:project_id/issues/calendar'
-    calendars_routes.connect '/issues/calendar'
-  end
-
-  map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
-    reports.connect 'projects/:id/issues/report', :action => 'issue_report'
-    reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
-  end
-
-  # Following two routes conflict with the resources because #index allows POST
-  map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
-  map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
-
-  map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
-    issues.resources :time_entries, :controller => 'timelog'
-    issues.resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
-  end
-
-  map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
-    issues.resources :time_entries, :controller => 'timelog'
-  end
-
-  map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
-
-  map.with_options :controller => 'users' do |users|
-    users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
-
-    users.with_options :conditions => {:method => :post} do |user_actions|
-      user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
-      user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
-      user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
-    end
-  end
-
-  map.resources :users, :member => {
-    :edit_membership => :post,
-    :destroy_membership => :post
-  }
-
-  # For nice "roadmap" in the url for the index action
-  map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
-
-  map.all_news 'news', :controller => 'news', :action => 'index'
-  map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
-  map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
-  map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
-  map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
-
-  map.resources :projects, :member => {
-    :copy => [:get, :post],
-    :settings => :get,
-    :modules => :post,
-    :archive => :post,
-    :unarchive => :post
-  } do |project|
-    project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
-    project.resources :files, :only => [:index, :new, :create]
-    project.resources :versions, :shallow => true, :collection => {:close_completed => :put}, :member => {:status_by => :post}
-    project.resources :news, :shallow => true
-    project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
-    project.resources :queries, :only => [:new, :create]
-    project.resources :issue_categories, :shallow => true
-
-    project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
-    project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
-    project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
-    project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
-    project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
-    project.resources :wiki, :except => [:new, :create], :member => {
-      :rename => [:get, :post],
-      :history => :get,
-      :preview => :any,
-      :protect => :post,
-      :add_attachment => :post
-    }, :collection => {
-      :export => :get,
-      :date_index => :get
-    }
-
-  end
-
-  # Destroy uses a get request to prompt the user before the actual DELETE request
-  map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
-
-  # TODO: port to be part of the resources route(s)
-  map.with_options :controller => 'projects' do |project_mapper|
-    project_mapper.with_options :conditions => {:method => :get} do |project_views|
-      project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
-      project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
-    end
-  end
-
-  map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
-    activity.connect 'projects/:id/activity'
-    activity.connect 'projects/:id/activity.:format'
-    activity.connect 'activity', :id => nil
-    activity.connect 'activity.:format', :id => nil
-  end
-
-  map.with_options :controller => 'repositories' do |repositories|
-    repositories.with_options :conditions => {:method => :get} do |repository_views|
-      repository_views.connect 'projects/:id/repository', :action => 'show'
-      repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
-      repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
-      repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
-      repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
-      repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
-      repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
-      repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
-      repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
-      repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
-      repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
-      # TODO: why the following route is required?
-      repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
-      repository_views.connect 'projects/:id/repository/:action/*path'
-    end
-
-    repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
-  end
-  
-  map.resources :attachments, :only => [:show, :destroy]
-  # additional routes for having the file name at the end of url
-  map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
-  map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
-
-  map.resources :groups, :member => {:autocomplete_for_user => :get}
-  map.group_users 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :conditions => {:method => :post}
-  map.group_user  'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :conditions => {:method => :delete}
-
-  map.resources :trackers, :except => :show
-  map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
-
-  #left old routes at the bottom for backwards compat
-  map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
-  map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
-  map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
-  map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
-  map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
-  map.connect 'projects/:project_id/news/:action', :controller => 'news'
-  map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
-  map.with_options :controller => 'repositories' do |omap|
-    omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
-    omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
-    omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
-    omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
-    omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
-    omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
-  end
-
-  map.with_options :controller => 'sys' do |sys|
-    sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
-    sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
-  end
-
-  # Install the default route as the lowest priority.
-  map.connect ':controller/:action/:id'
-  map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
-  # Used for OpenID
-  map.root :controller => 'account', :action => 'login'
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ad/ad9161bbe4944ca1db8ea296d48b7287d41e3113.svn-base
--- /dev/null
+++ b/.svn/pristine/ad/ad9161bbe4944ca1db8ea296d48b7287d41e3113.svn-base
@@ -0,0 +1,134 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Acts
+    module Searchable
+      def self.included(base)
+        base.extend ClassMethods
+      end
+
+      module ClassMethods
+        # Options:
+        # * :columns - a column or an array of columns to search
+        # * :project_key - project foreign key (default to project_id)
+        # * :date_column - name of the datetime column (default to created_on)
+        # * :sort_order - name of the column used to sort results (default to :date_column or created_on)
+        # * :permission - permission required to search the model (default to :view_"objects")
+        def acts_as_searchable(options = {})
+          return if self.included_modules.include?(Redmine::Acts::Searchable::InstanceMethods)
+
+          cattr_accessor :searchable_options
+          self.searchable_options = options
+
+          if searchable_options[:columns].nil?
+            raise 'No searchable column defined.'
+          elsif !searchable_options[:columns].is_a?(Array)
+            searchable_options[:columns] = [] << searchable_options[:columns]
+          end
+
+          searchable_options[:project_key] ||= "#{table_name}.project_id"
+          searchable_options[:date_column] ||= "#{table_name}.created_on"
+          searchable_options[:order_column] ||= searchable_options[:date_column]
+
+          # Should we search custom fields on this model ?
+          searchable_options[:search_custom_fields] = !reflect_on_association(:custom_values).nil?
+
+          send :include, Redmine::Acts::Searchable::InstanceMethods
+        end
+      end
+
+      module InstanceMethods
+        def self.included(base)
+          base.extend ClassMethods
+        end
+
+        module ClassMethods
+          # Searches the model for the given tokens
+          # projects argument can be either nil (will search all projects), a project or an array of projects
+          # Returns the results and the results count
+          def search(tokens, projects=nil, options={})
+            if projects.is_a?(Array) && projects.empty?
+              # no results
+              return [[], 0]
+            end
+
+            # TODO: make user an argument
+            user = User.current
+            tokens = [] << tokens unless tokens.is_a?(Array)
+            projects = [] << projects unless projects.nil? || projects.is_a?(Array)
+
+            limit_options = {}
+            limit_options[:limit] = options[:limit] if options[:limit]
+
+            columns = searchable_options[:columns]
+            columns = columns[0..0] if options[:titles_only]
+
+            token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
+
+            if !options[:titles_only] && searchable_options[:search_custom_fields]
+              searchable_custom_field_ids = CustomField.where(:type => "#{self.name}CustomField", :searchable => true).pluck(:id)
+              if searchable_custom_field_ids.any?
+                custom_field_sql = "#{table_name}.id IN (SELECT customized_id FROM #{CustomValue.table_name}" +
+                  " WHERE customized_type='#{self.name}' AND customized_id=#{table_name}.id AND LOWER(value) LIKE ?" +
+                  " AND #{CustomValue.table_name}.custom_field_id IN (#{searchable_custom_field_ids.join(',')}))"
+                token_clauses << custom_field_sql
+              end
+            end
+
+            sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(options[:all_words] ? ' AND ' : ' OR ')
+
+            tokens_conditions = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
+
+            scope = self.scoped
+            project_conditions = []
+            if searchable_options.has_key?(:permission)
+              project_conditions << Project.allowed_to_condition(user, searchable_options[:permission] || :view_project)
+            elsif respond_to?(:visible)
+              scope = scope.visible(user)
+            else
+              ActiveSupport::Deprecation.warn "acts_as_searchable with implicit :permission option is deprecated. Add a visible scope to the #{self.name} model or use explicit :permission option."
+              project_conditions << Project.allowed_to_condition(user, "view_#{self.name.underscore.pluralize}".to_sym)
+            end
+            # TODO: use visible scope options instead
+            project_conditions << "#{searchable_options[:project_key]} IN (#{projects.collect(&:id).join(',')})" unless projects.nil?
+            project_conditions = project_conditions.empty? ? nil : project_conditions.join(' AND ')
+
+            results = []
+            results_count = 0
+
+            scope = scope.
+              includes(searchable_options[:include]).
+              order("#{searchable_options[:order_column]} " + (options[:before] ? 'DESC' : 'ASC')).
+              where(project_conditions).
+              where(tokens_conditions)
+
+            results_count = scope.count
+
+            scope_with_limit = scope.limit(options[:limit])
+            if options[:offset]
+              scope_with_limit = scope_with_limit.where("#{searchable_options[:date_column]} #{options[:before] ? '<' : '>'} ?", options[:offset])
+            end
+            results = scope_with_limit.all
+
+            [results, results_count]
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ad/ad9a838d54bbe521db9061919c47a336a3d26009.svn-base
--- a/.svn/pristine/ad/ad9a838d54bbe521db9061919c47a336a3d26009.svn-base
+++ /dev/null
@@ -1,86 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-<head>
-<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-<title><%=h html_title %></title>
-<meta name="description" content="<%= Redmine::Info.app_name %>" />
-<meta name="keywords" content="issue,bug,tracker" />
-<%= csrf_meta_tag %>
-<%= favicon %>
-<%= stylesheet_link_tag 'application', :media => 'all' %>
-<%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
-<%= javascript_heads %>
-<%= heads_for_theme %>
-<!--[if IE 6]>
-    <style type="text/css">
-      * html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
-      body {behavior: url(<%= stylesheet_path "csshover.htc" %>);}
-    </style>
-<![endif]-->
-<%= call_hook :view_layouts_base_html_head %>
-<!-- page specific tags -->
-<%= yield :header_tags -%>
-</head>
-<body class="<%=h body_css_classes %>">
-<div id="wrapper">
-<div id="wrapper2">
-<div id="top-menu">
-    <div id="account">
-        <%= render_menu :account_menu -%>
-    </div>
-    <%= content_tag(
-           'div',
-           "#{l(:label_logged_as)} #{link_to_user(User.current, :format => :username)}".html_safe,
-           :id => 'loggedas') if User.current.logged? %>
-    <%= render_menu :top_menu if User.current.logged? || !Setting.login_required? -%>
-</div>
-
-<div id="header">
-    <% if User.current.logged? || !Setting.login_required? %>
-    <div id="quick-search">
-        <% form_tag({:controller => 'search', :action => 'index', :id => @project}, :method => :get ) do %>
-        <%= hidden_field_tag(controller.default_search_scope, 1, :id => nil) if controller.default_search_scope %>
-        <label for='q'>
-          <%= link_to l(:label_search), {:controller => 'search', :action => 'index', :id => @project}, :accesskey => accesskey(:search) %>:
-        </label>
-        <%= text_field_tag 'q', @question, :size => 20, :class => 'small', :accesskey => accesskey(:quick_search) %>
-        <% end %>
-        <%= render_project_jump_box %>
-    </div>
-    <% end %>
-
-    <h1><%= page_header_title %></h1>
-
-    <% if display_main_menu?(@project) %>
-    <div id="main-menu">
-        <%= render_main_menu(@project) %>
-    </div>
-    <% end %>
-</div>
-
-<%= tag('div', {:id => 'main', :class => (has_content?(:sidebar) ? '' : 'nosidebar')}, true) %>
-    <div id="sidebar">
-        <%= yield :sidebar %>
-        <%= call_hook :view_layouts_base_sidebar %>
-    </div>
-
-    <div id="content">
-        <%= render_flash_messages %>
-        <%= yield %>
-        <%= call_hook :view_layouts_base_content %>
-        <div style="clear:both;"></div>
-    </div>
-</div>
-
-<div id="ajax-indicator" style="display:none;"><span><%= l(:label_loading) %></span></div>
-
-<div id="footer">
-  <div class="bgl"><div class="bgr">
-    Powered by <%= link_to Redmine::Info.app_name, Redmine::Info.url %> &copy; 2006-2012 Jean-Philippe Lang
-  </div></div>
-</div>
-</div>
-</div>
-<%= call_hook :view_layouts_base_body_bottom %>
-</body>
-</html>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ad/adc05921a5ce3f27356e32a8fbe09eae9855ea79.svn-base
--- a/.svn/pristine/ad/adc05921a5ce3f27356e32a8fbe09eae9855ea79.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-<h2><%=l(:label_password_lost)%></h2>
-
-<div class="box">
-<% form_tag({:action=> "lost_password"}, :class => "tabular") do %>
-
-<p><label for="mail"><%=l(:field_mail)%> <span class="required">*</span></label>
-<%= text_field_tag 'mail', nil, :size => 40 %>
-<%= submit_tag l(:button_submit) %></p>
-
-<% end %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ad/add3430324c137a983a618e2f764a7d937005ad5.svn-base
--- /dev/null
+++ b/.svn/pristine/ad/add3430324c137a983a618e2f764a7d937005ad5.svn-base
@@ -0,0 +1,67 @@
+<% roles = Role.find_all_givable %>
+<% projects = Project.active.all %>
+
+<div class="splitcontentleft">
+<% if @user.memberships.any? %>
+<table class="list memberships">
+  <thead><tr>
+    <th><%= l(:label_project) %></th>
+    <th><%= l(:label_role_plural) %></th>
+    <th style="width:15%"></th>
+      <%= call_hook(:view_users_memberships_table_header, :user => @user )%>
+  </tr></thead>
+  <tbody>
+  <% @user.memberships.each do |membership| %>
+  <% next if membership.new_record? %>
+  <tr id="member-<%= membership.id %>" class="<%= cycle 'odd', 'even' %> class">
+  <td class="project">
+    <%= link_to_project membership.project %>
+  </td>
+  <td class="roles">
+    <span id="member-<%= membership.id %>-roles"><%=h membership.roles.sort.collect(&:to_s).join(', ') %></span>
+    <%= form_for(:membership, :remote => true,
+                 :url => user_membership_path(@user, membership), :method => :put,
+                 :html => {:id => "member-#{membership.id}-roles-form",
+                           :style => 'display:none;'}) do %>
+        <p><% roles.each do |role| %>
+        <label><%= check_box_tag 'membership[role_ids][]', role.id, membership.roles.include?(role),
+                                                           :disabled => membership.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br />
+        <% end %></p>
+        <%= hidden_field_tag 'membership[role_ids][]', '' %>
+        <p><%= submit_tag l(:button_change) %>
+        <%= link_to_function l(:button_cancel),
+                             "$('#member-#{membership.id}-roles').show(); $('#member-#{membership.id}-roles-form').hide(); return false;"
+            %></p>
+    <% end %>
+  </td>
+  <td class="buttons">
+      <%= link_to_function l(:button_edit),
+                           "$('#member-#{membership.id}-roles').hide(); $('#member-#{membership.id}-roles-form').show(); return false;",
+                           :class => 'icon icon-edit'
+          %>
+      <%= delete_link user_membership_path(@user, membership), :remote => true if membership.deletable? %>
+  </td>
+      <%= call_hook(:view_users_memberships_table_row, :user => @user, :membership => membership, :roles => roles, :projects => projects )%>
+  </tr>
+  <% end; reset_cycle %>
+  </tbody>
+</table>
+<% else %>
+<p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
+</div>
+
+<div class="splitcontentright">
+<% if projects.any? %>
+<fieldset><legend><%=l(:label_project_new)%></legend>
+<%= form_for(:membership, :remote => true, :url => user_memberships_path(@user)) do %>
+<%= select_tag 'membership[project_id]', options_for_membership_project_select(@user, projects) %>
+<p><%= l(:label_role_plural) %>:
+<% roles.each do |role| %>
+  <label><%= check_box_tag 'membership[role_ids][]', role.id %> <%=h role %></label>
+<% end %></p>
+<p><%= submit_tag l(:button_add) %></p>
+<% end %>
+</fieldset>
+<% end %>
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ad/add68a0cfda9664dcb00c6400a024de641fa88b8.svn-base
--- /dev/null
+++ b/.svn/pristine/ad/add68a0cfda9664dcb00c6400a024de641fa88b8.svn-base
@@ -0,0 +1,57 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Document < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  belongs_to :project
+  belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
+  acts_as_attachable :delete_permission => :delete_documents
+
+  acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
+  acts_as_event :title => Proc.new {|o| "#{l(:label_document)}: #{o.title}"},
+                :author => Proc.new {|o| o.attachments.reorder("#{Attachment.table_name}.created_on ASC").first.try(:author) },
+                :url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}}
+  acts_as_activity_provider :find_options => {:include => :project}
+
+  validates_presence_of :project, :title, :category
+  validates_length_of :title, :maximum => 60
+
+  scope :visible, lambda {|*args|
+    includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_documents, *args))
+  }
+
+  safe_attributes 'category_id', 'title', 'description'
+
+  def visible?(user=User.current)
+    !user.nil? && user.allowed_to?(:view_documents, project)
+  end
+
+  def initialize(attributes=nil, *args)
+    super
+    if new_record?
+      self.category ||= DocumentCategory.default
+    end
+  end
+
+  def updated_on
+    unless @updated_on
+      a = attachments.last
+      @updated_on = (a && a.created_on) || created_on
+    end
+    @updated_on
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ad/adfb2deb75a122f46087f28c026a73e83ce67dc5.svn-base
--- /dev/null
+++ b/.svn/pristine/ad/adfb2deb75a122f46087f28c026a73e83ce67dc5.svn-base
@@ -0,0 +1,50 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# FileSystem adapter
+# File written by Paul Rivier, at Demotera.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/filesystem_adapter'
+
+class Repository::Filesystem < Repository
+  attr_protected :root_url
+  validates_presence_of :url
+
+  def self.human_attribute_name(attribute_key_name, *args)
+    attr_name = attribute_key_name.to_s
+    if attr_name == "url"
+      attr_name = "root_directory"
+    end
+    super(attr_name, *args)
+  end
+
+  def self.scm_adapter_class
+    Redmine::Scm::Adapters::FilesystemAdapter
+  end
+
+  def self.scm_name
+    'Filesystem'
+  end
+
+  def supports_all_revisions?
+    false
+  end
+
+  def fetch_changesets
+    nil
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ae/ae5dd4bce94cfba3abe32984720693c013f99ef0.svn-base
--- a/.svn/pristine/ae/ae5dd4bce94cfba3abe32984720693c013f99ef0.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday",
- "Sunday");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Sun",
- "Mon",
- "Tue",
- "Wed",
- "Thu",
- "Fri",
- "Sat",
- "Sun");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "Mar",
- "Apr",
- "May",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Oct",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "About the calendar";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)";
-Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)";
-Calendar._TT["GO_TODAY"] = "Go Today";
-Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)";
-Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)";
-Calendar._TT["SEL_DATE"] = "Select date";
-Calendar._TT["DRAG_TO_MOVE"] = "Drag to move";
-Calendar._TT["PART_TODAY"] = " (today)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Display %s first";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Close";
-Calendar._TT["TODAY"] = "Today";
-Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Time:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ae/ae670d8528dae7894b350a3933e33244d75d0910.svn-base
--- a/.svn/pristine/ae/ae670d8528dae7894b350a3933e33244d75d0910.svn-base
+++ /dev/null
@@ -1,113 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class GroupTest < ActiveSupport::TestCase
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :groups_users
-
-  include Redmine::I18n
-
-  def test_create
-    g = Group.new(:lastname => 'New group')
-    assert g.save
-  end
-
-  def test_blank_name_error_message
-    set_language_if_valid 'en'
-    g = Group.new
-    assert !g.save
-    assert_include "Name can't be blank", g.errors.full_messages
-  end
-
-  def test_blank_name_error_message_fr
-    set_language_if_valid 'fr'
-    str = "Nom doit \xc3\xaatre renseign\xc3\xa9(e)"
-    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
-    g = Group.new
-    assert !g.save
-    assert_include str, g.errors.full_messages
-  end
-
-  def test_roles_given_to_new_user
-    group = Group.find(11)
-    user = User.find(9)
-    project = Project.first
-
-    Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
-    group.users << user
-    assert user.member_of?(project)
-  end
-
-  def test_roles_given_to_existing_user
-    group = Group.find(11)
-    user = User.find(9)
-    project = Project.first
-
-    group.users << user
-    m = Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
-    assert user.member_of?(project)
-  end
-
-  def test_roles_updated
-    group = Group.find(11)
-    user = User.find(9)
-    project = Project.first
-    group.users << user
-    m = Member.create!(:principal => group, :project => project, :role_ids => [1])
-    assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
-
-    m.role_ids = [1, 2]
-    assert_equal [1, 2], user.reload.roles_for_project(project).collect(&:id).sort
-
-    m.role_ids = [2]
-    assert_equal [2], user.reload.roles_for_project(project).collect(&:id).sort
-
-    m.role_ids = [1]
-    assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
-  end
-
-  def test_roles_removed_when_removing_group_membership
-    assert User.find(8).member_of?(Project.find(5))
-    Member.find_by_project_id_and_user_id(5, 10).destroy
-    assert !User.find(8).member_of?(Project.find(5))
-  end
-
-  def test_roles_removed_when_removing_user_from_group
-    assert User.find(8).member_of?(Project.find(5))
-    User.find(8).groups.clear
-    assert !User.find(8).member_of?(Project.find(5))
-  end
-
-  def test_destroy_should_unassign_issues
-    group = Group.first
-    Issue.update_all(["assigned_to_id = ?", group.id], 'id = 1')
-
-    assert group.destroy
-    assert group.destroyed?
-
-    assert_equal nil, Issue.find(1).assigned_to_id
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ae/ae7604689327a3d413e43c105b3415b7c3844f37.svn-base
--- a/.svn/pristine/ae/ae7604689327a3d413e43c105b3415b7c3844f37.svn-base
+++ /dev/null
@@ -1,174 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class GroupsControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :members, :member_roles, :groups_users
-
-  def setup
-    @request.session[:user_id] = 1
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-  end
-
-  def test_show
-    get :show, :id => 10
-    assert_response :success
-    assert_template 'show'
-  end
-
-  def test_new
-    get :new
-    assert_response :success
-    assert_template 'new'
-  end
-
-  def test_create
-    assert_difference 'Group.count' do
-      post :create, :group => {:lastname => 'New group'}
-    end
-    assert_redirected_to '/groups'
-    group = Group.first(:order => 'id DESC')
-    assert_equal 'New group', group.name
-    assert_equal [], group.users
-  end
-
-  def test_create_and_continue
-    assert_difference 'Group.count' do
-      post :create, :group => {:lastname => 'New group'}, :continue => 'Create and continue'
-    end
-    assert_redirected_to '/groups/new'
-    group = Group.first(:order => 'id DESC')
-    assert_equal 'New group', group.name
-  end
-
-  def test_create_with_failure
-    assert_no_difference 'Group.count' do
-      post :create, :group => {:lastname => ''}
-    end
-    assert_response :success
-    assert_template 'new'
-  end
-
-  def test_edit
-    get :edit, :id => 10
-    assert_response :success
-    assert_template 'edit'
-    assert_tag 'div', :attributes => {:id => 'tab-content-users'}
-    assert_tag 'div', :attributes => {:id => 'tab-content-memberships'}
-  end
-
-  def test_update
-    new_name = 'New name'
-    put :update, :id => 10, :group => {:lastname => new_name}
-    assert_redirected_to '/groups'
-    group = Group.find(10)
-    assert_equal new_name, group.name
-  end
-
-  def test_update_with_failure
-    put :update, :id => 10, :group => {:lastname => ''}
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_destroy
-    assert_difference 'Group.count', -1 do
-      post :destroy, :id => 10
-    end
-    assert_redirected_to '/groups'
-  end
-
-  def test_add_users
-    assert_difference 'Group.find(10).users.count', 2 do
-      post :add_users, :id => 10, :user_ids => ['2', '3']
-    end
-  end
-
-  def test_xhr_add_users
-    assert_difference 'Group.find(10).users.count', 2 do
-      xhr :post, :add_users, :id => 10, :user_ids => ['2', '3']
-    end
-    assert_select_rjs :replace_html, 'tab-content-users'
-  end
-
-  def test_remove_user
-    assert_difference 'Group.find(10).users.count', -1 do
-      delete :remove_user, :id => 10, :user_id => '8'
-    end
-  end
-
-  def test_xhr_remove_user
-    assert_difference 'Group.find(10).users.count', -1 do
-      xhr :delete, :remove_user, :id => 10, :user_id => '8'
-    end
-    assert_select_rjs :replace_html, 'tab-content-users'
-  end
-
-  def test_new_membership
-    assert_difference 'Group.find(10).members.count' do
-      post :edit_membership, :id => 10, :membership => { :project_id => 2, :role_ids => ['1', '2']}
-    end
-  end
-
-  def test_xhr_new_membership
-    assert_difference 'Group.find(10).members.count' do
-      xhr :post, :edit_membership, :id => 10, :membership => { :project_id => 2, :role_ids => ['1', '2']}
-    end
-    assert_select_rjs :replace_html, 'tab-content-memberships'
-  end
-
-  def test_xhr_new_membership_with_failure
-    assert_no_difference 'Group.find(10).members.count' do
-      xhr :post, :edit_membership, :id => 10, :membership => { :project_id => 999, :role_ids => ['1', '2']}
-    end
-    assert @response.body.match(/alert/i), "Alert message not sent"
-  end
-
-  def test_edit_membership
-    assert_no_difference 'Group.find(10).members.count' do
-      post :edit_membership, :id => 10, :membership_id => 6, :membership => { :role_ids => ['1', '3']}
-    end
-  end
-
-  def test_destroy_membership
-    assert_difference 'Group.find(10).members.count', -1 do
-      post :destroy_membership, :id => 10, :membership_id => 6
-    end
-  end
-
-  def test_xhr_destroy_membership
-    assert_difference 'Group.find(10).members.count', -1 do
-      xhr :post, :destroy_membership, :id => 10, :membership_id => 6
-    end
-    assert_select_rjs :replace_html, 'tab-content-memberships'
-  end
-
-  def test_autocomplete_for_user
-    get :autocomplete_for_user, :id => 10, :q => 'mis'
-    assert_response :success
-    users = assigns(:users)
-    assert_not_nil users
-    assert users.any?
-    assert !users.include?(Group.find(10).users.first)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ae/aebfff37f858adc52ca91629ed8d12be26a654bf.svn-base
--- /dev/null
+++ b/.svn/pristine/ae/aebfff37f858adc52ca91629ed8d12be26a654bf.svn-base
@@ -0,0 +1,124 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class IssueStatusTest < ActiveSupport::TestCase
+  fixtures :issue_statuses, :issues, :roles, :trackers
+
+  def test_create
+    status = IssueStatus.new :name => "Assigned"
+    assert !status.save
+    # status name uniqueness
+    assert_equal 1, status.errors.count
+
+    status.name = "Test Status"
+    assert status.save
+    assert !status.is_default
+  end
+
+  def test_destroy
+    status = IssueStatus.find(3)
+    assert_difference 'IssueStatus.count', -1 do
+      assert status.destroy
+    end
+    assert_nil WorkflowTransition.first(:conditions => {:old_status_id => status.id})
+    assert_nil WorkflowTransition.first(:conditions => {:new_status_id => status.id})
+  end
+
+  def test_destroy_status_in_use
+    # Status assigned to an Issue
+    status = Issue.find(1).status
+    assert_raise(RuntimeError, "Can't delete status") { status.destroy }
+  end
+
+  def test_default
+    status = IssueStatus.default
+    assert_kind_of IssueStatus, status
+  end
+
+  def test_change_default
+    status = IssueStatus.find(2)
+    assert !status.is_default
+    status.is_default = true
+    assert status.save
+    status.reload
+
+    assert_equal status, IssueStatus.default
+    assert !IssueStatus.find(1).is_default
+  end
+
+  def test_reorder_should_not_clear_default_status
+    status = IssueStatus.default
+    status.move_to_bottom
+    status.reload
+    assert status.is_default?
+  end
+
+  def test_new_statuses_allowed_to
+    WorkflowTransition.delete_all
+
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
+    WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
+    status = IssueStatus.find(1)
+    role = Role.find(1)
+    tracker = Tracker.find(1)
+
+    assert_equal [2], status.new_statuses_allowed_to([role], tracker, false, false).map(&:id)
+    assert_equal [2], status.find_new_statuses_allowed_to([role], tracker, false, false).map(&:id)
+
+    assert_equal [2, 3, 5], status.new_statuses_allowed_to([role], tracker, true, false).map(&:id)
+    assert_equal [2, 3, 5], status.find_new_statuses_allowed_to([role], tracker, true, false).map(&:id)
+
+    assert_equal [2, 4, 5], status.new_statuses_allowed_to([role], tracker, false, true).map(&:id)
+    assert_equal [2, 4, 5], status.find_new_statuses_allowed_to([role], tracker, false, true).map(&:id)
+
+    assert_equal [2, 3, 4, 5], status.new_statuses_allowed_to([role], tracker, true, true).map(&:id)
+    assert_equal [2, 3, 4, 5], status.find_new_statuses_allowed_to([role], tracker, true, true).map(&:id)
+  end
+
+  def test_update_done_ratios_with_issue_done_ratio_set_to_issue_field_should_change_nothing
+    IssueStatus.find(1).update_attribute(:default_done_ratio, 50)
+
+    with_settings :issue_done_ratio => 'issue_field' do
+      IssueStatus.update_issue_done_ratios
+      assert_equal 0, Issue.count(:conditions => {:done_ratio => 50})
+    end
+  end
+
+  def test_update_done_ratios_with_issue_done_ratio_set_to_issue_status_should_update_issues
+    IssueStatus.find(1).update_attribute(:default_done_ratio, 50)
+
+    with_settings :issue_done_ratio => 'issue_status' do
+      IssueStatus.update_issue_done_ratios
+      issues = Issue.all(:conditions => {:status_id => 1})
+      assert_equal [50], issues.map {|issue| issue.read_attribute(:done_ratio)}.uniq
+    end
+  end
+
+  def test_sorted_scope
+    assert_equal IssueStatus.all.sort, IssueStatus.sorted.all
+  end
+
+  def test_named_scope
+    status = IssueStatus.named("resolved").first
+    assert_not_nil status
+    assert_equal "Resolved", status.name
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ae/aec5b584466e9e60b9cc8f97f0d1ae1d90e9fe28.svn-base
--- /dev/null
+++ b/.svn/pristine/ae/aec5b584466e9e60b9cc8f97f0d1ae1d90e9fe28.svn-base
@@ -0,0 +1,162 @@
+#!/usr/bin/env ruby
+
+require 'net/http'
+require 'net/https'
+require 'uri'
+require 'optparse'
+
+module Net
+  class HTTPS < HTTP
+    def self.post_form(url, params, headers, options={})
+      request = Post.new(url.path)
+      request.form_data = params
+      request.initialize_http_header(headers)
+      request.basic_auth url.user, url.password if url.user
+      http = new(url.host, url.port)
+      http.use_ssl = (url.scheme == 'https')
+      if options[:no_check_certificate]
+        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+      end
+      http.start {|h| h.request(request) }
+    end
+  end
+end
+
+class RedmineMailHandler
+  VERSION = '0.2.3'
+
+  attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :default_group, :no_permission_check,
+    :url, :key, :no_check_certificate, :no_account_notice, :no_notification
+
+  def initialize
+    self.issue_attributes = {}
+
+    optparse = OptionParser.new do |opts|
+      opts.banner = "Usage: rdm-mailhandler.rb [options] --url=<Redmine URL> --key=<API key>"
+      opts.separator("")
+      opts.separator("Reads an email from standard input and forward it to a Redmine server through a HTTP request.")
+      opts.separator("")
+      opts.separator("Required arguments:")
+      opts.on("-u", "--url URL",              "URL of the Redmine server") {|v| self.url = v}
+      opts.on("-k", "--key KEY",              "Redmine API key") {|v| self.key = v}
+      opts.separator("")
+      opts.separator("General options:")
+      opts.on("--no-permission-check",        "disable permission checking when receiving",
+                                              "the email") {self.no_permission_check = '1'}
+      opts.on("--key-file FILE",              "path to a file that contains the Redmine",
+                                              "API key (use this option instead of --key",
+                                              "if you don't the key to appear in the",
+                                              "command line)") {|v| read_key_from_file(v)}
+      opts.on("--no-check-certificate",       "do not check server certificate") {self.no_check_certificate = true}
+      opts.on("-h", "--help",                 "show this help") {puts opts; exit 1}
+      opts.on("-v", "--verbose",              "show extra information") {self.verbose = true}
+      opts.on("-V", "--version",              "show version information and exit") {puts VERSION; exit}
+      opts.separator("")
+      opts.separator("User creation options:")
+      opts.on("--unknown-user ACTION",        "how to handle emails from an unknown user",
+                                              "ACTION can be one of the following values:",
+                                              "* ignore: email is ignored (default)",
+                                              "* accept: accept as anonymous user",
+                                              "* create: create a user account") {|v| self.unknown_user = v}
+      opts.on("--default-group GROUP",        "add created user to GROUP (none by default)",
+                                              "GROUP can be a comma separated list of groups") { |v| self.default_group = v}
+      opts.on("--no-account-notice",          "don't send account information to the newly",
+                                              "created user") { |v| self.no_account_notice = '1'}
+      opts.on("--no-notification",            "disable email notifications for the created",
+                                              "user") { |v| self.no_notification = '1'}
+      opts.separator("")
+      opts.separator("Issue attributes control options:")
+      opts.on("-p", "--project PROJECT",      "identifier of the target project") {|v| self.issue_attributes['project'] = v}
+      opts.on("-s", "--status STATUS",        "name of the target status") {|v| self.issue_attributes['status'] = v}
+      opts.on("-t", "--tracker TRACKER",      "name of the target tracker") {|v| self.issue_attributes['tracker'] = v}
+      opts.on(      "--category CATEGORY",    "name of the target category") {|v| self.issue_attributes['category'] = v}
+      opts.on(      "--priority PRIORITY",    "name of the target priority") {|v| self.issue_attributes['priority'] = v}
+      opts.on("-o", "--allow-override ATTRS", "allow email content to override attributes",
+                                              "specified by previous options",
+                                              "ATTRS is a comma separated list of attributes") {|v| self.allow_override = v}
+      opts.separator("")
+      opts.separator("Examples:")
+      opts.separator("No project specified. Emails MUST contain the 'Project' keyword:")
+      opts.separator("  rdm-mailhandler.rb --url http://redmine.domain.foo --key secret")
+      opts.separator("")
+      opts.separator("Fixed project and default tracker specified, but emails can override")
+      opts.separator("both tracker and priority attributes using keywords:")
+      opts.separator("  rdm-mailhandler.rb --url https://domain.foo/redmine --key secret \\")
+      opts.separator("    --project foo \\")
+      opts.separator("    --tracker bug \\")
+      opts.separator("    --allow-override tracker,priority")
+
+      opts.summary_width = 27
+    end
+    optparse.parse!
+
+    unless url && key
+      puts "Some arguments are missing. Use `rdm-mailhandler.rb --help` for getting help."
+      exit 1
+    end
+  end
+
+  def submit(email)
+    uri = url.gsub(%r{/*$}, '') + '/mail_handler'
+
+    headers = { 'User-Agent' => "Redmine mail handler/#{VERSION}" }
+
+    data = { 'key' => key, 'email' => email,
+                           'allow_override' => allow_override,
+                           'unknown_user' => unknown_user,
+                           'default_group' => default_group,
+                           'no_account_notice' => no_account_notice,
+                           'no_notification' => no_notification,
+                           'no_permission_check' => no_permission_check}
+    issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
+
+    debug "Posting to #{uri}..."
+    begin
+      response = Net::HTTPS.post_form(URI.parse(uri), data, headers, :no_check_certificate => no_check_certificate)
+    rescue SystemCallError => e # connection refused, etc.
+      warn "An error occured while contacting your Redmine server: #{e.message}"
+      return 75 # temporary failure
+    end
+    debug "Response received: #{response.code}"
+
+    case response.code.to_i
+      when 403
+        warn "Request was denied by your Redmine server. " +
+             "Make sure that 'WS for incoming emails' is enabled in application settings and that you provided the correct API key."
+        return 77
+      when 422
+        warn "Request was denied by your Redmine server. " +
+             "Possible reasons: email is sent from an invalid email address or is missing some information."
+        return 77
+      when 400..499
+        warn "Request was denied by your Redmine server (#{response.code})."
+        return 77
+      when 500..599
+        warn "Failed to contact your Redmine server (#{response.code})."
+        return 75
+      when 201
+        debug "Proccessed successfully"
+        return 0
+      else
+        return 1
+    end
+  end
+
+  private
+
+  def debug(msg)
+    puts msg if verbose
+  end
+
+  def read_key_from_file(filename)
+    begin
+      self.key = File.read(filename).strip
+    rescue Exception => e
+      $stderr.puts "Unable to read the key from #{filename}:\n#{e.message}"
+      exit 1
+    end
+  end
+end
+
+handler = RedmineMailHandler.new
+exit(handler.submit(STDIN.read))
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ae/aece43382595a414583466234e19e24279ff6883.svn-base
--- a/.svn/pristine/ae/aece43382595a414583466234e19e24279ff6883.svn-base
+++ /dev/null
@@ -1,55 +0,0 @@
-require 'rails_generator/base'
-require 'rails_generator/generators/components/controller/controller_generator'
-
-class RedminePluginControllerGenerator < ControllerGenerator
-  attr_reader :plugin_path, :plugin_name, :plugin_pretty_name
-  
-  def initialize(runtime_args, runtime_options = {})
-    runtime_args = runtime_args.dup
-    usage if runtime_args.empty?
-    @plugin_name = "redmine_" + runtime_args.shift.underscore
-    @plugin_pretty_name = plugin_name.titleize
-    @plugin_path = "vendor/plugins/#{plugin_name}"
-    super(runtime_args, runtime_options)
-  end
-  
-  def destination_root
-    File.join(Rails.root, plugin_path)
-  end
-  
-  def manifest
-    record do |m|
-      # Check for class naming collisions.
-      m.class_collisions class_path, "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper"
-
-      # Controller, helper, views, and test directories.
-      m.directory File.join('app/controllers', class_path)
-      m.directory File.join('app/helpers', class_path)
-      m.directory File.join('app/views', class_path, file_name)
-      m.directory File.join('test/functional', class_path)
-
-      # Controller class, functional test, and helper class.
-      m.template 'controller.rb.erb',
-                  File.join('app/controllers',
-                            class_path,
-                            "#{file_name}_controller.rb")
-
-      m.template 'functional_test.rb.erb',
-                  File.join('test/functional',
-                            class_path,
-                            "#{file_name}_controller_test.rb")
-
-      m.template 'helper.rb.erb',
-                  File.join('app/helpers',
-                            class_path,
-                            "#{file_name}_helper.rb")
-
-      # View template for each action.
-      actions.each do |action|
-        path = File.join('app/views', class_path, file_name, "#{action}.html.erb")
-        m.template 'view.html.erb', path,
-          :assigns => { :action => action, :path => path }
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ae/aeebe27a38f69be19f4e3ffca81684cdef660ac9.svn-base
--- a/.svn/pristine/ae/aeebe27a38f69be19f4e3ffca81684cdef660ac9.svn-base
+++ /dev/null
@@ -1,70 +0,0 @@
-<div class="contextual">
-<%= link_to(l(:button_edit), edit_user_path(@user), :class => 'icon icon-edit') if User.current.admin? %>
-</div>
-
-<h2><%= avatar @user, :size => "50" %> <%=h @user.name %></h2>
-
-<div class="splitcontentleft">
-<ul>
-  <% unless @user.pref.hide_mail %>
-    <li><%=l(:field_mail)%>: <%= mail_to(h(@user.mail), nil, :encode => 'javascript') %></li>
-  <% end %>
-  <% @user.visible_custom_field_values.each do |custom_value| %>
-  <% if !custom_value.value.blank? %>
-    <li><%=h custom_value.custom_field.name%>: <%=h show_value(custom_value) %></li>
-  <% end %>
-  <% end %>
-    <li><%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %></li>
-  <% unless @user.last_login_on.nil? %>
-    <li><%=l(:field_last_login_on)%>: <%= format_date(@user.last_login_on) %></li>
-  <% end %>
-</ul>
-
-<% unless @memberships.empty? %>
-<h3><%=l(:label_project_plural)%></h3>
-<ul>
-<% for membership in @memberships %>
-  <li><%= link_to_project(membership.project) %>
-    (<%=h membership.roles.sort.collect(&:to_s).join(', ') %>, <%= format_date(membership.created_on) %>)</li>
-<% end %>
-</ul>
-<% end %>
-<%= call_hook :view_account_left_bottom, :user => @user %>
-</div>
-
-<div class="splitcontentright">
-
-<% unless @events_by_day.empty? %>
-<h3><%= link_to l(:label_activity), :controller => 'activities', :action => 'index', :id => nil, :user_id => @user, :from => @events_by_day.keys.first %></h3>
-
-<p>
-<%=l(:label_reported_issues)%>: <%= Issue.count(:conditions => ["author_id=?", @user.id]) %>
-</p>
-
-<div id="activity">
-<% @events_by_day.keys.sort.reverse.each do |day| %>
-<h4><%= format_activity_day(day) %></h4>
-<dl>
-<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
-  <dt class="<%= e.event_type %>">
-  <span class="time"><%= format_time(e.event_datetime, false) %></span>
-  <%= content_tag('span', h(e.project), :class => 'project') %>
-  <%= link_to format_activity_title(e.event_title), e.event_url %></dt>
-  <dd><span class="description"><%= format_activity_description(e.event_description) %></span></dd>
-<% end -%>
-</dl>
-<% end -%>
-</div>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => nil, :user_id => @user, :key => User.current.rss_key} %>
-<% end %>
-
-<% content_for :header_tags do %>
-  <%= auto_discovery_link_tag(:atom, :controller => 'activities', :action => 'index', :user_id => @user, :format => :atom, :key => User.current.rss_key) %>
-<% end %>
-<% end %>
-<%= call_hook :view_account_right_bottom, :user => @user %>
-</div>
-
-<% html_title @user.name %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ae/aefeab10a4ff6b2a67574515811a4defa07ce6aa.svn-base
--- a/.svn/pristine/ae/aefeab10a4ff6b2a67574515811a4defa07ce6aa.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-<h2><%= l(:label_confirmation) %></h2>
-
-<% form_tag do %>
-<%= @issues.collect {|i| hidden_field_tag 'ids[]', i.id } %>
-<div class="box">
-<p><strong><%= l(:text_destroy_time_entries_question, :hours => number_with_precision(@hours, :precision => 2)) %></strong></p>
-<p>
-<label><%= radio_button_tag 'todo', 'destroy', true %> <%= l(:text_destroy_time_entries) %></label><br />
-<label><%= radio_button_tag 'todo', 'nullify', false %> <%= l(:text_assign_time_entries_to_project) %></label><br />
-<label><%= radio_button_tag 'todo', 'reassign', false, :onchange => 'if (this.checked) { $("reassign_to_id").focus(); }' %> <%= l(:text_reassign_time_entries) %></label>
-<%= text_field_tag 'reassign_to_id', params[:reassign_to_id], :size => 6, :onfocus => '$("todo_reassign").checked=true;' %>
-</p>
-</div>
-<%= submit_tag l(:button_apply) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/af/af12a7c7b0cc0f8267262dce6f48ac239ee40dc3.svn-base
--- /dev/null
+++ b/.svn/pristine/af/af12a7c7b0cc0f8267262dce6f48ac239ee40dc3.svn-base
@@ -0,0 +1,206 @@
+# = Redmine configuration file
+#
+# Each environment has it's own configuration options.  If you are only
+# running in production, only the production block needs to be configured.
+# Environment specific configuration options override the default ones.
+#
+# Note that this file needs to be a valid YAML file.
+# DO NOT USE TABS! Use 2 spaces instead of tabs for identation.
+#
+# == Outgoing email settings (email_delivery setting)
+#
+# === Common configurations
+#
+# ==== Sendmail command
+#
+# production:
+#   email_delivery:
+#     delivery_method: :sendmail
+#
+# ==== Simple SMTP server at localhost
+#
+# production:
+#   email_delivery:
+#     delivery_method: :smtp
+#     smtp_settings:
+#       address: "localhost"
+#       port: 25
+#
+# ==== SMTP server at example.com using LOGIN authentication and checking HELO for foo.com
+#
+# production:
+#   email_delivery:
+#     delivery_method: :smtp
+#     smtp_settings:
+#       address: "example.com"
+#       port: 25
+#       authentication: :login
+#       domain: 'foo.com'
+#       user_name: 'myaccount'
+#       password: 'password'
+#
+# ==== SMTP server at example.com using PLAIN authentication
+#
+# production:
+#   email_delivery:
+#     delivery_method: :smtp
+#     smtp_settings:
+#       address: "example.com"
+#       port: 25
+#       authentication: :plain
+#       domain: 'example.com'
+#       user_name: 'myaccount'
+#       password: 'password'
+#
+# ==== SMTP server at using TLS (GMail)
+#
+# This might require some additional configuration. See the guides at:
+# http://www.redmine.org/projects/redmine/wiki/EmailConfiguration
+#
+# production:
+#   email_delivery:
+#     delivery_method: :smtp
+#     smtp_settings:
+#       enable_starttls_auto: true
+#       address: "smtp.gmail.com"
+#       port: 587
+#       domain: "smtp.gmail.com" # 'your.domain.com' for GoogleApps
+#       authentication: :plain
+#       user_name: "your_email@gmail.com"
+#       password: "your_password"
+#
+#
+# === More configuration options
+#
+# See the "Configuration options" at the following website for a list of the
+# full options allowed:
+#
+# http://wiki.rubyonrails.org/rails/pages/HowToSendEmailsWithActionMailer
+
+
+# default configuration options for all environments
+default:
+  # Outgoing emails configuration (see examples above)
+  email_delivery:
+    delivery_method: :smtp
+    smtp_settings:
+      address: smtp.example.net
+      port: 25
+      domain: example.net
+      authentication: :login
+      user_name: "redmine@example.net"
+      password: "redmine"
+
+  # Absolute path to the directory where attachments are stored.
+  # The default is the 'files' directory in your Redmine instance.
+  # Your Redmine instance needs to have write permission on this
+  # directory.
+  # Examples:
+  # attachments_storage_path: /var/redmine/files
+  # attachments_storage_path: D:/redmine/files
+  attachments_storage_path:
+
+  # Configuration of the autologin cookie.
+  # autologin_cookie_name: the name of the cookie (default: autologin)
+  # autologin_cookie_path: the cookie path (default: /)
+  # autologin_cookie_secure: true sets the cookie secure flag (default: false)
+  autologin_cookie_name:
+  autologin_cookie_path:
+  autologin_cookie_secure:
+
+  # Configuration of SCM executable command.
+  #
+  # Absolute path (e.g. /usr/local/bin/hg) or command name (e.g. hg.exe, bzr.exe)
+  # On Windows + CRuby, *.cmd, *.bat (e.g. hg.cmd, bzr.bat) does not work.
+  #
+  # On Windows + JRuby 1.6.2, path which contains spaces does not work.
+  # For example, "C:\Program Files\TortoiseHg\hg.exe".
+  # If you want to this feature, you need to install to the path which does not contains spaces.
+  # For example, "C:\TortoiseHg\hg.exe".
+  #
+  # Examples:
+  # scm_subversion_command: svn                                       # (default: svn)
+  # scm_mercurial_command:  C:\Program Files\TortoiseHg\hg.exe        # (default: hg)
+  # scm_git_command:        /usr/local/bin/git                        # (default: git)
+  # scm_cvs_command:        cvs                                       # (default: cvs)
+  # scm_bazaar_command:     bzr.exe                                   # (default: bzr)
+  # scm_darcs_command:      darcs-1.0.9-i386-linux                    # (default: darcs)
+  #
+  scm_subversion_command:
+  scm_mercurial_command:
+  scm_git_command:
+  scm_cvs_command:
+  scm_bazaar_command:
+  scm_darcs_command:
+
+  # Absolute path to the SCM commands errors (stderr) log file.
+  # The default is to log in the 'log' directory of your Redmine instance.
+  # Example:
+  # scm_stderr_log_file: /var/log/redmine_scm_stderr.log
+  scm_stderr_log_file:
+
+  # Key used to encrypt sensitive data in the database (SCM and LDAP passwords).
+  # If you don't want to enable data encryption, just leave it blank.
+  # WARNING: losing/changing this key will make encrypted data unreadable.
+  #
+  # If you want to encrypt existing passwords in your database:
+  # * set the cipher key here in your configuration file
+  # * encrypt data using 'rake db:encrypt RAILS_ENV=production'
+  #
+  # If you have encrypted data and want to change this key, you have to:
+  # * decrypt data using 'rake db:decrypt RAILS_ENV=production' first
+  # * change the cipher key here in your configuration file
+  # * encrypt data using 'rake db:encrypt RAILS_ENV=production'
+  database_cipher_key:
+
+  # Set this to false to disable plugins' assets mirroring on startup.
+  # You can use `rake redmine:plugins:assets` to manually mirror assets
+  # to public/plugin_assets when you install/upgrade a Redmine plugin.
+  #
+  #mirror_plugins_assets_on_startup: false
+
+  # Your secret key for verifying cookie session data integrity. If you
+  # change this key, all old sessions will become invalid! Make sure the
+  # secret is at least 30 characters and all random, no regular words or
+  # you'll be exposed to dictionary attacks.
+  #
+  # If you have a load-balancing Redmine cluster, you have to use the
+  # same secret token on each machine.
+  #secret_token: 'change it to a long random string'
+
+  # Absolute path (e.g. /usr/bin/convert, c:/im/convert.exe) to
+  # the ImageMagick's `convert` binary. Used to generate attachment thumbnails.
+  #imagemagick_convert_command:
+
+  # Configuration of RMagcik font.
+  #
+  # Redmine uses RMagcik in order to export gantt png.
+  # You don't need this setting if you don't install RMagcik.
+  #
+  # In CJK (Chinese, Japanese and Korean),
+  # in order to show CJK characters correctly,
+  # you need to set this configuration.
+  #
+  # Because there is no standard font across platforms in CJK,
+  # you need to set a font installed in your server.
+  #
+  # This setting is not necessary in non CJK.
+  #
+  # Examples for Japanese:
+  #   Windows:
+  #     rmagick_font_path: C:\windows\fonts\msgothic.ttc
+  #   Linux:
+  #     rmagick_font_path: /usr/share/fonts/ipa-mincho/ipam.ttf
+  #
+  rmagick_font_path:
+
+  # Maximum number of simultaneous AJAX uploads
+  #max_concurrent_ajax_uploads: 2
+
+# specific configuration options for production environment
+# that overrides the default ones
+production:
+
+# specific configuration options for development environment
+# that overrides the default ones
+development:
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/af/af29735a25eb50d8f3a1e0e41e55ec8241f4e68f.svn-base
--- a/.svn/pristine/af/af29735a25eb50d8f3a1e0e41e55ec8241f4e68f.svn-base
+++ /dev/null
@@ -1,82 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssueStatusesController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin, :except => :index
-  before_filter :require_admin_or_api_request, :only => :index
-  accept_api_auth :index
-
-  def index
-    respond_to do |format|
-      format.html {
-        @issue_status_pages, @issue_statuses = paginate :issue_statuses, :per_page => 25, :order => "position"
-        render :action => "index", :layout => false if request.xhr?
-      }
-      format.api {
-        @issue_statuses = IssueStatus.all(:order => 'position')
-      }
-    end
-  end
-
-  def new
-    @issue_status = IssueStatus.new
-  end
-
-  def create
-    @issue_status = IssueStatus.new(params[:issue_status])
-    if request.post? && @issue_status.save
-      flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index'
-    else
-      render :action => 'new'
-    end
-  end
-
-  def edit
-    @issue_status = IssueStatus.find(params[:id])
-  end
-
-  def update
-    @issue_status = IssueStatus.find(params[:id])
-    if request.put? && @issue_status.update_attributes(params[:issue_status])
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
-    else
-      render :action => 'edit'
-    end
-  end
-
-  verify :method => :delete, :only => :destroy, :redirect_to => { :action => :index }
-  def destroy
-    IssueStatus.find(params[:id]).destroy
-    redirect_to :action => 'index'
-  rescue
-    flash[:error] = l(:error_unable_delete_issue_status)
-    redirect_to :action => 'index'
-  end  	
-
-  def update_issue_done_ratio
-    if request.post? && IssueStatus.update_issue_done_ratios
-      flash[:notice] = l(:notice_issue_done_ratios_updated)
-    else
-      flash[:error] =  l(:error_issue_done_ratios_not_updated)
-    end
-    redirect_to :action => 'index'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/af/afff6ebb421c46aa468f585b7d8909132a409f4d.svn-base
--- /dev/null
+++ b/.svn/pristine/af/afff6ebb421c46aa468f585b7d8909132a409f4d.svn-base
@@ -0,0 +1,248 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class MyControllerTest < ActionController::TestCase
+  fixtures :users, :user_preferences, :roles, :projects, :members, :member_roles,
+  :issues, :issue_statuses, :trackers, :enumerations, :custom_fields, :auth_sources
+
+  def setup
+    @request.session[:user_id] = 2
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'page'
+  end
+
+  def test_page
+    get :page
+    assert_response :success
+    assert_template 'page'
+  end
+
+  def test_page_with_timelog_block
+    preferences = User.find(2).pref
+    preferences[:my_page_layout] = {'top' => ['timelog']}
+    preferences.save!
+    TimeEntry.create!(:user => User.find(2), :spent_on => Date.yesterday, :issue_id => 1, :hours => 2.5, :activity_id => 10)
+
+    get :page
+    assert_response :success
+    assert_select 'tr.time-entry' do
+      assert_select 'td.subject a[href=/issues/1]'
+      assert_select 'td.hours', :text => '2.50'
+    end
+  end
+
+  def test_page_with_all_blocks
+    blocks = MyController::BLOCKS.keys
+    preferences = User.find(2).pref
+    preferences[:my_page_layout] = {'top' => blocks}
+    preferences.save!
+
+    get :page
+    assert_response :success
+    assert_select 'div.mypage-box', blocks.size
+  end
+
+  def test_my_account_should_show_editable_custom_fields
+    get :account
+    assert_response :success
+    assert_template 'account'
+    assert_equal User.find(2), assigns(:user)
+
+    assert_tag :input, :attributes => { :name => 'user[custom_field_values][4]'}
+  end
+
+  def test_my_account_should_not_show_non_editable_custom_fields
+    UserCustomField.find(4).update_attribute :editable, false
+
+    get :account
+    assert_response :success
+    assert_template 'account'
+    assert_equal User.find(2), assigns(:user)
+
+    assert_no_tag :input, :attributes => { :name => 'user[custom_field_values][4]'}
+  end
+
+  def test_update_account
+    post :account,
+      :user => {
+        :firstname => "Joe",
+        :login => "root",
+        :admin => 1,
+        :group_ids => ['10'],
+        :custom_field_values => {"4" => "0100562500"}
+      }
+
+    assert_redirected_to '/my/account'
+    user = User.find(2)
+    assert_equal user, assigns(:user)
+    assert_equal "Joe", user.firstname
+    assert_equal "jsmith", user.login
+    assert_equal "0100562500", user.custom_value_for(4).value
+    # ignored
+    assert !user.admin?
+    assert user.groups.empty?
+  end
+
+  def test_my_account_should_show_destroy_link
+    get :account
+    assert_select 'a[href=/my/account/destroy]'
+  end
+
+  def test_get_destroy_should_display_the_destroy_confirmation
+    get :destroy
+    assert_response :success
+    assert_template 'destroy'
+    assert_select 'form[action=/my/account/destroy]' do
+      assert_select 'input[name=confirm]'
+    end
+  end
+
+  def test_post_destroy_without_confirmation_should_not_destroy_account
+    assert_no_difference 'User.count' do
+      post :destroy
+    end
+    assert_response :success
+    assert_template 'destroy'
+  end
+
+  def test_post_destroy_without_confirmation_should_destroy_account
+    assert_difference 'User.count', -1 do
+      post :destroy, :confirm => '1'
+    end
+    assert_redirected_to '/'
+    assert_match /deleted/i, flash[:notice]
+  end
+
+  def test_post_destroy_with_unsubscribe_not_allowed_should_not_destroy_account
+    User.any_instance.stubs(:own_account_deletable?).returns(false)
+
+    assert_no_difference 'User.count' do
+      post :destroy, :confirm => '1'
+    end
+    assert_redirected_to '/my/account'
+  end
+
+  def test_change_password
+    get :password
+    assert_response :success
+    assert_template 'password'
+
+    # non matching password confirmation
+    post :password, :password => 'jsmith',
+                    :new_password => 'secret123',
+                    :new_password_confirmation => 'secret1234'
+    assert_response :success
+    assert_template 'password'
+    assert_error_tag :content => /Password doesn&#x27;t match confirmation/
+
+    # wrong password
+    post :password, :password => 'wrongpassword',
+                    :new_password => 'secret123',
+                    :new_password_confirmation => 'secret123'
+    assert_response :success
+    assert_template 'password'
+    assert_equal 'Wrong password', flash[:error]
+
+    # good password
+    post :password, :password => 'jsmith',
+                    :new_password => 'secret123',
+                    :new_password_confirmation => 'secret123'
+    assert_redirected_to '/my/account'
+    assert User.try_to_login('jsmith', 'secret123')
+  end
+
+  def test_change_password_should_redirect_if_user_cannot_change_its_password
+    User.find(2).update_attribute(:auth_source_id, 1)
+
+    get :password
+    assert_not_nil flash[:error]
+    assert_redirected_to '/my/account'
+  end
+
+  def test_page_layout
+    get :page_layout
+    assert_response :success
+    assert_template 'page_layout'
+  end
+
+  def test_add_block
+    post :add_block, :block => 'issuesreportedbyme'
+    assert_redirected_to '/my/page_layout'
+    assert User.find(2).pref[:my_page_layout]['top'].include?('issuesreportedbyme')
+  end
+
+  def test_add_invalid_block_should_redirect
+    post :add_block, :block => 'invalid'
+    assert_redirected_to '/my/page_layout'
+  end
+
+  def test_remove_block
+    post :remove_block, :block => 'issuesassignedtome'
+    assert_redirected_to '/my/page_layout'
+    assert !User.find(2).pref[:my_page_layout].values.flatten.include?('issuesassignedtome')
+  end
+
+  def test_order_blocks
+    xhr :post, :order_blocks, :group => 'left', 'blocks' => ['documents', 'calendar', 'latestnews']
+    assert_response :success
+    assert_equal ['documents', 'calendar', 'latestnews'], User.find(2).pref[:my_page_layout]['left']
+  end
+
+  def test_reset_rss_key_with_existing_key
+    @previous_token_value = User.find(2).rss_key # Will generate one if it's missing
+    post :reset_rss_key
+
+    assert_not_equal @previous_token_value, User.find(2).rss_key
+    assert User.find(2).rss_token
+    assert_match /reset/, flash[:notice]
+    assert_redirected_to '/my/account'
+  end
+
+  def test_reset_rss_key_without_existing_key
+    assert_nil User.find(2).rss_token
+    post :reset_rss_key
+
+    assert User.find(2).rss_token
+    assert_match /reset/, flash[:notice]
+    assert_redirected_to '/my/account'
+  end
+
+  def test_reset_api_key_with_existing_key
+    @previous_token_value = User.find(2).api_key # Will generate one if it's missing
+    post :reset_api_key
+
+    assert_not_equal @previous_token_value, User.find(2).api_key
+    assert User.find(2).api_token
+    assert_match /reset/, flash[:notice]
+    assert_redirected_to '/my/account'
+  end
+
+  def test_reset_api_key_without_existing_key
+    assert_nil User.find(2).api_token
+    post :reset_api_key
+
+    assert User.find(2).api_token
+    assert_match /reset/, flash[:notice]
+    assert_redirected_to '/my/account'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b0/b028ab37b0e71e8b5e428fa2705253f8e96293a8.svn-base
--- /dev/null
+++ b/.svn/pristine/b0/b028ab37b0e71e8b5e428fa2705253f8e96293a8.svn-base
@@ -0,0 +1,81 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class CustomFieldsController < ApplicationController
+  layout 'admin'
+
+  before_filter :require_admin
+  before_filter :build_new_custom_field, :only => [:new, :create]
+  before_filter :find_custom_field, :only => [:edit, :update, :destroy]
+
+  def index
+    @custom_fields_by_type = CustomField.all.group_by {|f| f.class.name }
+    @tab = params[:tab] || 'IssueCustomField'
+  end
+
+  def new
+  end
+
+  def create
+    if @custom_field.save
+      flash[:notice] = l(:notice_successful_create)
+      call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field)
+      redirect_to custom_fields_path(:tab => @custom_field.class.name)
+    else
+      render :action => 'new'
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    if @custom_field.update_attributes(params[:custom_field])
+      flash[:notice] = l(:notice_successful_update)
+      call_hook(:controller_custom_fields_edit_after_save, :params => params, :custom_field => @custom_field)
+      redirect_to custom_fields_path(:tab => @custom_field.class.name)
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def destroy
+    begin
+      @custom_field.destroy
+    rescue
+      flash[:error] = l(:error_can_not_delete_custom_field)
+    end
+    redirect_to custom_fields_path(:tab => @custom_field.class.name)
+  end
+
+  private
+
+  def build_new_custom_field
+    @custom_field = CustomField.new_subclass_instance(params[:type], params[:custom_field])
+    if @custom_field.nil?
+      render_404
+    else
+      @custom_field.default_value = nil
+    end
+  end
+
+  def find_custom_field
+    @custom_field = CustomField.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b0/b066b1cae6607ed81e028785b51c4cc7869325ff.svn-base
--- a/.svn/pristine/b0/b066b1cae6607ed81e028785b51c4cc7869325ff.svn-base
+++ /dev/null
@@ -1,142 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::VersionsTest < ActionController::IntegrationTest
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :versions
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "/projects/:project_id/versions" do
-    context "GET" do
-      should "return project versions" do
-        get '/projects/1/versions.xml'
-
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-        assert_tag :tag => 'versions',
-          :attributes => {:type => 'array'},
-          :child => {
-            :tag => 'version',
-            :child => {
-              :tag => 'id',
-              :content => '2',
-              :sibling => {
-                :tag => 'name',
-                :content => '1.0'
-              }
-            }
-          }
-      end
-    end
-
-    context "POST" do
-      should "create the version" do
-        assert_difference 'Version.count' do
-          post '/projects/1/versions.xml', {:version => {:name => 'API test'}}, :authorization => credentials('jsmith')
-        end
-
-        version = Version.first(:order => 'id DESC')
-        assert_equal 'API test', version.name
-
-        assert_response :created
-        assert_equal 'application/xml', @response.content_type
-        assert_tag 'version', :child => {:tag => 'id', :content => version.id.to_s}
-      end
-
-      should "create the version with due date" do
-        assert_difference 'Version.count' do
-          post '/projects/1/versions.xml', {:version => {:name => 'API test', :due_date => '2012-01-24'}}, :authorization => credentials('jsmith')
-        end
-
-        version = Version.first(:order => 'id DESC')
-        assert_equal 'API test', version.name
-        assert_equal Date.parse('2012-01-24'), version.due_date
-
-        assert_response :created
-        assert_equal 'application/xml', @response.content_type
-        assert_tag 'version', :child => {:tag => 'id', :content => version.id.to_s}
-      end
-
-      context "with failure" do
-        should "return the errors" do
-          assert_no_difference('Version.count') do
-            post '/projects/1/versions.xml', {:version => {:name => ''}}, :authorization => credentials('jsmith')
-          end
-
-          assert_response :unprocessable_entity
-          assert_tag :errors, :child => {:tag => 'error', :content => "Name can't be blank"}
-        end
-      end
-    end
-  end
-
-  context "/versions/:id" do
-    context "GET" do
-      should "return the version" do
-        get '/versions/2.xml'
-
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-        assert_tag 'version',
-          :child => {
-            :tag => 'id',
-            :content => '2',
-            :sibling => {
-              :tag => 'name',
-              :content => '1.0'
-            }
-          }
-      end
-    end
-
-    context "PUT" do
-      should "update the version" do
-        put '/versions/2.xml', {:version => {:name => 'API update'}}, :authorization => credentials('jsmith')
-
-        assert_response :ok
-        assert_equal 'API update', Version.find(2).name
-      end
-    end
-
-    context "DELETE" do
-      should "destroy the version" do
-        assert_difference 'Version.count', -1 do
-          delete '/versions/3.xml', {}, :authorization => credentials('jsmith')
-        end
-
-        assert_response :ok
-        assert_nil Version.find_by_id(3)
-      end
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b1/b11a4104da3bd4ac01a0f204b3deb8706ff5132c.svn-base
--- /dev/null
+++ b/.svn/pristine/b1/b11a4104da3bd4ac01a0f204b3deb8706ff5132c.svn-base
@@ -0,0 +1,83 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WikisControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :wikis
+
+  def setup
+    User.current = nil
+  end
+
+  def test_create
+    @request.session[:user_id] = 1
+    assert_nil Project.find(3).wiki
+
+    assert_difference 'Wiki.count' do
+      xhr :post, :edit, :id => 3, :wiki => { :start_page => 'Start page' }
+      assert_response :success
+      assert_template 'edit'
+      assert_equal 'text/javascript', response.content_type
+    end
+
+    wiki = Project.find(3).wiki
+    assert_not_nil wiki
+    assert_equal 'Start page', wiki.start_page
+  end
+
+  def test_create_with_failure
+    @request.session[:user_id] = 1
+
+    assert_no_difference 'Wiki.count' do
+      xhr :post, :edit, :id => 3, :wiki => { :start_page => '' }
+      assert_response :success
+      assert_template 'edit'
+      assert_equal 'text/javascript', response.content_type
+    end
+
+    assert_include 'errorExplanation', response.body
+    assert_include 'Start page can&#x27;t be blank', response.body
+  end
+
+  def test_update
+    @request.session[:user_id] = 1
+
+    assert_no_difference 'Wiki.count' do
+      xhr :post, :edit, :id => 1, :wiki => { :start_page => 'Other start page' }
+      assert_response :success
+      assert_template 'edit'
+      assert_equal 'text/javascript', response.content_type
+    end
+
+    wiki = Project.find(1).wiki
+    assert_equal 'Other start page', wiki.start_page
+  end
+
+  def test_destroy
+    @request.session[:user_id] = 1
+    post :destroy, :id => 1, :confirm => 1
+    assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'ecookbook', :tab => 'wiki'
+    assert_nil Project.find(1).wiki
+  end
+
+  def test_not_found
+    @request.session[:user_id] = 1
+    post :destroy, :id => 999, :confirm => 1
+    assert_response 404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b1/b1305218fa537002c87b9060e9986ab919c383af.svn-base
--- a/.svn/pristine/b1/b1305218fa537002c87b9060e9986ab919c383af.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssueObserver < ActiveRecord::Observer
-  def after_create(issue)
-    Mailer.deliver_issue_add(issue) if Setting.notified_events.include?('issue_added')
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b1/b1358dfd8cf4af5f0821c479be164931290d3c62.svn-base
--- a/.svn/pristine/b1/b1358dfd8cf4af5f0821c479be164931290d3c62.svn-base
+++ /dev/null
@@ -1,14 +0,0 @@
-<div class="attributes">
-<div class="splitcontentleft">
-<p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
-<p><%= f.select :assigned_to_id, principals_options_for_select(@issue.assignable_users, @issue.assigned_to), :include_blank => true %></p>
-</div>
-<div class="splitcontentright">
-<% if Issue.use_field_for_done_ratio? %>
-<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
-<% end %>
-<% unless @issue.assignable_versions.empty? %>
-<p><%= f.select :fixed_version_id, (@issue.assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true %></p>
-<% end %>
-</div>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b1/b149002696296ef786f76433663805d29e4cf811.svn-base
--- a/.svn/pristine/b1/b149002696296ef786f76433663805d29e4cf811.svn-base
+++ /dev/null
@@ -1,16 +0,0 @@
-<%= back_url_hidden_field_tag %>
-<%= error_messages_for 'version' %>
-
-<div class="box">
-<p><%= f.text_field :name, :size => 60, :required => true %></p>
-<p><%= f.text_field :description, :size => 60 %></p>
-<p><%= f.select :status, Version::VERSION_STATUSES.collect {|s| [l("version_status_#{s}"), s]} %></p>
-<p><%= f.text_field :wiki_page_title, :label => :label_wiki_page, :size => 60, :disabled => @project.wiki.nil? %></p>
-<p><%= f.text_field :effective_date, :size => 10 %><%= calendar_for('version_effective_date') %></p>
-<p><%= f.select :sharing, @version.allowed_sharings.collect {|v| [format_version_sharing(v), v]} %></p>
-
-<% @version.custom_field_values.each do |value| %>
-  <p><%= custom_field_tag_with_label :version, value %></p>
-<% end %>
-
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b1/b14ebfff3002a9832e4164e5c03b714ee9b7d35b.svn-base
--- a/.svn/pristine/b1/b14ebfff3002a9832e4164e5c03b714ee9b7d35b.svn-base
+++ /dev/null
@@ -1,45 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Views
-    module Builders
-      class Xml < ::Builder::XmlMarkup
-        def initialize
-          super
-          instruct!
-        end
-
-        def output
-          target!
-        end
-
-        def method_missing(sym, *args, &block)
-          if args.size == 1 && args.first.is_a?(Time)
-            __send__ sym, args.first.xmlschema, &block
-          else
-            super
-          end
-        end
-
-        def array(name, options={}, &block)
-          __send__ name, (options || {}).merge(:type => 'array'), &block
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b1/b1bf1d96c8982d9d19b70df31949c7bb6b7d7f65.svn-base
--- a/.svn/pristine/b1/b1bf1d96c8982d9d19b70df31949c7bb6b7d7f65.svn-base
+++ /dev/null
@@ -1,52 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class AssetsTest < Test::Unit::TestCase  
-  def setup
-    Engines::Assets.mirror_files_for Engines.plugins[:test_assets]
-  end
-  
-  def teardown
-    FileUtils.rm_r(Engines.public_directory) if File.exist?(Engines.public_directory)
-  end
-  
-  def test_engines_has_created_base_public_file
-    assert File.exist?(Engines.public_directory)
-  end
-  
-  def test_engines_has_created_README_in_public_directory
-    assert File.exist?(File.join(Engines.public_directory, 'README'))
-  end
-  
-  def test_public_files_have_been_copied_from_test_assets_plugin
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets'))
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets', 'file.txt'))
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets', 'subfolder'))
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets', 'subfolder', 'file_in_subfolder.txt'))
-  end
-  
-  def test_engines_has_not_created_duplicated_file_structure
-    assert !File.exists?(File.join(Engines.public_directory, "test_assets", RAILS_ROOT))
-  end
-  
-  def test_public_files_have_been_copied_from_test_assets_with_assets_dir_plugin
-    Engines::Assets.mirror_files_for Engines.plugins[:test_assets_with_assets_directory]
-
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_assets_directory'))
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_assets_directory', 'file.txt'))
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_assets_directory', 'subfolder'))
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_assets_directory', 'subfolder', 'file_in_subfolder.txt'))
-  end
-  
-  def test_public_files_have_been_copied_from_test_assets_with_no_subdirectory_plugin
-    Engines::Assets.mirror_files_for Engines.plugins[:test_assets_with_no_subdirectory]
-
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_no_subdirectory'))
-    assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_no_subdirectory', 'file.txt'))    
-  end
-  
-  def test_public_files_have_NOT_been_copied_from_plugins_without_public_or_asset_directories
-    Engines::Assets.mirror_files_for Engines.plugins[:alpha_plugin]
-    
-    assert !File.exist?(File.join(Engines.public_directory, 'alpha_plugin'))
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b1/b1d111606e6209139efdaa2010c7f0c3da0229c5.svn-base
--- /dev/null
+++ b/.svn/pristine/b1/b1d111606e6209139efdaa2010c7f0c3da0229c5.svn-base
@@ -0,0 +1,1440 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Issue < ActiveRecord::Base
+  include Redmine::SafeAttributes
+  include Redmine::Utils::DateCalculation
+
+  belongs_to :project
+  belongs_to :tracker
+  belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
+  belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+  belongs_to :assigned_to, :class_name => 'Principal', :foreign_key => 'assigned_to_id'
+  belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
+  belongs_to :priority, :class_name => 'IssuePriority', :foreign_key => 'priority_id'
+  belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
+
+  has_many :journals, :as => :journalized, :dependent => :destroy
+  has_many :visible_journals,
+    :class_name => 'Journal',
+    :as => :journalized,
+    :conditions => Proc.new { 
+      ["(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))", false]
+    },
+    :readonly => true
+
+  has_many :time_entries, :dependent => :delete_all
+  has_and_belongs_to_many :changesets, :order => "#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC"
+
+  has_many :relations_from, :class_name => 'IssueRelation', :foreign_key => 'issue_from_id', :dependent => :delete_all
+  has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all
+
+  acts_as_nested_set :scope => 'root_id', :dependent => :destroy
+  acts_as_attachable :after_add => :attachment_added, :after_remove => :attachment_removed
+  acts_as_customizable
+  acts_as_watchable
+  acts_as_searchable :columns => ['subject', "#{table_name}.description", "#{Journal.table_name}.notes"],
+                     :include => [:project, :visible_journals],
+                     # sort by id so that limited eager loading doesn't break with postgresql
+                     :order_column => "#{table_name}.id"
+  acts_as_event :title => Proc.new {|o| "#{o.tracker.name} ##{o.id} (#{o.status}): #{o.subject}"},
+                :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.id}},
+                :type => Proc.new {|o| 'issue' + (o.closed? ? ' closed' : '') }
+
+  acts_as_activity_provider :find_options => {:include => [:project, :author, :tracker]},
+                            :author_key => :author_id
+
+  DONE_RATIO_OPTIONS = %w(issue_field issue_status)
+
+  attr_reader :current_journal
+  delegate :notes, :notes=, :private_notes, :private_notes=, :to => :current_journal, :allow_nil => true
+
+  validates_presence_of :subject, :priority, :project, :tracker, :author, :status
+
+  validates_length_of :subject, :maximum => 255
+  validates_inclusion_of :done_ratio, :in => 0..100
+  validates :estimated_hours, :numericality => {:greater_than_or_equal_to => 0, :allow_nil => true, :message => :invalid}
+  validates :start_date, :date => true
+  validates :due_date, :date => true
+  validate :validate_issue, :validate_required_fields
+
+  scope :visible, lambda {|*args|
+    includes(:project).where(Issue.visible_condition(args.shift || User.current, *args))
+  }
+
+  scope :open, lambda {|*args|
+    is_closed = args.size > 0 ? !args.first : false
+    includes(:status).where("#{IssueStatus.table_name}.is_closed = ?", is_closed)
+  }
+
+  scope :recently_updated, lambda { order("#{Issue.table_name}.updated_on DESC") }
+  scope :on_active_project, lambda {
+    includes(:status, :project, :tracker).where("#{Project.table_name}.status = ?", Project::STATUS_ACTIVE)
+  }
+  scope :fixed_version, lambda {|versions|
+    ids = [versions].flatten.compact.map {|v| v.is_a?(Version) ? v.id : v}
+    ids.any? ? where(:fixed_version_id => ids) : where('1=0')
+  }
+
+  before_create :default_assign
+  before_save :close_duplicates, :update_done_ratio_from_issue_status, :force_updated_on_change, :update_closed_on
+  after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?} 
+  after_save :reschedule_following_issues, :update_nested_set_attributes, :update_parent_attributes, :create_journal
+  # Should be after_create but would be called before previous after_save callbacks
+  after_save :after_create_from_copy
+  after_destroy :update_parent_attributes
+
+  # Returns a SQL conditions string used to find all issues visible by the specified user
+  def self.visible_condition(user, options={})
+    Project.allowed_to_condition(user, :view_issues, options) do |role, user|
+      if user.logged?
+        case role.issues_visibility
+        when 'all'
+          nil
+        when 'default'
+          user_ids = [user.id] + user.groups.map(&:id)
+          "(#{table_name}.is_private = #{connection.quoted_false} OR #{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))"
+        when 'own'
+          user_ids = [user.id] + user.groups.map(&:id)
+          "(#{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))"
+        else
+          '1=0'
+        end
+      else
+        "(#{table_name}.is_private = #{connection.quoted_false})"
+      end
+    end
+  end
+
+  # Returns true if usr or current user is allowed to view the issue
+  def visible?(usr=nil)
+    (usr || User.current).allowed_to?(:view_issues, self.project) do |role, user|
+      if user.logged?
+        case role.issues_visibility
+        when 'all'
+          true
+        when 'default'
+          !self.is_private? || (self.author == user || user.is_or_belongs_to?(assigned_to))
+        when 'own'
+          self.author == user || user.is_or_belongs_to?(assigned_to)
+        else
+          false
+        end
+      else
+        !self.is_private?
+      end
+    end
+  end
+
+  # Returns true if user or current user is allowed to edit or add a note to the issue
+  def editable?(user=User.current)
+    user.allowed_to?(:edit_issues, project) || user.allowed_to?(:add_issue_notes, project)
+  end
+
+  def initialize(attributes=nil, *args)
+    super
+    if new_record?
+      # set default values for new records only
+      self.status ||= IssueStatus.default
+      self.priority ||= IssuePriority.default
+      self.watcher_user_ids = []
+    end
+  end
+
+  def create_or_update
+    super
+  ensure
+    @status_was = nil
+  end
+  private :create_or_update
+
+  # AR#Persistence#destroy would raise and RecordNotFound exception
+  # if the issue was already deleted or updated (non matching lock_version).
+  # This is a problem when bulk deleting issues or deleting a project
+  # (because an issue may already be deleted if its parent was deleted
+  # first).
+  # The issue is reloaded by the nested_set before being deleted so
+  # the lock_version condition should not be an issue but we handle it.
+  def destroy
+    super
+  rescue ActiveRecord::RecordNotFound
+    # Stale or already deleted
+    begin
+      reload
+    rescue ActiveRecord::RecordNotFound
+      # The issue was actually already deleted
+      @destroyed = true
+      return freeze
+    end
+    # The issue was stale, retry to destroy
+    super
+  end
+
+  alias :base_reload :reload
+  def reload(*args)
+    @workflow_rule_by_attribute = nil
+    @assignable_versions = nil
+    @relations = nil
+    base_reload(*args)
+  end
+
+  # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
+  def available_custom_fields
+    (project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : []
+  end
+
+  # Copies attributes from another issue, arg can be an id or an Issue
+  def copy_from(arg, options={})
+    issue = arg.is_a?(Issue) ? arg : Issue.visible.find(arg)
+    self.attributes = issue.attributes.dup.except("id", "root_id", "parent_id", "lft", "rgt", "created_on", "updated_on")
+    self.custom_field_values = issue.custom_field_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
+    self.status = issue.status
+    self.author = User.current
+    unless options[:attachments] == false
+      self.attachments = issue.attachments.map do |attachement| 
+        attachement.copy(:container => self)
+      end
+    end
+    @copied_from = issue
+    @copy_options = options
+    self
+  end
+
+  # Returns an unsaved copy of the issue
+  def copy(attributes=nil, copy_options={})
+    copy = self.class.new.copy_from(self, copy_options)
+    copy.attributes = attributes if attributes
+    copy
+  end
+
+  # Returns true if the issue is a copy
+  def copy?
+    @copied_from.present?
+  end
+
+  # Moves/copies an issue to a new project and tracker
+  # Returns the moved/copied issue on success, false on failure
+  def move_to_project(new_project, new_tracker=nil, options={})
+    ActiveSupport::Deprecation.warn "Issue#move_to_project is deprecated, use #project= instead."
+
+    if options[:copy]
+      issue = self.copy
+    else
+      issue = self
+    end
+
+    issue.init_journal(User.current, options[:notes])
+
+    # Preserve previous behaviour
+    # #move_to_project doesn't change tracker automatically
+    issue.send :project=, new_project, true
+    if new_tracker
+      issue.tracker = new_tracker
+    end
+    # Allow bulk setting of attributes on the issue
+    if options[:attributes]
+      issue.attributes = options[:attributes]
+    end
+
+    issue.save ? issue : false
+  end
+
+  def status_id=(sid)
+    self.status = nil
+    result = write_attribute(:status_id, sid)
+    @workflow_rule_by_attribute = nil
+    result
+  end
+
+  def priority_id=(pid)
+    self.priority = nil
+    write_attribute(:priority_id, pid)
+  end
+
+  def category_id=(cid)
+    self.category = nil
+    write_attribute(:category_id, cid)
+  end
+
+  def fixed_version_id=(vid)
+    self.fixed_version = nil
+    write_attribute(:fixed_version_id, vid)
+  end
+
+  def tracker_id=(tid)
+    self.tracker = nil
+    result = write_attribute(:tracker_id, tid)
+    @custom_field_values = nil
+    @workflow_rule_by_attribute = nil
+    result
+  end
+
+  def project_id=(project_id)
+    if project_id.to_s != self.project_id.to_s
+      self.project = (project_id.present? ? Project.find_by_id(project_id) : nil)
+    end
+  end
+
+  def project=(project, keep_tracker=false)
+    project_was = self.project
+    write_attribute(:project_id, project ? project.id : nil)
+    association_instance_set('project', project)
+    if project_was && project && project_was != project
+      @assignable_versions = nil
+
+      unless keep_tracker || project.trackers.include?(tracker)
+        self.tracker = project.trackers.first
+      end
+      # Reassign to the category with same name if any
+      if category
+        self.category = project.issue_categories.find_by_name(category.name)
+      end
+      # Keep the fixed_version if it's still valid in the new_project
+      if fixed_version && fixed_version.project != project && !project.shared_versions.include?(fixed_version)
+        self.fixed_version = nil
+      end
+      # Clear the parent task if it's no longer valid
+      unless valid_parent_project?
+        self.parent_issue_id = nil
+      end
+      @custom_field_values = nil
+    end
+  end
+
+  def description=(arg)
+    if arg.is_a?(String)
+      arg = arg.gsub(/(\r\n|\n|\r)/, "\r\n")
+    end
+    write_attribute(:description, arg)
+  end
+
+  # Overrides assign_attributes so that project and tracker get assigned first
+  def assign_attributes_with_project_and_tracker_first(new_attributes, *args)
+    return if new_attributes.nil?
+    attrs = new_attributes.dup
+    attrs.stringify_keys!
+
+    %w(project project_id tracker tracker_id).each do |attr|
+      if attrs.has_key?(attr)
+        send "#{attr}=", attrs.delete(attr)
+      end
+    end
+    send :assign_attributes_without_project_and_tracker_first, attrs, *args
+  end
+  # Do not redefine alias chain on reload (see #4838)
+  alias_method_chain(:assign_attributes, :project_and_tracker_first) unless method_defined?(:assign_attributes_without_project_and_tracker_first)
+
+  def estimated_hours=(h)
+    write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
+  end
+
+  safe_attributes 'project_id',
+    :if => lambda {|issue, user|
+      if issue.new_record?
+        issue.copy?
+      elsif user.allowed_to?(:move_issues, issue.project)
+        projects = Issue.allowed_target_projects_on_move(user)
+        projects.include?(issue.project) && projects.size > 1
+      end
+    }
+
+  safe_attributes 'tracker_id',
+    'status_id',
+    'category_id',
+    'assigned_to_id',
+    'priority_id',
+    'fixed_version_id',
+    'subject',
+    'description',
+    'start_date',
+    'due_date',
+    'done_ratio',
+    'estimated_hours',
+    'custom_field_values',
+    'custom_fields',
+    'lock_version',
+    'notes',
+    :if => lambda {|issue, user| issue.new_record? || user.allowed_to?(:edit_issues, issue.project) }
+
+  safe_attributes 'status_id',
+    'assigned_to_id',
+    'fixed_version_id',
+    'done_ratio',
+    'lock_version',
+    'notes',
+    :if => lambda {|issue, user| issue.new_statuses_allowed_to(user).any? }
+
+  safe_attributes 'notes',
+    :if => lambda {|issue, user| user.allowed_to?(:add_issue_notes, issue.project)}
+
+  safe_attributes 'private_notes',
+    :if => lambda {|issue, user| !issue.new_record? && user.allowed_to?(:set_notes_private, issue.project)} 
+
+  safe_attributes 'watcher_user_ids',
+    :if => lambda {|issue, user| issue.new_record? && user.allowed_to?(:add_issue_watchers, issue.project)} 
+
+  safe_attributes 'is_private',
+    :if => lambda {|issue, user|
+      user.allowed_to?(:set_issues_private, issue.project) ||
+        (issue.author == user && user.allowed_to?(:set_own_issues_private, issue.project))
+    }
+
+  safe_attributes 'parent_issue_id',
+    :if => lambda {|issue, user| (issue.new_record? || user.allowed_to?(:edit_issues, issue.project)) &&
+      user.allowed_to?(:manage_subtasks, issue.project)}
+
+  def safe_attribute_names(user=nil)
+    names = super
+    names -= disabled_core_fields
+    names -= read_only_attribute_names(user)
+    names
+  end
+
+  # Safely sets attributes
+  # Should be called from controllers instead of #attributes=
+  # attr_accessible is too rough because we still want things like
+  # Issue.new(:project => foo) to work
+  def safe_attributes=(attrs, user=User.current)
+    return unless attrs.is_a?(Hash)
+
+    attrs = attrs.dup
+
+    # Project and Tracker must be set before since new_statuses_allowed_to depends on it.
+    if (p = attrs.delete('project_id')) && safe_attribute?('project_id')
+      if allowed_target_projects(user).collect(&:id).include?(p.to_i)
+        self.project_id = p
+      end
+    end
+
+    if (t = attrs.delete('tracker_id')) && safe_attribute?('tracker_id')
+      self.tracker_id = t
+    end
+
+    if (s = attrs.delete('status_id')) && safe_attribute?('status_id')
+      if new_statuses_allowed_to(user).collect(&:id).include?(s.to_i)
+        self.status_id = s
+      end
+    end
+
+    attrs = delete_unsafe_attributes(attrs, user)
+    return if attrs.empty?
+
+    unless leaf?
+      attrs.reject! {|k,v| %w(priority_id done_ratio start_date due_date estimated_hours).include?(k)}
+    end
+
+    if attrs['parent_issue_id'].present?
+      s = attrs['parent_issue_id'].to_s
+      unless (m = s.match(%r{\A#?(\d+)\z})) && (m[1] == parent_id.to_s || Issue.visible(user).exists?(m[1]))
+        @invalid_parent_issue_id = attrs.delete('parent_issue_id')
+      end
+    end
+
+    if attrs['custom_field_values'].present?
+      attrs['custom_field_values'] = attrs['custom_field_values'].reject {|k, v| read_only_attribute_names(user).include? k.to_s}
+    end
+
+    if attrs['custom_fields'].present?
+      attrs['custom_fields'] = attrs['custom_fields'].reject {|c| read_only_attribute_names(user).include? c['id'].to_s}
+    end
+
+    # mass-assignment security bypass
+    assign_attributes attrs, :without_protection => true
+  end
+
+  def disabled_core_fields
+    tracker ? tracker.disabled_core_fields : []
+  end
+
+  # Returns the custom_field_values that can be edited by the given user
+  def editable_custom_field_values(user=nil)
+    custom_field_values.reject do |value|
+      read_only_attribute_names(user).include?(value.custom_field_id.to_s)
+    end
+  end
+
+  # Returns the names of attributes that are read-only for user or the current user
+  # For users with multiple roles, the read-only fields are the intersection of
+  # read-only fields of each role
+  # The result is an array of strings where sustom fields are represented with their ids
+  #
+  # Examples:
+  #   issue.read_only_attribute_names # => ['due_date', '2']
+  #   issue.read_only_attribute_names(user) # => []
+  def read_only_attribute_names(user=nil)
+    workflow_rule_by_attribute(user).reject {|attr, rule| rule != 'readonly'}.keys
+  end
+
+  # Returns the names of required attributes for user or the current user
+  # For users with multiple roles, the required fields are the intersection of
+  # required fields of each role
+  # The result is an array of strings where sustom fields are represented with their ids
+  #
+  # Examples:
+  #   issue.required_attribute_names # => ['due_date', '2']
+  #   issue.required_attribute_names(user) # => []
+  def required_attribute_names(user=nil)
+    workflow_rule_by_attribute(user).reject {|attr, rule| rule != 'required'}.keys
+  end
+
+  # Returns true if the attribute is required for user
+  def required_attribute?(name, user=nil)
+    required_attribute_names(user).include?(name.to_s)
+  end
+
+  # Returns a hash of the workflow rule by attribute for the given user
+  #
+  # Examples:
+  #   issue.workflow_rule_by_attribute # => {'due_date' => 'required', 'start_date' => 'readonly'}
+  def workflow_rule_by_attribute(user=nil)
+    return @workflow_rule_by_attribute if @workflow_rule_by_attribute && user.nil?
+
+    user_real = user || User.current
+    roles = user_real.admin ? Role.all : user_real.roles_for_project(project)
+    return {} if roles.empty?
+
+    result = {}
+    workflow_permissions = WorkflowPermission.where(:tracker_id => tracker_id, :old_status_id => status_id, :role_id => roles.map(&:id)).all
+    if workflow_permissions.any?
+      workflow_rules = workflow_permissions.inject({}) do |h, wp|
+        h[wp.field_name] ||= []
+        h[wp.field_name] << wp.rule
+        h
+      end
+      workflow_rules.each do |attr, rules|
+        next if rules.size < roles.size
+        uniq_rules = rules.uniq
+        if uniq_rules.size == 1
+          result[attr] = uniq_rules.first
+        else
+          result[attr] = 'required'
+        end
+      end
+    end
+    @workflow_rule_by_attribute = result if user.nil?
+    result
+  end
+  private :workflow_rule_by_attribute
+
+  def done_ratio
+    if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
+      status.default_done_ratio
+    else
+      read_attribute(:done_ratio)
+    end
+  end
+
+  def self.use_status_for_done_ratio?
+    Setting.issue_done_ratio == 'issue_status'
+  end
+
+  def self.use_field_for_done_ratio?
+    Setting.issue_done_ratio == 'issue_field'
+  end
+
+  def validate_issue
+    if due_date && start_date && due_date < start_date
+      errors.add :due_date, :greater_than_start_date
+    end
+
+    if start_date && soonest_start && start_date < soonest_start
+      errors.add :start_date, :invalid
+    end
+
+    if fixed_version
+      if !assignable_versions.include?(fixed_version)
+        errors.add :fixed_version_id, :inclusion
+      elsif reopened? && fixed_version.closed?
+        errors.add :base, I18n.t(:error_can_not_reopen_issue_on_closed_version)
+      end
+    end
+
+    # Checks that the issue can not be added/moved to a disabled tracker
+    if project && (tracker_id_changed? || project_id_changed?)
+      unless project.trackers.include?(tracker)
+        errors.add :tracker_id, :inclusion
+      end
+    end
+
+    # Checks parent issue assignment
+    if @invalid_parent_issue_id.present?
+      errors.add :parent_issue_id, :invalid
+    elsif @parent_issue
+      if !valid_parent_project?(@parent_issue)
+        errors.add :parent_issue_id, :invalid
+      elsif (@parent_issue != parent) && (all_dependent_issues.include?(@parent_issue) || @parent_issue.all_dependent_issues.include?(self))
+        errors.add :parent_issue_id, :invalid
+      elsif !new_record?
+        # moving an existing issue
+        if @parent_issue.root_id != root_id
+          # we can always move to another tree
+        elsif move_possible?(@parent_issue)
+          # move accepted inside tree
+        else
+          errors.add :parent_issue_id, :invalid
+        end
+      end
+    end
+  end
+
+  # Validates the issue against additional workflow requirements
+  def validate_required_fields
+    user = new_record? ? author : current_journal.try(:user)
+
+    required_attribute_names(user).each do |attribute|
+      if attribute =~ /^\d+$/
+        attribute = attribute.to_i
+        v = custom_field_values.detect {|v| v.custom_field_id == attribute }
+        if v && v.value.blank?
+          errors.add :base, v.custom_field.name + ' ' + l('activerecord.errors.messages.blank')
+        end
+      else
+        if respond_to?(attribute) && send(attribute).blank?
+          errors.add attribute, :blank
+        end
+      end
+    end
+  end
+
+  # Set the done_ratio using the status if that setting is set.  This will keep the done_ratios
+  # even if the user turns off the setting later
+  def update_done_ratio_from_issue_status
+    if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
+      self.done_ratio = status.default_done_ratio
+    end
+  end
+
+  def init_journal(user, notes = "")
+    @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
+    if new_record?
+      @current_journal.notify = false
+    else
+      @attributes_before_change = attributes.dup
+      @custom_values_before_change = {}
+      self.custom_field_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
+    end
+    @current_journal
+  end
+
+  # Returns the id of the last journal or nil
+  def last_journal_id
+    if new_record?
+      nil
+    else
+      journals.maximum(:id)
+    end
+  end
+
+  # Returns a scope for journals that have an id greater than journal_id
+  def journals_after(journal_id)
+    scope = journals.reorder("#{Journal.table_name}.id ASC")
+    if journal_id.present?
+      scope = scope.where("#{Journal.table_name}.id > ?", journal_id.to_i)
+    end
+    scope
+  end
+
+  # Returns the initial status of the issue
+  # Returns nil for a new issue
+  def status_was
+    if status_id_was && status_id_was.to_i > 0
+      @status_was ||= IssueStatus.find_by_id(status_id_was)
+    end
+  end
+
+  # Return true if the issue is closed, otherwise false
+  def closed?
+    self.status.is_closed?
+  end
+
+  # Return true if the issue is being reopened
+  def reopened?
+    if !new_record? && status_id_changed?
+      status_was = IssueStatus.find_by_id(status_id_was)
+      status_new = IssueStatus.find_by_id(status_id)
+      if status_was && status_new && status_was.is_closed? && !status_new.is_closed?
+        return true
+      end
+    end
+    false
+  end
+
+  # Return true if the issue is being closed
+  def closing?
+    if !new_record? && status_id_changed?
+      if status_was && status && !status_was.is_closed? && status.is_closed?
+        return true
+      end
+    end
+    false
+  end
+
+  # Returns true if the issue is overdue
+  def overdue?
+    !due_date.nil? && (due_date < Date.today) && !status.is_closed?
+  end
+
+  # Is the amount of work done less than it should for the due date
+  def behind_schedule?
+    return false if start_date.nil? || due_date.nil?
+    done_date = start_date + ((due_date - start_date+1)* done_ratio/100).floor
+    return done_date <= Date.today
+  end
+
+  # Does this issue have children?
+  def children?
+    !leaf?
+  end
+
+  # Users the issue can be assigned to
+  def assignable_users
+    users = project.assignable_users
+    users << author if author
+    users << assigned_to if assigned_to
+    users.uniq.sort
+  end
+
+  # Versions that the issue can be assigned to
+  def assignable_versions
+    return @assignable_versions if @assignable_versions
+
+    versions = project.shared_versions.open.all
+    if fixed_version
+      if fixed_version_id_changed?
+        # nothing to do
+      elsif project_id_changed?
+        if project.shared_versions.include?(fixed_version)
+          versions << fixed_version
+        end
+      else
+        versions << fixed_version
+      end
+    end
+    @assignable_versions = versions.uniq.sort
+  end
+
+  # Returns true if this issue is blocked by another issue that is still open
+  def blocked?
+    !relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil?
+  end
+
+  # Returns an array of statuses that user is able to apply
+  def new_statuses_allowed_to(user=User.current, include_default=false)
+    if new_record? && @copied_from
+      [IssueStatus.default, @copied_from.status].compact.uniq.sort
+    else
+      initial_status = nil
+      if new_record?
+        initial_status = IssueStatus.default
+      elsif status_id_was
+        initial_status = IssueStatus.find_by_id(status_id_was)
+      end
+      initial_status ||= status
+  
+      statuses = initial_status.find_new_statuses_allowed_to(
+        user.admin ? Role.all : user.roles_for_project(project),
+        tracker,
+        author == user,
+        assigned_to_id_changed? ? assigned_to_id_was == user.id : assigned_to_id == user.id
+        )
+      statuses << initial_status unless statuses.empty?
+      statuses << IssueStatus.default if include_default
+      statuses = statuses.compact.uniq.sort
+      blocked? ? statuses.reject {|s| s.is_closed?} : statuses
+    end
+  end
+
+  def assigned_to_was
+    if assigned_to_id_changed? && assigned_to_id_was.present?
+      @assigned_to_was ||= User.find_by_id(assigned_to_id_was)
+    end
+  end
+
+  # Returns the users that should be notified
+  def notified_users
+    notified = []
+    # Author and assignee are always notified unless they have been
+    # locked or don't want to be notified
+    notified << author if author
+    if assigned_to
+      notified += (assigned_to.is_a?(Group) ? assigned_to.users : [assigned_to])
+    end
+    if assigned_to_was
+      notified += (assigned_to_was.is_a?(Group) ? assigned_to_was.users : [assigned_to_was])
+    end
+    notified = notified.select {|u| u.active? && u.notify_about?(self)}
+
+    notified += project.notified_users
+    notified.uniq!
+    # Remove users that can not view the issue
+    notified.reject! {|user| !visible?(user)}
+    notified
+  end
+
+  # Returns the email addresses that should be notified
+  def recipients
+    notified_users.collect(&:mail)
+  end
+
+  # Returns the number of hours spent on this issue
+  def spent_hours
+    @spent_hours ||= time_entries.sum(:hours) || 0
+  end
+
+  # Returns the total number of hours spent on this issue and its descendants
+  #
+  # Example:
+  #   spent_hours => 0.0
+  #   spent_hours => 50.2
+  def total_spent_hours
+    @total_spent_hours ||= self_and_descendants.sum("#{TimeEntry.table_name}.hours",
+      :joins => "LEFT JOIN #{TimeEntry.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id").to_f || 0.0
+  end
+
+  def relations
+    @relations ||= IssueRelation::Relations.new(self, (relations_from + relations_to).sort)
+  end
+
+  # Preloads relations for a collection of issues
+  def self.load_relations(issues)
+    if issues.any?
+      relations = IssueRelation.all(:conditions => ["issue_from_id IN (:ids) OR issue_to_id IN (:ids)", {:ids => issues.map(&:id)}])
+      issues.each do |issue|
+        issue.instance_variable_set "@relations", relations.select {|r| r.issue_from_id == issue.id || r.issue_to_id == issue.id}
+      end
+    end
+  end
+
+  # Preloads visible spent time for a collection of issues
+  def self.load_visible_spent_hours(issues, user=User.current)
+    if issues.any?
+      hours_by_issue_id = TimeEntry.visible(user).sum(:hours, :group => :issue_id)
+      issues.each do |issue|
+        issue.instance_variable_set "@spent_hours", (hours_by_issue_id[issue.id] || 0)
+      end
+    end
+  end
+
+  # Preloads visible relations for a collection of issues
+  def self.load_visible_relations(issues, user=User.current)
+    if issues.any?
+      issue_ids = issues.map(&:id)
+      # Relations with issue_from in given issues and visible issue_to
+      relations_from = IssueRelation.includes(:issue_to => [:status, :project]).where(visible_condition(user)).where(:issue_from_id => issue_ids).all
+      # Relations with issue_to in given issues and visible issue_from
+      relations_to = IssueRelation.includes(:issue_from => [:status, :project]).where(visible_condition(user)).where(:issue_to_id => issue_ids).all
+
+      issues.each do |issue|
+        relations =
+          relations_from.select {|relation| relation.issue_from_id == issue.id} +
+          relations_to.select {|relation| relation.issue_to_id == issue.id}
+
+        issue.instance_variable_set "@relations", IssueRelation::Relations.new(issue, relations.sort)
+      end
+    end
+  end
+
+  # Finds an issue relation given its id.
+  def find_relation(relation_id)
+    IssueRelation.find(relation_id, :conditions => ["issue_to_id = ? OR issue_from_id = ?", id, id])
+  end
+
+  # Returns all the other issues that depend on the issue
+  def all_dependent_issues(except=[])
+    except << self
+    dependencies = []
+    dependencies += relations_from.map(&:issue_to)
+    dependencies += children unless leaf?
+    dependencies.compact!
+    dependencies -= except
+    dependencies += dependencies.map {|issue| issue.all_dependent_issues(except)}.flatten
+    if parent
+      dependencies << parent
+      dependencies += parent.all_dependent_issues(except + parent.descendants)
+    end
+    dependencies
+  end
+
+  # Returns an array of issues that duplicate this one
+  def duplicates
+    relations_to.select {|r| r.relation_type == IssueRelation::TYPE_DUPLICATES}.collect {|r| r.issue_from}
+  end
+
+  # Returns the due date or the target due date if any
+  # Used on gantt chart
+  def due_before
+    due_date || (fixed_version ? fixed_version.effective_date : nil)
+  end
+
+  # Returns the time scheduled for this issue.
+  #
+  # Example:
+  #   Start Date: 2/26/09, End Date: 3/04/09
+  #   duration => 6
+  def duration
+    (start_date && due_date) ? due_date - start_date : 0
+  end
+
+  # Returns the duration in working days
+  def working_duration
+    (start_date && due_date) ? working_days(start_date, due_date) : 0
+  end
+
+  def soonest_start(reload=false)
+    @soonest_start = nil if reload
+    @soonest_start ||= (
+        relations_to(reload).collect{|relation| relation.successor_soonest_start} +
+        [(@parent_issue || parent).try(:soonest_start)]
+      ).compact.max
+  end
+
+  # Sets start_date on the given date or the next working day
+  # and changes due_date to keep the same working duration.
+  def reschedule_on(date)
+    wd = working_duration
+    date = next_working_date(date)
+    self.start_date = date
+    self.due_date = add_working_days(date, wd)
+  end
+
+  # Reschedules the issue on the given date or the next working day and saves the record.
+  # If the issue is a parent task, this is done by rescheduling its subtasks.
+  def reschedule_on!(date)
+    return if date.nil?
+    if leaf?
+      if start_date.nil? || start_date != date
+        if start_date && start_date > date
+          # Issue can not be moved earlier than its soonest start date
+          date = [soonest_start(true), date].compact.max
+        end
+        reschedule_on(date)
+        begin
+          save
+        rescue ActiveRecord::StaleObjectError
+          reload
+          reschedule_on(date)
+          save
+        end
+      end
+    else
+      leaves.each do |leaf|
+        if leaf.start_date
+          # Only move subtask if it starts at the same date as the parent
+          # or if it starts before the given date
+          if start_date == leaf.start_date || date > leaf.start_date 
+            leaf.reschedule_on!(date)
+          end
+        else
+          leaf.reschedule_on!(date)
+        end
+      end
+    end
+  end
+
+  def <=>(issue)
+    if issue.nil?
+      -1
+    elsif root_id != issue.root_id
+      (root_id || 0) <=> (issue.root_id || 0)
+    else
+      (lft || 0) <=> (issue.lft || 0)
+    end
+  end
+
+  def to_s
+    "#{tracker} ##{id}: #{subject}"
+  end
+
+  # Returns a string of css classes that apply to the issue
+  def css_classes
+    s = "issue tracker-#{tracker_id} status-#{status_id} #{priority.try(:css_classes)}"
+    s << ' closed' if closed?
+    s << ' overdue' if overdue?
+    s << ' child' if child?
+    s << ' parent' unless leaf?
+    s << ' private' if is_private?
+    s << ' created-by-me' if User.current.logged? && author_id == User.current.id
+    s << ' assigned-to-me' if User.current.logged? && assigned_to_id == User.current.id
+    s
+  end
+
+  # Saves an issue and a time_entry from the parameters
+  def save_issue_with_child_records(params, existing_time_entry=nil)
+    Issue.transaction do
+      if params[:time_entry] && (params[:time_entry][:hours].present? || params[:time_entry][:comments].present?) && User.current.allowed_to?(:log_time, project)
+        @time_entry = existing_time_entry || TimeEntry.new
+        @time_entry.project = project
+        @time_entry.issue = self
+        @time_entry.user = User.current
+        @time_entry.spent_on = User.current.today
+        @time_entry.attributes = params[:time_entry]
+        self.time_entries << @time_entry
+      end
+
+      # TODO: Rename hook
+      Redmine::Hook.call_hook(:controller_issues_edit_before_save, { :params => params, :issue => self, :time_entry => @time_entry, :journal => @current_journal})
+      if save
+        # TODO: Rename hook
+        Redmine::Hook.call_hook(:controller_issues_edit_after_save, { :params => params, :issue => self, :time_entry => @time_entry, :journal => @current_journal})
+      else
+        raise ActiveRecord::Rollback
+      end
+    end
+  end
+
+  # Unassigns issues from +version+ if it's no longer shared with issue's project
+  def self.update_versions_from_sharing_change(version)
+    # Update issues assigned to the version
+    update_versions(["#{Issue.table_name}.fixed_version_id = ?", version.id])
+  end
+
+  # Unassigns issues from versions that are no longer shared
+  # after +project+ was moved
+  def self.update_versions_from_hierarchy_change(project)
+    moved_project_ids = project.self_and_descendants.reload.collect(&:id)
+    # Update issues of the moved projects and issues assigned to a version of a moved project
+    Issue.update_versions(["#{Version.table_name}.project_id IN (?) OR #{Issue.table_name}.project_id IN (?)", moved_project_ids, moved_project_ids])
+  end
+
+  def parent_issue_id=(arg)
+    s = arg.to_s.strip.presence
+    if s && (m = s.match(%r{\A#?(\d+)\z})) && (@parent_issue = Issue.find_by_id(m[1]))
+      @parent_issue.id
+    else
+      @parent_issue = nil
+      @invalid_parent_issue_id = arg
+    end
+  end
+
+  def parent_issue_id
+    if @invalid_parent_issue_id
+      @invalid_parent_issue_id
+    elsif instance_variable_defined? :@parent_issue
+      @parent_issue.nil? ? nil : @parent_issue.id
+    else
+      parent_id
+    end
+  end
+
+  # Returns true if issue's project is a valid
+  # parent issue project
+  def valid_parent_project?(issue=parent)
+    return true if issue.nil? || issue.project_id == project_id
+
+    case Setting.cross_project_subtasks
+    when 'system'
+      true
+    when 'tree'
+      issue.project.root == project.root
+    when 'hierarchy'
+      issue.project.is_or_is_ancestor_of?(project) || issue.project.is_descendant_of?(project)
+    when 'descendants'
+      issue.project.is_or_is_ancestor_of?(project)
+    else
+      false
+    end
+  end
+
+  # Extracted from the ReportsController.
+  def self.by_tracker(project)
+    count_and_group_by(:project => project,
+                       :field => 'tracker_id',
+                       :joins => Tracker.table_name)
+  end
+
+  def self.by_version(project)
+    count_and_group_by(:project => project,
+                       :field => 'fixed_version_id',
+                       :joins => Version.table_name)
+  end
+
+  def self.by_priority(project)
+    count_and_group_by(:project => project,
+                       :field => 'priority_id',
+                       :joins => IssuePriority.table_name)
+  end
+
+  def self.by_category(project)
+    count_and_group_by(:project => project,
+                       :field => 'category_id',
+                       :joins => IssueCategory.table_name)
+  end
+
+  def self.by_assigned_to(project)
+    count_and_group_by(:project => project,
+                       :field => 'assigned_to_id',
+                       :joins => User.table_name)
+  end
+
+  def self.by_author(project)
+    count_and_group_by(:project => project,
+                       :field => 'author_id',
+                       :joins => User.table_name)
+  end
+
+  def self.by_subproject(project)
+    ActiveRecord::Base.connection.select_all("select    s.id as status_id, 
+                                                s.is_closed as closed, 
+                                                #{Issue.table_name}.project_id as project_id,
+                                                count(#{Issue.table_name}.id) as total 
+                                              from 
+                                                #{Issue.table_name}, #{Project.table_name}, #{IssueStatus.table_name} s
+                                              where 
+                                                #{Issue.table_name}.status_id=s.id
+                                                and #{Issue.table_name}.project_id = #{Project.table_name}.id
+                                                and #{visible_condition(User.current, :project => project, :with_subprojects => true)}
+                                                and #{Issue.table_name}.project_id <> #{project.id}
+                                              group by s.id, s.is_closed, #{Issue.table_name}.project_id") if project.descendants.active.any?
+  end
+  # End ReportsController extraction
+
+  # Returns an array of projects that user can assign the issue to
+  def allowed_target_projects(user=User.current)
+    if new_record?
+      Project.all(:conditions => Project.allowed_to_condition(user, :add_issues))
+    else
+      self.class.allowed_target_projects_on_move(user)
+    end
+  end
+
+  # Returns an array of projects that user can move issues to
+  def self.allowed_target_projects_on_move(user=User.current)
+    Project.all(:conditions => Project.allowed_to_condition(user, :move_issues))
+  end
+
+  private
+
+  def after_project_change
+    # Update project_id on related time entries
+    TimeEntry.update_all(["project_id = ?", project_id], {:issue_id => id})
+
+    # Delete issue relations
+    unless Setting.cross_project_issue_relations?
+      relations_from.clear
+      relations_to.clear
+    end
+
+    # Move subtasks that were in the same project
+    children.each do |child|
+      next unless child.project_id == project_id_was
+      # Change project and keep project
+      child.send :project=, project, true
+      unless child.save
+        raise ActiveRecord::Rollback
+      end
+    end
+  end
+
+  # Callback for after the creation of an issue by copy
+  # * adds a "copied to" relation with the copied issue
+  # * copies subtasks from the copied issue
+  def after_create_from_copy
+    return unless copy? && !@after_create_from_copy_handled
+
+    if (@copied_from.project_id == project_id || Setting.cross_project_issue_relations?) && @copy_options[:link] != false
+      relation = IssueRelation.new(:issue_from => @copied_from, :issue_to => self, :relation_type => IssueRelation::TYPE_COPIED_TO)
+      unless relation.save
+        logger.error "Could not create relation while copying ##{@copied_from.id} to ##{id} due to validation errors: #{relation.errors.full_messages.join(', ')}" if logger
+      end
+    end
+
+    unless @copied_from.leaf? || @copy_options[:subtasks] == false
+      copy_options = (@copy_options || {}).merge(:subtasks => false)
+      copied_issue_ids = {@copied_from.id => self.id}
+      @copied_from.reload.descendants.reorder("#{Issue.table_name}.lft").each do |child|
+        # Do not copy self when copying an issue as a descendant of the copied issue
+        next if child == self
+        # Do not copy subtasks of issues that were not copied
+        next unless copied_issue_ids[child.parent_id]
+        # Do not copy subtasks that are not visible to avoid potential disclosure of private data
+        unless child.visible?
+          logger.error "Subtask ##{child.id} was not copied during ##{@copied_from.id} copy because it is not visible to the current user" if logger
+          next
+        end
+        copy = Issue.new.copy_from(child, copy_options)
+        copy.author = author
+        copy.project = project
+        copy.parent_issue_id = copied_issue_ids[child.parent_id]
+        unless copy.save
+          logger.error "Could not copy subtask ##{child.id} while copying ##{@copied_from.id} to ##{id} due to validation errors: #{copy.errors.full_messages.join(', ')}" if logger
+          next
+        end
+        copied_issue_ids[child.id] = copy.id
+      end
+    end
+    @after_create_from_copy_handled = true
+  end
+
+  def update_nested_set_attributes
+    if root_id.nil?
+      # issue was just created
+      self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id)
+      set_default_left_and_right
+      Issue.update_all("root_id = #{root_id}, lft = #{lft}, rgt = #{rgt}", ["id = ?", id])
+      if @parent_issue
+        move_to_child_of(@parent_issue)
+      end
+      reload
+    elsif parent_issue_id != parent_id
+      former_parent_id = parent_id
+      # moving an existing issue
+      if @parent_issue && @parent_issue.root_id == root_id
+        # inside the same tree
+        move_to_child_of(@parent_issue)
+      else
+        # to another tree
+        unless root?
+          move_to_right_of(root)
+          reload
+        end
+        old_root_id = root_id
+        self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id )
+        target_maxright = nested_set_scope.maximum(right_column_name) || 0
+        offset = target_maxright + 1 - lft
+        Issue.update_all("root_id = #{root_id}, lft = lft + #{offset}, rgt = rgt + #{offset}",
+                          ["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt])
+        self[left_column_name] = lft + offset
+        self[right_column_name] = rgt + offset
+        if @parent_issue
+          move_to_child_of(@parent_issue)
+        end
+      end
+      reload
+      # delete invalid relations of all descendants
+      self_and_descendants.each do |issue|
+        issue.relations.each do |relation|
+          relation.destroy unless relation.valid?
+        end
+      end
+      # update former parent
+      recalculate_attributes_for(former_parent_id) if former_parent_id
+    end
+    remove_instance_variable(:@parent_issue) if instance_variable_defined?(:@parent_issue)
+  end
+
+  def update_parent_attributes
+    recalculate_attributes_for(parent_id) if parent_id
+  end
+
+  def recalculate_attributes_for(issue_id)
+    if issue_id && p = Issue.find_by_id(issue_id)
+      # priority = highest priority of children
+      if priority_position = p.children.maximum("#{IssuePriority.table_name}.position", :joins => :priority)
+        p.priority = IssuePriority.find_by_position(priority_position)
+      end
+
+      # start/due dates = lowest/highest dates of children
+      p.start_date = p.children.minimum(:start_date)
+      p.due_date = p.children.maximum(:due_date)
+      if p.start_date && p.due_date && p.due_date < p.start_date
+        p.start_date, p.due_date = p.due_date, p.start_date
+      end
+
+      # done ratio = weighted average ratio of leaves
+      unless Issue.use_status_for_done_ratio? && p.status && p.status.default_done_ratio
+        leaves_count = p.leaves.count
+        if leaves_count > 0
+          average = p.leaves.average(:estimated_hours).to_f
+          if average == 0
+            average = 1
+          end
+          done = p.leaves.sum("COALESCE(estimated_hours, #{average}) * (CASE WHEN is_closed = #{connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)", :joins => :status).to_f
+          progress = done / (average * leaves_count)
+          p.done_ratio = progress.round
+        end
+      end
+
+      # estimate = sum of leaves estimates
+      p.estimated_hours = p.leaves.sum(:estimated_hours).to_f
+      p.estimated_hours = nil if p.estimated_hours == 0.0
+
+      # ancestors will be recursively updated
+      p.save(:validate => false)
+    end
+  end
+
+  # Update issues so their versions are not pointing to a
+  # fixed_version that is not shared with the issue's project
+  def self.update_versions(conditions=nil)
+    # Only need to update issues with a fixed_version from
+    # a different project and that is not systemwide shared
+    Issue.scoped(:conditions => conditions).all(
+      :conditions => "#{Issue.table_name}.fixed_version_id IS NOT NULL" +
+        " AND #{Issue.table_name}.project_id <> #{Version.table_name}.project_id" +
+        " AND #{Version.table_name}.sharing <> 'system'",
+      :include => [:project, :fixed_version]
+    ).each do |issue|
+      next if issue.project.nil? || issue.fixed_version.nil?
+      unless issue.project.shared_versions.include?(issue.fixed_version)
+        issue.init_journal(User.current)
+        issue.fixed_version = nil
+        issue.save
+      end
+    end
+  end
+
+  # Callback on file attachment
+  def attachment_added(obj)
+    if @current_journal && !obj.new_record?
+      @current_journal.details << JournalDetail.new(:property => 'attachment', :prop_key => obj.id, :value => obj.filename)
+    end
+  end
+
+  # Callback on attachment deletion
+  def attachment_removed(obj)
+    if @current_journal && !obj.new_record?
+      @current_journal.details << JournalDetail.new(:property => 'attachment', :prop_key => obj.id, :old_value => obj.filename)
+      @current_journal.save
+    end
+  end
+
+  # Default assignment based on category
+  def default_assign
+    if assigned_to.nil? && category && category.assigned_to
+      self.assigned_to = category.assigned_to
+    end
+  end
+
+  # Updates start/due dates of following issues
+  def reschedule_following_issues
+    if start_date_changed? || due_date_changed?
+      relations_from.each do |relation|
+        relation.set_issue_to_dates
+      end
+    end
+  end
+
+  # Closes duplicates if the issue is being closed
+  def close_duplicates
+    if closing?
+      duplicates.each do |duplicate|
+        # Reload is need in case the duplicate was updated by a previous duplicate
+        duplicate.reload
+        # Don't re-close it if it's already closed
+        next if duplicate.closed?
+        # Same user and notes
+        if @current_journal
+          duplicate.init_journal(@current_journal.user, @current_journal.notes)
+        end
+        duplicate.update_attribute :status, self.status
+      end
+    end
+  end
+
+  # Make sure updated_on is updated when adding a note and set updated_on now
+  # so we can set closed_on with the same value on closing
+  def force_updated_on_change
+    if @current_journal || changed?
+      self.updated_on = current_time_from_proper_timezone
+      if new_record?
+        self.created_on = updated_on
+      end
+    end
+  end
+
+  # Callback for setting closed_on when the issue is closed.
+  # The closed_on attribute stores the time of the last closing
+  # and is preserved when the issue is reopened.
+  def update_closed_on
+    if closing? || (new_record? && closed?)
+      self.closed_on = updated_on
+    end
+  end
+
+  # Saves the changes in a Journal
+  # Called after_save
+  def create_journal
+    if @current_journal
+      # attributes changes
+      if @attributes_before_change
+        (Issue.column_names - %w(id root_id lft rgt lock_version created_on updated_on closed_on)).each {|c|
+          before = @attributes_before_change[c]
+          after = send(c)
+          next if before == after || (before.blank? && after.blank?)
+          @current_journal.details << JournalDetail.new(:property => 'attr',
+                                                        :prop_key => c,
+                                                        :old_value => before,
+                                                        :value => after)
+        }
+      end
+      if @custom_values_before_change
+        # custom fields changes
+        custom_field_values.each {|c|
+          before = @custom_values_before_change[c.custom_field_id]
+          after = c.value
+          next if before == after || (before.blank? && after.blank?)
+          
+          if before.is_a?(Array) || after.is_a?(Array)
+            before = [before] unless before.is_a?(Array)
+            after = [after] unless after.is_a?(Array)
+            
+            # values removed
+            (before - after).reject(&:blank?).each do |value|
+              @current_journal.details << JournalDetail.new(:property => 'cf',
+                                                            :prop_key => c.custom_field_id,
+                                                            :old_value => value,
+                                                            :value => nil)
+            end
+            # values added
+            (after - before).reject(&:blank?).each do |value|
+              @current_journal.details << JournalDetail.new(:property => 'cf',
+                                                            :prop_key => c.custom_field_id,
+                                                            :old_value => nil,
+                                                            :value => value)
+            end
+          else
+            @current_journal.details << JournalDetail.new(:property => 'cf',
+                                                          :prop_key => c.custom_field_id,
+                                                          :old_value => before,
+                                                          :value => after)
+          end
+        }
+      end
+      @current_journal.save
+      # reset current journal
+      init_journal @current_journal.user, @current_journal.notes
+    end
+  end
+
+  # Query generator for selecting groups of issue counts for a project
+  # based on specific criteria
+  #
+  # Options
+  # * project - Project to search in.
+  # * field - String. Issue field to key off of in the grouping.
+  # * joins - String. The table name to join against.
+  def self.count_and_group_by(options)
+    project = options.delete(:project)
+    select_field = options.delete(:field)
+    joins = options.delete(:joins)
+
+    where = "#{Issue.table_name}.#{select_field}=j.id"
+
+    ActiveRecord::Base.connection.select_all("select    s.id as status_id, 
+                                                s.is_closed as closed, 
+                                                j.id as #{select_field},
+                                                count(#{Issue.table_name}.id) as total 
+                                              from 
+                                                  #{Issue.table_name}, #{Project.table_name}, #{IssueStatus.table_name} s, #{joins} j
+                                              where 
+                                                #{Issue.table_name}.status_id=s.id 
+                                                and #{where}
+                                                and #{Issue.table_name}.project_id=#{Project.table_name}.id
+                                                and #{visible_condition(User.current, :project => project)}
+                                              group by s.id, s.is_closed, j.id")
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b1/b1f000d854347a89ecaf4a279495670486d096e4.svn-base
--- /dev/null
+++ b/.svn/pristine/b1/b1f000d854347a89ecaf4a279495670486d096e4.svn-base
@@ -0,0 +1,212 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class UsersController < ApplicationController
+  layout 'admin'
+
+  before_filter :require_admin, :except => :show
+  before_filter :find_user, :only => [:show, :edit, :update, :destroy, :edit_membership, :destroy_membership]
+  accept_api_auth :index, :show, :create, :update, :destroy
+
+  helper :sort
+  include SortHelper
+  helper :custom_fields
+  include CustomFieldsHelper
+
+  def index
+    sort_init 'login', 'asc'
+    sort_update %w(login firstname lastname mail admin created_on last_login_on)
+
+    case params[:format]
+    when 'xml', 'json'
+      @offset, @limit = api_offset_and_limit
+    else
+      @limit = per_page_option
+    end
+
+    @status = params[:status] || 1
+
+    scope = User.logged.status(@status)
+    scope = scope.like(params[:name]) if params[:name].present?
+    scope = scope.in_group(params[:group_id]) if params[:group_id].present?
+
+    @user_count = scope.count
+    @user_pages = Paginator.new @user_count, @limit, params['page']
+    @offset ||= @user_pages.offset
+    @users =  scope.order(sort_clause).limit(@limit).offset(@offset).all
+
+    respond_to do |format|
+      format.html {
+        @groups = Group.all.sort
+        render :layout => !request.xhr?
+      }
+      format.api
+    end
+  end
+
+  def show
+    # show projects based on current user visibility
+    @memberships = @user.memberships.all(:conditions => Project.visible_condition(User.current))
+
+    events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 10)
+    @events_by_day = events.group_by(&:event_date)
+
+    unless User.current.admin?
+      if !@user.active? || (@user != User.current  && @memberships.empty? && events.empty?)
+        render_404
+        return
+      end
+    end
+
+    respond_to do |format|
+      format.html { render :layout => 'base' }
+      format.api
+    end
+  end
+
+  def new
+    @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option)
+    @auth_sources = AuthSource.all
+  end
+
+  def create
+    @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option)
+    @user.safe_attributes = params[:user]
+    @user.admin = params[:user][:admin] || false
+    @user.login = params[:user][:login]
+    @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation] unless @user.auth_source_id
+
+    if @user.save
+      @user.pref.attributes = params[:pref]
+      @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
+      @user.pref.save
+      @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
+
+      Mailer.account_information(@user, params[:user][:password]).deliver if params[:send_information]
+
+      respond_to do |format|
+        format.html {
+          flash[:notice] = l(:notice_user_successful_create, :id => view_context.link_to(@user.login, user_path(@user)))
+          if params[:continue]
+            redirect_to new_user_path
+          else
+            redirect_to edit_user_path(@user)
+          end
+        }
+        format.api  { render :action => 'show', :status => :created, :location => user_url(@user) }
+      end
+    else
+      @auth_sources = AuthSource.all
+      # Clear password input
+      @user.password = @user.password_confirmation = nil
+
+      respond_to do |format|
+        format.html { render :action => 'new' }
+        format.api  { render_validation_errors(@user) }
+      end
+    end
+  end
+
+  def edit
+    @auth_sources = AuthSource.all
+    @membership ||= Member.new
+  end
+
+  def update
+    @user.admin = params[:user][:admin] if params[:user][:admin]
+    @user.login = params[:user][:login] if params[:user][:login]
+    if params[:user][:password].present? && (@user.auth_source_id.nil? || params[:user][:auth_source_id].blank?)
+      @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation]
+    end
+    @user.safe_attributes = params[:user]
+    # Was the account actived ? (do it before User#save clears the change)
+    was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE])
+    # TODO: Similar to My#account
+    @user.pref.attributes = params[:pref]
+    @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
+
+    if @user.save
+      @user.pref.save
+      @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
+
+      if was_activated
+        Mailer.account_activated(@user).deliver
+      elsif @user.active? && params[:send_information] && !params[:user][:password].blank? && @user.auth_source_id.nil?
+        Mailer.account_information(@user, params[:user][:password]).deliver
+      end
+
+      respond_to do |format|
+        format.html {
+          flash[:notice] = l(:notice_successful_update)
+          redirect_to_referer_or edit_user_path(@user)
+        }
+        format.api  { render_api_ok }
+      end
+    else
+      @auth_sources = AuthSource.all
+      @membership ||= Member.new
+      # Clear password input
+      @user.password = @user.password_confirmation = nil
+
+      respond_to do |format|
+        format.html { render :action => :edit }
+        format.api  { render_validation_errors(@user) }
+      end
+    end
+  end
+
+  def destroy
+    @user.destroy
+    respond_to do |format|
+      format.html { redirect_back_or_default(users_path) }
+      format.api  { render_api_ok }
+    end
+  end
+
+  def edit_membership
+    @membership = Member.edit_membership(params[:membership_id], params[:membership], @user)
+    @membership.save
+    respond_to do |format|
+      format.html { redirect_to edit_user_path(@user, :tab => 'memberships') }
+      format.js
+    end
+  end
+
+  def destroy_membership
+    @membership = Member.find(params[:membership_id])
+    if @membership.deletable?
+      @membership.destroy
+    end
+    respond_to do |format|
+      format.html { redirect_to edit_user_path(@user, :tab => 'memberships') }
+      format.js
+    end
+  end
+
+  private
+
+  def find_user
+    if params[:id] == 'current'
+      require_login || return
+      @user = User.current
+    else
+      @user = User.find(params[:id])
+    end
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b2/b20de0d941bae7b47e7469cc1d3f6bcbdc09efb1.svn-base
--- a/.svn/pristine/b2/b20de0d941bae7b47e7469cc1d3f6bcbdc09efb1.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-Description:
-    Generates a plugin controller.
-
-Example:
-    ./script/generate redmine_plugin_controller MyPlugin Pools index show vote
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b2/b22806e378e1eb7b0e1d944340a5a3887ecdad01.svn-base
--- a/.svn/pristine/b2/b22806e378e1eb7b0e1d944340a5a3887ecdad01.svn-base
+++ /dev/null
@@ -1,38 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class IssuePriorityTest < ActiveSupport::TestCase
-  fixtures :enumerations, :issues
-
-  def test_should_be_an_enumeration
-    assert IssuePriority.ancestors.include?(Enumeration)
-  end
-
-  def test_objects_count
-    # low priority
-    assert_equal 6, IssuePriority.find(4).objects_count
-    # urgent
-    assert_equal 0, IssuePriority.find(7).objects_count
-  end
-
-  def test_option_name
-    assert_equal :enumeration_issue_priorities, IssuePriority.new.option_name
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b2/b2402650e8784d78193fadbdd730ba690a27bbab.svn-base
--- a/.svn/pristine/b2/b2402650e8784d78193fadbdd730ba690a27bbab.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-<ul>
-<% if @issues.any? -%>
-  <% @issues.each do |issue| -%>
-    <%= content_tag 'li', h("#{issue.tracker} ##{issue.id}: #{issue.subject}"), :id => issue.id %>
-  <% end -%>
-<% else -%>
-  <%= content_tag("li", l(:label_none), :style => 'display:none') %>
-<% end -%>
-</ul>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b2/b2adc52778d4d3ebd2c0c35b234944a4234c7e40.svn-base
--- a/.svn/pristine/b2/b2adc52778d4d3ebd2c0c35b234944a4234c7e40.svn-base
+++ /dev/null
@@ -1,38 +0,0 @@
-require 'source_annotation_extractor'
-
-# Modified version of the SourceAnnotationExtractor in railties
-# Will search for runable code that uses <tt>call_hook</tt>
-class PluginSourceAnnotationExtractor < SourceAnnotationExtractor
-  # Returns a hash that maps filenames under +dir+ (recursively) to arrays
-  # with their annotations. Only files with annotations are included, and only
-  # those with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, and +.erb+
-  # are taken into account.
-  def find_in(dir)
-    results = {}
-
-    Dir.glob("#{dir}/*") do |item|
-      next if File.basename(item)[0] == ?.
-
-      if File.directory?(item)
-        results.update(find_in(item))
-      elsif item =~ /(hook|test)\.rb/
-        # skip
-      elsif item =~ /\.(builder|(r(?:b|xml|js)))$/
-        results.update(extract_annotations_from(item, /\s*(#{tag})\(?\s*(.*)$/))
-      elsif item =~ /\.(rhtml|erb)$/
-        results.update(extract_annotations_from(item, /<%=\s*\s*(#{tag})\(?\s*(.*?)\s*%>/))
-      end
-    end
-
-    results
-  end
-end
-
-namespace :redmine do
-  namespace :plugins do
-    desc "Enumerate all Redmine plugin hooks and their context parameters"
-    task :hook_list do
-      PluginSourceAnnotationExtractor.enumerate 'call_hook'
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b2/b2ec709a5741656dee33e1e0c9df1f53a0a7af3f.svn-base
--- a/.svn/pristine/b2/b2ec709a5741656dee33e1e0c9df1f53a0a7af3f.svn-base
+++ /dev/null
@@ -1,1128 +0,0 @@
-// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-// Contributors:
-//  Justin Palmer (http://encytemedia.com/)
-//  Mark Pilgrim (http://diveintomark.org/)
-//  Martin Bialasinki
-//
-// script.aculo.us is freely distributable under the terms of an MIT-style license.
-// For details, see the script.aculo.us web site: http://script.aculo.us/
-
-// converts rgb() and #xxx to #xxxxxx format,
-// returns self (or first argument) if not convertable
-String.prototype.parseColor = function() {
-  var color = '#';
-  if (this.slice(0,4) == 'rgb(') {
-    var cols = this.slice(4,this.length-1).split(',');
-    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
-  } else {
-    if (this.slice(0,1) == '#') {
-      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
-      if (this.length==7) color = this.toLowerCase();
-    }
-  }
-  return (color.length==7 ? color : (arguments[0] || this));
-};
-
-/*--------------------------------------------------------------------------*/
-
-Element.collectTextNodes = function(element) {
-  return $A($(element).childNodes).collect( function(node) {
-    return (node.nodeType==3 ? node.nodeValue :
-      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
-  }).flatten().join('');
-};
-
-Element.collectTextNodesIgnoreClass = function(element, className) {
-  return $A($(element).childNodes).collect( function(node) {
-    return (node.nodeType==3 ? node.nodeValue :
-      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
-        Element.collectTextNodesIgnoreClass(node, className) : ''));
-  }).flatten().join('');
-};
-
-Element.setContentZoom = function(element, percent) {
-  element = $(element);
-  element.setStyle({fontSize: (percent/100) + 'em'});
-  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
-  return element;
-};
-
-Element.getInlineOpacity = function(element){
-  return $(element).style.opacity || '';
-};
-
-Element.forceRerendering = function(element) {
-  try {
-    element = $(element);
-    var n = document.createTextNode(' ');
-    element.appendChild(n);
-    element.removeChild(n);
-  } catch(e) { }
-};
-
-/*--------------------------------------------------------------------------*/
-
-var Effect = {
-  _elementDoesNotExistError: {
-    name: 'ElementDoesNotExistError',
-    message: 'The specified DOM element does not exist, but is required for this effect to operate'
-  },
-  Transitions: {
-    linear: Prototype.K,
-    sinoidal: function(pos) {
-      return (-Math.cos(pos*Math.PI)/2) + .5;
-    },
-    reverse: function(pos) {
-      return 1-pos;
-    },
-    flicker: function(pos) {
-      var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
-      return pos > 1 ? 1 : pos;
-    },
-    wobble: function(pos) {
-      return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
-    },
-    pulse: function(pos, pulses) {
-      return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
-    },
-    spring: function(pos) {
-      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
-    },
-    none: function(pos) {
-      return 0;
-    },
-    full: function(pos) {
-      return 1;
-    }
-  },
-  DefaultOptions: {
-    duration:   1.0,   // seconds
-    fps:        100,   // 100= assume 66fps max.
-    sync:       false, // true for combining
-    from:       0.0,
-    to:         1.0,
-    delay:      0.0,
-    queue:      'parallel'
-  },
-  tagifyText: function(element) {
-    var tagifyStyle = 'position:relative';
-    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
-
-    element = $(element);
-    $A(element.childNodes).each( function(child) {
-      if (child.nodeType==3) {
-        child.nodeValue.toArray().each( function(character) {
-          element.insertBefore(
-            new Element('span', {style: tagifyStyle}).update(
-              character == ' ' ? String.fromCharCode(160) : character),
-              child);
-        });
-        Element.remove(child);
-      }
-    });
-  },
-  multiple: function(element, effect) {
-    var elements;
-    if (((typeof element == 'object') ||
-        Object.isFunction(element)) &&
-       (element.length))
-      elements = element;
-    else
-      elements = $(element).childNodes;
-
-    var options = Object.extend({
-      speed: 0.1,
-      delay: 0.0
-    }, arguments[2] || { });
-    var masterDelay = options.delay;
-
-    $A(elements).each( function(element, index) {
-      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
-    });
-  },
-  PAIRS: {
-    'slide':  ['SlideDown','SlideUp'],
-    'blind':  ['BlindDown','BlindUp'],
-    'appear': ['Appear','Fade']
-  },
-  toggle: function(element, effect) {
-    element = $(element);
-    effect = (effect || 'appear').toLowerCase();
-    var options = Object.extend({
-      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
-    }, arguments[2] || { });
-    Effect[element.visible() ?
-      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
-  }
-};
-
-Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
-
-/* ------------- core effects ------------- */
-
-Effect.ScopedQueue = Class.create(Enumerable, {
-  initialize: function() {
-    this.effects  = [];
-    this.interval = null;
-  },
-  _each: function(iterator) {
-    this.effects._each(iterator);
-  },
-  add: function(effect) {
-    var timestamp = new Date().getTime();
-
-    var position = Object.isString(effect.options.queue) ?
-      effect.options.queue : effect.options.queue.position;
-
-    switch(position) {
-      case 'front':
-        // move unstarted effects after this effect
-        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
-            e.startOn  += effect.finishOn;
-            e.finishOn += effect.finishOn;
-          });
-        break;
-      case 'with-last':
-        timestamp = this.effects.pluck('startOn').max() || timestamp;
-        break;
-      case 'end':
-        // start effect after last queued effect has finished
-        timestamp = this.effects.pluck('finishOn').max() || timestamp;
-        break;
-    }
-
-    effect.startOn  += timestamp;
-    effect.finishOn += timestamp;
-
-    if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
-      this.effects.push(effect);
-
-    if (!this.interval)
-      this.interval = setInterval(this.loop.bind(this), 15);
-  },
-  remove: function(effect) {
-    this.effects = this.effects.reject(function(e) { return e==effect });
-    if (this.effects.length == 0) {
-      clearInterval(this.interval);
-      this.interval = null;
-    }
-  },
-  loop: function() {
-    var timePos = new Date().getTime();
-    for(var i=0, len=this.effects.length;i<len;i++)
-      this.effects[i] && this.effects[i].loop(timePos);
-  }
-});
-
-Effect.Queues = {
-  instances: $H(),
-  get: function(queueName) {
-    if (!Object.isString(queueName)) return queueName;
-
-    return this.instances.get(queueName) ||
-      this.instances.set(queueName, new Effect.ScopedQueue());
-  }
-};
-Effect.Queue = Effect.Queues.get('global');
-
-Effect.Base = Class.create({
-  position: null,
-  start: function(options) {
-    function codeForEvent(options,eventName){
-      return (
-        (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
-        (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
-      );
-    }
-    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
-    this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
-    this.currentFrame = 0;
-    this.state        = 'idle';
-    this.startOn      = this.options.delay*1000;
-    this.finishOn     = this.startOn+(this.options.duration*1000);
-    this.fromToDelta  = this.options.to-this.options.from;
-    this.totalTime    = this.finishOn-this.startOn;
-    this.totalFrames  = this.options.fps*this.options.duration;
-
-    this.render = (function() {
-      function dispatch(effect, eventName) {
-        if (effect.options[eventName + 'Internal'])
-          effect.options[eventName + 'Internal'](effect);
-        if (effect.options[eventName])
-          effect.options[eventName](effect);
-      }
-
-      return function(pos) {
-        if (this.state === "idle") {
-          this.state = "running";
-          dispatch(this, 'beforeSetup');
-          if (this.setup) this.setup();
-          dispatch(this, 'afterSetup');
-        }
-        if (this.state === "running") {
-          pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
-          this.position = pos;
-          dispatch(this, 'beforeUpdate');
-          if (this.update) this.update(pos);
-          dispatch(this, 'afterUpdate');
-        }
-      };
-    })();
-
-    this.event('beforeStart');
-    if (!this.options.sync)
-      Effect.Queues.get(Object.isString(this.options.queue) ?
-        'global' : this.options.queue.scope).add(this);
-  },
-  loop: function(timePos) {
-    if (timePos >= this.startOn) {
-      if (timePos >= this.finishOn) {
-        this.render(1.0);
-        this.cancel();
-        this.event('beforeFinish');
-        if (this.finish) this.finish();
-        this.event('afterFinish');
-        return;
-      }
-      var pos   = (timePos - this.startOn) / this.totalTime,
-          frame = (pos * this.totalFrames).round();
-      if (frame > this.currentFrame) {
-        this.render(pos);
-        this.currentFrame = frame;
-      }
-    }
-  },
-  cancel: function() {
-    if (!this.options.sync)
-      Effect.Queues.get(Object.isString(this.options.queue) ?
-        'global' : this.options.queue.scope).remove(this);
-    this.state = 'finished';
-  },
-  event: function(eventName) {
-    if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
-    if (this.options[eventName]) this.options[eventName](this);
-  },
-  inspect: function() {
-    var data = $H();
-    for(property in this)
-      if (!Object.isFunction(this[property])) data.set(property, this[property]);
-    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
-  }
-});
-
-Effect.Parallel = Class.create(Effect.Base, {
-  initialize: function(effects) {
-    this.effects = effects || [];
-    this.start(arguments[1]);
-  },
-  update: function(position) {
-    this.effects.invoke('render', position);
-  },
-  finish: function(position) {
-    this.effects.each( function(effect) {
-      effect.render(1.0);
-      effect.cancel();
-      effect.event('beforeFinish');
-      if (effect.finish) effect.finish(position);
-      effect.event('afterFinish');
-    });
-  }
-});
-
-Effect.Tween = Class.create(Effect.Base, {
-  initialize: function(object, from, to) {
-    object = Object.isString(object) ? $(object) : object;
-    var args = $A(arguments), method = args.last(),
-      options = args.length == 5 ? args[3] : null;
-    this.method = Object.isFunction(method) ? method.bind(object) :
-      Object.isFunction(object[method]) ? object[method].bind(object) :
-      function(value) { object[method] = value };
-    this.start(Object.extend({ from: from, to: to }, options || { }));
-  },
-  update: function(position) {
-    this.method(position);
-  }
-});
-
-Effect.Event = Class.create(Effect.Base, {
-  initialize: function() {
-    this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
-  },
-  update: Prototype.emptyFunction
-});
-
-Effect.Opacity = Class.create(Effect.Base, {
-  initialize: function(element) {
-    this.element = $(element);
-    if (!this.element) throw(Effect._elementDoesNotExistError);
-    // make this work on IE on elements without 'layout'
-    if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
-      this.element.setStyle({zoom: 1});
-    var options = Object.extend({
-      from: this.element.getOpacity() || 0.0,
-      to:   1.0
-    }, arguments[1] || { });
-    this.start(options);
-  },
-  update: function(position) {
-    this.element.setOpacity(position);
-  }
-});
-
-Effect.Move = Class.create(Effect.Base, {
-  initialize: function(element) {
-    this.element = $(element);
-    if (!this.element) throw(Effect._elementDoesNotExistError);
-    var options = Object.extend({
-      x:    0,
-      y:    0,
-      mode: 'relative'
-    }, arguments[1] || { });
-    this.start(options);
-  },
-  setup: function() {
-    this.element.makePositioned();
-    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
-    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
-    if (this.options.mode == 'absolute') {
-      this.options.x = this.options.x - this.originalLeft;
-      this.options.y = this.options.y - this.originalTop;
-    }
-  },
-  update: function(position) {
-    this.element.setStyle({
-      left: (this.options.x  * position + this.originalLeft).round() + 'px',
-      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
-    });
-  }
-});
-
-// for backwards compatibility
-Effect.MoveBy = function(element, toTop, toLeft) {
-  return new Effect.Move(element,
-    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
-};
-
-Effect.Scale = Class.create(Effect.Base, {
-  initialize: function(element, percent) {
-    this.element = $(element);
-    if (!this.element) throw(Effect._elementDoesNotExistError);
-    var options = Object.extend({
-      scaleX: true,
-      scaleY: true,
-      scaleContent: true,
-      scaleFromCenter: false,
-      scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
-      scaleFrom: 100.0,
-      scaleTo:   percent
-    }, arguments[2] || { });
-    this.start(options);
-  },
-  setup: function() {
-    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
-    this.elementPositioning = this.element.getStyle('position');
-
-    this.originalStyle = { };
-    ['top','left','width','height','fontSize'].each( function(k) {
-      this.originalStyle[k] = this.element.style[k];
-    }.bind(this));
-
-    this.originalTop  = this.element.offsetTop;
-    this.originalLeft = this.element.offsetLeft;
-
-    var fontSize = this.element.getStyle('font-size') || '100%';
-    ['em','px','%','pt'].each( function(fontSizeType) {
-      if (fontSize.indexOf(fontSizeType)>0) {
-        this.fontSize     = parseFloat(fontSize);
-        this.fontSizeType = fontSizeType;
-      }
-    }.bind(this));
-
-    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
-
-    this.dims = null;
-    if (this.options.scaleMode=='box')
-      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
-    if (/^content/.test(this.options.scaleMode))
-      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
-    if (!this.dims)
-      this.dims = [this.options.scaleMode.originalHeight,
-                   this.options.scaleMode.originalWidth];
-  },
-  update: function(position) {
-    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
-    if (this.options.scaleContent && this.fontSize)
-      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
-    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
-  },
-  finish: function(position) {
-    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
-  },
-  setDimensions: function(height, width) {
-    var d = { };
-    if (this.options.scaleX) d.width = width.round() + 'px';
-    if (this.options.scaleY) d.height = height.round() + 'px';
-    if (this.options.scaleFromCenter) {
-      var topd  = (height - this.dims[0])/2;
-      var leftd = (width  - this.dims[1])/2;
-      if (this.elementPositioning == 'absolute') {
-        if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
-        if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
-      } else {
-        if (this.options.scaleY) d.top = -topd + 'px';
-        if (this.options.scaleX) d.left = -leftd + 'px';
-      }
-    }
-    this.element.setStyle(d);
-  }
-});
-
-Effect.Highlight = Class.create(Effect.Base, {
-  initialize: function(element) {
-    this.element = $(element);
-    if (!this.element) throw(Effect._elementDoesNotExistError);
-    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
-    this.start(options);
-  },
-  setup: function() {
-    // Prevent executing on elements not in the layout flow
-    if (this.element.getStyle('display')=='none') { this.cancel(); return; }
-    // Disable background image during the effect
-    this.oldStyle = { };
-    if (!this.options.keepBackgroundImage) {
-      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
-      this.element.setStyle({backgroundImage: 'none'});
-    }
-    if (!this.options.endcolor)
-      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
-    if (!this.options.restorecolor)
-      this.options.restorecolor = this.element.getStyle('background-color');
-    // init color calculations
-    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
-    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
-  },
-  update: function(position) {
-    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
-      return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
-  },
-  finish: function() {
-    this.element.setStyle(Object.extend(this.oldStyle, {
-      backgroundColor: this.options.restorecolor
-    }));
-  }
-});
-
-Effect.ScrollTo = function(element) {
-  var options = arguments[1] || { },
-  scrollOffsets = document.viewport.getScrollOffsets(),
-  elementOffsets = $(element).cumulativeOffset();
-
-  if (options.offset) elementOffsets[1] += options.offset;
-
-  return new Effect.Tween(null,
-    scrollOffsets.top,
-    elementOffsets[1],
-    options,
-    function(p){ scrollTo(scrollOffsets.left, p.round()); }
-  );
-};
-
-/* ------------- combination effects ------------- */
-
-Effect.Fade = function(element) {
-  element = $(element);
-  var oldOpacity = element.getInlineOpacity();
-  var options = Object.extend({
-    from: element.getOpacity() || 1.0,
-    to:   0.0,
-    afterFinishInternal: function(effect) {
-      if (effect.options.to!=0) return;
-      effect.element.hide().setStyle({opacity: oldOpacity});
-    }
-  }, arguments[1] || { });
-  return new Effect.Opacity(element,options);
-};
-
-Effect.Appear = function(element) {
-  element = $(element);
-  var options = Object.extend({
-  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
-  to:   1.0,
-  // force Safari to render floated elements properly
-  afterFinishInternal: function(effect) {
-    effect.element.forceRerendering();
-  },
-  beforeSetup: function(effect) {
-    effect.element.setOpacity(effect.options.from).show();
-  }}, arguments[1] || { });
-  return new Effect.Opacity(element,options);
-};
-
-Effect.Puff = function(element) {
-  element = $(element);
-  var oldStyle = {
-    opacity: element.getInlineOpacity(),
-    position: element.getStyle('position'),
-    top:  element.style.top,
-    left: element.style.left,
-    width: element.style.width,
-    height: element.style.height
-  };
-  return new Effect.Parallel(
-   [ new Effect.Scale(element, 200,
-      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
-     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
-     Object.extend({ duration: 1.0,
-      beforeSetupInternal: function(effect) {
-        Position.absolutize(effect.effects[0].element);
-      },
-      afterFinishInternal: function(effect) {
-         effect.effects[0].element.hide().setStyle(oldStyle); }
-     }, arguments[1] || { })
-   );
-};
-
-Effect.BlindUp = function(element) {
-  element = $(element);
-  element.makeClipping();
-  return new Effect.Scale(element, 0,
-    Object.extend({ scaleContent: false,
-      scaleX: false,
-      restoreAfterFinish: true,
-      afterFinishInternal: function(effect) {
-        effect.element.hide().undoClipping();
-      }
-    }, arguments[1] || { })
-  );
-};
-
-Effect.BlindDown = function(element) {
-  element = $(element);
-  var elementDimensions = element.getDimensions();
-  return new Effect.Scale(element, 100, Object.extend({
-    scaleContent: false,
-    scaleX: false,
-    scaleFrom: 0,
-    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
-    restoreAfterFinish: true,
-    afterSetup: function(effect) {
-      effect.element.makeClipping().setStyle({height: '0px'}).show();
-    },
-    afterFinishInternal: function(effect) {
-      effect.element.undoClipping();
-    }
-  }, arguments[1] || { }));
-};
-
-Effect.SwitchOff = function(element) {
-  element = $(element);
-  var oldOpacity = element.getInlineOpacity();
-  return new Effect.Appear(element, Object.extend({
-    duration: 0.4,
-    from: 0,
-    transition: Effect.Transitions.flicker,
-    afterFinishInternal: function(effect) {
-      new Effect.Scale(effect.element, 1, {
-        duration: 0.3, scaleFromCenter: true,
-        scaleX: false, scaleContent: false, restoreAfterFinish: true,
-        beforeSetup: function(effect) {
-          effect.element.makePositioned().makeClipping();
-        },
-        afterFinishInternal: function(effect) {
-          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
-        }
-      });
-    }
-  }, arguments[1] || { }));
-};
-
-Effect.DropOut = function(element) {
-  element = $(element);
-  var oldStyle = {
-    top: element.getStyle('top'),
-    left: element.getStyle('left'),
-    opacity: element.getInlineOpacity() };
-  return new Effect.Parallel(
-    [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
-      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
-    Object.extend(
-      { duration: 0.5,
-        beforeSetup: function(effect) {
-          effect.effects[0].element.makePositioned();
-        },
-        afterFinishInternal: function(effect) {
-          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
-        }
-      }, arguments[1] || { }));
-};
-
-Effect.Shake = function(element) {
-  element = $(element);
-  var options = Object.extend({
-    distance: 20,
-    duration: 0.5
-  }, arguments[1] || {});
-  var distance = parseFloat(options.distance);
-  var split = parseFloat(options.duration) / 10.0;
-  var oldStyle = {
-    top: element.getStyle('top'),
-    left: element.getStyle('left') };
-    return new Effect.Move(element,
-      { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
-    new Effect.Move(effect.element,
-      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
-        effect.element.undoPositioned().setStyle(oldStyle);
-  }}); }}); }}); }}); }}); }});
-};
-
-Effect.SlideDown = function(element) {
-  element = $(element).cleanWhitespace();
-  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
-  var oldInnerBottom = element.down().getStyle('bottom');
-  var elementDimensions = element.getDimensions();
-  return new Effect.Scale(element, 100, Object.extend({
-    scaleContent: false,
-    scaleX: false,
-    scaleFrom: window.opera ? 0 : 1,
-    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
-    restoreAfterFinish: true,
-    afterSetup: function(effect) {
-      effect.element.makePositioned();
-      effect.element.down().makePositioned();
-      if (window.opera) effect.element.setStyle({top: ''});
-      effect.element.makeClipping().setStyle({height: '0px'}).show();
-    },
-    afterUpdateInternal: function(effect) {
-      effect.element.down().setStyle({bottom:
-        (effect.dims[0] - effect.element.clientHeight) + 'px' });
-    },
-    afterFinishInternal: function(effect) {
-      effect.element.undoClipping().undoPositioned();
-      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
-    }, arguments[1] || { })
-  );
-};
-
-Effect.SlideUp = function(element) {
-  element = $(element).cleanWhitespace();
-  var oldInnerBottom = element.down().getStyle('bottom');
-  var elementDimensions = element.getDimensions();
-  return new Effect.Scale(element, window.opera ? 0 : 1,
-   Object.extend({ scaleContent: false,
-    scaleX: false,
-    scaleMode: 'box',
-    scaleFrom: 100,
-    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
-    restoreAfterFinish: true,
-    afterSetup: function(effect) {
-      effect.element.makePositioned();
-      effect.element.down().makePositioned();
-      if (window.opera) effect.element.setStyle({top: ''});
-      effect.element.makeClipping().show();
-    },
-    afterUpdateInternal: function(effect) {
-      effect.element.down().setStyle({bottom:
-        (effect.dims[0] - effect.element.clientHeight) + 'px' });
-    },
-    afterFinishInternal: function(effect) {
-      effect.element.hide().undoClipping().undoPositioned();
-      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
-    }
-   }, arguments[1] || { })
-  );
-};
-
-// Bug in opera makes the TD containing this element expand for a instance after finish
-Effect.Squish = function(element) {
-  return new Effect.Scale(element, window.opera ? 1 : 0, {
-    restoreAfterFinish: true,
-    beforeSetup: function(effect) {
-      effect.element.makeClipping();
-    },
-    afterFinishInternal: function(effect) {
-      effect.element.hide().undoClipping();
-    }
-  });
-};
-
-Effect.Grow = function(element) {
-  element = $(element);
-  var options = Object.extend({
-    direction: 'center',
-    moveTransition: Effect.Transitions.sinoidal,
-    scaleTransition: Effect.Transitions.sinoidal,
-    opacityTransition: Effect.Transitions.full
-  }, arguments[1] || { });
-  var oldStyle = {
-    top: element.style.top,
-    left: element.style.left,
-    height: element.style.height,
-    width: element.style.width,
-    opacity: element.getInlineOpacity() };
-
-  var dims = element.getDimensions();
-  var initialMoveX, initialMoveY;
-  var moveX, moveY;
-
-  switch (options.direction) {
-    case 'top-left':
-      initialMoveX = initialMoveY = moveX = moveY = 0;
-      break;
-    case 'top-right':
-      initialMoveX = dims.width;
-      initialMoveY = moveY = 0;
-      moveX = -dims.width;
-      break;
-    case 'bottom-left':
-      initialMoveX = moveX = 0;
-      initialMoveY = dims.height;
-      moveY = -dims.height;
-      break;
-    case 'bottom-right':
-      initialMoveX = dims.width;
-      initialMoveY = dims.height;
-      moveX = -dims.width;
-      moveY = -dims.height;
-      break;
-    case 'center':
-      initialMoveX = dims.width / 2;
-      initialMoveY = dims.height / 2;
-      moveX = -dims.width / 2;
-      moveY = -dims.height / 2;
-      break;
-  }
-
-  return new Effect.Move(element, {
-    x: initialMoveX,
-    y: initialMoveY,
-    duration: 0.01,
-    beforeSetup: function(effect) {
-      effect.element.hide().makeClipping().makePositioned();
-    },
-    afterFinishInternal: function(effect) {
-      new Effect.Parallel(
-        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
-          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
-          new Effect.Scale(effect.element, 100, {
-            scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
-            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
-        ], Object.extend({
-             beforeSetup: function(effect) {
-               effect.effects[0].element.setStyle({height: '0px'}).show();
-             },
-             afterFinishInternal: function(effect) {
-               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
-             }
-           }, options)
-      );
-    }
-  });
-};
-
-Effect.Shrink = function(element) {
-  element = $(element);
-  var options = Object.extend({
-    direction: 'center',
-    moveTransition: Effect.Transitions.sinoidal,
-    scaleTransition: Effect.Transitions.sinoidal,
-    opacityTransition: Effect.Transitions.none
-  }, arguments[1] || { });
-  var oldStyle = {
-    top: element.style.top,
-    left: element.style.left,
-    height: element.style.height,
-    width: element.style.width,
-    opacity: element.getInlineOpacity() };
-
-  var dims = element.getDimensions();
-  var moveX, moveY;
-
-  switch (options.direction) {
-    case 'top-left':
-      moveX = moveY = 0;
-      break;
-    case 'top-right':
-      moveX = dims.width;
-      moveY = 0;
-      break;
-    case 'bottom-left':
-      moveX = 0;
-      moveY = dims.height;
-      break;
-    case 'bottom-right':
-      moveX = dims.width;
-      moveY = dims.height;
-      break;
-    case 'center':
-      moveX = dims.width / 2;
-      moveY = dims.height / 2;
-      break;
-  }
-
-  return new Effect.Parallel(
-    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
-      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
-      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
-    ], Object.extend({
-         beforeStartInternal: function(effect) {
-           effect.effects[0].element.makePositioned().makeClipping();
-         },
-         afterFinishInternal: function(effect) {
-           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
-       }, options)
-  );
-};
-
-Effect.Pulsate = function(element) {
-  element = $(element);
-  var options    = arguments[1] || { },
-    oldOpacity = element.getInlineOpacity(),
-    transition = options.transition || Effect.Transitions.linear,
-    reverser   = function(pos){
-      return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
-    };
-
-  return new Effect.Opacity(element,
-    Object.extend(Object.extend({  duration: 2.0, from: 0,
-      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
-    }, options), {transition: reverser}));
-};
-
-Effect.Fold = function(element) {
-  element = $(element);
-  var oldStyle = {
-    top: element.style.top,
-    left: element.style.left,
-    width: element.style.width,
-    height: element.style.height };
-  element.makeClipping();
-  return new Effect.Scale(element, 5, Object.extend({
-    scaleContent: false,
-    scaleX: false,
-    afterFinishInternal: function(effect) {
-    new Effect.Scale(element, 1, {
-      scaleContent: false,
-      scaleY: false,
-      afterFinishInternal: function(effect) {
-        effect.element.hide().undoClipping().setStyle(oldStyle);
-      } });
-  }}, arguments[1] || { }));
-};
-
-Effect.Morph = Class.create(Effect.Base, {
-  initialize: function(element) {
-    this.element = $(element);
-    if (!this.element) throw(Effect._elementDoesNotExistError);
-    var options = Object.extend({
-      style: { }
-    }, arguments[1] || { });
-
-    if (!Object.isString(options.style)) this.style = $H(options.style);
-    else {
-      if (options.style.include(':'))
-        this.style = options.style.parseStyle();
-      else {
-        this.element.addClassName(options.style);
-        this.style = $H(this.element.getStyles());
-        this.element.removeClassName(options.style);
-        var css = this.element.getStyles();
-        this.style = this.style.reject(function(style) {
-          return style.value == css[style.key];
-        });
-        options.afterFinishInternal = function(effect) {
-          effect.element.addClassName(effect.options.style);
-          effect.transforms.each(function(transform) {
-            effect.element.style[transform.style] = '';
-          });
-        };
-      }
-    }
-    this.start(options);
-  },
-
-  setup: function(){
-    function parseColor(color){
-      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
-      color = color.parseColor();
-      return $R(0,2).map(function(i){
-        return parseInt( color.slice(i*2+1,i*2+3), 16 );
-      });
-    }
-    this.transforms = this.style.map(function(pair){
-      var property = pair[0], value = pair[1], unit = null;
-
-      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
-        value = value.parseColor();
-        unit  = 'color';
-      } else if (property == 'opacity') {
-        value = parseFloat(value);
-        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
-          this.element.setStyle({zoom: 1});
-      } else if (Element.CSS_LENGTH.test(value)) {
-          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
-          value = parseFloat(components[1]);
-          unit = (components.length == 3) ? components[2] : null;
-      }
-
-      var originalValue = this.element.getStyle(property);
-      return {
-        style: property.camelize(),
-        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
-        targetValue: unit=='color' ? parseColor(value) : value,
-        unit: unit
-      };
-    }.bind(this)).reject(function(transform){
-      return (
-        (transform.originalValue == transform.targetValue) ||
-        (
-          transform.unit != 'color' &&
-          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
-        )
-      );
-    });
-  },
-  update: function(position) {
-    var style = { }, transform, i = this.transforms.length;
-    while(i--)
-      style[(transform = this.transforms[i]).style] =
-        transform.unit=='color' ? '#'+
-          (Math.round(transform.originalValue[0]+
-            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
-          (Math.round(transform.originalValue[1]+
-            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
-          (Math.round(transform.originalValue[2]+
-            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
-        (transform.originalValue +
-          (transform.targetValue - transform.originalValue) * position).toFixed(3) +
-            (transform.unit === null ? '' : transform.unit);
-    this.element.setStyle(style, true);
-  }
-});
-
-Effect.Transform = Class.create({
-  initialize: function(tracks){
-    this.tracks  = [];
-    this.options = arguments[1] || { };
-    this.addTracks(tracks);
-  },
-  addTracks: function(tracks){
-    tracks.each(function(track){
-      track = $H(track);
-      var data = track.values().first();
-      this.tracks.push($H({
-        ids:     track.keys().first(),
-        effect:  Effect.Morph,
-        options: { style: data }
-      }));
-    }.bind(this));
-    return this;
-  },
-  play: function(){
-    return new Effect.Parallel(
-      this.tracks.map(function(track){
-        var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
-        var elements = [$(ids) || $$(ids)].flatten();
-        return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
-      }).flatten(),
-      this.options
-    );
-  }
-});
-
-Element.CSS_PROPERTIES = $w(
-  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
-  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
-  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
-  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
-  'fontSize fontWeight height left letterSpacing lineHeight ' +
-  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
-  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
-  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
-  'right textIndent top width wordSpacing zIndex');
-
-Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
-
-String.__parseStyleElement = document.createElement('div');
-String.prototype.parseStyle = function(){
-  var style, styleRules = $H();
-  if (Prototype.Browser.WebKit)
-    style = new Element('div',{style:this}).style;
-  else {
-    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
-    style = String.__parseStyleElement.childNodes[0].style;
-  }
-
-  Element.CSS_PROPERTIES.each(function(property){
-    if (style[property]) styleRules.set(property, style[property]);
-  });
-
-  if (Prototype.Browser.IE && this.include('opacity'))
-    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
-
-  return styleRules;
-};
-
-if (document.defaultView && document.defaultView.getComputedStyle) {
-  Element.getStyles = function(element) {
-    var css = document.defaultView.getComputedStyle($(element), null);
-    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
-      styles[property] = css[property];
-      return styles;
-    });
-  };
-} else {
-  Element.getStyles = function(element) {
-    element = $(element);
-    var css = element.currentStyle, styles;
-    styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
-      results[property] = css[property];
-      return results;
-    });
-    if (!styles.opacity) styles.opacity = element.getOpacity();
-    return styles;
-  };
-}
-
-Effect.Methods = {
-  morph: function(element, style) {
-    element = $(element);
-    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
-    return element;
-  },
-  visualEffect: function(element, effect, options) {
-    element = $(element);
-    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
-    new Effect[klass](element, options);
-    return element;
-  },
-  highlight: function(element, options) {
-    element = $(element);
-    new Effect.Highlight(element, options);
-    return element;
-  }
-};
-
-$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
-  'pulsate shake puff squish switchOff dropOut').each(
-  function(effect) {
-    Effect.Methods[effect] = function(element, options){
-      element = $(element);
-      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
-      return element;
-    };
-  }
-);
-
-$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
-  function(f) { Effect.Methods[f] = Element[f]; }
-);
-
-Element.addMethods(Effect.Methods);
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b2/b2f284009205068a659d0ac9822336c00dcda837.svn-base
--- /dev/null
+++ b/.svn/pristine/b2/b2f284009205068a659d0ac9822336c00dcda837.svn-base
@@ -0,0 +1,2 @@
+function jsToolBar(e){if(!document.createElement){return}if(!e){return}if(typeof document["selection"]=="undefined"&&typeof e["setSelectionRange"]=="undefined"){return}this.textarea=e;this.editor=document.createElement("div");this.editor.className="jstEditor";this.textarea.parentNode.insertBefore(this.editor,this.textarea);this.editor.appendChild(this.textarea);this.toolbar=document.createElement("div");this.toolbar.className="jstElements";this.editor.parentNode.insertBefore(this.toolbar,this.editor);if(this.editor.addEventListener&&navigator.appVersion.match(/\bMSIE\b/)){this.handle=document.createElement("div");this.handle.className="jstHandle";var t=this.resizeDragStart;var n=this;this.handle.addEventListener("mousedown",function(e){t.call(n,e)},false);window.addEventListener("unload",function(){var e=n.handle.parentNode.removeChild(n.handle);delete n.handle},false);this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling)}this.context=null;this.toolNodes={}}function jsButton(e,t,n,r){if(typeof jsToolBar.strings=="undefined"){this.title=e||null}else{this.title=jsToolBar.strings[e]||e||null}this.fn=t||function(){};this.scope=n||null;this.className=r||null}function jsSpace(e){this.id=e||null;this.width=null}function jsCombo(e,t,n,r,i){this.title=e||null;this.options=t||null;this.scope=n||null;this.fn=r||function(){};this.className=i||null}jsButton.prototype.draw=function(){if(!this.scope)return null;var e=document.createElement("button");e.setAttribute("type","button");e.tabIndex=200;if(this.className)e.className=this.className;e.title=this.title;var t=document.createElement("span");t.appendChild(document.createTextNode(this.title));e.appendChild(t);if(this.icon!=undefined){e.style.backgroundImage="url("+this.icon+")"}if(typeof this.fn=="function"){var n=this;e.onclick=function(){try{n.fn.apply(n.scope,arguments)}catch(e){}return false}}return e};jsSpace.prototype.draw=function(){var e=document.createElement("span");if(this.id)e.id=this.id;e.appendChild(document.createTextNode(String.fromCharCode(160)));e.className="jstSpacer";if(this.width)e.style.marginRight=this.width+"px";return e};jsCombo.prototype.draw=function(){if(!this.scope||!this.options)return null;var e=document.createElement("select");if(this.className)e.className=className;e.title=this.title;for(var t in this.options){var n=document.createElement("option");n.value=t;n.appendChild(document.createTextNode(this.options[t]));e.appendChild(n)}var r=this;e.onchange=function(){try{r.fn.call(r.scope,this.value)}catch(e){alert(e)}return false};return e};jsToolBar.prototype={base_url:"",mode:"wiki",elements:{},help_link:"",getMode:function(){return this.mode},setMode:function(e){this.mode=e||"wiki"},switchMode:function(e){e=e||"wiki";this.draw(e)},setHelpLink:function(e){this.help_link=e},button:function(e){var t=this.elements[e];if(typeof t.fn[this.mode]!="function")return null;var n=new jsButton(t.title,t.fn[this.mode],this,"jstb_"+e);if(t.icon!=undefined)n.icon=t.icon;return n},space:function(e){var t=new jsSpace(e);if(this.elements[e].width!==undefined)t.width=this.elements[e].width;return t},combo:function(e){var t=this.elements[e];var n=t[this.mode].list.length;if(typeof t[this.mode].fn!="function"||n==0){return null}else{var r={};for(var i=0;i<n;i++){var s=t[this.mode].list[i];r[s]=t.options[s]}return new jsCombo(t.title,r,this,t[this.mode].fn)}},draw:function(e){this.setMode(e);while(this.toolbar.hasChildNodes()){this.toolbar.removeChild(this.toolbar.firstChild)}this.toolNodes={};var t,n,r;for(var i in this.elements){t=this.elements[i];var s=t.type==undefined||t.type==""||t.disabled!=undefined&&t.disabled||t.context!=undefined&&t.context!=null&&t.context!=this.context;if(!s&&typeof this[t.type]=="function"){n=this[t.type](i);if(n)r=n.draw();if(r){this.toolNodes[i]=r;this.toolbar.appendChild(r)}}}},singleTag:function(e,t){e=e||null;t=t||e;if(!e||!t){return}this.encloseSelection(e,t)},encloseLineSelection:function(e,t,n){this.textarea.focus();e=e||"";t=t||"";var r,i,s,o,u,a;if(typeof document["selection"]!="undefined"){s=document.selection.createRange().text}else if(typeof this.textarea["setSelectionRange"]!="undefined"){r=this.textarea.selectionStart;i=this.textarea.selectionEnd;o=this.textarea.scrollTop;r=this.textarea.value.substring(0,r).replace(/[^\r\n]*$/g,"").length;i=this.textarea.value.length-this.textarea.value.substring(i,this.textarea.value.length).replace(/^[^\r\n]*/,"").length;s=this.textarea.value.substring(r,i)}if(s.match(/ $/)){s=s.substring(0,s.length-1);t=t+" "}if(typeof n=="function"){a=s?n.call(this,s):n("")}else{a=s?s:""}u=e+a+t;if(typeof document["selection"]!="undefined"){document.selection.createRange().text=u;var f=this.textarea.createTextRange();f.collapse(false);f.move("character",-t.length);f.select()}else if(typeof this.textarea["setSelectionRange"]!="undefined"){this.textarea.value=this.textarea.value.substring(0,r)+u+this.textarea.value.substring(i);if(s){this.textarea.setSelectionRange(r+u.length,r+u.length)}else{this.textarea.setSelectionRange(r+e.length,r+e.length)}this.textarea.scrollTop=o}},encloseSelection:function(e,t,n){this.textarea.focus();e=e||"";t=t||"";var r,i,s,o,u,a;if(typeof document["selection"]!="undefined"){s=document.selection.createRange().text}else if(typeof this.textarea["setSelectionRange"]!="undefined"){r=this.textarea.selectionStart;i=this.textarea.selectionEnd;o=this.textarea.scrollTop;s=this.textarea.value.substring(r,i)}if(s.match(/ $/)){s=s.substring(0,s.length-1);t=t+" "}if(typeof n=="function"){a=s?n.call(this,s):n("")}else{a=s?s:""}u=e+a+t;if(typeof document["selection"]!="undefined"){document.selection.createRange().text=u;var f=this.textarea.createTextRange();f.collapse(false);f.move("character",-t.length);f.select()}else if(typeof this.textarea["setSelectionRange"]!="undefined"){this.textarea.value=this.textarea.value.substring(0,r)+u+this.textarea.value.substring(i);if(s){this.textarea.setSelectionRange(r+u.length,r+u.length)}else{this.textarea.setSelectionRange(r+e.length,r+e.length)}this.textarea.scrollTop=o}},stripBaseURL:function(e){if(this.base_url!=""){var t=e.indexOf(this.base_url);if(t==0){e=e.substr(this.base_url.length)}}return e}};jsToolBar.prototype.resizeSetStartH=function(){this.dragStartH=this.textarea.offsetHeight+0};jsToolBar.prototype.resizeDragStart=function(e){var t=this;this.dragStartY=e.clientY;this.resizeSetStartH();document.addEventListener("mousemove",this.dragMoveHdlr=function(e){t.resizeDragMove(e)},false);document.addEventListener("mouseup",this.dragStopHdlr=function(e){t.resizeDragStop(e)},false)};jsToolBar.prototype.resizeDragMove=function(e){this.textarea.style.height=this.dragStartH+e.clientY-this.dragStartY+"px"};jsToolBar.prototype.resizeDragStop=function(e){document.removeEventListener("mousemove",this.dragMoveHdlr,false);document.removeEventListener("mouseup",this.dragStopHdlr,false)};
+jsToolBar.prototype.elements.strong={type:"button",title:"Strong",fn:{wiki:function(){this.singleTag("*")}}};jsToolBar.prototype.elements.em={type:"button",title:"Italic",fn:{wiki:function(){this.singleTag("_")}}};jsToolBar.prototype.elements.ins={type:"button",title:"Underline",fn:{wiki:function(){this.singleTag("+")}}};jsToolBar.prototype.elements.del={type:"button",title:"Deleted",fn:{wiki:function(){this.singleTag("-")}}};jsToolBar.prototype.elements.code={type:"button",title:"Code",fn:{wiki:function(){this.singleTag("@")}}};jsToolBar.prototype.elements.space1={type:"space"};jsToolBar.prototype.elements.h1={type:"button",title:"Heading 1",fn:{wiki:function(){this.encloseLineSelection("h1. ","",function(e){e=e.replace(/^h\d+\.\s+/,"");return e})}}};jsToolBar.prototype.elements.h2={type:"button",title:"Heading 2",fn:{wiki:function(){this.encloseLineSelection("h2. ","",function(e){e=e.replace(/^h\d+\.\s+/,"");return e})}}};jsToolBar.prototype.elements.h3={type:"button",title:"Heading 3",fn:{wiki:function(){this.encloseLineSelection("h3. ","",function(e){e=e.replace(/^h\d+\.\s+/,"");return e})}}};jsToolBar.prototype.elements.space2={type:"space"};jsToolBar.prototype.elements.ul={type:"button",title:"Unordered list",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^)[#-]?\s*/g,"$1* ")})}}};jsToolBar.prototype.elements.ol={type:"button",title:"Ordered list",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^)[*-]?\s*/g,"$1# ")})}}};jsToolBar.prototype.elements.space3={type:"space"};jsToolBar.prototype.elements.bq={type:"button",title:"Quote",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^) *([^\n]*)/g,"$1> $2")})}}};jsToolBar.prototype.elements.unbq={type:"button",title:"Unquote",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^) *[>]? *([^\n]*)/g,"$1$2")})}}};jsToolBar.prototype.elements.pre={type:"button",title:"Preformatted text",fn:{wiki:function(){this.encloseLineSelection("<pre>\n","\n</pre>")}}};jsToolBar.prototype.elements.space4={type:"space"};jsToolBar.prototype.elements.link={type:"button",title:"Wiki link",fn:{wiki:function(){this.encloseSelection("[[","]]")}}};jsToolBar.prototype.elements.img={type:"button",title:"Image",fn:{wiki:function(){this.encloseSelection("!","!")}}};jsToolBar.prototype.elements.space5={type:"space"};jsToolBar.prototype.elements.help={type:"button",title:"Help",fn:{wiki:function(){window.open(this.help_link,"","resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes")}}}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b3/b314740f953a31b89fda7f481071584ad0011ffb.svn-base
--- /dev/null
+++ b/.svn/pristine/b3/b314740f953a31b89fda7f481071584ad0011ffb.svn-base
@@ -0,0 +1,52 @@
+# Default setup is given for MySQL with ruby1.9. If you're running Redmine
+# with MySQL and ruby1.8, replace the adapter name with `mysql`.
+# Examples for PostgreSQL, SQLite3 and SQL Server can be found at the end.
+# Line indentation must be 2 spaces (no tabs).
+
+production:
+  adapter: mysql2
+  database: redmine
+  host: localhost
+  username: root
+  password: ""
+  encoding: utf8
+
+development:
+  adapter: mysql2
+  database: redmine_development
+  host: localhost
+  username: root
+  password: ""
+  encoding: utf8
+
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
+test:
+  adapter: mysql2
+  database: redmine_test
+  host: localhost
+  username: root
+  password: ""
+  encoding: utf8
+
+# PostgreSQL configuration example
+#production:
+#  adapter: postgresql
+#  database: redmine
+#  host: localhost
+#  username: postgres
+#  password: "postgres"
+
+# SQLite3 configuration example
+#production:
+#  adapter: sqlite3
+#  database: db/redmine.sqlite3
+
+# SQL Server configuration example
+#production:
+#  adapter: sqlserver
+#  database: redmine
+#  host: localhost
+#  username: jenkins
+#  password: jenkins
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b3/b333dffc13c9a539e0deff64e8ed8799512cbc7c.svn-base
--- a/.svn/pristine/b3/b333dffc13c9a539e0deff64e8ed8799512cbc7c.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-<% form_for @user, :builder => TabularFormBuilder do |f| %>
-  <%= render :partial => 'form', :locals => { :f => f } %>
-  <% if @user.active? && email_delivery_enabled? -%>
-    <p><label><%= check_box_tag 'send_information', 1, true %> <%= l(:label_send_information) %></label></p>
-  <% end -%>
-  <p><%= submit_tag l(:button_save) %></p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b3/b34008d72f69a2170aed046a9caabca7a17faaac.svn-base
--- /dev/null
+++ b/.svn/pristine/b3/b34008d72f69a2170aed046a9caabca7a17faaac.svn-base
@@ -0,0 +1,1106 @@
+# Danish translation file for standard Ruby on Rails internationalization
+# by Lars Hoeg (http://www.lenio.dk/)
+# updated and upgraded to 0.9 by Morten Krogh Andersen (http://www.krogh.net)
+
+da:
+  direction: ltr
+  date:
+    formats:
+      default: "%d.%m.%Y"
+      short: "%e. %b %Y"
+      long: "%e. %B %Y"
+
+    day_names: [sÃ¸ndag, mandag, tirsdag, onsdag, torsdag, fredag, lÃ¸rdag]
+    abbr_day_names: [sÃ¸, ma, ti, 'on', to, fr, lÃ¸]
+    month_names: [~, januar, februar, marts, april, maj, juni, juli, august, september, oktober, november, december]
+    abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, dec]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%e. %B %Y, %H:%M"
+      time: "%H:%M"
+      short: "%e. %b %Y, %H:%M"
+      long: "%A, %e. %B %Y, %H:%M"
+    am: ""
+    pm: ""
+
+  support:
+    array:
+      sentence_connector: "og"
+      skip_last_comma: true
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "et halvt minut"
+      less_than_x_seconds:
+        one:  "mindre end et sekund"
+        other: "mindre end %{count} sekunder"
+      x_seconds:
+        one:  "et sekund"
+        other: "%{count} sekunder"
+      less_than_x_minutes:
+        one:  "mindre end et minut"
+        other: "mindre end %{count} minutter"
+      x_minutes:
+        one:  "et minut"
+        other: "%{count} minutter"
+      about_x_hours:
+        one:  "cirka en time"
+        other: "cirka %{count} timer"
+      x_hours:
+        one:   "1 time"
+        other: "%{count} timer"
+      x_days:
+        one:  "en dag"
+        other: "%{count} dage"
+      about_x_months:
+        one:  "cirka en mÃ¥ned"
+        other: "cirka %{count} mÃ¥neder"
+      x_months:
+        one:  "en mÃ¥ned"
+        other: "%{count} mÃ¥neder"
+      about_x_years:
+        one:  "cirka et Ã¥r"
+        other: "cirka %{count} Ã¥r"
+      over_x_years:
+        one:  "mere end et Ã¥r"
+        other: "mere end %{count} Ã¥r"
+      almost_x_years:
+        one:   "nÃ¦sten 1 Ã¥r"
+        other: "nÃ¦sten %{count} Ã¥r"
+
+  number:
+    format:
+      separator: ","
+      delimiter: "."
+      precision: 3
+    currency:
+      format:
+        format: "%u %n"
+        unit: "DKK"
+        separator: ","
+        delimiter: "."
+        precision: 2
+    precision:
+      format:
+        # separator:
+        delimiter: ""
+        # precision:
+    human:
+      format:
+        # separator:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+    percentage:
+      format:
+        # separator:
+        delimiter: ""
+        # precision:
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "er ikke i listen"
+        exclusion: "er reserveret"
+        invalid: "er ikke gyldig"
+        confirmation: "stemmer ikke overens"
+        accepted: "skal accepteres"
+        empty: "mÃ¥ ikke udelades"
+        blank: "skal udfyldes"
+        too_long: "er for lang (hÃ¸jst %{count} tegn)"
+        too_short: "er for kort (mindst %{count} tegn)"
+        wrong_length: "har forkert lÃ¦ngde (skulle vÃ¦re %{count} tegn)"
+        taken: "er allerede anvendt"
+        not_a_number: "er ikke et tal"
+        greater_than: "skal vÃ¦re stÃ¸rre end %{count}"
+        greater_than_or_equal_to: "skal vÃ¦re stÃ¸rre end eller lig med %{count}"
+        equal_to: "skal vÃ¦re lig med %{count}"
+        less_than: "skal vÃ¦re mindre end %{count}"
+        less_than_or_equal_to: "skal vÃ¦re mindre end eller lig med %{count}"
+        odd: "skal vÃ¦re ulige"
+        even: "skal vÃ¦re lige"
+        greater_than_start_date: "skal vÃ¦re senere end startdatoen"
+        not_same_project: "hÃ¸rer ikke til samme projekt"
+        circular_dependency: "Denne relation vil skabe et afhÃ¦ngighedsforhold"
+        cant_link_an_issue_with_a_descendant: "En sag kan ikke relateres til en af dens underopgaver"
+
+      template:
+        header:
+          one:   "En fejl forhindrede %{model} i at blive gemt"
+          other:  "%{count} fejl forhindrede denne %{model} i at blive gemt"
+        body: "Der var problemer med fÃ¸lgende felter:"
+
+  actionview_instancetag_blank_option: VÃ¦lg venligst
+
+  general_text_No: 'Nej'
+  general_text_Yes: 'Ja'
+  general_text_no: 'nej'
+  general_text_yes: 'ja'
+  general_lang_name: 'Danish (Dansk)'
+  general_csv_separator: ','
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Kontoen er opdateret.
+  notice_account_invalid_creditentials: Ugyldig bruger og/eller kodeord
+  notice_account_password_updated: Kodeordet er opdateret.
+  notice_account_wrong_password: Forkert kodeord
+  notice_account_register_done: Kontoen er oprettet. For at aktivere kontoen skal du klikke pÃ¥ linket i den tilsendte email.
+  notice_account_unknown_email: Ukendt bruger.
+  notice_can_t_change_password: Denne konto benytter en ekstern sikkerhedsgodkendelse. Det er ikke muligt at skifte kodeord.
+  notice_account_lost_email_sent: En email med instruktioner til at vÃ¦lge et nyt kodeord er afsendt til dig.
+  notice_account_activated: Din konto er aktiveret. Du kan nu logge ind.
+  notice_successful_create: Succesfuld oprettelse.
+  notice_successful_update: Succesfuld opdatering.
+  notice_successful_delete: Succesfuld sletning.
+  notice_successful_connection: Succesfuld forbindelse.
+  notice_file_not_found: Siden du forsÃ¸ger at tilgÃ¥ eksisterer ikke eller er blevet fjernet.
+  notice_locking_conflict: Data er opdateret af en anden bruger.
+  notice_not_authorized: Du har ikke adgang til denne side.
+  notice_email_sent: "En email er sendt til %{value}"
+  notice_email_error: "En fejl opstod under afsendelse af email (%{value})"
+  notice_feeds_access_key_reseted: Din adgangsnÃ¸gle til RSS er nulstillet.
+  notice_failed_to_save_issues: "Det mislykkedes at gemme %{count} sage(r) pÃ¥ %{total} valgt: %{ids}."
+  notice_no_issue_selected: "Ingen sag er valgt! VÃ¦lg venligst hvilke emner du vil rette."
+  notice_account_pending: "Din konto er oprettet, og afventer administrators godkendelse."
+  notice_default_data_loaded: StandardopsÃ¦tningen er indlÃ¦st.
+
+  error_can_t_load_default_data: "StandardopsÃ¦tning kunne ikke indlÃ¦ses: %{value}"
+  error_scm_not_found: "Adgang nÃ¦gtet og/eller revision blev ikke fundet i det valgte repository."
+  error_scm_command_failed: "En fejl opstod under forbindelsen til det valgte repository: %{value}"
+
+  mail_subject_lost_password: "Dit %{value} kodeord"
+  mail_body_lost_password: 'Klik pÃ¥ dette link for at Ã¦ndre dit kodeord:'
+  mail_subject_register: "%{value} kontoaktivering"
+  mail_body_register: 'Klik pÃ¥ dette link for at aktivere din konto:'
+  mail_body_account_information_external: "Du kan bruge din %{value} konto til at logge ind."
+  mail_body_account_information: Din kontoinformation
+  mail_subject_account_activation_request: "%{value} kontoaktivering"
+  mail_body_account_activation_request: "En ny bruger (%{value}) er registreret. Godkend venligst kontoen:"
+
+
+  field_name: Navn
+  field_description: Beskrivelse
+  field_summary: Sammenfatning
+  field_is_required: Skal udfyldes
+  field_firstname: Fornavn
+  field_lastname: Efternavn
+  field_mail: Email
+  field_filename: Fil
+  field_filesize: StÃ¸rrelse
+  field_downloads: Downloads
+  field_author: Forfatter
+  field_created_on: Oprettet
+  field_updated_on: Opdateret
+  field_field_format: Format
+  field_is_for_all: For alle projekter
+  field_possible_values: Mulige vÃ¦rdier
+  field_regexp: RegulÃ¦re udtryk
+  field_min_length: Mindste lÃ¦ngde
+  field_max_length: StÃ¸rste lÃ¦ngde
+  field_value: VÃ¦rdi
+  field_category: Kategori
+  field_title: Titel
+  field_project: Projekt
+  field_issue: Sag
+  field_status: Status
+  field_notes: Noter
+  field_is_closed: Sagen er lukket
+  field_is_default: StandardvÃ¦rdi
+  field_tracker: Type
+  field_subject: Emne
+  field_due_date: Deadline
+  field_assigned_to: Tildelt til
+  field_priority: Prioritet
+  field_fixed_version: Udgave
+  field_user: Bruger
+  field_role: Rolle
+  field_homepage: Hjemmeside
+  field_is_public: Offentlig
+  field_parent: Underprojekt af
+  field_is_in_roadmap: Sager vist i roadmap
+  field_login: Login
+  field_mail_notification: Email-pÃ¥mindelser
+  field_admin: Administrator
+  field_last_login_on: Sidste forbindelse
+  field_language: Sprog
+  field_effective_date: Dato
+  field_password: Kodeord
+  field_new_password: Nyt kodeord
+  field_password_confirmation: BekrÃ¦ft
+  field_version: Version
+  field_type: Type
+  field_host: VÃ¦rt
+  field_port: Port
+  field_account: Kode
+  field_base_dn: Base DN
+  field_attr_login: Login attribut
+  field_attr_firstname: Fornavn attribut
+  field_attr_lastname: Efternavn attribut
+  field_attr_mail: Email attribut
+  field_onthefly: lÃ¸bende brugeroprettelse
+  field_start_date: Start dato
+  field_done_ratio: "% fÃ¦rdig"
+  field_auth_source: Sikkerhedsmetode
+  field_hide_mail: Skjul min email
+  field_comments: Kommentar
+  field_url: URL
+  field_start_page: Startside
+  field_subproject: Underprojekt
+  field_hours: Timer
+  field_activity: Aktivitet
+  field_spent_on: Dato
+  field_identifier: Identifikator
+  field_is_filter: Brugt som et filter
+  field_issue_to: BeslÃ¦gtede sag
+  field_delay: UdsÃ¦ttelse
+  field_assignable: Sager kan tildeles denne rolle
+  field_redirect_existing_links: Videresend eksisterende links
+  field_estimated_hours: AnslÃ¥et tid
+  field_column_names: Kolonner
+  field_time_zone: Tidszone
+  field_searchable: SÃ¸gbar
+  field_default_value: StandardvÃ¦rdi
+
+  setting_app_title: Applikationstitel
+  setting_app_subtitle: Applikationsundertekst
+  setting_welcome_text: Velkomsttekst
+  setting_default_language: Standardsporg
+  setting_login_required: Sikkerhed pÃ¥krÃ¦vet
+  setting_self_registration: Brugeroprettelse
+  setting_attachment_max_size: VedhÃ¦ftede filers max stÃ¸rrelse
+  setting_issues_export_limit: SagseksporteringsbegrÃ¦nsning
+  setting_mail_from: Afsender-email
+  setting_bcc_recipients: Skjult modtager (bcc)
+  setting_host_name: VÃ¦rtsnavn
+  setting_text_formatting: Tekstformatering
+  setting_wiki_compression: Komprimering af wiki-historik
+  setting_feeds_limit: Feed indholdsbegrÃ¦nsning
+  setting_autofetch_changesets: Hent automatisk commits
+  setting_sys_api_enabled: Aktiver webservice for automatisk administration af repository
+  setting_commit_ref_keywords: ReferencenÃ¸gleord
+  setting_commit_fix_keywords: AfslutningsnÃ¸gleord
+  setting_autologin: Automatisk login
+  setting_date_format: Datoformat
+  setting_time_format: Tidsformat
+  setting_cross_project_issue_relations: Tillad sagsrelationer pÃ¥ tvÃ¦rs af projekter
+  setting_issue_list_default_columns: Standardkolonner pÃ¥ sagslisten
+  setting_emails_footer: Email-fodnote
+  setting_protocol: Protokol
+  setting_user_format: Brugervisningsformat
+
+  project_module_issue_tracking: SagssÃ¸gning
+  project_module_time_tracking: Tidsstyring
+  project_module_news: Nyheder
+  project_module_documents: Dokumenter
+  project_module_files: Filer
+  project_module_wiki: Wiki
+  project_module_repository: Repository
+  project_module_boards: Fora
+
+  label_user: Bruger
+  label_user_plural: Brugere
+  label_user_new: Ny bruger
+  label_project: Projekt
+  label_project_new: Nyt projekt
+  label_project_plural: Projekter
+  label_x_projects:
+    zero:  Ingen projekter
+    one:   1 projekt
+    other: "%{count} projekter"
+  label_project_all: Alle projekter
+  label_project_latest: Seneste projekter
+  label_issue: Sag
+  label_issue_new: Opret sag
+  label_issue_plural: Sager
+  label_issue_view_all: Vis alle sager
+  label_issues_by: "Sager fra %{value}"
+  label_issue_added: Sagen er oprettet
+  label_issue_updated: Sagen er opdateret
+  label_document: Dokument
+  label_document_new: Nyt dokument
+  label_document_plural: Dokumenter
+  label_document_added: Dokument tilfÃ¸jet
+  label_role: Rolle
+  label_role_plural: Roller
+  label_role_new: Ny rolle
+  label_role_and_permissions: Roller og rettigheder
+  label_member: Medlem
+  label_member_new: Nyt medlem
+  label_member_plural: Medlemmer
+  label_tracker: Type
+  label_tracker_plural: Typer
+  label_tracker_new: Ny type
+  label_workflow: Arbejdsgang
+  label_issue_status: Sagsstatus
+  label_issue_status_plural: Sagsstatusser
+  label_issue_status_new: Ny status
+  label_issue_category: Sagskategori
+  label_issue_category_plural: Sagskategorier
+  label_issue_category_new: Ny kategori
+  label_custom_field: Brugerdefineret felt
+  label_custom_field_plural: Brugerdefinerede felter
+  label_custom_field_new: Nyt brugerdefineret felt
+  label_enumerations: VÃ¦rdier
+  label_enumeration_new: Ny vÃ¦rdi
+  label_information: Information
+  label_information_plural: Information
+  label_please_login: Login
+  label_register: RegistrÃ©r
+  label_password_lost: Glemt kodeord
+  label_home: Forside
+  label_my_page: Min side
+  label_my_account: Min konto
+  label_my_projects: Mine projekter
+  label_administration: Administration
+  label_login: Log ind
+  label_logout: Log ud
+  label_help: HjÃ¦lp
+  label_reported_issues: Rapporterede sager
+  label_assigned_to_me_issues: Sager tildelt til mig
+  label_last_login: Sidste logintidspunkt
+  label_registered_on: Registreret den
+  label_activity: Aktivitet
+  label_new: Ny
+  label_logged_as: Registreret som
+  label_environment: MiljÃ¸
+  label_authentication: Sikkerhed
+  label_auth_source: Sikkerhedsmetode
+  label_auth_source_new: Ny sikkerhedsmetode
+  label_auth_source_plural: Sikkerhedsmetoder
+  label_subproject_plural: Underprojekter
+  label_min_max_length: Min - Max lÃ¦ngde
+  label_list: Liste
+  label_date: Dato
+  label_integer: Heltal
+  label_float: Kommatal
+  label_boolean: Sand/falsk
+  label_string: Tekst
+  label_text: Lang tekst
+  label_attribute: Attribut
+  label_attribute_plural: Attributter
+  label_no_data: Ingen data at vise
+  label_change_status: Ã†ndringsstatus
+  label_history: Historik
+  label_attachment: Fil
+  label_attachment_new: Ny fil
+  label_attachment_delete: Slet fil
+  label_attachment_plural: Filer
+  label_file_added: Fil tilfÃ¸jet
+  label_report: Rapport
+  label_report_plural: Rapporter
+  label_news: Nyheder
+  label_news_new: TilfÃ¸j nyheder
+  label_news_plural: Nyheder
+  label_news_latest: Seneste nyheder
+  label_news_view_all: Vis alle nyheder
+  label_news_added: Nyhed tilfÃ¸jet
+  label_settings: Indstillinger
+  label_overview: Oversigt
+  label_version: Udgave
+  label_version_new: Ny udgave
+  label_version_plural: Udgaver
+  label_confirmation: BekrÃ¦ftelser
+  label_export_to: Eksporter til
+  label_read: LÃ¦s...
+  label_public_projects: Offentlige projekter
+  label_open_issues: Ã¥ben
+  label_open_issues_plural: Ã¥bne
+  label_closed_issues: lukket
+  label_closed_issues_plural: lukkede
+  label_x_open_issues_abbr_on_total:
+    zero:  0 Ã¥bne / %{total}
+    one:   1 Ã¥ben / %{total}
+    other: "%{count} Ã¥bne / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 Ã¥bne
+    one:   1 Ã¥ben
+    other: "%{count} Ã¥bne"
+  label_x_closed_issues_abbr:
+    zero:  0 lukkede
+    one:   1 lukket
+    other: "%{count} lukkede"
+  label_total: Total
+  label_permissions: Rettigheder
+  label_current_status: NuvÃ¦rende status
+  label_new_statuses_allowed: Ny status tilladt
+  label_all: alle
+  label_none: intet
+  label_nobody: ingen
+  label_next: NÃ¦ste
+  label_previous: Forrige
+  label_used_by: Brugt af
+  label_details: Detaljer
+  label_add_note: TilfÃ¸j note
+  label_per_page: Pr. side
+  label_calendar: Kalender
+  label_months_from: mÃ¥neder frem
+  label_gantt: Gantt
+  label_internal: Intern
+  label_last_changes: "sidste %{count} Ã¦ndringer"
+  label_change_view_all: Vis alle Ã¦ndringer
+  label_personalize_page: Tilret denne side
+  label_comment: Kommentar
+  label_comment_plural: Kommentarer
+  label_x_comments:
+    zero: ingen kommentarer
+    one: 1 kommentar
+    other: "%{count} kommentarer"
+  label_comment_add: TilfÃ¸j en kommentar
+  label_comment_added: Kommentaren er tilfÃ¸jet
+  label_comment_delete: Slet kommentar
+  label_query: Brugerdefineret forespÃ¸rgsel
+  label_query_plural: Brugerdefinerede forespÃ¸rgsler
+  label_query_new: Ny forespÃ¸rgsel
+  label_filter_add: TilfÃ¸j filter
+  label_filter_plural: Filtre
+  label_equals: er
+  label_not_equals: er ikke
+  label_in_less_than: er mindre end
+  label_in_more_than: er stÃ¸rre end
+  label_in: indeholdt i
+  label_today: i dag
+  label_all_time: altid
+  label_yesterday: i gÃ¥r
+  label_this_week: denne uge
+  label_last_week: sidste uge
+  label_last_n_days: "sidste %{count} dage"
+  label_this_month: denne mÃ¥ned
+  label_last_month: sidste mÃ¥ned
+  label_this_year: dette Ã¥r
+  label_date_range: Dato interval
+  label_less_than_ago: mindre end dage siden
+  label_more_than_ago: mere end dage siden
+  label_ago: dage siden
+  label_contains: indeholder
+  label_not_contains: ikke indeholder
+  label_day_plural: dage
+  label_repository: Repository
+  label_repository_plural: Repositories
+  label_browse: Gennemse
+  label_revision: Revision
+  label_revision_plural: Revisioner
+  label_associated_revisions: Tilknyttede revisioner
+  label_added: tilfÃ¸jet
+  label_modified: Ã¦ndret
+  label_deleted: slettet
+  label_latest_revision: Seneste revision
+  label_latest_revision_plural: Seneste revisioner
+  label_view_revisions: Se revisioner
+  label_max_size: Maksimal stÃ¸rrelse
+  label_sort_highest: Flyt til toppen
+  label_sort_higher: Flyt op
+  label_sort_lower: Flyt ned
+  label_sort_lowest: Flyt til bunden
+  label_roadmap: Roadmap
+  label_roadmap_due_in: Deadline
+  label_roadmap_overdue: "%{value} forsinket"
+  label_roadmap_no_issues: Ingen sager i denne version
+  label_search: SÃ¸g
+  label_result_plural: Resultater
+  label_all_words: Alle ord
+  label_wiki: Wiki
+  label_wiki_edit: Wiki Ã¦ndring
+  label_wiki_edit_plural: Wiki Ã¦ndringer
+  label_wiki_page: Wiki side
+  label_wiki_page_plural: Wiki sider
+  label_index_by_title: Indhold efter titel
+  label_index_by_date: Indhold efter dato
+  label_current_version: NuvÃ¦rende version
+  label_preview: ForhÃ¥ndsvisning
+  label_feed_plural: Feeds
+  label_changes_details: Detaljer for alle Ã¦ndringer
+  label_issue_tracking: SagssÃ¸gning
+  label_spent_time: Anvendt tid
+  label_f_hour: "%{value} time"
+  label_f_hour_plural: "%{value} timer"
+  label_time_tracking: Tidsstyring
+  label_change_plural: Ã†ndringer
+  label_statistics: Statistik
+  label_commits_per_month: Commits pr. mÃ¥ned
+  label_commits_per_author: Commits pr. bruger
+  label_view_diff: Vis forskelle
+  label_diff_inline: inline
+  label_diff_side_by_side: side om side
+  label_options: Formatering
+  label_copy_workflow_from: Kopier arbejdsgang fra
+  label_permissions_report: Godkendelsesrapport
+  label_watched_issues: OvervÃ¥gede sager
+  label_related_issues: Relaterede sager
+  label_applied_status: Anvendte statusser
+  label_loading: IndlÃ¦ser...
+  label_relation_new: Ny relation
+  label_relation_delete: Slet relation
+  label_relates_to: relaterer til
+  label_duplicates: duplikater
+  label_blocks: blokerer
+  label_blocked_by: blokeret af
+  label_precedes: kommer fÃ¸r
+  label_follows: fÃ¸lger
+  label_end_to_start: slut til start
+  label_end_to_end: slut til slut
+  label_start_to_start: start til start
+  label_start_to_end: start til slut
+  label_stay_logged_in: Forbliv indlogget
+  label_disabled: deaktiveret
+  label_show_completed_versions: Vis fÃ¦rdige versioner
+  label_me: mig
+  label_board: Forum
+  label_board_new: Nyt forum
+  label_board_plural: Fora
+  label_topic_plural: Emner
+  label_message_plural: Beskeder
+  label_message_last: Sidste besked
+  label_message_new: Ny besked
+  label_message_posted: Besked tilfÃ¸jet
+  label_reply_plural: Besvarer
+  label_send_information: Send konto information til bruger
+  label_year: Ã…r
+  label_month: MÃ¥ned
+  label_week: Uge
+  label_date_from: Fra
+  label_date_to: Til
+  label_language_based: Baseret pÃ¥ brugerens sprog
+  label_sort_by: "SortÃ©r efter %{value}"
+  label_send_test_email: Send en test email
+  label_feeds_access_key_created_on: "RSS adgangsnÃ¸gle dannet for %{value} siden"
+  label_module_plural: Moduler
+  label_added_time_by: "TilfÃ¸jet af %{author} for %{age} siden"
+  label_updated_time: "Opdateret for %{value} siden"
+  label_jump_to_a_project: Skift til projekt...
+  label_file_plural: Filer
+  label_changeset_plural: Ã†ndringer
+  label_default_columns: Standardkolonner
+  label_no_change_option: (Ingen Ã¦ndringer)
+  label_bulk_edit_selected_issues: Masse-ret de valgte sager
+  label_theme: Tema
+  label_default: standard
+  label_search_titles_only: SÃ¸g kun i titler
+  label_user_mail_option_all: "For alle hÃ¦ndelser pÃ¥ mine projekter"
+  label_user_mail_option_selected: "For alle hÃ¦ndelser pÃ¥ de valgte projekter..."
+  label_user_mail_no_self_notified: "Jeg Ã¸nsker ikke besked om Ã¦ndring foretaget af mig selv"
+  label_registration_activation_by_email: kontoaktivering pÃ¥ email
+  label_registration_manual_activation: manuel kontoaktivering
+  label_registration_automatic_activation: automatisk kontoaktivering
+  label_display_per_page: "Per side: %{value}"
+  label_age: Alder
+  label_change_properties: Ã†ndre indstillinger
+  label_general: Generelt
+  label_more: Mere
+  label_scm: SCM
+  label_plugins: Plugins
+  label_ldap_authentication: LDAP-godkendelse
+  label_downloads_abbr: D/L
+
+  button_login: Login
+  button_submit: Send
+  button_save: Gem
+  button_check_all: VÃ¦lg alt
+  button_uncheck_all: FravÃ¦lg alt
+  button_delete: Slet
+  button_create: Opret
+  button_test: Test
+  button_edit: Ret
+  button_add: TilfÃ¸j
+  button_change: Ã†ndre
+  button_apply: Anvend
+  button_clear: Nulstil
+  button_lock: LÃ¥s
+  button_unlock: LÃ¥s op
+  button_download: Download
+  button_list: List
+  button_view: Vis
+  button_move: Flyt
+  button_back: Tilbage
+  button_cancel: AnnullÃ©r
+  button_activate: AktivÃ©r
+  button_sort: SortÃ©r
+  button_log_time: Log tid
+  button_rollback: TilbagefÃ¸r til denne version
+  button_watch: OvervÃ¥g
+  button_unwatch: Stop overvÃ¥gning
+  button_reply: Besvar
+  button_archive: ArkivÃ©r
+  button_unarchive: Fjern fra arkiv
+  button_reset: Nulstil
+  button_rename: OmdÃ¸b
+  button_change_password: Skift kodeord
+  button_copy: KopiÃ©r
+  button_annotate: AnnotÃ©r
+  button_update: OpdatÃ©r
+  button_configure: KonfigurÃ©r
+
+  status_active: aktiv
+  status_registered: registreret
+  status_locked: lÃ¥st
+
+  text_select_mail_notifications: VÃ¦lg handlinger der skal sendes email besked for.
+  text_regexp_info: f.eks. ^[A-ZÃ†Ã˜Ã…0-9]+$
+  text_min_max_length_info: 0 betyder ingen begrÃ¦nsninger
+  text_project_destroy_confirmation: Er du sikker pÃ¥ at du vil slette dette projekt og alle relaterede data?
+  text_workflow_edit: VÃ¦lg en rolle samt en type, for at redigere arbejdsgangen
+  text_are_you_sure: Er du sikker?
+  text_tip_issue_begin_day: opgaven begynder denne dag
+  text_tip_issue_end_day: opaven slutter denne dag
+  text_tip_issue_begin_end_day: opgaven begynder og slutter denne dag
+  text_caracters_maximum: "max %{count} karakterer."
+  text_caracters_minimum: "Skal vÃ¦re mindst %{count} karakterer lang."
+  text_length_between: "LÃ¦ngde skal vÃ¦re mellem %{min} og %{max} karakterer."
+  text_tracker_no_workflow: Ingen arbejdsgang defineret for denne type
+  text_unallowed_characters: Ikke-tilladte karakterer
+  text_comma_separated: Adskillige vÃ¦rdier tilladt (adskilt med komma).
+  text_issues_ref_in_commit_messages: Referer og lÃ¸ser sager i commit-beskeder
+  text_issue_added: "Sag %{id} er rapporteret af %{author}."
+  text_issue_updated: "Sag %{id} er blevet opdateret af %{author}."
+  text_wiki_destroy_confirmation: Er du sikker pÃ¥ at du vil slette denne wiki og dens indhold?
+  text_issue_category_destroy_question: "Nogle sager (%{count}) er tildelt denne kategori. Hvad Ã¸nsker du at gÃ¸re?"
+  text_issue_category_destroy_assignments: Slet tildelinger af kategori
+  text_issue_category_reassign_to: Tildel sager til denne kategori
+  text_user_mail_option: "For ikke-valgte projekter vil du kun modtage beskeder omhandlende ting du er involveret i eller overvÃ¥ger (f.eks. sager du har indberettet eller ejer)."
+  text_no_configuration_data: "Roller, typer, sagsstatusser og arbejdsgange er endnu ikke konfigureret.\nDet er anbefalet at indlÃ¦se standardopsÃ¦tningen. Du vil kunne Ã¦ndre denne nÃ¥r den er indlÃ¦st."
+  text_load_default_configuration: IndlÃ¦s standardopsÃ¦tningen
+  text_status_changed_by_changeset: "Anvendt i Ã¦ndring %{value}."
+  text_issues_destroy_confirmation: 'Er du sikker pÃ¥ du Ã¸nsker at slette den/de valgte sag(er)?'
+  text_select_project_modules: 'VÃ¦lg moduler er skal vÃ¦re aktiveret for dette projekt:'
+  text_default_administrator_account_changed: Standardadministratorkonto Ã¦ndret
+  text_file_repository_writable: Filarkiv er skrivbar
+  text_rmagick_available: RMagick tilgÃ¦ngelig (valgfri)
+
+  default_role_manager: Leder
+  default_role_developer: Udvikler
+  default_role_reporter: RapportÃ¸r
+  default_tracker_bug: Fejl
+  default_tracker_feature: Funktion
+  default_tracker_support: Support
+  default_issue_status_new: Ny
+  default_issue_status_in_progress: IgangvÃ¦rende
+  default_issue_status_resolved: LÃ¸st
+  default_issue_status_feedback: Feedback
+  default_issue_status_closed: Lukket
+  default_issue_status_rejected: Afvist
+  default_doc_category_user: Brugerdokumentation
+  default_doc_category_tech: Teknisk dokumentation
+  default_priority_low: Lav
+  default_priority_normal: Normal
+  default_priority_high: HÃ¸j
+  default_priority_urgent: Akut
+  default_priority_immediate: OmgÃ¥ende
+  default_activity_design: Design
+  default_activity_development: Udvikling
+
+  enumeration_issue_priorities: Sagsprioriteter
+  enumeration_doc_categories: Dokumentkategorier
+  enumeration_activities: Aktiviteter (tidsstyring)
+
+  label_add_another_file: TilfÃ¸j endnu en fil
+  label_chronological_order: I kronologisk rÃ¦kkefÃ¸lge
+  setting_activity_days_default: Antal dage der vises under projektaktivitet
+  text_destroy_time_entries_question: "%{hours} timer er registreret pÃ¥ denne sag som du er ved at slette. Hvad vil du gÃ¸re?"
+  error_issue_not_found_in_project: 'Sagen blev ikke fundet eller tilhÃ¸rer ikke dette projekt'
+  text_assign_time_entries_to_project: Tildel raporterede timer til projektet
+  setting_display_subprojects_issues: Vis sager for underprojekter pÃ¥ hovedprojektet som standard
+  label_optional_description: Valgfri beskrivelse
+  text_destroy_time_entries: Slet registrerede timer
+  field_comments_sorting: Vis kommentar
+  text_reassign_time_entries: 'Tildel registrerede timer til denne sag igen'
+  label_reverse_chronological_order: I omvendt kronologisk rÃ¦kkefÃ¸lge
+  label_preferences: PrÃ¦ferencer
+  label_overall_activity: Overordnet aktivitet
+  setting_default_projects_public: Nye projekter er offentlige som standard
+  error_scm_annotate: "Filen findes ikke, eller kunne ikke annoteres."
+  label_planning: PlanlÃ¦gning
+  text_subprojects_destroy_warning: "Dets underprojekter(er): %{value} vil ogsÃ¥ blive slettet."
+  permission_edit_issues: RedigÃ©r sager
+  setting_diff_max_lines_displayed: HÃ¸jeste antal forskelle der vises
+  permission_edit_own_issue_notes: RedigÃ©r egne noter
+  setting_enabled_scm: Aktiveret SCM
+  button_quote: CitÃ©r
+  permission_view_files: Se filer
+  permission_add_issues: TilfÃ¸j sager
+  permission_edit_own_messages: RedigÃ©r egne beskeder
+  permission_delete_own_messages: Slet egne beskeder
+  permission_manage_public_queries: AdministrÃ©r offentlig forespÃ¸rgsler
+  permission_log_time: RegistrÃ©r anvendt tid
+  label_renamed: omdÃ¸bt
+  label_incoming_emails: Indkommende emails
+  permission_view_changesets: Se Ã¦ndringer
+  permission_manage_versions: AdministrÃ©r versioner
+  permission_view_time_entries: Se anvendt tid
+  label_generate_key: GenerÃ©r en nÃ¸glefil
+  permission_manage_categories: AdministrÃ©r sagskategorier
+  permission_manage_wiki: AdministrÃ©r wiki
+  setting_sequential_project_identifiers: GenerÃ©r sekventielle projekt-identifikatorer
+  setting_plain_text_mail: Emails som almindelig tekst (ingen HTML)
+  field_parent_title: Siden over
+  text_email_delivery_not_configured: "Email-afsendelse er ikke indstillet og notifikationer er defor slÃ¥et fra.\nKonfigurÃ©r din SMTP server i config/configuration.yml og genstart applikationen for at aktivere email-afsendelse."
+  permission_protect_wiki_pages: Beskyt wiki sider
+  permission_add_issue_watchers: TilfÃ¸j overvÃ¥gere
+  warning_attachments_not_saved: "der var %{count} fil(er), som ikke kunne gemmes."
+  permission_comment_news: KommentÃ©r nyheder
+  text_enumeration_category_reassign_to: 'Flyt dem til denne vÃ¦rdi:'
+  permission_select_project_modules: VÃ¦lg projektmoduler
+  permission_view_gantt: Se Gantt diagram
+  permission_delete_messages: Slet beskeder
+  permission_move_issues: Flyt sager
+  permission_edit_wiki_pages: RedigÃ©r wiki sider
+  label_user_activity: "%{value}'s aktivitet"
+  permission_manage_issue_relations: AdministrÃ©r sags-relationer
+  label_issue_watchers: OvervÃ¥gere
+  permission_delete_wiki_pages: Slet wiki sider
+  notice_unable_delete_version: Kan ikke slette versionen.
+  permission_view_wiki_edits: Se wiki historik
+  field_editable: RedigÃ©rbar
+  label_duplicated_by: dubleret af
+  permission_manage_boards: AdministrÃ©r fora
+  permission_delete_wiki_pages_attachments: Slet filer vedhÃ¦ftet wiki sider
+  permission_view_messages: Se beskeder
+  text_enumeration_destroy_question: "%{count} objekter er tildelt denne vÃ¦rdi."
+  permission_manage_files: AdministrÃ©r filer
+  permission_add_messages: Opret beskeder
+  permission_edit_issue_notes: RedigÃ©r noter
+  permission_manage_news: AdministrÃ©r nyheder
+  text_plugin_assets_writable: Der er skriverettigheder til plugin assets folderen
+  label_display: Vis
+  label_and_its_subprojects: "%{value} og dets underprojekter"
+  permission_view_calendar: Se kalender
+  button_create_and_continue: Opret og fortsÃ¦t
+  setting_gravatar_enabled: Anvend Gravatar brugerikoner
+  label_updated_time_by: "Opdateret af %{author} for %{age} siden"
+  text_diff_truncated: '... Listen over forskelle er blevet afkortet da den overstiger den maksimale stÃ¸rrelse der kan vises.'
+  text_user_wrote: "%{value} skrev:"
+  setting_mail_handler_api_enabled: Aktiver webservice for indkomne emails
+  permission_delete_issues: Slet sager
+  permission_view_documents: Se dokumenter
+  permission_browse_repository: Gennemse repository
+  permission_manage_repository: AdministrÃ©r repository
+  permission_manage_members: AdministrÃ©r medlemmer
+  mail_subject_reminder: "%{count} sag(er) har deadline i de kommende dage (%{days})"
+  permission_add_issue_notes: TilfÃ¸j noter
+  permission_edit_messages: RedigÃ©r beskeder
+  permission_view_issue_watchers: Se liste over overvÃ¥gere
+  permission_commit_access: Commit adgang
+  setting_mail_handler_api_key: API nÃ¸gle
+  label_example: Eksempel
+  permission_rename_wiki_pages: OmdÃ¸b wiki sider
+  text_custom_field_possible_values_info: 'En linje for hver vÃ¦rdi'
+  permission_view_wiki_pages: Se wiki
+  permission_edit_project: RedigÃ©r projekt
+  permission_save_queries: Gem forespÃ¸rgsler
+  label_copied: kopieret
+  text_repository_usernames_mapping: "VÃ¦lg eller opdatÃ©r de Redmine brugere der svarer til de enkelte brugere fundet i repository loggen.\nBrugere med samme brugernavn eller email adresse i bÃ¥de Redmine og det valgte repository bliver automatisk koblet sammen."
+  permission_edit_time_entries: RedigÃ©r tidsregistreringer
+  general_csv_decimal_separator: ','
+  permission_edit_own_time_entries: RedigÃ©r egne tidsregistreringer
+  setting_repository_log_display_limit: HÃ¸jeste antal revisioner vist i fil-log
+  setting_file_max_size_displayed: Maksimale stÃ¸rrelse pÃ¥ tekstfiler vist inline
+  field_watcher: OvervÃ¥ger
+  setting_openid: Tillad OpenID login og registrering
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: eller login med OpenID
+  setting_per_page_options: Enheder per side muligheder
+  mail_body_reminder: "%{count} sage(er) som er tildelt dig har deadline indenfor de nÃ¦ste %{days} dage:"
+  field_content: Indhold
+  label_descending: Aftagende
+  label_sort: SortÃ©r
+  label_ascending: Tiltagende
+  label_date_from_to: Fra %{start} til %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Denne side har %{descendants} underside(r) og afledte. Hvad vil du gÃ¸re?
+  text_wiki_page_reassign_children: Flyt undersider til denne side
+  text_wiki_page_nullify_children: Behold undersider som rod-sider
+  text_wiki_page_destroy_children: Slet undersider ogalle deres afledte sider.
+  setting_password_min_length: Mindste lÃ¦ngde pÃ¥ kodeord
+  field_group_by: GruppÃ©r resultater efter
+  mail_subject_wiki_content_updated: "'%{id}' wikisiden er blevet opdateret"
+  label_wiki_content_added: Wiki side tilfÃ¸jet
+  mail_subject_wiki_content_added: "'%{id}' wikisiden er blevet tilfÃ¸jet"
+  mail_body_wiki_content_added: The '%{id}' wikiside er blevet tilfÃ¸jet af %{author}.
+  label_wiki_content_updated: Wikiside opdateret
+  mail_body_wiki_content_updated: Wikisiden '%{id}' er blevet opdateret af %{author}.
+  permission_add_project: Opret projekt
+  setting_new_project_user_role_id: Denne rolle gives til en bruger, som ikke er administrator, og som opretter et projekt
+  label_view_all_revisions: Se alle revisioner
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: Der er ingen sagshÃ¥ndtering for dette projekt. KontrollÃ©r venligst projektindstillingerne.
+  error_no_default_issue_status: Der er ikke defineret en standardstatus. KontrollÃ©r venligst indstillingerne (gÃ¥ til "Administration -> Sagsstatusser").
+  text_journal_changed: "%{label} Ã¦ndret fra %{old} til %{new}"
+  text_journal_set_to: "%{label} sat til %{value}"
+  text_journal_deleted: "%{label} slettet (%{old})"
+  label_group_plural: Grupper
+  label_group: Grupper
+  label_group_new: Ny gruppe
+  label_time_entry_plural: Anvendt tid
+  text_journal_added: "%{label} %{value} tilfÃ¸jet"
+  field_active: Aktiv
+  enumeration_system_activity: System Aktivitet
+  permission_delete_issue_watchers: Slet overvÃ¥gere
+  version_status_closed: lukket
+  version_status_locked: lÃ¥st
+  version_status_open: Ã¥ben
+  error_can_not_reopen_issue_on_closed_version: En sag tildelt en lukket version kan ikke genÃ¥bnes
+  label_user_anonymous: Anonym
+  button_move_and_follow: Flyt og overvÃ¥g
+  setting_default_projects_modules: Standard moduler, aktiveret for nye projekter
+  setting_gravatar_default: Standard Gravatar billede
+  field_sharing: Delning
+  label_version_sharing_hierarchy: Med projekthierarki
+  label_version_sharing_system: Med alle projekter
+  label_version_sharing_descendants: Med underprojekter
+  label_version_sharing_tree: Med projekttrÃ¦
+  label_version_sharing_none: Ikke delt
+  error_can_not_archive_project: Dette projekt kan ikke arkiveres
+  button_duplicate: DuplikÃ©r
+  button_copy_and_follow: KopiÃ©r og overvÃ¥g
+  label_copy_source: Kilde
+  setting_issue_done_ratio: Beregn sagslÃ¸sning ratio
+  setting_issue_done_ratio_issue_status: Benyt sagsstatus
+  error_issue_done_ratios_not_updated: SagslÃ¸snings ratio, ikke opdateret.
+  error_workflow_copy_target: VÃ¦lg venligst mÃ¥ltracker og rolle(r)
+  setting_issue_done_ratio_issue_field: Benyt sagsfelt
+  label_copy_same_as_target: Samme som mÃ¥l
+  label_copy_target: MÃ¥l
+  notice_issue_done_ratios_updated: SagslÃ¸sningsratio opdateret.
+  error_workflow_copy_source: VÃ¦lg venligst en kildetracker eller rolle
+  label_update_issue_done_ratios: Opdater sagslÃ¸sningsratio
+  setting_start_of_week: Start kalendre pÃ¥
+  permission_view_issues: Vis sager
+  label_display_used_statuses_only: Vis kun statusser der er benyttet af denne tracker
+  label_revision_id: Revision %{value}
+  label_api_access_key: API nÃ¸gle
+  label_api_access_key_created_on: API nÃ¸gle genereret %{value} siden
+  label_feeds_access_key: RSS nÃ¸gle
+  notice_api_access_key_reseted: Din API nÃ¸gle er nulstillet.
+  setting_rest_api_enabled: Aktiver REST web service
+  label_missing_api_access_key: Mangler en API nÃ¸gle
+  label_missing_feeds_access_key: Mangler en RSS nÃ¸gle
+  button_show: Vis
+  text_line_separated: Flere vÃ¦redier tilladt (en linje for hver vÃ¦rdi).
+  setting_mail_handler_body_delimiters: TrunkÃ©r emails efter en af disse linjer
+  permission_add_subprojects: Lav underprojekter
+  label_subproject_new: Nyt underprojekt
+  text_own_membership_delete_confirmation: |-
+    Du er ved at fjerne en eller flere af dine rettigheder, og kan muligvis ikke redigere projektet bagefter.
+    Er du sikker pÃ¥ du Ã¸nsker at fortsÃ¦tte?
+  label_close_versions: Luk fÃ¦rdige versioner
+  label_board_sticky: Klistret
+  label_board_locked: LÃ¥st
+  permission_export_wiki_pages: Eksporter wiki sider
+  setting_cache_formatted_text: Cache formatteret tekst
+  permission_manage_project_activities: Administrer projektaktiviteter
+  error_unable_delete_issue_status: Det var ikke muligt at slette sagsstatus
+  label_profile: Profil
+  permission_manage_subtasks: Administrer underopgaver
+  field_parent_issue: Hovedopgave
+  label_subtask_plural: Underopgaver
+  label_project_copy_notifications: Send email notifikationer, mens projektet kopieres
+  error_can_not_delete_custom_field: Kan ikke slette brugerdefineret felt
+  error_unable_to_connect: Kan ikke forbinde (%{value})
+  error_can_not_remove_role: Denne rolle er i brug og kan ikke slettes.
+  error_can_not_delete_tracker: Denne type indeholder sager og kan ikke slettes.
+  field_principal: Principal
+  label_my_page_block: blok
+  notice_failed_to_save_members: "Fejl under lagring af medlem(mer): %{errors}."
+  text_zoom_out: Zoom ud
+  text_zoom_in: Zoom ind
+  notice_unable_delete_time_entry: Kan ikke slette tidsregistrering.
+  label_overall_spent_time: Overordnet forbrug af tid
+  field_time_entries: Log tid
+  project_module_gantt: Gantt
+  project_module_calendar: Kalender
+  button_edit_associated_wikipage: "RedigÃ©r tilknyttet Wiki side: %{page_title}"
+  field_text: Tekstfelt
+  label_user_mail_option_only_owner: Kun for ting jeg er ejer af
+  setting_default_notification_option: StandardpÃ¥mindelsesmulighed
+  label_user_mail_option_only_my_events: Kun for ting jeg overvÃ¥ger eller er involveret i
+  label_user_mail_option_only_assigned: Kun for ting jeg er tildelt
+  label_user_mail_option_none: Ingen hÃ¦ndelser
+  field_member_of_group: Medlem af gruppe
+  field_assigned_to_role: Medlem af rolle
+  notice_not_authorized_archived_project: Projektet du prÃ¸ver at tilgÃ¥, er blevet arkiveret.
+  label_principal_search: "SÃ¸g efter bruger eller gruppe:"
+  label_user_search: "SÃ¸g efter bruger:"
+  field_visible: Synlig
+  setting_commit_logtime_activity_id: Aktivitet for registreret tid
+  text_time_logged_by_changeset: Anvendt i changeset %{value}.
+  setting_commit_logtime_enabled: Aktiver tidsregistrering
+  notice_gantt_chart_truncated: Kortet er blevet afkortet, fordi det overstiger det maksimale antal elementer, der kan vises (%{max})
+  setting_gantt_items_limit: Maksimalt antal af elementer der kan vises pÃ¥ gantt kortet
+
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Kodning af Commit beskeder
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 sag
+    one:   1 sag
+    other: "%{count} sager"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: alle
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Med underprojekter
+  label_cross_project_tree: Med projekttrÃ¦
+  label_cross_project_hierarchy: Med projekthierarki
+  label_cross_project_system: Med alle projekter
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b3/b34e429087475d4465ce64636ce8471db1fe2c9b.svn-base
--- a/.svn/pristine/b3/b34e429087475d4465ce64636ce8471db1fe2c9b.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= @note %>
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b3/b36297cf2d44103422882a07a880a4a5ace75e6e.svn-base
--- a/.svn/pristine/b3/b36297cf2d44103422882a07a880a4a5ace75e6e.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. .. .. .. test test_helper]))
-
-class OverrideTest < ActiveSupport::TestCase
-  def test_overrides_from_the_application_should_work
-    flunk "this test should be overridden by the app"
-  end
-  
-  def test_tests_within_the_plugin_should_still_run
-    assert true, "non-overridden plugin tests should still run"
-  end
-end
-
-Engines::Testing.override_tests_from_app
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b3/b3a7b313b8a4897b400c5ff30d9b95ebda65226d.svn-base
--- a/.svn/pristine/b3/b3a7b313b8a4897b400c5ff30d9b95ebda65226d.svn-base
+++ /dev/null
@@ -1,55 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::WikiFormattingTest < ActiveSupport::TestCase
-
-  def test_textile_formatter
-    assert_equal Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting.formatter_for('textile')
-    assert_equal Redmine::WikiFormatting::Textile::Helper, Redmine::WikiFormatting.helper_for('textile')
-  end
-
-  def test_null_formatter
-    assert_equal Redmine::WikiFormatting::NullFormatter::Formatter, Redmine::WikiFormatting.formatter_for('')
-    assert_equal Redmine::WikiFormatting::NullFormatter::Helper, Redmine::WikiFormatting.helper_for('')
-  end
-
-  def test_should_link_urls_and_email_addresses
-    raw = <<-DIFF
-This is a sample *text* with a link: http://www.redmine.org
-and an email address foo@example.net
-DIFF
-
-    expected = <<-EXPECTED
-<p>This is a sample *text* with a link: <a href="http://www.redmine.org">http://www.redmine.org</a><br />
-and an email address <a href="mailto:foo@example.net">foo@example.net</a></p>
-EXPECTED
-
-    assert_equal expected.gsub(%r{[\r\n\t]}, ''), Redmine::WikiFormatting::NullFormatter::Formatter.new(raw).to_html.gsub(%r{[\r\n\t]}, '')
-  end
-
-  def test_supports_section_edit
-    with_settings :text_formatting => 'textile' do
-      assert_equal true, Redmine::WikiFormatting.supports_section_edit?
-    end
-    
-    with_settings :text_formatting => '' do
-      assert_equal false, Redmine::WikiFormatting.supports_section_edit?
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b3/b3ae8401c116d3c968d234881e8c4c29afe48532.svn-base
--- a/.svn/pristine/b3/b3ae8401c116d3c968d234881e8c4c29afe48532.svn-base
+++ /dev/null
@@ -1,36 +0,0 @@
-class FilesController < ApplicationController
-  menu_item :files
-
-  before_filter :find_project_by_project_id
-  before_filter :authorize
-
-  helper :sort
-  include SortHelper
-
-  def index
-    sort_init 'filename', 'asc'
-    sort_update 'filename' => "#{Attachment.table_name}.filename",
-                'created_on' => "#{Attachment.table_name}.created_on",
-                'size' => "#{Attachment.table_name}.filesize",
-                'downloads' => "#{Attachment.table_name}.downloads"
-
-    @containers = [ Project.find(@project.id, :include => :attachments, :order => sort_clause)]
-    @containers += @project.versions.find(:all, :include => :attachments, :order => sort_clause).sort.reverse
-    render :layout => !request.xhr?
-  end
-
-  def new
-    @versions = @project.versions.sort
-  end
-
-  def create
-    container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id]))
-    attachments = Attachment.attach_files(container, params[:attachments])
-    render_attachment_warning_if_needed(container)
-
-    if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added')
-      Mailer.deliver_attachments_added(attachments[:files])
-    end
-    redirect_to project_files_path(@project)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b3/b3eef499e5cbca352c47457989158ba7a363f279.svn-base
--- a/.svn/pristine/b3/b3eef499e5cbca352c47457989158ba7a363f279.svn-base
+++ /dev/null
@@ -1,145 +0,0 @@
---- 
-custom_fields_001: 
-  name: Database
-  min_length: 0
-  regexp: ""
-  is_for_all: true
-  is_filter: true
-  type: IssueCustomField
-  max_length: 0
-  possible_values: 
-  - MySQL
-  - PostgreSQL
-  - Oracle
-  id: 1
-  is_required: false
-  field_format: list
-  default_value: ""
-  editable: true
-custom_fields_002: 
-  name: Searchable field
-  min_length: 1
-  regexp: ""
-  is_for_all: true
-  type: IssueCustomField
-  max_length: 100
-  possible_values: ""
-  id: 2
-  is_required: false
-  field_format: string
-  searchable: true
-  default_value: "Default string"
-  editable: true
-custom_fields_003: 
-  name: Development status
-  min_length: 0
-  regexp: ""
-  is_for_all: false
-  is_filter: true
-  type: ProjectCustomField
-  max_length: 0
-  possible_values: 
-  - Stable
-  - Beta
-  - Alpha
-  - Planning
-  id: 3
-  is_required: false
-  field_format: list
-  default_value: ""
-  editable: true
-custom_fields_004: 
-  name: Phone number
-  min_length: 0
-  regexp: ""
-  is_for_all: false
-  type: UserCustomField
-  max_length: 0
-  possible_values: ""
-  id: 4
-  is_required: false
-  field_format: string
-  default_value: ""
-  editable: true
-custom_fields_005: 
-  name: Money
-  min_length: 0
-  regexp: ""
-  is_for_all: false
-  type: UserCustomField
-  max_length: 0
-  possible_values: ""
-  id: 5
-  is_required: false
-  field_format: float
-  default_value: ""
-  editable: true
-custom_fields_006: 
-  name: Float field
-  min_length: 0
-  regexp: ""
-  is_for_all: true
-  type: IssueCustomField
-  max_length: 0
-  possible_values: ""
-  id: 6
-  is_required: false
-  field_format: float
-  default_value: ""
-  editable: true
-custom_fields_007: 
-  name: Billable
-  min_length: 0
-  regexp: ""
-  is_for_all: false
-  is_filter: true
-  type: TimeEntryActivityCustomField
-  max_length: 0
-  possible_values: ""
-  id: 7
-  is_required: false
-  field_format: bool
-  default_value: ""
-  editable: true
-custom_fields_008: 
-  name: Custom date
-  min_length: 0
-  regexp: ""
-  is_for_all: true
-  is_filter: false
-  type: IssueCustomField
-  max_length: 0
-  possible_values: ""
-  id: 8
-  is_required: false
-  field_format: date
-  default_value: ""
-  editable: true
-custom_fields_009: 
-  name: Project 1 cf
-  min_length: 0
-  regexp: ""
-  is_for_all: false
-  is_filter: true
-  type: IssueCustomField
-  max_length: 0
-  possible_values: ""
-  id: 9
-  is_required: false
-  field_format: date
-  default_value: ""
-  editable: true
-custom_fields_010: 
-  name: Overtime
-  min_length: 0
-  regexp: ""
-  is_for_all: false
-  is_filter: false
-  type: TimeEntryCustomField
-  max_length: 0
-  possible_values: ""
-  id: 10
-  is_required: false
-  field_format: bool
-  default_value: 0
-  editable: true
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b4/b4795ced5acceb3bc06993b762ac31de2976a1c3.svn-base
--- /dev/null
+++ b/.svn/pristine/b4/b4795ced5acceb3bc06993b762ac31de2976a1c3.svn-base
@@ -0,0 +1,69 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class WatchersHelperTest < ActionView::TestCase
+  include WatchersHelper
+  include Redmine::I18n
+
+  fixtures :users, :issues
+
+  def setup
+    super
+    set_language_if_valid('en')
+    User.current = nil
+  end
+
+  test '#watcher_link with a non-watched object' do
+    expected = link_to(
+      "Watch",
+      "/watchers/watch?object_id=1&object_type=issue",
+      :remote => true, :method => 'post', :class => "issue-1-watcher icon icon-fav-off"
+    )
+    assert_equal expected, watcher_link(Issue.find(1), User.find(1))
+  end
+
+  test '#watcher_link with a single objet array' do
+    expected = link_to(
+      "Watch",
+      "/watchers/watch?object_id=1&object_type=issue",
+      :remote => true, :method => 'post', :class => "issue-1-watcher icon icon-fav-off"
+    )
+    assert_equal expected, watcher_link([Issue.find(1)], User.find(1))
+  end
+
+  test '#watcher_link with a multiple objets array' do
+    expected = link_to(
+      "Watch",
+      "/watchers/watch?object_id%5B%5D=1&object_id%5B%5D=3&object_type=issue",
+      :remote => true, :method => 'post', :class => "issue-bulk-watcher icon icon-fav-off"
+    )
+    assert_equal expected, watcher_link([Issue.find(1), Issue.find(3)], User.find(1))
+  end
+
+  test '#watcher_link with a watched object' do
+    Watcher.create!(:watchable => Issue.find(1), :user => User.find(1))
+
+    expected = link_to(
+      "Unwatch",
+      "/watchers/watch?object_id=1&object_type=issue",
+      :remote => true, :method => 'delete', :class => "issue-1-watcher icon icon-fav"
+    )
+    assert_equal expected, watcher_link(Issue.find(1), User.find(1))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b4/b48acd5a3b1789516c48ce1cc9019fc8dddb53c4.svn-base
--- a/.svn/pristine/b4/b48acd5a3b1789516c48ce1cc9019fc8dddb53c4.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class Namespace::TestRoutingController < ApplicationController
-  def routed_action
-    render_class_and_action
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b4/b49f8e8955f20d373ff50965f6541cbad8b508b5.svn-base
--- a/.svn/pristine/b4/b49f8e8955f20d373ff50965f6541cbad8b508b5.svn-base
+++ /dev/null
@@ -1,231 +0,0 @@
-OpenIdAuthentication
-====================
-
-Provides a thin wrapper around the excellent ruby-openid gem from JanRan. Be sure to install that first:
-
-  gem install ruby-openid
-
-To understand what OpenID is about and how it works, it helps to read the documentation for lib/openid/consumer.rb
-from that gem.
-
-The specification used is http://openid.net/specs/openid-authentication-2_0.html.
-
-
-Prerequisites
-=============
-
-OpenID authentication uses the session, so be sure that you haven't turned that off. It also relies on a number of
-database tables to store the authentication keys. So you'll have to run the migration to create these before you get started:
-
-  rake open_id_authentication:db:create
-
-Or, use the included generators to install or upgrade:
-
-  ./script/generate open_id_authentication_tables MigrationName
-  ./script/generate upgrade_open_id_authentication_tables MigrationName
-
-Alternatively, you can use the file-based store, which just relies on on tmp/openids being present in RAILS_ROOT. But be aware that this store only works if you have a single application server. And it's not safe to use across NFS. It's recommended that you use the database store if at all possible. To use the file-based store, you'll also have to add this line to your config/environment.rb:
-
-  OpenIdAuthentication.store = :file
-
-This particular plugin also relies on the fact that the authentication action allows for both POST and GET operations.
-If you're using RESTful authentication, you'll need to explicitly allow for this in your routes.rb. 
-
-The plugin also expects to find a root_url method that points to the home page of your site. You can accomplish this by using a root route in config/routes.rb:
-
-  map.root :controller => 'articles'
-
-This plugin relies on Rails Edge revision 6317 or newer.
-
-
-Example
-=======
-
-This example is just to meant to demonstrate how you could use OpenID authentication. You might well want to add
-salted hash logins instead of plain text passwords and other requirements on top of this. Treat it as a starting point,
-not a destination.
-
-Note that the User model referenced in the simple example below has an 'identity_url' attribute. You will want to add the same or similar field to whatever
-model you are using for authentication.
-
-Also of note is the following code block used in the example below:
-
-  authenticate_with_open_id do |result, identity_url|
-    ...
-  end
-  
-In the above code block, 'identity_url' will need to match user.identity_url exactly. 'identity_url' will be a string in the form of 'http://example.com' -
-If you are storing just 'example.com' with your user, the lookup will fail.
-
-There is a handy method in this plugin called 'normalize_url' that will help with validating OpenID URLs.
-
-  OpenIdAuthentication.normalize_url(user.identity_url)
-
-The above will return a standardized version of the OpenID URL - the above called with 'example.com' will return 'http://example.com/'
-It will also raise an InvalidOpenId exception if the URL is determined to not be valid.
-Use the above code in your User model and validate OpenID URLs before saving them.
-
-config/routes.rb
-
-  map.root :controller => 'articles'
-  map.resource :session
-
-
-app/views/sessions/new.erb
-
-  <% form_tag(session_url) do %>
-    <p>
-      <label for="name">Username:</label>
-      <%= text_field_tag "name" %>
-    </p>
-
-    <p>
-      <label for="password">Password:</label>
-      <%= password_field_tag %>
-    </p>
-
-    <p>
-      ...or use:
-    </p>
-
-    <p>
-      <label for="openid_identifier">OpenID:</label>
-      <%= text_field_tag "openid_identifier" %>
-    </p>
-
-    <p>
-      <%= submit_tag 'Sign in', :disable_with => "Signing in&hellip;" %>
-    </p>
-  <% end %>
-
-app/controllers/sessions_controller.rb
-  class SessionsController < ApplicationController
-    def create
-      if using_open_id?
-        open_id_authentication
-      else
-        password_authentication(params[:name], params[:password])
-      end
-    end
-
-
-    protected
-      def password_authentication(name, password)
-        if @current_user = @account.users.authenticate(params[:name], params[:password])
-          successful_login
-        else
-          failed_login "Sorry, that username/password doesn't work"
-        end
-      end
-
-      def open_id_authentication
-        authenticate_with_open_id do |result, identity_url|
-          if result.successful?
-            if @current_user = @account.users.find_by_identity_url(identity_url)
-              successful_login
-            else
-              failed_login "Sorry, no user by that identity URL exists (#{identity_url})"
-            end
-          else
-            failed_login result.message
-          end
-        end
-      end
-    
-    
-    private
-      def successful_login
-        session[:user_id] = @current_user.id
-        redirect_to(root_url)
-      end
-
-      def failed_login(message)
-        flash[:error] = message
-        redirect_to(new_session_url)
-      end
-  end
-
-
-
-If you're fine with the result messages above and don't need individual logic on a per-failure basis,
-you can collapse the case into a mere boolean:
-
-    def open_id_authentication
-      authenticate_with_open_id do |result, identity_url|
-        if result.successful? && @current_user = @account.users.find_by_identity_url(identity_url)
-          successful_login
-        else
-          failed_login(result.message || "Sorry, no user by that identity URL exists (#{identity_url})")
-        end
-      end
-    end
-
-
-Simple Registration OpenID Extension
-====================================
-
-Some OpenID Providers support this lightweight profile exchange protocol.  See more: http://www.openidenabled.com/openid/simple-registration-extension
-
-You can support it in your app by changing #open_id_authentication
-
-      def open_id_authentication(identity_url)
-        # Pass optional :required and :optional keys to specify what sreg fields you want.
-        # Be sure to yield registration, a third argument in the #authenticate_with_open_id block.
-        authenticate_with_open_id(identity_url, 
-            :required => [ :nickname, :email ],
-            :optional => :fullname) do |result, identity_url, registration|
-          case result.status
-          when :missing
-            failed_login "Sorry, the OpenID server couldn't be found"
-          when :invalid
-            failed_login "Sorry, but this does not appear to be a valid OpenID"
-          when :canceled
-            failed_login "OpenID verification was canceled"
-          when :failed
-            failed_login "Sorry, the OpenID verification failed"
-          when :successful
-            if @current_user = @account.users.find_by_identity_url(identity_url)
-              assign_registration_attributes!(registration)
-
-              if current_user.save
-                successful_login
-              else
-                failed_login "Your OpenID profile registration failed: " +
-                  @current_user.errors.full_messages.to_sentence
-              end
-            else
-              failed_login "Sorry, no user by that identity URL exists"
-            end
-          end
-        end
-      end
-      
-      # registration is a hash containing the valid sreg keys given above
-      # use this to map them to fields of your user model
-      def assign_registration_attributes!(registration)
-        model_to_registration_mapping.each do |model_attribute, registration_attribute|
-          unless registration[registration_attribute].blank?
-            @current_user.send("#{model_attribute}=", registration[registration_attribute])
-          end
-        end
-      end
-
-      def model_to_registration_mapping
-        { :login => 'nickname', :email => 'email', :display_name => 'fullname' }
-      end
-
-Attribute Exchange OpenID Extension
-===================================
-
-Some OpenID providers also support the OpenID AX (attribute exchange) protocol for exchanging identity information between endpoints.  See more: http://openid.net/specs/openid-attribute-exchange-1_0.html
-
-Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters.  For example:
-
-        authenticate_with_open_id(identity_url, 
-            :required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration|
-      
-This would provide the sreg data for :email, and the AX data for 'http://schema.openid.net/birthDate'
-
-
-
-Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b4/b4b121a602e6db678b41699ec2d4ceada140049b.svn-base
--- /dev/null
+++ b/.svn/pristine/b4/b4b121a602e6db678b41699ec2d4ceada140049b.svn-base
@@ -0,0 +1,141 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class GroupsController < ApplicationController
+  layout 'admin'
+
+  before_filter :require_admin
+  before_filter :find_group, :except => [:index, :new, :create]
+  accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user
+
+  helper :custom_fields
+
+  def index
+    @groups = Group.sorted.all
+
+    respond_to do |format|
+      format.html
+      format.api
+    end
+  end
+
+  def show
+    respond_to do |format|
+      format.html
+      format.api
+    end
+  end
+
+  def new
+    @group = Group.new
+  end
+
+  def create
+    @group = Group.new
+    @group.safe_attributes = params[:group]
+
+    respond_to do |format|
+      if @group.save
+        format.html {
+          flash[:notice] = l(:notice_successful_create)
+          redirect_to(params[:continue] ? new_group_path : groups_path)
+        }
+        format.api  { render :action => 'show', :status => :created, :location => group_url(@group) }
+      else
+        format.html { render :action => "new" }
+        format.api  { render_validation_errors(@group) }
+      end
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    @group.safe_attributes = params[:group]
+
+    respond_to do |format|
+      if @group.save
+        flash[:notice] = l(:notice_successful_update)
+        format.html { redirect_to(groups_path) }
+        format.api  { render_api_ok }
+      else
+        format.html { render :action => "edit" }
+        format.api  { render_validation_errors(@group) }
+      end
+    end
+  end
+
+  def destroy
+    @group.destroy
+
+    respond_to do |format|
+      format.html { redirect_to(groups_path) }
+      format.api  { render_api_ok }
+    end
+  end
+
+  def add_users
+    @users = User.find_all_by_id(params[:user_id] || params[:user_ids])
+    @group.users << @users if request.post?
+    respond_to do |format|
+      format.html { redirect_to edit_group_path(@group, :tab => 'users') }
+      format.js
+      format.api { render_api_ok }
+    end
+  end
+
+  def remove_user
+    @group.users.delete(User.find(params[:user_id])) if request.delete?
+    respond_to do |format|
+      format.html { redirect_to edit_group_path(@group, :tab => 'users') }
+      format.js
+      format.api { render_api_ok }
+    end
+  end
+
+  def autocomplete_for_user
+    respond_to do |format|
+      format.js
+    end
+  end
+
+  def edit_membership
+    @membership = Member.edit_membership(params[:membership_id], params[:membership], @group)
+    @membership.save if request.post?
+    respond_to do |format|
+      format.html { redirect_to edit_group_path(@group, :tab => 'memberships') }
+      format.js
+    end
+  end
+
+  def destroy_membership
+    Member.find(params[:membership_id]).destroy if request.post?
+    respond_to do |format|
+      format.html { redirect_to edit_group_path(@group, :tab => 'memberships') }
+      format.js
+    end
+  end
+
+  private
+
+  def find_group
+    @group = Group.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b4/b4ba08d8234f93ee5bdf8cc15661d379cb66b24f.svn-base
--- a/.svn/pristine/b4/b4ba08d8234f93ee5bdf8cc15661d379cb66b24f.svn-base
+++ /dev/null
@@ -1,180 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'roles_controller'
-
-# Re-raise errors caught by the controller.
-class RolesController; def rescue_action(e) raise e end; end
-
-class RolesControllerTest < ActionController::TestCase
-  fixtures :roles, :users, :members, :member_roles, :workflows, :trackers
-
-  def setup
-    @controller = RolesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @request.session[:user_id] = 1 # admin
-  end
-
-  def test_get_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-
-    assert_not_nil assigns(:roles)
-    assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
-
-    assert_tag :tag => 'a', :attributes => { :href => '/roles/edit/1' },
-                            :content => 'Manager'
-  end
-
-  def test_get_new
-    get :new
-    assert_response :success
-    assert_template 'new'
-  end
-
-  def test_post_new_with_validaton_failure
-    post :new, :role => {:name => '',
-                         :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
-                         :assignable => '0'}
-
-    assert_response :success
-    assert_template 'new'
-    assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' }
-  end
-
-  def test_post_new_without_workflow_copy
-    post :new, :role => {:name => 'RoleWithoutWorkflowCopy',
-                         :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
-                         :assignable => '0'}
-
-    assert_redirected_to '/roles'
-    role = Role.find_by_name('RoleWithoutWorkflowCopy')
-    assert_not_nil role
-    assert_equal [:add_issues, :edit_issues, :log_time], role.permissions
-    assert !role.assignable?
-  end
-
-  def test_post_new_with_workflow_copy
-    post :new, :role => {:name => 'RoleWithWorkflowCopy',
-                         :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
-                         :assignable => '0'},
-               :copy_workflow_from => '1'
-
-    assert_redirected_to '/roles'
-    role = Role.find_by_name('RoleWithWorkflowCopy')
-    assert_not_nil role
-    assert_equal Role.find(1).workflows.size, role.workflows.size
-  end
-
-  def test_get_edit
-    get :edit, :id => 1
-    assert_response :success
-    assert_template 'edit'
-    assert_equal Role.find(1), assigns(:role)
-  end
-
-  def test_post_edit
-    post :edit, :id => 1,
-                :role => {:name => 'Manager',
-                          :permissions => ['edit_project', ''],
-                          :assignable => '0'}
-
-    assert_redirected_to '/roles'
-    role = Role.find(1)
-    assert_equal [:edit_project], role.permissions
-  end
-
-  def test_destroy
-    r = Role.new(:name => 'ToBeDestroyed', :permissions => [:view_wiki_pages])
-    assert r.save
-
-    post :destroy, :id => r
-    assert_redirected_to '/roles'
-    assert_nil Role.find_by_id(r.id)
-  end
-
-  def test_destroy_role_in_use
-    post :destroy, :id => 1
-    assert_redirected_to '/roles'
-    assert flash[:error] == 'This role is in use and cannot be deleted.'
-    assert_not_nil Role.find_by_id(1)
-  end
-
-  def test_get_report
-    get :report
-    assert_response :success
-    assert_template 'report'
-
-    assert_not_nil assigns(:roles)
-    assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
-
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'permissions[3][]',
-                                                 :value => 'add_issues',
-                                                 :checked => 'checked' }
-
-    assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
-                                                 :name => 'permissions[3][]',
-                                                 :value => 'delete_issues',
-                                                 :checked => nil }
-  end
-
-  def test_post_report
-    post :report, :permissions => { '0' => '', '1' => ['edit_issues'], '3' => ['add_issues', 'delete_issues']}
-    assert_redirected_to '/roles'
-
-    assert_equal [:edit_issues], Role.find(1).permissions
-    assert_equal [:add_issues, :delete_issues], Role.find(3).permissions
-    assert Role.find(2).permissions.empty?
-  end
-
-  def test_clear_all_permissions
-    post :report, :permissions => { '0' => '' }
-    assert_redirected_to '/roles'
-    assert Role.find(1).permissions.empty?
-  end
-
-  def test_move_highest
-    post :edit, :id => 3, :role => {:move_to => 'highest'}
-    assert_redirected_to '/roles'
-    assert_equal 1, Role.find(3).position
-  end
-
-  def test_move_higher
-    position = Role.find(3).position
-    post :edit, :id => 3, :role => {:move_to => 'higher'}
-    assert_redirected_to '/roles'
-    assert_equal position - 1, Role.find(3).position
-  end
-
-  def test_move_lower
-    position = Role.find(2).position
-    post :edit, :id => 2, :role => {:move_to => 'lower'}
-    assert_redirected_to '/roles'
-    assert_equal position + 1, Role.find(2).position
-  end
-
-  def test_move_lowest
-    post :edit, :id => 2, :role => {:move_to => 'lowest'}
-    assert_redirected_to '/roles'
-    assert_equal Role.count, Role.find(2).position
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b4/b4cfef9e8223bd39d2080e9087f88b2607c14914.svn-base
--- /dev/null
+++ b/.svn/pristine/b4/b4cfef9e8223bd39d2080e9087f88b2607c14914.svn-base
@@ -0,0 +1,51 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ProjectsTest < ActionController::IntegrationTest
+  fixtures :projects, :users, :members, :enabled_modules
+
+  def test_archive_project
+    subproject = Project.find(1).children.first
+    log_user("admin", "admin")
+    get "admin/projects"
+    assert_response :success
+    assert_template "admin/projects"
+    post "projects/1/archive"
+    assert_redirected_to "/admin/projects"
+    assert !Project.find(1).active?
+
+    get 'projects/1'
+    assert_response 403
+    get "projects/#{subproject.id}"
+    assert_response 403
+
+    post "projects/1/unarchive"
+    assert_redirected_to "/admin/projects"
+    assert Project.find(1).active?
+    get "projects/1"
+    assert_response :success
+  end
+
+  def test_modules_should_not_allow_get
+    assert_no_difference 'EnabledModule.count' do
+      get '/projects/1/modules', {:enabled_module_names => ['']}, credentials('jsmith')
+      assert_response 404
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b4/b4fc2c9a97b87455aef29af5d4be937c21ee3844.svn-base
--- /dev/null
+++ b/.svn/pristine/b4/b4fc2c9a97b87455aef29af5d4be937c21ee3844.svn-base
@@ -0,0 +1,376 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module IssuesHelper
+  include ApplicationHelper
+
+  def issue_list(issues, &block)
+    ancestors = []
+    issues.each do |issue|
+      while (ancestors.any? && !issue.is_descendant_of?(ancestors.last))
+        ancestors.pop
+      end
+      yield issue, ancestors.size
+      ancestors << issue unless issue.leaf?
+    end
+  end
+
+  # Renders a HTML/CSS tooltip
+  #
+  # To use, a trigger div is needed.  This is a div with the class of "tooltip"
+  # that contains this method wrapped in a span with the class of "tip"
+  #
+  #    <div class="tooltip"><%= link_to_issue(issue) %>
+  #      <span class="tip"><%= render_issue_tooltip(issue) %></span>
+  #    </div>
+  #
+  def render_issue_tooltip(issue)
+    @cached_label_status ||= l(:field_status)
+    @cached_label_start_date ||= l(:field_start_date)
+    @cached_label_due_date ||= l(:field_due_date)
+    @cached_label_assigned_to ||= l(:field_assigned_to)
+    @cached_label_priority ||= l(:field_priority)
+    @cached_label_project ||= l(:field_project)
+
+    link_to_issue(issue) + "<br /><br />".html_safe +
+      "<strong>#{@cached_label_project}</strong>: #{link_to_project(issue.project)}<br />".html_safe +
+      "<strong>#{@cached_label_status}</strong>: #{h(issue.status.name)}<br />".html_safe +
+      "<strong>#{@cached_label_start_date}</strong>: #{format_date(issue.start_date)}<br />".html_safe +
+      "<strong>#{@cached_label_due_date}</strong>: #{format_date(issue.due_date)}<br />".html_safe +
+      "<strong>#{@cached_label_assigned_to}</strong>: #{h(issue.assigned_to)}<br />".html_safe +
+      "<strong>#{@cached_label_priority}</strong>: #{h(issue.priority.name)}".html_safe
+  end
+
+  def issue_heading(issue)
+    h("#{issue.tracker} ##{issue.id}")
+  end
+
+  def render_issue_subject_with_tree(issue)
+    s = ''
+    ancestors = issue.root? ? [] : issue.ancestors.visible.all
+    ancestors.each do |ancestor|
+      s << '<div>' + content_tag('p', link_to_issue(ancestor, :project => (issue.project_id != ancestor.project_id)))
+    end
+    s << '<div>'
+    subject = h(issue.subject)
+    if issue.is_private?
+      subject = content_tag('span', l(:field_is_private), :class => 'private') + ' ' + subject
+    end
+    s << content_tag('h3', subject)
+    s << '</div>' * (ancestors.size + 1)
+    s.html_safe
+  end
+
+  def render_descendants_tree(issue)
+    s = '<form><table class="list issues">'
+    issue_list(issue.descendants.visible.sort_by(&:lft)) do |child, level|
+      css = "issue issue-#{child.id} hascontextmenu"
+      css << " idnt idnt-#{level}" if level > 0
+      s << content_tag('tr',
+             content_tag('td', check_box_tag("ids[]", child.id, false, :id => nil), :class => 'checkbox') +
+             content_tag('td', link_to_issue(child, :truncate => 60, :project => (issue.project_id != child.project_id)), :class => 'subject') +
+             content_tag('td', h(child.status)) +
+             content_tag('td', link_to_user(child.assigned_to)) +
+             content_tag('td', progress_bar(child.done_ratio, :width => '80px')),
+             :class => css)
+    end
+    s << '</table></form>'
+    s.html_safe
+  end
+
+  # Returns a link for adding a new subtask to the given issue
+  def link_to_new_subtask(issue)
+    attrs = {
+      :tracker_id => issue.tracker,
+      :parent_issue_id => issue
+    }
+    link_to(l(:button_add), new_project_issue_path(issue.project, :issue => attrs))
+  end
+
+  class IssueFieldsRows
+    include ActionView::Helpers::TagHelper
+
+    def initialize
+      @left = []
+      @right = []
+    end
+
+    def left(*args)
+      args.any? ? @left << cells(*args) : @left
+    end
+
+    def right(*args)
+      args.any? ? @right << cells(*args) : @right
+    end
+
+    def size
+      @left.size > @right.size ? @left.size : @right.size
+    end
+
+    def to_html
+      html = ''.html_safe
+      blank = content_tag('th', '') + content_tag('td', '')
+      size.times do |i|
+        left = @left[i] || blank
+        right = @right[i] || blank
+        html << content_tag('tr', left + right)
+      end
+      html
+    end
+
+    def cells(label, text, options={})
+      content_tag('th', "#{label}:", options) + content_tag('td', text, options)
+    end
+  end
+
+  def issue_fields_rows
+    r = IssueFieldsRows.new
+    yield r
+    r.to_html
+  end
+
+  def render_custom_fields_rows(issue)
+    return if issue.custom_field_values.empty?
+    ordered_values = []
+    half = (issue.custom_field_values.size / 2.0).ceil
+    half.times do |i|
+      ordered_values << issue.custom_field_values[i]
+      ordered_values << issue.custom_field_values[i + half]
+    end
+    s = "<tr>\n"
+    n = 0
+    ordered_values.compact.each do |value|
+      s << "</tr>\n<tr>\n" if n > 0 && (n % 2) == 0
+      s << "\t<th>#{ h(value.custom_field.name) }:</th><td>#{ simple_format_without_paragraph(h(show_value(value))) }</td>\n"
+      n += 1
+    end
+    s << "</tr>\n"
+    s.html_safe
+  end
+
+  def issues_destroy_confirmation_message(issues)
+    issues = [issues] unless issues.is_a?(Array)
+    message = l(:text_issues_destroy_confirmation)
+    descendant_count = issues.inject(0) {|memo, i| memo += (i.right - i.left - 1)/2}
+    if descendant_count > 0
+      issues.each do |issue|
+        next if issue.root?
+        issues.each do |other_issue|
+          descendant_count -= 1 if issue.is_descendant_of?(other_issue)
+        end
+      end
+      if descendant_count > 0
+        message << "\n" + l(:text_issues_destroy_descendants_confirmation, :count => descendant_count)
+      end
+    end
+    message
+  end
+
+  def sidebar_queries
+    unless @sidebar_queries
+      @sidebar_queries = IssueQuery.visible.all(
+        :order => "#{Query.table_name}.name ASC",
+        # Project specific queries and global queries
+        :conditions => (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id])
+      )
+    end
+    @sidebar_queries
+  end
+
+  def query_links(title, queries)
+    # links to #index on issues/show
+    url_params = controller_name == 'issues' ? {:controller => 'issues', :action => 'index', :project_id => @project} : params
+
+    content_tag('h3', h(title)) +
+      queries.collect {|query|
+          css = 'query'
+          css << ' selected' if query == @query
+          link_to(h(query.name), url_params.merge(:query_id => query), :class => css)
+        }.join('<br />').html_safe
+  end
+
+  def render_sidebar_queries
+    out = ''.html_safe
+    queries = sidebar_queries.select {|q| !q.is_public?}
+    out << query_links(l(:label_my_queries), queries) if queries.any?
+    queries = sidebar_queries.select {|q| q.is_public?}
+    out << query_links(l(:label_query_plural), queries) if queries.any?
+    out
+  end
+
+  # Returns the textual representation of a journal details
+  # as an array of strings
+  def details_to_strings(details, no_html=false, options={})
+    options[:only_path] = (options[:only_path] == false ? false : true)
+    strings = []
+    values_by_field = {}
+    details.each do |detail|
+      if detail.property == 'cf'
+        field_id = detail.prop_key
+        field = CustomField.find_by_id(field_id)
+        if field && field.multiple?
+          values_by_field[field_id] ||= {:added => [], :deleted => []}
+          if detail.old_value
+            values_by_field[field_id][:deleted] << detail.old_value
+          end
+          if detail.value
+            values_by_field[field_id][:added] << detail.value
+          end
+          next
+        end
+      end
+      strings << show_detail(detail, no_html, options)
+    end
+    values_by_field.each do |field_id, changes|
+      detail = JournalDetail.new(:property => 'cf', :prop_key => field_id)
+      if changes[:added].any?
+        detail.value = changes[:added]
+        strings << show_detail(detail, no_html, options)
+      elsif changes[:deleted].any?
+        detail.old_value = changes[:deleted]
+        strings << show_detail(detail, no_html, options)
+      end
+    end
+    strings
+  end
+
+  # Returns the textual representation of a single journal detail
+  def show_detail(detail, no_html=false, options={})
+    multiple = false
+    case detail.property
+    when 'attr'
+      field = detail.prop_key.to_s.gsub(/\_id$/, "")
+      label = l(("field_" + field).to_sym)
+      case detail.prop_key
+      when 'due_date', 'start_date'
+        value = format_date(detail.value.to_date) if detail.value
+        old_value = format_date(detail.old_value.to_date) if detail.old_value
+
+      when 'project_id', 'status_id', 'tracker_id', 'assigned_to_id',
+            'priority_id', 'category_id', 'fixed_version_id'
+        value = find_name_by_reflection(field, detail.value)
+        old_value = find_name_by_reflection(field, detail.old_value)
+
+      when 'estimated_hours'
+        value = "%0.02f" % detail.value.to_f unless detail.value.blank?
+        old_value = "%0.02f" % detail.old_value.to_f unless detail.old_value.blank?
+
+      when 'parent_id'
+        label = l(:field_parent_issue)
+        value = "##{detail.value}" unless detail.value.blank?
+        old_value = "##{detail.old_value}" unless detail.old_value.blank?
+
+      when 'is_private'
+        value = l(detail.value == "0" ? :general_text_No : :general_text_Yes) unless detail.value.blank?
+        old_value = l(detail.old_value == "0" ? :general_text_No : :general_text_Yes) unless detail.old_value.blank?
+      end
+    when 'cf'
+      custom_field = CustomField.find_by_id(detail.prop_key)
+      if custom_field
+        multiple = custom_field.multiple?
+        label = custom_field.name
+        value = format_value(detail.value, custom_field.field_format) if detail.value
+        old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value
+      end
+    when 'attachment'
+      label = l(:label_attachment)
+    end
+    call_hook(:helper_issues_show_detail_after_setting,
+              {:detail => detail, :label => label, :value => value, :old_value => old_value })
+
+    label ||= detail.prop_key
+    value ||= detail.value
+    old_value ||= detail.old_value
+
+    unless no_html
+      label = content_tag('strong', label)
+      old_value = content_tag("i", h(old_value)) if detail.old_value
+      old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank?
+      if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key)
+        # Link to the attachment if it has not been removed
+        value = link_to_attachment(atta, :download => true, :only_path => options[:only_path])
+        if options[:only_path] != false && atta.is_text?
+          value += link_to(
+                       image_tag('magnifier.png'),
+                       :controller => 'attachments', :action => 'show',
+                       :id => atta, :filename => atta.filename
+                     )
+        end
+      else
+        value = content_tag("i", h(value)) if value
+      end
+    end
+
+    if detail.property == 'attr' && detail.prop_key == 'description'
+      s = l(:text_journal_changed_no_detail, :label => label)
+      unless no_html
+        diff_link = link_to 'diff',
+          {:controller => 'journals', :action => 'diff', :id => detail.journal_id,
+           :detail_id => detail.id, :only_path => options[:only_path]},
+          :title => l(:label_view_diff)
+        s << " (#{ diff_link })"
+      end
+      s.html_safe
+    elsif detail.value.present?
+      case detail.property
+      when 'attr', 'cf'
+        if detail.old_value.present?
+          l(:text_journal_changed, :label => label, :old => old_value, :new => value).html_safe
+        elsif multiple
+          l(:text_journal_added, :label => label, :value => value).html_safe
+        else
+          l(:text_journal_set_to, :label => label, :value => value).html_safe
+        end
+      when 'attachment'
+        l(:text_journal_added, :label => label, :value => value).html_safe
+      end
+    else
+      l(:text_journal_deleted, :label => label, :old => old_value).html_safe
+    end
+  end
+
+  # Find the name of an associated record stored in the field attribute
+  def find_name_by_reflection(field, id)
+    unless id.present?
+      return nil
+    end
+    association = Issue.reflect_on_association(field.to_sym)
+    if association
+      record = association.class_name.constantize.find_by_id(id)
+      if record
+        record.name.force_encoding('UTF-8') if record.name.respond_to?(:force_encoding)
+        return record.name
+      end
+    end
+  end
+
+  # Renders issue children recursively
+  def render_api_issue_children(issue, api)
+    return if issue.leaf?
+    api.array :children do
+      issue.children.each do |child|
+        api.issue(:id => child.id) do
+          api.tracker(:id => child.tracker_id, :name => child.tracker.name) unless child.tracker.nil?
+          api.subject child.subject
+          render_api_issue_children(child, api)
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b5/b516f333e4615d3ec7b7c90303ba24e1004720cf.svn-base
--- /dev/null
+++ b/.svn/pristine/b5/b516f333e4615d3ec7b7c90303ba24e1004720cf.svn-base
@@ -0,0 +1,232 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class VersionsControllerTest < ActionController::TestCase
+  fixtures :projects, :versions, :issues, :users, :roles, :members, :member_roles, :enabled_modules, :issue_statuses, :issue_categories
+
+  def setup
+    User.current = nil
+  end
+
+  def test_index
+    get :index, :project_id => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:versions)
+    # Version with no date set appears
+    assert assigns(:versions).include?(Version.find(3))
+    # Completed version doesn't appear
+    assert !assigns(:versions).include?(Version.find(1))
+    # Context menu on issues
+    assert_select "script", :text => Regexp.new(Regexp.escape("contextMenuInit('/issues/context_menu')"))
+    # Links to versions anchors
+    assert_tag 'a', :attributes => {:href => '#2.0'},
+                    :ancestor => {:tag => 'div', :attributes => {:id => 'sidebar'}}
+    # Links to completed versions in the sidebar
+    assert_tag 'a', :attributes => {:href => '/versions/1'},
+                    :ancestor => {:tag => 'div', :attributes => {:id => 'sidebar'}}
+  end
+
+  def test_index_with_completed_versions
+    get :index, :project_id => 1, :completed => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:versions)
+    # Version with no date set appears
+    assert assigns(:versions).include?(Version.find(3))
+    # Completed version appears
+    assert assigns(:versions).include?(Version.find(1))
+  end
+
+  def test_index_with_tracker_ids
+    get :index, :project_id => 1, :tracker_ids => [1, 3]
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:issues_by_version)
+    assert_nil assigns(:issues_by_version).values.flatten.detect {|issue| issue.tracker_id == 2}
+  end
+
+  def test_index_showing_subprojects_versions
+    @subproject_version = Version.create!(:project => Project.find(3), :name => "Subproject version")
+    get :index, :project_id => 1, :with_subprojects => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:versions)
+
+    assert assigns(:versions).include?(Version.find(4)), "Shared version not found"
+    assert assigns(:versions).include?(@subproject_version), "Subproject version not found"
+  end
+
+  def test_index_should_prepend_shared_versions
+    get :index, :project_id => 1
+    assert_response :success
+
+    assert_select '#sidebar' do
+      assert_select 'a[href=?]', '#2.0', :text => '2.0'
+      assert_select 'a[href=?]', '#subproject1-2.0', :text => 'eCookbook Subproject 1 - 2.0'
+    end
+    assert_select '#content' do
+      assert_select 'a[name=?]', '2.0', :text => '2.0'
+      assert_select 'a[name=?]', 'subproject1-2.0', :text => 'eCookbook Subproject 1 - 2.0'
+    end
+  end
+
+  def test_show
+    get :show, :id => 2
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:version)
+
+    assert_tag :tag => 'h2', :content => /1.0/
+  end
+
+  def test_show_should_display_nil_counts
+    with_settings :default_language => 'en' do
+      get :show, :id => 2, :status_by => 'category'
+      assert_response :success
+      assert_select 'div#status_by' do
+        assert_select 'select[name=status_by]' do
+          assert_select 'option[value=category][selected=selected]'
+        end
+        assert_select 'a', :text => 'none'
+      end
+    end
+  end
+
+  def test_new
+    @request.session[:user_id] = 2
+    get :new, :project_id => '1'
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_new_from_issue_form
+    @request.session[:user_id] = 2
+    xhr :get, :new, :project_id => '1'
+    assert_response :success
+    assert_template 'new'
+    assert_equal 'text/javascript', response.content_type
+  end
+
+  def test_create
+    @request.session[:user_id] = 2 # manager
+    assert_difference 'Version.count' do
+      post :create, :project_id => '1', :version => {:name => 'test_add_version'}
+    end
+    assert_redirected_to '/projects/ecookbook/settings/versions'
+    version = Version.find_by_name('test_add_version')
+    assert_not_nil version
+    assert_equal 1, version.project_id
+  end
+
+  def test_create_from_issue_form
+    @request.session[:user_id] = 2
+    assert_difference 'Version.count' do
+      xhr :post, :create, :project_id => '1', :version => {:name => 'test_add_version_from_issue_form'}
+    end
+    version = Version.find_by_name('test_add_version_from_issue_form')
+    assert_not_nil version
+    assert_equal 1, version.project_id
+
+    assert_response :success
+    assert_template 'create'
+    assert_equal 'text/javascript', response.content_type
+    assert_include 'test_add_version_from_issue_form', response.body
+  end
+
+  def test_create_from_issue_form_with_failure
+    @request.session[:user_id] = 2
+    assert_no_difference 'Version.count' do
+      xhr :post, :create, :project_id => '1', :version => {:name => ''}
+    end
+    assert_response :success
+    assert_template 'new'
+    assert_equal 'text/javascript', response.content_type
+  end
+
+  def test_get_edit
+    @request.session[:user_id] = 2
+    get :edit, :id => 2
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_close_completed
+    Version.update_all("status = 'open'")
+    @request.session[:user_id] = 2
+    put :close_completed, :project_id => 'ecookbook'
+    assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
+    assert_not_nil Version.find_by_status('closed')
+  end
+
+  def test_post_update
+    @request.session[:user_id] = 2
+    put :update, :id => 2,
+                :version => { :name => 'New version name',
+                              :effective_date => Date.today.strftime("%Y-%m-%d")}
+    assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
+    version = Version.find(2)
+    assert_equal 'New version name', version.name
+    assert_equal Date.today, version.effective_date
+  end
+
+  def test_post_update_with_validation_failure
+    @request.session[:user_id] = 2
+    put :update, :id => 2,
+                 :version => { :name => '',
+                               :effective_date => Date.today.strftime("%Y-%m-%d")}
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_destroy
+    @request.session[:user_id] = 2
+    assert_difference 'Version.count', -1 do
+      delete :destroy, :id => 3
+    end
+    assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
+    assert_nil Version.find_by_id(3)
+  end
+
+  def test_destroy_version_in_use_should_fail
+    @request.session[:user_id] = 2
+    assert_no_difference 'Version.count' do
+      delete :destroy, :id => 2
+    end
+    assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
+    assert flash[:error].match(/Unable to delete version/)
+    assert Version.find_by_id(2)
+  end
+
+  def test_issue_status_by
+    xhr :get, :status_by, :id => 2
+    assert_response :success
+    assert_template 'status_by'
+    assert_template '_issue_counts'
+  end
+
+  def test_issue_status_by_status
+    xhr :get, :status_by, :id => 2, :status_by => 'status'
+    assert_response :success
+    assert_template 'status_by'
+    assert_template '_issue_counts'
+    assert_include 'Assigned', response.body
+    assert_include 'Closed', response.body
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b5/b523992066f5a0cd044c8bc1ce95ed3c48f7f9b8.svn-base
--- a/.svn/pristine/b5/b523992066f5a0cd044c8bc1ce95ed3c48f7f9b8.svn-base
+++ /dev/null
@@ -1,97 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssueRelationsController < ApplicationController
-  before_filter :find_issue, :find_project_from_association, :authorize, :only => [:index, :create]
-  before_filter :find_relation, :except => [:index, :create]
-
-  accept_api_auth :index, :show, :create, :destroy
-
-  def index
-    @relations = @issue.relations
-
-    respond_to do |format|
-      format.html { render :nothing => true }
-      format.api
-    end
-  end
-
-  def show
-    raise Unauthorized unless @relation.visible?
-
-    respond_to do |format|
-      format.html { render :nothing => true }
-      format.api
-    end
-  end
-
-  verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
-  def create
-    @relation = IssueRelation.new(params[:relation])
-    @relation.issue_from = @issue
-    if params[:relation] && m = params[:relation][:issue_to_id].to_s.match(/^#?(\d+)$/)
-      @relation.issue_to = Issue.visible.find_by_id(m[1].to_i)
-    end
-    saved = @relation.save
-
-    respond_to do |format|
-      format.html { redirect_to :controller => 'issues', :action => 'show', :id => @issue }
-      format.js do
-        @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
-        render :update do |page|
-          page.replace_html "relations", :partial => 'issues/relations'
-          if @relation.errors.empty?
-            page << "$('relation_delay').value = ''"
-            page << "$('relation_issue_to_id').value = ''"
-          end
-        end
-      end
-      format.api {
-        if saved
-          render :action => 'show', :status => :created, :location => relation_url(@relation)
-        else
-          render_validation_errors(@relation)
-        end
-      }
-    end
-  end
-
-  verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
-  def destroy
-    raise Unauthorized unless @relation.deletable?
-    @relation.destroy
-
-    respond_to do |format|
-      format.html { redirect_to :controller => 'issues', :action => 'show', :id => @issue }
-      format.js   { render(:update) {|page| page.remove "relation-#{@relation.id}"} }
-      format.api  { head :ok }
-    end
-  end
-
-private
-  def find_issue
-    @issue = @object = Issue.find(params[:issue_id])
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  def find_relation
-    @relation = IssueRelation.find(params[:id])
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b5/b5842903c628d7f7ca625476f554fde27898338a.svn-base
--- a/.svn/pristine/b5/b5842903c628d7f7ca625476f554fde27898338a.svn-base
+++ /dev/null
@@ -1,460 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-ENV["RAILS_ENV"] = "test"
-require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
-require 'test_help'
-require File.expand_path(File.dirname(__FILE__) + '/helper_testcase')
-require Rails.root.join('test', 'mocks', 'open_id_authentication_mock.rb').to_s
-
-require File.expand_path(File.dirname(__FILE__) + '/object_daddy_helpers')
-include ObjectDaddyHelpers
-
-class ActiveSupport::TestCase
-  # Transactional fixtures accelerate your tests by wrapping each test method
-  # in a transaction that's rolled back on completion.  This ensures that the
-  # test database remains unchanged so your fixtures don't have to be reloaded
-  # between every test method.  Fewer database queries means faster tests.
-  #
-  # Read Mike Clark's excellent walkthrough at
-  #   http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
-  #
-  # Every Active Record database supports transactions except MyISAM tables
-  # in MySQL.  Turn off transactional fixtures in this case; however, if you
-  # don't care one way or the other, switching from MyISAM to InnoDB tables
-  # is recommended.
-  self.use_transactional_fixtures = true
-
-  # Instantiated fixtures are slow, but give you @david where otherwise you
-  # would need people(:david).  If you don't want to migrate your existing
-  # test cases which use the @david style and don't mind the speed hit (each
-  # instantiated fixtures translates to a database query per test method),
-  # then set this back to true.
-  self.use_instantiated_fixtures  = false
-
-  # Add more helper methods to be used by all tests here...
-
-  def log_user(login, password)
-    User.anonymous
-    get "/login"
-    assert_equal nil, session[:user_id]
-    assert_response :success
-    assert_template "account/login"
-    post "/login", :username => login, :password => password
-    assert_equal login, User.find(session[:user_id]).login
-  end
-
-  def uploaded_test_file(name, mime)
-    ActionController::TestUploadedFile.new(
-      ActiveSupport::TestCase.fixture_path + "/files/#{name}", mime, true)
-  end
-
-  # Mock out a file
-  def self.mock_file
-    file = 'a_file.png'
-    file.stubs(:size).returns(32)
-    file.stubs(:original_filename).returns('a_file.png')
-    file.stubs(:content_type).returns('image/png')
-    file.stubs(:read).returns(false)
-    file
-  end
-
-  def mock_file
-    self.class.mock_file
-  end
-
-  def mock_file_with_options(options={})
-    file = ''
-    file.stubs(:size).returns(32)
-    original_filename = options[:original_filename] || nil
-    file.stubs(:original_filename).returns(original_filename)
-    content_type = options[:content_type] || nil
-    file.stubs(:content_type).returns(content_type)
-    file.stubs(:read).returns(false)
-    file
-  end
-
-  # Use a temporary directory for attachment related tests
-  def set_tmp_attachments_directory
-    Dir.mkdir "#{Rails.root}/tmp/test" unless File.directory?("#{Rails.root}/tmp/test")
-    unless File.directory?("#{Rails.root}/tmp/test/attachments")
-      Dir.mkdir "#{Rails.root}/tmp/test/attachments"
-    end
-    Attachment.storage_path = "#{Rails.root}/tmp/test/attachments"
-  end
-
-  def with_settings(options, &block)
-    saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].is_a?(Symbol) ? Setting[k] : Setting[k].dup; h}
-    options.each {|k, v| Setting[k] = v}
-    yield
-  ensure
-    saved_settings.each {|k, v| Setting[k] = v} if saved_settings
-  end
-
-  def change_user_password(login, new_password)
-    user = User.first(:conditions => {:login => login})
-    user.password, user.password_confirmation = new_password, new_password
-    user.save!
-  end
-
-  def self.ldap_configured?
-    @test_ldap = Net::LDAP.new(:host => '127.0.0.1', :port => 389)
-    return @test_ldap.bind
-  rescue Exception => e
-    # LDAP is not listening
-    return nil
-  end
-
-  # Returns the path to the test +vendor+ repository
-  def self.repository_path(vendor)
-    Rails.root.join("tmp/test/#{vendor.downcase}_repository").to_s
-  end
-
-  # Returns the url of the subversion test repository
-  def self.subversion_repository_url
-    path = repository_path('subversion')
-    path = '/' + path unless path.starts_with?('/')
-    "file://#{path}"
-  end
-
-  # Returns true if the +vendor+ test repository is configured
-  def self.repository_configured?(vendor)
-    File.directory?(repository_path(vendor))
-  end
-
-  def assert_error_tag(options={})
-    assert_tag({:attributes => { :id => 'errorExplanation' }}.merge(options))
-  end
-
-  def assert_include(expected, s)
-    assert s.include?(expected), "\"#{expected}\" not found in \"#{s}\""
-  end
-
-  # Shoulda macros
-  def self.should_render_404
-    should_respond_with :not_found
-    should_render_template 'common/error'
-  end
-
-  def self.should_have_before_filter(expected_method, options = {})
-    should_have_filter('before', expected_method, options)
-  end
-
-  def self.should_have_after_filter(expected_method, options = {})
-    should_have_filter('after', expected_method, options)
-  end
-
-  def self.should_have_filter(filter_type, expected_method, options)
-    description = "have #{filter_type}_filter :#{expected_method}"
-    description << " with #{options.inspect}" unless options.empty?
-
-    should description do
-      klass = "action_controller/filters/#{filter_type}_filter".classify.constantize
-      expected = klass.new(:filter, expected_method.to_sym, options)
-      assert_equal 1, @controller.class.filter_chain.select { |filter|
-        filter.method == expected.method && filter.kind == expected.kind &&
-        filter.options == expected.options && filter.class == expected.class
-      }.size
-    end
-  end
-
-  def self.should_show_the_old_and_new_values_for(prop_key, model, &block)
-    context "" do
-      setup do
-        if block_given?
-          instance_eval &block
-        else
-          @old_value = model.generate!
-          @new_value = model.generate!
-        end
-      end
-
-      should "use the new value's name" do
-        @detail = JournalDetail.generate!(:property => 'attr',
-                                          :old_value => @old_value.id,
-                                          :value => @new_value.id,
-                                          :prop_key => prop_key)
-
-        assert_match @new_value.name, show_detail(@detail, true)
-      end
-
-      should "use the old value's name" do
-        @detail = JournalDetail.generate!(:property => 'attr',
-                                          :old_value => @old_value.id,
-                                          :value => @new_value.id,
-                                          :prop_key => prop_key)
-
-        assert_match @old_value.name, show_detail(@detail, true)
-      end
-    end
-  end
-
-  def self.should_create_a_new_user(&block)
-    should "create a new user" do
-      user = instance_eval &block
-      assert user
-      assert_kind_of User, user
-      assert !user.new_record?
-    end
-  end
-
-  # Test that a request allows the three types of API authentication
-  #
-  # * HTTP Basic with username and password
-  # * HTTP Basic with an api key for the username
-  # * Key based with the key=X parameter
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_api_authentication(http_method, url, parameters={}, options={})
-    should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters, options)
-    should_allow_http_basic_auth_with_key(http_method, url, parameters, options)
-    should_allow_key_based_auth(http_method, url, parameters, options)
-  end
-
-  # Test that a request allows the username and password for HTTP BASIC
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters={}, options={})
-    success_code = options[:success_code] || :success
-    failure_code = options[:failure_code] || :unauthorized
-
-    context "should allow http basic auth using a username and password for #{http_method} #{url}" do
-      context "with a valid HTTP authentication" do
-        setup do
-          @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password', :admin => true) # Admin so they can access the project
-          @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
-          send(http_method, url, parameters, {:authorization => @authorization})
-        end
-
-        should_respond_with success_code
-        should_respond_with_content_type_based_on_url(url)
-        should "login as the user" do
-          assert_equal @user, User.current
-        end
-      end
-
-      context "with an invalid HTTP authentication" do
-        setup do
-          @user = User.generate_with_protected!
-          @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
-          send(http_method, url, parameters, {:authorization => @authorization})
-        end
-
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-
-      context "without credentials" do
-        setup do
-          send(http_method, url, parameters, {:authorization => ''})
-        end
-
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "include_www_authenticate_header" do
-          assert @controller.response.headers.has_key?('WWW-Authenticate')
-        end
-      end
-    end
-
-  end
-
-  # Test that a request allows the API key with HTTP BASIC
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_http_basic_auth_with_key(http_method, url, parameters={}, options={})
-    success_code = options[:success_code] || :success
-    failure_code = options[:failure_code] || :unauthorized
-
-    context "should allow http basic auth with a key for #{http_method} #{url}" do
-      context "with a valid HTTP authentication using the API token" do
-        setup do
-          @user = User.generate_with_protected!(:admin => true)
-          @token = Token.generate!(:user => @user, :action => 'api')
-          @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
-          send(http_method, url, parameters, {:authorization => @authorization})
-        end
-
-        should_respond_with success_code
-        should_respond_with_content_type_based_on_url(url)
-        should_be_a_valid_response_string_based_on_url(url)
-        should "login as the user" do
-          assert_equal @user, User.current
-        end
-      end
-
-      context "with an invalid HTTP authentication" do
-        setup do
-          @user = User.generate_with_protected!
-          @token = Token.generate!(:user => @user, :action => 'feeds')
-          @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
-          send(http_method, url, parameters, {:authorization => @authorization})
-        end
-
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-    end
-  end
-
-  # Test that a request allows full key authentication
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url, without the key=ZXY parameter
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_key_based_auth(http_method, url, parameters={}, options={})
-    success_code = options[:success_code] || :success
-    failure_code = options[:failure_code] || :unauthorized
-
-    context "should allow key based auth using key=X for #{http_method} #{url}" do
-      context "with a valid api token" do
-        setup do
-          @user = User.generate_with_protected!(:admin => true)
-          @token = Token.generate!(:user => @user, :action => 'api')
-          # Simple url parse to add on ?key= or &key=
-          request_url = if url.match(/\?/)
-                          url + "&key=#{@token.value}"
-                        else
-                          url + "?key=#{@token.value}"
-                        end
-          send(http_method, request_url, parameters)
-        end
-
-        should_respond_with success_code
-        should_respond_with_content_type_based_on_url(url)
-        should_be_a_valid_response_string_based_on_url(url)
-        should "login as the user" do
-          assert_equal @user, User.current
-        end
-      end
-
-      context "with an invalid api token" do
-        setup do
-          @user = User.generate_with_protected!
-          @token = Token.generate!(:user => @user, :action => 'feeds')
-          # Simple url parse to add on ?key= or &key=
-          request_url = if url.match(/\?/)
-                          url + "&key=#{@token.value}"
-                        else
-                          url + "?key=#{@token.value}"
-                        end
-          send(http_method, request_url, parameters)
-        end
-
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-    end
-
-    context "should allow key based auth using X-Redmine-API-Key header for #{http_method} #{url}" do
-      setup do
-        @user = User.generate_with_protected!(:admin => true)
-        @token = Token.generate!(:user => @user, :action => 'api')
-        send(http_method, url, parameters, {'X-Redmine-API-Key' => @token.value.to_s})
-      end
-
-      should_respond_with success_code
-      should_respond_with_content_type_based_on_url(url)
-      should_be_a_valid_response_string_based_on_url(url)
-      should "login as the user" do
-        assert_equal @user, User.current
-      end
-    end
-  end
-
-  # Uses should_respond_with_content_type based on what's in the url:
-  #
-  # '/project/issues.xml' => should_respond_with_content_type :xml
-  # '/project/issues.json' => should_respond_with_content_type :json
-  #
-  # @param [String] url Request
-  def self.should_respond_with_content_type_based_on_url(url)
-    case
-    when url.match(/xml/i)
-      should_respond_with_content_type :xml
-    when url.match(/json/i)
-      should_respond_with_content_type :json
-    else
-      raise "Unknown content type for should_respond_with_content_type_based_on_url: #{url}"
-    end
-
-  end
-
-  # Uses the url to assert which format the response should be in
-  #
-  # '/project/issues.xml' => should_be_a_valid_xml_string
-  # '/project/issues.json' => should_be_a_valid_json_string
-  #
-  # @param [String] url Request
-  def self.should_be_a_valid_response_string_based_on_url(url)
-    case
-    when url.match(/xml/i)
-      should_be_a_valid_xml_string
-    when url.match(/json/i)
-      should_be_a_valid_json_string
-    else
-      raise "Unknown content type for should_be_a_valid_response_based_on_url: #{url}"
-    end
-
-  end
-
-  # Checks that the response is a valid JSON string
-  def self.should_be_a_valid_json_string
-    should "be a valid JSON string (or empty)" do
-      assert(response.body.blank? || ActiveSupport::JSON.decode(response.body))
-    end
-  end
-
-  # Checks that the response is a valid XML string
-  def self.should_be_a_valid_xml_string
-    should "be a valid XML string" do
-      assert REXML::Document.new(response.body)
-    end
-  end
-
-end
-
-# Simple module to "namespace" all of the API tests
-module ApiTest
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b5/b5912509c719c19cefc865fb8a655b03174ed731.svn-base
--- /dev/null
+++ b/.svn/pristine/b5/b5912509c719c19cefc865fb8a655b03174ed731.svn-base
@@ -0,0 +1,150 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ActivitiesControllerTest < ActionController::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :groups_users,
+           :enabled_modules,
+           :journals, :journal_details
+
+
+  def test_project_index
+    get :index, :id => 1, :with_subprojects => 0
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:events_by_day)
+
+    assert_select 'h3', :text => /#{2.days.ago.to_date.day}/
+    assert_select 'dl dt.issue-edit a', :text => /(#{IssueStatus.find(2).name})/
+  end
+
+  def test_project_index_with_invalid_project_id_should_respond_404
+    get :index, :id => 299
+    assert_response 404
+  end
+
+  def test_previous_project_index
+    get :index, :id => 1, :from => 2.days.ago.to_date
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:events_by_day)
+
+    assert_select 'h3', :text => /#{3.days.ago.to_date.day}/
+    assert_select 'dl dt.issue a', :text => /Can&#x27;t print recipes/
+  end
+
+  def test_global_index
+    @request.session[:user_id] = 1
+    get :index
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:events_by_day)
+
+    i5 = Issue.find(5)
+    d5 = User.find(1).time_to_date(i5.created_on)
+
+    assert_select 'h3', :text => /#{d5.day}/
+    assert_select 'dl dt.issue a', :text => /Subproject issue/
+  end
+
+  def test_user_index
+    @request.session[:user_id] = 1
+    get :index, :user_id => 2
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:events_by_day)
+
+    assert_select 'h2 a[href=/users/2]', :text => 'John Smith'
+
+    i1 = Issue.find(1)
+    d1 = User.find(1).time_to_date(i1.created_on)
+
+    assert_select 'h3', :text => /#{d1.day}/
+    assert_select 'dl dt.issue a', :text => /Can&#x27;t print recipes/
+  end
+
+  def test_user_index_with_invalid_user_id_should_respond_404
+    get :index, :user_id => 299
+    assert_response 404
+  end
+
+  def test_index_atom_feed
+    get :index, :format => 'atom', :with_subprojects => 0
+    assert_response :success
+    assert_template 'common/feed'
+
+    assert_select 'feed' do
+      assert_select 'link[rel=self][href=?]', 'http://test.host/activity.atom?with_subprojects=0'
+      assert_select 'link[rel=alternate][href=?]', 'http://test.host/activity?with_subprojects=0'
+      assert_select 'entry' do
+        assert_select 'link[href=?]', 'http://test.host/issues/11'
+      end
+    end
+  end
+
+  def test_index_atom_feed_with_explicit_selection
+    get :index, :format => 'atom', :with_subprojects => 0,
+      :show_changesets => 1,
+      :show_documents => 1,
+      :show_files => 1,
+      :show_issues => 1,
+      :show_messages => 1,
+      :show_news => 1,
+      :show_time_entries => 1,
+      :show_wiki_edits => 1
+
+    assert_response :success
+    assert_template 'common/feed'
+
+    assert_select 'feed' do
+      assert_select 'link[rel=self][href=?]', 'http://test.host/activity.atom?show_changesets=1&amp;show_documents=1&amp;show_files=1&amp;show_issues=1&amp;show_messages=1&amp;show_news=1&amp;show_time_entries=1&amp;show_wiki_edits=1&amp;with_subprojects=0'
+      assert_select 'link[rel=alternate][href=?]', 'http://test.host/activity?show_changesets=1&amp;show_documents=1&amp;show_files=1&amp;show_issues=1&amp;show_messages=1&amp;show_news=1&amp;show_time_entries=1&amp;show_wiki_edits=1&amp;with_subprojects=0'
+      assert_select 'entry' do
+        assert_select 'link[href=?]', 'http://test.host/issues/11'
+      end
+    end
+  end
+
+  def test_index_atom_feed_with_one_item_type
+    get :index, :format => 'atom', :show_issues => '1'
+    assert_response :success
+    assert_template 'common/feed'
+
+    assert_select 'title', :text => /Issues/
+  end
+
+  def test_index_should_show_private_notes_with_permission_only
+    journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Private notes with searchkeyword', :private_notes => true)
+    @request.session[:user_id] = 2
+
+    get :index
+    assert_response :success
+    assert_include journal, assigns(:events_by_day).values.flatten
+
+    Role.find(1).remove_permission! :view_private_notes
+    get :index
+    assert_response :success
+    assert_not_include journal, assigns(:events_by_day).values.flatten
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b5/b5d71b1233be49fcf1babc0bab7d8a2c992deddb.svn-base
--- /dev/null
+++ b/.svn/pristine/b5/b5d71b1233be49fcf1babc0bab7d8a2c992deddb.svn-base
@@ -0,0 +1,149 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module CustomFieldsHelper
+
+  def custom_fields_tabs
+    CustomField::CUSTOM_FIELDS_TABS
+  end
+
+  # Return custom field html tag corresponding to its format
+  def custom_field_tag(name, custom_value)
+    custom_field = custom_value.custom_field
+    field_name = "#{name}[custom_field_values][#{custom_field.id}]"
+    field_name << "[]" if custom_field.multiple?
+    field_id = "#{name}_custom_field_values_#{custom_field.id}"
+
+    tag_options = {:id => field_id, :class => "#{custom_field.field_format}_cf"}
+
+    field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format)
+    case field_format.try(:edit_as)
+    when "date"
+      text_field_tag(field_name, custom_value.value, tag_options.merge(:size => 10)) +
+      calendar_for(field_id)
+    when "text"
+      text_area_tag(field_name, custom_value.value, tag_options.merge(:rows => 3))
+    when "bool"
+      hidden_field_tag(field_name, '0') + check_box_tag(field_name, '1', custom_value.true?, tag_options)
+    when "list"
+      blank_option = ''.html_safe
+      unless custom_field.multiple?
+        if custom_field.is_required?
+          unless custom_field.default_value.present?
+            blank_option = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---", :value => '')
+          end
+        else
+          blank_option = content_tag('option')
+        end
+      end
+      s = select_tag(field_name, blank_option + options_for_select(custom_field.possible_values_options(custom_value.customized), custom_value.value),
+        tag_options.merge(:multiple => custom_field.multiple?))
+      if custom_field.multiple?
+        s << hidden_field_tag(field_name, '')
+      end
+      s
+    else
+      text_field_tag(field_name, custom_value.value, tag_options)
+    end
+  end
+
+  # Return custom field label tag
+  def custom_field_label_tag(name, custom_value, options={})
+    required = options[:required] || custom_value.custom_field.is_required?
+
+    content_tag "label", h(custom_value.custom_field.name) +
+      (required ? " <span class=\"required\">*</span>".html_safe : ""),
+      :for => "#{name}_custom_field_values_#{custom_value.custom_field.id}"
+  end
+
+  # Return custom field tag with its label tag
+  def custom_field_tag_with_label(name, custom_value, options={})
+    custom_field_label_tag(name, custom_value, options) + custom_field_tag(name, custom_value)
+  end
+
+  def custom_field_tag_for_bulk_edit(name, custom_field, projects=nil)
+    field_name = "#{name}[custom_field_values][#{custom_field.id}]"
+    field_name << "[]" if custom_field.multiple?
+    field_id = "#{name}_custom_field_values_#{custom_field.id}"
+
+    tag_options = {:id => field_id, :class => "#{custom_field.field_format}_cf"}
+
+    field_format = Redmine::CustomFieldFormat.find_by_name(custom_field.field_format)
+    case field_format.try(:edit_as)
+      when "date"
+        text_field_tag(field_name, '', tag_options.merge(:size => 10)) +
+        calendar_for(field_id)
+      when "text"
+        text_area_tag(field_name, '', tag_options.merge(:rows => 3))
+      when "bool"
+        select_tag(field_name, options_for_select([[l(:label_no_change_option), ''],
+                                                   [l(:general_text_yes), '1'],
+                                                   [l(:general_text_no), '0']]), tag_options)
+      when "list"
+        options = []
+        options << [l(:label_no_change_option), ''] unless custom_field.multiple?
+        options << [l(:label_none), '__none__'] unless custom_field.is_required?
+        options += custom_field.possible_values_options(projects)
+        select_tag(field_name, options_for_select(options), tag_options.merge(:multiple => custom_field.multiple?))
+      else
+        text_field_tag(field_name, '', tag_options)
+    end
+  end
+
+  # Return a string used to display a custom value
+  def show_value(custom_value)
+    return "" unless custom_value
+    format_value(custom_value.value, custom_value.custom_field.field_format)
+  end
+
+  # Return a string used to display a custom value
+  def format_value(value, field_format)
+    if value.is_a?(Array)
+      value.collect {|v| format_value(v, field_format)}.compact.sort.join(', ')
+    else
+      Redmine::CustomFieldFormat.format_value(value, field_format)
+    end
+  end
+
+  # Return an array of custom field formats which can be used in select_tag
+  def custom_field_formats_for_select(custom_field)
+    Redmine::CustomFieldFormat.as_select(custom_field.class.customized_class.name)
+  end
+
+  # Renders the custom_values in api views
+  def render_api_custom_values(custom_values, api)
+    api.array :custom_fields do
+      custom_values.each do |custom_value|
+        attrs = {:id => custom_value.custom_field_id, :name => custom_value.custom_field.name}
+        attrs.merge!(:multiple => true) if custom_value.custom_field.multiple?
+        api.custom_field attrs do
+          if custom_value.value.is_a?(Array)
+            api.array :value do
+              custom_value.value.each do |value|
+                api.value value unless value.blank?
+              end
+            end
+          else
+            api.value custom_value.value
+          end
+        end
+      end
+    end unless custom_values.empty?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b6/b60c09f950ca3bc2a75c168cc7ffe809b3b36299.svn-base
--- /dev/null
+++ b/.svn/pristine/b6/b60c09f950ca3bc2a75c168cc7ffe809b3b36299.svn-base
@@ -0,0 +1,73 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::AuthenticationTest < Redmine::ApiTest::Base
+  fixtures :users
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  def teardown
+    Setting.rest_api_enabled = '0'
+  end
+
+  def test_api_request_should_not_use_user_session
+    log_user('jsmith', 'jsmith')
+
+    get '/users/current'
+    assert_response :success
+
+    get '/users/current.json'
+    assert_response 401
+  end
+
+  def test_api_should_accept_switch_user_header_for_admin_user
+    user = User.find(1)
+    su = User.find(4)
+
+    get '/users/current', {}, {'X-Redmine-API-Key' => user.api_key, 'X-Redmine-Switch-User' => su.login}
+    assert_response :success
+    assert_equal su, assigns(:user)
+    assert_equal su, User.current
+  end
+
+  def test_api_should_respond_with_412_when_trying_to_switch_to_a_invalid_user
+    get '/users/current', {}, {'X-Redmine-API-Key' => User.find(1).api_key, 'X-Redmine-Switch-User' => 'foobar'}
+    assert_response 412
+  end
+
+  def test_api_should_respond_with_412_when_trying_to_switch_to_a_locked_user
+    user = User.find(5)
+    assert user.locked?
+
+    get '/users/current', {}, {'X-Redmine-API-Key' => User.find(1).api_key, 'X-Redmine-Switch-User' => user.login}
+    assert_response 412
+  end
+
+  def test_api_should_not_accept_switch_user_header_for_non_admin_user
+    user = User.find(2)
+    su = User.find(4)
+
+    get '/users/current', {}, {'X-Redmine-API-Key' => user.api_key, 'X-Redmine-Switch-User' => su.login}
+    assert_response :success
+    assert_equal user, assigns(:user)
+    assert_equal user, User.current
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b6/b612d779ff3fef92dfc91fea6eed6b0e5e922b26.svn-base
--- a/.svn/pristine/b6/b612d779ff3fef92dfc91fea6eed6b0e5e922b26.svn-base
+++ /dev/null
@@ -1,119 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class JournalsController < ApplicationController
-  before_filter :find_journal, :only => [:edit, :diff]
-  before_filter :find_issue, :only => [:new]
-  before_filter :find_optional_project, :only => [:index]
-  before_filter :authorize, :only => [:new, :edit, :diff]
-  accept_rss_auth :index
-  menu_item :issues
-
-  helper :issues
-  helper :custom_fields
-  helper :queries
-  include QueriesHelper
-  helper :sort
-  include SortHelper
-
-  def index
-    retrieve_query
-    sort_init 'id', 'desc'
-    sort_update(@query.sortable_columns)
-
-    if @query.valid?
-      @journals = @query.journals(:order => "#{Journal.table_name}.created_on DESC",
-                                  :limit => 25)
-    end
-    @title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name)
-    render :layout => false, :content_type => 'application/atom+xml'
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  def diff
-    @issue = @journal.issue
-    if params[:detail_id].present?
-      @detail = @journal.details.find_by_id(params[:detail_id])
-    else
-      @detail = @journal.details.detect {|d| d.prop_key == 'description'}
-    end
-    (render_404; return false) unless @issue && @detail
-    @diff = Redmine::Helpers::Diff.new(@detail.value, @detail.old_value)
-  end
-
-  def new
-    journal = Journal.find(params[:journal_id]) if params[:journal_id]
-    if journal
-      user = journal.user
-      text = journal.notes
-    else
-      user = @issue.author
-      text = @issue.description
-    end
-    # Replaces pre blocks with [...]
-    text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]')
-    content = "#{ll(Setting.default_language, :text_user_wrote, user)}\n> "
-    content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
-
-    render(:update) { |page|
-      page.<< "$('notes').value = \"#{escape_javascript content}\";"
-      page.show 'update'
-      page << "Form.Element.focus('notes');"
-      page << "Element.scrollTo('update');"
-      page << "$('notes').scrollTop = $('notes').scrollHeight - $('notes').clientHeight;"
-    }
-  end
-
-  def edit
-    (render_403; return false) unless @journal.editable_by?(User.current)
-    if request.post?
-      @journal.update_attributes(:notes => params[:notes]) if params[:notes]
-      @journal.destroy if @journal.details.empty? && @journal.notes.blank?
-      call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params})
-      respond_to do |format|
-        format.html { redirect_to :controller => 'issues', :action => 'show', :id => @journal.journalized_id }
-        format.js { render :action => 'update' }
-      end
-    else
-      respond_to do |format|
-        format.html {
-          # TODO: implement non-JS journal update
-          render :nothing => true
-        }
-        format.js
-      end
-    end
-  end
-
-  private
-
-  def find_journal
-    @journal = Journal.find(params[:id])
-    @project = @journal.journalized.project
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  # TODO: duplicated in IssuesController
-  def find_issue
-    @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
-    @project = @issue.project
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b6/b648e7261c6cf5a90c411f73fe039c9171cf83b0.svn-base
--- /dev/null
+++ b/.svn/pristine/b6/b648e7261c6cf5a90c411f73fe039c9171cf83b0.svn-base
@@ -0,0 +1,372 @@
+# -*- coding: utf-8 -*-
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class TimeEntryReportsControllerTest < ActionController::TestCase
+  tests TimelogController
+
+  fixtures :projects, :enabled_modules, :roles, :members, :member_roles,
+           :issues, :time_entries, :users, :trackers, :enumerations,
+           :issue_statuses, :custom_fields, :custom_values
+
+  include Redmine::I18n
+
+  def setup
+    Setting.default_language = "en"
+  end
+
+  def test_report_at_project_level
+    get :report, :project_id => 'ecookbook'
+    assert_response :success
+    assert_template 'report'
+    assert_tag :form,
+      :attributes => {:action => "/projects/ecookbook/time_entries/report", :id => 'query_form'}
+  end
+
+  def test_report_all_projects
+    get :report
+    assert_response :success
+    assert_template 'report'
+    assert_tag :form,
+      :attributes => {:action => "/time_entries/report", :id => 'query_form'}
+  end
+
+  def test_report_all_projects_denied
+    r = Role.anonymous
+    r.permissions.delete(:view_time_entries)
+    r.permissions_will_change!
+    r.save
+    get :report
+    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Ftime_entries%2Freport'
+  end
+
+  def test_report_all_projects_one_criteria
+    get :report, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criteria => ['project']
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:report)
+    assert_equal "8.65", "%.2f" % assigns(:report).total_hours
+  end
+
+  def test_report_all_time
+    get :report, :project_id => 1, :criteria => ['project', 'issue']
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:report)
+    assert_equal "162.90", "%.2f" % assigns(:report).total_hours
+  end
+
+  def test_report_all_time_by_day
+    get :report, :project_id => 1, :criteria => ['project', 'issue'], :columns => 'day'
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:report)
+    assert_equal "162.90", "%.2f" % assigns(:report).total_hours
+    assert_tag :tag => 'th', :content => '2007-03-12'
+  end
+
+  def test_report_one_criteria
+    get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criteria => ['project']
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:report)
+    assert_equal "8.65", "%.2f" % assigns(:report).total_hours
+  end
+
+  def test_report_two_criteria
+    get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criteria => ["user", "activity"]
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:report)
+    assert_equal "162.90", "%.2f" % assigns(:report).total_hours
+  end
+
+  def test_report_custom_field_criteria_with_multiple_values
+    field = TimeEntryCustomField.create!(:name => 'multi', :field_format => 'list', :possible_values => ['value1', 'value2'])
+    entry = TimeEntry.create!(:project => Project.find(1), :hours => 1, :activity_id => 10, :user => User.find(2), :spent_on => Date.today)
+    CustomValue.create!(:customized => entry, :custom_field => field, :value => 'value1')
+    CustomValue.create!(:customized => entry, :custom_field => field, :value => 'value2')
+
+    get :report, :project_id => 1, :columns => 'day', :criteria => ["cf_#{field.id}"]
+    assert_response :success
+  end
+
+  def test_report_one_day
+    get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criteria => ["user", "activity"]
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:report)
+    assert_equal "4.25", "%.2f" % assigns(:report).total_hours
+  end
+
+  def test_report_at_issue_level
+    get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criteria => ["user", "activity"]
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:report)
+    assert_equal "154.25", "%.2f" % assigns(:report).total_hours
+    assert_tag :form,
+      :attributes => {:action => "/projects/ecookbook/issues/1/time_entries/report", :id => 'query_form'}
+  end
+
+  def test_report_by_week_should_use_commercial_year
+    TimeEntry.delete_all
+    TimeEntry.generate!(:hours => '2', :spent_on => '2009-12-25') # 2009-52
+    TimeEntry.generate!(:hours => '4', :spent_on => '2009-12-31') # 2009-53
+    TimeEntry.generate!(:hours => '8', :spent_on => '2010-01-01') # 2009-53
+    TimeEntry.generate!(:hours => '16', :spent_on => '2010-01-05') # 2010-1
+
+    get :report, :columns => 'week', :from => "2009-12-25", :to => "2010-01-05", :criteria => ["project"]
+    assert_response :success
+
+    assert_select '#time-report thead tr' do
+      assert_select 'th:nth-child(1)', :text => 'Project'
+      assert_select 'th:nth-child(2)', :text => '2009-52'
+      assert_select 'th:nth-child(3)', :text => '2009-53'
+      assert_select 'th:nth-child(4)', :text => '2010-1'
+      assert_select 'th:nth-child(5)', :text => 'Total time'
+    end
+    assert_select '#time-report tbody tr' do
+      assert_select 'td:nth-child(1)', :text => 'eCookbook'
+      assert_select 'td:nth-child(2)', :text => '2.00'
+      assert_select 'td:nth-child(3)', :text => '12.00'
+      assert_select 'td:nth-child(4)', :text => '16.00'
+      assert_select 'td:nth-child(5)', :text => '30.00' # Total
+    end
+  end
+
+  def test_report_should_propose_association_custom_fields
+    get :report
+    assert_response :success
+    assert_template 'report'
+
+    assert_select 'select[name=?]', 'criteria[]' do
+      assert_select 'option[value=cf_1]', {:text => 'Database'}, 'Issue custom field not found'
+      assert_select 'option[value=cf_3]', {:text => 'Development status'}, 'Project custom field not found'
+      assert_select 'option[value=cf_7]', {:text => 'Billable'}, 'TimeEntryActivity custom field not found'
+    end
+  end
+
+  def test_report_with_association_custom_fields
+    get :report, :criteria => ['cf_1', 'cf_3', 'cf_7']
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:report)
+    assert_equal 3, assigns(:report).criteria.size
+    assert_equal "162.90", "%.2f" % assigns(:report).total_hours
+
+    # Custom fields columns
+    assert_select 'th', :text => 'Database'
+    assert_select 'th', :text => 'Development status'
+    assert_select 'th', :text => 'Billable'
+
+    # Custom field row
+    assert_select 'tr' do
+      assert_select 'td', :text => 'MySQL'
+      assert_select 'td.hours', :text => '1.00'
+    end
+  end
+
+  def test_report_one_criteria_no_result
+    get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criteria => ['project']
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:report)
+    assert_equal "0.00", "%.2f" % assigns(:report).total_hours
+  end
+
+  def test_report_status_criterion
+    get :report, :project_id => 1, :criteria => ['status']
+    assert_response :success
+    assert_template 'report'
+    assert_tag :tag => 'th', :content => 'Status'
+    assert_tag :tag => 'td', :content => 'New'
+  end
+
+  def test_report_all_projects_csv_export
+    get :report, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30",
+        :criteria => ["project", "user", "activity"], :format => "csv"
+    assert_response :success
+    assert_equal 'text/csv; header=present', @response.content_type
+    lines = @response.body.chomp.split("\n")
+    # Headers
+    assert_equal 'Project,User,Activity,2007-3,2007-4,Total time', lines.first
+    # Total row
+    assert_equal 'Total time,"","",154.25,8.65,162.90', lines.last
+  end
+
+  def test_report_csv_export
+    get :report, :project_id => 1, :columns => 'month',
+        :from => "2007-01-01", :to => "2007-06-30",
+        :criteria => ["project", "user", "activity"], :format => "csv"
+    assert_response :success
+    assert_equal 'text/csv; header=present', @response.content_type
+    lines = @response.body.chomp.split("\n")
+    # Headers
+    assert_equal 'Project,User,Activity,2007-3,2007-4,Total time', lines.first
+    # Total row
+    assert_equal 'Total time,"","",154.25,8.65,162.90', lines.last
+  end
+
+  def test_csv_big_5
+    Setting.default_language = "zh-TW"
+    str_utf8  = "\xe4\xb8\x80\xe6\x9c\x88"
+    str_big5  = "\xa4@\xa4\xeb"
+    if str_utf8.respond_to?(:force_encoding)
+      str_utf8.force_encoding('UTF-8')
+      str_big5.force_encoding('Big5')
+    end
+    user = User.find_by_id(3)
+    user.firstname = str_utf8
+    user.lastname  = "test-lastname"
+    assert user.save
+    comments = "test_csv_big_5"
+    te1 = TimeEntry.create(:spent_on => '2011-11-11',
+                           :hours    => 7.3,
+                           :project  => Project.find(1),
+                           :user     => user,
+                           :activity => TimeEntryActivity.find_by_name('Design'),
+                           :comments => comments)
+
+    te2 = TimeEntry.find_by_comments(comments)
+    assert_not_nil te2
+    assert_equal 7.3, te2.hours
+    assert_equal 3, te2.user_id
+
+    get :report, :project_id => 1, :columns => 'day',
+        :from => "2011-11-11", :to => "2011-11-11",
+        :criteria => ["user"], :format => "csv"
+    assert_response :success
+    assert_equal 'text/csv; header=present', @response.content_type
+    lines = @response.body.chomp.split("\n")    
+    # Headers
+    s1 = "\xa5\xce\xa4\xe1,2011-11-11,\xc1`\xadp"
+    s2 = "\xc1`\xadp"
+    if s1.respond_to?(:force_encoding)
+      s1.force_encoding('Big5')
+      s2.force_encoding('Big5')
+    end
+    assert_equal s1, lines.first
+    # Total row
+    assert_equal "#{str_big5} #{user.lastname},7.30,7.30", lines[1]
+    assert_equal "#{s2},7.30,7.30", lines[2]
+
+    str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
+    if str_tw.respond_to?(:force_encoding)
+      str_tw.force_encoding('UTF-8')
+    end
+    assert_equal str_tw, l(:general_lang_name)
+    assert_equal 'Big5', l(:general_csv_encoding)
+    assert_equal ',', l(:general_csv_separator)
+    assert_equal '.', l(:general_csv_decimal_separator)
+  end
+
+  def test_csv_cannot_convert_should_be_replaced_big_5
+    Setting.default_language = "zh-TW"
+    str_utf8  = "\xe4\xbb\xa5\xe5\x86\x85"
+    if str_utf8.respond_to?(:force_encoding)
+      str_utf8.force_encoding('UTF-8')
+    end
+    user = User.find_by_id(3)
+    user.firstname = str_utf8
+    user.lastname  = "test-lastname"
+    assert user.save
+    comments = "test_replaced"
+    te1 = TimeEntry.create(:spent_on => '2011-11-11',
+                           :hours    => 7.3,
+                           :project  => Project.find(1),
+                           :user     => user,
+                           :activity => TimeEntryActivity.find_by_name('Design'),
+                           :comments => comments)
+
+    te2 = TimeEntry.find_by_comments(comments)
+    assert_not_nil te2
+    assert_equal 7.3, te2.hours
+    assert_equal 3, te2.user_id
+
+    get :report, :project_id => 1, :columns => 'day',
+        :from => "2011-11-11", :to => "2011-11-11",
+        :criteria => ["user"], :format => "csv"
+    assert_response :success
+    assert_equal 'text/csv; header=present', @response.content_type
+    lines = @response.body.chomp.split("\n")    
+    # Headers
+    s1 = "\xa5\xce\xa4\xe1,2011-11-11,\xc1`\xadp"
+    if s1.respond_to?(:force_encoding)
+      s1.force_encoding('Big5')
+    end
+    assert_equal s1, lines.first
+    # Total row
+    s2 = ""
+    if s2.respond_to?(:force_encoding)
+      s2 = "\xa5H?"
+      s2.force_encoding('Big5')
+    elsif RUBY_PLATFORM == 'java'
+      s2 = "??"
+    else
+      s2 = "\xa5H???"
+    end
+    assert_equal "#{s2} #{user.lastname},7.30,7.30", lines[1]
+  end
+
+  def test_csv_fr
+    with_settings :default_language => "fr" do
+      str1  = "test_csv_fr"
+      user = User.find_by_id(3)
+      te1 = TimeEntry.create(:spent_on => '2011-11-11',
+                             :hours    => 7.3,
+                             :project  => Project.find(1),
+                             :user     => user,
+                             :activity => TimeEntryActivity.find_by_name('Design'),
+                             :comments => str1)
+
+      te2 = TimeEntry.find_by_comments(str1)
+      assert_not_nil te2
+      assert_equal 7.3, te2.hours
+      assert_equal 3, te2.user_id
+
+      get :report, :project_id => 1, :columns => 'day',
+          :from => "2011-11-11", :to => "2011-11-11",
+          :criteria => ["user"], :format => "csv"
+      assert_response :success
+      assert_equal 'text/csv; header=present', @response.content_type
+      lines = @response.body.chomp.split("\n")    
+      # Headers
+      s1 = "Utilisateur;2011-11-11;Temps total"
+      s2 = "Temps total"
+      if s1.respond_to?(:force_encoding)
+        s1.force_encoding('ISO-8859-1')
+        s2.force_encoding('ISO-8859-1')
+      end
+      assert_equal s1, lines.first
+      # Total row
+      assert_equal "#{user.firstname} #{user.lastname};7,30;7,30", lines[1]
+      assert_equal "#{s2};7,30;7,30", lines[2]
+
+      str_fr = "Fran\xc3\xa7ais"
+      if str_fr.respond_to?(:force_encoding)
+        str_fr.force_encoding('UTF-8')
+      end
+      assert_equal str_fr, l(:general_lang_name)
+      assert_equal 'ISO-8859-1', l(:general_csv_encoding)
+      assert_equal ';', l(:general_csv_separator)
+      assert_equal ',', l(:general_csv_decimal_separator)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b6/b6683def4ff299aa9cca77fe57bb77ce73743047.svn-base
--- a/.svn/pristine/b6/b6683def4ff299aa9cca77fe57bb77ce73743047.svn-base
+++ /dev/null
@@ -1,21 +0,0 @@
-module PrependEngineViews
-  def self.included(base)
-    base.send(:include, InstanceMethods)
-    base.class_eval do
-      alias_method_chain :add_engine_view_paths, :prepend
-    end
-  end
-
-  module InstanceMethods
-    # Patch Rails so engine's views are prepended to the view_path,
-    # thereby letting plugins override application views
-    def add_engine_view_paths_with_prepend
-      paths = ActionView::PathSet.new(engines.collect(&:view_path))
-      ActionController::Base.view_paths.unshift(*paths)
-      ActionMailer::Base.view_paths.unshift(*paths) if configuration.frameworks.include?(:action_mailer)
-    end
-  end
-end
-
-Rails::Plugin::Loader.send :include, PrependEngineViews
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b6/b6a2caf496a03e85c1175dd3619219a219866eff.svn-base
--- a/.svn/pristine/b6/b6a2caf496a03e85c1175dd3619219a219866eff.svn-base
+++ /dev/null
@@ -1,19 +0,0 @@
-<% @hours.collect {|h| h[criterias[level]].to_s}.uniq.each do |value| %>
-<% hours_for_value = select_hours(hours, criterias[level], value) -%>
-<% next if hours_for_value.empty? -%>
-<tr class="<%= cycle('odd', 'even') %> <%= 'last-level' unless criterias.length > level+1 %>">
-<%= '<td></td>' * level %>
-<td><%= h(format_criteria_value(criterias[level], value)) %></td>
-<%= '<td></td>' * (criterias.length - level - 1) -%>
-  <% total = 0 -%>
-  <% @periods.each do |period| -%>
-    <% sum = sum_hours(select_hours(hours_for_value, @columns, period.to_s)); total += sum -%>
-    <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
-  <% end -%>
-  <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
-</tr>
-<% if criterias.length > level+1 -%>
-  <%= render(:partial => 'report_criteria', :locals => {:criterias => criterias, :hours => hours_for_value, :level => (level + 1)}) %>
-<% end -%>
-
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b6/b6d670172a09c11965c73ff10d0fdb7558766e0d.svn-base
--- a/.svn/pristine/b6/b6d670172a09c11965c73ff10d0fdb7558766e0d.svn-base
+++ /dev/null
@@ -1,54 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# FileSystem adapter
-# File written by Paul Rivier, at Demotera.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/filesystem_adapter'
-
-class Repository::Filesystem < Repository
-  attr_protected :root_url
-  validates_presence_of :url
-
-  def self.human_attribute_name(attribute_key_name)
-    attr_name = attribute_key_name
-    if attr_name == "url"
-      attr_name = "root_directory"
-    end
-    super(attr_name)
-  end
-
-  def self.scm_adapter_class
-    Redmine::Scm::Adapters::FilesystemAdapter
-  end
-
-  def self.scm_name
-    'Filesystem'
-  end
-
-  def supports_all_revisions?
-    false
-  end
-
-  def entries(path=nil, identifier=nil)
-    scm.entries(path, identifier)
-  end
-
-  def fetch_changesets
-    nil
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b7/b74317bccac34414d54322b279285d4bd780b35b.svn-base
--- /dev/null
+++ b/.svn/pristine/b7/b74317bccac34414d54322b279285d4bd780b35b.svn-base
@@ -0,0 +1,1108 @@
+# Hungarian translations for Ruby on Rails
+# by Richard Abonyi (richard.abonyi@gmail.com)
+# thanks to KKata, replaced and #hup.hu
+# Cleaned up by LÃ¡szlÃ³ BÃ¡csi (http://lackac.hu)
+# updated by kfl62 kfl62g@gmail.com
+# updated by GÃ¡bor TakÃ¡cs (taky77@gmail.com)
+
+"hu":
+  direction: ltr
+  date:
+    formats:
+      default: "%Y.%m.%d."
+      short: "%b %e."
+      long: "%Y. %B %e."
+    day_names: [vasÃ¡rnap, hÃ©tfÅ‘, kedd, szerda, csÃ¼tÃ¶rtÃ¶k, pÃ©ntek, szombat]
+    abbr_day_names: [v., h., k., sze., cs., p., szo.]
+    month_names: [~, januÃ¡r, februÃ¡r, mÃ¡rcius, Ã¡prilis, mÃ¡jus, jÃºnius, jÃºlius, augusztus, szeptember, oktÃ³ber, november, december]
+    abbr_month_names: [~, jan., febr., mÃ¡rc., Ã¡pr., mÃ¡j., jÃºn., jÃºl., aug., szept., okt., nov., dec.]
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%Y. %b %d., %H:%M"
+      time: "%H:%M"
+      short: "%b %e., %H:%M"
+      long: "%Y. %B %e., %A, %H:%M"
+    am: "de."
+    pm: "du."
+
+  datetime:
+    distance_in_words:
+      half_a_minute: 'fÃ©l perc'
+      less_than_x_seconds:
+#        zero: 'kevesebb, mint 1 mÃ¡sodperce'
+        one: 'kevesebb, mint 1 mÃ¡sodperce'
+        other: 'kevesebb, mint %{count} mÃ¡sodperce'
+      x_seconds:
+        one: '1 mÃ¡sodperce'
+        other: '%{count} mÃ¡sodperce'
+      less_than_x_minutes:
+#        zero: 'kevesebb, mint 1 perce'
+        one: 'kevesebb, mint 1 perce'
+        other: 'kevesebb, mint %{count} perce'
+      x_minutes:
+        one: '1 perce'
+        other: '%{count} perce'
+      about_x_hours:
+        one: 'csaknem 1 Ã³rÃ¡ja'
+        other: 'csaknem %{count} Ã³rÃ¡ja'
+      x_hours:
+        one:   "1 Ã³ra"
+        other: "%{count} Ã³ra"
+      x_days:
+        one: '1 napja'
+        other: '%{count} napja'
+      about_x_months:
+        one: 'csaknem 1 hÃ³napja'
+        other: 'csaknem %{count} hÃ³napja'
+      x_months:
+        one: '1 hÃ³napja'
+        other: '%{count} hÃ³napja'
+      about_x_years:
+        one: 'csaknem 1 Ã©ve'
+        other: 'csaknem %{count} Ã©ve'
+      over_x_years:
+        one: 'tÃ¶bb, mint 1 Ã©ve'
+        other: 'tÃ¶bb, mint %{count} Ã©ve'
+      almost_x_years:
+        one:   "csaknem 1 Ã©ve"
+        other: "csaknem %{count} Ã©ve"
+    prompts:
+      year:   "Ã‰v"
+      month:  "HÃ³nap"
+      day:    "Nap"
+      hour:   "Ã“ra"
+      minute: "Perc"
+      second: "MÃ¡sodperc"
+
+  number:
+    format:
+      precision: 2
+      separator: ','
+      delimiter: ' '
+    currency:
+      format:
+        unit: 'Ft'
+        precision: 0
+        format: '%n %u'
+        separator: ","
+        delimiter: ""
+    percentage:
+      format:
+        delimiter: ""
+    precision:
+      format:
+        delimiter: ""
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "bÃ¡jt"
+            other: "bÃ¡jt"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  support:
+    array:
+#      sentence_connector: "Ã©s"
+#      skip_last_comma: true
+      words_connector: ", "
+      two_words_connector: " Ã©s "
+      last_word_connector: " Ã©s "
+  activerecord:
+    errors:
+      template:
+        header:
+          one: "1 hiba miatt nem menthetÅ‘ a kÃ¶vetkezÅ‘: %{model}"
+          other: "%{count} hiba miatt nem menthetÅ‘ a kÃ¶vetkezÅ‘: %{model}"
+        body: "ProblÃ©mÃ¡s mezÅ‘k:"
+      messages:
+        inclusion: "nincs a listÃ¡ban"
+        exclusion: "nem elÃ©rhetÅ‘"
+        invalid: "nem megfelelÅ‘"
+        confirmation: "nem egyezik"
+        accepted: "nincs elfogadva"
+        empty: "nincs megadva"
+        blank: "nincs megadva"
+        too_long: "tÃºl hosszÃº (nem lehet tÃ¶bb %{count} karakternÃ©l)"
+        too_short: "tÃºl rÃ¶vid (legalÃ¡bb %{count} karakter kell legyen)"
+        wrong_length: "nem megfelelÅ‘ hosszÃºsÃ¡gÃº (%{count} karakter szÃ¼ksÃ©ges)"
+        taken: "mÃ¡r foglalt"
+        not_a_number: "nem szÃ¡m"
+        greater_than: "nagyobb kell legyen, mint %{count}"
+        greater_than_or_equal_to: "legalÃ¡bb %{count} kell legyen"
+        equal_to: "pontosan %{count} kell legyen"
+        less_than: "kevesebb, mint %{count} kell legyen"
+        less_than_or_equal_to: "legfeljebb %{count} lehet"
+        odd: "pÃ¡ratlan kell legyen"
+        even: "pÃ¡ros kell legyen"
+        greater_than_start_date: "nagyobbnak kell lennie, mint az indÃ­tÃ¡s dÃ¡tuma"
+        not_same_project: "nem azonos projekthez tartozik"
+        circular_dependency: "Ez a kapcsolat egy kÃ¶rkÃ¶rÃ¶s fÃ¼ggÅ‘sÃ©get eredmÃ©nyez"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: KÃ©rem vÃ¡lasszon
+
+  general_text_No: 'Nem'
+  general_text_Yes: 'Igen'
+  general_text_no: 'nem'
+  general_text_yes: 'igen'
+  general_lang_name: 'Magyar'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-2
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: A fiÃ³k adatai sikeresen frissÃ­tve.
+  notice_account_invalid_creditentials: HibÃ¡s felhasznÃ¡lÃ³i nÃ©v, vagy jelszÃ³
+  notice_account_password_updated: A jelszÃ³ mÃ³dosÃ­tÃ¡sa megtÃ¶rtÃ©nt.
+  notice_account_wrong_password: HibÃ¡s jelszÃ³
+  notice_account_register_done: A fiÃ³k sikeresen lÃ©trehozva. AktivÃ¡lÃ¡sÃ¡hoz kattints az e-mailben kapott linkre
+  notice_account_unknown_email: Ismeretlen felhasznÃ¡lÃ³.
+  notice_can_t_change_password: A fiÃ³k kÃ¼lsÅ‘ azonosÃ­tÃ¡si forrÃ¡st hasznÃ¡l. A jelszÃ³ megvÃ¡ltoztatÃ¡sa nem lehetsÃ©ges.
+  notice_account_lost_email_sent: Egy e-mail Ã¼zenetben postÃ¡ztunk Ã–nnek egy leÃ­rÃ¡st az Ãºj jelszÃ³ beÃ¡llÃ­tÃ¡sÃ¡rÃ³l.
+  notice_account_activated: FiÃ³kjÃ¡t aktivÃ¡ltuk. Most mÃ¡r be tud jelentkezni a rendszerbe.
+  notice_successful_create: Sikeres lÃ©trehozÃ¡s.
+  notice_successful_update: Sikeres mÃ³dosÃ­tÃ¡s.
+  notice_successful_delete: Sikeres tÃ¶rlÃ©s.
+  notice_successful_connection: Sikeres bejelentkezÃ©s.
+  notice_file_not_found: Az oldal, amit meg szeretne nÃ©zni nem talÃ¡lhatÃ³, vagy Ã¡tkerÃ¼lt egy mÃ¡sik helyre.
+  notice_locking_conflict: Az adatot egy mÃ¡sik felhasznÃ¡lÃ³ idÅ‘ kÃ¶zben mÃ³dosÃ­totta.
+  notice_not_authorized: Nincs hozzÃ¡fÃ©rÃ©si engedÃ©lye ehhez az oldalhoz.
+  notice_email_sent: "Egy e-mail Ã¼zenetet kÃ¼ldtÃ¼nk a kÃ¶vetkezÅ‘ cÃ­mre %{value}"
+  notice_email_error: "Hiba tÃ¶rtÃ©nt a levÃ©l kÃ¼ldÃ©se kÃ¶zben (%{value})"
+  notice_feeds_access_key_reseted: Az RSS hozzÃ¡fÃ©rÃ©si kulcsÃ¡t Ãºjra generÃ¡ltuk.
+  notice_failed_to_save_issues: "Nem sikerÃ¼lt a %{count} feladat(ok) mentÃ©se a %{total} -ban kivÃ¡lasztva: %{ids}."
+  notice_no_issue_selected: "Nincs feladat kivÃ¡lasztva! KÃ©rem jelÃ¶lje meg melyik feladatot szeretnÃ© szerkeszteni!"
+  notice_account_pending: "A fiÃ³kja lÃ©trejÃ¶tt, Ã©s adminisztrÃ¡tori jÃ³vÃ¡hagyÃ¡sra vÃ¡r."
+  notice_default_data_loaded: Az alapÃ©rtelmezett konfigurÃ¡ciÃ³ betÃ¶ltÃ©se sikeresen megtÃ¶rtÃ©nt.
+
+  error_can_t_load_default_data: "Az alapÃ©rtelmezett konfigurÃ¡ciÃ³ betÃ¶ltÃ©se nem lehetsÃ©ges: %{value}"
+  error_scm_not_found: "A bejegyzÃ©s, vagy revÃ­ziÃ³ nem talÃ¡lhatÃ³ a tÃ¡rolÃ³ban."
+  error_scm_command_failed: "A tÃ¡rolÃ³ elÃ©rÃ©se kÃ¶zben hiba lÃ©pett fel: %{value}"
+  error_scm_annotate: "A bejegyzÃ©s nem lÃ©tezik, vagy nics jegyzetekkel ellÃ¡tva."
+  error_issue_not_found_in_project: 'A feladat nem talÃ¡lhatÃ³, vagy nem ehhez a projekthez tartozik'
+
+  mail_subject_lost_password: Az Ã–n Redmine jelszava
+  mail_body_lost_password: 'A Redmine jelszÃ³ megvÃ¡ltoztatÃ¡sÃ¡hoz, kattintson a kÃ¶vetkezÅ‘ linkre:'
+  mail_subject_register: Redmine azonosÃ­tÃ³ aktivÃ¡lÃ¡sa
+  mail_body_register: 'A Redmine azonosÃ­tÃ³ja aktivÃ¡lÃ¡sÃ¡hoz, kattintson a kÃ¶vetkezÅ‘ linkre:'
+  mail_body_account_information_external: "A %{value} azonosÃ­tÃ³ hasznÃ¡latÃ¡val bejelentkezhet a Redmine-ba."
+  mail_body_account_information: Az Ã–n Redmine azonosÃ­tÃ³jÃ¡nak informÃ¡ciÃ³i
+  mail_subject_account_activation_request: Redmine azonosÃ­tÃ³ aktivÃ¡lÃ¡si kÃ©relem
+  mail_body_account_activation_request: "Egy Ãºj felhasznÃ¡lÃ³ (%{value}) regisztrÃ¡lt, azonosÃ­tÃ³ja jÃ³vÃ¡hasgyÃ¡sra vÃ¡rakozik:"
+
+
+  field_name: NÃ©v
+  field_description: LeÃ­rÃ¡s
+  field_summary: Ã–sszegzÃ©s
+  field_is_required: KÃ¶telezÅ‘
+  field_firstname: KeresztnÃ©v
+  field_lastname: VezetÃ©knÃ©v
+  field_mail: E-mail
+  field_filename: FÃ¡jl
+  field_filesize: MÃ©ret
+  field_downloads: LetÃ¶ltÃ©sek
+  field_author: SzerzÅ‘
+  field_created_on: LÃ©trehozva
+  field_updated_on: MÃ³dosÃ­tva
+  field_field_format: FormÃ¡tum
+  field_is_for_all: Minden projekthez
+  field_possible_values: LehetsÃ©ges Ã©rtÃ©kek
+  field_regexp: RegulÃ¡ris kifejezÃ©s
+  field_min_length: Minimum hossz
+  field_max_length: Maximum hossz
+  field_value: Ã‰rtÃ©k
+  field_category: KategÃ³ria
+  field_title: CÃ­m
+  field_project: Projekt
+  field_issue: Feladat
+  field_status: StÃ¡tusz
+  field_notes: FeljegyzÃ©sek
+  field_is_closed: Feladat lezÃ¡rva
+  field_is_default: AlapÃ©rtelmezett Ã©rtÃ©k
+  field_tracker: TÃ­pus
+  field_subject: TÃ¡rgy
+  field_due_date: BefejezÃ©s dÃ¡tuma
+  field_assigned_to: FelelÅ‘s
+  field_priority: PrioritÃ¡s
+  field_fixed_version: CÃ©l verziÃ³
+  field_user: FelhasznÃ¡lÃ³
+  field_role: SzerepkÃ¶r
+  field_homepage: Weboldal
+  field_is_public: NyilvÃ¡nos
+  field_parent: SzÃ¼lÅ‘ projekt
+  field_is_in_roadmap: Feladatok lÃ¡tszanak az Ã©letÃºtban
+  field_login: AzonosÃ­tÃ³
+  field_mail_notification: E-mail Ã©rtesÃ­tÃ©sek
+  field_admin: AdminisztrÃ¡tor
+  field_last_login_on: UtolsÃ³ bejelentkezÃ©s
+  field_language: Nyelv
+  field_effective_date: DÃ¡tum
+  field_password: JelszÃ³
+  field_new_password: Ãšj jelszÃ³
+  field_password_confirmation: MegerÅ‘sÃ­tÃ©s
+  field_version: VerziÃ³
+  field_type: TÃ­pus
+  field_host: KiszolgÃ¡lÃ³
+  field_port: Port
+  field_account: FelhasznÃ¡lÃ³i fiÃ³k
+  field_base_dn: Base DN
+  field_attr_login: BejelentkezÃ©si tulajdonsÃ¡g
+  field_attr_firstname: KeresztnÃ©v
+  field_attr_lastname: VezetÃ©knÃ©v
+  field_attr_mail: E-mail
+  field_onthefly: On-the-fly felhasznÃ¡lÃ³ lÃ©trehozÃ¡s
+  field_start_date: KezdÃ©s dÃ¡tuma
+  field_done_ratio: KÃ©szÃ¼ltsÃ©g (%)
+  field_auth_source: AzonosÃ­tÃ¡si mÃ³d
+  field_hide_mail: Rejtse el az e-mail cÃ­mem
+  field_comments: MegjegyzÃ©s
+  field_url: URL
+  field_start_page: KezdÅ‘lap
+  field_subproject: Alprojekt
+  field_hours: Ã“ra
+  field_activity: AktivitÃ¡s
+  field_spent_on: DÃ¡tum
+  field_identifier: AzonosÃ­tÃ³
+  field_is_filter: SzÅ±rÅ‘kÃ©nt hasznÃ¡lhatÃ³
+  field_issue_to: KapcsolÃ³dÃ³ feladat
+  field_delay: KÃ©sÃ©s
+  field_assignable: Feladat rendelhetÅ‘ ehhez a szerepkÃ¶rhÃ¶z
+  field_redirect_existing_links: LÃ©tezÅ‘ linkek Ã¡tirÃ¡nyÃ­tÃ¡sa
+  field_estimated_hours: BecsÃ¼lt idÅ‘igÃ©ny
+  field_column_names: Oszlopok
+  field_time_zone: IdÅ‘zÃ³na
+  field_searchable: KereshetÅ‘
+  field_default_value: AlapÃ©rtelmezett Ã©rtÃ©k
+  field_comments_sorting: FeljegyzÃ©sek megjelenÃ­tÃ©se
+
+  setting_app_title: AlkalmazÃ¡s cÃ­me
+  setting_app_subtitle: AlkalmazÃ¡s alcÃ­me
+  setting_welcome_text: ÃœdvÃ¶zlÅ‘ Ã¼zenet
+  setting_default_language: AlapÃ©rtelmezett nyelv
+  setting_login_required: AzonosÃ­tÃ¡s szÃ¼ksÃ©ges
+  setting_self_registration: RegisztrÃ¡ciÃ³
+  setting_attachment_max_size: MellÃ©klet max. mÃ©rete
+  setting_issues_export_limit: Feladatok exportÃ¡lÃ¡sÃ¡nak korlÃ¡tja
+  setting_mail_from: KibocsÃ¡tÃ³ e-mail cÃ­me
+  setting_bcc_recipients: Titkos mÃ¡solat cÃ­mzet (bcc)
+  setting_host_name: KiszolgÃ¡lÃ³ neve
+  setting_text_formatting: SzÃ¶veg formÃ¡zÃ¡s
+  setting_wiki_compression: Wiki tÃ¶rtÃ©net tÃ¶mÃ¶rÃ­tÃ©s
+  setting_feeds_limit: RSS tartalom korlÃ¡t
+  setting_default_projects_public: Az Ãºj projektek alapÃ©rtelmezÃ©s szerint nyilvÃ¡nosak
+  setting_autofetch_changesets: Commitok automatikus lehÃºzÃ¡sa
+  setting_sys_api_enabled: WS engedÃ©lyezÃ©se a tÃ¡rolÃ³k kezelÃ©sÃ©hez
+  setting_commit_ref_keywords: HivatkozÃ³ kulcsszavak
+  setting_commit_fix_keywords: JavÃ­tÃ¡sok kulcsszavai
+  setting_autologin: Automatikus bejelentkezÃ©s
+  setting_date_format: DÃ¡tum formÃ¡tum
+  setting_time_format: IdÅ‘ formÃ¡tum
+  setting_cross_project_issue_relations: Kereszt-projekt feladat hivatkozÃ¡sok engedÃ©lyezÃ©se
+  setting_issue_list_default_columns: Az alapÃ©rtelmezÃ©skÃ©nt megjelenÃ­tett oszlopok a feladat listÃ¡ban
+  setting_emails_footer: E-mail lÃ¡blÃ©c
+  setting_protocol: Protokol
+  setting_per_page_options: Objektum / oldal opciÃ³k
+  setting_user_format: FelhasznÃ¡lÃ³k megjelenÃ­tÃ©sÃ©nek formÃ¡ja
+  setting_activity_days_default: Napok megjelenÃ­tÃ©se a project aktivitÃ¡snÃ¡l
+  setting_display_subprojects_issues: AlapÃ©rtelmezettkÃ©nt mutassa az alprojektek feladatait is a projekteken
+  setting_start_of_week: A hÃ©t elsÅ‘ napja
+
+  project_module_issue_tracking: Feladat kÃ¶vetÃ©s
+  project_module_time_tracking: IdÅ‘ rÃ¶gzÃ­tÃ©s
+  project_module_news: HÃ­rek
+  project_module_documents: Dokumentumok
+  project_module_files: FÃ¡jlok
+  project_module_wiki: Wiki
+  project_module_repository: ForrÃ¡skÃ³d
+  project_module_boards: FÃ³rumok
+
+  label_user: FelhasznÃ¡lÃ³
+  label_user_plural: FelhasznÃ¡lÃ³k
+  label_user_new: Ãšj felhasznÃ¡lÃ³
+  label_project: Projekt
+  label_project_new: Ãšj projekt
+  label_project_plural: Projektek
+  label_x_projects:
+    zero:  nincsenek projektek
+    one:   1 projekt
+    other: "%{count} projekt"
+  label_project_all: Az Ã¶sszes projekt
+  label_project_latest: LegutÃ³bbi projektek
+  label_issue: Feladat
+  label_issue_new: Ãšj feladat
+  label_issue_plural: Feladatok
+  label_issue_view_all: Minden feladat
+  label_issues_by: "%{value} feladatai"
+  label_issue_added: Feladat hozzÃ¡adva
+  label_issue_updated: Feladat frissÃ­tve
+  label_document: Dokumentum
+  label_document_new: Ãšj dokumentum
+  label_document_plural: Dokumentumok
+  label_document_added: Dokumentum hozzÃ¡adva
+  label_role: SzerepkÃ¶r
+  label_role_plural: SzerepkÃ¶rÃ¶k
+  label_role_new: Ãšj szerepkÃ¶r
+  label_role_and_permissions: SzerepkÃ¶rÃ¶k, Ã©s jogosultsÃ¡gok
+  label_member: RÃ©sztvevÅ‘
+  label_member_new: Ãšj rÃ©sztvevÅ‘
+  label_member_plural: RÃ©sztvevÅ‘k
+  label_tracker: Feladat tÃ­pus
+  label_tracker_plural: Feladat tÃ­pusok
+  label_tracker_new: Ãšj feladat tÃ­pus
+  label_workflow: Workflow
+  label_issue_status: Feladat stÃ¡tusz
+  label_issue_status_plural: Feladat stÃ¡tuszok
+  label_issue_status_new: Ãšj stÃ¡tusz
+  label_issue_category: Feladat kategÃ³ria
+  label_issue_category_plural: Feladat kategÃ³riÃ¡k
+  label_issue_category_new: Ãšj kategÃ³ria
+  label_custom_field: EgyÃ©ni mezÅ‘
+  label_custom_field_plural: EgyÃ©ni mezÅ‘k
+  label_custom_field_new: Ãšj egyÃ©ni mezÅ‘
+  label_enumerations: FelsorolÃ¡sok
+  label_enumeration_new: Ãšj Ã©rtÃ©k
+  label_information: InformÃ¡ciÃ³
+  label_information_plural: InformÃ¡ciÃ³k
+  label_please_login: Jelentkezzen be
+  label_register: RegisztrÃ¡ljon
+  label_password_lost: Elfelejtett jelszÃ³
+  label_home: KezdÅ‘lap
+  label_my_page: SajÃ¡t kezdÅ‘lapom
+  label_my_account: FiÃ³kom adatai
+  label_my_projects: SajÃ¡t projektem
+  label_administration: AdminisztrÃ¡ciÃ³
+  label_login: BejelentkezÃ©s
+  label_logout: KijelentkezÃ©s
+  label_help: SÃºgÃ³
+  label_reported_issues: Bejelentett feladatok
+  label_assigned_to_me_issues: A nekem kiosztott feladatok
+  label_last_login: UtolsÃ³ bejelentkezÃ©s
+  label_registered_on: RegisztrÃ¡lt
+  label_activity: TÃ¶rtÃ©nÃ©sek
+  label_overall_activity: Teljes aktivitÃ¡s
+  label_new: Ãšj
+  label_logged_as: Bejelentkezve, mint
+  label_environment: KÃ¶rnyezet
+  label_authentication: AzonosÃ­tÃ¡s
+  label_auth_source: AzonosÃ­tÃ¡s mÃ³dja
+  label_auth_source_new: Ãšj azonosÃ­tÃ¡si mÃ³d
+  label_auth_source_plural: AzonosÃ­tÃ¡si mÃ³dok
+  label_subproject_plural: Alprojektek
+  label_and_its_subprojects: "%{value} Ã©s alprojektjei"
+  label_min_max_length: Min - Max hossz
+  label_list: Lista
+  label_date: DÃ¡tum
+  label_integer: EgÃ©sz
+  label_float: LebegÅ‘pontos
+  label_boolean: Logikai
+  label_string: SzÃ¶veg
+  label_text: HosszÃº szÃ¶veg
+  label_attribute: TulajdonsÃ¡g
+  label_attribute_plural: TulajdonsÃ¡gok
+  label_no_data: Nincs megjelenÃ­thetÅ‘ adat
+  label_change_status: StÃ¡tusz mÃ³dosÃ­tÃ¡sa
+  label_history: TÃ¶rtÃ©net
+  label_attachment: FÃ¡jl
+  label_attachment_new: Ãšj fÃ¡jl
+  label_attachment_delete: FÃ¡jl tÃ¶rlÃ©se
+  label_attachment_plural: FÃ¡jlok
+  label_file_added: FÃ¡jl hozzÃ¡adva
+  label_report: JelentÃ©s
+  label_report_plural: JelentÃ©sek
+  label_news: HÃ­rek
+  label_news_new: HÃ­r hozzÃ¡adÃ¡sa
+  label_news_plural: HÃ­rek
+  label_news_latest: LegutÃ³bbi hÃ­rek
+  label_news_view_all: Minden hÃ­r megtekintÃ©se
+  label_news_added: HÃ­r hozzÃ¡adva
+  label_settings: BeÃ¡llÃ­tÃ¡sok
+  label_overview: ÃttekintÃ©s
+  label_version: VerziÃ³
+  label_version_new: Ãšj verziÃ³
+  label_version_plural: VerziÃ³k
+  label_confirmation: JÃ³vÃ¡hagyÃ¡s
+  label_export_to: ExportÃ¡lÃ¡s
+  label_read: Olvas...
+  label_public_projects: NyilvÃ¡nos projektek
+  label_open_issues: nyitott
+  label_open_issues_plural: nyitott
+  label_closed_issues: lezÃ¡rt
+  label_closed_issues_plural: lezÃ¡rt
+  label_x_open_issues_abbr_on_total:
+    zero:  nyitott 0 / %{total}
+    one:   nyitott 1 / %{total}
+    other: "nyitott %{count} / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 nyitott
+    one:   1 nyitott
+    other: "%{count} nyitott"
+  label_x_closed_issues_abbr:
+    zero:  0 lezÃ¡rt
+    one:   1 lezÃ¡rt
+    other: "%{count} lezÃ¡rt"
+  label_total: Ã–sszesen
+  label_permissions: JogosultsÃ¡gok
+  label_current_status: Jelenlegi stÃ¡tusz
+  label_new_statuses_allowed: StÃ¡tusz vÃ¡ltoztatÃ¡sok engedÃ©lyei
+  label_all: mind
+  label_none: nincs
+  label_nobody: senki
+  label_next: KÃ¶vetkezÅ‘
+  label_previous: ElÅ‘zÅ‘
+  label_used_by: HasznÃ¡lja
+  label_details: RÃ©szletek
+  label_add_note: Jegyzet hozzÃ¡adÃ¡sa
+  label_per_page: OldalankÃ©nt
+  label_calendar: NaptÃ¡r
+  label_months_from: hÃ³nap, kezdve
+  label_gantt: Gantt
+  label_internal: BelsÅ‘
+  label_last_changes: "utolsÃ³ %{count} vÃ¡ltozÃ¡s"
+  label_change_view_all: Minden vÃ¡ltozÃ¡s megtekintÃ©se
+  label_personalize_page: Az oldal testreszabÃ¡sa
+  label_comment: MegjegyzÃ©s
+  label_comment_plural: MegjegyzÃ©s
+  label_x_comments:
+    zero: nincs megjegyzÃ©s
+    one: 1 megjegyzÃ©s
+    other: "%{count} megjegyzÃ©s"
+  label_comment_add: MegjegyzÃ©s hozzÃ¡adÃ¡sa
+  label_comment_added: MegjegyzÃ©s hozzÃ¡adva
+  label_comment_delete: MegjegyzÃ©sek tÃ¶rlÃ©se
+  label_query: EgyÃ©ni lekÃ©rdezÃ©s
+  label_query_plural: EgyÃ©ni lekÃ©rdezÃ©sek
+  label_query_new: Ãšj lekÃ©rdezÃ©s
+  label_filter_add: SzÅ±rÅ‘ hozzÃ¡adÃ¡sa
+  label_filter_plural: SzÅ±rÅ‘k
+  label_equals: egyenlÅ‘
+  label_not_equals: nem egyenlÅ‘
+  label_in_less_than: kevesebb, mint
+  label_in_more_than: tÃ¶bb, mint
+  label_in: in
+  label_today: ma
+  label_all_time: mindenkor
+  label_yesterday: tegnap
+  label_this_week: aktuÃ¡lis hÃ©t
+  label_last_week: mÃºlt hÃ©t
+  label_last_n_days: "az elmÃºlt %{count} nap"
+  label_this_month: aktuÃ¡lis hÃ³nap
+  label_last_month: mÃºlt hÃ³nap
+  label_this_year: aktuÃ¡lis Ã©v
+  label_date_range: DÃ¡tum intervallum
+  label_less_than_ago: kevesebb, mint nappal ezelÅ‘tt
+  label_more_than_ago: tÃ¶bb, mint nappal ezelÅ‘tt
+  label_ago: nappal ezelÅ‘tt
+  label_contains: tartalmazza
+  label_not_contains: nem tartalmazza
+  label_day_plural: nap
+  label_repository: ForrÃ¡skÃ³d
+  label_repository_plural: ForrÃ¡skÃ³dok
+  label_browse: TallÃ³z
+  label_revision: RevÃ­ziÃ³
+  label_revision_plural: RevÃ­ziÃ³k
+  label_associated_revisions: Kapcsolt revÃ­ziÃ³k
+  label_added: hozzÃ¡adva
+  label_modified: mÃ³dosÃ­tva
+  label_deleted: tÃ¶rÃ¶lve
+  label_latest_revision: LegutolsÃ³ revÃ­ziÃ³
+  label_latest_revision_plural: LegutolsÃ³ revÃ­ziÃ³k
+  label_view_revisions: RevÃ­ziÃ³k megtekintÃ©se
+  label_max_size: MaximÃ¡lis mÃ©ret
+  label_sort_highest: Az elejÃ©re
+  label_sort_higher: Eggyel feljebb
+  label_sort_lower: Eggyel lejjebb
+  label_sort_lowest: Az aljÃ¡ra
+  label_roadmap: Ã‰letÃºt
+  label_roadmap_due_in: "ElkÃ©szÃ¼ltÃ©ig vÃ¡rhatÃ³an mÃ©g %{value}"
+  label_roadmap_overdue: "%{value} kÃ©sÃ©sben"
+  label_roadmap_no_issues: Nincsenek feladatok ehhez a verziÃ³hoz
+  label_search: KeresÃ©s
+  label_result_plural: TalÃ¡latok
+  label_all_words: Minden szÃ³
+  label_wiki: Wiki
+  label_wiki_edit: Wiki szerkesztÃ©s
+  label_wiki_edit_plural: Wiki szerkesztÃ©sek
+  label_wiki_page: Wiki oldal
+  label_wiki_page_plural: Wiki oldalak
+  label_index_by_title: CÃ­m szerint indexelve
+  label_index_by_date: DÃ¡tum szerint indexelve
+  label_current_version: Jelenlegi verziÃ³
+  label_preview: ElÅ‘nÃ©zet
+  label_feed_plural: VisszajelzÃ©sek
+  label_changes_details: VÃ¡ltozÃ¡sok rÃ©szletei
+  label_issue_tracking: Feladat kÃ¶vetÃ©s
+  label_spent_time: RÃ¡fordÃ­tott idÅ‘
+  label_f_hour: "%{value} Ã³ra"
+  label_f_hour_plural: "%{value} Ã³ra"
+  label_time_tracking: IdÅ‘ rÃ¶gzÃ­tÃ©s
+  label_change_plural: VÃ¡ltozÃ¡sok
+  label_statistics: StatisztikÃ¡k
+  label_commits_per_month: Commitok havonta
+  label_commits_per_author: Commitok szerzÅ‘nkÃ©nt
+  label_view_diff: KÃ¼lÃ¶nbsÃ©gek megtekintÃ©se
+  label_diff_inline: soronkÃ©nt
+  label_diff_side_by_side: egymÃ¡s mellett
+  label_options: OpciÃ³k
+  label_copy_workflow_from: Workflow mÃ¡solÃ¡sa innen
+  label_permissions_report: JogosultsÃ¡gi riport
+  label_watched_issues: Megfigyelt feladatok
+  label_related_issues: KapcsolÃ³dÃ³ feladatok
+  label_applied_status: AlkalmazandÃ³ stÃ¡tusz
+  label_loading: BetÃ¶ltÃ©s...
+  label_relation_new: Ãšj kapcsolat
+  label_relation_delete: Kapcsolat tÃ¶rlÃ©se
+  label_relates_to: kapcsolÃ³dik
+  label_duplicates: duplikÃ¡lja
+  label_blocks: zÃ¡rolja
+  label_blocked_by: zÃ¡rolta
+  label_precedes: megelÅ‘zi
+  label_follows: kÃ¶veti
+  label_end_to_start: vÃ©gÃ©tÅ‘l indulÃ¡sig
+  label_end_to_end: vÃ©gÃ©tÅ‘l vÃ©gÃ©ig
+  label_start_to_start: indulÃ¡stÃ³l indulÃ¡sig
+  label_start_to_end: indulÃ¡stÃ³l vÃ©gÃ©ig
+  label_stay_logged_in: EmlÃ©kezzen rÃ¡m
+  label_disabled: kikapcsolva
+  label_show_completed_versions: A kÃ©sz verziÃ³k mutatÃ¡sa
+  label_me: Ã©n
+  label_board: FÃ³rum
+  label_board_new: Ãšj fÃ³rum
+  label_board_plural: FÃ³rumok
+  label_topic_plural: TÃ©mÃ¡k
+  label_message_plural: Ãœzenetek
+  label_message_last: UtolsÃ³ Ã¼zenet
+  label_message_new: Ãšj Ã¼zenet
+  label_message_posted: Ãœzenet hozzÃ¡adva
+  label_reply_plural: VÃ¡laszok
+  label_send_information: FiÃ³k infomÃ¡ciÃ³k kÃ¼ldÃ©se a felhasznÃ¡lÃ³nak
+  label_year: Ã‰v
+  label_month: HÃ³nap
+  label_week: HÃ©t
+  label_date_from: 'Kezdet:'
+  label_date_to: 'VÃ©ge:'
+  label_language_based: A felhasznÃ¡lÃ³ nyelve alapjÃ¡n
+  label_sort_by: "%{value} szerint rendezve"
+  label_send_test_email: Teszt e-mail kÃ¼ldÃ©se
+  label_feeds_access_key_created_on: "RSS hozzÃ¡fÃ©rÃ©si kulcs lÃ©trehozva %{value}"
+  label_module_plural: Modulok
+  label_added_time_by: "%{author} adta hozzÃ¡ %{age}"
+  label_updated_time: "UtolsÃ³ mÃ³dosÃ­tÃ¡s %{value}"
+  label_jump_to_a_project: UgrÃ¡s projekthez...
+  label_file_plural: FÃ¡jlok
+  label_changeset_plural: Changesets
+  label_default_columns: AlapÃ©rtelmezett oszlopok
+  label_no_change_option: (Nincs vÃ¡ltozÃ¡s)
+  label_bulk_edit_selected_issues: A kivÃ¡lasztott feladatok kÃ¶tegelt szerkesztÃ©se
+  label_theme: TÃ©ma
+  label_default: AlapÃ©rtelmezett
+  label_search_titles_only: KeresÃ©s csak a cÃ­mekben
+  label_user_mail_option_all: "Minden esemÃ©nyrÅ‘l minden sajÃ¡t projektemben"
+  label_user_mail_option_selected: "Minden esemÃ©nyrÅ‘l a kivÃ¡lasztott projektekben..."
+  label_user_mail_no_self_notified: "Nem kÃ©rek Ã©rtesÃ­tÃ©st az Ã¡ltalam vÃ©gzett mÃ³dosÃ­tÃ¡sokrÃ³l"
+  label_registration_activation_by_email: FiÃ³k aktivÃ¡lÃ¡sa e-mailben
+  label_registration_manual_activation: ManuÃ¡lis fiÃ³k aktivÃ¡lÃ¡s
+  label_registration_automatic_activation: Automatikus fiÃ³k aktivÃ¡lÃ¡s
+  label_display_per_page: "OldalankÃ©nt: %{value}"
+  label_age: Kor
+  label_change_properties: TulajdonsÃ¡gok vÃ¡ltoztatÃ¡sa
+  label_general: ÃltalÃ¡nos
+  label_more: tovÃ¡bbiak
+  label_scm: SCM
+  label_plugins: Pluginek
+  label_ldap_authentication: LDAP azonosÃ­tÃ¡s
+  label_downloads_abbr: D/L
+  label_optional_description: OpcionÃ¡lis leÃ­rÃ¡s
+  label_add_another_file: Ãšjabb fÃ¡jl hozzÃ¡adÃ¡sa
+  label_preferences: TulajdonsÃ¡gok
+  label_chronological_order: IdÅ‘rendben
+  label_reverse_chronological_order: FordÃ­tott idÅ‘rendben
+  label_planning: TervezÃ©s
+
+  button_login: BejelentkezÃ©s
+  button_submit: Elfogad
+  button_save: MentÃ©s
+  button_check_all: Mindent kijelÃ¶l
+  button_uncheck_all: KijelÃ¶lÃ©s tÃ¶rlÃ©se
+  button_delete: TÃ¶rÃ¶l
+  button_create: LÃ©trehoz
+  button_test: Teszt
+  button_edit: Szerkeszt
+  button_add: HozzÃ¡ad
+  button_change: VÃ¡ltoztat
+  button_apply: Alkalmaz
+  button_clear: TÃ¶rÃ¶l
+  button_lock: ZÃ¡rol
+  button_unlock: Felold
+  button_download: LetÃ¶ltÃ©s
+  button_list: Lista
+  button_view: MegnÃ©z
+  button_move: Mozgat
+  button_back: Vissza
+  button_cancel: MÃ©gse
+  button_activate: AktivÃ¡l
+  button_sort: RendezÃ©s
+  button_log_time: IdÅ‘ rÃ¶gzÃ­tÃ©s
+  button_rollback: VisszaÃ¡ll erre a verziÃ³ra
+  button_watch: Megfigyel
+  button_unwatch: MegfigyelÃ©s tÃ¶rlÃ©se
+  button_reply: VÃ¡lasz
+  button_archive: ArchivÃ¡l
+  button_unarchive: DearchivÃ¡l
+  button_reset: Reset
+  button_rename: Ãtnevez
+  button_change_password: JelszÃ³ megvÃ¡ltoztatÃ¡sa
+  button_copy: MÃ¡sol
+  button_annotate: Jegyzetel
+  button_update: MÃ³dosÃ­t
+  button_configure: KonfigurÃ¡l
+
+  status_active: aktÃ­v
+  status_registered: regisztrÃ¡lt
+  status_locked: zÃ¡rolt
+
+  text_select_mail_notifications: VÃ¡lasszon esemÃ©nyeket, amelyekrÅ‘l e-mail Ã©rtesÃ­tÃ©st kell kÃ¼ldeni.
+  text_regexp_info: pl. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 = nincs korlÃ¡tozÃ¡s
+  text_project_destroy_confirmation: Biztosan tÃ¶rÃ¶lni szeretnÃ© a projektet Ã©s vele egyÃ¼tt minden kapcsolÃ³dÃ³ adatot ?
+  text_subprojects_destroy_warning: "Az alprojekt(ek): %{value} szintÃ©n tÃ¶rlÃ©sre kerÃ¼lnek."
+  text_workflow_edit: VÃ¡lasszon egy szerepkÃ¶rt, Ã©s egy feladat tÃ­pust a workflow szerkesztÃ©sÃ©hez
+  text_are_you_sure: Biztos benne ?
+  text_tip_issue_begin_day: a feladat ezen a napon kezdÅ‘dik
+  text_tip_issue_end_day: a feladat ezen a napon Ã©r vÃ©get
+  text_tip_issue_begin_end_day: a feladat ezen a napon kezdÅ‘dik Ã©s Ã©r vÃ©get
+  text_caracters_maximum: "maximum %{count} karakter."
+  text_caracters_minimum: "Legkevesebb %{count} karakter hosszÃºnek kell lennie."
+  text_length_between: "LegalÃ¡bb %{min} Ã©s legfeljebb %{max} hosszÃº karakter."
+  text_tracker_no_workflow: Nincs workflow definiÃ¡lva ehhez a feladat tÃ­pushoz
+  text_unallowed_characters: Tiltott karakterek
+  text_comma_separated: TÃ¶bb Ã©rtÃ©k megengedett (vesszÅ‘vel elvÃ¡lasztva)
+  text_issues_ref_in_commit_messages: HivatkozÃ¡s feladatokra, feladatok javÃ­tÃ¡sa a commit Ã¼zenetekben
+  text_issue_added: "%{author} Ãºj feladatot hozott lÃ©tre %{id} sorszÃ¡mmal."
+  text_issue_updated: "%{author} mÃ³dosÃ­totta a %{id} sorszÃ¡mÃº feladatot."
+  text_wiki_destroy_confirmation: Biztosan tÃ¶rÃ¶lni szeretnÃ© ezt a wiki-t minden tartalmÃ¡val egyÃ¼tt ?
+  text_issue_category_destroy_question: "NÃ©hÃ¡ny feladat (%{count}) hozzÃ¡ van rendelve ehhez a kategÃ³riÃ¡hoz. Mit szeretne tenni?"
+  text_issue_category_destroy_assignments: KategÃ³ria hozzÃ¡rendelÃ©s megszÃ¼ntetÃ©se
+  text_issue_category_reassign_to: Feladatok Ãºjra hozzÃ¡rendelÃ©se mÃ¡sik kategÃ³riÃ¡hoz
+  text_user_mail_option: "A nem kivÃ¡lasztott projektekrÅ‘l csak akkor kap Ã©rtesÃ­tÃ©st, ha figyelÃ©st kÃ©r rÃ¡, vagy rÃ©szt vesz benne (pl. Ã–n a lÃ©trehozÃ³, vagy a hozzÃ¡rendelÅ‘)"
+  text_no_configuration_data: "SzerepkÃ¶rÃ¶k, feladat tÃ­pusok, feladat stÃ¡tuszok, Ã©s workflow adatok mÃ©g nincsenek konfigurÃ¡lva.\nErÅ‘sen ajÃ¡nlott, az alapÃ©rtelmezett konfigurÃ¡ciÃ³ betÃ¶ltÃ©se, Ã©s utÃ¡na mÃ³dosÃ­thatja azt."
+  text_load_default_configuration: AlapÃ©rtelmezett konfigurÃ¡ciÃ³ betÃ¶ltÃ©se
+  text_status_changed_by_changeset: "Applied in changeset %{value}."
+  text_issues_destroy_confirmation: 'Biztos benne, hogy tÃ¶rÃ¶lni szeretnÃ© a kijelÃ¶lt feladato(ka)t ?'
+  text_select_project_modules: 'VÃ¡lassza ki az engedÃ©lyezett modulokat ehhez a projekthez:'
+  text_default_administrator_account_changed: AlapÃ©rtelmezett adminisztrÃ¡tor fiÃ³k megvÃ¡ltoztatva
+  text_file_repository_writable: FÃ¡jl tÃ¡rolÃ³ Ã­rhatÃ³
+  text_rmagick_available: RMagick elÃ©rhetÅ‘ (nem kÃ¶telezÅ‘)
+  text_destroy_time_entries_question: "%{hours} Ã³rÃ¡nyi munka van rÃ¶gzÃ­tve a feladatokon, amiket tÃ¶rÃ¶lni szeretne. Mit szeretne tenni?"
+  text_destroy_time_entries: A rÃ¶gzÃ­tett Ã³rÃ¡k tÃ¶rlÃ©se
+  text_assign_time_entries_to_project: A rÃ¶gzÃ­tett Ã³rÃ¡k hozzÃ¡rendelÃ©se a projekthez
+  text_reassign_time_entries: 'A rÃ¶gzÃ­tett Ã³rÃ¡k Ãºjra hozzÃ¡rendelÃ©se mÃ¡sik feladathoz:'
+
+  default_role_manager: VezetÅ‘
+  default_role_developer: FejlesztÅ‘
+  default_role_reporter: BejelentÅ‘
+  default_tracker_bug: Hiba
+  default_tracker_feature: FejlesztÃ©s
+  default_tracker_support: TÃ¡mogatÃ¡s
+  default_issue_status_new: Ãšj
+  default_issue_status_in_progress: Folyamatban
+  default_issue_status_resolved: Megoldva
+  default_issue_status_feedback: VisszajelzÃ©s
+  default_issue_status_closed: LezÃ¡rt
+  default_issue_status_rejected: ElutasÃ­tott
+  default_doc_category_user: FelhasznÃ¡lÃ³i dokumentÃ¡ciÃ³
+  default_doc_category_tech: Technikai dokumentÃ¡ciÃ³
+  default_priority_low: Alacsony
+  default_priority_normal: NormÃ¡l
+  default_priority_high: Magas
+  default_priority_urgent: SÃ¼rgÅ‘s
+  default_priority_immediate: Azonnal
+  default_activity_design: TervezÃ©s
+  default_activity_development: FejlesztÃ©s
+
+  enumeration_issue_priorities: Feladat prioritÃ¡sok
+  enumeration_doc_categories: Dokumentum kategÃ³riÃ¡k
+  enumeration_activities: TevÃ©kenysÃ©gek (idÅ‘ rÃ¶gzÃ­tÃ©s)
+  mail_body_reminder: "%{count} neked kiosztott feladat hatÃ¡ridÅ‘s az elkÃ¶vetkezÅ‘ %{days} napban:"
+  mail_subject_reminder: "%{count} feladat hatÃ¡ridÅ‘s az elkÃ¶vetkezÅ‘ %{days} napban"
+  text_user_wrote: "%{value} Ã­rta:"
+  label_duplicated_by: duplikÃ¡lta
+  setting_enabled_scm: ForrÃ¡skÃ³dkezelÅ‘ (SCM) engedÃ©lyezÃ©se
+  text_enumeration_category_reassign_to: 'Ãšjra hozzÃ¡rendelÃ©s ehhez:'
+  text_enumeration_destroy_question: "%{count} objektum van hozzÃ¡rendelve ehhez az Ã©rtÃ©khez."
+  label_incoming_emails: BeÃ©rkezett levelek
+  label_generate_key: Kulcs generÃ¡lÃ¡sa
+  setting_mail_handler_api_enabled: Web Service engedÃ©lyezÃ©se a beÃ©rkezett levelekhez
+  setting_mail_handler_api_key: API kulcs
+  text_email_delivery_not_configured: "Az E-mail kÃ¼ldÃ©s nincs konfigurÃ¡lva, Ã©s az Ã©rtesÃ­tÃ©sek ki vannak kapcsolva.\nÃllÃ­tsd be az SMTP szervert a config/configuration.yml fÃ¡jlban Ã©s indÃ­tsd Ãºjra az alkalmazÃ¡st, hogy Ã©rvÃ©nybe lÃ©pjen."
+  field_parent_title: SzÃ¼lÅ‘ oldal
+  label_issue_watchers: MegfigyelÅ‘k
+  button_quote: HozzÃ¡szÃ³lÃ¡s / IdÃ©zet
+  setting_sequential_project_identifiers: SzekvenciÃ¡lis projekt azonosÃ­tÃ³k generÃ¡lÃ¡sa
+  notice_unable_delete_version: A verziÃ³t nem lehet tÃ¶rÃ¶lni
+  label_renamed: Ã¡tnevezve
+  label_copied: lemÃ¡solva
+  setting_plain_text_mail: csak szÃ¶veg (nem HTML)
+  permission_view_files: FÃ¡jlok megtekintÃ©se
+  permission_edit_issues: Feladatok szerkesztÃ©se
+  permission_edit_own_time_entries: SajÃ¡t idÅ‘naplÃ³ szerkesztÃ©se
+  permission_manage_public_queries: NyilvÃ¡nos kÃ©rÃ©sek kezelÃ©se
+  permission_add_issues: Feladat felvÃ©tele
+  permission_log_time: IdÅ‘ rÃ¶gzÃ­tÃ©se
+  permission_view_changesets: VÃ¡ltozÃ¡skÃ¶tegek megtekintÃ©se
+  permission_view_time_entries: IdÅ‘rÃ¶gzÃ­tÃ©sek megtekintÃ©se
+  permission_manage_versions: VerziÃ³k kezelÃ©se
+  permission_manage_wiki: Wiki kezelÃ©se
+  permission_manage_categories: Feladat kategÃ³riÃ¡k kezelÃ©se
+  permission_protect_wiki_pages: Wiki oldalak vÃ©delme
+  permission_comment_news: HÃ­rek kommentelÃ©se
+  permission_delete_messages: Ãœzenetek tÃ¶rlÃ©se
+  permission_select_project_modules: Projekt modulok kezelÃ©se
+  permission_edit_wiki_pages: Wiki oldalak szerkesztÃ©se
+  permission_add_issue_watchers: MegfigyelÅ‘k felvÃ©tele
+  permission_view_gantt: Gannt diagramm megtekintÃ©se
+  permission_move_issues: Feladatok mozgatÃ¡sa
+  permission_manage_issue_relations: Feladat kapcsolatok kezelÃ©se
+  permission_delete_wiki_pages: Wiki oldalak tÃ¶rlÃ©se
+  permission_manage_boards: FÃ³rumok kezelÃ©se
+  permission_delete_wiki_pages_attachments: CsatolmÃ¡nyok tÃ¶rlÃ©se
+  permission_view_wiki_edits: Wiki tÃ¶rtÃ©net megtekintÃ©se
+  permission_add_messages: Ãœzenet bekÃ¼ldÃ©se
+  permission_view_messages: Ãœzenetek megtekintÃ©se
+  permission_manage_files: FÃ¡jlok kezelÃ©se
+  permission_edit_issue_notes: Jegyzetek szerkesztÃ©se
+  permission_manage_news: HÃ­rek kezelÃ©se
+  permission_view_calendar: NaptÃ¡r megtekintÃ©se
+  permission_manage_members: Tagok kezelÃ©se
+  permission_edit_messages: Ãœzenetek szerkesztÃ©se
+  permission_delete_issues: Feladatok tÃ¶rlÃ©se
+  permission_view_issue_watchers: MegfigyelÅ‘k listÃ¡zÃ¡sa
+  permission_manage_repository: TÃ¡rolÃ³k kezelÃ©se
+  permission_commit_access: Commit hozzÃ¡fÃ©rÃ©s
+  permission_browse_repository: TÃ¡rolÃ³ bÃ¶ngÃ©szÃ©se
+  permission_view_documents: Dokumetumok megtekintÃ©se
+  permission_edit_project: Projekt szerkesztÃ©se
+  permission_add_issue_notes: Jegyzet rÃ¶gzÃ­tÃ©se
+  permission_save_queries: KÃ©rÃ©sek mentÃ©se
+  permission_view_wiki_pages: Wiki megtekintÃ©se
+  permission_rename_wiki_pages: Wiki oldalak Ã¡tnevezÃ©se
+  permission_edit_time_entries: IdÅ‘naplÃ³k szerkesztÃ©se
+  permission_edit_own_issue_notes: SajÃ¡t jegyzetek szerkesztÃ©se
+  setting_gravatar_enabled: FelhasznÃ¡lÃ³i fÃ©nykÃ©pek engedÃ©lyezÃ©se
+  label_example: PÃ©lda
+  text_repository_usernames_mapping: "ÃllÃ­tsd be a felhasznÃ¡lÃ³ Ã¶sszerendelÃ©seket a Redmine, Ã©s a tÃ¡rolÃ³ logban talÃ¡lhatÃ³ felhasznÃ¡lÃ³k kÃ¶zÃ¶tt.\nAz azonos felhasznÃ¡lÃ³ nevek Ã¶sszerendelÃ©se automatikusan megtÃ¶rtÃ©nik."
+  permission_edit_own_messages: SajÃ¡t Ã¼zenetek szerkesztÃ©se
+  permission_delete_own_messages: SajÃ¡t Ã¼zenetek tÃ¶rlÃ©se
+  label_user_activity: "%{value} tevÃ©kenysÃ©gei"
+  label_updated_time_by: "MÃ³dosÃ­totta %{author} %{age}"
+  text_diff_truncated: '... A diff fÃ¡jl vÃ©ge nem jelenik meg, mert hosszab, mint a megjelenÃ­thetÅ‘ sorok szÃ¡ma.'
+  setting_diff_max_lines_displayed: A megjelenÃ­tendÅ‘ sorok szÃ¡ma (maximum) a diff fÃ¡jloknÃ¡l
+  text_plugin_assets_writable: Plugin eszkÃ¶zÃ¶k kÃ¶nyvtÃ¡r Ã­rhatÃ³
+  warning_attachments_not_saved: "%{count} fÃ¡jl mentÃ©se nem sikerÃ¼lt."
+  button_create_and_continue: LÃ©trehozÃ¡s Ã©s folytatÃ¡s
+  text_custom_field_possible_values_info: 'Ã‰rtÃ©kenkÃ©nt egy sor'
+  label_display: Megmutat
+  field_editable: SzerkeszthetÅ‘
+  setting_repository_log_display_limit: Maximum hÃ¡ny revÃ­ziÃ³t mutasson meg a log megjelenÃ­tÃ©sekor
+  setting_file_max_size_displayed: Maximum mekkora szÃ¶vegfÃ¡jlokat jelenÃ­tsen meg soronkÃ©nti Ã¶sszehasonlÃ­tÃ¡snÃ¡l
+  field_watcher: MegfigyelÅ‘
+  setting_openid: OpenID regisztrÃ¡ciÃ³ Ã©s bejelentkezÃ©s engedÃ©lyezÃ©se
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: bejelentkezÃ©s OpenID hasznÃ¡latÃ¡val
+  field_content: Tartalom
+  label_descending: CsÃ¶kkenÅ‘
+  label_sort: RendezÃ©s
+  label_ascending: NÃ¶vekvÅ‘
+  label_date_from_to: "%{start} -tÃ³l %{end} -ig"
+  label_greater_or_equal: ">="
+  label_less_or_equal: "<="
+  text_wiki_page_destroy_question: Ennek az oldalnak %{descendants} gyermek-, Ã©s leszÃ¡rmazott oldala van. Mit szeretne tenni?
+  text_wiki_page_reassign_children: Aloldalak hozzÃ¡rendelÃ©se ehhez a szÃ¼lÅ‘ oldalhoz
+  text_wiki_page_nullify_children: Aloldalak Ã¡talakÃ­tÃ¡sa fÅ‘oldallÃ¡
+  text_wiki_page_destroy_children: Minden aloldal Ã©s leszÃ¡rmazottjÃ¡nak tÃ¶rlÃ©se
+  setting_password_min_length: Minimum jelszÃ³ hosszÃºsÃ¡g
+  field_group_by: Szerint csoportosÃ­tva
+  mail_subject_wiki_content_updated: "'%{id}' wiki oldal frissÃ­tve"
+  label_wiki_content_added: Wiki oldal hozzÃ¡adva
+  mail_subject_wiki_content_added: "Ãšj wiki oldal: '%{id}'"
+  mail_body_wiki_content_added: "%{author} lÃ©trehozta a '%{id}' wiki oldalt."
+  label_wiki_content_updated: Wiki oldal frissÃ­tve
+  mail_body_wiki_content_updated: "%{author} frissÃ­tette a '%{id}' wiki oldalt."
+  permission_add_project: Projekt lÃ©trehozÃ¡sa
+  setting_new_project_user_role_id: Projekt lÃ©trehozÃ¡si jog nem adminisztrÃ¡tor felhasznÃ¡lÃ³knak
+  label_view_all_revisions: Ã–sszes verziÃ³
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: Nincs feladat tÃ­pus hozzÃ¡rendelve ehhez a projekthez. KÃ©rem ellenÅ‘rizze a projekt beÃ¡llÃ­tÃ¡sait.
+  error_no_default_issue_status: Nincs alapÃ©rtelmezett feladat stÃ¡tusz beÃ¡llÃ­tva. KÃ©rem ellenÅ‘rizze a beÃ¡llÃ­tÃ¡sokat (Itt talÃ¡lja "AdminisztrÃ¡ciÃ³ -> Feladat stÃ¡tuszok").
+  text_journal_changed: "%{label} megvÃ¡ltozott, %{old} helyett %{new} lett"
+  text_journal_set_to: "%{label} Ãºj Ã©rtÃ©ke: %{value}"
+  text_journal_deleted: "%{label} tÃ¶rÃ¶lve lett (%{old})"
+  label_group_plural: Csoportok
+  label_group: Csoport
+  label_group_new: Ãšj csoport
+  label_time_entry_plural: IdÅ‘rÃ¡fordÃ­tÃ¡s
+  text_journal_added: "%{label} %{value} hozzÃ¡adva"
+  field_active: AktÃ­v
+  enumeration_system_activity: RendszertevÃ©kenysÃ©g
+  permission_delete_issue_watchers: MegfigyelÅ‘k tÃ¶rlÃ©se
+  version_status_closed: lezÃ¡rt
+  version_status_locked: zÃ¡rolt
+  version_status_open: nyitott
+  error_can_not_reopen_issue_on_closed_version: LezÃ¡rt verziÃ³hoz rendelt feladatot nem lehet Ãºjranyitni
+  label_user_anonymous: NÃ©vtelen
+  button_move_and_follow: MozgatÃ¡s Ã©s kÃ¶vetÃ©s
+  setting_default_projects_modules: AlapÃ©rtelmezett modulok az Ãºj projektekhez
+  setting_gravatar_default: AlapÃ©rtelmezett Gravatar kÃ©p
+  field_sharing: MegosztÃ¡s
+  label_version_sharing_hierarchy: Projekt hierarchiÃ¡val
+  label_version_sharing_system: Minden projekttel
+  label_version_sharing_descendants: Alprojektekkel
+  label_version_sharing_tree: Projekt fÃ¡val
+  label_version_sharing_none: Nincs megosztva
+  error_can_not_archive_project: A projektet nem lehet archivÃ¡lni
+  button_duplicate: DuplikÃ¡lÃ¡s
+  button_copy_and_follow: MÃ¡solÃ¡s Ã©s kÃ¶vetÃ©s
+  label_copy_source: ForrÃ¡s
+  setting_issue_done_ratio: Feladat kÃ©szÃ¼ltsÃ©gi szint szÃ¡molÃ¡sa a kÃ¶vetkezÅ‘ alapjÃ¡n
+  setting_issue_done_ratio_issue_status: Feladat stÃ¡tusz alapjÃ¡n
+  error_issue_done_ratios_not_updated: A feladat kÃ©szÃ¼ltsÃ©gi szintek nem lettek frissÃ­tve.
+  error_workflow_copy_target: KÃ©rem vÃ¡lasszon cÃ©l feladat tÃ­pus(oka)t Ã©s szerepkÃ¶r(Ã¶ke)t.
+  setting_issue_done_ratio_issue_field: A feladat mezÅ‘ alapjÃ¡n
+  label_copy_same_as_target: A cÃ©llal egyezÅ‘
+  label_copy_target: CÃ©l
+  notice_issue_done_ratios_updated: Feladat kÃ©szÃ¼ltsÃ©gi szintek frissÃ­tve.
+  error_workflow_copy_source: KÃ©rem vÃ¡lasszon forrÃ¡s feladat tÃ­pust vagy szerepkÃ¶rt
+  label_update_issue_done_ratios: Feladat kÃ©szÃ¼ltsÃ©gi szintek frissÃ­tÃ©se
+  setting_start_of_week: A hÃ©t elsÅ‘ napja
+  permission_view_issues: Feladatok megtekintÃ©se
+  label_display_used_statuses_only: Csak olyan feladat stÃ¡tuszok megjelenÃ­tÃ©se, amit ez a feladat tÃ­pus hasznÃ¡l
+  label_revision_id: RevÃ­ziÃ³ %{value}
+  label_api_access_key: API hozzÃ¡fÃ©rÃ©si kulcs
+  label_api_access_key_created_on: API hozzÃ¡fÃ©rÃ©si kulcs lÃ©trehozva %{value} ezelÅ‘tt
+  label_feeds_access_key: RSS hozzÃ¡fÃ©rÃ©si kulcs
+  notice_api_access_key_reseted: Az API hozzÃ¡fÃ©rÃ©si kulcsa ÃºjragenerÃ¡lva.
+  setting_rest_api_enabled: REST web service engedÃ©lyezÃ©se
+  label_missing_api_access_key: Egy API hozzÃ¡fÃ©rÃ©si kulcs hiÃ¡nyzik
+  label_missing_feeds_access_key: RSS hozzÃ¡fÃ©rÃ©si kulcs hiÃ¡nyzik
+  button_show: Megmutat
+  text_line_separated: TÃ¶bb Ã©rtÃ©k megadÃ¡sa lehetsÃ©ges (soronkÃ©nt 1 Ã©rtÃ©k).
+  setting_mail_handler_body_delimiters: E-mailek levÃ¡gÃ¡sa a kÃ¶vetkezÅ‘ sorok valamelyike esetÃ©n
+  permission_add_subprojects: Alprojektek lÃ©trehozÃ¡sa
+  label_subproject_new: Ãšj alprojekt
+  text_own_membership_delete_confirmation: |-
+    Arra kÃ©szÃ¼l, hogy eltÃ¡volÃ­tja egyes vagy minden jogosultsÃ¡gÃ¡t! Ezt kÃ¶vetÅ‘en lehetsÃ©ges, hogy nem fogja tudni szerkeszteni ezt a projektet!
+    Biztosan folyatni szeretnÃ©?
+  label_close_versions: KÃ©sz verziÃ³k lezÃ¡rÃ¡sa
+  label_board_sticky: Sticky
+  setting_cache_formatted_text: FormÃ¡zott szÃ¶veg gyorsÃ­tÃ³tÃ¡razÃ¡sa (Cache)
+  permission_export_wiki_pages: Wiki oldalak exportÃ¡lÃ¡sa
+  permission_manage_project_activities: Projekt tevÃ©kenysÃ©gek kezelÃ©se
+  label_board_locked: ZÃ¡rolt
+  error_can_not_delete_custom_field: Nem lehet tÃ¶rÃ¶lni az egyÃ©ni mezÅ‘t
+  permission_manage_subtasks: Alfeladatok kezelÃ©se
+  label_profile: Profil
+  error_unable_to_connect: Nem lehet csatlakozni (%{value})
+  error_can_not_remove_role: Ez a szerepkÃ¶r hasznÃ¡latban van Ã©s ezÃ©rt nem tÃ¶rÃ¶lhetÅ‘-
+  field_parent_issue: SzÃ¼lÅ‘ feladat
+  error_unable_delete_issue_status: Nem lehet tÃ¶rÃ¶lni a feladat Ã¡llapotÃ¡t
+  label_subtask_plural: Alfeladatok
+  error_can_not_delete_tracker: Ebbe a kategÃ³riÃ¡ba feladatok tartoznak Ã©s ezÃ©rt nem tÃ¶rÃ¶lhetÅ‘.
+  label_project_copy_notifications: KÃ¼ldjÃ¶n e-mail Ã©rtesÃ­tÃ©seket projektmÃ¡solÃ¡s kÃ¶zben.
+  field_principal: FelelÅ‘s
+  label_my_page_block: SajÃ¡t kezdÅ‘lap-blokk
+  notice_failed_to_save_members: "Nem sikerÃ¼lt menteni a tago(ka)t: %{errors}."
+  text_zoom_out: KicsinyÃ­t
+  text_zoom_in: NagyÃ­t
+  notice_unable_delete_time_entry: Az idÅ‘rÃ¶gzÃ­tÃ©s nem tÃ¶rÃ¶lhetÅ‘
+  label_overall_spent_time: Ã–sszes rÃ¡fordÃ­tott idÅ‘
+  field_time_entries: IdÅ‘ rÃ¶gzÃ­tÃ©s
+  project_module_gantt: Gantt
+  project_module_calendar: NaptÃ¡r
+  button_edit_associated_wikipage: "HozzÃ¡rendelt Wiki oldal szerkesztÃ©se: %{page_title}"
+  field_text: SzÃ¶veg mezÅ‘
+  label_user_mail_option_only_owner: Csak arrÃ³l, aminek Ã©n vagyok a tulajdonosa
+  setting_default_notification_option: AlapÃ©rtelmezett Ã©rtesÃ­tÃ©si beÃ¡llÃ­tÃ¡sok
+  label_user_mail_option_only_my_events: Csak az Ã¡ltalam megfigyelt dolgokrÃ³l vagy amiben rÃ©szt veszek
+  label_user_mail_option_only_assigned: Csak a hozzÃ¡mrendelt dolgokrÃ³l
+  label_user_mail_option_none: Semilyen esemÃ©nyrÅ‘l
+  field_member_of_group: HozzÃ¡rendelt csoport
+  field_assigned_to_role: HozzÃ¡rendelt szerepkÃ¶r
+  notice_not_authorized_archived_project: A projekt, amihez hozzÃ¡ szeretnÃ©l fÃ©rni archivÃ¡lva lett.
+  label_principal_search: "FelhasznÃ¡lÃ³ vagy csoport keresÃ©se:"
+  label_user_search: "FelhasznÃ¡lÃ³ keresÃ©se:"
+  field_visible: LÃ¡thatÃ³
+  setting_emails_header: Emailek fejlÃ©ce
+  setting_commit_logtime_activity_id: A rÃ¶gzÃ­tett idÅ‘hÃ¶z tartozÃ³ tevÃ©kenysÃ©g
+  text_time_logged_by_changeset: Alkalmazva a %{value} changeset-ben.
+  setting_commit_logtime_enabled: IdÅ‘rÃ¶gzÃ­tÃ©s engedÃ©lyezÃ©se
+  notice_gantt_chart_truncated: A diagram le lett vÃ¡gva, mert elÃ©rte a maximÃ¡lisan megjelenÃ­thetÅ‘ elemek szÃ¡mÃ¡t (%{max})
+  setting_gantt_items_limit: A gantt diagrammon megjelenÃ­thetÅ‘ maximÃ¡lis elemek szÃ¡ma
+  field_warn_on_leaving_unsaved: Figyelmeztessen, nem mentett mÃ³dosÃ­tÃ¡sokat tartalmazÃ³ oldal elhagyÃ¡sakor
+  text_warn_on_leaving_unsaved: A jelenlegi oldal nem mentett mÃ³dosÃ­tÃ¡sokat tartalmaz, ami elvÃ©sz, ha elhagyja az oldalt.
+  label_my_queries: EgyÃ©ni lekÃ©rdezÃ©seim
+  text_journal_changed_no_detail: "%{label} mÃ³dosÃ­tva"
+  label_news_comment_added: MegjegyzÃ©s hozzÃ¡adva a hÃ­rhez
+  button_expand_all: Mindet kibont
+  button_collapse_all: Mindet Ã¶sszecsuk
+  label_additional_workflow_transitions_for_assignee: TovÃ¡bbi Ã¡tmenetek engedÃ©lyezettek, ha a felhasznÃ¡lÃ³ a hozzÃ¡rendelt
+  label_additional_workflow_transitions_for_author: TovÃ¡bbi Ã¡tmenetek engedÃ©lyezettek, ha a felhasznÃ¡lÃ³ a szerzÅ‘
+  label_bulk_edit_selected_time_entries: A kivÃ¡lasztott idÅ‘ bejegyzÃ©sek csoportos szerkesztÃ©se
+  text_time_entries_destroy_confirmation: Biztos benne, hogy tÃ¶rÃ¶lni szeretnÃ© a kivÃ¡lasztott idÅ‘ bejegyzÃ©s(eke)t?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Nem tag
+  label_issue_note_added: Jegyzet hozzÃ¡adva
+  label_issue_status_updated: Ãllapot mÃ³dosÃ­tva
+  label_issue_priority_updated: PrioritÃ¡s mÃ³dosÃ­tva
+  label_issues_visibility_own: A felhasznÃ¡lÃ³ Ã¡ltal lÃ©trehozott vagy hozzÃ¡rendelt feladatok
+  field_issues_visibility: Feladatok lÃ¡thatÃ³sÃ¡ga
+  label_issues_visibility_all: Minden feladat
+  permission_set_own_issues_private: SajÃ¡t feladatok beÃ¡llÃ­tÃ¡sa nyilvÃ¡nosra vagy privÃ¡tra
+  field_is_private: PrivÃ¡t
+  permission_set_issues_private: Feladatok beÃ¡llÃ­tÃ¡sa nyilvÃ¡nosra vagy privÃ¡tra
+  label_issues_visibility_public: Minden nem privÃ¡t feladat
+  text_issues_destroy_descendants_confirmation: Ezzel tÃ¶rÃ¶lni fog %{count} alfeladatot is.
+  field_commit_logs_encoding: Commit Ã¼zenetek kÃ³dlapja
+  field_scm_path_encoding: ElÃ©rÃ©si Ãºtvonal kÃ³dlapja
+  text_scm_path_encoding_note: "AlapÃ©rtelmezett: UTF-8"
+  field_path_to_repository: A repository elÃ©rÃ©si Ãºtja
+  field_root_directory: GyÃ¶kÃ©r kÃ¶nyvtÃ¡r
+  field_cvs_module: Modul
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Helyi repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Parancs
+  text_scm_command_version: VerziÃ³
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 feladat
+    one:   1 feladat
+    other: "%{count} feladatok"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: mind
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Alprojektekkel
+  label_cross_project_tree: Projekt fÃ¡val
+  label_cross_project_hierarchy: Projekt hierarchiÃ¡val
+  label_cross_project_system: Minden projekttel
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ã–sszesen
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b7/b755a1924dda89bcbd2ab15ed92fea448726807c.svn-base
--- a/.svn/pristine/b7/b755a1924dda89bcbd2ab15ed92fea448726807c.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../../config/boot',  __FILE__)
-require 'commands/performance/profiler'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b7/b789966309eb822c678528d8a6d3affdf01146bc.svn-base
--- /dev/null
+++ b/.svn/pristine/b7/b789966309eb822c678528d8a6d3affdf01146bc.svn-base
@@ -0,0 +1,105 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WikiTest < ActiveSupport::TestCase
+  fixtures :projects, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
+
+  def test_create
+    wiki = Wiki.new(:project => Project.find(2))
+    assert !wiki.save
+    assert_equal 1, wiki.errors.count
+
+    wiki.start_page = "Start page"
+    assert wiki.save
+  end
+
+  def test_update
+    @wiki = Wiki.find(1)
+    @wiki.start_page = "Another start page"
+    assert @wiki.save
+    @wiki.reload
+    assert_equal "Another start page", @wiki.start_page
+  end
+
+  def test_find_page_should_not_be_case_sensitive
+    wiki = Wiki.find(1)
+    page = WikiPage.find(2)
+
+    assert_equal page, wiki.find_page('Another_page')
+    assert_equal page, wiki.find_page('Another page')
+    assert_equal page, wiki.find_page('ANOTHER page')
+  end
+
+  def test_find_page_with_cyrillic_characters
+    wiki = Wiki.find(1)
+    page = WikiPage.find(10)
+    assert_equal page, wiki.find_page('Ð­Ñ‚Ð¸ÐºÐ°_Ð¼ÐµÐ½ÐµÐ´Ð¶Ð¼ÐµÐ½Ñ‚Ð°')
+  end
+
+  def test_find_page_with_backslashes
+    wiki = Wiki.find(1)
+    page = WikiPage.create!(:wiki => wiki, :title => '2009\\02\\09')
+    assert_equal page, wiki.find_page('2009\\02\\09')
+  end
+
+  def test_find_page_without_redirect
+    wiki = Wiki.find(1)
+    page = wiki.find_page('Another_page')
+    assert_not_nil page
+    assert_equal 'Another_page', page.title
+    assert_equal false, wiki.page_found_with_redirect?
+  end
+
+  def test_find_page_with_redirect
+    wiki = Wiki.find(1)
+    WikiRedirect.create!(:wiki => wiki, :title => 'Old_title', :redirects_to => 'Another_page')
+    page = wiki.find_page('Old_title')
+    assert_not_nil page
+    assert_equal 'Another_page', page.title
+    assert_equal true, wiki.page_found_with_redirect?
+  end
+
+  def test_titleize
+    ja_test = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88"
+    ja_test.force_encoding('UTF-8') if ja_test.respond_to?(:force_encoding)
+    assert_equal 'Page_title_with_CAPITALES', Wiki.titleize('page title with CAPITALES')
+    assert_equal ja_test, Wiki.titleize(ja_test)
+  end
+
+  context "#sidebar" do
+    setup do
+      @wiki = Wiki.find(1)
+    end
+
+    should "return nil if undefined" do
+      assert_nil @wiki.sidebar
+    end
+
+    should "return a WikiPage if defined" do
+      page = @wiki.pages.new(:title => 'Sidebar')
+      page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
+      page.save!
+
+      assert_kind_of WikiPage, @wiki.sidebar
+      assert_equal 'Sidebar', @wiki.sidebar.title
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b7/b78bf98398b832636a37f703d706727f51baac1c.svn-base
--- a/.svn/pristine/b7/b78bf98398b832636a37f703d706727f51baac1c.svn-base
+++ /dev/null
@@ -1,130 +0,0 @@
-ï»¿// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// Italian translation
-// by Diego Pierotto (ita.translations@tiscali.it)
-
-// full day names
-Calendar._DN = new Array
-("Domenica",
- "LunedÃ¬",
- "MartedÃ¬",
- "MercoledÃ¬",
- "GiovedÃ¬",
- "VenerdÃ¬",
- "Sabato",
- "Domenica");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Dom",
- "Lun",
- "Mar",
- "Mer",
- "Gio",
- "Ven",
- "Sab",
- "Dom");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Gennaio",
- "Febbraio",
- "Marzo",
- "Aprile",
- "Maggio",
- "Giugno",
- "Luglio",
- "Agosto",
- "Settembre",
- "Ottobre",
- "Novembre",
- "Dicembre");
-
-// short month names
-Calendar._SMN = new Array
-("Gen",
- "Feb",
- "Mar",
- "Apr",
- "Mag",
- "Giu",
- "Lug",
- "Ago",
- "Set",
- "Ott",
- "Nov",
- "Dic");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Informazioni sul calendario";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Autore: Mihai Bazon\n" + // don't translate this this ;-)
-"Per l'ultima versione visita: http://www.dynarch.com/projects/calendar/\n" +
-"Distribuito sotto i termini GNU LGPL.  Vedi http://gnu.org/licenses/lgpl.html per maggiori dettagli." +
-"\n\n" +
-"Selezione data:\n" +
-"- Usa i tasti \xab, \xbb per selezionare l'anno\n" +
-"- Usa i tasti " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " per selezionare il mese\n" +
-"- Tieni premuto il tasto del mouse su uno qualunque dei tasti sopra per una selezione piÃ¹ veloce.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Selezione ora:\n" +
-"- Fai click su una delle ore per incrementarla\n" +
-"- oppure Shift-click per diminuirla\n" +
-"- oppure click e trascina per una selezione piÃ¹ veloce.";
-
-Calendar._TT["PREV_YEAR"] = "Anno prec. (tieni premuto per menu)";
-Calendar._TT["PREV_MONTH"] = "Mese prec. (tieni premuto per menu)";
-Calendar._TT["GO_TODAY"] = "Oggi";
-Calendar._TT["NEXT_MONTH"] = "Mese succ. (tieni premuto per menu)";
-Calendar._TT["NEXT_YEAR"] = "Anno succ. (tieni premuto per menu)";
-Calendar._TT["SEL_DATE"] = "Seleziona data";
-Calendar._TT["DRAG_TO_MOVE"] = "Trascina per spostare";
-Calendar._TT["PART_TODAY"] = " (oggi)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Mostra %s per primo";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Chiudi";
-Calendar._TT["TODAY"] = "Oggi";
-Calendar._TT["TIME_PART"] = "(Shift-)Click o trascina per modificare";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "sett";
-Calendar._TT["TIME"] = "Ora:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b7/b79791de4d5f7b498396b0a1261c36b1da41245f.svn-base
--- a/.svn/pristine/b7/b79791de4d5f7b498396b0a1261c36b1da41245f.svn-base
+++ /dev/null
@@ -1,113 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Configuration
-
-    # Configuration default values
-    @defaults = {
-      'email_delivery' => nil
-    }
-
-    @config = nil
-
-    class << self
-      # Loads the Redmine configuration file
-      # Valid options:
-      # * <tt>:file</tt>: the configuration file to load (default: config/configuration.yml)
-      # * <tt>:env</tt>: the environment to load the configuration for (default: Rails.env)
-      def load(options={})
-        filename = options[:file] || File.join(Rails.root, 'config', 'configuration.yml')
-        env = options[:env] || Rails.env
-
-        @config = @defaults.dup
-
-        load_deprecated_email_configuration(env)
-        if File.file?(filename)
-          @config.merge!(load_from_yaml(filename, env))
-        end
-
-        # Compatibility mode for those who copy email.yml over configuration.yml
-        %w(delivery_method smtp_settings sendmail_settings).each do |key|
-          if value = @config.delete(key)
-            @config['email_delivery'] ||= {}
-            @config['email_delivery'][key] = value
-          end
-        end
-
-        if @config['email_delivery']
-          ActionMailer::Base.perform_deliveries = true
-          @config['email_delivery'].each do |k, v|
-            v.symbolize_keys! if v.respond_to?(:symbolize_keys!)
-            ActionMailer::Base.send("#{k}=", v)
-          end
-        end
-
-        @config
-      end
-
-      # Returns a configuration setting
-      def [](name)
-        load unless @config
-        @config[name]
-      end
-
-      # Yields a block with the specified hash configuration settings
-      def with(settings)
-        settings.stringify_keys!
-        load unless @config
-        was = settings.keys.inject({}) {|h,v| h[v] = @config[v]; h}
-        @config.merge! settings
-        yield if block_given?
-        @config.merge! was
-      end
-
-      private
-
-      def load_from_yaml(filename, env)
-        yaml = nil
-        begin
-          yaml = YAML::load_file(filename)
-        rescue ArgumentError
-          $stderr.puts "Your Redmine configuration file located at #{filename} is not a valid YAML file and could not be loaded."
-          exit 1
-        end
-        conf = {}
-        if yaml.is_a?(Hash)
-          if yaml['default']
-            conf.merge!(yaml['default'])
-          end
-          if yaml[env]
-            conf.merge!(yaml[env])
-          end
-        else
-          $stderr.puts "Your Redmine configuration file located at #{filename} is not a valid Redmine configuration file."
-          exit 1
-        end
-        conf
-      end
-
-      def load_deprecated_email_configuration(env)
-        deprecated_email_conf = File.join(Rails.root, 'config', 'email.yml')
-        if File.file?(deprecated_email_conf)
-          warn "Storing outgoing emails configuration in config/email.yml is deprecated. You should now store it in config/configuration.yml using the email_delivery setting."
-          @config.merge!({'email_delivery' => load_from_yaml(deprecated_email_conf, env)})
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b7/b7ae01db7f962eeecf06a14315cde4d9125f1ae3.svn-base
--- a/.svn/pristine/b7/b7ae01db7f962eeecf06a14315cde4d9125f1ae3.svn-base
+++ /dev/null
@@ -1,100 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'journals_controller'
-
-# Re-raise errors caught by the controller.
-class JournalsController; def rescue_action(e) raise e end; end
-
-class JournalsControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :members, :member_roles, :roles, :issues, :journals, :journal_details, :enabled_modules,
-    :trackers, :issue_statuses, :enumerations, :custom_fields, :custom_values, :custom_fields_projects
-
-  def setup
-    @controller = JournalsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_index
-    get :index, :project_id => 1
-    assert_response :success
-    assert_not_nil assigns(:journals)
-    assert_equal 'application/atom+xml', @response.content_type
-  end
-
-  def test_diff
-    get :diff, :id => 3, :detail_id => 4
-    assert_response :success
-    assert_template 'diff'
-
-    assert_tag 'span',
-      :attributes => {:class => 'diff_out'},
-      :content => /removed/
-    assert_tag 'span',
-      :attributes => {:class => 'diff_in'},
-      :content => /added/
-  end
-
-  def test_reply_to_issue
-    @request.session[:user_id] = 2
-    get :new, :id => 6
-    assert_response :success
-    assert_select_rjs :show, "update"
-  end
-
-  def test_reply_to_issue_without_permission
-    @request.session[:user_id] = 7
-    get :new, :id => 6
-    assert_response 403
-  end
-
-  def test_reply_to_note
-    @request.session[:user_id] = 2
-    get :new, :id => 6, :journal_id => 4
-    assert_response :success
-    assert_select_rjs :show, "update"
-  end
-
-  def test_get_edit
-    @request.session[:user_id] = 1
-    xhr :get, :edit, :id => 2
-    assert_response :success
-    assert_select_rjs :insert, :after, 'journal-2-notes' do
-      assert_select 'form[id=journal-2-form]'
-      assert_select 'textarea'
-    end
-  end
-
-  def test_post_edit
-    @request.session[:user_id] = 1
-    xhr :post, :edit, :id => 2, :notes => 'Updated notes'
-    assert_response :success
-    assert_select_rjs :replace, 'journal-2-notes'
-    assert_equal 'Updated notes', Journal.find(2).notes
-  end
-
-  def test_post_edit_with_empty_notes
-    @request.session[:user_id] = 1
-    xhr :post, :edit, :id => 2, :notes => ''
-    assert_response :success
-    assert_select_rjs :remove, 'change-2'
-    assert_nil Journal.find_by_id(2)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b7/b7c7443654af68cf9c522afbacac1ebc7839e6c2.svn-base
--- /dev/null
+++ b/.svn/pristine/b7/b7c7443654af68cf9c522afbacac1ebc7839e6c2.svn-base
@@ -0,0 +1,9 @@
+class ChangeUsersLastnameLengthTo255 < ActiveRecord::Migration
+  def self.up
+    change_column :users, :lastname, :string, :limit => 255, :default => '', :null => false
+  end
+
+  def self.down
+    change_column :users, :lastname, :string, :limit => 30, :default => '', :null => false
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b7/b7ce32d6d323c0c17625f798be613bed9b23b225.svn-base
--- a/.svn/pristine/b7/b7ce32d6d323c0c17625f798be613bed9b23b225.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
---- 
-auth_sources_001: 
-  id: 1
-  type: AuthSourceLdap
-  name: 'LDAP test server'
-  host: '127.0.0.1'
-  port: 389
-  base_dn: 'OU=Person,DC=redmine,DC=org'
-  attr_login: uid
-  attr_firstname: givenName
-  attr_lastname: sn
-  attr_mail: mail
-  onthefly_register: true
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b8/b80a919fe53496e29af18c43cb6375f80fa86ba6.svn-base
--- a/.svn/pristine/b8/b80a919fe53496e29af18c43cb6375f80fa86ba6.svn-base
+++ /dev/null
@@ -1,204 +0,0 @@
-#!/usr/bin/env ruby
-
-# test_binarytree.rb
-#
-# $Revision: 1.5 $ by $Author: anupamsg $
-# $Name:  $
-#
-# Copyright (c) 2006, 2007 Anupam Sengupta
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# - Redistributions of source code must retain the above copyright notice, this
-#   list of conditions and the following disclaimer.
-#
-# - Redistributions in binary form must reproduce the above copyright notice, this
-#   list of conditions and the following disclaimer in the documentation and/or
-#   other materials provided with the distribution.
-#
-# - Neither the name of the organization nor the names of its contributors may
-#   be used to endorse or promote products derived from this software without
-#   specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-require 'test/unit'
-require 'tree/binarytree'
-
-module TestTree
-  # Test class for the Tree node.
-  class TestBinaryTreeNode < Test::Unit::TestCase
-
-    def setup
-      @root = Tree::BinaryTreeNode.new("ROOT", "Root Node")
-
-      @left_child1  = Tree::BinaryTreeNode.new("A Child at Left", "Child Node @ left")
-      @right_child1 = Tree::BinaryTreeNode.new("B Child at Right", "Child Node @ right")
-
-    end
-
-    def teardown
-      @root.remove!(@left_child1)
-      @root.remove!(@right_child1)
-      @root = nil
-    end
-
-    def test_initialize
-      assert_not_nil(@root, "Binary tree's Root should have been created")
-    end
-
-    def test_add
-      @root.add  @left_child1
-      assert_same(@left_child1, @root.leftChild, "The left node should be left_child1")
-      assert_same(@left_child1, @root.firstChild, "The first node should be left_child1")
-
-      @root.add @right_child1
-      assert_same(@right_child1, @root.rightChild, "The right node should be right_child1")
-      assert_same(@right_child1, @root.lastChild, "The first node should be right_child1")
-
-      assert_raise RuntimeError do
-        @root.add Tree::BinaryTreeNode.new("The third child!")
-      end
-
-      assert_raise RuntimeError do
-        @root << Tree::BinaryTreeNode.new("The third child!")
-      end
-    end
-
-    def test_leftChild
-      @root << @left_child1
-      @root << @right_child1
-      assert_same(@left_child1, @root.leftChild, "The left child should be 'left_child1")
-      assert_not_same(@right_child1, @root.leftChild, "The right_child1 is not the left child")
-    end
-
-    def test_rightChild
-      @root << @left_child1
-      @root << @right_child1
-      assert_same(@right_child1, @root.rightChild, "The right child should be 'right_child1")
-      assert_not_same(@left_child1, @root.rightChild, "The left_child1 is not the left child")
-    end
-
-    def test_leftChild_equals
-      @root << @left_child1
-      @root << @right_child1
-      assert_same(@left_child1, @root.leftChild, "The left child should be 'left_child1")
-
-      @root.leftChild = Tree::BinaryTreeNode.new("New Left Child")
-      assert_equal("New Left Child", @root.leftChild.name, "The left child should now be the new child")
-      assert_equal("B Child at Right", @root.lastChild.name, "The last child should now be the right child")
-
-      # Now set the left child as nil, and retest
-      @root.leftChild = nil
-      assert_nil(@root.leftChild, "The left child should now be nil")
-      assert_nil(@root.firstChild, "The first child is now nil")
-      assert_equal("B Child at Right", @root.lastChild.name, "The last child should now be the right child")
-    end
-
-    def test_rightChild_equals
-      @root << @left_child1
-      @root << @right_child1
-      assert_same(@right_child1, @root.rightChild, "The right child should be 'right_child1")
-
-      @root.rightChild = Tree::BinaryTreeNode.new("New Right Child")
-      assert_equal("New Right Child", @root.rightChild.name, "The right child should now be the new child")
-      assert_equal("A Child at Left", @root.firstChild.name, "The first child should now be the left child")
-      assert_equal("New Right Child", @root.lastChild.name, "The last child should now be the right child")
-
-      # Now set the right child as nil, and retest
-      @root.rightChild = nil
-      assert_nil(@root.rightChild, "The right child should now be nil")
-      assert_equal("A Child at Left", @root.firstChild.name, "The first child should now be the left child")
-      assert_nil(@root.lastChild, "The first child is now nil")
-    end
-
-    def test_isLeftChild_eh
-      @root << @left_child1
-      @root << @right_child1
-
-      assert(@left_child1.isLeftChild?, "left_child1 should be the left child")
-      assert(!@right_child1.isLeftChild?, "left_child1 should be the left child")
-
-      # Now set the right child as nil, and retest
-      @root.rightChild = nil
-      assert(@left_child1.isLeftChild?, "left_child1 should be the left child")
-
-      assert(!@root.isLeftChild?, "Root is neither left child nor right")
-    end
-
-    def test_isRightChild_eh
-      @root << @left_child1
-      @root << @right_child1
-
-      assert(@right_child1.isRightChild?, "right_child1 should be the right child")
-      assert(!@left_child1.isRightChild?, "right_child1 should be the right child")
-
-      # Now set the left child as nil, and retest
-      @root.leftChild = nil
-      assert(@right_child1.isRightChild?, "right_child1 should be the right child")
-      assert(!@root.isRightChild?, "Root is neither left child nor right")
-    end
-
-    def test_swap_children
-      @root << @left_child1
-      @root << @right_child1
-
-      assert(@right_child1.isRightChild?, "right_child1 should be the right child")
-      assert(!@left_child1.isRightChild?, "right_child1 should be the right child")
-
-      @root.swap_children
-
-      assert(@right_child1.isLeftChild?, "right_child1 should now be the left child")
-      assert(@left_child1.isRightChild?, "left_child1 should now be the right child")
-      assert_equal(@right_child1, @root.firstChild, "right_child1 should now be the first child")
-      assert_equal(@left_child1, @root.lastChild, "left_child1 should now be the last child")
-      assert_equal(@right_child1, @root[0], "right_child1 should now be the first child")
-      assert_equal(@left_child1, @root[1], "left_child1 should now be the last child")
-    end
-  end
-end
-
-# $Log: test_binarytree.rb,v $
-# Revision 1.5  2007/12/22 00:28:59  anupamsg
-# Added more test cases, and enabled ZenTest compatibility.
-#
-# Revision 1.4  2007/12/18 23:11:29  anupamsg
-# Minor documentation changes in the binarytree class.
-#
-# Revision 1.3  2007/10/02 03:07:30  anupamsg
-# * Rakefile: Added an optional task for rcov code coverage.
-#
-# * test/test_binarytree.rb: Removed the unnecessary dependency on "Person" class.
-#
-# * test/test_tree.rb: Removed dependency on the redundant "Person" class.
-#
-# Revision 1.2  2007/08/30 22:06:13  anupamsg
-# Added a new swap_children method for the Binary Tree class.
-# Also made minor documentation updates and test additions.
-#
-# Revision 1.1  2007/07/21 04:52:37  anupamsg
-# Renamed the test files.
-#
-# Revision 1.4  2007/07/19 02:03:57  anupamsg
-# Minor syntax correction.
-#
-# Revision 1.3  2007/07/19 02:02:12  anupamsg
-# Removed useless files (including rdoc, which should be generated for each release.
-#
-# Revision 1.2  2007/07/18 20:15:06  anupamsg
-# Added two predicate methods in BinaryTreeNode to determine whether a node
-# is a left or a right node.
-#
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b8/b871d50d611e927908723febabdcb8cd0183c9ab.svn-base
--- a/.svn/pristine/b8/b871d50d611e927908723febabdcb8cd0183c9ab.svn-base
+++ /dev/null
@@ -1,539 +0,0 @@
-# tree.rb
-#
-# $Revision: 1.29 $ by $Author: anupamsg $
-# $Name:  $
-#
-# = tree.rb - Generic Multi-way Tree implementation
-#
-# Provides a generic tree data structure with ability to
-# store keyed node elements in the tree. The implementation
-# mixes in the Enumerable module.
-#
-# Author:: Anupam Sengupta (anupamsg@gmail.com)
-#
-
-# Copyright (c) 2006, 2007 Anupam Sengupta
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# - Redistributions of source code must retain the above copyright notice, this
-#   list of conditions and the following disclaimer.
-#
-# - Redistributions in binary form must reproduce the above copyright notice, this
-#   list of conditions and the following disclaimer in the documentation and/or
-#   other materials provided with the distribution.
-#
-# - Neither the name of the organization nor the names of its contributors may
-#   be used to endorse or promote products derived from this software without
-#   specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-# This module provides a TreeNode class which is the primary class for all
-# nodes represented in the Tree.
-# This module mixes in the Enumerable module.
-module Tree
-
-  # Rubytree Package Version
-  VERSION = '0.5.2'
-
-  # == TreeNode Class Description
-  #
-  # The node class for the tree representation. the nodes are named and have a
-  # place-holder for the node data (i.e., the `content' of the node). The node
-  # names are expected to be unique.  In addition, the node provides navigation
-  # methods to traverse the tree.
-  #
-  # The nodes can have any number of child nodes attached to it. Note that while
-  # this implementation does not support directed graphs, the class itself makes
-  # no restrictions on associating a node's CONTENT with multiple parent nodes.
-  #
-  #
-  # == Example
-  #
-  #  The following code-snippet implements this tree structure:
-  #
-  #                    +------------+
-  #                    |    ROOT    |
-  #                    +-----+------+
-  #            +-------------+------------+
-  #            |                          |
-  #    +-------+-------+          +-------+-------+
-  #    |  CHILD 1      |          |  CHILD 2      |
-  #    +-------+-------+          +---------------+
-  #            |
-  #            |
-  #    +-------+-------+
-  #    | GRANDCHILD 1  |
-  #    +---------------+
-  #
-  # require 'tree'
-  #
-  # myTreeRoot = Tree::TreeNode.new("ROOT", "Root Content")
-  #
-  # myTreeRoot << Tree::TreeNode.new("CHILD1", "Child1 Content") << Tree::TreeNode.new("GRANDCHILD1", "GrandChild1 Content")
-  #
-  # myTreeRoot << Tree::TreeNode.new("CHILD2", "Child2 Content")
-  #
-  # myTreeRoot.printTree
-  #
-  # child1 = myTreeRoot["CHILD1"]
-  #
-  # grandChild1 = myTreeRoot["CHILD1"]["GRANDCHILD1"]
-  #
-  # siblingsOfChild1Array = child1.siblings
-  #
-  # immediateChildrenArray = myTreeRoot.children
-  #
-  # # Process all nodes
-  #
-  # myTreeRoot.each { |node| node.content.reverse }
-  #
-  # myTreeRoot.remove!(child1) # Remove the child
-  class TreeNode
-    include Enumerable
-
-    attr_reader :content, :name, :parent
-    attr_writer :content
-
-    # Constructor which expects the name of the node
-    #
-    # Name of the node is expected to be unique across the
-    # tree.
-    #
-    # The content can be of any type, and is defaulted to _nil_.
-    def initialize(name, content = nil)
-      raise "Node name HAS to be provided" if name == nil
-      @name = name
-      @content = content
-      self.setAsRoot!
-
-      @childrenHash = Hash.new
-      @children = []
-    end
-
-    # Returns a copy of this node, with the parent and children links removed.
-    def detached_copy
-      Tree::TreeNode.new(@name, @content ? @content.clone : nil)
-    end
-
-    # Print the string representation of this node.
-    def to_s
-      "Node Name: #{@name}" +
-        " Content: " + (@content || "<Empty>") +
-        " Parent: " + (isRoot?()  ? "<None>" : @parent.name) +
-        " Children: #{@children.length}" +
-        " Total Nodes: #{size()}"
-    end
-
-    # Returns an array of ancestors in reversed order (the first element is the
-    # immediate parent). Returns nil if this is a root node.
-    def parentage
-      return nil if isRoot?
-
-      parentageArray = []
-      prevParent = self.parent
-      while (prevParent)
-        parentageArray << prevParent
-        prevParent = prevParent.parent
-      end
-
-      parentageArray
-    end
-
-    # Protected method to set the parent node.
-    # This method should NOT be invoked by client code.
-    def parent=(parent)
-      @parent = parent
-    end
-
-    # Convenience synonym for TreeNode#add method.  This method allows a convenient
-    # method to add children hierarchies in the tree.
-    #
-    # E.g. root << child << grand_child
-    def <<(child)
-      add(child)
-    end
-
-    # Adds the specified child node to the receiver node.  The child node's
-    # parent is set to be the receiver.  The child is added as the last child in
-    # the current list of children for the receiver node.
-    def add(child)
-      raise "Child already added" if @childrenHash.has_key?(child.name)
-
-      @childrenHash[child.name]  = child
-      @children << child
-      child.parent = self
-      return child
-
-    end
-
-    # Removes the specified child node from the receiver node.  The removed
-    # children nodes are orphaned but available if an alternate reference
-    # exists.
-    #
-    # Returns the child node.
-    def remove!(child)
-      @childrenHash.delete(child.name)
-      @children.delete(child)
-      child.setAsRoot! unless child == nil
-      return child
-    end
-
-    # Removes this node from its parent. If this is the root node, then does
-    # nothing.
-    def removeFromParent!
-      @parent.remove!(self) unless isRoot?
-    end
-
-    # Removes all children from the receiver node.
-    def removeAll!
-      for child in @children
-        child.setAsRoot!
-      end
-      @childrenHash.clear
-      @children.clear
-      self
-    end
-
-    # Indicates whether this node has any associated content.
-    def hasContent?
-      @content != nil
-    end
-
-    # Protected method which sets this node as a root node.
-    def setAsRoot!
-      @parent = nil
-    end
-
-    # Indicates whether this node is a root node. Note that
-    # orphaned children will also be reported as root nodes.
-    def isRoot?
-      @parent == nil
-    end
-
-    # Indicates whether this node has any immediate child nodes.
-    def hasChildren?
-      @children.length != 0
-    end
-
-    # Indicates whether this node is a 'leaf' - i.e., one without
-    # any children
-    def isLeaf?
-      !hasChildren?
-    end
-
-    # Returns an array of all the immediate children.  If a block is given,
-    # yields each child node to the block.
-    def children
-      if block_given?
-        @children.each {|child| yield child}
-      else
-        @children
-      end
-    end
-
-    # Returns the first child of this node. Will return nil if no children are
-    # present.
-    def firstChild
-      children.first
-    end
-
-    # Returns the last child of this node. Will return nil if no children are
-    # present.
-    def lastChild
-      children.last
-    end
-
-    # Returns every node (including the receiver node) from the tree to the
-    # specified block. The traversal is depth first and from left to right in
-    # pre-ordered sequence.
-    def each &block
-      yield self
-      children { |child| child.each(&block) }
-    end
-
-    # Traverses the tree in a pre-ordered sequence. This is equivalent to
-    # TreeNode#each
-    def preordered_each &block
-      each(&block)
-    end
-
-    # Performs breadth first traversal of the tree rooted at this node. The
-    # traversal in a given level is from left to right.
-    def breadth_each &block
-      node_queue = [self]       # Create a queue with self as the initial entry
-
-      # Use a queue to do breadth traversal
-      until node_queue.empty?
-        node_to_traverse = node_queue.shift
-        yield node_to_traverse
-        # Enqueue the children from left to right.
-        node_to_traverse.children { |child| node_queue.push child }
-      end
-    end
-
-    # Yields all leaf nodes from this node to the specified block. May yield
-    # this node as well if this is a leaf node.  Leaf traversal depth first and
-    # left to right.
-    def each_leaf &block
-      self.each { |node| yield(node) if node.isLeaf? }
-    end
-
-    # Returns the requested node from the set of immediate children.
-    #
-    # If the parameter is _numeric_, then the in-sequence array of children is
-    # accessed (see Tree#children).  If the parameter is not _numeric_, then it
-    # is assumed to be the *name* of the child node to be returned.
-    def [](name_or_index)
-      raise "Name_or_index needs to be provided" if name_or_index == nil
-
-      if name_or_index.kind_of?(Integer)
-        @children[name_or_index]
-      else
-        @childrenHash[name_or_index]
-      end
-    end
-
-    # Returns the total number of nodes in this tree, rooted at the receiver
-    # node.
-    def size
-      @children.inject(1) {|sum, node| sum + node.size}
-    end
-
-    # Convenience synonym for Tree#size
-    def length
-      size()
-    end
-
-    # Pretty prints the tree starting with the receiver node.
-    def printTree(level = 0)
-
-      if isRoot?
-        print "*"
-      else
-        print "|" unless parent.isLastSibling?
-        print(' ' * (level - 1) * 4)
-        print(isLastSibling? ? "+" : "|")
-        print "---"
-        print(hasChildren? ? "+" : ">")
-      end
-
-      puts " #{name}"
-
-      children { |child| child.printTree(level + 1)}
-    end
-
-    # Returns the root for this tree. Root's root is itself.
-    def root
-      root = self
-      root = root.parent while !root.isRoot?
-      root
-    end
-
-    # Returns the first sibling for this node. If this is the root node, returns
-    # itself.
-    def firstSibling
-      if isRoot?
-        self
-      else
-        parent.children.first
-      end
-    end
-
-    # Returns true if this node is the first sibling.
-    def isFirstSibling?
-      firstSibling == self
-    end
-
-    # Returns the last sibling for this node.  If this node is the root, returns
-    # itself.
-    def lastSibling
-      if isRoot?
-        self
-      else
-        parent.children.last
-      end
-    end
-
-    # Returns true if his node is the last sibling
-    def isLastSibling?
-      lastSibling == self
-    end
-
-    # Returns an array of siblings for this node.
-    # If a block is provided, yields each of the sibling
-    # nodes to the block. The root always has nil siblings.
-    def siblings
-      return nil if isRoot?
-      if block_given?
-        for sibling in parent.children
-          yield sibling if sibling != self
-        end
-      else
-        siblings = []
-        parent.children {|sibling| siblings << sibling if sibling != self}
-        siblings
-      end
-    end
-
-    # Returns true if this node is the only child of its parent
-    def isOnlyChild?
-      parent.children.size == 1
-    end
-
-    # Returns the next sibling for this node. Will return nil if no subsequent
-    # node is present.
-    def nextSibling
-      if myidx = parent.children.index(self)
-        parent.children.at(myidx + 1)
-      end
-    end
-
-    # Returns the previous sibling for this node. Will return nil if no
-    # subsequent node is present.
-    def previousSibling
-      if myidx = parent.children.index(self)
-        parent.children.at(myidx - 1) if myidx > 0
-      end
-    end
-
-    # Provides a comparision operation for the nodes. Comparision
-    # is based on the natural character-set ordering for the
-    # node names.
-    def <=>(other)
-      return +1 if other == nil
-      self.name <=> other.name
-    end
-
-    # Freezes all nodes in the tree
-    def freezeTree!
-      each {|node| node.freeze}
-    end
-
-    # Creates the marshal-dump represention of the tree rooted at this node.
-    def marshal_dump
-      self.collect { |node| node.createDumpRep }
-    end
-
-    # Creates a dump representation and returns the same as a hash.
-    def createDumpRep
-      { :name => @name, :parent => (isRoot? ? nil : @parent.name),  :content => Marshal.dump(@content)}
-    end
-
-    # Loads a marshalled dump of the tree and returns the root node of the
-    # reconstructed tree. See the Marshal class for additional details.
-    def marshal_load(dumped_tree_array)
-      nodes = { }
-      for node_hash in dumped_tree_array do
-        name        = node_hash[:name]
-        parent_name = node_hash[:parent]
-        content     = Marshal.load(node_hash[:content])
-
-        if parent_name then
-          nodes[name] = current_node = Tree::TreeNode.new(name, content)
-          nodes[parent_name].add current_node
-        else
-          # This is the root node, hence initialize self.
-          initialize(name, content)
-
-          nodes[name] = self    # Add self to the list of nodes
-         end
-      end
-    end
-
-    # Returns depth of the tree from this node. A single leaf node has a
-    # depth of 1.
-    def depth
-      return 1 if isLeaf?
-      1 + @children.collect { |child| child.depth }.max
-    end
-
-    # Returns breadth of the tree at this node level. A single node has a
-    # breadth of 1.
-    def breadth
-      return 1 if isRoot?
-      parent.children.size
-    end
-
-    protected :parent=, :setAsRoot!, :createDumpRep
-
-  end
-end
-
-# $Log: tree.rb,v $
-# Revision 1.29  2007/12/22 00:28:59  anupamsg
-# Added more test cases, and enabled ZenTest compatibility.
-#
-# Revision 1.28  2007/12/20 03:19:33  anupamsg
-# * README (Module): Modified the install instructions from source.
-# (Module): Updated the minor version number.
-#
-# Revision 1.27  2007/12/20 03:00:03  anupamsg
-# Minor code changes. Removed self_initialize from the protected methods' list.
-#
-# Revision 1.26  2007/12/20 02:50:04  anupamsg
-# (Tree::TreeNode): Removed the spurious self_initialize from the protected list.
-#
-# Revision 1.25  2007/12/19 20:28:05  anupamsg
-# Removed the unnecesary self_initialize method.
-#
-# Revision 1.24  2007/12/19 06:39:17  anupamsg
-# Removed the unnecessary field and record separator constants.  Also updated the
-# history.txt file.
-#
-# Revision 1.23  2007/12/19 06:25:00  anupamsg
-# (Tree::TreeNode): Minor fix to the comments.  Also fixed the private/protected
-# scope issue with the createDumpRep method.
-#
-# Revision 1.22  2007/12/19 06:22:03  anupamsg
-# Updated the marshalling logic to correctly handle non-string content. This
-# should fix the bug # 15614 ("When dumping with an Object as the content, you get
-# a delimiter collision")
-#
-# Revision 1.21  2007/12/19 02:24:17  anupamsg
-# Updated the marshalling logic to handle non-string contents on the nodes.
-#
-# Revision 1.20  2007/10/10 08:42:57  anupamsg
-# Release 0.4.3
-#
-# Revision 1.19  2007/08/31 01:16:27  anupamsg
-# Added breadth and pre-order traversals for the tree. Also added a method
-# to return the detached copy of a node from the tree.
-#
-# Revision 1.18  2007/07/21 05:14:44  anupamsg
-# Added a VERSION constant to the Tree module,
-# and using the same in the Rakefile.
-#
-# Revision 1.17  2007/07/21 03:24:25  anupamsg
-# Minor edits to parameter names. User visible functionality does not change.
-#
-# Revision 1.16  2007/07/18 23:38:55  anupamsg
-# Minor updates to tree.rb
-#
-# Revision 1.15  2007/07/18 22:11:50  anupamsg
-# Added depth and breadth methods for the TreeNode.
-#
-# Revision 1.14  2007/07/18 19:33:27  anupamsg
-# Added a new binary tree implementation.
-#
-# Revision 1.13  2007/07/18 07:17:34  anupamsg
-# Fixed a  issue where TreeNode.ancestors was shadowing Module.ancestors. This method
-# has been renamed to TreeNode.parentage.
-#
-# Revision 1.12  2007/07/17 03:39:28  anupamsg
-# Moved the CVS Log keyword to end of the files.
-#
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b8/b88a5636c69b130c8183f821f7a1caea35568ba0.svn-base
--- a/.svn/pristine/b8/b88a5636c69b130c8183f821f7a1caea35568ba0.svn-base
+++ /dev/null
@@ -1,1008 +0,0 @@
-# Serbian translations for Redmine
-# by Vladimir MedaroviÄ‡ (vlada@medarovic.com)
-sr-YU:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%d.%m.%Y."
-      short: "%e %b"
-      long: "%B %e, %Y"
-      
-    day_names: [nedelja, ponedeljak, utorak, sreda, Äetvrtak, petak, subota]
-    abbr_day_names: [ned, pon, uto, sre, Äet, pet, sub]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, januar, februar, mart, april, maj, jun, jul, avgust, septembar, oktobar, novembar, decembar]
-    abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, avg, sep, okt, nov, dec]
-    # Used in date_select and datime_select.
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%d.%m.%Y. u %H:%M"
-      time: "%H:%M"
-      short: "%d. %b u %H:%M"
-      long: "%d. %B %Y u %H:%M"
-    am: "am"
-    pm: "pm"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "pola minuta"
-      less_than_x_seconds:
-        one:   "manje od jedne sekunde"
-        other: "manje od %{count} sek."
-      x_seconds:
-        one:   "jedna sekunda"
-        other: "%{count} sek."
-      less_than_x_minutes:
-        one:   "manje od minuta"
-        other: "manje od %{count} min."
-      x_minutes:
-        one:   "jedan minut"
-        other: "%{count} min."
-      about_x_hours:
-        one:   "pribliÅ¾no jedan sat"
-        other: "pribliÅ¾no %{count} sati"
-      x_days:
-        one:   "jedan dan"
-        other: "%{count} dana"
-      about_x_months:
-        one:   "pribliÅ¾no jedan mesec"
-        other: "pribliÅ¾no %{count} meseci"
-      x_months:
-        one:   "jedan mesec"
-        other: "%{count} meseci"
-      about_x_years:
-        one:   "pribliÅ¾no godinu dana"
-        other: "pribliÅ¾no %{count} god."
-      over_x_years:
-        one:   "preko godinu dana"
-        other: "preko %{count} god."
-      almost_x_years:
-        one:   "skoro godinu dana"
-        other: "skoro %{count} god."
-
-  number:
-    format:
-      separator: ","
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "i"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "nije ukljuÄen u spisak"
-        exclusion: "je rezervisan"
-        invalid: "je neispravan"
-        confirmation: "potvrda ne odgovara"
-        accepted: "mora biti prihvaÄ‡en"
-        empty: "ne moÅ¾e biti prazno"
-        blank: "ne moÅ¾e biti prazno"
-        too_long: "je predugaÄka (maksimum znakova je %{count})"
-        too_short: "je prekratka (minimum znakova je %{count})"
-        wrong_length: "je pogreÅ¡ne duÅ¾ine (broj znakova mora biti %{count})"
-        taken: "je veÄ‡ u upotrebi"
-        not_a_number: "nije broj"
-        not_a_date: "nije ispravan datum"
-        greater_than: "mora biti veÄ‡i od %{count}"
-        greater_than_or_equal_to: "mora biti veÄ‡i ili jednak %{count}"
-        equal_to: "mora biti jednak %{count}"
-        less_than: "mora biti manji od %{count}"
-        less_than_or_equal_to: "mora biti manji ili jednak %{count}"
-        odd: "mora biti paran"
-        even: "mora biti neparan"
-        greater_than_start_date: "mora biti veÄ‡i od poÄetnog datuma"
-        not_same_project: "ne pripada istom projektu"
-        circular_dependency: "Ova veza Ä‡e stvoriti kruÅ¾nu referencu"
-        cant_link_an_issue_with_a_descendant: "Problem ne moÅ¾e biti povezan sa jednim od svojih podzadataka"
-
-  actionview_instancetag_blank_option: Molim odaberite
-  
-  general_text_No: 'Ne'
-  general_text_Yes: 'Da'
-  general_text_no: 'ne'
-  general_text_yes: 'da'
-  general_lang_name: 'Srpski'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: Nalog je uspeÅ¡no aÅ¾uriran.
-  notice_account_invalid_creditentials: Neispravno korisniÄko ime ili lozinka.
-  notice_account_password_updated: Lozinka je uspeÅ¡no aÅ¾urirana.
-  notice_account_wrong_password: PogreÅ¡na lozinka
-  notice_account_register_done: KorisniÄki nalog je uspeÅ¡no kreiran. Kliknite na link koji ste dobili u e-poruci za aktivaciju.
-  notice_account_unknown_email: Nepoznat korisnik.
-  notice_can_t_change_password: Ovaj korisniÄki nalog za potvrdu identiteta koristi spoljni izvor. NemoguÄ‡e je promeniti lozinku.
-  notice_account_lost_email_sent: Poslata vam je e-poruka sa uputstvom za izbor nove lozinke
-  notice_account_activated: VaÅ¡ korisniÄki nalog je aktiviran. Sada se moÅ¾ete prijaviti.
-  notice_successful_create: UspeÅ¡no kreiranje.
-  notice_successful_update: UspeÅ¡no aÅ¾uriranje.
-  notice_successful_delete: UspeÅ¡no brisanje.
-  notice_successful_connection: UspeÅ¡no povezivanje.
-  notice_file_not_found: Strana kojoj Å¾elite pristupiti ne postoji ili je uklonjena.
-  notice_locking_conflict: Podatak je aÅ¾uriran od strane drugog korisnika.
-  notice_not_authorized: Niste ovlaÅ¡Ä‡eni za pristup ovoj strani.
-  notice_email_sent: "E-poruka je poslata na %{value}"
-  notice_email_error: "Dogodila se greÅ¡ka prilikom slanja e-poruke (%{value})"
-  notice_feeds_access_key_reseted: VaÅ¡ RSS pristupni kljuÄ je poniÅ¡ten.
-  notice_api_access_key_reseted: VaÅ¡ API pristupni kljuÄ je poniÅ¡ten.
-  notice_failed_to_save_issues: "NeuspeÅ¡no snimanje %{count} problema od %{total} odabranih: %{ids}."
-  notice_failed_to_save_members: "NeuspeÅ¡no snimanje Älana(ova): %{errors}."
-  notice_no_issue_selected: "Ni jedan problem nije odabran! Molimo, odaberite problem koji Å¾elite da menjate."
-  notice_account_pending: "VaÅ¡ nalog je kreiran i Äeka na odobrenje administratora."
-  notice_default_data_loaded: Podrazumevano konfigurisanje je uspeÅ¡no uÄitano.
-  notice_unable_delete_version: Verziju je nemoguÄ‡e izbrisati.
-  notice_unable_delete_time_entry: Stavku evidencije vremena je nemoguÄ‡e izbrisati.
-  notice_issue_done_ratios_updated: Odnos reÅ¡enih problema je aÅ¾uriran.
-  
-  error_can_t_load_default_data: "Podrazumevano konfigurisanje je nemoguÄ‡e uÄitati: %{value}"
-  error_scm_not_found: "Stavka ili ispravka nisu pronaÄ‘ene u spremiÅ¡tu."
-  error_scm_command_failed: "GreÅ¡ka se javila prilikom pokuÅ¡aja pristupa spremiÅ¡tu: %{value}"
-  error_scm_annotate: "Stavka ne postoji ili ne moÅ¾e biti oznaÄena."
-  error_issue_not_found_in_project: 'Problem nije pronaÄ‘en ili ne pripada ovom projektu.'
-  error_no_tracker_in_project: 'Ni jedno praÄ‡enje nije povezano sa ovim projektom. Molimo proverite podeÅ¡avanja projekta.'
-  error_no_default_issue_status: 'Podrazumevani status problema nije definisan. Molimo proverite vaÅ¡e konfigurisanje (idite na "Administracija -> Statusi problema").'
-  error_can_not_delete_custom_field: NemoguÄ‡e je izbrisati prilagoÄ‘eno polje
-  error_can_not_delete_tracker: "Ovo praÄ‡enje sadrÅ¾i probleme i ne moÅ¾e biti obrisano."
-  error_can_not_remove_role: "Ova uloga je u upotrebi i ne moÅ¾e biti obrisana."
-  error_can_not_reopen_issue_on_closed_version: 'Problem dodeljen zatvorenoj verziji ne moÅ¾e biti ponovo otvoren'
-  error_can_not_archive_project: Ovaj projekat se ne moÅ¾e arhivirati
-  error_issue_done_ratios_not_updated: "Odnos reÅ¡enih problema nije aÅ¾uriran."
-  error_workflow_copy_source: 'Molimo odaberite izvorno praÄ‡enje ili ulogu'
-  error_workflow_copy_target: 'Molimo odaberite odrediÅ¡no praÄ‡enje i ulogu'
-  error_unable_delete_issue_status: 'Status problema je nemoguÄ‡e obrisati'
-  error_unable_to_connect: "Povezivanje sa (%{value}) je nemoguÄ‡e"  
-  warning_attachments_not_saved: "%{count} datoteka ne moÅ¾e biti snimljena."
-  
-  mail_subject_lost_password: "VaÅ¡a %{value} lozinka"
-  mail_body_lost_password: 'Za promenu vaÅ¡e lozinke, kliknite na sledeÄ‡i link:'
-  mail_subject_register: "Aktivacija vaÅ¡eg %{value} naloga"
-  mail_body_register: 'Za aktivaciju vaÅ¡eg naloga, kliknite na sledeÄ‡i link:'
-  mail_body_account_information_external: "VaÅ¡ nalog %{value} moÅ¾ete koristiti za prijavu."
-  mail_body_account_information: Informacije o vaÅ¡em nalogu
-  mail_subject_account_activation_request: "Zahtev za aktivaciju naloga %{value}"
-  mail_body_account_activation_request: "Novi korisnik (%{value}) je registrovan. Nalog Äeka na vaÅ¡e odobrenje:"
-  mail_subject_reminder: "%{count} problema dospeva narednih %{days} dana"
-  mail_body_reminder: "%{count} problema dodeljenih vama dospeva u narednih %{days} dana:"
-  mail_subject_wiki_content_added: "Wiki stranica '%{id}' je dodata"
-  mail_body_wiki_content_added: "%{author} je dodao wiki stranicu '%{id}'."
-  mail_subject_wiki_content_updated: "Wiki stranica '%{id}' je aÅ¾urirana"
-  mail_body_wiki_content_updated: "%{author} je aÅ¾urirao wiki stranicu '%{id}'."
-  
-  gui_validation_error: jedna greÅ¡ka
-  gui_validation_error_plural: "%{count} greÅ¡aka"
-  
-  field_name: Naziv
-  field_description: Opis
-  field_summary: Rezime
-  field_is_required: Obavezno
-  field_firstname: Ime
-  field_lastname: Prezime
-  field_mail: E-adresa
-  field_filename: Datoteka
-  field_filesize: VeliÄina
-  field_downloads: Preuzimanja
-  field_author: Autor
-  field_created_on: Kreirano
-  field_updated_on: AÅ¾urirano
-  field_field_format: Format
-  field_is_for_all: Za sve projekte
-  field_possible_values: MoguÄ‡e vrednosti
-  field_regexp: Regularan izraz
-  field_min_length: Minimalna duÅ¾ina
-  field_max_length: Maksimalna duÅ¾ina
-  field_value: Vrednost
-  field_category: Kategorija
-  field_title: Naslov
-  field_project: Projekat
-  field_issue: Problem
-  field_status: Status
-  field_notes: BeleÅ¡ke
-  field_is_closed: Zatvoren problem
-  field_is_default: Podrazumevana vrednost
-  field_tracker: PraÄ‡enje
-  field_subject: Predmet
-  field_due_date: Krajnji rok
-  field_assigned_to: Dodeljeno
-  field_priority: Prioritet
-  field_fixed_version: OdrediÅ¡na verzija
-  field_user: Korisnik
-  field_principal: Glavni
-  field_role: Uloga
-  field_homepage: PoÄetna stranica
-  field_is_public: Javno objavljivanje
-  field_parent: Potprojekat od
-  field_is_in_roadmap: Problemi prikazani u planu rada
-  field_login: KorisniÄko ime
-  field_mail_notification: ObaveÅ¡tenja putem e-poÅ¡te
-  field_admin: Administrator
-  field_last_login_on: Poslednje povezivanje
-  field_language: Jezik
-  field_effective_date: Datum
-  field_password: Lozinka
-  field_new_password: Nova lozinka
-  field_password_confirmation: Potvrda lozinke
-  field_version: Verzija
-  field_type: Tip
-  field_host: Glavni raÄunar
-  field_port: Port
-  field_account: KorisniÄki nalog
-  field_base_dn: Bazni DN
-  field_attr_login: Atribut prijavljivanja
-  field_attr_firstname: Atribut imena
-  field_attr_lastname: Atribut prezimena
-  field_attr_mail: Atribut e-adrese
-  field_onthefly: Kreiranje korisnika u toku rada
-  field_start_date: PoÄetak
-  field_done_ratio: "% uraÄ‘eno"
-  field_auth_source: ReÅ¾im potvrde identiteta
-  field_hide_mail: Sakrij moju e-adresu
-  field_comments: Komentar
-  field_url: URL
-  field_start_page: PoÄetna stranica
-  field_subproject: Potprojekat
-  field_hours: sati
-  field_activity: Aktivnost
-  field_spent_on: Datum
-  field_identifier: Identifikator
-  field_is_filter: Upotrebi kao filter
-  field_issue_to: Srodni problemi
-  field_delay: KaÅ¡njenje
-  field_assignable: Problem moÅ¾e biti dodeljen ovoj ulozi
-  field_redirect_existing_links: Preusmeri postojeÄ‡e veze
-  field_estimated_hours: Proteklo vreme
-  field_column_names: Kolone
-  field_time_zone: Vremenska zona
-  field_searchable: MoÅ¾e da se pretraÅ¾uje
-  field_default_value: Podrazumevana vrednost
-  field_comments_sorting: PrikaÅ¾i komentare
-  field_parent_title: MatiÄna stranica
-  field_editable: Izmenljivo
-  field_watcher: PosmatraÄ
-  field_identity_url: OpenID URL
-  field_content: SadrÅ¾aj
-  field_group_by: Grupisanje rezultata po
-  field_sharing: Deljenje
-  field_parent_issue: MatiÄni zadatak
-  
-  setting_app_title: Naslov aplikacije
-  setting_app_subtitle: Podnaslov aplikacije
-  setting_welcome_text: Tekst dobrodoÅ¡lice
-  setting_default_language: Podrazumevani jezik
-  setting_login_required: Obavezna potvrda identiteta
-  setting_self_registration: Samoregistracija
-  setting_attachment_max_size: Maks. veliÄina priloÅ¾ene datoteke
-  setting_issues_export_limit: OgraniÄenje izvoza â€žproblemaâ€œ
-  setting_mail_from: E-adresa poÅ¡iljaoca
-  setting_bcc_recipients: Primaoci â€žBccâ€œ kopije
-  setting_plain_text_mail: Poruka sa Äistim tekstom (bez HTML-a)
-  setting_host_name: Putanja i naziv glavnog raÄunara
-  setting_text_formatting: Oblikovanje teksta
-  setting_wiki_compression: Kompresija Wiki istorije
-  setting_feeds_limit: OgraniÄenje sadrÅ¾aja izvora vesti
-  setting_default_projects_public: Podrazumeva se javno prikazivanje novih projekata
-  setting_autofetch_changesets: IzvrÅ¡avanje automatskog preuzimanja
-  setting_sys_api_enabled: OmoguÄ‡avanje WS za upravljanje spremiÅ¡tem
-  setting_commit_ref_keywords: Referenciranje kljuÄnih reÄi
-  setting_commit_fix_keywords: Popravljanje kljuÄnih reÄi
-  setting_autologin: Automatska prijava
-  setting_date_format: Format datuma
-  setting_time_format: Format vremena
-  setting_cross_project_issue_relations: Dozvoli povezivanje problema iz unakrsnih projekata
-  setting_issue_list_default_columns: Podrazumevane kolone prikazane na spisku problema
-  setting_emails_footer: PodnoÅ¾je stranice e-poruke
-  setting_protocol: Protokol
-  setting_per_page_options: Opcije prikaza objekata po stranici
-  setting_user_format: Format prikaza korisnika
-  setting_activity_days_default: Broj dana prikazanih na projektnoj aktivnosti
-  setting_display_subprojects_issues: Prikazuj probleme iz potprojekata na glavnom projektu, ukoliko nije drugaÄije navedeno
-  setting_enabled_scm: OmoguÄ‡avanje SCM
-  setting_mail_handler_body_delimiters: "SkraÄ‡ivanje e-poruke nakon jedne od ovih linija"
-  setting_mail_handler_api_enabled: OmoguÄ‡avanje WS dolazne e-poruke
-  setting_mail_handler_api_key: API kljuÄ
-  setting_sequential_project_identifiers: Generisanje sekvencijalnog imena projekta
-  setting_gravatar_enabled: Koristi Gravatar korisniÄke ikone
-  setting_gravatar_default: Podrazumevana Gravatar slika
-  setting_diff_max_lines_displayed: Maks. broj prikazanih razliÄitih linija
-  setting_file_max_size_displayed: Maks. veliÄina tekst. datoteka prikazanih umetnuto
-  setting_repository_log_display_limit: Maks. broj revizija prikazanih u datoteci za evidenciju
-  setting_openid: Dozvoli OpenID prijavu i registraciju
-  setting_password_min_length: Minimalna duÅ¾ina lozinke
-  setting_new_project_user_role_id: Kreatoru projekta (koji nije administrator) dodeljuje je uloga
-  setting_default_projects_modules: Podrazumevano omoguÄ‡eni moduli za nove projekte
-  setting_issue_done_ratio: IzraÄunaj odnos reÅ¡enih problema
-  setting_issue_done_ratio_issue_field: koristeÄ‡i polje problema
-  setting_issue_done_ratio_issue_status: koristeÄ‡i status problema
-  setting_start_of_week: Prvi dan u sedmici
-  setting_rest_api_enabled: OmoguÄ‡i REST web usluge
-  setting_cache_formatted_text: KeÅ¡iranje obraÄ‘enog teksta
-  
-  permission_add_project: Kreiranje projekta
-  permission_add_subprojects: Kreiranje potpojekta
-  permission_edit_project: Izmena projekata
-  permission_select_project_modules: Odabiranje modula projekta
-  permission_manage_members: Upravljanje Älanovima
-  permission_manage_project_activities: Upravljanje projektnim aktivnostima
-  permission_manage_versions: Upravljanje verzijama
-  permission_manage_categories: Upravljanje kategorijama problema
-  permission_view_issues: Pregled problema
-  permission_add_issues: Dodavanje problema
-  permission_edit_issues: Izmena problema
-  permission_manage_issue_relations: Upravljanje vezama izmeÄ‘u problema
-  permission_add_issue_notes: Dodavanje beleÅ¡ki
-  permission_edit_issue_notes: Izmena beleÅ¡ki
-  permission_edit_own_issue_notes: Izmena sopstvenih beleÅ¡ki
-  permission_move_issues: Pomeranje problema
-  permission_delete_issues: Brisanje problema
-  permission_manage_public_queries: Upravljanje javnim upitima
-  permission_save_queries: Snimanje upita
-  permission_view_gantt: Pregledanje Gantovog dijagrama
-  permission_view_calendar: Pregledanje kalendara
-  permission_view_issue_watchers: Pregledanje spiska posmatraÄa
-  permission_add_issue_watchers: Dodavanje posmatraÄa
-  permission_delete_issue_watchers: Brisanje posmatraÄa
-  permission_log_time: BeleÅ¾enje utroÅ¡enog vremena
-  permission_view_time_entries: Pregledanje utroÅ¡enog vremena
-  permission_edit_time_entries: Izmena utroÅ¡enog vremena
-  permission_edit_own_time_entries: Izmena sopstvenog utroÅ¡enog vremena
-  permission_manage_news: Upravljanje vestima
-  permission_comment_news: Komentarisanje vesti
-  permission_manage_documents: Upravljanje dokumentima
-  permission_view_documents: Pregledanje dokumenata
-  permission_manage_files: Upravljanje datotekama
-  permission_view_files: Pregledanje datoteka
-  permission_manage_wiki: Upravljanje wiki stranicama
-  permission_rename_wiki_pages: Promena imena wiki stranicama
-  permission_delete_wiki_pages: Brisanje wiki stranica
-  permission_view_wiki_pages: Pregledanje wiki stranica
-  permission_view_wiki_edits: Pregledanje wiki istorije
-  permission_edit_wiki_pages: Izmena wiki stranica
-  permission_delete_wiki_pages_attachments: Brisanje priloÅ¾enih datoteka
-  permission_protect_wiki_pages: ZaÅ¡tita wiki stranica
-  permission_manage_repository: Upravljanje spremiÅ¡tem
-  permission_browse_repository: Pregledanje spremiÅ¡ta
-  permission_view_changesets: Pregledanje skupa promena
-  permission_commit_access: Potvrda pristupa
-  permission_manage_boards: Upravljanje forumima
-  permission_view_messages: Pregledanje poruka
-  permission_add_messages: Slanje poruka
-  permission_edit_messages: Izmena poruka
-  permission_edit_own_messages: Izmena sopstvenih poruka
-  permission_delete_messages: Brisanje poruka
-  permission_delete_own_messages: Brisanje sopstvenih poruka
-  permission_export_wiki_pages: Izvoz wiki stranica
-  permission_manage_subtasks: Upravljanje podzadacima
-  
-  project_module_issue_tracking: PraÄ‡enje problema
-  project_module_time_tracking: PraÄ‡enje vremena
-  project_module_news: Vesti
-  project_module_documents: Dokumenti
-  project_module_files: Datoteke
-  project_module_wiki: Wiki
-  project_module_repository: SpremiÅ¡te
-  project_module_boards: Forumi
-  
-  label_user: Korisnik
-  label_user_plural: Korisnici
-  label_user_new: Novi korisnik
-  label_user_anonymous: Anoniman
-  label_project: Projekat
-  label_project_new: Novi projekat
-  label_project_plural: Projekti
-  label_x_projects:
-    zero:  nema projekata
-    one:   jedan projekat
-    other: "%{count} projekata"
-  label_project_all: Svi projekti
-  label_project_latest: Poslednji projekti
-  label_issue: Problem
-  label_issue_new: Novi problem
-  label_issue_plural: Problemi
-  label_issue_view_all: Prikaz svih problema
-  label_issues_by: "Problemi (%{value})"
-  label_issue_added: Problem je dodat
-  label_issue_updated: Problem je aÅ¾uriran
-  label_document: Dokument
-  label_document_new: Novi dokument
-  label_document_plural: Dokumenti
-  label_document_added: Dokument je dodat
-  label_role: Uloga
-  label_role_plural: Uloge
-  label_role_new: Nova uloga
-  label_role_and_permissions: Uloge i dozvole
-  label_member: ÄŒlan
-  label_member_new: Novi Älan
-  label_member_plural: ÄŒlanovi
-  label_tracker: PraÄ‡enje
-  label_tracker_plural: PraÄ‡enja
-  label_tracker_new: Novo praÄ‡enje
-  label_workflow: Tok posla
-  label_issue_status: Status problema
-  label_issue_status_plural: Statusi problema
-  label_issue_status_new: Novi status
-  label_issue_category: Kategorija problema
-  label_issue_category_plural: Kategorije problema
-  label_issue_category_new: Nova kategorija
-  label_custom_field: PrilagoÄ‘eno polje
-  label_custom_field_plural: PrilagoÄ‘ena polja
-  label_custom_field_new: Novo prilagoÄ‘eno polje
-  label_enumerations: Nabrojiva lista
-  label_enumeration_new: Nova vrednost
-  label_information: Informacija
-  label_information_plural: Informacije
-  label_please_login: Molimo, prijavite se
-  label_register: Registracija
-  label_login_with_open_id_option: ili prijava sa OpenID
-  label_password_lost: Izgubljena lozinka
-  label_home: PoÄetak
-  label_my_page: Moja stranica
-  label_my_account: Moj nalog
-  label_my_projects: Moji projekti
-  label_my_page_block: My page block
-  label_administration: Administracija
-  label_login: Prijava
-  label_logout: Odjava
-  label_help: PomoÄ‡
-  label_reported_issues: Prijavljeni problemi
-  label_assigned_to_me_issues: Problemi dodeljeni meni
-  label_last_login: Poslednje povezivanje
-  label_registered_on: Registrovan
-  label_activity: Aktivnost
-  label_overall_activity: Celokupna aktivnost
-  label_user_activity: "Aktivnost korisnika %{value}"
-  label_new: Novo
-  label_logged_as: Prijavljeni ste kao
-  label_environment: OkruÅ¾enje
-  label_authentication: Potvrda identiteta
-  label_auth_source: ReÅ¾im potvrde identiteta
-  label_auth_source_new: Novi reÅ¾im potvrde identiteta
-  label_auth_source_plural: ReÅ¾imi potvrde identiteta
-  label_subproject_plural: Potprojekti
-  label_subproject_new: Novi potprojekat
-  label_and_its_subprojects: "%{value} i njegovi potprojekti"
-  label_min_max_length: Min. - Maks. duÅ¾ina
-  label_list: Spisak
-  label_date: Datum
-  label_integer: Ceo broj
-  label_float: Sa pokretnim zarezom
-  label_boolean: LogiÄki operator
-  label_string: Tekst
-  label_text: Dugi tekst
-  label_attribute: Osobina
-  label_attribute_plural: Osobine
-  label_download: "%{count} preuzimanje"
-  label_download_plural: "%{count} preuzimanja"
-  label_no_data: Nema podataka za prikazivanje
-  label_change_status: Promena statusa
-  label_history: Istorija
-  label_attachment: Datoteka
-  label_attachment_new: Nova datoteka
-  label_attachment_delete: Brisanje datoteke
-  label_attachment_plural: Datoteke
-  label_file_added: Datoteka je dodata
-  label_report: IzveÅ¡taj
-  label_report_plural: IzveÅ¡taji
-  label_news: Vesti
-  label_news_new: Dodavanje vesti
-  label_news_plural: Vesti
-  label_news_latest: Poslednje vesti
-  label_news_view_all: Prikaz svih vesti
-  label_news_added: Vesti su dodate
-  label_settings: PodeÅ¡avanja
-  label_overview: Pregled
-  label_version: Verzija
-  label_version_new: Nova verzija
-  label_version_plural: Verzije
-  label_close_versions: Zatvori zavrÅ¡ene verzije
-  label_confirmation: Potvrda
-  label_export_to: 'TakoÄ‘e dostupno i u varijanti:'
-  label_read: ÄŒitanje...
-  label_public_projects: Javni projekti
-  label_open_issues: otvoren
-  label_open_issues_plural: otvorenih
-  label_closed_issues: zatvoren
-  label_closed_issues_plural: zatvorenih
-  label_x_open_issues_abbr_on_total:
-    zero:  0 otvorenih / %{total}
-    one:   1 otvoren / %{total}
-    other: "%{count} otvorenih / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 otvorenih
-    one:   1 otvoren
-    other: "%{count} otvorenih"
-  label_x_closed_issues_abbr:
-    zero:  0 zatvorenih
-    one:   1 zatvoren
-    other: "%{count} zatvorenih"
-  label_total: Ukupno
-  label_permissions: Dozvole
-  label_current_status: Trenutni status
-  label_new_statuses_allowed: Novi statusi dozvoljeni
-  label_all: svi
-  label_none: nijedan
-  label_nobody: nikome
-  label_next: SledeÄ‡e
-  label_previous: Prethodno
-  label_used_by: Koristio
-  label_details: Detalji
-  label_add_note: Dodaj beleÅ¡ku
-  label_per_page: Po strani
-  label_calendar: Kalendar
-  label_months_from: meseci od
-  label_gantt: Gantov dijagram
-  label_internal: UnutraÅ¡nji
-  label_last_changes: "poslednjih %{count} promena"
-  label_change_view_all: PrikaÅ¾i sve promene
-  label_personalize_page: Personalizuj ovu stranu
-  label_comment: Komentar
-  label_comment_plural: Komentari
-  label_x_comments:
-    zero: bez komentara
-    one: jedan komentar
-    other: "%{count} komentara"
-  label_comment_add: Dodaj komentar
-  label_comment_added: Komentar dodat
-  label_comment_delete: ObriÅ¡i komentare
-  label_query: PrilagoÄ‘en upit
-  label_query_plural: PrilagoÄ‘eni upiti
-  label_query_new: Novi upit
-  label_filter_add: Dodavanje filtera
-  label_filter_plural: Filteri
-  label_equals: je
-  label_not_equals: nije
-  label_in_less_than: manje od
-  label_in_more_than: viÅ¡e od
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: u
-  label_today: danas
-  label_all_time: sve vreme
-  label_yesterday: juÄe
-  label_this_week: ove sedmice
-  label_last_week: poslednje sedmice
-  label_last_n_days: "poslednjih %{count} dana"
-  label_this_month: ovog meseca
-  label_last_month: poslednjeg meseca
-  label_this_year: ove godine
-  label_date_range: Vremenski period
-  label_less_than_ago: pre manje od nekoliko dana
-  label_more_than_ago: pre viÅ¡e od nekoliko dana
-  label_ago: pre nekoliko dana
-  label_contains: sadrÅ¾i
-  label_not_contains: ne sadrÅ¾i
-  label_day_plural: dana
-  label_repository: SpremiÅ¡te
-  label_repository_plural: SpremiÅ¡ta
-  label_browse: Pregledanje
-  label_modification: "%{count} promena"
-  label_modification_plural: "%{count} promena"
-  label_branch: Grana
-  label_tag: Oznaka
-  label_revision: Revizija
-  label_revision_plural: Revizije
-  label_revision_id: "Revizija %{value}"
-  label_associated_revisions: PridruÅ¾ene revizije
-  label_added: dodato
-  label_modified: promenjeno
-  label_copied: kopirano
-  label_renamed: preimenovano
-  label_deleted: izbrisano
-  label_latest_revision: Poslednja revizija
-  label_latest_revision_plural: Poslednje revizije
-  label_view_revisions: Pregled revizija
-  label_view_all_revisions: Pregled svih revizija
-  label_max_size: Maksimalna veliÄina
-  label_sort_highest: PremeÅ¡tanje na vrh
-  label_sort_higher: PremeÅ¡tanje na gore
-  label_sort_lower: PremeÅ¡tanje na dole
-  label_sort_lowest: PremeÅ¡tanje na dno
-  label_roadmap: Plan rada
-  label_roadmap_due_in: "Dospeva %{value}"
-  label_roadmap_overdue: "%{value} najkasnije"
-  label_roadmap_no_issues: Nema problema za ovu verziju
-  label_search: Pretraga
-  label_result_plural: Rezultati
-  label_all_words: Sve reÄi
-  label_wiki: Wiki
-  label_wiki_edit: Wiki izmena
-  label_wiki_edit_plural: Wiki izmene
-  label_wiki_page: Wiki stranica
-  label_wiki_page_plural: Wiki stranice
-  label_index_by_title: Indeksiranje po naslovu
-  label_index_by_date: Indeksiranje po datumu
-  label_current_version: Trenutna verzija
-  label_preview: Pregled
-  label_feed_plural: Izvori vesti
-  label_changes_details: Detalji svih promena
-  label_issue_tracking: PraÄ‡enje problema
-  label_spent_time: UtroÅ¡eno vreme
-  label_overall_spent_time: Celokupno utroÅ¡eno vreme
-  label_f_hour: "%{value} sat"
-  label_f_hour_plural: "%{value} sati"
-  label_time_tracking: PraÄ‡enje vremena
-  label_change_plural: Promene
-  label_statistics: Statistika
-  label_commits_per_month: IzvrÅ¡enja meseÄno
-  label_commits_per_author: IzvrÅ¡enja po autoru
-  label_view_diff: Pogledaj razlike
-  label_diff_inline: unutra
-  label_diff_side_by_side: uporedo
-  label_options: Opcije
-  label_copy_workflow_from: Kopiranje toka posla od
-  label_permissions_report: IzveÅ¡taj o dozvolama
-  label_watched_issues: Posmatrani problemi
-  label_related_issues: Srodni problemi
-  label_applied_status: Primenjeni statusi
-  label_loading: UÄitavanje...
-  label_relation_new: Nova relacija
-  label_relation_delete: Brisanje relacije
-  label_relates_to: srodnih sa
-  label_duplicates: dupliranih
-  label_duplicated_by: dupliranih od
-  label_blocks: odbijenih
-  label_blocked_by: odbijenih od
-  label_precedes: prethodi
-  label_follows: praÄ‡enih
-  label_end_to_start: od kraja do poÄetka
-  label_end_to_end: od kraja do kraja
-  label_start_to_start: od poÄetka do poÄetka
-  label_start_to_end: od poÄetka do kraja
-  label_stay_logged_in: Ostanite prijavljeni
-  label_disabled: onemoguÄ‡eno
-  label_show_completed_versions: Prikazivanje zavrÅ¡ene verzije
-  label_me: meni
-  label_board: Forum
-  label_board_new: Novi forum
-  label_board_plural: Forumi
-  label_board_locked: ZakljuÄana
-  label_board_sticky: Lepljiva
-  label_topic_plural: Teme
-  label_message_plural: Poruke
-  label_message_last: Poslednja poruka
-  label_message_new: Nova poruka
-  label_message_posted: Poruka je dodata
-  label_reply_plural: Odgovori
-  label_send_information: PoÅ¡alji korisniku detalje naloga
-  label_year: Godina
-  label_month: Mesec
-  label_week: Sedmica
-  label_date_from: Å alje
-  label_date_to: Prima
-  label_language_based: Bazirano na jeziku korisnika
-  label_sort_by: "Sortirano po %{value}"
-  label_send_test_email: Slanje probne e-poruke
-  label_feeds_access_key: RSS pristupni kljuÄ
-  label_missing_feeds_access_key: RSS pristupni kljuÄ nedostaje
-  label_feeds_access_key_created_on: "RSS pristupni kljuÄ je napravljen pre %{value}"
-  label_module_plural: Moduli
-  label_added_time_by: "Dodao %{author} pre %{age}"
-  label_updated_time_by: "AÅ¾urirao %{author} pre %{age}"
-  label_updated_time: "AÅ¾urirano pre %{value}"
-  label_jump_to_a_project: Skok na projekat...
-  label_file_plural: Datoteke
-  label_changeset_plural: Skupovi promena
-  label_default_columns: Podrazumevane kolone
-  label_no_change_option: (Bez promena)
-  label_bulk_edit_selected_issues: Grupna izmena odabranih problema
-  label_theme: Tema
-  label_default: Podrazumevano
-  label_search_titles_only: PretraÅ¾uj samo naslove
-  label_user_mail_option_all: "Za bilo koji dogaÄ‘aj na svim mojim projektima"
-  label_user_mail_option_selected: "Za bilo koji dogaÄ‘aj na samo odabranim projektima..."
-  label_user_mail_no_self_notified: "Ne Å¾elim biti obaveÅ¡tavan za promene koje sam pravim"
-  label_registration_activation_by_email: aktivacija naloga putem e-poruke
-  label_registration_manual_activation: ruÄna aktivacija naloga
-  label_registration_automatic_activation: automatska aktivacija naloga
-  label_display_per_page: "Broj stavki po stranici: %{value}"
-  label_age: Starost
-  label_change_properties: Promeni svojstva
-  label_general: OpÅ¡ti
-  label_more: ViÅ¡e
-  label_scm: SCM
-  label_plugins: Dodatne komponente
-  label_ldap_authentication: LDAP potvrda identiteta
-  label_downloads_abbr: D/L
-  label_optional_description: Opciono opis
-  label_add_another_file: Dodaj joÅ¡ jednu datoteku
-  label_preferences: PodeÅ¡avanja
-  label_chronological_order: po hronoloÅ¡kom redosledu
-  label_reverse_chronological_order: po obrnutom hronoloÅ¡kom redosledu
-  label_planning: Planiranje
-  label_incoming_emails: Dolazne e-poruke
-  label_generate_key: Generisanje kljuÄa
-  label_issue_watchers: PosmatraÄi
-  label_example: Primer
-  label_display: Prikaz
-  label_sort: Sortiranje
-  label_ascending: RastuÄ‡i niz
-  label_descending: OpadajuÄ‡i niz
-  label_date_from_to: Od %{start} do %{end}
-  label_wiki_content_added: Wiki stranica je dodata
-  label_wiki_content_updated: Wiki stranica je aÅ¾urirana
-  label_group: Grupa
-  label_group_plural: Grupe
-  label_group_new: Nova grupa
-  label_time_entry_plural: UtroÅ¡eno vreme
-  label_version_sharing_none: Nije deljeno
-  label_version_sharing_descendants: Sa potprojektima
-  label_version_sharing_hierarchy: Sa hijerarhijom projekta
-  label_version_sharing_tree: Sa stablom projekta
-  label_version_sharing_system: Sa svim projektima
-  label_update_issue_done_ratios: AÅ¾uriraj odnos reÅ¡enih problema
-  label_copy_source: Izvor
-  label_copy_target: OdrediÅ¡te
-  label_copy_same_as_target: Isto kao odrediÅ¡te
-  label_display_used_statuses_only: Prikazuj statuse koriÅ¡Ä‡ene samo od strane ovog praÄ‡enja
-  label_api_access_key: API pristupni kljuÄ
-  label_missing_api_access_key: Nedostaje API pristupni kljuÄ
-  label_api_access_key_created_on: "API pristupni kljuÄ je kreiran pre %{value}"
-  label_profile: Profil
-  label_subtask_plural: Podzadatak
-  label_project_copy_notifications: PoÅ¡alji e-poruku sa obaveÅ¡tenjem prilikom kopiranja projekta 
-  
-  button_login: Prijava
-  button_submit: PoÅ¡alji
-  button_save: Snimi
-  button_check_all: UkljuÄi sve
-  button_uncheck_all: IskljuÄi sve
-  button_delete: IzbriÅ¡i
-  button_create: Kreiraj
-  button_create_and_continue: Kreiraj i nastavi
-  button_test: Test
-  button_edit: Izmeni
-  button_add: Dodaj
-  button_change: Promeni
-  button_apply: Primeni
-  button_clear: ObriÅ¡i
-  button_lock: ZakljuÄaj
-  button_unlock: OtkljuÄaj
-  button_download: Preuzmi
-  button_list: Spisak
-  button_view: PrikaÅ¾i
-  button_move: Pomeri
-  button_move_and_follow: Pomeri i prati
-  button_back: Nazad
-  button_cancel: PoniÅ¡ti
-  button_activate: Aktiviraj
-  button_sort: Sortiraj
-  button_log_time: Evidentiraj vreme
-  button_rollback: Povratak na ovu verziju
-  button_watch: Prati
-  button_unwatch: Ne prati viÅ¡e
-  button_reply: Odgovori
-  button_archive: Arhiviraj
-  button_unarchive: Vrati iz arhive
-  button_reset: PoniÅ¡ti
-  button_rename: Preimenuj
-  button_change_password: Promeni lozinku
-  button_copy: Kopiraj
-  button_copy_and_follow: Kopiraj i prati
-  button_annotate: PribeleÅ¾i
-  button_update: AÅ¾uriraj
-  button_configure: Podesi
-  button_quote: Pod navodnicima
-  button_duplicate: Dupliraj
-  button_show: PrikaÅ¾i
-  
-  status_active: aktivni
-  status_registered: registrovani
-  status_locked: zakljuÄani
-  
-  version_status_open: otvoren
-  version_status_locked: zakljuÄan
-  version_status_closed: zatvoren
-
-  field_active: Aktivan
-  
-  text_select_mail_notifications: Odaberi akcije za koje Ä‡e obaveÅ¡tenje biti poslato putem e-poÅ¡te.
-  text_regexp_info: npr. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 znaÄi bez ograniÄenja
-  text_project_destroy_confirmation: Jeste li sigurni da Å¾elite da izbriÅ¡ete ovaj projekat i sve pripadajuÄ‡e podatke?
-  text_subprojects_destroy_warning: "Potprojekti: %{value} Ä‡e takoÄ‘e biti izbrisan."
-  text_workflow_edit: Odaberite ulogu i praÄ‡enje za izmenu toka posla
-  text_are_you_sure: Jeste li sigurni?
-  text_journal_changed: "%{label} promenjen od %{old} u %{new}"
-  text_journal_set_to: "%{label} postavljen u %{value}"
-  text_journal_deleted: "%{label} izbrisano (%{old})"
-  text_journal_added: "%{label} %{value} dodato"
-  text_tip_issue_begin_day: zadatak poÄinje ovog dana
-  text_tip_issue_end_day: zadatak se zavrÅ¡ava ovog dana
-  text_tip_issue_begin_end_day: zadatak poÄinje i zavrÅ¡ava ovog dana
-  text_project_identifier_info: 'Dozvoljena su samo mala slova (a-Å¡), brojevi i crtice.<br />Jednom snimljen identifikator viÅ¡e se ne moÅ¾e promeniti.'
-  text_caracters_maximum: "NajviÅ¡e %{count} znak(ova)."
-  text_caracters_minimum: "Broj znakova mora biti najmanje %{count}."
-  text_length_between: "Broj znakova mora biti izmeÄ‘u %{min} i %{max}."
-  text_tracker_no_workflow: Ovo praÄ‡enje nema definisan tok posla
-  text_unallowed_characters: Nedozvoljeni znakovi
-  text_comma_separated: Dozvoljene su viÅ¡estruke vrednosti (odvojene zarezom).
-  text_line_separated: Dozvoljene su viÅ¡estruke vrednosti (jedan red za svaku vrednost).
-  text_issues_ref_in_commit_messages: Referenciranje i popravljanje problema u izvrÅ¡nim porukama
-  text_issue_added: "%{author} je prijavio problem %{id}."
-  text_issue_updated: "%{author} je aÅ¾urirao problem %{id}."
-  text_wiki_destroy_confirmation: Jeste li sigurni da Å¾elite da obriÅ¡ete wiki i sav sadrÅ¾aj?
-  text_issue_category_destroy_question: "Nekoliko problema (%{count}) je dodeljeno ovoj kategoriji. Å ta Å¾elite da uradite?"
-  text_issue_category_destroy_assignments: Ukloni dodeljene kategorije
-  text_issue_category_reassign_to: Dodeli ponovo probleme ovoj kategoriji
-  text_user_mail_option: "Za neizabrane projekte, dobiÄ‡ete samo obaveÅ¡tenje o stvarima koje pratite ili ste ukljuÄeni (npr. problemi Äiji ste vi autor ili zastupnik)."
-  text_no_configuration_data: "Uloge, praÄ‡enja, statusi problema i toka posla joÅ¡ uvek nisu podeÅ¡eni.\nPreporuÄljivo je da uÄitate podrazumevano konfigurisanje. Izmena je moguÄ‡a nakon prvog uÄitavanja."
-  text_load_default_configuration: UÄitaj podrazumevano konfigurisanje
-  text_status_changed_by_changeset: "Primenjeno u skupu sa promenama %{value}."
-  text_issues_destroy_confirmation: 'Jeste li sigurni da Å¾elite da izbriÅ¡ete odabrane probleme?'
-  text_select_project_modules: 'Odaberite module koje Å¾elite omoguÄ‡iti za ovaj projekat:'
-  text_default_administrator_account_changed: Podrazumevani administratorski nalog je promenjen
-  text_file_repository_writable: Fascikla priloÅ¾enih datoteka je upisiva
-  text_plugin_assets_writable: Fascikla elemenata dodatnih komponenti je upisiva
-  text_rmagick_available: RMagick je dostupan (opciono)
-  text_destroy_time_entries_question: "%{hours} sati je prijavljeno za ovaj problem koji Å¾elite izbrisati. Å ta Å¾elite da uradite?"
-  text_destroy_time_entries: IzbriÅ¡i prijavljene sate
-  text_assign_time_entries_to_project: Dodeli prijavljene sate projektu
-  text_reassign_time_entries: 'Dodeli ponovo prijavljene sate ovom problemu:'
-  text_user_wrote: "%{value} je napisao:"
-  text_enumeration_destroy_question: "%{count} objekat(a) je dodeljeno ovoj vrednosti."
-  text_enumeration_category_reassign_to: 'Dodeli ih ponovo ovoj vrednosti:'
-  text_email_delivery_not_configured: "Isporuka e-poruka nije konfigurisana i obaveÅ¡tenja su onemoguÄ‡ena.\nPodesite vaÅ¡ SMTP server u config/configuration.yml i pokrenite ponovo aplikaciju za njihovo omoguÄ‡avanje."
-  text_repository_usernames_mapping: "Odaberite ili aÅ¾urirajte Redmine korisnike mapiranjem svakog korisniÄkog imena pronaÄ‘enog u evidenciji spremiÅ¡ta.\nKorisnici sa istim Redmine imenom i imenom spremiÅ¡ta ili e-adresom su automatski mapirani."
-  text_diff_truncated: '... Ova razlika je iseÄena jer je dostignuta maksimalna veliÄina prikaza.'
-  text_custom_field_possible_values_info: 'Jedan red za svaku vrednost'
-  text_wiki_page_destroy_question: "Ova stranica ima %{descendants} podreÄ‘enih stranica i podstranica. Å ta Å¾elite da uradite?"
-  text_wiki_page_nullify_children: "ZadrÅ¾i podreÄ‘ene stranice kao korene stranice"
-  text_wiki_page_destroy_children: "IzbriÅ¡i podreÄ‘ene stranice i sve njihove podstranice"
-  text_wiki_page_reassign_children: "Dodeli ponovo podreÄ‘ene stranice ovoj matiÄnoj stranici"
-  text_own_membership_delete_confirmation: "Nakon uklanjanja pojedinih ili svih vaÅ¡ih dozvola neÄ‡ete viÅ¡e moÄ‡i da ureÄ‘ujete ovaj projekat.\nÅ½elite li da nastavite?"
-  text_zoom_in: UveÄ‡aj
-  text_zoom_out: Umanji
-  
-  default_role_manager: MenadÅ¾er
-  default_role_developer: Programer
-  default_role_reporter: IzveÅ¡taÄ
-  default_tracker_bug: GreÅ¡ka
-  default_tracker_feature: Funkcionalnost
-  default_tracker_support: PodrÅ¡ka
-  default_issue_status_new: Novo
-  default_issue_status_in_progress: U toku
-  default_issue_status_resolved: ReÅ¡eno
-  default_issue_status_feedback: Povratna informacija
-  default_issue_status_closed: Zatvoreno
-  default_issue_status_rejected: Odbijeno
-  default_doc_category_user: KorisniÄka dokumentacija
-  default_doc_category_tech: TehniÄka dokumentacija
-  default_priority_low: Nizak
-  default_priority_normal: Normalan
-  default_priority_high: Visok
-  default_priority_urgent: Hitno
-  default_priority_immediate: Neposredno
-  default_activity_design: Dizajn
-  default_activity_development: Razvoj
-  
-  enumeration_issue_priorities: Prioriteti problema
-  enumeration_doc_categories: Kategorije dokumenta
-  enumeration_activities: Aktivnosti (praÄ‡enje vremena)
-  enumeration_system_activity: Sistemska aktivnost
-  
-  field_time_entries: Vreme evidencije
-  project_module_gantt: Gantov dijagram
-  project_module_calendar: Kalendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Kodiranje izvrÅ¡nih poruka
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b8/b89d65b305414155d303b1421252bad2d311e25e.svn-base
--- a/.svn/pristine/b8/b89d65b305414155d303b1421252bad2d311e25e.svn-base
+++ /dev/null
@@ -1,427 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class RoutingTest < ActionController::IntegrationTest
-  context "activities" do
-    should_route :get, "/activity", :controller => 'activities', :action => 'index', :id => nil
-    should_route :get, "/activity.atom", :controller => 'activities', :action => 'index', :id => nil, :format => 'atom'
-  end
-
-  context "attachments" do
-    should_route :get, "/attachments/1", :controller => 'attachments', :action => 'show', :id => '1'
-    should_route :get, "/attachments/1.xml", :controller => 'attachments', :action => 'show', :id => '1', :format => 'xml'
-    should_route :get, "/attachments/1.json", :controller => 'attachments', :action => 'show', :id => '1', :format => 'json'
-    should_route :get, "/attachments/1/filename.ext", :controller => 'attachments', :action => 'show', :id => '1', :filename => 'filename.ext'
-    should_route :get, "/attachments/download/1", :controller => 'attachments', :action => 'download', :id => '1'
-    should_route :get, "/attachments/download/1/filename.ext", :controller => 'attachments', :action => 'download', :id => '1', :filename => 'filename.ext'
-  end
-
-  context "boards" do
-    should_route :get, "/projects/world_domination/boards", :controller => 'boards', :action => 'index', :project_id => 'world_domination'
-    should_route :get, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
-    should_route :get, "/projects/world_domination/boards/44", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44'
-    should_route :get, "/projects/world_domination/boards/44.atom", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44', :format => 'atom'
-    should_route :get, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
-
-    should_route :post, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
-    should_route :post, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
-    should_route :post, "/projects/world_domination/boards/44/destroy", :controller => 'boards', :action => 'destroy', :project_id => 'world_domination', :id => '44'
-
-  end
-
-  context "documents" do
-    should_route :get, "/projects/567/documents", :controller => 'documents', :action => 'index', :project_id => '567'
-    should_route :get, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
-    should_route :get, "/documents/22", :controller => 'documents', :action => 'show', :id => '22'
-    should_route :get, "/documents/22/edit", :controller => 'documents', :action => 'edit', :id => '22'
-
-    should_route :post, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
-    should_route :post, "/documents/567/edit", :controller => 'documents', :action => 'edit', :id => '567'
-    should_route :post, "/documents/567/destroy", :controller => 'documents', :action => 'destroy', :id => '567'
-  end
-  
-  context "groups" do
-    should_route :post,   "/groups/567/users", :controller => 'groups', :action => 'add_users', :id => '567'
-    should_route :delete, "/groups/567/users/12", :controller => 'groups', :action => 'remove_user', :id => '567', :user_id => '12'
-  end
-
-  context "issues" do
-    # REST actions
-    should_route :get, "/issues", :controller => 'issues', :action => 'index'
-    should_route :get, "/issues.pdf", :controller => 'issues', :action => 'index', :format => 'pdf'
-    should_route :get, "/issues.atom", :controller => 'issues', :action => 'index', :format => 'atom'
-    should_route :get, "/issues.xml", :controller => 'issues', :action => 'index', :format => 'xml'
-    should_route :get, "/projects/23/issues", :controller => 'issues', :action => 'index', :project_id => '23'
-    should_route :get, "/projects/23/issues.pdf", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'pdf'
-    should_route :get, "/projects/23/issues.atom", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'atom'
-    should_route :get, "/projects/23/issues.xml", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'xml'
-    should_route :get, "/issues/64", :controller => 'issues', :action => 'show', :id => '64'
-    should_route :get, "/issues/64.pdf", :controller => 'issues', :action => 'show', :id => '64', :format => 'pdf'
-    should_route :get, "/issues/64.atom", :controller => 'issues', :action => 'show', :id => '64', :format => 'atom'
-    should_route :get, "/issues/64.xml", :controller => 'issues', :action => 'show', :id => '64', :format => 'xml'
-
-    should_route :get, "/projects/23/issues/new", :controller => 'issues', :action => 'new', :project_id => '23'
-    should_route :post, "/projects/23/issues", :controller => 'issues', :action => 'create', :project_id => '23'
-    should_route :post, "/issues.xml", :controller => 'issues', :action => 'create', :format => 'xml'
-
-    should_route :get, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
-    # TODO: Should use PUT
-    should_route :post, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
-    should_route :put, "/issues/1.xml", :controller => 'issues', :action => 'update', :id => '1', :format => 'xml'
-
-    # TODO: Should use DELETE
-    should_route :post, "/issues/64/destroy", :controller => 'issues', :action => 'destroy', :id => '64'
-    should_route :delete, "/issues/1.xml", :controller => 'issues', :action => 'destroy', :id => '1', :format => 'xml'
-
-    # Extra actions
-    should_route :get, "/projects/23/issues/64/copy", :controller => 'issues', :action => 'new', :project_id => '23', :copy_from => '64'
-
-    should_route :get, "/issues/move/new", :controller => 'issue_moves', :action => 'new'
-    should_route :post, "/issues/move", :controller => 'issue_moves', :action => 'create'
-
-    should_route :post, "/issues/1/quoted", :controller => 'journals', :action => 'new', :id => '1'
-
-    should_route :get, "/issues/calendar", :controller => 'calendars', :action => 'show'
-    should_route :get, "/projects/project-name/issues/calendar", :controller => 'calendars', :action => 'show', :project_id => 'project-name'
-
-    should_route :get, "/issues/gantt", :controller => 'gantts', :action => 'show'
-    should_route :get, "/issues/gantt.pdf", :controller => 'gantts', :action => 'show', :format => 'pdf'
-    should_route :get, "/projects/project-name/issues/gantt", :controller => 'gantts', :action => 'show', :project_id => 'project-name'
-    should_route :get, "/projects/project-name/issues/gantt.pdf", :controller => 'gantts', :action => 'show', :project_id => 'project-name', :format => 'pdf'
-
-    should_route :get, "/issues/auto_complete", :controller => 'auto_completes', :action => 'issues'
-
-    should_route :get, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
-    should_route :post, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
-    should_route :get, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
-    should_route :post, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
-
-    should_route :get, "/issues/changes", :controller => 'journals', :action => 'index'
-
-    should_route :get, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_edit'
-    should_route :post, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_update'
-  end
-
-  context "issue categories" do
-    should_route :get, "/projects/foo/issue_categories", :controller => 'issue_categories', :action => 'index', :project_id => 'foo'
-    should_route :get, "/projects/foo/issue_categories.xml", :controller => 'issue_categories', :action => 'index', :project_id => 'foo', :format => 'xml'
-    should_route :get, "/projects/foo/issue_categories.json", :controller => 'issue_categories', :action => 'index', :project_id => 'foo', :format => 'json'
-
-    should_route :get, "/projects/foo/issue_categories/new", :controller => 'issue_categories', :action => 'new', :project_id => 'foo'
-
-    should_route :post, "/projects/foo/issue_categories", :controller => 'issue_categories', :action => 'create', :project_id => 'foo'
-    should_route :post, "/projects/foo/issue_categories.xml", :controller => 'issue_categories', :action => 'create', :project_id => 'foo', :format => 'xml'
-    should_route :post, "/projects/foo/issue_categories.json", :controller => 'issue_categories', :action => 'create', :project_id => 'foo', :format => 'json'
-
-    should_route :get, "/issue_categories/1", :controller => 'issue_categories', :action => 'show', :id => '1'
-    should_route :get, "/issue_categories/1.xml", :controller => 'issue_categories', :action => 'show', :id => '1', :format => 'xml'
-    should_route :get, "/issue_categories/1.json", :controller => 'issue_categories', :action => 'show', :id => '1', :format => 'json'
-
-    should_route :get, "/issue_categories/1/edit", :controller => 'issue_categories', :action => 'edit', :id => '1'
-
-    should_route :put, "/issue_categories/1", :controller => 'issue_categories', :action => 'update', :id => '1'
-    should_route :put, "/issue_categories/1.xml", :controller => 'issue_categories', :action => 'update', :id => '1', :format => 'xml'
-    should_route :put, "/issue_categories/1.json", :controller => 'issue_categories', :action => 'update', :id => '1', :format => 'json'
-
-    should_route :delete, "/issue_categories/1", :controller => 'issue_categories', :action => 'destroy', :id => '1'
-    should_route :delete, "/issue_categories/1.xml", :controller => 'issue_categories', :action => 'destroy', :id => '1', :format => 'xml'
-    should_route :delete, "/issue_categories/1.json", :controller => 'issue_categories', :action => 'destroy', :id => '1', :format => 'json'
-  end
-
-  context "issue relations" do
-    should_route :get, "/issues/1/relations", :controller => 'issue_relations', :action => 'index', :issue_id => '1'
-    should_route :get, "/issues/1/relations.xml", :controller => 'issue_relations', :action => 'index', :issue_id => '1', :format => 'xml'
-    should_route :get, "/issues/1/relations.json", :controller => 'issue_relations', :action => 'index', :issue_id => '1', :format => 'json'
-
-    should_route :post, "/issues/1/relations", :controller => 'issue_relations', :action => 'create', :issue_id => '1'
-    should_route :post, "/issues/1/relations.xml", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'xml'
-    should_route :post, "/issues/1/relations.json", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'json'
-
-    should_route :get, "/relations/23", :controller => 'issue_relations', :action => 'show', :id => '23'
-    should_route :get, "/relations/23.xml", :controller => 'issue_relations', :action => 'show', :id => '23', :format => 'xml'
-    should_route :get, "/relations/23.json", :controller => 'issue_relations', :action => 'show', :id => '23', :format => 'json'
-
-    should_route :delete, "/relations/23", :controller => 'issue_relations', :action => 'destroy', :id => '23'
-    should_route :delete, "/relations/23.xml", :controller => 'issue_relations', :action => 'destroy', :id => '23', :format => 'xml'
-    should_route :delete, "/relations/23.json", :controller => 'issue_relations', :action => 'destroy', :id => '23', :format => 'json'
-  end
-
-  context "issue reports" do
-    should_route :get, "/projects/567/issues/report", :controller => 'reports', :action => 'issue_report', :id => '567'
-    should_route :get, "/projects/567/issues/report/assigned_to", :controller => 'reports', :action => 'issue_report_details', :id => '567', :detail => 'assigned_to'
-  end
-
-  context "members" do
-    should_route :post, "/projects/5234/members/new", :controller => 'members', :action => 'new', :id => '5234'
-  end
-
-  context "messages" do
-    should_route :get, "/boards/22/topics/2", :controller => 'messages', :action => 'show', :id => '2', :board_id => '22'
-    should_route :get, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
-    should_route :get, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
-
-    should_route :post, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
-    should_route :post, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
-    should_route :post, "/boards/22/topics/555/replies", :controller => 'messages', :action => 'reply', :id => '555', :board_id => '22'
-    should_route :post, "/boards/22/topics/555/destroy", :controller => 'messages', :action => 'destroy', :id => '555', :board_id => '22'
-  end
-
-  context "news" do
-    should_route :get, "/news", :controller => 'news', :action => 'index'
-    should_route :get, "/news.atom", :controller => 'news', :action => 'index', :format => 'atom'
-    should_route :get, "/news.xml", :controller => 'news', :action => 'index', :format => 'xml'
-    should_route :get, "/news.json", :controller => 'news', :action => 'index', :format => 'json'
-    should_route :get, "/projects/567/news", :controller => 'news', :action => 'index', :project_id => '567'
-    should_route :get, "/projects/567/news.atom", :controller => 'news', :action => 'index', :format => 'atom', :project_id => '567'
-    should_route :get, "/projects/567/news.xml", :controller => 'news', :action => 'index', :format => 'xml', :project_id => '567'
-    should_route :get, "/projects/567/news.json", :controller => 'news', :action => 'index', :format => 'json', :project_id => '567'
-    should_route :get, "/news/2", :controller => 'news', :action => 'show', :id => '2'
-    should_route :get, "/projects/567/news/new", :controller => 'news', :action => 'new', :project_id => '567'
-    should_route :get, "/news/234", :controller => 'news', :action => 'show', :id => '234'
-    should_route :get, "/news/567/edit", :controller => 'news', :action => 'edit', :id => '567'
-    should_route :get, "/news/preview", :controller => 'previews', :action => 'news'
-
-    should_route :post, "/projects/567/news", :controller => 'news', :action => 'create', :project_id => '567'
-    should_route :post, "/news/567/comments", :controller => 'comments', :action => 'create', :id => '567'
-
-    should_route :put, "/news/567", :controller => 'news', :action => 'update', :id => '567'
-
-    should_route :delete, "/news/567", :controller => 'news', :action => 'destroy', :id => '567'
-    should_route :delete, "/news/567/comments/15", :controller => 'comments', :action => 'destroy', :id => '567', :comment_id => '15'
-  end
-
-  context "projects" do
-    should_route :get, "/projects", :controller => 'projects', :action => 'index'
-    should_route :get, "/projects.atom", :controller => 'projects', :action => 'index', :format => 'atom'
-    should_route :get, "/projects.xml", :controller => 'projects', :action => 'index', :format => 'xml'
-    should_route :get, "/projects/new", :controller => 'projects', :action => 'new'
-    should_route :get, "/projects/test", :controller => 'projects', :action => 'show', :id => 'test'
-    should_route :get, "/projects/1.xml", :controller => 'projects', :action => 'show', :id => '1', :format => 'xml'
-    should_route :get, "/projects/4223/settings", :controller => 'projects', :action => 'settings', :id => '4223'
-    should_route :get, "/projects/4223/settings/members", :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'
-    should_route :get, "/projects/33/files", :controller => 'files', :action => 'index', :project_id => '33'
-    should_route :get, "/projects/33/files/new", :controller => 'files', :action => 'new', :project_id => '33'
-    should_route :get, "/projects/33/roadmap", :controller => 'versions', :action => 'index', :project_id => '33'
-    should_route :get, "/projects/33/activity", :controller => 'activities', :action => 'index', :id => '33'
-    should_route :get, "/projects/33/activity.atom", :controller => 'activities', :action => 'index', :id => '33', :format => 'atom'
-
-    should_route :post, "/projects", :controller => 'projects', :action => 'create'
-    should_route :post, "/projects.xml", :controller => 'projects', :action => 'create', :format => 'xml'
-    should_route :post, "/projects/33/files", :controller => 'files', :action => 'create', :project_id => '33'
-    should_route :post, "/projects/64/archive", :controller => 'projects', :action => 'archive', :id => '64'
-    should_route :post, "/projects/64/unarchive", :controller => 'projects', :action => 'unarchive', :id => '64'
-
-    should_route :put, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'update', :project_id => '64'
-    should_route :put, "/projects/4223", :controller => 'projects', :action => 'update', :id => '4223'
-    should_route :put, "/projects/1.xml", :controller => 'projects', :action => 'update', :id => '1', :format => 'xml'
-
-    should_route :delete, "/projects/64", :controller => 'projects', :action => 'destroy', :id => '64'
-    should_route :delete, "/projects/1.xml", :controller => 'projects', :action => 'destroy', :id => '1', :format => 'xml'
-    should_route :delete, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'destroy', :project_id => '64'
-  end
-
-  context "queries" do
-    should_route :get, "/queries.xml", :controller => 'queries', :action => 'index', :format => 'xml'
-    should_route :get, "/queries.json", :controller => 'queries', :action => 'index', :format => 'json'
-
-    should_route :get, "/queries/new", :controller => 'queries', :action => 'new'
-    should_route :get, "/projects/redmine/queries/new", :controller => 'queries', :action => 'new', :project_id => 'redmine'
-
-    should_route :post, "/queries", :controller => 'queries', :action => 'create'
-    should_route :post, "/projects/redmine/queries", :controller => 'queries', :action => 'create', :project_id => 'redmine'
-
-    should_route :get, "/queries/1/edit", :controller => 'queries', :action => 'edit', :id => '1'
-
-    should_route :put, "/queries/1", :controller => 'queries', :action => 'update', :id => '1'
-
-    should_route :delete, "/queries/1", :controller => 'queries', :action => 'destroy', :id => '1'
-  end
-
-  context "repositories" do
-    should_route :get, "/projects/redmine/repository", :controller => 'repositories', :action => 'show', :id => 'redmine'
-    should_route :get, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
-    should_route :get, "/projects/redmine/repository/revisions", :controller => 'repositories', :action => 'revisions', :id => 'redmine'
-    should_route :get, "/projects/redmine/repository/revisions.atom", :controller => 'repositories', :action => 'revisions', :id => 'redmine', :format => 'atom'
-    should_route :get, "/projects/redmine/repository/revisions/2457", :controller => 'repositories', :action => 'revision', :id => 'redmine', :rev => '2457'
-    should_route :get, "/projects/redmine/repository/revisions/2457/diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457'
-    should_route :get, "/projects/redmine/repository/revisions/2457/diff.diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457', :format => 'diff'
-    should_route :get, "/projects/redmine/repository/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c]
-    should_route :get, "/projects/redmine/repository/revisions/2/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
-    should_route :get, "/projects/redmine/repository/browse/path/to/file.c", :controller => 'repositories', :action => 'browse', :id => 'redmine', :path => %w[path to file.c]
-    should_route :get, "/projects/redmine/repository/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c]
-    should_route :get, "/projects/redmine/repository/revisions/2/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
-    should_route :get, "/projects/redmine/repository/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :format => 'raw'
-    should_route :get, "/projects/redmine/repository/revisions/2/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2', :format => 'raw'
-    should_route :get, "/projects/redmine/repository/annotate/path/to/file.c", :controller => 'repositories', :action => 'annotate', :id => 'redmine', :path => %w[path to file.c]
-    should_route :get, "/projects/redmine/repository/changes/path/to/file.c", :controller => 'repositories', :action => 'changes', :id => 'redmine', :path => %w[path to file.c]
-    should_route :get, "/projects/redmine/repository/statistics", :controller => 'repositories', :action => 'stats', :id => 'redmine'
-
-    should_route :post, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
-  end
-
-  context "timelogs (global)" do
-    should_route :get, "/time_entries", :controller => 'timelog', :action => 'index'
-    should_route :get, "/time_entries.csv", :controller => 'timelog', :action => 'index', :format => 'csv'
-    should_route :get, "/time_entries.atom", :controller => 'timelog', :action => 'index', :format => 'atom'
-    should_route :get, "/time_entries/new", :controller => 'timelog', :action => 'new'
-    should_route :get, "/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22'
-
-    should_route :post, "/time_entries", :controller => 'timelog', :action => 'create'
-
-    should_route :put, "/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22'
-
-    should_route :delete, "/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55'
-  end
-
-  context "timelogs (scoped under project)" do
-    should_route :get, "/projects/567/time_entries", :controller => 'timelog', :action => 'index', :project_id => '567'
-    should_route :get, "/projects/567/time_entries.csv", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'csv'
-    should_route :get, "/projects/567/time_entries.atom", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'atom'
-    should_route :get, "/projects/567/time_entries/new", :controller => 'timelog', :action => 'new', :project_id => '567'
-    should_route :get, "/projects/567/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :project_id => '567'
-
-    should_route :post, "/projects/567/time_entries", :controller => 'timelog', :action => 'create', :project_id => '567'
-
-    should_route :put, "/projects/567/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :project_id => '567'
-
-    should_route :delete, "/projects/567/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :project_id => '567'
-  end
-
-  context "timelogs (scoped under issues)" do
-    should_route :get, "/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234'
-    should_route :get, "/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'csv'
-    should_route :get, "/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'atom'
-    should_route :get, "/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234'
-    should_route :get, "/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234'
-
-    should_route :post, "/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234'
-
-    should_route :put, "/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234'
-
-    should_route :delete, "/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234'
-  end
-
-  context "timelogs (scoped under project and issues)" do
-    should_route :get, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook'
-    should_route :get, "/projects/ecookbook/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'csv'
-    should_route :get, "/projects/ecookbook/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'atom'
-    should_route :get, "/projects/ecookbook/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234', :project_id => 'ecookbook'
-    should_route :get, "/projects/ecookbook/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
-
-    should_route :post, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234', :project_id => 'ecookbook'
-
-    should_route :put, "/projects/ecookbook/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
-
-    should_route :delete, "/projects/ecookbook/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234', :project_id => 'ecookbook'
-  end
-
-  context "time_entry_reports" do
-    should_route :get, "/time_entries/report", :controller => 'time_entry_reports', :action => 'report'
-    should_route :get, "/projects/567/time_entries/report", :controller => 'time_entry_reports', :action => 'report', :project_id => '567'
-    should_route :get, "/projects/567/time_entries/report.csv", :controller => 'time_entry_reports', :action => 'report', :project_id => '567', :format => 'csv'
-  end
-
-  context "users" do
-    should_route :get, "/users", :controller => 'users', :action => 'index'
-    should_route :get, "/users.xml", :controller => 'users', :action => 'index', :format => 'xml'
-    should_route :get, "/users/44", :controller => 'users', :action => 'show', :id => '44'
-    should_route :get, "/users/44.xml", :controller => 'users', :action => 'show', :id => '44', :format => 'xml'
-    should_route :get, "/users/current", :controller => 'users', :action => 'show', :id => 'current'
-    should_route :get, "/users/current.xml", :controller => 'users', :action => 'show', :id => 'current', :format => 'xml'
-    should_route :get, "/users/new", :controller => 'users', :action => 'new'
-    should_route :get, "/users/444/edit", :controller => 'users', :action => 'edit', :id => '444'
-    should_route :get, "/users/222/edit/membership", :controller => 'users', :action => 'edit', :id => '222', :tab => 'membership'
-
-    should_route :post, "/users", :controller => 'users', :action => 'create'
-    should_route :post, "/users.xml", :controller => 'users', :action => 'create', :format => 'xml'
-    should_route :post, "/users/123/memberships", :controller => 'users', :action => 'edit_membership', :id => '123'
-    should_route :post, "/users/123/memberships/55", :controller => 'users', :action => 'edit_membership', :id => '123', :membership_id => '55'
-    should_route :post, "/users/567/memberships/12/destroy", :controller => 'users', :action => 'destroy_membership', :id => '567', :membership_id => '12'
-
-    should_route :put, "/users/444", :controller => 'users', :action => 'update', :id => '444'
-    should_route :put, "/users/444.xml", :controller => 'users', :action => 'update', :id => '444', :format => 'xml'
-
-    should_route :delete, "/users/44", :controller => 'users', :action => 'destroy', :id => '44'
-    should_route :delete, "/users/44.xml", :controller => 'users', :action => 'destroy', :id => '44', :format => 'xml'
-  end
-
-  context "versions" do
-    # /projects/foo/versions is /projects/foo/roadmap
-    should_route :get, "/projects/foo/versions.xml", :controller => 'versions', :action => 'index', :project_id => 'foo', :format => 'xml'
-    should_route :get, "/projects/foo/versions.json", :controller => 'versions', :action => 'index', :project_id => 'foo', :format => 'json'
-
-    should_route :get, "/projects/foo/versions/new", :controller => 'versions', :action => 'new', :project_id => 'foo'
-
-    should_route :post, "/projects/foo/versions", :controller => 'versions', :action => 'create', :project_id => 'foo'
-    should_route :post, "/projects/foo/versions.xml", :controller => 'versions', :action => 'create', :project_id => 'foo', :format => 'xml'
-    should_route :post, "/projects/foo/versions.json", :controller => 'versions', :action => 'create', :project_id => 'foo', :format => 'json'
-
-    should_route :get, "/versions/1", :controller => 'versions', :action => 'show', :id => '1'
-    should_route :get, "/versions/1.xml", :controller => 'versions', :action => 'show', :id => '1', :format => 'xml'
-    should_route :get, "/versions/1.json", :controller => 'versions', :action => 'show', :id => '1', :format => 'json'
-
-    should_route :get, "/versions/1/edit", :controller => 'versions', :action => 'edit', :id => '1'
-
-    should_route :put, "/versions/1", :controller => 'versions', :action => 'update', :id => '1'
-    should_route :put, "/versions/1.xml", :controller => 'versions', :action => 'update', :id => '1', :format => 'xml'
-    should_route :put, "/versions/1.json", :controller => 'versions', :action => 'update', :id => '1', :format => 'json'
-
-    should_route :delete, "/versions/1", :controller => 'versions', :action => 'destroy', :id => '1'
-    should_route :delete, "/versions/1.xml", :controller => 'versions', :action => 'destroy', :id => '1', :format => 'xml'
-    should_route :delete, "/versions/1.json", :controller => 'versions', :action => 'destroy', :id => '1', :format => 'json'
-
-    should_route :put, "/projects/foo/versions/close_completed", :controller => 'versions', :action => 'close_completed', :project_id => 'foo'
-    should_route :post, "/versions/1/status_by", :controller => 'versions', :action => 'status_by', :id => '1'
-  end
-
-  context "wiki (singular, project's pages)" do
-    should_route :get, "/projects/567/wiki", :controller => 'wiki', :action => 'show', :project_id => '567'
-    should_route :get, "/projects/567/wiki/lalala", :controller => 'wiki', :action => 'show', :project_id => '567', :id => 'lalala'
-    should_route :get, "/projects/567/wiki/my_page/edit", :controller => 'wiki', :action => 'edit', :project_id => '567', :id => 'my_page'
-    should_route :get, "/projects/1/wiki/CookBook_documentation/history", :controller => 'wiki', :action => 'history', :project_id => '1', :id => 'CookBook_documentation'
-    should_route :get, "/projects/1/wiki/CookBook_documentation/diff", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation'
-    should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
-    should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2/vs/1", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2', :version_from => '1'
-    should_route :get, "/projects/1/wiki/CookBook_documentation/annotate/2", :controller => 'wiki', :action => 'annotate', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
-    should_route :get, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
-    should_route :get, "/projects/567/wiki/index", :controller => 'wiki', :action => 'index', :project_id => '567'
-    should_route :get, "/projects/567/wiki/date_index", :controller => 'wiki', :action => 'date_index', :project_id => '567'
-    should_route :get, "/projects/567/wiki/export", :controller => 'wiki', :action => 'export', :project_id => '567'
-
-    should_route :post, "/projects/567/wiki/CookBook_documentation/preview", :controller => 'wiki', :action => 'preview', :project_id => '567', :id => 'CookBook_documentation'
-    should_route :post, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
-    should_route :post, "/projects/22/wiki/ladida/protect", :controller => 'wiki', :action => 'protect', :project_id => '22', :id => 'ladida'
-    should_route :post, "/projects/22/wiki/ladida/add_attachment", :controller => 'wiki', :action => 'add_attachment', :project_id => '22', :id => 'ladida'
-
-    should_route :put, "/projects/567/wiki/my_page", :controller => 'wiki', :action => 'update', :project_id => '567', :id => 'my_page'
-
-    should_route :delete, "/projects/22/wiki/ladida", :controller => 'wiki', :action => 'destroy', :project_id => '22', :id => 'ladida'
-  end
-
-  context "wikis (plural, admin setup)" do
-    should_route :get, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
-
-    should_route :post, "/projects/ladida/wiki", :controller => 'wikis', :action => 'edit', :id => 'ladida'
-    should_route :post, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
-  end
-
-  context "administration panel" do
-    should_route :get, "/admin/projects", :controller => 'admin', :action => 'projects'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b8/b8a1965fd8f5780ffc827ed99a393772297ea734.svn-base
--- a/.svn/pristine/b8/b8a1965fd8f5780ffc827ed99a393772297ea734.svn-base
+++ /dev/null
@@ -1,95 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class ActivityTest < ActiveSupport::TestCase
-  fixtures :projects, :versions, :attachments, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
-           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages
-
-  def setup
-    @project = Project.find(1)
-  end
-
-  def test_activity_without_subprojects
-    events = find_events(User.anonymous, :project => @project)
-    assert_not_nil events
-
-    assert events.include?(Issue.find(1))
-    assert !events.include?(Issue.find(4))
-    # subproject issue
-    assert !events.include?(Issue.find(5))
-  end
-
-  def test_activity_with_subprojects
-    events = find_events(User.anonymous, :project => @project, :with_subprojects => 1)
-    assert_not_nil events
-
-    assert events.include?(Issue.find(1))
-    # subproject issue
-    assert events.include?(Issue.find(5))
-  end
-
-  def test_global_activity_anonymous
-    events = find_events(User.anonymous)
-    assert_not_nil events
-
-    assert events.include?(Issue.find(1))
-    assert events.include?(Message.find(5))
-    # Issue of a private project
-    assert !events.include?(Issue.find(4))
-    # Private issue and comment
-    assert !events.include?(Issue.find(14))
-    assert !events.include?(Journal.find(5))
-  end
-
-  def test_global_activity_logged_user
-    events = find_events(User.find(2)) # manager
-    assert_not_nil events
-
-    assert events.include?(Issue.find(1))
-    # Issue of a private project the user belongs to
-    assert events.include?(Issue.find(4))
-  end
-
-  def test_user_activity
-    user = User.find(2)
-    events = Redmine::Activity::Fetcher.new(User.anonymous, :author => user).events(nil, nil, :limit => 10)
-
-    assert(events.size > 0)
-    assert(events.size <= 10)
-    assert_nil(events.detect {|e| e.event_author != user})
-  end
-
-  def test_files_activity
-    f = Redmine::Activity::Fetcher.new(User.anonymous, :project => Project.find(1))
-    f.scope = ['files']
-    events = f.events
-
-    assert_kind_of Array, events
-    assert events.include?(Attachment.find_by_container_type_and_container_id('Project', 1))
-    assert events.include?(Attachment.find_by_container_type_and_container_id('Version', 1))
-    assert_equal [Attachment], events.collect(&:class).uniq
-    assert_equal %w(Project Version), events.collect(&:container_type).uniq.sort
-  end
-
-  private
-
-  def find_events(user, options={})
-    Redmine::Activity::Fetcher.new(user, options).events(Date.today - 30, Date.today + 1)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b8/b8c4a4f62502265603b5dac16f30aca8838956d0.svn-base
--- /dev/null
+++ b/.svn/pristine/b8/b8c4a4f62502265603b5dac16f30aca8838956d0.svn-base
@@ -0,0 +1,341 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/abstract_adapter'
+require 'cgi'
+
+module Redmine
+  module Scm
+    module Adapters
+      class MercurialAdapter < AbstractAdapter
+
+        # Mercurial executable name
+        HG_BIN = Redmine::Configuration['scm_mercurial_command'] || "hg"
+        HELPERS_DIR = File.dirname(__FILE__) + "/mercurial"
+        HG_HELPER_EXT = "#{HELPERS_DIR}/redminehelper.py"
+        TEMPLATE_NAME = "hg-template"
+        TEMPLATE_EXTENSION = "tmpl"
+
+        # raised if hg command exited with error, e.g. unknown revision.
+        class HgCommandAborted < CommandFailed; end
+
+        class << self
+          def client_command
+            @@bin    ||= HG_BIN
+          end
+
+          def sq_bin
+            @@sq_bin ||= shell_quote_command
+          end
+
+          def client_version
+            @@client_version ||= (hgversion || [])
+          end
+
+          def client_available
+            client_version_above?([1, 2])
+          end
+
+          def hgversion
+            # The hg version is expressed either as a
+            # release number (eg 0.9.5 or 1.0) or as a revision
+            # id composed of 12 hexa characters.
+            theversion = hgversion_from_command_line.dup
+            if theversion.respond_to?(:force_encoding)
+              theversion.force_encoding('ASCII-8BIT')
+            end
+            if m = theversion.match(%r{\A(.*?)((\d+\.)+\d+)})
+              m[2].scan(%r{\d+}).collect(&:to_i)
+            end
+          end
+
+          def hgversion_from_command_line
+            shellout("#{sq_bin} --version") { |io| io.read }.to_s
+          end
+
+          def template_path
+            @@template_path ||= template_path_for(client_version)
+          end
+
+          def template_path_for(version)
+            "#{HELPERS_DIR}/#{TEMPLATE_NAME}-1.0.#{TEMPLATE_EXTENSION}"
+          end
+        end
+
+        def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil)
+          super
+          @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
+        end
+
+        def path_encoding
+          @path_encoding
+        end
+
+        def info
+          tip = summary['repository']['tip']
+          Info.new(:root_url => CGI.unescape(summary['repository']['root']),
+                   :lastrev => Revision.new(:revision => tip['revision'],
+                                            :scmid => tip['node']))
+        # rescue HgCommandAborted
+        rescue Exception => e
+          logger.error "hg: error during getting info: #{e.message}"
+          nil
+        end
+
+        def tags
+          as_ary(summary['repository']['tag']).map { |e| e['name'] }
+        end
+
+        # Returns map of {'tag' => 'nodeid', ...}
+        def tagmap
+          alist = as_ary(summary['repository']['tag']).map do |e|
+            e.values_at('name', 'node')
+          end
+          Hash[*alist.flatten]
+        end
+
+        def branches
+          brs = []
+          as_ary(summary['repository']['branch']).each do |e|
+            br = Branch.new(e['name'])
+            br.revision =  e['revision']
+            br.scmid    =  e['node']
+            brs << br
+          end
+          brs
+        end
+
+        # Returns map of {'branch' => 'nodeid', ...}
+        def branchmap
+          alist = as_ary(summary['repository']['branch']).map do |e|
+            e.values_at('name', 'node')
+          end
+          Hash[*alist.flatten]
+        end
+
+        def summary
+          return @summary if @summary
+          hg 'rhsummary' do |io|
+            output = io.read
+            if output.respond_to?(:force_encoding)
+              output.force_encoding('UTF-8')
+            end
+            begin
+              @summary = parse_xml(output)['rhsummary']
+            rescue
+            end
+          end
+        end
+        private :summary
+
+        def entries(path=nil, identifier=nil, options={})
+          p1 = scm_iconv(@path_encoding, 'UTF-8', path)
+          manifest = hg('rhmanifest', '-r', CGI.escape(hgrev(identifier)),
+                        CGI.escape(without_leading_slash(p1.to_s))) do |io|
+            output = io.read
+            if output.respond_to?(:force_encoding)
+              output.force_encoding('UTF-8')
+            end
+            begin
+              parse_xml(output)['rhmanifest']['repository']['manifest']
+            rescue
+            end
+          end
+          path_prefix = path.blank? ? '' : with_trailling_slash(path)
+
+          entries = Entries.new
+          as_ary(manifest['dir']).each do |e|
+            n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name']))
+            p = "#{path_prefix}#{n}"
+            entries << Entry.new(:name => n, :path => p, :kind => 'dir')
+          end
+
+          as_ary(manifest['file']).each do |e|
+            n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name']))
+            p = "#{path_prefix}#{n}"
+            lr = Revision.new(:revision => e['revision'], :scmid => e['node'],
+                              :identifier => e['node'],
+                              :time => Time.at(e['time'].to_i))
+            entries << Entry.new(:name => n, :path => p, :kind => 'file',
+                                 :size => e['size'].to_i, :lastrev => lr)
+          end
+
+          entries
+        rescue HgCommandAborted
+          nil  # means not found
+        end
+
+        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
+          revs = Revisions.new
+          each_revision(path, identifier_from, identifier_to, options) { |e| revs << e }
+          revs
+        end
+
+        # Iterates the revisions by using a template file that
+        # makes Mercurial produce a xml output.
+        def each_revision(path=nil, identifier_from=nil, identifier_to=nil, options={})
+          hg_args = ['log', '--debug', '-C', '--style', self.class.template_path]
+          hg_args << '-r' << "#{hgrev(identifier_from)}:#{hgrev(identifier_to)}"
+          hg_args << '--limit' << options[:limit] if options[:limit]
+          hg_args << hgtarget(path) unless path.blank?
+          log = hg(*hg_args) do |io|
+            output = io.read
+            if output.respond_to?(:force_encoding)
+              output.force_encoding('UTF-8')
+            end
+            begin
+              # Mercurial < 1.5 does not support footer template for '</log>'
+              parse_xml("#{output}</log>")['log']
+            rescue
+            end
+          end
+          as_ary(log['logentry']).each do |le|
+            cpalist = as_ary(le['paths']['path-copied']).map do |e|
+              [e['__content__'], e['copyfrom-path']].map do |s|
+                scm_iconv('UTF-8', @path_encoding, CGI.unescape(s))
+              end
+            end
+            cpmap = Hash[*cpalist.flatten]
+            paths = as_ary(le['paths']['path']).map do |e|
+              p = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['__content__']) )
+              {:action        => e['action'],
+               :path          => with_leading_slash(p),
+               :from_path     => (cpmap.member?(p) ? with_leading_slash(cpmap[p]) : nil),
+               :from_revision => (cpmap.member?(p) ? le['node'] : nil)}
+            end.sort { |a, b| a[:path] <=> b[:path] }
+            parents_ary = []
+            as_ary(le['parents']['parent']).map do |par|
+              parents_ary << par['__content__'] if par['__content__'] != "000000000000"
+            end
+            yield Revision.new(:revision => le['revision'],
+                               :scmid    => le['node'],
+                               :author   => (le['author']['__content__'] rescue ''),
+                               :time     => Time.parse(le['date']['__content__']),
+                               :message  => le['msg']['__content__'],
+                               :paths    => paths,
+                               :parents  => parents_ary)
+          end
+          self
+        end
+
+        # Returns list of nodes in the specified branch
+        def nodes_in_branch(branch, options={})
+          hg_args = ['rhlog', '--template', '{node|short}\n', '--rhbranch', CGI.escape(branch)]
+          hg_args << '--from' << CGI.escape(branch)
+          hg_args << '--to'   << '0'
+          hg_args << '--limit' << options[:limit] if options[:limit]
+          hg(*hg_args) { |io| io.readlines.map { |e| e.chomp } }
+        end
+
+        def diff(path, identifier_from, identifier_to=nil)
+          hg_args = %w|rhdiff|
+          if identifier_to
+            hg_args << '-r' << hgrev(identifier_to) << '-r' << hgrev(identifier_from)
+          else
+            hg_args << '-c' << hgrev(identifier_from)
+          end
+          unless path.blank?
+            p = scm_iconv(@path_encoding, 'UTF-8', path)
+            hg_args << CGI.escape(hgtarget(p))
+          end
+          diff = []
+          hg *hg_args do |io|
+            io.each_line do |line|
+              diff << line
+            end
+          end
+          diff
+        rescue HgCommandAborted
+          nil  # means not found
+        end
+
+        def cat(path, identifier=nil)
+          p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path))
+          hg 'rhcat', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io|
+            io.binmode
+            io.read
+          end
+        rescue HgCommandAborted
+          nil  # means not found
+        end
+
+        def annotate(path, identifier=nil)
+          p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path))
+          blame = Annotate.new
+          hg 'rhannotate', '-ncu', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io|
+            io.each_line do |line|
+              line.force_encoding('ASCII-8BIT') if line.respond_to?(:force_encoding)
+              next unless line =~ %r{^([^:]+)\s(\d+)\s([0-9a-f]+):\s(.*)$}
+              r = Revision.new(:author => $1.strip, :revision => $2, :scmid => $3,
+                               :identifier => $3)
+              blame.add_line($4.rstrip, r)
+            end
+          end
+          blame
+        rescue HgCommandAborted
+          # means not found or cannot be annotated
+          Annotate.new
+        end
+
+        class Revision < Redmine::Scm::Adapters::Revision
+          # Returns the readable identifier
+          def format_identifier
+            "#{revision}:#{scmid}"
+          end
+        end
+
+        # Runs 'hg' command with the given args
+        def hg(*args, &block)
+          repo_path = root_url || url
+          full_args = ['-R', repo_path, '--encoding', 'utf-8']
+          full_args << '--config' << "extensions.redminehelper=#{HG_HELPER_EXT}"
+          full_args << '--config' << 'diff.git=false'
+          full_args += args
+          ret = shellout(
+                   self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
+                   &block
+                   )
+          if $? && $?.exitstatus != 0
+            raise HgCommandAborted, "hg exited with non-zero status: #{$?.exitstatus}"
+          end
+          ret
+        end
+        private :hg
+
+        # Returns correct revision identifier
+        def hgrev(identifier, sq=false)
+          rev = identifier.blank? ? 'tip' : identifier.to_s
+          rev = shell_quote(rev) if sq
+          rev
+        end
+        private :hgrev
+
+        def hgtarget(path)
+          path ||= ''
+          root_url + '/' + without_leading_slash(path)
+        end
+        private :hgtarget
+
+        def as_ary(o)
+          return [] unless o
+          o.is_a?(Array) ? o : Array[o]
+        end
+        private :as_ary
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b9/b90cd149441f836cbc1e4f50f6a53eb280e646a6.svn-base
--- /dev/null
+++ b/.svn/pristine/b9/b90cd149441f836cbc1e4f50f6a53eb280e646a6.svn-base
@@ -0,0 +1,49 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine #:nodoc:
+  module CoreExtensions #:nodoc:
+    module String #:nodoc:
+      # Custom string conversions
+      module Conversions
+        # Parses hours format and returns a float
+        def to_hours
+          s = self.dup
+          s.strip!
+          if s =~ %r{^(\d+([.,]\d+)?)h?$}
+            s = $1
+          else
+            # 2:30 => 2.5
+            s.gsub!(%r{^(\d+):(\d+)$}) { $1.to_i + $2.to_i / 60.0 }
+            # 2h30, 2h, 30m => 2.5, 2, 0.5
+            s.gsub!(%r{^((\d+)\s*(h|hours?))?\s*((\d+)\s*(m|min)?)?$}i) { |m| ($1 || $4) ? ($2.to_i + $5.to_i / 60.0) : m[0] }
+          end
+          # 2,5 => 2.5
+          s.gsub!(',', '.')
+          begin; Kernel.Float(s); rescue; nil; end
+        end
+
+        # Object#to_a removed in ruby1.9
+        if RUBY_VERSION > '1.9'
+          def to_a
+            [self.dup]
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b9/b90f665732cea00de6a43cb9e0e055b111dd8028.svn-base
--- a/.svn/pristine/b9/b90f665732cea00de6a43cb9e0e055b111dd8028.svn-base
+++ /dev/null
@@ -1,103 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Ciphering
-    def self.included(base)
-      base.extend ClassMethods
-    end
-
-    class << self
-      def encrypt_text(text)
-        if cipher_key.blank? || text.blank?
-          text
-        else
-          c = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
-          iv = c.random_iv
-          c.encrypt
-          c.key = cipher_key
-          c.iv = iv
-          e = c.update(text.to_s)
-          e << c.final
-          "aes-256-cbc:" + [e, iv].map {|v| Base64.encode64(v).strip}.join('--')
-        end
-      end
-
-      def decrypt_text(text)
-        if text && match = text.match(/\Aaes-256-cbc:(.+)\Z/)
-          if cipher_key.blank?
-            logger.error "Attempt to decrypt a ciphered text with no cipher key configured in config/configuration.yml" if logger
-            return text
-          end
-          text = match[1]
-          c = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
-          e, iv = text.split("--").map {|s| Base64.decode64(s)}
-          c.decrypt
-          c.key = cipher_key
-          c.iv = iv
-          d = c.update(e)
-          d << c.final
-        else
-          text
-        end
-      end
-
-      def cipher_key
-        key = Redmine::Configuration['database_cipher_key'].to_s
-        key.blank? ? nil : Digest::SHA256.hexdigest(key)
-      end
-      
-      def logger
-        Rails.logger
-      end
-    end
-
-    module ClassMethods
-      def encrypt_all(attribute)
-        transaction do
-          all.each do |object|
-            clear = object.send(attribute)
-            object.send "#{attribute}=", clear
-            raise(ActiveRecord::Rollback) unless object.save(false)
-          end
-        end ? true : false
-      end
-
-      def decrypt_all(attribute)
-        transaction do
-          all.each do |object|
-            clear = object.send(attribute)
-            object.write_attribute attribute, clear
-            raise(ActiveRecord::Rollback) unless object.save(false)
-          end
-        end
-      end ? true : false
-    end
-
-    private
-
-    # Returns the value of the given ciphered attribute
-    def read_ciphered_attribute(attribute)
-      Redmine::Ciphering.decrypt_text(read_attribute(attribute))
-    end
-
-    # Sets the value of the given ciphered attribute
-    def write_ciphered_attribute(attribute, value)
-      write_attribute(attribute, Redmine::Ciphering.encrypt_text(value))
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b9/b9350cafa5fd1809b5fffbaee5fa651925ff007b.svn-base
--- /dev/null
+++ b/.svn/pristine/b9/b9350cafa5fd1809b5fffbaee5fa651925ff007b.svn-base
@@ -0,0 +1,63 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+require 'capybara/rails'
+
+Capybara.default_driver = :selenium
+Capybara.register_driver :selenium do |app|
+  # Use the following driver definition to test locally using Chrome (also requires chromedriver to be in PATH)
+  # Capybara::Selenium::Driver.new(app, :browser => :chrome)
+  # Add :switches => %w[--lang=en] to force default browser locale to English
+  # Default for Selenium remote driver is to connect to local host on port 4444 
+  # This can be change using :url => 'http://localhost:9195' if necessary
+  # PhantomJS 1.8 now directly supports Webdriver Wire API, simply run it with `phantomjs --webdriver 4444`
+  # Add :desired_capabilities => Selenium::WebDriver::Remote::Capabilities.internet_explorer) to run on Selenium Grid Hub with IE
+  Capybara::Selenium::Driver.new(app, :browser => :remote)
+end
+
+module Redmine
+  module UiTest
+    # Base class for UI tests
+    class Base < ActionDispatch::IntegrationTest
+      include Capybara::DSL
+
+      # Stop ActiveRecord from wrapping tests in transactions
+      # Transactional fixtures do not work with Selenium tests, because Capybara
+      # uses a separate server thread, which the transactions would be hidden
+      self.use_transactional_fixtures = false
+
+      # Should not depend on locale since Redmine displays login page
+      # using default browser locale which depend on system locale for "real" browsers drivers
+      def log_user(login, password)
+        visit '/my/page'
+        assert_equal '/login', current_path
+        within('#login-form form') do
+          fill_in 'username', :with => login
+          fill_in 'password', :with => password
+          find('input[name=login]').click
+        end
+        assert_equal '/my/page', current_path
+      end
+
+      teardown do
+        Capybara.reset_sessions!    # Forget the (simulated) browser state
+        Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b9/b94e9d09ba0ad12320000d9bdc7207a4e6a55736.svn-base
--- /dev/null
+++ b/.svn/pristine/b9/b94e9d09ba0ad12320000d9bdc7207a4e6a55736.svn-base
@@ -0,0 +1,34 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::MenuManagerTest < ActiveSupport::TestCase
+  def test_map_should_yield_a_mapper
+    assert_difference 'Redmine::MenuManager.items(:project_menu).size' do
+      Redmine::MenuManager.map :project_menu do |mapper|
+        assert_kind_of  Redmine::MenuManager::Mapper, mapper
+        mapper.push :new_item, '/'
+      end
+    end
+  end
+
+  def test_items_should_return_menu_items
+    items = Redmine::MenuManager.items(:project_menu)
+    assert_kind_of Redmine::MenuManager::MenuNode, items.first
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b9/b982f3bb626cbc93a53ddb7f7ab16811202b4d33.svn-base
--- a/.svn/pristine/b9/b982f3bb626cbc93a53ddb7f7ab16811202b4d33.svn-base
+++ /dev/null
@@ -1,58 +0,0 @@
-module CodeRay
-module Encoders
-  
-  # A Filter encoder has another Tokens instance as output.
-  # It can be subclass to select, remove, or modify tokens in the stream.
-  # 
-  # Subclasses of Filter are called "Filters" and can be chained.
-  # 
-  # == Options
-  # 
-  # === :tokens
-  # 
-  # The Tokens object which will receive the output.
-  # 
-  # Default: Tokens.new
-  # 
-  # See also: TokenKindFilter
-  class Filter < Encoder
-    
-    register_for :filter
-    
-  protected
-    def setup options
-      super
-      
-      @tokens = options[:tokens] || Tokens.new
-    end
-    
-    def finish options
-      output @tokens
-    end
-    
-  public
-    
-    def text_token text, kind  # :nodoc:
-      @tokens.text_token text, kind
-    end
-    
-    def begin_group kind  # :nodoc:
-      @tokens.begin_group kind
-    end
-    
-    def begin_line kind  # :nodoc:
-      @tokens.begin_line kind
-    end
-    
-    def end_group kind  # :nodoc:
-      @tokens.end_group kind
-    end
-    
-    def end_line kind  # :nodoc:
-      @tokens.end_line kind
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b9/b9b369ba62511c0ebd06b8be1740859029f63b82.svn-base
--- a/.svn/pristine/b9/b9b369ba62511c0ebd06b8be1740859029f63b82.svn-base
+++ /dev/null
@@ -1,4 +0,0 @@
-<%= l(:text_issue_added, :id => "##{@issue.id}", :author => @issue.author) %>
-
-----------------------------------------
-<%= render :partial => "issue.text.erb", :locals => { :issue => @issue, :issue_url => @issue_url } %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b9/b9c49fb69739cb0669c7aaa7fd8210822f5d8d67.svn-base
--- a/.svn/pristine/b9/b9c49fb69739cb0669c7aaa7fd8210822f5d8d67.svn-base
+++ /dev/null
@@ -1,46 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Activity
-
-    mattr_accessor :available_event_types, :default_event_types, :providers
-
-    @@available_event_types = []
-    @@default_event_types = []
-    @@providers = Hash.new {|h,k| h[k]=[] }
-
-    class << self
-      def map(&block)
-        yield self
-      end
-
-      # Registers an activity provider
-      def register(event_type, options={})
-        options.assert_valid_keys(:class_name, :default)
-
-        event_type = event_type.to_s
-        providers = options[:class_name] || event_type.classify
-        providers = ([] << providers) unless providers.is_a?(Array)
-
-        @@available_event_types << event_type unless @@available_event_types.include?(event_type)
-        @@default_event_types << event_type unless options[:default] == false
-        @@providers[event_type] += providers
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b9/b9c79e5fb4d089dbf3a1ba6662defed5de839aa8.svn-base
--- a/.svn/pristine/b9/b9c79e5fb4d089dbf3a1ba6662defed5de839aa8.svn-base
+++ /dev/null
@@ -1,117 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'custom_fields_controller'
-
-# Re-raise errors caught by the controller.
-class CustomFieldsController; def rescue_action(e) raise e end; end
-
-class CustomFieldsControllerTest < ActionController::TestCase
-  fixtures :custom_fields, :custom_values, :trackers, :users
-
-  def setup
-    @controller = CustomFieldsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    @request.session[:user_id] = 1
-  end
-
-  def test_index
-    get :index
-    assert_response :success
-    assert_template 'index'
-  end
-
-  def test_get_new_issue_custom_field
-    get :new, :type => 'IssueCustomField'
-    assert_response :success
-    assert_template 'new'
-    assert_tag :select,
-      :attributes => {:name => 'custom_field[field_format]'},
-      :child => {
-        :tag => 'option',
-        :attributes => {:value => 'user'},
-        :content => 'User'
-      }
-    assert_tag :select,
-      :attributes => {:name => 'custom_field[field_format]'},
-      :child => {
-        :tag => 'option',
-        :attributes => {:value => 'version'},
-        :content => 'Version'
-      }
-  end
-
-  def test_get_new_with_invalid_custom_field_class_should_redirect_to_list
-    get :new, :type => 'UnknownCustomField'
-    assert_redirected_to '/custom_fields'
-  end
-
-  def test_post_new_list_custom_field
-    assert_difference 'CustomField.count' do
-      post :new, :type => "IssueCustomField",
-                 :custom_field => {:name => "test_post_new_list",
-                                   :default_value => "",
-                                   :min_length => "0",
-                                   :searchable => "0",
-                                   :regexp => "",
-                                   :is_for_all => "1",
-                                   :possible_values => "0.1\n0.2\n",
-                                   :max_length => "0",
-                                   :is_filter => "0",
-                                   :is_required =>"0",
-                                   :field_format => "list",
-                                   :tracker_ids => ["1", ""]}
-    end
-    assert_redirected_to '/custom_fields?tab=IssueCustomField'
-    field = IssueCustomField.find_by_name('test_post_new_list')
-    assert_not_nil field
-    assert_equal ["0.1", "0.2"], field.possible_values
-    assert_equal 1, field.trackers.size
-  end
-
-  def test_get_edit
-    get :edit, :id => 1
-    assert_response :success
-    assert_template 'edit'
-    assert_tag 'input', :attributes => {:name => 'custom_field[name]', :value => 'Database'}
-  end
-
-  def test_post_edit
-    post :edit, :id => 1, :custom_field => {:name => 'New name'}
-    assert_redirected_to '/custom_fields?tab=IssueCustomField'
-
-    field = CustomField.find(1)
-    assert_equal 'New name', field.name
-  end
-
-  def test_destroy
-    custom_values_count = CustomValue.count(:conditions => {:custom_field_id => 1})
-    assert custom_values_count > 0
-
-    assert_difference 'CustomField.count', -1 do
-      assert_difference 'CustomValue.count', - custom_values_count do
-        post :destroy, :id => 1
-      end
-    end
-
-    assert_redirected_to '/custom_fields?tab=IssueCustomField'
-    assert_nil CustomField.find_by_id(1)
-    assert_nil CustomValue.find_by_custom_field_id(1)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/b9/b9d9e90e281bd059a71c5297b3f5ef791108f131.svn-base
--- a/.svn/pristine/b9/b9d9e90e281bd059a71c5297b3f5ef791108f131.svn-base
+++ /dev/null
@@ -1,19 +0,0 @@
-<% form_for :project, @project,
-            :url => { :action => 'modules', :id => @project },
-            :html => {:id => 'modules-form'} do |f| %>
-
-<div class="box">
-<fieldset>
-<legend><%= l(:text_select_project_modules) %></legend>
-
-<% Redmine::AccessControl.available_project_modules.each do |m| %>
-<p><label><%= check_box_tag 'enabled_module_names[]', m, @project.module_enabled?(m) -%>
- <%= l_or_humanize(m, :prefix => "project_module_") %></label></p>
-<% end %>
-</fieldset>
-</div>
-
-<p><%= check_all_links 'modules-form' %></p>
-<p><%= submit_tag l(:button_save) %></p>
-
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ba/ba2cdbf5143aa221881daae5498faf0c38a97b1e.svn-base
--- a/.svn/pristine/ba/ba2cdbf5143aa221881daae5498faf0c38a97b1e.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-<p>
-<%= label_tag "user_mail_notification", l(:description_user_mail_notification), :class => "hidden-for-sighted" %>
-<%= select_tag 'user[mail_notification]', options_for_select(user_mail_notification_options(@user), @user.mail_notification),
-                                      :onchange => 'if (this.value == "selected") {Element.show("notified-projects")} else {Element.hide("notified-projects")}' %>
-</p>
-<% content_tag 'div', :id => 'notified-projects', :style => (@user.mail_notification == 'selected' ? '' : 'display:none;') do %>
-<p><% @user.projects.each do |project| %>
-    <label><%= check_box_tag 'notified_project_ids[]', project.id, @user.notified_projects_ids.include?(project.id) %> <%=h project.name %></label><br />
-<% end %></p>
-<p><em><%= l(:text_user_mail_option) %></em></p>
-<% end %>
-<p><label><%= l(:label_user_mail_no_self_notified) %><%= check_box_tag 'no_self_notified', 1, @user.pref[:no_self_notified] %></label></p>
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ba/ba72614f0eded334b07543763dc30ef562051344.svn-base
--- a/.svn/pristine/ba/ba72614f0eded334b07543763dc30ef562051344.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-the plaintext part of the email
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ba/ba9f25e41e4fcaaccad1973afa47059d51f609dd.svn-base
--- a/.svn/pristine/ba/ba9f25e41e4fcaaccad1973afa47059d51f609dd.svn-base
+++ /dev/null
@@ -1,34 +0,0 @@
-<h2><%= l(:label_repository) %></h2>
-
-<%= simple_format(l(:text_repository_usernames_mapping)) %>
-
-<% if @committers.empty? %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% else %>
-
-<% form_tag({}) do %>
-<table class="list">
-<thead>
-  <tr>
-    <th><%= l(:field_login) %></th>
-    <th><%= l(:label_user) %></th>
-  </tr>
-</thead>
-<tbody>
-<% i = 0 -%>
-<% @committers.each do |committer, user_id| -%>
-  <tr class="<%= cycle 'odd', 'even' %>">
-    <td><%=h committer %></td>
-    <td>
-      <%= hidden_field_tag "committers[#{i}][]", committer %>
-      <%= select_tag "committers[#{i}][]", content_tag('option', "-- #{l :actionview_instancetag_blank_option} --", :value => '') + options_from_collection_for_select(@users, 'id', 'name', user_id.to_i) %>
-    </td>
-  </tr>
-  <% i += 1 -%>
-<% end -%>
-</tbody>
-</table>
-<p><%= submit_tag(l(:button_update)) %></p>
-<% end %>
-
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ba/baabaf53d0cee72482d890624c4c30bf15a17124.svn-base
--- a/.svn/pristine/ba/baabaf53d0cee72482d890624c4c30bf15a17124.svn-base
+++ /dev/null
@@ -1,1025 +0,0 @@
-# Danish translation file for standard Ruby on Rails internationalization
-# by Lars Hoeg (http://www.lenio.dk/)
-# updated and upgraded to 0.9 by Morten Krogh Andersen (http://www.krogh.net)
-
-da:
-  direction: ltr
-  date:
-    formats:
-      default: "%d.%m.%Y"
-      short: "%e. %b %Y"
-      long: "%e. %B %Y"
-
-    day_names: [sÃ¸ndag, mandag, tirsdag, onsdag, torsdag, fredag, lÃ¸rdag]
-    abbr_day_names: [sÃ¸, ma, ti, 'on', to, fr, lÃ¸]
-    month_names: [~, januar, februar, marts, april, maj, juni, juli, august, september, oktober, november, december]
-    abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, dec]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%e. %B %Y, %H:%M"
-      time: "%H:%M"
-      short: "%e. %b %Y, %H:%M"
-      long: "%A, %e. %B %Y, %H:%M"
-    am: ""
-    pm: ""
-
-  support:
-    array:
-      sentence_connector: "og"
-      skip_last_comma: true
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "et halvt minut"
-      less_than_x_seconds:
-        one:  "mindre end et sekund"
-        other: "mindre end %{count} sekunder"
-      x_seconds:
-        one:  "et sekund"
-        other: "%{count} sekunder"
-      less_than_x_minutes:
-        one:  "mindre end et minut"
-        other: "mindre end %{count} minutter"
-      x_minutes:
-        one:  "et minut"
-        other: "%{count} minutter"
-      about_x_hours:
-        one:  "cirka en time"
-        other: "cirka %{count} timer"
-      x_days:
-        one:  "en dag"
-        other: "%{count} dage"
-      about_x_months:
-        one:  "cirka en mÃ¥ned"
-        other: "cirka %{count} mÃ¥neder"
-      x_months:
-        one:  "en mÃ¥ned"
-        other: "%{count} mÃ¥neder"
-      about_x_years:
-        one:  "cirka et Ã¥r"
-        other: "cirka %{count} Ã¥r"
-      over_x_years:
-        one:  "mere end et Ã¥r"
-        other: "mere end %{count} Ã¥r"
-      almost_x_years:
-        one:   "nÃ¦sten 1 Ã¥r"
-        other: "nÃ¦sten %{count} Ã¥r"
-
-  number:
-    format:
-      separator: ","
-      delimiter: "."
-      precision: 3
-    currency:
-      format:
-        format: "%u %n"
-        unit: "DKK"
-        separator: ","
-        delimiter: "."
-        precision: 2
-    precision:
-      format:
-        # separator:
-        delimiter: ""
-        # precision:
-    human:
-      format:
-        # separator: 
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-    percentage:
-      format:
-        # separator:
-        delimiter: ""
-        # precision:
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "er ikke i listen"
-        exclusion: "er reserveret"
-        invalid: "er ikke gyldig"
-        confirmation: "stemmer ikke overens"
-        accepted: "skal accepteres"
-        empty: "mÃ¥ ikke udelades"
-        blank: "skal udfyldes"
-        too_long: "er for lang (hÃ¸jst %{count} tegn)"
-        too_short: "er for kort (mindst %{count} tegn)"
-        wrong_length: "har forkert lÃ¦ngde (skulle vÃ¦re %{count} tegn)"
-        taken: "er allerede anvendt"
-        not_a_number: "er ikke et tal"
-        greater_than: "skal vÃ¦re stÃ¸rre end %{count}"
-        greater_than_or_equal_to: "skal vÃ¦re stÃ¸rre end eller lig med %{count}"
-        equal_to: "skal vÃ¦re lig med %{count}"
-        less_than: "skal vÃ¦re mindre end %{count}"
-        less_than_or_equal_to: "skal vÃ¦re mindre end eller lig med %{count}"
-        odd: "skal vÃ¦re ulige"
-        even: "skal vÃ¦re lige"
-        greater_than_start_date: "skal vÃ¦re senere end startdatoen"
-        not_same_project: "hÃ¸rer ikke til samme projekt"
-        circular_dependency: "Denne relation vil skabe et afhÃ¦ngighedsforhold"
-        cant_link_an_issue_with_a_descendant: "En sag kan ikke relateres til en af dens underopgaver"
-
-      template:
-        header:
-          one:   "En fejl forhindrede %{model} i at blive gemt"
-          other:  "%{count} fejl forhindrede denne %{model} i at blive gemt"
-        body: "Der var problemer med fÃ¸lgende felter:"
-  
-  actionview_instancetag_blank_option: VÃ¦lg venligst
-  
-  general_text_No: 'Nej'
-  general_text_Yes: 'Ja'
-  general_text_no: 'nej'
-  general_text_yes: 'ja'
-  general_lang_name: 'Danish (Dansk)'
-  general_csv_separator: ','
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: Kontoen er opdateret.
-  notice_account_invalid_creditentials: Ugyldig bruger og/eller kodeord
-  notice_account_password_updated: Kodeordet er opdateret.
-  notice_account_wrong_password: Forkert kodeord
-  notice_account_register_done: Kontoen er oprettet. For at aktivere kontoen skal du klikke pÃ¥ linket i den tilsendte email.
-  notice_account_unknown_email: Ukendt bruger.
-  notice_can_t_change_password: Denne konto benytter en ekstern sikkerhedsgodkendelse. Det er ikke muligt at skifte kodeord.
-  notice_account_lost_email_sent: En email med instruktioner til at vÃ¦lge et nyt kodeord er afsendt til dig.
-  notice_account_activated: Din konto er aktiveret. Du kan nu logge ind.
-  notice_successful_create: Succesfuld oprettelse.
-  notice_successful_update: Succesfuld opdatering.
-  notice_successful_delete: Succesfuld sletning.
-  notice_successful_connection: Succesfuld forbindelse.
-  notice_file_not_found: Siden du forsÃ¸ger at tilgÃ¥ eksisterer ikke eller er blevet fjernet.
-  notice_locking_conflict: Data er opdateret af en anden bruger.
-  notice_not_authorized: Du har ikke adgang til denne side.
-  notice_email_sent: "En email er sendt til %{value}"
-  notice_email_error: "En fejl opstod under afsendelse af email (%{value})"
-  notice_feeds_access_key_reseted: Din adgangsnÃ¸gle til RSS er nulstillet.
-  notice_failed_to_save_issues: "Det mislykkedes at gemme %{count} sage(r) pÃ¥ %{total} valgt: %{ids}."
-  notice_no_issue_selected: "Ingen sag er valgt! VÃ¦lg venligst hvilke emner du vil rette."
-  notice_account_pending: "Din konto er oprettet, og afventer administrators godkendelse."
-  notice_default_data_loaded: StandardopsÃ¦tningen er indlÃ¦st.
-  
-  error_can_t_load_default_data: "StandardopsÃ¦tning kunne ikke indlÃ¦ses: %{value}"
-  error_scm_not_found: "Adgang nÃ¦gtet og/eller revision blev ikke fundet i det valgte repository."
-  error_scm_command_failed: "En fejl opstod under forbindelsen til det valgte repository: %{value}"
-  
-  mail_subject_lost_password: "Dit %{value} kodeord"
-  mail_body_lost_password: 'Klik pÃ¥ dette link for at Ã¦ndre dit kodeord:'
-  mail_subject_register: "%{value} kontoaktivering"
-  mail_body_register: 'Klik pÃ¥ dette link for at aktivere din konto:'
-  mail_body_account_information_external: "Du kan bruge din %{value} konto til at logge ind."
-  mail_body_account_information: Din kontoinformation
-  mail_subject_account_activation_request: "%{value} kontoaktivering"
-  mail_body_account_activation_request: "En ny bruger (%{value}) er registreret. Godkend venligst kontoen:"
-  
-  gui_validation_error: 1 fejl
-  gui_validation_error_plural: "%{count} fejl"
-  
-  field_name: Navn
-  field_description: Beskrivelse
-  field_summary: Sammenfatning
-  field_is_required: Skal udfyldes
-  field_firstname: Fornavn
-  field_lastname: Efternavn
-  field_mail: Email
-  field_filename: Fil
-  field_filesize: StÃ¸rrelse
-  field_downloads: Downloads
-  field_author: Forfatter
-  field_created_on: Oprettet
-  field_updated_on: Opdateret
-  field_field_format: Format
-  field_is_for_all: For alle projekter
-  field_possible_values: Mulige vÃ¦rdier
-  field_regexp: RegulÃ¦re udtryk
-  field_min_length: Mindste lÃ¦ngde
-  field_max_length: StÃ¸rste lÃ¦ngde
-  field_value: VÃ¦rdi
-  field_category: Kategori
-  field_title: Titel
-  field_project: Projekt
-  field_issue: Sag
-  field_status: Status
-  field_notes: Noter
-  field_is_closed: Sagen er lukket
-  field_is_default: StandardvÃ¦rdi
-  field_tracker: Type
-  field_subject: Emne
-  field_due_date: Deadline
-  field_assigned_to: Tildelt til
-  field_priority: Prioritet
-  field_fixed_version: Udgave
-  field_user: Bruger
-  field_role: Rolle
-  field_homepage: Hjemmeside
-  field_is_public: Offentlig
-  field_parent: Underprojekt af
-  field_is_in_roadmap: Sager vist i roadmap
-  field_login: Login
-  field_mail_notification: Email-pÃ¥mindelser
-  field_admin: Administrator
-  field_last_login_on: Sidste forbindelse
-  field_language: Sprog
-  field_effective_date: Dato
-  field_password: Kodeord
-  field_new_password: Nyt kodeord
-  field_password_confirmation: BekrÃ¦ft
-  field_version: Version
-  field_type: Type
-  field_host: VÃ¦rt
-  field_port: Port
-  field_account: Kode
-  field_base_dn: Base DN
-  field_attr_login: Login attribut
-  field_attr_firstname: Fornavn attribut
-  field_attr_lastname: Efternavn attribut
-  field_attr_mail: Email attribut
-  field_onthefly: lÃ¸bende brugeroprettelse
-  field_start_date: Start dato
-  field_done_ratio: "% fÃ¦rdig"
-  field_auth_source: Sikkerhedsmetode
-  field_hide_mail: Skjul min email
-  field_comments: Kommentar
-  field_url: URL
-  field_start_page: Startside
-  field_subproject: Underprojekt
-  field_hours: Timer
-  field_activity: Aktivitet
-  field_spent_on: Dato
-  field_identifier: Identifikator
-  field_is_filter: Brugt som et filter
-  field_issue_to: BeslÃ¦gtede sag
-  field_delay: UdsÃ¦ttelse
-  field_assignable: Sager kan tildeles denne rolle
-  field_redirect_existing_links: Videresend eksisterende links
-  field_estimated_hours: AnslÃ¥et tid
-  field_column_names: Kolonner
-  field_time_zone: Tidszone
-  field_searchable: SÃ¸gbar
-  field_default_value: StandardvÃ¦rdi
-  
-  setting_app_title: Applikationstitel
-  setting_app_subtitle: Applikationsundertekst
-  setting_welcome_text: Velkomsttekst
-  setting_default_language: Standardsporg
-  setting_login_required: Sikkerhed pÃ¥krÃ¦vet
-  setting_self_registration: Brugeroprettelse
-  setting_attachment_max_size: VedhÃ¦ftede filers max stÃ¸rrelse
-  setting_issues_export_limit: SagseksporteringsbegrÃ¦nsning
-  setting_mail_from: Afsender-email
-  setting_bcc_recipients: Skjult modtager (bcc)
-  setting_host_name: VÃ¦rtsnavn
-  setting_text_formatting: Tekstformatering
-  setting_wiki_compression: Komprimering af wiki-historik
-  setting_feeds_limit: Feed indholdsbegrÃ¦nsning
-  setting_autofetch_changesets: Hent automatisk commits
-  setting_sys_api_enabled: Aktiver webservice for automatisk administration af repository
-  setting_commit_ref_keywords: ReferencenÃ¸gleord
-  setting_commit_fix_keywords: AfslutningsnÃ¸gleord
-  setting_autologin: Automatisk login
-  setting_date_format: Datoformat
-  setting_time_format: Tidsformat
-  setting_cross_project_issue_relations: Tillad sagsrelationer pÃ¥ tvÃ¦rs af projekter
-  setting_issue_list_default_columns: Standardkolonner pÃ¥ sagslisten
-  setting_emails_footer: Email-fodnote
-  setting_protocol: Protokol
-  setting_user_format: Brugervisningsformat
-  
-  project_module_issue_tracking: SagssÃ¸gning
-  project_module_time_tracking: Tidsstyring
-  project_module_news: Nyheder
-  project_module_documents: Dokumenter
-  project_module_files: Filer
-  project_module_wiki: Wiki
-  project_module_repository: Repository
-  project_module_boards: Fora
-  
-  label_user: Bruger
-  label_user_plural: Brugere
-  label_user_new: Ny bruger
-  label_project: Projekt
-  label_project_new: Nyt projekt
-  label_project_plural: Projekter
-  label_x_projects:
-    zero:  Ingen projekter
-    one:   1 projekt
-    other: "%{count} projekter"
-  label_project_all: Alle projekter
-  label_project_latest: Seneste projekter
-  label_issue: Sag
-  label_issue_new: Opret sag
-  label_issue_plural: Sager
-  label_issue_view_all: Vis alle sager
-  label_issues_by: "Sager fra %{value}"
-  label_issue_added: Sagen er oprettet
-  label_issue_updated: Sagen er opdateret
-  label_document: Dokument
-  label_document_new: Nyt dokument
-  label_document_plural: Dokumenter
-  label_document_added: Dokument tilfÃ¸jet
-  label_role: Rolle
-  label_role_plural: Roller
-  label_role_new: Ny rolle
-  label_role_and_permissions: Roller og rettigheder
-  label_member: Medlem
-  label_member_new: Nyt medlem
-  label_member_plural: Medlemmer
-  label_tracker: Type
-  label_tracker_plural: Typer
-  label_tracker_new: Ny type
-  label_workflow: Arbejdsgang
-  label_issue_status: Sagsstatus
-  label_issue_status_plural: Sagsstatusser
-  label_issue_status_new: Ny status
-  label_issue_category: Sagskategori
-  label_issue_category_plural: Sagskategorier
-  label_issue_category_new: Ny kategori
-  label_custom_field: Brugerdefineret felt
-  label_custom_field_plural: Brugerdefinerede felter
-  label_custom_field_new: Nyt brugerdefineret felt
-  label_enumerations: VÃ¦rdier
-  label_enumeration_new: Ny vÃ¦rdi
-  label_information: Information
-  label_information_plural: Information
-  label_please_login: Login
-  label_register: RegistrÃ©r
-  label_password_lost: Glemt kodeord
-  label_home: Forside
-  label_my_page: Min side
-  label_my_account: Min konto
-  label_my_projects: Mine projekter
-  label_administration: Administration
-  label_login: Log ind
-  label_logout: Log ud
-  label_help: HjÃ¦lp
-  label_reported_issues: Rapporterede sager
-  label_assigned_to_me_issues: Sager tildelt til mig
-  label_last_login: Sidste logintidspunkt
-  label_registered_on: Registreret den
-  label_activity: Aktivitet
-  label_new: Ny
-  label_logged_as: Registreret som
-  label_environment: MiljÃ¸
-  label_authentication: Sikkerhed
-  label_auth_source: Sikkerhedsmetode
-  label_auth_source_new: Ny sikkerhedsmetode
-  label_auth_source_plural: Sikkerhedsmetoder
-  label_subproject_plural: Underprojekter
-  label_min_max_length: Min - Max lÃ¦ngde
-  label_list: Liste
-  label_date: Dato
-  label_integer: Heltal
-  label_float: Kommatal
-  label_boolean: Sand/falsk
-  label_string: Tekst
-  label_text: Lang tekst
-  label_attribute: Attribut
-  label_attribute_plural: Attributter
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
-  label_no_data: Ingen data at vise
-  label_change_status: Ã†ndringsstatus
-  label_history: Historik
-  label_attachment: Fil
-  label_attachment_new: Ny fil
-  label_attachment_delete: Slet fil
-  label_attachment_plural: Filer
-  label_file_added: Fil tilfÃ¸jet
-  label_report: Rapport
-  label_report_plural: Rapporter
-  label_news: Nyheder
-  label_news_new: TilfÃ¸j nyheder
-  label_news_plural: Nyheder
-  label_news_latest: Seneste nyheder
-  label_news_view_all: Vis alle nyheder
-  label_news_added: Nyhed tilfÃ¸jet
-  label_settings: Indstillinger
-  label_overview: Oversigt
-  label_version: Udgave
-  label_version_new: Ny udgave
-  label_version_plural: Udgaver
-  label_confirmation: BekrÃ¦ftelser
-  label_export_to: Eksporter til
-  label_read: LÃ¦s...
-  label_public_projects: Offentlige projekter
-  label_open_issues: Ã¥ben
-  label_open_issues_plural: Ã¥bne
-  label_closed_issues: lukket
-  label_closed_issues_plural: lukkede
-  label_x_open_issues_abbr_on_total:
-    zero:  0 Ã¥bne / %{total}
-    one:   1 Ã¥ben / %{total}
-    other: "%{count} Ã¥bne / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 Ã¥bne
-    one:   1 Ã¥ben
-    other: "%{count} Ã¥bne"
-  label_x_closed_issues_abbr:
-    zero:  0 lukkede
-    one:   1 lukket
-    other: "%{count} lukkede"
-  label_total: Total
-  label_permissions: Rettigheder
-  label_current_status: NuvÃ¦rende status
-  label_new_statuses_allowed: Ny status tilladt
-  label_all: alle
-  label_none: intet
-  label_nobody: ingen
-  label_next: NÃ¦ste
-  label_previous: Forrige
-  label_used_by: Brugt af
-  label_details: Detaljer
-  label_add_note: TilfÃ¸j note
-  label_per_page: Pr. side
-  label_calendar: Kalender
-  label_months_from: mÃ¥neder frem
-  label_gantt: Gantt
-  label_internal: Intern
-  label_last_changes: "sidste %{count} Ã¦ndringer"
-  label_change_view_all: Vis alle Ã¦ndringer
-  label_personalize_page: Tilret denne side
-  label_comment: Kommentar
-  label_comment_plural: Kommentarer
-  label_x_comments:
-    zero: ingen kommentarer
-    one: 1 kommentar
-    other: "%{count} kommentarer"
-  label_comment_add: TilfÃ¸j en kommentar
-  label_comment_added: Kommentaren er tilfÃ¸jet
-  label_comment_delete: Slet kommentar
-  label_query: Brugerdefineret forespÃ¸rgsel
-  label_query_plural: Brugerdefinerede forespÃ¸rgsler
-  label_query_new: Ny forespÃ¸rgsel
-  label_filter_add: TilfÃ¸j filter
-  label_filter_plural: Filtre
-  label_equals: er
-  label_not_equals: er ikke
-  label_in_less_than: er mindre end
-  label_in_more_than: er stÃ¸rre end
-  label_in: indeholdt i
-  label_today: i dag
-  label_all_time: altid
-  label_yesterday: i gÃ¥r
-  label_this_week: denne uge
-  label_last_week: sidste uge
-  label_last_n_days: "sidste %{count} dage"
-  label_this_month: denne mÃ¥ned
-  label_last_month: sidste mÃ¥ned
-  label_this_year: dette Ã¥r
-  label_date_range: Dato interval
-  label_less_than_ago: mindre end dage siden
-  label_more_than_ago: mere end dage siden
-  label_ago: dage siden
-  label_contains: indeholder
-  label_not_contains: ikke indeholder
-  label_day_plural: dage
-  label_repository: Repository
-  label_repository_plural: Repositories
-  label_browse: Gennemse
-  label_modification: "%{count} Ã¦ndring"
-  label_modification_plural: "%{count} Ã¦ndringer"
-  label_revision: Revision
-  label_revision_plural: Revisioner
-  label_associated_revisions: Tilknyttede revisioner
-  label_added: tilfÃ¸jet
-  label_modified: Ã¦ndret
-  label_deleted: slettet
-  label_latest_revision: Seneste revision
-  label_latest_revision_plural: Seneste revisioner
-  label_view_revisions: Se revisioner
-  label_max_size: Maksimal stÃ¸rrelse
-  label_sort_highest: Flyt til toppen
-  label_sort_higher: Flyt op
-  label_sort_lower: Flyt ned
-  label_sort_lowest: Flyt til bunden
-  label_roadmap: Roadmap
-  label_roadmap_due_in: Deadline
-  label_roadmap_overdue: "%{value} forsinket"
-  label_roadmap_no_issues: Ingen sager i denne version
-  label_search: SÃ¸g
-  label_result_plural: Resultater
-  label_all_words: Alle ord
-  label_wiki: Wiki
-  label_wiki_edit: Wiki Ã¦ndring
-  label_wiki_edit_plural: Wiki Ã¦ndringer
-  label_wiki_page: Wiki side
-  label_wiki_page_plural: Wiki sider
-  label_index_by_title: Indhold efter titel
-  label_index_by_date: Indhold efter dato
-  label_current_version: NuvÃ¦rende version
-  label_preview: ForhÃ¥ndsvisning
-  label_feed_plural: Feeds
-  label_changes_details: Detaljer for alle Ã¦ndringer
-  label_issue_tracking: SagssÃ¸gning
-  label_spent_time: Anvendt tid
-  label_f_hour: "%{value} time"
-  label_f_hour_plural: "%{value} timer"
-  label_time_tracking: Tidsstyring
-  label_change_plural: Ã†ndringer
-  label_statistics: Statistik
-  label_commits_per_month: Commits pr. mÃ¥ned
-  label_commits_per_author: Commits pr. bruger
-  label_view_diff: Vis forskelle
-  label_diff_inline: inline
-  label_diff_side_by_side: side om side
-  label_options: Formatering
-  label_copy_workflow_from: Kopier arbejdsgang fra
-  label_permissions_report: Godkendelsesrapport
-  label_watched_issues: OvervÃ¥gede sager
-  label_related_issues: Relaterede sager
-  label_applied_status: Anvendte statusser
-  label_loading: IndlÃ¦ser...
-  label_relation_new: Ny relation
-  label_relation_delete: Slet relation
-  label_relates_to: relaterer til
-  label_duplicates: duplikater
-  label_blocks: blokerer
-  label_blocked_by: blokeret af
-  label_precedes: kommer fÃ¸r
-  label_follows: fÃ¸lger
-  label_end_to_start: slut til start
-  label_end_to_end: slut til slut
-  label_start_to_start: start til start
-  label_start_to_end: start til slut
-  label_stay_logged_in: Forbliv indlogget
-  label_disabled: deaktiveret
-  label_show_completed_versions: Vis fÃ¦rdige versioner
-  label_me: mig
-  label_board: Forum
-  label_board_new: Nyt forum
-  label_board_plural: Fora
-  label_topic_plural: Emner
-  label_message_plural: Beskeder
-  label_message_last: Sidste besked
-  label_message_new: Ny besked
-  label_message_posted: Besked tilfÃ¸jet
-  label_reply_plural: Besvarer
-  label_send_information: Send konto information til bruger
-  label_year: Ã…r
-  label_month: MÃ¥ned
-  label_week: Uge
-  label_date_from: Fra
-  label_date_to: Til
-  label_language_based: Baseret pÃ¥ brugerens sprog
-  label_sort_by: "SortÃ©r efter %{value}"
-  label_send_test_email: Send en test email
-  label_feeds_access_key_created_on: "RSS adgangsnÃ¸gle dannet for %{value} siden"
-  label_module_plural: Moduler
-  label_added_time_by: "TilfÃ¸jet af %{author} for %{age} siden"
-  label_updated_time: "Opdateret for %{value} siden"
-  label_jump_to_a_project: Skift til projekt...
-  label_file_plural: Filer
-  label_changeset_plural: Ã†ndringer
-  label_default_columns: Standardkolonner
-  label_no_change_option: (Ingen Ã¦ndringer)
-  label_bulk_edit_selected_issues: Masse-ret de valgte sager
-  label_theme: Tema
-  label_default: standard
-  label_search_titles_only: SÃ¸g kun i titler
-  label_user_mail_option_all: "For alle hÃ¦ndelser pÃ¥ mine projekter"
-  label_user_mail_option_selected: "For alle hÃ¦ndelser pÃ¥ de valgte projekter..."
-  label_user_mail_no_self_notified: "Jeg Ã¸nsker ikke besked om Ã¦ndring foretaget af mig selv"
-  label_registration_activation_by_email: kontoaktivering pÃ¥ email
-  label_registration_manual_activation: manuel kontoaktivering
-  label_registration_automatic_activation: automatisk kontoaktivering
-  label_display_per_page: "Per side: %{value}"
-  label_age: Alder
-  label_change_properties: Ã†ndre indstillinger
-  label_general: Generelt
-  label_more: Mere
-  label_scm: SCM
-  label_plugins: Plugins
-  label_ldap_authentication: LDAP-godkendelse
-  label_downloads_abbr: D/L
-  
-  button_login: Login
-  button_submit: Send
-  button_save: Gem
-  button_check_all: VÃ¦lg alt
-  button_uncheck_all: FravÃ¦lg alt
-  button_delete: Slet
-  button_create: Opret
-  button_test: Test
-  button_edit: Ret
-  button_add: TilfÃ¸j
-  button_change: Ã†ndre
-  button_apply: Anvend
-  button_clear: Nulstil
-  button_lock: LÃ¥s
-  button_unlock: LÃ¥s op
-  button_download: Download
-  button_list: List
-  button_view: Vis
-  button_move: Flyt
-  button_back: Tilbage
-  button_cancel: AnnullÃ©r
-  button_activate: AktivÃ©r
-  button_sort: SortÃ©r
-  button_log_time: Log tid
-  button_rollback: TilbagefÃ¸r til denne version
-  button_watch: OvervÃ¥g
-  button_unwatch: Stop overvÃ¥gning
-  button_reply: Besvar
-  button_archive: ArkivÃ©r
-  button_unarchive: Fjern fra arkiv
-  button_reset: Nulstil
-  button_rename: OmdÃ¸b
-  button_change_password: Skift kodeord
-  button_copy: KopiÃ©r
-  button_annotate: AnnotÃ©r
-  button_update: OpdatÃ©r
-  button_configure: KonfigurÃ©r
-  
-  status_active: aktiv
-  status_registered: registreret
-  status_locked: lÃ¥st
-  
-  text_select_mail_notifications: VÃ¦lg handlinger der skal sendes email besked for.
-  text_regexp_info: f.eks. ^[A-ZÃ†Ã˜Ã…0-9]+$
-  text_min_max_length_info: 0 betyder ingen begrÃ¦nsninger
-  text_project_destroy_confirmation: Er du sikker pÃ¥ at du vil slette dette projekt og alle relaterede data?
-  text_workflow_edit: VÃ¦lg en rolle samt en type, for at redigere arbejdsgangen
-  text_are_you_sure: Er du sikker?
-  text_tip_issue_begin_day: opgaven begynder denne dag
-  text_tip_issue_end_day: opaven slutter denne dag
-  text_tip_issue_begin_end_day: opgaven begynder og slutter denne dag
-  text_project_identifier_info: 'SmÃ¥ bogstaver (a-z), numre og bindestreg er tilladt.<br />Denne er en unik identifikation for projektet, og kan defor ikke rettes senere.'
-  text_caracters_maximum: "max %{count} karakterer."
-  text_caracters_minimum: "Skal vÃ¦re mindst %{count} karakterer lang."
-  text_length_between: "LÃ¦ngde skal vÃ¦re mellem %{min} og %{max} karakterer."
-  text_tracker_no_workflow: Ingen arbejdsgang defineret for denne type
-  text_unallowed_characters: Ikke-tilladte karakterer
-  text_comma_separated: Adskillige vÃ¦rdier tilladt (adskilt med komma).
-  text_issues_ref_in_commit_messages: Referer og lÃ¸ser sager i commit-beskeder
-  text_issue_added: "Sag %{id} er rapporteret af %{author}."
-  text_issue_updated: "Sag %{id} er blevet opdateret af %{author}."
-  text_wiki_destroy_confirmation: Er du sikker pÃ¥ at du vil slette denne wiki og dens indhold?
-  text_issue_category_destroy_question: "Nogle sager (%{count}) er tildelt denne kategori. Hvad Ã¸nsker du at gÃ¸re?"
-  text_issue_category_destroy_assignments: Slet tildelinger af kategori
-  text_issue_category_reassign_to: Tildel sager til denne kategori
-  text_user_mail_option: "For ikke-valgte projekter vil du kun modtage beskeder omhandlende ting du er involveret i eller overvÃ¥ger (f.eks. sager du har indberettet eller ejer)."
-  text_no_configuration_data: "Roller, typer, sagsstatusser og arbejdsgange er endnu ikke konfigureret.\nDet er anbefalet at indlÃ¦se standardopsÃ¦tningen. Du vil kunne Ã¦ndre denne nÃ¥r den er indlÃ¦st."
-  text_load_default_configuration: IndlÃ¦s standardopsÃ¦tningen
-  text_status_changed_by_changeset: "Anvendt i Ã¦ndring %{value}."
-  text_issues_destroy_confirmation: 'Er du sikker pÃ¥ du Ã¸nsker at slette den/de valgte sag(er)?'
-  text_select_project_modules: 'VÃ¦lg moduler er skal vÃ¦re aktiveret for dette projekt:'
-  text_default_administrator_account_changed: Standardadministratorkonto Ã¦ndret
-  text_file_repository_writable: Filarkiv er skrivbar
-  text_rmagick_available: RMagick tilgÃ¦ngelig (valgfri)
-  
-  default_role_manager: Leder
-  default_role_developer: Udvikler
-  default_role_reporter: RapportÃ¸r
-  default_tracker_bug: Fejl
-  default_tracker_feature: Funktion
-  default_tracker_support: Support
-  default_issue_status_new: Ny
-  default_issue_status_in_progress: IgangvÃ¦rende
-  default_issue_status_resolved: LÃ¸st
-  default_issue_status_feedback: Feedback
-  default_issue_status_closed: Lukket
-  default_issue_status_rejected: Afvist
-  default_doc_category_user: Brugerdokumentation
-  default_doc_category_tech: Teknisk dokumentation
-  default_priority_low: Lav
-  default_priority_normal: Normal
-  default_priority_high: HÃ¸j
-  default_priority_urgent: Akut
-  default_priority_immediate: OmgÃ¥ende
-  default_activity_design: Design
-  default_activity_development: Udvikling
-  
-  enumeration_issue_priorities: Sagsprioriteter
-  enumeration_doc_categories: Dokumentkategorier
-  enumeration_activities: Aktiviteter (tidsstyring)
-  
-  label_add_another_file: TilfÃ¸j endnu en fil
-  label_chronological_order: I kronologisk rÃ¦kkefÃ¸lge
-  setting_activity_days_default: Antal dage der vises under projektaktivitet
-  text_destroy_time_entries_question: "%{hours} timer er registreret pÃ¥ denne sag som du er ved at slette. Hvad vil du gÃ¸re?"
-  error_issue_not_found_in_project: 'Sagen blev ikke fundet eller tilhÃ¸rer ikke dette projekt'
-  text_assign_time_entries_to_project: Tildel raporterede timer til projektet
-  setting_display_subprojects_issues: Vis sager for underprojekter pÃ¥ hovedprojektet som standard
-  label_optional_description: Valgfri beskrivelse
-  text_destroy_time_entries: Slet registrerede timer
-  field_comments_sorting: Vis kommentar
-  text_reassign_time_entries: 'Tildel registrerede timer til denne sag igen'
-  label_reverse_chronological_order: I omvendt kronologisk rÃ¦kkefÃ¸lge
-  label_preferences: PrÃ¦ferencer
-  label_overall_activity: Overordnet aktivitet
-  setting_default_projects_public: Nye projekter er offentlige som standard
-  error_scm_annotate: "Filen findes ikke, eller kunne ikke annoteres."
-  label_planning: PlanlÃ¦gning
-  text_subprojects_destroy_warning: "Dets underprojekter(er): %{value} vil ogsÃ¥ blive slettet."
-  permission_edit_issues: RedigÃ©r sager
-  setting_diff_max_lines_displayed: HÃ¸jeste antal forskelle der vises
-  permission_edit_own_issue_notes: RedigÃ©r egne noter
-  setting_enabled_scm: Aktiveret SCM
-  button_quote: CitÃ©r
-  permission_view_files: Se filer
-  permission_add_issues: TilfÃ¸j sager
-  permission_edit_own_messages: RedigÃ©r egne beskeder
-  permission_delete_own_messages: Slet egne beskeder
-  permission_manage_public_queries: AdministrÃ©r offentlig forespÃ¸rgsler
-  permission_log_time: RegistrÃ©r anvendt tid
-  label_renamed: omdÃ¸bt
-  label_incoming_emails: Indkommende emails
-  permission_view_changesets: Se Ã¦ndringer
-  permission_manage_versions: AdministrÃ©r versioner
-  permission_view_time_entries: Se anvendt tid
-  label_generate_key: GenerÃ©r en nÃ¸glefil
-  permission_manage_categories: AdministrÃ©r sagskategorier
-  permission_manage_wiki: AdministrÃ©r wiki
-  setting_sequential_project_identifiers: GenerÃ©r sekventielle projekt-identifikatorer
-  setting_plain_text_mail: Emails som almindelig tekst (ingen HTML)
-  field_parent_title: Siden over
-  text_email_delivery_not_configured: "Email-afsendelse er ikke indstillet og notifikationer er defor slÃ¥et fra.\nKonfigurÃ©r din SMTP server i config/configuration.yml og genstart applikationen for at aktivere email-afsendelse."
-  permission_protect_wiki_pages: Beskyt wiki sider
-  permission_manage_documents: AdministrÃ©r dokumenter
-  permission_add_issue_watchers: TilfÃ¸j overvÃ¥gere
-  warning_attachments_not_saved: "der var %{count} fil(er), som ikke kunne gemmes."
-  permission_comment_news: KommentÃ©r nyheder
-  text_enumeration_category_reassign_to: 'Flyt dem til denne vÃ¦rdi:'
-  permission_select_project_modules: VÃ¦lg projektmoduler
-  permission_view_gantt: Se Gantt diagram
-  permission_delete_messages: Slet beskeder
-  permission_move_issues: Flyt sager
-  permission_edit_wiki_pages: RedigÃ©r wiki sider
-  label_user_activity: "%{value}'s aktivitet"
-  permission_manage_issue_relations: AdministrÃ©r sags-relationer
-  label_issue_watchers: OvervÃ¥gere
-  permission_delete_wiki_pages: Slet wiki sider
-  notice_unable_delete_version: Kan ikke slette versionen.
-  permission_view_wiki_edits: Se wiki historik
-  field_editable: RedigÃ©rbar
-  label_duplicated_by: dubleret af
-  permission_manage_boards: AdministrÃ©r fora
-  permission_delete_wiki_pages_attachments: Slet filer vedhÃ¦ftet wiki sider
-  permission_view_messages: Se beskeder
-  text_enumeration_destroy_question: "%{count} objekter er tildelt denne vÃ¦rdi."
-  permission_manage_files: AdministrÃ©r filer
-  permission_add_messages: Opret beskeder
-  permission_edit_issue_notes: RedigÃ©r noter
-  permission_manage_news: AdministrÃ©r nyheder
-  text_plugin_assets_writable: Der er skriverettigheder til plugin assets folderen 
-  label_display: Vis
-  label_and_its_subprojects: "%{value} og dets underprojekter"
-  permission_view_calendar: Se kalender
-  button_create_and_continue: Opret og fortsÃ¦t
-  setting_gravatar_enabled: Anvend Gravatar brugerikoner
-  label_updated_time_by: "Opdateret af %{author} for %{age} siden"
-  text_diff_truncated: '... Listen over forskelle er blevet afkortet da den overstiger den maksimale stÃ¸rrelse der kan vises.'
-  text_user_wrote: "%{value} skrev:"
-  setting_mail_handler_api_enabled: Aktiver webservice for indkomne emails
-  permission_delete_issues: Slet sager
-  permission_view_documents: Se dokumenter
-  permission_browse_repository: Gennemse repository
-  permission_manage_repository: AdministrÃ©r repository
-  permission_manage_members: AdministrÃ©r medlemmer
-  mail_subject_reminder: "%{count} sag(er) har deadline i de kommende dage (%{days})"
-  permission_add_issue_notes: TilfÃ¸j noter
-  permission_edit_messages: RedigÃ©r beskeder
-  permission_view_issue_watchers: Se liste over overvÃ¥gere
-  permission_commit_access: Commit adgang
-  setting_mail_handler_api_key: API nÃ¸gle
-  label_example: Eksempel
-  permission_rename_wiki_pages: OmdÃ¸b wiki sider
-  text_custom_field_possible_values_info: 'En linje for hver vÃ¦rdi'
-  permission_view_wiki_pages: Se wiki
-  permission_edit_project: RedigÃ©r projekt
-  permission_save_queries: Gem forespÃ¸rgsler
-  label_copied: kopieret
-  text_repository_usernames_mapping: "VÃ¦lg eller opdatÃ©r de Redmine brugere der svarer til de enkelte brugere fundet i repository loggen.\nBrugere med samme brugernavn eller email adresse i bÃ¥de Redmine og det valgte repository bliver automatisk koblet sammen."
-  permission_edit_time_entries: RedigÃ©r tidsregistreringer
-  general_csv_decimal_separator: ','
-  permission_edit_own_time_entries: RedigÃ©r egne tidsregistreringer
-  setting_repository_log_display_limit: HÃ¸jeste antal revisioner vist i fil-log
-  setting_file_max_size_displayed: Maksimale stÃ¸rrelse pÃ¥ tekstfiler vist inline
-  field_watcher: OvervÃ¥ger
-  setting_openid: Tillad OpenID login og registrering
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: eller login med OpenID
-  setting_per_page_options: Enheder per side muligheder
-  mail_body_reminder: "%{count} sage(er) som er tildelt dig har deadline indenfor de nÃ¦ste %{days} dage:"
-  field_content: Indhold
-  label_descending: Aftagende
-  label_sort: SortÃ©r
-  label_ascending: Tiltagende
-  label_date_from_to: Fra %{start} til %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: Denne side har %{descendants} underside(r) og afledte. Hvad vil du gÃ¸re?
-  text_wiki_page_reassign_children: Flyt undersider til denne side
-  text_wiki_page_nullify_children: Behold undersider som rod-sider
-  text_wiki_page_destroy_children: Slet undersider ogalle deres afledte sider.
-  setting_password_min_length: Mindste lÃ¦ngde pÃ¥ kodeord
-  field_group_by: GruppÃ©r resultater efter
-  mail_subject_wiki_content_updated: "'%{id}' wikisiden er blevet opdateret"
-  label_wiki_content_added: Wiki side tilfÃ¸jet
-  mail_subject_wiki_content_added: "'%{id}' wikisiden er blevet tilfÃ¸jet"
-  mail_body_wiki_content_added: The '%{id}' wikiside er blevet tilfÃ¸jet af %{author}.
-  label_wiki_content_updated: Wikiside opdateret
-  mail_body_wiki_content_updated: Wikisiden '%{id}' er blevet opdateret af %{author}.
-  permission_add_project: Opret projekt
-  setting_new_project_user_role_id: Denne rolle gives til en bruger, som ikke er administrator, og som opretter et projekt
-  label_view_all_revisions: Se alle revisioner
-  label_tag: Tag
-  label_branch: Branch
-  error_no_tracker_in_project: Der er ingen sagshÃ¥ndtering for dette projekt. KontrollÃ©r venligst projektindstillingerne.
-  error_no_default_issue_status: Der er ikke defineret en standardstatus. KontrollÃ©r venligst indstillingerne (gÃ¥ til "Administration -> Sagsstatusser").
-  text_journal_changed: "%{label} Ã¦ndret fra %{old} til %{new}"
-  text_journal_set_to: "%{label} sat til %{value}"
-  text_journal_deleted: "%{label} slettet (%{old})"
-  label_group_plural: Grupper
-  label_group: Grupper
-  label_group_new: Ny gruppe
-  label_time_entry_plural: Anvendt tid
-  text_journal_added: "%{label} %{value} tilfÃ¸jet"
-  field_active: Aktiv
-  enumeration_system_activity: System Aktivitet
-  permission_delete_issue_watchers: Slet overvÃ¥gere
-  version_status_closed: lukket
-  version_status_locked: lÃ¥st
-  version_status_open: Ã¥ben
-  error_can_not_reopen_issue_on_closed_version: En sag tildelt en lukket version kan ikke genÃ¥bnes
-  label_user_anonymous: Anonym
-  button_move_and_follow: Flyt og overvÃ¥g
-  setting_default_projects_modules: Standard moduler, aktiveret for nye projekter
-  setting_gravatar_default: Standard Gravatar billede
-  field_sharing: Delning
-  label_version_sharing_hierarchy: Med projekthierarki
-  label_version_sharing_system: Med alle projekter
-  label_version_sharing_descendants: Med underprojekter
-  label_version_sharing_tree: Med projekttrÃ¦
-  label_version_sharing_none: Ikke delt
-  error_can_not_archive_project: Dette projekt kan ikke arkiveres
-  button_duplicate: DuplikÃ©r
-  button_copy_and_follow: KopiÃ©r og overvÃ¥g
-  label_copy_source: Kilde
-  setting_issue_done_ratio: Beregn sagslÃ¸sning ratio
-  setting_issue_done_ratio_issue_status: Benyt sagsstatus
-  error_issue_done_ratios_not_updated: SagslÃ¸snings ratio, ikke opdateret.
-  error_workflow_copy_target: VÃ¦lg venligst mÃ¥ltracker og rolle(r)
-  setting_issue_done_ratio_issue_field: Benyt sagsfelt
-  label_copy_same_as_target: Samme som mÃ¥l
-  label_copy_target: MÃ¥l
-  notice_issue_done_ratios_updated: SagslÃ¸sningsratio opdateret.
-  error_workflow_copy_source: VÃ¦lg venligst en kildetracker eller rolle
-  label_update_issue_done_ratios: Opdater sagslÃ¸sningsratio
-  setting_start_of_week: Start kalendre pÃ¥
-  permission_view_issues: Vis sager
-  label_display_used_statuses_only: Vis kun statusser der er benyttet af denne tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API nÃ¸gle
-  label_api_access_key_created_on: API nÃ¸gle genereret %{value} siden
-  label_feeds_access_key: RSS nÃ¸gle
-  notice_api_access_key_reseted: Din API nÃ¸gle er nulstillet.
-  setting_rest_api_enabled: Aktiver REST web service
-  label_missing_api_access_key: Mangler en API nÃ¸gle
-  label_missing_feeds_access_key: Mangler en RSS nÃ¸gle
-  button_show: Vis
-  text_line_separated: Flere vÃ¦redier tilladt (en linje for hver vÃ¦rdi).
-  setting_mail_handler_body_delimiters: TrunkÃ©r emails efter en af disse linjer
-  permission_add_subprojects: Lav underprojekter
-  label_subproject_new: Nyt underprojekt
-  text_own_membership_delete_confirmation: |-
-    Du er ved at fjerne en eller flere af dine rettigheder, og kan muligvis ikke redigere projektet bagefter.
-    Er du sikker pÃ¥ du Ã¸nsker at fortsÃ¦tte?
-  label_close_versions: Luk fÃ¦rdige versioner
-  label_board_sticky: Klistret
-  label_board_locked: LÃ¥st
-  permission_export_wiki_pages: Eksporter wiki sider
-  setting_cache_formatted_text: Cache formatteret tekst
-  permission_manage_project_activities: Administrer projektaktiviteter
-  error_unable_delete_issue_status: Det var ikke muligt at slette sagsstatus
-  label_profile: Profil
-  permission_manage_subtasks: Administrer underopgaver
-  field_parent_issue: Hovedopgave
-  label_subtask_plural: Underopgaver
-  label_project_copy_notifications: Send email notifikationer, mens projektet kopieres
-  error_can_not_delete_custom_field: Kan ikke slette brugerdefineret felt
-  error_unable_to_connect: Kan ikke forbinde (%{value})
-  error_can_not_remove_role: Denne rolle er i brug og kan ikke slettes.
-  error_can_not_delete_tracker: Denne type indeholder sager og kan ikke slettes.
-  field_principal: Principal
-  label_my_page_block: blok
-  notice_failed_to_save_members: "Fejl under lagring af medlem(mer): %{errors}."
-  text_zoom_out: Zoom ud
-  text_zoom_in: Zoom ind
-  notice_unable_delete_time_entry: Kan ikke slette tidsregistrering.
-  label_overall_spent_time: Overordnet forbrug af tid
-  field_time_entries: Log tid
-  project_module_gantt: Gantt
-  project_module_calendar: Kalender
-  button_edit_associated_wikipage: "RedigÃ©r tilknyttet Wiki side: %{page_title}"
-  text_are_you_sure_with_children: Slet sag og alle undersager?
-  field_text: Tekstfelt
-  label_user_mail_option_only_owner: Kun for ting jeg er ejer af
-  setting_default_notification_option: StandardpÃ¥mindelsesmulighed
-  label_user_mail_option_only_my_events: Kun for ting jeg overvÃ¥ger eller er involveret i
-  label_user_mail_option_only_assigned: Kun for ting jeg er tildelt
-  label_user_mail_option_none: Ingen hÃ¦ndelser
-  field_member_of_group: Medlem af gruppe
-  field_assigned_to_role: Medlem af rolle
-  notice_not_authorized_archived_project: Projektet du prÃ¸ver at tilgÃ¥, er blevet arkiveret.
-  label_principal_search: "SÃ¸g efter bruger eller gruppe:"
-  label_user_search: "SÃ¸g efter bruger:"
-  field_visible: Synlig
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Aktivitet for registreret tid
-  text_time_logged_by_changeset: Anvendt i changeset %{value}.
-  setting_commit_logtime_enabled: Aktiver tidsregistrering
-  notice_gantt_chart_truncated: Kortet er blevet afkortet, fordi det overstiger det maksimale antal elementer, der kan vises (%{max})
-  setting_gantt_items_limit: Maksimalt antal af elementer der kan vises pÃ¥ gantt kortet
-
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Kodning af Commit beskeder
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ba/bad7988dc8d7b98fa49d927fe46638bead208bbb.svn-base
--- /dev/null
+++ b/.svn/pristine/ba/bad7988dc8d7b98fa49d927fe46638bead208bbb.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module MailHandlerHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ba/badfd965f10fb42e2363bdf98738ced2e08c301d.svn-base
--- a/.svn/pristine/ba/badfd965f10fb42e2363bdf98738ced2e08c301d.svn-base
+++ /dev/null
@@ -1,36 +0,0 @@
-<%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %>
-
-<div class="contextual">
-  <%= render :partial => 'navigation' %>
-</div>
-
-<h2><%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2>
-
-<p><%= render :partial => 'link_to_functions' %></p>
-
-<% colors = Hash.new {|k,v| k[v] = (k.size % 12) } %>
-
-<div class="autoscroll">
-<table class="filecontent annotate syntaxhl">
-  <tbody>
-    <% line_num = 1 %>
-    <% syntax_highlight(@path, Redmine::CodesetUtil.to_utf8_by_setting(@annotate.content)).each_line do |line| %>
-      <% revision = @annotate.revisions[line_num - 1] %>
-      <tr class="bloc-<%= revision.nil? ? 0 : colors[revision.identifier || revision.revision] %>">
-        <th class="line-num" id="L<%= line_num %>"><a href="#L<%= line_num %>"><%= line_num %></a></th>
-        <td class="revision">
-        <%= (revision.identifier ? link_to_revision(revision, @project) : format_revision(revision)) if revision %></td>
-        <td class="author"><%= h(revision.author.to_s.split('<').first) if revision %></td>
-        <td class="line-code"><pre><%= line %></pre></td>
-      </tr>
-      <% line_num += 1 %>
-    <% end %>
-  </tbody>
-</table>
-</div>
-
-<% html_title(l(:button_annotate)) -%>
-
-<% content_for :header_tags do %>
-<%= stylesheet_link_tag 'scm' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bb/bb06370b97e92382be8f657caf2728943f14253a.svn-base
--- /dev/null
+++ b/.svn/pristine/bb/bb06370b97e92382be8f657caf2728943f14253a.svn-base
@@ -0,0 +1,144 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class SearchTest < ActiveSupport::TestCase
+  fixtures :users,
+           :members,
+           :member_roles,
+           :projects,
+           :roles,
+           :enabled_modules,
+           :issues,
+           :trackers,
+           :journals,
+           :journal_details,
+           :repositories,
+           :changesets
+
+  def setup
+    @project = Project.find(1)
+    @issue_keyword = '%unable to print recipes%'
+    @issue = Issue.find(1)
+    @changeset_keyword = '%very first commit%'
+    @changeset = Changeset.find(100)
+  end
+
+  def test_search_by_anonymous
+    User.current = nil
+
+    r = Issue.search(@issue_keyword).first
+    assert r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert r.include?(@changeset)
+
+    # Removes the :view_changesets permission from Anonymous role
+    remove_permission Role.anonymous, :view_changesets
+
+    r = Issue.search(@issue_keyword).first
+    assert r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert !r.include?(@changeset)
+
+    # Make the project private
+    @project.update_attribute :is_public, false
+    r = Issue.search(@issue_keyword).first
+    assert !r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert !r.include?(@changeset)
+  end
+
+  def test_search_by_user
+    User.current = User.find_by_login('rhill')
+    assert User.current.memberships.empty?
+
+    r = Issue.search(@issue_keyword).first
+    assert r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert r.include?(@changeset)
+
+    # Removes the :view_changesets permission from Non member role
+    remove_permission Role.non_member, :view_changesets
+
+    r = Issue.search(@issue_keyword).first
+    assert r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert !r.include?(@changeset)
+
+    # Make the project private
+    @project.update_attribute :is_public, false
+    r = Issue.search(@issue_keyword).first
+    assert !r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert !r.include?(@changeset)
+  end
+
+  def test_search_by_allowed_member
+    User.current = User.find_by_login('jsmith')
+    assert User.current.projects.include?(@project)
+
+    r = Issue.search(@issue_keyword).first
+    assert r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert r.include?(@changeset)
+
+    # Make the project private
+    @project.update_attribute :is_public, false
+    r = Issue.search(@issue_keyword).first
+    assert r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert r.include?(@changeset)
+  end
+
+  def test_search_by_unallowed_member
+    # Removes the :view_changesets permission from user's and non member role
+    remove_permission Role.find(1), :view_changesets
+    remove_permission Role.non_member, :view_changesets
+
+    User.current = User.find_by_login('jsmith')
+    assert User.current.projects.include?(@project)
+
+    r = Issue.search(@issue_keyword).first
+    assert r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert !r.include?(@changeset)
+
+    # Make the project private
+    @project.update_attribute :is_public, false
+    r = Issue.search(@issue_keyword).first
+    assert r.include?(@issue)
+    r = Changeset.search(@changeset_keyword).first
+    assert !r.include?(@changeset)
+  end
+
+  def test_search_issue_with_multiple_hits_in_journals
+    i = Issue.find(1)
+    assert_equal 2, i.journals.count(:all, :conditions => "notes LIKE '%notes%'")
+
+    r = Issue.search('%notes%').first
+    assert_equal 1, r.size
+    assert_equal i, r.first
+  end
+
+  private
+
+  def remove_permission(role, permission)
+    role.permissions = role.permissions - [ permission ]
+    role.save
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bb/bb10932a078b9ed11d9a91d216248a45a8481e6c.svn-base
--- a/.svn/pristine/bb/bb10932a078b9ed11d9a91d216248a45a8481e6c.svn-base
+++ /dev/null
@@ -1,235 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class VersionTest < ActiveSupport::TestCase
-  fixtures :projects, :users, :issues, :issue_statuses, :trackers, :enumerations, :versions
-
-  def setup
-  end
-
-  def test_create
-    v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '2011-03-25')
-    assert v.save
-    assert_equal 'open', v.status
-    assert_equal 'none', v.sharing
-  end
-
-  def test_invalid_effective_date_validation
-    v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '99999-01-01')
-    assert !v.save
-    assert_equal I18n.translate('activerecord.errors.messages.not_a_date'), v.errors.on(:effective_date)
-  end
-
-  def test_progress_should_be_0_with_no_assigned_issues
-    project = Project.find(1)
-    v = Version.create!(:project => project, :name => 'Progress')
-    assert_equal 0, v.completed_pourcent
-    assert_equal 0, v.closed_pourcent
-  end
-
-  def test_progress_should_be_0_with_unbegun_assigned_issues
-    project = Project.find(1)
-    v = Version.create!(:project => project, :name => 'Progress')
-    add_issue(v)
-    add_issue(v, :done_ratio => 0)
-    assert_progress_equal 0, v.completed_pourcent
-    assert_progress_equal 0, v.closed_pourcent
-  end
-
-  def test_progress_should_be_100_with_closed_assigned_issues
-    project = Project.find(1)
-    status = IssueStatus.find(:first, :conditions => {:is_closed => true})
-    v = Version.create!(:project => project, :name => 'Progress')
-    add_issue(v, :status => status)
-    add_issue(v, :status => status, :done_ratio => 20)
-    add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
-    add_issue(v, :status => status, :estimated_hours => 15)
-    assert_progress_equal 100.0, v.completed_pourcent
-    assert_progress_equal 100.0, v.closed_pourcent
-  end
-
-  def test_progress_should_consider_done_ratio_of_open_assigned_issues
-    project = Project.find(1)
-    v = Version.create!(:project => project, :name => 'Progress')
-    add_issue(v)
-    add_issue(v, :done_ratio => 20)
-    add_issue(v, :done_ratio => 70)
-    assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_pourcent
-    assert_progress_equal 0, v.closed_pourcent
-  end
-
-  def test_progress_should_consider_closed_issues_as_completed
-    project = Project.find(1)
-    v = Version.create!(:project => project, :name => 'Progress')
-    add_issue(v)
-    add_issue(v, :done_ratio => 20)
-    add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
-    assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_pourcent
-    assert_progress_equal (100.0)/3, v.closed_pourcent
-  end
-
-  def test_progress_should_consider_estimated_hours_to_weigth_issues
-    project = Project.find(1)
-    v = Version.create!(:project => project, :name => 'Progress')
-    add_issue(v, :estimated_hours => 10)
-    add_issue(v, :estimated_hours => 20, :done_ratio => 30)
-    add_issue(v, :estimated_hours => 40, :done_ratio => 10)
-    add_issue(v, :estimated_hours => 25, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
-    assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_pourcent
-    assert_progress_equal 25.0/95.0*100, v.closed_pourcent
-  end
-
-  def test_progress_should_consider_average_estimated_hours_to_weigth_unestimated_issues
-    project = Project.find(1)
-    v = Version.create!(:project => project, :name => 'Progress')
-    add_issue(v, :done_ratio => 20)
-    add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
-    add_issue(v, :estimated_hours => 10, :done_ratio => 30)
-    add_issue(v, :estimated_hours => 40, :done_ratio => 10)
-    assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_pourcent
-    assert_progress_equal 25.0/100.0*100, v.closed_pourcent
-  end
-
-  context "#behind_schedule?" do
-    setup do
-      ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
-      @project = Project.generate!(:identifier => 'test0')
-      @project.trackers << Tracker.generate!
-
-      @version = Version.generate!(:project => @project, :effective_date => nil)
-    end
-
-    should "be false if there are no issues assigned" do
-      @version.update_attribute(:effective_date, Date.yesterday)
-      assert_equal false, @version.behind_schedule?
-    end
-
-    should "be false if there is no effective_date" do
-      assert_equal false, @version.behind_schedule?
-    end
-
-    should "be false if all of the issues are ahead of schedule" do
-      @version.update_attribute(:effective_date, 7.days.from_now.to_date)
-      @version.fixed_issues = [
-                               Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 60), # 14 day span, 60% done, 50% time left
-                               Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
-                              ]
-      assert_equal 60, @version.completed_pourcent
-      assert_equal false, @version.behind_schedule?
-    end
-
-    should "be true if any of the issues are behind schedule" do
-      @version.update_attribute(:effective_date, 7.days.from_now.to_date)
-      @version.fixed_issues = [
-                               Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 60), # 14 day span, 60% done, 50% time left
-                               Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
-                              ]
-      assert_equal 40, @version.completed_pourcent
-      assert_equal true, @version.behind_schedule?
-    end
-
-    should "be false if all of the issues are complete" do
-      @version.update_attribute(:effective_date, 7.days.from_now.to_date)
-      @version.fixed_issues = [
-                               Issue.generate_for_project!(@project, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)), # 7 day span
-                               Issue.generate_for_project!(@project, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
-                              ]
-      assert_equal 100, @version.completed_pourcent
-      assert_equal false, @version.behind_schedule?
-
-    end
-  end
-
-  context "#estimated_hours" do
-    setup do
-      @version = Version.create!(:project_id => 1, :name => '#estimated_hours')
-    end
-
-    should "return 0 with no assigned issues" do
-      assert_equal 0, @version.estimated_hours
-    end
-
-    should "return 0 with no estimated hours" do
-      add_issue(@version)
-      assert_equal 0, @version.estimated_hours
-    end
-
-    should "return the sum of estimated hours" do
-      add_issue(@version, :estimated_hours => 2.5)
-      add_issue(@version, :estimated_hours => 5)
-      assert_equal 7.5, @version.estimated_hours
-    end
-
-    should "return the sum of leaves estimated hours" do
-      parent = add_issue(@version)
-      add_issue(@version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
-      add_issue(@version, :estimated_hours => 5, :parent_issue_id => parent.id)
-      assert_equal 7.5, @version.estimated_hours
-    end
-  end
-
-  test "should update all issue's fixed_version associations in case the hierarchy changed XXX" do
-    User.current = User.find(1) # Need the admin's permissions
-
-    @version = Version.find(7)
-    # Separate hierarchy
-    project_1_issue = Issue.find(1)
-    project_1_issue.fixed_version = @version
-    assert project_1_issue.save, project_1_issue.errors.full_messages.to_s
-
-    project_5_issue = Issue.find(6)
-    project_5_issue.fixed_version = @version
-    assert project_5_issue.save
-
-    # Project
-    project_2_issue = Issue.find(4)
-    project_2_issue.fixed_version = @version
-    assert project_2_issue.save
-
-    # Update the sharing
-    @version.sharing = 'none'
-    assert @version.save
-
-    # Project 1 now out of the shared scope
-    project_1_issue.reload
-    assert_equal nil, project_1_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
-
-    # Project 5 now out of the shared scope
-    project_5_issue.reload
-    assert_equal nil, project_5_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
-
-    # Project 2 issue remains
-    project_2_issue.reload
-    assert_equal @version, project_2_issue.fixed_version
-  end
-
-  private
-
-  def add_issue(version, attributes={})
-    Issue.create!({:project => version.project,
-                   :fixed_version => version,
-                   :subject => 'Test',
-                   :author => User.find(:first),
-                   :tracker => version.project.trackers.find(:first)}.merge(attributes))
-  end
-
-  def assert_progress_equal(expected_float, actual_float, message="")
-    assert_in_delta(expected_float, actual_float, 0.000001, message="")
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bb/bb49c4fef4c5f6dfdf8261e28af3d432f71a4be4.svn-base
--- a/.svn/pristine/bb/bb49c4fef4c5f6dfdf8261e28af3d432f71a4be4.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssuePriorityCustomField < CustomField
-  def type_name
-    :enumeration_issue_priorities
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bb/bbeaa4adc5af51c51d47294e768410269cf13b7e.svn-base
--- a/.svn/pristine/bb/bbeaa4adc5af51c51d47294e768410269cf13b7e.svn-base
+++ /dev/null
@@ -1,32 +0,0 @@
-<table class="cal">
-<thead>
-<tr><th scope="col" title="<%= l(:label_week) %>" class="week-number"></th><% 7.times do |i| %><th scope="col"><%= day_name( (calendar.first_wday+i)%7 ) %></th><% end %></tr>
-</thead>
-<tbody>
-<tr>
-<% day = calendar.startdt
-while day <= calendar.enddt %>
-<%= "<td class='week-number' title='#{ l(:label_week) }'>#{(day+(11-day.cwday)%7).cweek}</td>" if day.cwday == calendar.first_wday %>
-<td class="<%= day.month==calendar.month ? 'even' : 'odd' %><%= ' today' if Date.today == day %>">
-<p class="day-num"><%= day.day %></p>
-<% calendar.events_on(day).each do |i| %>
-  <% if i.is_a? Issue %>
-  <div class="<%= i.css_classes %> <%= 'starting' if day == i.start_date %> <%= 'ending' if day == i.due_date %> tooltip">
-  <%= h("#{i.project} -") unless @project && @project == i.project %>
-  <%= link_to_issue i, :truncate => 30 %>
-  <span class="tip"><%= render_issue_tooltip i %></span>
-  </div>
-  <% else %>
-  <span class="icon icon-package">
-    <%= h("#{i.project} -") unless @project && @project == i.project %>
-    <%= link_to_version i%>
-  </span>
-  <% end %>
-<% end %>
-</td>
-<%= '</tr><tr>' if day.cwday==calendar.last_wday and day!=calendar.enddt %>
-<% day = day + 1
-end %>
-</tr>
-</tbody>
-</table>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bc/bc0bc495f28563c2bc2992c3db8742ac43b1ee5f.svn-base
--- a/.svn/pristine/bc/bc0bc495f28563c2bc2992c3db8742ac43b1ee5f.svn-base
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copy this file to additional_environment.rb and add any statements
-# that need to be passed to the Rails::Initializer.  `config` is
-# available in this context.
-#
-# Example:
-#
-#   config.log_level = :debug
-#   config.gem "example_plugin", :lib => false
-#   config.gem "timesheet_plugin", :lib => false, :version => '0.5.0'
-#   config.gem "aws-s3", :lib => "aws/s3"
-#   ...
-#
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bc/bc0c969dde0ae26fdb5eed30992ca79327b8efb8.svn-base
--- a/.svn/pristine/bc/bc0c969dde0ae26fdb5eed30992ca79327b8efb8.svn-base
+++ /dev/null
@@ -1,387 +0,0 @@
-# $Id: filter.rb 151 2006-08-15 08:34:53Z blackhedd $
-#
-#
-#----------------------------------------------------------------------------
-#
-# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
-#
-# Gmail: garbagecat10
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#---------------------------------------------------------------------------
-#
-#
-
-
-module Net
-class LDAP
-
-
-# Class Net::LDAP::Filter is used to constrain
-# LDAP searches. An object of this class is
-# passed to Net::LDAP#search in the parameter :filter.
-#
-# Net::LDAP::Filter supports the complete set of search filters
-# available in LDAP, including conjunction, disjunction and negation
-# (AND, OR, and NOT). This class supplants the (infamous) RFC-2254
-# standard notation for specifying LDAP search filters.
-#
-# Here's how to code the familiar "objectclass is present" filter:
-#  f = Net::LDAP::Filter.pres( "objectclass" )
-# The object returned by this code can be passed directly to
-# the <tt>:filter</tt> parameter of Net::LDAP#search.
-#
-# See the individual class and instance methods below for more examples.
-#
-class Filter
-
-  def initialize op, a, b
-    @op = op
-    @left = a
-    @right = b
-  end
-
-  # #eq creates a filter object indicating that the value of
-  # a paticular attribute must be either <i>present</i> or must
-  # match a particular string.
-  #
-  # To specify that an attribute is "present" means that only
-  # directory entries which contain a value for the particular
-  # attribute will be selected by the filter. This is useful
-  # in case of optional attributes such as <tt>mail.</tt>
-  # Presence is indicated by giving the value "*" in the second
-  # parameter to #eq. This example selects only entries that have
-  # one or more values for <tt>sAMAccountName:</tt>
-  #  f = Net::LDAP::Filter.eq( "sAMAccountName", "*" )
-  #
-  # To match a particular range of values, pass a string as the
-  # second parameter to #eq. The string may contain one or more
-  # "*" characters as wildcards: these match zero or more occurrences
-  # of any character. Full regular-expressions are <i>not</i> supported
-  # due to limitations in the underlying LDAP protocol.
-  # This example selects any entry with a <tt>mail</tt> value containing
-  # the substring "anderson":
-  #  f = Net::LDAP::Filter.eq( "mail", "*anderson*" )
-  #--
-  # Removed gt and lt. They ain't in the standard!
-  #
-  def Filter::eq attribute, value; Filter.new :eq, attribute, value; end
-  def Filter::ne attribute, value; Filter.new :ne, attribute, value; end
-  #def Filter::gt attribute, value; Filter.new :gt, attribute, value; end
-  #def Filter::lt attribute, value; Filter.new :lt, attribute, value; end
-  def Filter::ge attribute, value; Filter.new :ge, attribute, value; end
-  def Filter::le attribute, value; Filter.new :le, attribute, value; end
-
-  # #pres( attribute ) is a synonym for #eq( attribute, "*" )
-  #
-  def Filter::pres attribute; Filter.eq attribute, "*"; end
-
-  # operator & ("AND") is used to conjoin two or more filters.
-  # This expression will select only entries that have an <tt>objectclass</tt>
-  # attribute AND have a <tt>mail</tt> attribute that begins with "George":
-  #  f = Net::LDAP::Filter.pres( "objectclass" ) & Net::LDAP::Filter.eq( "mail", "George*" )
-  #
-  def & filter; Filter.new :and, self, filter; end
-
-  # operator | ("OR") is used to disjoin two or more filters.
-  # This expression will select entries that have either an <tt>objectclass</tt>
-  # attribute OR a <tt>mail</tt> attribute that begins with "George":
-  #  f = Net::LDAP::Filter.pres( "objectclass" ) | Net::LDAP::Filter.eq( "mail", "George*" )
-  #
-  def | filter; Filter.new :or, self, filter; end
-
-
-  #
-  # operator ~ ("NOT") is used to negate a filter.
-  # This expression will select only entries that <i>do not</i> have an <tt>objectclass</tt>
-  # attribute:
-  #  f = ~ Net::LDAP::Filter.pres( "objectclass" )
-  #
-  #--
-  # This operator can't be !, evidently. Try it.
-  # Removed GT and LT. They're not in the RFC.
-  def ~@; Filter.new :not, self, nil; end
-
-
-  def to_s
-    case @op
-    when :ne
-      "(!(#{@left}=#{@right}))"
-    when :eq
-      "(#{@left}=#{@right})"
-    #when :gt
-     # "#{@left}>#{@right}"
-    #when :lt
-     # "#{@left}<#{@right}"
-    when :ge
-      "#{@left}>=#{@right}"
-    when :le
-      "#{@left}<=#{@right}"
-    when :and
-      "(&(#{@left})(#{@right}))"
-    when :or
-      "(|(#{@left})(#{@right}))"
-    when :not
-      "(!(#{@left}))"
-    else
-      raise "invalid or unsupported operator in LDAP Filter"
-    end
-  end
-
-
-  #--
-  # to_ber
-  # Filter ::=
-  #     CHOICE {
-  #         and            [0] SET OF Filter,
-  #         or             [1] SET OF Filter,
-  #         not            [2] Filter,
-  #         equalityMatch  [3] AttributeValueAssertion,
-  #         substrings     [4] SubstringFilter,
-  #         greaterOrEqual [5] AttributeValueAssertion,
-  #         lessOrEqual    [6] AttributeValueAssertion,
-  #         present        [7] AttributeType,
-  #         approxMatch    [8] AttributeValueAssertion
-  #     }
-  #
-  # SubstringFilter
-  #     SEQUENCE {
-  #         type               AttributeType,
-  #         SEQUENCE OF CHOICE {
-  #             initial        [0] LDAPString,
-  #             any            [1] LDAPString,
-  #             final          [2] LDAPString
-  #         }
-  #     }
-  #
-  # Parsing substrings is a little tricky.
-  # We use the split method to break a string into substrings
-  # delimited by the * (star) character. But we also need
-  # to know whether there is a star at the head and tail
-  # of the string. A Ruby particularity comes into play here:
-  # if you split on * and the first character of the string is
-  # a star, then split will return an array whose first element
-  # is an _empty_ string. But if the _last_ character of the
-  # string is star, then split will return an array that does
-  # _not_ add an empty string at the end. So we have to deal
-  # with all that specifically.
-  #
-  def to_ber
-    case @op
-    when :eq
-      if @right == "*"          # present
-        @left.to_s.to_ber_contextspecific 7
-      elsif @right =~ /[\*]/    #substring
-        ary = @right.split( /[\*]+/ )
-        final_star = @right =~ /[\*]$/
-        initial_star = ary.first == "" and ary.shift
-
-        seq = []
-        unless initial_star
-          seq << ary.shift.to_ber_contextspecific(0)
-        end
-        n_any_strings = ary.length - (final_star ? 0 : 1)
-        #p n_any_strings
-        n_any_strings.times {
-          seq << ary.shift.to_ber_contextspecific(1)
-        }
-        unless final_star
-          seq << ary.shift.to_ber_contextspecific(2)
-        end
-        [@left.to_s.to_ber, seq.to_ber].to_ber_contextspecific 4
-      else                      #equality
-        [@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 3
-      end
-    when :ge
-      [@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 5
-    when :le
-      [@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 6
-    when :and
-      ary = [@left.coalesce(:and), @right.coalesce(:and)].flatten
-      ary.map {|a| a.to_ber}.to_ber_contextspecific( 0 )
-    when :or
-      ary = [@left.coalesce(:or), @right.coalesce(:or)].flatten
-      ary.map {|a| a.to_ber}.to_ber_contextspecific( 1 )
-    when :not
-        [@left.to_ber].to_ber_contextspecific 2
-    else
-      # ERROR, we'll return objectclass=* to keep things from blowing up,
-      # but that ain't a good answer and we need to kick out an error of some kind.
-      raise "unimplemented search filter"
-    end
-  end
-
-  #--
-  # coalesce
-  # This is a private helper method for dealing with chains of ANDs and ORs
-  # that are longer than two. If BOTH of our branches are of the specified
-  # type of joining operator, then return both of them as an array (calling
-  # coalesce recursively). If they're not, then return an array consisting
-  # only of self.
-  #
-  def coalesce operator
-    if @op == operator
-      [@left.coalesce( operator ), @right.coalesce( operator )]
-    else
-      [self]
-    end
-  end
-
-
-
-  #--
-  # We get a Ruby object which comes from parsing an RFC-1777 "Filter"
-  # object. Convert it to a Net::LDAP::Filter.
-  # TODO, we're hardcoding the RFC-1777 BER-encodings of the various
-  # filter types. Could pull them out into a constant.
-  #
-  def Filter::parse_ldap_filter obj
-    case obj.ber_identifier
-    when 0x87         # present. context-specific primitive 7.
-      Filter.eq( obj.to_s, "*" )
-    when 0xa3         # equalityMatch. context-specific constructed 3.
-      Filter.eq( obj[0], obj[1] )
-    else
-      raise LdapError.new( "unknown ldap search-filter type: #{obj.ber_identifier}" )
-    end
-  end
-
-
-  #--
-  # We got a hash of attribute values.
-  # Do we match the attributes?
-  # Return T/F, and call match recursively as necessary.
-  def match entry
-    case @op
-    when :eq
-      if @right == "*"
-        l = entry[@left] and l.length > 0
-      else
-        l = entry[@left] and l = l.to_a and l.index(@right)
-      end
-    else
-      raise LdapError.new( "unknown filter type in match: #{@op}" )
-    end
-  end
-
-  # Converts an LDAP filter-string (in the prefix syntax specified in RFC-2254)
-  # to a Net::LDAP::Filter.
-  def self.construct ldap_filter_string
-    FilterParser.new(ldap_filter_string).filter
-  end
-
-  # Synonym for #construct.
-  # to a Net::LDAP::Filter.
-  def self.from_rfc2254 ldap_filter_string
-    construct ldap_filter_string
-  end
-
-end # class Net::LDAP::Filter
-
-
-
-class FilterParser #:nodoc:
-
-  attr_reader :filter
-
-  def initialize str
-    require 'strscan'
-    @filter = parse( StringScanner.new( str )) or raise Net::LDAP::LdapError.new( "invalid filter syntax" )
-  end
-
-  def parse scanner
-    parse_filter_branch(scanner) or parse_paren_expression(scanner)
-  end
-
-  def parse_paren_expression scanner
-    if scanner.scan(/\s*\(\s*/)
-      b = if scanner.scan(/\s*\&\s*/)
-        a = nil
-        branches = []
-        while br = parse_paren_expression(scanner)
-          branches << br
-        end
-        if branches.length >= 2
-          a = branches.shift
-          while branches.length > 0
-            a = a & branches.shift
-          end
-          a
-        end
-      elsif scanner.scan(/\s*\|\s*/)
-        # TODO: DRY!
-        a = nil
-        branches = []
-        while br = parse_paren_expression(scanner)
-          branches << br
-        end
-        if branches.length >= 2
-          a = branches.shift
-          while branches.length > 0
-            a = a | branches.shift
-          end
-          a
-        end
-      elsif scanner.scan(/\s*\!\s*/)
-        br = parse_paren_expression(scanner)
-        if br
-          ~ br
-        end
-      else
-        parse_filter_branch( scanner )
-      end
-
-      if b and scanner.scan( /\s*\)\s*/ )
-        b
-      end
-    end
-  end
-
-  # Added a greatly-augmented filter contributed by Andre Nathan
-  # for detecting special characters in values. (15Aug06)
-  def parse_filter_branch scanner
-    scanner.scan(/\s*/)
-    if token = scanner.scan( /[\w\-_]+/ )
-      scanner.scan(/\s*/)
-      if op = scanner.scan( /\=|\<\=|\<|\>\=|\>|\!\=/ )
-        scanner.scan(/\s*/)
-        #if value = scanner.scan( /[\w\*\.]+/ ) (ORG)
-        if value = scanner.scan( /[\w\*\.\+\-@=#\$%&!]+/ )
-          case op
-          when "="
-            Filter.eq( token, value )
-          when "!="
-            Filter.ne( token, value )
-          when "<"
-            Filter.lt( token, value )
-          when "<="
-            Filter.le( token, value )
-          when ">"
-            Filter.gt( token, value )
-          when ">="
-            Filter.ge( token, value )
-          end
-        end
-      end
-    end
-  end
-
-end # class Net::LDAP::FilterParser
-
-end # class Net::LDAP
-end # module Net
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bc/bc6c8f57596923e6557efae3c8c80b8c20b03444.svn-base
--- /dev/null
+++ b/.svn/pristine/bc/bc6c8f57596923e6557efae3c8c80b8c20b03444.svn-base
@@ -0,0 +1,7 @@
+<div class="contextual">
+<%= link_to l(:button_update), edit_issue_path(@issue), :onclick => 'showAndScrollTo("update", "issue_notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit) if @issue.editable? %>
+<%= link_to l(:button_log_time), new_issue_time_entry_path(@issue), :class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project) %>
+<%= watcher_link(@issue, User.current) %>
+<%= link_to l(:button_copy), project_copy_issue_path(@project, @issue), :class => 'icon icon-copy' if User.current.allowed_to?(:add_issues, @project) %>
+<%= link_to l(:button_delete), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if User.current.allowed_to?(:delete_issues, @project) %>
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bc/bc77379f72c1c3054db92fc46067a164afd7381c.svn-base
--- a/.svn/pristine/bc/bc77379f72c1c3054db92fc46067a164afd7381c.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-<table class="list">
-  <thead><tr>
-    <th width="30%"><%=l(:field_name)%></th>
-    <th><%=l(:field_field_format)%></th>
-    <th><%=l(:field_is_required)%></th>
-    <% if tab[:name] == 'IssueCustomField' %>
-      <th><%=l(:field_is_for_all)%></th>
-      <th><%=l(:label_used_by)%></th>
-    <% end %>
-    <th><%=l(:button_sort)%></th>
-    <th width="10%"></th>
-  </tr></thead>
-  <tbody>
-  <% (@custom_fields_by_type[tab[:name]] || []).sort.each do |custom_field| -%>
-    <tr class="<%= cycle("odd", "even") %>">
-      <td><%= link_to h(custom_field.name), :action => 'edit', :id => custom_field %></td>
-      <td align="center"><%= l(Redmine::CustomFieldFormat.label_for(custom_field.field_format)) %></td>
-      <td align="center"><%= checked_image custom_field.is_required? %></td>
-      <% if tab[:name] == 'IssueCustomField' %>
-      <td align="center"><%= checked_image custom_field.is_for_all? %></td>
-      <td align="center"><%= l(:label_x_projects, :count => custom_field.projects.count) if custom_field.is_a? IssueCustomField and !custom_field.is_for_all? %></td>
-      <% end %>
-      <td align="center" style="width:15%;"><%= reorder_links('custom_field', {:action => 'edit', :id => custom_field}) %></td>
-      <td class="buttons">
-        <%= link_to(l(:button_delete), { :action => 'destroy', :id => custom_field },
-                                       :method => :post,
-                                       :confirm => l(:text_are_you_sure),
-                                       :class => 'icon icon-del') %>
-      </td>
-    </tr>
-  <% end; reset_cycle %>
-  </tbody>
-</table>
-
-<p><%= link_to l(:label_custom_field_new), {:action => 'new', :type => tab[:name]}, :class => 'icon icon-add' %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bc/bc80d541c6475644f6001e496712258a1420a78a.svn-base
--- a/.svn/pristine/bc/bc80d541c6475644f6001e496712258a1420a78a.svn-base
+++ /dev/null
@@ -1,24 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-desc 'Fetch changesets from the repositories'
-
-namespace :redmine do
-  task :fetch_changesets => :environment do
-    Repository.fetch_changesets
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bc/bc982db69a13b04b1b1a64088ae5e941fe3eac9c.svn-base
--- a/.svn/pristine/bc/bc982db69a13b04b1b1a64088ae5e941fe3eac9c.svn-base
+++ /dev/null
@@ -1,499 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class RepositoryGitTest < ActiveSupport::TestCase
-  fixtures :projects, :repositories, :enabled_modules, :users, :roles
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
-  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
-
-  NUM_REV = 21
-
-  FELIX_HEX  = "Felix Sch\xC3\xA4fer"
-  CHAR_1_HEX = "\xc3\x9c"
-
-  ## Ruby uses ANSI api to fork a process on Windows.
-  ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
-  ## and these are incompatible with ASCII.
-  # WINDOWS_PASS = Redmine::Platform.mswin?
-  WINDOWS_PASS = false
-
-  ## Git, Mercurial and CVS path encodings are binary.
-  ## Subversion supports URL encoding for path.
-  ## Redmine Mercurial adapter and extension use URL encoding.
-  ## Git accepts only binary path in command line parameter.
-  ## So, there is no way to use binary command line parameter in JRuby.
-  JRUBY_SKIP     = (RUBY_PLATFORM == 'java')
-  JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
-
-  if File.directory?(REPOSITORY_PATH)
-    def setup
-      klass = Repository::Git
-      assert_equal "Git", klass.scm_name
-      assert klass.scm_adapter_class
-      assert_not_equal "", klass.scm_command
-      assert_equal true, klass.scm_available
-
-      @project = Project.find(3)
-      @repository = Repository::Git.create(
-                        :project       => @project,
-                        :url           => REPOSITORY_PATH,
-                        :path_encoding => 'ISO-8859-1'
-                        )
-      assert @repository
-      @char_1        = CHAR_1_HEX.dup
-      if @char_1.respond_to?(:force_encoding)
-        @char_1.force_encoding('UTF-8')
-      end
-    end
-
-    def test_fetch_changesets_from_scratch
-      assert_nil @repository.extra_info
-
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_equal 33, @repository.changes.count
-
-      commit = @repository.changesets.find(:first, :order => 'committed_on ASC')
-      assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments
-      assert_equal "jsmith <jsmith@foo.bar>", commit.committer
-      assert_equal User.find_by_login('jsmith'), commit.user
-      # TODO: add a commit with commit time <> author time to the test repository
-      assert_equal "2007-12-14 09:22:52".to_time, commit.committed_on
-      assert_equal "2007-12-14".to_date, commit.commit_date
-      assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", commit.revision
-      assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", commit.scmid
-      assert_equal 3, commit.changes.count
-      change = commit.changes.sort_by(&:path).first
-      assert_equal "README", change.path
-      assert_equal "A", change.action
-
-      assert_equal 4, @repository.extra_info["branches"].size
-    end
-
-    def test_fetch_changesets_incremental
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_equal 33, @repository.changes.count
-      extra_info_db = @repository.extra_info["branches"]
-      assert_equal 4, extra_info_db.size
-      assert_equal "1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127",
-                    extra_info_db["latin-1-path-encoding"]["last_scmid"]
-      assert_equal "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
-                    extra_info_db["master"]["last_scmid"]
-
-      del_revs = [
-          "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
-          "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
-          "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
-          "deff712f05a90d96edbd70facc47d944be5897e3",
-          "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
-          "7e61ac704deecde634b51e59daa8110435dcb3da",
-         ]
-      @repository.changesets.each do |rev|
-        rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
-      end
-      @project.reload
-      cs1 = @repository.changesets
-      assert_equal 15, cs1.count
-      h = @repository.extra_info.dup
-      h["branches"]["master"]["last_scmid"] =
-            "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
-      @repository.merge_extra_info(h)
-      @repository.save
-      @project.reload
-      extra_info_db_1 = @repository.extra_info["branches"]
-      assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8",
-                    extra_info_db_1["master"]["last_scmid"]
-
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-    end
-
-    def test_fetch_changesets_invalid_rev
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      extra_info_db = @repository.extra_info["branches"]
-      assert_equal 4, extra_info_db.size
-      assert_equal "1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127",
-                    extra_info_db["latin-1-path-encoding"]["last_scmid"]
-      assert_equal "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
-                    extra_info_db["master"]["last_scmid"]
-
-      del_revs = [
-          "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
-          "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
-          "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
-          "deff712f05a90d96edbd70facc47d944be5897e3",
-          "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
-          "7e61ac704deecde634b51e59daa8110435dcb3da",
-         ]
-      @repository.changesets.each do |rev|
-        rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
-      end
-      @project.reload
-      cs1 = @repository.changesets
-      assert_equal 15, cs1.count
-      h = @repository.extra_info.dup
-      h["branches"]["master"]["last_scmid"] =
-            "abcd1234efgh"
-      @repository.merge_extra_info(h)
-      @repository.save
-      @project.reload
-      extra_info_db_1 = @repository.extra_info["branches"]
-      assert_equal "abcd1234efgh",
-                    extra_info_db_1["master"]["last_scmid"]
-
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal 15, @repository.changesets.count
-    end
-
-    def test_parents
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      r1 = @repository.find_changeset_by_name("7234cb2750b63")
-      assert_equal [], r1.parents
-      r2 = @repository.find_changeset_by_name("899a15dba03a3")
-      assert_equal 1, r2.parents.length
-      assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
-                   r2.parents[0].identifier
-      r3 = @repository.find_changeset_by_name("32ae898b720c2")
-      assert_equal 2, r3.parents.length
-      r4 = [r3.parents[0].identifier, r3.parents[1].identifier].sort
-      assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", r4[0]
-      assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da", r4[1]
-    end
-
-    def test_db_consistent_ordering_init
-      assert_nil @repository.extra_info
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal 1, @repository.extra_info["db_consistent"]["ordering"]
-    end
-
-    def test_db_consistent_ordering_before_1_2
-      assert_nil @repository.extra_info
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_not_nil @repository.extra_info
-      @repository.write_attribute(:extra_info, nil)
-      @repository.save
-      assert_nil @repository.extra_info
-      assert_equal NUM_REV, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
-
-      del_revs = [
-          "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
-          "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
-          "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
-          "deff712f05a90d96edbd70facc47d944be5897e3",
-          "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
-          "7e61ac704deecde634b51e59daa8110435dcb3da",
-         ]
-      @repository.changesets.each do |rev|
-        rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
-      end
-      @project.reload
-      cs1 = @repository.changesets
-      assert_equal 15, cs1.count
-      assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
-      h = @repository.extra_info.dup
-      h["branches"]["master"]["last_scmid"] =
-            "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
-      @repository.merge_extra_info(h)
-      @repository.save
-      @project.reload
-      extra_info_db_1 = @repository.extra_info["branches"]
-      assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8",
-                    extra_info_db_1["master"]["last_scmid"]
-
-      @repository.fetch_changesets
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
-    end
-
-    def test_latest_changesets
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      # with limit
-      changesets = @repository.latest_changesets('', nil, 2)
-      assert_equal 2, changesets.size
-
-      # with path
-      changesets = @repository.latest_changesets('images', nil)
-      assert_equal [
-              'deff712f05a90d96edbd70facc47d944be5897e3',
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-              '7234cb2750b63f47bff735edc50a1c0a433c2518',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README', nil)
-      assert_equal [
-              '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf',
-              '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8',
-              '713f4944648826f558cf548222f813dabe7cbb04',
-              '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-              '7234cb2750b63f47bff735edc50a1c0a433c2518',
-          ], changesets.collect(&:revision)
-
-      # with path, revision and limit
-      changesets = @repository.latest_changesets('images', '899a15dba')
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-              '7234cb2750b63f47bff735edc50a1c0a433c2518',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('images', '899a15dba', 1)
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README', '899a15dba')
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-              '7234cb2750b63f47bff735edc50a1c0a433c2518',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README', '899a15dba', 1)
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-          ], changesets.collect(&:revision)
-
-      # with path, tag and limit
-      changesets = @repository.latest_changesets('images', 'tag01.annotated')
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-              '7234cb2750b63f47bff735edc50a1c0a433c2518',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('images', 'tag01.annotated', 1)
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README', 'tag01.annotated')
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-              '7234cb2750b63f47bff735edc50a1c0a433c2518',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README', 'tag01.annotated', 1)
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-          ], changesets.collect(&:revision)
-
-      # with path, branch and limit
-      changesets = @repository.latest_changesets('images', 'test_branch')
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-              '7234cb2750b63f47bff735edc50a1c0a433c2518',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('images', 'test_branch', 1)
-      assert_equal [
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README', 'test_branch')
-      assert_equal [
-              '713f4944648826f558cf548222f813dabe7cbb04',
-              '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
-              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
-              '7234cb2750b63f47bff735edc50a1c0a433c2518',
-          ], changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README', 'test_branch', 2)
-      assert_equal [
-              '713f4944648826f558cf548222f813dabe7cbb04',
-              '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
-          ], changesets.collect(&:revision)
-
-      if JRUBY_SKIP
-        puts JRUBY_SKIP_STR
-      else
-        # latin-1 encoding path
-        changesets = @repository.latest_changesets(
-                      "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89')
-        assert_equal [
-              '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
-              '4fc55c43bf3d3dc2efb66145365ddc17639ce81e',
-          ], changesets.collect(&:revision)
-
-        changesets = @repository.latest_changesets(
-                    "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89', 1)
-        assert_equal [
-              '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
-          ], changesets.collect(&:revision)
-      end
-    end
-
-    def test_latest_changesets_latin_1_dir
-      if WINDOWS_PASS
-        #
-      elsif JRUBY_SKIP
-        puts JRUBY_SKIP_STR
-      else
-        assert_equal 0, @repository.changesets.count
-        @repository.fetch_changesets
-        @project.reload
-        assert_equal NUM_REV, @repository.changesets.count
-        changesets = @repository.latest_changesets(
-                    "latin-1-dir/test-#{@char_1}-subdir", '1ca7f5ed')
-        assert_equal [
-              '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127',
-          ], changesets.collect(&:revision)
-      end
-    end
-
-    def test_find_changeset_by_name
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['7234cb2750b63f47bff735edc50a1c0a433c2518', '7234cb2750b'].each do |r|
-        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518',
-                     @repository.find_changeset_by_name(r).revision
-      end
-    end
-
-    def test_find_changeset_by_empty_name
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['', ' ', nil].each do |r|
-        assert_nil @repository.find_changeset_by_name(r)
-      end
-    end
-
-    def test_identifier
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      c = @repository.changesets.find_by_revision(
-                          '7234cb2750b63f47bff735edc50a1c0a433c2518')
-      assert_equal c.scmid, c.identifier
-    end
-
-    def test_format_identifier
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      c = @repository.changesets.find_by_revision(
-                          '7234cb2750b63f47bff735edc50a1c0a433c2518')
-      assert_equal '7234cb27', c.format_identifier
-    end
-
-    def test_activities
-      c = Changeset.new(:repository => @repository,
-                        :committed_on => Time.now,
-                        :revision => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
-                        :scmid    => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
-                        :comments => 'test')
-      assert c.event_title.include?('abc7234c:')
-      assert_equal 'abc7234cb2750b63f47bff735edc50a1c0a433c2', c.event_url[:rev]
-    end
-
-    def test_log_utf8
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      str_felix_hex  = FELIX_HEX.dup
-      if str_felix_hex.respond_to?(:force_encoding)
-          str_felix_hex.force_encoding('UTF-8')
-      end
-      c = @repository.changesets.find_by_revision(
-                        'ed5bb786bbda2dee66a2d50faf51429dbc043a7b')
-      assert_equal "#{str_felix_hex} <felix@fachschaften.org>", c.committer
-    end
-
-    def test_previous
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
-        changeset = @repository.find_changeset_by_name(r1)
-        %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
-          assert_equal @repository.find_changeset_by_name(r2), changeset.previous
-        end
-      end
-    end
-
-    def test_previous_nil
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      %w|7234cb2750b63f47bff735edc50a1c0a433c2518 7234cb2|.each do |r1|
-        changeset = @repository.find_changeset_by_name(r1)
-        assert_nil changeset.previous
-      end
-    end
-
-    def test_next
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
-        changeset = @repository.find_changeset_by_name(r2)
-        %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
-        assert_equal @repository.find_changeset_by_name(r1), changeset.next
-        end
-      end
-    end
-
-    def test_next_nil
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      %w|67e7792ce20ccae2e4bb73eed09bb397819c8834 67e7792ce20cca|.each do |r1|
-        changeset = @repository.find_changeset_by_name(r1)
-        assert_nil changeset.next
-      end
-    end
-  else
-    puts "Git test repository NOT FOUND. Skipping unit tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bc/bca7a91b92854552085eb74f2cd0489d2e2f6423.svn-base
--- a/.svn/pristine/bc/bca7a91b92854552085eb74f2cd0489d2e2f6423.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class WikiRedirect < ActiveRecord::Base
-  belongs_to :wiki
-
-  validates_presence_of :title, :redirects_to
-  validates_length_of :title, :redirects_to, :maximum => 255
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bc/bcb08a380a912688504e27334c28309a609ac626.svn-base
--- a/.svn/pristine/bc/bcb08a380a912688504e27334c28309a609ac626.svn-base
+++ /dev/null
@@ -1,36 +0,0 @@
---- 
-journals_001: 
-  created_on: <%= 2.days.ago.to_date.to_s(:db) %>
-  notes: "Journal notes"
-  id: 1
-  journalized_type: Issue
-  user_id: 1
-  journalized_id: 1
-journals_002: 
-  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
-  notes: "Some notes with Redmine links: #2, r2."
-  id: 2
-  journalized_type: Issue
-  user_id: 2
-  journalized_id: 1
-journals_003: 
-  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
-  notes: "A comment with inline image: !picture.jpg!"
-  id: 3
-  journalized_type: Issue
-  user_id: 2
-  journalized_id: 2
-journals_004: 
-  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
-  notes: "A comment with a private version."
-  id: 4
-  journalized_type: Issue
-  user_id: 1
-  journalized_id: 6
-journals_005: 
-  id: 5
-  created_on: <%= 1.days.ago.to_date.to_s(:db) %>
-  notes: "A comment on a private issue."
-  user_id: 2
-  journalized_type: Issue
-  journalized_id: 14
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bc/bcfa9d438ab075834f07a24d5350ce45aa5386bc.svn-base
--- /dev/null
+++ b/.svn/pristine/bc/bcfa9d438ab075834f07a24d5350ce45aa5386bc.svn-base
@@ -0,0 +1,86 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class SortHelperTest < ActionView::TestCase
+  include SortHelper
+  include ERB::Util
+
+  def setup
+    @session = nil
+    @sort_param = nil
+  end
+
+  def test_default_sort_clause_with_array
+    sort_init 'attr1', 'desc'
+    sort_update(['attr1', 'attr2'])
+
+    assert_equal ['attr1 DESC'], sort_clause
+  end
+
+  def test_default_sort_clause_with_hash
+    sort_init 'attr1', 'desc'
+    sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
+
+    assert_equal ['table1.attr1 DESC'], sort_clause
+  end
+
+  def test_default_sort_clause_with_multiple_columns
+    sort_init 'attr1', 'desc'
+    sort_update({'attr1' => ['table1.attr1', 'table1.attr2'], 'attr2' => 'table2.attr2'})
+
+    assert_equal ['table1.attr1 DESC', 'table1.attr2 DESC'], sort_clause
+  end
+
+  def test_params_sort
+    @sort_param = 'attr1,attr2:desc'
+
+    sort_init 'attr1', 'desc'
+    sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
+
+    assert_equal ['table1.attr1', 'table2.attr2 DESC'], sort_clause
+    assert_equal 'attr1,attr2:desc', @session['foo_bar_sort']
+  end
+
+  def test_invalid_params_sort
+    @sort_param = 'invalid_key'
+
+    sort_init 'attr1', 'desc'
+    sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
+
+    assert_equal ['table1.attr1 DESC'], sort_clause
+    assert_equal 'attr1:desc', @session['foo_bar_sort']
+  end
+
+  def test_invalid_order_params_sort
+    @sort_param = 'attr1:foo:bar,attr2'
+
+    sort_init 'attr1', 'desc'
+    sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
+
+    assert_equal ['table1.attr1', 'table2.attr2'], sort_clause
+    assert_equal 'attr1,attr2', @session['foo_bar_sort']
+  end
+
+  private
+
+  def controller_name; 'foo'; end
+  def action_name; 'bar'; end
+  def params; {:sort => @sort_param}; end
+  def session; @session ||= {}; end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bd/bd00588170200c1a584eeedf772a99216b774e3a.svn-base
--- /dev/null
+++ b/.svn/pristine/bd/bd00588170200c1a584eeedf772a99216b774e3a.svn-base
@@ -0,0 +1,9 @@
+class UpdateQueriesToSti < ActiveRecord::Migration
+  def up
+    ::Query.update_all :type => 'IssueQuery'
+  end
+
+  def down
+    ::Query.update_all :type => nil
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bd/bd14f74ff8fe3ceb6d84b4dbead570fb4b8e960a.svn-base
--- /dev/null
+++ b/.svn/pristine/bd/bd14f74ff8fe3ceb6d84b4dbead570fb4b8e960a.svn-base
@@ -0,0 +1,68 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../../test_helper', __FILE__)
+
+class FilesystemAdapterTest < ActiveSupport::TestCase
+  REPOSITORY_PATH = Rails.root.join('tmp/test/filesystem_repository').to_s
+
+  if File.directory?(REPOSITORY_PATH)
+    def setup
+      @adapter = Redmine::Scm::Adapters::FilesystemAdapter.new(REPOSITORY_PATH)
+    end
+
+    def test_entries
+      assert_equal 3, @adapter.entries.size
+      assert_equal ["dir", "japanese", "test"], @adapter.entries.collect(&:name)
+      assert_equal ["dir", "japanese", "test"], @adapter.entries(nil).collect(&:name)
+      assert_equal ["dir", "japanese", "test"], @adapter.entries("/").collect(&:name)
+      ["dir", "/dir", "/dir/", "dir/"].each do |path|
+        assert_equal ["subdir", "dirfile"], @adapter.entries(path).collect(&:name)
+      end
+      # If y try to use "..", the path is ignored
+      ["/../","dir/../", "..", "../", "/..", "dir/.."].each do |path|
+        assert_equal ["dir", "japanese", "test"], @adapter.entries(path).collect(&:name),
+             ".. must be ignored in path argument"
+      end
+    end
+
+    def test_cat
+      assert_equal "TEST CAT\n", @adapter.cat("test")
+      assert_equal "TEST CAT\n", @adapter.cat("/test")
+      # Revision number is ignored
+      assert_equal "TEST CAT\n", @adapter.cat("/test", 1)
+    end
+
+    def test_path_encoding_default_utf8
+      adpt1 = Redmine::Scm::Adapters::FilesystemAdapter.new(
+                                  REPOSITORY_PATH
+                                )
+      assert_equal "UTF-8", adpt1.path_encoding
+      adpt2 = Redmine::Scm::Adapters::FilesystemAdapter.new(
+                                  REPOSITORY_PATH,
+                                  nil,
+                                  nil,
+                                  nil,
+                                  ""
+                                )
+      assert_equal "UTF-8", adpt2.path_encoding
+    end
+  else
+    puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bd/bd3924b39d6ae670e2c3a78de4733fbc67a0e993.svn-base
--- a/.svn/pristine/bd/bd3924b39d6ae670e2c3a78de4733fbc67a0e993.svn-base
+++ /dev/null
@@ -1,421 +0,0 @@
-module CodeRay
-module Scanners
-  
-  module Java::BuiltinTypes  # :nodoc:
-    
-    #:nocov:
-    List = %w[
-      AbstractAction AbstractBorder AbstractButton AbstractCellEditor AbstractCollection
-      AbstractColorChooserPanel AbstractDocument AbstractExecutorService AbstractInterruptibleChannel
-      AbstractLayoutCache AbstractList AbstractListModel AbstractMap AbstractMethodError AbstractPreferences
-      AbstractQueue AbstractQueuedSynchronizer AbstractSelectableChannel AbstractSelectionKey AbstractSelector
-      AbstractSequentialList AbstractSet AbstractSpinnerModel AbstractTableModel AbstractUndoableEdit
-      AbstractWriter AccessControlContext AccessControlException AccessController AccessException Accessible
-      AccessibleAction AccessibleAttributeSequence AccessibleBundle AccessibleComponent AccessibleContext
-      AccessibleEditableText AccessibleExtendedComponent AccessibleExtendedTable AccessibleExtendedText
-      AccessibleHyperlink AccessibleHypertext AccessibleIcon AccessibleKeyBinding AccessibleObject
-      AccessibleRelation AccessibleRelationSet AccessibleResourceBundle AccessibleRole AccessibleSelection
-      AccessibleState AccessibleStateSet AccessibleStreamable AccessibleTable AccessibleTableModelChange
-      AccessibleText AccessibleTextSequence AccessibleValue AccountException AccountExpiredException
-      AccountLockedException AccountNotFoundException Acl AclEntry AclNotFoundException Action ActionEvent
-      ActionListener ActionMap ActionMapUIResource Activatable ActivateFailedException ActivationDesc
-      ActivationException ActivationGroup ActivationGroupDesc ActivationGroupID ActivationGroup_Stub
-      ActivationID ActivationInstantiator ActivationMonitor ActivationSystem Activator ActiveEvent
-      ActivityCompletedException ActivityRequiredException Adjustable AdjustmentEvent AdjustmentListener
-      Adler32 AffineTransform AffineTransformOp AlgorithmParameterGenerator AlgorithmParameterGeneratorSpi
-      AlgorithmParameters AlgorithmParameterSpec AlgorithmParametersSpi AllPermission AlphaComposite
-      AlreadyBoundException AlreadyConnectedException AncestorEvent AncestorListener AnnotatedElement
-      Annotation AnnotationFormatError AnnotationTypeMismatchException AppConfigurationEntry Appendable Applet
-      AppletContext AppletInitializer AppletStub Arc2D Area AreaAveragingScaleFilter ArithmeticException Array
-      ArrayBlockingQueue ArrayIndexOutOfBoundsException ArrayList Arrays ArrayStoreException ArrayType
-      AssertionError AsyncBoxView AsynchronousCloseException AtomicBoolean AtomicInteger AtomicIntegerArray
-      AtomicIntegerFieldUpdater AtomicLong AtomicLongArray AtomicLongFieldUpdater AtomicMarkableReference
-      AtomicReference AtomicReferenceArray AtomicReferenceFieldUpdater AtomicStampedReference Attribute
-      AttributeChangeNotification AttributeChangeNotificationFilter AttributedCharacterIterator
-      AttributedString AttributeException AttributeInUseException AttributeList AttributeModificationException
-      AttributeNotFoundException Attributes AttributeSet AttributeSetUtilities AttributeValueExp AudioClip
-      AudioFileFormat AudioFileReader AudioFileWriter AudioFormat AudioInputStream AudioPermission AudioSystem
-      AuthenticationException AuthenticationNotSupportedException Authenticator AuthorizeCallback
-      AuthPermission AuthProvider Autoscroll AWTError AWTEvent AWTEventListener AWTEventListenerProxy
-      AWTEventMulticaster AWTException AWTKeyStroke AWTPermission BackingStoreException
-      BadAttributeValueExpException BadBinaryOpValueExpException BadLocationException BadPaddingException
-      BadStringOperationException BandCombineOp BandedSampleModel BaseRowSet BasicArrowButton BasicAttribute
-      BasicAttributes BasicBorders BasicButtonListener BasicButtonUI BasicCheckBoxMenuItemUI BasicCheckBoxUI
-      BasicColorChooserUI BasicComboBoxEditor BasicComboBoxRenderer BasicComboBoxUI BasicComboPopup
-      BasicControl BasicDesktopIconUI BasicDesktopPaneUI BasicDirectoryModel BasicEditorPaneUI
-      BasicFileChooserUI BasicFormattedTextFieldUI BasicGraphicsUtils BasicHTML BasicIconFactory
-      BasicInternalFrameTitlePane BasicInternalFrameUI BasicLabelUI BasicListUI BasicLookAndFeel
-      BasicMenuBarUI BasicMenuItemUI BasicMenuUI BasicOptionPaneUI BasicPanelUI BasicPasswordFieldUI
-      BasicPermission BasicPopupMenuSeparatorUI BasicPopupMenuUI BasicProgressBarUI BasicRadioButtonMenuItemUI
-      BasicRadioButtonUI BasicRootPaneUI BasicScrollBarUI BasicScrollPaneUI BasicSeparatorUI BasicSliderUI
-      BasicSpinnerUI BasicSplitPaneDivider BasicSplitPaneUI BasicStroke BasicTabbedPaneUI BasicTableHeaderUI
-      BasicTableUI BasicTextAreaUI BasicTextFieldUI BasicTextPaneUI BasicTextUI BasicToggleButtonUI
-      BasicToolBarSeparatorUI BasicToolBarUI BasicToolTipUI BasicTreeUI BasicViewportUI BatchUpdateException
-      BeanContext BeanContextChild BeanContextChildComponentProxy BeanContextChildSupport
-      BeanContextContainerProxy BeanContextEvent BeanContextMembershipEvent BeanContextMembershipListener
-      BeanContextProxy BeanContextServiceAvailableEvent BeanContextServiceProvider
-      BeanContextServiceProviderBeanInfo BeanContextServiceRevokedEvent BeanContextServiceRevokedListener
-      BeanContextServices BeanContextServicesListener BeanContextServicesSupport BeanContextSupport
-      BeanDescriptor BeanInfo Beans BevelBorder Bidi BigDecimal BigInteger BinaryRefAddr BindException Binding
-      BitSet Blob BlockingQueue BlockView BMPImageWriteParam Book Boolean BooleanControl Border BorderFactory
-      BorderLayout BorderUIResource BoundedRangeModel Box BoxLayout BoxView BreakIterator
-      BrokenBarrierException Buffer BufferCapabilities BufferedImage BufferedImageFilter BufferedImageOp
-      BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter BufferOverflowException
-      BufferStrategy BufferUnderflowException Button ButtonGroup ButtonModel ButtonUI Byte
-      ByteArrayInputStream ByteArrayOutputStream ByteBuffer ByteChannel ByteLookupTable ByteOrder CachedRowSet
-      CacheRequest CacheResponse Calendar Callable CallableStatement Callback CallbackHandler
-      CancelablePrintJob CancellationException CancelledKeyException CannotProceedException
-      CannotRedoException CannotUndoException Canvas CardLayout Caret CaretEvent CaretListener CellEditor
-      CellEditorListener CellRendererPane Certificate CertificateEncodingException CertificateException
-      CertificateExpiredException CertificateFactory CertificateFactorySpi CertificateNotYetValidException
-      CertificateParsingException CertPath CertPathBuilder CertPathBuilderException CertPathBuilderResult
-      CertPathBuilderSpi CertPathParameters CertPathTrustManagerParameters CertPathValidator
-      CertPathValidatorException CertPathValidatorResult CertPathValidatorSpi CertSelector CertStore
-      CertStoreException CertStoreParameters CertStoreSpi ChangedCharSetException ChangeEvent ChangeListener
-      Channel Channels Character CharacterCodingException CharacterIterator CharArrayReader CharArrayWriter
-      CharBuffer CharConversionException CharSequence Charset CharsetDecoder CharsetEncoder CharsetProvider
-      Checkbox CheckboxGroup CheckboxMenuItem CheckedInputStream CheckedOutputStream Checksum Choice
-      ChoiceCallback ChoiceFormat Chromaticity Cipher CipherInputStream CipherOutputStream CipherSpi Class
-      ClassCastException ClassCircularityError ClassDefinition ClassDesc ClassFileTransformer ClassFormatError
-      ClassLoader ClassLoaderRepository ClassLoadingMXBean ClassNotFoundException Clip Clipboard
-      ClipboardOwner Clob Cloneable CloneNotSupportedException Closeable ClosedByInterruptException
-      ClosedChannelException ClosedSelectorException CMMException CoderMalfunctionError CoderResult CodeSigner
-      CodeSource CodingErrorAction CollationElementIterator CollationKey Collator Collection
-      CollectionCertStoreParameters Collections Color ColorChooserComponentFactory ColorChooserUI
-      ColorConvertOp ColorModel ColorSelectionModel ColorSpace ColorSupported ColorType ColorUIResource
-      ComboBoxEditor ComboBoxModel ComboBoxUI ComboPopup CommunicationException Comparable Comparator
-      CompilationMXBean Compiler CompletionService Component ComponentAdapter ComponentColorModel
-      ComponentEvent ComponentInputMap ComponentInputMapUIResource ComponentListener ComponentOrientation
-      ComponentSampleModel ComponentUI ComponentView Composite CompositeContext CompositeData
-      CompositeDataSupport CompositeName CompositeType CompositeView CompoundBorder CompoundControl
-      CompoundEdit CompoundName Compression ConcurrentHashMap ConcurrentLinkedQueue ConcurrentMap
-      ConcurrentModificationException Condition Configuration ConfigurationException ConfirmationCallback
-      ConnectException ConnectIOException Connection ConnectionEvent ConnectionEventListener
-      ConnectionPendingException ConnectionPoolDataSource ConsoleHandler Constructor Container
-      ContainerAdapter ContainerEvent ContainerListener ContainerOrderFocusTraversalPolicy ContentHandler
-      ContentHandlerFactory ContentModel Context ContextNotEmptyException ContextualRenderedImageFactory
-      Control ControlFactory ControllerEventListener ConvolveOp CookieHandler Copies CopiesSupported
-      CopyOnWriteArrayList CopyOnWriteArraySet CountDownLatch CounterMonitor CounterMonitorMBean CRC32
-      CredentialException CredentialExpiredException CredentialNotFoundException CRL CRLException CRLSelector
-      CropImageFilter CSS CubicCurve2D Currency Cursor Customizer CyclicBarrier DatabaseMetaData DataBuffer
-      DataBufferByte DataBufferDouble DataBufferFloat DataBufferInt DataBufferShort DataBufferUShort
-      DataFlavor DataFormatException DatagramChannel DatagramPacket DatagramSocket DatagramSocketImpl
-      DatagramSocketImplFactory DataInput DataInputStream DataLine DataOutput DataOutputStream DataSource
-      DataTruncation DatatypeConfigurationException DatatypeConstants DatatypeFactory Date DateFormat
-      DateFormatSymbols DateFormatter DateTimeAtCompleted DateTimeAtCreation DateTimeAtProcessing
-      DateTimeSyntax DebugGraphics DecimalFormat DecimalFormatSymbols DefaultBoundedRangeModel
-      DefaultButtonModel DefaultCaret DefaultCellEditor DefaultColorSelectionModel DefaultComboBoxModel
-      DefaultDesktopManager DefaultEditorKit DefaultFocusManager DefaultFocusTraversalPolicy DefaultFormatter
-      DefaultFormatterFactory DefaultHighlighter DefaultKeyboardFocusManager DefaultListCellRenderer
-      DefaultListModel DefaultListSelectionModel DefaultLoaderRepository DefaultMenuLayout DefaultMetalTheme
-      DefaultMutableTreeNode DefaultPersistenceDelegate DefaultSingleSelectionModel DefaultStyledDocument
-      DefaultTableCellRenderer DefaultTableColumnModel DefaultTableModel DefaultTextUI DefaultTreeCellEditor
-      DefaultTreeCellRenderer DefaultTreeModel DefaultTreeSelectionModel Deflater DeflaterOutputStream Delayed
-      DelayQueue DelegationPermission Deprecated Descriptor DescriptorAccess DescriptorSupport DESedeKeySpec
-      DesignMode DESKeySpec DesktopIconUI DesktopManager DesktopPaneUI Destination Destroyable
-      DestroyFailedException DGC DHGenParameterSpec DHKey DHParameterSpec DHPrivateKey DHPrivateKeySpec
-      DHPublicKey DHPublicKeySpec Dialog Dictionary DigestException DigestInputStream DigestOutputStream
-      Dimension Dimension2D DimensionUIResource DirContext DirectColorModel DirectoryManager DirObjectFactory
-      DirStateFactory DisplayMode DnDConstants Doc DocAttribute DocAttributeSet DocFlavor DocPrintJob Document
-      DocumentBuilder DocumentBuilderFactory Documented DocumentEvent DocumentFilter DocumentListener
-      DocumentName DocumentParser DomainCombiner DOMLocator DOMResult DOMSource Double DoubleBuffer
-      DragGestureEvent DragGestureListener DragGestureRecognizer DragSource DragSourceAdapter
-      DragSourceContext DragSourceDragEvent DragSourceDropEvent DragSourceEvent DragSourceListener
-      DragSourceMotionListener Driver DriverManager DriverPropertyInfo DropTarget DropTargetAdapter
-      DropTargetContext DropTargetDragEvent DropTargetDropEvent DropTargetEvent DropTargetListener DSAKey
-      DSAKeyPairGenerator DSAParameterSpec DSAParams DSAPrivateKey DSAPrivateKeySpec DSAPublicKey
-      DSAPublicKeySpec DTD DTDConstants DuplicateFormatFlagsException Duration DynamicMBean ECField ECFieldF2m
-      ECFieldFp ECGenParameterSpec ECKey ECParameterSpec ECPoint ECPrivateKey ECPrivateKeySpec ECPublicKey
-      ECPublicKeySpec EditorKit Element ElementIterator ElementType Ellipse2D EllipticCurve EmptyBorder
-      EmptyStackException EncodedKeySpec Encoder EncryptedPrivateKeyInfo Entity Enum
-      EnumConstantNotPresentException EnumControl Enumeration EnumMap EnumSet EnumSyntax EOFException Error
-      ErrorListener ErrorManager EtchedBorder Event EventContext EventDirContext EventHandler EventListener
-      EventListenerList EventListenerProxy EventObject EventQueue EventSetDescriptor Exception
-      ExceptionInInitializerError ExceptionListener Exchanger ExecutionException Executor
-      ExecutorCompletionService Executors ExecutorService ExemptionMechanism ExemptionMechanismException
-      ExemptionMechanismSpi ExpandVetoException ExportException Expression ExtendedRequest ExtendedResponse
-      Externalizable FactoryConfigurationError FailedLoginException FeatureDescriptor Fidelity Field
-      FieldPosition FieldView File FileCacheImageInputStream FileCacheImageOutputStream FileChannel
-      FileChooserUI FileDescriptor FileDialog FileFilter FileHandler FileImageInputStream
-      FileImageOutputStream FileInputStream FileLock FileLockInterruptionException FilenameFilter FileNameMap
-      FileNotFoundException FileOutputStream FilePermission FileReader FileSystemView FileView FileWriter
-      Filter FilteredImageSource FilteredRowSet FilterInputStream FilterOutputStream FilterReader FilterWriter
-      Finishings FixedHeightLayoutCache FlatteningPathIterator FlavorEvent FlavorException FlavorListener
-      FlavorMap FlavorTable Float FloatBuffer FloatControl FlowLayout FlowView Flushable FocusAdapter
-      FocusEvent FocusListener FocusManager FocusTraversalPolicy Font FontFormatException FontMetrics
-      FontRenderContext FontUIResource Format FormatConversionProvider FormatFlagsConversionMismatchException
-      Formattable FormattableFlags Formatter FormatterClosedException FormSubmitEvent FormView Frame Future
-      FutureTask GapContent GarbageCollectorMXBean GatheringByteChannel GaugeMonitor GaugeMonitorMBean
-      GeneralPath GeneralSecurityException GenericArrayType GenericDeclaration GenericSignatureFormatError
-      GlyphJustificationInfo GlyphMetrics GlyphVector GlyphView GradientPaint GraphicAttribute Graphics
-      Graphics2D GraphicsConfigTemplate GraphicsConfiguration GraphicsDevice GraphicsEnvironment GrayFilter
-      GregorianCalendar GridBagConstraints GridBagLayout GridLayout Group Guard GuardedObject GZIPInputStream
-      GZIPOutputStream Handler HandshakeCompletedEvent HandshakeCompletedListener HasControls HashAttributeSet
-      HashDocAttributeSet HashMap HashPrintJobAttributeSet HashPrintRequestAttributeSet
-      HashPrintServiceAttributeSet HashSet Hashtable HeadlessException HierarchyBoundsAdapter
-      HierarchyBoundsListener HierarchyEvent HierarchyListener Highlighter HostnameVerifier HTML HTMLDocument
-      HTMLEditorKit HTMLFrameHyperlinkEvent HTMLWriter HttpRetryException HttpsURLConnection HttpURLConnection
-      HyperlinkEvent HyperlinkListener ICC_ColorSpace ICC_Profile ICC_ProfileGray ICC_ProfileRGB Icon
-      IconUIResource IconView Identity IdentityHashMap IdentityScope IIOByteBuffer IIOException IIOImage
-      IIOInvalidTreeException IIOMetadata IIOMetadataController IIOMetadataFormat IIOMetadataFormatImpl
-      IIOMetadataNode IIOParam IIOParamController IIOReadProgressListener IIOReadUpdateListener
-      IIOReadWarningListener IIORegistry IIOServiceProvider IIOWriteProgressListener IIOWriteWarningListener
-      IllegalAccessError IllegalAccessException IllegalArgumentException IllegalBlockingModeException
-      IllegalBlockSizeException IllegalCharsetNameException IllegalClassFormatException
-      IllegalComponentStateException IllegalFormatCodePointException IllegalFormatConversionException
-      IllegalFormatException IllegalFormatFlagsException IllegalFormatPrecisionException
-      IllegalFormatWidthException IllegalMonitorStateException IllegalPathStateException
-      IllegalSelectorException IllegalStateException IllegalThreadStateException Image ImageCapabilities
-      ImageConsumer ImageFilter ImageGraphicAttribute ImageIcon ImageInputStream ImageInputStreamImpl
-      ImageInputStreamSpi ImageIO ImageObserver ImageOutputStream ImageOutputStreamImpl ImageOutputStreamSpi
-      ImageProducer ImageReader ImageReaderSpi ImageReaderWriterSpi ImageReadParam ImageTranscoder
-      ImageTranscoderSpi ImageTypeSpecifier ImageView ImageWriteParam ImageWriter ImageWriterSpi
-      ImagingOpException IncompatibleClassChangeError IncompleteAnnotationException IndexColorModel
-      IndexedPropertyChangeEvent IndexedPropertyDescriptor IndexOutOfBoundsException Inet4Address Inet6Address
-      InetAddress InetSocketAddress Inflater InflaterInputStream InheritableThreadLocal Inherited
-      InitialContext InitialContextFactory InitialContextFactoryBuilder InitialDirContext InitialLdapContext
-      InlineView InputContext InputEvent InputMap InputMapUIResource InputMethod InputMethodContext
-      InputMethodDescriptor InputMethodEvent InputMethodHighlight InputMethodListener InputMethodRequests
-      InputMismatchException InputStream InputStreamReader InputSubset InputVerifier Insets InsetsUIResource
-      InstanceAlreadyExistsException InstanceNotFoundException InstantiationError InstantiationException
-      Instrument Instrumentation InsufficientResourcesException IntBuffer Integer IntegerSyntax InternalError
-      InternalFrameAdapter InternalFrameEvent InternalFrameFocusTraversalPolicy InternalFrameListener
-      InternalFrameUI InternationalFormatter InterruptedException InterruptedIOException
-      InterruptedNamingException InterruptibleChannel IntrospectionException Introspector
-      InvalidActivityException InvalidAlgorithmParameterException InvalidApplicationException
-      InvalidAttributeIdentifierException InvalidAttributesException InvalidAttributeValueException
-      InvalidClassException InvalidDnDOperationException InvalidKeyException InvalidKeySpecException
-      InvalidMarkException InvalidMidiDataException InvalidNameException InvalidObjectException
-      InvalidOpenTypeException InvalidParameterException InvalidParameterSpecException
-      InvalidPreferencesFormatException InvalidPropertiesFormatException InvalidRelationIdException
-      InvalidRelationServiceException InvalidRelationTypeException InvalidRoleInfoException
-      InvalidRoleValueException InvalidSearchControlsException InvalidSearchFilterException
-      InvalidTargetObjectTypeException InvalidTransactionException InvocationEvent InvocationHandler
-      InvocationTargetException IOException ItemEvent ItemListener ItemSelectable Iterable Iterator
-      IvParameterSpec JApplet JarEntry JarException JarFile JarInputStream JarOutputStream JarURLConnection
-      JButton JCheckBox JCheckBoxMenuItem JColorChooser JComboBox JComponent JdbcRowSet JDesktopPane JDialog
-      JEditorPane JFileChooser JFormattedTextField JFrame JInternalFrame JLabel JLayeredPane JList JMenu
-      JMenuBar JMenuItem JMException JMRuntimeException JMXAuthenticator JMXConnectionNotification
-      JMXConnector JMXConnectorFactory JMXConnectorProvider JMXConnectorServer JMXConnectorServerFactory
-      JMXConnectorServerMBean JMXConnectorServerProvider JMXPrincipal JMXProviderException
-      JMXServerErrorException JMXServiceURL JobAttributes JobHoldUntil JobImpressions JobImpressionsCompleted
-      JobImpressionsSupported JobKOctets JobKOctetsProcessed JobKOctetsSupported JobMediaSheets
-      JobMediaSheetsCompleted JobMediaSheetsSupported JobMessageFromOperator JobName JobOriginatingUserName
-      JobPriority JobPrioritySupported JobSheets JobState JobStateReason JobStateReasons Joinable JoinRowSet
-      JOptionPane JPanel JPasswordField JPEGHuffmanTable JPEGImageReadParam JPEGImageWriteParam JPEGQTable
-      JPopupMenu JProgressBar JRadioButton JRadioButtonMenuItem JRootPane JScrollBar JScrollPane JSeparator
-      JSlider JSpinner JSplitPane JTabbedPane JTable JTableHeader JTextArea JTextComponent JTextField
-      JTextPane JToggleButton JToolBar JToolTip JTree JViewport JWindow KerberosKey KerberosPrincipal
-      KerberosTicket Kernel Key KeyAdapter KeyAgreement KeyAgreementSpi KeyAlreadyExistsException
-      KeyboardFocusManager KeyEvent KeyEventDispatcher KeyEventPostProcessor KeyException KeyFactory
-      KeyFactorySpi KeyGenerator KeyGeneratorSpi KeyListener KeyManagementException KeyManager
-      KeyManagerFactory KeyManagerFactorySpi Keymap KeyPair KeyPairGenerator KeyPairGeneratorSpi KeyRep
-      KeySpec KeyStore KeyStoreBuilderParameters KeyStoreException KeyStoreSpi KeyStroke Label LabelUI
-      LabelView LanguageCallback LastOwnerException LayeredHighlighter LayoutFocusTraversalPolicy
-      LayoutManager LayoutManager2 LayoutQueue LDAPCertStoreParameters LdapContext LdapName
-      LdapReferralException Lease Level LimitExceededException Line Line2D LineBorder LineBreakMeasurer
-      LineEvent LineListener LineMetrics LineNumberInputStream LineNumberReader LineUnavailableException
-      LinkageError LinkedBlockingQueue LinkedHashMap LinkedHashSet LinkedList LinkException LinkLoopException
-      LinkRef List ListCellRenderer ListDataEvent ListDataListener ListenerNotFoundException ListIterator
-      ListModel ListResourceBundle ListSelectionEvent ListSelectionListener ListSelectionModel ListUI ListView
-      LoaderHandler Locale LocateRegistry Lock LockSupport Logger LoggingMXBean LoggingPermission LoginContext
-      LoginException LoginModule LogManager LogRecord LogStream Long LongBuffer LookAndFeel LookupOp
-      LookupTable Mac MacSpi MalformedInputException MalformedLinkException MalformedObjectNameException
-      MalformedParameterizedTypeException MalformedURLException ManagementFactory ManagementPermission
-      ManageReferralControl ManagerFactoryParameters Manifest Map MappedByteBuffer MarshalException
-      MarshalledObject MaskFormatter Matcher MatchResult Math MathContext MatteBorder MBeanAttributeInfo
-      MBeanConstructorInfo MBeanException MBeanFeatureInfo MBeanInfo MBeanNotificationInfo MBeanOperationInfo
-      MBeanParameterInfo MBeanPermission MBeanRegistration MBeanRegistrationException MBeanServer
-      MBeanServerBuilder MBeanServerConnection MBeanServerDelegate MBeanServerDelegateMBean MBeanServerFactory
-      MBeanServerForwarder MBeanServerInvocationHandler MBeanServerNotification MBeanServerNotificationFilter
-      MBeanServerPermission MBeanTrustPermission Media MediaName MediaPrintableArea MediaSize MediaSizeName
-      MediaTracker MediaTray Member MemoryCacheImageInputStream MemoryCacheImageOutputStream MemoryHandler
-      MemoryImageSource MemoryManagerMXBean MemoryMXBean MemoryNotificationInfo MemoryPoolMXBean MemoryType
-      MemoryUsage Menu MenuBar MenuBarUI MenuComponent MenuContainer MenuDragMouseEvent MenuDragMouseListener
-      MenuElement MenuEvent MenuItem MenuItemUI MenuKeyEvent MenuKeyListener MenuListener MenuSelectionManager
-      MenuShortcut MessageDigest MessageDigestSpi MessageFormat MetaEventListener MetalBorders MetalButtonUI
-      MetalCheckBoxIcon MetalCheckBoxUI MetalComboBoxButton MetalComboBoxEditor MetalComboBoxIcon
-      MetalComboBoxUI MetalDesktopIconUI MetalFileChooserUI MetalIconFactory MetalInternalFrameTitlePane
-      MetalInternalFrameUI MetalLabelUI MetalLookAndFeel MetalMenuBarUI MetalPopupMenuSeparatorUI
-      MetalProgressBarUI MetalRadioButtonUI MetalRootPaneUI MetalScrollBarUI MetalScrollButton
-      MetalScrollPaneUI MetalSeparatorUI MetalSliderUI MetalSplitPaneUI MetalTabbedPaneUI MetalTextFieldUI
-      MetalTheme MetalToggleButtonUI MetalToolBarUI MetalToolTipUI MetalTreeUI MetaMessage Method
-      MethodDescriptor MGF1ParameterSpec MidiChannel MidiDevice MidiDeviceProvider MidiEvent MidiFileFormat
-      MidiFileReader MidiFileWriter MidiMessage MidiSystem MidiUnavailableException MimeTypeParseException
-      MinimalHTMLWriter MissingFormatArgumentException MissingFormatWidthException MissingResourceException
-      Mixer MixerProvider MLet MLetMBean ModelMBean ModelMBeanAttributeInfo ModelMBeanConstructorInfo
-      ModelMBeanInfo ModelMBeanInfoSupport ModelMBeanNotificationBroadcaster ModelMBeanNotificationInfo
-      ModelMBeanOperationInfo ModificationItem Modifier Monitor MonitorMBean MonitorNotification
-      MonitorSettingException MouseAdapter MouseDragGestureRecognizer MouseEvent MouseInfo MouseInputAdapter
-      MouseInputListener MouseListener MouseMotionAdapter MouseMotionListener MouseWheelEvent
-      MouseWheelListener MultiButtonUI MulticastSocket MultiColorChooserUI MultiComboBoxUI MultiDesktopIconUI
-      MultiDesktopPaneUI MultiDoc MultiDocPrintJob MultiDocPrintService MultiFileChooserUI
-      MultiInternalFrameUI MultiLabelUI MultiListUI MultiLookAndFeel MultiMenuBarUI MultiMenuItemUI
-      MultiOptionPaneUI MultiPanelUI MultiPixelPackedSampleModel MultipleDocumentHandling MultipleMaster
-      MultiPopupMenuUI MultiProgressBarUI MultiRootPaneUI MultiScrollBarUI MultiScrollPaneUI MultiSeparatorUI
-      MultiSliderUI MultiSpinnerUI MultiSplitPaneUI MultiTabbedPaneUI MultiTableHeaderUI MultiTableUI
-      MultiTextUI MultiToolBarUI MultiToolTipUI MultiTreeUI MultiViewportUI MutableAttributeSet
-      MutableComboBoxModel MutableTreeNode Name NameAlreadyBoundException NameCallback NameClassPair
-      NameNotFoundException NameParser NamespaceChangeListener NamespaceContext Naming NamingEnumeration
-      NamingEvent NamingException NamingExceptionEvent NamingListener NamingManager NamingSecurityException
-      NavigationFilter NegativeArraySizeException NetPermission NetworkInterface NoClassDefFoundError
-      NoConnectionPendingException NodeChangeEvent NodeChangeListener NoInitialContextException
-      NoninvertibleTransformException NonReadableChannelException NonWritableChannelException
-      NoPermissionException NoRouteToHostException NoSuchAlgorithmException NoSuchAttributeException
-      NoSuchElementException NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException
-      NoSuchObjectException NoSuchPaddingException NoSuchProviderException NotActiveException
-      NotBoundException NotCompliantMBeanException NotContextException Notification NotificationBroadcaster
-      NotificationBroadcasterSupport NotificationEmitter NotificationFilter NotificationFilterSupport
-      NotificationListener NotificationResult NotOwnerException NotSerializableException NotYetBoundException
-      NotYetConnectedException NullCipher NullPointerException Number NumberFormat NumberFormatException
-      NumberFormatter NumberOfDocuments NumberOfInterveningJobs NumberUp NumberUpSupported NumericShaper
-      OAEPParameterSpec Object ObjectChangeListener ObjectFactory ObjectFactoryBuilder ObjectInput
-      ObjectInputStream ObjectInputValidation ObjectInstance ObjectName ObjectOutput ObjectOutputStream
-      ObjectStreamClass ObjectStreamConstants ObjectStreamException ObjectStreamField ObjectView ObjID
-      Observable Observer OceanTheme OpenDataException OpenMBeanAttributeInfo OpenMBeanAttributeInfoSupport
-      OpenMBeanConstructorInfo OpenMBeanConstructorInfoSupport OpenMBeanInfo OpenMBeanInfoSupport
-      OpenMBeanOperationInfo OpenMBeanOperationInfoSupport OpenMBeanParameterInfo
-      OpenMBeanParameterInfoSupport OpenType OperatingSystemMXBean Operation OperationNotSupportedException
-      OperationsException Option OptionalDataException OptionPaneUI OrientationRequested OutOfMemoryError
-      OutputDeviceAssigned OutputKeys OutputStream OutputStreamWriter OverlappingFileLockException
-      OverlayLayout Override Owner Pack200 Package PackedColorModel Pageable PageAttributes
-      PagedResultsControl PagedResultsResponseControl PageFormat PageRanges PagesPerMinute PagesPerMinuteColor
-      Paint PaintContext PaintEvent Panel PanelUI Paper ParagraphView ParameterBlock ParameterDescriptor
-      ParameterizedType ParameterMetaData ParseException ParsePosition Parser ParserConfigurationException
-      ParserDelegator PartialResultException PasswordAuthentication PasswordCallback PasswordView Patch
-      PathIterator Pattern PatternSyntaxException PBEKey PBEKeySpec PBEParameterSpec PDLOverrideSupported
-      Permission PermissionCollection Permissions PersistenceDelegate PersistentMBean PhantomReference Pipe
-      PipedInputStream PipedOutputStream PipedReader PipedWriter PixelGrabber PixelInterleavedSampleModel
-      PKCS8EncodedKeySpec PKIXBuilderParameters PKIXCertPathBuilderResult PKIXCertPathChecker
-      PKIXCertPathValidatorResult PKIXParameters PlainDocument PlainView Point Point2D PointerInfo Policy
-      PolicyNode PolicyQualifierInfo Polygon PooledConnection Popup PopupFactory PopupMenu PopupMenuEvent
-      PopupMenuListener PopupMenuUI Port PortableRemoteObject PortableRemoteObjectDelegate
-      PortUnreachableException Position Predicate PreferenceChangeEvent PreferenceChangeListener Preferences
-      PreferencesFactory PreparedStatement PresentationDirection Principal Printable PrinterAbortException
-      PrinterException PrinterGraphics PrinterInfo PrinterIOException PrinterIsAcceptingJobs PrinterJob
-      PrinterLocation PrinterMakeAndModel PrinterMessageFromOperator PrinterMoreInfo
-      PrinterMoreInfoManufacturer PrinterName PrinterResolution PrinterState PrinterStateReason
-      PrinterStateReasons PrinterURI PrintEvent PrintException PrintGraphics PrintJob PrintJobAdapter
-      PrintJobAttribute PrintJobAttributeEvent PrintJobAttributeListener PrintJobAttributeSet PrintJobEvent
-      PrintJobListener PrintQuality PrintRequestAttribute PrintRequestAttributeSet PrintService
-      PrintServiceAttribute PrintServiceAttributeEvent PrintServiceAttributeListener PrintServiceAttributeSet
-      PrintServiceLookup PrintStream PrintWriter PriorityBlockingQueue PriorityQueue PrivateClassLoader
-      PrivateCredentialPermission PrivateKey PrivateMLet PrivilegedAction PrivilegedActionException
-      PrivilegedExceptionAction Process ProcessBuilder ProfileDataException ProgressBarUI ProgressMonitor
-      ProgressMonitorInputStream Properties PropertyChangeEvent PropertyChangeListener
-      PropertyChangeListenerProxy PropertyChangeSupport PropertyDescriptor PropertyEditor
-      PropertyEditorManager PropertyEditorSupport PropertyPermission PropertyResourceBundle
-      PropertyVetoException ProtectionDomain ProtocolException Provider ProviderException Proxy ProxySelector
-      PSource PSSParameterSpec PublicKey PushbackInputStream PushbackReader QName QuadCurve2D Query QueryEval
-      QueryExp Queue QueuedJobCount Random RandomAccess RandomAccessFile Raster RasterFormatException RasterOp
-      RC2ParameterSpec RC5ParameterSpec Rdn Readable ReadableByteChannel Reader ReadOnlyBufferException
-      ReadWriteLock RealmCallback RealmChoiceCallback Receiver Rectangle Rectangle2D RectangularShape
-      ReentrantLock ReentrantReadWriteLock Ref RefAddr Reference Referenceable ReferenceQueue
-      ReferenceUriSchemesSupported ReferralException ReflectionException ReflectPermission Refreshable
-      RefreshFailedException Region RegisterableService Registry RegistryHandler RejectedExecutionException
-      RejectedExecutionHandler Relation RelationException RelationNotFoundException RelationNotification
-      RelationService RelationServiceMBean RelationServiceNotRegisteredException RelationSupport
-      RelationSupportMBean RelationType RelationTypeNotFoundException RelationTypeSupport Remote RemoteCall
-      RemoteException RemoteObject RemoteObjectInvocationHandler RemoteRef RemoteServer RemoteStub
-      RenderableImage RenderableImageOp RenderableImageProducer RenderContext RenderedImage
-      RenderedImageFactory Renderer RenderingHints RepaintManager ReplicateScaleFilter RequestingUserName
-      RequiredModelMBean RescaleOp ResolutionSyntax Resolver ResolveResult ResourceBundle ResponseCache Result
-      ResultSet ResultSetMetaData Retention RetentionPolicy ReverbType RGBImageFilter RMIClassLoader
-      RMIClassLoaderSpi RMIClientSocketFactory RMIConnection RMIConnectionImpl RMIConnectionImpl_Stub
-      RMIConnector RMIConnectorServer RMIFailureHandler RMIIIOPServerImpl RMIJRMPServerImpl
-      RMISecurityException RMISecurityManager RMIServer RMIServerImpl RMIServerImpl_Stub
-      RMIServerSocketFactory RMISocketFactory Robot Role RoleInfo RoleInfoNotFoundException RoleList
-      RoleNotFoundException RoleResult RoleStatus RoleUnresolved RoleUnresolvedList RootPaneContainer
-      RootPaneUI RoundingMode RoundRectangle2D RowMapper RowSet RowSetEvent RowSetInternal RowSetListener
-      RowSetMetaData RowSetMetaDataImpl RowSetReader RowSetWarning RowSetWriter RSAKey RSAKeyGenParameterSpec
-      RSAMultiPrimePrivateCrtKey RSAMultiPrimePrivateCrtKeySpec RSAOtherPrimeInfo RSAPrivateCrtKey
-      RSAPrivateCrtKeySpec RSAPrivateKey RSAPrivateKeySpec RSAPublicKey RSAPublicKeySpec RTFEditorKit
-      RuleBasedCollator Runnable Runtime RuntimeErrorException RuntimeException RuntimeMBeanException
-      RuntimeMXBean RuntimeOperationsException RuntimePermission SampleModel Sasl SaslClient SaslClientFactory
-      SaslException SaslServer SaslServerFactory Savepoint SAXParser SAXParserFactory SAXResult SAXSource
-      SAXTransformerFactory Scanner ScatteringByteChannel ScheduledExecutorService ScheduledFuture
-      ScheduledThreadPoolExecutor Schema SchemaFactory SchemaFactoryLoader SchemaViolationException Scrollable
-      Scrollbar ScrollBarUI ScrollPane ScrollPaneAdjustable ScrollPaneConstants ScrollPaneLayout ScrollPaneUI
-      SealedObject SearchControls SearchResult SecretKey SecretKeyFactory SecretKeyFactorySpi SecretKeySpec
-      SecureCacheResponse SecureClassLoader SecureRandom SecureRandomSpi Security SecurityException
-      SecurityManager SecurityPermission Segment SelectableChannel SelectionKey Selector SelectorProvider
-      Semaphore SeparatorUI Sequence SequenceInputStream Sequencer SerialArray SerialBlob SerialClob
-      SerialDatalink SerialException Serializable SerializablePermission SerialJavaObject SerialRef
-      SerialStruct ServerCloneException ServerError ServerException ServerNotActiveException ServerRef
-      ServerRuntimeException ServerSocket ServerSocketChannel ServerSocketFactory ServiceNotFoundException
-      ServicePermission ServiceRegistry ServiceUI ServiceUIFactory ServiceUnavailableException Set
-      SetOfIntegerSyntax Severity Shape ShapeGraphicAttribute SheetCollate Short ShortBuffer
-      ShortBufferException ShortLookupTable ShortMessage Sides Signature SignatureException SignatureSpi
-      SignedObject Signer SimpleAttributeSet SimpleBeanInfo SimpleDateFormat SimpleDoc SimpleFormatter
-      SimpleTimeZone SimpleType SinglePixelPackedSampleModel SingleSelectionModel Size2DSyntax
-      SizeLimitExceededException SizeRequirements SizeSequence Skeleton SkeletonMismatchException
-      SkeletonNotFoundException SliderUI Socket SocketAddress SocketChannel SocketException SocketFactory
-      SocketHandler SocketImpl SocketImplFactory SocketOptions SocketPermission SocketSecurityException
-      SocketTimeoutException SoftBevelBorder SoftReference SortControl SortedMap SortedSet
-      SortingFocusTraversalPolicy SortKey SortResponseControl Soundbank SoundbankReader SoundbankResource
-      Source SourceDataLine SourceLocator SpinnerDateModel SpinnerListModel SpinnerModel SpinnerNumberModel
-      SpinnerUI SplitPaneUI Spring SpringLayout SQLData SQLException SQLInput SQLInputImpl SQLOutput
-      SQLOutputImpl SQLPermission SQLWarning SSLContext SSLContextSpi SSLEngine SSLEngineResult SSLException
-      SSLHandshakeException SSLKeyException SSLPeerUnverifiedException SSLPermission SSLProtocolException
-      SslRMIClientSocketFactory SslRMIServerSocketFactory SSLServerSocket SSLServerSocketFactory SSLSession
-      SSLSessionBindingEvent SSLSessionBindingListener SSLSessionContext SSLSocket SSLSocketFactory Stack
-      StackOverflowError StackTraceElement StandardMBean StartTlsRequest StartTlsResponse StateEdit
-      StateEditable StateFactory Statement StreamCorruptedException StreamHandler StreamPrintService
-      StreamPrintServiceFactory StreamResult StreamSource StreamTokenizer StrictMath String StringBuffer
-      StringBufferInputStream StringBuilder StringCharacterIterator StringContent
-      StringIndexOutOfBoundsException StringMonitor StringMonitorMBean StringReader StringRefAddr
-      StringSelection StringTokenizer StringValueExp StringWriter Stroke Struct Stub StubDelegate
-      StubNotFoundException Style StyleConstants StyleContext StyledDocument StyledEditorKit StyleSheet
-      Subject SubjectDelegationPermission SubjectDomainCombiner SupportedValuesAttribute SuppressWarnings
-      SwingConstants SwingPropertyChangeSupport SwingUtilities SyncFactory SyncFactoryException
-      SyncFailedException SynchronousQueue SyncProvider SyncProviderException SyncResolver SynthConstants
-      SynthContext Synthesizer SynthGraphicsUtils SynthLookAndFeel SynthPainter SynthStyle SynthStyleFactory
-      SysexMessage System SystemColor SystemFlavorMap TabableView TabbedPaneUI TabExpander TableCellEditor
-      TableCellRenderer TableColumn TableColumnModel TableColumnModelEvent TableColumnModelListener
-      TableHeaderUI TableModel TableModelEvent TableModelListener TableUI TableView TabSet TabStop TabularData
-      TabularDataSupport TabularType TagElement Target TargetDataLine TargetedNotification Templates
-      TemplatesHandler TextAction TextArea TextAttribute TextComponent TextEvent TextField TextHitInfo
-      TextInputCallback TextLayout TextListener TextMeasurer TextOutputCallback TextSyntax TextUI TexturePaint
-      Thread ThreadDeath ThreadFactory ThreadGroup ThreadInfo ThreadLocal ThreadMXBean ThreadPoolExecutor
-      Throwable Tie TileObserver Time TimeLimitExceededException TimeoutException Timer
-      TimerAlarmClockNotification TimerMBean TimerNotification TimerTask Timestamp TimeUnit TimeZone
-      TitledBorder ToolBarUI Toolkit ToolTipManager ToolTipUI TooManyListenersException Track
-      TransactionalWriter TransactionRequiredException TransactionRolledbackException Transferable
-      TransferHandler TransformAttribute Transformer TransformerConfigurationException TransformerException
-      TransformerFactory TransformerFactoryConfigurationError TransformerHandler Transmitter Transparency
-      TreeCellEditor TreeCellRenderer TreeExpansionEvent TreeExpansionListener TreeMap TreeModel
-      TreeModelEvent TreeModelListener TreeNode TreePath TreeSelectionEvent TreeSelectionListener
-      TreeSelectionModel TreeSet TreeUI TreeWillExpandListener TrustAnchor TrustManager TrustManagerFactory
-      TrustManagerFactorySpi Type TypeInfoProvider TypeNotPresentException Types TypeVariable UID UIDefaults
-      UIManager UIResource UndeclaredThrowableException UndoableEdit UndoableEditEvent UndoableEditListener
-      UndoableEditSupport UndoManager UnexpectedException UnicastRemoteObject UnknownError
-      UnknownFormatConversionException UnknownFormatFlagsException UnknownGroupException UnknownHostException
-      UnknownObjectException UnknownServiceException UnmappableCharacterException UnmarshalException
-      UnmodifiableClassException UnmodifiableSetException UnrecoverableEntryException
-      UnrecoverableKeyException Unreferenced UnresolvedAddressException UnresolvedPermission
-      UnsatisfiedLinkError UnsolicitedNotification UnsolicitedNotificationEvent
-      UnsolicitedNotificationListener UnsupportedAddressTypeException UnsupportedAudioFileException
-      UnsupportedCallbackException UnsupportedCharsetException UnsupportedClassVersionError
-      UnsupportedEncodingException UnsupportedFlavorException UnsupportedLookAndFeelException
-      UnsupportedOperationException URI URIException URIResolver URISyntax URISyntaxException URL
-      URLClassLoader URLConnection URLDecoder URLEncoder URLStreamHandler URLStreamHandlerFactory
-      UTFDataFormatException Util UtilDelegate Utilities UUID Validator ValidatorHandler ValueExp ValueHandler
-      ValueHandlerMultiFormat VariableHeightLayoutCache Vector VerifyError VetoableChangeListener
-      VetoableChangeListenerProxy VetoableChangeSupport View ViewFactory ViewportLayout ViewportUI
-      VirtualMachineError Visibility VMID VoiceStatus Void VolatileImage WeakHashMap WeakReference WebRowSet
-      WildcardType Window WindowAdapter WindowConstants WindowEvent WindowFocusListener WindowListener
-      WindowStateListener WrappedPlainView WritableByteChannel WritableRaster WritableRenderedImage
-      WriteAbortedException Writer X500Principal X500PrivateCredential X509Certificate X509CertSelector
-      X509CRL X509CRLEntry X509CRLSelector X509EncodedKeySpec X509ExtendedKeyManager X509Extension
-      X509KeyManager X509TrustManager XAConnection XADataSource XAException XAResource Xid XMLConstants
-      XMLDecoder XMLEncoder XMLFormatter XMLGregorianCalendar XMLParseException XmlReader XmlWriter XPath
-      XPathConstants XPathException XPathExpression XPathExpressionException XPathFactory
-      XPathFactoryConfigurationException XPathFunction XPathFunctionException XPathFunctionResolver
-      XPathVariableResolver ZipEntry ZipException ZipFile ZipInputStream ZipOutputStream ZoneView
-    ]
-    #:nocov:
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bd/bd3a97351347227e1d7fd377fed6a7d933544ec4.svn-base
--- /dev/null
+++ b/.svn/pristine/bd/bd3a97351347227e1d7fd377fed6a7d933544ec4.svn-base
@@ -0,0 +1,57 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class TimelogHelperTest < ActionView::TestCase
+  include TimelogHelper
+  include ActionView::Helpers::TextHelper
+  include ActionView::Helpers::DateHelper
+  include ERB::Util
+
+  fixtures :projects, :roles, :enabled_modules, :users,
+                      :repositories, :changesets,
+                      :trackers, :issue_statuses, :issues, :versions, :documents,
+                      :wikis, :wiki_pages, :wiki_contents,
+                      :boards, :messages,
+                      :attachments,
+                      :enumerations
+
+  def setup
+    super
+  end
+
+  def test_activities_collection_for_select_options_should_return_array_of_activity_names_and_ids
+    activities = activity_collection_for_select_options
+    assert activities.include?(["Design", 9])
+    assert activities.include?(["Development", 10])
+  end
+
+  def test_activities_collection_for_select_options_should_not_include_inactive_activities
+    activities = activity_collection_for_select_options
+    assert !activities.include?(["Inactive Activity", 14])
+  end
+
+  def test_activities_collection_for_select_options_should_use_the_projects_override
+    project = Project.find(1)
+    override_activity = TimeEntryActivity.create!({:name => "Design override", :parent => TimeEntryActivity.find_by_name("Design"), :project => project})
+
+    activities = activity_collection_for_select_options(nil, project)
+    assert !activities.include?(["Design", 9]), "System activity found in: " + activities.inspect
+    assert activities.include?(["Design override", override_activity.id]), "Override activity not found in: " + activities.inspect
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/be/be1a47ce0b0f5def64a1b6af9eae01ab183cefda.svn-base
--- /dev/null
+++ b/.svn/pristine/be/be1a47ce0b0f5def64a1b6af9eae01ab183cefda.svn-base
@@ -0,0 +1,2 @@
+<% selector = ".#{watcher_css(watched)}" %>
+$("<%= selector %>").each(function(){$(this).replaceWith("<%= escape_javascript watcher_link(watched, user) %>")});
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/be/be27e3694ff6dcbbc4da7e18fcaa3cc047688636.svn-base
--- a/.svn/pristine/be/be27e3694ff6dcbbc4da7e18fcaa3cc047688636.svn-base
+++ /dev/null
@@ -1,69 +0,0 @@
-/* 
-	calendar-cs-win.js
-	language: Czech
-	encoding: windows-1250
-	author: Lubos Jerabek (xnet@seznam.cz)
-	        Jan Uhlir (espinosa@centrum.cz)
-*/
-
-// ** I18N
-Calendar._DN  = new Array('NedÄ›le','PondÄ›lÃ­','ÃšterÃ½','StÅ™eda','ÄŒtvrtek','PÃ¡tek','Sobota','NedÄ›le');
-Calendar._SDN = new Array('Ne','Po','Ãšt','St','ÄŒt','PÃ¡','So','Ne');
-Calendar._MN  = new Array('Leden','Ãšnor','BÅ™ezen','Duben','KvÄ›ten','ÄŒerven','ÄŒervenec','Srpen','ZÃ¡Å™Ã­','Å˜Ã­jen','Listopad','Prosinec');
-Calendar._SMN = new Array('Led','Ãšno','BÅ™e','Dub','KvÄ›','ÄŒrv','ÄŒvc','Srp','ZÃ¡Å™','Å˜Ã­j','Lis','Pro');
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "O komponentÄ› kalendÃ¡Å™";
-Calendar._TT["TOGGLE"] = "ZmÄ›na prvnÃ­ho dne v tÃ½dnu";
-Calendar._TT["PREV_YEAR"] = "PÅ™edchozÃ­ rok (pÅ™idrÅ¾ pro menu)";
-Calendar._TT["PREV_MONTH"] = "PÅ™edchozÃ­ mÄ›sÃ­c (pÅ™idrÅ¾ pro menu)";
-Calendar._TT["GO_TODAY"] = "DneÅ¡nÃ­ datum";
-Calendar._TT["NEXT_MONTH"] = "DalÅ¡Ã­ mÄ›sÃ­c (pÅ™idrÅ¾ pro menu)";
-Calendar._TT["NEXT_YEAR"] = "DalÅ¡Ã­ rok (pÅ™idrÅ¾ pro menu)";
-Calendar._TT["SEL_DATE"] = "Vyber datum";
-Calendar._TT["DRAG_TO_MOVE"] = "ChyÅ¥ a tÃ¡hni, pro pÅ™esun";
-Calendar._TT["PART_TODAY"] = " (dnes)";
-Calendar._TT["MON_FIRST"] = "UkaÅ¾ jako prvnÃ­ PondÄ›lÃ­";
-//Calendar._TT["SUN_FIRST"] = "UkaÅ¾ jako prvnÃ­ NedÄ›li";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"VÃ½bÄ›r datumu:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- PouÅ¾ijte tlaÄÃ­tka " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " k vÃ½bÄ›ru mÄ›sÃ­ce\n" +
-"- PodrÅ¾te tlaÄÃ­tko myÅ¡i na jakÃ©mkoliv z tÄ›ch tlaÄÃ­tek pro rychlejÅ¡Ã­ vÃ½bÄ›r.";
-
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"VÃ½bÄ›r Äasu:\n" +
-"- KliknÄ›te na jakoukoliv z ÄÃ¡stÃ­ vÃ½bÄ›ru Äasu pro zvÃ½Å¡enÃ­.\n" +
-"- nebo Shift-click pro snÃ­Å¾enÃ­\n" +
-"- nebo kliknÄ›te a tÃ¡hnÄ›te pro rychlejÅ¡Ã­ vÃ½bÄ›r.";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Zobraz %s prvnÃ­";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "ZavÅ™Ã­t";
-Calendar._TT["TODAY"] = "Dnes";
-Calendar._TT["TIME_PART"] = "(Shift-)Klikni nebo tÃ¡hni pro zmÄ›nu hodnoty";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "ÄŒas:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/be/be426f97dcd56a1fbbffc6dfa2d91fa4931c0a53.svn-base
Binary file .svn/pristine/be/be426f97dcd56a1fbbffc6dfa2d91fa4931c0a53.svn-base has changed
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/be/be4294c8059ba2b20a6dcda9e55ee99a61e208a6.svn-base
--- a/.svn/pristine/be/be4294c8059ba2b20a6dcda9e55ee99a61e208a6.svn-base
+++ /dev/null
@@ -1,19 +0,0 @@
-<% remote_form_for :wiki, @wiki,
-                   :url => { :controller => 'wikis', :action => 'edit', :id => @project },
-                   :builder => TabularFormBuilder,
-                   :lang => current_language do |f| %>
-
-<%= error_messages_for 'wiki' %>
-
-<div class="box tabular">
-<p><%= f.text_field :start_page, :size => 60, :required => true %><br />
-<em><%= l(:text_unallowed_characters) %>: , . / ? ; : |</em></p>
-</div>
-
-<div class="contextual">
-<%= link_to(l(:button_delete), {:controller => 'wikis', :action => 'destroy', :id => @project},
-            :class => 'icon icon-del') if @wiki && !@wiki.new_record? %>
-</div>
-
-<%= submit_tag((@wiki.nil? || @wiki.new_record?) ? l(:button_create) : l(:button_save)) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/be/be60b294fa53596894bfd4efd7ed28e8a1bbb00b.svn-base
--- /dev/null
+++ b/.svn/pristine/be/be60b294fa53596894bfd4efd7ed28e8a1bbb00b.svn-base
@@ -0,0 +1,252 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ContextMenusControllerTest < ActionController::TestCase
+  fixtures :projects,
+           :trackers,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :workflows,
+           :journals, :journal_details,
+           :versions,
+           :issues, :issue_statuses, :issue_categories,
+           :users,
+           :enumerations,
+           :time_entries
+
+  def test_context_menu_one_issue
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1]
+    assert_response :success
+    assert_template 'context_menu'
+
+    assert_select 'a.icon-edit[href=?]', '/issues/1/edit', :text => 'Edit'
+    assert_select 'a.icon-copy[href=?]', '/projects/ecookbook/issues/1/copy', :text => 'Copy'
+    assert_select 'a.icon-del[href=?]', '/issues?ids%5B%5D=1', :text => 'Delete'
+
+    # Statuses
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bstatus_id%5D=5', :text => 'Closed'
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8', :text => 'Immediate'
+    # No inactive priorities
+    assert_select 'a', :text => /Inactive Priority/, :count => 0
+    # Versions
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3', :text => '2.0'
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4', :text => 'eCookbook Subproject 1 - 2.0'
+    # Assignees
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3', :text => 'Dave Lopper'
+  end
+
+  def test_context_menu_one_issue_by_anonymous
+    get :issues, :ids => [1]
+    assert_response :success
+    assert_template 'context_menu'
+    assert_tag :tag => 'a', :content => 'Delete',
+                            :attributes => { :href => '#',
+                                             :class => 'icon-del disabled' }
+  end
+
+  def test_context_menu_multiple_issues_of_same_project
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1, 2]
+    assert_response :success
+    assert_template 'context_menu'
+    assert_not_nil assigns(:issues)
+    assert_equal [1, 2], assigns(:issues).map(&:id).sort
+
+    ids = assigns(:issues).map(&:id).sort.map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
+
+    assert_select 'a.icon-edit[href=?]', "/issues/bulk_edit?#{ids}", :text => 'Edit'
+    assert_select 'a.icon-copy[href=?]', "/issues/bulk_edit?copy=1&amp;#{ids}", :text => 'Copy'
+    assert_select 'a.icon-del[href=?]', "/issues?#{ids}", :text => 'Delete'
+
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5", :text => 'Closed'
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8", :text => 'Immediate'
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=3", :text => 'Dave Lopper'
+  end
+
+  def test_context_menu_multiple_issues_of_different_projects
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1, 2, 6]
+    assert_response :success
+    assert_template 'context_menu'
+    assert_not_nil assigns(:issues)
+    assert_equal [1, 2, 6], assigns(:issues).map(&:id).sort
+
+    ids = assigns(:issues).map(&:id).sort.map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
+
+    assert_select 'a.icon-edit[href=?]', "/issues/bulk_edit?#{ids}", :text => 'Edit'
+    assert_select 'a.icon-del[href=?]', "/issues?#{ids}", :text => 'Delete'
+
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5", :text => 'Closed'
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8", :text => 'Immediate'
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=2", :text => 'John Smith'
+  end
+
+  def test_context_menu_should_include_list_custom_fields
+    field = IssueCustomField.create!(:name => 'List', :field_format => 'list',
+      :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1]
+
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'List'
+      assert_select 'ul' do
+        assert_select 'a', 3
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=Foo", :text => 'Foo'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=__none__", :text => 'none'
+      end
+    end
+  end
+
+  def test_context_menu_should_not_include_null_value_for_required_custom_fields
+    field = IssueCustomField.create!(:name => 'List', :is_required => true, :field_format => 'list',
+      :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1, 2]
+
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'List'
+      assert_select 'ul' do
+        assert_select 'a', 2
+        assert_select 'a', :text => 'none', :count => 0
+      end
+    end
+  end
+
+  def test_context_menu_on_single_issue_should_select_current_custom_field_value
+    field = IssueCustomField.create!(:name => 'List', :field_format => 'list',
+      :possible_values => ['Foo', 'Bar'], :is_for_all => true, :tracker_ids => [1, 2, 3])
+    issue = Issue.find(1)
+    issue.custom_field_values = {field.id => 'Bar'}
+    issue.save!
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1]
+
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'List'
+      assert_select 'ul' do
+        assert_select 'a', 3
+        assert_select 'a.icon-checked', :text => 'Bar'
+      end
+    end
+  end
+
+  def test_context_menu_should_include_bool_custom_fields
+    field = IssueCustomField.create!(:name => 'Bool', :field_format => 'bool',
+      :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1]
+
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'Bool'
+      assert_select 'ul' do
+        assert_select 'a', 3
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=0", :text => 'No'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=1", :text => 'Yes'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=__none__", :text => 'none'
+      end
+    end
+  end
+
+  def test_context_menu_should_include_user_custom_fields
+    field = IssueCustomField.create!(:name => 'User', :field_format => 'user',
+      :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1]
+
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'User'
+      assert_select 'ul' do
+        assert_select 'a', Project.find(1).members.count + 1
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=2", :text => 'John Smith'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=__none__", :text => 'none'
+      end
+    end
+  end
+
+  def test_context_menu_should_include_version_custom_fields
+    field = IssueCustomField.create!(:name => 'Version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1, 2, 3])
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1]
+
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'Version'
+      assert_select 'ul' do
+        assert_select 'a', Project.find(1).shared_versions.count + 1
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=3", :text => '2.0'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=__none__", :text => 'none'
+      end
+    end
+  end
+
+  def test_context_menu_by_assignable_user_should_include_assigned_to_me_link
+    @request.session[:user_id] = 2
+    get :issues, :ids => [1]
+    assert_response :success
+    assert_template 'context_menu'
+
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=2', :text => / me /
+  end
+
+  def test_context_menu_should_propose_shared_versions_for_issues_from_different_projects
+    @request.session[:user_id] = 2
+    version = Version.create!(:name => 'Shared', :sharing => 'system', :project_id => 1)
+
+    get :issues, :ids => [1, 4]
+    assert_response :success
+    assert_template 'context_menu'
+
+    assert_include version, assigns(:versions)
+    assert_select 'a', :text => 'eCookbook - Shared'
+  end
+
+  def test_context_menu_issue_visibility
+    get :issues, :ids => [1, 4]
+    assert_response :success
+    assert_template 'context_menu'
+    assert_equal [1], assigns(:issues).collect(&:id)
+  end
+
+  def test_should_respond_with_404_without_ids
+    get :issues
+    assert_response 404
+  end
+
+  def test_time_entries_context_menu
+    @request.session[:user_id] = 2
+    get :time_entries, :ids => [1, 2]
+    assert_response :success
+    assert_template 'time_entries'
+
+    assert_select 'a:not(.disabled)', :text => 'Edit'
+  end
+
+  def test_time_entries_context_menu_without_edit_permission
+    @request.session[:user_id] = 2
+    Role.find_by_name('Manager').remove_permission! :edit_time_entries
+    
+    get :time_entries, :ids => [1, 2]
+    assert_response :success
+    assert_template 'time_entries'
+    assert_select 'a.disabled', :text => 'Edit'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/be/be8651657bb8574f8d5bb330df4828685014b41d.svn-base
--- /dev/null
+++ b/.svn/pristine/be/be8651657bb8574f8d5bb330df4828685014b41d.svn-base
@@ -0,0 +1,27 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Platform
+    class << self
+      def mswin?
+        (RUBY_PLATFORM =~ /(:?mswin|mingw)/) ||
+           (RUBY_PLATFORM == 'java' && (ENV['OS'] || ENV['os']) =~ /windows/i)
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/be/be90f4942b9fef3772683eb8abd9a2cf97bea5fc.svn-base
--- a/.svn/pristine/be/be90f4942b9fef3772683eb8abd9a2cf97bea5fc.svn-base
+++ /dev/null
@@ -1,29 +0,0 @@
-# Settings specified here will take precedence over those in config/environment.rb
-
-# The test environment is used exclusively to run your application's
-# test suite.  You never need to work with it otherwise.  Remember that
-# your test database is "scratch space" for the test suite and is wiped
-# and recreated between test runs.  Don't rely on the data there!
-config.cache_classes = true
-
-# Log error messages when you accidentally call methods on nil.
-config.whiny_nils    = true
-
-# Show full error reports and disable caching
-config.action_controller.consider_all_requests_local = true
-config.action_controller.perform_caching             = false
-
-config.action_mailer.perform_deliveries = true
-config.action_mailer.delivery_method = :test
-
-config.action_controller.session = { 
-  :key => "_test_session",
-  :secret => "some secret phrase for the tests."
-}
-
-# Skip protect_from_forgery in requests http://m.onkey.org/2007/9/28/csrf-protection-for-your-existing-rails-application
-config.action_controller.allow_forgery_protection  = false
-
-config.gem "shoulda", :version => "~> 2.10.3"
-config.gem "edavis10-object_daddy", :lib => "object_daddy"
-config.gem "mocha"
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/be/be94916770d801e739bf40c2184705ed8eb8a610.svn-base
--- a/.svn/pristine/be/be94916770d801e739bf40c2184705ed8eb8a610.svn-base
+++ /dev/null
@@ -1,73 +0,0 @@
-<%= breadcrumb link_to(l(:label_board_plural), {:controller => 'boards', :action => 'index', :project_id => @project}) %>
-
-<div class="contextual">
-<%= link_to_if_authorized l(:label_message_new),
-                          {:controller => 'messages', :action => 'new', :board_id => @board},
-                          :class => 'icon icon-add',
-                          :onclick => 'Element.show("add-message"); Form.Element.focus("message_subject"); return false;' %>
-<%= watcher_tag(@board, User.current) %>
-</div>
-
-<div id="add-message" style="display:none;">
-<% if authorize_for('messages', 'new') %>
-<h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%= l(:label_message_new) %></h2>
-<% form_for :message, @message, :url => {:controller => 'messages', :action => 'new', :board_id => @board}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
-  <%= render :partial => 'messages/form', :locals => {:f => f} %>
-  <p><%= submit_tag l(:button_create) %>
-  <%= link_to_remote l(:label_preview),
-                     { :url => { :controller => 'messages', :action => 'preview', :board_id => @board },
-                       :method => 'post',
-                       :update => 'preview',
-                       :with => "Form.serialize('message-form')",
-                       :complete => "Element.scrollTo('preview')"
-                     }, :accesskey => accesskey(:preview) %> |
-  <%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("add-message")' %></p>
-<% end %>
-<div id="preview" class="wiki"></div>
-<% end %>
-</div>
-
-<h2><%=h @board.name %></h2>
-<p class="subtitle"><%=h @board.description %></p>
-
-<% if @topics.any? %>
-<table class="list messages">
-  <thead><tr>
-    <th><%= l(:field_subject) %></th>
-    <th><%= l(:field_author) %></th>
-    <%= sort_header_tag('created_on', :caption => l(:field_created_on)) %>
-    <%= sort_header_tag('replies', :caption => l(:label_reply_plural)) %>
-    <%= sort_header_tag('updated_on', :caption => l(:label_message_last)) %>
-  </tr></thead>
-  <tbody>
-  <% @topics.each do |topic| %>
-    <tr class="message <%= cycle 'odd', 'even' %> <%= topic.sticky? ? 'sticky' : '' %> <%= topic.locked? ? 'locked' : '' %>">
-      <td class="subject"><%= link_to h(topic.subject), { :controller => 'messages', :action => 'show', :board_id => @board, :id => topic } %></td>
-      <td class="author" align="center"><%= link_to_user(topic.author) %></td>
-      <td class="created_on" align="center"><%= format_time(topic.created_on) %></td>
-      <td class="replies" align="center"><%= topic.replies_count %></td>
-      <td class="last_message">
-        <% if topic.last_reply %>
-        <%= authoring topic.last_reply.created_on, topic.last_reply.author %><br />
-        <%= link_to_message topic.last_reply %>
-        <% end %>
-      </td>
-    </tr>
-  <% end %>
-  </tbody>
-</table>
-<p class="pagination"><%= pagination_links_full @topic_pages, @topic_count %></p>
-<% else %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
-<% end %>
-
-<% html_title @board.name %>
-
-<% content_for :header_tags do %>
-    <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@project}: #{@board}") %>
-    <%= stylesheet_link_tag 'scm' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/be/beabb054b1ce2bec73f7e1f3d3b45e0d6c9f4b45.svn-base
--- /dev/null
+++ b/.svn/pristine/be/beabb054b1ce2bec73f7e1f3d3b45e0d6c9f4b45.svn-base
@@ -0,0 +1,12 @@
+class IssueAddNote < ActiveRecord::Migration
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    Permission.create :controller => "issues", :action => "add_note", :description => "label_add_note", :sort => 1057, :mail_option => 1, :mail_enabled => 0
+  end
+
+  def self.down
+    Permission.where("controller=? and action=?", 'issues', 'add_note').first.destroy
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bf/bf27e7a4eaace3c336ad2614552c89b7687ffee1.svn-base
--- /dev/null
+++ b/.svn/pristine/bf/bf27e7a4eaace3c336ad2614552c89b7687ffee1.svn-base
@@ -0,0 +1,49 @@
+<h3><%=l(:label_spent_time)%> (<%= l(:label_last_n_days, 7) %>)</h3>
+<%
+entries = timelog_items
+entries_by_day = entries.group_by(&:spent_on)
+%>
+
+<div class="total-hours">
+<p><%= l(:label_total_time) %>: <%= html_hours("%.2f" % entries.sum(&:hours).to_f) %></p>
+</div>
+
+<% if entries.any? %>
+<table class="list time-entries">
+<thead><tr>
+<th><%= l(:label_activity) %></th>
+<th><%= l(:label_project) %></th>
+<th><%= l(:field_comments) %></th>
+<th><%= l(:field_hours) %></th>
+<th></th>
+</tr></thead>
+<tbody>
+<% entries_by_day.keys.sort.reverse.each do |day| %>
+    <tr class="odd">
+    <td><strong><%= day == Date.today ? l(:label_today).titleize : format_date(day) %></strong></td>
+    <td colspan="2"></td>
+    <td class="hours"><em><%= html_hours("%.2f" % entries_by_day[day].sum(&:hours).to_f) %></em></td>
+    <td></td>
+    </tr>
+    <% entries_by_day[day].each do |entry| -%>
+    <tr class="time-entry" style="border-bottom: 1px solid #f5f5f5;">
+    <td class="activity"><%=h entry.activity %></td>
+    <td class="subject"><%=h entry.project %> <%= h(' - ') + link_to_issue(entry.issue, :truncate => 50) if entry.issue %></td>
+    <td class="comments"><%=h entry.comments %></td>
+    <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
+    <td align="center">
+    <% if entry.editable_by?(@user) -%>
+        <%= link_to image_tag('edit.png'), {:controller => 'timelog', :action => 'edit', :id => entry},
+                                           :title => l(:button_edit) %>
+        <%= link_to image_tag('delete.png'), {:controller => 'timelog', :action => 'destroy', :id => entry},
+                                             :data => {:confirm => l(:text_are_you_sure)},
+                                             :method => :delete,
+                                             :title => l(:button_delete) %>
+    <% end -%>
+    </td>
+    </tr>
+    <% end -%>
+<% end -%>
+</tbody>
+</table>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bf/bf4dd67c04712c99f4042f3516157030fb9d215d.svn-base
--- a/.svn/pristine/bf/bf4dd67c04712c99f4042f3516157030fb9d215d.svn-base
+++ /dev/null
@@ -1,34 +0,0 @@
-<table style="border-collapse: collapse; border:0;">
-  <tr>
-    <td style="padding-left:0">
-      <%= label_tag "available_columns", l(:description_available_columns) %>
-      <br />
-      <%= select_tag 'available_columns',
-              options_for_select((query.available_columns - query.columns).collect {|column| [column.caption, column.name]}),
-              :multiple => true, :size => 10, :style => "width:150px",
-              :ondblclick => "moveOptions(this.form.available_columns, this.form.selected_columns);" %>
-    </td>
-    <td align="center" valign="middle">
-      <input type="button" value="&#8594;"
-       onclick="moveOptions(this.form.available_columns, this.form.selected_columns);" /><br />
-      <input type="button" value="&#8592;"
-       onclick="moveOptions(this.form.selected_columns, this.form.available_columns);" />
-    </td>
-    <td>
-      <%= label_tag "selected_columns", l(:description_selected_columns) %>
-      <br />
-      <%= select_tag 'c[]',
-              options_for_select(query.columns.collect {|column| [column.caption, column.name]}),
-              :id => 'selected_columns', :multiple => true, :size => 10, :style => "width:150px",
-              :ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);" %>
-    </td>
-    <td align="center" valign="middle">
-      <input type="button" value="&#8593;" onclick="moveOptionUp(this.form.selected_columns);" /><br />
-      <input type="button" value="&#8595;" onclick="moveOptionDown(this.form.selected_columns);" />
-    </td>
-  </tr>
-</table>
-
-<% content_for :header_tags do %>
-<%= javascript_include_tag 'select_list_move' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bf/bf5525ed584bcef3f8f764b00823c6be53e94184.svn-base
--- /dev/null
+++ b/.svn/pristine/bf/bf5525ed584bcef3f8f764b00823c6be53e94184.svn-base
@@ -0,0 +1,25 @@
+class PopulateIssuesClosedOn < ActiveRecord::Migration
+  def up
+    closed_status_ids = IssueStatus.where(:is_closed => true).pluck(:id)
+    if closed_status_ids.any?
+      # First set closed_on for issues that have been closed once
+      closed_status_values = closed_status_ids.map {|status_id| "'#{status_id}'"}.join(',')
+      subselect = "SELECT MAX(#{Journal.table_name}.created_on)" +
+        " FROM #{Journal.table_name}, #{JournalDetail.table_name}" +
+        " WHERE #{Journal.table_name}.id = #{JournalDetail.table_name}.journal_id" +
+        " AND #{Journal.table_name}.journalized_type = 'Issue' AND #{Journal.table_name}.journalized_id = #{Issue.table_name}.id" +
+        " AND #{JournalDetail.table_name}.property = 'attr' AND #{JournalDetail.table_name}.prop_key = 'status_id'" +
+        " AND #{JournalDetail.table_name}.old_value NOT IN (#{closed_status_values})" +
+        " AND #{JournalDetail.table_name}.value IN (#{closed_status_values})"
+      Issue.update_all "closed_on = (#{subselect})"
+
+      # Then set closed_on for closed issues that weren't up updated by the above UPDATE
+      # No journal was found so we assume that they were closed on creation
+      Issue.update_all "closed_on = created_on", {:status_id => closed_status_ids, :closed_on => nil}
+    end
+  end
+
+  def down
+    Issue.update_all :closed_on => nil
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bf/bf9449c8a5e5c36fd71f4cedeb50a3723161073b.svn-base
--- a/.svn/pristine/bf/bf9449c8a5e5c36fd71f4cedeb50a3723161073b.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
---- 
-groups_users_001: 
-  group_id: 10
-  user_id: 8
-groups_users_002: 
-  group_id: 11
-  user_id: 8
-  
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bf/bf98d515ec4bff92546aa50c0abb45c796ba093a.svn-base
--- a/.svn/pristine/bf/bf98d515ec4bff92546aa50c0abb45c796ba093a.svn-base
+++ /dev/null
@@ -1,18 +0,0 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-comments_001: 
-  commented_type: News
-  commented_id: 1
-  id: 1
-  author_id: 1
-  comments: my first comment
-  created_on: 2006-12-10 18:10:10 +01:00
-  updated_on: 2006-12-10 18:10:10 +01:00
-comments_002: 
-  commented_type: News
-  commented_id: 1
-  id: 2
-  author_id: 2
-  comments: This is an other comment
-  created_on: 2006-12-10 18:12:10 +01:00
-  updated_on: 2006-12-10 18:12:10 +01:00
-  
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bf/bfd931633e0e6d8fdb9235166742d57815e8d4ab.svn-base
--- a/.svn/pristine/bf/bfd931633e0e6d8fdb9235166742d57815e8d4ab.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-<% form_tag({:action => 'edit', :tab => 'display'}) do %>
-
-<div class="box tabular settings">
-<p><%= setting_select :ui_theme, Redmine::Themes.themes.collect {|t| [t.name, t.id]}, :blank => :label_default, :label => :label_theme %></p>
-
-<p><%= setting_select :default_language, lang_options_for_select(false) %></p>
-
-<p><%= setting_select :start_of_week, [[day_name(1),'1'], [day_name(6),'6'], [day_name(7),'7']], :blank => :label_language_based %></p>
-
-<p><%= setting_select :date_format, Setting::DATE_FORMATS.collect {|f| [Date.today.strftime(f), f]}, :blank => :label_language_based %></p>
-
-<p><%= setting_select :time_format, Setting::TIME_FORMATS.collect {|f| [Time.now.strftime(f), f]}, :blank => :label_language_based %></p>
-
-<p><%= setting_select :user_format, @options[:user_format] %></p>
-
-<p><%= setting_check_box :gravatar_enabled %></p>
-
-<p><%= setting_select :gravatar_default, [["Wavatars", 'wavatar'], ["Identicons", 'identicon'], ["Monster ids", 'monsterid'], ["Retro", 'retro'], ["Mystery man", 'mm']], :blank => :label_none %></p>
-</div>
-
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bf/bfe1171346960c651d4d5f6f55c3e48b3102dcc1.svn-base
--- /dev/null
+++ b/.svn/pristine/bf/bfe1171346960c651d4d5f6f55c3e48b3102dcc1.svn-base
@@ -0,0 +1,60 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::WikiFormattingTest < ActiveSupport::TestCase
+  fixtures :issues
+
+  def test_textile_formatter
+    assert_equal Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting.formatter_for('textile')
+    assert_equal Redmine::WikiFormatting::Textile::Helper, Redmine::WikiFormatting.helper_for('textile')
+  end
+
+  def test_null_formatter
+    assert_equal Redmine::WikiFormatting::NullFormatter::Formatter, Redmine::WikiFormatting.formatter_for('')
+    assert_equal Redmine::WikiFormatting::NullFormatter::Helper, Redmine::WikiFormatting.helper_for('')
+  end
+
+  def test_should_link_urls_and_email_addresses
+    raw = <<-DIFF
+This is a sample *text* with a link: http://www.redmine.org
+and an email address foo@example.net
+DIFF
+
+    expected = <<-EXPECTED
+<p>This is a sample *text* with a link: <a class="external" href="http://www.redmine.org">http://www.redmine.org</a><br />
+and an email address <a class="email" href="mailto:foo@example.net">foo@example.net</a></p>
+EXPECTED
+
+    assert_equal expected.gsub(%r{[\r\n\t]}, ''), Redmine::WikiFormatting::NullFormatter::Formatter.new(raw).to_html.gsub(%r{[\r\n\t]}, '')
+  end
+
+  def test_supports_section_edit
+    with_settings :text_formatting => 'textile' do
+      assert_equal true, Redmine::WikiFormatting.supports_section_edit?
+    end
+    
+    with_settings :text_formatting => '' do
+      assert_equal false, Redmine::WikiFormatting.supports_section_edit?
+    end
+  end
+
+  def test_cache_key_for_saved_object_should_no_be_nil
+    assert_not_nil Redmine::WikiFormatting.cache_key_for('textile', 'Text', Issue.find(1), :description)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/bf/bffc97455f7192a4c50a5daa226945f5e048b46b.svn-base
--- /dev/null
+++ b/.svn/pristine/bf/bffc97455f7192a4c50a5daa226945f5e048b46b.svn-base
@@ -0,0 +1,63 @@
+desc "Run the Continous Integration tests for Redmine"
+task :ci do
+  # RAILS_ENV and ENV[] can diverge so force them both to test
+  ENV['RAILS_ENV'] = 'test'
+  RAILS_ENV = 'test'
+  Rake::Task["ci:setup"].invoke
+  Rake::Task["ci:build"].invoke
+  Rake::Task["ci:teardown"].invoke
+end
+
+namespace :ci do
+  desc "Setup Redmine for a new build"
+  task :setup do
+    Rake::Task["tmp:clear"].invoke
+    Rake::Task["log:clear"].invoke
+    Rake::Task["db:create:all"].invoke
+    Rake::Task["db:migrate"].invoke
+    Rake::Task["db:schema:dump"].invoke
+    Rake::Task["test:scm:setup:all"].invoke
+    Rake::Task["test:scm:update"].invoke
+  end
+
+  desc "Build Redmine"
+  task :build do
+    Rake::Task["test"].invoke
+    #Rake::Task["test:ui"].invoke unless RUBY_VERSION < '1.9'
+  end
+
+  desc "Finish the build"
+  task :teardown do
+  end
+end
+
+desc "Creates database.yml for the CI server"
+file 'config/database.yml' do
+  require 'yaml'
+  database = ENV['DATABASE_ADAPTER']
+  ruby = ENV['RUBY_VER'].gsub('.', '').gsub('-', '')
+  branch = ENV['BRANCH'].gsub('.', '').gsub('-', '')
+  dev_db_name = "ci_#{branch}_#{ruby}_dev"
+  test_db_name = "ci_#{branch}_#{ruby}_test"
+
+  case database
+  when 'mysql'
+    dev_conf =  {'adapter' => (RUBY_VERSION >= '1.9' ? 'mysql2' : 'mysql'), 'database' => dev_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins', 'encoding' => 'utf8'}
+    test_conf = dev_conf.merge('database' => test_db_name)
+  when 'postgresql'
+    dev_conf =  {'adapter' => 'postgresql', 'database' => dev_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins'}
+    test_conf = dev_conf.merge('database' => test_db_name)
+  when 'sqlite3'
+    dev_conf =  {'adapter' => 'sqlite3', 'database' => "db/#{dev_db_name}.sqlite3"}
+    test_conf = dev_conf.merge('database' => "db/#{test_db_name}.sqlite3")
+  when 'sqlserver'
+    dev_conf =  {'adapter' => 'sqlserver', 'database' => dev_db_name, 'host' => 'mssqlserver', 'port' => 1433, 'username' => 'jenkins', 'password' => 'jenkins'}
+    test_conf = dev_conf.merge('database' => test_db_name)
+  else
+    abort "Unknown database"
+  end
+
+  File.open('config/database.yml', 'w') do |f|
+    f.write YAML.dump({'development' => dev_conf, 'test' => test_conf})
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c0/c01563d0a237a5d88091f0f7a0b811b886e08b5f.svn-base
--- /dev/null
+++ b/.svn/pristine/c0/c01563d0a237a5d88091f0f7a0b811b886e08b5f.svn-base
@@ -0,0 +1,1102 @@
+#Ernad Husremovic hernad@bring.out.ba
+
+bs:
+  direction: ltr
+  date:
+    formats:
+      default: "%d.%m.%Y"
+      short: "%e. %b"
+      long: "%e. %B %Y"
+      only_day: "%e"
+
+
+    day_names: [Nedjelja, Ponedjeljak, Utorak, Srijeda, ÄŒetvrtak, Petak, Subota]
+    abbr_day_names: [Ned, Pon, Uto, Sri, ÄŒet, Pet, Sub]
+
+    month_names: [~, Januar, Februar, Mart, April, Maj, Jun, Jul, Avgust, Septembar, Oktobar, Novembar, Decembar]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, Maj, Jun, Jul, Avg, Sep, Okt, Nov, Dec]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%A, %e. %B %Y, %H:%M"
+      short: "%e. %B, %H:%M Uhr"
+      long: "%A, %e. %B %Y, %H:%M"
+      time: "%H:%M"
+
+    am: "prijepodne"
+    pm: "poslijepodne"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pola minute"
+      less_than_x_seconds:
+        one:   "manje od 1 sekunde"
+        other: "manje od %{count} sekudni"
+      x_seconds:
+        one:   "1 sekunda"
+        other: "%{count} sekundi"
+      less_than_x_minutes:
+        one:   "manje od 1 minute"
+        other: "manje od %{count} minuta"
+      x_minutes:
+        one:   "1 minuta"
+        other: "%{count} minuta"
+      about_x_hours:
+        one:   "oko 1 sahat"
+        other: "oko %{count} sahata"
+      x_hours:
+        one:   "1 sahat"
+        other: "%{count} sahata"
+      x_days:
+        one:   "1 dan"
+        other: "%{count} dana"
+      about_x_months:
+        one:   "oko 1 mjesec"
+        other: "oko %{count} mjeseci"
+      x_months:
+        one:   "1 mjesec"
+        other: "%{count} mjeseci"
+      about_x_years:
+        one:   "oko 1 godine"
+        other: "oko %{count} godina"
+      over_x_years:
+        one:   "preko 1 godine"
+        other: "preko %{count} godina"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+
+  number:
+    format:
+      precision: 2
+      separator: ','
+      delimiter: '.'
+    currency:
+      format:
+        unit: 'KM'
+        format: '%u %n'
+        negative_format: '%u -%n'
+        delimiter: ''
+    percentage:
+      format:
+        delimiter: ""
+    precision:
+      format:
+        delimiter: ""
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "i"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "nije ukljuÄeno u listu"
+        exclusion: "je rezervisano"
+        invalid: "nije ispravno"
+        confirmation: "ne odgovara potvrdi"
+        accepted: "mora se prihvatiti"
+        empty: "ne moÅ¾e biti prazno"
+        blank: "ne moÅ¾e biti znak razmaka"
+        too_long: "je predugaÄko"
+        too_short: "je prekratko"
+        wrong_length: "je pogreÅ¡ne duÅ¾ine"
+        taken: "veÄ‡ je zauzeto"
+        not_a_number: "nije broj"
+        not_a_date: "nije ispravan datum"
+        greater_than: "mora bit veÄ‡i od %{count}"
+        greater_than_or_equal_to: "mora bit veÄ‡i ili jednak %{count}"
+        equal_to: "mora biti jednak %{count}"
+        less_than: "mora biti manji od %{count}"
+        less_than_or_equal_to: "mora bit manji ili jednak %{count}"
+        odd: "mora biti neparan"
+        even: "mora biti paran"
+        greater_than_start_date: "mora biti veÄ‡i nego poÄetni datum"
+        not_same_project: "ne pripada istom projektu"
+        circular_dependency: "Ova relacija stvar cirkularnu zavisnost"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: Molimo odaberite
+
+  general_text_No: 'Da'
+  general_text_Yes: 'Ne'
+  general_text_no: 'ne'
+  general_text_yes: 'da'
+  general_lang_name: 'Bosanski'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_activated: VaÅ¡ nalog je aktiviran. MoÅ¾ete se prijaviti.
+  notice_account_invalid_creditentials: PogreÅ¡an korisnik ili lozinka
+  notice_account_lost_email_sent: Email sa uputstvima o izboru nove Å¡ifre je poslat na vaÅ¡u adresu.
+  notice_account_password_updated: Lozinka je uspjeÅ¡no promjenjena.
+  notice_account_pending: "VaÅ¡ nalog je kreiran i Äeka odobrenje administratora."
+  notice_account_register_done: Nalog je uspjeÅ¡no kreiran. Da bi ste aktivirali vaÅ¡ nalog kliknite na link koji vam je poslat.
+  notice_account_unknown_email: Nepoznati korisnik.
+  notice_account_updated: Nalog je uspjeÅ¡no promjenen.
+  notice_account_wrong_password: PogreÅ¡na lozinka
+  notice_can_t_change_password: Ovaj nalog koristi eksterni izvor prijavljivanja. Ne mogu da promjenim Å¡ifru.
+  notice_default_data_loaded: Podrazumjevana konfiguracija uspjeÄno uÄitana.
+  notice_email_error: DoÅ¡lo je do greÅ¡ke pri slanju emaila (%{value})
+  notice_email_sent: "Email je poslan %{value}"
+  notice_failed_to_save_issues: "NeuspjeÅ¡no snimanje %{count} aktivnosti na %{total} izabrano: %{ids}."
+  notice_feeds_access_key_reseted: VaÅ¡ RSS pristup je resetovan.
+  notice_file_not_found: Stranica kojoj pokuÅ¡avate da pristupite ne postoji ili je uklonjena.
+  notice_locking_conflict: "Konflikt: podaci su izmjenjeni od strane drugog korisnika."
+  notice_no_issue_selected: "Nijedna aktivnost nije izabrana! Molim, izaberite aktivnosti koje Å¾elite za ispravljate."
+  notice_not_authorized: Niste ovlaÅ¡Ä‡eni da pristupite ovoj stranici.
+  notice_successful_connection: UspjeÅ¡na konekcija.
+  notice_successful_create: UspjeÅ¡no kreiranje.
+  notice_successful_delete: Brisanje izvrÅ¡eno.
+  notice_successful_update: Promjene uspjeÅ¡no izvrÅ¡ene.
+
+  error_can_t_load_default_data: "Podrazumjevane postavke se ne mogu uÄitati %{value}"
+  error_scm_command_failed: "Desila se greÅ¡ka pri pristupu repozitoriju: %{value}"
+  error_scm_not_found: "Unos i/ili revizija ne postoji u repozitoriju."
+
+  error_scm_annotate: "Ova stavka ne postoji ili nije oznaÄena."
+  error_issue_not_found_in_project: 'Aktivnost nije naÄ‘ena ili ne pripada ovom projektu'
+
+  warning_attachments_not_saved: "%{count} fajl(ovi) ne mogu biti snimljen(i)."
+
+  mail_subject_lost_password: "VaÅ¡a %{value} lozinka"
+  mail_body_lost_password: 'Za promjenu lozinke, kliknite na sljedeÄ‡i link:'
+  mail_subject_register: "Aktivirajte %{value} vaÅ¡ korisniÄki raÄun"
+  mail_body_register: 'Za aktivaciju vaÅ¡eg korisniÄkog raÄuna, kliknite na sljedeÄ‡i link:'
+  mail_body_account_information_external: "MoÅ¾ete koristiti  vaÅ¡ %{value} korisniÄki raÄun za prijavu na sistem."
+  mail_body_account_information: Informacija o vaÅ¡em korisniÄkom raÄunu
+  mail_subject_account_activation_request: "%{value} zahtjev za aktivaciju korisniÄkog raÄuna"
+  mail_body_account_activation_request: "Novi korisnik (%{value}) se registrovao. KorisniÄki raÄun Äeka vaÅ¡e odobrenje za aktivaciju:"
+  mail_subject_reminder: "%{count} aktivnost(i) u kaÅ¡njenju u narednim %{days} danima"
+  mail_body_reminder: "%{count} aktivnost(i) koje su dodjeljenje vama u narednim %{days} danima:"
+
+
+  field_name: Ime
+  field_description: Opis
+  field_summary: PojaÅ¡njenje
+  field_is_required: Neophodno popuniti
+  field_firstname: Ime
+  field_lastname: Prezime
+  field_mail: Email
+  field_filename: Fajl
+  field_filesize: VeliÄina
+  field_downloads: Downloadi
+  field_author: Autor
+  field_created_on: Kreirano
+  field_updated_on: Izmjenjeno
+  field_field_format: Format
+  field_is_for_all: Za sve projekte
+  field_possible_values: MoguÄ‡e vrijednosti
+  field_regexp: '"Regularni izraz"'
+  field_min_length: Minimalna veliÄina
+  field_max_length: Maksimalna veliÄina
+  field_value: Vrijednost
+  field_category: Kategorija
+  field_title: Naslov
+  field_project: Projekat
+  field_issue: Aktivnost
+  field_status: Status
+  field_notes: BiljeÅ¡ke
+  field_is_closed: Aktivnost zatvorena
+  field_is_default: Podrazumjevana vrijednost
+  field_tracker: PodruÄje aktivnosti
+  field_subject: Subjekat
+  field_due_date: ZavrÅ¡iti do
+  field_assigned_to: Dodijeljeno
+  field_priority: Prioritet
+  field_fixed_version: Ciljna verzija
+  field_user: Korisnik
+  field_role: Uloga
+  field_homepage: Naslovna strana
+  field_is_public: Javni
+  field_parent: Podprojekt od
+  field_is_in_roadmap: Aktivnosti prikazane u planu realizacije
+  field_login: Prijava
+  field_mail_notification: Email notifikacije
+  field_admin: Administrator
+  field_last_login_on: Posljednja konekcija
+  field_language: Jezik
+  field_effective_date: Datum
+  field_password: Lozinka
+  field_new_password: Nova lozinka
+  field_password_confirmation: Potvrda
+  field_version: Verzija
+  field_type: Tip
+  field_host: Host
+  field_port: Port
+  field_account: KorisniÄki raÄun
+  field_base_dn: Base DN
+  field_attr_login:  Attribut za prijavu
+  field_attr_firstname: Attribut za ime
+  field_attr_lastname: Atribut za prezime
+  field_attr_mail: Atribut za email
+  field_onthefly: 'Kreiranje korisnika "On-the-fly"'
+  field_start_date: PoÄetak
+  field_done_ratio: "% Realizovano"
+  field_auth_source: Mod za authentifikaciju
+  field_hide_mail: Sakrij moju email adresu
+  field_comments: Komentar
+  field_url: URL
+  field_start_page: PoÄetna stranica
+  field_subproject: Podprojekat
+  field_hours: Sahata
+  field_activity: Operacija
+  field_spent_on: Datum
+  field_identifier: Identifikator
+  field_is_filter: KoriÅ¡teno kao filter
+  field_issue_to: Povezana aktivnost
+  field_delay: OdgaÄ‘anje
+  field_assignable: Aktivnosti dodijeljene ovoj ulozi
+  field_redirect_existing_links: IzvrÅ¡i redirekciju postojeÄ‡ih linkova
+  field_estimated_hours: Procjena vremena
+  field_column_names: Kolone
+  field_time_zone: Vremenska zona
+  field_searchable: PretraÅ¾ivo
+  field_default_value: Podrazumjevana vrijednost
+  field_comments_sorting: PrikaÅ¾i komentare
+  field_parent_title: 'Stranica "roditelj"'
+  field_editable: MoÅ¾e se mijenjati
+  field_watcher: PosmatraÄ
+  field_identity_url: OpenID URL
+  field_content: SadrÅ¾aj
+
+  setting_app_title: Naslov aplikacije
+  setting_app_subtitle: Podnaslov aplikacije
+  setting_welcome_text: Tekst dobrodoÅ¡lice
+  setting_default_language: Podrazumjevani jezik
+  setting_login_required: Authentifikacija neophodna
+  setting_self_registration: Samo-registracija
+  setting_attachment_max_size: Maksimalna veliÄina prikaÄenog fajla
+  setting_issues_export_limit: Limit za eksport aktivnosti
+  setting_mail_from: Mail adresa - poÅ¡aljilac
+  setting_bcc_recipients: '"BCC" (blind carbon copy) primaoci '
+  setting_plain_text_mail: Email sa obiÄnim tekstom (bez HTML-a)
+  setting_host_name: Ime hosta i putanja
+  setting_text_formatting: Formatiranje teksta
+  setting_wiki_compression: Kompresija Wiki istorije
+
+  setting_feeds_limit: 'Limit za "RSS" feed-ove'
+  setting_default_projects_public: Podrazumjeva se da je novi projekat javni
+  setting_autofetch_changesets: 'Automatski kupi "commit"-e'
+  setting_sys_api_enabled: 'OmoguÄ‡i "WS" za upravljanje repozitorijom'
+  setting_commit_ref_keywords: KljuÄne rijeÄi za reference
+  setting_commit_fix_keywords: 'KljuÄne rijeÄi za status "zatvoreno"'
+  setting_autologin: Automatski login
+  setting_date_format: Format datuma
+  setting_time_format: Format vremena
+  setting_cross_project_issue_relations: OmoguÄ‡i relacije izmeÄ‘u aktivnosti na razliÄitim projektima
+  setting_issue_list_default_columns: Podrazumjevane koleone za prikaz na listi aktivnosti
+  setting_emails_footer: Potpis na email-ovima
+  setting_protocol: Protokol
+  setting_per_page_options: Broj objekata po stranici
+  setting_user_format: Format korisniÄkog prikaza
+  setting_activity_days_default: Prikaz promjena na projektu - opseg dana
+  setting_display_subprojects_issues: Prikaz podprojekata na glavnom projektima (podrazumjeva se)
+  setting_enabled_scm: OmoguÄ‡i SCM (source code management)
+  setting_mail_handler_api_enabled: OmoguÄ‡i automatsku obradu ulaznih emailova
+  setting_mail_handler_api_key: API kljuÄ (obrada ulaznih mailova)
+  setting_sequential_project_identifiers: GeneriÅ¡i identifikatore projekta sekvencijalno
+  setting_gravatar_enabled: 'Koristi "gravatar" korisniÄke ikone'
+  setting_diff_max_lines_displayed: Maksimalan broj linija za prikaz razlika izmeÄ‘u dva fajla
+  setting_file_max_size_displayed: Maksimalna veliÄina fajla kod prikaza razlika unutar fajla (inline)
+  setting_repository_log_display_limit: Maksimalna veliÄina revizija prikazanih na log fajlu
+  setting_openid: OmoguÄ‡i OpenID prijavu i registraciju
+
+  permission_edit_project: Ispravke projekta
+  permission_select_project_modules: Odaberi module projekta
+  permission_manage_members: Upravljanje Älanovima
+  permission_manage_versions: Upravljanje verzijama
+  permission_manage_categories: Upravljanje kategorijama aktivnosti
+  permission_add_issues: Dodaj aktivnosti
+  permission_edit_issues: Ispravka aktivnosti
+  permission_manage_issue_relations: Upravljaj relacijama meÄ‘u aktivnostima
+  permission_add_issue_notes: Dodaj biljeÅ¡ke
+  permission_edit_issue_notes: Ispravi biljeÅ¡ke
+  permission_edit_own_issue_notes: Ispravi sopstvene biljeÅ¡ke
+  permission_move_issues: Pomjeri aktivnosti
+  permission_delete_issues: IzbriÅ¡i aktivnosti
+  permission_manage_public_queries: Upravljaj javnim upitima
+  permission_save_queries: Snimi upite
+  permission_view_gantt: Pregled gantograma
+  permission_view_calendar: Pregled kalendara
+  permission_view_issue_watchers: Pregled liste korisnika koji prate aktivnost
+  permission_add_issue_watchers: Dodaj onoga koji prati aktivnost
+  permission_log_time: Evidentiraj utroÅ¡ak vremena
+  permission_view_time_entries: Pregled utroÅ¡ka vremena
+  permission_edit_time_entries: Ispravka utroÅ¡ka vremena
+  permission_edit_own_time_entries: Ispravka svog utroÅ¡ka vremena
+  permission_manage_news: Upravljaj novostima
+  permission_comment_news: Komentiraj novosti
+  permission_view_documents: Pregled dokumenata
+  permission_manage_files: Upravljaj fajlovima
+  permission_view_files: Pregled fajlova
+  permission_manage_wiki: Upravljaj wiki stranicama
+  permission_rename_wiki_pages: Ispravi wiki stranicu
+  permission_delete_wiki_pages: IzbriÅ¡i wiki stranicu
+  permission_view_wiki_pages: Pregled wiki sadrÅ¾aja
+  permission_view_wiki_edits: Pregled wiki istorije
+  permission_edit_wiki_pages: Ispravka wiki stranica
+  permission_delete_wiki_pages_attachments: Brisanje fajlova prikaÄenih wiki-ju
+  permission_protect_wiki_pages: ZaÅ¡titi wiki stranicu
+  permission_manage_repository: Upravljaj repozitorijem
+  permission_browse_repository: Pregled repozitorija
+  permission_view_changesets: Pregled setova promjena
+  permission_commit_access: 'Pristup "commit"-u'
+  permission_manage_boards: Upravljaj forumima
+  permission_view_messages: Pregled poruka
+  permission_add_messages: Å alji poruke
+  permission_edit_messages: Ispravi poruke
+  permission_edit_own_messages: Ispravka sopstvenih poruka
+  permission_delete_messages: Prisanje poruka
+  permission_delete_own_messages: Brisanje sopstvenih poruka
+
+  project_module_issue_tracking: PraÄ‡enje aktivnosti
+  project_module_time_tracking: PraÄ‡enje vremena
+  project_module_news: Novosti
+  project_module_documents: Dokumenti
+  project_module_files: Fajlovi
+  project_module_wiki: Wiki stranice
+  project_module_repository: Repozitorij
+  project_module_boards: Forumi
+
+  label_user: Korisnik
+  label_user_plural: Korisnici
+  label_user_new: Novi korisnik
+  label_project: Projekat
+  label_project_new: Novi projekat
+  label_project_plural: Projekti
+  label_x_projects:
+    zero:  0 projekata
+    one:   1 projekat
+    other: "%{count} projekata"
+  label_project_all: Svi projekti
+  label_project_latest: Posljednji projekti
+  label_issue: Aktivnost
+  label_issue_new: Nova aktivnost
+  label_issue_plural: Aktivnosti
+  label_issue_view_all: Vidi sve aktivnosti
+  label_issues_by: "Aktivnosti po %{value}"
+  label_issue_added: Aktivnost je dodana
+  label_issue_updated: Aktivnost je izmjenjena
+  label_document: Dokument
+  label_document_new: Novi dokument
+  label_document_plural: Dokumenti
+  label_document_added: Dokument je dodan
+  label_role: Uloga
+  label_role_plural: Uloge
+  label_role_new: Nove uloge
+  label_role_and_permissions: Uloge i dozvole
+  label_member: IzvrÅ¡ilac
+  label_member_new: Novi izvrÅ¡ilac
+  label_member_plural: IzvrÅ¡ioci
+  label_tracker: PodruÄje aktivnosti
+  label_tracker_plural: PodruÄja aktivnosti
+  label_tracker_new: Novo podruÄje aktivnosti
+  label_workflow: Tok promjena na aktivnosti
+  label_issue_status: Status aktivnosti
+  label_issue_status_plural: Statusi aktivnosti
+  label_issue_status_new: Novi status
+  label_issue_category: Kategorija aktivnosti
+  label_issue_category_plural: Kategorije aktivnosti
+  label_issue_category_new: Nova kategorija
+  label_custom_field: Proizvoljno polje
+  label_custom_field_plural: Proizvoljna polja
+  label_custom_field_new: Novo proizvoljno polje
+  label_enumerations: Enumeracije
+  label_enumeration_new: Nova vrijednost
+  label_information: Informacija
+  label_information_plural: Informacije
+  label_please_login: Molimo prijavite se
+  label_register: Registracija
+  label_login_with_open_id_option: ili prijava sa OpenID-om
+  label_password_lost: Izgubljena lozinka
+  label_home: PoÄetna stranica
+  label_my_page: Moja stranica
+  label_my_account: Moj korisniÄki raÄun
+  label_my_projects: Moji projekti
+  label_administration: Administracija
+  label_login: Prijavi se
+  label_logout: Odjavi se
+  label_help: PomoÄ‡
+  label_reported_issues: Prijavljene aktivnosti
+  label_assigned_to_me_issues: Aktivnosti dodjeljene meni
+  label_last_login: Posljednja konekcija
+  label_registered_on: Registrovan na
+  label_activity_plural: Promjene
+  label_activity: Operacija
+  label_overall_activity: Pregled svih promjena
+  label_user_activity: "Promjene izvrÅ¡ene od: %{value}"
+  label_new: Novi
+  label_logged_as: Prijavljen kao
+  label_environment: Sistemsko okruÅ¾enje
+  label_authentication: Authentifikacija
+  label_auth_source: Mod authentifikacije
+  label_auth_source_new: Novi mod authentifikacije
+  label_auth_source_plural: Modovi authentifikacije
+  label_subproject_plural: Podprojekti
+  label_and_its_subprojects: "%{value} i njegovi podprojekti"
+  label_min_max_length: Min - Maks duÅ¾ina
+  label_list: Lista
+  label_date: Datum
+  label_integer: Cijeli broj
+  label_float: Float
+  label_boolean: LogiÄka varijabla
+  label_string: Tekst
+  label_text: Dugi tekst
+  label_attribute: Atribut
+  label_attribute_plural: Atributi
+  label_no_data: Nema podataka za prikaz
+  label_change_status: Promjeni status
+  label_history: Istorija
+  label_attachment: Fajl
+  label_attachment_new: Novi fajl
+  label_attachment_delete: IzbriÅ¡i fajl
+  label_attachment_plural: Fajlovi
+  label_file_added: Fajl je dodan
+  label_report: IzvjeÅ¡taj
+  label_report_plural: IzvjeÅ¡taji
+  label_news: Novosti
+  label_news_new: Dodaj novosti
+  label_news_plural: Novosti
+  label_news_latest: Posljednje novosti
+  label_news_view_all: Pogledaj sve novosti
+  label_news_added: Novosti su dodane
+  label_settings: Postavke
+  label_overview: Pregled
+  label_version: Verzija
+  label_version_new: Nova verzija
+  label_version_plural: Verzije
+  label_confirmation: Potvrda
+  label_export_to: 'TakoÄ‘e dostupno u:'
+  label_read: ÄŒitaj...
+  label_public_projects: Javni projekti
+  label_open_issues: otvoren
+  label_open_issues_plural: otvoreni
+  label_closed_issues: zatvoren
+  label_closed_issues_plural: zatvoreni
+  label_x_open_issues_abbr_on_total:
+    zero:  0 otvoreno / %{total}
+    one:   1 otvorena / %{total}
+    other: "%{count} otvorene / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 otvoreno
+    one:   1 otvorena
+    other: "%{count} otvorene"
+  label_x_closed_issues_abbr:
+    zero:  0 zatvoreno
+    one:   1 zatvorena
+    other: "%{count} zatvorene"
+  label_total: Ukupno
+  label_permissions: Dozvole
+  label_current_status: TekuÄ‡i status
+  label_new_statuses_allowed: Novi statusi dozvoljeni
+  label_all: sve
+  label_none: niÅ¡ta
+  label_nobody: niko
+  label_next: SljedeÄ‡e
+  label_previous: Predhodno
+  label_used_by: KoriÅ¡teno od
+  label_details: Detalji
+  label_add_note: Dodaj biljeÅ¡ku
+  label_per_page: Po stranici
+  label_calendar: Kalendar
+  label_months_from: mjeseci od
+  label_gantt: Gantt
+  label_internal: Interno
+  label_last_changes: "posljednjih %{count} promjena"
+  label_change_view_all: Vidi sve promjene
+  label_personalize_page: Personaliziraj ovu stranicu
+  label_comment: Komentar
+  label_comment_plural: Komentari
+  label_x_comments:
+    zero: bez komentara
+    one: 1 komentar
+    other: "%{count} komentari"
+  label_comment_add: Dodaj komentar
+  label_comment_added: Komentar je dodan
+  label_comment_delete: IzbriÅ¡i komentar
+  label_query: Proizvoljan upit
+  label_query_plural: Proizvoljni upiti
+  label_query_new: Novi upit
+  label_filter_add: Dodaj filter
+  label_filter_plural: Filteri
+  label_equals: je
+  label_not_equals: nije
+  label_in_less_than: je manji nego
+  label_in_more_than: je viÅ¡e nego
+  label_in: u
+  label_today: danas
+  label_all_time: sve vrijeme
+  label_yesterday: juÄe
+  label_this_week: ova hefta
+  label_last_week: zadnja hefta
+  label_last_n_days: "posljednjih %{count} dana"
+  label_this_month: ovaj mjesec
+  label_last_month: posljednji mjesec
+  label_this_year: ova godina
+  label_date_range: Datumski opseg
+  label_less_than_ago: ranije nego (dana)
+  label_more_than_ago: starije nego (dana)
+  label_ago: prije (dana)
+  label_contains: sadrÅ¾i
+  label_not_contains: ne sadrÅ¾i
+  label_day_plural: dani
+  label_repository: Repozitorij
+  label_repository_plural: Repozitoriji
+  label_browse: Listaj
+  label_revision: Revizija
+  label_revision_plural: Revizije
+  label_associated_revisions: Doddjeljene revizije
+  label_added: dodano
+  label_modified: izmjenjeno
+  label_copied: kopirano
+  label_renamed: preimenovano
+  label_deleted: izbrisano
+  label_latest_revision: Posljednja revizija
+  label_latest_revision_plural: Posljednje revizije
+  label_view_revisions: Vidi revizije
+  label_max_size: Maksimalna veliÄina
+  label_sort_highest: Pomjeri na vrh
+  label_sort_higher: Pomjeri gore
+  label_sort_lower: Pomjeri dole
+  label_sort_lowest: Pomjeri na dno
+  label_roadmap: Plan realizacije
+  label_roadmap_due_in: "Obavezan do %{value}"
+  label_roadmap_overdue: "%{value} kasni"
+  label_roadmap_no_issues: Nema aktivnosti za ovu verziju
+  label_search: TraÅ¾i
+  label_result_plural: Rezultati
+  label_all_words: Sve rijeÄi
+  label_wiki: Wiki stranice
+  label_wiki_edit: ispravka wiki-ja
+  label_wiki_edit_plural: ispravke wiki-ja
+  label_wiki_page: Wiki stranica
+  label_wiki_page_plural: Wiki stranice
+  label_index_by_title: Indeks prema naslovima
+  label_index_by_date: Indeks po datumima
+  label_current_version: TekuÄ‡a verzija
+  label_preview: Pregled
+  label_feed_plural: Feeds
+  label_changes_details: Detalji svih promjena
+  label_issue_tracking: Evidencija aktivnosti
+  label_spent_time: UtroÅ¡ak vremena
+  label_f_hour: "%{value} sahat"
+  label_f_hour_plural: "%{value} sahata"
+  label_time_tracking: Evidencija vremena
+  label_change_plural: Promjene
+  label_statistics: Statistika
+  label_commits_per_month: '"Commit"-a po mjesecu'
+  label_commits_per_author: '"Commit"-a po autoru'
+  label_view_diff: Pregled razlika
+  label_diff_inline: zajedno
+  label_diff_side_by_side: jedna pored druge
+  label_options: Opcije
+  label_copy_workflow_from: Kopiraj tok promjena statusa iz
+  label_permissions_report: IzvjeÅ¡taj
+  label_watched_issues: Aktivnosti koje pratim
+  label_related_issues: Korelirane aktivnosti
+  label_applied_status: Status je primjenjen
+  label_loading: UÄitavam...
+  label_relation_new: Nova relacija
+  label_relation_delete: IzbriÅ¡i relaciju
+  label_relates_to: korelira sa
+  label_duplicates: duplikat
+  label_duplicated_by: duplicirano od
+  label_blocks: blokira
+  label_blocked_by: blokirano on
+  label_precedes: predhodi
+  label_follows: slijedi
+  label_end_to_start: 'kraj -> poÄetak'
+  label_end_to_end: 'kraja -> kraj'
+  label_start_to_start: 'poÄetak -> poÄetak'
+  label_start_to_end: 'poÄetak -> kraj'
+  label_stay_logged_in: Ostani prijavljen
+  label_disabled: onemoguÄ‡en
+  label_show_completed_versions: PrikaÅ¾i zavrÅ¡ene verzije
+  label_me: ja
+  label_board: Forum
+  label_board_new: Novi forum
+  label_board_plural: Forumi
+  label_topic_plural: Teme
+  label_message_plural: Poruke
+  label_message_last: Posljednja poruka
+  label_message_new: Nova poruka
+  label_message_posted: Poruka je dodana
+  label_reply_plural: Odgovori
+  label_send_information: PoÅ¡alji informaciju o korisniÄkom raÄunu
+  label_year: Godina
+  label_month: Mjesec
+  label_week: Hefta
+  label_date_from: Od
+  label_date_to: Do
+  label_language_based: Bazirano na korisnikovom jeziku
+  label_sort_by: "Sortiraj po %{value}"
+  label_send_test_email: PoÅ¡alji testni email
+  label_feeds_access_key_created_on: "RSS pristupni kljuÄ kreiran prije %{value} dana"
+  label_module_plural: Moduli
+  label_added_time_by: "Dodano od %{author} prije %{age}"
+  label_updated_time_by: "Izmjenjeno od %{author} prije %{age}"
+  label_updated_time: "Izmjenjeno prije %{value}"
+  label_jump_to_a_project: SkoÄi na projekat...
+  label_file_plural: Fajlovi
+  label_changeset_plural: Setovi promjena
+  label_default_columns: Podrazumjevane kolone
+  label_no_change_option: (Bez promjene)
+  label_bulk_edit_selected_issues: Ispravi odjednom odabrane aktivnosti
+  label_theme: Tema
+  label_default: Podrazumjevano
+  label_search_titles_only: PretraÅ¾i samo naslove
+  label_user_mail_option_all: "Za bilo koji dogaÄ‘aj na svim mojim projektima"
+  label_user_mail_option_selected: "Za bilo koji dogaÄ‘aj na odabranim projektima..."
+  label_user_mail_no_self_notified: "Ne Å¾elim notifikaciju za promjene koje sam ja napravio"
+  label_registration_activation_by_email: aktivacija korisniÄkog raÄuna email-om
+  label_registration_manual_activation: ruÄna aktivacija korisniÄkog raÄuna
+  label_registration_automatic_activation: automatska kreacija korisniÄkog raÄuna
+  label_display_per_page: "Po stranici: %{value}"
+  label_age: Starost
+  label_change_properties: Promjena osobina
+  label_general: Generalno
+  label_more: ViÅ¡e
+  label_scm: SCM
+  label_plugins: Plugin-ovi
+  label_ldap_authentication: LDAP authentifikacija
+  label_downloads_abbr: D/L
+  label_optional_description: Opis (opciono)
+  label_add_another_file: Dodaj joÅ¡ jedan fajl
+  label_preferences: Postavke
+  label_chronological_order: HronoloÅ¡ki poredak
+  label_reverse_chronological_order: Reverzni hronoloÅ¡ki poredak
+  label_planning: Planiranje
+  label_incoming_emails: Dolazni email-ovi
+  label_generate_key: GeneriÅ¡i kljuÄ
+  label_issue_watchers: PraÄ‡eno od
+  label_example: Primjer
+  label_display: Prikaz
+
+  button_apply: Primjeni
+  button_add: Dodaj
+  button_archive: Arhiviranje
+  button_back: Nazad
+  button_cancel: Odustani
+  button_change: Izmjeni
+  button_change_password: Izmjena lozinke
+  button_check_all: OznaÄi sve
+  button_clear: BriÅ¡i
+  button_copy: Kopiraj
+  button_create: Novi
+  button_delete: BriÅ¡i
+  button_download: Download
+  button_edit: Ispravka
+  button_list: Lista
+  button_lock: ZakljuÄaj
+  button_log_time: UtroÅ¡ak vremena
+  button_login: Prijava
+  button_move: Pomjeri
+  button_rename: Promjena imena
+  button_reply: Odgovor
+  button_reset: Resetuj
+  button_rollback: Vrati predhodno stanje
+  button_save: Snimi
+  button_sort: Sortiranje
+  button_submit: PoÅ¡alji
+  button_test: Testiraj
+  button_unarchive: Otpakuj arhivu
+  button_uncheck_all: IskljuÄi sve
+  button_unlock: OtkljuÄaj
+  button_unwatch: Prekini notifikaciju
+  button_update: Promjena na aktivnosti
+  button_view: Pregled
+  button_watch: Notifikacija
+  button_configure: Konfiguracija
+  button_quote: Citat
+
+  status_active: aktivan
+  status_registered: registrovan
+  status_locked: zakljuÄan
+
+  text_select_mail_notifications: Odaberi dogaÄ‘aje za koje Ä‡e se slati email notifikacija.
+  text_regexp_info: npr. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 znaÄi bez restrikcije
+  text_project_destroy_confirmation: Sigurno Å¾elite izbrisati ovaj projekat i njegove podatke ?
+  text_subprojects_destroy_warning: "Podprojekt(i): %{value} Ä‡e takoÄ‘e biti izbrisani."
+  text_workflow_edit: Odaberite ulogu i podruÄje aktivnosti za ispravku toka promjena na aktivnosti
+  text_are_you_sure: Da li ste sigurni ?
+  text_tip_issue_begin_day: zadatak poÄinje danas
+  text_tip_issue_end_day: zadatak zavrÅ¡ava danas
+  text_tip_issue_begin_end_day: zadatak zapoÄinje i zavrÅ¡ava danas
+  text_caracters_maximum: "maksimum %{count} karaktera."
+  text_caracters_minimum: "DuÅ¾ina mora biti najmanje %{count} znakova."
+  text_length_between: "Broj znakova izmeÄ‘u %{min} i %{max}."
+  text_tracker_no_workflow: Tok statusa nije definisan za ovo podruÄje aktivnosti
+  text_unallowed_characters: Nedozvoljeni znakovi
+  text_comma_separated: ViÅ¡estruke vrijednosti dozvoljene (odvojiti zarezom).
+  text_issues_ref_in_commit_messages: 'Referenciranje i zatvaranje aktivnosti putem "commit" poruka'
+  text_issue_added: "Aktivnost %{id} je prijavljena od %{author}."
+  text_issue_updated: "Aktivnost %{id} je izmjenjena od %{author}."
+  text_wiki_destroy_confirmation: Sigurno Å¾elite izbrisati ovaj wiki i Äitav njegov sadrÅ¾aj ?
+  text_issue_category_destroy_question: "Neke aktivnosti (%{count}) pripadaju ovoj kategoriji. Sigurno to Å¾elite uraditi ?"
+  text_issue_category_destroy_assignments: Ukloni kategoriju
+  text_issue_category_reassign_to: Ponovo dodijeli ovu kategoriju
+  text_user_mail_option: "Za projekte koje niste odabrali, primiÄ‡ete samo notifikacije o stavkama koje pratite ili ste u njih ukljuÄeni (npr. vi ste autor ili su vama dodjeljenje)."
+  text_no_configuration_data: "Uloge, podruÄja aktivnosti, statusi aktivnosti i tok promjena statusa nisu konfigurisane.\nKrajnje je preporuÄeno da uÄitate tekuÄ‘e postavke. Kasnije Ä‡ete ih moÄ‡i mjenjati po svojim potrebama."
+  text_load_default_configuration: UÄitaj tekuÄ‡u konfiguraciju
+  text_status_changed_by_changeset: "Primjenjeno u setu promjena %{value}."
+  text_issues_destroy_confirmation: 'Sigurno Å¾elite izbrisati odabranu/e aktivnost/i ?'
+  text_select_project_modules: 'Odaberi module koje Å¾elite u ovom projektu:'
+  text_default_administrator_account_changed: TekuÄ‡i administratorski raÄun je promjenjen
+  text_file_repository_writable: U direktorij sa fajlovima koji su prilozi se moÅ¾e pisati
+  text_plugin_assets_writable: U direktorij plugin-ova se moÅ¾e pisati
+  text_rmagick_available: RMagick je dostupan (opciono)
+  text_destroy_time_entries_question: "%{hours} sahata je prijavljeno na aktivnostima koje Å¾elite brisati. Å½elite li to uÄiniti ?"
+  text_destroy_time_entries: IzbriÅ¡i prijavljeno vrijeme
+  text_assign_time_entries_to_project: Dodaj prijavljenoo vrijeme projektu
+  text_reassign_time_entries: 'Preraspodjeli prijavljeno vrijeme na ovu aktivnost:'
+  text_user_wrote: "%{value} je napisao/la:"
+  text_enumeration_destroy_question: "Za %{count} objekata je dodjeljenja ova vrijednost."
+  text_enumeration_category_reassign_to: 'Ponovo im dodjeli ovu vrijednost:'
+  text_email_delivery_not_configured: "Email dostava nije konfiguraisana, notifikacija je onemoguÄ‡ena.\nKonfiguriÅ¡i SMTP server u config/configuration.yml i restartuj aplikaciju nakon toga."
+  text_repository_usernames_mapping: "Odaberi ili ispravi redmine korisnika mapiranog za svako korisniÄko ima naÄ‘eno u logu repozitorija.\nKorisnici sa istim imenom u redmineu i u repozitoruju se automatski mapiraju."
+  text_diff_truncated: '... Ovaj prikaz razlike je odsjeÄen poÅ¡to premaÅ¡uje maksimalnu veliÄinu za prikaz'
+  text_custom_field_possible_values_info: 'Jedna linija za svaku vrijednost'
+
+  default_role_manager: MenadÅ¾er
+  default_role_developer: Programer
+  default_role_reporter: Reporter
+  default_tracker_bug: GreÅ¡ka
+  default_tracker_feature: Nova funkcija
+  default_tracker_support: PodrÅ¡ka
+  default_issue_status_new: Novi
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: RijeÅ¡en
+  default_issue_status_feedback: ÄŒeka se povratna informacija
+  default_issue_status_closed: Zatvoren
+  default_issue_status_rejected: Odbijen
+  default_doc_category_user: KorisniÄka dokumentacija
+  default_doc_category_tech: TehniÄka dokumentacija
+  default_priority_low: Nizak
+  default_priority_normal: Normalan
+  default_priority_high: Visok
+  default_priority_urgent: Urgentno
+  default_priority_immediate: Odmah
+  default_activity_design: Dizajn
+  default_activity_development: Programiranje
+
+  enumeration_issue_priorities: Prioritet aktivnosti
+  enumeration_doc_categories: Kategorije dokumenata
+  enumeration_activities: Operacije (utroÅ¡ak vremena)
+  notice_unable_delete_version: Ne mogu izbrisati verziju.
+  button_create_and_continue: Kreiraj i nastavi
+  button_annotate: ZabiljeÅ¾i
+  button_activate: Aktiviraj
+  label_sort: Sortiranje
+  label_date_from_to: Od %{start} do %{end}
+  label_ascending: RastuÄ‡e
+  label_descending: OpadajuÄ‡e
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
+  text_wiki_page_reassign_children: Reassign child pages to this parent page
+  text_wiki_page_nullify_children: Keep child pages as root pages
+  text_wiki_page_destroy_children: Delete child pages and all their descendants
+  setting_password_min_length: Minimum password length
+  field_group_by: Group results by
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  label_wiki_content_added: Wiki page added
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
+  label_wiki_content_updated: Wiki page updated
+  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
+  permission_add_project: Create project
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  label_view_all_revisions: View all revisions
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
+  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
+  text_journal_changed: "%{label} changed from %{old} to %{new}"
+  text_journal_set_to: "%{label} set to %{value}"
+  text_journal_deleted: "%{label} deleted (%{old})"
+  label_group_plural: Groups
+  label_group: Group
+  label_group_new: New group
+  label_time_entry_plural: Spent time
+  text_journal_added: "%{label} %{value} added"
+  field_active: Active
+  enumeration_system_activity: System Activity
+  permission_delete_issue_watchers: Delete watchers
+  version_status_closed: closed
+  version_status_locked: locked
+  version_status_open: open
+  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
+  label_user_anonymous: Anonymous
+  button_move_and_follow: Move and follow
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_gravatar_default: Default Gravatar image
+  field_sharing: Sharing
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_system: With all projects
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_tree: With project tree
+  label_version_sharing_none: Not shared
+  error_can_not_archive_project: This project can not be archived
+  button_duplicate: Duplicate
+  button_copy_and_follow: Copy and follow
+  label_copy_source: Source
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_status: Use the issue status
+  error_issue_done_ratios_not_updated: Issue done ratios not updated.
+  error_workflow_copy_target: Please select target tracker(s) and role(s)
+  setting_issue_done_ratio_issue_field: Use the issue field
+  label_copy_same_as_target: Same as target
+  label_copy_target: Target
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  error_workflow_copy_source: Please select a source tracker or role
+  label_update_issue_done_ratios: Update issue done ratios
+  setting_start_of_week: Start calendars on
+  permission_view_issues: View Issues
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_revision_id: Revision %{value}
+  label_api_access_key: API access key
+  label_api_access_key_created_on: API access key created %{value} ago
+  label_feeds_access_key: RSS access key
+  notice_api_access_key_reseted: Your API access key was reset.
+  setting_rest_api_enabled: Enable REST web service
+  label_missing_api_access_key: Missing an API access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  button_show: Show
+  text_line_separated: Multiple values allowed (one line for each value).
+  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
+  permission_add_subprojects: Create subprojects
+  label_subproject_new: New subproject
+  text_own_membership_delete_confirmation: |-
+    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
+    Are you sure you want to continue?
+  label_close_versions: Close completed versions
+  label_board_sticky: Sticky
+  label_board_locked: Locked
+  permission_export_wiki_pages: Export wiki pages
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: Manage project activities
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_profile: Profile
+  permission_manage_subtasks: Manage subtasks
+  field_parent_issue: Parent task
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: 'Enkodiranje "commit" poruka'
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 aktivnost
+    one:   1 aktivnost
+    other: "%{count} aktivnosti"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: sve
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ukupno
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c0/c0b43345f86fbda7707c9e88d3122baac3b53e87.svn-base
--- /dev/null
+++ b/.svn/pristine/c0/c0b43345f86fbda7707c9e88d3122baac3b53e87.svn-base
@@ -0,0 +1,142 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class MessagesController < ApplicationController
+  menu_item :boards
+  default_search_scope :messages
+  before_filter :find_board, :only => [:new, :preview]
+  before_filter :find_attachments, :only => [:preview]
+  before_filter :find_message, :except => [:new, :preview]
+  before_filter :authorize, :except => [:preview, :edit, :destroy]
+
+  helper :boards
+  helper :watchers
+  helper :attachments
+  include AttachmentsHelper
+
+  REPLIES_PER_PAGE = 25 unless const_defined?(:REPLIES_PER_PAGE)
+
+  # Show a topic and its replies
+  def show
+    page = params[:page]
+    # Find the page of the requested reply
+    if params[:r] && page.nil?
+      offset = @topic.children.count(:conditions => ["#{Message.table_name}.id < ?", params[:r].to_i])
+      page = 1 + offset / REPLIES_PER_PAGE
+    end
+
+    @reply_count = @topic.children.count
+    @reply_pages = Paginator.new @reply_count, REPLIES_PER_PAGE, page
+    @replies =  @topic.children.
+      includes(:author, :attachments, {:board => :project}).
+      reorder("#{Message.table_name}.created_on ASC").
+      limit(@reply_pages.per_page).
+      offset(@reply_pages.offset).
+      all
+
+    @reply = Message.new(:subject => "RE: #{@message.subject}")
+    render :action => "show", :layout => false if request.xhr?
+  end
+
+  # Create a new topic
+  def new
+    @message = Message.new
+    @message.author = User.current
+    @message.board = @board
+    @message.safe_attributes = params[:message]
+    if request.post?
+      @message.save_attachments(params[:attachments])
+      if @message.save
+        call_hook(:controller_messages_new_after_save, { :params => params, :message => @message})
+        render_attachment_warning_if_needed(@message)
+        redirect_to board_message_path(@board, @message)
+      end
+    end
+  end
+
+  # Reply to a topic
+  def reply
+    @reply = Message.new
+    @reply.author = User.current
+    @reply.board = @board
+    @reply.safe_attributes = params[:reply]
+    @topic.children << @reply
+    if !@reply.new_record?
+      call_hook(:controller_messages_reply_after_save, { :params => params, :message => @reply})
+      attachments = Attachment.attach_files(@reply, params[:attachments])
+      render_attachment_warning_if_needed(@reply)
+    end
+    redirect_to board_message_path(@board, @topic, :r => @reply)
+  end
+
+  # Edit a message
+  def edit
+    (render_403; return false) unless @message.editable_by?(User.current)
+    @message.safe_attributes = params[:message]
+    if request.post? && @message.save
+      attachments = Attachment.attach_files(@message, params[:attachments])
+      render_attachment_warning_if_needed(@message)
+      flash[:notice] = l(:notice_successful_update)
+      @message.reload
+      redirect_to board_message_path(@message.board, @message.root, :r => (@message.parent_id && @message.id))
+    end
+  end
+
+  # Delete a messages
+  def destroy
+    (render_403; return false) unless @message.destroyable_by?(User.current)
+    r = @message.to_param
+    @message.destroy
+    if @message.parent
+      redirect_to board_message_path(@board, @message.parent, :r => r)
+    else
+      redirect_to project_board_path(@project, @board)
+    end
+  end
+
+  def quote
+    @subject = @message.subject
+    @subject = "RE: #{@subject}" unless @subject.starts_with?('RE:')
+
+    @content = "#{ll(Setting.default_language, :text_user_wrote, @message.author)}\n> "
+    @content << @message.content.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
+  end
+
+  def preview
+    message = @board.messages.find_by_id(params[:id])
+    @text = (params[:message] || params[:reply])[:content]
+    @previewed = message
+    render :partial => 'common/preview'
+  end
+
+private
+  def find_message
+    return unless find_board
+    @message = @board.messages.find(params[:id], :include => :parent)
+    @topic = @message.root
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def find_board
+    @board = Board.find(params[:board_id], :include => :project)
+    @project = @board.project
+  rescue ActiveRecord::RecordNotFound
+    render_404
+    nil
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c0/c0e0396acd39b35299e743ef8ce87e15b656ab9c.svn-base
--- a/.svn/pristine/c0/c0e0396acd39b35299e743ef8ce87e15b656ab9c.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-<h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%= l(:label_message_new) %></h2>
-
-<% form_for :message, @message, :url => {:action => 'new'}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
-  <%= render :partial => 'form', :locals => {:f => f} %>
-  <%= submit_tag l(:button_create) %>
-  <%= link_to_remote l(:label_preview),
-                     { :url => { :controller => 'messages', :action => 'preview', :board_id => @board },
-                       :method => 'post',
-                       :update => 'preview',
-                       :with => "Form.serialize('message-form')",
-                       :complete => "Element.scrollTo('preview')"
-                     }, :accesskey => accesskey(:preview) %>
-<% end %>
-
-<div id="preview" class="wiki"></div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c1/c13203b8c9801034c2e99e8551c74a2c3c923252.svn-base
--- /dev/null
+++ b/.svn/pristine/c1/c13203b8c9801034c2e99e8551c74a2c3c923252.svn-base
@@ -0,0 +1,96 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class AuthSourcesController < ApplicationController
+  layout 'admin'
+  menu_item :ldap_authentication
+
+  before_filter :require_admin
+  before_filter :find_auth_source, :only => [:edit, :update, :test_connection, :destroy]
+
+  def index
+    @auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25
+  end
+
+  def new
+    klass_name = params[:type] || 'AuthSourceLdap'
+    @auth_source = AuthSource.new_subclass_instance(klass_name, params[:auth_source])
+    render_404 unless @auth_source
+  end
+
+  def create
+    @auth_source = AuthSource.new_subclass_instance(params[:type], params[:auth_source])
+    if @auth_source.save
+      flash[:notice] = l(:notice_successful_create)
+      redirect_to auth_sources_path
+    else
+      render :action => 'new'
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    if @auth_source.update_attributes(params[:auth_source])
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to auth_sources_path
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def test_connection
+    begin
+      @auth_source.test_connection
+      flash[:notice] = l(:notice_successful_connection)
+    rescue Exception => e
+      flash[:error] = l(:error_unable_to_connect, e.message)
+    end
+    redirect_to auth_sources_path
+  end
+
+  def destroy
+    unless @auth_source.users.exists?
+      @auth_source.destroy
+      flash[:notice] = l(:notice_successful_delete)
+    end
+    redirect_to auth_sources_path
+  end
+
+  def autocomplete_for_new_user
+    results = AuthSource.search(params[:term])
+
+    render :json => results.map {|result| {
+      'value' => result[:login],
+      'label' => "#{result[:login]} (#{result[:firstname]} #{result[:lastname]})",
+      'login' => result[:login].to_s,
+      'firstname' => result[:firstname].to_s,
+      'lastname' => result[:lastname].to_s,
+      'mail' => result[:mail].to_s,
+      'auth_source_id' => result[:auth_source_id].to_s
+    }}
+  end
+
+  private
+
+  def find_auth_source
+    @auth_source = AuthSource.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c1/c1d45432ffa47ce422a38647a20792c2b62b62e8.svn-base
--- a/.svn/pristine/c1/c1d45432ffa47ce422a38647a20792c2b62b62e8.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-# Add your own tasks in files placed in lib/tasks ending in .rake,
-# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake.
-
-require(File.join(File.dirname(__FILE__), 'config', 'boot'))
-
-require 'rake'
-require 'rake/testtask'
-
-begin
-  require 'rdoc/task'
-rescue LoadError
-  # RDoc is not available
-end
-
-require 'tasks/rails'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c2/c2155d1a90b73a86baf62c217f9d15ae922ab7b2.svn-base
--- a/.svn/pristine/c2/c2155d1a90b73a86baf62c217f9d15ae922ab7b2.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-<div class="contextual">
-<%= link_to l(:label_auth_source_new), {:action => 'new'}, :class => 'icon icon-add' %>
-</div>
-
-<h2><%=l(:label_auth_source_plural)%></h2>
-
-<table class="list">
-  <thead><tr>
-    <th><%=l(:field_name)%></th>
-    <th><%=l(:field_type)%></th>
-    <th><%=l(:field_host)%></th>
-    <th><%=l(:label_user_plural)%></th>
-    <th></th>
-  </tr></thead>
-  <tbody>
-<% for source in @auth_sources %>
-  <tr id="auth-source-<%= source.id %>" class="<%= cycle("odd", "even") %>">
-    <td><%= link_to(h(source.name), :action => 'edit', :id => source)%></td>
-    <td align="center"><%= h source.auth_method_name %></td>
-    <td align="center"><%= h source.host %></td>
-    <td align="center"><%= h source.users.count %></td>
-    <td class="buttons">
-      <%= link_to l(:button_test), :action => 'test_connection', :id => source %>
-      <%= link_to l(:button_delete), { :action => 'destroy', :id => source },
-                                                        :method => :post,
-                                                        :confirm => l(:text_are_you_sure),
-                                                        :class => 'icon icon-del',
-                                                        :disabled => source.users.any? %>
-    </td>
-  </tr>
-<% end %>
-  </tbody>
-</table>
-
-<p class="pagination"><%= pagination_links_full @auth_source_pages %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c2/c22734b0a706ecad447a99eddb6be080500c20cb.svn-base
--- a/.svn/pristine/c2/c22734b0a706ecad447a99eddb6be080500c20cb.svn-base
+++ /dev/null
@@ -1,25 +0,0 @@
-<div class="contextual">
-<%= link_to l(:label_group_new), new_group_path, :class => 'icon icon-add' %>
-</div>
-
-<h2><%= l(:label_group_plural) %></h2>
-
-<% if @groups.any? %>
-<table class="list groups">
-  <thead><tr>
-  <th><%=l(:label_group)%></th>
-  <th><%=l(:label_user_plural)%></th>
-  <th></th>
-  </tr></thead>
-  <tbody>
-<% @groups.each do |group| %>
-  <tr class="<%= cycle 'odd', 'even' %>">
-    <td><%= link_to h(group), edit_group_path(group) %></td>
-    <td align="center"><%= group.users.size %></td>
-    <td class="buttons"><%= link_to l(:button_delete), group, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %></td>
-  </tr>
-<% end %>
-</table>
-<% else %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c2/c22f3e78d33cc33390133e36001a79182aa59239.svn-base
--- a/.svn/pristine/c2/c22f3e78d33cc33390133e36001a79182aa59239.svn-base
+++ /dev/null
@@ -1,100 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'application_controller'
-
-class ApplicationControllerTest < ActionController::TestCase
-  include Redmine::I18n
-
-  def setup
-    @controller = ApplicationController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-  end
-
-  # check that all language files are valid
-  def test_localization
-    lang_files_count = Dir["#{Rails.root}/config/locales/*.yml"].size
-    assert_equal lang_files_count, valid_languages.size
-    valid_languages.each do |lang|
-      assert set_language_if_valid(lang)
-    end
-    set_language_if_valid('en')
-  end
-
-  def test_call_hook_mixed_in
-    assert @controller.respond_to?(:call_hook)
-  end
-
-  context "test_api_offset_and_limit" do
-    context "without params" do
-      should "return 0, 25" do
-        assert_equal [0, 25], @controller.api_offset_and_limit({})
-      end
-    end
-
-    context "with limit" do
-      should "return 0, limit" do
-        assert_equal [0, 30], @controller.api_offset_and_limit({:limit => 30})
-      end
-
-      should "not exceed 100" do
-        assert_equal [0, 100], @controller.api_offset_and_limit({:limit => 120})
-      end
-
-      should "not be negative" do
-        assert_equal [0, 25], @controller.api_offset_and_limit({:limit => -10})
-      end
-    end
-
-    context "with offset" do
-      should "return offset, 25" do
-        assert_equal [10, 25], @controller.api_offset_and_limit({:offset => 10})
-      end
-
-      should "not be negative" do
-        assert_equal [0, 25], @controller.api_offset_and_limit({:offset => -10})
-      end
-
-      context "and limit" do
-        should "return offset, limit" do
-          assert_equal [10, 50], @controller.api_offset_and_limit({:offset => 10, :limit => 50})
-        end
-      end
-    end
-
-    context "with page" do
-      should "return offset, 25" do
-        assert_equal [0, 25], @controller.api_offset_and_limit({:page => 1})
-        assert_equal [50, 25], @controller.api_offset_and_limit({:page => 3})
-      end
-
-      should "not be negative" do
-        assert_equal [0, 25], @controller.api_offset_and_limit({:page => 0})
-        assert_equal [0, 25], @controller.api_offset_and_limit({:page => -2})
-      end
-
-      context "and limit" do
-        should "return offset, limit" do
-          assert_equal [0, 100], @controller.api_offset_and_limit({:page => 1, :limit => 100})
-          assert_equal [200, 100], @controller.api_offset_and_limit({:page => 3, :limit => 100})
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c2/c26f9f7dcd2039d9fe6ae4b53c1ff2ec4244a70f.svn-base
--- a/.svn/pristine/c2/c26f9f7dcd2039d9fe6ae4b53c1ff2ec4244a70f.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-class TestRoutingController < ApplicationController
-  def routed_action
-    render_class_and_action
-  end
-  
-  def test_named_routes_from_plugin
-    render :text => plugin_route_path(:action => "index")
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c2/c299ca060f15e623987cf6394cff809ee4d3e1d6.svn-base
--- a/.svn/pristine/c2/c299ca060f15e623987cf6394cff809ee4d3e1d6.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-<h2><%= link_to l(:label_tracker_plural), trackers_path %> &#187; <%=l(:label_tracker_new)%></h2>
-
-<% form_for @tracker, :builder => TabularFormBuilder do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c2/c2add2fc48545c9490209f8ae390f5752a7e9c91.svn-base
--- a/.svn/pristine/c2/c2add2fc48545c9490209f8ae390f5752a7e9c91.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-<h2><%= l(:label_statistics) %></h2>
-
-<p>
-<%= tag("embed", :width => 800, :height => 300, :type => "image/svg+xml", :src => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :graph => "commits_per_month")) %>
-</p>
-<p>
-<%= tag("embed", :width => 800, :height => 400, :type => "image/svg+xml", :src => url_for(:controller => 'repositories', :action => 'graph', :id => @project, :graph => "commits_per_author")) %>
-</p>
-
-<p><%= link_to l(:button_back), :action => 'show', :id => @project %></p>
-
-<% html_title(l(:label_repository), l(:label_statistics)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c2/c2ea979b406c20e95d30b9fa3044bb4c0af68697.svn-base
--- a/.svn/pristine/c2/c2ea979b406c20e95d30b9fa3044bb4c0af68697.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
---- 
-wikis_001: 
-  status: 1
-  start_page: CookBook documentation
-  project_id: 1
-  id: 1
-wikis_002: 
-  status: 1
-  start_page: Start page
-  project_id: 2
-  id: 2
-  
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c2/c2efec7daff7304595ce1ecc0edb5b5532a60347.svn-base
--- /dev/null
+++ b/.svn/pristine/c2/c2efec7daff7304595ce1ecc0edb5b5532a60347.svn-base
@@ -0,0 +1,41 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module BoardsHelper
+  def board_breadcrumb(item)
+    board = item.is_a?(Message) ? item.board : item
+    links = [link_to(l(:label_board_plural), project_boards_path(item.project))]
+    boards = board.ancestors.reverse
+    if item.is_a?(Message)
+      boards << board
+    end
+    links += boards.map {|ancestor| link_to(h(ancestor.name), project_board_path(ancestor.project, ancestor))}
+    breadcrumb links
+  end
+
+  def boards_options_for_select(boards)
+    options = []
+    Board.board_tree(boards) do |board, level|
+      label = (level > 0 ? '&nbsp;' * 2 * level + '&#187; ' : '').html_safe
+      label << board.name
+      options << [label, board.id]
+    end
+    options
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c2/c2fb52399397b4091535a470ec0b6dfd68749025.svn-base
--- a/.svn/pristine/c2/c2fb52399397b4091535a470ec0b6dfd68749025.svn-base
+++ /dev/null
@@ -1,41 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class ARCondition
-  attr_reader :conditions
-
-  def initialize(condition=nil)
-    @conditions = ['1=1']
-    add(condition) if condition
-  end
-
-  def add(condition)
-    if condition.is_a?(Array)
-      @conditions.first << " AND (#{condition.first})"
-      @conditions += condition[1..-1]
-    elsif condition.is_a?(String)
-      @conditions.first << " AND (#{condition})"
-    else
-      raise "Unsupported #{condition.class} condition: #{condition}"
-    end
-    self
-  end
-
-  def <<(condition)
-    add(condition)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c3/c3434dc1252ecfbed9052875659c7477dd01f91d.svn-base
--- /dev/null
+++ b/.svn/pristine/c3/c3434dc1252ecfbed9052875659c7477dd01f91d.svn-base
@@ -0,0 +1,67 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ApplicationTest < ActionController::IntegrationTest
+  include Redmine::I18n
+
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  def test_set_localization
+    Setting.default_language = 'en'
+
+    # a french user
+    get 'projects', { }, 'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
+    assert_response :success
+    assert_tag :tag => 'h2', :content => 'Projets'
+    assert_equal :fr, current_language
+
+    # then an italien user
+    get 'projects', { }, 'HTTP_ACCEPT_LANGUAGE' => 'it;q=0.8,en-us;q=0.5,en;q=0.3'
+    assert_response :success
+    assert_tag :tag => 'h2', :content => 'Progetti'
+    assert_equal :it, current_language
+
+    # not a supported language: default language should be used
+    get 'projects', { }, 'HTTP_ACCEPT_LANGUAGE' => 'zz'
+    assert_response :success
+    assert_tag :tag => 'h2', :content => 'Projects'
+  end
+
+  def test_token_based_access_should_not_start_session
+    # issue of a private project
+    get 'issues/4.atom'
+    assert_response 302
+
+    rss_key = User.find(2).rss_key
+    get "issues/4.atom?key=#{rss_key}"
+    assert_response 200
+    assert_nil session[:user_id]
+  end
+
+  def test_missing_template_should_respond_with_404
+    get '/login.png'
+    assert_response 404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c3/c359a81860a9169febc935dc31d96675ccce6f95.svn-base
--- /dev/null
+++ b/.svn/pristine/c3/c359a81860a9169febc935dc31d96675ccce6f95.svn-base
@@ -0,0 +1,431 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingRepositoriesTest < ActionController::IntegrationTest
+  def setup
+    @path_hash  = repository_path_hash(%w[path to file.c])
+    assert_equal "path/to/file.c", @path_hash[:path]
+    assert_equal "path/to/file.c", @path_hash[:param]
+  end
+
+  def test_repositories_resources
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repositories/new" },
+        { :controller => 'repositories', :action => 'new', :project_id => 'redmine' }
+      )
+    assert_routing(
+        { :method => 'post',
+          :path => "/projects/redmine/repositories" },
+        { :controller => 'repositories', :action => 'create', :project_id => 'redmine' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/repositories/1/edit" },
+        { :controller => 'repositories', :action => 'edit', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put',
+          :path => "/repositories/1" },
+        { :controller => 'repositories', :action => 'update', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'delete',
+          :path => "/repositories/1" },
+        { :controller => 'repositories', :action => 'destroy', :id => '1' }
+      )
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method,
+            :path => "/repositories/1/committers" },
+          { :controller => 'repositories', :action => 'committers', :id => '1' }
+        )
+    end
+  end
+
+  def test_repositories_show
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository" },
+        { :controller => 'repositories', :action => 'show', :id => 'redmine' }
+      )
+  end
+
+  def test_repositories
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/statistics" },
+        { :controller => 'repositories', :action => 'stats', :id => 'redmine' }
+     )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/graph" },
+        { :controller => 'repositories', :action => 'graph', :id => 'redmine' }
+     )
+  end
+
+  def test_repositories_show_with_repository_id
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo" },
+        { :controller => 'repositories', :action => 'show', :id => 'redmine', :repository_id => 'foo' }
+      )
+  end
+
+  def test_repositories_with_repository_id
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/statistics" },
+        { :controller => 'repositories', :action => 'stats', :id => 'redmine', :repository_id => 'foo' }
+     )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/graph" },
+        { :controller => 'repositories', :action => 'graph', :id => 'redmine', :repository_id => 'foo' }
+     )
+  end
+
+  def test_repositories_revisions
+    empty_path_param = []
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions" },
+        { :controller => 'repositories', :action => 'revisions', :id => 'redmine' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions.atom" },
+        { :controller => 'repositories', :action => 'revisions', :id => 'redmine',
+          :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2457" },
+        { :controller => 'repositories', :action => 'revision', :id => 'redmine',
+          :rev => '2457' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2457/show" },
+        { :controller => 'repositories', :action => 'show', :id => 'redmine',
+          :rev => '2457' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2457/show/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'show', :id => 'redmine',
+          :path => @path_hash[:param] , :rev => '2457'}
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2457/diff" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine',
+          :rev => '2457' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2457/diff" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine',
+          :rev => '2457', :format => 'diff' },
+        {},
+        { :format => 'diff' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2/diff/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine',
+          :path => @path_hash[:param], :rev => '2' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2/diff/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine',
+          :path => @path_hash[:param], :rev => '2', :format => 'diff' },
+        {},
+        { :format => 'diff' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2/entry/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'entry', :id => 'redmine',
+          :path => @path_hash[:param], :rev => '2' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2/raw/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'raw', :id => 'redmine',
+          :path => @path_hash[:param], :rev => '2' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revisions/2/annotate/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'annotate', :id => 'redmine',
+          :path => @path_hash[:param], :rev => '2' }
+      )
+  end
+
+  def test_repositories_revisions_with_repository_id
+    empty_path_param = []
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions" },
+        { :controller => 'repositories', :action => 'revisions', :id => 'redmine', :repository_id => 'foo' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions.atom" },
+        { :controller => 'repositories', :action => 'revisions', :id => 'redmine', :repository_id => 'foo',
+          :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2457" },
+        { :controller => 'repositories', :action => 'revision', :id => 'redmine', :repository_id => 'foo',
+          :rev => '2457' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2457/show" },
+        { :controller => 'repositories', :action => 'show', :id => 'redmine', :repository_id => 'foo',
+          :rev => '2457' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2457/show/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'show', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param] , :rev => '2457'}
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2457/diff" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine', :repository_id => 'foo',
+          :rev => '2457' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2457/diff" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine', :repository_id => 'foo',
+          :rev => '2457', :format => 'diff' },
+        {},
+        { :format => 'diff' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2/diff/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param], :rev => '2' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2/diff/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param], :rev => '2', :format => 'diff' },
+        {},
+        { :format => 'diff' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2/entry/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'entry', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param], :rev => '2' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2/raw/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'raw', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param], :rev => '2' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revisions/2/annotate/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'annotate', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param], :rev => '2' }
+      )
+  end
+
+  def test_repositories_non_revisions_path
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/changes" },
+        { :controller => 'repositories', :action => 'changes', :id => 'redmine' }
+      )
+    ['2457', 'master', 'slash/slash'].each do |rev|
+      assert_routing(
+           { :method => 'get',
+             :path => "/projects/redmine/repository/changes" },
+           { :controller => 'repositories', :action => 'changes', :id => 'redmine',
+             :rev => rev },
+           {},
+           { :rev => rev }
+         )
+    end
+    ['2457', 'master', 'slash/slash'].each do |rev|
+      assert_routing(
+           { :method => 'get',
+             :path => "/projects/redmine/repository/changes/#{@path_hash[:path]}" },
+           { :controller => 'repositories', :action => 'changes', :id => 'redmine',
+             :path => @path_hash[:param], :rev => rev },
+           {},
+           { :rev => rev }
+         )
+    end
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/diff/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/browse/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'browse', :id => 'redmine',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/entry/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'entry', :id => 'redmine',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/raw/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'raw', :id => 'redmine',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/annotate/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'annotate', :id => 'redmine',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/changes/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'changes', :id => 'redmine',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/revision" },
+        { :controller => 'repositories', :action => 'revision', :id => 'redmine' }
+      )
+  end
+
+  def test_repositories_non_revisions_path_with_repository_id
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/changes" },
+        { :controller => 'repositories', :action => 'changes',
+          :id => 'redmine', :repository_id => 'foo' }
+      )
+    ['2457', 'master', 'slash/slash'].each do |rev|
+      assert_routing(
+           { :method => 'get',
+             :path => "/projects/redmine/repository/foo/changes" },
+           { :controller => 'repositories', :action => 'changes',
+             :id => 'redmine',
+             :repository_id => 'foo', :rev => rev },
+           {},
+           { :rev => rev }
+         )
+    end
+    ['2457', 'master', 'slash/slash'].each do |rev|
+      assert_routing(
+           { :method => 'get',
+             :path => "/projects/redmine/repository/foo/changes/#{@path_hash[:path]}" },
+           { :controller => 'repositories', :action => 'changes', :id => 'redmine',
+             :repository_id => 'foo', :path => @path_hash[:param], :rev => rev },
+           {},
+           { :rev => rev }
+         )
+    end
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/diff/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'diff', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/browse/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'browse', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/entry/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'entry', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/raw/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'raw', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/annotate/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'annotate', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/changes/#{@path_hash[:path]}" },
+        { :controller => 'repositories', :action => 'changes', :id => 'redmine', :repository_id => 'foo',
+          :path => @path_hash[:param] }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/redmine/repository/foo/revision" },
+        { :controller => 'repositories', :action => 'revision', :id => 'redmine', :repository_id => 'foo'}
+      )
+  end
+
+  def test_repositories_related_issues
+    assert_routing(
+        { :method => 'post',
+          :path => "/projects/redmine/repository/revisions/123/issues" },
+        { :controller => 'repositories', :action => 'add_related_issue',
+          :id => 'redmine', :rev => '123' }
+      )
+    assert_routing(
+        { :method => 'delete',
+          :path => "/projects/redmine/repository/revisions/123/issues/25" },
+        { :controller => 'repositories', :action => 'remove_related_issue',
+          :id => 'redmine', :rev => '123', :issue_id => '25' }
+      )
+  end
+
+  def test_repositories_related_issues_with_repository_id
+    assert_routing(
+        { :method => 'post',
+          :path => "/projects/redmine/repository/foo/revisions/123/issues" },
+        { :controller => 'repositories', :action => 'add_related_issue',
+          :id => 'redmine', :repository_id => 'foo', :rev => '123' }
+      )
+    assert_routing(
+        { :method => 'delete',
+          :path => "/projects/redmine/repository/foo/revisions/123/issues/25" },
+        { :controller => 'repositories', :action => 'remove_related_issue',
+          :id => 'redmine', :repository_id => 'foo', :rev => '123', :issue_id => '25' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c3/c36c3ff1ad3e3f0290f0f72dd0de479a7596b93a.svn-base
--- /dev/null
+++ b/.svn/pristine/c3/c36c3ff1ad3e3f0290f0f72dd0de479a7596b93a.svn-base
@@ -0,0 +1,1086 @@
+th:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
+    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "half a minute"
+      less_than_x_seconds:
+        one:   "less than 1 second"
+        other: "less than %{count} seconds"
+      x_seconds:
+        one:   "1 second"
+        other: "%{count} seconds"
+      less_than_x_minutes:
+        one:   "less than a minute"
+        other: "less than %{count} minutes"
+      x_minutes:
+        one:   "1 minute"
+        other: "%{count} minutes"
+      about_x_hours:
+        one:   "about 1 hour"
+        other: "about %{count} hours"
+      x_hours:
+        one:   "1 hour"
+        other: "%{count} hours"
+      x_days:
+        one:   "1 day"
+        other: "%{count} days"
+      about_x_months:
+        one:   "about 1 month"
+        other: "about %{count} months"
+      x_months:
+        one:   "1 month"
+        other: "%{count} months"
+      about_x_years:
+        one:   "about 1 year"
+        other: "about %{count} years"
+      over_x_years:
+        one:   "over 1 year"
+        other: "over %{count} years"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        precision: 3
+        delimiter: ""
+      storage_units:
+        format: "%n %u"
+        units:
+          kb: KB
+          tb: TB
+          gb: GB
+          byte:
+            one: Byte
+            other: Bytes
+          mb: MB
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "and"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "à¹„à¸¡à¹ˆà¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¸£à¸²à¸¢à¸à¸²à¸£"
+        exclusion: "à¸–à¸¹à¸à¸ªà¸‡à¸§à¸™à¹„à¸§à¹‰"
+        invalid: "à¹„à¸¡à¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡"
+        confirmation: "à¸žà¸´à¸¡à¸žà¹Œà¹„à¸¡à¹ˆà¹€à¸«à¸¡à¸·à¸­à¸™à¹€à¸”à¸´à¸¡"
+        accepted: "à¸•à¹‰à¸­à¸‡à¸¢à¸­à¸¡à¸£à¸±à¸š"
+        empty: "à¸•à¹‰à¸­à¸‡à¹€à¸•à¸´à¸¡"
+        blank: "à¸•à¹‰à¸­à¸‡à¹€à¸•à¸´à¸¡"
+        too_long: "à¸¢à¸²à¸§à¹€à¸à¸´à¸™à¹„à¸›"
+        too_short: "à¸ªà¸±à¹‰à¸™à¹€à¸à¸´à¸™à¹„à¸›"
+        wrong_length: "à¸„à¸§à¸²à¸¡à¸¢à¸²à¸§à¹„à¸¡à¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡"
+        taken: "à¸–à¸¹à¸à¹ƒà¸Šà¹‰à¹„à¸›à¹à¸¥à¹‰à¸§"
+        not_a_number: "à¹„à¸¡à¹ˆà¹ƒà¸Šà¹ˆà¸•à¸±à¸§à¹€à¸¥à¸‚"
+        not_a_date: "à¹„à¸¡à¹ˆà¹ƒà¸Šà¹ˆà¸§à¸±à¸™à¸—à¸µà¹ˆ à¸—à¸µà¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡"
+        greater_than: "must be greater than %{count}"
+        greater_than_or_equal_to: "must be greater than or equal to %{count}"
+        equal_to: "must be equal to %{count}"
+        less_than: "must be less than %{count}"
+        less_than_or_equal_to: "must be less than or equal to %{count}"
+        odd: "must be odd"
+        even: "must be even"
+        greater_than_start_date: "à¸•à¹‰à¸­à¸‡à¸¡à¸²à¸à¸à¸§à¹ˆà¸²à¸§à¸±à¸™à¹€à¸£à¸´à¹ˆà¸¡"
+        not_same_project: "à¹„à¸¡à¹ˆà¹„à¸”à¹‰à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¹€à¸”à¸µà¸¢à¸§à¸à¸±à¸™"
+        circular_dependency: "à¸„à¸§à¸²à¸¡à¸ªà¸±à¸¡à¸žà¸±à¸™à¸˜à¹Œà¸­à¹‰à¸²à¸‡à¸­à¸´à¸‡à¹€à¸›à¹‡à¸™à¸§à¸‡à¸à¸¥à¸¡"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: à¸à¸£à¸¸à¸“à¸²à¹€à¸¥à¸·à¸­à¸
+
+  general_text_No: 'à¹„à¸¡à¹ˆ'
+  general_text_Yes: 'à¹ƒà¸Šà¹ˆ'
+  general_text_no: 'à¹„à¸¡à¹ˆ'
+  general_text_yes: 'à¹ƒà¸Šà¹ˆ'
+  general_lang_name: 'Thai (à¹„à¸—à¸¢)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: Windows-874
+  general_pdf_encoding: cp874
+  general_first_day_of_week: '1'
+
+  notice_account_updated: à¸šà¸±à¸à¸Šà¸µà¹„à¸”à¹‰à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹à¸¥à¹‰à¸§.
+  notice_account_invalid_creditentials: à¸Šà¸·à¹‰à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸«à¸£à¸·à¸­à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™à¹„à¸¡à¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡
+  notice_account_password_updated: à¸£à¸«à¸±à¸ªà¹„à¸”à¹‰à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹à¸¥à¹‰à¸§.
+  notice_account_wrong_password: à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™à¹„à¸¡à¹ˆà¸–à¸¹à¸à¸•à¹‰à¸­à¸‡
+  notice_account_register_done: à¸šà¸±à¸à¸Šà¸µà¸–à¸¹à¸à¸ªà¸£à¹‰à¸²à¸‡à¹à¸¥à¹‰à¸§. à¸à¸£à¸¸à¸“à¸²à¹€à¸Šà¹‡à¸„à¹€à¸¡à¸¥à¹Œ à¹à¸¥à¹‰à¸§à¸„à¸¥à¸´à¹Šà¸à¸—à¸µà¹ˆà¸¥à¸´à¸‡à¸„à¹Œà¹ƒà¸™à¸­à¸µà¹€à¸¡à¸¥à¹Œà¹€à¸žà¸·à¹ˆà¸­à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰à¸šà¸±à¸à¸Šà¸µ
+  notice_account_unknown_email: à¹„à¸¡à¹ˆà¸¡à¸µà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¸­à¸µà¹€à¸¡à¸¥à¹Œà¸™à¸µà¹‰.
+  notice_can_t_change_password: à¸šà¸±à¸à¸Šà¸µà¸™à¸µà¹‰à¹ƒà¸Šà¹‰à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™à¸ˆà¸²à¸à¹à¸«à¸¥à¹ˆà¸‡à¸ à¸²à¸¢à¸™à¸­à¸. à¹„à¸¡à¹ˆà¸ªà¸²à¸¡à¸²à¸£à¸–à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™à¹„à¸”à¹‰.
+  notice_account_lost_email_sent: à¹€à¸£à¸²à¹„à¸”à¹‰à¸ªà¹ˆà¸‡à¸­à¸µà¹€à¸¡à¸¥à¹Œà¸žà¸£à¹‰à¸­à¸¡à¸§à¸´à¸˜à¸µà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸£à¸«à¸±à¸µà¸ªà¸œà¹ˆà¸²à¸™à¹ƒà¸«à¸¡à¹ˆà¹ƒà¸«à¹‰à¸„à¸¸à¸“à¹à¸¥à¹‰à¸§ à¸à¸£à¸¸à¸“à¸²à¹€à¸Šà¹‡à¸„à¹€à¸¡à¸¥à¹Œ.
+  notice_account_activated: à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¸„à¸¸à¸“à¹„à¸”à¹‰à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰à¹à¸¥à¹‰à¸§. à¸•à¸­à¸™à¸™à¸µà¹‰à¸„à¸¸à¸“à¸ªà¸²à¸¡à¸²à¸£à¸–à¹€à¸‚à¹‰à¸²à¸ªà¸¹à¹ˆà¸£à¸°à¸šà¸šà¹„à¸”à¹‰à¹à¸¥à¹‰à¸§.
+  notice_successful_create: à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
+  notice_successful_update: à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
+  notice_successful_delete: à¸¥à¸šà¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
+  notice_successful_connection: à¸•à¸´à¸”à¸•à¹ˆà¸­à¸ªà¸³à¹€à¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
+  notice_file_not_found: à¸«à¸™à¹‰à¸²à¸—à¸µà¹ˆà¸„à¸¸à¸“à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸”à¸¹à¹„à¸¡à¹ˆà¸¡à¸µà¸­à¸¢à¸¹à¹ˆà¸ˆà¸£à¸´à¸‡ à¸«à¸£à¸·à¸­à¸–à¸¹à¸à¸¥à¸šà¹„à¸›à¹à¸¥à¹‰à¸§.
+  notice_locking_conflict: à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹‚à¸”à¸¢à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸„à¸™à¸­à¸·à¹ˆà¸™.
+  notice_not_authorized: à¸„à¸¸à¸“à¹„à¸¡à¹ˆà¸¡à¸µà¸ªà¸´à¸—à¸˜à¸´à¹€à¸‚à¹‰à¸²à¸–à¸¶à¸‡à¸«à¸™à¹‰à¸²à¸™à¸µà¹‰.
+  notice_email_sent: "à¸­à¸µà¹€à¸¡à¸¥à¹Œà¹„à¸”à¹‰à¸–à¸¹à¸à¸ªà¹ˆà¸‡à¸–à¸¶à¸‡ %{value}"
+  notice_email_error: "à¹€à¸à¸´à¸”à¸„à¸§à¸²à¸¡à¸œà¸´à¸”à¸žà¸¥à¸²à¸”à¸‚à¸“à¸°à¸à¸³à¸ªà¹ˆà¸‡à¸­à¸µà¹€à¸¡à¸¥à¹Œ (%{value})"
+  notice_feeds_access_key_reseted: RSS access key à¸‚à¸­à¸‡à¸„à¸¸à¸“à¸–à¸¹à¸ reset à¹à¸¥à¹‰à¸§.
+  notice_failed_to_save_issues: "%{count} à¸›à¸±à¸à¸«à¸²à¸ˆà¸²à¸ %{total} à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸–à¸¹à¸à¹€à¸¥à¸·à¸­à¸à¹„à¸¡à¹ˆà¸ªà¸²à¸¡à¸²à¸£à¸–à¸ˆà¸±à¸”à¹€à¸à¹‡à¸š: %{ids}."
+  notice_no_issue_selected: "à¹„à¸¡à¹ˆà¸¡à¸µà¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸–à¸¹à¸à¹€à¸¥à¸·à¸­à¸! à¸à¸£à¸¸à¸“à¸²à¹€à¸¥à¸·à¸­à¸à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸„à¸¸à¸“à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚."
+  notice_account_pending: "à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¸„à¸¸à¸“à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§ à¸‚à¸“à¸°à¸™à¸µà¹‰à¸£à¸­à¸à¸²à¸£à¸­à¸™à¸¸à¸¡à¸±à¸•à¸´à¸ˆà¸²à¸à¸œà¸¹à¹‰à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£."
+  notice_default_data_loaded: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¹‚à¸«à¸¥à¸”à¹€à¸ªà¸£à¹‡à¸ˆà¹à¸¥à¹‰à¸§.
+
+  error_can_t_load_default_data: "à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¹‚à¸«à¸¥à¸”à¹„à¸¡à¹ˆà¸ªà¸³à¹€à¸£à¹‡à¸ˆ: %{value}"
+  error_scm_not_found: "à¹„à¸¡à¹ˆà¸žà¸šà¸£à¸¸à¹ˆà¸™à¸—à¸µà¹ˆà¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹ƒà¸™à¹à¸«à¸¥à¹ˆà¸‡à¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š."
+  error_scm_command_failed: "à¹€à¸à¸´à¸”à¸„à¸§à¸²à¸¡à¸œà¸´à¸”à¸žà¸¥à¸²à¸”à¹ƒà¸™à¸à¸²à¸£à¹€à¸‚à¹‰à¸²à¸–à¸¶à¸‡à¹à¸«à¸¥à¹ˆà¸‡à¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š: %{value}"
+  error_scm_annotate: "entry à¹„à¸¡à¹ˆà¸¡à¸µà¸­à¸¢à¸¹à¹ˆà¸ˆà¸£à¸´à¸‡ à¸«à¸£à¸·à¸­à¹„à¸¡à¹ˆà¸ªà¸²à¸¡à¸²à¸£à¸–à¹€à¸‚à¸µà¸¢à¸™à¸«à¸¡à¸²à¸¢à¹€à¸«à¸•à¸¸à¸›à¸£à¸°à¸à¸­à¸š."
+  error_issue_not_found_in_project: 'à¹„à¸¡à¹ˆà¸žà¸šà¸›à¸±à¸à¸«à¸²à¸™à¸µà¹‰ à¸«à¸£à¸·à¸­à¸›à¸±à¸à¸«à¸²à¹„à¸¡à¹ˆà¹„à¸”à¹‰à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸™à¸µà¹‰'
+
+  mail_subject_lost_password: "à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™ %{value} à¸‚à¸­à¸‡à¸„à¸¸à¸“"
+  mail_body_lost_password: 'à¸„à¸¥à¸´à¹Šà¸à¸—à¸µà¹ˆà¸¥à¸´à¸‡à¸„à¹Œà¸•à¹ˆà¸­à¹„à¸›à¸™à¸µà¹‰à¹€à¸žà¸·à¹ˆà¸­à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™:'
+  mail_subject_register: "à¹€à¸›à¸´à¸”à¸šà¸±à¸à¸Šà¸µ %{value} à¸‚à¸­à¸‡à¸„à¸¸à¸“"
+  mail_body_register: 'à¸„à¸¥à¸´à¹Šà¸à¸—à¸µà¹ˆà¸¥à¸´à¸‡à¸„à¹Œà¸•à¹ˆà¸­à¹„à¸›à¸™à¸µà¹‰à¹€à¸žà¸·à¹ˆà¸­à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™:'
+  mail_body_account_information_external: "à¸„à¸¸à¸“à¸ªà¸²à¸¡à¸²à¸£à¸–à¹ƒà¸Šà¹‰à¸šà¸±à¸à¸Šà¸µ %{value} à¹€à¸žà¸·à¹ˆà¸­à¹€à¸‚à¹‰à¸²à¸ªà¸¹à¹ˆà¸£à¸°à¸šà¸š."
+  mail_body_account_information: à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¸„à¸¸à¸“
+  mail_subject_account_activation_request: "à¸à¸£à¸¸à¸“à¸²à¹€à¸›à¸´à¸”à¸šà¸±à¸à¸Šà¸µ %{value}"
+  mail_body_account_activation_request: "à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¹ƒà¸«à¸¡à¹ˆ (%{value}) à¹„à¸”à¹‰à¸¥à¸‡à¸—à¸°à¹€à¸šà¸µà¸¢à¸™. à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¹€à¸‚à¸²à¸à¸³à¸¥à¸±à¸‡à¸£à¸­à¸­à¸™à¸¸à¸¡à¸±à¸•à¸´:"
+
+
+  field_name: à¸Šà¸·à¹ˆà¸­
+  field_description: à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”
+  field_summary: à¸ªà¸£à¸¸à¸›à¸¢à¹ˆà¸­
+  field_is_required: à¸•à¹‰à¸­à¸‡à¹ƒà¸ªà¹ˆ
+  field_firstname: à¸Šà¸·à¹ˆà¸­
+  field_lastname: à¸™à¸²à¸¡à¸ªà¸à¸¸à¸¥
+  field_mail: à¸­à¸µà¹€à¸¡à¸¥à¹Œ
+  field_filename: à¹à¸Ÿà¹‰à¸¡
+  field_filesize: à¸‚à¸™à¸²à¸”
+  field_downloads: à¸”à¸²à¸§à¸™à¹Œà¹‚à¸«à¸¥à¸”
+  field_author: à¸œà¸¹à¹‰à¹à¸•à¹ˆà¸‡
+  field_created_on: à¸ªà¸£à¹‰à¸²à¸‡
+  field_updated_on: à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡
+  field_field_format: à¸£à¸¹à¸›à¹à¸šà¸š
+  field_is_for_all: à¸ªà¸³à¸«à¸£à¸±à¸šà¸—à¸¸à¸à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
+  field_possible_values: à¸„à¹ˆà¸²à¸—à¸µà¹ˆà¹€à¸›à¹‡à¸™à¹„à¸›à¹„à¸”à¹‰
+  field_regexp: Regular expression
+  field_min_length: à¸ªà¸±à¹‰à¸™à¸ªà¸¸à¸”
+  field_max_length: à¸¢à¸²à¸§à¸ªà¸¸à¸”
+  field_value: à¸„à¹ˆà¸²
+  field_category: à¸›à¸£à¸°à¹€à¸ à¸—
+  field_title: à¸Šà¸·à¹ˆà¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡
+  field_project: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
+  field_issue: à¸›à¸±à¸à¸«à¸²
+  field_status: à¸ªà¸–à¸²à¸™à¸°
+  field_notes: à¸šà¸±à¸™à¸—à¸¶à¸
+  field_is_closed: à¸›à¸±à¸à¸«à¸²à¸ˆà¸š
+  field_is_default: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
+  field_tracker: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡
+  field_subject: à¹€à¸£à¸·à¹ˆà¸­à¸‡
+  field_due_date: à¸§à¸±à¸™à¸„à¸£à¸šà¸à¸³à¸«à¸™à¸”
+  field_assigned_to: à¸¡à¸­à¸šà¸«à¸¡à¸²à¸¢à¹ƒà¸«à¹‰
+  field_priority: à¸„à¸§à¸²à¸¡à¸ªà¸³à¸„à¸±à¸
+  field_fixed_version: à¸£à¸¸à¹ˆà¸™
+  field_user: à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
+  field_role: à¸šà¸—à¸šà¸²à¸—
+  field_homepage: à¸«à¸™à¹‰à¸²à¹à¸£à¸
+  field_is_public: à¸ªà¸²à¸˜à¸²à¸£à¸“à¸°
+  field_parent: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢à¸‚à¸­à¸‡
+  field_is_in_roadmap: à¸›à¸±à¸à¸«à¸²à¹à¸ªà¸”à¸‡à¹ƒà¸™ à¹à¸œà¸™à¸‡à¸²à¸™
+  field_login: à¸Šà¸·à¹ˆà¸­à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸š
+  field_mail_notification: à¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•à¸·à¸­à¸™à¸—à¸²à¸‡à¸­à¸µà¹€à¸¡à¸¥à¹Œ
+  field_admin: à¸œà¸¹à¹‰à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£
+  field_last_login_on: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸šà¸„à¸£à¸±à¹‰à¸‡à¸ªà¸¸à¸”à¸—à¹‰à¸²à¸¢
+  field_language: à¸ à¸²à¸©à¸²
+  field_effective_date: à¸§à¸±à¸™à¸—à¸µà¹ˆ
+  field_password: à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
+  field_new_password: à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™à¹ƒà¸«à¸¡à¹ˆ
+  field_password_confirmation: à¸¢à¸·à¸™à¸¢à¸±à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
+  field_version: à¸£à¸¸à¹ˆà¸™
+  field_type: à¸Šà¸™à¸´à¸”
+  field_host: à¹‚à¸®à¸ªà¸•à¹Œ
+  field_port: à¸žà¸­à¸£à¹Œà¸•
+  field_account: à¸šà¸±à¸à¸Šà¸µ
+  field_base_dn: Base DN
+  field_attr_login: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸š attribute
+  field_attr_firstname: à¸Šà¸·à¹ˆà¸­ attribute
+  field_attr_lastname: à¸™à¸²à¸¡à¸ªà¸à¸¸à¸¥ attribute
+  field_attr_mail: à¸­à¸µà¹€à¸¡à¸¥à¹Œ attribute
+  field_onthefly: à¸ªà¸£à¹‰à¸²à¸‡à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¸—à¸±à¸™à¸—à¸µ
+  field_start_date: à¹€à¸£à¸´à¹ˆà¸¡
+  field_done_ratio: "% à¸ªà¸³à¹€à¸£à¹‡à¸ˆ"
+  field_auth_source: à¸§à¸´à¸˜à¸µà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™
+  field_hide_mail: à¸‹à¹ˆà¸­à¸™à¸­à¸µà¹€à¸¡à¸¥à¹Œà¸‚à¸­à¸‡à¸‰à¸±à¸™
+  field_comments: à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
+  field_url: URL
+  field_start_page: à¸«à¸™à¹‰à¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
+  field_subproject: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢
+  field_hours: à¸Šà¸±à¹ˆà¸§à¹‚à¸¡à¸‡
+  field_activity: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡
+  field_spent_on: à¸§à¸±à¸™à¸—à¸µà¹ˆ
+  field_identifier: à¸Šà¸·à¹ˆà¸­à¹€à¸‰à¸žà¸²à¸°
+  field_is_filter: à¹ƒà¸Šà¹‰à¹€à¸›à¹‡à¸™à¸•à¸±à¸§à¸à¸£à¸­à¸‡
+  field_issue_to: à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¸­à¸‡
+  field_delay: à¹€à¸¥à¸·à¹ˆà¸­à¸™
+  field_assignable: à¸›à¸±à¸à¸«à¸²à¸ªà¸²à¸¡à¸²à¸£à¸–à¸¡à¸­à¸šà¸«à¸¡à¸²à¸¢à¹ƒà¸«à¹‰à¸„à¸™à¸—à¸µà¹ˆà¸—à¸³à¸šà¸—à¸šà¸²à¸—à¸™à¸µà¹‰
+  field_redirect_existing_links: à¸¢à¹‰à¸²à¸¢à¸ˆà¸¸à¸”à¹€à¸Šà¸·à¹ˆà¸­à¸¡à¹‚à¸¢à¸‡à¸™à¸µà¹‰
+  field_estimated_hours: à¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¹‚à¸”à¸¢à¸›à¸£à¸°à¸¡à¸²à¸“
+  field_column_names: à¸ªà¸”à¸¡à¸ à¹Œ
+  field_time_zone: à¸¢à¹ˆà¸²à¸™à¹€à¸§à¸¥à¸²
+  field_searchable: à¸„à¹‰à¸™à¸«à¸²à¹„à¸”à¹‰
+  field_default_value: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
+  field_comments_sorting: à¹à¸ªà¸”à¸‡à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
+
+  setting_app_title: à¸Šà¸·à¹ˆà¸­à¹‚à¸›à¸£à¹à¸à¸£à¸¡
+  setting_app_subtitle: à¸Šà¸·à¹ˆà¸­à¹‚à¸›à¸£à¹à¸à¸£à¸¡à¸£à¸­à¸‡
+  setting_welcome_text: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¸•à¹‰à¸­à¸™à¸£à¸±à¸š
+  setting_default_language: à¸ à¸²à¸©à¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
+  setting_login_required: à¸•à¹‰à¸­à¸‡à¸›à¹‰à¸­à¸™à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰-à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
+  setting_self_registration: à¸¥à¸‡à¸—à¸°à¹€à¸šà¸µà¸¢à¸™à¸”à¹‰à¸§à¸¢à¸•à¸™à¹€à¸­à¸‡
+  setting_attachment_max_size: à¸‚à¸™à¸²à¸”à¹à¸Ÿà¹‰à¸¡à¹à¸™à¸šà¸ªà¸¹à¸‡à¸ªà¸¸à¸”
+  setting_issues_export_limit: à¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸à¸›à¸±à¸à¸«à¸²à¸ªà¸¹à¸‡à¸ªà¸¸à¸”
+  setting_mail_from: à¸­à¸µà¹€à¸¡à¸¥à¹Œà¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¸ªà¹ˆà¸‡
+  setting_bcc_recipients: à¹„à¸¡à¹ˆà¸£à¸°à¸šà¸¸à¸Šà¸·à¹ˆà¸­à¸œà¸¹à¹‰à¸£à¸±à¸š (bcc)
+  setting_host_name: à¸Šà¸·à¹ˆà¸­à¹‚à¸®à¸ªà¸•à¹Œ
+  setting_text_formatting: à¸à¸²à¸£à¸ˆà¸±à¸”à¸£à¸¹à¸›à¹à¸šà¸šà¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
+  setting_wiki_compression: à¸šà¸µà¸šà¸­à¸±à¸”à¸›à¸£à¸°à¸§à¸±à¸•à¸´ Wiki
+  setting_feeds_limit: à¸ˆà¸³à¸™à¸§à¸™ Feed
+  setting_default_projects_public: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¹ƒà¸«à¸¡à¹ˆà¸¡à¸µà¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¹€à¸›à¹‡à¸™ à¸ªà¸²à¸˜à¸²à¸£à¸“à¸°
+  setting_autofetch_changesets: à¸”à¸¶à¸‡ commits à¸­à¸±à¸•à¹‚à¸™à¸¡à¸±à¸•à¸´
+  setting_sys_api_enabled: à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰ WS à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
+  setting_commit_ref_keywords: à¸„à¸³à¸ªà¸³à¸„à¸±à¸ Referencing
+  setting_commit_fix_keywords: à¸„à¸³à¸ªà¸³à¸„à¸±à¸ Fixing
+  setting_autologin: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸šà¸­à¸±à¸•à¹‚à¸™à¸¡à¸±à¸•à¸´
+  setting_date_format: à¸£à¸¹à¸›à¹à¸šà¸šà¸§à¸±à¸™à¸—à¸µà¹ˆ
+  setting_time_format: à¸£à¸¹à¸›à¹à¸šà¸šà¹€à¸§à¸¥à¸²
+  setting_cross_project_issue_relations: à¸­à¸™à¸¸à¸à¸²à¸•à¹ƒà¸«à¹‰à¸£à¸°à¸šà¸¸à¸›à¸±à¸à¸«à¸²à¸‚à¹‰à¸²à¸¡à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
+  setting_issue_list_default_columns: à¸ªà¸”à¸¡à¸ à¹Œà¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¹à¸ªà¸”à¸‡à¹ƒà¸™à¸£à¸²à¸¢à¸à¸²à¸£à¸›à¸±à¸à¸«à¸²
+  setting_emails_footer: à¸„à¸³à¸¥à¸‡à¸—à¹‰à¸²à¸¢à¸­à¸µà¹€à¸¡à¸¥à¹Œ
+  setting_protocol: Protocol
+  setting_per_page_options: à¸•à¸±à¸§à¹€à¸¥à¸·à¸­à¸à¸ˆà¸³à¸™à¸§à¸™à¸•à¹ˆà¸­à¸«à¸™à¹‰à¸²
+  setting_user_format: à¸£à¸¹à¸›à¹à¸šà¸šà¸à¸²à¸£à¹à¸ªà¸”à¸‡à¸Šà¸·à¹ˆà¸­à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
+  setting_activity_days_default: à¸ˆà¸³à¸™à¸§à¸™à¸§à¸±à¸™à¸—à¸µà¹ˆà¹à¸ªà¸”à¸‡à¹ƒà¸™à¸à¸´à¸ˆà¸à¸£à¸£à¸¡à¸‚à¸­à¸‡à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
+  setting_display_subprojects_issues: à¹à¸ªà¸”à¸‡à¸›à¸±à¸à¸«à¸²à¸‚à¸­à¸‡à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢à¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸«à¸¥à¸±à¸
+
+  project_module_issue_tracking: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡à¸›à¸±à¸à¸«à¸²
+  project_module_time_tracking: à¸à¸²à¸£à¹ƒà¸Šà¹‰à¹€à¸§à¸¥à¸²
+  project_module_news: à¸‚à¹ˆà¸²à¸§
+  project_module_documents: à¹€à¸­à¸à¸ªà¸²à¸£
+  project_module_files: à¹à¸Ÿà¹‰à¸¡
+  project_module_wiki: Wiki
+  project_module_repository: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
+  project_module_boards: à¸à¸£à¸°à¸”à¸²à¸™à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
+
+  label_user: à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
+  label_user_plural: à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
+  label_user_new: à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¹ƒà¸«à¸¡à¹ˆ
+  label_project: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
+  label_project_new: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¹ƒà¸«à¸¡à¹ˆ
+  label_project_plural: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£
+  label_x_projects:
+    zero:  no projects
+    one:   1 project
+    other: "%{count} projects"
+  label_project_all: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  label_project_latest: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
+  label_issue: à¸›à¸±à¸à¸«à¸²
+  label_issue_new: à¸›à¸±à¸à¸«à¸²à¹ƒà¸«à¸¡à¹ˆ
+  label_issue_plural: à¸›à¸±à¸à¸«à¸²
+  label_issue_view_all: à¸”à¸¹à¸›à¸±à¸à¸«à¸²à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  label_issues_by: "à¸›à¸±à¸à¸«à¸²à¹‚à¸”à¸¢ %{value}"
+  label_issue_added: à¸›à¸±à¸à¸«à¸²à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
+  label_issue_updated: à¸›à¸±à¸à¸«à¸²à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡
+  label_document: à¹€à¸­à¸à¸ªà¸²à¸£
+  label_document_new: à¹€à¸­à¸à¸ªà¸²à¸£à¹ƒà¸«à¸¡à¹ˆ
+  label_document_plural: à¹€à¸­à¸à¸ªà¸²à¸£
+  label_document_added: à¹€à¸­à¸à¸ªà¸²à¸£à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
+  label_role: à¸šà¸—à¸šà¸²à¸—
+  label_role_plural: à¸šà¸—à¸šà¸²à¸—
+  label_role_new: à¸šà¸—à¸šà¸²à¸—à¹ƒà¸«à¸¡à¹ˆ
+  label_role_and_permissions: à¸šà¸—à¸šà¸²à¸—à¹à¸¥à¸°à¸ªà¸´à¸—à¸˜à¸´
+  label_member: à¸ªà¸¡à¸²à¸Šà¸´à¸
+  label_member_new: à¸ªà¸¡à¸²à¸Šà¸´à¸à¹ƒà¸«à¸¡à¹ˆ
+  label_member_plural: à¸ªà¸¡à¸²à¸Šà¸´à¸
+  label_tracker: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡
+  label_tracker_plural: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡
+  label_tracker_new: à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡à¹ƒà¸«à¸¡à¹ˆ
+  label_workflow: à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™
+  label_issue_status: à¸ªà¸–à¸²à¸™à¸°à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
+  label_issue_status_plural: à¸ªà¸–à¸²à¸™à¸°à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
+  label_issue_status_new: à¸ªà¸–à¸²à¸™à¸°à¹ƒà¸«à¸¡
+  label_issue_category: à¸›à¸£à¸°à¹€à¸ à¸—à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
+  label_issue_category_plural: à¸›à¸£à¸°à¹€à¸ à¸—à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
+  label_issue_category_new: à¸›à¸£à¸°à¹€à¸ à¸—à¹ƒà¸«à¸¡à¹ˆ
+  label_custom_field: à¹€à¸‚à¸•à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¹à¸šà¸šà¸£à¸°à¸šà¸¸à¹€à¸­à¸‡
+  label_custom_field_plural: à¹€à¸‚à¸•à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¹à¸šà¸šà¸£à¸°à¸šà¸¸à¹€à¸­à¸‡
+  label_custom_field_new: à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸‚à¸•à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¹à¸šà¸šà¸£à¸°à¸šà¸¸à¹€à¸­à¸‡
+  label_enumerations: à¸£à¸²à¸¢à¸à¸²à¸£
+  label_enumeration_new: à¸ªà¸£à¹‰à¸²à¸‡à¹ƒà¸«à¸¡à¹ˆ
+  label_information: à¸‚à¹‰à¸­à¸¡à¸¹à¸¥
+  label_information_plural: à¸‚à¹‰à¸­à¸¡à¸¹à¸¥
+  label_please_login: à¸à¸£à¸¸à¸“à¸²à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸šà¸à¹ˆà¸­à¸™
+  label_register: à¸¥à¸‡à¸—à¸°à¹€à¸šà¸µà¸¢à¸™
+  label_password_lost: à¸¥à¸·à¸¡à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
+  label_home: à¸«à¸™à¹‰à¸²à¹à¸£à¸
+  label_my_page: à¸«à¸™à¹‰à¸²à¸‚à¸­à¸‡à¸‰à¸±à¸™
+  label_my_account: à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¸‰à¸±à¸™
+  label_my_projects: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸‚à¸­à¸‡à¸‰à¸±à¸™
+  label_administration: à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£
+  label_login: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸š
+  label_logout: à¸­à¸­à¸à¸£à¸°à¸šà¸š
+  label_help: à¸Šà¹ˆà¸§à¸¢à¹€à¸«à¸¥à¸·à¸­
+  label_reported_issues: à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¹à¸ˆà¹‰à¸‡à¹„à¸§à¹‰
+  label_assigned_to_me_issues: à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸¡à¸­à¸šà¸«à¸¡à¸²à¸¢à¹ƒà¸«à¹‰à¸‰à¸±à¸™
+  label_last_login: à¸•à¸´à¸”à¸•à¹ˆà¸­à¸„à¸£à¸±à¹‰à¸‡à¸ªà¸¸à¸”à¸—à¹‰à¸²à¸¢
+  label_registered_on: à¸¥à¸‡à¸—à¸°à¹€à¸šà¸µà¸¢à¸™à¹€à¸¡à¸·à¹ˆà¸­
+  label_activity: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡
+  label_activity_plural: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡
+  label_activity_latest: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
+  label_overall_activity: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡à¹‚à¸”à¸¢à¸£à¸§à¸¡
+  label_new: à¹ƒà¸«à¸¡à¹ˆ
+  label_logged_as: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸šà¹ƒà¸™à¸Šà¸·à¹ˆà¸­
+  label_environment: à¸ªà¸ à¸²à¸žà¹à¸§à¸”à¸¥à¹‰à¸­à¸¡
+  label_authentication: à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™
+  label_auth_source: à¸§à¸´à¸˜à¸µà¸à¸²à¸£à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™
+  label_auth_source_new: à¸ªà¸£à¹‰à¸²à¸‡à¸§à¸´à¸˜à¸µà¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™à¹ƒà¸«à¸¡à¹ˆ
+  label_auth_source_plural: à¸§à¸´à¸˜à¸µà¸à¸²à¸£ Authentication
+  label_subproject_plural: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢
+  label_min_max_length: à¸ªà¸±à¹‰à¸™-à¸¢à¸²à¸§ à¸ªà¸¸à¸”à¸—à¸µà¹ˆ
+  label_list: à¸£à¸²à¸¢à¸à¸²à¸£
+  label_date: à¸§à¸±à¸™à¸—à¸µà¹ˆ
+  label_integer: à¸ˆà¸³à¸™à¸§à¸™à¹€à¸•à¹‡à¸¡
+  label_float: à¸ˆà¸³à¸™à¸§à¸™à¸ˆà¸£à¸´à¸‡
+  label_boolean: à¸–à¸¹à¸à¸œà¸´à¸”
+  label_string: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
+  label_text: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¸‚à¸™à¸²à¸”à¸¢à¸²à¸§
+  label_attribute: à¸„à¸¸à¸“à¸¥à¸±à¸à¸©à¸“à¸°
+  label_attribute_plural: à¸„à¸¸à¸“à¸¥à¸±à¸à¸©à¸“à¸°
+  label_no_data: à¸ˆà¸³à¸™à¸§à¸™à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¸—à¸µà¹ˆà¹à¸ªà¸”à¸‡
+  label_change_status: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸ªà¸–à¸²à¸™à¸°
+  label_history: à¸›à¸£à¸°à¸§à¸±à¸•à¸´
+  label_attachment: à¹à¸Ÿà¹‰à¸¡
+  label_attachment_new: à¹à¸Ÿà¹‰à¸¡à¹ƒà¸«à¸¡à¹ˆ
+  label_attachment_delete: à¸¥à¸šà¹à¸Ÿà¹‰à¸¡
+  label_attachment_plural: à¹à¸Ÿà¹‰à¸¡
+  label_file_added: à¹à¸Ÿà¹‰à¸¡à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
+  label_report: à¸£à¸²à¸¢à¸‡à¸²à¸™
+  label_report_plural: à¸£à¸²à¸¢à¸‡à¸²à¸™
+  label_news: à¸‚à¹ˆà¸²à¸§
+  label_news_new: à¹€à¸žà¸´à¹ˆà¸¡à¸‚à¹ˆà¸²à¸§
+  label_news_plural: à¸‚à¹ˆà¸²à¸§
+  label_news_latest: à¸‚à¹ˆà¸²à¸§à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
+  label_news_view_all: à¸”à¸¹à¸‚à¹ˆà¸²à¸§à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  label_news_added: à¸‚à¹ˆà¸²à¸§à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
+  label_settings: à¸›à¸£à¸±à¸šà¹à¸•à¹ˆà¸‡
+  label_overview: à¸ à¸²à¸žà¸£à¸§à¸¡
+  label_version: à¸£à¸¸à¹ˆà¸™
+  label_version_new: à¸£à¸¸à¹ˆà¸™à¹ƒà¸«à¸¡à¹ˆ
+  label_version_plural: à¸£à¸¸à¹ˆà¸™
+  label_confirmation: à¸¢à¸·à¸™à¸¢à¸±à¸™
+  label_export_to: 'à¸£à¸¹à¸›à¹à¸šà¸šà¸­à¸·à¹ˆà¸™à¹† :'
+  label_read: à¸­à¹ˆà¸²à¸™...
+  label_public_projects: à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸ªà¸²à¸˜à¸²à¸£à¸“à¸°
+  label_open_issues: à¹€à¸›à¸´à¸”
+  label_open_issues_plural: à¹€à¸›à¸´à¸”
+  label_closed_issues: à¸›à¸´à¸”
+  label_closed_issues_plural: à¸›à¸´à¸”
+  label_x_open_issues_abbr_on_total:
+    zero:  0 open / %{total}
+    one:   1 open / %{total}
+    other: "%{count} open / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 open
+    one:   1 open
+    other: "%{count} open"
+  label_x_closed_issues_abbr:
+    zero:  0 closed
+    one:   1 closed
+    other: "%{count} closed"
+  label_total: à¸ˆà¸³à¸™à¸§à¸™à¸£à¸§à¸¡
+  label_permissions: à¸ªà¸´à¸—à¸˜à¸´
+  label_current_status: à¸ªà¸–à¸²à¸™à¸°à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™
+  label_new_statuses_allowed: à¸­à¸™à¸¸à¸à¸²à¸•à¹ƒà¸«à¹‰à¸¡à¸µà¸ªà¸–à¸²à¸™à¸°à¹ƒà¸«à¸¡à¹ˆ
+  label_all: à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  label_none: à¹„à¸¡à¹ˆà¸¡à¸µ
+  label_nobody: à¹„à¸¡à¹ˆà¸¡à¸µà¹ƒà¸„à¸£
+  label_next: à¸•à¹ˆà¸­à¹„à¸›
+  label_previous: à¸à¹ˆà¸­à¸™à¸«à¸™à¹‰à¸²
+  label_used_by: à¸–à¸¹à¸à¹ƒà¸Šà¹‰à¹‚à¸”à¸¢
+  label_details: à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”
+  label_add_note: à¹€à¸žà¸´à¹ˆà¸¡à¸šà¸±à¸™à¸—à¸¶à¸
+  label_per_page: à¸•à¹ˆà¸­à¸«à¸™à¹‰à¸²
+  label_calendar: à¸›à¸à¸´à¸—à¸´à¸™
+  label_months_from: à¹€à¸”à¸·à¸­à¸™à¸ˆà¸²à¸
+  label_gantt: Gantt
+  label_internal: à¸ à¸²à¸¢à¹ƒà¸™
+  label_last_changes: "last %{count} à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡"
+  label_change_view_all: à¸”à¸¹à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  label_personalize_page: à¸›à¸£à¸±à¸šà¹à¸•à¹ˆà¸‡à¸«à¸™à¹‰à¸²à¸™à¸µà¹‰
+  label_comment: à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
+  label_comment_plural: à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
+  label_x_comments:
+    zero: no comments
+    one: 1 comment
+    other: "%{count} comments"
+  label_comment_add: à¹€à¸žà¸´à¹ˆà¸¡à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
+  label_comment_added: à¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
+  label_comment_delete: à¸¥à¸šà¸„à¸§à¸²à¸¡à¹€à¸«à¹‡à¸™
+  label_query: à¹à¸šà¸šà¸ªà¸­à¸šà¸–à¸²à¸¡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”à¹€à¸­à¸‡
+  label_query_plural: à¹à¸šà¸šà¸ªà¸­à¸šà¸–à¸²à¸¡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”à¹€à¸­à¸‡
+  label_query_new: à¹à¸šà¸šà¸ªà¸­à¸šà¸–à¸²à¸¡à¹ƒà¸«à¸¡à¹ˆ
+  label_filter_add: à¹€à¸žà¸´à¹ˆà¸¡à¸•à¸±à¸§à¸à¸£à¸­à¸‡
+  label_filter_plural: à¸•à¸±à¸§à¸à¸£à¸­à¸‡
+  label_equals: à¸„à¸·à¸­
+  label_not_equals: à¹„à¸¡à¹ˆà¹ƒà¸Šà¹ˆ
+  label_in_less_than: à¸™à¹‰à¸­à¸¢à¸à¸§à¹ˆà¸²
+  label_in_more_than: à¸¡à¸²à¸à¸à¸§à¹ˆà¸²
+  label_in: à¹ƒà¸™à¸Šà¹ˆà¸§à¸‡
+  label_today: à¸§à¸±à¸™à¸™à¸µà¹‰
+  label_all_time: à¸•à¸¥à¸­à¸”à¹€à¸§à¸¥à¸²
+  label_yesterday: à¹€à¸¡à¸·à¹ˆà¸­à¸§à¸²à¸™
+  label_this_week: à¸­à¸²à¸—à¸´à¸•à¸¢à¹Œà¸™à¸µà¹‰
+  label_last_week: à¸­à¸²à¸—à¸´à¸•à¸¢à¹Œà¸—à¸µà¹ˆà¹à¸¥à¹‰à¸§
+  label_last_n_days: "%{count} à¸§à¸±à¸™à¸¢à¹‰à¸­à¸™à¸«à¸¥à¸±à¸‡"
+  label_this_month: à¹€à¸”à¸·à¸­à¸™à¸™à¸µà¹‰
+  label_last_month: à¹€à¸”à¸·à¸­à¸™à¸—à¸µà¹ˆà¹à¸¥à¹‰à¸§
+  label_this_year: à¸›à¸µà¸™à¸µà¹‰
+  label_date_range: à¸Šà¹ˆà¸§à¸‡à¸§à¸±à¸™à¸—à¸µà¹ˆ
+  label_less_than_ago: à¸™à¹‰à¸­à¸¢à¸à¸§à¹ˆà¸²à¸«à¸™à¸¶à¹ˆà¸‡à¸§à¸±à¸™
+  label_more_than_ago: à¸¡à¸²à¸à¸à¸§à¹ˆà¸²à¸«à¸™à¸¶à¹ˆà¸‡à¸§à¸±à¸™
+  label_ago: à¸§à¸±à¸™à¸œà¹ˆà¸²à¸™à¸¡à¸²à¹à¸¥à¹‰à¸§
+  label_contains: à¸¡à¸µ...
+  label_not_contains: à¹„à¸¡à¹ˆà¸¡à¸µ...
+  label_day_plural: à¸§à¸±à¸™
+  label_repository: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
+  label_repository_plural: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
+  label_browse: à¹€à¸›à¸´à¸”à¸«à¸²
+  label_revision: à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚
+  label_revision_plural: à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚
+  label_associated_revisions: à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚à¸—à¸µà¹ˆà¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¸­à¸‡
+  label_added: à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡
+  label_modified: à¸–à¸¹à¸à¹à¸à¹‰à¹„à¸‚
+  label_deleted: à¸–à¸¹à¸à¸¥à¸š
+  label_latest_revision: à¸£à¸¸à¹ˆà¸™à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
+  label_latest_revision_plural: à¸£à¸¸à¹ˆà¸™à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
+  label_view_revisions: à¸”à¸¹à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚
+  label_max_size: à¸‚à¸™à¸²à¸”à¹ƒà¸«à¸à¹ˆà¸ªà¸¸à¸”
+  label_sort_highest: à¸¢à¹‰à¸²à¸¢à¹„à¸›à¸šà¸™à¸ªà¸¸à¸”
+  label_sort_higher: à¸¢à¹‰à¸²à¸¢à¸‚à¸¶à¹‰à¸™
+  label_sort_lower: à¸¢à¹‰à¸²à¸¢à¸¥à¸‡
+  label_sort_lowest: à¸¢à¹‰à¸²à¸¢à¹„à¸›à¸¥à¹ˆà¸²à¸‡à¸ªà¸¸à¸”
+  label_roadmap: à¹à¸œà¸™à¸‡à¸²à¸™
+  label_roadmap_due_in: "à¸–à¸¶à¸‡à¸à¸³à¸«à¸™à¸”à¹ƒà¸™ %{value}"
+  label_roadmap_overdue: "%{value} à¸Šà¹‰à¸²à¸à¸§à¹ˆà¸²à¸à¸³à¸«à¸™à¸”"
+  label_roadmap_no_issues: à¹„à¸¡à¹ˆà¸¡à¸µà¸›à¸±à¸à¸«à¸²à¸ªà¸³à¸«à¸£à¸±à¸šà¸£à¸¸à¹ˆà¸™à¸™à¸µà¹‰
+  label_search: à¸„à¹‰à¸™à¸«à¸²
+  label_result_plural: à¸œà¸¥à¸à¸²à¸£à¸„à¹‰à¸™à¸«à¸²
+  label_all_words: à¸—à¸¸à¸à¸„à¸³
+  label_wiki: Wiki
+  label_wiki_edit: à¹à¸à¹‰à¹„à¸‚ Wiki
+  label_wiki_edit_plural: à¹à¸à¹‰à¹„à¸‚ Wiki
+  label_wiki_page: à¸«à¸™à¹‰à¸² Wiki
+  label_wiki_page_plural: à¸«à¸™à¹‰à¸² Wiki
+  label_index_by_title: à¹€à¸£à¸µà¸¢à¸‡à¸•à¸²à¸¡à¸Šà¸·à¹ˆà¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡
+  label_index_by_date: à¹€à¸£à¸µà¸¢à¸‡à¸•à¸²à¸¡à¸§à¸±à¸™
+  label_current_version: à¸£à¸¸à¹ˆà¸™à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™
+  label_preview: à¸•à¸±à¸§à¸­à¸¢à¹ˆà¸²à¸‡à¸à¹ˆà¸­à¸™à¸ˆà¸±à¸”à¹€à¸à¹‡à¸š
+  label_feed_plural: Feeds
+  label_changes_details: à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  label_issue_tracking: à¸•à¸´à¸”à¸•à¸²à¸¡à¸›à¸±à¸à¸«à¸²
+  label_spent_time: à¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰
+  label_f_hour: "%{value} à¸Šà¸±à¹ˆà¸§à¹‚à¸¡à¸‡"
+  label_f_hour_plural: "%{value} à¸Šà¸±à¹ˆà¸§à¹‚à¸¡à¸‡"
+  label_time_tracking: à¸•à¸´à¸”à¸•à¸²à¸¡à¸à¸²à¸£à¹ƒà¸Šà¹‰à¹€à¸§à¸¥à¸²
+  label_change_plural: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡
+  label_statistics: à¸ªà¸–à¸´à¸•à¸´
+  label_commits_per_month: Commits à¸•à¹ˆà¸­à¹€à¸”à¸·à¸­à¸™
+  label_commits_per_author: Commits à¸•à¹ˆà¸­à¸œà¸¹à¹‰à¹à¸•à¹ˆà¸‡
+  label_view_diff: à¸”à¸¹à¸„à¸§à¸²à¸¡à¹à¸•à¸à¸•à¹ˆà¸²à¸‡
+  label_diff_inline: inline
+  label_diff_side_by_side: side by side
+  label_options: à¸•à¸±à¸§à¹€à¸¥à¸·à¸­à¸
+  label_copy_workflow_from: à¸„à¸±à¸”à¸¥à¸­à¸à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™à¸ˆà¸²à¸
+  label_permissions_report: à¸£à¸²à¸¢à¸‡à¸²à¸™à¸ªà¸´à¸—à¸˜à¸´
+  label_watched_issues: à¹€à¸à¹‰à¸²à¸”à¸¹à¸›à¸±à¸à¸«à¸²
+  label_related_issues: à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¸­à¸‡
+  label_applied_status: à¸ˆà¸±à¸”à¹€à¸à¹‡à¸šà¸ªà¸–à¸²à¸™à¸°
+  label_loading: à¸à¸³à¸¥à¸±à¸‡à¹‚à¸«à¸¥à¸”...
+  label_relation_new: à¸„à¸§à¸²à¸¡à¸ªà¸±à¸¡à¸žà¸±à¸™à¸˜à¹Œà¹ƒà¸«à¸¡à¹ˆ
+  label_relation_delete: à¸¥à¸šà¸„à¸§à¸²à¸¡à¸ªà¸±à¸¡à¸žà¸±à¸™à¸˜à¹Œ
+  label_relates_to: à¸ªà¸±à¸¡à¸žà¸±à¸™à¸˜à¹Œà¸à¸±à¸š
+  label_duplicates: à¸‹à¹‰à¸³
+  label_blocks: à¸à¸µà¸”à¸à¸±à¸™
+  label_blocked_by: à¸à¸µà¸”à¸à¸±à¸™à¹‚à¸”à¸¢
+  label_precedes: à¸™à¸³à¸«à¸™à¹‰à¸²
+  label_follows: à¸•à¸²à¸¡à¸«à¸¥à¸±à¸‡
+  label_end_to_start: à¸ˆà¸š-à¹€à¸£à¸´à¹ˆà¸¡
+  label_end_to_end: à¸ˆà¸š-à¸ˆà¸š
+  label_start_to_start: à¹€à¸£à¸´à¹ˆà¸¡-à¹€à¸£à¸´à¹ˆà¸¡
+  label_start_to_end: à¹€à¸£à¸´à¹ˆà¸¡-à¸ˆà¸š
+  label_stay_logged_in: à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¸£à¸°à¸šà¸šà¸•à¹ˆà¸­
+  label_disabled: à¹„à¸¡à¹ˆà¹ƒà¸Šà¹‰à¸‡à¸²à¸™
+  label_show_completed_versions: à¹à¸ªà¸”à¸‡à¸£à¸¸à¹ˆà¸™à¸—à¸µà¹ˆà¸ªà¸¡à¸šà¸¹à¸£à¸“à¹Œ
+  label_me: à¸‰à¸±à¸™
+  label_board: à¸ªà¸ à¸²à¸à¸²à¹à¸Ÿ
+  label_board_new: à¸ªà¸£à¹‰à¸²à¸‡à¸ªà¸ à¸²à¸à¸²à¹à¸Ÿ
+  label_board_plural: à¸ªà¸ à¸²à¸à¸²à¹à¸Ÿ
+  label_topic_plural: à¸«à¸±à¸§à¸‚à¹‰à¸­
+  label_message_plural: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
+  label_message_last: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¸¥à¹ˆà¸²à¸ªà¸¸à¸”
+  label_message_new: à¹€à¸‚à¸µà¸¢à¸™à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¹ƒà¸«à¸¡à¹ˆ
+  label_message_posted: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¸–à¸¹à¸à¹€à¸žà¸´à¹ˆà¸¡à¹à¸¥à¹‰à¸§
+  label_reply_plural: à¸•à¸­à¸šà¸à¸¥à¸±à¸š
+  label_send_information: à¸ªà¹ˆà¸‡à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”à¸‚à¸­à¸‡à¸šà¸±à¸à¸Šà¸µà¹ƒà¸«à¹‰à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
+  label_year: à¸›à¸µ
+  label_month: à¹€à¸”à¸·à¸­à¸™
+  label_week: à¸ªà¸±à¸›à¸”à¸²à¸«à¹Œ
+  label_date_from: à¸ˆà¸²à¸
+  label_date_to: à¸–à¸¶à¸‡
+  label_language_based: à¸‚à¸¶à¹‰à¸™à¸­à¸¢à¸¹à¹ˆà¸à¸±à¸šà¸ à¸²à¸©à¸²à¸‚à¸­à¸‡à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
+  label_sort_by: "à¹€à¸£à¸µà¸¢à¸‡à¹‚à¸”à¸¢ %{value}"
+  label_send_test_email: à¸ªà¹ˆà¸‡à¸ˆà¸”à¸«à¸¡à¸²à¸¢à¸—à¸”à¸ªà¸­à¸š
+  label_feeds_access_key_created_on: "RSS access key à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸¡à¸·à¹ˆà¸­ %{value} à¸—à¸µà¹ˆà¸œà¹ˆà¸²à¸™à¸¡à¸²"
+  label_module_plural: à¸ªà¹ˆà¸§à¸™à¸›à¸£à¸°à¸à¸­à¸š
+  label_added_time_by: "à¹€à¸žà¸´à¹ˆà¸¡à¹‚à¸”à¸¢ %{author} %{age} à¸—à¸µà¹ˆà¸œà¹ˆà¸²à¸™à¸¡à¸²"
+  label_updated_time: "à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡ %{value} à¸—à¸µà¹ˆà¸œà¹ˆà¸²à¸™à¸¡à¸²"
+  label_jump_to_a_project: à¹„à¸›à¸—à¸µà¹ˆà¹‚à¸„à¸£à¸‡à¸à¸²à¸£...
+  label_file_plural: à¹à¸Ÿà¹‰à¸¡
+  label_changeset_plural: à¸à¸¥à¸¸à¹ˆà¸¡à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡
+  label_default_columns: à¸ªà¸”à¸¡à¸ à¹Œà¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
+  label_no_change_option: (à¹„à¸¡à¹ˆà¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡)
+  label_bulk_edit_selected_issues: à¹à¸à¹‰à¹„à¸‚à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¹€à¸¥à¸·à¸­à¸à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  label_theme: à¸Šà¸¸à¸”à¸£à¸¹à¸›à¹à¸šà¸š
+  label_default: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
+  label_search_titles_only: à¸„à¹‰à¸™à¸«à¸²à¸ˆà¸²à¸à¸Šà¸·à¹ˆà¸­à¹€à¸£à¸·à¹ˆà¸­à¸‡à¹€à¸—à¹ˆà¸²à¸™à¸±à¹‰à¸™
+  label_user_mail_option_all: "à¸—à¸¸à¸à¹† à¹€à¸«à¸•à¸¸à¸à¸²à¸£à¸“à¹Œà¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸‚à¸­à¸‡à¸‰à¸±à¸™"
+  label_user_mail_option_selected: "à¸—à¸¸à¸à¹† à¹€à¸«à¸•à¸¸à¸à¸²à¸£à¸“à¹Œà¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸—à¸µà¹ˆà¹€à¸¥à¸·à¸­à¸..."
+  label_user_mail_no_self_notified: "à¸‰à¸±à¸™à¹„à¸¡à¹ˆà¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹„à¸”à¹‰à¸£à¸±à¸šà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸•à¸·à¸­à¸™à¹ƒà¸™à¸ªà¸´à¹ˆà¸‡à¸—à¸µà¹ˆà¸‰à¸±à¸™à¸—à¸³à¹€à¸­à¸‡"
+  label_registration_activation_by_email: à¹€à¸›à¸´à¸”à¸šà¸±à¸à¸Šà¸µà¸œà¹ˆà¸²à¸™à¸­à¸µà¹€à¸¡à¸¥à¹Œ
+  label_registration_manual_activation: à¸­à¸™à¸¸à¸¡à¸±à¸•à¸´à¹‚à¸”à¸¢à¸œà¸¹à¹‰à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£
+  label_registration_automatic_activation: à¹€à¸›à¸´à¸”à¸šà¸±à¸à¸Šà¸µà¸­à¸±à¸•à¹‚à¸™à¸¡à¸±à¸•à¸´
+  label_display_per_page: "à¸•à¹ˆà¸­à¸«à¸™à¹‰à¸²: %{value}"
+  label_age: à¸­à¸²à¸¢à¸¸
+  label_change_properties: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸„à¸¸à¸“à¸ªà¸¡à¸šà¸±à¸•à¸´
+  label_general: à¸—à¸±à¹ˆà¸§à¹† à¹„à¸›
+  label_more: à¸­à¸·à¹ˆà¸™ à¹†
+  label_scm: à¸•à¸±à¸§à¸ˆà¸±à¸”à¸à¸²à¸£à¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
+  label_plugins: à¸ªà¹ˆà¸§à¸™à¹€à¸ªà¸£à¸´à¸¡
+  label_ldap_authentication: à¸à¸²à¸£à¸¢à¸·à¸™à¸¢à¸±à¸™à¸•à¸±à¸§à¸•à¸™à¹‚à¸”à¸¢à¹ƒà¸Šà¹‰ LDAP
+  label_downloads_abbr: D/L
+  label_optional_description: à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”à¹€à¸žà¸´à¹ˆà¸¡à¹€à¸•à¸´à¸¡
+  label_add_another_file: à¹€à¸žà¸´à¹ˆà¸¡à¹à¸Ÿà¹‰à¸¡à¸­à¸·à¹ˆà¸™à¹†
+  label_preferences: à¸„à¹ˆà¸²à¸—à¸µà¹ˆà¸Šà¸­à¸šà¹ƒà¸ˆ
+  label_chronological_order: à¹€à¸£à¸µà¸¢à¸‡à¸ˆà¸²à¸à¹€à¸à¹ˆà¸²à¹„à¸›à¹ƒà¸«à¸¡à¹ˆ
+  label_reverse_chronological_order: à¹€à¸£à¸µà¸¢à¸‡à¸ˆà¸²à¸à¹ƒà¸«à¸¡à¹ˆà¹„à¸›à¹€à¸à¹ˆà¸²
+  label_planning: à¸à¸²à¸£à¸§à¸²à¸‡à¹à¸œà¸™
+
+  button_login: à¹€à¸‚à¹‰à¸²à¸£à¸°à¸šà¸š
+  button_submit: à¸ˆà¸±à¸”à¸ªà¹ˆà¸‡à¸‚à¹‰à¸­à¸¡à¸¹à¸¥
+  button_save: à¸ˆà¸±à¸”à¹€à¸à¹‡à¸š
+  button_check_all: à¹€à¸¥à¸·à¸­à¸à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  button_uncheck_all: à¹„à¸¡à¹ˆà¹€à¸¥à¸·à¸­à¸à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  button_delete: à¸¥à¸š
+  button_create: à¸ªà¸£à¹‰à¸²à¸‡
+  button_test: à¸—à¸”à¸ªà¸­à¸š
+  button_edit: à¹à¸à¹‰à¹„à¸‚
+  button_add: à¹€à¸žà¸´à¹ˆà¸¡
+  button_change: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡
+  button_apply: à¸›à¸£à¸°à¸¢à¸¸à¸à¸•à¹Œà¹ƒà¸Šà¹‰
+  button_clear: à¸¥à¹‰à¸²à¸‡à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡
+  button_lock: à¸¥à¹‡à¸­à¸„
+  button_unlock: à¸¢à¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸¥à¹‡à¸­à¸„
+  button_download: à¸”à¸²à¸§à¸™à¹Œà¹‚à¸«à¸¥à¸”
+  button_list: à¸£à¸²à¸¢à¸à¸²à¸£
+  button_view: à¸¡à¸¸à¸¡à¸¡à¸­à¸‡
+  button_move: à¸¢à¹‰à¸²à¸¢
+  button_back: à¸à¸¥à¸±à¸š
+  button_cancel: à¸¢à¸à¹€à¸¥à¸´à¸
+  button_activate: à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰
+  button_sort: à¸ˆà¸±à¸”à¹€à¸£à¸µà¸¢à¸‡
+  button_log_time: à¸šà¸±à¸™à¸—à¸¶à¸à¹€à¸§à¸¥à¸²
+  button_rollback: à¸–à¸­à¸¢à¸à¸¥à¸±à¸šà¸¡à¸²à¸—à¸µà¹ˆà¸£à¸¸à¹ˆà¸™à¸™à¸µà¹‰
+  button_watch: à¹€à¸à¹‰à¸²à¸”à¸¹
+  button_unwatch: à¹€à¸¥à¸´à¸à¹€à¸à¹‰à¸²à¸”à¸¹
+  button_reply: à¸•à¸­à¸šà¸à¸¥à¸±à¸š
+  button_archive: à¹€à¸à¹‡à¸šà¹€à¸‚à¹‰à¸²à¹‚à¸à¸”à¸±à¸‡
+  button_unarchive: à¹€à¸­à¸²à¸­à¸­à¸à¸ˆà¸²à¸à¹‚à¸à¸”à¸±à¸‡
+  button_reset: à¹€à¸£à¸´à¹ˆà¸¡à¹ƒà¸«à¸¡à¸—
+  button_rename: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸Šà¸·à¹ˆà¸­
+  button_change_password: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸£à¸«à¸±à¸ªà¸œà¹ˆà¸²à¸™
+  button_copy: à¸„à¸±à¸”à¸¥à¸­à¸
+  button_annotate: à¸«à¸¡à¸²à¸¢à¹€à¸«à¸•à¸¸à¸›à¸£à¸°à¸à¸­à¸š
+  button_update: à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡
+  button_configure: à¸›à¸£à¸±à¸šà¹à¸•à¹ˆà¸‡
+
+  status_active: à¹€à¸›à¸´à¸”à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹à¸¥à¹‰à¸§
+  status_registered: à¸£à¸­à¸à¸²à¸£à¸­à¸™à¸¸à¸¡à¸±à¸•à¸´
+  status_locked: à¸¥à¹‡à¸­à¸„
+
+  text_select_mail_notifications: à¹€à¸¥à¸·à¸­à¸à¸à¸²à¸£à¸à¸£à¸°à¸—à¸³à¸—à¸µà¹ˆà¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹ƒà¸«à¹‰à¸ªà¹ˆà¸‡à¸­à¸µà¹€à¸¡à¸¥à¹Œà¹à¸ˆà¹‰à¸‡.
+  text_regexp_info: à¸•à¸±à¸§à¸­à¸¢à¹ˆà¸²à¸‡ ^[A-Z0-9]+$
+  text_min_max_length_info: 0 à¸«à¸¡à¸²à¸¢à¸–à¸¶à¸‡à¹„à¸¡à¹ˆà¸ˆà¸³à¸à¸±à¸”
+  text_project_destroy_confirmation: à¸„à¸¸à¸“à¹à¸™à¹ˆà¹ƒà¸ˆà¹„à¸«à¸¡à¸§à¹ˆà¸²à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸¥à¸šà¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¹à¸¥à¸°à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¸—à¸µà¹ˆà¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¹ˆà¸­à¸‡ ?
+  text_subprojects_destroy_warning: "à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸¢à¹ˆà¸­à¸¢: %{value} à¸ˆà¸°à¸–à¸¹à¸à¸¥à¸šà¸”à¹‰à¸§à¸¢."
+  text_workflow_edit: à¹€à¸¥à¸·à¸­à¸à¸šà¸—à¸šà¸²à¸—à¹à¸¥à¸°à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡ à¹€à¸žà¸·à¹ˆà¸­à¹à¸à¹‰à¹„à¸‚à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™
+  text_are_you_sure: à¸„à¸¸à¸“à¹à¸™à¹ˆà¹ƒà¸ˆà¹„à¸«à¸¡ ?
+  text_tip_issue_begin_day: à¸‡à¸²à¸™à¸—à¸µà¹ˆà¹€à¸£à¸´à¹ˆà¸¡à¸§à¸±à¸™à¸™à¸µà¹‰
+  text_tip_issue_end_day: à¸‡à¸²à¸™à¸—à¸µà¹ˆà¸ˆà¸šà¸§à¸±à¸™à¸™à¸µà¹‰
+  text_tip_issue_begin_end_day: à¸‡à¸²à¸™à¸—à¸µà¹ˆà¹€à¸£à¸´à¹ˆà¸¡à¹à¸¥à¸°à¸ˆà¸šà¸§à¸±à¸™à¸™à¸µà¹‰
+  text_caracters_maximum: "à¸ªà¸¹à¸‡à¸ªà¸¸à¸” %{count} à¸•à¸±à¸§à¸­à¸±à¸à¸©à¸£."
+  text_caracters_minimum: "à¸•à¹‰à¸­à¸‡à¸¢à¸²à¸§à¸­à¸¢à¹ˆà¸²à¸‡à¸™à¹‰à¸­à¸¢ %{count} à¸•à¸±à¸§à¸­à¸±à¸à¸©à¸£."
+  text_length_between: "à¸„à¸§à¸²à¸¡à¸¢à¸²à¸§à¸£à¸°à¸«à¸§à¹ˆà¸²à¸‡ %{min} à¸–à¸¶à¸‡ %{max} à¸•à¸±à¸§à¸­à¸±à¸à¸©à¸£."
+  text_tracker_no_workflow: à¹„à¸¡à¹ˆà¹„à¸”à¹‰à¸šà¸±à¸à¸à¸±à¸•à¸´à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™à¸ªà¸³à¸«à¸£à¸±à¸šà¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡à¸™à¸µà¹‰
+  text_unallowed_characters: à¸•à¸±à¸§à¸­à¸±à¸à¸©à¸£à¸•à¹‰à¸­à¸‡à¸«à¹‰à¸²à¸¡
+  text_comma_separated: à¹ƒà¸ªà¹ˆà¹„à¸”à¹‰à¸«à¸¥à¸²à¸¢à¸„à¹ˆà¸² à¹‚à¸”à¸¢à¸„à¸±à¹ˆà¸™à¸”à¹‰à¸§à¸¢à¸¥à¸¹à¸à¸™à¹‰à¸³( ,).
+  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
+  text_issue_added: "à¸›à¸±à¸à¸«à¸² %{id} à¸–à¸¹à¸à¹à¸ˆà¹‰à¸‡à¹‚à¸”à¸¢ %{author}."
+  text_issue_updated: "à¸›à¸±à¸à¸«à¸² %{id} à¸–à¸¹à¸à¸›à¸£à¸±à¸šà¸›à¸£à¸¸à¸‡à¹‚à¸”à¸¢ %{author}."
+  text_wiki_destroy_confirmation: à¸„à¸¸à¸“à¹à¸™à¹ˆà¹ƒà¸ˆà¸«à¸£à¸·à¸­à¸§à¹ˆà¸²à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸¥à¸š wiki à¸™à¸µà¹‰à¸žà¸£à¹‰à¸­à¸¡à¸—à¸±à¹‰à¸‡à¹€à¸™à¸µà¹‰à¸­à¸«à¸²?
+  text_issue_category_destroy_question: "à¸šà¸²à¸‡à¸›à¸±à¸à¸«à¸² (%{count}) à¸­à¸¢à¸¹à¹ˆà¹ƒà¸™à¸›à¸£à¸°à¹€à¸ à¸—à¸™à¸µà¹‰. à¸„à¸¸à¸“à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸—à¸³à¸­à¸¢à¹ˆà¸²à¸‡à¹„à¸£ ?"
+  text_issue_category_destroy_assignments: à¸¥à¸šà¸›à¸£à¸°à¹€à¸ à¸—à¸™à¸µà¹‰
+  text_issue_category_reassign_to: à¸£à¸°à¸šà¸¸à¸›à¸±à¸à¸«à¸²à¹ƒà¸™à¸›à¸£à¸°à¹€à¸ à¸—à¸™à¸µà¹‰
+  text_user_mail_option: "à¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸—à¸µà¹ˆà¹„à¸¡à¹ˆà¹„à¸”à¹‰à¹€à¸¥à¸·à¸­à¸, à¸„à¸¸à¸“à¸ˆà¸°à¹„à¸”à¹‰à¸£à¸±à¸šà¸à¸²à¸£à¹à¸ˆà¹‰à¸‡à¹€à¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸ªà¸´à¹ˆà¸‡à¸—à¸µà¹ˆà¸„à¸¸à¸“à¹€à¸à¹‰à¸²à¸”à¸¹à¸«à¸£à¸·à¸­à¸¡à¸µà¸ªà¹ˆà¸§à¸™à¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¸­à¸‡ (à¹€à¸Šà¹ˆà¸™à¸›à¸±à¸à¸«à¸²à¸—à¸µà¹ˆà¸„à¸¸à¸“à¹à¸ˆà¹‰à¸‡à¹„à¸§à¹‰à¸«à¸£à¸·à¸­à¹„à¸”à¹‰à¸£à¸±à¸šà¸¡à¸­à¸šà¸«à¸¡à¸²à¸¢)."
+  text_no_configuration_data: "à¸šà¸—à¸šà¸²à¸—, à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡, à¸ªà¸–à¸²à¸™à¸°à¸›à¸±à¸à¸«à¸² à¹à¸¥à¸°à¸¥à¸³à¸”à¸±à¸šà¸‡à¸²à¸™à¸¢à¸±à¸‡à¹„à¸¡à¹ˆà¹„à¸”à¹‰à¸–à¸¹à¸à¸•à¸±à¹‰à¸‡à¸„à¹ˆà¸².\nà¸‚à¸­à¹à¸™à¸°à¸™à¸³à¹ƒà¸«à¹‰à¹‚à¸«à¸¥à¸”à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™. à¸„à¸¸à¸“à¸ªà¸²à¸¡à¸²à¸£à¸–à¹à¸à¹‰à¹„à¸‚à¸„à¹ˆà¸²à¹„à¸”à¹‰à¸«à¸¥à¸±à¸‡à¸ˆà¸²à¸à¹‚à¸«à¸¥à¸”à¹à¸¥à¹‰à¸§."
+  text_load_default_configuration: à¹‚à¸«à¸¥à¸”à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™
+  text_status_changed_by_changeset: "à¸›à¸£à¸°à¸¢à¸¸à¸à¸•à¹Œà¹ƒà¸Šà¹‰à¹ƒà¸™à¸à¸¥à¸¸à¹ˆà¸¡à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡ %{value}."
+  text_issues_destroy_confirmation: 'à¸„à¸¸à¸“à¹à¸™à¹ˆà¹ƒà¸ˆà¹„à¸«à¸¡à¸§à¹ˆà¸²à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸¥à¸šà¸›à¸±à¸à¸«à¸²(à¸—à¸±à¹‰à¸‡à¸«à¸¥à¸²à¸¢)à¸—à¸µà¹ˆà¹€à¸¥à¸·à¸­à¸à¹„à¸§à¹‰?'
+  text_select_project_modules: 'à¹€à¸¥à¸·à¸­à¸à¸ªà¹ˆà¸§à¸™à¸›à¸£à¸°à¸à¸­à¸šà¸—à¸µà¹ˆà¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸ªà¸³à¸«à¸£à¸±à¸šà¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸™à¸µà¹‰:'
+  text_default_administrator_account_changed: à¸„à¹ˆà¸²à¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™à¸‚à¸­à¸‡à¸šà¸±à¸à¸Šà¸µà¸œà¸¹à¹‰à¸šà¸£à¸´à¸«à¸²à¸£à¸ˆà¸±à¸”à¸à¸²à¸£à¸–à¸¹à¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡
+  text_file_repository_writable: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸šà¸ªà¸²à¸¡à¸²à¸£à¸–à¹€à¸‚à¸µà¸¢à¸™à¹„à¸”à¹‰
+  text_rmagick_available: RMagick à¸¡à¸µà¹ƒà¸«à¹‰à¹ƒà¸Šà¹‰ (à¹€à¸›à¹‡à¸™à¸•à¸±à¸§à¹€à¸¥à¸·à¸­à¸)
+  text_destroy_time_entries_question: "%{hours} à¸Šà¸±à¹ˆà¸§à¹‚à¸¡à¸‡à¸—à¸µà¹ˆà¸–à¸¹à¸à¹à¸ˆà¹‰à¸‡à¹ƒà¸™à¸›à¸±à¸à¸«à¸²à¸™à¸µà¹‰à¸ˆà¸°à¹‚à¸”à¸™à¸¥à¸š. à¸„à¸¸à¸“à¸•à¹‰à¸­à¸‡à¸à¸²à¸£à¸—à¸³à¸­à¸¢à¹ˆà¸²à¸‡à¹„à¸£?"
+  text_destroy_time_entries: à¸¥à¸šà¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¸£à¸²à¸¢à¸‡à¸²à¸™à¹„à¸§à¹‰
+  text_assign_time_entries_to_project: à¸£à¸°à¸šà¸¸à¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸™à¸µà¹‰
+  text_reassign_time_entries: 'à¸£à¸°à¸šà¸¸à¹€à¸§à¸¥à¸²à¸—à¸µà¹ˆà¹ƒà¸Šà¹‰à¹ƒà¸™à¹‚à¸„à¸£à¸‡à¸à¸²à¸£à¸™à¸µà¹ˆà¸­à¸µà¸à¸„à¸£à¸±à¹‰à¸‡:'
+
+  default_role_manager: à¸œà¸¹à¹‰à¸ˆà¸±à¸”à¸à¸²à¸£
+  default_role_developer: à¸œà¸¹à¹‰à¸žà¸±à¸’à¸™à¸²
+  default_role_reporter: à¸œà¸¹à¹‰à¸£à¸²à¸¢à¸‡à¸²à¸™
+  default_tracker_bug: à¸šà¸±à¹Šà¸
+  default_tracker_feature: à¸¥à¸±à¸à¸©à¸“à¸°à¹€à¸”à¹ˆà¸™
+  default_tracker_support: à¸ªà¸™à¸±à¸šà¸ªà¸™à¸¸à¸™
+  default_issue_status_new: à¹€à¸à¸´à¸”à¸‚à¸¶à¹‰à¸™
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: à¸”à¸³à¹€à¸™à¸´à¸™à¸à¸²à¸£
+  default_issue_status_feedback: à¸£à¸­à¸„à¸³à¸•à¸­à¸š
+  default_issue_status_closed: à¸ˆà¸š
+  default_issue_status_rejected: à¸¢à¸à¹€à¸¥à¸´à¸
+  default_doc_category_user: à¹€à¸­à¸à¸ªà¸²à¸£à¸‚à¸­à¸‡à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰
+  default_doc_category_tech: à¹€à¸­à¸à¸ªà¸²à¸£à¸—à¸²à¸‡à¹€à¸—à¸„à¸™à¸´à¸„
+  default_priority_low: à¸•à¹ˆà¸³
+  default_priority_normal: à¸›à¸à¸•à¸´
+  default_priority_high: à¸ªà¸¹à¸‡
+  default_priority_urgent: à¹€à¸£à¹ˆà¸‡à¸”à¹ˆà¸§à¸™
+  default_priority_immediate: à¸”à¹ˆà¸§à¸™à¸¡à¸²à¸
+  default_activity_design: à¸­à¸­à¸à¹à¸šà¸š
+  default_activity_development: à¸žà¸±à¸’à¸™à¸²
+
+  enumeration_issue_priorities: à¸„à¸§à¸²à¸¡à¸ªà¸³à¸„à¸±à¸à¸‚à¸­à¸‡à¸›à¸±à¸à¸«à¸²
+  enumeration_doc_categories: à¸›à¸£à¸°à¹€à¸ à¸—à¹€à¸­à¸à¸ªà¸²à¸£
+  enumeration_activities: à¸à¸´à¸ˆà¸à¸£à¸£à¸¡ (à¹ƒà¸Šà¹‰à¹ƒà¸™à¸à¸²à¸£à¸•à¸´à¸”à¸•à¸²à¸¡à¹€à¸§à¸¥à¸²)
+  label_and_its_subprojects: "%{value} and its subprojects"
+  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
+  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
+  text_user_wrote: "%{value} wrote:"
+  label_duplicated_by: duplicated by
+  setting_enabled_scm: Enabled SCM
+  text_enumeration_category_reassign_to: 'Reassign them to this value:'
+  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
+  label_incoming_emails: Incoming emails
+  label_generate_key: Generate a key
+  setting_mail_handler_api_enabled: Enable WS for incoming emails
+  setting_mail_handler_api_key: API key
+  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
+  field_parent_title: Parent page
+  label_issue_watchers: Watchers
+  button_quote: Quote
+  setting_sequential_project_identifiers: Generate sequential project identifiers
+  notice_unable_delete_version: Unable to delete version
+  label_renamed: renamed
+  label_copied: copied
+  setting_plain_text_mail: plain text only (no HTML)
+  permission_view_files: View files
+  permission_edit_issues: Edit issues
+  permission_edit_own_time_entries: Edit own time logs
+  permission_manage_public_queries: Manage public queries
+  permission_add_issues: Add issues
+  permission_log_time: Log spent time
+  permission_view_changesets: View changesets
+  permission_view_time_entries: View spent time
+  permission_manage_versions: Manage versions
+  permission_manage_wiki: Manage wiki
+  permission_manage_categories: Manage issue categories
+  permission_protect_wiki_pages: Protect wiki pages
+  permission_comment_news: Comment news
+  permission_delete_messages: Delete messages
+  permission_select_project_modules: Select project modules
+  permission_edit_wiki_pages: Edit wiki pages
+  permission_add_issue_watchers: Add watchers
+  permission_view_gantt: View gantt chart
+  permission_move_issues: Move issues
+  permission_manage_issue_relations: Manage issue relations
+  permission_delete_wiki_pages: Delete wiki pages
+  permission_manage_boards: Manage boards
+  permission_delete_wiki_pages_attachments: Delete attachments
+  permission_view_wiki_edits: View wiki history
+  permission_add_messages: Post messages
+  permission_view_messages: View messages
+  permission_manage_files: Manage files
+  permission_edit_issue_notes: Edit notes
+  permission_manage_news: Manage news
+  permission_view_calendar: View calendrier
+  permission_manage_members: Manage members
+  permission_edit_messages: Edit messages
+  permission_delete_issues: Delete issues
+  permission_view_issue_watchers: View watchers list
+  permission_manage_repository: Manage repository
+  permission_commit_access: Commit access
+  permission_browse_repository: Browse repository
+  permission_view_documents: View documents
+  permission_edit_project: Edit project
+  permission_add_issue_notes: Add notes
+  permission_save_queries: Save queries
+  permission_view_wiki_pages: View wiki
+  permission_rename_wiki_pages: Rename wiki pages
+  permission_edit_time_entries: Edit time logs
+  permission_edit_own_issue_notes: Edit own notes
+  setting_gravatar_enabled: Use Gravatar user icons
+  label_example: Example
+  text_repository_usernames_mapping: "Select ou update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  permission_edit_own_messages: Edit own messages
+  permission_delete_own_messages: Delete own messages
+  label_user_activity: "%{value}'s activity"
+  label_updated_time_by: "Updated by %{author} %{age} ago"
+  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
+  setting_diff_max_lines_displayed: Max number of diff lines displayed
+  text_plugin_assets_writable: Plugin assets directory writable
+  warning_attachments_not_saved: "%{count} file(s) could not be saved."
+  button_create_and_continue: Create and continue
+  text_custom_field_possible_values_info: 'One line for each value'
+  label_display: Display
+  field_editable: Editable
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_file_max_size_displayed: Max size of text files displayed inline
+  field_watcher: Watcher
+  setting_openid: Allow OpenID login and registration
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: or login with OpenID
+  field_content: Content
+  label_descending: Descending
+  label_sort: Sort
+  label_ascending: Ascending
+  label_date_from_to: From %{start} to %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
+  text_wiki_page_reassign_children: Reassign child pages to this parent page
+  text_wiki_page_nullify_children: Keep child pages as root pages
+  text_wiki_page_destroy_children: Delete child pages and all their descendants
+  setting_password_min_length: Minimum password length
+  field_group_by: Group results by
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  label_wiki_content_added: Wiki page added
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
+  label_wiki_content_updated: Wiki page updated
+  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
+  permission_add_project: Create project
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  label_view_all_revisions: View all revisions
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
+  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
+  text_journal_changed: "%{label} changed from %{old} to %{new}"
+  text_journal_set_to: "%{label} set to %{value}"
+  text_journal_deleted: "%{label} deleted (%{old})"
+  label_group_plural: Groups
+  label_group: Group
+  label_group_new: New group
+  label_time_entry_plural: Spent time
+  text_journal_added: "%{label} %{value} added"
+  field_active: Active
+  enumeration_system_activity: System Activity
+  permission_delete_issue_watchers: Delete watchers
+  version_status_closed: closed
+  version_status_locked: locked
+  version_status_open: open
+  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
+  label_user_anonymous: Anonymous
+  button_move_and_follow: Move and follow
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_gravatar_default: Default Gravatar image
+  field_sharing: Sharing
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_system: With all projects
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_tree: With project tree
+  label_version_sharing_none: Not shared
+  error_can_not_archive_project: This project can not be archived
+  button_duplicate: Duplicate
+  button_copy_and_follow: Copy and follow
+  label_copy_source: Source
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_status: Use the issue status
+  error_issue_done_ratios_not_updated: Issue done ratios not updated.
+  error_workflow_copy_target: Please select target tracker(s) and role(s)
+  setting_issue_done_ratio_issue_field: Use the issue field
+  label_copy_same_as_target: Same as target
+  label_copy_target: Target
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  error_workflow_copy_source: Please select a source tracker or role
+  label_update_issue_done_ratios: Update issue done ratios
+  setting_start_of_week: Start calendars on
+  permission_view_issues: View Issues
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_revision_id: Revision %{value}
+  label_api_access_key: API access key
+  label_api_access_key_created_on: API access key created %{value} ago
+  label_feeds_access_key: RSS access key
+  notice_api_access_key_reseted: Your API access key was reset.
+  setting_rest_api_enabled: Enable REST web service
+  label_missing_api_access_key: Missing an API access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  button_show: Show
+  text_line_separated: Multiple values allowed (one line for each value).
+  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
+  permission_add_subprojects: Create subprojects
+  label_subproject_new: New subproject
+  text_own_membership_delete_confirmation: |-
+    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
+    Are you sure you want to continue?
+  label_close_versions: Close completed versions
+  label_board_sticky: Sticky
+  label_board_locked: Locked
+  permission_export_wiki_pages: Export wiki pages
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: Manage project activities
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_profile: Profile
+  permission_manage_subtasks: Manage subtasks
+  field_parent_issue: Parent task
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Commit messages encoding
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 à¸›à¸±à¸à¸«à¸²
+    one:   1 à¸›à¸±à¸à¸«à¸²
+    other: "%{count} à¸›à¸±à¸à¸«à¸²"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: à¸—à¸±à¹‰à¸‡à¸«à¸¡à¸”
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: à¸ˆà¸³à¸™à¸§à¸™à¸£à¸§à¸¡
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c3/c380a8da5e4aab76f8d0af1d1700421b9d214474.svn-base
--- /dev/null
+++ b/.svn/pristine/c3/c380a8da5e4aab76f8d0af1d1700421b9d214474.svn-base
@@ -0,0 +1,77 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class CustomFieldUserFormatTest < ActiveSupport::TestCase
+  fixtures :custom_fields, :projects, :members, :users, :member_roles, :trackers, :issues
+
+  def setup
+    @field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user')
+  end
+
+  def test_possible_values_with_no_arguments
+    assert_equal [], @field.possible_values
+    assert_equal [], @field.possible_values(nil)
+  end
+
+  def test_possible_values_with_project_resource
+    project = Project.find(1)
+    possible_values = @field.possible_values(project.issues.first)
+    assert possible_values.any?
+    assert_equal project.users.sort.collect(&:id).map(&:to_s), possible_values
+  end
+
+  def test_possible_values_with_nil_project_resource
+    project = Project.find(1)
+    assert_equal [], @field.possible_values(Issue.new)
+  end
+
+  def test_possible_values_options_with_no_arguments
+    assert_equal [], @field.possible_values_options
+    assert_equal [], @field.possible_values_options(nil)
+  end
+
+  def test_possible_values_options_with_project_resource
+    project = Project.find(1)
+    possible_values_options = @field.possible_values_options(project.issues.first)
+    assert possible_values_options.any?
+    assert_equal project.users.sort.map {|u| [u.name, u.id.to_s]}, possible_values_options
+  end
+
+  def test_possible_values_options_with_array
+    projects = Project.find([1, 2])
+    possible_values_options = @field.possible_values_options(projects)
+    assert possible_values_options.any?
+    assert_equal (projects.first.users & projects.last.users).sort.map {|u| [u.name, u.id.to_s]}, possible_values_options
+  end
+
+  def test_cast_blank_value
+    assert_equal nil, @field.cast_value(nil)
+    assert_equal nil, @field.cast_value("")
+  end
+
+  def test_cast_valid_value
+    user = @field.cast_value("2")
+    assert_kind_of User, user
+    assert_equal User.find(2), user
+  end
+
+  def test_cast_invalid_value
+    assert_equal nil, @field.cast_value("187")
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c3/c39fa7ae90b01243cdc7410aaa557ea9c9fade29.svn-base
--- a/.svn/pristine/c3/c39fa7ae90b01243cdc7410aaa557ea9c9fade29.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-<h2><%=l(:label_auth_source)%> (<%= h(@auth_source.auth_method_name) %>)</h2>
-
-<% form_tag({:action => 'update', :id => @auth_source}, :class => "tabular") do %>
-  <%= render :partial => 'form' %>
-  <%= submit_tag l(:button_save) %>
-<% end %>
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c3/c3b3fde2322bc5fb3fb730ddaf39d1d7a4bf6387.svn-base
--- a/.svn/pristine/c3/c3b3fde2322bc5fb3fb730ddaf39d1d7a4bf6387.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-# == Using plugin assets for form tag helpers
-#
-# It's as easy to use plugin images for image_submit_tag using Engines as it is for image_tag:
-#
-#   <%= image_submit_tag "my_face", :plugin => "my_plugin" %>
-#
-# ---
-#
-# This module enhances one of the methods from ActionView::Helpers::FormTagHelper:
-#
-#  * image_submit_tag
-#
-# This method now accepts the key/value pair <tt>:plugin => "plugin_name"</tt>,
-# which can be used to specify the originating plugin for any assets.
-#
-module Engines::RailsExtensions::FormTagHelpers
-	def self.included(base)
-		base.class_eval do
-			alias_method_chain :image_submit_tag, :engine_additions
-		end
-	end
-	
-	# Adds plugin functionality to Rails' default image_submit_tag method.
-	def image_submit_tag_with_engine_additions(source, options={})
-		options.stringify_keys!
-		if options["plugin"]
-			source = Engines::RailsExtensions::AssetHelpers.plugin_asset_path(options["plugin"], "images", source)
-			options.delete("plugin")
-		end
-		image_submit_tag_without_engine_additions(source, options)
-	end
-end
-
-module ::ActionView::Helpers::FormTagHelper #:nodoc:
-  include Engines::RailsExtensions::FormTagHelpers
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c3/c3cde01a42095e130d429cd695c3b938d274bb0b.svn-base
--- /dev/null
+++ b/.svn/pristine/c3/c3cde01a42095e130d429cd695c3b938d274bb0b.svn-base
@@ -0,0 +1,438 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class ScmFetchError < Exception; end
+
+class Repository < ActiveRecord::Base
+  include Redmine::Ciphering
+  include Redmine::SafeAttributes
+
+  # Maximum length for repository identifiers
+  IDENTIFIER_MAX_LENGTH = 255
+
+  belongs_to :project
+  has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
+  has_many :filechanges, :class_name => 'Change', :through => :changesets
+
+  serialize :extra_info
+
+  before_save :check_default
+
+  # Raw SQL to delete changesets and changes in the database
+  # has_many :changesets, :dependent => :destroy is too slow for big repositories
+  before_destroy :clear_changesets
+
+  validates_length_of :password, :maximum => 255, :allow_nil => true
+  validates_length_of :identifier, :maximum => IDENTIFIER_MAX_LENGTH, :allow_blank => true
+  validates_presence_of :identifier, :unless => Proc.new { |r| r.is_default? || r.set_as_default? }
+  validates_uniqueness_of :identifier, :scope => :project_id, :allow_blank => true
+  validates_exclusion_of :identifier, :in => %w(show entry raw changes annotate diff show stats graph)
+  # donwcase letters, digits, dashes, underscores but not digits only
+  validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :allow_blank => true
+  # Checks if the SCM is enabled when creating a repository
+  validate :repo_create_validation, :on => :create
+
+  safe_attributes 'identifier',
+    'login',
+    'password',
+    'path_encoding',
+    'log_encoding',
+    'is_default'
+
+  safe_attributes 'url',
+    :if => lambda {|repository, user| repository.new_record?}
+
+  def repo_create_validation
+    unless Setting.enabled_scm.include?(self.class.name.demodulize)
+      errors.add(:type, :invalid)
+    end
+  end
+
+  def self.human_attribute_name(attribute_key_name, *args)
+    attr_name = attribute_key_name.to_s
+    if attr_name == "log_encoding"
+      attr_name = "commit_logs_encoding"
+    end
+    super(attr_name, *args)
+  end
+
+  # Removes leading and trailing whitespace
+  def url=(arg)
+    write_attribute(:url, arg ? arg.to_s.strip : nil)
+  end
+
+  # Removes leading and trailing whitespace
+  def root_url=(arg)
+    write_attribute(:root_url, arg ? arg.to_s.strip : nil)
+  end
+
+  def password
+    read_ciphered_attribute(:password)
+  end
+
+  def password=(arg)
+    write_ciphered_attribute(:password, arg)
+  end
+
+  def scm_adapter
+    self.class.scm_adapter_class
+  end
+
+  def scm
+    unless @scm
+      @scm = self.scm_adapter.new(url, root_url,
+                                  login, password, path_encoding)
+      if root_url.blank? && @scm.root_url.present?
+        update_attribute(:root_url, @scm.root_url)
+      end
+    end
+    @scm
+  end
+
+  def scm_name
+    self.class.scm_name
+  end
+
+  def name
+    if identifier.present?
+      identifier
+    elsif is_default?
+      l(:field_repository_is_default)
+    else
+      scm_name
+    end
+  end
+
+  def identifier=(identifier)
+    super unless identifier_frozen?
+  end
+
+  def identifier_frozen?
+    errors[:identifier].blank? && !(new_record? || identifier.blank?)
+  end
+
+  def identifier_param
+    if is_default?
+      nil
+    elsif identifier.present?
+      identifier
+    else
+      id.to_s
+    end
+  end
+
+  def <=>(repository)
+    if is_default?
+      -1
+    elsif repository.is_default?
+      1
+    else
+      identifier.to_s <=> repository.identifier.to_s
+    end
+  end
+
+  def self.find_by_identifier_param(param)
+    if param.to_s =~ /^\d+$/
+      find_by_id(param)
+    else
+      find_by_identifier(param)
+    end
+  end
+
+  def merge_extra_info(arg)
+    h = extra_info || {}
+    return h if arg.nil?
+    h.merge!(arg)
+    write_attribute(:extra_info, h)
+  end
+
+  def report_last_commit
+    true
+  end
+
+  def supports_cat?
+    scm.supports_cat?
+  end
+
+  def supports_annotate?
+    scm.supports_annotate?
+  end
+
+  def supports_all_revisions?
+    true
+  end
+
+  def supports_directory_revisions?
+    false
+  end
+
+  def supports_revision_graph?
+    false
+  end
+
+  def entry(path=nil, identifier=nil)
+    scm.entry(path, identifier)
+  end
+
+  def entries(path=nil, identifier=nil)
+    entries = scm.entries(path, identifier)
+    load_entries_changesets(entries)
+    entries
+  end
+
+  def branches
+    scm.branches
+  end
+
+  def tags
+    scm.tags
+  end
+
+  def default_branch
+    nil
+  end
+
+  def properties(path, identifier=nil)
+    scm.properties(path, identifier)
+  end
+
+  def cat(path, identifier=nil)
+    scm.cat(path, identifier)
+  end
+
+  def diff(path, rev, rev_to)
+    scm.diff(path, rev, rev_to)
+  end
+
+  def diff_format_revisions(cs, cs_to, sep=':')
+    text = ""
+    text << cs_to.format_identifier + sep if cs_to
+    text << cs.format_identifier if cs
+    text
+  end
+
+  # Returns a path relative to the url of the repository
+  def relative_path(path)
+    path
+  end
+
+  # Finds and returns a revision with a number or the beginning of a hash
+  def find_changeset_by_name(name)
+    return nil if name.blank?
+    s = name.to_s
+    if s.match(/^\d*$/)
+      changesets.where("revision = ?", s).first
+    else
+      changesets.where("revision LIKE ?", s + '%').first
+    end
+  end
+
+  def latest_changeset
+    @latest_changeset ||= changesets.first
+  end
+
+  # Returns the latest changesets for +path+
+  # Default behaviour is to search in cached changesets
+  def latest_changesets(path, rev, limit=10)
+    if path.blank?
+      changesets.find(
+         :all,
+         :include => :user,
+         :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC",
+         :limit => limit)
+    else
+      filechanges.find(
+         :all,
+         :include => {:changeset => :user},
+         :conditions => ["path = ?", path.with_leading_slash],
+         :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC",
+         :limit => limit
+       ).collect(&:changeset)
+    end
+  end
+
+  def scan_changesets_for_issue_ids
+    self.changesets.each(&:scan_comment_for_issue_ids)
+  end
+
+  # Returns an array of committers usernames and associated user_id
+  def committers
+    @committers ||= Changeset.connection.select_rows(
+         "SELECT DISTINCT committer, user_id FROM #{Changeset.table_name} WHERE repository_id = #{id}")
+  end
+
+  # Maps committers username to a user ids
+  def committer_ids=(h)
+    if h.is_a?(Hash)
+      committers.each do |committer, user_id|
+        new_user_id = h[committer]
+        if new_user_id && (new_user_id.to_i != user_id.to_i)
+          new_user_id = (new_user_id.to_i > 0 ? new_user_id.to_i : nil)
+          Changeset.update_all(
+               "user_id = #{ new_user_id.nil? ? 'NULL' : new_user_id }",
+               ["repository_id = ? AND committer = ?", id, committer])
+        end
+      end
+      @committers            = nil
+      @found_committer_users = nil
+      true
+    else
+      false
+    end
+  end
+
+  # Returns the Redmine User corresponding to the given +committer+
+  # It will return nil if the committer is not yet mapped and if no User
+  # with the same username or email was found
+  def find_committer_user(committer)
+    unless committer.blank?
+      @found_committer_users ||= {}
+      return @found_committer_users[committer] if @found_committer_users.has_key?(committer)
+
+      user = nil
+      c = changesets.where(:committer => committer).includes(:user).first
+      if c && c.user
+        user = c.user
+      elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/
+        username, email = $1.strip, $3
+        u = User.find_by_login(username)
+        u ||= User.find_by_mail(email) unless email.blank?
+        user = u
+      end
+      @found_committer_users[committer] = user
+      user
+    end
+  end
+
+  def repo_log_encoding
+    encoding = log_encoding.to_s.strip
+    encoding.blank? ? 'UTF-8' : encoding
+  end
+
+  # Fetches new changesets for all repositories of active projects
+  # Can be called periodically by an external script
+  # eg. ruby script/runner "Repository.fetch_changesets"
+  def self.fetch_changesets
+    Project.active.has_module(:repository).all.each do |project|
+      project.repositories.each do |repository|
+        begin
+          repository.fetch_changesets
+        rescue Redmine::Scm::Adapters::CommandFailed => e
+          logger.error "scm: error during fetching changesets: #{e.message}"
+        end
+      end
+    end
+  end
+
+  # scan changeset comments to find related and fixed issues for all repositories
+  def self.scan_changesets_for_issue_ids
+    all.each(&:scan_changesets_for_issue_ids)
+  end
+
+  def self.scm_name
+    'Abstract'
+  end
+
+  def self.available_scm
+    subclasses.collect {|klass| [klass.scm_name, klass.name]}
+  end
+
+  def self.factory(klass_name, *args)
+    klass = "Repository::#{klass_name}".constantize
+    klass.new(*args)
+  rescue
+    nil
+  end
+
+  def self.scm_adapter_class
+    nil
+  end
+
+  def self.scm_command
+    ret = ""
+    begin
+      ret = self.scm_adapter_class.client_command if self.scm_adapter_class
+    rescue Exception => e
+      logger.error "scm: error during get command: #{e.message}"
+    end
+    ret
+  end
+
+  def self.scm_version_string
+    ret = ""
+    begin
+      ret = self.scm_adapter_class.client_version_string if self.scm_adapter_class
+    rescue Exception => e
+      logger.error "scm: error during get version string: #{e.message}"
+    end
+    ret
+  end
+
+  def self.scm_available
+    ret = false
+    begin
+      ret = self.scm_adapter_class.client_available if self.scm_adapter_class
+    rescue Exception => e
+      logger.error "scm: error during get scm available: #{e.message}"
+    end
+    ret
+  end
+
+  def set_as_default?
+    new_record? && project && !Repository.first(:conditions => {:project_id => project.id})
+  end
+
+  protected
+
+  def check_default
+    if !is_default? && set_as_default?
+      self.is_default = true
+    end
+    if is_default? && is_default_changed?
+      Repository.update_all(["is_default = ?", false], ["project_id = ?", project_id])
+    end
+  end
+
+  def load_entries_changesets(entries)
+    if entries
+      entries.each do |entry|
+        if entry.lastrev && entry.lastrev.identifier
+          entry.changeset = find_changeset_by_name(entry.lastrev.identifier)
+        end
+      end
+    end
+  end
+
+  private
+
+  # Deletes repository data
+  def clear_changesets
+    cs = Changeset.table_name
+    ch = Change.table_name
+    ci = "#{table_name_prefix}changesets_issues#{table_name_suffix}"
+    cp = "#{table_name_prefix}changeset_parents#{table_name_suffix}"
+
+    connection.delete("DELETE FROM #{ch} WHERE #{ch}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
+    connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
+    connection.delete("DELETE FROM #{cp} WHERE #{cp}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
+    connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}")
+    clear_extra_info_of_changesets
+  end
+
+  def clear_extra_info_of_changesets
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c3/c3ef157204ed32856d2cce37cd8fd93fa5678cb4.svn-base
--- /dev/null
+++ b/.svn/pristine/c3/c3ef157204ed32856d2cce37cd8fd93fa5678cb4.svn-base
@@ -0,0 +1,933 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class WikiControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :enabled_modules, :wikis, :wiki_pages, :wiki_contents,
+           :wiki_content_versions, :attachments
+
+  def setup
+    User.current = nil
+  end
+
+  def test_show_start_page
+    get :show, :project_id => 'ecookbook'
+    assert_response :success
+    assert_template 'show'
+    assert_tag :tag => 'h1', :content => /CookBook documentation/
+
+    # child_pages macro
+    assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
+               :child => { :tag => 'li',
+                           :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
+                                                    :content => 'Page with an inline image' } }
+  end
+  
+  def test_export_link
+    Role.anonymous.add_permission! :export_wiki_pages
+    get :show, :project_id => 'ecookbook'
+    assert_response :success
+    assert_tag 'a', :attributes => {:href => '/projects/ecookbook/wiki/CookBook_documentation.txt'}
+  end
+
+  def test_show_page_with_name
+    get :show, :project_id => 1, :id => 'Another_page'
+    assert_response :success
+    assert_template 'show'
+    assert_tag :tag => 'h1', :content => /Another page/
+    # Included page with an inline image
+    assert_tag :tag => 'p', :content => /This is an inline image/
+    assert_tag :tag => 'img', :attributes => { :src => '/attachments/download/3/logo.gif',
+                                               :alt => 'This is a logo' }
+  end
+
+  def test_show_old_version
+    get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
+    assert_response :success
+    assert_template 'show'
+
+    assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/1', :text => /Previous/
+    assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/diff', :text => /diff/
+    assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/3', :text => /Next/
+    assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
+  end
+
+  def test_show_old_version_with_attachments
+    page = WikiPage.find(4)
+    assert page.attachments.any?
+    content = page.content
+    content.text = "update"
+    content.save!
+
+    get :show, :project_id => 'ecookbook', :id => page.title, :version => '1'
+    assert_kind_of WikiContent::Version, assigns(:content)
+    assert_response :success
+    assert_template 'show'
+  end
+
+  def test_show_old_version_without_permission_should_be_denied
+    Role.anonymous.remove_permission! :view_wiki_edits
+
+    get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
+    assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fprojects%2Fecookbook%2Fwiki%2FCookBook_documentation%2F2'
+  end
+
+  def test_show_first_version
+    get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '1'
+    assert_response :success
+    assert_template 'show'
+
+    assert_select 'a', :text => /Previous/, :count => 0
+    assert_select 'a', :text => /diff/, :count => 0
+    assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => /Next/
+    assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
+  end
+
+  def test_show_redirected_page
+    WikiRedirect.create!(:wiki_id => 1, :title => 'Old_title', :redirects_to => 'Another_page')
+
+    get :show, :project_id => 'ecookbook', :id => 'Old_title'
+    assert_redirected_to '/projects/ecookbook/wiki/Another_page'
+  end
+
+  def test_show_with_sidebar
+    page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
+    page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
+    page.save!
+
+    get :show, :project_id => 1, :id => 'Another_page'
+    assert_response :success
+    assert_tag :tag => 'div', :attributes => {:id => 'sidebar'},
+                              :content => /Side bar content for test_show_with_sidebar/
+  end
+  
+  def test_show_should_display_section_edit_links
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :id => 'Page with sections'
+    assert_no_tag 'a', :attributes => {
+      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=1'
+    }
+    assert_tag 'a', :attributes => {
+      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
+    }
+    assert_tag 'a', :attributes => {
+      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=3'
+    }
+  end
+
+  def test_show_current_version_should_display_section_edit_links
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :id => 'Page with sections', :version => 3
+
+    assert_tag 'a', :attributes => {
+      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
+    }
+  end
+
+  def test_show_old_version_should_not_display_section_edit_links
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :id => 'Page with sections', :version => 2
+
+    assert_no_tag 'a', :attributes => {
+      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
+    }
+  end
+
+  def test_show_unexistent_page_without_edit_right
+    get :show, :project_id => 1, :id => 'Unexistent page'
+    assert_response 404
+  end
+
+  def test_show_unexistent_page_with_edit_right
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :id => 'Unexistent page'
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_show_unexistent_page_with_parent_should_preselect_parent
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :id => 'Unexistent page', :parent => 'Another_page'
+    assert_response :success
+    assert_template 'edit'
+    assert_tag 'select', :attributes => {:name => 'wiki_page[parent_id]'},
+      :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}}
+  end
+
+  def test_show_should_not_show_history_without_permission
+    Role.anonymous.remove_permission! :view_wiki_edits
+    get :show, :project_id => 1, :id => 'Page with sections', :version => 2
+
+    assert_response 302
+  end
+
+  def test_create_page
+    @request.session[:user_id] = 2
+    assert_difference 'WikiPage.count' do
+      assert_difference 'WikiContent.count' do
+        put :update, :project_id => 1,
+                    :id => 'New page',
+                    :content => {:comments => 'Created the page',
+                                 :text => "h1. New page\n\nThis is a new page",
+                                 :version => 0}
+      end
+    end
+    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
+    page = Project.find(1).wiki.find_page('New page')
+    assert !page.new_record?
+    assert_not_nil page.content
+    assert_nil page.parent
+    assert_equal 'Created the page', page.content.comments
+  end
+
+  def test_create_page_with_attachments
+    @request.session[:user_id] = 2
+    assert_difference 'WikiPage.count' do
+      assert_difference 'Attachment.count' do
+        put :update, :project_id => 1,
+                    :id => 'New page',
+                    :content => {:comments => 'Created the page',
+                                 :text => "h1. New page\n\nThis is a new page",
+                                 :version => 0},
+                    :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
+      end
+    end
+    page = Project.find(1).wiki.find_page('New page')
+    assert_equal 1, page.attachments.count
+    assert_equal 'testfile.txt', page.attachments.first.filename
+  end
+
+  def test_create_page_with_parent
+    @request.session[:user_id] = 2
+    assert_difference 'WikiPage.count' do
+      put :update, :project_id => 1, :id => 'New page',
+        :content => {:text => "h1. New page\n\nThis is a new page", :version => 0},
+        :wiki_page => {:parent_id => 2}
+    end
+    page = Project.find(1).wiki.find_page('New page')
+    assert_equal WikiPage.find(2), page.parent
+  end
+
+  def test_edit_page
+    @request.session[:user_id] = 2
+    get :edit, :project_id => 'ecookbook', :id => 'Another_page'
+
+    assert_response :success
+    assert_template 'edit'
+
+    assert_tag 'textarea',
+      :attributes => { :name => 'content[text]' },
+      :content => "\n"+WikiPage.find_by_title('Another_page').content.text
+  end
+
+  def test_edit_section
+    @request.session[:user_id] = 2
+    get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 2
+
+    assert_response :success
+    assert_template 'edit'
+    
+    page = WikiPage.find_by_title('Page_with_sections')
+    section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
+
+    assert_tag 'textarea',
+      :attributes => { :name => 'content[text]' },
+      :content => "\n"+section
+    assert_tag 'input',
+      :attributes => { :name => 'section', :type => 'hidden', :value => '2' }
+    assert_tag 'input',
+      :attributes => { :name => 'section_hash', :type => 'hidden', :value => hash }
+  end
+
+  def test_edit_invalid_section_should_respond_with_404
+    @request.session[:user_id] = 2
+    get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 10
+
+    assert_response 404
+  end
+
+  def test_update_page
+    @request.session[:user_id] = 2
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_difference 'WikiContent::Version.count' do
+          put :update, :project_id => 1,
+            :id => 'Another_page',
+            :content => {
+              :comments => "my comments",
+              :text => "edited",
+              :version => 1
+            }
+        end
+      end
+    end
+    assert_redirected_to '/projects/ecookbook/wiki/Another_page'
+
+    page = Wiki.find(1).pages.find_by_title('Another_page')
+    assert_equal "edited", page.content.text
+    assert_equal 2, page.content.version
+    assert_equal "my comments", page.content.comments
+  end
+
+  def test_update_page_with_parent
+    @request.session[:user_id] = 2
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_difference 'WikiContent::Version.count' do
+          put :update, :project_id => 1,
+            :id => 'Another_page',
+            :content => {
+              :comments => "my comments",
+              :text => "edited",
+              :version => 1
+            },
+            :wiki_page => {:parent_id => '1'}
+        end
+      end
+    end
+    assert_redirected_to '/projects/ecookbook/wiki/Another_page'
+
+    page = Wiki.find(1).pages.find_by_title('Another_page')
+    assert_equal "edited", page.content.text
+    assert_equal 2, page.content.version
+    assert_equal "my comments", page.content.comments
+    assert_equal WikiPage.find(1), page.parent
+  end
+
+  def test_update_page_with_failure
+    @request.session[:user_id] = 2
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_no_difference 'WikiContent::Version.count' do
+          put :update, :project_id => 1,
+            :id => 'Another_page',
+            :content => {
+              :comments => 'a' * 300,  # failure here, comment is too long
+              :text => 'edited',
+              :version => 1
+            }
+          end
+        end
+      end
+    assert_response :success
+    assert_template 'edit'
+
+    assert_error_tag :descendant => {:content => /Comment is too long/}
+    assert_tag :tag => 'textarea', :attributes => {:id => 'content_text'}, :content => "\nedited"
+    assert_tag :tag => 'input', :attributes => {:id => 'content_version', :value => '1'}
+  end
+
+  def test_update_page_with_parent_change_only_should_not_create_content_version
+    @request.session[:user_id] = 2
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_no_difference 'WikiContent::Version.count' do
+          put :update, :project_id => 1,
+            :id => 'Another_page',
+            :content => {
+              :comments => '',
+              :text => Wiki.find(1).find_page('Another_page').content.text,
+              :version => 1
+            },
+            :wiki_page => {:parent_id => '1'}
+        end
+      end
+    end
+    page = Wiki.find(1).pages.find_by_title('Another_page')
+    assert_equal 1, page.content.version
+    assert_equal WikiPage.find(1), page.parent
+  end
+
+  def test_update_page_with_attachments_only_should_not_create_content_version
+    @request.session[:user_id] = 2
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_no_difference 'WikiContent::Version.count' do
+          assert_difference 'Attachment.count' do
+            put :update, :project_id => 1,
+              :id => 'Another_page',
+              :content => {
+                :comments => '',
+                :text => Wiki.find(1).find_page('Another_page').content.text,
+                :version => 1
+              },
+              :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
+          end
+        end
+      end
+    end
+    page = Wiki.find(1).pages.find_by_title('Another_page')
+    assert_equal 1, page.content.version
+  end
+
+  def test_update_stale_page_should_not_raise_an_error
+    @request.session[:user_id] = 2
+    c = Wiki.find(1).find_page('Another_page').content
+    c.text = 'Previous text'
+    c.save!
+    assert_equal 2, c.version
+
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_no_difference 'WikiContent::Version.count' do
+          put :update, :project_id => 1,
+            :id => 'Another_page',
+            :content => {
+              :comments => 'My comments',
+              :text => 'Text should not be lost',
+              :version => 1
+            }
+        end
+      end
+    end
+    assert_response :success
+    assert_template 'edit'
+    assert_tag :div,
+      :attributes => { :class => /error/ },
+      :content => /Data has been updated by another user/
+    assert_tag 'textarea',
+      :attributes => { :name => 'content[text]' },
+      :content => /Text should not be lost/
+    assert_tag 'input',
+      :attributes => { :name => 'content[comments]', :value => 'My comments' }
+
+    c.reload
+    assert_equal 'Previous text', c.text
+    assert_equal 2, c.version
+  end
+
+  def test_update_section
+    @request.session[:user_id] = 2
+    page = WikiPage.find_by_title('Page_with_sections')
+    section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
+    text = page.content.text
+
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_difference 'WikiContent::Version.count' do
+          put :update, :project_id => 1, :id => 'Page_with_sections',
+            :content => {
+              :text => "New section content",
+              :version => 3
+            },
+            :section => 2,
+            :section_hash => hash
+        end
+      end
+    end
+    assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections'
+    assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.reload.content.text
+  end
+
+  def test_update_section_should_allow_stale_page_update
+    @request.session[:user_id] = 2
+    page = WikiPage.find_by_title('Page_with_sections')
+    section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
+    text = page.content.text
+
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_difference 'WikiContent::Version.count' do
+          put :update, :project_id => 1, :id => 'Page_with_sections',
+            :content => {
+              :text => "New section content",
+              :version => 2 # Current version is 3
+            },
+            :section => 2,
+            :section_hash => hash
+        end
+      end
+    end
+    assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections'
+    page.reload
+    assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.content.text
+    assert_equal 4, page.content.version
+  end
+
+  def test_update_section_should_not_allow_stale_section_update
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent.count' do
+        assert_no_difference 'WikiContent::Version.count' do
+          put :update, :project_id => 1, :id => 'Page_with_sections',
+            :content => {
+              :comments => 'My comments',
+              :text => "Text should not be lost",
+              :version => 3
+            },
+            :section => 2,
+            :section_hash => Digest::MD5.hexdigest("wrong hash")
+        end
+      end
+    end
+    assert_response :success
+    assert_template 'edit'
+    assert_tag :div,
+      :attributes => { :class => /error/ },
+      :content => /Data has been updated by another user/
+    assert_tag 'textarea',
+      :attributes => { :name => 'content[text]' },
+      :content => /Text should not be lost/
+    assert_tag 'input',
+      :attributes => { :name => 'content[comments]', :value => 'My comments' }
+  end
+
+  def test_preview
+    @request.session[:user_id] = 2
+    xhr :post, :preview, :project_id => 1, :id => 'CookBook_documentation',
+                                   :content => { :comments => '',
+                                                 :text => 'this is a *previewed text*',
+                                                 :version => 3 }
+    assert_response :success
+    assert_template 'common/_preview'
+    assert_tag :tag => 'strong', :content => /previewed text/
+  end
+
+  def test_preview_new_page
+    @request.session[:user_id] = 2
+    xhr :post, :preview, :project_id => 1, :id => 'New page',
+                                   :content => { :text => 'h1. New page',
+                                                 :comments => '',
+                                                 :version => 0 }
+    assert_response :success
+    assert_template 'common/_preview'
+    assert_tag :tag => 'h1', :content => /New page/
+  end
+
+  def test_history
+    @request.session[:user_id] = 2
+    get :history, :project_id => 'ecookbook', :id => 'CookBook_documentation'
+    assert_response :success
+    assert_template 'history'
+    assert_not_nil assigns(:versions)
+    assert_equal 3, assigns(:versions).size
+
+    assert_select "input[type=submit][name=commit]"
+    assert_select 'td' do
+      assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => '2'
+      assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/annotate', :text => 'Annotate'
+      assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => 'Delete'
+    end
+  end
+
+  def test_history_with_one_version
+    @request.session[:user_id] = 2
+    get :history, :project_id => 'ecookbook', :id => 'Another_page'
+    assert_response :success
+    assert_template 'history'
+    assert_not_nil assigns(:versions)
+    assert_equal 1, assigns(:versions).size
+    assert_select "input[type=submit][name=commit]", false
+    assert_select 'td' do
+      assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => '1'
+      assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1/annotate', :text => 'Annotate'
+      assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => 'Delete', :count => 0
+    end
+  end
+
+  def test_diff
+    content = WikiPage.find(1).content
+    assert_difference 'WikiContent::Version.count', 2 do
+      content.text = "Line removed\nThis is a sample text for testing diffs"
+      content.save!
+      content.text = "This is a sample text for testing diffs\nLine added"
+      content.save!
+    end
+
+    get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => content.version, :version_from => (content.version - 1)
+    assert_response :success
+    assert_template 'diff'
+    assert_select 'span.diff_out', :text => 'Line removed'
+    assert_select 'span.diff_in', :text => 'Line added'
+  end
+
+  def test_diff_with_invalid_version_should_respond_with_404
+    get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
+    assert_response 404
+  end
+
+  def test_diff_with_invalid_version_from_should_respond_with_404
+    get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99', :version_from => '98'
+    assert_response 404
+  end
+
+  def test_annotate
+    get :annotate, :project_id => 1, :id =>  'CookBook_documentation', :version => 2
+    assert_response :success
+    assert_template 'annotate'
+
+    # Line 1
+    assert_tag :tag => 'tr', :child => {
+      :tag => 'th', :attributes => {:class => 'line-num'}, :content => '1', :sibling => {
+        :tag => 'td', :attributes => {:class => 'author'}, :content => /John Smith/, :sibling => {
+          :tag => 'td', :content => /h1\. CookBook documentation/
+        }
+      }
+    }
+
+    # Line 5
+    assert_tag :tag => 'tr', :child => {
+      :tag => 'th', :attributes => {:class => 'line-num'}, :content => '5', :sibling => {
+        :tag => 'td', :attributes => {:class => 'author'}, :content => /Redmine Admin/, :sibling => {
+          :tag => 'td', :content => /Some updated \[\[documentation\]\] here/
+        }
+      }
+    }
+  end
+
+  def test_annotate_with_invalid_version_should_respond_with_404
+    get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
+    assert_response 404
+  end
+
+  def test_get_rename
+    @request.session[:user_id] = 2
+    get :rename, :project_id => 1, :id => 'Another_page'
+    assert_response :success
+    assert_template 'rename'
+    assert_tag 'option',
+      :attributes => {:value => ''},
+      :content => '',
+      :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
+    assert_no_tag 'option',
+      :attributes => {:selected => 'selected'},
+      :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
+  end
+
+  def test_get_rename_child_page
+    @request.session[:user_id] = 2
+    get :rename, :project_id => 1, :id => 'Child_1'
+    assert_response :success
+    assert_template 'rename'
+    assert_tag 'option',
+      :attributes => {:value => ''},
+      :content => '',
+      :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
+    assert_tag 'option',
+      :attributes => {:value => '2', :selected => 'selected'},
+      :content => /Another page/,
+      :parent => {
+        :tag => 'select',
+        :attributes => {:name => 'wiki_page[parent_id]'}
+      }
+  end
+
+  def test_rename_with_redirect
+    @request.session[:user_id] = 2
+    post :rename, :project_id => 1, :id => 'Another_page',
+                            :wiki_page => { :title => 'Another renamed page',
+                                            :redirect_existing_links => 1 }
+    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
+    wiki = Project.find(1).wiki
+    # Check redirects
+    assert_not_nil wiki.find_page('Another page')
+    assert_nil wiki.find_page('Another page', :with_redirect => false)
+  end
+
+  def test_rename_without_redirect
+    @request.session[:user_id] = 2
+    post :rename, :project_id => 1, :id => 'Another_page',
+                            :wiki_page => { :title => 'Another renamed page',
+                                            :redirect_existing_links => "0" }
+    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
+    wiki = Project.find(1).wiki
+    # Check that there's no redirects
+    assert_nil wiki.find_page('Another page')
+  end
+
+  def test_rename_with_parent_assignment
+    @request.session[:user_id] = 2
+    post :rename, :project_id => 1, :id => 'Another_page',
+      :wiki_page => { :title => 'Another page', :redirect_existing_links => "0", :parent_id => '4' }
+    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
+    assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
+  end
+
+  def test_rename_with_parent_unassignment
+    @request.session[:user_id] = 2
+    post :rename, :project_id => 1, :id => 'Child_1',
+      :wiki_page => { :title => 'Child 1', :redirect_existing_links => "0", :parent_id => '' }
+    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
+    assert_nil WikiPage.find_by_title('Child_1').parent
+  end
+
+  def test_destroy_a_page_without_children_should_not_ask_confirmation
+    @request.session[:user_id] = 2
+    delete :destroy, :project_id => 1, :id => 'Child_2'
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+  end
+
+  def test_destroy_parent_should_ask_confirmation
+    @request.session[:user_id] = 2
+    assert_no_difference('WikiPage.count') do
+      delete :destroy, :project_id => 1, :id => 'Another_page'
+    end
+    assert_response :success
+    assert_template 'destroy'
+    assert_select 'form' do
+      assert_select 'input[name=todo][value=nullify]'
+      assert_select 'input[name=todo][value=destroy]'
+      assert_select 'input[name=todo][value=reassign]'
+    end
+  end
+
+  def test_destroy_parent_with_nullify_should_delete_parent_only
+    @request.session[:user_id] = 2
+    assert_difference('WikiPage.count', -1) do
+      delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'nullify'
+    end
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    assert_nil WikiPage.find_by_id(2)
+  end
+
+  def test_destroy_parent_with_cascade_should_delete_descendants
+    @request.session[:user_id] = 2
+    assert_difference('WikiPage.count', -4) do
+      delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'destroy'
+    end
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    assert_nil WikiPage.find_by_id(2)
+    assert_nil WikiPage.find_by_id(5)
+  end
+
+  def test_destroy_parent_with_reassign
+    @request.session[:user_id] = 2
+    assert_difference('WikiPage.count', -1) do
+      delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1
+    end
+    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
+    assert_nil WikiPage.find_by_id(2)
+    assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
+  end
+
+  def test_destroy_version
+    @request.session[:user_id] = 2
+    assert_difference 'WikiContent::Version.count', -1 do
+      assert_no_difference 'WikiContent.count' do
+        assert_no_difference 'WikiPage.count' do
+          delete :destroy_version, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => 2
+          assert_redirected_to '/projects/ecookbook/wiki/CookBook_documentation/history'
+        end
+      end
+    end
+  end
+
+  def test_index
+    get :index, :project_id => 'ecookbook'
+    assert_response :success
+    assert_template 'index'
+    pages = assigns(:pages)
+    assert_not_nil pages
+    assert_equal Project.find(1).wiki.pages.size, pages.size
+    assert_equal pages.first.content.updated_on, pages.first.updated_on
+
+    assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
+                    :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/CookBook_documentation' },
+                                              :content => 'CookBook documentation' },
+                                :child => { :tag => 'ul',
+                                            :child => { :tag => 'li',
+                                                        :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
+                                                                                 :content => 'Page with an inline image' } } } },
+                    :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Another_page' },
+                                                                       :content => 'Another page' } }
+  end
+
+  def test_index_should_include_atom_link
+    get :index, :project_id => 'ecookbook'
+    assert_tag 'a', :attributes => { :href => '/projects/ecookbook/activity.atom?show_wiki_edits=1'}
+  end
+
+  def test_export_to_html
+    @request.session[:user_id] = 2
+    get :export, :project_id => 'ecookbook'
+
+    assert_response :success
+    assert_not_nil assigns(:pages)
+    assert assigns(:pages).any?
+    assert_equal "text/html", @response.content_type
+
+    assert_select "a[name=?]", "CookBook_documentation"
+    assert_select "a[name=?]", "Another_page"
+    assert_select "a[name=?]", "Page_with_an_inline_image"
+  end
+
+  def test_export_to_pdf
+    @request.session[:user_id] = 2
+    get :export, :project_id => 'ecookbook', :format => 'pdf'
+
+    assert_response :success
+    assert_not_nil assigns(:pages)
+    assert assigns(:pages).any?
+    assert_equal 'application/pdf', @response.content_type
+    assert_equal 'attachment; filename="ecookbook.pdf"', @response.headers['Content-Disposition']
+    assert @response.body.starts_with?('%PDF')
+  end
+
+  def test_export_without_permission_should_be_denied
+    @request.session[:user_id] = 2
+    Role.find_by_name('Manager').remove_permission! :export_wiki_pages
+    get :export, :project_id => 'ecookbook'
+
+    assert_response 403
+  end
+
+  def test_date_index
+    get :date_index, :project_id => 'ecookbook'
+
+    assert_response :success
+    assert_template 'date_index'
+    assert_not_nil assigns(:pages)
+    assert_not_nil assigns(:pages_by_date)
+
+    assert_tag 'a', :attributes => { :href => '/projects/ecookbook/activity.atom?show_wiki_edits=1'}
+  end
+
+  def test_not_found
+    get :show, :project_id => 999
+    assert_response 404
+  end
+
+  def test_protect_page
+    page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
+    assert !page.protected?
+    @request.session[:user_id] = 2
+    post :protect, :project_id => 1, :id => page.title, :protected => '1'
+    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
+    assert page.reload.protected?
+  end
+
+  def test_unprotect_page
+    page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
+    assert page.protected?
+    @request.session[:user_id] = 2
+    post :protect, :project_id => 1, :id => page.title, :protected => '0'
+    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
+    assert !page.reload.protected?
+  end
+
+  def test_show_page_with_edit_link
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1
+    assert_response :success
+    assert_template 'show'
+    assert_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
+  end
+
+  def test_show_page_without_edit_link
+    @request.session[:user_id] = 4
+    get :show, :project_id => 1
+    assert_response :success
+    assert_template 'show'
+    assert_no_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
+  end
+
+  def test_show_pdf
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :format => 'pdf'
+    assert_response :success
+    assert_not_nil assigns(:page)
+    assert_equal 'application/pdf', @response.content_type
+    assert_equal 'attachment; filename="CookBook_documentation.pdf"',
+                  @response.headers['Content-Disposition']
+  end
+
+  def test_show_html
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :format => 'html'
+    assert_response :success
+    assert_not_nil assigns(:page)
+    assert_equal 'text/html', @response.content_type
+    assert_equal 'attachment; filename="CookBook_documentation.html"',
+                  @response.headers['Content-Disposition']
+    assert_tag 'h1', :content => 'CookBook documentation'
+  end
+
+  def test_show_versioned_html
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :format => 'html', :version => 2
+    assert_response :success
+    assert_not_nil assigns(:content)
+    assert_equal 2, assigns(:content).version
+    assert_equal 'text/html', @response.content_type
+    assert_equal 'attachment; filename="CookBook_documentation.html"',
+                  @response.headers['Content-Disposition']
+    assert_tag 'h1', :content => 'CookBook documentation'
+  end
+
+  def test_show_txt
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :format => 'txt'
+    assert_response :success
+    assert_not_nil assigns(:page)
+    assert_equal 'text/plain', @response.content_type
+    assert_equal 'attachment; filename="CookBook_documentation.txt"',
+                  @response.headers['Content-Disposition']
+    assert_include 'h1. CookBook documentation', @response.body
+  end
+
+  def test_show_versioned_txt
+    @request.session[:user_id] = 2
+    get :show, :project_id => 1, :format => 'txt', :version => 2
+    assert_response :success
+    assert_not_nil assigns(:content)
+    assert_equal 2, assigns(:content).version
+    assert_equal 'text/plain', @response.content_type
+    assert_equal 'attachment; filename="CookBook_documentation.txt"',
+                  @response.headers['Content-Disposition']
+    assert_include 'h1. CookBook documentation', @response.body
+  end
+
+  def test_edit_unprotected_page
+    # Non members can edit unprotected wiki pages
+    @request.session[:user_id] = 4
+    get :edit, :project_id => 1, :id => 'Another_page'
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_edit_protected_page_by_nonmember
+    # Non members can't edit protected wiki pages
+    @request.session[:user_id] = 4
+    get :edit, :project_id => 1, :id => 'CookBook_documentation'
+    assert_response 403
+  end
+
+  def test_edit_protected_page_by_member
+    @request.session[:user_id] = 2
+    get :edit, :project_id => 1, :id => 'CookBook_documentation'
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_history_of_non_existing_page_should_return_404
+    get :history, :project_id => 1, :id => 'Unknown_page'
+    assert_response 404
+  end
+
+  def test_add_attachment
+    @request.session[:user_id] = 2
+    assert_difference 'Attachment.count' do
+      post :add_attachment, :project_id => 1, :id => 'CookBook_documentation',
+        :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
+    end
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal Wiki.find(1).find_page('CookBook_documentation'), attachment.container
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c4/c434d791a7d10db078bf19f213b250982f17b1e9.svn-base
--- a/.svn/pristine/c4/c434d791a7d10db078bf19f213b250982f17b1e9.svn-base
+++ /dev/null
@@ -1,253 +0,0 @@
-module CodeRay
-module Scanners
-
-  # HTML Scanner
-  # 
-  # Alias: +xhtml+
-  # 
-  # See also: Scanners::XML
-  class HTML < Scanner
-
-    register_for :html
-    
-    KINDS_NOT_LOC = [
-      :comment, :doctype, :preprocessor,
-      :tag, :attribute_name, :operator,
-      :attribute_value, :string,
-      :plain, :entity, :error,
-    ]  # :nodoc:
-    
-    EVENT_ATTRIBUTES = %w(
-      onabort onafterprint onbeforeprint onbeforeunload onblur oncanplay
-      oncanplaythrough onchange onclick oncontextmenu oncuechange ondblclick
-      ondrag ondragdrop ondragend ondragenter ondragleave ondragover
-      ondragstart ondrop ondurationchange onemptied onended onerror onfocus
-      onformchange onforminput onhashchange oninput oninvalid onkeydown
-      onkeypress onkeyup onload onloadeddata onloadedmetadata onloadstart
-      onmessage onmousedown onmousemove onmouseout onmouseover onmouseup
-      onmousewheel onmove onoffline ononline onpagehide onpageshow onpause
-      onplay onplaying onpopstate onprogress onratechange onreadystatechange
-      onredo onreset onresize onscroll onseeked onseeking onselect onshow
-      onstalled onstorage onsubmit onsuspend ontimeupdate onundo onunload
-      onvolumechange onwaiting
-    )
-    
-    IN_ATTRIBUTE = WordList::CaseIgnoring.new(nil).
-      add(EVENT_ATTRIBUTES, :script)
-    
-    ATTR_NAME = /[\w.:-]+/  # :nodoc:
-    TAG_END = /\/?>/  # :nodoc:
-    HEX = /[0-9a-fA-F]/  # :nodoc:
-    ENTITY = /
-      &
-      (?:
-        \w+
-      |
-        \#
-        (?:
-          \d+
-        |
-          x#{HEX}+
-        )
-      )
-      ;
-    /ox  # :nodoc:
-    
-    PLAIN_STRING_CONTENT = {
-      "'" => /[^&'>\n]+/,
-      '"' => /[^&">\n]+/,
-    }  # :nodoc:
-    
-    def reset
-      super
-      @state = :initial
-      @plain_string_content = nil
-    end
-    
-  protected
-    
-    def setup
-      @state = :initial
-      @plain_string_content = nil
-    end
-    
-    def scan_java_script encoder, code
-      if code && !code.empty?
-        @java_script_scanner ||= Scanners::JavaScript.new '', :keep_tokens => true
-        # encoder.begin_group :inline
-        @java_script_scanner.tokenize code, :tokens => encoder
-        # encoder.end_group :inline
-      end
-    end
-    
-    def scan_tokens encoder, options
-      state = options[:state] || @state
-      plain_string_content = @plain_string_content
-      in_tag = in_attribute = nil
-      
-      encoder.begin_group :string if state == :attribute_value_string
-      
-      until eos?
-        
-        if state != :in_special_tag && match = scan(/\s+/m)
-          encoder.text_token match, :space
-          
-        else
-          
-          case state
-          
-          when :initial
-            if match = scan(/<!--(?:.*?-->|.*)/m)
-              encoder.text_token match, :comment
-            elsif match = scan(/<!DOCTYPE(?:.*?>|.*)/m)
-              encoder.text_token match, :doctype
-            elsif match = scan(/<\?xml(?:.*?\?>|.*)/m)
-              encoder.text_token match, :preprocessor
-            elsif match = scan(/<\?(?:.*?\?>|.*)/m)
-              encoder.text_token match, :comment
-            elsif match = scan(/<\/[-\w.:]*>?/m)
-              in_tag = nil
-              encoder.text_token match, :tag
-            elsif match = scan(/<(?:(script)|[-\w.:]+)(>)?/m)
-              encoder.text_token match, :tag
-              in_tag = self[1]
-              if self[2]
-                state = :in_special_tag if in_tag
-              else
-                state = :attribute
-              end
-            elsif match = scan(/[^<>&]+/)
-              encoder.text_token match, :plain
-            elsif match = scan(/#{ENTITY}/ox)
-              encoder.text_token match, :entity
-            elsif match = scan(/[<>&]/)
-              in_tag = nil
-              encoder.text_token match, :error
-            else
-              raise_inspect '[BUG] else-case reached with state %p' % [state], encoder
-            end
-            
-          when :attribute
-            if match = scan(/#{TAG_END}/o)
-              encoder.text_token match, :tag
-              in_attribute = nil
-              if in_tag
-                state = :in_special_tag
-              else
-                state = :initial
-              end
-            elsif match = scan(/#{ATTR_NAME}/o)
-              in_attribute = IN_ATTRIBUTE[match]
-              encoder.text_token match, :attribute_name
-              state = :attribute_equal
-            else
-              in_tag = nil
-              encoder.text_token getch, :error
-            end
-            
-          when :attribute_equal
-            if match = scan(/=/)  #/
-              encoder.text_token match, :operator
-              state = :attribute_value
-            elsif scan(/#{ATTR_NAME}/o) || scan(/#{TAG_END}/o)
-              state = :attribute
-              next
-            else
-              encoder.text_token getch, :error
-              state = :attribute
-            end
-            
-          when :attribute_value
-            if match = scan(/#{ATTR_NAME}/o)
-              encoder.text_token match, :attribute_value
-              state = :attribute
-            elsif match = scan(/["']/)
-              if in_attribute == :script
-                encoder.begin_group :inline
-                encoder.text_token match, :inline_delimiter
-                if scan(/javascript:[ \t]*/)
-                  encoder.text_token matched, :comment
-                end
-                code = scan_until(match == '"' ? /(?="|\z)/ : /(?='|\z)/)
-                scan_java_script encoder, code
-                match = scan(/["']/)
-                encoder.text_token match, :inline_delimiter if match
-                encoder.end_group :inline
-                state = :attribute
-                in_attribute = nil
-              else
-                encoder.begin_group :string
-                state = :attribute_value_string
-                plain_string_content = PLAIN_STRING_CONTENT[match]
-                encoder.text_token match, :delimiter
-              end
-            elsif match = scan(/#{TAG_END}/o)
-              encoder.text_token match, :tag
-              state = :initial
-            else
-              encoder.text_token getch, :error
-            end
-            
-          when :attribute_value_string
-            if match = scan(plain_string_content)
-              encoder.text_token match, :content
-            elsif match = scan(/['"]/)
-              encoder.text_token match, :delimiter
-              encoder.end_group :string
-              state = :attribute
-            elsif match = scan(/#{ENTITY}/ox)
-              encoder.text_token match, :entity
-            elsif match = scan(/&/)
-              encoder.text_token match, :content
-            elsif match = scan(/[\n>]/)
-              encoder.end_group :string
-              state = :initial
-              encoder.text_token match, :error
-            end
-            
-          when :in_special_tag
-            case in_tag
-            when 'script'
-              encoder.text_token match, :space if match = scan(/[ \t]*\n/)
-              if scan(/(\s*<!--)(?:(.*?)(-->)|(.*))/m)
-                code = self[2] || self[4]
-                closing = self[3]
-                encoder.text_token self[1], :comment
-              else
-                code = scan_until(/(?=(?:\n\s*)?<\/script>)|\z/)
-                closing = false
-              end
-              unless code.empty?
-                encoder.begin_group :inline
-                scan_java_script encoder, code
-                encoder.end_group :inline
-              end
-              encoder.text_token closing, :comment if closing
-              state = :initial
-            else
-              raise 'unknown special tag: %p' % [in_tag]
-            end
-            
-          else
-            raise_inspect 'Unknown state: %p' % [state], encoder
-            
-          end
-          
-        end
-        
-      end
-      
-      if options[:keep_state]
-        @state = state
-        @plain_string_content = plain_string_content
-      end
-      
-      encoder.end_group :string if state == :attribute_value_string
-      
-      encoder
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c4/c44c388b41c813b95c15c47903c713fd3c24bb0e.svn-base
--- a/.svn/pristine/c4/c44c388b41c813b95c15c47903c713fd3c24bb0e.svn-base
+++ /dev/null
@@ -1,102 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-require 'pp'
-class ApiTest::NewsTest < ActionController::IntegrationTest
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :news
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "GET /news" do
-    context ".xml" do
-      should "return news" do
-        get '/news.xml'
-
-        assert_tag :tag => 'news',
-          :attributes => {:type => 'array'},
-          :child => {
-            :tag => 'news',
-            :child => {
-              :tag => 'id',
-              :content => '2'
-            }
-          }
-      end
-    end
-
-    context ".json" do
-      should "return news" do
-        get '/news.json'
-
-        json = ActiveSupport::JSON.decode(response.body)
-        assert_kind_of Hash, json
-        assert_kind_of Array, json['news']
-        assert_kind_of Hash, json['news'].first
-        assert_equal 2, json['news'].first['id']
-      end
-    end
-  end
-
-  context "GET /projects/:project_id/news" do
-    context ".xml" do
-      should_allow_api_authentication(:get, "/projects/onlinestore/news.xml")
-
-      should "return news" do
-        get '/projects/ecookbook/news.xml'
-
-        assert_tag :tag => 'news',
-          :attributes => {:type => 'array'},
-          :child => {
-            :tag => 'news',
-            :child => {
-              :tag => 'id',
-              :content => '2'
-            }
-          }
-      end
-    end
-
-    context ".json" do
-      should_allow_api_authentication(:get, "/projects/onlinestore/news.json")
-
-      should "return news" do
-        get '/projects/ecookbook/news.json'
-
-        json = ActiveSupport::JSON.decode(response.body)
-        assert_kind_of Hash, json
-        assert_kind_of Array, json['news']
-        assert_kind_of Hash, json['news'].first
-        assert_equal 2, json['news'].first['id']
-      end
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c4/c4ac74e610c2462a31209e180df1fe8ab03e924c.svn-base
--- a/.svn/pristine/c4/c4ac74e610c2462a31209e180df1fe8ab03e924c.svn-base
+++ /dev/null
@@ -1,504 +0,0 @@
-                  GNU LESSER GENERAL PUBLIC LICENSE
-                       Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-                            Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-                  GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-                            NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-                     END OF TERMS AND CONDITIONS
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c4/c4b62ae1f4f01307776331aad68b547e24878c12.svn-base
--- a/.svn/pristine/c4/c4b62ae1f4f01307776331aad68b547e24878c12.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class ModelAndLibTest < Test::Unit::TestCase
-
- 	def test_WITH_a_model_defined_only_in_a_plugin_IT_should_load_the_model
- 	  assert_equal 'AlphaPluginModel (from alpha_plugin)', AlphaPluginModel.report_location
-  end
-  
-  def test_WITH_a_model_defined_only_in_a_plugin_lib_dir_IT_should_load_the_model
- 	  assert_equal 'AlphaPluginLibModel (from alpha_plugin)', AlphaPluginLibModel.report_location
-  end
-
-  # app takes precedence over plugins
-	
-	def test_WITH_a_model_defined_in_both_app_and_plugin_IT_should_load_the_one_in_app
- 	  assert_equal 'AppAndPluginModel (from app)',	AppAndPluginModel.report_location  
- 	  assert_raises(NoMethodError) { AppAndPluginLibModel.defined_only_in_alpha_engine_version }
-  end
-	
-	def test_WITH_a_model_defined_in_both_app_and_plugin_lib_dirs_IT_should_load_the_one_in_app
- 	  assert_equal 'AppAndPluginLibModel (from lib)', AppAndPluginLibModel.report_location
- 	  assert_raises(NoMethodError) { AppAndPluginLibModel.defined_only_in_alpha_engine_version }
-  end
-
-  # subsequently loaded plugins take precendence over previously loaded plugins
-	
-  # TODO
-  #
-  # this does work when we rely on $LOAD_PATH while it won't work when we use
-  # Dependency constant autoloading. This somewhat confusing difference has
-  # been there since at least Rails 1.2.x. See http://www.ruby-forum.com/topic/134529
-  
-  def test_WITH_a_model_defined_in_two_plugins_IT_should_load_the_latter_of_both
-    require 'shared_plugin_model'
-    assert_equal SharedPluginModel.report_location, 'SharedPluginModel (from beta_plugin)'
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c4/c4b7e166da06347732efe23afdfc246d0e8be00e.svn-base
--- a/.svn/pristine/c4/c4b7e166da06347732efe23afdfc246d0e8be00e.svn-base
+++ /dev/null
@@ -1,101 +0,0 @@
-# Contains the enhancements to assist in testing plugins. See Engines::Testing
-# for more details.
-
-require 'test/unit'
-
-require 'tmpdir'
-require 'fileutils'
-
-# In most cases, Rails' own plugin testing mechanisms are sufficient. However, there
-# are cases where plugins can be given a helping hand in the testing arena. This module 
-# contains some methods to assist when testing plugins that contain fixtures.
-# 
-# == Fixtures and plugins
-#
-# Since Rails' own fixtures method is fairly strict about where files can be loaded from,
-# the simplest approach when running plugin tests with fixtures is to simply copy all
-# fixtures into a single temporary location and inform the standard Rails mechanism to
-# use this directory, rather than RAILS_ROOT/test/fixtures.
-#
-# The Engines::Testing#setup_plugin_fixtures method does this, copying all plugin fixtures
-# into the temporary location before and tests are performed. This behaviour is invoked
-# the the rake tasks provided by the Engines plugin, in the "test:plugins" namespace. If
-# necessary, you can invoke the task manually.
-#
-# If you wish to take advantage of this, add a call to the Engines::Testing.set_fixture_path
-# method somewhere before your tests (in a test_helper file, or above the TestCase itself).
-#
-# = Testing plugins
-#
-# Normally testing a plugin will require that Rails is loaded, unless you are including
-# a skeleton Rails environment or set of mocks within your plugin tests. If you require
-# the Rails environment to be started, you must ensure that this actually happens; while
-# it's not obvious, your tests do not automatically run with Rails loaded.
-#
-# The simplest way to setup plugin tests is to include a test helper with the following
-# contents:
-#
-#   # Load the normal Rails helper. This ensures the environment is loaded
-#   require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
-#   # Ensure that we are using the temporary fixture path
-#   Engines::Testing.set_fixture_path
-#
-# Then run tests using the provided tasks (<tt>test:plugins</tt>, or the tasks that the engines
-# plugin provides - <tt>test:plugins:units</tt>, etc.).
-#
-# Alternatively, you can explicitly load the environment by adpating the contents of the
-# default <tt>test_helper</tt>:
-#
-#   ENV["RAILS_ENV"] = "test"
-#   # Note that we are requiring config/environment from the root of the enclosing application.
-#   require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
-#   require 'test_help'
-#
-module Engines::Testing
-  mattr_accessor :temporary_fixtures_directory
-  self.temporary_fixtures_directory = FileUtils.mkdir_p(File.join(Dir.tmpdir, "rails_fixtures"))
-  
-  # Copies fixtures from plugins and the application into a temporary directory 
-  # (Engines::Testing.temporary_fixtures_directory). 
-  # 
-  # If a set of plugins is not given, fixtures are copied from all plugins in order 
-  # of precedence, meaning that plugins can 'overwrite' the fixtures of others if they are 
-  # loaded later; the application's fixtures are copied last, allowing any custom fixtures
-  # to override those in the plugins. If no argument is given, plugins are loaded via
-  # PluginList#by_precedence.
-  #
-  # This method is called by the engines-supplied plugin testing rake tasks
-  def self.setup_plugin_fixtures(plugins = Engines.plugins.by_precedence)
-    
-    # First, clear the directory
-    Dir.glob("#{self.temporary_fixtures_directory}/*.yml").each{|fixture| File.delete(fixture)}
-    
-    # Copy all plugin fixtures, and then the application fixtures, into this directory
-    plugins.each do |plugin| 
-      plugin_fixtures_directory =  File.join(plugin.directory, "test", "fixtures")
-      plugin_app_directory =  File.join(plugin.directory, "app")
-      if File.directory?(plugin_app_directory) && File.directory?(plugin_fixtures_directory)
-        Engines.mirror_files_from(plugin_fixtures_directory, self.temporary_fixtures_directory)
-      end
-    end
-    Engines.mirror_files_from(File.join(RAILS_ROOT, "test", "fixtures"),
-                              self.temporary_fixtures_directory)
-  end
-  
-  # Sets the fixture path used by Test::Unit::TestCase to the temporary
-  # directory which contains all plugin fixtures.
-  def self.set_fixture_path
-    ActiveSupport::TestCase.fixture_path = self.temporary_fixtures_directory
-    $LOAD_PATH.unshift self.temporary_fixtures_directory
-  end
-  
-  # overridden test should be in test/{unit,functional,integration}/{plugin_name}/{test_name}
-  def self.override_tests_from_app
-    filename = caller.first.split(":").first
-    plugin_name = filename.split("/")[-4]
-    test_kind = filename.split("/")[-2]
-    override_file = File.expand_path(File.join(File.dirname(filename), "..", "..", "..", "..", "..", "test", 
-                                               test_kind, plugin_name, File.basename(filename)))
-    load(override_file) if File.exist?(override_file)
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c4/c4ee80c89b51195f1785a06677f274a4ebb1c20c.svn-base
--- a/.svn/pristine/c4/c4ee80c89b51195f1785a06677f274a4ebb1c20c.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-class Thing
-  def self.from_app; TestHelper::report_location(__FILE__); end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c52de5352fd6a63c50f835f73d19c6ea098b9072.svn-base
--- a/.svn/pristine/c5/c52de5352fd6a63c50f835f73d19c6ea098b9072.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-class SharedPluginModel < ActiveRecord::Base
-  def self.report_location; TestHelper::report_location(__FILE__); end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c52e05a6bbf465f32cbcf511ef2e13fc1ee99956.svn-base
--- /dev/null
+++ b/.svn/pristine/c5/c52e05a6bbf465f32cbcf511ef2e13fc1ee99956.svn-base
@@ -0,0 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module AccountHelper
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c5503b3ee9ba7623ae8cf8fbea689e4b99399e2c.svn-base
--- a/.svn/pristine/c5/c5503b3ee9ba7623ae8cf8fbea689e4b99399e2c.svn-base
+++ /dev/null
@@ -1,154 +0,0 @@
-require File.expand_path('../../../../../../test_helper', __FILE__)
-begin
-  require 'mocha'
-
-  class BazaarAdapterTest < ActiveSupport::TestCase
-    REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s
-    REPOSITORY_PATH.gsub!(/\/+/, '/')
-
-    if File.directory?(REPOSITORY_PATH)
-      def setup
-        @adapter = Redmine::Scm::Adapters::BazaarAdapter.new(
-                                File.join(REPOSITORY_PATH, "trunk")
-                                )
-      end
-
-      def test_scm_version
-        to_test = { "Bazaar (bzr) 2.1.2\n"             => [2,1,2],
-                    "2.1.1\n1.7\n1.8"                  => [2,1,1],
-                    "2.0.1\r\n1.8.1\r\n1.9.1"          => [2,0,1]}
-        to_test.each do |s, v|
-          test_scm_version_for(s, v)
-        end
-      end
-
-      def test_cat
-        cat = @adapter.cat('directory/document.txt')
-        assert cat =~ /Write the contents of a file as of a given revision to standard output/
-      end
-
-      def test_cat_path_invalid
-        assert_nil @adapter.cat('invalid')
-      end
-
-      def test_cat_revision_invalid
-        assert_nil @adapter.cat('doc-mkdir.txt', '12345678')
-      end
-
-      def test_diff_path_invalid
-        assert_equal [], @adapter.diff('invalid', 1)
-      end
-
-      def test_diff_revision_invalid
-        assert_equal [], @adapter.diff(nil, 12345678)
-        assert_equal [], @adapter.diff(nil, 12345678, 87654321)
-      end
-
-      def test_annotate
-        annotate = @adapter.annotate('doc-mkdir.txt')
-        assert_equal 17, annotate.lines.size
-        assert_equal '1', annotate.revisions[0].identifier
-        assert_equal 'jsmith@', annotate.revisions[0].author
-        assert_equal 'mkdir', annotate.lines[0]
-      end
-
-      def test_annotate_path_invalid
-        assert_nil @adapter.annotate('invalid')
-      end
-
-      def test_annotate_revision_invalid
-        assert_nil @adapter.annotate('doc-mkdir.txt', '12345678')
-      end
-
-      def test_branch_conf_path
-        p = "c:\\test\\test\\"
-        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
-        assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
-        p = "c:\\test\\test\\.bzr"
-        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
-        assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
-        p = "c:\\test\\test\\.bzr\\"
-        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
-        assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
-        p = "c:\\test\\test"
-        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
-        assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
-        p = "\\\\server\\test\\test\\"
-        bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
-        assert_equal File.join("\\\\server\\test\\test", ".bzr", "branch", "branch.conf"), bcp
-      end
-
-      def test_append_revisions_only_true
-        assert_equal true, @adapter.append_revisions_only
-      end
-
-      def test_append_revisions_only_false
-        adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
-                                File.join(REPOSITORY_PATH, "empty-branch")
-                                )
-        assert_equal false, adpt.append_revisions_only
-      end
-
-      def test_append_revisions_only_shared_repo
-        adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
-                                REPOSITORY_PATH
-                                )
-        assert_equal false, adpt.append_revisions_only
-      end
-
-      def test_info_not_nil
-        assert_not_nil @adapter.info
-      end
-
-      def test_info_nil
-        adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
-                  "/invalid/invalid/"
-                  )
-        assert_nil adpt.info
-      end
-
-      def test_info
-        info = @adapter.info
-        assert_equal 4, info.lastrev.identifier.to_i
-      end
-
-      def test_info_emtpy
-        adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
-                                File.join(REPOSITORY_PATH, "empty-branch")
-                                )
-        assert_equal 0, adpt.info.lastrev.identifier.to_i
-      end
-
-      def test_entries_path_invalid
-        assert_equal [], @adapter.entries('invalid')
-      end
-
-      def test_entries_revision_invalid
-        assert_nil @adapter.entries(nil, 12345678)
-      end
-
-      def test_revisions_path_invalid
-        assert_nil @adapter.revisions('invalid')
-      end
-
-      def test_revisions_revision_invalid
-        assert_nil @adapter.revisions(nil, 12345678)
-        assert_nil @adapter.revisions(nil, 12345678, 87654321)
-      end
-
-      private
-
-      def test_scm_version_for(scm_command_version, version)
-        @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
-        assert_equal version, @adapter.class.scm_command_version
-      end
-    else
-      puts "Bazaar test repository NOT FOUND. Skipping unit tests !!!"
-      def test_fake; assert true end
-    end
-  end
-rescue LoadError
-  class BazaarMochaFake < ActiveSupport::TestCase
-    def test_fake; assert(false, "Requires mocha to run those tests")  end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c5649a1bf27c5e95ae3ea1070e4c95186fc163f0.svn-base
--- a/.svn/pristine/c5/c5649a1bf27c5e95ae3ea1070e4c95186fc163f0.svn-base
+++ /dev/null
@@ -1,80 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'issues_controller'
-
-class IssuesControllerTransactionTest < ActionController::TestCase
-  fixtures :projects,
-           :users,
-           :roles,
-           :members,
-           :member_roles,
-           :issues,
-           :issue_statuses,
-           :versions,
-           :trackers,
-           :projects_trackers,
-           :issue_categories,
-           :enabled_modules,
-           :enumerations,
-           :attachments,
-           :workflows,
-           :custom_fields,
-           :custom_values,
-           :custom_fields_projects,
-           :custom_fields_trackers,
-           :time_entries,
-           :journals,
-           :journal_details,
-           :queries
-
-  self.use_transactional_fixtures = false
-
-  def setup
-    @controller = IssuesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_put_update_stale_issue
-    issue = Issue.find(2)
-    @request.session[:user_id] = 2
-
-    assert_no_difference 'Journal.count' do
-      assert_no_difference 'TimeEntry.count' do
-        assert_no_difference 'Attachment.count' do
-          put :update,
-                :id => issue.id,
-                :issue => {
-                  :fixed_version_id => 4,
-                  :lock_version => (issue.lock_version - 1)
-                },
-                :notes => '',
-                :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}},
-                :time_entry => { :hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first.id }
-        end
-      end
-    end
-
-    assert_response :success
-    assert_template 'edit'
-    assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' },
-                              :content => /Data has been updated by another user/
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c5707570ea0196ea9f935f667e3dcd5ff44e5925.svn-base
--- a/.svn/pristine/c5/c5707570ea0196ea9f935f667e3dcd5ff44e5925.svn-base
+++ /dev/null
@@ -1,74 +0,0 @@
-Return-Path: <jsmith@somenet.foo>
-Received: from osiris ([127.0.0.1])
-	by OSIRIS
-	with hMailServer ; Sat, 21 Jun 2008 18:41:39 +0200
-Message-ID: <006a01c8d3bd$ad9baec0$0a00a8c0@osiris>
-In-Reply-To: <redmine.issue-2.20060719210421@osiris>
-From: "John Smith" <jsmith@somenet.foo>
-To: <redmine@somenet.foo>
-References: <485d0ad366c88_d7014663a025f@osiris.tmail>
-Subject: Re: Add ingredients categories
-Date: Sat, 21 Jun 2008 18:41:39 +0200
-MIME-Version: 1.0
-Content-Type: multipart/alternative;
-	boundary="----=_NextPart_000_0067_01C8D3CE.711F9CC0"
-X-Priority: 3
-X-MSMail-Priority: Normal
-X-Mailer: Microsoft Outlook Express 6.00.2900.2869
-X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
-
-This is a multi-part message in MIME format.
-
-------=_NextPart_000_0067_01C8D3CE.711F9CC0
-Content-Type: text/plain;
-	charset="utf-8"
-Content-Transfer-Encoding: quoted-printable
-
-This is reply
-------=_NextPart_000_0067_01C8D3CE.711F9CC0
-Content-Type: text/html;
-	charset="utf-8"
-Content-Transfer-Encoding: quoted-printable
-
-=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<HTML><HEAD>
-<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
-<STYLE>BODY {
-	FONT-SIZE: 0.8em; COLOR: #484848; FONT-FAMILY: Verdana, sans-serif
-}
-BODY H1 {
-	FONT-SIZE: 1.2em; MARGIN: 0px; FONT-FAMILY: "Trebuchet MS", Verdana, =
-sans-serif
-}
-A {
-	COLOR: #2a5685
-}
-A:link {
-	COLOR: #2a5685
-}
-A:visited {
-	COLOR: #2a5685
-}
-A:hover {
-	COLOR: #c61a1a
-}
-A:active {
-	COLOR: #c61a1a
-}
-HR {
-	BORDER-RIGHT: 0px; BORDER-TOP: 0px; BACKGROUND: #ccc; BORDER-LEFT: 0px; =
-WIDTH: 100%; BORDER-BOTTOM: 0px; HEIGHT: 1px
-}
-.footer {
-	FONT-SIZE: 0.8em; FONT-STYLE: italic
-}
-</STYLE>
-
-<META content=3D"MSHTML 6.00.2900.2883" name=3DGENERATOR></HEAD>
-<BODY bgColor=3D#ffffff>
-<DIV><SPAN class=3Dfooter><FONT face=3DArial color=3D#000000 =
-size=3D2>This is=20
-reply</FONT></DIV></SPAN></BODY></HTML>
-
-------=_NextPart_000_0067_01C8D3CE.711F9CC0--
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c579e1089533be72e96be9f837601901aa22b4de.svn-base
--- /dev/null
+++ b/.svn/pristine/c5/c579e1089533be72e96be9f837601901aa22b4de.svn-base
@@ -0,0 +1,263 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+require 'issues_controller'
+
+class IssuesControllerTransactionTest < ActionController::TestCase
+  tests IssuesController
+  fixtures :projects,
+           :users,
+           :roles,
+           :members,
+           :member_roles,
+           :issues,
+           :issue_statuses,
+           :versions,
+           :trackers,
+           :projects_trackers,
+           :issue_categories,
+           :enabled_modules,
+           :enumerations,
+           :attachments,
+           :workflows,
+           :custom_fields,
+           :custom_values,
+           :custom_fields_projects,
+           :custom_fields_trackers,
+           :time_entries,
+           :journals,
+           :journal_details,
+           :queries
+
+  self.use_transactional_fixtures = false
+
+  def setup
+    User.current = nil
+  end
+
+  def test_update_stale_issue_should_not_update_the_issue
+    issue = Issue.find(2)
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Journal.count' do
+      assert_no_difference 'TimeEntry.count' do
+        put :update,
+              :id => issue.id,
+              :issue => {
+                :fixed_version_id => 4,
+                :notes => 'My notes',
+                :lock_version => (issue.lock_version - 1)
+              },
+              :time_entry => { :hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first.id }
+      end
+    end
+
+    assert_response :success
+    assert_template 'edit'
+
+    assert_select 'div.conflict'
+    assert_select 'input[name=?][value=?]', 'conflict_resolution', 'overwrite'
+    assert_select 'input[name=?][value=?]', 'conflict_resolution', 'add_notes'
+    assert_select 'label' do
+      assert_select 'input[name=?][value=?]', 'conflict_resolution', 'cancel'
+      assert_select 'a[href=/issues/2]'
+    end
+  end
+
+  def test_update_stale_issue_should_save_attachments
+    set_tmp_attachments_directory
+    issue = Issue.find(2)
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Journal.count' do
+      assert_no_difference 'TimeEntry.count' do
+        assert_difference 'Attachment.count' do
+          put :update,
+                :id => issue.id,
+                :issue => {
+                  :fixed_version_id => 4,
+                  :notes => 'My notes',
+                  :lock_version => (issue.lock_version - 1)
+                },
+                :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}},
+                :time_entry => { :hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first.id }
+        end
+      end
+    end
+
+    assert_response :success
+    assert_template 'edit'
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
+    assert_tag 'input', :attributes => {:name => 'attachments[p0][filename]', :value => 'testfile.txt'}
+  end
+
+  def test_update_stale_issue_without_notes_should_not_show_add_notes_option
+    issue = Issue.find(2)
+    @request.session[:user_id] = 2
+
+    put :update, :id => issue.id,
+          :issue => {
+            :fixed_version_id => 4,
+            :notes => '',
+            :lock_version => (issue.lock_version - 1)
+          }
+
+    assert_tag 'div', :attributes => {:class => 'conflict'}
+    assert_tag 'input', :attributes => {:name => 'conflict_resolution', :value => 'overwrite'}
+    assert_no_tag 'input', :attributes => {:name => 'conflict_resolution', :value => 'add_notes'}
+    assert_tag 'input', :attributes => {:name => 'conflict_resolution', :value => 'cancel'}
+  end
+
+  def test_update_stale_issue_should_show_conflicting_journals
+    @request.session[:user_id] = 2
+
+    put :update, :id => 1,
+          :issue => {
+            :fixed_version_id => 4,
+            :notes => '',
+            :lock_version => 2
+          },
+          :last_journal_id => 1
+
+    assert_not_nil assigns(:conflict_journals)
+    assert_equal 1, assigns(:conflict_journals).size
+    assert_equal 2, assigns(:conflict_journals).first.id
+    assert_tag 'div', :attributes => {:class => 'conflict'},
+      :descendant => {:content => /Some notes with Redmine links/}
+  end
+
+  def test_update_stale_issue_without_previous_journal_should_show_all_journals
+    @request.session[:user_id] = 2
+
+    put :update, :id => 1,
+          :issue => {
+            :fixed_version_id => 4,
+            :notes => '',
+            :lock_version => 2
+          },
+          :last_journal_id => ''
+
+    assert_not_nil assigns(:conflict_journals)
+    assert_equal 2, assigns(:conflict_journals).size
+    assert_tag 'div', :attributes => {:class => 'conflict'},
+      :descendant => {:content => /Some notes with Redmine links/}
+    assert_tag 'div', :attributes => {:class => 'conflict'},
+      :descendant => {:content => /Journal notes/}
+  end
+
+  def test_update_stale_issue_should_show_private_journals_with_permission_only
+    journal = Journal.create!(:journalized => Issue.find(1), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
+
+    @request.session[:user_id] = 2
+    put :update, :id => 1, :issue => {:fixed_version_id => 4, :lock_version => 2}, :last_journal_id => ''
+    assert_include journal, assigns(:conflict_journals)
+
+    Role.find(1).remove_permission! :view_private_notes
+    put :update, :id => 1, :issue => {:fixed_version_id => 4, :lock_version => 2}, :last_journal_id => ''
+    assert_not_include journal, assigns(:conflict_journals)
+  end
+
+  def test_update_stale_issue_with_overwrite_conflict_resolution_should_update
+    @request.session[:user_id] = 2
+
+    assert_difference 'Journal.count' do
+      put :update, :id => 1,
+            :issue => {
+              :fixed_version_id => 4,
+              :notes => 'overwrite_conflict_resolution',
+              :lock_version => 2
+            },
+            :conflict_resolution => 'overwrite'
+    end
+
+    assert_response 302
+    issue = Issue.find(1)
+    assert_equal 4, issue.fixed_version_id
+    journal = Journal.first(:order => 'id DESC')
+    assert_equal 'overwrite_conflict_resolution', journal.notes
+    assert journal.details.any?
+  end
+
+  def test_update_stale_issue_with_add_notes_conflict_resolution_should_update
+    @request.session[:user_id] = 2
+
+    assert_difference 'Journal.count' do
+      put :update, :id => 1,
+            :issue => {
+              :fixed_version_id => 4,
+              :notes => 'add_notes_conflict_resolution',
+              :lock_version => 2
+            },
+            :conflict_resolution => 'add_notes'
+    end
+
+    assert_response 302
+    issue = Issue.find(1)
+    assert_nil issue.fixed_version_id
+    journal = Journal.first(:order => 'id DESC')
+    assert_equal 'add_notes_conflict_resolution', journal.notes
+    assert journal.details.empty?
+  end
+
+  def test_update_stale_issue_with_cancel_conflict_resolution_should_redirect_without_updating
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Journal.count' do
+      put :update, :id => 1,
+            :issue => {
+              :fixed_version_id => 4,
+              :notes => 'add_notes_conflict_resolution',
+              :lock_version => 2
+            },
+            :conflict_resolution => 'cancel'
+    end
+
+    assert_redirected_to '/issues/1'
+    issue = Issue.find(1)
+    assert_nil issue.fixed_version_id
+  end
+
+  def test_put_update_with_spent_time_and_failure_should_not_add_spent_time
+    @request.session[:user_id] = 2
+
+    assert_no_difference('TimeEntry.count') do
+      put :update,
+           :id => 1,
+           :issue => { :subject => '' },
+           :time_entry => { :hours => '2.5', :comments => 'should not be added', :activity_id => TimeEntryActivity.first.id }
+      assert_response :success
+    end
+
+    assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2.5'
+    assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'should not be added'
+    assert_select 'select[name=?]', 'time_entry[activity_id]' do
+      assert_select 'option[value=?][selected=selected]', TimeEntryActivity.first.id
+    end
+  end
+
+  def test_index_should_rescue_invalid_sql_query
+    IssueQuery.any_instance.stubs(:statement).returns("INVALID STATEMENT")
+
+    get :index
+    assert_response 500
+    assert_tag 'p', :content => /An error occurred/
+    assert_nil session[:query]
+    assert_nil session[:issues_index_sort]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c58d60a26982a819fdf9b2a65688b42aae5216fc.svn-base
--- /dev/null
+++ b/.svn/pristine/c5/c58d60a26982a819fdf9b2a65688b42aae5216fc.svn-base
@@ -0,0 +1,32 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingReportsTest < ActionController::IntegrationTest
+  def test_reports
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/issues/report" },
+        { :controller => 'reports', :action => 'issue_report', :id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/issues/report/assigned_to" },
+        { :controller => 'reports', :action => 'issue_report_details',
+          :id => '567', :detail => 'assigned_to' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c5babbe46fab862c827420531f4d70904c54b5e3.svn-base
--- /dev/null
+++ b/.svn/pristine/c5/c5babbe46fab862c827420531f4d70904c54b5e3.svn-base
@@ -0,0 +1,373 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoryTest < ActiveSupport::TestCase
+  fixtures :projects,
+           :trackers,
+           :projects_trackers,
+           :enabled_modules,
+           :repositories,
+           :issues,
+           :issue_statuses,
+           :issue_categories,
+           :changesets,
+           :changes,
+           :users,
+           :members,
+           :member_roles,
+           :roles,
+           :enumerations
+
+  include Redmine::I18n
+
+  def setup
+    @repository = Project.find(1).repository
+  end
+
+  def test_blank_log_encoding_error_message
+    set_language_if_valid 'en'
+    repo = Repository::Bazaar.new(
+                        :project      => Project.find(3),
+                        :url          => "/test",
+                        :log_encoding => ''
+                      )
+    assert !repo.save
+    assert_include "Commit messages encoding can't be blank",
+                   repo.errors.full_messages
+  end
+
+  def test_blank_log_encoding_error_message_fr
+    set_language_if_valid 'fr'
+    str = "Encodage des messages de commit doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    repo = Repository::Bazaar.new(
+                        :project      => Project.find(3),
+                        :url          => "/test"
+                      )
+    assert !repo.save
+    assert_include str, repo.errors.full_messages
+  end
+
+  def test_create
+    repository = Repository::Subversion.new(:project => Project.find(3))
+    assert !repository.save
+
+    repository.url = "svn://localhost"
+    assert repository.save
+    repository.reload
+
+    project = Project.find(3)
+    assert_equal repository, project.repository
+  end
+
+  def test_first_repository_should_be_set_as_default
+    repository1 = Repository::Subversion.new(
+                      :project => Project.find(3),
+                      :identifier => 'svn1',
+                      :url => 'file:///svn1'
+                    )
+    assert repository1.save
+    assert repository1.is_default?
+
+    repository2 = Repository::Subversion.new(
+                      :project => Project.find(3),
+                      :identifier => 'svn2',
+                      :url => 'file:///svn2'
+                    )
+    assert repository2.save
+    assert !repository2.is_default?
+
+    assert_equal repository1, Project.find(3).repository
+    assert_equal [repository1, repository2], Project.find(3).repositories.sort
+  end
+
+  def test_identifier_should_accept_letters_digits_dashes_and_underscores
+    r = Repository::Subversion.new(
+      :project_id => 3,
+      :identifier => 'svn-123_45',
+      :url => 'file:///svn'
+    )
+    assert r.save
+  end
+  
+  def test_identifier_should_not_be_frozen_for_a_new_repository
+    assert_equal false, Repository.new.identifier_frozen?
+  end
+
+  def test_identifier_should_not_be_frozen_for_a_saved_repository_with_blank_identifier
+    Repository.update_all(["identifier = ''"], "id = 10")
+
+    assert_equal false, Repository.find(10).identifier_frozen?
+  end
+
+  def test_identifier_should_be_frozen_for_a_saved_repository_with_valid_identifier
+    Repository.update_all(["identifier = 'abc123'"], "id = 10")
+
+    assert_equal true, Repository.find(10).identifier_frozen?
+  end
+
+  def test_identifier_should_not_accept_change_if_frozen
+    r = Repository.new(:identifier => 'foo')
+    r.stubs(:identifier_frozen?).returns(true)
+
+    r.identifier = 'bar'
+    assert_equal 'foo', r.identifier
+  end
+
+  def test_identifier_should_accept_change_if_not_frozen
+    r = Repository.new(:identifier => 'foo')
+    r.stubs(:identifier_frozen?).returns(false)
+
+    r.identifier = 'bar'
+    assert_equal 'bar', r.identifier
+  end
+
+  def test_destroy
+    repository = Repository.find(10)
+    changesets = repository.changesets.count
+    changes = repository.filechanges.count
+
+    assert_difference 'Changeset.count', -changesets do
+      assert_difference 'Change.count', -changes do
+        Repository.find(10).destroy
+      end
+    end
+  end
+
+  def test_destroy_should_delete_parents_associations
+    changeset = Changeset.find(102)
+    changeset.parents = Changeset.find_all_by_id([100, 101])
+
+    assert_difference 'Changeset.connection.select_all("select * from changeset_parents").size', -2 do
+      Repository.find(10).destroy
+    end
+  end
+
+  def test_destroy_should_delete_issues_associations
+    changeset = Changeset.find(102)
+    changeset.issues = Issue.find_all_by_id([1, 2])
+
+    assert_difference 'Changeset.connection.select_all("select * from changesets_issues").size', -2 do
+      Repository.find(10).destroy
+    end
+  end
+
+  def test_should_not_create_with_disabled_scm
+    # disable Subversion
+    with_settings :enabled_scm => ['Darcs', 'Git'] do
+      repository = Repository::Subversion.new(
+                      :project => Project.find(3), :url => "svn://localhost")
+      assert !repository.save
+      assert_include I18n.translate('activerecord.errors.messages.invalid'),
+                     repository.errors[:type]
+    end
+  end
+
+  def test_scan_changesets_for_issue_ids
+    Setting.default_language = 'en'
+
+    # choosing a status to apply to fix issues
+    Setting.commit_fix_status_id = IssueStatus.find(
+                                     :first,
+                                     :conditions => ["is_closed = ?", true]).id
+    Setting.commit_fix_done_ratio = "90"
+    Setting.commit_ref_keywords = 'refs , references, IssueID'
+    Setting.commit_fix_keywords = 'fixes , closes'
+    Setting.default_language = 'en'
+    ActionMailer::Base.deliveries.clear
+
+    # make sure issue 1 is not already closed
+    fixed_issue = Issue.find(1)
+    assert !fixed_issue.status.is_closed?
+    old_status = fixed_issue.status
+
+    with_settings :notified_events => %w(issue_added issue_updated) do
+      Repository.scan_changesets_for_issue_ids
+    end
+    assert_equal [101, 102], Issue.find(3).changeset_ids
+
+    # fixed issues
+    fixed_issue.reload
+    assert fixed_issue.status.is_closed?
+    assert_equal 90, fixed_issue.done_ratio
+    assert_equal [101], fixed_issue.changeset_ids
+
+    # issue change
+    journal = fixed_issue.journals.reorder('created_on desc').first
+    assert_equal User.find_by_login('dlopper'), journal.user
+    assert_equal 'Applied in changeset r2.', journal.notes
+
+    # 2 email notifications
+    assert_equal 2, ActionMailer::Base.deliveries.size
+    mail = ActionMailer::Base.deliveries.first
+    assert_not_nil mail
+    assert mail.subject.starts_with?(
+        "[#{fixed_issue.project.name} - #{fixed_issue.tracker.name} ##{fixed_issue.id}]")
+    assert_mail_body_match(
+        "Status changed from #{old_status} to #{fixed_issue.status}", mail)
+
+    # ignoring commits referencing an issue of another project
+    assert_equal [], Issue.find(4).changesets
+  end
+
+  def test_for_changeset_comments_strip
+    repository = Repository::Mercurial.create(
+                    :project => Project.find( 4 ),
+                    :url => '/foo/bar/baz' )
+    comment = <<-COMMENT
+    This is a loooooooooooooooooooooooooooong comment                                                   
+                                                                                                       
+                                                                                            
+    COMMENT
+    changeset = Changeset.new(
+      :comments => comment, :commit_date => Time.now,
+      :revision => 0, :scmid => 'f39b7922fb3c',
+      :committer => 'foo <foo@example.com>',
+      :committed_on => Time.now, :repository => repository )
+    assert( changeset.save )
+    assert_not_equal( comment, changeset.comments )
+    assert_equal( 'This is a loooooooooooooooooooooooooooong comment',
+                  changeset.comments )
+  end
+
+  def test_for_urls_strip_cvs
+    repository = Repository::Cvs.create(
+        :project => Project.find(4),
+        :url => ' :pserver:login:password@host:/path/to/the/repository',
+        :root_url => 'foo  ',
+        :log_encoding => 'UTF-8')
+    assert repository.save
+    repository.reload
+    assert_equal ':pserver:login:password@host:/path/to/the/repository',
+                  repository.url
+    assert_equal 'foo', repository.root_url
+  end
+
+  def test_for_urls_strip_subversion
+    repository = Repository::Subversion.create(
+        :project => Project.find(4),
+        :url => ' file:///dummy   ')
+    assert repository.save
+    repository.reload
+    assert_equal 'file:///dummy', repository.url
+  end
+
+  def test_for_urls_strip_git
+    repository = Repository::Git.create(
+        :project => Project.find(4),
+        :url => ' c:\dummy   ')
+    assert repository.save
+    repository.reload
+    assert_equal 'c:\dummy', repository.url
+  end
+
+  def test_manual_user_mapping
+    assert_no_difference "Changeset.count(:conditions => 'user_id <> 2')" do
+      c = Changeset.create!(
+              :repository => @repository,
+              :committer => 'foo',
+              :committed_on => Time.now,
+              :revision => 100,
+              :comments => 'Committed by foo.'
+            )
+      assert_nil c.user
+      @repository.committer_ids = {'foo' => '2'}
+      assert_equal User.find(2), c.reload.user
+      # committer is now mapped
+      c = Changeset.create!(
+              :repository => @repository,
+              :committer => 'foo',
+              :committed_on => Time.now,
+              :revision => 101,
+              :comments => 'Another commit by foo.'
+            )
+      assert_equal User.find(2), c.user
+    end
+  end
+
+  def test_auto_user_mapping_by_username
+    c = Changeset.create!(
+          :repository   => @repository,
+          :committer    => 'jsmith',
+          :committed_on => Time.now,
+          :revision     => 100,
+          :comments     => 'Committed by john.'
+        )
+    assert_equal User.find(2), c.user
+  end
+
+  def test_auto_user_mapping_by_email
+    c = Changeset.create!(
+          :repository   => @repository,
+          :committer    => 'john <jsmith@somenet.foo>',
+          :committed_on => Time.now,
+          :revision     => 100,
+          :comments     => 'Committed by john.'
+        )
+    assert_equal User.find(2), c.user
+  end
+
+  def test_filesystem_avaialbe
+    klass = Repository::Filesystem
+    assert klass.scm_adapter_class
+    assert_equal true, klass.scm_available
+  end
+
+  def test_merge_extra_info
+    repo = Repository::Subversion.new(:project => Project.find(3))
+    assert !repo.save
+    repo.url = "svn://localhost"
+    assert repo.save
+    repo.reload
+    project = Project.find(3)
+    assert_equal repo, project.repository
+    assert_nil repo.extra_info
+    h1 = {"test_1" => {"test_11" => "test_value_11"}}
+    repo.merge_extra_info(h1)
+    assert_equal h1, repo.extra_info
+    h2 = {"test_2" => {
+                   "test_21" => "test_value_21",
+                   "test_22" => "test_value_22",
+                  }}
+    repo.merge_extra_info(h2)
+    assert_equal (h = {"test_11" => "test_value_11"}),
+                 repo.extra_info["test_1"]
+    assert_equal "test_value_21",
+                 repo.extra_info["test_2"]["test_21"]
+    h3 = {"test_2" => {
+                   "test_23" => "test_value_23",
+                   "test_24" => "test_value_24",
+                  }}
+    repo.merge_extra_info(h3)
+    assert_equal (h = {"test_11" => "test_value_11"}),
+                 repo.extra_info["test_1"]
+    assert_nil repo.extra_info["test_2"]["test_21"]
+    assert_equal "test_value_23",
+                 repo.extra_info["test_2"]["test_23"]
+  end
+
+  def test_sort_should_not_raise_an_error_with_nil_identifiers
+    r1 = Repository.new
+    r2 = Repository.new
+
+    assert_nothing_raised do
+      [r1, r2].sort
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c5caa31d1ab1ccf81fe14cfaca2195b9d5a737f4.svn-base
--- a/.svn/pristine/c5/c5caa31d1ab1ccf81fe14cfaca2195b9d5a737f4.svn-base
+++ /dev/null
@@ -1,73 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class CustomValue < ActiveRecord::Base
-  belongs_to :custom_field
-  belongs_to :customized, :polymorphic => true
-
-  validate :validate_custom_value
-
-  def after_initialize
-    if new_record? && custom_field && (customized_type.blank? || (customized && customized.new_record?))
-      self.value ||= custom_field.default_value
-    end
-  end
-
-  # Returns true if the boolean custom value is true
-  def true?
-    self.value == '1'
-  end
-
-  def editable?
-    custom_field.editable?
-  end
-
-  def visible?
-    custom_field.visible?
-  end
-
-  def required?
-    custom_field.is_required?
-  end
-
-  def to_s
-    value.to_s
-  end
-
-protected
-  def validate_custom_value
-    if value.blank?
-      errors.add(:value, :blank) if custom_field.is_required? and value.blank?
-    else
-      errors.add(:value, :invalid) unless custom_field.regexp.blank? or value =~ Regexp.new(custom_field.regexp)
-      errors.add(:value, :too_short, :count => custom_field.min_length) if custom_field.min_length > 0 and value.length < custom_field.min_length
-      errors.add(:value, :too_long, :count => custom_field.max_length) if custom_field.max_length > 0 and value.length > custom_field.max_length
-
-      # Format specific validations
-      case custom_field.field_format
-      when 'int'
-        errors.add(:value, :not_a_number) unless value =~ /^[+-]?\d+$/	
-      when 'float'
-        begin; Kernel.Float(value); rescue; errors.add(:value, :invalid) end
-      when 'date'
-        errors.add(:value, :not_a_date) unless value =~ /^\d{4}-\d{2}-\d{2}$/ && begin; value.to_date; rescue; false end
-      when 'list'
-        errors.add(:value, :inclusion) unless custom_field.possible_values.include?(value)
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c5/c5eef695c607c92e30f00026dd7c86eab2c87b3e.svn-base
--- a/.svn/pristine/c5/c5eef695c607c92e30f00026dd7c86eab2c87b3e.svn-base
+++ /dev/null
@@ -1,76 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class CustomFieldVersionFormatTest < ActiveSupport::TestCase
-  fixtures :custom_fields, :projects, :members, :users, :member_roles, :trackers, :issues, :versions
-
-  def setup
-    @field = IssueCustomField.create!(:name => 'Tester', :field_format => 'version')
-  end
-
-  def test_possible_values_with_no_arguments
-    assert_equal [], @field.possible_values
-    assert_equal [], @field.possible_values(nil)
-  end
-
-  def test_possible_values_with_project_resource
-    project = Project.find(1)
-    possible_values = @field.possible_values(project.issues.first)
-    assert possible_values.any?
-    assert_equal project.shared_versions.sort.collect(&:id).map(&:to_s), possible_values
-  end
-
-  def test_possible_values_with_nil_project_resource
-    assert_equal [], @field.possible_values(Issue.new)
-  end
-
-  def test_possible_values_options_with_no_arguments
-    assert_equal [], @field.possible_values_options
-    assert_equal [], @field.possible_values_options(nil)
-  end
-
-  def test_possible_values_options_with_project_resource
-    project = Project.find(1)
-    possible_values_options = @field.possible_values_options(project.issues.first)
-    assert possible_values_options.any?
-    assert_equal project.shared_versions.sort.map {|u| [u.name, u.id.to_s]}, possible_values_options
-  end
-
-  def test_possible_values_options_with_array
-    projects = Project.find([1, 2])
-    possible_values_options = @field.possible_values_options(projects)
-    assert possible_values_options.any?
-    assert_equal (projects.first.shared_versions & projects.last.shared_versions).sort.map {|u| [u.name, u.id.to_s]}, possible_values_options
-  end
-
-  def test_cast_blank_value
-    assert_equal nil, @field.cast_value(nil)
-    assert_equal nil, @field.cast_value("")
-  end
-
-  def test_cast_valid_value
-    version = @field.cast_value("2")
-    assert_kind_of Version, version
-    assert_equal Version.find(2), version
-  end
-
-  def test_cast_invalid_value
-    assert_equal nil, @field.cast_value("187")
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c6/c620273a13fb0c5f40f2c943a9b0b5bb40f34369.svn-base
--- /dev/null
+++ b/.svn/pristine/c6/c620273a13fb0c5f40f2c943a9b0b5bb40f34369.svn-base
@@ -0,0 +1,164 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::TimeEntriesTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :time_entries
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "GET /time_entries.xml" do
+    should "return time entries" do
+      get '/time_entries.xml', {}, credentials('jsmith')
+      assert_response :success
+      assert_equal 'application/xml', @response.content_type
+      assert_tag :tag => 'time_entries',
+        :child => {:tag => 'time_entry', :child => {:tag => 'id', :content => '2'}}
+    end
+
+    context "with limit" do
+      should "return limited results" do
+        get '/time_entries.xml?limit=2', {}, credentials('jsmith')
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+        assert_tag :tag => 'time_entries',
+          :children => {:count => 2}
+      end
+    end
+  end
+
+  context "GET /time_entries/2.xml" do
+    should "return requested time entry" do
+      get '/time_entries/2.xml', {}, credentials('jsmith')
+      assert_response :success
+      assert_equal 'application/xml', @response.content_type
+      assert_tag :tag => 'time_entry',
+        :child => {:tag => 'id', :content => '2'}
+    end
+  end
+
+  context "POST /time_entries.xml" do
+    context "with issue_id" do
+      should "return create time entry" do
+        assert_difference 'TimeEntry.count' do
+          post '/time_entries.xml', {:time_entry => {:issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, credentials('jsmith')
+        end
+        assert_response :created
+        assert_equal 'application/xml', @response.content_type
+
+        entry = TimeEntry.first(:order => 'id DESC')
+        assert_equal 'jsmith', entry.user.login
+        assert_equal Issue.find(1), entry.issue
+        assert_equal Project.find(1), entry.project
+        assert_equal Date.parse('2010-12-02'), entry.spent_on
+        assert_equal 3.5, entry.hours
+        assert_equal TimeEntryActivity.find(11), entry.activity
+      end
+
+      should "accept custom fields" do
+        field = TimeEntryCustomField.create!(:name => 'Test', :field_format => 'string')
+
+        assert_difference 'TimeEntry.count' do
+          post '/time_entries.xml', {:time_entry => {
+            :issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11', :custom_fields => [{:id => field.id.to_s, :value => 'accepted'}]
+          }}, credentials('jsmith')
+        end
+        assert_response :created
+        assert_equal 'application/xml', @response.content_type
+
+        entry = TimeEntry.first(:order => 'id DESC')
+        assert_equal 'accepted', entry.custom_field_value(field)
+      end
+    end
+
+    context "with project_id" do
+      should "return create time entry" do
+        assert_difference 'TimeEntry.count' do
+          post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, credentials('jsmith')
+        end
+        assert_response :created
+        assert_equal 'application/xml', @response.content_type
+
+        entry = TimeEntry.first(:order => 'id DESC')
+        assert_equal 'jsmith', entry.user.login
+        assert_nil entry.issue
+        assert_equal Project.find(1), entry.project
+        assert_equal Date.parse('2010-12-02'), entry.spent_on
+        assert_equal 3.5, entry.hours
+        assert_equal TimeEntryActivity.find(11), entry.activity
+      end
+    end
+
+    context "with invalid parameters" do
+      should "return errors" do
+        assert_no_difference 'TimeEntry.count' do
+          post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :activity_id => '11'}}, credentials('jsmith')
+        end
+        assert_response :unprocessable_entity
+        assert_equal 'application/xml', @response.content_type
+
+        assert_tag 'errors', :child => {:tag => 'error', :content => "Hours can't be blank"}
+      end
+    end
+  end
+
+  context "PUT /time_entries/2.xml" do
+    context "with valid parameters" do
+      should "update time entry" do
+        assert_no_difference 'TimeEntry.count' do
+          put '/time_entries/2.xml', {:time_entry => {:comments => 'API Update'}}, credentials('jsmith')
+        end
+        assert_response :ok
+        assert_equal '', @response.body
+        assert_equal 'API Update', TimeEntry.find(2).comments
+      end
+    end
+
+    context "with invalid parameters" do
+      should "return errors" do
+        assert_no_difference 'TimeEntry.count' do
+          put '/time_entries/2.xml', {:time_entry => {:hours => '', :comments => 'API Update'}}, credentials('jsmith')
+        end
+        assert_response :unprocessable_entity
+        assert_equal 'application/xml', @response.content_type
+
+        assert_tag 'errors', :child => {:tag => 'error', :content => "Hours can't be blank"}
+      end
+    end
+  end
+
+  context "DELETE /time_entries/2.xml" do
+    should "destroy time entry" do
+      assert_difference 'TimeEntry.count', -1 do
+        delete '/time_entries/2.xml', {}, credentials('jsmith')
+      end
+      assert_response :ok
+      assert_equal '', @response.body
+      assert_nil TimeEntry.find_by_id(2)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c6/c65bfd6780a9f0fa4b112d559eaf34468d9f02bc.svn-base
--- a/.svn/pristine/c6/c65bfd6780a9f0fa4b112d559eaf34468d9f02bc.svn-base
+++ /dev/null
@@ -1,1011 +0,0 @@
-en-GB:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%d/%m/%Y"
-      short: "%d %b"
-      long: "%d %B, %Y"
-      
-    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
-    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
-    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%d/%m/%Y %I:%M %p"
-      time: "%I:%M %p"
-      short: "%d %b %H:%M"
-      long: "%d %B, %Y %H:%M"
-    am: "am"
-    pm: "pm"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "half a minute"
-      less_than_x_seconds:
-        one:   "less than 1 second"
-        other: "less than %{count} seconds"
-      x_seconds:
-        one:   "1 second"
-        other: "%{count} seconds"
-      less_than_x_minutes:
-        one:   "less than a minute"
-        other: "less than %{count} minutes"
-      x_minutes:
-        one:   "1 minute"
-        other: "%{count} minutes"
-      about_x_hours:
-        one:   "about 1 hour"
-        other: "about %{count} hours"
-      x_days:
-        one:   "1 day"
-        other: "%{count} days"
-      about_x_months:
-        one:   "about 1 month"
-        other: "about %{count} months"
-      x_months:
-        one:   "1 month"
-        other: "%{count} months"
-      about_x_years:
-        one:   "about 1 year"
-        other: "about %{count} years"
-      over_x_years:
-        one:   "over 1 year"
-        other: "over %{count} years"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  number:
-    format:
-      separator: "."
-      delimiter: " "
-      precision: 3
-
-    currency:
-      format:
-        format: "%u%n"
-        unit: "Â£"
-
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "kB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "and"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "is not included in the list"
-        exclusion: "is reserved"
-        invalid: "is invalid"
-        confirmation: "doesn't match confirmation"
-        accepted: "must be accepted"
-        empty: "can't be empty"
-        blank: "can't be blank"
-        too_long: "is too long (maximum is %{count} characters)"
-        too_short: "is too short (minimum is %{count} characters)"
-        wrong_length: "is the wrong length (should be %{count} characters)"
-        taken: "has already been taken"
-        not_a_number: "is not a number"
-        not_a_date: "is not a valid date"
-        greater_than: "must be greater than %{count}"
-        greater_than_or_equal_to: "must be greater than or equal to %{count}"
-        equal_to: "must be equal to %{count}"
-        less_than: "must be less than %{count}"
-        less_than_or_equal_to: "must be less than or equal to %{count}"
-        odd: "must be odd"
-        even: "must be even"
-        greater_than_start_date: "must be greater than start date"
-        not_same_project: "doesn't belong to the same project"
-        circular_dependency: "This relation would create a circular dependency"
-        cant_link_an_issue_with_a_descendant: "An issue cannot be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: Please select
-  
-  general_text_No: 'No'
-  general_text_Yes: 'Yes'
-  general_text_no: 'no'
-  general_text_yes: 'yes'
-  general_lang_name: 'English (British)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: Account was successfully updated.
-  notice_account_invalid_creditentials: Invalid user or password
-  notice_account_password_updated: Password was successfully updated.
-  notice_account_wrong_password: Wrong password
-  notice_account_register_done: Account was successfully created. To activate your account, click on the link that was emailed to you.
-  notice_account_unknown_email: Unknown user.
-  notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
-  notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
-  notice_account_activated: Your account has been activated. You can now log in.
-  notice_successful_create: Successful creation.
-  notice_successful_update: Successful update.
-  notice_successful_delete: Successful deletion.
-  notice_successful_connection: Successful connection.
-  notice_file_not_found: The page you were trying to access doesn't exist or has been removed.
-  notice_locking_conflict: Data has been updated by another user.
-  notice_not_authorized: You are not authorised to access this page.
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  notice_email_sent: "An email was sent to %{value}"
-  notice_email_error: "An error occurred while sending mail (%{value})"
-  notice_feeds_access_key_reseted: Your RSS access key was reset.
-  notice_api_access_key_reseted: Your API access key was reset.
-  notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
-  notice_account_pending: "Your account was created and is now pending administrator approval."
-  notice_default_data_loaded: Default configuration successfully loaded.
-  notice_unable_delete_version: Unable to delete version.
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})"
-  
-  error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
-  error_scm_not_found: "The entry or revision was not found in the repository."
-  error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
-  error_scm_annotate: "The entry does not exist or cannot be annotated."
-  error_scm_annotate_big_text_file: "The entry cannot be annotated, as it exceeds the maximum text file size."
-  error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
-  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
-  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_can_not_delete_tracker: "This tracker contains issues and cannot be deleted."
-  error_can_not_remove_role: "This role is in use and cannot be deleted."
-  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version cannot be reopened'
-  error_can_not_archive_project: This project cannot be archived
-  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
-  error_workflow_copy_source: 'Please select a source tracker or role'
-  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
-  error_unable_delete_issue_status: 'Unable to delete issue status'
-  error_unable_to_connect: "Unable to connect (%{value})"
-  warning_attachments_not_saved: "%{count} file(s) could not be saved."
-  
-  mail_subject_lost_password: "Your %{value} password"
-  mail_body_lost_password: 'To change your password, click on the following link:'
-  mail_subject_register: "Your %{value} account activation"
-  mail_body_register: 'To activate your account, click on the following link:'
-  mail_body_account_information_external: "You can use your %{value} account to log in."
-  mail_body_account_information: Your account information
-  mail_subject_account_activation_request: "%{value} account activation request"
-  mail_body_account_activation_request: "A new user (%{value}) has registered. The account is pending your approval:"
-  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
-  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
-  
-  gui_validation_error: 1 error
-  gui_validation_error_plural: "%{count} errors"
-  
-  field_name: Name
-  field_description: Description
-  field_summary: Summary
-  field_is_required: Required
-  field_firstname: First name
-  field_lastname: Last name
-  field_mail: Email
-  field_filename: File
-  field_filesize: Size
-  field_downloads: Downloads
-  field_author: Author
-  field_created_on: Created
-  field_updated_on: Updated
-  field_field_format: Format
-  field_is_for_all: For all projects
-  field_possible_values: Possible values
-  field_regexp: Regular expression
-  field_min_length: Minimum length
-  field_max_length: Maximum length
-  field_value: Value
-  field_category: Category
-  field_title: Title
-  field_project: Project
-  field_issue: Issue
-  field_status: Status
-  field_notes: Notes
-  field_is_closed: Issue closed
-  field_is_default: Default value
-  field_tracker: Tracker
-  field_subject: Subject
-  field_due_date: Due date
-  field_assigned_to: Assignee
-  field_priority: Priority
-  field_fixed_version: Target version
-  field_user: User
-  field_principal: Principal
-  field_role: Role
-  field_homepage: Homepage
-  field_is_public: Public
-  field_parent: Subproject of
-  field_is_in_roadmap: Issues displayed in roadmap
-  field_login: Login
-  field_mail_notification: Email notifications
-  field_admin: Administrator
-  field_last_login_on: Last connection
-  field_language: Language
-  field_effective_date: Date
-  field_password: Password
-  field_new_password: New password
-  field_password_confirmation: Confirmation
-  field_version: Version
-  field_type: Type
-  field_host: Host
-  field_port: Port
-  field_account: Account
-  field_base_dn: Base DN
-  field_attr_login: Login attribute
-  field_attr_firstname: Firstname attribute
-  field_attr_lastname: Lastname attribute
-  field_attr_mail: Email attribute
-  field_onthefly: On-the-fly user creation
-  field_start_date: Start date
-  field_done_ratio: "% Done"
-  field_auth_source: Authentication mode
-  field_hide_mail: Hide my email address
-  field_comments: Comment
-  field_url: URL
-  field_start_page: Start page
-  field_subproject: Subproject
-  field_hours: Hours
-  field_activity: Activity
-  field_spent_on: Date
-  field_identifier: Identifier
-  field_is_filter: Used as a filter
-  field_issue_to: Related issue
-  field_delay: Delay
-  field_assignable: Issues can be assigned to this role
-  field_redirect_existing_links: Redirect existing links
-  field_estimated_hours: Estimated time
-  field_column_names: Columns
-  field_time_entries: Log time
-  field_time_zone: Time zone
-  field_searchable: Searchable
-  field_default_value: Default value
-  field_comments_sorting: Display comments
-  field_parent_title: Parent page
-  field_editable: Editable
-  field_watcher: Watcher
-  field_identity_url: OpenID URL
-  field_content: Content
-  field_group_by: Group results by
-  field_sharing: Sharing
-  field_parent_issue: Parent task
-  field_member_of_group: "Assignee's group"
-  field_assigned_to_role: "Assignee's role"
-  field_text: Text field
-  field_visible: Visible
-  field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text"
-  
-  setting_app_title: Application title
-  setting_app_subtitle: Application subtitle
-  setting_welcome_text: Welcome text
-  setting_default_language: Default language
-  setting_login_required: Authentication required
-  setting_self_registration: Self-registration
-  setting_attachment_max_size: Attachment max. size
-  setting_issues_export_limit: Issues export limit
-  setting_mail_from: Emission email address
-  setting_bcc_recipients: Blind carbon copy recipients (bcc)
-  setting_plain_text_mail: Plain text mail (no HTML)
-  setting_host_name: Host name and path
-  setting_text_formatting: Text formatting
-  setting_wiki_compression: Wiki history compression
-  setting_feeds_limit: Feed content limit
-  setting_default_projects_public: New projects are public by default
-  setting_autofetch_changesets: Autofetch commits
-  setting_sys_api_enabled: Enable WS for repository management
-  setting_commit_ref_keywords: Referencing keywords
-  setting_commit_fix_keywords: Fixing keywords
-  setting_autologin: Autologin
-  setting_date_format: Date format
-  setting_time_format: Time format
-  setting_cross_project_issue_relations: Allow cross-project issue relations
-  setting_issue_list_default_columns: Default columns displayed on the issue list
-  setting_emails_header: Emails header
-  setting_emails_footer: Emails footer
-  setting_protocol: Protocol
-  setting_per_page_options: Objects per page options
-  setting_user_format: Users display format
-  setting_activity_days_default: Days displayed on project activity
-  setting_display_subprojects_issues: Display subprojects issues on main projects by default
-  setting_enabled_scm: Enabled SCM
-  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
-  setting_mail_handler_api_enabled: Enable WS for incoming emails
-  setting_mail_handler_api_key: API key
-  setting_sequential_project_identifiers: Generate sequential project identifiers
-  setting_gravatar_enabled: Use Gravatar user icons
-  setting_gravatar_default: Default Gravatar image
-  setting_diff_max_lines_displayed: Max number of diff lines displayed
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_openid: Allow OpenID login and registration
-  setting_password_min_length: Minimum password length
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_field: Use the issue field
-  setting_issue_done_ratio_issue_status: Use the issue status
-  setting_start_of_week: Start calendars on
-  setting_rest_api_enabled: Enable REST web service
-  setting_cache_formatted_text: Cache formatted text
-  setting_default_notification_option: Default notification option
-  setting_commit_logtime_enabled: Enable time logging
-  setting_commit_logtime_activity_id: Activity for logged time
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  setting_issue_group_assignment: Allow issue assignment to groups
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-
-  permission_add_project: Create project
-  permission_add_subprojects: Create subprojects
-  permission_edit_project: Edit project
-  permission_select_project_modules: Select project modules
-  permission_manage_members: Manage members
-  permission_manage_project_activities: Manage project activities
-  permission_manage_versions: Manage versions
-  permission_manage_categories: Manage issue categories
-  permission_view_issues: View Issues
-  permission_add_issues: Add issues
-  permission_edit_issues: Edit issues
-  permission_manage_issue_relations: Manage issue relations
-  permission_add_issue_notes: Add notes
-  permission_edit_issue_notes: Edit notes
-  permission_edit_own_issue_notes: Edit own notes
-  permission_move_issues: Move issues
-  permission_delete_issues: Delete issues
-  permission_manage_public_queries: Manage public queries
-  permission_save_queries: Save queries
-  permission_view_gantt: View gantt chart
-  permission_view_calendar: View calendar
-  permission_view_issue_watchers: View watchers list
-  permission_add_issue_watchers: Add watchers
-  permission_delete_issue_watchers: Delete watchers
-  permission_log_time: Log spent time
-  permission_view_time_entries: View spent time
-  permission_edit_time_entries: Edit time logs
-  permission_edit_own_time_entries: Edit own time logs
-  permission_manage_news: Manage news
-  permission_comment_news: Comment news
-  permission_manage_documents: Manage documents
-  permission_view_documents: View documents
-  permission_manage_files: Manage files
-  permission_view_files: View files
-  permission_manage_wiki: Manage wiki
-  permission_rename_wiki_pages: Rename wiki pages
-  permission_delete_wiki_pages: Delete wiki pages
-  permission_view_wiki_pages: View wiki
-  permission_view_wiki_edits: View wiki history
-  permission_edit_wiki_pages: Edit wiki pages
-  permission_delete_wiki_pages_attachments: Delete attachments
-  permission_protect_wiki_pages: Protect wiki pages
-  permission_manage_repository: Manage repository
-  permission_browse_repository: Browse repository
-  permission_view_changesets: View changesets
-  permission_commit_access: Commit access
-  permission_manage_boards: Manage forums
-  permission_view_messages: View messages
-  permission_add_messages: Post messages
-  permission_edit_messages: Edit messages
-  permission_edit_own_messages: Edit own messages
-  permission_delete_messages: Delete messages
-  permission_delete_own_messages: Delete own messages
-  permission_export_wiki_pages: Export wiki pages
-  permission_manage_subtasks: Manage subtasks
-  
-  project_module_issue_tracking: Issue tracking
-  project_module_time_tracking: Time tracking
-  project_module_news: News
-  project_module_documents: Documents
-  project_module_files: Files
-  project_module_wiki: Wiki
-  project_module_repository: Repository
-  project_module_boards: Forums
-  project_module_calendar: Calendar
-  project_module_gantt: Gantt
-  
-  label_user: User
-  label_user_plural: Users
-  label_user_new: New user
-  label_user_anonymous: Anonymous
-  label_project: Project
-  label_project_new: New project
-  label_project_plural: Projects
-  label_x_projects:
-    zero:  no projects
-    one:   1 project
-    other: "%{count} projects"
-  label_project_all: All Projects
-  label_project_latest: Latest projects
-  label_issue: Issue
-  label_issue_new: New issue
-  label_issue_plural: Issues
-  label_issue_view_all: View all issues
-  label_issues_by: "Issues by %{value}"
-  label_issue_added: Issue added
-  label_issue_updated: Issue updated
-  label_document: Document
-  label_document_new: New document
-  label_document_plural: Documents
-  label_document_added: Document added
-  label_role: Role
-  label_role_plural: Roles
-  label_role_new: New role
-  label_role_and_permissions: Roles and permissions
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_member: Member
-  label_member_new: New member
-  label_member_plural: Members
-  label_tracker: Tracker
-  label_tracker_plural: Trackers
-  label_tracker_new: New tracker
-  label_workflow: Workflow
-  label_issue_status: Issue status
-  label_issue_status_plural: Issue statuses
-  label_issue_status_new: New status
-  label_issue_category: Issue category
-  label_issue_category_plural: Issue categories
-  label_issue_category_new: New category
-  label_custom_field: Custom field
-  label_custom_field_plural: Custom fields
-  label_custom_field_new: New custom field
-  label_enumerations: Enumerations
-  label_enumeration_new: New value
-  label_information: Information
-  label_information_plural: Information
-  label_please_login: Please log in
-  label_register: Register
-  label_login_with_open_id_option: or login with OpenID
-  label_password_lost: Lost password
-  label_home: Home
-  label_my_page: My page
-  label_my_account: My account
-  label_my_projects: My projects
-  label_my_page_block: My page block
-  label_administration: Administration
-  label_login: Sign in
-  label_logout: Sign out
-  label_help: Help
-  label_reported_issues: Reported issues
-  label_assigned_to_me_issues: Issues assigned to me
-  label_last_login: Last connection
-  label_registered_on: Registered on
-  label_activity: Activity
-  label_overall_activity: Overall activity
-  label_user_activity: "%{value}'s activity"
-  label_new: New
-  label_logged_as: Logged in as
-  label_environment: Environment
-  label_authentication: Authentication
-  label_auth_source: Authentication mode
-  label_auth_source_new: New authentication mode
-  label_auth_source_plural: Authentication modes
-  label_subproject_plural: Subprojects
-  label_subproject_new: New subproject
-  label_and_its_subprojects: "%{value} and its subprojects"
-  label_min_max_length: Min - Max length
-  label_list: List
-  label_date: Date
-  label_integer: Integer
-  label_float: Float
-  label_boolean: Boolean
-  label_string: Text
-  label_text: Long text
-  label_attribute: Attribute
-  label_attribute_plural: Attributes
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
-  label_no_data: No data to display
-  label_change_status: Change status
-  label_history: History
-  label_attachment: File
-  label_attachment_new: New file
-  label_attachment_delete: Delete file
-  label_attachment_plural: Files
-  label_file_added: File added
-  label_report: Report
-  label_report_plural: Reports
-  label_news: News
-  label_news_new: Add news
-  label_news_plural: News
-  label_news_latest: Latest news
-  label_news_view_all: View all news
-  label_news_added: News added
-  label_news_comment_added: Comment added to a news
-  label_settings: Settings
-  label_overview: Overview
-  label_version: Version
-  label_version_new: New version
-  label_version_plural: Versions
-  label_close_versions: Close completed versions
-  label_confirmation: Confirmation
-  label_export_to: 'Also available in:'
-  label_read: Read...
-  label_public_projects: Public projects
-  label_open_issues: open
-  label_open_issues_plural: open
-  label_closed_issues: closed
-  label_closed_issues_plural: closed
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_total: Total
-  label_permissions: Permissions
-  label_current_status: Current status
-  label_new_statuses_allowed: New statuses allowed
-  label_all: all
-  label_none: none
-  label_nobody: nobody
-  label_next: Next
-  label_previous: Previous
-  label_used_by: Used by
-  label_details: Details
-  label_add_note: Add a note
-  label_per_page: Per page
-  label_calendar: Calendar
-  label_months_from: months from
-  label_gantt: Gantt
-  label_internal: Internal
-  label_last_changes: "last %{count} changes"
-  label_change_view_all: View all changes
-  label_personalize_page: Personalise this page
-  label_comment: Comment
-  label_comment_plural: Comments
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_comment_add: Add a comment
-  label_comment_added: Comment added
-  label_comment_delete: Delete comments
-  label_query: Custom query
-  label_query_plural: Custom queries
-  label_query_new: New query
-  label_my_queries: My custom queries
-  label_filter_add: Add filter
-  label_filter_plural: Filters
-  label_equals: is
-  label_not_equals: is not
-  label_in_less_than: in less than
-  label_in_more_than: in more than
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: in
-  label_today: today
-  label_all_time: all time
-  label_yesterday: yesterday
-  label_this_week: this week
-  label_last_week: last week
-  label_last_n_days: "last %{count} days"
-  label_this_month: this month
-  label_last_month: last month
-  label_this_year: this year
-  label_date_range: Date range
-  label_less_than_ago: less than days ago
-  label_more_than_ago: more than days ago
-  label_ago: days ago
-  label_contains: contains
-  label_not_contains: doesn't contain
-  label_day_plural: days
-  label_repository: Repository
-  label_repository_plural: Repositories
-  label_browse: Browse
-  label_modification: "%{count} change"
-  label_modification_plural: "%{count} changes"
-  label_branch: Branch
-  label_tag: Tag 
-  label_revision: Revision
-  label_revision_plural: Revisions
-  label_revision_id: "Revision %{value}"
-  label_associated_revisions: Associated revisions
-  label_added: added
-  label_modified: modified
-  label_copied: copied
-  label_renamed: renamed
-  label_deleted: deleted
-  label_latest_revision: Latest revision
-  label_latest_revision_plural: Latest revisions
-  label_view_revisions: View revisions
-  label_view_all_revisions: View all revisions
-  label_max_size: Maximum size
-  label_sort_highest: Move to top
-  label_sort_higher: Move up
-  label_sort_lower: Move down
-  label_sort_lowest: Move to bottom
-  label_roadmap: Roadmap
-  label_roadmap_due_in: "Due in %{value}"
-  label_roadmap_overdue: "%{value} late"
-  label_roadmap_no_issues: No issues for this version
-  label_search: Search
-  label_result_plural: Results
-  label_all_words: All words
-  label_wiki: Wiki
-  label_wiki_edit: Wiki edit
-  label_wiki_edit_plural: Wiki edits
-  label_wiki_page: Wiki page
-  label_wiki_page_plural: Wiki pages
-  label_index_by_title: Index by title
-  label_index_by_date: Index by date
-  label_current_version: Current version
-  label_preview: Preview
-  label_feed_plural: Feeds
-  label_changes_details: Details of all changes
-  label_issue_tracking: Issue tracking
-  label_spent_time: Spent time
-  label_overall_spent_time: Overall spent time
-  label_f_hour: "%{value} hour"
-  label_f_hour_plural: "%{value} hours"
-  label_time_tracking: Time tracking
-  label_change_plural: Changes
-  label_statistics: Statistics
-  label_commits_per_month: Commits per month
-  label_commits_per_author: Commits per author
-  label_view_diff: View differences
-  label_diff_inline: inline
-  label_diff_side_by_side: side by side
-  label_options: Options
-  label_copy_workflow_from: Copy workflow from
-  label_permissions_report: Permissions report
-  label_watched_issues: Watched issues
-  label_related_issues: Related issues
-  label_applied_status: Applied status
-  label_loading: Loading...
-  label_relation_new: New relation
-  label_relation_delete: Delete relation
-  label_relates_to: related to
-  label_duplicates: duplicates
-  label_duplicated_by: duplicated by
-  label_blocks: blocks
-  label_blocked_by: blocked by
-  label_precedes: precedes
-  label_follows: follows
-  label_end_to_start: end to start
-  label_end_to_end: end to end
-  label_start_to_start: start to start
-  label_start_to_end: start to end
-  label_stay_logged_in: Stay logged in
-  label_disabled: disabled
-  label_show_completed_versions: Show completed versions
-  label_me: me
-  label_board: Forum
-  label_board_new: New forum
-  label_board_plural: Forums
-  label_board_locked: Locked
-  label_board_sticky: Sticky
-  label_topic_plural: Topics
-  label_message_plural: Messages
-  label_message_last: Last message
-  label_message_new: New message
-  label_message_posted: Message added
-  label_reply_plural: Replies
-  label_send_information: Send account information to the user
-  label_year: Year
-  label_month: Month
-  label_week: Week
-  label_date_from: From
-  label_date_to: To
-  label_language_based: Based on user's language
-  label_sort_by: "Sort by %{value}"
-  label_send_test_email: Send a test email
-  label_feeds_access_key: RSS access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  label_feeds_access_key_created_on: "RSS access key created %{value} ago"
-  label_module_plural: Modules
-  label_added_time_by: "Added by %{author} %{age} ago"
-  label_updated_time_by: "Updated by %{author} %{age} ago"
-  label_updated_time: "Updated %{value} ago"
-  label_jump_to_a_project: Jump to a project...
-  label_file_plural: Files
-  label_changeset_plural: Changesets
-  label_default_columns: Default columns
-  label_no_change_option: (No change)
-  label_bulk_edit_selected_issues: Bulk edit selected issues
-  label_theme: Theme
-  label_default: Default
-  label_search_titles_only: Search titles only
-  label_user_mail_option_all: "For any event on all my projects"
-  label_user_mail_option_selected: "For any event on the selected projects only..."
-  label_user_mail_option_none: "No events"
-  label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
-  label_user_mail_option_only_assigned: "Only for things I am assigned to"
-  label_user_mail_option_only_owner: "Only for things I am the owner of"
-  label_user_mail_no_self_notified: "I don't want to be notified of changes that I make myself"
-  label_registration_activation_by_email: account activation by email
-  label_registration_manual_activation: manual account activation
-  label_registration_automatic_activation: automatic account activation
-  label_display_per_page: "Per page: %{value}"
-  label_age: Age
-  label_change_properties: Change properties
-  label_general: General
-  label_more: More
-  label_scm: SCM
-  label_plugins: Plugins
-  label_ldap_authentication: LDAP authentication
-  label_downloads_abbr: D/L
-  label_optional_description: Optional description
-  label_add_another_file: Add another file
-  label_preferences: Preferences
-  label_chronological_order: In chronological order
-  label_reverse_chronological_order: In reverse chronological order
-  label_planning: Planning
-  label_incoming_emails: Incoming emails
-  label_generate_key: Generate a key
-  label_issue_watchers: Watchers
-  label_example: Example
-  label_display: Display
-  label_sort: Sort
-  label_ascending: Ascending
-  label_descending: Descending
-  label_date_from_to: From %{start} to %{end}
-  label_wiki_content_added: Wiki page added
-  label_wiki_content_updated: Wiki page updated
-  label_group: Group
-  label_group_plural: Groups
-  label_group_new: New group
-  label_time_entry_plural: Spent time
-  label_version_sharing_none: Not shared
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_tree: With project tree
-  label_version_sharing_system: With all projects
-  label_update_issue_done_ratios: Update issue done ratios
-  label_copy_source: Source
-  label_copy_target: Target
-  label_copy_same_as_target: Same as target
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_api_access_key: API access key
-  label_missing_api_access_key: Missing an API access key
-  label_api_access_key_created_on: "API access key created %{value} ago"
-  label_profile: Profile
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  
-  button_login: Login
-  button_submit: Submit
-  button_save: Save
-  button_check_all: Check all
-  button_uncheck_all: Uncheck all
-  button_collapse_all: Collapse all
-  button_expand_all: Expand all
-  button_delete: Delete
-  button_create: Create
-  button_create_and_continue: Create and continue
-  button_test: Test
-  button_edit: Edit
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  button_add: Add
-  button_change: Change
-  button_apply: Apply
-  button_clear: Clear
-  button_lock: Lock
-  button_unlock: Unlock
-  button_download: Download
-  button_list: List
-  button_view: View
-  button_move: Move
-  button_move_and_follow: Move and follow
-  button_back: Back
-  button_cancel: Cancel
-  button_activate: Activate
-  button_sort: Sort
-  button_log_time: Log time
-  button_rollback: Rollback to this version
-  button_watch: Watch
-  button_unwatch: Unwatch
-  button_reply: Reply
-  button_archive: Archive
-  button_unarchive: Unarchive
-  button_reset: Reset
-  button_rename: Rename
-  button_change_password: Change password
-  button_copy: Copy
-  button_copy_and_follow: Copy and follow
-  button_annotate: Annotate
-  button_update: Update
-  button_configure: Configure
-  button_quote: Quote
-  button_duplicate: Duplicate
-  button_show: Show
-  
-  status_active: active
-  status_registered: registered
-  status_locked: locked
-  
-  version_status_open: open
-  version_status_locked: locked
-  version_status_closed: closed
-
-  field_active: Active
-  
-  text_select_mail_notifications: Select actions for which email notifications should be sent.
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 means no restriction
-  text_project_destroy_confirmation: Are you sure you want to delete this project and related data?
-  text_subprojects_destroy_warning: "Its subproject(s): %{value} will be also deleted."
-  text_workflow_edit: Select a role and a tracker to edit the workflow
-  text_are_you_sure: Are you sure?
-  text_are_you_sure_with_children: "Delete issue and all child issues?"
-  text_journal_changed: "%{label} changed from %{old} to %{new}"
-  text_journal_changed_no_detail: "%{label} updated"
-  text_journal_set_to: "%{label} set to %{value}"
-  text_journal_deleted: "%{label} deleted (%{old})"
-  text_journal_added: "%{label} %{value} added"
-  text_tip_issue_begin_day: task beginning this day
-  text_tip_issue_end_day: task ending this day
-  text_tip_issue_begin_end_day: task beginning and ending this day
-  text_project_identifier_info: 'Only lower case letters (a-z), numbers and dashes are allowed.<br />Once saved, the identifier cannot be changed.'
-  text_caracters_maximum: "%{count} characters maximum."
-  text_caracters_minimum: "Must be at least %{count} characters long."
-  text_length_between: "Length between %{min} and %{max} characters."
-  text_tracker_no_workflow: No workflow defined for this tracker
-  text_unallowed_characters: Unallowed characters
-  text_comma_separated: Multiple values allowed (comma separated).
-  text_line_separated: Multiple values allowed (one line for each value).
-  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
-  text_issue_added: "Issue %{id} has been reported by %{author}."
-  text_issue_updated: "Issue %{id} has been updated by %{author}."
-  text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content?
-  text_issue_category_destroy_question: "Some issues (%{count}) are assigned to this category. What do you want to do?"
-  text_issue_category_destroy_assignments: Remove category assignments
-  text_issue_category_reassign_to: Reassign issues to this category
-  text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
-  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
-  text_load_default_configuration: Load the default configuration
-  text_status_changed_by_changeset: "Applied in changeset %{value}."
-  text_time_logged_by_changeset: "Applied in changeset %{value}."
-  text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?'
-  text_select_project_modules: 'Select modules to enable for this project:'
-  text_default_administrator_account_changed: Default administrator account changed
-  text_file_repository_writable: Attachments directory writable
-  text_plugin_assets_writable: Plugin assets directory writable
-  text_rmagick_available: RMagick available (optional)
-  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do?"
-  text_destroy_time_entries: Delete reported hours
-  text_assign_time_entries_to_project: Assign reported hours to the project
-  text_reassign_time_entries: 'Reassign reported hours to this issue:'
-  text_user_wrote: "%{value} wrote:"
-  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
-  text_enumeration_category_reassign_to: 'Reassign them to this value:'
-  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
-  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
-  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
-  text_custom_field_possible_values_info: 'One line for each value'
-  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
-  text_wiki_page_nullify_children: "Keep child pages as root pages"
-  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
-  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
-  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
-  text_zoom_in: Zoom in
-  text_zoom_out: Zoom out
-  text_warn_on_leaving_unsaved: "The current page contains unsaved text that will be lost if you leave this page."
-  
-  default_role_manager: Manager
-  default_role_developer: Developer
-  default_role_reporter: Reporter
-  default_tracker_bug: Bug
-  default_tracker_feature: Feature
-  default_tracker_support: Support
-  default_issue_status_new: New
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: Resolved
-  default_issue_status_feedback: Feedback
-  default_issue_status_closed: Closed
-  default_issue_status_rejected: Rejected
-  default_doc_category_user: User documentation
-  default_doc_category_tech: Technical documentation
-  default_priority_low: Low
-  default_priority_normal: Normal
-  default_priority_high: High
-  default_priority_urgent: Urgent
-  default_priority_immediate: Immediate
-  default_activity_design: Design
-  default_activity_development: Development
-  
-  enumeration_issue_priorities: Issue priorities
-  enumeration_doc_categories: Document categories
-  enumeration_activities: Activities (time tracking)
-  enumeration_system_activity: System Activity
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Commit messages encoding
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c6/c66377d22fe47ecd09af051b19c6f64432a147d3.svn-base
--- a/.svn/pristine/c6/c66377d22fe47ecd09af051b19c6f64432a147d3.svn-base
+++ /dev/null
@@ -1,1011 +0,0 @@
-# Redmine catalan translation: 
-# by Joan Duran
-
-ca:
-  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%d-%m-%Y"
-      short: "%e de %b"
-      long: "%a, %e de %b de %Y"
-      
-    day_names: [Diumenge, Dilluns, Dimarts, Dimecres, Dijous, Divendres, Dissabte]
-    abbr_day_names: [dg, dl, dt, dc, dj, dv, ds]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Gener, Febrer, MarÃ§, Abril, Maig, Juny, Juliol, Agost, Setembre, Octubre, Novembre, Desembre]
-    abbr_month_names: [~, Gen, Feb, Mar, Abr, Mai, Jun, Jul, Ago, Set, Oct, Nov, Des]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%d-%m-%Y %H:%M"
-      time: "%H:%M"
-      short: "%e de %b, %H:%M"
-      long: "%a, %e de %b de %Y, %H:%M"
-    am: "am"
-    pm: "pm"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "mig minut"
-      less_than_x_seconds:
-        one:   "menys d'un segon"
-        other: "menys de %{count} segons"
-      x_seconds:
-        one:   "1 segons"
-        other: "%{count} segons"
-      less_than_x_minutes:
-        one:   "menys d'un minut"
-        other: "menys de %{count} minuts"
-      x_minutes:
-        one:   "1 minut"
-        other: "%{count} minuts"
-      about_x_hours:
-        one:   "aproximadament 1 hora"
-        other: "aproximadament %{count} hores"
-      x_days:
-        one:   "1 dia"
-        other: "%{count} dies"
-      about_x_months:
-        one:   "aproximadament 1 mes"
-        other: "aproximadament %{count} mesos"
-      x_months:
-        one:   "1 mes"
-        other: "%{count} mesos"
-      about_x_years:
-        one:   "aproximadament 1 any"
-        other: "aproximadament %{count} anys"
-      over_x_years:
-        one:   "mÃ©s d'un any"
-        other: "mÃ©s de %{count} anys"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  number:
-    # Default format for numbers
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "i"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "no estÃ  inclÃ²s a la llista"
-        exclusion: "estÃ  reservat"
-        invalid: "no Ã©s vÃ lid"
-        confirmation: "la confirmaciÃ³ no coincideix"
-        accepted: "s'ha d'acceptar"
-        empty: "no pot estar buit"
-        blank: "no pot estar en blanc"
-        too_long: "Ã©s massa llarg"
-        too_short: "Ã©s massa curt"
-        wrong_length: "la longitud Ã©s incorrecta"
-        taken: "ja s'estÃ  utilitzant"
-        not_a_number: "no Ã©s un nÃºmero"
-        not_a_date: "no Ã©s una data vÃ lida"
-        greater_than: "ha de ser mÃ©s gran que %{count}"
-        greater_than_or_equal_to: "ha de ser mÃ©s gran o igual a %{count}"
-        equal_to: "ha de ser igual a %{count}"
-        less_than: "ha de ser menys que %{count}"
-        less_than_or_equal_to: "ha de ser menys o igual a %{count}"
-        odd: "ha de ser senar"
-        even: "ha de ser parell"
-        greater_than_start_date: "ha de ser superior que la data inicial"
-        not_same_project: "no pertany al mateix projecte"
-        circular_dependency: "Aquesta relaciÃ³ crearia una dependÃ¨ncia circular"
-        cant_link_an_issue_with_a_descendant: "Un assumpte no es pot enllaÃ§ar a una de les seves subtasques"
-
-  actionview_instancetag_blank_option: Seleccioneu
-  
-  general_text_No: 'No'
-  general_text_Yes: 'Si'
-  general_text_no: 'no'
-  general_text_yes: 'si'
-  general_lang_name: 'CatalÃ '
-  general_csv_separator: ';'
-  general_csv_decimal_separator: ','
-  general_csv_encoding: ISO-8859-15
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: "El compte s'ha actualitzat correctament."
-  notice_account_invalid_creditentials: Usuari o contrasenya invÃ lid
-  notice_account_password_updated: "La contrasenya s'ha modificat correctament."
-  notice_account_wrong_password: Contrasenya incorrecta
-  notice_account_register_done: "El compte s'ha creat correctament. Per a activar el compte, feu clic en l'enllaÃ§ que us han enviat per correu electrÃ²nic."
-  notice_account_unknown_email: Usuari desconegut.
-  notice_can_t_change_password: "Aquest compte utilitza una font d'autenticaciÃ³ externa. No Ã©s possible canviar la contrasenya."
-  notice_account_lost_email_sent: "S'ha enviat un correu electrÃ²nic amb instruccions per a seleccionar una contrasenya nova."
-  notice_account_activated: "El compte s'ha activat. Ara podeu entrar."
-  notice_successful_create: "S'ha creat correctament."
-  notice_successful_update: "S'ha modificat correctament."
-  notice_successful_delete: "S'ha suprimit correctament."
-  notice_successful_connection: "S'ha connectat correctament."
-  notice_file_not_found: "La pÃ gina a la que intenteu accedir no existeix o s'ha suprimit."
-  notice_locking_conflict: Un altre usuari ha actualitzat les dades.
-  notice_not_authorized: No teniu permÃ­s per a accedir a aquesta pÃ gina.
-  notice_email_sent: "S'ha enviat un correu electrÃ²nic a %{value}"
-  notice_email_error: "S'ha produÃ¯t un error en enviar el correu (%{value})"
-  notice_feeds_access_key_reseted: "S'ha reiniciat la clau d'accÃ©s del RSS."
-  notice_api_access_key_reseted: "S'ha reiniciat la clau d'accÃ©s a l'API."
-  notice_failed_to_save_issues: "No s'han pogut desar %{count} assumptes de %{total} seleccionats: %{ids}."
-  notice_failed_to_save_members: "No s'han pogut desar els membres: %{errors}."
-  notice_no_issue_selected: "No s'ha seleccionat cap assumpte. Activeu els assumptes que voleu editar."
-  notice_account_pending: "S'ha creat el compte i ara estÃ  pendent de l'aprovaciÃ³ de l'administrador."
-  notice_default_data_loaded: "S'ha carregat correctament la configuraciÃ³ predeterminada."
-  notice_unable_delete_version: "No s'ha pogut suprimir la versiÃ³."
-  notice_unable_delete_time_entry: "No s'ha pogut suprimir l'entrada del registre de temps."
-  notice_issue_done_ratios_updated: "S'ha actualitzat el tant per cent dels assumptes."
-  
-  error_can_t_load_default_data: "No s'ha pogut carregar la configuraciÃ³ predeterminada: %{value} "
-  error_scm_not_found: "No s'ha trobat l'entrada o la revisiÃ³ en el dipÃ²sit."
-  error_scm_command_failed: "S'ha produÃ¯t un error en intentar accedir al dipÃ²sit: %{value}"
-  error_scm_annotate: "L'entrada no existeix o no s'ha pogut anotar."
-  error_issue_not_found_in_project: "No s'ha trobat l'assumpte o no pertany a aquest projecte"
-  error_no_tracker_in_project: "Aquest projecte no tÃ© seguidor associat. Comproveu els parÃ metres del projecte."
-  error_no_default_issue_status: "No s'ha definit cap estat d'assumpte predeterminat. Comproveu la configuraciÃ³ (aneu a Â«AdministraciÃ³ -> Estats de l'assumpteÂ»)."
-  error_can_not_delete_custom_field: "No s'ha pogut suprimir el camp personalitat"
-  error_can_not_delete_tracker: "Aquest seguidor contÃ© assumptes i no es pot suprimir."
-  error_can_not_remove_role: "Aquest rol s'estÃ  utilitzant i no es pot suprimir."
-  error_can_not_reopen_issue_on_closed_version: "Un assumpte assignat a una versiÃ³ tancada no es pot tornar a obrir"
-  error_can_not_archive_project: "Aquest projecte no es pot arxivar"
-  error_issue_done_ratios_not_updated: "No s'ha actualitza el tant per cent dels assumptes."
-  error_workflow_copy_source: "Seleccioneu un seguidor o rol font"
-  error_workflow_copy_target: "Seleccioneu seguidors i rols objectiu"
-  error_unable_delete_issue_status: "No s'ha pogut suprimir l'estat de l'assumpte"
-  error_unable_to_connect: "No s'ha pogut connectar (%{value})"
-  warning_attachments_not_saved: "No s'han pogut desar %{count} fitxers."
-  
-  mail_subject_lost_password: "Contrasenya de %{value}"
-  mail_body_lost_password: "Per a canviar la contrasenya, feu clic en l'enllaÃ§ segÃ¼ent:"
-  mail_subject_register: "ActivaciÃ³ del compte de %{value}"
-  mail_body_register: "Per a activar el compte, feu clic en l'enllaÃ§ segÃ¼ent:"
-  mail_body_account_information_external: "Podeu utilitzar el compte Â«%{value}Â» per a entrar."
-  mail_body_account_information: InformaciÃ³ del compte
-  mail_subject_account_activation_request: "SolÂ·licitud d'activaciÃ³ del compte de %{value}"
-  mail_body_account_activation_request: "S'ha registrat un usuari nou (%{value}). El seu compte estÃ  pendent d'aprovaciÃ³:"
-  mail_subject_reminder: "%{count} assumptes venceran els segÃ¼ents %{days} dies"
-  mail_body_reminder: "%{count} assumptes que teniu assignades venceran els segÃ¼ents %{days} dies:"
-  mail_subject_wiki_content_added: "S'ha afegit la pÃ gina wiki Â«%{id}Â»"
-  mail_body_wiki_content_added: "En %{author} ha afegit la pÃ gina wiki Â«%{id}Â»."
-  mail_subject_wiki_content_updated: "S'ha actualitzat la pÃ gina wiki Â«%{id}Â»"
-  mail_body_wiki_content_updated: "En %{author} ha actualitzat la pÃ gina wiki Â«%{id}Â»."
-  
-  gui_validation_error: 1 error
-  gui_validation_error_plural: "%{count} errors"
-  
-  field_name: Nom
-  field_description: DescripciÃ³
-  field_summary: Resum
-  field_is_required: Necessari
-  field_firstname: Nom
-  field_lastname: Cognom
-  field_mail: Correu electrÃ²nic 
-  field_filename: Fitxer
-  field_filesize: Mida
-  field_downloads: Baixades
-  field_author: Autor
-  field_created_on: Creat
-  field_updated_on: Actualitzat
-  field_field_format: Format
-  field_is_for_all: Per a tots els projectes
-  field_possible_values: Valores possibles
-  field_regexp: ExpressiÃ³ regular
-  field_min_length: Longitud mÃ­nima
-  field_max_length: Longitud mÃ xima
-  field_value: Valor
-  field_category: Categoria
-  field_title: TÃ­tol
-  field_project: Projecte
-  field_issue: Assumpte
-  field_status: Estat
-  field_notes: Notes
-  field_is_closed: Assumpte tancat
-  field_is_default: Estat predeterminat
-  field_tracker: Seguidor
-  field_subject: Tema
-  field_due_date: Data de venciment
-  field_assigned_to: Assignat a
-  field_priority: Prioritat
-  field_fixed_version: VersiÃ³ objectiu
-  field_user: Usuari
-  field_principal: Principal
-  field_role: Rol
-  field_homepage: PÃ gina web
-  field_is_public: PÃºblic
-  field_parent: Subprojecte de
-  field_is_in_roadmap: Assumptes mostrats en la planificaciÃ³
-  field_login: Entrada
-  field_mail_notification: Notificacions per correu electrÃ²nic
-  field_admin: Administrador
-  field_last_login_on: Ãšltima connexiÃ³
-  field_language: Idioma
-  field_effective_date: Data
-  field_password: Contrasenya
-  field_new_password: Contrasenya nova
-  field_password_confirmation: ConfirmaciÃ³
-  field_version: VersiÃ³
-  field_type: Tipus
-  field_host: Ordinador
-  field_port: Port
-  field_account: Compte
-  field_base_dn: Base DN
-  field_attr_login: "Atribut d'entrada"
-  field_attr_firstname: Atribut del nom
-  field_attr_lastname: Atribut del cognom
-  field_attr_mail: Atribut del correu electrÃ²nic
-  field_onthefly: "CreaciÃ³ de l'usuari Â«al volÂ»"
-  field_start_date: Inici
-  field_done_ratio: "% realitzat"
-  field_auth_source: "Mode d'autenticaciÃ³"
-  field_hide_mail: "Oculta l'adreÃ§a de correu electrÃ²nic"
-  field_comments: Comentari
-  field_url: URL
-  field_start_page: PÃ gina inicial
-  field_subproject: Subprojecte
-  field_hours: Hores
-  field_activity: Activitat
-  field_spent_on: Data
-  field_identifier: Identificador
-  field_is_filter: "S'ha utilitzat com a filtre"
-  field_issue_to: Assumpte relacionat
-  field_delay: Retard
-  field_assignable: Es poden assignar assumptes a aquest rol
-  field_redirect_existing_links: Redirigeix els enllaÃ§os existents
-  field_estimated_hours: Temps previst
-  field_column_names: Columnes
-  field_time_entries: "Registre de temps"
-  field_time_zone: Zona horÃ ria
-  field_searchable: Es pot cercar
-  field_default_value: Valor predeterminat
-  field_comments_sorting: Mostra els comentaris
-  field_parent_title: PÃ gina pare
-  field_editable: Es pot editar
-  field_watcher: VigilÃ ncia
-  field_identity_url: URL OpenID
-  field_content: Contingut
-  field_group_by: "Agrupa els resultats per"
-  field_sharing: ComparticiÃ³
-  field_parent_issue: "Tasca pare"
-  
-  setting_app_title: "TÃ­tol de l'aplicaciÃ³"
-  setting_app_subtitle: "SubtÃ­tol de l'aplicaciÃ³"
-  setting_welcome_text: Text de benvinguda
-  setting_default_language: Idioma predeterminat
-  setting_login_required: Es necessita autenticaciÃ³
-  setting_self_registration: Registre automÃ tic
-  setting_attachment_max_size: Mida mÃ xima dels adjunts
-  setting_issues_export_limit: "LÃ­mit d'exportaciÃ³ d'assumptes"
-  setting_mail_from: "AdreÃ§a de correu electrÃ²nic d'emissiÃ³"
-  setting_bcc_recipients: Vincula els destinataris de les cÃ²pies amb carbÃ³ (bcc)
-  setting_plain_text_mail: nomÃ©s text pla (no HTML)
-  setting_host_name: "Nom de l'ordinador"
-  setting_text_formatting: Format del text
-  setting_wiki_compression: "Comprimeix l'historial del wiki"
-  setting_feeds_limit: LÃ­mit de contingut del canal
-  setting_default_projects_public: Els projectes nous sÃ³n pÃºblics per defecte
-  setting_autofetch_changesets: Omple automÃ ticament les publicacions
-  setting_sys_api_enabled: Habilita el WS per a la gestiÃ³ del dipÃ²sit
-  setting_commit_ref_keywords: Paraules claus per a la referÃ¨ncia
-  setting_commit_fix_keywords: Paraules claus per a la correcciÃ³
-  setting_autologin: Entrada automÃ tica
-  setting_date_format: Format de la data
-  setting_time_format: Format de hora
-  setting_cross_project_issue_relations: "Permet les relacions d'assumptes entre projectes"
-  setting_issue_list_default_columns: "Columnes mostrades per defecte en la llista d'assumptes"
-  setting_emails_footer: Peu dels correus electrÃ²nics
-  setting_protocol: Protocol
-  setting_per_page_options: Opcions dels objectes per pÃ gina
-  setting_user_format: "Format de com mostrar l'usuari"
-  setting_activity_days_default: "Dies a mostrar l'activitat del projecte"
-  setting_display_subprojects_issues: "Mostra els assumptes d'un subprojecte en el projecte pare per defecte"
-  setting_enabled_scm: "Habilita l'SCM"
-  setting_mail_handler_body_delimiters: "Trunca els correus electrÃ²nics desprÃ©s d'una d'aquestes lÃ­nies"
-  setting_mail_handler_api_enabled: "Habilita el WS per correus electrÃ²nics d'entrada"
-  setting_mail_handler_api_key: Clau API
-  setting_sequential_project_identifiers: Genera identificadors de projecte seqÃ¼encials
-  setting_gravatar_enabled: "Utilitza les icones d'usuari Gravatar"
-  setting_gravatar_default: "Imatge Gravatar predeterminada"
-  setting_diff_max_lines_displayed: NÃºmero mÃ xim de lÃ­nies amb diferÃ¨ncies mostrades
-  setting_file_max_size_displayed: Mida mÃ xima dels fitxers de text mostrats en lÃ­nia
-  setting_repository_log_display_limit: NÃºmero mÃ xim de revisions que es mostren al registre de fitxers
-  setting_openid: "Permet entrar i registrar-se amb l'OpenID"
-  setting_password_min_length: "Longitud mÃ­nima de la contrasenya"
-  setting_new_project_user_role_id: "Aquest rol es dÃ³na a un usuari no administrador per a crear projectes"
-  setting_default_projects_modules: "MÃ²duls activats per defecte en els projectes nous"
-  setting_issue_done_ratio: "Calcula tant per cent realitzat de l'assumpte amb"
-  setting_issue_done_ratio_issue_status: "Utilitza l'estat de l'assumpte"
-  setting_issue_done_ratio_issue_field: "Utilitza el camp de l'assumpte"
-  setting_start_of_week: "Inicia les setmanes en"
-  setting_rest_api_enabled: "Habilita el servei web REST"
-  setting_cache_formatted_text: Cache formatted text
-  
-  permission_add_project: "Crea projectes"
-  permission_add_subprojects: "Crea subprojectes"
-  permission_edit_project: Edita el projecte
-  permission_select_project_modules: Selecciona els mÃ²duls del projecte
-  permission_manage_members: Gestiona els membres
-  permission_manage_project_activities: "Gestiona les activitats del projecte"
-  permission_manage_versions: Gestiona les versions
-  permission_manage_categories: Gestiona les categories dels assumptes
-  permission_view_issues: "Visualitza els assumptes"
-  permission_add_issues: Afegeix assumptes
-  permission_edit_issues: Edita els assumptes
-  permission_manage_issue_relations: Gestiona les relacions dels assumptes
-  permission_add_issue_notes: Afegeix notes
-  permission_edit_issue_notes: Edita les notes
-  permission_edit_own_issue_notes: Edita les notes prÃ²pies
-  permission_move_issues: Mou els assumptes
-  permission_delete_issues: Suprimeix els assumptes
-  permission_manage_public_queries: Gestiona les consultes pÃºbliques
-  permission_save_queries: Desa les consultes
-  permission_view_gantt: Visualitza la grÃ fica de Gantt
-  permission_view_calendar: Visualitza el calendari
-  permission_view_issue_watchers: Visualitza la llista de vigilÃ ncies
-  permission_add_issue_watchers: Afegeix vigilÃ ncies
-  permission_delete_issue_watchers: Suprimeix els vigilants
-  permission_log_time: Registra el temps invertit
-  permission_view_time_entries: Visualitza el temps invertit
-  permission_edit_time_entries: Edita els registres de temps
-  permission_edit_own_time_entries: Edita els registres de temps propis
-  permission_manage_news: Gestiona les noticies
-  permission_comment_news: Comenta les noticies
-  permission_manage_documents: Gestiona els documents
-  permission_view_documents: Visualitza els documents
-  permission_manage_files: Gestiona els fitxers
-  permission_view_files: Visualitza els fitxers
-  permission_manage_wiki: Gestiona el wiki
-  permission_rename_wiki_pages: Canvia el nom de les pÃ gines wiki
-  permission_delete_wiki_pages: Suprimeix les pÃ gines wiki
-  permission_view_wiki_pages: Visualitza el wiki
-  permission_view_wiki_edits: "Visualitza l'historial del wiki"
-  permission_edit_wiki_pages: Edita les pÃ gines wiki
-  permission_delete_wiki_pages_attachments: Suprimeix adjunts
-  permission_protect_wiki_pages: Protegeix les pÃ gines wiki
-  permission_manage_repository: Gestiona el dipÃ²sit
-  permission_browse_repository: Navega pel dipÃ²sit
-  permission_view_changesets: Visualitza els canvis realitzats
-  permission_commit_access: AccÃ©s a les publicacions
-  permission_manage_boards: Gestiona els taulers
-  permission_view_messages: Visualitza els missatges
-  permission_add_messages: Envia missatges
-  permission_edit_messages: Edita els missatges
-  permission_edit_own_messages: Edita els missatges propis
-  permission_delete_messages: Suprimeix els missatges
-  permission_delete_own_messages: Suprimeix els missatges propis
-  permission_export_wiki_pages: "Exporta les pÃ gines wiki"
-  permission_manage_subtasks: "Gestiona subtasques"
-  
-  project_module_issue_tracking: "Seguidor d'assumptes"
-  project_module_time_tracking: Seguidor de temps
-  project_module_news: Noticies
-  project_module_documents: Documents
-  project_module_files: Fitxers
-  project_module_wiki: Wiki
-  project_module_repository: DipÃ²sit
-  project_module_boards: Taulers
-  project_module_calendar: Calendari
-  project_module_gantt: Gantt
-  
-  label_user: Usuari
-  label_user_plural: Usuaris
-  label_user_new: Usuari nou
-  label_user_anonymous: AnÃ²nim
-  label_project: Projecte
-  label_project_new: Projecte nou
-  label_project_plural: Projectes
-  label_x_projects:
-    zero:  cap projecte
-    one:   1 projecte
-    other: "%{count} projectes"
-  label_project_all: Tots els projectes
-  label_project_latest: Els Ãºltims projectes
-  label_issue: Assumpte
-  label_issue_new: Assumpte nou
-  label_issue_plural: Assumptes
-  label_issue_view_all: Visualitza tots els assumptes
-  label_issues_by: "Assumptes per %{value}"
-  label_issue_added: Assumpte afegit
-  label_issue_updated: Assumpte actualitzat
-  label_document: Document
-  label_document_new: Document nou
-  label_document_plural: Documents
-  label_document_added: Document afegit
-  label_role: Rol
-  label_role_plural: Rols
-  label_role_new: Rol nou
-  label_role_and_permissions: Rols i permisos
-  label_member: Membre
-  label_member_new: Membre nou
-  label_member_plural: Membres
-  label_tracker: Seguidor
-  label_tracker_plural: Seguidors
-  label_tracker_new: Seguidor nou
-  label_workflow: Flux de treball
-  label_issue_status: "Estat de l'assumpte"
-  label_issue_status_plural: "Estats de l'assumpte"
-  label_issue_status_new: Estat nou
-  label_issue_category: "Categoria de l'assumpte"
-  label_issue_category_plural: "Categories de l'assumpte"
-  label_issue_category_new: Categoria nova
-  label_custom_field: Camp personalitzat
-  label_custom_field_plural: Camps personalitzats
-  label_custom_field_new: Camp personalitzat nou
-  label_enumerations: Enumeracions
-  label_enumeration_new: Valor nou
-  label_information: InformaciÃ³
-  label_information_plural: InformaciÃ³
-  label_please_login: Entreu
-  label_register: Registre
-  label_login_with_open_id_option: "o entra amb l'OpenID"
-  label_password_lost: Contrasenya perduda
-  label_home: Inici
-  label_my_page: La meva pÃ gina
-  label_my_account: El meu compte
-  label_my_projects: Els meus projectes
-  label_my_page_block: "Els meus blocs de pÃ gina"
-  label_administration: AdministraciÃ³
-  label_login: Entra
-  label_logout: Surt
-  label_help: Ajuda
-  label_reported_issues: Assumptes informats
-  label_assigned_to_me_issues: Assumptes assignats a mi
-  label_last_login: Ãšltima connexiÃ³
-  label_registered_on: Informat el
-  label_activity: Activitat
-  label_overall_activity: Activitat global
-  label_user_activity: "Activitat de %{value}"
-  label_new: Nou
-  label_logged_as: Heu entrat com a
-  label_environment: Entorn
-  label_authentication: AutenticaciÃ³
-  label_auth_source: "Mode d'autenticaciÃ³"
-  label_auth_source_new: "Mode d'autenticaciÃ³ nou"
-  label_auth_source_plural: "Modes d'autenticaciÃ³"
-  label_subproject_plural: Subprojectes
-  label_subproject_new: "Subprojecte nou"
-  label_and_its_subprojects: "%{value} i els seus subprojectes"
-  label_min_max_length: Longitud mÃ­n - max
-  label_list: Llist
-  label_date: Data
-  label_integer: Enter
-  label_float: Flotant
-  label_boolean: BooleÃ 
-  label_string: Text
-  label_text: Text llarg
-  label_attribute: Atribut
-  label_attribute_plural: Atributs
-  label_download: "%{count} baixada"
-  label_download_plural: "%{count} baixades"
-  label_no_data: Sense dades a mostrar
-  label_change_status: "Canvia l'estat"
-  label_history: Historial
-  label_attachment: Fitxer
-  label_attachment_new: Fitxer nou
-  label_attachment_delete: Suprimeix el fitxer
-  label_attachment_plural: Fitxers
-  label_file_added: Fitxer afegit
-  label_report: Informe
-  label_report_plural: Informes
-  label_news: Noticies
-  label_news_new: Afegeix noticies
-  label_news_plural: Noticies
-  label_news_latest: Ãšltimes noticies
-  label_news_view_all: Visualitza totes les noticies
-  label_news_added: Noticies afegides
-  label_settings: ParÃ metres
-  label_overview: Resum
-  label_version: VersiÃ³
-  label_version_new: VersiÃ³ nova
-  label_version_plural: Versions
-  label_close_versions: "Tanca les versions completades"
-  label_confirmation: ConfirmaciÃ³
-  label_export_to: "TambÃ© disponible a:"
-  label_read: Llegeix...
-  label_public_projects: Projectes pÃºblics
-  label_open_issues: obert
-  label_open_issues_plural: oberts
-  label_closed_issues: tancat
-  label_closed_issues_plural: tancats
-  label_x_open_issues_abbr_on_total:
-    zero:  0 oberts / %{total}
-    one:   1 obert / %{total}
-    other: "%{count} oberts / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 oberts
-    one:   1 obert
-    other: "%{count} oberts"
-  label_x_closed_issues_abbr:
-    zero:  0 tancats
-    one:   1 tancat
-    other: "%{count} tancats"
-  label_total: Total
-  label_permissions: Permisos
-  label_current_status: Estat actual
-  label_new_statuses_allowed: Nous estats autoritzats
-  label_all: tots
-  label_none: cap
-  label_nobody: ningÃº
-  label_next: SegÃ¼ent
-  label_previous: Anterior
-  label_used_by: Utilitzat per
-  label_details: Detalls
-  label_add_note: Afegeix una nota
-  label_per_page: Per pÃ gina
-  label_calendar: Calendari
-  label_months_from: mesos des de
-  label_gantt: Gantt
-  label_internal: Intern
-  label_last_changes: "Ãºltims %{count} canvis"
-  label_change_view_all: Visualitza tots els canvis
-  label_personalize_page: Personalitza aquesta pÃ gina
-  label_comment: Comentari
-  label_comment_plural: Comentaris
-  label_x_comments:
-    zero: sense comentaris
-    one: 1 comentari
-    other: "%{count} comentaris"
-  label_comment_add: Afegeix un comentari
-  label_comment_added: Comentari afegit
-  label_comment_delete: Suprimeix comentaris
-  label_query: Consulta personalitzada
-  label_query_plural: Consultes personalitzades
-  label_query_new: Consulta nova
-  label_filter_add: Afegeix un filtre
-  label_filter_plural: Filtres
-  label_equals: Ã©s
-  label_not_equals: no Ã©s
-  label_in_less_than: en menys de
-  label_in_more_than: en mÃ©s de
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  label_in: en
-  label_today: avui
-  label_all_time: tot el temps
-  label_yesterday: ahir
-  label_this_week: aquesta setmana
-  label_last_week: "l'Ãºltima setmana"
-  label_last_n_days: "els Ãºltims %{count} dies"
-  label_this_month: aquest mÃ©s
-  label_last_month: "l'Ãºltim mÃ©s"
-  label_this_year: aquest any
-  label_date_range: Abast de les dates
-  label_less_than_ago: fa menys de
-  label_more_than_ago: fa mÃ©s de 
-  label_ago: fa
-  label_contains: contÃ©
-  label_not_contains: no contÃ©
-  label_day_plural: dies
-  label_repository: DipÃ²sit
-  label_repository_plural: DipÃ²sits
-  label_browse: Navega
-  label_modification: "%{count} canvi"
-  label_modification_plural: "%{count} canvis"
-  label_branch: Branca
-  label_tag: Etiqueta
-  label_revision: RevisiÃ³
-  label_revision_plural: Revisions
-  label_revision_id: "RevisiÃ³ %{value}"
-  label_associated_revisions: Revisions associades
-  label_added: afegit
-  label_modified: modificat
-  label_copied: copiat
-  label_renamed: reanomenat
-  label_deleted: suprimit
-  label_latest_revision: Ãšltima revisiÃ³
-  label_latest_revision_plural: Ãšltimes revisions
-  label_view_revisions: Visualitza les revisions
-  label_view_all_revisions: "Visualitza totes les revisions"
-  label_max_size: Mida mÃ xima
-  label_sort_highest: Mou a la part superior
-  label_sort_higher: Mou cap amunt
-  label_sort_lower: Mou cap avall
-  label_sort_lowest: Mou a la part inferior
-  label_roadmap: PlanificaciÃ³
-  label_roadmap_due_in: "VenÃ§ en %{value}"
-  label_roadmap_overdue: "%{value} tard"
-  label_roadmap_no_issues: No hi ha assumptes per a aquesta versiÃ³
-  label_search: Cerca
-  label_result_plural: Resultats
-  label_all_words: Totes les paraules
-  label_wiki: Wiki
-  label_wiki_edit: EdiciÃ³ wiki
-  label_wiki_edit_plural: Edicions wiki
-  label_wiki_page: PÃ gina wiki
-  label_wiki_page_plural: PÃ gines wiki
-  label_index_by_title: Ãndex per tÃ­tol
-  label_index_by_date: Ãndex per data
-  label_current_version: VersiÃ³ actual
-  label_preview: PrevisualitzaciÃ³
-  label_feed_plural: Canals
-  label_changes_details: Detalls de tots els canvis
-  label_issue_tracking: "Seguiment d'assumptes"
-  label_spent_time: Temps invertit
-  label_overall_spent_time: "Temps total invertit"
-  label_f_hour: "%{value} hora"
-  label_f_hour_plural: "%{value} hores"
-  label_time_tracking: Temps de seguiment
-  label_change_plural: Canvis
-  label_statistics: EstadÃ­stiques
-  label_commits_per_month: Publicacions per mes
-  label_commits_per_author: Publicacions per autor
-  label_view_diff: Visualitza les diferÃ¨ncies
-  label_diff_inline: en lÃ­nia
-  label_diff_side_by_side: costat per costat
-  label_options: Opcions
-  label_copy_workflow_from: Copia el flux de treball des de
-  label_permissions_report: Informe de permisos
-  label_watched_issues: Assumptes vigilats
-  label_related_issues: Assumptes relacionats
-  label_applied_status: Estat aplicat
-  label_loading: "S'estÃ  carregant..."
-  label_relation_new: RelaciÃ³ nova
-  label_relation_delete: Suprimeix la relaciÃ³
-  label_relates_to: relacionat amb
-  label_duplicates: duplicats
-  label_duplicated_by: duplicat per
-  label_blocks: bloqueja
-  label_blocked_by: bloquejats per
-  label_precedes: anterior a
-  label_follows: posterior a
-  label_end_to_start: final al comenÃ§ament
-  label_end_to_end: final al final
-  label_start_to_start: comenÃ§ament al comenÃ§ament
-  label_start_to_end: comenÃ§ament al final
-  label_stay_logged_in: "MantÃ© l'entrada"
-  label_disabled: inhabilitat
-  label_show_completed_versions: Mostra les versions completes
-  label_me: jo mateix
-  label_board: FÃ²rum
-  label_board_new: FÃ²rum nou
-  label_board_plural: FÃ²rums
-  label_board_locked: Bloquejat
-  label_board_sticky: Sticky
-  label_topic_plural: Temes
-  label_message_plural: Missatges
-  label_message_last: Ãšltim missatge
-  label_message_new: Missatge nou
-  label_message_posted: Missatge afegit
-  label_reply_plural: Respostes
-  label_send_information: "Envia la informaciÃ³ del compte a l'usuari"
-  label_year: Any
-  label_month: Mes
-  label_week: Setmana
-  label_date_from: Des de
-  label_date_to: A
-  label_language_based: "Basat en l'idioma de l'usuari"
-  label_sort_by: "Ordena per %{value}"
-  label_send_test_email: Envia un correu electrÃ²nic de prova
-  label_feeds_access_key: "Clau d'accÃ©s del RSS"
-  label_missing_feeds_access_key: "Falta una clau d'accÃ©s del RSS"
-  label_feeds_access_key_created_on: "Clau d'accÃ©s del RSS creada fa %{value}"
-  label_module_plural: MÃ²duls
-  label_added_time_by: "Afegit per %{author} fa %{age}"
-  label_updated_time_by: "Actualitzat per %{author} fa %{age}"
-  label_updated_time: "Actualitzat fa %{value}"
-  label_jump_to_a_project: Salta al projecte...
-  label_file_plural: Fitxers
-  label_changeset_plural: Conjunt de canvis
-  label_default_columns: Columnes predeterminades
-  label_no_change_option: (sense canvis)
-  label_bulk_edit_selected_issues: Edita en bloc els assumptes seleccionats
-  label_theme: Tema
-  label_default: Predeterminat
-  label_search_titles_only: Cerca nomÃ©s en els tÃ­tols
-  label_user_mail_option_all: "Per qualsevol esdeveniment en tots els meus projectes"
-  label_user_mail_option_selected: "Per qualsevol esdeveniment en els projectes seleccionats..."
-  label_user_mail_no_self_notified: "No vull ser notificat pels canvis que faig jo mateix"
-  label_registration_activation_by_email: activaciÃ³ del compte per correu electrÃ²nic
-  label_registration_manual_activation: activaciÃ³ del compte manual
-  label_registration_automatic_activation: activaciÃ³ del compte automÃ tica
-  label_display_per_page: "Per pÃ gina: %{value}"
-  label_age: Edat
-  label_change_properties: Canvia les propietats
-  label_general: General
-  label_more: MÃ©s
-  label_scm: SCM
-  label_plugins: Connectors
-  label_ldap_authentication: AutenticaciÃ³ LDAP
-  label_downloads_abbr: Baixades
-  label_optional_description: DescripciÃ³ opcional
-  label_add_another_file: Afegeix un altre fitxer
-  label_preferences: PreferÃ¨ncies
-  label_chronological_order: En ordre cronolÃ²gic
-  label_reverse_chronological_order: En ordre cronolÃ²gic invers
-  label_planning: PlanificaciÃ³
-  label_incoming_emails: "Correu electrÃ²nics d'entrada"
-  label_generate_key: Genera una clau
-  label_issue_watchers: VigilÃ ncies
-  label_example: Exemple
-  label_display: Mostra
-  label_sort: Ordena
-  label_ascending: Ascendent
-  label_descending: Descendent
-  label_date_from_to: Des de %{start} a %{end}
-  label_wiki_content_added: "S'ha afegit la pÃ gina wiki"
-  label_wiki_content_updated: "S'ha actualitzat la pÃ gina wiki"
-  label_group: Grup
-  label_group_plural: Grups
-  label_group_new: Grup nou
-  label_time_entry_plural: Temps invertit
-  label_version_sharing_hierarchy: "Amb la jerarquia del projecte"
-  label_version_sharing_system: "Amb tots els projectes"
-  label_version_sharing_descendants: "Amb tots els subprojectes"
-  label_version_sharing_tree: "Amb l'arbre del projecte"
-  label_version_sharing_none: "Sense compartir"
-  label_update_issue_done_ratios: "Actualitza el tant per cent dels assumptes realitzats"
-  label_copy_source: Font
-  label_copy_target: Objectiu
-  label_copy_same_as_target: "El mateix que l'objectiu"
-  label_display_used_statuses_only: "Mostra nomÃ©s els estats que utilitza aquest seguidor"
-  label_api_access_key: "Clau d'accÃ©s a l'API"
-  label_missing_api_access_key: "Falta una clau d'accÃ©s de l'API"
-  label_api_access_key_created_on: "Clau d'accÃ©s de l'API creada fa %{value}"
-  label_profile: Perfil
-  label_subtask_plural: Subtasques
-  label_project_copy_notifications: "Envia notificacions de correu electrÃ²nic durant la cÃ²pia del projecte"
-  
-  button_login: Entra
-  button_submit: Tramet
-  button_save: Desa
-  button_check_all: Activa-ho tot
-  button_uncheck_all: Desactiva-ho tot
-  button_delete: Suprimeix
-  button_create: Crea
-  button_create_and_continue: Crea i continua
-  button_test: Test
-  button_edit: Edit
-  button_add: Afegeix
-  button_change: Canvia
-  button_apply: Aplica
-  button_clear: Neteja
-  button_lock: Bloca
-  button_unlock: Desbloca
-  button_download: Baixa
-  button_list: Llista
-  button_view: Visualitza
-  button_move: Mou
-  button_move_and_follow: "Mou i segueix"
-  button_back: Enrere
-  button_cancel: CancelÂ·la
-  button_activate: Activa
-  button_sort: Ordena
-  button_log_time: "Registre de temps"
-  button_rollback: Torna a aquesta versiÃ³
-  button_watch: Vigila
-  button_unwatch: No vigilis
-  button_reply: Resposta
-  button_archive: Arxiva
-  button_unarchive: Desarxiva
-  button_reset: Reinicia
-  button_rename: Reanomena
-  button_change_password: Canvia la contrasenya
-  button_copy: Copia
-  button_copy_and_follow: "Copia i segueix"
-  button_annotate: Anota
-  button_update: Actualitza
-  button_configure: Configura
-  button_quote: Cita
-  button_duplicate: Duplica
-  button_show: Mostra
-  
-  status_active: actiu
-  status_registered: informat
-  status_locked: bloquejat
-  
-  version_status_open: oberta
-  version_status_locked: bloquejada
-  version_status_closed: tancada
-
-  field_active: Actiu
-  
-  text_select_mail_notifications: "Seleccioneu les accions per les quals s'hauria d'enviar una notificaciÃ³ per correu electrÃ²nic."
-  text_regexp_info: ex. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 significa sense restricciÃ³
-  text_project_destroy_confirmation: Segur que voleu suprimir aquest projecte i les dades relacionades?
-  text_subprojects_destroy_warning: "TambÃ© seran suprimits els seus subprojectes: %{value}."
-  text_workflow_edit: Seleccioneu un rol i un seguidor per a editar el flux de treball
-  text_are_you_sure: Segur?
-  text_journal_changed: "%{label} ha canviat de %{old} a %{new}"
-  text_journal_set_to: "%{label} s'ha establert a %{value}"
-  text_journal_deleted: "%{label} s'ha suprimit (%{old})"
-  text_journal_added: "S'ha afegit %{label} %{value}"
-  text_tip_issue_begin_day: "tasca que s'inicia aquest dia"
-  text_tip_issue_end_day: tasca que finalitza aquest dia
-  text_tip_issue_begin_end_day: "tasca que s'inicia i finalitza aquest dia"
-  text_project_identifier_info: "Es permeten lletres en minÃºscules (a-z), nÃºmeros i guions.<br />Un cop desat, l'identificador no es pot modificar."
-  text_caracters_maximum: "%{count} carÃ cters com a mÃ xim."
-  text_caracters_minimum: "Com a mÃ­nim ha de tenir %{count} carÃ cters."
-  text_length_between: "Longitud entre %{min} i %{max} carÃ cters."
-  text_tracker_no_workflow: "No s'ha definit cap flux de treball per a aquest seguidor"
-  text_unallowed_characters: CarÃ cters no permesos
-  text_comma_separated: Es permeten valors mÃºltiples (separats per una coma).
-  text_line_separated: "Es permeten diversos valors (una lÃ­nia per cada valor)."
-  text_issues_ref_in_commit_messages: ReferÃ¨ncia i soluciona els assumptes en els missatges publicats
-  text_issue_added: "L'assumpte %{id} ha sigut informat per %{author}."
-  text_issue_updated: "L'assumpte %{id} ha sigut actualitzat per %{author}."
-  text_wiki_destroy_confirmation: Segur que voleu suprimir aquest wiki i tots els seus continguts?
-  text_issue_category_destroy_question: "Alguns assumptes (%{count}) estan assignats a aquesta categoria. QuÃ¨ voleu fer?"
-  text_issue_category_destroy_assignments: Suprimeix les assignacions de la categoria
-  text_issue_category_reassign_to: Torna a assignar els assumptes a aquesta categoria
-  text_user_mail_option: "Per als projectes no seleccionats, nomÃ©s rebreu notificacions sobre les coses que vigileu o que hi esteu implicat (ex. assumptes que en sou l'autor o hi esteu assignat)."
-  text_no_configuration_data: "Encara no s'han configurat els rols, seguidors, estats de l'assumpte i flux de treball.\nÃ‰s altament recomanable que carregueu la configuraciÃ³ predeterminada. Podreu modificar-la un cop carregada."
-  text_load_default_configuration: Carrega la configuraciÃ³ predeterminada
-  text_status_changed_by_changeset: "Aplicat en el conjunt de canvis %{value}."
-  text_issues_destroy_confirmation: "Segur que voleu suprimir els assumptes seleccionats?"
-  text_select_project_modules: "Seleccioneu els mÃ²duls a habilitar per a aquest projecte:"
-  text_default_administrator_account_changed: "S'ha canviat el compte d'administrador predeterminat"
-  text_file_repository_writable: Es pot escriure en el dipÃ²sit de fitxers
-  text_plugin_assets_writable: Es pot escriure als connectors actius
-  text_rmagick_available: RMagick disponible (opcional)
-  text_destroy_time_entries_question: "S'han informat %{hours} hores en els assumptes que aneu a suprimir. QuÃ¨ voleu fer?"
-  text_destroy_time_entries: Suprimeix les hores informades
-  text_assign_time_entries_to_project: Assigna les hores informades al projecte
-  text_reassign_time_entries: "Torna a assignar les hores informades a aquest assumpte:"
-  text_user_wrote: "%{value} va escriure:"
-  text_enumeration_destroy_question: "%{count} objectes estan assignats a aquest valor."
-  text_enumeration_category_reassign_to: "Torna a assignar-los a aquest valor:"
-  text_email_delivery_not_configured: "El lliurament per correu electrÃ²nic no estÃ  configurat i les notificacions estan inhabilitades.\nConfigureu el servidor SMTP a config/configuration.yml i reinicieu l'aplicaciÃ³ per habilitar-lo."
-  text_repository_usernames_mapping: "Seleccioneu l'assignaciÃ³ entre els usuaris del Redmine i cada nom d'usuari trobat al dipÃ²sit.\nEls usuaris amb el mateix nom d'usuari o correu del Redmine i del dipÃ²sit s'assignaran automÃ ticament."
-  text_diff_truncated: "... Aquestes diferÃ¨ncies s'han trucat perquÃ¨ excedeixen la mida mÃ xima que es pot mostrar."
-  text_custom_field_possible_values_info: "Una lÃ­nia per a cada valor"
-  text_wiki_page_destroy_question: "Aquesta pÃ gina tÃ© %{descendants} pÃ gines fill i descendents. QuÃ¨ voleu fer?"
-  text_wiki_page_nullify_children: "Deixa les pÃ gines fill com a pÃ gines arrel"
-  text_wiki_page_destroy_children: "Suprimeix les pÃ gines fill i tots els seus descendents"
-  text_wiki_page_reassign_children: "Reasigna les pÃ gines fill a aquesta pÃ gina pare"
-  text_own_membership_delete_confirmation: "Esteu a punt de suprimir algun o tots els vostres permisos i potser no podreu editar mÃ©s aquest projecte.\nSegur que voleu continuar?"
-  text_zoom_in: Redueix
-  text_zoom_out: Amplia
-  
-  default_role_manager: Gestor
-  default_role_developer: Desenvolupador
-  default_role_reporter: Informador
-  default_tracker_bug: Error
-  default_tracker_feature: CaracterÃ­stica
-  default_tracker_support: Suport
-  default_issue_status_new: Nou
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: Resolt
-  default_issue_status_feedback: Comentaris
-  default_issue_status_closed: Tancat
-  default_issue_status_rejected: Rebutjat
-  default_doc_category_user: "DocumentaciÃ³ d'usuari"
-  default_doc_category_tech: DocumentaciÃ³ tÃ¨cnica
-  default_priority_low: Baixa
-  default_priority_normal: Normal
-  default_priority_high: Alta
-  default_priority_urgent: Urgent
-  default_priority_immediate: Immediata
-  default_activity_design: Disseny
-  default_activity_development: Desenvolupament
-  
-  enumeration_issue_priorities: Prioritat dels assumptes
-  enumeration_doc_categories: Categories del document
-  enumeration_activities: Activitats (seguidor de temps)
-  enumeration_system_activity: Activitat del sistema
-
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: CodificaciÃ³ dels missatges publicats
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c6/c66d3b3ac719b98649d62296e3f91aca262abec6.svn-base
Binary file .svn/pristine/c6/c66d3b3ac719b98649d62296e3f91aca262abec6.svn-base has changed
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c6/c670b46ea2087eed9b8431a525368aa41fa88c54.svn-base
--- /dev/null
+++ b/.svn/pristine/c6/c670b46ea2087eed9b8431a525368aa41fa88c54.svn-base
@@ -0,0 +1,148 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'zlib'
+
+class WikiContent < ActiveRecord::Base
+  self.locking_column = 'version'
+  belongs_to :page, :class_name => 'WikiPage', :foreign_key => 'page_id'
+  belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
+  validates_presence_of :text
+  validates_length_of :comments, :maximum => 255, :allow_nil => true
+
+  acts_as_versioned
+
+  def visible?(user=User.current)
+    page.visible?(user)
+  end
+
+  def project
+    page.project
+  end
+
+  def attachments
+    page.nil? ? [] : page.attachments
+  end
+
+  # Returns the mail adresses of users that should be notified
+  def recipients
+    notified = project.notified_users
+    notified.reject! {|user| !visible?(user)}
+    notified.collect(&:mail)
+  end
+
+  # Return true if the content is the current page content
+  def current_version?
+    true
+  end
+
+  class Version
+    belongs_to :page, :class_name => '::WikiPage', :foreign_key => 'page_id'
+    belongs_to :author, :class_name => '::User', :foreign_key => 'author_id'
+    attr_protected :data
+
+    acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"},
+                  :description => :comments,
+                  :datetime => :updated_on,
+                  :type => 'wiki-page',
+                  :group => :page,
+                  :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.page.wiki.project, :id => o.page.title, :version => o.version}}
+
+    acts_as_activity_provider :type => 'wiki_edits',
+                              :timestamp => "#{WikiContent.versioned_table_name}.updated_on",
+                              :author_key => "#{WikiContent.versioned_table_name}.author_id",
+                              :permission => :view_wiki_edits,
+                              :find_options => {:select => "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
+                                                           "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
+                                                           "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
+                                                           "#{WikiContent.versioned_table_name}.id",
+                                                :joins => "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
+                                                          "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
+                                                          "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"}
+
+    after_destroy :page_update_after_destroy
+
+    def text=(plain)
+      case Setting.wiki_compression
+      when 'gzip'
+      begin
+        self.data = Zlib::Deflate.deflate(plain, Zlib::BEST_COMPRESSION)
+        self.compression = 'gzip'
+      rescue
+        self.data = plain
+        self.compression = ''
+      end
+      else
+        self.data = plain
+        self.compression = ''
+      end
+      plain
+    end
+
+    def text
+      @text ||= begin
+        str = case compression
+              when 'gzip'
+                Zlib::Inflate.inflate(data)
+              else
+                # uncompressed data
+                data
+              end
+        str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
+        str
+      end
+    end
+
+    def project
+      page.project
+    end
+
+    # Return true if the content is the current page content
+    def current_version?
+      page.content.version == self.version
+    end
+
+    # Returns the previous version or nil
+    def previous
+      @previous ||= WikiContent::Version.
+        reorder('version DESC').
+        includes(:author).
+        where("wiki_content_id = ? AND version < ?", wiki_content_id, version).first
+    end
+
+    # Returns the next version or nil
+    def next
+      @next ||= WikiContent::Version.
+        reorder('version ASC').
+        includes(:author).
+        where("wiki_content_id = ? AND version > ?", wiki_content_id, version).first
+    end
+
+    private
+
+    # Updates page's content if the latest version is removed
+    # or destroys the page if it was the only version
+    def page_update_after_destroy
+      latest = page.content.versions.reorder("#{self.class.table_name}.version DESC").first
+      if latest && page.content.version != latest.version
+        raise ActiveRecord::Rollback unless page.content.revert_to!(latest)
+      elsif latest.nil?
+        raise ActiveRecord::Rollback unless page.destroy
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c6/c67df8f4061dcb392af7b61e6af1469235ed0229.svn-base
--- a/.svn/pristine/c6/c67df8f4061dcb392af7b61e6af1469235ed0229.svn-base
+++ /dev/null
@@ -1,1038 +0,0 @@
-# Japanese translations for Ruby on Rails
-# by Akira Matsuda (ronnie@dio.jp)
-# AR error messages are basically taken from Ruby-GetText-Package. Thanks to Masao Mutoh.
-
-ja:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y/%m/%d"
-      short: "%m/%d"
-      long: "%Yå¹´%mæœˆ%dæ—¥(%a)"
-
-    day_names: [æ—¥æ›œæ—¥, æœˆæ›œæ—¥, ç«æ›œæ—¥, æ°´æ›œæ—¥, æœ¨æ›œæ—¥, é‡‘æ›œæ—¥, åœŸæ›œæ—¥]
-    abbr_day_names: [æ—¥, æœˆ, ç«, æ°´, æœ¨, é‡‘, åœŸ]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, 1æœˆ, 2æœˆ, 3æœˆ, 4æœˆ, 5æœˆ, 6æœˆ, 7æœˆ, 8æœˆ, 9æœˆ, 10æœˆ, 11æœˆ, 12æœˆ]
-    abbr_month_names: [~, 1æœˆ, 2æœˆ, 3æœˆ, 4æœˆ, 5æœˆ, 6æœˆ, 7æœˆ, 8æœˆ, 9æœˆ, 10æœˆ, 11æœˆ, 12æœˆ]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%Y/%m/%d %H:%M:%S"
-      time: "%H:%M"
-      short: "%y/%m/%d %H:%M"
-      long: "%Yå¹´%mæœˆ%dæ—¥(%a) %Hæ™‚%Måˆ†%Sç§’ %Z"
-    am: "åˆå‰"
-    pm: "åˆå¾Œ"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "30ç§’å‰å¾Œ"
-      less_than_x_seconds:
-        one:   "1ç§’ä»¥å†…"
-        other: "%{count}ç§’ä»¥å†…"
-      x_seconds:
-        one:   "1ç§’"
-        other: "%{count}ç§’"
-      less_than_x_minutes:
-        one:   "1åˆ†ä»¥å†…"
-        other: "%{count}åˆ†ä»¥å†…"
-      x_minutes:
-        one:   "1åˆ†"
-        other: "%{count}åˆ†"
-      about_x_hours:
-        one:   "ç´„1æ™‚é–“"
-        other: "ç´„%{count}æ™‚é–“"
-      x_days:
-        one:   "1æ—¥"
-        other: "%{count}æ—¥"
-      about_x_months:
-        one:   "ç´„1ãƒ¶æœˆ"
-        other: "ç´„%{count}ãƒ¶æœˆ"
-      x_months:
-        one:   "1ãƒ¶æœˆ"
-        other: "%{count}ãƒ¶æœˆ"
-      about_x_years:
-        one:   "ç´„1å¹´"
-        other: "ç´„%{count}å¹´"
-      over_x_years:
-        one:   "1å¹´ä»¥ä¸Š"
-        other: "%{count}å¹´ä»¥ä¸Š"
-      almost_x_years:
-        one:   "ã»ã¼1å¹´"
-        other: "ã»ã¼%{count}å¹´"
-
-  number:
-    format:
-      separator: "."
-      delimiter: ","
-      precision: 3
-
-    currency:
-      format:
-        format: "%n%u"
-        unit: "å††"
-        separator: "."
-        delimiter: ","
-        precision: 0
-
-    percentage:
-      format:
-        delimiter: ""
-
-    precision:
-      format:
-        delimiter: ""
-
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "åŠã³"
-      skip_last_comma: true
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:   "%{model} ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
-          other: "%{model} ã« %{count} ã¤ã®ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
-        body: "æ¬¡ã®é …ç›®ã‚’ç¢ºèªã—ã¦ãã ã•ã„ã€‚"
-
-      messages:
-        inclusion: "ã¯ä¸€è¦§ã«ã‚ã‚Šã¾ã›ã‚“ã€‚"
-        exclusion: "ã¯äºˆç´„ã•ã‚Œã¦ã„ã¾ã™ã€‚"
-        invalid: "ã¯ä¸æ­£ãªå€¤ã§ã™ã€‚"
-        confirmation: "ãŒä¸€è‡´ã—ã¾ã›ã‚“ã€‚"
-        accepted: "ã‚’å—è«¾ã—ã¦ãã ã•ã„ã€‚"
-        empty: "ã‚’å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
-        blank: "ã‚’å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
-        too_long: "ã¯%{count}æ–‡å­—ä»¥å†…ã§å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
-        too_short: "ã¯%{count}æ–‡å­—ä»¥ä¸Šã§å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
-        wrong_length: "ã¯%{count}æ–‡å­—ã§å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
-        taken: "ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚"
-        not_a_number: "ã¯æ•°å€¤ã§å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
-        not_a_date: "ã¯æ—¥ä»˜ã‚’å…¥åŠ›ã—ã¦ãã ã•ã„ã€‚"
-        greater_than: "ã¯%{count}ã‚ˆã‚Šå¤§ãã„å€¤ã«ã—ã¦ãã ã•ã„ã€‚"
-        greater_than_or_equal_to: "ã¯%{count}ä»¥ä¸Šã®å€¤ã«ã—ã¦ãã ã•ã„ã€‚"
-        equal_to: "ã¯%{count}ã«ã—ã¦ãã ã•ã„ã€‚"
-        less_than: "ã¯%{count}ã‚ˆã‚Šå°ã•ã„å€¤ã«ã—ã¦ãã ã•ã„ã€‚"
-        less_than_or_equal_to: "ã¯%{count}ä»¥ä¸‹ã®å€¤ã«ã—ã¦ãã ã•ã„ã€‚"
-        odd: "ã¯å¥‡æ•°ã«ã—ã¦ãã ã•ã„ã€‚"
-        even: "ã¯å¶æ•°ã«ã—ã¦ãã ã•ã„ã€‚"
-        greater_than_start_date: "ã‚’é–‹å§‹æ—¥ã‚ˆã‚Šå¾Œã«ã—ã¦ãã ã•ã„"
-        not_same_project: "åŒã˜ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«å±žã—ã¦ã„ã¾ã›ã‚“"
-        circular_dependency: "ã“ã®é–¢ä¿‚ã§ã¯ã€å¾ªç’°ä¾å­˜ã«ãªã‚Šã¾ã™"
-        cant_link_an_issue_with_a_descendant: "æŒ‡å®šã—ãŸãƒã‚±ãƒƒãƒˆã¨ã¯è¦ªå­é–¢ä¿‚ã«ãªã£ã¦ã„ã‚‹ãŸã‚é–¢é€£ã¥ã‘ã‚‰ã‚Œã¾ã›ã‚“"
-
-  actionview_instancetag_blank_option: é¸ã‚“ã§ãã ã•ã„
-
-  general_text_No: 'ã„ã„ãˆ'
-  general_text_Yes: 'ã¯ã„'
-  general_text_no: 'ã„ã„ãˆ'
-  general_text_yes: 'ã¯ã„'
-  general_lang_name: 'Japanese (æ—¥æœ¬èªž)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: CP932
-  ## Redmine 1.2.0 ç¾åœ¨ã€ã“ã®å€¤ã«ã‚ˆã£ã¦ã€pdfã®å‡ºåŠ›ã®ãƒ•ã‚©ãƒ³ãƒˆã‚’åˆ‡ã‚Šæ›¿ãˆã¦ã„ã¾ã™ã€‚
-  ## CRuby ã§ã¯ CP932 ã«ã—ã¦ãã ã•ã„ã€‚
-  ## JRuby 1.6.2 (ruby-1.8.7-p330) ã§ã¯ã€CP932 ã§ã™ã¨
-  ## Iconv::InvalidEncodingä¾‹å¤–ãŒç™ºç”Ÿã—ã¾ã™ã€‚
-  ## JRuby ã§ã¯ã€SJIS ã‹ Shift_JIS ã«ã—ã¦ãã ã•ã„ã€‚
-  ## ã”å­˜çŸ¥ã®é€šã‚Šã€CP932 ã¨ SJIS ã¯åˆ¥ç‰©ã§ã™ãŒã€
-  ## ãã“ã¾ã§ã®æ¤œè¨¼ã¯ã—ã¦ã„ã¾ã›ã‚“ã€‚
-  # general_pdf_encoding: SJIS
-  general_pdf_encoding: CP932
-  general_first_day_of_week: '7'
-
-  notice_account_updated: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚
-  notice_account_invalid_creditentials: ãƒ¦ãƒ¼ã‚¶åã‚‚ã—ãã¯ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒç„¡åŠ¹
-  notice_account_password_updated: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚
-  notice_account_wrong_password: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒé•ã„ã¾ã™
-  notice_account_register_done: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚
-  notice_account_unknown_email: ãƒ¦ãƒ¼ã‚¶ãŒå­˜åœ¨ã—ã¾ã›ã‚“ã€‚
-  notice_can_t_change_password: ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§ã¯å¤–éƒ¨èªè¨¼ã‚’ä½¿ã£ã¦ã„ã¾ã™ã€‚ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã¯å¤‰æ›´ã§ãã¾ã›ã‚“ã€‚
-  notice_account_lost_email_sent: æ–°ã—ã„ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã—ãŸã€‚
-  notice_account_activated: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒæœ‰åŠ¹ã«ãªã‚Šã¾ã—ãŸã€‚ãƒ­ã‚°ã‚¤ãƒ³ã§ãã¾ã™ã€‚
-  notice_successful_create: ä½œæˆã—ã¾ã—ãŸã€‚
-  notice_successful_update: æ›´æ–°ã—ã¾ã—ãŸã€‚
-  notice_successful_delete: å‰Šé™¤ã—ã¾ã—ãŸã€‚
-  notice_successful_connection: æŽ¥ç¶šã—ã¾ã—ãŸã€‚
-  notice_file_not_found: ã‚¢ã‚¯ã‚»ã‚¹ã—ã‚ˆã†ã¨ã—ãŸãƒšãƒ¼ã‚¸ã¯å­˜åœ¨ã—ãªã„ã‹å‰Šé™¤ã•ã‚Œã¦ã„ã¾ã™ã€‚
-  notice_locking_conflict: åˆ¥ã®ãƒ¦ãƒ¼ã‚¶ãŒãƒ‡ãƒ¼ã‚¿ã‚’æ›´æ–°ã—ã¦ã„ã¾ã™ã€‚
-  notice_not_authorized: ã“ã®ãƒšãƒ¼ã‚¸ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯èªè¨¼ãŒå¿…è¦ã§ã™ã€‚
-  notice_not_authorized_archived_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¯æ›¸åº«ã«ä¿å­˜ã•ã‚Œã¦ã„ã¾ã™ã€‚
-  notice_email_sent: "%{value} å®›ã«ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã—ãŸã€‚"
-  notice_email_error: "ãƒ¡ãƒ¼ãƒ«é€ä¿¡ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ (%{value})"
-  notice_feeds_access_key_reseted: RSSã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã‚’åˆæœŸåŒ–ã—ã¾ã—ãŸã€‚
-  notice_api_access_key_reseted: APIã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã‚’åˆæœŸåŒ–ã—ã¾ã—ãŸã€‚
-  notice_failed_to_save_issues: "%{total}ä»¶ã®ã†ã¡%{count}ä»¶ã®ãƒã‚±ãƒƒãƒˆãŒä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %{ids}."
-  notice_failed_to_save_members: "ãƒ¡ãƒ³ãƒãƒ¼ã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸ: %{errors}."
-  notice_no_issue_selected: "ãƒã‚±ãƒƒãƒˆãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“! æ›´æ–°å¯¾è±¡ã®ãƒã‚±ãƒƒãƒˆã‚’é¸æŠžã—ã¦ãã ã•ã„ã€‚"
-  notice_account_pending: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯ä½œæˆæ¸ˆã¿ã§ã€ç®¡ç†è€…ã®æ‰¿èªå¾…ã¡ã§ã™ã€‚
-  notice_default_data_loaded: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®šã‚’ãƒ­ãƒ¼ãƒ‰ã—ã¾ã—ãŸã€‚
-  notice_unable_delete_version: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’å‰Šé™¤ã§ãã¾ã›ã‚“
-  notice_unable_delete_time_entry: ä½œæ¥­æ™‚é–“ã‚’å‰Šé™¤ã§ãã¾ã›ã‚“
-  notice_issue_done_ratios_updated: ãƒã‚±ãƒƒãƒˆã®é€²æ—ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚
-  notice_gantt_chart_truncated: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆã¯ã€æœ€å¤§è¡¨ç¤ºé …ç›®æ•°(%{max})ã‚’è¶…ãˆãŸãŸãŸã‚åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã—ãŸã€‚
-
-  error_can_t_load_default_data: "ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®šãŒãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ: %{value}"
-  error_scm_not_found: ãƒªãƒã‚¸ãƒˆãƒªã«ã€ã‚¨ãƒ³ãƒˆãƒª/ãƒªãƒ“ã‚¸ãƒ§ãƒ³ãŒå­˜åœ¨ã—ã¾ã›ã‚“ã€‚
-  error_scm_command_failed: "ãƒªãƒã‚¸ãƒˆãƒªã¸ã‚¢ã‚¯ã‚»ã‚¹ã—ã‚ˆã†ã¨ã—ã¦ã‚¨ãƒ©ãƒ¼ã«ãªã‚Šã¾ã—ãŸ: %{value}"
-  error_scm_annotate: "ã‚¨ãƒ³ãƒˆãƒªãŒå­˜åœ¨ã—ãªã„ã€ã‚‚ã—ãã¯ã‚¢ãƒŽãƒ†ãƒ¼ãƒˆã§ãã¾ã›ã‚“ã€‚"
-  error_issue_not_found_in_project: 'ãƒã‚±ãƒƒãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€ã‚‚ã—ãã¯ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«å±žã—ã¦ã„ã¾ã›ã‚“'
-  error_unable_delete_issue_status: "ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’å‰Šé™¤ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
-  error_no_tracker_in_project: 'ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«ã¯ãƒˆãƒ©ãƒƒã‚«ãƒ¼ãŒç™»éŒ²ã•ã‚Œã¦ã„ã¾ã›ã‚“ã€‚ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆè¨­å®šã‚’ç¢ºèªã—ã¦ãã ã•ã„ã€‚'
-  error_no_default_issue_status: 'ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒã‚±ãƒƒãƒˆã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“ã€‚è¨­å®šã‚’ç¢ºèªã—ã¦ãã ã•ã„ï¼ˆç®¡ç†â†’ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ï¼‰ã€‚'
-  error_can_not_delete_custom_field: 'ã‚«ã‚¹ã‚¿ãƒ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’å‰Šé™¤ã§ãã¾ã›ã‚“ã€‚'
-  error_unable_to_connect: "æŽ¥ç¶šã§ãã¾ã›ã‚“ã€‚ (%{value})"
-  error_can_not_remove_role: 'ã“ã®ãƒ­ãƒ¼ãƒ«ã¯ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚å‰Šé™¤ã§ãã¾ã›ã‚“ã€‚'
-  error_can_not_reopen_issue_on_closed_version: 'çµ‚äº†ã—ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã²ã‚‚ä»˜ã‘ã•ã‚ŒãŸãƒã‚±ãƒƒãƒˆã®å†ã‚ªãƒ¼ãƒ—ãƒ³ã¯ã§ãã¾ã›ã‚“ã€‚'
-  error_can_not_archive_project: ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¯æ›¸åº«ã«ä¿å­˜ã§ãã¾ã›ã‚“
-  error_issue_done_ratios_not_updated: "ãƒã‚±ãƒƒãƒˆã®é€²æ—ãŒæ›´æ–°ã§ãã¾ã›ã‚“ã€‚"
-  error_workflow_copy_source: 'ã‚³ãƒ”ãƒ¼å…ƒã¨ãªã‚‹ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã¾ãŸã¯ãƒ­ãƒ¼ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„'
-  error_workflow_copy_target: 'ã‚³ãƒ”ãƒ¼å…ˆã¨ãªã‚‹ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã¨ãƒ­ãƒ¼ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„'
-  error_can_not_delete_tracker: 'ã“ã®ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã¯ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚å‰Šé™¤ã§ãã¾ã›ã‚“ã€‚'
-
-  warning_attachments_not_saved: "%{count}å€‹ã®æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ãŒä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
-
-  mail_subject_lost_password: "%{value} ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰å†ç™ºè¡Œ"
-  mail_body_lost_password: 'ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã‚’å¤‰æ›´ã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®ãƒªãƒ³ã‚¯ã‚’ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„:'
-  mail_subject_register: "%{value} ã‚¢ã‚«ã‚¦ãƒ³ãƒˆç™»éŒ²ã®ç¢ºèª"
-  mail_body_register: 'ã‚¢ã‚«ã‚¦ãƒ³ãƒˆç™»éŒ²ã‚’å®Œäº†ã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„:'
-  mail_body_account_information_external: "%{value} ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’ä½¿ã£ã¦ã«ãƒ­ã‚°ã‚¤ãƒ³ã§ãã¾ã™ã€‚"
-  mail_body_account_information: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆæƒ…å ±
-  mail_subject_account_activation_request: "%{value} ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®æ‰¿èªè¦æ±‚"
-  mail_body_account_activation_request: "æ–°ã—ã„ãƒ¦ãƒ¼ã‚¶ %{value} ãŒç™»éŒ²ã•ã‚Œã¾ã—ãŸã€‚ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯ã‚ãªãŸã®æ‰¿èªå¾…ã¡ã§ã™ï¼š"
-  mail_subject_reminder: "%{count}ä»¶ã®ãƒã‚±ãƒƒãƒˆã®æœŸæ—¥ãŒ%{days}æ—¥ä»¥å†…ã«åˆ°æ¥ã—ã¾ã™"
-  mail_body_reminder: "%{count}ä»¶ã®æ‹…å½“ãƒã‚±ãƒƒãƒˆã®æœŸæ—¥ãŒ%{days}æ—¥ä»¥å†…ã«åˆ°æ¥ã—ã¾ã™:"
-  mail_subject_wiki_content_added: "Wikiãƒšãƒ¼ã‚¸ %{id} ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ"
-  mail_body_wiki_content_added: "%{author} ã«ã‚ˆã£ã¦Wikiãƒšãƒ¼ã‚¸ %{id} ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚"
-  mail_subject_wiki_content_updated: "Wikiãƒšãƒ¼ã‚¸ %{id} ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ"
-  mail_body_wiki_content_updated: "%{author} ã«ã‚ˆã£ã¦Wikiãƒšãƒ¼ã‚¸ %{id} ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
-
-  gui_validation_error: 1ä»¶ã®ã‚¨ãƒ©ãƒ¼
-  gui_validation_error_plural: "%{count}ä»¶ã®ã‚¨ãƒ©ãƒ¼"
-
-  field_name: åç§°
-  field_description: èª¬æ˜Ž
-  field_summary: ã‚µãƒžãƒªãƒ¼
-  field_is_required: å¿…é ˆ
-  field_firstname: åå‰
-  field_lastname: è‹—å­—
-  field_mail: ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹
-  field_filename: ãƒ•ã‚¡ã‚¤ãƒ«
-  field_filesize: ã‚µã‚¤ã‚º
-  field_downloads: ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰
-  field_author: ä½œæˆè€…
-  field_created_on: ä½œæˆæ—¥
-  field_updated_on: æ›´æ–°æ—¥
-  field_field_format: æ›¸å¼
-  field_is_for_all: å…¨ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå‘ã‘
-  field_possible_values: é¸æŠžè‚¢
-  field_regexp: æ­£è¦è¡¨ç¾
-  field_min_length: æœ€å°å€¤
-  field_max_length: æœ€å¤§å€¤
-  field_value: å€¤
-  field_category: ã‚«ãƒ†ã‚´ãƒª
-  field_title: ã‚¿ã‚¤ãƒˆãƒ«
-  field_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  field_issue: ãƒã‚±ãƒƒãƒˆ
-  field_status: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
-  field_notes: æ³¨è¨˜
-  field_is_closed: çµ‚äº†ã—ãŸãƒã‚±ãƒƒãƒˆ
-  field_is_default: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤
-  field_tracker: ãƒˆãƒ©ãƒƒã‚«ãƒ¼
-  field_subject: é¡Œå
-  field_due_date: æœŸæ—¥
-  field_assigned_to: æ‹…å½“è€…
-  field_priority: å„ªå…ˆåº¦
-  field_fixed_version: å¯¾è±¡ãƒãƒ¼ã‚¸ãƒ§ãƒ³
-  field_user: ãƒ¦ãƒ¼ã‚¶
-  field_principal: ä¸»ä½“
-  field_role: ãƒ­ãƒ¼ãƒ«
-  field_homepage: ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸
-  field_is_public: å…¬é–‹
-  field_parent: è¦ªãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå
-  field_is_in_roadmap: ãƒã‚±ãƒƒãƒˆã‚’ãƒ­ãƒ¼ãƒ‰ãƒžãƒƒãƒ—ã«è¡¨ç¤ºã™ã‚‹
-  field_login: ãƒ­ã‚°ã‚¤ãƒ³
-  field_mail_notification: ãƒ¡ãƒ¼ãƒ«é€šçŸ¥
-  field_admin: ç®¡ç†è€…
-  field_last_login_on: æœ€çµ‚æŽ¥ç¶šæ—¥
-  field_language: è¨€èªž
-  field_effective_date: æœŸæ—¥
-  field_password: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰
-  field_new_password: æ–°ã—ã„ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰
-  field_password_confirmation: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®ç¢ºèª
-  field_version: ãƒãƒ¼ã‚¸ãƒ§ãƒ³
-  field_type: ã‚¿ã‚¤ãƒ—
-  field_host: ãƒ›ã‚¹ãƒˆ
-  field_port: ãƒãƒ¼ãƒˆ
-  field_account: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆ
-  field_base_dn: æ¤œç´¢ç¯„å›²
-  field_attr_login: ãƒ­ã‚°ã‚¤ãƒ³åå±žæ€§
-  field_attr_firstname: åå‰å±žæ€§
-  field_attr_lastname: è‹—å­—å±žæ€§
-  field_attr_mail: ãƒ¡ãƒ¼ãƒ«å±žæ€§
-  field_onthefly: ã‚ã‚ã›ã¦ãƒ¦ãƒ¼ã‚¶ã‚’ä½œæˆ
-  field_start_date: é–‹å§‹æ—¥
-  field_done_ratio: é€²æ— %
-  field_auth_source: èªè¨¼æ–¹å¼
-  field_hide_mail: ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’éš ã™
-  field_comments: ã‚³ãƒ¡ãƒ³ãƒˆ
-  field_url: URL
-  field_start_page: ãƒ¡ã‚¤ãƒ³ãƒšãƒ¼ã‚¸
-  field_subproject: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  field_hours: æ™‚é–“
-  field_activity: æ´»å‹•
-  field_spent_on: æ—¥ä»˜
-  field_identifier: è­˜åˆ¥å­
-  field_is_filter: ãƒ•ã‚£ãƒ«ã‚¿ã¨ã—ã¦ä½¿ã†
-  field_issue_to: é–¢é€£ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
-  field_delay: é…å»¶
-  field_assignable: ã“ã®ãƒ­ãƒ¼ãƒ«ã«ãƒã‚±ãƒƒãƒˆã‚’å‰²ã‚Šå½“ã¦å¯èƒ½
-  field_redirect_existing_links: æ—¢å­˜ã®ãƒªãƒ³ã‚¯ã‚’ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã™ã‚‹
-  field_estimated_hours: äºˆå®šå·¥æ•°
-  field_column_names: é …ç›®
-  field_time_entries: æ™‚é–“ã‚’è¨˜éŒ²
-  field_time_zone: ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³
-  field_searchable: æ¤œç´¢æ¡ä»¶ã«è¨­å®šå¯èƒ½ã¨ã™ã‚‹
-  field_default_value: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤
-  field_comments_sorting: ã‚³ãƒ¡ãƒ³ãƒˆã®è¡¨ç¤ºé †
-  field_parent_title: è¦ªãƒšãƒ¼ã‚¸
-  field_editable: ç·¨é›†å¯èƒ½
-  field_watcher: ã‚¦ã‚©ãƒƒãƒãƒ£ãƒ¼
-  field_identity_url: OpenID URL
-  field_content: å†…å®¹
-  field_group_by: ã‚°ãƒ«ãƒ¼ãƒ—æ¡ä»¶
-  field_sharing: å…±æœ‰
-  field_parent_issue: è¦ªãƒã‚±ãƒƒãƒˆ
-  field_member_of_group: æ‹…å½“è€…ã®ã‚°ãƒ«ãƒ¼ãƒ—
-  field_assigned_to_role: æ‹…å½“è€…ã®ãƒ­ãƒ¼ãƒ«
-  field_text: ãƒ†ã‚­ã‚¹ãƒˆ
-  field_visible: è¡¨ç¤º
-  field_warn_on_leaving_unsaved: ãƒ‡ãƒ¼ã‚¿ã‚’ä¿å­˜ã›ãšã«ãƒšãƒ¼ã‚¸ã‹ã‚‰ç§»å‹•ã™ã‚‹ã¨ãã«è­¦å‘Š
-  field_commit_logs_encoding: ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°
-  field_scm_path_encoding: ãƒ‘ã‚¹ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°
-  field_path_to_repository: ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ‘ã‚¹
-  field_root_directory: ãƒ«ãƒ¼ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª
-  field_cvsroot: CVSROOT
-  field_cvs_module: ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«
-
-  setting_app_title: ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚¿ã‚¤ãƒˆãƒ«
-  setting_app_subtitle: ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚µãƒ–ã‚¿ã‚¤ãƒˆãƒ«
-  setting_welcome_text: ã‚¦ã‚§ãƒ«ã‚«ãƒ ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
-  setting_default_language: æ—¢å®šã®è¨€èªž
-  setting_login_required: èªè¨¼ãŒå¿…è¦
-  setting_self_registration: ãƒ¦ãƒ¼ã‚¶ã¯è‡ªåˆ†ã§ç™»éŒ²ã§ãã‚‹
-  setting_attachment_max_size: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ä¸Šé™
-  setting_issues_export_limit: ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã™ã‚‹ãƒã‚±ãƒƒãƒˆæ•°ã®ä¸Šé™
-  setting_mail_from: é€ä¿¡å…ƒãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹
-  setting_bcc_recipients: ãƒ–ãƒ©ã‚¤ãƒ³ãƒ‰ã‚«ãƒ¼ãƒœãƒ³ã‚³ãƒ”ãƒ¼ã§å—ä¿¡(bcc)
-  setting_plain_text_mail: ãƒ—ãƒ¬ã‚¤ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®ã¿(HTMLãªã—)
-  setting_host_name: ãƒ›ã‚¹ãƒˆå
-  setting_text_formatting: ãƒ†ã‚­ã‚¹ãƒˆã®æ›¸å¼
-  setting_cache_formatted_text: æ›¸å¼åŒ–ã•ã‚ŒãŸãƒ†ã‚­ã‚¹ãƒˆã‚’ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã™ã‚‹
-  setting_wiki_compression: Wikiå±¥æ­´ã‚’åœ§ç¸®ã™ã‚‹
-  setting_feeds_limit: ãƒ•ã‚£ãƒ¼ãƒ‰å†…å®¹ã®ä¸Šé™
-  setting_default_projects_public: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§æ–°ã—ã„ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¯å…¬é–‹ã«ã™ã‚‹
-  setting_autofetch_changesets: ã‚³ãƒŸãƒƒãƒˆã‚’è‡ªå‹•å–å¾—ã™ã‚‹
-  setting_sys_api_enabled: ãƒªãƒã‚¸ãƒˆãƒªç®¡ç†ç”¨ã®Webã‚µãƒ¼ãƒ“ã‚¹ã‚’æœ‰åŠ¹ã«ã™ã‚‹
-  setting_commit_ref_keywords: å‚ç…§ç”¨ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰
-  setting_commit_fix_keywords: ä¿®æ­£ç”¨ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰
-  setting_autologin: è‡ªå‹•ãƒ­ã‚°ã‚¤ãƒ³
-  setting_date_format: æ—¥ä»˜ã®å½¢å¼
-  setting_time_format: æ™‚åˆ»ã®å½¢å¼
-  setting_cross_project_issue_relations: ç•°ãªã‚‹ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ãƒã‚±ãƒƒãƒˆé–“ã§é–¢ä¿‚ã®è¨­å®šã‚’è¨±å¯
-  setting_issue_list_default_columns: ãƒã‚±ãƒƒãƒˆã®ä¸€è¦§ã§è¡¨ç¤ºã™ã‚‹é …ç›®
-  setting_repositories_encodings: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒªãƒã‚¸ãƒˆãƒªã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°
-  setting_emails_header: ãƒ¡ãƒ¼ãƒ«ã®ãƒ˜ãƒƒãƒ€
-  setting_emails_footer: ãƒ¡ãƒ¼ãƒ«ã®ãƒ•ãƒƒã‚¿
-  setting_protocol: ãƒ—ãƒ­ãƒˆã‚³ãƒ«
-  setting_per_page_options: ãƒšãƒ¼ã‚¸æ¯Žã®è¡¨ç¤ºä»¶æ•°
-  setting_user_format: ãƒ¦ãƒ¼ã‚¶åã®è¡¨ç¤ºæ›¸å¼
-  setting_activity_days_default: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®æ´»å‹•ãƒšãƒ¼ã‚¸ã«è¡¨ç¤ºã•ã‚Œã‚‹æ—¥æ•°
-  setting_display_subprojects_issues: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ãƒã‚±ãƒƒãƒˆã‚’ãƒ¡ã‚¤ãƒ³ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«è¡¨ç¤ºã™ã‚‹
-  setting_enabled_scm: ä½¿ç”¨ã™ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã‚·ã‚¹ãƒ†ãƒ 
-  setting_mail_handler_body_delimiters: "ãƒ¡ãƒ¼ãƒ«æœ¬æ–‡ã‹ã‚‰ä¸€è‡´ã™ã‚‹è¡Œä»¥é™ã‚’åˆ‡ã‚Šå–ã‚‹"
-  setting_mail_handler_api_enabled: å—ä¿¡ãƒ¡ãƒ¼ãƒ«ç”¨ã®Webã‚µãƒ¼ãƒ“ã‚¹ã‚’æœ‰åŠ¹ã«ã™ã‚‹
-  setting_mail_handler_api_key: APIã‚­ãƒ¼
-  setting_sequential_project_identifiers: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆè­˜åˆ¥å­ã‚’é€£ç•ªã§ç”Ÿæˆã™ã‚‹
-  setting_gravatar_enabled: Gravatarã®ã‚¢ã‚¤ã‚³ãƒ³ã‚’ä½¿ç”¨ã™ã‚‹
-  setting_gravatar_default: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®Gravatarã‚¢ã‚¤ã‚³ãƒ³
-  setting_diff_max_lines_displayed: å·®åˆ†ã®è¡¨ç¤ºè¡Œæ•°ã®ä¸Šé™
-  setting_file_max_size_displayed: ç”»é¢è¡¨ç¤ºã™ã‚‹ãƒ†ã‚­ã‚¹ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ä¸Šé™
-  setting_repository_log_display_limit: ãƒ•ã‚¡ã‚¤ãƒ«ã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³è¡¨ç¤ºæ•°ã®ä¸Šé™
-  setting_openid: OpenIDã«ã‚ˆã‚‹ãƒ­ã‚°ã‚¤ãƒ³ã¨ç™»éŒ²
-  setting_password_min_length: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®æœ€ä½Žå¿…è¦æ–‡å­—æ•°
-  setting_new_project_user_role_id: ç®¡ç†è€…ä»¥å¤–ã®ãƒ¦ãƒ¼ã‚¶ãŒä½œæˆã—ãŸãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«è¨­å®šã™ã‚‹ãƒ­ãƒ¼ãƒ«
-  setting_default_projects_modules: æ–°è¦ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«ãŠã„ã¦ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§æœ‰åŠ¹ã«ãªã‚‹ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«
-  setting_issue_done_ratio: é€²æ—ã®ç®—å‡ºæ–¹æ³•
-  setting_issue_done_ratio_issue_field: å„ãƒã‚±ãƒƒãƒˆã«ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ç”¨æ„ã™ã‚‹
-  setting_issue_done_ratio_issue_status: ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’ä½¿ç”¨ã™ã‚‹
-  setting_start_of_week: é€±ã®é–‹å§‹æ›œæ—¥
-  setting_rest_api_enabled: RESTã«ã‚ˆã‚‹Webã‚µãƒ¼ãƒ“ã‚¹ã‚’æœ‰åŠ¹ã«ã™ã‚‹
-  setting_default_notification_option: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã‚ªãƒ—ã‚·ãƒ§ãƒ³
-  setting_commit_logtime_enabled: ã‚³ãƒŸãƒƒãƒˆæ™‚ã«ä½œæ¥­æ™‚é–“ã‚’è¨˜éŒ²ã™ã‚‹
-  setting_commit_logtime_activity_id: ä½œæ¥­æ™‚é–“ã®ä½œæ¥­åˆ†é¡ž
-  setting_gantt_items_limit: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆæœ€å¤§è¡¨ç¤ºé …ç›®æ•°
-
-  permission_add_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®è¿½åŠ 
-  permission_add_subprojects: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®è¿½åŠ 
-  permission_edit_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ç·¨é›†
-  permission_select_project_modules: ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã®é¸æŠž
-  permission_manage_members: ãƒ¡ãƒ³ãƒãƒ¼ã®ç®¡ç†
-  permission_manage_versions: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ç®¡ç†
-  permission_manage_categories: ãƒã‚±ãƒƒãƒˆã®ã‚«ãƒ†ã‚´ãƒªã®ç®¡ç†
-  permission_view_issues: ãƒã‚±ãƒƒãƒˆã®é–²è¦§
-  permission_add_issues: ãƒã‚±ãƒƒãƒˆã®è¿½åŠ 
-  permission_edit_issues: ãƒã‚±ãƒƒãƒˆã®ç·¨é›†
-  permission_manage_issue_relations: ãƒã‚±ãƒƒãƒˆã®ç®¡ç†
-  permission_add_issue_notes: æ³¨è¨˜ã®è¿½åŠ 
-  permission_edit_issue_notes: æ³¨è¨˜ã®ç·¨é›†
-  permission_edit_own_issue_notes: è‡ªèº«ãŒè¨˜å…¥ã—ãŸæ³¨è¨˜ã®ç·¨é›†
-  permission_move_issues: ãƒã‚±ãƒƒãƒˆã®ç§»å‹•
-  permission_delete_issues: ãƒã‚±ãƒƒãƒˆã®å‰Šé™¤
-  permission_manage_public_queries: å…¬é–‹ã‚¯ã‚¨ãƒªã®ç®¡ç†
-  permission_save_queries: ã‚¯ã‚¨ãƒªã®ä¿å­˜
-  permission_view_gantt: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆã®é–²è¦§
-  permission_view_calendar: ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼ã®é–²è¦§
-  permission_view_issue_watchers: ã‚¦ã‚©ãƒƒãƒä¸€è¦§ã®é–²è¦§
-  permission_add_issue_watchers: ã‚¦ã‚©ãƒƒãƒã®è¿½åŠ 
-  permission_delete_issue_watchers: ã‚¦ã‚©ãƒƒãƒã®å‰Šé™¤
-  permission_log_time: å¤‰æ›´å±¥æ­´ã®è¨˜å…¥
-  permission_view_time_entries: å¤‰æ›´å±¥æ­´ã®é–²è¦§
-  permission_edit_time_entries: å¤‰æ›´å±¥æ­´ã®ç·¨é›†
-  permission_edit_own_time_entries: è‡ªèº«ãŒè¨˜å…¥ã—ãŸå¤‰æ›´å±¥æ­´ã®ç·¨é›†
-  permission_manage_project_activities: ä½œæ¥­åˆ†é¡ž (æ™‚é–“ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°) ã®ç®¡ç†
-  permission_manage_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã®ç®¡ç†
-  permission_comment_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã¸ã®ã‚³ãƒ¡ãƒ³ãƒˆ
-  permission_manage_documents: æ–‡æ›¸ã®ç®¡ç†
-  permission_view_documents: æ–‡æ›¸ã®é–²è¦§
-  permission_manage_files: ãƒ•ã‚¡ã‚¤ãƒ«ã®ç®¡ç†
-  permission_view_files: ãƒ•ã‚¡ã‚¤ãƒ«ã®é–²è¦§
-  permission_manage_wiki: Wikiã®ç®¡ç†
-  permission_rename_wiki_pages: Wikiãƒšãƒ¼ã‚¸åã®å¤‰æ›´
-  permission_delete_wiki_pages: Wikiãƒšãƒ¼ã‚¸ã®å‰Šé™¤
-  permission_view_wiki_pages: Wikiã®é–²è¦§
-  permission_export_wiki_pages: Wikiãƒšãƒ¼ã‚¸ã‚’ä»–ã®å½¢å¼ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ
-  permission_view_wiki_edits: Wikiå±¥æ­´ã®é–²è¦§
-  permission_edit_wiki_pages: Wikiãƒšãƒ¼ã‚¸ã®ç·¨é›†
-  permission_delete_wiki_pages_attachments: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã®å‰Šé™¤
-  permission_protect_wiki_pages: Wikiãƒšãƒ¼ã‚¸ã®å‡çµ
-  permission_manage_repository: ãƒªãƒã‚¸ãƒˆãƒªã®ç®¡ç†
-  permission_browse_repository: ãƒªãƒã‚¸ãƒˆãƒªã®é–²è¦§
-  permission_view_changesets: æ›´æ–°å±¥æ­´ã®é–²è¦§
-  permission_commit_access: ã‚³ãƒŸãƒƒãƒˆã®é–²è¦§
-  permission_manage_boards: ãƒ•ã‚©ãƒ¼ãƒ©ãƒ ã®ç®¡ç†
-  permission_view_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®é–²è¦§
-  permission_add_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®è¿½åŠ 
-  permission_edit_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ç·¨é›†
-  permission_edit_own_messages: è‡ªèº«ãŒè¨˜å…¥ã—ãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ç·¨é›†
-  permission_delete_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®å‰Šé™¤
-  permission_delete_own_messages: è‡ªèº«ãŒè¨˜å…¥ã—ãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®å‰Šé™¤
-  permission_manage_subtasks: å­ãƒã‚±ãƒƒãƒˆã®ç®¡ç†
-
-  project_module_issue_tracking: ãƒã‚±ãƒƒãƒˆãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°
-  project_module_time_tracking: æ™‚é–“ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°
-  project_module_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹
-  project_module_documents: æ–‡æ›¸
-  project_module_files: ãƒ•ã‚¡ã‚¤ãƒ«
-  project_module_wiki: Wiki
-  project_module_repository: ãƒªãƒã‚¸ãƒˆãƒª
-  project_module_boards: ãƒ•ã‚©ãƒ¼ãƒ©ãƒ 
-  project_module_gantt: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆ
-  project_module_calendar: ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼
-
-  label_user: ãƒ¦ãƒ¼ã‚¶
-  label_user_plural: ãƒ¦ãƒ¼ã‚¶
-  label_user_new: æ–°ã—ã„ãƒ¦ãƒ¼ã‚¶
-  label_user_anonymous: åŒ¿åãƒ¦ãƒ¼ã‚¶
-  label_profile: ãƒ—ãƒ­ãƒ•ã‚£ãƒ¼ãƒ«
-  label_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_project_new: æ–°ã—ã„ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_project_plural: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_x_projects:
-    zero:  ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¯ã‚ã‚Šã¾ã›ã‚“
-    one:   1ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-    other: "%{count}ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ"
-  label_project_all: å…¨ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_project_latest: æœ€è¿‘ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_issue: ãƒã‚±ãƒƒãƒˆ
-  label_issue_new: æ–°ã—ã„ãƒã‚±ãƒƒãƒˆ
-  label_issue_plural: ãƒã‚±ãƒƒãƒˆ
-  label_issue_view_all: ã™ã¹ã¦ã®ãƒã‚±ãƒƒãƒˆã‚’è¦‹ã‚‹
-  label_issues_by: "%{value} åˆ¥ã®ãƒã‚±ãƒƒãƒˆ"
-  label_issue_added: ãƒã‚±ãƒƒãƒˆãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
-  label_issue_updated: ãƒã‚±ãƒƒãƒˆãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ
-  label_document: æ–‡æ›¸
-  label_document_new: æ–°ã—ã„æ–‡æ›¸
-  label_document_plural: æ–‡æ›¸
-  label_document_added: æ–‡æ›¸ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
-  label_role: ãƒ­ãƒ¼ãƒ«
-  label_role_plural: ãƒ­ãƒ¼ãƒ«
-  label_role_new: æ–°ã—ã„ãƒ­ãƒ¼ãƒ«
-  label_role_and_permissions: ãƒ­ãƒ¼ãƒ«ã¨æ¨©é™
-  label_member: ãƒ¡ãƒ³ãƒãƒ¼
-  label_member_new: æ–°ã—ã„ãƒ¡ãƒ³ãƒãƒ¼
-  label_member_plural: ãƒ¡ãƒ³ãƒãƒ¼
-  label_tracker: ãƒˆãƒ©ãƒƒã‚«ãƒ¼
-  label_tracker_plural: ãƒˆãƒ©ãƒƒã‚«ãƒ¼
-  label_tracker_new: æ–°ã—ã„ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã‚’ä½œæˆ
-  label_workflow: ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼
-  label_issue_status: ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
-  label_issue_status_plural: ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
-  label_issue_status_new: æ–°ã—ã„ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
-  label_issue_category: ãƒã‚±ãƒƒãƒˆã®ã‚«ãƒ†ã‚´ãƒª
-  label_issue_category_plural: ãƒã‚±ãƒƒãƒˆã®ã‚«ãƒ†ã‚´ãƒª
-  label_issue_category_new: æ–°ã—ã„ã‚«ãƒ†ã‚´ãƒª
-  label_custom_field: ã‚«ã‚¹ã‚¿ãƒ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰
-  label_custom_field_plural: ã‚«ã‚¹ã‚¿ãƒ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰
-  label_custom_field_new: æ–°ã—ã„ã‚«ã‚¹ã‚¿ãƒ ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’ä½œæˆ
-  label_enumerations: åˆ—æŒ™é …ç›®
-  label_enumeration_new: æ–°ã—ã„å€¤
-  label_information: æƒ…å ±
-  label_information_plural: æƒ…å ±
-  label_please_login: ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ãã ã•ã„
-  label_register: ç™»éŒ²ã™ã‚‹
-  label_login_with_open_id_option: ã¾ãŸã¯OpenIDã§ãƒ­ã‚°ã‚¤ãƒ³ã™ã‚‹
-  label_password_lost: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®å†ç™ºè¡Œ
-  label_home: ãƒ›ãƒ¼ãƒ 
-  label_my_page: ãƒžã‚¤ãƒšãƒ¼ã‚¸
-  label_my_account: å€‹äººè¨­å®š
-  label_my_projects: ãƒžã‚¤ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_my_page_block: ãƒžã‚¤ãƒšãƒ¼ã‚¸ãƒ‘ãƒ¼ãƒ„
-  label_administration: ç®¡ç†
-  label_login: ãƒ­ã‚°ã‚¤ãƒ³
-  label_logout: ãƒ­ã‚°ã‚¢ã‚¦ãƒˆ
-  label_help: ãƒ˜ãƒ«ãƒ—
-  label_reported_issues: å ±å‘Šã—ãŸãƒã‚±ãƒƒãƒˆ
-  label_assigned_to_me_issues: æ‹…å½“ã—ã¦ã„ã‚‹ãƒã‚±ãƒƒãƒˆ
-  label_last_login: æœ€è¿‘ã®æŽ¥ç¶š
-  label_registered_on: ç™»éŒ²æ—¥
-  label_activity: æ´»å‹•
-  label_overall_activity: ã™ã¹ã¦ã®æ´»å‹•
-  label_user_activity: "%{value} ã®æ´»å‹•"
-  label_new: æ–°ã—ãä½œæˆ
-  label_logged_as: ãƒ­ã‚°ã‚¤ãƒ³ä¸­ï¼š
-  label_environment: ç’°å¢ƒ
-  label_authentication: èªè¨¼
-  label_auth_source: èªè¨¼æ–¹å¼
-  label_auth_source_new: æ–°ã—ã„èªè¨¼æ–¹å¼
-  label_auth_source_plural: èªè¨¼æ–¹å¼
-  label_subproject_plural: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_subproject_new: æ–°ã—ã„ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_and_its_subprojects: "%{value} ã¨ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ"
-  label_min_max_length: æœ€å°å€¤ - æœ€å¤§å€¤ã®é•·ã•
-  label_list: ãƒªã‚¹ãƒˆã‹ã‚‰é¸æŠž
-  label_date: æ—¥ä»˜
-  label_integer: æ•´æ•°
-  label_float: å°æ•°
-  label_boolean: çœŸå½å€¤
-  label_string: ãƒ†ã‚­ã‚¹ãƒˆ
-  label_text: é•·ã„ãƒ†ã‚­ã‚¹ãƒˆ
-  label_attribute: å±žæ€§
-  label_attribute_plural: å±žæ€§
-  label_download: "%{count}ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
-  label_download_plural: "%{count}ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
-  label_no_data: è¡¨ç¤ºã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãŒã‚ã‚Šã¾ã›ã‚“
-  label_change_status: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®å¤‰æ›´
-  label_history: å±¥æ­´
-  label_attachment: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«
-  label_attachment_new: æ–°ã—ã„æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«
-  label_attachment_delete: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å‰Šé™¤
-  label_attachment_plural: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«
-  label_file_added: ãƒ•ã‚¡ã‚¤ãƒ«ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
-  label_report: ãƒ¬ãƒãƒ¼ãƒˆ
-  label_report_plural: ãƒ¬ãƒãƒ¼ãƒˆ
-  label_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹
-  label_news_new: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã‚’è¿½åŠ 
-  label_news_plural: ãƒ‹ãƒ¥ãƒ¼ã‚¹
-  label_news_latest: æœ€æ–°ãƒ‹ãƒ¥ãƒ¼ã‚¹
-  label_news_view_all: ã™ã¹ã¦ã®ãƒ‹ãƒ¥ãƒ¼ã‚¹ã‚’è¦‹ã‚‹
-  label_news_added: ãƒ‹ãƒ¥ãƒ¼ã‚¹ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
-  label_news_comment_added: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã«ã‚³ãƒ¡ãƒ³ãƒˆãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
-  label_settings: è¨­å®š
-  label_overview: æ¦‚è¦
-  label_version: ãƒãƒ¼ã‚¸ãƒ§ãƒ³
-  label_version_new: æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³
-  label_version_plural: ãƒãƒ¼ã‚¸ãƒ§ãƒ³
-  label_confirmation: ç¢ºèª
-  label_close_versions: å®Œäº†ã—ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’çµ‚äº†ã«ã™ã‚‹
-  label_export_to: 'ä»–ã®å½¢å¼ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ:'
-  label_read: èª­ã‚€...
-  label_public_projects: å…¬é–‹ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_open_issues: æœªå®Œäº†
-  label_open_issues_plural: æœªå®Œäº†
-  label_closed_issues: å®Œäº†
-  label_closed_issues_plural: å®Œäº†
-  label_x_open_issues_abbr_on_total:
-    zero:  0ä»¶æœªå®Œäº† / å…¨%{total}ä»¶
-    one:   1ä»¶æœªå®Œäº† / å…¨%{total}ä»¶
-    other: "%{count}ä»¶æœªå®Œäº† / å…¨%{total}ä»¶"
-  label_x_open_issues_abbr:
-    zero:  0ä»¶æœªå®Œäº†
-    one:   1ä»¶æœªå®Œäº†
-    other: "%{count}ä»¶æœªå®Œäº†"
-  label_x_closed_issues_abbr:
-    zero:  0ä»¶å®Œäº†
-    one:   1ä»¶å®Œäº†
-    other: "%{count}ä»¶å®Œäº†"
-  label_total: åˆè¨ˆ
-  label_permissions: æ¨©é™
-  label_current_status: ç¾åœ¨ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
-  label_new_statuses_allowed: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®ç§»è¡Œå…ˆ
-  label_all: ã™ã¹ã¦
-  label_none: ãªã—
-  label_nobody: ç„¡è¨˜å
-  label_next: æ¬¡
-  label_previous: å‰
-  label_used_by: ä½¿ç”¨ä¸­
-  label_details: è©³ç´°
-  label_add_note: æ³¨è¨˜ã‚’è¿½åŠ 
-  label_per_page: ãƒšãƒ¼ã‚¸æ¯Ž
-  label_calendar: ã‚«ãƒ¬ãƒ³ãƒ€ãƒ¼
-  label_months_from: ãƒ¶æœˆåˆ†
-  label_gantt: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆ
-  label_internal: å†…éƒ¨
-  label_last_changes: "æœ€æ–°ã®å¤‰æ›´ %{count}ä»¶"
-  label_change_view_all: ã™ã¹ã¦ã®å¤‰æ›´ã‚’è¦‹ã‚‹
-  label_personalize_page: ã“ã®ãƒšãƒ¼ã‚¸ã‚’ãƒ‘ãƒ¼ã‚½ãƒŠãƒ©ã‚¤ã‚ºã™ã‚‹
-  label_comment: ã‚³ãƒ¡ãƒ³ãƒˆ
-  label_comment_plural: ã‚³ãƒ¡ãƒ³ãƒˆ
-  label_x_comments:
-    zero: ã‚³ãƒ¡ãƒ³ãƒˆãŒã‚ã‚Šã¾ã›ã‚“
-    one: 1ã‚³ãƒ¡ãƒ³ãƒˆ
-    other: "%{count}ã‚³ãƒ¡ãƒ³ãƒˆ"
-  label_comment_add: ã‚³ãƒ¡ãƒ³ãƒˆè¿½åŠ 
-  label_comment_added: è¿½åŠ ã•ã‚ŒãŸã‚³ãƒ¡ãƒ³ãƒˆ
-  label_comment_delete: ã‚³ãƒ¡ãƒ³ãƒˆå‰Šé™¤
-  label_query: ã‚«ã‚¹ã‚¿ãƒ ã‚¯ã‚¨ãƒª
-  label_query_plural: ã‚«ã‚¹ã‚¿ãƒ ã‚¯ã‚¨ãƒª
-  label_query_new: æ–°ã—ã„ã‚¯ã‚¨ãƒª
-  label_my_queries: ãƒžã‚¤ã‚«ã‚¹ã‚¿ãƒ ã‚¯ã‚¨ãƒª
-  label_filter_add: ãƒ•ã‚£ãƒ«ã‚¿è¿½åŠ 
-  label_filter_plural: ãƒ•ã‚£ãƒ«ã‚¿
-  label_equals: ç­‰ã—ã„
-  label_not_equals: ç­‰ã—ããªã„
-  label_in_less_than: ãŒä»Šæ—¥ã‹ã‚‰â—‹æ—¥å¾Œä»¥å‰
-  label_in_more_than: ãŒä»Šæ—¥ã‹ã‚‰â—‹æ—¥å¾Œä»¥é™
-  label_greater_or_equal: ä»¥ä¸Š
-  label_less_or_equal: ä»¥ä¸‹
-  label_in: ãŒä»Šæ—¥ã‹ã‚‰â—‹æ—¥å¾Œ
-  label_today: ä»Šæ—¥
-  label_all_time: å…¨æœŸé–“
-  label_yesterday: æ˜¨æ—¥
-  label_this_week: ä»Šé€±
-  label_last_week: å…ˆé€±
-  label_last_n_days: "ç›´è¿‘%{count}æ—¥é–“"
-  label_this_month: ä»Šæœˆ
-  label_last_month: å…ˆæœˆ
-  label_this_year: ä»Šå¹´
-  label_date_range: æœŸé–“
-  label_less_than_ago: ãŒä»Šæ—¥ã‚ˆã‚Šâ—‹æ—¥å‰ä»¥é™
-  label_more_than_ago: ãŒä»Šæ—¥ã‚ˆã‚Šâ—‹æ—¥å‰ä»¥å‰
-  label_ago: æ—¥å‰
-  label_contains: å«ã‚€
-  label_not_contains: å«ã¾ãªã„
-  label_day_plural: æ—¥
-  label_repository: ãƒªãƒã‚¸ãƒˆãƒª
-  label_repository_plural: ãƒªãƒã‚¸ãƒˆãƒª
-  label_browse: ãƒ–ãƒ©ã‚¦ã‚º
-  label_modification: "%{count}ç‚¹ã®å¤‰æ›´"
-  label_modification_plural: "%{count}ç‚¹ã®å¤‰æ›´"
-  label_branch: ãƒ–ãƒ©ãƒ³ãƒ
-  label_tag: ã‚¿ã‚°
-  label_revision: ãƒªãƒ“ã‚¸ãƒ§ãƒ³
-  label_revision_plural: ãƒªãƒ“ã‚¸ãƒ§ãƒ³
-  label_revision_id: ãƒªãƒ“ã‚¸ãƒ§ãƒ³ %{value}
-  label_associated_revisions: é–¢ä¿‚ã—ã¦ã„ã‚‹ãƒªãƒ“ã‚¸ãƒ§ãƒ³
-  label_added: è¿½åŠ 
-  label_modified: å¤‰æ›´
-  label_copied: ã‚³ãƒ”ãƒ¼
-  label_renamed: åç§°å¤‰æ›´
-  label_deleted: å‰Šé™¤
-  label_latest_revision: æœ€æ–°ãƒªãƒ“ã‚¸ãƒ§ãƒ³
-  label_latest_revision_plural: æœ€æ–°ãƒªãƒ“ã‚¸ãƒ§ãƒ³
-  label_view_revisions: ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã‚’è¦‹ã‚‹
-  label_view_all_revisions: ã™ã¹ã¦ã®ãƒªãƒ“ã‚¸ãƒ§ãƒ³ã‚’è¦‹ã‚‹
-  label_max_size: ã‚µã‚¤ã‚ºã®ä¸Šé™
-  label_sort_highest: ä¸€ç•ªä¸Šã¸
-  label_sort_higher: ä¸Šã¸
-  label_sort_lower: ä¸‹ã¸
-  label_sort_lowest: ä¸€ç•ªä¸‹ã¸
-  label_roadmap: ãƒ­ãƒ¼ãƒ‰ãƒžãƒƒãƒ—
-  label_roadmap_due_in: "æœŸæ—¥ã¾ã§ %{value}"
-  label_roadmap_overdue: "%{value} é…ã‚Œ"
-  label_roadmap_no_issues: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«é–¢ã™ã‚‹ãƒã‚±ãƒƒãƒˆã¯ã‚ã‚Šã¾ã›ã‚“
-  label_search: æ¤œç´¢
-  label_result_plural: çµæžœ
-  label_all_words: ã™ã¹ã¦ã®å˜èªž
-  label_wiki: Wiki
-  label_wiki_edit: Wikiç·¨é›†
-  label_wiki_edit_plural: Wikiç·¨é›†
-  label_wiki_page: Wikiãƒšãƒ¼ã‚¸
-  label_wiki_page_plural: Wikiãƒšãƒ¼ã‚¸
-  label_index_by_title: ç´¢å¼•(åå‰é †)
-  label_index_by_date: ç´¢å¼•(æ—¥ä»˜é †)
-  label_current_version: æœ€æ–°ç‰ˆ
-  label_preview: ãƒ—ãƒ¬ãƒ“ãƒ¥ãƒ¼
-  label_feed_plural: ãƒ•ã‚£ãƒ¼ãƒ‰
-  label_changes_details: å…¨å¤‰æ›´ã®è©³ç´°
-  label_issue_tracking: ãƒã‚±ãƒƒãƒˆãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°
-  label_spent_time: ä½œæ¥­æ™‚é–“ã®è¨˜éŒ²
-  label_overall_spent_time: ã™ã¹ã¦ã®ä½œæ¥­æ™‚é–“ã®è¨˜éŒ²
-  label_f_hour: "%{value}æ™‚é–“"
-  label_f_hour_plural: "%{value}æ™‚é–“"
-  label_time_tracking: æ™‚é–“ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°
-  label_change_plural: å¤‰æ›´
-  label_statistics: çµ±è¨ˆ
-  label_commits_per_month: æœˆåˆ¥ã®ã‚³ãƒŸãƒƒãƒˆ
-  label_commits_per_author: èµ·ç¥¨è€…åˆ¥ã®ã‚³ãƒŸãƒƒãƒˆ
-  label_diff: å·®åˆ†
-  label_view_diff: å·®åˆ†ã‚’è¦‹ã‚‹
-  label_diff_inline: ã‚¤ãƒ³ãƒ©ã‚¤ãƒ³
-  label_diff_side_by_side: æ¨ªã«ä¸¦ã¹ã‚‹
-  label_options: ã‚ªãƒ—ã‚·ãƒ§ãƒ³
-  label_copy_workflow_from: ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼ã‚’ã“ã“ã‹ã‚‰ã‚³ãƒ”ãƒ¼
-  label_permissions_report: æ¨©é™ãƒ¬ãƒãƒ¼ãƒˆ
-  label_watched_issues: ã‚¦ã‚©ãƒƒãƒã—ã¦ã„ã‚‹ãƒã‚±ãƒƒãƒˆ
-  label_related_issues: é–¢é€£ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
-  label_applied_status: é©ç”¨ã•ã‚Œã‚‹ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹
-  label_loading: ãƒ­ãƒ¼ãƒ‰ä¸­...
-  label_relation_new: æ–°ã—ã„é–¢é€£
-  label_relation_delete: é–¢é€£ã®å‰Šé™¤
-  label_relates_to: é–¢ä¿‚ã—ã¦ã„ã‚‹
-  label_duplicates: é‡è¤‡ã—ã¦ã„ã‚‹
-  label_duplicated_by: é‡è¤‡ã•ã‚Œã¦ã„ã‚‹
-  label_blocks: ãƒ–ãƒ­ãƒƒã‚¯ã—ã¦ã„ã‚‹
-  label_blocked_by: ãƒ–ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã‚‹
-  label_precedes: å…ˆè¡Œã™ã‚‹
-  label_follows: å¾Œç¶šã™ã‚‹
-  label_end_to_start: æœ€å¾Œ-æœ€åˆ
-  label_end_to_end: æœ€å¾Œ-æœ€å¾Œ
-  label_start_to_start: æœ€åˆ-æœ€åˆ
-  label_start_to_end: æœ€åˆ-æœ€å¾Œ
-  label_stay_logged_in: ãƒ­ã‚°ã‚¤ãƒ³ã‚’ç¶­æŒ
-  label_disabled: ç„¡åŠ¹
-  label_show_completed_versions: å®Œäº†ã—ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’è¡¨ç¤º
-  label_me: è‡ªåˆ†
-  label_board: ãƒ•ã‚©ãƒ¼ãƒ©ãƒ 
-  label_board_new: æ–°ã—ã„ãƒ•ã‚©ãƒ¼ãƒ©ãƒ 
-  label_board_plural: ãƒ•ã‚©ãƒ¼ãƒ©ãƒ 
-  label_board_sticky: ã‚¹ãƒ†ã‚£ãƒƒã‚­ãƒ¼
-  label_board_locked: ãƒ­ãƒƒã‚¯
-  label_topic_plural: ãƒˆãƒ”ãƒƒã‚¯
-  label_message_plural: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
-  label_message_last: æœ€æ–°ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
-  label_message_new: æ–°ã—ã„ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
-  label_message_posted: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
-  label_reply_plural: è¿”ç­”
-  label_send_information: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆæƒ…å ±ã‚’ãƒ¦ãƒ¼ã‚¶ã«é€ä¿¡
-  label_year: å¹´
-  label_month: æœˆ
-  label_week: é€±
-  label_date_from: "æ—¥ä»˜æŒ‡å®š: "
-  label_date_to: ã‹ã‚‰
-  label_language_based: æ—¢å®šã®è¨€èªžã®è¨­å®šã«å¾“ã†
-  label_sort_by: "ä¸¦ã³æ›¿ãˆ %{value}"
-  label_send_test_email: ãƒ†ã‚¹ãƒˆãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡
-  label_feeds_access_key: RSSã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼
-  label_missing_feeds_access_key: RSSã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“
-  label_feeds_access_key_created_on: "RSSã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã¯%{value}å‰ã«ä½œæˆã•ã‚Œã¾ã—ãŸ"
-  label_module_plural: ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«
-  label_added_time_by: "%{author} ãŒ%{age}å‰ã«è¿½åŠ "
-  label_updated_time_by: "%{author} ãŒ%{age}å‰ã«æ›´æ–°"
-  label_updated_time: "%{value}å‰ã«æ›´æ–°"
-  label_jump_to_a_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¸ç§»å‹•...
-  label_file_plural: ãƒ•ã‚¡ã‚¤ãƒ«
-  label_changeset_plural: æ›´æ–°å±¥æ­´
-  label_default_columns: æ—¢å®šã®é …ç›®
-  label_no_change_option: (å¤‰æ›´ç„¡ã—)
-  label_bulk_edit_selected_issues: ãƒã‚±ãƒƒãƒˆã®ä¸€æ‹¬ç·¨é›†
-  label_theme: ãƒ†ãƒ¼ãƒž
-  label_default: æ—¢å®š
-  label_search_titles_only: ã‚¿ã‚¤ãƒˆãƒ«ã®ã¿
-  label_user_mail_option_all: "å‚åŠ ã—ã¦ã„ã‚‹ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ã™ã¹ã¦ã®é€šçŸ¥"
-  label_user_mail_option_selected: "é¸æŠžã—ãŸãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ã™ã¹ã¦ã®é€šçŸ¥..."
-  label_user_mail_option_none: "é€šçŸ¥ã—ãªã„"
-  label_user_mail_option_only_my_events: "ã‚¦ã‚©ãƒƒãƒã¾ãŸã¯é–¢ä¿‚ã—ã¦ã„ã‚‹äº‹æŸ„ã®ã¿"
-  label_user_mail_option_only_assigned: "è‡ªåˆ†ãŒæ‹…å½“ã—ã¦ã„ã‚‹äº‹æŸ„ã®ã¿"
-  label_user_mail_option_only_owner: "è‡ªåˆ†ãŒä½œæˆã—ãŸäº‹æŸ„ã®ã¿"
-  label_user_mail_no_self_notified: è‡ªåˆ†è‡ªèº«ã«ã‚ˆã‚‹å¤‰æ›´ã®é€šçŸ¥ã¯ä¸è¦
-  label_registration_activation_by_email: ãƒ¡ãƒ¼ãƒ«ã§ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’æœ‰åŠ¹åŒ–
-  label_registration_manual_activation: æ‰‹å‹•ã§ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’æœ‰åŠ¹åŒ–
-  label_registration_automatic_activation: è‡ªå‹•ã§ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’æœ‰åŠ¹åŒ–
-  label_display_per_page: "1ãƒšãƒ¼ã‚¸ã«: %{value}"
-  label_age: å¹´é½¢
-  label_change_properties: ãƒ—ãƒ­ãƒ‘ãƒ†ã‚£ã®å¤‰æ›´
-  label_general: å…¨èˆ¬
-  label_more: ç¶šã
-  label_scm: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã‚·ã‚¹ãƒ†ãƒ 
-  label_plugins: ãƒ—ãƒ©ã‚°ã‚¤ãƒ³
-  label_ldap_authentication: LDAPèªè¨¼
-  label_downloads_abbr: DL
-  label_optional_description: ä»»æ„ã®ã‚³ãƒ¡ãƒ³ãƒˆ
-  label_add_another_file: åˆ¥ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’è¿½åŠ 
-  label_preferences: è¨­å®š
-  label_chronological_order: å¤ã„é †
-  label_reverse_chronological_order: æ–°ã—ã„é †
-  label_planning: è¨ˆç”»
-  label_incoming_emails: å—ä¿¡ãƒ¡ãƒ¼ãƒ«
-  label_generate_key: ã‚­ãƒ¼ã®ç”Ÿæˆ
-  label_issue_watchers: ãƒã‚±ãƒƒãƒˆã®ã‚¦ã‚©ãƒƒãƒãƒ£ãƒ¼
-  label_example: ä¾‹
-  label_display: è¡¨ç¤º
-  label_sort: ã‚½ãƒ¼ãƒˆæ¡ä»¶
-  label_ascending: æ˜‡é †
-  label_descending: é™é †
-  label_date_from_to: "%{start}ã‹ã‚‰%{end}ã¾ã§"
-  label_wiki_content_added: Wikiãƒšãƒ¼ã‚¸ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
-  label_wiki_content_updated: Wikiãƒšãƒ¼ã‚¸ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ
-  label_group: ã‚°ãƒ«ãƒ¼ãƒ—
-  label_group_plural: ã‚°ãƒ«ãƒ¼ãƒ—
-  label_group_new: æ–°ã—ã„ã‚°ãƒ«ãƒ¼ãƒ—
-  label_time_entry_plural: ä½œæ¥­æ™‚é–“ã®è¨˜éŒ²
-  label_version_sharing_none: å…±æœ‰ã—ãªã„
-  label_version_sharing_descendants: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆå˜ä½
-  label_version_sharing_hierarchy: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆéšŽå±¤å˜ä½
-  label_version_sharing_tree: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆãƒ„ãƒªãƒ¼å˜ä½
-  label_version_sharing_system: ã™ã¹ã¦ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  label_update_issue_done_ratios: é€²æ—ã®æ›´æ–°
-  label_copy_source: ã‚³ãƒ”ãƒ¼å…ƒ
-  label_copy_target: ã‚³ãƒ”ãƒ¼å…ˆ
-  label_copy_same_as_target: åŒã˜ã‚³ãƒ”ãƒ¼å…ˆ
-  label_display_used_statuses_only: ã“ã®ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã§ä½¿ã‚ã‚Œã¦ã„ã‚‹ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®ã¿è¡¨ç¤ºã™ã‚‹
-  label_api_access_key: APIã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼
-  label_missing_api_access_key: APIã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“
-  label_api_access_key_created_on: "APIã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã¯%{value}å‰ã«ä½œæˆã•ã‚Œã¾ã—ãŸ"
-  label_subtask_plural: å­ãƒã‚±ãƒƒãƒˆ
-  label_project_copy_notifications: ã‚³ãƒ”ãƒ¼ã—ãŸãƒã‚±ãƒƒãƒˆã®ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã‚’é€ä¿¡ã™ã‚‹
-  label_principal_search: "ãƒ¦ãƒ¼ã‚¶ã¾ãŸã¯ã‚°ãƒ«ãƒ¼ãƒ—ã®æ¤œç´¢:"
-  label_user_search: "ãƒ¦ãƒ¼ã‚¶ã®æ¤œç´¢:"
-  label_git_report_last_commit: ãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®æœ€æ–°ã‚³ãƒŸãƒƒãƒˆã‚’è¡¨ç¤ºã™ã‚‹
-  label_parent_revision: è¦ª
-  label_child_revision: å­
-
-  button_login: ãƒ­ã‚°ã‚¤ãƒ³
-  button_submit: å¤‰æ›´
-  button_save: ä¿å­˜
-  button_check_all: ã™ã¹ã¦ã«ãƒã‚§ãƒƒã‚¯ã‚’ã¤ã‘ã‚‹
-  button_uncheck_all: ã™ã¹ã¦ã®ãƒã‚§ãƒƒã‚¯ã‚’å¤–ã™
-  button_expand_all: å±•é–‹
-  button_collapse_all: æŠ˜ã‚ŠãŸãŸã¿
-  button_delete: å‰Šé™¤
-  button_create: ä½œæˆ
-  button_create_and_continue: é€£ç¶šä½œæˆ
-  button_test: ãƒ†ã‚¹ãƒˆ
-  button_edit: ç·¨é›†
-  button_edit_associated_wikipage: "é–¢é€£ã™ã‚‹Wikiãƒšãƒ¼ã‚¸ã‚’ç·¨é›†: %{page_title}"
-  button_add: è¿½åŠ 
-  button_change: å¤‰æ›´
-  button_apply: é©ç”¨
-  button_clear: ã‚¯ãƒªã‚¢
-  button_lock: ãƒ­ãƒƒã‚¯
-  button_unlock: ã‚¢ãƒ³ãƒ­ãƒƒã‚¯
-  button_download: ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰
-  button_list: ä¸€è¦§
-  button_view: è¦‹ã‚‹
-  button_move: ç§»å‹•
-  button_move_and_follow: ç§»å‹•å¾Œè¡¨ç¤º
-  button_back: æˆ»ã‚‹
-  button_cancel: ã‚­ãƒ£ãƒ³ã‚»ãƒ«
-  button_activate: æœ‰åŠ¹ã«ã™ã‚‹
-  button_sort: ã‚½ãƒ¼ãƒˆ
-  button_log_time: æ™‚é–“ã‚’è¨˜éŒ²
-  button_rollback: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯
-  button_watch: ã‚¦ã‚©ãƒƒãƒ
-  button_unwatch: ã‚¦ã‚©ãƒƒãƒã‚’ã‚„ã‚ã‚‹
-  button_reply: è¿”ç­”
-  button_archive: æ›¸åº«ã«ä¿å­˜
-  button_unarchive: æ›¸åº«ã‹ã‚‰æˆ»ã™
-  button_reset: ãƒªã‚»ãƒƒãƒˆ
-  button_rename: åå‰å¤‰æ›´
-  button_change_password: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰å¤‰æ›´
-  button_copy: ã‚³ãƒ”ãƒ¼
-  button_copy_and_follow: ã‚³ãƒ”ãƒ¼å¾Œè¡¨ç¤º
-  button_annotate: ã‚¢ãƒŽãƒ†ãƒ¼ãƒˆ
-  button_update: æ›´æ–°
-  button_configure: è¨­å®š
-  button_quote: å¼•ç”¨
-  button_duplicate: è¤‡è£½
-  button_show: è¡¨ç¤º
-
-  status_active: æœ‰åŠ¹
-  status_registered: ç™»éŒ²
-  status_locked: ãƒ­ãƒƒã‚¯
-
-  version_status_open: é€²è¡Œä¸­
-  version_status_locked: ãƒ­ãƒƒã‚¯ä¸­
-  version_status_closed: çµ‚äº†
-
-  field_active: æœ‰åŠ¹
-
-  text_select_mail_notifications: ã©ã®ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã‚’é€ä¿¡ã™ã‚‹ã‹ã€ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’é¸æŠžã—ã¦ãã ã•ã„ã€‚
-  text_regexp_info: ä¾‹) ^[A-Z0-9]+$
-  text_min_max_length_info: 0ã ã¨ç„¡åˆ¶é™ã«ãªã‚Šã¾ã™
-  text_project_destroy_confirmation: æœ¬å½“ã«ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã¨é–¢é€£ãƒ‡ãƒ¼ã‚¿ã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
-  text_subprojects_destroy_warning: "ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ %{value} ã‚‚å‰Šé™¤ã•ã‚Œã¾ã™ã€‚"
-  text_workflow_edit: ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼ã‚’ç·¨é›†ã™ã‚‹ãƒ­ãƒ¼ãƒ«ã¨ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã‚’é¸ã‚“ã§ãã ã•ã„
-  text_are_you_sure: ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ
-  text_are_you_sure_with_children: ãƒã‚±ãƒƒãƒˆã¨ãã®å­ãƒã‚±ãƒƒãƒˆã™ã¹ã¦ã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
-  text_journal_changed: "%{label} ã‚’ %{old} ã‹ã‚‰ %{new} ã«å¤‰æ›´"
-  text_journal_changed_no_detail: "%{label} ã‚’æ›´æ–°"
-  text_journal_set_to: "%{label} ã‚’ %{value} ã«ã‚»ãƒƒãƒˆ"
-  text_journal_deleted: "%{label} ã‚’å‰Šé™¤ (%{old})"
-  text_journal_added: "%{label} %{value} ã‚’è¿½åŠ "
-  text_tip_issue_begin_day: ã“ã®æ—¥ã«é–‹å§‹ã™ã‚‹ã‚¿ã‚¹ã‚¯
-  text_tip_issue_end_day: ã“ã®æ—¥ã«çµ‚äº†ã™ã‚‹ã‚¿ã‚¹ã‚¯
-  text_tip_issue_begin_end_day: ã“ã®æ—¥ã®ã†ã¡ã«é–‹å§‹ã—ã¦çµ‚äº†ã™ã‚‹ã‚¿ã‚¹ã‚¯
-  text_project_identifier_info: 'è‹±å°æ–‡å­—(a-z)ã¨æ•°å­—ã¨ãƒ€ãƒƒã‚·ãƒ¥(-)ãŒä½¿ãˆã¾ã™ã€‚<br />ä¸€åº¦ä¿å­˜ã™ã‚‹ã¨ã€è­˜åˆ¥å­ã¯å¤‰æ›´ã§ãã¾ã›ã‚“ã€‚'
-  text_caracters_maximum: "æœ€å¤§%{count}æ–‡å­—ã§ã™ã€‚"
-  text_caracters_minimum: "æœ€ä½Ž%{count}æ–‡å­—ã®é•·ã•ãŒå¿…è¦ã§ã™"
-  text_length_between: "é•·ã•ã¯%{min}ã‹ã‚‰%{max}æ–‡å­—ã¾ã§ã§ã™ã€‚"
-  text_tracker_no_workflow: ã“ã®ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã«ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“
-  text_unallowed_characters: æ¬¡ã®æ–‡å­—ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“
-  text_comma_separated: (ã‚«ãƒ³ãƒžã§åŒºåˆ‡ã‚‹ã“ã¨ã§)è¤‡æ•°ã®å€¤ã‚’è¨­å®šã§ãã¾ã™ã€‚
-  text_line_separated: (1è¡Œã”ã¨ã«æ›¸ãã“ã¨ã§)è¤‡æ•°ã®å€¤ã‚’è¨­å®šã§ãã¾ã™ã€‚
-  text_issues_ref_in_commit_messages: ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸å†…ã§ãƒã‚±ãƒƒãƒˆã®å‚ç…§/ä¿®æ­£
-  text_issue_added: "ãƒã‚±ãƒƒãƒˆ %{id} ãŒ %{author} ã«ã‚ˆã£ã¦å ±å‘Šã•ã‚Œã¾ã—ãŸã€‚"
-  text_issue_updated: "ãƒã‚±ãƒƒãƒˆ %{id} ãŒ %{author} ã«ã‚ˆã£ã¦æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
-  text_wiki_destroy_confirmation: æœ¬å½“ã«ã“ã®wikiã¨ãã®å†…å®¹ã®ã™ã¹ã¦ã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
-  text_issue_category_destroy_question: "%{count}ä»¶ã®ãƒã‚±ãƒƒãƒˆãŒã“ã®ã‚«ãƒ†ã‚´ãƒªã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚"
-  text_issue_category_destroy_assignments: ã‚«ãƒ†ã‚´ãƒªã®å‰²ã‚Šå½“ã¦ã‚’å‰Šé™¤ã™ã‚‹
-  text_issue_category_reassign_to: ãƒã‚±ãƒƒãƒˆã‚’ã“ã®ã‚«ãƒ†ã‚´ãƒªã«å†å‰²ã‚Šå½“ã¦ã™ã‚‹
-  text_user_mail_option: "æœªé¸æŠžã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã§ã¯ã€ã‚¦ã‚©ãƒƒãƒã¾ãŸã¯é–¢ä¿‚ã—ã¦ã„ã‚‹äº‹æŸ„(ä¾‹: è‡ªåˆ†ãŒå ±å‘Šè€…ã‚‚ã—ãã¯æ‹…å½“è€…ã§ã‚ã‚‹ãƒã‚±ãƒƒãƒˆ)ã®ã¿ãƒ¡ãƒ¼ãƒ«ãŒé€ä¿¡ã•ã‚Œã¾ã™ã€‚"
-  text_no_configuration_data: "ãƒ­ãƒ¼ãƒ«ã€ãƒˆãƒ©ãƒƒã‚«ãƒ¼ã€ãƒã‚±ãƒƒãƒˆã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã€ãƒ¯ãƒ¼ã‚¯ãƒ•ãƒ­ãƒ¼ãŒã¾ã è¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“ã€‚\nãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®šã®ãƒ­ãƒ¼ãƒ‰ã‚’å¼·ããŠå‹§ã‚ã—ã¾ã™ã€‚ãƒ­ãƒ¼ãƒ‰ã—ãŸå¾Œã€ãã‚Œã‚’ä¿®æ­£ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
-  text_load_default_configuration: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®šã‚’ãƒ­ãƒ¼ãƒ‰
-  text_status_changed_by_changeset: "æ›´æ–°å±¥æ­´ %{value} ã§é©ç”¨ã•ã‚Œã¾ã—ãŸã€‚"
-  text_time_logged_by_changeset: "æ›´æ–°å±¥æ­´ %{value} ã§é©ç”¨ã•ã‚Œã¾ã—ãŸã€‚"
-  text_issues_destroy_confirmation: 'æœ¬å½“ã«é¸æŠžã—ãŸãƒã‚±ãƒƒãƒˆã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ'
-  text_select_project_modules: 'ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã§ä½¿ç”¨ã™ã‚‹ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„:'
-  text_default_administrator_account_changed: ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆç®¡ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¤‰æ›´æ¸ˆ
-  text_file_repository_writable: ãƒ•ã‚¡ã‚¤ãƒ«ãƒªãƒã‚¸ãƒˆãƒªã«æ›¸ãè¾¼ã¿å¯èƒ½
-  text_plugin_assets_writable: Plugin assetsãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ›¸ãè¾¼ã¿å¯èƒ½
-  text_rmagick_available: RMagickãŒä½¿ç”¨å¯èƒ½ (ã‚ªãƒ—ã‚·ãƒ§ãƒ³)
-  text_destroy_time_entries_question: ã“ã®ãƒã‚±ãƒƒãƒˆã®%{hours}æ™‚é–“åˆ†ã®ä½œæ¥­è¨˜éŒ²ã®æ‰±ã„ã‚’é¸æŠžã—ã¦ãã ã•ã„ã€‚
-  text_destroy_time_entries: è¨˜éŒ²ã•ã‚ŒãŸä½œæ¥­æ™‚é–“ã‚’å«ã‚ã¦å‰Šé™¤
-  text_assign_time_entries_to_project: è¨˜éŒ²ã•ã‚ŒãŸä½œæ¥­æ™‚é–“ã‚’ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆè‡ªä½“ã«å‰²ã‚Šå½“ã¦
-  text_reassign_time_entries: 'è¨˜éŒ²ã•ã‚ŒãŸä½œæ¥­æ™‚é–“ã‚’ã“ã®ãƒã‚±ãƒƒãƒˆã«å†å‰²ã‚Šå½“ã¦ï¼š'
-  text_user_wrote: "%{value} ã¯æ›¸ãã¾ã—ãŸ:"
-  text_enumeration_destroy_question: "%{count}å€‹ã®ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒã“ã®å€¤ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚"
-  text_enumeration_category_reassign_to: 'æ¬¡ã®å€¤ã«å‰²ã‚Šå½“ã¦ç›´ã™:'
-  text_email_delivery_not_configured: "ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã™ã‚‹ãŸã‚ã«å¿…è¦ãªè¨­å®šãŒè¡Œã‚ã‚Œã¦ã„ãªã„ãŸã‚ã€ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“ã€‚\nconfig/configuration.ymlã§SMTPã‚µãƒ¼ãƒã®è¨­å®šã‚’è¡Œã„ã€ã‚¢ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„ã€‚"
-  text_repository_usernames_mapping: "ãƒªãƒã‚¸ãƒˆãƒªã®ãƒ­ã‚°ã‹ã‚‰æ¤œå‡ºã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚’ã©ã®Redmineãƒ¦ãƒ¼ã‚¶ãƒ¼ã«é–¢é€£ã¥ã‘ã‚‹ã®ã‹é¸æŠžã—ã¦ãã ã•ã„ã€‚\nãƒ­ã‚°ä¸Šã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åã¾ãŸã¯ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒRedmineã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¨ä¸€è‡´ã™ã‚‹å ´åˆã¯è‡ªå‹•çš„ã«é–¢é€£ã¥ã‘ã‚‰ã‚Œã¾ã™ã€‚"
-  text_diff_truncated: '... å·®åˆ†ã®è¡Œæ•°ãŒè¡¨ç¤ºå¯èƒ½ãªä¸Šé™ã‚’è¶…ãˆã¾ã—ãŸã€‚è¶…éŽåˆ†ã¯è¡¨ç¤ºã—ã¾ã›ã‚“ã€‚'
-  text_custom_field_possible_values_info: 'é¸æŠžè‚¢ã®å€¤ã¯1è¡Œã«1å€‹ãšã¤è¨˜è¿°ã—ã¦ãã ã•ã„ã€‚'
-  text_wiki_page_destroy_question: "ã“ã®è¦ªãƒšãƒ¼ã‚¸ã®é…ä¸‹ã«%{descendants}ãƒšãƒ¼ã‚¸ã®å­å­«ãƒšãƒ¼ã‚¸ãŒã‚ã‚Šã¾ã™ã€‚"
-  text_wiki_page_nullify_children: "å­ãƒšãƒ¼ã‚¸ã‚’ãƒ¡ã‚¤ãƒ³ãƒšãƒ¼ã‚¸é…ä¸‹ã«ç§»å‹•ã™ã‚‹"
-  text_wiki_page_destroy_children: "é…ä¸‹ã®å­å­«ãƒšãƒ¼ã‚¸ã‚‚å‰Šé™¤ã™ã‚‹"
-  text_wiki_page_reassign_children: "å­ãƒšãƒ¼ã‚¸ã‚’æ¬¡ã®è¦ªãƒšãƒ¼ã‚¸ã®é…ä¸‹ã«ç§»å‹•ã™ã‚‹"
-  text_own_membership_delete_confirmation: "ä¸€éƒ¨ã¾ãŸã¯ã™ã¹ã¦ã®æ¨©é™ã‚’è‡ªåˆ†è‡ªèº«ã‹ã‚‰å‰¥å¥ªã—ã‚ˆã†ã¨ã—ã¦ã„ã‚‹ãŸã‚ã€ã“ã®ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã‚’ç·¨é›†ã§ããªããªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚\næœ¬å½“ã«ç¶šã‘ã¾ã™ã‹ï¼Ÿ"
-  text_zoom_in: æ‹¡å¤§
-  text_zoom_out: ç¸®å°
-  text_warn_on_leaving_unsaved: ã“ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰ç§»å‹•ã™ã‚‹ã¨ã€ä¿å­˜ã•ã‚Œã¦ã„ãªã„ãƒ‡ãƒ¼ã‚¿ãŒå¤±ã‚ã‚Œã¾ã™ã€‚
-  text_scm_path_encoding_note: "ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆ: UTF-8"
-  text_mercurial_repository_note: "ãƒ­ãƒ¼ã‚«ãƒ«ãƒªãƒã‚¸ãƒˆãƒª (ä¾‹: /hgrepo, c:\\hgrepo)"
-  text_git_repository_note: "Bareã€ã‹ã¤ã€ãƒ­ãƒ¼ã‚«ãƒ«ãƒªãƒã‚¸ãƒˆãƒª (ä¾‹: /gitrepo, c:\\gitrepo)"
-  text_scm_command: ã‚³ãƒžãƒ³ãƒ‰
-  text_scm_command_version: ãƒãƒ¼ã‚¸ãƒ§ãƒ³
-  text_scm_config: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã‚·ã‚¹ãƒ†ãƒ ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’config/configuration.ymlã§è¨­å®šã§ãã¾ã™ã€‚è¨­å®šå¾Œã€Redmineã‚’å†èµ·å‹•ã—ã¦ãã ã•ã„ã€‚
-  text_scm_command_not_available: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç®¡ç†ã‚·ã‚¹ãƒ†ãƒ ã®ã‚³ãƒžãƒ³ãƒ‰ãŒåˆ©ç”¨ã§ãã¾ã›ã‚“ã€‚ç®¡ç†ç”»é¢ã«ã¦è¨­å®šã‚’ç¢ºèªã—ã¦ãã ã•ã„ã€‚
-
-  default_role_manager: ç®¡ç†è€…
-  default_role_developer: é–‹ç™ºè€…
-  default_role_reporter: å ±å‘Šè€…
-  default_tracker_bug: ãƒã‚°
-  default_tracker_feature: æ©Ÿèƒ½
-  default_tracker_support: ã‚µãƒãƒ¼ãƒˆ
-  default_issue_status_new: æ–°è¦
-  default_issue_status_in_progress: é€²è¡Œä¸­
-  default_issue_status_resolved: è§£æ±º
-  default_issue_status_feedback: ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯
-  default_issue_status_closed: çµ‚äº†
-  default_issue_status_rejected: å´ä¸‹
-  default_doc_category_user: ãƒ¦ãƒ¼ã‚¶æ–‡æ›¸
-  default_doc_category_tech: æŠ€è¡“æ–‡æ›¸
-  default_priority_low: ä½Žã‚
-  default_priority_normal: é€šå¸¸
-  default_priority_high: é«˜ã‚
-  default_priority_urgent: æ€¥ã„ã§
-  default_priority_immediate: ä»Šã™ã
-  default_activity_design: è¨­è¨ˆä½œæ¥­
-  default_activity_development: é–‹ç™ºä½œæ¥­
-
-  enumeration_issue_priorities: ãƒã‚±ãƒƒãƒˆã®å„ªå…ˆåº¦
-  enumeration_doc_categories: æ–‡æ›¸ã‚«ãƒ†ã‚´ãƒª
-  enumeration_activities: ä½œæ¥­åˆ†é¡ž (æ™‚é–“ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°)
-  enumeration_system_activity: ã‚·ã‚¹ãƒ†ãƒ ä½œæ¥­åˆ†é¡ž
-  label_additional_workflow_transitions_for_assignee: ãƒã‚±ãƒƒãƒˆæ‹…å½“è€…ã«è¿½åŠ ã§è¨±å¯ã™ã‚‹é·ç§»
-  label_additional_workflow_transitions_for_author: ãƒã‚±ãƒƒãƒˆä½œæˆè€…ã«è¿½åŠ ã§è¨±å¯ã™ã‚‹é·ç§»
-  label_bulk_edit_selected_time_entries: ä½œæ¥­æ™‚é–“ã®ä¸€æ‹¬ç·¨é›†
-  text_time_entries_destroy_confirmation: æœ¬å½“ã«é¸æŠžã—ãŸä½œæ¥­æ™‚é–“ã‚’å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ
-
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-
-  label_issue_note_added: æ³¨è¨˜ãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸ
-  label_issue_status_updated: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ
-  label_issue_priority_updated: å„ªå…ˆåº¦ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ
-  label_issues_visibility_own: ä½œæˆè€…ã‹æ‹…å½“è€…ã§ã‚ã‚‹ãƒã‚±ãƒƒãƒˆ
-  field_issues_visibility: è¡¨ç¤ºã§ãã‚‹ãƒã‚±ãƒƒãƒˆ
-  label_issues_visibility_all: ã™ã¹ã¦ã®ãƒã‚±ãƒƒãƒˆ
-  permission_set_own_issues_private: è‡ªåˆ†ã®ãƒã‚±ãƒƒãƒˆã‚’ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆã«è¨­å®š
-  field_is_private: ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆ
-  permission_set_issues_private: ãƒã‚±ãƒƒãƒˆã‚’ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆã«è¨­å®š
-  label_issues_visibility_public: ãƒ—ãƒ©ã‚¤ãƒ™ãƒ¼ãƒˆãƒã‚±ãƒƒãƒˆä»¥å¤–
-  text_issues_destroy_descendants_confirmation: "%{count}å€‹ã®å­ãƒã‚±ãƒƒãƒˆã‚‚å‰Šé™¤ã•ã‚Œã¾ã™ã€‚"
-  notice_issue_successful_create: ãƒã‚±ãƒƒãƒˆ %{id} ãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚
-  label_between: æ¬¡ã®ç¯„å›²å†…
-  setting_issue_group_assignment: ã‚°ãƒ«ãƒ¼ãƒ—ã¸ã®ãƒã‚±ãƒƒãƒˆå‰²ã‚Šå½“ã¦ã‚’è¨±å¯
-  description_query_sort_criteria_direction: é †åº
-  description_project_scope: æ¤œç´¢ç¯„å›²
-  description_filter: Filter
-  description_user_mail_notification: ãƒ¡ãƒ¼ãƒ«é€šçŸ¥ã®è¨­å®š
-  description_date_from: é–‹å§‹æ—¥
-  description_message_content: å†…å®¹
-  description_available_columns: åˆ©ç”¨ã§ãã‚‹é …ç›®
-  description_date_range_interval: æ—¥ä»˜ã§æŒ‡å®š
-  description_issue_category_reassign: æ–°ã—ã„ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã¦ãã ã•ã„
-  description_search: æ¤œç´¢ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰
-  description_notes: æ³¨è¨˜
-  description_date_range_list: ä¸€è¦§ã‹ã‚‰é¸æŠž
-  description_choose_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆ
-  description_date_to: çµ‚äº†æ—¥
-  description_query_sort_criteria_attribute: é …ç›®
-  description_wiki_subpages_reassign: æ–°ã—ã„è¦ªãƒšãƒ¼ã‚¸ã‚’é¸æŠžã—ã¦ãã ã•ã„
-  description_selected_columns: é¸æŠžã•ã‚ŒãŸé …ç›®
-  error_scm_annotate_big_text_file: ãƒ†ã‚­ã‚¹ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ä¸Šé™ã‚’è¶…ãˆã¦ã„ã‚‹ãŸã‚ã‚¢ãƒŽãƒ†ãƒ¼ãƒˆã§ãã¾ã›ã‚“ã€‚
-  setting_default_issue_start_date_to_creation_date: ç¾åœ¨ã®æ—¥ä»˜ã‚’æ–°ã—ã„ãƒã‚±ãƒƒãƒˆã®é–‹å§‹æ—¥ã¨ã™ã‚‹
-  button_edit_section: ã“ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’ç·¨é›†
-  description_all_columns: ã™ã¹ã¦ã®é …ç›®
-  button_export: ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ
-  label_export_options: "%{export_format} ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆè¨­å®š"
-  error_attachment_too_big: ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã‚¢ãƒƒãƒ—ãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã€‚æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ä¸Šé™(%{max_size})ã‚’è¶…ãˆã¦ã„ã¾ã™ã€‚
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c6/c6ff1374312284d6c1b8200e5a3e6f1fba439441.svn-base
--- a/.svn/pristine/c6/c6ff1374312284d6c1b8200e5a3e6f1fba439441.svn-base
+++ /dev/null
@@ -1,112 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module WikiFormatting
-    class StaleSectionError < Exception; end
-
-    @@formatters = {}
-
-    class << self
-      def map
-        yield self
-      end
-
-      def register(name, formatter, helper)
-        raise ArgumentError, "format name '#{name}' is already taken" if @@formatters[name.to_s]
-        @@formatters[name.to_s] = {:formatter => formatter, :helper => helper}
-      end
-
-      def formatter
-        formatter_for(Setting.text_formatting)
-      end
-
-      def formatter_for(name)
-        entry = @@formatters[name.to_s]
-        (entry && entry[:formatter]) || Redmine::WikiFormatting::NullFormatter::Formatter
-      end
-
-      def helper_for(name)
-        entry = @@formatters[name.to_s]
-        (entry && entry[:helper]) || Redmine::WikiFormatting::NullFormatter::Helper
-      end
-
-      def format_names
-        @@formatters.keys.map
-      end
-
-      def to_html(format, text, options = {})
-        text = if Setting.cache_formatted_text? && text.size > 2.kilobyte && cache_store && cache_key = cache_key_for(format, options[:object], options[:attribute])
-          # Text retrieved from the cache store may be frozen
-          # We need to dup it so we can do in-place substitutions with gsub!
-          cache_store.fetch cache_key do
-            formatter_for(format).new(text).to_html
-          end.dup
-        else
-          formatter_for(format).new(text).to_html
-        end
-        text
-      end
-
-      # Returns true if the text formatter supports single section edit
-      def supports_section_edit?
-        (formatter.instance_methods & ['update_section', :update_section]).any?
-      end
-
-      # Returns a cache key for the given text +format+, +object+ and +attribute+ or nil if no caching should be done
-      def cache_key_for(format, object, attribute)
-        if object && attribute && !object.new_record? && object.respond_to?(:updated_on) && !format.blank?
-          "formatted_text/#{format}/#{object.class.model_name.cache_key}/#{object.id}-#{attribute}-#{object.updated_on.to_s(:number)}"
-        end
-      end
-
-      # Returns the cache store used to cache HTML output
-      def cache_store
-        ActionController::Base.cache_store
-      end
-    end
-
-    # Default formatter module
-    module NullFormatter
-      class Formatter
-        include ActionView::Helpers::TagHelper
-        include ActionView::Helpers::TextHelper
-        include ActionView::Helpers::UrlHelper
-
-        def initialize(text)
-          @text = text
-        end
-
-        def to_html(*args)
-          simple_format(auto_link(CGI::escapeHTML(@text)))
-        end
-      end
-
-      module Helper
-        def wikitoolbar_for(field_id)
-        end
-
-        def heads_for_wiki_formatter
-        end
-
-        def initial_page_content(page)
-          page.pretty_title.to_s
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c7537906149075d910ea5c8b0b1bfdd4bc722018.svn-base
--- /dev/null
+++ b/.svn/pristine/c7/c7537906149075d910ea5c8b0b1bfdd4bc722018.svn-base
@@ -0,0 +1,6 @@
+<h3><%= l(:label_calendar) %></h3>
+
+<% calendar = Redmine::Helpers::Calendar.new(Date.today, current_language, :week)
+   calendar.events = calendar_items(calendar.startdt, calendar.enddt) %>
+
+<%= render :partial => 'common/calendar', :locals => {:calendar => calendar } %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c776d4773c045c08108bca39e768c557cd3d3f3c.svn-base
--- /dev/null
+++ b/.svn/pristine/c7/c776d4773c045c08108bca39e768c557cd3d3f3c.svn-base
@@ -0,0 +1,39 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module RoutesHelper
+
+  # Returns the path to project issues or to the cross-project
+  # issue list if project is nil
+  def _project_issues_path(project, *args)
+    if project
+      project_issues_path(project, *args)
+    else
+      issues_path(*args)
+    end
+  end
+
+  def _project_calendar_path(project, *args)
+    project ? project_calendar_path(project, *args) : issues_calendar_path(*args)
+  end
+
+  def _project_gantt_path(project, *args)
+    project ? project_gantt_path(project, *args) : issues_gantt_path(*args)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c7847076c2df1da6c67e052fc800303ce438f4c9.svn-base
--- a/.svn/pristine/c7/c7847076c2df1da6c67e052fc800303ce438f4c9.svn-base
+++ /dev/null
@@ -1,1003 +0,0 @@
-sk:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y-%m-%d"
-      short: "%b %d"
-      long: "%B %d, %Y"
-      
-    day_names: [NedeÄ¾a, Pondelok, Utorok, Streda, Å tvrtok, Piatok, Sobota]
-    abbr_day_names: [Ne, Po, Ut, St, Å t, Pi, So]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, JanuÃ¡r, FebruÃ¡r, Marec, AprÃ­l, MÃ¡j, JÃºn, JÃºl, August, September, OktÃ³ber, November, December]
-    abbr_month_names: [~, Jan, Feb, Mar, Apr, MÃ¡j, JÃºn, JÃºl, Aug, Sep, Okt, Nov, Dec]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%a, %d %b %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "am"
-    pm: "pm"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "pol minÃºty"
-      less_than_x_seconds:
-        one:   "menej ako 1 sekunda"
-        other: "menej ako %{count} sekÃºnd"
-      x_seconds:
-        one:   "1 sekunda"
-        other: "%{count} sekÃºnd"
-      less_than_x_minutes:
-        one:   "menej ako minÃºta"
-        other: "menej ako %{count} minÃºt"
-      x_minutes:
-        one:   "1 minuta"
-        other: "%{count} minÃºt"
-      about_x_hours:
-        one:   "okolo 1 hodiny"
-        other: "okolo %{count} hodÃ­n"
-      x_days:
-        one:   "1 deÅˆ"
-        other: "%{count} dnÃ­"
-      about_x_months:
-        one:   "okolo 1 mesiaca"
-        other: "okolo %{count} mesiace/ov"
-      x_months:
-        one:   "1 mesiac"
-        other: "%{count} mesiace/ov"
-      about_x_years:
-        one:   "okolo 1 roka"
-        other: "okolo %{count} roky/ov"
-      over_x_years:
-        one:   "cez 1 rok"
-        other: "cez %{count} roky/ov"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-
-  number: 
-    human: 
-      format: 
-        precision: 1
-        delimiter: ""
-      storage_units: 
-        format: "%n %u"
-        units: 
-          kb: KB
-          tb: TB
-          gb: GB
-          byte: 
-            one: Byte
-            other: Bytes
-          mb: MB
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "a"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "nieje zahrnutÃ© v zozname"
-        exclusion: "je rezervovanÃ©"
-        invalid: "je neplatnÃ©"
-        confirmation: "sa nezhoduje s potvrdenÃ­m"
-        accepted: "musÃ­ byÅ¥ akceptovanÃ©"
-        empty: "nemÃ´Å¾e byÅ¥ prÃ¡zdne"
-        blank: "nemÃ´Å¾e byÅ¥ prÃ¡zdne"
-        too_long: "je prÃ­liÅ¡ dlhÃ©"
-        too_short: "je prÃ­liÅ¡ krÃ¡tke"
-        wrong_length: "mÃ¡ chybnÃº dÄºÅ¾ku"
-        taken: "je uÅ¾ pouÅ¾itÃ©"
-        not_a_number: "nieje ÄÃ­slo"
-        not_a_date: "nieje platnÃ½ dÃ¡tum"
-        greater_than: "musÃ­ byÅ¥ vÃ¤ÄÅ¡Ã­e ako %{count}"
-        greater_than_or_equal_to: "musÃ­ byÅ¥ vÃ¤ÄÅ¡ie alebo rovnÃ© %{count}"
-        equal_to: "musÃ­ byÅ¥ rovnÃ© %{count}"
-        less_than: "musÃ­ byÅ¥ menej ako %{count}"
-        less_than_or_equal_to: "musÃ­ byÅ¥ menej alebo rovnÃ© %{count}"
-        odd: "musÃ­ byÅ¥ nepÃ¡rne"
-        even: "musÃ­ byÅ¥ pÃ¡rne"
-        greater_than_start_date: "musÃ­ byÅ¥ neskÃ´r ako poÄiatoÄnÃ½ dÃ¡tum"
-        not_same_project: "nepatrÃ­ rovnakÃ©mu projektu"
-        circular_dependency: "Tento vzÅ¥ah by vytvoril cyklickÃº zÃ¡vislosÅ¥"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  # SK translation by Stanislav Pach | stano.pach@seznam.cz
-  
-  actionview_instancetag_blank_option: ProsÃ­m vyberte
-  
-  general_text_No: 'Nie'
-  general_text_Yes: 'Ãno'
-  general_text_no: 'nie'
-  general_text_yes: 'Ã¡no'
-  general_lang_name: 'SlovenÄina'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: ÃšÄet bol ÃºspeÅ¡ne zmenenÃ½.
-  notice_account_invalid_creditentials: ChybnÃ© meno alebo heslo
-  notice_account_password_updated: Heslo bolo ÃºspeÅ¡ne zmenenÃ©.
-  notice_account_wrong_password: ChybnÃ© heslo
-  notice_account_register_done: ÃšÄet bol ÃºspeÅ¡ne vytvorenÃ½. Pre aktivÃ¡ciu ÃºÄtu kliknite na odkaz v emailu, ktorÃ½ vam bol zaslanÃ½.
-  notice_account_unknown_email: NeznÃ¡my uÅ¾Ã­vateÄ¾.
-  notice_can_t_change_password: Tento ÃºÄet pouÅ¾Ã­va externÃº autentifikÃ¡ciu. Tu heslo zmeniÅ¥ nemÃ´Å¾ete.
-  notice_account_lost_email_sent: Bol vÃ¡m zaslanÃ½ email s inÅ¡trukciami ako si nastavite novÃ© heslo.
-  notice_account_activated: VÃ¡Å¡ ÃºÄet bol aktivovanÃ½. Teraz se mÃ´Å¾ete prihlÃ¡siÅ¥.
-  notice_successful_create: ÃšspeÅ¡ne vytvorenÃ©.
-  notice_successful_update: ÃšspeÅ¡ne aktualizovanÃ©.
-  notice_successful_delete: ÃšspeÅ¡ne odstrÃ¡nenÃ©.
-  notice_successful_connection: ÃšspeÅ¡ne pripojenÃ©.
-  notice_file_not_found: StrÃ¡nka, ktorÃº se snaÅ¾Ã­te zobraziÅ¥, neexistuje alebo bola zmazanÃ¡.
-  notice_locking_conflict: Ãšdaje boli zmenenÃ© inÃ½m uÅ¾Ã­vateÄ¾om.
-  notice_scm_error: PoloÅ¾ka a/alebo revÃ­zia neexistuje v repozitÃ¡ri.
-  notice_not_authorized: NemÃ¡te dostatoÄnÃ© prÃ¡va pre zobrazenie tejto strÃ¡nky.
-  notice_email_sent: "Na adresu %{value} bol odeslanÃ½ email"
-  notice_email_error: "Pri odosielanÃ­ emailu nastala chyba (%{value})"
-  notice_feeds_access_key_reseted: VÃ¡Å¡ klÃºÄ pre prÃ­stup k Atomu bol resetovanÃ½.
-  notice_failed_to_save_issues: "Nastala chyba pri uklÃ¡danÃ­ %{count} Ãºloh na %{total} zvolenÃ½: %{ids}."
-  notice_no_issue_selected: "Nebola zvolenÃ¡ Å¾iadnÃ¡ Ãºloha. ProsÃ­m, zvoÄ¾te Ãºlohy, ktorÃ© chcete upraviÅ¥"
-  notice_account_pending: "VÃ¡Å¡ ÃºÄet bol vytvorenÃ½, teraz ÄakÃ¡ na schvÃ¡lenie administrÃ¡torom."
-  notice_default_data_loaded: VÃ½chozia konfigurÃ¡cia ÃºspeÅ¡ne nahranÃ¡.
-  
-  error_can_t_load_default_data: "VÃ½chozia konfigurÃ¡cia nebola nahranÃ¡: %{value}"
-  error_scm_not_found: "PoloÅ¾ka a/alebo revÃ­zia neexistuje v repozitÃ¡ri."
-  error_scm_command_failed: "Pri pokuse o prÃ­stup k repozitÃ¡ri doÅ¡lo k chybe: %{value}"
-  error_issue_not_found_in_project: 'Ãšloha nebola nÃ¡jdenÃ¡ alebo nepatrÃ­ k tomuto projektu'
-  
-  mail_subject_lost_password: "VaÅ¡e heslo (%{value})"
-  mail_body_lost_password: 'Pre zmenu vaÅ¡eho hesla kliknite na nÃ¡sledujÃºci odkaz:'
-  mail_subject_register: "AktivÃ¡cia ÃºÄtu (%{value})"
-  mail_body_register: 'Pre aktivÃ¡ciu vaÅ¡eho ÃºÄtu kliknite na nÃ¡sledujÃºci odkaz:'
-  mail_body_account_information_external: "Pomocou vaÅ¡eho ÃºÄtu %{value} se mÃ´Å¾ete prihlÃ¡siÅ¥."
-  mail_body_account_information: InformÃ¡cie o vaÅ¡om ÃºÄte
-  mail_subject_account_activation_request: "AktivÃ¡cia %{value} ÃºÄtu"
-  mail_body_account_activation_request: "Bol zaregistrovanÃ½ novÃ½ uÅ¾ivateÄ¾ %{value}. AktivÃ¡cia jeho ÃºÄtu zÃ¡visÃ­ na vaÅ¡om potvrdenÃ­."
-  
-  gui_validation_error: 1 chyba
-  gui_validation_error_plural: "%{count} chyb(y)"
-  
-  field_name: NÃ¡zov
-  field_description: Popis
-  field_summary: PrehÄ¾ad
-  field_is_required: PovinnÃ© pole
-  field_firstname: Meno
-  field_lastname: Priezvisko
-  field_mail: Email
-  field_filename: SÃºbor
-  field_filesize: VeÄ¾kosÅ¥
-  field_downloads: StiahnutÃ©
-  field_author: Autor
-  field_created_on: VytvorenÃ©
-  field_updated_on: AktualizovanÃ©
-  field_field_format: FormÃ¡t
-  field_is_for_all: Pre vÅ¡etky projekty
-  field_possible_values: MoÅ¾nÃ© hodnoty
-  field_regexp: RegulÃ©rny vÃ½raz
-  field_min_length: MinimÃ¡lna dÄºÅ¾ka
-  field_max_length: MaximÃ¡lna dÄºÅ¾ka
-  field_value: Hodnota
-  field_category: KategÃ³ria
-  field_title: NÃ¡zov
-  field_project: Projekt
-  field_issue: Ãšloha
-  field_status: Stav
-  field_notes: PoznÃ¡mka
-  field_is_closed: Ãšloha uzavretÃ¡
-  field_is_default: VÃ½chodzÃ­ stav
-  field_tracker: Fronta
-  field_subject: Predmet
-  field_due_date: UzavrieÅ¥ do
-  field_assigned_to: PriradenÃ©
-  field_priority: Priorita
-  field_fixed_version: PriradenÃ© k verzii
-  field_user: UÅ¾Ã­vateÄ¾
-  field_role: Rola
-  field_homepage: DomovskÃ¡ strÃ¡nka
-  field_is_public: VerejnÃ½
-  field_parent: NadradenÃ½ projekt
-  field_is_in_roadmap: Ãšlohy zobrazenÃ© v plÃ¡ne
-  field_login: Login
-  field_mail_notification: EmailovÃ© oznÃ¡menie
-  field_admin: AdministrÃ¡tor
-  field_last_login_on: PoslednÃ© prihlÃ¡senie
-  field_language: Jazyk
-  field_effective_date: DÃ¡tum
-  field_password: Heslo
-  field_new_password: NovÃ© heslo
-  field_password_confirmation: Potvrdenie
-  field_version: Verzia
-  field_type: Typ
-  field_host: Host
-  field_port: Port
-  field_account: ÃšÄet
-  field_base_dn: Base DN
-  field_attr_login: PrihlÃ¡senie (atribut)
-  field_attr_firstname: Meno (atribut)
-  field_attr_lastname: Priezvisko (atribut)
-  field_attr_mail: Email (atribut)
-  field_onthefly: AutomatickÃ© vytvÃ¡ranie uÅ¾Ã­vateÄ¾ov
-  field_start_date: ZaÄiatok
-  field_done_ratio: "% hotovo"
-  field_auth_source: AutentifikaÄnÃ½ mÃ³d
-  field_hide_mail: NezobrazovaÅ¥ mÃ´j email
-  field_comments: KomentÃ¡r
-  field_url: URL
-  field_start_page: VÃ½chozia strÃ¡nka
-  field_subproject: Podprojekt
-  field_hours: Hodiny
-  field_activity: Aktivita
-  field_spent_on: DÃ¡tum
-  field_identifier: IdentifikÃ¡tor
-  field_is_filter: PouÅ¾iÅ¥ ako filter
-  field_issue_to: SÃºvisiaca Ãºloha
-  field_delay: Oneskorenie
-  field_assignable: Ãšlohy mÃ´Å¾u byÅ¥ priradenÃ© tejto roli
-  field_redirect_existing_links: PresmerovaÅ¥ existujÃºce odkazy
-  field_estimated_hours: OdhadovanÃ¡ doba
-  field_column_names: StÄºpce
-  field_time_zone: ÄŒasovÃ© pÃ¡smo
-  field_searchable: UmoÅ¾niÅ¥ vyhÄ¾adÃ¡vanie
-  field_default_value: VÃ½chodzia hodnota
-  field_comments_sorting: ZobraziÅ¥ komentÃ¡re
-  
-  setting_app_title: NÃ¡zov aplikÃ¡cie
-  setting_app_subtitle: Podtitulok aplikÃ¡cie
-  setting_welcome_text: UvÃ­tacÃ­ text
-  setting_default_language: VÃ½chodzÃ­ jazyk
-  setting_login_required: Auten. vyÅ¾adovanÃ¡
-  setting_self_registration: Povolenie registrÃ¡cie
-  setting_attachment_max_size: MaximÃ¡lna veÄ¾kosÅ¥ prÃ­lohy
-  setting_issues_export_limit: Limit pre export Ãºloh
-  setting_mail_from: OdosielaÅ¥ emaily z adresy
-  setting_bcc_recipients: PrÃ­jemcovia skrytej kÃ³pie (bcc)
-  setting_host_name: Hostname
-  setting_text_formatting: FormÃ¡tovanie textu
-  setting_wiki_compression: Kompresia histÃ³rie Wiki 
-  setting_feeds_limit: Limit zobrazenÃ½ch poloÅ¾iek (Atom feed)
-  setting_default_projects_public: NovÃ© projekty nastavovaÅ¥ ako verejnÃ©
-  setting_autofetch_changesets: AutomatickÃ½ prenos zmien
-  setting_sys_api_enabled: Povolit WebovÃº SluÅ¾bu (WS) pre sprÃ¡vu repozitÃ¡ra
-  setting_commit_ref_keywords: KlÃºÄovÃ© slovÃ¡ pre odkazy
-  setting_commit_fix_keywords: KlÃºÄovÃ© slovÃ¡ pre uzavretie
-  setting_autologin: AutomatickÃ© prihlasovanie
-  setting_date_format: FormÃ¡t dÃ¡tumu
-  setting_time_format: FormÃ¡t Äasu
-  setting_cross_project_issue_relations: PovoliÅ¥ vÃ¤zby Ãºloh skrz projekty
-  setting_issue_list_default_columns: VÃ½chodzie stÄºpce zobrazenÃ© v zozname Ãºloh
-  setting_ itories_encodings: KÃ³dovanie 
-  setting_emails_footer: ZapÃ¤tie emailov
-  setting_protocol: Protokol
-  setting_per_page_options: PovolenÃ© mnoÅ¾stvo riadkov na strÃ¡nke
-  setting_user_format: FormÃ¡t zobrazenia uÅ¾Ã­vateÄ¾a
-  setting_activity_days_default: "ZobrazenÃ© dni aktivity projektu:" 
-  setting_display_subprojects_issues: Prednastavenie zobrazenia Ãºloh podporojektov v hlavnom projekte
-  
-  project_module_issue_tracking: Sledovanie Ãºloh
-  project_module_time_tracking: Sledovanie Äasu
-  project_module_news: Novinky
-  project_module_documents: Dokumenty
-  project_module_files: SÃºbory
-  project_module_wiki: Wiki 
-  project_module_repository: RepozitÃ¡r
-  project_module_boards: Diskusie
-  
-  label_user: UÅ¾Ã­vateÄ¾
-  label_user_plural: UÅ¾Ã­vatelia
-  label_user_new: NovÃ½ uÅ¾Ã­vateÄ¾
-  label_project: Projekt
-  label_project_new: NovÃ½ projekt
-  label_project_plural: Projekty
-  label_x_projects:
-    zero:  Å¾iadne projekty
-    one:   1 projekt
-    other: "%{count} projekty/ov"
-  label_project_all: VÅ¡etky projekty
-  label_project_latest: PoslednÃ© projekty
-  label_issue: Ãšloha
-  label_issue_new: NovÃ¡ Ãºloha
-  label_issue_plural: Ãšlohy
-  label_issue_view_all: VÅ¡etky Ãºlohy
-  label_issues_by: "Ãšlohy od uÅ¾Ã­vateÄ¾a %{value}"
-  label_issue_added: Ãšloha pridanÃ¡
-  label_issue_updated: Ãšloha aktualizovanÃ¡
-  label_document: Dokument
-  label_document_new: NovÃ½ dokument
-  label_document_plural: Dokumenty
-  label_document_added: Dokument pridanÃ½
-  label_role: Rola
-  label_role_plural: Role
-  label_role_new: NovÃ¡ rola
-  label_role_and_permissions: Role a prÃ¡va
-  label_member: ÄŒlen
-  label_member_new: NovÃ½ Älen
-  label_member_plural: ÄŒlenovia
-  label_tracker: Fronta
-  label_tracker_plural: Fronty
-  label_tracker_new: NovÃ¡ fronta
-  label_workflow: Workflow
-  label_issue_status: Stav Ãºloh
-  label_issue_status_plural: Stavy Ãºloh
-  label_issue_status_new: NovÃ½ stav
-  label_issue_category: KategÃ³ria Ãºloh
-  label_issue_category_plural: KategÃ³rie Ãºloh
-  label_issue_category_new: NovÃ¡ kategÃ³ria
-  label_custom_field: UÅ¾Ã­vateÄ¾skÃ© pole
-  label_custom_field_plural: UÅ¾Ã­vateÄ¾skÃ© polia
-  label_custom_field_new: NovÃ© uÅ¾Ã­vateÄ¾skÃ© pole
-  label_enumerations: Zoznamy
-  label_enumeration_new: NovÃ¡ hodnota
-  label_information: InformÃ¡cia
-  label_information_plural: InformÃ¡cie
-  label_please_login: ProsÃ­m prihlÃ¡ste sa
-  label_register: RegistrovaÅ¥
-  label_password_lost: ZabudnutÃ© heslo
-  label_home: DomovskÃ¡ strÃ¡nka
-  label_my_page: Moja strÃ¡nka
-  label_my_account: MÃ´j ÃºÄet
-  label_my_projects: Moje projekty
-  label_administration: AdministrÃ¡cia
-  label_login: PrihlÃ¡senie
-  label_logout: OdhlÃ¡senie
-  label_help: NÃ¡poveda
-  label_reported_issues: NahlÃ¡senÃ© Ãºlohy
-  label_assigned_to_me_issues: Moje Ãºlohy
-  label_last_login: PoslednÃ© prihlÃ¡senie
-  label_registered_on: RegistrovanÃ½
-  label_activity: Aktivita
-  label_overall_activity: CelkovÃ¡ aktivita
-  label_new: NovÃ½
-  label_logged_as: PrihlÃ¡senÃ½ ako
-  label_environment: Prostredie
-  label_authentication: AutentifikÃ¡cia
-  label_auth_source: MÃ³d autentifikÃ¡cie
-  label_auth_source_new: NovÃ½ mÃ³d autentifikÃ¡cie
-  label_auth_source_plural: MÃ³dy autentifikÃ¡cie
-  label_subproject_plural: Podprojekty
-  label_min_max_length: Min - Max dÄºÅ¾ka
-  label_list: Zoznam
-  label_date: DÃ¡tum
-  label_integer: CelÃ© ÄÃ­slo
-  label_float: DesatinnÃ© ÄÃ­slo
-  label_boolean: Ãno/Nie
-  label_string: Text
-  label_text: DlhÃ½ text
-  label_attribute: Atribut
-  label_attribute_plural: Atributy
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloady"
-  label_no_data: Å½iadnÃ© poloÅ¾ky
-  label_change_status: ZmeniÅ¥ stav
-  label_history: HistÃ³ria
-  label_attachment: SÃºbor
-  label_attachment_new: NovÃ½ sÃºbor
-  label_attachment_delete: OdstrÃ¡niÅ¥ sÃºbor
-  label_attachment_plural: SÃºbory
-  label_file_added: SÃºbor pridanÃ½
-  label_report: PrehÄ¾ad
-  label_report_plural: PrehÄ¾ady
-  label_news: Novinky
-  label_news_new: PridaÅ¥ novinku
-  label_news_plural: Novinky
-  label_news_latest: PoslednÃ© novinky
-  label_news_view_all: Zobrazit vÅ¡etky novinky
-  label_news_added: Novinka pridanÃ¡
-  label_settings: Nastavenie
-  label_overview: PrehÄ¾ad
-  label_version: Verzia
-  label_version_new: NovÃ¡ verzia
-  label_version_plural: Verzie
-  label_confirmation: Potvrdenie
-  label_export_to: 'TieÅ¾ k dispozÃ­ciÃ­:'
-  label_read: NaÄÃ­ta sa...
-  label_public_projects: VerejnÃ© projekty
-  label_open_issues: OtvorenÃ½
-  label_open_issues_plural: OtvorenÃ©
-  label_closed_issues: UzavrenÃ½
-  label_closed_issues_plural: UzavrenÃ©
-  label_x_open_issues_abbr_on_total:
-    zero:  0 otvorenÃ½ch z celkovo %{total}
-    one:   1 otvorenÃ½ z celkovo %{total}
-    other: "%{count} otvorenÃ©/Ã½ch z celkovo %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 otvorenÃ½ch
-    one:   1 otvorenÃ½
-    other: "%{count} otvorenÃ©/Ã½ch"
-  label_x_closed_issues_abbr:
-    zero:  0 zavretÃ½ch
-    one:   1 zavretÃ½
-    other: "%{count} zavretÃ©/Ã½ch"
-  label_total: Celkovo
-  label_permissions: PrÃ¡va
-  label_current_status: AktuÃ¡lny stav
-  label_new_statuses_allowed: NovÃ© povolenÃ© stavy
-  label_all: vÅ¡etko
-  label_none: niÄ
-  label_nobody: nikto
-  label_next: ÄŽalÅ¡Ã­
-  label_previous: PredchÃ¡dzajÃºci
-  label_used_by: PouÅ¾itÃ©
-  label_details: Detaily
-  label_add_note: PridaÅ¥ poznÃ¡mku
-  label_per_page: Na strÃ¡nku
-  label_calendar: KalendÃ¡r
-  label_months_from: mesiacov od
-  label_gantt: Ganttov graf
-  label_internal: InternÃ½
-  label_last_changes: "poslednÃ½ch %{count} zmien"
-  label_change_view_all: ZobraziÅ¥ vÅ¡etky zmeny
-  label_personalize_page: PrispÃ´sobiÅ¥ tÃºto strÃ¡nku
-  label_comment: KomentÃ¡r
-  label_comment_plural: KomentÃ¡re
-  label_x_comments:
-    zero: Å¾iaden komentÃ¡r
-    one: 1 komentÃ¡r
-    other: "%{count} komentÃ¡re/ov"
-  label_comment_add: PridaÅ¥ komentÃ¡r
-  label_comment_added: KomentÃ¡r pridanÃ½
-  label_comment_delete: OdstrÃ¡niÅ¥ komentÃ¡r
-  label_query: UÅ¾Ã­vateÄ¾skÃ½ dotaz
-  label_query_plural: UÅ¾Ã­vateÄ¾skÃ© dotazy
-  label_query_new: NovÃ½ dotaz
-  label_filter_add: PridaÅ¥ filter
-  label_filter_plural: Filtre
-  label_equals: je
-  label_not_equals: nieje
-  label_in_less_than: je menÅ¡Ã­ ako
-  label_in_more_than: je vÃ¤ÄÅ¡Ã­ ako
-  label_in: v
-  label_today: dnes
-  label_all_time: vÅ¾dy
-  label_yesterday: vÄera
-  label_this_week: tento tÃ½Å¾deÅˆ
-  label_last_week: minulÃ½ tÃ½Å¾deÅˆ
-  label_last_n_days: "poslednÃ½ch %{count} dnÃ­"
-  label_this_month: tento mesiac
-  label_last_month: minulÃ½ mesiac
-  label_this_year: tento rok
-  label_date_range: ÄŒasovÃ½ rozsah
-  label_less_than_ago: pred menej ako (dÅˆami)
-  label_more_than_ago: pred viac ako (dÅˆami)
-  label_ago: pred (dÅˆami)
-  label_contains: obsahuje
-  label_not_contains: neobsahuje
-  label_day_plural: dnÃ­
-  label_repository: RepozitÃ¡r
-  label_repository_plural: RepozitÃ¡re
-  label_browse: PrechÃ¡dzaÅ¥
-  label_modification: "%{count} zmena"
-  label_modification_plural: "%{count} zmien"
-  label_revision: RevÃ­zia
-  label_revision_plural: RevÃ­ziÃ­
-  label_associated_revisions: SÃºvisiace verzie
-  label_added: pridanÃ©
-  label_modified: zmenenÃ©
-  label_deleted: odstrÃ¡nenÃ©
-  label_latest_revision: PoslednÃ¡ revÃ­zia
-  label_latest_revision_plural: PoslednÃ© revÃ­zie
-  label_view_revisions: ZobraziÅ¥ revÃ­zie
-  label_max_size: MaximÃ¡lna veÄ¾kosÅ¥
-  label_sort_highest: PresunÃºÅ¥ na zaÄiatok
-  label_sort_higher: PresunÃºÅ¥ navrch
-  label_sort_lower: PresunÃºÅ¥ dole
-  label_sort_lowest: PresunÃºÅ¥ na koniec
-  label_roadmap: PlÃ¡n
-  label_roadmap_due_in: "ZostÃ¡va %{value}"
-  label_roadmap_overdue: "%{value} neskoro"
-  label_roadmap_no_issues: Pre tÃºto verziu niesÃº Å¾iadne Ãºlohy
-  label_search: HÄ¾adaÅ¥
-  label_result_plural: VÃ½sledky
-  label_all_words: VÅ¡etky slova
-  label_wiki: Wiki 
-  label_wiki_edit: Wiki Ãºprava
-  label_wiki_edit_plural: Wiki Ãºpravy
-  label_wiki_page: Wiki strÃ¡nka
-  label_wiki_page_plural: Wiki strÃ¡nky
-  label_index_by_title: Index podÄ¾a nÃ¡zvu
-  label_index_by_date: Index podÄ¾a dÃ¡tumu
-  label_current_version: AktuÃ¡lna verzia
-  label_preview: NÃ¡hÄ¾ad
-  label_feed_plural: PrÃ­spevky
-  label_changes_details: Detail vÅ¡etkÃ½ch zmien
-  label_issue_tracking: Sledovanie Ãºloh
-  label_spent_time: StrÃ¡venÃ½ Äas
-  label_f_hour: "%{value} hodina"
-  label_f_hour_plural: "%{value} hodÃ­n"
-  label_time_tracking: SledovÃ¡nie Äasu
-  label_change_plural: Zmeny
-  label_statistics: Å tatistiky
-  label_commits_per_month: Ãškony za mesiac
-  label_commits_per_author: Ãškony podÄ¾a autora
-  label_view_diff: Zobrazit rozdiely
-  label_diff_inline: vo vnÃºtri
-  label_diff_side_by_side: vedÄ¾a seba
-  label_options: Nastavenie
-  label_copy_workflow_from: KopÃ­rovaÅ¥ workflow z
-  label_permissions_report: PrehÄ¾ad prÃ¡v
-  label_watched_issues: SledovanÃ© Ãºlohy
-  label_related_issues: SÃºvisiace Ãºlohy
-  label_applied_status: PouÅ¾itÃ½ stav
-  label_loading: NahrÃ¡vam ...
-  label_relation_new: NovÃ¡ sÃºvislosÅ¥
-  label_relation_delete: OdstrÃ¡niÅ¥ sÃºvislosÅ¥
-  label_relates_to: sÃºvisiacÃ­ s
-  label_duplicates: duplicity
-  label_blocks: blokovanÃ½
-  label_blocked_by: zablokovanÃ½
-  label_precedes: predchÃ¡za
-  label_follows: nÃ¡sleduje
-  label_end_to_start: od konca na zaÄiatok
-  label_end_to_end: od konca do konca
-  label_start_to_start: od zaÄiatku do zaÄiatku
-  label_start_to_end: od zaÄiatku do konca
-  label_stay_logged_in: ZostaÅ¥ prihlÃ¡senÃ½
-  label_disabled: zakazanÃ©
-  label_show_completed_versions: UkÃ¡zaÅ¥ dokonÄenÃ© verzie
-  label_me: ja
-  label_board: FÃ³rum
-  label_board_new: NovÃ© fÃ³rum
-  label_board_plural: FÃ³ra
-  label_topic_plural: TÃ©my
-  label_message_plural: SprÃ¡vy
-  label_message_last: PoslednÃ¡ sprÃ¡va
-  label_message_new: NovÃ¡ sprÃ¡va
-  label_message_posted: SprÃ¡va pridanÃ¡
-  label_reply_plural: Odpovede
-  label_send_information: ZaslaÅ¥ informÃ¡cie o ÃºÄte uÅ¾Ã­vateÄ¾a
-  label_year: Rok
-  label_month: Mesiac
-  label_week: TÃ½Å¾den
-  label_date_from: Od
-  label_date_to: Do
-  label_language_based: PodÄ¾a vÃ½chozieho jazyka
-  label_sort_by: "Zoradenie podÄ¾a %{value}"
-  label_send_test_email: PoslaÅ¥ testovacÃ­ email
-  label_feeds_access_key_created_on: "PrÃ­stupovÃ½ klÃºÄ pre RSS bol vytvorenÃ½ pred %{value}"
-  label_module_plural: Moduly
-  label_added_time_by: "PridanÃ© uÅ¾Ã­vateÄ¾om %{author} pred %{age}"
-  label_updated_time: "AktualizovanÃ© pred %{value}"
-  label_jump_to_a_project: ZvoliÅ¥ projekt...
-  label_file_plural: SÃºbory
-  label_changeset_plural: Sady zmien
-  label_default_columns: VÃ½chodzie stÄºpce
-  label_no_change_option: (bez zmeny)
-  label_bulk_edit_selected_issues: SkupinovÃ¡ Ãºprava vybranÃ½ch Ãºloh
-  label_theme: TÃ©ma
-  label_default: VÃ½chodzÃ­
-  label_search_titles_only: VyhÄ¾adÃ¡vaÅ¥ iba v nÃ¡zvoch
-  label_user_mail_option_all: "Pre vÅ¡etky udÃ¡losti vÅ¡etkÃ½ch mojÃ­ch projektov"
-  label_user_mail_option_selected: "Pre vÅ¡etky udÃ¡losti vybranÃ½ch projektov"
-  label_user_mail_no_self_notified: "NezasielaÅ¥ informÃ¡cie o mnou vytvorenÃ½ch zmenÃ¡ch"
-  label_registration_activation_by_email: aktivÃ¡cia ÃºÄtu emailom
-  label_registration_manual_activation: manuÃ¡lna aktivÃ¡cia ÃºÄtu
-  label_registration_automatic_activation: automatickÃ¡ aktivÃ¡cia ÃºÄtu
-  label_display_per_page: "%{value} na strÃ¡nku"
-  label_age: Vek
-  label_change_properties: ZmeniÅ¥ vlastnosti
-  label_general: VÅ¡eobecnÃ©
-  label_more: Viac
-  label_scm: SCM
-  label_plugins: Pluginy
-  label_ldap_authentication: AutentifikÃ¡cia LDAP
-  label_downloads_abbr: D/L
-  label_optional_description: VoliteÄ¾nÃ½ popis
-  label_add_another_file: PridaÅ¥ ÄaÄ¾Å¡Ã­ sÃºbor
-  label_preferences: Nastavenia
-  label_chronological_order: V chronologickom poradÃ­
-  label_reverse_chronological_order: V obrÃ¡tenom chronologickom poradÃ­
-  
-  button_login: PrihlÃ¡siÅ¥
-  button_submit: PotvrdiÅ¥
-  button_save: UloÅ¾iÅ¥
-  button_check_all: OznaÄiÅ¥ vÅ¡etko
-  button_uncheck_all: OdznaÄiÅ¥ vÅ¡etko
-  button_delete: OdstrÃ¡niÅ¥
-  button_create: VytvoriÅ¥
-  button_test: Test
-  button_edit: UpraviÅ¥
-  button_add: PridaÅ¥
-  button_change: ZmeniÅ¥
-  button_apply: PouÅ¾iÅ¥
-  button_clear: ZmazaÅ¥
-  button_lock: ZamknÃºÅ¥
-  button_unlock: OdomknÃºÅ¥
-  button_download: StiahnÃºÅ¥
-  button_list: VypÃ­saÅ¥
-  button_view: ZobraziÅ¥
-  button_move: PresunÃºÅ¥
-  button_back: NaspÃ¤Å¥
-  button_cancel: Storno
-  button_activate: AktivovaÅ¥
-  button_sort: Zoradenie
-  button_log_time: PridaÅ¥ Äas
-  button_rollback: NaspÃ¤Å¥ k tejto verzii
-  button_watch: SledovaÅ¥
-  button_unwatch: NesledovaÅ¥
-  button_reply: OdpovedaÅ¥
-  button_archive: ArchivovaÅ¥
-  button_unarchive: OdarchivovaÅ¥
-  button_reset: Reset
-  button_rename: PremenovaÅ¥
-  button_change_password: ZmeniÅ¥ heslo
-  button_copy: KopÃ­rovaÅ¥
-  button_annotate: KomentovaÅ¥
-  button_update: AktualizovaÅ¥
-  button_configure: KonfigurovaÅ¥
-  
-  status_active: aktÃ­vny
-  status_registered: registrovanÃ½
-  status_locked: uzamknutÃ½
-  
-  text_select_mail_notifications: Vyberte akciu, pri ktorej bude zaslanÃ© upozornenie emailom
-  text_regexp_info: napr. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 znamenÃ¡ bez limitu
-  text_project_destroy_confirmation: Ste si istÃ½, Å¾e chcete odstrÃ¡nit tento projekt a vÅ¡etky sÃºvisiace dÃ¡ta ?
-  text_workflow_edit: Vyberte rolu a frontu k Ãºprave workflow
-  text_are_you_sure: Ste si istÃ½?
-  text_tip_issue_begin_day: Ãºloha zaÄÃ­na v tento deÅˆ
-  text_tip_issue_end_day: Ãºloha konÄÃ­ v tento deÅˆ
-  text_tip_issue_begin_end_day: Ãºloha zaÄÃ­na a konÄÃ­ v tento deÅˆ
-  text_project_identifier_info: 'PovolenÃ© znaky sÃº malÃ© pÃ­smena (a-z), ÄÃ­sla a pomlÄka.<br />Po uloÅ¾enÃ­ uÅ¾ nieje moÅ¾nÃ© identifikÃ¡tor zmeniÅ¥.'
-  text_caracters_maximum: "%{count} znakov maximÃ¡lne."
-  text_caracters_minimum: "MusÃ­ byÅ¥ aspoÅˆ %{count} znaky/ov dlhÃ©."
-  text_length_between: "DÄºÅ¾ka medzi %{min} aÅ¾ %{max} znakmi."
-  text_tracker_no_workflow: Pre tuto frontu nieje definovanÃ½ Å¾iadnÃ½ workflow
-  text_unallowed_characters: NepovolenÃ© znaky
-  text_comma_separated: Je povolenÃ© viacero hodnÃ´t (oddelenÃ© navzÃ¡jom Äiarkou).
-  text_issues_ref_in_commit_messages: OdkazovaÅ¥ a upravovaÅ¥ Ãºlohy v sprÃ¡vach s nÃ¡sledovnym obsahom
-  text_issue_added: "Ãºloha %{id} bola vytvorenÃ¡ uÅ¾Ã­vateÄ¾om %{author}."
-  text_issue_updated: "Ãšloha %{id} byla aktualizovanÃ¡ uÅ¾Ã­vateÄ¾om %{author}."
-  text_wiki_destroy_confirmation: Naozaj si prajete odstrÃ¡niÅ¥ tÃºto Wiki a celÃ½ jej obsah?
-  text_issue_category_destroy_question: "NiektorÃ© Ãºlohy (%{count}) sÃº priradenÃ© k tejto kategÃ³rii. ÄŒo chtete  s nimi spraviÅ¥?"
-  text_issue_category_destroy_assignments: ZruÅ¡iÅ¥ priradenie ku kategÃ³rii
-  text_issue_category_reassign_to: PriradiÅ¥ Ãºlohy do tejto kategÃ³rie
-  text_user_mail_option: "U projektov, kterÃ© neboli vybranÃ©, budete dostÃ¡vaÅ¥ oznamenie iba o vaÅ¡ich Äi o sledovanÃ½ch poloÅ¾kÃ¡ch (napr. o poloÅ¾kÃ¡ch, ktorÃ½ch ste autor, alebo ku ktorÃ½m ste priradenÃ½/Ã¡)."
-  text_no_configuration_data: "Role, fronty, stavy Ãºloh ani workflow neboli zatiaÄ¾ nakonfigurovanÃ©.\nVelmi doporuÄujeme nahraÅ¥ vÃ½chodziu konfigurÃ¡ciu. Potom si mÃ´Å¾ete vÅ¡etko upraviÅ¥"
-  text_load_default_configuration: NahraÅ¥ vÃ½chodziu konfigurÃ¡ciu
-  text_status_changed_by_changeset: "AktualizovanÃ© v sade zmien %{value}."
-  text_issues_destroy_confirmation: 'Naozaj si prajete odstrÃ¡niÅ¥ vÅ¡etky zvolenÃ© Ãºlohy?'
-  text_select_project_modules: 'Aktivne moduly v tomto projekte:'
-  text_default_administrator_account_changed: ZmenenÃ© vÃ½chozie nastavenie administrÃ¡torskÃ©ho ÃºÄtu
-  text_file_repository_writable: PovolenÃ½ zÃ¡pis do repozitÃ¡ra
-  text_rmagick_available: RMagick k dispozÃ­ciÃ­ (voliteÄ¾nÃ©)
-  text_destroy_time_entries_question: U Ãºloh, kterÃ© chcete odstraniÅ¥, je evidovanÃ© %.02f prÃ¡ce. ÄŒo chcete vykonaÅ¥?
-  text_destroy_time_entries: OdstrÃ¡niÅ¥ evidovanÃ© hodiny.
-  text_assign_time_entries_to_project: PriradiÅ¥ evidovanÃ© hodiny projektu
-  text_reassign_time_entries: 'PreradiÅ¥ evidovanÃ© hodiny k tejto Ãºlohe:'
-  
-  default_role_manager: ManaÅ¾Ã©r
-  default_role_developer: VÃ½vojÃ¡r
-  default_role_reporter: ReportÃ©r
-  default_tracker_bug: Chyba
-  default_tracker_feature: RozÅ¡Ã­renie
-  default_tracker_support: Podpora
-  default_issue_status_new: NovÃ½
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: VyrieÅ¡enÃ½
-  default_issue_status_feedback: ÄŒakÃ¡ sa
-  default_issue_status_closed: UzavrenÃ½
-  default_issue_status_rejected: OdmietnutÃ½
-  default_doc_category_user: UÅ¾Ã­vateÄ¾skÃ¡ dokumentÃ¡cia
-  default_doc_category_tech: TechnickÃ¡ dokumentÃ¡cia
-  default_priority_low: NÃ­zkÃ¡
-  default_priority_normal: NormÃ¡lna
-  default_priority_high: VysokÃ¡
-  default_priority_urgent: UrgentnÃ¡
-  default_priority_immediate: OkamÅ¾itÃ¡
-  default_activity_design: Design
-  default_activity_development: VÃ½voj
-  
-  enumeration_issue_priorities: Priority Ãºloh
-  enumeration_doc_categories: Kategorie dokumentov
-  enumeration_activities: Aktivity (sledovanie Äasu)
-  error_scm_annotate: "PoloÅ¾ka neexistuje alebo nemÃ´Å¾e byÅ¥ komentovanÃ¡."
-  label_planning: PlÃ¡novanie
-  text_subprojects_destroy_warning: "Jeho podprojekt(y): %{value} budÃº takisto vymazanÃ©."
-  label_and_its_subprojects: "%{value} a jeho podprojekty"
-  mail_body_reminder: "%{count} Ãºloha(y), ktorÃ¡(Ã©) je(sÃº) vÃ¡m priradenÃ½(Ã©), ma(jÃº) byÅ¥ hotova(Ã©) za %{days} dnÃ­:"
-  mail_subject_reminder: "%{count} Ãºloha(y) ma(jÃº) byÅ¥ hotova(Ã©) za pÃ¡r %{days} dnÃ­"
-  text_user_wrote: "%{value} napÃ­sal:"
-  label_duplicated_by: duplikovanÃ½
-  setting_enabled_scm: ZapnÃºÅ¥ SCM
-  text_enumeration_category_reassign_to: 'PrenastaviÅ¥ na tÃºto hodnotu:'
-  text_enumeration_destroy_question: "%{count} objekty sÃº nastavenÃ© na tÃºto hodnotu."
-  label_incoming_emails: PrÃ­chÃ¡dzajÃºce emaily
-  label_generate_key: VygenerovaÅ¥ kÄ¾ÃºÄ
-  setting_mail_handler_api_enabled: ZapnÃºÅ¥ WebovÃº SluÅ¾bu (WS) pre prÃ­chodzie emaily
-  setting_mail_handler_api_key: API kÄ¾ÃºÄ
-  text_email_delivery_not_configured: "DoruÄenie emailov nieje nastavenÃ©, notifikÃ¡cie sÃº vypnutÃ©.\nNastavte vÃ¡Å¡ SMTP server v config/configuration.yml a reÅ¡tartnite aplikÃ¡ciu pre aktivÃ¡ciu funkcie."
-  field_parent_title: NadradenÃ¡ strÃ¡nka
-  label_issue_watchers: Pozorovatelia
-  button_quote: CitÃ¡cia
-  setting_sequential_project_identifiers: GenerovaÅ¥ sekvenÄnÃ© identifikÃ¡tory projektov
-  notice_unable_delete_version: Verzia nemÃ´Å¾e byÅ¥ zmazanÃ¡
-  label_renamed: premenovanÃ©
-  label_copied: kopÃ­rovanÃ©
-  setting_plain_text_mail: Len jednoduchÃ½ text (bez HTML)
-  permission_view_files: Zobrazenie sÃºborov
-  permission_edit_issues: Ãšprava Ãºloh
-  permission_edit_own_time_entries: Ãšprava vlastnÃ½ch zaznamov o strÃ¡venom Äase
-  permission_manage_public_queries: SprÃ¡va verejnÃ½ch otÃ¡ziek
-  permission_add_issues: Pridanie Ãºlohy
-  permission_log_time: ZaznamenÃ¡vanie strÃ¡venÃ©ho Äasu
-  permission_view_changesets: Zobrazenie sÃ¡d zmien
-  permission_view_time_entries: Zobrazenie strÃ¡venÃ©ho Äasu
-  permission_manage_versions: SprÃ¡va verziÃ­
-  permission_manage_wiki: SprÃ¡va Wiki 
-  permission_manage_categories: SprÃ¡va kategÃ³riÃ­ Ãºloh
-  permission_protect_wiki_pages: Ochrana Wiki strÃ¡niek
-  permission_comment_news: Komentovanie noviniek
-  permission_delete_messages: Mazanie sprÃ¡v
-  permission_select_project_modules: VoÄ¾ba projektovÃ½ch modulov
-  permission_manage_documents: SprÃ¡va dokumentov
-  permission_edit_wiki_pages: Ãšprava Wiki strÃ¡niek
-  permission_add_issue_watchers: Pridanie pozorovateÄ¾ov
-  permission_view_gantt: Zobrazenie Ganttovho diagramu
-  permission_move_issues: Presun Ãºloh
-  permission_manage_issue_relations: SprÃ¡va vzÅ¥ahov medzi Ãºlohami
-  permission_delete_wiki_pages: Mazanie Wiki strÃ¡niek
-  permission_manage_boards: SprÃ¡va diskusiÃ­
-  permission_delete_wiki_pages_attachments: Mazanie Wiki prÃ­loh
-  permission_view_wiki_edits: Zobrazenie Wiki Ãºprav
-  permission_add_messages: Pridanie sprÃ¡v
-  permission_view_messages: Zobrazenie sprÃ¡v
-  permission_manage_files: SprÃ¡va sÃºborov
-  permission_edit_issue_notes: Ãšprava poznÃ¡mok Ãºlohy
-  permission_manage_news: SprÃ¡va noviniek
-  permission_view_calendar: Zobrazenie kalendÃ¡ra
-  permission_manage_members: SprÃ¡va Älenov
-  permission_edit_messages: Ãšprava sprÃ¡v
-  permission_delete_issues: Mazanie sprÃ¡v
-  permission_view_issue_watchers: Zobrazenie zoznamu pozorovateÄ¾ov
-  permission_manage_repository: SprÃ¡va repozitÃ¡ra
-  permission_commit_access: PovoliÅ¥ prÃ­stup
-  permission_browse_repository: PrechÃ¡dzanie repozitÃ¡ra
-  permission_view_documents: Zobrazenie dokumentov
-  permission_edit_project: Ãšprava projektu
-  permission_add_issue_notes: Pridanie poznÃ¡mky Ãºlohy
-  permission_save_queries: UloÅ¾enie otÃ¡ziek
-  permission_view_wiki_pages: Zobrazenie Wiki strÃ¡niek
-  permission_rename_wiki_pages: Premenovanie Wiki strÃ¡niek
-  permission_edit_time_entries: Ãšprava zÃ¡znamov o strÃ¡venom Äase
-  permission_edit_own_issue_notes: Ãšprava vlastnÃ½ch poznÃ¡mok Ãºlohy
-  setting_gravatar_enabled: PouÅ¾itie uÅ¾Ã­vateÄ¾skÃ½ch Gravatar ikon
-  permission_edit_own_messages: Ãšprava vlastnÃ½ch sprÃ¡v
-  permission_delete_own_messages: Mazanie vlastnÃ½ch sprÃ¡v
-  text_repository_usernames_mapping: "Vyberte alebo upravte mapovanie medzi uÅ¾Ã­vateÄ¾mi systÃ©mu Redmine a uÅ¾Ã­vateÄ¾skÃ½mi menami nÃ¡jdenÃ½mi v logu repozitÃ¡ra.\nUÅ¾Ã­vatelia s rovnakÃ½m prihlasovacÃ­m menom alebo emailom v systÃ©me Redmine a repozitÃ¡ra sÃº mapovanÃ­ automaticky."
-  label_example: PrÃ­klad
-  label_user_activity: "Aktivita uÅ¾Ã­vateÄ¾a %{value}"
-  label_updated_time_by: "AktualizovanÃ© uÅ¾Ã­vateÄ¾om %{author} pred %{age}"
-  text_diff_truncated: '... Tento rozdielovÃ½ vÃ½pis bol skratenÃ½, pretoÅ¾e prekraÄuje maximÃ¡lnu veÄ¾kosÅ¥, ktorÃ¡ mÃ´Å¾e byÅ¥ zobrazenÃ¡.'
-  setting_diff_max_lines_displayed: MaximÃ¡lne mnoÅ¾stvo zobrazenÃ½ch riadkov rozdielovÃ©ho vÃ½pisu
-  text_plugin_assets_writable: AdresÃ¡r pre pluginy s moÅ¾nosÅ¥ou zÃ¡pisu
-  warning_attachments_not_saved: "%{count} sÃºbor(y) nemohol(li) byÅ¥ uloÅ¾enÃ©."
-  field_editable: EditovateÄ¾nÃ©
-  label_display: Zobrazenie
-  button_create_and_continue: VytvoriÅ¥ a pokraÄovaÅ¥
-  text_custom_field_possible_values_info: 'Jeden riadok pre kaÅ¾dÃº hodnotu'
-  setting_repository_log_display_limit: MaximÃ¡lne mnoÅ¾stvo reviziÃ­ zobrazenÃ© v logu
-  setting_file_max_size_displayed: MaximÃ¡lna veÄ¾kosÅ¥ textovÃ½ch sÃºborov zobrazenÃ½ch priamo na strÃ¡nke
-  field_watcher: PozorovateÄ¾
-  setting_openid: PovoliÅ¥ OpenID prihlasovanie a registrÃ¡ciu
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: alebo sa prihlÃ¡siÅ¥ pomocou OpenID
-  field_content: Obsah
-  label_descending: ZostupnÃ©
-  label_sort: Zoradenie
-  label_ascending: RastÃºce
-  label_date_from_to: Od %{start} do %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: TÃ¡to strÃ¡nka mÃ¡ %{descendants} podstrÃ¡nku/y a potomka/ov. ÄŒo chcete vykonaÅ¥?
-  text_wiki_page_reassign_children: PreradiÅ¥ podstrÃ¡nky k tejto hlavnej strÃ¡nke
-  text_wiki_page_nullify_children: ZachovaÅ¥ podstrÃ¡nky ako hlavnÃ© strÃ¡nky
-  text_wiki_page_destroy_children: VymazaÅ¥ podstrÃ¡nky a vÅ¡etkÃ½ch ich potomkov
-  setting_password_min_length: MinimÃ¡lna dÄºÅ¾ka hesla
-  field_group_by: SkupinovÃ© vÃ½sledky podÄ¾a
-  mail_subject_wiki_content_updated: "'%{id}' Wiki strÃ¡nka bola aktualizovanÃ¡"
-  label_wiki_content_added: Wiki strÃ¡nka pridanÃ¡
-  mail_subject_wiki_content_added: "'%{id}' Wiki strÃ¡nka bola pridanÃ¡"
-  mail_body_wiki_content_added: The '%{id}' Wiki strÃ¡nka bola pridanÃ¡ uÅ¾Ã­vateÄ¾om %{author}.
-  permission_add_project: Vytvorenie projektu
-  label_wiki_content_updated: Wiki strÃ¡nka aktualizovanÃ¡
-  mail_body_wiki_content_updated: Wiki strÃ¡nka '%{id}' bola aktualizovanÃ¡ uÅ¾Ã­vateÄ¾om %{author}.
-  setting_new_project_user_role_id: Rola dÃ¡na non-admin uÅ¾Ã­vateÄ¾ovi, ktorÃ½ vytvorÃ­ projekt
-  label_view_all_revisions: ZobraziÅ¥ vÅ¡etkz revÃ­zie
-  label_tag: Tag
-  label_branch: Vetva
-  error_no_tracker_in_project: K tomuto projektu nieje priradenÃ¡ Å¾iadna fronta. ProsÃ­m skontrolujte nastavenie projektu.
-  error_no_default_issue_status: Nieje definovanÃ½ vÃ½chodzÃ­ stav Ãºlohy. ProsÃ­m skontrolujte vase nastavenie (ChoÄte na "AdministrÃ¡cia -> Stavz Ãºloh").
-  text_journal_changed: "%{label} zmenenÃ© z %{old} na %{new}"
-  text_journal_set_to: "%{label} nastavenÃ© na %{value}"
-  text_journal_deleted: "%{label} zmazanÃ© (%{old})"
-  label_group_plural: Skupiny
-  label_group: Skupina
-  label_group_new: NovÃ¡ skupina
-  label_time_entry_plural: StrÃ¡venÃ½ Äas
-  text_journal_added: "%{label} %{value} pridanÃ©"
-  field_active: AktÃ­vne
-  enumeration_system_activity: Aktivita systÃ©mu
-  permission_delete_issue_watchers: OdstrÃ¡niÅ¥ pozorovateÄ¾ov
-  version_status_closed: zavretÃ©
-  version_status_locked: uzavretÃ©
-  version_status_open: otvorenÃ©
-  error_can_not_reopen_issue_on_closed_version: Ãšloha priradenÃ¡ uzavretej verziÃ­ nemÃ´Å¾e byÅ¥ znovu-otvorenÃ¡
-  label_user_anonymous: Anonym
-  button_move_and_follow: PresunÃºÅ¥ a nÃ¡sledovaÅ¥
-  setting_default_projects_modules: PrednastavenÃ© aktÃ­vne moduly pre novÃ© projekty
-  setting_gravatar_default: VÃ½chodzÃ­ Gravatar obrÃ¡zok
-  field_sharing: ZdieÄ¾anie
-  label_version_sharing_hierarchy: S hierarchiou projektu
-  label_version_sharing_system: So vÅ¡etkÃ½mi projektami
-  label_version_sharing_descendants: S podprojektami
-  label_version_sharing_tree: S projektovÃ½m stromom
-  label_version_sharing_none: NezdielanÃ©
-  error_can_not_archive_project: Tento projekt nemÃ´Å¾e byÅ¥ archivovanÃ½
-  button_duplicate: DuplikovaÅ¥
-  button_copy_and_follow: KopÃ­rovaÅ¥ a nÃ¡sledovaÅ¥
-  label_copy_source: Zdroj
-  setting_issue_done_ratio: VyrÃ¡taÅ¥ pomer vypracovania Ãºlohy s
-  setting_issue_done_ratio_issue_status: PouÅ¾iÅ¥ stav Ãºlohy
-  error_issue_done_ratios_not_updated: Stav vypracovania Ãºlohy neaktualizovanÃ½.
-  error_workflow_copy_target: ProsÃ­m zvoÄ¾te cieÄ¾ovÃº frontu(y) a rolu(e)
-  setting_issue_done_ratio_issue_field: PouÅ¾iÅ¥ pole Ãºlohy
-  label_copy_same_as_target: RovnakÃ© ako cieÄ¾
-  label_copy_target: CieÄ¾
-  notice_issue_done_ratios_updated: Stav vypracovania Ãºlohy aktualizovanÃ½.
-  error_workflow_copy_source: ProsÃ­m zvoÄ¾te zdrojovÃº frontu alebo rolu
-  label_update_issue_done_ratios: AktualizÃ¡cia stavu Ãºloh
-  setting_start_of_week: Å tart pracovnÃ©ho tÃ½Å¾dÅˆa v
-  permission_view_issues: ZobraziÅ¥ Ãºlohy
-  label_display_used_statuses_only: ZobraziÅ¥ len stavy, ktorÃ© sÃº priradenÃ© k tejto fronte
-  label_revision_id: RevÃ­zia %{value}
-  label_api_access_key: API prÃ­stupovÃ½ kÄ¾ÃºÄ
-  label_api_access_key_created_on: API prÃ­stupovÃ½ kÄ¾ÃºÄ vytvorenÃ½ pred %{value}
-  label_feeds_access_key: RSS prÃ­stupovÃ½ kÄ¾ÃºÄ
-  notice_api_access_key_reseted: VÃ¡Å¡ API prÃ­stupovÃ½ kÄ¾ÃºÄ bol resetovanÃ½.
-  setting_rest_api_enabled: ZapnÃºÅ¥ REST web sluÅ¾bu
-  label_missing_api_access_key: API prÃ­stupovÃ½ kÄ¾uÄ nenÃ¡jdenÃ½
-  label_missing_feeds_access_key: RSS prÃ­stupovÃ½ kÄ¾ÃºÄ nenÃ¡jdenÃ½
-  button_show: ZobraziÅ¥
-  text_line_separated: MoÅ¾nosÅ¥ viacerÃ½ch hodnÃ´t (jeden riadok pre kaÅ¾dÃº hodnotu).
-  setting_mail_handler_body_delimiters: OrezaÅ¥ emaily po nÃ¡sledujÃºcich riadkoch
-  permission_add_subprojects: VytvÃ¡ranie podprojektov
-  label_subproject_new: NovÃ½ podprojekt
-  text_own_membership_delete_confirmation: |-
-    PrÃ¡ve sa pokÃºÅ¡ate o odstrÃ¡nenie niektorÃ½ch alebo vÅ¡etkÃ½ch prÃ­stupovÃ½ch prÃ¡v a moÅ¾no nebudete maÅ¥ moÅ¾nost naÄalej upravovaÅ¥ tento projekt.
-    Ste si istÃ½(Ã¡), Å¾e chcete pokraÄovat? 
-  label_close_versions: UzavrieÅ¥ ukonÄenÃ© verzie
-  label_board_sticky: Sticky
-  label_board_locked: UzamknutÃ©
-  permission_export_wiki_pages: ExportovaÅ¥ WiKi strÃ¡nky
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: NastavovaÅ¥ aktivity projektu
-  error_unable_delete_issue_status: Nieje moÅ¾nÃ© zmeniÅ¥ stav Ãºlohy
-  label_profile: Profil
-  permission_manage_subtasks: NastavovaÅ¥ podÃºlohy
-  field_parent_issue: NadradenÃ¡ Ãºloha
-  label_subtask_plural: PodÃºlohy
-  label_project_copy_notifications: ZaslaÅ¥ emailovÃ© upozornenie behom kopÃ­rovania projektu
-  error_can_not_delete_custom_field: Nieje moÅ¾nÃ© vymazaÅ¥ uÅ¾Ã­vateÄ¾skÃ© pole
-  error_unable_to_connect: Nieje moÅ¾nÃ© vymazaÅ¥ (%{value})
-  error_can_not_remove_role: TÃ¡to roÄ¾a sa pouÅ¾Ã­va a nemÃ´Å¾e byÅ¥ vymazanÃ¡.
-  error_can_not_delete_tracker: TÃ¡to fronta obsahuje Ãºlohy a nemÃ´Å¾e byÅ¥ vymazanÃ¡.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: KÃ³dovanie prenÃ¡Å¡anÃ½ch sprÃ¡v
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c7bb69004035c6ba51de1c4b9e2df0f70c675d27.svn-base
--- a/.svn/pristine/c7/c7bb69004035c6ba51de1c4b9e2df0f70c675d27.svn-base
+++ /dev/null
@@ -1,84 +0,0 @@
-// ** I18N
-
-// full day names
-Calendar._DN = new Array
-("SÃ¶ndag",
- "MÃ¥ndag",
- "Tisdag",
- "Onsdag",
- "Torsdag",
- "Fredag",
- "LÃ¶rdag",
- "SÃ¶ndag");
-
-Calendar._SDN_len = 3; // short day name length
-Calendar._SMN_len = 3; // short month name length
-
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Januari",
- "Februari",
- "Mars",
- "April",
- "Maj",
- "Juni",
- "Juli",
- "Augusti",
- "September",
- "Oktober",
- "November",
- "December");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Om kalendern";
-
-Calendar._TT["ABOUT"] =
-"DHTML Datum/Tid-vÃ¤ljare\n" +
-"(c) dynarch.com 2002-2005 / Upphovsman: Mihai Bazon\n" + // don't translate this this ;-)
-"FÃ¶r senaste version besÃ¶k: http://www.dynarch.com/projects/calendar/\n" +
-"Distribueras under GNU LGPL.  Se http://gnu.org/licenses/lgpl.html fÃ¶r detaljer." +
-"\n\n" +
-"VÃ¤lja datum:\n" +
-"- AnvÃ¤nd \xab, \xbb knapparna fÃ¶r att vÃ¤lja Ã¥r\n" +
-"- AnvÃ¤nd " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " knapparna fÃ¶r att vÃ¤lja mÃ¥nad\n" +
-"- HÃ¥ll nere musknappen pÃ¥ nÃ¥gon av ovanstÃ¥ende knappar fÃ¶r att se snabbval.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"VÃ¤lja tid:\n" +
-"- Klicka pÃ¥ nÃ¥got av tidsfÃ¤lten fÃ¶r att Ã¶ka\n" +
-"- eller Skift-klicka fÃ¶r att minska\n" +
-"- eller klicka och dra fÃ¶r att vÃ¤lja snabbare.";
-
-Calendar._TT["PREV_YEAR"] = "FÃ¶reg. Ã¥r (hÃ¥ll nere fÃ¶r lista)";
-Calendar._TT["PREV_MONTH"] = "FÃ¶reg. mÃ¥nad (hÃ¥ll nere fÃ¶r lista)";
-Calendar._TT["GO_TODAY"] = "GÃ¥ till Idag";
-Calendar._TT["NEXT_MONTH"] = "NÃ¤sta mÃ¥nad (hÃ¥ll nere fÃ¶r lista)";
-Calendar._TT["NEXT_YEAR"] = "NÃ¤sta Ã¥r (hÃ¥ll nere fÃ¶r lista)";
-Calendar._TT["SEL_DATE"] = "VÃ¤lj datum";
-Calendar._TT["DRAG_TO_MOVE"] = "Dra fÃ¶r att flytta";
-Calendar._TT["PART_TODAY"] = " (idag)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Visa %s fÃ¶rst";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "StÃ¤ng";
-Calendar._TT["TODAY"] = "Idag";
-Calendar._TT["TIME_PART"] = "(Skift-)klicka eller dra fÃ¶r att Ã¤ndra vÃ¤rde";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "v.";
-Calendar._TT["TIME"] = "Tid:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c7cf137c2588796a3073e5736e9e052805b1bb66.svn-base
--- /dev/null
+++ b/.svn/pristine/c7/c7cf137c2588796a3073e5736e9e052805b1bb66.svn-base
@@ -0,0 +1,33 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Views
+    class OtherFormatsBuilder
+      def initialize(view)
+        @view = view
+      end
+
+      def link_to(name, options={})
+        url = { :format => name.to_s.downcase }.merge(options.delete(:url) || {}).except('page')
+        caption = options.delete(:caption) || name
+        html_options = { :class => name.to_s.downcase, :rel => 'nofollow' }.merge(options)
+        @view.content_tag('span', @view.link_to(caption, url, html_options))
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c7d5fcf60428c25b64f2230a47dd713a94818cae.svn-base
--- a/.svn/pristine/c7/c7d5fcf60428c25b64f2230a47dd713a94818cae.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-class Namespace::AlphaPluginController < ApplicationController
-  def an_action
-    render_class_and_action
-  end  
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c7d848a2c73159ca5a8ab924fb977b51dbc69f9f.svn-base
--- /dev/null
+++ b/.svn/pristine/c7/c7d848a2c73159ca5a8ab924fb977b51dbc69f9f.svn-base
@@ -0,0 +1,937 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ProjectTest < ActiveSupport::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :journals, :journal_details,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :custom_fields,
+           :custom_fields_projects,
+           :custom_fields_trackers,
+           :custom_values,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :versions,
+           :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
+           :groups_users,
+           :boards, :messages,
+           :repositories,
+           :news, :comments,
+           :documents
+
+  def setup
+    @ecookbook = Project.find(1)
+    @ecookbook_sub1 = Project.find(3)
+    set_tmp_attachments_directory
+    User.current = nil
+  end
+
+  def test_truth
+    assert_kind_of Project, @ecookbook
+    assert_equal "eCookbook", @ecookbook.name
+  end
+
+  def test_default_attributes
+    with_settings :default_projects_public => '1' do
+      assert_equal true, Project.new.is_public
+      assert_equal false, Project.new(:is_public => false).is_public
+    end
+
+    with_settings :default_projects_public => '0' do
+      assert_equal false, Project.new.is_public
+      assert_equal true, Project.new(:is_public => true).is_public
+    end
+
+    with_settings :sequential_project_identifiers => '1' do
+      assert !Project.new.identifier.blank?
+      assert Project.new(:identifier => '').identifier.blank?
+    end
+
+    with_settings :sequential_project_identifiers => '0' do
+      assert Project.new.identifier.blank?
+      assert !Project.new(:identifier => 'test').blank?
+    end
+
+    with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
+      assert_equal ['issue_tracking', 'repository'], Project.new.enabled_module_names
+    end
+  end
+
+  def test_default_trackers_should_match_default_tracker_ids_setting
+    with_settings :default_projects_tracker_ids => ['1', '3'] do
+      assert_equal Tracker.find(1, 3).sort, Project.new.trackers.sort
+    end
+  end
+
+  def test_default_trackers_should_be_all_trackers_with_blank_setting
+    with_settings :default_projects_tracker_ids => nil do
+      assert_equal Tracker.all.sort, Project.new.trackers.sort
+    end
+  end
+
+  def test_default_trackers_should_be_empty_with_empty_setting
+    with_settings :default_projects_tracker_ids => [] do
+      assert_equal [], Project.new.trackers
+    end
+  end
+
+  def test_default_trackers_should_not_replace_initialized_trackers
+    with_settings :default_projects_tracker_ids => ['1', '3'] do
+      assert_equal Tracker.find(1, 2).sort, Project.new(:tracker_ids => [1, 2]).trackers.sort
+    end
+  end
+
+  def test_update
+    assert_equal "eCookbook", @ecookbook.name
+    @ecookbook.name = "eCook"
+    assert @ecookbook.save, @ecookbook.errors.full_messages.join("; ")
+    @ecookbook.reload
+    assert_equal "eCook", @ecookbook.name
+  end
+
+  def test_validate_identifier
+    to_test = {"abc" => true,
+               "ab12" => true,
+               "ab-12" => true,
+               "ab_12" => true,
+               "12" => false,
+               "new" => false}
+
+    to_test.each do |identifier, valid|
+      p = Project.new
+      p.identifier = identifier
+      p.valid?
+      if valid
+        assert p.errors['identifier'].blank?, "identifier #{identifier} was not valid"
+      else
+        assert p.errors['identifier'].present?, "identifier #{identifier} was valid"
+      end
+    end
+  end
+
+  def test_identifier_should_not_be_frozen_for_a_new_project
+    assert_equal false, Project.new.identifier_frozen?
+  end
+
+  def test_identifier_should_not_be_frozen_for_a_saved_project_with_blank_identifier
+    Project.update_all(["identifier = ''"], "id = 1")
+
+    assert_equal false, Project.find(1).identifier_frozen?
+  end
+
+  def test_identifier_should_be_frozen_for_a_saved_project_with_valid_identifier
+    assert_equal true, Project.find(1).identifier_frozen?
+  end
+
+  def test_members_should_be_active_users
+    Project.all.each do |project|
+      assert_nil project.members.detect {|m| !(m.user.is_a?(User) && m.user.active?) }
+    end
+  end
+
+  def test_users_should_be_active_users
+    Project.all.each do |project|
+      assert_nil project.users.detect {|u| !(u.is_a?(User) && u.active?) }
+    end
+  end
+
+  def test_open_scope_on_issues_association
+    assert_kind_of Issue, Project.find(1).issues.open.first
+  end
+
+  def test_archive
+    user = @ecookbook.members.first.user
+    @ecookbook.archive
+    @ecookbook.reload
+
+    assert !@ecookbook.active?
+    assert @ecookbook.archived?
+    assert !user.projects.include?(@ecookbook)
+    # Subproject are also archived
+    assert !@ecookbook.children.empty?
+    assert @ecookbook.descendants.active.empty?
+  end
+
+  def test_archive_should_fail_if_versions_are_used_by_non_descendant_projects
+    # Assign an issue of a project to a version of a child project
+    Issue.find(4).update_attribute :fixed_version_id, 4
+
+    assert_no_difference "Project.count(:all, :conditions => 'status = #{Project::STATUS_ARCHIVED}')" do
+      assert_equal false, @ecookbook.archive
+    end
+    @ecookbook.reload
+    assert @ecookbook.active?
+  end
+
+  def test_unarchive
+    user = @ecookbook.members.first.user
+    @ecookbook.archive
+    # A subproject of an archived project can not be unarchived
+    assert !@ecookbook_sub1.unarchive
+
+    # Unarchive project
+    assert @ecookbook.unarchive
+    @ecookbook.reload
+    assert @ecookbook.active?
+    assert !@ecookbook.archived?
+    assert user.projects.include?(@ecookbook)
+    # Subproject can now be unarchived
+    @ecookbook_sub1.reload
+    assert @ecookbook_sub1.unarchive
+  end
+
+  def test_destroy
+    # 2 active members
+    assert_equal 2, @ecookbook.members.size
+    # and 1 is locked
+    assert_equal 3, Member.where('project_id = ?', @ecookbook.id).all.size
+    # some boards
+    assert @ecookbook.boards.any?
+
+    @ecookbook.destroy
+    # make sure that the project non longer exists
+    assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) }
+    # make sure related data was removed
+    assert_nil Member.first(:conditions => {:project_id => @ecookbook.id})
+    assert_nil Board.first(:conditions => {:project_id => @ecookbook.id})
+    assert_nil Issue.first(:conditions => {:project_id => @ecookbook.id})
+  end
+
+  def test_destroy_should_destroy_subtasks
+    issues = (0..2).to_a.map {Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'test')}
+    issues[0].update_attribute :parent_issue_id, issues[1].id
+    issues[2].update_attribute :parent_issue_id, issues[1].id
+    assert_equal 2, issues[1].children.count
+
+    assert_nothing_raised do
+      Project.find(1).destroy
+    end
+    assert Issue.find_all_by_id(issues.map(&:id)).empty?
+  end
+
+  def test_destroying_root_projects_should_clear_data
+    Project.roots.each do |root|
+      root.destroy
+    end
+
+    assert_equal 0, Project.count, "Projects were not deleted: #{Project.all.inspect}"
+    assert_equal 0, Member.count, "Members were not deleted: #{Member.all.inspect}"
+    assert_equal 0, MemberRole.count
+    assert_equal 0, Issue.count
+    assert_equal 0, Journal.count
+    assert_equal 0, JournalDetail.count
+    assert_equal 0, Attachment.count, "Attachments were not deleted: #{Attachment.all.inspect}"
+    assert_equal 0, EnabledModule.count
+    assert_equal 0, IssueCategory.count
+    assert_equal 0, IssueRelation.count
+    assert_equal 0, Board.count
+    assert_equal 0, Message.count
+    assert_equal 0, News.count
+    assert_equal 0, Query.count(:conditions => "project_id IS NOT NULL")
+    assert_equal 0, Repository.count
+    assert_equal 0, Changeset.count
+    assert_equal 0, Change.count
+    assert_equal 0, Comment.count
+    assert_equal 0, TimeEntry.count
+    assert_equal 0, Version.count
+    assert_equal 0, Watcher.count
+    assert_equal 0, Wiki.count
+    assert_equal 0, WikiPage.count
+    assert_equal 0, WikiContent.count
+    assert_equal 0, WikiContent::Version.count
+    assert_equal 0, Project.connection.select_all("SELECT * FROM projects_trackers").size
+    assert_equal 0, Project.connection.select_all("SELECT * FROM custom_fields_projects").size
+    assert_equal 0, CustomValue.count(:conditions => {:customized_type => ['Project', 'Issue', 'TimeEntry', 'Version']})
+  end
+
+  def test_move_an_orphan_project_to_a_root_project
+    sub = Project.find(2)
+    sub.set_parent! @ecookbook
+    assert_equal @ecookbook.id, sub.parent.id
+    @ecookbook.reload
+    assert_equal 4, @ecookbook.children.size
+  end
+
+  def test_move_an_orphan_project_to_a_subproject
+    sub = Project.find(2)
+    assert sub.set_parent!(@ecookbook_sub1)
+  end
+
+  def test_move_a_root_project_to_a_project
+    sub = @ecookbook
+    assert sub.set_parent!(Project.find(2))
+  end
+
+  def test_should_not_move_a_project_to_its_children
+    sub = @ecookbook
+    assert !(sub.set_parent!(Project.find(3)))
+  end
+
+  def test_set_parent_should_add_roots_in_alphabetical_order
+    ProjectCustomField.delete_all
+    Project.delete_all
+    Project.create!(:name => 'Project C', :identifier => 'project-c').set_parent!(nil)
+    Project.create!(:name => 'Project B', :identifier => 'project-b').set_parent!(nil)
+    Project.create!(:name => 'Project D', :identifier => 'project-d').set_parent!(nil)
+    Project.create!(:name => 'Project A', :identifier => 'project-a').set_parent!(nil)
+
+    assert_equal 4, Project.count
+    assert_equal Project.all.sort_by(&:name), Project.all.sort_by(&:lft)
+  end
+
+  def test_set_parent_should_add_children_in_alphabetical_order
+    ProjectCustomField.delete_all
+    parent = Project.create!(:name => 'Parent', :identifier => 'parent')
+    Project.create!(:name => 'Project C', :identifier => 'project-c').set_parent!(parent)
+    Project.create!(:name => 'Project B', :identifier => 'project-b').set_parent!(parent)
+    Project.create!(:name => 'Project D', :identifier => 'project-d').set_parent!(parent)
+    Project.create!(:name => 'Project A', :identifier => 'project-a').set_parent!(parent)
+
+    parent.reload
+    assert_equal 4, parent.children.size
+    assert_equal parent.children.all.sort_by(&:name), parent.children.all
+  end
+
+  def test_set_parent_should_update_issue_fixed_version_associations_when_a_fixed_version_is_moved_out_of_the_hierarchy
+    # Parent issue with a hierarchy project's fixed version
+    parent_issue = Issue.find(1)
+    parent_issue.update_attribute(:fixed_version_id, 4)
+    parent_issue.reload
+    assert_equal 4, parent_issue.fixed_version_id
+
+    # Should keep fixed versions for the issues
+    issue_with_local_fixed_version = Issue.find(5)
+    issue_with_local_fixed_version.update_attribute(:fixed_version_id, 4)
+    issue_with_local_fixed_version.reload
+    assert_equal 4, issue_with_local_fixed_version.fixed_version_id
+
+    # Local issue with hierarchy fixed_version
+    issue_with_hierarchy_fixed_version = Issue.find(13)
+    issue_with_hierarchy_fixed_version.update_attribute(:fixed_version_id, 6)
+    issue_with_hierarchy_fixed_version.reload
+    assert_equal 6, issue_with_hierarchy_fixed_version.fixed_version_id
+
+    # Move project out of the issue's hierarchy
+    moved_project = Project.find(3)
+    moved_project.set_parent!(Project.find(2))
+    parent_issue.reload
+    issue_with_local_fixed_version.reload
+    issue_with_hierarchy_fixed_version.reload
+
+    assert_equal 4, issue_with_local_fixed_version.fixed_version_id, "Fixed version was not keep on an issue local to the moved project"
+    assert_equal nil, issue_with_hierarchy_fixed_version.fixed_version_id, "Fixed version is still set after moving the Project out of the hierarchy where the version is defined in"
+    assert_equal nil, parent_issue.fixed_version_id, "Fixed version is still set after moving the Version out of the hierarchy for the issue."
+  end
+
+  def test_parent
+    p = Project.find(6).parent
+    assert p.is_a?(Project)
+    assert_equal 5, p.id
+  end
+
+  def test_ancestors
+    a = Project.find(6).ancestors
+    assert a.first.is_a?(Project)
+    assert_equal [1, 5], a.collect(&:id)
+  end
+
+  def test_root
+    r = Project.find(6).root
+    assert r.is_a?(Project)
+    assert_equal 1, r.id
+  end
+
+  def test_children
+    c = Project.find(1).children
+    assert c.first.is_a?(Project)
+    assert_equal [5, 3, 4], c.collect(&:id)
+  end
+
+  def test_descendants
+    d = Project.find(1).descendants
+    assert d.first.is_a?(Project)
+    assert_equal [5, 6, 3, 4], d.collect(&:id)
+  end
+
+  def test_allowed_parents_should_be_empty_for_non_member_user
+    Role.non_member.add_permission!(:add_project)
+    user = User.find(9)
+    assert user.memberships.empty?
+    User.current = user
+    assert Project.new.allowed_parents.compact.empty?
+  end
+
+  def test_allowed_parents_with_add_subprojects_permission
+    Role.find(1).remove_permission!(:add_project)
+    Role.find(1).add_permission!(:add_subprojects)
+    User.current = User.find(2)
+    # new project
+    assert !Project.new.allowed_parents.include?(nil)
+    assert Project.new.allowed_parents.include?(Project.find(1))
+    # existing root project
+    assert Project.find(1).allowed_parents.include?(nil)
+    # existing child
+    assert Project.find(3).allowed_parents.include?(Project.find(1))
+    assert !Project.find(3).allowed_parents.include?(nil)
+  end
+
+  def test_allowed_parents_with_add_project_permission
+    Role.find(1).add_permission!(:add_project)
+    Role.find(1).remove_permission!(:add_subprojects)
+    User.current = User.find(2)
+    # new project
+    assert Project.new.allowed_parents.include?(nil)
+    assert !Project.new.allowed_parents.include?(Project.find(1))
+    # existing root project
+    assert Project.find(1).allowed_parents.include?(nil)
+    # existing child
+    assert Project.find(3).allowed_parents.include?(Project.find(1))
+    assert Project.find(3).allowed_parents.include?(nil)
+  end
+
+  def test_allowed_parents_with_add_project_and_subprojects_permission
+    Role.find(1).add_permission!(:add_project)
+    Role.find(1).add_permission!(:add_subprojects)
+    User.current = User.find(2)
+    # new project
+    assert Project.new.allowed_parents.include?(nil)
+    assert Project.new.allowed_parents.include?(Project.find(1))
+    # existing root project
+    assert Project.find(1).allowed_parents.include?(nil)
+    # existing child
+    assert Project.find(3).allowed_parents.include?(Project.find(1))
+    assert Project.find(3).allowed_parents.include?(nil)
+  end
+
+  def test_users_by_role
+    users_by_role = Project.find(1).users_by_role
+    assert_kind_of Hash, users_by_role
+    role = Role.find(1)
+    assert_kind_of Array, users_by_role[role]
+    assert users_by_role[role].include?(User.find(2))
+  end
+
+  def test_rolled_up_trackers
+    parent = Project.find(1)
+    parent.trackers = Tracker.find([1,2])
+    child = parent.children.find(3)
+
+    assert_equal [1, 2], parent.tracker_ids
+    assert_equal [2, 3], child.trackers.collect(&:id)
+
+    assert_kind_of Tracker, parent.rolled_up_trackers.first
+    assert_equal Tracker.find(1), parent.rolled_up_trackers.first
+
+    assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id)
+    assert_equal [2, 3], child.rolled_up_trackers.collect(&:id)
+  end
+
+  def test_rolled_up_trackers_should_ignore_archived_subprojects
+    parent = Project.find(1)
+    parent.trackers = Tracker.find([1,2])
+    child = parent.children.find(3)
+    child.trackers = Tracker.find([1,3])
+    parent.children.each(&:archive)
+
+    assert_equal [1,2], parent.rolled_up_trackers.collect(&:id)
+  end
+
+  test "#rolled_up_trackers should ignore projects with issue_tracking module disabled" do
+    parent = Project.generate!
+    parent.trackers = Tracker.find([1, 2])
+    child = Project.generate_with_parent!(parent)
+    child.trackers = Tracker.find([2, 3])
+
+    assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id).sort
+
+    assert child.disable_module!(:issue_tracking)
+    parent.reload
+    assert_equal [1, 2], parent.rolled_up_trackers.collect(&:id).sort
+  end
+
+  test "#rolled_up_versions should include the versions for the current project" do
+    project = Project.generate!
+    parent_version_1 = Version.generate!(:project => project)
+    parent_version_2 = Version.generate!(:project => project)
+    assert_same_elements [parent_version_1, parent_version_2], project.rolled_up_versions
+  end
+
+  test "#rolled_up_versions should include versions for a subproject" do
+    project = Project.generate!
+    parent_version_1 = Version.generate!(:project => project)
+    parent_version_2 = Version.generate!(:project => project)
+    subproject = Project.generate_with_parent!(project)
+    subproject_version = Version.generate!(:project => subproject)
+
+    assert_same_elements [
+                          parent_version_1,
+                          parent_version_2,
+                          subproject_version
+                         ], project.rolled_up_versions
+  end
+
+  test "#rolled_up_versions should include versions for a sub-subproject" do
+    project = Project.generate!
+    parent_version_1 = Version.generate!(:project => project)
+    parent_version_2 = Version.generate!(:project => project)
+    subproject = Project.generate_with_parent!(project)
+    sub_subproject = Project.generate_with_parent!(subproject)
+    sub_subproject_version = Version.generate!(:project => sub_subproject)
+    project.reload
+
+    assert_same_elements [
+                          parent_version_1,
+                          parent_version_2,
+                          sub_subproject_version
+                         ], project.rolled_up_versions
+  end
+
+  test "#rolled_up_versions should only check active projects" do
+    project = Project.generate!
+    parent_version_1 = Version.generate!(:project => project)
+    parent_version_2 = Version.generate!(:project => project)
+    subproject = Project.generate_with_parent!(project)
+    subproject_version = Version.generate!(:project => subproject)
+    assert subproject.archive
+    project.reload
+
+    assert !subproject.active?
+    assert_same_elements [parent_version_1, parent_version_2], project.rolled_up_versions
+  end
+
+  def test_shared_versions_none_sharing
+    p = Project.find(5)
+    v = Version.create!(:name => 'none_sharing', :project => p, :sharing => 'none')
+    assert p.shared_versions.include?(v)
+    assert !p.children.first.shared_versions.include?(v)
+    assert !p.root.shared_versions.include?(v)
+    assert !p.siblings.first.shared_versions.include?(v)
+    assert !p.root.siblings.first.shared_versions.include?(v)
+  end
+
+  def test_shared_versions_descendants_sharing
+    p = Project.find(5)
+    v = Version.create!(:name => 'descendants_sharing', :project => p, :sharing => 'descendants')
+    assert p.shared_versions.include?(v)
+    assert p.children.first.shared_versions.include?(v)
+    assert !p.root.shared_versions.include?(v)
+    assert !p.siblings.first.shared_versions.include?(v)
+    assert !p.root.siblings.first.shared_versions.include?(v)
+  end
+
+  def test_shared_versions_hierarchy_sharing
+    p = Project.find(5)
+    v = Version.create!(:name => 'hierarchy_sharing', :project => p, :sharing => 'hierarchy')
+    assert p.shared_versions.include?(v)
+    assert p.children.first.shared_versions.include?(v)
+    assert p.root.shared_versions.include?(v)
+    assert !p.siblings.first.shared_versions.include?(v)
+    assert !p.root.siblings.first.shared_versions.include?(v)
+  end
+
+  def test_shared_versions_tree_sharing
+    p = Project.find(5)
+    v = Version.create!(:name => 'tree_sharing', :project => p, :sharing => 'tree')
+    assert p.shared_versions.include?(v)
+    assert p.children.first.shared_versions.include?(v)
+    assert p.root.shared_versions.include?(v)
+    assert p.siblings.first.shared_versions.include?(v)
+    assert !p.root.siblings.first.shared_versions.include?(v)
+  end
+
+  def test_shared_versions_system_sharing
+    p = Project.find(5)
+    v = Version.create!(:name => 'system_sharing', :project => p, :sharing => 'system')
+    assert p.shared_versions.include?(v)
+    assert p.children.first.shared_versions.include?(v)
+    assert p.root.shared_versions.include?(v)
+    assert p.siblings.first.shared_versions.include?(v)
+    assert p.root.siblings.first.shared_versions.include?(v)
+  end
+
+  def test_shared_versions
+    parent = Project.find(1)
+    child = parent.children.find(3)
+    private_child = parent.children.find(5)
+
+    assert_equal [1,2,3], parent.version_ids.sort
+    assert_equal [4], child.version_ids
+    assert_equal [6], private_child.version_ids
+    assert_equal [7], Version.find_all_by_sharing('system').collect(&:id)
+
+    assert_equal 6, parent.shared_versions.size
+    parent.shared_versions.each do |version|
+      assert_kind_of Version, version
+    end
+
+    assert_equal [1,2,3,4,6,7], parent.shared_versions.collect(&:id).sort
+  end
+
+  def test_shared_versions_should_ignore_archived_subprojects
+    parent = Project.find(1)
+    child = parent.children.find(3)
+    child.archive
+    parent.reload
+
+    assert_equal [1,2,3], parent.version_ids.sort
+    assert_equal [4], child.version_ids
+    assert !parent.shared_versions.collect(&:id).include?(4)
+  end
+
+  def test_shared_versions_visible_to_user
+    user = User.find(3)
+    parent = Project.find(1)
+    child = parent.children.find(5)
+
+    assert_equal [1,2,3], parent.version_ids.sort
+    assert_equal [6], child.version_ids
+
+    versions = parent.shared_versions.visible(user)
+
+    assert_equal 4, versions.size
+    versions.each do |version|
+      assert_kind_of Version, version
+    end
+
+    assert !versions.collect(&:id).include?(6)
+  end
+
+  def test_shared_versions_for_new_project_should_include_system_shared_versions
+    p = Project.find(5)
+    v = Version.create!(:name => 'system_sharing', :project => p, :sharing => 'system')
+
+    assert_include v, Project.new.shared_versions
+  end
+
+  def test_next_identifier
+    ProjectCustomField.delete_all
+    Project.create!(:name => 'last', :identifier => 'p2008040')
+    assert_equal 'p2008041', Project.next_identifier
+  end
+
+  def test_next_identifier_first_project
+    Project.delete_all
+    assert_nil Project.next_identifier
+  end
+
+  def test_enabled_module_names
+    with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
+      project = Project.new
+
+      project.enabled_module_names = %w(issue_tracking news)
+      assert_equal %w(issue_tracking news), project.enabled_module_names.sort
+    end
+  end
+
+  test "enabled_modules should define module by names and preserve ids" do
+    @project = Project.find(1)
+    # Remove one module
+    modules = @project.enabled_modules.slice(0..-2)
+    assert modules.any?
+    assert_difference 'EnabledModule.count', -1 do
+      @project.enabled_module_names = modules.collect(&:name)
+    end
+    @project.reload
+    # Ids should be preserved
+    assert_equal @project.enabled_module_ids.sort, modules.collect(&:id).sort
+  end
+
+  test "enabled_modules should enable a module" do
+    @project = Project.find(1)
+    @project.enabled_module_names = []
+    @project.reload
+    assert_equal [], @project.enabled_module_names
+    #with string
+    @project.enable_module!("issue_tracking")
+    assert_equal ["issue_tracking"], @project.enabled_module_names
+    #with symbol
+    @project.enable_module!(:gantt)
+    assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
+    #don't add a module twice
+    @project.enable_module!("issue_tracking")
+    assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
+  end
+
+  test "enabled_modules should disable a module" do
+    @project = Project.find(1)
+    #with string
+    assert @project.enabled_module_names.include?("issue_tracking")
+    @project.disable_module!("issue_tracking")
+    assert ! @project.reload.enabled_module_names.include?("issue_tracking")
+    #with symbol
+    assert @project.enabled_module_names.include?("gantt")
+    @project.disable_module!(:gantt)
+    assert ! @project.reload.enabled_module_names.include?("gantt")
+    #with EnabledModule object
+    first_module = @project.enabled_modules.first
+    @project.disable_module!(first_module)
+    assert ! @project.reload.enabled_module_names.include?(first_module.name)
+  end
+
+  def test_enabled_module_names_should_not_recreate_enabled_modules
+    project = Project.find(1)
+    # Remove one module
+    modules = project.enabled_modules.slice(0..-2)
+    assert modules.any?
+    assert_difference 'EnabledModule.count', -1 do
+      project.enabled_module_names = modules.collect(&:name)
+    end
+    project.reload
+    # Ids should be preserved
+    assert_equal project.enabled_module_ids.sort, modules.collect(&:id).sort
+  end
+
+  def test_copy_from_existing_project
+    source_project = Project.find(1)
+    copied_project = Project.copy_from(1)
+
+    assert copied_project
+    # Cleared attributes
+    assert copied_project.id.blank?
+    assert copied_project.name.blank?
+    assert copied_project.identifier.blank?
+
+    # Duplicated attributes
+    assert_equal source_project.description, copied_project.description
+    assert_equal source_project.enabled_modules, copied_project.enabled_modules
+    assert_equal source_project.trackers, copied_project.trackers
+
+    # Default attributes
+    assert_equal 1, copied_project.status
+  end
+
+  def test_activities_should_use_the_system_activities
+    project = Project.find(1)
+    assert_equal project.activities, TimeEntryActivity.where(:active => true).all
+  end
+
+
+  def test_activities_should_use_the_project_specific_activities
+    project = Project.find(1)
+    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project})
+    assert overridden_activity.save!
+
+    assert project.activities.include?(overridden_activity), "Project specific Activity not found"
+  end
+
+  def test_activities_should_not_include_the_inactive_project_specific_activities
+    project = Project.find(1)
+    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.first, :active => false})
+    assert overridden_activity.save!
+
+    assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity found"
+  end
+
+  def test_activities_should_not_include_project_specific_activities_from_other_projects
+    project = Project.find(1)
+    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(2)})
+    assert overridden_activity.save!
+
+    assert !project.activities.include?(overridden_activity), "Project specific Activity found on a different project"
+  end
+
+  def test_activities_should_handle_nils
+    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(1), :parent => TimeEntryActivity.first})
+    TimeEntryActivity.delete_all
+
+    # No activities
+    project = Project.find(1)
+    assert project.activities.empty?
+
+    # No system, one overridden
+    assert overridden_activity.save!
+    project.reload
+    assert_equal [overridden_activity], project.activities
+  end
+
+  def test_activities_should_override_system_activities_with_project_activities
+    project = Project.find(1)
+    parent_activity = TimeEntryActivity.first
+    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => parent_activity})
+    assert overridden_activity.save!
+
+    assert project.activities.include?(overridden_activity), "Project specific Activity not found"
+    assert !project.activities.include?(parent_activity), "System Activity found when it should have been overridden"
+  end
+
+  def test_activities_should_include_inactive_activities_if_specified
+    project = Project.find(1)
+    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.first, :active => false})
+    assert overridden_activity.save!
+
+    assert project.activities(true).include?(overridden_activity), "Inactive Project specific Activity not found"
+  end
+
+  test 'activities should not include active System activities if the project has an override that is inactive' do
+    project = Project.find(1)
+    system_activity = TimeEntryActivity.find_by_name('Design')
+    assert system_activity.active?
+    overridden_activity = TimeEntryActivity.create!(:name => "Project", :project => project, :parent => system_activity, :active => false)
+    assert overridden_activity.save!
+
+    assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity not found"
+    assert !project.activities.include?(system_activity), "System activity found when the project has an inactive override"
+  end
+
+  def test_close_completed_versions
+    Version.update_all("status = 'open'")
+    project = Project.find(1)
+    assert_not_nil project.versions.detect {|v| v.completed? && v.status == 'open'}
+    assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'}
+    project.close_completed_versions
+    project.reload
+    assert_nil project.versions.detect {|v| v.completed? && v.status != 'closed'}
+    assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'}
+  end
+
+  test "#start_date should be nil if there are no issues on the project" do
+    project = Project.generate!
+    assert_nil project.start_date
+  end
+
+  test "#start_date should be nil when issues have no start date" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    early = 7.days.ago.to_date
+    Issue.generate!(:project => project, :start_date => nil)
+
+    assert_nil project.start_date
+  end
+
+  test "#start_date should be the earliest start date of it's issues" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    early = 7.days.ago.to_date
+    Issue.generate!(:project => project, :start_date => Date.today)
+    Issue.generate!(:project => project, :start_date => early)
+
+    assert_equal early, project.start_date
+  end
+
+  test "#due_date should be nil if there are no issues on the project" do
+    project = Project.generate!
+    assert_nil project.due_date
+  end
+
+  test "#due_date should be nil if there are no issues with due dates" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    Issue.generate!(:project => project, :due_date => nil)
+
+    assert_nil project.due_date
+  end
+
+  test "#due_date should be the latest due date of it's issues" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    future = 7.days.from_now.to_date
+    Issue.generate!(:project => project, :due_date => future)
+    Issue.generate!(:project => project, :due_date => Date.today)
+
+    assert_equal future, project.due_date
+  end
+
+  test "#due_date should be the latest due date of it's versions" do
+    project = Project.generate!
+    future = 7.days.from_now.to_date
+    project.versions << Version.generate!(:effective_date => future)
+    project.versions << Version.generate!(:effective_date => Date.today)
+
+    assert_equal future, project.due_date
+  end
+
+  test "#due_date should pick the latest date from it's issues and versions" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    future = 7.days.from_now.to_date
+    far_future = 14.days.from_now.to_date
+    Issue.generate!(:project => project, :due_date => far_future)
+    project.versions << Version.generate!(:effective_date => future)
+
+    assert_equal far_future, project.due_date
+  end
+
+  test "#completed_percent with no versions should be 100" do
+    project = Project.generate!
+    assert_equal 100, project.completed_percent
+  end
+
+  test "#completed_percent with versions should return 0 if the versions have no issues" do
+    project = Project.generate!
+    Version.generate!(:project => project)
+    Version.generate!(:project => project)
+
+    assert_equal 0, project.completed_percent
+  end
+
+  test "#completed_percent with versions should return 100 if the version has only closed issues" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    v1 = Version.generate!(:project => project)
+    Issue.generate!(:project => project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v1)
+    v2 = Version.generate!(:project => project)
+    Issue.generate!(:project => project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v2)
+
+    assert_equal 100, project.completed_percent
+  end
+
+  test "#completed_percent with versions should return the averaged completed percent of the versions (not weighted)" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    v1 = Version.generate!(:project => project)
+    Issue.generate!(:project => project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v1)
+    v2 = Version.generate!(:project => project)
+    Issue.generate!(:project => project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v2)
+
+    assert_equal 50, project.completed_percent
+  end
+
+  test "#notified_users" do
+    project = Project.generate!
+    role = Role.generate!
+
+    user_with_membership_notification = User.generate!(:mail_notification => 'selected')
+    Member.create!(:project => project, :roles => [role], :principal => user_with_membership_notification, :mail_notification => true)
+
+    all_events_user = User.generate!(:mail_notification => 'all')
+    Member.create!(:project => project, :roles => [role], :principal => all_events_user)
+
+    no_events_user = User.generate!(:mail_notification => 'none')
+    Member.create!(:project => project, :roles => [role], :principal => no_events_user)
+
+    only_my_events_user = User.generate!(:mail_notification => 'only_my_events')
+    Member.create!(:project => project, :roles => [role], :principal => only_my_events_user)
+
+    only_assigned_user = User.generate!(:mail_notification => 'only_assigned')
+    Member.create!(:project => project, :roles => [role], :principal => only_assigned_user)
+
+    only_owned_user = User.generate!(:mail_notification => 'only_owner')
+    Member.create!(:project => project, :roles => [role], :principal => only_owned_user)
+
+    assert project.notified_users.include?(user_with_membership_notification), "should include members with a mail notification"
+    assert project.notified_users.include?(all_events_user), "should include users with the 'all' notification option"
+    assert !project.notified_users.include?(no_events_user), "should not include users with the 'none' notification option"
+    assert !project.notified_users.include?(only_my_events_user), "should not include users with the 'only_my_events' notification option"
+    assert !project.notified_users.include?(only_assigned_user), "should not include users with the 'only_assigned' notification option"
+    assert !project.notified_users.include?(only_owned_user), "should not include users with the 'only_owner' notification option"
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c7dbabe98ae3e574a637d9bbb8d3b6e27e263f8a.svn-base
--- a/.svn/pristine/c7/c7dbabe98ae3e574a637d9bbb8d3b6e27e263f8a.svn-base
+++ /dev/null
@@ -1,75 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class ActivitiesController < ApplicationController
-  menu_item :activity
-  before_filter :find_optional_project
-  accept_rss_auth :index
-
-  def index
-    @days = Setting.activity_days_default.to_i
-
-    if params[:from]
-      begin; @date_to = params[:from].to_date + 1; rescue; end
-    end
-
-    @date_to ||= Date.today + 1
-    @date_from = @date_to - @days
-    @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
-    @author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id]))
-
-    @activity = Redmine::Activity::Fetcher.new(User.current, :project => @project,
-                                                             :with_subprojects => @with_subprojects,
-                                                             :author => @author)
-    @activity.scope_select {|t| !params["show_#{t}"].nil?}
-    @activity.scope = (@author.nil? ? :default : :all) if @activity.scope.empty?
-
-    events = @activity.events(@date_from, @date_to)
-
-    if events.empty? || stale?(:etag => [@activity.scope, @date_to, @date_from, @with_subprojects, @author, events.first, User.current, current_language])
-      respond_to do |format|
-        format.html {
-          @events_by_day = events.group_by(&:event_date)
-          render :layout => false if request.xhr?
-        }
-        format.atom {
-          title = l(:label_activity)
-          if @author
-            title = @author.name
-          elsif @activity.scope.size == 1
-            title = l("label_#{@activity.scope.first.singularize}_plural")
-          end
-          render_feed(events, :title => "#{@project || Setting.app_title}: #{title}")
-        }
-      end
-    end
-
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  private
-
-  # TODO: refactor, duplicated in projects_controller
-  def find_optional_project
-    return true unless params[:id]
-    @project = Project.find(params[:id])
-    authorize
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c7e95199fb385468769aedf565c2d839f1f86093.svn-base
--- /dev/null
+++ b/.svn/pristine/c7/c7e95199fb385468769aedf565c2d839f1f86093.svn-base
@@ -0,0 +1,66 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Watcher < ActiveRecord::Base
+  belongs_to :watchable, :polymorphic => true
+  belongs_to :user
+
+  validates_presence_of :user
+  validates_uniqueness_of :user_id, :scope => [:watchable_type, :watchable_id]
+  validate :validate_user
+
+  # Unwatch things that users are no longer allowed to view
+  def self.prune(options={})
+    if options.has_key?(:user)
+      prune_single_user(options[:user], options)
+    else
+      pruned = 0
+      User.where("id IN (SELECT DISTINCT user_id FROM #{table_name})").all.each do |user|
+        pruned += prune_single_user(user, options)
+      end
+      pruned
+    end
+  end
+
+  protected
+
+  def validate_user
+    errors.add :user_id, :invalid unless user.nil? || user.active?
+  end
+
+  private
+
+  def self.prune_single_user(user, options={})
+    return unless user.is_a?(User)
+    pruned = 0
+    where(:user_id => user.id).all.each do |watcher|
+      next if watcher.watchable.nil?
+
+      if options.has_key?(:project)
+        next unless watcher.watchable.respond_to?(:project) && watcher.watchable.project == options[:project]
+      end
+
+      if watcher.watchable.respond_to?(:visible?)
+        unless watcher.watchable.visible?(user)
+          watcher.destroy
+          pruned += 1
+        end
+      end
+    end
+    pruned
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c7/c7f45701bf3ca95a0ce3920f446037ebb4fbe0a7.svn-base
--- /dev/null
+++ b/.svn/pristine/c7/c7f45701bf3ca95a0ce3920f446037ebb4fbe0a7.svn-base
@@ -0,0 +1,46 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module WikiFormatting
+    module Textile
+      module Helper
+        def wikitoolbar_for(field_id)
+          heads_for_wiki_formatter
+          # Is there a simple way to link to a public resource?
+          url = "#{Redmine::Utils.relative_url_root}/help/wiki_syntax.html"
+          javascript_tag("var wikiToolbar = new jsToolBar(document.getElementById('#{field_id}')); wikiToolbar.setHelpLink('#{escape_javascript url}'); wikiToolbar.draw();")
+        end
+
+        def initial_page_content(page)
+          "h1. #{@page.pretty_title}"
+        end
+
+        def heads_for_wiki_formatter
+          unless @heads_for_wiki_formatter_included
+            content_for :header_tags do
+              javascript_include_tag('jstoolbar/jstoolbar-textile.min') +
+              javascript_include_tag("jstoolbar/lang/jstoolbar-#{current_language.to_s.downcase}") +
+              stylesheet_link_tag('jstoolbar')
+            end
+            @heads_for_wiki_formatter_included = true
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c8/c84d690d9bd0576dfc0e1af20e017bb13ff2e71d.svn-base
--- a/.svn/pristine/c8/c84d690d9bd0576dfc0e1af20e017bb13ff2e71d.svn-base
+++ /dev/null
@@ -1,1311 +0,0 @@
-# $Id: ldap.rb 154 2006-08-15 09:35:43Z blackhedd $
-#
-# Net::LDAP for Ruby
-#
-#
-# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
-#
-# Written and maintained by Francis Cianfrocca, gmail: garbagecat10.
-#
-# This program is free software.
-# You may re-distribute and/or modify this program under the same terms
-# as Ruby itself: Ruby Distribution License or GNU General Public License.
-#
-#
-# See Net::LDAP for documentation and usage samples.
-#
-
-
-require 'socket'
-require 'ostruct'
-
-begin
-  require 'openssl'
-  $net_ldap_openssl_available = true
-rescue LoadError
-end
-
-require 'net/ber'
-require 'net/ldap/pdu'
-require 'net/ldap/filter'
-require 'net/ldap/dataset'
-require 'net/ldap/psw'
-require 'net/ldap/entry'
-
-
-module Net
-
-
-  # == Net::LDAP
-  #
-  # This library provides a pure-Ruby implementation of the
-  # LDAP client protocol, per RFC-2251.
-  # It can be used to access any server which implements the
-  # LDAP protocol.
-  #
-  # Net::LDAP is intended to provide full LDAP functionality
-  # while hiding the more arcane aspects
-  # the LDAP protocol itself, and thus presenting as Ruby-like
-  # a programming interface as possible.
-  # 
-  # == Quick-start for the Impatient
-  # === Quick Example of a user-authentication against an LDAP directory:
-  #
-  #  require 'rubygems'
-  #  require 'net/ldap'
-  #  
-  #  ldap = Net::LDAP.new
-  #  ldap.host = your_server_ip_address
-  #  ldap.port = 389
-  #  ldap.auth "joe_user", "opensesame"
-  #  if ldap.bind
-  #    # authentication succeeded
-  #  else
-  #    # authentication failed
-  #  end
-  #
-  #
-  # === Quick Example of a search against an LDAP directory:
-  #
-  #  require 'rubygems'
-  #  require 'net/ldap'
-  #  
-  #  ldap = Net::LDAP.new :host => server_ip_address,
-  #       :port => 389,
-  #       :auth => {
-  #             :method => :simple,
-  #             :username => "cn=manager,dc=example,dc=com",
-  #             :password => "opensesame"
-  #       }
-  #
-  #  filter = Net::LDAP::Filter.eq( "cn", "George*" )
-  #  treebase = "dc=example,dc=com"
-  #  
-  #  ldap.search( :base => treebase, :filter => filter ) do |entry|
-  #    puts "DN: #{entry.dn}"
-  #    entry.each do |attribute, values|
-  #      puts "   #{attribute}:"
-  #      values.each do |value|
-  #        puts "      --->#{value}"
-  #      end
-  #    end
-  #  end
-  #  
-  #  p ldap.get_operation_result
-  #  
-  #
-  # == A Brief Introduction to LDAP
-  #
-  # We're going to provide a quick, informal introduction to LDAP
-  # terminology and
-  # typical operations. If you're comfortable with this material, skip
-  # ahead to "How to use Net::LDAP." If you want a more rigorous treatment
-  # of this material, we recommend you start with the various IETF and ITU
-  # standards that relate to LDAP.
-  #
-  # === Entities
-  # LDAP is an Internet-standard protocol used to access directory servers.
-  # The basic search unit is the <i>entity,</i> which corresponds to
-  # a person or other domain-specific object.
-  # A directory service which supports the LDAP protocol typically
-  # stores information about a number of entities.
-  #
-  # === Principals
-  # LDAP servers are typically used to access information about people,
-  # but also very often about such items as printers, computers, and other
-  # resources. To reflect this, LDAP uses the term <i>entity,</i> or less
-  # commonly, <i>principal,</i> to denote its basic data-storage unit.
-  # 
-  #
-  # === Distinguished Names
-  # In LDAP's view of the world,
-  # an entity is uniquely identified by a globally-unique text string
-  # called a <i>Distinguished Name,</i> originally defined in the X.400
-  # standards from which LDAP is ultimately derived.
-  # Much like a DNS hostname, a DN is a "flattened" text representation
-  # of a string of tree nodes. Also like DNS (and unlike Java package
-  # names), a DN expresses a chain of tree-nodes written from left to right
-  # in order from the most-resolved node to the most-general one.
-  #
-  # If you know the DN of a person or other entity, then you can query
-  # an LDAP-enabled directory for information (attributes) about the entity.
-  # Alternatively, you can query the directory for a list of DNs matching
-  # a set of criteria that you supply.
-  #
-  # === Attributes
-  #
-  # In the LDAP view of the world, a DN uniquely identifies an entity.
-  # Information about the entity is stored as a set of <i>Attributes.</i>
-  # An attribute is a text string which is associated with zero or more
-  # values. Most LDAP-enabled directories store a well-standardized
-  # range of attributes, and constrain their values according to standard
-  # rules.
-  #
-  # A good example of an attribute is <tt>sn,</tt> which stands for "Surname."
-  # This attribute is generally used to store a person's surname, or last name.
-  # Most directories enforce the standard convention that
-  # an entity's <tt>sn</tt> attribute have <i>exactly one</i> value. In LDAP
-  # jargon, that means that <tt>sn</tt> must be <i>present</i> and
-  # <i>single-valued.</i>
-  #
-  # Another attribute is <tt>mail,</tt> which is used to store email addresses.
-  # (No, there is no attribute called "email," perhaps because X.400 terminology
-  # predates the invention of the term <i>email.</i>) <tt>mail</tt> differs
-  # from <tt>sn</tt> in that most directories permit any number of values for the
-  # <tt>mail</tt> attribute, including zero.
-  #
-  #
-  # === Tree-Base
-  # We said above that X.400 Distinguished Names are <i>globally unique.</i>
-  # In a manner reminiscent of DNS, LDAP supposes that each directory server
-  # contains authoritative attribute data for a set of DNs corresponding
-  # to a specific sub-tree of the (notional) global directory tree.
-  # This subtree is generally configured into a directory server when it is
-  # created. It matters for this discussion because most servers will not
-  # allow you to query them unless you specify a correct tree-base.
-  #
-  # Let's say you work for the engineering department of Big Company, Inc.,
-  # whose internet domain is bigcompany.com. You may find that your departmental
-  # directory is stored in a server with a defined tree-base of
-  #  ou=engineering,dc=bigcompany,dc=com
-  # You will need to supply this string as the <i>tree-base</i> when querying this
-  # directory. (Ou is a very old X.400 term meaning "organizational unit."
-  # Dc is a more recent term meaning "domain component.")
-  #
-  # === LDAP Versions
-  # (stub, discuss v2 and v3)
-  #
-  # === LDAP Operations
-  # The essential operations are: #bind, #search, #add, #modify, #delete, and #rename.
-  # ==== Bind
-  # #bind supplies a user's authentication credentials to a server, which in turn verifies
-  # or rejects them. There is a range of possibilities for credentials, but most directories
-  # support a simple username and password authentication.
-  #
-  # Taken by itself, #bind can be used to authenticate a user against information
-  # stored in a directory, for example to permit or deny access to some other resource.
-  # In terms of the other LDAP operations, most directories require a successful #bind to
-  # be performed before the other operations will be permitted. Some servers permit certain
-  # operations to be performed with an "anonymous" binding, meaning that no credentials are
-  # presented by the user. (We're glossing over a lot of platform-specific detail here.)
-  #
-  # ==== Search
-  # Calling #search against the directory involves specifying a treebase, a set of <i>search filters,</i>
-  # and a list of attribute values.
-  # The filters specify ranges of possible values for particular attributes. Multiple
-  # filters can be joined together with AND, OR, and NOT operators.
-  # A server will respond to a #search by returning a list of matching DNs together with a
-  # set of attribute values for each entity, depending on what attributes the search requested.
-  # 
-  # ==== Add
-  # #add specifies a new DN and an initial set of attribute values. If the operation
-  # succeeds, a new entity with the corresponding DN and attributes is added to the directory.
-  #
-  # ==== Modify
-  # #modify specifies an entity DN, and a list of attribute operations. #modify is used to change
-  # the attribute values stored in the directory for a particular entity.
-  # #modify may add or delete attributes (which are lists of values) or it change attributes by
-  # adding to or deleting from their values.
-  # Net::LDAP provides three easier methods to modify an entry's attribute values:
-  # #add_attribute, #replace_attribute, and #delete_attribute.
-  #
-  # ==== Delete
-  # #delete specifies an entity DN. If it succeeds, the entity and all its attributes
-  # is removed from the directory.
-  #
-  # ==== Rename (or Modify RDN)
-  # #rename (or #modify_rdn) is an operation added to version 3 of the LDAP protocol. It responds to
-  # the often-arising need to change the DN of an entity without discarding its attribute values.
-  # In earlier LDAP versions, the only way to do this was to delete the whole entity and add it
-  # again with a different DN.
-  #
-  # #rename works by taking an "old" DN (the one to change) and a "new RDN," which is the left-most
-  # part of the DN string. If successful, #rename changes the entity DN so that its left-most
-  # node corresponds to the new RDN given in the request. (RDN, or "relative distinguished name,"
-  # denotes a single tree-node as expressed in a DN, which is a chain of tree nodes.)
-  #
-  # == How to use Net::LDAP
-  #
-  # To access Net::LDAP functionality in your Ruby programs, start by requiring
-  # the library:
-  #
-  #  require 'net/ldap'
-  #
-  # If you installed the Gem version of Net::LDAP, and depending on your version of
-  # Ruby and rubygems, you _may_ also need to require rubygems explicitly:
-  #
-  #  require 'rubygems'
-  #  require 'net/ldap'
-  #
-  # Most operations with Net::LDAP start by instantiating a Net::LDAP object.
-  # The constructor for this object takes arguments specifying the network location
-  # (address and port) of the LDAP server, and also the binding (authentication)
-  # credentials, typically a username and password.
-  # Given an object of class Net:LDAP, you can then perform LDAP operations by calling
-  # instance methods on the object. These are documented with usage examples below.
-  #
-  # The Net::LDAP library is designed to be very disciplined about how it makes network
-  # connections to servers. This is different from many of the standard native-code
-  # libraries that are provided on most platforms, which share bloodlines with the
-  # original Netscape/Michigan LDAP client implementations. These libraries sought to
-  # insulate user code from the workings of the network. This is a good idea of course,
-  # but the practical effect has been confusing and many difficult bugs have been caused
-  # by the opacity of the native libraries, and their variable behavior across platforms.
-  #
-  # In general, Net::LDAP instance methods which invoke server operations make a connection
-  # to the server when the method is called. They execute the operation (typically binding first)
-  # and then disconnect from the server. The exception is Net::LDAP#open, which makes a connection
-  # to the server and then keeps it open while it executes a user-supplied block. Net::LDAP#open
-  # closes the connection on completion of the block.
-  #
-
-  class LDAP
-
-    class LdapError < Exception; end
-
-    VERSION = "0.0.4"
-
-
-    SearchScope_BaseObject = 0
-    SearchScope_SingleLevel = 1
-    SearchScope_WholeSubtree = 2
-    SearchScopes = [SearchScope_BaseObject, SearchScope_SingleLevel, SearchScope_WholeSubtree]
-
-    AsnSyntax = {
-      :application => {
-        :constructed => {
-          0 => :array,              # BindRequest
-          1 => :array,              # BindResponse
-          2 => :array,              # UnbindRequest
-          3 => :array,              # SearchRequest
-          4 => :array,              # SearchData
-          5 => :array,              # SearchResult
-          6 => :array,              # ModifyRequest
-          7 => :array,              # ModifyResponse
-          8 => :array,              # AddRequest
-          9 => :array,              # AddResponse
-          10 => :array,             # DelRequest
-          11 => :array,             # DelResponse
-          12 => :array,             # ModifyRdnRequest
-          13 => :array,             # ModifyRdnResponse
-          14 => :array,             # CompareRequest
-          15 => :array,             # CompareResponse
-          16 => :array,             # AbandonRequest
-          19 => :array,             # SearchResultReferral
-          24 => :array,             # Unsolicited Notification
-        }
-      },
-      :context_specific => {
-        :primitive => {
-          0 => :string,             # password
-          1 => :string,             # Kerberos v4
-          2 => :string,             # Kerberos v5
-        },
-        :constructed => {
-          0 => :array,              # RFC-2251 Control
-          3 => :array,              # Seach referral
-        }
-      }
-    }
-
-    DefaultHost = "127.0.0.1"
-    DefaultPort = 389
-    DefaultAuth = {:method => :anonymous}
-    DefaultTreebase = "dc=com"
-
-
-    ResultStrings = {
-      0 => "Success",
-      1 => "Operations Error",
-      2 => "Protocol Error",
-      3 => "Time Limit Exceeded",
-      4 => "Size Limit Exceeded",
-      12 => "Unavailable crtical extension",
-      16 => "No Such Attribute",
-      17 => "Undefined Attribute Type",
-      20 => "Attribute or Value Exists",
-      32 => "No Such Object",
-      34 => "Invalid DN Syntax",
-      48 => "Invalid DN Syntax",
-      48 => "Inappropriate Authentication",
-      49 => "Invalid Credentials",
-      50 => "Insufficient Access Rights",
-      51 => "Busy",
-      52 => "Unavailable",
-      53 => "Unwilling to perform",
-      65 => "Object Class Violation",
-      68 => "Entry Already Exists"
-    }
-
-
-    module LdapControls
-      PagedResults = "1.2.840.113556.1.4.319" # Microsoft evil from RFC 2696
-    end
-
-
-    #
-    # LDAP::result2string
-    #
-    def LDAP::result2string code # :nodoc:
-      ResultStrings[code] || "unknown result (#{code})"
-    end 
-
-
-    attr_accessor :host, :port, :base
-
-
-    # Instantiate an object of type Net::LDAP to perform directory operations.
-    # This constructor takes a Hash containing arguments, all of which are either optional or may be specified later with other methods as described below. The following arguments
-    # are supported:
-    # * :host => the LDAP server's IP-address (default 127.0.0.1)
-    # * :port => the LDAP server's TCP port (default 389)
-    # * :auth => a Hash containing authorization parameters. Currently supported values include:
-    #   {:method => :anonymous} and
-    #   {:method => :simple, :username => your_user_name, :password => your_password }
-    #   The password parameter may be a Proc that returns a String.
-    # * :base => a default treebase parameter for searches performed against the LDAP server. If you don't give this value, then each call to #search must specify a treebase parameter. If you do give this value, then it will be used in subsequent calls to #search that do not specify a treebase. If you give a treebase value in any particular call to #search, that value will override any treebase value you give here.
-    # * :encryption => specifies the encryption to be used in communicating with the LDAP server. The value is either a Hash containing additional parameters, or the Symbol :simple_tls, which is equivalent to specifying the Hash {:method => :simple_tls}. There is a fairly large range of potential values that may be given for this parameter. See #encryption for details.
-    #
-    # Instantiating a Net::LDAP object does <i>not</i> result in network traffic to
-    # the LDAP server. It simply stores the connection and binding parameters in the
-    # object.
-    #
-    def initialize args = {}
-      @host = args[:host] || DefaultHost
-      @port = args[:port] || DefaultPort
-      @verbose = false # Make this configurable with a switch on the class.
-      @auth = args[:auth] || DefaultAuth
-      @base = args[:base] || DefaultTreebase
-      encryption args[:encryption] # may be nil
-
-      if pr = @auth[:password] and pr.respond_to?(:call)
-        @auth[:password] = pr.call
-      end
-
-      # This variable is only set when we are created with LDAP::open.
-      # All of our internal methods will connect using it, or else
-      # they will create their own.
-      @open_connection = nil
-    end
-
-    # Convenience method to specify authentication credentials to the LDAP
-    # server. Currently supports simple authentication requiring
-    # a username and password.
-    #
-    # Observe that on most LDAP servers,
-    # the username is a complete DN. However, with A/D, it's often possible
-    # to give only a user-name rather than a complete DN. In the latter
-    # case, beware that many A/D servers are configured to permit anonymous
-    # (uncredentialled) binding, and will silently accept your binding
-    # as anonymous if you give an unrecognized username. This is not usually
-    # what you want. (See #get_operation_result.)
-    #
-    # <b>Important:</b> The password argument may be a Proc that returns a string.
-    # This makes it possible for you to write client programs that solicit
-    # passwords from users or from other data sources without showing them
-    # in your code or on command lines.
-    #
-    #  require 'net/ldap'
-    #  
-    #  ldap = Net::LDAP.new
-    #  ldap.host = server_ip_address
-    #  ldap.authenticate "cn=Your Username,cn=Users,dc=example,dc=com", "your_psw"
-    #
-    # Alternatively (with a password block):
-    #
-    #  require 'net/ldap'
-    #  
-    #  ldap = Net::LDAP.new
-    #  ldap.host = server_ip_address
-    #  psw = proc { your_psw_function }
-    #  ldap.authenticate "cn=Your Username,cn=Users,dc=example,dc=com", psw
-    #
-    def authenticate username, password
-      password = password.call if password.respond_to?(:call)
-      @auth = {:method => :simple, :username => username, :password => password}
-    end
-
-    alias_method :auth, :authenticate
-
-    # Convenience method to specify encryption characteristics for connections
-    # to LDAP servers. Called implicitly by #new and #open, but may also be called
-    # by user code if desired.
-    # The single argument is generally a Hash (but see below for convenience alternatives).
-    # This implementation is currently a stub, supporting only a few encryption
-    # alternatives. As additional capabilities are added, more configuration values
-    # will be added here.
-    #
-    # Currently, the only supported argument is {:method => :simple_tls}.
-    # (Equivalently, you may pass the symbol :simple_tls all by itself, without
-    # enclosing it in a Hash.)
-    #
-    # The :simple_tls encryption method encrypts <i>all</i> communications with the LDAP
-    # server.
-    # It completely establishes SSL/TLS encryption with the LDAP server 
-    # before any LDAP-protocol data is exchanged.
-    # There is no plaintext negotiation and no special encryption-request controls
-    # are sent to the server. 
-    # <i>The :simple_tls option is the simplest, easiest way to encrypt communications
-    # between Net::LDAP and LDAP servers.</i>
-    # It's intended for cases where you have an implicit level of trust in the authenticity
-    # of the LDAP server. No validation of the LDAP server's SSL certificate is
-    # performed. This means that :simple_tls will not produce errors if the LDAP
-    # server's encryption certificate is not signed by a well-known Certification
-    # Authority.
-    # If you get communications or protocol errors when using this option, check
-    # with your LDAP server administrator. Pay particular attention to the TCP port
-    # you are connecting to. It's impossible for an LDAP server to support plaintext
-    # LDAP communications and <i>simple TLS</i> connections on the same port.
-    # The standard TCP port for unencrypted LDAP connections is 389, but the standard
-    # port for simple-TLS encrypted connections is 636. Be sure you are using the
-    # correct port.
-    #
-    # <i>[Note: a future version of Net::LDAP will support the STARTTLS LDAP control,
-    # which will enable encrypted communications on the same TCP port used for
-    # unencrypted connections.]</i>
-    #
-    def encryption args
-      if args == :simple_tls
-        args = {:method => :simple_tls}
-      end
-      @encryption = args
-    end
-
-
-    # #open takes the same parameters as #new. #open makes a network connection to the
-    # LDAP server and then passes a newly-created Net::LDAP object to the caller-supplied block.
-    # Within the block, you can call any of the instance methods of Net::LDAP to
-    # perform operations against the LDAP directory. #open will perform all the
-    # operations in the user-supplied block on the same network connection, which
-    # will be closed automatically when the block finishes.
-    #
-    #  # (PSEUDOCODE)
-    #  auth = {:method => :simple, :username => username, :password => password}
-    #  Net::LDAP.open( :host => ipaddress, :port => 389, :auth => auth ) do |ldap|
-    #    ldap.search( ... )
-    #    ldap.add( ... )
-    #    ldap.modify( ... )
-    #  end
-    #
-    def LDAP::open args
-      ldap1 = LDAP.new args
-      ldap1.open {|ldap| yield ldap }
-    end
-
-    # Returns a meaningful result any time after
-    # a protocol operation (#bind, #search, #add, #modify, #rename, #delete)
-    # has completed.
-    # It returns an #OpenStruct containing an LDAP result code (0 means success),
-    # and a human-readable string.
-    #  unless ldap.bind
-    #    puts "Result: #{ldap.get_operation_result.code}"
-    #    puts "Message: #{ldap.get_operation_result.message}"
-    #  end
-    #
-    def get_operation_result
-      os = OpenStruct.new
-      if @result
-        os.code = @result
-      else
-        os.code = 0
-      end
-      os.message = LDAP.result2string( os.code )
-      os
-    end
-
-
-    # Opens a network connection to the server and then
-    # passes <tt>self</tt> to the caller-supplied block. The connection is
-    # closed when the block completes. Used for executing multiple
-    # LDAP operations without requiring a separate network connection
-    # (and authentication) for each one.
-    # <i>Note:</i> You do not need to log-in or "bind" to the server. This will
-    # be done for you automatically.
-    # For an even simpler approach, see the class method Net::LDAP#open.
-    #
-    #  # (PSEUDOCODE)
-    #  auth = {:method => :simple, :username => username, :password => password}
-    #  ldap = Net::LDAP.new( :host => ipaddress, :port => 389, :auth => auth )
-    #  ldap.open do |ldap|
-    #    ldap.search( ... )
-    #    ldap.add( ... )
-    #    ldap.modify( ... )
-    #  end
-    #--
-    # First we make a connection and then a binding, but we don't
-    # do anything with the bind results.
-    # We then pass self to the caller's block, where he will execute
-    # his LDAP operations. Of course they will all generate auth failures
-    # if the bind was unsuccessful.
-    def open
-      raise LdapError.new( "open already in progress" ) if @open_connection
-      @open_connection = Connection.new( :host => @host, :port => @port, :encryption => @encryption )
-      @open_connection.bind @auth
-      yield self
-      @open_connection.close
-      @open_connection = nil
-    end
-
-
-    # Searches the LDAP directory for directory entries.
-    # Takes a hash argument with parameters. Supported parameters include:
-    # * :base (a string specifying the tree-base for the search);
-    # * :filter (an object of type Net::LDAP::Filter, defaults to objectclass=*);
-    # * :attributes (a string or array of strings specifying the LDAP attributes to return from the server);
-    # * :return_result (a boolean specifying whether to return a result set).
-    # * :attributes_only (a boolean flag, defaults false)
-    # * :scope (one of: Net::LDAP::SearchScope_BaseObject, Net::LDAP::SearchScope_SingleLevel, Net::LDAP::SearchScope_WholeSubtree. Default is WholeSubtree.)
-    #
-    # #search queries the LDAP server and passes <i>each entry</i> to the
-    # caller-supplied block, as an object of type Net::LDAP::Entry.
-    # If the search returns 1000 entries, the block will
-    # be called 1000 times. If the search returns no entries, the block will
-    # not be called.
-    #
-    #--
-    # ORIGINAL TEXT, replaced 04May06.
-    # #search returns either a result-set or a boolean, depending on the
-    # value of the <tt>:return_result</tt> argument. The default behavior is to return
-    # a result set, which is a hash. Each key in the hash is a string specifying
-    # the DN of an entry. The corresponding value for each key is a Net::LDAP::Entry object.
-    # If you request a result set and #search fails with an error, it will return nil.
-    # Call #get_operation_result to get the error information returned by
-    # the LDAP server.
-    #++
-    # #search returns either a result-set or a boolean, depending on the
-    # value of the <tt>:return_result</tt> argument. The default behavior is to return
-    # a result set, which is an Array of objects of class Net::LDAP::Entry.
-    # If you request a result set and #search fails with an error, it will return nil.
-    # Call #get_operation_result to get the error information returned by
-    # the LDAP server.
-    #
-    # When <tt>:return_result => false,</tt> #search will
-    # return only a Boolean, to indicate whether the operation succeeded. This can improve performance
-    # with very large result sets, because the library can discard each entry from memory after
-    # your block processes it.
-    #
-    #
-    #  treebase = "dc=example,dc=com"
-    #  filter = Net::LDAP::Filter.eq( "mail", "a*.com" )
-    #  attrs = ["mail", "cn", "sn", "objectclass"]
-    #  ldap.search( :base => treebase, :filter => filter, :attributes => attrs, :return_result => false ) do |entry|
-    #    puts "DN: #{entry.dn}"
-    #    entry.each do |attr, values|
-    #      puts ".......#{attr}:"
-    #      values.each do |value|
-    #        puts "          #{value}"
-    #      end
-    #    end
-    #  end
-    #
-    #--
-    # This is a re-implementation of search that replaces the
-    # original one (now renamed searchx and possibly destined to go away).
-    # The difference is that we return a dataset (or nil) from the
-    # call, and pass _each entry_ as it is received from the server
-    # to the caller-supplied block. This will probably make things
-    # far faster as we can do useful work during the network latency
-    # of the search. The downside is that we have no access to the
-    # whole set while processing the blocks, so we can't do stuff
-    # like sort the DNs until after the call completes.
-    # It's also possible that this interacts badly with server timeouts.
-    # We'll have to ensure that something reasonable happens if
-    # the caller has processed half a result set when we throw a timeout
-    # error.
-    # Another important difference is that we return a result set from
-    # this method rather than a T/F indication.
-    # Since this can be very heavy-weight, we define an argument flag
-    # that the caller can set to suppress the return of a result set,
-    # if he's planning to process every entry as it comes from the server.
-    #
-    # REINTERPRETED the result set, 04May06. Originally this was a hash
-    # of entries keyed by DNs. But let's get away from making users
-    # handle DNs. Change it to a plain array. Eventually we may
-    # want to return a Dataset object that delegates to an internal
-    # array, so we can provide sort methods and what-not.
-    #
-    def search args = {}
-      args[:base] ||= @base
-      result_set = (args and args[:return_result] == false) ? nil : []
-
-      if @open_connection
-        @result = @open_connection.search( args ) {|entry|
-          result_set << entry if result_set
-          yield( entry ) if block_given?
-        }
-      else
-        @result = 0
-        conn = Connection.new( :host => @host, :port => @port, :encryption => @encryption )
-        if (@result = conn.bind( args[:auth] || @auth )) == 0
-          @result = conn.search( args ) {|entry|
-            result_set << entry if result_set
-            yield( entry ) if block_given?
-          }
-        end
-        conn.close
-      end
-
-      @result == 0 and result_set
-    end
-
-    # #bind connects to an LDAP server and requests authentication
-    # based on the <tt>:auth</tt> parameter passed to #open or #new.
-    # It takes no parameters.
-    #
-    # User code does not need to call #bind directly. It will be called
-    # implicitly by the library whenever you invoke an LDAP operation,
-    # such as #search or #add.
-    #
-    # It is useful, however, to call #bind in your own code when the
-    # only operation you intend to perform against the directory is
-    # to validate a login credential. #bind returns true or false
-    # to indicate whether the binding was successful. Reasons for
-    # failure include malformed or unrecognized usernames and
-    # incorrect passwords. Use #get_operation_result to find out
-    # what happened in case of failure.
-    #
-    # Here's a typical example using #bind to authenticate a
-    # credential which was (perhaps) solicited from the user of a
-    # web site:
-    #
-    #  require 'net/ldap'
-    #  ldap = Net::LDAP.new
-    #  ldap.host = your_server_ip_address
-    #  ldap.port = 389
-    #  ldap.auth your_user_name, your_user_password
-    #  if ldap.bind
-    #    # authentication succeeded
-    #  else
-    #    # authentication failed
-    #    p ldap.get_operation_result
-    #  end
-    #
-    # You don't have to create a new instance of Net::LDAP every time
-    # you perform a binding in this way. If you prefer, you can cache the Net::LDAP object
-    # and re-use it to perform subsequent bindings, <i>provided</i> you call
-    # #auth to specify a new credential before calling #bind. Otherwise, you'll
-    # just re-authenticate the previous user! (You don't need to re-set
-    # the values of #host and #port.) As noted in the documentation for #auth,
-    # the password parameter can be a Ruby Proc instead of a String.
-    #
-    #--
-    # If there is an @open_connection, then perform the bind
-    # on it. Otherwise, connect, bind, and disconnect.
-    # The latter operation is obviously useful only as an auth check.
-    #
-    def bind auth=@auth
-      if @open_connection
-        @result = @open_connection.bind auth
-      else
-        conn = Connection.new( :host => @host, :port => @port , :encryption => @encryption)
-        @result = conn.bind @auth
-        conn.close
-      end
-
-      @result == 0
-    end
-
-    #
-    # #bind_as is for testing authentication credentials.
-    #
-    # As described under #bind, most LDAP servers require that you supply a complete DN
-    # as a binding-credential, along with an authenticator such as a password.
-    # But for many applications (such as authenticating users to a Rails application),
-    # you often don't have a full DN to identify the user. You usually get a simple
-    # identifier like a username or an email address, along with a password.
-    # #bind_as allows you to authenticate these user-identifiers.
-    #
-    # #bind_as is a combination of a search and an LDAP binding. First, it connects and
-    # binds to the directory as normal. Then it searches the directory for an entry
-    # corresponding to the email address, username, or other string that you supply.
-    # If the entry exists, then #bind_as will <b>re-bind</b> as that user with the
-    # password (or other authenticator) that you supply.
-    #
-    # #bind_as takes the same parameters as #search, <i>with the addition of an
-    # authenticator.</i> Currently, this authenticator must be <tt>:password</tt>.
-    # Its value may be either a String, or a +proc+ that returns a String.
-    # #bind_as returns +false+ on failure. On success, it returns a result set,
-    # just as #search does. This result set is an Array of objects of
-    # type Net::LDAP::Entry. It contains the directory attributes corresponding to
-    # the user. (Just test whether the return value is logically true, if you don't
-    # need this additional information.)
-    #
-    # Here's how you would use #bind_as to authenticate an email address and password:
-    #
-    #  require 'net/ldap'
-    #  
-    #  user,psw = "joe_user@yourcompany.com", "joes_psw"
-    #  
-    #  ldap = Net::LDAP.new
-    #  ldap.host = "192.168.0.100"
-    #  ldap.port = 389
-    #  ldap.auth "cn=manager,dc=yourcompany,dc=com", "topsecret"
-    #  
-    #  result = ldap.bind_as(
-    #    :base => "dc=yourcompany,dc=com",
-    #    :filter => "(mail=#{user})",
-    #    :password => psw
-    #  )
-    #  if result
-    #    puts "Authenticated #{result.first.dn}"
-    #  else
-    #    puts "Authentication FAILED."
-    #  end
-    def bind_as args={}
-      result = false
-      open {|me|
-        rs = search args
-        if rs and rs.first and dn = rs.first.dn
-          password = args[:password]
-          password = password.call if password.respond_to?(:call)
-          result = rs if bind :method => :simple, :username => dn, :password => password
-        end
-      }
-      result
-    end
-
-
-    # Adds a new entry to the remote LDAP server.
-    # Supported arguments:
-    # :dn :: Full DN of the new entry
-    # :attributes :: Attributes of the new entry.
-    #
-    # The attributes argument is supplied as a Hash keyed by Strings or Symbols
-    # giving the attribute name, and mapping to Strings or Arrays of Strings
-    # giving the actual attribute values. Observe that most LDAP directories
-    # enforce schema constraints on the attributes contained in entries.
-    # #add will fail with a server-generated error if your attributes violate
-    # the server-specific constraints.
-    # Here's an example:
-    #
-    #  dn = "cn=George Smith,ou=people,dc=example,dc=com"
-    #  attr = {
-    #    :cn => "George Smith",
-    #    :objectclass => ["top", "inetorgperson"],
-    #    :sn => "Smith",
-    #    :mail => "gsmith@example.com"
-    #  }
-    #  Net::LDAP.open (:host => host) do |ldap|
-    #    ldap.add( :dn => dn, :attributes => attr )
-    #  end
-    #
-    def add args
-      if @open_connection
-          @result = @open_connection.add( args )
-      else
-        @result = 0
-        conn = Connection.new( :host => @host, :port => @port, :encryption => @encryption)
-        if (@result = conn.bind( args[:auth] || @auth )) == 0
-          @result = conn.add( args )
-        end
-        conn.close
-      end
-      @result == 0
-    end
-
-
-    # Modifies the attribute values of a particular entry on the LDAP directory.
-    # Takes a hash with arguments. Supported arguments are:
-    # :dn :: (the full DN of the entry whose attributes are to be modified)
-    # :operations :: (the modifications to be performed, detailed next)
-    #
-    # This method returns True or False to indicate whether the operation
-    # succeeded or failed, with extended information available by calling
-    # #get_operation_result.
-    #
-    # Also see #add_attribute, #replace_attribute, or #delete_attribute, which
-    # provide simpler interfaces to this functionality.
-    #
-    # The LDAP protocol provides a full and well thought-out set of operations
-    # for changing the values of attributes, but they are necessarily somewhat complex
-    # and not always intuitive. If these instructions are confusing or incomplete,
-    # please send us email or create a bug report on rubyforge.
-    #
-    # The :operations parameter to #modify takes an array of operation-descriptors.
-    # Each individual operation is specified in one element of the array, and
-    # most LDAP servers will attempt to perform the operations in order.
-    #
-    # Each of the operations appearing in the Array must itself be an Array
-    # with exactly three elements:
-    # an operator:: must be :add, :replace, or :delete
-    # an attribute name:: the attribute name (string or symbol) to modify
-    # a value:: either a string or an array of strings.
-    #
-    # The :add operator will, unsurprisingly, add the specified values to
-    # the specified attribute. If the attribute does not already exist,
-    # :add will create it. Most LDAP servers will generate an error if you
-    # try to add a value that already exists.
-    #
-    # :replace will erase the current value(s) for the specified attribute,
-    # if there are any, and replace them with the specified value(s).
-    #
-    # :delete will remove the specified value(s) from the specified attribute.
-    # If you pass nil, an empty string, or an empty array as the value parameter
-    # to a :delete operation, the _entire_ _attribute_ will be deleted, along
-    # with all of its values.
-    #
-    # For example:
-    #
-    #  dn = "mail=modifyme@example.com,ou=people,dc=example,dc=com"
-    #  ops = [
-    #    [:add, :mail, "aliasaddress@example.com"],
-    #    [:replace, :mail, ["newaddress@example.com", "newalias@example.com"]],
-    #    [:delete, :sn, nil]
-    #  ]
-    #  ldap.modify :dn => dn, :operations => ops
-    #
-    # <i>(This example is contrived since you probably wouldn't add a mail
-    # value right before replacing the whole attribute, but it shows that order
-    # of execution matters. Also, many LDAP servers won't let you delete SN
-    # because that would be a schema violation.)</i>
-    #
-    # It's essential to keep in mind that if you specify more than one operation in
-    # a call to #modify, most LDAP servers will attempt to perform all of the operations
-    # in the order you gave them.
-    # This matters because you may specify operations on the
-    # same attribute which must be performed in a certain order.
-    #
-    # Most LDAP servers will _stop_ processing your modifications if one of them
-    # causes an error on the server (such as a schema-constraint violation).
-    # If this happens, you will probably get a result code from the server that
-    # reflects only the operation that failed, and you may or may not get extended
-    # information that will tell you which one failed. #modify has no notion
-    # of an atomic transaction. If you specify a chain of modifications in one
-    # call to #modify, and one of them fails, the preceding ones will usually
-    # not be "rolled back," resulting in a partial update. This is a limitation
-    # of the LDAP protocol, not of Net::LDAP.
-    #
-    # The lack of transactional atomicity in LDAP means that you're usually
-    # better off using the convenience methods #add_attribute, #replace_attribute,
-    # and #delete_attribute, which are are wrappers over #modify. However, certain
-    # LDAP servers may provide concurrency semantics, in which the several operations
-    # contained in a single #modify call are not interleaved with other
-    # modification-requests received simultaneously by the server.
-    # It bears repeating that this concurrency does _not_ imply transactional
-    # atomicity, which LDAP does not provide.
-    #
-    def modify args
-      if @open_connection
-          @result = @open_connection.modify( args )
-      else
-        @result = 0
-        conn = Connection.new( :host => @host, :port => @port, :encryption => @encryption )
-        if (@result = conn.bind( args[:auth] || @auth )) == 0
-          @result = conn.modify( args )
-        end
-        conn.close
-      end
-      @result == 0
-    end
-
-
-    # Add a value to an attribute.
-    # Takes the full DN of the entry to modify,
-    # the name (Symbol or String) of the attribute, and the value (String or
-    # Array). If the attribute does not exist (and there are no schema violations),
-    # #add_attribute will create it with the caller-specified values.
-    # If the attribute already exists (and there are no schema violations), the
-    # caller-specified values will be _added_ to the values already present.
-    #
-    # Returns True or False to indicate whether the operation
-    # succeeded or failed, with extended information available by calling
-    # #get_operation_result. See also #replace_attribute and #delete_attribute.
-    #
-    #  dn = "cn=modifyme,dc=example,dc=com"
-    #  ldap.add_attribute dn, :mail, "newmailaddress@example.com"
-    #
-    def add_attribute dn, attribute, value
-      modify :dn => dn, :operations => [[:add, attribute, value]]
-    end
-
-    # Replace the value of an attribute.
-    # #replace_attribute can be thought of as equivalent to calling #delete_attribute
-    # followed by #add_attribute. It takes the full DN of the entry to modify,
-    # the name (Symbol or String) of the attribute, and the value (String or
-    # Array). If the attribute does not exist, it will be created with the
-    # caller-specified value(s). If the attribute does exist, its values will be
-    # _discarded_ and replaced with the caller-specified values.
-    #
-    # Returns True or False to indicate whether the operation
-    # succeeded or failed, with extended information available by calling
-    # #get_operation_result. See also #add_attribute and #delete_attribute.
-    #
-    #  dn = "cn=modifyme,dc=example,dc=com"
-    #  ldap.replace_attribute dn, :mail, "newmailaddress@example.com"
-    #
-    def replace_attribute dn, attribute, value
-      modify :dn => dn, :operations => [[:replace, attribute, value]]
-    end
-
-    # Delete an attribute and all its values.
-    # Takes the full DN of the entry to modify, and the
-    # name (Symbol or String) of the attribute to delete.
-    #
-    # Returns True or False to indicate whether the operation
-    # succeeded or failed, with extended information available by calling
-    # #get_operation_result. See also #add_attribute and #replace_attribute.
-    #
-    #  dn = "cn=modifyme,dc=example,dc=com"
-    #  ldap.delete_attribute dn, :mail
-    #
-    def delete_attribute dn, attribute
-      modify :dn => dn, :operations => [[:delete, attribute, nil]]
-    end
-
-
-    # Rename an entry on the remote DIS by changing the last RDN of its DN.
-    # _Documentation_ _stub_
-    #
-    def rename args
-      if @open_connection
-          @result = @open_connection.rename( args )
-      else
-        @result = 0
-        conn = Connection.new( :host => @host, :port => @port, :encryption => @encryption )
-        if (@result = conn.bind( args[:auth] || @auth )) == 0
-          @result = conn.rename( args )
-        end
-        conn.close
-      end
-      @result == 0
-    end
-
-    # modify_rdn is an alias for #rename.
-    def modify_rdn args
-      rename args
-    end
-
-    # Delete an entry from the LDAP directory.
-    # Takes a hash of arguments.
-    # The only supported argument is :dn, which must
-    # give the complete DN of the entry to be deleted.
-    # Returns True or False to indicate whether the delete
-    # succeeded. Extended status information is available by
-    # calling #get_operation_result.
-    #
-    #  dn = "mail=deleteme@example.com,ou=people,dc=example,dc=com"
-    #  ldap.delete :dn => dn
-    #
-    def delete args
-      if @open_connection
-          @result = @open_connection.delete( args )
-      else
-        @result = 0
-        conn = Connection.new( :host => @host, :port => @port, :encryption => @encryption )
-        if (@result = conn.bind( args[:auth] || @auth )) == 0
-          @result = conn.delete( args )
-        end
-        conn.close
-      end
-      @result == 0
-    end
-
-  end # class LDAP
-
-
-
-  class LDAP
-  # This is a private class used internally by the library. It should not be called by user code.
-  class Connection # :nodoc:
-
-    LdapVersion = 3
-
-
-    #--
-    # initialize
-    #
-    def initialize server
-      begin
-        @conn = TCPsocket.new( server[:host], server[:port] )
-      rescue
-        raise LdapError.new( "no connection to server" )
-      end
-
-      if server[:encryption]
-        setup_encryption server[:encryption]
-      end
-
-      yield self if block_given?
-    end
-
-
-    #--
-    # Helper method called only from new, and only after we have a successfully-opened
-    # @conn instance variable, which is a TCP connection.
-    # Depending on the received arguments, we establish SSL, potentially replacing
-    # the value of @conn accordingly.
-    # Don't generate any errors here if no encryption is requested.
-    # DO raise LdapError objects if encryption is requested and we have trouble setting
-    # it up. That includes if OpenSSL is not set up on the machine. (Question:
-    # how does the Ruby OpenSSL wrapper react in that case?)
-    # DO NOT filter exceptions raised by the OpenSSL library. Let them pass back
-    # to the user. That should make it easier for us to debug the problem reports.
-    # Presumably (hopefully?) that will also produce recognizable errors if someone
-    # tries to use this on a machine without OpenSSL.
-    #
-    # The simple_tls method is intended as the simplest, stupidest, easiest solution
-    # for people who want nothing more than encrypted comms with the LDAP server.
-    # It doesn't do any server-cert validation and requires nothing in the way
-    # of key files and root-cert files, etc etc.
-    # OBSERVE: WE REPLACE the value of @conn, which is presumed to be a connected
-    # TCPsocket object.
-    #
-    def setup_encryption args
-      case args[:method]
-      when :simple_tls
-        raise LdapError.new("openssl unavailable") unless $net_ldap_openssl_available
-        ctx = OpenSSL::SSL::SSLContext.new
-        @conn = OpenSSL::SSL::SSLSocket.new(@conn, ctx)
-        @conn.connect
-        @conn.sync_close = true
-      # additional branches requiring server validation and peer certs, etc. go here.
-      else
-        raise LdapError.new( "unsupported encryption method #{args[:method]}" )
-      end
-    end
-
-    #--
-    # close
-    # This is provided as a convenience method to make
-    # sure a connection object gets closed without waiting
-    # for a GC to happen. Clients shouldn't have to call it,
-    # but perhaps it will come in handy someday.
-    def close
-      @conn.close
-      @conn = nil
-    end
-
-    #--
-    # next_msgid
-    #
-    def next_msgid
-      @msgid ||= 0
-      @msgid += 1
-    end
-
-
-    #--
-    # bind
-    #
-    def bind auth
-      user,psw = case auth[:method]
-      when :anonymous
-        ["",""]
-      when :simple
-        [auth[:username] || auth[:dn], auth[:password]]
-      end
-      raise LdapError.new( "invalid binding information" ) unless (user && psw)
-
-      msgid = next_msgid.to_ber
-      request = [LdapVersion.to_ber, user.to_ber, psw.to_ber_contextspecific(0)].to_ber_appsequence(0)
-      request_pkt = [msgid, request].to_ber_sequence
-      @conn.write request_pkt
-
-      (be = @conn.read_ber(AsnSyntax) and pdu = Net::LdapPdu.new( be )) or raise LdapError.new( "no bind result" )
-      pdu.result_code
-    end
-
-    #--
-    # search
-    # Alternate implementation, this yields each search entry to the caller
-    # as it are received.
-    # TODO, certain search parameters are hardcoded.
-    # TODO, if we mis-parse the server results or the results are wrong, we can block
-    # forever. That's because we keep reading results until we get a type-5 packet,
-    # which might never come. We need to support the time-limit in the protocol.
-    #--
-    # WARNING: this code substantially recapitulates the searchx method.
-    #
-    # 02May06: Well, I added support for RFC-2696-style paged searches.
-    # This is used on all queries because the extension is marked non-critical.
-    # As far as I know, only A/D uses this, but it's required for A/D. Otherwise
-    # you won't get more than 1000 results back from a query.
-    # This implementation is kindof clunky and should probably be refactored.
-    # Also, is it my imagination, or are A/Ds the slowest directory servers ever???
-    #
-    def search args = {}
-      search_filter = (args && args[:filter]) || Filter.eq( "objectclass", "*" )
-      search_filter = Filter.construct(search_filter) if search_filter.is_a?(String)
-      search_base = (args && args[:base]) || "dc=example,dc=com"
-      search_attributes = ((args && args[:attributes]) || []).map {|attr| attr.to_s.to_ber}
-      return_referrals = args && args[:return_referrals] == true
-
-      attributes_only = (args and args[:attributes_only] == true)
-      scope = args[:scope] || Net::LDAP::SearchScope_WholeSubtree
-      raise LdapError.new( "invalid search scope" ) unless SearchScopes.include?(scope)
-
-      # An interesting value for the size limit would be close to A/D's built-in
-      # page limit of 1000 records, but openLDAP newer than version 2.2.0 chokes
-      # on anything bigger than 126. You get a silent error that is easily visible
-      # by running slapd in debug mode. Go figure.
-      rfc2696_cookie = [126, ""]
-      result_code = 0
-
-      loop {
-        # should collect this into a private helper to clarify the structure
-
-        request = [
-          search_base.to_ber,
-          scope.to_ber_enumerated,
-          0.to_ber_enumerated,
-          0.to_ber,
-          0.to_ber,
-          attributes_only.to_ber,
-          search_filter.to_ber,
-          search_attributes.to_ber_sequence
-        ].to_ber_appsequence(3)
-  
-        controls = [
-          [
-          LdapControls::PagedResults.to_ber,
-          false.to_ber, # criticality MUST be false to interoperate with normal LDAPs.
-          rfc2696_cookie.map{|v| v.to_ber}.to_ber_sequence.to_s.to_ber
-          ].to_ber_sequence
-        ].to_ber_contextspecific(0)
-
-        pkt = [next_msgid.to_ber, request, controls].to_ber_sequence
-        @conn.write pkt
-
-        result_code = 0
-        controls = []
-
-        while (be = @conn.read_ber(AsnSyntax)) && (pdu = LdapPdu.new( be ))
-          case pdu.app_tag
-          when 4 # search-data
-            yield( pdu.search_entry ) if block_given?
-          when 19 # search-referral
-            if return_referrals
-              if block_given?
-                se = Net::LDAP::Entry.new
-                se[:search_referrals] = (pdu.search_referrals || [])
-                yield se
-              end
-            end
-            #p pdu.referrals
-          when 5 # search-result
-            result_code = pdu.result_code
-            controls = pdu.result_controls
-            break
-          else
-            raise LdapError.new( "invalid response-type in search: #{pdu.app_tag}" )
-          end
-        end
-
-        # When we get here, we have seen a type-5 response.
-        # If there is no error AND there is an RFC-2696 cookie,
-        # then query again for the next page of results.
-        # If not, we're done.
-        # Don't screw this up or we'll break every search we do.
-        more_pages = false
-        if result_code == 0 and controls
-          controls.each do |c|
-            if c.oid == LdapControls::PagedResults
-              more_pages = false # just in case some bogus server sends us >1 of these.
-              if c.value and c.value.length > 0
-                cookie = c.value.read_ber[1]
-                if cookie and cookie.length > 0
-                  rfc2696_cookie[1] = cookie
-                  more_pages = true
-                end
-              end
-            end
-          end
-        end
-
-        break unless more_pages
-      } # loop
-
-      result_code
-    end
-
-
-
-
-    #--
-    # modify
-    # TODO, need to support a time limit, in case the server fails to respond.
-    # TODO!!! We're throwing an exception here on empty DN.
-    # Should return a proper error instead, probaby from farther up the chain.
-    # TODO!!! If the user specifies a bogus opcode, we'll throw a
-    # confusing error here ("to_ber_enumerated is not defined on nil").
-    #
-    def modify args
-      modify_dn = args[:dn] or raise "Unable to modify empty DN"
-      modify_ops = []
-      a = args[:operations] and a.each {|op, attr, values|
-        # TODO, fix the following line, which gives a bogus error
-        # if the opcode is invalid.
-        op_1 = {:add => 0, :delete => 1, :replace => 2} [op.to_sym].to_ber_enumerated
-        modify_ops << [op_1, [attr.to_s.to_ber, values.to_a.map {|v| v.to_ber}.to_ber_set].to_ber_sequence].to_ber_sequence
-      }
-
-      request = [modify_dn.to_ber, modify_ops.to_ber_sequence].to_ber_appsequence(6)
-      pkt = [next_msgid.to_ber, request].to_ber_sequence
-      @conn.write pkt
-
-      (be = @conn.read_ber(AsnSyntax)) && (pdu = LdapPdu.new( be )) && (pdu.app_tag == 7) or raise LdapError.new( "response missing or invalid" )
-      pdu.result_code
-    end
-
-
-    #--
-    # add
-    # TODO, need to support a time limit, in case the server fails to respond.
-    #
-    def add args
-      add_dn = args[:dn] or raise LdapError.new("Unable to add empty DN")
-      add_attrs = []
-      a = args[:attributes] and a.each {|k,v|
-        add_attrs << [ k.to_s.to_ber, v.to_a.map {|m| m.to_ber}.to_ber_set ].to_ber_sequence
-      }
-
-      request = [add_dn.to_ber, add_attrs.to_ber_sequence].to_ber_appsequence(8)
-      pkt = [next_msgid.to_ber, request].to_ber_sequence
-      @conn.write pkt
-
-      (be = @conn.read_ber(AsnSyntax)) && (pdu = LdapPdu.new( be )) && (pdu.app_tag == 9) or raise LdapError.new( "response missing or invalid" )
-      pdu.result_code
-    end
-
-
-    #--
-    # rename
-    # TODO, need to support a time limit, in case the server fails to respond.
-    #
-    def rename args
-      old_dn = args[:olddn] or raise "Unable to rename empty DN"
-      new_rdn = args[:newrdn] or raise "Unable to rename to empty RDN"
-      delete_attrs = args[:delete_attributes] ? true : false
-
-      request = [old_dn.to_ber, new_rdn.to_ber, delete_attrs.to_ber].to_ber_appsequence(12)
-      pkt = [next_msgid.to_ber, request].to_ber_sequence
-      @conn.write pkt
-
-      (be = @conn.read_ber(AsnSyntax)) && (pdu = LdapPdu.new( be )) && (pdu.app_tag == 13) or raise LdapError.new( "response missing or invalid" )
-      pdu.result_code
-    end
-
-
-    #--
-    # delete
-    # TODO, need to support a time limit, in case the server fails to respond.
-    #
-    def delete args
-      dn = args[:dn] or raise "Unable to delete empty DN"
-
-      request = dn.to_s.to_ber_application_string(10)
-      pkt = [next_msgid.to_ber, request].to_ber_sequence
-      @conn.write pkt
-
-      (be = @conn.read_ber(AsnSyntax)) && (pdu = LdapPdu.new( be )) && (pdu.app_tag == 11) or raise LdapError.new( "response missing or invalid" )
-      pdu.result_code
-    end
-
-
-  end # class Connection
-  end # class LDAP
-
-
-end # module Net
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c8/c8bf21d1404b2daaac7abe315bbaa50d1e93dc11.svn-base
--- a/.svn/pristine/c8/c8bf21d1404b2daaac7abe315bbaa50d1e93dc11.svn-base
+++ /dev/null
@@ -1,16 +0,0 @@
-begin
-  require 'openid'
-rescue LoadError
-  begin
-    gem 'ruby-openid', '>=2.1.4'
-  rescue Gem::LoadError
-    # no openid support
-  end
-end
-
-if Object.const_defined?(:OpenID)
-  config.to_prepare do
-    OpenID::Util.logger = Rails.logger
-    ActionController::Base.send :include, OpenIdAuthentication
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c8/c8c8b891b8b1a98cd7dec3eea46d3351c5d63dc0.svn-base
--- /dev/null
+++ b/.svn/pristine/c8/c8c8b891b8b1a98cd7dec3eea46d3351c5d63dc0.svn-base
@@ -0,0 +1,114 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/darcs_adapter'
+
+class Repository::Darcs < Repository
+  validates_presence_of :url, :log_encoding
+
+  def self.human_attribute_name(attribute_key_name, *args)
+    attr_name = attribute_key_name.to_s
+    if attr_name == "url"
+      attr_name = "path_to_repository"
+    end
+    super(attr_name, *args)
+  end
+
+  def self.scm_adapter_class
+    Redmine::Scm::Adapters::DarcsAdapter
+  end
+
+  def self.scm_name
+    'Darcs'
+  end
+
+  def supports_directory_revisions?
+    true
+  end
+
+  def entry(path=nil, identifier=nil)
+    patch = identifier.nil? ? nil : changesets.find_by_revision(identifier)
+    scm.entry(path, patch.nil? ? nil : patch.scmid)
+  end
+
+  def entries(path=nil, identifier=nil)
+    patch = nil
+    if ! identifier.nil?
+      patch = changesets.find_by_revision(identifier)
+      return nil if patch.nil?
+    end
+    entries = scm.entries(path, patch.nil? ? nil : patch.scmid)
+    if entries
+      entries.each do |entry|
+        # Search the DB for the entry's last change
+        if entry.lastrev && !entry.lastrev.scmid.blank?
+          changeset = changesets.find_by_scmid(entry.lastrev.scmid)
+        end
+        if changeset
+          entry.lastrev.identifier = changeset.revision
+          entry.lastrev.name       = changeset.revision
+          entry.lastrev.time       = changeset.committed_on
+          entry.lastrev.author     = changeset.committer
+        end
+      end
+    end
+    load_entries_changesets(entries)
+    entries
+  end
+
+  def cat(path, identifier=nil)
+    patch = identifier.nil? ? nil : changesets.find_by_revision(identifier.to_s)
+    scm.cat(path, patch.nil? ? nil : patch.scmid)
+  end
+
+  def diff(path, rev, rev_to)
+    patch_from = changesets.find_by_revision(rev)
+    return nil if patch_from.nil?
+    patch_to = changesets.find_by_revision(rev_to) if rev_to
+    if path.blank?
+      path = patch_from.filechanges.collect{|change| change.path}.join(' ')
+    end
+    patch_from ? scm.diff(path, patch_from.scmid, patch_to ? patch_to.scmid : nil) : nil
+  end
+
+  def fetch_changesets
+    scm_info = scm.info
+    if scm_info
+      db_last_id = latest_changeset ? latest_changeset.scmid : nil
+      next_rev   = latest_changeset ? latest_changeset.revision.to_i + 1 : 1
+      # latest revision in the repository
+      scm_revision = scm_info.lastrev.scmid
+      unless changesets.find_by_scmid(scm_revision)
+        revisions = scm.revisions('', db_last_id, nil, :with_path => true)
+        transaction do
+          revisions.reverse_each do |revision|
+            changeset = Changeset.create(:repository   => self,
+                                         :revision     => next_rev,
+                                         :scmid        => revision.scmid,
+                                         :committer    => revision.author,
+                                         :committed_on => revision.time,
+                                         :comments     => revision.message)
+            revision.paths.each do |change|
+              changeset.create_change(change)
+            end
+            next_rev += 1
+          end if revisions
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c9/c915cdc5a63346a4f09f2d9cd1c727112cb89f1c.svn-base
--- /dev/null
+++ b/.svn/pristine/c9/c915cdc5a63346a4f09f2d9cd1c727112cb89f1c.svn-base
@@ -0,0 +1,371 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
+  fixtures :users, :members, :member_roles, :roles, :projects
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "GET /users" do
+    should_allow_api_authentication(:get, "/users.xml")
+    should_allow_api_authentication(:get, "/users.json")
+  end
+
+  context "GET /users/2" do
+    context ".xml" do
+      should "return requested user" do
+        get '/users/2.xml'
+
+        assert_response :success
+        assert_tag :tag => 'user',
+          :child => {:tag => 'id', :content => '2'}
+      end
+
+      context "with include=memberships" do
+        should "include memberships" do
+          get '/users/2.xml?include=memberships'
+  
+          assert_response :success
+          assert_tag :tag => 'memberships',
+            :parent => {:tag => 'user'},
+            :children => {:count => 1}
+        end
+      end
+    end
+
+    context ".json" do
+      should "return requested user" do
+        get '/users/2.json'
+
+        assert_response :success
+        json = ActiveSupport::JSON.decode(response.body)
+        assert_kind_of Hash, json
+        assert_kind_of Hash, json['user']
+        assert_equal 2, json['user']['id']
+      end
+
+      context "with include=memberships" do
+        should "include memberships" do
+          get '/users/2.json?include=memberships'
+  
+          assert_response :success
+          json = ActiveSupport::JSON.decode(response.body)
+          assert_kind_of Array, json['user']['memberships']
+          assert_equal [{
+            "id"=>1,
+            "project"=>{"name"=>"eCookbook", "id"=>1},
+            "roles"=>[{"name"=>"Manager", "id"=>1}]
+          }], json['user']['memberships']
+        end
+      end
+    end
+  end
+
+  context "GET /users/current" do
+    context ".xml" do
+      should "require authentication" do
+        get '/users/current.xml'
+
+        assert_response 401
+      end
+
+      should "return current user" do
+        get '/users/current.xml', {}, credentials('jsmith')
+
+        assert_tag :tag => 'user',
+          :child => {:tag => 'id', :content => '2'}
+      end
+    end
+  end
+
+  test "GET /users/:id should not return login for other user" do
+    get '/users/3.xml', {}, credentials('jsmith')
+    assert_response :success
+    assert_no_tag 'user', :child => {:tag => 'login'}
+  end
+
+  test "GET /users/:id should return login for current user" do
+    get '/users/2.xml', {}, credentials('jsmith')
+    assert_response :success
+    assert_tag 'user', :child => {:tag => 'login', :content => 'jsmith'}
+  end
+
+  test "GET /users/:id should not return api_key for other user" do
+    get '/users/3.xml', {}, credentials('jsmith')
+    assert_response :success
+    assert_no_tag 'user', :child => {:tag => 'api_key'}
+  end
+
+  test "GET /users/:id should return api_key for current user" do
+    get '/users/2.xml', {}, credentials('jsmith')
+    assert_response :success
+    assert_tag 'user', :child => {:tag => 'api_key', :content => User.find(2).api_key}
+  end
+
+  context "POST /users" do
+    context "with valid parameters" do
+      setup do
+        @parameters = {
+          :user => {
+             :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
+             :mail => 'foo@example.net', :password => 'secret123',
+             :mail_notification => 'only_assigned'
+          }
+        }
+      end
+
+      context ".xml" do
+        should_allow_api_authentication(:post,
+          '/users.xml',
+           {:user => {
+              :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
+              :mail => 'foo@example.net', :password => 'secret123'
+            }},
+          {:success_code => :created})
+
+        should "create a user with the attributes" do
+          assert_difference('User.count') do
+            post '/users.xml', @parameters, credentials('admin')
+          end
+
+          user = User.first(:order => 'id DESC')
+          assert_equal 'foo', user.login
+          assert_equal 'Firstname', user.firstname
+          assert_equal 'Lastname', user.lastname
+          assert_equal 'foo@example.net', user.mail
+          assert_equal 'only_assigned', user.mail_notification
+          assert !user.admin?
+          assert user.check_password?('secret123')
+
+          assert_response :created
+          assert_equal 'application/xml', @response.content_type
+          assert_tag 'user', :child => {:tag => 'id', :content => user.id.to_s}
+        end
+      end
+
+      context ".json" do
+        should_allow_api_authentication(:post,
+          '/users.json',
+          {:user => {
+             :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
+             :mail => 'foo@example.net'
+          }},
+          {:success_code => :created})
+
+        should "create a user with the attributes" do
+          assert_difference('User.count') do
+            post '/users.json', @parameters, credentials('admin')
+          end
+
+          user = User.first(:order => 'id DESC')
+          assert_equal 'foo', user.login
+          assert_equal 'Firstname', user.firstname
+          assert_equal 'Lastname', user.lastname
+          assert_equal 'foo@example.net', user.mail
+          assert !user.admin?
+
+          assert_response :created
+          assert_equal 'application/json', @response.content_type
+          json = ActiveSupport::JSON.decode(response.body)
+          assert_kind_of Hash, json
+          assert_kind_of Hash, json['user']
+          assert_equal user.id, json['user']['id']
+        end
+      end
+    end
+
+    context "with invalid parameters" do
+      setup do
+        @parameters = {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}
+      end
+
+      context ".xml" do
+        should "return errors" do
+          assert_no_difference('User.count') do
+            post '/users.xml', @parameters, credentials('admin')
+          end
+
+          assert_response :unprocessable_entity
+          assert_equal 'application/xml', @response.content_type
+          assert_tag 'errors', :child => {
+                                 :tag => 'error',
+                                 :content => "First name can't be blank"
+                               }
+        end
+      end
+
+      context ".json" do
+        should "return errors" do
+          assert_no_difference('User.count') do
+            post '/users.json', @parameters, credentials('admin')
+          end
+
+          assert_response :unprocessable_entity
+          assert_equal 'application/json', @response.content_type
+          json = ActiveSupport::JSON.decode(response.body)
+          assert_kind_of Hash, json
+          assert json.has_key?('errors')
+          assert_kind_of Array, json['errors']
+        end
+      end
+    end
+  end
+
+  context "PUT /users/2" do
+    context "with valid parameters" do
+      setup do
+        @parameters = {
+          :user => {
+            :login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
+            :mail => 'jsmith@somenet.foo'
+          }
+        }
+      end
+
+      context ".xml" do
+        should_allow_api_authentication(:put,
+          '/users/2.xml',
+          {:user => {
+              :login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
+              :mail => 'jsmith@somenet.foo'
+          }},
+          {:success_code => :ok})
+
+        should "update user with the attributes" do
+          assert_no_difference('User.count') do
+            put '/users/2.xml', @parameters, credentials('admin')
+          end
+
+          user = User.find(2)
+          assert_equal 'jsmith', user.login
+          assert_equal 'John', user.firstname
+          assert_equal 'Renamed', user.lastname
+          assert_equal 'jsmith@somenet.foo', user.mail
+          assert !user.admin?
+
+          assert_response :ok
+          assert_equal '', @response.body
+        end
+      end
+
+      context ".json" do
+        should_allow_api_authentication(:put,
+          '/users/2.json',
+          {:user => {
+              :login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
+              :mail => 'jsmith@somenet.foo'
+          }},
+          {:success_code => :ok})
+
+        should "update user with the attributes" do
+          assert_no_difference('User.count') do
+            put '/users/2.json', @parameters, credentials('admin')
+          end
+
+          user = User.find(2)
+          assert_equal 'jsmith', user.login
+          assert_equal 'John', user.firstname
+          assert_equal 'Renamed', user.lastname
+          assert_equal 'jsmith@somenet.foo', user.mail
+          assert !user.admin?
+
+          assert_response :ok
+          assert_equal '', @response.body
+        end
+      end
+    end
+
+    context "with invalid parameters" do
+      setup do
+        @parameters = {
+          :user => {
+            :login => 'jsmith', :firstname => '', :lastname => 'Lastname',
+            :mail => 'foo'
+          }
+        }
+      end
+
+      context ".xml" do
+        should "return errors" do
+          assert_no_difference('User.count') do
+            put '/users/2.xml', @parameters, credentials('admin')
+          end
+
+          assert_response :unprocessable_entity
+          assert_equal 'application/xml', @response.content_type
+          assert_tag 'errors', :child => {
+                                 :tag => 'error',
+                                 :content => "First name can't be blank"
+                                }
+        end
+      end
+
+      context ".json" do
+        should "return errors" do
+          assert_no_difference('User.count') do
+            put '/users/2.json', @parameters, credentials('admin')
+          end
+
+          assert_response :unprocessable_entity
+          assert_equal 'application/json', @response.content_type
+          json = ActiveSupport::JSON.decode(response.body)
+          assert_kind_of Hash, json
+          assert json.has_key?('errors')
+          assert_kind_of Array, json['errors']
+        end
+      end
+    end
+  end
+
+  context "DELETE /users/2" do
+    context ".xml" do
+      should_allow_api_authentication(:delete,
+        '/users/2.xml',
+        {},
+        {:success_code => :ok})
+
+      should "delete user" do
+        assert_difference('User.count', -1) do
+          delete '/users/2.xml', {}, credentials('admin')
+        end
+
+        assert_response :ok
+        assert_equal '', @response.body
+      end
+    end
+
+    context ".json" do
+      should_allow_api_authentication(:delete,
+        '/users/2.xml',
+        {},
+        {:success_code => :ok})
+
+      should "delete user" do
+        assert_difference('User.count', -1) do
+          delete '/users/2.json', {}, credentials('admin')
+        end
+
+        assert_response :ok
+        assert_equal '', @response.body
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c9/c98b53052b91d2ade4ab264e541402cfff642b4a.svn-base
--- a/.svn/pristine/c9/c98b53052b91d2ade4ab264e541402cfff642b4a.svn-base
+++ /dev/null
@@ -1,92 +0,0 @@
-<% form_tag({:action => 'edit', :tab => 'repositories'}) do %>
-
-<fieldset class="box settings enabled_scm">
-<%= hidden_field_tag 'settings[enabled_scm][]', '' %>
-<legend><%= l(:setting_enabled_scm) %></legend>
-<table>
-  <tr>
-    <th></th>
-    <th><%= l(:text_scm_command)         %></th>
-    <th><%= l(:text_scm_command_version) %></th>
-  </tr>
-  <% Redmine::Scm::Base.all.collect do |choice| %>
-    <% scm_class = "Repository::#{choice}".constantize %>
-    <% text, value = (choice.is_a?(Array) ? choice : [choice, choice]) %>
-    <% setting = :enabled_scm %>
-    <tr>
-      <td class="scm_name">
-        <%=
-          check_box_tag(
-              "settings[#{setting}][]",
-               value,
-               Setting.send(setting).include?(value))
-         %>
-        <%= text.to_s %>
-      </td>
-      <td>
-         <%=
-           image_tag(
-              (scm_class.scm_available ? 'true.png' : 'exclamation.png'),
-              :style => "vertical-align:bottom;"
-           )
-           %>
-          <%= scm_class.scm_command %>
-       </td>
-       <td>
-          <%= scm_class.scm_version_string %>
-       </td>
-     </tr>
-  <% end %>
-</table>
-<p><em><%= l(:text_scm_config) %></em></p>
-</fieldset>
-
-<div class="box tabular settings">
-<p><%= setting_check_box :autofetch_changesets %></p>
-
-<p><%= setting_check_box :sys_api_enabled,
-                         :onclick =>
-                             "if (this.checked) { Form.Element.enable('settings_sys_api_key'); } else { Form.Element.disable('settings_sys_api_key'); }" %></p>
-
-<p><%= setting_text_field :sys_api_key,
-                          :size     => 30,
-                          :id       => 'settings_sys_api_key',
-                          :disabled => !Setting.sys_api_enabled?,
-                          :label    => :setting_mail_handler_api_key %>
-  <%= link_to_function l(:label_generate_key),
-                       "if ($('settings_sys_api_key').disabled == false) { $('settings_sys_api_key').value = randomKey(20) }" %>
-</p>
-
-<p><%= setting_text_field :repository_log_display_limit, :size => 6 %></p>
-</div>
-
-<fieldset class="box tabular settings">
-<legend><%= l(:text_issues_ref_in_commit_messages) %></legend>
-<p><%= setting_text_field :commit_ref_keywords, :size => 30 %><br />
-<em><%= l(:text_comma_separated) %></em></p>
-
-<p><%= setting_text_field :commit_fix_keywords, :size => 30 %>
-&nbsp;<%= l(:label_applied_status) %>: <%= setting_select :commit_fix_status_id,
-                                                          [["", 0]] +
-                                                              IssueStatus.find(:all).collect{
-                                                                 |status| [status.name, status.id.to_s]
-                                                              },
-                                                          :label => false %>
-&nbsp;<%= l(:field_done_ratio) %>: <%= setting_select :commit_fix_done_ratio,
-                                                       (0..10).to_a.collect {|r| ["#{r*10} %", "#{r*10}"] },
-                                                       :blank => :label_no_change_option,
-                                                       :label => false %>
-<br /><em><%= l(:text_comma_separated) %></em></p>
-
-<p><%= setting_check_box :commit_logtime_enabled,
-                         :onclick =>
-                            "if (this.checked) { Form.Element.enable('settings_commit_logtime_activity_id'); } else { Form.Element.disable('settings_commit_logtime_activity_id'); }"%></p>
-
-<p><%= setting_select :commit_logtime_activity_id,
-                      [[l(:label_default), 0]] +
-                          TimeEntryActivity.shared.active.collect{|activity| [activity.name, activity.id.to_s]},
-                      :disabled => !Setting.commit_logtime_enabled?%></p>
-</fieldset>
-
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/c9/c9ed1c5ecdb956b01f130ded5e7336f5878cd4a2.svn-base
--- a/.svn/pristine/c9/c9ed1c5ecdb956b01f130ded5e7336f5878cd4a2.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-module CodeRay
-
-  # This module holds the Style class and its subclasses.
-  # 
-  # See Plugin.
-  module Styles
-    extend PluginHost
-    plugin_path File.dirname(__FILE__), 'styles'
-    
-    # Base class for styles.
-    # 
-    # Styles are used by Encoders::HTML to colorize tokens.
-    class Style
-      extend Plugin
-      plugin_host Styles
-      
-      DEFAULT_OPTIONS = { }  # :nodoc:
-      
-    end
-    
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ca/ca0155b87af1f6afa9052425d12b486a3be81421.svn-base
--- a/.svn/pristine/ca/ca0155b87af1f6afa9052425d12b486a3be81421.svn-base
+++ /dev/null
@@ -1,462 +0,0 @@
-# redMine - project management software
-# Copyright (C) 2006-2007  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/abstract_adapter'
-
-module Redmine
-  module Scm
-    module Adapters
-      class CvsAdapter < AbstractAdapter
-
-        # CVS executable name
-        CVS_BIN = Redmine::Configuration['scm_cvs_command'] || "cvs"
-
-        class << self
-          def client_command
-            @@bin    ||= CVS_BIN
-          end
-
-          def sq_bin
-            @@sq_bin ||= shell_quote_command
-          end
-
-          def client_version
-            @@client_version ||= (scm_command_version || [])
-          end
-
-          def client_available
-            client_version_above?([1, 12])
-          end
-
-          def scm_command_version
-            scm_version = scm_version_from_command_line.dup
-            if scm_version.respond_to?(:force_encoding)
-              scm_version.force_encoding('ASCII-8BIT')
-            end
-            if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)}m)
-              m[2].scan(%r{\d+}).collect(&:to_i)
-            end
-          end
-
-          def scm_version_from_command_line
-            shellout("#{sq_bin} --version") { |io| io.read }.to_s
-          end
-        end
-
-        # Guidelines for the input:
-        #  url      -> the project-path, relative to the cvsroot (eg. module name)
-        #  root_url -> the good old, sometimes damned, CVSROOT
-        #  login    -> unnecessary
-        #  password -> unnecessary too
-        def initialize(url, root_url=nil, login=nil, password=nil,
-                       path_encoding=nil)
-          @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
-          @url      = url
-          # TODO: better Exception here (IllegalArgumentException)
-          raise CommandFailed if root_url.blank?
-          @root_url  = root_url
-
-          # These are unused.
-          @login    = login if login && !login.empty?
-          @password = (password || "") if @login
-        end
-
-        def path_encoding
-          @path_encoding
-        end
-
-        def info
-          logger.debug "<cvs> info"
-          Info.new({:root_url => @root_url, :lastrev => nil})
-        end
-
-        def get_previous_revision(revision)
-          CvsRevisionHelper.new(revision).prevRev
-        end
-
-        # Returns an Entries collection
-        # or nil if the given path doesn't exist in the repository
-        # this method is used by the repository-browser (aka LIST)
-        def entries(path=nil, identifier=nil, options={})
-          logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'"
-          path_locale = scm_iconv(@path_encoding, 'UTF-8', path)
-          path_locale.force_encoding("ASCII-8BIT") if path_locale.respond_to?(:force_encoding)
-          entries = Entries.new
-          cmd_args = %w|-q rls -e|
-          cmd_args << "-D" << time_to_cvstime_rlog(identifier) if identifier
-          cmd_args << path_with_proj(path)
-          scm_cmd(*cmd_args) do |io|
-            io.each_line() do |line|
-              fields = line.chop.split('/',-1)
-              logger.debug(">>InspectLine #{fields.inspect}")
-              if fields[0]!="D"
-                time = nil
-                # Thu Dec 13 16:27:22 2007
-                time_l = fields[-3].split(' ')
-                if time_l.size == 5 && time_l[4].length == 4
-                  begin
-                    time = Time.parse(
-                             "#{time_l[1]} #{time_l[2]} #{time_l[3]} GMT #{time_l[4]}")
-                  rescue
-                  end
-                end
-                entries << Entry.new(
-                 {
-                  :name => scm_iconv('UTF-8', @path_encoding, fields[-5]),
-                  #:path => fields[-4].include?(path)?fields[-4]:(path + "/"+ fields[-4]),
-                  :path => scm_iconv('UTF-8', @path_encoding, "#{path_locale}/#{fields[-5]}"),
-                  :kind => 'file',
-                  :size => nil,
-                  :lastrev => Revision.new(
-                      {
-                        :revision => fields[-4],
-                        :name     => scm_iconv('UTF-8', @path_encoding, fields[-4]),
-                        :time     => time,
-                        :author   => ''
-                      })
-                  })
-              else
-                entries << Entry.new(
-                 {
-                  :name    => scm_iconv('UTF-8', @path_encoding, fields[1]),
-                  :path    => scm_iconv('UTF-8', @path_encoding, "#{path_locale}/#{fields[1]}"),
-                  :kind    => 'dir',
-                  :size    => nil,
-                  :lastrev => nil
-                 })
-              end
-            end
-          end
-          entries.sort_by_name
-        rescue ScmCommandAborted
-          nil
-        end
-
-        STARTLOG="----------------------------"
-        ENDLOG  ="============================================================================="
-
-        # Returns all revisions found between identifier_from and identifier_to
-        # in the repository. both identifier have to be dates or nil.
-        # these method returns nothing but yield every result in block
-        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}, &block)
-          path_with_project_utf8   = path_with_proj(path)
-          path_with_project_locale = scm_iconv(@path_encoding, 'UTF-8', path_with_project_utf8)
-          logger.debug "<cvs> revisions path:" +
-              "'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
-          cmd_args = %w|-q rlog|
-          cmd_args << "-d" << ">#{time_to_cvstime_rlog(identifier_from)}" if identifier_from
-          cmd_args << path_with_project_utf8
-          scm_cmd(*cmd_args) do |io|
-            state      = "entry_start"
-            commit_log = String.new
-            revision   = nil
-            date       = nil
-            author     = nil
-            entry_path = nil
-            entry_name = nil
-            file_state = nil
-            branch_map = nil
-            io.each_line() do |line|
-              if state != "revision" && /^#{ENDLOG}/ =~ line
-                commit_log = String.new
-                revision   = nil
-                state      = "entry_start"
-              end
-              if state == "entry_start"
-                branch_map = Hash.new
-                if /^RCS file: #{Regexp.escape(root_url_path)}\/#{Regexp.escape(path_with_project_locale)}(.+),v$/ =~ line
-                  entry_path = normalize_cvs_path($1)
-                  entry_name = normalize_path(File.basename($1))
-                  logger.debug("Path #{entry_path} <=> Name #{entry_name}")
-                elsif /^head: (.+)$/ =~ line
-                  entry_headRev = $1 #unless entry.nil?
-                elsif /^symbolic names:/ =~ line
-                  state = "symbolic" #unless entry.nil?
-                elsif /^#{STARTLOG}/ =~ line
-                  commit_log = String.new
-                  state      = "revision"
-                end
-                next
-              elsif state == "symbolic"
-                if /^(.*):\s(.*)/ =~ (line.strip)
-                  branch_map[$1] = $2
-                else
-                  state = "tags"
-                  next
-                end
-              elsif state == "tags"
-                if /^#{STARTLOG}/ =~ line
-                  commit_log = ""
-                  state = "revision"
-                elsif /^#{ENDLOG}/ =~ line
-                  state = "head"
-                end
-                next
-              elsif state == "revision"
-                if /^#{ENDLOG}/ =~ line || /^#{STARTLOG}/ =~ line
-                  if revision
-                    revHelper = CvsRevisionHelper.new(revision)
-                    revBranch = "HEAD"
-                    branch_map.each() do |branch_name, branch_point|
-                      if revHelper.is_in_branch_with_symbol(branch_point)
-                        revBranch = branch_name
-                      end
-                    end
-                    logger.debug("********** YIELD Revision #{revision}::#{revBranch}")
-                    yield Revision.new({
-                      :time    => date,
-                      :author  => author,
-                      :message => commit_log.chomp,
-                      :paths => [{
-                        :revision => revision,
-                        :branch   => revBranch,
-                        :path     => scm_iconv('UTF-8', @path_encoding, entry_path),
-                        :name     => scm_iconv('UTF-8', @path_encoding, entry_name),
-                        :kind     => 'file',
-                        :action   => file_state
-                           }]
-                         })
-                  end
-                  commit_log = String.new
-                  revision   = nil
-                  if /^#{ENDLOG}/ =~ line
-                    state = "entry_start"
-                  end
-                  next
-                end
-
-                if /^branches: (.+)$/ =~ line
-                  # TODO: version.branch = $1
-                elsif /^revision (\d+(?:\.\d+)+).*$/ =~ line
-                  revision = $1
-                elsif /^date:\s+(\d+.\d+.\d+\s+\d+:\d+:\d+)/ =~ line
-                  date       = Time.parse($1)
-                  line_utf8    = scm_iconv('UTF-8', options[:log_encoding], line)
-                  author_utf8  = /author: ([^;]+)/.match(line_utf8)[1]
-                  author       = scm_iconv(options[:log_encoding], 'UTF-8', author_utf8)
-                  file_state   = /state: ([^;]+)/.match(line)[1]
-                  # TODO:
-                  #    linechanges only available in CVS....
-                  #    maybe a feature our SVN implementation.
-                  #    I'm sure, they are useful for stats or something else
-                  #                linechanges =/lines: \+(\d+) -(\d+)/.match(line)
-                  #                unless linechanges.nil?
-                  #                  version.line_plus  = linechanges[1]
-                  #                  version.line_minus = linechanges[2]
-                  #                else
-                  #                  version.line_plus  = 0
-                  #                  version.line_minus = 0
-                  #                end
-                else
-                  commit_log << line unless line =~ /^\*\*\* empty log message \*\*\*/
-                end
-              end
-            end
-          end
-        rescue ScmCommandAborted
-          Revisions.new
-        end
-
-        def diff(path, identifier_from, identifier_to=nil)
-          logger.debug "<cvs> diff path:'#{path}'" +
-              ",identifier_from #{identifier_from}, identifier_to #{identifier_to}"
-          cmd_args = %w|rdiff -u|
-          cmd_args << "-r#{identifier_to}"
-          cmd_args << "-r#{identifier_from}"
-          cmd_args << path_with_proj(path)
-          diff = []
-          scm_cmd(*cmd_args) do |io|
-            io.each_line do |line|
-              diff << line
-            end
-          end
-          diff
-        rescue ScmCommandAborted
-          nil
-        end
-
-        def cat(path, identifier=nil)
-          identifier = (identifier) ? identifier : "HEAD"
-          logger.debug "<cvs> cat path:'#{path}',identifier #{identifier}"
-          cmd_args = %w|-q co|
-          cmd_args << "-D" << time_to_cvstime(identifier) if identifier
-          cmd_args << "-p" << path_with_proj(path)
-          cat = nil
-          scm_cmd(*cmd_args) do |io|
-            io.binmode
-            cat = io.read
-          end
-          cat
-        rescue ScmCommandAborted
-          nil
-        end
-
-        def annotate(path, identifier=nil)
-          identifier = (identifier) ? identifier : "HEAD"
-          logger.debug "<cvs> annotate path:'#{path}',identifier #{identifier}"
-          cmd_args = %w|rannotate|
-          cmd_args << "-D" << time_to_cvstime(identifier) if identifier
-          cmd_args << path_with_proj(path)
-          blame = Annotate.new
-          scm_cmd(*cmd_args) do |io|
-            io.each_line do |line|
-              next unless line =~ %r{^([\d\.]+)\s+\(([^\)]+)\s+[^\)]+\):\s(.*)$}
-              blame.add_line(
-                  $3.rstrip,
-                  Revision.new(
-                    :revision   => $1,
-                    :identifier => nil,
-                    :author     => $2.strip
-                    ))
-            end
-          end
-          blame
-        rescue ScmCommandAborted
-          Annotate.new
-        end
-
-        private
-
-        # Returns the root url without the connexion string
-        # :pserver:anonymous@foo.bar:/path => /path
-        # :ext:cvsservername:/path => /path
-        def root_url_path
-          root_url.to_s.gsub(/^:.+:\d*/, '')
-        end
-
-        # convert a date/time into the CVS-format
-        def time_to_cvstime(time)
-          return nil if time.nil?
-          time = Time.now if time == 'HEAD'
-
-          unless time.kind_of? Time
-            time = Time.parse(time)
-          end
-          return time_to_cvstime_rlog(time)
-        end
-
-        def time_to_cvstime_rlog(time)
-          return nil if time.nil?
-          t1 = time.clone.localtime
-          return t1.strftime("%Y-%m-%d %H:%M:%S")
-        end
-
-        def normalize_cvs_path(path)
-          normalize_path(path.gsub(/Attic\//,''))
-        end
-
-        def normalize_path(path)
-          path.sub(/^(\/)*(.*)/,'\2').sub(/(.*)(,v)+/,'\1')
-        end
-
-        def path_with_proj(path)
-          "#{url}#{with_leading_slash(path)}"
-        end
-        private :path_with_proj
-
-        class Revision < Redmine::Scm::Adapters::Revision
-          # Returns the readable identifier
-          def format_identifier
-            revision.to_s
-          end
-        end
-
-        def scm_cmd(*args, &block)
-          full_args = ['-d', root_url]
-          full_args += args
-          full_args_locale = []
-          full_args.map do |e|
-            full_args_locale << scm_iconv(@path_encoding, 'UTF-8', e)
-          end
-          ret = shellout(
-                   self.class.sq_bin + ' ' + full_args_locale.map { |e| shell_quote e.to_s }.join(' '),
-                   &block
-                   )
-          if $? && $?.exitstatus != 0
-            raise ScmCommandAborted, "cvs exited with non-zero status: #{$?.exitstatus}"
-          end
-          ret
-        end
-        private :scm_cmd
-      end
-
-      class CvsRevisionHelper
-        attr_accessor :complete_rev, :revision, :base, :branchid
-
-        def initialize(complete_rev)
-          @complete_rev = complete_rev
-          parseRevision()
-        end
-
-        def branchPoint
-          return @base
-        end
-
-        def branchVersion
-          if isBranchRevision
-            return @base+"."+@branchid
-          end
-          return @base
-        end
-
-        def isBranchRevision
-          !@branchid.nil?
-        end
-
-        def prevRev
-          unless @revision == 0
-            return buildRevision( @revision - 1 )
-          end
-          return buildRevision( @revision )
-        end
-
-        def is_in_branch_with_symbol(branch_symbol)
-          bpieces = branch_symbol.split(".")
-          branch_start = "#{bpieces[0..-3].join(".")}.#{bpieces[-1]}"
-          return ( branchVersion == branch_start )
-        end
-
-        private
-        def buildRevision(rev)
-          if rev == 0
-            if @branchid.nil?
-              @base + ".0"
-            else
-              @base
-            end
-          elsif @branchid.nil?
-            @base + "." + rev.to_s
-          else
-            @base + "." + @branchid + "." + rev.to_s
-          end
-        end
-
-        # Interpretiert die cvs revisionsnummern wie z.b. 1.14 oder 1.3.0.15
-        def parseRevision()
-          pieces = @complete_rev.split(".")
-          @revision = pieces.last.to_i
-          baseSize = 1
-          baseSize += (pieces.size / 2)
-          @base = pieces[0..-baseSize].join(".")
-          if baseSize > 2
-            @branchid = pieces[-2]
-          end
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ca/ca0795b70306f0c036dcfe85786cda89b037c6f0.svn-base
--- a/.svn/pristine/ca/ca0795b70306f0c036dcfe85786cda89b037c6f0.svn-base
+++ /dev/null
@@ -1,97 +0,0 @@
-# An instance of Plugin is created for each plugin loaded by Rails, and
-# stored in the <tt>Engines.plugins</tt> PluginList 
-# (see Engines::RailsExtensions::RailsInitializer for more details).
-#
-#   Engines.plugins[:plugin_name]
-#
-# Other properties of the Plugin instance can also be set.
-module Engines
-  class Plugin < Rails::Plugin    
-    # Plugins can add paths to this attribute in init.rb if they need
-    # controllers loaded from additional locations. 
-    attr_accessor :controller_paths
-  
-    # The directory in this plugin to mirror into the shared directory
-    # under +public+.
-    #
-    # Defaults to "assets" (see default_public_directory).
-    attr_accessor :public_directory   
-    
-    protected
-      # The default set of code paths which will be added to the routing system
-      def default_controller_paths
-        %w(app/controllers components)
-      end
-
-      # Attempts to detect the directory to use for public files.
-      # If +assets+ exists in the plugin, this will be used. If +assets+ is missing
-      # but +public+ is found, +public+ will be used.
-      def default_public_directory
-        Engines.select_existing_paths(%w(assets public).map { |p| File.join(directory, p) }).first
-      end
-    
-    public
-  
-    def initialize(directory)
-      super directory
-      @controller_paths = default_controller_paths
-      @public_directory = default_public_directory
-    end
-  
-    # Extends the superclass' load method to additionally mirror public assets
-    def load(initializer)
-      return if loaded?
-      super initializer
-      add_plugin_locale_paths
-      Assets.mirror_files_for(self)
-    end    
-  
-    # select those paths that actually exist in the plugin's directory
-    def select_existing_paths(name)
-      Engines.select_existing_paths(self.send(name).map { |p| File.join(directory, p) })
-    end    
-
-    def add_plugin_locale_paths
-      locale_path = File.join(directory, 'locales')
-      return unless File.exists?(locale_path)
-
-      locale_files = Dir[File.join(locale_path, '*.{rb,yml}')]
-      return if locale_files.blank?
-
-      first_app_element = 
-        I18n.load_path.select{ |e| e =~ /^#{ RAILS_ROOT }/ }.reject{ |e| e =~ /^#{ RAILS_ROOT }\/vendor\/plugins/ }.first
-      app_index = I18n.load_path.index(first_app_element) || - 1
-
-      I18n.load_path.insert(app_index, *locale_files)
-    end
-
-    # The path to this plugin's public files
-    def public_asset_directory
-      "#{File.basename(Engines.public_directory)}/#{name}"
-    end
-    
-    # The directory containing this plugin's migrations (<tt>plugin/db/migrate</tt>)
-    def migration_directory
-      File.join(self.directory, 'db', 'migrate')
-    end
-  
-    # Returns the version number of the latest migration for this plugin. Returns
-    # nil if this plugin has no migrations.
-    def latest_migration
-      migrations.last
-    end
-    
-    # Returns the version numbers of all migrations for this plugin.
-    def migrations
-      migrations = Dir[migration_directory+"/*.rb"]
-      migrations.map { |p| File.basename(p).match(/0*(\d+)\_/)[1].to_i }.sort
-    end
-    
-    # Migrate this plugin to the given version. See Engines::Plugin::Migrator for more
-    # information.   
-    def migrate(version = nil)
-      Engines::Plugin::Migrator.migrate_plugin(self, version)
-    end
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ca/ca2690f201462335a7ca37a385b267b1298dce63.svn-base
--- /dev/null
+++ b/.svn/pristine/ca/ca2690f201462335a7ca37a385b267b1298dce63.svn-base
@@ -0,0 +1,142 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Enumeration < ActiveRecord::Base
+  include Redmine::SubclassFactory
+
+  default_scope :order => "#{Enumeration.table_name}.position ASC"
+
+  belongs_to :project
+
+  acts_as_list :scope => 'type = \'#{type}\''
+  acts_as_customizable
+  acts_as_tree :order => "#{Enumeration.table_name}.position ASC"
+
+  before_destroy :check_integrity
+  before_save    :check_default
+
+  attr_protected :type
+
+  validates_presence_of :name
+  validates_uniqueness_of :name, :scope => [:type, :project_id]
+  validates_length_of :name, :maximum => 30
+
+  scope :shared, lambda { where(:project_id => nil) }
+  scope :sorted, lambda { order("#{table_name}.position ASC") }
+  scope :active, lambda { where(:active => true) }
+  scope :system, lambda { where(:project_id => nil) }
+  scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
+
+  def self.default
+    # Creates a fake default scope so Enumeration.default will check
+    # it's type.  STI subclasses will automatically add their own
+    # types to the finder.
+    if self.descends_from_active_record?
+      where(:is_default => true, :type => 'Enumeration').first
+    else
+      # STI classes are
+      where(:is_default => true).first
+    end
+  end
+
+  # Overloaded on concrete classes
+  def option_name
+    nil
+  end
+
+  def check_default
+    if is_default? && is_default_changed?
+      Enumeration.update_all({:is_default => false}, {:type => type})
+    end
+  end
+
+  # Overloaded on concrete classes
+  def objects_count
+    0
+  end
+
+  def in_use?
+    self.objects_count != 0
+  end
+
+  # Is this enumeration overiding a system level enumeration?
+  def is_override?
+    !self.parent.nil?
+  end
+
+  alias :destroy_without_reassign :destroy
+
+  # Destroy the enumeration
+  # If a enumeration is specified, objects are reassigned
+  def destroy(reassign_to = nil)
+    if reassign_to && reassign_to.is_a?(Enumeration)
+      self.transfer_relations(reassign_to)
+    end
+    destroy_without_reassign
+  end
+
+  def <=>(enumeration)
+    position <=> enumeration.position
+  end
+
+  def to_s; name end
+
+  # Returns the Subclasses of Enumeration.  Each Subclass needs to be
+  # required in development mode.
+  #
+  # Note: subclasses is protected in ActiveRecord
+  def self.get_subclasses
+    subclasses
+  end
+
+  # Does the +new+ Hash override the previous Enumeration?
+  def self.overridding_change?(new, previous)
+    if (same_active_state?(new['active'], previous.active)) && same_custom_values?(new,previous)
+      return false
+    else
+      return true
+    end
+  end
+
+  # Does the +new+ Hash have the same custom values as the previous Enumeration?
+  def self.same_custom_values?(new, previous)
+    previous.custom_field_values.each do |custom_value|
+      if custom_value.value != new["custom_field_values"][custom_value.custom_field_id.to_s]
+        return false
+      end
+    end
+
+    return true
+  end
+
+  # Are the new and previous fields equal?
+  def self.same_active_state?(new, previous)
+    new = (new == "1" ? true : false)
+    return new == previous
+  end
+
+private
+  def check_integrity
+    raise "Can't delete enumeration" if self.in_use?
+  end
+
+end
+
+# Force load the subclasses in development mode
+require_dependency 'time_entry_activity'
+require_dependency 'document_category'
+require_dependency 'issue_priority'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ca/caa1ddd4c159daa3892ce812a7b8945e9e584642.svn-base
--- a/.svn/pristine/ca/caa1ddd4c159daa3892ce812a7b8945e9e584642.svn-base
+++ /dev/null
@@ -1,90 +0,0 @@
-<div class="contextual">
-<% if !@query.new_record? && @query.editable_by?(User.current) %>
-  <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %>
-  <%= link_to l(:button_delete), query_path(@query), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
-<% end %>
-</div>
-
-<h2><%= @query.new_record? ? l(:label_issue_plural) : h(@query.name) %></h2>
-<% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %>
-
-<% form_tag({ :controller => 'issues', :action => 'index', :project_id => @project }, :method => :get, :id => 'query_form') do %>
-    <%= hidden_field_tag 'set_filter', '1' %>
-    <div id="query_form_content" class="hide-when-print">
-    <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
-      <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
-      <div style="<%= @query.new_record? ? "" : "display: none;" %>">
-        <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
-      </div>
-    </fieldset>
-    <fieldset class="collapsible collapsed">
-      <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
-      <div style="display: none;">
-        <table>
-          <tr>
-            <td><%= l(:field_column_names) %></td>
-            <td><%= render :partial => 'queries/columns', :locals => {:query => @query} %></td>
-          </tr>
-          <tr>
-            <td><label for='group_by'><%= l(:field_group_by) %></label></td>
-            <td><%= select_tag('group_by', options_for_select([[]] + @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, @query.group_by)) %></td>
-          </tr>
-        </table>
-      </div>
-    </fieldset>
-    </div>
-    <p class="buttons hide-when-print">
-
-    <%= link_to_function l(:button_apply), 'submit_query_form("query_form")', :class => 'icon icon-checked' %>
-    <%= link_to l(:button_clear), { :set_filter => 1, :project_id => @project }, :class => 'icon icon-reload'  %>
-    <% if @query.new_record? && User.current.allowed_to?(:save_queries, @project, :global => true) %>
-        <%= link_to_function l(:button_save), "$('query_form').action='#{ @project ? new_project_query_path : new_query_path }'; submit_query_form('query_form')", :class => 'icon icon-save' %>
-    <% end %>
-    </p>
-<% end %>
-
-<%= error_messages_for 'query' %>
-<% if @query.valid? %>
-<% if @issues.empty? %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% else %>
-<%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
-<p class="pagination"><%= pagination_links_full @issue_pages, @issue_count %></p>
-<% end %>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %>
-  <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
-  <%= f.link_to 'PDF', :url => params %>
-<% end %>
-
-<div id="csv-export-options" style="display:none;">
-  <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
-  <% form_tag(params.merge({:format => 'csv',:page=>nil}), :method => :get, :id => 'csv-export-form') do %>
-  <p>
-    <label><%= radio_button_tag 'columns', '', true %> <%= l(:description_selected_columns) %></label><br />
-    <label><%= radio_button_tag 'columns', 'all' %> <%= l(:description_all_columns) %></label>
-  </p>
-  <p>
-    <label><%= check_box_tag 'description', '1' %> <%= l(:field_description) %></label>
-  </p>
-  <p class="buttons">
-    <%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);" %>
-    <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
-  </p>
-  <% end %>
-</div>
-
-<% end %>
-<%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %>
-
-<% content_for :sidebar do %>
-    <%= render :partial => 'issues/sidebar' %>
-<% end %>
-
-<% content_for :header_tags do %>
-    <%= auto_discovery_link_tag(:atom, {:query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_issue_plural)) %>
-    <%= auto_discovery_link_tag(:atom, {:controller => 'journals', :action => 'index', :query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_changes_details)) %>
-<% end %>
-
-<%= context_menu issues_context_menu_path %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ca/caa790576a7a41ad0997dc10006135ba339b93a8.svn-base
--- a/.svn/pristine/ca/caa790576a7a41ad0997dc10006135ba339b93a8.svn-base
+++ /dev/null
@@ -1,29 +0,0 @@
-<% if @project.issue_categories.any? %>
-<table class="list">
-  <thead><tr>
-    <th><%= l(:label_issue_category) %></th>
-    <th><%= l(:field_assigned_to) %></th>
-    <th></th>
-  </tr></thead>
-  <tbody>
-<% for category in @project.issue_categories %>
-  <% unless category.new_record? %>
-  <tr class="<%= cycle 'odd', 'even' %>">
-    <td><%=h(category.name) %></td>
-    <td><%=h(category.assigned_to.name) if category.assigned_to %></td>
-    <td class="buttons">
-    	<% if User.current.allowed_to?(:manage_categories, @project) %>
-        <%= link_to l(:button_edit), edit_issue_category_path(category), :class => 'icon icon-edit' %>
-        <%= link_to l(:button_delete), issue_category_path(category), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
-		  <% end %>
-    </td>
-  </tr>
-  <% end %>
-<% end %>
-    </tbody>
-</table>
-<% else %>
-<p class="nodata"><%= l(:label_no_data) %></p>
-<% end %>
-
-<p><%= link_to l(:label_issue_category_new), new_project_issue_category_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_categories, @project) %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ca/caaf4adc236fed5cfdedcad59181499afa1fb97d.svn-base
--- a/.svn/pristine/ca/caaf4adc236fed5cfdedcad59181499afa1fb97d.svn-base
+++ /dev/null
@@ -1,205 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/cvs_adapter'
-require 'digest/sha1'
-
-class Repository::Cvs < Repository
-  validates_presence_of :url, :root_url, :log_encoding
-
-  def self.human_attribute_name(attribute_key_name)
-    attr_name = attribute_key_name
-    if attr_name == "root_url"
-      attr_name = "cvsroot"
-    elsif attr_name == "url"
-      attr_name = "cvs_module"
-    end
-    super(attr_name)
-  end
-
-  def self.scm_adapter_class
-    Redmine::Scm::Adapters::CvsAdapter
-  end
-
-  def self.scm_name
-    'CVS'
-  end
-
-  def entry(path=nil, identifier=nil)
-    rev = identifier.nil? ? nil : changesets.find_by_revision(identifier)
-    scm.entry(path, rev.nil? ? nil : rev.committed_on)
-  end
-
-  def entries(path=nil, identifier=nil)
-    rev = nil
-    if ! identifier.nil?
-      rev = changesets.find_by_revision(identifier)
-      return nil if rev.nil?
-    end
-    entries = scm.entries(path, rev.nil? ? nil : rev.committed_on)
-    if entries
-      entries.each() do |entry|
-        if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? )
-          change=changes.find_by_revision_and_path(
-                     entry.lastrev.revision,
-                     scm.with_leading_slash(entry.path) )
-          if change
-            entry.lastrev.identifier = change.changeset.revision
-            entry.lastrev.revision   = change.changeset.revision
-            entry.lastrev.author     = change.changeset.committer
-            # entry.lastrev.branch     = change.branch
-          end
-        end
-      end
-    end
-    entries
-  end
-
-  def cat(path, identifier=nil)
-    rev = nil
-    if ! identifier.nil?
-      rev = changesets.find_by_revision(identifier)
-      return nil if rev.nil?
-    end
-    scm.cat(path, rev.nil? ? nil : rev.committed_on)
-  end
-
-  def annotate(path, identifier=nil)
-    rev = nil
-    if ! identifier.nil?
-      rev = changesets.find_by_revision(identifier)
-      return nil if rev.nil?
-    end
-    scm.annotate(path, rev.nil? ? nil : rev.committed_on)
-  end
-
-  def diff(path, rev, rev_to)
-    # convert rev to revision. CVS can't handle changesets here
-    diff=[]
-    changeset_from = changesets.find_by_revision(rev)
-    if rev_to.to_i > 0
-      changeset_to = changesets.find_by_revision(rev_to)
-    end
-    changeset_from.changes.each() do |change_from|
-      revision_from = nil
-      revision_to   = nil
-      if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path))
-        revision_from = change_from.revision
-      end
-      if revision_from
-        if changeset_to
-          changeset_to.changes.each() do |change_to|
-            revision_to = change_to.revision if change_to.path == change_from.path
-          end
-        end
-        unless revision_to
-          revision_to = scm.get_previous_revision(revision_from)
-        end
-        file_diff = scm.diff(change_from.path, revision_from, revision_to)
-        diff = diff + file_diff unless file_diff.nil?
-      end
-    end
-    return diff
-  end
-
-  def fetch_changesets
-    # some nifty bits to introduce a commit-id with cvs
-    # natively cvs doesn't provide any kind of changesets,
-    # there is only a revision per file.
-    # we now take a guess using the author, the commitlog and the commit-date.
-
-    # last one is the next step to take. the commit-date is not equal for all
-    # commits in one changeset. cvs update the commit-date when the *,v file was touched. so
-    # we use a small delta here, to merge all changes belonging to _one_ changeset
-    time_delta  = 10.seconds
-    fetch_since = latest_changeset ? latest_changeset.committed_on : nil
-    transaction do
-      tmp_rev_num = 1
-      scm.revisions('', fetch_since, nil, :log_encoding => repo_log_encoding) do |revision|
-        # only add the change to the database, if it doen't exists. the cvs log
-        # is not exclusive at all.
-        tmp_time = revision.time.clone
-        unless changes.find_by_path_and_revision(
-	                         scm.with_leading_slash(revision.paths[0][:path]),
-	                         revision.paths[0][:revision]
-	                           )
-          cmt = Changeset.normalize_comments(revision.message, repo_log_encoding)
-          author_utf8 = Changeset.to_utf8(revision.author, repo_log_encoding)
-          cs  = changesets.find(
-            :first,
-            :conditions => {
-                :committed_on => tmp_time - time_delta .. tmp_time + time_delta,
-                :committer    => author_utf8,
-                :comments     => cmt
-                }
-             )
-          # create a new changeset....
-          unless cs
-            # we use a temporaray revision number here (just for inserting)
-            # later on, we calculate a continous positive number
-            tmp_time2 = tmp_time.clone.gmtime
-            branch    = revision.paths[0][:branch]
-            scmid     = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S")
-            cs = Changeset.create(:repository   => self,
-                                  :revision     => "tmp#{tmp_rev_num}",
-                                  :scmid        => scmid,
-                                  :committer    => revision.author,
-                                  :committed_on => tmp_time,
-                                  :comments     => revision.message)
-            tmp_rev_num += 1
-          end
-          # convert CVS-File-States to internal Action-abbrevations
-          # default action is (M)odified
-          action = "M"
-          if revision.paths[0][:action] == "Exp" && revision.paths[0][:revision] == "1.1"
-            action = "A" # add-action always at first revision (= 1.1)
-          elsif revision.paths[0][:action] == "dead"
-            action = "D" # dead-state is similar to Delete
-          end
-          Change.create(
-             :changeset => cs,
-             :action    => action,
-             :path      => scm.with_leading_slash(revision.paths[0][:path]),
-             :revision  => revision.paths[0][:revision],
-             :branch    => revision.paths[0][:branch]
-              )
-        end
-      end
-
-      # Renumber new changesets in chronological order
-      changesets.find(
-              :all,
-              :order => 'committed_on ASC, id ASC',
-              :conditions => "revision LIKE 'tmp%'"
-           ).each do |changeset|
-        changeset.update_attribute :revision, next_revision_number
-      end
-    end # transaction
-    @current_revision_number = nil
-  end
-
-  private
-
-  # Returns the next revision number to assign to a CVS changeset
-  def next_revision_number
-    # Need to retrieve existing revision numbers to sort them as integers
-    sql = "SELECT revision FROM #{Changeset.table_name} "
-    sql << "WHERE repository_id = #{id} AND revision NOT LIKE 'tmp%'"
-    @current_revision_number ||= (connection.select_values(sql).collect(&:to_i).max || 0)
-    @current_revision_number += 1
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ca/cadd13f5c17692bf3bd94786e8022d3458924f05.svn-base
--- a/.svn/pristine/ca/cadd13f5c17692bf3bd94786e8022d3458924f05.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-User-agent: *
-<% @projects.each do |p| -%>
-Disallow: /projects/<%= p.to_param %>/repository
-Disallow: /projects/<%= p.to_param %>/issues
-Disallow: /projects/<%= p.to_param %>/activity
-<% end -%>
-Disallow: /issues/gantt
-Disallow: /issues/calendar
-Disallow: /activity
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ca/cade6eedd6319cb3e2496764528bb0106de2f7c9.svn-base
--- a/.svn/pristine/ca/cade6eedd6319cb3e2496764528bb0106de2f7c9.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-<span id="attachments_fields">
-  <span>
-    <%= file_field_tag 'attachments[1][file]', :size => 30, :id => nil, :class => 'file',
-          :onchange => "checkFileSize(this, #{Setting.attachment_max_size.to_i.kilobytes}, '#{escape_javascript(l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)))}');"  -%>
-    <label class="inline"><%= l(:label_optional_description) %><%= text_field_tag 'attachments[1][description]', '', :size => 60, :id => nil, :class => 'description' %></label>
-    <%= link_to_function(image_tag('delete.png'), 'removeFileField(this)', :title => (l(:button_delete))) %>
-  </span>
-</span>
-<small><%= link_to l(:label_add_another_file), '#', :onclick => 'addFileField(); return false;' %>
-(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
-</small>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cb/cb0276a6b1828c54ac9135df3c312c39f935b7fa.svn-base
--- a/.svn/pristine/cb/cb0276a6b1828c54ac9135df3c312c39f935b7fa.svn-base
+++ /dev/null
@@ -1,54 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class ActionMailerWithinApplicationTest < Test::Unit::TestCase
-  
-  def test_normal_implicit_template
-    m = NotifyMail.create_signup("hello")
-    assert m.body =~ /^Signup template from application/
-  end
-  
-  def test_action_mailer_can_get_helper
-    m = NotifyMail.create_signup('James')
-    assert m.body =~ /James/
-    assert m.body =~ /semaJ/ # from the helper
-  end
-  
-  def test_multipart_mails_with_explicit_templates
-    m = NotifyMail.create_multipart
-    assert_equal 2, m.parts.length
-    assert_equal 'the html part of the email james', m.parts[0].body
-    assert_equal 'the plaintext part of the email', m.parts[1].body
-  end
-  
-  def test_multipart_mails_with_implicit_templates
-    m = NotifyMail.create_implicit_multipart
-    assert_equal 2, m.parts.length
-    assert_equal 'the implicit plaintext part of the email', m.parts[0].body    
-    assert_equal 'the implicit html part of the email james', m.parts[1].body
-  end
-end
-
-
-class ActionMailerWithinPluginsTest < Test::Unit::TestCase  
-  def test_should_be_able_to_create_mails_from_plugin
-    m = PluginMail.create_mail_from_plugin("from_plugin")
-    assert_equal "from_plugin", m.body
-  end
-  
-  def test_should_be_able_to_overload_views_within_the_application
-    m = PluginMail.create_mail_from_plugin_with_application_template("from_plugin")
-    assert_equal "from_plugin (from application)", m.body    
-  end
-  
-  def test_should_be_able_to_create_a_multipart_mail_from_within_plugin
-    m = PluginMail.create_multipart_from_plugin
-    assert_equal 2, m.parts.length
-    assert_equal 'html template', m.parts[0].body
-    assert_equal 'plain template', m.parts[1].body
-  end
-  
-  def test_plugin_mailer_template_overriding
-    m = PluginMail.create_multipart_from_plugin_with_application_template
-    assert_equal 'plugin mail template loaded from application', m.parts[1].body
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cb/cb0e71af9d9855ebc68f242e545c17bcb9905dc1.svn-base
--- a/.svn/pristine/cb/cb0e71af9d9855ebc68f242e545c17bcb9905dc1.svn-base
+++ /dev/null
@@ -1,271 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-<head>
-<title>RedmineWikiFormatting</title>
-<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-<style type="text/css">
-    body { font:80% Verdana,Tahoma,Arial,sans-serif; }
-    h1, h2, h3, h4 {  font-family: Trebuchet MS,Georgia,"Times New Roman",serif; }
-    pre, code { font-size:120%; }
-    pre code { font-size:100%; }
-    pre {
-        margin: 1em 1em 1em 1.6em;
-        padding: 2px;
-        background-color: #fafafa;
-        border: 1px solid #dadada;
-        width:95%;
-        overflow-x: auto;
-    }
-    a.new { color: #b73535; }
-
-    .syntaxhl .line-numbers { padding: 2px 4px 2px 4px; background-color: #eee; margin:0 }
-    .syntaxhl .comment  { color:#666; }
-
-    .syntaxhl .class { color:#B06; font-weight:bold }
-    .syntaxhl .delimiter { color:black }
-    .syntaxhl .function { color:#06B; font-weight:bold }
-
-    .syntaxhl .inline { background: #eee }
-    .syntaxhl .inline .inline-delimiter { font-weight: bold; color: #888 }
-
-    .syntaxhl .instance-variable { color:#33B }
-    .syntaxhl .reserved { color:#080; font-weight:bold }
-
-    .syntaxhl .string { background-color:#fff0f0; color: #D20; }
-    .syntaxhl .string .delimiter { color:#710 }
-
-</style>
-</head>
-
-<body>
-<h1><a name="1" class="wiki-page"></a>Wiki formatting</h1>
-
-    <h2><a name="2" class="wiki-page"></a>Links</h2>
-
-        <h3><a name="3" class="wiki-page"></a>Redmine links</h3>
-
-        <p>Redmine allows hyperlinking between issues, changesets and wiki pages from anywhere wiki formatting is used.</p>
-        <ul>
-            <li>Link to an issue: <strong>#124</strong> (displays <del><a href="#" class="issue" title="bulk edit doesn't change the category or fixed version properties (Closed)">#124</a></del>, link is striked-through if the issue is closed)</li>
-            <li>Link to a changeset: <strong>r758</strong> (displays <a href="#" class="changeset" title="Search engine now only searches objects the user is allowed to view.">r758</a>)</li>
-            <li>Link to a changeset with a non-numeric hash: <strong>commit:c6f4d0fd</strong> (displays <a href="#" class="changeset">c6f4d0fd</a>).</li>
-            <li>Link to a changeset of another project: <strong>sandbox:r758</strong> (displays <a href="#" class="changeset" title="Search engine now only searches objects the user is allowed to view.">sandbox:r758</a>)</li>
-            <li>Link to a changeset with a non-numeric hash: <strong>sandbox:c6f4d0fd</strong> (displays <a href="#" class="changeset">sandbox:c6f4d0fd</a>).</li>
-        </ul>
-
-        <p>Wiki links:</p>
-
-        <ul>
-            <li><strong>[[Guide]]</strong> displays a link to the page named 'Guide': <a href="#" class="wiki-page">Guide</a></li>
-            <li><strong>[[Guide#further-reading]]</strong> takes you to the anchor "further-reading". Headings get automatically assigned anchors so that you can refer to them: <a href="#" class="wiki-page">Guide</a></li>
-            <li><strong>[[Guide|User manual]]</strong> displays a link to the same page but with a different text: <a href="#" class="wiki-page">User manual</a></li>
-        </ul>
-
-        <p>You can also link to pages of an other project wiki:</p>
-
-        <ul>
-            <li><strong>[[sandbox:some page]]</strong> displays a link to the page named 'Some page' of the Sandbox wiki</li>
-            <li><strong>[[sandbox:]]</strong> displays a link to the Sandbox wiki main page</li>
-        </ul>
-
-        <p>Wiki links are displayed in red if the page doesn't exist yet, eg: <a href="#" class="wiki-page new">Nonexistent page</a>.</p>
-
-        <p>Links to other resources:</p>
-
-        <ul>
-            <li>Documents:
-                <ul>
-                    <li><strong>document#17</strong> (link to document with id 17)</li>
-                    <li><strong>document:Greetings</strong> (link to the document with title "Greetings")</li>
-                    <li><strong>document:"Some document"</strong> (double quotes can be used when document title contains spaces)</li>
-                    <li><strong>sandbox:document:"Some document"</strong> (link to a document with title "Some document" in other project "sandbox")</li>
-                </ul></li>
-        </ul>
-
-        <ul>
-            <li>Versions:
-                <ul>
-                    <li><strong>version#3</strong> (link to version with id 3)</li>
-                    <li><strong>version:1.0.0</strong> (link to version named "1.0.0")</li>
-                    <li><strong>version:"1.0 beta 2"</strong></li>
-                    <li><strong>sandbox:version:1.0.0</strong> (link to version "1.0.0" in the project "sandbox")</li>
-                </ul></li>
-        </ul>
-
-        <ul>
-            <li>Attachments:
-                <ul>
-                    <li><strong>attachment:file.zip</strong> (link to the attachment of the current object named file.zip)</li>
-                    <li>For now, attachments of the current object can be referenced only (if you're on an issue, it's possible to reference attachments of this issue only)</li>
-                </ul></li>
-        </ul>
-
-        <ul>
-             <li>Repository files:
-                <ul>
-                    <li><strong>source:some/file</strong>           (link to the file located at /some/file in the project's repository)</li>
-                    <li><strong>source:some/file@52</strong>        (link to the file's revision 52)</li>
-                    <li><strong>source:some/file#L120</strong>      (link to line 120 of the file)</li>
-                    <li><strong>source:some/file@52#L120</strong>   (link to line 120 of the file's revision 52)</li>
-                    <li><strong>source:"some file@52#L120"</strong> (use double quotes when the URL contains spaces</li>
-                    <li><strong>export:some/file</strong>           (force the download of the file)</li>
-                    <li><strong>sandbox:source:some/file</strong>   (link to the file located at /some/file in the repository of the project "sandbox")</li>
-                    <li><strong>sandbox:export:some/file</strong>   (force the download of the file)</li>
-                </ul></li>
-        </ul>
-
-        <ul>
-            <li>Forum messages:
-                <ul>
-                    <li><strong>message#1218</strong> (link to message with id 1218)</li>
-                </ul></li>
-        </ul>
-
-        <ul>
-            <li>Projects:
-                <ul>
-                    <li><strong>project#3</strong> (link to project with id 3)</li>
-                    <li><strong>project:someproject</strong> (link to project named "someproject")</li>
-                </ul></li>
-        </ul>
-
-
-        <p>Escaping:</p>
-
-        <ul>
-            <li>You can prevent Redmine links from being parsed by preceding them with an exclamation mark: !</li>
-        </ul>
-
-
-        <h3><a name="4" class="wiki-page"></a>External links</h3>
-
-        <p>HTTP URLs and email addresses are automatically turned into clickable links:</p>
-
-<pre>
-http://www.redmine.org, someone@foo.bar
-</pre>
-
-        <p>displays: <a class="external" href="http://www.redmine.org">http://www.redmine.org</a>, <a href="mailto:someone@foo.bar" class="email">someone@foo.bar</a></p>
-
-        <p>If you want to display a specific text instead of the URL, you can use the standard textile syntax:</p>
-
-<pre>
-"Redmine web site":http://www.redmine.org
-</pre>
-
-        <p>displays: <a href="http://www.redmine.org" class="external">Redmine web site</a></p>
-
-
-    <h2><a name="5" class="wiki-page"></a>Text formatting</h2>
-
-
-    <p>For things such as headlines, bold, tables, lists, Redmine supports Textile syntax.  See <a class="external" href="http://www.textism.com/tools/textile/">http://www.textism.com/tools/textile/</a> for information on using any of these features.  A few samples are included below, but the engine is capable of much more of that.</p>
-
-        <h3><a name="6" class="wiki-page"></a>Font style</h3>
-
-<pre>
-* *bold*
-* _italic_
-* _*bold italic*_
-* +underline+
-* -strike-through-
-</pre>
-
-        <p>Display:</p>
-
-        <ul>
-            <li><strong>bold</strong></li>
-            <li><em>italic</em></li>
-            <li><em>*bold italic*</em></li>
-            <li><ins>underline</ins></li>
-            <li><del>strike-through</del></li>
-        </ul>
-
-        <h3><a name="7" class="wiki-page"></a>Inline images</h3>
-
-        <ul>
-            <li><strong>!image_url!</strong> displays an image located at image_url (textile syntax)</li>
-            <li><strong>!>image_url!</strong> right floating image</li>
-            <li>If you have an image attached to your wiki page, it can be displayed inline using its filename: <strong>!attached_image.png!</strong></li>
-        </ul>
-
-        <h3><a name="8" class="wiki-page"></a>Headings</h3>
-
-<pre>
-h1. Heading
-h2. Subheading
-h3. Subsubheading
-</pre>
-
-        <p>Redmine assigns an anchor to each of those headings thus you can link to them with "#Heading", "#Subheading" and so forth.</p>
-
-
-        <h3><a name="9" class="wiki-page"></a>Paragraphs</h3>
-
-<pre>
-p>. right aligned
-p=. centered
-</pre>
-
-        <p style="text-align:center;">This is a centered paragraph.</p>
-
-
-        <h3><a name="10" class="wiki-page"></a>Blockquotes</h3>
-
-        <p>Start the paragraph with <strong>bq.</strong></p>
-
-<pre>
-bq. Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern.
-To go live, all you need to add is a database and a web server.
-</pre>
-
-        <p>Display:</p>
-
-        <blockquote>
-                <p>Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern.<br />To go live, all you need to add is a database and a web server.</p>
-        </blockquote>
-
-
-        <h3><a name="11" class="wiki-page"></a>Table of content</h3>
-
-<pre>
-{{toc}} => left aligned toc
-{{>toc}} => right aligned toc
-</pre>
-
-    <h2><a name="12" class="wiki-page"></a>Macros</h2>
-
-    <p>Redmine has the following builtin macros:</p>
-
-    <p><dl><dt><code>hello_world</code></dt><dd><p>Sample macro.</p></dd><dt><code>include</code></dt><dd><p>Include a wiki page. Example:</p>
-
-    <pre><code>{{include(Foo)}}</code></pre></dd><dt><code>macro_list</code></dt><dd><p>Displays a list of all available macros, including description if available.</p></dd></dl></p>
-
-
-    <h2><a name="13" class="wiki-page"></a>Code highlighting</h2>
-
-    <p>Default code highlightment relies on <a href="http://coderay.rubychan.de/" class="external">CodeRay</a>, a fast syntax highlighting library written completely in Ruby. It currently supports c, cpp, css, delphi, groovy, html, java, javascript, json, php, python, rhtml, ruby, scheme, sql, xml and yaml languages.</p>
-
-    <p>You can highlight code in your wiki page using this syntax:</p>
-
-<pre>
-&lt;pre&gt;&lt;code class="ruby"&gt;
-  Place you code here.
-&lt;/code&gt;&lt;/pre&gt;
-</pre>
-
-    <p>Example:</p>
-
-<pre><code class="ruby syntaxhl"><span class="line-numbers"> 1</span> <span class="comment"># The Greeter class</span>
-<span class="line-numbers"> 2</span> <span class="reserved">class</span> <span class="class">Greeter</span>
-<span class="line-numbers"> 3</span>   <span class="reserved">def</span> <span class="function">initialize</span>(name)
-<span class="line-numbers"> 4</span>     <span class="instance-variable">@name</span> = name.capitalize
-<span class="line-numbers"> 5</span>   <span class="reserved">end</span>
-<span class="line-numbers"> 6</span> 
-<span class="line-numbers"> 7</span>   <span class="reserved">def</span> <span class="function">salute</span>
-<span class="line-numbers"> 8</span>     puts <span class="string"><span class="delimiter">"</span><span class="content">Hello </span><span class="inline"><span class="inline-delimiter">#{</span><span class="instance-variable">@name</span><span class="inline-delimiter">}</span></span><span class="content">!</span><span class="delimiter">"</span></span> 
-<span class="line-numbers"> 9</span>   <span class="reserved">end</span>
-<span class="line-numbers"><strong>10</strong></span> <span class="reserved">end</span></code>
-</pre>
-</body>
-</html>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cb/cb35b0c83c5d7dbb01a2f023d75853f295f8ebcc.svn-base
--- /dev/null
+++ b/.svn/pristine/cb/cb35b0c83c5d7dbb01a2f023d75853f295f8ebcc.svn-base
@@ -0,0 +1,11 @@
+/*! jQuery v1.8.3 jquery.com | jquery.org/license */
+(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r<i;r++)v.event.add(t,n,u[n][r])}o.data&&(o.data=v.extend({},o.data))}function Ot(e,t){var n;if(t.nodeType!==1)return;t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),n==="object"?(t.parentNode&&(t.outerHTML=e.outerHTML),v.support.html5Clone&&e.innerHTML&&!v.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):n==="input"&&Et.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):n==="option"?t.selected=e.defaultSelected:n==="input"||n==="textarea"?t.defaultValue=e.defaultValue:n==="script"&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(v.expando)}function Mt(e){return typeof e.getElementsByTagName!="undefined"?e.getElementsByTagName("*"):typeof e.querySelectorAll!="undefined"?e.querySelectorAll("*"):[]}function _t(e){Et.test(e.type)&&(e.defaultChecked=e.checked)}function Qt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Jt.length;while(i--){t=Jt[i]+n;if(t in e)return t}return r}function Gt(e,t){return e=t||e,v.css(e,"display")==="none"||!v.contains(e.ownerDocument,e)}function Yt(e,t){var n,r,i=[],s=0,o=e.length;for(;s<o;s++){n=e[s];if(!n.style)continue;i[s]=v._data(n,"olddisplay"),t?(!i[s]&&n.style.display==="none"&&(n.style.display=""),n.style.display===""&&Gt(n)&&(i[s]=v._data(n,"olddisplay",nn(n.nodeName)))):(r=Dt(n,"display"),!i[s]&&r!=="none"&&v._data(n,"olddisplay",r))}for(s=0;s<o;s++){n=e[s];if(!n.style)continue;if(!t||n.style.display==="none"||n.style.display==="")n.style.display=t?i[s]||"":"none"}return e}function Zt(e,t,n){var r=Rt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function en(e,t,n,r){var i=n===(r?"border":"content")?4:t==="width"?1:0,s=0;for(;i<4;i+=2)n==="margin"&&(s+=v.css(e,n+$t[i],!0)),r?(n==="content"&&(s-=parseFloat(Dt(e,"padding"+$t[i]))||0),n!=="margin"&&(s-=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0)):(s+=parseFloat(Dt(e,"padding"+$t[i]))||0,n!=="padding"&&(s+=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0));return s}function tn(e,t,n){var r=t==="width"?e.offsetWidth:e.offsetHeight,i=!0,s=v.support.boxSizing&&v.css(e,"boxSizing")==="border-box";if(r<=0||r==null){r=Dt(e,t);if(r<0||r==null)r=e.style[t];if(Ut.test(r))return r;i=s&&(v.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+en(e,t,n||(s?"border":"content"),i)+"px"}function nn(e){if(Wt[e])return Wt[e];var t=v("<"+e+">").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write("<!doctype html><html><body>"),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<a;u++)r=o[u],s=/^\+/.test(r),s&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[s?"unshift":"push"](n)}}function kn(e,n,r,i,s,o){s=s||n.dataTypes[0],o=o||{},o[s]=!0;var u,a=e[s],f=0,l=a?a.length:0,c=e===Sn;for(;f<l&&(c||!u);f++)u=a[f](n,r,i),typeof u=="string"&&(!c||o[u]?u=t:(n.dataTypes.unshift(u),u=kn(e,n,r,i,u,o)));return(c||!u)&&!o["*"]&&(u=kn(e,n,r,i,"*",o)),u}function Ln(e,n){var r,i,s=v.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((s[r]?e:i||(i={}))[r]=n[r]);i&&v.extend(!0,e,i)}function An(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes,l=e.responseFields;for(s in l)s in r&&(n[l[s]]=r[s]);while(f[0]==="*")f.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(s in a)if(a[s]&&a[s].test(i)){f.unshift(s);break}if(f[0]in r)o=f[0];else{for(s in r){if(!f[0]||e.converters[s+" "+f[0]]){o=s;break}u||(u=s)}o=o||u}if(o)return o!==f[0]&&f.unshift(o),r[o]}function On(e,t){var n,r,i,s,o=e.dataTypes.slice(),u=o[0],a={},f=0;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(o[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=o[++f];)if(i!=="*"){if(u!=="*"&&u!==i){n=a[u+" "+i]||a["* "+i];if(!n)for(r in a){s=r.split(" ");if(s[1]===i){n=a[u+" "+s[0]]||a["* "+s[0]];if(n){n===!0?n=a[r]:a[r]!==!0&&(i=s[0],o.splice(f--,0,i));break}}}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(l){return{state:"parsererror",error:n?l:"No conversion from "+u+" to "+i}}}u=i}return{state:"success",data:t}}function Fn(){try{return new e.XMLHttpRequest}catch(t){}}function In(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function $n(){return setTimeout(function(){qn=t},0),qn=v.now()}function Jn(e,t){v.each(t,function(t,n){var r=(Vn[t]||[]).concat(Vn["*"]),i=0,s=r.length;for(;i<s;i++)if(r[i].call(e,t,n))return})}function Kn(e,t,n){var r,i=0,s=0,o=Xn.length,u=v.Deferred().always(function(){delete a.elem}),a=function(){var t=qn||$n(),n=Math.max(0,f.startTime+f.duration-t),r=n/f.duration||0,i=1-r,s=0,o=f.tweens.length;for(;s<o;s++)f.tweens[s].run(i);return u.notifyWith(e,[f,i,n]),i<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n<r;n++)f.tweens[n].run(1);return t?u.resolveWith(e,[f,t]):u.rejectWith(e,[f,t]),this}}),l=f.props;Qn(l,f.opts.specialEasing);for(;i<o;i++){r=Xn[i].call(f,e,l,f.opts);if(r)return r}return Jn(f,l),v.isFunction(f.opts.start)&&f.opts.start.call(e,f),v.fx.timer(v.extend(a,{anim:f,queue:f.opts.queue,elem:e})),f.progress(f.opts.progress).done(f.opts.done,f.opts.complete).fail(f.opts.fail).always(f.opts.always)}function Qn(e,t){var n,r,i,s,o;for(n in e){r=v.camelCase(n),i=t[r],s=e[n],v.isArray(s)&&(i=s[1],s=e[n]=s[0]),n!==r&&(e[r]=s,delete e[n]),o=v.cssHooks[r];if(o&&"expand"in o){s=o.expand(s),delete e[r];for(n in s)n in e||(e[n]=s[n],t[n]=i)}else t[r]=i}}function Gn(e,t,n){var r,i,s,o,u,a,f,l,c,h=this,p=e.style,d={},m=[],g=e.nodeType&&Gt(e);n.queue||(l=v._queueHooks(e,"fx"),l.unqueued==null&&(l.unqueued=0,c=l.empty.fire,l.empty.fire=function(){l.unqueued||c()}),l.unqueued++,h.always(function(){h.always(function(){l.unqueued--,v.queue(e,"fx").length||l.empty.fire()})})),e.nodeType===1&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],v.css(e,"display")==="inline"&&v.css(e,"float")==="none"&&(!v.support.inlineBlockNeedsLayout||nn(e.nodeName)==="inline"?p.display="inline-block":p.zoom=1)),n.overflow&&(p.overflow="hidden",v.support.shrinkWrapBlocks||h.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t){s=t[r];if(Un.exec(s)){delete t[r],a=a||s==="toggle";if(s===(g?"hide":"show"))continue;m.push(r)}}o=m.length;if(o){u=v._data(e,"fxshow")||v._data(e,"fxshow",{}),"hidden"in u&&(g=u.hidden),a&&(u.hidden=!g),g?v(e).show():h.done(function(){v(e).hide()}),h.done(function(){var t;v.removeData(e,"fxshow",!0);for(t in d)v.style(e,t,d[t])});for(r=0;r<o;r++)i=m[r],f=h.createTween(i,g?u[i]:0),d[i]=u[i]||v.style(e,i),i in u||(u[i]=f.start,g&&(f.end=f.start,f.start=i==="width"||i==="height"?1:0))}}function Yn(e,t,n,r,i){return new Yn.prototype.init(e,t,n,r,i)}function Zn(e,t){var n,r={height:e},i=0;t=t?1:0;for(;i<4;i+=2-t)n=$t[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function tr(e){return v.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:!1}var n,r,i=e.document,s=e.location,o=e.navigator,u=e.jQuery,a=e.$,f=Array.prototype.push,l=Array.prototype.slice,c=Array.prototype.indexOf,h=Object.prototype.toString,p=Object.prototype.hasOwnProperty,d=String.prototype.trim,v=function(e,t){return new v.fn.init(e,t,n)},m=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,g=/\S/,y=/\s+/,b=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,w=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a<f;a++)if((e=arguments[a])!=null)for(n in e){r=u[n],i=e[n];if(u===i)continue;l&&i&&(v.isPlainObject(i)||(s=v.isArray(i)))?(s?(s=!1,o=r&&v.isArray(r)?r:[]):o=r&&v.isPlainObject(r)?r:{},u[n]=v.extend(l,o,i)):i!==t&&(u[n]=i)}return u},v.extend({noConflict:function(t){return e.$===v&&(e.$=a),t&&e.jQuery===v&&(e.jQuery=u),v},isReady:!1,readyWait:1,holdReady:function(e){e?v.readyWait++:v.ready(!0)},ready:function(e){if(e===!0?--v.readyWait:v.isReady)return;if(!i.body)return setTimeout(v.ready,1);v.isReady=!0;if(e!==!0&&--v.readyWait>0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s<o;)if(n.apply(e[s++],r)===!1)break}else if(u){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;s<o;)if(n.call(e[s],s,e[s++])===!1)break;return e},trim:d&&!d.call("\ufeff\u00a0")?function(e){return e==null?"":d.call(e)}:function(e){return e==null?"":(e+"").replace(b,"")},makeArray:function(e,t){var n,r=t||[];return e!=null&&(n=v.type(e),e.length==null||n==="string"||n==="function"||n==="regexp"||v.isWindow(e)?f.call(r,e):v.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(c)return c.call(t,e,n);r=t.length,n=n?n<0?Math.max(0,r+n):n:0;for(;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,s=0;if(typeof r=="number")for(;s<r;s++)e[i++]=n[s];else while(n[s]!==t)e[i++]=n[s++];return e.length=i,e},grep:function(e,t,n){var r,i=[],s=0,o=e.length;n=!!n;for(;s<o;s++)r=!!t(e[s],s),n!==r&&i.push(e[s]);return i},map:function(e,n,r){var i,s,o=[],u=0,a=e.length,f=e instanceof v||a!==t&&typeof a=="number"&&(a>0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u<a;u++)i=n(e[u],u,r),i!=null&&(o[o.length]=i);else for(s in e)i=n(e[s],s,r),i!=null&&(o[o.length]=i);return o.concat.apply([],o)},guid:1,proxy:function(e,n){var r,i,s;return typeof n=="string"&&(r=e[n],n=e,e=r),v.isFunction(e)?(i=l.call(arguments,2),s=function(){return e.apply(n,i.concat(l.call(arguments)))},s.guid=e.guid=e.guid||v.guid++,s):t},access:function(e,n,r,i,s,o,u){var a,f=r==null,l=0,c=e.length;if(r&&typeof r=="object"){for(l in r)v.access(e,n,l,r[l],1,o,i);s=1}else if(i!==t){a=u===t&&v.isFunction(i),f&&(a?(a=n,n=function(e,t,n){return a.call(v(e),n)}):(n.call(e,i),n=null));if(n)for(;l<c;l++)n(e[l],r,a?i.call(e[l],l,n(e[l],r)):i,u);s=1}return s?e:f?n.call(e):c?n(e[0],r):o},now:function(){return(new Date).getTime()}}),v.ready.promise=function(t){if(!r){r=v.Deferred();if(i.readyState==="complete")setTimeout(v.ready,1);else if(i.addEventListener)i.addEventListener("DOMContentLoaded",A,!1),e.addEventListener("load",v.ready,!1);else{i.attachEvent("onreadystatechange",A),e.attachEvent("onload",v.ready);var n=!1;try{n=e.frameElement==null&&i.documentElement}catch(s){}n&&n.doScroll&&function o(){if(!v.isReady){try{n.doScroll("left")}catch(e){return setTimeout(o,50)}v.ready()}}()}}return r.promise(t)},v.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){O["[object "+t+"]"]=t.toLowerCase()}),n=v(i);var M={};v.Callbacks=function(e){e=typeof e=="string"?M[e]||_(e):v.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){n=e.memory&&t,r=!0,u=s||0,s=0,o=a.length,i=!0;for(;a&&u<o;u++)if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}i=!1,a&&(f?f.length&&l(f.shift()):n?a=[]:c.disable())},c={add:function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this},remove:function(){return a&&v.each(arguments,function(e,t){var n;while((n=v.inArray(t,a,n))>-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t<r;t++)n[t]&&v.isFunction(n[t].promise)?n[t].promise().done(o(t,f,n)).fail(s.reject).progress(o(t,a,u)):--i}return i||s.resolveWith(f,n),s.promise()}}),v.support=function(){var t,n,r,s,o,u,a,f,l,c,h,p=i.createElement("div");p.setAttribute("className","t"),p.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i<s;i++)delete r[t[i]];if(!(n?B:v.isEmptyObject)(r))return}}if(!n){delete u[a].data;if(!B(u[a]))return}o?v.cleanData([e],!0):v.support.deleteExpando||u!=u.window?delete u[a]:u[a]=null},_data:function(e,t,n){return v.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&v.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),v.fn.extend({data:function(e,n){var r,i,s,o,u,a=this[0],f=0,l=null;if(e===t){if(this.length){l=v.data(a);if(a.nodeType===1&&!v._data(a,"parsedAttrs")){s=a.attributes;for(u=s.length;f<u;f++)o=s[f].name,o.indexOf("data-")||(o=v.camelCase(o.substring(5)),H(a,o,l[o]));v._data(a,"parsedAttrs",!0)}}return l}return typeof e=="object"?this.each(function(){v.data(this,e)}):(r=e.split(".",2),r[1]=r[1]?"."+r[1]:"",i=r[1]+"!",v.access(this,function(n){if(n===t)return l=this.triggerHandler("getData"+i,[r[0]]),l===t&&a&&(l=v.data(a,e),l=H(a,e,l)),l===t&&r[1]?this.data(r[0]):l;r[1]=n,this.each(function(){var t=v(this);t.triggerHandler("setData"+i,r),v.data(this,e,n),t.triggerHandler("changeData"+i,r)})},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length<r?v.queue(this[0],e):n===t?this:this.each(function(){var t=v.queue(this,e,n);v._queueHooks(this,e),e==="fx"&&t[0]!=="inprogress"&&v.dequeue(this,e)})},dequeue:function(e){return this.each(function(){v.dequeue(this,e)})},delay:function(e,t){return e=v.fx?v.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,s=v.Deferred(),o=this,u=this.length,a=function(){--i||s.resolveWith(o,[o])};typeof e!="string"&&(n=e,e=t),e=e||"fx";while(u--)r=v._data(o[u],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(a));return a(),s.promise(n)}});var j,F,I,q=/[\t\r\n]/g,R=/\r/g,U=/^(?:button|input)$/i,z=/^(?:button|input|object|select|textarea)$/i,W=/^a(?:rea|)$/i,X=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,V=v.support.getSetAttribute;v.fn.extend({attr:function(e,t){return v.access(this,v.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<r;n++){i=this[n];if(i.nodeType===1)if(!i.className&&t.length===1)i.className=e;else{s=" "+i.className+" ";for(o=0,u=t.length;o<u;o++)s.indexOf(" "+t[o]+" ")<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u<a;u++){i=this[u];if(i.nodeType===1&&i.className){r=(" "+i.className+" ").replace(q," ");for(s=0,o=n.length;s<o;s++)while(r.indexOf(" "+n[s]+" ")>=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n<r;n++)if(this[n].nodeType===1&&(" "+this[n].className+" ").replace(q," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a<u;a++){n=r[a];if((n.selected||a===i)&&(v.support.optDisabled?!n.disabled:n.getAttribute("disabled")===null)&&(!n.parentNode.disabled||!v.nodeName(n.parentNode,"optgroup"))){t=v(n).val();if(s)return t;o.push(t)}}return o},set:function(e,t){var n=v.makeArray(t);return v(e).find("option").each(function(){this.selected=v.inArray(v(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o<r.length;o++)i=r[o],i&&(n=v.propFix[i]||i,s=X.test(i),s||v.attr(e,i,""),e.removeAttribute(V?i:n),s&&n in e&&(e[n]=!1))}},attrHooks:{type:{set:function(e,t){if(U.test(e.nodeName)&&e.parentNode)v.error("type property can't be changed");else if(!v.support.radioValue&&t==="radio"&&v.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return j&&v.nodeName(e,"button")?j.get(e,t):t in e?e.value:null},set:function(e,t,n){if(j&&v.nodeName(e,"button"))return j.set(e,t,n);e.value=t}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2)return;return o=u!==1||!v.isXMLDoc(e),o&&(n=v.propFix[n]||n,s=v.propHooks[n]),r!==t?s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r:s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):z.test(e.nodeName)||W.test(e.nodeName)&&e.href?0:t}}}}),F={get:function(e,n){var r,i=v.prop(e,n);return i===!0||typeof i!="boolean"&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?v.removeAttr(e,n):(r=v.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},V||(I={name:!0,id:!0,coords:!0},j=v.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(I[n]?r.value!=="":r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=i.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},v.each(["width","height"],function(e,t){v.attrHooks[t]=v.extend(v.attrHooks[t],{set:function(e,n){if(n==="")return e.setAttribute(t,"auto"),n}})}),v.attrHooks.contenteditable={get:j.get,set:function(e,t,n){t===""&&(t="false"),j.set(e,t,n)}}),v.support.hrefNormalized||v.each(["href","src","width","height"],function(e,n){v.attrHooks[n]=v.extend(v.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return r===null?t:r}})}),v.support.style||(v.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=t+""}}),v.support.optSelected||(v.propHooks.selected=v.extend(v.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),v.support.enctype||(v.propFix.enctype="encoding"),v.support.checkOn||v.each(["radio","checkbox"],function(){v.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),v.each(["radio","checkbox"],function(){v.valHooks[this]=v.extend(v.valHooks[this],{set:function(e,t){if(v.isArray(t))return e.checked=v.inArray(v(e).val(),t)>=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f<n.length;f++){l=J.exec(n[f])||[],c=l[1],h=(l[2]||"").split(".").sort(),g=v.event.special[c]||{},c=(s?g.delegateType:g.bindType)||c,g=v.event.special[c]||{},p=v.extend({type:c,origType:l[1],data:i,handler:r,guid:r.guid,selector:s,needsContext:s&&v.expr.match.needsContext.test(s),namespace:h.join(".")},d),m=a[c];if(!m){m=a[c]=[],m.delegateCount=0;if(!g.setup||g.setup.call(e,i,h,u)===!1)e.addEventListener?e.addEventListener(c,u,!1):e.attachEvent&&e.attachEvent("on"+c,u)}g.add&&(g.add.call(e,p),p.handler.guid||(p.handler.guid=r.guid)),s?m.splice(m.delegateCount++,0,p):m.push(p),v.event.global[c]=!0}e=null},global:{},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,m,g=v.hasData(e)&&v._data(e);if(!g||!(h=g.events))return;t=v.trim(Z(t||"")).split(" ");for(s=0;s<t.length;s++){o=J.exec(t[s])||[],u=a=o[1],f=o[2];if(!u){for(u in h)v.event.remove(e,u+t[s],n,r,!0);continue}p=v.event.special[u]||{},u=(r?p.delegateType:p.bindType)||u,d=h[u]||[],l=d.length,f=f?new RegExp("(^|\\.)"+f.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(c=0;c<d.length;c++)m=d[c],(i||a===m.origType)&&(!n||n.guid===m.guid)&&(!f||f.test(m.namespace))&&(!r||r===m.selector||r==="**"&&m.selector)&&(d.splice(c--,1),m.selector&&d.delegateCount--,p.remove&&p.remove.call(e,m));d.length===0&&l!==d.length&&((!p.teardown||p.teardown.call(e,f,g.handle)===!1)&&v.removeEvent(e,u,g.handle),delete h[u])}v.isEmptyObject(h)&&(delete g.handle,v.removeData(e,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,s,o){if(!s||s.nodeType!==3&&s.nodeType!==8){var u,a,f,l,c,h,p,d,m,g,y=n.type||n,b=[];if(Y.test(y+v.event.triggered))return;y.indexOf("!")>=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f<m.length&&!n.isPropagationStopped();f++)l=m[f][0],n.type=m[f][1],d=(v._data(l,"events")||{})[n.type]&&v._data(l,"handle"),d&&d.apply(l,r),d=h&&l[h],d&&v.acceptData(l)&&d.apply&&d.apply(l,r)===!1&&n.preventDefault();return n.type=y,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(s.ownerDocument,r)===!1)&&(y!=="click"||!v.nodeName(s,"a"))&&v.acceptData(s)&&h&&s[y]&&(y!=="focus"&&y!=="blur"||n.target.offsetWidth!==0)&&!v.isWindow(s)&&(c=s[h],c&&(s[h]=null),v.event.triggered=y,s[y](),v.event.triggered=t,c&&(s[h]=c)),n.result}return},dispatch:function(n){n=v.event.fix(n||e.event);var r,i,s,o,u,a,f,c,h,p,d=(v._data(this,"events")||{})[n.type]||[],m=d.delegateCount,g=l.call(arguments),y=!n.exclusive&&!n.namespace,b=v.event.special[n.type]||{},w=[];g[0]=n,n.delegateTarget=this;if(b.preDispatch&&b.preDispatch.call(this,n)===!1)return;if(m&&(!n.button||n.type!=="click"))for(s=n.target;s!=this;s=s.parentNode||this)if(s.disabled!==!0||n.type!=="click"){u={},f=[];for(r=0;r<m;r++)c=d[r],h=c.selector,u[h]===t&&(u[h]=c.needsContext?v(h,this).index(s)>=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r<w.length&&!n.isPropagationStopped();r++){a=w[r],n.currentTarget=a.elem;for(i=0;i<a.matches.length&&!n.isImmediatePropagationStopped();i++){c=a.matches[i];if(y||!n.namespace&&!c.namespace||n.namespace_re&&n.namespace_re.test(c.namespace))n.data=c.data,n.handleObj=c,o=((v.event.special[c.origType]||{}).handle||c.handler).apply(a.elem,g),o!==t&&(n.result=o,o===!1&&(n.preventDefault(),n.stopPropagation()))}}return b.postDispatch&&b.postDispatch.call(this,n),n.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return e.which==null&&(e.which=t.charCode!=null?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,s,o,u=n.button,a=n.fromElement;return e.pageX==null&&n.clientX!=null&&(r=e.target.ownerDocument||i,s=r.documentElement,o=r.body,e.pageX=n.clientX+(s&&s.scrollLeft||o&&o.scrollLeft||0)-(s&&s.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(s&&s.scrollTop||o&&o.scrollTop||0)-(s&&s.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?n.toElement:a),!e.which&&u!==t&&(e.which=u&1?1:u&2?3:u&4?2:0),e}},fix:function(e){if(e[v.expando])return e;var t,n,r=e,s=v.event.fixHooks[e.type]||{},o=s.props?this.props.concat(s.props):this.props;e=v.Event(r);for(t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||i),e.target.nodeType===3&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,r):e},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){v.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=v.extend(new v.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?v.event.trigger(i,null,t):v.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},v.event.handle=v.event.dispatch,v.removeEvent=i.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]=="undefined"&&(e[r]=null),e.detachEvent(r,n))},v.Event=function(e,t){if(!(this instanceof v.Event))return new v.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?tt:et):this.type=e,t&&v.extend(this,t),this.timeStamp=e&&e.timeStamp||v.now(),this[v.expando]=!0},v.Event.prototype={preventDefault:function(){this.isDefaultPrevented=tt;var e=this.originalEvent;if(!e)return;e.preventDefault?e.preventDefault():e.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=tt;var e=this.originalEvent;if(!e)return;e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=tt,this.stopPropagation()},isDefaultPrevented:et,isPropagationStopped:et,isImmediatePropagationStopped:et},v.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){v.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,s=e.handleObj,o=s.selector;if(!i||i!==r&&!v.contains(r,i))e.type=s.origType,n=s.handler.apply(this,arguments),e.type=t;return n}}}),v.support.submitBubbles||(v.event.special.submit={setup:function(){if(v.nodeName(this,"form"))return!1;v.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=v.nodeName(n,"input")||v.nodeName(n,"button")?n.form:t;r&&!v._data(r,"_submit_attached")&&(v.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),v._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&v.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){if(v.nodeName(this,"form"))return!1;v.event.remove(this,"._submit")}}),v.support.changeBubbles||(v.event.special.change={setup:function(){if($.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")v.event.add(this,"propertychange._change",function(e){e.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),v.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),v.event.simulate("change",this,e,!0)});return!1}v.event.add(this,"beforeactivate._change",function(e){var t=e.target;$.test(t.nodeName)&&!v._data(t,"_change_attached")&&(v.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&v.event.simulate("change",this.parentNode,e,!0)}),v._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||t.type!=="radio"&&t.type!=="checkbox")return e.handleObj.handler.apply(this,arguments)},teardown:function(){return v.event.remove(this,"._change"),!$.test(this.nodeName)}}),v.support.focusinBubbles||v.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){v.event.simulate(t,e.target,v.event.fix(e),!0)};v.event.special[t]={setup:function(){n++===0&&i.addEventListener(e,r,!0)},teardown:function(){--n===0&&i.removeEventListener(e,r,!0)}}}),v.fn.extend({on:function(e,n,r,i,s){var o,u;if(typeof e=="object"){typeof n!="string"&&(r=r||n,n=t);for(u in e)this.on(u,n,r,e[u],s);return this}r==null&&i==null?(i=n,r=n=t):i==null&&(typeof n=="string"?(i=r,r=t):(i=r,r=n,n=t));if(i===!1)i=et;else if(!i)return this;return s===1&&(o=i,i=function(e){return v().off(e),o.apply(this,arguments)},i.guid=o.guid||(o.guid=v.guid++)),this.each(function(){v.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,s;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,v(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if(typeof e=="object"){for(s in e)this.off(s,n,e[s]);return this}if(n===!1||typeof n=="function")r=n,n=t;return r===!1&&(r=et),this.each(function(){v.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return v(this.context).on(e,this.selector,t,n),this},die:function(e,t){return v(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){v.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return v.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||v.guid++,r=0,i=function(n){var i=(v._data(this,"lastToggle"+e.guid)||0)%r;return v._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};i.guid=n;while(r<t.length)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),v.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){v.fn[t]=function(e,n){return n==null&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u<a;u++)if(s=e[u])if(!n||n(s,r,i))o.push(s),f&&t.push(u);return o}function ct(e,t,n,r,i,s){return r&&!r[d]&&(r=ct(r)),i&&!i[d]&&(i=ct(i,s)),N(function(s,o,u,a){var f,l,c,h=[],p=[],d=o.length,v=s||dt(t||"*",u.nodeType?[u]:u,[]),m=e&&(s||!t)?lt(v,h,e,u,a):v,g=n?i||(s?e:d||r)?[]:o:m;n&&n(m,g,u,a);if(r){f=lt(g,p),r(f,[],u,a),l=f.length;while(l--)if(c=f[l])g[p[l]]=!(m[p[l]]=c)}if(s){if(i||e){if(i){f=[],l=g.length;while(l--)(c=g[l])&&f.push(m[l]=c);i(null,g=[],f,a)}l=g.length;while(l--)(c=g[l])&&(f=i?T.call(s,c):h[l])>-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a<s;a++)if(n=i.relative[e[a].type])h=[at(ft(h),n)];else{n=i.filter[e[a].type].apply(null,e[a].matches);if(n[d]){r=++a;for(;r<s;r++)if(i.relative[e[r].type])break;return ct(a>1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a<r&&ht(e.slice(a,r)),r<s&&ht(e=e.slice(r)),r<s&&e.join(""))}h.push(n)}return ft(h)}function pt(e,t){var r=t.length>0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r<i;r++)nt(e,t[r],n);return n}function vt(e,t,n,r,s){var o,u,f,l,c,h=ut(e),p=h.length;if(!r&&h.length===1){u=h[0]=h[0].slice(0);if(u.length>2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;t<n;t++)if(this[t]===e)return t;return-1},N=function(e,t){return e[d]=t==null||t,e},C=function(){var e={},t=[];return N(function(n,r){return t.push(n)>i.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="<a name='"+d+"'></a><div name='"+d+"'></div>",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:st(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:st(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},f=y.compareDocumentPosition?function(e,t){return e===t?(l=!0,0):(!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition:e.compareDocumentPosition(t)&4)?-1:1}:function(e,t){if(e===t)return l=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return ot(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var f=0;f<n&&f<r;f++)if(i[f]!==s[f])return ot(i[f],s[f]);return f===n?ot(e,s[f],-1):ot(i[f],t,1)},[0,0].sort(f),h=!l,nt.uniqueSort=function(e){var t,n=[],r=1,i=0;l=h,e.sort(f);if(l){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e},nt.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a=nt.compile=function(e,t){var n,r=[],i=[],s=A[d][e+" "];if(!s){t||(t=ut(e)),n=t.length;while(n--)s=ht(t[n]),s[d]?r.push(s):i.push(s);s=A(e,pt(i,r))}return s},g.querySelectorAll&&function(){var e,t=vt,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[":focus"],s=[":active"],u=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector||y.oMatchesSelector||y.msMatchesSelector;K(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'/>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t<n;t++)if(v.contains(u[t],this))return!0});o=this.pushStack("","find",e);for(t=0,n=this.length;t<n;t++){r=o.length,v.find(e,this[t],o);if(t>0)for(i=r;i<o.length;i++)for(s=0;s<r;s++)if(o[s]===o[i]){o.splice(i--,1);break}}return o},has:function(e){var t,n=v(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(v.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1),"not",e)},filter:function(e){return this.pushStack(ft(this,e,!0),"filter",e)},is:function(e){return!!e&&(typeof e=="string"?st.test(e)?v(e,this.context).index(this[0])>=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r<i;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&n.nodeType!==11){if(o?o.index(n)>-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<tbody/i,gt=/<|&#?\w+;/,yt=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,wt=new RegExp("<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Nt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X<div>","</div>"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(s){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return ut(this[0])?this.length?this.pushStack(v(v.isFunction(e)?e():e),"replaceWith",e):this:v.isFunction(e)?this.each(function(t){var n=v(this),r=n.html();n.replaceWith(e.call(this,t,r))}):(typeof e!="string"&&(e=v(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;v(this).remove(),t?v(t).before(e):v(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,s,o,u,a=0,f=e[0],l=[],c=this.length;if(!v.support.checkClone&&c>1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a<c;a++)r.call(n&&v.nodeName(this[a],"table")?Lt(this[a],"tbody"):this[a],a===u?o:v.clone(o,!0,!0))}o=s=null,l.length&&v.each(l,function(e,t){t.src?v.ajax?v.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):v.error("no ajax"):v.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Tt,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),v.buildFragment=function(e,n,r){var s,o,u,a=e[0];return n=n||i,n=!n.nodeType&&n[0]||n,n=n.ownerDocument||n,e.length===1&&typeof a=="string"&&a.length<512&&n===i&&a.charAt(0)==="<"&&!bt.test(a)&&(v.support.checkClone||!St.test(a))&&(v.support.html5Clone||!wt.test(a))&&(o=!0,s=v.fragments[a],u=s!==t),s||(s=n.createDocumentFragment(),v.clean(e,n,s,r),o&&(v.fragments[a]=u&&s)),{fragment:s,cacheable:o}},v.fragments={},v.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){v.fn[e]=function(n){var r,i=0,s=[],o=v(n),u=o.length,a=this.length===1&&this[0].parentNode;if((a==null||a&&a.nodeType===11&&a.childNodes.length===1)&&u===1)return o[t](this[0]),this;for(;i<u;i++)r=(i>0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1></$2>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]==="<table>"&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("<div>").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r<i;r++)n=e[r],Vn[n]=Vn[n]||[],Vn[n].unshift(t)},prefilter:function(e,t){t?Xn.unshift(e):Xn.push(e)}}),v.Tween=Yn,Yn.prototype={constructor:Yn,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(v.cssNumber[n]?"":"px")},cur:function(){var e=Yn.propHooks[this.prop];return e&&e.get?e.get(this):Yn.propHooks._default.get(this)},run:function(e){var t,n=Yn.propHooks[this.prop];return this.options.duration?this.pos=t=v.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Yn.propHooks._default.set(this),this}},Yn.prototype.init.prototype=Yn.prototype,Yn.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=v.css(e.elem,e.prop,!1,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){v.fx.step[e.prop]?v.fx.step[e.prop](e):e.elem.style&&(e.elem.style[v.cssProps[e.prop]]!=null||v.cssHooks[e.prop])?v.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Yn.propHooks.scrollTop=Yn.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},v.each(["toggle","show","hide"],function(e,t){var n=v.fn[t];v.fn[t]=function(r,i,s){return r==null||typeof r=="boolean"||!e&&v.isFunction(r)&&v.isFunction(i)?n.apply(this,arguments):this.animate(Zn(t,!0),r,i,s)}}),v.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Gt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=v.isEmptyObject(e),s=v.speed(t,n,r),o=function(){var t=Kn(this,v.extend({},e),s);i&&t.stop(!0)};return i||s.queue===!1?this.each(o):this.queue(s.queue,o)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return typeof e!="string"&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=e!=null&&e+"queueHooks",s=v.timers,o=v._data(this);if(n)o[n]&&o[n].stop&&i(o[n]);else for(n in o)o[n]&&o[n].stop&&Wn.test(n)&&i(o[n]);for(n=s.length;n--;)s[n].elem===this&&(e==null||s[n].queue===e)&&(s[n].anim.stop(r),t=!1,s.splice(n,1));(t||!r)&&v.dequeue(this,e)})}}),v.each({slideDown:Zn("show"),slideUp:Zn("hide"),slideToggle:Zn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){v.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),v.speed=function(e,t,n){var r=e&&typeof e=="object"?v.extend({},e):{complete:n||!n&&t||v.isFunction(e)&&e,duration:e,easing:n&&t||t&&!v.isFunction(t)&&t};r.duration=v.fx.off?0:typeof r.duration=="number"?r.duration:r.duration in v.fx.speeds?v.fx.speeds[r.duration]:v.fx.speeds._default;if(r.queue==null||r.queue===!0)r.queue="fx";return r.old=r.complete,r.complete=function(){v.isFunction(r.old)&&r.old.call(this),r.queue&&v.dequeue(this,r.queue)},r},v.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},v.timers=[],v.fx=Yn.prototype.init,v.fx.tick=function(){var e,n=v.timers,r=0;qn=v.now();for(;r<n.length;r++)e=n[r],!e()&&n[r]===e&&n.splice(r--,1);n.length||v.fx.stop(),qn=t},v.fx.timer=function(e){e()&&v.timers.push(e)&&!Rn&&(Rn=setInterval(v.fx.tick,v.fx.interval))},v.fx.interval=13,v.fx.stop=function(){clearInterval(Rn),Rn=null},v.fx.speeds={slow:600,fast:200,_default:400},v.fx.step={},v.expr&&v.expr.filters&&(v.expr.filters.animated=function(e){return v.grep(v.timers,function(t){return e===t.elem}).length});var er=/^(?:body|html)$/i;v.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){v.offset.setOffset(this,e,t)});var n,r,i,s,o,u,a,f={top:0,left:0},l=this[0],c=l&&l.ownerDocument;if(!c)return;return(r=c.body)===l?v.offset.bodyOffset(l):(n=c.documentElement,v.contains(n,l)?(typeof l.getBoundingClientRect!="undefined"&&(f=l.getBoundingClientRect()),i=tr(c),s=n.clientTop||r.clientTop||0,o=n.clientLeft||r.clientLeft||0,u=i.pageYOffset||n.scrollTop,a=i.pageXOffset||n.scrollLeft,{top:f.top+u-s,left:f.left+a-o}):f)},v.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return v.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(v.css(e,"marginTop"))||0,n+=parseFloat(v.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=v.css(e,"position");r==="static"&&(e.style.position="relative");var i=v(e),s=i.offset(),o=v.css(e,"top"),u=v.css(e,"left"),a=(r==="absolute"||r==="fixed")&&v.inArray("auto",[o,u])>-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window);
+
+/*! jQuery UI - v1.9.2 - 2012-12-26
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
+* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
+(function(e,t){function i(t,n){var r,i,o,u=t.nodeName.toLowerCase();return"area"===u?(r=t.parentNode,i=r.name,!t.href||!i||r.nodeName.toLowerCase()!=="map"?!1:(o=e("img[usemap=#"+i+"]")[0],!!o&&s(o))):(/input|select|textarea|button|object/.test(u)?!t.disabled:"a"===u?t.href||n:n)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().andSelf().filter(function(){return e.css(this,"visibility")==="hidden"}).length}var n=0,r=/^ui-id-\d+$/;e.ui=e.ui||{};if(e.ui.version)return;e.extend(e.ui,{version:"1.9.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({_focus:e.fn.focus,focus:function(t,n){return typeof t=="number"?this.each(function(){var r=this;setTimeout(function(){e(r).focus(),n&&n.call(r)},t)}):this._focus.apply(this,arguments)},scrollParent:function(){var t;return e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?t=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):t=this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(n){if(n!==t)return this.css("zIndex",n);if(this.length){var r=e(this[0]),i,s;while(r.length&&r[0]!==document){i=r.css("position");if(i==="absolute"||i==="relative"||i==="fixed"){s=parseInt(r.css("zIndex"),10);if(!isNaN(s)&&s!==0)return s}r=r.parent()}}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){r.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),r=isNaN(n);return(r||n>=0)&&i(t,!r)}}),e(function(){var t=document.body,n=t.appendChild(n=document.createElement("div"));n.offsetHeight,e.extend(n.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),e.support.minHeight=n.offsetHeight===100,e.support.selectstart="onselectstart"in n,t.removeChild(n).style.display="none"}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(n,r){function u(t,n,r,s){return e.each(i,function(){n-=parseFloat(e.css(t,"padding"+this))||0,r&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var i=r==="Width"?["Left","Right"]:["Top","Bottom"],s=r.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+r]=function(n){return n===t?o["inner"+r].call(this):this.each(function(){e(this).css(s,u(this,n)+"px")})},e.fn["outer"+r]=function(t,n){return typeof t!="number"?o["outer"+r].call(this,t):this.each(function(){e(this).css(s,u(this,t,!0,n)+"px")})}}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),function(){var t=/msie ([\w.]+)/.exec(navigator.userAgent.toLowerCase())||[];e.ui.ie=t.length?!0:!1,e.ui.ie6=parseFloat(t[1],10)===6}(),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r)s.plugins[i]=s.plugins[i]||[],s.plugins[i].push([n,r[i]])},call:function(e,t,n){var r,i=e.plugins[t];if(!i||!e.element[0].parentNode||e.element[0].parentNode.nodeType===11)return;for(r=0;r<i.length;r++)e.options[i[r][0]]&&i[r][1].apply(e.element,n)}},contains:e.contains,hasScroll:function(t,n){if(e(t).css("overflow")==="hidden")return!1;var r=n&&n==="left"?"scrollLeft":"scrollTop",i=!1;return t[r]>0?!0:(t[r]=1,i=t[r]>0,t[r]=0,i)},isOverAxis:function(e,t,n){return e>t&&e<t+n},isOver:function(t,n,r,i,s,o){return e.ui.isOverAxis(t,r,s)&&e.ui.isOverAxis(n,i,o)}})})(jQuery);(function(e,t){var n=0,r=Array.prototype.slice,i=e.cleanData;e.cleanData=function(t){for(var n=0,r;(r=t[n])!=null;n++)try{e(r).triggerHandler("remove")}catch(s){}i(t)},e.widget=function(t,n,r){var i,s,o,u,a=t.split(".")[0];t=t.split(".")[1],i=a+"-"+t,r||(r=n,n=e.Widget),e.expr[":"][i.toLowerCase()]=function(t){return!!e.data(t,i)},e[a]=e[a]||{},s=e[a][t],o=e[a][t]=function(e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)},e.extend(o,s,{version:r.version,_proto:e.extend({},r),_childConstructors:[]}),u=new n,u.options=e.widget.extend({},u.options),e.each(r,function(t,i){e.isFunction(i)&&(r[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},r=function(e){return n.prototype[t].apply(this,e)};return function(){var t=this._super,n=this._superApply,s;return this._super=e,this._superApply=r,s=i.apply(this,arguments),this._super=t,this._superApply=n,s}}())}),o.prototype=e.widget.extend(u,{widgetEventPrefix:s?u.widgetEventPrefix:t},r,{constructor:o,namespace:a,widgetName:t,widgetBaseClass:i,widgetFullName:i}),s?(e.each(s._childConstructors,function(t,n){var r=n.prototype;e.widget(r.namespace+"."+r.widgetName,o,n._proto)}),delete s._childConstructors):n._childConstructors.push(o),e.widget.bridge(t,o)},e.widget.extend=function(n){var i=r.call(arguments,1),s=0,o=i.length,u,a;for(;s<o;s++)for(u in i[s])a=i[s][u],i[s].hasOwnProperty(u)&&a!==t&&(e.isPlainObject(a)?n[u]=e.isPlainObject(n[u])?e.widget.extend({},n[u],a):e.widget.extend({},a):n[u]=a);return n},e.widget.bridge=function(n,i){var s=i.prototype.widgetFullName||n;e.fn[n]=function(o){var u=typeof o=="string",a=r.call(arguments,1),f=this;return o=!u&&a.length?e.widget.extend.apply(null,[o].concat(a)):o,u?this.each(function(){var r,i=e.data(this,s);if(!i)return e.error("cannot call methods on "+n+" prior to initialization; "+"attempted to call method '"+o+"'");if(!e.isFunction(i[o])||o.charAt(0)==="_")return e.error("no such method '"+o+"' for "+n+" widget instance");r=i[o].apply(i,a);if(r!==i&&r!==t)return f=r&&r.jquery?f.pushStack(r.get()):r,!1}):this.each(function(){var t=e.data(this,s);t?t.option(o||{})._init():e.data(this,s,new i(o,this))}),f}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetName,this),e.data(r,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===r&&this.destroy()}}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u<s.length-1;u++)o[s[u]]=o[s[u]]||{},o=o[s[u]];n=s.pop();if(r===t)return o[n]===t?null:o[n];o[n]=r}else{if(r===t)return this.options[n]===t?null:this.options[n];i[n]=r}}return this._setOptions(i),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,e==="disabled"&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(t,n,r){var i,s=this;typeof t!="boolean"&&(r=n,n=t,t=!1),r?(n=i=e(n),this.bindings=this.bindings.add(n)):(r=n,n=this.element,i=this.widget()),e.each(r,function(r,o){function u(){if(!t&&(s.options.disabled===!0||e(this).hasClass("ui-state-disabled")))return;return(typeof o=="string"?s[o]:o).apply(s,arguments)}typeof o!="string"&&(u.guid=o.guid=o.guid||u.guid||e.guid++);var a=r.match(/^(\w+)\s*(.*)$/),f=a[1]+s.eventNamespace,l=a[2];l?i.delegate(l,f,u):n.bind(f,u)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function n(){return(typeof e=="string"?r[e]:e).apply(r,arguments)}var r=this;return setTimeout(n,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,n,r){var i,s,o=this.options[t];r=r||{},n=e.Event(n),n.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),n.target=this.element[0],s=n.originalEvent;if(s)for(i in s)i in n||(n[i]=s[i]);return this.element.trigger(n,r),!(e.isFunction(o)&&o.apply(this.element[0],[n].concat(r))===!1||n.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,n){e.Widget.prototype["_"+t]=function(r,i,s){typeof i=="string"&&(i={effect:i});var o,u=i?i===!0||typeof i=="number"?n:i.effect||n:t;i=i||{},typeof i=="number"&&(i={duration:i}),o=!e.isEmptyObject(i),i.complete=s,i.delay&&r.delay(i.delay),o&&e.effects&&(e.effects.effect[u]||e.uiBackCompat!==!1&&e.effects[u])?r[t](i):u!==t&&r[u]?r[u](i.duration,i.easing,s):r.queue(function(n){e(this)[t](),s&&s.call(r[0]),n()})}}),e.uiBackCompat!==!1&&(e.Widget.prototype._getCreateOptions=function(){return e.metadata&&e.metadata.get(this.element[0])[this.widgetName]})})(jQuery);(function(e,t){var n=!1;e(document).mouseup(function(e){n=!1}),e.widget("ui.mouse",{version:"1.9.2",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(n){if(!0===e.data(n.target,t.widgetName+".preventClickEvent"))return e.removeData(n.target,t.widgetName+".preventClickEvent"),n.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(n)return;this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var r=this,i=t.which===1,s=typeof this.options.cancel=="string"&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;if(!i||s||!this._mouseCapture(t))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){r.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)){this._mouseStarted=this._mouseStart(t)!==!1;if(!this._mouseStarted)return t.preventDefault(),!0}return!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return r._mouseMove(e)},this._mouseUpDelegate=function(e){return r._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),n=!0,!0},_mouseMove:function(t){return!e.ui.ie||document.documentMode>=9||!!t.button?this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted):this._mouseUp(t)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(e){return this.mouseDelayMet},_mouseStart:function(e){},_mouseDrag:function(e){},_mouseStop:function(e){},_mouseCapture:function(e){return!0}})})(jQuery);(function(e,t){function h(e,t,n){return[parseInt(e[0],10)*(l.test(e[0])?t/100:1),parseInt(e[1],10)*(l.test(e[1])?n/100:1)]}function p(t,n){return parseInt(e.css(t,n),10)||0}e.ui=e.ui||{};var n,r=Math.max,i=Math.abs,s=Math.round,o=/left|center|right/,u=/top|center|bottom/,a=/[\+\-]\d+%?/,f=/^\w+/,l=/%$/,c=e.fn.position;e.position={scrollbarWidth:function(){if(n!==t)return n;var r,i,s=e("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return e("body").append(s),r=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,r===i&&(i=s[0].clientWidth),s.remove(),n=r-i},getScrollInfo:function(t){var n=t.isWindow?"":t.element.css("overflow-x"),r=t.isWindow?"":t.element.css("overflow-y"),i=n==="scroll"||n==="auto"&&t.width<t.element[0].scrollWidth,s=r==="scroll"||r==="auto"&&t.height<t.element[0].scrollHeight;return{width:i?e.position.scrollbarWidth():0,height:s?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var n=e(t||window),r=e.isWindow(n[0]);return{element:n,isWindow:r,offset:n.offset()||{left:0,top:0},scrollLeft:n.scrollLeft(),scrollTop:n.scrollTop(),width:r?n.width():n.outerWidth(),height:r?n.height():n.outerHeight()}}},e.fn.position=function(t){if(!t||!t.of)return c.apply(this,arguments);t=e.extend({},t);var n,l,d,v,m,g=e(t.of),y=e.position.getWithinInfo(t.within),b=e.position.getScrollInfo(y),w=g[0],E=(t.collision||"flip").split(" "),S={};return w.nodeType===9?(l=g.width(),d=g.height(),v={top:0,left:0}):e.isWindow(w)?(l=g.width(),d=g.height(),v={top:g.scrollTop(),left:g.scrollLeft()}):w.preventDefault?(t.at="left top",l=d=0,v={top:w.pageY,left:w.pageX}):(l=g.outerWidth(),d=g.outerHeight(),v=g.offset()),m=e.extend({},v),e.each(["my","at"],function(){var e=(t[this]||"").split(" "),n,r;e.length===1&&(e=o.test(e[0])?e.concat(["center"]):u.test(e[0])?["center"].concat(e):["center","center"]),e[0]=o.test(e[0])?e[0]:"center",e[1]=u.test(e[1])?e[1]:"center",n=a.exec(e[0]),r=a.exec(e[1]),S[this]=[n?n[0]:0,r?r[0]:0],t[this]=[f.exec(e[0])[0],f.exec(e[1])[0]]}),E.length===1&&(E[1]=E[0]),t.at[0]==="right"?m.left+=l:t.at[0]==="center"&&(m.left+=l/2),t.at[1]==="bottom"?m.top+=d:t.at[1]==="center"&&(m.top+=d/2),n=h(S.at,l,d),m.left+=n[0],m.top+=n[1],this.each(function(){var o,u,a=e(this),f=a.outerWidth(),c=a.outerHeight(),w=p(this,"marginLeft"),x=p(this,"marginTop"),T=f+w+p(this,"marginRight")+b.width,N=c+x+p(this,"marginBottom")+b.height,C=e.extend({},m),k=h(S.my,a.outerWidth(),a.outerHeight());t.my[0]==="right"?C.left-=f:t.my[0]==="center"&&(C.left-=f/2),t.my[1]==="bottom"?C.top-=c:t.my[1]==="center"&&(C.top-=c/2),C.left+=k[0],C.top+=k[1],e.support.offsetFractions||(C.left=s(C.left),C.top=s(C.top)),o={marginLeft:w,marginTop:x},e.each(["left","top"],function(r,i){e.ui.position[E[r]]&&e.ui.position[E[r]][i](C,{targetWidth:l,targetHeight:d,elemWidth:f,elemHeight:c,collisionPosition:o,collisionWidth:T,collisionHeight:N,offset:[n[0]+k[0],n[1]+k[1]],my:t.my,at:t.at,within:y,elem:a})}),e.fn.bgiframe&&a.bgiframe(),t.using&&(u=function(e){var n=v.left-C.left,s=n+l-f,o=v.top-C.top,u=o+d-c,h={target:{element:g,left:v.left,top:v.top,width:l,height:d},element:{element:a,left:C.left,top:C.top,width:f,height:c},horizontal:s<0?"left":n>0?"right":"center",vertical:u<0?"top":o>0?"bottom":"middle"};l<f&&i(n+s)<l&&(h.horizontal="center"),d<c&&i(o+u)<d&&(h.vertical="middle"),r(i(n),i(s))>r(i(o),i(u))?h.important="horizontal":h.important="vertical",t.using.call(this,e,h)}),a.offset(e.extend(C,{using:u}))})},e.ui.position={fit:{left:function(e,t){var n=t.within,i=n.isWindow?n.scrollLeft:n.offset.left,s=n.width,o=e.left-t.collisionPosition.marginLeft,u=i-o,a=o+t.collisionWidth-s-i,f;t.collisionWidth>s?u>0&&a<=0?(f=e.left+u+t.collisionWidth-s-i,e.left+=u-f):a>0&&u<=0?e.left=i:u>a?e.left=i+s-t.collisionWidth:e.left=i:u>0?e.left+=u:a>0?e.left-=a:e.left=r(e.left-o,e.left)},top:function(e,t){var n=t.within,i=n.isWindow?n.scrollTop:n.offset.top,s=t.within.height,o=e.top-t.collisionPosition.marginTop,u=i-o,a=o+t.collisionHeight-s-i,f;t.collisionHeight>s?u>0&&a<=0?(f=e.top+u+t.collisionHeight-s-i,e.top+=u-f):a>0&&u<=0?e.top=i:u>a?e.top=i+s-t.collisionHeight:e.top=i:u>0?e.top+=u:a>0?e.top-=a:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var n=t.within,r=n.offset.left+n.scrollLeft,s=n.width,o=n.isWindow?n.scrollLeft:n.offset.left,u=e.left-t.collisionPosition.marginLeft,a=u-o,f=u+t.collisionWidth-s-o,l=t.my[0]==="left"?-t.elemWidth:t.my[0]==="right"?t.elemWidth:0,c=t.at[0]==="left"?t.targetWidth:t.at[0]==="right"?-t.targetWidth:0,h=-2*t.offset[0],p,d;if(a<0){p=e.left+l+c+h+t.collisionWidth-s-r;if(p<0||p<i(a))e.left+=l+c+h}else if(f>0){d=e.left-t.collisionPosition.marginLeft+l+c+h-o;if(d>0||i(d)<f)e.left+=l+c+h}},top:function(e,t){var n=t.within,r=n.offset.top+n.scrollTop,s=n.height,o=n.isWindow?n.scrollTop:n.offset.top,u=e.top-t.collisionPosition.marginTop,a=u-o,f=u+t.collisionHeight-s-o,l=t.my[1]==="top",c=l?-t.elemHeight:t.my[1]==="bottom"?t.elemHeight:0,h=t.at[1]==="top"?t.targetHeight:t.at[1]==="bottom"?-t.targetHeight:0,p=-2*t.offset[1],d,v;a<0?(v=e.top+c+h+p+t.collisionHeight-s-r,e.top+c+h+p>a&&(v<0||v<i(a))&&(e.top+=c+h+p)):f>0&&(d=e.top-t.collisionPosition.marginTop+c+h+p-o,e.top+c+h+p>f&&(d>0||i(d)<f)&&(e.top+=c+h+p))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,n,r,i,s,o=document.getElementsByTagName("body")[0],u=document.createElement("div");t=document.createElement(o?"div":"body"),r={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},o&&e.extend(r,{position:"absolute",left:"-1000px",top:"-1000px"});for(s in r)t.style[s]=r[s];t.appendChild(u),n=o||document.documentElement,n.insertBefore(t,n.firstChild),u.style.cssText="position: absolute; left: 10.7432222px;",i=e(u).offset().left,e.support.offsetFractions=i>10&&i<11,t.innerHTML="",n.removeChild(t)}(),e.uiBackCompat!==!1&&function(e){var n=e.fn.position;e.fn.position=function(r){if(!r||!r.offset)return n.call(this,r);var i=r.offset.split(" "),s=r.at.split(" ");return i.length===1&&(i[1]=i[0]),/^\d/.test(i[0])&&(i[0]="+"+i[0]),/^\d/.test(i[1])&&(i[1]="+"+i[1]),s.length===1&&(/left|center|right/.test(s[0])?s[1]="center":(s[1]=s[0],s[0]="center")),n.call(this,e.extend(r,{at:s[0]+i[0]+" "+s[1]+i[1],offset:t}))}}(jQuery)})(jQuery);(function(e,t){e.widget("ui.draggable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var n=this.options;return this.helper||n.disabled||e(t.target).is(".ui-resizable-handle")?!1:(this.handle=this._getHandle(t),this.handle?(e(n.iframeFix===!0?"iframe":n.iframeFix).each(function(){e('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),n.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,n){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===!1)return this._mouseUp({}),!1;this.position=r.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";return e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n=!1;e.ui.ddmanager&&!this.options.dropBehaviour&&(n=e.ui.ddmanager.drop(this,t)),this.dropped&&(n=this.dropped,this.dropped=!1);var r=this.element[0],i=!1;while(r&&(r=r.parentNode))r==document&&(i=!0);if(!i&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!n||this.options.revert=="valid"&&n||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,n)){var s=this;e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){s._trigger("stop",t)!==!1&&s._clear()})}else this._trigger("stop",t)!==!1&&this._clear();return!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){var n=!this.options.handle||!e(this.options.handle,this.element).length?!0:!1;return e(this.options.handle,this.element).find("*").andSelf().each(function(){this==t.target&&(n=!0)}),n},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return r.parents("body").length||r.appendTo(n.appendTo=="parent"?this.element[0].parentNode:n.appendTo),r[0]!=this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))&&r.css("position","absolute"),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[t.containment=="document"?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t.containment=="document"?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(t.containment=="document"?0:e(window).scrollLeft())+e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(t.containment=="document"?0:e(window).scrollTop())+(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)&&t.containment.constructor!=Array){var n=e(t.containment),r=n[0];if(!r)return;var i=n.offset(),s=e(r).css("overflow")!="hidden";this.containment=[(parseInt(e(r).css("borderLeftWidth"),10)||0)+(parseInt(e(r).css("paddingLeft"),10)||0),(parseInt(e(r).css("borderTopWidth"),10)||0)+(parseInt(e(r).css("paddingTop"),10)||0),(s?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(e(r).css("borderLeftWidth"),10)||0)-(parseInt(e(r).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(s?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(e(r).css("borderTopWidth"),10)||0)-(parseInt(e(r).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=n}else t.containment.constructor==Array&&(this.containment=t.containment)},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName),s=t.pageX,o=t.pageY;if(this.originalPosition){var u;if(this.containment){if(this.relative_container){var a=this.relative_container.offset();u=[this.containment[0]+a.left,this.containment[1]+a.top,this.containment[2]+a.left,this.containment[3]+a.top]}else u=this.containment;t.pageX-this.offset.click.left<u[0]&&(s=u[0]+this.offset.click.left),t.pageY-this.offset.click.top<u[1]&&(o=u[1]+this.offset.click.top),t.pageX-this.offset.click.left>u[2]&&(s=u[2]+this.offset.click.left),t.pageY-this.offset.click.top>u[3]&&(o=u[3]+this.offset.click.top)}if(n.grid){var f=n.grid[1]?this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1]:this.originalPageY;o=u?f-this.offset.click.top<u[1]||f-this.offset.click.top>u[3]?f-this.offset.click.top<u[1]?f+n.grid[1]:f-n.grid[1]:f:f;var l=n.grid[0]?this.originalPageX+Math.round((s-this.originalPageX)/n.grid[0])*n.grid[0]:this.originalPageX;s=u?l-this.offset.click.left<u[0]||l-this.offset.click.left>u[2]?l-this.offset.click.left<u[0]?l+n.grid[0]:l-n.grid[0]:l:l}}return{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():i?0:r.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:r.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,n,r){return r=r||this._uiHash(),e.ui.plugin.call(this,t,[n,r]),t=="drag"&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,n,r)},plugins:{},_uiHash:function(e){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,n){var r=e(this).data("draggable"),i=r.options,s=e.extend({},n,{item:r.element});r.sortables=[],e(i.connectToSortable).each(function(){var n=e.data(this,"sortable");n&&!n.options.disabled&&(r.sortables.push({instance:n,shouldRevert:n.options.revert}),n.refreshPositions(),n._trigger("activate",t,s))})},stop:function(t,n){var r=e(this).data("draggable"),i=e.extend({},n,{item:r.element});e.each(r.sortables,function(){this.instance.isOver?(this.instance.isOver=0,r.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,r.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,i))})},drag:function(t,n){var r=e(this).data("draggable"),i=this,s=function(t){var n=this.offset.click.top,r=this.offset.click.left,i=this.positionAbs.top,s=this.positionAbs.left,o=t.height,u=t.width,a=t.top,f=t.left;return e.ui.isOver(i+n,s+r,a,f,o,u)};e.each(r.sortables,function(s){var o=!1,u=this;this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(o=!0,e.each(r.sortables,function(){return this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this!=u&&this.instance._intersectsWith(this.instance.containerCache)&&e.ui.contains(u.instance.element[0],this.instance.element[0])&&(o=!1),o})),o?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(i).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return n.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=r.offset.click.top,this.instance.offset.click.left=r.offset.click.left,this.instance.offset.parent.left-=r.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=r.offset.parent.top-this.instance.offset.parent.top,r._trigger("toSortable",t),r.dropped=this.instance.element,r.currentItem=r.element,this.instance.fromOutside=r),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),r._trigger("fromSortable",t),r.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,n){var r=e("body"),i=e(this).data("draggable").options;r.css("cursor")&&(i._cursor=r.css("cursor")),r.css("cursor",i.cursor)},stop:function(t,n){var r=e(this).data("draggable").options;r._cursor&&e("body").css("cursor",r._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,n){var r=e(n.helper),i=e(this).data("draggable").options;r.css("opacity")&&(i._opacity=r.css("opacity")),r.css("opacity",i.opacity)},stop:function(t,n){var r=e(this).data("draggable").options;r._opacity&&e(n.helper).css("opacity",r._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(t,n){var r=e(this).data("draggable");r.scrollParent[0]!=document&&r.scrollParent[0].tagName!="HTML"&&(r.overflowOffset=r.scrollParent.offset())},drag:function(t,n){var r=e(this).data("draggable"),i=r.options,s=!1;if(r.scrollParent[0]!=document&&r.scrollParent[0].tagName!="HTML"){if(!i.axis||i.axis!="x")r.overflowOffset.top+r.scrollParent[0].offsetHeight-t.pageY<i.scrollSensitivity?r.scrollParent[0].scrollTop=s=r.scrollParent[0].scrollTop+i.scrollSpeed:t.pageY-r.overflowOffset.top<i.scrollSensitivity&&(r.scrollParent[0].scrollTop=s=r.scrollParent[0].scrollTop-i.scrollSpeed);if(!i.axis||i.axis!="y")r.overflowOffset.left+r.scrollParent[0].offsetWidth-t.pageX<i.scrollSensitivity?r.scrollParent[0].scrollLeft=s=r.scrollParent[0].scrollLeft+i.scrollSpeed:t.pageX-r.overflowOffset.left<i.scrollSensitivity&&(r.scrollParent[0].scrollLeft=s=r.scrollParent[0].scrollLeft-i.scrollSpeed)}else{if(!i.axis||i.axis!="x")t.pageY-e(document).scrollTop()<i.scrollSensitivity?s=e(document).scrollTop(e(document).scrollTop()-i.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<i.scrollSensitivity&&(s=e(document).scrollTop(e(document).scrollTop()+i.scrollSpeed));if(!i.axis||i.axis!="y")t.pageX-e(document).scrollLeft()<i.scrollSensitivity?s=e(document).scrollLeft(e(document).scrollLeft()-i.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<i.scrollSensitivity&&(s=e(document).scrollLeft(e(document).scrollLeft()+i.scrollSpeed))}s!==!1&&e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(r,t)}}),e.ui.plugin.add("draggable","snap",{start:function(t,n){var r=e(this).data("draggable"),i=r.options;r.snapElements=[],e(i.snap.constructor!=String?i.snap.items||":data(draggable)":i.snap).each(function(){var t=e(this),n=t.offset();this!=r.element[0]&&r.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:n.top,left:n.left})})},drag:function(t,n){var r=e(this).data("draggable"),i=r.options,s=i.snapTolerance,o=n.offset.left,u=o+r.helperProportions.width,a=n.offset.top,f=a+r.helperProportions.height;for(var l=r.snapElements.length-1;l>=0;l--){var c=r.snapElements[l].left,h=c+r.snapElements[l].width,p=r.snapElements[l].top,d=p+r.snapElements[l].height;if(!(c-s<o&&o<h+s&&p-s<a&&a<d+s||c-s<o&&o<h+s&&p-s<f&&f<d+s||c-s<u&&u<h+s&&p-s<a&&a<d+s||c-s<u&&u<h+s&&p-s<f&&f<d+s)){r.snapElements[l].snapping&&r.options.snap.release&&r.options.snap.release.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[l].item})),r.snapElements[l].snapping=!1;continue}if(i.snapMode!="inner"){var v=Math.abs(p-f)<=s,m=Math.abs(d-a)<=s,g=Math.abs(c-u)<=s,y=Math.abs(h-o)<=s;v&&(n.position.top=r._convertPositionTo("relative",{top:p-r.helperProportions.height,left:0}).top-r.margins.top),m&&(n.position.top=r._convertPositionTo("relative",{top:d,left:0}).top-r.margins.top),g&&(n.position.left=r._convertPositionTo("relative",{top:0,left:c-r.helperProportions.width}).left-r.margins.left),y&&(n.position.left=r._convertPositionTo("relative",{top:0,left:h}).left-r.margins.left)}var b=v||m||g||y;if(i.snapMode!="outer"){var v=Math.abs(p-a)<=s,m=Math.abs(d-f)<=s,g=Math.abs(c-o)<=s,y=Math.abs(h-u)<=s;v&&(n.position.top=r._convertPositionTo("relative",{top:p,left:0}).top-r.margins.top),m&&(n.position.top=r._convertPositionTo("relative",{top:d-r.helperProportions.height,left:0}).top-r.margins.top),g&&(n.position.left=r._convertPositionTo("relative",{top:0,left:c}).left-r.margins.left),y&&(n.position.left=r._convertPositionTo("relative",{top:0,left:h-r.helperProportions.width}).left-r.margins.left)}!r.snapElements[l].snapping&&(v||m||g||y||b)&&r.options.snap.snap&&r.options.snap.snap.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[l].item})),r.snapElements[l].snapping=v||m||g||y||b}}}),e.ui.plugin.add("draggable","stack",{start:function(t,n){var r=e(this).data("draggable").options,i=e.makeArray(e(r.stack)).sort(function(t,n){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(n).css("zIndex"),10)||0)});if(!i.length)return;var s=parseInt(i[0].style.zIndex)||0;e(i).each(function(e){this.style.zIndex=s+e}),this[0].style.zIndex=s+i.length}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,n){var r=e(n.helper),i=e(this).data("draggable").options;r.css("zIndex")&&(i._zIndex=r.css("zIndex")),r.css("zIndex",i.zIndex)},stop:function(t,n){var r=e(this).data("draggable").options;r._zIndex&&e(n.helper).css("zIndex",r._zIndex)}})})(jQuery);(function(e,t){e.widget("ui.droppable",{version:"1.9.2",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var t=this.options,n=t.accept;this.isover=0,this.isout=1,this.accept=e.isFunction(n)?n:function(e){return e.is(n)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},e.ui.ddmanager.droppables[t.scope]=e.ui.ddmanager.droppables[t.scope]||[],e.ui.ddmanager.droppables[t.scope].push(this),t.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){var t=e.ui.ddmanager.droppables[this.options.scope];for(var n=0;n<t.length;n++)t[n]==this&&t.splice(n,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,n){t=="accept"&&(this.accept=e.isFunction(n)?n:function(e){return e.is(n)}),e.Widget.prototype._setOption.apply(this,arguments)},_activate:function(t){var n=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),n&&this._trigger("activate",t,this.ui(n))},_deactivate:function(t){var n=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),n&&this._trigger("deactivate",t,this.ui(n))},_over:function(t){var n=e.ui.ddmanager.current;if(!n||(n.currentItem||n.element)[0]==this.element[0])return;this.accept.call(this.element[0],n.currentItem||n.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(n)))},_out:function(t){var n=e.ui.ddmanager.current;if(!n||(n.currentItem||n.element)[0]==this.element[0])return;this.accept.call(this.element[0],n.currentItem||n.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(n)))},_drop:function(t,n){var r=n||e.ui.ddmanager.current;if(!r||(r.currentItem||r.element)[0]==this.element[0])return!1;var i=!1;return this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var t=e.data(this,"droppable");if(t.options.greedy&&!t.options.disabled&&t.options.scope==r.options.scope&&t.accept.call(t.element[0],r.currentItem||r.element)&&e.ui.intersect(r,e.extend(t,{offset:t.element.offset()}),t.options.tolerance))return i=!0,!1}),i?!1:this.accept.call(this.element[0],r.currentItem||r.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(r)),this.element):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(t,n,r){if(!n.offset)return!1;var i=(t.positionAbs||t.position.absolute).left,s=i+t.helperProportions.width,o=(t.positionAbs||t.position.absolute).top,u=o+t.helperProportions.height,a=n.offset.left,f=a+n.proportions.width,l=n.offset.top,c=l+n.proportions.height;switch(r){case"fit":return a<=i&&s<=f&&l<=o&&u<=c;case"intersect":return a<i+t.helperProportions.width/2&&s-t.helperProportions.width/2<f&&l<o+t.helperProportions.height/2&&u-t.helperProportions.height/2<c;case"pointer":var h=(t.positionAbs||t.position.absolute).left+(t.clickOffset||t.offset.click).left,p=(t.positionAbs||t.position.absolute).top+(t.clickOffset||t.offset.click).top,d=e.ui.isOver(p,h,l,a,n.proportions.height,n.proportions.width);return d;case"touch":return(o>=l&&o<=c||u>=l&&u<=c||o<l&&u>c)&&(i>=a&&i<=f||s>=a&&s<=f||i<a&&s>f);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,n){var r=e.ui.ddmanager.droppables[t.options.scope]||[],i=n?n.type:null,s=(t.currentItem||t.element).find(":data(droppable)").andSelf();e:for(var o=0;o<r.length;o++){if(r[o].options.disabled||t&&!r[o].accept.call(r[o].element[0],t.currentItem||t.element))continue;for(var u=0;u<s.length;u++)if(s[u]==r[o].element[0]){r[o].proportions.height=0;continue e}r[o].visible=r[o].element.css("display")!="none";if(!r[o].visible)continue;i=="mousedown"&&r[o]._activate.call(r[o],n),r[o].offset=r[o].element.offset(),r[o].proportions={width:r[o].element[0].offsetWidth,height:r[o].element[0].offsetHeight}}},drop:function(t,n){var r=!1;return e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options)return;!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance)&&(r=this._drop.call(this,n)||r),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,n))}),r},dragStart:function(t,n){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,n)})},drag:function(t,n){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,n),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(this.options.disabled||this.greedyChild||!this.visible)return;var r=e.ui.intersect(t,this,this.options.tolerance),i=!r&&this.isover==1?"isout":r&&this.isover==0?"isover":null;if(!i)return;var s;if(this.options.greedy){var o=this.options.scope,u=this.element.parents(":data(droppable)").filter(function(){return e.data(this,"droppable").options.scope===o});u.length&&(s=e.data(u[0],"droppable"),s.greedyChild=i=="isover"?1:0)}s&&i=="isover"&&(s.isover=0,s.isout=1,s._out.call(s,n)),this[i]=1,this[i=="isout"?"isover":"isout"]=0,this[i=="isover"?"_over":"_out"].call(this,n),s&&i=="isout"&&(s.isout=0,s.isover=1,s._over.call(s,n))})},dragStop:function(t,n){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,n)}}})(jQuery);(function(e,t){e.widget("ui.resizable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var t=this,n=this.options;this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!n.aspectRatio,aspectRatio:n.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:n.helper||n.ghost||n.animate?n.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=n.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var r=this.handles.split(",");this.handles={};for(var i=0;i<r.length;i++){var s=e.trim(r[i]),o="ui-resizable-"+s,u=e('<div class="ui-resizable-handle '+o+'"></div>');u.css({zIndex:n.zIndex}),"se"==s&&u.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(u)}}this._renderAxis=function(t){t=t||this.element;for(var n in this.handles){this.handles[n].constructor==String&&(this.handles[n]=e(this.handles[n],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var r=e(this.handles[n],this.element),i=0;i=/sw|ne|nw|se|n|s/.test(n)?r.outerHeight():r.outerWidth();var s=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");t.css(s,i),this._proportionallyResize()}if(!e(this.handles[n]).length)continue}},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!t.resizing){if(this.className)var e=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);t.axis=e&&e[1]?e[1]:"se"}}),n.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(n.disabled)return;e(this).removeClass("ui-resizable-autohide"),t._handles.show()}).mouseleave(function(){if(n.disabled)return;t.resizing||(e(this).addClass("ui-resizable-autohide"),t._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){t(this.element);var n=this.element;this.originalElement.css({position:n.css("position"),width:n.outerWidth(),height:n.outerHeight(),top:n.css("top"),left:n.css("left")}).insertAfter(n),n.remove()}return this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_mouseCapture:function(t){var n=!1;for(var r in this.handles)e(this.handles[r])[0]==t.target&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(t){var r=this.options,i=this.element.position(),s=this.element;this.resizing=!0,this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()},(s.is(".ui-draggable")||/absolute/.test(s.css("position")))&&s.css({position:"absolute",top:i.top,left:i.left}),this._renderProxy();var o=n(this.helper.css("left")),u=n(this.helper.css("top"));r.containment&&(o+=e(r.containment).scrollLeft()||0,u+=e(r.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:o,top:u},this.size=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalSize=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalPosition={left:o,top:u},this.sizeDiff={width:s.outerWidth()-s.width(),height:s.outerHeight()-s.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio=typeof r.aspectRatio=="number"?r.aspectRatio:this.originalSize.width/this.originalSize.height||1;var a=e(".ui-resizable-"+this.axis).css("cursor");return e("body").css("cursor",a=="auto"?this.axis+"-resize":a),s.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(e){var t=this.helper,n=this.options,r={},i=this,s=this.originalMousePosition,o=this.axis,u=e.pageX-s.left||0,a=e.pageY-s.top||0,f=this._change[o];if(!f)return!1;var l=f.apply(this,[e,u,a]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey)l=this._updateRatio(l,e);return l=this._respectSize(l,e),this._propagate("resize",e),t.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",e,this.ui()),!1},_mouseStop:function(t){this.resizing=!1;var n=this.options,r=this;if(this._helper){var i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&e.ui.hasScroll(i[0],"left")?0:r.sizeDiff.height,u=s?0:r.sizeDiff.width,a={width:r.helper.width()-u,height:r.helper.height()-o},f=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,l=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;n.animate||this.element.css(e.extend(a,{top:l,left:f})),r.helper.height(r.size.height),r.helper.width(r.size.width),this._helper&&!n.animate&&this._proportionallyResize()}return e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t=this.options,n,i,s,o,u;u={minWidth:r(t.minWidth)?t.minWidth:0,maxWidth:r(t.maxWidth)?t.maxWidth:Infinity,minHeight:r(t.minHeight)?t.minHeight:0,maxHeight:r(t.maxHeight)?t.maxHeight:Infinity};if(this._aspectRatio||e)n=u.minHeight*this.aspectRatio,s=u.minWidth/this.aspectRatio,i=u.maxHeight*this.aspectRatio,o=u.maxWidth/this.aspectRatio,n>u.minWidth&&(u.minWidth=n),s>u.minHeight&&(u.minHeight=s),i<u.maxWidth&&(u.maxWidth=i),o<u.maxHeight&&(u.maxHeight=o);this._vBoundaries=u},_updateCache:function(e){var t=this.options;this.offset=this.helper.offset(),r(e.left)&&(this.position.left=e.left),r(e.top)&&(this.position.top=e.top),r(e.height)&&(this.size.height=e.height),r(e.width)&&(this.size.width=e.width)},_updateRatio:function(e,t){var n=this.options,i=this.position,s=this.size,o=this.axis;return r(e.height)?e.width=e.height*this.aspectRatio:r(e.width)&&(e.height=e.width/this.aspectRatio),o=="sw"&&(e.left=i.left+(s.width-e.width),e.top=null),o=="nw"&&(e.top=i.top+(s.height-e.height),e.left=i.left+(s.width-e.width)),e},_respectSize:function(e,t){var n=this.helper,i=this._vBoundaries,s=this._aspectRatio||t.shiftKey,o=this.axis,u=r(e.width)&&i.maxWidth&&i.maxWidth<e.width,a=r(e.height)&&i.maxHeight&&i.maxHeight<e.height,f=r(e.width)&&i.minWidth&&i.minWidth>e.width,l=r(e.height)&&i.minHeight&&i.minHeight>e.height;f&&(e.width=i.minWidth),l&&(e.height=i.minHeight),u&&(e.width=i.maxWidth),a&&(e.height=i.maxHeight);var c=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,p=/sw|nw|w/.test(o),d=/nw|ne|n/.test(o);f&&p&&(e.left=c-i.minWidth),u&&p&&(e.left=c-i.maxWidth),l&&d&&(e.top=h-i.minHeight),a&&d&&(e.top=h-i.maxHeight);var v=!e.width&&!e.height;return v&&!e.left&&e.top?e.top=null:v&&!e.top&&e.left&&(e.left=null),e},_proportionallyResize:function(){var t=this.options;if(!this._proportionallyResizeElements.length)return;var n=this.helper||this.element;for(var r=0;r<this._proportionallyResizeElements.length;r++){var i=this._proportionallyResizeElements[r];if(!this.borderDif){var s=[i.css("borderTopWidth"),i.css("borderRightWidth"),i.css("borderBottomWidth"),i.css("borderLeftWidth")],o=[i.css("paddingTop"),i.css("paddingRight"),i.css("paddingBottom"),i.css("paddingLeft")];this.borderDif=e.map(s,function(e,t){var n=parseInt(e,10)||0,r=parseInt(o[t],10)||0;return n+r})}i.css({height:n.height()-this.borderDif[0]-this.borderDif[2]||0,width:n.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var t=this.element,n=this.options;this.elementOffset=t.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var r=e.ui.ie6?1:0,i=e.ui.ie6?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+i,height:this.element.outerHeight()+i,position:"absolute",left:this.elementOffset.left-r+"px",top:this.elementOffset.top-r+"px",zIndex:++n.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(e,t,n){return{width:this.originalSize.width+t}},w:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{top:s.top+n,height:i.height-n}},s:function(e,t,n){return{height:this.originalSize.height+n}},se:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},sw:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,n,r]))},ne:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},nw:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,n,r]))}},_propagate:function(t,n){e.ui.plugin.call(this,t,[n,this.ui()]),t!="resize"&&this._trigger(t,n,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","alsoResize",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=function(t){e(t).each(function(){var t=e(this);t.data("resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};typeof i.alsoResize=="object"&&!i.alsoResize.parentNode?i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)}):s(i.alsoResize)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.originalSize,o=r.originalPosition,u={height:r.size.height-s.height||0,width:r.size.width-s.width||0,top:r.position.top-o.top||0,left:r.position.left-o.left||0},a=function(t,r){e(t).each(function(){var t=e(this),i=e(this).data("resizable-alsoresize"),s={},o=r&&r.length?r:t.parents(n.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var n=(i[t]||0)+(u[t]||0);n&&n>=0&&(s[t]=n||null)}),t.css(s)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?e.each(i.alsoResize,function(e,t){a(e,t)}):a(i.alsoResize)},stop:function(t,n){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","animate",{stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r._proportionallyResizeElements,o=s.length&&/textarea/i.test(s[0].nodeName),u=o&&e.ui.hasScroll(s[0],"left")?0:r.sizeDiff.height,a=o?0:r.sizeDiff.width,f={width:r.size.width-a,height:r.size.height-u},l=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,c=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;r.element.animate(e.extend(f,c&&l?{top:c,left:l}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var n={width:parseInt(r.element.css("width"),10),height:parseInt(r.element.css("height"),10),top:parseInt(r.element.css("top"),10),left:parseInt(r.element.css("left"),10)};s&&s.length&&e(s[0]).css({width:n.width,height:n.height}),r._updateCache(n),r._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(t,r){var i=e(this).data("resizable"),s=i.options,o=i.element,u=s.containment,a=u instanceof e?u.get(0):/parent/.test(u)?o.parent().get(0):u;if(!a)return;i.containerElement=e(a);if(/document/.test(u)||u==document)i.containerOffset={left:0,top:0},i.containerPosition={left:0,top:0},i.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight};else{var f=e(a),l=[];e(["Top","Right","Left","Bottom"]).each(function(e,t){l[e]=n(f.css("padding"+t))}),i.containerOffset=f.offset(),i.containerPosition=f.position(),i.containerSize={height:f.innerHeight()-l[3],width:f.innerWidth()-l[1]};var c=i.containerOffset,h=i.containerSize.height,p=i.containerSize.width,d=e.ui.hasScroll(a,"left")?a.scrollWidth:p,v=e.ui.hasScroll(a)?a.scrollHeight:h;i.parentData={element:a,left:c.left,top:c.top,width:d,height:v}}},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.containerSize,o=r.containerOffset,u=r.size,a=r.position,f=r._aspectRatio||t.shiftKey,l={top:0,left:0},c=r.containerElement;c[0]!=document&&/static/.test(c.css("position"))&&(l=o),a.left<(r._helper?o.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-o.left:r.position.left-l.left),f&&(r.size.height=r.size.width/r.aspectRatio),r.position.left=i.helper?o.left:0),a.top<(r._helper?o.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-o.top:r.position.top),f&&(r.size.width=r.size.height*r.aspectRatio),r.position.top=r._helper?o.top:0),r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top;var h=Math.abs((r._helper?r.offset.left-l.left:r.offset.left-l.left)+r.sizeDiff.width),p=Math.abs((r._helper?r.offset.top-l.top:r.offset.top-o.top)+r.sizeDiff.height),d=r.containerElement.get(0)==r.element.parent().get(0),v=/relative|absolute/.test(r.containerElement.css("position"));d&&v&&(h-=r.parentData.left),h+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-h,f&&(r.size.height=r.size.width/r.aspectRatio)),p+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-p,f&&(r.size.width=r.size.height*r.aspectRatio))},stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.position,o=r.containerOffset,u=r.containerPosition,a=r.containerElement,f=e(r.helper),l=f.offset(),c=f.outerWidth()-r.sizeDiff.width,h=f.outerHeight()-r.sizeDiff.height;r._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h}),r._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h})}}),e.ui.plugin.add("resizable","ghost",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size;r.ghost=r.originalElement.clone(),r.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:""),r.ghost.appendTo(r.helper)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.ghost.css({position:"relative",height:r.size.height,width:r.size.width})},stop:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.helper&&r.helper.get(0).removeChild(r.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size,o=r.originalSize,u=r.originalPosition,a=r.axis,f=i._aspectRatio||t.shiftKey;i.grid=typeof i.grid=="number"?[i.grid,i.grid]:i.grid;var l=Math.round((s.width-o.width)/(i.grid[0]||1))*(i.grid[0]||1),c=Math.round((s.height-o.height)/(i.grid[1]||1))*(i.grid[1]||1);/^(se|s|e)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c):/^(ne)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c):/^(sw)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.left=u.left-l):(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c,r.position.left=u.left-l)}});var n=function(e){return parseInt(e,10)||0},r=function(e){return!isNaN(parseInt(e,10))}})(jQuery);(function(e,t){e.widget("ui.selectable",e.ui.mouse,{version:"1.9.2",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var t=this;this.element.addClass("ui-selectable"),this.dragged=!1;var n;this.refresh=function(){n=e(t.options.filter,t.element[0]),n.addClass("ui-selectee"),n.each(function(){var t=e(this),n=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:n.left,top:n.top,right:n.left+t.outerWidth(),bottom:n.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=n.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;var r=this.options;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.clientX,top:t.clientY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().andSelf().each(function(){var r=e.data(this,"selectable-item");if(r){var i=!t.metaKey&&!t.ctrlKey||!r.$element.hasClass("ui-selected");return r.$element.removeClass(i?"ui-unselecting":"ui-selected").addClass(i?"ui-selecting":"ui-unselecting"),r.unselecting=!i,r.selecting=i,r.selected=i,i?n._trigger("selecting",t,{selecting:r.element}):n._trigger("unselecting",t,{unselecting:r.element}),!1}})},_mouseDrag:function(t){var n=this;this.dragged=!0;if(this.options.disabled)return;var r=this.options,i=this.opos[0],s=this.opos[1],o=t.pageX,u=t.pageY;if(i>o){var a=o;o=i,i=a}if(s>u){var a=u;u=s,s=a}return this.helper.css({left:i,top:s,width:o-i,height:u-s}),this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!a||a.element==n.element[0])return;var f=!1;r.tolerance=="touch"?f=!(a.left>o||a.right<i||a.top>u||a.bottom<s):r.tolerance=="fit"&&(f=a.left>i&&a.right<o&&a.top>s&&a.bottom<u),f?(a.selected&&(a.$element.removeClass("ui-selected"),a.selected=!1),a.unselecting&&(a.$element.removeClass("ui-unselecting"),a.unselecting=!1),a.selecting||(a.$element.addClass("ui-selecting"),a.selecting=!0,n._trigger("selecting",t,{selecting:a.element}))):(a.selecting&&((t.metaKey||t.ctrlKey)&&a.startselected?(a.$element.removeClass("ui-selecting"),a.selecting=!1,a.$element.addClass("ui-selected"),a.selected=!0):(a.$element.removeClass("ui-selecting"),a.selecting=!1,a.startselected&&(a.$element.addClass("ui-unselecting"),a.unselecting=!0),n._trigger("unselecting",t,{unselecting:a.element}))),a.selected&&!t.metaKey&&!t.ctrlKey&&!a.startselected&&(a.$element.removeClass("ui-selected"),a.selected=!1,a.$element.addClass("ui-unselecting"),a.unselecting=!0,n._trigger("unselecting",t,{unselecting:a.element})))}),!1},_mouseStop:function(t){var n=this;this.dragged=!1;var r=this.options;return e(".ui-unselecting",this.element[0]).each(function(){var r=e.data(this,"selectable-item");r.$element.removeClass("ui-unselecting"),r.unselecting=!1,r.startselected=!1,n._trigger("unselected",t,{unselected:r.element})}),e(".ui-selecting",this.element[0]).each(function(){var r=e.data(this,"selectable-item");r.$element.removeClass("ui-selecting").addClass("ui-selected"),r.selecting=!1,r.selected=!0,r.startselected=!0,n._trigger("selected",t,{selected:r.element})}),this._trigger("stop",t),this.helper.remove(),!1}})})(jQuery);(function(e,t){e.widget("ui.sortable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(t);var i=null,s=e(t.target).parents().each(function(){if(e.data(this,r.widgetName+"-item")==r)return i=e(this),!1});e.data(t.target,r.widgetName+"-item")==r&&(i=e(t.target));if(!i)return!1;if(this.options.handle&&!n){var o=!1;e(this.options.handle,i).find("*").andSelf().each(function(){this==t.target&&(o=!0)});if(!o)return!1}return this.currentItem=i,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),i.containment&&this._setContainment(),i.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",i.cursor)),i.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",i.opacity)),i.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",i.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(var s=this.containers.length-1;s>=0;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var n=this.options,r=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<n.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+n.scrollSpeed:t.pageY-this.overflowOffset.top<n.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-n.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<n.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+n.scrollSpeed:t.pageX-this.overflowOffset.left<n.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-n.scrollSpeed)):(t.pageY-e(document).scrollTop()<n.scrollSensitivity?r=e(document).scrollTop(e(document).scrollTop()-n.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<n.scrollSensitivity&&(r=e(document).scrollTop(e(document).scrollTop()+n.scrollSpeed)),t.pageX-e(document).scrollLeft()<n.scrollSensitivity?r=e(document).scrollLeft(e(document).scrollLeft()-n.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<n.scrollSensitivity&&(r=e(document).scrollLeft(e(document).scrollLeft()+n.scrollSpeed))),r!==!1&&e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var i=this.items.length-1;i>=0;i--){var s=this.items[i],o=s.item[0],u=this._intersectsWithPointer(s);if(!u)continue;if(s.instance!==this.currentContainer)continue;if(o!=this.currentItem[0]&&this.placeholder[u==1?"next":"prev"]()[0]!=o&&!e.contains(this.placeholder[0],o)&&(this.options.type=="semi-dynamic"?!e.contains(this.element[0],o):!0)){this.direction=u==1?"down":"up";if(this.options.tolerance!="pointer"&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+f<a&&t+l>s&&t+l<o;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?c:s<t+this.helperProportions.width/2&&n-this.helperProportions.width/2<o&&u<r+this.helperProportions.height/2&&i-this.helperProportions.height/2<a},_intersectsWithPointer:function(t){var n=this.options.axis==="x"||e.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),r=this.options.axis==="y"||e.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),i=n&&r,s=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return i?this.floating?o&&o=="right"||s=="down"?2:1:s&&(s=="down"?2:1):!1},_intersectsWithSides:function(t){var n=e.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),r=e.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),i=this._getDragVerticalDirection(),s=this._getDragHorizontalDirection();return this.floating&&s?s=="right"&&r||s=="left"&&!r:i&&(i=="down"&&n||i=="up"&&!n)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return e!=0&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!=0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor==String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n=[],r=[],i=this._connectWith();if(i&&t)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&r.push([e.isFunction(a.options.items)?a.options.items.call(a.element):e(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a])}}r.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var s=r.length-1;s>=0;s--)r[s][0].each(function(){n.push(this)});return e(n)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var n=0;n<t.length;n++)if(t[n]==e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var n=this.items,r=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],i=this._connectWith();if(i&&this.ready)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&(r.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a))}}for(var s=r.length-1;s>=0;s--){var f=r[s][1],l=r[s][0];for(var u=0,c=l.length;u<c;u++){var h=e(l[u]);h.data(this.widgetName+"-item",f),n.push({item:h,instance:f,width:0,height:0,left:0,top:0})}}},refreshPositions:function(t){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var n=this.items.length-1;n>=0;n--){var r=this.items[n];if(r.instance!=this.currentContainer&&this.currentContainer&&r.item[0]!=this.currentItem[0])continue;var i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item;t||(r.width=i.outerWidth(),r.height=i.outerHeight());var s=i.offset();r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var n=this.containers.length-1;n>=0;n--){var s=this.containers[n].element.offset();this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight()}return this},_createPlaceholder:function(t){t=t||this;var n=t.options;if(!n.placeholder||n.placeholder.constructor==String){var r=n.placeholder;n.placeholder={element:function(){var n=e(document.createElement(t.currentItem[0].nodeName)).addClass(r||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return r||(n.style.visibility="hidden"),n},update:function(e,i){if(r&&!n.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}}}t.placeholder=e(n.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),n.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n=null,r=null;for(var i=this.containers.length-1;i>=0;i--){if(e.contains(this.currentItem[0],this.containers[i].element[0]))continue;if(this._intersectsWith(this.containers[i].containerCache)){if(n&&e.contains(this.containers[i].element[0],n.element[0]))continue;n=this.containers[i],r=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0)}if(!n)return;if(this.containers.length===1)this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1;else{var s=1e4,o=null,u=this.containers[r].floating?"left":"top",a=this.containers[r].floating?"width":"height",f=this.positionAbs[u]+this.offset.click[u];for(var l=this.items.length-1;l>=0;l--){if(!e.contains(this.containers[r].element[0],this.items[l].item[0]))continue;if(this.items[l].item[0]==this.currentItem[0])continue;var c=this.items[l].item.offset()[u],h=!1;Math.abs(c-f)>Math.abs(c+this.items[l][a]-f)&&(h=!0,c+=this.items[l][a]),Math.abs(c-f)<s&&(s=Math.abs(c-f),o=this.items[l],this.direction=h?"up":"down")}if(!o&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[r],o?this._rearrange(t,o,null,!0):this._rearrange(t,null,this.containers[r].element,!0),this._trigger("change",t,this._uiHash()),this.containers[r]._trigger("change",t,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1}},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t,this.currentItem])):n.helper=="clone"?this.currentItem.clone():this.currentItem;return r.parents("body").length||e(n.appendTo!="parent"?n.appendTo:this.currentItem[0].parentNode)[0].appendChild(r[0]),r[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(r[0].style.width==""||n.forceHelperSize)&&r.width(this.currentItem.width()),(r[0].style.height==""||n.forceHelperSize)&&r.height(this.currentItem.height()),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)){var n=e(t.containment)[0],r=e(t.containment).offset(),i=e(n).css("overflow")!="hidden";this.containment=[r.left+(parseInt(e(n).css("borderLeftWidth"),10)||0)+(parseInt(e(n).css("paddingLeft"),10)||0)-this.margins.left,r.top+(parseInt(e(n).css("borderTopWidth"),10)||0)+(parseInt(e(n).css("paddingTop"),10)||0)-this.margins.top,r.left+(i?Math.max(n.scrollWidth,n.offsetWidth):n.offsetWidth)-(parseInt(e(n).css("borderLeftWidth"),10)||0)-(parseInt(e(n).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,r.top+(i?Math.max(n.scrollHeight,n.offsetHeight):n.offsetHeight)-(parseInt(e(n).css("borderTopWidth"),10)||0)-(parseInt(e(n).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var s=t.pageX,o=t.pageY;if(this.originalPosition){this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(s=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(o=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top));if(n.grid){var u=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1];o=this.containment?u-this.offset.click.top<this.containment[1]||u-this.offset.click.top>this.containment[3]?u-this.offset.click.top<this.containment[1]?u+n.grid[1]:u-n.grid[1]:u:u;var a=this.originalPageX+Math.round((s-this.originalPageX)/n.grid[0])*n.grid[0];s=this.containment?a-this.offset.click.left<this.containment[0]||a-this.offset.click.left>this.containment[2]?a-this.offset.click.left<this.containment[0]?a+n.grid[0]:a-n.grid[0]:a:a}}return{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():i?0:r.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:r.scrollLeft())}},_rearrange:function(e,t,n,r){n?n[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var i=this.counter;this._delay(function(){i==this.counter&&this.refreshPositions(!r)})},_clear:function(t,n){this.reverting=!1;var r=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var i in this._storedCSS)if(this._storedCSS[i]=="auto"||this._storedCSS[i]=="static")this._storedCSS[i]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!n&&r.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!n&&r.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(n||(r.push(function(e){this._trigger("remove",e,this._uiHash())}),r.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),r.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer))));for(var i=this.containers.length-1;i>=0;i--)n||r.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(r.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(var i=0;i<r.length;i++)r[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}n||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!n){for(var i=0;i<r.length;i++)r[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var n=t||this;return{helper:n.helper,placeholder:n.placeholder||e([]),position:n.position,originalPosition:n.originalPosition,offset:n.positionAbs,item:n.currentItem,sender:t?t.element:null}}})})(jQuery);(function(e,t){var n=0,r={},i={};r.height=r.paddingTop=r.paddingBottom=r.borderTopWidth=r.borderBottomWidth="hide",i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="show",e.widget("ui.accordion",{version:"1.9.2",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var t=this.accordionId="ui-accordion-"+(this.element.attr("id")||++n),r=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset"),this.headers=this.element.find(r.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this._hoverable(this.headers),this._focusable(this.headers),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").hide(),!r.collapsible&&(r.active===!1||r.active==null)&&(r.active=0),r.active<0&&(r.active+=this.headers.length),this.active=this._findActive(r.active).addClass("ui-accordion-header-active ui-state-active").toggleClass("ui-corner-all ui-corner-top"),this.active.next().addClass("ui-accordion-content-active").show(),this._createIcons(),this.refresh(),this.element.attr("role","tablist"),this.headers.attr("role","tab").each(function(n){var r=e(this),i=r.attr("id"),s=r.next(),o=s.attr("id");i||(i=t+"-header-"+n,r.attr("id",i)),o||(o=t+"-panel-"+n,s.attr("id",o)),r.attr("aria-controls",o),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._on(this.headers,{keydown:"_keydown"}),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._setupEvents(r.event)},_getCreateEventData:function(){return{header:this.active,content:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("<span>").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this.options.heightStyle!=="content"&&e.css("height","")},_setOption:function(e,t){if(e==="active"){this._activate(t);return}e==="event"&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),e==="collapsible"&&!t&&this.options.active===!1&&this._activate(0),e==="icons"&&(this._destroyIcons(),t&&this._createIcons()),e==="disabled"&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)},_keydown:function(t){if(t.altKey||t.ctrlKey)return;var n=e.ui.keyCode,r=this.headers.length,i=this.headers.index(t.target),s=!1;switch(t.keyCode){case n.RIGHT:case n.DOWN:s=this.headers[(i+1)%r];break;case n.LEFT:case n.UP:s=this.headers[(i-1+r)%r];break;case n.SPACE:case n.ENTER:this._eventHandler(t);break;case n.HOME:s=this.headers[0];break;case n.END:s=this.headers[r-1]}s&&(e(t.target).attr("tabIndex",-1),e(s).attr("tabIndex",0),s.focus(),t.preventDefault())},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t,n,r=this.options.heightStyle,i=this.element.parent();r==="fill"?(e.support.minHeight||(n=i.css("overflow"),i.css("overflow","hidden")),t=i.height(),this.element.siblings(":visible").each(function(){var n=e(this),r=n.css("position");if(r==="absolute"||r==="fixed")return;t-=n.outerHeight(!0)}),n&&i.css("overflow",n),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):r==="auto"&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var n=this._findActive(t)[0];if(n===this.active[0])return;n=n||this.active[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return typeof t=="number"?this.headers.eq(t):e()},_setupEvents:function(t){var n={};if(!t)return;e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._on(this.headers,n)},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i[0]===r[0],o=s&&n.collapsible,u=o?e():i.next(),a=r.next(),f={oldHeader:r,oldPanel:a,newHeader:o?e():i,newPanel:u};t.preventDefault();if(s&&!n.collapsible||this._trigger("beforeActivate",t,f)===!1)return;n.active=o?!1:this.headers.index(i),this.active=s?e():i,this._toggle(f),r.removeClass("ui-accordion-header-active ui-state-active"),n.icons&&r.children(".ui-accordion-header-icon").removeClass(n.icons.activeHeader).addClass(n.icons.header),s||(i.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),n.icons&&i.children(".ui-accordion-header-icon").removeClass(n.icons.header).addClass(n.icons.activeHeader),i.next().addClass("ui-accordion-content-active"))},_toggle:function(t){var n=t.newPanel,r=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=n,this.prevHide=r,this.options.animate?this._animate(n,r,t):(r.hide(),n.show(),this._toggleComplete(t)),r.attr({"aria-expanded":"false","aria-hidden":"true"}),r.prev().attr("aria-selected","false"),n.length&&r.length?r.prev().attr("tabIndex",-1):n.length&&this.headers.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),n.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(e,t,n){var s,o,u,a=this,f=0,l=e.length&&(!t.length||e.index()<t.index()),c=this.options.animate||{},h=l&&c.down||c,p=function(){a._toggleComplete(n)};typeof h=="number"&&(u=h),typeof h=="string"&&(o=h),o=o||h.easing||c.easing,u=u||h.duration||c.duration;if(!t.length)return e.animate(i,u,o,p);if(!e.length)return t.animate(r,u,o,p);s=e.show().outerHeight(),t.animate(r,{duration:u,easing:o,step:function(e,t){t.now=Math.round(e)}}),e.hide().animate(i,{duration:u,easing:o,complete:p,step:function(e,n){n.now=Math.round(e),n.prop!=="height"?f+=n.now:a.options.heightStyle!=="content"&&(n.now=Math.round(s-t.outerHeight()-f),f=0)}})},_toggleComplete:function(e){var t=e.oldPanel;t.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),t.length&&(t.parent()[0].className=t.parent()[0].className),this._trigger("activate",null,e)}}),e.uiBackCompat!==!1&&(function(e,t){e.extend(t.options,{navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}});var n=t._create;t._create=function(){if(this.options.navigation){var t=this,r=this.element.find(this.options.header),i=r.next(),s=r.add(i).find("a").filter(this.options.navigationFilter)[0];s&&r.add(i).each(function(n){if(e.contains(this,s))return t.options.active=Math.floor(n/2),!1})}n.call(this)}}(jQuery,jQuery.ui.accordion.prototype),function(e,t){e.extend(t.options,{heightStyle:null,autoHeight:!0,clearStyle:!1,fillSpace:!1});var n=t._create,r=t._setOption;e.extend(t,{_create:function(){this.options.heightStyle=this.options.heightStyle||this._mergeHeightStyle(),n.call(this)},_setOption:function(e){if(e==="autoHeight"||e==="clearStyle"||e==="fillSpace")this.options.heightStyle=this._mergeHeightStyle();r.apply(this,arguments)},_mergeHeightStyle:function(){var e=this.options;if(e.fillSpace)return"fill";if(e.clearStyle)return"content";if(e.autoHeight)return"auto"}})}(jQuery,jQuery.ui.accordion.prototype),function(e,t){e.extend(t.options.icons,{activeHeader:null,headerSelected:"ui-icon-triangle-1-s"});var n=t._createIcons;t._createIcons=function(){this.options.icons&&(this.options.icons.activeHeader=this.options.icons.activeHeader||this.options.icons.headerSelected),n.call(this)}}(jQuery,jQuery.ui.accordion.prototype),function(e,t){t.activate=t._activate;var n=t._findActive;t._findActive=function(e){return e===-1&&(e=!1),e&&typeof e!="number"&&(e=this.headers.index(this.headers.filter(e)),e===-1&&(e=!1)),n.call(this,e)}}(jQuery,jQuery.ui.accordion.prototype),jQuery.ui.accordion.prototype.resize=jQuery.ui.accordion.prototype.refresh,function(e,t){e.extend(t.options,{change:null,changestart:null});var n=t._trigger;t._trigger=function(e,t,r){var i=n.apply(this,arguments);return i?(e==="beforeActivate"?i=n.call(this,"changestart",t,{oldHeader:r.oldHeader,oldContent:r.oldPanel,newHeader:r.newHeader,newContent:r.newPanel}):e==="activate"&&(i=n.call(this,"change",t,{oldHeader:r.oldHeader,oldContent:r.oldPanel,newHeader:r.newHeader,newContent:r.newPanel})),i):!1}}(jQuery,jQuery.ui.accordion.prototype),function(e,t){e.extend(t.options,{animate:null,animated:"slide"});var n=t._create;t._create=function(){var e=this.options;e.animate===null&&(e.animated?e.animated==="slide"?e.animate=300:e.animated==="bounceslide"?e.animate={duration:200,down:{easing:"easeOutBounce",duration:1e3}}:e.animate=e.animated:e.animate=!1),n.call(this)}}(jQuery,jQuery.ui.accordion.prototype))})(jQuery);(function(e,t){var n=0;e.widget("ui.autocomplete",{version:"1.9.2",defaultElement:"<input>",options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var t,n,r;this.isMultiLine=this._isMultiLine(),this.valueMethod=this.element[this.element.is("input,textarea")?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(i){if(this.element.prop("readOnly")){t=!0,r=!0,n=!0;return}t=!1,r=!1,n=!1;var s=e.ui.keyCode;switch(i.keyCode){case s.PAGE_UP:t=!0,this._move("previousPage",i);break;case s.PAGE_DOWN:t=!0,this._move("nextPage",i);break;case s.UP:t=!0,this._keyEvent("previous",i);break;case s.DOWN:t=!0,this._keyEvent("next",i);break;case s.ENTER:case s.NUMPAD_ENTER:this.menu.active&&(t=!0,i.preventDefault(),this.menu.select(i));break;case s.TAB:this.menu.active&&this.menu.select(i);break;case s.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(i),i.preventDefault());break;default:n=!0,this._searchTimeout(i)}},keypress:function(r){if(t){t=!1,r.preventDefault();return}if(n)return;var i=e.ui.keyCode;switch(r.keyCode){case i.PAGE_UP:this._move("previousPage",r);break;case i.PAGE_DOWN:this._move("nextPage",r);break;case i.UP:this._keyEvent("previous",r);break;case i.DOWN:this._keyEvent("next",r)}},input:function(e){if(r){r=!1,e.preventDefault();return}this._searchTimeout(e)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}clearTimeout(this.searching),this.close(e),this._change(e)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete").appendTo(this.document.find(this.options.appendTo||"body")[0]).menu({input:e(),role:null}).zIndex(this.element.zIndex()+1).hide().data("menu"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var n=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(r){r.target!==t.element[0]&&r.target!==n&&!e.contains(n,r.target)&&t.close()})})},menufocus:function(t,n){if(this.isNewMenu){this.isNewMenu=!1;if(t.originalEvent&&/^mouse/.test(t.originalEvent.type)){this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)});return}}var r=n.item.data("ui-autocomplete-item")||n.item.data("item.autocomplete");!1!==this._trigger("focus",t,{item:r})?t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(r.value):this.liveRegion.text(r.value)},menuselect:function(e,t){var n=t.item.data("ui-autocomplete-item")||t.item.data("item.autocomplete"),r=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=r,this._delay(function(){this.previous=r,this.selectedItem=n})),!1!==this._trigger("select",e,{item:n})&&this._value(n.value),this.term=this._value(),this.close(e),this.selectedItem=n}}),this.liveRegion=e("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertAfter(this.element),e.fn.bgiframe&&this.menu.element.bgiframe(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),e==="source"&&this._initSource(),e==="appendTo"&&this.menu.element.appendTo(this.document.find(t||"body")[0]),e==="disabled"&&t&&this.xhr&&this.xhr.abort()},_isMultiLine:function(){return this.element.is("textarea")?!0:this.element.is("input")?!1:this.element.prop("isContentEditable")},_initSource:function(){var t,n,r=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(n,r){r(e.ui.autocomplete.filter(t,n.term))}):typeof this.options.source=="string"?(n=this.options.source,this.source=function(t,i){r.xhr&&r.xhr.abort(),r.xhr=e.ajax({url:n,data:t,dataType:"json",success:function(e){i(e)},error:function(){i([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){e=e!=null?e:this._value(),this.term=this._value();if(e.length<this.options.minLength)return this.close(t);if(this._trigger("search",t)===!1)return;return this._search(e)},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var e=this,t=++n;return function(r){t===n&&e.__response(r),e.pending--,e.pending||e.element.removeClass("ui-autocomplete-loading")}},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return typeof t=="string"?{label:t,value:t}:e.extend({label:t.label||t.value,value:t.value||t.label},t)})},_suggest:function(t){var n=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(n,t),this.menu.refresh(),n.show(),this._resizeMenu(),n.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,n){var r=this;e.each(n,function(e,n){r._renderItemData(t,n)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,n){return e("<li>").append(e("<a>").text(n.label)).appendTo(t)},_move:function(e,t){if(!this.menu.element.is(":visible")){this.search(null,t);return}if(this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)){this._value(this.term),this.menu.blur();return}this.menu[e](t)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){if(!this.isMultiLine||this.menu.element.is(":visible"))this._move(e,t),t.preventDefault()}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,n){var r=new RegExp(e.ui.autocomplete.escapeRegex(n),"i");return e.grep(t,function(e){return r.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var t;this._superApply(arguments);if(this.options.disabled||this.cancelSearch)return;e&&e.length?t=this.options.messages.results(e.length):t=this.options.messages.noResults,this.liveRegion.text(t)}})})(jQuery);(function(e,t){var n,r,i,s,o="ui-button ui-widget ui-state-default ui-corner-all",u="ui-state-hover ui-state-active ",a="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",f=function(){var t=e(this).find(":ui-button");setTimeout(function(){t.button("refresh")},1)},l=function(t){var n=t.name,r=t.form,i=e([]);return n&&(r?i=e(r).find("[name='"+n+"']"):i=e("[name='"+n+"']",t.ownerDocument).filter(function(){return!this.form})),i};e.widget("ui.button",{version:"1.9.2",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,f),typeof this.options.disabled!="boolean"?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var t=this,u=this.options,a=this.type==="checkbox"||this.type==="radio",c=a?"":"ui-state-active",h="ui-state-focus";u.label===null&&(u.label=this.type==="input"?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(o).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){if(u.disabled)return;this===n&&e(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){if(u.disabled)return;e(this).removeClass(c)}).bind("click"+this.eventNamespace,function(e){u.disabled&&(e.preventDefault(),e.stopImmediatePropagation())}),this.element.bind("focus"+this.eventNamespace,function(){t.buttonElement.addClass(h)}).bind("blur"+this.eventNamespace,function(){t.buttonElement.removeClass(h)}),a&&(this.element.bind("change"+this.eventNamespace,function(){if(s)return;t.refresh()}),this.buttonElement.bind("mousedown"+this.eventNamespace,function(e){if(u.disabled)return;s=!1,r=e.pageX,i=e.pageY}).bind("mouseup"+this.eventNamespace,function(e){if(u.disabled)return;if(r!==e.pageX||i!==e.pageY)s=!0})),this.type==="checkbox"?this.buttonElement.bind("click"+this.eventNamespace,function(){if(u.disabled||s)return!1;e(this).toggleClass("ui-state-active"),t.buttonElement.attr("aria-pressed",t.element[0].checked)}):this.type==="radio"?this.buttonElement.bind("click"+this.eventNamespace,function(){if(u.disabled||s)return!1;e(this).addClass("ui-state-active"),t.buttonElement.attr("aria-pressed","true");var n=t.element[0];l(n).not(n).map(function(){return e(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){if(u.disabled)return!1;e(this).addClass("ui-state-active"),n=this,t.document.one("mouseup",function(){n=null})}).bind("mouseup"+this.eventNamespace,function(){if(u.disabled)return!1;e(this).removeClass("ui-state-active")}).bind("keydown"+this.eventNamespace,function(t){if(u.disabled)return!1;(t.keyCode===e.ui.keyCode.SPACE||t.keyCode===e.ui.keyCode.ENTER)&&e(this).addClass("ui-state-active")}).bind("keyup"+this.eventNamespace,function(){e(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(t){t.keyCode===e.ui.keyCode.SPACE&&e(this).click()})),this._setOption("disabled",u.disabled),this._resetButton()},_determineButtonType:function(){var e,t,n;this.element.is("[type=checkbox]")?this.type="checkbox":this.element.is("[type=radio]")?this.type="radio":this.element.is("input")?this.type="input":this.type="button",this.type==="checkbox"||this.type==="radio"?(e=this.element.parents().last(),t="label[for='"+this.element.attr("id")+"']",this.buttonElement=e.find(t),this.buttonElement.length||(e=e.length?e.siblings():this.element.siblings(),this.buttonElement=e.filter(t),this.buttonElement.length||(this.buttonElement=e.find(t))),this.element.addClass("ui-helper-hidden-accessible"),n=this.element.is(":checked"),n&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",n)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(o+" "+u+" "+a).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(e,t){this._super(e,t);if(e==="disabled"){t?this.element.prop("disabled",!0):this.element.prop("disabled",!1);return}this._resetButton()},refresh:function(){var t=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOption("disabled",t),this.type==="radio"?l(this.element[0]).each(function(){e(this).is(":checked")?e(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):e(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):this.type==="checkbox"&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if(this.type==="input"){this.options.label&&this.element.val(this.options.label);return}var t=this.buttonElement.removeClass(a),n=e("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(t.empty()).text(),r=this.options.icons,i=r.primary&&r.secondary,s=[];r.primary||r.secondary?(this.options.text&&s.push("ui-button-text-icon"+(i?"s":r.primary?"-primary":"-secondary")),r.primary&&t.prepend("<span class='ui-button-icon-primary ui-icon "+r.primary+"'></span>"),r.secondary&&t.append("<span class='ui-button-icon-secondary ui-icon "+r.secondary+"'></span>"),this.options.text||(s.push(i?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||t.attr("title",e.trim(n)))):s.push("ui-button-text-only"),t.addClass(s.join(" "))}}),e.widget("ui.buttonset",{version:"1.9.2",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(e,t){e==="disabled"&&this.buttons.button("option",e,t),this._super(e,t)},refresh:function(){var t=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(t?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(t?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})})(jQuery);(function($,undefined){function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function bindHover(e){var t="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(t,"mouseout",function(){$(this).removeClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!=-1&&$(this).removeClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!=-1&&$(this).removeClass("ui-datepicker-next-hover")}).delegate(t,"mouseover",function(){$.datepicker._isDisabledDatepicker(instActive.inline?e.parent()[0]:instActive.input[0])||($(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),$(this).addClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!=-1&&$(this).addClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!=-1&&$(this).addClass("ui-datepicker-next-hover"))})}function extendRemove(e,t){$.extend(e,t);for(var n in t)if(t[n]==null||t[n]==undefined)e[n]=t[n];return e}$.extend($.ui,{datepicker:{version:"1.9.2"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return extendRemove(this._defaults,e||{}),this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(e,t){var n=e[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:n,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:t,dpDiv:t?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(e,t){var n=$(e);t.append=$([]),t.trigger=$([]);if(n.hasClass(this.markerClassName))return;this._attachments(n,t),n.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),this._autoSize(t),$.data(e,PROP_NAME,t),t.settings.disabled&&this._disableDatepicker(e)},_attachments:function(e,t){var n=this._get(t,"appendText"),r=this._get(t,"isRTL");t.append&&t.append.remove(),n&&(t.append=$('<span class="'+this._appendClass+'">'+n+"</span>"),e[r?"before":"after"](t.append)),e.unbind("focus",this._showDatepicker),t.trigger&&t.trigger.remove();var i=this._get(t,"showOn");(i=="focus"||i=="both")&&e.focus(this._showDatepicker);if(i=="button"||i=="both"){var s=this._get(t,"buttonText"),o=this._get(t,"buttonImage");t.trigger=$(this._get(t,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:o,alt:s,title:s}):$('<button type="button"></button>').addClass(this._triggerClass).html(o==""?s:$("<img/>").attr({src:o,alt:s,title:s}))),e[r?"before":"after"](t.trigger),t.trigger.click(function(){return $.datepicker._datepickerShowing&&$.datepicker._lastInput==e[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=e[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(e[0])):$.datepicker._showDatepicker(e[0]),!1})}},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t=new Date(2009,11,20),n=this._get(e,"dateFormat");if(n.match(/[DM]/)){var r=function(e){var t=0,n=0;for(var r=0;r<e.length;r++)e[r].length>t&&(t=e[r].length,n=r);return n};t.setMonth(r(this._get(e,n.match(/MM/)?"monthNames":"monthNamesShort"))),t.setDate(r(this._get(e,n.match(/DD/)?"dayNames":"dayNamesShort"))+20-t.getDay())}e.input.attr("size",this._formatDate(e,t).length)}},_inlineDatepicker:function(e,t){var n=$(e);if(n.hasClass(this.markerClassName))return;n.addClass(this.markerClassName).append(t.dpDiv).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),$.data(e,PROP_NAME,t),this._setDate(t,this._getDefaultDate(t),!0),this._updateDatepicker(t),this._updateAlternate(t),t.settings.disabled&&this._disableDatepicker(e),t.dpDiv.css("display","block")},_dialogDatepicker:function(e,t,n,r,i){var s=this._dialogInst;if(!s){this.uuid+=1;var o="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+o+'" style="position: absolute; top: -100px; width: 0px;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),s=this._dialogInst=this._newInst(this._dialogInput,!1),s.settings={},$.data(this._dialogInput[0],PROP_NAME,s)}extendRemove(s.settings,r||{}),t=t&&t.constructor==Date?this._formatDate(s,t):t,this._dialogInput.val(t),this._pos=i?i.length?i:[i.pageX,i.pageY]:null;if(!this._pos){var u=document.documentElement.clientWidth,a=document.documentElement.clientHeight,f=document.documentElement.scrollLeft||document.body.scrollLeft,l=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[u/2-100+f,a/2-150+l]}return this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),s.settings.onSelect=n,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,s),this},_destroyDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();$.removeData(e,PROP_NAME),r=="input"?(n.append.remove(),n.trigger.remove(),t.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(r=="div"||r=="span")&&t.removeClass(this.markerClassName).empty()},_enableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!1,n.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().removeClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t})},_disableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!0,n.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().addClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t}),this._disabledInputs[this._disabledInputs.length]=e},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;t<this._disabledInputs.length;t++)if(this._disabledInputs[t]==e)return!0;return!1},_getInst:function(e){try{return $.data(e,PROP_NAME)}catch(t){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(e,t,n){var r=this._getInst(e);if(arguments.length==2&&typeof t=="string")return t=="defaults"?$.extend({},$.datepicker._defaults):r?t=="all"?$.extend({},r.settings):this._get(r,t):null;var i=t||{};typeof t=="string"&&(i={},i[t]=n);if(r){this._curInst==r&&this._hideDatepicker();var s=this._getDateDatepicker(e,!0),o=this._getMinMaxDate(r,"min"),u=this._getMinMaxDate(r,"max");extendRemove(r.settings,i),o!==null&&i.dateFormat!==undefined&&i.minDate===undefined&&(r.settings.minDate=this._formatDate(r,o)),u!==null&&i.dateFormat!==undefined&&i.maxDate===undefined&&(r.settings.maxDate=this._formatDate(r,u)),this._attachments($(e),r),this._autoSize(r),this._setDate(r,s),this._updateAlternate(r),this._updateDatepicker(r)}},_changeDatepicker:function(e,t,n){this._optionDatepicker(e,t,n)},_refreshDatepicker:function(e){var t=this._getInst(e);t&&this._updateDatepicker(t)},_setDateDatepicker:function(e,t){var n=this._getInst(e);n&&(this._setDate(n,t),this._updateDatepicker(n),this._updateAlternate(n))},_getDateDatepicker:function(e,t){var n=this._getInst(e);return n&&!n.inline&&this._setDateFromField(n,t),n?this._getDate(n):null},_doKeyDown:function(e){var t=$.datepicker._getInst(e.target),n=!0,r=t.dpDiv.is(".ui-datepicker-rtl");t._keyEvent=!0;if($.datepicker._datepickerShowing)switch(e.keyCode){case 9:$.datepicker._hideDatepicker(),n=!1;break;case 13:var i=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",t.dpDiv);i[0]&&$.datepicker._selectDay(e.target,t.selectedMonth,t.selectedYear,i[0]);var s=$.datepicker._get(t,"onSelect");if(s){var o=$.datepicker._formatDate(t);s.apply(t.input?t.input[0]:null,[o,t])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(e.target,e.ctrlKey?-$.datepicker._get(t,"stepBigMonths"):-$.datepicker._get(t,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(e.target,e.ctrlKey?+$.datepicker._get(t,"stepBigMonths"):+$.datepicker._get(t,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&$.datepicker._clearDate(e.target),n=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&$.datepicker._gotoToday(e.target),n=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,r?1:-1,"D"),n=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&$.datepicker._adjustDate(e.target,e.ctrlKey?-$.datepicker._get(t,"stepBigMonths"):-$.datepicker._get(t,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,-7,"D"),n=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,r?-1:1,"D"),n=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&$.datepicker._adjustDate(e.target,e.ctrlKey?+$.datepicker._get(t,"stepBigMonths"):+$.datepicker._get(t,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,7,"D"),n=e.ctrlKey||e.metaKey;break;default:n=!1}else e.keyCode==36&&e.ctrlKey?$.datepicker._showDatepicker(this):n=!1;n&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(e){var t=$.datepicker._getInst(e.target);if($.datepicker._get(t,"constrainInput")){var n=$.datepicker._possibleChars($.datepicker._get(t,"dateFormat")),r=String.fromCharCode(e.charCode==undefined?e.keyCode:e.charCode);return e.ctrlKey||e.metaKey||r<" "||!n||n.indexOf(r)>-1}},_doKeyUp:function(e){var t=$.datepicker._getInst(e.target);if(t.input.val()!=t.lastVal)try{var n=$.datepicker.parseDate($.datepicker._get(t,"dateFormat"),t.input?t.input.val():null,$.datepicker._getFormatConfig(t));n&&($.datepicker._setDateFromField(t),$.datepicker._updateAlternate(t),$.datepicker._updateDatepicker(t))}catch(r){$.datepicker.log(r)}return!0},_showDatepicker:function(e){e=e.target||e,e.nodeName.toLowerCase()!="input"&&(e=$("input",e.parentNode)[0]);if($.datepicker._isDisabledDatepicker(e)||$.datepicker._lastInput==e)return;var t=$.datepicker._getInst(e);$.datepicker._curInst&&$.datepicker._curInst!=t&&($.datepicker._curInst.dpDiv.stop(!0,!0),t&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var n=$.datepicker._get(t,"beforeShow"),r=n?n.apply(e,[e,t]):{};if(r===!1)return;extendRemove(t.settings,r),t.lastVal=null,$.datepicker._lastInput=e,$.datepicker._setDateFromField(t),$.datepicker._inDialog&&(e.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(e),$.datepicker._pos[1]+=e.offsetHeight);var i=!1;$(e).parents().each(function(){return i|=$(this).css("position")=="fixed",!i});var s={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,t.dpDiv.empty(),t.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(t),s=$.datepicker._checkOffset(t,s,i),t.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":i?"fixed":"absolute",display:"none",left:s.left+"px",top:s.top+"px"});if(!t.inline){var o=$.datepicker._get(t,"showAnim"),u=$.datepicker._get(t,"duration"),a=function(){var e=t.dpDiv.find("iframe.ui-datepicker-cover");if(!!e.length){var n=$.datepicker._getBorders(t.dpDiv);e.css({left:-n[0],top:-n[1],width:t.dpDiv.outerWidth(),height:t.dpDiv.outerHeight()})}};t.dpDiv.zIndex($(e).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&($.effects.effect[o]||$.effects[o])?t.dpDiv.show(o,$.datepicker._get(t,"showOptions"),u,a):t.dpDiv[o||"show"](o?u:null,a),(!o||!u)&&a(),t.input.is(":visible")&&!t.input.is(":disabled")&&t.input.focus(),$.datepicker._curInst=t}},_updateDatepicker:function(e){this.maxRows=4;var t=$.datepicker._getBorders(e.dpDiv);instActive=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var n=e.dpDiv.find("iframe.ui-datepicker-cover");!n.length||n.css({left:-t[0],top:-t[1],width:e.dpDiv.outerWidth(),height:e.dpDiv.outerHeight()}),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var r=this._getNumberOfMonths(e),i=r[1],s=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),i>1&&e.dpDiv.addClass("ui-datepicker-multi-"+i).css("width",s*i+"em"),e.dpDiv[(r[0]!=1||r[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e==$.datepicker._curInst&&$.datepicker._datepickerShowing&&e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&e.input[0]!=document.activeElement&&e.input.focus();if(e.yearshtml){var o=e.yearshtml;setTimeout(function(){o===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),o=e.yearshtml=null},0)}},_getBorders:function(e){var t=function(e){return{thin:1,medium:2,thick:3}[e]||e};return[parseFloat(t(e.css("border-left-width"))),parseFloat(t(e.css("border-top-width")))]},_checkOffset:function(e,t,n){var r=e.dpDiv.outerWidth(),i=e.dpDiv.outerHeight(),s=e.input?e.input.outerWidth():0,o=e.input?e.input.outerHeight():0,u=document.documentElement.clientWidth+(n?0:$(document).scrollLeft()),a=document.documentElement.clientHeight+(n?0:$(document).scrollTop());return t.left-=this._get(e,"isRTL")?r-s:0,t.left-=n&&t.left==e.input.offset().left?$(document).scrollLeft():0,t.top-=n&&t.top==e.input.offset().top+o?$(document).scrollTop():0,t.left-=Math.min(t.left,t.left+r>u&&u>r?Math.abs(t.left+r-u):0),t.top-=Math.min(t.top,t.top+i>a&&a>i?Math.abs(i+o):0),t},_findPos:function(e){var t=this._getInst(e),n=this._get(t,"isRTL");while(e&&(e.type=="hidden"||e.nodeType!=1||$.expr.filters.hidden(e)))e=e[n?"previousSibling":"nextSibling"];var r=$(e).offset();return[r.left,r.top]},_hideDatepicker:function(e){var t=this._curInst;if(!t||e&&t!=$.data(e,PROP_NAME))return;if(this._datepickerShowing){var n=this._get(t,"showAnim"),r=this._get(t,"duration"),i=function(){$.datepicker._tidyDialog(t)};$.effects&&($.effects.effect[n]||$.effects[n])?t.dpDiv.hide(n,$.datepicker._get(t,"showOptions"),r,i):t.dpDiv[n=="slideDown"?"slideUp":n=="fadeIn"?"fadeOut":"hide"](n?r:null,i),n||i(),this._datepickerShowing=!1;var s=this._get(t,"onClose");s&&s.apply(t.input?t.input[0]:null,[t.input?t.input.val():"",t]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(!$.datepicker._curInst)return;var t=$(e.target),n=$.datepicker._getInst(t[0]);(t[0].id!=$.datepicker._mainDivId&&t.parents("#"+$.datepicker._mainDivId).length==0&&!t.hasClass($.datepicker.markerClassName)&&!t.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||t.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=n)&&$.datepicker._hideDatepicker()},_adjustDate:function(e,t,n){var r=$(e),i=this._getInst(r[0]);if(this._isDisabledDatepicker(r[0]))return;this._adjustInstDate(i,t+(n=="M"?this._get(i,"showCurrentAtPos"):0),n),this._updateDatepicker(i)},_gotoToday:function(e){var t=$(e),n=this._getInst(t[0]);if(this._get(n,"gotoCurrent")&&n.currentDay)n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear;else{var r=new Date;n.selectedDay=r.getDate(),n.drawMonth=n.selectedMonth=r.getMonth(),n.drawYear=n.selectedYear=r.getFullYear()}this._notifyChange(n),this._adjustDate(t)},_selectMonthYear:function(e,t,n){var r=$(e),i=this._getInst(r[0]);i["selected"+(n=="M"?"Month":"Year")]=i["draw"+(n=="M"?"Month":"Year")]=parseInt(t.options[t.selectedIndex].value,10),this._notifyChange(i),this._adjustDate(r)},_selectDay:function(e,t,n,r){var i=$(e);if($(r).hasClass(this._unselectableClass)||this._isDisabledDatepicker(i[0]))return;var s=this._getInst(i[0]);s.selectedDay=s.currentDay=$("a",r).html(),s.selectedMonth=s.currentMonth=t,s.selectedYear=s.currentYear=n,this._selectDate(e,this._formatDate(s,s.currentDay,s.currentMonth,s.currentYear))},_clearDate:function(e){var t=$(e),n=this._getInst(t[0]);this._selectDate(t,"")},_selectDate:function(e,t){var n=$(e),r=this._getInst(n[0]);t=t!=null?t:this._formatDate(r),r.input&&r.input.val(t),this._updateAlternate(r);var i=this._get(r,"onSelect");i?i.apply(r.input?r.input[0]:null,[t,r]):r.input&&r.input.trigger("change"),r.inline?this._updateDatepicker(r):(this._hideDatepicker(),this._lastInput=r.input[0],typeof r.input[0]!="object"&&r.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var t=this._get(e,"altField");if(t){var n=this._get(e,"altFormat")||this._get(e,"dateFormat"),r=this._getDate(e),i=this.formatDate(n,r,this._getFormatConfig(e));$(t).each(function(){$(this).val(i)})}},noWeekends:function(e){var t=e.getDay();return[t>0&&t<6,""]},iso8601Week:function(e){var t=new Date(e.getTime());t.setDate(t.getDate()+4-(t.getDay()||7));var n=t.getTime();return t.setMonth(0),t.setDate(1),Math.floor(Math.round((n-t)/864e5)/7)+1},parseDate:function(e,t,n){if(e==null||t==null)throw"Invalid arguments";t=typeof t=="object"?t.toString():t+"";if(t=="")return null;var r=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff;r=typeof r!="string"?r:(new Date).getFullYear()%100+parseInt(r,10);var i=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,s=(n?n.dayNames:null)||this._defaults.dayNames,o=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,u=(n?n.monthNames:null)||this._defaults.monthNames,a=-1,f=-1,l=-1,c=-1,h=!1,p=function(t){var n=y+1<e.length&&e.charAt(y+1)==t;return n&&y++,n},d=function(e){var n=p(e),r=e=="@"?14:e=="!"?20:e=="y"&&n?4:e=="o"?3:2,i=new RegExp("^\\d{1,"+r+"}"),s=t.substring(g).match(i);if(!s)throw"Missing number at position "+g;return g+=s[0].length,parseInt(s[0],10)},v=function(e,n,r){var i=$.map(p(e)?r:n,function(e,t){return[[t,e]]}).sort(function(e,t){return-(e[1].length-t[1].length)}),s=-1;$.each(i,function(e,n){var r=n[1];if(t.substr(g,r.length).toLowerCase()==r.toLowerCase())return s=n[0],g+=r.length,!1});if(s!=-1)return s+1;throw"Unknown name at position "+g},m=function(){if(t.charAt(g)!=e.charAt(y))throw"Unexpected literal at position "+g;g++},g=0;for(var y=0;y<e.length;y++)if(h)e.charAt(y)=="'"&&!p("'")?h=!1:m();else switch(e.charAt(y)){case"d":l=d("d");break;case"D":v("D",i,s);break;case"o":c=d("o");break;case"m":f=d("m");break;case"M":f=v("M",o,u);break;case"y":a=d("y");break;case"@":var b=new Date(d("@"));a=b.getFullYear(),f=b.getMonth()+1,l=b.getDate();break;case"!":var b=new Date((d("!")-this._ticksTo1970)/1e4);a=b.getFullYear(),f=b.getMonth()+1,l=b.getDate();break;case"'":p("'")?m():h=!0;break;default:m()}if(g<t.length){var w=t.substr(g);if(!/^\s+/.test(w))throw"Extra/unparsed characters found in date: "+w}a==-1?a=(new Date).getFullYear():a<100&&(a+=(new Date).getFullYear()-(new Date).getFullYear()%100+(a<=r?0:-100));if(c>-1){f=1,l=c;do{var E=this._getDaysInMonth(a,f-1);if(l<=E)break;f++,l-=E}while(!0)}var b=this._daylightSavingAdjust(new Date(a,f-1,l));if(b.getFullYear()!=a||b.getMonth()+1!=f||b.getDate()!=l)throw"Invalid date";return b},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(e,t,n){if(!t)return"";var r=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,i=(n?n.dayNames:null)||this._defaults.dayNames,s=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,o=(n?n.monthNames:null)||this._defaults.monthNames,u=function(t){var n=h+1<e.length&&e.charAt(h+1)==t;return n&&h++,n},a=function(e,t,n){var r=""+t;if(u(e))while(r.length<n)r="0"+r;return r},f=function(e,t,n,r){return u(e)?r[t]:n[t]},l="",c=!1;if(t)for(var h=0;h<e.length;h++)if(c)e.charAt(h)=="'"&&!u("'")?c=!1:l+=e.charAt(h);else switch(e.charAt(h)){case"d":l+=a("d",t.getDate(),2);break;case"D":l+=f("D",t.getDay(),r,i);break;case"o":l+=a("o",Math.round(((new Date(t.getFullYear(),t.getMonth(),t.getDate())).getTime()-(new Date(t.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":l+=a("m",t.getMonth()+1,2);break;case"M":l+=f("M",t.getMonth(),s,o);break;case"y":l+=u("y")?t.getFullYear():(t.getYear()%100<10?"0":"")+t.getYear()%100;break;case"@":l+=t.getTime();break;case"!":l+=t.getTime()*1e4+this._ticksTo1970;break;case"'":u("'")?l+="'":c=!0;break;default:l+=e.charAt(h)}return l},_possibleChars:function(e){var t="",n=!1,r=function(t){var n=i+1<e.length&&e.charAt(i+1)==t;return n&&i++,n};for(var i=0;i<e.length;i++)if(n)e.charAt(i)=="'"&&!r("'")?n=!1:t+=e.charAt(i);else switch(e.charAt(i)){case"d":case"m":case"y":case"@":t+="0123456789";break;case"D":case"M":return null;case"'":r("'")?t+="'":n=!0;break;default:t+=e.charAt(i)}return t},_get:function(e,t){return e.settings[t]!==undefined?e.settings[t]:this._defaults[t]},_setDateFromField:function(e,t){if(e.input.val()==e.lastVal)return;var n=this._get(e,"dateFormat"),r=e.lastVal=e.input?e.input.val():null,i,s;i=s=this._getDefaultDate(e);var o=this._getFormatConfig(e);try{i=this.parseDate(n,r,o)||s}catch(u){this.log(u),r=t?"":r}e.selectedDay=i.getDate(),e.drawMonth=e.selectedMonth=i.getMonth(),e.drawYear=e.selectedYear=i.getFullYear(),e.currentDay=r?i.getDate():0,e.currentMonth=r?i.getMonth():0,e.currentYear=r?i.getFullYear():0,this._adjustInstDate(e)},_getDefaultDate:function(e){return this._restrictMinMax(e,this._determineDate(e,this._get(e,"defaultDate"),new Date))},_determineDate:function(e,t,n){var r=function(e){var t=new Date;return t.setDate(t.getDate()+e),t},i=function(t){try{return $.datepicker.parseDate($.datepicker._get(e,"dateFormat"),t,$.datepicker._getFormatConfig(e))}catch(n){}var r=(t.toLowerCase().match(/^c/)?$.datepicker._getDate(e):null)||new Date,i=r.getFullYear(),s=r.getMonth(),o=r.getDate(),u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,a=u.exec(t);while(a){switch(a[2]||"d"){case"d":case"D":o+=parseInt(a[1],10);break;case"w":case"W":o+=parseInt(a[1],10)*7;break;case"m":case"M":s+=parseInt(a[1],10),o=Math.min(o,$.datepicker._getDaysInMonth(i,s));break;case"y":case"Y":i+=parseInt(a[1],10),o=Math.min(o,$.datepicker._getDaysInMonth(i,s))}a=u.exec(t)}return new Date(i,s,o)},s=t==null||t===""?n:typeof t=="string"?i(t):typeof t=="number"?isNaN(t)?n:r(t):new Date(t.getTime());return s=s&&s.toString()=="Invalid Date"?n:s,s&&(s.setHours(0),s.setMinutes(0),s.setSeconds(0),s.setMilliseconds(0)),this._daylightSavingAdjust(s)},_daylightSavingAdjust:function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},_setDate:function(e,t,n){var r=!t,i=e.selectedMonth,s=e.selectedYear,o=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=o.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=o.getMonth(),e.drawYear=e.selectedYear=e.currentYear=o.getFullYear(),(i!=e.selectedMonth||s!=e.selectedYear)&&!n&&this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(r?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&e.input.val()==""?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(e){var t=this._get(e,"stepMonths"),n="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,-t,"M")},next:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,+t,"M")},hide:function(){window["DP_jQuery_"+dpuuid].datepicker._hideDatepicker()},today:function(){window["DP_jQuery_"+dpuuid].datepicker._gotoToday(n)},selectDay:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectDay(n,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"Y"),!1}};$(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t=new Date;t=this._daylightSavingAdjust(new Date(t.getFullYear(),t.getMonth(),t.getDate()));var n=this._get(e,"isRTL"),r=this._get(e,"showButtonPanel"),i=this._get(e,"hideIfNoPrevNext"),s=this._get(e,"navigationAsDateFormat"),o=this._getNumberOfMonths(e),u=this._get(e,"showCurrentAtPos"),a=this._get(e,"stepMonths"),f=o[0]!=1||o[1]!=1,l=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),c=this._getMinMaxDate(e,"min"),h=this._getMinMaxDate(e,"max"),p=e.drawMonth-u,d=e.drawYear;p<0&&(p+=12,d--);if(h){var v=this._daylightSavingAdjust(new Date(h.getFullYear(),h.getMonth()-o[0]*o[1]+1,h.getDate()));v=c&&v<c?c:v;while(this._daylightSavingAdjust(new Date(d,p,1))>v)p--,p<0&&(p=11,d--)}e.drawMonth=p,e.drawYear=d;var m=this._get(e,"prevText");m=s?this.formatDate(m,this._daylightSavingAdjust(new Date(d,p-a,1)),this._getFormatConfig(e)):m;var g=this._canAdjustMonth(e,-1,d,p)?'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click" title="'+m+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"e":"w")+'">'+m+"</span></a>":i?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+m+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"e":"w")+'">'+m+"</span></a>",y=this._get(e,"nextText");y=s?this.formatDate(y,this._daylightSavingAdjust(new Date(d,p+a,1)),this._getFormatConfig(e)):y;var b=this._canAdjustMonth(e,1,d,p)?'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click" title="'+y+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"w":"e")+'">'+y+"</span></a>":i?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+y+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"w":"e")+'">'+y+"</span></a>",w=this._get(e,"currentText"),E=this._get(e,"gotoCurrent")&&e.currentDay?l:t;w=s?this.formatDate(w,E,this._getFormatConfig(e)):w;var S=e.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">'+this._get(e,"closeText")+"</button>",x=r?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(n?S:"")+(this._isInRange(e,E)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click">'+w+"</button>":"")+(n?"":S)+"</div>":"",T=parseInt(this._get(e,"firstDay"),10);T=isNaN(T)?0:T;var N=this._get(e,"showWeek"),C=this._get(e,"dayNames"),k=this._get(e,"dayNamesShort"),L=this._get(e,"dayNamesMin"),A=this._get(e,"monthNames"),O=this._get(e,"monthNamesShort"),M=this._get(e,"beforeShowDay"),_=this._get(e,"showOtherMonths"),D=this._get(e,"selectOtherMonths"),P=this._get(e,"calculateWeek")||this.iso8601Week,H=this._getDefaultDate(e),B="";for(var j=0;j<o[0];j++){var F="";this.maxRows=4;for(var I=0;I<o[1];I++){var q=this._daylightSavingAdjust(new Date(d,p,e.selectedDay)),R=" ui-corner-all",U="";if(f){U+='<div class="ui-datepicker-group';if(o[1]>1)switch(I){case 0:U+=" ui-datepicker-group-first",R=" ui-corner-"+(n?"right":"left");break;case o[1]-1:U+=" ui-datepicker-group-last",R=" ui-corner-"+(n?"left":"right");break;default:U+=" ui-datepicker-group-middle",R=""}U+='">'}U+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+R+'">'+(/all|left/.test(R)&&j==0?n?b:g:"")+(/all|right/.test(R)&&j==0?n?g:b:"")+this._generateMonthYearHeader(e,p,d,c,h,j>0||I>0,A,O)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var z=N?'<th class="ui-datepicker-week-col">'+this._get(e,"weekHeader")+"</th>":"";for(var W=0;W<7;W++){var X=(W+T)%7;z+="<th"+((W+T+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+C[X]+'">'+L[X]+"</span></th>"}U+=z+"</tr></thead><tbody>";var V=this._getDaysInMonth(d,p);d==e.selectedYear&&p==e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,V));var J=(this._getFirstDayOfMonth(d,p)-T+7)%7,K=Math.ceil((J+V)/7),Q=f?this.maxRows>K?this.maxRows:K:K;this.maxRows=Q;var G=this._daylightSavingAdjust(new Date(d,p,1-J));for(var Y=0;Y<Q;Y++){U+="<tr>";var Z=N?'<td class="ui-datepicker-week-col">'+this._get(e,"calculateWeek")(G)+"</td>":"";for(var W=0;W<7;W++){var et=M?M.apply(e.input?e.input[0]:null,[G]):[!0,""],tt=G.getMonth()!=p,nt=tt&&!D||!et[0]||c&&G<c||h&&G>h;Z+='<td class="'+((W+T+6)%7>=5?" ui-datepicker-week-end":"")+(tt?" ui-datepicker-other-month":"")+(G.getTime()==q.getTime()&&p==e.selectedMonth&&e._keyEvent||H.getTime()==G.getTime()&&H.getTime()==q.getTime()?" "+this._dayOverClass:"")+(nt?" "+this._unselectableClass+" ui-state-disabled":"")+(tt&&!_?"":" "+et[1]+(G.getTime()==l.getTime()?" "+this._currentClass:"")+(G.getTime()==t.getTime()?" ui-datepicker-today":""))+'"'+((!tt||_)&&et[2]?' title="'+et[2]+'"':"")+(nt?"":' data-handler="selectDay" data-event="click" data-month="'+G.getMonth()+'" data-year="'+G.getFullYear()+'"')+">"+(tt&&!_?"&#xa0;":nt?'<span class="ui-state-default">'+G.getDate()+"</span>":'<a class="ui-state-default'+(G.getTime()==t.getTime()?" ui-state-highlight":"")+(G.getTime()==l.getTime()?" ui-state-active":"")+(tt?" ui-priority-secondary":"")+'" href="#">'+G.getDate()+"</a>")+"</td>",G.setDate(G.getDate()+1),G=this._daylightSavingAdjust(G)}U+=Z+"</tr>"}p++,p>11&&(p=0,d++),U+="</tbody></table>"+(f?"</div>"+(o[0]>0&&I==o[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),F+=U}B+=F}return B+=x+($.ui.ie6&&!e.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""),e._keyEvent=!1,B},_generateMonthYearHeader:function(e,t,n,r,i,s,o,u){var a=this._get(e,"changeMonth"),f=this._get(e,"changeYear"),l=this._get(e,"showMonthAfterYear"),c='<div class="ui-datepicker-title">',h="";if(s||!a)h+='<span class="ui-datepicker-month">'+o[t]+"</span>";else{var p=r&&r.getFullYear()==n,d=i&&i.getFullYear()==n;h+='<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';for(var v=0;v<12;v++)(!p||v>=r.getMonth())&&(!d||v<=i.getMonth())&&(h+='<option value="'+v+'"'+(v==t?' selected="selected"':"")+">"+u[v]+"</option>");h+="</select>"}l||(c+=h+(s||!a||!f?"&#xa0;":""));if(!e.yearshtml){e.yearshtml="";if(s||!f)c+='<span class="ui-datepicker-year">'+n+"</span>";else{var m=this._get(e,"yearRange").split(":"),g=(new Date).getFullYear(),y=function(e){var t=e.match(/c[+-].*/)?n+parseInt(e.substring(1),10):e.match(/[+-].*/)?g+parseInt(e,10):parseInt(e,10);return isNaN(t)?g:t},b=y(m[0]),w=Math.max(b,y(m[1]||""));b=r?Math.max(b,r.getFullYear()):b,w=i?Math.min(w,i.getFullYear()):w,e.yearshtml+='<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';for(;b<=w;b++)e.yearshtml+='<option value="'+b+'"'+(b==n?' selected="selected"':"")+">"+b+"</option>";e.yearshtml+="</select>",c+=e.yearshtml,e.yearshtml=null}}return c+=this._get(e,"yearSuffix"),l&&(c+=(s||!a||!f?"&#xa0;":"")+h),c+="</div>",c},_adjustInstDate:function(e,t,n){var r=e.drawYear+(n=="Y"?t:0),i=e.drawMonth+(n=="M"?t:0),s=Math.min(e.selectedDay,this._getDaysInMonth(r,i))+(n=="D"?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(r,i,s)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),(n=="M"||n=="Y")&&this._notifyChange(e)},_restrictMinMax:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max"),i=n&&t<n?n:t;return i=r&&i>r?r:i,i},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return t==null?[1,1]:typeof t=="number"?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return(new Date(e,t,1)).getDay()},_canAdjustMonth:function(e,t,n,r){var i=this._getNumberOfMonths(e),s=this._daylightSavingAdjust(new Date(n,r+(t<0?t:i[0]*i[1]),1));return t<0&&s.setDate(this._getDaysInMonth(s.getFullYear(),s.getMonth())),this._isInRange(e,s)},_isInRange:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max");return(!n||t.getTime()>=n.getTime())&&(!r||t.getTime()<=r.getTime())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t=typeof t!="string"?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,n,r){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var i=t?typeof t=="object"?t:this._daylightSavingAdjust(new Date(r,n,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),i,this._getFormatConfig(e))}}),$.fn.datepicker=function(e){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find(document.body).append($.datepicker.dpDiv),$.datepicker.initialized=!0);var t=Array.prototype.slice.call(arguments,1);return typeof e!="string"||e!="isDisabled"&&e!="getDate"&&e!="widget"?e=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t)):this.each(function(){typeof e=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this].concat(t)):$.datepicker._attachDatepicker(this,e)}):$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.9.2",window["DP_jQuery_"+dpuuid]=$})(jQuery);(function(e,t){var n="ui-dialog ui-widget ui-widget-content ui-corner-all ",r={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.9.2",options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var n=e(this).css(t).offset().top;n<0&&e(this).css("top",t.top-n)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.oldPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.options.title=this.options.title||this.originalTitle;var t=this,r=this.options,i=r.title||"&#160;",s,o,u,a,f;s=(this.uiDialog=e("<div>")).addClass(n+r.dialogClass).css({display:"none",outline:0,zIndex:r.zIndex}).attr("tabIndex",-1).keydown(function(n){r.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===e.ui.keyCode.ESCAPE&&(t.close(n),n.preventDefault())}).mousedown(function(e){t.moveToTop(!1,e)}).appendTo("body"),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(s),o=(this.uiDialogTitlebar=e("<div>")).addClass("ui-dialog-titlebar  ui-widget-header  ui-corner-all  ui-helper-clearfix").bind("mousedown",function(){s.focus()}).prependTo(s),u=e("<a href='#'></a>").addClass("ui-dialog-titlebar-close  ui-corner-all").attr("role","button").click(function(e){e.preventDefault(),t.close(e)}).appendTo(o),(this.uiDialogTitlebarCloseText=e("<span>")).addClass("ui-icon ui-icon-closethick").text(r.closeText).appendTo(u),a=e("<span>").uniqueId().addClass("ui-dialog-title").html(i).prependTo(o),f=(this.uiDialogButtonPane=e("<div>")).addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),(this.uiButtonSet=e("<div>")).addClass("ui-dialog-buttonset").appendTo(f),s.attr({role:"dialog","aria-labelledby":a.attr("id")}),o.find("*").add(o).disableSelection(),this._hoverable(u),this._focusable(u),r.draggable&&e.fn.draggable&&this._makeDraggable(),r.resizable&&e.fn.resizable&&this._makeResizable(),this._createButtons(r.buttons),this._isOpen=!1,e.fn.bgiframe&&s.bgiframe(),this._on(s,{keydown:function(t){if(!r.modal||t.keyCode!==e.ui.keyCode.TAB)return;var n=e(":tabbable",s),i=n.filter(":first"),o=n.filter(":last");if(t.target===o[0]&&!t.shiftKey)return i.focus(1),!1;if(t.target===i[0]&&t.shiftKey)return o.focus(1),!1}})},_init:function(){this.options.autoOpen&&this.open()},_destroy:function(){var e,t=this.oldPosition;this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},close:function(t){var n=this,r,i;if(!this._isOpen)return;if(!1===this._trigger("beforeClose",t))return;return this._isOpen=!1,this.overlay&&this.overlay.destroy(),this.options.hide?this._hide(this.uiDialog,this.options.hide,function(){n._trigger("close",t)}):(this.uiDialog.hide(),this._trigger("close",t)),e.ui.dialog.overlay.resize(),this.options.modal&&(r=0,e(".ui-dialog").each(function(){this!==n.uiDialog[0]&&(i=e(this).css("z-index"),isNaN(i)||(r=Math.max(r,i)))}),e.ui.dialog.maxZ=r),this},isOpen:function(){return this._isOpen},moveToTop:function(t,n){var r=this.options,i;return r.modal&&!t||!r.stack&&!r.modal?this._trigger("focus",n):(r.zIndex>e.ui.dialog.maxZ&&(e.ui.dialog.maxZ=r.zIndex),this.overlay&&(e.ui.dialog.maxZ+=1,e.ui.dialog.overlay.maxZ=e.ui.dialog.maxZ,this.overlay.$el.css("z-index",e.ui.dialog.overlay.maxZ)),i={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},e.ui.dialog.maxZ+=1,this.uiDialog.css("z-index",e.ui.dialog.maxZ),this.element.attr(i),this._trigger("focus",n),this)},open:function(){if(this._isOpen)return;var t,n=this.options,r=this.uiDialog;return this._size(),this._position(n.position),r.show(n.show),this.overlay=n.modal?new e.ui.dialog.overlay(this):null,this.moveToTop(!0),t=this.element.find(":tabbable"),t.length||(t=this.uiDialogButtonPane.find(":tabbable"),t.length||(t=r)),t.eq(0).focus(),this._isOpen=!0,this._trigger("open"),this},_createButtons:function(t){var n=this,r=!1;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),typeof t=="object"&&t!==null&&e.each(t,function(){return!(r=!0)}),r?(e.each(t,function(t,r){var i,s;r=e.isFunction(r)?{click:r,text:t}:r,r=e.extend({type:"button"},r),s=r.click,r.click=function(){s.apply(n.element[0],arguments)},i=e("<button></button>",r).appendTo(n.uiButtonSet),e.fn.button&&i.button()}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog)):this.uiDialog.removeClass("ui-dialog-buttons")},_makeDraggable:function(){function r(e){return{position:e.position,offset:e.offset}}var t=this,n=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(n,i){e(this).addClass("ui-dialog-dragging"),t._trigger("dragStart",n,r(i))},drag:function(e,n){t._trigger("drag",e,r(n))},stop:function(i,s){n.position=[s.position.left-t.document.scrollLeft(),s.position.top-t.document.scrollTop()],e(this).removeClass("ui-dialog-dragging"),t._trigger("dragStop",i,r(s)),e.ui.dialog.overlay.resize()}})},_makeResizable:function(n){function u(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}n=n===t?this.options.resizable:n;var r=this,i=this.options,s=this.uiDialog.css("position"),o=typeof n=="string"?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:i.maxWidth,maxHeight:i.maxHeight,minWidth:i.minWidth,minHeight:this._minHeight(),handles:o,start:function(t,n){e(this).addClass("ui-dialog-resizing"),r._trigger("resizeStart",t,u(n))},resize:function(e,t){r._trigger("resize",e,u(t))},stop:function(t,n){e(this).removeClass("ui-dialog-resizing"),i.height=e(this).height(),i.width=e(this).width(),r._trigger("resizeStop",t,u(n)),e.ui.dialog.overlay.resize()}}).css("position",s).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var e=this.options;return e.height==="auto"?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(t){var n=[],r=[0,0],i;if(t){if(typeof t=="string"||typeof t=="object"&&"0"in t)n=t.split?t.split(" "):[t[0],t[1]],n.length===1&&(n[1]=n[0]),e.each(["left","top"],function(e,t){+n[e]===n[e]&&(r[e]=n[e],n[e]=t)}),t={my:n[0]+(r[0]<0?r[0]:"+"+r[0])+" "+n[1]+(r[1]<0?r[1]:"+"+r[1]),at:n.join(" ")};t=e.extend({},e.ui.dialog.prototype.options.position,t)}else t=e.ui.dialog.prototype.options.position;i=this.uiDialog.is(":visible"),i||this.uiDialog.show(),this.uiDialog.position(t),i||this.uiDialog.hide()},_setOptions:function(t){var n=this,s={},o=!1;e.each(t,function(e,t){n._setOption(e,t),e in r&&(o=!0),e in i&&(s[e]=t)}),o&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",s)},_setOption:function(t,r){var i,s,o=this.uiDialog;switch(t){case"buttons":this._createButtons(r);break;case"closeText":this.uiDialogTitlebarCloseText.text(""+r);break;case"dialogClass":o.removeClass(this.options.dialogClass).addClass(n+r);break;case"disabled":r?o.addClass("ui-dialog-disabled"):o.removeClass("ui-dialog-disabled");break;case"draggable":i=o.is(":data(draggable)"),i&&!r&&o.draggable("destroy"),!i&&r&&this._makeDraggable();break;case"position":this._position(r);break;case"resizable":s=o.is(":data(resizable)"),s&&!r&&o.resizable("destroy"),s&&typeof r=="string"&&o.resizable("option","handles",r),!s&&r!==!1&&this._makeResizable(r);break;case"title":e(".ui-dialog-title",this.uiDialogTitlebar).html(""+(r||"&#160;"))}this._super(t,r)},_size:function(){var t,n,r,i=this.options,s=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),i.minWidth>i.width&&(i.width=i.minWidth),t=this.uiDialog.css({height:"auto",width:i.width}).outerHeight(),n=Math.max(0,i.minHeight-t),i.height==="auto"?e.support.minHeight?this.element.css({minHeight:n,height:"auto"}):(this.uiDialog.show(),r=this.element.css("height","auto").height(),s||this.uiDialog.hide(),this.element.height(Math.max(r,n))):this.element.height(Math.max(i.height-t,0)),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),e.extend(e.ui.dialog,{uuid:0,maxZ:0,getTitleId:function(e){var t=e.attr("id");return t||(this.uuid+=1,t=this.uuid),"ui-dialog-title-"+t},overlay:function(t){this.$el=e.ui.dialog.overlay.create(t)}}),e.extend(e.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:e.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(e){return e+".dialog-overlay"}).join(" "),create:function(t){this.instances.length===0&&(setTimeout(function(){e.ui.dialog.overlay.instances.length&&e(document).bind(e.ui.dialog.overlay.events,function(t){if(e(t.target).zIndex()<e.ui.dialog.overlay.maxZ)return!1})},1),e(window).bind("resize.dialog-overlay",e.ui.dialog.overlay.resize));var n=this.oldInstances.pop()||e("<div>").addClass("ui-widget-overlay");return e(document).bind("keydown.dialog-overlay",function(r){var i=e.ui.dialog.overlay.instances;i.length!==0&&i[i.length-1]===n&&t.options.closeOnEscape&&!r.isDefaultPrevented()&&r.keyCode&&r.keyCode===e.ui.keyCode.ESCAPE&&(t.close(r),r.preventDefault())}),n.appendTo(document.body).css({width:this.width(),height:this.height()}),e.fn.bgiframe&&n.bgiframe(),this.instances.push(n),n},destroy:function(t){var n=e.inArray(t,this.instances),r=0;n!==-1&&this.oldInstances.push(this.instances.splice(n,1)[0]),this.instances.length===0&&e([document,window]).unbind(".dialog-overlay"),t.height(0).width(0).remove(),e.each(this.instances,function(){r=Math.max(r,this.css("z-index"))}),this.maxZ=r},height:function(){var t,n;return e.ui.ie?(t=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),n=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),t<n?e(window).height()+"px":t+"px"):e(document).height()+"px"},width:function(){var t,n;return e.ui.ie?(t=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),n=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth),t<n?e(window).width()+"px":t+"px"):e(document).width()+"px"},resize:function(){var t=e([]);e.each(e.ui.dialog.overlay.instances,function(){t=t.add(this)}),t.css({width:0,height:0}).css({width:e.ui.dialog.overlay.width(),height:e.ui.dialog.overlay.height()})}}),e.extend(e.ui.dialog.overlay.prototype,{destroy:function(){e.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);(function(e,t){var n=!1;e.widget("ui.menu",{version:"1.9.2",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,e.proxy(function(e){this.options.disabled&&e.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(e){e.preventDefault()},"click .ui-state-disabled > a":function(e){e.preventDefault()},"click .ui-menu-item:has(a)":function(t){var r=e(t.target).closest(".ui-menu-item");!n&&r.not(".ui-state-disabled").length&&(n=!0,this.select(t),r.has(".ui-menu").length?this.expand(t):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&this.active.parents(".ui-menu").length===1&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var n=e(t.currentTarget);n.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(t,n)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var n=this.active||this.element.children(".ui-menu-item").eq(0);t||this.focus(e,n)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){e(t.target).closest(".ui-menu").length||this.collapseAll(t),n=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").andSelf().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){function a(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var n,r,i,s,o,u=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:u=!1,r=this.previousFilter||"",i=String.fromCharCode(t.keyCode),s=!1,clearTimeout(this.filterTimer),i===r?s=!0:i=r+i,o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())}),n=s&&n.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):n,n.length||(i=String.fromCharCode(t.keyCode),o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())})),n.length?(this.focus(t,n),n.length>1?(this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}u&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(e):this.select(e))},refresh:function(){var t,n=this.options.icons.submenu,r=this.element.find(this.options.menus);r.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),r=t.prev("a"),i=e("<span>").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);r.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",r.attr("id"))}),t=r.add(this.element),t.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),t.children(":not(.ui-menu-item)").each(function(){var t=e(this);/[^\-Ã¢â‚¬â€Ã¢â‚¬â€œ\s]/.test(t.text())||t.addClass("ui-widget-content ui-menu-divider")}),t.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},focus:function(e,t){var n,r;this.blur(e,e&&e.type==="focus"),this._scrollIntoView(t),this.active=t.first(),r=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",r.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),e&&e.type==="keydown"?this._close():this.timer=this._delay(function(){this._close()},this.delay),n=t.children(".ui-menu"),n.length&&/^mouse/.test(e.type)&&this._startOpening(n),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var n,r,i,s,o,u;this._hasScroll()&&(n=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,r=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,i=t.offset().top-this.activeMenu.offset().top-n-r,s=this.activeMenu.scrollTop(),o=this.activeMenu.height(),u=t.height(),i<0?this.activeMenu.scrollTop(s+i):i+u>o&&this.activeMenu.scrollTop(s+i-o+u))},blur:function(e,t){t||clearTimeout(this.timer);if(!this.active)return;this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active})},_startOpening:function(e){clearTimeout(this.timer);if(e.attr("aria-hidden")!=="true")return;this.timer=this._delay(function(){this._close(),this._open(e)},this.delay)},_open:function(t){var n=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(n)},collapseAll:function(t,n){clearTimeout(this.timer),this.timer=this._delay(function(){var r=n?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));r.length||(r=this.element),this._close(r),this.blur(t),this.activeMenu=r},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,n){var r;this.active&&(e==="first"||e==="last"?r=this.active[e==="first"?"prevAll":"nextAll"](".ui-menu-item").eq(-1):r=this.active[e+"All"](".ui-menu-item").eq(0));if(!r||!r.length||!this.active)r=this.activeMenu.children(".ui-menu-item")[t]();this.focus(n,r)},nextPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isLastItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r-i<0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())},previousPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isFirstItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r+i>0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item").first())},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||e(t.target).closest(".ui-menu-item");var n={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,n)}})})(jQuery);(function(e,t){e.widget("ui.progressbar",{version:"1.9.2",options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=e("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return e===t?this._value():(this._setOption("value",e),this)},_setOption:function(e,t){e==="value"&&(this.options.value=t,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),this._super(e,t)},_value:function(){var e=this.options.value;return typeof e!="number"&&(e=0),Math.min(this.options.max,Math.max(this.min,e))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var e=this.value(),t=this._percentage();this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),this.valueDiv.toggle(e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(t.toFixed(0)+"%"),this.element.attr("aria-valuenow",e)}})})(jQuery);(function(e,t){var n=5;e.widget("ui.slider",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var t,r,i=this.options,s=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),o="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",u=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(i.disabled?" ui-slider-disabled ui-disabled":"")),this.range=e([]),i.range&&(i.range===!0&&(i.values||(i.values=[this._valueMin(),this._valueMin()]),i.values.length&&i.values.length!==2&&(i.values=[i.values[0],i.values[0]])),this.range=e("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(i.range==="min"||i.range==="max"?" ui-slider-range-"+i.range:""))),r=i.values&&i.values.length||1;for(t=s.length;t<r;t++)u.push(o);this.handles=s.add(e(u.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(e){e.preventDefault()}).mouseenter(function(){i.disabled||e(this).addClass("ui-state-hover")}).mouseleave(function(){e(this).removeClass("ui-state-hover")}).focus(function(){i.disabled?e(this).blur():(e(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),e(this).addClass("ui-state-focus"))}).blur(function(){e(this).removeClass("ui-state-focus")}),this.handles.each(function(t){e(this).data("ui-slider-handle-index",t)}),this._on(this.handles,{keydown:function(t){var r,i,s,o,u=e(t.target).data("ui-slider-handle-index");switch(t.keyCode){case e.ui.keyCode.HOME:case e.ui.keyCode.END:case e.ui.keyCode.PAGE_UP:case e.ui.keyCode.PAGE_DOWN:case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:t.preventDefault();if(!this._keySliding){this._keySliding=!0,e(t.target).addClass("ui-state-active"),r=this._start(t,u);if(r===!1)return}}o=this.options.step,this.options.values&&this.options.values.length?i=s=this.values(u):i=s=this.value();switch(t.keyCode){case e.ui.keyCode.HOME:s=this._valueMin();break;case e.ui.keyCode.END:s=this._valueMax();break;case e.ui.keyCode.PAGE_UP:s=this._trimAlignValue(i+(this._valueMax()-this._valueMin())/n);break;case e.ui.keyCode.PAGE_DOWN:s=this._trimAlignValue(i-(this._valueMax()-this._valueMin())/n);break;case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:if(i===this._valueMax())return;s=this._trimAlignValue(i+o);break;case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(i===this._valueMin())return;s=this._trimAlignValue(i-o)}this._slide(t,u,s)},keyup:function(t){var n=e(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,n),this._change(t,n),e(t.target).removeClass("ui-state-active"))}}),this._refreshValue(),this._animateOff=!1},_destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(t){var n,r,i,s,o,u,a,f,l=this,c=this.options;return c.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),n={x:t.pageX,y:t.pageY},r=this._normValueFromMouse(n),i=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var n=Math.abs(r-l.values(t));i>n&&(i=n,s=e(this),o=t)}),c.range===!0&&this.values(1)===c.min&&(o+=1,s=e(this.handles[o])),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n<r)&&(n=r),n!==this.values(t)&&(i=this.values(),i[t]=n,s=this._trigger("slide",e,{handle:this.handles[t],value:n,values:i}),r=this.values(t?0:1),s!==!1&&this.values(t,n,!0))):n!==this.value()&&(s=this._trigger("slide",e,{handle:this.handles[t],value:n}),s!==!1&&this.value(n))},_stop:function(e,t){var n={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("stop",e,n)},_change:function(e,t){if(!this._keySliding&&!this._mouseSliding){var n={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("change",e,n)}},value:function(e){if(arguments.length){this.options.value=this._trimAlignValue(e),this._refreshValue(),this._change(null,0);return}return this._value()},values:function(t,n){var r,i,s;if(arguments.length>1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s<r.length;s+=1)r[s]=this._trimAlignValue(i[s]),this._change(null,s);this._refreshValue()},_setOption:function(t,n){var r,i=0;e.isArray(this.options.values)&&(i=this.options.values.length),e.Widget.prototype._setOption.apply(this,arguments);switch(t){case"disabled":n?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.prop("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.prop("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(r=0;r<i;r+=1)this._change(null,r);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1}},_value:function(){var e=this.options.value;return e=this._trimAlignValue(e),e},_values:function(e){var t,n,r;if(arguments.length)return t=this.options.values[e],t=this._trimAlignValue(t),t;n=this.options.values.slice();for(r=0;r<n.length;r+=1)n[r]=this._trimAlignValue(n[r]);return n},_trimAlignValue:function(e){if(e<=this._valueMin())return this._valueMin();if(e>=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))}})})(jQuery);(function(e){function t(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.widget("ui.spinner",{version:"1.9.2",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e<r.min?r.min:e},_stop:function(e){if(!this.spinning)return;clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",e)},_setOption:function(e,t){if(e==="culture"||e==="numberFormat"){var n=this._parse(this.element.val());this.options[e]=t,this.element.val(this._format(n));return}(e==="max"||e==="min"||e==="step")&&typeof t=="string"&&(t=this._parse(t)),this._super(e,t),e==="disabled"&&(t?(this.element.prop("disabled",!0),this.buttons.button("disable")):(this.element.prop("disabled",!1),this.buttons.button("enable")))},_setOptions:t(function(e){this._super(e),this._value(this.element.val())}),_parse:function(e){return typeof e=="string"&&e!==""&&(e=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(e,10,this.options.culture):+e),e===""||isNaN(e)?null:e},_format:function(e){return e===""?"":window.Globalize&&this.options.numberFormat?Globalize.format(e,this.options.numberFormat,this.options.culture):e},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},_value:function(e,t){var n;e!==""&&(n=this._parse(e),n!==null&&(t||(n=this._adjustValue(n)),e=this._format(n))),this.element.val(e),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:t(function(e){this._stepUp(e)}),_stepUp:function(e){this._spin((e||1)*this.options.step)},stepDown:t(function(e){this._stepDown(e)}),_stepDown:function(e){this._spin((e||1)*-this.options.step)},pageUp:t(function(e){this._stepUp((e||1)*this.options.page)}),pageDown:t(function(e){this._stepDown((e||1)*this.options.page)}),value:function(e){if(!arguments.length)return this._parse(this.element.val());t(this._value).call(this,e)},widget:function(){return this.uiSpinner}})})(jQuery);(function(e,t){function i(){return++n}function s(e){return e.hash.length>1&&e.href.replace(r,"")===location.href.replace(r,"").replace(/\s/g,"%20")}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.9.2",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t=this,n=this.options,r=n.active,i=location.hash.substring(1);this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",n.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs();if(r===null){i&&this.tabs.each(function(t,n){if(e(n).attr("aria-controls")===i)return r=t,!1}),r===null&&(r=this.tabs.index(this.tabs.filter(".ui-tabs-active")));if(r===null||r===-1)r=this.tabs.length?0:!1}r!==!1&&(r=this.tabs.index(this.tabs.eq(r)),r===-1&&(r=n.collapsible?!1:0)),n.active=r,!n.collapsible&&n.active===!1&&this.anchors.length&&(n.active=0),e.isArray(n.disabled)&&(n.disabled=e.unique(n.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(this.options.active):this.active=e(),this._refresh(),this.active.length&&this.load(n.active)},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,n=this.tablist.children(":has(a[href])");t.disabled=e.map(n.filter(".ui-state-disabled"),function(e){return n.index(e)}),this._processTabs(),t.active===!1||!this.anchors.length?(t.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("<div>").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r,i=this.element.parent();t==="fill"?(e.support.minHeight||(r=i.css("overflow"),i.css("overflow","hidden")),n=i.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),r&&i.css("overflow",r),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n):t.removeAttr("aria-controls")}),this.panels.show(),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}}),e.uiBackCompat!==!1&&(e.ui.tabs.prototype._ui=function(e,t){return{tab:e,panel:t,index:this.anchors.index(e)}},e.widget("ui.tabs",e.ui.tabs,{url:function(e,t){this.anchors.eq(e).attr("href",t)}}),e.widget("ui.tabs",e.ui.tabs,{options:{ajaxOptions:null,cache:!1},_create:function(){this._super();var t=this;this._on({tabsbeforeload:function(n,r){if(e.data(r.tab[0],"cache.tabs")){n.preventDefault();return}r.jqXHR.success(function(){t.options.cache&&e.data(r.tab[0],"cache.tabs",!0)})}})},_ajaxSettings:function(t,n,r){var i=this.options.ajaxOptions;return e.extend({},i,{error:function(e,t){try{i.error(e,t,r.tab.closest("li").index(),r.tab[0])}catch(n){}}},this._superApply(arguments))},_setOption:function(e,t){e==="cache"&&t===!1&&this.anchors.removeData("cache.tabs"),this._super(e,t)},_destroy:function(){this.anchors.removeData("cache.tabs"),this._super()},url:function(e){this.anchors.eq(e).removeData("cache.tabs"),this._superApply(arguments)}}),e.widget("ui.tabs",e.ui.tabs,{abort:function(){this.xhr&&this.xhr.abort()}}),e.widget("ui.tabs",e.ui.tabs,{options:{spinner:"<em>Loading&#8230;</em>"},_create:function(){this._super(),this._on({tabsbeforeload:function(e,t){if(e.target!==this.element[0]||!this.options.spinner)return;var n=t.tab.find("span"),r=n.html();n.html(this.options.spinner),t.jqXHR.complete(function(){n.html(r)})}})}}),e.widget("ui.tabs",e.ui.tabs,{options:{enable:null,disable:null},enable:function(t){var n=this.options,r;if(t&&n.disabled===!0||e.isArray(n.disabled)&&e.inArray(t,n.disabled)!==-1)r=!0;this._superApply(arguments),r&&this._trigger("enable",null,this._ui(this.anchors[t],this.panels[t]))},disable:function(t){var n=this.options,r;if(t&&n.disabled===!1||e.isArray(n.disabled)&&e.inArray(t,n.disabled)===-1)r=!0;this._superApply(arguments),r&&this._trigger("disable",null,this._ui(this.anchors[t],this.panels[t]))}}),e.widget("ui.tabs",e.ui.tabs,{options:{add:null,remove:null,tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},add:function(n,r,i){i===t&&(i=this.anchors.length);var s,o,u=this.options,a=e(u.tabTemplate.replace(/#\{href\}/g,n).replace(/#\{label\}/g,r)),f=n.indexOf("#")?this._tabId(a):n.replace("#","");return a.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",!0),a.attr("aria-controls",f),s=i>=this.tabs.length,o=this.element.find("#"+f),o.length||(o=this._createPanel(f),s?i>0?o.insertAfter(this.panels.eq(-1)):o.appendTo(this.element):o.insertBefore(this.panels[i])),o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(),s?a.appendTo(this.tablist):a.insertBefore(this.tabs[i]),u.disabled=e.map(u.disabled,function(e){return e>=i?++e:e}),this.refresh(),this.tabs.length===1&&u.active===!1&&this.option("active",0),this._trigger("add",null,this._ui(this.anchors[i],this.panels[i])),this},remove:function(t){t=this._getIndex(t);var n=this.options,r=this.tabs.eq(t).remove(),i=this._getPanelForTab(r).remove();return r.hasClass("ui-tabs-active")&&this.anchors.length>2&&this._activate(t+(t+1<this.anchors.length?1:-1)),n.disabled=e.map(e.grep(n.disabled,function(e){return e!==t}),function(e){return e>=t?--e:e}),this.refresh(),this._trigger("remove",null,this._ui(r.find("a")[0],i[0])),this}}),e.widget("ui.tabs",e.ui.tabs,{length:function(){return this.anchors.length}}),e.widget("ui.tabs",e.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(t){var n=t.is("li")?t.find("a[href]"):t;return n=n[0],e(n).closest("li").attr("aria-controls")||n.title&&n.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+i()}}),e.widget("ui.tabs",e.ui.tabs,{options:{panelTemplate:"<div></div>"},_createPanel:function(t){return e(this.options.panelTemplate).attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)}}),e.widget("ui.tabs",e.ui.tabs,{_create:function(){var e=this.options;e.active===null&&e.selected!==t&&(e.active=e.selected===-1?!1:e.selected),this._super(),e.selected=e.active,e.selected===!1&&(e.selected=-1)},_setOption:function(e,t){if(e!=="selected")return this._super(e,t);var n=this.options;this._super("active",t===-1?!1:t),n.selected=n.active,n.selected===!1&&(n.selected=-1)},_eventHandler:function(){this._superApply(arguments),this.options.selected=this.options.active,this.options.selected===!1&&(this.options.selected=-1)}}),e.widget("ui.tabs",e.ui.tabs,{options:{show:null,select:null},_create:function(){this._super(),this.options.active!==!1&&this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))},_trigger:function(e,t,n){var r,i,s=this._superApply(arguments);return s?(e==="beforeActivate"?(r=n.newTab.length?n.newTab:n.oldTab,i=n.newPanel.length?n.newPanel:n.oldPanel,s=this._super("select",t,{tab:r.find(".ui-tabs-anchor")[0],panel:i[0],index:r.closest("li").index()})):e==="activate"&&n.newTab.length&&(s=this._super("show",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()})),s):!1}}),e.widget("ui.tabs",e.ui.tabs,{select:function(e){e=this._getIndex(e);if(e===-1){if(!this.options.collapsible||this.options.selected===-1)return;e=this.options.selected}this.anchors.eq(e).trigger(this.options.event+this.eventNamespace)}}),function(){var t=0;e.widget("ui.tabs",e.ui.tabs,{options:{cookie:null},_create:function(){var e=this.options,t;e.active==null&&e.cookie&&(t=parseInt(this._cookie(),10),t===-1&&(t=!1),e.active=t),this._super()},_cookie:function(n){var r=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++t)];return arguments.length&&(r.push(n===!1?-1:n),r.push(this.options.cookie)),e.cookie.apply(null,r)},_refresh:function(){this._super(),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_eventHandler:function(){this._superApply(arguments),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super(),this.options.cookie&&this._cookie(null,this.options.cookie)}})}(),e.widget("ui.tabs",e.ui.tabs,{_trigger:function(t,n,r){var i=e.extend({},r);return t==="load"&&(i.panel=i.panel[0],i.tab=i.tab.find(".ui-tabs-anchor")[0]),this._super(t,n,i)}}),e.widget("ui.tabs",e.ui.tabs,{options:{fx:null},_getFx:function(){var t,n,r=this.options.fx;return r&&(e.isArray(r)?(t=r[0],n=r[1]):t=n=r),r?{show:n,hide:t}:null},_toggle:function(e,t){function o(){n.running=!1,n._trigger("activate",e,t)}function u(){t.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&s.show?r.animate(s.show,s.show.duration,function(){o()}):(r.show(),o())}var n=this,r=t.newPanel,i=t.oldPanel,s=this._getFx();if(!s)return this._super(e,t);n.running=!0,i.length&&s.hide?i.animate(s.hide,s.hide.duration,function(){t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),i.hide(),u())}}))})(jQuery);(function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.9.2",options:{content:function(){return e(this).attr("title")},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=this,r=e(t?t.target:this.element).closest(this.options.items);if(!r.length||r.data("ui-tooltip-id"))return;r.attr("title")&&r.data("ui-tooltip-title",r.attr("title")),r.data("ui-tooltip-open",!0),t&&t.type==="mouseover"&&r.parents().each(function(){var t=e(this),r;t.data("ui-tooltip-open")&&(r=e.Event("blur"),r.target=r.currentTarget=this,n.close(r,!0)),t.attr("title")&&(t.uniqueId(),n.parents[this.id]={element:this,title:t.attr("title")},t.attr("title",""))}),this._updateContent(r,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this,s=t?t.type:null;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("ui-tooltip-open"))return;i._delay(function(){t&&(t.type=s),this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function f(e){a.of=e;if(s.is(":hidden"))return;s.position(a)}var s,o,u,a=e.extend({},this.options.position);if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:f}),f(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this.options.show&&this.options.show.delay&&(u=setInterval(function(){s.is(":visible")&&(f(a.of),clearInterval(u))},e.fx.interval)),this._trigger("open",t,{tooltip:s}),o={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}},remove:function(){this._removeTooltip(s)}};if(!t||t.type==="mouseover")o.mouseleave="close";if(!t||t.type==="focusin")o.focusout="close";this._on(!0,r,o)},close:function(t){var n=this,i=e(t?t.currentTarget:this.element),s=this._find(i);if(this.closing)return;i.data("ui-tooltip-title")&&i.attr("title",i.data("ui-tooltip-title")),r(i),s.stop(!0),this._hide(s,this.options.hide,function(){n._removeTooltip(e(this))}),i.removeData("ui-tooltip-open"),this._off(i,"mouseleave focusout keyup"),i[0]!==this.element[0]&&this._off(i,"remove"),this._off(this.document,"mousemove"),t&&t.type==="mouseleave"&&e.each(this.parents,function(t,r){e(r.element).attr("title",r.title),delete n.parents[t]}),this.closing=!0,this._trigger("close",t,{tooltip:s}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("<div>").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("<div>").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),e.fn.bgiframe&&i.bgiframe(),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})})(jQuery);jQuery.effects||function(e,t){var n=e.uiBackCompat!==!1,r="ui-effects-";e.effects={effect:{}},function(t,n){function p(e,t,n){var r=a[t.type]||{};return e==null?n||!t.def?null:t.def:(e=r.floor?~~e:parseFloat(e),isNaN(e)?t.def:r.mod?(e+r.mod)%r.mod:0>e?0:r.max<e?r.max:e)}function d(e){var n=o(),r=n._rgba=[];return e=e.toLowerCase(),h(s,function(t,i){var s,o=i.re.exec(e),a=o&&i.parse(o),f=i.space||"rgba";if(a)return s=n[f](a),n[u[f].cache]=s[u[f].cache],r=n._rgba=s._rgba,!1}),r.length?(r.join()==="0,0,0,0"&&t.extend(r,c.transparent),n):c[e]}function v(e,t,n){return n=(n+1)%1,n*6<1?e+(t-e)*n*6:n*2<1?t:n*3<2?e+(t-e)*(2/3-n)*6:e}var r="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),i=/^([\-+])=\s*(\d+\.?\d*)/,s=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1],e[2],e[3],e[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1]*2.55,e[2]*2.55,e[3]*2.55,e[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(e){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(e){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(e){return[e[1],e[2]/100,e[3]/100,e[4]]}}],o=t.Color=function(e,n,r,i){return new t.Color.fn.parse(e,n,r,i)},u={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},a={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},f=o.support={},l=t("<p>")[0],c,h=t.each;l.style.cssText="background-color:rgba(1,1,1,.5)",f.rgba=l.style.backgroundColor.indexOf("rgba")>-1,h(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),o.fn=t.extend(o.prototype,{parse:function(r,i,s,a){if(r===n)return this._rgba=[null,null,null,null],this;if(r.jquery||r.nodeType)r=t(r).css(i),i=n;var f=this,l=t.type(r),v=this._rgba=[];i!==n&&(r=[r,i,s,a],l="array");if(l==="string")return this.parse(d(r)||c._default);if(l==="array")return h(u.rgba.props,function(e,t){v[t.idx]=p(r[t.idx],t)}),this;if(l==="object")return r instanceof o?h(u,function(e,t){r[t.cache]&&(f[t.cache]=r[t.cache].slice())}):h(u,function(t,n){var i=n.cache;h(n.props,function(e,t){if(!f[i]&&n.to){if(e==="alpha"||r[e]==null)return;f[i]=n.to(f._rgba)}f[i][t.idx]=p(r[e],t,!0)}),f[i]&&e.inArray(null,f[i].slice(0,3))<0&&(f[i][3]=1,n.from&&(f._rgba=n.from(f[i])))}),this},is:function(e){var t=o(e),n=!0,r=this;return h(u,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],h(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return h(u,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=o(e),r=n._space(),i=u[r],s=this.alpha()===0?o("transparent"):this,f=s[i.cache]||i.to(s._rgba),l=f.slice();return n=n[i.cache],h(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],u=a[r.type]||{};if(o===null)return;s===null?l[i]=o:(u.mod&&(o-s>u.mod/2?s+=u.mod:s-o>u.mod/2&&(s-=u.mod)),l[i]=p((o-s)*t+s,r))}),this[r](l)},blend:function(e){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=o(e)._rgba;return o(t.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var e="rgba(",n=t.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),e="rgb("),e+n.join()+")"},toHslaString:function(){var e="hsla(",n=t.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),e="hsl("),e+n.join()+")"},toHexString:function(e){var n=this._rgba.slice(),r=n.pop();return e&&n.push(~~(r*255)),"#"+t.map(n,function(e){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),o.fn.parse.prototype=o.fn,u.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,f===0||f===1?c=f:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},u.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s;return[Math.round(v(o,s,t+1/3)*255),Math.round(v(o,s,t)*255),Math.round(v(o,s,t-1/3)*255),i]},h(u,function(e,r){var s=r.props,u=r.cache,a=r.to,f=r.from;o.fn[e]=function(e){a&&!this[u]&&(this[u]=a(this._rgba));if(e===n)return this[u].slice();var r,i=t.type(e),l=i==="array"||i==="object"?e:arguments,c=this[u].slice();return h(s,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=c[t.idx]),c[t.idx]=p(n,t)}),f?(r=o(f(c)),r[u]=c,r):o(c)},h(s,function(n,r){if(o.fn[n])return;o.fn[n]=function(s){var o=t.type(s),u=n==="alpha"?this._hsla?"hsla":"rgba":e,a=this[u](),f=a[r.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=t.type(s)),s==null&&r.empty?this:(o==="string"&&(l=i.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[r.idx]=s,this[u](a)))}})}),h(r,function(e,n){t.cssHooks[n]={set:function(e,r){var i,s,u="";if(t.type(r)!=="string"||(i=d(r))){r=o(i||r);if(!f.rgba&&r._rgba[3]!==1){s=n==="backgroundColor"?e.parentNode:e;while((u===""||u==="transparent")&&s&&s.style)try{u=t.css(s,"backgroundColor"),s=s.parentNode}catch(a){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{e.style[n]=r}catch(l){}}},t.fx.step[n]=function(e){e.colorInit||(e.start=o(e.elem,n),e.end=o(e.end),e.colorInit=!0),t.cssHooks[n].set(e.elem,e.start.transition(e.end,e.pos))}}),t.cssHooks.borderColor={expand:function(e){var t={};return h(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},c=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(){var t=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,n={},r,i;if(t&&t.length&&t[0]&&t[t[0]]){i=t.length;while(i--)r=t[i],typeof t[r]=="string"&&(n[e.camelCase(r)]=t[r])}else for(r in t)typeof t[r]=="string"&&(n[r]=t[r]);return n}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").andSelf():r;f=f.map(function(){var t=e(this);return{el:t,start:i.call(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i.call(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=jQuery.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass(t)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function i(t,n,r,i){e.isPlainObject(t)&&(n=t,t=t.effect),t={effect:t},n==null&&(n={}),e.isFunction(n)&&(i=n,r=null,n={});if(typeof n=="number"||e.fx.speeds[n])i=r,r=n,n={};return e.isFunction(r)&&(i=r,r=null),n&&e.extend(t,n),r=r||n.duration,t.duration=e.fx.off?0:typeof r=="number"?r:r in e.fx.speeds?e.fx.speeds[r]:e.fx.speeds._default,t.complete=i||n.complete,t}function s(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]?n&&e.effects[t]?!1:!0:!1}e.extend(e.effects,{version:"1.9.2",save:function(e,t){for(var n=0;n<t.length;n++)t[n]!==null&&e.data(r+t[n],e[0].style[t[n]])},restore:function(e,n){var i,s;for(s=0;s<n.length;s++)n[s]!==null&&(i=e.data(r+n[s]),i===t&&(i=""),e.css(n[s],i))},setMode:function(e,t){return t==="toggle"&&(t=e.is(":hidden")?"show":"hide"),t},getBaseline:function(e,t){var n,r;switch(e[0]){case"top":n=0;break;case"middle":n=.5;break;case"bottom":n=1;break;default:n=e[0]/t.height}switch(e[1]){case"left":r=0;break;case"center":r=.5;break;case"right":r=1;break;default:r=e[1]/t.width}return{x:r,y:n}},createWrapper:function(t){if(t.parent().is(".ui-effects-wrapper"))return t.parent();var n={width:t.outerWidth(!0),height:t.outerHeight(!0),"float":t.css("float")},r=e("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(){function a(n){function u(){e.isFunction(i)&&i.call(r[0]),e.isFunction(n)&&n()}var r=e(this),i=t.complete,s=t.mode;(r.is(":hidden")?s==="hide":s==="show")?u():o.call(r[0],t,u)}var t=i.apply(this,arguments),r=t.mode,s=t.queue,o=e.effects.effect[t.effect],u=!o&&n&&e.effects[t.effect];return e.fx.off||!o&&!u?r?this[r](t.duration,t.complete):this.each(function(){t.complete&&t.complete.call(this)}):o?s===!1?this.each(a):this.queue(s||"fx",a):u.call(this,{options:t,duration:t.duration,callback:t.complete,mode:t.mode})},_show:e.fn.show,show:function(e){if(s(e))return this._show.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(s(e))return this._hide.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(s(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=i.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery);(function(e,t){var n=/up|down|vertical/,r=/up|left|vertical|horizontal/;e.effects.effect.blind=function(t,i){var s=e(this),o=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(s,t.mode||"hide"),a=t.direction||"up",f=n.test(a),l=f?"height":"width",c=f?"top":"left",h=r.test(a),p={},d=u==="show",v,m,g;s.parent().is(".ui-effects-wrapper")?e.effects.save(s.parent(),o):e.effects.save(s,o),s.show(),v=e.effects.createWrapper(s).css({overflow:"hidden"}),m=v[l](),g=parseFloat(v.css(c))||0,p[l]=d?m:0,h||(s.css(f?"bottom":"right",0).css(f?"top":"left","auto").css({position:"absolute"}),p[c]=d?g:m+g),d&&(v.css(l,0),h||v.css(c,g+m)),v.animate(p,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){u==="hide"&&s.hide(),e.effects.restore(s,o),e.effects.removeWrapper(s),i()}})}})(jQuery);(function(e,t){e.effects.effect.bounce=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=s==="hide",u=s==="show",a=t.direction||"up",f=t.distance,l=t.times||5,c=l*2+(u||o?1:0),h=t.duration/c,p=t.easing,d=a==="up"||a==="down"?"top":"left",v=a==="up"||a==="left",m,g,y,b=r.queue(),w=b.length;(u||o)&&i.push("opacity"),e.effects.save(r,i),r.show(),e.effects.createWrapper(r),f||(f=r[d==="top"?"outerHeight":"outerWidth"]()/3),u&&(y={opacity:1},y[d]=0,r.css("opacity",0).css(d,v?-f*2:f*2).animate(y,h,p)),o&&(f/=Math.pow(2,l-1)),y={},y[d]=0;for(m=0;m<l;m++)g={},g[d]=(v?"-=":"+=")+f,r.animate(g,h,p).animate(y,h,p),f=o?f*2:f/2;o&&(g={opacity:0},g[d]=(v?"-=":"+=")+f,r.animate(g,h,p)),r.queue(function(){o&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}),w>1&&b.splice.apply(b,[1,0].concat(b.splice(w,c+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.clip=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"vertical",a=u==="vertical",f=a?"height":"width",l=a?"top":"left",c={},h,p,d;e.effects.save(r,i),r.show(),h=e.effects.createWrapper(r).css({overflow:"hidden"}),p=r[0].tagName==="IMG"?h:r,d=p[f](),o&&(p.css(f,0),p.css(l,d/2)),c[f]=o?d:0,c[l]=o?0:d/2,p.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o||r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.drop=function(t,n){var r=e(this),i=["position","top","bottom","left","right","opacity","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left"?"pos":"neg",l={opacity:o?1:0},c;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),c=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0)/2,o&&r.css("opacity",0).css(a,f==="pos"?-c:c),l[a]=(o?f==="pos"?"+=":"-=":f==="pos"?"-=":"+=")+c,r.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.explode=function(t,n){function y(){c.push(this),c.length===r*i&&b()}function b(){s.css({visibility:"visible"}),e(c).remove(),u||s.hide(),n()}var r=t.pieces?Math.round(Math.sqrt(t.pieces)):3,i=r,s=e(this),o=e.effects.setMode(s,t.mode||"hide"),u=o==="show",a=s.show().css("visibility","hidden").offset(),f=Math.ceil(s.outerWidth()/i),l=Math.ceil(s.outerHeight()/r),c=[],h,p,d,v,m,g;for(h=0;h<r;h++){v=a.top+h*l,g=h-(r-1)/2;for(p=0;p<i;p++)d=a.left+p*f,m=p-(i-1)/2,s.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-p*f,top:-h*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:f,height:l,left:d+(u?m*f:0),top:v+(u?g*l:0),opacity:u?0:1}).animate({left:d+(u?0:m*f),top:v+(u?0:g*l),opacity:u?1:0},t.duration||500,t.easing,y)}}})(jQuery);(function(e,t){e.effects.effect.fade=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"toggle");r.animate({opacity:i},{queue:!1,duration:t.duration,easing:t.easing,complete:n})}})(jQuery);(function(e,t){e.effects.effect.fold=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=s==="hide",a=t.size||15,f=/([0-9]+)%/.exec(a),l=!!t.horizFirst,c=o!==l,h=c?["width","height"]:["height","width"],p=t.duration/2,d,v,m={},g={};e.effects.save(r,i),r.show(),d=e.effects.createWrapper(r).css({overflow:"hidden"}),v=c?[d.width(),d.height()]:[d.height(),d.width()],f&&(a=parseInt(f[1],10)/100*v[u?0:1]),o&&d.css(l?{height:0,width:a}:{height:a,width:0}),m[h[0]]=o?v[0]:a,g[h[1]]=o?v[1]:0,d.animate(m,p,t.easing).animate(g,p,t.easing,function(){u&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()})}})(jQuery);(function(e,t){e.effects.effect.highlight=function(t,n){var r=e(this),i=["backgroundImage","backgroundColor","opacity"],s=e.effects.setMode(r,t.mode||"show"),o={backgroundColor:r.css("backgroundColor")};s==="hide"&&(o.opacity=0),e.effects.save(r,i),r.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),n()}})}})(jQuery);(function(e,t){e.effects.effect.pulsate=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"show"),s=i==="show",o=i==="hide",u=s||i==="hide",a=(t.times||5)*2+(u?1:0),f=t.duration/a,l=0,c=r.queue(),h=c.length,p;if(s||!r.is(":visible"))r.css("opacity",0).show(),l=1;for(p=1;p<a;p++)r.animate({opacity:l},f,t.easing),l=1-l;r.animate({opacity:l},f,t.easing),r.queue(function(){o&&r.hide(),n()}),h>1&&c.splice.apply(c,[1,0].concat(c.splice(h,a+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.puff=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"hide"),s=i==="hide",o=parseInt(t.percent,10)||150,u=o/100,a={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:i,complete:n,percent:s?o:100,from:s?a:{height:a.height*u,width:a.width*u,outerHeight:a.outerHeight*u,outerWidth:a.outerWidth*u}}),r.effect(t)},e.effects.effect.scale=function(t,n){var r=e(this),i=e.extend(!0,{},t),s=e.effects.setMode(r,t.mode||"effect"),o=parseInt(t.percent,10)||(parseInt(t.percent,10)===0?0:s==="hide"?0:100),u=t.direction||"both",a=t.origin,f={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},l={y:u!=="horizontal"?o/100:1,x:u!=="vertical"?o/100:1};i.effect="size",i.queue=!1,i.complete=n,s!=="effect"&&(i.origin=a||["middle","center"],i.restore=!0),i.from=t.from||(s==="show"?{height:0,width:0,outerHeight:0,outerWidth:0}:f),i.to={height:f.height*l.y,width:f.width*l.x,outerHeight:f.outerHeight*l.y,outerWidth:f.outerWidth*l.x},i.fade&&(s==="show"&&(i.from.opacity=0,i.to.opacity=1),s==="hide"&&(i.from.opacity=1,i.to.opacity=0)),r.effect(i)},e.effects.effect.size=function(t,n){var r,i,s,o=e(this),u=["position","top","bottom","left","right","width","height","overflow","opacity"],a=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],l=["fontSize"],c=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],h=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(o,t.mode||"effect"),d=t.restore||p!=="effect",v=t.scale||"both",m=t.origin||["middle","center"],g=o.css("position"),y=d?u:a,b={height:0,width:0,outerHeight:0,outerWidth:0};p==="show"&&o.show(),r={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},t.mode==="toggle"&&p==="show"?(o.from=t.to||b,o.to=t.from||r):(o.from=t.from||(p==="show"?b:r),o.to=t.to||(p==="hide"?b:r)),s={from:{y:o.from.height/r.height,x:o.from.width/r.width},to:{y:o.to.height/r.height,x:o.to.width/r.width}};if(v==="box"||v==="both")s.from.y!==s.to.y&&(y=y.concat(c),o.from=e.effects.setTransition(o,c,s.from.y,o.from),o.to=e.effects.setTransition(o,c,s.to.y,o.to)),s.from.x!==s.to.x&&(y=y.concat(h),o.from=e.effects.setTransition(o,h,s.from.x,o.from),o.to=e.effects.setTransition(o,h,s.to.x,o.to));(v==="content"||v==="both")&&s.from.y!==s.to.y&&(y=y.concat(l).concat(f),o.from=e.effects.setTransition(o,l,s.from.y,o.from),o.to=e.effects.setTransition(o,l,s.to.y,o.to)),e.effects.save(o,y),o.show(),e.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),m&&(i=e.effects.getBaseline(m,r),o.from.top=(r.outerHeight-o.outerHeight())*i.y,o.from.left=(r.outerWidth-o.outerWidth())*i.x,o.to.top=(r.outerHeight-o.to.outerHeight)*i.y,o.to.left=(r.outerWidth-o.to.outerWidth)*i.x),o.css(o.from);if(v==="content"||v==="both")c=c.concat(["marginTop","marginBottom"]).concat(l),h=h.concat(["marginLeft","marginRight"]),f=u.concat(c).concat(h),o.find("*[width]").each(function(){var n=e(this),r={height:n.height(),width:n.width(),outerHeight:n.outerHeight(),outerWidth:n.outerWidth()};d&&e.effects.save(n,f),n.from={height:r.height*s.from.y,width:r.width*s.from.x,outerHeight:r.outerHeight*s.from.y,outerWidth:r.outerWidth*s.from.x},n.to={height:r.height*s.to.y,width:r.width*s.to.x,outerHeight:r.height*s.to.y,outerWidth:r.width*s.to.x},s.from.y!==s.to.y&&(n.from=e.effects.setTransition(n,c,s.from.y,n.from),n.to=e.effects.setTransition(n,c,s.to.y,n.to)),s.from.x!==s.to.x&&(n.from=e.effects.setTransition(n,h,s.from.x,n.from),n.to=e.effects.setTransition(n,h,s.to.x,n.to)),n.css(n.from),n.animate(n.to,t.duration,t.easing,function(){d&&e.effects.restore(n,f)})});o.animate(o.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o.to.opacity===0&&o.css("opacity",o.from.opacity),p==="hide"&&o.hide(),e.effects.restore(o,y),d||(g==="static"?o.css({position:"relative",top:o.to.top,left:o.to.left}):e.each(["top","left"],function(e,t){o.css(t,function(t,n){var r=parseInt(n,10),i=e?o.to.left:o.to.top;return n==="auto"?i+"px":r+i+"px"})})),e.effects.removeWrapper(o),n()}})}})(jQuery);(function(e,t){e.effects.effect.shake=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=t.direction||"left",u=t.distance||20,a=t.times||3,f=a*2+1,l=Math.round(t.duration/f),c=o==="up"||o==="down"?"top":"left",h=o==="up"||o==="left",p={},d={},v={},m,g=r.queue(),y=g.length;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),p[c]=(h?"-=":"+=")+u,d[c]=(h?"+=":"-=")+u*2,v[c]=(h?"-=":"+=")+u*2,r.animate(p,l,t.easing);for(m=1;m<a;m++)r.animate(d,l,t.easing).animate(v,l,t.easing);r.animate(d,l,t.easing).animate(p,l/2,t.easing).queue(function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}),y>1&&g.splice.apply(g,[1,0].concat(g.splice(y,f+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.slide=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height"],s=e.effects.setMode(r,t.mode||"show"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left",l,c={};e.effects.save(r,i),r.show(),l=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(r).css({overflow:"hidden"}),o&&r.css(a,f?isNaN(l)?"-"+l:-l:l),c[a]=(o?f?"+=":"-=":f?"-=":"+=")+l,r.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.transfer=function(t,n){var r=e(this),i=e(t.to),s=i.css("position")==="fixed",o=e("body"),u=s?o.scrollTop():0,a=s?o.scrollLeft():0,f=i.offset(),l={top:f.top-u,left:f.left-a,height:i.innerHeight(),width:i.innerWidth()},c=r.offset(),h=e('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(t.className).css({top:c.top-u,left:c.left-a,height:r.innerHeight(),width:r.innerWidth(),position:s?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){h.remove(),n()})}})(jQuery);
+
+/* JQuery UJS 2.0.3 */
+(function(a,b){var c=function(){var b=a(document).data("events");return b&&b.click&&a.grep(b.click,function(a){return a.namespace==="rails"}).length};if(c()){a.error("jquery-ujs has already been loaded!")}var d;a.rails=d={linkClickSelector:"a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]",inputChangeSelector:"select[data-remote], input[data-remote], textarea[data-remote]",formSubmitSelector:"form",formInputClickSelector:"form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])",disableSelector:"input[data-disable-with], button[data-disable-with], textarea[data-disable-with]",enableSelector:"input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled",requiredInputSelector:"input[name][required]:not([disabled]),textarea[name][required]:not([disabled])",fileInputSelector:"input:file",linkDisableSelector:"a[data-disable-with]",CSRFProtection:function(b){var c=a('meta[name="csrf-token"]').attr("content");if(c)b.setRequestHeader("X-CSRF-Token",c)},fire:function(b,c,d){var e=a.Event(c);b.trigger(e,d);return e.result!==false},confirm:function(a){return confirm(a)},ajax:function(b){return a.ajax(b)},href:function(a){return a.attr("href")},handleRemote:function(c){var e,f,g,h,i,j,k,l;if(d.fire(c,"ajax:before")){h=c.data("cross-domain");i=h===b?null:h;j=c.data("with-credentials")||null;k=c.data("type")||a.ajaxSettings&&a.ajaxSettings.dataType;if(c.is("form")){e=c.attr("method");f=c.attr("action");g=c.serializeArray();var m=c.data("ujs:submit-button");if(m){g.push(m);c.data("ujs:submit-button",null)}}else if(c.is(d.inputChangeSelector)){e=c.data("method");f=c.data("url");g=c.serialize();if(c.data("params"))g=g+"&"+c.data("params")}else{e=c.data("method");f=d.href(c);g=c.data("params")||null}l={type:e||"GET",data:g,dataType:k,beforeSend:function(a,e){if(e.dataType===b){a.setRequestHeader("accept","*/*;q=0.5, "+e.accepts.script)}return d.fire(c,"ajax:beforeSend",[a,e])},success:function(a,b,d){c.trigger("ajax:success",[a,b,d])},complete:function(a,b){c.trigger("ajax:complete",[a,b])},error:function(a,b,d){c.trigger("ajax:error",[a,b,d])},xhrFields:{withCredentials:j},crossDomain:i};if(f){l.url=f}var n=d.ajax(l);c.trigger("ajax:send",n);return n}else{return false}},handleMethod:function(c){var e=d.href(c),f=c.data("method"),g=c.attr("target"),h=a("meta[name=csrf-token]").attr("content"),i=a("meta[name=csrf-param]").attr("content"),j=a('<form method="post" action="'+e+'"></form>'),k='<input name="_method" value="'+f+'" type="hidden" />';if(i!==b&&h!==b){k+='<input name="'+i+'" value="'+h+'" type="hidden" />'}if(g){j.attr("target",g)}j.hide().append(k).appendTo("body");j.submit()},disableFormElements:function(b){b.find(d.disableSelector).each(function(){var b=a(this),c=b.is("button")?"html":"val";b.data("ujs:enable-with",b[c]());b[c](b.data("disable-with"));b.prop("disabled",true)})},enableFormElements:function(b){b.find(d.enableSelector).each(function(){var b=a(this),c=b.is("button")?"html":"val";if(b.data("ujs:enable-with"))b[c](b.data("ujs:enable-with"));b.prop("disabled",false)})},allowAction:function(a){var b=a.data("confirm"),c=false,e;if(!b){return true}if(d.fire(a,"confirm")){c=d.confirm(b);e=d.fire(a,"confirm:complete",[c])}return c&&e},blankInputs:function(b,c,d){var e=a(),f,g,h=c||"input,textarea";b.find(h).each(function(){f=a(this);g=f.is(":checkbox,:radio")?f.is(":checked"):f.val();if(g==!!d){e=e.add(f)}});return e.length?e:false},nonBlankInputs:function(a,b){return d.blankInputs(a,b,true)},stopEverything:function(b){a(b.target).trigger("ujs:everythingStopped");b.stopImmediatePropagation();return false},callFormSubmitBindings:function(c,d){var e=c.data("events"),f=true;if(e!==b&&e["submit"]!==b){a.each(e["submit"],function(a,b){if(typeof b.handler==="function")return f=b.handler(d)})}return f},disableElement:function(a){a.data("ujs:enable-with",a.html());a.html(a.data("disable-with"));a.bind("click.railsDisable",function(a){return d.stopEverything(a)})},enableElement:function(a){if(a.data("ujs:enable-with")!==b){a.html(a.data("ujs:enable-with"));a.data("ujs:enable-with",false)}a.unbind("click.railsDisable")}};if(d.fire(a(document),"rails:attachBindings")){a.ajaxPrefilter(function(a,b,c){if(!a.crossDomain){d.CSRFProtection(c)}});a(document).delegate(d.linkDisableSelector,"ajax:complete",function(){d.enableElement(a(this))});a(document).delegate(d.linkClickSelector,"click.rails",function(c){var e=a(this),f=e.data("method"),g=e.data("params");if(!d.allowAction(e))return d.stopEverything(c);if(e.is(d.linkDisableSelector))d.disableElement(e);if(e.data("remote")!==b){if((c.metaKey||c.ctrlKey)&&(!f||f==="GET")&&!g){return true}if(d.handleRemote(e)===false){d.enableElement(e)}return false}else if(e.data("method")){d.handleMethod(e);return false}});a(document).delegate(d.inputChangeSelector,"change.rails",function(b){var c=a(this);if(!d.allowAction(c))return d.stopEverything(b);d.handleRemote(c);return false});a(document).delegate(d.formSubmitSelector,"submit.rails",function(c){var e=a(this),f=e.data("remote")!==b,g=d.blankInputs(e,d.requiredInputSelector),h=d.nonBlankInputs(e,d.fileInputSelector);if(!d.allowAction(e))return d.stopEverything(c);if(g&&e.attr("novalidate")==b&&d.fire(e,"ajax:aborted:required",[g])){return d.stopEverything(c)}if(f){if(h){setTimeout(function(){d.disableFormElements(e)},13);return d.fire(e,"ajax:aborted:file",[h])}if(!a.support.submitBubbles&&a().jquery<"1.7"&&d.callFormSubmitBindings(e,c)===false)return d.stopEverything(c);d.handleRemote(e);return false}else{setTimeout(function(){d.disableFormElements(e)},13)}});a(document).delegate(d.formInputClickSelector,"click.rails",function(b){var c=a(this);if(!d.allowAction(c))return d.stopEverything(b);var e=c.attr("name"),f=e?{name:e,value:c.val()}:null;c.closest("form").data("ujs:submit-button",f)});a(document).delegate(d.formSubmitSelector,"ajax:beforeSend.rails",function(b){if(this==b.target)d.disableFormElements(a(this))});a(document).delegate(d.formSubmitSelector,"ajax:complete.rails",function(b){if(this==b.target)d.enableFormElements(a(this))});a(function(){csrf_token=a("meta[name=csrf-token]").attr("content");csrf_param=a("meta[name=csrf-param]").attr("content");a('form input[name="'+csrf_param+'"]').val(csrf_token)})}})(jQuery)
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cb/cb8860bc881def0adbb33f2d3107b033de5fdd84.svn-base
--- a/.svn/pristine/cb/cb8860bc881def0adbb33f2d3107b033de5fdd84.svn-base
+++ /dev/null
@@ -1,69 +0,0 @@
-<div class="contextual">
-<% if @editable %>
-<%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.current_version? %>
-<%= watcher_tag(@page, User.current) %>
-<%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
-<%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
-<%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') if @content.current_version? %>
-<%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %>
-<%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') unless @content.current_version? %>
-<% end %>
-<%= link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %>
-</div>
-
-<%= wiki_page_breadcrumb(@page) %>
-
-<% unless @content.current_version? %>
-    <p>
-    <%= link_to(("\xc2\xab " + l(:label_previous)),
-                :action => 'show', :id => @page.title, :project_id => @page.project,
-                :version => (@content.version - 1)) + " - " if @content.version > 1 %>
-    <%= "#{l(:label_version)} #{@content.version}/#{@page.content.version}" %>
-    <%= '(' + link_to(l(:label_diff), :controller => 'wiki', :action => 'diff',
-                      :id => @page.title, :project_id => @page.project,
-                      :version => @content.version) + ')' if @content.version > 1 %> - 
-    <%= link_to((l(:label_next) + " \xc2\xbb"), :action => 'show',
-                :id => @page.title, :project_id => @page.project,
-                :version => (@content.version + 1)) + " - " if @content.version < @page.content.version %>
-    <%= link_to(l(:label_current_version), :action => 'show', :id => @page.title, :project_id => @page.project) %>
-    <br />
-    <em><%= @content.author ? link_to_user(@content.author) : l(:label_user_anonymous)
-         %>, <%= format_time(@content.updated_on) %> </em><br />
-    <%=h @content.comments %>
-    </p>
-    <hr />
-<% end %>
-
-<%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
-
-<%= link_to_attachments @page %>
-
-<% if @editable && authorize_for('wiki', 'add_attachment') %>
-<div id="wiki_add_attachment">
-<p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
-                                             :id => 'attach_files_link' %></p>
-<% form_tag({ :controller => 'wiki', :action => 'add_attachment', :project_id => @project, :id => @page.title }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
-  <div class="box">
-  <p><%= render :partial => 'attachments/form' %></p>
-  </div>
-<%= submit_tag l(:button_add) %>
-<%= link_to l(:button_cancel), {}, :onclick => "Element.hide('add_attachment_form'); Element.show('attach_files_link'); return false;" %>
-<% end %>
-</div>
-<% end %>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'PDF', :url => {:id => @page.title, :version => params[:version]} %>
-  <%= f.link_to 'HTML', :url => {:id => @page.title, :version => params[:version]} %>
-  <%= f.link_to 'TXT', :url => {:id => @page.title, :version => params[:version]} %>
-<% end if User.current.allowed_to?(:export_wiki_pages, @project) %>
-
-<% content_for :header_tags do %>
-  <%= stylesheet_link_tag 'scm' %>
-<% end %>
-
-<% content_for :sidebar do %>
-  <%= render :partial => 'sidebar' %>
-<% end %>
-
-<% html_title @page.pretty_title %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cb/cb9498d4606605e6e97dd345a7fb3ba9d914a73a.svn-base
--- a/.svn/pristine/cb/cb9498d4606605e6e97dd345a7fb3ba9d914a73a.svn-base
+++ /dev/null
@@ -1,63 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::QueriesTest < ActionController::IntegrationTest
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :queries
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "/queries" do
-    context "GET" do
-
-      should "return queries" do
-        get '/queries.xml'
-
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-        assert_tag :tag => 'queries',
-          :attributes => {:type => 'array'},
-          :child => {
-            :tag => 'query',
-            :child => {
-              :tag => 'id',
-              :content => '4',
-              :sibling => {
-                :tag => 'name',
-                :content => 'Public query for all projects'
-              }
-            }
-          }
-      end
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cb/cbbbbf51cf00f3931cd57d857e449b95b77320ca.svn-base
--- /dev/null
+++ b/.svn/pristine/cb/cbbbbf51cf00f3931cd57d857e449b95b77320ca.svn-base
@@ -0,0 +1,115 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Tracker < ActiveRecord::Base
+
+  CORE_FIELDS_UNDISABLABLE = %w(project_id tracker_id subject description priority_id is_private).freeze
+  # Fields that can be disabled
+  # Other (future) fields should be appended, not inserted!
+  CORE_FIELDS = %w(assigned_to_id category_id fixed_version_id parent_issue_id start_date due_date estimated_hours done_ratio).freeze
+  CORE_FIELDS_ALL = (CORE_FIELDS_UNDISABLABLE + CORE_FIELDS).freeze
+
+  before_destroy :check_integrity
+  has_many :issues
+  has_many :workflow_rules, :dependent => :delete_all do
+    def copy(source_tracker)
+      WorkflowRule.copy(source_tracker, nil, proxy_association.owner, nil)
+    end
+  end
+
+  has_and_belongs_to_many :projects
+  has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :association_foreign_key => 'custom_field_id'
+  acts_as_list
+
+  attr_protected :fields_bits
+
+  validates_presence_of :name
+  validates_uniqueness_of :name
+  validates_length_of :name, :maximum => 30
+
+  scope :sorted, lambda { order("#{table_name}.position ASC") }
+  scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
+
+  def to_s; name end
+
+  def <=>(tracker)
+    position <=> tracker.position
+  end
+
+  # Returns an array of IssueStatus that are used
+  # in the tracker's workflows
+  def issue_statuses
+    if @issue_statuses
+      return @issue_statuses
+    elsif new_record?
+      return []
+    end
+
+    ids = WorkflowTransition.
+            connection.select_rows("SELECT DISTINCT old_status_id, new_status_id FROM #{WorkflowTransition.table_name} WHERE tracker_id = #{id} AND type = 'WorkflowTransition'").
+            flatten.
+            uniq
+
+    @issue_statuses = IssueStatus.find_all_by_id(ids).sort
+  end
+
+  def disabled_core_fields
+    i = -1
+    @disabled_core_fields ||= CORE_FIELDS.select { i += 1; (fields_bits || 0) & (2 ** i) != 0}
+  end
+
+  def core_fields
+    CORE_FIELDS - disabled_core_fields
+  end
+
+  def core_fields=(fields)
+    raise ArgumentError.new("Tracker.core_fields takes an array") unless fields.is_a?(Array)
+
+    bits = 0
+    CORE_FIELDS.each_with_index do |field, i|
+      unless fields.include?(field)
+        bits |= 2 ** i
+      end
+    end
+    self.fields_bits = bits
+    @disabled_core_fields = nil
+    core_fields
+  end
+
+  # Returns the fields that are disabled for all the given trackers
+  def self.disabled_core_fields(trackers)
+    if trackers.present?
+      trackers.uniq.map(&:disabled_core_fields).reduce(:&)
+    else
+      []
+    end
+  end
+
+  # Returns the fields that are enabled for one tracker at least
+  def self.core_fields(trackers)
+    if trackers.present?
+      trackers.uniq.map(&:core_fields).reduce(:|)
+    else
+      CORE_FIELDS.dup
+    end
+  end
+
+private
+  def check_integrity
+    raise Exception.new("Can't delete tracker") if Issue.where(:tracker_id => self.id).any?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cb/cbc9695a147fcc463edc9725d0fd463106ff0284.svn-base
--- a/.svn/pristine/cb/cbc9695a147fcc463edc9725d0fd463106ff0284.svn-base
+++ /dev/null
@@ -1,39 +0,0 @@
-# MySQL (default setup).
-
-production:
-  adapter: mysql
-  database: redmine
-  host: localhost
-  username: root
-  password:
-  encoding: utf8
-
-development:
-  adapter: mysql
-  database: redmine_development
-  host: localhost
-  username: root
-  password:
-  encoding: utf8
-
-# Warning: The database defined as "test" will be erased and
-# re-generated from your development database when you run "rake".
-# Do not set this db to the same as development or production.
-test:
-  adapter: mysql
-  database: redmine_test
-  host: localhost
-  username: root
-  password:
-  encoding: utf8
-
-test_pgsql:
-  adapter: postgresql
-  database: redmine_test
-  host: localhost
-  username: postgres
-  password: "postgres"
-
-test_sqlite3:
-  adapter: sqlite3
-  database: db/test.sqlite3
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cc/cc6020dd7fb43016d05c4e77058b762d643cb4c2.svn-base
--- a/.svn/pristine/cc/cc6020dd7fb43016d05c4e77058b762d643cb4c2.svn-base
+++ /dev/null
@@ -1,1025 +0,0 @@
-# Polish translations for Ruby on Rails
-# by Jacek Becela (jacek.becela@gmail.com, http://github.com/ncr)
-# by Krzysztof Podejma (kpodejma@customprojects.pl, http://www.customprojects.pl)
-
-pl:
-  number:
-    format:
-      separator: ","
-      delimiter: " "
-      precision: 2
-    currency:
-      format:
-        format: "%n %u"
-        unit: "PLN"
-    percentage:
-      format:
-        delimiter: ""
-    precision:
-      format:
-        delimiter: ""
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "B"
-            other: "B"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  direction: ltr
-  date:
-    formats:
-      default: "%Y-%m-%d"
-      short: "%d %b"
-      long: "%d %B %Y"
-    
-    day_names: [Niedziela, PoniedziaÅ‚ek, Wtorek, Åšroda, Czwartek, PiÄ…tek, Sobota]
-    abbr_day_names: [nie, pon, wto, Å›ro, czw, pia, sob]
-    
-    month_names: [~, StyczeÅ„, Luty, Marzec, KwiecieÅ„, Maj, Czerwiec, Lipiec, SierpieÅ„, WrzesieÅ„, PaÅºdziernik, Listopad, GrudzieÅ„]
-    abbr_month_names: [~, sty, lut, mar, kwi, maj, cze, lip, sie, wrz, paÅº, lis, gru]
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%a, %d %b %Y, %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b, %H:%M"
-      long: "%d %B %Y, %H:%M"
-    am: "przed poÅ‚udniem"
-    pm: "po poÅ‚udniu"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "pÃ³Å‚ minuty"
-      less_than_x_seconds:
-        one:   "mniej niÅ¼ sekundÄ™"
-        few:   "mniej niÅ¼ %{count} sekundy"
-        other: "mniej niÅ¼ %{count} sekund"
-      x_seconds:
-        one:   "sekundÄ™"
-        few:   "%{count} sekundy"
-        other: "%{count} sekund"
-      less_than_x_minutes:
-        one:   "mniej niÅ¼ minutÄ™"
-        few:   "mniej niÅ¼ %{count} minuty"
-        other: "mniej niÅ¼ %{count} minut"
-      x_minutes:
-        one:   "minutÄ™"
-        few:   "%{count} minuty"
-        other: "%{count} minut"
-      about_x_hours:
-        one:   "okoÅ‚o godziny"
-        other: "okoÅ‚o %{count} godzin"
-      x_days:
-        one:   "1 dzieÅ„"
-        other: "%{count} dni"
-      about_x_months:
-        one:   "okoÅ‚o miesiÄ…ca"
-        other: "okoÅ‚o %{count} miesiÄ™cy"
-      x_months:
-        one:   "1 miesiÄ…c"
-        few:   "%{count} miesiÄ…ce"
-        other: "%{count} miesiÄ™cy"
-      about_x_years:
-        one:   "okoÅ‚o roku"
-        other: "okoÅ‚o %{count} lat"
-      over_x_years:
-        one:   "ponad rok"
-        few:   "ponad %{count} lata"
-        other: "ponad %{count} lat"
-      almost_x_years:
-        one:   "prawie rok"
-        other: "prawie %{count} lata"
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "%{model} nie zostaÅ‚ zachowany z powodu jednego bÅ‚Ä™du"
-          other:  "%{model} nie zostaÅ‚ zachowany z powodu %{count} bÅ‚Ä™dÃ³w"
-        body: "BÅ‚Ä™dy dotyczÄ… nastÄ™pujÄ…cych pÃ³l:"
-      messages:
-        inclusion: "nie znajduje siÄ™ na liÅ›cie dopuszczalnych wartoÅ›ci"
-        exclusion: "znajduje siÄ™ na liÅ›cie zabronionych wartoÅ›ci"
-        invalid: "jest nieprawidÅ‚owe"
-        confirmation: "nie zgadza siÄ™ z potwierdzeniem"
-        accepted: "musi byÄ‡ zaakceptowane"
-        empty: "nie moÅ¼e byÄ‡ puste"
-        blank: "nie moÅ¼e byÄ‡ puste"
-        too_long: "jest za dÅ‚ugie (maksymalnie %{count} znakÃ³w)"
-        too_short: "jest za krÃ³tkie (minimalnie %{count} znakÃ³w)"
-        wrong_length: "jest nieprawidÅ‚owej dÅ‚ugoÅ›ci (powinna wynosiÄ‡ %{count} znakÃ³w)"
-        taken: "jest juÅ¼ zajÄ™te"
-        not_a_number: "nie jest liczbÄ…"
-        greater_than: "musi byÄ‡ wiÄ™ksze niÅ¼ %{count}"
-        greater_than_or_equal_to: "musi byÄ‡ wiÄ™ksze lub rÃ³wne %{count}"
-        equal_to: "musi byÄ‡ rÃ³wne %{count}"
-        less_than: "musi byÄ‡ mniejsze niÅ¼ %{count}"
-        less_than_or_equal_to: "musi byÄ‡ mniejsze lub rÃ³wne %{count}"
-        odd: "musi byÄ‡ nieparzyste"
-        even: "musi byÄ‡ parzyste"
-        greater_than_start_date: "musi byÄ‡ wiÄ™ksze niÅ¼ poczÄ…tkowa data"
-        not_same_project: "nie naleÅ¼y do tego samego projektu"
-        circular_dependency: "Ta relacja moÅ¼e wytworzyÄ‡ koÅ‚owÄ… zaleÅ¼noÅ›Ä‡"
-        cant_link_an_issue_with_a_descendant: "Zagadnienie nie moÅ¼e zostaÄ‡ powiÄ…zane z jednym z wÅ‚asnych podzagadnieÅ„"
-      
-  support:
-    array:
-      sentence_connector: "i"
-      skip_last_comma: true
-
-  # Keep this line in order to avoid problems with Windows Notepad UTF-8 EF-BB-BFidea...
-  # Best regards from Lublin@Poland :-)
-  # PL translation by Mariusz@Olejnik.net,
-  actionview_instancetag_blank_option: ProszÄ™ wybierz
-  
-  button_activate: Aktywuj
-  button_add: Dodaj
-  button_annotate: Adnotuj
-  button_apply: Ustaw
-  button_archive: Archiwizuj
-  button_back: Wstecz
-  button_cancel: Anuluj
-  button_change: ZmieÅ„
-  button_change_password: ZmieÅ„ hasÅ‚o
-  button_check_all: Zaznacz wszystko
-  button_clear: WyczyÅ›Ä‡
-  button_configure: Konfiguruj
-  button_copy: Kopia
-  button_create: StwÃ³rz
-  button_delete: UsuÅ„
-  button_download: Pobierz
-  button_edit: Edytuj
-  button_list: Lista
-  button_lock: Zablokuj
-  button_log_time: Dziennik
-  button_login: Login
-  button_move: PrzenieÅ›
-  button_quote: Cytuj
-  button_rename: ZmieÅ„ nazwÄ™
-  button_reply: Odpowiedz
-  button_reset: Resetuj
-  button_rollback: PrzywrÃ³Ä‡ do tej wersji
-  button_save: Zapisz
-  button_sort: Sortuj
-  button_submit: WyÅ›lij
-  button_test: Testuj
-  button_unarchive: PrzywrÃ³Ä‡ z archiwum
-  button_uncheck_all: Odznacz wszystko
-  button_unlock: Odblokuj
-  button_unwatch: Nie obserwuj
-  button_update: Uaktualnij
-  button_view: PokaÅ¼
-  button_watch: Obserwuj
-  default_activity_design: Projektowanie
-  default_activity_development: RozwÃ³j
-  default_doc_category_tech: Dokumentacja techniczna
-  default_doc_category_user: Dokumentacja uÅ¼ytkownika
-  default_issue_status_in_progress: W Toku
-  default_issue_status_closed: ZamkniÄ™ty
-  default_issue_status_feedback: OdpowiedÅº
-  default_issue_status_new: Nowy
-  default_issue_status_rejected: Odrzucony
-  default_issue_status_resolved: RozwiÄ…zany
-  default_priority_high: Wysoki
-  default_priority_immediate: Natychmiastowy
-  default_priority_low: Niski
-  default_priority_normal: Normalny
-  default_priority_urgent: Pilny
-  default_role_developer: Programista
-  default_role_manager: Kierownik
-  default_role_reporter: Wprowadzajacy
-  default_tracker_bug: BÅ‚Ä…d
-  default_tracker_feature: Zadanie
-  default_tracker_support: Wsparcie
-  enumeration_activities: DziaÅ‚ania (Å›ledzenie czasu)
-  enumeration_doc_categories: Kategorie dokumentÃ³w
-  enumeration_issue_priorities: Priorytety zagadnieÅ„
-  error_can_t_load_default_data: "DomyÅ›lna konfiguracja nie moÅ¼e byÄ‡ zaÅ‚adowana: %{value}"
-  error_issue_not_found_in_project: 'Zaganienie nie zostaÅ‚o znalezione lub nie naleÅ¼y do tego projektu'
-  error_scm_annotate: "Wpis nie istnieje lub nie moÅ¼na do niego dodawaÄ‡ adnotacji."
-  error_scm_command_failed: "WystÄ…piÅ‚ bÅ‚Ä…d przy prÃ³bie dostÄ™pu do repozytorium: %{value}"
-  error_scm_not_found: "Obiekt lub wersja nie zostaÅ‚y znalezione w repozytorium."
-  field_account: Konto
-  field_activity: AktywnoÅ›Ä‡
-  field_admin: Administrator
-  field_assignable: Zagadnienia mogÄ… byÄ‡ przypisane do tej roli
-  field_assigned_to: Przydzielony do
-  field_attr_firstname: ImiÄ™ atrybut
-  field_attr_lastname: Nazwisko atrybut
-  field_attr_login: Login atrybut
-  field_attr_mail: Email atrybut
-  field_auth_source: Tryb identyfikacji
-  field_author: Autor
-  field_base_dn: Base DN
-  field_category: Kategoria
-  field_column_names: Nazwy kolumn
-  field_comments: Komentarz
-  field_comments_sorting: Pokazuj komentarze
-  field_created_on: Stworzone
-  field_default_value: DomyÅ›lny
-  field_delay: OpÃ³Åºnienie
-  field_description: Opis
-  field_done_ratio: "% Wykonane"
-  field_downloads: PobraÅ„
-  field_due_date: Data oddania
-  field_effective_date: Data
-  field_estimated_hours: Szacowany czas
-  field_field_format: Format
-  field_filename: Plik
-  field_filesize: Rozmiar
-  field_firstname: ImiÄ™
-  field_fixed_version: Wersja docelowa
-  field_hide_mail: Ukryj mÃ³j adres email
-  field_homepage: Strona www
-  field_host: Host
-  field_hours: Godzin
-  field_identifier: Identifikator
-  field_is_closed: Zagadnienie zamkniÄ™te
-  field_is_default: DomyÅ›lny status
-  field_is_filter: Atrybut filtrowania
-  field_is_for_all: Dla wszystkich projektÃ³w
-  field_is_in_roadmap: Zagadnienie pokazywane na mapie
-  field_is_public: Publiczny
-  field_is_required: Wymagane
-  field_issue: Zagadnienie
-  field_issue_to: PowiÄ…zania zagadnienia
-  field_language: JÄ™zyk
-  field_last_login_on: Ostatnie poÅ‚Ä…czenie
-  field_lastname: Nazwisko
-  field_login: Login
-  field_mail: Email
-  field_mail_notification: Powiadomienia Email
-  field_max_length: Maksymalna dÅ‚ugoÅ›Ä‡
-  field_min_length: Minimalna dÅ‚ugoÅ›Ä‡
-  field_name: Nazwa
-  field_new_password: Nowe hasÅ‚o
-  field_notes: Notatki
-  field_onthefly: Tworzenie uÅ¼ytkownika w locie
-  field_parent: Nadprojekt
-  field_parent_title: Strona rodzica
-  field_password: HasÅ‚o
-  field_password_confirmation: Potwierdzenie
-  field_port: Port
-  field_possible_values: MoÅ¼liwe wartoÅ›ci
-  field_priority: Priorytet
-  field_project: Projekt
-  field_redirect_existing_links: Przekierowanie istniejÄ…cych odnoÅ›nikÃ³w
-  field_regexp: WyraÅ¼enie regularne
-  field_role: Rola
-  field_searchable: Przeszukiwalne
-  field_spent_on: Data
-  field_start_date: Start
-  field_start_page: Strona startowa
-  field_status: Status
-  field_subject: Temat
-  field_subproject: Podprojekt
-  field_summary: Podsumowanie
-  field_time_zone: Strefa czasowa
-  field_title: TytuÅ‚
-  field_tracker: Typ zagadnienia
-  field_type: Typ
-  field_updated_on: Zmienione
-  field_url: URL
-  field_user: UÅ¼ytkownik
-  field_value: WartoÅ›Ä‡
-  field_version: Wersja
-  field_vf_personnel: Personel
-  field_vf_watcher: Obserwator
-  general_csv_decimal_separator: ','
-  general_csv_encoding: UTF-8
-  general_csv_separator: ';'
-  general_first_day_of_week: '1'
-  general_lang_name: 'Polski'
-  general_pdf_encoding: UTF-8
-  general_text_No: 'Nie'
-  general_text_Yes: 'Tak'
-  general_text_no: 'nie'
-  general_text_yes: 'tak'
-  gui_validation_error: 1 bÅ‚Ä…d
-  gui_validation_error_plural234: "%{count} bÅ‚Ä™dy"
-  gui_validation_error_plural5: "%{count} bÅ‚Ä™dÃ³w"
-  gui_validation_error_plural: "%{count} bÅ‚Ä™dÃ³w"
-  label_activity: AktywnoÅ›Ä‡
-  label_add_another_file: Dodaj kolejny plik
-  label_add_note: Dodaj notatkÄ™
-  label_added: dodane
-  label_added_time_by: "Dodane przez %{author} %{age} temu"
-  label_administration: Administracja
-  label_age: Wiek
-  label_ago: dni temu
-  label_all: wszystko
-  label_all_time: caÅ‚y czas
-  label_all_words: Wszystkie sÅ‚owa
-  label_and_its_subprojects: "%{value} i podprojekty"
-  label_applied_status: Stosowany status
-  label_assigned_to_me_issues: Zagadnienia przypisane do mnie
-  label_associated_revisions: Skojarzone rewizje
-  label_attachment: Plik
-  label_attachment_delete: UsuÅ„ plik
-  label_attachment_new: Nowy plik
-  label_attachment_plural: Pliki
-  label_attribute: Atrybut
-  label_attribute_plural: Atrybuty
-  label_auth_source: Tryb identyfikacji
-  label_auth_source_new: Nowy tryb identyfikacji
-  label_auth_source_plural: Tryby identyfikacji
-  label_authentication: Identyfikacja
-  label_blocked_by: zablokowane przez
-  label_blocks: blokuje
-  label_board: Forum
-  label_board_new: Nowe forum
-  label_board_plural: Fora
-  label_boolean: WartoÅ›Ä‡ logiczna
-  label_browse: PrzeglÄ…d
-  label_bulk_edit_selected_issues: Zbiorowa edycja zagadnieÅ„
-  label_calendar: Kalendarz
-  label_change_plural: Zmiany
-  label_change_properties: ZmieÅ„ wÅ‚aÅ›ciwoÅ›ci
-  label_change_status: Status zmian
-  label_change_view_all: PokaÅ¼ wszystkie zmiany
-  label_changes_details: SzczegÃ³Å‚y wszystkich zmian
-  label_changeset_plural: Zestawienia zmian
-  label_chronological_order: W kolejnoÅ›ci chronologicznej
-  label_closed_issues: zamkniÄ™te
-  label_closed_issues_plural234: zamkniÄ™te
-  label_closed_issues_plural5: zamkniÄ™te
-  label_closed_issues_plural: zamkniÄ™te
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_comment: Komentarz
-  label_comment_add: Dodaj komentarz
-  label_comment_added: Komentarz dodany
-  label_comment_delete: UsuÅ„ komentarze
-  label_comment_plural234: Komentarze
-  label_comment_plural5: Komentarze
-  label_comment_plural: Komentarze
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_commits_per_author: Zatwierdzenia wedÅ‚ug autorÃ³w
-  label_commits_per_month: Zatwierdzenia wedÅ‚ug miesiÄ™cy
-  label_confirmation: Potwierdzenie
-  label_contains: zawiera
-  label_copied: skopiowano
-  label_copy_workflow_from: Kopiuj przepÅ‚yw z
-  label_current_status: Obecny status
-  label_current_version: Obecna wersja
-  label_custom_field: Dowolne pole
-  label_custom_field_new: Nowe dowolne pole
-  label_custom_field_plural: Dowolne pola
-  label_date: Data
-  label_date_from: Z
-  label_date_range: Zakres datowy
-  label_date_to: Do
-  label_day_plural: dni
-  label_default: DomyÅ›lne
-  label_default_columns: DomyÅ›lne kolumny
-  label_deleted: usuniÄ™te
-  label_details: SzczegÃ³Å‚y
-  label_diff_inline: w linii
-  label_diff_side_by_side: obok siebie
-  label_disabled: zablokowany
-  label_display_per_page: "Na stronÄ™: %{value}"
-  label_document: Dokument
-  label_document_added: Dodano dokument
-  label_document_new: Nowy dokument
-  label_document_plural: Dokumenty
-  label_download: "%{count} Pobranie"
-  label_download_plural234: "%{count} Pobrania"
-  label_download_plural5: "%{count} PobraÅ„"
-  label_download_plural: "%{count} Pobrania"
-  label_downloads_abbr: Pobieranie
-  label_duplicated_by: zduplikowane przez
-  label_duplicates: duplikuje
-  label_end_to_end: koniec do koÅ„ca
-  label_end_to_start: koniec do poczÄ…tku
-  label_enumeration_new: Nowa wartoÅ›Ä‡
-  label_enumerations: Wyliczenia
-  label_environment: Åšrodowisko
-  label_equals: rÃ³wna siÄ™
-  label_example: PrzykÅ‚ad
-  label_export_to: Eksportuj do
-  label_f_hour: "%{value} godzina"
-  label_f_hour_plural: "%{value} godzin"
-  label_feed_plural: IloÅ›Ä‡ RSS
-  label_feeds_access_key_created_on: "Klucz dostÄ™pu RSS stworzony %{value} dni temu"
-  label_file_added: Dodano plik
-  label_file_plural: Pliki
-  label_filter_add: Dodaj filtr
-  label_filter_plural: Filtry
-  label_float: Liczba rzeczywista
-  label_follows: nastÄ™puje po
-  label_gantt: Gantt
-  label_general: OgÃ³lne
-  label_generate_key: Wygeneruj klucz
-  label_help: Pomoc
-  label_history: Historia
-  label_home: GÅ‚Ã³wna
-  label_in: w
-  label_in_less_than: mniejsze niÅ¼
-  label_in_more_than: wiÄ™ksze niÅ¼
-  label_incoming_emails: PrzychodzÄ…ca poczta elektroniczna
-  label_index_by_date: Indeks wg daty
-  label_index_by_title: Indeks
-  label_information: Informacja
-  label_information_plural: Informacje
-  label_integer: Liczba caÅ‚kowita
-  label_internal: WewnÄ™trzny
-  label_issue: Zagadnienie
-  label_issue_added: Dodano zagadnienie
-  label_issue_category: Kategoria zagadnienia
-  label_issue_category_new: Nowa kategoria
-  label_issue_category_plural: Kategorie zagadnieÅ„
-  label_issue_new: Nowe zagadnienie
-  label_issue_plural: Zagadnienia
-  label_issue_status: Status zagadnienia
-  label_issue_status_new: Nowy status
-  label_issue_status_plural: Statusy zagadnieÅ„
-  label_issue_tracking: Åšledzenie zagadnieÅ„
-  label_issue_updated: Uaktualniono zagadnienie
-  label_issue_view_all: Zobacz wszystkie zagadnienia
-  label_issue_watchers: Obserwatorzy
-  label_issues_by: "Zagadnienia wprowadzone przez %{value}"
-  label_jump_to_a_project: Skocz do projektu...
-  label_language_based: Na podstawie jÄ™zyka
-  label_last_changes: "ostatnie %{count} zmian"
-  label_last_login: Ostatnie poÅ‚Ä…czenie
-  label_last_month: ostatni miesiÄ…c
-  label_last_n_days: "ostatnie %{count} dni"
-  label_last_week: ostatni tydzieÅ„
-  label_latest_revision: Najnowsza rewizja
-  label_latest_revision_plural: Najnowsze rewizje
-  label_ldap_authentication: Autoryzacja LDAP
-  label_less_than_ago: dni mniej
-  label_list: Lista
-  label_loading: Åadowanie...
-  label_logged_as: Zalogowany jako
-  label_login: Login
-  label_logout: Wylogowanie
-  label_max_size: Maksymalny rozmiar
-  label_me: ja
-  label_member: Uczestnik
-  label_member_new: Nowy uczestnik
-  label_member_plural: Uczestnicy
-  label_message_last: Ostatnia wiadomoÅ›Ä‡
-  label_message_new: Nowa wiadomoÅ›Ä‡
-  label_message_plural: WiadomoÅ›ci
-  label_message_posted: Dodano wiadomoÅ›Ä‡
-  label_min_max_length: Min - Maks dÅ‚ugoÅ›Ä‡
-  label_modification: "%{count} modyfikacja"
-  label_modification_plural234: "%{count} modyfikacje"
-  label_modification_plural5: "%{count} modyfikacji"
-  label_modification_plural: "%{count} modyfikacje"
-  label_modified: zmodyfikowane
-  label_module_plural: ModuÅ‚y
-  label_month: MiesiÄ…c
-  label_months_from: miesiÄ…ce od
-  label_more: WiÄ™cej
-  label_more_than_ago: dni wiÄ™cej
-  label_my_account: Moje konto
-  label_my_page: Moja strona
-  label_my_projects: Moje projekty
-  label_new: Nowy
-  label_new_statuses_allowed: Uprawnione nowe statusy
-  label_news: Komunikat
-  label_news_added: Dodano komunikat
-  label_news_latest: Ostatnie komunikaty
-  label_news_new: Dodaj komunikat
-  label_news_plural: Komunikaty
-  label_news_view_all: PokaÅ¼ wszystkie komunikaty
-  label_next: NastÄ™pne
-  label_no_change_option: (Bez zmian)
-  label_no_data: Brak danych do pokazania
-  label_nobody: nikt
-  label_none: brak
-  label_not_contains: nie zawiera
-  label_not_equals: rÃ³Å¼ni siÄ™
-  label_open_issues: otwarte
-  label_open_issues_plural234: otwarte
-  label_open_issues_plural5: otwarte
-  label_open_issues_plural: otwarte
-  label_optional_description: Opcjonalny opis
-  label_options: Opcje
-  label_overall_activity: OgÃ³lna aktywnoÅ›Ä‡
-  label_overview: PrzeglÄ…d
-  label_password_lost: Zapomniane hasÅ‚o
-  label_per_page: Na stronÄ™
-  label_permissions: Uprawnienia
-  label_permissions_report: Raport uprawnieÅ„
-  label_personalize_page: Personalizuj tÄ… stronÄ™
-  label_planning: Planowanie
-  label_please_login: Zaloguj siÄ™
-  label_plugins: Wtyczki
-  label_precedes: poprzedza
-  label_preferences: Preferencje
-  label_preview: PodglÄ…d
-  label_previous: Poprzednie
-  label_project: Projekt
-  label_project_all: Wszystkie projekty
-  label_project_latest: Ostatnie projekty
-  label_project_new: Nowy projekt
-  label_project_plural234: Projekty
-  label_project_plural5: ProjektÃ³w
-  label_project_plural: Projekty
-  label_x_projects:
-    zero:  brak projektÃ³w
-    one:   jeden projekt
-    other: "%{count} projektÃ³w"
-  label_public_projects: Projekty publiczne
-  label_query: Kwerenda
-  label_query_new: Nowa kwerenda
-  label_query_plural: Kwerendy
-  label_read: Czytanie...
-  label_register: Rejestracja
-  label_registered_on: Zarejestrowany
-  label_registration_activation_by_email: aktywacja konta przez e-mail
-  label_registration_automatic_activation: automatyczna aktywacja kont
-  label_registration_manual_activation: manualna aktywacja kont
-  label_related_issues: PowiÄ…zane zagadnienia
-  label_relates_to: powiÄ…zane z
-  label_relation_delete: UsuÅ„ powiÄ…zanie
-  label_relation_new: Nowe powiÄ…zanie
-  label_renamed: przemianowano
-  label_reply_plural: Odpowiedzi
-  label_report: Raport
-  label_report_plural: Raporty
-  label_reported_issues: Wprowadzone zagadnienia
-  label_repository: Repozytorium
-  label_repository_plural: Repozytoria
-  label_result_plural: RezultatÃ³w
-  label_reverse_chronological_order: W kolejnoÅ›ci odwrotnej do chronologicznej
-  label_revision: Rewizja
-  label_revision_plural: Rewizje
-  label_roadmap: Mapa
-  label_roadmap_due_in: W czasie
-  label_roadmap_no_issues: Brak zagadnieÅ„ do tej wersji
-  label_roadmap_overdue: "%{value} spÃ³Åºnienia"
-  label_role: Rola
-  label_role_and_permissions: Role i Uprawnienia
-  label_role_new: Nowa rola
-  label_role_plural: Role
-  label_scm: SCM
-  label_search: Szukaj
-  label_search_titles_only: Przeszukuj tylko tytuÅ‚y
-  label_send_information: WyÅ›lij informacjÄ™ uÅ¼ytkownikowi
-  label_send_test_email: WyÅ›lij prÃ³bny email
-  label_settings: Ustawienia
-  label_show_completed_versions: PokaÅ¼ kompletne wersje
-  label_sort_by: "Sortuj po %{value}"
-  label_sort_higher: Do gÃ³ry
-  label_sort_highest: PrzesuÅ„ na gÃ³rÄ™
-  label_sort_lower: Do doÅ‚u
-  label_sort_lowest: PrzesuÅ„ na dÃ³Å‚
-  label_spent_time: Przepracowany czas
-  label_start_to_end: poczÄ…tek do koÅ„ca
-  label_start_to_start: poczÄ…tek do poczÄ…tku
-  label_statistics: Statystyki
-  label_stay_logged_in: PozostaÅ„ zalogowany
-  label_string: Tekst
-  label_subproject_plural: Podprojekty
-  label_text: DÅ‚ugi tekst
-  label_theme: Temat
-  label_this_month: ten miesiÄ…c
-  label_this_week: ten tydzieÅ„
-  label_this_year: ten rok
-  label_time_tracking: Åšledzenie czasu pracy
-  label_today: dzisiaj
-  label_topic_plural: Tematy
-  label_total: OgÃ³Å‚em
-  label_tracker: Typ zagadnienia
-  label_tracker_new: Nowy typ zagadnienia
-  label_tracker_plural: Typy zagadnieÅ„
-  label_updated_time: "Zaktualizowane %{value} temu"
-  label_used_by: UÅ¼ywane przez
-  label_user: UÅ¼ytkownik
-  label_user_mail_no_self_notified: "Nie chcÄ™ powiadomieÅ„ o zmianach, ktÃ³re sam wprowadzam."
-  label_user_mail_option_all: "Dla kaÅ¼dego zdarzenia w kaÅ¼dym moim projekcie"
-  label_user_mail_option_selected: "Tylko dla kaÅ¼dego zdarzenia w wybranych projektach..."
-  label_user_new: Nowy uÅ¼ytkownik
-  label_user_plural: UÅ¼ytkownicy
-  label_version: Wersja
-  label_version_new: Nowa wersja
-  label_version_plural: Wersje
-  label_view_diff: PokaÅ¼ rÃ³Å¼nice
-  label_view_revisions: PokaÅ¼ rewizje
-  label_watched_issues: Obserwowane zagadnienia
-  label_week: TydzieÅ„
-  label_wiki: Wiki
-  label_wiki_edit: Edycja wiki
-  label_wiki_edit_plural: Edycje wiki
-  label_wiki_page: Strona wiki
-  label_wiki_page_plural: Strony wiki
-  label_workflow: PrzepÅ‚yw
-  label_year: Rok
-  label_yesterday: wczoraj
-  mail_body_account_activation_request: "Zarejestrowano nowego uÅ¼ytkownika: (%{value}). Konto oczekuje na twoje zatwierdzenie:"
-  mail_body_account_information: Twoje konto
-  mail_body_account_information_external: "MoÅ¼esz uÅ¼yÄ‡ twojego %{value} konta do zalogowania."
-  mail_body_lost_password: 'W celu zmiany swojego hasÅ‚a uÅ¼yj poniÅ¼szego odnoÅ›nika:'
-  mail_body_register: 'W celu aktywacji Twojego konta, uÅ¼yj poniÅ¼szego odnoÅ›nika:'
-  mail_body_reminder: "Wykaz przypisanych do Ciebie zagadnieÅ„, ktÃ³rych termin wypada w ciÄ…gu nastÄ™pnych %{count} dni"
-  mail_subject_account_activation_request: "Zapytanie aktywacyjne konta %{value}"
-  mail_subject_lost_password: "Twoje hasÅ‚o do %{value}"
-  mail_subject_register: "Aktywacja konta w %{value}"
-  mail_subject_reminder: "Uwaga na terminy, masz zagadnienia do obsÅ‚uÅ¼enia w ciÄ…gu nastÄ™pnych %{count} dni! (%{days})"
-  notice_account_activated: Twoje konto zostaÅ‚o aktywowane. MoÅ¼esz siÄ™ zalogowaÄ‡.
-  notice_account_invalid_creditentials: ZÅ‚y uÅ¼ytkownik lub hasÅ‚o
-  notice_account_lost_email_sent: Email z instrukcjami zmiany hasÅ‚a zostaÅ‚ wysÅ‚any do Ciebie.
-  notice_account_password_updated: HasÅ‚o prawidÅ‚owo zmienione.
-  notice_account_pending: "Twoje konto zostaÅ‚o utworzone i oczekuje na zatwierdzenie administratora."
-  notice_account_register_done: Konto prawidÅ‚owo stworzone.
-  notice_account_unknown_email: Nieznany uÅ¼ytkownik.
-  notice_account_updated: Konto prawidÅ‚owo zaktualizowane.
-  notice_account_wrong_password: ZÅ‚e hasÅ‚o
-  notice_can_t_change_password: To konto ma zewnÄ™trzne ÅºrÃ³dÅ‚o identyfikacji. Nie moÅ¼esz zmieniÄ‡ hasÅ‚a.
-  notice_default_data_loaded: DomyÅ›lna konfiguracja zostaÅ‚a pomyÅ›lnie zaÅ‚adowana.
-  notice_email_error: "WystÄ…piÅ‚ bÅ‚Ä…d w trakcie wysyÅ‚ania maila (%{value})"
-  notice_email_sent: "Email zostaÅ‚ wysÅ‚any do %{value}"
-  notice_failed_to_save_issues: "BÅ‚Ä…d podczas zapisu zagadnieÅ„ %{count} z %{total} zaznaczonych: %{ids}."
-  notice_feeds_access_key_reseted: TwÃ³j klucz dostÄ™pu RSS zostaÅ‚ zrestetowany.
-  notice_file_not_found: Strona do ktÃ³rej prÃ³bujesz siÄ™ dostaÄ‡ nie istnieje lub zostaÅ‚a usuniÄ™ta.
-  notice_locking_conflict: Dane poprawione przez innego uÅ¼ytkownika.
-  notice_no_issue_selected: "Nie wybrano zagadnienia! Zaznacz zagadnienie, ktÃ³re chcesz edytowaÄ‡."
-  notice_not_authorized: Nie jesteÅ› autoryzowany by zobaczyÄ‡ stronÄ™.
-  notice_successful_connection: Udane nawiÄ…zanie poÅ‚Ä…czenia.
-  notice_successful_create: Utworzenie zakoÅ„czone sukcesem.
-  notice_successful_delete: UsuniÄ™cie zakoÅ„czone sukcesem.
-  notice_successful_update: Uaktualnienie zakoÅ„czone sukcesem.
-  notice_unable_delete_version: Nie moÅ¼na usunÄ…Ä‡ wersji
-  permission_add_issue_notes: Dodawanie notatek
-  permission_add_issue_watchers: Dodawanie obserwatorÃ³w
-  permission_add_issues: Dodawanie zagadnieÅ„
-  permission_add_messages: Dodawanie wiadomoÅ›ci
-  permission_browse_repository: PrzeglÄ…danie repozytorium
-  permission_comment_news: Komentowanie komunikatÃ³w
-  permission_commit_access: Wykonywanie zatwierdzeÅ„
-  permission_delete_issues: Usuwanie zagadnieÅ„
-  permission_delete_messages: Usuwanie wiadomoÅ›ci
-  permission_delete_wiki_pages: Usuwanie stron wiki
-  permission_delete_wiki_pages_attachments: Usuwanie zaÅ‚Ä…cznikÃ³w
-  permission_delete_own_messages: Usuwanie wÅ‚asnych wiadomoÅ›ci
-  permission_edit_issue_notes: Edycja notatek
-  permission_edit_issues: Edycja zagadnieÅ„
-  permission_edit_messages: Edycja wiadomoÅ›ci
-  permission_edit_own_issue_notes: Edycja wÅ‚asnych notatek
-  permission_edit_own_messages: Edycja wÅ‚asnych wiadomoÅ›ci
-  permission_edit_own_time_entries: Edycja wÅ‚asnego dziennika
-  permission_edit_project: Edycja projektÃ³w
-  permission_edit_time_entries: Edycja wpisÃ³w dziennika
-  permission_edit_wiki_pages: Edycja stron wiki
-  permission_log_time: Zapisywanie przepracowanego czasu
-  permission_manage_boards: ZarzÄ…dzanie forami
-  permission_manage_categories: ZarzÄ…dzanie kategoriami zaganieÅ„
-  permission_manage_documents: ZarzÄ…dzanie dokumentami
-  permission_manage_files: ZarzÄ…dzanie plikami
-  permission_manage_issue_relations: ZarzÄ…dzanie powiÄ…zaniami zagadnieÅ„
-  permission_manage_members: ZarzÄ…dzanie uczestnikami
-  permission_manage_news: ZarzÄ…dzanie komunikatami
-  permission_manage_public_queries: ZarzÄ…dzanie publicznymi kwerendami
-  permission_manage_repository: ZarzÄ…dzanie repozytorium
-  permission_manage_versions: ZarzÄ…dzanie wersjami
-  permission_manage_wiki: ZarzÄ…dzanie wiki
-  permission_move_issues: Przenoszenie zagadnieÅ„
-  permission_protect_wiki_pages: Blokowanie stron wiki
-  permission_rename_wiki_pages: Zmiana nazw stron wiki
-  permission_save_queries: Zapisywanie kwerend
-  permission_select_project_modules: Wybieranie moduÅ‚Ã³w projektu
-  permission_view_calendar: PodglÄ…d kalendarza
-  permission_view_changesets: PodglÄ…d zmian
-  permission_view_documents: PodglÄ…d dokumentÃ³w
-  permission_view_files: PodglÄ…d plikÃ³w
-  permission_view_gantt: PodglÄ…d diagramu Gantta
-  permission_view_issue_watchers: PodglÄ…d listy obserwatorÃ³w
-  permission_view_messages: PodglÄ…d wiadomoÅ›ci
-  permission_view_time_entries: PodglÄ…d przepracowanego czasu
-  permission_view_wiki_edits: PodglÄ…d historii wiki
-  permission_view_wiki_pages: PodglÄ…d wiki
-  project_module_boards: Fora
-  project_module_documents: Dokumenty
-  project_module_files: Pliki
-  project_module_issue_tracking: Åšledzenie zagadnieÅ„
-  project_module_news: Komunikaty
-  project_module_repository: Repozytorium
-  project_module_time_tracking: Åšledzenie czasu pracy
-  project_module_wiki: Wiki
-  setting_activity_days_default: Dni wyÅ›wietlane w aktywnoÅ›ci projektu
-  setting_app_subtitle: PodtytuÅ‚ aplikacji
-  setting_app_title: TytuÅ‚ aplikacji
-  setting_attachment_max_size: Maks. rozm. zaÅ‚Ä…cznika
-  setting_autofetch_changesets: Automatyczne pobieranie zmian
-  setting_autologin: Auto logowanie
-  setting_bcc_recipients: Odbiorcy kopii tajnej (kt/bcc)
-  setting_commit_fix_keywords: SÅ‚owa zmieniajÄ…ce status
-  setting_commit_ref_keywords: SÅ‚owa tworzÄ…ce powiÄ…zania
-  setting_cross_project_issue_relations: ZezwÃ³l na powiÄ…zania zagadnieÅ„ miÄ™dzy projektami
-  setting_date_format: Format daty
-  setting_default_language: DomyÅ›lny jÄ™zyk
-  setting_default_projects_public: Nowe projekty sÄ… domyÅ›lnie publiczne
-  setting_display_subprojects_issues: DomyÅ›lnie pokazuj zagadnienia podprojektÃ³w w gÅ‚Ã³wnym projekcie
-  setting_emails_footer: Stopka e-mail
-  setting_enabled_scm: DostÄ™pny SCM
-  setting_feeds_limit: Limit danych RSS
-  setting_gravatar_enabled: UÅ¼ywaj ikon uÅ¼ytkownikÃ³w Gravatar
-  setting_host_name: Nazwa hosta i Å›cieÅ¼ka
-  setting_issue_list_default_columns: DomyÅ›lne kolumny wyÅ›wietlane na liÅ›cie zagadnieÅ„
-  setting_issues_export_limit: Limit eksportu zagadnieÅ„
-  setting_login_required: Identyfikacja wymagana
-  setting_mail_from: Adres email wysyÅ‚ki
-  setting_mail_handler_api_enabled: Uaktywnij usÅ‚ugi sieciowe (WebServices) dla poczty przychodzÄ…cej
-  setting_mail_handler_api_key: Klucz API
-  setting_per_page_options: Opcje iloÅ›ci obiektÃ³w na stronie
-  setting_plain_text_mail: tylko tekst (bez HTML)
-  setting_protocol: ProtokoÅ‚
-  setting_self_registration: Samodzielna rejestracja uÅ¼ytkownikÃ³w
-  setting_sequential_project_identifiers: Generuj sekwencyjne identyfikatory projektÃ³w
-  setting_sys_api_enabled: WÅ‚Ä…czenie WS do zarzÄ…dzania repozytorium
-  setting_text_formatting: Formatowanie tekstu
-  setting_time_format: Format czasu
-  setting_user_format: Personalny format wyÅ›wietlania
-  setting_welcome_text: Tekst powitalny
-  setting_wiki_compression: Kompresja historii Wiki
-  status_active: aktywny
-  status_locked: zablokowany
-  status_registered: zarejestrowany
-  text_are_you_sure: JesteÅ› pewien ?
-  text_assign_time_entries_to_project: Przypisz wpisy dziennika do projektu
-  text_caracters_maximum: "%{count} znakÃ³w maksymalnie."
-  text_caracters_minimum: "Musi byÄ‡ nie krÃ³tsze niÅ¼ %{count} znakÃ³w."
-  text_comma_separated: Wielokrotne wartoÅ›ci dozwolone (rozdzielone przecinkami).
-  text_default_administrator_account_changed: Zmieniono domyÅ›lne hasÅ‚o administratora
-  text_destroy_time_entries: UsuÅ„ wpisy dziennika
-  text_destroy_time_entries_question: Przepracowano %{hours} godzin przy zagadnieniu, ktÃ³re chcesz usunÄ…Ä‡. Co chcesz zrobiÄ‡?
-  text_email_delivery_not_configured: "Dostarczanie poczty elektronicznej nie zostaÅ‚o skonfigurowane, wiÄ™c powiadamianie jest nieaktywne.\nSkonfiguruj serwer SMTP w config/configuration.yml  a nastÄ™pnie zrestartuj aplikacjÄ™ i uaktywnij to."
-  text_enumeration_category_reassign_to: 'ZmieÅ„ przypisanie na tÄ… wartoÅ›Ä‡:'
-  text_enumeration_destroy_question: "%{count} obiektÃ³w jest przypisana do tej wartoÅ›ci."
-  text_file_repository_writable: Zapisywalne repozytorium plikÃ³w
-  text_issue_added: "Zagadnienie %{id} zostaÅ‚o wprowadzone (by %{author})."
-  text_issue_category_destroy_assignments: UsuÅ„ przydziaÅ‚y kategorii
-  text_issue_category_destroy_question: "Zagadnienia (%{count}) sÄ… przypisane do tej kategorii. Co chcesz zrobiÄ‡?"
-  text_issue_category_reassign_to: Przydziel zagadnienie do tej kategorii
-  text_issue_updated: "Zagadnienie %{id} zostaÅ‚o zaktualizowane (by %{author})."
-  text_issues_destroy_confirmation: 'Czy jestes pewien, Å¼e chcesz usunÄ…Ä‡ wskazane zagadnienia?'
-  text_issues_ref_in_commit_messages: OdwoÅ‚ania do zagadnieÅ„ w komentarzach zatwierdzeÅ„
-  text_length_between: "DÅ‚ugoÅ›Ä‡ pomiÄ™dzy %{min} i %{max} znakÃ³w."
-  text_load_default_configuration: ZaÅ‚aduj domyÅ›lnÄ… konfiguracjÄ™
-  text_min_max_length_info: 0 oznacza brak restrykcji
-  text_no_configuration_data: "Role uÅ¼ytkownikÃ³w, typy zagadnieÅ„, statusy zagadnieÅ„ oraz przepÅ‚yw pracy nie zostaÅ‚y jeszcze skonfigurowane.\nJest wysoce rekomendowane by zaÅ‚adowaÄ‡ domyÅ›lnÄ… konfiguracjÄ™. Po zaÅ‚adowaniu bÄ™dzie moÅ¼liwoÅ›Ä‡ edycji tych danych."
-  text_project_destroy_confirmation: JesteÅ› pewien, Å¼e chcesz usunÄ…Ä‡ ten projekt i wszystkie powiÄ…zane dane?
-  text_project_identifier_info: 'MaÅ‚e litery (a-z), liczby i myÅ›lniki dozwolone.<br />Raz zapisany, identyfikator nie moÅ¼e byÄ‡ zmieniony.'
-  text_reassign_time_entries: 'Przepnij przepracowany czas do tego zagadnienia:'
-  text_regexp_info: np. ^[A-Z0-9]+$
-  text_repository_usernames_mapping: "Wybierz lub uaktualnij przyporzÄ…dkowanie uÅ¼ytkownikÃ³w Redmine do uÅ¼ytkownikÃ³w repozytorium.\nUÅ¼ytkownicy z takÄ… samÄ… nazwÄ… lub adresem email sÄ… przyporzÄ…dkowani automatycznie."
-  text_rmagick_available: RMagick dostÄ™pne (opcjonalnie)
-  text_select_mail_notifications: Zaznacz czynnoÅ›ci przy ktÃ³rych uÅ¼ytkownik powinien byÄ‡ powiadomiony mailem.
-  text_select_project_modules: 'Wybierz moduÅ‚y do aktywacji w tym projekcie:'
-  text_status_changed_by_changeset: "Zastosowane w zmianach %{value}."
-  text_subprojects_destroy_warning: "Podprojekt(y): %{value} zostanÄ… takÅ¼e usuniÄ™te."
-  text_tip_issue_begin_day: zadanie zaczynajÄ…ce siÄ™ dzisiaj
-  text_tip_issue_begin_end_day: zadanie zaczynajÄ…ce i koÅ„czÄ…ce siÄ™ dzisiaj
-  text_tip_issue_end_day: zadanie koÅ„czÄ…ce siÄ™ dzisiaj
-  text_tracker_no_workflow: Brak przepÅ‚ywu zdefiniowanego dla tego typu zagadnienia
-  text_unallowed_characters: Niedozwolone znaki
-  text_user_mail_option: "W przypadku niezaznaczonych projektÃ³w, bÄ™dziesz otrzymywaÅ‚ powiadomienia tylko na temat zagadnieÅ„, ktÃ³re obserwujesz, lub w ktÃ³rych bierzesz udziaÅ‚ (np. jesteÅ› autorem lub adresatem)."
-  text_user_wrote: "%{value} napisaÅ‚:"
-  text_wiki_destroy_confirmation: JesteÅ› pewien, Å¼e chcesz usunÄ…Ä‡ to wiki i caÅ‚Ä… jego zawartoÅ›Ä‡ ?
-  text_workflow_edit: Zaznacz rolÄ™ i typ zagadnienia do edycji przepÅ‚ywu
-  
-  label_user_activity: "AktywnoÅ›Ä‡: %{value}"
-  label_updated_time_by: "Uaktualnione przez %{author} %{age} temu"
-  text_diff_truncated: '... Ten plik rÃ³Å¼nic zostaÅ‚ przyciÄ™ty poniewaÅ¼ jest zbyt dÅ‚ugi.'
-  setting_diff_max_lines_displayed: Maksymalna liczba linii rÃ³Å¼nicy do pokazania
-  text_plugin_assets_writable: Zapisywalny katalog zasobÃ³w wtyczek
-  warning_attachments_not_saved: "%{count} zaÅ‚Ä…cznik(Ã³w) nie zostaÅ‚o zapisanych."
-  field_editable: Edytowalne
-  label_display: WyglÄ…d
-  button_create_and_continue: StwÃ³rz i dodaj kolejne
-  text_custom_field_possible_values_info: 'KaÅ¼da wartoÅ›Ä‡ w osobnej linii'
-  setting_repository_log_display_limit: Maksymalna liczba rewizji pokazywanych w logu pliku
-  setting_file_max_size_displayed: Maksymalny rozmiar plikÃ³w tekstowych osadzanych w stronie
-  field_watcher: Obserwator
-  setting_openid: Logowanie i rejestracja przy uÅ¼yciu OpenID
-  field_identity_url: Identyfikator OpenID (URL)
-  label_login_with_open_id_option: albo uÅ¼yj OpenID
-  field_content: TreÅ›Ä‡
-  label_descending: MalejÄ…co
-  label_sort: Sortuj
-  label_ascending: RosnÄ…co
-  label_date_from_to: Od %{start} do %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: Ta strona posiada podstrony (%{descendants}). Co chcesz zrobiÄ‡?
-  text_wiki_page_reassign_children: Podepnij je do strony nadrzÄ™dnej wzglÄ™dem usuwanej
-  text_wiki_page_nullify_children: PrzesuÅ„ je na szczyt hierarchii
-  text_wiki_page_destroy_children: UsuÅ„ wszystkie podstrony
-  setting_password_min_length: Minimalna dÅ‚ugoÅ›Ä‡ hasÅ‚a
-  field_group_by: Grupuj wyniki wg
-  mail_subject_wiki_content_updated: "Strona wiki '%{id}' zostaÅ‚a uaktualniona"
-  label_wiki_content_added: Dodano stronÄ™ wiki
-  mail_subject_wiki_content_added: "Strona wiki '%{id}' zostaÅ‚a dodana"
-  mail_body_wiki_content_added: Strona wiki '%{id}' zostaÅ‚a dodana przez %{author}.
-  label_wiki_content_updated: Uaktualniono stronÄ™ wiki
-  mail_body_wiki_content_updated: Strona wiki '%{id}' zostaÅ‚a uaktualniona przez %{author}.
-  permission_add_project: Tworzenie projektu
-  setting_new_project_user_role_id: Rola nadawana twÃ³rcom projektÃ³w, ktÃ³rzy nie posiadajÄ… uprawnieÅ„ administatora
-  label_view_all_revisions: PokaÅ¼ wszystkie rewizje
-  label_tag: SÅ‚owo kluczowe
-  label_branch: GaÅ‚Ä…Åº
-  error_no_tracker_in_project: Projekt nie posiada powiÄ…zanych typÃ³w zagadnieÅ„. SprawdÅº ustawienia projektu.
-  error_no_default_issue_status: Nie zdefiniowano domyÅ›lnego statusu zagadnieÅ„. SprawdÅº konfiguracjÄ™ (PrzejdÅº do "Administracja -> Statusy zagadnieÅ„).
-  text_journal_changed: "Zmieniono %{label} z %{old} na %{new}"
-  text_journal_set_to: "Ustawiono %{label} na %{value}"
-  text_journal_deleted: "UsuniÄ™to %{label} (%{old})"
-  label_group_plural: Grupy
-  label_group: Grupa
-  label_group_new: Nowa grupa
-  label_time_entry_plural: Przepracowany czas
-  text_journal_added: "Dodano %{label} %{value}"
-  field_active: Aktywne
-  enumeration_system_activity: AktywnoÅ›Ä‡ Systemowa
-  button_copy_and_follow: Kopiuj i przejdÅº do kopii zagadnienia
-  button_duplicate: Duplikuj
-  button_move_and_follow: PrzenieÅ› i przejdÅº do zagadnienia
-  button_show: PokaÅ¼
-  error_can_not_archive_project: Ten projekt nie moÅ¼e zostaÄ‡ zarchiwizowany
-  error_can_not_reopen_issue_on_closed_version: Zagadnienie przydzielone do zakoÅ„czonej wersji nie moÅ¼e zostaÄ‡ ponownie otwarte
-  error_issue_done_ratios_not_updated: "% wykonania zagadnienia nie zostaÅ‚ uaktualniony."
-  error_workflow_copy_source: ProszÄ™ wybraÄ‡ ÅºrÃ³dÅ‚owy typ zagadnienia lub rolÄ™
-  error_workflow_copy_target: ProszÄ™ wybraÄ‡ docelowe typ(y) zagadnieÅ„ i rolÄ™(e)
-  field_sharing: WspÃ³Å‚dzielenie
-  label_api_access_key: Klucz dostÄ™pu do API
-  label_api_access_key_created_on: Klucz dostÄ™pu do API zostaÅ‚ utworzony %{value} temu
-  label_close_versions: Zamknij ukoÅ„czone wersje
-  label_copy_same_as_target: Jak cel
-  label_copy_source: Å¹rÃ³dÅ‚o
-  label_copy_target: Cel
-  label_display_used_statuses_only: WyÅ›wietlaj tylko statusy uÅ¼ywane przez ten typ zagadnienia
-  label_feeds_access_key: Klucz dostÄ™pu do RSS
-  label_missing_api_access_key: Brakuje klucza dostÄ™pu do API
-  label_missing_feeds_access_key: Brakuje klucza dostÄ™pu do RSS
-  label_revision_id: Rewizja %{value}
-  label_subproject_new: Nowy podprojekt
-  label_update_issue_done_ratios: Uaktualnij % wykonania
-  label_user_anonymous: Anonimowy
-  label_version_sharing_descendants: Z podprojektami
-  label_version_sharing_hierarchy: Z hierarchiÄ… projektÃ³w
-  label_version_sharing_none: Brak wspÃ³Å‚dzielenia
-  label_version_sharing_system: Ze wszystkimi projektami
-  label_version_sharing_tree: Z drzewem projektÃ³w
-  notice_api_access_key_reseted: TwÃ³j klucz dostÄ™pu do API zostaÅ‚ zresetowany.
-  notice_issue_done_ratios_updated: Uaktualnienie % wykonania zakoÅ„czone sukcesem.
-  permission_add_subprojects: Tworzenie podprojektÃ³w
-  permission_delete_issue_watchers: UsuÅ„ obserwatorÃ³w
-  permission_view_issues: PrzeglÄ…danie zagadnieÅ„
-  setting_default_projects_modules: DomyÅ›lnie wÅ‚Ä…czone moduÅ‚y dla nowo tworzonych projektÃ³w
-  setting_gravatar_default: DomyÅ›lny obraz Gravatar
-  setting_issue_done_ratio: Obliczaj postÄ™p realizacji zagadnieÅ„ za pomocÄ…
-  setting_issue_done_ratio_issue_field: "% Wykonania zagadnienia"
-  setting_issue_done_ratio_issue_status: Statusu zagadnienia
-  setting_mail_handler_body_delimiters: Przycinaj e-maile po jednej z tych linii
-  setting_rest_api_enabled: Uaktywnij usÅ‚ugÄ™ sieciowÄ… REST
-  setting_start_of_week: Pierwszy dzieÅ„ tygodnia
-  text_line_separated: Dozwolone jest wiele wartoÅ›ci (kaÅ¼da wartoÅ›Ä‡ w osobnej linii).
-  text_own_membership_delete_confirmation: |-
-    Masz zamiar usunÄ…Ä‡ niektÃ³re lub wszystkie swoje uprawnienia. Po wykonaniu tej czynnoÅ›ci moÅ¼esz utraciÄ‡ moÅ¼liwoÅ›ci edycji tego projektu.
-    Czy na pewno chcesz kontynuowaÄ‡?
-  version_status_closed: zamkniÄ™ta
-  version_status_locked: zablokowana
-  version_status_open: otwarta
-  
-  label_board_sticky: Przyklejona
-  label_board_locked: ZamkniÄ™ta
-  permission_export_wiki_pages: Eksport stron wiki
-  permission_manage_project_activities: ZarzÄ…dzanie aktywnoÅ›ciami projektu
-  setting_cache_formatted_text: Buforuj sformatowany tekst
-  error_unable_delete_issue_status: Nie moÅ¼na usunÄ…Ä‡ statusu zagadnienia
-  label_profile: Profil
-  permission_manage_subtasks: ZarzÄ…dzanie podzagadnieniami
-  field_parent_issue: Zagadnienie nadrzÄ™dne
-  label_subtask_plural: Podzagadnienia
-  label_project_copy_notifications: WyÅ›lij powiadomienia mailowe przy kopiowaniu projektu
-  error_can_not_delete_custom_field: Nie moÅ¼na usunÄ…Ä‡ tego pola
-  error_unable_to_connect: Nie moÅ¼na poÅ‚Ä…czyÄ‡ (%{value})
-  error_can_not_remove_role: Ta rola przypisana jest niektÃ³rym uÅ¼ytkownikom i nie moÅ¼e zostaÄ‡ usuniÄ™ta.
-  error_can_not_delete_tracker: Ten typ przypisany jest do czÄ™Å›ci zagadnieÅ„ i nie moÅ¼e zostaÄ‡ usuniÄ™ty.
-  field_principal: PrzeÅ‚oÅ¼ony
-  label_my_page_block: Elementy
-  notice_failed_to_save_members: "Nie moÅ¼na zapisaÄ‡ uczestnikÃ³w: %{errors}."
-  text_zoom_out: Zmniejsz czcionkÄ™
-  text_zoom_in: PowiÄ™ksz czcionkÄ™
-  notice_unable_delete_time_entry: Nie moÅ¼na usunÄ…Ä‡ wpisu z dziennika.
-  label_overall_spent_time: Przepracowany czas
-  field_time_entries: Dziennik
-  project_module_gantt: Diagram Gantta
-  project_module_calendar: Kalendarz
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Kodowanie komentarzy zatwierdzeÅ„
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cc/cc76092d2df9eadcf4380975fd38796b31db8ed4.svn-base
--- /dev/null
+++ b/.svn/pristine/cc/cc76092d2df9eadcf4380975fd38796b31db8ed4.svn-base
@@ -0,0 +1,1142 @@
+# Vietnamese translation for Ruby on Rails
+# by
+#   Do Hai Bac (dohaibac@gmail.com)
+#   Dao Thanh Ngoc (ngocdaothanh@gmail.com, http://github.com/ngocdaothanh/rails-i18n/tree/master)
+#   Nguyen Minh Thien (thiencdcn@gmail.com, http://www.eDesignLab.org)
+
+vi:
+  number:
+    # Used in number_with_delimiter()
+    # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
+    format:
+      # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
+      separator: ","
+      # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
+      delimiter: "."
+      # Number of decimals, behind the separator (1 with a precision of 2 gives: 1.00)
+      precision: 3
+
+    # Used in number_to_currency()
+    currency:
+      format:
+        # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
+        format: "%n %u"
+        unit: "Ä‘á»“ng"
+        # These three are to override number.format and are optional
+        separator: ","
+        delimiter: "."
+        precision: 2
+
+    # Used in number_to_percentage()
+    percentage:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # Used in number_to_precision()
+    precision:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        # precision:
+
+    # Used in number_to_human_size()
+    human:
+      format:
+        # These three are to override number.format and are optional
+        # separator:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
+  datetime:
+    distance_in_words:
+      half_a_minute: "30 giÃ¢y"
+      less_than_x_seconds:
+        one:   "chÆ°a tá»›i 1 giÃ¢y"
+        other: "chÆ°a tá»›i %{count} giÃ¢y"
+      x_seconds:
+        one:   "1 giÃ¢y"
+        other: "%{count} giÃ¢y"
+      less_than_x_minutes:
+        one:   "chÆ°a tá»›i 1 phÃºt"
+        other: "chÆ°a tá»›i %{count} phÃºt"
+      x_minutes:
+        one:   "1 phÃºt"
+        other: "%{count} phÃºt"
+      about_x_hours:
+        one:   "khoáº£ng 1 giá»"
+        other: "khoáº£ng %{count} giá»"
+      x_hours:
+        one:   "1 giá»"
+        other: "%{count} giá»"
+      x_days:
+        one:   "1 ngÃ y"
+        other: "%{count} ngÃ y"
+      about_x_months:
+        one:   "khoáº£ng 1 thÃ¡ng"
+        other: "khoáº£ng %{count} thÃ¡ng"
+      x_months:
+        one:   "1 thÃ¡ng"
+        other: "%{count} thÃ¡ng"
+      about_x_years:
+        one:   "khoáº£ng 1 nÄƒm"
+        other: "khoáº£ng %{count} nÄƒm"
+      over_x_years:
+        one:   "hÆ¡n 1 nÄƒm"
+        other: "hÆ¡n %{count} nÄƒm"
+      almost_x_years:
+        one:   "gáº§n 1 nÄƒm"
+        other: "gáº§n %{count} nÄƒm"
+    prompts:
+      year:   "NÄƒm"
+      month:  "ThÃ¡ng"
+      day:    "NgÃ y"
+      hour:   "Giá»"
+      minute: "PhÃºt"
+      second: "GiÃ¢y"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:   "1 lá»—i ngÄƒn khÃ´ng cho lÆ°u %{model} nÃ y"
+          other: "%{count} lá»—i ngÄƒn khÃ´ng cho lÆ°u %{model} nÃ y"
+        # The variable :count is also available
+        body: "CÃ³ lá»—i vá»›i cÃ¡c má»¥c sau:"
+
+      # The values :model, :attribute and :value are always available for interpolation
+      # The value :count is available when applicable. Can be used for pluralization.
+      messages:
+        inclusion: "khÃ´ng cÃ³ trong danh sÃ¡ch"
+        exclusion: "Ä‘Ã£ Ä‘Æ°á»£c giÃ nh trÆ°á»›c"
+        invalid: "khÃ´ng há»£p lá»‡"
+        confirmation: "khÃ´ng khá»›p vá»›i xÃ¡c nháº­n"
+        accepted: "pháº£i Ä‘Æ°á»£c Ä‘á»“ng Ã½"
+        empty: "khÃ´ng thá»ƒ rá»—ng"
+        blank: "khÃ´ng thá»ƒ Ä‘á»ƒ tráº¯ng"
+        too_long: "quÃ¡ dÃ i (tá»‘i Ä‘a %{count} kÃ½ tá»±)"
+        too_short: "quÃ¡ ngáº¯n (tá»‘i thiá»ƒu %{count} kÃ½ tá»±)"
+        wrong_length: "Ä‘á»™ dÃ i khÃ´ng Ä‘Ãºng (pháº£i lÃ  %{count} kÃ½ tá»±)"
+        taken: "Ä‘Ã£ cÃ³"
+        not_a_number: "khÃ´ng pháº£i lÃ  sá»‘"
+        greater_than: "pháº£i lá»›n hÆ¡n %{count}"
+        greater_than_or_equal_to: "pháº£i lá»›n hÆ¡n hoáº·c báº±ng %{count}"
+        equal_to: "pháº£i báº±ng %{count}"
+        less_than: "pháº£i nhá» hÆ¡n %{count}"
+        less_than_or_equal_to: "pháº£i nhá» hÆ¡n hoáº·c báº±ng %{count}"
+        odd: "pháº£i lÃ  sá»‘ cháºµn"
+        even: "pháº£i lÃ  sá»‘ láº»"
+        greater_than_start_date: "pháº£i Ä‘i sau ngÃ y báº¯t Ä‘áº§u"
+        not_same_project: "khÃ´ng thuá»™c cÃ¹ng dá»± Ã¡n"
+        circular_dependency: "quan há»‡ cÃ³ thá»ƒ gÃ¢y ra láº·p vÃ´ táº­n"
+        cant_link_an_issue_with_a_descendant: "Má»™t váº¥n Ä‘á» khÃ´ng thá»ƒ liÃªn káº¿t tá»›i má»™t trong sá»‘ nhá»¯ng tÃ¡c vá»¥ con cá»§a nÃ³"
+
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d-%m-%Y"
+      short: "%d %b"
+      long: "%d %B, %Y"
+
+    day_names: ["Chá»§ nháº­t", "Thá»© hai", "Thá»© ba", "Thá»© tÆ°", "Thá»© nÄƒm", "Thá»© sÃ¡u", "Thá»© báº£y"]
+    abbr_day_names: ["Chá»§ nháº­t", "Thá»© hai", "Thá»© ba", "Thá»© tÆ°", "Thá»© nÄƒm", "Thá»© sÃ¡u", "Thá»© báº£y"]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, "ThÃ¡ng má»™t", "ThÃ¡ng hai", "ThÃ¡ng ba", "ThÃ¡ng tÆ°", "ThÃ¡ng nÄƒm", "ThÃ¡ng sÃ¡u", "ThÃ¡ng báº£y", "ThÃ¡ng tÃ¡m", "ThÃ¡ng chÃ­n", "ThÃ¡ng mÆ°á»i", "ThÃ¡ng mÆ°á»i má»™t", "ThÃ¡ng mÆ°á»i hai"]
+    abbr_month_names: [~, "ThÃ¡ng má»™t", "ThÃ¡ng hai", "ThÃ¡ng ba", "ThÃ¡ng tÆ°", "ThÃ¡ng nÄƒm", "ThÃ¡ng sÃ¡u", "ThÃ¡ng báº£y", "ThÃ¡ng tÃ¡m", "ThÃ¡ng chÃ­n", "ThÃ¡ng mÆ°á»i", "ThÃ¡ng mÆ°á»i má»™t", "ThÃ¡ng mÆ°á»i hai"]
+    # Used in date_select and datime_select.
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%d %B, %Y %H:%M"
+    am: "sÃ¡ng"
+    pm: "chiá»u"
+
+  # Used in array.to_sentence.
+  support:
+    array:
+      words_connector: ", "
+      two_words_connector: " vÃ  "
+      last_word_connector: ", vÃ  "
+
+  actionview_instancetag_blank_option: Vui lÃ²ng chá»n
+
+  general_text_No: 'KhÃ´ng'
+  general_text_Yes: 'CÃ³'
+  general_text_no: 'khÃ´ng'
+  general_text_yes: 'cÃ³'
+  general_lang_name: 'Tiáº¿ng Viá»‡t'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Cáº­p nháº­t tÃ i khoáº£n thÃ nh cÃ´ng.
+  notice_account_invalid_creditentials: TÃ i khoáº£n hoáº·c máº­t mÃ£ khÃ´ng há»£p lá»‡
+  notice_account_password_updated: Cáº­p nháº­t máº­t mÃ£ thÃ nh cÃ´ng.
+  notice_account_wrong_password: Sai máº­t mÃ£
+  notice_account_register_done: TÃ i khoáº£n Ä‘Æ°á»£c táº¡o thÃ nh cÃ´ng. Äá»ƒ kÃ­ch hoáº¡t vui lÃ²ng lÃ m theo hÆ°á»›ng dáº«n trong email gá»­i Ä‘áº¿n báº¡n.
+  notice_account_unknown_email: KhÃ´ng rÃµ tÃ i khoáº£n.
+  notice_can_t_change_password: TÃ i khoáº£n Ä‘Æ°á»£c chá»©ng thá»±c tá»« nguá»“n bÃªn ngoÃ i. KhÃ´ng thá»ƒ Ä‘á»•i máº­t mÃ£ cho loáº¡i chá»©ng thá»±c nÃ y.
+  notice_account_lost_email_sent: ThÃ´ng tin Ä‘á»ƒ Ä‘á»•i máº­t mÃ£ má»›i Ä‘Ã£ gá»­i Ä‘áº¿n báº¡n qua email.
+  notice_account_activated: TÃ i khoáº£n vá»«a Ä‘Æ°á»£c kÃ­ch hoáº¡t. BÃ¢y giá» báº¡n cÃ³ thá»ƒ Ä‘Äƒng nháº­p.
+  notice_successful_create: Táº¡o thÃ nh cÃ´ng.
+  notice_successful_update: Cáº­p nháº­t thÃ nh cÃ´ng.
+  notice_successful_delete: XÃ³a thÃ nh cÃ´ng.
+  notice_successful_connection: Káº¿t ná»‘i thÃ nh cÃ´ng.
+  notice_file_not_found: Trang báº¡n cá»‘ xem khÃ´ng tá»“n táº¡i hoáº·c Ä‘Ã£ chuyá»ƒn.
+  notice_locking_conflict: ThÃ´ng tin Ä‘ang Ä‘Æ°á»£c cáº­p nháº­t bá»Ÿi ngÆ°á»i khÃ¡c. HÃ£y chÃ©p ná»™i dung cáº­p nháº­t cá»§a báº¡n vÃ o clipboard.
+  notice_not_authorized: Báº¡n khÃ´ng cÃ³ quyá»n xem trang nÃ y.
+  notice_email_sent: "Email Ä‘Ã£ Ä‘Æ°á»£c gá»­i tá»›i %{value}"
+  notice_email_error: "Lá»—i xáº£y ra khi gá»­i email (%{value})"
+  notice_feeds_access_key_reseted: MÃ£ sá»‘ chá»©ng thá»±c RSS Ä‘Ã£ Ä‘Æ°á»£c táº¡o láº¡i.
+  notice_failed_to_save_issues: "Tháº¥t báº¡i khi lÆ°u %{count} váº¥n Ä‘á» trong %{total} lá»±a chá»n: %{ids}."
+  notice_no_issue_selected: "KhÃ´ng cÃ³ váº¥n Ä‘á» Ä‘Æ°á»£c chá»n! Vui lÃ²ng kiá»ƒm tra cÃ¡c váº¥n Ä‘á» báº¡n cáº§n chá»‰nh sá»­a."
+  notice_account_pending: "ThÃ´ng tin tÃ i khoáº£n Ä‘Ã£ Ä‘Æ°á»£c táº¡o ra vÃ  Ä‘ang chá» chá»©ng thá»±c tá»« ban quáº£n trá»‹."
+  notice_default_data_loaded: ÄÃ£ náº¡p cáº¥u hÃ¬nh máº·c Ä‘á»‹nh.
+  notice_unable_delete_version: KhÃ´ng thá»ƒ xÃ³a phiÃªn báº£n.
+
+  error_can_t_load_default_data: "KhÃ´ng thá»ƒ náº¡p cáº¥u hÃ¬nh máº·c Ä‘á»‹nh: %{value}"
+  error_scm_not_found: "KhÃ´ng tÃ¬m tháº¥y dá»¯ liá»‡u trong kho chá»©a."
+  error_scm_command_failed: "Lá»—i xáº£y ra khi truy cáº­p vÃ o kho lÆ°u trá»¯: %{value}"
+  error_scm_annotate: "Äáº§u vÃ o khÃ´ng tá»“n táº¡i hoáº·c khÃ´ng thá»ƒ chÃº thÃ­ch."
+  error_issue_not_found_in_project: 'Váº¥n Ä‘á» khÃ´ng tá»“n táº¡i hoáº·c khÃ´ng thuá»™c dá»± Ã¡n'
+
+  mail_subject_lost_password: "%{value}: máº­t mÃ£ cá»§a báº¡n"
+  mail_body_lost_password: "Äá»ƒ Ä‘á»•i máº­t mÃ£, hÃ£y click chuá»™t vÃ o liÃªn káº¿t sau:"
+  mail_subject_register: "%{value}: kÃ­ch hoáº¡t tÃ i khoáº£n"
+  mail_body_register: "Äá»ƒ kÃ­ch hoáº¡t tÃ i khoáº£n, hÃ£y click chuá»™t vÃ o liÃªn káº¿t sau:"
+  mail_body_account_information_external: " Báº¡n cÃ³ thá»ƒ dÃ¹ng tÃ i khoáº£n %{value} Ä‘á»ƒ Ä‘Äƒng nháº­p."
+  mail_body_account_information: ThÃ´ng tin vá» tÃ i khoáº£n
+  mail_subject_account_activation_request: "%{value}: YÃªu cáº§u chá»©ng thá»±c tÃ i khoáº£n"
+  mail_body_account_activation_request: "NgÆ°á»i dÃ¹ng (%{value}) má»›i Ä‘Äƒng kÃ½ vÃ  cáº§n báº¡n xÃ¡c nháº­n:"
+  mail_subject_reminder: "%{count} váº¥n Ä‘á» háº¿t háº¡n trong cÃ¡c %{days} ngÃ y tá»›i"
+  mail_body_reminder: "%{count} cÃ´ng viá»‡c báº¡n Ä‘Æ°á»£c phÃ¢n cÃ´ng sáº½ háº¿t háº¡n trong %{days} ngÃ y tá»›i:"
+
+  field_name: TÃªn dá»± Ã¡n
+  field_description: MÃ´ táº£
+  field_summary: TÃ³m táº¯t
+  field_is_required: Báº¯t buá»™c
+  field_firstname: TÃªn Ä‘á»‡m vÃ  TÃªn
+  field_lastname: Há»
+  field_mail: Email
+  field_filename: Táº­p tin
+  field_filesize: Cá»¡
+  field_downloads: Táº£i vá»
+  field_author: TÃ¡c giáº£
+  field_created_on: Táº¡o
+  field_updated_on: Cáº­p nháº­t
+  field_field_format: Äá»‹nh dáº¡ng
+  field_is_for_all: Cho má»i dá»± Ã¡n
+  field_possible_values: GiÃ¡ trá»‹ há»£p lá»‡
+  field_regexp: Biá»ƒu thá»©c chÃ­nh quy
+  field_min_length: Chiá»u dÃ i tá»‘i thiá»ƒu
+  field_max_length: Chiá»u dÃ i tá»‘i Ä‘a
+  field_value: GiÃ¡ trá»‹
+  field_category: Chá»§ Ä‘á»
+  field_title: TiÃªu Ä‘á»
+  field_project: Dá»± Ã¡n
+  field_issue: Váº¥n Ä‘á»
+  field_status: Tráº¡ng thÃ¡i
+  field_notes: Ghi chÃº
+  field_is_closed: Váº¥n Ä‘á» Ä‘Ã³ng
+  field_is_default: GiÃ¡ trá»‹ máº·c Ä‘á»‹nh
+  field_tracker: Kiá»ƒu váº¥n Ä‘á»
+  field_subject: Chá»§ Ä‘á»
+  field_due_date: Háº¿t háº¡n
+  field_assigned_to: PhÃ¢n cÃ´ng cho
+  field_priority: Má»©c Æ°u tiÃªn
+  field_fixed_version: PhiÃªn báº£n
+  field_user: NgÆ°á»i dÃ¹ng
+  field_role: Quyá»n
+  field_homepage: Trang chá»§
+  field_is_public: CÃ´ng cá»™ng
+  field_parent: Dá»± Ã¡n con cá»§a
+  field_is_in_roadmap: CÃ³ thá»ƒ tháº¥y trong Káº¿ hoáº¡ch
+  field_login: ÄÄƒng nháº­p
+  field_mail_notification: ThÃ´ng bÃ¡o qua email
+  field_admin: Quáº£n trá»‹
+  field_last_login_on: Káº¿t ná»‘i cuá»‘i
+  field_language: NgÃ´n ngá»¯
+  field_effective_date: NgÃ y
+  field_password: Máº­t kháº©u
+  field_new_password: Máº­t kháº©u má»›i
+  field_password_confirmation: Nháº­p láº¡i máº­t kháº©u
+  field_version: PhiÃªn báº£n
+  field_type: Kiá»ƒu
+  field_host: Host
+  field_port: Cá»•ng
+  field_account: TÃ i khoáº£n
+  field_base_dn: Base DN
+  field_attr_login: Thuá»™c tÃ­nh Ä‘Äƒng nháº­p
+  field_attr_firstname: Thuá»™c tÃ­nh tÃªn Ä‘á»‡m vÃ  TÃªn
+  field_attr_lastname: Thuá»™c tÃ­nh Há»
+  field_attr_mail: Thuá»™c tÃ­nh Email
+  field_onthefly: Táº¡o ngÆ°á»i dÃ¹ng tá»©c thÃ¬
+  field_start_date: Báº¯t Ä‘áº§u
+  field_done_ratio: Tiáº¿n Ä‘á»™
+  field_auth_source: Cháº¿ Ä‘á»™ xÃ¡c thá»±c
+  field_hide_mail: KhÃ´ng hiá»‡n email cá»§a tÃ´i
+  field_comments: BÃ¬nh luáº­n
+  field_url: URL
+  field_start_page: Trang báº¯t Ä‘áº§u
+  field_subproject: Dá»± Ã¡n con
+  field_hours: Giá»
+  field_activity: Hoáº¡t Ä‘á»™ng
+  field_spent_on: NgÃ y
+  field_identifier: MÃ£ nháº­n dáº¡ng
+  field_is_filter: DÃ¹ng nhÆ° bá»™ lá»c
+  field_issue_to: Váº¥n Ä‘á» liÃªn quan
+  field_delay: Äá»™ trá»…
+  field_assignable: Váº¥n Ä‘á» cÃ³ thá»ƒ gÃ¡n cho vai trÃ² nÃ y
+  field_redirect_existing_links: Chuyá»ƒn hÆ°á»›ng trang Ä‘Ã£ cÃ³
+  field_estimated_hours: Thá»i gian Æ°á»›c lÆ°á»£ng
+  field_column_names: Cá»™t
+  field_time_zone: MÃºi giá»
+  field_searchable: TÃ¬m kiáº¿m Ä‘Æ°á»£c
+  field_default_value: GiÃ¡ trá»‹ máº·c Ä‘á»‹nh
+  field_comments_sorting: Liá»‡t kÃª bÃ¬nh luáº­n
+  field_parent_title: Trang máº¹
+
+  setting_app_title: Tá»±a Ä‘á» á»©ng dá»¥ng
+  setting_app_subtitle: Tá»±a Ä‘á» nhá» cá»§a á»©ng dá»¥ng
+  setting_welcome_text: ThÃ´ng Ä‘iá»‡p chÃ o má»«ng
+  setting_default_language: NgÃ´n ngá»¯ máº·c Ä‘á»‹nh
+  setting_login_required: Cáº§n Ä‘Äƒng nháº­p
+  setting_self_registration: Tá»± chá»©ng thá»±c
+  setting_attachment_max_size: Cá»¡ tá»‘i Ä‘a cá»§a táº­p tin Ä‘Ã­nh kÃ¨m
+  setting_issues_export_limit: Giá»›i háº¡n Export váº¥n Ä‘á»
+  setting_mail_from: Äá»‹a chá»‰ email gá»­i thÃ´ng bÃ¡o
+  setting_bcc_recipients: Táº¡o báº£n CC bÃ­ máº­t (bcc)
+  setting_host_name: TÃªn miá»n vÃ  Ä‘Æ°á»ng dáº«n
+  setting_text_formatting: Äá»‹nh dáº¡ng bÃ i viáº¿t
+  setting_wiki_compression: NÃ©n lá»‹ch sá»­ Wiki
+  setting_feeds_limit: Giá»›i háº¡n ná»™i dung cá»§a feed
+  setting_default_projects_public: Dá»± Ã¡n máº·c Ä‘á»‹nh lÃ  public
+  setting_autofetch_changesets: Tá»± Ä‘á»™ng tÃ¬m náº¡p commits
+  setting_sys_api_enabled: Cho phÃ©p WS quáº£n lÃ½ kho chá»©a
+  setting_commit_ref_keywords: Tá»« khÃ³a tham kháº£o
+  setting_commit_fix_keywords: Tá»« khÃ³a chá»‰ váº¥n Ä‘á» Ä‘Ã£ giáº£i quyáº¿t
+  setting_autologin: Tá»± Ä‘á»™ng Ä‘Äƒng nháº­p
+  setting_date_format: Äá»‹nh dáº¡ng ngÃ y
+  setting_time_format: Äá»‹nh dáº¡ng giá»
+  setting_cross_project_issue_relations: Cho phÃ©p quan há»‡ chÃ©o giá»¯a cÃ¡c dá»± Ã¡n
+  setting_issue_list_default_columns: CÃ¡c cá»™t máº·c Ä‘á»‹nh hiá»ƒn thá»‹ trong danh sÃ¡ch váº¥n Ä‘á»
+  setting_emails_footer: Chá»¯ kÃ½ cuá»‘i thÆ°
+  setting_protocol: Giao thá»©c
+  setting_per_page_options: TÃ¹y chá»n Ä‘á»‘i tÆ°á»£ng má»—i trang
+  setting_user_format: Äá»‹nh dáº¡ng hiá»ƒn thá»‹ ngÆ°á»i dÃ¹ng
+  setting_activity_days_default: NgÃ y hiá»ƒn thá»‹ hoáº¡t Ä‘á»™ng cá»§a dá»± Ã¡n
+  setting_display_subprojects_issues: Hiá»ƒn thá»‹ máº·c Ä‘á»‹nh váº¥n Ä‘á» cá»§a dá»± Ã¡n con á»Ÿ dá»± Ã¡n chÃ­nh
+  setting_enabled_scm: Cho phÃ©p SCM
+  setting_mail_handler_api_enabled: Cho phÃ©p WS cho cÃ¡c email tá»›i
+  setting_mail_handler_api_key: MÃ£ sá»‘ API
+  setting_sequential_project_identifiers: Tá»± sinh chuá»—i ID dá»± Ã¡n
+
+  project_module_issue_tracking: Theo dÃµi váº¥n Ä‘á»
+  project_module_time_tracking: Theo dÃµi thá»i gian
+  project_module_news: Tin tá»©c
+  project_module_documents: TÃ i liá»‡u
+  project_module_files: Táº­p tin
+  project_module_wiki: Wiki
+  project_module_repository: Kho lÆ°u trá»¯
+  project_module_boards: Diá»…n Ä‘Ã n
+
+  label_user: TÃ i khoáº£n
+  label_user_plural: TÃ i khoáº£n
+  label_user_new: TÃ i khoáº£n má»›i
+  label_project: Dá»± Ã¡n
+  label_project_new: Dá»± Ã¡n má»›i
+  label_project_plural: Dá»± Ã¡n
+  label_x_projects:
+    zero:  khÃ´ng cÃ³ dá»± Ã¡n
+    one:   má»™t dá»± Ã¡n
+    other: "%{count} dá»± Ã¡n"
+  label_project_all: Má»i dá»± Ã¡n
+  label_project_latest: Dá»± Ã¡n má»›i nháº¥t
+  label_issue: Váº¥n Ä‘á»
+  label_issue_new: Táº¡o váº¥n Ä‘á» má»›i
+  label_issue_plural: Váº¥n Ä‘á»
+  label_issue_view_all: Táº¥t cáº£ váº¥n Ä‘á»
+  label_issues_by: "Váº¥n Ä‘á» cá»§a %{value}"
+  label_issue_added: ÄÃ£ thÃªm váº¥n Ä‘á»
+  label_issue_updated: Váº¥n Ä‘á» Ä‘Æ°á»£c cáº­p nháº­t
+  label_document: TÃ i liá»‡u
+  label_document_new: TÃ i liá»‡u má»›i
+  label_document_plural: TÃ i liá»‡u
+  label_document_added: ÄÃ£ thÃªm tÃ i liá»‡u
+  label_role: Vai trÃ²
+  label_role_plural: Vai trÃ²
+  label_role_new: Vai trÃ² má»›i
+  label_role_and_permissions: Vai trÃ² vÃ  Quyá»n háº¡n
+  label_member: ThÃ nh viÃªn
+  label_member_new: ThÃ nh viÃªn má»›i
+  label_member_plural: ThÃ nh viÃªn
+  label_tracker: Kiá»ƒu váº¥n Ä‘á»
+  label_tracker_plural: Kiá»ƒu váº¥n Ä‘á»
+  label_tracker_new: Táº¡o kiá»ƒu váº¥n Ä‘á» má»›i
+  label_workflow: Quy trÃ¬nh lÃ m viá»‡c
+  label_issue_status: Tráº¡ng thÃ¡i váº¥n Ä‘á»
+  label_issue_status_plural: Tráº¡ng thÃ¡i váº¥n Ä‘á»
+  label_issue_status_new: ThÃªm tráº¡ng thÃ¡i
+  label_issue_category: Chá»§ Ä‘á»
+  label_issue_category_plural: Chá»§ Ä‘á»
+  label_issue_category_new: Chá»§ Ä‘á» má»›i
+  label_custom_field: TrÆ°á»ng tÃ¹y biáº¿n
+  label_custom_field_plural: TrÆ°á»ng tÃ¹y biáº¿n
+  label_custom_field_new: ThÃªm TrÆ°á»ng tÃ¹y biáº¿n
+  label_enumerations: Liá»‡t kÃª
+  label_enumeration_new: ThÃªm giÃ¡ trá»‹
+  label_information: ThÃ´ng tin
+  label_information_plural: ThÃ´ng tin
+  label_please_login: Vui lÃ²ng Ä‘Äƒng nháº­p
+  label_register: ÄÄƒng kÃ½
+  label_password_lost: Phá»¥c há»“i máº­t mÃ£
+  label_home: Trang chÃ­nh
+  label_my_page: Trang riÃªng
+  label_my_account: CÃ¡ nhÃ¢n
+  label_my_projects: Dá»± Ã¡n cá»§a báº¡n
+  label_administration: Quáº£n trá»‹
+  label_login: ÄÄƒng nháº­p
+  label_logout: ThoÃ¡t
+  label_help: GiÃºp Ä‘á»¡
+  label_reported_issues: CÃ´ng viá»‡c báº¡n phÃ¢n cÃ´ng
+  label_assigned_to_me_issues: CÃ´ng viá»‡c Ä‘Æ°á»£c phÃ¢n cÃ´ng
+  label_last_login: Káº¿t ná»‘i cuá»‘i
+  label_registered_on: NgÃ y tham gia
+  label_activity: Hoáº¡t Ä‘á»™ng
+  label_overall_activity: Táº¥t cáº£ hoáº¡t Ä‘á»™ng
+  label_new: Má»›i
+  label_logged_as: TÃ i khoáº£n &raquo;
+  label_environment: MÃ´i trÆ°á»ng
+  label_authentication: XÃ¡c thá»±c
+  label_auth_source: Cháº¿ Ä‘á»™ xÃ¡c thá»±c
+  label_auth_source_new: Cháº¿ Ä‘á»™ xÃ¡c thá»±c má»›i
+  label_auth_source_plural: Cháº¿ Ä‘á»™ xÃ¡c thá»±c
+  label_subproject_plural: Dá»± Ã¡n con
+  label_and_its_subprojects: "%{value} vÃ  dá»± Ã¡n con"
+  label_min_max_length: Äá»™ dÃ i nhá» nháº¥t - lá»›n nháº¥t
+  label_list: Danh sÃ¡ch
+  label_date: NgÃ y
+  label_integer: Sá»‘ nguyÃªn
+  label_float: Sá»‘ thá»±c
+  label_boolean: Boolean
+  label_string: VÄƒn báº£n
+  label_text: VÄƒn báº£n dÃ i
+  label_attribute: Thuá»™c tÃ­nh
+  label_attribute_plural: CÃ¡c thuá»™c tÃ­nh
+  label_no_data: ChÆ°a cÃ³ thÃ´ng tin gÃ¬
+  label_change_status: Äá»•i tráº¡ng thÃ¡i
+  label_history: LÆ°á»£c sá»­
+  label_attachment: Táº­p tin
+  label_attachment_new: ThÃªm táº­p tin má»›i
+  label_attachment_delete: XÃ³a táº­p tin
+  label_attachment_plural: Táº­p tin
+  label_file_added: ÄÃ£ thÃªm táº­p tin
+  label_report: BÃ¡o cÃ¡o
+  label_report_plural: BÃ¡o cÃ¡o
+  label_news: Tin tá»©c
+  label_news_new: ThÃªm tin
+  label_news_plural: Tin tá»©c
+  label_news_latest: Tin má»›i
+  label_news_view_all: Xem má»i tin
+  label_news_added: ÄÃ£ thÃªm tin
+  label_settings: Thiáº¿t láº­p
+  label_overview: TÃ³m táº¯t
+  label_version: PhiÃªn báº£n
+  label_version_new: PhiÃªn báº£n má»›i
+  label_version_plural: PhiÃªn báº£n
+  label_confirmation: Kháº³ng Ä‘á»‹nh
+  label_export_to: 'Äá»‹nh dáº¡ng khÃ¡c cá»§a trang nÃ y:'
+  label_read: Äá»c...
+  label_public_projects: CÃ¡c dá»± Ã¡n cÃ´ng cá»™ng
+  label_open_issues: má»Ÿ
+  label_open_issues_plural: má»Ÿ
+  label_closed_issues: Ä‘Ã³ng
+  label_closed_issues_plural: Ä‘Ã³ng
+  label_x_open_issues_abbr_on_total:
+    zero:  "0 má»Ÿ / %{total}"
+    one:   "1 má»Ÿ / %{total}"
+    other: "%{count} má»Ÿ / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 má»Ÿ
+    one:   1 má»Ÿ
+    other: "%{count} má»Ÿ"
+  label_x_closed_issues_abbr:
+    zero:  0 Ä‘Ã³ng
+    one:   1 Ä‘Ã³ng
+    other: "%{count} Ä‘Ã³ng"
+  label_total: Tá»•ng cá»™ng
+  label_permissions: Quyá»n
+  label_current_status: Tráº¡ng thÃ¡i hiá»‡n táº¡i
+  label_new_statuses_allowed: Tráº¡ng thÃ¡i má»›i Ä‘Æ°á»£c phÃ©p
+  label_all: Táº¥t cáº£
+  label_none: khÃ´ng
+  label_nobody: Cháº³ng ai
+  label_next: Sau
+  label_previous: TrÆ°á»›c
+  label_used_by: ÄÆ°á»£c dÃ¹ng bá»Ÿi
+  label_details: Chi tiáº¿t
+  label_add_note: ThÃªm ghi chÃº
+  label_per_page: Má»—i trang
+  label_calendar: Lá»‹ch
+  label_months_from: thÃ¡ng tá»«
+  label_gantt: Biá»ƒu Ä‘á»“ sá»± kiá»‡n
+  label_internal: Ná»™i bá»™
+  label_last_changes: "%{count} thay Ä‘á»•i cuá»‘i"
+  label_change_view_all: Xem má»i thay Ä‘á»•i
+  label_personalize_page: Äiá»u chá»‰nh trang nÃ y
+  label_comment: BÃ¬nh luáº­n
+  label_comment_plural: BÃ¬nh luáº­n
+  label_x_comments:
+    zero: khÃ´ng cÃ³ bÃ¬nh luáº­n
+    one: 1 bÃ¬nh luáº­n
+    other: "%{count} bÃ¬nh luáº­n"
+  label_comment_add: ThÃªm bÃ¬nh luáº­n
+  label_comment_added: ÄÃ£ thÃªm bÃ¬nh luáº­n
+  label_comment_delete: XÃ³a bÃ¬nh luáº­n
+  label_query: Truy váº¥n riÃªng
+  label_query_plural: Truy váº¥n riÃªng
+  label_query_new: Truy váº¥n má»›i
+  label_filter_add: ThÃªm lá»c
+  label_filter_plural: Bá»™ lá»c
+  label_equals: lÃ 
+  label_not_equals: khÃ´ng lÃ 
+  label_in_less_than: Ã­t hÆ¡n
+  label_in_more_than: nhiá»u hÆ¡n
+  label_in: trong
+  label_today: hÃ´m nay
+  label_all_time: má»i thá»i gian
+  label_yesterday: hÃ´m qua
+  label_this_week: tuáº§n nÃ y
+  label_last_week: tuáº§n trÆ°á»›c
+  label_last_n_days: "%{count} ngÃ y cuá»‘i"
+  label_this_month: thÃ¡ng nÃ y
+  label_last_month: thÃ¡ng cuá»‘i
+  label_this_year: nÄƒm nÃ y
+  label_date_range: Thá»i gian
+  label_less_than_ago: cÃ¡ch Ä‘Ã¢y dÆ°á»›i
+  label_more_than_ago: cÃ¡ch Ä‘Ã¢y hÆ¡n
+  label_ago: cÃ¡ch Ä‘Ã¢y
+  label_contains: chá»©a
+  label_not_contains: khÃ´ng chá»©a
+  label_day_plural: ngÃ y
+  label_repository: Kho lÆ°u trá»¯
+  label_repository_plural: Kho lÆ°u trá»¯
+  label_browse: Duyá»‡t
+  label_revision: Báº£n Ä‘iá»u chá»‰nh
+  label_revision_plural: Báº£n Ä‘iá»u chá»‰nh
+  label_associated_revisions: CÃ¡c báº£n Ä‘iá»u chá»‰nh Ä‘Æ°á»£c ghÃ©p
+  label_added: thÃªm
+  label_modified: Ä‘á»•i
+  label_copied: chÃ©p
+  label_renamed: Ä‘á»•i tÃªn
+  label_deleted: xÃ³a
+  label_latest_revision: Báº£n Ä‘iá»u chá»‰nh cuá»‘i cÃ¹ng
+  label_latest_revision_plural: Báº£n Ä‘iá»u chá»‰nh cuá»‘i cÃ¹ng
+  label_view_revisions: Xem cÃ¡c báº£n Ä‘iá»u chá»‰nh
+  label_max_size: Dung lÆ°á»£ng tá»‘i Ä‘a
+  label_sort_highest: LÃªn trÃªn cÃ¹ng
+  label_sort_higher: Dá»‹ch lÃªn
+  label_sort_lower: Dá»‹ch xuá»‘ng
+  label_sort_lowest: Xuá»‘ng dÆ°á»›i cÃ¹ng
+  label_roadmap: Káº¿ hoáº¡ch
+  label_roadmap_due_in: "Háº¿t háº¡n trong %{value}"
+  label_roadmap_overdue: "Trá»… %{value}"
+  label_roadmap_no_issues: KhÃ´ng cÃ³ váº¥n Ä‘á» cho phiÃªn báº£n nÃ y
+  label_search: TÃ¬m
+  label_result_plural: Káº¿t quáº£
+  label_all_words: Má»i tá»«
+  label_wiki: Wiki
+  label_wiki_edit: Sá»­a Wiki
+  label_wiki_edit_plural: Thay Ä‘á»•i wiki
+  label_wiki_page: Trang wiki
+  label_wiki_page_plural: Trang wiki
+  label_index_by_title: Danh sÃ¡ch theo tÃªn
+  label_index_by_date: Danh sÃ¡ch theo ngÃ y
+  label_current_version: Báº£n hiá»‡n táº¡i
+  label_preview: Xem trÆ°á»›c
+  label_feed_plural: Nguá»“n cáº¥p tin
+  label_changes_details: Chi tiáº¿t cá»§a má»i thay Ä‘á»•i
+  label_issue_tracking: Váº¥n Ä‘á»
+  label_spent_time: Thá»i gian
+  label_f_hour: "%{value} giá»"
+  label_f_hour_plural: "%{value} giá»"
+  label_time_tracking: Theo dÃµi thá»i gian
+  label_change_plural: Thay Ä‘á»•i
+  label_statistics: Thá»‘ng kÃª
+  label_commits_per_month: Commits má»—i thÃ¡ng
+  label_commits_per_author: Commits má»—i tÃ¡c giáº£
+  label_view_diff: So sÃ¡nh
+  label_diff_inline: inline
+  label_diff_side_by_side: bÃªn cáº¡nh nhau
+  label_options: TÃ¹y chá»n
+  label_copy_workflow_from: Sao chÃ©p quy trÃ¬nh tá»«
+  label_permissions_report: Thá»‘ng kÃª cÃ¡c quyá»n
+  label_watched_issues: Chá»§ Ä‘á» Ä‘ang theo dÃµi
+  label_related_issues: LiÃªn quan
+  label_applied_status: Tráº¡ng thÃ¡i Ã¡p dá»¥ng
+  label_loading: Äang xá»­ lÃ½...
+  label_relation_new: Quan há»‡ má»›i
+  label_relation_delete: XÃ³a quan há»‡
+  label_relates_to: liÃªn quan
+  label_duplicates: trÃ¹ng vá»›i
+  label_duplicated_by: bá»‹ trÃ¹ng bá»Ÿi
+  label_blocks: cháº·n
+  label_blocked_by: cháº·n bá»Ÿi
+  label_precedes: Ä‘i trÆ°á»›c
+  label_follows: Ä‘i sau
+  label_end_to_start: cuá»‘i tá»›i Ä‘áº§u
+  label_end_to_end: cuá»‘i tá»›i cuá»‘i
+  label_start_to_start: Ä‘áº§u tá»› Ä‘áº§u
+  label_start_to_end: Ä‘áº§u tá»›i cuá»‘i
+  label_stay_logged_in: LÆ°u thÃ´ng tin Ä‘Äƒng nháº­p
+  label_disabled: Bá»‹ vÃ´ hiá»‡u
+  label_show_completed_versions: Xem phiÃªn báº£n Ä‘Ã£ hoÃ n thÃ nh
+  label_me: tÃ´i
+  label_board: Diá»…n Ä‘Ã n
+  label_board_new: Táº¡o diá»…n Ä‘Ã n má»›i
+  label_board_plural: Diá»…n Ä‘Ã n
+  label_topic_plural: Chá»§ Ä‘á»
+  label_message_plural: Diá»…n Ä‘Ã n
+  label_message_last: BÃ i cuá»‘i
+  label_message_new: Táº¡o bÃ i má»›i
+  label_message_posted: ÄÃ£ thÃªm bÃ i viáº¿t
+  label_reply_plural: Há»“i Ã¢m
+  label_send_information: Gá»­i thÃ´ng tin Ä‘áº¿n ngÆ°á»i dÃ¹ng qua email
+  label_year: NÄƒm
+  label_month: ThÃ¡ng
+  label_week: Tuáº§n
+  label_date_from: Tá»«
+  label_date_to: Äáº¿n
+  label_language_based: Theo ngÃ´n ngá»¯ ngÆ°á»i dÃ¹ng
+  label_sort_by: "Sáº¯p xáº¿p theo %{value}"
+  label_send_test_email: Gá»­i má»™t email kiá»ƒm tra
+  label_feeds_access_key_created_on: "MÃ£ chá»©ng thá»±c RSS Ä‘Æ°á»£c táº¡o ra cÃ¡ch Ä‘Ã¢y %{value}"
+  label_module_plural: Module
+  label_added_time_by: "ThÃªm bá»Ÿi %{author} cÃ¡ch Ä‘Ã¢y %{age}"
+  label_updated_time: "Cáº­p nháº­t cÃ¡ch Ä‘Ã¢y %{value}"
+  label_jump_to_a_project: Nháº£y Ä‘áº¿n dá»± Ã¡n...
+  label_file_plural: Táº­p tin
+  label_changeset_plural: Thay Ä‘á»•i
+  label_default_columns: Cá»™t máº·c Ä‘á»‹nh
+  label_no_change_option: (khÃ´ng Ä‘á»•i)
+  label_bulk_edit_selected_issues: Sá»­a nhiá»u váº¥n Ä‘á»
+  label_theme: Giao diá»‡n
+  label_default: Máº·c Ä‘á»‹nh
+  label_search_titles_only: Chá»‰ tÃ¬m trong tá»±a Ä‘á»
+  label_user_mail_option_all: "Má»i sá»± kiá»‡n trÃªn má»i dá»± Ã¡n cá»§a tÃ´i"
+  label_user_mail_option_selected: "Má»i sá»± kiá»‡n trÃªn cÃ¡c dá»± Ã¡n Ä‘Æ°á»£c chá»n..."
+  label_user_mail_no_self_notified: "Äá»«ng gá»­i email vá» cÃ¡c thay Ä‘á»•i do chÃ­nh tÃ´i thá»±c hiá»‡n"
+  label_registration_activation_by_email: kÃ­ch hoáº¡t tÃ i khoáº£n qua email
+  label_registration_manual_activation: kÃ­ch hoáº¡t tÃ i khoáº£n thá»§ cÃ´ng
+  label_registration_automatic_activation: kÃ­ch hoáº¡t tÃ i khoáº£n tá»± Ä‘á»™ng
+  label_display_per_page: "má»—i trang: %{value}"
+  label_age: Thá»i gian
+  label_change_properties: Thay Ä‘á»•i thuá»™c tÃ­nh
+  label_general: Tá»•ng quan
+  label_more: Chi tiáº¿t
+  label_scm: SCM
+  label_plugins: Module
+  label_ldap_authentication: Chá»©ng thá»±c LDAP
+  label_downloads_abbr: Sá»‘ lÆ°á»£ng Download
+  label_optional_description: MÃ´ táº£ bá»• sung
+  label_add_another_file: ThÃªm táº­p tin khÃ¡c
+  label_preferences: Cáº¥u hÃ¬nh
+  label_chronological_order: BÃ i cÅ© xáº¿p trÆ°á»›c
+  label_reverse_chronological_order: BÃ i má»›i xáº¿p trÆ°á»›c
+  label_planning: Káº¿ hoáº¡ch
+  label_incoming_emails: Nháº­n mail
+  label_generate_key: Táº¡o mÃ£
+  label_issue_watchers: Theo dÃµi
+
+  button_login: ÄÄƒng nháº­p
+  button_submit: Gá»­i
+  button_save: LÆ°u
+  button_check_all: ÄÃ¡nh dáº¥u táº¥t cáº£
+  button_uncheck_all: Bá» dáº¥u táº¥t cáº£
+  button_delete: XÃ³a
+  button_create: Táº¡o
+  button_test: Kiá»ƒm tra
+  button_edit: Sá»­a
+  button_add: ThÃªm
+  button_change: Äá»•i
+  button_apply: Ãp dá»¥ng
+  button_clear: XÃ³a
+  button_lock: KhÃ³a
+  button_unlock: Má»Ÿ khÃ³a
+  button_download: Táº£i vá»
+  button_list: Liá»‡t kÃª
+  button_view: Xem
+  button_move: Chuyá»ƒn
+  button_back: Quay láº¡i
+  button_cancel: Bá» qua
+  button_activate: KÃ­ch hoáº¡t
+  button_sort: Sáº¯p xáº¿p
+  button_log_time: ThÃªm thá»i gian
+  button_rollback: Quay trá»Ÿ láº¡i phiÃªn báº£n nÃ y
+  button_watch: Theo dÃµi
+  button_unwatch: Bá» theo dÃµi
+  button_reply: Tráº£ lá»i
+  button_archive: ÄÃ³ng bÄƒng
+  button_unarchive: Xáº£ bÄƒng
+  button_reset: Táº¡o láº¡i
+  button_rename: Äá»•i tÃªn
+  button_change_password: Äá»•i máº­t mÃ£
+  button_copy: Sao chÃ©p
+  button_annotate: ChÃº giáº£i
+  button_update: Cáº­p nháº­t
+  button_configure: Cáº¥u hÃ¬nh
+  button_quote: TrÃ­ch dáº«n
+
+  status_active: Äang hoáº¡t Ä‘á»™ng
+  status_registered: Má»›i Ä‘Äƒng kÃ½
+  status_locked: ÄÃ£ khÃ³a
+
+  text_select_mail_notifications: Chá»n hÃ nh Ä‘á»™ng Ä‘á»‘i vá»›i má»—i email sáº½ gá»­i.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 Ä‘á»ƒ chá»‰ khÃ´ng háº¡n cháº¿
+  text_project_destroy_confirmation: Báº¡n cÃ³ cháº¯c cháº¯n muá»‘n xÃ³a dá»± Ã¡n nÃ y vÃ  cÃ¡c dá»¯ liá»‡u liÃªn quan ?
+  text_subprojects_destroy_warning: "Dá»± Ã¡n con cá»§a : %{value} cÅ©ng sáº½ bá»‹ xÃ³a."
+  text_workflow_edit: Chá»n má»™t vai trÃ² vÃ  má»™t váº¥n Ä‘á» Ä‘á»ƒ sá»­a quy trÃ¬nh
+  text_are_you_sure: Báº¡n cháº¯c chá»©?
+  text_tip_issue_begin_day: ngÃ y báº¯t Ä‘áº§u
+  text_tip_issue_end_day: ngÃ y káº¿t thÃºc
+  text_tip_issue_begin_end_day: báº¯t Ä‘áº§u vÃ  káº¿t thÃºc cÃ¹ng ngÃ y
+  text_caracters_maximum: "Tá»‘i Ä‘a %{count} kÃ½ tá»±."
+  text_caracters_minimum: "Pháº£i gá»“m Ã­t nháº¥t %{count} kÃ½ tá»±."
+  text_length_between: "Chiá»u dÃ i giá»¯a %{min} vÃ  %{max} kÃ½ tá»±."
+  text_tracker_no_workflow: KhÃ´ng cÃ³ quy trÃ¬nh Ä‘Æ°á»£c Ä‘á»‹nh nghÄ©a cho theo dÃµi nÃ y
+  text_unallowed_characters: KÃ½ tá»± khÃ´ng há»£p lá»‡
+  text_comma_separated: Nhiá»u giÃ¡ trá»‹ Ä‘Æ°á»£c phÃ©p (cÃ¡ch nhau bá»Ÿi dáº¥u pháº©y).
+  text_issues_ref_in_commit_messages: Váº¥n Ä‘á» tham kháº£o vÃ  cá»‘ Ä‘á»‹nh trong ghi chÃº commit
+  text_issue_added: "Váº¥n Ä‘á» %{id} Ä‘Ã£ Ä‘Æ°á»£c bÃ¡o cÃ¡o bá»Ÿi %{author}."
+  text_issue_updated: "Váº¥n Ä‘á» %{id} Ä‘Ã£ Ä‘Æ°á»£c cáº­p nháº­t bá»Ÿi %{author}."
+  text_wiki_destroy_confirmation: Báº¡n cÃ³ cháº¯c cháº¯n muá»‘n xÃ³a trang wiki nÃ y vÃ  táº¥t cáº£ ná»™i dung cá»§a nÃ³ ?
+  text_issue_category_destroy_question: "Má»™t sá»‘ váº¥n Ä‘á» (%{count}) Ä‘Æ°á»£c gÃ¡n cho danh má»¥c nÃ y. Báº¡n muá»‘n lÃ m gÃ¬ ?"
+  text_issue_category_destroy_assignments: Gá»¡ bá» danh má»¥c Ä‘Æ°á»£c phÃ¢n cÃ´ng
+  text_issue_category_reassign_to: GÃ¡n láº¡i váº¥n Ä‘á» cho danh má»¥c nÃ y
+  text_user_mail_option: "Vá»›i cÃ¡c dá»± Ã¡n khÃ´ng Ä‘Æ°á»£c chá»n, báº¡n chá»‰ cÃ³ thá»ƒ nháº­n Ä‘Æ°á»£c thÃ´ng bÃ¡o vá» cÃ¡c váº¥n Ä‘á» báº¡n Ä‘Äƒng kÃ½ theo dÃµi hoáº·c cÃ³ liÃªn quan Ä‘áº¿n báº¡n (cháº³ng háº¡n, váº¥n Ä‘á» Ä‘Æ°á»£c gÃ¡n cho báº¡n)."
+  text_no_configuration_data: "Quyá»n, theo dÃµi, tÃ¬nh tráº¡ng váº¥n Ä‘á» vÃ  quy trÃ¬nh chÆ°a Ä‘Æ°á»£c cáº¥u hÃ¬nh.\nBáº¯t buá»™c pháº£i náº¡p cáº¥u hÃ¬nh máº·c Ä‘á»‹nh. Báº¡n sáº½ thay Ä‘á»•i nÃ³ Ä‘Æ°á»£c sau khi Ä‘Ã£ náº¡p."
+  text_load_default_configuration: Náº¡p láº¡i cáº¥u hÃ¬nh máº·c Ä‘á»‹nh
+  text_status_changed_by_changeset: "Ãp dá»¥ng trong changeset : %{value}."
+  text_issues_destroy_confirmation: 'Báº¡n cÃ³ cháº¯c cháº¯n muá»‘n xÃ³a cÃ¡c váº¥n Ä‘á» Ä‘Ã£ chá»n ?'
+  text_select_project_modules: 'Chá»n cÃ¡c module cho dá»± Ã¡n:'
+  text_default_administrator_account_changed: Thay Ä‘á»•i tÃ i khoáº£n quáº£n trá»‹ máº·c Ä‘á»‹nh
+  text_file_repository_writable: Cho phÃ©p ghi thÆ° má»¥c Ä‘Ã­nh kÃ¨m
+  text_rmagick_available: Tráº¡ng thÃ¡i RMagick
+  text_destroy_time_entries_question: "Thá»i gian %{hours} giá» Ä‘Ã£ bÃ¡o cÃ¡o trong váº¥n Ä‘á» báº¡n Ä‘á»‹nh xÃ³a. Báº¡n muá»‘n lÃ m gÃ¬ tiáº¿p ?"
+  text_destroy_time_entries: XÃ³a thá»i gian bÃ¡o cÃ¡o
+  text_assign_time_entries_to_project: GÃ¡n thá»i gian bÃ¡o cÃ¡o cho dá»± Ã¡n
+  text_reassign_time_entries: 'GÃ¡n láº¡i thá»i gian bÃ¡o cÃ¡o cho Váº¥n Ä‘á» nÃ y:'
+  text_user_wrote: "%{value} Ä‘Ã£ viáº¿t:"
+  text_enumeration_destroy_question: "%{count} Ä‘á»‘i tÆ°á»£ng Ä‘Æ°á»£c gÃ¡n giÃ¡ trá»‹ nÃ y."
+  text_enumeration_category_reassign_to: 'GÃ¡n láº¡i giÃ¡ trá»‹ nÃ y:'
+  text_email_delivery_not_configured: "Cáº¥u hÃ¬nh gá»­i Email chÆ°a Ä‘Æ°á»£c Ä‘áº·t, vÃ  chá»©c nÄƒng thÃ´ng bÃ¡o bá»‹ loáº¡i bá».\nCáº¥u hÃ¬nh mÃ¡y chá»§ SMTP cá»§a báº¡n á»Ÿ file config/configuration.yml vÃ  khá»Ÿi Ä‘á»™ng láº¡i Ä‘á»ƒ kÃ­ch hoáº¡t chÃºng."
+
+  default_role_manager: 'Äiá»u hÃ nh '
+  default_role_developer: 'PhÃ¡t triá»ƒn '
+  default_role_reporter: BÃ¡o cÃ¡o
+  default_tracker_bug: Lá»—i
+  default_tracker_feature: TÃ­nh nÄƒng
+  default_tracker_support: Há»— trá»£
+  default_issue_status_new: Má»›i
+  default_issue_status_in_progress: Äang tiáº¿n hÃ nh
+  default_issue_status_resolved: ÄÃ£ Ä‘Æ°á»£c giáº£i quyáº¿t
+  default_issue_status_feedback: Pháº£n há»“i
+  default_issue_status_closed: ÄÃ£ Ä‘Ã³ng
+  default_issue_status_rejected: Tá»« chá»‘i
+  default_doc_category_user: TÃ i liá»‡u ngÆ°á»i dÃ¹ng
+  default_doc_category_tech: TÃ i liá»‡u ká»¹ thuáº­t
+  default_priority_low: Tháº¥p
+  default_priority_normal: BÃ¬nh thÆ°á»ng
+  default_priority_high: Cao
+  default_priority_urgent: Kháº©n cáº¥p
+  default_priority_immediate: Trung bÃ¬nh
+  default_activity_design: Thiáº¿t káº¿
+  default_activity_development: PhÃ¡t triá»ƒn
+
+  enumeration_issue_priorities: Má»©c Ä‘á»™ Æ°u tiÃªn váº¥n Ä‘á»
+  enumeration_doc_categories: Danh má»¥c tÃ i liá»‡u
+  enumeration_activities: Hoáº¡t Ä‘á»™ng
+
+  setting_plain_text_mail: Mail dáº¡ng text Ä‘Æ¡n giáº£n (khÃ´ng dÃ¹ng HTML)
+  setting_gravatar_enabled: DÃ¹ng biá»ƒu tÆ°á»£ng Gravatar
+  permission_edit_project: Chá»‰nh dá»± Ã¡n
+  permission_select_project_modules: Chá»n Module
+  permission_manage_members: Quáº£n lÃ½ thÃ nh viÃªn
+  permission_manage_versions: Quáº£n lÃ½ phiÃªn báº£n
+  permission_manage_categories: Quáº£n lÃ½ chá»§ Ä‘á»
+  permission_add_issues: ThÃªm váº¥n Ä‘á»
+  permission_edit_issues: Sá»­a váº¥n Ä‘á»
+  permission_manage_issue_relations: Quáº£n lÃ½ quan há»‡ váº¥n Ä‘á»
+  permission_add_issue_notes: ThÃªm chÃº thÃ­ch
+  permission_edit_issue_notes: Sá»­a chÃº thÃ­ch
+  permission_edit_own_issue_notes: Sá»­a chÃº thÃ­ch cÃ¡ nhÃ¢n
+  permission_move_issues: Chuyá»ƒn váº¥n Ä‘á»
+  permission_delete_issues: XÃ³a váº¥n Ä‘á»
+  permission_manage_public_queries: Quáº£n lÃ½ truy váº¥n cÃ´ng cá»™ng
+  permission_save_queries: LÆ°u truy váº¥n
+  permission_view_gantt: Xem biá»ƒu Ä‘á»“ sá»± kiá»‡n
+  permission_view_calendar: Xem lá»‹ch
+  permission_view_issue_watchers: Xem nhá»¯ng ngÆ°á»i theo dÃµi
+  permission_add_issue_watchers: ThÃªm ngÆ°á»i theo dÃµi
+  permission_log_time: LÆ°u thá»i gian Ä‘Ã£ qua
+  permission_view_time_entries: Xem thá»i gian Ä‘Ã£ qua
+  permission_edit_time_entries: Xem nháº­t kÃ½ thá»i gian
+  permission_edit_own_time_entries: Sá»­a thá»i gian Ä‘Ã£ lÆ°u
+  permission_manage_news: Quáº£n lÃ½ tin má»›i
+  permission_comment_news: ChÃº thÃ­ch vÃ o tin má»›i
+  permission_view_documents: Xem tÃ i liá»‡u
+  permission_manage_files: Quáº£n lÃ½ táº­p tin
+  permission_view_files: Xem táº­p tin
+  permission_manage_wiki: Quáº£n lÃ½ wiki
+  permission_rename_wiki_pages: Äá»•i tÃªn trang wiki
+  permission_delete_wiki_pages: XÃ³a trang wiki
+  permission_view_wiki_pages: Xem wiki
+  permission_view_wiki_edits: Xem lÆ°á»£c sá»­ trang wiki
+  permission_edit_wiki_pages: Sá»­a trang wiki
+  permission_delete_wiki_pages_attachments: XÃ³a tá»‡p Ä‘Ã­nh kÃ¨m
+  permission_protect_wiki_pages: Báº£o vá»‡ trang wiki
+  permission_manage_repository: Quáº£n lÃ½ kho lÆ°u trá»¯
+  permission_browse_repository: Duyá»‡t kho lÆ°u trá»¯
+  permission_view_changesets: Xem cÃ¡c thay Ä‘á»•i
+  permission_commit_access: Truy cáº­p commit
+  permission_manage_boards: Quáº£n lÃ½ diá»…n Ä‘Ã n
+  permission_view_messages: Xem bÃ i viáº¿t
+  permission_add_messages: Gá»­i bÃ i viáº¿t
+  permission_edit_messages: Sá»­a bÃ i viáº¿t
+  permission_edit_own_messages: Sá»­a bÃ i viáº¿t cÃ¡ nhÃ¢n
+  permission_delete_messages: XÃ³a bÃ i viáº¿t
+  permission_delete_own_messages: XÃ³a bÃ i viáº¿t cÃ¡ nhÃ¢n
+  label_example: VÃ­ dá»¥
+  text_repository_usernames_mapping: "Lá»±a chá»n hoáº·c cáº­p nháº­t Ã¡nh xáº¡ ngÆ°á»i dÃ¹ng há»‡ thá»‘ng vá»›i ngÆ°á»i dÃ¹ng trong kho lÆ°u trá»¯.\nKhi ngÆ°á»i dÃ¹ng trÃ¹ng há»£p vá» tÃªn vÃ  email sáº½ Ä‘Æ°á»£c tá»± Ä‘á»™ng Ã¡nh xáº¡."
+  permission_delete_own_messages: XÃ³a thÃ´ng Ä‘iá»‡p
+  label_user_activity: "%{value} hoáº¡t Ä‘á»™ng"
+  label_updated_time_by: "Cáº­p nháº­t bá»Ÿi %{author} cÃ¡ch Ä‘Ã¢y %{age}"
+  text_diff_truncated: '... Thay Ä‘á»•i nÃ y Ä‘Ã£ Ä‘Æ°á»£c cáº¯t bá»›t do nÃ³ vÆ°á»£t qua giá»›i háº¡n kÃ­ch thÆ°á»›c cÃ³ thá»ƒ hiá»ƒn thá»‹.'
+  setting_diff_max_lines_displayed: Sá»‘ dÃ²ng thay Ä‘á»•i tá»‘i Ä‘a Ä‘Æ°á»£c hiá»ƒn thá»‹
+  text_plugin_assets_writable: Cho phÃ©p ghi thÆ° má»¥c Plugin
+  warning_attachments_not_saved: "%{count} file khÃ´ng Ä‘Æ°á»£c lÆ°u."
+  button_create_and_continue: Táº¡o vÃ  tiáº¿p tá»¥c
+  text_custom_field_possible_values_info: 'Má»™t dÃ²ng cho má»—i giÃ¡ trá»‹'
+  label_display: Hiá»ƒn thá»‹
+  field_editable: CÃ³ thá»ƒ sá»­a Ä‘Æ°á»£c
+  setting_repository_log_display_limit: Sá»‘ lÆ°á»£ng tá»‘i Ä‘a cÃ¡c báº£n Ä‘iá»u chá»‰nh hiá»ƒn thá»‹ trong file log
+  setting_file_max_size_displayed: KÃ­ch thÆ°á»›c tá»‘i Ä‘a cá»§a tá»‡p tin vÄƒn báº£n
+  field_watcher: NgÆ°á»i quan sÃ¡t
+  setting_openid: Cho phÃ©p Ä‘Äƒng nháº­p vÃ  Ä‘Äƒng kÃ½ dÃ¹ng OpenID
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: hoáº·c Ä‘Äƒng nháº­p vá»›i OpenID
+  field_content: Ná»™i dung
+  label_descending: Giáº£m dáº§n
+  label_sort: Sáº¯p xáº¿p
+  label_ascending: TÄƒng dáº§n
+  label_date_from_to: "Tá»« %{start} tá»›i %{end}"
+  label_greater_or_equal: ">="
+  label_less_or_equal: "<="
+  text_wiki_page_destroy_question: "Trang nÃ y cÃ³ %{descendants} trang con vÃ  trang chÃ¡u. Báº¡n muá»‘n lÃ m gÃ¬ tiáº¿p?"
+  text_wiki_page_reassign_children: GÃ¡n láº¡i trang con vÃ o trang máº¹ nÃ y
+  text_wiki_page_nullify_children: Giá»¯ trang con nhÆ° trang gá»‘c
+  text_wiki_page_destroy_children: XÃ³a trang con vÃ  táº¥t cáº£ trang con chÃ¡u cá»§a nÃ³
+  setting_password_min_length: Chiá»u dÃ i tá»‘i thiá»ƒu cá»§a máº­t kháº©u
+  field_group_by: NhÃ³m káº¿t quáº£ bá»Ÿi
+  mail_subject_wiki_content_updated: "%{id} trang wiki Ä‘Ã£ Ä‘Æ°á»£c cáº­p nháº­t"
+  label_wiki_content_added: ÄÃ£ thÃªm trang Wiki
+  mail_subject_wiki_content_added: "%{id} trang wiki Ä‘Ã£ Ä‘Æ°á»£c thÃªm vÃ o"
+  mail_body_wiki_content_added: "CÃ³ %{id} trang wiki Ä‘Ã£ Ä‘Æ°á»£c thÃªm vÃ o bá»Ÿi %{author}."
+  label_wiki_content_updated: Trang Wiki Ä‘Ã£ Ä‘Æ°á»£c cáº­p nháº­t
+  mail_body_wiki_content_updated: "CÃ³ %{id} trang wiki Ä‘Ã£ Ä‘Æ°á»£c cáº­p nháº­t bá»Ÿi %{author}."
+  permission_add_project: Táº¡o dá»± Ã¡n
+  setting_new_project_user_role_id: Quyá»n Ä‘Æ°á»£c gÃ¡n cho ngÆ°á»i dÃ¹ng khÃ´ng pháº£i quáº£n trá»‹ viÃªn khi táº¡o dá»± Ã¡n má»›i
+  label_view_all_revisions: Xem táº¥t cáº£ báº£n Ä‘iá»u chá»‰nh
+  label_tag: Tháº»
+  label_branch: NhÃ¡nh
+  error_no_tracker_in_project: KhÃ´ng cÃ³ ai theo dÃµi dá»± Ã¡n nÃ y. HÃ£y kiá»ƒm tra láº¡i pháº§n thiáº¿t láº­p cho dá»± Ã¡n.
+  error_no_default_issue_status: KhÃ´ng cÃ³ váº¥n Ä‘á» máº·c Ä‘á»‹nh Ä‘Æ°á»£c Ä‘á»‹nh nghÄ©a. Vui lÃ²ng kiá»ƒm tra cáº¥u hÃ¬nh cá»§a báº¡n (VÃ o "Quáº£n trá»‹ -> Tráº¡ng thÃ¡i váº¥n Ä‘á»").
+  text_journal_changed: "%{label} thay Ä‘á»•i tá»« %{old} tá»›i %{new}"
+  text_journal_set_to: "%{label} gÃ¡n cho %{value}"
+  text_journal_deleted: "%{label} xÃ³a (%{old})"
+  label_group_plural: CÃ¡c nhÃ³m
+  label_group: NhÃ³m
+  label_group_new: ThÃªm nhÃ³m
+  label_time_entry_plural: Thá»i gian Ä‘Ã£ sá»­ dá»¥ng
+  text_journal_added: "%{label} %{value} Ä‘Æ°á»£c thÃªm"
+  field_active: TÃ­ch cá»±c
+  enumeration_system_activity: Hoáº¡t Ä‘á»™ng há»‡ thá»‘ng
+  permission_delete_issue_watchers: XÃ³a ngÆ°á»i quan sÃ¡t
+  version_status_closed: Ä‘Ã³ng
+  version_status_locked: khÃ³a
+  version_status_open: má»Ÿ
+  error_can_not_reopen_issue_on_closed_version: Má»™t váº¥n Ä‘á» Ä‘Æ°á»£c gÃ¡n cho phiÃªn báº£n Ä‘Ã£ Ä‘Ã³ng khÃ´ng thá»ƒ má»Ÿ láº¡i Ä‘Æ°á»£c
+  label_user_anonymous: áº¨n danh
+  button_move_and_follow: Di chuyá»ƒn vÃ  theo
+  setting_default_projects_modules: CÃ¡c Module Ä‘Æ°á»£c kÃ­ch hoáº¡t máº·c Ä‘á»‹nh cho dá»± Ã¡n má»›i
+  setting_gravatar_default: áº¢nh Gravatar máº·c Ä‘á»‹nh
+  field_sharing: Chia sáº»
+  label_version_sharing_hierarchy: Vá»›i thá»© báº­c dá»± Ã¡n
+  label_version_sharing_system: Vá»›i táº¥t cáº£ dá»± Ã¡n
+  label_version_sharing_descendants: Vá»›i dá»± Ã¡n con
+  label_version_sharing_tree: Vá»›i cÃ¢y dá»± Ã¡n
+  label_version_sharing_none: KhÃ´ng chia sáº»
+  error_can_not_archive_project: Dá»±a Ã¡n nÃ y khÃ´ng thá»ƒ lÆ°u trá»¯ Ä‘Æ°á»£c
+  button_duplicate: NhÃ¢n Ä‘Ã´i
+  button_copy_and_follow: Sao chÃ©p vÃ  theo
+  label_copy_source: Nguá»“n
+  setting_issue_done_ratio: TÃ­nh toÃ¡n tá»· lá»‡ hoÃ n thÃ nh váº¥n Ä‘á» vá»›i
+  setting_issue_done_ratio_issue_status: Sá»­ dá»¥ng tráº¡ng thÃ¡i cá»§a váº¥n Ä‘á»
+  error_issue_done_ratios_not_updated: Tá»· lá»‡ hoÃ n thÃ nh váº¥n Ä‘á» khÃ´ng Ä‘Æ°á»£c cáº­p nháº­t.
+  error_workflow_copy_target: Vui lÃ²ng lá»±a chá»n Ä‘Ã­ch cá»§a theo dáº¥u vÃ  quyá»n
+  setting_issue_done_ratio_issue_field: DÃ¹ng trÆ°á»ng váº¥n Ä‘á»
+  label_copy_same_as_target: TÆ°Æ¡ng tá»± nhÆ° Ä‘Ã­ch
+  label_copy_target: ÄÃ­ch
+  notice_issue_done_ratios_updated: Tá»· lá»‡ hoÃ n thÃ nh váº¥n Ä‘á» Ä‘Æ°á»£c cáº­p nháº­t.
+  error_workflow_copy_source: Vui lÃ²ng lá»±a chá»n nguá»“n cá»§a theo dáº¥u hoáº·c quyá»n
+  label_update_issue_done_ratios: Cáº­p nháº­t tá»· lá»‡ hoÃ n thÃ nh váº¥n Ä‘á»
+  setting_start_of_week: Äá»‹nh dáº¡ng lá»‹ch
+  permission_view_issues: Xem Váº¥n Ä‘á»
+  label_display_used_statuses_only: Chá»‰ hiá»ƒn thá»‹ tráº¡ng thÃ¡i Ä‘Ã£ Ä‘Æ°á»£c dÃ¹ng bá»Ÿi theo dÃµi nÃ y
+  label_revision_id: "Báº£n Ä‘iá»u chá»‰nh %{value}"
+  label_api_access_key: KhoÃ¡ truy cáº­p API
+  label_api_access_key_created_on: "KhoÃ¡ truy cáº­p API Ä‘á»±Æ¡c táº¡o cÃ¡ch Ä‘Ã¢y %{value}. KhÃ³a nÃ y Ä‘Æ°á»£c dÃ¹ng cho eDesignLab Client."
+  label_feeds_access_key: KhoÃ¡ truy cáº­p RSS
+  notice_api_access_key_reseted: KhoÃ¡ truy cáº­p API cá»§a báº¡n Ä‘Ã£ Ä‘Æ°á»£c Ä‘áº·t láº¡i.
+  setting_rest_api_enabled: Cho phÃ©p dá»‹ch vá»¥ web REST
+  label_missing_api_access_key: Máº¥t KhoÃ¡ truy cáº­p API
+  label_missing_feeds_access_key: Máº¥t KhoÃ¡ truy cáº­p RSS
+  button_show: Hiá»‡n
+  text_line_separated: Nhiá»u giÃ¡ trá»‹ Ä‘Æ°á»£c phÃ©p(má»—i dÃ²ng má»™t giÃ¡ trá»‹).
+  setting_mail_handler_body_delimiters: "Cáº¯t bá»›t email sau nhá»¯ng dÃ²ng :"
+  permission_add_subprojects: Táº¡o Dá»± Ã¡n con
+  label_subproject_new: ThÃªm dá»± Ã¡n con
+  text_own_membership_delete_confirmation: |-
+    Báº¡n Ä‘ang cá»‘ gá»¡ bá» má»™t sá»‘ hoáº·c táº¥t cáº£ quyá»n cá»§a báº¡n vá»›i dá»± Ã¡n nÃ y vÃ  cÃ³ thá»ƒ sáº½ máº¥t quyá»n thay Ä‘á»•i nÃ³ sau Ä‘Ã³.
+    Báº¡n cÃ³ muá»‘n tiáº¿p tá»¥c?
+  label_close_versions: ÄÃ³ng phiÃªn báº£n Ä‘Ã£ hoÃ n thÃ nh
+  label_board_sticky: ChÃº Ã½
+  label_board_locked: ÄÃ£ khÃ³a
+  permission_export_wiki_pages: Xuáº¥t trang wiki
+  setting_cache_formatted_text: Cache Ä‘á»‹nh dáº¡ng cÃ¡c kÃ½ tá»±
+  permission_manage_project_activities: Quáº£n lÃ½ hoáº¡t Ä‘á»™ng cá»§a dá»± Ã¡n
+  error_unable_delete_issue_status: KhÃ´ng thá»ƒ xÃ³a tráº¡ng thÃ¡i váº¥n Ä‘á»
+  label_profile: Há»“ sÆ¡
+  permission_manage_subtasks: Quáº£n lÃ½ tÃ¡c vá»¥ con
+  field_parent_issue: TÃ¡c vá»¥ cha
+  label_subtask_plural: TÃ¡c vá»¥ con
+  label_project_copy_notifications: Gá»­i email thÃ´ng bÃ¡o trong khi dá»± Ã¡n Ä‘Æ°á»£c sao chÃ©p
+  error_can_not_delete_custom_field: KhÃ´ng thá»ƒ xÃ³a trÆ°á»ng tÃ¹y biáº¿n
+  error_unable_to_connect: "KhÃ´ng thá»ƒ káº¿t ná»‘i (%{value})"
+  error_can_not_remove_role: Quyá»n nÃ y Ä‘ang Ä‘Æ°á»£c dÃ¹ng vÃ  khÃ´ng thá»ƒ xÃ³a Ä‘Æ°á»£c.
+  error_can_not_delete_tracker: Theo dÃµi nÃ y chá»©a váº¥n Ä‘á» vÃ  khÃ´ng thá»ƒ xÃ³a Ä‘Æ°á»£c.
+  field_principal: Chá»§ yáº¿u
+  label_my_page_block: Block trang cá»§a tÃ´i
+  notice_failed_to_save_members: "Tháº¥t báº¡i khi lÆ°u thÃ nh viÃªn : %{errors}."
+  text_zoom_out: Thu nhá»
+  text_zoom_in: PhÃ³ng to
+  notice_unable_delete_time_entry: KhÃ´ng thá»ƒ xÃ³a má»¥c time log.
+  label_overall_spent_time: Tá»•ng thá»i gian sá»­ dá»¥ng
+  field_time_entries: Log time
+  project_module_gantt: Biá»ƒu Ä‘á»“ Gantt
+  project_module_calendar: Lá»‹ch
+  button_edit_associated_wikipage: "Chá»‰nh sá»­a trang Wiki liÃªn quan: %{page_title}"
+  text_are_you_sure_with_children: XÃ³a váº¥n Ä‘á» vÃ  táº¥t cáº£ váº¥n Ä‘á» con?  
+  field_text: TrÆ°á»ng vÄƒn báº£n
+  label_user_mail_option_only_owner: Chá»‰ nhá»¯ng thá»© tÃ´i sá»Ÿ há»¯u
+  setting_default_notification_option: Tuá»³ chá»n thÃ´ng bÃ¡o máº·c Ä‘á»‹nh
+  label_user_mail_option_only_my_events: Chá»‰ nhá»¯ng thá»© tÃ´i theo dÃµi hoáº·c liÃªn quan
+  label_user_mail_option_only_assigned: Chá»‰ nhá»¯ng thá»© tÃ´i Ä‘Æ°á»£c phÃ¢n cÃ´ng
+  label_user_mail_option_none: KhÃ´ng cÃ³ sá»± kiá»‡n
+  field_member_of_group: NhÃ³m thá»¥ hÆ°á»Ÿng
+  field_assigned_to_role: Quyá»n thá»¥ hÆ°á»Ÿng
+  notice_not_authorized_archived_project: Dá»± Ã¡n báº¡n Ä‘ang cÃ³ truy cáº­p Ä‘Ã£ Ä‘Æ°á»£c lÆ°u trá»¯.
+  label_principal_search: "TÃ¬m kiáº¿m ngÆ°á»i dÃ¹ng hoáº·c nhÃ³m:"
+  label_user_search: "TÃ¬m kiáº¿m ngÆ°á»i dÃ¹ng:"
+  field_visible: NhÃ¬n tháº¥y
+  setting_emails_header: TiÃªu Ä‘á» Email
+  setting_commit_logtime_activity_id: Cho phÃ©p ghi láº¡i thá»i gian
+  text_time_logged_by_changeset: "Ãp dá»¥ng trong changeset : %{value}."
+  setting_commit_logtime_enabled: Cho phÃ©p time logging
+  notice_gantt_chart_truncated: "Äá»“ thá»‹ Ä‘Ã£ Ä‘Æ°á»£c cáº¯t bá»›t bá»Ÿi vÃ¬ nÃ³ Ä‘Ã£ vÆ°á»£t qua lÆ°á»£ng thÃ´ng tin tá»‘i Ä‘a cÃ³ thá»ƒ hiá»ƒn thá»‹ :(%{max})"
+  setting_gantt_items_limit: LÆ°á»£ng thÃ´ng tin tá»‘i Ä‘a trÃªn Ä‘á»“ thá»‹ gantt
+  description_selected_columns: CÃ¡c cá»™t Ä‘Æ°á»£c lá»±a chá»n
+  field_warn_on_leaving_unsaved: Cáº£nh bÃ¡o tÃ´i khi rá»i má»™t trang cÃ³ cÃ¡c ná»™i dung chÆ°a lÆ°u
+  text_warn_on_leaving_unsaved: Trang hiá»‡n táº¡i chá»©a ná»™i dung chÆ°a lÆ°u vÃ  sáº½ bá»‹ máº¥t náº¿u báº¡n rá»i trang nÃ y.
+  label_my_queries: CÃ¡c truy váº¥n tÃ¹y biáº¿n
+  text_journal_changed_no_detail: "%{label} cáº­p nháº­t"
+  label_news_comment_added: BÃ¬nh luáº­n Ä‘Ã£ Ä‘Æ°á»£c thÃªm cho má»™t tin tá»©c
+  button_expand_all: Má»Ÿ rá»™ng táº¥t cáº£
+  button_collapse_all: Thu gá»n táº¥t cáº£
+  label_additional_workflow_transitions_for_assignee: Chuyá»ƒn Ä‘á»•i bá»• sung cho phÃ©p khi ngÆ°á»i sá»­ dá»¥ng lÃ  ngÆ°á»i nháº­n chuyá»ƒn nhÆ°á»£ng
+  label_additional_workflow_transitions_for_author: CÃ¡c chuyá»ƒn Ä‘á»•i bá»• xung Ä‘Æ°á»£c phÃ©p khi ngÆ°á»i dÃ¹ng lÃ  tÃ¡c giáº£
+  label_bulk_edit_selected_time_entries: Sá»­a nhiá»u má»¥c Ä‘Ã£ chá»n
+  text_time_entries_destroy_confirmation: Báº¡n cÃ³ cháº¯c cháº¯n muá»‘n xÃ³a bá» cÃ¡c má»¥c Ä‘Ã£ chá»n?
+  label_role_anonymous: áº¨n danh
+  label_role_non_member: KhÃ´ng lÃ  thÃ nh viÃªn
+  label_issue_note_added: Ghi chÃº Ä‘Æ°á»£c thÃªm
+  label_issue_status_updated: Tráº¡ng thÃ¡i cáº­p nháº­t
+  label_issue_priority_updated: Cáº­p nháº­t Æ°u tiÃªn
+  label_issues_visibility_own: Váº¥n Ä‘á» táº¡o bá»Ÿi hoáº·c gÃ¡n cho ngÆ°á»i dÃ¹ng
+  field_issues_visibility: Váº¥n Ä‘á» Ä‘Æ°á»£c nhÃ¬n tháº¥y
+  label_issues_visibility_all: Táº¥t cáº£ váº¥n Ä‘á»
+  permission_set_own_issues_private: Äáº·t váº¥n Ä‘á» sá»Ÿ há»¯u lÃ  riÃªng tÆ° hoáº·c cÃ´ng cá»™ng
+  field_is_private: RiÃªng tÆ°
+  permission_set_issues_private: GÃ¡n váº¥n Ä‘á» lÃ  riÃªng tÆ° hoáº·c cÃ´ng cá»™ng
+  label_issues_visibility_public: Táº¥t cáº£ váº¥n Ä‘á» khÃ´ng riÃªng tÆ°
+  text_issues_destroy_descendants_confirmation: "HÃ nh Ä‘á»™ng nÃ y sáº½ xÃ³a %{count} tÃ¡c vá»¥ con."
+  field_commit_logs_encoding: MÃ£ hÃ³a ghi chÃº Commit
+  field_scm_path_encoding: MÃ£ hÃ³a Ä‘Æ°á»ng dáº«n
+  text_scm_path_encoding_note: "Máº·c Ä‘á»‹nh: UTF-8"
+  field_path_to_repository: ÄÆ°á»ng dáº«n tá»›i kho chá»©a
+  field_root_directory: ThÆ° má»¥c gá»‘c
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Kho chá»©a cá»¥c bá»™ (vd. /hgrepo, c:\hgrepo)
+  text_scm_command: Lá»‡nh
+  text_scm_command_version: PhiÃªn báº£n  
+  label_git_report_last_commit: BÃ¡o cÃ¡o láº§n Commit cuá»‘i cÃ¹ng cho file vÃ  thÆ° má»¥c  
+  text_scm_config: Báº¡n cÃ³ thá»ƒ cáº¥u hÃ¬nh lá»‡nh Scm trong file config/configuration.yml. Vui lÃ²ng khá»Ÿi Ä‘á»™ng láº¡i á»©ng dá»¥ng sau khi chá»‰nh sá»­a nÃ³.
+  text_scm_command_not_available: Lá»‡nh Scm khÃ´ng cÃ³ sáºµn. Vui lÃ²ng kiá»ƒm tra láº¡i thiáº¿t Ä‘áº·t trong pháº§n Quáº£n trá»‹.  
+  notice_issue_successful_create: "Váº¥n Ä‘á» %{id} Ä‘Ã£ Ä‘Æ°á»£c táº¡o."  
+  label_between: á»ž giá»¯a
+  setting_issue_group_assignment: Cho phÃ©p gÃ¡n váº¥n Ä‘á» Ä‘áº¿n cÃ¡c nhÃ³m
+  label_diff: Sá»± khÃ¡c nhau
+  text_git_repository_note: Kho chá»©a cá»¥c bá»™ vÃ  cÃ´ng cá»™ng (vd. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Chiá»u sáº¯p xáº¿p
+  description_project_scope: Pháº¡m vi tÃ¬m kiáº¿m
+  description_filter: Lá»c
+  description_user_mail_notification: Thiáº¿t láº­p email thÃ´ng bÃ¡o
+  description_date_from: Nháº­p ngÃ y báº¯t Ä‘áº§u
+  description_message_content: Ná»™i dung thÃ´ng Ä‘iá»‡p
+  description_available_columns: CÃ¡c cá»™t cÃ³ sáºµn
+  description_date_range_interval: Chá»n khoáº£ng thá»i gian giá»¯a ngÃ y báº¯t Ä‘áº§u vÃ  káº¿t thÃºc
+  description_issue_category_reassign: Chá»n danh má»¥c váº¥n Ä‘á»
+  description_search: TrÆ°á»ng tÃ¬m kiáº¿m
+  description_notes: CÃ¡c chÃº Ã½
+  description_date_range_list: Chá»n khoáº£ng tá»« danh sÃ¡ch
+  description_choose_project: CÃ¡c dá»± Ã¡n
+  description_date_to: Nháº­p ngÃ y káº¿t thÃºc
+  description_query_sort_criteria_attribute: Sáº¯p xáº¿p thuá»™c tÃ­nh
+  description_wiki_subpages_reassign: Chá»n má»™t trang cáº¥p trÃªn
+  label_parent_revision: Cha
+  label_child_revision: Con
+  error_scm_annotate_big_text_file: CÃ¡c má»¥c khÃ´ng Ä‘Æ°á»£c chÃº thÃ­ch, vÃ¬ nÃ³ vÆ°á»£t quÃ¡ kÃ­ch thÆ°á»›c táº­p tin vÄƒn báº£n tá»‘i Ä‘a.
+  setting_default_issue_start_date_to_creation_date: Sá»­ dá»¥ng thá»i gian hiá»‡n táº¡i khi táº¡o váº¥n Ä‘á» má»›i
+  button_edit_section: Soáº¡n tháº£o sá»± lá»±a chá»n nÃ y
+  setting_repositories_encodings: MÃ£ hÃ³a kho chá»©a
+  description_all_columns: CÃ¡c cá»™t
+  button_export: Export
+  label_export_options: "%{export_format} tÃ¹y chá»n Export"
+  error_attachment_too_big: "File nÃ y khÃ´ng thá»ƒ táº£i lÃªn vÃ¬ nÃ³ vÆ°á»£t quÃ¡ kÃ­ch thÆ°á»›c cho phÃ©p : (%{max_size})"
+  notice_failed_to_save_time_entries: "Lá»—i khi lÆ°u %{count} láº§n trÃªn %{total} sá»± lá»±a chá»n : %{ids}."
+  label_x_issues:
+    zero:  0 váº¥n Ä‘á»
+    one:   1 váº¥n Ä‘á»
+    other: "%{count} váº¥n Ä‘á»"
+  label_repository_new: Kho lÆ°u trá»¯ má»›i
+  field_repository_is_default: Kho lÆ°u trá»¯ chÃ­nh
+  label_copy_attachments: Copy cÃ¡c file Ä‘Ã­nh kÃ¨m
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: CÃ¡c phiÃªn báº£n hoÃ n thÃ nh
+  text_project_identifier_info: Chá»‰ cho phÃ©p chá»¯ cÃ¡i thÆ°á»ng (a-z), con sá»‘ vÃ  dáº¥u gáº¡ch ngang.<br />Sau khi lÆ°u, chá»‰ sá»‘ ID khÃ´ng thá»ƒ thay Ä‘á»•i.
+  field_multiple: Nhiá»u giÃ¡ trá»‹
+  setting_commit_cross_project_ref: Sá»­ dá»¥ng thá»i gian hiá»‡n táº¡i khi táº¡o váº¥n Ä‘á» má»›i
+  text_issue_conflict_resolution_add_notes: ThÃªm ghi chÃº cá»§a tÃ´i vÃ  loáº¡i bá» cÃ¡c thay Ä‘á»•i khÃ¡c 
+  text_issue_conflict_resolution_overwrite: Ãp dá»¥ng thay Ä‘á»•i báº±ng báº¥t cá»© giÃ¡ nÃ o, ghi chÃº trÆ°á»›c Ä‘Ã³ cÃ³ thá»ƒ bá»‹ ghi Ä‘Ã¨
+  notice_issue_update_conflict: Váº¥n Ä‘á» nÃ y Ä‘Ã£ Ä‘Æ°á»£c cáº­p nháº­t bá»Ÿi má»™t ngÆ°á»i dÃ¹ng khÃ¡c trong khi báº¡n Ä‘ang chá»‰nh sá»­a nÃ³.
+  text_issue_conflict_resolution_cancel: "Loáº¡i bá» táº¥t cáº£ cÃ¡c thay Ä‘á»•i vÃ  hiá»ƒn thá»‹ láº¡i %{link}"
+  permission_manage_related_issues: Quáº£n lÃ½ cÃ¡c váº¥n Ä‘á» liÃªn quan
+  field_auth_source_ldap_filter: Bá»™ lá»c LDAP
+  label_search_for_watchers: TÃ¬m kiáº¿m ngÆ°á»i theo dÃµi Ä‘á»ƒ thÃªm
+  notice_account_deleted: TÃ i khoáº£n cá»§a báº¡n Ä‘Ã£ Ä‘Æ°á»£c xÃ³a vÄ©nh viá»…n.
+  button_delete_my_account: XÃ³a tÃ i khoáº£n cá»§a tÃ´i
+  setting_unsubscribe: Cho phÃ©p ngÆ°á»i dÃ¹ng xÃ³a Account
+  text_account_destroy_confirmation: |-
+    Báº¡n Ä‘á»“ng Ã½ khÃ´ng ?
+    TÃ i khoáº£n cá»§a báº¡n sáº½ bá»‹ xÃ³a vÄ©nh viá»…n, khÃ´ng thá»ƒ khÃ´i phá»¥c láº¡i!
+  error_session_expired: PhiÃªn lÃ m viá»‡c cá»§a báº¡n bá»‹ quÃ¡ háº¡n, hÃ£y Ä‘Äƒng nháº­p láº¡i 
+  text_session_expiration_settings: "ChÃº Ã½ : Thay Ä‘á»•i cÃ¡c thiáº¿t láº­p nÃ y cÃ³ thá»ƒ gÃ¢y vÃ´ hiá»‡u hÃ³a Session hiá»‡n táº¡i"
+  setting_session_lifetime: Thá»i gian tá»“n táº¡i lá»›n nháº¥t cá»§a Session
+  setting_session_timeout: Thá»i gian vÃ´ hiá»‡u hÃ³a Session
+  label_session_expiration: PhiÃªn lÃ m viá»‡c bá»‹ quÃ¡ háº¡n
+  permission_close_project: ÄÃ³ng / Má»Ÿ láº¡i dá»± Ã¡n
+  label_show_closed_projects: Xem cÃ¡c dá»± Ã¡n Ä‘Ã£ Ä‘Ã³ng
+  button_close: ÄÃ³ng
+  button_reopen: Má»Ÿ láº¡i
+  project_status_active: KÃ­ch hoáº¡t
+  project_status_closed: ÄÃ£ Ä‘Ã³ng
+  project_status_archived: LÆ°u trá»¯
+  text_project_closed: Dá»± Ã¡n nÃ y Ä‘Ã£ Ä‘Ã³ng vÃ  chá»‰ Ä‘á»c
+  notice_user_successful_create: "NgÆ°á»i dÃ¹ng %{id} Ä‘Ã£ Ä‘Æ°á»£c táº¡o."
+  field_core_fields: CÃ¡c trÆ°á»ng tiÃªu chuáº©n
+  field_timeout: QuÃ¡ háº¡n
+  setting_thumbnails_enabled: Hiá»ƒn thá»‹ cÃ¡c thumbnail Ä‘Ã­nh kÃ¨m
+  setting_thumbnails_size: KÃ­ch thÆ°á»›c Thumbnails(pixel)
+  setting_session_lifetime: Thá»i gian tá»“n táº¡i lá»›n nháº¥t cá»§a Session
+  setting_session_timeout: Thá»i gian vÃ´ hiá»‡u hÃ³a Session
+  label_status_transitions: Tráº¡ng thÃ¡i chuyá»ƒn tiáº¿p
+  label_fields_permissions: Cho phÃ©p cÃ¡c trÆ°á»ng
+  label_readonly: Chá»‰ Ä‘á»c
+  label_required: YÃªu cáº§u
+  text_repository_identifier_info: Chá»‰ cÃ³ cÃ¡c chá»¯ thÆ°á»ng (a-z), cÃ¡c sá»‘ (0-9), dáº¥u gáº¡ch ngang vÃ  gáº¡ch dÆ°á»›i lÃ  há»£p lá»‡.<br />Khi Ä‘Ã£ lÆ°u, tÃªn Ä‘á»‹nh danh sáº½ khÃ´ng thá»ƒ thay Ä‘á»•i.
+  field_board_parent: Diá»…n Ä‘Ã n cha
+  label_attribute_of_project: "Cá»§a dá»± Ã¡n : %{name}"
+  label_attribute_of_author: "Cá»§a tÃ¡c giáº£ : %{name}"
+  label_attribute_of_assigned_to: "ÄÆ°á»£c phÃ¢n cÃ´ng bá»Ÿi %{name}"
+  label_attribute_of_fixed_version: "PhiÃªn báº£n má»¥c tiÃªu cá»§a %{name}"
+  label_copy_subtasks: Sao chÃ©p cÃ¡c nhiá»‡m vá»¥ con
+  label_copied_to: Sao chÃ©p Ä‘áº¿n
+  label_copied_from: Sao chÃ©p tá»«
+  label_any_issues_in_project: Báº¥t ká»³ váº¥n Ä‘á» nÃ o trong dá»± Ã¡n
+  label_any_issues_not_in_project: Báº¥t ká»³ váº¥n Ä‘á» nÃ o khÃ´ng thuá»™c dá»± Ã¡n
+  field_private_notes: Ghi chÃº riÃªng tÆ°
+  permission_view_private_notes: Xem ghi chÃº riÃªng tÆ°
+  permission_set_notes_private: Äáº·t ghi chÃº thÃ nh riÃªng tÆ°
+  label_no_issues_in_project: KhÃ´ng cÃ³ váº¥n Ä‘á» nÃ o trong dá»± Ã¡n
+  label_any: táº¥t cáº£
+  label_last_n_weeks: "%{count} tuáº§n qua"
+  setting_cross_project_subtasks: Cho phÃ©p cÃ¡c nhiá»‡m vá»¥ con liÃªn dá»± Ã¡n
+  label_cross_project_descendants: Trong cÃ¡c dá»± Ã¡n con
+  label_cross_project_tree: Trong cÃ¹ng cÃ¢y dá»± Ã¡n
+  label_cross_project_hierarchy: Trong dá»± Ã¡n cÃ¹ng cáº¥p báº­c
+  label_cross_project_system: Trong táº¥t cáº£ cÃ¡c dá»± Ã¡n
+  button_hide: áº¨n
+  setting_non_working_week_days: CÃ¡c ngÃ y khÃ´ng lÃ m viá»‡c
+  label_in_the_next_days: Trong tÆ°Æ¡ng lai
+  label_in_the_past_days: Trong quÃ¡ khá»©
+  label_attribute_of_user: "Cá»§a ngÆ°á»i dÃ¹ng %{name}"
+  text_turning_multiple_off: Náº¿u báº¡n vÃ´ hiá»‡u hÃ³a nhiá»u giÃ¡ trá»‹, chÃºng sáº½ bá»‹ loáº¡i bá» Ä‘á»ƒ duy trÃ¬ chá»‰ cÃ³ má»™t giÃ¡ trá»‹ cho má»—i má»¥c.
+  label_attribute_of_issue: "Váº¥n Ä‘á» cá»§a %{name}"
+  permission_add_documents: ThÃªm tÃ i liá»‡u
+  permission_edit_documents: Soáº¡n tháº£o tÃ i liá»‡u
+  permission_delete_documents: XÃ³a tÃ i liá»‡u
+  label_gantt_progress_line: Tiáº¿n Ä‘á»™
+  setting_jsonp_enabled: Cho phÃ©p trá»£ giÃºp JSONP
+  field_inherit_members: CÃ¡c thÃ nh viÃªn káº¿ thá»«a
+  field_closed_on: ÄÃ£ Ä‘Ã³ng
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Tá»•ng cá»™ng
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cc/cca369f9be126f556b2935f2f589ff1e46939064.svn-base
--- /dev/null
+++ b/.svn/pristine/cc/cca369f9be126f556b2935f2f589ff1e46939064.svn-base
@@ -0,0 +1,3 @@
+<h3><%=l(:label_news_latest)%></h3>
+
+<%= render :partial => 'news/news', :collection => news_items %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cc/ccad1072a6b0c20c818238d015e69db735382ae9.svn-base
--- a/.svn/pristine/cc/ccad1072a6b0c20c818238d015e69db735382ae9.svn-base
+++ /dev/null
@@ -1,40 +0,0 @@
-module CollectiveIdea #:nodoc:
-  module Acts #:nodoc:
-    module NestedSet #:nodoc:
-      # This module provides some helpers for the model classes using acts_as_nested_set.
-      # It is included by default in all views.
-      #
-      module Helper
-        # Returns options for select.
-        # You can exclude some items from the tree.
-        # You can pass a block receiving an item and returning the string displayed in the select.
-        #
-        # == Params
-        #  * +class_or_item+ - Class name or top level times
-        #  * +mover+ - The item that is being move, used to exlude impossible moves
-        #  * +&block+ - a block that will be used to display: {Â |item| ... item.name }
-        #
-        # == Usage
-        #
-        #   <%= f.select :parent_id, nested_set_options(Category, @category) {|i|
-        #       "#{'â€“' * i.level} #{i.name}"
-        #     }) %>
-        #
-        def nested_set_options(class_or_item, mover = nil)
-          class_or_item = class_or_item.roots if class_or_item.is_a?(Class)
-          items = Array(class_or_item)
-          result = []
-          items.each do |root|
-            result += root.self_and_descendants.map do |i|
-              if mover.nil? || mover.new_record? || mover.move_possible?(i)
-                [yield(i), i.id]
-              end
-            end.compact
-          end
-          result
-        end  
-        
-      end
-    end  
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cc/ccce2abaec3cc91d9ea2ed85e7c358fb0d8c01ed.svn-base
--- /dev/null
+++ b/.svn/pristine/cc/ccce2abaec3cc91d9ea2ed85e7c358fb0d8c01ed.svn-base
@@ -0,0 +1,44 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::EnumerationsTest < Redmine::ApiTest::Base
+  fixtures :enumerations
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  context "/enumerations/issue_priorities" do
+    context "GET" do
+
+      should "return priorities" do
+        get '/enumerations/issue_priorities.xml'
+
+        assert_response :success
+        assert_equal 'application/xml', response.content_type
+        assert_select 'issue_priorities[type=array]' do
+          assert_select 'issue_priority' do
+            assert_select 'id', :text => '6'
+            assert_select 'name', :text => 'High'
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cd0cd3d509a8a2e2326a5695c336ef169a2d874f.svn-base
--- a/.svn/pristine/cd/cd0cd3d509a8a2e2326a5695c336ef169a2d874f.svn-base
+++ /dev/null
@@ -1,201 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # Scanner for output of the diff command.
-  # 
-  # Alias: +patch+
-  class Diff < Scanner
-    
-    register_for :diff
-    title 'diff output'
-    
-    DEFAULT_OPTIONS = {
-      :highlight_code => true,
-      :inline_diff    => true,
-    }
-    
-  protected
-    
-    require 'coderay/helpers/file_type'
-    
-    def scan_tokens encoder, options
-      
-      line_kind = nil
-      state = :initial
-      deleted_lines = 0
-      scanners = Hash.new do |h, lang|
-        h[lang] = Scanners[lang].new '', :keep_tokens => true, :keep_state => true
-      end
-      content_scanner = scanners[:plain]
-      content_scanner_entry_state = nil
-      
-      until eos?
-        
-        if match = scan(/\n/)
-          deleted_lines = 0 unless line_kind == :delete
-          if line_kind
-            encoder.end_line line_kind
-            line_kind = nil
-          end
-          encoder.text_token match, :space
-          next
-        end
-        
-        case state
-        
-        when :initial
-          if match = scan(/--- |\+\+\+ |=+|_+/)
-            encoder.begin_line line_kind = :head
-            encoder.text_token match, :head
-            if match = scan(/.*?(?=$|[\t\n\x00]|  \(revision)/)
-              encoder.text_token match, :filename
-              if options[:highlight_code]
-                file_type = FileType.fetch(match, :text)
-                file_type = :text if file_type == :diff
-                content_scanner = scanners[file_type]
-                content_scanner_entry_state = nil
-              end
-            end
-            next unless match = scan(/.+/)
-            encoder.text_token match, :plain
-          elsif match = scan(/Index: |Property changes on: /)
-            encoder.begin_line line_kind = :head
-            encoder.text_token match, :head
-            next unless match = scan(/.+/)
-            encoder.text_token match, :plain
-          elsif match = scan(/Added: /)
-            encoder.begin_line line_kind = :head
-            encoder.text_token match, :head
-            next unless match = scan(/.+/)
-            encoder.text_token match, :plain
-            state = :added
-          elsif match = scan(/\\ .*/)
-            encoder.text_token match, :comment
-          elsif match = scan(/@@(?>[^@\n]*)@@/)
-            content_scanner.state = :initial unless match?(/\n\+/)
-            content_scanner_entry_state = nil
-            if check(/\n|$/)
-              encoder.begin_line line_kind = :change
-            else
-              encoder.begin_group :change
-            end
-            encoder.text_token match[0,2], :change
-            encoder.text_token match[2...-2], :plain
-            encoder.text_token match[-2,2], :change
-            encoder.end_group :change unless line_kind
-            next unless match = scan(/.+/)
-            if options[:highlight_code]
-              content_scanner.tokenize match, :tokens => encoder
-            else
-              encoder.text_token match, :plain
-            end
-            next
-          elsif match = scan(/\+/)
-            encoder.begin_line line_kind = :insert
-            encoder.text_token match, :insert
-            next unless match = scan(/.+/)
-            if options[:highlight_code]
-              content_scanner.tokenize match, :tokens => encoder
-            else
-              encoder.text_token match, :plain
-            end
-            next
-          elsif match = scan(/-/)
-            deleted_lines += 1
-            encoder.begin_line line_kind = :delete
-            encoder.text_token match, :delete
-            if options[:inline_diff] && deleted_lines == 1 && check(/(?>.*)\n\+(?>.*)$(?!\n\+)/)
-              content_scanner_entry_state = content_scanner.state
-              skip(/(.*)\n\+(.*)$/)
-              head, deletion, insertion, tail = diff self[1], self[2]
-              pre, deleted, post = content_scanner.tokenize [head, deletion, tail], :tokens => Tokens.new
-              encoder.tokens pre
-              unless deleted.empty?
-                encoder.begin_group :eyecatcher
-                encoder.tokens deleted
-                encoder.end_group :eyecatcher
-              end
-              encoder.tokens post
-              encoder.end_line line_kind
-              encoder.text_token "\n", :space
-              encoder.begin_line line_kind = :insert
-              encoder.text_token '+', :insert
-              content_scanner.state = content_scanner_entry_state || :initial
-              pre, inserted, post = content_scanner.tokenize [head, insertion, tail], :tokens => Tokens.new
-              encoder.tokens pre
-              unless inserted.empty?
-                encoder.begin_group :eyecatcher
-                encoder.tokens inserted
-                encoder.end_group :eyecatcher
-              end
-              encoder.tokens post
-            elsif match = scan(/.*/)
-              if options[:highlight_code]
-                if deleted_lines == 1
-                  content_scanner_entry_state = content_scanner.state
-                end
-                content_scanner.tokenize match, :tokens => encoder unless match.empty?
-                if !match?(/\n-/)
-                  if match?(/\n\+/)
-                    content_scanner.state = content_scanner_entry_state || :initial
-                  end
-                  content_scanner_entry_state = nil
-                end
-              else
-                encoder.text_token match, :plain
-              end
-            end
-            next
-          elsif match = scan(/ .*/)
-            if options[:highlight_code]
-              content_scanner.tokenize match, :tokens => encoder
-            else
-              encoder.text_token match, :plain
-            end
-            next
-          elsif match = scan(/.+/)
-            encoder.begin_line line_kind = :comment
-            encoder.text_token match, :plain
-          else
-            raise_inspect 'else case rached'
-          end
-        
-        when :added
-          if match = scan(/   \+/)
-            encoder.begin_line line_kind = :insert
-            encoder.text_token match, :insert
-            next unless match = scan(/.+/)
-            encoder.text_token match, :plain
-          else
-            state = :initial
-            next
-          end
-        end
-        
-      end
-      
-      encoder.end_line line_kind if line_kind
-      
-      encoder
-    end
-    
-  private
-    
-    def diff a, b
-      # i will be the index of the leftmost difference from the left.
-      i_max = [a.size, b.size].min
-      i = 0
-      i += 1 while i < i_max && a[i] == b[i]
-      # j_min will be the index of the leftmost difference from the right.
-      j_min = i - i_max
-      # j will be the index of the rightmost difference from the right which
-      # does not precede the leftmost one from the left.
-      j = -1
-      j -= 1 while j >= j_min && a[j] == b[j]
-      return a[0...i], a[i..j], b[i..j], (j < -1) ? a[j+1..-1] : ''
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cd13f3dd427937eb092253330df74831980a985d.svn-base
--- /dev/null
+++ b/.svn/pristine/cd/cd13f3dd427937eb092253330df74831980a985d.svn-base
@@ -0,0 +1,63 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingMembersTest < ActionController::IntegrationTest
+  def test_members
+    assert_routing(
+        { :method => 'get', :path => "/projects/5234/memberships.xml" },
+        { :controller => 'members', :action => 'index', :project_id => '5234', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/memberships/5234.xml" },
+        { :controller => 'members', :action => 'show', :id => '5234', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/5234/memberships" },
+        { :controller => 'members', :action => 'create', :project_id => '5234' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/5234/memberships.xml" },
+        { :controller => 'members', :action => 'create', :project_id => '5234', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/memberships/5234" },
+        { :controller => 'members', :action => 'update', :id => '5234' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/memberships/5234.xml" },
+        { :controller => 'members', :action => 'update', :id => '5234', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/memberships/5234" },
+        { :controller => 'members', :action => 'destroy', :id => '5234' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/memberships/5234.xml" },
+        { :controller => 'members', :action => 'destroy', :id => '5234', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/5234/memberships/autocomplete" },
+        { :controller => 'members', :action => 'autocomplete', :project_id => '5234' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/5234/memberships/autocomplete.js" },
+        { :controller => 'members', :action => 'autocomplete', :project_id => '5234', :format => 'js' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cd2d5ab029a36ca237e5cbe16a9436e83ff2e3a8.svn-base
--- /dev/null
+++ b/.svn/pristine/cd/cd2d5ab029a36ca237e5cbe16a9436e83ff2e3a8.svn-base
@@ -0,0 +1,3 @@
+<h3><%=l(:label_document_plural)%></h3>
+
+<%= render :partial => 'documents/document', :collection => documents_items %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cd412581b9626dbf7e98af61ce1dd6cc17d027b2.svn-base
--- a/.svn/pristine/cd/cd412581b9626dbf7e98af61ce1dd6cc17d027b2.svn-base
+++ /dev/null
@@ -1,104 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/bazaar_adapter'
-
-class Repository::Bazaar < Repository
-  attr_protected :root_url
-  validates_presence_of :url, :log_encoding
-
-  def self.human_attribute_name(attribute_key_name)
-    attr_name = attribute_key_name
-    if attr_name == "url"
-      attr_name = "path_to_repository"
-    end
-    super(attr_name)
-  end
-
-  def self.scm_adapter_class
-    Redmine::Scm::Adapters::BazaarAdapter
-  end
-
-  def self.scm_name
-    'Bazaar'
-  end
-
-  def entries(path=nil, identifier=nil)
-    entries = scm.entries(path, identifier)
-    if entries
-      entries.each do |e|
-        next if e.lastrev.revision.blank?
-        # Set the filesize unless browsing a specific revision
-        if identifier.nil? && e.is_file?
-          full_path = File.join(root_url, e.path)
-          e.size = File.stat(full_path).size if File.file?(full_path)
-        end
-        c = Change.find(
-               :first,
-               :include    => :changeset,
-               :conditions => [
-                   "#{Change.table_name}.revision = ? and #{Changeset.table_name}.repository_id = ?",
-                   e.lastrev.revision,
-                   id
-                   ],
-               :order => "#{Changeset.table_name}.revision DESC")
-        if c
-          e.lastrev.identifier = c.changeset.revision
-          e.lastrev.name       = c.changeset.revision
-          e.lastrev.author     = c.changeset.committer
-        end
-      end
-    end
-  end
-
-  def fetch_changesets
-    scm_info = scm.info
-    if scm_info
-      # latest revision found in database
-      db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
-      # latest revision in the repository
-      scm_revision = scm_info.lastrev.identifier.to_i
-      if db_revision < scm_revision
-        logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
-        identifier_from = db_revision + 1
-        while (identifier_from <= scm_revision)
-          # loads changesets by batches of 200
-          identifier_to = [identifier_from + 199, scm_revision].min
-          revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
-          transaction do
-            revisions.reverse_each do |revision|
-              changeset = Changeset.create(:repository   => self,
-                                           :revision     => revision.identifier,
-                                           :committer    => revision.author,
-                                           :committed_on => revision.time,
-                                           :scmid        => revision.scmid,
-                                           :comments     => revision.message)
-
-              revision.paths.each do |change|
-                Change.create(:changeset => changeset,
-                              :action    => change[:action],
-                              :path      => change[:path],
-                              :revision  => change[:revision])
-              end
-            end
-          end unless revisions.nil?
-          identifier_from = identifier_to + 1
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cd4379a595a2f49e8f17242a4f6bf12380cbc901.svn-base
--- /dev/null
+++ b/.svn/pristine/cd/cd4379a595a2f49e8f17242a4f6bf12380cbc901.svn-base
@@ -0,0 +1,1093 @@
+# Indonesian translations
+# by Raden Prabowo (cakbowo@gmail.com)
+
+id:
+  direction: ltr
+  date:
+    formats:
+      default: "%d-%m-%Y"
+      short: "%d %b"
+      long: "%d %B %Y"
+
+    day_names: [Minggu, Senin, Selasa, Rabu, Kamis, Jumat, Sabtu]
+    abbr_day_names: [Ming, Sen, Sel, Rab, Kam, Jum, Sab]
+
+    month_names: [~, Januari, Februari, Maret, April, Mei, Juni, Juli, Agustus, September, Oktober, November, Desember]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, Mei, Jun, Jul, Agu, Sep, Okt, Nov, Des]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a %d %b %Y, %H:%M:%S"
+      time: "%H:%M"
+      short: "%d %b %H:%M"
+      long: "%d %B %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "setengah menit"
+      less_than_x_seconds:
+        one:   "kurang dari sedetik"
+        other: "kurang dari %{count} detik"
+      x_seconds:
+        one:   "sedetik"
+        other: "%{count} detik"
+      less_than_x_minutes:
+        one:   "kurang dari semenit"
+        other: "kurang dari %{count} menit"
+      x_minutes:
+        one:   "semenit"
+        other: "%{count} menit"
+      about_x_hours:
+        one:   "sekitar sejam"
+        other: "sekitar %{count} jam"
+      x_hours:
+        one:   "1 jam"
+        other: "%{count} jam"
+      x_days:
+        one:   "sehari"
+        other: "%{count} hari"
+      about_x_months:
+        one:   "sekitar sebulan"
+        other: "sekitar %{count} bulan"
+      x_months:
+        one:   "sebulan"
+        other: "%{count} bulan"
+      about_x_years:
+        one:   "sekitar setahun"
+        other: "sekitar %{count} tahun"
+      over_x_years:
+        one:   "lebih dari setahun"
+        other: "lebih dari %{count} tahun"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    format:
+      precision: 3
+      separator: ','
+      delimiter: '.'
+    currency:
+      format:
+        unit: 'Rp'
+        precision: 2
+        format: '%n %u'
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  support:
+    array:
+      sentence_connector: "dan"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "tidak termasuk dalam daftar"
+        exclusion: "sudah dicadangkan"
+        invalid: "salah"
+        confirmation: "tidak sesuai konfirmasi"
+        accepted: "harus disetujui"
+        empty: "tidak boleh kosong"
+        blank: "tidak boleh kosong"
+        too_long: "terlalu panjang (maksimum %{count} karakter)"
+        too_short: "terlalu pendek (minimum %{count} karakter)"
+        wrong_length: "panjangnya salah (seharusnya %{count} karakter)"
+        taken: "sudah diambil"
+        not_a_number: "bukan angka"
+        not_a_date: "bukan tanggal"
+        greater_than: "harus lebih besar dari %{count}"
+        greater_than_or_equal_to: "harus lebih besar atau sama dengan %{count}"
+        equal_to: "harus sama dengan %{count}"
+        less_than: "harus kurang dari %{count}"
+        less_than_or_equal_to: "harus kurang atau sama dengan %{count}"
+        odd: "harus ganjil"
+        even: "harus genap"
+        greater_than_start_date: "harus lebih besar dari tanggal mulai"
+        not_same_project: "tidak tergabung dalam proyek yang sama"
+        circular_dependency: "kaitan ini akan menghasilkan circular dependency"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: Silakan pilih
+
+  general_text_No: 'Tidak'
+  general_text_Yes: 'Ya'
+  general_text_no: 'tidak'
+  general_text_yes: 'ya'
+  general_lang_name: 'Indonesia'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_updated: Akun sudah berhasil diperbarui.
+  notice_account_invalid_creditentials: Pengguna atau kata sandi salah
+  notice_account_password_updated: Kata sandi sudah berhasil diperbarui.
+  notice_account_wrong_password: Kata sandi salah.
+  notice_account_register_done: Akun sudah berhasil dibuat. Untuk mengaktifkan akun anda, silakan klik tautan (link) yang dikirim kepada anda melalui e-mail.
+  notice_account_unknown_email: Pengguna tidak dikenal.
+  notice_can_t_change_password: Akun ini menggunakan sumber otentikasi eksternal yang tidak dikenal. Kata sandi tidak bisa diubah.
+  notice_account_lost_email_sent: Email berisi instruksi untuk memilih kata sandi baru sudah dikirimkan kepada anda.
+  notice_account_activated: Akun anda sudah diaktifasi. Sekarang anda bisa login.
+  notice_successful_create: Berhasil dibuat.
+  notice_successful_update: Berhasil diperbarui.
+  notice_successful_delete: Berhasil dihapus.
+  notice_successful_connection: Berhasil terhubung.
+  notice_file_not_found: Berkas yang anda buka tidak ada atau sudah dihapus.
+  notice_locking_conflict: Data sudah diubah oleh pengguna lain.
+  notice_not_authorized: Anda tidak memiliki akses ke halaman ini.
+  notice_email_sent: "Email sudah dikirim ke %{value}"
+  notice_email_error: "Terjadi kesalahan pada saat pengiriman email (%{value})"
+  notice_feeds_access_key_reseted: RSS access key anda sudah direset.
+  notice_failed_to_save_issues: "Gagal menyimpan %{count} masalah dari %{total} yang dipilih: %{ids}."
+  notice_no_issue_selected: "Tidak ada masalah yang dipilih! Silakan pilih masalah yang akan anda sunting."
+  notice_account_pending: "Akun anda sudah dibuat dan sekarang sedang menunggu persetujuan administrator."
+  notice_default_data_loaded: Konfigurasi default sudah berhasil dimuat.
+  notice_unable_delete_version: Tidak bisa menghapus versi.
+
+  error_can_t_load_default_data: "Konfigurasi default tidak bisa dimuat: %{value}"
+  error_scm_not_found: "Entri atau revisi tidak terdapat pada repositori."
+  error_scm_command_failed: "Terjadi kesalahan pada saat mengakses repositori: %{value}"
+  error_scm_annotate: "Entri tidak ada, atau tidak dapat di anotasi."
+  error_issue_not_found_in_project: 'Masalah tidak ada atau tidak tergabung dalam proyek ini.'
+  error_no_tracker_in_project: 'Tidak ada pelacak yang diasosiasikan pada proyek ini. Silakan pilih Pengaturan Proyek.'
+  error_no_default_issue_status: 'Nilai default untuk Status masalah belum didefinisikan. Periksa kembali konfigurasi anda (Pilih "Administrasi --> Status masalah").'
+  error_can_not_reopen_issue_on_closed_version: 'Masalah yang ditujukan pada versi tertutup tidak bisa dibuka kembali'
+  error_can_not_archive_project: Proyek ini tidak bisa diarsipkan
+
+  warning_attachments_not_saved: "%{count} berkas tidak bisa disimpan."
+
+  mail_subject_lost_password: "Kata sandi %{value} anda"
+  mail_body_lost_password: 'Untuk mengubah kata sandi anda, klik tautan berikut::'
+  mail_subject_register: "Aktivasi akun %{value} anda"
+  mail_body_register: 'Untuk mengaktifkan akun anda, klik tautan berikut:'
+  mail_body_account_information_external: "Anda dapat menggunakan akun %{value} anda untuk login."
+  mail_body_account_information: Informasi akun anda
+  mail_subject_account_activation_request: "Permintaan aktivasi akun %{value} "
+  mail_body_account_activation_request: "Pengguna baru (%{value}) sudan didaftarkan. Akun tersebut menunggu persetujuan anda:"
+  mail_subject_reminder: "%{count} masalah harus selesai pada hari berikutnya (%{days})"
+  mail_body_reminder: "%{count} masalah yang ditugaskan pada anda harus selesai dalam %{days} hari kedepan:"
+  mail_subject_wiki_content_added: "'%{id}' halaman wiki sudah ditambahkan"
+  mail_body_wiki_content_added: "The '%{id}' halaman wiki sudah ditambahkan oleh %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' halaman wiki sudah diperbarui"
+  mail_body_wiki_content_updated: "The '%{id}' halaman wiki sudah diperbarui oleh %{author}."
+
+
+  field_name: Nama
+  field_description: Deskripsi
+  field_summary: Ringkasan
+  field_is_required: Dibutuhkan
+  field_firstname: Nama depan
+  field_lastname: Nama belakang
+  field_mail: Email
+  field_filename: Berkas
+  field_filesize: Ukuran
+  field_downloads: Unduhan
+  field_author: Pengarang
+  field_created_on: Dibuat
+  field_updated_on: Diperbarui
+  field_field_format: Format
+  field_is_for_all: Untuk semua proyek
+  field_possible_values: Nilai yang mungkin
+  field_regexp: Regular expression
+  field_min_length: Panjang minimum
+  field_max_length: Panjang maksimum
+  field_value: Nilai
+  field_category: Kategori
+  field_title: Judul
+  field_project: Proyek
+  field_issue: Masalah
+  field_status: Status
+  field_notes: Catatan
+  field_is_closed: Masalah ditutup
+  field_is_default: Nilai default
+  field_tracker: Pelacak
+  field_subject: Perihal
+  field_due_date: Harus selesai
+  field_assigned_to: Ditugaskan ke
+  field_priority: Prioritas
+  field_fixed_version: Versi target
+  field_user: Pengguna
+  field_role: Peran
+  field_homepage: Halaman web
+  field_is_public: Publik
+  field_parent: Subproyek dari
+  field_is_in_roadmap: Masalah ditampilkan di rencana kerja
+  field_login: Login
+  field_mail_notification: Notifikasi email
+  field_admin: Administrator
+  field_last_login_on: Terakhir login
+  field_language: Bahasa
+  field_effective_date: Tanggal
+  field_password: Kata sandi
+  field_new_password: Kata sandi baru
+  field_password_confirmation: Konfirmasi
+  field_version: Versi
+  field_type: Tipe
+  field_host: Host
+  field_port: Port
+  field_account: Akun
+  field_base_dn: Base DN
+  field_attr_login: Atribut login
+  field_attr_firstname: Atribut nama depan
+  field_attr_lastname: Atribut nama belakang
+  field_attr_mail: Atribut email
+  field_onthefly: Pembuatan pengguna seketika
+  field_start_date: Mulai
+  field_done_ratio: "% Selesai"
+  field_auth_source: Mode otentikasi
+  field_hide_mail: Sembunyikan email saya
+  field_comments: Komentar
+  field_url: URL
+  field_start_page: Halaman awal
+  field_subproject: Subproyek
+  field_hours: Jam
+  field_activity: Kegiatan
+  field_spent_on: Tanggal
+  field_identifier: Pengenal
+  field_is_filter: Digunakan sebagai penyaring
+  field_issue_to: Masalah terkait
+  field_delay: Tertunday
+  field_assignable: Masalah dapat ditugaskan pada peran ini
+  field_redirect_existing_links: Alihkan tautan yang ada
+  field_estimated_hours: Perkiraan waktu
+  field_column_names: Kolom
+  field_time_zone: Zona waktu
+  field_searchable: Dapat dicari
+  field_default_value: Nilai default
+  field_comments_sorting: Tampilkan komentar
+  field_parent_title: Halaman induk
+  field_editable: Dapat disunting
+  field_watcher: Pemantau
+  field_identity_url: OpenID URL
+  field_content: Isi
+  field_group_by: Dikelompokkan berdasar
+  field_sharing: Berbagi
+
+  setting_app_title: Judul aplikasi
+  setting_app_subtitle: Subjudul aplikasi
+  setting_welcome_text: Teks sambutan
+  setting_default_language: Bahasa Default
+  setting_login_required: Butuhkan otentikasi
+  setting_self_registration: Swa-pendaftaran
+  setting_attachment_max_size: Ukuran maksimum untuk lampiran
+  setting_issues_export_limit: Batasan ukuran export masalah
+  setting_mail_from: Emisi alamat email
+  setting_bcc_recipients: Blind carbon copy recipients (bcc)
+  setting_plain_text_mail: Plain text mail (no HTML)
+  setting_host_name: Nama host dan path
+  setting_text_formatting: Format teks
+  setting_wiki_compression: Kompresi untuk riwayat wiki
+  setting_feeds_limit: Batasan isi feed
+  setting_default_projects_public: Proyek baru defaultnya adalah publik
+  setting_autofetch_changesets: Autofetch commits
+  setting_sys_api_enabled: Aktifkan WS untuk pengaturan repositori
+  setting_commit_ref_keywords: Referensi kaca kunci
+  setting_commit_fix_keywords: Pembetulan kaca kunci
+  setting_autologin: Autologin
+  setting_date_format: Format tanggal
+  setting_time_format: Format waktu
+  setting_cross_project_issue_relations: Perbolehkan kaitan masalah proyek berbeda
+  setting_issue_list_default_columns: Kolom default ditampilkan di daftar masalah
+  setting_emails_footer: Footer untuk email
+  setting_protocol: Protokol
+  setting_per_page_options: Pilihan obyek per halaman
+  setting_user_format: Format tampilan untuk pengguna
+  setting_activity_days_default: Hari tertampil pada kegiatan proyek
+  setting_display_subprojects_issues: Secara default, tampilkan masalah subproyek pada proyek utama
+  setting_enabled_scm: Enabled SCM
+  setting_mail_handler_api_enabled: Enable WS for incoming emails
+  setting_mail_handler_api_key: API key
+  setting_sequential_project_identifiers: Buat pengenal proyek terurut
+  setting_gravatar_enabled: Gunakan icon pengguna dari Gravatar
+  setting_gravatar_default: Gambar default untuk Gravatar
+  setting_diff_max_lines_displayed: Maksimum perbedaan baris tertampil
+  setting_file_max_size_displayed: Maksimum berkas tertampil secara inline
+  setting_repository_log_display_limit: Nilai maksimum dari revisi ditampilkan di log berkas
+  setting_openid: Perbolehkan Login dan pendaftaran melalui OpenID
+  setting_password_min_length: Panjang minimum untuk kata sandi
+  setting_new_project_user_role_id: Peran diberikan pada pengguna non-admin yang membuat proyek
+  setting_default_projects_modules: Modul yang diaktifkan pada proyek baru
+
+  permission_add_project: Tambahkan proyek
+  permission_edit_project: Sunting proyek
+  permission_select_project_modules: Pilih modul proyek
+  permission_manage_members: Atur anggota
+  permission_manage_versions: Atur versi
+  permission_manage_categories: Atur kategori masalah
+  permission_add_issues: Tambahkan masalah
+  permission_edit_issues: Sunting masalah
+  permission_manage_issue_relations: Atur kaitan masalah
+  permission_add_issue_notes: Tambahkan catatan
+  permission_edit_issue_notes: Sunting catatan
+  permission_edit_own_issue_notes: Sunting catatan saya
+  permission_move_issues: Pindahkan masalah
+  permission_delete_issues: Hapus masalah
+  permission_manage_public_queries: Atur query publik
+  permission_save_queries: Simpan query
+  permission_view_gantt: Tampilkan gantt chart
+  permission_view_calendar: Tampilkan kalender
+  permission_view_issue_watchers: Tampilkan daftar pemantau
+  permission_add_issue_watchers: Tambahkan pemantau
+  permission_delete_issue_watchers: Hapus pemantau
+  permission_log_time: Log waktu terpakai
+  permission_view_time_entries: Tampilkan waktu terpakai
+  permission_edit_time_entries: Sunting catatan waktu
+  permission_edit_own_time_entries: Sunting catatan waktu saya
+  permission_manage_news: Atur berita
+  permission_comment_news: Komentari berita
+  permission_view_documents: Tampilkan dokumen
+  permission_manage_files: Atur berkas
+  permission_view_files: Tampilkan berkas
+  permission_manage_wiki: Atur wiki
+  permission_rename_wiki_pages: Ganti nama halaman wiki
+  permission_delete_wiki_pages: Hapus halaman wiki
+  permission_view_wiki_pages: Tampilkan wiki
+  permission_view_wiki_edits: Tampilkan riwayat wiki
+  permission_edit_wiki_pages: Sunting halaman wiki
+  permission_delete_wiki_pages_attachments: Hapus lampiran
+  permission_protect_wiki_pages: Proteksi halaman wiki
+  permission_manage_repository: Atur repositori
+  permission_browse_repository: Jelajah repositori
+  permission_view_changesets: Tampilkan set perubahan
+  permission_commit_access: Commit akses
+  permission_manage_boards: Atur forum
+  permission_view_messages: Tampilkan pesan
+  permission_add_messages: Tambahkan pesan
+  permission_edit_messages: Sunting pesan
+  permission_edit_own_messages: Sunting pesan saya
+  permission_delete_messages: Hapus pesan
+  permission_delete_own_messages: Hapus pesan saya
+
+  project_module_issue_tracking: Pelacak masalah
+  project_module_time_tracking: Pelacak waktu
+  project_module_news: Berita
+  project_module_documents: Dokumen
+  project_module_files: Berkas
+  project_module_wiki: Wiki
+  project_module_repository: Repositori
+  project_module_boards: Forum
+
+  label_user: Pengguna
+  label_user_plural: Pengguna
+  label_user_new: Pengguna baru
+  label_user_anonymous: Anonymous
+  label_project: Proyek
+  label_project_new: Proyek baru
+  label_project_plural: Proyek
+  label_x_projects:
+    zero:  tidak ada proyek
+    one:   1 proyek
+    other: "%{count} proyek"
+  label_project_all: Semua Proyek
+  label_project_latest: Proyek terakhir
+  label_issue: Masalah
+  label_issue_new: Masalah baru
+  label_issue_plural: Masalah
+  label_issue_view_all: tampilkan semua masalah
+  label_issues_by: "Masalah ditambahkan oleh %{value}"
+  label_issue_added: Masalah ditambahan
+  label_issue_updated: Masalah diperbarui
+  label_document: Dokumen
+  label_document_new: Dokumen baru
+  label_document_plural: Dokumen
+  label_document_added: Dokumen ditambahkan
+  label_role: Peran
+  label_role_plural: Peran
+  label_role_new: Peran baru
+  label_role_and_permissions: Peran dan perijinan
+  label_member: Anggota
+  label_member_new: Anggota baru
+  label_member_plural: Anggota
+  label_tracker: Pelacak
+  label_tracker_plural: Pelacak
+  label_tracker_new: Pelacak baru
+  label_workflow: Alur kerja
+  label_issue_status: Status masalah
+  label_issue_status_plural: Status masalah
+  label_issue_status_new: Status baru
+  label_issue_category: Kategori masalah
+  label_issue_category_plural: Kategori masalah
+  label_issue_category_new: Kategori baru
+  label_custom_field: Field kustom
+  label_custom_field_plural: Field kustom
+  label_custom_field_new: Field kustom
+  label_enumerations: Enumerasi
+  label_enumeration_new: Buat baru
+  label_information: Informasi
+  label_information_plural: Informasi
+  label_please_login: Silakan login
+  label_register: mendaftar
+  label_login_with_open_id_option: atau login menggunakan OpenID
+  label_password_lost: Lupa password
+  label_home: Halaman depan
+  label_my_page: Beranda
+  label_my_account: Akun saya
+  label_my_projects: Proyek saya
+  label_administration: Administrasi
+  label_login: Login
+  label_logout: Keluar
+  label_help: Bantuan
+  label_reported_issues: Masalah terlapor
+  label_assigned_to_me_issues: Masalah yang ditugaskan pada saya
+  label_last_login: Terakhir login
+  label_registered_on: Terdaftar pada
+  label_activity: Kegiatan
+  label_overall_activity: Kegiatan umum
+  label_user_activity: "kegiatan %{value}"
+  label_new: Baru
+  label_logged_as: Login sebagai
+  label_environment: Lingkungan
+  label_authentication: Otentikasi
+  label_auth_source: Mode Otentikasi
+  label_auth_source_new: Mode otentikasi baru
+  label_auth_source_plural: Mode Otentikasi
+  label_subproject_plural: Subproyek
+  label_and_its_subprojects: "%{value} dan subproyeknya"
+  label_min_max_length: Panjang Min - Maks
+  label_list: Daftar
+  label_date: Tanggal
+  label_integer: Integer
+  label_float: Float
+  label_boolean: Boolean
+  label_string: Text
+  label_text: Long text
+  label_attribute: Atribut
+  label_attribute_plural: Atribut
+  label_no_data: Tidak ada data untuk ditampilkan
+  label_change_status: Status perubahan
+  label_history: Riwayat
+  label_attachment: Berkas
+  label_attachment_new: Berkas baru
+  label_attachment_delete: Hapus Berkas
+  label_attachment_plural: Berkas
+  label_file_added: Berkas ditambahkan
+  label_report: Laporan
+  label_report_plural: Laporan
+  label_news: Berita
+  label_news_new: Tambahkan berita
+  label_news_plural: Berita
+  label_news_latest: Berita terakhir
+  label_news_view_all: Tampilkan semua berita
+  label_news_added: Berita ditambahkan
+  label_settings: Pengaturan
+  label_overview: Umum
+  label_version: Versi
+  label_version_new: Versi baru
+  label_version_plural: Versi
+  label_confirmation: Konfirmasi
+  label_export_to: 'Juga tersedia dalam:'
+  label_read: Baca...
+  label_public_projects: Proyek publik
+  label_open_issues: belum selesai
+  label_open_issues_plural: belum selesai
+  label_closed_issues: selesai
+  label_closed_issues_plural: selesai
+  label_x_open_issues_abbr_on_total:
+    zero:  0 belum selesai / %{total}
+    one:   1 belum selesai / %{total}
+    other: "%{count} terbuka / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 belum selesai
+    one:   1 belum selesai
+    other: "%{count} belum selesai"
+  label_x_closed_issues_abbr:
+    zero:  0 selesai
+    one:   1 selesai
+    other: "%{count} selesai"
+  label_total: Total
+  label_permissions: Perijinan
+  label_current_status: Status sekarang
+  label_new_statuses_allowed: Status baru yang diijinkan
+  label_all: semua
+  label_none: tidak ada
+  label_nobody: tidak ada
+  label_next: Berikut
+  label_previous: Sebelum
+  label_used_by: Digunakan oleh
+  label_details: Rincian
+  label_add_note: Tambahkan catatan
+  label_per_page: Per halaman
+  label_calendar: Kalender
+  label_months_from: dari bulan
+  label_gantt: Gantt
+  label_internal: Internal
+  label_last_changes: "%{count} perubahan terakhir"
+  label_change_view_all: Tampilkan semua perubahan
+  label_personalize_page: Personalkan halaman ini
+  label_comment: Komentar
+  label_comment_plural: Komentar
+  label_x_comments:
+    zero: tak ada komentar
+    one: 1 komentar
+    other: "%{count} komentar"
+  label_comment_add: Tambahkan komentar
+  label_comment_added: Komentar ditambahkan
+  label_comment_delete: Hapus komentar
+  label_query: Custom query
+  label_query_plural: Custom queries
+  label_query_new: Query baru
+  label_filter_add: Tambahkan filter
+  label_filter_plural: Filter
+  label_equals: sama dengan
+  label_not_equals: tidak sama dengan
+  label_in_less_than: kurang dari
+  label_in_more_than: lebih dari
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: pada
+  label_today: hari ini
+  label_all_time: semua waktu
+  label_yesterday: kemarin
+  label_this_week: minggu ini
+  label_last_week: minggu lalu
+  label_last_n_days: "%{count} hari terakhir"
+  label_this_month: bulan ini
+  label_last_month: bulan lalu
+  label_this_year: this year
+  label_date_range: Jangkauan tanggal
+  label_less_than_ago: kurang dari hari yang lalu
+  label_more_than_ago: lebih dari hari yang lalu
+  label_ago: hari yang lalu
+  label_contains: berisi
+  label_not_contains: tidak berisi
+  label_day_plural: hari
+  label_repository: Repositori
+  label_repository_plural: Repositori
+  label_browse: Jelajah
+  label_branch: Cabang
+  label_tag: Tag
+  label_revision: Revisi
+  label_revision_plural: Revisi
+  label_associated_revisions: Revisi terkait
+  label_added: ditambahkan
+  label_modified: diubah
+  label_copied: disalin
+  label_renamed: diganti nama
+  label_deleted: dihapus
+  label_latest_revision: Revisi terakhir
+  label_latest_revision_plural: Revisi terakhir
+  label_view_revisions: Tampilkan revisi
+  label_view_all_revisions: Tampilkan semua revisi
+  label_max_size: Ukuran maksimum
+  label_sort_highest: Ke paling atas
+  label_sort_higher: Ke atas
+  label_sort_lower: Ke bawah
+  label_sort_lowest: Ke paling bawah
+  label_roadmap: Rencana kerja
+  label_roadmap_due_in: "Harus selesai dalam %{value}"
+  label_roadmap_overdue: "%{value} terlambat"
+  label_roadmap_no_issues: Tak ada masalah pada versi ini
+  label_search: Cari
+  label_result_plural: Hasil
+  label_all_words: Semua kata
+  label_wiki: Wiki
+  label_wiki_edit: Sunting wiki
+  label_wiki_edit_plural: Sunting wiki
+  label_wiki_page: Halaman wiki
+  label_wiki_page_plural: Halaman wiki
+  label_index_by_title: Indeks menurut judul
+  label_index_by_date: Indeks menurut tanggal
+  label_current_version: Versi sekarang
+  label_preview: Tinjauan
+  label_feed_plural: Feeds
+  label_changes_details: Rincian semua perubahan
+  label_issue_tracking: Pelacak masalah
+  label_spent_time: Waktu terpakai
+  label_f_hour: "%{value} jam"
+  label_f_hour_plural: "%{value} jam"
+  label_time_tracking: Pelacak waktu
+  label_change_plural: Perubahan
+  label_statistics: Statistik
+  label_commits_per_month: Komit per bulan
+  label_commits_per_author: Komit per pengarang
+  label_view_diff: Tampilkan perbedaan
+  label_diff_inline: inline
+  label_diff_side_by_side: berdampingan
+  label_options: Pilihan
+  label_copy_workflow_from: Salin alur kerja dari
+  label_permissions_report: Laporan perijinan
+  label_watched_issues: Masalah terpantau
+  label_related_issues: Masalah terkait
+  label_applied_status: Status teraplikasi
+  label_loading: Memuat...
+  label_relation_new: Kaitan baru
+  label_relation_delete: Hapus kaitan
+  label_relates_to: terkait pada
+  label_duplicates: salinan
+  label_duplicated_by: disalin oleh
+  label_blocks: blok
+  label_blocked_by: diblok oleh
+  label_precedes: mendahului
+  label_follows: mengikuti
+  label_end_to_start: akhir ke awal
+  label_end_to_end: akhir ke akhir
+  label_start_to_start: awal ke awal
+  label_start_to_end: awal ke akhir
+  label_stay_logged_in: Tetap login
+  label_disabled: tidak diaktifkan
+  label_show_completed_versions: Tampilkan versi lengkap
+  label_me: saya
+  label_board: Forum
+  label_board_new: Forum baru
+  label_board_plural: Forum
+  label_topic_plural: Topik
+  label_message_plural: Pesan
+  label_message_last: Pesan terakhir
+  label_message_new: Pesan baru
+  label_message_posted: Pesan ditambahkan
+  label_reply_plural: Balasan
+  label_send_information: Kirim informasi akun ke pengguna
+  label_year: Tahun
+  label_month: Bulan
+  label_week: Minggu
+  label_date_from: Dari
+  label_date_to: Sampai
+  label_language_based: Berdasarkan bahasa pengguna
+  label_sort_by: "Urut berdasarkan %{value}"
+  label_send_test_email: Kirim email percobaan
+  label_feeds_access_key_created_on: "RSS access key dibuat %{value} yang lalu"
+  label_module_plural: Modul
+  label_added_time_by: "Ditambahkan oleh %{author} %{age} yang lalu"
+  label_updated_time_by: "Diperbarui oleh %{author} %{age} yang lalu"
+  label_updated_time: "Diperbarui oleh %{value} yang lalu"
+  label_jump_to_a_project: Pilih proyek...
+  label_file_plural: Berkas
+  label_changeset_plural: Set perubahan
+  label_default_columns: Kolom default
+  label_no_change_option: (Tak ada perubahan)
+  label_bulk_edit_selected_issues: Ubah masalah terpilih secara masal
+  label_theme: Tema
+  label_default: Default
+  label_search_titles_only: Cari judul saja
+  label_user_mail_option_all: "Untuk semua kejadian pada semua proyek saya"
+  label_user_mail_option_selected: "Hanya untuk semua kejadian pada proyek yang saya pilih ..."
+  label_user_mail_no_self_notified: "Saya tak ingin diberitahu untuk perubahan yang saya buat sendiri"
+  label_user_mail_assigned_only_mail_notification: "Kirim email hanya bila saya ditugaskan untuk masalah terkait"
+  label_user_mail_block_mail_notification: "Saya tidak ingin menerima email. Terima kasih."
+  label_registration_activation_by_email: aktivasi akun melalui email
+  label_registration_manual_activation: aktivasi akun secara manual
+  label_registration_automatic_activation: aktivasi akun secara otomatis
+  label_display_per_page: "Per halaman: %{value}"
+  label_age: Umur
+  label_change_properties: Rincian perubahan
+  label_general: Umum
+  label_more: Lanjut
+  label_scm: SCM
+  label_plugins: Plugin
+  label_ldap_authentication: Otentikasi LDAP
+  label_downloads_abbr: Unduh
+  label_optional_description: Deskripsi optional
+  label_add_another_file: Tambahkan berkas lain
+  label_preferences: Preferensi
+  label_chronological_order: Urut sesuai kronologis
+  label_reverse_chronological_order: Urut dari yang terbaru
+  label_planning: Perencanaan
+  label_incoming_emails: Email masuk
+  label_generate_key: Buat kunci
+  label_issue_watchers: Pemantau
+  label_example: Contoh
+  label_display: Tampilan
+  label_sort: Urut
+  label_ascending: Menaik
+  label_descending: Menurun
+  label_date_from_to: Dari %{start} sampai %{end}
+  label_wiki_content_added: Halaman wiki ditambahkan
+  label_wiki_content_updated: Halaman wiki diperbarui
+  label_group: Kelompok
+  label_group_plural: Kelompok
+  label_group_new: Kelompok baru
+  label_time_entry_plural: Waktu terpakai
+  label_version_sharing_none: Tidak dibagi
+  label_version_sharing_descendants: Dengan subproyek
+  label_version_sharing_hierarchy: Dengan hirarki proyek
+  label_version_sharing_tree: Dengan pohon proyek
+  label_version_sharing_system: Dengan semua proyek
+
+
+  button_login: Login
+  button_submit: Kirim
+  button_save: Simpan
+  button_check_all: Contreng semua
+  button_uncheck_all: Hilangkan semua contreng
+  button_delete: Hapus
+  button_create: Buat
+  button_create_and_continue: Buat dan lanjutkan
+  button_test: Test
+  button_edit: Sunting
+  button_add: Tambahkan
+  button_change: Ubah
+  button_apply: Terapkan
+  button_clear: Bersihkan
+  button_lock: Kunci
+  button_unlock: Buka kunci
+  button_download: Unduh
+  button_list: Daftar
+  button_view: Tampilkan
+  button_move: Pindah
+  button_move_and_follow: Pindah dan ikuti
+  button_back: Kembali
+  button_cancel: Batal
+  button_activate: Aktifkan
+  button_sort: Urut
+  button_log_time: Rekam waktu
+  button_rollback: Kembali ke versi ini
+  button_watch: Pantau
+  button_unwatch: Tidak Memantau
+  button_reply: Balas
+  button_archive: Arsip
+  button_unarchive: Batalkan arsip
+  button_reset: Reset
+  button_rename: Ganti nama
+  button_change_password: Ubah kata sandi
+  button_copy: Salin
+  button_copy_and_follow: Salin dan ikuti
+  button_annotate: Anotasi
+  button_update: Perbarui
+  button_configure: Konfigur
+  button_quote: Kutip
+  button_duplicate: Duplikat
+
+  status_active: aktif
+  status_registered: terdaftar
+  status_locked: terkunci
+
+  version_status_open: terbuka
+  version_status_locked: terkunci
+  version_status_closed: tertutup
+
+  field_active: Aktif
+
+  text_select_mail_notifications: Pilih aksi dimana email notifikasi akan dikirimkan.
+  text_regexp_info: mis. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 berarti tidak ada pembatasan
+  text_project_destroy_confirmation: Apakah anda benar-benar akan menghapus proyek ini beserta data terkait ?
+  text_subprojects_destroy_warning: "Subproyek: %{value} juga akan dihapus."
+  text_workflow_edit: Pilih peran dan pelacak untuk menyunting alur kerja
+  text_are_you_sure: Anda yakin ?
+  text_journal_changed: "%{label} berubah dari %{old} menjadi %{new}"
+  text_journal_set_to: "%{label} di set ke %{value}"
+  text_journal_deleted: "%{label} dihapus (%{old})"
+  text_journal_added: "%{label} %{value} ditambahkan"
+  text_tip_issue_begin_day: tugas dimulai hari itu
+  text_tip_issue_end_day: tugas berakhir hari itu
+  text_tip_issue_begin_end_day: tugas dimulai dan berakhir hari itu
+  text_caracters_maximum: "maximum %{count} karakter."
+  text_caracters_minimum: "Setidaknya harus sepanjang %{count} karakter."
+  text_length_between: "Panjang diantara %{min} dan %{max} karakter."
+  text_tracker_no_workflow: Tidak ada alur kerja untuk pelacak ini
+  text_unallowed_characters: Karakter tidak diperbolehkan
+  text_comma_separated: Beberapa nilai diperbolehkan (dipisahkan koma).
+  text_issues_ref_in_commit_messages: Mereferensikan dan membetulkan masalah pada pesan komit
+  text_issue_added: "Masalah %{id} sudah dilaporkan oleh %{author}."
+  text_issue_updated: "Masalah %{id} sudah diperbarui oleh %{author}."
+  text_wiki_destroy_confirmation: Apakah anda benar-benar akan menghapus wiki ini beserta semua isinya ?
+  text_issue_category_destroy_question: "Beberapa masalah (%{count}) ditugaskan pada kategori ini. Apa yang anda lakukan ?"
+  text_issue_category_destroy_assignments: Hapus kategori penugasan
+  text_issue_category_reassign_to: Tugaskan kembali masalah untuk kategori ini
+  text_user_mail_option: "Untuk proyek yang tidak dipilih, anda hanya akan menerima notifikasi hal-hal yang anda pantau atau anda terlibat di dalamnya (misalnya masalah yang anda tulis atau ditugaskan pada anda)."
+  text_no_configuration_data: "Peran, pelacak, status masalah dan alur kerja belum dikonfigur.\nSangat disarankan untuk memuat konfigurasi default. Anda akan bisa mengubahnya setelah konfigurasi dimuat."
+  text_load_default_configuration: Muat konfigurasi default
+  text_status_changed_by_changeset: "Diterapkan di set perubahan %{value}."
+  text_issues_destroy_confirmation: 'Apakah anda yakin untuk menghapus masalah terpilih ?'
+  text_select_project_modules: 'Pilih modul untuk diaktifkan pada proyek ini:'
+  text_default_administrator_account_changed: Akun administrator default sudah berubah
+  text_file_repository_writable: Direktori yang bisa ditulisi untuk lampiran
+  text_plugin_assets_writable: Direktori yang bisa ditulisi untuk plugin asset
+  text_rmagick_available: RMagick tersedia (optional)
+  text_destroy_time_entries_question: "%{hours} jam sudah dilaporkan pada masalah yang akan anda hapus. Apa yang akan anda lakukan ?"
+  text_destroy_time_entries: Hapus jam yang terlapor
+  text_assign_time_entries_to_project: Tugaskan jam terlapor pada proyek
+  text_reassign_time_entries: 'Tugaskan kembali jam terlapor pada masalah ini:'
+  text_user_wrote: "%{value} menulis:"
+  text_enumeration_destroy_question: "%{count} obyek ditugaskan untuk nilai ini."
+  text_enumeration_category_reassign_to: 'Tugaskan kembali untuk nilai ini:'
+  text_email_delivery_not_configured: "Pengiriman email belum dikonfigurasi, notifikasi tidak diaktifkan.\nAnda harus mengkonfigur SMTP server anda pada config/configuration.yml dan restart kembali aplikasi untuk mengaktifkan."
+  text_repository_usernames_mapping: "Pilih atau perbarui pengguna Redmine yang terpetakan ke setiap nama pengguna yang ditemukan di log repositori.\nPengguna dengan nama pengguna dan repositori atau email yang sama  secara otomasit akan dipetakan."
+  text_diff_truncated: '... Perbedaan terpotong karena melebihi batas maksimum yang bisa ditampilkan.'
+  text_custom_field_possible_values_info: 'Satu baris untuk setiap nilai'
+  text_wiki_page_destroy_question: "Halaman ini mempunyai %{descendants} halaman anak dan turunannya. Apa yang akan anda lakukan ?"
+  text_wiki_page_nullify_children: "Biarkan halaman anak sebagai halaman teratas (root)"
+  text_wiki_page_destroy_children: "Hapus halaman anak dan semua turunannya"
+  text_wiki_page_reassign_children: "Tujukan halaman anak ke halaman induk yang ini"
+
+  default_role_manager: Manager
+  default_role_developer: Pengembang
+  default_role_reporter: Pelapor
+  default_tracker_bug: Bug
+  default_tracker_feature: Fitur
+  default_tracker_support: Dukungan
+  default_issue_status_new: Baru
+  default_issue_status_in_progress: Dalam proses
+  default_issue_status_resolved: Resolved
+  default_issue_status_feedback: Umpan balik
+  default_issue_status_closed: Ditutup
+  default_issue_status_rejected: Ditolak
+  default_doc_category_user: Dokumentasi pengguna
+  default_doc_category_tech: Dokumentasi teknis
+  default_priority_low: Rendah
+  default_priority_normal: Normal
+  default_priority_high: Tinggi
+  default_priority_urgent: Penting
+  default_priority_immediate: Segera
+  default_activity_design: Rancangan
+  default_activity_development: Pengembangan
+
+  enumeration_issue_priorities: Prioritas masalah
+  enumeration_doc_categories: Kategori dokumen
+  enumeration_activities: Kegiatan
+  enumeration_system_activity: Kegiatan Sistem
+  label_copy_source: Source
+  label_update_issue_done_ratios: Update issue done ratios
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  label_api_access_key: API access key
+  text_line_separated: Multiple values allowed (one line for each value).
+  label_revision_id: Revision %{value}
+  permission_view_issues: View Issues
+  setting_issue_done_ratio_issue_status: Use the issue status
+  error_issue_done_ratios_not_updated: Issue done ratios not updated.
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  error_workflow_copy_target: Please select target tracker(s) and role(s)
+  label_api_access_key_created_on: API access key created %{value} ago
+  label_feeds_access_key: RSS access key
+  notice_api_access_key_reseted: Your API access key was reset.
+  setting_rest_api_enabled: Enable REST web service
+  label_copy_same_as_target: Same as target
+  button_show: Show
+  setting_issue_done_ratio_issue_field: Use the issue field
+  label_missing_api_access_key: Missing an API access key
+  label_copy_target: Target
+  label_missing_feeds_access_key: Missing a RSS access key
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  error_workflow_copy_source: Please select a source tracker or role
+  setting_start_of_week: Start calendars on
+  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
+  permission_add_subprojects: Create subprojects
+  label_subproject_new: New subproject
+  text_own_membership_delete_confirmation: |-
+    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
+    Are you sure you want to continue?
+  label_close_versions: Close completed versions
+  label_board_sticky: Sticky
+  label_board_locked: Locked
+  permission_export_wiki_pages: Export wiki pages
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: Manage project activities
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_profile: Profile
+  permission_manage_subtasks: Manage subtasks
+  field_parent_issue: Parent task
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Commit messages encoding
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 masalah
+    one:   1 masalah
+    other: "%{count} masalah"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: semua
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Dengan subproyek
+  label_cross_project_tree: Dengan pohon proyek
+  label_cross_project_hierarchy: Dengan hirarki proyek
+  label_cross_project_system: Dengan semua proyek
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cd49a55900aad4b25d728efce849eefc8dc672da.svn-base
--- /dev/null
+++ b/.svn/pristine/cd/cd49a55900aad4b25d728efce849eefc8dc672da.svn-base
@@ -0,0 +1,139 @@
+<ul>
+  <%= call_hook(:view_issues_context_menu_start, {:issues => @issues, :can => @can, :back => @back }) %>
+
+  <% if @issue -%>
+    <li><%= context_menu_link l(:button_edit), edit_issue_path(@issue),
+            :class => 'icon-edit', :disabled => !@can[:edit] %></li>
+  <% else %>
+    <li><%= context_menu_link l(:button_edit), bulk_edit_issues_path(:ids => @issue_ids),
+            :class => 'icon-edit', :disabled => !@can[:edit] %></li>
+  <% end %>
+
+  <% if @allowed_statuses.present? %>
+  <li class="folder">
+    <a href="#" class="submenu"><%= l(:field_status) %></a>
+    <ul>
+    <% @allowed_statuses.each do |s| -%>
+        <li><%= context_menu_link h(s.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {:status_id => s}, :back_url => @back), :method => :post,
+                                  :selected => (@issue && s == @issue.status), :disabled => !@can[:update] %></li>
+    <% end -%>
+    </ul>
+  </li>
+  <% end %>
+
+  <% if @trackers.present? %>
+  <li class="folder">
+    <a href="#" class="submenu"><%= l(:field_tracker) %></a>
+    <ul>
+    <% @trackers.each do |t| -%>
+        <li><%= context_menu_link h(t.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {'tracker_id' => t}, :back_url => @back), :method => :post,
+                                  :selected => (@issue && t == @issue.tracker), :disabled => !@can[:edit] %></li>
+    <% end -%>
+    </ul>
+  </li>
+  <% end %>
+
+  <% if @safe_attributes.include?('priority_id') && @priorities.present? -%>
+  <li class="folder">
+    <a href="#" class="submenu"><%= l(:field_priority) %></a>
+    <ul>
+    <% @priorities.each do |p| -%>
+        <li><%= context_menu_link h(p.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {'priority_id' => p}, :back_url => @back), :method => :post,
+                                  :selected => (@issue && p == @issue.priority), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
+    <% end -%>
+    </ul>
+  </li>
+  <% end %>
+
+  <% if @safe_attributes.include?('fixed_version_id') && @versions.present? -%>
+  <li class="folder">
+    <a href="#" class="submenu"><%= l(:field_fixed_version) %></a>
+    <ul>
+    <% @versions.sort.each do |v| -%>
+        <li><%= context_menu_link format_version_name(v), bulk_update_issues_path(:ids => @issue_ids, :issue => {'fixed_version_id' => v}, :back_url => @back), :method => :post,
+                                  :selected => (@issue && v == @issue.fixed_version), :disabled => !@can[:update] %></li>
+    <% end -%>
+        <li><%= context_menu_link l(:label_none), bulk_update_issues_path(:ids => @issue_ids, :issue => {'fixed_version_id' => 'none'}, :back_url => @back), :method => :post,
+                                  :selected => (@issue && @issue.fixed_version.nil?), :disabled => !@can[:update] %></li>
+    </ul>
+  </li>
+  <% end %>
+
+  <% if @safe_attributes.include?('assigned_to_id') && @assignables.present? -%>
+  <li class="folder">
+    <a href="#" class="submenu"><%= l(:field_assigned_to) %></a>
+    <ul>
+    <% if @assignables.include?(User.current) %>
+        <li><%= context_menu_link "<< #{l(:label_me)} >>", bulk_update_issues_path(:ids => @issue_ids, :issue => {'assigned_to_id' => User.current}, :back_url => @back), :method => :post,
+                                  :disabled => !@can[:update] %></li>
+    <% end %>
+    <% @assignables.each do |u| -%>
+        <li><%= context_menu_link h(u.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {'assigned_to_id' => u}, :back_url => @back), :method => :post,
+                                  :selected => (@issue && u == @issue.assigned_to), :disabled => !@can[:update] %></li>
+    <% end -%>
+        <li><%= context_menu_link l(:label_nobody), bulk_update_issues_path(:ids => @issue_ids, :issue => {'assigned_to_id' => 'none'}, :back_url => @back), :method => :post,
+                                  :selected => (@issue && @issue.assigned_to.nil?), :disabled => !@can[:update] %></li>
+    </ul>
+  </li>
+  <% end %>
+
+  <% if @safe_attributes.include?('category_id') && @project && @project.issue_categories.any? -%>
+  <li class="folder">
+    <a href="#" class="submenu"><%= l(:field_category) %></a>
+    <ul>
+    <% @project.issue_categories.each do |u| -%>
+        <li><%= context_menu_link h(u.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {'category_id' => u}, :back_url => @back), :method => :post,
+                                  :selected => (@issue && u == @issue.category), :disabled => !@can[:update] %></li>
+    <% end -%>
+        <li><%= context_menu_link l(:label_none), bulk_update_issues_path(:ids => @issue_ids, :issue => {'category_id' => 'none'}, :back_url => @back), :method => :post,
+                                  :selected => (@issue && @issue.category.nil?), :disabled => !@can[:update] %></li>
+    </ul>
+  </li>
+  <% end -%>
+
+  <% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %>
+  <li class="folder">
+    <a href="#" class="submenu"><%= l(:field_done_ratio) %></a>
+    <ul>
+    <% (0..10).map{|x|x*10}.each do |p| -%>
+        <li><%= context_menu_link "#{p}%", bulk_update_issues_path(:ids => @issue_ids, :issue => {'done_ratio' => p}, :back_url => @back), :method => :post,
+                                      :selected => (@issue && p == @issue.done_ratio), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
+    <% end -%>
+    </ul>
+  </li>
+  <% end %>
+
+  <% @options_by_custom_field.each do |field, options| %>
+    <li class="folder cf_<%= field.id %>">
+      <a href="#" class="submenu"><%= h(field.name) %></a>
+      <ul>
+      <% options.each do |text, value| %>
+        <li><%= bulk_update_custom_field_context_menu_link(field, text, value || text) %></li>
+      <% end %>
+      <% unless field.is_required? %>
+        <li><%= bulk_update_custom_field_context_menu_link(field, l(:label_none), '__none__') %></li>
+      <% end %>
+      </ul>
+    </li>
+  <% end %>
+
+<% if User.current.logged? %>
+  <li><%= watcher_link(@issues, User.current) %></li>
+<% end %>
+
+<% if @issue.present? %>
+  <% if @can[:log_time] -%>
+  <li><%= context_menu_link l(:button_log_time), new_issue_time_entry_path(@issue),
+          :class => 'icon-time-add' %></li>
+  <% end %>
+  <li><%= context_menu_link l(:button_copy), project_copy_issue_path(@project, @issue),
+          :class => 'icon-copy', :disabled => !@can[:copy] %></li>
+<% else %>
+  <li><%= context_menu_link l(:button_copy), bulk_edit_issues_path(:ids => @issue_ids, :copy => '1'),
+                          :class => 'icon-copy', :disabled => !@can[:move] %></li>
+<% end %>													
+  <li><%= context_menu_link l(:button_delete), issues_path(:ids => @issue_ids, :back_url => @back),
+                            :method => :delete, :data => {:confirm => issues_destroy_confirmation_message(@issues)}, :class => 'icon-del', :disabled => !@can[:delete] %></li>
+
+  <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %>
+</ul>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cd592887335d21aca272fd319f91c63379f5d086.svn-base
--- a/.svn/pristine/cd/cd592887335d21aca272fd319f91c63379f5d086.svn-base
+++ /dev/null
@@ -1,74 +0,0 @@
---- 
-projects_001: 
-  created_on: 2006-07-19 19:13:59 +02:00
-  name: eCookbook
-  updated_on: 2006-07-19 22:53:01 +02:00
-  id: 1
-  description: Recipes management application
-  homepage: http://ecookbook.somenet.foo/
-  is_public: true
-  identifier: ecookbook
-  parent_id: 
-  lft: 1
-  rgt: 10
-projects_002: 
-  created_on: 2006-07-19 19:14:19 +02:00
-  name: OnlineStore
-  updated_on: 2006-07-19 19:14:19 +02:00
-  id: 2
-  description: E-commerce web site
-  homepage: ""
-  is_public: false
-  identifier: onlinestore
-  parent_id: 
-  lft: 11
-  rgt: 12
-projects_003: 
-  created_on: 2006-07-19 19:15:21 +02:00
-  name: eCookbook Subproject 1
-  updated_on: 2006-07-19 19:18:12 +02:00
-  id: 3
-  description: eCookBook Subproject 1
-  homepage: ""
-  is_public: true
-  identifier: subproject1
-  parent_id: 1
-  lft: 6
-  rgt: 7
-projects_004: 
-  created_on: 2006-07-19 19:15:51 +02:00
-  name: eCookbook Subproject 2
-  updated_on: 2006-07-19 19:17:07 +02:00
-  id: 4
-  description: eCookbook Subproject 2
-  homepage: ""
-  is_public: true
-  identifier: subproject2
-  parent_id: 1
-  lft: 8
-  rgt: 9
-projects_005: 
-  created_on: 2006-07-19 19:15:51 +02:00
-  name: Private child of eCookbook
-  updated_on: 2006-07-19 19:17:07 +02:00
-  id: 5
-  description: This is a private subproject of a public project
-  homepage: ""
-  is_public: false
-  identifier: private-child
-  parent_id: 1
-  lft: 2
-  rgt: 5
-projects_006: 
-  created_on: 2006-07-19 19:15:51 +02:00
-  name: Child of private child
-  updated_on: 2006-07-19 19:17:07 +02:00
-  id: 6
-  description: This is a public subproject of a private project
-  homepage: ""
-  is_public: true
-  identifier: project6
-  parent_id: 5
-  lft: 3
-  rgt: 4
-  
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cd674353ec11ce3e47c106792aeb680957571d71.svn-base
--- a/.svn/pristine/cd/cd674353ec11ce3e47c106792aeb680957571d71.svn-base
+++ /dev/null
@@ -1,21 +0,0 @@
-<% content_for :header_tags do %>
-  <%= javascript_include_tag 'repository_navigation' %>
-<% end %>
-
-<%= link_to l(:label_statistics), {:action => 'stats', :id => @project}, :class => 'icon icon-stats' %>
-
-<% form_tag({:action => controller.action_name, :id => @project, :path => to_path_param(@path), :rev => ''}, {:method => :get, :id => 'revision_selector'}) do -%>
-  <!-- Branches Dropdown -->
-  <% if !@repository.branches.nil? && @repository.branches.length > 0 -%>
-    | <%= l(:label_branch) %>: 
-    <%= select_tag :branch, options_for_select([''] + @repository.branches,@rev), :id => 'branch' %>
-  <% end -%>
-
-  <% if !@repository.tags.nil? && @repository.tags.length > 0 -%>
-    | <%= l(:label_tag) %>: 
-    <%= select_tag :tag, options_for_select([''] + @repository.tags,@rev), :id => 'tag' %>
-  <% end -%>
-
-  | <%= l(:label_revision) %>: 
-  <%= text_field_tag 'rev', @rev, :size => 8 %>
-<% end -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cd82575e9a77e51c0f726bf6149523455798899e.svn-base
--- a/.svn/pristine/cd/cd82575e9a77e51c0f726bf6149523455798899e.svn-base
+++ /dev/null
@@ -1,17 +0,0 @@
-<table class="list entries" id="browser">
-<thead>
-<tr id="root">
-<th><%= l(:field_name) %></th>
-<th><%= l(:field_filesize) %></th>
-<% if @repository.report_last_commit %>
-<th><%= l(:label_revision)  %></th>
-<th><%= l(:label_age)       %></th>
-<th><%= l(:field_author)    %></th>
-<th><%= l(:field_comments)  %></th>
-<% end %>
-</tr>
-</thead>
-<tbody>
-<%= render :partial => 'dir_list_content' %>
-</tbody>
-</table>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cdbe648d6f9e337038e30cb5fa01921b70b5cc71.svn-base
--- /dev/null
+++ b/.svn/pristine/cd/cdbe648d6f9e337038e30cb5fa01921b70b5cc71.svn-base
@@ -0,0 +1,1090 @@
+mn:
+  direction: ltr
+  jquery:
+    locale: "en"
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y/%m/%d"
+      short: "%b %d"
+      long: "%Y, %B %d"
+
+    day_names: [Ð”Ð°Ð²Ð°Ð°, ÐœÑÐ³Ð¼Ð°Ñ€, Ð›Ñ…Ð°Ð³Ð²Ð°, ÐŸÒ¯Ñ€ÑÐ², Ð‘Ð°Ð°ÑÐ°Ð½, Ð‘ÑÐ¼Ð±Ð°, ÐÑÐ¼]
+    abbr_day_names: [Ð”Ð°Ð², ÐœÑÐ³, Ð›Ñ…Ð°, ÐŸÒ¯Ñ€, Ð‘ÑÐ½, Ð‘ÑÐ¼, ÐÑÐ¼]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, 1-Ñ€ ÑÐ°Ñ€, 2-Ñ€ ÑÐ°Ñ€, 3-Ñ€ ÑÐ°Ñ€, 4-Ñ€ ÑÐ°Ñ€, 5-Ñ€ ÑÐ°Ñ€, 6-Ñ€ ÑÐ°Ñ€, 7-Ñ€ ÑÐ°Ñ€, 8-Ñ€ ÑÐ°Ñ€, 9-Ñ€ ÑÐ°Ñ€, 10-Ñ€ ÑÐ°Ñ€, 11-Ñ€ ÑÐ°Ñ€, 12-Ñ€ ÑÐ°Ñ€]
+    abbr_month_names: [~, 1ÑÐ°Ñ€, 2ÑÐ°Ñ€, 3ÑÐ°Ñ€, 4ÑÐ°Ñ€, 5ÑÐ°Ñ€, 6ÑÐ°Ñ€, 7ÑÐ°Ñ€, 8ÑÐ°Ñ€, 9ÑÐ°Ñ€, 10ÑÐ°Ñ€, 11ÑÐ°Ñ€, 12ÑÐ°Ñ€]
+    # Used in date_select and datime_select.
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%Y/%m/%d %I:%M %p"
+      time: "%I:%M %p"
+      short: "%d %b %H:%M"
+      long: "%Y, %B %d %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "Ñ…Ð°Ð³Ð°Ñ Ð¼Ð¸Ð½ÑƒÑ‚"
+      less_than_x_seconds:
+        one:   "ÑÐµÐºÑƒÐ½Ð´ Ð¾Ñ€Ñ‡Ð¸Ð¼"
+        other: "%{count} ÑÐµÐºÑƒÐ½Ð´ÑÑÑ Ð±Ð°Ð³Ð° Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°"
+      x_seconds:
+        one:   "1 ÑÐµÐºÑƒÐ½Ð´"
+        other: "%{count} ÑÐµÐºÑƒÐ½Ð´"
+      less_than_x_minutes:
+        one:   "Ð¼Ð¸Ð½ÑƒÑ‚Ð°Ð°Ñ Ð±Ð°Ð³Ð° Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°"
+        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚Ð°Ð°Ñ Ð±Ð°Ð³Ð° Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°"
+      x_minutes:
+        one:   "1 Ð¼Ð¸Ð½ÑƒÑ‚"
+        other: "%{count} Ð¼Ð¸Ð½ÑƒÑ‚"
+      about_x_hours:
+        one:   "1 Ñ†Ð°Ð³ Ð¾Ñ€Ñ‡Ð¸Ð¼"
+        other: "Ð¾Ð¹Ñ€Ð¾Ð»Ñ†Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ %{count} Ñ†Ð°Ð³"
+      x_hours:
+        one:   "1 Ñ†Ð°Ð³"
+        other: "%{count} Ñ†Ð°Ð³"
+      x_days:
+        one:   "1 Ó©Ð´Ó©Ñ€"
+        other: "%{count} Ó©Ð´Ó©Ñ€"
+      about_x_months:
+        one:   "1 ÑÐ°Ñ€ Ð¾Ñ€Ñ‡Ð¸Ð¼"
+        other: "Ð¾Ð¹Ñ€Ð¾Ð»Ñ†Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ %{count} ÑÐ°Ñ€"
+      x_months:
+        one:   "1 ÑÐ°Ñ€"
+        other: "%{count} ÑÐ°Ñ€"
+      about_x_years:
+        one:   "Ð¾Ð¹Ñ€Ð¾Ð»Ñ†Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ 1 Ð¶Ð¸Ð»"
+        other: "Ð¾Ð¹Ñ€Ð¾Ð»Ñ†Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ %{count} Ð¶Ð¸Ð»"
+      over_x_years:
+        one:   "1 Ð¶Ð¸Ð»ÑÑÑ Ð¸Ñ…"
+        other: "%{count} Ð¶Ð¸Ð»ÑÑÑ Ð¸Ñ…"
+      almost_x_years:
+        one:   "Ð±Ð°Ñ€Ð°Ð³ 1 Ð¶Ð¸Ð»"
+        other: "Ð±Ð°Ñ€Ð°Ð³ %{count} Ð¶Ð¸Ð»"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Ð‘Ð°Ð¹Ñ‚"
+            other: "Ð‘Ð°Ð¹Ñ‚"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "Ð±Ð°Ñ"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ‚Ð°Ð´ Ð·Ð°Ð°Ð³Ð´Ð°Ð°Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°"
+        exclusion: "Ð½Ó©Ó©Ñ†Ð»Ó©Ð³Ð´ÑÓ©Ð½"
+        invalid: "Ð±ÑƒÑ€ÑƒÑƒ"
+        confirmation: "Ð±Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑÐ°Ð½ Ó©Ð³Ó©Ð³Ð´Ó©Ð»Ñ‚ÑÐ¹ Ñ‚Ð°Ð°Ñ€Ð°Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°"
+        accepted: "Ñ…Ò¯Ð»ÑÑÐ¶ Ð°Ð²Ð°Ñ… Ñ‘ÑÑ‚Ð¾Ð¹"
+        empty: "Ñ…Ð¾Ð¾ÑÐ¾Ð½ Ð±Ð°Ð¹Ð¶ Ð±Ð¾Ð»Ð¾Ñ…Ð³Ò¯Ð¹"
+        blank: "Ð±Ð»Ð°Ð½Ðº Ð±Ð°Ð¹Ð¶ Ð±Ð¾Ð»Ð¾Ñ…Ð³Ò¯Ð¹"
+        too_long: "Ð´ÑÐ½Ð´Ò¯Ò¯ ÑƒÑ€Ñ‚ Ð±Ð°Ð¹Ð½Ð° (Ñ…Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð¸Ñ…Ð´ÑÑ %{count} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚)"
+        too_short: "Ð´ÑÐ½Ð´Ò¯Ò¯ Ð±Ð¾Ð³Ð¸Ð½Ð¾ Ð±Ð°Ð¹Ð½Ð° (Ñ…Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð±Ð°Ð³Ð°Ð´Ð°Ð° %{count} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚)"
+        wrong_length: "Ð±ÑƒÑ€ÑƒÑƒ ÑƒÑ€Ñ‚Ñ‚Ð°Ð¹ Ð±Ð°Ð¹Ð½Ð° (Ð·Ð°Ð°Ð²Ð°Ð» %{count} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚)"
+        taken: "Ð°Ð»ÑŒ Ñ…ÑÐ´Ð¸Ð¹Ð½Ñ Ð°Ð²ÑÐ°Ð½ Ð±Ð°Ð¹Ð½Ð°"
+        not_a_number: "Ñ‚Ð¾Ð¾ Ð±Ð¸Ñˆ Ð±Ð°Ð¹Ð½Ð°"
+        not_a_date: "Ð·Ó©Ð² Ð¾Ð³Ð½Ð¾Ð¾ Ð±Ð¸Ñˆ Ð±Ð°Ð¹Ð½Ð°"
+        greater_than: "%{count} Ð¸Ñ… Ð±Ð°Ð¹Ñ… Ñ‘ÑÑ‚Ð¾Ð¹"
+        greater_than_or_equal_to: "must be greater than or equal to %{count}"
+        equal_to: "must be equal to %{count}"
+        less_than: "must be less than %{count}"
+        less_than_or_equal_to: "must be less than or equal to %{count}"
+        odd: "Ð·Ð°Ð°Ð²Ð°Ð» ÑÐ¾Ð½Ð´Ð³Ð¾Ð¹"
+        even: "Ð·Ð°Ð°Ð²Ð°Ð» Ñ‚ÑÐ³Ñˆ"
+        greater_than_start_date: "must be greater than start date"
+        not_same_project: "Ð½ÑÐ³ Ð¸Ð¶Ð¸Ð» Ñ‚Ó©ÑÓ©Ð»Ð´ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°"
+        circular_dependency: "Ð­Ð½Ñ Ñ…Ð°Ñ€ÑŒÑ†Ð°Ð° Ð½ÑŒ Ð³Ð¸Ð½Ð¶Ð¸Ð½(Ñ€ÐµÐºÑƒÑ€ÑÐ¸Ð²) Ñ…Ð°Ñ€ÑŒÑ†Ð°Ð° Ò¯Ò¯ÑÐ³ÑÑ… ÑŽÐ¼ Ð±Ð°Ð¹Ð½Ð°"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: Ð¡Ð¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ
+
+  general_text_No: 'Ò®Ð³Ò¯Ð¹'
+  general_text_Yes: 'Ð¢Ð¸Ð¹Ð¼'
+  general_text_no: 'Ò¯Ð³Ò¯Ð¹'
+  general_text_yes: 'Ñ‚Ð¸Ð¹Ð¼'
+  general_lang_name: 'Mongolian (ÐœÐ¾Ð½Ð³Ð¾Ð»)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '7'
+
+  notice_account_updated: Ð”Ð°Ð½ÑÑ‹Ð³ Ð°Ð¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ó©Ó©Ñ€Ñ‡Ð¸Ð»Ð»Ó©Ó©.
+  notice_account_invalid_creditentials: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ð½ÑÑ€ ÑÑÐ²ÑÐ» Ð½ÑƒÑƒÑ† Ò¯Ð³ Ð±ÑƒÑ€ÑƒÑƒ Ð±Ð°Ð¹Ð½Ð°
+  notice_account_password_updated: ÐÑƒÑƒÑ† Ò¯Ð³Ð¸Ð¹Ð³ Ð°Ð¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ó©Ó©Ñ€Ñ‡Ð¸Ð»Ð»Ó©Ó©.
+  notice_account_wrong_password: Ð‘ÑƒÑ€ÑƒÑƒ Ð½ÑƒÑƒÑ† Ò¯Ð³
+  notice_account_register_done: Ð¨Ð¸Ð½Ñ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ Ð°Ð¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ò¯Ò¯ÑÐ³ÑÐ»ÑÑ. Ð˜Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…Ð¸Ð¹Ð½ Ñ‚ÑƒÐ»Ð´, Ð±Ð¸Ð´Ð½Ð¸Ð¹ Ñ‚Ð°Ð½ÑŒ Ð»ÑƒÑƒ Ð¸Ð»Ð³ÑÑÑÑÐ½ Ð¼ÑÐ¹Ð» Ð´Ð¾Ñ‚Ð¾Ñ€ Ð±Ð°Ð¹Ð³Ð°Ð° Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ Ð´Ð°Ñ€Ð°Ð°Ñ€Ð°Ð¹.
+  notice_account_unknown_email: Ò®Ð» Ð¼ÑÐ´ÑÐ³Ð´ÑÑ… Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡.
+  notice_can_t_change_password: Ð­Ð½Ñ ÑÑ€Ñ… Ð³Ð°Ð´Ð°Ð°Ð´ Ð½ÑÐ²Ñ‚Ñ€ÑÐ»Ñ‚ÑÐ´ Ð°ÑˆÐ¸Ð³Ð»Ð°Ð´Ð°Ð³ ÑƒÑ‡Ñ€Ð°Ð°Ñ Ð½ÑƒÑƒÑ† Ò¯Ð³Ð¸Ð¹Ð³ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ… Ð±Ð¾Ð»Ð¾Ð¼Ð¶Ð³Ò¯Ð¹.
+  notice_account_lost_email_sent: Ð‘Ð¸Ð´ Ñ‚Ð°Ð½ÑŒÐ´ Ð¼ÑÐ¹Ð»ÑÑÑ€ Ð½ÑƒÑƒÑ† Ò¯Ð³ÑÑ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ… Ð·Ð°Ð°Ð²Ñ€Ñ‹Ð³ Ð¸Ð»Ð³ÑÑÑÑÐ½ Ð±Ð°Ð¹Ð³Ð°Ð°.
+  notice_account_activated: Ð¢Ð°Ð½Ñ‹ Ð´Ð°Ð½Ñ Ð¸Ð´ÑÐ²Ñ…Ð¶Ð»ÑÑ. ÐžÐ´Ð¾Ð¾ Ð½ÑÐ²Ñ‚ÑÑ€Ñ‡ Ð¾Ñ€Ð¶ Ð±Ð¾Ð»Ð½Ð¾.
+  notice_successful_create: ÐÐ¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ò¯Ò¯ÑÐ³ÑÐ»ÑÑ.
+  notice_successful_update: ÐÐ¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ó©Ó©Ñ€Ñ‡Ð¸Ð»Ð»Ó©Ó©.
+  notice_successful_delete: ÐÐ¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ ÑƒÑÑ‚Ð³Ð°Ð»Ð°Ð°.
+  notice_successful_connection: ÐÐ¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ñ…Ð¾Ð»Ð±Ð¾Ð³Ð´Ð»Ð¾Ð¾.
+  notice_file_not_found: Ð¢Ð°Ð½Ñ‹ Ò¯Ð·ÑÑ… Ð³ÑÑÑÐ½ Ñ…ÑƒÑƒÐ´Ð°Ñ Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ ÑŽÐ¼ÑƒÑƒ ÑƒÑÑ‚Ð³Ð°Ð³Ð´ÑÐ°Ð½ Ð±Ð°Ð¹Ð½Ð°.
+  notice_locking_conflict: Ó¨Ð³Ó©Ð³Ð´Ð»Ð¸Ð¹Ð³ Ó©Ó©Ñ€ Ñ…Ò¯Ð½ Ó©Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½ Ð±Ð°Ð¹Ð½Ð°.
+  notice_not_authorized: Ð¢Ð°Ð½Ð´ ÑÐ½Ñ Ñ…ÑƒÑƒÐ´ÑÑ‹Ð³ Ò¯Ð·ÑÑ… ÑÑ€Ñ… Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°.
+  notice_email_sent: "%{value} - Ñ€ÑƒÑƒ Ð¼ÑÐ¹Ð» Ð¸Ð»Ð³ÑÑÐ»ÑÑ"
+  notice_email_error: "ÐœÑÐ¹Ð» Ð¸Ð»Ð³ÑÑÑ…ÑÐ´ Ð°Ð»Ð´Ð°Ð° Ð³Ð°Ñ€Ð»Ð°Ð° (%{value})"
+  notice_feeds_access_key_reseted: Ð¢Ð°Ð½Ñ‹ RSS Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€Ð¸Ð¹Ð³ Ð´Ð°Ñ…Ð¸Ð½ ÑÑ…Ð»Ò¯Ò¯Ð»Ð»ÑÑ.
+  notice_api_access_key_reseted: Your API access key was reset.
+  notice_failed_to_save_issues: "%{total} Ð°ÑÑƒÑƒÐ´Ð°Ð» ÑÐ¾Ð½Ð³Ð¾Ð³Ð´ÑÐ¾Ð½Ð¾Ð¾Ñ %{count} Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð³ Ð½ÑŒ Ñ…Ð°Ð´Ð³Ð°Ð»Ð°Ñ…Ð°Ð´ Ð°Ð»Ð´Ð°Ð° Ð³Ð°Ñ€Ð»Ð°Ð°: %{ids}."
+  notice_no_issue_selected: "Ð¯Ð¼Ð°Ñ€ Ñ‡ Ð°ÑÑƒÑƒÐ´Ð°Ð» ÑÐ¾Ð½Ð³Ð¾Ð³Ð´Ð¾Ð¾Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°! Ð—Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ… Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ð°Ð° ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ."
+  notice_account_pending: "Ð¢Ð°Ð½Ñ‹ Ð´Ð°Ð½ÑÑ‹Ð³ Ò¯Ò¯ÑÐ³ÑÐ¶ Ð´ÑƒÑƒÑÐ»Ð°Ð°, Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€ Ð±Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑƒÑƒÐ»Ð°Ñ… Ñ…Ò¯Ñ€Ñ‚ÑÐ» Ñ…Ò¯Ð»ÑÑÐ½Ñ Ò¯Ò¯."
+  notice_default_data_loaded: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ñ‚Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾Ð³ Ð°Ð¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ Ð°Ñ‡Ð°Ð°Ð»Ð»Ð°Ð°.
+  notice_unable_delete_version: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ… Ð±Ð¾Ð»Ð¾Ð¼Ð¶Ð³Ò¯Ð¹.
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+
+  error_can_t_load_default_data: "Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ñ‚Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾Ð³ Ð°Ñ‡Ð°Ð°Ð»Ð¶ Ñ‡Ð°Ð´ÑÐ°Ð½Ð³Ò¯Ð¹: %{value}"
+  error_scm_not_found: "Repository Ð´Ð¾Ñ‚Ð¾Ñ€ Ñ‚ÑƒÑ…Ð°Ð¹Ð½ Ð±Ð¸Ñ‡Ð»ÑÐ³ ÑÑÐ²ÑÐ» Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ñ‹Ð³ Ð¾Ð»ÑÐ¾Ð½Ð³Ò¯Ð¹."
+  error_scm_command_failed: "Repository-Ð´ Ñ…Ð°Ð½Ð´Ð°Ñ…Ð°Ð´ Ð°Ð»Ð´Ð°Ð° Ð³Ð°Ñ€Ð»Ð°Ð°:  %{value}"
+  error_scm_annotate: "Ð‘Ð¸Ñ‡Ð»ÑÐ³ Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°, ÑÑÐ²ÑÐ» Ð±Ð¸Ñ‡Ð»ÑÐ³Ñ‚ Ñ‚Ð°Ð¹Ð»Ð±Ð°Ñ€ Ñ…Ð°Ð²ÑÐ°Ñ€Ð³Ð°Ð¶ Ð±Ð¾Ð»Ð¾Ñ…Ð³Ò¯Ð¹."
+  error_issue_not_found_in_project: 'Ð¡Ð¾Ð½Ð³Ð¾ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ´Ð°Ð» ÑÐ½Ñ Ñ‚Ó©ÑÓ©Ð»Ð´ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð´Ð°Ð³Ð³Ò¯Ð¹ ÑŽÐ¼ ÑƒÑƒ ÑÑÐ²ÑÐ» ÑÐ¸ÑÑ‚ÐµÐ¼Ð´ Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°.'
+  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
+  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
+  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version can not be reopened'
+  error_can_not_archive_project: This project can not be archived
+  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
+  error_workflow_copy_source: 'Please select a source tracker or role'
+  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
+
+  warning_attachments_not_saved: "%{count} file(s) Ñ„Ð°Ð¹Ð»Ñ‹Ð³ Ñ…Ð°Ð´Ð³Ð°Ð»Ð¶ Ñ‡Ð°Ð´ÑÐ°Ð½Ð³Ò¯Ð¹."
+
+  mail_subject_lost_password: "Ð¢Ð°Ð½Ñ‹ %{value} Ð½ÑƒÑƒÑ† Ò¯Ð³"
+  mail_body_lost_password: 'ÐÑƒÑƒÑ† Ò¯Ð³ÑÑ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…Ð¸Ð¹Ð½ Ñ‚ÑƒÐ»Ð´ Ð´Ð¾Ð¾Ñ€Ñ… Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ Ð´Ð°Ñ€Ð½Ð° ÑƒÑƒ:'
+  mail_subject_register: "Ð¢Ð°Ð½Ñ‹ %{value} Ð´Ð°Ð½ÑÑ‹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…"
+  mail_body_register: 'Ð”Ð°Ð½ÑÐ°Ð° Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…Ð¸Ð¹Ð½ Ñ‚ÑƒÐ»Ð´ Ð´Ð¾Ð¾Ñ€Ñ… Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ Ð´Ð°Ñ€Ð½Ð° ÑƒÑƒ:'
+  mail_body_account_information_external: "Ð¢Ð° Ó©Ó©Ñ€Ð¸Ð¹Ð½Ñ…Ó©Ó© %{value} Ð´Ð°Ð½ÑÑ‹Ð³ Ð°ÑˆÐ¸Ð³Ð»Ð°Ð¶ Ñ…Ð¾Ð»Ð±Ð¾Ð³Ð´Ð¾Ð¶ Ð±Ð¾Ð»Ð½Ð¾."
+  mail_body_account_information: Ð¢Ð°Ð½Ñ‹ Ð´Ð°Ð½ÑÐ½Ñ‹ Ñ‚ÑƒÑ…Ð°Ð¹ Ð¼ÑÐ´ÑÑÐ»ÑÐ»
+  mail_subject_account_activation_request: "%{value} Ð´Ð°Ð½ÑÑ‹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ… Ñ…Ò¯ÑÑÐ»Ñ‚"
+  mail_body_account_activation_request: "Ð¨Ð¸Ð½Ñ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ (%{value}) Ð±Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑÐ½ Ð±Ð°Ð¹Ð½Ð°. Ð¢Ð°Ð½Ñ‹ Ð±Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑƒÑƒÐ»Ð°Ñ…Ñ‹Ð³ Ñ…Ò¯Ð»ÑÑÐ¶ Ð±Ð°Ð¹Ð½Ð°:"
+  mail_subject_reminder: "Ð”Ð°Ñ€Ð°Ð°Ð³Ð¸Ð¹Ð½ Ó©Ð´Ñ€Ò¯Ò¯Ð´ÑÐ´ %{count} Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð³ ÑˆÐ¸Ð¹Ð´ÑÑ… Ñ…ÑÑ€ÑÐ³Ñ‚ÑÐ¹ (%{days})"
+  mail_body_reminder: "Ð¢Ð°Ð½Ð´ Ð¾Ð½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½ %{count} Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð´Ð°Ñ€Ð°Ð°Ð³Ð¸Ð¹Ð½ %{days} Ó©Ð´Ñ€Ò¯Ò¯Ð´ÑÐ´ ÑˆÐ¸Ð¹Ð´ÑÑ… Ñ…ÑÑ€ÑÐ³Ñ‚ÑÐ¹:"
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
+
+
+  field_name: ÐÑÑ€
+  field_description: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€
+  field_summary: Ð”Ò¯Ð³Ð½ÑÐ»Ñ‚
+  field_is_required: Ð—Ð°Ð¹Ð»ÑˆÐ³Ò¯Ð¹
+  field_firstname: Ð¢Ð°Ð½Ñ‹ Ð½ÑÑ€
+  field_lastname: ÐžÐ²Ð¾Ð³
+  field_mail: Ð˜Ð¼ÑÐ¹Ð»
+  field_filename: Ð¤Ð°Ð¹Ð»
+  field_filesize: Ð¥ÑÐ¼Ð¶ÑÑ
+  field_downloads: Ð¢Ð°Ñ‚Ð°Ð¶ Ð°Ð²Ð°Ñ… Ð·Ò¯Ð¹Ð»Ñ
+  field_author: Ð—Ð¾Ñ…Ð¸Ð¾Ð³Ñ‡
+  field_created_on: Ò®Ò¯ÑÑÑÐ½
+  field_updated_on: Ó¨Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½
+  field_field_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚
+  field_is_for_all: Ð‘Ò¯Ñ… Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´
+  field_possible_values: Ð‘Ð¾Ð»Ð¾Ð¼Ð¶Ñ‚Ð¾Ð¹ ÑƒÑ‚Ð³ÑƒÑƒÐ´
+  field_regexp: Ð­Ð½Ð³Ð¸Ð¹Ð½ Ð¸Ð»ÑÑ€Ñ…Ð¸Ð¹Ð»ÑÐ»
+  field_min_length: ÐœÐ¸Ð½Ð¸Ð¼ÑƒÐ¼ ÑƒÑ€Ñ‚
+  field_max_length: ÐœÐ°ÐºÑÐ¸Ð¼ÑƒÐ¼ ÑƒÑ€Ñ‚
+  field_value: Ð£Ñ‚Ð³Ð°
+  field_category: Ð¢Ó©Ñ€Ó©Ð»
+  field_title: Ð“Ð°Ñ€Ñ‡Ð¸Ð³
+  field_project: Ð¢Ó©ÑÓ©Ð»
+  field_issue: ÐÑÑƒÑƒÐ´Ð°Ð»
+  field_status: Ð¢Ó©Ð»Ó©Ð²
+  field_notes: Ð¢ÑÐ¼Ð´ÑÐ³Ð»ÑÐ»Ò¯Ò¯Ð´
+  field_is_closed: ÐÑÑƒÑƒÐ´Ð°Ð» Ñ…Ð°Ð°Ð³Ð´ÑÐ°Ð½
+  field_is_default: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ ÑƒÑ‚Ð³Ð°
+  field_tracker: Ð§Ð¸Ð³Ð»ÑÐ»
+  field_subject: Ð“Ð°Ñ€Ñ‡Ð¸Ð³
+  field_due_date: Ð”ÑƒÑƒÑÐ°Ñ… Ð¾Ð³Ð½Ð¾Ð¾
+  field_assigned_to: ÐžÐ½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½
+  field_priority: Ð—ÑÑ€ÑÐ³Ð»ÑÐ»
+  field_fixed_version: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
+  field_user: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡
+  field_role: Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…
+  field_homepage: ÐÒ¯Ò¯Ñ€ Ñ…ÑƒÑƒÐ´Ð°Ñ
+  field_is_public: ÐžÐ»Ð¾Ð½ Ð½Ð¸Ð¹Ñ‚Ð¸Ð¹Ð½
+  field_parent: Ð­Ñ†ÑÐ³ Ñ‚Ó©ÑÓ©Ð» Ð½ÑŒ
+  field_is_in_roadmap: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑÐ²Ñ†Ñ‹Ð½ Ð·ÑƒÑ€Ð°Ð³ Ð´ÑÑÑ€ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ…
+  field_login: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð½ÑÑ€
+  field_mail_notification: Ð˜Ð¼ÑÐ¹Ð» Ð¼ÑÐ´ÑÐ³Ð´Ð»Ò¯Ò¯Ð´
+  field_admin: ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€
+  field_last_login_on: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ñ…Ð¾Ð»Ð±Ð¾Ð¾
+  field_language: Ð¥ÑÐ»
+  field_effective_date: ÐžÐ³Ð½Ð¾Ð¾
+  field_password: ÐÑƒÑƒÑ† Ò¯Ð³
+  field_new_password: Ð¨Ð½Ð½Ñ Ð½ÑƒÑƒÑ† Ò¯Ð³
+  field_password_confirmation: Ð‘Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑƒÑƒÐ»Ð°Ñ…
+  field_version: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
+  field_type: Ð¢Ó©Ñ€Ó©Ð»
+  field_host: Ð¥Ð¾ÑÑ‚
+  field_port: ÐŸÐ¾Ñ€Ñ‚
+  field_account: Ð”Ð°Ð½Ñ
+  field_base_dn: Ò®Ð½Ð´ÑÑÐ½ Ð”Ð
+  field_attr_login: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
+  field_attr_firstname: Ð¢Ð°Ð½Ñ‹ Ð½ÑÑ€ Ð°Ñ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
+  field_attr_lastname: ÐžÐ²Ð¾Ð³ Ð°Ñ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
+  field_attr_mail: Ð˜Ð¼ÑÐ¹Ð» Ð°Ñ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
+  field_onthefly: Ð¥Ò¯ÑÑÑÐ½ Ò¯ÐµÐ´ÑÑ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ Ò¯Ò¯ÑÐ³ÑÑ…
+  field_start_date: Ð­Ñ…Ð»ÑÐ»
+  field_done_ratio: "%% Ð“Ò¯Ð¹Ñ†ÑÑ‚Ð³ÑÑÑÐ½"
+  field_auth_source: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ€Ð³Ð°
+  field_hide_mail: ÐœÐ¸Ð½Ð¸Ð¹ Ð¸Ð¼ÑÐ¹Ð» Ñ…Ð°ÑÐ³Ð¸Ð¹Ð³ Ð½ÑƒÑƒ
+  field_comments: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€
+  field_url: URL Ð¥Ð°ÑÐ³
+  field_start_page: Ð¢ÑÑ€Ð³Ò¯Ò¯Ð½ Ñ…ÑƒÑƒÐ´Ð°Ñ
+  field_subproject: Ð”ÑÐ´ Ñ‚Ó©ÑÓ©Ð»
+  field_hours: Ð¦Ð°Ð³
+  field_activity: Ò®Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°
+  field_spent_on: ÐžÐ³Ð½Ð¾Ð¾
+  field_identifier: Ð¢Ó©ÑÐ»Ð¸Ð¹Ð½ Ð³Ð»Ð¾Ð±Ð°Ð» Ð½ÑÑ€
+  field_is_filter: Ð¨Ò¯Ò¯Ð»Ñ‚Ò¯Ò¯Ñ€ Ð±Ð¾Ð»Ð³Ð¾Ð½ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ð´Ð´ÑÐ³
+  field_issue_to: Ð¥Ð°Ð¼Ð°Ð°Ñ‚Ð°Ð¹ Ð°ÑÑƒÑƒÐ´Ð°Ð»
+  field_delay: Ð¥Ð¾Ñ†Ñ€Ð¾Ð»Ñ‚
+  field_assignable: Ð­Ð½Ñ Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…ÑÐ´ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð¾Ð½Ð¾Ð¾Ð¶ Ó©Ð³Ñ‡ Ð±Ð¾Ð»Ð½Ð¾
+  field_redirect_existing_links: Ð‘Ð°Ð¹Ð³Ð°Ð° Ñ…Ð¾Ð»Ð±Ð¾Ð¾ÑÑƒÑƒÐ´Ñ‹Ð³ Ð´Ð°Ñ…Ð¸Ð½ Ñ‡Ð¸Ð³Ð»Ò¯Ò¯Ð»ÑÑ…
+  field_estimated_hours: Ð‘Ð°Ñ€Ð°Ð³Ñ†Ð°Ð°Ð»ÑÐ°Ð½ Ñ†Ð°Ð³
+  field_column_names: Ð‘Ð°Ð³Ð°Ð½ÑƒÑƒÐ´
+  field_time_zone: Ð¦Ð°Ð³Ñ‹Ð½ Ð±Ò¯Ñ
+  field_searchable: Ð¥Ð°Ð¹Ð¶ Ð±Ð¾Ð»Ð¾Ñ…
+  field_default_value: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ ÑƒÑ‚Ð³Ð°
+  field_comments_sorting: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€ÑƒÑƒÐ»
+  field_parent_title: Ð­Ñ†ÑÐ³ Ñ…ÑƒÑƒÐ´Ð°Ñ
+  field_editable: Ð—Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ð³Ð´Ð°Ð½Ð°
+  field_watcher: Ð¥Ð°Ñ€Ð½Ð°
+  field_identity_url: OpenID URL
+  field_content: ÐÐ³ÑƒÑƒÐ»Ð³Ð°
+  field_group_by: Ò®Ñ€ Ð´Ò¯Ð½Ð³ÑÑÑ€ Ð±Ò¯Ð»ÑÐ³Ð»ÑÑ…
+  field_sharing: Sharing
+
+  setting_app_title: ÐŸÑ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹Ð½ Ð³Ð°Ñ€Ñ‡Ð¸Ð³
+  setting_app_subtitle: ÐŸÑ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹Ð½ Ð´ÑÐ´ Ð³Ð°Ñ€Ñ‡Ð¸Ð³
+  setting_welcome_text: ÐœÑÐ½Ð´Ñ‡Ð¸Ð»Ð³ÑÑ
+  setting_default_language: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ñ…ÑÐ»
+  setting_login_required: ÐÑÐ²Ñ‚Ñ€ÑÑ… ÑˆÐ°Ð°Ñ€Ð´Ð»Ð°Ð³Ð°Ñ‚Ð°Ð¹
+  setting_self_registration: Ó¨Ó©Ñ€Ð¸Ð¹Ð³Ó©Ó© Ð±Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑ…
+  setting_attachment_max_size: Ð¥Ð°Ð²ÑÑ€Ð°Ð»Ñ‚ Ñ„Ð°Ð¹Ð»Ñ‹Ð½ Ð´ÑÑÐ´ Ñ…ÑÐ¼Ð¶ÑÑ
+  setting_issues_export_limit: ÐÑÑƒÑƒÐ´Ð°Ð» ÑÐºÑÐ¿Ð¾Ñ€Ñ‚Ð»Ð¾Ñ… Ñ…ÑÐ·Ð³Ð°Ð°Ñ€
+  setting_mail_from: Ð¯Ð¼Ð°Ñ€ Ð¸Ð¼ÑÐ¹Ð» Ñ…Ð°ÑÐ³ Ò¯Ò¯ÑÐ³ÑÑ…
+  setting_bcc_recipients: BCC Ñ‚Ð°Ð»Ð±Ð°Ñ€Ñ‹Ð½ Ñ…Ð°ÑÐ³ÑƒÑƒÐ´ (bcc)
+  setting_plain_text_mail: Ð´Ð°Ð½ Ñ‚ÐµÐºÑÑ‚ Ð¼ÑÐ¹Ð» (HTML Ð±Ð¸Ñˆ)
+  setting_host_name: Ð¥Ð¾ÑÑ‚Ñ‹Ð½ Ð½ÑÑ€ Ð±Ð¾Ð»Ð¾Ð½ Ð·Ð°Ð¼
+  setting_text_formatting: Ð¢ÐµÐºÑÑ‚ Ñ…ÑÐ»Ð±ÑÑ€Ð¶Ò¯Ò¯Ð»ÑÐ»Ñ‚
+  setting_wiki_compression: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð½ Ñ‚Ò¯Ò¯Ñ… Ð´ÑÑÑ€ ÑˆÐ°Ñ…Ð°Ð»Ñ‚ Ñ…Ð¸Ð¹Ñ…
+  setting_feeds_limit: Ð¤Ð¸Ð¹Ð´ Ð°Ð³ÑƒÑƒÐ»Ð³Ñ‹Ð½ Ñ…ÑÐ·Ð³Ð°Ð°Ñ€
+  setting_default_projects_public: Ð¨Ð¸Ð½Ñ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð°Ð°Ñ€ Ð¾Ð»Ð¾Ð½ Ð½Ð¸Ð¹Ñ‚Ð¸Ð¹Ð½Ñ… Ð±Ð°Ð¹Ð½Ð°
+  setting_autofetch_changesets: ÐšÐ¾Ð¼Ð¸Ñ‚ÑƒÑƒÐ´Ñ‹Ð³ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð°Ð°Ñ€ Ñ‚Ð°Ñ‚Ð°Ð¶ Ð°Ð²Ð°Ñ…
+  setting_sys_api_enabled: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸ Ð¼ÐµÐ½ÐµÐ¶Ð¼ÐµÐ½Ñ‚ÑÐ´ Ð·Ð¾Ñ€Ð¸ÑƒÐ»Ð°Ð½ WS-Ð¸Ð¹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
+  setting_commit_ref_keywords: Ð¥Ð°Ð¼Ð°Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ… Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ Ò¯Ð³Ñ
+  setting_commit_fix_keywords: Ð—Ð¾Ð¾Ð»Ñ‚Ñ‚Ð¾Ð¹ Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ Ò¯Ð³Ñ
+  setting_autologin: ÐšÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€ Ð´ÑÑÑ€ ÑÐ°Ð½Ð°Ñ…
+  setting_date_format: ÐžÐ³Ð½Ð¾Ð¾Ð½Ñ‹ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚
+  setting_time_format: Ð¦Ð°Ð³Ð¸Ð¹Ð½ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚
+  setting_cross_project_issue_relations: Ð¢Ó©ÑÓ©Ð» Ñ…Ð¾Ð¾Ñ€Ð¾Ð½Ð´ Ð°ÑÑƒÑƒÐ´Ð°Ð» Ñ…Ð°Ð¼Ð°Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ…Ñ‹Ð³ Ð·Ó©Ð²ÑˆÓ©Ó©Ñ€Ó©Ñ…
+  setting_issue_list_default_columns: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ… ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ð±Ð°Ð³Ð°Ð½ÑƒÑƒÐ´
+  setting_emails_footer: Ð˜Ð¼ÑÐ¹Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…Ó©Ð» Ñ…ÑÑÑÐ³
+  setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
+  setting_per_page_options: ÐÑÐ³ Ñ…ÑƒÑƒÐ´ÑÐ°Ð½Ð´ Ð±Ð°Ð¹Ñ… Ð¾Ð±ÑŒÐµÐºÑ‚ÑƒÑƒÐ´Ñ‹Ð½ Ñ‚Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾
+  setting_user_format: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð´Ð¸Ð¹Ð³ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ… Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚
+  setting_activity_days_default: Ð¢Ó©ÑÐ»Ð¸Ð¹Ð½ Ò¯Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð° Ñ…ÑÑÑÐ³Ñ‚ Ò¯Ð·Ò¯Ò¯Ð»ÑÑ… Ó©Ð´Ñ€Ð¸Ð¹Ð½ Ñ‚Ð¾Ð¾
+  setting_display_subprojects_issues: Ð”ÑÐ´ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð°Ð°Ñ€ Ð³Ð¾Ð» Ñ‚Ó©ÑÓ©Ð» Ð´ÑÑÑ€ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ…
+  setting_enabled_scm: SCM - Ð¸Ð¹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
+  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
+  setting_mail_handler_api_enabled: Ð˜Ñ€ÑÑÐ½ Ð¼ÑÐ¹Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´ WS-Ð¸Ð¹Ð³ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
+  setting_mail_handler_api_key: API Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€
+  setting_sequential_project_identifiers: Ð”ÑÑ Ð´Ð°Ñ€Ð°Ð°Ð»ÑÐ°Ð½ Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ð³Ð»Ð¾Ð±Ð°Ð» Ð½ÑÑ€ Ò¯Ò¯ÑÐ³ÑÐ¶ Ð±Ð°Ð¹Ñ…
+  setting_gravatar_enabled: Gravatar Ð´Ò¯Ñ€ÑÒ¯Ò¯Ð´Ð¸Ð¹Ð³ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð´ÑÐ´ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ¶ Ð±Ð°Ð¹Ñ…
+  setting_gravatar_default: Default Gravatar image
+  setting_diff_max_lines_displayed: Ð¯Ð»Ð³Ð°Ð°Ñ‚Ð°Ð¹ Ð¼Ó©Ñ€Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ‚Ð¾Ð¾ (Ð´ÑÑÐ´ Ñ‚Ð°Ð» Ð½ÑŒ)
+  setting_file_max_size_displayed: Max size of text files displayed inline
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_openid: Allow OpenID login and registration
+  setting_password_min_length: Minimum password length
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_field: Use the issue field
+  setting_issue_done_ratio_issue_status: Use the issue status
+  setting_start_of_week: Start calendars on
+  setting_rest_api_enabled: Enable REST web service
+  setting_cache_formatted_text: Cache formatted text
+
+  permission_add_project: Create project
+  permission_add_subprojects: Create subprojects
+  permission_edit_project: Ð¢Ó©ÑÐ»Ð¸Ð¹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  permission_select_project_modules: Ð¢Ó©ÑÐ»Ð¸Ð¹Ð½ Ð¼Ð¾Ð´ÑƒÐ»ÑƒÑƒÐ´Ð¸Ð¹Ð³ ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ
+  permission_manage_members: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð¸Ð¹Ð½ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð´
+  permission_manage_project_activities: Manage project activities
+  permission_manage_versions: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
+  permission_manage_categories: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ð°Ð½Ð³Ð¸Ð»Ð»ÑƒÑƒÐ´
+  permission_view_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  permission_add_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´ Ð½ÑÐ¼ÑÑ…
+  permission_edit_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  permission_manage_issue_relations: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð»Ñ‹Ð³ Ð·Ð¾Ñ…Ð¸Ñ†ÑƒÑƒÐ»Ð°Ñ…
+  permission_add_issue_notes: Ð¢ÑÐ¼Ð´ÑÐ³Ð»ÑÐ» Ð½ÑÐ¼ÑÑ…
+  permission_edit_issue_notes: Ð¢ÑÐ¼Ð´ÑÐ³Ð»ÑÐ»Ò¯Ò¯Ð´ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  permission_edit_own_issue_notes: Ó¨Ó©Ñ€Ð¸Ð¹Ð½ Ò¯Ð»Ð´ÑÑÑÑÐ½ Ñ‚ÑÐ¼Ð´ÑÐ³Ð»ÑÐ»Ò¯Ò¯Ð´Ð¸Ð¹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  permission_move_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð·Ó©Ó©Ñ…
+  permission_delete_issues: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
+  permission_manage_public_queries: ÐžÐ»Ð¾Ð½ Ð½Ð¸Ð¹Ñ‚Ð¸Ð¹Ð½ Ð°ÑÑƒÑƒÐ»Ñ‚ÑƒÑƒÐ´
+  permission_save_queries: ÐÑÑƒÑƒÐ»Ñ‚ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ð´Ð³Ð°Ð»Ð°Ñ…
+  permission_view_gantt: Ð“Ð°Ð½Ñ‚ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼Ñ‹Ð³ Ò¯Ð·ÑÑ…
+  permission_view_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€ÑŒ Ò¯Ð·ÑÑ…
+  permission_view_issue_watchers: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ñ‡Ð´Ñ‹Ð½ Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ‚Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  permission_add_issue_watchers: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ñ‡Ð¸Ð´ Ð½ÑÐ¼ÑÑ…
+  permission_delete_issue_watchers: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ñ‡Ð´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
+  permission_log_time: Ð—Ð°Ñ€Ñ†ÑƒÑƒÐ»ÑÐ°Ð½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð³ Ð»Ð¾Ð³ Ñ…Ð¸Ð¹Ñ…
+  permission_view_time_entries: Ð—Ð°Ñ€Ñ†ÑƒÑƒÐ»ÑÐ°Ð½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  permission_edit_time_entries: Ð¥ÑƒÐ³Ð°Ñ†Ð°Ð°Ð½Ñ‹ Ð»Ð¾Ð³ÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  permission_edit_own_time_entries: Ó¨Ó©Ñ€Ð¸Ð¹Ð½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð½Ñ‹ Ð»Ð¾Ð³ÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  permission_manage_news: ÐœÑÐ´ÑÑ Ð¼ÑÐ´ÑÑÐ»Ð»Ò¯Ò¯Ð´
+  permission_comment_news: ÐœÑÐ´ÑÑÐ½Ð´ Ñ‚Ð°Ð¹Ð»Ð±Ð°Ñ€ Ò¯Ð»Ð´ÑÑÑ…
+  permission_view_documents: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  permission_manage_files: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´
+  permission_view_files: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  permission_manage_wiki: Ð’Ð¸ÐºÐ¸ ÑƒÐ´Ð¸Ñ€Ð´Ð°Ñ…
+  permission_rename_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ Ð´Ð°Ñ…Ð¸Ð¶ Ð½ÑÑ€Ð»ÑÑ…
+  permission_delete_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
+  permission_view_wiki_pages: Ð’Ð¸ÐºÐ¸ Ò¯Ð·ÑÑ…
+  permission_view_wiki_edits: Ð’Ð¸ÐºÐ¸ Ñ‚Ò¯Ò¯Ñ… Ò¯Ð·ÑÑ…
+  permission_edit_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  permission_delete_wiki_pages_attachments: Ð¥Ð°Ð²ÑÑ€Ð°Ð»Ñ‚ÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
+  permission_protect_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ð¼Ð³Ð°Ð°Ð»Ð°Ñ…
+  permission_manage_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸
+  permission_browse_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ð¹Ð³ Ò¯Ð·ÑÑ…
+  permission_view_changesets: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  permission_commit_access: ÐšÐ¾Ð¼Ð¼Ð¸Ñ‚ Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚
+  permission_manage_boards: Ð¡Ð°Ð¼Ð±Ð°Ñ€ÑƒÑƒÐ´
+  permission_view_messages: Ð—ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  permission_add_messages: Ð—ÑƒÑ€Ð²Ð°Ñ Ð¸Ð»Ð³ÑÑÑ…
+  permission_edit_messages: Ð—ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  permission_edit_own_messages: Ó¨Ó©Ñ€Ð¸Ð¹Ð½ Ð·ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  permission_delete_messages: Ð—ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
+  permission_delete_own_messages: Ó¨Ó©Ñ€Ð¸Ð¹Ð½ Ð·ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
+  permission_export_wiki_pages: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´ÑÑƒÑƒÐ´Ñ‹Ð³ ÑÐºÑÐ¿Ð¾Ñ€Ñ‚ Ñ…Ð¸Ð¹Ñ…
+
+  project_module_issue_tracking: ÐÑÑƒÑƒÐ´Ð°Ð» Ñ…ÑÐ½Ð°Ñ…
+  project_module_time_tracking: Ð¥ÑƒÐ³Ð°Ñ†Ð°Ð° Ñ…ÑÐ½Ð°Ñ…
+  project_module_news: ÐœÑÐ´ÑÑ Ð¼ÑÐ´ÑÑÐ»Ð»Ò¯Ò¯Ð´
+  project_module_documents: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ÑƒÑƒÐ´
+  project_module_files: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´
+  project_module_wiki: Ð’Ð¸ÐºÐ¸
+  project_module_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸
+  project_module_boards: Ð¡Ð°Ð¼Ð±Ð°Ñ€ÑƒÑƒÐ´
+
+  label_user: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡
+  label_user_plural: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð´
+  label_user_new: Ð¨Ð¸Ð½Ñ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡
+  label_user_anonymous: Ð¥Ð°Ð¼Ð°Ð°Ð³Ò¯Ð¹ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡
+  label_project: Ð¢Ó©ÑÓ©Ð»
+  label_project_new: Ð¨Ð¸Ð½Ñ Ñ‚Ó©ÑÓ©Ð»
+  label_project_plural: Ð¢Ó©ÑÐ»Ò¯Ò¯Ð´
+  label_x_projects:
+    zero:  Ñ‚Ó©ÑÓ©Ð» Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹
+    one:   1 Ñ‚Ó©ÑÓ©Ð»
+    other: "%{count} Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´"
+  label_project_all: Ð‘Ò¯Ñ… Ð¢Ó©ÑÐ»Ò¯Ò¯Ð´
+  label_project_latest: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ò¯ÐµÐ¸Ð¹Ð½ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´
+  label_issue: ÐÑÑƒÑƒÐ´Ð°Ð»
+  label_issue_new: Ð¨Ð¸Ð½Ñ Ð°ÑÑƒÑƒÐ´Ð°Ð»
+  label_issue_plural: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
+  label_issue_view_all: Ð‘Ò¯Ñ… Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  label_issues_by: "%{value} - Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´"
+  label_issue_added: ÐÑÑƒÑƒÐ´Ð°Ð» Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
+  label_issue_updated: ÐÑÑƒÑƒÐ´Ð°Ð» Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð³Ð´Ð»Ó©Ó©
+  label_document: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚
+  label_document_new: Ð¨Ð¸Ð½Ñ Ð±Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚
+  label_document_plural: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ÑƒÑƒÐ´
+  label_document_added: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
+  label_role: Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…
+  label_role_plural: Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…Ò¯Ò¯Ð´
+  label_role_new: Ð¨Ð¸Ð½Ñ Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…
+  label_role_and_permissions: Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…Ò¯Ò¯Ð´ Ð±Ð¾Ð»Ð¾Ð½ Ð·Ó©Ð²ÑˆÓ©Ó©Ñ€Ð»Ò¯Ò¯Ð´
+  label_member: Ð“Ð¸ÑˆÒ¯Ò¯Ð½
+  label_member_new: Ð¨Ð¸Ð½Ñ Ð³Ð¸ÑˆÒ¯Ò¯Ð½
+  label_member_plural: Ð“Ð¸ÑˆÒ¯Ò¯Ð´
+  label_tracker: Ð§Ð¸Ð³Ð»ÑÐ»
+  label_tracker_plural: Ð§Ð¸Ð³Ð»ÑÐ»Ò¯Ò¯Ð´
+  label_tracker_new: Ð¨Ð¸Ð½Ñ Ñ‡Ð¸Ð³Ð»ÑÐ»
+  label_workflow: ÐÐ¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð°Ð»
+  label_issue_status: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‚Ó©Ð»Ó©Ð²
+  label_issue_status_plural: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‚Ó©Ð»Ð²Ò¯Ò¯Ð´
+  label_issue_status_new: Ð¨Ð¸Ð½Ñ Ñ‚Ó©Ð»Ó©Ð²
+  label_issue_category: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ð°Ð½Ð³Ð¸Ð»Ð°Ð»
+  label_issue_category_plural: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ð°Ð½Ð³Ð¸Ð»Ð»ÑƒÑƒÐ´
+  label_issue_category_new: Ð¨Ð¸Ð½Ñ Ð°Ð½Ð³Ð¸Ð»Ð°Ð»
+  label_custom_field: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ñ‚Ð°Ð»Ð±Ð°Ñ€
+  label_custom_field_plural: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ñ‚Ð°Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
+  label_custom_field_new: Ð¨Ð¸Ð½ÑÑÑ€ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ñ‚Ð°Ð»Ð±Ð°Ñ€ Ò¯Ò¯ÑÐ³ÑÑ…
+  label_enumerations: ÐÐ½Ð³Ð¸Ð»Ð»ÑƒÑƒÐ´
+  label_enumeration_new: Ð¨Ð¸Ð½Ñ ÑƒÑ‚Ð³Ð°
+  label_information: ÐœÑÐ´ÑÑÐ»ÑÐ»
+  label_information_plural: ÐœÑÐ´ÑÑÐ»Ð»Ò¯Ò¯Ð´
+  label_please_login: ÐÑÐ²Ñ‚ÑÑ€Ñ‡ Ð¾Ñ€Ð½Ð¾ ÑƒÑƒ
+  label_register: Ð‘Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑ…
+  label_login_with_open_id_option: or login with OpenID
+  label_password_lost: ÐÑƒÑƒÑ† Ò¯Ð³ÑÑ Ð°Ð»Ð´ÑÐ°Ð½
+  label_home: ÐÒ¯Ò¯Ñ€
+  label_my_page: ÐœÐ¸Ð½Ð¸Ð¹ Ñ…ÑƒÑƒÐ´Ð°Ñ
+  label_my_account: ÐœÐ¸Ð½Ð¸Ð¹ Ð´Ð°Ð½Ñ
+  label_my_projects: ÐœÐ¸Ð½Ð¸Ð¹ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´
+  label_administration: ÐÐ´Ð¼Ð¸Ð½ Ñ…ÑÑÑÐ³
+  label_login: ÐÑÐ²Ñ‚Ñ€ÑÑ…
+  label_logout: Ð“Ð°Ñ€Ð°Ñ…
+  label_help: Ð¢ÑƒÑÐ»Ð°Ð¼Ð¶
+  label_reported_issues: ÐœÑÐ´ÑÐ³Ð´ÑÑÐ½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
+  label_assigned_to_me_issues: ÐÐ°Ð´Ð°Ð´ Ð¾Ð½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
+  label_last_login: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ñ…Ð¾Ð»Ð±Ð¾Ð»Ñ‚
+  label_registered_on: Ð‘Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑÐ½ Ð¾Ð³Ð½Ð¾Ð¾
+  label_activity: Ò®Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°
+  label_overall_activity: Ð•Ñ€Ó©Ð½Ñ…Ð¸Ð¹ Ò¯Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°
+  label_user_activity: "%{value}-Ð¸Ð¹Ð½ Ò¯Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°"
+  label_new: Ð¨Ð¸Ð½Ñ
+  label_logged_as: Ð¥Ð¾Ð»Ð±Ð¾Ð³Ð´ÑÐ¾Ð½ Ð½ÑÑ€
+  label_environment: ÐžÑ€Ñ‡Ð¸Ð½
+  label_authentication: ÐÑÐ²Ñ‚Ñ€ÑÑ…
+  label_auth_source: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ€Ð³Ð°
+  label_auth_source_new: Ð¨Ð¸Ð½Ñ Ð½ÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ€Ð³Ð°
+  label_auth_source_plural: ÐÑÐ²Ñ‚Ñ€ÑÑ… Ð°Ñ€Ð³ÑƒÑƒÐ´
+  label_subproject_plural: Ð”ÑÐ´ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´
+  label_subproject_new: Ð¨Ð¸Ð½Ñ Ð´ÑÐ´ Ñ‚Ó©ÑÓ©Ð»
+  label_and_its_subprojects: "%{value} Ð±Ð¾Ð»Ð¾Ð½ Ñ…Ð¾Ð»Ð±Ð¾Ð³Ð´Ð¾Ñ… Ð´ÑÐ´ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´"
+  label_min_max_length: Ð”ÑÑÐ´ - Ð”Ð¾Ð¾Ð´ ÑƒÑ€Ñ‚
+  label_list: Ð–Ð°Ð³ÑÐ°Ð°Ð»Ñ‚
+  label_date: ÐžÐ³Ð½Ð¾Ð¾
+  label_integer: Ð‘Ò¯Ñ…ÑÐ» Ñ‚Ð¾Ð¾
+  label_float: Ð‘ÑƒÑ‚Ð°Ñ€Ñ…Ð°Ð¹ Ñ‚Ð¾Ð¾
+  label_boolean: Ò®Ð½ÑÐ½ Ñ…ÑƒÐ´Ð°Ð» ÑƒÑ‚Ð³Ð°
+  label_string: Ð¢ÐµÐºÑÑ‚
+  label_text: Ð£Ñ€Ñ‚ Ñ‚ÐµÐºÑÑ‚
+  label_attribute: ÐÑ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
+  label_attribute_plural: ÐÑ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚ÑƒÑƒÐ´
+  label_no_data: Ò®Ð·Ò¯Ò¯Ð»ÑÑ… Ó©Ð³Ó©Ð³Ð´Ó©Ð» Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°
+  label_change_status: Ð¢Ó©Ð»Ð²Ð¸Ð¹Ð³ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…
+  label_history: Ð¢Ò¯Ò¯Ñ…
+  label_attachment: Ð¤Ð°Ð¹Ð»
+  label_attachment_new: Ð¨Ð¸Ð½Ñ Ñ„Ð°Ð¹Ð»
+  label_attachment_delete: Ð¤Ð°Ð¹Ð» ÑƒÑÑ‚Ð³Ð°Ñ…
+  label_attachment_plural: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´
+  label_file_added: Ð¤Ð°Ð¹Ð» Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
+  label_report: Ð¢Ð°Ð¹Ð»Ð°Ð½
+  label_report_plural: Ð¢Ð°Ð¹Ð»Ð°Ð½Ð³ÑƒÑƒÐ´
+  label_news: ÐœÑÐ´ÑÑ
+  label_news_new: Ð¨Ð¸Ð½Ñ Ð¼ÑÐ´ÑÑ
+  label_news_plural: ÐœÑÐ´ÑÑ
+  label_news_latest: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ò¯ÐµÐ¸Ð¹Ð½ Ð¼ÑÐ´ÑÑÐ½Ò¯Ò¯Ð´
+  label_news_view_all: Ð‘Ò¯Ñ… Ð¼ÑÐ´ÑÑÐ³ Ñ…Ð°Ñ€Ð°Ñ…
+  label_news_added: ÐœÑÐ´ÑÑ Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
+  label_settings: Ð¢Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾
+  label_overview: Ð­Ñ…Ð»ÑÐ»
+  label_version: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
+  label_version_new: Ð¨Ð¸Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
+  label_version_plural: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
+  label_close_versions: Ð“Ò¯Ð¹Ñ†ÑÑ‚ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ð°Ð»Ð°Ð°
+  label_confirmation: Ð‘Ð°Ñ‚Ð°Ð»Ð³Ð°Ð°Ð¶ÑƒÑƒÐ»Ð°Ñ…
+  label_export_to: 'Ó¨Ó©Ñ€ Ð°Ð²Ñ‡ Ð±Ð¾Ð»Ð¾Ñ… Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚:'
+  label_read: Ð£Ð½ÑˆÐ¸Ñ…...
+  label_public_projects: ÐžÐ»Ð¾Ð½ Ð½Ð¸Ð¹Ñ‚Ð¸Ð¹Ð½ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´
+  label_open_issues: Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
+  label_open_issues_plural: Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
+  label_closed_issues: Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
+  label_closed_issues_plural: Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
+  label_x_open_issues_abbr_on_total:
+    zero:  0 Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹ / %{total}
+    one:   1 Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹ / %{total}
+    other: "%{count} Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹ / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
+    one:   1 Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
+    other: "%{count} Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹"
+  label_x_closed_issues_abbr:
+    zero:  0 Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
+    one:   1 Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
+    other: "%{count} Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹"
+  label_total: ÐÐ¸Ð¹Ñ‚
+  label_permissions: Ð—Ó©Ð²ÑˆÓ©Ó©Ñ€Ð»Ò¯Ò¯Ð´
+  label_current_status: ÐžÐ´Ð¾Ð¾Ð³Ð¸Ð¹Ð½ Ñ‚Ó©Ð»Ó©Ð²
+  label_new_statuses_allowed: Ð¨Ð¸Ð½ÑÑÑ€ Ð¾Ð»Ð³Ð¾Ð¶ Ð±Ð¾Ð»Ð¾Ñ… Ñ‚Ó©Ð»Ð²Ò¯Ò¯Ð´
+  label_all: Ð±Ò¯Ð³Ð´
+  label_none: Ñ…Ð¾Ð¾ÑÐ¾Ð½
+  label_nobody: Ñ…ÑÐ½ Ñ‡ Ð±Ð¸Ñˆ
+  label_next: Ð”Ð°Ñ€Ð°Ð°Ð³Ð¸Ð¹Ð½
+  label_previous: Ó¨Ð¼Ð½Ó©Ñ…
+  label_used_by: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ð´Ð´ÑÐ³
+  label_details: Ð”ÑÐ»Ð³ÑÑ€ÑÐ½Ð³Ò¯Ð¹
+  label_add_note: Ð¢ÑÐ¼Ð´ÑÐ³Ð»ÑÐ» Ð½ÑÐ¼ÑÑ…
+  label_per_page: ÐÑÐ³ Ñ…ÑƒÑƒÐ´ÑÐ°Ð½Ð´
+  label_calendar: ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€ÑŒ
+  label_months_from: Ð¡Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ð°Ð½Ð°Ð°Ñ
+  label_gantt: Ð“Ð°Ð½Ñ‚ Ð´Ð¸Ð°Ð³Ñ€Ð°Ð¼
+  label_internal: Ð”Ð¾Ñ‚Ð¾Ð¾Ð´
+  label_last_changes: "ÑÒ¯Ò¯Ð»Ð¸Ð¹Ð½ %{count} Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´"
+  label_change_view_all: Ð‘Ò¯Ñ… Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  label_personalize_page: Ð­Ð½Ñ Ñ…ÑƒÑƒÐ´ÑÑ‹Ð³ Ó©Ó©Ñ€Ñ‚ Ð·Ð¾Ñ€Ð¸ÑƒÐ»Ð°Ð½ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…
+  label_comment: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€
+  label_comment_plural: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
+  label_x_comments:
+    zero: ÑÑÑ‚Ð³ÑÐ³Ð´ÑÐ» Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹
+    one: 1 ÑÑÑ‚Ð³ÑÐ³Ð´ÑÐ»Ñ‚ÑÐ¹
+    other: "%{count} ÑÑÑ‚Ð³ÑÐ³Ð´ÑÐ»Ñ‚ÑÐ¹"
+  label_comment_add: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ Ð½ÑÐ¼ÑÑ…
+  label_comment_added: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
+  label_comment_delete: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´ ÑƒÑÑ‚Ð³Ð°Ñ…
+  label_query: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ»Ñ‚
+  label_query_plural: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ»Ñ‚ÑƒÑƒÐ´
+  label_query_new: Ð¨Ð¸Ð½ÑÑÑ€ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ»Ñ‚ Ò¯Ò¯ÑÐ³ÑÑ…
+  label_filter_add: Ð¨Ò¯Ò¯Ð»Ñ‚Ò¯Ò¯Ñ€ Ð½ÑÐ¼ÑÑ…
+  label_filter_plural: Ð¨Ò¯Ò¯Ð»Ñ‚Ò¯Ò¯Ñ€Ò¯Ò¯Ð´
+  label_equals: Ð±Ð¾Ð»
+  label_not_equals: Ð±Ð¸Ñˆ
+  label_in_less_than: Ð°Ð°Ñ Ð±Ð°Ð³Ð°
+  label_in_more_than: Ð°Ð°Ñ Ð¸Ñ…
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: Ð´Ð¾Ñ‚Ð¾Ñ€
+  label_today: Ó©Ð½Ó©Ó©Ð´Ó©Ñ€
+  label_all_time: Ð±Ò¯Ñ… Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°
+  label_yesterday: Ó©Ñ‡Ð¸Ð³Ð´Ó©Ñ€
+  label_this_week: ÑÐ½Ñ Ð´Ð¾Ð»Ð¾Ð¾ Ñ…Ð¾Ð½Ð¾Ð³
+  label_last_week: Ó©Ð½Ð³Ó©Ñ€ÑÓ©Ð½ Ð´Ð¾Ð»Ð¾Ð¾ Ñ…Ð¾Ð½Ð¾Ð³
+  label_last_n_days: "ÑÒ¯Ò¯Ð»Ð¸Ð¹Ð½ %{count} Ó©Ð´Ñ€Ò¯Ò¯Ð´"
+  label_this_month: ÑÐ½Ñ ÑÐ°Ñ€
+  label_last_month: ÑÒ¯Ò¯Ð»Ð¸Ð¹Ð½ ÑÐ°Ñ€
+  label_this_year: ÑÐ½Ñ Ð¶Ð¸Ð»
+  label_date_range: Ð¥ÑÐ·Ð³Ð°Ð°Ñ€ Ð¾Ð³Ð½Ð¾Ð¾
+  label_less_than_ago: Ð±Ð°Ð³Ð° Ó©Ð´Ñ€Ð¸Ð¹Ð½ Ð´Ð¾Ñ‚Ð¾Ñ€
+  label_more_than_ago: Ð¸Ñ… Ó©Ð´Ñ€Ð¸Ð¹Ð½ Ð´Ð¾Ñ‚Ð¾Ñ€
+  label_ago: Ó©Ð´Ñ€Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó©
+  label_contains: Ð°Ð³ÑƒÑƒÐ»Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð°
+  label_not_contains: Ð°Ð³ÑƒÑƒÐ»Ð°Ð°Ð³Ò¯Ð¹
+  label_day_plural: Ó©Ð´Ñ€Ò¯Ò¯Ð´
+  label_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸
+  label_repository_plural: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€ÑƒÑƒÐ´
+  label_browse: Ò®Ð·ÑÑ…
+  label_branch: Ð¡Ð°Ð»Ð±Ð°Ñ€
+  label_tag: Ð¨Ð¾ÑˆÐ³Ð¾
+  label_revision: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
+  label_revision_plural: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
+  label_revision_id: "%{value} Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€"
+  label_associated_revisions: Ð¥Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
+  label_added: Ð½ÑÐ¼ÑÐ³Ð´ÑÑÐ½
+  label_modified: Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð³Ð´ÑÓ©Ð½
+  label_copied: Ñ…ÑƒÑƒÐ»ÑÐ°Ð½
+  label_renamed: Ð½ÑÑ€Ð¸Ð¹Ð³ Ð½ÑŒ Ó©Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½
+  label_deleted: ÑƒÑÑ‚Ð³Ð°ÑÐ°Ð½
+  label_latest_revision: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ò¯ÐµÐ¸Ð¹Ð½ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
+  label_latest_revision_plural: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ò¯ÐµÐ¸Ð¹Ð½ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´
+  label_view_revisions: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  label_view_all_revisions: Ð‘Ò¯Ñ… Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  label_max_size: Maximum size
+  label_sort_highest: Ð¥Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð´ÑÑÑ€
+  label_sort_higher: Ð”ÑÑÑˆ Ð½ÑŒ
+  label_sort_lower: Ð”Ð¾Ð¾Ñˆ Ð½ÑŒ
+  label_sort_lowest: Ð¥Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð´Ð¾Ð¾Ñ€
+  label_roadmap: Ð¥Ó©Ñ‚Ó©Ñ‡
+  label_roadmap_due_in: "%{value} Ð´Ð¾Ñ‚Ð¾Ñ€ Ð´ÑƒÑƒÑÐ³Ð°Ñ…"
+  label_roadmap_overdue: "%{value} Ð¾Ñ€Ð¾Ð¹Ñ‚ÑÐ¾Ð½"
+  label_roadmap_no_issues: Ð­Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ñ‚ Ð°ÑÑƒÑƒÐ´Ð°Ð» Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°
+  label_search: Ð¥Ð°Ð¹Ñ…
+  label_result_plural: Ò®Ñ€ Ð´Ò¯Ð½
+  label_all_words: Ð‘Ò¯Ñ… Ò¯Ð³Ñ
+  label_wiki: Ð’Ð¸ÐºÐ¸
+  label_wiki_edit: Ð’Ð¸ÐºÐ¸ Ð·Ð°ÑÐ²Ð°Ñ€
+  label_wiki_edit_plural: Ð’Ð¸ÐºÐ¸ Ð·Ð°ÑÐ²Ð°Ñ€ÑƒÑƒÐ´
+  label_wiki_page: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´Ð°Ñ
+  label_wiki_page_plural: Ð’Ð¸ÐºÐ¸ Ñ…ÑƒÑƒÐ´Ð°Ñ
+  label_index_by_title: Ð“Ð°Ñ€Ñ‡Ð³Ð°Ð°Ñ€ ÑÑ€ÑÐ¼Ð±ÑÐ»ÑÑ…
+  label_index_by_date: ÐžÐ³Ð½Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ ÑÑ€ÑÐ¼Ð±ÑÐ»ÑÑ…
+  label_current_version: ÐžÐ´Ð¾Ð¾Ð³Ð¸Ð¹Ð½ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
+  label_preview: Ð¯Ð¼Ð°Ñ€ Ñ…Ð°Ñ€Ð°Ð³Ð´Ð°Ñ…Ñ‹Ð³ ÑˆÐ°Ð»Ð³Ð°Ñ…
+  label_feed_plural: Feeds
+  label_changes_details: Ð‘Ò¯Ñ… Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ð´ÑÐ»Ð³ÑÑ€ÑÐ½Ð³Ò¯Ð¹
+  label_issue_tracking: ÐÑÑƒÑƒÐ´Ð°Ð» Ñ…ÑÐ½Ð°Ñ…
+  label_spent_time: Ð—Ð°Ñ€Ñ†ÑƒÑƒÐ»ÑÐ°Ð½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°
+  label_f_hour: "%{value} Ñ†Ð°Ð³"
+  label_f_hour_plural: "%{value} Ñ†Ð°Ð³"
+  label_time_tracking: Ð¥ÑƒÐ³Ð°Ñ†Ð°Ð°Ð³ Ñ…ÑÐ½Ð°Ñ…
+  label_change_plural: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´
+  label_statistics: Ð¡Ñ‚Ð°Ñ‚Ð¸ÑÑ‚Ð¸Ðº
+  label_commits_per_month: Ð¡Ð°Ñ€Ð´ Ñ…Ð¸Ð¹ÑÑÐ½ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ñ‹Ð½ Ñ‚Ð¾Ð¾
+  label_commits_per_author: Ð—Ð¾Ñ…Ð¸Ð¾Ð³Ñ‡ Ð±Ò¯Ñ€Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ñ‹Ð½ Ñ‚Ð¾Ð¾
+  label_view_diff: Ð¯Ð»Ð³Ð°Ð°Ð½ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
+  label_diff_inline: Ð´Ð¾Ñ‚Ð¾Ñ€ Ð½ÑŒ
+  label_diff_side_by_side: Ð·ÑÑ€ÑÐ³Ñ†Ò¯Ò¯Ð»Ð¶
+  label_options: Ð¢Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾
+  label_copy_workflow_from: ÐÐ¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ñ‹Ð³ Ñ…ÑƒÑƒÐ»Ð°Ñ…
+  label_permissions_report: Ð—Ó©Ð²ÑˆÓ©Ó©Ñ€Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ‚Ð°Ð±Ð»Ð¸Ñ†
+  label_watched_issues: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ð´Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
+  label_related_issues: Ð¥Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
+  label_applied_status: ÐžÐ»Ð³Ð¾ÑÐ¾Ð½ Ñ‚Ó©Ð»Ó©Ð²
+  label_loading: ÐÑ‡Ð°Ð°Ð»Ð¶ Ð±Ð°Ð¹Ð½Ð°...
+  label_relation_new: Ð¨Ð¸Ð½Ñ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»
+  label_relation_delete: Ð¥Ð°Ð¼Ð°Ð°Ñ€Ð»Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
+  label_relates_to: ÑÐ½Ð³Ð¸Ð¹Ð½ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
+  label_duplicates: Ñ…Ð¾Ñ Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
+  label_duplicated_by: Ð´Ð°Ð²Ñ…Ð°Ñ€Ð´ÑƒÑƒÐ»ÑÐ°Ð½ ÑÐ·ÑÐ½
+  label_blocks: ÑˆÐ°Ð°Ñ€Ð´Ð°Ñ… Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
+  label_blocked_by: Ð±Ð»Ð¾ÐºÐ¾Ð»ÑÐ¾Ð½ ÑÐ·ÑÐ½
+  label_precedes: ÑƒÑ€ÑŒÐ´Ñ‡Ð¸Ð»Ð°Ñ… Ñ…Ð°Ð¼Ð°Ð°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
+  label_follows: Ð´Ð°Ð³Ð°Ð¶
+  label_end_to_start: Ñ…Ð¾Ð¹Ð½Ð¾Ð¾Ñ Ð½ÑŒ ÑƒÑ€Ð°Ð³ÑˆÐ°Ð°
+  label_end_to_end: Ñ…Ð¾Ð¹Ð½Ð¾Ð¾Ñ Ð½ÑŒ Ñ…Ð¾Ð¹ÑˆÐ¾Ð¾
+  label_start_to_start: ÑƒÑ€Ð´Ð°Ð°Ñ Ð½ÑŒ ÑƒÑ€Ð°Ð³Ð°Ð°
+  label_start_to_end: ÑƒÑ€Ð´Ð°Ð°Ñ Ð½ÑŒ Ñ…Ð¾Ð¹ÑˆÐ¾Ð¾
+  label_stay_logged_in: Ð­Ð½Ñ ÐºÐ¾Ð¼ÑŒÑŽÑ‚ÐµÑ€ Ð´ÑÑÑ€ ÑÐ°Ð½Ð°Ñ…
+  label_disabled: Ð¸Ð´ÑÐ²Ñ…Ð³Ò¯Ð¹ Ð±Ð¾Ð»ÑÐ¾Ð½
+  label_show_completed_versions: Ð“Ò¯Ð¹Ñ†ÑÐ´ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ…
+  label_me: Ð±Ð¸
+  label_board: Ð¤Ð¾Ñ€ÑƒÐ¼
+  label_board_new: Ð¨Ð¸Ð½Ñ Ñ„Ð¾Ñ€ÑƒÐ¼
+  label_board_plural: Ð¤Ð¾Ñ€ÑƒÐ¼ÑƒÑƒÐ´
+  label_board_locked: Ð¢Ò¯Ð³Ð¶ÑÑÑ‚ÑÐ¹
+  label_board_sticky: Sticky
+  label_topic_plural: Ð¡ÑÐ´Ð²Ò¯Ò¯Ð´
+  label_message_plural: Ð—ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´
+  label_message_last: Ð¡Ò¯Ò¯Ð»Ð¸Ð¹Ð½ Ð·ÑƒÑ€Ð²Ð°Ñ
+  label_message_new: Ð¨Ð¸Ð½Ñ Ð·ÑƒÑ€Ð²Ð°Ñ
+  label_message_posted: Ð—ÑƒÑ€Ð²Ð°Ñ Ð½ÑÐ¼ÑÐ³Ð´Ð»ÑÑ
+  label_reply_plural: Ð¥Ð°Ñ€Ð¸ÑƒÐ»Ñ‚ÑƒÑƒÐ´
+  label_send_information: Ð”Ð°Ð½ÑÐ½Ñ‹ Ð¼ÑÐ´ÑÑÐ»Ð»Ð¸Ð¹Ð³ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð´ Ð¸Ð»Ð³ÑÑÑ…
+  label_year: Ð–Ð¸Ð»
+  label_month: Ð¡Ð°Ñ€
+  label_week: Ð”Ð¾Ð»Ð¾Ð¾ Ñ…Ð¾Ð½Ð¾Ð³
+  label_date_from: Ð¥ÑÐ·ÑÑÐ½ÑÑÑ
+  label_date_to: Ð¥ÑÐ´Ð¸Ð¹ Ñ…Ò¯Ñ€Ñ‚ÑÐ»
+  label_language_based: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ñ…ÑÐ»Ð½Ð°Ñ ÑˆÐ°Ð»Ñ‚Ð³Ð°Ð°Ð»Ð°Ð½
+  label_sort_by: "%{value} Ñ‚Ð°Ð»Ð±Ð°Ñ€Ð°Ð°Ñ€ Ð½ÑŒ ÑÑ€ÑÐ¼Ð±ÑÐ»ÑÑ…"
+  label_send_test_email: Ð¢ÑƒÑ€ÑˆÐ¸Ñ… Ð¼ÑÐ¹Ð» Ð¸Ð»Ð³ÑÑÑ…
+  label_feeds_access_key: RSS Ñ…Ð°Ð½Ð´Ð°Ñ… Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€
+  label_missing_feeds_access_key: RSS Ñ…Ð°Ð½Ð´Ð°Ñ… Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ Ð°Ð»Ð³Ð°
+  label_feeds_access_key_created_on: "RSS Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ Ñ‚Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ %{value}-Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó© Ò¯Ò¯ÑÑÑÐ½"
+  label_module_plural: ÐœÐ¾Ð´ÑƒÐ»ÑƒÑƒÐ´
+  label_added_time_by: "%{author} %{age}-Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó© Ð½ÑÐ¼ÑÑÐ½"
+  label_updated_time_by: "%{author} %{age}-Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó© Ó©Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½"
+  label_updated_time: "%{value} -Ð¸Ð¹Ð½ Ó©Ð¼Ð½Ó© Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð³Ð´ÑÓ©Ð½"
+  label_jump_to_a_project: Ð¢Ó©ÑÓ©Ð» Ñ€Ò¯Ò¯ Ð¾Ñ‡Ð¸Ñ…...
+  label_file_plural: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´
+  label_changeset_plural: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´
+  label_default_columns: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ð±Ð°Ð³Ð°Ð½ÑƒÑƒÐ´
+  label_no_change_option: (Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚ Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹)
+  label_bulk_edit_selected_issues: Ð¡Ð¾Ð½Ð³Ð¾Ð³Ð´ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ð±Ó©Ó©Ð½Ó©Ó©Ñ€ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  label_theme: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð¸Ð¹Ð½ Ð”Ð¸Ð·Ð°Ð¹Ð½
+  label_default: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚
+  label_search_titles_only: Ð—Ó©Ð²Ñ…Ó©Ð½ Ð³Ð°Ñ€Ñ‡Ð¸Ð³ Ñ…Ð°Ð¹Ñ…
+  label_user_mail_option_all: "ÐœÐ¸Ð½Ð¸Ð¹ Ð±Ò¯Ñ… Ñ‚Ó©ÑÓ©Ð» Ð´ÑÑÑ€Ñ… Ð±Ò¯Ñ… Ò¯Ð·ÑÐ³Ð´Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´"
+  label_user_mail_option_selected: "Ð¡Ð¾Ð½Ð³Ð¾Ð³Ð´ÑÐ¾Ð½ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´ Ð±Ò¯Ñ… Ò¯Ð·ÑÐ³Ð´ÑÐ» Ð´ÑÑÑ€..."
+  label_user_mail_no_self_notified: "ÐœÐ¸Ð½Ð¸Ð¹ Ó©Ó©Ñ€Ð¸Ð¹Ð½ Ñ…Ð¸Ð¹ÑÑÐ½ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ‚ÑƒÑ…Ð°Ð¹ Ð½Ð°Ð´Ð°Ð´ Ð¼ÑÐ´ÑÐ³Ð´ÑÑ… Ñ…ÑÑ€ÑÐ³Ð³Ò¯Ð¹"
+  label_registration_activation_by_email: Ð´Ð°Ð½ÑÑ‹Ð³ Ð¸Ð¼ÑÐ¹Ð»ÑÑÑ€ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
+  label_registration_manual_activation: Ð´Ð°Ð½ÑÑ‹Ð³ Ð³Ð°Ñ€Ð°Ð°Ñ€ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
+  label_registration_automatic_activation: Ð´Ð°Ð½ÑÑ‹Ð³ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð°Ð°Ñ€ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
+  label_display_per_page: 'ÐÑÐ³ Ñ…ÑƒÑƒÐ´ÑÐ°Ð½Ð´: %{value}'
+  label_age: ÐÐ°Ñ
+  label_change_properties: Ð¢Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾Ð³ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…
+  label_general: Ð•Ñ€Ó©Ð½Ñ…Ð¸Ð¹
+  label_more: Ð¦Ð°Ð°Ñˆ Ð½ÑŒ
+  label_scm: SCM
+  label_plugins: ÐœÐ¾Ð´ÑƒÐ»ÑƒÑƒÐ´
+  label_ldap_authentication: LDAP Ð½ÑÐ²Ñ‚Ñ€ÑÑ… Ð³Ð¾Ñ€Ð¸Ð¼
+  label_downloads_abbr: D/L
+  label_optional_description: Ð”ÑƒÑ€Ñ‹Ð½ Ñ‚Ð°Ð¹Ð»Ð±Ð°Ñ€
+  label_add_another_file: Ð”Ð°Ñ…Ð¸Ð½ Ñ„Ð°Ð¹Ð» Ð½ÑÐ¼ÑÑ…
+  label_preferences: Ð¢Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾
+  label_chronological_order: Ð¦Ð°Ð³Ð°Ð°Ð½ Ñ‚Ð¾Ð»Ð³Ð¾Ð¹Ð½ Ò¯ÑÐ³Ð¸Ð¹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ð°Ð°Ñ€
+  label_reverse_chronological_order: Ð£Ñ€Ð²ÑƒÑƒ Ñ†Ð°Ð³Ð°Ð°Ð½ Ñ‚Ð¾Ð»Ð³Ð¾Ð¹Ð½ Ò¯ÑÐ³Ð¸Ð¹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ð°Ð°Ñ€
+  label_planning: Ð¢Ó©Ð»Ó©Ð²Ð»Ó©Ð»Ñ‚
+  label_incoming_emails: Ð˜Ñ€ÑÑÐ½ Ð¼ÑÐ¹Ð»Ò¯Ò¯Ð´
+  label_generate_key: Ð¢Ò¯Ð»Ñ…Ò¯Ò¯Ñ€ Ò¯Ò¯ÑÐ³ÑÑ…
+  label_issue_watchers: ÐÐ¶Ð¸Ð³Ð»Ð°Ð³Ñ‡Ð¸Ð´
+  label_example: Ð–Ð¸ÑˆÑÑ
+  label_display: Display
+  label_sort: Sort
+  label_ascending: Ascending
+  label_descending: Descending
+  label_date_from_to: From %{start} to %{end}
+  label_wiki_content_added: Wiki page added
+  label_wiki_content_updated: Wiki page updated
+  label_group: Group
+  label_group_plural: Groups
+  label_group_new: New group
+  label_time_entry_plural: Spent time
+  label_version_sharing_none: Not shared
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_tree: With project tree
+  label_version_sharing_system: With all projects
+  label_update_issue_done_ratios: Update issue done ratios
+  label_copy_source: Source
+  label_copy_target: Target
+  label_copy_same_as_target: Same as target
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_api_access_key: API access key
+  label_missing_api_access_key: Missing an API access key
+  label_api_access_key_created_on: "API access key created %{value} ago"
+
+  button_login: ÐÑÐ²Ñ‚Ñ€ÑÑ…
+  button_submit: Ð˜Ð»Ð³ÑÑÑ…
+  button_save: Ð¥Ð°Ð´Ð³Ð°Ð»Ð°Ñ…
+  button_check_all: Ð‘Ò¯Ð³Ð´Ð¸Ð¹Ð³ ÑÐ¾Ð½Ð³Ð¾
+  button_uncheck_all: Ð‘Ò¯Ð³Ð´Ð¸Ð¹Ð³ Ò¯Ð» ÑÐ¾Ð½Ð³Ð¾
+  button_delete: Ð£ÑÑ‚Ð³Ð°Ñ…
+  button_create: Ò®Ò¯ÑÐ³ÑÑ…
+  button_create_and_continue: Ò®Ò¯ÑÐ³ÑÑÐ´ Ñ†Ð°Ð°Ñˆ Ò¯Ñ€Ð³ÑÐ»Ð¶Ð»Ò¯Ò¯Ð»ÑÑ…
+  button_test: Ð¢ÑƒÑ€ÑˆÐ¸Ñ…
+  button_edit: Ð—Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
+  button_add: ÐÑÐ¼ÑÑ…
+  button_change: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ñ…
+  button_apply: Ó¨Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ð¸Ð¹Ð³ Ñ…Ð°Ð´Ð³Ð°Ð»Ð°Ñ…
+  button_clear: Ð¦ÑÐ²ÑÑ€Ð»ÑÑ…
+  button_lock: Ð¢Ò¯Ð³Ð¶Ð¸Ñ…
+  button_unlock: Ð¢Ò¯Ð³Ð¶ÑÑÐ³ Ñ‚Ð°Ð¹Ð»Ð°Ñ…
+  button_download: Ð¢Ð°Ñ‚Ð°Ñ…
+  button_list: Ð–Ð°Ð³ÑÐ°Ð°Ð»Ñ‚
+  button_view: Ð¥Ð°Ñ€Ð°Ñ…
+  button_move: Ð—Ó©Ó©Ñ…
+  button_move_and_follow: Ð—Ó©Ó© Ð±Ð°Ñ Ð´Ð°Ð³Ð°
+  button_back: Ð‘ÑƒÑ†Ð°Ñ…
+  button_cancel: Ð‘Ð¾Ð»Ð¸Ñ…
+  button_activate: Ð˜Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ…
+  button_sort: Ð­Ñ€ÑÐ¼Ð±ÑÐ»ÑÑ…
+  button_log_time: Ð›Ð¾Ð³ Ñ…Ð¸Ð¹ÑÑÐ½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°
+  button_rollback: Ð­Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ Ñ€ÑƒÑƒ Ð±ÑƒÑ†Ð°Ñ…
+  button_watch: ÐÐ¶Ð¸Ð³Ð»Ð°Ñ…
+  button_unwatch: ÐÐ¶Ð¸Ð³Ð»Ð°Ñ…Ð°Ð° Ð±Ð¾Ð»Ð¸Ñ…
+  button_reply: Ð¥Ð°Ñ€Ð¸ÑƒÐ»Ð°Ñ…
+  button_archive: ÐÑ€Ñ…Ð¸Ð²Ð»Ð°Ñ…
+  button_unarchive: ÐÑ€Ñ…Ð¸Ð²Ñ‹Ð³ Ð·Ð°Ð´Ð»Ð°Ñ…
+  button_reset: ÐÐ½Ñ…Ð½Ñ‹ ÑƒÑ‚Ð³ÑƒÑƒÐ´
+  button_rename: ÐÑÑ€Ð¸Ð¹Ð³ Ð½ÑŒ ÑÐ¾Ð»Ð¸Ñ…
+  button_change_password: ÐÑƒÑƒÑ† Ò¯Ð³ÑÑ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…
+  button_copy: Ð¥ÑƒÑƒÐ»Ð°Ñ…
+  button_copy_and_follow: Ð—Ó©Ó© Ð±Ð°Ñ Ð´Ð°Ð³Ð°
+  button_annotate: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€ Ñ…Ð°Ð²ÑÐ°Ñ€Ð³Ð°Ñ…
+  button_update: Ð¨Ð¸Ð½ÑÑ‡Ð»ÑÑ…
+  button_configure: Ð¢Ð¾Ñ…Ð¸Ñ€ÑƒÑƒÐ»Ð°Ñ…
+  button_quote: Ð˜ÑˆÐ»ÑÐ»
+  button_duplicate: Ð¥ÑƒÑƒÐ»Ð±Ð°Ñ€
+  button_show: Ò®Ð·ÑÑ…
+
+  status_active: Ð¸Ð´ÑÐ²Ñ…Ñ‚ÑÐ¹
+  status_registered: Ð±Ò¯Ñ€Ñ‚Ð³Ò¯Ò¯Ð»ÑÑÐ½
+  status_locked: Ñ‚Ò¯Ð³Ð¶ÑÑÑ‚ÑÐ¹
+
+  version_status_open: Ð½ÑÑÐ»Ñ‚Ñ‚ÑÐ¹
+  version_status_locked: Ñ‚Ò¯Ð³Ð¶ÑÑÑ‚ÑÐ¹
+  version_status_closed: Ñ…Ð°Ð°Ð»Ñ‚Ñ‚Ð°Ð¹
+
+  field_active: Ð¸Ð´ÑÐ²Ñ…Ñ‚ÑÐ¹
+
+  text_select_mail_notifications: Ð¯Ð¼Ð°Ñ€ Ò¯ÐµÐ´ Ð¸Ð¼ÑÐ¹Ð»ÑÑÑ€ Ð¼ÑÐ´ÑÐ³Ð´ÑÐ» Ð¸Ð»Ð³ÑÑÑ…Ð¸Ð¹Ð³ ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 Ð³ÑÐ²ÑÐ» ÑÐ¼Ð°Ñ€ Ñ‡ Ñ…ÑÐ·Ð³Ð°Ð°Ñ€Ð³Ò¯Ð¹ Ð³ÑÑÑÐ½ Ò¯Ð³
+  text_project_destroy_confirmation: Ð¢Ð° ÑÐ½Ñ Ñ‚Ó©ÑÓ©Ð» Ð±Ð¾Ð»Ð¾Ð¾Ð´ Ð±ÑƒÑÐ°Ð´ Ð¼ÑÐ´ÑÑÐ»Ð»Ð¸Ð¹Ð³ Ð½ÑŒ Ò¯Ð½ÑÑ…ÑÑÑ€ ÑƒÑÑ‚Ð³Ð°Ð¼Ð°Ð°Ñ€ Ð±Ð°Ð¹Ð½Ð° ÑƒÑƒ ?
+  text_subprojects_destroy_warning: "Ð£Ð³ Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ð´ÑÐ´ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´ : %{value} Ð½ÑŒ Ð±Ð°Ñ ÑƒÑÑ‚Ð³Ð°Ð³Ð´Ð°Ñ… Ð±Ð¾Ð»Ð½Ð¾."
+  text_workflow_edit: ÐÐ¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ñ‹Ð³ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…Ð¸Ð¹Ð½ Ñ‚ÑƒÐ»Ð´ Ñ…Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ… Ð±Ð¾Ð»Ð¾Ð½ Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‡Ð¸Ð³Ð»ÑÐ»Ð¸Ð¹Ð³ ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ
+  text_are_you_sure: Ð¢Ð° Ð¸Ñ‚Ð³ÑÐ»Ñ‚ÑÐ¹ Ð±Ð°Ð¹Ð½Ð° ÑƒÑƒ ?
+  text_journal_changed: "%{label} %{old} Ð±Ð°Ð¹ÑÐ°Ð½ Ð½ÑŒ %{new} Ð±Ð¾Ð»Ð¾Ð²"
+  text_journal_set_to: "%{label} %{value} Ð±Ð¾Ð»Ð³Ð¾Ð¶ Ó©Ó©Ñ€Ñ‡Ð¸Ð»Ð»Ó©Ó©"
+  text_journal_deleted: "%{label} ÑƒÑÑ‚ÑÐ°Ð½ (%{old})"
+  text_journal_added: "%{label} %{value} Ð½ÑÐ¼ÑÐ³Ð´ÑÑÐ½"
+  text_tip_issue_begin_day: ÑÐ½Ñ Ó©Ð´Ó©Ñ€ ÑÑ…Ð»ÑÑ… Ð°Ð¶Ð¸Ð»
+  text_tip_issue_end_day: ÑÐ½Ñ Ó©Ð´Ó©Ñ€ Ð´ÑƒÑƒÑÐ°Ñ… Ð°Ð¶Ð¸Ð»
+  text_tip_issue_begin_end_day: ÑÐ½Ñ Ó©Ð´Ó©Ñ€ ÑÑ…Ð»ÑÑÐ´ Ð¼Ó©Ð½ Ð´ÑƒÑƒÑÑ‡ Ð±Ð°Ð¹Ð³Ð°Ð° Ð°Ð¶Ð¸Ð»
+  text_caracters_maximum: "Ð´ÑÑÐ´ Ñ‚Ð°Ð» Ð½ÑŒ %{count} Ò¯ÑÑÐ³."
+  text_caracters_minimum: "Ð¥Ð°Ð¼Ð³Ð¸Ð¹Ð½ Ð±Ð°Ð³Ð°Ð´Ð°Ð° ÑÐ´Ð°Ð¶ %{count} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚ Ð±Ð°Ð¹Ñ…."
+  text_length_between: "Ð£Ñ€Ñ‚ Ð½ÑŒ Ð±Ð°Ð³Ð°Ð´Ð°Ð° %{min}, Ð¸Ñ…Ð´ÑÑ %{max} Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚."
+  text_tracker_no_workflow: Ð­Ð½ÑÑ…Ò¯Ò¯ Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‡Ð¸Ð³Ð»ÑÐ»Ð´ ÑÐ¼Ð°Ñ€ Ñ‡ Ð°Ð¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð°Ð» Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»Ð¾Ð³Ð´Ð¾Ð¾Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°
+  text_unallowed_characters: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ¶ Ð±Ð¾Ð»Ð¾Ñ…Ð³Ò¯Ð¹ Ñ‚ÑÐ¼Ð´ÑÐ³Ñ‚Ò¯Ò¯Ð´
+  text_comma_separated: Ð¢Ð°ÑÐ»Ð°Ð»Ð°Ð°Ñ€ Ð·Ð°Ð°Ð³Ð»Ð°Ð½ Ð¾Ð»Ð¾Ð½ ÑƒÑ‚Ð³Ð° Ð¾Ñ€ÑƒÑƒÐ»Ð¶ Ð±Ð¾Ð»Ð½Ð¾.
+  text_line_separated: Multiple values allowed (one line for each value).
+  text_issues_ref_in_commit_messages: ÐšÐ¾Ð¼Ð¼Ð¸Ñ‚Ð¸Ð¹Ð½ Ð·ÑƒÑ€Ð²Ð°ÑÑƒÑƒÐ´Ð°Ð´ Ñ…Ð°Ð¼Ð°Ð°Ñ€ÑƒÑƒÐ»ÑÐ°Ð½ Ð±Ð¾Ð»Ð¾Ð½ Ð±Ð°Ð¹Ð½Ð³Ñ‹Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´
+  text_issue_added: "ÐÑÑƒÑƒÐ´Ð°Ð» %{id} - Ð¸Ð¹Ð³ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ %{author} Ð¼ÑÐ´ÑÐ³Ð´ÑÑÐ½ Ð±Ð°Ð¹Ð½Ð°."
+  text_issue_updated: "ÐÑÑƒÑƒÐ´Ð°Ð» %{id} - Ð¸Ð¹Ð³ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡ %{author} Ó©Ó©Ñ€Ñ‡Ð¸Ð»ÑÓ©Ð½ Ð±Ð°Ð¹Ð½Ð°."
+  text_wiki_destroy_confirmation: Ð¢Ð° ÑÐ½Ñ Ð²Ð¸ÐºÐ¸ Ð±Ð¾Ð»Ð¾Ð½ Ñ…Ð¾Ð»Ð±Ð¾Ð³Ð´Ð¾Ñ… Ð±Ò¯Ñ… Ð¼ÑÐ´ÑÑÐ»Ð»Ð¸Ð¹Ð³ Ò¯Ð½ÑÑ…ÑÑÑ€ ÑƒÑÑ‚Ð³Ð°Ð¼Ð°Ð°Ñ€ Ð±Ð°Ð¹Ð½Ð° ÑƒÑƒ ?
+  text_issue_category_destroy_question: "Ð­Ð½Ñ Ð°Ð½Ð³Ð¸Ð»Ð°Ð»Ð´ Ð·Ð°Ñ€Ð¸Ð¼ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´ (%{count})  Ð¾Ñ€ÑÐ¾Ð½ Ð±Ð°Ð¹Ð½Ð°. Ð¢Ð° ÑÐ°Ñ… Ð²Ñ ?"
+  text_issue_category_destroy_assignments: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑÐ½Ñ Ð°Ð½Ð³Ð¸Ð»Ð»Ð°Ð°Ñ Ð°Ð²Ð°Ñ…
+  text_issue_category_reassign_to: ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑÐ½Ñ Ð°Ð½Ð³Ð¸Ð»Ð°Ð»Ð´ Ð´Ð°Ñ…Ð¸Ð½ Ð¾Ð½Ð¾Ð¾Ñ…
+  text_user_mail_option: "Ð¡Ð¾Ð½Ð³Ð¾Ð³Ð´Ð¾Ð¾Ð³Ò¯Ð¹ Ñ‚Ó©ÑÐ»Ò¯Ò¯Ð´Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´, Ñ‚Ð° Ð·Ó©Ð²Ñ…Ó©Ð½ Ó©Ó©Ñ€Ð¸Ð¹Ð½Ñ…Ó©Ó© Ð°Ð¶Ð¸Ð³Ð»Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð·Ò¯Ð¹Ð»Ñ ÑŽÐ¼ÑƒÑƒ Ñ‚Ð°Ð½Ð´ Ñ…Ð°Ð¼Ð°Ð°Ñ‚Ð°Ð¹ Ð·Ò¯Ð¹Ð»ÑÐ¸Ð¹Ð½ Ñ‚Ð°Ð»Ð°Ð°Ñ€ Ð¼ÑÐ´ÑÐ³Ð´ÑÐ» Ð°Ð²Ð°Ñ… Ð±Ð¾Ð»Ð½Ð¾ (Ð¢Ð°Ð½Ñ‹ Ð¾Ñ€ÑƒÑƒÐ»ÑÐ°Ð½ Ð°ÑÑƒÑƒÐ´Ð°Ð», ÑÑÐ²ÑÐ» Ñ‚Ð°Ð½Ð´ Ð¾Ð½Ð¾Ð¾ÑÐ¾Ð½ Ð³ÑÑ… Ð¼ÑÑ‚)."
+  text_no_configuration_data: "Ð¥Ð°Ð½Ð´Ð°Ð»Ñ‚Ñ‹Ð½ ÑÑ€Ñ…Ò¯Ò¯Ð´, Ñ‡Ð¸Ð³Ð»ÑÐ»Ò¯Ò¯Ð´, Ð°ÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ñ‚Ó©Ð»Ð²Ò¯Ò¯Ð´ Ð±Ð¾Ð»Ð¾Ð½ Ð°Ð¶Ð»Ñ‹Ð½ Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ñ‹Ð½ Ñ‚ÑƒÑ…Ð°Ð¹ Ð¼ÑÐ´ÑÑÐ»Ð»Ð¸Ð¹Ð³ Ñ…Ð°Ñ€Ð°Ð°Ñ…Ð°Ð½ Ð¾Ñ€ÑƒÑƒÐ»Ð°Ð°Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°.\nÐ¢Ð° ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ó©Ð³Ó©Ð³Ð´Ð»Ò¯Ò¯Ð´Ð¸Ð¹Ð³ Ð´Ð°Ñ€ÑƒÐ¹Ñ…Ð°Ð½ Ð¾Ñ€ÑƒÑƒÐ»Ð°Ñ…Ñ‹Ð³ Ð·Ó©Ð²Ð»Ó©Ð¶ Ð±Ð°Ð¹Ð½Ð°, Ð¾Ñ€ÑƒÑƒÐ»ÑÐ°Ð½ Ñ…Ð¾Ð¹Ð½Ð¾ Ñ‚Ð° Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ð¶ Ð±Ð¾Ð»Ð½Ð¾."
+  text_load_default_configuration: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ó©Ð³Ó©Ð³Ð´Ð»Ð¸Ð¹Ð³ Ð°Ñ‡Ð°Ð°Ð»Ð°Ñ…
+  text_status_changed_by_changeset: "%{value} Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ó©Ð´ Ñ…Ð¸Ð¹Ð³Ð´ÑÑÐ½."
+  text_issues_destroy_confirmation: 'Ð¢Ð° ÑÐ¾Ð½Ð³Ð¾Ð³Ð´ÑÐ¾Ð½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ò¯Ð½ÑÑ…ÑÑÑ€ ÑƒÑÑ‚Ð³Ð°Ð¼Ð°Ð°Ñ€ Ð±Ð°Ð¹Ð½Ð° ÑƒÑƒ ?'
+  text_select_project_modules:  'Ð­Ð½Ñ Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ñ…ÑƒÐ²ÑŒÐ´ Ð¸Ð´ÑÐ²Ñ…Ð¶Ò¯Ò¯Ð»ÑÑ… Ð¼Ð¾Ð´ÑƒÐ»ÑƒÑƒÐ´Ð°Ð° ÑÐ¾Ð½Ð³Ð¾Ð½Ð¾ ÑƒÑƒ:'
+  text_default_administrator_account_changed: Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑ‚Ñ€Ð°Ñ‚Ð¾Ñ€Ñ‹Ð½ Ð±Ò¯Ñ€Ñ‚Ð³ÑÐ» Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð³Ð´Ð»Ó©Ó©
+  text_file_repository_writable: Ð¥Ð°Ð²ÑÑ€Ð°Ð»Ñ‚ Ñ„Ð°Ð¹Ð» Ñ…Ð°Ð´Ð³Ð°Ð»Ð°Ñ… Ñ…Ð°Ð²Ñ‚Ð°Ñ Ñ€ÑƒÑƒ Ð±Ð¸Ñ‡Ð¸Ñ… ÑÑ€Ñ…Ñ‚ÑÐ¹
+  text_plugin_assets_writable: ÐŸÐ»Ð°Ð³Ð¸Ð½ Ð¼Ð¾Ð´ÑƒÐ»Ð¸Ð¹Ð½ Ð°ÑÑÐµÑ‚ Ñ…Ð°Ð²Ñ‚Ð°Ñ Ñ€ÑƒÑƒ Ð±Ð¸Ñ‡Ð¸Ñ… ÑÑ€Ñ…Ñ‚ÑÐ¹
+  text_rmagick_available: RMagick ÑÑƒÑƒÐ»Ð³Ð°Ð³Ð´ÑÐ°Ð½ (Ð·Ð°Ð°Ð²Ð°Ð» Ð±Ð¸Ñˆ)
+  text_destroy_time_entries_question: "Ð¢Ð°Ð½Ñ‹ ÑƒÑÑ‚Ð³Ð°Ñ… Ð³ÑÐ¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´ Ð´ÑÑÑ€ Ð½Ð¸Ð¹Ñ‚ %{hours} Ñ†Ð°Ð³ Ð·Ð°Ñ€Ñ†ÑƒÑƒÐ»ÑÐ°Ð½ ÑŽÐ¼ Ð±Ð°Ð¹Ð½Ð°, Ñ‚Ð° ÑÐ°Ñ… Ð²Ñ ?"
+  text_destroy_time_entries: ÐœÑÐ´ÑÐ³Ð´ÑÑÐ½ Ñ†Ð°Ð³ÑƒÑƒÐ´Ñ‹Ð³ ÑƒÑÑ‚Ð³Ð°Ñ…
+  text_assign_time_entries_to_project: ÐœÑÐ´ÑÐ³Ð´ÑÑÐ½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ‚Ó©ÑÓ©Ð»Ð´ Ð¾Ð½Ð¾Ð¾Ñ…
+  text_reassign_time_entries: 'ÐœÑÐ´ÑÐ³Ð´ÑÑÐ½ Ð°ÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´Ñ‹Ð³ ÑÐ½Ñ Ð°ÑÑƒÑƒÐ´Ð°Ð»Ð´ Ð´Ð°Ñ…Ð¸Ð½ Ð¾Ð½Ð¾Ð¾:'
+  text_user_wrote: "%{value} Ð±Ð¸Ñ‡Ð¸Ñ…Ð´ÑÑ:"
+  text_enumeration_destroy_question: "Ð­Ð½Ñ ÑƒÑ‚Ð³Ð°Ð´ %{count} Ð¾Ð±ÑŒÐµÐºÑ‚ Ð¾Ð½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½ Ð±Ð°Ð¹Ð½Ð°."
+  text_enumeration_category_reassign_to: 'Ð¢ÑÐ´Ð³ÑÑÑ€Ð¸Ð¹Ð³ ÑÐ½Ñ ÑƒÑ‚Ð³Ð°Ð´ Ð´Ð°Ñ…Ð¸Ð½ Ð¾Ð½Ð¾Ð¾:'
+  text_email_delivery_not_configured: "Ð˜Ð¼ÑÐ¹Ð»Ð¸Ð¹Ð½ Ñ‚Ð¾Ñ…Ð¸Ñ€Ð³Ð¾Ð¾Ð³ Ñ…Ð°Ñ€Ð°Ð°Ñ…Ð°Ð½ Ñ‚Ð¾Ñ…Ð¸Ñ€ÑƒÑƒÐ»Ð°Ð°Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°, Ñ‚Ð¸Ð¹Ð¼ÑÑÑ Ð¸Ð¼ÑÐ¹Ð» Ð¼ÑÐ´ÑÐ³Ð´ÑÐ» ÑÐ²ÑƒÑƒÐ»Ð°Ñ… Ð±Ð¾Ð»Ð¾Ð¼Ð¶Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°.\nSMTP ÑÐµÑ€Ð²ÑÑ€ÑÑ config/configuration.yml Ñ„Ð°Ð¹Ð» Ð´Ð¾Ñ‚Ð¾Ñ€ Ñ‚Ð¾Ñ…Ð¸Ñ€ÑƒÑƒÐ»Ð°Ð°Ð´ Ñ‚Ó©ÑÐ»Ð¸Ð¹Ð½ Ð¼ÐµÐ½ÐµÐ¶ÐµÑ€ÑÑ Ð´Ð°Ñ…Ð¸Ð°Ð´ ÑÑ…Ð»Ò¯Ò¯Ð»ÑÑÑ€ÑÐ¹."
+  text_repository_usernames_mapping: "Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ð¹Ð½ Ð»Ð¾Ð³Ð´ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±Ò¯Ñ… Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ð½ÑÑ€Ò¯Ò¯Ð´ÑÐ´ Ñ…Ð°Ñ€Ð³Ð°Ð»Ð·ÑÐ°Ð½ Ð¢Ó©ÑÐ»Ð¸Ð¹Ð½ ÐœÐµÐ½ÐµÐ¶ÐµÑ€ ÑÐ¸ÑÑ‚ÐµÐ¼Ð´ Ð±Ò¯Ñ€Ñ‚Ð³ÑÐ»Ñ‚ÑÐ¹ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð´Ð¸Ð¹Ð³ Ð¡Ð¾Ð½Ð³Ð¾Ñ… ÑŽÐ¼ÑƒÑƒ ÑˆÐ¸Ð½ÑÑ‡Ð¸Ð»Ð½Ñ Ò¯Ò¯.\nÐ¢Ó©ÑÐ»Ð¸Ð¹Ð½ Ð¼ÐµÐ½ÐµÐ¶ÐµÑ€ Ð±Ð¾Ð»Ð¾Ð½ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ð´ Ð±Ð°Ð¹Ð³Ð°Ð° Ð¸Ð¶Ð¸Ð»Ñ…ÑÐ½ Ð½ÑÑ€ ÑŽÐ¼ÑƒÑƒ Ð¸Ð¼ÑÐ¹Ð»Ñ‚ÑÐ¹ Ñ…ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð´ Ñ…Ð°Ñ€Ð¸Ð»Ñ†Ð°Ð½ Ñ…Ð°Ñ€Ð³Ð°Ð»Ð·Ð½Ð°."
+  text_diff_truncated: '... Ð¤Ð°Ð¹Ð»Ñ‹Ð½ ÑÐ»Ð³Ð°Ð²Ñ€Ñ‹Ð½ Ñ…ÑÐ¼Ð¶ÑÑ Ò¯Ð·Ò¯Ò¯Ð»ÑÑ…ÑÐ´ Ð´ÑÐ½Ð´Ò¯Ò¯ ÑƒÑ€Ñ‚ Ð±Ð°Ð¹Ð³Ð°Ð° ÑƒÑ‡Ñ€Ð°Ð°Ñ Ñ‚Ó©Ð³ÑÐ³Ó©Ð»Ó©Ó©Ñ Ð½ÑŒ Ñ…Ð°ÑÑ‡ Ò¯Ð·Ò¯Ò¯Ð»ÑÐ².'
+  text_custom_field_possible_values_info: 'One line for each value'
+  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
+  text_wiki_page_nullify_children: "Keep child pages as root pages"
+  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
+  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
+  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
+
+  default_role_manager: ÐœÐµÐ½ÐµÐ¶ÐµÑ€
+  default_role_developer: Ð¥Ó©Ð³Ð¶Ò¯Ò¯Ð»ÑÐ³Ñ‡
+  default_role_reporter: ÐœÑÐ´ÑÐ³Ð´ÑÐ³Ñ‡
+  default_tracker_bug: ÐÐ»Ð´Ð°Ð°
+  default_tracker_feature: ÐžÐ½Ñ†Ð»Ð¾Ð³
+  default_tracker_support: Ð¢ÑƒÑÐ»Ð°Ð¼Ð¶
+  default_issue_status_new: Ð¨Ð¸Ð½Ñ
+  default_issue_status_in_progress: ÐÑ…Ð¸Ñ†Ñ‚Ð°Ð¹
+  default_issue_status_assigned: ÐžÐ½Ð¾Ð¾Ð³Ð´ÑÐ¾Ð½
+  default_issue_status_resolved: Ð¨Ð¸Ð¹Ð´Ð²ÑÑ€Ð»ÑÐ³Ð´ÑÑÐ½
+  default_issue_status_feedback: Feedback
+  default_issue_status_closed: Ð¥Ð°Ð°Ð³Ð´ÑÐ°Ð½
+  default_issue_status_rejected: Ð¥Ò¯Ð»ÑÑÐ¶ Ð°Ð²Ð°Ð°Ð³Ò¯Ð¹
+  default_doc_category_user: Ð¥ÑÑ€ÑÐ³Ð»ÑÐ³Ñ‡Ð¸Ð¹Ð½ Ð±Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚
+  default_doc_category_tech: Ð¢ÐµÑ…Ð½Ð¸ÐºÐ¸Ð¹Ð½ Ð±Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚
+  default_priority_low: Ð‘Ð°Ð³Ð°
+  default_priority_normal: Ð¥ÑÐ²Ð¸Ð¹Ð½
+  default_priority_high: Ó¨Ð½Ð´Ó©Ñ€
+  default_priority_urgent: ÐÑÐ½ ÑÐ°Ñ€Ð°Ð»Ñ‚Ð°Ð¹
+  default_priority_immediate: ÐÑÐ½ Ð´Ð°Ñ€ÑƒÐ¹
+  default_activity_design: Ð”Ð¸Ð·Ð°Ð¹Ð½
+  default_activity_development: Ð¥Ó©Ð³Ð¶Ò¯Ò¯Ð»ÑÐ»Ñ‚
+
+  enumeration_issue_priorities: ÐÑÑƒÑƒÐ´Ð»Ñ‹Ð½ Ð·ÑÑ€ÑÐ³Ð»ÑÐ»Ò¯Ò¯Ð´
+  enumeration_doc_categories: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚Ñ‹Ð½ Ð°Ð½Ð³Ð¸Ð»Ð»ÑƒÑƒÐ´
+  enumeration_activities: Ò®Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°Ð½ÑƒÑƒÐ´ (Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð³ Ñ…ÑÐ½Ð°Ñ…)
+  enumeration_system_activity: Ð¡Ð¸ÑÑ‚ÐµÐ¼Ð¸Ð¹Ð½ Ò¯Ð¹Ð» Ð°Ð¶Ð¸Ð»Ð»Ð°Ð³Ð°Ð°
+
+  permission_manage_subtasks: Manage subtasks
+  label_profile: Profile
+  field_parent_issue: Parent task
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: ÐšÐ¾Ð¼Ð¼Ð¸Ñ‚ Ñ…Ð¸Ð¹Ñ… Ò¯ÐµÐ´ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ñ… Ñ‚ÐµÐºÑÑ‚Ò¯Ò¯Ð´Ð¸Ð¹Ð½ ÑÐ½ÐºÐ¾Ð´Ð¸Ð½Ð³
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 ÐÑÑƒÑƒÐ´Ð°Ð»
+    one:   1 ÐÑÑƒÑƒÐ´Ð°Ð»
+    other: "%{count} ÐÑÑƒÑƒÐ´Ð»ÑƒÑƒÐ´"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: Ð±Ò¯Ð³Ð´
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: ÐÐ¸Ð¹Ñ‚
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cde0e9e2f86f3f2daa1bb290f329ede0eed7e74f.svn-base
--- a/.svn/pristine/cd/cde0e9e2f86f3f2daa1bb290f329ede0eed7e74f.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-<h2><%=l(:label_enumerations)%></h2>
-
-<% Enumeration.get_subclasses.each do |klass| %>
-<h3><%= l(klass::OptionName) %></h3>
-
-<% enumerations = klass.shared %>
-<% if enumerations.any? %>
-<table class="list"><thead>
-<tr>
-    <th><%= l(:field_name) %></th>
-    <th style="width:15%;"><%= l(:field_is_default) %></th>
-    <th style="width:15%;"><%= l(:field_active) %></th>
-    <th style="width:15%;"></th>
-    <th align="center" style="width:10%;"> </th>
-</tr></thead>
-<% enumerations.each do |enumeration| %>
-<tr class="<%= cycle('odd', 'even') %>">
-    <td><%= link_to h(enumeration), :action => 'edit', :id => enumeration %></td>
-    <td class="center" style="width:15%;"><%= checked_image enumeration.is_default? %></td>
-    <td class="center" style="width:15%;"><%= checked_image enumeration.active? %></td>
-    <td style="width:15%;"><%= reorder_links('enumeration', {:action => 'update', :id => enumeration}) %></td>
-    <td class="buttons">
-    <%= link_to l(:button_delete), { :action => 'destroy', :id => enumeration },
-                                   :method => :post,
-                                   :confirm => l(:text_are_you_sure),
-                                   :class => 'icon icon-del' %>
-    </td>
-</tr>
-<% end %>
-</table>
-<% reset_cycle %>
-<% end %>
-
-<p><%= link_to l(:label_enumeration_new), { :action => 'new', :type => klass.name } %></p>
-<% end %>
-
-<% html_title(l(:label_enumerations)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cd/cde9f06f97fdd301b66d1d21b5f974e9b5aa95e4.svn-base
--- a/.svn/pristine/cd/cde9f06f97fdd301b66d1d21b5f974e9b5aa95e4.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/dbconsole'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ce/ce01f810d3a29f63f33f44d575176d9d1fd50f81.svn-base
--- /dev/null
+++ b/.svn/pristine/ce/ce01f810d3a29f63f33f44d575176d9d1fd50f81.svn-base
@@ -0,0 +1,66 @@
+<%= board_breadcrumb(@board) %>
+
+<div class="contextual">
+<%= link_to l(:label_message_new),
+            new_board_message_path(@board),
+            :class => 'icon icon-add',
+            :onclick => 'showAndScrollTo("add-message", "message_subject"); return false;' if User.current.allowed_to?(:add_messages, @board.project) %>
+<%= watcher_link(@board, User.current) %>
+</div>
+
+<div id="add-message" style="display:none;">
+<% if User.current.allowed_to?(:add_messages, @board.project) %>
+<h2><%= link_to h(@board.name), project_board_path(@project, @board) %> &#187; <%= l(:label_message_new) %></h2>
+<%= form_for @message, :url => new_board_message_path(@board), :html => {:multipart => true, :id => 'message-form'} do |f| %>
+  <%= render :partial => 'messages/form', :locals => {:f => f} %>
+  <p><%= submit_tag l(:button_create) %>
+  <%= preview_link(preview_board_message_path(@board), 'message-form') %> |
+  <%= link_to l(:button_cancel), "#", :onclick => '$("#add-message").hide(); return false;' %></p>
+<% end %>
+<div id="preview" class="wiki"></div>
+<% end %>
+</div>
+
+<h2><%=h @board.name %></h2>
+<p class="subtitle"><%=h @board.description %></p>
+
+<% if @topics.any? %>
+<table class="list messages">
+  <thead><tr>
+    <th><%= l(:field_subject) %></th>
+    <th><%= l(:field_author) %></th>
+    <%= sort_header_tag('created_on', :caption => l(:field_created_on)) %>
+    <%= sort_header_tag('replies', :caption => l(:label_reply_plural)) %>
+    <%= sort_header_tag('updated_on', :caption => l(:label_message_last)) %>
+  </tr></thead>
+  <tbody>
+  <% @topics.each do |topic| %>
+    <tr class="message <%= cycle 'odd', 'even' %> <%= topic.sticky? ? 'sticky' : '' %> <%= topic.locked? ? 'locked' : '' %>">
+      <td class="subject"><%= link_to h(topic.subject), board_message_path(@board, topic) %></td>
+      <td class="author"><%= link_to_user(topic.author) %></td>
+      <td class="created_on"><%= format_time(topic.created_on) %></td>
+      <td class="reply-count"><%= topic.replies_count %></td>
+      <td class="last_message">
+        <% if topic.last_reply %>
+        <%= authoring topic.last_reply.created_on, topic.last_reply.author %><br />
+        <%= link_to_message topic.last_reply %>
+        <% end %>
+      </td>
+    </tr>
+  <% end %>
+  </tbody>
+</table>
+<p class="pagination"><%= pagination_links_full @topic_pages, @topic_count %></p>
+<% else %>
+<p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
+
+<% other_formats_links do |f| %>
+  <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
+<% end %>
+
+<% html_title @board.name %>
+
+<% content_for :header_tags do %>
+    <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@project}: #{@board}") %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ce/ce0ddfb0e373d214b7494e9b42aebe1b7d26bc67.svn-base
--- a/.svn/pristine/ce/ce0ddfb0e373d214b7494e9b42aebe1b7d26bc67.svn-base
+++ /dev/null
@@ -1,41 +0,0 @@
-module CodeRay
-  
-  # A simplified interface to the gzip library +zlib+ (from the Ruby Standard Library.)
-  module GZip
-    
-    require 'zlib'
-    
-    # The default zipping level. 7 zips good and fast.
-    DEFAULT_GZIP_LEVEL = 7
-    
-    # Unzips the given string +s+.
-    #
-    # Example:
-    #   require 'gzip_simple'
-    #   print GZip.gunzip(File.read('adresses.gz'))
-    def GZip.gunzip s
-      Zlib::Inflate.inflate s
-    end
-    
-    # Zips the given string +s+.
-    #
-    # Example:
-    #   require 'gzip_simple'
-    #   File.open('adresses.gz', 'w') do |file
-    #     file.write GZip.gzip('Mum: 0123 456 789', 9)
-    #   end
-    #
-    # If you provide a +level+, you can control how strong
-    # the string is compressed:
-    # - 0: no compression, only convert to gzip format
-    # - 1: compress fast
-    # - 7: compress more, but still fast (default)
-    # - 8: compress more, slower
-    # - 9: compress best, very slow
-    def GZip.gzip s, level = DEFAULT_GZIP_LEVEL
-      Zlib::Deflate.new(level).deflate s, Zlib::FINISH
-    end
-    
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ce/ce0fa91ce6538119a32d18dfd025c34cf1ec7c43.svn-base
--- a/.svn/pristine/ce/ce0fa91ce6538119a32d18dfd025c34cf1ec7c43.svn-base
+++ /dev/null
@@ -1,54 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../../test_helper', __FILE__)
-
-class Redmine::Views::Builders::XmlTest < ActiveSupport::TestCase
-
-  def test_hash
-    assert_xml_output('<person><name>Ryan</name><age>32</age></person>') do |b|
-      b.person do
-        b.name 'Ryan'
-        b.age  32
-      end
-    end
-  end
-
-  def test_array
-    assert_xml_output('<books type="array"><book title="Book 1"/><book title="Book 2"/></books>') do |b|
-      b.array :books do |b|
-        b.book :title => 'Book 1'
-        b.book :title => 'Book 2'
-      end
-    end
-  end
-
-  def test_array_with_content_tags
-    assert_xml_output('<books type="array"><book author="B. Smith">Book 1</book><book author="G. Cooper">Book 2</book></books>') do |b|
-      b.array :books do |b|
-        b.book 'Book 1', :author => 'B. Smith'
-        b.book 'Book 2', :author => 'G. Cooper'
-      end
-    end
-  end
-
-  def assert_xml_output(expected, &block)
-    builder = Redmine::Views::Builders::Xml.new
-    block.call(builder)
-    assert_equal('<?xml version="1.0" encoding="UTF-8"?>' + expected, builder.output)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ce/ce3436e583ff12a4824d53281463f89ddea0a5e7.svn-base
--- a/.svn/pristine/ce/ce3436e583ff12a4824d53281463f89ddea0a5e7.svn-base
+++ /dev/null
@@ -1,189 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class IssuesHelperTest < HelperTestCase
-  include ApplicationHelper
-  include IssuesHelper
-
-  include ActionController::Assertions::SelectorAssertions
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows
-
-  # Used by assert_select
-  def html_document
-    HTML::Document.new(@response.body)
-  end
-
-  def setup
-    super
-    set_language_if_valid('en')
-    User.current = nil
-    @response = ActionController::TestResponse.new
-  end
-
-  def controller
-    @controller ||= IssuesController.new
-  end
-
-  def request
-    @request ||= ActionController::TestRequest.new
-  end
-
-  def test_issue_heading
-    assert_equal "Bug #1", issue_heading(Issue.find(1))
-  end
-
-  def test_issues_destroy_confirmation_message_with_one_root_issue
-    assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find(1))
-  end
-
-  def test_issues_destroy_confirmation_message_with_an_arrayt_of_root_issues
-    assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find([1, 2]))
-  end
-
-  def test_issues_destroy_confirmation_message_with_one_parent_issue
-    Issue.find(2).update_attribute :parent_issue_id, 1
-    assert_equal l(:text_issues_destroy_confirmation) + "\n" + l(:text_issues_destroy_descendants_confirmation, :count => 1),
-      issues_destroy_confirmation_message(Issue.find(1))
-  end
-
-  def test_issues_destroy_confirmation_message_with_one_parent_issue_and_its_child
-    Issue.find(2).update_attribute :parent_issue_id, 1
-    assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find([1, 2]))
-  end
-
-  context "IssuesHelper#show_detail" do
-    context "with no_html" do
-      should 'show a changing attribute' do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => '40', :value => '100', :prop_key => 'done_ratio')
-        assert_equal "% Done changed from 40 to 100", show_detail(@detail, true)
-      end
-
-      should 'show a new attribute' do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => nil, :value => '100', :prop_key => 'done_ratio')
-        assert_equal "% Done set to 100", show_detail(@detail, true)
-      end
-
-      should 'show a deleted attribute' do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => '50', :value => nil, :prop_key => 'done_ratio')
-        assert_equal "% Done deleted (50)", show_detail(@detail, true)
-      end
-    end
-
-    context "with html" do
-      should 'show a changing attribute with HTML highlights' do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => '40', :value => '100', :prop_key => 'done_ratio')
-        @response.body = show_detail(@detail, false)
-
-        assert_select 'strong', :text => '% Done'
-        assert_select 'i', :text => '40'
-        assert_select 'i', :text => '100'
-      end
-
-      should 'show a new attribute with HTML highlights' do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => nil, :value => '100', :prop_key => 'done_ratio')
-        @response.body = show_detail(@detail, false)
-
-        assert_select 'strong', :text => '% Done'
-        assert_select 'i', :text => '100'
-      end
-
-      should 'show a deleted attribute with HTML highlights' do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => '50', :value => nil, :prop_key => 'done_ratio')
-        @response.body = show_detail(@detail, false)
-
-        assert_select 'strong', :text => '% Done'
-        assert_select 'strike' do
-          assert_select 'i', :text => '50'
-        end
-      end
-    end
-
-    context "with a start_date attribute" do
-      should "format the current date" do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => '2010-01-01', :value => '2010-01-31', :prop_key => 'start_date')
-        assert_match "01/31/2010", show_detail(@detail, true)
-      end
-
-      should "format the old date" do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => '2010-01-01', :value => '2010-01-31', :prop_key => 'start_date')
-        assert_match "01/01/2010", show_detail(@detail, true)
-      end
-    end
-
-    context "with a due_date attribute" do
-      should "format the current date" do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => '2010-01-01', :value => '2010-01-31', :prop_key => 'due_date')
-        assert_match "01/31/2010", show_detail(@detail, true)
-      end
-
-      should "format the old date" do
-        @detail = JournalDetail.generate!(:property => 'attr', :old_value => '2010-01-01', :value => '2010-01-31', :prop_key => 'due_date')
-        assert_match "01/01/2010", show_detail(@detail, true)
-      end
-    end
-
-    context "with a project attribute" do
-      should_show_the_old_and_new_values_for('project_id', Project)
-    end
-
-    context "with a issue status attribute" do
-      should_show_the_old_and_new_values_for('status_id', IssueStatus)
-    end
-
-    context "with a tracker attribute" do
-      should_show_the_old_and_new_values_for('tracker_id', Tracker)
-    end
-
-    context "with a assigned to attribute" do
-      should_show_the_old_and_new_values_for('assigned_to_id', User)
-    end
-
-    context "with a priority attribute" do
-      should_show_the_old_and_new_values_for('priority_id', IssuePriority) do
-        @old_value = IssuePriority.generate!(:type => 'IssuePriority')
-        @new_value = IssuePriority.generate!(:type => 'IssuePriority')
-      end
-    end
-
-    context "with a category attribute" do
-      should_show_the_old_and_new_values_for('category_id', IssueCategory)
-    end
-
-    context "with a fixed version attribute" do
-      should_show_the_old_and_new_values_for('fixed_version_id', Version)
-    end
-
-    context "with a estimated hours attribute" do
-      should "format the time into two decimal places"
-      should "format the old time into two decimal places"
-    end
-
-    should "test custom fields"
-    should "test attachments"
-
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ce/ce47c7361e1efd01e41b63643992673c2a65f3bf.svn-base
--- a/.svn/pristine/ce/ce47c7361e1efd01e41b63643992673c2a65f3bf.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-<% form_for(:user, :url => { :action => 'update' }, :html => {:method => :put}) do %>
-<div class="box">
-<% Group.all.sort.each do |group| %>
-<label><%= check_box_tag 'user[group_ids][]', group.id, @user.groups.include?(group) %> <%=h group %></label><br />
-<% end %>
-<%= hidden_field_tag 'user[group_ids][]', '' %>
-</div>
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cf/cf1a848896acb56eab1a3d8174b0732f774a9b99.svn-base
--- a/.svn/pristine/cf/cf1a848896acb56eab1a3d8174b0732f774a9b99.svn-base
+++ /dev/null
@@ -1,10 +0,0 @@
-<h2><%=l(:label_confirmation)%></h2>
-
-<div class="box"><center>
-<p><strong><%= h(@project.name) %></strong><br /><%=l(:text_wiki_destroy_confirmation)%></p>
-
-<% form_tag({:controller => 'wikis', :action => 'destroy', :id => @project}) do %>
-<%= hidden_field_tag "confirm", 1 %>
-<%= submit_tag l(:button_delete) %>
-<% end %>
-</center></div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cf/cf83b2054e56a61378d31a5b59a9e7ef95f73db1.svn-base
--- /dev/null
+++ b/.svn/pristine/cf/cf83b2054e56a61378d31a5b59a9e7ef95f73db1.svn-base
@@ -0,0 +1,1091 @@
+en-GB:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d/%m/%Y"
+      short: "%d %b"
+      long: "%d %B, %Y"
+
+    day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
+    abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%d/%m/%Y %I:%M %p"
+      time: "%I:%M %p"
+      short: "%d %b %H:%M"
+      long: "%d %B, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "half a minute"
+      less_than_x_seconds:
+        one:   "less than 1 second"
+        other: "less than %{count} seconds"
+      x_seconds:
+        one:   "1 second"
+        other: "%{count} seconds"
+      less_than_x_minutes:
+        one:   "less than a minute"
+        other: "less than %{count} minutes"
+      x_minutes:
+        one:   "1 minute"
+        other: "%{count} minutes"
+      about_x_hours:
+        one:   "about 1 hour"
+        other: "about %{count} hours"
+      x_hours:
+        one:   "1 hour"
+        other: "%{count} hours"
+      x_days:
+        one:   "1 day"
+        other: "%{count} days"
+      about_x_months:
+        one:   "about 1 month"
+        other: "about %{count} months"
+      x_months:
+        one:   "1 month"
+        other: "%{count} months"
+      about_x_years:
+        one:   "about 1 year"
+        other: "about %{count} years"
+      over_x_years:
+        one:   "over 1 year"
+        other: "over %{count} years"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    format:
+      separator: "."
+      delimiter: " "
+      precision: 3
+
+    currency:
+      format:
+        format: "%u%n"
+        unit: "Â£"
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "and"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "is not included in the list"
+        exclusion: "is reserved"
+        invalid: "is invalid"
+        confirmation: "doesn't match confirmation"
+        accepted: "must be accepted"
+        empty: "can't be empty"
+        blank: "can't be blank"
+        too_long: "is too long (maximum is %{count} characters)"
+        too_short: "is too short (minimum is %{count} characters)"
+        wrong_length: "is the wrong length (should be %{count} characters)"
+        taken: "has already been taken"
+        not_a_number: "is not a number"
+        not_a_date: "is not a valid date"
+        greater_than: "must be greater than %{count}"
+        greater_than_or_equal_to: "must be greater than or equal to %{count}"
+        equal_to: "must be equal to %{count}"
+        less_than: "must be less than %{count}"
+        less_than_or_equal_to: "must be less than or equal to %{count}"
+        odd: "must be odd"
+        even: "must be even"
+        greater_than_start_date: "must be greater than start date"
+        not_same_project: "doesn't belong to the same project"
+        circular_dependency: "This relation would create a circular dependency"
+        cant_link_an_issue_with_a_descendant: "An issue cannot be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: Please select
+
+  general_text_No: 'No'
+  general_text_Yes: 'Yes'
+  general_text_no: 'no'
+  general_text_yes: 'yes'
+  general_lang_name: 'English (British)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: ISO-8859-1
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Account was successfully updated.
+  notice_account_invalid_creditentials: Invalid user or password
+  notice_account_password_updated: Password was successfully updated.
+  notice_account_wrong_password: Wrong password
+  notice_account_register_done: Account was successfully created. To activate your account, click on the link that was emailed to you.
+  notice_account_unknown_email: Unknown user.
+  notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
+  notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
+  notice_account_activated: Your account has been activated. You can now log in.
+  notice_successful_create: Successful creation.
+  notice_successful_update: Successful update.
+  notice_successful_delete: Successful deletion.
+  notice_successful_connection: Successful connection.
+  notice_file_not_found: The page you were trying to access doesn't exist or has been removed.
+  notice_locking_conflict: Data has been updated by another user.
+  notice_not_authorized: You are not authorised to access this page.
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  notice_email_sent: "An email was sent to %{value}"
+  notice_email_error: "An error occurred while sending mail (%{value})"
+  notice_feeds_access_key_reseted: Your RSS access key was reset.
+  notice_api_access_key_reseted: Your API access key was reset.
+  notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
+  notice_account_pending: "Your account was created and is now pending administrator approval."
+  notice_default_data_loaded: Default configuration successfully loaded.
+  notice_unable_delete_version: Unable to delete version.
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})"
+
+  error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
+  error_scm_not_found: "The entry or revision was not found in the repository."
+  error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
+  error_scm_annotate: "The entry does not exist or cannot be annotated."
+  error_scm_annotate_big_text_file: "The entry cannot be annotated, as it exceeds the maximum text file size."
+  error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
+  error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
+  error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_can_not_delete_tracker: "This tracker contains issues and cannot be deleted."
+  error_can_not_remove_role: "This role is in use and cannot be deleted."
+  error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version cannot be reopened'
+  error_can_not_archive_project: This project cannot be archived
+  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
+  error_workflow_copy_source: 'Please select a source tracker or role'
+  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
+  error_unable_delete_issue_status: 'Unable to delete issue status'
+  error_unable_to_connect: "Unable to connect (%{value})"
+  warning_attachments_not_saved: "%{count} file(s) could not be saved."
+
+  mail_subject_lost_password: "Your %{value} password"
+  mail_body_lost_password: 'To change your password, click on the following link:'
+  mail_subject_register: "Your %{value} account activation"
+  mail_body_register: 'To activate your account, click on the following link:'
+  mail_body_account_information_external: "You can use your %{value} account to log in."
+  mail_body_account_information: Your account information
+  mail_subject_account_activation_request: "%{value} account activation request"
+  mail_body_account_activation_request: "A new user (%{value}) has registered. The account is pending your approval:"
+  mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
+  mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
+  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
+  mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
+  mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
+
+
+  field_name: Name
+  field_description: Description
+  field_summary: Summary
+  field_is_required: Required
+  field_firstname: First name
+  field_lastname: Last name
+  field_mail: Email
+  field_filename: File
+  field_filesize: Size
+  field_downloads: Downloads
+  field_author: Author
+  field_created_on: Created
+  field_updated_on: Updated
+  field_field_format: Format
+  field_is_for_all: For all projects
+  field_possible_values: Possible values
+  field_regexp: Regular expression
+  field_min_length: Minimum length
+  field_max_length: Maximum length
+  field_value: Value
+  field_category: Category
+  field_title: Title
+  field_project: Project
+  field_issue: Issue
+  field_status: Status
+  field_notes: Notes
+  field_is_closed: Issue closed
+  field_is_default: Default value
+  field_tracker: Tracker
+  field_subject: Subject
+  field_due_date: Due date
+  field_assigned_to: Assignee
+  field_priority: Priority
+  field_fixed_version: Target version
+  field_user: User
+  field_principal: Principal
+  field_role: Role
+  field_homepage: Homepage
+  field_is_public: Public
+  field_parent: Subproject of
+  field_is_in_roadmap: Issues displayed in roadmap
+  field_login: Login
+  field_mail_notification: Email notifications
+  field_admin: Administrator
+  field_last_login_on: Last connection
+  field_language: Language
+  field_effective_date: Date
+  field_password: Password
+  field_new_password: New password
+  field_password_confirmation: Confirmation
+  field_version: Version
+  field_type: Type
+  field_host: Host
+  field_port: Port
+  field_account: Account
+  field_base_dn: Base DN
+  field_attr_login: Login attribute
+  field_attr_firstname: Firstname attribute
+  field_attr_lastname: Lastname attribute
+  field_attr_mail: Email attribute
+  field_onthefly: On-the-fly user creation
+  field_start_date: Start date
+  field_done_ratio: "% Done"
+  field_auth_source: Authentication mode
+  field_hide_mail: Hide my email address
+  field_comments: Comment
+  field_url: URL
+  field_start_page: Start page
+  field_subproject: Subproject
+  field_hours: Hours
+  field_activity: Activity
+  field_spent_on: Date
+  field_identifier: Identifier
+  field_is_filter: Used as a filter
+  field_issue_to: Related issue
+  field_delay: Delay
+  field_assignable: Issues can be assigned to this role
+  field_redirect_existing_links: Redirect existing links
+  field_estimated_hours: Estimated time
+  field_column_names: Columns
+  field_time_entries: Log time
+  field_time_zone: Time zone
+  field_searchable: Searchable
+  field_default_value: Default value
+  field_comments_sorting: Display comments
+  field_parent_title: Parent page
+  field_editable: Editable
+  field_watcher: Watcher
+  field_identity_url: OpenID URL
+  field_content: Content
+  field_group_by: Group results by
+  field_sharing: Sharing
+  field_parent_issue: Parent task
+  field_member_of_group: "Assignee's group"
+  field_assigned_to_role: "Assignee's role"
+  field_text: Text field
+  field_visible: Visible
+  field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text"
+
+  setting_app_title: Application title
+  setting_app_subtitle: Application subtitle
+  setting_welcome_text: Welcome text
+  setting_default_language: Default language
+  setting_login_required: Authentication required
+  setting_self_registration: Self-registration
+  setting_attachment_max_size: Attachment max. size
+  setting_issues_export_limit: Issues export limit
+  setting_mail_from: Emission email address
+  setting_bcc_recipients: Blind carbon copy recipients (bcc)
+  setting_plain_text_mail: Plain text mail (no HTML)
+  setting_host_name: Host name and path
+  setting_text_formatting: Text formatting
+  setting_wiki_compression: Wiki history compression
+  setting_feeds_limit: Feed content limit
+  setting_default_projects_public: New projects are public by default
+  setting_autofetch_changesets: Autofetch commits
+  setting_sys_api_enabled: Enable WS for repository management
+  setting_commit_ref_keywords: Referencing keywords
+  setting_commit_fix_keywords: Fixing keywords
+  setting_autologin: Autologin
+  setting_date_format: Date format
+  setting_time_format: Time format
+  setting_cross_project_issue_relations: Allow cross-project issue relations
+  setting_issue_list_default_columns: Default columns displayed on the issue list
+  setting_emails_header: Email header
+  setting_emails_footer: Email footer
+  setting_protocol: Protocol
+  setting_per_page_options: Objects per page options
+  setting_user_format: Users display format
+  setting_activity_days_default: Days displayed on project activity
+  setting_display_subprojects_issues: Display subprojects issues on main projects by default
+  setting_enabled_scm: Enabled SCM
+  setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
+  setting_mail_handler_api_enabled: Enable WS for incoming emails
+  setting_mail_handler_api_key: API key
+  setting_sequential_project_identifiers: Generate sequential project identifiers
+  setting_gravatar_enabled: Use Gravatar user icons
+  setting_gravatar_default: Default Gravatar image
+  setting_diff_max_lines_displayed: Max number of diff lines displayed
+  setting_file_max_size_displayed: Max size of text files displayed inline
+  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
+  setting_openid: Allow OpenID login and registration
+  setting_password_min_length: Minimum password length
+  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_field: Use the issue field
+  setting_issue_done_ratio_issue_status: Use the issue status
+  setting_start_of_week: Start calendars on
+  setting_rest_api_enabled: Enable REST web service
+  setting_cache_formatted_text: Cache formatted text
+  setting_default_notification_option: Default notification option
+  setting_commit_logtime_enabled: Enable time logging
+  setting_commit_logtime_activity_id: Activity for logged time
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  setting_issue_group_assignment: Allow issue assignment to groups
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+
+  permission_add_project: Create project
+  permission_add_subprojects: Create subprojects
+  permission_edit_project: Edit project
+  permission_select_project_modules: Select project modules
+  permission_manage_members: Manage members
+  permission_manage_project_activities: Manage project activities
+  permission_manage_versions: Manage versions
+  permission_manage_categories: Manage issue categories
+  permission_view_issues: View Issues
+  permission_add_issues: Add issues
+  permission_edit_issues: Edit issues
+  permission_manage_issue_relations: Manage issue relations
+  permission_add_issue_notes: Add notes
+  permission_edit_issue_notes: Edit notes
+  permission_edit_own_issue_notes: Edit own notes
+  permission_move_issues: Move issues
+  permission_delete_issues: Delete issues
+  permission_manage_public_queries: Manage public queries
+  permission_save_queries: Save queries
+  permission_view_gantt: View gantt chart
+  permission_view_calendar: View calendar
+  permission_view_issue_watchers: View watchers list
+  permission_add_issue_watchers: Add watchers
+  permission_delete_issue_watchers: Delete watchers
+  permission_log_time: Log spent time
+  permission_view_time_entries: View spent time
+  permission_edit_time_entries: Edit time logs
+  permission_edit_own_time_entries: Edit own time logs
+  permission_manage_news: Manage news
+  permission_comment_news: Comment news
+  permission_view_documents: View documents
+  permission_manage_files: Manage files
+  permission_view_files: View files
+  permission_manage_wiki: Manage wiki
+  permission_rename_wiki_pages: Rename wiki pages
+  permission_delete_wiki_pages: Delete wiki pages
+  permission_view_wiki_pages: View wiki
+  permission_view_wiki_edits: View wiki history
+  permission_edit_wiki_pages: Edit wiki pages
+  permission_delete_wiki_pages_attachments: Delete attachments
+  permission_protect_wiki_pages: Protect wiki pages
+  permission_manage_repository: Manage repository
+  permission_browse_repository: Browse repository
+  permission_view_changesets: View changesets
+  permission_commit_access: Commit access
+  permission_manage_boards: Manage forums
+  permission_view_messages: View messages
+  permission_add_messages: Post messages
+  permission_edit_messages: Edit messages
+  permission_edit_own_messages: Edit own messages
+  permission_delete_messages: Delete messages
+  permission_delete_own_messages: Delete own messages
+  permission_export_wiki_pages: Export wiki pages
+  permission_manage_subtasks: Manage subtasks
+
+  project_module_issue_tracking: Issue tracking
+  project_module_time_tracking: Time tracking
+  project_module_news: News
+  project_module_documents: Documents
+  project_module_files: Files
+  project_module_wiki: Wiki
+  project_module_repository: Repository
+  project_module_boards: Forums
+  project_module_calendar: Calendar
+  project_module_gantt: Gantt
+
+  label_user: User
+  label_user_plural: Users
+  label_user_new: New user
+  label_user_anonymous: Anonymous
+  label_project: Project
+  label_project_new: New project
+  label_project_plural: Projects
+  label_x_projects:
+    zero:  no projects
+    one:   1 project
+    other: "%{count} projects"
+  label_project_all: All Projects
+  label_project_latest: Latest projects
+  label_issue: Issue
+  label_issue_new: New issue
+  label_issue_plural: Issues
+  label_issue_view_all: View all issues
+  label_issues_by: "Issues by %{value}"
+  label_issue_added: Issue added
+  label_issue_updated: Issue updated
+  label_document: Document
+  label_document_new: New document
+  label_document_plural: Documents
+  label_document_added: Document added
+  label_role: Role
+  label_role_plural: Roles
+  label_role_new: New role
+  label_role_and_permissions: Roles and permissions
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_member: Member
+  label_member_new: New member
+  label_member_plural: Members
+  label_tracker: Tracker
+  label_tracker_plural: Trackers
+  label_tracker_new: New tracker
+  label_workflow: Workflow
+  label_issue_status: Issue status
+  label_issue_status_plural: Issue statuses
+  label_issue_status_new: New status
+  label_issue_category: Issue category
+  label_issue_category_plural: Issue categories
+  label_issue_category_new: New category
+  label_custom_field: Custom field
+  label_custom_field_plural: Custom fields
+  label_custom_field_new: New custom field
+  label_enumerations: Enumerations
+  label_enumeration_new: New value
+  label_information: Information
+  label_information_plural: Information
+  label_please_login: Please log in
+  label_register: Register
+  label_login_with_open_id_option: or login with OpenID
+  label_password_lost: Lost password
+  label_home: Home
+  label_my_page: My page
+  label_my_account: My account
+  label_my_projects: My projects
+  label_my_page_block: My page block
+  label_administration: Administration
+  label_login: Sign in
+  label_logout: Sign out
+  label_help: Help
+  label_reported_issues: Reported issues
+  label_assigned_to_me_issues: Issues assigned to me
+  label_last_login: Last connection
+  label_registered_on: Registered on
+  label_activity: Activity
+  label_overall_activity: Overall activity
+  label_user_activity: "%{value}'s activity"
+  label_new: New
+  label_logged_as: Logged in as
+  label_environment: Environment
+  label_authentication: Authentication
+  label_auth_source: Authentication mode
+  label_auth_source_new: New authentication mode
+  label_auth_source_plural: Authentication modes
+  label_subproject_plural: Subprojects
+  label_subproject_new: New subproject
+  label_and_its_subprojects: "%{value} and its subprojects"
+  label_min_max_length: Min - Max length
+  label_list: List
+  label_date: Date
+  label_integer: Integer
+  label_float: Float
+  label_boolean: Boolean
+  label_string: Text
+  label_text: Long text
+  label_attribute: Attribute
+  label_attribute_plural: Attributes
+  label_no_data: No data to display
+  label_change_status: Change status
+  label_history: History
+  label_attachment: File
+  label_attachment_new: New file
+  label_attachment_delete: Delete file
+  label_attachment_plural: Files
+  label_file_added: File added
+  label_report: Report
+  label_report_plural: Reports
+  label_news: News
+  label_news_new: Add news
+  label_news_plural: News
+  label_news_latest: Latest news
+  label_news_view_all: View all news
+  label_news_added: News added
+  label_news_comment_added: Comment added to a news
+  label_settings: Settings
+  label_overview: Overview
+  label_version: Version
+  label_version_new: New version
+  label_version_plural: Versions
+  label_close_versions: Close completed versions
+  label_confirmation: Confirmation
+  label_export_to: 'Also available in:'
+  label_read: Read...
+  label_public_projects: Public projects
+  label_open_issues: open
+  label_open_issues_plural: open
+  label_closed_issues: closed
+  label_closed_issues_plural: closed
+  label_x_open_issues_abbr_on_total:
+    zero:  0 open / %{total}
+    one:   1 open / %{total}
+    other: "%{count} open / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 open
+    one:   1 open
+    other: "%{count} open"
+  label_x_closed_issues_abbr:
+    zero:  0 closed
+    one:   1 closed
+    other: "%{count} closed"
+  label_total: Total
+  label_permissions: Permissions
+  label_current_status: Current status
+  label_new_statuses_allowed: New statuses allowed
+  label_all: all
+  label_none: none
+  label_nobody: nobody
+  label_next: Next
+  label_previous: Previous
+  label_used_by: Used by
+  label_details: Details
+  label_add_note: Add a note
+  label_per_page: Per page
+  label_calendar: Calendar
+  label_months_from: months from
+  label_gantt: Gantt
+  label_internal: Internal
+  label_last_changes: "last %{count} changes"
+  label_change_view_all: View all changes
+  label_personalize_page: Personalise this page
+  label_comment: Comment
+  label_comment_plural: Comments
+  label_x_comments:
+    zero: no comments
+    one: 1 comment
+    other: "%{count} comments"
+  label_comment_add: Add a comment
+  label_comment_added: Comment added
+  label_comment_delete: Delete comments
+  label_query: Custom query
+  label_query_plural: Custom queries
+  label_query_new: New query
+  label_my_queries: My custom queries
+  label_filter_add: Add filter
+  label_filter_plural: Filters
+  label_equals: is
+  label_not_equals: is not
+  label_in_less_than: in less than
+  label_in_more_than: in more than
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: in
+  label_today: today
+  label_all_time: all time
+  label_yesterday: yesterday
+  label_this_week: this week
+  label_last_week: last week
+  label_last_n_days: "last %{count} days"
+  label_this_month: this month
+  label_last_month: last month
+  label_this_year: this year
+  label_date_range: Date range
+  label_less_than_ago: less than days ago
+  label_more_than_ago: more than days ago
+  label_ago: days ago
+  label_contains: contains
+  label_not_contains: doesn't contain
+  label_day_plural: days
+  label_repository: Repository
+  label_repository_plural: Repositories
+  label_browse: Browse
+  label_branch: Branch
+  label_tag: Tag
+  label_revision: Revision
+  label_revision_plural: Revisions
+  label_revision_id: "Revision %{value}"
+  label_associated_revisions: Associated revisions
+  label_added: added
+  label_modified: modified
+  label_copied: copied
+  label_renamed: renamed
+  label_deleted: deleted
+  label_latest_revision: Latest revision
+  label_latest_revision_plural: Latest revisions
+  label_view_revisions: View revisions
+  label_view_all_revisions: View all revisions
+  label_max_size: Maximum size
+  label_sort_highest: Move to top
+  label_sort_higher: Move up
+  label_sort_lower: Move down
+  label_sort_lowest: Move to bottom
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "Due in %{value}"
+  label_roadmap_overdue: "%{value} late"
+  label_roadmap_no_issues: No issues for this version
+  label_search: Search
+  label_result_plural: Results
+  label_all_words: All words
+  label_wiki: Wiki
+  label_wiki_edit: Wiki edit
+  label_wiki_edit_plural: Wiki edits
+  label_wiki_page: Wiki page
+  label_wiki_page_plural: Wiki pages
+  label_index_by_title: Index by title
+  label_index_by_date: Index by date
+  label_current_version: Current version
+  label_preview: Preview
+  label_feed_plural: Feeds
+  label_changes_details: Details of all changes
+  label_issue_tracking: Issue tracking
+  label_spent_time: Spent time
+  label_overall_spent_time: Overall spent time
+  label_f_hour: "%{value} hour"
+  label_f_hour_plural: "%{value} hours"
+  label_time_tracking: Time tracking
+  label_change_plural: Changes
+  label_statistics: Statistics
+  label_commits_per_month: Commits per month
+  label_commits_per_author: Commits per author
+  label_view_diff: View differences
+  label_diff_inline: inline
+  label_diff_side_by_side: side by side
+  label_options: Options
+  label_copy_workflow_from: Copy workflow from
+  label_permissions_report: Permissions report
+  label_watched_issues: Watched issues
+  label_related_issues: Related issues
+  label_applied_status: Applied status
+  label_loading: Loading...
+  label_relation_new: New relation
+  label_relation_delete: Delete relation
+  label_relates_to: related to
+  label_duplicates: duplicates
+  label_duplicated_by: duplicated by
+  label_blocks: blocks
+  label_blocked_by: blocked by
+  label_precedes: precedes
+  label_follows: follows
+  label_end_to_start: end to start
+  label_end_to_end: end to end
+  label_start_to_start: start to start
+  label_start_to_end: start to end
+  label_stay_logged_in: Stay logged in
+  label_disabled: disabled
+  label_show_completed_versions: Show completed versions
+  label_me: me
+  label_board: Forum
+  label_board_new: New forum
+  label_board_plural: Forums
+  label_board_locked: Locked
+  label_board_sticky: Sticky
+  label_topic_plural: Topics
+  label_message_plural: Messages
+  label_message_last: Last message
+  label_message_new: New message
+  label_message_posted: Message added
+  label_reply_plural: Replies
+  label_send_information: Send account information to the user
+  label_year: Year
+  label_month: Month
+  label_week: Week
+  label_date_from: From
+  label_date_to: To
+  label_language_based: Based on user's language
+  label_sort_by: "Sort by %{value}"
+  label_send_test_email: Send a test email
+  label_feeds_access_key: RSS access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  label_feeds_access_key_created_on: "RSS access key created %{value} ago"
+  label_module_plural: Modules
+  label_added_time_by: "Added by %{author} %{age} ago"
+  label_updated_time_by: "Updated by %{author} %{age} ago"
+  label_updated_time: "Updated %{value} ago"
+  label_jump_to_a_project: Jump to a project...
+  label_file_plural: Files
+  label_changeset_plural: Changesets
+  label_default_columns: Default columns
+  label_no_change_option: (No change)
+  label_bulk_edit_selected_issues: Bulk edit selected issues
+  label_theme: Theme
+  label_default: Default
+  label_search_titles_only: Search titles only
+  label_user_mail_option_all: "For any event on all my projects"
+  label_user_mail_option_selected: "For any event on the selected projects only..."
+  label_user_mail_option_none: "No events"
+  label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
+  label_user_mail_option_only_assigned: "Only for things I am assigned to"
+  label_user_mail_option_only_owner: "Only for things I am the owner of"
+  label_user_mail_no_self_notified: "I don't want to be notified of changes that I make myself"
+  label_registration_activation_by_email: account activation by email
+  label_registration_manual_activation: manual account activation
+  label_registration_automatic_activation: automatic account activation
+  label_display_per_page: "Per page: %{value}"
+  label_age: Age
+  label_change_properties: Change properties
+  label_general: General
+  label_more: More
+  label_scm: SCM
+  label_plugins: Plugins
+  label_ldap_authentication: LDAP authentication
+  label_downloads_abbr: D/L
+  label_optional_description: Optional description
+  label_add_another_file: Add another file
+  label_preferences: Preferences
+  label_chronological_order: In chronological order
+  label_reverse_chronological_order: In reverse chronological order
+  label_planning: Planning
+  label_incoming_emails: Incoming emails
+  label_generate_key: Generate a key
+  label_issue_watchers: Watchers
+  label_example: Example
+  label_display: Display
+  label_sort: Sort
+  label_ascending: Ascending
+  label_descending: Descending
+  label_date_from_to: From %{start} to %{end}
+  label_wiki_content_added: Wiki page added
+  label_wiki_content_updated: Wiki page updated
+  label_group: Group
+  label_group_plural: Groups
+  label_group_new: New group
+  label_time_entry_plural: Spent time
+  label_version_sharing_none: Not shared
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_tree: With project tree
+  label_version_sharing_system: With all projects
+  label_update_issue_done_ratios: Update issue done ratios
+  label_copy_source: Source
+  label_copy_target: Target
+  label_copy_same_as_target: Same as target
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_api_access_key: API access key
+  label_missing_api_access_key: Missing an API access key
+  label_api_access_key_created_on: "API access key created %{value} ago"
+  label_profile: Profile
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+
+  button_login: Login
+  button_submit: Submit
+  button_save: Save
+  button_check_all: Check all
+  button_uncheck_all: Uncheck all
+  button_collapse_all: Collapse all
+  button_expand_all: Expand all
+  button_delete: Delete
+  button_create: Create
+  button_create_and_continue: Create and continue
+  button_test: Test
+  button_edit: Edit
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  button_add: Add
+  button_change: Change
+  button_apply: Apply
+  button_clear: Clear
+  button_lock: Lock
+  button_unlock: Unlock
+  button_download: Download
+  button_list: List
+  button_view: View
+  button_move: Move
+  button_move_and_follow: Move and follow
+  button_back: Back
+  button_cancel: Cancel
+  button_activate: Activate
+  button_sort: Sort
+  button_log_time: Log time
+  button_rollback: Rollback to this version
+  button_watch: Watch
+  button_unwatch: Unwatch
+  button_reply: Reply
+  button_archive: Archive
+  button_unarchive: Unarchive
+  button_reset: Reset
+  button_rename: Rename
+  button_change_password: Change password
+  button_copy: Copy
+  button_copy_and_follow: Copy and follow
+  button_annotate: Annotate
+  button_update: Update
+  button_configure: Configure
+  button_quote: Quote
+  button_duplicate: Duplicate
+  button_show: Show
+
+  status_active: active
+  status_registered: registered
+  status_locked: locked
+
+  version_status_open: open
+  version_status_locked: locked
+  version_status_closed: closed
+
+  field_active: Active
+
+  text_select_mail_notifications: Select actions for which email notifications should be sent.
+  text_regexp_info: eg. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 means no restriction
+  text_project_destroy_confirmation: Are you sure you want to delete this project and related data?
+  text_subprojects_destroy_warning: "Its subproject(s): %{value} will be also deleted."
+  text_workflow_edit: Select a role and a tracker to edit the workflow
+  text_are_you_sure: Are you sure?
+  text_journal_changed: "%{label} changed from %{old} to %{new}"
+  text_journal_changed_no_detail: "%{label} updated"
+  text_journal_set_to: "%{label} set to %{value}"
+  text_journal_deleted: "%{label} deleted (%{old})"
+  text_journal_added: "%{label} %{value} added"
+  text_tip_issue_begin_day: task beginning this day
+  text_tip_issue_end_day: task ending this day
+  text_tip_issue_begin_end_day: task beginning and ending this day
+  text_project_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed, must start with a lower case letter.<br />Once saved, the identifier cannot be changed.'
+  text_caracters_maximum: "%{count} characters maximum."
+  text_caracters_minimum: "Must be at least %{count} characters long."
+  text_length_between: "Length between %{min} and %{max} characters."
+  text_tracker_no_workflow: No workflow defined for this tracker
+  text_unallowed_characters: Unallowed characters
+  text_comma_separated: Multiple values allowed (comma separated).
+  text_line_separated: Multiple values allowed (one line for each value).
+  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
+  text_issue_added: "Issue %{id} has been reported by %{author}."
+  text_issue_updated: "Issue %{id} has been updated by %{author}."
+  text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content?
+  text_issue_category_destroy_question: "Some issues (%{count}) are assigned to this category. What do you want to do?"
+  text_issue_category_destroy_assignments: Remove category assignments
+  text_issue_category_reassign_to: Reassign issues to this category
+  text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
+  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
+  text_load_default_configuration: Load the default configuration
+  text_status_changed_by_changeset: "Applied in changeset %{value}."
+  text_time_logged_by_changeset: "Applied in changeset %{value}."
+  text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?'
+  text_select_project_modules: 'Select modules to enable for this project:'
+  text_default_administrator_account_changed: Default administrator account changed
+  text_file_repository_writable: Attachments directory writable
+  text_plugin_assets_writable: Plugin assets directory writable
+  text_rmagick_available: RMagick available (optional)
+  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do?"
+  text_destroy_time_entries: Delete reported hours
+  text_assign_time_entries_to_project: Assign reported hours to the project
+  text_reassign_time_entries: 'Reassign reported hours to this issue:'
+  text_user_wrote: "%{value} wrote:"
+  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
+  text_enumeration_category_reassign_to: 'Reassign them to this value:'
+  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
+  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
+  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
+  text_custom_field_possible_values_info: 'One line for each value'
+  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
+  text_wiki_page_nullify_children: "Keep child pages as root pages"
+  text_wiki_page_destroy_children: "Delete child pages and all their descendants"
+  text_wiki_page_reassign_children: "Reassign child pages to this parent page"
+  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
+  text_zoom_in: Zoom in
+  text_zoom_out: Zoom out
+  text_warn_on_leaving_unsaved: "The current page contains unsaved text that will be lost if you leave this page."
+
+  default_role_manager: Manager
+  default_role_developer: Developer
+  default_role_reporter: Reporter
+  default_tracker_bug: Bug
+  default_tracker_feature: Feature
+  default_tracker_support: Support
+  default_issue_status_new: New
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: Resolved
+  default_issue_status_feedback: Feedback
+  default_issue_status_closed: Closed
+  default_issue_status_rejected: Rejected
+  default_doc_category_user: User documentation
+  default_doc_category_tech: Technical documentation
+  default_priority_low: Low
+  default_priority_normal: Normal
+  default_priority_high: High
+  default_priority_urgent: Urgent
+  default_priority_immediate: Immediate
+  default_activity_design: Design
+  default_activity_development: Development
+
+  enumeration_issue_priorities: Issue priorities
+  enumeration_doc_categories: Document categories
+  enumeration_activities: Activities (time tracking)
+  enumeration_system_activity: System Activity
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Commit messages encoding
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 issue
+    one:   1 issue
+    other: "%{count} issues"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position} of %{count}"
+  label_completed_versions: Completed versions
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.'
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: all
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cf/cf95716aca909d9dc04cf88a70448176a0b10143.svn-base
--- /dev/null
+++ b/.svn/pristine/cf/cf95716aca909d9dc04cf88a70448176a0b10143.svn-base
@@ -0,0 +1,53 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class FilesController < ApplicationController
+  menu_item :files
+
+  before_filter :find_project_by_project_id
+  before_filter :authorize
+
+  helper :sort
+  include SortHelper
+
+  def index
+    sort_init 'filename', 'asc'
+    sort_update 'filename' => "#{Attachment.table_name}.filename",
+                'created_on' => "#{Attachment.table_name}.created_on",
+                'size' => "#{Attachment.table_name}.filesize",
+                'downloads' => "#{Attachment.table_name}.downloads"
+
+    @containers = [ Project.includes(:attachments).reorder(sort_clause).find(@project.id)]
+    @containers += @project.versions.includes(:attachments).reorder(sort_clause).all.sort.reverse
+    render :layout => !request.xhr?
+  end
+
+  def new
+    @versions = @project.versions.sort
+  end
+
+  def create
+    container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id]))
+    attachments = Attachment.attach_files(container, params[:attachments])
+    render_attachment_warning_if_needed(container)
+
+    if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added')
+      Mailer.attachments_added(attachments[:files]).deliver
+    end
+    redirect_to project_files_path(@project)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cf/cf99c613decbc54df4a99c63e23764d371ea8fbc.svn-base
--- /dev/null
+++ b/.svn/pristine/cf/cf99c613decbc54df4a99c63e23764d371ea8fbc.svn-base
@@ -0,0 +1,122 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueCategoriesController < ApplicationController
+  menu_item :settings
+  model_object IssueCategory
+  before_filter :find_model_object, :except => [:index, :new, :create]
+  before_filter :find_project_from_association, :except => [:index, :new, :create]
+  before_filter :find_project_by_project_id, :only => [:index, :new, :create]
+  before_filter :authorize
+  accept_api_auth :index, :show, :create, :update, :destroy
+
+  def index
+    respond_to do |format|
+      format.html { redirect_to_settings_in_projects }
+      format.api { @categories = @project.issue_categories.all }
+    end
+  end
+
+  def show
+    respond_to do |format|
+      format.html { redirect_to_settings_in_projects }
+      format.api
+    end
+  end
+
+  def new
+    @category = @project.issue_categories.build
+    @category.safe_attributes = params[:issue_category]
+
+    respond_to do |format|
+      format.html
+      format.js
+    end
+  end
+
+  def create
+    @category = @project.issue_categories.build
+    @category.safe_attributes = params[:issue_category]
+    if @category.save
+      respond_to do |format|
+        format.html do
+          flash[:notice] = l(:notice_successful_create)
+          redirect_to_settings_in_projects
+        end
+        format.js
+        format.api { render :action => 'show', :status => :created, :location => issue_category_path(@category) }
+      end
+    else
+      respond_to do |format|
+        format.html { render :action => 'new'}
+        format.js   { render :action => 'new'}
+        format.api { render_validation_errors(@category) }
+      end
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    @category.safe_attributes = params[:issue_category]
+    if @category.save
+      respond_to do |format|
+        format.html {
+          flash[:notice] = l(:notice_successful_update)
+          redirect_to_settings_in_projects
+        }
+        format.api { render_api_ok }
+      end
+    else
+      respond_to do |format|
+        format.html { render :action => 'edit' }
+        format.api { render_validation_errors(@category) }
+      end
+    end
+  end
+
+  def destroy
+    @issue_count = @category.issues.size
+    if @issue_count == 0 || params[:todo] || api_request?
+      reassign_to = nil
+      if params[:reassign_to_id] && (params[:todo] == 'reassign' || params[:todo].blank?)
+        reassign_to = @project.issue_categories.find_by_id(params[:reassign_to_id])
+      end
+      @category.destroy(reassign_to)
+      respond_to do |format|
+        format.html { redirect_to_settings_in_projects }
+        format.api { render_api_ok }
+      end
+      return
+    end
+    @categories = @project.issue_categories - [@category]
+  end
+
+  private
+
+  def redirect_to_settings_in_projects
+    redirect_to settings_project_path(@project, :tab => 'categories')
+  end
+
+  # Wrap ApplicationController's find_model_object method to set
+  # @category instead of just @issue_category
+  def find_model_object
+    super
+    @category = @object
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cf/cfa38091d70dac5ed0710a8ebb3ecb812073f2f5.svn-base
--- /dev/null
+++ b/.svn/pristine/cf/cfa38091d70dac5ed0710a8ebb3ecb812073f2f5.svn-base
@@ -0,0 +1,95 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Activity
+    # Class used to retrieve activity events
+    class Fetcher
+      attr_reader :user, :project, :scope
+
+      # Needs to be unloaded in development mode
+      @@constantized_providers = Hash.new {|h,k| h[k] = Redmine::Activity.providers[k].collect {|t| t.constantize } }
+
+      def initialize(user, options={})
+        options.assert_valid_keys(:project, :with_subprojects, :author)
+        @user = user
+        @project = options[:project]
+        @options = options
+
+        @scope = event_types
+      end
+
+      # Returns an array of available event types
+      def event_types
+        return @event_types unless @event_types.nil?
+
+        @event_types = Redmine::Activity.available_event_types
+        @event_types = @event_types.select {|o| @project.self_and_descendants.detect {|p| @user.allowed_to?("view_#{o}".to_sym, p)}} if @project
+        @event_types
+      end
+
+      # Yields to filter the activity scope
+      def scope_select(&block)
+        @scope = @scope.select {|t| yield t }
+      end
+
+      # Sets the scope
+      # Argument can be :all, :default or an array of event types
+      def scope=(s)
+        case s
+        when :all
+          @scope = event_types
+        when :default
+          default_scope!
+        else
+          @scope = s & event_types
+        end
+      end
+
+      # Resets the scope to the default scope
+      def default_scope!
+        @scope = Redmine::Activity.default_event_types
+      end
+
+      # Returns an array of events for the given date range
+      # sorted in reverse chronological order
+      def events(from = nil, to = nil, options={})
+        e = []
+        @options[:limit] = options[:limit]
+
+        @scope.each do |event_type|
+          constantized_providers(event_type).each do |provider|
+            e += provider.find_events(event_type, @user, from, to, @options)
+          end
+        end
+
+        e.sort! {|a,b| b.event_datetime <=> a.event_datetime}
+
+        if options[:limit]
+          e = e.slice(0, options[:limit])
+        end
+        e
+      end
+
+      private
+
+      def constantized_providers(event_type)
+        @@constantized_providers[event_type]
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cf/cfc7663e122e84036abc6410ab71cccdc11c960a.svn-base
--- /dev/null
+++ b/.svn/pristine/cf/cfc7663e122e84036abc6410ab71cccdc11c960a.svn-base
@@ -0,0 +1,47 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class CustomFieldsHelperTest < ActionView::TestCase
+  include CustomFieldsHelper
+  include Redmine::I18n
+  include ERB::Util
+
+  def test_format_boolean_value
+    I18n.locale = 'en'
+    assert_equal 'Yes', format_value('1', 'bool')
+    assert_equal 'No', format_value('0', 'bool')
+  end
+
+  def test_unknow_field_format_should_be_edited_as_string
+    field = CustomField.new(:field_format => 'foo')
+    value = CustomValue.new(:value => 'bar', :custom_field => field)
+    field.id = 52
+
+    assert_equal '<input class="foo_cf" id="object_custom_field_values_52" name="object[custom_field_values][52]" type="text" value="bar" />',
+      custom_field_tag('object', value)
+  end
+
+  def test_unknow_field_format_should_be_bulk_edited_as_string
+    field = CustomField.new(:field_format => 'foo')
+    field.id = 52
+
+    assert_equal '<input class="foo_cf" id="object_custom_field_values_52" name="object[custom_field_values][52]" type="text" value="" />',
+      custom_field_tag_for_bulk_edit('object', field)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/cf/cfcd7c9b97a7c386801c8595e27a26562b98c813.svn-base
--- a/.svn/pristine/cf/cfcd7c9b97a7c386801c8595e27a26562b98c813.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-# $Id: testfilter.rb 122 2006-05-15 20:03:56Z blackhedd $
-#
-#
-
-require 'test/unit'
-
-$:.unshift "lib"
-
-require 'net/ldap'
-
-
-class TestFilter < Test::Unit::TestCase
-
-  def setup
-  end
-
-
-  def teardown
-  end
-
-  def test_rfc_2254
-    p Net::LDAP::Filter.from_rfc2254( " ( uid=george*   ) " )
-    p Net::LDAP::Filter.from_rfc2254( "uid!=george*" )
-    p Net::LDAP::Filter.from_rfc2254( "uid<george*" )
-    p Net::LDAP::Filter.from_rfc2254( "uid <= george*" )
-    p Net::LDAP::Filter.from_rfc2254( "uid>george*" )
-    p Net::LDAP::Filter.from_rfc2254( "uid>=george*" )
-    p Net::LDAP::Filter.from_rfc2254( "uid!=george*" )
-
-    p Net::LDAP::Filter.from_rfc2254( "(& (uid!=george* ) (mail=*))" )
-    p Net::LDAP::Filter.from_rfc2254( "(| (uid!=george* ) (mail=*))" )
-    p Net::LDAP::Filter.from_rfc2254( "(! (mail=*))" )
-  end
-
-
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d0/d009627e726f03a1c296b163bb2546a76eb0de0f.svn-base
--- /dev/null
+++ b/.svn/pristine/d0/d009627e726f03a1c296b163bb2546a76eb0de0f.svn-base
@@ -0,0 +1,99 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingProjectsTest < ActionController::IntegrationTest
+  def test_projects
+    assert_routing(
+        { :method => 'get', :path => "/projects" },
+        { :controller => 'projects', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects.atom" },
+        { :controller => 'projects', :action => 'index', :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects.xml" },
+        { :controller => 'projects', :action => 'index', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/new" },
+        { :controller => 'projects', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/test" },
+        { :controller => 'projects', :action => 'show', :id => 'test' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/1.xml" },
+        { :controller => 'projects', :action => 'show', :id => '1',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/4223/settings" },
+        { :controller => 'projects', :action => 'settings', :id => '4223' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/4223/settings/members" },
+        { :controller => 'projects', :action => 'settings', :id => '4223',
+          :tab => 'members' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects" },
+        { :controller => 'projects', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects.xml" },
+        { :controller => 'projects', :action => 'create', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/64/archive" },
+        { :controller => 'projects', :action => 'archive', :id => '64' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/64/unarchive" },
+        { :controller => 'projects', :action => 'unarchive', :id => '64' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/64/close" },
+        { :controller => 'projects', :action => 'close', :id => '64' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/64/reopen" },
+        { :controller => 'projects', :action => 'reopen', :id => '64' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/projects/4223" },
+        { :controller => 'projects', :action => 'update', :id => '4223' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/projects/1.xml" },
+        { :controller => 'projects', :action => 'update', :id => '1',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/projects/64" },
+        { :controller => 'projects', :action => 'destroy', :id => '64' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/projects/1.xml" },
+        { :controller => 'projects', :action => 'destroy', :id => '1',
+          :format => 'xml' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d0/d039eff47c882ca8fdcaa341586c99c94f946614.svn-base
--- a/.svn/pristine/d0/d039eff47c882ca8fdcaa341586c99c94f946614.svn-base
+++ /dev/null
@@ -1,32 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Views
-    module MyPage
-      module Block
-        def self.additional_blocks
-          @@additional_blocks ||= Dir.glob("#{Rails.root}/vendor/plugins/*/app/views/my/blocks/_*.{rhtml,erb}").inject({}) do |h,file|
-            name = File.basename(file).split('.').first.gsub(/^_/, '')
-            h[name] = name.to_sym
-            h
-          end
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d0/d06b6083b66969c3f352b413de031bfbb21d7aa5.svn-base
--- a/.svn/pristine/d0/d06b6083b66969c3f352b413de031bfbb21d7aa5.svn-base
+++ /dev/null
@@ -1,2 +0,0 @@
-<p><%= l(:mail_body_register) %><br />
-<%= auto_link(@url) %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d0/d06e7cefb510a385899794a94c740218a4fb9cd9.svn-base
--- /dev/null
+++ b/.svn/pristine/d0/d06e7cefb510a385899794a94c740218a4fb9cd9.svn-base
@@ -0,0 +1,42 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module GroupsHelper
+  def group_settings_tabs
+    tabs = [{:name => 'general', :partial => 'groups/general', :label => :label_general},
+            {:name => 'users', :partial => 'groups/users', :label => :label_user_plural},
+            {:name => 'memberships', :partial => 'groups/memberships', :label => :label_project_plural}
+            ]
+  end
+
+  def render_principals_for_new_group_users(group)
+    scope = User.active.sorted.not_in_group(group).like(params[:q])
+    principal_count = scope.count
+    principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
+    principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
+
+    s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals')
+
+    links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
+      link_to text, autocomplete_for_user_group_path(group, parameters.merge(:q => params[:q], :format => 'js')), :remote => true
+    }
+
+    s + content_tag('p', links, :class => 'pagination')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d0/d0da4895684ef4cb299c5edf6622c92dd56d9cc9.svn-base
--- a/.svn/pristine/d0/d0da4895684ef4cb299c5edf6622c92dd56d9cc9.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-<div class="contextual">
-<%= link_to l(:label_role_new), {:action => 'new'}, :class => 'icon icon-add' %>
-</div>
-
-<h2><%=l(:label_role_plural)%></h2>
-
-<table class="list">
-  <thead><tr>
-    <th><%=l(:label_role)%></th>
-    <th><%=l(:button_sort)%></th>
-  <th></th>
-  </tr></thead>
-  <tbody>
-<% for role in @roles %>
-  <tr class="<%= cycle("odd", "even") %>">
-  <td><%= content_tag(role.builtin? ? 'em' : 'span', link_to(h(role.name), :action => 'edit', :id => role)) %></td>
-  <td align="center" style="width:15%;">
-  <% unless role.builtin? %>
-    <%= reorder_links('role', {:action => 'edit', :id => role}) %>
-  <% end %>
-  </td>
-  <td class="buttons">
-    <%= link_to(l(:button_delete), { :action => 'destroy', :id => role },
-                                  :method => :post,
-                                  :confirm => l(:text_are_you_sure),
-                                  :class => 'icon icon-del') unless role.builtin? %>
-  </td>
-  </tr>
-<% end %>
-  </tbody>
-</table>
-
-<p class="pagination"><%= pagination_links_full @role_pages %></p>
-
-<p><%= link_to l(:label_permissions_report), :action => 'report' %></p>
-
-<% html_title(l(:label_role_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d0/d0f8878bdc56439db6ee9330f7bfbb77c7251f27.svn-base
--- a/.svn/pristine/d0/d0f8878bdc56439db6ee9330f7bfbb77c7251f27.svn-base
+++ /dev/null
@@ -1,200 +0,0 @@
-/*  Copyright Mihai Bazon, 2002, 2003  |  http://dynarch.com/mishoo/
- * ---------------------------------------------------------------------------
- *
- * The DHTML Calendar
- *
- * Details and latest version at:
- * http://dynarch.com/mishoo/calendar.epl
- *
- * This script is distributed under the GNU Lesser General Public License.
- * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
- *
- * This file defines helper functions for setting up the calendar.  They are
- * intended to help non-programmers get a working calendar on their site
- * quickly.  This script should not be seen as part of the calendar.  It just
- * shows you what one can do with the calendar, while in the same time
- * providing a quick and simple method for setting it up.  If you need
- * exhaustive customization of the calendar creation process feel free to
- * modify this code to suit your needs (this is recommended and much better
- * than modifying calendar.js itself).
- */
-
-// $Id: calendar-setup.js,v 1.25 2005/03/07 09:51:33 mishoo Exp $
-
-/**
- *  This function "patches" an input field (or other element) to use a calendar
- *  widget for date selection.
- *
- *  The "params" is a single object that can have the following properties:
- *
- *    prop. name   | description
- *  -------------------------------------------------------------------------------------------------
- *   inputField    | the ID of an input field to store the date
- *   displayArea   | the ID of a DIV or other element to show the date
- *   button        | ID of a button or other element that will trigger the calendar
- *   eventName     | event that will trigger the calendar, without the "on" prefix (default: "click")
- *   ifFormat      | date format that will be stored in the input field
- *   daFormat      | the date format that will be used to display the date in displayArea
- *   singleClick   | (true/false) wether the calendar is in single click mode or not (default: true)
- *   firstDay      | numeric: 0 to 6.  "0" means display Sunday first, "1" means display Monday first, etc.
- *   align         | alignment (default: "Br"); if you don't know what's this see the calendar documentation
- *   range         | array with 2 elements.  Default: [1900, 2999] -- the range of years available
- *   weekNumbers   | (true/false) if it's true (default) the calendar will display week numbers
- *   flat          | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
- *   flatCallback  | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
- *   disableFunc   | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
- *   onSelect      | function that gets called when a date is selected.  You don't _have_ to supply this (the default is generally okay)
- *   onClose       | function that gets called when the calendar is closed.  [default]
- *   onUpdate      | function that gets called after the date is updated in the input field.  Receives a reference to the calendar.
- *   date          | the date that the calendar will be initially displayed to
- *   showsTime     | default: false; if true the calendar will include a time selector
- *   timeFormat    | the time format; can be "12" or "24", default is "12"
- *   electric      | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close
- *   step          | configures the step of the years in drop-down boxes; default: 2
- *   position      | configures the calendar absolute position; default: null
- *   cache         | if "true" (but default: "false") it will reuse the same calendar object, where possible
- *   showOthers    | if "true" (but default: "false") it will show days from other months too
- *
- *  None of them is required, they all have default values.  However, if you
- *  pass none of "inputField", "displayArea" or "button" you'll get a warning
- *  saying "nothing to setup".
- */
-Calendar.setup = function (params) {
-	function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };
-
-	param_default("inputField",     null);
-	param_default("displayArea",    null);
-	param_default("button",         null);
-	param_default("eventName",      "click");
-	param_default("ifFormat",       "%Y/%m/%d");
-	param_default("daFormat",       "%Y/%m/%d");
-	param_default("singleClick",    true);
-	param_default("disableFunc",    null);
-	param_default("dateStatusFunc", params["disableFunc"]);	// takes precedence if both are defined
-	param_default("dateText",       null);
-	param_default("firstDay",       null);
-	param_default("align",          "Br");
-	param_default("range",          [1900, 2999]);
-	param_default("weekNumbers",    true);
-	param_default("flat",           null);
-	param_default("flatCallback",   null);
-	param_default("onSelect",       null);
-	param_default("onClose",        null);
-	param_default("onUpdate",       null);
-	param_default("date",           null);
-	param_default("showsTime",      false);
-	param_default("timeFormat",     "24");
-	param_default("electric",       true);
-	param_default("step",           2);
-	param_default("position",       null);
-	param_default("cache",          false);
-	param_default("showOthers",     false);
-	param_default("multiple",       null);
-
-	var tmp = ["inputField", "displayArea", "button"];
-	for (var i in tmp) {
-		if (typeof params[tmp[i]] == "string") {
-			params[tmp[i]] = document.getElementById(params[tmp[i]]);
-		}
-	}
-	if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
-		alert("Calendar.setup:\n  Nothing to setup (no fields found).  Please check your code");
-		return false;
-	}
-
-	function onSelect(cal) {
-		var p = cal.params;
-		var update = (cal.dateClicked || p.electric);
-		if (update && p.inputField) {
-			p.inputField.value = cal.date.print(p.ifFormat);
-			if (typeof p.inputField.onchange == "function")
-				p.inputField.onchange();
-		}
-		if (update && p.displayArea)
-			p.displayArea.innerHTML = cal.date.print(p.daFormat);
-		if (update && typeof p.onUpdate == "function")
-			p.onUpdate(cal);
-		if (update && p.flat) {
-			if (typeof p.flatCallback == "function")
-				p.flatCallback(cal);
-		}
-		if (update && p.singleClick && cal.dateClicked)
-			cal.callCloseHandler();
-	};
-
-	if (params.flat != null) {
-		if (typeof params.flat == "string")
-			params.flat = document.getElementById(params.flat);
-		if (!params.flat) {
-			alert("Calendar.setup:\n  Flat specified but can't find parent.");
-			return false;
-		}
-		var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect);
-		cal.showsOtherMonths = params.showOthers;
-		cal.showsTime = params.showsTime;
-		cal.time24 = (params.timeFormat == "24");
-		cal.params = params;
-		cal.weekNumbers = params.weekNumbers;
-		cal.setRange(params.range[0], params.range[1]);
-		cal.setDateStatusHandler(params.dateStatusFunc);
-		cal.getDateText = params.dateText;
-		if (params.ifFormat) {
-			cal.setDateFormat(params.ifFormat);
-		}
-		if (params.inputField && typeof params.inputField.value == "string") {
-			cal.parseDate(params.inputField.value);
-		}
-		cal.create(params.flat);
-		cal.show();
-		return false;
-	}
-
-	var triggerEl = params.button || params.displayArea || params.inputField;
-	triggerEl["on" + params.eventName] = function() {
-		var dateEl = params.inputField || params.displayArea;
-		var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
-		var mustCreate = false;
-		var cal = window.calendar;
-		if (dateEl)
-			params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
-		if (!(cal && params.cache)) {
-			window.calendar = cal = new Calendar(params.firstDay,
-							     params.date,
-							     params.onSelect || onSelect,
-							     params.onClose || function(cal) { cal.hide(); });
-			cal.showsTime = params.showsTime;
-			cal.time24 = (params.timeFormat == "24");
-			cal.weekNumbers = params.weekNumbers;
-			mustCreate = true;
-		} else {
-			if (params.date)
-				cal.setDate(params.date);
-			cal.hide();
-		}
-		if (params.multiple) {
-			cal.multiple = {};
-			for (var i = params.multiple.length; --i >= 0;) {
-				var d = params.multiple[i];
-				var ds = d.print("%Y%m%d");
-				cal.multiple[ds] = d;
-			}
-		}
-		cal.showsOtherMonths = params.showOthers;
-		cal.yearStep = params.step;
-		cal.setRange(params.range[0], params.range[1]);
-		cal.params = params;
-		cal.setDateStatusHandler(params.dateStatusFunc);
-		cal.getDateText = params.dateText;
-		cal.setDateFormat(dateFmt);
-		if (mustCreate)
-			cal.create();
-		cal.refresh();
-		if (!params.position)
-			cal.showAtElement(params.button || params.displayArea || params.inputField);
-		else
-			cal.showAt(params.position[0], params.position[1]);
-		return false;
-	};
-
-	return cal;
-};
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d1/d12fedcbe9f8547cfa6f4a11afa8ce1f7c83ddcf.svn-base
--- a/.svn/pristine/d1/d12fedcbe9f8547cfa6f4a11afa8ce1f7c83ddcf.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-<h2><%= link_to l(:label_user_plural), users_path %> &#187; <%=l(:label_user_new)%></h2>
-
-<% form_for @user, :builder => TabularFormBuilder do |f| %>
-  <%= render :partial => 'form', :locals => { :f => f } %>
-  <% if email_delivery_enabled? %>
-  <p><label><%= check_box_tag 'send_information', 1, true %> <%= l(:label_send_information) %></label></p>
-  <% end %>
-  <p>
-    <%= submit_tag l(:button_create) %>
-    <%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
-  </p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d1/d15c9bc4de1f1d7b094ee61fb27085757eaaa6fd.svn-base
--- /dev/null
+++ b/.svn/pristine/d1/d15c9bc4de1f1d7b094ee61fb27085757eaaa6fd.svn-base
@@ -0,0 +1,11 @@
+class AddSettingsUpdatedOn < ActiveRecord::Migration
+  def self.up
+    add_column :settings, :updated_on, :timestamp
+    # set updated_on
+    Setting.all.each(&:save)
+  end
+
+  def self.down
+    remove_column :settings, :updated_on
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d1/d1641076738b16a5e8c3b02dfb1eb74a370bb3d4.svn-base
--- /dev/null
+++ b/.svn/pristine/d1/d1641076738b16a5e8c3b02dfb1eb74a370bb3d4.svn-base
@@ -0,0 +1,198 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoriesBazaarControllerTest < ActionController::TestCase
+  tests RepositoriesController
+
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :repositories, :enabled_modules
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository/trunk').to_s
+  PRJ_ID = 3
+
+  def setup
+    User.current = nil
+    @project = Project.find(PRJ_ID)
+    @repository = Repository::Bazaar.create(
+                    :project      => @project,
+                    :url          => REPOSITORY_PATH,
+                    :log_encoding => 'UTF-8')
+    assert @repository
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    def test_get_new
+      @request.session[:user_id] = 1
+      @project.repository.destroy
+      get :new, :project_id => 'subproject1', :repository_scm => 'Bazaar'
+      assert_response :success
+      assert_template 'new'
+      assert_kind_of Repository::Bazaar, assigns(:repository)
+      assert assigns(:repository).new_record?
+    end
+
+    def test_browse_root
+      get :show, :id => PRJ_ID
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal 2, assigns(:entries).size
+      assert assigns(:entries).detect {|e| e.name == 'directory' && e.kind == 'dir'}
+      assert assigns(:entries).detect {|e| e.name == 'doc-mkdir.txt' && e.kind == 'file'}
+    end
+
+    def test_browse_directory
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['directory'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['doc-ls.txt', 'document.txt', 'edit.png'], assigns(:entries).collect(&:name)
+      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
+      assert_not_nil entry
+      assert_equal 'file', entry.kind
+      assert_equal 'directory/edit.png', entry.path
+    end
+
+    def test_browse_at_given_revision
+      get :show, :id => PRJ_ID, :path => repository_path_hash([])[:param],
+          :rev => 3
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['directory', 'doc-deleted.txt', 'doc-ls.txt', 'doc-mkdir.txt'],
+                   assigns(:entries).collect(&:name)
+    end
+
+    def test_changes
+      get :changes, :id => PRJ_ID,
+          :path => repository_path_hash(['doc-mkdir.txt'])[:param]
+      assert_response :success
+      assert_template 'changes'
+      assert_tag :tag => 'h2', :content => 'doc-mkdir.txt'
+    end
+
+    def test_entry_show
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['directory', 'doc-ls.txt'])[:param]
+      assert_response :success
+      assert_template 'entry'
+      # Line 19
+      assert_tag :tag => 'th',
+                 :content => /29/,
+                 :attributes => { :class => /line-num/ },
+                 :sibling => { :tag => 'td', :content => /Show help message/ }
+    end
+
+    def test_entry_download
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['directory', 'doc-ls.txt'])[:param],
+          :format => 'raw'
+      assert_response :success
+      # File content
+      assert @response.body.include?('Show help message')
+    end
+
+    def test_directory_entry
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['directory'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entry)
+      assert_equal 'directory', assigns(:entry).name
+    end
+
+    def test_diff
+      # Full diff of changeset 3
+      ['inline', 'sbs'].each do |dt|
+        get :diff, :id => PRJ_ID, :rev => 3, :type => dt
+        assert_response :success
+        assert_template 'diff'
+        # Line 11 removed
+        assert_tag :tag => 'th',
+                   :content => '11',
+                   :sibling => { :tag => 'td',
+                                 :attributes => { :class => /diff_out/ },
+                                 :content => /Display more information/ }
+      end
+    end
+
+    def test_annotate
+      get :annotate, :id => PRJ_ID,
+          :path => repository_path_hash(['doc-mkdir.txt'])[:param]
+      assert_response :success
+      assert_template 'annotate'
+      assert_tag :tag => 'th', :content => '2',
+                 :sibling => {
+                    :tag => 'td',
+                    :child => {
+                       :tag => 'a',
+                       :content => '3'
+                       }
+                    }
+      assert_tag :tag => 'th', :content => '2',
+                 :sibling => { :tag => 'td', :content => /jsmith/ }
+      assert_tag :tag => 'th', :content => '2',
+                 :sibling => {
+                    :tag => 'td',
+                    :child => {
+                       :tag => 'a',
+                       :content => '3'
+                       }
+                    }
+      assert_tag :tag => 'th', :content => '2',
+                 :sibling => { :tag => 'td', :content => /Main purpose/ }
+    end
+
+    def test_destroy_valid_repository
+      @request.session[:user_id] = 1 # admin
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      assert @repository.changesets.count > 0
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+
+    def test_destroy_invalid_repository
+      @request.session[:user_id] = 1 # admin
+      @project.repository.destroy
+      @repository = Repository::Bazaar.create!(
+                    :project      => @project,
+                    :url          => "/invalid",
+                    :log_encoding => 'UTF-8')
+      @repository.fetch_changesets
+      @repository.reload
+      assert_equal 0, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+  else
+    puts "Bazaar test repository NOT FOUND. Skipping functional tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d1/d17414b1dfdce0231596e6df806c393321b9c1d6.svn-base
--- a/.svn/pristine/d1/d17414b1dfdce0231596e6df806c393321b9c1d6.svn-base
+++ /dev/null
@@ -1,200 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class IssuesTest < ActionController::IntegrationTest
-  fixtures :projects,
-           :users,
-           :roles,
-           :members,
-           :trackers,
-           :projects_trackers,
-           :enabled_modules,
-           :issue_statuses,
-           :issues,
-           :enumerations,
-           :custom_fields,
-           :custom_values,
-           :custom_fields_trackers
-
-  # create an issue
-  def test_add_issue
-    log_user('jsmith', 'jsmith')
-    get 'projects/1/issues/new', :tracker_id => '1'
-    assert_response :success
-    assert_template 'issues/new'
-
-    post 'projects/1/issues', :tracker_id => "1",
-                                 :issue => { :start_date => "2006-12-26",
-                                             :priority_id => "4",
-                                             :subject => "new test issue",
-                                             :category_id => "",
-                                             :description => "new issue",
-                                             :done_ratio => "0",
-                                             :due_date => "",
-                                             :assigned_to_id => "" },
-                                 :custom_fields => {'2' => 'Value for field 2'}
-    # find created issue
-    issue = Issue.find_by_subject("new test issue")
-    assert_kind_of Issue, issue
-
-    # check redirection
-    assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
-    follow_redirect!
-    assert_equal issue, assigns(:issue)
-
-    # check issue attributes
-    assert_equal 'jsmith', issue.author.login
-    assert_equal 1, issue.project.id
-    assert_equal 1, issue.status.id
-  end
-
-  # add then remove 2 attachments to an issue
-  def test_issue_attachments
-    log_user('jsmith', 'jsmith')
-    set_tmp_attachments_directory
-
-    put 'issues/1',
-         :notes => 'Some notes',
-         :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'This is an attachment'}}
-    assert_redirected_to "/issues/1"
-
-    # make sure attachment was saved
-    attachment = Issue.find(1).attachments.find_by_filename("testfile.txt")
-    assert_kind_of Attachment, attachment
-    assert_equal Issue.find(1), attachment.container
-    assert_equal 'This is an attachment', attachment.description
-    # verify the size of the attachment stored in db
-    #assert_equal file_data_1.length, attachment.filesize
-    # verify that the attachment was written to disk
-    assert File.exist?(attachment.diskfile)
-
-    # remove the attachments
-    Issue.find(1).attachments.each(&:destroy)
-    assert_equal 0, Issue.find(1).attachments.length
-  end
-
-  def test_other_formats_links_on_get_index
-    get '/projects/ecookbook/issues'
-
-    %w(Atom PDF CSV).each do |format|
-      assert_tag :a, :content => format,
-                     :attributes => { :href => "/projects/ecookbook/issues.#{format.downcase}",
-                                      :rel => 'nofollow' }
-    end
-  end
-
-  def test_other_formats_links_on_post_index_without_project_id_in_url
-    post '/issues', :project_id => 'ecookbook'
-
-    %w(Atom PDF CSV).each do |format|
-      assert_tag :a, :content => format,
-                     :attributes => { :href => "/projects/ecookbook/issues.#{format.downcase}",
-                                      :rel => 'nofollow' }
-    end
-  end
-
-  def test_pagination_links_on_get_index
-    Setting.per_page_options = '2'
-    get '/projects/ecookbook/issues'
-
-    assert_tag :a, :content => '2',
-                   :attributes => { :href => '/projects/ecookbook/issues?page=2' }
-
-  end
-
-  def test_pagination_links_on_post_index_without_project_id_in_url
-    Setting.per_page_options = '2'
-    post '/issues', :project_id => 'ecookbook'
-
-    assert_tag :a, :content => '2',
-                   :attributes => { :href => '/projects/ecookbook/issues?page=2' }
-
-  end
-
-  def test_issue_with_user_custom_field
-    @field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :trackers => Tracker.all)
-    Role.anonymous.add_permission! :add_issues, :edit_issues
-    users = Project.find(1).users
-    tester = users.first
-
-    # Issue form
-    get '/projects/ecookbook/issues/new'
-    assert_response :success
-    assert_tag :select,
-      :attributes => {:name => "issue[custom_field_values][#{@field.id}]"},
-      :children => {:count => (users.size + 1)}, # +1 for blank value
-      :child => {
-        :tag => 'option',
-        :attributes => {:value => tester.id.to_s},
-        :content => tester.name
-      }
-
-    # Create issue
-    assert_difference 'Issue.count' do
-      post '/projects/ecookbook/issues',
-        :issue => {
-          :tracker_id => '1',
-          :priority_id => '4',
-          :subject => 'Issue with user custom field',
-          :custom_field_values => {@field.id.to_s => users.first.id.to_s}
-        }
-    end
-    issue = Issue.first(:order => 'id DESC')
-    assert_response 302
-
-    # Issue view
-    follow_redirect!
-    assert_tag :th,
-      :content => /Tester/,
-      :sibling => {
-        :tag => 'td',
-        :content => tester.name
-      }
-    assert_tag :select,
-      :attributes => {:name => "issue[custom_field_values][#{@field.id}]"},
-      :children => {:count => (users.size + 1)}, # +1 for blank value
-      :child => {
-        :tag => 'option',
-        :attributes => {:value => tester.id.to_s, :selected => 'selected'},
-        :content => tester.name
-      }
-
-    # Update issue
-    new_tester = users[1]
-    assert_difference 'Journal.count' do
-      put "/issues/#{issue.id}",
-        :notes => 'Updating custom field',
-        :issue => {
-          :custom_field_values => {@field.id.to_s => new_tester.id.to_s}
-        }
-    end
-    assert_response 302
-
-    # Issue view
-    follow_redirect!
-    assert_tag :content => 'Tester',
-      :ancestor => {:tag => 'ul', :attributes => {:class => /details/}},
-      :sibling => {
-        :content => tester.name,
-        :sibling => {
-          :content => new_tester.name
-        }
-      }
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d1/d17ed0048a8732d627b6e8e9b53ae2903c41d045.svn-base
--- a/.svn/pristine/d1/d17ed0048a8732d627b6e8e9b53ae2903c41d045.svn-base
+++ /dev/null
@@ -1,85 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Helpers
-
-    # Simple class to compute the start and end dates of a calendar
-    class Calendar
-      include Redmine::I18n
-      attr_reader :startdt, :enddt
-
-      def initialize(date, lang = current_language, period = :month)
-        @date = date
-        @events = []
-        @ending_events_by_days = {}
-        @starting_events_by_days = {}
-        set_language_if_valid lang
-        case period
-        when :month
-          @startdt = Date.civil(date.year, date.month, 1)
-          @enddt = (@startdt >> 1)-1
-          # starts from the first day of the week
-          @startdt = @startdt - (@startdt.cwday - first_wday)%7
-          # ends on the last day of the week
-          @enddt = @enddt + (last_wday - @enddt.cwday)%7
-        when :week
-          @startdt = date - (date.cwday - first_wday)%7
-          @enddt = date + (last_wday - date.cwday)%7
-        else
-          raise 'Invalid period'
-        end
-      end
-
-      # Sets calendar events
-      def events=(events)
-        @events = events
-        @ending_events_by_days = @events.group_by {|event| event.due_date}
-        @starting_events_by_days = @events.group_by {|event| event.start_date}
-      end
-
-      # Returns events for the given day
-      def events_on(day)
-        ((@ending_events_by_days[day] || []) + (@starting_events_by_days[day] || [])).uniq
-      end
-
-      # Calendar current month
-      def month
-        @date.month
-      end
-
-      # Return the first day of week
-      # 1 = Monday ... 7 = Sunday
-      def first_wday
-        case Setting.start_of_week.to_i
-        when 1
-          @first_dow ||= (1 - 1)%7 + 1
-        when 6
-          @first_dow ||= (6 - 1)%7 + 1
-        when 7
-          @first_dow ||= (7 - 1)%7 + 1
-        else
-          @first_dow ||= (l(:general_first_day_of_week).to_i - 1)%7 + 1
-        end
-      end
-
-      def last_wday
-        @last_dow ||= (first_wday + 5)%7 + 1
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d1/d1f54456cad7de7f5bbac6928b60b16922921a2a.svn-base
--- /dev/null
+++ b/.svn/pristine/d1/d1f54456cad7de7f5bbac6928b60b16922921a2a.svn-base
@@ -0,0 +1,232 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+# DO NOT MODIFY THIS FILE !!!
+# Settings can be defined through the application in Admin -> Settings
+
+app_title:
+  default: Redmine
+app_subtitle:
+  default: Project management
+welcome_text:
+  default:
+login_required:
+  default: 0
+self_registration:
+  default: '2'
+lost_password:
+  default: 1
+unsubscribe:
+  default: 1
+password_min_length:
+  format: int
+  default: 8
+# Maximum lifetime of user sessions in minutes
+session_lifetime:
+  format: int
+  default: 0
+# User session timeout in minutes
+session_timeout:
+  format: int
+  default: 0
+attachment_max_size:
+  format: int
+  default: 5120
+issues_export_limit:
+  format: int
+  default: 500
+activity_days_default:
+  format: int
+  default: 30
+per_page_options:
+  default: '25,50,100'
+mail_from:
+  default: redmine@example.net
+bcc_recipients:
+  default: 1
+plain_text_mail:
+  default: 0
+text_formatting:
+  default: textile
+cache_formatted_text:
+  default: 0
+wiki_compression:
+  default: ""
+default_language:
+  default: en
+host_name:
+  default: localhost:3000
+protocol:
+  default: http
+feeds_limit:
+  format: int
+  default: 15
+gantt_items_limit:
+  format: int
+  default: 500
+# Maximum size of files that can be displayed
+# inline through the file viewer (in KB)
+file_max_size_displayed:
+  format: int
+  default: 512
+diff_max_lines_displayed:
+  format: int
+  default: 1500
+enabled_scm:
+  serialized: true
+  default:
+  - Subversion
+  - Darcs
+  - Mercurial
+  - Cvs
+  - Bazaar
+  - Git
+autofetch_changesets:
+  default: 1
+sys_api_enabled:
+  default: 0
+sys_api_key:
+  default: ''
+commit_cross_project_ref:
+  default: 0
+commit_ref_keywords:
+  default: 'refs,references,IssueID'
+commit_fix_keywords:
+  default: 'fixes,closes'
+commit_fix_status_id:
+  format: int
+  default: 0
+commit_fix_done_ratio:
+  default: 100
+commit_logtime_enabled:
+  default: 0
+commit_logtime_activity_id:
+  format: int
+  default: 0
+# autologin duration in days
+# 0 means autologin is disabled
+autologin:
+  format: int
+  default: 0
+# date format
+date_format:
+  default: ''
+time_format:
+  default: ''
+user_format:
+  default: :firstname_lastname
+  format: symbol
+cross_project_issue_relations:
+  default: 0
+# Enables subtasks to be in other projects
+cross_project_subtasks:
+  default: 'tree'
+issue_group_assignment:
+  default: 0
+default_issue_start_date_to_creation_date:
+  default: 1
+notified_events:
+  serialized: true
+  default:
+  - issue_added
+  - issue_updated
+mail_handler_body_delimiters:
+  default: ''
+mail_handler_api_enabled:
+  default: 0
+mail_handler_api_key:
+  default:
+issue_list_default_columns:
+  serialized: true
+  default:
+  - tracker
+  - status
+  - priority
+  - subject
+  - assigned_to
+  - updated_on
+display_subprojects_issues:
+  default: 1
+issue_done_ratio:
+  default: 'issue_field'
+default_projects_public:
+  default: 1
+default_projects_modules:
+  serialized: true
+  default:
+  - issue_tracking
+  - time_tracking
+  - news
+  - documents
+  - files
+  - wiki
+  - repository
+  - boards
+  - calendar
+  - gantt
+default_projects_tracker_ids:
+  serialized: true
+  default: 
+# Role given to a non-admin user who creates a project
+new_project_user_role_id:
+  format: int
+  default: ''
+sequential_project_identifiers:
+  default: 0
+# encodings used to convert repository files content to UTF-8
+# multiple values accepted, comma separated
+repositories_encodings:
+  default: ''
+# encoding used to convert commit logs to UTF-8
+commit_logs_encoding:
+  default: 'UTF-8'
+repository_log_display_limit:
+  format: int
+  default: 100
+ui_theme:
+  default: ''
+emails_footer:
+  default: |-
+    You have received this notification because you have either subscribed to it, or are involved in it.
+    To change your notification preferences, please click here: http://hostname/my/account
+gravatar_enabled:
+  default: 0
+openid:
+  default: 0
+gravatar_default:
+  default: ''
+start_of_week:
+  default: ''
+rest_api_enabled:
+  default: 0
+jsonp_enabled:
+  default: 0
+default_notification_option:
+  default: 'only_my_events'
+emails_header:
+  default: ''
+thumbnails_enabled:
+  default: 0
+thumbnails_size:
+  format: int
+  default: 100
+non_working_week_days:
+  serialized: true
+  default:
+  - '6'
+  - '7'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d1/d1f808fff3001eb66af368407709979594e75713.svn-base
--- a/.svn/pristine/d1/d1f808fff3001eb66af368407709979594e75713.svn-base
+++ /dev/null
@@ -1,29 +0,0 @@
-# Tests in this file ensure that:
-#
-# * Routes from plugins can be routed to
-# * Named routes can be defined within a plugin
-
-require File.dirname(__FILE__) + '/../test_helper'
-
-class RoutesTest < ActionController::TestCase
-  tests TestRoutingController
-  
-	def test_WITH_a_route_defined_in_a_plugin_IT_should_route_it
-	  path = '/routes/an_action'
-    opts = {:controller => 'test_routing', :action => 'an_action'}
-    assert_routing path, opts
-    assert_recognizes opts, path # not sure what exactly the difference is, but it won't hurt either
-  end
-
-	def test_WITH_a_route_for_a_namespaced_controller_defined_in_a_plugin_IT_should_route_it
-	  path = 'somespace/routes/an_action'
-    opts = {:controller => 'namespace/test_routing', :action => 'an_action'}
-    assert_routing path, opts
-    assert_recognizes opts, path
-  end
-  
-  def test_should_properly_generate_named_routes
-    get :test_named_routes_from_plugin
-    assert_response_body '/somespace/routes'
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d1/d1fe1a10e719bee9e65cf063fc9ec9a0c05f2327.svn-base
--- /dev/null
+++ b/.svn/pristine/d1/d1fe1a10e719bee9e65cf063fc9ec9a0c05f2327.svn-base
@@ -0,0 +1,21 @@
+class AddProjectsTrackersUniqueIndex < ActiveRecord::Migration
+  def self.up
+    remove_duplicates
+    add_index :projects_trackers, [:project_id, :tracker_id], :name => :projects_trackers_unique, :unique => true
+  end
+
+  def self.down
+    remove_index :projects_trackers, :name => :projects_trackers_unique
+  end
+
+  # Removes duplicates in projects_trackers table
+  def self.remove_duplicates
+    Project.all.each do |project|
+      ids = project.trackers.collect(&:id)
+      unless ids == ids.uniq
+        project.trackers.clear
+        project.tracker_ids = ids.uniq
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d2/d229908205785bb3d05ed246eb92f48aebe96ceb.svn-base
--- a/.svn/pristine/d2/d229908205785bb3d05ed246eb92f48aebe96ceb.svn-base
+++ /dev/null
@@ -1,28 +0,0 @@
-# $Id: testpsw.rb 72 2006-04-24 21:58:14Z blackhedd $
-#
-#
-
-
-$:.unshift "lib"
-
-require 'net/ldap'
-require 'stringio'
-
-
-class TestPassword < Test::Unit::TestCase
-
-  def setup
-  end
-
-
-  def test_psw
-    assert_equal( "{MD5}xq8jwrcfibi0sZdZYNkSng==", Net::LDAP::Password.generate( :md5, "cashflow" ))
-    assert_equal( "{SHA}YE4eGkN4BvwNN1f5R7CZz0kFn14=", Net::LDAP::Password.generate( :sha, "cashflow" ))
-  end
-
-
-
-
-end
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d2/d235886576ad0af00741b82cf28f624324ebe1c5.svn-base
--- a/.svn/pristine/d2/d235886576ad0af00741b82cf28f624324ebe1c5.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-class AlphaPluginModel < ActiveRecord::Base
-  def self.report_location; TestHelper::report_location(__FILE__); end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d2/d24962e05eefa8c4a95f4bd86c0954dda018dde6.svn-base
--- a/.svn/pristine/d2/d24962e05eefa8c4a95f4bd86c0954dda018dde6.svn-base
+++ /dev/null
@@ -1,20 +0,0 @@
-# Sample plugin controller
-class ExampleController < ApplicationController
-  unloadable
-  
-  layout 'base'  
-  before_filter :find_project, :authorize
-  menu_item :sample_plugin
-    
-  def say_hello
-    @value = Setting.plugin_sample_plugin['sample_setting']
-  end
-
-  def say_goodbye
-  end
-  
-private
-  def find_project   
-    @project=Project.find(params[:id])
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d2/d24f4899353e6be2fcd4f22d01a7b5ad69fcd0bd.svn-base
--- a/.svn/pristine/d2/d24f4899353e6be2fcd4f22d01a7b5ad69fcd0bd.svn-base
+++ /dev/null
@@ -1,51 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::IssueStatusesTest < ActionController::IntegrationTest
-  fixtures :issue_statuses
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "/issue_statuses" do
-    context "GET" do
-
-      should "return issue statuses" do
-        get '/issue_statuses.xml'
-
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-        assert_tag :tag => 'issue_statuses',
-          :attributes => {:type => 'array'},
-          :child => {
-            :tag => 'issue_status',
-            :child => {
-              :tag => 'id',
-              :content => '2',
-              :sibling => {
-                :tag => 'name',
-                :content => 'Assigned'
-              }
-            }
-          }
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d2/d27acaba5e51d3baf547fd1e551a5deb117304a0.svn-base
--- a/.svn/pristine/d2/d27acaba5e51d3baf547fd1e551a5deb117304a0.svn-base
+++ /dev/null
@@ -1,461 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # This scanner is really complex, since Ruby _is_ a complex language!
-  #
-  # It tries to highlight 100% of all common code,
-  # and 90% of strange codes.
-  #
-  # It is optimized for HTML highlighting, and is not very useful for
-  # parsing or pretty printing.
-  class Ruby < Scanner
-    
-    register_for :ruby
-    file_extension 'rb'
-    
-    autoload :Patterns,    'coderay/scanners/ruby/patterns'
-    autoload :StringState, 'coderay/scanners/ruby/string_state'
-    
-    def interpreted_string_state
-      StringState.new :string, true, '"'
-    end
-    
-  protected
-    
-    def setup
-      @state = :initial
-    end
-    
-    def scan_tokens encoder, options
-      state, heredocs = options[:state] || @state
-      heredocs = heredocs.dup if heredocs.is_a?(Array)
-      
-      if state && state.instance_of?(StringState)
-        encoder.begin_group state.type
-      end
-      
-      last_state = nil
-      
-      method_call_expected = false
-      value_expected = true
-      
-      inline_block_stack = nil
-      inline_block_curly_depth = 0
-      
-      if heredocs
-        state = heredocs.shift
-        encoder.begin_group state.type
-        heredocs = nil if heredocs.empty?
-      end
-      
-      # def_object_stack = nil
-      # def_object_paren_depth = 0
-      
-      patterns = Patterns  # avoid constant lookup
-      
-      unicode = string.respond_to?(:encoding) && string.encoding.name == 'UTF-8'
-      
-      until eos?
-        
-        if state.instance_of? ::Symbol
-          
-          if match = scan(/[ \t\f\v]+/)
-            encoder.text_token match, :space
-            
-          elsif match = scan(/\n/)
-            if heredocs
-              unscan  # heredoc scanning needs \n at start
-              state = heredocs.shift
-              encoder.begin_group state.type
-              heredocs = nil if heredocs.empty?
-            else
-              state = :initial if state == :undef_comma_expected
-              encoder.text_token match, :space
-              value_expected = true
-            end
-            
-          elsif match = scan(bol? ? / \#(!)?.* | #{patterns::RUBYDOC_OR_DATA} /ox : /\#.*/)
-            encoder.text_token match, self[1] ? :doctype : :comment
-            
-          elsif match = scan(/\\\n/)
-            if heredocs
-              unscan  # heredoc scanning needs \n at start
-              encoder.text_token scan(/\\/), :space
-              state = heredocs.shift
-              encoder.begin_group state.type
-              heredocs = nil if heredocs.empty?
-            else
-              encoder.text_token match, :space
-            end
-            
-          elsif state == :initial
-            
-            # IDENTS #
-            if !method_call_expected &&
-               match = scan(unicode ? /#{patterns::METHOD_NAME}/uo :
-                                      /#{patterns::METHOD_NAME}/o)
-              value_expected = false
-              kind = patterns::IDENT_KIND[match]
-              if kind == :ident
-                if match[/\A[A-Z]/] && !(match[/[!?]$/] || match?(/\(/))
-                  kind = :constant
-                end
-              elsif kind == :keyword
-                state = patterns::KEYWORD_NEW_STATE[match]
-                value_expected = true if patterns::KEYWORDS_EXPECTING_VALUE[match]
-              end
-              value_expected = true if !value_expected && check(/#{patterns::VALUE_FOLLOWS}/o)
-              encoder.text_token match, kind
-              
-            elsif method_call_expected &&
-               match = scan(unicode ? /#{patterns::METHOD_AFTER_DOT}/uo :
-                                      /#{patterns::METHOD_AFTER_DOT}/o)
-              if method_call_expected == '::' && match[/\A[A-Z]/] && !match?(/\(/)
-                encoder.text_token match, :constant
-              else
-                encoder.text_token match, :ident
-              end
-              method_call_expected = false
-              value_expected = check(/#{patterns::VALUE_FOLLOWS}/o)
-              
-            # OPERATORS #
-            elsif !method_call_expected && match = scan(/ (\.(?!\.)|::) | (?: \.\.\.? | ==?=? | [,\(\[\{] )() | [\)\]\}] /x)
-              method_call_expected = self[1]
-              value_expected = !method_call_expected && self[2]
-              if inline_block_stack
-                case match
-                when '{'
-                  inline_block_curly_depth += 1
-                when '}'
-                  inline_block_curly_depth -= 1
-                  if inline_block_curly_depth == 0  # closing brace of inline block reached
-                    state, inline_block_curly_depth, heredocs = inline_block_stack.pop
-                    inline_block_stack = nil if inline_block_stack.empty?
-                    heredocs = nil if heredocs && heredocs.empty?
-                    encoder.text_token match, :inline_delimiter
-                    encoder.end_group :inline
-                    next
-                  end
-                end
-              end
-              encoder.text_token match, :operator
-              
-            elsif match = scan(unicode ? /#{patterns::SYMBOL}/uo :
-                                         /#{patterns::SYMBOL}/o)
-              case delim = match[1]
-              when ?', ?"
-                encoder.begin_group :symbol
-                encoder.text_token ':', :symbol
-                match = delim.chr
-                encoder.text_token match, :delimiter
-                state = self.class::StringState.new :symbol, delim == ?", match
-              else
-                encoder.text_token match, :symbol
-                value_expected = false
-              end
-              
-            elsif match = scan(/ ' (?:(?>[^'\\]*) ')? | " (?:(?>[^"\\\#]*) ")? /mx)
-              encoder.begin_group :string
-              if match.size == 1
-                encoder.text_token match, :delimiter
-                state = self.class::StringState.new :string, match == '"', match  # important for streaming
-              else
-                encoder.text_token match[0,1], :delimiter
-                encoder.text_token match[1..-2], :content if match.size > 2
-                encoder.text_token match[-1,1], :delimiter
-                encoder.end_group :string
-                value_expected = false
-              end
-              
-            elsif match = scan(unicode ? /#{patterns::INSTANCE_VARIABLE}/uo :
-                                         /#{patterns::INSTANCE_VARIABLE}/o)
-              value_expected = false
-              encoder.text_token match, :instance_variable
-              
-            elsif value_expected && match = scan(/\//)
-              encoder.begin_group :regexp
-              encoder.text_token match, :delimiter
-              state = self.class::StringState.new :regexp, true, '/'
-              
-            elsif match = scan(value_expected ? /[-+]?#{patterns::NUMERIC}/o : /#{patterns::NUMERIC}/o)
-              if method_call_expected
-                encoder.text_token match, :error
-                method_call_expected = false
-              else
-                encoder.text_token match, self[1] ? :float : :integer  # TODO: send :hex/:octal/:binary
-              end
-              value_expected = false
-              
-            elsif match = scan(/ [-+!~^\/]=? | [:;] | [*|&]{1,2}=? | >>? /x)
-              value_expected = true
-              encoder.text_token match, :operator
-              
-            elsif value_expected && match = scan(/#{patterns::HEREDOC_OPEN}/o)
-              quote = self[3]
-              delim = self[quote ? 4 : 2]
-              kind = patterns::QUOTE_TO_TYPE[quote]
-              encoder.begin_group kind
-              encoder.text_token match, :delimiter
-              encoder.end_group kind
-              heredocs ||= []  # create heredocs if empty
-              heredocs << self.class::StringState.new(kind, quote != "'", delim,
-                self[1] == '-' ? :indented : :linestart)
-              value_expected = false
-              
-            elsif value_expected && match = scan(/#{patterns::FANCY_STRING_START}/o)
-              kind = patterns::FANCY_STRING_KIND[self[1]]
-              encoder.begin_group kind
-              state = self.class::StringState.new kind, patterns::FANCY_STRING_INTERPRETED[self[1]], self[2]
-              encoder.text_token match, :delimiter
-              
-            elsif value_expected && match = scan(/#{patterns::CHARACTER}/o)
-              value_expected = false
-              encoder.text_token match, :integer
-              
-            elsif match = scan(/ %=? | <(?:<|=>?)? | \? /x)
-              value_expected = true
-              encoder.text_token match, :operator
-              
-            elsif match = scan(/`/)
-              encoder.begin_group :shell
-              encoder.text_token match, :delimiter
-              state = self.class::StringState.new :shell, true, match
-              
-            elsif match = scan(unicode ? /#{patterns::GLOBAL_VARIABLE}/uo :
-                                         /#{patterns::GLOBAL_VARIABLE}/o)
-              encoder.text_token match, :global_variable
-              value_expected = false
-              
-            elsif match = scan(unicode ? /#{patterns::CLASS_VARIABLE}/uo :
-                                         /#{patterns::CLASS_VARIABLE}/o)
-              encoder.text_token match, :class_variable
-              value_expected = false
-              
-            elsif match = scan(/\\\z/)
-              encoder.text_token match, :space
-              
-            else
-              if method_call_expected
-                method_call_expected = false
-                next
-              end
-              unless unicode
-                # check for unicode
-                $DEBUG_BEFORE, $DEBUG = $DEBUG, false
-                begin
-                  if check(/./mu).size > 1
-                    # seems like we should try again with unicode
-                    unicode = true
-                  end
-                rescue
-                  # bad unicode char; use getch
-                ensure
-                  $DEBUG = $DEBUG_BEFORE
-                end
-                next if unicode
-              end
-              
-              encoder.text_token getch, :error
-              
-            end
-            
-            if last_state
-              state = last_state
-              last_state = nil
-            end
-            
-          elsif state == :def_expected
-            if match = scan(unicode ? /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/uo :
-                                      /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/o)
-              encoder.text_token match, :method
-              state = :initial
-            else
-              last_state = :dot_expected
-              state = :initial
-            end
-            
-          elsif state == :dot_expected
-            if match = scan(/\.|::/)
-              # invalid definition
-              state = :def_expected
-              encoder.text_token match, :operator
-            else
-              state = :initial
-            end
-            
-          elsif state == :module_expected
-            if match = scan(/<</)
-              encoder.text_token match, :operator
-            else
-              state = :initial
-              if match = scan(unicode ? / (?:#{patterns::IDENT}::)* #{patterns::IDENT} /oux :
-                                        / (?:#{patterns::IDENT}::)* #{patterns::IDENT} /ox)
-                encoder.text_token match, :class
-              end
-            end
-            
-          elsif state == :undef_expected
-            state = :undef_comma_expected
-            if match = scan(unicode ? /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/uo :
-                                      /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/o)
-              encoder.text_token match, :method
-            elsif match = scan(/#{patterns::SYMBOL}/o)
-              case delim = match[1]
-              when ?', ?"
-                encoder.begin_group :symbol
-                encoder.text_token ':', :symbol
-                match = delim.chr
-                encoder.text_token match, :delimiter
-                state = self.class::StringState.new :symbol, delim == ?", match
-                state.next_state = :undef_comma_expected
-              else
-                encoder.text_token match, :symbol
-              end
-            else
-              state = :initial
-            end
-            
-          elsif state == :undef_comma_expected
-            if match = scan(/,/)
-              encoder.text_token match, :operator
-              state = :undef_expected
-            else
-              state = :initial
-            end
-            
-          elsif state == :alias_expected
-            match = scan(unicode ? /(#{patterns::METHOD_NAME_OR_SYMBOL})([ \t]+)(#{patterns::METHOD_NAME_OR_SYMBOL})/uo :
-                                   /(#{patterns::METHOD_NAME_OR_SYMBOL})([ \t]+)(#{patterns::METHOD_NAME_OR_SYMBOL})/o)
-            
-            if match
-              encoder.text_token self[1], (self[1][0] == ?: ? :symbol : :method)
-              encoder.text_token self[2], :space
-              encoder.text_token self[3], (self[3][0] == ?: ? :symbol : :method)
-            end
-            state = :initial
-            
-          else
-            #:nocov:
-            raise_inspect 'Unknown state: %p' % [state], encoder
-            #:nocov:
-          end
-          
-        else  # StringState
-          
-          match = scan_until(state.pattern) || scan_rest
-          unless match.empty?
-            encoder.text_token match, :content
-            break if eos?
-          end
-          
-          if state.heredoc && self[1]  # end of heredoc
-            match = getch
-            match << scan_until(/$/) unless eos?
-            encoder.text_token match, :delimiter unless match.empty?
-            encoder.end_group state.type
-            state = state.next_state
-            next
-          end
-          
-          case match = getch
-          
-          when state.delim
-            if state.paren_depth
-              state.paren_depth -= 1
-              if state.paren_depth > 0
-                encoder.text_token match, :content
-                next
-              end
-            end
-            encoder.text_token match, :delimiter
-            if state.type == :regexp && !eos?
-              match = scan(/#{patterns::REGEXP_MODIFIERS}/o)
-              encoder.text_token match, :modifier unless match.empty?
-            end
-            encoder.end_group state.type
-            value_expected = false
-            state = state.next_state
-            
-          when '\\'
-            if state.interpreted
-              if esc = scan(/#{patterns::ESCAPE}/o)
-                encoder.text_token match + esc, :char
-              else
-                encoder.text_token match, :error
-              end
-            else
-              case esc = getch
-              when nil
-                encoder.text_token match, :content
-              when state.delim, '\\'
-                encoder.text_token match + esc, :char
-              else
-                encoder.text_token match + esc, :content
-              end
-            end
-            
-          when '#'
-            case peek(1)
-            when '{'
-              inline_block_stack ||= []
-              inline_block_stack << [state, inline_block_curly_depth, heredocs]
-              value_expected = true
-              state = :initial
-              inline_block_curly_depth = 1
-              encoder.begin_group :inline
-              encoder.text_token match + getch, :inline_delimiter
-            when '$', '@'
-              encoder.text_token match, :escape
-              last_state = state
-              state = :initial
-            else
-              #:nocov:
-              raise_inspect 'else-case # reached; #%p not handled' % [peek(1)], encoder
-              #:nocov:
-            end
-            
-          when state.opening_paren
-            state.paren_depth += 1
-            encoder.text_token match, :content
-            
-          else
-            #:nocov
-            raise_inspect 'else-case " reached; %p not handled, state = %p' % [match, state], encoder
-            #:nocov:
-            
-          end
-          
-        end
-        
-      end
-      
-      # cleaning up
-      if state.is_a? StringState
-        encoder.end_group state.type
-      end
-      
-      if options[:keep_state]
-        if state.is_a?(StringState) && state.heredoc
-          (heredocs ||= []).unshift state
-          state = :initial
-        elsif heredocs && heredocs.empty?
-          heredocs = nil
-        end
-        @state = state, heredocs
-      end
-      
-      if inline_block_stack
-        until inline_block_stack.empty?
-          state, = *inline_block_stack.pop
-          encoder.end_group :inline
-          encoder.end_group state.type
-        end
-      end
-      
-      encoder
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d2/d2ab451eb617526d561093c390e63e0839289e3b.svn-base
--- a/.svn/pristine/d2/d2ab451eb617526d561093c390e63e0839289e3b.svn-base
+++ /dev/null
@@ -1,84 +0,0 @@
-require 'test/unit'
-require File.expand_path('../../lib/assert_warning', __FILE__)
-
-$:.unshift File.expand_path('../../../lib', __FILE__)
-require 'coderay'
-
-begin
-  require 'rubygems' unless defined? Gem
-  gem 'RedCloth', '>= 4.0.3' rescue nil
-  require 'redcloth'
-rescue LoadError
-  warn 'RedCloth not found - skipping for_redcloth tests.'
-  undef RedCloth if defined? RedCloth
-end
-
-class BasicTest < Test::Unit::TestCase
-  
-  def test_for_redcloth
-    require 'coderay/for_redcloth'
-    assert_equal "<p><span lang=\"ruby\" class=\"CodeRay\">puts <span style=\"background-color:hsla(0,100%,50%,0.05)\"><span style=\"color:#710\">&quot;</span><span style=\"color:#D20\">Hello, World!</span><span style=\"color:#710\">&quot;</span></span></span></p>",
-      RedCloth.new('@[ruby]puts "Hello, World!"@').to_html
-    assert_equal <<-BLOCKCODE.chomp,
-<div lang="ruby" class="CodeRay">
-  <div class="code"><pre>puts <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Hello, World!</span><span style="color:#710">&quot;</span></span></pre></div>
-</div>
-      BLOCKCODE
-      RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html
-  end
-  
-  def test_for_redcloth_no_lang
-    require 'coderay/for_redcloth'
-    assert_equal "<p><code>puts \"Hello, World!\"</code></p>",
-      RedCloth.new('@puts "Hello, World!"@').to_html
-    assert_equal <<-BLOCKCODE.chomp,
-<pre><code>puts \"Hello, World!\"</code></pre>
-      BLOCKCODE
-      RedCloth.new('bc. puts "Hello, World!"').to_html
-  end
-  
-  def test_for_redcloth_style
-    require 'coderay/for_redcloth'
-    assert_equal <<-BLOCKCODE.chomp,
-<pre style=\"color: red;\"><code style=\"color: red;\">puts \"Hello, World!\"</code></pre>
-      BLOCKCODE
-      RedCloth.new('bc{color: red}. puts "Hello, World!"').to_html
-  end
-  
-  def test_for_redcloth_escapes
-    require 'coderay/for_redcloth'
-    assert_equal '<p><span lang="ruby" class="CodeRay">&gt;</span></p>',
-      RedCloth.new('@[ruby]>@').to_html
-    assert_equal <<-BLOCKCODE.chomp,
-<div lang="ruby" class="CodeRay">
-  <div class="code"><pre>&amp;</pre></div>
-</div>
-      BLOCKCODE
-      RedCloth.new('bc[ruby]. &').to_html
-  end
-  
-  def test_for_redcloth_escapes2
-    require 'coderay/for_redcloth'
-    assert_equal "<p><span lang=\"c\" class=\"CodeRay\"><span style=\"color:#579\">#include</span> <span style=\"color:#B44;font-weight:bold\">&lt;test.h&gt;</span></span></p>",
-      RedCloth.new('@[c]#include <test.h>@').to_html
-  end
-  
-  # See http://jgarber.lighthouseapp.com/projects/13054/tickets/124-code-markup-does-not-allow-brackets.
-  def test_for_redcloth_false_positive
-    require 'coderay/for_redcloth'
-    assert_warning 'CodeRay::Scanners could not load plugin :project; falling back to :text' do
-      assert_equal '<p><code>[project]_dff.skjd</code></p>',
-        RedCloth.new('@[project]_dff.skjd@').to_html
-    end
-    # false positive, but expected behavior / known issue
-    assert_equal "<p><span lang=\"ruby\" class=\"CodeRay\">_dff.skjd</span></p>",
-      RedCloth.new('@[ruby]_dff.skjd@').to_html
-    assert_warning 'CodeRay::Scanners could not load plugin :project; falling back to :text' do
-      assert_equal <<-BLOCKCODE.chomp,
-<pre><code>[project]_dff.skjd</code></pre>
-        BLOCKCODE
-        RedCloth.new('bc. [project]_dff.skjd').to_html
-    end
-  end
-  
-end if defined? RedCloth
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d2/d2bd0bf95ab05008a71c2b2b37ad8bf69fcda9be.svn-base
--- a/.svn/pristine/d2/d2bd0bf95ab05008a71c2b2b37ad8bf69fcda9be.svn-base
+++ /dev/null
@@ -1,77 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class MenuManagerTest < ActionController::IntegrationTest
-  include Redmine::I18n
-
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows
-
-  def test_project_menu_with_specific_locale
-    get 'projects/ecookbook/issues', { }, 'Accept-Language' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
-
-    assert_tag :div, :attributes => { :id => 'main-menu' },
-                     :descendant => { :tag => 'li', :child => { :tag => 'a', :content => ll('fr', :label_activity),
-                                                                             :attributes => { :href => '/projects/ecookbook/activity',
-                                                                                              :class => 'activity' } } }
-    assert_tag :div, :attributes => { :id => 'main-menu' },
-                     :descendant => { :tag => 'li', :child => { :tag => 'a', :content => ll('fr', :label_issue_plural),
-                                                                             :attributes => { :href => '/projects/ecookbook/issues',
-                                                                                              :class => 'issues selected' } } }
-  end
-
-  def test_project_menu_with_additional_menu_items
-    Setting.default_language = 'en'
-    assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do
-      Redmine::MenuManager.map :project_menu do |menu|
-        menu.push :foo, { :controller => 'projects', :action => 'show' }, :caption => 'Foo'
-        menu.push :bar, { :controller => 'projects', :action => 'show' }, :before => :activity
-        menu.push :hello, { :controller => 'projects', :action => 'show' }, :caption => Proc.new {|p| p.name.upcase }, :after => :bar
-      end
-
-      get 'projects/ecookbook'
-      assert_tag :div, :attributes => { :id => 'main-menu' },
-                       :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Foo',
-                                                                               :attributes => { :class => 'foo' } } }
-
-      assert_tag :div, :attributes => { :id => 'main-menu' },
-                       :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Bar',
-                                                                               :attributes => { :class => 'bar' } },
-                                                      :before => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' } } }
-
-      assert_tag :div, :attributes => { :id => 'main-menu' },
-                       :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK',
-                                                                               :attributes => { :class => 'hello' } },
-                                                      :before => { :tag => 'li', :child => { :tag => 'a', :content => 'Activity' } } }
-
-      # Remove the menu items
-      Redmine::MenuManager.map :project_menu do |menu|
-        menu.delete :foo
-        menu.delete :bar
-        menu.delete :hello
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d2/d2f1b8e2151a17fc86ef289127a063bc9d150c8c.svn-base
--- a/.svn/pristine/d2/d2f1b8e2151a17fc86ef289127a063bc9d150c8c.svn-base
+++ /dev/null
@@ -1,408 +0,0 @@
-require File.expand_path('../../../../../../test_helper', __FILE__)
-begin
-  require 'mocha'
-
-  class MercurialAdapterTest < ActiveSupport::TestCase
-    HELPERS_DIR        = Redmine::Scm::Adapters::MercurialAdapter::HELPERS_DIR
-    TEMPLATE_NAME      = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_NAME
-    TEMPLATE_EXTENSION = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_EXTENSION
-
-    REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
-    CHAR_1_HEX = "\xc3\x9c"
-
-    if File.directory?(REPOSITORY_PATH)
-      def setup
-        adapter_class = Redmine::Scm::Adapters::MercurialAdapter
-        assert adapter_class
-        assert adapter_class.client_command
-        assert_equal true, adapter_class.client_available
-        assert_equal true, adapter_class.client_version_above?([0, 9, 5])
-
-        @adapter = Redmine::Scm::Adapters::MercurialAdapter.new(
-                              REPOSITORY_PATH,
-                              nil,
-                              nil,
-                              nil,
-                             'ISO-8859-1')
-        @diff_c_support = true
-        @char_1        = CHAR_1_HEX.dup
-        @tag_char_1    = "tag-#{CHAR_1_HEX}-00"
-        @branch_char_0 = "branch-#{CHAR_1_HEX}-00"
-        @branch_char_1 = "branch-#{CHAR_1_HEX}-01"
-        if @tag_char_1.respond_to?(:force_encoding)
-          @char_1.force_encoding('UTF-8')
-          @tag_char_1.force_encoding('UTF-8')
-          @branch_char_0.force_encoding('UTF-8')
-          @branch_char_1.force_encoding('UTF-8')
-        end
-      end
-
-      def test_hgversion
-        to_test = { "Mercurial Distributed SCM (version 0.9.5)\n"  => [0,9,5],
-                    "Mercurial Distributed SCM (1.0)\n"            => [1,0],
-                    "Mercurial Distributed SCM (1e4ddc9ac9f7+20080325)\n" => nil,
-                    "Mercurial Distributed SCM (1.0.1+20080525)\n" => [1,0,1],
-                    "Mercurial Distributed SCM (1916e629a29d)\n"   => nil,
-                    "Mercurial SCM Distribuito (versione 0.9.5)\n" => [0,9,5],
-                    "(1.6)\n(1.7)\n(1.8)"                          => [1,6],
-                    "(1.7.1)\r\n(1.8.1)\r\n(1.9.1)"                => [1,7,1]}
-
-        to_test.each do |s, v|
-          test_hgversion_for(s, v)
-        end
-      end
-
-      def test_template_path
-        to_test = {
-                    [1,2]    => "1.0",
-                    []       => "1.0",
-                    [1,2,1]  => "1.0",
-                    [1,7]    => "1.0",
-                    [1,7,1]  => "1.0",
-                    [2,0]    => "1.0",
-                   }
-        to_test.each do |v, template|
-          test_template_path_for(v, template)
-        end
-      end
-
-      def test_info
-        [REPOSITORY_PATH, REPOSITORY_PATH + "/",
-             REPOSITORY_PATH + "//"].each do |repo|
-          adp = Redmine::Scm::Adapters::MercurialAdapter.new(repo)
-          repo_path =  adp.info.root_url.gsub(/\\/, "/")
-          assert_equal REPOSITORY_PATH, repo_path
-          assert_equal '31', adp.info.lastrev.revision
-          assert_equal '31eeee7395c8',adp.info.lastrev.scmid
-        end
-      end
-
-      def test_revisions
-        revisions = @adapter.revisions(nil, 2, 4)
-        assert_equal 3, revisions.size
-        assert_equal '2', revisions[0].revision
-        assert_equal '400bb8672109', revisions[0].scmid
-        assert_equal '4', revisions[2].revision
-        assert_equal 'def6d2f1254a', revisions[2].scmid
-
-        revisions = @adapter.revisions(nil, 2, 4, {:limit => 2})
-        assert_equal 2, revisions.size
-        assert_equal '2', revisions[0].revision
-        assert_equal '400bb8672109', revisions[0].scmid
-      end
-
-      def test_parents
-        revs1 = @adapter.revisions(nil, 0, 0)
-        assert_equal 1, revs1.size
-        assert_equal [], revs1[0].parents
-        revs2 = @adapter.revisions(nil, 1, 1)
-        assert_equal 1, revs2.size
-        assert_equal 1, revs2[0].parents.size
-        assert_equal "0885933ad4f6", revs2[0].parents[0]
-        revs3 = @adapter.revisions(nil, 30, 30)
-        assert_equal 1, revs3.size
-        assert_equal 2, revs3[0].parents.size
-        assert_equal "a94b0528f24f", revs3[0].parents[0]
-        assert_equal "3a330eb32958", revs3[0].parents[1]
-      end
-
-      def test_diff
-        if @adapter.class.client_version_above?([1, 2])
-          assert_nil @adapter.diff(nil, '100000')
-        end
-        assert_nil @adapter.diff(nil, '100000', '200000')
-        [2, '400bb8672109', '400', 400].each do |r1|
-          diff1 = @adapter.diff(nil, r1)
-          if @diff_c_support
-            assert_equal 28, diff1.size
-            buf = diff1[24].gsub(/\r\n|\r|\n/, "")
-            assert_equal "+    return true unless klass.respond_to?('watched_by')", buf
-          else
-            assert_equal 0, diff1.size
-          end
-          [4, 'def6d2f1254a'].each do |r2|
-            diff2 = @adapter.diff(nil,r1,r2)
-            assert_equal 49, diff2.size
-            buf =  diff2[41].gsub(/\r\n|\r|\n/, "")
-            assert_equal "+class WelcomeController < ApplicationController", buf
-            diff3 = @adapter.diff('sources/watchers_controller.rb', r1, r2)
-            assert_equal 20, diff3.size
-            buf =  diff3[12].gsub(/\r\n|\r|\n/, "")
-            assert_equal "+    @watched.remove_watcher(user)", buf
-          end
-        end
-      end
-
-      def test_diff_made_by_revision
-        if @diff_c_support
-          [24, '24', '4cddb4e45f52'].each do |r1|
-            diff1 = @adapter.diff(nil, r1)
-            assert_equal 5, diff1.size
-            buf = diff1[4].gsub(/\r\n|\r|\n/, "")
-            assert_equal '+0885933ad4f68d77c2649cd11f8311276e7ef7ce tag-init-revision', buf
-          end
-        end
-      end
-
-      def test_cat
-        [2, '400bb8672109', '400', 400].each do |r|
-          buf = @adapter.cat('sources/welcome_controller.rb', r)
-          assert buf
-          lines = buf.split("\r\n")
-          assert_equal 25, lines.length
-          assert_equal 'class WelcomeController < ApplicationController', lines[17]
-        end
-        assert_nil @adapter.cat('sources/welcome_controller.rb')
-      end
-
-      def test_annotate
-        assert_equal [], @adapter.annotate("sources/welcome_controller.rb").lines
-        [2, '400bb8672109', '400', 400].each do |r|
-          ann = @adapter.annotate('sources/welcome_controller.rb', r)
-          assert ann
-          assert_equal '1', ann.revisions[17].revision
-          assert_equal '9d5b5b004199', ann.revisions[17].identifier
-          assert_equal 'jsmith', ann.revisions[0].author
-          assert_equal 25, ann.lines.length
-          assert_equal 'class WelcomeController < ApplicationController', ann.lines[17]
-        end
-      end
-
-      def test_entries
-        assert_nil @adapter.entries(nil, '100000')
-
-        assert_equal 1, @adapter.entries("sources", 3).size
-        assert_equal 1, @adapter.entries("sources", 'b3a615152df8').size
-
-        [2, '400bb8672109', '400', 400].each do |r|
-          entries1 = @adapter.entries(nil, r)
-          assert entries1
-          assert_equal 3, entries1.size
-          assert_equal 'sources', entries1[1].name
-          assert_equal 'sources', entries1[1].path
-          assert_equal 'dir', entries1[1].kind
-          readme = entries1[2]
-          assert_equal 'README', readme.name
-          assert_equal 'README', readme.path
-          assert_equal 'file', readme.kind
-          assert_equal 27, readme.size
-          assert_equal '1', readme.lastrev.revision
-          assert_equal '9d5b5b004199', readme.lastrev.identifier
-          # 2007-12-14 10:24:01 +0100
-          assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time
-
-          entries2 = @adapter.entries('sources', r)
-          assert entries2
-          assert_equal 2, entries2.size
-          assert_equal 'watchers_controller.rb', entries2[0].name
-          assert_equal 'sources/watchers_controller.rb', entries2[0].path
-          assert_equal 'file', entries2[0].kind
-          assert_equal 'welcome_controller.rb', entries2[1].name
-          assert_equal 'sources/welcome_controller.rb', entries2[1].path
-          assert_equal 'file', entries2[1].kind
-        end
-      end
-
-      def test_entries_tag
-        entries1 = @adapter.entries(nil, 'tag_test.00')
-        assert entries1
-        assert_equal 3, entries1.size
-        assert_equal 'sources', entries1[1].name
-        assert_equal 'sources', entries1[1].path
-        assert_equal 'dir', entries1[1].kind
-        readme = entries1[2]
-        assert_equal 'README', readme.name
-        assert_equal 'README', readme.path
-        assert_equal 'file', readme.kind
-        assert_equal 21, readme.size
-        assert_equal '0', readme.lastrev.revision
-        assert_equal '0885933ad4f6', readme.lastrev.identifier
-        # 2007-12-14 10:22:52 +0100
-        assert_equal Time.gm(2007, 12, 14, 9, 22, 52), readme.lastrev.time
-      end
-
-      def test_entries_branch
-        entries1 = @adapter.entries(nil, 'test-branch-00')
-        assert entries1
-        assert_equal 5, entries1.size
-        assert_equal 'sql_escape', entries1[2].name
-        assert_equal 'sql_escape', entries1[2].path
-        assert_equal 'dir', entries1[2].kind
-        readme = entries1[4]
-        assert_equal 'README', readme.name
-        assert_equal 'README', readme.path
-        assert_equal 'file', readme.kind
-        assert_equal 365, readme.size
-        assert_equal '8', readme.lastrev.revision
-        assert_equal 'c51f5bb613cd', readme.lastrev.identifier
-        # 2001-02-01 00:00:00 -0900
-        assert_equal Time.gm(2001, 2, 1, 9, 0, 0), readme.lastrev.time
-      end
-
-      def test_locate_on_outdated_repository
-        assert_equal 1, @adapter.entries("images", 0).size
-        assert_equal 2, @adapter.entries("images").size
-        assert_equal 2, @adapter.entries("images", 2).size
-      end
-
-      def test_access_by_nodeid
-        path = 'sources/welcome_controller.rb'
-        assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400bb8672109')
-      end
-
-      def test_access_by_fuzzy_nodeid
-        path = 'sources/welcome_controller.rb'
-        # falls back to nodeid
-        assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400')
-      end
-
-      def test_tags
-        assert_equal [@tag_char_1, 'tag_test.00', 'tag-init-revision'], @adapter.tags
-      end
-
-      def test_tagmap
-        tm = {
-          @tag_char_1         => 'adf805632193',
-          'tag_test.00'       => '6987191f453a',
-          'tag-init-revision' => '0885933ad4f6',
-          }
-        assert_equal tm, @adapter.tagmap
-      end
-
-      def test_branches
-        brs = []
-        @adapter.branches.each do |b|
-          brs << b
-        end
-        assert_equal 7, brs.length
-        assert_equal 'default', brs[0].to_s
-        assert_equal '31', brs[0].revision
-        assert_equal '31eeee7395c8', brs[0].scmid
-        assert_equal 'test-branch-01', brs[1].to_s
-        assert_equal '30', brs[1].revision
-        assert_equal 'ad4dc4f80284', brs[1].scmid
-        assert_equal @branch_char_1, brs[2].to_s
-        assert_equal '27', brs[2].revision
-        assert_equal '7bbf4c738e71', brs[2].scmid
-        assert_equal 'branch (1)[2]&,%.-3_4', brs[3].to_s
-        assert_equal '25', brs[3].revision
-        assert_equal 'afc61e85bde7', brs[3].scmid
-        assert_equal @branch_char_0, brs[4].to_s
-        assert_equal '23', brs[4].revision
-        assert_equal 'c8d3e4887474', brs[4].scmid
-        assert_equal 'test_branch.latin-1', brs[5].to_s
-        assert_equal '22', brs[5].revision
-        assert_equal 'c2ffe7da686a', brs[5].scmid
-        assert_equal 'test-branch-00', brs[6].to_s
-        assert_equal '13', brs[6].revision
-        assert_equal '3a330eb32958', brs[6].scmid
-      end
-
-      def test_branchmap
-        bm = {
-           'default'               => '31eeee7395c8',
-           'test_branch.latin-1'   => 'c2ffe7da686a',
-           'branch (1)[2]&,%.-3_4' => 'afc61e85bde7',
-           'test-branch-00'        => '3a330eb32958',
-           "test-branch-01"        => 'ad4dc4f80284',
-           @branch_char_0          => 'c8d3e4887474',
-           @branch_char_1          => '7bbf4c738e71',
-         }
-        assert_equal bm, @adapter.branchmap
-      end
-
-      def test_path_space
-        p = 'README (1)[2]&,%.-3_4'
-        [15, '933ca60293d7'].each do |r1|
-          assert @adapter.diff(p, r1)
-          assert @adapter.cat(p, r1)
-          assert_equal 1, @adapter.annotate(p, r1).lines.length
-          [25, 'afc61e85bde7'].each do |r2|
-            assert @adapter.diff(p, r1, r2)
-          end
-        end
-      end
-
-      def test_tag_non_ascii
-        p = "latin-1-dir/test-#{@char_1}-1.txt"
-        assert @adapter.cat(p, @tag_char_1)
-        assert_equal 1, @adapter.annotate(p, @tag_char_1).lines.length
-      end
-
-      def test_branch_non_ascii
-        p = "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-1.txt"
-        assert @adapter.cat(p, @branch_char_1)
-        assert_equal 1, @adapter.annotate(p, @branch_char_1).lines.length
-      end
-
-      def test_nodes_in_branch
-         [
-            'default',
-            @branch_char_1,
-            'branch (1)[2]&,%.-3_4',
-            @branch_char_0,
-            'test_branch.latin-1',
-            'test-branch-00',
-               ].each do |bra|
-          nib0 = @adapter.nodes_in_branch(bra)
-          assert nib0
-          nib1 = @adapter.nodes_in_branch(bra, :limit => 1)
-          assert_equal 1, nib1.size
-          case bra
-            when 'branch (1)[2]&,%.-3_4'
-              if @adapter.class.client_version_above?([1, 6])
-                assert_equal 3, nib0.size
-                assert_equal nib0[0], 'afc61e85bde7'
-                nib2 = @adapter.nodes_in_branch(bra, :limit => 2)
-                assert_equal 2, nib2.size
-                assert_equal nib2[1], '933ca60293d7'
-              end
-            when @branch_char_1
-              if @adapter.class.client_version_above?([1, 6])
-                assert_equal 2, nib0.size
-                assert_equal nib0[1], '08ff3227303e'
-                nib2 = @adapter.nodes_in_branch(bra, :limit => 1)
-                assert_equal 1, nib2.size
-                assert_equal nib2[0], '7bbf4c738e71'
-              end
-          end
-        end
-      end
-
-      def test_path_encoding_default_utf8
-        adpt1 = Redmine::Scm::Adapters::MercurialAdapter.new(
-                                  REPOSITORY_PATH
-                                )
-        assert_equal "UTF-8", adpt1.path_encoding
-        adpt2 = Redmine::Scm::Adapters::MercurialAdapter.new(
-                                  REPOSITORY_PATH,
-                                  nil,
-                                  nil,
-                                  nil,
-                                  ""
-                                )
-        assert_equal "UTF-8", adpt2.path_encoding
-      end
-
-      private
-
-      def test_hgversion_for(hgversion, version)
-        @adapter.class.expects(:hgversion_from_command_line).returns(hgversion)
-        assert_equal version, @adapter.class.hgversion
-      end
-
-      def test_template_path_for(version, template)
-        assert_equal "#{HELPERS_DIR}/#{TEMPLATE_NAME}-#{template}.#{TEMPLATE_EXTENSION}",
-                     @adapter.class.template_path_for(version)
-        assert File.exist?(@adapter.class.template_path_for(version))
-      end
-    else
-      puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!"
-      def test_fake; assert true end
-    end
-  end
-rescue LoadError
-  class MercurialMochaFake < ActiveSupport::TestCase
-    def test_fake; assert(false, "Requires mocha to run those tests")  end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d4/d4053288db720e7328efde6be5005ae9fef364cf.svn-base
--- a/.svn/pristine/d4/d4053288db720e7328efde6be5005ae9fef364cf.svn-base
+++ /dev/null
@@ -1,131 +0,0 @@
-# binarytree.rb
-#
-# $Revision: 1.5 $ by $Author: anupamsg $
-# $Name:  $
-#
-# = binarytree.rb - Binary Tree implementation
-#
-# Provides a generic tree data structure with ability to
-# store keyed node elements in the tree. The implementation
-# mixes in the Enumerable module.
-#
-# Author:: Anupam Sengupta (anupamsg@gmail.com)
-#
-
-# Copyright (c) 2007 Anupam Sengupta
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without modification,
-# are permitted provided that the following conditions are met:
-#
-# - Redistributions of source code must retain the above copyright notice, this
-#   list of conditions and the following disclaimer.
-#
-# - Redistributions in binary form must reproduce the above copyright notice, this
-#   list of conditions and the following disclaimer in the documentation and/or
-#   other materials provided with the distribution.
-#
-# - Neither the name of the organization nor the names of its contributors may
-#   be used to endorse or promote products derived from this software without
-#   specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-require 'tree'
-
-module Tree
-
-  # Provides a Binary tree implementation. This tree node allows only two child
-  # nodes (left and right childs). It also provides direct access to the left
-  # and right children, including assignment to the same.
-  class BinaryTreeNode < TreeNode
-
-    # Adds the specified child node to the receiver node.  The child node's
-    # parent is set to be the receiver.  The child nodes are added in the order
-    # of addition, i.e., the first child added becomes the left node, and the
-    # second child will be the second node.
-    # If only one child is present, then this will be the left child.
-    def add(child)
-      raise "Already has two child nodes" if @children.size == 2
-
-      super(child)
-    end
-
-    # Returns the left child node. Note that
-    # left Child == first Child
-    def leftChild
-      children.first
-    end
-
-    # Returns the right child node. Note that
-    # right child == last child unless there is only one child.
-    # Returns nil if the right child does not exist.
-    def rightChild
-      children[1]
-    end
-
-    # Sets the left child. If a previous child existed, it is replaced.
-    def leftChild=(child)
-      @children[0] = child
-      @childrenHash[child.name] = child if child # Assign the name mapping
-    end
-
-    # Sets the right child. If a previous child existed, it is replaced.
-    def rightChild=(child)
-      @children[1] = child
-      @childrenHash[child.name] = child if child # Assign the name mapping
-    end
-
-    # Returns true if this is the left child of its parent. Always returns false
-    # if this is the root node.
-    def isLeftChild?
-      return nil if isRoot?
-      self == parent.leftChild
-    end
-
-    # Returns true if this is the right child of its parent. Always returns false
-    # if this is the root node.
-    def isRightChild?
-      return nil if isRoot?
-      self == parent.rightChild
-    end
-
-    # Swaps the left and right children with each other
-    def swap_children
-      tempChild = leftChild
-      self.leftChild= rightChild
-      self.rightChild= tempChild
-    end
-  end
-
-end
-
-# $Log: binarytree.rb,v $
-# Revision 1.5  2007/12/18 23:11:29  anupamsg
-# Minor documentation changes in the binarytree class.
-#
-# Revision 1.4  2007/08/30 22:08:58  anupamsg
-# Added a new swap_children method for Binary Tree. Also added minor
-# documentation and test updates.
-#
-# Revision 1.3  2007/07/21 03:24:25  anupamsg
-# Minor edits to parameter names. User visible functionality does not change.
-#
-# Revision 1.2  2007/07/18 20:15:06  anupamsg
-# Added two predicate methods in BinaryTreeNode to determine whether a node
-# is a left or a right node.
-#
-# Revision 1.1  2007/07/18 19:33:27  anupamsg
-# Added a new binary tree implementation.
-#
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d4/d40bacc3af8fb7641b23c992be523d5d162b016d.svn-base
--- /dev/null
+++ b/.svn/pristine/d4/d40bacc3af8fb7641b23c992be523d5d162b016d.svn-base
@@ -0,0 +1,294 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  # Class used to parse unified diffs
+  class UnifiedDiff < Array
+    attr_reader :diff_type, :diff_style
+
+    def initialize(diff, options={})
+      options.assert_valid_keys(:type, :style, :max_lines)
+      diff = diff.split("\n") if diff.is_a?(String)
+      @diff_type = options[:type] || 'inline'
+      @diff_style = options[:style]
+      lines = 0
+      @truncated = false
+      diff_table = DiffTable.new(diff_type, diff_style)
+      diff.each do |line_raw|
+        line = Redmine::CodesetUtil.to_utf8_by_setting(line_raw)
+        unless diff_table.add_line(line)
+          self << diff_table if diff_table.length > 0
+          diff_table = DiffTable.new(diff_type, diff_style)
+        end
+        lines += 1
+        if options[:max_lines] && lines > options[:max_lines]
+          @truncated = true
+          break
+        end
+      end
+      self << diff_table unless diff_table.empty?
+      self
+    end
+
+    def truncated?; @truncated; end
+  end
+
+  # Class that represents a file diff
+  class DiffTable < Array
+    attr_reader :file_name
+
+    # Initialize with a Diff file and the type of Diff View
+    # The type view must be inline or sbs (side_by_side)
+    def initialize(type="inline", style=nil)
+      @parsing = false
+      @added = 0
+      @removed = 0
+      @type = type
+      @style = style
+      @file_name = nil
+      @git_diff = false
+    end
+
+    # Function for add a line of this Diff
+    # Returns false when the diff ends
+    def add_line(line)
+      unless @parsing
+        if line =~ /^(---|\+\+\+) (.*)$/
+          self.file_name = $2
+        elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
+          @line_num_l = $2.to_i
+          @line_num_r = $5.to_i
+          @parsing = true
+        end
+      else
+        if line =~ %r{^[^\+\-\s@\\]}
+          @parsing = false
+          return false
+        elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
+          @line_num_l = $2.to_i
+          @line_num_r = $5.to_i
+        else
+          parse_line(line, @type)
+        end
+      end
+      return true
+    end
+
+    def each_line
+      prev_line_left, prev_line_right = nil, nil
+      each do |line|
+        spacing = prev_line_left && prev_line_right && (line.nb_line_left != prev_line_left+1) && (line.nb_line_right != prev_line_right+1)
+        yield spacing, line
+        prev_line_left = line.nb_line_left.to_i if line.nb_line_left.to_i > 0
+        prev_line_right = line.nb_line_right.to_i if line.nb_line_right.to_i > 0
+      end
+    end
+
+    def inspect
+      puts '### DIFF TABLE ###'
+      puts "file : #{file_name}"
+      self.each do |d|
+        d.inspect
+      end
+    end
+
+    private
+
+    def file_name=(arg)
+      both_git_diff = false
+      if file_name.nil?
+        @git_diff = true if arg =~ %r{^(a/|/dev/null)}
+      else
+        both_git_diff = (@git_diff && arg =~ %r{^(b/|/dev/null)})
+      end
+      if both_git_diff
+        if file_name && arg == "/dev/null"
+          # keep the original file name
+          @file_name = file_name.sub(%r{^a/}, '')
+        else
+          # remove leading b/
+          @file_name = arg.sub(%r{^b/}, '')
+        end
+      elsif @style == "Subversion"
+        # removing trailing "(revision nn)"
+        @file_name = arg.sub(%r{\t+\(.*\)$}, '')
+      else
+        @file_name = arg
+      end
+    end
+
+    def diff_for_added_line
+      if @type == 'sbs' && @removed > 0 && @added < @removed
+        self[-(@removed - @added)]
+      else
+        diff = Diff.new
+        self << diff
+        diff
+      end
+    end
+
+    def parse_line(line, type="inline")
+      if line[0, 1] == "+"
+        diff = diff_for_added_line
+        diff.line_right = line[1..-1]
+        diff.nb_line_right = @line_num_r
+        diff.type_diff_right = 'diff_in'
+        @line_num_r += 1
+        @added += 1
+        true
+      elsif line[0, 1] == "-"
+        diff = Diff.new
+        diff.line_left = line[1..-1]
+        diff.nb_line_left = @line_num_l
+        diff.type_diff_left = 'diff_out'
+        self << diff
+        @line_num_l += 1
+        @removed += 1
+        true
+      else
+        write_offsets
+        if line[0, 1] =~ /\s/
+          diff = Diff.new
+          diff.line_right = line[1..-1]
+          diff.nb_line_right = @line_num_r
+          diff.line_left = line[1..-1]
+          diff.nb_line_left = @line_num_l
+          self << diff
+          @line_num_l += 1
+          @line_num_r += 1
+          true
+        elsif line[0, 1] = "\\"
+          true
+        else
+          false
+        end
+      end
+    end
+
+    def write_offsets
+      if @added > 0 && @added == @removed
+        @added.times do |i|
+          line = self[-(1 + i)]
+          removed = (@type == 'sbs') ? line : self[-(1 + @added + i)]
+          offsets = offsets(removed.line_left, line.line_right)
+          removed.offsets = line.offsets = offsets
+        end
+      end
+      @added = 0
+      @removed = 0
+    end
+
+    def offsets(line_left, line_right)
+      if line_left.present? && line_right.present? && line_left != line_right
+        max = [line_left.size, line_right.size].min
+        starting = 0
+        while starting < max && line_left[starting] == line_right[starting]
+          starting += 1
+        end
+        if (! "".respond_to?(:force_encoding)) && starting < line_left.size
+          while line_left[starting].ord.between?(128, 191) && starting > 0
+            starting -= 1
+          end
+        end
+        ending = -1
+        while ending >= -(max - starting) && line_left[ending] == line_right[ending]
+          ending -= 1
+        end
+        if (! "".respond_to?(:force_encoding)) && ending > (-1 * line_left.size)
+          while line_left[ending].ord.between?(128, 191) && ending > -1
+            ending -= 1
+          end
+        end
+        unless starting == 0 && ending == -1
+          [starting, ending]
+        end
+      end
+    end
+  end
+
+  # A line of diff
+  class Diff
+    attr_accessor :nb_line_left
+    attr_accessor :line_left
+    attr_accessor :nb_line_right
+    attr_accessor :line_right
+    attr_accessor :type_diff_right
+    attr_accessor :type_diff_left
+    attr_accessor :offsets
+
+    def initialize()
+      self.nb_line_left = ''
+      self.nb_line_right = ''
+      self.line_left = ''
+      self.line_right = ''
+      self.type_diff_right = ''
+      self.type_diff_left = ''
+    end
+
+    def type_diff
+      type_diff_right == 'diff_in' ? type_diff_right : type_diff_left
+    end
+
+    def line
+      type_diff_right == 'diff_in' ? line_right : line_left
+    end
+
+    def html_line_left
+      line_to_html(line_left, offsets)
+    end
+
+    def html_line_right
+      line_to_html(line_right, offsets)
+    end
+
+    def html_line
+      line_to_html(line, offsets)
+    end
+
+    def inspect
+      puts '### Start Line Diff ###'
+      puts self.nb_line_left
+      puts self.line_left
+      puts self.nb_line_right
+      puts self.line_right
+    end
+
+    private
+
+    def line_to_html(line, offsets)
+      html = line_to_html_raw(line, offsets)
+      html.force_encoding('UTF-8') if html.respond_to?(:force_encoding)
+      html
+    end
+
+    def line_to_html_raw(line, offsets)
+      if offsets
+        s = ''
+        unless offsets.first == 0
+          s << CGI.escapeHTML(line[0..offsets.first-1])
+        end
+        s << '<span>' + CGI.escapeHTML(line[offsets.first..offsets.last]) + '</span>'
+        unless offsets.last == -1
+          s << CGI.escapeHTML(line[offsets.last+1..-1])
+        end
+        s
+      else
+        CGI.escapeHTML(line)
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d4/d43d36e594d16de75bb067e8d84f9828c830aa58.svn-base
--- /dev/null
+++ b/.svn/pristine/d4/d43d36e594d16de75bb067e8d84f9828c830aa58.svn-base
@@ -0,0 +1,58 @@
+<div class="contextual">
+<%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %>
+</div>
+
+<h2><%=l(:label_user_plural)%></h2>
+
+<%= form_tag(users_path, :method => :get) do %>
+<fieldset><legend><%= l(:label_filter_plural) %></legend>
+<label for='status'><%= l(:field_status) %>:</label>
+<%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;"  %>
+
+<% if @groups.present? %>
+<label for='group_id'><%= l(:label_group) %>:</label>
+<%= select_tag 'group_id', content_tag('option') + options_from_collection_for_select(@groups, :id, :name, params[:group_id].to_i), :onchange => "this.form.submit(); return false;"  %>
+<% end %>
+
+<label for='name'><%= l(:label_user) %>:</label>
+<%= text_field_tag 'name', params[:name], :size => 30 %>
+<%= submit_tag l(:button_apply), :class => "small", :name => nil %>
+<%= link_to l(:button_clear), users_path, :class => 'icon icon-reload' %>
+</fieldset>
+<% end %>
+&nbsp;
+
+<div class="autoscroll">
+<table class="list">
+  <thead><tr>
+  <%= sort_header_tag('login', :caption => l(:field_login)) %>
+  <%= sort_header_tag('firstname', :caption => l(:field_firstname)) %>
+  <%= sort_header_tag('lastname', :caption => l(:field_lastname)) %>
+  <%= sort_header_tag('mail', :caption => l(:field_mail)) %>
+  <%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %>
+  <%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %>
+  <%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %>
+    <th></th>
+  </tr></thead>
+  <tbody>
+<% for user in @users -%>
+  <tr class="<%= user.css_classes %> <%= cycle("odd", "even") %>">
+  <td class="username"><%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %></td>
+  <td class="firstname"><%= h(user.firstname) %></td>
+  <td class="lastname"><%= h(user.lastname) %></td>
+  <td class="email"><%= mail_to(h(user.mail)) %></td>
+  <td align="center"><%= checked_image user.admin? %></td>
+  <td class="created_on" align="center"><%= format_time(user.created_on) %></td>
+  <td class="last_login_on" align="center"><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>
+    <td class="buttons">
+      <%= change_status_link(user) %>
+      <%= delete_link user_path(user, :back_url => users_path(params)) unless User.current == user %>
+    </td>
+  </tr>
+<% end -%>
+  </tbody>
+</table>
+</div>
+<p class="pagination"><%= pagination_links_full @user_pages, @user_count %></p>
+
+<% html_title(l(:label_user_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d4/d4482ad7b7f59be62f8bc68fbfaf937393743402.svn-base
--- a/.svn/pristine/d4/d4482ad7b7f59be62f8bc68fbfaf937393743402.svn-base
+++ /dev/null
@@ -1,172 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::Hook::ManagerTest < ActiveSupport::TestCase
-
-  fixtures :issues
-
-  # Some hooks that are manually registered in these tests
-  class TestHook < Redmine::Hook::ViewListener; end
-
-  class TestHook1 < TestHook
-    def view_layouts_base_html_head(context)
-      'Test hook 1 listener.'
-    end
-  end
-
-  class TestHook2 < TestHook
-    def view_layouts_base_html_head(context)
-      'Test hook 2 listener.'
-    end
-  end
-
-  class TestHook3 < TestHook
-    def view_layouts_base_html_head(context)
-      "Context keys: #{context.keys.collect(&:to_s).sort.join(', ')}."
-    end
-  end
-
-  class TestLinkToHook < TestHook
-    def view_layouts_base_html_head(context)
-      link_to('Issues', :controller => 'issues')
-    end
-  end
-
-  class TestHookHelperController < ActionController::Base
-    include Redmine::Hook::Helper
-  end
-
-  class TestHookHelperView < ActionView::Base
-    include Redmine::Hook::Helper
-  end
-
-  Redmine::Hook.clear_listeners
-
-  def setup
-    @hook_module = Redmine::Hook
-  end
-
-  def teardown
-    @hook_module.clear_listeners
-  end
-
-  def test_clear_listeners
-    assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
-    @hook_module.add_listener(TestHook1)
-    @hook_module.add_listener(TestHook2)
-    assert_equal 2, @hook_module.hook_listeners(:view_layouts_base_html_head).size
-
-    @hook_module.clear_listeners
-    assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
-  end
-
-  def test_add_listener
-    assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
-    @hook_module.add_listener(TestHook1)
-    assert_equal 1, @hook_module.hook_listeners(:view_layouts_base_html_head).size
-  end
-
-  def test_call_hook
-    @hook_module.add_listener(TestHook1)
-    assert_equal ['Test hook 1 listener.'], hook_helper.call_hook(:view_layouts_base_html_head)
-  end
-
-  def test_call_hook_with_context
-    @hook_module.add_listener(TestHook3)
-    assert_equal ['Context keys: bar, controller, foo, project, request.'],
-                 hook_helper.call_hook(:view_layouts_base_html_head, :foo => 1, :bar => 'a')
-  end
-
-  def test_call_hook_with_multiple_listeners
-    @hook_module.add_listener(TestHook1)
-    @hook_module.add_listener(TestHook2)
-    assert_equal ['Test hook 1 listener.', 'Test hook 2 listener.'], hook_helper.call_hook(:view_layouts_base_html_head)
-  end
-
-  # Context: Redmine::Hook::Helper.call_hook default_url
-  def test_call_hook_default_url_options
-    @hook_module.add_listener(TestLinkToHook)
-
-    assert_equal ['<a href="/issues">Issues</a>'], hook_helper.call_hook(:view_layouts_base_html_head)
-  end
-
-  # Context: Redmine::Hook::Helper.call_hook
-  def test_call_hook_with_project_added_to_context
-    @hook_module.add_listener(TestHook3)
-    assert_match /project/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
-  end
-
-  def test_call_hook_from_controller_with_controller_added_to_context
-    @hook_module.add_listener(TestHook3)
-    assert_match /controller/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
-  end
-
-  def test_call_hook_from_controller_with_request_added_to_context
-    @hook_module.add_listener(TestHook3)
-    assert_match /request/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
-  end
-
-  def test_call_hook_from_view_with_project_added_to_context
-    @hook_module.add_listener(TestHook3)
-    assert_match /project/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
-  end
-
-  def test_call_hook_from_view_with_controller_added_to_context
-    @hook_module.add_listener(TestHook3)
-    assert_match /controller/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
-  end
-
-  def test_call_hook_from_view_with_request_added_to_context
-    @hook_module.add_listener(TestHook3)
-    assert_match /request/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
-  end
-
-  def test_call_hook_from_view_should_join_responses_with_a_space
-    @hook_module.add_listener(TestHook1)
-    @hook_module.add_listener(TestHook2)
-    assert_equal 'Test hook 1 listener. Test hook 2 listener.',
-                 view_hook_helper.call_hook(:view_layouts_base_html_head)
-  end
-
-  def test_call_hook_should_not_change_the_default_url_for_email_notifications
-    issue = Issue.find(1)
-
-    ActionMailer::Base.deliveries.clear
-    Mailer.deliver_issue_add(issue)
-    mail = ActionMailer::Base.deliveries.last
-
-    @hook_module.add_listener(TestLinkToHook)
-    hook_helper.call_hook(:view_layouts_base_html_head)
-
-    ActionMailer::Base.deliveries.clear
-    Mailer.deliver_issue_add(issue)
-    mail2 = ActionMailer::Base.deliveries.last
-
-    assert_equal mail.body, mail2.body
-  end
-
-  def hook_helper
-    @hook_helper ||= TestHookHelperController.new
-  end
-
-  def view_hook_helper
-    @view_hook_helper ||= TestHookHelperView.new(Rails.root.to_s + '/app/views')
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d4/d4784b674172654e5a4164cf7f526c3360280dc5.svn-base
--- a/.svn/pristine/d4/d4784b674172654e5a4164cf7f526c3360280dc5.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-<h2><%=l(:label_password_lost)%></h2>
-
-<%= error_messages_for 'user' %>
-
-<% form_tag({:token => @token.value}) do %>
-<div class="box tabular">
-<p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label>
-<%= password_field_tag 'new_password', nil, :size => 25 %><br />
-<em><%= l(:text_caracters_minimum, :count => Setting.password_min_length) %></em></p>
-
-<p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
-<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
-</div>
-<p><%= submit_tag l(:button_save) %></p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d4/d4926106ef44c5f951d961f9eb5f2af78dbe9754.svn-base
--- a/.svn/pristine/d4/d4926106ef44c5f951d961f9eb5f2af78dbe9754.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/process/spawner'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d4/d4da4a559fadb71236d2e8c75903152ca38b8d80.svn-base
--- a/.svn/pristine/d4/d4da4a559fadb71236d2e8c75903152ca38b8d80.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class NewsObserver < ActiveRecord::Observer
-  def after_create(news)
-    Mailer.deliver_news_added(news) if Setting.notified_events.include?('news_added')
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d5050114448f68b3daa8ff218c27426ce16d4bf7.svn-base
--- a/.svn/pristine/d5/d5050114448f68b3daa8ff218c27426ce16d4bf7.svn-base
+++ /dev/null
@@ -1,143 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class WatcherTest < ActiveSupport::TestCase
-  fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules,
-           :issues,
-           :boards, :messages,
-           :wikis, :wiki_pages,
-           :watchers
-
-  def setup
-    @user = User.find(1)
-    @issue = Issue.find(1)
-  end
-
-  def test_watch
-    assert @issue.add_watcher(@user)
-    @issue.reload
-    assert @issue.watchers.detect { |w| w.user == @user }
-  end
-
-  def test_cant_watch_twice
-    assert @issue.add_watcher(@user)
-    assert !@issue.add_watcher(@user)
-  end
-
-  def test_watched_by
-    assert @issue.add_watcher(@user)
-    @issue.reload
-    assert @issue.watched_by?(@user)
-    assert Issue.watched_by(@user).include?(@issue)
-  end
-
-  def test_watcher_users
-    watcher_users = Issue.find(2).watcher_users
-    assert_kind_of Array, watcher_users
-    assert_kind_of User, watcher_users.first
-  end
-
-  def test_watcher_users_should_not_validate_user
-    User.update_all("firstname = ''", "id=1")
-    @user.reload
-    assert !@user.valid?
-
-    issue = Issue.new(:project => Project.find(1), :tracker_id => 1, :subject => "test", :author => User.find(2))
-    issue.watcher_users << @user
-    issue.save!
-    assert issue.watched_by?(@user)
-  end
-
-  def test_watcher_user_ids
-    assert_equal [1, 3], Issue.find(2).watcher_user_ids.sort
-  end
-
-  def test_watcher_user_ids=
-    issue = Issue.new
-    issue.watcher_user_ids = ['1', '3']
-    assert issue.watched_by?(User.find(1))
-  end
-
-  def test_addable_watcher_users
-    addable_watcher_users = @issue.addable_watcher_users
-    assert_kind_of Array, addable_watcher_users
-    assert_kind_of User, addable_watcher_users.first
-  end
-
-  def test_addable_watcher_users_should_not_include_user_that_cannot_view_the_object
-    issue = Issue.new(:project => Project.find(1), :is_private => true)
-    assert_nil issue.addable_watcher_users.detect {|user| !issue.visible?(user)}
-  end
-
-  def test_recipients
-    @issue.watchers.delete_all
-    @issue.reload
-
-    assert @issue.watcher_recipients.empty?
-    assert @issue.add_watcher(@user)
-
-    @user.mail_notification = 'all'
-    @user.save!
-    @issue.reload
-    assert @issue.watcher_recipients.include?(@user.mail)
-
-    @user.mail_notification = 'none'
-    @user.save!
-    @issue.reload
-    assert !@issue.watcher_recipients.include?(@user.mail)
-  end
-
-  def test_unwatch
-    assert @issue.add_watcher(@user)
-    @issue.reload
-    assert_equal 1, @issue.remove_watcher(@user)
-  end
-
-  def test_prune
-    Watcher.delete_all("user_id = 9")
-    user = User.find(9)
-
-    # public
-    Watcher.create!(:watchable => Issue.find(1), :user => user)
-    Watcher.create!(:watchable => Issue.find(2), :user => user)
-    Watcher.create!(:watchable => Message.find(1), :user => user)
-    Watcher.create!(:watchable => Wiki.find(1), :user => user)
-    Watcher.create!(:watchable => WikiPage.find(2), :user => user)
-
-    # private project (id: 2)
-    Member.create!(:project => Project.find(2), :principal => user, :role_ids => [1])
-    Watcher.create!(:watchable => Issue.find(4), :user => user)
-    Watcher.create!(:watchable => Message.find(7), :user => user)
-    Watcher.create!(:watchable => Wiki.find(2), :user => user)
-    Watcher.create!(:watchable => WikiPage.find(3), :user => user)
-
-    assert_no_difference 'Watcher.count' do
-      Watcher.prune(:user => User.find(9))
-    end
-
-    Member.delete_all
-
-    assert_difference 'Watcher.count', -4 do
-      Watcher.prune(:user => User.find(9))
-    end
-
-    assert Issue.find(1).watched_by?(user)
-    assert !Issue.find(4).watched_by?(user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d52cd894471c60da0fd08878344d5bd7680a2e5a.svn-base
--- a/.svn/pristine/d5/d52cd894471c60da0fd08878344d5bd7680a2e5a.svn-base
+++ /dev/null
@@ -1,65 +0,0 @@
-# Be sure to restart your web server when you modify this file.
-
-# Uncomment below to force Rails into production mode when
-# you don't control web/app server and can't set it the proper way
-# ENV['RAILS_ENV'] ||= 'production'
-
-# Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '2.3.14' unless defined? RAILS_GEM_VERSION
-
-if RUBY_VERSION >= '1.9'
-  Encoding.default_external = 'UTF-8'
-end
-
-# Bootstrap the Rails environment, frameworks, and default configuration
-require File.join(File.dirname(__FILE__), 'boot')
-
-# Load Engine plugin if available
-begin
-  require File.join(File.dirname(__FILE__), '../vendor/plugins/engines/boot')
-rescue LoadError
-  # Not available
-end
-
-Rails::Initializer.run do |config|
-  # Settings in config/environments/* take precedence those specified here
-
-  # Skip frameworks you're not going to use
-  # config.frameworks -= [ :action_web_service, :action_mailer ]
-
-  # Add additional load paths for sweepers
-  config.autoload_paths += %W( #{RAILS_ROOT}/app/sweepers )
-
-  # Force all environments to use the same logger level
-  # (by default production uses :info, the others :debug)
-  # config.log_level = :debug
-
-  # Enable page/fragment caching by setting a file-based store
-  # (remember to create the caching directory and make it readable to the application)
-  # config.action_controller.cache_store = :file_store, "#{RAILS_ROOT}/tmp/cache"
-
-  # Activate observers that should always be running
-  # config.active_record.observers = :cacher, :garbage_collector
-  config.active_record.observers = :message_observer, :issue_observer, :journal_observer, :news_observer, :document_observer, :wiki_content_observer, :comment_observer
-
-  # Make Active Record use UTC-base instead of local time
-  # config.active_record.default_timezone = :utc
-
-  # Use Active Record's schema dumper instead of SQL when creating the test database
-  # (enables use of different database adapters for development and test environments)
-  # config.active_record.schema_format = :ruby
-
-  # Deliveries are disabled by default. Do NOT modify this section.
-  # Define your email configuration in configuration.yml instead.
-  # It will automatically turn deliveries on
-  config.action_mailer.perform_deliveries = false
-
-  config.gem 'rubytree', :lib => 'tree'
-  config.gem 'coderay', :version => '~>1.0.0'
-
-  # Load any local configuration that is kept out of source control
-  # (e.g. gems, patches).
-  if File.exists?(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
-    instance_eval File.read(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d562875108cecc41042a4d0be1488884f1e06a95.svn-base
--- a/.svn/pristine/d5/d562875108cecc41042a4d0be1488884f1e06a95.svn-base
+++ /dev/null
@@ -1,68 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class AuthSource < ActiveRecord::Base
-  include Redmine::Ciphering
-
-  has_many :users
-
-  validates_presence_of :name
-  validates_uniqueness_of :name
-  validates_length_of :name, :maximum => 60
-
-  def authenticate(login, password)
-  end
-
-  def test_connection
-  end
-
-  def auth_method_name
-    "Abstract"
-  end
-
-  def account_password
-    read_ciphered_attribute(:account_password)
-  end
-
-  def account_password=(arg)
-    write_ciphered_attribute(:account_password, arg)
-  end
-
-  def allow_password_changes?
-    self.class.allow_password_changes?
-  end
-
-  # Does this auth source backend allow password changes?
-  def self.allow_password_changes?
-    false
-  end
-
-  # Try to authenticate a user not yet registered against available sources
-  def self.authenticate(login, password)
-    AuthSource.find(:all, :conditions => ["onthefly_register=?", true]).each do |source|
-      begin
-        logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
-        attrs = source.authenticate(login, password)
-      rescue => e
-        logger.error "Error during authentication: #{e.message}"
-        attrs = nil
-      end
-      return attrs if attrs
-    end
-    return nil
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d56bb30205e35d46995a303698017ed24f7ce040.svn-base
--- /dev/null
+++ b/.svn/pristine/d5/d56bb30205e35d46995a303698017ed24f7ce040.svn-base
@@ -0,0 +1,217 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class MessagesControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
+
+  def setup
+    User.current = nil
+  end
+
+  def test_show
+    get :show, :board_id => 1, :id => 1
+    assert_response :success
+    assert_template 'show'
+    assert_not_nil assigns(:board)
+    assert_not_nil assigns(:project)
+    assert_not_nil assigns(:topic)
+  end
+  
+  def test_show_should_contain_reply_field_tags_for_quoting
+    @request.session[:user_id] = 2
+    get :show, :board_id => 1, :id => 1
+    assert_response :success
+
+    # tags required by MessagesController#quote
+    assert_tag 'input', :attributes => {:id => 'message_subject'}
+    assert_tag 'textarea', :attributes => {:id => 'message_content'}
+    assert_tag 'div', :attributes => {:id => 'reply'}
+  end
+
+  def test_show_with_pagination
+    message = Message.find(1)
+    assert_difference 'Message.count', 30 do
+      30.times do
+        message.children << Message.new(:subject => 'Reply', :content => 'Reply body', :author_id => 2, :board_id => 1)
+      end
+    end
+    get :show, :board_id => 1, :id => 1, :r => message.children.last(:order => 'id').id
+    assert_response :success
+    assert_template 'show'
+    replies = assigns(:replies)
+    assert_not_nil replies
+    assert !replies.include?(message.children.first(:order => 'id'))
+    assert replies.include?(message.children.last(:order => 'id'))
+  end
+
+  def test_show_with_reply_permission
+    @request.session[:user_id] = 2
+    get :show, :board_id => 1, :id => 1
+    assert_response :success
+    assert_template 'show'
+    assert_tag :div, :attributes => { :id => 'reply' },
+                     :descendant => { :tag => 'textarea', :attributes => { :id => 'message_content' } }
+  end
+
+  def test_show_message_not_found
+    get :show, :board_id => 1, :id => 99999
+    assert_response 404
+  end
+
+  def test_show_message_from_invalid_board_should_respond_with_404
+    get :show, :board_id => 999, :id => 1
+    assert_response 404
+  end
+
+  def test_get_new
+    @request.session[:user_id] = 2
+    get :new, :board_id => 1
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_get_new_with_invalid_board
+    @request.session[:user_id] = 2
+    get :new, :board_id => 99
+    assert_response 404
+  end
+
+  def test_post_new
+    @request.session[:user_id] = 2
+    ActionMailer::Base.deliveries.clear
+
+    with_settings :notified_events => %w(message_posted) do
+      post :new, :board_id => 1,
+               :message => { :subject => 'Test created message',
+                             :content => 'Message body'}
+    end
+    message = Message.find_by_subject('Test created message')
+    assert_not_nil message
+    assert_redirected_to "/boards/1/topics/#{message.to_param}"
+    assert_equal 'Message body', message.content
+    assert_equal 2, message.author_id
+    assert_equal 1, message.board_id
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert_equal "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] Test created message", mail.subject
+    assert_mail_body_match 'Message body', mail
+    # author
+    assert mail.bcc.include?('jsmith@somenet.foo')
+    # project member
+    assert mail.bcc.include?('dlopper@somenet.foo')
+  end
+
+  def test_get_edit
+    @request.session[:user_id] = 2
+    get :edit, :board_id => 1, :id => 1
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_post_edit
+    @request.session[:user_id] = 2
+    post :edit, :board_id => 1, :id => 1,
+                :message => { :subject => 'New subject',
+                              :content => 'New body'}
+    assert_redirected_to '/boards/1/topics/1'
+    message = Message.find(1)
+    assert_equal 'New subject', message.subject
+    assert_equal 'New body', message.content
+  end
+
+  def test_post_edit_sticky_and_locked
+    @request.session[:user_id] = 2
+    post :edit, :board_id => 1, :id => 1,
+                :message => { :subject => 'New subject',
+                              :content => 'New body',
+                              :locked => '1',
+                              :sticky => '1'}
+    assert_redirected_to '/boards/1/topics/1'
+    message = Message.find(1)
+    assert_equal true, message.sticky?
+    assert_equal true, message.locked?
+  end
+
+  def test_post_edit_should_allow_to_change_board
+    @request.session[:user_id] = 2
+    post :edit, :board_id => 1, :id => 1,
+                :message => { :subject => 'New subject',
+                              :content => 'New body',
+                              :board_id => 2}
+    assert_redirected_to '/boards/2/topics/1'
+    message = Message.find(1)
+    assert_equal Board.find(2), message.board
+  end
+
+  def test_reply
+    @request.session[:user_id] = 2
+    post :reply, :board_id => 1, :id => 1, :reply => { :content => 'This is a test reply', :subject => 'Test reply' }
+    reply = Message.order('id DESC').first
+    assert_redirected_to "/boards/1/topics/1?r=#{reply.id}"
+    assert Message.find_by_subject('Test reply')
+  end
+
+  def test_destroy_topic
+    @request.session[:user_id] = 2
+    assert_difference 'Message.count', -3 do
+      post :destroy, :board_id => 1, :id => 1
+    end
+    assert_redirected_to '/projects/ecookbook/boards/1'
+    assert_nil Message.find_by_id(1)
+  end
+
+  def test_destroy_reply
+    @request.session[:user_id] = 2
+    assert_difference 'Message.count', -1 do
+      post :destroy, :board_id => 1, :id => 2
+    end
+    assert_redirected_to '/boards/1/topics/1?r=2'
+    assert_nil Message.find_by_id(2)
+  end
+
+  def test_quote
+    @request.session[:user_id] = 2
+    xhr :get, :quote, :board_id => 1, :id => 3
+    assert_response :success
+    assert_equal 'text/javascript', response.content_type
+    assert_template 'quote'
+    assert_include 'RE: First post', response.body
+    assert_include '> An other reply', response.body
+  end
+
+  def test_preview_new
+    @request.session[:user_id] = 2
+    post :preview,
+      :board_id => 1,
+      :message => {:subject => "", :content => "Previewed text"}
+    assert_response :success
+    assert_template 'common/_preview'
+  end
+
+  def test_preview_edit
+    @request.session[:user_id] = 2
+    post :preview,
+      :id => 4,
+      :board_id => 1,
+      :message => {:subject => "", :content => "Previewed text"}
+    assert_response :success
+    assert_template 'common/_preview'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d5702bcdc6e61efeb5c6de92cb904d7e57f2c46b.svn-base
--- a/.svn/pristine/d5/d5702bcdc6e61efeb5c6de92cb904d7e57f2c46b.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-module RenderInformation
-  def render_class_and_action(note = nil, options={})
-    text = "rendered in #{self.class.name}##{params[:action]}"
-    text += " (#{note})" unless note.nil?
-    render options.update(:text => text)
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d588ced6d5efcbe60b58d36d380d9f3530582ca9.svn-base
--- a/.svn/pristine/d5/d588ced6d5efcbe60b58d36d380d9f3530582ca9.svn-base
+++ /dev/null
@@ -1,51 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Token < ActiveRecord::Base
-  belongs_to :user
-  validates_uniqueness_of :value
-
-  before_create :delete_previous_tokens, :generate_new_token
-
-  @@validity_time = 1.day
-
-  def generate_new_token
-    self.value = Token.generate_token_value
-  end
-
-  # Return true if token has expired
-  def expired?
-    return Time.now > self.created_on + @@validity_time
-  end
-
-  # Delete all expired tokens
-  def self.destroy_expired
-    Token.delete_all ["action <> 'feeds' AND created_on < ?", Time.now - @@validity_time]
-  end
-
-private
-  def self.generate_token_value
-    ActiveSupport::SecureRandom.hex(20)
-  end
-
-  # Removes obsolete tokens (same user and action)
-  def delete_previous_tokens
-    if user
-      Token.delete_all(['user_id = ? AND action = ?', user.id, action])
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d5c99af330410b19fab22c939293b2b8a8b960e8.svn-base
--- /dev/null
+++ b/.svn/pristine/d5/d5c99af330410b19fab22c939293b2b8a8b960e8.svn-base
@@ -0,0 +1,50 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoriesGitTest < ActionController::IntegrationTest
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :repositories, :enabled_modules
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
+  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
+  PRJ_ID     = 3
+
+  def setup
+    User.current = nil
+    @project    = Project.find(PRJ_ID)
+    @repository = Repository::Git.create(
+                      :project       => @project,
+                      :url           => REPOSITORY_PATH,
+                      :path_encoding => 'ISO-8859-1'
+                      )
+    assert @repository
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    def test_index
+      get '/projects/subproject1/repository/'
+      assert_response :success
+    end
+
+    def test_diff_two_revs
+      get '/projects/subproject1/repository/diff?rev=61b685fbe&rev_to=2f9c0091'
+      assert_response :success
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d5d37bb7dbfb0bad38a53c5b63ab300f544aea42.svn-base
--- a/.svn/pristine/d5/d5d37bb7dbfb0bad38a53c5b63ab300f544aea42.svn-base
+++ /dev/null
@@ -1,62 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'net/pop'
-
-module Redmine
-  module POP3
-    class << self
-      def check(pop_options={}, options={})
-        host = pop_options[:host] || '127.0.0.1'
-        port = pop_options[:port] || '110'
-        apop = (pop_options[:apop].to_s == '1')
-        delete_unprocessed = (pop_options[:delete_unprocessed].to_s == '1')
-
-        pop = Net::POP3.APOP(apop).new(host,port)
-        logger.debug "Connecting to #{host}..." if logger && logger.debug?
-        pop.start(pop_options[:username], pop_options[:password]) do |pop_session|
-          if pop_session.mails.empty?
-            logger.debug "No email to process" if logger && logger.debug?
-          else
-            logger.debug "#{pop_session.mails.size} email(s) to process..." if logger && logger.debug?
-            pop_session.each_mail do |msg|
-              message = msg.pop
-              message_id = (message =~ /^Message-ID: (.*)/ ? $1 : '').strip
-              if MailHandler.receive(message, options)
-                msg.delete
-                logger.debug "--> Message #{message_id} processed and deleted from the server" if logger && logger.debug?
-              else
-                if delete_unprocessed
-                  msg.delete
-                  logger.debug "--> Message #{message_id} NOT processed and deleted from the server" if logger && logger.debug?
-                else
-                  logger.debug "--> Message #{message_id} NOT processed and left on the server" if logger && logger.debug?
-                end
-              end
-            end
-          end
-        end
-      end
-
-      private
-
-      def logger
-        RAILS_DEFAULT_LOGGER
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d5da71bbc5df333be197c332633aea4f67a15e31.svn-base
--- /dev/null
+++ b/.svn/pristine/d5/d5da71bbc5df333be197c332633aea4f67a15e31.svn-base
@@ -0,0 +1,50 @@
+<h2><%= l(:label_bulk_edit_selected_time_entries) %></h2>
+
+<ul id="bulk-selection">
+<% @time_entries.each do |entry| %>
+  <%= content_tag 'li',
+        link_to("#{format_date(entry.spent_on)} - #{entry.project}: #{l(:label_f_hour_plural, :value => entry.hours)}", edit_time_entry_path(entry)) %>
+<% end %>
+</ul>
+
+<%= form_tag(bulk_update_time_entries_path, :id => 'bulk_edit_form') do %>
+<%= @time_entries.collect {|i| hidden_field_tag('ids[]', i.id)}.join.html_safe %>
+<div class="box tabular">
+  <div>
+    <p>
+      <label><%= l(:field_issue) %></label>
+      <%= text_field :time_entry, :issue_id, :size => 6 %>
+    </p>
+
+    <p>
+      <label><%= l(:field_spent_on) %></label>
+      <%= text_field :time_entry, :spent_on, :size => 10 %><%= calendar_for('time_entry_spent_on') %>
+    </p>
+
+    <p>
+      <label><%= l(:field_hours) %></label>
+      <%= text_field :time_entry, :hours, :size => 6 %>
+    </p>
+
+    <% if @available_activities.any? %>
+    <p>
+      <label><%= l(:field_activity) %></label>
+      <%= select_tag('time_entry[activity_id]', content_tag('option', l(:label_no_change_option), :value => '') + options_from_collection_for_select(@available_activities, :id, :name)) %>
+    </p>
+    <% end %>
+
+    <p>
+      <label><%= l(:field_comments) %></label>
+      <%= text_field(:time_entry, :comments, :size => 100) %>
+    </p>
+
+    <% @custom_fields.each do |custom_field| %>
+      <p><label><%= h(custom_field.name) %></label> <%= custom_field_tag_for_bulk_edit('time_entry', custom_field, @projects) %></p>
+    <% end %>
+
+    <%= call_hook(:view_time_entries_bulk_edit_details_bottom, { :time_entries => @time_entries }) %>
+  </div>
+</div>
+
+<p><%= submit_tag l(:button_submit) %></p>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d5/d5f12b9435fe0efa5be5065b1768cd4f3672f5e4.svn-base
--- a/.svn/pristine/d5/d5f12b9435fe0efa5be5065b1768cd4f3672f5e4.svn-base
+++ /dev/null
@@ -1,5 +0,0 @@
-Description:
-    Generates a plugin model.
-
-Examples:
-    ./script/generate redmine_plugin_model MyPlugin pool title:string question:text
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d6/d629345df56e3e889eaaef3db666cce1ae6753ff.svn-base
--- a/.svn/pristine/d6/d629345df56e3e889eaaef3db666cce1ae6753ff.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/server'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d6/d6359025a5eb4f10b9cc606f83ccdea5749d7ce4.svn-base
--- a/.svn/pristine/d6/d6359025a5eb4f10b9cc606f83ccdea5749d7ce4.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-<% if @wiki && @wiki.sidebar -%>
-  <%= textilizable @wiki.sidebar.content, :text %>
-<% end -%>
-
-<h3><%= l(:label_wiki) %></h3>
-
-<%= link_to l(:field_start_page), {:action => 'show', :id => nil} %><br />
-<%= link_to l(:label_index_by_title), {:action => 'index'} %><br />
-<%= link_to l(:label_index_by_date), {:action => 'date_index'} %><br />
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d6/d6629aa169e2a2fae49ddb2b561672fa11a7bb57.svn-base
--- /dev/null
+++ b/.svn/pristine/d6/d6629aa169e2a2fae49ddb2b561672fa11a7bb57.svn-base
@@ -0,0 +1,269 @@
+--- 
+attachments_001: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  downloads: 0
+  content_type: text/plain
+  disk_filename: 060719210727_error281.txt
+  disk_directory: "2006/07"
+  container_id: 3
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 1
+  container_type: Issue
+  filesize: 28
+  filename: error281.txt
+  author_id: 2
+attachments_002: 
+  created_on: 2007-01-27 15:08:27 +01:00
+  downloads: 0
+  content_type: text/plain
+  disk_filename: 060719210727_document.txt
+  disk_directory: "2006/07"
+  container_id: 1
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 2
+  container_type: Document
+  filesize: 28
+  filename: document.txt
+  author_id: 2
+attachments_003: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  downloads: 0
+  content_type: image/gif
+  disk_filename: 060719210727_logo.gif
+  disk_directory: "2006/07"
+  container_id: 4
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 3
+  container_type: WikiPage
+  filesize: 280
+  filename: logo.gif
+  description: This is a logo
+  author_id: 2
+attachments_004: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 3
+  downloads: 0
+  disk_filename: 060719210727_source.rb
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 4
+  filesize: 153
+  filename: source.rb
+  author_id: 2
+  description: This is a Ruby source file
+  content_type: application/x-ruby
+attachments_005: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 3
+  downloads: 0
+  disk_filename: 060719210727_changeset_iso8859-1.diff
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 5
+  filesize: 687
+  filename: changeset_iso8859-1.diff
+  author_id: 2
+  content_type: text/x-diff
+attachments_006: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 3
+  downloads: 0
+  disk_filename: 060719210727_archive.zip
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 6
+  filesize: 157
+  filename: archive.zip
+  author_id: 2
+  content_type: application/octet-stream
+attachments_007: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 4
+  downloads: 0
+  disk_filename: 060719210727_archive.zip
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 7
+  filesize: 157
+  filename: archive.zip
+  author_id: 1
+  content_type: application/octet-stream
+attachments_008: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Project
+  container_id: 1
+  downloads: 0
+  disk_filename: 060719210727_project_file.zip
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 8
+  filesize: 320
+  filename: project_file.zip
+  author_id: 2
+  content_type: application/octet-stream
+attachments_009: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Version
+  container_id: 1
+  downloads: 0
+  disk_filename: 060719210727_archive.zip
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 9
+  filesize: 452
+  filename: version_file.zip
+  author_id: 2
+  content_type: application/octet-stream
+attachments_010: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 2
+  downloads: 0
+  disk_filename: 060719210727_picture.jpg
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 10
+  filesize: 452
+  filename: picture.jpg
+  author_id: 2
+  content_type: image/jpeg
+attachments_011: 
+  created_on: 2007-02-12 15:08:27 +01:00
+  container_type: Document
+  container_id: 1
+  downloads: 0
+  disk_filename: 060719210727_picture.jpg
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 11
+  filesize: 452
+  filename: picture.jpg
+  author_id: 2
+  content_type: image/jpeg
+attachments_012:
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Version
+  container_id: 1
+  downloads: 0
+  disk_filename: 060719210727_version_file.zip
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 12
+  filesize: 452
+  filename: version_file.zip
+  author_id: 2
+  content_type: application/octet-stream
+attachments_013:
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Message
+  container_id: 1
+  downloads: 0
+  disk_filename: 060719210727_foo.zip
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 13
+  filesize: 452
+  filename: foo.zip
+  author_id: 2
+  content_type: application/octet-stream
+attachments_014: 
+  created_on: 2006-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 3
+  downloads: 0
+  disk_filename: 060719210727_changeset_utf8.diff
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  id: 14
+  filesize: 687
+  filename: changeset_utf8.diff
+  author_id: 2
+  content_type: text/x-diff
+attachments_015: 
+  id: 15
+  created_on: 2010-07-19 21:07:27 +02:00
+  container_type: Issue
+  container_id: 14
+  downloads: 0
+  disk_filename: 060719210727_changeset_utf8.diff
+  disk_directory: "2006/07"
+  digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
+  filesize: 687
+  filename: private.diff
+  author_id: 2
+  content_type: text/x-diff
+  description: attachement of a private issue
+attachments_016: 
+  content_type: image/png
+  downloads: 0
+  created_on: 2010-11-23 16:14:50 +09:00
+  disk_filename: 101123161450_testfile_1.png
+  disk_directory: "2010/11"
+  container_id: 14
+  digest: 8e0294de2441577c529f170b6fb8f638
+  id: 16
+  container_type: Issue
+  description: ""
+  filename: testfile.png
+  filesize: 2654
+  author_id: 2
+attachments_017: 
+  content_type: image/png
+  downloads: 0
+  created_on: 2010-12-23 16:14:50 +09:00
+  disk_filename: 101223161450_testfile_2.png
+  disk_directory: "2010/12"
+  container_id: 14
+  digest: 6bc2963e8d7ea0d3e68d12d1fba3d6ca
+  id: 17
+  container_type: Issue
+  description: ""
+  filename: testfile.PNG
+  filesize: 3582
+  author_id: 2
+attachments_018:
+  content_type: image/png
+  downloads: 0
+  created_on: 2011-01-23 16:14:50 +09:00
+  disk_filename: 101123161450_testfile_1.png
+  disk_directory: "2010/11"
+  container_id: 14
+  digest: 8e0294de2441577c529f170b6fb8f638
+  id: 18
+  container_type: Issue
+  description: ""
+  filename: testãƒ†ã‚¹ãƒˆ.png
+  filesize: 2654
+  author_id: 2
+attachments_019:
+  content_type: image/png
+  downloads: 0
+  created_on: 2011-02-23 16:14:50 +09:00
+  disk_filename: 101223161450_testfile_2.png
+  disk_directory: "2010/12"
+  container_id: 14
+  digest: 6bc2963e8d7ea0d3e68d12d1fba3d6ca
+  id: 19
+  container_type: Issue
+  description: ""
+  filename: Testãƒ†ã‚¹ãƒˆ.PNG
+  filesize: 3582
+  author_id: 2
+attachments_020: 
+  content_type: text/plain
+  downloads: 0
+  created_on: 2012-05-12 16:14:50 +09:00
+  disk_filename: 120512161450_root_attachment.txt
+  disk_directory:
+  container_id: 14
+  digest: b0fe2abdb2599743d554a61d7da7ff74
+  id: 20
+  container_type: Issue
+  description: ""
+  filename: root_attachment.txt
+  filesize: 54
+  author_id: 2
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d6/d66e175c15ed6eac30ec3dcf7b51f04bd3ad7599.svn-base
--- /dev/null
+++ b/.svn/pristine/d6/d66e175c15ed6eac30ec3dcf7b51f04bd3ad7599.svn-base
@@ -0,0 +1,319 @@
+<% @gantt.view = self %>
+<h2><%= @query.new_record? ? l(:label_gantt) : h(@query.name) %></h2>
+
+<%= form_tag({:controller => 'gantts', :action => 'show',
+             :project_id => @project, :month => params[:month],
+             :year => params[:year], :months => params[:months]},
+             :method => :get, :id => 'query_form') do %>
+<%= hidden_field_tag 'set_filter', '1' %>
+<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
+  <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
+  <div style="<%= @query.new_record? ? "" : "display: none;" %>">
+    <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
+  </div>
+</fieldset>
+<fieldset class="collapsible collapsed">
+  <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
+  <div style="display: none;">
+    <table>
+      <tr>
+        <td>
+          <fieldset>
+            <legend><%= l(:label_related_issues) %></legend>
+            <label>
+              <%= check_box_tag "draw_rels", params["draw_rels"], params[:set_filter].blank? || params[:draw_rels] %>
+              <% rels = [IssueRelation::TYPE_BLOCKS, IssueRelation::TYPE_PRECEDES] %>
+              <% rels.each do |rel| %>
+                <% color = Redmine::Helpers::Gantt::DRAW_TYPES[rel][:color] %>
+                <%= content_tag(:span, '&nbsp;&nbsp;&nbsp;'.html_safe,
+                                :style => "background-color: #{color}") %>
+                <%= l(IssueRelation::TYPES[rel][:name]) %>
+              <% end %>
+            </label>
+          </fieldset>
+        </td>
+        <td>
+          <fieldset>
+            <legend><%= l(:label_gantt_progress_line) %></legend>
+            <label>
+              <%= check_box_tag "draw_progress_line", params[:draw_progress_line], params[:draw_progress_line] %>
+              <%= l(:label_display) %>
+            </label>
+          </fieldset>
+        </td>
+      </tr>
+    </table>
+  </div>
+</fieldset>
+
+<p class="contextual">
+  <%= gantt_zoom_link(@gantt, :in) %>
+  <%= gantt_zoom_link(@gantt, :out) %>
+</p>
+
+<p class="buttons">
+<%= text_field_tag 'months', @gantt.months, :size => 2 %>
+<%= l(:label_months_from) %>
+<%= select_month(@gantt.month_from, :prefix => "month", :discard_type => true) %>
+<%= select_year(@gantt.year_from, :prefix => "year", :discard_type => true) %>
+<%= hidden_field_tag 'zoom', @gantt.zoom %>
+
+<%= link_to_function l(:button_apply), '$("#query_form").submit()',
+                     :class => 'icon icon-checked' %>
+<%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 },
+            :class => 'icon icon-reload' %>
+</p>
+<% end %>
+
+<%= error_messages_for 'query' %>
+<% if @query.valid? %>
+<%
+  zoom = 1
+  @gantt.zoom.times { zoom = zoom * 2 }
+
+  subject_width = 330
+  header_height = 18
+
+  headers_height = header_height
+  show_weeks = false
+  show_days  = false
+
+  if @gantt.zoom > 1
+    show_weeks = true
+    headers_height = 2 * header_height
+    if @gantt.zoom > 2
+        show_days = true
+        headers_height = 3 * header_height
+    end
+  end
+
+  # Width of the entire chart
+  g_width = ((@gantt.date_to - @gantt.date_from + 1) * zoom).to_i
+  @gantt.render(:top => headers_height + 8,
+                :zoom => zoom,
+                :g_width => g_width,
+                :subject_width => subject_width)
+  g_height = [(20 * (@gantt.number_of_rows + 6)) + 150, 206].max
+  t_height = g_height + headers_height
+%>
+
+<% if @gantt.truncated %>
+  <p class="warning"><%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %></p>
+<% end %>
+
+<table style="width:100%; border:0; border-collapse: collapse;">
+<tr>
+<td style="width:<%= subject_width %>px; padding:0px;">
+  <%
+    style  = ""
+    style += "position:relative;"
+    style += "height: #{t_height + 24}px;"
+    style += "width: #{subject_width + 1}px;"
+  %>
+  <%= content_tag(:div, :style => style) do %>
+    <%
+      style  = ""
+      style += "right:-2px;"
+      style += "width: #{subject_width}px;"
+      style += "height: #{headers_height}px;"
+      style += 'background: #eee;'
+    %>
+    <%= content_tag(:div, "", :style => style, :class => "gantt_hdr") %>
+    <%
+      style  = ""
+      style += "right:-2px;"
+      style += "width: #{subject_width}px;"
+      style += "height: #{t_height}px;"
+      style += 'border-left: 1px solid #c0c0c0;'
+      style += 'overflow: hidden;'
+    %>
+    <%= content_tag(:div, "", :style => style, :class => "gantt_hdr") %>
+    <%= content_tag(:div, :class => "gantt_subjects") do %>
+      <%= @gantt.subjects.html_safe %>
+    <% end %>
+  <% end %>
+</td>
+
+<td>
+<div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;" id="gantt_area">
+<%
+  style  = ""
+  style += "width: #{g_width - 1}px;"
+  style += "height: #{headers_height}px;"
+  style += 'background: #eee;'
+%>
+<%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :class => "gantt_hdr") %>
+
+<% ###### Months headers ###### %>
+<%
+  month_f = @gantt.date_from
+  left = 0
+  height = (show_weeks ? header_height : header_height + g_height)
+%>
+<% @gantt.months.times do %>
+  <%
+    width = (((month_f >> 1) - month_f) * zoom - 1).to_i
+    style  = ""
+    style += "left: #{left}px;"
+    style += "width: #{width}px;"
+    style += "height: #{height}px;"
+  %>
+  <%= content_tag(:div, :style => style, :class => "gantt_hdr") do %>
+    <%= link_to h("#{month_f.year}-#{month_f.month}"),
+                @gantt.params.merge(:year => month_f.year, :month => month_f.month),
+                :title => "#{month_name(month_f.month)} #{month_f.year}" %>
+  <% end %>
+  <%
+    left = left + width + 1
+    month_f = month_f >> 1
+  %>
+<% end %>
+
+<% ###### Weeks headers ###### %>
+<% if show_weeks %>
+  <%
+    left = 0
+    height = (show_days ? header_height - 1 : header_height - 1 + g_height)
+  %>
+  <% if @gantt.date_from.cwday == 1 %>
+    <%
+      # @date_from is monday
+      week_f = @gantt.date_from
+    %>
+  <% else %>
+    <%
+      # find next monday after @date_from
+      week_f = @gantt.date_from + (7 - @gantt.date_from.cwday + 1)
+      width = (7 - @gantt.date_from.cwday + 1) * zoom - 1
+      style  = ""
+      style += "left: #{left}px;"
+      style += "top: 19px;"
+      style += "width: #{width}px;"
+      style += "height: #{height}px;"
+    %>
+    <%= content_tag(:div, '&nbsp;'.html_safe,
+                    :style => style, :class => "gantt_hdr") %>
+    <% left = left + width + 1 %>
+  <% end %>
+  <% while week_f <= @gantt.date_to %>
+    <%
+      width = ((week_f + 6 <= @gantt.date_to) ?
+                  7 * zoom - 1 :
+                  (@gantt.date_to - week_f + 1) * zoom - 1).to_i
+      style  = ""
+      style += "left: #{left}px;"
+      style += "top: 19px;"
+      style += "width: #{width}px;"
+      style += "height: #{height}px;"
+    %>
+    <%= content_tag(:div, :style => style, :class => "gantt_hdr") do %>
+      <%= content_tag(:small) do %>
+        <%= week_f.cweek if width >= 16 %>
+      <% end %>
+    <% end %>
+    <%
+      left = left + width + 1
+      week_f = week_f + 7
+    %>
+  <% end %>
+<% end %>
+
+<% ###### Days headers ####### %>
+<% if show_days %>
+  <%
+    left = 0
+    height = g_height + header_height - 1
+    wday = @gantt.date_from.cwday
+  %>
+  <% (@gantt.date_to - @gantt.date_from + 1).to_i.times do %>
+    <%
+      width =  zoom - 1
+      style  = ""
+      style += "left: #{left}px;"
+      style += "top:37px;"
+      style += "width: #{width}px;"
+      style += "height: #{height}px;"
+      style += "font-size:0.7em;"
+      clss = "gantt_hdr"
+      clss << " nwday" if @gantt.non_working_week_days.include?(wday)
+    %>
+    <%= content_tag(:div, :style => style, :class => clss) do %>
+      <%= day_letter(wday) %>
+    <% end %>
+    <%
+      left = left + width + 1
+      wday = wday + 1
+      wday = 1 if wday > 7
+    %>
+  <% end %>
+<% end %>
+
+<%= @gantt.lines.html_safe %>
+
+<% ###### Today red line (excluded from cache) ###### %>
+<% if Date.today >= @gantt.date_from and Date.today <= @gantt.date_to %>
+  <%
+    today_left = (((Date.today - @gantt.date_from + 1) * zoom).floor() - 1).to_i
+    style  = ""
+    style += "position: absolute;"
+    style += "height: #{g_height}px;"
+    style += "top: #{headers_height + 1}px;"
+    style += "left: #{today_left}px;"
+    style += "width:10px;"
+    style += "border-left: 1px dashed red;"
+  %>
+  <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :id => 'today_line') %>
+<% end %>
+<%
+  style  = ""
+  style += "position: absolute;"
+  style += "height: #{g_height}px;"
+  style += "top: #{headers_height + 1}px;"
+  style += "left: 0px;"
+  style += "width: #{g_width - 1}px;"
+%>
+<%= content_tag(:div, '', :style => style, :id => "gantt_draw_area") %>
+</div>
+</td>
+</tr>
+</table>
+
+<table style="width:100%">
+<tr>
+  <td align="left">
+    <%= link_to_content_update("\xc2\xab " + l(:label_previous),
+                               params.merge(@gantt.params_previous)) %>
+  </td>
+  <td align="right">
+    <%= link_to_content_update(l(:label_next) + " \xc2\xbb",
+                               params.merge(@gantt.params_next)) %>
+  </td>
+</tr>
+</table>
+
+<% other_formats_links do |f| %>
+  <%= f.link_to 'PDF', :url => params.merge(@gantt.params) %>
+  <%= f.link_to('PNG', :url => params.merge(@gantt.params)) if @gantt.respond_to?('to_image') %>
+<% end %>
+<% end # query.valid? %>
+
+<% content_for :sidebar do %>
+  <%= render :partial => 'issues/sidebar' %>
+<% end %>
+
+<% html_title(l(:label_gantt)) -%>
+
+<% content_for :header_tags do %>
+  <%= javascript_include_tag 'raphael' %>
+  <%= javascript_include_tag 'gantt' %>
+<% end %>
+
+<%= javascript_tag do %>
+  var issue_relation_type = <%= raw Redmine::Helpers::Gantt::DRAW_TYPES.to_json %>;
+  $(document).ready(drawGanttHandler);
+  $(window).resize(drawGanttHandler);
+  $(function() {
+    $("#draw_rels").change(drawGanttHandler);
+    $("#draw_progress_line").change(drawGanttHandler);
+  });
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d6/d6ec7da458d1a6039ba94f943e025c4cbc9d1f92.svn-base
--- a/.svn/pristine/d6/d6ec7da458d1a6039ba94f943e025c4cbc9d1f92.svn-base
+++ /dev/null
@@ -1,38 +0,0 @@
-<fieldset id="date-range" class="collapsible">
-<legend onclick="toggleFieldset(this);"><%= l(:label_date_range) %></legend>
-<div>
-<p>
-<%= label_tag "period_type_list", l(:description_date_range_list), :class => "hidden-for-sighted" %>
-<%= radio_button_tag 'period_type', '1', !@free_period, :onclick => 'Form.Element.disable("from");Form.Element.disable("to");Form.Element.enable("period");', :id => "period_type_list"%>
-<%= select_tag 'period', options_for_period_select(params[:period]),
-                         :onchange => 'this.form.submit();',
-                         :onfocus => '$("period_type_1").checked = true;',
-                         :disabled => @free_period %>
-</p>
-<p>
-<%= label_tag "period_type_interval", l(:description_date_range_interval), :class => "hidden-for-sighted" %>
-<%= radio_button_tag 'period_type', '2', @free_period, :onclick => 'Form.Element.enable("from");Form.Element.enable("to");Form.Element.disable("period");', :id => "period_type_interval" %>
-<span onclick="$('period_type_2').checked = true;">
-<%= l(:label_date_from_to,
-        :start => ((label_tag "from", l(:description_date_from), :class => "hidden-for-sighted") + 
-            text_field_tag('from', @from, :size => 10, :disabled => !@free_period) + calendar_for('from')),
-        :end => ((label_tag "to", l(:description_date_to), :class => "hidden-for-sighted") +
-            text_field_tag('to', @to, :size => 10, :disabled => !@free_period) + calendar_for('to'))) %>
-</span>
-</p>
-</div>
-</fieldset>
-<p class="buttons">
-  <%= link_to_function l(:button_apply), '$("query_form").submit()', :class => 'icon icon-checked' %>
-  <%= link_to l(:button_clear), {:controller => controller_name, :action => action_name, :project_id => @project, :issue_id => @issue}, :class => 'icon icon-reload' %>
-</p>
-
-<div class="tabs">
-<% url_params = @free_period ? { :from => @from, :to => @to } : { :period => params[:period] } %>
-<ul>
-    <li><%= link_to(l(:label_details), url_params.merge({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue }),
-                                       :class => (@controller.action_name == 'index' ? 'selected' : nil)) %></li>
-    <li><%= link_to(l(:label_report), url_params.merge({:controller => 'time_entry_reports', :action => 'report', :project_id => @project, :issue_id => @issue}),
-                                       :class => (@controller.action_name == 'report' ? 'selected' : nil)) %></li>
-</ul>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d7/d70fd8a8adbbd6e7c06cc19c2775e3cc0289e1f1.svn-base
--- /dev/null
+++ b/.svn/pristine/d7/d70fd8a8adbbd6e7c06cc19c2775e3cc0289e1f1.svn-base
@@ -0,0 +1,63 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../test_helper', __FILE__)
+
+class CalendarTest < ActiveSupport::TestCase
+
+  def test_monthly
+    c = Redmine::Helpers::Calendar.new(Date.today, :fr, :month)
+    assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday]
+
+    c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :month)
+    assert_equal ['2007-06-25'.to_date, '2007-08-05'.to_date], [c.startdt, c.enddt]
+
+    c = Redmine::Helpers::Calendar.new(Date.today, :en, :month)
+    assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday]
+  end
+
+  def test_weekly
+    c = Redmine::Helpers::Calendar.new(Date.today, :fr, :week)
+    assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday]
+
+    c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :week)
+    assert_equal ['2007-07-09'.to_date, '2007-07-15'.to_date], [c.startdt, c.enddt]
+
+    c = Redmine::Helpers::Calendar.new(Date.today, :en, :week)
+    assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday]
+  end
+
+  def test_monthly_start_day
+    [1, 6, 7].each do |day|
+      with_settings :start_of_week => day do
+        c = Redmine::Helpers::Calendar.new(Date.today, :en, :month)
+        assert_equal day , c.startdt.cwday
+        assert_equal (day + 5) % 7 + 1, c.enddt.cwday
+      end
+    end
+  end
+
+  def test_weekly_start_day
+    [1, 6, 7].each do |day|
+      with_settings :start_of_week => day do
+        c = Redmine::Helpers::Calendar.new(Date.today, :en, :week)
+        assert_equal day, c.startdt.cwday
+        assert_equal (day + 5) % 7 + 1, c.enddt.cwday
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d7/d71b9b00f65094cf8529cb2de333f24542a6b92b.svn-base
--- /dev/null
+++ b/.svn/pristine/d7/d71b9b00f65094cf8529cb2de333f24542a6b92b.svn-base
@@ -0,0 +1,35 @@
+<div class="contextual">
+<%= watcher_link(@wiki, User.current) %>
+</div>
+
+<h2><%= l(:label_index_by_title) %></h2>
+
+<% if @pages.empty? %>
+<p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
+
+<%= render_page_hierarchy(@pages_by_parent_id, nil, :timestamp => true) %>
+
+<% content_for :sidebar do %>
+  <%= render :partial => 'sidebar' %>
+<% end %>
+
+<% unless @pages.empty? %>
+<% other_formats_links do |f| %>
+  <%= f.link_to 'Atom',
+                :url => {:controller => 'activities', :action => 'index',
+                         :id => @project, :show_wiki_edits => 1,
+                         :key => User.current.rss_key} %>
+  <% if User.current.allowed_to?(:export_wiki_pages, @project) %>
+  <%= f.link_to('PDF', :url => {:action => 'export', :format => 'pdf'}) %>
+  <%= f.link_to('HTML', :url => {:action => 'export'}) %>
+  <% end %>
+<% end %>
+<% end %>
+
+<% content_for :header_tags do %>
+<%= auto_discovery_link_tag(
+      :atom, :controller => 'activities', :action => 'index',
+      :id => @project, :show_wiki_edits => 1, :format => 'atom',
+      :key => User.current.rss_key) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d7/d71db2ac4105263a352d2e280dedafe26d5196e1.svn-base
--- a/.svn/pristine/d7/d71db2ac4105263a352d2e280dedafe26d5196e1.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-class CreateTests < ActiveRecord::Migration
-  def self.up
-    create_table 'tests' do |t|
-      t.column 'name', :string
-    end
-  end
-
-  def self.down
-    drop_table 'tests'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d7/d748c91ccd41e8268da967dfd983a0fea41803f6.svn-base
--- a/.svn/pristine/d7/d748c91ccd41e8268da967dfd983a0fea41803f6.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar SR language
-// Author: Dragan Matic, <kkid@panforma.co.yu>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Ð½ÐµÐ´ÐµÑ™Ð°",
- "Ð¿Ð¾Ð½ÐµÐ´ÐµÑ™Ð°Ðº",
- "ÑƒÑ‚Ð¾Ñ€Ð°Ðº",
- "ÑÑ€ÐµÐ´Ð°",
- "Ñ‡ÐµÑ‚Ð²Ñ€Ñ‚Ð°Ðº",
- "Ð¿ÐµÑ‚Ð°Ðº",
- "ÑÑƒÐ±Ð¾Ñ‚Ð°",
- "Ð½ÐµÐ´ÐµÑ™Ð°");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Ð½ÐµÐ´",
- "Ð¿Ð¾Ð½",
- "ÑƒÑ‚Ð¾",
- "ÑÑ€Ðµ",
- "Ñ‡ÐµÑ‚",
- "Ð¿ÐµÑ‚",
- "ÑÑƒÐ±",
- "Ð½ÐµÐ´");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Ñ˜Ð°Ð½ÑƒÐ°Ñ€",
- "Ñ„ÐµÐ±Ñ€ÑƒÐ°Ñ€",
- "Ð¼Ð°Ñ€Ñ‚",
- "Ð°Ð¿Ñ€Ð¸Ð»",
- "Ð¼Ð°Ñ˜",
- "Ñ˜ÑƒÐ½",
- "Ñ˜ÑƒÐ»",
- "Ð°Ð²Ð³ÑƒÑÑ‚",
- "ÑÐµÐ¿Ñ‚ÐµÐ¼Ð±Ð°Ñ€",
- "Ð¾ÐºÑ‚Ð¾Ð±Ð°Ñ€",
- "Ð½Ð¾Ð²ÐµÐ¼Ð±Ð°Ñ€",
- "Ð´ÐµÑ†ÐµÐ¼Ð±Ð°Ñ€");
-
-// short month names
-Calendar._SMN = new Array
-("Ñ˜Ð°Ð½",
- "Ñ„ÐµÐ±",
- "Ð¼Ð°Ñ€",
- "Ð°Ð¿Ñ€",
- "Ð¼Ð°Ñ˜",
- "Ñ˜ÑƒÐ½",
- "Ñ˜ÑƒÐ»",
- "Ð°Ð²Ð³",
- "ÑÐµÐ¿",
- "Ð¾ÐºÑ‚",
- "Ð½Ð¾Ð²",
- "Ð´ÐµÑ†");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Ðž ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñƒ";
-
-Calendar._TT["ABOUT"] =
-"DHTML Ð±Ð¸Ñ€Ð°Ñ‡ Ð´Ð°Ñ‚ÑƒÐ¼Ð°/Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°\n" +
-"(c) dynarch.com 2002-2005 / ÐÑƒÑ‚Ð¾Ñ€: Mihai Bazon\n" + // don't translate this this ;-)
-"Ð—Ð° Ð½Ð¾Ð²Ð¸Ñ˜Ñƒ Ð²ÐµÑ€Ð·Ð¸Ñ˜Ñƒ Ð¿Ð¾ÑÐµÑ‚Ð¸Ñ‚Ðµ: http://www.dynarch.com/projects/calendar/\n" +
-"Ð”Ð¸ÑÑ‚Ñ€Ð¸Ð±ÑƒÐ¸Ñ€Ð° ÑÐµ Ð¿Ð¾Ð´ GNU LGPL.  ÐŸÐ¾Ð³Ð»ÐµÐ´Ð°Ñ˜Ñ‚Ðµ http://gnu.org/licenses/lgpl.html Ð·Ð° Ð´ÐµÑ‚Ð°Ñ™e." +
-"\n\n" +
-"Ð˜Ð·Ð±Ð¾Ñ€ Ð´Ð°Ñ‚ÑƒÐ¼Ð°:\n" +
-"- ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸Ñ‚Ðµ \xab, \xbb Ñ‚Ð°ÑÑ‚ÐµÑ€Ðµ Ð·Ð° Ð¸Ð·Ð±Ð¾Ñ€ Ð³Ð¾Ð´Ð¸Ð½Ðµ\n" +
-"- ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸Ñ‚Ðµ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Ñ‚Ð°ÑÑ‚ÐµÑ€Ðµ Ð·Ð° Ð¸Ð·Ð±Ð¾Ñ€ Ð¼ÐµÑÐµÑ†Ð°\n" +
-"- Ð—Ð°Ð´Ñ€Ð¶Ð¸Ñ‚Ðµ Ñ‚Ð°ÑÑ‚ÐµÑ€ Ð¼Ð¸ÑˆÐ° Ð½Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ð¼ Ñ‚Ð°ÑÑ‚ÐµÑ€Ñƒ Ð¸Ð·Ð½Ð°Ð´ Ð·Ð° Ð±Ñ€Ð¶Ð¸ Ð¸Ð·Ð±Ð¾Ñ€.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Ð˜Ð·Ð±Ð¾Ñ€ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°:\n" +
-"- ÐšÐ»Ð¸ÐºÐ½Ð¸Ñ‚Ðµ Ð½Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ñ˜Ð¸ Ð´ÐµÐ¾ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð° Ð·Ð° Ð¿Ð¾Ð²ÐµÑ›Ð°ÑšÐµ\n" +
-"- Ð¸Ð»Ð¸ Shift-ÐºÐ»Ð¸Ðº Ð·Ð° ÑƒÐ¼Ð°ÑšÐµÑšÐµ\n" +
-"- Ð¸Ð»Ð¸ ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ‚Ðµ Ð¸ Ð¿Ñ€ÐµÐ²ÑƒÑ†Ð¸Ñ‚Ðµ Ð·Ð° Ð±Ñ€Ð¶Ð¸ Ð¾Ð´Ð°Ð±Ð¸Ñ€.";
-
-Calendar._TT["PREV_YEAR"] = "ÐŸÑ€ÐµÑ‚Ñ…Ð¾Ð´Ð½Ð° Ð³Ð¾Ð´Ð¸Ð½Ð° (Ð·Ð°Ð´Ñ€Ð¶Ð°Ñ‚Ð¸ Ð·Ð° Ð¼ÐµÐ½Ð¸)";
-Calendar._TT["PREV_MONTH"] = "ÐŸÑ€ÐµÑ‚Ñ…Ð¾Ð´Ð½Ð¸ Ð¼ÐµÑÐµÑ† (Ð·Ð°Ð´Ñ€Ð¶Ð°Ñ‚Ð¸ Ð·Ð° Ð¼ÐµÐ½Ð¸)";
-Calendar._TT["GO_TODAY"] = "ÐÐ° Ð´Ð°Ð½Ð°ÑˆÑšÐ¸ Ð´Ð°Ð½";
-Calendar._TT["NEXT_MONTH"] = "ÐÐ°Ñ€ÐµÐ´Ð½Ð¸ Ð¼ÐµÑÐµÑ† (Ð·Ð°Ð´Ñ€Ð¶Ð°Ñ‚Ð¸ Ð·Ð° Ð¼ÐµÐ½Ð¸)";
-Calendar._TT["NEXT_YEAR"] = "ÐÐ°Ñ€ÐµÐ´Ð½Ð° Ð³Ð¾Ð´Ð¸Ð½Ð° (Ð·Ð°Ð´Ñ€Ð¶Ð°Ñ‚Ð¸ Ð·Ð° Ð¼ÐµÐ½Ð¸)";
-Calendar._TT["SEL_DATE"] = "Ð˜Ð·Ð±Ð¾Ñ€ Ð´Ð°Ñ‚ÑƒÐ¼Ð°";
-Calendar._TT["DRAG_TO_MOVE"] = "ÐŸÑ€ÐµÐ²ÑƒÑ†Ð¸Ñ‚Ðµ Ð·Ð° Ð¿Ñ€ÐµÐ¼ÐµÑˆÑ‚Ð°ÑšÐµ";
-Calendar._TT["PART_TODAY"] = " (Ð´Ð°Ð½Ð°Ñ)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "%s ÐºÐ°Ð¾ Ð¿Ñ€Ð²Ð¸ Ð´Ð°Ð½ Ñƒ ÑÐµÐ´Ð¼Ð¸Ñ†Ð¸";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "6,7";
-
-Calendar._TT["CLOSE"] = "Ð—Ð°Ñ‚Ð²Ð¾Ñ€Ð¸";
-Calendar._TT["TODAY"] = "Ð”Ð°Ð½Ð°Ñ";
-Calendar._TT["TIME_PART"] = "(Shift-) ÐºÐ»Ð¸Ðº Ð¸Ð»Ð¸ Ð¿Ñ€ÐµÐ²Ð»Ð°Ñ‡ÐµÑšÐµ Ð·Ð° Ð¸Ð·Ð¼ÐµÐ½Ñƒ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚Ð¸";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y.";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %e. %b";
-
-Calendar._TT["WK"] = "ÑÐµÐ´.";
-Calendar._TT["TIME"] = "Ð’Ñ€ÐµÐ¼Ðµ:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d7/d75e9d9a3eafcbb243ad41e212cf5cdb308eeb31.svn-base
--- a/.svn/pristine/d7/d75e9d9a3eafcbb243ad41e212cf5cdb308eeb31.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-en:
-  hello: "Hello from alfa"
-  plugin: "alfa"
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d7/d7610ec8c096fad5d592071757d4c3415e6a2e6a.svn-base
--- /dev/null
+++ b/.svn/pristine/d7/d7610ec8c096fad5d592071757d4c3415e6a2e6a.svn-base
@@ -0,0 +1,106 @@
+== Redmine installation
+
+Redmine - project management software
+Copyright (C) 2006-2013  Jean-Philippe Lang
+http://www.redmine.org/
+
+
+== Requirements
+
+* Ruby 1.8.7, 1.9.2, 1.9.3 or 2.0.0
+* RubyGems
+* Bundler >= 1.0.21
+
+* A database:
+  * MySQL (tested with MySQL 5.1)
+  * PostgreSQL (tested with PostgreSQL 9.1)
+  * SQLite3 (tested with SQLite 3.7)
+  * SQLServer (tested with SQLServer 2012)
+
+Optional:
+* SCM binaries (e.g. svn, git...), for repository browsing (must be available in PATH)
+* ImageMagick (to enable Gantt export to png images)
+
+== Installation
+
+1. Uncompress the program archive
+
+2. Create an empty utf8 encoded database: "redmine" for example
+
+3. Configure the database parameters in config/database.yml
+   for the "production" environment (default database is MySQL and ruby1.9)
+
+   If you're running Redmine with MySQL and ruby1.8, replace the adapter name
+   with `mysql`
+
+4. Install the required gems by running:
+     bundle install --without development test
+
+   If ImageMagick is not installed on your system, you should skip the installation
+   of the rmagick gem using:
+     bundle install --without development test rmagick
+
+   Only the gems that are needed by the adapters you've specified in your database
+   configuration file are actually installed (eg. if your config/database.yml
+   uses the 'mysql2' adapter, then only the mysql2 gem will be installed). Don't
+   forget to re-run `bundle install` when you change config/database.yml for using
+   other database adapters.
+
+   If you need to load some gems that are not required by Redmine core (eg. fcgi),
+   you can create a file named Gemfile.local at the root of your redmine directory.
+   It will be loaded automatically when running `bundle install`.
+
+5. Generate a session store secret
+   
+   Redmine stores session data in cookies by default, which requires
+   a secret to be generated. Under the application main directory run:
+     rake generate_secret_token
+
+6. Create the database structure
+   
+   Under the application main directory run:
+     rake db:migrate RAILS_ENV="production"
+   
+   It will create all the tables and an administrator account.
+
+7. Setting up permissions (Windows users have to skip this section)
+   
+   The user who runs Redmine must have write permission on the following
+   subdirectories: files, log, tmp & public/plugin_assets.
+   
+   Assuming you run Redmine with a user named "redmine":
+     sudo chown -R redmine:redmine files log tmp public/plugin_assets
+     sudo chmod -R 755 files log tmp public/plugin_assets
+
+8. Test the installation by running the WEBrick web server
+   
+   Under the main application directory run:
+     ruby script/rails server -e production
+   
+   Once WEBrick has started, point your browser to http://localhost:3000/
+   You should now see the application welcome page.
+
+9. Use the default administrator account to log in:
+   login: admin
+   password: admin
+   
+   Go to "Administration" to load the default configuration data (roles,
+   trackers, statuses, workflow) and to adjust the application settings
+
+== SMTP server Configuration
+
+Copy config/configuration.yml.example to config/configuration.yml and
+edit this file to adjust your SMTP settings.
+Do not forget to restart the application after any change to this file.
+
+Please do not enter your SMTP settings in environment.rb.
+
+== References
+
+* http://www.redmine.org/wiki/redmine/RedmineInstall
+* http://www.redmine.org/wiki/redmine/EmailConfiguration
+* http://www.redmine.org/wiki/redmine/RedmineSettings
+* http://www.redmine.org/wiki/redmine/RedmineRepositories
+* http://www.redmine.org/wiki/redmine/RedmineReceivingEmails
+* http://www.redmine.org/wiki/redmine/RedmineReminderEmails
+* http://www.redmine.org/wiki/redmine/RedmineLDAP
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d7/d79648acb8390e7dfe4f791129d77e634240a8ef.svn-base
--- a/.svn/pristine/d7/d79648acb8390e7dfe4f791129d77e634240a8ef.svn-base
+++ /dev/null
@@ -1,287 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # Scanner for Python. Supports Python 3.
-  # 
-  # Based on pygments' PythonLexer, see
-  # http://dev.pocoo.org/projects/pygments/browser/pygments/lexers/agile.py.
-  class Python < Scanner
-    
-    register_for :python
-    file_extension 'py'
-    
-    KEYWORDS = [
-      'and', 'as', 'assert', 'break', 'class', 'continue', 'def',
-      'del', 'elif', 'else', 'except', 'finally', 'for',
-      'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not',
-      'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield',
-      'nonlocal',  # new in Python 3
-    ]  # :nodoc:
-    
-    OLD_KEYWORDS = [
-      'exec', 'print',  # gone in Python 3
-    ]  # :nodoc:
-    
-    PREDEFINED_METHODS_AND_TYPES = %w[
-      __import__ abs all any apply basestring bin bool buffer
-      bytearray bytes callable chr classmethod cmp coerce compile
-      complex delattr dict dir divmod enumerate eval execfile exit
-      file filter float frozenset getattr globals hasattr hash hex id
-      input int intern isinstance issubclass iter len list locals
-      long map max min next object oct open ord pow property range
-      raw_input reduce reload repr reversed round set setattr slice
-      sorted staticmethod str sum super tuple type unichr unicode
-      vars xrange zip
-    ]  # :nodoc:
-    
-    PREDEFINED_EXCEPTIONS = %w[
-      ArithmeticError AssertionError AttributeError
-      BaseException DeprecationWarning EOFError EnvironmentError
-      Exception FloatingPointError FutureWarning GeneratorExit IOError
-      ImportError ImportWarning IndentationError IndexError KeyError
-      KeyboardInterrupt LookupError MemoryError NameError
-      NotImplemented NotImplementedError OSError OverflowError
-      OverflowWarning PendingDeprecationWarning ReferenceError
-      RuntimeError RuntimeWarning StandardError StopIteration
-      SyntaxError SyntaxWarning SystemError SystemExit TabError
-      TypeError UnboundLocalError UnicodeDecodeError
-      UnicodeEncodeError UnicodeError UnicodeTranslateError
-      UnicodeWarning UserWarning ValueError Warning ZeroDivisionError
-    ]  # :nodoc:
-    
-    PREDEFINED_VARIABLES_AND_CONSTANTS = [
-      'False', 'True', 'None',  # "keywords" since Python 3
-      'self', 'Ellipsis', 'NotImplemented',
-    ]  # :nodoc:
-    
-    IDENT_KIND = WordList.new(:ident).
-      add(KEYWORDS, :keyword).
-      add(OLD_KEYWORDS, :old_keyword).
-      add(PREDEFINED_METHODS_AND_TYPES, :predefined).
-      add(PREDEFINED_VARIABLES_AND_CONSTANTS, :predefined_constant).
-      add(PREDEFINED_EXCEPTIONS, :exception)  # :nodoc:
-    
-    NAME = / [^\W\d] \w* /x  # :nodoc:
-    ESCAPE = / [abfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x  # :nodoc:
-    UNICODE_ESCAPE =  / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} | N\{[-\w ]+\} /x  # :nodoc:
-    
-    OPERATOR = /
-      \.\.\. |          # ellipsis
-      \.(?!\d) |        # dot but not decimal point
-      [,;:()\[\]{}] |   # simple delimiters
-      \/\/=? | \*\*=? | # special math
-      [-+*\/%&|^]=? |   # ordinary math and binary logic
-      [~`] |            # binary complement and inspection
-      <<=? | >>=? | [<>=]=? | !=  # comparison and assignment
-    /x  # :nodoc:
-    
-    STRING_DELIMITER_REGEXP = Hash.new { |h, delimiter|
-      h[delimiter] = Regexp.union delimiter  # :nodoc:
-    }
-    
-    STRING_CONTENT_REGEXP = Hash.new { |h, delimiter|
-      h[delimiter] = / [^\\\n]+? (?= \\ | $ | #{Regexp.escape(delimiter)} ) /x  # :nodoc:
-    }
-    
-    DEF_NEW_STATE = WordList.new(:initial).
-      add(%w(def), :def_expected).
-      add(%w(import from), :include_expected).
-      add(%w(class), :class_expected)  # :nodoc:
-    
-    DESCRIPTOR = /
-      #{NAME}
-      (?: \. #{NAME} )*
-      | \*
-    /x  # :nodoc:
-    
-    DOCSTRING_COMING = /
-      [ \t]* u?r? ("""|''')
-    /x  # :nodoc:
-    
-  protected
-    
-    def scan_tokens encoder, options
-      
-      state = :initial
-      string_delimiter = nil
-      string_raw = false
-      string_type = nil
-      docstring_coming = match?(/#{DOCSTRING_COMING}/o)
-      last_token_dot = false
-      unicode = string.respond_to?(:encoding) && string.encoding.name == 'UTF-8'
-      from_import_state = []
-      
-      until eos?
-        
-        if state == :string
-          if match = scan(STRING_DELIMITER_REGEXP[string_delimiter])
-            encoder.text_token match, :delimiter
-            encoder.end_group string_type
-            string_type = nil
-            state = :initial
-            next
-          elsif string_delimiter.size == 3 && match = scan(/\n/)
-            encoder.text_token match, :content
-          elsif match = scan(STRING_CONTENT_REGEXP[string_delimiter])
-            encoder.text_token match, :content
-          elsif !string_raw && match = scan(/ \\ #{ESCAPE} /ox)
-            encoder.text_token match, :char
-          elsif match = scan(/ \\ #{UNICODE_ESCAPE} /ox)
-            encoder.text_token match, :char
-          elsif match = scan(/ \\ . /x)
-            encoder.text_token match, :content
-          elsif match = scan(/ \\ | $ /x)
-            encoder.end_group string_type
-            string_type = nil
-            encoder.text_token match, :error
-            state = :initial
-          else
-            raise_inspect "else case \" reached; %p not handled." % peek(1), encoder, state
-          end
-        
-        elsif match = scan(/ [ \t]+ | \\?\n /x)
-          encoder.text_token match, :space
-          if match == "\n"
-            state = :initial if state == :include_expected
-            docstring_coming = true if match?(/#{DOCSTRING_COMING}/o)
-          end
-          next
-        
-        elsif match = scan(/ \# [^\n]* /mx)
-          encoder.text_token match, :comment
-          next
-        
-        elsif state == :initial
-          
-          if match = scan(/#{OPERATOR}/o)
-            encoder.text_token match, :operator
-          
-          elsif match = scan(/(u?r?|b)?("""|"|'''|')/i)
-            string_delimiter = self[2]
-            string_type = docstring_coming ? :docstring : :string
-            docstring_coming = false if docstring_coming
-            encoder.begin_group string_type
-            string_raw = false
-            modifiers = self[1]
-            unless modifiers.empty?
-              string_raw = !!modifiers.index(?r)
-              encoder.text_token modifiers, :modifier
-              match = string_delimiter
-            end
-            state = :string
-            encoder.text_token match, :delimiter
-          
-          # TODO: backticks
-          
-          elsif match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o)
-            kind = IDENT_KIND[match]
-            # TODO: keyword arguments
-            kind = :ident if last_token_dot
-            if kind == :old_keyword
-              kind = check(/\(/) ? :ident : :keyword
-            elsif kind == :predefined && check(/ *=/)
-              kind = :ident
-            elsif kind == :keyword
-              state = DEF_NEW_STATE[match]
-              from_import_state << match.to_sym if state == :include_expected
-            end
-            encoder.text_token match, kind
-          
-          elsif match = scan(/@[a-zA-Z0-9_.]+[lL]?/)
-            encoder.text_token match, :decorator
-          
-          elsif match = scan(/0[xX][0-9A-Fa-f]+[lL]?/)
-            encoder.text_token match, :hex
-          
-          elsif match = scan(/0[bB][01]+[lL]?/)
-            encoder.text_token match, :binary
-          
-          elsif match = scan(/(?:\d*\.\d+|\d+\.\d*)(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+/)
-            if scan(/[jJ]/)
-              match << matched
-              encoder.text_token match, :imaginary
-            else
-              encoder.text_token match, :float
-            end
-          
-          elsif match = scan(/0[oO][0-7]+|0[0-7]+(?![89.eE])[lL]?/)
-            encoder.text_token match, :octal
-          
-          elsif match = scan(/\d+([lL])?/)
-            if self[1] == nil && scan(/[jJ]/)
-              match << matched
-              encoder.text_token match, :imaginary
-            else
-              encoder.text_token match, :integer
-            end
-          
-          else
-            encoder.text_token getch, :error
-          
-          end
-            
-        elsif state == :def_expected
-          state = :initial
-          if match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o)
-            encoder.text_token match, :method
-          else
-            next
-          end
-        
-        elsif state == :class_expected
-          state = :initial
-          if match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o)
-            encoder.text_token match, :class
-          else
-            next
-          end
-          
-        elsif state == :include_expected
-          if match = scan(unicode ? /#{DESCRIPTOR}/uo : /#{DESCRIPTOR}/o)
-            if match == 'as'
-              encoder.text_token match, :keyword
-              from_import_state << :as
-            elsif from_import_state.first == :from && match == 'import'
-              encoder.text_token match, :keyword
-              from_import_state << :import
-            elsif from_import_state.last == :as
-              # encoder.text_token match, match[0,1][unicode ? /[[:upper:]]/u : /[[:upper:]]/] ? :class : :method
-              encoder.text_token match, :ident
-              from_import_state.pop
-            elsif IDENT_KIND[match] == :keyword
-              unscan
-              match = nil
-              state = :initial
-              next
-            else
-              encoder.text_token match, :include
-            end
-          elsif match = scan(/,/)
-            from_import_state.pop if from_import_state.last == :as
-            encoder.text_token match, :operator
-          else
-            from_import_state = []
-            state = :initial
-            next
-          end
-          
-        else
-          raise_inspect 'Unknown state', encoder, state
-          
-        end
-        
-        last_token_dot = match == '.'
-        
-      end
-      
-      if state == :string
-        encoder.end_group string_type
-      end
-      
-      encoder
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d7/d7993eab0e03bf713eaae4e70ad89bacc08a8657.svn-base
--- /dev/null
+++ b/.svn/pristine/d7/d7993eab0e03bf713eaae4e70ad89bacc08a8657.svn-base
@@ -0,0 +1,37 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingPreviewsTest < ActionController::IntegrationTest
+  def test_previews
+    ["get", "post", "put"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/issues/preview/new/123" },
+          { :controller => 'previews', :action => 'issue', :project_id => '123' }
+        )
+      assert_routing(
+          { :method => method, :path => "/issues/preview/edit/321" },
+          { :controller => 'previews', :action => 'issue', :id => '321' }
+        )
+    end
+    assert_routing(
+        { :method => 'get', :path => "/news/preview" },
+        { :controller => 'previews', :action => 'news' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d7/d79a58970645e3cccc641d96056ab588a943ade9.svn-base
--- a/.svn/pristine/d7/d79a58970645e3cccc641d96056ab588a943ade9.svn-base
+++ /dev/null
@@ -1,17 +0,0 @@
---- 
-repositories_001: 
-  project_id: 1
-  url: file:///<%= Rails.root %>/tmp/test/subversion_repository
-  id: 10
-  root_url: file:///<%= Rails.root %>/tmp/test/subversion_repository
-  password: ""
-  login: ""
-  type: Subversion
-repositories_002: 
-  project_id: 2
-  url: svn://localhost/test
-  id: 11
-  root_url: svn://localhost
-  password: ""
-  login: ""
-  type: Subversion
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d8/d80da60d3b09791df71ff5976cfe2c8e851b79a7.svn-base
--- a/.svn/pristine/d8/d80da60d3b09791df71ff5976cfe2c8e851b79a7.svn-base
+++ /dev/null
@@ -1,1615 +0,0 @@
---- 
-workflows_189: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 2
-  id: 189
-  tracker_id: 3
-workflows_001: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 1
-  id: 1
-  tracker_id: 1
-workflows_002: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 1
-  id: 2
-  tracker_id: 1
-workflows_003: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 1
-  id: 3
-  tracker_id: 1
-workflows_110: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 4
-  id: 110
-  tracker_id: 2
-workflows_004: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 1
-  id: 4
-  tracker_id: 1
-workflows_030: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 6
-  id: 30
-  tracker_id: 1
-workflows_111: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 5
-  id: 111
-  tracker_id: 2
-workflows_005: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 1
-  id: 5
-  tracker_id: 1
-workflows_031: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 1
-  id: 31
-  tracker_id: 1
-workflows_112: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 5
-  id: 112
-  tracker_id: 2
-workflows_006: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 2
-  id: 6
-  tracker_id: 1
-workflows_032: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 1
-  id: 32
-  tracker_id: 1
-workflows_113: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 5
-  id: 113
-  tracker_id: 2
-workflows_220: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 2
-  id: 220
-  tracker_id: 3
-workflows_007: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 2
-  id: 7
-  tracker_id: 1
-workflows_033: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 1
-  id: 33
-  tracker_id: 1
-workflows_060: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 6
-  id: 60
-  tracker_id: 1
-workflows_114: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 5
-  id: 114
-  tracker_id: 2
-workflows_140: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 4
-  id: 140
-  tracker_id: 2
-workflows_221: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 3
-  id: 221
-  tracker_id: 3
-workflows_008: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 2
-  id: 8
-  tracker_id: 1
-workflows_034: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 1
-  id: 34
-  tracker_id: 1
-workflows_115: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 5
-  id: 115
-  tracker_id: 2
-workflows_141: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 5
-  id: 141
-  tracker_id: 2
-workflows_222: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 3
-  id: 222
-  tracker_id: 3
-workflows_223: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 3
-  id: 223
-  tracker_id: 3
-workflows_009: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 2
-  id: 9
-  tracker_id: 1
-workflows_035: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 1
-  id: 35
-  tracker_id: 1
-workflows_061: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 1
-  id: 61
-  tracker_id: 1
-workflows_116: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 6
-  id: 116
-  tracker_id: 2
-workflows_142: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 5
-  id: 142
-  tracker_id: 2
-workflows_250: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 2
-  id: 250
-  tracker_id: 3
-workflows_224: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 3
-  id: 224
-  tracker_id: 3
-workflows_036: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 2
-  id: 36
-  tracker_id: 1
-workflows_062: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 1
-  id: 62
-  tracker_id: 1
-workflows_117: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 6
-  id: 117
-  tracker_id: 2
-workflows_143: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 5
-  id: 143
-  tracker_id: 2
-workflows_170: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 4
-  id: 170
-  tracker_id: 2
-workflows_251: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 3
-  id: 251
-  tracker_id: 3
-workflows_225: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 3
-  id: 225
-  tracker_id: 3
-workflows_063: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 1
-  id: 63
-  tracker_id: 1
-workflows_090: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 6
-  id: 90
-  tracker_id: 1
-workflows_118: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 6
-  id: 118
-  tracker_id: 2
-workflows_144: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 5
-  id: 144
-  tracker_id: 2
-workflows_252: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 3
-  id: 252
-  tracker_id: 3
-workflows_226: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 4
-  id: 226
-  tracker_id: 3
-workflows_038: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 2
-  id: 38
-  tracker_id: 1
-workflows_064: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 1
-  id: 64
-  tracker_id: 1
-workflows_091: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 1
-  id: 91
-  tracker_id: 2
-workflows_119: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 6
-  id: 119
-  tracker_id: 2
-workflows_145: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 5
-  id: 145
-  tracker_id: 2
-workflows_171: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 5
-  id: 171
-  tracker_id: 2
-workflows_253: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 3
-  id: 253
-  tracker_id: 3
-workflows_227: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 4
-  id: 227
-  tracker_id: 3
-workflows_039: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 2
-  id: 39
-  tracker_id: 1
-workflows_065: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 1
-  id: 65
-  tracker_id: 1
-workflows_092: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 1
-  id: 92
-  tracker_id: 2
-workflows_146: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 6
-  id: 146
-  tracker_id: 2
-workflows_172: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 5
-  id: 172
-  tracker_id: 2
-workflows_254: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 3
-  id: 254
-  tracker_id: 3
-workflows_228: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 4
-  id: 228
-  tracker_id: 3
-workflows_066: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 2
-  id: 66
-  tracker_id: 1
-workflows_093: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 1
-  id: 93
-  tracker_id: 2
-workflows_147: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 6
-  id: 147
-  tracker_id: 2
-workflows_173: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 5
-  id: 173
-  tracker_id: 2
-workflows_255: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 3
-  id: 255
-  tracker_id: 3
-workflows_229: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 4
-  id: 229
-  tracker_id: 3
-workflows_067: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 2
-  id: 67
-  tracker_id: 1
-workflows_148: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 6
-  id: 148
-  tracker_id: 2
-workflows_174: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 5
-  id: 174
-  tracker_id: 2
-workflows_256: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 4
-  id: 256
-  tracker_id: 3
-workflows_068: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 2
-  id: 68
-  tracker_id: 1
-workflows_094: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 1
-  id: 94
-  tracker_id: 2
-workflows_149: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 6
-  id: 149
-  tracker_id: 2
-workflows_175: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 5
-  id: 175
-  tracker_id: 2
-workflows_257: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 4
-  id: 257
-  tracker_id: 3
-workflows_069: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 2
-  id: 69
-  tracker_id: 1
-workflows_095: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 1
-  id: 95
-  tracker_id: 2
-workflows_176: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 6
-  id: 176
-  tracker_id: 2
-workflows_258: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 4
-  id: 258
-  tracker_id: 3
-workflows_096: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 2
-  id: 96
-  tracker_id: 2
-workflows_177: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 6
-  id: 177
-  tracker_id: 2
-workflows_259: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 4
-  id: 259
-  tracker_id: 3
-workflows_097: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 2
-  id: 97
-  tracker_id: 2
-workflows_178: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 6
-  id: 178
-  tracker_id: 2
-workflows_098: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 2
-  id: 98
-  tracker_id: 2
-workflows_179: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 6
-  id: 179
-  tracker_id: 2
-workflows_099: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 2
-  id: 99
-  tracker_id: 2
-workflows_100: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 2
-  id: 100
-  tracker_id: 2
-workflows_020: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 4
-  id: 20
-  tracker_id: 1
-workflows_101: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 3
-  id: 101
-  tracker_id: 2
-workflows_021: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 5
-  id: 21
-  tracker_id: 1
-workflows_102: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 3
-  id: 102
-  tracker_id: 2
-workflows_210: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 6
-  id: 210
-  tracker_id: 3
-workflows_022: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 5
-  id: 22
-  tracker_id: 1
-workflows_103: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 3
-  id: 103
-  tracker_id: 2
-workflows_023: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 5
-  id: 23
-  tracker_id: 1
-workflows_104: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 3
-  id: 104
-  tracker_id: 2
-workflows_130: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 2
-  id: 130
-  tracker_id: 2
-workflows_211: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 1
-  id: 211
-  tracker_id: 3
-workflows_024: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 5
-  id: 24
-  tracker_id: 1
-workflows_050: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 4
-  id: 50
-  tracker_id: 1
-workflows_105: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 3
-  id: 105
-  tracker_id: 2
-workflows_131: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 3
-  id: 131
-  tracker_id: 2
-workflows_212: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 1
-  id: 212
-  tracker_id: 3
-workflows_025: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 5
-  id: 25
-  tracker_id: 1
-workflows_051: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 5
-  id: 51
-  tracker_id: 1
-workflows_106: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 4
-  id: 106
-  tracker_id: 2
-workflows_132: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 3
-  id: 132
-  tracker_id: 2
-workflows_213: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 1
-  id: 213
-  tracker_id: 3
-workflows_240: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 6
-  id: 240
-  tracker_id: 3
-workflows_026: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 6
-  id: 26
-  tracker_id: 1
-workflows_052: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 5
-  id: 52
-  tracker_id: 1
-workflows_107: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 4
-  id: 107
-  tracker_id: 2
-workflows_133: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 3
-  id: 133
-  tracker_id: 2
-workflows_214: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 1
-  id: 214
-  tracker_id: 3
-workflows_241: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 1
-  id: 241
-  tracker_id: 3
-workflows_027: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 6
-  id: 27
-  tracker_id: 1
-workflows_053: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 5
-  id: 53
-  tracker_id: 1
-workflows_080: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 4
-  id: 80
-  tracker_id: 1
-workflows_108: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 4
-  id: 108
-  tracker_id: 2
-workflows_134: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 3
-  id: 134
-  tracker_id: 2
-workflows_160: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 2
-  id: 160
-  tracker_id: 2
-workflows_215: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 1
-  id: 215
-  tracker_id: 3
-workflows_242: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 1
-  id: 242
-  tracker_id: 3
-workflows_028: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 6
-  id: 28
-  tracker_id: 1
-workflows_054: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 5
-  id: 54
-  tracker_id: 1
-workflows_081: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 5
-  id: 81
-  tracker_id: 1
-workflows_109: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 4
-  id: 109
-  tracker_id: 2
-workflows_135: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 3
-  id: 135
-  tracker_id: 2
-workflows_161: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 3
-  id: 161
-  tracker_id: 2
-workflows_216: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 2
-  id: 216
-  tracker_id: 3
-workflows_243: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 1
-  id: 243
-  tracker_id: 3
-workflows_029: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 6
-  id: 29
-  tracker_id: 1
-workflows_055: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 5
-  id: 55
-  tracker_id: 1
-workflows_082: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 5
-  id: 82
-  tracker_id: 1
-workflows_136: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 4
-  id: 136
-  tracker_id: 2
-workflows_162: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 3
-  id: 162
-  tracker_id: 2
-workflows_217: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 2
-  id: 217
-  tracker_id: 3
-workflows_270: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 6
-  id: 270
-  tracker_id: 3
-workflows_244: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 1
-  id: 244
-  tracker_id: 3
-workflows_056: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 6
-  id: 56
-  tracker_id: 1
-workflows_137: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 4
-  id: 137
-  tracker_id: 2
-workflows_163: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 3
-  id: 163
-  tracker_id: 2
-workflows_190: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 2
-  id: 190
-  tracker_id: 3
-workflows_218: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 2
-  id: 218
-  tracker_id: 3
-workflows_245: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 1
-  id: 245
-  tracker_id: 3
-workflows_057: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 6
-  id: 57
-  tracker_id: 1
-workflows_083: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 5
-  id: 83
-  tracker_id: 1
-workflows_138: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 4
-  id: 138
-  tracker_id: 2
-workflows_164: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 3
-  id: 164
-  tracker_id: 2
-workflows_191: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 3
-  id: 191
-  tracker_id: 3
-workflows_219: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 2
-  id: 219
-  tracker_id: 3
-workflows_246: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 2
-  id: 246
-  tracker_id: 3
-workflows_058: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 6
-  id: 58
-  tracker_id: 1
-workflows_084: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 5
-  id: 84
-  tracker_id: 1
-workflows_139: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 4
-  id: 139
-  tracker_id: 2
-workflows_165: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 3
-  id: 165
-  tracker_id: 2
-workflows_192: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 3
-  id: 192
-  tracker_id: 3
-workflows_247: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 2
-  id: 247
-  tracker_id: 3
-workflows_059: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 6
-  id: 59
-  tracker_id: 1
-workflows_085: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 5
-  id: 85
-  tracker_id: 1
-workflows_166: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 4
-  id: 166
-  tracker_id: 2
-workflows_248: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 2
-  id: 248
-  tracker_id: 3
-workflows_086: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 6
-  id: 86
-  tracker_id: 1
-workflows_167: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 4
-  id: 167
-  tracker_id: 2
-workflows_193: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 3
-  id: 193
-  tracker_id: 3
-workflows_249: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 2
-  id: 249
-  tracker_id: 3
-workflows_087: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 6
-  id: 87
-  tracker_id: 1
-workflows_168: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 4
-  id: 168
-  tracker_id: 2
-workflows_194: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 3
-  id: 194
-  tracker_id: 3
-workflows_088: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 6
-  id: 88
-  tracker_id: 1
-workflows_169: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 4
-  id: 169
-  tracker_id: 2
-workflows_195: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 3
-  id: 195
-  tracker_id: 3
-workflows_089: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 6
-  id: 89
-  tracker_id: 1
-workflows_196: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 4
-  id: 196
-  tracker_id: 3
-workflows_197: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 4
-  id: 197
-  tracker_id: 3
-workflows_198: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 4
-  id: 198
-  tracker_id: 3
-workflows_199: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 4
-  id: 199
-  tracker_id: 3
-workflows_010: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 2
-  id: 10
-  tracker_id: 1
-workflows_011: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 3
-  id: 11
-  tracker_id: 1
-workflows_012: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 3
-  id: 12
-  tracker_id: 1
-workflows_200: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 4
-  id: 200
-  tracker_id: 3
-workflows_013: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 3
-  id: 13
-  tracker_id: 1
-workflows_120: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 6
-  id: 120
-  tracker_id: 2
-workflows_201: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 5
-  id: 201
-  tracker_id: 3
-workflows_040: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 2
-  id: 40
-  tracker_id: 1
-workflows_121: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 1
-  id: 121
-  tracker_id: 2
-workflows_202: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 5
-  id: 202
-  tracker_id: 3
-workflows_014: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 3
-  id: 14
-  tracker_id: 1
-workflows_041: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 3
-  id: 41
-  tracker_id: 1
-workflows_122: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 1
-  id: 122
-  tracker_id: 2
-workflows_203: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 5
-  id: 203
-  tracker_id: 3
-workflows_015: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 3
-  id: 15
-  tracker_id: 1
-workflows_230: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 4
-  id: 230
-  tracker_id: 3
-workflows_123: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 1
-  id: 123
-  tracker_id: 2
-workflows_204: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 5
-  id: 204
-  tracker_id: 3
-workflows_016: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 4
-  id: 16
-  tracker_id: 1
-workflows_042: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 3
-  id: 42
-  tracker_id: 1
-workflows_231: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 5
-  id: 231
-  tracker_id: 3
-workflows_070: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 2
-  id: 70
-  tracker_id: 1
-workflows_124: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 1
-  id: 124
-  tracker_id: 2
-workflows_150: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 6
-  id: 150
-  tracker_id: 2
-workflows_205: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 5
-  id: 205
-  tracker_id: 3
-workflows_017: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 4
-  id: 17
-  tracker_id: 1
-workflows_043: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 3
-  id: 43
-  tracker_id: 1
-workflows_232: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 5
-  id: 232
-  tracker_id: 3
-workflows_125: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 1
-  id: 125
-  tracker_id: 2
-workflows_151: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 1
-  id: 151
-  tracker_id: 2
-workflows_206: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 6
-  id: 206
-  tracker_id: 3
-workflows_018: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 4
-  id: 18
-  tracker_id: 1
-workflows_044: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 3
-  id: 44
-  tracker_id: 1
-workflows_071: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 3
-  id: 71
-  tracker_id: 1
-workflows_233: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 5
-  id: 233
-  tracker_id: 3
-workflows_126: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 2
-  id: 126
-  tracker_id: 2
-workflows_152: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 1
-  id: 152
-  tracker_id: 2
-workflows_207: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 6
-  id: 207
-  tracker_id: 3
-workflows_019: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 4
-  id: 19
-  tracker_id: 1
-workflows_045: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 3
-  id: 45
-  tracker_id: 1
-workflows_260: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 4
-  id: 260
-  tracker_id: 3
-workflows_234: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 5
-  id: 234
-  tracker_id: 3
-workflows_127: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 2
-  id: 127
-  tracker_id: 2
-workflows_153: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 1
-  id: 153
-  tracker_id: 2
-workflows_180: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 6
-  id: 180
-  tracker_id: 2
-workflows_208: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 6
-  id: 208
-  tracker_id: 3
-workflows_046: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 4
-  id: 46
-  tracker_id: 1
-workflows_072: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 3
-  id: 72
-  tracker_id: 1
-workflows_261: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 5
-  id: 261
-  tracker_id: 3
-workflows_235: 
-  new_status_id: 6
-  role_id: 2
-  old_status_id: 5
-  id: 235
-  tracker_id: 3
-workflows_154: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 1
-  id: 154
-  tracker_id: 2
-workflows_181: 
-  new_status_id: 2
-  role_id: 1
-  old_status_id: 1
-  id: 181
-  tracker_id: 3
-workflows_209: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 6
-  id: 209
-  tracker_id: 3
-workflows_047: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 4
-  id: 47
-  tracker_id: 1
-workflows_073: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 3
-  id: 73
-  tracker_id: 1
-workflows_128: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 2
-  id: 128
-  tracker_id: 2
-workflows_262: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 5
-  id: 262
-  tracker_id: 3
-workflows_236: 
-  new_status_id: 1
-  role_id: 2
-  old_status_id: 6
-  id: 236
-  tracker_id: 3
-workflows_155: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 1
-  id: 155
-  tracker_id: 2
-workflows_048: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 4
-  id: 48
-  tracker_id: 1
-workflows_074: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 3
-  id: 74
-  tracker_id: 1
-workflows_129: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 2
-  id: 129
-  tracker_id: 2
-workflows_263: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 5
-  id: 263
-  tracker_id: 3
-workflows_237: 
-  new_status_id: 2
-  role_id: 2
-  old_status_id: 6
-  id: 237
-  tracker_id: 3
-workflows_182: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 1
-  id: 182
-  tracker_id: 3
-workflows_049: 
-  new_status_id: 5
-  role_id: 2
-  old_status_id: 4
-  id: 49
-  tracker_id: 1
-workflows_075: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 3
-  id: 75
-  tracker_id: 1
-workflows_156: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 2
-  id: 156
-  tracker_id: 2
-workflows_264: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 5
-  id: 264
-  tracker_id: 3
-workflows_238: 
-  new_status_id: 3
-  role_id: 2
-  old_status_id: 6
-  id: 238
-  tracker_id: 3
-workflows_183: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 1
-  id: 183
-  tracker_id: 3
-workflows_076: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 4
-  id: 76
-  tracker_id: 1
-workflows_157: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 2
-  id: 157
-  tracker_id: 2
-workflows_265: 
-  new_status_id: 6
-  role_id: 3
-  old_status_id: 5
-  id: 265
-  tracker_id: 3
-workflows_239: 
-  new_status_id: 4
-  role_id: 2
-  old_status_id: 6
-  id: 239
-  tracker_id: 3
-workflows_077: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 4
-  id: 77
-  tracker_id: 1
-workflows_158: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 2
-  id: 158
-  tracker_id: 2
-workflows_184: 
-  new_status_id: 5
-  role_id: 1
-  old_status_id: 1
-  id: 184
-  tracker_id: 3
-workflows_266: 
-  new_status_id: 1
-  role_id: 3
-  old_status_id: 6
-  id: 266
-  tracker_id: 3
-workflows_078: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 4
-  id: 78
-  tracker_id: 1
-workflows_159: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 2
-  id: 159
-  tracker_id: 2
-workflows_185: 
-  new_status_id: 6
-  role_id: 1
-  old_status_id: 1
-  id: 185
-  tracker_id: 3
-workflows_267: 
-  new_status_id: 2
-  role_id: 3
-  old_status_id: 6
-  id: 267
-  tracker_id: 3
-workflows_079: 
-  new_status_id: 5
-  role_id: 3
-  old_status_id: 4
-  id: 79
-  tracker_id: 1
-workflows_186: 
-  new_status_id: 1
-  role_id: 1
-  old_status_id: 2
-  id: 186
-  tracker_id: 3
-workflows_268: 
-  new_status_id: 3
-  role_id: 3
-  old_status_id: 6
-  id: 268
-  tracker_id: 3
-workflows_187: 
-  new_status_id: 3
-  role_id: 1
-  old_status_id: 2
-  id: 187
-  tracker_id: 3
-workflows_269: 
-  new_status_id: 4
-  role_id: 3
-  old_status_id: 6
-  id: 269
-  tracker_id: 3
-workflows_188: 
-  new_status_id: 4
-  role_id: 1
-  old_status_id: 2
-  id: 188
-  tracker_id: 3
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d8/d83bafa7609c4f835b3d41747d13968f00d9ddaf.svn-base
--- a/.svn/pristine/d8/d83bafa7609c4f835b3d41747d13968f00d9ddaf.svn-base
+++ /dev/null
@@ -1,91 +0,0 @@
-<h2><%= l(:label_bulk_edit_selected_issues) %></h2>
-
-<ul><%= @issues.collect {|i| content_tag('li', link_to(h("#{i.tracker} ##{i.id}"), { :action => 'show', :id => i }) + h(": #{i.subject}")) }.join("\n") %></ul>
-
-<% form_tag(:action => 'bulk_update') do %>
-<%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join %>
-<div class="box tabular">
-<fieldset class="attributes">
-<legend><%= l(:label_change_properties) %></legend>
-
-<div class="splitcontentleft">
-<p>
-  <label for="issue_tracker_id"><%= l(:field_tracker) %></label>
-  <%= select_tag('issue[tracker_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@trackers, :id, :name)) %>
-</p>
-<% if @available_statuses.any? %>
-<p>
-  <label for='issue_status_id'><%= l(:field_status) %></label>
-  <%= select_tag('issue[status_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@available_statuses, :id, :name)) %>
-</p>
-<% end %>
-<p>
-  <label for='issue_priority_id'><%= l(:field_priority) %></label>
-  <%= select_tag('issue[priority_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(IssuePriority.active, :id, :name)) %>
-</p>
-<p>
-  <label for='issue_assigned_to_id'><%= l(:field_assigned_to) %></label>
-  <%= select_tag('issue[assigned_to_id]', content_tag('option', l(:label_no_change_option), :value => '') +
-                                 content_tag('option', l(:label_nobody), :value => 'none') +
-                                 principals_options_for_select(@assignables)) %>
-</p>
-<% if @project %>
-<p>
-  <label for='issue_category_id'><%= l(:field_category) %></label>
-  <%= select_tag('issue[category_id]', content_tag('option', l(:label_no_change_option), :value => '') +
-                                content_tag('option', l(:label_none), :value => 'none') +
-                                options_from_collection_for_select(@project.issue_categories, :id, :name)) %>
-</p>
-<% end %>
-<% #TODO: allow editing versions when multiple projects %>
-<% if @project %>
-<p>
-  <label for='issue_fixed_version_id'><%= l(:field_fixed_version) %></label>
-  <%= select_tag('issue[fixed_version_id]', content_tag('option', l(:label_no_change_option), :value => '') +
-                                   content_tag('option', l(:label_none), :value => 'none') +
-                                   version_options_for_select(@project.shared_versions.open.sort)) %>
-</p>
-<% end %>
-
-<% @custom_fields.each do |custom_field| %>
-  <p><label><%= h(custom_field.name) %> <%= custom_field_tag_for_bulk_edit('issue', custom_field, @projects) %></label></p>
-<% end %>
-
-<%= call_hook(:view_issues_bulk_edit_details_bottom, { :issues => @issues }) %>
-</div>
-
-<div class="splitcontentright">
-<% if @project && User.current.allowed_to?(:manage_subtasks, @project) %>
-<p>
-  <label for='issue_parent_issue_id'><%= l(:field_parent_issue) %></label>
-  <%= text_field_tag 'issue[parent_issue_id]', '', :size => 10 %>
-</p>
-<div id="parent_issue_candidates" class="autocomplete"></div>
-<%= javascript_tag "observeParentIssueField('#{auto_complete_issues_path(:project_id => @project) }')" %>
-<% end %>
-<p>
-  <label for='issue_start_date'><%= l(:field_start_date) %></label>
-  <%= text_field_tag 'issue[start_date]', '', :size => 10 %><%= calendar_for('issue_start_date') %>
-</p>
-<p>
-  <label for='issue_due_date'><%= l(:field_due_date) %></label>
-  <%= text_field_tag 'issue[due_date]', '', :size => 10 %><%= calendar_for('issue_due_date') %>
-</p>
-<% if Issue.use_field_for_done_ratio? %>
-<p>
-  <label for='issue_done_ratio'><%= l(:field_done_ratio) %></label>
-  <%= select_tag 'issue[done_ratio]', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %>
-</p>
-<% end %>
-</div>
-
-</fieldset>
-
-<fieldset><legend><%= l(:field_notes) %></legend>
-<%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %>
-<%= wikitoolbar_for 'notes' %>
-</fieldset>
-</div>
-
-<p><%= submit_tag l(:button_submit) %></p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d8/d85492482f3555bd4792888f6e64bcab52480eca.svn-base
--- a/.svn/pristine/d8/d85492482f3555bd4792888f6e64bcab52480eca.svn-base
+++ /dev/null
@@ -1,342 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class RepositoryMercurialTest < ActiveSupport::TestCase
-  fixtures :projects
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
-  NUM_REV = 32
-  CHAR_1_HEX = "\xc3\x9c"
-
-  if File.directory?(REPOSITORY_PATH)
-    def setup
-      klass = Repository::Mercurial
-      assert_equal "Mercurial", klass.scm_name
-      assert klass.scm_adapter_class
-      assert_not_equal "", klass.scm_command
-      assert_equal true, klass.scm_available
-
-      @project    = Project.find(3)
-      @repository = Repository::Mercurial.create(
-                      :project => @project,
-                      :url     => REPOSITORY_PATH,
-                      :path_encoding => 'ISO-8859-1'
-                      )
-      assert @repository
-      @char_1        = CHAR_1_HEX.dup
-      @tag_char_1    = "tag-#{CHAR_1_HEX}-00"
-      @branch_char_0 = "branch-#{CHAR_1_HEX}-00"
-      @branch_char_1 = "branch-#{CHAR_1_HEX}-01"
-      if @char_1.respond_to?(:force_encoding)
-        @char_1.force_encoding('UTF-8')
-        @tag_char_1.force_encoding('UTF-8')
-        @branch_char_0.force_encoding('UTF-8')
-        @branch_char_1.force_encoding('UTF-8')
-      end
-    end
-
-    def test_fetch_changesets_from_scratch
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_equal 46, @repository.changes.count
-      assert_equal "Initial import.\nThe repository contains 3 files.",
-                   @repository.changesets.find_by_revision('0').comments
-    end
-
-    def test_fetch_changesets_incremental
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      # Remove changesets with revision > 2
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 2}
-      @project.reload
-      assert_equal 3, @repository.changesets.count
-
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-    end
-
-    def test_isodatesec
-      # Template keyword 'isodatesec' supported in Mercurial 1.0 and higher
-      if @repository.scm.class.client_version_above?([1, 0])
-        assert_equal 0, @repository.changesets.count
-        @repository.fetch_changesets
-        @project.reload
-        assert_equal NUM_REV, @repository.changesets.count
-        rev0_committed_on = Time.gm(2007, 12, 14, 9, 22, 52)
-        assert_equal @repository.changesets.find_by_revision('0').committed_on, rev0_committed_on
-      end
-    end
-
-    def test_changeset_order_by_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      c0 = @repository.latest_changeset
-      c1 = @repository.changesets.find_by_revision('0')
-      # sorted by revision (id), not by date
-      assert c0.revision.to_i > c1.revision.to_i
-      assert c0.committed_on  < c1.committed_on
-    end
-
-    def test_latest_changesets
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      # with_limit
-      changesets = @repository.latest_changesets('', nil, 2)
-      assert_equal %w|31 30|, changesets.collect(&:revision)
-
-      # with_filepath
-      changesets = @repository.latest_changesets(
-                      '/sql_escape/percent%dir/percent%file1.txt', nil)
-      assert_equal %w|30 11 10 9|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets(
-                      '/sql_escape/underscore_dir/understrike_file.txt', nil)
-      assert_equal %w|30 12 9|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README', nil)
-      assert_equal %w|31 30 28 17 8 6 1 0|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README','8')
-      assert_equal %w|8 6 1 0|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('README','8', 2)
-      assert_equal %w|8 6|, changesets.collect(&:revision)
-
-      # with_dirpath
-      changesets = @repository.latest_changesets('images', nil)
-      assert_equal %w|1 0|, changesets.collect(&:revision)
-
-      path = 'sql_escape/percent%dir'
-      changesets = @repository.latest_changesets(path, nil)
-      assert_equal %w|30 13 11 10 9|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets(path, '11')
-      assert_equal %w|11 10 9|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets(path, '11', 2)
-      assert_equal %w|11 10|, changesets.collect(&:revision)
-
-      path = 'sql_escape/underscore_dir'
-      changesets = @repository.latest_changesets(path, nil)
-      assert_equal %w|30 13 12 9|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets(path, '12')
-      assert_equal %w|12 9|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets(path, '12', 1)
-      assert_equal %w|12|, changesets.collect(&:revision)
-
-      # tag
-      changesets = @repository.latest_changesets('', 'tag_test.00')
-      assert_equal %w|5 4 3 2 1 0|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('', 'tag_test.00', 2)
-      assert_equal %w|5 4|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('sources', 'tag_test.00')
-      assert_equal %w|4 3 2 1 0|, changesets.collect(&:revision)
-
-      changesets = @repository.latest_changesets('sources', 'tag_test.00', 2)
-      assert_equal %w|4 3|, changesets.collect(&:revision)
-
-      # named branch
-      if @repository.scm.class.client_version_above?([1, 6])
-        changesets = @repository.latest_changesets('', @branch_char_1)
-        assert_equal %w|27 26|, changesets.collect(&:revision)
-      end
-
-      changesets = @repository.latest_changesets("latin-1-dir/test-#{@char_1}-subdir", @branch_char_1)
-      assert_equal %w|27|, changesets.collect(&:revision)
-    end
-
-    def test_copied_files
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      cs1 = @repository.changesets.find_by_revision('13')
-      assert_not_nil cs1
-      c1  = cs1.changes.sort_by(&:path)
-      assert_equal 2, c1.size
-
-      assert_equal 'A', c1[0].action
-      assert_equal '/sql_escape/percent%dir/percentfile1.txt',  c1[0].path
-      assert_equal '/sql_escape/percent%dir/percent%file1.txt', c1[0].from_path
-      assert_equal '3a330eb32958', c1[0].from_revision
-
-      assert_equal 'A', c1[1].action
-      assert_equal '/sql_escape/underscore_dir/understrike-file.txt', c1[1].path
-      assert_equal '/sql_escape/underscore_dir/understrike_file.txt', c1[1].from_path
-
-      cs2 = @repository.changesets.find_by_revision('15')
-      c2  = cs2.changes
-      assert_equal 1, c2.size
-
-      assert_equal 'A', c2[0].action
-      assert_equal '/README (1)[2]&,%.-3_4', c2[0].path
-      assert_equal '/README', c2[0].from_path
-      assert_equal '933ca60293d7', c2[0].from_revision
-
-      cs3 = @repository.changesets.find_by_revision('19')
-      c3  = cs3.changes
-      assert_equal 1, c3.size
-      assert_equal 'A', c3[0].action
-      assert_equal "/latin-1-dir/test-#{@char_1}-1.txt",  c3[0].path
-      assert_equal "/latin-1-dir/test-#{@char_1}.txt",    c3[0].from_path
-      assert_equal '5d9891a1b425', c3[0].from_revision
-    end
-
-    def test_find_changeset_by_name
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      %w|2 400bb8672109 400|.each do |r|
-        assert_equal '2', @repository.find_changeset_by_name(r).revision
-      end
-    end
-
-    def test_find_changeset_by_invalid_name
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      assert_nil @repository.find_changeset_by_name('100000')
-    end
-
-    def test_identifier
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      c = @repository.changesets.find_by_revision('2')
-      assert_equal c.scmid, c.identifier
-    end
-
-    def test_format_identifier
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      c = @repository.changesets.find_by_revision('2')
-      assert_equal '2:400bb8672109', c.format_identifier
-    end
-
-    def test_find_changeset_by_empty_name
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['', ' ', nil].each do |r|
-        assert_nil @repository.find_changeset_by_name(r)
-      end
-    end
-
-    def test_parents
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      r1 = @repository.changesets.find_by_revision('0')
-      assert_equal [], r1.parents
-      r2 = @repository.changesets.find_by_revision('1')
-      assert_equal 1, r2.parents.length
-      assert_equal "0885933ad4f6",
-                   r2.parents[0].identifier
-      r3 = @repository.changesets.find_by_revision('30')
-      assert_equal 2, r3.parents.length
-      r4 = [r3.parents[0].identifier, r3.parents[1].identifier].sort
-      assert_equal "3a330eb32958", r4[0]
-      assert_equal "a94b0528f24f", r4[1]
-    end
-
-    def test_activities
-      c = Changeset.new(:repository   => @repository,
-                        :committed_on => Time.now,
-                        :revision     => '123',
-                        :scmid        => 'abc400bb8672',
-                        :comments     => 'test')
-      assert c.event_title.include?('123:abc400bb8672:')
-      assert_equal 'abc400bb8672', c.event_url[:rev]
-    end
-
-    def test_previous
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      %w|28 3ae45e2d177d 3ae45|.each do |r1|
-        changeset = @repository.find_changeset_by_name(r1)
-        %w|27 7bbf4c738e71 7bbf|.each do |r2|
-          assert_equal @repository.find_changeset_by_name(r2), changeset.previous
-        end
-      end
-    end
-
-    def test_previous_nil
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      %w|0 0885933ad4f6 0885|.each do |r1|
-        changeset = @repository.find_changeset_by_name(r1)
-        assert_nil changeset.previous
-      end
-    end
-
-    def test_next
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      %w|27 7bbf4c738e71 7bbf|.each do |r2|
-        changeset = @repository.find_changeset_by_name(r2)
-        %w|28 3ae45e2d177d 3ae45|.each do |r1|
-        assert_equal @repository.find_changeset_by_name(r1), changeset.next
-        end
-      end
-    end
-
-    def test_next_nil
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      %w|31 31eeee7395c8 31eee|.each do |r1|
-        changeset = @repository.find_changeset_by_name(r1)
-        assert_nil changeset.next
-      end
-    end
-  else
-    puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d8/d8a1532f2aee52af2f226f2b6de368773957b39e.svn-base
--- a/.svn/pristine/d8/d8a1532f2aee52af2f226f2b6de368773957b39e.svn-base
+++ /dev/null
@@ -1,85 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class EnumerationsController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin
-
-  helper :custom_fields
-  include CustomFieldsHelper
-
-  def index
-  end
-
-  verify :method => :post, :only => [ :destroy, :create, :update ],
-         :redirect_to => { :action => :index }
-
-  def new
-    begin
-      @enumeration = params[:type].constantize.new
-    rescue NameError
-      @enumeration = Enumeration.new
-    end
-  end
-
-  def create
-    @enumeration = Enumeration.new(params[:enumeration])
-    @enumeration.type = params[:enumeration][:type]
-    if @enumeration.save
-      flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index', :type => @enumeration.type
-    else
-      render :action => 'new'
-    end
-  end
-
-  def edit
-    @enumeration = Enumeration.find(params[:id])
-  end
-
-  def update
-    @enumeration = Enumeration.find(params[:id])
-    @enumeration.type = params[:enumeration][:type] if params[:enumeration][:type]
-    if @enumeration.update_attributes(params[:enumeration])
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index', :type => @enumeration.type
-    else
-      render :action => 'edit'
-    end
-  end
-
-  def destroy
-    @enumeration = Enumeration.find(params[:id])
-    if !@enumeration.in_use?
-      # No associated objects
-      @enumeration.destroy
-      redirect_to :action => 'index'
-      return
-    elsif params[:reassign_to_id]
-      if reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id])
-        @enumeration.destroy(reassign_to)
-        redirect_to :action => 'index'
-        return
-      end
-    end
-    @enumerations = @enumeration.class.find(:all) - [@enumeration]
-  #rescue
-  #  flash[:error] = 'Unable to delete enumeration'
-  #  redirect_to :action => 'index'
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d8/d8da15b6a8a2fb05e57342be295616d42903caef.svn-base
--- /dev/null
+++ b/.svn/pristine/d8/d8da15b6a8a2fb05e57342be295616d42903caef.svn-base
@@ -0,0 +1,55 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'fileutils'
+
+module Redmine
+  module Thumbnail
+    extend Redmine::Utils::Shell
+
+    CONVERT_BIN = (Redmine::Configuration['imagemagick_convert_command'] || 'convert').freeze
+
+    # Generates a thumbnail for the source image to target
+    def self.generate(source, target, size)
+      return nil unless convert_available?
+      unless File.exists?(target)
+        directory = File.dirname(target)
+        unless File.exists?(directory)
+          FileUtils.mkdir_p directory
+        end
+        size_option = "#{size}x#{size}>"
+        cmd = "#{shell_quote CONVERT_BIN} #{shell_quote source} -thumbnail #{shell_quote size_option} #{shell_quote target}"
+        unless system(cmd)
+          logger.error("Creating thumbnail failed (#{$?}):\nCommand: #{cmd}")
+          return nil
+        end
+      end
+      target
+    end
+
+    def self.convert_available?
+      return @convert_available if defined?(@convert_available)
+      @convert_available = system("#{shell_quote CONVERT_BIN} -version") rescue false
+      logger.warn("Imagemagick's convert binary (#{CONVERT_BIN}) not available") unless @convert_available
+      @convert_available
+    end
+
+    def self.logger
+      Rails.logger
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d8/d8e9da00dfea83d984989db0c06cbb5c3633374a.svn-base
--- a/.svn/pristine/d8/d8e9da00dfea83d984989db0c06cbb5c3633374a.svn-base
+++ /dev/null
@@ -1,103 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class WikiTest < ActiveSupport::TestCase
-  fixtures :projects, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
-
-  def test_create
-    wiki = Wiki.new(:project => Project.find(2))
-    assert !wiki.save
-    assert_equal 1, wiki.errors.count
-
-    wiki.start_page = "Start page"
-    assert wiki.save
-  end
-
-  def test_update
-    @wiki = Wiki.find(1)
-    @wiki.start_page = "Another start page"
-    assert @wiki.save
-    @wiki.reload
-    assert_equal "Another start page", @wiki.start_page
-  end
-
-  def test_find_page_should_not_be_case_sensitive
-    wiki = Wiki.find(1)
-    page = WikiPage.find(2)
-
-    assert_equal page, wiki.find_page('Another_page')
-    assert_equal page, wiki.find_page('Another page')
-    assert_equal page, wiki.find_page('ANOTHER page')
-  end
-
-  def test_find_page_with_cyrillic_characters
-    wiki = Wiki.find(1)
-    page = WikiPage.find(10)
-    assert_equal page, wiki.find_page('Ð­Ñ‚Ð¸ÐºÐ°_Ð¼ÐµÐ½ÐµÐ´Ð¶Ð¼ÐµÐ½Ñ‚Ð°')
-  end
-
-  def test_find_page_with_backslashes
-    wiki = Wiki.find(1)
-    page = WikiPage.generate!(:wiki => wiki, :title => '2009\\02\\09')
-    assert_equal page, wiki.find_page('2009\\02\\09')
-  end
-
-  def test_find_page_without_redirect
-    wiki = Wiki.find(1)
-    page = wiki.find_page('Another_page')
-    assert_not_nil page
-    assert_equal 'Another_page', page.title
-    assert_equal false, wiki.page_found_with_redirect?
-  end
-
-  def test_find_page_with_redirect
-    wiki = Wiki.find(1)
-    WikiRedirect.create!(:wiki => wiki, :title => 'Old_title', :redirects_to => 'Another_page')
-    page = wiki.find_page('Old_title')
-    assert_not_nil page
-    assert_equal 'Another_page', page.title
-    assert_equal true, wiki.page_found_with_redirect?
-  end
-
-  def test_titleize
-    assert_equal 'Page_title_with_CAPITALES', Wiki.titleize('page title with CAPITALES')
-    assert_equal 'ãƒ†ã‚¹ãƒˆ', Wiki.titleize('ãƒ†ã‚¹ãƒˆ')
-  end
-
-  context "#sidebar" do
-    setup do
-      @wiki = Wiki.find(1)
-    end
-
-    should "return nil if undefined" do
-      assert_nil @wiki.sidebar
-    end
-
-    should "return a WikiPage if defined" do
-      page = @wiki.pages.new(:title => 'Sidebar')
-      page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
-      page.save!
-
-      assert_kind_of WikiPage, @wiki.sidebar
-      assert_equal 'Sidebar', @wiki.sidebar.title
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d8/d8ff1c547a8ab5f2037b019f178ac4f2175d8b5d.svn-base
--- a/.svn/pristine/d8/d8ff1c547a8ab5f2037b019f178ac4f2175d8b5d.svn-base
+++ /dev/null
@@ -1,201 +0,0 @@
-module CodeRay
-  
-  # This module holds the Encoder class and its subclasses.
-  # For example, the HTML encoder is named CodeRay::Encoders::HTML
-  # can be found in coderay/encoders/html.
-  #
-  # Encoders also provides methods and constants for the register
-  # mechanism and the [] method that returns the Encoder class
-  # belonging to the given format.
-  module Encoders
-    
-    extend PluginHost
-    plugin_path File.dirname(__FILE__), 'encoders'
-    
-    # = Encoder
-    #
-    # The Encoder base class. Together with Scanner and
-    # Tokens, it forms the highlighting triad.
-    #
-    # Encoder instances take a Tokens object and do something with it.
-    #
-    # The most common Encoder is surely the HTML encoder
-    # (CodeRay::Encoders::HTML). It highlights the code in a colorful
-    # html page.
-    # If you want the highlighted code in a div or a span instead,
-    # use its subclasses Div and Span.
-    class Encoder
-      extend Plugin
-      plugin_host Encoders
-      
-      class << self
-        
-        # If FILE_EXTENSION isn't defined, this method returns the
-        # downcase class name instead.
-        def const_missing sym
-          if sym == :FILE_EXTENSION
-            (defined?(@plugin_id) && @plugin_id || name[/\w+$/].downcase).to_s
-          else
-            super
-          end
-        end
-        
-        # The default file extension for output file of this encoder class.
-        def file_extension
-          self::FILE_EXTENSION
-        end
-        
-      end
-      
-      # Subclasses are to store their default options in this constant.
-      DEFAULT_OPTIONS = { }
-      
-      # The options you gave the Encoder at creating.
-      attr_accessor :options, :scanner
-      
-      # Creates a new Encoder.
-      # +options+ is saved and used for all encode operations, as long
-      # as you don't overwrite it there by passing additional options.
-      #
-      # Encoder objects provide three encode methods:
-      # - encode simply takes a +code+ string and a +lang+
-      # - encode_tokens expects a +tokens+ object instead
-      #
-      # Each method has an optional +options+ parameter. These are
-      # added to the options you passed at creation.
-      def initialize options = {}
-        @options = self.class::DEFAULT_OPTIONS.merge options
-        @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN = false
-      end
-      
-      # Encode a Tokens object.
-      def encode_tokens tokens, options = {}
-        options = @options.merge options
-        @scanner = tokens.scanner if tokens.respond_to? :scanner
-        setup options
-        compile tokens, options
-        finish options
-      end
-      
-      # Encode the given +code+ using the Scanner for +lang+.
-      def encode code, lang, options = {}
-        options = @options.merge options
-        @scanner = Scanners[lang].new code, CodeRay.get_scanner_options(options).update(:tokens => self)
-        setup options
-        @scanner.tokenize
-        finish options
-      end
-      
-      # You can use highlight instead of encode, if that seems
-      # more clear to you.
-      alias highlight encode
-      
-      # The default file extension for this encoder.
-      def file_extension
-        self.class.file_extension
-      end
-      
-      def << token
-        unless @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN
-          warn 'Using old Tokens#<< interface.'
-          @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN = true
-        end
-        self.token(*token)
-      end
-      
-      # Called with +content+ and +kind+ of the currently scanned token.
-      # For simple scanners, it's enougth to implement this method.
-      #
-      # By default, it calls text_token, begin_group, end_group, begin_line,
-      # or end_line, depending on the +content+.
-      def token content, kind
-        case content
-        when String
-          text_token content, kind
-        when :begin_group
-          begin_group kind
-        when :end_group
-          end_group kind
-        when :begin_line
-          begin_line kind
-        when :end_line
-          end_line kind
-        else
-          raise ArgumentError, 'Unknown token content type: %p, kind = %p' % [content, kind]
-        end
-      end
-      
-      # Called for each text token ([text, kind]), where text is a String.
-      def text_token text, kind
-        @out << text
-      end
-      
-      # Starts a token group with the given +kind+.
-      def begin_group kind
-      end
-      
-      # Ends a token group with the given +kind+.
-      def end_group kind
-      end
-      
-      # Starts a new line token group with the given +kind+.
-      def begin_line kind
-      end
-      
-      # Ends a new line token group with the given +kind+.
-      def end_line kind
-      end
-      
-    protected
-      
-      # Called with merged options before encoding starts.
-      # Sets @out to an empty string.
-      #
-      # See the HTML Encoder for an example of option caching.
-      def setup options
-        @out = get_output(options)
-      end
-      
-      def get_output options
-        options[:out] || ''
-      end
-      
-      # Append data.to_s to the output. Returns the argument.
-      def output data
-        @out << data.to_s
-        data
-      end
-      
-      # Called with merged options after encoding starts.
-      # The return value is the result of encoding, typically @out.
-      def finish options
-        @out
-      end
-      
-      # Do the encoding.
-      #
-      # The already created +tokens+ object must be used; it must be a
-      # Tokens object.
-      def compile tokens, options = {}
-        content = nil
-        for item in tokens
-          if item.is_a? Array
-            raise ArgumentError, 'Two-element array tokens are no longer supported.'
-          end
-          if content
-            token content, item
-            content = nil
-          else
-            content = item
-          end
-        end
-        raise 'odd number list for Tokens' if content
-      end
-      
-      alias tokens compile
-      public :tokens
-      
-    end
-    
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d9/d9145aecdf1e457a5a7621d312378e695962ee1a.svn-base
--- a/.svn/pristine/d9/d9145aecdf1e457a5a7621d312378e695962ee1a.svn-base
+++ /dev/null
@@ -1,237 +0,0 @@
-require 'redmine/access_control'
-require 'redmine/menu_manager'
-require 'redmine/activity'
-require 'redmine/search'
-require 'redmine/custom_field_format'
-require 'redmine/mime_type'
-require 'redmine/core_ext'
-require 'redmine/themes'
-require 'redmine/hook'
-require 'redmine/plugin'
-require 'redmine/notifiable'
-require 'redmine/wiki_formatting'
-require 'redmine/scm/base'
-
-begin
-  require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
-rescue LoadError
-  # RMagick is not available
-end
-
-if RUBY_VERSION < '1.9'
-  require 'faster_csv'
-else
-  require 'csv'
-  FCSV = CSV
-end
-
-Redmine::Scm::Base.add "Subversion"
-Redmine::Scm::Base.add "Darcs"
-Redmine::Scm::Base.add "Mercurial"
-Redmine::Scm::Base.add "Cvs"
-Redmine::Scm::Base.add "Bazaar"
-Redmine::Scm::Base.add "Git"
-Redmine::Scm::Base.add "Filesystem"
-
-Redmine::CustomFieldFormat.map do |fields|
-  fields.register Redmine::CustomFieldFormat.new('string', :label => :label_string, :order => 1)
-  fields.register Redmine::CustomFieldFormat.new('text', :label => :label_text, :order => 2)
-  fields.register Redmine::CustomFieldFormat.new('int', :label => :label_integer, :order => 3)
-  fields.register Redmine::CustomFieldFormat.new('float', :label => :label_float, :order => 4)
-  fields.register Redmine::CustomFieldFormat.new('list', :label => :label_list, :order => 5)
-  fields.register Redmine::CustomFieldFormat.new('date', :label => :label_date, :order => 6)
-  fields.register Redmine::CustomFieldFormat.new('bool', :label => :label_boolean, :order => 7)
-  fields.register Redmine::CustomFieldFormat.new('user', :label => :label_user, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 8)
-  fields.register Redmine::CustomFieldFormat.new('version', :label => :label_version, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 9)
-end
-
-# Permissions
-Redmine::AccessControl.map do |map|
-  map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true
-  map.permission :search_project, {:search => :index}, :public => true
-  map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
-  map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
-  map.permission :select_project_modules, {:projects => :modules}, :require => :member
-  map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy, :autocomplete_for_member]}, :require => :member
-  map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
-  map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
-
-  map.project_module :issue_tracking do |map|
-    # Issue categories
-    map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
-    # Issues
-    map.permission :view_issues, {:issues => [:index, :show],
-                                  :auto_complete => [:issues],
-                                  :context_menus => [:issues],
-                                  :versions => [:index, :show, :status_by],
-                                  :journals => [:index, :diff],
-                                  :queries => :index,
-                                  :reports => [:issue_report, :issue_report_details]}
-    map.permission :add_issues, {:issues => [:new, :create, :update_form]}
-    map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]}
-    map.permission :manage_issue_relations, {:issue_relations => [:index, :show, :create, :destroy]}
-    map.permission :manage_subtasks, {}
-    map.permission :set_issues_private, {}
-    map.permission :set_own_issues_private, {}, :require => :loggedin
-    map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]}
-    map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
-    map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
-    map.permission :move_issues, {:issue_moves => [:new, :create]}, :require => :loggedin
-    map.permission :delete_issues, {:issues => :destroy}, :require => :member
-    # Queries
-    map.permission :manage_public_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :member
-    map.permission :save_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
-    # Watchers
-    map.permission :view_issue_watchers, {}
-    map.permission :add_issue_watchers, {:watchers => :new}
-    map.permission :delete_issue_watchers, {:watchers => :destroy}
-  end
-
-  map.project_module :time_tracking do |map|
-    map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
-    map.permission :view_time_entries, :timelog => [:index, :show], :time_entry_reports => [:report]
-    map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
-    map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
-    map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
-  end
-
-  map.project_module :news do |map|
-    map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
-    map.permission :view_news, {:news => [:index, :show]}, :public => true
-    map.permission :comment_news, {:comments => :create}
-  end
-
-  map.project_module :documents do |map|
-    map.permission :manage_documents, {:documents => [:new, :edit, :destroy, :add_attachment]}, :require => :loggedin
-    map.permission :view_documents, :documents => [:index, :show, :download]
-  end
-
-  map.project_module :files do |map|
-    map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
-    map.permission :view_files, :files => :index, :versions => :download
-  end
-
-  map.project_module :wiki do |map|
-    map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
-    map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
-    map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
-    map.permission :view_wiki_pages, :wiki => [:index, :show, :special, :date_index]
-    map.permission :export_wiki_pages, :wiki => [:export]
-    map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
-    map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
-    map.permission :delete_wiki_pages_attachments, {}
-    map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
-  end
-
-  map.project_module :repository do |map|
-    map.permission :manage_repository, {:repositories => [:edit, :committers, :destroy]}, :require => :member
-    map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
-    map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
-    map.permission :commit_access, {}
-  end
-
-  map.project_module :boards do |map|
-    map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
-    map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
-    map.permission :add_messages, {:messages => [:new, :reply, :quote]}
-    map.permission :edit_messages, {:messages => :edit}, :require => :member
-    map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
-    map.permission :delete_messages, {:messages => :destroy}, :require => :member
-    map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
-  end
-
-  map.project_module :calendar do |map|
-    map.permission :view_calendar, :calendars => [:show, :update]
-  end
-
-  map.project_module :gantt do |map|
-    map.permission :view_gantt, :gantts => [:show, :update]
-  end
-end
-
-Redmine::MenuManager.map :top_menu do |menu|
-  menu.push :home, :home_path
-  menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
-  menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
-  menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
-  menu.push :help, Redmine::Info.help_url, :last => true
-end
-
-Redmine::MenuManager.map :account_menu do |menu|
-  menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
-  menu.push :register, { :controller => 'account', :action => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
-  menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
-  menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
-end
-
-Redmine::MenuManager.map :application_menu do |menu|
-  # Empty
-end
-
-Redmine::MenuManager.map :admin_menu do |menu|
-  menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
-  menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
-  menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
-  menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
-  menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
-  menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
-            :html => {:class => 'issue_statuses'}
-  menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
-  menu.push :custom_fields, {:controller => 'custom_fields'},  :caption => :label_custom_field_plural,
-            :html => {:class => 'custom_fields'}
-  menu.push :enumerations, {:controller => 'enumerations'}
-  menu.push :settings, {:controller => 'settings'}
-  menu.push :ldap_authentication, {:controller => 'ldap_auth_sources', :action => 'index'},
-            :html => {:class => 'server_authentication'}
-  menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
-  menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
-end
-
-Redmine::MenuManager.map :project_menu do |menu|
-  menu.push :overview, { :controller => 'projects', :action => 'show' }
-  menu.push :activity, { :controller => 'activities', :action => 'index' }
-  menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
-              :if => Proc.new { |p| p.shared_versions.any? }
-  menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
-  menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
-              :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
-  menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
-  menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
-  menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
-  menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
-  menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
-              :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
-  menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
-              :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
-  menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
-  menu.push :repository, { :controller => 'repositories', :action => 'show' },
-              :if => Proc.new { |p| p.repository && !p.repository.new_record? }
-  menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
-end
-
-Redmine::Activity.map do |activity|
-  activity.register :issues, :class_name => %w(Issue Journal)
-  activity.register :changesets
-  activity.register :news
-  activity.register :documents, :class_name => %w(Document Attachment)
-  activity.register :files, :class_name => 'Attachment'
-  activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
-  activity.register :messages, :default => false
-  activity.register :time_entries, :default => false
-end
-
-Redmine::Search.map do |search|
-  search.register :issues
-  search.register :news
-  search.register :documents
-  search.register :changesets
-  search.register :wiki_pages
-  search.register :messages
-  search.register :projects
-end
-
-Redmine::WikiFormatting.map do |format|
-  format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
-end
-
-ActionView::Template.register_template_handler :rsb, Redmine::Views::ApiTemplateHandler
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d9/d9247e732a56dd9b3466a2d481b475b595b379f2.svn-base
--- /dev/null
+++ b/.svn/pristine/d9/d9247e732a56dd9b3466a2d481b475b595b379f2.svn-base
@@ -0,0 +1,183 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ProjectNestedSetTest < ActiveSupport::TestCase
+
+  def setup
+    Project.delete_all
+
+    @a = Project.create!(:name => 'A', :identifier => 'projecta')
+    @a1 = Project.create!(:name => 'A1', :identifier => 'projecta1')
+    @a1.set_parent!(@a)
+    @a2 = Project.create!(:name => 'A2', :identifier => 'projecta2')
+    @a2.set_parent!(@a)
+
+    @c = Project.create!(:name => 'C', :identifier => 'projectc')
+    @c1 = Project.create!(:name => 'C1', :identifier => 'projectc1')
+    @c1.set_parent!(@c)
+
+    @b = Project.create!(:name => 'B', :identifier => 'projectb')
+    @b2 = Project.create!(:name => 'B2', :identifier => 'projectb2')
+    @b2.set_parent!(@b)
+    @b1 = Project.create!(:name => 'B1', :identifier => 'projectb1')
+    @b1.set_parent!(@b)
+    @b11 = Project.create!(:name => 'B11', :identifier => 'projectb11')
+    @b11.set_parent!(@b1)
+
+    @a, @a1, @a2, @b, @b1, @b11, @b2, @c, @c1 = *(Project.all.sort_by(&:name))
+  end
+
+  def test_valid_tree
+    assert_valid_nested_set
+  end
+
+  def test_rebuild_should_build_valid_tree
+    Project.update_all "lft = NULL, rgt = NULL"
+
+    Project.rebuild!
+    assert_valid_nested_set
+  end
+
+  def test_rebuild_tree_should_build_valid_tree_even_with_valid_lft_rgt_values
+    Project.update_all "name = 'YY'", {:id => @a.id }
+    # lft and rgt values are still valid (Project.rebuild! would not update anything)
+    # but projects are not ordered properly (YY is in the first place)
+
+    Project.rebuild_tree!
+    assert_valid_nested_set
+  end
+
+  def test_moving_a_child_to_a_different_parent_should_keep_valid_tree
+    assert_no_difference 'Project.count' do
+      Project.find_by_name('B1').set_parent!(Project.find_by_name('A2'))
+    end
+    assert_valid_nested_set
+  end
+
+  def test_renaming_a_root_to_first_position_should_update_nested_set_order
+    @c.name = '1'
+    @c.save!
+    assert_valid_nested_set
+  end
+
+  def test_renaming_a_root_to_middle_position_should_update_nested_set_order
+    @a.name = 'BA'
+    @a.save!
+    assert_valid_nested_set
+  end
+
+  def test_renaming_a_root_to_last_position_should_update_nested_set_order
+    @a.name = 'D'
+    @a.save!
+    assert_valid_nested_set
+  end
+
+  def test_renaming_a_root_to_same_position_should_update_nested_set_order
+    @c.name = 'D'
+    @c.save!
+    assert_valid_nested_set
+  end
+
+  def test_renaming_a_child_should_update_nested_set_order
+    @a1.name = 'A3'
+    @a1.save!
+    assert_valid_nested_set
+  end
+
+  def test_renaming_a_child_with_child_should_update_nested_set_order
+    @b1.name = 'B3'
+    @b1.save!
+    assert_valid_nested_set
+  end
+
+  def test_adding_a_root_to_first_position_should_update_nested_set_order
+    project = Project.create!(:name => '1', :identifier => 'projectba')
+    assert_valid_nested_set
+  end
+
+  def test_adding_a_root_to_middle_position_should_update_nested_set_order
+    project = Project.create!(:name => 'BA', :identifier => 'projectba')
+    assert_valid_nested_set
+  end
+
+  def test_adding_a_root_to_last_position_should_update_nested_set_order
+    project = Project.create!(:name => 'Z', :identifier => 'projectba')
+    assert_valid_nested_set
+  end
+
+  def test_destroying_a_root_with_children_should_keep_valid_tree
+    assert_difference 'Project.count', -4 do
+      Project.find_by_name('B').destroy
+    end
+    assert_valid_nested_set
+  end
+
+  def test_destroying_a_child_with_children_should_keep_valid_tree
+    assert_difference 'Project.count', -2 do
+      Project.find_by_name('B1').destroy
+    end
+    assert_valid_nested_set
+  end
+
+  private
+
+  def assert_nested_set_values(h)
+    assert Project.valid?
+    h.each do |project, expected|
+      project.reload
+      assert_equal expected, [project.parent_id, project.lft, project.rgt], "Unexpected nested set values for #{project.name}"
+    end
+  end
+
+  def assert_valid_nested_set
+    projects = Project.all
+    lft_rgt = projects.map {|p| [p.lft, p.rgt]}.flatten
+    assert_equal projects.size * 2, lft_rgt.uniq.size
+    assert_equal 1, lft_rgt.min
+    assert_equal projects.size * 2, lft_rgt.max
+
+    projects.each do |project|
+      # lft should always be < rgt
+      assert project.lft < project.rgt, "lft=#{project.lft} was not < rgt=#{project.rgt} for project #{project.name}"
+      if project.parent_id
+        # child lft/rgt values must be greater/lower
+        assert_not_nil project.parent, "parent was nil for project #{project.name}"
+        assert project.lft > project.parent.lft, "lft=#{project.lft} was not > parent.lft=#{project.parent.lft} for project #{project.name}"
+        assert project.rgt < project.parent.rgt, "rgt=#{project.rgt} was not < parent.rgt=#{project.parent.rgt} for project #{project.name}"
+      end
+      # no overlapping lft/rgt values
+      overlapping = projects.detect {|other| 
+        other != project && (
+          (other.lft > project.lft && other.lft < project.rgt && other.rgt > project.rgt) ||
+          (other.rgt > project.lft && other.rgt < project.rgt && other.lft < project.lft)
+        )
+      }
+      assert_nil overlapping, (overlapping && "Project #{overlapping.name} (#{overlapping.lft}/#{overlapping.rgt}) overlapped #{project.name} (#{project.lft}/#{project.rgt})")
+    end
+
+    # root projects sorted alphabetically
+    assert_equal Project.roots.map(&:name).sort, Project.roots.sort_by(&:lft).map(&:name), "Root projects were not properly sorted"
+    projects.each do |project|
+      if project.children.any?
+        # sibling projects sorted alphabetically
+        assert_equal project.children.map(&:name).sort, project.children.order('lft').map(&:name), "Project #{project.name}'s children were not properly sorted"
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d9/d9545294de024a7e3a5f7c74daf7f80255e0f5d7.svn-base
--- a/.svn/pristine/d9/d9545294de024a7e3a5f7c74daf7f80255e0f5d7.svn-base
+++ /dev/null
@@ -1,215 +0,0 @@
-module CodeRay
-  
-  # GZip library for writing and reading token dumps.
-  autoload :GZip, 'coderay/helpers/gzip'
-  
-  # = Tokens  TODO: Rewrite!
-  #
-  # The Tokens class represents a list of tokens returnd from
-  # a Scanner.
-  #
-  # A token is not a special object, just a two-element Array
-  # consisting of
-  # * the _token_ _text_ (the original source of the token in a String) or
-  #   a _token_ _action_ (begin_group, end_group, begin_line, end_line)
-  # * the _token_ _kind_ (a Symbol representing the type of the token)
-  #
-  # A token looks like this:
-  #
-  #   ['# It looks like this', :comment]
-  #   ['3.1415926', :float]
-  #   ['$^', :error]
-  #
-  # Some scanners also yield sub-tokens, represented by special
-  # token actions, namely begin_group and end_group.
-  #
-  # The Ruby scanner, for example, splits "a string" into:
-  #
-  #  [
-  #   [:begin_group, :string],
-  #   ['"', :delimiter],
-  #   ['a string', :content],
-  #   ['"', :delimiter],
-  #   [:end_group, :string]
-  #  ]
-  #
-  # Tokens is the interface between Scanners and Encoders:
-  # The input is split and saved into a Tokens object. The Encoder
-  # then builds the output from this object.
-  #
-  # Thus, the syntax below becomes clear:
-  #
-  #   CodeRay.scan('price = 2.59', :ruby).html
-  #   # the Tokens object is here -------^
-  #
-  # See how small it is? ;)
-  #
-  # Tokens gives you the power to handle pre-scanned code very easily:
-  # You can convert it to a webpage, a YAML file, or dump it into a gzip'ed string
-  # that you put in your DB.
-  # 
-  # It also allows you to generate tokens directly (without using a scanner),
-  # to load them from a file, and still use any Encoder that CodeRay provides.
-  class Tokens < Array
-    
-    # The Scanner instance that created the tokens.
-    attr_accessor :scanner
-    
-    # Encode the tokens using encoder.
-    #
-    # encoder can be
-    # * a symbol like :html oder :statistic
-    # * an Encoder class
-    # * an Encoder object
-    #
-    # options are passed to the encoder.
-    def encode encoder, options = {}
-      encoder = Encoders[encoder].new options if encoder.respond_to? :to_sym
-      encoder.encode_tokens self, options
-    end
-    
-    # Turn tokens into a string by concatenating them.
-    def to_s
-      encode CodeRay::Encoders::Encoder.new
-    end
-    
-    # Redirects unknown methods to encoder calls.
-    #
-    # For example, if you call +tokens.html+, the HTML encoder
-    # is used to highlight the tokens.
-    def method_missing meth, options = {}
-      encode meth, options
-    rescue PluginHost::PluginNotFound
-      super
-    end
-    
-    # Split the tokens into parts of the given +sizes+.
-    # 
-    # The result will be an Array of Tokens objects. The parts have
-    # the text size specified by the parameter. In addition, each
-    # part closes all opened tokens. This is useful to insert tokens
-    # betweem them.
-    # 
-    # This method is used by @Scanner#tokenize@ when called with an Array
-    # of source strings. The Diff encoder uses it for inline highlighting.
-    def split_into_parts *sizes
-      parts = []
-      opened = []
-      content = nil
-      part = Tokens.new
-      part_size = 0
-      size = sizes.first
-      i = 0
-      for item in self
-        case content
-        when nil
-          content = item
-        when String
-          if size && part_size + content.size > size  # token must be cut
-            if part_size < size  # some part of the token goes into this part
-              content = content.dup  # content may no be safe to change
-              part << content.slice!(0, size - part_size) << item
-            end
-            # close all open groups and lines...
-            closing = opened.reverse.flatten.map do |content_or_kind|
-              case content_or_kind
-              when :begin_group
-                :end_group
-              when :begin_line
-                :end_line
-              else
-                content_or_kind
-              end
-            end
-            part.concat closing
-            begin
-              parts << part
-              part = Tokens.new
-              size = sizes[i += 1]
-            end until size.nil? || size > 0
-            # ...and open them again.
-            part.concat opened.flatten
-            part_size = 0
-            redo unless content.empty?
-          else
-            part << content << item
-            part_size += content.size
-          end
-          content = nil
-        when Symbol
-          case content
-          when :begin_group, :begin_line
-            opened << [content, item]
-          when :end_group, :end_line
-            opened.pop
-          else
-            raise ArgumentError, 'Unknown token action: %p, kind = %p' % [content, item]
-          end
-          part << content << item
-          content = nil
-        else
-          raise ArgumentError, 'Token input junk: %p, kind = %p' % [content, item]
-        end
-      end
-      parts << part
-      parts << Tokens.new while parts.size < sizes.size
-      parts
-    end
-    
-    # Dumps the object into a String that can be saved
-    # in files or databases.
-    #
-    # The dump is created with Marshal.dump;
-    # In addition, it is gzipped using GZip.gzip.
-    #
-    # The returned String object includes Undumping
-    # so it has an #undump method. See Tokens.load.
-    #
-    # You can configure the level of compression,
-    # but the default value 7 should be what you want
-    # in most cases as it is a good compromise between
-    # speed and compression rate.
-    #
-    # See GZip module.
-    def dump gzip_level = 7
-      dump = Marshal.dump self
-      dump = GZip.gzip dump, gzip_level
-      dump.extend Undumping
-    end
-    
-    # Return the actual number of tokens.
-    def count
-      size / 2
-    end
-    
-    # Include this module to give an object an #undump
-    # method.
-    #
-    # The string returned by Tokens.dump includes Undumping.
-    module Undumping
-      # Calls Tokens.load with itself.
-      def undump
-        Tokens.load self
-      end
-    end
-    
-    # Undump the object using Marshal.load, then
-    # unzip it using GZip.gunzip.
-    #
-    # The result is commonly a Tokens object, but
-    # this is not guaranteed.
-    def Tokens.load dump
-      dump = GZip.gunzip dump
-      @dump = Marshal.load dump
-    end
-    
-    alias text_token push
-    def begin_group kind; push :begin_group, kind end
-    def end_group kind; push :end_group, kind end
-    def begin_line kind; push :begin_line, kind end
-    def end_line kind; push :end_line, kind end
-    alias tokens concat
-    
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d9/d986f7b46fa5ce6dde5f77817cfb4867911e726d.svn-base
--- a/.svn/pristine/d9/d986f7b46fa5ce6dde5f77817cfb4867911e726d.svn-base
+++ /dev/null
@@ -1,201 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require "digest/md5"
-
-class Attachment < ActiveRecord::Base
-  belongs_to :container, :polymorphic => true
-  belongs_to :author, :class_name => "User", :foreign_key => "author_id"
-
-  validates_presence_of :container, :filename, :author
-  validates_length_of :filename, :maximum => 255
-  validates_length_of :disk_filename, :maximum => 255
-  validate :validate_max_file_size
-
-  acts_as_event :title => :filename,
-                :url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}}
-
-  acts_as_activity_provider :type => 'files',
-                            :permission => :view_files,
-                            :author_key => :author_id,
-                            :find_options => {:select => "#{Attachment.table_name}.*",
-                                              :joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " +
-                                                        "LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id OR ( #{Attachment.table_name}.container_type='Project' AND #{Attachment.table_name}.container_id = #{Project.table_name}.id )"}
-
-  acts_as_activity_provider :type => 'documents',
-                            :permission => :view_documents,
-                            :author_key => :author_id,
-                            :find_options => {:select => "#{Attachment.table_name}.*",
-                                              :joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " +
-                                                        "LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"}
-
-  cattr_accessor :storage_path
-  @@storage_path = Redmine::Configuration['attachments_storage_path'] || "#{Rails.root}/files"
-
-  before_save :files_to_final_location
-  after_destroy :delete_from_disk
-
-  def validate_max_file_size
-    if self.filesize > Setting.attachment_max_size.to_i.kilobytes
-      errors.add(:base, :too_long, :count => Setting.attachment_max_size.to_i.kilobytes)
-    end
-  end
-
-  def file=(incoming_file)
-    unless incoming_file.nil?
-      @temp_file = incoming_file
-      if @temp_file.size > 0
-        self.filename = sanitize_filename(@temp_file.original_filename)
-        self.disk_filename = Attachment.disk_filename(filename)
-        self.content_type = @temp_file.content_type.to_s.chomp
-        if content_type.blank?
-          self.content_type = Redmine::MimeType.of(filename)
-        end
-        self.filesize = @temp_file.size
-      end
-    end
-  end
-	
-  def file
-    nil
-  end
-
-  # Copies the temporary file to its final location
-  # and computes its MD5 hash
-  def files_to_final_location
-    if @temp_file && (@temp_file.size > 0)
-      logger.info("Saving attachment '#{self.diskfile}' (#{@temp_file.size} bytes)")
-      md5 = Digest::MD5.new
-      File.open(diskfile, "wb") do |f|
-        buffer = ""
-        while (buffer = @temp_file.read(8192))
-          f.write(buffer)
-          md5.update(buffer)
-        end
-      end
-      self.digest = md5.hexdigest
-    end
-    @temp_file = nil
-    # Don't save the content type if it's longer than the authorized length
-    if self.content_type && self.content_type.length > 255
-      self.content_type = nil
-    end
-  end
-
-  # Deletes file on the disk
-  def delete_from_disk
-    File.delete(diskfile) if !filename.blank? && File.exist?(diskfile)
-  end
-
-  # Returns file's location on disk
-  def diskfile
-    "#{@@storage_path}/#{self.disk_filename}"
-  end
-
-  def increment_download
-    increment!(:downloads)
-  end
-
-  def project
-    container.project
-  end
-
-  def visible?(user=User.current)
-    container.attachments_visible?(user)
-  end
-
-  def deletable?(user=User.current)
-    container.attachments_deletable?(user)
-  end
-
-  def image?
-    self.filename =~ /\.(bmp|gif|jpg|jpe|jpeg|png)$/i
-  end
-
-  def is_text?
-    Redmine::MimeType.is_type?('text', filename)
-  end
-
-  def is_diff?
-    self.filename =~ /\.(patch|diff)$/i
-  end
-
-  # Returns true if the file is readable
-  def readable?
-    File.readable?(diskfile)
-  end
-
-  # Bulk attaches a set of files to an object
-  #
-  # Returns a Hash of the results:
-  # :files => array of the attached files
-  # :unsaved => array of the files that could not be attached
-  def self.attach_files(obj, attachments)
-    attached = []
-    if attachments && attachments.is_a?(Hash)
-      attachments.each_value do |attachment|
-        file = attachment['file']
-        next unless file && file.size > 0
-        a = Attachment.create(:container => obj,
-                              :file => file,
-                              :description => attachment['description'].to_s.strip,
-                              :author => User.current)
-        obj.attachments << a
-
-        if a.new_record?
-          obj.unsaved_attachments ||= []
-          obj.unsaved_attachments << a
-        else
-          attached << a
-        end
-      end
-    end
-    {:files => attached, :unsaved => obj.unsaved_attachments}
-  end
-
-  def self.latest_attach(attachments, filename)
-    attachments.sort_by(&:created_on).reverse.detect { 
-      |att| att.filename.downcase == filename.downcase
-     }
-  end
-
-private
-  def sanitize_filename(value)
-    # get only the filename, not the whole path
-    just_filename = value.gsub(/^.*(\\|\/)/, '')
-
-    # Finally, replace invalid characters with underscore
-    @filename = just_filename.gsub(/[\/\?\%\*\:\|\"\'<>]+/, '_')
-  end
-
-  # Returns an ASCII or hashed filename
-  def self.disk_filename(filename)
-    timestamp = DateTime.now.strftime("%y%m%d%H%M%S")
-    ascii = ''
-    if filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
-      ascii = filename
-    else
-      ascii = Digest::MD5.hexdigest(filename)
-      # keep the extension if any
-      ascii << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$}
-    end
-    while File.exist?(File.join(@@storage_path, "#{timestamp}_#{ascii}"))
-      timestamp.succ!
-    end
-    "#{timestamp}_#{ascii}"
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d9/d98764f99d236520bd5f6ca42381f61878a79847.svn-base
--- /dev/null
+++ b/.svn/pristine/d9/d98764f99d236520bd5f6ca42381f61878a79847.svn-base
@@ -0,0 +1,186 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingWikiTest < ActionController::IntegrationTest
+  def test_wiki_matching
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki" },
+        { :controller => 'wiki', :action => 'show', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/lalala" },
+        { :controller => 'wiki', :action => 'show', :project_id => '567',
+          :id => 'lalala' }
+        )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/lalala.pdf" },
+        { :controller => 'wiki', :action => 'show', :project_id => '567',
+          :id => 'lalala', :format => 'pdf' }
+        )
+    assert_routing(
+         { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/diff" },
+         { :controller => 'wiki', :action => 'diff', :project_id => '1',
+           :id => 'CookBook_documentation' }
+       )
+    assert_routing(
+         { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2" },
+         { :controller => 'wiki', :action => 'show', :project_id => '1',
+           :id => 'CookBook_documentation', :version => '2' }
+       )
+    assert_routing(
+         { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2/diff" },
+         { :controller => 'wiki', :action => 'diff', :project_id => '1',
+           :id => 'CookBook_documentation', :version => '2' }
+       )
+    assert_routing(
+         { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2/annotate" },
+         { :controller => 'wiki', :action => 'annotate', :project_id => '1',
+           :id => 'CookBook_documentation', :version => '2' }
+       )
+    # Make sure we don't route wiki page sub-uris to let plugins handle them
+    assert_raise(ActionController::RoutingError) do
+      assert_recognizes({}, {:method => 'get', :path => "/projects/1/wiki/CookBook_documentation/whatever"})
+    end
+  end
+
+  def test_wiki_misc
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/date_index" },
+        { :controller => 'wiki', :action => 'date_index', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/export" },
+        { :controller => 'wiki', :action => 'export', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/export.pdf" },
+        { :controller => 'wiki', :action => 'export', :project_id => '567', :format => 'pdf' }
+      )
+    assert_routing(
+         { :method => 'get', :path => "/projects/567/wiki/index" },
+         { :controller => 'wiki', :action => 'index', :project_id => '567' }
+       )
+  end
+
+  def test_wiki_resources
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/my_page/edit" },
+        { :controller => 'wiki', :action => 'edit', :project_id => '567',
+          :id => 'my_page' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/history" },
+        { :controller => 'wiki', :action => 'history', :project_id => '1',
+          :id => 'CookBook_documentation' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/22/wiki/ladida/rename" },
+        { :controller => 'wiki', :action => 'rename', :project_id => '22',
+          :id => 'ladida' }
+      )
+    ["post", "put"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/projects/567/wiki/CookBook_documentation/preview" },
+          { :controller => 'wiki', :action => 'preview', :project_id => '567',
+            :id => 'CookBook_documentation' }
+        )
+    end
+    assert_routing(
+        { :method => 'post', :path => "/projects/22/wiki/ladida/rename" },
+        { :controller => 'wiki', :action => 'rename', :project_id => '22',
+          :id => 'ladida' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/22/wiki/ladida/protect" },
+        { :controller => 'wiki', :action => 'protect', :project_id => '22',
+          :id => 'ladida' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/22/wiki/ladida/add_attachment" },
+        { :controller => 'wiki', :action => 'add_attachment', :project_id => '22',
+          :id => 'ladida' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/projects/567/wiki/my_page" },
+        { :controller => 'wiki', :action => 'update', :project_id => '567',
+          :id => 'my_page' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/projects/22/wiki/ladida" },
+        { :controller => 'wiki', :action => 'destroy', :project_id => '22',
+          :id => 'ladida' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/projects/22/wiki/ladida/3" },
+        { :controller => 'wiki', :action => 'destroy_version', :project_id => '22',
+          :id => 'ladida', :version => '3' }
+      )
+  end
+
+  def test_api
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/my_page.xml" },
+        { :controller => 'wiki', :action => 'show', :project_id => '567',
+          :id => 'my_page', :format => 'xml' }
+        )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/wiki/my_page.json" },
+        { :controller => 'wiki', :action => 'show', :project_id => '567',
+          :id => 'my_page', :format => 'json' }
+        )
+    assert_routing(
+         { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2.xml" },
+         { :controller => 'wiki', :action => 'show', :project_id => '1',
+           :id => 'CookBook_documentation', :version => '2', :format => 'xml' }
+       )
+    assert_routing(
+         { :method => 'get', :path => "/projects/1/wiki/CookBook_documentation/2.json" },
+         { :controller => 'wiki', :action => 'show', :project_id => '1',
+           :id => 'CookBook_documentation', :version => '2', :format => 'json' }
+       )
+    assert_routing(
+         { :method => 'get', :path => "/projects/567/wiki/index.xml" },
+         { :controller => 'wiki', :action => 'index', :project_id => '567', :format => 'xml' }
+       )
+    assert_routing(
+         { :method => 'get', :path => "/projects/567/wiki/index.json" },
+         { :controller => 'wiki', :action => 'index', :project_id => '567', :format => 'json' }
+       )
+    assert_routing(
+        { :method => 'put', :path => "/projects/567/wiki/my_page.xml" },
+        { :controller => 'wiki', :action => 'update', :project_id => '567',
+          :id => 'my_page', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/projects/567/wiki/my_page.json" },
+        { :controller => 'wiki', :action => 'update', :project_id => '567',
+          :id => 'my_page', :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/projects/567/wiki/my_page.xml" },
+        { :controller => 'wiki', :action => 'destroy', :project_id => '567',
+          :id => 'my_page', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/projects/567/wiki/my_page.json" },
+        { :controller => 'wiki', :action => 'destroy', :project_id => '567',
+          :id => 'my_page', :format => 'json' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d9/d99d005bc4c66e06d02d4fede2fc4aa27612b15b.svn-base
--- a/.svn/pristine/d9/d99d005bc4c66e06d02d4fede2fc4aa27612b15b.svn-base
+++ /dev/null
@@ -1,70 +0,0 @@
-<div class="contextual">
-<%= watcher_tag(@news, User.current) %>
-<%= link_to(l(:button_edit),
-      edit_news_path(@news),
-      :class => 'icon icon-edit',
-      :accesskey => accesskey(:edit),
-      :onclick => 'Element.show("edit-news"); return false;') if User.current.allowed_to?(:manage_news, @project) %>
-<%= link_to(l(:button_delete),
-      news_path(@news),
-      :confirm => l(:text_are_you_sure),
-      :method => :delete,
-      :class => 'icon icon-del') if User.current.allowed_to?(:manage_news, @project) %>
-</div>
-
-<h2><%= avatar(@news.author, :size => "24") %><%=h @news.title %></h2>
-
-<% if authorize_for('news', 'edit') %>
-<div id="edit-news" style="display:none;">
-<% labelled_tabular_form_for :news, @news, :url => news_path(@news),
-                                           :html => { :id => 'news-form', :method => :put } do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= submit_tag l(:button_save) %>
-<%= link_to_remote l(:label_preview),
-                   { :url => preview_news_path(:project_id => @project),
-                     :method => 'get',
-                     :update => 'preview',
-                     :with => "Form.serialize('news-form')"
-                   }, :accesskey => accesskey(:preview) %> |
-<%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("edit-news"); return false;' %>
-<% end %>
-<div id="preview" class="wiki"></div>
-</div>
-<% end %>
-
-<p><% unless @news.summary.blank? %><em><%=h @news.summary %></em><br /><% end %>
-<span class="author"><%= authoring @news.created_on, @news.author %></span></p>
-<div class="wiki">
-<%= textilizable(@news.description) %>
-</div>
-<br />
-
-<div id="comments" style="margin-bottom:16px;">
-<h3 class="comments"><%= l(:label_comment_plural) %></h3>
-<% @comments.each do |comment| %>
-    <% next if comment.new_record? %>
-    <div class="contextual">
-    <%= link_to_if_authorized image_tag('delete.png'), {:controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment},
-                                                       :confirm => l(:text_are_you_sure), :method => :delete, :title => l(:button_delete) %>
-    </div>
-    <h4><%= avatar(comment.author, :size => "24") %><%= authoring comment.created_on, comment.author %></h4>
-    <%= textilizable(comment.comments) %>
-<% end if @comments.any? %>
-</div>
-
-<% if authorize_for 'comments', 'create' %>
-<p><%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %></p>
-<% form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %>
-<div class="box">
-    <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %>
-    <%= wikitoolbar_for 'comment_comments' %>
-</div>
-<p><%= submit_tag l(:button_add) %></p>
-<% end %>
-<% end %>
-
-<% html_title @news.title -%>
-
-<% content_for :header_tags do %>
-  <%= stylesheet_link_tag 'scm' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d9/d9ae3cb5600a5eb2525edf835bf114f2fc4ccc54.svn-base
--- /dev/null
+++ b/.svn/pristine/d9/d9ae3cb5600a5eb2525edf835bf114f2fc4ccc54.svn-base
@@ -0,0 +1,291 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/abstract_adapter'
+require 'uri'
+
+module Redmine
+  module Scm
+    module Adapters
+      class SubversionAdapter < AbstractAdapter
+
+        # SVN executable name
+        SVN_BIN = Redmine::Configuration['scm_subversion_command'] || "svn"
+
+        class << self
+          def client_command
+            @@bin    ||= SVN_BIN
+          end
+
+          def sq_bin
+            @@sq_bin ||= shell_quote_command
+          end
+
+          def client_version
+            @@client_version ||= (svn_binary_version || [])
+          end
+
+          def client_available
+            # --xml options are introduced in 1.3.
+            # http://subversion.apache.org/docs/release-notes/1.3.html
+            client_version_above?([1, 3])
+          end
+
+          def svn_binary_version
+            scm_version = scm_version_from_command_line.dup
+            if scm_version.respond_to?(:force_encoding)
+              scm_version.force_encoding('ASCII-8BIT')
+            end
+            if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
+              m[2].scan(%r{\d+}).collect(&:to_i)
+            end
+          end
+
+          def scm_version_from_command_line
+            shellout("#{sq_bin} --version") { |io| io.read }.to_s
+          end
+        end
+
+        # Get info about the svn repository
+        def info
+          cmd = "#{self.class.sq_bin} info --xml #{target}"
+          cmd << credentials_string
+          info = nil
+          shellout(cmd) do |io|
+            output = io.read
+            if output.respond_to?(:force_encoding)
+              output.force_encoding('UTF-8')
+            end
+            begin
+              doc = parse_xml(output)
+              # root_url = doc.elements["info/entry/repository/root"].text
+              info = Info.new({:root_url => doc['info']['entry']['repository']['root']['__content__'],
+                               :lastrev => Revision.new({
+                                 :identifier => doc['info']['entry']['commit']['revision'],
+                                 :time => Time.parse(doc['info']['entry']['commit']['date']['__content__']).localtime,
+                                 :author => (doc['info']['entry']['commit']['author'] ? doc['info']['entry']['commit']['author']['__content__'] : "")
+                               })
+                             })
+            rescue
+            end
+          end
+          return nil if $? && $?.exitstatus != 0
+          info
+        rescue CommandFailed
+          return nil
+        end
+
+        # Returns an Entries collection
+        # or nil if the given path doesn't exist in the repository
+        def entries(path=nil, identifier=nil, options={})
+          path ||= ''
+          identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
+          entries = Entries.new
+          cmd = "#{self.class.sq_bin} list --xml #{target(path)}@#{identifier}"
+          cmd << credentials_string
+          shellout(cmd) do |io|
+            output = io.read
+            if output.respond_to?(:force_encoding)
+              output.force_encoding('UTF-8')
+            end
+            begin
+              doc = parse_xml(output)
+              each_xml_element(doc['lists']['list'], 'entry') do |entry|
+                commit = entry['commit']
+                commit_date = commit['date']
+                # Skip directory if there is no commit date (usually that
+                # means that we don't have read access to it)
+                next if entry['kind'] == 'dir' && commit_date.nil?
+                name = entry['name']['__content__']
+                entries << Entry.new({:name => URI.unescape(name),
+                            :path => ((path.empty? ? "" : "#{path}/") + name),
+                            :kind => entry['kind'],
+                            :size => ((s = entry['size']) ? s['__content__'].to_i : nil),
+                            :lastrev => Revision.new({
+                              :identifier => commit['revision'],
+                              :time => Time.parse(commit_date['__content__'].to_s).localtime,
+                              :author => ((a = commit['author']) ? a['__content__'] : nil)
+                              })
+                            })
+              end
+            rescue Exception => e
+              logger.error("Error parsing svn output: #{e.message}")
+              logger.error("Output was:\n #{output}")
+            end
+          end
+          return nil if $? && $?.exitstatus != 0
+          logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug?
+          entries.sort_by_name
+        end
+
+        def properties(path, identifier=nil)
+          # proplist xml output supported in svn 1.5.0 and higher
+          return nil unless self.class.client_version_above?([1, 5, 0])
+
+          identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
+          cmd = "#{self.class.sq_bin} proplist --verbose --xml #{target(path)}@#{identifier}"
+          cmd << credentials_string
+          properties = {}
+          shellout(cmd) do |io|
+            output = io.read
+            if output.respond_to?(:force_encoding)
+              output.force_encoding('UTF-8')
+            end
+            begin
+              doc = parse_xml(output)
+              each_xml_element(doc['properties']['target'], 'property') do |property|
+                properties[ property['name'] ] = property['__content__'].to_s
+              end
+            rescue
+            end
+          end
+          return nil if $? && $?.exitstatus != 0
+          properties
+        end
+
+        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
+          path ||= ''
+          identifier_from = (identifier_from && identifier_from.to_i > 0) ? identifier_from.to_i : "HEAD"
+          identifier_to = (identifier_to && identifier_to.to_i > 0) ? identifier_to.to_i : 1
+          revisions = Revisions.new
+          cmd = "#{self.class.sq_bin} log --xml -r #{identifier_from}:#{identifier_to}"
+          cmd << credentials_string
+          cmd << " --verbose " if  options[:with_paths]
+          cmd << " --limit #{options[:limit].to_i}" if options[:limit]
+          cmd << ' ' + target(path)
+          shellout(cmd) do |io|
+            output = io.read
+            if output.respond_to?(:force_encoding)
+              output.force_encoding('UTF-8')
+            end
+            begin
+              doc = parse_xml(output)
+              each_xml_element(doc['log'], 'logentry') do |logentry|
+                paths = []
+                each_xml_element(logentry['paths'], 'path') do |path|
+                  paths << {:action => path['action'],
+                            :path => path['__content__'],
+                            :from_path => path['copyfrom-path'],
+                            :from_revision => path['copyfrom-rev']
+                            }
+                end if logentry['paths'] && logentry['paths']['path']
+                paths.sort! { |x,y| x[:path] <=> y[:path] }
+
+                revisions << Revision.new({:identifier => logentry['revision'],
+                              :author => (logentry['author'] ? logentry['author']['__content__'] : ""),
+                              :time => Time.parse(logentry['date']['__content__'].to_s).localtime,
+                              :message => logentry['msg']['__content__'],
+                              :paths => paths
+                            })
+              end
+            rescue
+            end
+          end
+          return nil if $? && $?.exitstatus != 0
+          revisions
+        end
+
+        def diff(path, identifier_from, identifier_to=nil)
+          path ||= ''
+          identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : ''
+
+          identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : (identifier_from.to_i - 1)
+
+          cmd = "#{self.class.sq_bin} diff -r "
+          cmd << "#{identifier_to}:"
+          cmd << "#{identifier_from}"
+          cmd << " #{target(path)}@#{identifier_from}"
+          cmd << credentials_string
+          diff = []
+          shellout(cmd) do |io|
+            io.each_line do |line|
+              diff << line
+            end
+          end
+          return nil if $? && $?.exitstatus != 0
+          diff
+        end
+
+        def cat(path, identifier=nil)
+          identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
+          cmd = "#{self.class.sq_bin} cat #{target(path)}@#{identifier}"
+          cmd << credentials_string
+          cat = nil
+          shellout(cmd) do |io|
+            io.binmode
+            cat = io.read
+          end
+          return nil if $? && $?.exitstatus != 0
+          cat
+        end
+
+        def annotate(path, identifier=nil)
+          identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
+          cmd = "#{self.class.sq_bin} blame #{target(path)}@#{identifier}"
+          cmd << credentials_string
+          blame = Annotate.new
+          shellout(cmd) do |io|
+            io.each_line do |line|
+              next unless line =~ %r{^\s*(\d+)\s*(\S+)\s(.*)$}
+              rev = $1
+              blame.add_line($3.rstrip,
+                   Revision.new(
+                      :identifier => rev,
+                      :revision   => rev,
+                      :author     => $2.strip
+                      ))
+            end
+          end
+          return nil if $? && $?.exitstatus != 0
+          blame
+        end
+
+        private
+
+        def credentials_string
+          str = ''
+          str << " --username #{shell_quote(@login)}" unless @login.blank?
+          str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
+          str << " --no-auth-cache --non-interactive"
+          str
+        end
+
+        # Helper that iterates over the child elements of a xml node
+        # MiniXml returns a hash when a single child is found
+        # or an array of hashes for multiple children
+        def each_xml_element(node, name)
+          if node && node[name]
+            if node[name].is_a?(Hash)
+              yield node[name]
+            else
+              node[name].each do |element|
+                yield element
+              end
+            end
+          end
+        end
+
+        def target(path = '')
+          base = path.match(/^\//) ? root_url : url
+          uri = "#{base}/#{path}"
+          uri = URI.escape(URI.escape(uri), '[]')
+          shell_quote(uri.gsub(/[?<>\*]/, ''))
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/d9/d9b67bdb1cd5b0fd18dbd383da288aca840b669d.svn-base
--- /dev/null
+++ b/.svn/pristine/d9/d9b67bdb1cd5b0fd18dbd383da288aca840b669d.svn-base
@@ -0,0 +1,84 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class SysController < ActionController::Base
+  before_filter :check_enabled
+
+  def projects
+    p = Project.active.has_module(:repository).find(
+                   :all,
+                   :include => :repository,
+                   :order => "#{Project.table_name}.identifier"
+                 )
+    # extra_info attribute from repository breaks activeresource client
+    render :xml => p.to_xml(
+                       :only => [:id, :identifier, :name, :is_public, :status],
+                       :include => {:repository => {:only => [:id, :url]}}
+                     )
+  end
+
+  def create_project_repository
+    project = Project.find(params[:id])
+    if project.repository
+      render :nothing => true, :status => 409
+    else
+      logger.info "Repository for #{project.name} was reported to be created by #{request.remote_ip}."
+      repository = Repository.factory(params[:vendor], params[:repository])
+      repository.project = project
+      if repository.save
+        render :xml => {repository.class.name.underscore.gsub('/', '-') => {:id => repository.id, :url => repository.url}}, :status => 201
+      else
+        render :nothing => true, :status => 422
+      end
+    end
+  end
+
+  def fetch_changesets
+    projects = []
+    scope = Project.active.has_module(:repository)
+    if params[:id]
+      project = nil
+      if params[:id].to_s =~ /^\d*$/
+        project = scope.find(params[:id])
+      else
+        project = scope.find_by_identifier(params[:id])
+      end
+      raise ActiveRecord::RecordNotFound unless project
+      projects << project
+    else
+      projects = scope.all
+    end
+    projects.each do |project|
+      project.repositories.each do |repository|
+        repository.fetch_changesets
+      end
+    end
+    render :nothing => true, :status => 200
+  rescue ActiveRecord::RecordNotFound
+    render :nothing => true, :status => 404
+  end
+
+  protected
+
+  def check_enabled
+    User.current = nil
+    unless Setting.sys_api_enabled? && params[:key].to_s == Setting.sys_api_key
+      render :text => 'Access denied. Repository management WS is disabled or key is invalid.', :status => 403
+      return false
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/da12c9756273b44fbd8170e245294f84a463055c.svn-base
--- /dev/null
+++ b/.svn/pristine/da/da12c9756273b44fbd8170e245294f84a463055c.svn-base
@@ -0,0 +1,117 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class SessionStartTest < ActionController::TestCase
+  tests AccountController
+
+  fixtures :users
+
+  def test_login_should_set_session_timestamps
+    post :login, :username => 'jsmith', :password => 'jsmith'
+    assert_response 302
+    assert_equal 2, session[:user_id]
+    assert_not_nil session[:ctime]
+    assert_not_nil session[:atime]
+  end
+end
+
+class SessionsTest < ActionController::TestCase
+  tests WelcomeController
+
+  fixtures :users
+
+  def test_atime_from_user_session_should_be_updated
+    created = 2.hours.ago.utc.to_i
+    get :index, {}, {:user_id => 2, :ctime => created, :atime => created}
+    assert_response :success
+    assert_equal created, session[:ctime]
+    assert_not_equal created, session[:atime]
+    assert session[:atime] > created
+  end
+
+  def test_user_session_should_not_be_reset_if_lifetime_and_timeout_disabled
+    with_settings :session_lifetime => '0', :session_timeout => '0' do
+      get :index, {}, {:user_id => 2}
+      assert_response :success
+    end
+  end
+
+  def test_user_session_without_ctime_should_be_reset_if_lifetime_enabled
+    with_settings :session_lifetime => '720' do
+      get :index, {}, {:user_id => 2}
+      assert_redirected_to '/login'
+    end
+  end
+
+  def test_user_session_with_expired_ctime_should_be_reset_if_lifetime_enabled
+    with_settings :session_timeout => '720' do
+      get :index, {}, {:user_id => 2, :atime => 2.days.ago.utc.to_i}
+      assert_redirected_to '/login'
+    end
+  end
+
+  def test_user_session_with_valid_ctime_should_not_be_reset_if_lifetime_enabled
+    with_settings :session_timeout => '720' do
+      get :index, {}, {:user_id => 2, :atime => 3.hours.ago.utc.to_i}
+      assert_response :success
+    end
+  end
+
+  def test_user_session_without_atime_should_be_reset_if_timeout_enabled
+    with_settings :session_timeout => '60' do
+      get :index, {}, {:user_id => 2}
+      assert_redirected_to '/login'
+    end
+  end
+
+  def test_user_session_with_expired_atime_should_be_reset_if_timeout_enabled
+    with_settings :session_timeout => '60' do
+      get :index, {}, {:user_id => 2, :atime => 4.hours.ago.utc.to_i}
+      assert_redirected_to '/login'
+    end
+  end
+
+  def test_user_session_with_valid_atime_should_not_be_reset_if_timeout_enabled
+    with_settings :session_timeout => '60' do
+      get :index, {}, {:user_id => 2, :atime => 10.minutes.ago.utc.to_i}
+      assert_response :success
+    end
+  end
+
+  def test_expired_user_session_should_be_restarted_if_autologin
+    with_settings :session_lifetime => '720', :session_timeout => '60', :autologin => 7 do
+      token = Token.create!(:user_id => 2, :action => 'autologin', :created_on => 1.day.ago)
+      @request.cookies['autologin'] = token.value
+      created = 2.hours.ago.utc.to_i
+
+      get :index, {}, {:user_id => 2, :ctime => created, :atime => created}
+      assert_equal 2, session[:user_id]
+      assert_response :success
+      assert_not_equal created, session[:ctime]
+      assert session[:ctime] >= created
+    end
+  end
+
+  def test_anonymous_session_should_not_be_reset
+    with_settings :session_lifetime => '720', :session_timeout => '60' do
+      get :index
+      assert_response :success
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/da30f481208d9237a3f64922ab33dc92a83a4114.svn-base
--- a/.svn/pristine/da/da30f481208d9237a3f64922ab33dc92a83a4114.svn-base
+++ /dev/null
@@ -1,119 +0,0 @@
-# Don't change this file!
-# Configure your app in config/environment.rb and config/environments/*.rb
-
-if RUBY_VERSION >= '1.9'
-  require 'yaml'
-  YAML::ENGINE.yamler = 'syck'
-end
-
-RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
-
-module Rails
-  class << self
-    def boot!
-      unless booted?
-        preinitialize
-        pick_boot.run
-      end
-    end
-
-    def booted?
-      defined? Rails::Initializer
-    end
-
-    def pick_boot
-      (vendor_rails? ? VendorBoot : GemBoot).new
-    end
-
-    def vendor_rails?
-      File.exist?("#{RAILS_ROOT}/vendor/rails")
-    end
-
-    def preinitialize
-      load(preinitializer_path) if File.exist?(preinitializer_path)
-    end
-
-    def preinitializer_path
-      "#{RAILS_ROOT}/config/preinitializer.rb"
-    end
-  end
-
-  class Boot
-    def run
-      load_initializer
-      Rails::Initializer.run(:set_load_path)
-    end
-  end
-
-  class VendorBoot < Boot
-    def load_initializer
-      require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
-      Rails::Initializer.run(:install_gem_spec_stubs)
-      Rails::GemDependency.add_frozen_gem_path
-    end
-  end
-
-  class GemBoot < Boot
-    def load_initializer
-      self.class.load_rubygems
-      load_rails_gem
-      require 'initializer'
-    end
-
-    def load_rails_gem
-      if version = self.class.gem_version
-        gem 'rails', version
-      else
-        gem 'rails'
-      end
-    rescue Gem::LoadError => load_error
-      if load_error.message =~ /Could not find RubyGem rails/
-        STDERR.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
-        exit 1
-      else
-        raise
-      end
-    end
-
-    class << self
-      def rubygems_version
-        Gem::RubyGemsVersion rescue nil
-      end
-
-      def gem_version
-        if defined? RAILS_GEM_VERSION
-          RAILS_GEM_VERSION
-        elsif ENV.include?('RAILS_GEM_VERSION')
-          ENV['RAILS_GEM_VERSION']
-        else
-          parse_gem_version(read_environment_rb)
-        end
-      end
-
-      def load_rubygems
-        min_version = '1.3.2'
-        require 'rubygems'
-        unless rubygems_version >= min_version
-          $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
-          exit 1
-        end
-
-      rescue LoadError
-        $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
-        exit 1
-      end
-
-      def parse_gem_version(text)
-        $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
-      end
-
-      private
-        def read_environment_rb
-          File.read("#{RAILS_ROOT}/config/environment.rb")
-        end
-    end
-  end
-end
-
-# All that for this:
-Rails.boot!
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/da391cc28994d066c2bbb55ae6f4853a48f37175.svn-base
--- /dev/null
+++ b/.svn/pristine/da/da391cc28994d066c2bbb55ae6f4853a48f37175.svn-base
@@ -0,0 +1,202 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class GroupsControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles, :groups_users
+
+  def setup
+    @request.session[:user_id] = 1
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+  end
+
+  def test_show
+    get :show, :id => 10
+    assert_response :success
+    assert_template 'show'
+  end
+
+  def test_show_invalid_should_return_404
+    get :show, :id => 99
+    assert_response 404
+  end
+
+  def test_new
+    get :new
+    assert_response :success
+    assert_template 'new'
+    assert_select 'input[name=?]', 'group[name]'
+  end
+
+  def test_create
+    assert_difference 'Group.count' do
+      post :create, :group => {:name => 'New group'}
+    end
+    assert_redirected_to '/groups'
+    group = Group.first(:order => 'id DESC')
+    assert_equal 'New group', group.name
+    assert_equal [], group.users
+  end
+
+  def test_create_and_continue
+    assert_difference 'Group.count' do
+      post :create, :group => {:name => 'New group'}, :continue => 'Create and continue'
+    end
+    assert_redirected_to '/groups/new'
+    group = Group.first(:order => 'id DESC')
+    assert_equal 'New group', group.name
+  end
+
+  def test_create_with_failure
+    assert_no_difference 'Group.count' do
+      post :create, :group => {:name => ''}
+    end
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_edit
+    get :edit, :id => 10
+    assert_response :success
+    assert_template 'edit'
+
+    assert_select 'div#tab-content-users'
+    assert_select 'div#tab-content-memberships' do
+      assert_select 'a', :text => 'Private child of eCookbook'
+    end
+  end
+
+  def test_update
+    new_name = 'New name'
+    put :update, :id => 10, :group => {:name => new_name}
+    assert_redirected_to '/groups'
+    group = Group.find(10)
+    assert_equal new_name, group.name
+  end
+
+  def test_update_with_failure
+    put :update, :id => 10, :group => {:name => ''}
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_destroy
+    assert_difference 'Group.count', -1 do
+      post :destroy, :id => 10
+    end
+    assert_redirected_to '/groups'
+  end
+
+  def test_add_users
+    assert_difference 'Group.find(10).users.count', 2 do
+      post :add_users, :id => 10, :user_ids => ['2', '3']
+    end
+  end
+
+  def test_xhr_add_users
+    assert_difference 'Group.find(10).users.count', 2 do
+      xhr :post, :add_users, :id => 10, :user_ids => ['2', '3']
+      assert_response :success
+      assert_template 'add_users'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_match /John Smith/, response.body
+  end
+
+  def test_remove_user
+    assert_difference 'Group.find(10).users.count', -1 do
+      delete :remove_user, :id => 10, :user_id => '8'
+    end
+  end
+
+  def test_xhr_remove_user
+    assert_difference 'Group.find(10).users.count', -1 do
+      xhr :delete, :remove_user, :id => 10, :user_id => '8'
+      assert_response :success
+      assert_template 'remove_user'
+      assert_equal 'text/javascript', response.content_type
+    end
+  end
+
+  def test_new_membership
+    assert_difference 'Group.find(10).members.count' do
+      post :edit_membership, :id => 10, :membership => { :project_id => 2, :role_ids => ['1', '2']}
+    end
+  end
+
+  def test_xhr_new_membership
+    assert_difference 'Group.find(10).members.count' do
+      xhr :post, :edit_membership, :id => 10, :membership => { :project_id => 2, :role_ids => ['1', '2']}
+      assert_response :success
+      assert_template 'edit_membership'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_match /OnlineStore/, response.body
+  end
+
+  def test_xhr_new_membership_with_failure
+    assert_no_difference 'Group.find(10).members.count' do
+      xhr :post, :edit_membership, :id => 10, :membership => { :project_id => 999, :role_ids => ['1', '2']}
+      assert_response :success
+      assert_template 'edit_membership'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_match /alert/, response.body, "Alert message not sent"
+  end
+
+  def test_edit_membership
+    assert_no_difference 'Group.find(10).members.count' do
+      post :edit_membership, :id => 10, :membership_id => 6, :membership => { :role_ids => ['1', '3']}
+    end
+  end
+
+  def test_xhr_edit_membership
+    assert_no_difference 'Group.find(10).members.count' do
+      xhr :post, :edit_membership, :id => 10, :membership_id => 6, :membership => { :role_ids => ['1', '3']}
+      assert_response :success
+      assert_template 'edit_membership'
+      assert_equal 'text/javascript', response.content_type
+    end
+  end
+
+  def test_destroy_membership
+    assert_difference 'Group.find(10).members.count', -1 do
+      post :destroy_membership, :id => 10, :membership_id => 6
+    end
+  end
+
+  def test_xhr_destroy_membership
+    assert_difference 'Group.find(10).members.count', -1 do
+      xhr :post, :destroy_membership, :id => 10, :membership_id => 6
+      assert_response :success
+      assert_template 'destroy_membership'
+      assert_equal 'text/javascript', response.content_type
+    end
+  end
+
+  def test_autocomplete_for_user
+    get :autocomplete_for_user, :id => 10, :q => 'smi', :format => 'js'
+    assert_response :success
+    assert_include 'John Smith', response.body
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/da537956704422014aaac51b3eca6fc3565a3bb2.svn-base
--- a/.svn/pristine/da/da537956704422014aaac51b3eca6fc3565a3bb2.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-<div class="contextual">
-<%= link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %>
-<%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue}, :class => 'icon icon-time-add' %>
-<%= watcher_tag(@issue, User.current) %>
-<%= link_to_if_authorized l(:button_duplicate), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue }, :class => 'icon icon-duplicate' %>
-<%= link_to_if_authorized l(:button_copy), {:controller => 'issue_moves', :action => 'new', :id => @issue, :copy_options => {:copy => 't'}}, :class => 'icon icon-copy' %>
-<%= link_to_if_authorized l(:button_move), {:controller => 'issue_moves', :action => 'new', :id => @issue}, :class => 'icon icon-move' %>
-<%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => issues_destroy_confirmation_message(@issue), :method => :post, :class => 'icon icon-del' %>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/da5d2841572970a1cf259b4374a2ceda5138a513.svn-base
--- a/.svn/pristine/da/da5d2841572970a1cf259b4374a2ceda5138a513.svn-base
+++ /dev/null
@@ -1,341 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssuesController < ApplicationController
-  menu_item :new_issue, :only => [:new, :create]
-  default_search_scope :issues
-
-  before_filter :find_issue, :only => [:show, :edit, :update]
-  before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :move, :perform_move, :destroy]
-  before_filter :check_project_uniqueness, :only => [:move, :perform_move]
-  before_filter :find_project, :only => [:new, :create]
-  before_filter :authorize, :except => [:index]
-  before_filter :find_optional_project, :only => [:index]
-  before_filter :check_for_default_issue_status, :only => [:new, :create]
-  before_filter :build_new_issue_from_params, :only => [:new, :create]
-  accept_rss_auth :index, :show
-  accept_api_auth :index, :show, :create, :update, :destroy
-
-  rescue_from Query::StatementInvalid, :with => :query_statement_invalid
-
-  helper :journals
-  helper :projects
-  include ProjectsHelper
-  helper :custom_fields
-  include CustomFieldsHelper
-  helper :issue_relations
-  include IssueRelationsHelper
-  helper :watchers
-  include WatchersHelper
-  helper :attachments
-  include AttachmentsHelper
-  helper :queries
-  include QueriesHelper
-  helper :repositories
-  include RepositoriesHelper
-  helper :sort
-  include SortHelper
-  include IssuesHelper
-  helper :timelog
-  helper :gantt
-  include Redmine::Export::PDF
-
-  verify :method => [:post, :delete],
-         :only => :destroy,
-         :render => { :nothing => true, :status => :method_not_allowed }
-
-  verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
-  verify :method => :post, :only => :bulk_update, :render => {:nothing => true, :status => :method_not_allowed }
-  verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
-
-  def index
-    retrieve_query
-    sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
-    sort_update(@query.sortable_columns)
-
-    if @query.valid?
-      case params[:format]
-      when 'csv', 'pdf'
-        @limit = Setting.issues_export_limit.to_i
-      when 'atom'
-        @limit = Setting.feeds_limit.to_i
-      when 'xml', 'json'
-        @offset, @limit = api_offset_and_limit
-      else
-        @limit = per_page_option
-      end
-
-      @issue_count = @query.issue_count
-      @issue_pages = Paginator.new self, @issue_count, @limit, params['page']
-      @offset ||= @issue_pages.current.offset
-      @issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
-                              :order => sort_clause,
-                              :offset => @offset,
-                              :limit => @limit)
-      @issue_count_by_group = @query.issue_count_by_group
-
-      respond_to do |format|
-        format.html { render :template => 'issues/index', :layout => !request.xhr? }
-        format.api  {
-          Issue.load_relations(@issues) if include_in_api_response?('relations')
-        }
-        format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
-        format.csv  { send_data(issues_to_csv(@issues, @project, @query, params), :type => 'text/csv; header=present', :filename => 'export.csv') }
-        format.pdf  { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'export.pdf') }
-      end
-    else
-      respond_to do |format|
-        format.html { render(:template => 'issues/index', :layout => !request.xhr?) }
-        format.any(:atom, :csv, :pdf) { render(:nothing => true) }
-        format.api { render_validation_errors(@query) }
-      end
-    end
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  def show
-    @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
-    @journals.each_with_index {|j,i| j.indice = i+1}
-    @journals.reverse! if User.current.wants_comments_in_reverse_order?
-
-    if User.current.allowed_to?(:view_changesets, @project)
-      @changesets = @issue.changesets.visible.all
-      @changesets.reverse! if User.current.wants_comments_in_reverse_order?
-    end
-
-    @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
-    @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
-    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
-    @priorities = IssuePriority.active
-    @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
-    respond_to do |format|
-      format.html { render :template => 'issues/show' }
-      format.api
-      format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' }
-      format.pdf  { send_data(issue_to_pdf(@issue), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") }
-    end
-  end
-
-  # Add a new issue
-  # The new issue will be created from an existing one if copy_from parameter is given
-  def new
-    respond_to do |format|
-      format.html { render :action => 'new', :layout => !request.xhr? }
-      format.js { render :partial => 'attributes' }
-    end
-  end
-
-  def create
-    call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue })
-    if @issue.save
-      attachments = Attachment.attach_files(@issue, params[:attachments])
-      call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue})
-      respond_to do |format|
-        format.html {
-          render_attachment_warning_if_needed(@issue)
-          flash[:notice] = l(:notice_issue_successful_create, :id => "<a href='#{issue_path(@issue)}'>##{@issue.id}</a>")
-          redirect_to(params[:continue] ?  { :action => 'new', :project_id => @project, :issue => {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?} } :
-                      { :action => 'show', :id => @issue })
-        }
-        format.api  { render :action => 'show', :status => :created, :location => issue_url(@issue) }
-      end
-      return
-    else
-      respond_to do |format|
-        format.html { render :action => 'new' }
-        format.api  { render_validation_errors(@issue) }
-      end
-    end
-  end
-
-  def edit
-    update_issue_from_params
-
-    @journal = @issue.current_journal
-
-    respond_to do |format|
-      format.html { }
-      format.xml  { }
-    end
-  end
-
-  def update
-    update_issue_from_params
-
-    if @issue.save_issue_with_child_records(params, @time_entry)
-      render_attachment_warning_if_needed(@issue)
-      flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record?
-
-      respond_to do |format|
-        format.html { redirect_back_or_default({:action => 'show', :id => @issue}) }
-        format.api  { head :ok }
-      end
-    else
-      render_attachment_warning_if_needed(@issue)
-      flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record?
-      @journal = @issue.current_journal
-
-      respond_to do |format|
-        format.html { render :action => 'edit' }
-        format.api  { render_validation_errors(@issue) }
-      end
-    end
-  end
-
-  # Bulk edit a set of issues
-  def bulk_edit
-    @issues.sort!
-    @available_statuses = @projects.map{|p|Workflow.available_statuses(p)}.inject{|memo,w|memo & w}
-    @custom_fields = @projects.map{|p|p.all_issue_custom_fields}.inject{|memo,c|memo & c}
-    @assignables = @projects.map(&:assignable_users).inject{|memo,a| memo & a}
-    @trackers = @projects.map(&:trackers).inject{|memo,t| memo & t}
-  end
-
-  def bulk_update
-    @issues.sort!
-    attributes = parse_params_for_bulk_issue_attributes(params)
-
-    unsaved_issue_ids = []
-    @issues.each do |issue|
-      issue.reload
-      journal = issue.init_journal(User.current, params[:notes])
-      issue.safe_attributes = attributes
-      call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
-      unless issue.save
-        # Keep unsaved issue ids to display them in flash error
-        unsaved_issue_ids << issue.id
-      end
-    end
-    set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids)
-    redirect_back_or_default({:controller => 'issues', :action => 'index', :project_id => @project})
-  end
-
-  def destroy
-    @hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f
-    if @hours > 0
-      case params[:todo]
-      when 'destroy'
-        # nothing to do
-      when 'nullify'
-        TimeEntry.update_all('issue_id = NULL', ['issue_id IN (?)', @issues])
-      when 'reassign'
-        reassign_to = @project.issues.find_by_id(params[:reassign_to_id])
-        if reassign_to.nil?
-          flash.now[:error] = l(:error_issue_not_found_in_project)
-          return
-        else
-          TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues])
-        end
-      else
-        # display the destroy form if it's a user request
-        return unless api_request?
-      end
-    end
-    @issues.each do |issue|
-      begin
-        issue.reload.destroy
-      rescue ::ActiveRecord::RecordNotFound # raised by #reload if issue no longer exists
-        # nothing to do, issue was already deleted (eg. by a parent)
-      end
-    end
-    respond_to do |format|
-      format.html { redirect_back_or_default(:action => 'index', :project_id => @project) }
-      format.api  { head :ok }
-    end
-  end
-
-private
-  def find_issue
-    # Issue.visible.find(...) can not be used to redirect user to the login form
-    # if the issue actually exists but requires authentication
-    @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
-    unless @issue.visible?
-      deny_access
-      return
-    end
-    @project = @issue.project
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  def find_project
-    project_id = (params[:issue] && params[:issue][:project_id]) || params[:project_id]
-    @project = Project.find(project_id)
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  # Used by #edit and #update to set some common instance variables
-  # from the params
-  # TODO: Refactor, not everything in here is needed by #edit
-  def update_issue_from_params
-    @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
-    @priorities = IssuePriority.active
-    @edit_allowed = User.current.allowed_to?(:edit_issues, @project)
-    @time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
-    @time_entry.attributes = params[:time_entry]
-
-    @notes = params[:notes] || (params[:issue].present? ? params[:issue][:notes] : nil)
-    @issue.init_journal(User.current, @notes)
-    @issue.safe_attributes = params[:issue]
-  end
-
-  # TODO: Refactor, lots of extra code in here
-  # TODO: Changing tracker on an existing issue should not trigger this
-  def build_new_issue_from_params
-    if params[:id].blank?
-      @issue = Issue.new
-      @issue.copy_from(params[:copy_from]) if params[:copy_from]
-      @issue.project = @project
-    else
-      @issue = @project.issues.visible.find(params[:id])
-    end
-
-    @issue.project = @project
-    @issue.author = User.current
-    # Tracker must be set before custom field values
-    @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
-    if @issue.tracker.nil?
-      render_error l(:error_no_tracker_in_project)
-      return false
-    end
-    @issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date?
-    if params[:issue].is_a?(Hash)
-      @issue.safe_attributes = params[:issue]
-      if User.current.allowed_to?(:add_issue_watchers, @project) && @issue.new_record?
-        @issue.watcher_user_ids = params[:issue]['watcher_user_ids']
-      end
-    end
-    @priorities = IssuePriority.active
-    @allowed_statuses = @issue.new_statuses_allowed_to(User.current, true)
-  end
-
-  def check_for_default_issue_status
-    if IssueStatus.default.nil?
-      render_error l(:error_no_default_issue_status)
-      return false
-    end
-  end
-
-  def parse_params_for_bulk_issue_attributes(params)
-    attributes = (params[:issue] || {}).reject {|k,v| v.blank?}
-    attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'}
-    attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values]
-    attributes
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/da7369cd8f5f0b2ca40bf09589238bd7f30ff840.svn-base
--- a/.svn/pristine/da/da7369cd8f5f0b2ca40bf09589238bd7f30ff840.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar HE language
-// Author: Saggi Mizrahi
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("×¨××©×•×Ÿ",
- "×©× ×™",
- "×©×œ×™×©×™",
- "×¨×‘×™×¢×™",
- "×—×ž×™×©×™",
- "×©×™×©×™",
- "×©×‘×ª",
- "×¨××©×•×Ÿ");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("×",
- "×‘",
- "×’",
- "×“",
- "×”",
- "×•",
- "×©",
- "×");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("×™× ×•××¨",
- "×¤×‘×¨×•××¨",
- "×ž×¨×¥",
- "××¤×¨×™×œ",
- "×ž××™",
- "×™×•× ×™",
- "×™×•×œ×™",
- "××•×’×•×¡×˜",
- "×¡×¤×˜×ž×‘×¨",
- "××•×§×˜×•×‘×¨",
- "× ×•×‘×ž×‘×¨",
- "×“×¦×ž×‘×¨");
-
-// short month names
-Calendar._SMN = new Array
-("×™× ×•'",
- "×¤×‘×•'",
- "×ž×¨×¥",
- "××¤×¨'",
- "×ž××™",
- "×™×•× '",
- "×™×•×œ'",
- "××•×’'",
- "×¡×¤×˜'",
- "××•×§×˜'",
- "× ×•×‘'",
- "×“×¦×ž'");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "××•×“×•×ª ×œ×•×— ×”×©× ×”";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "×©× ×” ×§×•×“×ž×ª (×”×—×–×§ ×œ×ª×¤×¨×™×˜)";
-Calendar._TT["PREV_MONTH"] = "×—×•×“×© ×§×•×“× (×”×—×–×§ ×œ×ª×¤×¨×™×˜)";
-Calendar._TT["GO_TODAY"] = "×œ×š ×œ×”×™×•×";
-Calendar._TT["NEXT_MONTH"] = "×—×•×“×© ×”×‘× (×”×—×–×§ ×œ×ª×¤×¨×™×˜)";
-Calendar._TT["NEXT_YEAR"] = "×©× ×” ×”×‘××” (×”×—×–×§ ×œ×ª×¤×¨×™×˜)";
-Calendar._TT["SEL_DATE"] = "×‘×—×¨ ×ª××¨×™×š";
-Calendar._TT["DRAG_TO_MOVE"] = "×ž×©×•×š ×›×“×™ ×œ×”×–×™×–";
-Calendar._TT["PART_TODAY"] = " (×”×™×•×)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "×”×¦×’ %s ×§×•×“×";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "5,6";
-
-Calendar._TT["CLOSE"] = "×¡×’×•×¨";
-Calendar._TT["TODAY"] = "×”×™×•×";
-Calendar._TT["TIME_PART"] = "(Shift-)×œ×—×¥ ××• ×ž×©×•×š ×›×“×™ ×œ×©× ×•×ª ××ª ×”×¢×¨×š";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "×–×ž×Ÿ:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/da90b715e93c3c141bb44fb1b5742be6981e034a.svn-base
--- a/.svn/pristine/da/da90b715e93c3c141bb44fb1b5742be6981e034a.svn-base
+++ /dev/null
@@ -1,973 +0,0 @@
-// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-//           (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
-//
-// script.aculo.us is freely distributable under the terms of an MIT-style license.
-// For details, see the script.aculo.us web site: http://script.aculo.us/
-
-if(Object.isUndefined(Effect))
-  throw("dragdrop.js requires including script.aculo.us' effects.js library");
-
-var Droppables = {
-  drops: [],
-
-  remove: function(element) {
-    this.drops = this.drops.reject(function(d) { return d.element==$(element) });
-  },
-
-  add: function(element) {
-    element = $(element);
-    var options = Object.extend({
-      greedy:     true,
-      hoverclass: null,
-      tree:       false
-    }, arguments[1] || { });
-
-    // cache containers
-    if(options.containment) {
-      options._containers = [];
-      var containment = options.containment;
-      if(Object.isArray(containment)) {
-        containment.each( function(c) { options._containers.push($(c)) });
-      } else {
-        options._containers.push($(containment));
-      }
-    }
-
-    if(options.accept) options.accept = [options.accept].flatten();
-
-    Element.makePositioned(element); // fix IE
-    options.element = element;
-
-    this.drops.push(options);
-  },
-
-  findDeepestChild: function(drops) {
-    deepest = drops[0];
-
-    for (i = 1; i < drops.length; ++i)
-      if (Element.isParent(drops[i].element, deepest.element))
-        deepest = drops[i];
-
-    return deepest;
-  },
-
-  isContained: function(element, drop) {
-    var containmentNode;
-    if(drop.tree) {
-      containmentNode = element.treeNode;
-    } else {
-      containmentNode = element.parentNode;
-    }
-    return drop._containers.detect(function(c) { return containmentNode == c });
-  },
-
-  isAffected: function(point, element, drop) {
-    return (
-      (drop.element!=element) &&
-      ((!drop._containers) ||
-        this.isContained(element, drop)) &&
-      ((!drop.accept) ||
-        (Element.classNames(element).detect(
-          function(v) { return drop.accept.include(v) } ) )) &&
-      Position.within(drop.element, point[0], point[1]) );
-  },
-
-  deactivate: function(drop) {
-    if(drop.hoverclass)
-      Element.removeClassName(drop.element, drop.hoverclass);
-    this.last_active = null;
-  },
-
-  activate: function(drop) {
-    if(drop.hoverclass)
-      Element.addClassName(drop.element, drop.hoverclass);
-    this.last_active = drop;
-  },
-
-  show: function(point, element) {
-    if(!this.drops.length) return;
-    var drop, affected = [];
-
-    this.drops.each( function(drop) {
-      if(Droppables.isAffected(point, element, drop))
-        affected.push(drop);
-    });
-
-    if(affected.length>0)
-      drop = Droppables.findDeepestChild(affected);
-
-    if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
-    if (drop) {
-      Position.within(drop.element, point[0], point[1]);
-      if(drop.onHover)
-        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
-
-      if (drop != this.last_active) Droppables.activate(drop);
-    }
-  },
-
-  fire: function(event, element) {
-    if(!this.last_active) return;
-    Position.prepare();
-
-    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
-      if (this.last_active.onDrop) {
-        this.last_active.onDrop(element, this.last_active.element, event);
-        return true;
-      }
-  },
-
-  reset: function() {
-    if(this.last_active)
-      this.deactivate(this.last_active);
-  }
-};
-
-var Draggables = {
-  drags: [],
-  observers: [],
-
-  register: function(draggable) {
-    if(this.drags.length == 0) {
-      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
-      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
-      this.eventKeypress  = this.keyPress.bindAsEventListener(this);
-
-      Event.observe(document, "mouseup", this.eventMouseUp);
-      Event.observe(document, "mousemove", this.eventMouseMove);
-      Event.observe(document, "keypress", this.eventKeypress);
-    }
-    this.drags.push(draggable);
-  },
-
-  unregister: function(draggable) {
-    this.drags = this.drags.reject(function(d) { return d==draggable });
-    if(this.drags.length == 0) {
-      Event.stopObserving(document, "mouseup", this.eventMouseUp);
-      Event.stopObserving(document, "mousemove", this.eventMouseMove);
-      Event.stopObserving(document, "keypress", this.eventKeypress);
-    }
-  },
-
-  activate: function(draggable) {
-    if(draggable.options.delay) {
-      this._timeout = setTimeout(function() {
-        Draggables._timeout = null;
-        window.focus();
-        Draggables.activeDraggable = draggable;
-      }.bind(this), draggable.options.delay);
-    } else {
-      window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
-      this.activeDraggable = draggable;
-    }
-  },
-
-  deactivate: function() {
-    this.activeDraggable = null;
-  },
-
-  updateDrag: function(event) {
-    if(!this.activeDraggable) return;
-    var pointer = [Event.pointerX(event), Event.pointerY(event)];
-    // Mozilla-based browsers fire successive mousemove events with
-    // the same coordinates, prevent needless redrawing (moz bug?)
-    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
-    this._lastPointer = pointer;
-
-    this.activeDraggable.updateDrag(event, pointer);
-  },
-
-  endDrag: function(event) {
-    if(this._timeout) {
-      clearTimeout(this._timeout);
-      this._timeout = null;
-    }
-    if(!this.activeDraggable) return;
-    this._lastPointer = null;
-    this.activeDraggable.endDrag(event);
-    this.activeDraggable = null;
-  },
-
-  keyPress: function(event) {
-    if(this.activeDraggable)
-      this.activeDraggable.keyPress(event);
-  },
-
-  addObserver: function(observer) {
-    this.observers.push(observer);
-    this._cacheObserverCallbacks();
-  },
-
-  removeObserver: function(element) {  // element instead of observer fixes mem leaks
-    this.observers = this.observers.reject( function(o) { return o.element==element });
-    this._cacheObserverCallbacks();
-  },
-
-  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
-    if(this[eventName+'Count'] > 0)
-      this.observers.each( function(o) {
-        if(o[eventName]) o[eventName](eventName, draggable, event);
-      });
-    if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
-  },
-
-  _cacheObserverCallbacks: function() {
-    ['onStart','onEnd','onDrag'].each( function(eventName) {
-      Draggables[eventName+'Count'] = Draggables.observers.select(
-        function(o) { return o[eventName]; }
-      ).length;
-    });
-  }
-};
-
-/*--------------------------------------------------------------------------*/
-
-var Draggable = Class.create({
-  initialize: function(element) {
-    var defaults = {
-      handle: false,
-      reverteffect: function(element, top_offset, left_offset) {
-        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
-        new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
-          queue: {scope:'_draggable', position:'end'}
-        });
-      },
-      endeffect: function(element) {
-        var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
-        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
-          queue: {scope:'_draggable', position:'end'},
-          afterFinish: function(){
-            Draggable._dragging[element] = false
-          }
-        });
-      },
-      zindex: 1000,
-      revert: false,
-      quiet: false,
-      scroll: false,
-      scrollSensitivity: 20,
-      scrollSpeed: 15,
-      snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
-      delay: 0
-    };
-
-    if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
-      Object.extend(defaults, {
-        starteffect: function(element) {
-          element._opacity = Element.getOpacity(element);
-          Draggable._dragging[element] = true;
-          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
-        }
-      });
-
-    var options = Object.extend(defaults, arguments[1] || { });
-
-    this.element = $(element);
-
-    if(options.handle && Object.isString(options.handle))
-      this.handle = this.element.down('.'+options.handle, 0);
-
-    if(!this.handle) this.handle = $(options.handle);
-    if(!this.handle) this.handle = this.element;
-
-    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
-      options.scroll = $(options.scroll);
-      this._isScrollChild = Element.childOf(this.element, options.scroll);
-    }
-
-    Element.makePositioned(this.element); // fix IE
-
-    this.options  = options;
-    this.dragging = false;
-
-    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
-    Event.observe(this.handle, "mousedown", this.eventMouseDown);
-
-    Draggables.register(this);
-  },
-
-  destroy: function() {
-    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
-    Draggables.unregister(this);
-  },
-
-  currentDelta: function() {
-    return([
-      parseInt(Element.getStyle(this.element,'left') || '0'),
-      parseInt(Element.getStyle(this.element,'top') || '0')]);
-  },
-
-  initDrag: function(event) {
-    if(!Object.isUndefined(Draggable._dragging[this.element]) &&
-      Draggable._dragging[this.element]) return;
-    if(Event.isLeftClick(event)) {
-      // abort on form elements, fixes a Firefox issue
-      var src = Event.element(event);
-      if((tag_name = src.tagName.toUpperCase()) && (
-        tag_name=='INPUT' ||
-        tag_name=='SELECT' ||
-        tag_name=='OPTION' ||
-        tag_name=='BUTTON' ||
-        tag_name=='TEXTAREA')) return;
-
-      var pointer = [Event.pointerX(event), Event.pointerY(event)];
-      var pos     = Position.cumulativeOffset(this.element);
-      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
-
-      Draggables.activate(this);
-      Event.stop(event);
-    }
-  },
-
-  startDrag: function(event) {
-    this.dragging = true;
-    if(!this.delta)
-      this.delta = this.currentDelta();
-
-    if(this.options.zindex) {
-      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
-      this.element.style.zIndex = this.options.zindex;
-    }
-
-    if(this.options.ghosting) {
-      this._clone = this.element.cloneNode(true);
-      this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
-      if (!this._originallyAbsolute)
-        Position.absolutize(this.element);
-      this.element.parentNode.insertBefore(this._clone, this.element);
-    }
-
-    if(this.options.scroll) {
-      if (this.options.scroll == window) {
-        var where = this._getWindowScroll(this.options.scroll);
-        this.originalScrollLeft = where.left;
-        this.originalScrollTop = where.top;
-      } else {
-        this.originalScrollLeft = this.options.scroll.scrollLeft;
-        this.originalScrollTop = this.options.scroll.scrollTop;
-      }
-    }
-
-    Draggables.notify('onStart', this, event);
-
-    if(this.options.starteffect) this.options.starteffect(this.element);
-  },
-
-  updateDrag: function(event, pointer) {
-    if(!this.dragging) this.startDrag(event);
-
-    if(!this.options.quiet){
-      Position.prepare();
-      Droppables.show(pointer, this.element);
-    }
-
-    Draggables.notify('onDrag', this, event);
-
-    this.draw(pointer);
-    if(this.options.change) this.options.change(this);
-
-    if(this.options.scroll) {
-      this.stopScrolling();
-
-      var p;
-      if (this.options.scroll == window) {
-        with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
-      } else {
-        p = Position.page(this.options.scroll);
-        p[0] += this.options.scroll.scrollLeft + Position.deltaX;
-        p[1] += this.options.scroll.scrollTop + Position.deltaY;
-        p.push(p[0]+this.options.scroll.offsetWidth);
-        p.push(p[1]+this.options.scroll.offsetHeight);
-      }
-      var speed = [0,0];
-      if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
-      if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
-      if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
-      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
-      this.startScrolling(speed);
-    }
-
-    // fix AppleWebKit rendering
-    if(Prototype.Browser.WebKit) window.scrollBy(0,0);
-
-    Event.stop(event);
-  },
-
-  finishDrag: function(event, success) {
-    this.dragging = false;
-
-    if(this.options.quiet){
-      Position.prepare();
-      var pointer = [Event.pointerX(event), Event.pointerY(event)];
-      Droppables.show(pointer, this.element);
-    }
-
-    if(this.options.ghosting) {
-      if (!this._originallyAbsolute)
-        Position.relativize(this.element);
-      delete this._originallyAbsolute;
-      Element.remove(this._clone);
-      this._clone = null;
-    }
-
-    var dropped = false;
-    if(success) {
-      dropped = Droppables.fire(event, this.element);
-      if (!dropped) dropped = false;
-    }
-    if(dropped && this.options.onDropped) this.options.onDropped(this.element);
-    Draggables.notify('onEnd', this, event);
-
-    var revert = this.options.revert;
-    if(revert && Object.isFunction(revert)) revert = revert(this.element);
-
-    var d = this.currentDelta();
-    if(revert && this.options.reverteffect) {
-      if (dropped == 0 || revert != 'failure')
-        this.options.reverteffect(this.element,
-          d[1]-this.delta[1], d[0]-this.delta[0]);
-    } else {
-      this.delta = d;
-    }
-
-    if(this.options.zindex)
-      this.element.style.zIndex = this.originalZ;
-
-    if(this.options.endeffect)
-      this.options.endeffect(this.element);
-
-    Draggables.deactivate(this);
-    Droppables.reset();
-  },
-
-  keyPress: function(event) {
-    if(event.keyCode!=Event.KEY_ESC) return;
-    this.finishDrag(event, false);
-    Event.stop(event);
-  },
-
-  endDrag: function(event) {
-    if(!this.dragging) return;
-    this.stopScrolling();
-    this.finishDrag(event, true);
-    Event.stop(event);
-  },
-
-  draw: function(point) {
-    var pos = Position.cumulativeOffset(this.element);
-    if(this.options.ghosting) {
-      var r   = Position.realOffset(this.element);
-      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
-    }
-
-    var d = this.currentDelta();
-    pos[0] -= d[0]; pos[1] -= d[1];
-
-    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
-      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
-      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
-    }
-
-    var p = [0,1].map(function(i){
-      return (point[i]-pos[i]-this.offset[i])
-    }.bind(this));
-
-    if(this.options.snap) {
-      if(Object.isFunction(this.options.snap)) {
-        p = this.options.snap(p[0],p[1],this);
-      } else {
-      if(Object.isArray(this.options.snap)) {
-        p = p.map( function(v, i) {
-          return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
-      } else {
-        p = p.map( function(v) {
-          return (v/this.options.snap).round()*this.options.snap }.bind(this));
-      }
-    }}
-
-    var style = this.element.style;
-    if((!this.options.constraint) || (this.options.constraint=='horizontal'))
-      style.left = p[0] + "px";
-    if((!this.options.constraint) || (this.options.constraint=='vertical'))
-      style.top  = p[1] + "px";
-
-    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
-  },
-
-  stopScrolling: function() {
-    if(this.scrollInterval) {
-      clearInterval(this.scrollInterval);
-      this.scrollInterval = null;
-      Draggables._lastScrollPointer = null;
-    }
-  },
-
-  startScrolling: function(speed) {
-    if(!(speed[0] || speed[1])) return;
-    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
-    this.lastScrolled = new Date();
-    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
-  },
-
-  scroll: function() {
-    var current = new Date();
-    var delta = current - this.lastScrolled;
-    this.lastScrolled = current;
-    if(this.options.scroll == window) {
-      with (this._getWindowScroll(this.options.scroll)) {
-        if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
-          var d = delta / 1000;
-          this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
-        }
-      }
-    } else {
-      this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
-      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
-    }
-
-    Position.prepare();
-    Droppables.show(Draggables._lastPointer, this.element);
-    Draggables.notify('onDrag', this);
-    if (this._isScrollChild) {
-      Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
-      Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
-      Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
-      if (Draggables._lastScrollPointer[0] < 0)
-        Draggables._lastScrollPointer[0] = 0;
-      if (Draggables._lastScrollPointer[1] < 0)
-        Draggables._lastScrollPointer[1] = 0;
-      this.draw(Draggables._lastScrollPointer);
-    }
-
-    if(this.options.change) this.options.change(this);
-  },
-
-  _getWindowScroll: function(w) {
-    var T, L, W, H;
-    with (w.document) {
-      if (w.document.documentElement && documentElement.scrollTop) {
-        T = documentElement.scrollTop;
-        L = documentElement.scrollLeft;
-      } else if (w.document.body) {
-        T = body.scrollTop;
-        L = body.scrollLeft;
-      }
-      if (w.innerWidth) {
-        W = w.innerWidth;
-        H = w.innerHeight;
-      } else if (w.document.documentElement && documentElement.clientWidth) {
-        W = documentElement.clientWidth;
-        H = documentElement.clientHeight;
-      } else {
-        W = body.offsetWidth;
-        H = body.offsetHeight;
-      }
-    }
-    return { top: T, left: L, width: W, height: H };
-  }
-});
-
-Draggable._dragging = { };
-
-/*--------------------------------------------------------------------------*/
-
-var SortableObserver = Class.create({
-  initialize: function(element, observer) {
-    this.element   = $(element);
-    this.observer  = observer;
-    this.lastValue = Sortable.serialize(this.element);
-  },
-
-  onStart: function() {
-    this.lastValue = Sortable.serialize(this.element);
-  },
-
-  onEnd: function() {
-    Sortable.unmark();
-    if(this.lastValue != Sortable.serialize(this.element))
-      this.observer(this.element)
-  }
-});
-
-var Sortable = {
-  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
-
-  sortables: { },
-
-  _findRootElement: function(element) {
-    while (element.tagName.toUpperCase() != "BODY") {
-      if(element.id && Sortable.sortables[element.id]) return element;
-      element = element.parentNode;
-    }
-  },
-
-  options: function(element) {
-    element = Sortable._findRootElement($(element));
-    if(!element) return;
-    return Sortable.sortables[element.id];
-  },
-
-  destroy: function(element){
-    element = $(element);
-    var s = Sortable.sortables[element.id];
-
-    if(s) {
-      Draggables.removeObserver(s.element);
-      s.droppables.each(function(d){ Droppables.remove(d) });
-      s.draggables.invoke('destroy');
-
-      delete Sortable.sortables[s.element.id];
-    }
-  },
-
-  create: function(element) {
-    element = $(element);
-    var options = Object.extend({
-      element:     element,
-      tag:         'li',       // assumes li children, override with tag: 'tagname'
-      dropOnEmpty: false,
-      tree:        false,
-      treeTag:     'ul',
-      overlap:     'vertical', // one of 'vertical', 'horizontal'
-      constraint:  'vertical', // one of 'vertical', 'horizontal', false
-      containment: element,    // also takes array of elements (or id's); or false
-      handle:      false,      // or a CSS class
-      only:        false,
-      delay:       0,
-      hoverclass:  null,
-      ghosting:    false,
-      quiet:       false,
-      scroll:      false,
-      scrollSensitivity: 20,
-      scrollSpeed: 15,
-      format:      this.SERIALIZE_RULE,
-
-      // these take arrays of elements or ids and can be
-      // used for better initialization performance
-      elements:    false,
-      handles:     false,
-
-      onChange:    Prototype.emptyFunction,
-      onUpdate:    Prototype.emptyFunction
-    }, arguments[1] || { });
-
-    // clear any old sortable with same element
-    this.destroy(element);
-
-    // build options for the draggables
-    var options_for_draggable = {
-      revert:      true,
-      quiet:       options.quiet,
-      scroll:      options.scroll,
-      scrollSpeed: options.scrollSpeed,
-      scrollSensitivity: options.scrollSensitivity,
-      delay:       options.delay,
-      ghosting:    options.ghosting,
-      constraint:  options.constraint,
-      handle:      options.handle };
-
-    if(options.starteffect)
-      options_for_draggable.starteffect = options.starteffect;
-
-    if(options.reverteffect)
-      options_for_draggable.reverteffect = options.reverteffect;
-    else
-      if(options.ghosting) options_for_draggable.reverteffect = function(element) {
-        element.style.top  = 0;
-        element.style.left = 0;
-      };
-
-    if(options.endeffect)
-      options_for_draggable.endeffect = options.endeffect;
-
-    if(options.zindex)
-      options_for_draggable.zindex = options.zindex;
-
-    // build options for the droppables
-    var options_for_droppable = {
-      overlap:     options.overlap,
-      containment: options.containment,
-      tree:        options.tree,
-      hoverclass:  options.hoverclass,
-      onHover:     Sortable.onHover
-    };
-
-    var options_for_tree = {
-      onHover:      Sortable.onEmptyHover,
-      overlap:      options.overlap,
-      containment:  options.containment,
-      hoverclass:   options.hoverclass
-    };
-
-    // fix for gecko engine
-    Element.cleanWhitespace(element);
-
-    options.draggables = [];
-    options.droppables = [];
-
-    // drop on empty handling
-    if(options.dropOnEmpty || options.tree) {
-      Droppables.add(element, options_for_tree);
-      options.droppables.push(element);
-    }
-
-    (options.elements || this.findElements(element, options) || []).each( function(e,i) {
-      var handle = options.handles ? $(options.handles[i]) :
-        (options.handle ? $(e).select('.' + options.handle)[0] : e);
-      options.draggables.push(
-        new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
-      Droppables.add(e, options_for_droppable);
-      if(options.tree) e.treeNode = element;
-      options.droppables.push(e);
-    });
-
-    if(options.tree) {
-      (Sortable.findTreeElements(element, options) || []).each( function(e) {
-        Droppables.add(e, options_for_tree);
-        e.treeNode = element;
-        options.droppables.push(e);
-      });
-    }
-
-    // keep reference
-    this.sortables[element.id] = options;
-
-    // for onupdate
-    Draggables.addObserver(new SortableObserver(element, options.onUpdate));
-
-  },
-
-  // return all suitable-for-sortable elements in a guaranteed order
-  findElements: function(element, options) {
-    return Element.findChildren(
-      element, options.only, options.tree ? true : false, options.tag);
-  },
-
-  findTreeElements: function(element, options) {
-    return Element.findChildren(
-      element, options.only, options.tree ? true : false, options.treeTag);
-  },
-
-  onHover: function(element, dropon, overlap) {
-    if(Element.isParent(dropon, element)) return;
-
-    if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
-      return;
-    } else if(overlap>0.5) {
-      Sortable.mark(dropon, 'before');
-      if(dropon.previousSibling != element) {
-        var oldParentNode = element.parentNode;
-        element.style.visibility = "hidden"; // fix gecko rendering
-        dropon.parentNode.insertBefore(element, dropon);
-        if(dropon.parentNode!=oldParentNode)
-          Sortable.options(oldParentNode).onChange(element);
-        Sortable.options(dropon.parentNode).onChange(element);
-      }
-    } else {
-      Sortable.mark(dropon, 'after');
-      var nextElement = dropon.nextSibling || null;
-      if(nextElement != element) {
-        var oldParentNode = element.parentNode;
-        element.style.visibility = "hidden"; // fix gecko rendering
-        dropon.parentNode.insertBefore(element, nextElement);
-        if(dropon.parentNode!=oldParentNode)
-          Sortable.options(oldParentNode).onChange(element);
-        Sortable.options(dropon.parentNode).onChange(element);
-      }
-    }
-  },
-
-  onEmptyHover: function(element, dropon, overlap) {
-    var oldParentNode = element.parentNode;
-    var droponOptions = Sortable.options(dropon);
-
-    if(!Element.isParent(dropon, element)) {
-      var index;
-
-      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
-      var child = null;
-
-      if(children) {
-        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
-
-        for (index = 0; index < children.length; index += 1) {
-          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
-            offset -= Element.offsetSize (children[index], droponOptions.overlap);
-          } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
-            child = index + 1 < children.length ? children[index + 1] : null;
-            break;
-          } else {
-            child = children[index];
-            break;
-          }
-        }
-      }
-
-      dropon.insertBefore(element, child);
-
-      Sortable.options(oldParentNode).onChange(element);
-      droponOptions.onChange(element);
-    }
-  },
-
-  unmark: function() {
-    if(Sortable._marker) Sortable._marker.hide();
-  },
-
-  mark: function(dropon, position) {
-    // mark on ghosting only
-    var sortable = Sortable.options(dropon.parentNode);
-    if(sortable && !sortable.ghosting) return;
-
-    if(!Sortable._marker) {
-      Sortable._marker =
-        ($('dropmarker') || Element.extend(document.createElement('DIV'))).
-          hide().addClassName('dropmarker').setStyle({position:'absolute'});
-      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
-    }
-    var offsets = Position.cumulativeOffset(dropon);
-    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
-
-    if(position=='after')
-      if(sortable.overlap == 'horizontal')
-        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
-      else
-        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
-
-    Sortable._marker.show();
-  },
-
-  _tree: function(element, options, parent) {
-    var children = Sortable.findElements(element, options) || [];
-
-    for (var i = 0; i < children.length; ++i) {
-      var match = children[i].id.match(options.format);
-
-      if (!match) continue;
-
-      var child = {
-        id: encodeURIComponent(match ? match[1] : null),
-        element: element,
-        parent: parent,
-        children: [],
-        position: parent.children.length,
-        container: $(children[i]).down(options.treeTag)
-      };
-
-      /* Get the element containing the children and recurse over it */
-      if (child.container)
-        this._tree(child.container, options, child);
-
-      parent.children.push (child);
-    }
-
-    return parent;
-  },
-
-  tree: function(element) {
-    element = $(element);
-    var sortableOptions = this.options(element);
-    var options = Object.extend({
-      tag: sortableOptions.tag,
-      treeTag: sortableOptions.treeTag,
-      only: sortableOptions.only,
-      name: element.id,
-      format: sortableOptions.format
-    }, arguments[1] || { });
-
-    var root = {
-      id: null,
-      parent: null,
-      children: [],
-      container: element,
-      position: 0
-    };
-
-    return Sortable._tree(element, options, root);
-  },
-
-  /* Construct a [i] index for a particular node */
-  _constructIndex: function(node) {
-    var index = '';
-    do {
-      if (node.id) index = '[' + node.position + ']' + index;
-    } while ((node = node.parent) != null);
-    return index;
-  },
-
-  sequence: function(element) {
-    element = $(element);
-    var options = Object.extend(this.options(element), arguments[1] || { });
-
-    return $(this.findElements(element, options) || []).map( function(item) {
-      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
-    });
-  },
-
-  setSequence: function(element, new_sequence) {
-    element = $(element);
-    var options = Object.extend(this.options(element), arguments[2] || { });
-
-    var nodeMap = { };
-    this.findElements(element, options).each( function(n) {
-        if (n.id.match(options.format))
-            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
-        n.parentNode.removeChild(n);
-    });
-
-    new_sequence.each(function(ident) {
-      var n = nodeMap[ident];
-      if (n) {
-        n[1].appendChild(n[0]);
-        delete nodeMap[ident];
-      }
-    });
-  },
-
-  serialize: function(element) {
-    element = $(element);
-    var options = Object.extend(Sortable.options(element), arguments[1] || { });
-    var name = encodeURIComponent(
-      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
-
-    if (options.tree) {
-      return Sortable.tree(element, arguments[1]).children.map( function (item) {
-        return [name + Sortable._constructIndex(item) + "[id]=" +
-                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
-      }).flatten().join('&');
-    } else {
-      return Sortable.sequence(element, arguments[1]).map( function(item) {
-        return name + "[]=" + encodeURIComponent(item);
-      }).join('&');
-    }
-  }
-};
-
-// Returns true if child is contained within element
-Element.isParent = function(child, element) {
-  if (!child.parentNode || child == element) return false;
-  if (child.parentNode == element) return true;
-  return Element.isParent(child.parentNode, element);
-};
-
-Element.findChildren = function(element, only, recursive, tagName) {
-  if(!element.hasChildNodes()) return null;
-  tagName = tagName.toUpperCase();
-  if(only) only = [only].flatten();
-  var elements = [];
-  $A(element.childNodes).each( function(e) {
-    if(e.tagName && e.tagName.toUpperCase()==tagName &&
-      (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
-        elements.push(e);
-    if(recursive) {
-      var grandchildren = Element.findChildren(e, only, recursive, tagName);
-      if(grandchildren) elements.push(grandchildren);
-    }
-  });
-
-  return (elements.length>0 ? elements.flatten() : []);
-};
-
-Element.offsetSize = function (element, type) {
-  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
-};
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/dabffc2fc4a60cc2c87340311e04fc75053c2695.svn-base
--- /dev/null
+++ b/.svn/pristine/da/dabffc2fc4a60cc2c87340311e04fc75053c2695.svn-base
@@ -0,0 +1,43 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module GanttHelper
+
+  def gantt_zoom_link(gantt, in_or_out)
+    case in_or_out
+    when :in
+      if gantt.zoom < 4
+        link_to_content_update l(:text_zoom_in),
+          params.merge(gantt.params.merge(:zoom => (gantt.zoom + 1))),
+          :class => 'icon icon-zoom-in'
+      else
+        content_tag(:span, l(:text_zoom_in), :class => 'icon icon-zoom-in').html_safe
+      end
+
+    when :out
+      if gantt.zoom > 1
+        link_to_content_update l(:text_zoom_out),
+          params.merge(gantt.params.merge(:zoom => (gantt.zoom - 1))),
+          :class => 'icon icon-zoom-out'
+      else
+        content_tag(:span, l(:text_zoom_out), :class => 'icon icon-zoom-out').html_safe
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/dad3a3fd832f92aba5ee807842c8f128fb126df0.svn-base
--- /dev/null
+++ b/.svn/pristine/da/dad3a3fd832f92aba5ee807842c8f128fb126df0.svn-base
@@ -0,0 +1,59 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::ThemesTest < ActiveSupport::TestCase
+
+  def test_themes
+    themes = Redmine::Themes.themes
+    assert_kind_of Array, themes
+    assert_kind_of Redmine::Themes::Theme, themes.first
+  end
+
+  def test_rescan
+    Redmine::Themes.themes.pop
+
+    assert_difference 'Redmine::Themes.themes.size' do
+      Redmine::Themes.rescan
+    end
+  end
+
+  def test_theme_loaded
+    theme = Redmine::Themes.themes.last
+
+    assert_equal theme, Redmine::Themes.theme(theme.id)
+  end
+
+  def test_theme_loaded_without_rescan
+    theme = Redmine::Themes.themes.last
+
+    assert_equal theme, Redmine::Themes.theme(theme.id, :rescan => false)
+  end
+
+  def test_theme_not_loaded
+    theme = Redmine::Themes.themes.pop
+
+    assert_equal theme, Redmine::Themes.theme(theme.id)
+  end
+
+  def test_theme_not_loaded_without_rescan
+    theme = Redmine::Themes.themes.pop
+
+    assert_nil Redmine::Themes.theme(theme.id, :rescan => false)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/daec043929c9800ec1c86a096d250b8584050bd6.svn-base
--- a/.svn/pristine/da/daec043929c9800ec1c86a096d250b8584050bd6.svn-base
+++ /dev/null
@@ -1,79 +0,0 @@
-module Redmine
-  module I18n
-    def self.included(base)
-      base.extend Redmine::I18n
-    end
-
-    def l(*args)
-      case args.size
-      when 1
-        ::I18n.t(*args)
-      when 2
-        if args.last.is_a?(Hash)
-          ::I18n.t(*args)
-        elsif args.last.is_a?(String)
-          ::I18n.t(args.first, :value => args.last)
-        else
-          ::I18n.t(args.first, :count => args.last)
-        end
-      else
-        raise "Translation string with multiple values: #{args.first}"
-      end
-    end
-
-    def l_or_humanize(s, options={})
-      k = "#{options[:prefix]}#{s}".to_sym
-      ::I18n.t(k, :default => s.to_s.humanize)
-    end
-
-    def l_hours(hours)
-      hours = hours.to_f
-      l((hours < 2.0 ? :label_f_hour : :label_f_hour_plural), :value => ("%.2f" % hours.to_f))
-    end
-
-    def ll(lang, str, value=nil)
-      ::I18n.t(str.to_s, :value => value, :locale => lang.to_s.gsub(%r{(.+)\-(.+)$}) { "#{$1}-#{$2.upcase}" })
-    end
-
-    def format_date(date)
-      return nil unless date
-      Setting.date_format.blank? ? ::I18n.l(date.to_date) : date.strftime(Setting.date_format)
-    end
-
-    def format_time(time, include_date = true)
-      return nil unless time
-      time = time.to_time if time.is_a?(String)
-      zone = User.current.time_zone
-      local = zone ? time.in_time_zone(zone) : (time.utc? ? time.localtime : time)
-      (include_date ? "#{format_date(local)} " : "") +
-        (Setting.time_format.blank? ? ::I18n.l(local, :format => :time) : local.strftime(Setting.time_format))
-    end
-
-    def day_name(day)
-      ::I18n.t('date.day_names')[day % 7]
-    end
-
-    def month_name(month)
-      ::I18n.t('date.month_names')[month]
-    end
-
-    def valid_languages
-      @@valid_languages ||= Dir.glob(File.join(Rails.root, 'config', 'locales', '*.yml')).collect {|f| File.basename(f).split('.').first}.collect(&:to_sym)
-    end
-
-    def find_language(lang)
-      @@languages_lookup = valid_languages.inject({}) {|k, v| k[v.to_s.downcase] = v; k }
-      @@languages_lookup[lang.to_s.downcase]
-    end
-
-    def set_language_if_valid(lang)
-      if l = find_language(lang)
-        ::I18n.locale = l
-      end
-    end
-
-    def current_language
-      ::I18n.locale
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/daf4fabdd56445c8d4501b8329ee068b8165fa5c.svn-base
--- /dev/null
+++ b/.svn/pristine/da/daf4fabdd56445c8d4501b8329ee068b8165fa5c.svn-base
@@ -0,0 +1,1090 @@
+# Redmine EU language
+# Author: Ales Zabala Alava (Shagi), <shagi@gisa-elkartea.org>
+# 2010-01-25
+# Distributed under the same terms as the Redmine itself.
+eu:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y/%m/%d"
+      short: "%b %d"
+      long: "%Y %B %d"
+
+    day_names: [Igandea, Astelehena, Asteartea, Asteazkena, Osteguna, Ostirala, Larunbata]
+    abbr_day_names: [Ig., Al., Ar., Az., Og., Or., La.]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Urtarrila, Otsaila, Martxoa, Apirila, Maiatza, Ekaina, Uztaila, Abuztua, Iraila, Urria, Azaroa, Abendua]
+    abbr_month_names: [~, Urt, Ots, Mar, Api, Mai, Eka, Uzt, Abu, Ira, Urr, Aza, Abe]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%Y/%m/%d %H:%M"
+      time: "%H:%M"
+      short: "%b %d %H:%M"
+      long: "%Y %B %d %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "minutu erdi"
+      less_than_x_seconds:
+        one:   "segundu bat baino gutxiago"
+        other: "%{count} segundu baino gutxiago"
+      x_seconds:
+        one:   "segundu 1"
+        other: "%{count} segundu"
+      less_than_x_minutes:
+        one:   "minutu bat baino gutxiago"
+        other: "%{count} minutu baino gutxiago"
+      x_minutes:
+        one:   "minutu 1"
+        other: "%{count} minutu"
+      about_x_hours:
+        one:   "ordu 1 inguru"
+        other: "%{count} ordu inguru"
+      x_hours:
+        one:   "ordu 1"
+        other: "%{count} ordu"
+      x_days:
+        one:   "egun 1"
+        other: "%{count} egun"
+      about_x_months:
+        one:   "hilabete 1 inguru"
+        other: "%{count} hilabete inguru"
+      x_months:
+        one:   "hilabete 1"
+        other: "%{count} hilabete"
+      about_x_years:
+        one:   "urte 1 inguru"
+        other: "%{count} urte inguru"
+      over_x_years:
+        one:   "urte 1 baino gehiago"
+        other: "%{count} urte baino gehiago"
+      almost_x_years:
+        one:   "ia urte 1"
+        other: "ia %{count} urte"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Byte"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "eta"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "Errore batek %{model} hau godetzea galarazi du."
+          other:  "%{count} errorek %{model} hau gordetzea galarazi dute."
+      messages:
+        inclusion: "ez dago zerrendan"
+        exclusion: "erreserbatuta dago"
+        invalid: "baliogabea da"
+        confirmation: "ez du berrespenarekin bat egiten"
+        accepted: "onartu behar da"
+        empty: "ezin da hutsik egon"
+        blank: "ezin da hutsik egon"
+        too_long: "luzeegia da (maximoa %{count} karaktere dira)"
+        too_short: "laburregia da (minimoa %{count} karaktere dira)"
+        wrong_length: "luzera ezegokia da (%{count} karakter izan beharko litzake)"
+        taken: "dagoeneko hartuta dago"
+        not_a_number: "ez da zenbaki bat"
+        not_a_date: "ez da baliozko data"
+        greater_than: "%{count} baino handiagoa izan behar du"
+        greater_than_or_equal_to: "%{count} edo handiagoa izan behar du"
+        equal_to: "%{count} izan behar du"
+        less_than: "%{count} baino gutxiago izan behar du"
+        less_than_or_equal_to: "%{count} edo gutxiago izan behar du"
+        odd: "bakoitia izan behar du"
+        even: "bikoitia izan behar du"
+        greater_than_start_date: "hasiera data baino handiagoa izan behar du"
+        not_same_project: "ez dago proiektu berdinean"
+        circular_dependency: "Erlazio honek mendekotasun zirkular bat sortuko luke"
+        cant_link_an_issue_with_a_descendant: "Zeregin bat ezin da bere azpiataza batekin estekatu."
+
+  actionview_instancetag_blank_option: Hautatu mesedez
+
+  general_text_No: 'Ez'
+  general_text_Yes: 'Bai'
+  general_text_no: 'ez'
+  general_text_yes: 'bai'
+  general_lang_name: 'Euskara'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Kontua ongi eguneratu da.
+  notice_account_invalid_creditentials: Erabiltzaile edo pasahitz ezegokia
+  notice_account_password_updated: Pasahitza ongi eguneratu da.
+  notice_account_wrong_password: Pasahitz ezegokia.
+  notice_account_register_done: Kontua ongi sortu da. Kontua gaitzeko klikatu epostan adierazi zaizun estekan.
+  notice_account_unknown_email: Erabiltzaile ezezaguna.
+  notice_can_t_change_password: Kontu honek kanpoko autentikazio bat erabiltzen du. Ezinezkoa da pasahitza aldatzea.
+  notice_account_lost_email_sent: Pasahitz berria aukeratzeko jarraibideak dituen eposta bat bidali zaizu.
+  notice_account_activated: Zure kontua gaituta dago. Orain saioa has dezakezu
+  notice_successful_create: Sortze arrakastatsua.
+  notice_successful_update: Eguneratze arrakastatsua.
+  notice_successful_delete: Ezabaketa arrakastatsua.
+  notice_successful_connection: Konexio arrakastatsua.
+  notice_file_not_found: Atzitu nahi duzun orria ez da exisitzen edo ezabatua izan da.
+  notice_locking_conflict: Beste erabiltzaile batek datuak eguneratu ditu.
+  notice_not_authorized: Ez duzu orri hau atzitzeko baimenik.
+  notice_email_sent: "%{value} helbidera eposta bat bidali da"
+  notice_email_error: "Errorea eposta bidaltzean (%{value})"
+  notice_feeds_access_key_reseted: Zure RSS atzipen giltza berrezarri da.
+  notice_api_access_key_reseted: Zure API atzipen giltza berrezarri da.
+  notice_failed_to_save_issues: "Hautatutako %{total} zereginetatik %{count} ezin izan dira konpondu: %{ids}."
+  notice_no_issue_selected: "Ez da zereginik hautatu! Mesedez, editatu nahi dituzun arazoak markatu."
+  notice_account_pending: "Zure kontua sortu da, orain kudeatzailearen onarpenaren zain dago."
+  notice_default_data_loaded: Lehenetsitako konfigurazioa ongi kargatu da.
+  notice_unable_delete_version: Ezin da bertsioa ezabatu.
+  notice_issue_done_ratios_updated: Burututako zereginen erlazioa eguneratu da.
+
+  error_can_t_load_default_data: "Ezin izan da lehenetsitako konfigurazioa kargatu: %{value}"
+  error_scm_not_found: "Sarrera edo berrikuspena ez da biltegian topatu."
+  error_scm_command_failed: "Errorea gertatu da biltegia atzitzean: %{value}"
+  error_scm_annotate: "Sarrera ez da existitzen edo ezin da anotatu."
+  error_issue_not_found_in_project: 'Zeregina ez da topatu edo ez da proiektu honetakoa'
+  error_no_tracker_in_project: 'Proiektu honek ez du aztarnaririk esleituta. Mesedez egiaztatu Proiektuaren ezarpenak.'
+  error_no_default_issue_status: 'Zereginek ez dute lehenetsitako egoerarik.  Mesedez egiaztatu zure konfigurazioa ("Kudeaketa -> Arazoen egoerak" atalera joan).'
+  error_can_not_reopen_issue_on_closed_version: 'Itxitako bertsio batera esleitutako zereginak ezin dira berrireki'
+  error_can_not_archive_project: Proiektu hau ezin da artxibatu
+  error_issue_done_ratios_not_updated: "Burututako zereginen erlazioa ez da eguneratu."
+  error_workflow_copy_source: 'Mesedez hautatu iturburuko aztarnari edo rola'
+  error_workflow_copy_target: 'Mesedez hautatu helburuko aztarnari(ak) edo rola(k)'
+
+  warning_attachments_not_saved: "%{count} fitxategi ezin izan d(ir)a gorde."
+
+  mail_subject_lost_password: "Zure %{value} pasahitza"
+  mail_body_lost_password: 'Zure pasahitza aldatzeko hurrengo estekan klikatu:'
+  mail_subject_register: "Zure %{value} kontuaren gaitzea"
+  mail_body_register: 'Zure kontua gaitzeko hurrengo estekan klikatu:'
+  mail_body_account_information_external: "Zure %{value} kontua erabil dezakezu saioa hasteko."
+  mail_body_account_information: Zure kontuaren informazioa
+  mail_subject_account_activation_request: "%{value} kontu gaitzeko eskaera"
+  mail_body_account_activation_request: "Erabiltzaile berri bat (%{value}) erregistratu da. Kontua zure onarpenaren zain dago:"
+  mail_subject_reminder: "%{count} arazo hurrengo %{days} egunetan amaitzen d(ir)a"
+  mail_body_reminder: "Zuri esleituta dauden %{count} arazo hurrengo %{days} egunetan amaitzen d(ir)a:"
+  mail_subject_wiki_content_added: "'%{id}' wiki orria gehitu da"
+  mail_body_wiki_content_added: "%{author}-(e)k '%{id}' wiki orria gehitu du."
+  mail_subject_wiki_content_updated: "'%{id}' wiki orria eguneratu da"
+  mail_body_wiki_content_updated: "%{author}-(e)k '%{id}' wiki orria eguneratu du."
+
+
+  field_name: Izena
+  field_description: Deskribapena
+  field_summary: Laburpena
+  field_is_required: Beharrezkoa
+  field_firstname: Izena
+  field_lastname: Abizenak
+  field_mail: Eposta
+  field_filename: Fitxategia
+  field_filesize: Tamaina
+  field_downloads: Deskargak
+  field_author: Egilea
+  field_created_on: Sortuta
+  field_updated_on: Eguneratuta
+  field_field_format: Formatua
+  field_is_for_all: Proiektu guztietarako
+  field_possible_values: Balio posibleak
+  field_regexp: Expresio erregularra
+  field_min_length: Luzera minimoa
+  field_max_length: Luzera maxioma
+  field_value: Balioa
+  field_category: Kategoria
+  field_title: Izenburua
+  field_project: Proiektua
+  field_issue: Zeregina
+  field_status: Egoera
+  field_notes: Oharrak
+  field_is_closed: Itxitako arazoa
+  field_is_default: Lehenetsitako balioa
+  field_tracker: Aztarnaria
+  field_subject: Gaia
+  field_due_date: Amaiera data
+  field_assigned_to: Esleituta
+  field_priority: Lehentasuna
+  field_fixed_version: Helburuko bertsioa
+  field_user: Erabiltzilea
+  field_role: Rola
+  field_homepage: Orri nagusia
+  field_is_public: Publikoa
+  field_parent: "Honen azpiproiektua:"
+  field_is_in_roadmap: Arazoak ibilbide-mapan erakutsi
+  field_login: Erabiltzaile izena
+  field_mail_notification: Eposta jakinarazpenak
+  field_admin: Kudeatzailea
+  field_last_login_on: Azken konexioa
+  field_language: Hizkuntza
+  field_effective_date: Data
+  field_password: Pasahitza
+  field_new_password: Pasahitz berria
+  field_password_confirmation: Berrespena
+  field_version: Bertsioa
+  field_type: Mota
+  field_host: Ostalaria
+  field_port: Portua
+  field_account: Kontua
+  field_base_dn: Base DN
+  field_attr_login: Erabiltzaile atributua
+  field_attr_firstname: Izena atributua
+  field_attr_lastname: Abizenak atributua
+  field_attr_mail: Eposta atributua
+  field_onthefly: Zuzeneko erabiltzaile sorrera
+  field_start_date: Hasiera
+  field_done_ratio: Egindako %
+  field_auth_source: Autentikazio modua
+  field_hide_mail: Nire eposta helbidea ezkutatu
+  field_comments: Iruzkina
+  field_url: URL
+  field_start_page: Hasierako orria
+  field_subproject: Azpiproiektua
+  field_hours: Ordu
+  field_activity: Jarduera
+  field_spent_on: Data
+  field_identifier: Identifikatzailea
+  field_is_filter: Iragazki moduan erabilita
+  field_issue_to: Erlazionatutako zereginak
+  field_delay: Atzerapena
+  field_assignable: Arazoak rol honetara esleitu daitezke
+  field_redirect_existing_links: Existitzen diren estekak berbideratu
+  field_estimated_hours: Estimatutako denbora
+  field_column_names: Zutabeak
+  field_time_zone: Ordu zonaldea
+  field_searchable: Bilagarria
+  field_default_value: Lehenetsitako balioa
+  field_comments_sorting: Iruzkinak erakutsi
+  field_parent_title: Orri gurasoa
+  field_editable: Editagarria
+  field_watcher: Behatzailea
+  field_identity_url: OpenID URLa
+  field_content: Edukia
+  field_group_by: Emaitzak honegatik taldekatu
+  field_sharing: Partekatzea
+
+  setting_app_title: Aplikazioaren izenburua
+  setting_app_subtitle: Aplikazioaren azpizenburua
+  setting_welcome_text: Ongietorriko testua
+  setting_default_language: Lehenetsitako hizkuntza
+  setting_login_required: Autentikazioa derrigorrezkoa
+  setting_self_registration: Norberak erregistratu
+  setting_attachment_max_size: Eranskinen tamaina max.
+  setting_issues_export_limit: Zereginen esportatze limitea
+  setting_mail_from: Igorlearen eposta helbidea
+  setting_bcc_recipients: Hartzaileak ezkutuko kopian (bcc)
+  setting_plain_text_mail: Testu soileko epostak (HTML-rik ez)
+  setting_host_name: Ostalari izena eta bidea
+  setting_text_formatting: Testu formatua
+  setting_wiki_compression: Wikiaren historia konprimitu
+  setting_feeds_limit: Jarioaren edukiera limitea
+  setting_default_projects_public: Proiektu berriak defektuz publikoak dira
+  setting_autofetch_changesets: Commit-ak automatikoki hartu
+  setting_sys_api_enabled: Biltegien kudeaketarako WS gaitu
+  setting_commit_ref_keywords: Erreferentzien gako-hitzak
+  setting_commit_fix_keywords: Konpontze gako-hitzak
+  setting_autologin: Saioa automatikoki hasi
+  setting_date_format: Data formatua
+  setting_time_format: Ordu formatua
+  setting_cross_project_issue_relations: Zereginak proiektuen artean erlazionatzea baimendu
+  setting_issue_list_default_columns: Zereginen zerrendan defektuz ikusten diren zutabeak
+  setting_emails_footer: Eposten oina
+  setting_protocol: Protokoloa
+  setting_per_page_options: Orriko objektuen aukerak
+  setting_user_format: Erabiltzaileak erakusteko formatua
+  setting_activity_days_default: Proiektuen jardueran erakusteko egunak
+  setting_display_subprojects_issues: Azpiproiektuen zereginak proiektu nagusian erakutsi defektuz
+  setting_enabled_scm: Gaitutako IKKak
+  setting_mail_handler_body_delimiters: "Lerro hauteko baten ondoren epostak moztu"
+  setting_mail_handler_api_enabled: Sarrerako epostentzako WS gaitu
+  setting_mail_handler_api_key: API giltza
+  setting_sequential_project_identifiers: Proiektuen identifikadore sekuentzialak sortu
+  setting_gravatar_enabled: Erabili Gravatar erabiltzaile ikonoak
+  setting_gravatar_default: Lehenetsitako Gravatar irudia
+  setting_diff_max_lines_displayed: Erakutsiko diren diff lerro kopuru maximoa
+  setting_file_max_size_displayed: Barnean erakuzten diren testu fitxategien tamaina maximoa
+  setting_repository_log_display_limit: Egunkari fitxategian erakutsiko diren berrikuspen kopuru maximoa.
+  setting_openid: Baimendu OpenID saio hasiera eta erregistatzea
+  setting_password_min_length: Pasahitzen luzera minimoa
+  setting_new_project_user_role_id: Proiektu berriak sortzerakoan kudeatzaile ez diren erabiltzaileei esleitutako rola
+  setting_default_projects_modules: Proiektu berrientzako defektuz gaitutako moduluak
+  setting_issue_done_ratio: "Zereginen burututako tasa kalkulatzean erabili:"
+  setting_issue_done_ratio_issue_field: Zeregin eremua erabili
+  setting_issue_done_ratio_issue_status: Zeregin egoera erabili
+  setting_start_of_week: "Egutegiak noiz hasi:"
+  setting_rest_api_enabled: Gaitu REST web zerbitzua
+
+  permission_add_project: Proiektua sortu
+  permission_add_subprojects: Azpiproiektuak sortu
+  permission_edit_project: Proiektua editatu
+  permission_select_project_modules: Proiektuaren moduluak hautatu
+  permission_manage_members: Kideak kudeatu
+  permission_manage_versions: Bertsioak kudeatu
+  permission_manage_categories: Arazoen kategoriak kudeatu
+  permission_view_issues: Zereginak ikusi
+  permission_add_issues: Zereginak gehitu
+  permission_edit_issues: Zereginak aldatu
+  permission_manage_issue_relations: Zereginen erlazioak kudeatu
+  permission_add_issue_notes: Oharrak gehitu
+  permission_edit_issue_notes: Oharrak aldatu
+  permission_edit_own_issue_notes: Nork bere oharrak aldatu
+  permission_move_issues: Zereginak mugitu
+  permission_delete_issues: Zereginak ezabatu
+  permission_manage_public_queries: Galdera publikoak kudeatu
+  permission_save_queries: Galderak gorde
+  permission_view_gantt: Gantt grafikoa ikusi
+  permission_view_calendar: Egutegia ikusi
+  permission_view_issue_watchers: Behatzaileen zerrenda ikusi
+  permission_add_issue_watchers: Behatzaileak gehitu
+  permission_delete_issue_watchers: Behatzaileak ezabatu
+  permission_log_time: Igarotako denbora erregistratu
+  permission_view_time_entries: Igarotako denbora ikusi
+  permission_edit_time_entries: Denbora egunkariak editatu
+  permission_edit_own_time_entries: Nork bere denbora egunkariak editatu
+  permission_manage_news: Berriak kudeatu
+  permission_comment_news: Berrien iruzkinak egin
+  permission_view_documents: Dokumentuak ikusi
+  permission_manage_files: Fitxategiak kudeatu
+  permission_view_files: Fitxategiak ikusi
+  permission_manage_wiki: Wikia kudeatu
+  permission_rename_wiki_pages: Wiki orriak berrizendatu
+  permission_delete_wiki_pages: Wiki orriak ezabatu
+  permission_view_wiki_pages: Wikia ikusi
+  permission_view_wiki_edits: Wikiaren historia ikusi
+  permission_edit_wiki_pages: Wiki orriak editatu
+  permission_delete_wiki_pages_attachments: Eranskinak ezabatu
+  permission_protect_wiki_pages: Wiki orriak babestu
+  permission_manage_repository: Biltegiak kudeatu
+  permission_browse_repository: Biltegia arakatu
+  permission_view_changesets: Aldaketak ikusi
+  permission_commit_access: Commit atzipena
+  permission_manage_boards: Foroak kudeatu
+  permission_view_messages: Mezuak ikusi
+  permission_add_messages: Mezuak bidali
+  permission_edit_messages: Mezuak aldatu
+  permission_edit_own_messages: Nork bere mezuak aldatu
+  permission_delete_messages: Mezuak ezabatu
+  permission_delete_own_messages: Nork bere mezuak ezabatu
+
+  project_module_issue_tracking: Zereginen jarraipena
+  project_module_time_tracking: Denbora jarraipena
+  project_module_news: Berriak
+  project_module_documents: Dokumentuak
+  project_module_files: Fitxategiak
+  project_module_wiki: Wiki
+  project_module_repository: Biltegia
+  project_module_boards: Foroak
+
+  label_user: Erabiltzailea
+  label_user_plural: Erabiltzaileak
+  label_user_new: Erabiltzaile berria
+  label_user_anonymous: Ezezaguna
+  label_project: Proiektua
+  label_project_new: Proiektu berria
+  label_project_plural: Proiektuak
+  label_x_projects:
+    zero:  proiekturik ez
+    one:   proiektu bat
+    other: "%{count} proiektu"
+  label_project_all: Proiektu guztiak
+  label_project_latest: Azken proiektuak
+  label_issue: Zeregina
+  label_issue_new: Zeregin berria
+  label_issue_plural: Zereginak
+  label_issue_view_all: Zeregin guztiak ikusi
+  label_issues_by: "Zereginak honengatik: %{value}"
+  label_issue_added: Zeregina gehituta
+  label_issue_updated: Zeregina eguneratuta
+  label_document: Dokumentua
+  label_document_new: Dokumentu berria
+  label_document_plural: Dokumentuak
+  label_document_added: Dokumentua gehituta
+  label_role: Rola
+  label_role_plural: Rolak
+  label_role_new: Rol berria
+  label_role_and_permissions: Rolak eta baimenak
+  label_member: Kidea
+  label_member_new: Kide berria
+  label_member_plural: Kideak
+  label_tracker: Aztarnaria
+  label_tracker_plural: Aztarnariak
+  label_tracker_new: Aztarnari berria
+  label_workflow: Lan-fluxua
+  label_issue_status: Zeregin egoera
+  label_issue_status_plural: Zeregin egoerak
+  label_issue_status_new: Egoera berria
+  label_issue_category: Zeregin kategoria
+  label_issue_category_plural: Zeregin kategoriak
+  label_issue_category_new: Kategoria berria
+  label_custom_field: Eremu pertsonalizatua
+  label_custom_field_plural: Eremu pertsonalizatuak
+  label_custom_field_new: Eremu pertsonalizatu berria
+  label_enumerations: Enumerazioak
+  label_enumeration_new: Balio berria
+  label_information: Informazioa
+  label_information_plural: Informazioa
+  label_please_login: Saioa hasi mesedez
+  label_register: Erregistratu
+  label_login_with_open_id_option: edo OpenID-rekin saioa hasi
+  label_password_lost: Pasahitza galduta
+  label_home: Hasiera
+  label_my_page: Nire orria
+  label_my_account: Nire kontua
+  label_my_projects: Nire proiektuak
+  label_administration: Kudeaketa
+  label_login: Saioa hasi
+  label_logout: Saioa bukatu
+  label_help: Laguntza
+  label_reported_issues: Berri emandako zereginak
+  label_assigned_to_me_issues: Niri esleitutako arazoak
+  label_last_login: Azken konexioa
+  label_registered_on: Noiz erregistratuta
+  label_activity: Jarduerak
+  label_overall_activity: Jarduera guztiak
+  label_user_activity: "%{value}-(r)en jarduerak"
+  label_new: Berria
+  label_logged_as: "Sartutako erabiltzailea:"
+  label_environment: Ingurune
+  label_authentication: Autentikazioa
+  label_auth_source: Autentikazio modua
+  label_auth_source_new: Autentikazio modu berria
+  label_auth_source_plural: Autentikazio moduak
+  label_subproject_plural: Azpiproiektuak
+  label_subproject_new: Azpiproiektu berria
+  label_and_its_subprojects: "%{value} eta bere azpiproiektuak"
+  label_min_max_length: Luzera min - max
+  label_list: Zerrenda
+  label_date: Data
+  label_integer: Osokoa
+  label_float: Koma higikorrekoa
+  label_boolean: Boolearra
+  label_string: Testua
+  label_text: Testu luzea
+  label_attribute: Atributua
+  label_attribute_plural: Atributuak
+  label_no_data: Ez dago erakusteko daturik
+  label_change_status: Egoera aldatu
+  label_history: Historikoa
+  label_attachment: Fitxategia
+  label_attachment_new: Fitxategi berria
+  label_attachment_delete: Fitxategia ezabatu
+  label_attachment_plural: Fitxategiak
+  label_file_added: Fitxategia gehituta
+  label_report: Berri ematea
+  label_report_plural: Berri emateak
+  label_news: Berria
+  label_news_new: Berria gehitu
+  label_news_plural: Berriak
+  label_news_latest: Azken berriak
+  label_news_view_all: Berri guztiak ikusi
+  label_news_added: Berria gehituta
+  label_settings: Ezarpenak
+  label_overview: Gainbegirada
+  label_version: Bertsioa
+  label_version_new: Bertsio berria
+  label_version_plural: Bertsioak
+  label_close_versions: Burututako bertsioak itxi
+  label_confirmation: Baieztapena
+  label_export_to: 'Eskuragarri baita:'
+  label_read: Irakurri...
+  label_public_projects: Proiektu publikoak
+  label_open_issues: irekita
+  label_open_issues_plural: irekiak
+  label_closed_issues: itxita
+  label_closed_issues_plural: itxiak
+  label_x_open_issues_abbr_on_total:
+    zero:  0 irekita / %{total}
+    one:   1 irekita / %{total}
+    other: "%{count} irekiak / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 irekita
+    one:   1 irekita
+    other: "%{count} irekiak"
+  label_x_closed_issues_abbr:
+    zero:  0 itxita
+    one:   1 itxita
+    other: "%{count} itxiak"
+  label_total: Guztira
+  label_permissions: Baimenak
+  label_current_status: Uneko egoera
+  label_new_statuses_allowed: Baimendutako egoera berriak
+  label_all: guztiak
+  label_none: ezer
+  label_nobody: inor
+  label_next: Hurrengoa
+  label_previous: Aurrekoak
+  label_used_by: Erabilita
+  label_details: Xehetasunak
+  label_add_note: Oharra gehitu
+  label_per_page: Orriko
+  label_calendar: Egutegia
+  label_months_from: hilabete noiztik
+  label_gantt: Gantt
+  label_internal: Barnekoa
+  label_last_changes: "azken %{count} aldaketak"
+  label_change_view_all: Aldaketa guztiak ikusi
+  label_personalize_page: Orri hau pertsonalizatu
+  label_comment: Iruzkin
+  label_comment_plural: Iruzkinak
+  label_x_comments:
+    zero: iruzkinik ez
+    one: iruzkin 1
+    other: "%{count} iruzkin"
+  label_comment_add: Iruzkina gehitu
+  label_comment_added: Iruzkina gehituta
+  label_comment_delete: Iruzkinak ezabatu
+  label_query: Galdera pertsonalizatua
+  label_query_plural: Pertsonalizatutako galderak
+  label_query_new: Galdera berria
+  label_filter_add: Iragazkia gehitu
+  label_filter_plural: Iragazkiak
+  label_equals: da
+  label_not_equals: ez da
+  label_in_less_than: baino gutxiagotan
+  label_in_more_than: baino gehiagotan
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: hauetan
+  label_today: gaur
+  label_all_time: denbora guztia
+  label_yesterday: atzo
+  label_this_week: aste honetan
+  label_last_week: pasadan astean
+  label_last_n_days: "azken %{count} egunetan"
+  label_this_month: hilabete hau
+  label_last_month: pasadan hilabetea
+  label_this_year: urte hau
+  label_date_range: Data tartea
+  label_less_than_ago: egun hauek baino gutxiago
+  label_more_than_ago: egun hauek baino gehiago
+  label_ago: orain dela
+  label_contains: dauka
+  label_not_contains: ez dauka
+  label_day_plural: egun
+  label_repository: Biltegia
+  label_repository_plural: Biltegiak
+  label_browse: Arakatu
+  label_branch: Adarra
+  label_tag: Etiketa
+  label_revision: Berrikuspena
+  label_revision_plural: Berrikuspenak
+  label_revision_id: "%{value} berrikuspen"
+  label_associated_revisions: Elkartutako berrikuspenak
+  label_added: gehituta
+  label_modified: aldatuta
+  label_copied: kopiatuta
+  label_renamed: berrizendatuta
+  label_deleted: ezabatuta
+  label_latest_revision: Azken berrikuspena
+  label_latest_revision_plural: Azken berrikuspenak
+  label_view_revisions: Berrikuspenak ikusi
+  label_view_all_revisions: Berrikuspen guztiak ikusi
+  label_max_size: Tamaina maximoa
+  label_sort_highest: Goraino mugitu
+  label_sort_higher: Gora mugitu
+  label_sort_lower: Behera mugitu
+  label_sort_lowest: Beheraino mugitu
+  label_roadmap: Ibilbide-mapa
+  label_roadmap_due_in: "Epea: %{value}"
+  label_roadmap_overdue: "%{value} berandu"
+  label_roadmap_no_issues: Ez dago zereginik bertsio honetan
+  label_search: Bilatu
+  label_result_plural: Emaitzak
+  label_all_words: hitz guztiak
+  label_wiki: Wikia
+  label_wiki_edit: Wiki edizioa
+  label_wiki_edit_plural: Wiki edizioak
+  label_wiki_page: Wiki orria
+  label_wiki_page_plural: Wiki orriak
+  label_index_by_title: Izenburuaren araberako indizea
+  label_index_by_date: Dataren araberako indizea
+  label_current_version: Uneko bertsioa
+  label_preview: Aurreikusi
+  label_feed_plural: Jarioak
+  label_changes_details: Aldaketa guztien xehetasunak
+  label_issue_tracking: Zeregin jarraipena
+  label_spent_time: Igarotako denbora
+  label_f_hour: "ordu %{value}"
+  label_f_hour_plural: "%{value} ordu"
+  label_time_tracking: Denbora jarraipena
+  label_change_plural: Aldaketak
+  label_statistics: Estatistikak
+  label_commits_per_month: Commit-ak hilabeteka
+  label_commits_per_author: Commit-ak egileka
+  label_view_diff: Ezberdintasunak ikusi
+  label_diff_inline: barnean
+  label_diff_side_by_side: aldez alde
+  label_options: Aukerak
+  label_copy_workflow_from: Kopiatu workflow-a hemendik
+  label_permissions_report: Baimenen txostena
+  label_watched_issues: Behatutako zereginak
+  label_related_issues: Erlazionatutako zereginak
+  label_applied_status: Aplikatutako egoera
+  label_loading: Kargatzen...
+  label_relation_new: Erlazio berria
+  label_relation_delete: Erlazioa ezabatu
+  label_relates_to: erlazionatuta dago
+  label_duplicates: bikoizten du
+  label_duplicated_by: honek bikoiztuta
+  label_blocks: blokeatzen du
+  label_blocked_by: honek blokeatuta
+  label_precedes: aurretik doa
+  label_follows: jarraitzen du
+  label_end_to_start: bukaeratik hasierara
+  label_end_to_end: bukaeratik bukaerara
+  label_start_to_start: hasieratik hasierhasieratik bukaerara
+  label_start_to_end: hasieratik bukaerara
+  label_stay_logged_in: Saioa mantendu
+  label_disabled: ezgaituta
+  label_show_completed_versions: Bukatutako bertsioak ikusi
+  label_me: ni
+  label_board: Foroa
+  label_board_new: Foro berria
+  label_board_plural: Foroak
+  label_topic_plural: Gaiak
+  label_message_plural: Mezuak
+  label_message_last: Azken mezua
+  label_message_new: Mezu berria
+  label_message_posted: Mezua gehituta
+  label_reply_plural: Erantzunak
+  label_send_information: Erabiltzaileai kontuaren informazioa bidali
+  label_year: Urtea
+  label_month: Hilabetea
+  label_week: Astea
+  label_date_from: Nork
+  label_date_to: Nori
+  label_language_based: Erabiltzailearen hizkuntzaren arabera
+  label_sort_by: "Ordenazioa: %{value}"
+  label_send_test_email: Frogako mezua bidali
+  label_feeds_access_key: RSS atzipen giltza
+  label_missing_feeds_access_key: RSS atzipen giltza falta da
+  label_feeds_access_key_created_on: "RSS atzipen giltza orain dela %{value} sortuta"
+  label_module_plural: Moduluak
+  label_added_time_by: "%{author}, orain dela %{age} gehituta"
+  label_updated_time_by: "%{author}, orain dela %{age} eguneratuta"
+  label_updated_time: "Orain dela %{value} eguneratuta"
+  label_jump_to_a_project: Joan proiektura...
+  label_file_plural: Fitxategiak
+  label_changeset_plural: Aldaketak
+  label_default_columns: Lehenetsitako zutabeak
+  label_no_change_option: (Aldaketarik ez)
+  label_bulk_edit_selected_issues: Hautatutako zereginak batera editatu
+  label_theme: Itxura
+  label_default: Lehenetsia
+  label_search_titles_only: Izenburuetan bakarrik bilatu
+  label_user_mail_option_all: "Nire proiektu guztietako gertakari guztientzat"
+  label_user_mail_option_selected: "Hautatutako proiektuetako edozein gertakarientzat..."
+  label_user_mail_no_self_notified: "Ez dut nik egiten ditudan aldeketen jakinarazpenik jaso nahi"
+  label_registration_activation_by_email: kontuak epostaz gaitu
+  label_registration_manual_activation: kontuak eskuz gaitu
+  label_registration_automatic_activation: kontuak automatikoki gaitu
+  label_display_per_page: "Orriko: %{value}"
+  label_age: Adina
+  label_change_properties: Propietateak aldatu
+  label_general: Orokorra
+  label_more: Gehiago
+  label_scm: IKK
+  label_plugins: Pluginak
+  label_ldap_authentication: LDAP autentikazioa
+  label_downloads_abbr: Desk.
+  label_optional_description: Aukerako deskribapena
+  label_add_another_file: Beste fitxategia gehitu
+  label_preferences: Hobespenak
+  label_chronological_order: Orden kronologikoan
+  label_reverse_chronological_order: Alderantzizko orden kronologikoan
+  label_planning: Planifikazioa
+  label_incoming_emails: Sarrerako epostak
+  label_generate_key: Giltza sortu
+  label_issue_watchers: Behatzaileak
+  label_example: Adibidea
+  label_display: Bistaratzea
+  label_sort: Ordenatu
+  label_ascending: Gorantz
+  label_descending: Beherantz
+  label_date_from_to: "%{start}-tik %{end}-ra"
+  label_wiki_content_added: Wiki orria gehituta
+  label_wiki_content_updated: Wiki orria eguneratuta
+  label_group: Taldea
+  label_group_plural: Taldeak
+  label_group_new: Talde berria
+  label_time_entry_plural: Igarotako denbora
+  label_version_sharing_none: Ez partekatuta
+  label_version_sharing_descendants: Azpiproiektuekin
+  label_version_sharing_hierarchy: Proiektu Hierarkiarekin
+  label_version_sharing_tree: Proiektu zuhaitzarekin
+  label_version_sharing_system: Proiektu guztiekin
+  label_update_issue_done_ratios: Zereginen burututako erlazioa eguneratu
+  label_copy_source: Iturburua
+  label_copy_target: Helburua
+  label_copy_same_as_target: Helburuaren berdina
+  label_display_used_statuses_only: Aztarnari honetan erabiltzen diren egoerak bakarrik erakutsi
+  label_api_access_key: API atzipen giltza
+  label_missing_api_access_key: API atzipen giltza falta da
+  label_api_access_key_created_on: "API atzipen giltza sortuta orain dela %{value}"
+
+  button_login: Saioa hasi
+  button_submit: Bidali
+  button_save: Gorde
+  button_check_all: Guztiak markatu
+  button_uncheck_all: Guztiak desmarkatu
+  button_delete: Ezabatu
+  button_create: Sortu
+  button_create_and_continue: Sortu eta jarraitu
+  button_test: Frogatu
+  button_edit: Editatu
+  button_add: Gehitu
+  button_change: Aldatu
+  button_apply: Aplikatu
+  button_clear: Garbitu
+  button_lock: Blokeatu
+  button_unlock: Desblokeatu
+  button_download: Deskargatu
+  button_list: Zerrenda
+  button_view: Ikusi
+  button_move: Mugitu
+  button_move_and_follow: Mugitu eta jarraitu
+  button_back: Atzera
+  button_cancel: Ezeztatu
+  button_activate: Gahitu
+  button_sort: Ordenatu
+  button_log_time: Denbora erregistratu
+  button_rollback: Itzuli bertsio honetara
+  button_watch: Behatu
+  button_unwatch: Behatzen utzi
+  button_reply: Erantzun
+  button_archive: Artxibatu
+  button_unarchive: Desartxibatu
+  button_reset: Berrezarri
+  button_rename: Berrizendatu
+  button_change_password: Pasahitza aldatu
+  button_copy: Kopiatu
+  button_copy_and_follow: Kopiatu eta jarraitu
+  button_annotate: Anotatu
+  button_update: Eguneratu
+  button_configure: Konfiguratu
+  button_quote: Aipatu
+  button_duplicate: Bikoiztu
+  button_show: Ikusi
+
+  status_active: gaituta
+  status_registered: izena emanda
+  status_locked: blokeatuta
+
+  version_status_open: irekita
+  version_status_locked: blokeatuta
+  version_status_closed: itxita
+
+  field_active: Gaituta
+
+  text_select_mail_notifications: Jakinarazpenak zein ekintzetarako bidaliko diren hautatu.
+  text_regexp_info: adib. ^[A-Z0-9]+$
+  text_min_max_length_info: 0k mugarik gabe esan nahi du
+  text_project_destroy_confirmation: Ziur zaude proiektu hau eta erlazionatutako datu guztiak ezabatu nahi dituzula?
+  text_subprojects_destroy_warning: "%{value} azpiproiektuak ere ezabatuko dira."
+  text_workflow_edit: Hautatu rola eta aztarnaria workflow-a editatzeko
+  text_are_you_sure: Ziur zaude?
+  text_journal_changed: "%{label} %{old}-(e)tik %{new}-(e)ra aldatuta"
+  text_journal_set_to: "%{label}-k %{value} balioa hartu du"
+  text_journal_deleted: "%{label} ezabatuta (%{old})"
+  text_journal_added: "%{label} %{value} gehituta"
+  text_tip_issue_begin_day: gaur hasten diren zereginak
+  text_tip_issue_end_day: gaur bukatzen diren zereginak
+  text_tip_issue_begin_end_day: gaur hasi eta bukatzen diren zereginak
+  text_caracters_maximum: "%{count} karaktere gehienez."
+  text_caracters_minimum: "Gutxienez %{count} karaktereetako luzerakoa izan behar du."
+  text_length_between: "Luzera %{min} eta %{max} karaktereen artekoa."
+  text_tracker_no_workflow: Ez da workflow-rik definitu aztarnari honentzako
+  text_unallowed_characters: Debekatutako karaktereak
+  text_comma_separated: Balio anitz izan daitezke (komaz banatuta).
+  text_line_separated: Balio anitz izan daitezke (balio bakoitza lerro batean).
+  text_issues_ref_in_commit_messages: Commit-en mezuetan zereginak erlazionatu eta konpontzen
+  text_issue_added: "%{id} zeregina %{author}-(e)k jakinarazi du."
+  text_issue_updated: "%{id} zeregina %{author}-(e)k eguneratu du."
+  text_wiki_destroy_confirmation: Ziur zaude wiki hau eta bere eduki guztiak ezabatu nahi dituzula?
+  text_issue_category_destroy_question: "Zeregin batzuk (%{count}) kategoria honetara esleituta daude. Zer egin nahi duzu?"
+  text_issue_category_destroy_assignments: Kategoria esleipenak kendu
+  text_issue_category_reassign_to: Zereginak kategoria honetara esleitu
+  text_user_mail_option: "Hautatu gabeko proiektuetan, behatzen edo parte hartzen duzun gauzei buruzko jakinarazpenak jasoko dituzu (adib. zu egile zaren edo esleituta dituzun zereginak)."
+  text_no_configuration_data: "Rolak, aztarnariak, zeregin egoerak eta workflow-ak ez dira oraindik konfiguratu.\nOso gomendagarria de lehenetsitako kkonfigurazioa kargatzea. Kargatu eta gero aldatu ahalko duzu."
+  text_load_default_configuration: Lehenetsitako konfigurazioa kargatu
+  text_status_changed_by_changeset: "%{value} aldaketan aplikatuta."
+  text_issues_destroy_confirmation: 'Ziur zaude hautatutako zeregina(k) ezabatu nahi dituzula?'
+  text_select_project_modules: 'Hautatu proiektu honetan gaitu behar diren moduluak:'
+  text_default_administrator_account_changed: Lehenetsitako kudeatzaile kontua aldatuta
+  text_file_repository_writable: Eranskinen direktorioan idatz daiteke
+  text_plugin_assets_writable: Pluginen baliabideen direktorioan idatz daiteke
+  text_rmagick_available: RMagick eskuragarri (aukerazkoa)
+  text_destroy_time_entries_question: "%{hours} orduei buruz berri eman zen zuk ezabatzera zoazen zereginean. Zer egin nahi duzu?"
+  text_destroy_time_entries: Ezabatu berri emandako orduak
+  text_assign_time_entries_to_project: Berri emandako orduak proiektura esleitu
+  text_reassign_time_entries: 'Berri emandako orduak zeregin honetara esleitu:'
+  text_user_wrote: "%{value}-(e)k idatzi zuen:"
+  text_enumeration_destroy_question: "%{count} objetu balio honetara esleituta daude."
+  text_enumeration_category_reassign_to: 'Beste balio honetara esleitu:'
+  text_email_delivery_not_configured: "Eposta bidalketa ez dago konfiguratuta eta jakinarazpenak ezgaituta daude.\nKonfiguratu zure SMTP zerbitzaria config/configuration.yml-n eta aplikazioa berrabiarazi hauek gaitzeko."
+  text_repository_usernames_mapping: "Hautatu edo eguneratu Redmineko erabiltzailea biltegiko egunkarietan topatzen diren erabiltzaile izenekin erlazionatzeko.\nRedmine-n eta biltegian erabiltzaile izen edo eposta berdina duten erabiltzaileak automatikoki erlazionatzen dira."
+  text_diff_truncated: '... Diff hau moztua izan da erakus daitekeen tamaina maximoa gainditu duelako.'
+  text_custom_field_possible_values_info: 'Lerro bat balio bakoitzeko'
+  text_wiki_page_destroy_question: "Orri honek %{descendants} orri seme eta ondorengo ditu. Zer egin nahi duzu?"
+  text_wiki_page_nullify_children: "Orri semeak erro orri moduan mantendu"
+  text_wiki_page_destroy_children: "Orri semeak eta beraien ondorengo guztiak ezabatu"
+  text_wiki_page_reassign_children: "Orri semeak orri guraso honetara esleitu"
+  text_own_membership_delete_confirmation: "Zure baimen batzuk (edo guztiak) kentzera zoaz eta baliteke horren ondoren proiektu hau ezin editatzea.\n Ziur zaude jarraitu nahi duzula?"
+
+  default_role_manager: Kudeatzailea
+  default_role_developer: Garatzailea
+  default_role_reporter: Berriemailea
+  default_tracker_bug: Errorea
+  default_tracker_feature: Eginbidea
+  default_tracker_support: Laguntza
+  default_issue_status_new: Berria
+  default_issue_status_in_progress: Lanean
+  default_issue_status_resolved: Ebatzita
+  default_issue_status_feedback: Berrelikadura
+  default_issue_status_closed: Itxita
+  default_issue_status_rejected: Baztertua
+  default_doc_category_user: Erabiltzaile dokumentazioa
+  default_doc_category_tech: Dokumentazio teknikoa
+  default_priority_low: Baxua
+  default_priority_normal: Normala
+  default_priority_high: Altua
+  default_priority_urgent: Larria
+  default_priority_immediate: Berehalakoa
+  default_activity_design: Diseinua
+  default_activity_development: Garapena
+
+  enumeration_issue_priorities: Zeregin lehentasunak
+  enumeration_doc_categories: Dokumentu kategoriak
+  enumeration_activities: Jarduerak (denbora kontrola))
+  enumeration_system_activity: Sistemako Jarduera
+  label_board_sticky: Itsaskorra
+  label_board_locked: Blokeatuta
+  permission_export_wiki_pages: Wiki orriak esportatu
+  setting_cache_formatted_text: Formatudun testua katxeatu
+  permission_manage_project_activities: Proiektuaren jarduerak kudeatu
+  error_unable_delete_issue_status: Ezine da zereginaren egoera ezabatu
+  label_profile: Profila
+  permission_manage_subtasks: Azpiatazak kudeatu
+  field_parent_issue: Zeregin gurasoa
+  label_subtask_plural: Azpiatazak
+  label_project_copy_notifications: Proiektua kopiatzen den bitartean eposta jakinarazpenak bidali
+  error_can_not_delete_custom_field: Ezin da eremu pertsonalizatua ezabatu
+  error_unable_to_connect: Ezin da konektatu (%{value})
+  error_can_not_remove_role: Rol hau erabiltzen hari da eta ezin da ezabatu.
+  error_can_not_delete_tracker: Aztarnari honek zereginak ditu eta ezin da ezabatu.
+  field_principal: Ekintzaile
+  label_my_page_block: "Nire orriko blokea"
+  notice_failed_to_save_members: "Kidea(k) gordetzean errorea: %{errors}."
+  text_zoom_out: Zooma txikiagotu
+  text_zoom_in: Zooma handiagotu
+  notice_unable_delete_time_entry: "Ezin da hautatutako denbora erregistroa ezabatu."
+  label_overall_spent_time: Igarotako denbora guztira
+  field_time_entries: "Denbora erregistratu"
+  project_module_gantt: Gantt
+  project_module_calendar: Egutegia
+  button_edit_associated_wikipage: "Esleitutako wiki orria editatu: %{page_title}"
+  field_text: Testu eremua
+  label_user_mail_option_only_owner: "Jabea naizen gauzetarako barrarik"
+  setting_default_notification_option: "Lehenetsitako ohartarazpen aukera"
+  label_user_mail_option_only_my_events: "Behatzen ditudan edo partaide naizen gauzetarako bakarrik"
+  label_user_mail_option_only_assigned: "Niri esleitutako gauzentzat bakarrik"
+  label_user_mail_option_none: "Gertakaririk ez"
+  field_member_of_group: "Esleituta duenaren taldea"
+  field_assigned_to_role: "Esleituta duenaren rola"
+  notice_not_authorized_archived_project: "Atzitu nahi duzun proiektua artxibatua izan da."
+  label_principal_search: "Bilatu erabiltzaile edo taldea:"
+  label_user_search: "Erabiltzailea bilatu:"
+  field_visible: Ikusgai
+  setting_emails_header: "Eposten goiburua"
+  setting_commit_logtime_activity_id: "Erregistratutako denboraren jarduera"
+  text_time_logged_by_changeset: "%{value} aldaketan egindakoa."
+  setting_commit_logtime_enabled: "Erregistrutako denbora gaitu"
+  notice_gantt_chart_truncated: Grafikoa moztu da bistara daitekeen elementuen kopuru maximoa gainditu delako (%{max})
+  setting_gantt_items_limit: "Gantt grafikoan bistara daitekeen elementu kopuru maximoa"
+  field_warn_on_leaving_unsaved: Gorde gabeko testua duen orri batetik ateratzen naizenean ohartarazi
+  text_warn_on_leaving_unsaved: Uneko orritik joaten bazara gorde gabeko testua galduko da.
+  label_my_queries: Nire galdera pertsonalizatuak
+  text_journal_changed_no_detail: "%{label} eguneratuta"
+  label_news_comment_added: Berri batera iruzkina gehituta
+  button_expand_all: Guztia zabaldu
+  button_collapse_all: Guztia tolestu
+  label_additional_workflow_transitions_for_assignee: Erabiltzaileak esleitua duenean baimendutako transtsizio gehigarriak
+  label_additional_workflow_transitions_for_author: Erabiltzailea egilea denean baimendutako transtsizio gehigarriak
+  label_bulk_edit_selected_time_entries: Hautatutako denbora egunkariak batera editatu
+  text_time_entries_destroy_confirmation: Ziur zaude hautatutako denbora egunkariak ezabatu nahi dituzula?
+  label_role_anonymous: Ezezaguna
+  label_role_non_member: Ez kidea
+  label_issue_note_added: Oharra gehituta
+  label_issue_status_updated: Egoera eguneratuta
+  label_issue_priority_updated: Lehentasuna eguneratuta
+  label_issues_visibility_own: Erabiltzaileak sortu edo esleituta dituen zereginak
+  field_issues_visibility: Zeregin ikusgarritasuna
+  label_issues_visibility_all: Zeregin guztiak
+  permission_set_own_issues_private: Nork bere zereginak publiko edo pribatu jarri
+  field_is_private: Pribatu
+  permission_set_issues_private: Zereginak publiko edo pribatu jarri
+  label_issues_visibility_public: Pribatu ez diren zeregin guztiak
+  text_issues_destroy_descendants_confirmation: Honek %{count} azpiataza ezabatuko ditu baita ere.
+  field_commit_logs_encoding: Commit-en egunkarien kodetzea
+  field_scm_path_encoding: Bidearen kodeketa
+  text_scm_path_encoding_note: "Lehentsita: UTF-8"
+  field_path_to_repository: Biltegirako bidea
+  field_root_directory: Erro direktorioa
+  field_cvs_module: Modulua
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Biltegi locala (adib. /hgrepo, c:\hgrepo)
+  text_scm_command: Komandoa
+  text_scm_command_version: Bertsioa
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 zeregina
+    one:   1 zeregina
+    other: "%{count} zereginak"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: guztiak
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Azpiproiektuekin
+  label_cross_project_tree: Proiektu zuhaitzarekin
+  label_cross_project_hierarchy: Proiektu Hierarkiarekin
+  label_cross_project_system: Proiektu guztiekin
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Guztira
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/da/dafecb9ad68a1547dfb840791b3055c95d90810f.svn-base
--- /dev/null
+++ b/.svn/pristine/da/dafecb9ad68a1547dfb840791b3055c95d90810f.svn-base
@@ -0,0 +1,749 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../test_helper', __FILE__)
+
+class Redmine::Helpers::GanttHelperTest < ActionView::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :journals, :journal_details,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :versions,
+           :groups_users
+
+  include ApplicationHelper
+  include ProjectsHelper
+  include IssuesHelper
+  include ERB::Util
+  include Rails.application.routes.url_helpers
+
+  def setup
+    setup_with_controller
+    User.current = User.find(1)
+  end
+
+  def today
+    @today ||= Date.today
+  end
+
+  # Creates a Gantt chart for a 4 week span
+  def create_gantt(project=Project.generate!, options={})
+    @project = project
+    @gantt = Redmine::Helpers::Gantt.new(options)
+    @gantt.project = @project
+    @gantt.query = IssueQuery.create!(:project => @project, :name => 'Gantt')
+    @gantt.view = self
+    @gantt.instance_variable_set('@date_from', options[:date_from] || (today - 14))
+    @gantt.instance_variable_set('@date_to', options[:date_to] || (today + 14))
+  end
+
+  context "#number_of_rows" do
+    context "with one project" do
+      should "return the number of rows just for that project"
+    end
+
+    context "with no project" do
+      should "return the total number of rows for all the projects, resursively"
+    end
+
+    should "not exceed max_rows option" do
+      p = Project.generate!
+      5.times do
+        Issue.generate!(:project => p)
+      end
+      create_gantt(p)
+      @gantt.render
+      assert_equal 6, @gantt.number_of_rows
+      assert !@gantt.truncated
+      create_gantt(p, :max_rows => 3)
+      @gantt.render
+      assert_equal 3, @gantt.number_of_rows
+      assert @gantt.truncated
+    end
+  end
+
+  context "#number_of_rows_on_project" do
+    setup do
+      create_gantt
+    end
+
+    should "count 0 for an empty the project" do
+      assert_equal 0, @gantt.number_of_rows_on_project(@project)
+    end
+
+    should "count the number of issues without a version" do
+      @project.issues << Issue.generate!(:project => @project, :fixed_version => nil)
+      assert_equal 2, @gantt.number_of_rows_on_project(@project)
+    end
+
+    should "count the number of issues on versions, including cross-project" do
+      version = Version.generate!
+      @project.versions << version
+      @project.issues << Issue.generate!(:project => @project, :fixed_version => version)
+      assert_equal 3, @gantt.number_of_rows_on_project(@project)
+    end
+  end
+
+  # TODO: more of an integration test
+  context "#subjects" do
+    setup do
+      create_gantt
+      @project.enabled_module_names = [:issue_tracking]
+      @tracker = Tracker.generate!
+      @project.trackers << @tracker
+      @version = Version.generate!(:effective_date => (today + 7), :sharing => 'none')
+      @project.versions << @version
+      @issue = Issue.generate!(:fixed_version => @version,
+                               :subject => "gantt#line_for_project",
+                               :tracker => @tracker,
+                               :project => @project,
+                               :done_ratio => 30,
+                               :start_date => (today - 1),
+                               :due_date => (today + 7))
+      @project.issues << @issue
+    end
+
+    context "project" do
+      should "be rendered" do
+        @output_buffer = @gantt.subjects
+        assert_select "div.project-name a", /#{@project.name}/
+      end
+
+      should "have an indent of 4" do
+        @output_buffer = @gantt.subjects
+        assert_select "div.project-name[style*=left:4px]"
+      end
+    end
+
+    context "version" do
+      should "be rendered" do
+        @output_buffer = @gantt.subjects
+        assert_select "div.version-name a", /#{@version.name}/
+      end
+
+      should "be indented 24 (one level)" do
+        @output_buffer = @gantt.subjects
+        assert_select "div.version-name[style*=left:24px]"
+      end
+
+      context "without assigned issues" do
+        setup do
+          @version = Version.generate!(:effective_date => (today + 14),
+                                       :sharing => 'none',
+                                       :name => 'empty_version')
+          @project.versions << @version
+        end
+
+        should "not be rendered" do
+          @output_buffer = @gantt.subjects
+          assert_select "div.version-name a", :text => /#{@version.name}/, :count => 0
+        end
+      end
+    end
+
+    context "issue" do
+      should "be rendered" do
+        @output_buffer = @gantt.subjects
+        assert_select "div.issue-subject", /#{@issue.subject}/
+      end
+
+      should "be indented 44 (two levels)" do
+        @output_buffer = @gantt.subjects
+        assert_select "div.issue-subject[style*=left:44px]"
+      end
+
+      context "assigned to a shared version of another project" do
+        setup do
+          p = Project.generate!
+          p.enabled_module_names = [:issue_tracking]
+          @shared_version = Version.generate!(:sharing => 'system')
+          p.versions << @shared_version
+          # Reassign the issue to a shared version of another project
+          @issue = Issue.generate!(:fixed_version => @shared_version,
+                                   :subject => "gantt#assigned_to_shared_version",
+                                   :tracker => @tracker,
+                                   :project => @project,
+                                   :done_ratio => 30,
+                                   :start_date => (today - 1),
+                                   :due_date => (today + 7))
+          @project.issues << @issue
+        end
+
+        should "be rendered" do
+          @output_buffer = @gantt.subjects
+          assert_select "div.issue-subject", /#{@issue.subject}/
+        end
+      end
+
+      context "with subtasks" do
+        setup do
+          attrs = {:project => @project, :tracker => @tracker, :fixed_version => @version}
+          @child1 = Issue.generate!(
+                       attrs.merge(:subject => 'child1',
+                                   :parent_issue_id => @issue.id,
+                                   :start_date => (today - 1),
+                                   :due_date => (today + 2))
+                      )
+          @child2 = Issue.generate!(
+                       attrs.merge(:subject => 'child2',
+                                   :parent_issue_id => @issue.id,
+                                   :start_date => today,
+                                   :due_date => (today + 7))
+                       )
+          @grandchild = Issue.generate!(
+                          attrs.merge(:subject => 'grandchild',
+                                      :parent_issue_id => @child1.id,
+                                      :start_date => (today - 1),
+                                      :due_date => (today + 2))
+                          )
+        end
+
+        should "indent subtasks" do
+          @output_buffer = @gantt.subjects
+          # parent task 44px
+          assert_select "div.issue-subject[style*=left:44px]", /#{@issue.subject}/
+          # children 64px
+          assert_select "div.issue-subject[style*=left:64px]", /child1/
+          assert_select "div.issue-subject[style*=left:64px]", /child2/
+          # grandchild 84px
+          assert_select "div.issue-subject[style*=left:84px]", /grandchild/, @output_buffer
+        end
+      end
+    end
+  end
+
+  context "#lines" do
+    setup do
+      create_gantt
+      @project.enabled_module_names = [:issue_tracking]
+      @tracker = Tracker.generate!
+      @project.trackers << @tracker
+      @version = Version.generate!(:effective_date => (today + 7))
+      @project.versions << @version
+      @issue = Issue.generate!(:fixed_version => @version,
+                               :subject => "gantt#line_for_project",
+                               :tracker => @tracker,
+                               :project => @project,
+                               :done_ratio => 30,
+                               :start_date => (today - 1),
+                               :due_date => (today + 7))
+      @project.issues << @issue
+      @output_buffer = @gantt.lines
+    end
+
+    context "project" do
+      should "be rendered" do
+        assert_select "div.project.task_todo"
+        assert_select "div.project.starting"
+        assert_select "div.project.ending"
+        assert_select "div.label.project", /#{@project.name}/
+      end
+    end
+
+    context "version" do
+      should "be rendered" do
+        assert_select "div.version.task_todo"
+        assert_select "div.version.starting"
+        assert_select "div.version.ending"
+        assert_select "div.label.version", /#{@version.name}/
+      end
+    end
+
+    context "issue" do
+      should "be rendered" do
+        assert_select "div.task_todo"
+        assert_select "div.task.label", /#{@issue.done_ratio}/
+        assert_select "div.tooltip", /#{@issue.subject}/
+      end
+    end
+  end
+
+  context "#render_project" do
+    should "be tested"
+  end
+
+  context "#render_issues" do
+    should "be tested"
+  end
+
+  context "#render_version" do
+    should "be tested"
+  end
+
+  context "#subject_for_project" do
+    setup do
+      create_gantt
+    end
+
+    context ":html format" do
+      should "add an absolute positioned div" do
+        @output_buffer = @gantt.subject_for_project(@project, {:format => :html})
+        assert_select "div[style*=absolute]"
+      end
+
+      should "use the indent option to move the div to the right" do
+        @output_buffer = @gantt.subject_for_project(@project, {:format => :html, :indent => 40})
+        assert_select "div[style*=left:40]"
+      end
+
+      should "include the project name" do
+        @output_buffer = @gantt.subject_for_project(@project, {:format => :html})
+        assert_select 'div', :text => /#{@project.name}/
+      end
+
+      should "include a link to the project" do
+        @output_buffer = @gantt.subject_for_project(@project, {:format => :html})
+        assert_select 'a[href=?]', "/projects/#{@project.identifier}", :text => /#{@project.name}/
+      end
+
+      should "style overdue projects" do
+        @project.enabled_module_names = [:issue_tracking]
+        @project.versions << Version.generate!(:effective_date => (today - 1))
+        assert @project.reload.overdue?, "Need an overdue project for this test"
+        @output_buffer = @gantt.subject_for_project(@project, {:format => :html})
+        assert_select 'div span.project-overdue'
+      end
+    end
+    should "test the PNG format"
+    should "test the PDF format"
+  end
+
+  context "#line_for_project" do
+    setup do
+      create_gantt
+      @project.enabled_module_names = [:issue_tracking]
+      @tracker = Tracker.generate!
+      @project.trackers << @tracker
+      @version = Version.generate!(:effective_date => (today - 1))
+      @project.versions << @version
+      @project.issues << Issue.generate!(:fixed_version => @version,
+                                         :subject => "gantt#line_for_project",
+                                         :tracker => @tracker,
+                                         :project => @project,
+                                         :done_ratio => 30,
+                                         :start_date => (today - 7),
+                                         :due_date => (today + 7))
+    end
+
+    context ":html format" do
+      context "todo line" do
+        should "start from the starting point on the left" do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.task_todo[style*=left:28px]", true, @output_buffer
+        end
+
+        should "be the total width of the project" do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.task_todo[style*=width:58px]", true, @output_buffer
+        end
+      end
+
+      context "late line" do
+        should_eventually "start from the starting point on the left" do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.task_late[style*=left:28px]", true, @output_buffer
+        end
+
+        should_eventually "be the total delayed width of the project" do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.task_late[style*=width:30px]", true, @output_buffer
+        end
+      end
+
+      context "done line" do
+        should_eventually "start from the starting point on the left" do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.task_done[style*=left:28px]", true, @output_buffer
+        end
+
+        should_eventually "Be the total done width of the project"  do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.task_done[style*=width:18px]", true, @output_buffer
+        end
+      end
+
+      context "starting marker" do
+        should "not appear if the starting point is off the gantt chart" do
+          # Shift the date range of the chart
+          @gantt.instance_variable_set('@date_from', today)
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.starting", false, @output_buffer
+        end
+
+        should "appear at the starting point" do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.starting[style*=left:28px]", true, @output_buffer
+        end
+      end
+
+      context "ending marker" do
+        should "not appear if the starting point is off the gantt chart" do
+          # Shift the date range of the chart
+          @gantt.instance_variable_set('@date_to', (today - 14))
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.ending", false, @output_buffer
+        end
+
+        should "appear at the end of the date range" do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.ending[style*=left:88px]", true, @output_buffer
+        end
+      end
+
+      context "status content" do
+        should "appear at the far left, even if it's far in the past" do
+          @gantt.instance_variable_set('@date_to', (today - 14))
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.label", /#{@project.name}/
+        end
+
+        should "show the project name" do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.label", /#{@project.name}/
+        end
+
+        should_eventually "show the percent complete" do
+          @output_buffer = @gantt.line_for_project(@project, {:format => :html, :zoom => 4})
+          assert_select "div.project.label", /0%/
+        end
+      end
+    end
+    should "test the PNG format"
+    should "test the PDF format"
+  end
+
+  context "#subject_for_version" do
+    setup do
+      create_gantt
+      @project.enabled_module_names = [:issue_tracking]
+      @tracker = Tracker.generate!
+      @project.trackers << @tracker
+      @version = Version.generate!(:effective_date => (today - 1))
+      @project.versions << @version
+      @project.issues << Issue.generate!(:fixed_version => @version,
+                                         :subject => "gantt#subject_for_version",
+                                         :tracker => @tracker,
+                                         :project => @project,
+                                         :start_date => today)
+
+    end
+
+    context ":html format" do
+      should "add an absolute positioned div" do
+        @output_buffer = @gantt.subject_for_version(@version, {:format => :html})
+        assert_select "div[style*=absolute]"
+      end
+
+      should "use the indent option to move the div to the right" do
+        @output_buffer = @gantt.subject_for_version(@version, {:format => :html, :indent => 40})
+        assert_select "div[style*=left:40]"
+      end
+
+      should "include the version name" do
+        @output_buffer = @gantt.subject_for_version(@version, {:format => :html})
+        assert_select 'div', :text => /#{@version.name}/
+      end
+
+      should "include a link to the version" do
+        @output_buffer = @gantt.subject_for_version(@version, {:format => :html})
+        assert_select 'a[href=?]', Regexp.escape("/versions/#{@version.to_param}"), :text => /#{@version.name}/
+      end
+
+      should "style late versions" do
+        assert @version.overdue?, "Need an overdue version for this test"
+        @output_buffer = @gantt.subject_for_version(@version, {:format => :html})
+        assert_select 'div span.version-behind-schedule'
+      end
+
+      should "style behind schedule versions" do
+        assert @version.behind_schedule?, "Need a behind schedule version for this test"
+        @output_buffer = @gantt.subject_for_version(@version, {:format => :html})
+        assert_select 'div span.version-behind-schedule'
+      end
+    end
+    should "test the PNG format"
+    should "test the PDF format"
+  end
+
+  context "#line_for_version" do
+    setup do
+      create_gantt
+      @project.enabled_module_names = [:issue_tracking]
+      @tracker = Tracker.generate!
+      @project.trackers << @tracker
+      @version = Version.generate!(:effective_date => (today + 7))
+      @project.versions << @version
+      @project.issues << Issue.generate!(:fixed_version => @version,
+                                         :subject => "gantt#line_for_project",
+                                         :tracker => @tracker,
+                                         :project => @project,
+                                         :done_ratio => 30,
+                                         :start_date => (today - 7),
+                                         :due_date => (today + 7))
+    end
+
+    context ":html format" do
+      context "todo line" do
+        should "start from the starting point on the left" do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.task_todo[style*=left:28px]", true, @output_buffer
+        end
+
+        should "be the total width of the version" do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.task_todo[style*=width:58px]", true, @output_buffer
+        end
+      end
+
+      context "late line" do
+        should "start from the starting point on the left" do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.task_late[style*=left:28px]", true, @output_buffer
+        end
+
+        should "be the total delayed width of the version" do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.task_late[style*=width:30px]", true, @output_buffer
+        end
+      end
+
+      context "done line" do
+        should "start from the starting point on the left" do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.task_done[style*=left:28px]", true, @output_buffer
+        end
+
+        should "be the total done width of the version"  do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.task_done[style*=width:16px]", true, @output_buffer
+        end
+      end
+
+      context "starting marker" do
+        should "not appear if the starting point is off the gantt chart" do
+          # Shift the date range of the chart
+          @gantt.instance_variable_set('@date_from', today)
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.starting", false
+        end
+
+        should "appear at the starting point" do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.starting[style*=left:28px]", true, @output_buffer
+        end
+      end
+
+      context "ending marker" do
+        should "not appear if the starting point is off the gantt chart" do
+          # Shift the date range of the chart
+          @gantt.instance_variable_set('@date_to', (today - 14))
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.ending", false
+        end
+
+        should "appear at the end of the date range" do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.ending[style*=left:88px]", true, @output_buffer
+        end
+      end
+
+      context "status content" do
+        should "appear at the far left, even if it's far in the past" do
+          @gantt.instance_variable_set('@date_to', (today - 14))
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.label", /#{@version.name}/
+        end
+
+        should "show the version name" do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.label", /#{@version.name}/
+        end
+
+        should "show the percent complete" do
+          @output_buffer = @gantt.line_for_version(@version, {:format => :html, :zoom => 4})
+          assert_select "div.version.label", /30%/
+        end
+      end
+    end
+    should "test the PNG format"
+    should "test the PDF format"
+  end
+
+  context "#subject_for_issue" do
+    setup do
+      create_gantt
+      @project.enabled_module_names = [:issue_tracking]
+      @tracker = Tracker.generate!
+      @project.trackers << @tracker
+      @issue = Issue.generate!(:subject => "gantt#subject_for_issue",
+                               :tracker => @tracker,
+                               :project => @project,
+                               :start_date => (today - 3),
+                               :due_date => (today - 1))
+      @project.issues << @issue
+    end
+
+    context ":html format" do
+      should "add an absolute positioned div" do
+        @output_buffer = @gantt.subject_for_issue(@issue, {:format => :html})
+        assert_select "div[style*=absolute]"
+      end
+
+      should "use the indent option to move the div to the right" do
+        @output_buffer = @gantt.subject_for_issue(@issue, {:format => :html, :indent => 40})
+        assert_select "div[style*=left:40]"
+      end
+
+      should "include the issue subject" do
+        @output_buffer = @gantt.subject_for_issue(@issue, {:format => :html})
+        assert_select 'div', :text => /#{@issue.subject}/
+      end
+
+      should "include a link to the issue" do
+        @output_buffer = @gantt.subject_for_issue(@issue, {:format => :html})
+        assert_select 'a[href=?]', Regexp.escape("/issues/#{@issue.to_param}"), :text => /#{@tracker.name} ##{@issue.id}/
+      end
+
+      should "style overdue issues" do
+        assert @issue.overdue?, "Need an overdue issue for this test"
+        @output_buffer = @gantt.subject_for_issue(@issue, {:format => :html})
+        assert_select 'div span.issue-overdue'
+      end
+    end
+    should "test the PNG format"
+    should "test the PDF format"
+  end
+
+  context "#line_for_issue" do
+    setup do
+      create_gantt
+      @project.enabled_module_names = [:issue_tracking]
+      @tracker = Tracker.generate!
+      @project.trackers << @tracker
+      @version = Version.generate!(:effective_date => (today + 7))
+      @project.versions << @version
+      @issue = Issue.generate!(:fixed_version => @version,
+                               :subject => "gantt#line_for_project",
+                               :tracker => @tracker,
+                               :project => @project,
+                               :done_ratio => 30,
+                               :start_date => (today - 7),
+                               :due_date => (today + 7))
+      @project.issues << @issue
+    end
+
+    context ":html format" do
+      context "todo line" do
+        should "start from the starting point on the left" do
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          assert_select "div.task_todo[style*=left:28px]", true, @output_buffer
+        end
+
+        should "be the total width of the issue" do
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          assert_select "div.task_todo[style*=width:58px]", true, @output_buffer
+        end
+      end
+
+      context "late line" do
+        should "start from the starting point on the left" do
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          assert_select "div.task_late[style*=left:28px]", true, @output_buffer
+        end
+
+        should "be the total delayed width of the issue" do
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          assert_select "div.task_late[style*=width:30px]", true, @output_buffer
+        end
+      end
+
+      context "done line" do
+        should "start from the starting point on the left" do
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          assert_select "div.task_done[style*=left:28px]", true, @output_buffer
+        end
+
+        should "be the total done width of the issue"  do
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          # 15 days * 4 px * 30% - 2 px for borders = 16 px
+          assert_select "div.task_done[style*=width:16px]", true, @output_buffer
+        end
+
+        should "not be the total done width if the chart starts after issue start date"  do
+          create_gantt(@project, :date_from => (today - 5))
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          assert_select "div.task_done[style*=left:0px]", true, @output_buffer
+          assert_select "div.task_done[style*=width:8px]", true, @output_buffer
+        end
+
+        context "for completed issue" do
+          setup do
+            @issue.done_ratio = 100
+          end
+
+          should "be the total width of the issue"  do
+            @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+            assert_select "div.task_done[style*=width:58px]", true, @output_buffer
+          end
+
+          should "be the total width of the issue with due_date=start_date"  do
+            @issue.due_date = @issue.start_date
+            @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+            assert_select "div.task_done[style*=width:2px]", true, @output_buffer
+          end
+        end
+      end
+
+      context "status content" do
+        should "appear at the far left, even if it's far in the past" do
+          @gantt.instance_variable_set('@date_to', (today - 14))
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          assert_select "div.task.label", true, @output_buffer
+        end
+
+        should "show the issue status" do
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          assert_select "div.task.label", /#{@issue.status.name}/
+        end
+
+        should "show the percent complete" do
+          @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+          assert_select "div.task.label", /30%/
+        end
+      end
+    end
+
+    should "have an issue tooltip" do
+      @output_buffer = @gantt.line_for_issue(@issue, {:format => :html, :zoom => 4})
+      assert_select "div.tooltip", /#{@issue.subject}/
+    end
+    should "test the PNG format"
+    should "test the PDF format"
+  end
+
+  context "#to_image" do
+    should "be tested"
+  end
+
+  context "#to_pdf" do
+    should "be tested"
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/db/db3e656f6a1b8b9454d5de84d641938d6207efc9.svn-base
--- /dev/null
+++ b/.svn/pristine/db/db3e656f6a1b8b9454d5de84d641938d6207efc9.svn-base
@@ -0,0 +1,108 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class RolesController < ApplicationController
+  layout 'admin'
+
+  before_filter :require_admin, :except => [:index, :show]
+  before_filter :require_admin_or_api_request, :only => [:index, :show]
+  before_filter :find_role, :only => [:show, :edit, :update, :destroy]
+  accept_api_auth :index, :show
+
+  def index
+    respond_to do |format|
+      format.html {
+        @role_pages, @roles = paginate Role.sorted, :per_page => 25
+        render :action => "index", :layout => false if request.xhr?
+      }
+      format.api {
+        @roles = Role.givable.all
+      }
+    end
+  end
+
+  def show
+    respond_to do |format|
+      format.api
+    end
+  end
+
+  def new
+    # Prefills the form with 'Non member' role permissions by default
+    @role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
+    if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy])
+      @role.copy_from(@copy_from)
+    end
+    @roles = Role.sorted.all
+  end
+
+  def create
+    @role = Role.new(params[:role])
+    if request.post? && @role.save
+      # workflow copy
+      if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
+        @role.workflow_rules.copy(copy_from)
+      end
+      flash[:notice] = l(:notice_successful_create)
+      redirect_to roles_path
+    else
+      @roles = Role.sorted.all
+      render :action => 'new'
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    if request.put? and @role.update_attributes(params[:role])
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to roles_path
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def destroy
+    @role.destroy
+    redirect_to roles_path
+  rescue
+    flash[:error] =  l(:error_can_not_remove_role)
+    redirect_to roles_path
+  end
+
+  def permissions
+    @roles = Role.sorted.all
+    @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
+    if request.post?
+      @roles.each do |role|
+        role.permissions = params[:permissions][role.id.to_s]
+        role.save
+      end
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to roles_path
+    end
+  end
+
+  private
+
+  def find_role
+    @role = Role.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/db/db9d5de4e29d812e502d8ee4c3a6a7311df17b3f.svn-base
--- a/.svn/pristine/db/db9d5de4e29d812e502d8ee4c3a6a7311df17b3f.svn-base
+++ /dev/null
@@ -1,108 +0,0 @@
-# $Id: dataset.rb 78 2006-04-26 02:57:34Z blackhedd $
-#
-#
-#----------------------------------------------------------------------------
-#
-# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
-#
-# Gmail: garbagecat10
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-#
-#---------------------------------------------------------------------------
-#
-#
-
-
-
-
-module Net
-class LDAP
-
-class Dataset < Hash
-
-  attr_reader :comments
-
-
-  def Dataset::read_ldif io
-    ds = Dataset.new
-
-    line = io.gets && chomp
-    dn = nil
-
-    while line
-      io.gets and chomp
-      if $_ =~ /^[\s]+/
-        line << " " << $'
-      else
-        nextline = $_
-
-        if line =~ /^\#/
-          ds.comments << line
-        elsif line =~ /^dn:[\s]*/i
-          dn = $'
-          ds[dn] = Hash.new {|k,v| k[v] = []}
-        elsif line.length == 0
-          dn = nil
-        elsif line =~ /^([^:]+):([\:]?)[\s]*/
-          # $1 is the attribute name
-          # $2 is a colon iff the attr-value is base-64 encoded
-          # $' is the attr-value
-          # Avoid the Base64 class because not all Ruby versions have it.
-          attrvalue = ($2 == ":") ? $'.unpack('m').shift : $'
-          ds[dn][$1.downcase.intern] << attrvalue
-        end
-
-        line = nextline
-      end
-    end
-  
-    ds
-  end
-
-
-  def initialize
-    @comments = []
-  end
-
-
-  def to_ldif
-    ary = []
-    ary += (@comments || [])
-
-    keys.sort.each {|dn|
-      ary << "dn: #{dn}"
-
-      self[dn].keys.map {|sym| sym.to_s}.sort.each {|attr|
-        self[dn][attr.intern].each {|val|
-          ary << "#{attr}: #{val}"
-        }
-      }
-
-      ary << ""
-    }
-
-    block_given? and ary.each {|line| yield line}
-
-    ary
-  end
-
-
-end # Dataset
-
-end # LDAP
-end # Net
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/db/db9e904490ce0fdbeaf9fc8c27e1c7ab2c4b6c9a.svn-base
--- a/.svn/pristine/db/db9e904490ce0fdbeaf9fc8c27e1c7ab2c4b6c9a.svn-base
+++ /dev/null
@@ -1,189 +0,0 @@
-module CodeRay
-module Scanners
-  
-  # Scanner for C.
-  class C < Scanner
-
-    register_for :c
-    file_extension 'c'
-    
-    KEYWORDS = [
-      'asm', 'break', 'case', 'continue', 'default', 'do',
-      'else', 'enum', 'for', 'goto', 'if', 'return',
-      'sizeof', 'struct', 'switch', 'typedef', 'union', 'while',
-      'restrict',  # added in C99
-    ]  # :nodoc:
-
-    PREDEFINED_TYPES = [
-      'int', 'long', 'short', 'char',
-      'signed', 'unsigned', 'float', 'double',
-      'bool', 'complex',  # added in C99
-    ]  # :nodoc:
-
-    PREDEFINED_CONSTANTS = [
-      'EOF', 'NULL',
-      'true', 'false',  # added in C99
-    ]  # :nodoc:
-    DIRECTIVES = [
-      'auto', 'extern', 'register', 'static', 'void',
-      'const', 'volatile',  # added in C89
-      'inline',  # added in C99
-    ]  # :nodoc:
-
-    IDENT_KIND = WordList.new(:ident).
-      add(KEYWORDS, :keyword).
-      add(PREDEFINED_TYPES, :predefined_type).
-      add(DIRECTIVES, :directive).
-      add(PREDEFINED_CONSTANTS, :predefined_constant)  # :nodoc:
-
-    ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x  # :nodoc:
-    UNICODE_ESCAPE =  / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x  # :nodoc:
-    
-  protected
-    
-    def scan_tokens encoder, options
-
-      state = :initial
-      label_expected = true
-      case_expected = false
-      label_expected_before_preproc_line = nil
-      in_preproc_line = false
-
-      until eos?
-
-        case state
-
-        when :initial
-
-          if match = scan(/ \s+ | \\\n /x)
-            if in_preproc_line && match != "\\\n" && match.index(?\n)
-              in_preproc_line = false
-              label_expected = label_expected_before_preproc_line
-            end
-            encoder.text_token match, :space
-
-          elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
-            encoder.text_token match, :comment
-
-          elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x)
-            label_expected = match =~ /[;\{\}]/
-            if case_expected
-              label_expected = true if match == ':'
-              case_expected = false
-            end
-            encoder.text_token match, :operator
-
-          elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
-            kind = IDENT_KIND[match]
-            if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/)
-              kind = :label
-              match << matched
-            else
-              label_expected = false
-              if kind == :keyword
-                case match
-                when 'case', 'default'
-                  case_expected = true
-                end
-              end
-            end
-            encoder.text_token match, kind
-
-          elsif match = scan(/L?"/)
-            encoder.begin_group :string
-            if match[0] == ?L
-              encoder.text_token 'L', :modifier
-              match = '"'
-            end
-            encoder.text_token match, :delimiter
-            state = :string
-
-          elsif match = scan(/ \# \s* if \s* 0 /x)
-            match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos?
-            encoder.text_token match, :comment
-
-          elsif match = scan(/#[ \t]*(\w*)/)
-            encoder.text_token match, :preprocessor
-            in_preproc_line = true
-            label_expected_before_preproc_line = label_expected
-            state = :include_expected if self[1] == 'include'
-
-          elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
-            label_expected = false
-            encoder.text_token match, :char
-
-          elsif match = scan(/\$/)
-            encoder.text_token match, :ident
-          
-          elsif match = scan(/0[xX][0-9A-Fa-f]+/)
-            label_expected = false
-            encoder.text_token match, :hex
-
-          elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/)
-            label_expected = false
-            encoder.text_token match, :octal
-
-          elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/)
-            label_expected = false
-            encoder.text_token match, :integer
-
-          elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
-            label_expected = false
-            encoder.text_token match, :float
-
-          else
-            encoder.text_token getch, :error
-
-          end
-
-        when :string
-          if match = scan(/[^\\\n"]+/)
-            encoder.text_token match, :content
-          elsif match = scan(/"/)
-            encoder.text_token match, :delimiter
-            encoder.end_group :string
-            state = :initial
-            label_expected = false
-          elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
-            encoder.text_token match, :char
-          elsif match = scan(/ \\ | $ /x)
-            encoder.end_group :string
-            encoder.text_token match, :error
-            state = :initial
-            label_expected = false
-          else
-            raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
-          end
-
-        when :include_expected
-          if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/)
-            encoder.text_token match, :include
-            state = :initial
-
-          elsif match = scan(/\s+/)
-            encoder.text_token match, :space
-            state = :initial if match.index ?\n
-
-          else
-            state = :initial
-
-          end
-
-        else
-          raise_inspect 'Unknown state', encoder
-
-        end
-
-      end
-
-      if state == :string
-        encoder.end_group :string
-      end
-
-      encoder
-    end
-
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/db/dbb3c3187473e9009ac8919d34a2738a03662844.svn-base
--- /dev/null
+++ b/.svn/pristine/db/dbb3c3187473e9009ac8919d34a2738a03662844.svn-base
@@ -0,0 +1,16 @@
+jsToolBar.strings = {};
+jsToolBar.strings['Strong'] = 'Pastorinti';
+jsToolBar.strings['Italic'] = 'Italic';
+jsToolBar.strings['Underline'] = 'Pabraukti';
+jsToolBar.strings['Deleted'] = 'UÅ¾braukti';
+jsToolBar.strings['Code'] = 'Kodas';
+jsToolBar.strings['Heading 1'] = 'Heading 1';
+jsToolBar.strings['Heading 2'] = 'Heading 2';
+jsToolBar.strings['Heading 3'] = 'Heading 3';
+jsToolBar.strings['Unordered list'] = 'Nenumeruotas sÄ…raÅ¡as';
+jsToolBar.strings['Ordered list'] = 'Numeruotas sÄ…raÅ¡as';
+jsToolBar.strings['Quote'] = 'Cituoti';
+jsToolBar.strings['Unquote'] = 'PaÅ¡alinti citavimÄ…';
+jsToolBar.strings['Preformatted text'] = 'Preformatuotas tekstas';
+jsToolBar.strings['Wiki link'] = 'Nuoroda Ä¯ Wiki puslapÄ¯';
+jsToolBar.strings['Image'] = 'Paveikslas';
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/db/dbbe02344b02394382c3153c6c0b7b7ba7f46fe0.svn-base
--- a/.svn/pristine/db/dbbe02344b02394382c3153c6c0b7b7ba7f46fe0.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-Event.observe(window,'load',function() {
-  /* 
-  If we're viewing a tag or branch, don't display it in the
-  revision box
-  */
-  var branch_selected = $('branch') && $('rev').getValue() == $('branch').getValue();
-  var tag_selected = $('tag') && $('rev').getValue() == $('tag').getValue();
-  if (branch_selected || tag_selected) {
-    $('rev').setValue('');
-  }
-
-  /* 
-  Copy the branch/tag value into the revision box, then disable
-  the dropdowns before submitting the form
-  */
-  $$('#branch,#tag').each(function(e) {
-    e.observe('change',function(e) {
-      $('rev').setValue(e.element().getValue());
-      $$('#branch,#tag').invoke('disable');
-      e.element().parentNode.submit();
-      $$('#branch,#tag').invoke('enable');
-    });
-  });
-
-  /*
-  Disable the branch/tag dropdowns before submitting the revision form
-  */
-  $('rev').observe('keydown', function(e) {
-    if (e.keyCode == 13) {
-      $$('#branch,#tag').invoke('disable');
-      e.element().parentNode.submit();
-      $$('#branch,#tag').invoke('enable');
-    }
-  });
-})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/db/dbc0240219da62eef782708d0af28fabe28645e6.svn-base
--- /dev/null
+++ b/.svn/pristine/db/dbc0240219da62eef782708d0af28fabe28645e6.svn-base
@@ -0,0 +1,86 @@
+<%= board_breadcrumb(@message) %>
+
+<div class="contextual">
+    <%= watcher_link(@topic, User.current) %>
+    <%= link_to(
+          l(:button_quote),
+          {:action => 'quote', :id => @topic},
+          :remote => true,
+          :method => 'get',
+          :class => 'icon icon-comment',
+          :remote => true) if !@topic.locked? && authorize_for('messages', 'reply') %>
+    <%= link_to(
+          l(:button_edit),
+          {:action => 'edit', :id => @topic},
+          :class => 'icon icon-edit'
+        ) if @message.editable_by?(User.current) %>
+    <%= link_to(
+          l(:button_delete),
+          {:action => 'destroy', :id => @topic},
+          :method => :post,
+          :data => {:confirm => l(:text_are_you_sure)},
+          :class => 'icon icon-del'
+         ) if @message.destroyable_by?(User.current) %>
+</div>
+
+<h2><%= avatar(@topic.author, :size => "24") %><%=h @topic.subject %></h2>
+
+<div class="message">
+<p><span class="author"><%= authoring @topic.created_on, @topic.author %></span></p>
+<div class="wiki">
+<%= textilizable(@topic, :content) %>
+</div>
+<%= link_to_attachments @topic, :author => false %>
+</div>
+<br />
+
+<% unless @replies.empty? %>
+<h3 class="comments"><%= l(:label_reply_plural) %> (<%= @reply_count %>)</h3>
+<% @replies.each do |message| %>
+  <div class="message reply" id="<%= "message-#{message.id}" %>">
+    <div class="contextual">
+      <%= link_to(
+            image_tag('comment.png'),
+            {:action => 'quote', :id => message},
+            :remote => true,
+            :method => 'get',
+            :title => l(:button_quote)) if !@topic.locked? && authorize_for('messages', 'reply') %>
+      <%= link_to(
+            image_tag('edit.png'),
+            {:action => 'edit', :id => message},
+            :title => l(:button_edit)
+          ) if message.editable_by?(User.current) %>
+      <%= link_to(
+            image_tag('delete.png'),
+            {:action => 'destroy', :id => message},
+            :method => :post,
+            :data => {:confirm => l(:text_are_you_sure)},
+            :title => l(:button_delete)
+          ) if message.destroyable_by?(User.current) %>
+    </div>
+  <h4>
+    <%= avatar(message.author, :size => "24") %>
+    <%= link_to h(message.subject), { :controller => 'messages', :action => 'show', :board_id => @board, :id => @topic, :r => message, :anchor => "message-#{message.id}" } %>
+    -
+    <%= authoring message.created_on, message.author %>
+  </h4>
+  <div class="wiki"><%= textilizable message, :content, :attachments => message.attachments %></div>
+  <%= link_to_attachments message, :author => false %>
+  </div>
+<% end %>
+<p class="pagination"><%= pagination_links_full @reply_pages, @reply_count, :per_page_links => false %></p>
+<% end %>
+
+<% if !@topic.locked? && authorize_for('messages', 'reply') %>
+<p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p>
+<div id="reply" style="display:none;">
+<%= form_for @reply, :as => :reply, :url => {:action => 'reply', :id => @topic}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
+  <%= render :partial => 'form', :locals => {:f => f, :replying => true} %>
+  <%= submit_tag l(:button_submit) %>
+  <%= preview_link({:controller => 'messages', :action => 'preview', :board_id => @board}, 'message-form') %>
+<% end %>
+<div id="preview" class="wiki"></div>
+</div>
+<% end %>
+
+<% html_title @topic.subject %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/db/dbc74bfb5d695fe0fd5ec63c1a42442c480292e2.svn-base
--- /dev/null
+++ b/.svn/pristine/db/dbc74bfb5d695fe0fd5ec63c1a42442c480292e2.svn-base
@@ -0,0 +1,168 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AuthSourcesControllerTest < ActionController::TestCase
+  fixtures :users, :auth_sources
+
+  def setup
+    @request.session[:user_id] = 1
+  end
+
+  def test_index
+    get :index
+
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:auth_sources)
+  end
+
+  def test_new
+    get :new
+
+    assert_response :success
+    assert_template 'new'
+
+    source = assigns(:auth_source)
+    assert_equal AuthSourceLdap, source.class
+    assert source.new_record?
+
+    assert_select 'form#auth_source_form' do
+      assert_select 'input[name=type][value=AuthSourceLdap]'
+      assert_select 'input[name=?]', 'auth_source[host]'
+    end
+  end
+
+  def test_new_with_invalid_type_should_respond_with_404
+    get :new, :type => 'foo'
+    assert_response 404
+  end
+
+  def test_create
+    assert_difference 'AuthSourceLdap.count' do
+      post :create, :type => 'AuthSourceLdap', :auth_source => {:name => 'Test', :host => '127.0.0.1', :port => '389', :attr_login => 'cn'}
+      assert_redirected_to '/auth_sources'
+    end
+
+    source = AuthSourceLdap.order('id DESC').first
+    assert_equal 'Test', source.name
+    assert_equal '127.0.0.1', source.host
+    assert_equal 389, source.port
+    assert_equal 'cn', source.attr_login
+  end
+
+  def test_create_with_failure
+    assert_no_difference 'AuthSourceLdap.count' do
+      post :create, :type => 'AuthSourceLdap', :auth_source => {:name => 'Test', :host => '', :port => '389', :attr_login => 'cn'}
+      assert_response :success
+      assert_template 'new'
+    end
+    assert_error_tag :content => /host can&#x27;t be blank/i
+  end
+
+  def test_edit
+    get :edit, :id => 1
+
+    assert_response :success
+    assert_template 'edit'
+
+    assert_select 'form#auth_source_form' do
+      assert_select 'input[name=?]', 'auth_source[host]'
+    end
+  end
+
+  def test_edit_should_not_contain_password
+    AuthSource.find(1).update_column :account_password, 'secret'
+
+    get :edit, :id => 1
+    assert_response :success
+    assert_select 'input[value=secret]', 0
+    assert_select 'input[name=dummy_password][value=?]', /x+/
+  end
+
+  def test_edit_invalid_should_respond_with_404
+    get :edit, :id => 99
+    assert_response 404
+  end
+
+  def test_update
+    put :update, :id => 1, :auth_source => {:name => 'Renamed', :host => '192.168.0.10', :port => '389', :attr_login => 'uid'}
+    assert_redirected_to '/auth_sources'
+
+    source = AuthSourceLdap.find(1)
+    assert_equal 'Renamed', source.name
+    assert_equal '192.168.0.10', source.host
+  end
+
+  def test_update_with_failure
+    put :update, :id => 1, :auth_source => {:name => 'Renamed', :host => '', :port => '389', :attr_login => 'uid'}
+    assert_response :success
+    assert_template 'edit'
+    assert_error_tag :content => /host can&#x27;t be blank/i
+  end
+
+  def test_destroy
+    assert_difference 'AuthSourceLdap.count', -1 do
+      delete :destroy, :id => 1
+      assert_redirected_to '/auth_sources'
+    end
+  end
+
+  def test_destroy_auth_source_in_use
+    User.find(2).update_attribute :auth_source_id, 1
+
+    assert_no_difference 'AuthSourceLdap.count' do
+      delete :destroy, :id => 1
+      assert_redirected_to '/auth_sources'
+    end
+  end
+
+  def test_test_connection
+    AuthSourceLdap.any_instance.stubs(:test_connection).returns(true)
+
+    get :test_connection, :id => 1
+    assert_redirected_to '/auth_sources'
+    assert_not_nil flash[:notice]
+    assert_match /successful/i, flash[:notice]
+  end
+
+  def test_test_connection_with_failure
+    AuthSourceLdap.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError.new("Something went wrong"))
+
+    get :test_connection, :id => 1
+    assert_redirected_to '/auth_sources'
+    assert_not_nil flash[:error]
+    assert_include 'Something went wrong', flash[:error]
+  end
+
+  def test_autocomplete_for_new_user
+    AuthSource.expects(:search).with('foo').returns([
+      {:login => 'foo1', :firstname => 'John', :lastname => 'Smith', :mail => 'foo1@example.net', :auth_source_id => 1},
+      {:login => 'Smith', :firstname => 'John', :lastname => 'Doe', :mail => 'foo2@example.net', :auth_source_id => 1}
+    ])
+
+    get :autocomplete_for_new_user, :term => 'foo'
+    assert_response :success
+    assert_equal 'application/json', response.content_type
+    json = ActiveSupport::JSON.decode(response.body)
+    assert_kind_of Array, json
+    assert_equal 2, json.size
+    assert_equal 'foo1', json.first['value']
+    assert_equal 'foo1 (John Smith)', json.first['label']
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dc/dc231e8a382bad8f57c4f1f8d58c2fe3cb3a5e5d.svn-base
--- a/.svn/pristine/dc/dc231e8a382bad8f57c4f1f8d58c2fe3cb3a5e5d.svn-base
+++ /dev/null
@@ -1,36 +0,0 @@
-Installing gems for testing
-===========================
-
-Run `rake gems RAILS_ENV=test` to list the required gems.  Run 
-`rake gems:install RAILS_ENV=test` to install any missing gems.
-
-Running Tests
-=============
-
-Run `rake --tasks test` to see available tests.
-`rake test` will run the entire testsuite.
-You can run `ruby test/unit/issue_test.rb` for an each test.
-
-Before running tests, you need to configure both development
-and test databases.
-
-Creating test repositories
-===================
-
-Redmine supports a wide array of different version control systems.
-To test the support, a test repository needs to be created for each of those.
-
-Run `rake --tasks test:scm:setup` for a list of available test-repositories or
-run `rake test:scm:setup:all` to set up all of them
-
-Creating a test ldap database
-=============================
-
-Redmine supports using LDAP for user authentications.  To test LDAP
-with Redmine, load the LDAP export from test/fixtures/ldap/test-ldap.ldif
-into a testing LDAP server.  Test that the ldap server can be accessed
-at 127.0.0.1 on port 389.
-
-Setting up the test ldap server is beyond the scope of this documentation.
-The OpenLDAP project provides a simple LDAP implementation that should work
-good as a test server.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dc/dc4a8b889fb60778bdec8c2aea4b6206a1ffbc41.svn-base
--- /dev/null
+++ b/.svn/pristine/dc/dc4a8b889fb60778bdec8c2aea4b6206a1ffbc41.svn-base
@@ -0,0 +1,89 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoryFilesystemTest < ActiveSupport::TestCase
+  fixtures :projects
+
+  include Redmine::I18n
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/filesystem_repository').to_s
+
+  def setup
+    @project = Project.find(3)
+    Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
+    @repository = Repository::Filesystem.create(
+                               :project => @project,
+                               :url     => REPOSITORY_PATH
+                                 )
+    assert @repository
+  end
+
+  def test_blank_root_directory_error_message
+    set_language_if_valid 'en'
+    repo = Repository::Filesystem.new(
+                          :project      => @project,
+                          :identifier   => 'test'
+                        )
+    assert !repo.save
+    assert_include "Root directory can't be blank",
+                   repo.errors.full_messages
+  end
+
+  def test_blank_root_directory_error_message_fr
+    set_language_if_valid 'fr'
+    str = "R\xc3\xa9pertoire racine doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    repo = Repository::Filesystem.new(
+                          :project      => @project,
+                          :url          => "",
+                          :identifier   => 'test',
+                          :path_encoding => ''
+                        )
+    assert !repo.save
+    assert_include str, repo.errors.full_messages
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    def test_fetch_changesets
+      assert_equal 0, @repository.changesets.count
+      assert_equal 0, @repository.filechanges.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal 0, @repository.changesets.count
+      assert_equal 0, @repository.filechanges.count
+    end
+
+    def test_entries
+      entries = @repository.entries("", 2)
+      assert_kind_of Redmine::Scm::Adapters::Entries, entries
+      assert_equal 3, entries.size
+    end
+
+    def test_entries_in_directory
+      assert_equal 2, @repository.entries("dir", 3).size
+    end
+
+    def test_cat
+      assert_equal "TEST CAT\n", @repository.scm.cat("test")
+    end
+  else
+    puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dc/dc4adf759d88394a5073997f3ad66185b26b8013.svn-base
--- a/.svn/pristine/dc/dc4adf759d88394a5073997f3ad66185b26b8013.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-// ** I18N
-
-// Calendar HR language
-// Author: Helix d.o.o., <info@helix.hr>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Nedjelja",
- "Ponedjeljak",
- "Utorak",
- "Srijeda",
- "Cetvrtak",
- "Petak",
- "Subota",
- "Nedjelja");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Ned",
- "Pon",
- "Uto",
- "Sri",
- "Cet",
- "Pet",
- "Sub",
- "Ned");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("Sijecanj",
- "Veljaca",
- "OÅ¾ujak",
- "Travanj",
- "Svibanj",
- "Lipanj",
- "Srpanj",
- "Kolovoz",
- "Rujan",
- "Listopad",
- "Studeni",
- "Prosinac");
-
-// short month names
-Calendar._SMN = new Array
-("Sij",
- "Velj",
- "OÅ¾u",
- "Tra",
- "Svi",
- "Lip",
- "Srp",
- "Kol",
- "Ruj",
- "List",
- "Stu",
- "Pro");
-
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "About the calendar";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "Prethodna godina (hold for menu)";
-Calendar._TT["PREV_MONTH"] = "Prethodni mjesec (hold for menu)";
-Calendar._TT["GO_TODAY"] = "Na danaÅ¡nji dan";
-Calendar._TT["NEXT_MONTH"] = "Naredni mjesec (hold for menu)";
-Calendar._TT["NEXT_YEAR"] = "Naredna godina (hold for menu)";
-Calendar._TT["SEL_DATE"] = "Odaberite datum";
-Calendar._TT["DRAG_TO_MOVE"] = "Drag to move";
-Calendar._TT["PART_TODAY"] = " (Danas)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "PrikaÅ¾i %s prvo";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Zatvori";
-Calendar._TT["TODAY"] = "Danas";
-Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Vrijeme:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dc/dc67b5d95ecc47650b97552f261cf812282703c9.svn-base
--- /dev/null
+++ b/.svn/pristine/dc/dc67b5d95ecc47650b97552f261cf812282703c9.svn-base
@@ -0,0 +1,1070 @@
+nl:
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d-%m-%Y"
+      short: "%e %b"
+      long: "%d %B, %Y"
+
+    day_names: [zondag, maandag, dinsdag, woensdag, donderdag, vrijdag, zaterdag]
+    abbr_day_names: [zo, ma, di, wo, do, vr, za]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, januari, februari, maart, april, mei, juni, juli, augustus, september, oktober, november, december]
+    abbr_month_names: [~, jan, feb, mar, apr, mei, jun, jul, aug, sep, okt, nov, dec]
+    # Used in date_select and datime_select.
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a, %d %b %Y %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%e %b %H:%M"
+      long: "%d %B, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "halve minuut"
+      less_than_x_seconds:
+        one:   "minder dan een seconde"
+        other: "minder dan %{count} seconden"
+      x_seconds:
+        one:   "1 seconde"
+        other: "%{count} seconden"
+      less_than_x_minutes:
+        one:   "minder dan een minuut"
+        other: "minder dan %{count} minuten"
+      x_minutes:
+        one:   "1 minuut"
+        other: "%{count} minuten"
+      about_x_hours:
+        one:   "ongeveer 1 uur"
+        other: "ongeveer %{count} uren"
+      x_hours:
+        one:   "1 uur"
+        other: "%{count} uren"
+      x_days:
+        one:   "1 dag"
+        other: "%{count} dagen"
+      about_x_months:
+        one:   "ongeveer 1 maand"
+        other: "ongeveer %{count} maanden"
+      x_months:
+        one:   "1 maand"
+        other: "%{count} maanden"
+      about_x_years:
+        one:   "ongeveer 1 jaar"
+        other: "ongeveer %{count} jaar"
+      over_x_years:
+        one:   "meer dan 1 jaar"
+        other: "meer dan %{count} jaar"
+      almost_x_years:
+        one:   "bijna 1 jaar"
+        other: "bijna %{count} jaar"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        precision: 3
+        delimiter: ""
+      storage_units:
+        format: "%n %u"
+        units:
+          kb: KB
+          tb: TB
+          gb: GB
+          byte:
+            one: Byte
+            other: Bytes
+          mb: MB
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "en"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "Door een fout kon dit %{model} niet worden opgeslagen"
+          other:  "Door %{count} fouten kon dit %{model} niet worden opgeslagen"
+      messages:
+        inclusion: "staat niet in de lijst"
+        exclusion: "is gereserveerd"
+        invalid: "is ongeldig"
+        confirmation: "komt niet overeen met bevestiging"
+        accepted: "moet geaccepteerd worden"
+        empty: "mag niet leeg zijn"
+        blank: "mag niet blanco zijn"
+        too_long: "is te lang"
+        too_short: "is te kort"
+        wrong_length: "heeft een onjuiste lengte"
+        taken: "is al in gebruik"
+        not_a_number: "is geen getal"
+        not_a_date: "is geen valide datum"
+        greater_than: "moet groter zijn dan %{count}"
+        greater_than_or_equal_to: "moet groter zijn of gelijk zijn aan %{count}"
+        equal_to: "moet gelijk zijn aan %{count}"
+        less_than: "moet minder zijn dan %{count}"
+        less_than_or_equal_to: "moet minder dan of gelijk zijn aan %{count}"
+        odd: "moet oneven zijn"
+        even: "moet even zijn"
+        greater_than_start_date: "moet na de startdatum liggen"
+        not_same_project: "hoort niet bij hetzelfde project"
+        circular_dependency: "Deze relatie zou een circulaire afhankelijkheid tot gevolg hebben"
+        cant_link_an_issue_with_a_descendant: "Een issue kan niet gelinked worden met een subtask"
+
+  actionview_instancetag_blank_option: Selecteer
+
+  button_activate: Activeer
+  button_add: Voeg toe
+  button_annotate: Annoteer
+  button_apply: Pas toe
+  button_archive: Archiveer
+  button_back: Terug
+  button_cancel: Annuleer
+  button_change: Wijzig
+  button_change_password: Wijzig wachtwoord
+  button_check_all: Selecteer alle
+  button_clear: Leeg maken
+  button_configure: Configureer
+  button_copy: KopiÃ«er
+  button_create: Maak
+  button_delete: Verwijder
+  button_download: Download
+  button_edit: Bewerk
+  button_list: Lijst
+  button_lock: Sluit
+  button_log_time: Registreer tijd
+  button_login: Inloggen
+  button_move: Verplaatsen
+  button_quote: Citaat
+  button_rename: Hernoemen
+  button_reply: Antwoord
+  button_reset: Reset
+  button_rollback: Rollback naar deze versie
+  button_save: Bewaren
+  button_sort: Sorteer
+  button_submit: Toevoegen
+  button_test: Test
+  button_unarchive: Dearchiveer
+  button_uncheck_all: Deselecteer alle
+  button_unlock: Open
+  button_unwatch: Niet meer monitoren
+  button_update: Update
+  button_view: Bekijken
+  button_watch: Monitor
+  default_activity_design: Ontwerp
+  default_activity_development: Ontwikkeling
+  default_doc_category_tech: Technische documentatie
+  default_doc_category_user: Gebruikersdocumentatie
+  default_issue_status_in_progress: In Progress
+  default_issue_status_closed: Gesloten
+  default_issue_status_feedback: Terugkoppeling
+  default_issue_status_new: Nieuw
+  default_issue_status_rejected: Afgewezen
+  default_issue_status_resolved: Opgelost
+  default_priority_high: Hoog
+  default_priority_immediate: Onmiddellijk
+  default_priority_low: Laag
+  default_priority_normal: Normaal
+  default_priority_urgent: Spoed
+  default_role_developer: Ontwikkelaar
+  default_role_manager: Manager
+  default_role_reporter: Rapporteur
+  default_tracker_bug: Bug
+  default_tracker_feature: Feature
+  default_tracker_support: Support
+  enumeration_activities: Activiteiten (tijdtracking)
+  enumeration_doc_categories: DocumentcategorieÃ«n
+  enumeration_issue_priorities: Issueprioriteiten
+  error_can_t_load_default_data: "De standaard configuratie kon niet worden geladen: %{value}"
+  error_issue_not_found_in_project: 'Deze issue is niet gevonden of behoort niet toe tot dit project.'
+  error_scm_annotate: "Er kan geen commentaar toegevoegd worden."
+  error_scm_command_failed: "Er trad een fout op tijdens de poging om verbinding te maken met de repository: %{value}"
+  error_scm_not_found: "Deze ingang of revisie bestaat niet in de repository."
+  field_account: Account
+  field_activity: Activiteit
+  field_admin: Beheerder
+  field_assignable: Issues kunnen toegewezen worden aan deze rol
+  field_assigned_to: Toegewezen aan
+  field_attr_firstname: Voornaam attribuut
+  field_attr_lastname: Achternaam attribuut
+  field_attr_login: Login attribuut
+  field_attr_mail: E-mail attribuut
+  field_auth_source: Authenticatiemethode
+  field_author: Auteur
+  field_base_dn: Base DN
+  field_category: Categorie
+  field_column_names: Kolommen
+  field_comments: Commentaar
+  field_comments_sorting: Commentaar weergeven
+  field_created_on: Aangemaakt
+  field_default_value: Standaardwaarde
+  field_delay: Vertraging
+  field_description: Beschrijving
+  field_done_ratio: "% Gereed"
+  field_downloads: Downloads
+  field_due_date: Verwachte datum gereed
+  field_effective_date: Datum
+  field_estimated_hours: Geschatte tijd
+  field_field_format: Formaat
+  field_filename: Bestand
+  field_filesize: Grootte
+  field_firstname: Voornaam
+  field_fixed_version: Versie
+  field_hide_mail: Verberg mijn e-mailadres
+  field_homepage: Homepage
+  field_host: Host
+  field_hours: Uren
+  field_identifier: Identificatiecode
+  field_is_closed: Issue gesloten
+  field_is_default: Standaard
+  field_is_filter: Gebruikt als een filter
+  field_is_for_all: Voor alle projecten
+  field_is_in_roadmap: Issues weergegeven in roadmap
+  field_is_public: Publiek
+  field_is_required: Verplicht
+  field_issue: Issue
+  field_issue_to: Gerelateerd issue
+  field_language: Taal
+  field_last_login_on: Laatste bezoek
+  field_lastname: Achternaam
+  field_login: Gebruikersnaam
+  field_mail: E-mail
+  field_mail_notification: Mail notificaties
+  field_max_length: Maximale lengte
+  field_min_length: Minimale lengte
+  field_name: Naam
+  field_new_password: Nieuw wachtwoord
+  field_notes: Notities
+  field_onthefly: On-the-fly aanmaken van een gebruiker
+  field_parent: Subproject van
+  field_parent_title: Bovenliggende pagina
+  field_password: Wachtwoord
+  field_password_confirmation: Bevestig wachtwoord
+  field_port: Port
+  field_possible_values: Mogelijke waarden
+  field_priority: Prioriteit
+  field_project: Project
+  field_redirect_existing_links: Verwijs bestaande links door
+  field_regexp: Reguliere expressie
+  field_role: Rol
+  field_searchable: Doorzoekbaar
+  field_spent_on: Datum
+  field_start_date: Startdatum
+  field_start_page: Startpagina
+  field_status: Status
+  field_subject: Onderwerp
+  field_subproject: Subproject
+  field_summary: Samenvatting
+  field_time_zone: Tijdzone
+  field_title: Titel
+  field_tracker: Tracker
+  field_type: Type
+  field_updated_on: Gewijzigd
+  field_url: URL
+  field_user: Gebruiker
+  field_value: Waarde
+  field_version: Versie
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-1
+  general_csv_separator: ';'
+  general_first_day_of_week: '7'
+  general_lang_name: 'Nederlands'
+  general_pdf_encoding: UTF-8
+  general_text_No: 'Nee'
+  general_text_Yes: 'Ja'
+  general_text_no: 'nee'
+  general_text_yes: 'ja'
+  label_activity: Activiteit
+  label_add_another_file: Ander bestand toevoegen
+  label_add_note: Voeg een notitie toe
+  label_added: toegevoegd
+  label_added_time_by: "Toegevoegd door %{author} %{age} geleden"
+  label_administration: Administratie
+  label_age: Leeftijd
+  label_ago: dagen geleden
+  label_all: alle
+  label_all_time: alles
+  label_all_words: Alle woorden
+  label_and_its_subprojects: "%{value} en zijn subprojecten."
+  label_applied_status: Toegekende status
+  label_assigned_to_me_issues: Aan mij toegewezen issues
+  label_associated_revisions: GeassociÃ«erde revisies
+  label_attachment: Bestand
+  label_attachment_delete: Verwijder bestand
+  label_attachment_new: Nieuw bestand
+  label_attachment_plural: Bestanden
+  label_attribute: Attribuut
+  label_attribute_plural: Attributen
+  label_auth_source: Authenticatiemodus
+  label_auth_source_new: Nieuwe authenticatiemodus
+  label_auth_source_plural: Authenticatiemodi
+  label_authentication: Authenticatie
+  label_blocked_by: geblokkeerd door
+  label_blocks: blokkeert
+  label_board: Forum
+  label_board_new: Nieuw forum
+  label_board_plural: Forums
+  label_boolean: Boolean
+  label_browse: Blader
+  label_bulk_edit_selected_issues: Bewerk geselecteerde issues in bulk
+  label_calendar: Kalender
+  label_change_plural: Wijzigingen
+  label_change_properties: Eigenschappen wijzigen
+  label_change_status: Wijzig status
+  label_change_view_all: Bekijk alle wijzigingen
+  label_changes_details: Details van alle wijzigingen
+  label_changeset_plural: Changesets
+  label_chronological_order: In chronologische volgorde
+  label_closed_issues: gesloten
+  label_closed_issues_plural: gesloten
+  label_x_open_issues_abbr_on_total:
+    zero:  0 open / %{total}
+    one:   1 open / %{total}
+    other: "%{count} open / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 open
+    one:   1 open
+    other: "%{count} open"
+  label_x_closed_issues_abbr:
+    zero:  0 gesloten
+    one:   1 gesloten
+    other: "%{count} gesloten"
+  label_comment: Commentaar
+  label_comment_add: Voeg commentaar toe
+  label_comment_added: Commentaar toegevoegd
+  label_comment_delete: Verwijder commentaar
+  label_comment_plural: Commentaar
+  label_x_comments:
+    zero: geen commentaar
+    one: 1x commentaar
+    other: "%{count}x commentaar"
+  label_commits_per_author: Commits per auteur
+  label_commits_per_month: Commits per maand
+  label_confirmation: Bevestiging
+  label_contains: bevat
+  label_copied: gekopieerd
+  label_copy_workflow_from: Kopieer workflow van
+  label_current_status: Huidige status
+  label_current_version: Huidige versie
+  label_custom_field: Specifiek veld
+  label_custom_field_new: Nieuw specifiek veld
+  label_custom_field_plural: Specifieke velden
+  label_date: Datum
+  label_date_from: Van
+  label_date_range: Datumbereik
+  label_date_to: Tot
+  label_day_plural: dagen
+  label_default: Standaard
+  label_default_columns: Standaard kolommen.
+  label_deleted: verwijderd
+  label_details: Details
+  label_diff_inline: inline
+  label_diff_side_by_side: naast elkaar
+  label_disabled: uitgeschakeld
+  label_display_per_page: "Per pagina: %{value}"
+  label_document: Document
+  label_document_added: Document toegevoegd
+  label_document_new: Nieuw document
+  label_document_plural: Documenten
+  label_downloads_abbr: D/L
+  label_duplicated_by: gedupliceerd door
+  label_duplicates: dupliceert
+  label_end_to_end: eind tot eind
+  label_end_to_start: eind tot start
+  label_enumeration_new: Nieuwe waarde
+  label_enumerations: Enumeraties
+  label_environment: Omgeving
+  label_equals: is gelijk
+  label_example: Voorbeeld
+  label_export_to: Exporteer naar
+  label_f_hour: "%{value} uur"
+  label_f_hour_plural: "%{value} uren"
+  label_feed_plural: Feeds
+  label_feeds_access_key_created_on: "RSS toegangssleutel %{value} geleden gemaakt."
+  label_file_added: Bestand toegevoegd
+  label_file_plural: Bestanden
+  label_filter_add: Voeg filter toe
+  label_filter_plural: Filters
+  label_float: Float
+  label_follows: volgt op
+  label_gantt: Gantt
+  label_general: Algemeen
+  label_generate_key: Genereer een sleutel
+  label_help: Help
+  label_history: Geschiedenis
+  label_home: Home
+  label_in: in
+  label_in_less_than: in minder dan
+  label_in_more_than: in meer dan
+  label_incoming_emails: Inkomende e-mail
+  label_index_by_date: Indexeer op datum
+  label_index_by_title: Indexeer op titel
+  label_information: Informatie
+  label_information_plural: Informatie
+  label_integer: Integer
+  label_internal: Intern
+  label_issue: Incident
+  label_issue_added: Incident toegevoegd
+  label_issue_category: Incident categorie
+  label_issue_category_new: Nieuwe categorie
+  label_issue_category_plural: IssuecategorieÃ«n
+  label_issue_new: Nieuw incident
+  label_issue_plural: Incidenten
+  label_issue_status: Incident status
+  label_issue_status_new: Nieuwe status
+  label_issue_status_plural: Incident statussen
+  label_issue_tracking: Incident-tracking
+  label_issue_updated: Incident bijgewerkt
+  label_issue_view_all: Bekijk alle incidenten
+  label_issue_watchers: Monitoren
+  label_issues_by: "Issues door %{value}"
+  label_jump_to_a_project: Ga naar een project...
+  label_language_based: Taal gebaseerd
+  label_last_changes: "laatste %{count} wijzigingen"
+  label_last_login: Laatste bezoek
+  label_last_month: laatste maand
+  label_last_n_days: "%{count} dagen geleden"
+  label_last_week: vorige week
+  label_latest_revision: Meest recente revisie
+  label_latest_revision_plural: Meest recente revisies
+  label_ldap_authentication: LDAP authenticatie
+  label_less_than_ago: minder dan x dagen geleden
+  label_list: Lijst
+  label_loading: Laden...
+  label_logged_as: Ingelogd als
+  label_login: Inloggen
+  label_logout: Uitloggen
+  label_max_size: Maximumgrootte
+  label_me: mij
+  label_member: Lid
+  label_member_new: Nieuw lid
+  label_member_plural: Leden
+  label_message_last: Laatste bericht
+  label_message_new: Nieuw bericht
+  label_message_plural: Berichten
+  label_message_posted: Bericht toegevoegd
+  label_min_max_length: Min-max lengte
+  label_modified: gewijzigd
+  label_module_plural: Modules
+  label_month: Maand
+  label_months_from: maanden vanaf
+  label_more: Meer
+  label_more_than_ago: meer dan x dagen geleden
+  label_my_account: Mijn account
+  label_my_page: Mijn pagina
+  label_my_projects: Mijn projecten
+  label_new: Nieuw
+  label_new_statuses_allowed: Nieuwe toegestane statussen
+  label_news: Nieuws
+  label_news_added: Nieuws toegevoegd
+  label_news_latest: Laatste nieuws
+  label_news_new: Voeg nieuws toe
+  label_news_plural: Nieuws
+  label_news_view_all: Bekijk al het nieuws
+  label_next: Volgende
+  label_no_change_option: (Geen wijziging)
+  label_no_data: Geen gegevens om te tonen
+  label_nobody: niemand
+  label_none: geen
+  label_not_contains: bevat niet
+  label_not_equals: is niet gelijk
+  label_open_issues: open
+  label_open_issues_plural: open
+  label_optional_description: Optionele beschrijving
+  label_options: Opties
+  label_overall_activity: Activiteit
+  label_overview: Overzicht
+  label_password_lost: Wachtwoord verloren
+  label_per_page: Per pagina
+  label_permissions: Permissies
+  label_permissions_report: Permissierapport
+  label_personalize_page: Personaliseer deze pagina
+  label_planning: Planning
+  label_please_login: Log a.u.b. in
+  label_plugins: Plugins
+  label_precedes: gaat vooraf aan
+  label_preferences: Voorkeuren
+  label_preview: Voorbeeldweergave
+  label_previous: Vorige
+  label_project: Project
+  label_project_all: Alle projecten
+  label_project_latest: Nieuwste projecten
+  label_project_new: Nieuw project
+  label_project_plural: Projecten
+  label_x_projects:
+    zero:  geen projecten
+    one:   1 project
+    other: "%{count} projecten"
+  label_public_projects: Publieke projecten
+  label_query: Eigen zoekopdracht
+  label_query_new: Nieuwe zoekopdracht
+  label_query_plural: Eigen zoekopdrachten
+  label_read: Lees...
+  label_register: Registreer
+  label_registered_on: Geregistreerd op
+  label_registration_activation_by_email: accountactivatie per e-mail
+  label_registration_automatic_activation: automatische accountactivatie
+  label_registration_manual_activation: handmatige accountactivatie
+  label_related_issues: Gerelateerde issues
+  label_relates_to: gerelateerd aan
+  label_relation_delete: Verwijder relatie
+  label_relation_new: Nieuwe relatie
+  label_renamed: hernoemd
+  label_reply_plural: Antwoorden
+  label_report: Rapport
+  label_report_plural: Rapporten
+  label_reported_issues: Gemelde issues
+  label_repository: Repository
+  label_repository_plural: Repositories
+  label_result_plural: Resultaten
+  label_reverse_chronological_order: In omgekeerde chronologische volgorde
+  label_revision: Revisie
+  label_revision_plural: Revisies
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "Voldaan in %{value}"
+  label_roadmap_no_issues: Geen issues voor deze versie
+  label_roadmap_overdue: "%{value} over tijd"
+  label_role: Rol
+  label_role_and_permissions: Rollen en permissies
+  label_role_new: Nieuwe rol
+  label_role_plural: Rollen
+  label_scm: SCM
+  label_search: Zoeken
+  label_search_titles_only: Enkel titels doorzoeken
+  label_send_information: Stuur accountinformatie naar de gebruiker
+  label_send_test_email: Stuur een test e-mail
+  label_settings: Instellingen
+  label_show_completed_versions: Toon afgeronde versies
+  label_sort_by: "Sorteer op %{value}"
+  label_sort_higher: Verplaats naar boven
+  label_sort_highest: Verplaats naar begin
+  label_sort_lower: Verplaats naar beneden
+  label_sort_lowest: Verplaats naar eind
+  label_spent_time: Gespendeerde tijd
+  label_start_to_end: start tot eind
+  label_start_to_start: start tot start
+  label_statistics: Statistieken
+  label_stay_logged_in: Blijf ingelogd
+  label_string: Tekst
+  label_subproject_plural: Subprojecten
+  label_text: Lange tekst
+  label_theme: Thema
+  label_this_month: deze maand
+  label_this_week: deze week
+  label_this_year: dit jaar
+  label_time_tracking: Tijdregistratie bijhouden
+  label_today: vandaag
+  label_topic_plural: Onderwerpen
+  label_total: Totaal
+  label_tracker: Tracker
+  label_tracker_new: Nieuwe tracker
+  label_tracker_plural: Trackers
+  label_updated_time: "%{value} geleden bijgewerkt"
+  label_updated_time_by: "%{age} geleden bijgewerkt door %{author}"
+  label_used_by: Gebruikt door
+  label_user: Gebruiker
+  label_user_activity: "%{value}'s activiteit"
+  label_user_mail_no_self_notified: Ik wil niet op de hoogte gehouden worden van mijn eigen wijzigingen
+  label_user_mail_option_all: "Bij elk gebeurtenis in al mijn projecten..."
+  label_user_mail_option_selected: "Enkel bij elke gebeurtenis op het geselecteerde project..."
+  label_user_new: Nieuwe gebruiker
+  label_user_plural: Gebruikers
+  label_version: Versie
+  label_version_new: Nieuwe versie
+  label_version_plural: Versies
+  label_view_diff: Bekijk verschillen
+  label_view_revisions: Bekijk revisies
+  label_watched_issues: Gemonitorde issues
+  label_week: Week
+  label_wiki: Wiki
+  label_wiki_edit: Wiki edit
+  label_wiki_edit_plural: Wiki edits
+  label_wiki_page: Wikipagina
+  label_wiki_page_plural: Wikipagina's
+  label_workflow: Workflow
+  label_year: Jaar
+  label_yesterday: gisteren
+  mail_body_account_activation_request: "Een nieuwe gebruiker (%{value}) is geregistreerd. Zijn account wacht op uw akkoord:"
+  mail_body_account_information: Uw account gegevens
+  mail_body_account_information_external: "U kunt uw account (%{value}) gebruiken om in te loggen."
+  mail_body_lost_password: 'Gebruik de volgende link om uw wachtwoord te wijzigen:'
+  mail_body_register: 'Gebruik de volgende link om uw account te activeren:'
+  mail_body_reminder: "%{count} issue(s) die aan u toegewezen zijn en voldaan moeten zijn in de komende %{days} dagen:"
+  mail_subject_account_activation_request: "%{value} accountactivatieverzoek"
+  mail_subject_lost_password: "uw %{value} wachtwoord"
+  mail_subject_register: "uw %{value} accountactivatie"
+  mail_subject_reminder: "%{count} issue(s) die voldaan moeten zijn in de komende %{days} dagen."
+  notice_account_activated: uw account is geactiveerd. u kunt nu inloggen.
+  notice_account_invalid_creditentials: Incorrecte gebruikersnaam of wachtwoord
+  notice_account_lost_email_sent: Er is een e-mail naar u verstuurd met instructies over het kiezen van een nieuw wachtwoord.
+  notice_account_password_updated: Wachtwoord is met succes gewijzigd
+  notice_account_pending: "Uw account is aangemaakt, maar wacht nog op goedkeuring van de beheerder."
+  notice_account_register_done: Account is met succes aangemaakt.
+  notice_account_unknown_email: Onbekende gebruiker.
+  notice_account_updated: Account is met succes gewijzigd
+  notice_account_wrong_password: Incorrect wachtwoord
+  notice_can_t_change_password: Dit account gebruikt een externe bron voor authenticatie. Het is niet mogelijk om het wachtwoord te veranderen.
+  notice_default_data_loaded: Standaard configuratie succesvol geladen.
+  notice_email_error: "Er is een fout opgetreden tijdens het versturen van (%{value})"
+  notice_email_sent: "Een e-mail werd verstuurd naar %{value}"
+  notice_failed_to_save_issues: "Fout bij bewaren van %{count} issue(s) (%{total} geselecteerd): %{ids}."
+  notice_feeds_access_key_reseted: Je RSS toegangssleutel werd gereset.
+  notice_file_not_found: De pagina die u probeerde te benaderen bestaat niet of is verwijderd.
+  notice_locking_conflict: De gegevens zijn gewijzigd door een andere gebruiker.
+  notice_no_issue_selected: "Er is geen issue geselecteerd. Selecteer de issue die u wilt bewerken."
+  notice_not_authorized: Het is u niet toegestaan deze pagina te raadplegen.
+  notice_successful_connection: Verbinding succesvol.
+  notice_successful_create: Succesvol aangemaakt.
+  notice_successful_delete: Succesvol verwijderd.
+  notice_successful_update: Wijzigen succesvol.
+  notice_unable_delete_version: Niet mogelijk om deze versie te verwijderen.
+  permission_add_issue_notes: Voeg notities toe
+  permission_add_issue_watchers: Voeg monitors toe
+  permission_add_issues: Voeg issues toe
+  permission_add_messages: Voeg berichten toe
+  permission_browse_repository: Repository doorbladeren
+  permission_comment_news: Nieuws commentaar geven
+  permission_commit_access: Commit toegang
+  permission_delete_issues: Issues verwijderen
+  permission_delete_messages: Berichten verwijderen
+  permission_delete_own_messages: Eigen berichten verwijderen
+  permission_delete_wiki_pages: Wiki pagina's verwijderen
+  permission_delete_wiki_pages_attachments: Bijlagen verwijderen
+  permission_edit_issue_notes: Notities bewerken
+  permission_edit_issues: Issues bewerken
+  permission_edit_messages: Berichten bewerken
+  permission_edit_own_issue_notes: Eigen notities bewerken
+  permission_edit_own_messages: Eigen berichten bewerken
+  permission_edit_own_time_entries: Eigen tijdlogboek bewerken
+  permission_edit_project: Project bewerken
+  permission_edit_time_entries: Tijdlogboek bewerken
+  permission_edit_wiki_pages: Wiki pagina's bewerken
+  permission_log_time: Gespendeerde tijd loggen
+  permission_manage_boards: Forums beheren
+  permission_manage_categories: Issue-categorieÃ«n beheren
+  permission_manage_files: Bestanden beheren
+  permission_manage_issue_relations: Issuerelaties beheren
+  permission_manage_members: Leden beheren
+  permission_manage_news: Nieuws beheren
+  permission_manage_public_queries: Publieke queries beheren
+  permission_manage_repository: Repository beheren
+  permission_manage_versions: Versiebeheer
+  permission_manage_wiki: Wikibeheer
+  permission_move_issues: Issues verplaatsen
+  permission_protect_wiki_pages: Wikipagina's beschermen
+  permission_rename_wiki_pages: Wikipagina's hernoemen
+  permission_save_queries: Queries opslaan
+  permission_select_project_modules: Project modules selecteren
+  permission_view_calendar: Kalender bekijken
+  permission_view_changesets: Changesets bekijken
+  permission_view_documents: Documenten bekijken
+  permission_view_files: Bestanden bekijken
+  permission_view_gantt: Gantt grafiek bekijken
+  permission_view_issue_watchers: Monitorlijst bekijken
+  permission_view_messages: Berichten bekijken
+  permission_view_time_entries: Gespendeerde tijd bekijken
+  permission_view_wiki_edits: Wikihistorie bekijken
+  permission_view_wiki_pages: Wikipagina's bekijken
+  project_module_boards: Forums
+  project_module_documents: Documenten
+  project_module_files: Bestanden
+  project_module_issue_tracking: Issue tracking
+  project_module_news: Nieuws
+  project_module_repository: Repository
+  project_module_time_tracking: Tijd tracking
+  project_module_wiki: Wiki
+  setting_activity_days_default: Aantal dagen getoond bij het tabblad "Activiteit"
+  setting_app_subtitle: Applicatieondertitel
+  setting_app_title: Applicatietitel
+  setting_attachment_max_size: Attachment max. grootte
+  setting_autofetch_changesets: Haal commits automatisch op
+  setting_autologin: Automatisch inloggen
+  setting_bcc_recipients: Blind carbon copy ontvangers (bcc)
+  setting_commit_fix_keywords: Gefixeerde trefwoorden
+  setting_commit_ref_keywords: Refererende trefwoorden
+  setting_cross_project_issue_relations: Sta cross-project issuerelaties toe
+  setting_date_format: Datumformaat
+  setting_default_language: Standaard taal
+  setting_default_projects_public: Nieuwe projecten zijn standaard publiek
+  setting_diff_max_lines_displayed: Max aantal diff regels weer te geven
+  setting_display_subprojects_issues: Standaard issues van subproject tonen
+  setting_emails_footer: E-mails voettekst
+  setting_enabled_scm: SCM ingeschakeld
+  setting_feeds_limit: Feedinhoudlimiet
+  setting_gravatar_enabled: Gebruik Gravatar gebruikersiconen
+  setting_host_name: Hostnaam
+  setting_issue_list_default_columns: Standaardkolommen getoond op de lijst met issues
+  setting_issues_export_limit: Max aantal te exporteren issues
+  setting_login_required: Authenticatie vereist
+  setting_mail_from: Afzender e-mail adres
+  setting_mail_handler_api_enabled: Schakel WS in voor inkomende mail.
+  setting_mail_handler_api_key: API sleutel
+  setting_per_page_options: Aantal objecten per pagina (opties)
+  setting_plain_text_mail: platte tekst (geen HTML)
+  setting_protocol: Protocol
+  setting_self_registration: Zelfregistratie toegestaan
+  setting_sequential_project_identifiers: Genereer sequentiÃ«le projectidentiteiten
+  setting_sys_api_enabled: Gebruik WS voor repository beheer
+  setting_text_formatting: Tekstformaat
+  setting_time_format: Tijd formaat
+  setting_user_format: Gebruikers weergaveformaat
+  setting_welcome_text: Welkomsttekst
+  setting_wiki_compression: Wikigeschiedenis comprimeren
+  status_active: actief
+  status_locked: vergrendeld
+  status_registered: geregistreerd
+  text_are_you_sure: Weet u het zeker?
+  text_assign_time_entries_to_project: Gerapporteerde uren toevoegen aan dit project
+  text_caracters_maximum: "%{count} van maximum aantal tekens."
+  text_caracters_minimum: "Moet minstens %{count} karakters lang zijn."
+  text_comma_separated: Meerdere waarden toegestaan (kommagescheiden).
+  text_default_administrator_account_changed: Standaard beheerderaccount gewijzigd
+  text_destroy_time_entries: Verwijder gerapporteerde uren
+  text_destroy_time_entries_question: "%{hours} uren werden gerapporteerd op de issue(s) die u wilde verwijderen. Wat wil u doen?"
+  text_diff_truncated: '... Deze diff werd afgekort omdat het de maximale weer te geven karakters overschreed.'
+  text_email_delivery_not_configured: "E-mailbezorging is niet geconfigureerd. Mededelingen zijn uitgeschakeld.\nConfigureer uw SMTP server in config/configuration.yml en herstart de applicatie om dit te activeren."
+  text_enumeration_category_reassign_to: 'Wijs de volgende waarde toe:'
+  text_enumeration_destroy_question: "%{count} objecten zijn toegewezen aan deze waarde."
+  text_file_repository_writable: Bestandsrepository beschrijfbaar
+  text_issue_added: "Issue %{id} is gerapporteerd (door %{author})."
+  text_issue_category_destroy_assignments: Verwijder toewijzingen aan deze categorie
+  text_issue_category_destroy_question: "Er zijn issues (%{count}) aan deze categorie toegewezen. Wat wilt u hiermee doen ?"
+  text_issue_category_reassign_to: Issues opnieuw toewijzen aan deze categorie
+  text_issue_updated: "Issue %{id} is gewijzigd (door %{author})."
+  text_issues_destroy_confirmation: 'Weet u zeker dat u deze issue(s) wil verwijderen?'
+  text_issues_ref_in_commit_messages: Opzoeken en aanpassen van issues in commitberichten
+  text_length_between: "Lengte tussen %{min} en %{max} tekens."
+  text_load_default_configuration: Laad de standaardconfiguratie
+  text_min_max_length_info: 0 betekent geen restrictie
+  text_no_configuration_data: "Rollen, trackers, issue statussen en workflows zijn nog niet geconfigureerd.\nHet is ten zeerste aangeraden om de standaard configuratie in te laden. U kunt deze aanpassen nadat deze is ingeladen."
+  text_plugin_assets_writable: Plugin assets directory beschrijfbaar
+  text_project_destroy_confirmation: Weet u zeker dat u dit project en alle gerelateerde gegevens wilt verwijderen?
+  text_project_identifier_info: 'Alleen kleine letter (a-z), cijfers, streepjes en liggende streepjes zijn toegestaan.<br />Eenmaal opgeslagen kan de identifier niet worden gewijzigd.'
+  text_reassign_time_entries: 'Gerapporteerde uren opnieuw toewijzen:'
+  text_regexp_info: bv. ^[A-Z0-9]+$
+  text_repository_usernames_mapping: "Koppel de Redminegebruikers aan gebruikers in de repository log.\nGebruikers met dezelfde Redmine en repository gebruikersnaam of email worden automatisch gekoppeld."
+  text_rmagick_available: RMagick beschikbaar (optioneel)
+  text_select_mail_notifications: Selecteer acties waarvoor mededelingen via mail moeten worden verstuurd.
+  text_select_project_modules: 'Selecteer de modules die u wilt gebruiken voor dit project:'
+  text_status_changed_by_changeset: "Toegepast in changeset %{value}."
+  text_subprojects_destroy_warning: "De subprojecten: %{value} zullen ook verwijderd worden."
+  text_tip_issue_begin_day: issue die op deze dag begint
+  text_tip_issue_begin_end_day: issue die op deze dag begint en eindigt
+  text_tip_issue_end_day: issue die op deze dag eindigt
+  text_tracker_no_workflow: Geen workflow gedefinieerd voor deze tracker
+  text_unallowed_characters: Niet toegestane tekens
+  text_user_mail_option: "Bij niet-geselecteerde projecten zult u enkel mededelingen ontvangen voor issues die u monitort of waar u bij betrokken bent (als auteur of toegewezen persoon)."
+  text_user_wrote: "%{value} schreef:"
+  text_wiki_destroy_confirmation: Weet u zeker dat u deze wiki en zijn inhoud wenst te verwijderen?
+  text_workflow_edit: Selecteer een rol en een tracker om de workflow te wijzigen
+  warning_attachments_not_saved: "%{count} bestand(en) konden niet opgeslagen worden."
+  button_create_and_continue: Maak en ga verder
+  text_custom_field_possible_values_info: 'Per lijn een waarde'
+  label_display: Toon
+  field_editable: Bewerkbaar
+  setting_repository_log_display_limit: Max aantal revisies zichbaar
+  setting_file_max_size_displayed: Max grootte van tekst bestanden inline zichtbaar
+  field_watcher: Watcher
+  setting_openid: Sta OpenID login en registratie toe
+  field_identity_url: OpenID URL
+  label_login_with_open_id_option: of login met je OpenID
+  field_content: Content
+  label_descending: Aflopend
+  label_sort: Sorteer
+  label_ascending: Oplopend
+  label_date_from_to: Van %{start} tot %{end}
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: Deze pagina heeft %{descendants} subpagina's en onderliggende pagina's?. Wat wilt u hiermee doen?
+  text_wiki_page_reassign_children: Alle subpagina's toewijzen aan deze hoofdpagina
+  text_wiki_page_nullify_children: Behoud subpagina's als hoofdpagina's
+  text_wiki_page_destroy_children: Verwijder alle subpagina's en onderliggende pagina's
+  setting_password_min_length: Minimum wachtwoord lengte
+  field_group_by: Groepeer resultaten per
+  mail_subject_wiki_content_updated: "'%{id}' wiki pagina is bijgewerkt"
+  label_wiki_content_added: Wiki pagina toegevoegd
+  mail_subject_wiki_content_added: "'%{id}' wiki pagina is toegevoegd"
+  mail_body_wiki_content_added: De '%{id}' wiki pagina is toegevoegd door %{author}.
+  label_wiki_content_updated: Wiki pagina bijgewerkt
+  mail_body_wiki_content_updated: De '%{id}' wiki pagina is bijgewerkt door %{author}.
+  permission_add_project: Maak project
+  setting_new_project_user_role_id: Rol van gebruiker die een project maakt
+  label_view_all_revisions: Bekijk alle revisies
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: Geen tracker is geassocieerd met dit project. Check de project instellingen.
+  error_no_default_issue_status: Geen standaard issue status ingesteld. Check de configuratie (Ga naar "Administratie -> Issue statussen").
+  text_journal_changed: "%{label} gewijzigd van %{old} naar %{new}"
+  text_journal_set_to: "%{label} gewijzigd naar %{value}"
+  text_journal_deleted: "%{label} verwijderd (%{old})"
+  label_group_plural: Groepen
+  label_group: Groep
+  label_group_new: Nieuwe groep
+  label_time_entry_plural: Bestede tijd
+  text_journal_added: "%{label} %{value} toegevoegd"
+  field_active: Actief
+  enumeration_system_activity: Systeem Activiteit
+  permission_delete_issue_watchers: Verwijder volgers
+  version_status_closed: gesloten
+  version_status_locked: vergrendeld
+  version_status_open: open
+  error_can_not_reopen_issue_on_closed_version: Een issue toegewezen aan een gesloten versie kan niet heropend worden
+  label_user_anonymous: Anoniem
+  button_move_and_follow: Verplaats en volg
+  setting_default_projects_modules: Standaard geactiveerde modules voor nieuwe projecten
+  setting_gravatar_default: Standaard Gravatar plaatje
+  field_sharing: Delen
+  label_version_sharing_hierarchy: Met project hiÃ«rarchie
+  label_version_sharing_system: Met alle projecten
+  label_version_sharing_descendants: Met subprojecten
+  label_version_sharing_tree: Met project boom
+  label_version_sharing_none: Niet gedeeld
+  error_can_not_archive_project: Dit project kan niet worden gearchiveerd
+  button_duplicate: Dupliceer
+  button_copy_and_follow: KopiÃ«er en volg
+  label_copy_source: Bron
+  setting_issue_done_ratio: Bereken issue percentage voldaan met
+  setting_issue_done_ratio_issue_status: Gebruik de issue status
+  error_issue_done_ratios_not_updated: Issue percentage voldaan niet geupdate.
+  error_workflow_copy_target: Selecteer tracker(s) en rol(len)
+  setting_issue_done_ratio_issue_field: Gebruik het issue veld
+  label_copy_same_as_target: Zelfde als doel
+  label_copy_target: Doel
+  notice_issue_done_ratios_updated: Issue percentage voldaan geupdate.
+  error_workflow_copy_source: Selecteer een bron tracker of rol
+  label_update_issue_done_ratios: Update issue percentage voldaan
+  setting_start_of_week: Week begint op
+  permission_view_issues: Bekijk Issues
+  label_display_used_statuses_only: Laat alleen statussen zien die gebruikt worden door deze tracker
+  label_revision_id: Revisie %{value}
+  label_api_access_key: API access key
+  label_api_access_key_created_on: API access key gemaakt %{value} geleden
+  label_feeds_access_key: RSS access key
+  notice_api_access_key_reseted: Uw API access key was gereset.
+  setting_rest_api_enabled: Activeer REST web service
+  label_missing_api_access_key: Geen API access key
+  label_missing_feeds_access_key: Geen RSS access key
+  button_show: Laat zien
+  text_line_separated: Meerdere waarden toegestaan (elke regel is een waarde).
+  setting_mail_handler_body_delimiters: Breek email verwerking af na een van deze regels
+  permission_add_subprojects: Maak subprojecten
+  label_subproject_new: Nieuw subproject
+  text_own_membership_delete_confirmation: |-
+    U staat op punt om sommige of alle van uw permissies te verwijderen en bent mogelijk niet meer toegestaan om dit project hierna te wijzigen.
+    Wilt u doorgaan?
+  label_close_versions: Sluit complete versies
+  label_board_sticky: Sticky
+  label_board_locked: Vergrendeld
+  permission_export_wiki_pages: Exporteer wiki pagina's
+  setting_cache_formatted_text: Cache opgemaakte tekst
+  permission_manage_project_activities: Beheer project activiteiten
+  error_unable_delete_issue_status: Verwijderen van issue status niet gelukt
+  label_profile: Profiel
+  permission_manage_subtasks: Beheer subtaken
+  field_parent_issue: Hoofdtaak
+  label_subtask_plural: Subtaken
+  label_project_copy_notifications: Stuur email notificaties voor de project kopie
+  error_can_not_delete_custom_field: Verwijderen niet mogelijk van custom field
+  error_unable_to_connect: Geen connectie (%{value})
+  error_can_not_remove_role: Deze rol is in gebruik en kan niet worden verwijderd.
+  error_can_not_delete_tracker: Deze tracker bevat nog issues en kan niet worden verwijderd.
+  field_principal: Hoofd
+  label_my_page_block: Mijn pagina block
+  notice_failed_to_save_members: "Niet gelukt om lid/leden op te slaan: %{errors}."
+  text_zoom_out: Zoom uit
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Verwijderen niet mogelijk van tijd log invoer.
+  label_overall_spent_time: Totaal bestede tijd
+  field_time_entries: Registreer tijd
+  project_module_gantt: Gantt
+  project_module_calendar: Kalender
+  button_edit_associated_wikipage: "Bewerk bijbehorende wiki pagina: %{page_title}"
+  field_text: Tekst veld
+  label_user_mail_option_only_owner: Alleen voor dingen waarvan ik de auteur ben
+  setting_default_notification_option: Standaard instelling voor mededelingen
+  label_user_mail_option_only_my_events: Alleen voor dingen die ik volg of bij betrokken ben
+  label_user_mail_option_only_assigned: Alleen voor dingen die aan mij zijn toegewezen
+  label_user_mail_option_none: Bij geen enkele gebeurtenis
+  field_member_of_group: Groep van toegewezene
+  field_assigned_to_role: Rol van toegewezene
+  notice_not_authorized_archived_project: Het project dat u wilt bezoeken is gearchiveerd.
+  label_principal_search: "Zoek naar gebruiker of groep:"
+  label_user_search: "Zoek naar gebruiker:"
+  field_visible: Zichtbaar
+  setting_commit_logtime_activity_id: Standaard activiteit voor tijdregistratie
+  text_time_logged_by_changeset: Toegepast in changeset %{value}.
+  setting_commit_logtime_enabled: Activeer tijdregistratie
+  notice_gantt_chart_truncated: De gantt chart is ingekort omdat het meer objecten bevat dan kan worden weergegeven, (%{max})
+  setting_gantt_items_limit: Max. aantal objecten op gantt chart
+  field_warn_on_leaving_unsaved: Waarschuw me wanneer ik een pagina verlaat waarvan de tekst niet opgeslagen is
+  text_warn_on_leaving_unsaved: De huidige pagina bevat tekst die niet is opgeslagen en dit zal verloren gaan als u deze pagina nu verlaat.
+  label_my_queries: Mijn aangepaste zoekopdrachten
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Commentaar toegevoegd aan een nieuwsitem
+  button_expand_all: Klap uit
+  button_collapse_all: Klap in
+  label_additional_workflow_transitions_for_assignee: Aanvullende veranderingen toegestaan wanneer de gebruiker de toegewezene is
+  label_additional_workflow_transitions_for_author: Aanvullende veranderingen toegestaan wanneer de gebruiker de auteur is
+  label_bulk_edit_selected_time_entries: Massa wijziging geselecteerd tijd-registraties?
+  text_time_entries_destroy_confirmation: Weet u zeker dat u de geselecteerde item(s) wilt verwijderen ?
+  label_role_anonymous: Anoniem
+  label_role_non_member: Geen lid
+  label_issue_note_added: Notitie toegevoegd
+  label_issue_status_updated: Status gewijzigd
+  label_issue_priority_updated: Prioriteit geupdate
+  label_issues_visibility_own: Probleem aangemaakt door of toegewezen aan
+  field_issues_visibility: Incidenten weergave
+  label_issues_visibility_all: Alle incidenten
+  permission_set_own_issues_private: Zet eigen incidenten publiekelijk of privÃ©
+  field_is_private: PrivÃ©
+  permission_set_issues_private: Zet incidenten publiekelijk of privÃ©
+  label_issues_visibility_public: Alle niet privÃ©-incidenten
+  text_issues_destroy_descendants_confirmation: Dit zal ook de %{count} subtaken verwijderen.
+  field_commit_logs_encoding: Encodering van commit berichten
+  field_scm_path_encoding: Pad encodering
+  text_scm_path_encoding_note: "Standaard: UTF-8"
+  field_path_to_repository: Pad naar versie overzicht
+  field_root_directory: Root directorie
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: "Lokale versie overzicht (Voorbeeld: /hgrepo, c:\\hgrepo)"
+  text_scm_command: Commando
+  text_scm_command_version: Versie
+  label_git_report_last_commit: Rapporteer laatste toevoegen voor bestanden en directories
+  text_scm_config: U kan de scm commando's configureren in config/configuration.yml. Herstart de applicatie na het wijzigen ervan.
+  text_scm_command_not_available: Scm commando is niet beschikbaar. Controleer de instellingen in het administratiepaneel.
+  notice_issue_successful_create: Probleem %{id} aangemaakt.
+  label_between: tussen
+  setting_issue_group_assignment: Sta groepstoewijzingen toe
+  label_diff: Verschil
+  text_git_repository_note: "Versie overzicht lokaal is leeg (Voorbeeld: /gitrepo, c:\\gitrepo)"
+  description_query_sort_criteria_direction: Sortering
+  description_project_scope: Zoek bereik
+  description_filter: Filter
+  description_user_mail_notification: Mail notificatie instellingen
+  description_date_from: Vul start datum in
+  description_message_content: Inhoud bericht
+  description_available_columns: Beschikbare kolommen
+  description_date_range_interval: Kies een bereik bij het selecteren van een start en eind datum
+  description_issue_category_reassign: Kies probleem categorie
+  description_search: Zoekveld
+  description_notes: Notities
+  description_date_range_list: Kies bereik vanuit de lijst
+  description_choose_project: Projecten
+  description_date_to: Vul eind datum in
+  description_query_sort_criteria_attribute: Sorteer attribuut
+  description_wiki_subpages_reassign: Kies nieuwe hoofdpagina
+  description_selected_columns: Geselecteerde kolommen
+  label_parent_revision: Hoofd
+  label_child_revision: Sub
+  error_scm_annotate_big_text_file: De vermelding kan niet worden geannoteerd, omdat het groter is dan de maximale toegewezen grootte.
+  setting_default_issue_start_date_to_creation_date: Gebruik huidige datum als start datum voor nieuwe incidenten.
+  button_edit_section: Wijzig deze sectie
+  setting_repositories_encodings: Bijlage en opgeslagen bestanden coderingen
+  description_all_columns: Alle kolommen
+  button_export: Exporteren
+  label_export_options: "%{export_format} export opties"
+  error_attachment_too_big: Dit bestand kan niet worden geupload omdat het de maximaal toegestane grootte overschrijd (%{max_size})
+  notice_failed_to_save_time_entries: "Opslaan gefaald voor %{count} tijdsnotatie(s) van %{total} geselecteerde: %{ids}."
+  label_x_issues:
+    zero:  0 incidenten
+    one:   1 incidenten
+    other: "%{count} incidenten"
+  label_repository_new: Nieuw repository
+  field_repository_is_default: Hoofd repository
+  label_copy_attachments: Copieer bijlage(n)
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Versies compleet
+  field_multiple: Meerdere waardes
+  setting_commit_cross_project_ref: Sta toe om incidenten van alle projecten te refereren en oplossen
+  text_issue_conflict_resolution_add_notes: Voeg mijn notities toe en annuleer andere wijzigingen
+  text_issue_conflict_resolution_overwrite: Voeg mijn wijzigingen alsnog toe (voorgaande notities worden bewaard, maar sommige kunnen overschreden worden)
+  notice_issue_update_conflict: Dit incident is reeds geupdate door een andere gebruiker terwijl jij bezig was
+  text_issue_conflict_resolution_cancel: Annuleer mijn wijzigingen en geef pagina opnieuw weer %{link}
+  permission_manage_related_issues: Beheer gerelateerde incidenten
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Zoek om monitoorders toe te voegen
+  notice_account_deleted: Uw account is permanent verwijderd
+  setting_unsubscribe: Sta gebruikers toe hun eigen account te verwijderen
+  button_delete_my_account: Verwijder mijn account
+  text_account_destroy_confirmation: |-
+    Weet u zeker dat u door wilt gaan?
+    Uw account wordt permanent verwijderd zonder mogelijkheid deze te heractiveren.
+  error_session_expired: Uw sessie is verlopen. U dient opnieuw in te loggen.
+  text_session_expiration_settings: "Waarschuwing: door deze instelling te wijzigen kan sessies laten verlopen inclusief de uwe"
+  setting_session_lifetime: Maximale sessieduur
+  setting_session_timeout: Sessie inactiviteit timeout
+  label_session_expiration: Sessie verlopen
+  permission_close_project: Sluit / heropen project
+  label_show_closed_projects: Gesloten projecten weergeven
+  button_close: Sluiten
+  button_reopen: Heropen
+  project_status_active: actief
+  project_status_closed: gesloten
+  project_status_archived: gearchiveerd
+  text_project_closed: Dit project is gesloten en op alleen-lezen
+  notice_user_successful_create: Gebruiker %{id} aangemaakt.
+  field_core_fields: Standaard verleden
+  field_timeout: Timeout (in seconden)
+  setting_thumbnails_enabled: Geef bijlage miniaturen weer
+  setting_thumbnails_size: Grootte miniaturen (in pixels)
+  label_status_transitions: Status transitie
+  label_fields_permissions: Permissie velden
+  label_readonly: Alleen-lezen
+  label_required: Verplicht
+  text_repository_identifier_info: 'Alleen kleine letter (a-z), cijfers, streepjes en liggende streepjes zijn toegestaan.<br />Eenmaal opgeslagen kan de identifier niet worden gewijzigd.'
+  field_board_parent: Hoofd forum
+  label_attribute_of_project: Project %{name}
+  label_attribute_of_author: Auteur(s) %{name}
+  label_attribute_of_assigned_to: Toegewezen %{name}
+  label_attribute_of_fixed_version: Target versions %{name}
+  label_copy_subtasks: Kopieer subtaken
+  label_copied_to: gekopieerd naar
+  label_copied_from: gekopieerd van
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: PrivÃ© notities
+  permission_view_private_notes: Bekijk privÃ© notities
+  permission_set_notes_private: Maak notities privÃ©
+  label_no_issues_in_project: geen issues in project
+  label_any: alle
+  label_last_n_weeks: afgelopen %{count} weken
+  setting_cross_project_subtasks: Sta subtaken in andere projecten toe
+  label_cross_project_descendants: Met subprojecten
+  label_cross_project_tree: Met project boom
+  label_cross_project_hierarchy: Met project hiÃ«rarchie
+  label_cross_project_system: Met alle projecten
+  button_hide: Verberg
+  setting_non_working_week_days: Niet-werkdagen
+  label_in_the_next_days: in de volgende
+  label_in_the_past_days: in de afgelopen
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: Bij het uitschakelen van meerdere waardes zal er maar een waarde bewaard blijven.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Voeg documenten toe
+  permission_edit_documents: Bewerk documenten
+  permission_delete_documents: Verwijder documenten
+  label_gantt_progress_line: Voortgangslijn
+  setting_jsonp_enabled: Schakel JSONP support in
+  field_inherit_members: Neem leden over
+  field_closed_on: Gesloten
+  setting_default_projects_tracker_ids: Standaard trackers voor nieuwe projecten
+  label_total_time: Totaal
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dc/dc9139c99c509d9f76df794ebe1b204339e929fd.svn-base
--- /dev/null
+++ b/.svn/pristine/dc/dc9139c99c509d9f76df794ebe1b204339e929fd.svn-base
@@ -0,0 +1,34 @@
+<div class="contextual">
+<%= link_to l(:label_role_new), new_role_path, :class => 'icon icon-add' %>
+<%= link_to l(:label_permissions_report), permissions_roles_path, :class => 'icon icon-summary' %>
+</div>
+
+<h2><%=l(:label_role_plural)%></h2>
+
+<table class="list">
+  <thead><tr>
+    <th><%=l(:label_role)%></th>
+    <th><%=l(:button_sort)%></th>
+  <th></th>
+  </tr></thead>
+  <tbody>
+<% for role in @roles %>
+  <tr class="<%= cycle("odd", "even") %>">
+  <td><%= content_tag(role.builtin? ? 'em' : 'span', link_to(h(role.name), edit_role_path(role))) %></td>
+  <td align="center" style="width:15%;">
+  <% unless role.builtin? %>
+    <%= reorder_links('role', {:action => 'update', :id => role}, :put) %>
+  <% end %>
+  </td>
+  <td class="buttons">
+    <%= link_to l(:button_copy), new_role_path(:copy => role), :class => 'icon icon-copy' %>
+    <%= delete_link role_path(role) unless role.builtin? %>
+  </td>
+  </tr>
+<% end %>
+  </tbody>
+</table>
+
+<p class="pagination"><%= pagination_links_full @role_pages %></p>
+
+<% html_title(l(:label_role_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dc/dc9491f2af49f910aa61b48511dec77f59aca42c.svn-base
--- /dev/null
+++ b/.svn/pristine/dc/dc9491f2af49f910aa61b48511dec77f59aca42c.svn-base
@@ -0,0 +1,90 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class SettingTest < ActiveSupport::TestCase
+
+  def teardown
+    Setting.clear_cache
+  end
+
+  def test_read_default
+    assert_equal "Redmine", Setting.app_title
+    assert Setting.self_registration?
+    assert !Setting.login_required?
+  end
+
+  def test_update
+    Setting.app_title = "My title"
+    assert_equal "My title", Setting.app_title
+    # make sure db has been updated (INSERT)
+    assert_equal "My title", Setting.find_by_name('app_title').value
+
+    Setting.app_title = "My other title"
+    assert_equal "My other title", Setting.app_title
+    # make sure db has been updated (UPDATE)
+    assert_equal "My other title", Setting.find_by_name('app_title').value
+  end
+
+  def test_serialized_setting
+    Setting.notified_events = ['issue_added', 'issue_updated', 'news_added']
+    assert_equal ['issue_added', 'issue_updated', 'news_added'], Setting.notified_events
+    assert_equal ['issue_added', 'issue_updated', 'news_added'], Setting.find_by_name('notified_events').value
+  end
+  
+  def test_setting_should_be_reloaded_after_clear_cache
+    Setting.app_title = "My title"
+    assert_equal "My title", Setting.app_title
+    
+    s = Setting.find_by_name("app_title")
+    s.value = 'New title'
+    s.save!
+    assert_equal "My title", Setting.app_title
+    
+    Setting.clear_cache
+    assert_equal "New title", Setting.app_title
+  end
+
+  def test_per_page_options_array_should_be_an_empty_array_when_setting_is_blank
+    with_settings :per_page_options => nil do
+      assert_equal [], Setting.per_page_options_array
+    end
+
+    with_settings :per_page_options => '' do
+      assert_equal [], Setting.per_page_options_array
+    end
+  end
+
+  def test_per_page_options_array_should_be_an_array_of_integers
+    with_settings :per_page_options => '10, 25, 50' do
+      assert_equal [10, 25, 50], Setting.per_page_options_array
+    end
+  end
+
+  def test_per_page_options_array_should_omit_non_numerial_values
+    with_settings :per_page_options => 'a, 25, 50' do
+      assert_equal [25, 50], Setting.per_page_options_array
+    end
+  end
+
+  def test_per_page_options_array_should_be_sorted
+    with_settings :per_page_options => '25, 10, 50' do
+      assert_equal [10, 25, 50], Setting.per_page_options_array
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dc/dcac5a29f794b90b0c70d7b180bb1c20ea9606aa.svn-base
--- a/.svn/pristine/dc/dcac5a29f794b90b0c70d7b180bb1c20ea9606aa.svn-base
+++ /dev/null
@@ -1,42 +0,0 @@
-desc "Run the Continous Integration tests for Redmine"
-task :ci do
-  # RAILS_ENV and ENV[] can diverge so force them both to test
-  ENV['RAILS_ENV'] = 'test'
-  RAILS_ENV = 'test'
-  Rake::Task["ci:setup"].invoke
-  Rake::Task["ci:build"].invoke
-  Rake::Task["ci:teardown"].invoke
-end
-
-# Tasks can be hooked into by redefining them in a plugin
-namespace :ci do
-  desc "Setup Redmine for a new build."
-  task :setup do
-    Rake::Task["ci:dump_environment"].invoke
-    Rake::Task["db:create"].invoke
-    Rake::Task["db:migrate"].invoke
-    Rake::Task["db:schema:dump"].invoke
-    Rake::Task["test:scm:update"].invoke
-  end
-
-  desc "Build Redmine"
-  task :build do
-    Rake::Task["test"].invoke
-  end
-
-  # Use this to cleanup after building or run post-build analysis.
-  desc "Finish the build"
-  task :teardown do
-  end
-
-  desc "Dump the environment information to a BUILD_ENVIRONMENT ENV variable for debugging"
-  task :dump_environment do
-
-    ENV['BUILD_ENVIRONMENT'] = ['ruby -v', 'gem -v', 'gem list'].collect do |command|
-      result = `#{command}`
-      "$ #{command}\n#{result}"
-    end.join("\n")
-    
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dc/dcd8300edc662a87086c09fd122175e47ec511a0.svn-base
--- a/.svn/pristine/dc/dcd8300edc662a87086c09fd122175e47ec511a0.svn-base
+++ /dev/null
@@ -1,50 +0,0 @@
-<%= render :partial => 'action_menu' %>
-
-<h2><%=l(:label_workflow)%></h2>
-
-<p><%=l(:text_workflow_edit)%>:</p>
-
-<% form_tag({}, :method => 'get') do %>
-<p>
-  <label><%=l(:label_role)%>:
-  <%= select_tag 'role_id', options_from_collection_for_select(@roles, "id", "name", @role && @role.id) %></label>
-
-  <label><%=l(:label_tracker)%>:
-  <%= select_tag 'tracker_id', options_from_collection_for_select(@trackers, "id", "name", @tracker && @tracker.id) %></label>
-
-  <%= hidden_field_tag 'used_statuses_only', '0' %>
-  <label><%= check_box_tag 'used_statuses_only', '1', @used_statuses_only %> <%= l(:label_display_used_statuses_only) %></label>
-</p>
-<p>
-<%= submit_tag l(:button_edit), :name => nil %>
-</p>
-<% end %>
-
-<% if @tracker && @role && @statuses.any? %>
-  <% form_tag({}, :id => 'workflow_form' ) do %>
-    <%= hidden_field_tag 'tracker_id', @tracker.id %>
-    <%= hidden_field_tag 'role_id', @role.id %>
-    <div class="autoscroll">
-      <%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %>
-
-      <fieldset class="collapsible" style="padding: 0; margin-top: 0.5em;">
-        <legend onclick="toggleFieldset(this);"><%= l(:label_additional_workflow_transitions_for_author) %></legend>
-        <div id="author_workflows" style="margin: 0.5em 0 0.5em 0;">
-          <%= render :partial => 'form', :locals => {:name => 'author', :workflows => @workflows['author']} %>
-        </div>
-      </fieldset>
-      <%= javascript_tag "hideFieldset($('author_workflows'))" unless @workflows['author'].present? %>
-
-      <fieldset class="collapsible" style="padding: 0;">
-        <legend onclick="toggleFieldset(this);"><%= l(:label_additional_workflow_transitions_for_assignee) %></legend>
-        <div id="assignee_workflows" style="margin: 0.5em 0 0.5em 0;">
-      <%= render :partial => 'form', :locals => {:name => 'assignee', :workflows => @workflows['assignee']} %>
-        </div>
-      </fieldset>
-      <%= javascript_tag "hideFieldset($('assignee_workflows'))" unless @workflows['assignee'].present? %>
-    </div>
-    <%= submit_tag l(:button_save) %>
-  <% end %>
-<% end %>
-
-<% html_title(l(:label_workflow)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dc/dcee272a467f498348007d2ea60879c2d6c49cc7.svn-base
--- /dev/null
+++ b/.svn/pristine/dc/dcee272a467f498348007d2ea60879c2d6c49cc7.svn-base
@@ -0,0 +1,57 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module VersionsHelper
+
+  def version_anchor(version)
+    if @project == version.project
+      anchor version.name
+    else
+      anchor "#{version.project.try(:identifier)}-#{version.name}"
+    end
+  end
+
+  STATUS_BY_CRITERIAS = %w(tracker status priority author assigned_to category)
+
+  def render_issue_status_by(version, criteria)
+    criteria = 'tracker' unless STATUS_BY_CRITERIAS.include?(criteria)
+
+    h = Hash.new {|k,v| k[v] = [0, 0]}
+    begin
+      # Total issue count
+      Issue.count(:group => criteria,
+                  :conditions => ["#{Issue.table_name}.fixed_version_id = ?", version.id]).each {|c,s| h[c][0] = s}
+      # Open issues count
+      Issue.count(:group => criteria,
+                  :include => :status,
+                  :conditions => ["#{Issue.table_name}.fixed_version_id = ? AND #{IssueStatus.table_name}.is_closed = ?", version.id, false]).each {|c,s| h[c][1] = s}
+    rescue ActiveRecord::RecordNotFound
+    # When grouping by an association, Rails throws this exception if there's no result (bug)
+    end
+    # Sort with nil keys in last position
+    counts = h.keys.sort {|a,b| a.nil? ? 1 : (b.nil? ? -1 : a <=> b)}.collect {|k| {:group => k, :total => h[k][0], :open => h[k][1], :closed => (h[k][0] - h[k][1])}}
+    max = counts.collect {|c| c[:total]}.max
+
+    render :partial => 'issue_counts', :locals => {:version => version, :criteria => criteria, :counts => counts, :max => max}
+  end
+
+  def status_by_options_for_select(value)
+    options_for_select(STATUS_BY_CRITERIAS.collect {|criteria| [l("field_#{criteria}".to_sym), criteria]}, value)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dd/dd203a5a6750b57817c4b5777ab59c772c375a96.svn-base
--- a/.svn/pristine/dd/dd203a5a6750b57817c4b5777ab59c772c375a96.svn-base
+++ /dev/null
@@ -1,44 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class MailHandlerController < ActionController::Base
-  before_filter :check_credential
-
-  verify :method => :post,
-         :only => :index,
-         :render => { :nothing => true, :status => 405 }
-
-  # Submits an incoming email to MailHandler
-  def index
-    options = params.dup
-    email = options.delete(:email)
-    if MailHandler.receive(email, options)
-      render :nothing => true, :status => :created
-    else
-      render :nothing => true, :status => :unprocessable_entity
-    end
-  end
-
-  private
-
-  def check_credential
-    User.current = nil
-    unless Setting.mail_handler_api_enabled? && params[:key].to_s == Setting.mail_handler_api_key
-      render :text => 'Access denied. Incoming emails WS is disabled or key is invalid.', :status => 403
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dd/dd3fc580b46d142a6812688ff323c2b6855b5a85.svn-base
--- /dev/null
+++ b/.svn/pristine/dd/dd3fc580b46d142a6812688ff323c2b6855b5a85.svn-base
@@ -0,0 +1,129 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class EnumerationsControllerTest < ActionController::TestCase
+  fixtures :enumerations, :issues, :users
+
+  def setup
+    @request.session[:user_id] = 1 # admin
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+  end
+
+  def test_index_should_require_admin
+    @request.session[:user_id] = nil
+    get :index
+    assert_response 302
+  end
+
+  def test_new
+    get :new, :type => 'IssuePriority'
+    assert_response :success
+    assert_template 'new'
+    assert_kind_of IssuePriority, assigns(:enumeration)
+    assert_tag 'input', :attributes => {:name => 'enumeration[type]', :value => 'IssuePriority'}
+    assert_tag 'input', :attributes => {:name => 'enumeration[name]'}
+  end
+
+  def test_new_with_invalid_type_should_respond_with_404
+    get :new, :type => 'UnknownType'
+    assert_response 404
+  end
+
+  def test_create
+    assert_difference 'IssuePriority.count' do
+      post :create, :enumeration => {:type => 'IssuePriority', :name => 'Lowest'}
+    end
+    assert_redirected_to '/enumerations'
+    e = IssuePriority.find_by_name('Lowest')
+    assert_not_nil e
+  end
+
+  def test_create_with_failure
+    assert_no_difference 'IssuePriority.count' do
+      post :create, :enumeration => {:type => 'IssuePriority', :name => ''}
+    end
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_edit
+    get :edit, :id => 6
+    assert_response :success
+    assert_template 'edit'
+    assert_tag 'input', :attributes => {:name => 'enumeration[name]', :value => 'High'}
+  end
+
+  def test_edit_invalid_should_respond_with_404
+    get :edit, :id => 999
+    assert_response 404
+  end
+
+  def test_update
+    assert_no_difference 'IssuePriority.count' do
+      put :update, :id => 6, :enumeration => {:type => 'IssuePriority', :name => 'New name'}
+    end
+    assert_redirected_to '/enumerations'
+    e = IssuePriority.find(6)
+    assert_equal 'New name', e.name
+  end
+
+  def test_update_with_failure
+    assert_no_difference 'IssuePriority.count' do
+      put :update, :id => 6, :enumeration => {:type => 'IssuePriority', :name => ''}
+    end
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_destroy_enumeration_not_in_use
+    assert_difference 'IssuePriority.count', -1 do
+      delete :destroy, :id => 7
+    end
+    assert_redirected_to :controller => 'enumerations', :action => 'index'
+    assert_nil Enumeration.find_by_id(7)
+  end
+
+  def test_destroy_enumeration_in_use
+    assert_no_difference 'IssuePriority.count' do
+      delete :destroy, :id => 4
+    end
+    assert_response :success
+    assert_template 'destroy'
+    assert_not_nil Enumeration.find_by_id(4)
+    assert_select 'select[name=reassign_to_id]' do
+      assert_select 'option[value=6]', :text => 'High'
+    end
+  end
+
+  def test_destroy_enumeration_in_use_with_reassignment
+    issue = Issue.where(:priority_id => 4).first
+    assert_difference 'IssuePriority.count', -1 do
+      delete :destroy, :id => 4, :reassign_to_id => 6
+    end
+    assert_redirected_to :controller => 'enumerations', :action => 'index'
+    assert_nil Enumeration.find_by_id(4)
+    # check that the issue was reassign
+    assert_equal 6, issue.reload.priority_id
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dd/dd4d40b7c92af3319303c89259cc7a21a900ab6b.svn-base
--- /dev/null
+++ b/.svn/pristine/dd/dd4d40b7c92af3319303c89259cc7a21a900ab6b.svn-base
@@ -0,0 +1,34 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class ApplicationHelperTest < ActionView::TestCase
+  include Redmine::Pagination::Helper
+
+  def test_per_page_options_should_return_usefull_values
+    with_settings :per_page_options => '10, 25, 50, 100' do
+      assert_equal [], per_page_options(10, 3)
+      assert_equal [], per_page_options(25, 3)
+      assert_equal [10, 25], per_page_options(10, 22)
+      assert_equal [10, 25], per_page_options(25, 22)
+      assert_equal [10, 25, 50], per_page_options(50, 22)
+      assert_equal [10, 25, 50], per_page_options(25, 26)
+      assert_equal [10, 25, 50, 100], per_page_options(25, 120)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dd/dd9453d0bf7ef7086f723475ae286725a241d719.svn-base
--- /dev/null
+++ b/.svn/pristine/dd/dd9453d0bf7ef7086f723475ae286725a241d719.svn-base
@@ -0,0 +1,28 @@
+= Redmine
+
+Redmine is a flexible project management web application written using Ruby on Rails framework.
+
+More details can be found at http://www.redmine.org
+
+= License
+
+Copyright (C) 2006-2013  Jean-Philippe Lang
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+Icons credits:
+
+* Mark James (Silk Icons) licensed under a Creative Commons Attribution 2.5 License.
+* Yusuke Kamiyamane (Fugue Icons) licensed under a Creative Commons Attribution 3.0 License.
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/dd/ddb17ba3f75574f7f21e99b4c8c77f26e54a423b.svn-base
--- /dev/null
+++ b/.svn/pristine/dd/ddb17ba3f75574f7f21e99b4c8c77f26e54a423b.svn-base
@@ -0,0 +1,131 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class SettingsControllerTest < ActionController::TestCase
+  fixtures :users
+
+  def setup
+    User.current = nil
+    @request.session[:user_id] = 1 # admin
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_get_edit
+    get :edit
+    assert_response :success
+    assert_template 'edit'
+
+    assert_tag 'input', :attributes => {:name => 'settings[enabled_scm][]', :value => ''}
+  end
+
+  def test_get_edit_should_preselect_default_issue_list_columns
+    with_settings :issue_list_default_columns => %w(tracker subject status updated_on) do
+      get :edit
+      assert_response :success
+    end
+
+    assert_select 'select[id=selected_columns][name=?]', 'settings[issue_list_default_columns][]' do
+      assert_select 'option', 4
+      assert_select 'option[value=tracker]', :text => 'Tracker'
+      assert_select 'option[value=subject]', :text => 'Subject'
+      assert_select 'option[value=status]', :text => 'Status'
+      assert_select 'option[value=updated_on]', :text => 'Updated'
+    end
+
+    assert_select 'select[id=available_columns]' do
+      assert_select 'option[value=tracker]', 0
+      assert_select 'option[value=priority]', :text => 'Priority'
+    end
+  end
+
+  def test_get_edit_without_trackers_should_succeed
+    Tracker.delete_all
+
+    get :edit
+    assert_response :success
+  end
+
+  def test_post_edit_notifications
+    post :edit, :settings => {:mail_from => 'functional@test.foo',
+                              :bcc_recipients  => '0',
+                              :notified_events => %w(issue_added issue_updated news_added),
+                              :emails_footer => 'Test footer'
+                              }
+    assert_redirected_to '/settings'
+    assert_equal 'functional@test.foo', Setting.mail_from
+    assert !Setting.bcc_recipients?
+    assert_equal %w(issue_added issue_updated news_added), Setting.notified_events
+    assert_equal 'Test footer', Setting.emails_footer
+    Setting.clear_cache
+  end
+
+  def test_get_plugin_settings
+    Setting.stubs(:plugin_foo).returns({'sample_setting' => 'Plugin setting value'})
+    ActionController::Base.append_view_path(File.join(Rails.root, "test/fixtures/plugins"))
+    Redmine::Plugin.register :foo do
+      settings :partial => "foo_plugin/foo_plugin_settings"
+    end
+
+    get :plugin, :id => 'foo'
+    assert_response :success
+    assert_template 'plugin'
+    assert_tag 'form', :attributes => {:action => '/settings/plugin/foo'},
+      :descendant => {:tag => 'input', :attributes => {:name => 'settings[sample_setting]', :value => 'Plugin setting value'}}
+
+    Redmine::Plugin.clear
+  end
+
+  def test_get_invalid_plugin_settings
+    get :plugin, :id => 'none'
+    assert_response 404
+  end
+
+  def test_get_non_configurable_plugin_settings
+    Redmine::Plugin.register(:foo) {}
+
+    get :plugin, :id => 'foo'
+    assert_response 404
+
+    Redmine::Plugin.clear
+  end
+
+  def test_post_plugin_settings
+    Setting.expects(:plugin_foo=).with({'sample_setting' => 'Value'}).returns(true)
+    Redmine::Plugin.register(:foo) do
+      settings :partial => 'not blank' # so that configurable? is true
+    end
+
+    post :plugin, :id => 'foo', :settings => {'sample_setting' => 'Value'}
+    assert_redirected_to '/settings/plugin/foo'
+  end
+
+  def test_post_non_configurable_plugin_settings
+    Redmine::Plugin.register(:foo) {}
+
+    post :plugin, :id => 'foo', :settings => {'sample_setting' => 'Value'}
+    assert_response 404
+
+    Redmine::Plugin.clear
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/de/de186cfeffd5412721bd7bb4cddf802ed4f49ee2.svn-base
--- /dev/null
+++ b/.svn/pristine/de/de186cfeffd5412721bd7bb4cddf802ed4f49ee2.svn-base
@@ -0,0 +1,165 @@
+--- 
+queries_001: 
+  id: 1
+  type: IssueQuery
+  project_id: 1
+  is_public: true
+  name: Multiple custom fields query
+  filters: |
+    --- 
+    cf_1: 
+      :values: 
+      - MySQL
+      :operator: "="
+    status_id: 
+      :values: 
+      - "1"
+      :operator: o
+    cf_2: 
+      :values: 
+      - "125"
+      :operator: "="
+
+  user_id: 1
+  column_names: 
+queries_002: 
+  id: 2
+  type: IssueQuery
+  project_id: 1
+  is_public: false
+  name: Private query for cookbook
+  filters: |
+    --- 
+    tracker_id: 
+      :values: 
+      - "3"
+      :operator: "="
+    status_id: 
+      :values: 
+      - "1"
+      :operator: o
+
+  user_id: 3
+  column_names: 
+queries_003: 
+  id: 3
+  type: IssueQuery
+  project_id: 
+  is_public: false
+  name: Private query for all projects
+  filters: |
+    --- 
+    tracker_id: 
+      :values: 
+      - "3"
+      :operator: "="
+
+  user_id: 3
+  column_names: 
+queries_004: 
+  id: 4
+  type: IssueQuery
+  project_id: 
+  is_public: true
+  name: Public query for all projects
+  filters: |
+    --- 
+    tracker_id: 
+      :values: 
+      - "3"
+      :operator: "="
+
+  user_id: 2
+  column_names: 
+queries_005: 
+  id: 5
+  type: IssueQuery
+  project_id: 
+  is_public: true
+  name: Open issues by priority and tracker
+  filters: |
+    --- 
+    status_id: 
+      :values: 
+      - "1"
+      :operator: o
+
+  user_id: 1
+  column_names: 
+  sort_criteria: |
+    --- 
+    - - priority
+      - desc
+    - - tracker
+      - asc
+queries_006: 
+  id: 6
+  type: IssueQuery
+  project_id: 
+  is_public: true
+  name: Open issues grouped by tracker
+  filters: |
+    --- 
+    status_id: 
+      :values: 
+      - "1"
+      :operator: o
+
+  user_id: 1
+  column_names: 
+  group_by: tracker
+  sort_criteria: |
+    --- 
+    - - priority
+      - desc
+queries_007: 
+  id: 7
+  type: IssueQuery
+  project_id: 2
+  is_public: true
+  name: Public query for project 2
+  filters: |
+    --- 
+    tracker_id: 
+      :values: 
+      - "3"
+      :operator: "="
+
+  user_id: 2
+  column_names: 
+queries_008: 
+  id: 8
+  type: IssueQuery
+  project_id: 2
+  is_public: false
+  name: Private query for project 2
+  filters: |
+    --- 
+    tracker_id: 
+      :values: 
+      - "3"
+      :operator: "="
+
+  user_id: 2
+  column_names: 
+queries_009: 
+  id: 9
+  type: IssueQuery
+  project_id: 
+  is_public: true
+  name: Open issues grouped by list custom field
+  filters: |
+    --- 
+    status_id: 
+      :values: 
+      - "1"
+      :operator: o
+
+  user_id: 1
+  column_names: 
+  group_by: cf_1
+  sort_criteria: |
+    --- 
+    - - priority
+      - desc
+
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/de/de28294aaae4f7b627f7d8be23b384b587f38419.svn-base
--- a/.svn/pristine/de/de28294aaae4f7b627f7d8be23b384b587f38419.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-$LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info"
-require 'commands/about'
-
-Redmine::About.print_plugin_info
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/de/de33a6eb951226489a34da09937a4a47913b07fb.svn-base
--- /dev/null
+++ b/.svn/pristine/de/de33a6eb951226489a34da09937a4a47913b07fb.svn-base
@@ -0,0 +1,165 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class NewsControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news, :comments
+
+  def setup
+    User.current = nil
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:newss)
+    assert_nil assigns(:project)
+  end
+
+  def test_index_with_project
+    get :index, :project_id => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:newss)
+  end
+
+  def test_index_with_invalid_project_should_respond_with_404
+    get :index, :project_id => 999
+    assert_response 404
+  end
+
+  def test_show
+    get :show, :id => 1
+    assert_response :success
+    assert_template 'show'
+    assert_tag :tag => 'h2', :content => /eCookbook first release/
+  end
+
+  def test_show_should_show_attachments
+    attachment = Attachment.first
+    attachment.container = News.find(1)
+    attachment.save!
+
+    get :show, :id => 1
+    assert_response :success
+    assert_tag 'a', :content => attachment.filename
+  end
+
+  def test_show_not_found
+    get :show, :id => 999
+    assert_response 404
+  end
+
+  def test_get_new
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_post_create
+    ActionMailer::Base.deliveries.clear
+    @request.session[:user_id] = 2
+
+    with_settings :notified_events => %w(news_added) do
+      post :create, :project_id => 1, :news => { :title => 'NewsControllerTest',
+                                            :description => 'This is the description',
+                                            :summary => '' }
+    end
+    assert_redirected_to '/projects/ecookbook/news'
+
+    news = News.find_by_title('NewsControllerTest')
+    assert_not_nil news
+    assert_equal 'This is the description', news.description
+    assert_equal User.find(2), news.author
+    assert_equal Project.find(1), news.project
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_post_create_with_attachment
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+    assert_difference 'News.count' do
+      assert_difference 'Attachment.count' do
+        post :create, :project_id => 1,
+          :news => { :title => 'Test', :description => 'This is the description' },
+          :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
+      end
+    end
+    attachment = Attachment.first(:order => 'id DESC')
+    news = News.first(:order => 'id DESC')
+    assert_equal news, attachment.container
+  end
+
+  def test_post_create_with_validation_failure
+    @request.session[:user_id] = 2
+    post :create, :project_id => 1, :news => { :title => '',
+                                            :description => 'This is the description',
+                                            :summary => '' }
+    assert_response :success
+    assert_template 'new'
+    assert_not_nil assigns(:news)
+    assert assigns(:news).new_record?
+    assert_error_tag :content => /title can&#x27;t be blank/i
+  end
+
+  def test_get_edit
+    @request.session[:user_id] = 2
+    get :edit, :id => 1
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_put_update
+    @request.session[:user_id] = 2
+    put :update, :id => 1, :news => { :description => 'Description changed by test_post_edit' }
+    assert_redirected_to '/news/1'
+    news = News.find(1)
+    assert_equal 'Description changed by test_post_edit', news.description
+  end
+
+  def test_put_update_with_attachment
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+    assert_no_difference 'News.count' do
+      assert_difference 'Attachment.count' do
+        put :update, :id => 1,
+          :news => { :description => 'This is the description' },
+          :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
+      end
+    end
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal News.find(1), attachment.container
+  end
+
+  def test_update_with_failure
+    @request.session[:user_id] = 2
+    put :update, :id => 1, :news => { :description => '' }
+    assert_response :success
+    assert_template 'edit'
+    assert_error_tag :content => /description can&#x27;t be blank/i
+  end
+
+  def test_destroy
+    @request.session[:user_id] = 2
+    delete :destroy, :id => 1
+    assert_redirected_to '/projects/ecookbook/news'
+    assert_nil News.find_by_id(1)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/de/de4649b899e4b3b64fbf0d7e44653599c87a54ca.svn-base
--- a/.svn/pristine/de/de4649b899e4b3b64fbf0d7e44653599c87a54ca.svn-base
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- mode: outline; coding: utf-8-unix; -*-
-
-* Add logic in Rakefile to read the file list from Manifest.txt file.
-
-* Add a YAML export method to the TreeNode class.
-
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/de/de5abc3a0a3acefca62457872d2fd89b41a4f9a6.svn-base
--- /dev/null
+++ b/.svn/pristine/de/de5abc3a0a3acefca62457872d2fd89b41a4f9a6.svn-base
@@ -0,0 +1,104 @@
+--- 
+changesets_001: 
+  commit_date: 2007-04-11
+  committed_on: 2007-04-11 15:14:44 +02:00
+  revision: 1
+  scmid: 691322a8eb01e11fd7
+  id: 100
+  comments: 'My very first commit do not escaping #<>&'
+  repository_id: 10
+  committer: dlopper
+  user_id: 3
+changesets_002: 
+  commit_date: 2007-04-12
+  committed_on: 2007-04-12 15:14:44 +02:00
+  revision: 2
+  id: 101
+  comments: 'This commit fixes #1, #2 and references #1 & #3'
+  repository_id: 10
+  committer: dlopper
+  user_id: 3
+changesets_003: 
+  commit_date: 2007-04-12
+  committed_on: 2007-04-12 15:14:44 +02:00
+  revision: 3
+  id: 102
+  comments: |-
+    A commit with wrong issue ids
+    IssueID #666 #3
+  repository_id: 10
+  committer: dlopper
+  user_id: 3
+changesets_004: 
+  commit_date: 2007-04-12
+  committed_on: 2007-04-12 15:14:44 +02:00
+  revision: 4
+  id: 103
+  comments: |-
+    A commit with an issue id of an other project
+    IssueID 4 2
+  repository_id: 10
+  committer: dlopper
+  user_id: 3
+changesets_005: 
+  commit_date: "2007-09-10"
+  comments: Modified one file in the folder.
+  committed_on: 2007-09-10 19:01:08
+  revision: "5"
+  id: 104
+  scmid:
+  user_id: 3
+  repository_id: 10
+  committer: dlopper
+changesets_006: 
+  commit_date: "2007-09-10"
+  comments: Moved helloworld.rb from / to /folder.
+  committed_on: 2007-09-10 19:01:47
+  revision: "6"
+  id: 105
+  scmid:
+  user_id: 3
+  repository_id: 10
+  committer: dlopper
+changesets_007: 
+  commit_date: "2007-09-10"
+  comments: Removed one file.
+  committed_on: 2007-09-10 19:02:16
+  revision: "7"
+  id: 106
+  scmid:
+  user_id: 3
+  repository_id: 10
+  committer: dlopper
+changesets_008: 
+  commit_date: "2007-09-10"
+  comments: |-
+    This commits references an issue.
+    Refs #2
+  committed_on: 2007-09-10 19:04:35
+  revision: "8"
+  id: 107
+  scmid:
+  user_id: 3
+  repository_id: 10
+  committer: dlopper
+changesets_009: 
+  commit_date: "2009-09-10"
+  comments: One file added.
+  committed_on: 2009-09-10 19:04:35
+  revision: "9"
+  id: 108
+  scmid:
+  user_id: 3
+  repository_id: 10
+  committer: dlopper
+changesets_010: 
+  commit_date: "2009-09-10"
+  comments: Same file modified.
+  committed_on: 2009-09-10 19:04:35
+  revision: "10"
+  id: 109
+  scmid:
+  user_id: 3
+  repository_id: 10
+  committer: dlopper
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/de/de5d92ebbac6f996f9c447dfe646769615cd7350.svn-base
--- a/.svn/pristine/de/de5d92ebbac6f996f9c447dfe646769615cd7350.svn-base
+++ /dev/null
@@ -1,1029 +0,0 @@
-# German translations for Ruby on Rails
-# by Clemens Kofler (clemens@railway.at)
-# additions for Redmine 1.2 by Jens Martsch (jmartsch@gmail.com)
-
-de:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%d.%m.%Y"
-      short: "%e. %b"
-      long: "%e. %B %Y"
-
-    day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag]
-    abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Januar, Februar, MÃ¤rz, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember]
-    abbr_month_names: [~, Jan, Feb, MÃ¤r, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez]
-    # Used in date_select and datime_select.
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%d.%m.%Y %H:%M"
-      time: "%H:%M"
-      short: "%e. %b %H:%M"
-      long: "%A, %e. %B %Y, %H:%M Uhr"
-    am: "vormittags"
-    pm: "nachmittags"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: 'eine halbe Minute'
-      less_than_x_seconds:
-        one: 'weniger als 1 Sekunde'
-        other: 'weniger als %{count} Sekunden'
-      x_seconds:
-        one: '1 Sekunde'
-        other: '%{count} Sekunden'
-      less_than_x_minutes:
-        one: 'weniger als 1 Minute'
-        other: 'weniger als %{count} Minuten'
-      x_minutes:
-        one: '1 Minute'
-        other: '%{count} Minuten'
-      about_x_hours:
-        one: 'etwa 1 Stunde'
-        other: 'etwa %{count} Stunden'
-      x_days:
-        one: '1 Tag'
-        other: '%{count} Tagen'
-      about_x_months:
-        one: 'etwa 1 Monat'
-        other: 'etwa %{count} Monaten'
-      x_months:
-        one: '1 Monat'
-        other: '%{count} Monaten'
-      about_x_years:
-        one: 'etwa 1 Jahr'
-        other: 'etwa %{count} Jahren'
-      over_x_years:
-        one: 'mehr als 1 Jahr'
-        other: 'mehr als %{count} Jahren'
-      almost_x_years:
-        one:   "fast 1 Jahr"
-        other: "fast %{count} Jahren"
-
-  number:
-    # Default format for numbers
-    format:
-      separator: ','
-      delimiter: '.'
-      precision: 2
-    currency:
-      format:
-        unit: 'â‚¬'
-        format: '%n %u'
-        separator:
-        delimiter:
-        precision:
-    percentage:
-      format:
-        delimiter: ""
-    precision:
-      format:
-        delimiter: ""
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "und"
-      skip_last_comma: true
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "Dieses %{model}-Objekt konnte nicht gespeichert werden: %{count} Fehler."
-          other:  "Dieses %{model}-Objekt konnte nicht gespeichert werden: %{count} Fehler."
-        body: "Bitte Ã¼berprÃ¼fen Sie die folgenden Felder:"
-
-      messages:
-        inclusion: "ist kein gÃ¼ltiger Wert"
-        exclusion: "ist nicht verfÃ¼gbar"
-        invalid: "ist nicht gÃ¼ltig"
-        confirmation: "stimmt nicht mit der BestÃ¤tigung Ã¼berein"
-        accepted: "muss akzeptiert werden"
-        empty: "muss ausgefÃ¼llt werden"
-        blank: "muss ausgefÃ¼llt werden"
-        too_long: "ist zu lang (nicht mehr als %{count} Zeichen)"
-        too_short: "ist zu kurz (nicht weniger als %{count} Zeichen)"
-        wrong_length: "hat die falsche LÃ¤nge (muss genau %{count} Zeichen haben)"
-        taken: "ist bereits vergeben"
-        not_a_number: "ist keine Zahl"
-        not_a_date: "is kein gÃ¼ltiges Datum"
-        greater_than: "muss grÃ¶ÃŸer als %{count} sein"
-        greater_than_or_equal_to: "muss grÃ¶ÃŸer oder gleich %{count} sein"
-        equal_to: "muss genau %{count} sein"
-        less_than: "muss kleiner als %{count} sein"
-        less_than_or_equal_to: "muss kleiner oder gleich %{count} sein"
-        odd: "muss ungerade sein"
-        even: "muss gerade sein"
-        greater_than_start_date: "muss grÃ¶ÃŸer als Anfangsdatum sein"
-        not_same_project: "gehÃ¶rt nicht zum selben Projekt"
-        circular_dependency: "Diese Beziehung wÃ¼rde eine zyklische AbhÃ¤ngigkeit erzeugen"
-        cant_link_an_issue_with_a_descendant: "Ein Ticket kann nicht mit einer ihrer Unteraufgaben verlinkt werden"
-
-  actionview_instancetag_blank_option: Bitte auswÃ¤hlen
-  
-  general_text_No: 'Nein'
-  general_text_Yes: 'Ja'
-  general_text_no: 'nein'
-  general_text_yes: 'ja'
-  general_lang_name: 'Deutsch'
-  general_csv_separator: ';'
-  general_csv_decimal_separator: ','
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: Konto wurde erfolgreich aktualisiert.
-  notice_account_invalid_creditentials: Benutzer oder Kennwort ist ungÃ¼ltig.
-  notice_account_password_updated: Kennwort wurde erfolgreich aktualisiert.
-  notice_account_wrong_password: Falsches Kennwort.
-  notice_account_register_done: Konto wurde erfolgreich angelegt.
-  notice_account_unknown_email: Unbekannter Benutzer.
-  notice_can_t_change_password: Dieses Konto verwendet eine externe Authentifizierungs-Quelle. UnmÃ¶glich, das Kennwort zu Ã¤ndern.
-  notice_account_lost_email_sent: Eine E-Mail mit Anweisungen, ein neues Kennwort zu wÃ¤hlen, wurde Ihnen geschickt.
-  notice_account_activated: Ihr Konto ist aktiviert. Sie kÃ¶nnen sich jetzt anmelden.
-  notice_successful_create: Erfolgreich angelegt
-  notice_successful_update: Erfolgreich aktualisiert.
-  notice_successful_delete: Erfolgreich gelÃ¶scht.
-  notice_successful_connection: Verbindung erfolgreich.
-  notice_file_not_found: Anhang existiert nicht oder ist gelÃ¶scht worden.
-  notice_locking_conflict: Datum wurde von einem anderen Benutzer geÃ¤ndert.
-  notice_not_authorized: Sie sind nicht berechtigt, auf diese Seite zuzugreifen.
-  notice_email_sent: "Eine E-Mail wurde an %{value} gesendet."
-  notice_email_error: "Beim Senden einer E-Mail ist ein Fehler aufgetreten (%{value})."
-  notice_feeds_access_key_reseted: Ihr Atom-ZugriffsschlÃ¼ssel wurde zurÃ¼ckgesetzt.
-  notice_api_access_key_reseted: Ihr API-ZugriffsschlÃ¼ssel wurde zurÃ¼ckgesetzt.
-  notice_failed_to_save_issues: "%{count} von %{total} ausgewÃ¤hlten Tickets konnte(n) nicht gespeichert werden: %{ids}."
-  notice_failed_to_save_members: "Benutzer konnte nicht gespeichert werden: %{errors}."
-  notice_no_issue_selected: "Kein Ticket ausgewÃ¤hlt! Bitte wÃ¤hlen Sie die Tickets, die Sie bearbeiten mÃ¶chten."
-  notice_account_pending: "Ihr Konto wurde erstellt und wartet jetzt auf die Genehmigung des Administrators."
-  notice_default_data_loaded: Die Standard-Konfiguration wurde erfolgreich geladen.
-  notice_unable_delete_version: Die Version konnte nicht gelÃ¶scht werden.
-  notice_unable_delete_time_entry: Der Zeiterfassungseintrag konnte nicht gelÃ¶scht werden.
-  notice_issue_done_ratios_updated: Der Ticket-Fortschritt wurde aktualisiert.
-
-  error_can_t_load_default_data: "Die Standard-Konfiguration konnte nicht geladen werden: %{value}"
-  error_scm_not_found: Eintrag und/oder Revision existiert nicht im Projektarchiv.
-  error_scm_command_failed: "Beim Zugriff auf das Projektarchiv ist ein Fehler aufgetreten: %{value}"
-  error_scm_annotate: "Der Eintrag existiert nicht oder kann nicht annotiert werden."
-  error_issue_not_found_in_project: 'Das Ticket wurde nicht gefunden oder gehÃ¶rt nicht zu diesem Projekt.'
-  error_no_tracker_in_project: Diesem Projekt ist kein Tracker zugeordnet. Bitte Ã¼berprÃ¼fen Sie die Projekteinstellungen.
-  error_no_default_issue_status: Es ist kein Status als Standard definiert. Bitte Ã¼berprÃ¼fen Sie Ihre Konfiguration (unter "Administration -> Ticket-Status").
-  error_can_not_delete_custom_field: Kann das benutzerdefinierte Feld nicht lÃ¶schen.
-  error_can_not_delete_tracker: Dieser Tracker enthÃ¤lt Tickets und kann nicht gelÃ¶scht werden.
-  error_can_not_remove_role: Diese Rolle wird verwendet und kann nicht gelÃ¶scht werden.
-  error_can_not_reopen_issue_on_closed_version: Das Ticket ist einer abgeschlossenen Version zugeordnet und kann daher nicht wieder geÃ¶ffnet werden.
-  error_can_not_archive_project: Dieses Projekt kann nicht archiviert werden.
-  error_issue_done_ratios_not_updated: Der Ticket-Fortschritt wurde nicht aktualisiert.
-  error_workflow_copy_source: Bitte wÃ¤hlen Sie einen Quell-Tracker und eine Quell-Rolle.
-  error_workflow_copy_target: Bitte wÃ¤hlen Sie die Ziel-Tracker und -Rollen.
-  error_unable_delete_issue_status: "Der Ticket-Status konnte nicht gelÃ¶scht werden."
-  error_unable_to_connect: Fehler beim Verbinden (%{value})
-  warning_attachments_not_saved: "%{count} Datei(en) konnten nicht gespeichert werden."
-  
-  mail_subject_lost_password: "Ihr %{value} Kennwort"
-  mail_body_lost_password: 'Benutzen Sie den folgenden Link, um Ihr Kennwort zu Ã¤ndern:'
-  mail_subject_register: "%{value} Kontoaktivierung"
-  mail_body_register: 'Um Ihr Konto zu aktivieren, benutzen Sie folgenden Link:'
-  mail_body_account_information_external: "Sie kÃ¶nnen sich mit Ihrem Konto %{value} an anmelden."
-  mail_body_account_information: Ihre Konto-Informationen
-  mail_subject_account_activation_request: "Antrag auf %{value} Kontoaktivierung"
-  mail_body_account_activation_request: "Ein neuer Benutzer (%{value}) hat sich registriert. Sein Konto wartet auf Ihre Genehmigung:"
-  mail_subject_reminder: "%{count} Tickets mÃ¼ssen in den nÃ¤chsten %{days} Tagen abgegeben werden"
-  mail_body_reminder: "%{count} Tickets, die Ihnen zugewiesen sind, mÃ¼ssen in den nÃ¤chsten %{days} Tagen abgegeben werden:"
-  mail_subject_wiki_content_added: "Wiki-Seite '%{id}' hinzugefÃ¼gt"
-  mail_body_wiki_content_added: "Die Wiki-Seite '%{id}' wurde von %{author} hinzugefÃ¼gt."
-  mail_subject_wiki_content_updated: "Wiki-Seite '%{id}' erfolgreich aktualisiert"
-  mail_body_wiki_content_updated: "Die Wiki-Seite '%{id}' wurde von %{author} aktualisiert."
-
-  gui_validation_error: 1 Fehler
-  gui_validation_error_plural: "%{count} Fehler"
-
-  field_name: Name
-  field_description: Beschreibung
-  field_summary: Zusammenfassung
-  field_is_required: Erforderlich
-  field_firstname: Vorname
-  field_lastname: Nachname
-  field_mail: E-Mail
-  field_filename: Datei
-  field_filesize: GrÃ¶ÃŸe
-  field_downloads: Downloads
-  field_author: Autor
-  field_created_on: Angelegt
-  field_updated_on: Aktualisiert
-  field_field_format: Format
-  field_is_for_all: FÃ¼r alle Projekte
-  field_possible_values: MÃ¶gliche Werte
-  field_regexp: RegulÃ¤rer Ausdruck
-  field_min_length: Minimale LÃ¤nge
-  field_max_length: Maximale LÃ¤nge
-  field_value: Wert
-  field_category: Kategorie
-  field_title: Titel
-  field_project: Projekt
-  field_issue: Ticket
-  field_status: Status
-  field_notes: Kommentare
-  field_is_closed: Ticket geschlossen
-  field_is_default: Standardeinstellung
-  field_tracker: Tracker
-  field_subject: Thema
-  field_due_date: Abgabedatum
-  field_assigned_to: Zugewiesen an
-  field_priority: PrioritÃ¤t
-  field_fixed_version: Zielversion
-  field_user: Benutzer
-  field_principal: Auftraggeber
-  field_role: Rolle
-  field_homepage: Projekt-Homepage
-  field_is_public: Ã–ffentlich
-  field_parent: Unterprojekt von
-  field_is_in_roadmap: In der Roadmap anzeigen
-  field_login: Mitgliedsname
-  field_mail_notification: Mailbenachrichtigung
-  field_admin: Administrator
-  field_last_login_on: Letzte Anmeldung
-  field_language: Sprache
-  field_effective_date: Datum
-  field_password: Kennwort
-  field_new_password: Neues Kennwort
-  field_password_confirmation: BestÃ¤tigung
-  field_version: Version
-  field_type: Typ
-  field_host: Host
-  field_port: Port
-  field_account: Konto
-  field_base_dn: Base DN
-  field_attr_login: Mitgliedsname-Attribut
-  field_attr_firstname: Vorname-Attribut
-  field_attr_lastname: Name-Attribut
-  field_attr_mail: E-Mail-Attribut
-  field_onthefly: On-the-fly-Benutzererstellung
-  field_start_date: Beginn
-  field_done_ratio: "% erledigt"
-  field_auth_source: Authentifizierungs-Modus
-  field_hide_mail: E-Mail-Adresse nicht anzeigen
-  field_comments: Kommentar
-  field_url: URL
-  field_start_page: Hauptseite
-  field_subproject: Unterprojekt von
-  field_hours: Stunden
-  field_activity: AktivitÃ¤t
-  field_spent_on: Datum
-  field_identifier: Kennung
-  field_is_filter: Als Filter benutzen
-  field_issue_to: ZugehÃ¶riges Ticket
-  field_delay: Pufferzeit
-  field_assignable: Tickets kÃ¶nnen dieser Rolle zugewiesen werden
-  field_redirect_existing_links: Existierende Links umleiten
-  field_estimated_hours: GeschÃ¤tzter Aufwand
-  field_column_names: Spalten
-  field_time_entries: Logzeit
-  field_time_zone: Zeitzone
-  field_searchable: Durchsuchbar
-  field_default_value: Standardwert
-  field_comments_sorting: Kommentare anzeigen
-  field_parent_title: Ãœbergeordnete Seite
-  field_editable: Bearbeitbar
-  field_watcher: Beobachter
-  field_identity_url: OpenID-URL
-  field_content: Inhalt
-  field_group_by: Gruppiere Ergebnisse nach
-  field_sharing: Gemeinsame Verwendung
-  field_parent_issue: Ãœbergeordnete Aufgabe
-
-  setting_app_title: Applikations-Titel
-  setting_app_subtitle: Applikations-Untertitel
-  setting_welcome_text: Willkommenstext
-  setting_default_language: Default-Sprache
-  setting_login_required: Authentifizierung erforderlich
-  setting_self_registration: Anmeldung ermÃ¶glicht
-  setting_attachment_max_size: Max. DateigrÃ¶ÃŸe
-  setting_issues_export_limit: Max. Anzahl Tickets bei CSV/PDF-Export
-  setting_mail_from: E-Mail-Absender
-  setting_bcc_recipients: E-Mails als Blindkopie (BCC) senden
-  setting_plain_text_mail: Nur reinen Text (kein HTML) senden
-  setting_host_name: Hostname
-  setting_text_formatting: Textformatierung
-  setting_wiki_compression: Wiki-Historie komprimieren
-  setting_feeds_limit: Max. Anzahl EintrÃ¤ge pro Atom-Feed
-  setting_default_projects_public: Neue Projekte sind standardmÃ¤ÃŸig Ã¶ffentlich
-  setting_autofetch_changesets: Changesets automatisch abrufen
-  setting_sys_api_enabled: Webservice zur Verwaltung der Projektarchive benutzen
-  setting_commit_ref_keywords: SchlÃ¼sselwÃ¶rter (Beziehungen)
-  setting_commit_fix_keywords: SchlÃ¼sselwÃ¶rter (Status)
-  setting_autologin: Automatische Anmeldung
-  setting_date_format: Datumsformat
-  setting_time_format: Zeitformat
-  setting_cross_project_issue_relations: Ticket-Beziehungen zwischen Projekten erlauben
-  setting_issue_list_default_columns: Default-Spalten in der Ticket-Auflistung
-  setting_emails_footer: E-Mail-FuÃŸzeile
-  setting_protocol: Protokoll
-  setting_per_page_options: Objekte pro Seite
-  setting_user_format: Benutzer-Anzeigeformat
-  setting_activity_days_default: Anzahl Tage pro Seite der Projekt-AktivitÃ¤t
-  setting_display_subprojects_issues: Tickets von Unterprojekten im Hauptprojekt anzeigen
-  setting_enabled_scm: Aktivierte Versionskontrollsysteme
-  setting_mail_handler_body_delimiters: "Schneide E-Mails nach einer dieser Zeilen ab"
-  setting_mail_handler_api_enabled: Abruf eingehender E-Mails aktivieren
-  setting_mail_handler_api_key: API-SchlÃ¼ssel
-  setting_sequential_project_identifiers: Fortlaufende Projektkennungen generieren
-  setting_gravatar_enabled: Gravatar-Benutzerbilder benutzen
-  setting_gravatar_default: Standard-Gravatar-Bild
-  setting_diff_max_lines_displayed: Maximale Anzahl anzuzeigender Diff-Zeilen
-  setting_file_max_size_displayed: Maximale GrÃ¶ÃŸe inline angezeigter Textdateien
-  setting_repository_log_display_limit: Maximale Anzahl anzuzeigender Revisionen in der Historie einer Datei
-  setting_openid: Erlaube OpenID-Anmeldung und -Registrierung
-  setting_password_min_length: MindestlÃ¤nge des Kennworts
-  setting_new_project_user_role_id: Rolle, die einem Nicht-Administrator zugeordnet wird, der ein Projekt erstellt
-  setting_default_projects_modules: StandardmÃ¤ÃŸig aktivierte Module fÃ¼r neue Projekte
-  setting_issue_done_ratio: Berechne den Ticket-Fortschritt mittels
-  setting_issue_done_ratio_issue_field: Ticket-Feld %-erledigt
-  setting_issue_done_ratio_issue_status: Ticket-Status
-  setting_start_of_week: Wochenanfang
-  setting_rest_api_enabled: REST-Schnittstelle aktivieren
-  setting_cache_formatted_text: Formatierten Text im Cache speichern
-
-  permission_add_project: Projekt erstellen
-  permission_add_subprojects: Unterprojekte erstellen
-  permission_edit_project: Projekt bearbeiten
-  permission_select_project_modules: Projektmodule auswÃ¤hlen
-  permission_manage_members: Mitglieder verwalten
-  permission_manage_project_activities: AktivitÃ¤ten (Zeiterfassung) verwalten
-  permission_manage_versions: Versionen verwalten
-  permission_manage_categories: Ticket-Kategorien verwalten
-  permission_view_issues: Tickets anzeigen
-  permission_add_issues: Tickets hinzufÃ¼gen
-  permission_edit_issues: Tickets bearbeiten
-  permission_manage_issue_relations: Ticket-Beziehungen verwalten
-  permission_add_issue_notes: Kommentare hinzufÃ¼gen
-  permission_edit_issue_notes: Kommentare bearbeiten
-  permission_edit_own_issue_notes: Eigene Kommentare bearbeiten
-  permission_move_issues: Tickets verschieben
-  permission_delete_issues: Tickets lÃ¶schen
-  permission_manage_public_queries: Ã–ffentliche Filter verwalten
-  permission_save_queries: Filter speichern
-  permission_view_gantt: Gantt-Diagramm ansehen
-  permission_view_calendar: Kalender ansehen
-  permission_view_issue_watchers: Liste der Beobachter ansehen
-  permission_add_issue_watchers: Beobachter hinzufÃ¼gen
-  permission_delete_issue_watchers: Beobachter lÃ¶schen
-  permission_log_time: AufwÃ¤nde buchen
-  permission_view_time_entries: Gebuchte AufwÃ¤nde ansehen
-  permission_edit_time_entries: Gebuchte AufwÃ¤nde bearbeiten
-  permission_edit_own_time_entries: Selbst gebuchte AufwÃ¤nde bearbeiten
-  permission_manage_news: News verwalten
-  permission_comment_news: News kommentieren
-  permission_manage_documents: Dokumente verwalten
-  permission_view_documents: Dokumente ansehen
-  permission_manage_files: Dateien verwalten
-  permission_view_files: Dateien ansehen
-  permission_manage_wiki: Wiki verwalten
-  permission_rename_wiki_pages: Wiki-Seiten umbenennen
-  permission_delete_wiki_pages: Wiki-Seiten lÃ¶schen
-  permission_view_wiki_pages: Wiki ansehen
-  permission_view_wiki_edits: Wiki-Versionsgeschichte ansehen
-  permission_edit_wiki_pages: Wiki-Seiten bearbeiten
-  permission_delete_wiki_pages_attachments: AnhÃ¤nge lÃ¶schen
-  permission_protect_wiki_pages: Wiki-Seiten schÃ¼tzen
-  permission_manage_repository: Projektarchiv verwalten
-  permission_browse_repository: Projektarchiv ansehen
-  permission_view_changesets: Changesets ansehen
-  permission_commit_access: Commit-Zugriff (Ã¼ber WebDAV)
-  permission_manage_boards: Foren verwalten
-  permission_view_messages: ForenbeitrÃ¤ge ansehen
-  permission_add_messages: ForenbeitrÃ¤ge hinzufÃ¼gen
-  permission_edit_messages: ForenbeitrÃ¤ge bearbeiten
-  permission_edit_own_messages: Eigene ForenbeitrÃ¤ge bearbeiten
-  permission_delete_messages: ForenbeitrÃ¤ge lÃ¶schen
-  permission_delete_own_messages: Eigene ForenbeitrÃ¤ge lÃ¶schen
-  permission_export_wiki_pages: Wiki-Seiten exportieren
-  permission_manage_subtasks: Unteraufgaben verwalten
-
-  project_module_issue_tracking: Ticket-Verfolgung
-  project_module_time_tracking: Zeiterfassung
-  project_module_news: News
-  project_module_documents: Dokumente
-  project_module_files: Dateien
-  project_module_wiki: Wiki
-  project_module_repository: Projektarchiv
-  project_module_boards: Foren
-  project_module_calendar: Kalender
-  project_module_gantt: Gantt
-  
-  label_user: Benutzer
-  label_user_plural: Benutzer
-  label_user_new: Neuer Benutzer
-  label_user_anonymous: Anonym
-  label_project: Projekt
-  label_project_new: Neues Projekt
-  label_project_plural: Projekte
-  label_x_projects:
-    zero:  keine Projekte
-    one:   1 Projekt
-    other: "%{count} Projekte"
-  label_project_all: Alle Projekte
-  label_project_latest: Neueste Projekte
-  label_issue: Ticket
-  label_issue_new: Neues Ticket
-  label_issue_plural: Tickets
-  label_issue_view_all: Alle Tickets anzeigen
-  label_issues_by: "Tickets von %{value}"
-  label_issue_added: Ticket hinzugefÃ¼gt
-  label_issue_updated: Ticket aktualisiert
-  label_document: Dokument
-  label_document_new: Neues Dokument
-  label_document_plural: Dokumente
-  label_document_added: Dokument hinzugefÃ¼gt
-  label_role: Rolle
-  label_role_plural: Rollen
-  label_role_new: Neue Rolle
-  label_role_and_permissions: Rollen und Rechte
-  label_member: Mitglied
-  label_member_new: Neues Mitglied
-  label_member_plural: Mitglieder
-  label_tracker: Tracker
-  label_tracker_plural: Tracker
-  label_tracker_new: Neuer Tracker
-  label_workflow: Workflow
-  label_issue_status: Ticket-Status
-  label_issue_status_plural: Ticket-Status
-  label_issue_status_new: Neuer Status
-  label_issue_category: Ticket-Kategorie
-  label_issue_category_plural: Ticket-Kategorien
-  label_issue_category_new: Neue Kategorie
-  label_custom_field: Benutzerdefiniertes Feld
-  label_custom_field_plural: Benutzerdefinierte Felder
-  label_custom_field_new: Neues Feld
-  label_enumerations: AufzÃ¤hlungen
-  label_enumeration_new: Neuer Wert
-  label_information: Information
-  label_information_plural: Informationen
-  label_please_login: Anmelden
-  label_register: Registrieren
-  label_login_with_open_id_option: oder mit OpenID anmelden
-  label_password_lost: Kennwort vergessen
-  label_home: Hauptseite
-  label_my_page: Meine Seite
-  label_my_account: Mein Konto
-  label_my_projects: Meine Projekte
-  label_my_page_block: Bereich "Meine Seite"
-  label_administration: Administration
-  label_login: Anmelden
-  label_logout: Abmelden
-  label_help: Hilfe
-  label_reported_issues: Gemeldete Tickets
-  label_assigned_to_me_issues: Mir zugewiesen
-  label_last_login: Letzte Anmeldung
-  label_registered_on: Angemeldet am
-  label_activity: AktivitÃ¤t
-  label_overall_activity: AktivitÃ¤t aller Projekte anzeigen
-  label_user_activity: "AktivitÃ¤t von %{value}"
-  label_new: Neu
-  label_logged_as: Angemeldet als
-  label_environment: Umgebung
-  label_authentication: Authentifizierung
-  label_auth_source: Authentifizierungs-Modus
-  label_auth_source_new: Neuer Authentifizierungs-Modus
-  label_auth_source_plural: Authentifizierungs-Arten
-  label_subproject_plural: Unterprojekte
-  label_subproject_new: Neues Unterprojekt
-  label_and_its_subprojects: "%{value} und dessen Unterprojekte"
-  label_min_max_length: LÃ¤nge (Min. - Max.)
-  label_list: Liste
-  label_date: Datum
-  label_integer: Zahl
-  label_float: FlieÃŸkommazahl
-  label_boolean: Boolean
-  label_string: Text
-  label_text: Langer Text
-  label_attribute: Attribut
-  label_attribute_plural: Attribute
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
-  label_no_data: Nichts anzuzeigen
-  label_change_status: Statuswechsel
-  label_history: Historie
-  label_attachment: Datei
-  label_attachment_new: Neue Datei
-  label_attachment_delete: Anhang lÃ¶schen
-  label_attachment_plural: Dateien
-  label_file_added: Datei hinzugefÃ¼gt
-  label_report: Bericht
-  label_report_plural: Berichte
-  label_news: News
-  label_news_new: News hinzufÃ¼gen
-  label_news_plural: News
-  label_news_latest: Letzte News
-  label_news_view_all: Alle News anzeigen
-  label_news_added: News hinzugefÃ¼gt
-  label_settings: Konfiguration
-  label_overview: Ãœbersicht
-  label_version: Version
-  label_version_new: Neue Version
-  label_version_plural: Versionen
-  label_close_versions: VollstÃ¤ndige Versionen schlieÃŸen
-  label_confirmation: BestÃ¤tigung
-  label_export_to: "Auch abrufbar als:"
-  label_read: Lesen...
-  label_public_projects: Ã–ffentliche Projekte
-  label_open_issues: offen
-  label_open_issues_plural: offen
-  label_closed_issues: geschlossen
-  label_closed_issues_plural: geschlossen
-  label_x_open_issues_abbr_on_total:
-    zero:  0 offen / %{total}
-    one:   1 offen / %{total}
-    other: "%{count} offen / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 offen
-    one:   1 offen
-    other: "%{count} offen"
-  label_x_closed_issues_abbr:
-    zero:  0 geschlossen
-    one:   1 geschlossen
-    other: "%{count} geschlossen"
-  label_total: Gesamtzahl
-  label_permissions: Berechtigungen
-  label_current_status: GegenwÃ¤rtiger Status
-  label_new_statuses_allowed: Neue Berechtigungen
-  label_all: alle
-  label_none: kein
-  label_nobody: Niemand
-  label_next: Weiter
-  label_previous: ZurÃ¼ck
-  label_used_by: Benutzt von
-  label_details: Details
-  label_add_note: Kommentar hinzufÃ¼gen
-  label_per_page: Pro Seite
-  label_calendar: Kalender
-  label_months_from: Monate ab
-  label_gantt: Gantt-Diagramm
-  label_internal: Intern
-  label_last_changes: "%{count} letzte Ã„nderungen"
-  label_change_view_all: Alle Ã„nderungen anzeigen
-  label_personalize_page: Diese Seite anpassen
-  label_comment: Kommentar
-  label_comment_plural: Kommentare
-  label_x_comments:
-    zero: keine Kommentare
-    one: 1 Kommentar
-    other: "%{count} Kommentare"
-  label_comment_add: Kommentar hinzufÃ¼gen
-  label_comment_added: Kommentar hinzugefÃ¼gt
-  label_comment_delete: Kommentar lÃ¶schen
-  label_query: Benutzerdefinierte Abfrage
-  label_query_plural: Benutzerdefinierte Berichte
-  label_query_new: Neuer Bericht
-  label_filter_add: Filter hinzufÃ¼gen
-  label_filter_plural: Filter
-  label_equals: ist
-  label_not_equals: ist nicht
-  label_in_less_than: in weniger als
-  label_in_more_than: in mehr als
-  label_greater_or_equal: ">="
-  label_less_or_equal: "<="
-  label_in: an
-  label_today: heute
-  label_all_time: gesamter Zeitraum
-  label_yesterday: gestern
-  label_this_week: aktuelle Woche
-  label_last_week: vorige Woche
-  label_last_n_days: "die letzten %{count} Tage"
-  label_this_month: aktueller Monat
-  label_last_month: voriger Monat
-  label_this_year: aktuelles Jahr
-  label_date_range: Zeitraum
-  label_less_than_ago: vor weniger als
-  label_more_than_ago: vor mehr als
-  label_ago: vor
-  label_contains: enthÃ¤lt
-  label_not_contains: enthÃ¤lt nicht
-  label_day_plural: Tage
-  label_repository: Projektarchiv
-  label_repository_plural: Projektarchive
-  label_browse: Codebrowser
-  label_modification: "%{count} Ã„nderung"
-  label_modification_plural: "%{count} Ã„nderungen"
-  label_branch: Zweig
-  label_tag: Markierung
-  label_revision: Revision
-  label_revision_plural: Revisionen
-  label_revision_id: Revision %{value}
-  label_associated_revisions: ZugehÃ¶rige Revisionen
-  label_added: hinzugefÃ¼gt
-  label_modified: geÃ¤ndert
-  label_copied: kopiert
-  label_renamed: umbenannt
-  label_deleted: gelÃ¶scht
-  label_latest_revision: Aktuellste Revision
-  label_latest_revision_plural: Aktuellste Revisionen
-  label_view_revisions: Revisionen anzeigen
-  label_view_all_revisions: Alle Revisionen anzeigen
-  label_max_size: Maximale GrÃ¶ÃŸe
-  label_sort_highest: An den Anfang
-  label_sort_higher: Eins hÃ¶her
-  label_sort_lower: Eins tiefer
-  label_sort_lowest: Ans Ende
-  label_roadmap: Roadmap
-  label_roadmap_due_in: "FÃ¤llig in %{value}"
-  label_roadmap_overdue: "%{value} verspÃ¤tet"
-  label_roadmap_no_issues: Keine Tickets fÃ¼r diese Version
-  label_search: Suche
-  label_result_plural: Resultate
-  label_all_words: Alle WÃ¶rter
-  label_wiki: Wiki
-  label_wiki_edit: Wiki-Bearbeitung
-  label_wiki_edit_plural: Wiki-Bearbeitungen
-  label_wiki_page: Wiki-Seite
-  label_wiki_page_plural: Wiki-Seiten
-  label_index_by_title: Seiten nach Titel sortiert
-  label_index_by_date: Seiten nach Datum sortiert
-  label_current_version: GegenwÃ¤rtige Version
-  label_preview: Vorschau
-  label_feed_plural: Feeds
-  label_changes_details: Details aller Ã„nderungen
-  label_issue_tracking: Tickets
-  label_spent_time: Aufgewendete Zeit
-  label_overall_spent_time: Aufgewendete Zeit aller Projekte anzeigen
-  label_f_hour: "%{value} Stunde"
-  label_f_hour_plural: "%{value} Stunden"
-  label_time_tracking: Zeiterfassung
-  label_change_plural: Ã„nderungen
-  label_statistics: Statistiken
-  label_commits_per_month: Ãœbertragungen pro Monat
-  label_commits_per_author: Ãœbertragungen pro Autor
-  label_view_diff: Unterschiede anzeigen
-  label_diff_inline: einspaltig
-  label_diff_side_by_side: nebeneinander
-  label_options: Optionen
-  label_copy_workflow_from: Workflow kopieren von
-  label_permissions_report: BerechtigungsÃ¼bersicht
-  label_watched_issues: Beobachtete Tickets
-  label_related_issues: ZugehÃ¶rige Tickets
-  label_applied_status: Zugewiesener Status
-  label_loading: Lade...
-  label_relation_new: Neue Beziehung
-  label_relation_delete: Beziehung lÃ¶schen
-  label_relates_to: Beziehung mit
-  label_duplicates: Duplikat von
-  label_duplicated_by: Dupliziert durch
-  label_blocks: Blockiert
-  label_blocked_by: Blockiert durch
-  label_precedes: VorgÃ¤nger von
-  label_follows: folgt
-  label_end_to_start: Ende - Anfang
-  label_end_to_end: Ende - Ende
-  label_start_to_start: Anfang - Anfang
-  label_start_to_end: Anfang - Ende
-  label_stay_logged_in: Angemeldet bleiben
-  label_disabled: gesperrt
-  label_show_completed_versions: Abgeschlossene Versionen anzeigen
-  label_me: ich
-  label_board: Forum
-  label_board_new: Neues Forum
-  label_board_plural: Foren
-  label_board_locked: Gesperrt
-  label_board_sticky: Wichtig (immer oben)
-  label_topic_plural: Themen
-  label_message_plural: ForenbeitrÃ¤ge
-  label_message_last: Letzter Forenbeitrag
-  label_message_new: Neues Thema
-  label_message_posted: Forenbeitrag hinzugefÃ¼gt
-  label_reply_plural: Antworten
-  label_send_information: Sende Kontoinformationen zum Benutzer
-  label_year: Jahr
-  label_month: Monat
-  label_week: Woche
-  label_date_from: Von
-  label_date_to: Bis
-  label_language_based: SprachabhÃ¤ngig
-  label_sort_by: "Sortiert nach %{value}"
-  label_send_test_email: Test-E-Mail senden
-  label_feeds_access_key: RSS-ZugriffsschlÃ¼ssel
-  label_missing_feeds_access_key: Der RSS-ZugriffsschlÃ¼ssel fehlt.
-  label_feeds_access_key_created_on: "Atom-ZugriffsschlÃ¼ssel vor %{value} erstellt"
-  label_module_plural: Module
-  label_added_time_by: "Von %{author} vor %{age} hinzugefÃ¼gt"
-  label_updated_time_by: "Von %{author} vor %{age} aktualisiert"
-  label_updated_time: "Vor %{value} aktualisiert"
-  label_jump_to_a_project: Zu einem Projekt springen...
-  label_file_plural: Dateien
-  label_changeset_plural: Changesets
-  label_default_columns: Standard-Spalten
-  label_no_change_option: (Keine Ã„nderung)
-  label_bulk_edit_selected_issues: Alle ausgewÃ¤hlten Tickets bearbeiten
-  label_theme: Stil
-  label_default: Standard
-  label_search_titles_only: Nur Titel durchsuchen
-  label_user_mail_option_all: "FÃ¼r alle Ereignisse in all meinen Projekten"
-  label_user_mail_option_selected: "FÃ¼r alle Ereignisse in den ausgewÃ¤hlten Projekten..."
-  label_user_mail_no_self_notified: "Ich mÃ¶chte nicht Ã¼ber Ã„nderungen benachrichtigt werden, die ich selbst durchfÃ¼hre."
-  label_registration_activation_by_email: Kontoaktivierung durch E-Mail
-  label_registration_manual_activation: Manuelle Kontoaktivierung
-  label_registration_automatic_activation: Automatische Kontoaktivierung
-  label_display_per_page: "Pro Seite: %{value}"
-  label_age: GeÃ¤ndert vor
-  label_change_properties: Eigenschaften Ã¤ndern
-  label_general: Allgemein
-  label_more: Mehr
-  label_scm: Versionskontrollsystem
-  label_plugins: Plugins
-  label_ldap_authentication: LDAP-Authentifizierung
-  label_downloads_abbr: D/L
-  label_optional_description: Beschreibung (optional)
-  label_add_another_file: Eine weitere Datei hinzufÃ¼gen
-  label_preferences: PrÃ¤ferenzen
-  label_chronological_order: in zeitlicher Reihenfolge
-  label_reverse_chronological_order: in umgekehrter zeitlicher Reihenfolge
-  label_planning: Terminplanung
-  label_incoming_emails: Eingehende E-Mails
-  label_generate_key: Generieren
-  label_issue_watchers: Beobachter
-  label_example: Beispiel
-  label_display: Anzeige
-  label_sort: Sortierung
-  label_ascending: Aufsteigend
-  label_descending: Absteigend
-  label_date_from_to: von %{start} bis %{end}
-  label_wiki_content_added: Die Wiki-Seite wurde erfolgreich hinzugefÃ¼gt.
-  label_wiki_content_updated: Die Wiki-Seite wurde erfolgreich aktualisiert.
-  label_group: Gruppe
-  label_group_plural: Gruppen
-  label_group_new: Neue Gruppe
-  label_time_entry_plural: BenÃ¶tigte Zeit
-  label_version_sharing_none: Nicht gemeinsam verwenden
-  label_version_sharing_descendants: Mit Unterprojekten
-  label_version_sharing_hierarchy: Mit Projekthierarchie
-  label_version_sharing_tree: Mit Projektbaum
-  label_version_sharing_system: Mit allen Projekten
-  label_update_issue_done_ratios: Ticket-Fortschritt aktualisieren
-  label_copy_source: Quelle
-  label_copy_target: Ziel
-  label_copy_same_as_target: So wie das Ziel
-  label_display_used_statuses_only: Zeige nur Status an, die von diesem Tracker verwendet werden
-  label_api_access_key: API-ZugriffsschlÃ¼ssel
-  label_missing_api_access_key: Der API-ZugriffsschlÃ¼ssel fehlt.
-  label_api_access_key_created_on: Der API-ZugriffsschlÃ¼ssel wurde vor %{value} erstellt
-  label_profile: Profil
-  label_subtask_plural: Unteraufgaben
-  label_project_copy_notifications: Sende Mailbenachrichtigungen beim Kopieren des Projekts.
-  label_principal_search: "Nach Benutzer oder Gruppe suchen:"
-  label_user_search: "Nach Benutzer suchen:"
-  
-  button_login: Anmelden
-  button_submit: OK
-  button_save: Speichern
-  button_check_all: Alles auswÃ¤hlen
-  button_uncheck_all: Alles abwÃ¤hlen
-  button_delete: LÃ¶schen
-  button_create: Anlegen
-  button_create_and_continue: Anlegen und weiter
-  button_test: Testen
-  button_edit: Bearbeiten
-  button_edit_associated_wikipage: "ZugehÃ¶rige Wikiseite bearbeiten: %{page_title}"
-  button_add: HinzufÃ¼gen
-  button_change: Wechseln
-  button_apply: Anwenden
-  button_clear: ZurÃ¼cksetzen
-  button_lock: Sperren
-  button_unlock: Entsperren
-  button_download: Download
-  button_list: Liste
-  button_view: Anzeigen
-  button_move: Verschieben
-  button_move_and_follow: Verschieben und Ticket anzeigen
-  button_back: ZurÃ¼ck
-  button_cancel: Abbrechen
-  button_activate: Aktivieren
-  button_sort: Sortieren
-  button_log_time: Aufwand buchen
-  button_rollback: Auf diese Version zurÃ¼cksetzen
-  button_watch: Beobachten
-  button_unwatch: Nicht beobachten
-  button_reply: Antworten
-  button_archive: Archivieren
-  button_unarchive: Entarchivieren
-  button_reset: ZurÃ¼cksetzen
-  button_rename: Umbenennen
-  button_change_password: Kennwort Ã¤ndern
-  button_copy: Kopieren
-  button_copy_and_follow: Kopieren und Ticket anzeigen
-  button_annotate: Annotieren
-  button_update: Bearbeiten
-  button_configure: Konfigurieren
-  button_quote: Zitieren
-  button_duplicate: Duplizieren
-  button_show: Anzeigen
-  
-  status_active: aktiv
-  status_registered: angemeldet
-  status_locked: gesperrt
-  
-  version_status_open: offen
-  version_status_locked: gesperrt
-  version_status_closed: abgeschlossen
-
-  field_active: Aktiv
-  
-  text_select_mail_notifications: Bitte wÃ¤hlen Sie die Aktionen aus, fÃ¼r die eine Mailbenachrichtigung gesendet werden soll.
-  text_regexp_info: z. B. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 heiÃŸt keine BeschrÃ¤nkung
-  text_project_destroy_confirmation: Sind Sie sicher, dass sie das Projekt lÃ¶schen wollen?
-  text_subprojects_destroy_warning: "Dessen Unterprojekte (%{value}) werden ebenfalls gelÃ¶scht."
-  text_workflow_edit: Workflow zum Bearbeiten auswÃ¤hlen
-  text_are_you_sure: Sind Sie sicher?
-  text_are_you_sure_with_children: "LÃ¶sche Aufgabe und alle Unteraufgaben?"
-  text_journal_changed: "%{label} wurde von %{old} zu %{new} geÃ¤ndert"
-  text_journal_set_to: "%{label} wurde auf %{value} gesetzt"
-  text_journal_deleted: "%{label} %{old} wurde gelÃ¶scht"
-  text_journal_added: "%{label} %{value} wurde hinzugefÃ¼gt"
-  text_tip_issue_begin_day: Aufgabe, die an diesem Tag beginnt
-  text_tip_issue_end_day: Aufgabe, die an diesem Tag endet
-  text_tip_issue_begin_end_day: Aufgabe, die an diesem Tag beginnt und endet
-  text_project_identifier_info: 'Kleinbuchstaben (a-z), Ziffern und Bindestriche erlaubt.<br />Einmal gespeichert, kann die Kennung nicht mehr geÃ¤ndert werden.'
-  text_caracters_maximum: "Max. %{count} Zeichen."
-  text_caracters_minimum: "Muss mindestens %{count} Zeichen lang sein."
-  text_length_between: "LÃ¤nge zwischen %{min} und %{max} Zeichen."
-  text_tracker_no_workflow: Kein Workflow fÃ¼r diesen Tracker definiert.
-  text_unallowed_characters: Nicht erlaubte Zeichen
-  text_comma_separated: Mehrere Werte erlaubt (durch Komma getrennt).
-  text_line_separated: Mehrere Werte sind erlaubt (eine Zeile pro Wert).
-  text_issues_ref_in_commit_messages: Ticket-Beziehungen und -Status in Commit-Log-Meldungen
-  text_issue_added: "Ticket %{id} wurde erstellt von %{author}."
-  text_issue_updated: "Ticket %{id} wurde aktualisiert von %{author}."
-  text_wiki_destroy_confirmation: Sind Sie sicher, dass Sie dieses Wiki mit sÃ¤mtlichem Inhalt lÃ¶schen mÃ¶chten?
-  text_issue_category_destroy_question: "Einige Tickets (%{count}) sind dieser Kategorie zugeodnet. Was mÃ¶chten Sie tun?"
-  text_issue_category_destroy_assignments: Kategorie-Zuordnung entfernen
-  text_issue_category_reassign_to: Tickets dieser Kategorie zuordnen
-  text_user_mail_option: "FÃ¼r nicht ausgewÃ¤hlte Projekte werden Sie nur Benachrichtigungen fÃ¼r Dinge erhalten, die Sie beobachten oder an denen Sie beteiligt sind (z. B. Tickets, deren Autor Sie sind oder die Ihnen zugewiesen sind)."
-  text_no_configuration_data: "Rollen, Tracker, Ticket-Status und Workflows wurden noch nicht konfiguriert.\nEs ist sehr zu empfehlen, die Standard-Konfiguration zu laden. Sobald sie geladen ist, kÃ¶nnen Sie sie abÃ¤ndern."
-  text_load_default_configuration: Standard-Konfiguration laden
-  text_status_changed_by_changeset: "Status geÃ¤ndert durch Changeset %{value}."
-  text_issues_destroy_confirmation: 'Sind Sie sicher, dass Sie die ausgewÃ¤hlten Tickets lÃ¶schen mÃ¶chten?'
-  text_select_project_modules: 'Bitte wÃ¤hlen Sie die Module aus, die in diesem Projekt aktiviert sein sollen:'
-  text_default_administrator_account_changed: Administrator-Kennwort geÃ¤ndert
-  text_file_repository_writable: Verzeichnis fÃ¼r Dateien beschreibbar
-  text_plugin_assets_writable: Verzeichnis fÃ¼r Plugin-Assets beschreibbar
-  text_rmagick_available: RMagick verfÃ¼gbar (optional)
-  text_destroy_time_entries_question: Es wurden bereits %{hours} Stunden auf dieses Ticket gebucht. Was soll mit den AufwÃ¤nden geschehen?
-  text_destroy_time_entries: Gebuchte AufwÃ¤nde lÃ¶schen
-  text_assign_time_entries_to_project: Gebuchte AufwÃ¤nde dem Projekt zuweisen
-  text_reassign_time_entries: 'Gebuchte AufwÃ¤nde diesem Ticket zuweisen:'
-  text_user_wrote: "%{value} schrieb:"
-  text_enumeration_destroy_question: "%{count} Objekt(e) sind diesem Wert zugeordnet."
-  text_enumeration_category_reassign_to: 'Die Objekte stattdessen diesem Wert zuordnen:'
-  text_email_delivery_not_configured: "Der SMTP-Server ist nicht konfiguriert und Mailbenachrichtigungen sind ausgeschaltet.\nNehmen Sie die Einstellungen fÃ¼r Ihren SMTP-Server in config/configuration.yml vor und starten Sie die Applikation neu."
-  text_repository_usernames_mapping: "Bitte legen Sie die Zuordnung der Redmine-Benutzer zu den Benutzernamen der Commit-Log-Meldungen des Projektarchivs fest.\nBenutzer mit identischen Redmine- und Projektarchiv-Benutzernamen oder -E-Mail-Adressen werden automatisch zugeordnet."
-  text_diff_truncated: '... Dieser Diff wurde abgeschnitten, weil er die maximale Anzahl anzuzeigender Zeilen Ã¼berschreitet.'
-  text_custom_field_possible_values_info: 'Eine Zeile pro Wert'
-  text_wiki_page_destroy_question: "Diese Seite hat %{descendants} Unterseite(n). Was mÃ¶chten Sie tun?"
-  text_wiki_page_nullify_children: Verschiebe die Unterseiten auf die oberste Ebene
-  text_wiki_page_destroy_children: LÃ¶sche alle Unterseiten
-  text_wiki_page_reassign_children: Ordne die Unterseiten dieser Seite zu
-  text_own_membership_delete_confirmation: "Sie sind dabei, einige oder alle Ihre Berechtigungen zu entfernen. Es ist mÃ¶glich, dass Sie danach das Projekt nicht mehr ansehen oder bearbeiten dÃ¼rfen.\nSind Sie sicher, dass Sie dies tun mÃ¶chten?"
-  text_zoom_in: Zoom in
-  text_zoom_out: Zoom out
-  
-  default_role_manager: Manager
-  default_role_developer: Entwickler
-  default_role_reporter: Reporter
-  default_tracker_bug: Fehler
-  default_tracker_feature: Feature
-  default_tracker_support: UnterstÃ¼tzung
-  default_issue_status_new: Neu
-  default_issue_status_in_progress: In Bearbeitung
-  default_issue_status_resolved: GelÃ¶st
-  default_issue_status_feedback: Feedback
-  default_issue_status_closed: Erledigt
-  default_issue_status_rejected: Abgewiesen
-  default_doc_category_user: Benutzerdokumentation
-  default_doc_category_tech: Technische Dokumentation
-  default_priority_low: Niedrig
-  default_priority_normal: Normal
-  default_priority_high: Hoch
-  default_priority_urgent: Dringend
-  default_priority_immediate: Sofort
-  default_activity_design: Design
-  default_activity_development: Entwicklung
-  
-  enumeration_issue_priorities: Ticket-PrioritÃ¤ten
-  enumeration_doc_categories: Dokumentenkategorien
-  enumeration_activities: AktivitÃ¤ten (Zeiterfassung)
-  enumeration_system_activity: System-AktivitÃ¤t
-
-  field_text: Textfeld
-  label_user_mail_option_only_owner: Nur fÃ¼r Aufgaben die ich angelegt habe
-  setting_default_notification_option: Standard Benachrichtigungsoptionen
-  label_user_mail_option_only_my_events: Nur fÃ¼r Aufgaben die ich beobachte oder an welchen ich mitarbeite
-  label_user_mail_option_only_assigned: Nur fÃ¼r Aufgaben fÃ¼r die ich zustÃ¤ndig bin.
-  notice_not_authorized_archived_project: Das Projekt wurde archiviert und ist daher nicht nicht verfÃ¼gbar.
-  label_user_mail_option_none: keine Ereignisse
-  field_member_of_group: ZustÃ¤ndigkeitsgruppe
-  field_assigned_to_role: ZustÃ¤ndigkeitsrolle
-  field_visible: Sichtbar
-  setting_emails_header: E-Mail Betreffzeile
-  setting_commit_logtime_activity_id: AktivitÃ¤t fÃ¼r die Zeiterfassung
-  text_time_logged_by_changeset: Angewendet in Changeset %{value}.
-  setting_commit_logtime_enabled: Aktiviere Zeitlogging
-  notice_gantt_chart_truncated: Die Grafik ist unvollstÃ¤ndig, da das Maximum der anzeigbaren Aufgaben Ã¼berschritten wurde (%{max})
-  setting_gantt_items_limit: Maximale Anzahl von Aufgaben die im Gantt-Chart angezeigt werden.
-  field_warn_on_leaving_unsaved: vor dem Verlassen einer Seite mit ungesichertem Text im Editor warnen
-  text_warn_on_leaving_unsaved: Die aktuellen Ã„nderungen gehen verloren, wenn Sie diese Seite verlassen.
-  label_my_queries: Meine eigenen Abfragen
-  text_journal_changed_no_detail: "%{label} aktualisiert"
-  label_news_comment_added: Kommentar zu einer News hinzugefÃ¼gt
-  button_expand_all: Alle ausklappen
-  button_collapse_all: Alle einklappen
-  label_additional_workflow_transitions_for_assignee: ZusÃ¤tzliche Berechtigungen wenn der Benutzer der Zugewiesene ist
-  label_additional_workflow_transitions_for_author: ZusÃ¤tzliche Berechtigungen wenn der Benutzer der Autor ist
-  label_bulk_edit_selected_time_entries: AusgewÃ¤hlte ZeitaufwÃ¤nde bearbeiten
-  text_time_entries_destroy_confirmation: Sind Sie sicher, dass Sie die ausgewÃ¤hlten ZeitaufwÃ¤nde lÃ¶schen mÃ¶chten?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Nichtmitglied
-  label_issue_note_added: Notiz hinzugefÃ¼gt
-  label_issue_status_updated: Status aktualisiert
-  label_issue_priority_updated: PrioritÃ¤t aktualisiert
-  label_issues_visibility_own: Tickets die folgender User erstellt hat oder die ihm zugewiesen sind
-  field_issues_visibility: Ticket Sichtbarkeit
-  label_issues_visibility_all: Alle Tickets
-  permission_set_own_issues_private: Eigene Tickets privat oder Ã¶ffentlich markieren
-  field_is_private: Privat
-  permission_set_issues_private: Tickets privat oder Ã¶ffentlich markieren
-  label_issues_visibility_public: Alle Ã¶ffentlichen Tickets
-  text_issues_destroy_descendants_confirmation: Dies wird auch %{count} Unteraufgabe/n lÃ¶schen.
-  field_commit_logs_encoding: Kodierung der Commit-Log-Meldungen
-  field_scm_path_encoding: Pfad Kodierung
-  text_scm_path_encoding_note: "Standard: UTF-8"
-  field_path_to_repository: Pfad zum repository
-  field_root_directory: Wurzelverzeichnis
-  field_cvs_module: Modul
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Lokales repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Kommando
-  text_scm_command_version: Version
-  label_git_report_last_commit: Bericht des letzten Commits fÃ¼r Dateien und Verzeichnisse
-  text_scm_config: Die SCM-Kommandos kÃ¶nnen in der in config/configuration.yml konfiguriert werden. Redmine muss anschlieÃŸend neu gestartet werden.
-  text_scm_command_not_available: Scm Kommando ist nicht verfÃ¼gbar. Bitte prÃ¼fen Sie die Einstellungen im Administrationspanel.
-
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-
-  description_filter: Filter
-  description_search: Suchfeld
-  description_choose_project: Projekte
-  description_project_scope: Suchbereich
-  description_notes: Kommentare
-  description_message_content: Nachrichteninhalt
-  description_query_sort_criteria_attribute: Sortierattribut
-  description_query_sort_criteria_direction: Sortierrichtung
-  description_user_mail_notification: Mailbenachrichtigungseinstellung
-  description_available_columns: VerfÃ¼gbare Spalten
-  description_selected_columns: AusgewÃ¤hlte Spalten
-  description_issue_category_reassign: Neue Kategorie wÃ¤hlen
-  description_wiki_subpages_reassign: Neue Elternseite wÃ¤hlen
-  description_date_range_list: Zeitraum aus einer Liste wÃ¤hlen
-  description_date_range_interval: Zeitraum durch Start- und Enddatum festlegen
-  description_date_from: Startdatum eintragen
-  description_date_to: Enddatum eintragen
-
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/de/de71f387d0c606eebf684b499bd4901c9d91a85f.svn-base
--- a/.svn/pristine/de/de71f387d0c606eebf684b499bd4901c9d91a85f.svn-base
+++ /dev/null
@@ -1,174 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class IssueMovesControllerTest < ActionController::TestCase
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :journals, :journal_details
-
-  def setup
-    User.current = nil
-  end
-
-  def test_get_issue_moves_new
-    @request.session[:user_id] = 2
-    get :new, :id => 1
-
-    assert_tag :tag => 'option', :content => 'eCookbook',
-                                 :attributes => { :value => '1', :selected => 'selected' }
-    %w(new_tracker_id status_id priority_id assigned_to_id).each do |field|
-      assert_tag :tag => 'option', :content => '(No change)', :attributes => { :value => '' },
-                                   :parent => {:tag => 'select', :attributes => {:id => field}}
-      assert_no_tag :tag => 'option', :attributes => {:selected => 'selected'},
-                                      :parent => {:tag => 'select', :attributes => {:id => field}}
-    end
-
-    # Be sure we don't include inactive enumerations
-    assert ! IssuePriority.find(15).active?
-    assert_no_tag :option, :attributes => {:value => '15'},
-                           :parent => {:tag => 'select', :attributes => {:id => 'priority_id'} }
-  end
-
-  def test_create_one_issue_to_another_project
-    @request.session[:user_id] = 2
-    post :create, :id => 1, :new_project_id => 2, :tracker_id => '', :assigned_to_id => '', :status_id => '', :start_date => '', :due_date => ''
-    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
-    assert_equal 2, Issue.find(1).project_id
-  end
-
-  def test_create_one_issue_to_another_project_should_follow_when_needed
-    @request.session[:user_id] = 2
-    post :create, :id => 1, :new_project_id => 2, :follow => '1'
-    assert_redirected_to '/issues/1'
-  end
-
-  def test_bulk_create_to_another_project
-    @request.session[:user_id] = 2
-    post :create, :ids => [1, 2], :new_project_id => 2
-    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
-    # Issues moved to project 2
-    assert_equal 2, Issue.find(1).project_id
-    assert_equal 2, Issue.find(2).project_id
-    # No tracker change
-    assert_equal 1, Issue.find(1).tracker_id
-    assert_equal 2, Issue.find(2).tracker_id
-  end
-
-  def test_bulk_create_to_another_tracker
-    @request.session[:user_id] = 2
-    post :create, :ids => [1, 2], :new_tracker_id => 2
-    assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
-    assert_equal 2, Issue.find(1).tracker_id
-    assert_equal 2, Issue.find(2).tracker_id
-  end
-
-  context "#create via bulk move" do
-    setup do
-      @request.session[:user_id] = 2
-    end
-
-    should "allow changing the issue priority" do
-      post :create, :ids => [1, 2], :priority_id => 6
-
-      assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
-      assert_equal 6, Issue.find(1).priority_id
-      assert_equal 6, Issue.find(2).priority_id
-
-    end
-
-    should "allow adding a note when moving" do
-      post :create, :ids => [1, 2], :notes => 'Moving two issues'
-
-      assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
-      assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
-      assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
-
-    end
-
-  end
-
-  def test_bulk_copy_to_another_project
-    @request.session[:user_id] = 2
-    assert_difference 'Issue.count', 2 do
-      assert_no_difference 'Project.find(1).issues.count' do
-        post :create, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}
-      end
-    end
-    assert_redirected_to '/projects/ecookbook/issues'
-  end
-
-  context "#create via bulk copy" do
-    should "allow not changing the issue's attributes" do
-      @request.session[:user_id] = 2
-      issue_before_move = Issue.find(1)
-      assert_difference 'Issue.count', 1 do
-        assert_no_difference 'Project.find(1).issues.count' do
-          post :create, :ids => [1], :new_project_id => 2,
-               :copy_options => {:copy => '1'}, :new_tracker_id => '',
-               :assigned_to_id => '', :status_id => '',
-               :start_date => '', :due_date => ''
-        end
-      end
-      issue_after_move = Issue.first(:order => 'id desc', :conditions => {:project_id => 2})
-      assert_equal issue_before_move.tracker_id, issue_after_move.tracker_id
-      assert_equal issue_before_move.status_id, issue_after_move.status_id
-      assert_equal issue_before_move.assigned_to_id, issue_after_move.assigned_to_id
-    end
-
-    should "allow changing the issue's attributes" do
-      # Fixes random test failure with Mysql
-      # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
-      # doesn't return the expected results
-      Issue.delete_all("project_id=2")
-
-      @request.session[:user_id] = 2
-      assert_difference 'Issue.count', 2 do
-        assert_no_difference 'Project.find(1).issues.count' do
-          post :create, :ids => [1, 2], :new_project_id => 2,
-               :copy_options => {:copy => '1'}, :new_tracker_id => '',
-               :assigned_to_id => 4, :status_id => 3,
-               :start_date => '2009-12-01', :due_date => '2009-12-31'
-        end
-      end
-
-      copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
-      assert_equal 2, copied_issues.size
-      copied_issues.each do |issue|
-        assert_equal 2, issue.project_id, "Project is incorrect"
-        assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
-        assert_equal 3, issue.status_id, "Status is incorrect"
-        assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
-        assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
-      end
-    end
-
-    should "allow adding a note when copying" do
-      @request.session[:user_id] = 2
-      assert_difference 'Issue.count', 1 do
-        post :create, :ids => [1], :copy_options => {:copy => '1'},
-             :notes => 'Copying one issue', :new_tracker_id => '',
-             :assigned_to_id => 4, :status_id => 3,
-             :start_date => '2009-12-01', :due_date => '2009-12-31'
-      end
-
-      issue = Issue.first(:order => 'id DESC')
-      assert_equal 1, issue.journals.size
-      journal = issue.journals.first
-      assert_equal 0, journal.details.size
-      assert_equal 'Copying one issue', journal.notes
-    end
-  end
-
-  def test_copy_to_another_project_should_follow_when_needed
-    @request.session[:user_id] = 2
-    post :create, :ids => [1], :new_project_id => 2, :copy_options => {:copy => '1'}, :follow => '1'
-    issue = Issue.first(:order => 'id DESC')
-    assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/de/deb332748ae5865ff56ca20b49648024004688b4.svn-base
--- /dev/null
+++ b/.svn/pristine/de/deb332748ae5865ff56ca20b49648024004688b4.svn-base
@@ -0,0 +1,56 @@
+class CreateJournals < ActiveRecord::Migration
+
+  # model removed, but needed for data migration
+  class IssueHistory < ActiveRecord::Base; belongs_to :issue; end
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    create_table :journals, :force => true do |t|
+      t.column "journalized_id", :integer, :default => 0, :null => false
+      t.column "journalized_type", :string, :limit => 30, :default => "", :null => false
+      t.column "user_id", :integer, :default => 0, :null => false
+      t.column "notes", :text
+      t.column "created_on", :datetime, :null => false
+    end
+    create_table :journal_details, :force => true do |t|
+      t.column "journal_id", :integer, :default => 0, :null => false
+      t.column "property", :string, :limit => 30, :default => "", :null => false
+      t.column "prop_key", :string, :limit => 30, :default => "", :null => false
+      t.column "old_value", :string
+      t.column "value", :string
+    end
+
+    # indexes
+    add_index "journals", ["journalized_id", "journalized_type"], :name => "journals_journalized_id"
+    add_index "journal_details", ["journal_id"], :name => "journal_details_journal_id"
+
+    Permission.create :controller => "issues", :action => "history", :description => "label_history", :sort => 1006, :is_public => true, :mail_option => 0, :mail_enabled => 0
+
+    # data migration
+    IssueHistory.all.each {|h|
+      j = Journal.new(:journalized => h.issue, :user_id => h.author_id, :notes => h.notes, :created_on => h.created_on)
+      j.details << JournalDetail.new(:property => 'attr', :prop_key => 'status_id', :value => h.status_id)
+      j.save
+    }
+
+    drop_table :issue_histories
+  end
+
+  def self.down
+    drop_table :journal_details
+    drop_table :journals
+
+    create_table "issue_histories", :force => true do |t|
+      t.column "issue_id", :integer, :default => 0, :null => false
+      t.column "status_id", :integer, :default => 0, :null => false
+      t.column "author_id", :integer, :default => 0, :null => false
+      t.column "notes", :text, :default => ""
+      t.column "created_on", :timestamp
+    end
+
+    add_index "issue_histories", ["issue_id"], :name => "issue_histories_issue_id"
+
+    Permission.where("controller=? and action=?", 'issues', 'history').first.destroy
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/de/deb8226384e62bff3e0cb6d730d94aefe36c81a4.svn-base
--- a/.svn/pristine/de/deb8226384e62bff3e0cb6d730d94aefe36c81a4.svn-base
+++ /dev/null
@@ -1,12 +0,0 @@
-<h2><%= l(@enumeration.option_name) %>: <%=h @enumeration %></h2>
-
-<% form_tag({}) do %>
-<div class="box">
-<p><strong><%= l(:text_enumeration_destroy_question, @enumeration.objects_count) %></strong></p>
-<p><label for='reassign_to_id'><%= l(:text_enumeration_category_reassign_to) %></label>
-<%= select_tag 'reassign_to_id', ("<option>--- #{l(:actionview_instancetag_blank_option)} ---</option>" + options_from_collection_for_select(@enumerations, 'id', 'name')) %></p>
-</div>
-
-<%= submit_tag l(:button_apply) %>
-<%= link_to l(:button_cancel), :controller => 'enumerations', :action => 'index' %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/df3886ebb0000dac35671d112fc063ec223717dd.svn-base
--- a/.svn/pristine/df/df3886ebb0000dac35671d112fc063ec223717dd.svn-base
+++ /dev/null
@@ -1,78 +0,0 @@
---- !ruby/object:Gem::Specification 
-name: coderay
-version: !ruby/object:Gem::Version 
-  hash: 23
-  prerelease: 
-  segments: 
-  - 1
-  - 0
-  - 0
-  version: 1.0.0
-platform: ruby
-authors: 
-- Kornelius Kalnbach
-autorequire: 
-bindir: bin
-cert_chain: []
-
-date: 2011-09-21 00:00:00 Z
-default_executable: coderay
-dependencies: []
-
-description: Fast and easy syntax highlighting for selected languages, written in Ruby. Comes with RedCloth integration and LOC counter.
-email: 
-- murphy@rubychan.de
-executables: 
-- coderay
-extensions: []
-
-extra_rdoc_files: []
-
-files: 
-- test/functional/basic.rb
-- test/functional/examples.rb
-- test/functional/for_redcloth.rb
-- test/functional/suite.rb
-- bin/coderay
-has_rdoc: true
-homepage: http://coderay.rubychan.de
-licenses: []
-
-post_install_message: 
-rdoc_options: []
-
-require_paths: 
-- lib
-required_ruby_version: !ruby/object:Gem::Requirement 
-  none: false
-  requirements: 
-  - - ">="
-    - !ruby/object:Gem::Version 
-      hash: 59
-      segments: 
-      - 1
-      - 8
-      - 6
-      version: 1.8.6
-required_rubygems_version: !ruby/object:Gem::Requirement 
-  none: false
-  requirements: 
-  - - ">="
-    - !ruby/object:Gem::Version 
-      hash: 3
-      segments: 
-      - 0
-      version: "0"
-requirements: []
-
-rubyforge_project: coderay
-rubygems_version: 1.6.2
-signing_key: 
-specification_version: 3
-summary: Fast syntax highlighting for selected languages.
-test_files: 
-- test/functional/basic.rb
-- test/functional/examples.rb
-- test/functional/for_redcloth.rb
-- test/functional/suite.rb
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/df4288bbed742ae45b6043b135789eb3f2d620b1.svn-base
--- /dev/null
+++ b/.svn/pristine/df/df4288bbed742ae45b6043b135789eb3f2d620b1.svn-base
@@ -0,0 +1,434 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'SVG/Graph/Bar'
+require 'SVG/Graph/BarHorizontal'
+require 'digest/sha1'
+require 'redmine/scm/adapters/abstract_adapter'
+
+class ChangesetNotFound < Exception; end
+class InvalidRevisionParam < Exception; end
+
+class RepositoriesController < ApplicationController
+  menu_item :repository
+  menu_item :settings, :only => [:new, :create, :edit, :update, :destroy, :committers]
+  default_search_scope :changesets
+
+  before_filter :find_project_by_project_id, :only => [:new, :create]
+  before_filter :find_repository, :only => [:edit, :update, :destroy, :committers]
+  before_filter :find_project_repository, :except => [:new, :create, :edit, :update, :destroy, :committers]
+  before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue]
+  before_filter :authorize
+  accept_rss_auth :revisions
+
+  rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed
+
+  def new
+    scm = params[:repository_scm] || (Redmine::Scm::Base.all & Setting.enabled_scm).first
+    @repository = Repository.factory(scm)
+    @repository.is_default = @project.repository.nil?
+    @repository.project = @project
+  end
+
+  def create
+    attrs = pickup_extra_info
+    @repository = Repository.factory(params[:repository_scm])
+    @repository.safe_attributes = params[:repository]
+    if attrs[:attrs_extra].keys.any?
+      @repository.merge_extra_info(attrs[:attrs_extra])
+    end
+    @repository.project = @project
+    if request.post? && @repository.save
+      redirect_to settings_project_path(@project, :tab => 'repositories')
+    else
+      render :action => 'new'
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    attrs = pickup_extra_info
+    @repository.safe_attributes = attrs[:attrs]
+    if attrs[:attrs_extra].keys.any?
+      @repository.merge_extra_info(attrs[:attrs_extra])
+    end
+    @repository.project = @project
+    if request.put? && @repository.save
+      redirect_to settings_project_path(@project, :tab => 'repositories')
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def pickup_extra_info
+    p       = {}
+    p_extra = {}
+    params[:repository].each do |k, v|
+      if k =~ /^extra_/
+        p_extra[k] = v
+      else
+        p[k] = v
+      end
+    end
+    {:attrs => p, :attrs_extra => p_extra}
+  end
+  private :pickup_extra_info
+
+  def committers
+    @committers = @repository.committers
+    @users = @project.users
+    additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
+    @users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty?
+    @users.compact!
+    @users.sort!
+    if request.post? && params[:committers].is_a?(Hash)
+      # Build a hash with repository usernames as keys and corresponding user ids as values
+      @repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h}
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to settings_project_path(@project, :tab => 'repositories')
+    end
+  end
+
+  def destroy
+    @repository.destroy if request.delete?
+    redirect_to settings_project_path(@project, :tab => 'repositories')
+  end
+
+  def show
+    @repository.fetch_changesets if Setting.autofetch_changesets? && @path.empty?
+
+    @entries = @repository.entries(@path, @rev)
+    @changeset = @repository.find_changeset_by_name(@rev)
+    if request.xhr?
+      @entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
+    else
+      (show_error_not_found; return) unless @entries
+      @changesets = @repository.latest_changesets(@path, @rev)
+      @properties = @repository.properties(@path, @rev)
+      @repositories = @project.repositories
+      render :action => 'show'
+    end
+  end
+
+  alias_method :browse, :show
+
+  def changes
+    @entry = @repository.entry(@path, @rev)
+    (show_error_not_found; return) unless @entry
+    @changesets = @repository.latest_changesets(@path, @rev, Setting.repository_log_display_limit.to_i)
+    @properties = @repository.properties(@path, @rev)
+    @changeset = @repository.find_changeset_by_name(@rev)
+  end
+
+  def revisions
+    @changeset_count = @repository.changesets.count
+    @changeset_pages = Paginator.new @changeset_count,
+                                     per_page_option,
+                                     params['page']
+    @changesets = @repository.changesets.
+      limit(@changeset_pages.per_page).
+      offset(@changeset_pages.offset).
+      includes(:user, :repository, :parents).
+      all
+
+    respond_to do |format|
+      format.html { render :layout => false if request.xhr? }
+      format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
+    end
+  end
+
+  def raw
+    entry_and_raw(true)
+  end
+
+  def entry
+    entry_and_raw(false)
+  end
+
+  def entry_and_raw(is_raw)
+    @entry = @repository.entry(@path, @rev)
+    (show_error_not_found; return) unless @entry
+
+    # If the entry is a dir, show the browser
+    (show; return) if @entry.is_dir?
+
+    @content = @repository.cat(@path, @rev)
+    (show_error_not_found; return) unless @content
+    if is_raw ||
+         (@content.size && @content.size > Setting.file_max_size_displayed.to_i.kilobyte) ||
+         ! is_entry_text_data?(@content, @path)
+      # Force the download
+      send_opt = { :filename => filename_for_content_disposition(@path.split('/').last) }
+      send_type = Redmine::MimeType.of(@path)
+      send_opt[:type] = send_type.to_s if send_type
+      send_opt[:disposition] = (Redmine::MimeType.is_type?('image', @path) && !is_raw ? 'inline' : 'attachment')
+      send_data @content, send_opt
+    else
+      # Prevent empty lines when displaying a file with Windows style eol
+      # TODO: UTF-16
+      # Is this needs? AttachmentsController reads file simply.
+      @content.gsub!("\r\n", "\n")
+      @changeset = @repository.find_changeset_by_name(@rev)
+    end
+  end
+  private :entry_and_raw
+
+  def is_entry_text_data?(ent, path)
+    # UTF-16 contains "\x00".
+    # It is very strict that file contains less than 30% of ascii symbols
+    # in non Western Europe.
+    return true if Redmine::MimeType.is_type?('text', path)
+    # Ruby 1.8.6 has a bug of integer divisions.
+    # http://apidock.com/ruby/v1_8_6_287/String/is_binary_data%3F
+    return false if ent.is_binary_data?
+    true
+  end
+  private :is_entry_text_data?
+
+  def annotate
+    @entry = @repository.entry(@path, @rev)
+    (show_error_not_found; return) unless @entry
+
+    @annotate = @repository.scm.annotate(@path, @rev)
+    if @annotate.nil? || @annotate.empty?
+      (render_error l(:error_scm_annotate); return)
+    end
+    ann_buf_size = 0
+    @annotate.lines.each do |buf|
+      ann_buf_size += buf.size
+    end
+    if ann_buf_size > Setting.file_max_size_displayed.to_i.kilobyte
+      (render_error l(:error_scm_annotate_big_text_file); return)
+    end
+    @changeset = @repository.find_changeset_by_name(@rev)
+  end
+
+  def revision
+    respond_to do |format|
+      format.html
+      format.js {render :layout => false}
+    end
+  end
+
+  # Adds a related issue to a changeset
+  # POST /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues
+  def add_related_issue
+    @issue = @changeset.find_referenced_issue_by_id(params[:issue_id])
+    if @issue && (!@issue.visible? || @changeset.issues.include?(@issue))
+      @issue = nil
+    end
+
+    if @issue
+      @changeset.issues << @issue
+    end
+  end
+
+  # Removes a related issue from a changeset
+  # DELETE /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues/:issue_id
+  def remove_related_issue
+    @issue = Issue.visible.find_by_id(params[:issue_id])
+    if @issue
+      @changeset.issues.delete(@issue)
+    end
+  end
+
+  def diff
+    if params[:format] == 'diff'
+      @diff = @repository.diff(@path, @rev, @rev_to)
+      (show_error_not_found; return) unless @diff
+      filename = "changeset_r#{@rev}"
+      filename << "_r#{@rev_to}" if @rev_to
+      send_data @diff.join, :filename => "#{filename}.diff",
+                            :type => 'text/x-patch',
+                            :disposition => 'attachment'
+    else
+      @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
+      @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
+
+      # Save diff type as user preference
+      if User.current.logged? && @diff_type != User.current.pref[:diff_type]
+        User.current.pref[:diff_type] = @diff_type
+        User.current.preference.save
+      end
+      @cache_key = "repositories/diff/#{@repository.id}/" +
+                      Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}-#{current_language}")
+      unless read_fragment(@cache_key)
+        @diff = @repository.diff(@path, @rev, @rev_to)
+        show_error_not_found unless @diff
+      end
+
+      @changeset = @repository.find_changeset_by_name(@rev)
+      @changeset_to = @rev_to ? @repository.find_changeset_by_name(@rev_to) : nil
+      @diff_format_revisions = @repository.diff_format_revisions(@changeset, @changeset_to)
+    end
+  end
+
+  def stats
+  end
+
+  def graph
+    data = nil
+    case params[:graph]
+    when "commits_per_month"
+      data = graph_commits_per_month(@repository)
+    when "commits_per_author"
+      data = graph_commits_per_author(@repository)
+    end
+    if data
+      headers["Content-Type"] = "image/svg+xml"
+      send_data(data, :type => "image/svg+xml", :disposition => "inline")
+    else
+      render_404
+    end
+  end
+
+  private
+
+  def find_repository
+    @repository = Repository.find(params[:id])
+    @project = @repository.project
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  REV_PARAM_RE = %r{\A[a-f0-9]*\Z}i
+
+  def find_project_repository
+    @project = Project.find(params[:id])
+    if params[:repository_id].present?
+      @repository = @project.repositories.find_by_identifier_param(params[:repository_id])
+    else
+      @repository = @project.repository
+    end
+    (render_404; return false) unless @repository
+    @path = params[:path].is_a?(Array) ? params[:path].join('/') : params[:path].to_s
+    @rev = params[:rev].blank? ? @repository.default_branch : params[:rev].to_s.strip
+    @rev_to = params[:rev_to]
+
+    unless @rev.to_s.match(REV_PARAM_RE) && @rev_to.to_s.match(REV_PARAM_RE)
+      if @repository.branches.blank?
+        raise InvalidRevisionParam
+      end
+    end
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  rescue InvalidRevisionParam
+    show_error_not_found
+  end
+
+  def find_changeset
+    if @rev.present?
+      @changeset = @repository.find_changeset_by_name(@rev)
+    end
+    show_error_not_found unless @changeset
+  end
+
+  def show_error_not_found
+    render_error :message => l(:error_scm_not_found), :status => 404
+  end
+
+  # Handler for Redmine::Scm::Adapters::CommandFailed exception
+  def show_error_command_failed(exception)
+    render_error l(:error_scm_command_failed, exception.message)
+  end
+
+  def graph_commits_per_month(repository)
+    @date_to = Date.today
+    @date_from = @date_to << 11
+    @date_from = Date.civil(@date_from.year, @date_from.month, 1)
+    commits_by_day = Changeset.count(
+                          :all, :group => :commit_date,
+                          :conditions => ["repository_id = ? AND commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to])
+    commits_by_month = [0] * 12
+    commits_by_day.each {|c| commits_by_month[(@date_to.month - c.first.to_date.month) % 12] += c.last }
+
+    changes_by_day = Change.count(
+                          :all, :group => :commit_date, :include => :changeset,
+                          :conditions => ["#{Changeset.table_name}.repository_id = ? AND #{Changeset.table_name}.commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to])
+    changes_by_month = [0] * 12
+    changes_by_day.each {|c| changes_by_month[(@date_to.month - c.first.to_date.month) % 12] += c.last }
+
+    fields = []
+    12.times {|m| fields << month_name(((Date.today.month - 1 - m) % 12) + 1)}
+
+    graph = SVG::Graph::Bar.new(
+      :height => 300,
+      :width => 800,
+      :fields => fields.reverse,
+      :stack => :side,
+      :scale_integers => true,
+      :step_x_labels => 2,
+      :show_data_values => false,
+      :graph_title => l(:label_commits_per_month),
+      :show_graph_title => true
+    )
+
+    graph.add_data(
+      :data => commits_by_month[0..11].reverse,
+      :title => l(:label_revision_plural)
+    )
+
+    graph.add_data(
+      :data => changes_by_month[0..11].reverse,
+      :title => l(:label_change_plural)
+    )
+
+    graph.burn
+  end
+
+  def graph_commits_per_author(repository)
+    commits_by_author = Changeset.count(:all, :group => :committer, :conditions => ["repository_id = ?", repository.id])
+    commits_by_author.to_a.sort! {|x, y| x.last <=> y.last}
+
+    changes_by_author = Change.count(:all, :group => :committer, :include => :changeset, :conditions => ["#{Changeset.table_name}.repository_id = ?", repository.id])
+    h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o}
+
+    fields = commits_by_author.collect {|r| r.first}
+    commits_data = commits_by_author.collect {|r| r.last}
+    changes_data = commits_by_author.collect {|r| h[r.first] || 0}
+
+    fields = fields + [""]*(10 - fields.length) if fields.length<10
+    commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10
+    changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10
+
+    # Remove email adress in usernames
+    fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
+
+    graph = SVG::Graph::BarHorizontal.new(
+      :height => 400,
+      :width => 800,
+      :fields => fields,
+      :stack => :side,
+      :scale_integers => true,
+      :show_data_values => false,
+      :rotate_y_labels => false,
+      :graph_title => l(:label_commits_per_author),
+      :show_graph_title => true
+    )
+    graph.add_data(
+      :data => commits_data,
+      :title => l(:label_revision_plural)
+    )
+    graph.add_data(
+      :data => changes_data,
+      :title => l(:label_change_plural)
+    )
+    graph.burn
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/df8b371ed525f463b2814ba63c3245f1661898e6.svn-base
--- a/.svn/pristine/df/df8b371ed525f463b2814ba63c3245f1661898e6.svn-base
+++ /dev/null
@@ -1,33 +0,0 @@
-<html>
-<head>
-<style>
-body {
-  font-family: Verdana, sans-serif;
-  font-size: 0.8em;
-  color:#484848;
-}
-h1, h2, h3 { font-family: "Trebuchet MS", Verdana, sans-serif; margin: 0px; }
-h1 { font-size: 1.2em; }
-h2, h3 { font-size: 1.1em; }
-a, a:link, a:visited { color: #2A5685;}
-a:hover, a:active { color: #c61a1a; }
-a.wiki-anchor { display: none; }
-hr {
-  width: 100%;
-  height: 1px;
-  background: #ccc;
-  border: 0;
-}
-.footer {
-  font-size: 0.8em;
-  font-style: italic;
-}
-</style>
-</head>
-<body>
-<span class="header"><%= Redmine::WikiFormatting.to_html(Setting.text_formatting, Setting.emails_header) %></span>
-<%= yield %>
-<hr />
-<span class="footer"><%= Redmine::WikiFormatting.to_html(Setting.text_formatting, Setting.emails_footer) %></span>
-</body>
-</html>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/df905b0644ccdf0c1abfa3eb8cd4085be481962e.svn-base
--- a/.svn/pristine/df/df905b0644ccdf0c1abfa3eb8cd4085be481962e.svn-base
+++ /dev/null
@@ -1,41 +0,0 @@
-# The Plugin::Migrator class contains the logic to run migrations from
-# within plugin directories. The directory in which a plugin's migrations
-# should be is determined by the Plugin#migration_directory method.
-#
-# To migrate a plugin, you can simple call the migrate method (Plugin#migrate)
-# with the version number that plugin should be at. The plugin's migrations
-# will then be used to migrate up (or down) to the given version.
-#
-# For more information, see Engines::RailsExtensions::Migrations
-class Engines::Plugin::Migrator < ActiveRecord::Migrator
-
-  # We need to be able to set the 'current' engine being migrated.
-  cattr_accessor :current_plugin
-
-  class << self
-    # Runs the migrations from a plugin, up (or down) to the version given
-    def migrate_plugin(plugin, version)
-      self.current_plugin = plugin
-      return if current_version(plugin) == version
-      migrate(plugin.migration_directory, version)
-    end
-    
-    def current_version(plugin=current_plugin)
-      # Delete migrations that don't match .. to_i will work because the number comes first
-      ::ActiveRecord::Base.connection.select_values(
-        "SELECT version FROM #{schema_migrations_table_name}"
-      ).delete_if{ |v| v.match(/-#{plugin.name}/) == nil }.map(&:to_i).max || 0
-    end
-  end
-       
-  def migrated
-    sm_table = self.class.schema_migrations_table_name
-    ::ActiveRecord::Base.connection.select_values(
-      "SELECT version FROM #{sm_table}"
-    ).delete_if{ |v| v.match(/-#{current_plugin.name}/) == nil }.map(&:to_i).sort
-  end
-  
-  def record_version_state_after_migrating(version)
-    super(version.to_s + "-" + current_plugin.name)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/df9298bb3f452fa850d3a0c9bacf6b17a96855c3.svn-base
--- /dev/null
+++ b/.svn/pristine/df/df9298bb3f452fa850d3a0c9bacf6b17a96855c3.svn-base
@@ -0,0 +1,44 @@
+<div class="contextual">
+<% if User.current.allowed_to?(:manage_issue_relations, @project) %>
+  <%= toggle_link l(:button_add), 'new-relation-form', {:focus => 'relation_issue_to_id'} %>
+<% end %>
+</div>
+
+<p><strong><%=l(:label_related_issues)%></strong></p>
+
+<% if @relations.present? %>
+<form>
+<table class="list issues">
+<% @relations.each do |relation| %>
+  <% other_issue = relation.other_issue(@issue) -%>
+  <tr class="issue hascontextmenu" id="relation-<%= relation.id %>">
+  <td class="checkbox"><%= check_box_tag("ids[]", other_issue.id, false, :id => nil) %></td>
+  <td class="subject">
+    <%= l(relation.label_for(@issue)) %>
+    <%= "(#{l('datetime.distance_in_words.x_days', :count => relation.delay)})" if relation.delay && relation.delay != 0 %>
+    <%= h(other_issue.project) + ' - ' if Setting.cross_project_issue_relations? %>
+    <%= link_to_issue(other_issue, :truncate => 60) %>
+  </td>
+  <td class="status"><%=h other_issue.status.name %></td>
+  <td class="start_date"><%= format_date(other_issue.start_date) %></td>
+  <td class="due_date"><%= format_date(other_issue.due_date) %></td>
+  <td class="buttons"><%= link_to image_tag('link_break.png'),
+                                  relation_path(relation),
+                                  :remote => true,
+                                  :method => :delete,
+                                  :data => {:confirm => l(:text_are_you_sure)},
+                                  :title => l(:label_relation_delete) if User.current.allowed_to?(:manage_issue_relations, @project) %></td>
+  </tr>
+<% end %>
+</table>
+</form>
+<% end %>
+
+<%= form_for @relation, {
+                 :as => :relation, :remote => true,
+                 :url => issue_relations_path(@issue),
+                 :method => :post,
+                 :html => {:id => 'new-relation-form', :style => (@relation ? '' : 'display: none;')}
+               } do |f| %>
+<%= render :partial => 'issue_relations/form', :locals => {:f => f}%>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/df9bbf954b4f906004aaa967b48274754ad6dcd0.svn-base
--- /dev/null
+++ b/.svn/pristine/df/df9bbf954b4f906004aaa967b48274754ad6dcd0.svn-base
@@ -0,0 +1,200 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'net/ldap'
+require 'net/ldap/dn'
+require 'timeout'
+
+class AuthSourceLdap < AuthSource
+  validates_presence_of :host, :port, :attr_login
+  validates_length_of :name, :host, :maximum => 60, :allow_nil => true
+  validates_length_of :account, :account_password, :base_dn, :filter, :maximum => 255, :allow_blank => true
+  validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
+  validates_numericality_of :port, :only_integer => true
+  validates_numericality_of :timeout, :only_integer => true, :allow_blank => true
+  validate :validate_filter
+
+  before_validation :strip_ldap_attributes
+
+  def initialize(attributes=nil, *args)
+    super
+    self.port = 389 if self.port == 0
+  end
+
+  def authenticate(login, password)
+    return nil if login.blank? || password.blank?
+
+    with_timeout do
+      attrs = get_user_dn(login, password)
+      if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password)
+        logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
+        return attrs.except(:dn)
+      end
+    end
+  rescue Net::LDAP::LdapError => e
+    raise AuthSourceException.new(e.message)
+  end
+
+  # test the connection to the LDAP
+  def test_connection
+    with_timeout do
+      ldap_con = initialize_ldap_con(self.account, self.account_password)
+      ldap_con.open { }
+    end
+  rescue Net::LDAP::LdapError => e
+    raise AuthSourceException.new(e.message)
+  end
+
+  def auth_method_name
+    "LDAP"
+  end
+
+  # Returns true if this source can be searched for users
+  def searchable?
+    !account.to_s.include?("$login") && %w(login firstname lastname mail).all? {|a| send("attr_#{a}?")}
+  end
+
+  # Searches the source for users and returns an array of results
+  def search(q)
+    q = q.to_s.strip
+    return [] unless searchable? && q.present?
+
+    results = []
+    search_filter = base_filter & Net::LDAP::Filter.begins(self.attr_login, q)
+    ldap_con = initialize_ldap_con(self.account, self.account_password)
+    ldap_con.search(:base => self.base_dn,
+                    :filter => search_filter,
+                    :attributes => ['dn', self.attr_login, self.attr_firstname, self.attr_lastname, self.attr_mail],
+                    :size => 10) do |entry|
+      attrs = get_user_attributes_from_ldap_entry(entry)
+      attrs[:login] = AuthSourceLdap.get_attr(entry, self.attr_login)
+      results << attrs
+    end
+    results
+  rescue Net::LDAP::LdapError => e
+    raise AuthSourceException.new(e.message)
+  end
+
+  private
+
+  def with_timeout(&block)
+    timeout = self.timeout
+    timeout = 20 unless timeout && timeout > 0
+    Timeout.timeout(timeout) do
+      return yield
+    end
+  rescue Timeout::Error => e
+    raise AuthSourceTimeoutException.new(e.message)
+  end
+
+  def ldap_filter
+    if filter.present?
+      Net::LDAP::Filter.construct(filter)
+    end
+  rescue Net::LDAP::LdapError
+    nil
+  end
+
+  def base_filter
+    filter = Net::LDAP::Filter.eq("objectClass", "*")
+    if f = ldap_filter
+      filter = filter & f
+    end
+    filter
+  end
+
+  def validate_filter
+    if filter.present? && ldap_filter.nil?
+      errors.add(:filter, :invalid)
+    end
+  end
+
+  def strip_ldap_attributes
+    [:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr|
+      write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil?
+    end
+  end
+
+  def initialize_ldap_con(ldap_user, ldap_password)
+    options = { :host => self.host,
+                :port => self.port,
+                :encryption => (self.tls ? :simple_tls : nil)
+              }
+    options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
+    Net::LDAP.new options
+  end
+
+  def get_user_attributes_from_ldap_entry(entry)
+    {
+     :dn => entry.dn,
+     :firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
+     :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
+     :mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
+     :auth_source_id => self.id
+    }
+  end
+
+  # Return the attributes needed for the LDAP search.  It will only
+  # include the user attributes if on-the-fly registration is enabled
+  def search_attributes
+    if onthefly_register?
+      ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]
+    else
+      ['dn']
+    end
+  end
+
+  # Check if a DN (user record) authenticates with the password
+  def authenticate_dn(dn, password)
+    if dn.present? && password.present?
+      initialize_ldap_con(dn, password).bind
+    end
+  end
+
+  # Get the user's dn and any attributes for them, given their login
+  def get_user_dn(login, password)
+    ldap_con = nil
+    if self.account && self.account.include?("$login")
+      ldap_con = initialize_ldap_con(self.account.sub("$login", Net::LDAP::DN.escape(login)), password)
+    else
+      ldap_con = initialize_ldap_con(self.account, self.account_password)
+    end
+    attrs = {}
+    search_filter = base_filter & Net::LDAP::Filter.eq(self.attr_login, login)
+
+    ldap_con.search( :base => self.base_dn,
+                     :filter => search_filter,
+                     :attributes=> search_attributes) do |entry|
+
+      if onthefly_register?
+        attrs = get_user_attributes_from_ldap_entry(entry)
+      else
+        attrs = {:dn => entry.dn}
+      end
+
+      logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug?
+    end
+
+    attrs
+  end
+
+  def self.get_attr(entry, attr_name)
+    if !attr_name.blank?
+      entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/dfa4eb7ba7d6caceff9151c99aedb512ffa84738.svn-base
--- /dev/null
+++ b/.svn/pristine/df/dfa4eb7ba7d6caceff9151c99aedb512ffa84738.svn-base
@@ -0,0 +1,38 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class EnabledModule < ActiveRecord::Base
+  belongs_to :project
+
+  validates_presence_of :name
+  validates_uniqueness_of :name, :scope => :project_id
+
+  after_create :module_enabled
+
+  private
+
+  # after_create callback used to do things when a module is enabled
+  def module_enabled
+    case name
+    when 'wiki'
+      # Create a wiki with a default start page
+      if project && project.wiki.nil?
+        Wiki.create(:project => project, :start_page => 'Wiki')
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/dfae037e99ba26462449559915851052f4865887.svn-base
--- a/.svn/pristine/df/dfae037e99ba26462449559915851052f4865887.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-class <%= class_name %> < ActiveRecord::Base
-  unloadable
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/dfb3acb9226878b28e389fb4105ce64bd182e491.svn-base
--- a/.svn/pristine/df/dfb3acb9226878b28e389fb4105ce64bd182e491.svn-base
+++ /dev/null
@@ -1,385 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'cgi'
-
-module Redmine
-  module Scm
-    module Adapters
-      class CommandFailed < StandardError #:nodoc:
-      end
-
-      class AbstractAdapter #:nodoc:
-
-        # raised if scm command exited with error, e.g. unknown revision.
-        class ScmCommandAborted < CommandFailed; end
-
-        class << self
-          def client_command
-            ""
-          end
-
-          def shell_quote_command
-            if Redmine::Platform.mswin? && RUBY_PLATFORM == 'java'
-              client_command
-            else
-              shell_quote(client_command)
-            end
-          end
-
-          # Returns the version of the scm client
-          # Eg: [1, 5, 0] or [] if unknown
-          def client_version
-            []
-          end
-
-          # Returns the version string of the scm client
-          # Eg: '1.5.0' or 'Unknown version' if unknown
-          def client_version_string
-            v = client_version || 'Unknown version'
-            v.is_a?(Array) ? v.join('.') : v.to_s
-          end
-
-          # Returns true if the current client version is above
-          # or equals the given one
-          # If option is :unknown is set to true, it will return
-          # true if the client version is unknown
-          def client_version_above?(v, options={})
-            ((client_version <=> v) >= 0) || (client_version.empty? && options[:unknown])
-          end
-
-          def client_available
-            true
-          end
-
-          def shell_quote(str)
-            if Redmine::Platform.mswin?
-              '"' + str.gsub(/"/, '\\"') + '"'
-            else
-              "'" + str.gsub(/'/, "'\"'\"'") + "'"
-            end
-          end
-        end
-
-        def initialize(url, root_url=nil, login=nil, password=nil,
-                       path_encoding=nil)
-          @url = url
-          @login = login if login && !login.empty?
-          @password = (password || "") if @login
-          @root_url = root_url.blank? ? retrieve_root_url : root_url
-        end
-
-        def adapter_name
-          'Abstract'
-        end
-
-        def supports_cat?
-          true
-        end
-
-        def supports_annotate?
-          respond_to?('annotate')
-        end
-
-        def root_url
-          @root_url
-        end
-
-        def url
-          @url
-        end
-
-        def path_encoding
-          nil
-        end
-
-        # get info about the svn repository
-        def info
-          return nil
-        end
-
-        # Returns the entry identified by path and revision identifier
-        # or nil if entry doesn't exist in the repository
-        def entry(path=nil, identifier=nil)
-          parts = path.to_s.split(%r{[\/\\]}).select {|n| !n.blank?}
-          search_path = parts[0..-2].join('/')
-          search_name = parts[-1]
-          if search_path.blank? && search_name.blank?
-            # Root entry
-            Entry.new(:path => '', :kind => 'dir')
-          else
-            # Search for the entry in the parent directory
-            es = entries(search_path, identifier)
-            es ? es.detect {|e| e.name == search_name} : nil
-          end
-        end
-
-        # Returns an Entries collection
-        # or nil if the given path doesn't exist in the repository
-        def entries(path=nil, identifier=nil, options={})
-          return nil
-        end
-
-        def branches
-          return nil
-        end
-
-        def tags
-          return nil
-        end
-
-        def default_branch
-          return nil
-        end
-
-        def properties(path, identifier=nil)
-          return nil
-        end
-
-        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
-          return nil
-        end
-
-        def diff(path, identifier_from, identifier_to=nil)
-          return nil
-        end
-
-        def cat(path, identifier=nil)
-          return nil
-        end
-
-        def with_leading_slash(path)
-          path ||= ''
-          (path[0,1]!="/") ? "/#{path}" : path
-        end
-
-        def with_trailling_slash(path)
-          path ||= ''
-          (path[-1,1] == "/") ? path : "#{path}/"
-        end
-
-        def without_leading_slash(path)
-          path ||= ''
-          path.gsub(%r{^/+}, '')
-        end
-
-        def without_trailling_slash(path)
-          path ||= ''
-          (path[-1,1] == "/") ? path[0..-2] : path
-         end
-
-        def shell_quote(str)
-          self.class.shell_quote(str)
-        end
-
-      private
-        def retrieve_root_url
-          info = self.info
-          info ? info.root_url : nil
-        end
-
-        def target(path, sq=true)
-          path ||= ''
-          base = path.match(/^\//) ? root_url : url
-          str = "#{base}/#{path}".gsub(/[?<>\*]/, '')
-          if sq
-            str = shell_quote(str)
-          end
-          str
-        end
-
-        def logger
-          self.class.logger
-        end
-
-        def shellout(cmd, &block)
-          self.class.shellout(cmd, &block)
-        end
-
-        def self.logger
-          Rails.logger
-        end
-
-        def self.shellout(cmd, &block)
-          if logger && logger.debug?
-            logger.debug "Shelling out: #{strip_credential(cmd)}"
-          end
-          if Rails.env == 'development'
-            # Capture stderr when running in dev environment
-            cmd = "#{cmd} 2>>#{Rails.root}/log/scm.stderr.log"
-          end
-          begin
-            if RUBY_VERSION < '1.9'
-              mode = "r+"
-            else
-              mode = "r+:ASCII-8BIT"
-            end
-            IO.popen(cmd, mode) do |io|
-              io.close_write
-              block.call(io) if block_given?
-            end
-          ## If scm command does not exist,
-          ## Linux JRuby 1.6.2 (ruby-1.8.7-p330) raises java.io.IOException
-          ## in production environment.
-          # rescue Errno::ENOENT => e
-          rescue Exception => e
-            msg = strip_credential(e.message)
-            # The command failed, log it and re-raise
-            logmsg = "SCM command failed, "
-            logmsg += "make sure that your SCM command (e.g. svn) is "
-            logmsg += "in PATH (#{ENV['PATH']})\n"
-            logmsg += "You can configure your scm commands in config/configuration.yml.\n"
-            logmsg += "#{strip_credential(cmd)}\n"
-            logmsg += "with: #{msg}"
-            logger.error(logmsg)
-            raise CommandFailed.new(msg)
-          end
-        end
-
-        # Hides username/password in a given command
-        def self.strip_credential(cmd)
-          q = (Redmine::Platform.mswin? ? '"' : "'")
-          cmd.to_s.gsub(/(\-\-(password|username))\s+(#{q}[^#{q}]+#{q}|[^#{q}]\S+)/, '\\1 xxxx')
-        end
-
-        def strip_credential(cmd)
-          self.class.strip_credential(cmd)
-        end
-
-        def scm_iconv(to, from, str)
-          return nil if str.nil?
-          return str if to == from
-          begin
-            Iconv.conv(to, from, str)
-          rescue Iconv::Failure => err
-            logger.error("failed to convert from #{from} to #{to}. #{err}")
-            nil
-          end
-        end
-      end
-
-      class Entries < Array
-        def sort_by_name
-          sort {|x,y|
-            if x.kind == y.kind
-              x.name.to_s <=> y.name.to_s
-            else
-              x.kind <=> y.kind
-            end
-          }
-        end
-
-        def revisions
-          revisions ||= Revisions.new(collect{|entry| entry.lastrev}.compact)
-        end
-      end
-
-      class Info
-        attr_accessor :root_url, :lastrev
-        def initialize(attributes={})
-          self.root_url = attributes[:root_url] if attributes[:root_url]
-          self.lastrev = attributes[:lastrev]
-        end
-      end
-
-      class Entry
-        attr_accessor :name, :path, :kind, :size, :lastrev
-        def initialize(attributes={})
-          self.name = attributes[:name] if attributes[:name]
-          self.path = attributes[:path] if attributes[:path]
-          self.kind = attributes[:kind] if attributes[:kind]
-          self.size = attributes[:size].to_i if attributes[:size]
-          self.lastrev = attributes[:lastrev]
-        end
-
-        def is_file?
-          'file' == self.kind
-        end
-
-        def is_dir?
-          'dir' == self.kind
-        end
-
-        def is_text?
-          Redmine::MimeType.is_type?('text', name)
-        end
-      end
-
-      class Revisions < Array
-        def latest
-          sort {|x,y|
-            unless x.time.nil? or y.time.nil?
-              x.time <=> y.time
-            else
-              0
-            end
-          }.last
-        end
-      end
-
-      class Revision
-        attr_accessor :scmid, :name, :author, :time, :message,
-                      :paths, :revision, :branch, :identifier,
-                      :parents
-
-        def initialize(attributes={})
-          self.identifier = attributes[:identifier]
-          self.scmid      = attributes[:scmid]
-          self.name       = attributes[:name] || self.identifier
-          self.author     = attributes[:author]
-          self.time       = attributes[:time]
-          self.message    = attributes[:message] || ""
-          self.paths      = attributes[:paths]
-          self.revision   = attributes[:revision]
-          self.branch     = attributes[:branch]
-          self.parents    = attributes[:parents]
-        end
-
-        # Returns the readable identifier.
-        def format_identifier
-          self.identifier.to_s
-        end
-      end
-
-      class Annotate
-        attr_reader :lines, :revisions
-
-        def initialize
-          @lines = []
-          @revisions = []
-        end
-
-        def add_line(line, revision)
-          @lines << line
-          @revisions << revision
-        end
-
-        def content
-          content = lines.join("\n")
-        end
-
-        def empty?
-          lines.empty?
-        end
-      end
-
-      class Branch < String
-        attr_accessor :revision, :scmid
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/dfb56bf91d55da294a49c27210c1c84da038fd53.svn-base
--- /dev/null
+++ b/.svn/pristine/df/dfb56bf91d55da294a49c27210c1c84da038fd53.svn-base
@@ -0,0 +1,9 @@
+var fileSpan = $('#attachments_<%= j params[:attachment_id] %>');
+$('<input>', { type: 'hidden', name: 'attachments[<%= j params[:attachment_id] %>][token]' } ).val('<%= j @attachment.token %>').appendTo(fileSpan);
+fileSpan.find('a.remove-upload')
+  .attr({
+    "data-remote": true,
+    "data-method": 'delete',
+    href: '<%= j attachment_path(@attachment, :attachment_id => params[:attachment_id], :format => 'js') %>'
+  })
+  .off('click');
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/df/dfc1e477a4cb72dd0ef065e3d0ac9d62cc729189.svn-base
--- a/.svn/pristine/df/dfc1e477a4cb72dd0ef065e3d0ac9d62cc729189.svn-base
+++ /dev/null
@@ -1,78 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class RolesController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin
-
-  verify :method => :post, :only => [ :destroy ],
-         :redirect_to => { :action => :index }
-
-  def index
-    @role_pages, @roles = paginate :roles, :per_page => 25, :order => 'builtin, position'
-    render :action => "index", :layout => false if request.xhr?
-  end
-
-  def new
-    # Prefills the form with 'Non member' role permissions
-    @role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
-    if request.post? && @role.save
-      # workflow copy
-      if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
-        @role.workflows.copy(copy_from)
-      end
-      flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index'
-    else
-      @permissions = @role.setable_permissions
-      @roles = Role.find :all, :order => 'builtin, position'
-    end
-  end
-
-  def edit
-    @role = Role.find(params[:id])
-    if request.post? and @role.update_attributes(params[:role])
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
-    else
-      @permissions = @role.setable_permissions
-    end
-  end
-
-  def destroy
-    @role = Role.find(params[:id])
-    @role.destroy
-    redirect_to :action => 'index'
-  rescue
-    flash[:error] =  l(:error_can_not_remove_role)
-    redirect_to :action => 'index'
-  end
-
-  def report
-    @roles = Role.find(:all, :order => 'builtin, position')
-    @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
-    if request.post?
-      @roles.each do |role|
-        role.permissions = params[:permissions][role.id.to_s]
-        role.save
-      end
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e0/e0146f52672bac410fabc231692b8f39edc8e101.svn-base
--- /dev/null
+++ b/.svn/pristine/e0/e0146f52672bac410fabc231692b8f39edc8e101.svn-base
@@ -0,0 +1,159 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/mercurial_adapter'
+
+class Repository::Mercurial < Repository
+  # sort changesets by revision number
+  has_many :changesets,
+           :order       => "#{Changeset.table_name}.id DESC",
+           :foreign_key => 'repository_id'
+
+  attr_protected        :root_url
+  validates_presence_of :url
+
+  # number of changesets to fetch at once
+  FETCH_AT_ONCE = 100
+
+  def self.human_attribute_name(attribute_key_name, *args)
+    attr_name = attribute_key_name.to_s
+    if attr_name == "url"
+      attr_name = "path_to_repository"
+    end
+    super(attr_name, *args)
+  end
+
+  def self.scm_adapter_class
+    Redmine::Scm::Adapters::MercurialAdapter
+  end
+
+  def self.scm_name
+    'Mercurial'
+  end
+
+  def supports_directory_revisions?
+    true
+  end
+
+  def supports_revision_graph?
+    true
+  end
+
+  def repo_log_encoding
+    'UTF-8'
+  end
+
+  # Returns the readable identifier for the given mercurial changeset
+  def self.format_changeset_identifier(changeset)
+    "#{changeset.revision}:#{changeset.scmid}"
+  end
+
+  # Returns the identifier for the given Mercurial changeset
+  def self.changeset_identifier(changeset)
+    changeset.scmid
+  end
+
+  def diff_format_revisions(cs, cs_to, sep=':')
+    super(cs, cs_to, ' ')
+  end
+
+  # Finds and returns a revision with a number or the beginning of a hash
+  def find_changeset_by_name(name)
+    return nil if name.blank?
+    s = name.to_s
+    if /[^\d]/ =~ s or s.size > 8
+      cs = changesets.where(:scmid => s).first
+    else
+      cs = changesets.where(:revision => s).first
+    end
+    return cs if cs
+    changesets.where('scmid LIKE ?', "#{s}%").first
+  end
+
+  # Returns the latest changesets for +path+; sorted by revision number
+  #
+  # Because :order => 'id DESC' is defined at 'has_many',
+  # there is no need to set 'order'.
+  # But, MySQL test fails.
+  # Sqlite3 and PostgreSQL pass.
+  # Is this MySQL bug?
+  def latest_changesets(path, rev, limit=10)
+    changesets.
+      includes(:user).
+      where(latest_changesets_cond(path, rev, limit)).
+      limit(limit).
+      order("#{Changeset.table_name}.id DESC").
+      all
+  end
+
+  def latest_changesets_cond(path, rev, limit)
+    cond, args = [], []
+    if scm.branchmap.member? rev
+      # Mercurial named branch is *stable* in each revision.
+      # So, named branch can be stored in database.
+      # Mercurial provides *bookmark* which is equivalent with git branch.
+      # But, bookmark is not implemented.
+      cond << "#{Changeset.table_name}.scmid IN (?)"
+      # Revisions in root directory and sub directory are not equal.
+      # So, in order to get correct limit, we need to get all revisions.
+      # But, it is very heavy.
+      # Mercurial does not treat direcotry.
+      # So, "hg log DIR" is very heavy.
+      branch_limit = path.blank? ? limit : ( limit * 5 )
+      args << scm.nodes_in_branch(rev, :limit => branch_limit)
+    elsif last = rev ? find_changeset_by_name(scm.tagmap[rev] || rev) : nil
+      cond << "#{Changeset.table_name}.id <= ?"
+      args << last.id
+    end
+    unless path.blank?
+      cond << "EXISTS (SELECT * FROM #{Change.table_name}
+                 WHERE #{Change.table_name}.changeset_id = #{Changeset.table_name}.id
+                 AND (#{Change.table_name}.path = ?
+                       OR #{Change.table_name}.path LIKE ? ESCAPE ?))"
+      args << path.with_leading_slash
+      args << "#{path.with_leading_slash.gsub(%r{[%_\\]}) { |s| "\\#{s}" }}/%" << '\\'
+    end
+    [cond.join(' AND '), *args] unless cond.empty?
+  end
+  private :latest_changesets_cond
+
+  def fetch_changesets
+    return if scm.info.nil?
+    scm_rev = scm.info.lastrev.revision.to_i
+    db_rev  = latest_changeset ? latest_changeset.revision.to_i : -1
+    return unless db_rev < scm_rev  # already up-to-date
+
+    logger.debug "Fetching changesets for repository #{url}" if logger
+    (db_rev + 1).step(scm_rev, FETCH_AT_ONCE) do |i|
+      scm.each_revision('', i, [i + FETCH_AT_ONCE - 1, scm_rev].min) do |re|
+        transaction do
+          parents = (re.parents || []).collect{|rp| find_changeset_by_name(rp)}.compact
+          cs = Changeset.create(:repository   => self,
+                                :revision     => re.revision,
+                                :scmid        => re.scmid,
+                                :committer    => re.author,
+                                :committed_on => re.time,
+                                :comments     => re.message,
+                                :parents      => parents)
+          unless cs.new_record?
+            re.paths.each { |e| cs.create_change(e) }
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e0/e016f7bcdcab31cab9c67782c8874b33b52e7b82.svn-base
--- a/.svn/pristine/e0/e016f7bcdcab31cab9c67782c8874b33b52e7b82.svn-base
+++ /dev/null
@@ -1,963 +0,0 @@
-// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
-//           (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
-//           (c) 2005-2008 Jon Tirsen (http://www.tirsen.com)
-// Contributors:
-//  Richard Livsey
-//  Rahul Bhargava
-//  Rob Wills
-//
-// script.aculo.us is freely distributable under the terms of an MIT-style license.
-// For details, see the script.aculo.us web site: http://script.aculo.us/
-
-// Autocompleter.Base handles all the autocompletion functionality
-// that's independent of the data source for autocompletion. This
-// includes drawing the autocompletion menu, observing keyboard
-// and mouse events, and similar.
-//
-// Specific autocompleters need to provide, at the very least,
-// a getUpdatedChoices function that will be invoked every time
-// the text inside the monitored textbox changes. This method
-// should get the text for which to provide autocompletion by
-// invoking this.getToken(), NOT by directly accessing
-// this.element.value. This is to allow incremental tokenized
-// autocompletion. Specific auto-completion logic (AJAX, etc)
-// belongs in getUpdatedChoices.
-//
-// Tokenized incremental autocompletion is enabled automatically
-// when an autocompleter is instantiated with the 'tokens' option
-// in the options parameter, e.g.:
-// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
-// will incrementally autocomplete with a comma as the token.
-// Additionally, ',' in the above example can be replaced with
-// a token array, e.g. { tokens: [',', '\n'] } which
-// enables autocompletion on multiple tokens. This is most
-// useful when one of the tokens is \n (a newline), as it
-// allows smart autocompletion after linebreaks.
-
-if(typeof Effect == 'undefined')
-  throw("controls.js requires including script.aculo.us' effects.js library");
-
-var Autocompleter = { };
-Autocompleter.Base = Class.create({
-  baseInitialize: function(element, update, options) {
-    element          = $(element);
-    this.element     = element;
-    this.update      = $(update);
-    this.hasFocus    = false;
-    this.changed     = false;
-    this.active      = false;
-    this.index       = 0;
-    this.entryCount  = 0;
-    this.oldElementValue = this.element.value;
-
-    if(this.setOptions)
-      this.setOptions(options);
-    else
-      this.options = options || { };
-
-    this.options.paramName    = this.options.paramName || this.element.name;
-    this.options.tokens       = this.options.tokens || [];
-    this.options.frequency    = this.options.frequency || 0.4;
-    this.options.minChars     = this.options.minChars || 1;
-    this.options.onShow       = this.options.onShow ||
-      function(element, update){
-        if(!update.style.position || update.style.position=='absolute') {
-          update.style.position = 'absolute';
-          Position.clone(element, update, {
-            setHeight: false,
-            offsetTop: element.offsetHeight
-          });
-        }
-        Effect.Appear(update,{duration:0.15});
-      };
-    this.options.onHide = this.options.onHide ||
-      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
-
-    if(typeof(this.options.tokens) == 'string')
-      this.options.tokens = new Array(this.options.tokens);
-    // Force carriage returns as token delimiters anyway
-    if (!this.options.tokens.include('\n'))
-      this.options.tokens.push('\n');
-
-    this.observer = null;
-
-    this.element.setAttribute('autocomplete','off');
-
-    Element.hide(this.update);
-
-    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
-    Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
-  },
-
-  show: function() {
-    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
-    if(!this.iefix &&
-      (Prototype.Browser.IE) &&
-      (Element.getStyle(this.update, 'position')=='absolute')) {
-      new Insertion.After(this.update,
-       '<iframe id="' + this.update.id + '_iefix" '+
-       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
-       'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
-      this.iefix = $(this.update.id+'_iefix');
-    }
-    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
-  },
-
-  fixIEOverlapping: function() {
-    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
-    this.iefix.style.zIndex = 1;
-    this.update.style.zIndex = 2;
-    Element.show(this.iefix);
-  },
-
-  hide: function() {
-    this.stopIndicator();
-    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
-    if(this.iefix) Element.hide(this.iefix);
-  },
-
-  startIndicator: function() {
-    if(this.options.indicator) Element.show(this.options.indicator);
-  },
-
-  stopIndicator: function() {
-    if(this.options.indicator) Element.hide(this.options.indicator);
-  },
-
-  onKeyPress: function(event) {
-    if(this.active)
-      switch(event.keyCode) {
-       case Event.KEY_TAB:
-       case Event.KEY_RETURN:
-         this.selectEntry();
-         Event.stop(event);
-       case Event.KEY_ESC:
-         this.hide();
-         this.active = false;
-         Event.stop(event);
-         return;
-       case Event.KEY_LEFT:
-       case Event.KEY_RIGHT:
-         return;
-       case Event.KEY_UP:
-         this.markPrevious();
-         this.render();
-         Event.stop(event);
-         return;
-       case Event.KEY_DOWN:
-         this.markNext();
-         this.render();
-         Event.stop(event);
-         return;
-      }
-     else
-       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
-         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
-
-    this.changed = true;
-    this.hasFocus = true;
-
-    if(this.observer) clearTimeout(this.observer);
-      this.observer =
-        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
-  },
-
-  activate: function() {
-    this.changed = false;
-    this.hasFocus = true;
-    this.getUpdatedChoices();
-  },
-
-  onHover: function(event) {
-    var element = Event.findElement(event, 'LI');
-    if(this.index != element.autocompleteIndex)
-    {
-        this.index = element.autocompleteIndex;
-        this.render();
-    }
-    Event.stop(event);
-  },
-
-  onClick: function(event) {
-    var element = Event.findElement(event, 'LI');
-    this.index = element.autocompleteIndex;
-    this.selectEntry();
-    this.hide();
-  },
-
-  onBlur: function(event) {
-    // needed to make click events working
-    setTimeout(this.hide.bind(this), 250);
-    this.hasFocus = false;
-    this.active = false;
-  },
-
-  render: function() {
-    if(this.entryCount > 0) {
-      for (var i = 0; i < this.entryCount; i++)
-        this.index==i ?
-          Element.addClassName(this.getEntry(i),"selected") :
-          Element.removeClassName(this.getEntry(i),"selected");
-      if(this.hasFocus) {
-        this.show();
-        this.active = true;
-      }
-    } else {
-      this.active = false;
-      this.hide();
-    }
-  },
-
-  markPrevious: function() {
-    if(this.index > 0) this.index--;
-      else this.index = this.entryCount-1;
-    this.getEntry(this.index).scrollIntoView(true);
-  },
-
-  markNext: function() {
-    if(this.index < this.entryCount-1) this.index++;
-      else this.index = 0;
-    this.getEntry(this.index).scrollIntoView(false);
-  },
-
-  getEntry: function(index) {
-    return this.update.firstChild.childNodes[index];
-  },
-
-  getCurrentEntry: function() {
-    return this.getEntry(this.index);
-  },
-
-  selectEntry: function() {
-    this.active = false;
-    this.updateElement(this.getCurrentEntry());
-  },
-
-  updateElement: function(selectedElement) {
-    if (this.options.updateElement) {
-      this.options.updateElement(selectedElement);
-      return;
-    }
-    var value = '';
-    if (this.options.select) {
-      var nodes = $(selectedElement).select('.' + this.options.select) || [];
-      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
-    } else
-      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
-
-    var bounds = this.getTokenBounds();
-    if (bounds[0] != -1) {
-      var newValue = this.element.value.substr(0, bounds[0]);
-      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
-      if (whitespace)
-        newValue += whitespace[0];
-      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
-    } else {
-      this.element.value = value;
-    }
-    this.oldElementValue = this.element.value;
-    this.element.focus();
-
-    if (this.options.afterUpdateElement)
-      this.options.afterUpdateElement(this.element, selectedElement);
-  },
-
-  updateChoices: function(choices) {
-    if(!this.changed && this.hasFocus) {
-      this.update.innerHTML = choices;
-      Element.cleanWhitespace(this.update);
-      Element.cleanWhitespace(this.update.down());
-
-      if(this.update.firstChild && this.update.down().childNodes) {
-        this.entryCount =
-          this.update.down().childNodes.length;
-        for (var i = 0; i < this.entryCount; i++) {
-          var entry = this.getEntry(i);
-          entry.autocompleteIndex = i;
-          this.addObservers(entry);
-        }
-      } else {
-        this.entryCount = 0;
-      }
-
-      this.stopIndicator();
-      this.index = 0;
-
-      if(this.entryCount==1 && this.options.autoSelect) {
-        this.selectEntry();
-        this.hide();
-      } else {
-        this.render();
-      }
-    }
-  },
-
-  addObservers: function(element) {
-    Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
-    Event.observe(element, "click", this.onClick.bindAsEventListener(this));
-  },
-
-  onObserverEvent: function() {
-    this.changed = false;
-    this.tokenBounds = null;
-    if(this.getToken().length>=this.options.minChars) {
-      this.getUpdatedChoices();
-    } else {
-      this.active = false;
-      this.hide();
-    }
-    this.oldElementValue = this.element.value;
-  },
-
-  getToken: function() {
-    var bounds = this.getTokenBounds();
-    return this.element.value.substring(bounds[0], bounds[1]).strip();
-  },
-
-  getTokenBounds: function() {
-    if (null != this.tokenBounds) return this.tokenBounds;
-    var value = this.element.value;
-    if (value.strip().empty()) return [-1, 0];
-    var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
-    var offset = (diff == this.oldElementValue.length ? 1 : 0);
-    var prevTokenPos = -1, nextTokenPos = value.length;
-    var tp;
-    for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
-      tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
-      if (tp > prevTokenPos) prevTokenPos = tp;
-      tp = value.indexOf(this.options.tokens[index], diff + offset);
-      if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
-    }
-    return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
-  }
-});
-
-Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
-  var boundary = Math.min(newS.length, oldS.length);
-  for (var index = 0; index < boundary; ++index)
-    if (newS[index] != oldS[index])
-      return index;
-  return boundary;
-};
-
-Ajax.Autocompleter = Class.create(Autocompleter.Base, {
-  initialize: function(element, update, url, options) {
-    this.baseInitialize(element, update, options);
-    this.options.asynchronous  = true;
-    this.options.onComplete    = this.onComplete.bind(this);
-    this.options.defaultParams = this.options.parameters || null;
-    this.url                   = url;
-  },
-
-  getUpdatedChoices: function() {
-    this.startIndicator();
-
-    var entry = encodeURIComponent(this.options.paramName) + '=' +
-      encodeURIComponent(this.getToken());
-
-    this.options.parameters = this.options.callback ?
-      this.options.callback(this.element, entry) : entry;
-
-    if(this.options.defaultParams)
-      this.options.parameters += '&' + this.options.defaultParams;
-
-    new Ajax.Request(this.url, this.options);
-  },
-
-  onComplete: function(request) {
-    this.updateChoices(request.responseText);
-  }
-});
-
-// The local array autocompleter. Used when you'd prefer to
-// inject an array of autocompletion options into the page, rather
-// than sending out Ajax queries, which can be quite slow sometimes.
-//
-// The constructor takes four parameters. The first two are, as usual,
-// the id of the monitored textbox, and id of the autocompletion menu.
-// The third is the array you want to autocomplete from, and the fourth
-// is the options block.
-//
-// Extra local autocompletion options:
-// - choices - How many autocompletion choices to offer
-//
-// - partialSearch - If false, the autocompleter will match entered
-//                    text only at the beginning of strings in the
-//                    autocomplete array. Defaults to true, which will
-//                    match text at the beginning of any *word* in the
-//                    strings in the autocomplete array. If you want to
-//                    search anywhere in the string, additionally set
-//                    the option fullSearch to true (default: off).
-//
-// - fullSsearch - Search anywhere in autocomplete array strings.
-//
-// - partialChars - How many characters to enter before triggering
-//                   a partial match (unlike minChars, which defines
-//                   how many characters are required to do any match
-//                   at all). Defaults to 2.
-//
-// - ignoreCase - Whether to ignore case when autocompleting.
-//                 Defaults to true.
-//
-// It's possible to pass in a custom function as the 'selector'
-// option, if you prefer to write your own autocompletion logic.
-// In that case, the other options above will not apply unless
-// you support them.
-
-Autocompleter.Local = Class.create(Autocompleter.Base, {
-  initialize: function(element, update, array, options) {
-    this.baseInitialize(element, update, options);
-    this.options.array = array;
-  },
-
-  getUpdatedChoices: function() {
-    this.updateChoices(this.options.selector(this));
-  },
-
-  setOptions: function(options) {
-    this.options = Object.extend({
-      choices: 10,
-      partialSearch: true,
-      partialChars: 2,
-      ignoreCase: true,
-      fullSearch: false,
-      selector: function(instance) {
-        var ret       = []; // Beginning matches
-        var partial   = []; // Inside matches
-        var entry     = instance.getToken();
-        var count     = 0;
-
-        for (var i = 0; i < instance.options.array.length &&
-          ret.length < instance.options.choices ; i++) {
-
-          var elem = instance.options.array[i];
-          var foundPos = instance.options.ignoreCase ?
-            elem.toLowerCase().indexOf(entry.toLowerCase()) :
-            elem.indexOf(entry);
-
-          while (foundPos != -1) {
-            if (foundPos == 0 && elem.length != entry.length) {
-              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
-                elem.substr(entry.length) + "</li>");
-              break;
-            } else if (entry.length >= instance.options.partialChars &&
-              instance.options.partialSearch && foundPos != -1) {
-              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
-                partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
-                  elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
-                  foundPos + entry.length) + "</li>");
-                break;
-              }
-            }
-
-            foundPos = instance.options.ignoreCase ?
-              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
-              elem.indexOf(entry, foundPos + 1);
-
-          }
-        }
-        if (partial.length)
-          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
-        return "<ul>" + ret.join('') + "</ul>";
-      }
-    }, options || { });
-  }
-});
-
-// AJAX in-place editor and collection editor
-// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
-
-// Use this if you notice weird scrolling problems on some browsers,
-// the DOM might be a bit confused when this gets called so do this
-// waits 1 ms (with setTimeout) until it does the activation
-Field.scrollFreeActivate = function(field) {
-  setTimeout(function() {
-    Field.activate(field);
-  }, 1);
-};
-
-Ajax.InPlaceEditor = Class.create({
-  initialize: function(element, url, options) {
-    this.url = url;
-    this.element = element = $(element);
-    this.prepareOptions();
-    this._controls = { };
-    arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
-    Object.extend(this.options, options || { });
-    if (!this.options.formId && this.element.id) {
-      this.options.formId = this.element.id + '-inplaceeditor';
-      if ($(this.options.formId))
-        this.options.formId = '';
-    }
-    if (this.options.externalControl)
-      this.options.externalControl = $(this.options.externalControl);
-    if (!this.options.externalControl)
-      this.options.externalControlOnly = false;
-    this._originalBackground = this.element.getStyle('background-color') || 'transparent';
-    this.element.title = this.options.clickToEditText;
-    this._boundCancelHandler = this.handleFormCancellation.bind(this);
-    this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
-    this._boundFailureHandler = this.handleAJAXFailure.bind(this);
-    this._boundSubmitHandler = this.handleFormSubmission.bind(this);
-    this._boundWrapperHandler = this.wrapUp.bind(this);
-    this.registerListeners();
-  },
-  checkForEscapeOrReturn: function(e) {
-    if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
-    if (Event.KEY_ESC == e.keyCode)
-      this.handleFormCancellation(e);
-    else if (Event.KEY_RETURN == e.keyCode)
-      this.handleFormSubmission(e);
-  },
-  createControl: function(mode, handler, extraClasses) {
-    var control = this.options[mode + 'Control'];
-    var text = this.options[mode + 'Text'];
-    if ('button' == control) {
-      var btn = document.createElement('input');
-      btn.type = 'submit';
-      btn.value = text;
-      btn.className = 'editor_' + mode + '_button';
-      if ('cancel' == mode)
-        btn.onclick = this._boundCancelHandler;
-      this._form.appendChild(btn);
-      this._controls[mode] = btn;
-    } else if ('link' == control) {
-      var link = document.createElement('a');
-      link.href = '#';
-      link.appendChild(document.createTextNode(text));
-      link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
-      link.className = 'editor_' + mode + '_link';
-      if (extraClasses)
-        link.className += ' ' + extraClasses;
-      this._form.appendChild(link);
-      this._controls[mode] = link;
-    }
-  },
-  createEditField: function() {
-    var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
-    var fld;
-    if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
-      fld = document.createElement('input');
-      fld.type = 'text';
-      var size = this.options.size || this.options.cols || 0;
-      if (0 < size) fld.size = size;
-    } else {
-      fld = document.createElement('textarea');
-      fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
-      fld.cols = this.options.cols || 40;
-    }
-    fld.name = this.options.paramName;
-    fld.value = text; // No HTML breaks conversion anymore
-    fld.className = 'editor_field';
-    if (this.options.submitOnBlur)
-      fld.onblur = this._boundSubmitHandler;
-    this._controls.editor = fld;
-    if (this.options.loadTextURL)
-      this.loadExternalText();
-    this._form.appendChild(this._controls.editor);
-  },
-  createForm: function() {
-    var ipe = this;
-    function addText(mode, condition) {
-      var text = ipe.options['text' + mode + 'Controls'];
-      if (!text || condition === false) return;
-      ipe._form.appendChild(document.createTextNode(text));
-    };
-    this._form = $(document.createElement('form'));
-    this._form.id = this.options.formId;
-    this._form.addClassName(this.options.formClassName);
-    this._form.onsubmit = this._boundSubmitHandler;
-    this.createEditField();
-    if ('textarea' == this._controls.editor.tagName.toLowerCase())
-      this._form.appendChild(document.createElement('br'));
-    if (this.options.onFormCustomization)
-      this.options.onFormCustomization(this, this._form);
-    addText('Before', this.options.okControl || this.options.cancelControl);
-    this.createControl('ok', this._boundSubmitHandler);
-    addText('Between', this.options.okControl && this.options.cancelControl);
-    this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
-    addText('After', this.options.okControl || this.options.cancelControl);
-  },
-  destroy: function() {
-    if (this._oldInnerHTML)
-      this.element.innerHTML = this._oldInnerHTML;
-    this.leaveEditMode();
-    this.unregisterListeners();
-  },
-  enterEditMode: function(e) {
-    if (this._saving || this._editing) return;
-    this._editing = true;
-    this.triggerCallback('onEnterEditMode');
-    if (this.options.externalControl)
-      this.options.externalControl.hide();
-    this.element.hide();
-    this.createForm();
-    this.element.parentNode.insertBefore(this._form, this.element);
-    if (!this.options.loadTextURL)
-      this.postProcessEditField();
-    if (e) Event.stop(e);
-  },
-  enterHover: function(e) {
-    if (this.options.hoverClassName)
-      this.element.addClassName(this.options.hoverClassName);
-    if (this._saving) return;
-    this.triggerCallback('onEnterHover');
-  },
-  getText: function() {
-    return this.element.innerHTML.unescapeHTML();
-  },
-  handleAJAXFailure: function(transport) {
-    this.triggerCallback('onFailure', transport);
-    if (this._oldInnerHTML) {
-      this.element.innerHTML = this._oldInnerHTML;
-      this._oldInnerHTML = null;
-    }
-  },
-  handleFormCancellation: function(e) {
-    this.wrapUp();
-    if (e) Event.stop(e);
-  },
-  handleFormSubmission: function(e) {
-    var form = this._form;
-    var value = $F(this._controls.editor);
-    this.prepareSubmission();
-    var params = this.options.callback(form, value) || '';
-    if (Object.isString(params))
-      params = params.toQueryParams();
-    params.editorId = this.element.id;
-    if (this.options.htmlResponse) {
-      var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
-      Object.extend(options, {
-        parameters: params,
-        onComplete: this._boundWrapperHandler,
-        onFailure: this._boundFailureHandler
-      });
-      new Ajax.Updater({ success: this.element }, this.url, options);
-    } else {
-      var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
-      Object.extend(options, {
-        parameters: params,
-        onComplete: this._boundWrapperHandler,
-        onFailure: this._boundFailureHandler
-      });
-      new Ajax.Request(this.url, options);
-    }
-    if (e) Event.stop(e);
-  },
-  leaveEditMode: function() {
-    this.element.removeClassName(this.options.savingClassName);
-    this.removeForm();
-    this.leaveHover();
-    this.element.style.backgroundColor = this._originalBackground;
-    this.element.show();
-    if (this.options.externalControl)
-      this.options.externalControl.show();
-    this._saving = false;
-    this._editing = false;
-    this._oldInnerHTML = null;
-    this.triggerCallback('onLeaveEditMode');
-  },
-  leaveHover: function(e) {
-    if (this.options.hoverClassName)
-      this.element.removeClassName(this.options.hoverClassName);
-    if (this._saving) return;
-    this.triggerCallback('onLeaveHover');
-  },
-  loadExternalText: function() {
-    this._form.addClassName(this.options.loadingClassName);
-    this._controls.editor.disabled = true;
-    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
-    Object.extend(options, {
-      parameters: 'editorId=' + encodeURIComponent(this.element.id),
-      onComplete: Prototype.emptyFunction,
-      onSuccess: function(transport) {
-        this._form.removeClassName(this.options.loadingClassName);
-        var text = transport.responseText;
-        if (this.options.stripLoadedTextTags)
-          text = text.stripTags();
-        this._controls.editor.value = text;
-        this._controls.editor.disabled = false;
-        this.postProcessEditField();
-      }.bind(this),
-      onFailure: this._boundFailureHandler
-    });
-    new Ajax.Request(this.options.loadTextURL, options);
-  },
-  postProcessEditField: function() {
-    var fpc = this.options.fieldPostCreation;
-    if (fpc)
-      $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
-  },
-  prepareOptions: function() {
-    this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
-    Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
-    [this._extraDefaultOptions].flatten().compact().each(function(defs) {
-      Object.extend(this.options, defs);
-    }.bind(this));
-  },
-  prepareSubmission: function() {
-    this._saving = true;
-    this.removeForm();
-    this.leaveHover();
-    this.showSaving();
-  },
-  registerListeners: function() {
-    this._listeners = { };
-    var listener;
-    $H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
-      listener = this[pair.value].bind(this);
-      this._listeners[pair.key] = listener;
-      if (!this.options.externalControlOnly)
-        this.element.observe(pair.key, listener);
-      if (this.options.externalControl)
-        this.options.externalControl.observe(pair.key, listener);
-    }.bind(this));
-  },
-  removeForm: function() {
-    if (!this._form) return;
-    this._form.remove();
-    this._form = null;
-    this._controls = { };
-  },
-  showSaving: function() {
-    this._oldInnerHTML = this.element.innerHTML;
-    this.element.innerHTML = this.options.savingText;
-    this.element.addClassName(this.options.savingClassName);
-    this.element.style.backgroundColor = this._originalBackground;
-    this.element.show();
-  },
-  triggerCallback: function(cbName, arg) {
-    if ('function' == typeof this.options[cbName]) {
-      this.options[cbName](this, arg);
-    }
-  },
-  unregisterListeners: function() {
-    $H(this._listeners).each(function(pair) {
-      if (!this.options.externalControlOnly)
-        this.element.stopObserving(pair.key, pair.value);
-      if (this.options.externalControl)
-        this.options.externalControl.stopObserving(pair.key, pair.value);
-    }.bind(this));
-  },
-  wrapUp: function(transport) {
-    this.leaveEditMode();
-    // Can't use triggerCallback due to backward compatibility: requires
-    // binding + direct element
-    this._boundComplete(transport, this.element);
-  }
-});
-
-Object.extend(Ajax.InPlaceEditor.prototype, {
-  dispose: Ajax.InPlaceEditor.prototype.destroy
-});
-
-Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
-  initialize: function($super, element, url, options) {
-    this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
-    $super(element, url, options);
-  },
-
-  createEditField: function() {
-    var list = document.createElement('select');
-    list.name = this.options.paramName;
-    list.size = 1;
-    this._controls.editor = list;
-    this._collection = this.options.collection || [];
-    if (this.options.loadCollectionURL)
-      this.loadCollection();
-    else
-      this.checkForExternalText();
-    this._form.appendChild(this._controls.editor);
-  },
-
-  loadCollection: function() {
-    this._form.addClassName(this.options.loadingClassName);
-    this.showLoadingText(this.options.loadingCollectionText);
-    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
-    Object.extend(options, {
-      parameters: 'editorId=' + encodeURIComponent(this.element.id),
-      onComplete: Prototype.emptyFunction,
-      onSuccess: function(transport) {
-        var js = transport.responseText.strip();
-        if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
-          throw('Server returned an invalid collection representation.');
-        this._collection = eval(js);
-        this.checkForExternalText();
-      }.bind(this),
-      onFailure: this.onFailure
-    });
-    new Ajax.Request(this.options.loadCollectionURL, options);
-  },
-
-  showLoadingText: function(text) {
-    this._controls.editor.disabled = true;
-    var tempOption = this._controls.editor.firstChild;
-    if (!tempOption) {
-      tempOption = document.createElement('option');
-      tempOption.value = '';
-      this._controls.editor.appendChild(tempOption);
-      tempOption.selected = true;
-    }
-    tempOption.update((text || '').stripScripts().stripTags());
-  },
-
-  checkForExternalText: function() {
-    this._text = this.getText();
-    if (this.options.loadTextURL)
-      this.loadExternalText();
-    else
-      this.buildOptionList();
-  },
-
-  loadExternalText: function() {
-    this.showLoadingText(this.options.loadingText);
-    var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
-    Object.extend(options, {
-      parameters: 'editorId=' + encodeURIComponent(this.element.id),
-      onComplete: Prototype.emptyFunction,
-      onSuccess: function(transport) {
-        this._text = transport.responseText.strip();
-        this.buildOptionList();
-      }.bind(this),
-      onFailure: this.onFailure
-    });
-    new Ajax.Request(this.options.loadTextURL, options);
-  },
-
-  buildOptionList: function() {
-    this._form.removeClassName(this.options.loadingClassName);
-    this._collection = this._collection.map(function(entry) {
-      return 2 === entry.length ? entry : [entry, entry].flatten();
-    });
-    var marker = ('value' in this.options) ? this.options.value : this._text;
-    var textFound = this._collection.any(function(entry) {
-      return entry[0] == marker;
-    }.bind(this));
-    this._controls.editor.update('');
-    var option;
-    this._collection.each(function(entry, index) {
-      option = document.createElement('option');
-      option.value = entry[0];
-      option.selected = textFound ? entry[0] == marker : 0 == index;
-      option.appendChild(document.createTextNode(entry[1]));
-      this._controls.editor.appendChild(option);
-    }.bind(this));
-    this._controls.editor.disabled = false;
-    Field.scrollFreeActivate(this._controls.editor);
-  }
-});
-
-//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
-//**** This only  exists for a while,  in order to  let ****
-//**** users adapt to  the new API.  Read up on the new ****
-//**** API and convert your code to it ASAP!            ****
-
-Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
-  if (!options) return;
-  function fallback(name, expr) {
-    if (name in options || expr === undefined) return;
-    options[name] = expr;
-  };
-  fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
-    options.cancelLink == options.cancelButton == false ? false : undefined)));
-  fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
-    options.okLink == options.okButton == false ? false : undefined)));
-  fallback('highlightColor', options.highlightcolor);
-  fallback('highlightEndColor', options.highlightendcolor);
-};
-
-Object.extend(Ajax.InPlaceEditor, {
-  DefaultOptions: {
-    ajaxOptions: { },
-    autoRows: 3,                                // Use when multi-line w/ rows == 1
-    cancelControl: 'link',                      // 'link'|'button'|false
-    cancelText: 'cancel',
-    clickToEditText: 'Click to edit',
-    externalControl: null,                      // id|elt
-    externalControlOnly: false,
-    fieldPostCreation: 'activate',              // 'activate'|'focus'|false
-    formClassName: 'inplaceeditor-form',
-    formId: null,                               // id|elt
-    highlightColor: '#ffff99',
-    highlightEndColor: '#ffffff',
-    hoverClassName: '',
-    htmlResponse: true,
-    loadingClassName: 'inplaceeditor-loading',
-    loadingText: 'Loading...',
-    okControl: 'button',                        // 'link'|'button'|false
-    okText: 'ok',
-    paramName: 'value',
-    rows: 1,                                    // If 1 and multi-line, uses autoRows
-    savingClassName: 'inplaceeditor-saving',
-    savingText: 'Saving...',
-    size: 0,
-    stripLoadedTextTags: false,
-    submitOnBlur: false,
-    textAfterControls: '',
-    textBeforeControls: '',
-    textBetweenControls: ''
-  },
-  DefaultCallbacks: {
-    callback: function(form) {
-      return Form.serialize(form);
-    },
-    onComplete: function(transport, element) {
-      // For backward compatibility, this one is bound to the IPE, and passes
-      // the element directly.  It was too often customized, so we don't break it.
-      new Effect.Highlight(element, {
-        startcolor: this.options.highlightColor, keepBackgroundImage: true });
-    },
-    onEnterEditMode: null,
-    onEnterHover: function(ipe) {
-      ipe.element.style.backgroundColor = ipe.options.highlightColor;
-      if (ipe._effect)
-        ipe._effect.cancel();
-    },
-    onFailure: function(transport, ipe) {
-      alert('Error communication with the server: ' + transport.responseText.stripTags());
-    },
-    onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
-    onLeaveEditMode: null,
-    onLeaveHover: function(ipe) {
-      ipe._effect = new Effect.Highlight(ipe.element, {
-        startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
-        restorecolor: ipe._originalBackground, keepBackgroundImage: true
-      });
-    }
-  },
-  Listeners: {
-    click: 'enterEditMode',
-    keydown: 'checkForEscapeOrReturn',
-    mouseover: 'enterHover',
-    mouseout: 'leaveHover'
-  }
-});
-
-Ajax.InPlaceCollectionEditor.DefaultOptions = {
-  loadingCollectionText: 'Loading options...'
-};
-
-// Delayed observer, like Form.Element.Observer,
-// but waits for delay after last key input
-// Ideal for live-search fields
-
-Form.Element.DelayedObserver = Class.create({
-  initialize: function(element, delay, callback) {
-    this.delay     = delay || 0.5;
-    this.element   = $(element);
-    this.callback  = callback;
-    this.timer     = null;
-    this.lastValue = $F(this.element);
-    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
-  },
-  delayedListener: function(event) {
-    if(this.lastValue == $F(this.element)) return;
-    if(this.timer) clearTimeout(this.timer);
-    this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
-    this.lastValue = $F(this.element);
-  },
-  onTimerEvent: function() {
-    this.timer = null;
-    this.callback(this.element, $F(this.element));
-  }
-});
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e0/e03b3539b5eda7cb68bffc68e4f6d9f643e92475.svn-base
--- a/.svn/pristine/e0/e03b3539b5eda7cb68bffc68e4f6d9f643e92475.svn-base
+++ /dev/null
@@ -1,707 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'wiki_controller'
-
-# Re-raise errors caught by the controller.
-class WikiController; def rescue_action(e) raise e end; end
-
-class WikiControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles,
-           :enabled_modules, :wikis, :wiki_pages, :wiki_contents,
-           :wiki_content_versions, :attachments
-
-  def setup
-    @controller = WikiController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_show_start_page
-    get :show, :project_id => 'ecookbook'
-    assert_response :success
-    assert_template 'show'
-    assert_tag :tag => 'h1', :content => /CookBook documentation/
-
-    # child_pages macro
-    assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
-               :child => { :tag => 'li',
-                           :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
-                                                    :content => 'Page with an inline image' } }
-  end
-  
-  def test_export_link
-    Role.anonymous.add_permission! :export_wiki_pages
-    get :show, :project_id => 'ecookbook'
-    assert_response :success
-    assert_tag 'a', :attributes => {:href => '/projects/ecookbook/wiki/CookBook_documentation.txt'}
-  end
-
-  def test_show_page_with_name
-    get :show, :project_id => 1, :id => 'Another_page'
-    assert_response :success
-    assert_template 'show'
-    assert_tag :tag => 'h1', :content => /Another page/
-    # Included page with an inline image
-    assert_tag :tag => 'p', :content => /This is an inline image/
-    assert_tag :tag => 'img', :attributes => { :src => '/attachments/download/3',
-                                               :alt => 'This is a logo' }
-  end
-
-  def test_show_redirected_page
-    WikiRedirect.create!(:wiki_id => 1, :title => 'Old_title', :redirects_to => 'Another_page')
-
-    get :show, :project_id => 'ecookbook', :id => 'Old_title'
-    assert_redirected_to '/projects/ecookbook/wiki/Another_page'
-  end
-
-  def test_show_with_sidebar
-    page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
-    page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
-    page.save!
-
-    get :show, :project_id => 1, :id => 'Another_page'
-    assert_response :success
-    assert_tag :tag => 'div', :attributes => {:id => 'sidebar'},
-                              :content => /Side bar content for test_show_with_sidebar/
-  end
-
-  def test_show_unexistent_page_without_edit_right
-    get :show, :project_id => 1, :id => 'Unexistent page'
-    assert_response 404
-  end
-  
-  def test_show_should_display_section_edit_links
-    @request.session[:user_id] = 2
-    get :show, :project_id => 1, :id => 'Page with sections'
-    assert_no_tag 'a', :attributes => {
-      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=1'
-    }
-    assert_tag 'a', :attributes => {
-      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
-    }
-    assert_tag 'a', :attributes => {
-      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=3'
-    }
-  end
-
-  def test_show_current_version_should_display_section_edit_links
-    @request.session[:user_id] = 2
-    get :show, :project_id => 1, :id => 'Page with sections', :version => 3
-
-    assert_tag 'a', :attributes => {
-      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
-    }
-  end
-
-  def test_show_old_version_should_not_display_section_edit_links
-    @request.session[:user_id] = 2
-    get :show, :project_id => 1, :id => 'Page with sections', :version => 2
-
-    assert_no_tag 'a', :attributes => {
-      :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
-    }
-  end
-
-  def test_show_unexistent_page_with_edit_right
-    @request.session[:user_id] = 2
-    get :show, :project_id => 1, :id => 'Unexistent page'
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_create_page
-    @request.session[:user_id] = 2
-    put :update, :project_id => 1,
-                :id => 'New page',
-                :content => {:comments => 'Created the page',
-                             :text => "h1. New page\n\nThis is a new page",
-                             :version => 0}
-    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
-    page = Project.find(1).wiki.find_page('New page')
-    assert !page.new_record?
-    assert_not_nil page.content
-    assert_equal 'Created the page', page.content.comments
-  end
-
-  def test_create_page_with_attachments
-    @request.session[:user_id] = 2
-    assert_difference 'WikiPage.count' do
-      assert_difference 'Attachment.count' do
-        put :update, :project_id => 1,
-                    :id => 'New page',
-                    :content => {:comments => 'Created the page',
-                                 :text => "h1. New page\n\nThis is a new page",
-                                 :version => 0},
-                    :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
-      end
-    end
-    page = Project.find(1).wiki.find_page('New page')
-    assert_equal 1, page.attachments.count
-    assert_equal 'testfile.txt', page.attachments.first.filename
-  end
-
-  def test_edit_page
-    @request.session[:user_id] = 2
-    get :edit, :project_id => 'ecookbook', :id => 'Another_page'
-
-    assert_response :success
-    assert_template 'edit'
-
-    assert_tag 'textarea',
-      :attributes => { :name => 'content[text]' },
-      :content => WikiPage.find_by_title('Another_page').content.text
-  end
-
-  def test_edit_section
-    @request.session[:user_id] = 2
-    get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 2
-
-    assert_response :success
-    assert_template 'edit'
-    
-    page = WikiPage.find_by_title('Page_with_sections')
-    section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
-
-    assert_tag 'textarea',
-      :attributes => { :name => 'content[text]' },
-      :content => section
-    assert_tag 'input',
-      :attributes => { :name => 'section', :type => 'hidden', :value => '2' }
-    assert_tag 'input',
-      :attributes => { :name => 'section_hash', :type => 'hidden', :value => hash }
-  end
-
-  def test_edit_invalid_section_should_respond_with_404
-    @request.session[:user_id] = 2
-    get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 10
-
-    assert_response 404
-  end
-
-  def test_update_page
-    @request.session[:user_id] = 2
-    assert_no_difference 'WikiPage.count' do
-      assert_no_difference 'WikiContent.count' do
-        assert_difference 'WikiContent::Version.count' do
-          put :update, :project_id => 1,
-            :id => 'Another_page',
-            :content => {
-              :comments => "my comments",
-              :text => "edited",
-              :version => 1
-            }
-        end
-      end
-    end
-    assert_redirected_to '/projects/ecookbook/wiki/Another_page'
-
-    page = Wiki.find(1).pages.find_by_title('Another_page')
-    assert_equal "edited", page.content.text
-    assert_equal 2, page.content.version
-    assert_equal "my comments", page.content.comments
-  end
-
-  def test_update_page_with_failure
-    @request.session[:user_id] = 2
-    assert_no_difference 'WikiPage.count' do
-      assert_no_difference 'WikiContent.count' do
-        assert_no_difference 'WikiContent::Version.count' do
-          put :update, :project_id => 1,
-            :id => 'Another_page',
-            :content => {
-              :comments => 'a' * 300,  # failure here, comment is too long
-              :text => 'edited',
-              :version => 1
-            }
-          end
-        end
-      end
-    assert_response :success
-    assert_template 'edit'
-
-    assert_error_tag :descendant => {:content => /Comment is too long/}
-    assert_tag :tag => 'textarea', :attributes => {:id => 'content_text'}, :content => 'edited'
-    assert_tag :tag => 'input', :attributes => {:id => 'content_version', :value => '1'}
-  end
-
-  def test_update_stale_page_should_not_raise_an_error
-    @request.session[:user_id] = 2
-    c = Wiki.find(1).find_page('Another_page').content
-    c.text = 'Previous text'
-    c.save!
-    assert_equal 2, c.version
-
-    assert_no_difference 'WikiPage.count' do
-      assert_no_difference 'WikiContent.count' do
-        assert_no_difference 'WikiContent::Version.count' do
-          put :update, :project_id => 1,
-            :id => 'Another_page',
-            :content => {
-              :comments => 'My comments',
-              :text => 'Text should not be lost',
-              :version => 1
-            }
-        end
-      end
-    end
-    assert_response :success
-    assert_template 'edit'
-    assert_tag :div,
-      :attributes => { :class => /error/ },
-      :content => /Data has been updated by another user/
-    assert_tag 'textarea',
-      :attributes => { :name => 'content[text]' },
-      :content => /Text should not be lost/
-    assert_tag 'input',
-      :attributes => { :name => 'content[comments]', :value => 'My comments' }
-
-    c.reload
-    assert_equal 'Previous text', c.text
-    assert_equal 2, c.version
-  end
-
-  def test_update_section
-    @request.session[:user_id] = 2
-    page = WikiPage.find_by_title('Page_with_sections')
-    section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
-    text = page.content.text
-
-    assert_no_difference 'WikiPage.count' do
-      assert_no_difference 'WikiContent.count' do
-        assert_difference 'WikiContent::Version.count' do
-          put :update, :project_id => 1, :id => 'Page_with_sections',
-            :content => {
-              :text => "New section content",
-              :version => 3
-            },
-            :section => 2,
-            :section_hash => hash
-        end
-      end
-    end
-    assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections'
-    assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.reload.content.text
-  end
-
-  def test_update_section_should_allow_stale_page_update
-    @request.session[:user_id] = 2
-    page = WikiPage.find_by_title('Page_with_sections')
-    section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
-    text = page.content.text
-
-    assert_no_difference 'WikiPage.count' do
-      assert_no_difference 'WikiContent.count' do
-        assert_difference 'WikiContent::Version.count' do
-          put :update, :project_id => 1, :id => 'Page_with_sections',
-            :content => {
-              :text => "New section content",
-              :version => 2 # Current version is 3
-            },
-            :section => 2,
-            :section_hash => hash
-        end
-      end
-    end
-    assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections'
-    page.reload
-    assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.content.text
-    assert_equal 4, page.content.version
-  end
-
-  def test_update_section_should_not_allow_stale_section_update
-    @request.session[:user_id] = 2
-
-    assert_no_difference 'WikiPage.count' do
-      assert_no_difference 'WikiContent.count' do
-        assert_no_difference 'WikiContent::Version.count' do
-          put :update, :project_id => 1, :id => 'Page_with_sections',
-            :content => {
-              :comments => 'My comments',
-              :text => "Text should not be lost",
-              :version => 3
-            },
-            :section => 2,
-            :section_hash => Digest::MD5.hexdigest("wrong hash")
-        end
-      end
-    end
-    assert_response :success
-    assert_template 'edit'
-    assert_tag :div,
-      :attributes => { :class => /error/ },
-      :content => /Data has been updated by another user/
-    assert_tag 'textarea',
-      :attributes => { :name => 'content[text]' },
-      :content => /Text should not be lost/
-    assert_tag 'input',
-      :attributes => { :name => 'content[comments]', :value => 'My comments' }
-  end
-
-  def test_preview
-    @request.session[:user_id] = 2
-    xhr :post, :preview, :project_id => 1, :id => 'CookBook_documentation',
-                                   :content => { :comments => '',
-                                                 :text => 'this is a *previewed text*',
-                                                 :version => 3 }
-    assert_response :success
-    assert_template 'common/_preview'
-    assert_tag :tag => 'strong', :content => /previewed text/
-  end
-
-  def test_preview_new_page
-    @request.session[:user_id] = 2
-    xhr :post, :preview, :project_id => 1, :id => 'New page',
-                                   :content => { :text => 'h1. New page',
-                                                 :comments => '',
-                                                 :version => 0 }
-    assert_response :success
-    assert_template 'common/_preview'
-    assert_tag :tag => 'h1', :content => /New page/
-  end
-
-  def test_history
-    get :history, :project_id => 1, :id => 'CookBook_documentation'
-    assert_response :success
-    assert_template 'history'
-    assert_not_nil assigns(:versions)
-    assert_equal 3, assigns(:versions).size
-    assert_select "input[type=submit][name=commit]"
-  end
-
-  def test_history_with_one_version
-    get :history, :project_id => 1, :id => 'Another_page'
-    assert_response :success
-    assert_template 'history'
-    assert_not_nil assigns(:versions)
-    assert_equal 1, assigns(:versions).size
-    assert_select "input[type=submit][name=commit]", false
-  end
-
-  def test_diff
-    get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => 2, :version_from => 1
-    assert_response :success
-    assert_template 'diff'
-    assert_tag :tag => 'span', :attributes => { :class => 'diff_in'},
-                               :content => /updated/
-  end
-
-  def test_annotate
-    get :annotate, :project_id => 1, :id =>  'CookBook_documentation', :version => 2
-    assert_response :success
-    assert_template 'annotate'
-
-    # Line 1
-    assert_tag :tag => 'tr', :child => {
-      :tag => 'th', :attributes => {:class => 'line-num'}, :content => '1', :sibling => {
-        :tag => 'td', :attributes => {:class => 'author'}, :content => /John Smith/, :sibling => {
-          :tag => 'td', :content => /h1\. CookBook documentation/
-        }
-      }
-    }
-
-    # Line 5
-    assert_tag :tag => 'tr', :child => {
-      :tag => 'th', :attributes => {:class => 'line-num'}, :content => '5', :sibling => {
-        :tag => 'td', :attributes => {:class => 'author'}, :content => /redMine Admin/, :sibling => {
-          :tag => 'td', :content => /Some updated \[\[documentation\]\] here/
-        }
-      }
-    }
-  end
-
-  def test_get_rename
-    @request.session[:user_id] = 2
-    get :rename, :project_id => 1, :id => 'Another_page'
-    assert_response :success
-    assert_template 'rename'
-    assert_tag 'option',
-      :attributes => {:value => ''},
-      :content => '',
-      :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
-    assert_no_tag 'option',
-      :attributes => {:selected => 'selected'},
-      :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
-  end
-
-  def test_get_rename_child_page
-    @request.session[:user_id] = 2
-    get :rename, :project_id => 1, :id => 'Child_1'
-    assert_response :success
-    assert_template 'rename'
-    assert_tag 'option',
-      :attributes => {:value => ''},
-      :content => '',
-      :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
-    assert_tag 'option',
-      :attributes => {:value => '2', :selected => 'selected'},
-      :content => /Another page/,
-      :parent => {
-        :tag => 'select',
-        :attributes => {:name => 'wiki_page[parent_id]'}
-      }
-  end
-
-  def test_rename_with_redirect
-    @request.session[:user_id] = 2
-    post :rename, :project_id => 1, :id => 'Another_page',
-                            :wiki_page => { :title => 'Another renamed page',
-                                            :redirect_existing_links => 1 }
-    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
-    wiki = Project.find(1).wiki
-    # Check redirects
-    assert_not_nil wiki.find_page('Another page')
-    assert_nil wiki.find_page('Another page', :with_redirect => false)
-  end
-
-  def test_rename_without_redirect
-    @request.session[:user_id] = 2
-    post :rename, :project_id => 1, :id => 'Another_page',
-                            :wiki_page => { :title => 'Another renamed page',
-                                            :redirect_existing_links => "0" }
-    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
-    wiki = Project.find(1).wiki
-    # Check that there's no redirects
-    assert_nil wiki.find_page('Another page')
-  end
-
-  def test_rename_with_parent_assignment
-    @request.session[:user_id] = 2
-    post :rename, :project_id => 1, :id => 'Another_page',
-      :wiki_page => { :title => 'Another page', :redirect_existing_links => "0", :parent_id => '4' }
-    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
-    assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
-  end
-
-  def test_rename_with_parent_unassignment
-    @request.session[:user_id] = 2
-    post :rename, :project_id => 1, :id => 'Child_1',
-      :wiki_page => { :title => 'Child 1', :redirect_existing_links => "0", :parent_id => '' }
-    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
-    assert_nil WikiPage.find_by_title('Child_1').parent
-  end
-
-  def test_destroy_child
-    @request.session[:user_id] = 2
-    delete :destroy, :project_id => 1, :id => 'Child_1'
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-  end
-
-  def test_destroy_parent
-    @request.session[:user_id] = 2
-    assert_no_difference('WikiPage.count') do
-      delete :destroy, :project_id => 1, :id => 'Another_page'
-    end
-    assert_response :success
-    assert_template 'destroy'
-  end
-
-  def test_destroy_parent_with_nullify
-    @request.session[:user_id] = 2
-    assert_difference('WikiPage.count', -1) do
-      delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'nullify'
-    end
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-    assert_nil WikiPage.find_by_id(2)
-  end
-
-  def test_destroy_parent_with_cascade
-    @request.session[:user_id] = 2
-    assert_difference('WikiPage.count', -3) do
-      delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'destroy'
-    end
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-    assert_nil WikiPage.find_by_id(2)
-    assert_nil WikiPage.find_by_id(5)
-  end
-
-  def test_destroy_parent_with_reassign
-    @request.session[:user_id] = 2
-    assert_difference('WikiPage.count', -1) do
-      delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1
-    end
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-    assert_nil WikiPage.find_by_id(2)
-    assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
-  end
-
-  def test_index
-    get :index, :project_id => 'ecookbook'
-    assert_response :success
-    assert_template 'index'
-    pages = assigns(:pages)
-    assert_not_nil pages
-    assert_equal Project.find(1).wiki.pages.size, pages.size
-    assert_equal pages.first.content.updated_on, pages.first.updated_on
-
-    assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
-                    :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/CookBook_documentation' },
-                                              :content => 'CookBook documentation' },
-                                :child => { :tag => 'ul',
-                                            :child => { :tag => 'li',
-                                                        :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
-                                                                                 :content => 'Page with an inline image' } } } },
-                    :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Another_page' },
-                                                                       :content => 'Another page' } }
-  end
-
-  def test_index_should_include_atom_link
-    get :index, :project_id => 'ecookbook'
-    assert_tag 'a', :attributes => { :href => '/projects/ecookbook/activity.atom?show_wiki_edits=1'}
-  end
-
-  context "GET :export" do
-    context "with an authorized user to export the wiki" do
-      setup do
-        @request.session[:user_id] = 2
-        get :export, :project_id => 'ecookbook'
-      end
-
-      should_respond_with :success
-      should_assign_to :pages
-      should_respond_with_content_type "text/html"
-      should "export all of the wiki pages to a single html file" do
-        assert_select "a[name=?]", "CookBook_documentation"
-        assert_select "a[name=?]", "Another_page"
-        assert_select "a[name=?]", "Page_with_an_inline_image"
-      end
-
-    end
-
-    context "with an unauthorized user" do
-      setup do
-        get :export, :project_id => 'ecookbook'
-
-        should_respond_with :redirect
-        should_redirect_to('wiki index') { {:action => 'show', :project_id => @project, :id => nil} }
-      end
-    end
-  end
-
-  context "GET :date_index" do
-    setup do
-      get :date_index, :project_id => 'ecookbook'
-    end
-
-    should_respond_with :success
-    should_assign_to :pages
-    should_assign_to :pages_by_date
-    should_render_template 'wiki/date_index'
-
-    should "include atom link" do
-      assert_tag 'a', :attributes => { :href => '/projects/ecookbook/activity.atom?show_wiki_edits=1'}
-    end
-  end
-
-  def test_not_found
-    get :show, :project_id => 999
-    assert_response 404
-  end
-
-  def test_protect_page
-    page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
-    assert !page.protected?
-    @request.session[:user_id] = 2
-    post :protect, :project_id => 1, :id => page.title, :protected => '1'
-    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
-    assert page.reload.protected?
-  end
-
-  def test_unprotect_page
-    page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
-    assert page.protected?
-    @request.session[:user_id] = 2
-    post :protect, :project_id => 1, :id => page.title, :protected => '0'
-    assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
-    assert !page.reload.protected?
-  end
-
-  def test_show_page_with_edit_link
-    @request.session[:user_id] = 2
-    get :show, :project_id => 1
-    assert_response :success
-    assert_template 'show'
-    assert_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
-  end
-
-  def test_show_page_without_edit_link
-    @request.session[:user_id] = 4
-    get :show, :project_id => 1
-    assert_response :success
-    assert_template 'show'
-    assert_no_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
-  end
-
-  def test_show_pdf
-    @request.session[:user_id] = 2
-    get :show, :project_id => 1, :format => 'pdf'
-    assert_response :success
-    assert_not_nil assigns(:page)
-    assert_equal 'application/pdf', @response.content_type
-    assert_equal 'attachment; filename="CookBook_documentation.pdf"',
-                  @response.headers['Content-Disposition']
-  end
-
-  def test_show_html
-    @request.session[:user_id] = 2
-    get :show, :project_id => 1, :format => 'html'
-    assert_response :success
-    assert_not_nil assigns(:page)
-    assert_equal 'text/html', @response.content_type
-    assert_equal 'attachment; filename="CookBook_documentation.html"',
-                  @response.headers['Content-Disposition']
-  end
-
-  def test_show_txt
-    @request.session[:user_id] = 2
-    get :show, :project_id => 1, :format => 'txt'
-    assert_response :success
-    assert_not_nil assigns(:page)
-    assert_equal 'text/plain', @response.content_type
-    assert_equal 'attachment; filename="CookBook_documentation.txt"',
-                  @response.headers['Content-Disposition']
-  end
-
-  def test_edit_unprotected_page
-    # Non members can edit unprotected wiki pages
-    @request.session[:user_id] = 4
-    get :edit, :project_id => 1, :id => 'Another_page'
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_edit_protected_page_by_nonmember
-    # Non members can't edit protected wiki pages
-    @request.session[:user_id] = 4
-    get :edit, :project_id => 1, :id => 'CookBook_documentation'
-    assert_response 403
-  end
-
-  def test_edit_protected_page_by_member
-    @request.session[:user_id] = 2
-    get :edit, :project_id => 1, :id => 'CookBook_documentation'
-    assert_response :success
-    assert_template 'edit'
-  end
-
-  def test_history_of_non_existing_page_should_return_404
-    get :history, :project_id => 1, :id => 'Unknown_page'
-    assert_response 404
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e0/e05aa95bf99a3917bb79c084e2f744f98528a8e7.svn-base
--- a/.svn/pristine/e0/e05aa95bf99a3917bb79c084e2f744f98528a8e7.svn-base
+++ /dev/null
@@ -1,505 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'repositories_controller'
-
-# Re-raise errors caught by the controller.
-class RepositoriesController; def rescue_action(e) raise e end; end
-
-class RepositoriesMercurialControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles,
-           :repositories, :enabled_modules
-
-  REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
-  CHAR_1_HEX = "\xc3\x9c"
-  PRJ_ID     = 3
-  NUM_REV    = 32
-
-  ruby19_non_utf8_pass =
-     (RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8')
-
-  def setup
-    @controller = RepositoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-    @project    = Project.find(PRJ_ID)
-    @repository = Repository::Mercurial.create(
-                      :project => @project,
-                      :url     => REPOSITORY_PATH,
-                      :path_encoding => 'ISO-8859-1'
-                      )
-    assert @repository
-    @diff_c_support = true
-    @char_1        = CHAR_1_HEX.dup
-    @tag_char_1    = "tag-#{CHAR_1_HEX}-00"
-    @branch_char_0 = "branch-#{CHAR_1_HEX}-00"
-    @branch_char_1 = "branch-#{CHAR_1_HEX}-01"
-    if @char_1.respond_to?(:force_encoding)
-      @char_1.force_encoding('UTF-8')
-      @tag_char_1.force_encoding('UTF-8')
-      @branch_char_0.force_encoding('UTF-8')
-      @branch_char_1.force_encoding('UTF-8')
-    end
-  end
-
-  if ruby19_non_utf8_pass
-    puts "TODO: Mercurial functional test fails in Ruby 1.9 " +
-         "and Encoding.default_external is not UTF-8. " +
-         "Current value is '#{Encoding.default_external.to_s}'"
-    def test_fake; assert true end
-  elsif File.directory?(REPOSITORY_PATH)
-    def test_show_root
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal 4, assigns(:entries).size
-      assert assigns(:entries).detect {|e| e.name == 'images'  && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
-      assert assigns(:entries).detect {|e| e.name == 'README'  && e.kind == 'file'}
-      assert_not_nil assigns(:changesets)
-      assert assigns(:changesets).size > 0
-    end
-
-    def test_show_directory
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      get :show, :id => PRJ_ID, :path => ['images']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entries)
-      assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name)
-      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
-      assert_not_nil entry
-      assert_equal 'file', entry.kind
-      assert_equal 'images/edit.png', entry.path
-      assert_not_nil assigns(:changesets)
-      assert assigns(:changesets).size > 0
-    end
-
-    def test_show_at_given_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      [0, '0', '0885933ad4f6'].each do |r1|
-        get :show, :id => PRJ_ID, :path => ['images'], :rev => r1
-        assert_response :success
-        assert_template 'show'
-        assert_not_nil assigns(:entries)
-        assert_equal ['delete.png'], assigns(:entries).collect(&:name)
-        assert_not_nil assigns(:changesets)
-        assert assigns(:changesets).size > 0
-      end
-    end
-
-    def test_show_directory_sql_escape_percent
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      [13, '13', '3a330eb32958'].each do |r1|
-        get :show, :id => PRJ_ID, :path => ['sql_escape', 'percent%dir'],
-            :rev => r1
-        assert_response :success
-        assert_template 'show'
-
-        assert_not_nil assigns(:entries)
-        assert_equal ['percent%file1.txt', 'percentfile1.txt'],
-                     assigns(:entries).collect(&:name)
-        changesets = assigns(:changesets)
-        assert_not_nil changesets
-        assert assigns(:changesets).size > 0
-        assert_equal %w(13 11 10 9), changesets.collect(&:revision)
-      end
-    end
-
-    def test_show_directory_latin_1_path
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      [21, '21', 'adf805632193'].each do |r1|
-        get :show, :id => PRJ_ID, :path => ['latin-1-dir'], :rev => r1
-        assert_response :success
-        assert_template 'show'
-
-        assert_not_nil assigns(:entries)
-        assert_equal ["make-latin-1-file.rb",
-                      "test-#{@char_1}-1.txt",
-                      "test-#{@char_1}-2.txt",
-                      "test-#{@char_1}.txt"], assigns(:entries).collect(&:name)
-        changesets = assigns(:changesets)
-        assert_not_nil changesets
-        assert_equal %w(21 20 19 18 17), changesets.collect(&:revision)
-      end
-    end
-
-    def test_show_branch
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-       [
-          'default',
-          @branch_char_1,
-          'branch (1)[2]&,%.-3_4',
-          @branch_char_0,
-          'test_branch.latin-1',
-          'test-branch-00',
-      ].each do |bra|
-        get :show, :id => PRJ_ID, :rev => bra
-        assert_response :success
-        assert_template 'show'
-        assert_not_nil assigns(:entries)
-        assert assigns(:entries).size > 0
-        assert_not_nil assigns(:changesets)
-        assert assigns(:changesets).size > 0
-      end
-    end
-
-    def test_show_tag
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-       [
-        @tag_char_1,
-        'tag_test.00',
-        'tag-init-revision'
-      ].each do |tag|
-        get :show, :id => PRJ_ID, :rev => tag
-        assert_response :success
-        assert_template 'show'
-        assert_not_nil assigns(:entries)
-        assert assigns(:entries).size > 0
-        assert_not_nil assigns(:changesets)
-        assert assigns(:changesets).size > 0
-      end
-    end
-
-    def test_changes
-      get :changes, :id => PRJ_ID, :path => ['images', 'edit.png']
-      assert_response :success
-      assert_template 'changes'
-      assert_tag :tag => 'h2', :content => 'edit.png'
-    end
-
-    def test_entry_show
-      get :entry, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb']
-      assert_response :success
-      assert_template 'entry'
-      # Line 10
-      assert_tag :tag => 'th',
-                 :content => '10',
-                 :attributes => { :class => 'line-num' },
-                 :sibling => { :tag => 'td', :content => /WITHOUT ANY WARRANTY/ }
-    end
-
-    def test_entry_show_latin_1_path
-      [21, '21', 'adf805632193'].each do |r1|
-        get :entry, :id => PRJ_ID,
-            :path => ['latin-1-dir', "test-#{@char_1}-2.txt"], :rev => r1
-        assert_response :success
-        assert_template 'entry'
-        assert_tag :tag => 'th',
-                 :content => '1',
-                 :attributes => { :class => 'line-num' },
-                 :sibling => { :tag => 'td',
-                               :content => /Mercurial is a distributed version control system/ }
-      end
-    end
-
-    def test_entry_show_latin_1_contents
-      with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
-        [27, '27', '7bbf4c738e71'].each do |r1|
-          get :entry, :id => PRJ_ID,
-              :path => ['latin-1-dir', "test-#{@char_1}.txt"], :rev => r1
-          assert_response :success
-          assert_template 'entry'
-          assert_tag :tag => 'th',
-                 :content => '1',
-                 :attributes => { :class => 'line-num' },
-                 :sibling => { :tag => 'td',
-                               :content => /test-#{@char_1}.txt/ }
-        end
-      end
-    end
-
-    def test_entry_download
-      get :entry, :id => PRJ_ID,
-          :path => ['sources', 'watchers_controller.rb'], :format => 'raw'
-      assert_response :success
-      # File content
-      assert @response.body.include?('WITHOUT ANY WARRANTY')
-    end
-
-    def test_entry_binary_force_download
-      get :entry, :id => PRJ_ID, :rev => 1, :path => ['images', 'edit.png']
-      assert_response :success
-      assert_equal 'image/png', @response.content_type
-    end
-
-    def test_directory_entry
-      get :entry, :id => PRJ_ID, :path => ['sources']
-      assert_response :success
-      assert_template 'show'
-      assert_not_nil assigns(:entry)
-      assert_equal 'sources', assigns(:entry).name
-    end
-
-    def test_diff
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      [4, '4', 'def6d2f1254a'].each do |r1|
-        # Full diff of changeset 4
-        ['inline', 'sbs'].each do |dt|
-          get :diff, :id => PRJ_ID, :rev => r1, :type => dt
-          assert_response :success
-          assert_template 'diff'
-          if @diff_c_support
-            # Line 22 removed
-            assert_tag :tag => 'th',
-                       :content => '22',
-                       :sibling => { :tag => 'td',
-                                     :attributes => { :class => /diff_out/ },
-                                     :content => /def remove/ }
-            assert_tag :tag => 'h2', :content => /4:def6d2f1254a/
-          end
-        end
-      end
-    end
-
-    def test_diff_two_revs
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      [2, '400bb8672109', '400', 400].each do |r1|
-        [4, 'def6d2f1254a'].each do |r2|
-          ['inline', 'sbs'].each do |dt|
-            get :diff,
-                :id     => PRJ_ID,
-                :rev    => r1,
-                :rev_to => r2,
-                :type => dt
-            assert_response :success
-            assert_template 'diff'
-            diff = assigns(:diff)
-            assert_not_nil diff
-            assert_tag :tag => 'h2',
-                       :content => /4:def6d2f1254a 2:400bb8672109/
-          end
-        end
-      end
-    end
-
-    def test_diff_latin_1_path
-      with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
-        [21, 'adf805632193'].each do |r1|
-          ['inline', 'sbs'].each do |dt|
-            get :diff, :id => PRJ_ID, :rev => r1, :type => dt
-            assert_response :success
-            assert_template 'diff'
-            assert_tag :tag => 'thead',
-                       :descendant => {
-                         :tag => 'th',
-                         :attributes => { :class => 'filename' } ,
-                         :content => /latin-1-dir\/test-#{@char_1}-2.txt/ ,
-                        },
-                       :sibling => {
-                         :tag => 'tbody',
-                         :descendant => {
-                            :tag => 'td',
-                            :attributes => { :class => /diff_in/ },
-                            :content => /It is written in Python/
-                         }
-                       }
-          end
-        end
-      end
-    end
-
-    def test_annotate
-      get :annotate, :id => PRJ_ID, :path => ['sources', 'watchers_controller.rb']
-      assert_response :success
-      assert_template 'annotate'
-      # Line 23, revision 4:def6d2f1254a
-      assert_tag :tag => 'th',
-                 :content => '23',
-                 :attributes => { :class => 'line-num' },
-                 :sibling =>
-                       {
-                         :tag => 'td',
-                         :attributes => { :class => 'revision' },
-                         :child => { :tag => 'a', :content => '4:def6d2f1254a' }
-                       }
-      assert_tag :tag => 'th',
-                 :content => '23',
-                 :attributes => { :class => 'line-num' },
-                 :sibling =>
-                       {
-                          :tag     => 'td'    ,
-                          :content => 'jsmith' ,
-                          :attributes => { :class   => 'author' },
-                        }
-      assert_tag :tag => 'th',
-                 :content => '23',
-                 :attributes => { :class => 'line-num' },
-                 :sibling => { :tag => 'td', :content => /watcher =/ }
-    end
-
-    def test_annotate_not_in_tip
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :annotate, :id => PRJ_ID,
-          :path => ['sources', 'welcome_controller.rb']
-      assert_response 404
-      assert_error_tag :content => /was not found/
-    end
-
-    def test_annotate_at_given_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      [2, '400bb8672109', '400', 400].each do |r1|
-        get :annotate, :id => PRJ_ID, :rev => r1,
-            :path => ['sources', 'watchers_controller.rb']
-        assert_response :success
-        assert_template 'annotate'
-        assert_tag :tag => 'h2', :content => /@ 2:400bb8672109/
-      end
-    end
-
-    def test_annotate_latin_1_path
-      [21, '21', 'adf805632193'].each do |r1|
-        get :annotate, :id => PRJ_ID,
-            :path => ['latin-1-dir', "test-#{@char_1}-2.txt"], :rev => r1
-        assert_response :success
-        assert_template 'annotate'
-        assert_tag :tag => 'th',
-                 :content => '1',
-                 :attributes => { :class => 'line-num' },
-                 :sibling =>
-                       {
-                         :tag => 'td',
-                         :attributes => { :class => 'revision' },
-                         :child => { :tag => 'a', :content => '20:709858aafd1b' }
-                       }
-        assert_tag :tag => 'th',
-                 :content => '1',
-                 :attributes => { :class => 'line-num' },
-                 :sibling =>
-                       {
-                          :tag     => 'td'    ,
-                          :content => 'jsmith' ,
-                          :attributes => { :class   => 'author' },
-                        }
-        assert_tag :tag => 'th',
-                 :content => '1',
-                 :attributes => { :class => 'line-num' },
-                 :sibling => { :tag => 'td',
-                               :content => /Mercurial is a distributed version control system/ }
-
-      end
-    end
-
-    def test_annotate_latin_1_contents
-      with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
-        [27, '7bbf4c738e71'].each do |r1|
-          get :annotate, :id => PRJ_ID,
-              :path => ['latin-1-dir', "test-#{@char_1}.txt"], :rev => r1
-          assert_tag :tag => 'th',
-                     :content => '1',
-                     :attributes => { :class => 'line-num' },
-                     :sibling => { :tag => 'td',
-                                   :content => /test-#{@char_1}.txt/ }
-        end
-      end
-    end
-
-    def test_empty_revision
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-      ['', ' ', nil].each do |r|
-        get :revision, :id => PRJ_ID, :rev => r
-        assert_response 404
-        assert_error_tag :content => /was not found/
-      end
-    end
-
-    def test_destroy_valid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-
-    def test_destroy_invalid_repository
-      @request.session[:user_id] = 1 # admin
-      assert_equal 0, @repository.changesets.count
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal NUM_REV, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-
-      @repository = Repository::Mercurial.create(
-                      :project => Project.find(PRJ_ID),
-                      :url     => "/invalid",
-                      :path_encoding => 'ISO-8859-1'
-                      )
-      assert @repository
-      @repository.fetch_changesets
-      @project.reload
-      assert_equal 0, @repository.changesets.count
-
-      get :destroy, :id => PRJ_ID
-      assert_response 302
-      @project.reload
-      assert_nil @project.repository
-    end
-  else
-    puts "Mercurial test repository NOT FOUND. Skipping functional tests !!!"
-    def test_fake; assert true end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e0/e06c6b7247c11f5c7b45c36ab3ee4c82d2c34951.svn-base
--- a/.svn/pristine/e0/e06c6b7247c11f5c7b45c36ab3ee4c82d2c34951.svn-base
+++ /dev/null
@@ -1,164 +0,0 @@
---- 
-users_004: 
-  created_on: 2006-07-19 19:34:07 +02:00
-  status: 1
-  last_login_on: 
-  language: en
-  # password = foo
-  salt: 3126f764c3c5ac61cbfc103f25f934cf
-  hashed_password: 9e4dd7eeb172c12a0691a6d9d3a269f7e9fe671b
-  updated_on: 2006-07-19 19:34:07 +02:00
-  admin: false
-  mail: rhill@somenet.foo
-  lastname: Hill
-  firstname: Robert
-  id: 4
-  auth_source_id: 
-  mail_notification: all
-  login: rhill
-  type: User
-users_001: 
-  created_on: 2006-07-19 19:12:21 +02:00
-  status: 1
-  last_login_on: 2006-07-19 22:57:52 +02:00
-  language: en
-  # password = admin
-  salt: 82090c953c4a0000a7db253b0691a6b4
-  hashed_password: b5b6ff9543bf1387374cdfa27a54c96d236a7150
-  updated_on: 2006-07-19 22:57:52 +02:00
-  admin: true
-  mail: admin@somenet.foo
-  lastname: Admin
-  firstname: redMine
-  id: 1
-  auth_source_id: 
-  mail_notification: all
-  login: admin
-  type: User
-users_002: 
-  created_on: 2006-07-19 19:32:09 +02:00
-  status: 1
-  last_login_on: 2006-07-19 22:42:15 +02:00
-  language: en
-  # password = jsmith
-  salt: 67eb4732624d5a7753dcea7ce0bb7d7d
-  hashed_password: bfbe06043353a677d0215b26a5800d128d5413bc
-  updated_on: 2006-07-19 22:42:15 +02:00
-  admin: false
-  mail: jsmith@somenet.foo
-  lastname: Smith
-  firstname: John
-  id: 2
-  auth_source_id: 
-  mail_notification: all
-  login: jsmith
-  type: User
-users_003: 
-  created_on: 2006-07-19 19:33:19 +02:00
-  status: 1
-  last_login_on: 
-  language: en
-  # password = foo
-  salt: 7599f9963ec07b5a3b55b354407120c0
-  hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
-  updated_on: 2006-07-19 19:33:19 +02:00
-  admin: false
-  mail: dlopper@somenet.foo
-  lastname: Lopper
-  firstname: Dave
-  id: 3
-  auth_source_id: 
-  mail_notification: all
-  login: dlopper
-  type: User
-users_005: 
-  id: 5
-  created_on: 2006-07-19 19:33:19 +02:00
-  # Locked
-  status: 3
-  last_login_on: 
-  language: en
-  hashed_password: 1
-  updated_on: 2006-07-19 19:33:19 +02:00
-  admin: false
-  mail: dlopper2@somenet.foo
-  lastname: Lopper2
-  firstname: Dave2
-  auth_source_id: 
-  mail_notification: all
-  login: dlopper2
-  type: User
-users_006: 
-  id: 6
-  created_on: 2006-07-19 19:33:19 +02:00
-  status: 0
-  last_login_on: 
-  language: ''
-  hashed_password: 1
-  updated_on: 2006-07-19 19:33:19 +02:00
-  admin: false
-  mail: ''
-  lastname: Anonymous
-  firstname: ''
-  auth_source_id: 
-  mail_notification: only_my_events
-  login: ''
-  type: AnonymousUser
-users_007: 
-  id: 7
-  created_on: 2006-07-19 19:33:19 +02:00
-  status: 1
-  last_login_on: 
-  language: ''
-  hashed_password: 1
-  updated_on: 2006-07-19 19:33:19 +02:00
-  admin: false
-  mail: someone@foo.bar
-  lastname: One
-  firstname: Some
-  auth_source_id: 
-  mail_notification: only_my_events
-  login: someone
-  type: User
-users_008: 
-  id: 8
-  created_on: 2006-07-19 19:33:19 +02:00
-  status: 1
-  last_login_on: 
-  language: 'it'
-  hashed_password: 1
-  updated_on: 2006-07-19 19:33:19 +02:00
-  admin: false
-  mail: miscuser8@foo.bar
-  lastname: Misc
-  firstname: User
-  auth_source_id: 
-  mail_notification: only_my_events
-  login: miscuser8
-  type: User
-users_009: 
-  id: 9
-  created_on: 2006-07-19 19:33:19 +02:00
-  status: 1
-  last_login_on: 
-  language: 'it'
-  hashed_password: 1
-  updated_on: 2006-07-19 19:33:19 +02:00
-  admin: false
-  mail: miscuser9@foo.bar
-  lastname: Misc
-  firstname: User
-  auth_source_id: 
-  mail_notification: only_my_events
-  login: miscuser9
-  type: User
-groups_010: 
-  id: 10
-  lastname: A Team
-  type: Group
-groups_011: 
-  id: 11
-  lastname: B Team
-  type: Group
-
-  
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e0/e088e5d4b6c4b6c95679e610fde9533e4329854a.svn-base
--- /dev/null
+++ b/.svn/pristine/e0/e088e5d4b6c4b6c95679e610fde9533e4329854a.svn-base
@@ -0,0 +1,1213 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class ApplicationHelperTest < ActionView::TestCase
+  include ERB::Util
+  include Rails.application.routes.url_helpers
+
+  fixtures :projects, :roles, :enabled_modules, :users,
+           :repositories, :changesets,
+           :trackers, :issue_statuses, :issues, :versions, :documents,
+           :wikis, :wiki_pages, :wiki_contents,
+           :boards, :messages, :news,
+           :attachments, :enumerations
+
+  def setup
+    super
+    set_tmp_attachments_directory
+  end
+
+  context "#link_to_if_authorized" do
+    context "authorized user" do
+      should "be tested"
+    end
+
+    context "unauthorized user" do
+      should "be tested"
+    end
+
+    should "allow using the :controller and :action for the target link" do
+      User.current = User.find_by_login('admin')
+
+      @project = Issue.first.project # Used by helper
+      response = link_to_if_authorized("By controller/action",
+                                       {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
+      assert_match /href/, response
+    end
+
+  end
+
+  def test_auto_links
+    to_test = {
+      'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
+      'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
+      'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
+      'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
+      'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
+      'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
+      'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
+      'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
+      '(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : <a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>)',
+      '(see inline link : http://www.foo.bar/Test)' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>)',
+      '(see inline link : http://www.foo.bar/Test).' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>).',
+      '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
+      '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
+      '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
+      'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
+      'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&#38;t=z&#38;s=">http://foo.bar/page?p=1&#38;t=z&#38;s=</a>',
+      'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
+      'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
+      'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
+      'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
+      'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
+      'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
+      # two exclamation marks
+      'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
+      # escaping
+      'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo&quot;bar</a>',
+      # wrap in angle brackets
+      '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;',
+      # invalid urls
+      'http://' => 'http://',
+      'www.' => 'www.',
+      'test-www.bar.com' => 'test-www.bar.com',
+    }
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  if 'ruby'.respond_to?(:encoding)
+    def test_auto_links_with_non_ascii_characters
+      to_test = {
+        'http://foo.bar/Ñ‚ÐµÑÑ‚' => '<a class="external" href="http://foo.bar/Ñ‚ÐµÑÑ‚">http://foo.bar/Ñ‚ÐµÑÑ‚</a>'
+      }
+      to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+    end
+  else
+    puts 'Skipping test_auto_links_with_non_ascii_characters, unsupported ruby version'
+  end
+
+  def test_auto_mailto
+    to_test = {
+      'test@foo.bar' => '<a class="email" href="mailto:test@foo.bar">test@foo.bar</a>',
+      'test@www.foo.bar' => '<a class="email" href="mailto:test@www.foo.bar">test@www.foo.bar</a>',
+    }
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  def test_inline_images
+    to_test = {
+      '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
+      'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
+      'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
+      'with style !{width:100px;height:100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" style="width:100px;height:100px;" alt="" />',
+      'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a title" alt="This is a title" />',
+      'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a double-quoted &quot;title&quot;" alt="This is a double-quoted &quot;title&quot;" />',
+    }
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  def test_inline_images_inside_tags
+    raw = <<-RAW
+h1. !foo.png! Heading
+
+Centered image:
+
+p=. !bar.gif!
+RAW
+
+    assert textilizable(raw).include?('<img src="foo.png" alt="" />')
+    assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
+  end
+
+  def test_attached_images
+    to_test = {
+      'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
+      'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
+      'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
+      'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
+      # link image
+      '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" /></a>',
+    }
+    attachments = Attachment.all
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
+  end
+
+  def test_attached_images_filename_extension
+    set_tmp_attachments_directory
+    a1 = Attachment.new(
+            :container => Issue.find(1),
+            :file => mock_file_with_options({:original_filename => "testtest.JPG"}),
+            :author => User.find(1))
+    assert a1.save
+    assert_equal "testtest.JPG", a1.filename
+    assert_equal "image/jpeg", a1.content_type
+    assert a1.image?
+
+    a2 = Attachment.new(
+            :container => Issue.find(1),
+            :file => mock_file_with_options({:original_filename => "testtest.jpeg"}),
+            :author => User.find(1))
+    assert a2.save
+    assert_equal "testtest.jpeg", a2.filename
+    assert_equal "image/jpeg", a2.content_type
+    assert a2.image?
+
+    a3 = Attachment.new(
+            :container => Issue.find(1),
+            :file => mock_file_with_options({:original_filename => "testtest.JPE"}),
+            :author => User.find(1))
+    assert a3.save
+    assert_equal "testtest.JPE", a3.filename
+    assert_equal "image/jpeg", a3.content_type
+    assert a3.image?
+
+    a4 = Attachment.new(
+            :container => Issue.find(1),
+            :file => mock_file_with_options({:original_filename => "Testtest.BMP"}),
+            :author => User.find(1))
+    assert a4.save
+    assert_equal "Testtest.BMP", a4.filename
+    assert_equal "image/x-ms-bmp", a4.content_type
+    assert a4.image?
+
+    to_test = {
+      'Inline image: !testtest.jpg!' =>
+        'Inline image: <img src="/attachments/download/' + a1.id.to_s + '/testtest.JPG" alt="" />',
+      'Inline image: !testtest.jpeg!' =>
+        'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testtest.jpeg" alt="" />',
+      'Inline image: !testtest.jpe!' =>
+        'Inline image: <img src="/attachments/download/' + a3.id.to_s + '/testtest.JPE" alt="" />',
+      'Inline image: !testtest.bmp!' =>
+        'Inline image: <img src="/attachments/download/' + a4.id.to_s + '/Testtest.BMP" alt="" />',
+    }
+
+    attachments = [a1, a2, a3, a4]
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
+  end
+
+  def test_attached_images_should_read_later
+    set_fixtures_attachments_directory
+    a1 = Attachment.find(16)
+    assert_equal "testfile.png", a1.filename
+    assert a1.readable?
+    assert (! a1.visible?(User.anonymous))
+    assert a1.visible?(User.find(2))
+    a2 = Attachment.find(17)
+    assert_equal "testfile.PNG", a2.filename
+    assert a2.readable?
+    assert (! a2.visible?(User.anonymous))
+    assert a2.visible?(User.find(2))
+    assert a1.created_on < a2.created_on
+
+    to_test = {
+      'Inline image: !testfile.png!' =>
+        'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
+      'Inline image: !Testfile.PNG!' =>
+        'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
+    }
+    attachments = [a1, a2]
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
+    set_tmp_attachments_directory
+  end
+
+  def test_textile_external_links
+    to_test = {
+      'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
+      'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
+      '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
+      '"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
+      "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
+      # no multiline link text
+      "This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />and another on a second line\":test",
+      # mailto link
+      "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
+      # two exclamation marks
+      '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
+      # escaping
+      '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
+    }
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  if 'ruby'.respond_to?(:encoding)
+    def test_textile_external_links_with_non_ascii_characters
+      to_test = {
+        'This is a "link":http://foo.bar/Ñ‚ÐµÑÑ‚' => 'This is a <a href="http://foo.bar/Ñ‚ÐµÑÑ‚" class="external">link</a>'
+      }
+      to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+    end
+  else
+    puts 'Skipping test_textile_external_links_with_non_ascii_characters, unsupported ruby version'
+  end
+
+  def test_redmine_links
+    issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
+                               :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
+    note_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'},
+                               :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
+
+    revision_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
+                                   :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
+    revision_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
+                                    :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
+
+    changeset_link2 = link_to('691322a8eb01e11fd7',
+                              {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
+                               :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
+
+    document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
+                                             :class => 'document')
+
+    version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
+                                  :class => 'version')
+
+    board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
+
+    message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
+    
+    news_url = {:controller => 'news', :action => 'show', :id => 1}
+
+    project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
+
+    source_url = '/projects/ecookbook/repository/entry/some/file'
+    source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file'
+    source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext'
+    source_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/entry/some/file.ext'
+    source_url_with_branch = '/projects/ecookbook/repository/revisions/branch/entry/some/file'
+
+    export_url = '/projects/ecookbook/repository/raw/some/file'
+    export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
+    export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext'
+    export_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/raw/some/file.ext'
+    export_url_with_branch = '/projects/ecookbook/repository/revisions/branch/raw/some/file'
+
+    to_test = {
+      # tickets
+      '#3, [#3], (#3) and #3.'      => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
+      # ticket notes
+      '#3-14'                       => note_link,
+      '#3#note-14'                  => note_link,
+      # should not ignore leading zero
+      '#03'                         => '#03',
+      # changesets
+      'r1'                          => revision_link,
+      'r1.'                         => "#{revision_link}.",
+      'r1, r2'                      => "#{revision_link}, #{revision_link2}",
+      'r1,r2'                       => "#{revision_link},#{revision_link2}",
+      'commit:691322a8eb01e11fd7'   => changeset_link2,
+      # documents
+      'document#1'                  => document_link,
+      'document:"Test document"'    => document_link,
+      # versions
+      'version#2'                   => version_link,
+      'version:1.0'                 => version_link,
+      'version:"1.0"'               => version_link,
+      # source
+      'source:some/file'            => link_to('source:some/file', source_url, :class => 'source'),
+      'source:/some/file'           => link_to('source:/some/file', source_url, :class => 'source'),
+      'source:/some/file.'          => link_to('source:/some/file', source_url, :class => 'source') + ".",
+      'source:/some/file.ext.'      => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
+      'source:/some/file. '         => link_to('source:/some/file', source_url, :class => 'source') + ".",
+      'source:/some/file.ext. '     => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
+      'source:/some/file, '         => link_to('source:/some/file', source_url, :class => 'source') + ",",
+      'source:/some/file@52'        => link_to('source:/some/file@52', source_url_with_rev, :class => 'source'),
+      'source:/some/file@branch'    => link_to('source:/some/file@branch', source_url_with_branch, :class => 'source'),
+      'source:/some/file.ext@52'    => link_to('source:/some/file.ext@52', source_url_with_rev_and_ext, :class => 'source'),
+      'source:/some/file#L110'      => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'),
+      'source:/some/file.ext#L110'  => link_to('source:/some/file.ext#L110', source_url_with_ext + "#L110", :class => 'source'),
+      'source:/some/file@52#L110'   => link_to('source:/some/file@52#L110', source_url_with_rev + "#L110", :class => 'source'),
+      # export
+      'export:/some/file'           => link_to('export:/some/file', export_url, :class => 'source download'),
+      'export:/some/file.ext'       => link_to('export:/some/file.ext', export_url_with_ext, :class => 'source download'),
+      'export:/some/file@52'        => link_to('export:/some/file@52', export_url_with_rev, :class => 'source download'),
+      'export:/some/file.ext@52'    => link_to('export:/some/file.ext@52', export_url_with_rev_and_ext, :class => 'source download'),
+      'export:/some/file@branch'    => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'),
+      # forum
+      'forum#2'                     => link_to('Discussion', board_url, :class => 'board'),
+      'forum:Discussion'            => link_to('Discussion', board_url, :class => 'board'),
+      # message
+      'message#4'                   => link_to('Post 2', message_url, :class => 'message'),
+      'message#5'                   => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
+      # news
+      'news#1'                      => link_to('eCookbook first release !', news_url, :class => 'news'),
+      'news:"eCookbook first release !"'        => link_to('eCookbook first release !', news_url, :class => 'news'),
+      # project
+      'project#3'                   => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
+      'project:subproject1'         => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
+      'project:"eCookbook subProject 1"'        => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
+      # not found
+      '#0123456789'                 => '#0123456789',
+      # invalid expressions
+      'source:'                     => 'source:',
+      # url hash
+      "http://foo.bar/FAQ#3"       => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
+    }
+    @project = Project.find(1)
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
+  end
+
+  def test_redmine_links_with_a_different_project_before_current_project
+    vp1 = Version.generate!(:project_id => 1, :name => '1.4.4')
+    vp3 = Version.generate!(:project_id => 3, :name => '1.4.4')
+
+    @project = Project.find(3)
+    assert_equal %(<p><a href="/versions/#{vp1.id}" class="version">1.4.4</a> <a href="/versions/#{vp3.id}" class="version">1.4.4</a></p>),
+      textilizable("ecookbook:version:1.4.4 version:1.4.4")
+  end
+
+  def test_escaped_redmine_links_should_not_be_parsed
+    to_test = [
+      '#3.',
+      '#3-14.',
+      '#3#-note14.',
+      'r1',
+      'document#1',
+      'document:"Test document"',
+      'version#2',
+      'version:1.0',
+      'version:"1.0"',
+      'source:/some/file'
+    ]
+    @project = Project.find(1)
+    to_test.each { |text| assert_equal "<p>#{text}</p>", textilizable("!" + text), "#{text} failed" }
+  end
+
+  def test_cross_project_redmine_links
+    source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
+      :class => 'source')
+
+    changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
+      :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
+
+    to_test = {
+      # documents
+      'document:"Test document"'              => 'document:"Test document"',
+      'ecookbook:document:"Test document"'    => '<a href="/documents/1" class="document">Test document</a>',
+      'invalid:document:"Test document"'      => 'invalid:document:"Test document"',
+      # versions
+      'version:"1.0"'                         => 'version:"1.0"',
+      'ecookbook:version:"1.0"'               => '<a href="/versions/2" class="version">1.0</a>',
+      'invalid:version:"1.0"'                 => 'invalid:version:"1.0"',
+      # changeset
+      'r2'                                    => 'r2',
+      'ecookbook:r2'                          => changeset_link,
+      'invalid:r2'                            => 'invalid:r2',
+      # source
+      'source:/some/file'                     => 'source:/some/file',
+      'ecookbook:source:/some/file'           => source_link,
+      'invalid:source:/some/file'             => 'invalid:source:/some/file',
+    }
+    @project = Project.find(3)
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
+  end
+
+  def test_multiple_repositories_redmine_links
+    svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg')
+    Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
+    hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
+    Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
+
+    changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
+                                    :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
+    svn_changeset_link = link_to('svn_repo-1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn_repo-1', :rev => 123},
+                                    :class => 'changeset', :title => '')
+    hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
+                                    :class => 'changeset', :title => '')
+
+    source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
+    hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
+
+    to_test = {
+      'r2'                          => changeset_link,
+      'svn_repo-1|r123'             => svn_changeset_link,
+      'invalid|r123'                => 'invalid|r123',
+      'commit:hg1|abcd'             => hg_changeset_link,
+      'commit:invalid|abcd'         => 'commit:invalid|abcd',
+      # source
+      'source:some/file'            => source_link,
+      'source:hg1|some/file'        => hg_source_link,
+      'source:invalid|some/file'    => 'source:invalid|some/file',
+    }
+
+    @project = Project.find(1)
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
+  end
+
+  def test_cross_project_multiple_repositories_redmine_links
+    svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
+    Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
+    hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
+    Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
+
+    changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
+                                    :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
+    svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
+                                    :class => 'changeset', :title => '')
+    hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
+                                    :class => 'changeset', :title => '')
+
+    source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
+    hg_source_link = link_to('ecookbook:source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
+
+    to_test = {
+      'ecookbook:r2'                           => changeset_link,
+      'ecookbook:svn1|r123'                    => svn_changeset_link,
+      'ecookbook:invalid|r123'                 => 'ecookbook:invalid|r123',
+      'ecookbook:commit:hg1|abcd'              => hg_changeset_link,
+      'ecookbook:commit:invalid|abcd'          => 'ecookbook:commit:invalid|abcd',
+      'invalid:commit:invalid|abcd'            => 'invalid:commit:invalid|abcd',
+      # source
+      'ecookbook:source:some/file'             => source_link,
+      'ecookbook:source:hg1|some/file'         => hg_source_link,
+      'ecookbook:source:invalid|some/file'     => 'ecookbook:source:invalid|some/file',
+      'invalid:source:invalid|some/file'       => 'invalid:source:invalid|some/file',
+    }
+
+    @project = Project.find(3)
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
+  end
+
+  def test_redmine_links_git_commit
+    changeset_link = link_to('abcd',
+                               {
+                                 :controller => 'repositories',
+                                 :action     => 'revision',
+                                 :id         => 'subproject1',
+                                 :rev        => 'abcd',
+                                },
+                              :class => 'changeset', :title => 'test commit')
+    to_test = {
+      'commit:abcd' => changeset_link,
+     }
+    @project = Project.find(3)
+    r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
+    assert r
+    c = Changeset.new(:repository => r,
+                      :committed_on => Time.now,
+                      :revision => 'abcd',
+                      :scmid => 'abcd',
+                      :comments => 'test commit')
+    assert( c.save )
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
+  def test_redmine_links_darcs_commit
+    changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
+                               {
+                                 :controller => 'repositories',
+                                 :action     => 'revision',
+                                 :id         => 'subproject1',
+                                 :rev        => '123',
+                                },
+                              :class => 'changeset', :title => 'test commit')
+    to_test = {
+      'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
+     }
+    @project = Project.find(3)
+    r = Repository::Darcs.create!(
+            :project => @project, :url => '/tmp/test/darcs',
+            :log_encoding => 'UTF-8')
+    assert r
+    c = Changeset.new(:repository => r,
+                      :committed_on => Time.now,
+                      :revision => '123',
+                      :scmid => '20080308225258-98289-abcd456efg.gz',
+                      :comments => 'test commit')
+    assert( c.save )
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  def test_redmine_links_mercurial_commit
+    changeset_link_rev = link_to('r123',
+                                  {
+                                     :controller => 'repositories',
+                                     :action     => 'revision',
+                                     :id         => 'subproject1',
+                                     :rev        => '123' ,
+                                  },
+                              :class => 'changeset', :title => 'test commit')
+    changeset_link_commit = link_to('abcd',
+                                  {
+                                        :controller => 'repositories',
+                                        :action     => 'revision',
+                                        :id         => 'subproject1',
+                                        :rev        => 'abcd' ,
+                                  },
+                              :class => 'changeset', :title => 'test commit')
+    to_test = {
+      'r123' => changeset_link_rev,
+      'commit:abcd' => changeset_link_commit,
+     }
+    @project = Project.find(3)
+    r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
+    assert r
+    c = Changeset.new(:repository => r,
+                      :committed_on => Time.now,
+                      :revision => '123',
+                      :scmid => 'abcd',
+                      :comments => 'test commit')
+    assert( c.save )
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  def test_attachment_links
+    to_test = {
+      'attachment:error281.txt' => '<a href="/attachments/download/1/error281.txt" class="attachment">error281.txt</a>'
+    }
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
+  end
+
+  def test_attachment_link_should_link_to_latest_attachment
+    set_tmp_attachments_directory
+    a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
+    a2 = Attachment.generate!(:filename => "test.txt")
+
+    assert_equal %(<p><a href="/attachments/download/#{a2.id}/test.txt" class="attachment">test.txt</a></p>),
+      textilizable('attachment:test.txt', :attachments => [a1, a2])
+  end
+
+  def test_wiki_links
+    to_test = {
+      '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
+      '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
+      # title content should be formatted
+      '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
+      '[[Another page|With title containing <strong>HTML entities &amp; markups</strong>]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With title containing &lt;strong&gt;HTML entities &amp; markups&lt;/strong&gt;</a>',
+      # link with anchor
+      '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
+      '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
+      # UTF8 anchor
+      '[[Another_page#Ð¢ÐµÑÑ‚|Ð¢ÐµÑÑ‚]]' => %|<a href="/projects/ecookbook/wiki/Another_page##{CGI.escape 'Ð¢ÐµÑÑ‚'}" class="wiki-page">Ð¢ÐµÑÑ‚</a>|,
+      # page that doesn't exist
+      '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
+      '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
+      # link to another project wiki
+      '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
+      '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
+      '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
+      '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
+      '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
+      # striked through link
+      '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
+      '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
+      # escaping
+      '![[Another page|Page]]' => '[[Another page|Page]]',
+      # project does not exist
+      '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
+      '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
+    }
+
+    @project = Project.find(1)
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  def test_wiki_links_within_local_file_generation_context
+
+    to_test = {
+      # link to a page
+      '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
+      '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
+      '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
+      '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
+      # page that doesn't exist
+      '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
+      '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
+      '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
+      '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
+    }
+
+    @project = Project.find(1)
+
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
+  end
+
+  def test_wiki_links_within_wiki_page_context
+
+    page = WikiPage.find_by_title('Another_page' )
+
+    to_test = {
+      # link to another page
+      '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
+      '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
+      '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
+      '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
+      # link to the current page
+      '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
+      '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
+      '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
+      '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
+      # page that doesn't exist
+      '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">Unknown page</a>',
+      '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">404</a>',
+      '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">Unknown page</a>',
+      '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">404</a>',
+    }
+
+    @project = Project.find(1)
+
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.new( :text => text, :page => page ), :text) }
+  end
+
+  def test_wiki_links_anchor_option_should_prepend_page_title_to_href
+
+    to_test = {
+      # link to a page
+      '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
+      '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
+      '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
+      '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
+      # page that doesn't exist
+      '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
+      '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
+      '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
+      '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
+    }
+
+    @project = Project.find(1)
+
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
+  end
+
+  def test_html_tags
+    to_test = {
+      "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
+      "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
+      "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
+      # do not escape pre/code tags
+      "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
+      "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
+      "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
+      "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
+      "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
+      # remove attributes except class
+      "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
+      '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
+      "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
+      '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
+      "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
+      # xss
+      '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
+      '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
+    }
+    to_test.each { |text, result| assert_equal result, textilizable(text) }
+  end
+
+  def test_allowed_html_tags
+    to_test = {
+      "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
+      "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
+      "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
+    }
+    to_test.each { |text, result| assert_equal result, textilizable(text) }
+  end
+
+  def test_pre_tags
+    raw = <<-RAW
+Before
+
+<pre>
+<prepared-statement-cache-size>32</prepared-statement-cache-size>
+</pre>
+
+After
+RAW
+
+    expected = <<-EXPECTED
+<p>Before</p>
+<pre>
+&lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
+</pre>
+<p>After</p>
+EXPECTED
+
+    assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
+  end
+
+  def test_pre_content_should_not_parse_wiki_and_redmine_links
+    raw = <<-RAW
+[[CookBook documentation]]
+  
+#1
+
+<pre>
+[[CookBook documentation]]
+  
+#1
+</pre>
+RAW
+
+    expected = <<-EXPECTED
+<p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
+<p><a href="/issues/1" class="#{Issue.find(1).css_classes}" title="Can&#x27;t print recipes (New)">#1</a></p>
+<pre>
+[[CookBook documentation]]
+
+#1
+</pre>
+EXPECTED
+
+    @project = Project.find(1)
+    assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
+  end
+
+  def test_non_closing_pre_blocks_should_be_closed
+    raw = <<-RAW
+<pre><code>
+RAW
+
+    expected = <<-EXPECTED
+<pre><code>
+</code></pre>
+EXPECTED
+
+    @project = Project.find(1)
+    assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
+  end
+
+  def test_syntax_highlight
+    raw = <<-RAW
+<pre><code class="ruby">
+# Some ruby code here
+</code></pre>
+RAW
+
+    expected = <<-EXPECTED
+<pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
+</code></pre>
+EXPECTED
+
+    assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
+  end
+
+  def test_to_path_param
+    assert_equal 'test1/test2', to_path_param('test1/test2')
+    assert_equal 'test1/test2', to_path_param('/test1/test2/')
+    assert_equal 'test1/test2', to_path_param('//test1/test2/')
+    assert_equal nil, to_path_param('/')
+  end
+
+  def test_wiki_links_in_tables
+    to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
+                 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
+                 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
+                 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
+    }
+    @project = Project.find(1)
+    to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
+  end
+
+  def test_text_formatting
+    to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
+               '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
+               'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
+               'a H *umane* W *eb* T *ext* G *enerator*' => 'a H <strong>umane</strong> W <strong>eb</strong> T <strong>ext</strong> G <strong>enerator</strong>',
+               'a *H* umane *W* eb *T* ext *G* enerator' => 'a <strong>H</strong> umane <strong>W</strong> eb <strong>T</strong> ext <strong>G</strong> enerator',
+              }
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
+  end
+
+  def test_wiki_horizontal_rule
+    assert_equal '<hr />', textilizable('---')
+    assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
+  end
+
+  def test_footnotes
+    raw = <<-RAW
+This is some text[1].
+
+fn1. This is the foot note
+RAW
+
+    expected = <<-EXPECTED
+<p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
+<p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
+EXPECTED
+
+    assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
+  end
+
+  def test_headings
+    raw = 'h1. Some heading'
+    expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
+
+    assert_equal expected, textilizable(raw)
+  end
+
+  def test_headings_with_special_chars
+    # This test makes sure that the generated anchor names match the expected
+    # ones even if the heading text contains unconventional characters
+    raw = 'h1. Some heading related to version 0.5'
+    anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
+    expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
+
+    assert_equal expected, textilizable(raw)
+  end
+
+  def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
+    page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
+    content = WikiContent.new( :text => 'h1. Some heading', :page => page )
+
+    expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
+
+    assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
+  end
+
+  def test_table_of_content
+    raw = <<-RAW
+{{toc}}
+
+h1. Title
+
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
+
+h2. Subtitle with a [[Wiki]] link
+
+Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
+
+h2. Subtitle with [[Wiki|another Wiki]] link
+
+h2. Subtitle with %{color:red}red text%
+
+<pre>
+some code
+</pre>
+
+h3. Subtitle with *some* _modifiers_
+
+h3. Subtitle with @inline code@
+
+h1. Another title
+
+h3. An "Internet link":http://www.redmine.org/ inside subtitle
+
+h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
+
+RAW
+
+    expected =  '<ul class="toc">' +
+                  '<li><a href="#Title">Title</a>' +
+                    '<ul>' +
+                      '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
+                      '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
+                      '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
+                        '<ul>' +
+                          '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
+                          '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
+                        '</ul>' +
+                      '</li>' +
+                    '</ul>' +
+                  '</li>' +
+                  '<li><a href="#Another-title">Another title</a>' +
+                    '<ul>' +
+                      '<li>' +
+                        '<ul>' +
+                          '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
+                        '</ul>' +
+                      '</li>' +
+                      '<li><a href="#Project-Name">Project Name</a></li>' +
+                    '</ul>' +
+                  '</li>' +
+               '</ul>'
+
+    @project = Project.find(1)
+    assert textilizable(raw).gsub("\n", "").include?(expected)
+  end
+
+  def test_table_of_content_should_generate_unique_anchors
+    raw = <<-RAW
+{{toc}}
+
+h1. Title
+
+h2. Subtitle
+
+h2. Subtitle
+RAW
+
+    expected =  '<ul class="toc">' +
+                  '<li><a href="#Title">Title</a>' +
+                    '<ul>' +
+                      '<li><a href="#Subtitle">Subtitle</a></li>' +
+                      '<li><a href="#Subtitle-2">Subtitle</a></li>'
+                    '</ul>'
+                  '</li>' +
+               '</ul>'
+
+    @project = Project.find(1)
+    result = textilizable(raw).gsub("\n", "")
+    assert_include expected, result
+    assert_include '<a name="Subtitle">', result
+    assert_include '<a name="Subtitle-2">', result
+  end
+
+  def test_table_of_content_should_contain_included_page_headings
+    raw = <<-RAW
+{{toc}}
+
+h1. Included
+
+{{include(Child_1)}}
+RAW
+
+    expected = '<ul class="toc">' +
+               '<li><a href="#Included">Included</a></li>' +
+               '<li><a href="#Child-page-1">Child page 1</a></li>' +
+               '</ul>'
+
+    @project = Project.find(1)
+    assert textilizable(raw).gsub("\n", "").include?(expected)
+  end
+
+  def test_section_edit_links
+    raw = <<-RAW
+h1. Title
+
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
+
+h2. Subtitle with a [[Wiki]] link
+
+h2. Subtitle with *some* _modifiers_
+
+h2. Subtitle with @inline code@
+
+<pre>
+some code
+
+h2. heading inside pre
+
+<h2>html heading inside pre</h2>
+</pre>
+
+h2. Subtitle after pre tag
+RAW
+
+    @project = Project.find(1)
+    set_language_if_valid 'en'
+    result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
+
+    # heading that contains inline code
+    assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
+      '<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
+      '<a name="Subtitle-with-inline-code"></a>' +
+      '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
+      result
+
+    # last heading
+    assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
+      '<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
+      '<a name="Subtitle-after-pre-tag"></a>' +
+      '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
+      result
+  end
+
+  def test_default_formatter
+    with_settings :text_formatting => 'unknown' do
+      text = 'a *link*: http://www.example.net/'
+      assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
+    end
+  end
+
+  def test_due_date_distance_in_words
+    to_test = { Date.today => 'Due in 0 days',
+                Date.today + 1 => 'Due in 1 day',
+                Date.today + 100 => 'Due in about 3 months',
+                Date.today + 20000 => 'Due in over 54 years',
+                Date.today - 1 => '1 day late',
+                Date.today - 100 => 'about 3 months late',
+                Date.today - 20000 => 'over 54 years late',
+               }
+    ::I18n.locale = :en
+    to_test.each do |date, expected|
+      assert_equal expected, due_date_distance_in_words(date)
+    end
+  end
+
+  def test_avatar_enabled
+    with_settings :gravatar_enabled => '1' do
+      assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
+      assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
+      # Default size is 50
+      assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
+      assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
+      # Non-avatar options should be considered html options
+      assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
+      # The default class of the img tag should be gravatar
+      assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
+      assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
+      assert_nil avatar('jsmith')
+      assert_nil avatar(nil)
+    end
+  end
+
+  def test_avatar_disabled
+    with_settings :gravatar_enabled => '0' do
+      assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
+    end
+  end
+
+  def test_link_to_user
+    user = User.find(2)
+    assert_equal '<a href="/users/2" class="user active">John Smith</a>', link_to_user(user)
+  end
+
+  def test_link_to_user_should_not_link_to_locked_user
+    with_current_user nil do
+      user = User.find(5)
+      assert user.locked?
+      assert_equal 'Dave2 Lopper2', link_to_user(user)
+    end
+  end
+
+  def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
+    with_current_user User.find(1) do
+      user = User.find(5)
+      assert user.locked?
+      assert_equal '<a href="/users/5" class="user locked">Dave2 Lopper2</a>', link_to_user(user)
+    end
+  end
+
+  def test_link_to_user_should_not_link_to_anonymous
+    user = User.anonymous
+    assert user.anonymous?
+    t = link_to_user(user)
+    assert_equal ::I18n.t(:label_user_anonymous), t
+  end
+
+  def test_link_to_attachment
+    a = Attachment.find(3)
+    assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
+      link_to_attachment(a)
+    assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
+      link_to_attachment(a, :text => 'Text')
+    assert_equal '<a href="/attachments/3/logo.gif" class="foo">logo.gif</a>',
+      link_to_attachment(a, :class => 'foo')
+    assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
+      link_to_attachment(a, :download => true)
+    assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
+      link_to_attachment(a, :only_path => false)
+  end
+
+  def test_thumbnail_tag
+    a = Attachment.find(3)
+    assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
+      thumbnail_tag(a)
+  end
+
+  def test_link_to_project
+    project = Project.find(1)
+    assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
+                 link_to_project(project)
+    assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
+                 link_to_project(project, :action => 'settings')
+    assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
+                 link_to_project(project, {:only_path => false, :jump => 'blah'})
+    assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
+                 link_to_project(project, {:action => 'settings'}, :class => "project")
+  end
+
+  def test_link_to_project_settings
+    project = Project.find(1)
+    assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
+
+    project.status = Project::STATUS_CLOSED
+    assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
+
+    project.status = Project::STATUS_ARCHIVED
+    assert_equal 'eCookbook', link_to_project_settings(project)
+  end
+
+  def test_link_to_legacy_project_with_numerical_identifier_should_use_id
+    # numeric identifier are no longer allowed
+    Project.update_all "identifier=25", "id=1"
+
+    assert_equal '<a href="/projects/1">eCookbook</a>',
+                 link_to_project(Project.find(1))
+  end
+
+  def test_principals_options_for_select_with_users
+    User.current = nil
+    users = [User.find(2), User.find(4)]
+    assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
+      principals_options_for_select(users)
+  end
+
+  def test_principals_options_for_select_with_selected
+    User.current = nil
+    users = [User.find(2), User.find(4)]
+    assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
+      principals_options_for_select(users, User.find(4))
+  end
+
+  def test_principals_options_for_select_with_users_and_groups
+    User.current = nil
+    users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
+    assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
+      %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
+      principals_options_for_select(users)
+  end
+
+  def test_principals_options_for_select_with_empty_collection
+    assert_equal '', principals_options_for_select([])
+  end
+
+  def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
+    users = [User.find(2), User.find(4)]
+    User.current = User.find(4)
+    assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
+  end
+
+  def test_stylesheet_link_tag_should_pick_the_default_stylesheet
+    assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
+  end
+
+  def test_stylesheet_link_tag_for_plugin_should_pick_the_plugin_stylesheet
+    assert_match 'href="/plugin_assets/foo/stylesheets/styles.css"', stylesheet_link_tag("styles", :plugin => :foo)
+  end
+
+  def test_image_tag_should_pick_the_default_image
+    assert_match 'src="/images/image.png"', image_tag("image.png")
+  end
+
+  def test_image_tag_should_pick_the_theme_image_if_it_exists
+    theme = Redmine::Themes.themes.last
+    theme.images << 'image.png'
+
+    with_settings :ui_theme => theme.id do
+      assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
+      assert_match %|src="/images/other.png"|, image_tag("other.png")
+    end
+  ensure
+    theme.images.delete 'image.png'
+  end
+
+  def test_image_tag_sfor_plugin_should_pick_the_plugin_image
+    assert_match 'src="/plugin_assets/foo/images/image.png"', image_tag("image.png", :plugin => :foo)
+  end
+
+  def test_javascript_include_tag_should_pick_the_default_javascript
+    assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
+  end
+
+  def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
+    assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e0/e08b9f438981155ffc0c3a70e9b878dc891b06d2.svn-base
--- /dev/null
+++ b/.svn/pristine/e0/e08b9f438981155ffc0c3a70e9b878dc891b06d2.svn-base
@@ -0,0 +1,107 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingIssueCategoriesTest < ActionController::IntegrationTest
+  def test_issue_categories_scoped_under_project
+    assert_routing(
+        { :method => 'get', :path => "/projects/foo/issue_categories" },
+        { :controller => 'issue_categories', :action => 'index',
+          :project_id => 'foo' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/foo/issue_categories.xml" },
+        { :controller => 'issue_categories', :action => 'index',
+          :project_id => 'foo', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/foo/issue_categories.json" },
+        { :controller => 'issue_categories', :action => 'index',
+          :project_id => 'foo', :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/foo/issue_categories/new" },
+        { :controller => 'issue_categories', :action => 'new',
+          :project_id => 'foo' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/foo/issue_categories" },
+        { :controller => 'issue_categories', :action => 'create',
+          :project_id => 'foo' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/foo/issue_categories.xml" },
+        { :controller => 'issue_categories', :action => 'create',
+          :project_id => 'foo', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/foo/issue_categories.json" },
+        { :controller => 'issue_categories', :action => 'create',
+          :project_id => 'foo', :format => 'json' }
+      )
+  end
+
+  def test_issue_categories
+    assert_routing(
+        { :method => 'get', :path => "/issue_categories/1" },
+        { :controller => 'issue_categories', :action => 'show', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issue_categories/1.xml" },
+        { :controller => 'issue_categories', :action => 'show', :id => '1',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issue_categories/1.json" },
+        { :controller => 'issue_categories', :action => 'show', :id => '1',
+          :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issue_categories/1/edit" },
+        { :controller => 'issue_categories', :action => 'edit', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/issue_categories/1" },
+        { :controller => 'issue_categories', :action => 'update', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/issue_categories/1.xml" },
+        { :controller => 'issue_categories', :action => 'update', :id => '1',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/issue_categories/1.json" },
+        { :controller => 'issue_categories', :action => 'update', :id => '1',
+          :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/issue_categories/1" },
+        { :controller => 'issue_categories', :action => 'destroy', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/issue_categories/1.xml" },
+        { :controller => 'issue_categories', :action => 'destroy', :id => '1',
+          :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/issue_categories/1.json" },
+        { :controller => 'issue_categories', :action => 'destroy', :id => '1',
+          :format => 'json' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e0/e09af230a1244dd904e00eb402f9ad5ad77a9fd1.svn-base
--- /dev/null
+++ b/.svn/pristine/e0/e09af230a1244dd904e00eb402f9ad5ad77a9fd1.svn-base
@@ -0,0 +1,89 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class HookTest < ActionController::IntegrationTest
+  fixtures :users, :roles, :projects, :members, :member_roles
+
+  # Hooks that are manually registered later
+  class ProjectBasedTemplate < Redmine::Hook::ViewListener
+    def view_layouts_base_html_head(context)
+      # Adds a project stylesheet
+      stylesheet_link_tag(context[:project].identifier) if context[:project]
+    end
+  end
+
+  class SidebarContent < Redmine::Hook::ViewListener
+    def view_layouts_base_sidebar(context)
+      content_tag('p', 'Sidebar hook')
+    end
+  end
+
+  class ContentForInsideHook < Redmine::Hook::ViewListener
+    render_on :view_welcome_index_left, :inline => <<-VIEW
+<% content_for :header_tags do %>
+  <%= javascript_include_tag 'test_plugin.js', :plugin => 'test_plugin' %>
+  <%= stylesheet_link_tag 'test_plugin.css', :plugin => 'test_plugin' %>
+<% end %>
+
+<p>ContentForInsideHook content</p>
+VIEW
+  end
+
+  def setup
+    Redmine::Hook.clear_listeners
+  end
+
+  def teardown
+    Redmine::Hook.clear_listeners
+  end
+
+  def test_html_head_hook_response
+    Redmine::Hook.add_listener(ProjectBasedTemplate)
+
+    get '/projects/ecookbook'
+    assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},
+                               :parent => {:tag => 'head'}
+  end
+
+  def test_empty_sidebar_should_be_hidden
+    get '/'
+    assert_select 'div#main.nosidebar'
+  end
+
+  def test_sidebar_with_hook_content_should_not_be_hidden
+    Redmine::Hook.add_listener(SidebarContent)
+
+    get '/'
+    assert_select 'div#sidebar p', :text => 'Sidebar hook'
+    assert_select 'div#main'
+    assert_select 'div#main.nosidebar', 0
+  end
+
+  def test_hook_with_content_for_should_append_content
+    Redmine::Hook.add_listener(ContentForInsideHook)
+
+    get '/'
+    assert_response :success
+    assert_select 'p', :text => 'ContentForInsideHook content'
+    assert_select 'head' do
+      assert_select 'script[src=/plugin_assets/test_plugin/javascripts/test_plugin.js]'
+      assert_select 'link[href=/plugin_assets/test_plugin/stylesheets/test_plugin.css]'
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e0/e0ded1cb3e9db9162722719b443602d020469fa5.svn-base
--- a/.svn/pristine/e0/e0ded1cb3e9db9162722719b443602d020469fa5.svn-base
+++ /dev/null
@@ -1,59 +0,0 @@
-<h2><%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)) %></h2>
-<p class="subtitle"><%= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %></p>
-
-<div id="activity">
-<% @events_by_day.keys.sort.reverse.each do |day| %>
-<h3><%= format_activity_day(day) %></h3>
-<dl>
-<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
-  <dt class="<%= e.event_type %>  <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
-  <%= avatar(e.event_author, :size => "24") if e.respond_to?(:event_author) %>
-  <span class="time"><%= format_time(e.event_datetime, false) %></span>
-  <%= content_tag('span', h(e.project), :class => 'project') if @project.nil? || @project != e.project %>
-  <%= link_to format_activity_title(e.event_title), e.event_url %></dt>
-  <dd><span class="description"><%= format_activity_description(e.event_description) %></span>
-  <span class="author"><%= link_to_user(e.event_author) if e.respond_to?(:event_author) %></span></dd>
-<% end -%>
-</dl>
-<% end -%>
-</div>
-
-<%= content_tag('p', l(:label_no_data), :class => 'nodata') if @events_by_day.empty? %>
-
-<div style="float:left;">
-<%= link_to_content_update("\xc2\xab " + l(:label_previous),
-                   params.merge(:from => @date_to - @days - 1),
-                   :title => l(:label_date_from_to, :start => format_date(@date_to - 2*@days), :end => format_date(@date_to - @days - 1))) %>
-</div>
-<div style="float:right;">
-<%= link_to_content_update(l(:label_next) + " \xc2\xbb",
-                   params.merge(:from => @date_to + @days - 1),
-                   :title => l(:label_date_from_to, :start => format_date(@date_to), :end => format_date(@date_to + @days - 1))) unless @date_to >= Date.today %>
-</div>
-&nbsp;
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => params.merge(:from => nil, :key => User.current.rss_key) %>
-<% end %>
-
-<% content_for :header_tags do %>
-<%= auto_discovery_link_tag(:atom, params.merge(:format => 'atom', :from => nil, :key => User.current.rss_key)) %>
-<% end %>
-
-<% content_for :sidebar do %>
-<% form_tag({}, :method => :get) do %>
-<h3><%= l(:label_activity) %></h3>
-<p><% @activity.event_types.each do |t| %>
-<%= check_box_tag "show_#{t}", 1, @activity.scope.include?(t) %>
-<label for="show_<%=t%>"><%= link_to(l("label_#{t.singularize}_plural"), {"show_#{t}" => 1, :user_id => params[:user_id]})%></label>
-<br />
-<% end %></p>
-<% if @project && @project.descendants.active.any? %>
-    <%= hidden_field_tag 'with_subprojects', 0 %>
-    <p><label><%= check_box_tag 'with_subprojects', 1, @with_subprojects %> <%=l(:label_subproject_plural)%></label></p>
-<% end %>
-<%= hidden_field_tag('user_id', params[:user_id]) unless params[:user_id].blank? %>
-<p><%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %></p>
-<% end %>
-<% end %>
-
-<% html_title(l(:label_activity), @author) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e107366c1a6751ac8fc0593f4fc17da1868e7064.svn-base
--- a/.svn/pristine/e1/e107366c1a6751ac8fc0593f4fc17da1868e7064.svn-base
+++ /dev/null
@@ -1,510 +0,0 @@
-# -*- coding: utf-8 -*-
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'timelog_controller'
-
-# Re-raise errors caught by the controller.
-class TimelogController; def rescue_action(e) raise e end; end
-
-class TimelogControllerTest < ActionController::TestCase
-  fixtures :projects, :enabled_modules, :roles, :members,
-           :member_roles, :issues, :time_entries, :users,
-           :trackers, :enumerations, :issue_statuses,
-           :custom_fields, :custom_values
-
-  include Redmine::I18n
-
-  def setup
-    @controller = TimelogController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-  end
-
-  def test_get_new
-    @request.session[:user_id] = 3
-    get :new, :project_id => 1
-    assert_response :success
-    assert_template 'edit'
-    # Default activity selected
-    assert_tag :tag => 'option', :attributes => { :selected => 'selected' },
-                                 :content => 'Development'
-  end
-
-  def test_get_new_should_only_show_active_time_entry_activities
-    @request.session[:user_id] = 3
-    get :new, :project_id => 1
-    assert_response :success
-    assert_template 'edit'
-    assert_no_tag :tag => 'option', :content => 'Inactive Activity'
-  end
-
-  def test_get_edit_existing_time
-    @request.session[:user_id] = 2
-    get :edit, :id => 2, :project_id => nil
-    assert_response :success
-    assert_template 'edit'
-    # Default activity selected
-    assert_tag :tag => 'form', :attributes => { :action => '/projects/ecookbook/time_entries/2' }
-  end
-
-  def test_get_edit_with_an_existing_time_entry_with_inactive_activity
-    te = TimeEntry.find(1)
-    te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
-    te.save!
-
-    @request.session[:user_id] = 1
-    get :edit, :project_id => 1, :id => 1
-    assert_response :success
-    assert_template 'edit'
-    # Blank option since nothing is pre-selected
-    assert_tag :tag => 'option', :content => '--- Please select ---'
-  end
-
-  def test_post_create
-    # TODO: should POST to issuesâ€™ time log instead of project. change form
-    # and routing
-    @request.session[:user_id] = 3
-    post :create, :project_id => 1,
-                :time_entry => {:comments => 'Some work on TimelogControllerTest',
-                                # Not the default activity
-                                :activity_id => '11',
-                                :spent_on => '2008-03-14',
-                                :issue_id => '1',
-                                :hours => '7.3'}
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-
-    i = Issue.find(1)
-    t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
-    assert_not_nil t
-    assert_equal 11, t.activity_id
-    assert_equal 7.3, t.hours
-    assert_equal 3, t.user_id
-    assert_equal i, t.issue
-    assert_equal i.project, t.project
-  end
-
-  def test_post_create_with_blank_issue
-    # TODO: should POST to issuesâ€™ time log instead of project. change form
-    # and routing
-    @request.session[:user_id] = 3
-    post :create, :project_id => 1,
-                :time_entry => {:comments => 'Some work on TimelogControllerTest',
-                                # Not the default activity
-                                :activity_id => '11',
-                                :issue_id => '',
-                                :spent_on => '2008-03-14',
-                                :hours => '7.3'}
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-
-    t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
-    assert_not_nil t
-    assert_equal 11, t.activity_id
-    assert_equal 7.3, t.hours
-    assert_equal 3, t.user_id
-  end
-
-  def test_create_without_log_time_permission_should_be_denied
-    @request.session[:user_id] = 2
-    Role.find_by_name('Manager').remove_permission! :log_time
-    post :create, :project_id => 1,
-                :time_entry => {:activity_id => '11',
-                                :issue_id => '',
-                                :spent_on => '2008-03-14',
-                                :hours => '7.3'}
-
-    assert_response 403
-  end
-
-  def test_update
-    entry = TimeEntry.find(1)
-    assert_equal 1, entry.issue_id
-    assert_equal 2, entry.user_id
-
-    @request.session[:user_id] = 1
-    put :update, :id => 1,
-                :time_entry => {:issue_id => '2',
-                                :hours => '8'}
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-    entry.reload
-
-    assert_equal 8, entry.hours
-    assert_equal 2, entry.issue_id
-    assert_equal 2, entry.user_id
-  end
-
-  def test_get_bulk_edit
-    @request.session[:user_id] = 2
-    get :bulk_edit, :ids => [1, 2]
-    assert_response :success
-    assert_template 'bulk_edit'
-
-    # System wide custom field
-    assert_tag :select, :attributes => {:name => 'time_entry[custom_field_values][10]'}
-  end
-
-  def test_get_bulk_edit_on_different_projects
-    @request.session[:user_id] = 2
-    get :bulk_edit, :ids => [1, 2, 6]
-    assert_response :success
-    assert_template 'bulk_edit'
-  end
-
-  def test_bulk_update
-    @request.session[:user_id] = 2
-    # update time entry activity
-    post :bulk_update, :ids => [1, 2], :time_entry => { :activity_id => 9}
-
-    assert_response 302
-    # check that the issues were updated
-    assert_equal [9, 9], TimeEntry.find_all_by_id([1, 2]).collect {|i| i.activity_id}
-  end
-
-  def test_bulk_update_on_different_projects
-    @request.session[:user_id] = 2
-    # makes user a manager on the other project
-    Member.create!(:user_id => 2, :project_id => 3, :role_ids => [1])
-    
-    # update time entry activity
-    post :bulk_update, :ids => [1, 2, 4], :time_entry => { :activity_id => 9 }
-
-    assert_response 302
-    # check that the issues were updated
-    assert_equal [9, 9, 9], TimeEntry.find_all_by_id([1, 2, 4]).collect {|i| i.activity_id}
-  end
-
-  def test_bulk_update_on_different_projects_without_rights
-    @request.session[:user_id] = 3
-    user = User.find(3)
-    action = { :controller => "timelog", :action => "bulk_update" }
-    assert user.allowed_to?(action, TimeEntry.find(1).project)
-    assert ! user.allowed_to?(action, TimeEntry.find(5).project)
-    post :bulk_update, :ids => [1, 5], :time_entry => { :activity_id => 9 }
-    assert_response 403
-  end
-
-  def test_bulk_update_custom_field
-    @request.session[:user_id] = 2
-    post :bulk_update, :ids => [1, 2], :time_entry => { :custom_field_values => {'10' => '0'} }
-
-    assert_response 302
-    assert_equal ["0", "0"], TimeEntry.find_all_by_id([1, 2]).collect {|i| i.custom_value_for(10).value}
-  end
-
-  def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
-    @request.session[:user_id] = 2
-    post :bulk_update, :ids => [1,2], :back_url => '/time_entries'
-
-    assert_response :redirect
-    assert_redirected_to '/time_entries'
-  end
-
-  def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
-    @request.session[:user_id] = 2
-    post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
-
-    assert_response :redirect
-    assert_redirected_to :controller => 'timelog', :action => 'index', :project_id => Project.find(1).identifier
-  end
-
-  def test_post_bulk_update_without_edit_permission_should_be_denied
-    @request.session[:user_id] = 2
-    Role.find_by_name('Manager').remove_permission! :edit_time_entries
-    post :bulk_update, :ids => [1,2]
-
-    assert_response 403
-  end
-
-  def test_destroy
-    @request.session[:user_id] = 2
-    delete :destroy, :id => 1
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-    assert_equal I18n.t(:notice_successful_delete), flash[:notice]
-    assert_nil TimeEntry.find_by_id(1)
-  end
-
-  def test_destroy_should_fail
-    # simulate that this fails (e.g. due to a plugin), see #5700
-    TimeEntry.any_instance.expects(:destroy).returns(false)
-
-    @request.session[:user_id] = 2
-    delete :destroy, :id => 1
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-    assert_equal I18n.t(:notice_unable_delete_time_entry), flash[:error]
-    assert_not_nil TimeEntry.find_by_id(1)
-  end
-
-  def test_index_all_projects
-    get :index
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "162.90", "%.2f" % assigns(:total_hours)
-    assert_tag :form,
-      :attributes => {:action => "/time_entries", :id => 'query_form'}
-  end
-
-  def test_index_at_project_level
-    get :index, :project_id => 'ecookbook'
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:entries)
-    assert_equal 4, assigns(:entries).size
-    # project and subproject
-    assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
-    assert_not_nil assigns(:total_hours)
-    assert_equal "162.90", "%.2f" % assigns(:total_hours)
-    # display all time by default
-    assert_equal '2007-03-12'.to_date, assigns(:from)
-    assert_equal '2007-04-22'.to_date, assigns(:to)
-    assert_tag :form,
-      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
-  end
-
-  def test_index_at_project_level_with_date_range
-    get :index, :project_id => 'ecookbook', :from => '2007-03-20', :to => '2007-04-30'
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:entries)
-    assert_equal 3, assigns(:entries).size
-    assert_not_nil assigns(:total_hours)
-    assert_equal "12.90", "%.2f" % assigns(:total_hours)
-    assert_equal '2007-03-20'.to_date, assigns(:from)
-    assert_equal '2007-04-30'.to_date, assigns(:to)
-    assert_tag :form,
-      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
-  end
-
-  def test_index_at_project_level_with_period
-    get :index, :project_id => 'ecookbook', :period => '7_days'
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:entries)
-    assert_not_nil assigns(:total_hours)
-    assert_equal Date.today - 7, assigns(:from)
-    assert_equal Date.today, assigns(:to)
-    assert_tag :form,
-      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
-  end
-
-  def test_index_one_day
-    get :index, :project_id => 'ecookbook', :from => "2007-03-23", :to => "2007-03-23"
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "4.25", "%.2f" % assigns(:total_hours)
-    assert_tag :form,
-      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
-  end
-
-  def test_index_at_issue_level
-    get :index, :issue_id => 1
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:entries)
-    assert_equal 2, assigns(:entries).size
-    assert_not_nil assigns(:total_hours)
-    assert_equal 154.25, assigns(:total_hours)
-    # display all time based on what's been logged
-    assert_equal '2007-03-12'.to_date, assigns(:from)
-    assert_equal '2007-04-22'.to_date, assigns(:to)
-    # TODO: remove /projects/:project_id/issues/:issue_id/time_entries routes
-    # to use /issues/:issue_id/time_entries
-    assert_tag :form,
-      :attributes => {:action => "/projects/ecookbook/issues/1/time_entries", :id => 'query_form'}
-  end
-
-  def test_index_atom_feed
-    get :index, :project_id => 1, :format => 'atom'
-    assert_response :success
-    assert_equal 'application/atom+xml', @response.content_type
-    assert_not_nil assigns(:items)
-    assert assigns(:items).first.is_a?(TimeEntry)
-  end
-
-  def test_index_all_projects_csv_export
-    Setting.date_format = '%m/%d/%Y'
-    get :index, :format => 'csv'
-    assert_response :success
-    assert_equal 'text/csv', @response.content_type
-    assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment,Overtime\n")
-    assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\",\"\"\n")
-  end
-
-  def test_index_csv_export
-    Setting.date_format = '%m/%d/%Y'
-    get :index, :project_id => 1, :format => 'csv'
-    assert_response :success
-    assert_equal 'text/csv', @response.content_type
-    assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment,Overtime\n")
-    assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\",\"\"\n")
-  end
-
-  def test_csv_big_5
-    user = User.find_by_id(3)
-    user.language = "zh-TW"
-    assert user.save
-    str_utf8  = "\xe4\xb8\x80\xe6\x9c\x88"
-    str_big5  = "\xa4@\xa4\xeb"
-    if str_utf8.respond_to?(:force_encoding)
-      str_utf8.force_encoding('UTF-8')
-      str_big5.force_encoding('Big5')
-    end
-    @request.session[:user_id] = 3
-    post :create, :project_id => 1,
-                :time_entry => {:comments => str_utf8,
-                                # Not the default activity
-                                :activity_id => '11',
-                                :issue_id => '',
-                                :spent_on => '2011-11-10',
-                                :hours => '7.3'}
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-
-    t = TimeEntry.find_by_comments(str_utf8)
-    assert_not_nil t
-    assert_equal 11, t.activity_id
-    assert_equal 7.3, t.hours
-    assert_equal 3, t.user_id
-
-    get :index, :project_id => 1, :format => 'csv',
-        :from => '2011-11-10', :to => '2011-11-10'
-    assert_response :success
-    assert_equal 'text/csv', @response.content_type
-    ar = @response.body.chomp.split("\n")
-    s1 = "\xa4\xe9\xb4\xc1"
-    if str_utf8.respond_to?(:force_encoding)
-      s1.force_encoding('Big5')
-    end
-    assert ar[0].include?(s1)
-    assert ar[1].include?(str_big5)
-  end
-
-  def test_csv_cannot_convert_should_be_replaced_big_5
-    user = User.find_by_id(3)
-    user.language = "zh-TW"
-    assert user.save
-    str_utf8  = "\xe4\xbb\xa5\xe5\x86\x85"
-    if str_utf8.respond_to?(:force_encoding)
-      str_utf8.force_encoding('UTF-8')
-    end
-    @request.session[:user_id] = 3
-    post :create, :project_id => 1,
-                :time_entry => {:comments => str_utf8,
-                                # Not the default activity
-                                :activity_id => '11',
-                                :issue_id => '',
-                                :spent_on => '2011-11-10',
-                                :hours => '7.3'}
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-
-    t = TimeEntry.find_by_comments(str_utf8)
-    assert_not_nil t
-    assert_equal 11, t.activity_id
-    assert_equal 7.3, t.hours
-    assert_equal 3, t.user_id
-
-    get :index, :project_id => 1, :format => 'csv',
-        :from => '2011-11-10', :to => '2011-11-10'
-    assert_response :success
-    assert_equal 'text/csv', @response.content_type
-    ar = @response.body.chomp.split("\n")
-    s1 = "\xa4\xe9\xb4\xc1"
-    if str_utf8.respond_to?(:force_encoding)
-      s1.force_encoding('Big5')
-    end
-    assert ar[0].include?(s1)
-    s2 = ar[1].split(",")[8]
-    if s2.respond_to?(:force_encoding)
-      s3 = "\xa5H?"
-      s3.force_encoding('Big5')
-      assert_equal s3, s2
-    elsif RUBY_PLATFORM == 'java'
-      assert_equal "??", s2
-    else
-      assert_equal "\xa5H???", s2
-    end
-  end
-
-  def test_csv_tw
-    with_settings :default_language => "zh-TW" do
-      str1  = "test_csv_tw"
-      user = User.find_by_id(3)
-      te1 = TimeEntry.create(:spent_on => '2011-11-10',
-                             :hours    => 999.9,
-                             :project  => Project.find(1),
-                             :user     => user,
-                             :activity => TimeEntryActivity.find_by_name('Design'),
-                             :comments => str1)
-      te2 = TimeEntry.find_by_comments(str1)
-      assert_not_nil te2
-      assert_equal 999.9, te2.hours
-      assert_equal 3, te2.user_id
-
-      get :index, :project_id => 1, :format => 'csv',
-          :from => '2011-11-10', :to => '2011-11-10'
-      assert_response :success
-      assert_equal 'text/csv', @response.content_type
-
-      ar = @response.body.chomp.split("\n")
-      s2 = ar[1].split(",")[7]
-      assert_equal '999.9', s2
-
-      str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
-      if str_tw.respond_to?(:force_encoding)
-        str_tw.force_encoding('UTF-8')
-      end
-      assert_equal str_tw, l(:general_lang_name)
-      assert_equal ',', l(:general_csv_separator)
-      assert_equal '.', l(:general_csv_decimal_separator)
-    end
-  end
-
-  def test_csv_fr
-    with_settings :default_language => "fr" do
-      str1  = "test_csv_fr"
-      user = User.find_by_id(3)
-      te1 = TimeEntry.create(:spent_on => '2011-11-10',
-                             :hours    => 999.9,
-                             :project  => Project.find(1),
-                             :user     => user,
-                             :activity => TimeEntryActivity.find_by_name('Design'),
-                             :comments => str1)
-      te2 = TimeEntry.find_by_comments(str1)
-      assert_not_nil te2
-      assert_equal 999.9, te2.hours
-      assert_equal 3, te2.user_id
-
-      get :index, :project_id => 1, :format => 'csv',
-          :from => '2011-11-10', :to => '2011-11-10'
-      assert_response :success
-      assert_equal 'text/csv', @response.content_type
-
-      ar = @response.body.chomp.split("\n")
-      s2 = ar[1].split(";")[7]
-      assert_equal '999,9', s2
-
-      str_fr = "Fran\xc3\xa7ais"
-      if str_fr.respond_to?(:force_encoding)
-        str_fr.force_encoding('UTF-8')
-      end
-      assert_equal str_fr, l(:general_lang_name)
-      assert_equal ';', l(:general_csv_separator)
-      assert_equal ',', l(:general_csv_decimal_separator)
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e13d4eff8ef6e4c2192ff1fb6a6cfbcfa8709f65.svn-base
--- a/.svn/pristine/e1/e13d4eff8ef6e4c2192ff1fb6a6cfbcfa8709f65.svn-base
+++ /dev/null
@@ -1,304 +0,0 @@
-# encoding: utf-8
-require 'test/unit'
-require File.expand_path('../../lib/assert_warning', __FILE__)
-
-$:.unshift File.expand_path('../../../lib', __FILE__)
-require 'coderay'
-
-class BasicTest < Test::Unit::TestCase
-  
-  def test_version
-    assert_nothing_raised do
-      assert_match(/\A\d\.\d\.\d?\z/, CodeRay::VERSION)
-    end
-  end
-  
-  RUBY_TEST_CODE = 'puts "Hello, World!"'
-  
-  RUBY_TEST_TOKENS = [
-    ['puts', :ident],
-    [' ', :space],
-    [:begin_group, :string],
-      ['"', :delimiter],
-      ['Hello, World!', :content],
-      ['"', :delimiter],
-    [:end_group, :string]
-  ].flatten
-  def test_simple_scan
-    assert_nothing_raised do
-      assert_equal RUBY_TEST_TOKENS, CodeRay.scan(RUBY_TEST_CODE, :ruby).tokens
-    end
-  end
-  
-  RUBY_TEST_HTML = 'puts <span class="string"><span class="delimiter">&quot;</span>' + 
-    '<span class="content">Hello, World!</span><span class="delimiter">&quot;</span></span>'
-  def test_simple_highlight
-    assert_nothing_raised do
-      assert_equal RUBY_TEST_HTML, CodeRay.scan(RUBY_TEST_CODE, :ruby).html
-    end
-  end
-  
-  def test_scan_file
-    CodeRay.scan_file __FILE__
-  end
-  
-  def test_encode
-    assert_equal 1, CodeRay.encode('test', :python, :count)
-  end
-  
-  def test_encode_tokens
-    assert_equal 1, CodeRay.encode_tokens(CodeRay::Tokens['test', :string], :count)
-  end
-  
-  def test_encode_file
-    assert_equal File.read(__FILE__), CodeRay.encode_file(__FILE__, :text)
-  end
-  
-  def test_highlight
-    assert_match '<pre>test</pre>', CodeRay.highlight('test', :python)
-  end
-  
-  def test_highlight_file
-    assert_match "require <span class=\"string\"><span class=\"delimiter\">'</span><span class=\"content\">test/unit</span><span class=\"delimiter\">'</span></span>\n", CodeRay.highlight_file(__FILE__)
-  end
-  
-  def test_duo
-    assert_equal(RUBY_TEST_CODE,
-      CodeRay::Duo[:plain, :text].highlight(RUBY_TEST_CODE))
-    assert_equal(RUBY_TEST_CODE,
-      CodeRay::Duo[:plain => :text].highlight(RUBY_TEST_CODE))
-  end
-  
-  def test_duo_stream
-    assert_equal(RUBY_TEST_CODE,
-      CodeRay::Duo[:plain, :text].highlight(RUBY_TEST_CODE, :stream => true))
-  end
-  
-  def test_comment_filter
-    assert_equal <<-EXPECTED, CodeRay.scan(<<-INPUT, :ruby).comment_filter.text
-#!/usr/bin/env ruby
-
-code
-
-more code  
-      EXPECTED
-#!/usr/bin/env ruby
-=begin
-A multi-line comment.
-=end
-code
-# A single-line comment.
-more code  # and another comment, in-line.
-      INPUT
-  end
-  
-  def test_lines_of_code
-    assert_equal 2, CodeRay.scan(<<-INPUT, :ruby).lines_of_code
-#!/usr/bin/env ruby
-=begin
-A multi-line comment.
-=end
-code
-# A single-line comment.
-more code  # and another comment, in-line.
-      INPUT
-    rHTML = <<-RHTML
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
-  <title><%= controller.controller_name.titleize %>: <%= controller.action_name %></title>
-  <%= stylesheet_link_tag 'scaffold' %>
-</head>
-<body>
-
-<p style="color: green"><%= flash[:notice] %></p>
-
-<div id="main">
-  <%= yield %>
-</div>
-
-</body>
-</html>
-      RHTML
-    assert_equal 0, CodeRay.scan(rHTML, :html).lines_of_code
-    assert_equal 0, CodeRay.scan(rHTML, :php).lines_of_code
-    assert_equal 0, CodeRay.scan(rHTML, :yaml).lines_of_code
-    assert_equal 4, CodeRay.scan(rHTML, :erb).lines_of_code
-  end
-  
-  def test_list_of_encoders
-    assert_kind_of(Array, CodeRay::Encoders.list)
-    assert CodeRay::Encoders.list.include?(:count)
-  end
-  
-  def test_list_of_scanners
-    assert_kind_of(Array, CodeRay::Scanners.list)
-    assert CodeRay::Scanners.list.include?(:text)
-  end
-  
-  def test_token_kinds
-    assert_kind_of Hash, CodeRay::TokenKinds
-    for kind, css_class in CodeRay::TokenKinds
-      assert_kind_of Symbol, kind
-      if css_class != false
-        assert_kind_of String, css_class, "TokenKinds[%p] == %p" % [kind, css_class]
-      end
-    end
-    assert_equal 'reserved', CodeRay::TokenKinds[:reserved]
-    assert_warning 'Undefined Token kind: :shibboleet' do
-      assert_equal false, CodeRay::TokenKinds[:shibboleet]
-    end
-  end
-  
-  class Milk < CodeRay::Encoders::Encoder
-    FILE_EXTENSION = 'cocoa'
-  end
-  
-  class HoneyBee < CodeRay::Encoders::Encoder
-  end
-  
-  def test_encoder_file_extension
-    assert_nothing_raised do
-      assert_equal 'html', CodeRay::Encoders::Page::FILE_EXTENSION
-      assert_equal 'cocoa', Milk::FILE_EXTENSION
-      assert_equal 'cocoa', Milk.new.file_extension
-      assert_equal 'honeybee', HoneyBee::FILE_EXTENSION
-      assert_equal 'honeybee', HoneyBee.new.file_extension
-    end
-    assert_raise NameError do
-      HoneyBee::MISSING_CONSTANT
-    end
-  end
-  
-  def test_encoder_tokens
-    encoder = CodeRay::Encoders::Encoder.new
-    encoder.send :setup, {}
-    assert_raise(ArgumentError) { encoder.token :strange, '' }
-    encoder.token 'test', :debug
-  end
-  
-  def test_encoder_deprecated_interface
-    encoder = CodeRay::Encoders::Encoder.new
-    encoder.send :setup, {}
-    assert_warning 'Using old Tokens#<< interface.' do
-      encoder << ['test', :content]
-    end
-    assert_raise ArgumentError do
-      encoder << [:strange, :input]
-    end
-    assert_raise ArgumentError do
-      encoder.encode_tokens [['test', :token]]
-    end
-  end
-  
-  def encoder_token_interface_deprecation_warning_given
-    CodeRay::Encoders::Encoder.send :class_variable_get, :@@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN
-  end
-  
-  def test_scanner_file_extension
-    assert_equal 'rb', CodeRay::Scanners::Ruby.file_extension
-    assert_equal 'rb', CodeRay::Scanners::Ruby.new.file_extension
-    assert_equal 'java', CodeRay::Scanners::Java.file_extension
-    assert_equal 'java', CodeRay::Scanners::Java.new.file_extension
-  end
-  
-  def test_scanner_lang
-    assert_equal :ruby, CodeRay::Scanners::Ruby.lang
-    assert_equal :ruby, CodeRay::Scanners::Ruby.new.lang
-    assert_equal :java, CodeRay::Scanners::Java.lang
-    assert_equal :java, CodeRay::Scanners::Java.new.lang
-  end
-  
-  def test_scanner_tokenize
-    assert_equal ['foo', :plain], CodeRay::Scanners::Plain.new.tokenize('foo')
-    assert_equal [['foo', :plain], ['bar', :plain]], CodeRay::Scanners::Plain.new.tokenize(['foo', 'bar'])
-    CodeRay::Scanners::Plain.new.tokenize 42
-  end
-  
-  def test_scanner_tokens
-    scanner = CodeRay::Scanners::Plain.new
-    scanner.tokenize('foo')
-    assert_equal ['foo', :plain], scanner.tokens
-    scanner.string = ''
-    assert_equal ['', :plain], scanner.tokens
-  end
-  
-  def test_scanner_line_and_column
-    scanner = CodeRay::Scanners::Plain.new "foo\nbÃ¤r+quux"
-    assert_equal 0, scanner.pos
-    assert_equal 1, scanner.line
-    assert_equal 1, scanner.column
-    scanner.scan(/foo/)
-    assert_equal 3, scanner.pos
-    assert_equal 1, scanner.line
-    assert_equal 4, scanner.column
-    scanner.scan(/\n/)
-    assert_equal 4, scanner.pos
-    assert_equal 2, scanner.line
-    assert_equal 1, scanner.column
-    scanner.scan(/b/)
-    assert_equal 5, scanner.pos
-    assert_equal 2, scanner.line
-    assert_equal 2, scanner.column
-    scanner.scan(/a/)
-    assert_equal 5, scanner.pos
-    assert_equal 2, scanner.line
-    assert_equal 2, scanner.column
-    scanner.scan(/Ã¤/)
-    assert_equal 7, scanner.pos
-    assert_equal 2, scanner.line
-    assert_equal 4, scanner.column
-    scanner.scan(/r/)
-    assert_equal 8, scanner.pos
-    assert_equal 2, scanner.line
-    assert_equal 5, scanner.column
-  end
-  
-  def test_scanner_use_subclasses
-    assert_raise NotImplementedError do
-      CodeRay::Scanners::Scanner.new
-    end
-  end
-  
-  class InvalidScanner < CodeRay::Scanners::Scanner
-  end
-  
-  def test_scanner_scan_tokens
-    assert_raise NotImplementedError do
-      InvalidScanner.new.tokenize ''
-    end
-  end
-  
-  class RaisingScanner < CodeRay::Scanners::Scanner
-    def scan_tokens encoder, options
-      raise_inspect 'message', [], :initial
-    end
-  end
-  
-  def test_scanner_raise_inspect
-    assert_raise CodeRay::Scanners::Scanner::ScanError do
-      RaisingScanner.new.tokenize ''
-    end
-  end
-  
-  def test_scan_a_frozen_string
-    assert_nothing_raised do
-      CodeRay.scan RUBY_VERSION, :ruby
-      CodeRay.scan RUBY_VERSION, :plain
-    end
-  end
-  
-  def test_scan_a_non_string
-    assert_nothing_raised do
-      CodeRay.scan 42, :ruby
-      CodeRay.scan nil, :ruby
-      CodeRay.scan self, :ruby
-      CodeRay.encode ENV.to_hash, :ruby, :page
-      CodeRay.highlight CodeRay, :plain
-    end
-  end
-  
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e140ffeb12ccebdeac6bae46d7abe6d081f9bac4.svn-base
--- a/.svn/pristine/e1/e140ffeb12ccebdeac6bae46d7abe6d081f9bac4.svn-base
+++ /dev/null
@@ -1,64 +0,0 @@
-<%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %>
-
-<div class="contextual">
-  <%= render :partial => 'navigation' %>
-</div>
-
-<h2><%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => 'dir', :revision => @rev } %></h2>
-
-<% if !@entries.nil? && authorize_for('repositories', 'browse') %>
-<%= render :partial => 'dir_list' %>
-<% end %>
-
-<%= render_properties(@properties) %>
-
-<% if authorize_for('repositories', 'revisions') %>
-<%   if @changesets && !@changesets.empty? %>
-<h3><%= l(:label_latest_revision_plural) %></h3>
-<%=    render :partial => 'revisions',
-              :locals => {:project => @project, :path => @path,
-                          :revisions => @changesets, :entry => nil }%>
-<%   end %>
-<p>
-<%
-     has_branches = (!@repository.branches.nil? && @repository.branches.length > 0)
-     sep = ''
- %>
-<%   if @repository.supports_all_revisions? && @path.blank? %>
-<%= link_to l(:label_view_all_revisions), :action => 'revisions', :id => @project %>
-<%   sep = '|' %>
-<%   end %>
-<%
-     if @repository.supports_directory_revisions? &&
-         ( has_branches || !@path.blank? || !@rev.blank? )
- %>
-<%= sep %>
-<%=
-    link_to l(:label_view_revisions),
-                   :action => 'changes',
-                   :path   => to_path_param(@path),
-                   :id     => @project,
-                   :rev    => @rev
-                   %>
-<%   end %>
-</p>
-
-<%   if true # @path.blank? %>
-<%     content_for :header_tags do %>
-  <%= auto_discovery_link_tag(
-                   :atom, params.merge(
-                      {:format => 'atom', :action => 'revisions',
-                       :id => @project, :page => nil, :key => User.current.rss_key})) %>
-<%     end %>
-
-<%     other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:action => 'revisions', :id => @project, :key => User.current.rss_key} %>
-<%     end %>
-<%   end %>
-<% end %>
-
-<% content_for :header_tags do %>
-<%= stylesheet_link_tag "scm" %>
-<% end %>
-
-<% html_title(l(:label_repository)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e14ce008ab63fe1ed2c0583cdc8dd554192dcfe1.svn-base
--- /dev/null
+++ b/.svn/pristine/e1/e14ce008ab63fe1ed2c0583cdc8dd554192dcfe1.svn-base
@@ -0,0 +1,154 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class AttachmentsController < ApplicationController
+  before_filter :find_project, :except => :upload
+  before_filter :file_readable, :read_authorize, :only => [:show, :download, :thumbnail]
+  before_filter :delete_authorize, :only => :destroy
+  before_filter :authorize_global, :only => :upload
+
+  accept_api_auth :show, :download, :upload
+
+  def show
+    respond_to do |format|
+      format.html {
+        if @attachment.is_diff?
+          @diff = File.new(@attachment.diskfile, "rb").read
+          @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
+          @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
+          # Save diff type as user preference
+          if User.current.logged? && @diff_type != User.current.pref[:diff_type]
+            User.current.pref[:diff_type] = @diff_type
+            User.current.preference.save
+          end
+          render :action => 'diff'
+        elsif @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte
+          @content = File.new(@attachment.diskfile, "rb").read
+          render :action => 'file'
+        else
+          download
+        end
+      }
+      format.api
+    end
+  end
+
+  def download
+    if @attachment.container.is_a?(Version) || @attachment.container.is_a?(Project)
+      @attachment.increment_download
+    end
+
+    if stale?(:etag => @attachment.digest)
+      # images are sent inline
+      send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
+                                      :type => detect_content_type(@attachment),
+                                      :disposition => (@attachment.image? ? 'inline' : 'attachment')
+    end
+  end
+
+  def thumbnail
+    if @attachment.thumbnailable? && thumbnail = @attachment.thumbnail(:size => params[:size])
+      if stale?(:etag => thumbnail)
+        send_file thumbnail,
+          :filename => filename_for_content_disposition(@attachment.filename),
+          :type => detect_content_type(@attachment),
+          :disposition => 'inline'
+      end
+    else
+      # No thumbnail for the attachment or thumbnail could not be created
+      render :nothing => true, :status => 404
+    end
+  end
+
+  def upload
+    # Make sure that API users get used to set this content type
+    # as it won't trigger Rails' automatic parsing of the request body for parameters
+    unless request.content_type == 'application/octet-stream'
+      render :nothing => true, :status => 406
+      return
+    end
+
+    @attachment = Attachment.new(:file => request.raw_post)
+    @attachment.author = User.current
+    @attachment.filename = params[:filename].presence || Redmine::Utils.random_hex(16)
+    saved = @attachment.save
+
+    respond_to do |format|
+      format.js
+      format.api {
+        if saved
+          render :action => 'upload', :status => :created
+        else
+          render_validation_errors(@attachment)
+        end
+      }
+    end
+  end
+
+  def destroy
+    if @attachment.container.respond_to?(:init_journal)
+      @attachment.container.init_journal(User.current)
+    end
+    if @attachment.container
+      # Make sure association callbacks are called
+      @attachment.container.attachments.delete(@attachment)
+    else
+      @attachment.destroy
+    end
+
+    respond_to do |format|
+      format.html { redirect_to_referer_or project_path(@project) }
+      format.js
+    end
+  end
+
+private
+  def find_project
+    @attachment = Attachment.find(params[:id])
+    # Show 404 if the filename in the url is wrong
+    raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename
+    @project = @attachment.project
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  # Checks that the file exists and is readable
+  def file_readable
+    if @attachment.readable?
+      true
+    else
+      logger.error "Cannot send attachment, #{@attachment.diskfile} does not exist or is unreadable."
+      render_404
+    end
+  end
+
+  def read_authorize
+    @attachment.visible? ? true : deny_access
+  end
+
+  def delete_authorize
+    @attachment.deletable? ? true : deny_access
+  end
+
+  def detect_content_type(attachment)
+    content_type = attachment.content_type
+    if content_type.blank?
+      content_type = Redmine::MimeType.of(attachment.filename)
+    end
+    content_type.to_s
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e170cc478b88d5ba7f1f49c3d7b9996c36309faf.svn-base
--- /dev/null
+++ b/.svn/pristine/e1/e170cc478b88d5ba7f1f49c3d7b9996c36309faf.svn-base
@@ -0,0 +1,69 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingAttachmentsTest < ActionController::IntegrationTest
+  def test_attachments
+    assert_routing(
+           { :method => 'get', :path => "/attachments/1" },
+           { :controller => 'attachments', :action => 'show', :id => '1' }
+         )
+    assert_routing(
+           { :method => 'get', :path => "/attachments/1.xml" },
+           { :controller => 'attachments', :action => 'show', :id => '1', :format => 'xml' }
+         )
+    assert_routing(
+           { :method => 'get', :path => "/attachments/1.json" },
+           { :controller => 'attachments', :action => 'show', :id => '1', :format => 'json' }
+         )
+    assert_routing(
+           { :method => 'get', :path => "/attachments/1/filename.ext" },
+           { :controller => 'attachments', :action => 'show', :id => '1',
+             :filename => 'filename.ext' }
+         )
+    assert_routing(
+           { :method => 'get', :path => "/attachments/download/1" },
+           { :controller => 'attachments', :action => 'download', :id => '1' }
+         )
+    assert_routing(
+           { :method => 'get', :path => "/attachments/download/1/filename.ext" },
+           { :controller => 'attachments', :action => 'download', :id => '1',
+             :filename => 'filename.ext' }
+         )
+    assert_routing(
+           { :method => 'get', :path => "/attachments/thumbnail/1" },
+           { :controller => 'attachments', :action => 'thumbnail', :id => '1' }
+         )
+    assert_routing(
+           { :method => 'get', :path => "/attachments/thumbnail/1/200" },
+           { :controller => 'attachments', :action => 'thumbnail', :id => '1', :size => '200' }
+         )
+    assert_routing(
+           { :method => 'delete', :path => "/attachments/1" },
+           { :controller => 'attachments', :action => 'destroy', :id => '1' }
+         )
+    assert_routing(
+           { :method => 'post', :path => '/uploads.xml' },
+           { :controller => 'attachments', :action => 'upload', :format => 'xml' }
+    )
+    assert_routing(
+           { :method => 'post', :path => '/uploads.json' },
+           { :controller => 'attachments', :action => 'upload', :format => 'json' }
+    )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e19cb23ac2d90f9735c47ccc904dcda6e52b2377.svn-base
--- /dev/null
+++ b/.svn/pristine/e1/e19cb23ac2d90f9735c47ccc904dcda6e52b2377.svn-base
@@ -0,0 +1,283 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AttachmentTest < ActiveSupport::TestCase
+  fixtures :users, :projects, :roles, :members, :member_roles,
+           :enabled_modules, :issues, :trackers, :attachments
+  
+  class MockFile
+    attr_reader :original_filename, :content_type, :content, :size
+    
+    def initialize(attributes)
+      @original_filename = attributes[:original_filename]
+      @content_type = attributes[:content_type]
+      @content = attributes[:content] || "Content"
+      @size = content.size
+    end
+  end
+
+  def setup
+    set_tmp_attachments_directory
+  end
+
+  def test_container_for_new_attachment_should_be_nil
+    assert_nil Attachment.new.container
+  end
+
+  def test_create
+    a = Attachment.new(:container => Issue.find(1),
+                       :file => uploaded_test_file("testfile.txt", "text/plain"),
+                       :author => User.find(1))
+    assert a.save
+    assert_equal 'testfile.txt', a.filename
+    assert_equal 59, a.filesize
+    assert_equal 'text/plain', a.content_type
+    assert_equal 0, a.downloads
+    assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
+
+    assert a.disk_directory
+    assert_match %r{\A\d{4}/\d{2}\z}, a.disk_directory
+
+    assert File.exist?(a.diskfile)
+    assert_equal 59, File.size(a.diskfile)
+  end
+
+  def test_copy_should_preserve_attributes
+    a = Attachment.find(1)
+    copy = a.copy
+
+    assert_save copy
+    copy = Attachment.order('id DESC').first
+    %w(filename filesize content_type author_id created_on description digest disk_filename disk_directory diskfile).each do |attribute|
+      assert_equal a.send(attribute), copy.send(attribute), "#{attribute} was different"
+    end
+  end
+
+  def test_size_should_be_validated_for_new_file
+    with_settings :attachment_max_size => 0 do
+      a = Attachment.new(:container => Issue.find(1),
+                         :file => uploaded_test_file("testfile.txt", "text/plain"),
+                         :author => User.find(1))
+      assert !a.save
+    end
+  end
+
+  def test_size_should_not_be_validated_when_copying
+    a = Attachment.create!(:container => Issue.find(1),
+                           :file => uploaded_test_file("testfile.txt", "text/plain"),
+                           :author => User.find(1))
+    with_settings :attachment_max_size => 0 do
+      copy = a.copy
+      assert copy.save
+    end
+  end
+
+  def test_description_length_should_be_validated
+    a = Attachment.new(:description => 'a' * 300)
+    assert !a.save
+    assert_not_nil a.errors[:description]
+  end
+
+  def test_destroy
+    a = Attachment.new(:container => Issue.find(1),
+                       :file => uploaded_test_file("testfile.txt", "text/plain"),
+                       :author => User.find(1))
+    assert a.save
+    assert_equal 'testfile.txt', a.filename
+    assert_equal 59, a.filesize
+    assert_equal 'text/plain', a.content_type
+    assert_equal 0, a.downloads
+    assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
+    diskfile = a.diskfile
+    assert File.exist?(diskfile)
+    assert_equal 59, File.size(a.diskfile)
+    assert a.destroy
+    assert !File.exist?(diskfile)
+  end
+
+  def test_destroy_should_not_delete_file_referenced_by_other_attachment
+    a = Attachment.create!(:container => Issue.find(1),
+                           :file => uploaded_test_file("testfile.txt", "text/plain"),
+                           :author => User.find(1))
+    diskfile = a.diskfile
+
+    copy = a.copy
+    copy.save!
+
+    assert File.exists?(diskfile)
+    a.destroy
+    assert File.exists?(diskfile)
+    copy.destroy
+    assert !File.exists?(diskfile)
+  end
+
+  def test_create_should_auto_assign_content_type
+    a = Attachment.new(:container => Issue.find(1),
+                       :file => uploaded_test_file("testfile.txt", ""),
+                       :author => User.find(1))
+    assert a.save
+    assert_equal 'text/plain', a.content_type
+  end
+
+  def test_identical_attachments_at_the_same_time_should_not_overwrite
+    a1 = Attachment.create!(:container => Issue.find(1),
+                            :file => uploaded_test_file("testfile.txt", ""),
+                            :author => User.find(1))
+    a2 = Attachment.create!(:container => Issue.find(1),
+                            :file => uploaded_test_file("testfile.txt", ""),
+                            :author => User.find(1))
+    assert a1.disk_filename != a2.disk_filename
+  end
+  
+  def test_filename_should_be_basenamed
+    a = Attachment.new(:file => MockFile.new(:original_filename => "path/to/the/file"))
+    assert_equal 'file', a.filename
+  end
+  
+  def test_filename_should_be_sanitized
+    a = Attachment.new(:file => MockFile.new(:original_filename => "valid:[] invalid:?%*|\"'<>chars"))
+    assert_equal 'valid_[] invalid_chars', a.filename
+  end
+
+  def test_diskfilename
+    assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
+    assert_equal 'test_file.txt', Attachment.disk_filename("test_file.txt")[13..-1]
+    assert_equal '770c509475505f37c2b8fb6030434d6b.txt', Attachment.disk_filename("test_accentuÃ©.txt")[13..-1]
+    assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentuÃ©")[13..-1]
+    assert_equal 'cbb5b0f30978ba03731d61f9f6d10011', Attachment.disk_filename("test_accentuÃ©.Ã§a")[13..-1]
+  end
+
+  def test_title
+    a = Attachment.new(:filename => "test.png")
+    assert_equal "test.png", a.title
+
+    a = Attachment.new(:filename => "test.png", :description => "Cool image")
+    assert_equal "test.png (Cool image)", a.title
+  end
+
+  def test_prune_should_destroy_old_unattached_attachments
+    Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1, :created_on => 2.days.ago)
+    Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1, :created_on => 2.days.ago)
+    Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1)
+
+    assert_difference 'Attachment.count', -2 do
+      Attachment.prune
+    end
+  end
+
+  def test_move_from_root_to_target_directory_should_move_root_files
+    a = Attachment.find(20)
+    assert a.disk_directory.blank?
+    # Create a real file for this fixture
+    File.open(a.diskfile, "w") do |f|
+      f.write "test file at the root of files directory"
+    end
+    assert a.readable?
+    Attachment.move_from_root_to_target_directory
+
+    a.reload
+    assert_equal '2012/05', a.disk_directory
+    assert a.readable?
+  end
+
+  test "Attachmnet.attach_files should attach the file" do
+    issue = Issue.first
+    assert_difference 'Attachment.count' do
+      Attachment.attach_files(issue,
+        '1' => {
+          'file' => uploaded_test_file('testfile.txt', 'text/plain'),
+          'description' => 'test'
+        })
+    end
+
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal issue, attachment.container
+    assert_equal 'testfile.txt', attachment.filename
+    assert_equal 59, attachment.filesize
+    assert_equal 'test', attachment.description
+    assert_equal 'text/plain', attachment.content_type
+    assert File.exists?(attachment.diskfile)
+    assert_equal 59, File.size(attachment.diskfile)
+  end
+
+  test "Attachmnet.attach_files should add unsaved files to the object as unsaved attachments" do
+    # Max size of 0 to force Attachment creation failures
+    with_settings(:attachment_max_size => 0) do
+      @project = Project.find(1)
+      response = Attachment.attach_files(@project, {
+                                           '1' => {'file' => mock_file, 'description' => 'test'},
+                                           '2' => {'file' => mock_file, 'description' => 'test'}
+                                         })
+
+      assert response[:unsaved].present?
+      assert_equal 2, response[:unsaved].length
+      assert response[:unsaved].first.new_record?
+      assert response[:unsaved].second.new_record?
+      assert_equal response[:unsaved], @project.unsaved_attachments
+    end
+  end
+
+  def test_latest_attach
+    set_fixtures_attachments_directory
+    a1 = Attachment.find(16)
+    assert_equal "testfile.png", a1.filename
+    assert a1.readable?
+    assert (! a1.visible?(User.anonymous))
+    assert a1.visible?(User.find(2))
+    a2 = Attachment.find(17)
+    assert_equal "testfile.PNG", a2.filename
+    assert a2.readable?
+    assert (! a2.visible?(User.anonymous))
+    assert a2.visible?(User.find(2))
+    assert a1.created_on < a2.created_on
+
+    la1 = Attachment.latest_attach([a1, a2], "testfile.png")
+    assert_equal 17, la1.id
+    la2 = Attachment.latest_attach([a1, a2], "Testfile.PNG")
+    assert_equal 17, la2.id
+
+    set_tmp_attachments_directory
+  end
+
+  def test_thumbnailable_should_be_true_for_images
+    assert_equal true, Attachment.new(:filename => 'test.jpg').thumbnailable?
+  end
+
+  def test_thumbnailable_should_be_true_for_non_images
+    assert_equal false, Attachment.new(:filename => 'test.txt').thumbnailable?
+  end
+
+  if convert_installed?
+    def test_thumbnail_should_generate_the_thumbnail
+      set_fixtures_attachments_directory
+      attachment = Attachment.find(16)
+      Attachment.clear_thumbnails
+
+      assert_difference "Dir.glob(File.join(Attachment.thumbnails_storage_path, '*.thumb')).size" do
+        thumbnail = attachment.thumbnail
+        assert_equal "16_8e0294de2441577c529f170b6fb8f638_100.thumb", File.basename(thumbnail)
+        assert File.exists?(thumbnail)
+      end
+    end
+  else
+    puts '(ImageMagick convert not available)'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e1ad05eb66ac646a39350ef0e74e3c3caf45be4b.svn-base
--- a/.svn/pristine/e1/e1ad05eb66ac646a39350ef0e74e3c3caf45be4b.svn-base
+++ /dev/null
@@ -1,158 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/mercurial_adapter'
-
-class Repository::Mercurial < Repository
-  # sort changesets by revision number
-  has_many :changesets,
-           :order       => "#{Changeset.table_name}.id DESC",
-           :foreign_key => 'repository_id'
-
-  attr_protected        :root_url
-  validates_presence_of :url
-
-  # number of changesets to fetch at once
-  FETCH_AT_ONCE = 100
-
-  def self.human_attribute_name(attribute_key_name)
-    attr_name = attribute_key_name
-    if attr_name == "url"
-      attr_name = "path_to_repository"
-    end
-    super(attr_name)
-  end
-
-  def self.scm_adapter_class
-    Redmine::Scm::Adapters::MercurialAdapter
-  end
-
-  def self.scm_name
-    'Mercurial'
-  end
-
-  def supports_directory_revisions?
-    true
-  end
-
-  def supports_revision_graph?
-    true
-  end
-
-  def repo_log_encoding
-    'UTF-8'
-  end
-
-  # Returns the readable identifier for the given mercurial changeset
-  def self.format_changeset_identifier(changeset)
-    "#{changeset.revision}:#{changeset.scmid}"
-  end
-
-  # Returns the identifier for the given Mercurial changeset
-  def self.changeset_identifier(changeset)
-    changeset.scmid
-  end
-
-  def diff_format_revisions(cs, cs_to, sep=':')
-    super(cs, cs_to, ' ')
-  end
-
-  # Finds and returns a revision with a number or the beginning of a hash
-  def find_changeset_by_name(name)
-    return nil if name.nil? || name.empty?
-    if /[^\d]/ =~ name or name.to_s.size > 8
-      e = changesets.find(:first, :conditions => ['scmid = ?', name.to_s])
-    else
-      e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
-    end
-    return e if e
-    changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])  # last ditch
-  end
-
-  # Returns the latest changesets for +path+; sorted by revision number
-  #
-  # Because :order => 'id DESC' is defined at 'has_many',
-  # there is no need to set 'order'.
-  # But, MySQL test fails.
-  # Sqlite3 and PostgreSQL pass.
-  # Is this MySQL bug?
-  def latest_changesets(path, rev, limit=10)
-    changesets.find(:all,
-                    :include    => :user,
-                    :conditions => latest_changesets_cond(path, rev, limit),
-                    :limit      => limit,
-                    :order      => "#{Changeset.table_name}.id DESC")
-  end
-
-  def latest_changesets_cond(path, rev, limit)
-    cond, args = [], []
-    if scm.branchmap.member? rev
-      # Mercurial named branch is *stable* in each revision.
-      # So, named branch can be stored in database.
-      # Mercurial provides *bookmark* which is equivalent with git branch.
-      # But, bookmark is not implemented.
-      cond << "#{Changeset.table_name}.scmid IN (?)"
-      # Revisions in root directory and sub directory are not equal.
-      # So, in order to get correct limit, we need to get all revisions.
-      # But, it is very heavy.
-      # Mercurial does not treat direcotry.
-      # So, "hg log DIR" is very heavy.
-      branch_limit = path.blank? ? limit : ( limit * 5 )
-      args << scm.nodes_in_branch(rev, :limit => branch_limit)
-    elsif last = rev ? find_changeset_by_name(scm.tagmap[rev] || rev) : nil
-      cond << "#{Changeset.table_name}.id <= ?"
-      args << last.id
-    end
-    unless path.blank?
-      cond << "EXISTS (SELECT * FROM #{Change.table_name}
-                 WHERE #{Change.table_name}.changeset_id = #{Changeset.table_name}.id
-                 AND (#{Change.table_name}.path = ?
-                       OR #{Change.table_name}.path LIKE ? ESCAPE ?))"
-      args << path.with_leading_slash
-      args << "#{path.with_leading_slash.gsub(%r{[%_\\]}) { |s| "\\#{s}" }}/%" << '\\'
-    end
-    [cond.join(' AND '), *args] unless cond.empty?
-  end
-  private :latest_changesets_cond
-
-  def fetch_changesets
-    return if scm.info.nil?
-    scm_rev = scm.info.lastrev.revision.to_i
-    db_rev  = latest_changeset ? latest_changeset.revision.to_i : -1
-    return unless db_rev < scm_rev  # already up-to-date
-
-    logger.debug "Fetching changesets for repository #{url}" if logger
-    (db_rev + 1).step(scm_rev, FETCH_AT_ONCE) do |i|
-      transaction do
-        scm.each_revision('', i, [i + FETCH_AT_ONCE - 1, scm_rev].min) do |re|
-          cs = Changeset.create(:repository   => self,
-                                :revision     => re.revision,
-                                :scmid        => re.scmid,
-                                :committer    => re.author,
-                                :committed_on => re.time,
-                                :comments     => re.message)
-          re.paths.each { |e| cs.create_change(e) }
-          parents = {}
-          parents[cs] = re.parents unless re.parents.nil?
-          parents.each do |ch, chparents|
-            ch.parents = chparents.collect{|rp| find_changeset_by_name(rp)}.compact
-          end
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e1ade5140c036735af4b0ad735c4d03a68cc6596.svn-base
--- a/.svn/pristine/e1/e1ade5140c036735af4b0ad735c4d03a68cc6596.svn-base
+++ /dev/null
@@ -1,175 +0,0 @@
-# encoding: utf-8
-module CodeRay
-module Scanners
-
-  module Ruby::Patterns  # :nodoc: all
-
-    KEYWORDS = %w[
-      and def end in or unless begin
-      defined? ensure module redo super until
-      BEGIN break do next rescue then
-      when END case else for retry
-      while alias class elsif if not return
-      undef yield
-    ]
-
-    # See http://murfy.de/ruby-constants.
-    PREDEFINED_CONSTANTS = %w[
-      nil true false self
-      DATA ARGV ARGF ENV
-      FALSE TRUE NIL
-      STDERR STDIN STDOUT
-      TOPLEVEL_BINDING
-      RUBY_COPYRIGHT RUBY_DESCRIPTION RUBY_ENGINE RUBY_PATCHLEVEL
-      RUBY_PLATFORM RUBY_RELEASE_DATE RUBY_REVISION RUBY_VERSION
-      __FILE__ __LINE__ __ENCODING__
-    ]
-
-    IDENT_KIND = WordList.new(:ident).
-      add(KEYWORDS, :keyword).
-      add(PREDEFINED_CONSTANTS, :predefined_constant)
-
-    KEYWORD_NEW_STATE = WordList.new(:initial).
-      add(%w[ def ], :def_expected).
-      add(%w[ undef ], :undef_expected).
-      add(%w[ alias ], :alias_expected).
-      add(%w[ class module ], :module_expected)
-
-    IDENT = 'Ã¤'[/[[:alpha:]]/] == 'Ã¤' ? /[[:alpha:]_][[:alnum:]_]*/ : /[^\W\d]\w*/
-
-    METHOD_NAME = / #{IDENT} [?!]? /ox
-    METHOD_NAME_OPERATOR = /
-      \*\*?           # multiplication and power
-      | [-+~]@?       # plus, minus, tilde with and without at sign
-      | [\/%&|^`]     # division, modulo or format strings, and, or, xor, system
-      | \[\]=?        # array getter and setter
-      | << | >>       # append or shift left, shift right
-      | <=?>? | >=?   # comparison, rocket operator
-      | ===? | =~     # simple equality, case equality, match
-      | ![~=@]?       # negation with and without at sign, not-equal and not-match
-    /ox
-    METHOD_SUFFIX = / (?: [?!] | = (?![~>]|=(?!>)) ) /x
-    METHOD_NAME_EX = / #{IDENT} #{METHOD_SUFFIX}? | #{METHOD_NAME_OPERATOR} /ox
-    METHOD_AFTER_DOT = / #{IDENT} [?!]? | #{METHOD_NAME_OPERATOR} /ox
-    INSTANCE_VARIABLE = / @ #{IDENT} /ox
-    CLASS_VARIABLE = / @@ #{IDENT} /ox
-    OBJECT_VARIABLE = / @@? #{IDENT} /ox
-    GLOBAL_VARIABLE = / \$ (?: #{IDENT} | [1-9]\d* | 0\w* | [~&+`'=\/,;_.<>!@$?*":\\] | -[a-zA-Z_0-9] ) /ox
-    PREFIX_VARIABLE = / #{GLOBAL_VARIABLE} | #{OBJECT_VARIABLE} /ox
-    VARIABLE = / @?@? #{IDENT} | #{GLOBAL_VARIABLE} /ox
-
-    QUOTE_TO_TYPE = {
-      '`' => :shell,
-      '/'=> :regexp,
-    }
-    QUOTE_TO_TYPE.default = :string
-
-    REGEXP_MODIFIERS = /[mousenix]*/
-
-    DECIMAL = /\d+(?:_\d+)*/
-    OCTAL = /0_?[0-7]+(?:_[0-7]+)*/
-    HEXADECIMAL = /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/
-    BINARY = /0b[01]+(?:_[01]+)*/
-
-    EXPONENT = / [eE] [+-]? #{DECIMAL} /ox
-    FLOAT_SUFFIX = / #{EXPONENT} | \. #{DECIMAL} #{EXPONENT}? /ox
-    FLOAT_OR_INT = / #{DECIMAL} (?: #{FLOAT_SUFFIX} () )? /ox
-    NUMERIC = / (?: (?=0) (?: #{OCTAL} | #{HEXADECIMAL} | #{BINARY} ) | #{FLOAT_OR_INT} ) /ox
-
-    SYMBOL = /
-      :
-      (?:
-        #{METHOD_NAME_EX}
-      | #{PREFIX_VARIABLE}
-      | ['"]
-      )
-    /ox
-    METHOD_NAME_OR_SYMBOL = / #{METHOD_NAME_EX} | #{SYMBOL} /ox
-
-    SIMPLE_ESCAPE = /
-        [abefnrstv]
-      |  [0-7]{1,3}
-      | x[0-9A-Fa-f]{1,2}
-      | .
-    /mx
-    
-    CONTROL_META_ESCAPE = /
-      (?: M-|C-|c )
-      (?: \\ (?: M-|C-|c ) )*
-      (?: [^\\] | \\ #{SIMPLE_ESCAPE} )?
-    /mox
-    
-    ESCAPE = /
-      #{CONTROL_META_ESCAPE} | #{SIMPLE_ESCAPE}
-    /mox
-    
-    CHARACTER = /
-      \?
-      (?:
-        [^\s\\]
-      | \\ #{ESCAPE}
-      )
-    /mox
-
-    # NOTE: This is not completely correct, but
-    # nobody needs heredoc delimiters ending with \n.
-    HEREDOC_OPEN = /
-      << (-)?              # $1 = float
-      (?:
-        ( [A-Za-z_0-9]+ )  # $2 = delim
-      |
-        ( ["'`\/] )        # $3 = quote, type
-        ( [^\n]*? ) \3     # $4 = delim
-      )
-    /mx
-
-    RUBYDOC = /
-      =begin (?!\S)
-      .*?
-      (?: \Z | ^=end (?!\S) [^\n]* )
-    /mx
-
-    DATA = /
-      __END__$
-      .*?
-      (?: \Z | (?=^\#CODE) )
-    /mx
-    
-    RUBYDOC_OR_DATA = / #{RUBYDOC} | #{DATA} /xo
-
-    # Checks for a valid value to follow. This enables
-    # value_expected in method calls without parentheses.
-    VALUE_FOLLOWS = /
-      (?>[ \t\f\v]+)
-      (?:
-        [%\/][^\s=]
-      | <<-?\S
-      | [-+] \d
-      | #{CHARACTER}
-      )
-    /ox
-    KEYWORDS_EXPECTING_VALUE = WordList.new.add(%w[
-      and end in or unless begin
-      defined? ensure redo super until
-      break do next rescue then
-      when case else for retry
-      while elsif if not return
-      yield
-    ])
-    
-    FANCY_STRING_START = / % ( [QqrsWwx] | (?![a-zA-Z0-9]) ) ([^a-zA-Z0-9]) /x
-    FANCY_STRING_KIND = Hash.new(:string).merge({
-      'r' => :regexp,
-      's' => :symbol,
-      'x' => :shell,
-    })
-    FANCY_STRING_INTERPRETED = Hash.new(true).merge({
-      'q' => false,
-      's' => false,
-      'w' => false,
-    })
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e1b9b340fadfb7e6bd98d84b279ad7feab877137.svn-base
--- a/.svn/pristine/e1/e1b9b340fadfb7e6bd98d84b279ad7feab877137.svn-base
+++ /dev/null
@@ -1,89 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'watchers_controller'
-
-# Re-raise errors caught by the controller.
-class WatchersController; def rescue_action(e) raise e end; end
-
-class WatchersControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
-           :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers
-
-  def setup
-    @controller = WatchersController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_get_watch_should_be_invalid
-    @request.session[:user_id] = 3
-    get :watch, :object_type => 'issue', :object_id => '1'
-    assert_response 405
-  end
-
-  def test_watch
-    @request.session[:user_id] = 3
-    assert_difference('Watcher.count') do
-      xhr :post, :watch, :object_type => 'issue', :object_id => '1'
-      assert_response :success
-      assert @response.body.include?('$$(".issue-1-watcher")')
-    end
-    assert Issue.find(1).watched_by?(User.find(3))
-  end
-
-  def test_watch_should_be_denied_without_permission
-    Role.find(2).remove_permission! :view_issues
-    @request.session[:user_id] = 3
-    assert_no_difference('Watcher.count') do
-      xhr :post, :watch, :object_type => 'issue', :object_id => '1'
-      assert_response 403
-    end
-  end
-
-  def test_unwatch
-    @request.session[:user_id] = 3
-    assert_difference('Watcher.count', -1) do
-      xhr :post, :unwatch, :object_type => 'issue', :object_id => '2'
-      assert_response :success
-      assert @response.body.include?('$$(".issue-2-watcher")')
-    end
-    assert !Issue.find(1).watched_by?(User.find(3))
-  end
-
-  def test_new_watcher
-    @request.session[:user_id] = 2
-    assert_difference('Watcher.count') do
-      xhr :post, :new, :object_type => 'issue', :object_id => '2', :watcher => {:user_id => '4'}
-      assert_response :success
-      assert_select_rjs :replace_html, 'watchers'
-    end
-    assert Issue.find(2).watched_by?(User.find(4))
-  end
-
-  def test_remove_watcher
-    @request.session[:user_id] = 2
-    assert_difference('Watcher.count', -1) do
-      xhr :post, :destroy, :object_type => 'issue', :object_id => '2', :user_id => '3'
-      assert_response :success
-      assert_select_rjs :replace_html, 'watchers'
-    end
-    assert !Issue.find(2).watched_by?(User.find(3))
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e1ba3e53c732b378a9d000cce4792c744ea0af38.svn-base
--- a/.svn/pristine/e1/e1ba3e53c732b378a9d000cce4792c744ea0af38.svn-base
+++ /dev/null
@@ -1,47 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'action_view/helpers/form_helper'
-
-class TabularFormBuilder < ActionView::Helpers::FormBuilder
-  include Redmine::I18n
-
-  (field_helpers.map(&:to_s) - %w(radio_button hidden_field fields_for) +
-        %w(date_select)).each do |selector|
-    src = <<-END_SRC
-    def #{selector}(field, options = {})
-      label_for_field(field, options) + super
-    end
-    END_SRC
-    class_eval src, __FILE__, __LINE__
-  end
-
-  def select(field, choices, options = {}, html_options = {})
-    label_for_field(field, options) + super
-  end
-
-  # Returns a label tag for the given field
-  def label_for_field(field, options = {})
-      return ''.html_safe if options.delete(:no_label)
-      text = options[:label].is_a?(Symbol) ? l(options[:label]) : options[:label]
-      text ||= l(("field_" + field.to_s.gsub(/\_id$/, "")).to_sym)
-      text += @template.content_tag("span", " *", :class => "required") if options.delete(:required)
-      @template.content_tag("label", text.html_safe,
-                                     :class => (@object && @object.errors[field] ? "error" : nil),
-                                     :for => (@object_name.to_s + "_" + field.to_s))
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e1/e1f79dbc801c5a1911d5ef1cd062ba6f439b524d.svn-base
--- /dev/null
+++ b/.svn/pristine/e1/e1f79dbc801c5a1911d5ef1cd062ba6f439b524d.svn-base
@@ -0,0 +1,83 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module ProjectsHelper
+  def link_to_version(version, options = {})
+    return '' unless version && version.is_a?(Version)
+    link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, options
+  end
+
+  def project_settings_tabs
+    tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
+            {:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
+            {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural},
+            {:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural},
+            {:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural},
+            {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki},
+            {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural},
+            {:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural},
+            {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities}
+            ]
+    tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
+  end
+
+  def parent_project_select_tag(project)
+    selected = project.parent
+    # retrieve the requested parent project
+    parent_id = (params[:project] && params[:project][:parent_id]) || params[:parent_id]
+    if parent_id
+      selected = (parent_id.blank? ? nil : Project.find(parent_id))
+    end
+
+    options = ''
+    options << "<option value=''></option>" if project.allowed_parents.include?(nil)
+    options << project_tree_options_for_select(project.allowed_parents.compact, :selected => selected)
+    content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id')
+  end
+
+  # Renders the projects index
+  def render_project_hierarchy(projects)
+    render_project_nested_lists(projects) do |project|
+      s = link_to_project(project, {}, :class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}")
+      if project.description.present?
+        s << content_tag('div', textilizable(project.short_description, :project => project), :class => 'wiki description')
+      end
+      s
+    end
+  end
+
+  # Returns a set of options for a select field, grouped by project.
+  def version_options_for_select(versions, selected=nil)
+    grouped = Hash.new {|h,k| h[k] = []}
+    versions.each do |version|
+      grouped[version.project.name] << [version.name, version.id]
+    end
+
+    if grouped.keys.size > 1
+      grouped_options_for_select(grouped, selected && selected.id)
+    else
+      options_for_select((grouped.values.first || []), selected && selected.id)
+    end
+  end
+
+  def format_version_sharing(sharing)
+    sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing)
+    l("label_version_sharing_#{sharing}")
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e2/e21a4b89d491f51b044f36a2083293e96a46fada.svn-base
--- /dev/null
+++ b/.svn/pristine/e2/e21a4b89d491f51b044f36a2083293e96a46fada.svn-base
@@ -0,0 +1,37 @@
+require 'rexml/document'
+
+module Redmine
+  module VERSION #:nodoc:
+    MAJOR = 2
+    MINOR = 3
+    TINY  = 1
+
+    # Branch values:
+    # * official release: nil
+    # * stable branch:    stable
+    # * trunk:            devel
+    BRANCH = 'stable'
+
+    # Retrieves the revision from the working copy
+    def self.revision
+      if File.directory?(File.join(Rails.root, '.svn'))
+        begin
+          path = Redmine::Scm::Adapters::AbstractAdapter.shell_quote(Rails.root.to_s)
+          if `svn info --xml #{path}` =~ /revision="(\d+)"/
+            return $1.to_i
+          end
+        rescue
+          # Could not find the current revision
+        end
+      end
+      nil
+    end
+
+    REVISION = self.revision
+    ARRAY    = [MAJOR, MINOR, TINY, BRANCH, REVISION].compact
+    STRING   = ARRAY.join('.')
+
+    def self.to_a; ARRAY  end
+    def self.to_s; STRING end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e2/e2217f43c0e991a1cb8790cb4bc4f4cf7be6b81c.svn-base
--- a/.svn/pristine/e2/e2217f43c0e991a1cb8790cb4bc4f4cf7be6b81c.svn-base
+++ /dev/null
@@ -1,87 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../test_helper', __FILE__)
-
-class Redmine::SafeAttributesTest < ActiveSupport::TestCase
-
-  class Base
-    def attributes=(attrs)
-      attrs.each do |key, value|
-        send("#{key}=", value)
-      end
-    end
-  end
-
-  class Person < Base
-    attr_accessor :firstname, :lastname, :login
-    include Redmine::SafeAttributes
-    safe_attributes :firstname, :lastname
-    safe_attributes :login, :if => lambda {|person, user| user.admin?}
-  end
-
-  class Book < Base
-    attr_accessor :title
-    include Redmine::SafeAttributes
-    safe_attributes :title
-  end
-
-  def test_safe_attribute_names
-    p = Person.new
-    assert_equal ['firstname', 'lastname'], p.safe_attribute_names(User.anonymous)
-    assert_equal ['firstname', 'lastname', 'login'], p.safe_attribute_names(User.find(1))
-  end
-
-  def test_safe_attribute_names_without_user
-    p = Person.new
-    User.current = nil
-    assert_equal ['firstname', 'lastname'], p.safe_attribute_names
-    User.current = User.find(1)
-    assert_equal ['firstname', 'lastname', 'login'], p.safe_attribute_names
-  end
-
-  def test_set_safe_attributes
-    p = Person.new
-    p.send('safe_attributes=', {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}, User.anonymous)
-    assert_equal 'John', p.firstname
-    assert_equal 'Smith', p.lastname
-    assert_nil p.login
-
-    p = Person.new
-    User.current = User.find(1)
-    p.send('safe_attributes=', {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}, User.find(1))
-    assert_equal 'John', p.firstname
-    assert_equal 'Smith', p.lastname
-    assert_equal 'jsmith', p.login
-  end
-
-  def test_set_safe_attributes_without_user
-    p = Person.new
-    User.current = nil
-    p.safe_attributes = {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}
-    assert_equal 'John', p.firstname
-    assert_equal 'Smith', p.lastname
-    assert_nil p.login
-
-    p = Person.new
-    User.current = User.find(1)
-    p.safe_attributes = {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}
-    assert_equal 'John', p.firstname
-    assert_equal 'Smith', p.lastname
-    assert_equal 'jsmith', p.login
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e2/e266e25b07a78428f3a93344eb6302f16e43b884.svn-base
--- a/.svn/pristine/e2/e266e25b07a78428f3a93344eb6302f16e43b884.svn-base
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="Content-Style-Type" content="text/css" />
-<title>Wiki formatting</title>
-<style type="text/css">
-h1 { font-family: Verdana, sans-serif; font-size: 14px; text-align: center; color: #444; }
-body { font-family: Verdana, sans-serif; font-size: 12px; color: #444; }
-table th { padding-top: 1em; }
-table td { vertical-align: top; background-color: #f5f5f5; height: 2em; vertical-align: middle;}
-table td code { font-size: 1.2em; }
-table td h1 { font-size: 1.8em; text-align: left; }
-table td h2 { font-size: 1.4em; text-align: left; }
-table td h3 { font-size: 1.2em; text-align: left; }
-
-</style>
-</head>
-<body>
-
-<h1>Wiki Syntax Quick Reference</h1>
-
-<table width="100%">
-<tr><th colspan="3">Font Styles</th></tr>
-<tr><th><img src="../images/jstoolbar/bt_strong.png" style="border: 1px solid #bbb;" alt="Strong" /></th><td width="50%">*Strong*</td><td width="50%"><strong>Strong</strong></td></tr>
-<tr><th><img src="../images/jstoolbar/bt_em.png" style="border: 1px solid #bbb;" alt="Italic" /></th><td>_Italic_</td><td><em>Italic</em></td></tr>
-<tr><th><img src="../images/jstoolbar/bt_ins.png" style="border: 1px solid #bbb;" alt="Underline" /></th><td>+Underline+</td><td><ins>Underline</ins></td></tr>
-<tr><th><img src="../images/jstoolbar/bt_del.png" style="border: 1px solid #bbb;" alt="Deleted" /></th><td>-Deleted-</td><td><del>Deleted</del></td></tr>
-<tr><th></th><td>??Quote??</td><td><cite>Quote</cite></td></tr>
-<tr><th><img src="../images/jstoolbar/bt_code.png" style="border: 1px solid #bbb;" alt="Inline Code" /></th><td>@Inline Code@</td><td><code>Inline Code</code></td></tr>
-<tr><th><img src="../images/jstoolbar/bt_pre.png" style="border: 1px solid #bbb;" alt="Preformatted text" /></th><td>&lt;pre><br />&nbsp;lines<br />&nbsp;of code<br />&lt;/pre></td><td>
-<pre>
- lines
- of code
-</pre>
-</td></tr>
-
-<tr><th colspan="3">Lists</th></tr>
-<tr><th><img src="../images/jstoolbar/bt_ul.png" style="border: 1px solid #bbb;" alt="Unordered list" /></th><td>* Item 1<br />* Item 2</td><td><ul><li>Item 1</li><li>Item 2</li></ul></td></tr>
-<tr><th><img src="../images/jstoolbar/bt_ol.png" style="border: 1px solid #bbb;" alt="Ordered list" /></th><td># Item 1<br /># Item 2</td><td><ol><li>Item 1</li><li>Item 2</li></ol></td></tr>
-
-<tr><th colspan="3">Headings</th></tr>
-<tr><th><img src="../images/jstoolbar/bt_h1.png" style="border: 1px solid #bbb;" alt="Heading 1" /></th><td>h1. Title 1</td><td><h1>Title 1</h1></td></tr>
-<tr><th><img src="../images/jstoolbar/bt_h2.png" style="border: 1px solid #bbb;" alt="Heading 2" /></th><td>h2. Title 2</td><td><h2>Title 2</h2></td></tr>
-<tr><th><img src="../images/jstoolbar/bt_h3.png" style="border: 1px solid #bbb;" alt="Heading 3" /></th><td>h3. Title 3</td><td><h3>Title 3</h3></td></tr>
-
-<tr><th colspan="3">Links</th></tr>
-<tr><th></th><td>http://foo.bar</td><td><a href="#">http://foo.bar</a></td></tr>
-<tr><th></th><td>"Foo":http://foo.bar</td><td><a href="#">Foo</a></td></tr>
-
-<tr><th colspan="3">Redmine links</th></tr>
-<tr><th><img src="../images/jstoolbar/bt_link.png" style="border: 1px solid #bbb;" alt="Link to a Wiki page" /></th><td>[[Wiki page]]</td><td><a href="#">Wiki page</a></td></tr>
-<tr><th></th><td>Issue #12</td><td>Issue <a href="#">#12</a></td></tr>
-<tr><th></th><td>Revision r43</td><td>Revision <a href="#">r43</a></td></tr>
-<tr><th></th><td>commit:f30e13e43</td><td><a href="#">f30e13e4</a></td></tr>
-<tr><th></th><td>source:some/file</td><td><a href="#">source:some/file</a></td></tr>
-
-<tr><th colspan="3">Inline images</th></tr>
-<tr><th><img src="../images/jstoolbar/bt_img.png" style="border: 1px solid #bbb;" alt="Image" /></th><td>!<em>image_url</em>!</td><td></td></tr>
-<tr><th></th><td>!<em>attached_image</em>!</td><td></td></tr>
-</table>
-
-<p><a href="wiki_syntax_detailed.html" onclick="window.open('wiki_syntax_detailed.html', '', ''); return false;">More Information</a></p>
-
-</body>
-</html>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e2/e28ba6f846c6f1515b66e0a9739735f84231de66.svn-base
--- /dev/null
+++ b/.svn/pristine/e2/e28ba6f846c6f1515b66e0a9739735f84231de66.svn-base
@@ -0,0 +1,254 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class VersionTest < ActiveSupport::TestCase
+  fixtures :projects, :users, :issues, :issue_statuses, :trackers, :enumerations, :versions, :projects_trackers
+
+  def setup
+  end
+
+  def test_create
+    v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '2011-03-25')
+    assert v.save
+    assert_equal 'open', v.status
+    assert_equal 'none', v.sharing
+  end
+
+  def test_invalid_effective_date_validation
+    v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '99999-01-01')
+    assert !v.valid?
+    v.effective_date = '2012-11-33'
+    assert !v.valid?
+    v.effective_date = '2012-31-11'
+    assert !v.valid?
+    v.effective_date = '-2012-31-11'
+    assert !v.valid?
+    v.effective_date = 'ABC'
+    assert !v.valid?
+    assert_include I18n.translate('activerecord.errors.messages.not_a_date'),
+                   v.errors[:effective_date]
+  end
+
+  def test_progress_should_be_0_with_no_assigned_issues
+    project = Project.find(1)
+    v = Version.create!(:project => project, :name => 'Progress')
+    assert_equal 0, v.completed_percent
+    assert_equal 0, v.closed_percent
+  end
+
+  def test_progress_should_be_0_with_unbegun_assigned_issues
+    project = Project.find(1)
+    v = Version.create!(:project => project, :name => 'Progress')
+    add_issue(v)
+    add_issue(v, :done_ratio => 0)
+    assert_progress_equal 0, v.completed_percent
+    assert_progress_equal 0, v.closed_percent
+  end
+
+  def test_progress_should_be_100_with_closed_assigned_issues
+    project = Project.find(1)
+    status = IssueStatus.where(:is_closed => true).first
+    v = Version.create!(:project => project, :name => 'Progress')
+    add_issue(v, :status => status)
+    add_issue(v, :status => status, :done_ratio => 20)
+    add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
+    add_issue(v, :status => status, :estimated_hours => 15)
+    assert_progress_equal 100.0, v.completed_percent
+    assert_progress_equal 100.0, v.closed_percent
+  end
+
+  def test_progress_should_consider_done_ratio_of_open_assigned_issues
+    project = Project.find(1)
+    v = Version.create!(:project => project, :name => 'Progress')
+    add_issue(v)
+    add_issue(v, :done_ratio => 20)
+    add_issue(v, :done_ratio => 70)
+    assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_percent
+    assert_progress_equal 0, v.closed_percent
+  end
+
+  def test_progress_should_consider_closed_issues_as_completed
+    project = Project.find(1)
+    v = Version.create!(:project => project, :name => 'Progress')
+    add_issue(v)
+    add_issue(v, :done_ratio => 20)
+    add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
+    assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_percent
+    assert_progress_equal (100.0)/3, v.closed_percent
+  end
+
+  def test_progress_should_consider_estimated_hours_to_weigth_issues
+    project = Project.find(1)
+    v = Version.create!(:project => project, :name => 'Progress')
+    add_issue(v, :estimated_hours => 10)
+    add_issue(v, :estimated_hours => 20, :done_ratio => 30)
+    add_issue(v, :estimated_hours => 40, :done_ratio => 10)
+    add_issue(v, :estimated_hours => 25, :status => IssueStatus.where(:is_closed => true).first)
+    assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_percent
+    assert_progress_equal 25.0/95.0*100, v.closed_percent
+  end
+
+  def test_progress_should_consider_average_estimated_hours_to_weigth_unestimated_issues
+    project = Project.find(1)
+    v = Version.create!(:project => project, :name => 'Progress')
+    add_issue(v, :done_ratio => 20)
+    add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
+    add_issue(v, :estimated_hours => 10, :done_ratio => 30)
+    add_issue(v, :estimated_hours => 40, :done_ratio => 10)
+    assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_percent
+    assert_progress_equal 25.0/100.0*100, v.closed_percent
+  end
+
+  def test_should_sort_scheduled_then_unscheduled_versions
+    Version.delete_all
+    v4 = Version.create!(:project_id => 1, :name => 'v4')
+    v3 = Version.create!(:project_id => 1, :name => 'v2', :effective_date => '2012-07-14')
+    v2 = Version.create!(:project_id => 1, :name => 'v1')
+    v1 = Version.create!(:project_id => 1, :name => 'v3', :effective_date => '2012-08-02')
+    v5 = Version.create!(:project_id => 1, :name => 'v5', :effective_date => '2012-07-02')
+
+    assert_equal [v5, v3, v1, v2, v4], [v1, v2, v3, v4, v5].sort
+    assert_equal [v5, v3, v1, v2, v4], Version.sorted.all
+  end
+
+  def test_completed_should_be_false_when_due_today
+    version = Version.create!(:project_id => 1, :effective_date => Date.today, :name => 'Due today')
+    assert_equal false, version.completed?
+  end
+
+  context "#behind_schedule?" do
+    setup do
+      ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
+      @project = Project.create!(:name => 'test0', :identifier => 'test0')
+      @project.trackers << Tracker.create!(:name => 'track')
+
+      @version = Version.create!(:project => @project, :effective_date => nil, :name => 'version')
+    end
+
+    should "be false if there are no issues assigned" do
+      @version.update_attribute(:effective_date, Date.yesterday)
+      assert_equal false, @version.behind_schedule?
+    end
+
+    should "be false if there is no effective_date" do
+      assert_equal false, @version.behind_schedule?
+    end
+
+    should "be false if all of the issues are ahead of schedule" do
+      @version.update_attribute(:effective_date, 7.days.from_now.to_date)
+      add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
+      add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
+      assert_equal 60, @version.completed_percent
+      assert_equal false, @version.behind_schedule?
+    end
+
+    should "be true if any of the issues are behind schedule" do
+      @version.update_attribute(:effective_date, 7.days.from_now.to_date)
+      add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
+      add_issue(@version, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
+      assert_equal 40, @version.completed_percent
+      assert_equal true, @version.behind_schedule?
+    end
+
+    should "be false if all of the issues are complete" do
+      @version.update_attribute(:effective_date, 7.days.from_now.to_date)
+      add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
+      add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
+      assert_equal 100, @version.completed_percent
+      assert_equal false, @version.behind_schedule?
+    end
+  end
+
+  context "#estimated_hours" do
+    setup do
+      @version = Version.create!(:project_id => 1, :name => '#estimated_hours')
+    end
+
+    should "return 0 with no assigned issues" do
+      assert_equal 0, @version.estimated_hours
+    end
+
+    should "return 0 with no estimated hours" do
+      add_issue(@version)
+      assert_equal 0, @version.estimated_hours
+    end
+
+    should "return the sum of estimated hours" do
+      add_issue(@version, :estimated_hours => 2.5)
+      add_issue(@version, :estimated_hours => 5)
+      assert_equal 7.5, @version.estimated_hours
+    end
+
+    should "return the sum of leaves estimated hours" do
+      parent = add_issue(@version)
+      add_issue(@version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
+      add_issue(@version, :estimated_hours => 5, :parent_issue_id => parent.id)
+      assert_equal 7.5, @version.estimated_hours
+    end
+  end
+
+  test "should update all issue's fixed_version associations in case the hierarchy changed XXX" do
+    User.current = User.find(1) # Need the admin's permissions
+
+    @version = Version.find(7)
+    # Separate hierarchy
+    project_1_issue = Issue.find(1)
+    project_1_issue.fixed_version = @version
+    assert project_1_issue.save, project_1_issue.errors.full_messages.to_s
+
+    project_5_issue = Issue.find(6)
+    project_5_issue.fixed_version = @version
+    assert project_5_issue.save
+
+    # Project
+    project_2_issue = Issue.find(4)
+    project_2_issue.fixed_version = @version
+    assert project_2_issue.save
+
+    # Update the sharing
+    @version.sharing = 'none'
+    assert @version.save
+
+    # Project 1 now out of the shared scope
+    project_1_issue.reload
+    assert_equal nil, project_1_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
+
+    # Project 5 now out of the shared scope
+    project_5_issue.reload
+    assert_equal nil, project_5_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
+
+    # Project 2 issue remains
+    project_2_issue.reload
+    assert_equal @version, project_2_issue.fixed_version
+  end
+
+  private
+
+  def add_issue(version, attributes={})
+    Issue.create!({:project => version.project,
+                   :fixed_version => version,
+                   :subject => 'Test',
+                   :author => User.first,
+                   :tracker => version.project.trackers.first}.merge(attributes))
+  end
+
+  def assert_progress_equal(expected_float, actual_float, message="")
+    assert_in_delta(expected_float, actual_float, 0.000001, message="")
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e2/e2b323ec405901a9b13bdff14ce49dc5afc50cd7.svn-base
--- /dev/null
+++ b/.svn/pristine/e2/e2b323ec405901a9b13bdff14ce49dc5afc50cd7.svn-base
@@ -0,0 +1,1110 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class UserTest < ActiveSupport::TestCase
+  fixtures :users, :members, :projects, :roles, :member_roles, :auth_sources,
+            :trackers, :issue_statuses,
+            :projects_trackers,
+            :watchers,
+            :issue_categories, :enumerations, :issues,
+            :journals, :journal_details,
+            :groups_users,
+            :enabled_modules
+
+  def setup
+    @admin = User.find(1)
+    @jsmith = User.find(2)
+    @dlopper = User.find(3)
+  end
+
+  def test_sorted_scope_should_sort_user_by_display_name
+    assert_equal User.all.map(&:name).map(&:downcase).sort, User.sorted.all.map(&:name).map(&:downcase)
+  end
+
+  def test_generate
+    User.generate!(:firstname => 'Testing connection')
+    User.generate!(:firstname => 'Testing connection')
+    assert_equal 2, User.count(:all, :conditions => {:firstname => 'Testing connection'})
+  end
+
+  def test_truth
+    assert_kind_of User, @jsmith
+  end
+
+  def test_mail_should_be_stripped
+    u = User.new
+    u.mail = " foo@bar.com  "
+    assert_equal "foo@bar.com", u.mail
+  end
+
+  def test_mail_validation
+    u = User.new
+    u.mail = ''
+    assert !u.valid?
+    assert_include I18n.translate('activerecord.errors.messages.blank'), u.errors[:mail]
+  end
+
+  def test_login_length_validation
+    user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
+    user.login = "x" * (User::LOGIN_LENGTH_LIMIT+1)
+    assert !user.valid?
+
+    user.login = "x" * (User::LOGIN_LENGTH_LIMIT)
+    assert user.valid?
+    assert user.save
+  end
+
+  def test_create
+    user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
+
+    user.login = "jsmith"
+    user.password, user.password_confirmation = "password", "password"
+    # login uniqueness
+    assert !user.save
+    assert_equal 1, user.errors.count
+
+    user.login = "newuser"
+    user.password, user.password_confirmation = "password", "pass"
+    # password confirmation
+    assert !user.save
+    assert_equal 1, user.errors.count
+
+    user.password, user.password_confirmation = "password", "password"
+    assert user.save
+  end
+
+  def test_user_before_create_should_set_the_mail_notification_to_the_default_setting
+    @user1 = User.generate!
+    assert_equal 'only_my_events', @user1.mail_notification
+    with_settings :default_notification_option => 'all' do
+      @user2 = User.generate!
+      assert_equal 'all', @user2.mail_notification
+    end
+  end
+
+  def test_user_login_should_be_case_insensitive
+    u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
+    u.login = 'newuser'
+    u.password, u.password_confirmation = "password", "password"
+    assert u.save
+    u = User.new(:firstname => "Similar", :lastname => "User", :mail => "similaruser@somenet.foo")
+    u.login = 'NewUser'
+    u.password, u.password_confirmation = "password", "password"
+    assert !u.save
+    assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:login]
+  end
+
+  def test_mail_uniqueness_should_not_be_case_sensitive
+    u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
+    u.login = 'newuser1'
+    u.password, u.password_confirmation = "password", "password"
+    assert u.save
+
+    u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
+    u.login = 'newuser2'
+    u.password, u.password_confirmation = "password", "password"
+    assert !u.save
+    assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:mail]
+  end
+
+  def test_update
+    assert_equal "admin", @admin.login
+    @admin.login = "john"
+    assert @admin.save, @admin.errors.full_messages.join("; ")
+    @admin.reload
+    assert_equal "john", @admin.login
+  end
+
+  def test_update_should_not_fail_for_legacy_user_with_different_case_logins
+    u1 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser1@somenet.foo")
+    u1.login = 'newuser1'
+    assert u1.save
+
+    u2 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser2@somenet.foo")
+    u2.login = 'newuser1'
+    assert u2.save(:validate => false)
+
+    user = User.find(u2.id)
+    user.firstname = "firstname"
+    assert user.save, "Save failed"
+  end
+
+  def test_destroy_should_delete_members_and_roles
+    members = Member.find_all_by_user_id(2)
+    ms = members.size
+    rs = members.collect(&:roles).flatten.size
+
+    assert_difference 'Member.count', - ms do
+      assert_difference 'MemberRole.count', - rs do
+        User.find(2).destroy
+      end
+    end
+
+    assert_nil User.find_by_id(2)
+    assert Member.find_all_by_user_id(2).empty?
+  end
+
+  def test_destroy_should_update_attachments
+    attachment = Attachment.create!(:container => Project.find(1),
+      :file => uploaded_test_file("testfile.txt", "text/plain"),
+      :author_id => 2)
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous, attachment.reload.author
+  end
+
+  def test_destroy_should_update_comments
+    comment = Comment.create!(
+      :commented => News.create!(:project_id => 1, :author_id => 1, :title => 'foo', :description => 'foo'),
+      :author => User.find(2),
+      :comments => 'foo'
+    )
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous, comment.reload.author
+  end
+
+  def test_destroy_should_update_issues
+    issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous, issue.reload.author
+  end
+
+  def test_destroy_should_unassign_issues
+    issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_nil issue.reload.assigned_to
+  end
+
+  def test_destroy_should_update_journals
+    issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
+    issue.init_journal(User.find(2), "update")
+    issue.save!
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous, issue.journals.first.reload.user
+  end
+
+  def test_destroy_should_update_journal_details_old_value
+    issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
+    issue.init_journal(User.find(1), "update")
+    issue.assigned_to_id = nil
+    assert_difference 'JournalDetail.count' do
+      issue.save!
+    end
+    journal_detail = JournalDetail.first(:order => 'id DESC')
+    assert_equal '2', journal_detail.old_value
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value
+  end
+
+  def test_destroy_should_update_journal_details_value
+    issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
+    issue.init_journal(User.find(1), "update")
+    issue.assigned_to_id = 2
+    assert_difference 'JournalDetail.count' do
+      issue.save!
+    end
+    journal_detail = JournalDetail.first(:order => 'id DESC')
+    assert_equal '2', journal_detail.value
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous.id.to_s, journal_detail.reload.value
+  end
+
+  def test_destroy_should_update_messages
+    board = Board.create!(:project_id => 1, :name => 'Board', :description => 'Board')
+    message = Message.create!(:board_id => board.id, :author_id => 2, :subject => 'foo', :content => 'foo')
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous, message.reload.author
+  end
+
+  def test_destroy_should_update_news
+    news = News.create!(:project_id => 1, :author_id => 2, :title => 'foo', :description => 'foo')
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous, news.reload.author
+  end
+
+  def test_destroy_should_delete_private_queries
+    query = Query.new(:name => 'foo', :is_public => false)
+    query.project_id = 1
+    query.user_id = 2
+    query.save!
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_nil Query.find_by_id(query.id)
+  end
+
+  def test_destroy_should_update_public_queries
+    query = Query.new(:name => 'foo', :is_public => true)
+    query.project_id = 1
+    query.user_id = 2
+    query.save!
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous, query.reload.user
+  end
+
+  def test_destroy_should_update_time_entries
+    entry = TimeEntry.new(:hours => '2', :spent_on => Date.today, :activity => TimeEntryActivity.create!(:name => 'foo'))
+    entry.project_id = 1
+    entry.user_id = 2
+    entry.save!
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous, entry.reload.user
+  end
+
+  def test_destroy_should_delete_tokens
+    token = Token.create!(:user_id => 2, :value => 'foo')
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_nil Token.find_by_id(token.id)
+  end
+
+  def test_destroy_should_delete_watchers
+    issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
+    watcher = Watcher.create!(:user_id => 2, :watchable => issue)
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_nil Watcher.find_by_id(watcher.id)
+  end
+
+  def test_destroy_should_update_wiki_contents
+    wiki_content = WikiContent.create!(
+      :text => 'foo',
+      :author_id => 2,
+      :page => WikiPage.create!(:title => 'Foo', :wiki => Wiki.create!(:project_id => 1, :start_page => 'Start'))
+    )
+    wiki_content.text = 'bar'
+    assert_difference 'WikiContent::Version.count' do
+      wiki_content.save!
+    end
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_equal User.anonymous, wiki_content.reload.author
+    wiki_content.versions.each do |version|
+      assert_equal User.anonymous, version.reload.author
+    end
+  end
+
+  def test_destroy_should_nullify_issue_categories
+    category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo')
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_nil category.reload.assigned_to_id
+  end
+
+  def test_destroy_should_nullify_changesets
+    changeset = Changeset.create!(
+      :repository => Repository::Subversion.create!(
+        :project_id => 1,
+        :url => 'file:///tmp',
+        :identifier => 'tmp'
+      ),
+      :revision => '12',
+      :committed_on => Time.now,
+      :committer => 'jsmith'
+      )
+    assert_equal 2, changeset.user_id
+
+    User.find(2).destroy
+    assert_nil User.find_by_id(2)
+    assert_nil changeset.reload.user_id
+  end
+
+  def test_anonymous_user_should_not_be_destroyable
+    assert_no_difference 'User.count' do
+      assert_equal false, User.anonymous.destroy
+    end
+  end
+
+  def test_validate_login_presence
+    @admin.login = ""
+    assert !@admin.save
+    assert_equal 1, @admin.errors.count
+  end
+
+  def test_validate_mail_notification_inclusion
+    u = User.new
+    u.mail_notification = 'foo'
+    u.save
+    assert_not_nil u.errors[:mail_notification]
+  end
+
+  context "User#try_to_login" do
+    should "fall-back to case-insensitive if user login is not found as-typed." do
+      user = User.try_to_login("AdMin", "admin")
+      assert_kind_of User, user
+      assert_equal "admin", user.login
+    end
+
+    should "select the exact matching user first" do
+      case_sensitive_user = User.generate! do |user|
+        user.password = "admin123"
+      end
+      # bypass validations to make it appear like existing data
+      case_sensitive_user.update_attribute(:login, 'ADMIN')
+
+      user = User.try_to_login("ADMIN", "admin123")
+      assert_kind_of User, user
+      assert_equal "ADMIN", user.login
+
+    end
+  end
+
+  def test_password
+    user = User.try_to_login("admin", "admin")
+    assert_kind_of User, user
+    assert_equal "admin", user.login
+    user.password = "hello123"
+    assert user.save
+
+    user = User.try_to_login("admin", "hello123")
+    assert_kind_of User, user
+    assert_equal "admin", user.login
+  end
+
+  def test_validate_password_length
+    with_settings :password_min_length => '100' do
+      user = User.new(:firstname => "new100", :lastname => "user100", :mail => "newuser100@somenet.foo")
+      user.login = "newuser100"
+      user.password, user.password_confirmation = "password100", "password100"
+      assert !user.save
+      assert_equal 1, user.errors.count
+    end
+  end
+
+  def test_name_format
+    assert_equal 'John S.', @jsmith.name(:firstname_lastinitial)
+    assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
+    with_settings :user_format => :firstname_lastname do
+      assert_equal 'John Smith', @jsmith.reload.name
+    end
+    with_settings :user_format => :username do
+      assert_equal 'jsmith', @jsmith.reload.name
+    end
+    with_settings :user_format => :lastname do
+      assert_equal 'Smith', @jsmith.reload.name
+    end
+  end
+
+  def test_today_should_return_the_day_according_to_user_time_zone
+    preference = User.find(1).pref
+    date = Date.new(2012, 05, 15)
+    time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
+    Date.stubs(:today).returns(date)
+    Time.stubs(:now).returns(time)
+
+    preference.update_attribute :time_zone, 'Baku' # UTC+4
+    assert_equal '2012-05-16', User.find(1).today.to_s
+
+    preference.update_attribute :time_zone, 'La Paz' # UTC-4
+    assert_equal '2012-05-15', User.find(1).today.to_s
+
+    preference.update_attribute :time_zone, ''
+    assert_equal '2012-05-15', User.find(1).today.to_s
+  end
+
+  def test_time_to_date_should_return_the_date_according_to_user_time_zone
+    preference = User.find(1).pref
+    time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
+
+    preference.update_attribute :time_zone, 'Baku' # UTC+4
+    assert_equal '2012-05-16', User.find(1).time_to_date(time).to_s
+
+    preference.update_attribute :time_zone, 'La Paz' # UTC-4
+    assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
+
+    preference.update_attribute :time_zone, ''
+    assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
+  end
+
+  def test_fields_for_order_statement_should_return_fields_according_user_format_setting
+    with_settings :user_format => 'lastname_coma_firstname' do
+      assert_equal ['users.lastname', 'users.firstname', 'users.id'], User.fields_for_order_statement
+    end
+  end
+  
+  def test_fields_for_order_statement_width_table_name_should_prepend_table_name
+    with_settings :user_format => 'lastname_firstname' do
+      assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'], User.fields_for_order_statement('authors')
+    end
+  end
+  
+  def test_fields_for_order_statement_with_blank_format_should_return_default
+    with_settings :user_format => '' do
+      assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
+    end
+  end
+  
+  def test_fields_for_order_statement_with_invalid_format_should_return_default
+    with_settings :user_format => 'foo' do
+      assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
+    end
+  end
+
+  def test_lock
+    user = User.try_to_login("jsmith", "jsmith")
+    assert_equal @jsmith, user
+
+    @jsmith.status = User::STATUS_LOCKED
+    assert @jsmith.save
+
+    user = User.try_to_login("jsmith", "jsmith")
+    assert_equal nil, user
+  end
+
+  context ".try_to_login" do
+    context "with good credentials" do
+      should "return the user" do
+        user = User.try_to_login("admin", "admin")
+        assert_kind_of User, user
+        assert_equal "admin", user.login
+      end
+    end
+
+    context "with wrong credentials" do
+      should "return nil" do
+        assert_nil User.try_to_login("admin", "foo")
+      end
+    end
+  end
+
+  if ldap_configured?
+    context "#try_to_login using LDAP" do
+      context "with failed connection to the LDAP server" do
+        should "return nil" do
+          @auth_source = AuthSourceLdap.find(1)
+          AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
+
+          assert_equal nil, User.try_to_login('edavis', 'wrong')
+        end
+      end
+
+      context "with an unsuccessful authentication" do
+        should "return nil" do
+          assert_equal nil, User.try_to_login('edavis', 'wrong')
+        end
+      end
+
+      context "binding with user's account" do
+        setup do
+          @auth_source = AuthSourceLdap.find(1)
+          @auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
+          @auth_source.account_password = ''
+          @auth_source.save!
+
+          @ldap_user = User.new(:mail => 'example1@redmine.org', :firstname => 'LDAP', :lastname => 'user', :auth_source_id => 1)
+          @ldap_user.login = 'example1'
+          @ldap_user.save!
+        end
+
+        context "with a successful authentication" do
+          should "return the user" do
+            assert_equal @ldap_user, User.try_to_login('example1', '123456')
+          end
+        end
+
+        context "with an unsuccessful authentication" do
+          should "return nil" do
+            assert_nil User.try_to_login('example1', '11111')
+          end
+        end
+      end
+
+      context "on the fly registration" do
+        setup do
+          @auth_source = AuthSourceLdap.find(1)
+          @auth_source.update_attribute :onthefly_register, true
+        end
+
+        context "with a successful authentication" do
+          should "create a new user account if it doesn't exist" do
+            assert_difference('User.count') do
+              user = User.try_to_login('edavis', '123456')
+              assert !user.admin?
+            end
+          end
+
+          should "retrieve existing user" do
+            user = User.try_to_login('edavis', '123456')
+            user.admin = true
+            user.save!
+
+            assert_no_difference('User.count') do
+              user = User.try_to_login('edavis', '123456')
+              assert user.admin?
+            end
+          end
+        end
+
+        context "binding with user's account" do
+          setup do
+            @auth_source = AuthSourceLdap.find(1)
+            @auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
+            @auth_source.account_password = ''
+            @auth_source.save!
+          end
+  
+          context "with a successful authentication" do
+            should "create a new user account if it doesn't exist" do
+              assert_difference('User.count') do
+                user = User.try_to_login('example1', '123456')
+                assert_kind_of User, user
+              end
+            end
+          end
+  
+          context "with an unsuccessful authentication" do
+            should "return nil" do
+              assert_nil User.try_to_login('example1', '11111')
+            end
+          end
+        end
+      end
+    end
+
+  else
+    puts "Skipping LDAP tests."
+  end
+
+  def test_create_anonymous
+    AnonymousUser.delete_all
+    anon = User.anonymous
+    assert !anon.new_record?
+    assert_kind_of AnonymousUser, anon
+  end
+
+  def test_ensure_single_anonymous_user
+    AnonymousUser.delete_all
+    anon1 = User.anonymous
+    assert !anon1.new_record?
+    assert_kind_of AnonymousUser, anon1
+    anon2 = AnonymousUser.create(
+                :lastname => 'Anonymous', :firstname => '',
+                :mail => '', :login => '', :status => 0)
+    assert_equal 1, anon2.errors.count
+  end
+
+  def test_rss_key
+    assert_nil @jsmith.rss_token
+    key = @jsmith.rss_key
+    assert_equal 40, key.length
+
+    @jsmith.reload
+    assert_equal key, @jsmith.rss_key
+  end
+
+  def test_rss_key_should_not_be_generated_twice
+    assert_difference 'Token.count', 1 do
+      key1 = @jsmith.rss_key
+      key2 = @jsmith.rss_key
+      assert_equal key1, key2
+    end
+  end
+
+  def test_api_key_should_not_be_generated_twice
+    assert_difference 'Token.count', 1 do
+      key1 = @jsmith.api_key
+      key2 = @jsmith.api_key
+      assert_equal key1, key2
+    end
+  end
+
+  context "User#api_key" do
+    should "generate a new one if the user doesn't have one" do
+      user = User.generate!(:api_token => nil)
+      assert_nil user.api_token
+
+      key = user.api_key
+      assert_equal 40, key.length
+      user.reload
+      assert_equal key, user.api_key
+    end
+
+    should "return the existing api token value" do
+      user = User.generate!
+      token = Token.create!(:action => 'api')
+      user.api_token = token
+      assert user.save
+
+      assert_equal token.value, user.api_key
+    end
+  end
+
+  context "User#find_by_api_key" do
+    should "return nil if no matching key is found" do
+      assert_nil User.find_by_api_key('zzzzzzzzz')
+    end
+
+    should "return nil if the key is found for an inactive user" do
+      user = User.generate!
+      user.status = User::STATUS_LOCKED
+      token = Token.create!(:action => 'api')
+      user.api_token = token
+      user.save
+
+      assert_nil User.find_by_api_key(token.value)
+    end
+
+    should "return the user if the key is found for an active user" do
+      user = User.generate!
+      token = Token.create!(:action => 'api')
+      user.api_token = token
+      user.save
+
+      assert_equal user, User.find_by_api_key(token.value)
+    end
+  end
+
+  def test_default_admin_account_changed_should_return_false_if_account_was_not_changed
+    user = User.find_by_login("admin")
+    user.password = "admin"
+    assert user.save(:validate => false)
+
+    assert_equal false, User.default_admin_account_changed?
+  end
+
+  def test_default_admin_account_changed_should_return_true_if_password_was_changed
+    user = User.find_by_login("admin")
+    user.password = "newpassword"
+    user.save!
+
+    assert_equal true, User.default_admin_account_changed?
+  end
+
+  def test_default_admin_account_changed_should_return_true_if_account_is_disabled
+    user = User.find_by_login("admin")
+    user.password = "admin"
+    user.status = User::STATUS_LOCKED
+    assert user.save(:validate => false)
+
+    assert_equal true, User.default_admin_account_changed?
+  end
+
+  def test_default_admin_account_changed_should_return_true_if_account_does_not_exist
+    user = User.find_by_login("admin")
+    user.destroy
+
+    assert_equal true, User.default_admin_account_changed?
+  end
+
+  def test_membership_with_project_should_return_membership
+    project = Project.find(1)
+
+    membership = @jsmith.membership(project)
+    assert_kind_of Member, membership
+    assert_equal @jsmith, membership.user
+    assert_equal project, membership.project
+  end
+
+  def test_membership_with_project_id_should_return_membership
+    project = Project.find(1)
+
+    membership = @jsmith.membership(1)
+    assert_kind_of Member, membership
+    assert_equal @jsmith, membership.user
+    assert_equal project, membership.project
+  end
+
+  def test_membership_for_non_member_should_return_nil
+    project = Project.find(1)
+
+    user = User.generate!
+    membership = user.membership(1)
+    assert_nil membership
+  end
+
+  def test_roles_for_project
+    # user with a role
+    roles = @jsmith.roles_for_project(Project.find(1))
+    assert_kind_of Role, roles.first
+    assert_equal "Manager", roles.first.name
+
+    # user with no role
+    assert_nil @dlopper.roles_for_project(Project.find(2)).detect {|role| role.member?}
+  end
+
+  def test_projects_by_role_for_user_with_role
+    user = User.find(2)
+    assert_kind_of Hash, user.projects_by_role
+    assert_equal 2, user.projects_by_role.size
+    assert_equal [1,5], user.projects_by_role[Role.find(1)].collect(&:id).sort
+    assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort
+  end
+
+  def test_accessing_projects_by_role_with_no_projects_should_return_an_empty_array
+    user = User.find(2)
+    assert_equal [], user.projects_by_role[Role.find(3)]
+    # should not update the hash
+    assert_nil user.projects_by_role.values.detect(&:blank?)
+  end
+
+  def test_projects_by_role_for_user_with_no_role
+    user = User.generate!
+    assert_equal({}, user.projects_by_role)
+  end
+
+  def test_projects_by_role_for_anonymous
+    assert_equal({}, User.anonymous.projects_by_role)
+  end
+
+  def test_valid_notification_options
+    # without memberships
+    assert_equal 5, User.find(7).valid_notification_options.size
+    # with memberships
+    assert_equal 6, User.find(2).valid_notification_options.size
+  end
+
+  def test_valid_notification_options_class_method
+    assert_equal 5, User.valid_notification_options.size
+    assert_equal 5, User.valid_notification_options(User.find(7)).size
+    assert_equal 6, User.valid_notification_options(User.find(2)).size
+  end
+
+  def test_mail_notification_all
+    @jsmith.mail_notification = 'all'
+    @jsmith.notified_project_ids = []
+    @jsmith.save
+    @jsmith.reload
+    assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
+  end
+
+  def test_mail_notification_selected
+    @jsmith.mail_notification = 'selected'
+    @jsmith.notified_project_ids = [1]
+    @jsmith.save
+    @jsmith.reload
+    assert Project.find(1).recipients.include?(@jsmith.mail)
+  end
+
+  def test_mail_notification_only_my_events
+    @jsmith.mail_notification = 'only_my_events'
+    @jsmith.notified_project_ids = []
+    @jsmith.save
+    @jsmith.reload
+    assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
+  end
+
+  def test_comments_sorting_preference
+    assert !@jsmith.wants_comments_in_reverse_order?
+    @jsmith.pref.comments_sorting = 'asc'
+    assert !@jsmith.wants_comments_in_reverse_order?
+    @jsmith.pref.comments_sorting = 'desc'
+    assert @jsmith.wants_comments_in_reverse_order?
+  end
+
+  def test_find_by_mail_should_be_case_insensitive
+    u = User.find_by_mail('JSmith@somenet.foo')
+    assert_not_nil u
+    assert_equal 'jsmith@somenet.foo', u.mail
+  end
+
+  def test_random_password
+    u = User.new
+    u.random_password
+    assert !u.password.blank?
+    assert !u.password_confirmation.blank?
+  end
+
+  context "#change_password_allowed?" do
+    should "be allowed if no auth source is set" do
+      user = User.generate!
+      assert user.change_password_allowed?
+    end
+
+    should "delegate to the auth source" do
+      user = User.generate!
+
+      allowed_auth_source = AuthSource.generate!
+      def allowed_auth_source.allow_password_changes?; true; end
+
+      denied_auth_source = AuthSource.generate!
+      def denied_auth_source.allow_password_changes?; false; end
+
+      assert user.change_password_allowed?
+
+      user.auth_source = allowed_auth_source
+      assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
+
+      user.auth_source = denied_auth_source
+      assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
+    end
+  end
+
+  def test_own_account_deletable_should_be_true_with_unsubscrive_enabled
+    with_settings :unsubscribe => '1' do
+      assert_equal true, User.find(2).own_account_deletable?
+    end
+  end
+
+  def test_own_account_deletable_should_be_false_with_unsubscrive_disabled
+    with_settings :unsubscribe => '0' do
+      assert_equal false, User.find(2).own_account_deletable?
+    end
+  end
+
+  def test_own_account_deletable_should_be_false_for_a_single_admin
+    User.delete_all(["admin = ? AND id <> ?", true, 1])
+
+    with_settings :unsubscribe => '1' do
+      assert_equal false, User.find(1).own_account_deletable?
+    end
+  end
+
+  def test_own_account_deletable_should_be_true_for_an_admin_if_other_admin_exists
+    User.generate! do |user|
+      user.admin = true
+    end
+
+    with_settings :unsubscribe => '1' do
+      assert_equal true, User.find(1).own_account_deletable?
+    end
+  end
+
+  context "#allowed_to?" do
+    context "with a unique project" do
+      should "return false if project is archived" do
+        project = Project.find(1)
+        Project.any_instance.stubs(:status).returns(Project::STATUS_ARCHIVED)
+        assert_equal false, @admin.allowed_to?(:view_issues, Project.find(1))
+      end
+
+      should "return false for write action if project is closed" do
+        project = Project.find(1)
+        Project.any_instance.stubs(:status).returns(Project::STATUS_CLOSED)
+        assert_equal false, @admin.allowed_to?(:edit_project, Project.find(1))
+      end
+
+      should "return true for read action if project is closed" do
+        project = Project.find(1)
+        Project.any_instance.stubs(:status).returns(Project::STATUS_CLOSED)
+        assert_equal true, @admin.allowed_to?(:view_project, Project.find(1))
+      end
+
+      should "return false if related module is disabled" do
+        project = Project.find(1)
+        project.enabled_module_names = ["issue_tracking"]
+        assert_equal true, @admin.allowed_to?(:add_issues, project)
+        assert_equal false, @admin.allowed_to?(:view_wiki_pages, project)
+      end
+
+      should "authorize nearly everything for admin users" do
+        project = Project.find(1)
+        assert ! @admin.member_of?(project)
+        %w(edit_issues delete_issues manage_news add_documents manage_wiki).each do |p|
+          assert_equal true, @admin.allowed_to?(p.to_sym, project)
+        end
+      end
+
+      should "authorize normal users depending on their roles" do
+        project = Project.find(1)
+        assert_equal true, @jsmith.allowed_to?(:delete_messages, project)    #Manager
+        assert_equal false, @dlopper.allowed_to?(:delete_messages, project) #Developper
+      end
+    end
+
+    context "with multiple projects" do
+      should "return false if array is empty" do
+        assert_equal false, @admin.allowed_to?(:view_project, [])
+      end
+
+      should "return true only if user has permission on all these projects" do
+        assert_equal true, @admin.allowed_to?(:view_project, Project.all)
+        assert_equal false, @dlopper.allowed_to?(:view_project, Project.all) #cannot see Project(2)
+        assert_equal true, @jsmith.allowed_to?(:edit_issues, @jsmith.projects) #Manager or Developer everywhere
+        assert_equal false, @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects) #Dev cannot delete_issue_watchers
+      end
+
+      should "behave correctly with arrays of 1 project" do
+        assert_equal false, User.anonymous.allowed_to?(:delete_issues, [Project.first])
+      end
+    end
+
+    context "with options[:global]" do
+      should "authorize if user has at least one role that has this permission" do
+        @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
+        @anonymous = User.find(6)
+        assert_equal true, @jsmith.allowed_to?(:delete_issue_watchers, nil, :global => true)
+        assert_equal false, @dlopper2.allowed_to?(:delete_issue_watchers, nil, :global => true)
+        assert_equal true, @dlopper2.allowed_to?(:add_issues, nil, :global => true)
+        assert_equal false, @anonymous.allowed_to?(:add_issues, nil, :global => true)
+        assert_equal true, @anonymous.allowed_to?(:view_issues, nil, :global => true)
+      end
+    end
+  end
+
+  context "User#notify_about?" do
+    context "Issues" do
+      setup do
+        @project = Project.find(1)
+        @author = User.generate!
+        @assignee = User.generate!
+        @issue = Issue.generate!(:project => @project, :assigned_to => @assignee, :author => @author)
+      end
+
+      should "be true for a user with :all" do
+        @author.update_attribute(:mail_notification, 'all')
+        assert @author.notify_about?(@issue)
+      end
+
+      should "be false for a user with :none" do
+        @author.update_attribute(:mail_notification, 'none')
+        assert ! @author.notify_about?(@issue)
+      end
+
+      should "be false for a user with :only_my_events and isn't an author, creator, or assignee" do
+        @user = User.generate!(:mail_notification => 'only_my_events')
+        Member.create!(:user => @user, :project => @project, :role_ids => [1])
+        assert ! @user.notify_about?(@issue)
+      end
+
+      should "be true for a user with :only_my_events and is the author" do
+        @author.update_attribute(:mail_notification, 'only_my_events')
+        assert @author.notify_about?(@issue)
+      end
+
+      should "be true for a user with :only_my_events and is the assignee" do
+        @assignee.update_attribute(:mail_notification, 'only_my_events')
+        assert @assignee.notify_about?(@issue)
+      end
+
+      should "be true for a user with :only_assigned and is the assignee" do
+        @assignee.update_attribute(:mail_notification, 'only_assigned')
+        assert @assignee.notify_about?(@issue)
+      end
+
+      should "be false for a user with :only_assigned and is not the assignee" do
+        @author.update_attribute(:mail_notification, 'only_assigned')
+        assert ! @author.notify_about?(@issue)
+      end
+
+      should "be true for a user with :only_owner and is the author" do
+        @author.update_attribute(:mail_notification, 'only_owner')
+        assert @author.notify_about?(@issue)
+      end
+
+      should "be false for a user with :only_owner and is not the author" do
+        @assignee.update_attribute(:mail_notification, 'only_owner')
+        assert ! @assignee.notify_about?(@issue)
+      end
+
+      should "be true for a user with :selected and is the author" do
+        @author.update_attribute(:mail_notification, 'selected')
+        assert @author.notify_about?(@issue)
+      end
+
+      should "be true for a user with :selected and is the assignee" do
+        @assignee.update_attribute(:mail_notification, 'selected')
+        assert @assignee.notify_about?(@issue)
+      end
+
+      should "be false for a user with :selected and is not the author or assignee" do
+        @user = User.generate!(:mail_notification => 'selected')
+        Member.create!(:user => @user, :project => @project, :role_ids => [1])
+        assert ! @user.notify_about?(@issue)
+      end
+    end
+  end
+
+  def test_notify_about_news
+    user = User.generate!
+    news = News.new
+
+    User::MAIL_NOTIFICATION_OPTIONS.map(&:first).each do |option|
+      user.mail_notification = option
+      assert_equal (option != 'none'), user.notify_about?(news)
+    end
+  end
+
+  def test_salt_unsalted_passwords
+    # Restore a user with an unsalted password
+    user = User.find(1)
+    user.salt = nil
+    user.hashed_password = User.hash_password("unsalted")
+    user.save!
+
+    User.salt_unsalted_passwords!
+
+    user.reload
+    # Salt added
+    assert !user.salt.blank?
+    # Password still valid
+    assert user.check_password?("unsalted")
+    assert_equal user, User.try_to_login(user.login, "unsalted")
+  end
+
+  if Object.const_defined?(:OpenID)
+
+  def test_setting_identity_url
+    normalized_open_id_url = 'http://example.com/'
+    u = User.new( :identity_url => 'http://example.com/' )
+    assert_equal normalized_open_id_url, u.identity_url
+  end
+
+  def test_setting_identity_url_without_trailing_slash
+    normalized_open_id_url = 'http://example.com/'
+    u = User.new( :identity_url => 'http://example.com' )
+    assert_equal normalized_open_id_url, u.identity_url
+  end
+
+  def test_setting_identity_url_without_protocol
+    normalized_open_id_url = 'http://example.com/'
+    u = User.new( :identity_url => 'example.com' )
+    assert_equal normalized_open_id_url, u.identity_url
+  end
+
+  def test_setting_blank_identity_url
+    u = User.new( :identity_url => 'example.com' )
+    u.identity_url = ''
+    assert u.identity_url.blank?
+  end
+
+  def test_setting_invalid_identity_url
+    u = User.new( :identity_url => 'this is not an openid url' )
+    assert u.identity_url.blank?
+  end
+
+  else
+    puts "Skipping openid tests."
+  end
+
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e3/e31701d543027feaaec6f5716a6efe5c0c48db65.svn-base
--- a/.svn/pristine/e3/e31701d543027feaaec6f5716a6efe5c0c48db65.svn-base
+++ /dev/null
@@ -1,122 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2009  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../../../test_helper', __FILE__)
-
-module RedmineMenuTestHelper
-  # Helpers
-  def get_menu_item(menu_name, item_name)
-    Redmine::MenuManager.items(menu_name).find {|item| item.name == item_name.to_sym}
-  end
-end
-
-class Redmine::MenuManager::MenuItemTest < ActiveSupport::TestCase
-  include RedmineMenuTestHelper
-
-  Redmine::MenuManager.map :test_menu do |menu|
-    menu.push(:parent, '/test', { })
-    menu.push(:child_menu, '/test', { :parent => :parent})
-    menu.push(:child2_menu, '/test', { :parent => :parent})
-  end
-
-  context "MenuItem#caption" do
-    should "be tested"
-  end
-
-  context "MenuItem#html_options" do
-    should "be tested"
-  end
-
-  # context new menu item
-  def test_new_menu_item_should_require_a_name
-    assert_raises ArgumentError do
-      Redmine::MenuManager::MenuItem.new
-    end
-  end
-
-  def test_new_menu_item_should_require_an_url
-    assert_raises ArgumentError do
-      Redmine::MenuManager::MenuItem.new(:test_missing_url)
-    end
-  end
-
-  def test_new_menu_item_should_require_the_options
-    assert_raises ArgumentError do
-      Redmine::MenuManager::MenuItem.new(:test_missing_options, '/test')
-    end
-  end
-
-  def test_new_menu_item_with_all_required_parameters
-    assert Redmine::MenuManager::MenuItem.new(:test_good_menu, '/test', {})
-  end
-
-  def test_new_menu_item_should_require_a_proc_to_use_for_the_if_condition
-    assert_raises ArgumentError do
-      Redmine::MenuManager::MenuItem.new(:test_error, '/test',
-                                         {
-                                           :if => ['not_a_proc']
-                                         })
-    end
-
-    assert Redmine::MenuManager::MenuItem.new(:test_good_if, '/test',
-                                              {
-                                                :if => Proc.new{}
-                                              })
-  end
-
-  def test_new_menu_item_should_allow_a_hash_for_extra_html_options
-    assert_raises ArgumentError do
-      Redmine::MenuManager::MenuItem.new(:test_error, '/test',
-                                         {
-                                           :html => ['not_a_hash']
-                                         })
-    end
-
-    assert Redmine::MenuManager::MenuItem.new(:test_good_html, '/test',
-                                              {
-                                                :html => { :onclick => 'doSomething'}
-                                              })
-  end
-
-  def test_new_menu_item_should_require_a_proc_to_use_the_children_option
-    assert_raises ArgumentError do
-      Redmine::MenuManager::MenuItem.new(:test_error, '/test',
-                                         {
-                                           :children => ['not_a_proc']
-                                         })
-    end
-
-    assert Redmine::MenuManager::MenuItem.new(:test_good_children, '/test',
-                                              {
-                                                :children => Proc.new{}
-                                              })
-  end
-
-  def test_new_should_not_allow_setting_the_parent_item_to_the_current_item
-    assert_raises ArgumentError do
-      Redmine::MenuManager::MenuItem.new(:test_error, '/test', { :parent => :test_error })
-    end
-  end
-
-  def test_has_children
-    parent_item = get_menu_item(:test_menu, :parent)
-    assert parent_item.hasChildren?
-    assert_equal 2, parent_item.children.size
-    assert_equal get_menu_item(:test_menu, :child_menu), parent_item.children[0]
-    assert_equal get_menu_item(:test_menu, :child2_menu), parent_item.children[1]
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e3/e354d26876e9a19dc212c7bfe45506eaea725d1b.svn-base
--- a/.svn/pristine/e3/e354d26876e9a19dc212c7bfe45506eaea725d1b.svn-base
+++ /dev/null
@@ -1,1012 +0,0 @@
-# Redmine EU language
-# Author: Ales Zabala Alava (Shagi), <shagi@gisa-elkartea.org>
-# 2010-01-25
-# Distributed under the same terms as the Redmine itself.
-eu:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y/%m/%d"
-      short: "%b %d"
-      long: "%Y %B %d"
-      
-    day_names: [Igandea, Astelehena, Asteartea, Asteazkena, Osteguna, Ostirala, Larunbata]
-    abbr_day_names: [Ig., Al., Ar., Az., Og., Or., La.]
-      
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, Urtarrila, Otsaila, Martxoa, Apirila, Maiatza, Ekaina, Uztaila, Abuztua, Iraila, Urria, Azaroa, Abendua]
-    abbr_month_names: [~, Urt, Ots, Mar, Api, Mai, Eka, Uzt, Abu, Ira, Urr, Aza, Abe]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%Y/%m/%d %H:%M"
-      time: "%H:%M"
-      short: "%b %d %H:%M"
-      long: "%Y %B %d %H:%M"
-    am: "am"
-    pm: "pm"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "minutu erdi"
-      less_than_x_seconds:
-        one:   "segundu bat baino gutxiago"
-        other: "%{count} segundu baino gutxiago"
-      x_seconds:
-        one:   "segundu 1"
-        other: "%{count} segundu"
-      less_than_x_minutes:
-        one:   "minutu bat baino gutxiago"
-        other: "%{count} minutu baino gutxiago"
-      x_minutes:
-        one:   "minutu 1"
-        other: "%{count} minutu"
-      about_x_hours:
-        one:   "ordu 1 inguru"
-        other: "%{count} ordu inguru"
-      x_days:
-        one:   "egun 1"
-        other: "%{count} egun"
-      about_x_months:
-        one:   "hilabete 1 inguru"
-        other: "%{count} hilabete inguru"
-      x_months:
-        one:   "hilabete 1"
-        other: "%{count} hilabete"
-      about_x_years:
-        one:   "urte 1 inguru"
-        other: "%{count} urte inguru"
-      over_x_years:
-        one:   "urte 1 baino gehiago"
-        other: "%{count} urte baino gehiago"
-      almost_x_years:
-        one:   "ia urte 1"
-        other: "ia %{count} urte"
-
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Byte"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-        
-# Used in array.to_sentence.
-  support:
-    array:
-      sentence_connector: "eta"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "Errore batek %{model} hau godetzea galarazi du."
-          other:  "%{count} errorek %{model} hau gordetzea galarazi dute."
-      messages:
-        inclusion: "ez dago zerrendan"
-        exclusion: "erreserbatuta dago"
-        invalid: "baliogabea da"
-        confirmation: "ez du berrespenarekin bat egiten"
-        accepted: "onartu behar da"
-        empty: "ezin da hutsik egon"
-        blank: "ezin da hutsik egon"
-        too_long: "luzeegia da (maximoa %{count} karaktere dira)"
-        too_short: "laburregia da (minimoa %{count} karaktere dira)"
-        wrong_length: "luzera ezegokia da (%{count} karakter izan beharko litzake)"
-        taken: "dagoeneko hartuta dago"
-        not_a_number: "ez da zenbaki bat"
-        not_a_date: "ez da baliozko data"
-        greater_than: "%{count} baino handiagoa izan behar du"
-        greater_than_or_equal_to: "%{count} edo handiagoa izan behar du"
-        equal_to: "%{count} izan behar du"
-        less_than: "%{count} baino gutxiago izan behar du"
-        less_than_or_equal_to: "%{count} edo gutxiago izan behar du"
-        odd: "bakoitia izan behar du"
-        even: "bikoitia izan behar du"
-        greater_than_start_date: "hasiera data baino handiagoa izan behar du"
-        not_same_project: "ez dago proiektu berdinean"
-        circular_dependency: "Erlazio honek mendekotasun zirkular bat sortuko luke"
-        cant_link_an_issue_with_a_descendant: "Zeregin bat ezin da bere azpiataza batekin estekatu."
-
-  actionview_instancetag_blank_option: Hautatu mesedez
-  
-  general_text_No: 'Ez'
-  general_text_Yes: 'Bai'
-  general_text_no: 'ez'
-  general_text_yes: 'bai'
-  general_lang_name: 'Euskara'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: Kontua ongi eguneratu da.
-  notice_account_invalid_creditentials: Erabiltzaile edo pasahitz ezegokia
-  notice_account_password_updated: Pasahitza ongi eguneratu da.
-  notice_account_wrong_password: Pasahitz ezegokia.
-  notice_account_register_done: Kontua ongi sortu da. Kontua gaitzeko klikatu epostan adierazi zaizun estekan.
-  notice_account_unknown_email: Erabiltzaile ezezaguna.
-  notice_can_t_change_password: Kontu honek kanpoko autentikazio bat erabiltzen du. Ezinezkoa da pasahitza aldatzea.
-  notice_account_lost_email_sent: Pasahitz berria aukeratzeko jarraibideak dituen eposta bat bidali zaizu.
-  notice_account_activated: Zure kontua gaituta dago. Orain saioa has dezakezu
-  notice_successful_create: Sortze arrakastatsua.
-  notice_successful_update: Eguneratze arrakastatsua.
-  notice_successful_delete: Ezabaketa arrakastatsua.
-  notice_successful_connection: Konexio arrakastatsua.
-  notice_file_not_found: Atzitu nahi duzun orria ez da exisitzen edo ezabatua izan da.
-  notice_locking_conflict: Beste erabiltzaile batek datuak eguneratu ditu.
-  notice_not_authorized: Ez duzu orri hau atzitzeko baimenik.
-  notice_email_sent: "%{value} helbidera eposta bat bidali da"
-  notice_email_error: "Errorea eposta bidaltzean (%{value})"
-  notice_feeds_access_key_reseted: Zure RSS atzipen giltza berrezarri da.
-  notice_api_access_key_reseted: Zure API atzipen giltza berrezarri da.
-  notice_failed_to_save_issues: "Hautatutako %{total} zereginetatik %{count} ezin izan dira konpondu: %{ids}."
-  notice_no_issue_selected: "Ez da zereginik hautatu! Mesedez, editatu nahi dituzun arazoak markatu."
-  notice_account_pending: "Zure kontua sortu da, orain kudeatzailearen onarpenaren zain dago."
-  notice_default_data_loaded: Lehenetsitako konfigurazioa ongi kargatu da.
-  notice_unable_delete_version: Ezin da bertsioa ezabatu.
-  notice_issue_done_ratios_updated: Burututako zereginen erlazioa eguneratu da.
-  
-  error_can_t_load_default_data: "Ezin izan da lehenetsitako konfigurazioa kargatu: %{value}"
-  error_scm_not_found: "Sarrera edo berrikuspena ez da biltegian topatu."
-  error_scm_command_failed: "Errorea gertatu da biltegia atzitzean: %{value}"
-  error_scm_annotate: "Sarrera ez da existitzen edo ezin da anotatu."
-  error_issue_not_found_in_project: 'Zeregina ez da topatu edo ez da proiektu honetakoa'
-  error_no_tracker_in_project: 'Proiektu honek ez du aztarnaririk esleituta. Mesedez egiaztatu Proiektuaren ezarpenak.'
-  error_no_default_issue_status: 'Zereginek ez dute lehenetsitako egoerarik.  Mesedez egiaztatu zure konfigurazioa ("Kudeaketa -> Arazoen egoerak" atalera joan).'
-  error_can_not_reopen_issue_on_closed_version: 'Itxitako bertsio batera esleitutako zereginak ezin dira berrireki'
-  error_can_not_archive_project: Proiektu hau ezin da artxibatu
-  error_issue_done_ratios_not_updated: "Burututako zereginen erlazioa ez da eguneratu."
-  error_workflow_copy_source: 'Mesedez hautatu iturburuko aztarnari edo rola'
-  error_workflow_copy_target: 'Mesedez hautatu helburuko aztarnari(ak) edo rola(k)'
-  
-  warning_attachments_not_saved: "%{count} fitxategi ezin izan d(ir)a gorde."
-  
-  mail_subject_lost_password: "Zure %{value} pasahitza"
-  mail_body_lost_password: 'Zure pasahitza aldatzeko hurrengo estekan klikatu:'
-  mail_subject_register: "Zure %{value} kontuaren gaitzea"
-  mail_body_register: 'Zure kontua gaitzeko hurrengo estekan klikatu:'
-  mail_body_account_information_external: "Zure %{value} kontua erabil dezakezu saioa hasteko."
-  mail_body_account_information: Zure kontuaren informazioa
-  mail_subject_account_activation_request: "%{value} kontu gaitzeko eskaera"
-  mail_body_account_activation_request: "Erabiltzaile berri bat (%{value}) erregistratu da. Kontua zure onarpenaren zain dago:"
-  mail_subject_reminder: "%{count} arazo hurrengo %{days} egunetan amaitzen d(ir)a"
-  mail_body_reminder: "Zuri esleituta dauden %{count} arazo hurrengo %{days} egunetan amaitzen d(ir)a:"
-  mail_subject_wiki_content_added: "'%{id}' wiki orria gehitu da"
-  mail_body_wiki_content_added: "%{author}-(e)k '%{id}' wiki orria gehitu du."
-  mail_subject_wiki_content_updated: "'%{id}' wiki orria eguneratu da"
-  mail_body_wiki_content_updated: "%{author}-(e)k '%{id}' wiki orria eguneratu du."
-  
-  gui_validation_error: akats 1
-  gui_validation_error_plural: "%{count} akats"
-  
-  field_name: Izena
-  field_description: Deskribapena
-  field_summary: Laburpena
-  field_is_required: Beharrezkoa
-  field_firstname: Izena
-  field_lastname: Abizenak
-  field_mail: Eposta
-  field_filename: Fitxategia
-  field_filesize: Tamaina
-  field_downloads: Deskargak
-  field_author: Egilea
-  field_created_on: Sortuta
-  field_updated_on: Eguneratuta
-  field_field_format: Formatua
-  field_is_for_all: Proiektu guztietarako
-  field_possible_values: Balio posibleak
-  field_regexp: Expresio erregularra
-  field_min_length: Luzera minimoa
-  field_max_length: Luzera maxioma
-  field_value: Balioa
-  field_category: Kategoria
-  field_title: Izenburua
-  field_project: Proiektua
-  field_issue: Zeregina
-  field_status: Egoera
-  field_notes: Oharrak
-  field_is_closed: Itxitako arazoa
-  field_is_default: Lehenetsitako balioa
-  field_tracker: Aztarnaria
-  field_subject: Gaia
-  field_due_date: Amaiera data
-  field_assigned_to: Esleituta
-  field_priority: Lehentasuna
-  field_fixed_version: Helburuko bertsioa
-  field_user: Erabiltzilea
-  field_role: Rola
-  field_homepage: Orri nagusia
-  field_is_public: Publikoa
-  field_parent: "Honen azpiproiektua:"
-  field_is_in_chlog: Zereginak aldaketa egunkarian ikusten dira
-  field_is_in_roadmap: Arazoak ibilbide-mapan erakutsi
-  field_login: Erabiltzaile izena
-  field_mail_notification: Eposta jakinarazpenak
-  field_admin: Kudeatzailea
-  field_last_login_on: Azken konexioa
-  field_language: Hizkuntza
-  field_effective_date: Data
-  field_password: Pasahitza
-  field_new_password: Pasahitz berria
-  field_password_confirmation: Berrespena
-  field_version: Bertsioa
-  field_type: Mota
-  field_host: Ostalaria
-  field_port: Portua
-  field_account: Kontua
-  field_base_dn: Base DN
-  field_attr_login: Erabiltzaile atributua
-  field_attr_firstname: Izena atributua
-  field_attr_lastname: Abizenak atributua
-  field_attr_mail: Eposta atributua
-  field_onthefly: Zuzeneko erabiltzaile sorrera
-  field_start_date: Hasiera
-  field_done_ratio: Egindako %
-  field_auth_source: Autentikazio modua
-  field_hide_mail: Nire eposta helbidea ezkutatu
-  field_comments: Iruzkina
-  field_url: URL
-  field_start_page: Hasierako orria
-  field_subproject: Azpiproiektua
-  field_hours: Ordu
-  field_activity: Jarduera
-  field_spent_on: Data
-  field_identifier: Identifikatzailea
-  field_is_filter: Iragazki moduan erabilita
-  field_issue_to: Erlazionatutako zereginak
-  field_delay: Atzerapena
-  field_assignable: Arazoak rol honetara esleitu daitezke
-  field_redirect_existing_links: Existitzen diren estekak berbideratu
-  field_estimated_hours: Estimatutako denbora
-  field_column_names: Zutabeak
-  field_time_zone: Ordu zonaldea
-  field_searchable: Bilagarria
-  field_default_value: Lehenetsitako balioa
-  field_comments_sorting: Iruzkinak erakutsi
-  field_parent_title: Orri gurasoa
-  field_editable: Editagarria
-  field_watcher: Behatzailea
-  field_identity_url: OpenID URLa
-  field_content: Edukia
-  field_group_by: Emaitzak honegatik taldekatu
-  field_sharing: Partekatzea
-
-  setting_app_title: Aplikazioaren izenburua
-  setting_app_subtitle: Aplikazioaren azpizenburua
-  setting_welcome_text: Ongietorriko testua
-  setting_default_language: Lehenetsitako hizkuntza
-  setting_login_required: Autentikazioa derrigorrezkoa
-  setting_self_registration: Norberak erregistratu
-  setting_attachment_max_size: Eranskinen tamaina max.
-  setting_issues_export_limit: Zereginen esportatze limitea
-  setting_mail_from: Igorlearen eposta helbidea
-  setting_bcc_recipients: Hartzaileak ezkutuko kopian (bcc)
-  setting_plain_text_mail: Testu soileko epostak (HTML-rik ez)
-  setting_host_name: Ostalari izena eta bidea
-  setting_text_formatting: Testu formatua
-  setting_wiki_compression: Wikiaren historia konprimitu
-  setting_feeds_limit: Jarioaren edukiera limitea
-  setting_default_projects_public: Proiektu berriak defektuz publikoak dira
-  setting_autofetch_changesets: Commit-ak automatikoki hartu
-  setting_sys_api_enabled: Biltegien kudeaketarako WS gaitu
-  setting_commit_ref_keywords: Erreferentzien gako-hitzak
-  setting_commit_fix_keywords: Konpontze gako-hitzak
-  setting_autologin: Saioa automatikoki hasi
-  setting_date_format: Data formatua
-  setting_time_format: Ordu formatua
-  setting_cross_project_issue_relations: Zereginak proiektuen artean erlazionatzea baimendu
-  setting_issue_list_default_columns: Zereginen zerrendan defektuz ikusten diren zutabeak
-  setting_emails_footer: Eposten oina
-  setting_protocol: Protokoloa
-  setting_per_page_options: Orriko objektuen aukerak
-  setting_user_format: Erabiltzaileak erakusteko formatua
-  setting_activity_days_default: Proiektuen jardueran erakusteko egunak
-  setting_display_subprojects_issues: Azpiproiektuen zereginak proiektu nagusian erakutsi defektuz
-  setting_enabled_scm: Gaitutako IKKak
-  setting_mail_handler_body_delimiters: "Lerro hauteko baten ondoren epostak moztu"
-  setting_mail_handler_api_enabled: Sarrerako epostentzako WS gaitu
-  setting_mail_handler_api_key: API giltza
-  setting_sequential_project_identifiers: Proiektuen identifikadore sekuentzialak sortu
-  setting_gravatar_enabled: Erabili Gravatar erabiltzaile ikonoak
-  setting_gravatar_default: Lehenetsitako Gravatar irudia
-  setting_diff_max_lines_displayed: Erakutsiko diren diff lerro kopuru maximoa
-  setting_file_max_size_displayed: Barnean erakuzten diren testu fitxategien tamaina maximoa
-  setting_repository_log_display_limit: Egunkari fitxategian erakutsiko diren berrikuspen kopuru maximoa.
-  setting_openid: Baimendu OpenID saio hasiera eta erregistatzea
-  setting_password_min_length: Pasahitzen luzera minimoa
-  setting_new_project_user_role_id: Proiektu berriak sortzerakoan kudeatzaile ez diren erabiltzaileei esleitutako rola
-  setting_default_projects_modules: Proiektu berrientzako defektuz gaitutako moduluak
-  setting_issue_done_ratio: "Zereginen burututako tasa kalkulatzean erabili:"
-  setting_issue_done_ratio_issue_field: Zeregin eremua erabili
-  setting_issue_done_ratio_issue_status: Zeregin egoera erabili
-  setting_start_of_week: "Egutegiak noiz hasi:"
-  setting_rest_api_enabled: Gaitu REST web zerbitzua
-  
-  permission_add_project: Proiektua sortu
-  permission_add_subprojects: Azpiproiektuak sortu
-  permission_edit_project: Proiektua editatu
-  permission_select_project_modules: Proiektuaren moduluak hautatu
-  permission_manage_members: Kideak kudeatu
-  permission_manage_versions: Bertsioak kudeatu
-  permission_manage_categories: Arazoen kategoriak kudeatu
-  permission_view_issues: Zereginak ikusi
-  permission_add_issues: Zereginak gehitu
-  permission_edit_issues: Zereginak aldatu
-  permission_manage_issue_relations: Zereginen erlazioak kudeatu
-  permission_add_issue_notes: Oharrak gehitu
-  permission_edit_issue_notes: Oharrak aldatu
-  permission_edit_own_issue_notes: Nork bere oharrak aldatu
-  permission_move_issues: Zereginak mugitu
-  permission_delete_issues: Zereginak ezabatu
-  permission_manage_public_queries: Galdera publikoak kudeatu
-  permission_save_queries: Galderak gorde
-  permission_view_gantt: Gantt grafikoa ikusi
-  permission_view_calendar: Egutegia ikusi
-  permission_view_issue_watchers: Behatzaileen zerrenda ikusi
-  permission_add_issue_watchers: Behatzaileak gehitu
-  permission_delete_issue_watchers: Behatzaileak ezabatu
-  permission_log_time: Igarotako denbora erregistratu
-  permission_view_time_entries: Igarotako denbora ikusi
-  permission_edit_time_entries: Denbora egunkariak editatu
-  permission_edit_own_time_entries: Nork bere denbora egunkariak editatu
-  permission_manage_news: Berriak kudeatu
-  permission_comment_news: Berrien iruzkinak egin
-  permission_manage_documents: Dokumentuak kudeatu
-  permission_view_documents: Dokumentuak ikusi
-  permission_manage_files: Fitxategiak kudeatu
-  permission_view_files: Fitxategiak ikusi
-  permission_manage_wiki: Wikia kudeatu
-  permission_rename_wiki_pages: Wiki orriak berrizendatu
-  permission_delete_wiki_pages: Wiki orriak ezabatu
-  permission_view_wiki_pages: Wikia ikusi
-  permission_view_wiki_edits: Wikiaren historia ikusi
-  permission_edit_wiki_pages: Wiki orriak editatu
-  permission_delete_wiki_pages_attachments: Eranskinak ezabatu
-  permission_protect_wiki_pages: Wiki orriak babestu
-  permission_manage_repository: Biltegiak kudeatu
-  permission_browse_repository: Biltegia arakatu
-  permission_view_changesets: Aldaketak ikusi
-  permission_commit_access: Commit atzipena
-  permission_manage_boards: Foroak kudeatu
-  permission_view_messages: Mezuak ikusi
-  permission_add_messages: Mezuak bidali
-  permission_edit_messages: Mezuak aldatu
-  permission_edit_own_messages: Nork bere mezuak aldatu
-  permission_delete_messages: Mezuak ezabatu
-  permission_delete_own_messages: Nork bere mezuak ezabatu
-  
-  project_module_issue_tracking: Zereginen jarraipena
-  project_module_time_tracking: Denbora jarraipena
-  project_module_news: Berriak
-  project_module_documents: Dokumentuak
-  project_module_files: Fitxategiak
-  project_module_wiki: Wiki
-  project_module_repository: Biltegia
-  project_module_boards: Foroak
-  
-  label_user: Erabiltzailea
-  label_user_plural: Erabiltzaileak
-  label_user_new: Erabiltzaile berria
-  label_user_anonymous: Ezezaguna
-  label_project: Proiektua
-  label_project_new: Proiektu berria
-  label_project_plural: Proiektuak
-  label_x_projects:
-    zero:  proiekturik ez
-    one:   proiektu bat
-    other: "%{count} proiektu"
-  label_project_all: Proiektu guztiak
-  label_project_latest: Azken proiektuak
-  label_issue: Zeregina
-  label_issue_new: Zeregin berria
-  label_issue_plural: Zereginak
-  label_issue_view_all: Zeregin guztiak ikusi
-  label_issues_by: "Zereginak honengatik: %{value}"
-  label_issue_added: Zeregina gehituta
-  label_issue_updated: Zeregina eguneratuta
-  label_document: Dokumentua
-  label_document_new: Dokumentu berria
-  label_document_plural: Dokumentuak
-  label_document_added: Dokumentua gehituta
-  label_role: Rola
-  label_role_plural: Rolak
-  label_role_new: Rol berria
-  label_role_and_permissions: Rolak eta baimenak
-  label_member: Kidea
-  label_member_new: Kide berria
-  label_member_plural: Kideak
-  label_tracker: Aztarnaria
-  label_tracker_plural: Aztarnariak
-  label_tracker_new: Aztarnari berria
-  label_workflow: Lan-fluxua
-  label_issue_status: Zeregin egoera
-  label_issue_status_plural: Zeregin egoerak
-  label_issue_status_new: Egoera berria
-  label_issue_category: Zeregin kategoria
-  label_issue_category_plural: Zeregin kategoriak
-  label_issue_category_new: Kategoria berria
-  label_custom_field: Eremu pertsonalizatua
-  label_custom_field_plural: Eremu pertsonalizatuak
-  label_custom_field_new: Eremu pertsonalizatu berria
-  label_enumerations: Enumerazioak
-  label_enumeration_new: Balio berria
-  label_information: Informazioa
-  label_information_plural: Informazioa
-  label_please_login: Saioa hasi mesedez
-  label_register: Erregistratu
-  label_login_with_open_id_option: edo OpenID-rekin saioa hasi
-  label_password_lost: Pasahitza galduta
-  label_home: Hasiera
-  label_my_page: Nire orria
-  label_my_account: Nire kontua
-  label_my_projects: Nire proiektuak
-  label_administration: Kudeaketa
-  label_login: Saioa hasi
-  label_logout: Saioa bukatu
-  label_help: Laguntza
-  label_reported_issues: Berri emandako zereginak
-  label_assigned_to_me_issues: Niri esleitutako arazoak
-  label_last_login: Azken konexioa
-  label_registered_on: Noiz erregistratuta
-  label_activity: Jarduerak
-  label_overall_activity: Jarduera guztiak
-  label_user_activity: "%{value}-(r)en jarduerak"
-  label_new: Berria
-  label_logged_as: "Sartutako erabiltzailea:"
-  label_environment: Ingurune
-  label_authentication: Autentikazioa
-  label_auth_source: Autentikazio modua
-  label_auth_source_new: Autentikazio modu berria
-  label_auth_source_plural: Autentikazio moduak
-  label_subproject_plural: Azpiproiektuak
-  label_subproject_new: Azpiproiektu berria
-  label_and_its_subprojects: "%{value} eta bere azpiproiektuak"
-  label_min_max_length: Luzera min - max
-  label_list: Zerrenda
-  label_date: Data
-  label_integer: Osokoa
-  label_float: Koma higikorrekoa
-  label_boolean: Boolearra
-  label_string: Testua
-  label_text: Testu luzea
-  label_attribute: Atributua
-  label_attribute_plural: Atributuak
-  label_download: "Deskarga %{count}"
-  label_download_plural: "%{count} Deskarga"
-  label_no_data: Ez dago erakusteko daturik
-  label_change_status: Egoera aldatu
-  label_history: Historikoa
-  label_attachment: Fitxategia
-  label_attachment_new: Fitxategi berria
-  label_attachment_delete: Fitxategia ezabatu
-  label_attachment_plural: Fitxategiak
-  label_file_added: Fitxategia gehituta
-  label_report: Berri ematea
-  label_report_plural: Berri emateak
-  label_news: Berria
-  label_news_new: Berria gehitu
-  label_news_plural: Berriak
-  label_news_latest: Azken berriak
-  label_news_view_all: Berri guztiak ikusi
-  label_news_added: Berria gehituta
-  label_change_log: Aldaketa egunkaria
-  label_settings: Ezarpenak
-  label_overview: Gainbegirada
-  label_version: Bertsioa
-  label_version_new: Bertsio berria
-  label_version_plural: Bertsioak
-  label_close_versions: Burututako bertsioak itxi
-  label_confirmation: Baieztapena
-  label_export_to: 'Eskuragarri baita:'
-  label_read: Irakurri...
-  label_public_projects: Proiektu publikoak
-  label_open_issues: irekita
-  label_open_issues_plural: irekiak
-  label_closed_issues: itxita
-  label_closed_issues_plural: itxiak
-  label_x_open_issues_abbr_on_total:
-    zero:  0 irekita / %{total}
-    one:   1 irekita / %{total}
-    other: "%{count} irekiak / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 irekita
-    one:   1 irekita
-    other: "%{count} irekiak"
-  label_x_closed_issues_abbr:
-    zero:  0 itxita
-    one:   1 itxita
-    other: "%{count} itxiak"
-  label_total: Guztira
-  label_permissions: Baimenak
-  label_current_status: Uneko egoera
-  label_new_statuses_allowed: Baimendutako egoera berriak
-  label_all: guztiak
-  label_none: ezer
-  label_nobody: inor
-  label_next: Hurrengoa
-  label_previous: Aurrekoak
-  label_used_by: Erabilita
-  label_details: Xehetasunak
-  label_add_note: Oharra gehitu
-  label_per_page: Orriko
-  label_calendar: Egutegia
-  label_months_from: hilabete noiztik
-  label_gantt: Gantt
-  label_internal: Barnekoa
-  label_last_changes: "azken %{count} aldaketak"
-  label_change_view_all: Aldaketa guztiak ikusi
-  label_personalize_page: Orri hau pertsonalizatu
-  label_comment: Iruzkin
-  label_comment_plural: Iruzkinak
-  label_x_comments:
-    zero: iruzkinik ez
-    one: iruzkin 1
-    other: "%{count} iruzkin"
-  label_comment_add: Iruzkina gehitu
-  label_comment_added: Iruzkina gehituta
-  label_comment_delete: Iruzkinak ezabatu
-  label_query: Galdera pertsonalizatua
-  label_query_plural: Pertsonalizatutako galderak
-  label_query_new: Galdera berria
-  label_filter_add: Iragazkia gehitu
-  label_filter_plural: Iragazkiak
-  label_equals: da
-  label_not_equals: ez da
-  label_in_less_than: baino gutxiagotan
-  label_in_more_than: baino gehiagotan
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: hauetan
-  label_today: gaur
-  label_all_time: denbora guztia
-  label_yesterday: atzo
-  label_this_week: aste honetan
-  label_last_week: pasadan astean
-  label_last_n_days: "azken %{count} egunetan"
-  label_this_month: hilabete hau
-  label_last_month: pasadan hilabetea
-  label_this_year: urte hau
-  label_date_range: Data tartea
-  label_less_than_ago: egun hauek baino gutxiago
-  label_more_than_ago: egun hauek baino gehiago
-  label_ago: orain dela
-  label_contains: dauka
-  label_not_contains: ez dauka
-  label_day_plural: egun
-  label_repository: Biltegia
-  label_repository_plural: Biltegiak
-  label_browse: Arakatu
-  label_modification: "aldaketa %{count}"
-  label_modification_plural: "%{count} aldaketa"
-  label_branch: Adarra
-  label_tag: Etiketa 
-  label_revision: Berrikuspena
-  label_revision_plural: Berrikuspenak
-  label_revision_id: "%{value} berrikuspen"
-  label_associated_revisions: Elkartutako berrikuspenak
-  label_added: gehituta
-  label_modified: aldatuta
-  label_copied: kopiatuta
-  label_renamed: berrizendatuta
-  label_deleted: ezabatuta
-  label_latest_revision: Azken berrikuspena
-  label_latest_revision_plural: Azken berrikuspenak
-  label_view_revisions: Berrikuspenak ikusi
-  label_view_all_revisions: Berrikuspen guztiak ikusi
-  label_max_size: Tamaina maximoa
-  label_sort_highest: Goraino mugitu
-  label_sort_higher: Gora mugitu
-  label_sort_lower: Behera mugitu
-  label_sort_lowest: Beheraino mugitu
-  label_roadmap: Ibilbide-mapa
-  label_roadmap_due_in: "Epea: %{value}"
-  label_roadmap_overdue: "%{value} berandu"
-  label_roadmap_no_issues: Ez dago zereginik bertsio honetan
-  label_search: Bilatu
-  label_result_plural: Emaitzak
-  label_all_words: hitz guztiak
-  label_wiki: Wikia
-  label_wiki_edit: Wiki edizioa
-  label_wiki_edit_plural: Wiki edizioak
-  label_wiki_page: Wiki orria
-  label_wiki_page_plural: Wiki orriak
-  label_index_by_title: Izenburuaren araberako indizea
-  label_index_by_date: Dataren araberako indizea
-  label_current_version: Uneko bertsioa
-  label_preview: Aurreikusi
-  label_feed_plural: Jarioak
-  label_changes_details: Aldaketa guztien xehetasunak
-  label_issue_tracking: Zeregin jarraipena
-  label_spent_time: Igarotako denbora
-  label_f_hour: "ordu %{value}"
-  label_f_hour_plural: "%{value} ordu"
-  label_time_tracking: Denbora jarraipena
-  label_change_plural: Aldaketak
-  label_statistics: Estatistikak
-  label_commits_per_month: Commit-ak hilabeteka
-  label_commits_per_author: Commit-ak egileka
-  label_view_diff: Ezberdintasunak ikusi
-  label_diff_inline: barnean
-  label_diff_side_by_side: aldez alde
-  label_options: Aukerak
-  label_copy_workflow_from: Kopiatu workflow-a hemendik
-  label_permissions_report: Baimenen txostena
-  label_watched_issues: Behatutako zereginak
-  label_related_issues: Erlazionatutako zereginak
-  label_applied_status: Aplikatutako egoera
-  label_loading: Kargatzen...
-  label_relation_new: Erlazio berria
-  label_relation_delete: Erlazioa ezabatu
-  label_relates_to: erlazionatuta dago
-  label_duplicates: bikoizten du
-  label_duplicated_by: honek bikoiztuta
-  label_blocks: blokeatzen du
-  label_blocked_by: honek blokeatuta
-  label_precedes: aurretik doa
-  label_follows: jarraitzen du
-  label_end_to_start: bukaeratik hasierara
-  label_end_to_end: bukaeratik bukaerara
-  label_start_to_start: hasieratik hasierhasieratik bukaerara
-  label_start_to_end: hasieratik bukaerara
-  label_stay_logged_in: Saioa mantendu
-  label_disabled: ezgaituta
-  label_show_completed_versions: Bukatutako bertsioak ikusi
-  label_me: ni
-  label_board: Foroa
-  label_board_new: Foro berria
-  label_board_plural: Foroak
-  label_topic_plural: Gaiak
-  label_message_plural: Mezuak
-  label_message_last: Azken mezua
-  label_message_new: Mezu berria
-  label_message_posted: Mezua gehituta
-  label_reply_plural: Erantzunak
-  label_send_information: Erabiltzaileai kontuaren informazioa bidali
-  label_year: Urtea
-  label_month: Hilabetea
-  label_week: Astea
-  label_date_from: Nork
-  label_date_to: Nori
-  label_language_based: Erabiltzailearen hizkuntzaren arabera
-  label_sort_by: "Ordenazioa: %{value}"
-  label_send_test_email: Frogako mezua bidali
-  label_feeds_access_key: RSS atzipen giltza
-  label_missing_feeds_access_key: RSS atzipen giltza falta da
-  label_feeds_access_key_created_on: "RSS atzipen giltza orain dela %{value} sortuta"
-  label_module_plural: Moduluak
-  label_added_time_by: "%{author}, orain dela %{age} gehituta"
-  label_updated_time_by: "%{author}, orain dela %{age} eguneratuta"
-  label_updated_time: "Orain dela %{value} eguneratuta"
-  label_jump_to_a_project: Joan proiektura...
-  label_file_plural: Fitxategiak
-  label_changeset_plural: Aldaketak
-  label_default_columns: Lehenetsitako zutabeak
-  label_no_change_option: (Aldaketarik ez)
-  label_bulk_edit_selected_issues: Hautatutako zereginak batera editatu
-  label_theme: Itxura
-  label_default: Lehenetsia
-  label_search_titles_only: Izenburuetan bakarrik bilatu
-  label_user_mail_option_all: "Nire proiektu guztietako gertakari guztientzat"
-  label_user_mail_option_selected: "Hautatutako proiektuetako edozein gertakarientzat..."
-  label_user_mail_no_self_notified: "Ez dut nik egiten ditudan aldeketen jakinarazpenik jaso nahi"
-  label_registration_activation_by_email: kontuak epostaz gaitu
-  label_registration_manual_activation: kontuak eskuz gaitu
-  label_registration_automatic_activation: kontuak automatikoki gaitu
-  label_display_per_page: "Orriko: %{value}"
-  label_age: Adina
-  label_change_properties: Propietateak aldatu
-  label_general: Orokorra
-  label_more: Gehiago
-  label_scm: IKK
-  label_plugins: Pluginak
-  label_ldap_authentication: LDAP autentikazioa
-  label_downloads_abbr: Desk.
-  label_optional_description: Aukerako deskribapena
-  label_add_another_file: Beste fitxategia gehitu
-  label_preferences: Hobespenak
-  label_chronological_order: Orden kronologikoan
-  label_reverse_chronological_order: Alderantzizko orden kronologikoan
-  label_planning: Planifikazioa
-  label_incoming_emails: Sarrerako epostak
-  label_generate_key: Giltza sortu
-  label_issue_watchers: Behatzaileak
-  label_example: Adibidea
-  label_display: Bistaratzea
-  label_sort: Ordenatu
-  label_ascending: Gorantz
-  label_descending: Beherantz
-  label_date_from_to: "%{start}-tik %{end}-ra"
-  label_wiki_content_added: Wiki orria gehituta
-  label_wiki_content_updated: Wiki orria eguneratuta
-  label_group: Taldea
-  label_group_plural: Taldeak
-  label_group_new: Talde berria
-  label_time_entry_plural: Igarotako denbora
-  label_version_sharing_none: Ez partekatuta
-  label_version_sharing_descendants: Azpiproiektuekin
-  label_version_sharing_hierarchy: Proiektu Hierarkiarekin
-  label_version_sharing_tree: Proiektu zuhaitzarekin
-  label_version_sharing_system: Proiektu guztiekin
-  label_update_issue_done_ratios: Zereginen burututako erlazioa eguneratu
-  label_copy_source: Iturburua
-  label_copy_target: Helburua
-  label_copy_same_as_target: Helburuaren berdina
-  label_display_used_statuses_only: Aztarnari honetan erabiltzen diren egoerak bakarrik erakutsi
-  label_api_access_key: API atzipen giltza
-  label_missing_api_access_key: API atzipen giltza falta da
-  label_api_access_key_created_on: "API atzipen giltza sortuta orain dela %{value}"
-  
-  button_login: Saioa hasi
-  button_submit: Bidali
-  button_save: Gorde
-  button_check_all: Guztiak markatu
-  button_uncheck_all: Guztiak desmarkatu
-  button_delete: Ezabatu
-  button_create: Sortu
-  button_create_and_continue: Sortu eta jarraitu
-  button_test: Frogatu
-  button_edit: Editatu
-  button_add: Gehitu
-  button_change: Aldatu
-  button_apply: Aplikatu
-  button_clear: Garbitu
-  button_lock: Blokeatu
-  button_unlock: Desblokeatu
-  button_download: Deskargatu
-  button_list: Zerrenda
-  button_view: Ikusi
-  button_move: Mugitu
-  button_move_and_follow: Mugitu eta jarraitu
-  button_back: Atzera
-  button_cancel: Ezeztatu
-  button_activate: Gahitu
-  button_sort: Ordenatu
-  button_log_time: Denbora erregistratu
-  button_rollback: Itzuli bertsio honetara
-  button_watch: Behatu
-  button_unwatch: Behatzen utzi
-  button_reply: Erantzun
-  button_archive: Artxibatu
-  button_unarchive: Desartxibatu
-  button_reset: Berrezarri
-  button_rename: Berrizendatu
-  button_change_password: Pasahitza aldatu
-  button_copy: Kopiatu
-  button_copy_and_follow: Kopiatu eta jarraitu
-  button_annotate: Anotatu
-  button_update: Eguneratu
-  button_configure: Konfiguratu
-  button_quote: Aipatu
-  button_duplicate: Bikoiztu
-  button_show: Ikusi
-  
-  status_active: gaituta
-  status_registered: izena emanda
-  status_locked: blokeatuta
-  
-  version_status_open: irekita
-  version_status_locked: blokeatuta
-  version_status_closed: itxita
-
-  field_active: Gaituta
-  
-  text_select_mail_notifications: Jakinarazpenak zein ekintzetarako bidaliko diren hautatu.
-  text_regexp_info: adib. ^[A-Z0-9]+$
-  text_min_max_length_info: 0k mugarik gabe esan nahi du
-  text_project_destroy_confirmation: Ziur zaude proiektu hau eta erlazionatutako datu guztiak ezabatu nahi dituzula?
-  text_subprojects_destroy_warning: "%{value} azpiproiektuak ere ezabatuko dira."
-  text_workflow_edit: Hautatu rola eta aztarnaria workflow-a editatzeko
-  text_are_you_sure: Ziur zaude?
-  text_journal_changed: "%{label} %{old}-(e)tik %{new}-(e)ra aldatuta"
-  text_journal_set_to: "%{label}-k %{value} balioa hartu du"
-  text_journal_deleted: "%{label} ezabatuta (%{old})"
-  text_journal_added: "%{label} %{value} gehituta"
-  text_tip_issue_begin_day: gaur hasten diren zereginak
-  text_tip_issue_end_day: gaur bukatzen diren zereginak
-  text_tip_issue_begin_end_day: gaur hasi eta bukatzen diren zereginak
-  text_project_identifier_info: 'Letra xeheak (a-z), zenbakiak eta marrak erabil daitezke bakarrik.<br />Gorde eta gero identifikadorea ezin da aldatu.'
-  text_caracters_maximum: "%{count} karaktere gehienez."
-  text_caracters_minimum: "Gutxienez %{count} karaktereetako luzerakoa izan behar du."
-  text_length_between: "Luzera %{min} eta %{max} karaktereen artekoa."
-  text_tracker_no_workflow: Ez da workflow-rik definitu aztarnari honentzako
-  text_unallowed_characters: Debekatutako karaktereak
-  text_comma_separated: Balio anitz izan daitezke (komaz banatuta).
-  text_line_separated: Balio anitz izan daitezke (balio bakoitza lerro batean).
-  text_issues_ref_in_commit_messages: Commit-en mezuetan zereginak erlazionatu eta konpontzen
-  text_issue_added: "%{id} zeregina %{author}-(e)k jakinarazi du."
-  text_issue_updated: "%{id} zeregina %{author}-(e)k eguneratu du."
-  text_wiki_destroy_confirmation: Ziur zaude wiki hau eta bere eduki guztiak ezabatu nahi dituzula?
-  text_issue_category_destroy_question: "Zeregin batzuk (%{count}) kategoria honetara esleituta daude. Zer egin nahi duzu?"
-  text_issue_category_destroy_assignments: Kategoria esleipenak kendu
-  text_issue_category_reassign_to: Zereginak kategoria honetara esleitu
-  text_user_mail_option: "Hautatu gabeko proiektuetan, behatzen edo parte hartzen duzun gauzei buruzko jakinarazpenak jasoko dituzu (adib. zu egile zaren edo esleituta dituzun zereginak)."
-  text_no_configuration_data: "Rolak, aztarnariak, zeregin egoerak eta workflow-ak ez dira oraindik konfiguratu.\nOso gomendagarria de lehenetsitako kkonfigurazioa kargatzea. Kargatu eta gero aldatu ahalko duzu."
-  text_load_default_configuration: Lehenetsitako konfigurazioa kargatu
-  text_status_changed_by_changeset: "%{value} aldaketan aplikatuta."
-  text_issues_destroy_confirmation: 'Ziur zaude hautatutako zeregina(k) ezabatu nahi dituzula?'
-  text_select_project_modules: 'Hautatu proiektu honetan gaitu behar diren moduluak:'
-  text_default_administrator_account_changed: Lehenetsitako kudeatzaile kontua aldatuta
-  text_file_repository_writable: Eranskinen direktorioan idatz daiteke
-  text_plugin_assets_writable: Pluginen baliabideen direktorioan idatz daiteke
-  text_rmagick_available: RMagick eskuragarri (aukerazkoa)
-  text_destroy_time_entries_question: "%{hours} orduei buruz berri eman zen zuk ezabatzera zoazen zereginean. Zer egin nahi duzu?"
-  text_destroy_time_entries: Ezabatu berri emandako orduak
-  text_assign_time_entries_to_project: Berri emandako orduak proiektura esleitu
-  text_reassign_time_entries: 'Berri emandako orduak zeregin honetara esleitu:'
-  text_user_wrote: "%{value}-(e)k idatzi zuen:"
-  text_enumeration_destroy_question: "%{count} objetu balio honetara esleituta daude."
-  text_enumeration_category_reassign_to: 'Beste balio honetara esleitu:'
-  text_email_delivery_not_configured: "Eposta bidalketa ez dago konfiguratuta eta jakinarazpenak ezgaituta daude.\nKonfiguratu zure SMTP zerbitzaria config/configuration.yml-n eta aplikazioa berrabiarazi hauek gaitzeko."
-  text_repository_usernames_mapping: "Hautatu edo eguneratu Redmineko erabiltzailea biltegiko egunkarietan topatzen diren erabiltzaile izenekin erlazionatzeko.\nRedmine-n eta biltegian erabiltzaile izen edo eposta berdina duten erabiltzaileak automatikoki erlazionatzen dira."
-  text_diff_truncated: '... Diff hau moztua izan da erakus daitekeen tamaina maximoa gainditu duelako.'
-  text_custom_field_possible_values_info: 'Lerro bat balio bakoitzeko'
-  text_wiki_page_destroy_question: "Orri honek %{descendants} orri seme eta ondorengo ditu. Zer egin nahi duzu?"
-  text_wiki_page_nullify_children: "Orri semeak erro orri moduan mantendu"
-  text_wiki_page_destroy_children: "Orri semeak eta beraien ondorengo guztiak ezabatu"
-  text_wiki_page_reassign_children: "Orri semeak orri guraso honetara esleitu"
-  text_own_membership_delete_confirmation: "Zure baimen batzuk (edo guztiak) kentzera zoaz eta baliteke horren ondoren proiektu hau ezin editatzea.\n Ziur zaude jarraitu nahi duzula?"
-  
-  default_role_manager: Kudeatzailea
-  default_role_developer: Garatzailea
-  default_role_reporter: Berriemailea
-  default_tracker_bug: Errorea
-  default_tracker_feature: Eginbidea
-  default_tracker_support: Laguntza
-  default_issue_status_new: Berria
-  default_issue_status_in_progress: Lanean
-  default_issue_status_resolved: Ebatzita
-  default_issue_status_feedback: Berrelikadura
-  default_issue_status_closed: Itxita
-  default_issue_status_rejected: Baztertua
-  default_doc_category_user: Erabiltzaile dokumentazioa
-  default_doc_category_tech: Dokumentazio teknikoa
-  default_priority_low: Baxua
-  default_priority_normal: Normala
-  default_priority_high: Altua
-  default_priority_urgent: Larria
-  default_priority_immediate: Berehalakoa
-  default_activity_design: Diseinua
-  default_activity_development: Garapena
-  
-  enumeration_issue_priorities: Zeregin lehentasunak
-  enumeration_doc_categories: Dokumentu kategoriak
-  enumeration_activities: Jarduerak (denbora kontrola))
-  enumeration_system_activity: Sistemako Jarduera
-  label_board_sticky: Itsaskorra
-  label_board_locked: Blokeatuta
-  permission_export_wiki_pages: Wiki orriak esportatu
-  setting_cache_formatted_text: Formatudun testua katxeatu
-  permission_manage_project_activities: Proiektuaren jarduerak kudeatu
-  error_unable_delete_issue_status: Ezine da zereginaren egoera ezabatu
-  label_profile: Profila
-  permission_manage_subtasks: Azpiatazak kudeatu
-  field_parent_issue: Zeregin gurasoa
-  label_subtask_plural: Azpiatazak
-  label_project_copy_notifications: Proiektua kopiatzen den bitartean eposta jakinarazpenak bidali
-  error_can_not_delete_custom_field: Ezin da eremu pertsonalizatua ezabatu
-  error_unable_to_connect: Ezin da konektatu (%{value})
-  error_can_not_remove_role: Rol hau erabiltzen hari da eta ezin da ezabatu.
-  error_can_not_delete_tracker: Aztarnari honek zereginak ditu eta ezin da ezabatu.
-  field_principal: Ekintzaile
-  label_my_page_block: "Nire orriko blokea"
-  notice_failed_to_save_members: "Kidea(k) gordetzean errorea: %{errors}."
-  text_zoom_out: Zooma txikiagotu
-  text_zoom_in: Zooma handiagotu
-  notice_unable_delete_time_entry: "Ezin da hautatutako denbora erregistroa ezabatu."
-  label_overall_spent_time: Igarotako denbora guztira
-  field_time_entries: "Denbora erregistratu"
-  project_module_gantt: Gantt
-  project_module_calendar: Egutegia
-  button_edit_associated_wikipage: "Esleitutako wiki orria editatu: %{page_title}"
-  text_are_you_sure_with_children: "Zeregina eta azpi zeregin guztiak ezabatu?"
-  field_text: Testu eremua
-  label_user_mail_option_only_owner: "Jabea naizen gauzetarako barrarik"
-  setting_default_notification_option: "Lehenetsitako ohartarazpen aukera"
-  label_user_mail_option_only_my_events: "Behatzen ditudan edo partaide naizen gauzetarako bakarrik"
-  label_user_mail_option_only_assigned: "Niri esleitutako gauzentzat bakarrik"
-  label_user_mail_option_none: "Gertakaririk ez"
-  field_member_of_group: "Esleituta duenaren taldea"
-  field_assigned_to_role: "Esleituta duenaren rola"
-  notice_not_authorized_archived_project: "Atzitu nahi duzun proiektua artxibatua izan da."
-  label_principal_search: "Bilatu erabiltzaile edo taldea:"
-  label_user_search: "Erabiltzailea bilatu:"
-  field_visible: Ikusgai
-  setting_emails_header: "Eposten goiburua"
-  setting_commit_logtime_activity_id: "Erregistratutako denboraren jarduera"
-  text_time_logged_by_changeset: "%{value} aldaketan egindakoa."
-  setting_commit_logtime_enabled: "Erregistrutako denbora gaitu"
-  notice_gantt_chart_truncated: Grafikoa moztu da bistara daitekeen elementuen kopuru maximoa gainditu delako (%{max})
-  setting_gantt_items_limit: "Gantt grafikoan bistara daitekeen elementu kopuru maximoa"
-  field_warn_on_leaving_unsaved: Gorde gabeko testua duen orri batetik ateratzen naizenean ohartarazi
-  text_warn_on_leaving_unsaved: Uneko orritik joaten bazara gorde gabeko testua galduko da.
-  label_my_queries: Nire galdera pertsonalizatuak
-  text_journal_changed_no_detail: "%{label} eguneratuta"
-  label_news_comment_added: Berri batera iruzkina gehituta
-  button_expand_all: Guztia zabaldu
-  button_collapse_all: Guztia tolestu
-  label_additional_workflow_transitions_for_assignee: Erabiltzaileak esleitua duenean baimendutako transtsizio gehigarriak
-  label_additional_workflow_transitions_for_author: Erabiltzailea egilea denean baimendutako transtsizio gehigarriak
-  label_bulk_edit_selected_time_entries: Hautatutako denbora egunkariak batera editatu
-  text_time_entries_destroy_confirmation: Ziur zaude hautatutako denbora egunkariak ezabatu nahi dituzula?
-  label_role_anonymous: Ezezaguna
-  label_role_non_member: Ez kidea
-  label_issue_note_added: Oharra gehituta
-  label_issue_status_updated: Egoera eguneratuta
-  label_issue_priority_updated: Lehentasuna eguneratuta
-  label_issues_visibility_own: Erabiltzaileak sortu edo esleituta dituen zereginak
-  field_issues_visibility: Zeregin ikusgarritasuna
-  label_issues_visibility_all: Zeregin guztiak
-  permission_set_own_issues_private: Nork bere zereginak publiko edo pribatu jarri
-  field_is_private: Pribatu
-  permission_set_issues_private: Zereginak publiko edo pribatu jarri
-  label_issues_visibility_public: Pribatu ez diren zeregin guztiak
-  text_issues_destroy_descendants_confirmation: Honek %{count} azpiataza ezabatuko ditu baita ere.
-  field_commit_logs_encoding: Commit-en egunkarien kodetzea
-  field_scm_path_encoding: Bidearen kodeketa
-  text_scm_path_encoding_note: "Lehentsita: UTF-8"
-  field_path_to_repository: Biltegirako bidea
-  field_root_directory: Erro direktorioa
-  field_cvs_module: Modulua
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Biltegi locala (adib. /hgrepo, c:\hgrepo)
-  text_scm_command: Komandoa
-  text_scm_command_version: Bertsioa
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e3/e3717673d3341037068a46026d2f7990e0e1fb85.svn-base
--- a/.svn/pristine/e3/e3717673d3341037068a46026d2f7990e0e1fb85.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-.DS_Store
-test_app
-doc
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e3/e37759dea55d14e3086ea2b9ced5bbf696b3c056.svn-base
--- a/.svn/pristine/e3/e37759dea55d14e3086ea2b9ced5bbf696b3c056.svn-base
+++ /dev/null
@@ -1,56 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'wikis_controller'
-
-# Re-raise errors caught by the controller.
-class WikisController; def rescue_action(e) raise e end; end
-
-class WikisControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :wikis
-
-  def setup
-    @controller = WikisController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_create
-    @request.session[:user_id] = 1
-    assert_nil Project.find(3).wiki
-    post :edit, :id => 3, :wiki => { :start_page => 'Start page' }
-    assert_response :success
-    wiki = Project.find(3).wiki
-    assert_not_nil wiki
-    assert_equal 'Start page', wiki.start_page
-  end
-
-  def test_destroy
-    @request.session[:user_id] = 1
-    post :destroy, :id => 1, :confirm => 1
-    assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'ecookbook', :tab => 'wiki'
-    assert_nil Project.find(1).wiki
-  end
-
-  def test_not_found
-    @request.session[:user_id] = 1
-    post :destroy, :id => 999, :confirm => 1
-    assert_response 404
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e3/e383d141d18d0ab6640f2f0c195a246ce39b140f.svn-base
--- a/.svn/pristine/e3/e383d141d18d0ab6640f2f0c195a246ce39b140f.svn-base
+++ /dev/null
@@ -1,131 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class IssueStatusTest < ActiveSupport::TestCase
-  fixtures :issue_statuses, :issues, :roles, :trackers
-
-  def test_create
-    status = IssueStatus.new :name => "Assigned"
-    assert !status.save
-    # status name uniqueness
-    assert_equal 1, status.errors.count
-
-    status.name = "Test Status"
-    assert status.save
-    assert !status.is_default
-  end
-
-  def test_destroy
-    status = IssueStatus.find(3)
-    assert_difference 'IssueStatus.count', -1 do
-      assert status.destroy
-    end
-    assert_nil Workflow.first(:conditions => {:old_status_id => status.id})
-    assert_nil Workflow.first(:conditions => {:new_status_id => status.id})
-  end
-
-  def test_destroy_status_in_use
-    # Status assigned to an Issue
-    status = Issue.find(1).status
-    assert_raise(RuntimeError, "Can't delete status") { status.destroy }
-  end
-
-  def test_default
-    status = IssueStatus.default
-    assert_kind_of IssueStatus, status
-  end
-
-  def test_change_default
-    status = IssueStatus.find(2)
-    assert !status.is_default
-    status.is_default = true
-    assert status.save
-    status.reload
-
-    assert_equal status, IssueStatus.default
-    assert !IssueStatus.find(1).is_default
-  end
-
-  def test_reorder_should_not_clear_default_status
-    status = IssueStatus.default
-    status.move_to_bottom
-    status.reload
-    assert status.is_default?
-  end
-
-  def test_new_statuses_allowed_to
-    Workflow.delete_all
-
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
-    Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
-    status = IssueStatus.find(1)
-    role = Role.find(1)
-    tracker = Tracker.find(1)
-
-    assert_equal [2], status.new_statuses_allowed_to([role], tracker, false, false).map(&:id)
-    assert_equal [2], status.find_new_statuses_allowed_to([role], tracker, false, false).map(&:id)
-
-    assert_equal [2, 3, 5], status.new_statuses_allowed_to([role], tracker, true, false).map(&:id)
-    assert_equal [2, 3, 5], status.find_new_statuses_allowed_to([role], tracker, true, false).map(&:id)
-
-    assert_equal [2, 4, 5], status.new_statuses_allowed_to([role], tracker, false, true).map(&:id)
-    assert_equal [2, 4, 5], status.find_new_statuses_allowed_to([role], tracker, false, true).map(&:id)
-
-    assert_equal [2, 3, 4, 5], status.new_statuses_allowed_to([role], tracker, true, true).map(&:id)
-    assert_equal [2, 3, 4, 5], status.find_new_statuses_allowed_to([role], tracker, true, true).map(&:id)
-  end
-
-  context "#update_done_ratios" do
-    setup do
-      @issue = Issue.find(1)
-      @issue_status = IssueStatus.find(1)
-      @issue_status.update_attribute(:default_done_ratio, 50)
-    end
-
-    context "with Setting.issue_done_ratio using the issue_field" do
-      setup do
-        Setting.issue_done_ratio = 'issue_field'
-      end
-
-      should "change nothing" do
-        IssueStatus.update_issue_done_ratios
-
-        assert_equal 0, Issue.count(:conditions => {:done_ratio => 50})
-      end
-    end
-
-    context "with Setting.issue_done_ratio using the issue_status" do
-      setup do
-        Setting.issue_done_ratio = 'issue_status'
-      end
-
-      should "update all of the issue's done_ratios to match their Issue Status" do
-        IssueStatus.update_issue_done_ratios
-
-        issues = Issue.find([1,3,4,5,6,7,9,10])
-        issues.each do |issue|
-          assert_equal @issue_status, issue.status
-          assert_equal 50, issue.read_attribute(:done_ratio)
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e3/e38f15d25eddac622827eb4fb140d82f4ed1a927.svn-base
--- a/.svn/pristine/e3/e38f15d25eddac622827eb4fb140d82f4ed1a927.svn-base
+++ /dev/null
@@ -1,40 +0,0 @@
-<h2><%= l(:label_board_plural) %></h2>
-
-<table class="list boards">
-  <thead><tr>
-    <th><%= l(:label_board) %></th>
-    <th><%= l(:label_topic_plural) %></th>
-    <th><%= l(:label_message_plural) %></th>
-    <th><%= l(:label_message_last) %></th>
-  </tr></thead>
-  <tbody>
-<% for board in @boards %>
-  <tr class="<%= cycle 'odd', 'even' %>">
-    <td>
-      <%= link_to h(board.name), {:action => 'show', :id => board}, :class => "board"  %><br />
-      <%=h board.description %>
-    </td>
-    <td align="center"><%= board.topics_count %></td>
-    <td align="center"><%= board.messages_count %></td>
-    <td>
-    <small>
-      <% if board.last_message %>
-      <%= authoring board.last_message.created_on, board.last_message.author %><br />
-      <%= link_to_message board.last_message %>
-      <% end %>
-    </small>
-    </td>
-  </tr>
-<% end %>
-  </tbody>
-</table>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => @project, :show_messages => 1, :key => User.current.rss_key} %>
-<% end %>
-
-<% content_for :header_tags do %>
-  <%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :id => @project, :format => 'atom', :show_messages => 1, :key => User.current.rss_key}) %>
-<% end %>
-
-<% html_title l(:label_board_plural) %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e3/e3ce93992f0dcb5926074deef74a2fe1bdbea820.svn-base
--- a/.svn/pristine/e3/e3ce93992f0dcb5926074deef74a2fe1bdbea820.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-  <% if @users_by_role.any? %>
-  <div class="members box">
-    <h3><%=l(:label_member_plural)%></h3>
-    <p><% @users_by_role.keys.sort.each do |role| %>
-    <%=h role %>: <%= @users_by_role[role].sort.collect{|u| link_to_user u}.join(", ") %><br />
-    <% end %></p>
-  </div>
-  <% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e3/e3ea2cb6450687eb1d61c512debbaf9478178a88.svn-base
--- /dev/null
+++ b/.svn/pristine/e3/e3ea2cb6450687eb1d61c512debbaf9478178a88.svn-base
@@ -0,0 +1,52 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module ActiveRecord
+  module FinderMethods
+    def find_ids(*args)
+      find_ids_with_associations
+    end
+
+    private
+  
+    def find_ids_with_associations
+        join_dependency = construct_join_dependency_for_association_find
+        relation = construct_relation_for_association_find_ids(join_dependency)
+        rows = connection.select_all(relation, 'SQL', relation.bind_values)
+        rows.map {|row| row["id"].to_i}
+      rescue ThrowResult
+        []
+    end
+
+    def construct_relation_for_association_find_ids(join_dependency)
+      relation = except(:includes, :eager_load, :preload, :select).select("#{table_name}.id")
+      apply_join_dependency(relation, join_dependency)
+    end
+  end
+end
+
+class DateValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    before_type_cast = record.attributes_before_type_cast[attribute.to_s]
+    if before_type_cast.is_a?(String) && before_type_cast.present?
+      # TODO: #*_date_before_type_cast returns a Mysql::Time with ruby1.8+mysql gem
+      unless before_type_cast =~ /\A\d{4}-\d{2}-\d{2}( 00:00:00)?\z/ && value
+        record.errors.add attribute, :not_a_date
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e4/e4090c8aca96da6a48e07596b08d96af2c68fc96.svn-base
--- a/.svn/pristine/e4/e4090c8aca96da6a48e07596b08d96af2c68fc96.svn-base
+++ /dev/null
@@ -1,34 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class DocumentCategory < Enumeration
-  has_many :documents, :foreign_key => 'category_id'
-
-  OptionName = :enumeration_doc_categories
-
-  def option_name
-    OptionName
-  end
-
-  def objects_count
-    documents.count
-  end
-
-  def transfer_relations(to)
-    documents.update_all("category_id = #{to.id}")
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e4/e41e80687b0e0255ad1c86abdfe61ea87468ed76.svn-base
--- /dev/null
+++ b/.svn/pristine/e4/e41e80687b0e0255ad1c86abdfe61ea87468ed76.svn-base
@@ -0,0 +1,297 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::ProjectsTest < Redmine::ApiTest::Base
+  fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
+           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
+           :attachments, :custom_fields, :custom_values, :time_entries, :issue_categories
+
+  def setup
+    Setting.rest_api_enabled = '1'
+    set_tmp_attachments_directory
+  end
+
+  context "GET /projects" do
+    context ".xml" do
+      should "return projects" do
+        get '/projects.xml'
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+
+        assert_tag :tag => 'projects',
+          :child => {:tag => 'project', :child => {:tag => 'id', :content => '1'}}
+      end
+    end
+
+    context ".json" do
+      should "return projects" do
+        get '/projects.json'
+        assert_response :success
+        assert_equal 'application/json', @response.content_type
+
+        json = ActiveSupport::JSON.decode(response.body)
+        assert_kind_of Hash, json
+        assert_kind_of Array, json['projects']
+        assert_kind_of Hash, json['projects'].first
+        assert json['projects'].first.has_key?('id')
+      end
+    end
+  end
+
+  context "GET /projects/:id" do
+    context ".xml" do
+      # TODO: A private project is needed because should_allow_api_authentication
+      # actually tests that authentication is *required*, not just allowed
+      should_allow_api_authentication(:get, "/projects/2.xml")
+
+      should "return requested project" do
+        get '/projects/1.xml'
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+
+        assert_tag :tag => 'project',
+          :child => {:tag => 'id', :content => '1'}
+        assert_tag :tag => 'custom_field',
+          :attributes => {:name => 'Development status'}, :content => 'Stable'
+
+        assert_no_tag 'trackers'
+        assert_no_tag 'issue_categories'
+      end
+
+      context "with hidden custom fields" do
+        setup do
+          ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
+        end
+
+        should "not display hidden custom fields" do
+          get '/projects/1.xml'
+          assert_response :success
+          assert_equal 'application/xml', @response.content_type
+
+          assert_no_tag 'custom_field',
+            :attributes => {:name => 'Development status'}
+        end
+      end
+
+      should "return categories with include=issue_categories" do
+        get '/projects/1.xml?include=issue_categories'
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+
+        assert_tag 'issue_categories',
+          :attributes => {:type => 'array'},
+          :child => {
+            :tag => 'issue_category',
+            :attributes => {
+              :id => '2',
+              :name => 'Recipes'
+            }
+          }
+      end
+
+      should "return trackers with include=trackers" do
+        get '/projects/1.xml?include=trackers'
+        assert_response :success
+        assert_equal 'application/xml', @response.content_type
+
+        assert_tag 'trackers',
+          :attributes => {:type => 'array'},
+          :child => {
+            :tag => 'tracker',
+            :attributes => {
+              :id => '2',
+              :name => 'Feature request'
+            }
+          }
+      end
+    end
+
+    context ".json" do
+      should_allow_api_authentication(:get, "/projects/2.json")
+
+      should "return requested project" do
+        get '/projects/1.json'
+
+        json = ActiveSupport::JSON.decode(response.body)
+        assert_kind_of Hash, json
+        assert_kind_of Hash, json['project']
+        assert_equal 1, json['project']['id']
+      end
+    end
+  end
+
+  context "POST /projects" do
+    context "with valid parameters" do
+      setup do
+        Setting.default_projects_modules = ['issue_tracking', 'repository']
+        @parameters = {:project => {:name => 'API test', :identifier => 'api-test'}}
+      end
+
+      context ".xml" do
+        should_allow_api_authentication(:post,
+                                        '/projects.xml',
+                                        {:project => {:name => 'API test', :identifier => 'api-test'}},
+                                        {:success_code => :created})
+
+
+        should "create a project with the attributes" do
+          assert_difference('Project.count') do
+            post '/projects.xml', @parameters, credentials('admin')
+          end
+
+          project = Project.first(:order => 'id DESC')
+          assert_equal 'API test', project.name
+          assert_equal 'api-test', project.identifier
+          assert_equal ['issue_tracking', 'repository'], project.enabled_module_names.sort
+          assert_equal Tracker.all.size, project.trackers.size
+
+          assert_response :created
+          assert_equal 'application/xml', @response.content_type
+          assert_tag 'project', :child => {:tag => 'id', :content => project.id.to_s}
+        end
+
+        should "accept enabled_module_names attribute" do
+          @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
+
+          assert_difference('Project.count') do
+            post '/projects.xml', @parameters, credentials('admin')
+          end
+
+          project = Project.first(:order => 'id DESC')
+          assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
+        end
+
+        should "accept tracker_ids attribute" do
+          @parameters[:project].merge!({:tracker_ids => [1, 3]})
+
+          assert_difference('Project.count') do
+            post '/projects.xml', @parameters, credentials('admin')
+          end
+
+          project = Project.first(:order => 'id DESC')
+          assert_equal [1, 3], project.trackers.map(&:id).sort
+        end
+      end
+    end
+
+    context "with invalid parameters" do
+      setup do
+        @parameters = {:project => {:name => 'API test'}}
+      end
+
+      context ".xml" do
+        should "return errors" do
+          assert_no_difference('Project.count') do
+            post '/projects.xml', @parameters, credentials('admin')
+          end
+
+          assert_response :unprocessable_entity
+          assert_equal 'application/xml', @response.content_type
+          assert_tag 'errors', :child => {:tag => 'error', :content => "Identifier can't be blank"}
+        end
+      end
+    end
+  end
+
+  context "PUT /projects/:id" do
+    context "with valid parameters" do
+      setup do
+        @parameters = {:project => {:name => 'API update'}}
+      end
+
+      context ".xml" do
+        should_allow_api_authentication(:put,
+                                        '/projects/2.xml',
+                                        {:project => {:name => 'API update'}},
+                                        {:success_code => :ok})
+
+        should "update the project" do
+          assert_no_difference 'Project.count' do
+            put '/projects/2.xml', @parameters, credentials('jsmith')
+          end
+          assert_response :ok
+          assert_equal '', @response.body
+          assert_equal 'application/xml', @response.content_type
+          project = Project.find(2)
+          assert_equal 'API update', project.name
+        end
+
+        should "accept enabled_module_names attribute" do
+          @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
+
+          assert_no_difference 'Project.count' do
+            put '/projects/2.xml', @parameters, credentials('admin')
+          end
+          assert_response :ok
+          assert_equal '', @response.body
+          project = Project.find(2)
+          assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
+        end
+
+        should "accept tracker_ids attribute" do
+          @parameters[:project].merge!({:tracker_ids => [1, 3]})
+
+          assert_no_difference 'Project.count' do
+            put '/projects/2.xml', @parameters, credentials('admin')
+          end
+          assert_response :ok
+          assert_equal '', @response.body
+          project = Project.find(2)
+          assert_equal [1, 3], project.trackers.map(&:id).sort
+        end
+      end
+    end
+
+    context "with invalid parameters" do
+      setup do
+        @parameters = {:project => {:name => ''}}
+      end
+
+      context ".xml" do
+        should "return errors" do
+          assert_no_difference('Project.count') do
+            put '/projects/2.xml', @parameters, credentials('admin')
+          end
+
+          assert_response :unprocessable_entity
+          assert_equal 'application/xml', @response.content_type
+          assert_tag 'errors', :child => {:tag => 'error', :content => "Name can't be blank"}
+        end
+      end
+    end
+  end
+
+  context "DELETE /projects/:id" do
+    context ".xml" do
+      should_allow_api_authentication(:delete,
+                                      '/projects/2.xml',
+                                      {},
+                                      {:success_code => :ok})
+
+      should "delete the project" do
+        assert_difference('Project.count',-1) do
+          delete '/projects/2.xml', {}, credentials('admin')
+        end
+        assert_response :ok
+        assert_equal '', @response.body
+        assert_nil Project.find_by_id(2)
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e4/e45d0f01136e76ca9de552ead8c4d0d26e3695d4.svn-base
--- /dev/null
+++ b/.svn/pristine/e4/e45d0f01136e76ca9de552ead8c4d0d26e3695d4.svn-base
@@ -0,0 +1,36 @@
+<div class="contextual">
+<%= watcher_link(@wiki, User.current) %>
+</div>
+
+<h2><%= l(:label_index_by_date) %></h2>
+
+<% if @pages.empty? %>
+<p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
+
+<% @pages_by_date.keys.sort.reverse.each do |date| %>
+<h3><%= format_date(date) %></h3>
+<ul>
+<% @pages_by_date[date].each do |page| %>
+    <li><%= link_to h(page.pretty_title), :action => 'show', :id => page.title, :project_id => page.project %></li>
+<% end %>
+</ul>
+<% end %>
+
+<% content_for :sidebar do %>
+  <%= render :partial => 'sidebar' %>
+<% end %>
+
+<% unless @pages.empty? %>
+<% other_formats_links do |f| %>
+  <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :key => User.current.rss_key} %>
+  <% if User.current.allowed_to?(:export_wiki_pages, @project) %>
+  <%= f.link_to('PDF', :url => {:action => 'export', :format => 'pdf'}) %>
+  <%= f.link_to('HTML', :url => {:action => 'export'}) %>
+  <% end %>
+<% end %>
+<% end %>
+
+<% content_for :header_tags do %>
+<%= auto_discovery_link_tag(:atom, :controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :format => 'atom', :key => User.current.rss_key) %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e4/e479c671ce697e72b11bd49cf15871d767b7e451.svn-base
--- a/.svn/pristine/e4/e479c671ce697e72b11bd49cf15871d767b7e451.svn-base
+++ /dev/null
@@ -1,121 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module WikiFormatting
-    module Macros
-      module Definitions
-        def exec_macro(name, obj, args)
-          method_name = "macro_#{name}"
-          send(method_name, obj, args) if respond_to?(method_name)
-        end
-
-        def extract_macro_options(args, *keys)
-          options = {}
-          while args.last.to_s.strip =~ %r{^(.+)\=(.+)$} && keys.include?($1.downcase.to_sym)
-            options[$1.downcase.to_sym] = $2
-            args.pop
-          end
-          return [args, options]
-        end
-      end
-
-      @@available_macros = {}
-
-      class << self
-        # Called with a block to define additional macros.
-        # Macro blocks accept 2 arguments:
-        # * obj: the object that is rendered
-        # * args: macro arguments
-        #
-        # Plugins can use this method to define new macros:
-        #
-        #   Redmine::WikiFormatting::Macros.register do
-        #     desc "This is my macro"
-        #     macro :my_macro do |obj, args|
-        #       "My macro output"
-        #     end
-        #   end
-        def register(&block)
-          class_eval(&block) if block_given?
-        end
-
-      private
-        # Defines a new macro with the given name and block.
-        def macro(name, &block)
-          name = name.to_sym if name.is_a?(String)
-          @@available_macros[name] = @@desc || ''
-          @@desc = nil
-          raise "Can not create a macro without a block!" unless block_given?
-          Definitions.send :define_method, "macro_#{name}".downcase, &block
-        end
-
-        # Sets description for the next macro to be defined
-        def desc(txt)
-          @@desc = txt
-        end
-      end
-
-      # Builtin macros
-      desc "Sample macro."
-      macro :hello_world do |obj, args|
-        "Hello world! Object: #{obj.class.name}, " + (args.empty? ? "Called with no argument." : "Arguments: #{args.join(', ')}")
-      end
-
-      desc "Displays a list of all available macros, including description if available."
-      macro :macro_list do |obj, args|
-        out = ''
-        @@available_macros.keys.collect(&:to_s).sort.each do |macro|
-          out << content_tag('dt', content_tag('code', macro))
-          out << content_tag('dd', textilizable(@@available_macros[macro.to_sym]))
-        end
-        content_tag('dl', out)
-      end
-
-      desc "Displays a list of child pages. With no argument, it displays the child pages of the current wiki page. Examples:\n\n" +
-             "  !{{child_pages}} -- can be used from a wiki page only\n" +
-             "  !{{child_pages(Foo)}} -- lists all children of page Foo\n" +
-             "  !{{child_pages(Foo, parent=1)}} -- same as above with a link to page Foo"
-      macro :child_pages do |obj, args|
-        args, options = extract_macro_options(args, :parent)
-        page = nil
-        if args.size > 0
-          page = Wiki.find_page(args.first.to_s, :project => @project)
-        elsif obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)
-          page = obj.page
-        else
-          raise 'With no argument, this macro can be called from wiki pages only.'
-        end
-        raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project)
-        pages = ([page] + page.descendants).group_by(&:parent_id)
-        render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id)
-      end
-
-      desc "Include a wiki page. Example:\n\n  !{{include(Foo)}}\n\nor to include a page of a specific project wiki:\n\n  !{{include(projectname:Foo)}}"
-      macro :include do |obj, args|
-        page = Wiki.find_page(args.first.to_s, :project => @project)
-        raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project)
-        @included_wiki_pages ||= []
-        raise 'Circular inclusion detected' if @included_wiki_pages.include?(page.title)
-        @included_wiki_pages << page.title
-        out = textilizable(page.content, :text, :attachments => page.attachments, :headings => false)
-        @included_wiki_pages.pop
-        out
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e4/e47c28874d93e63d4ec1ec20c05fe818fb5867d7.svn-base
--- a/.svn/pristine/e4/e47c28874d93e63d4ec1ec20c05fe818fb5867d7.svn-base
+++ /dev/null
@@ -1,309 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'diff'
-
-# The WikiController follows the Rails REST controller pattern but with
-# a few differences
-#
-# * index - shows a list of WikiPages grouped by page or date
-# * new - not used
-# * create - not used
-# * show - will also show the form for creating a new wiki page
-# * edit - used to edit an existing or new page
-# * update - used to save a wiki page update to the database, including new pages
-# * destroy - normal
-#
-# Other member and collection methods are also used
-#
-# TODO: still being worked on
-class WikiController < ApplicationController
-  default_search_scope :wiki_pages
-  before_filter :find_wiki, :authorize
-  before_filter :find_existing_or_new_page, :only => [:show, :edit, :update]
-  before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
-
-  helper :attachments
-  include AttachmentsHelper
-  helper :watchers
-  include Redmine::Export::PDF
-
-  # List of pages, sorted alphabetically and by parent (hierarchy)
-  def index
-    load_pages_for_index
-    @pages_by_parent_id = @pages.group_by(&:parent_id)
-  end
-
-  # List of page, by last update
-  def date_index
-    load_pages_for_index
-    @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
-  end
-
-  # display a page (in editing mode if it doesn't exist)
-  def show
-    if @page.new_record?
-      if User.current.allowed_to?(:edit_wiki_pages, @project) && editable?
-        edit
-        render :action => 'edit'
-      else
-        render_404
-      end
-      return
-    end
-    if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
-      # Redirects user to the current version if he's not allowed to view previous versions
-      redirect_to :version => nil
-      return
-    end
-    @content = @page.content_for_version(params[:version])
-    if User.current.allowed_to?(:export_wiki_pages, @project)
-      if params[:format] == 'pdf'
-        send_data(wiki_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf")
-        return
-      elsif params[:format] == 'html'
-        export = render_to_string :action => 'export', :layout => false
-        send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
-        return
-      elsif params[:format] == 'txt'
-        send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
-        return
-      end
-    end
-    @editable = editable?
-    @sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) &&
-      @content.current_version? &&
-      Redmine::WikiFormatting.supports_section_edit?
-
-    render :action => 'show'
-  end
-
-  # edit an existing page or a new one
-  def edit
-    return render_403 unless editable?
-    @page.content = WikiContent.new(:page => @page) if @page.new_record?
-
-    @content = @page.content_for_version(params[:version])
-    @content.text = initial_page_content(@page) if @content.text.blank?
-    # don't keep previous comment
-    @content.comments = nil
-
-    # To prevent StaleObjectError exception when reverting to a previous version
-    @content.version = @page.content.version
-    
-    @text = @content.text
-    if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
-      @section = params[:section].to_i
-      @text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section)
-      render_404 if @text.blank?
-    end
-  end
-
-  verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
-  # Creates a new page or updates an existing one
-  def update
-    return render_403 unless editable?
-    @page.content = WikiContent.new(:page => @page) if @page.new_record?
-
-    @content = @page.content_for_version(params[:version])
-    @content.text = initial_page_content(@page) if @content.text.blank?
-    # don't keep previous comment
-    @content.comments = nil
-
-    if !@page.new_record? && params[:content].present? && @content.text == params[:content][:text]
-      attachments = Attachment.attach_files(@page, params[:attachments])
-      render_attachment_warning_if_needed(@page)
-      # don't save if text wasn't changed
-      redirect_to :action => 'show', :project_id => @project, :id => @page.title
-      return
-    end
-    
-    @content.comments = params[:content][:comments]
-    @text = params[:content][:text]
-    if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
-      @section = params[:section].to_i
-      @section_hash = params[:section_hash]
-      @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash)
-    else
-      @content.version = params[:content][:version]
-      @content.text = @text
-    end
-    @content.author = User.current
-    # if page is new @page.save will also save content, but not if page isn't a new record
-    if (@page.new_record? ? @page.save : @content.save)
-      attachments = Attachment.attach_files(@page, params[:attachments])
-      render_attachment_warning_if_needed(@page)
-      call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
-      redirect_to :action => 'show', :project_id => @project, :id => @page.title
-    else
-      render :action => 'edit'
-    end
-
-  rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError
-    # Optimistic locking exception
-    flash.now[:error] = l(:notice_locking_conflict)
-    render :action => 'edit'
-  end
-
-  # rename a page
-  def rename
-    return render_403 unless editable?
-    @page.redirect_existing_links = true
-    # used to display the *original* title if some AR validation errors occur
-    @original_title = @page.pretty_title
-    if request.post? && @page.update_attributes(params[:wiki_page])
-      flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'show', :project_id => @project, :id => @page.title
-    end
-  end
-
-  verify :method => :post, :only => :protect, :redirect_to => { :action => :show }
-  def protect
-    @page.update_attribute :protected, params[:protected]
-    redirect_to :action => 'show', :project_id => @project, :id => @page.title
-  end
-
-  # show page history
-  def history
-    @version_count = @page.content.versions.count
-    @version_pages = Paginator.new self, @version_count, per_page_option, params['p']
-    # don't load text
-    @versions = @page.content.versions.find :all,
-                                            :select => "id, author_id, comments, updated_on, version",
-                                            :order => 'version DESC',
-                                            :limit  =>  @version_pages.items_per_page + 1,
-                                            :offset =>  @version_pages.current.offset
-
-    render :layout => false if request.xhr?
-  end
-
-  def diff
-    @diff = @page.diff(params[:version], params[:version_from])
-    render_404 unless @diff
-  end
-
-  def annotate
-    @annotate = @page.annotate(params[:version])
-    render_404 unless @annotate
-  end
-
-  verify :method => :delete, :only => [:destroy], :redirect_to => { :action => :show }
-  # Removes a wiki page and its history
-  # Children can be either set as root pages, removed or reassigned to another parent page
-  def destroy
-    return render_403 unless editable?
-
-    @descendants_count = @page.descendants.size
-    if @descendants_count > 0
-      case params[:todo]
-      when 'nullify'
-        # Nothing to do
-      when 'destroy'
-        # Removes all its descendants
-        @page.descendants.each(&:destroy)
-      when 'reassign'
-        # Reassign children to another parent page
-        reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
-        return unless reassign_to
-        @page.children.each do |child|
-          child.update_attribute(:parent, reassign_to)
-        end
-      else
-        @reassignable_to = @wiki.pages - @page.self_and_descendants
-        return
-      end
-    end
-    @page.destroy
-    redirect_to :action => 'index', :project_id => @project
-  end
-
-  # Export wiki to a single html file
-  def export
-    if User.current.allowed_to?(:export_wiki_pages, @project)
-      @pages = @wiki.pages.find :all, :order => 'title'
-      export = render_to_string :action => 'export_multiple', :layout => false
-      send_data(export, :type => 'text/html', :filename => "wiki.html")
-    else
-      redirect_to :action => 'show', :project_id => @project, :id => nil
-    end
-  end
-
-  def preview
-    page = @wiki.find_page(params[:id])
-    # page is nil when previewing a new page
-    return render_403 unless page.nil? || editable?(page)
-    if page
-      @attachements = page.attachments
-      @previewed = page.content
-    end
-    @text = params[:content][:text]
-    render :partial => 'common/preview'
-  end
-
-  def add_attachment
-    return render_403 unless editable?
-    attachments = Attachment.attach_files(@page, params[:attachments])
-    render_attachment_warning_if_needed(@page)
-    redirect_to :action => 'show', :id => @page.title, :project_id => @project
-  end
-
-private
-
-  def find_wiki
-    @project = Project.find(params[:project_id])
-    @wiki = @project.wiki
-    render_404 unless @wiki
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-  # Finds the requested page or a new page if it doesn't exist
-  def find_existing_or_new_page
-    @page = @wiki.find_or_new_page(params[:id])
-    if @wiki.page_found_with_redirect?
-      redirect_to params.update(:id => @page.title)
-    end
-  end
-
-  # Finds the requested page and returns a 404 error if it doesn't exist
-  def find_existing_page
-    @page = @wiki.find_page(params[:id])
-    if @page.nil?
-      render_404
-      return
-    end
-    if @wiki.page_found_with_redirect?
-      redirect_to params.update(:id => @page.title)
-    end
-  end
-
-  # Returns true if the current user is allowed to edit the page, otherwise false
-  def editable?(page = @page)
-    page.editable_by?(User.current)
-  end
-
-  # Returns the default content of a new wiki page
-  def initial_page_content(page)
-    helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
-    extend helper unless self.instance_of?(helper)
-    helper.instance_method(:initial_page_content).bind(self).call(page)
-  end
-
-  def load_pages_for_index
-    @pages = @wiki.pages.with_updated_on.all(:order => 'title', :include => {:wiki => :project})
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e4/e4897735528df3f63a14478e29488229fe020925.svn-base
--- /dev/null
+++ b/.svn/pristine/e4/e4897735528df3f63a14478e29488229fe020925.svn-base
@@ -0,0 +1,96 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Acts
+    module Event
+      def self.included(base)
+        base.extend ClassMethods
+      end
+
+      module ClassMethods
+        def acts_as_event(options = {})
+          return if self.included_modules.include?(Redmine::Acts::Event::InstanceMethods)
+          default_options = { :datetime => :created_on,
+                              :title => :title,
+                              :description => :description,
+                              :author => :author,
+                              :url => {:controller => 'welcome'},
+                              :type => self.name.underscore.dasherize }
+
+          cattr_accessor :event_options
+          self.event_options = default_options.merge(options)
+          send :include, Redmine::Acts::Event::InstanceMethods
+        end
+      end
+
+      module InstanceMethods
+        def self.included(base)
+          base.extend ClassMethods
+        end
+
+        %w(datetime title description author type).each do |attr|
+          src = <<-END_SRC
+            def event_#{attr}
+              option = event_options[:#{attr}]
+              if option.is_a?(Proc)
+                option.call(self)
+              elsif option.is_a?(Symbol)
+                send(option)
+              else
+                option
+              end
+            end
+          END_SRC
+          class_eval src, __FILE__, __LINE__
+        end
+
+        def event_date
+          event_datetime.to_date
+        end
+
+        def event_group
+          group = event_options[:group] ? send(event_options[:group]) : self
+          group || self
+        end
+
+        def event_url(options = {})
+          option = event_options[:url]
+          if option.is_a?(Proc)
+            option.call(self).merge(options)
+          elsif option.is_a?(Hash)
+            option.merge(options)
+          elsif option.is_a?(Symbol)
+            send(option).merge(options)
+          else
+            option
+          end
+        end
+
+        # Returns the mail adresses of users that should be notified
+        def recipients
+          notified = project.notified_users
+          notified.reject! {|user| !visible?(user)}
+          notified.collect(&:mail)
+        end
+
+        module ClassMethods
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e4/e4ab6d8e5432db058f2447acda154774358a5665.svn-base
--- a/.svn/pristine/e4/e4ab6d8e5432db058f2447acda154774358a5665.svn-base
+++ /dev/null
@@ -1,1029 +0,0 @@
-# Finnish translations for Ruby on Rails 
-# by Marko SeppÃ¤ (marko.seppa@gmail.com)
-
-fi:
-  direction: ltr
-  date:
-    formats:
-      default: "%e. %Bta %Y"
-      long: "%A%e. %Bta %Y"
-      short: "%e.%m.%Y"
- 
-    day_names: [Sunnuntai, Maanantai, Tiistai, Keskiviikko, Torstai, Perjantai, Lauantai]
-    abbr_day_names: [Su, Ma, Ti, Ke, To, Pe, La]
-    month_names: [~, Tammikuu, Helmikuu, Maaliskuu, Huhtikuu, Toukokuu, KesÃ¤kuu, HeinÃ¤kuu, Elokuu, Syyskuu, Lokakuu, Marraskuu, Joulukuu]
-    abbr_month_names: [~, Tammi, Helmi, Maalis, Huhti, Touko, KesÃ¤, HeinÃ¤, Elo, Syys, Loka, Marras, Joulu]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%a, %e. %b %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%e. %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "aamupÃ¤ivÃ¤"
-    pm: "iltapÃ¤ivÃ¤"
-
-  support:
-    array:
-      words_connector: ", "
-      two_words_connector: " ja "
-      last_word_connector: " ja "
-
-
-
-  number:
-    format:
-      separator: ","
-      delimiter: "."
-      precision: 3
-    
-    currency:
-      format:
-        format: "%n %u"
-        unit: "â‚¬"
-        separator: ","
-        delimiter: "."
-        precision: 2
-        
-    percentage:
-      format:
-        # separator:
-        delimiter: ""
-        # precision: 
-
-    precision:
-      format:
-        # separator:
-        delimiter: ""
-        # precision:
-        
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Tavua"
-            other: "Tavua"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
- 
-  datetime:
-    distance_in_words:
-      half_a_minute: "puoli minuuttia"
-      less_than_x_seconds:
-        one:   "aiemmin kuin sekunti"
-        other: "aiemmin kuin %{count} sekuntia"
-      x_seconds:
-        one:   "sekunti"
-        other: "%{count} sekuntia"
-      less_than_x_minutes:
-        one:   "aiemmin kuin minuutti"
-        other: "aiemmin kuin %{count} minuuttia"
-      x_minutes:
-        one:   "minuutti"
-        other: "%{count} minuuttia"
-      about_x_hours:
-        one:   "noin tunti"
-        other: "noin %{count} tuntia"
-      x_days:
-        one:   "pÃ¤ivÃ¤"
-        other: "%{count} pÃ¤ivÃ¤Ã¤"
-      about_x_months:
-        one:   "noin kuukausi"
-        other: "noin %{count} kuukautta"
-      x_months:
-        one:   "kuukausi"
-        other: "%{count} kuukautta"
-      about_x_years:
-        one:   "vuosi"
-        other: "noin %{count} vuotta"
-      over_x_years:
-        one:   "yli vuosi"
-        other: "yli %{count} vuotta"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-    prompts:
-      year:   "Vuosi"
-      month:  "Kuukausi"
-      day:    "PÃ¤ivÃ¤"
-      hour:   "Tunti"
-      minute: "Minuutti"
-      second: "Sekuntia"
-  
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 virhe esti tÃ¤mÃ¤n %{model} mallinteen tallentamisen"
-          other:  "%{count} virhettÃ¤ esti tÃ¤mÃ¤n %{model} mallinteen tallentamisen"
-        body: "Seuraavat kentÃ¤t aiheuttivat ongelmia:"
-      messages:
-        inclusion: "ei lÃ¶ydy listauksesta"
-        exclusion: "on jo varattu"
-        invalid: "on kelvoton"
-        confirmation: "ei vastaa varmennusta"
-        accepted: "tÃ¤ytyy olla hyvÃ¤ksytty"
-        empty: "ei voi olla tyhjÃ¤"
-        blank: "ei voi olla sisÃ¤llÃ¶tÃ¶n"
-        too_long: "on liian pitkÃ¤ (maksimi on %{count} merkkiÃ¤)"
-        too_short: "on liian lyhyt (minimi on %{count} merkkiÃ¤)"
-        wrong_length: "on vÃ¤Ã¤rÃ¤n pituinen (tÃ¤ytyy olla tÃ¤smÃ¤lleen %{count} merkkiÃ¤)"
-        taken: "on jo kÃ¤ytÃ¶ssÃ¤"
-        not_a_number: "ei ole numero"
-        greater_than: "tÃ¤ytyy olla suurempi kuin %{count}"
-        greater_than_or_equal_to: "tÃ¤ytyy olla suurempi tai yhtÃ¤ suuri kuin%{count}"
-        equal_to: "tÃ¤ytyy olla yhtÃ¤ suuri kuin %{count}"
-        less_than: "tÃ¤ytyy olla pienempi kuin %{count}"
-        less_than_or_equal_to: "tÃ¤ytyy olla pienempi tai yhtÃ¤ suuri kuin %{count}"
-        odd: "tÃ¤ytyy olla pariton"
-        even: "tÃ¤ytyy olla parillinen"
-        greater_than_start_date: "tulee olla aloituspÃ¤ivÃ¤n jÃ¤lkeinen"
-        not_same_project: "ei kuulu samaan projektiin"
-        circular_dependency: "TÃ¤mÃ¤ suhde loisi kehÃ¤n."
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-  
-  actionview_instancetag_blank_option: Valitse, ole hyvÃ¤
-  
-  general_text_No: 'Ei'
-  general_text_Yes: 'KyllÃ¤'
-  general_text_no: 'ei'
-  general_text_yes: 'kyllÃ¤'
-  general_lang_name: 'Finnish (Suomi)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: ISO-8859-15
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: Tilin pÃ¤ivitys onnistui.
-  notice_account_invalid_creditentials: Virheellinen kÃ¤yttÃ¤jÃ¤tunnus tai salasana
-  notice_account_password_updated: Salasanan pÃ¤ivitys onnistui.
-  notice_account_wrong_password: VÃ¤Ã¤rÃ¤ salasana
-  notice_account_register_done: Tilin luonti onnistui. Aktivoidaksesi tilin seuraa linkkiÃ¤ joka vÃ¤litettiin sÃ¤hkÃ¶postiisi.
-  notice_account_unknown_email: Tuntematon kÃ¤yttÃ¤jÃ¤.
-  notice_can_t_change_password: TÃ¤mÃ¤ tili kÃ¤yttÃ¤Ã¤ ulkoista tunnistautumisjÃ¤rjestelmÃ¤Ã¤. Salasanaa ei voi muuttaa.
-  notice_account_lost_email_sent: Sinulle on lÃ¤hetetty sÃ¤hkÃ¶posti jossa on ohje kuinka vaihdat salasanasi.
-  notice_account_activated: Tilisi on nyt aktivoitu, voit kirjautua sisÃ¤lle.
-  notice_successful_create: Luonti onnistui.
-  notice_successful_update: PÃ¤ivitys onnistui.
-  notice_successful_delete: Poisto onnistui.
-  notice_successful_connection: Yhteyden muodostus onnistui.
-  notice_file_not_found: Hakemaasi sivua ei lÃ¶ytynyt tai se on poistettu.
-  notice_locking_conflict: Toinen kÃ¤yttÃ¤jÃ¤ on pÃ¤ivittÃ¤nyt tiedot.
-  notice_not_authorized: Sinulla ei ole oikeutta nÃ¤yttÃ¤Ã¤ tÃ¤tÃ¤ sivua.
-  notice_email_sent: "SÃ¤hkÃ¶posti on lÃ¤hetty osoitteeseen %{value}"
-  notice_email_error: "SÃ¤hkÃ¶postilÃ¤hetyksessÃ¤ tapahtui virhe (%{value})"
-  notice_feeds_access_key_reseted: RSS salasana on nollaantunut.
-  notice_failed_to_save_issues: "%{count} Tapahtum(an/ien) tallennus epÃ¤onnistui %{total} valitut: %{ids}."
-  notice_no_issue_selected: "Tapahtumia ei ole valittu! Valitse tapahtumat joita haluat muokata."
-  notice_account_pending: "Tilisi on luotu ja odottaa yllÃ¤pitÃ¤jÃ¤n hyvÃ¤ksyntÃ¤Ã¤."
-  notice_default_data_loaded: Vakioasetusten palautus onnistui.
-  
-  error_can_t_load_default_data: "Vakioasetuksia ei voitu ladata: %{value}"
-  error_scm_not_found: "SyÃ¶tettÃ¤ ja/tai versiota ei lÃ¶ydy tietovarastosta."
-  error_scm_command_failed: "Tietovarastoon pÃ¤Ã¤syssÃ¤ tapahtui virhe: %{value}"
-  
-  mail_subject_lost_password: "Sinun %{value} salasanasi"
-  mail_body_lost_password: 'Vaihtaaksesi salasanasi, napsauta seuraavaa linkkiÃ¤:'
-  mail_subject_register: "%{value} tilin aktivointi"
-  mail_body_register: 'Aktivoidaksesi tilisi, napsauta seuraavaa linkkiÃ¤:'
-  mail_body_account_information_external: "Voit nyt kÃ¤yttÃ¤Ã¤ %{value} tiliÃ¤si kirjautuaksesi jÃ¤rjestelmÃ¤Ã¤n."
-  mail_body_account_information: Sinun tilin tiedot
-  mail_subject_account_activation_request: "%{value} tilin aktivointi pyyntÃ¶"
-  mail_body_account_activation_request: "Uusi kÃ¤yttÃ¤jÃ¤ (%{value}) on rekisterÃ¶itynyt. HÃ¤nen tili odottaa hyvÃ¤ksyntÃ¤Ã¤si:"
-  
-  gui_validation_error: 1 virhe
-  gui_validation_error_plural: "%{count} virhettÃ¤"
-  
-  field_name: Nimi
-  field_description: Kuvaus
-  field_summary: Yhteenveto
-  field_is_required: Vaaditaan
-  field_firstname: Etunimi
-  field_lastname: Sukunimi
-  field_mail: SÃ¤hkÃ¶posti
-  field_filename: Tiedosto
-  field_filesize: Koko
-  field_downloads: Latausta
-  field_author: TekijÃ¤
-  field_created_on: Luotu
-  field_updated_on: PÃ¤ivitetty
-  field_field_format: Muoto
-  field_is_for_all: Kaikille projekteille
-  field_possible_values: Mahdolliset arvot
-  field_regexp: SÃ¤Ã¤nnÃ¶llinen lauseke (reg exp)
-  field_min_length: Minimipituus
-  field_max_length: Maksimipituus
-  field_value: Arvo
-  field_category: Luokka
-  field_title: Otsikko
-  field_project: Projekti
-  field_issue: Tapahtuma
-  field_status: Tila
-  field_notes: Muistiinpanot
-  field_is_closed: Tapahtuma suljettu
-  field_is_default: Vakioarvo
-  field_tracker: Tapahtuma
-  field_subject: Aihe
-  field_due_date: MÃ¤Ã¤rÃ¤aika
-  field_assigned_to: Nimetty
-  field_priority: Prioriteetti
-  field_fixed_version: Kohdeversio
-  field_user: KÃ¤yttÃ¤jÃ¤
-  field_role: Rooli
-  field_homepage: Kotisivu
-  field_is_public: Julkinen
-  field_parent: Aliprojekti
-  field_is_in_roadmap: Tapahtumat nÃ¤ytetÃ¤Ã¤n roadmap nÃ¤kymÃ¤ssÃ¤
-  field_login: Kirjautuminen
-  field_mail_notification: SÃ¤hkÃ¶posti muistutukset
-  field_admin: YllÃ¤pitÃ¤jÃ¤
-  field_last_login_on: Viimeinen yhteys
-  field_language: Kieli
-  field_effective_date: PÃ¤ivÃ¤
-  field_password: Salasana
-  field_new_password: Uusi salasana
-  field_password_confirmation: Vahvistus
-  field_version: Versio
-  field_type: Tyyppi
-  field_host: Verkko-osoite
-  field_port: Portti
-  field_account: Tili
-  field_base_dn: Base DN
-  field_attr_login: KirjautumismÃ¤Ã¤re
-  field_attr_firstname: EtuminenmÃ¤Ã¤re
-  field_attr_lastname: SukunimenmÃ¤Ã¤re
-  field_attr_mail: SÃ¤hkÃ¶postinmÃ¤Ã¤re
-  field_onthefly: Automaattinen kÃ¤yttÃ¤jien luonti
-  field_start_date: Alku
-  field_done_ratio: "% Tehty"
-  field_auth_source: Varmennusmuoto
-  field_hide_mail: Piiloita sÃ¤hkÃ¶postiosoitteeni
-  field_comments: Kommentti
-  field_url: URL
-  field_start_page: Aloitussivu
-  field_subproject: Aliprojekti
-  field_hours: Tuntia
-  field_activity: Historia
-  field_spent_on: PÃ¤ivÃ¤
-  field_identifier: Tunniste
-  field_is_filter: KÃ¤ytetÃ¤Ã¤n suodattimena
-  field_issue_to: LiittyvÃ¤ tapahtuma
-  field_delay: Viive
-  field_assignable: Tapahtumia voidaan nimetÃ¤ tÃ¤lle roolille
-  field_redirect_existing_links: Uudelleenohjaa olemassa olevat linkit
-  field_estimated_hours: Arvioitu aika
-  field_column_names: Saraketta
-  field_time_zone: AikavyÃ¶hyke
-  field_searchable: Haettava
-  field_default_value: Vakioarvo
-  
-  setting_app_title: Ohjelman otsikko
-  setting_app_subtitle: Ohjelman alaotsikko
-  setting_welcome_text: Tervehdysteksti
-  setting_default_language: Vakiokieli
-  setting_login_required: Pakollinen kirjautuminen
-  setting_self_registration: ItserekisterÃ¶inti
-  setting_attachment_max_size: Liitteen maksimikoko
-  setting_issues_export_limit: Tapahtumien vientirajoite
-  setting_mail_from: LÃ¤hettÃ¤jÃ¤n sÃ¤hkÃ¶postiosoite
-  setting_bcc_recipients: Vastaanottajat piilokopiona (bcc)
-  setting_host_name: Verkko-osoite
-  setting_text_formatting: Tekstin muotoilu
-  setting_wiki_compression: Wiki historian pakkaus
-  setting_feeds_limit: SyÃ¶tteen sisÃ¤llÃ¶n raja
-  setting_autofetch_changesets: Automaattisten muutosjoukkojen haku
-  setting_sys_api_enabled: Salli WS tietovaraston hallintaan
-  setting_commit_ref_keywords: Viittaavat hakusanat
-  setting_commit_fix_keywords: Korjaavat hakusanat
-  setting_autologin: Automaatinen kirjautuminen
-  setting_date_format: PÃ¤ivÃ¤n muoto
-  setting_time_format: Ajan muoto
-  setting_cross_project_issue_relations: Salli projektien vÃ¤liset tapahtuminen suhteet
-  setting_issue_list_default_columns: Vakiosarakkeiden nÃ¤yttÃ¶ tapahtumalistauksessa
-  setting_emails_footer: SÃ¤hkÃ¶postin alatunniste
-  setting_protocol: Protokolla
-  setting_per_page_options: Sivun objektien mÃ¤Ã¤rÃ¤n asetukset
-  
-  label_user: KÃ¤yttÃ¤jÃ¤
-  label_user_plural: KÃ¤yttÃ¤jÃ¤t
-  label_user_new: Uusi kÃ¤yttÃ¤jÃ¤
-  label_project: Projekti
-  label_project_new: Uusi projekti
-  label_project_plural: Projektit
-  label_x_projects:
-    zero:  no projects
-    one:   1 project
-    other: "%{count} projects"
-  label_project_all: Kaikki projektit
-  label_project_latest: Uusimmat projektit
-  label_issue: Tapahtuma
-  label_issue_new: Uusi tapahtuma
-  label_issue_plural: Tapahtumat
-  label_issue_view_all: NÃ¤ytÃ¤ kaikki tapahtumat
-  label_issues_by: "Tapahtumat %{value}"
-  label_document: Dokumentti
-  label_document_new: Uusi dokumentti
-  label_document_plural: Dokumentit
-  label_role: Rooli
-  label_role_plural: Roolit
-  label_role_new: Uusi rooli
-  label_role_and_permissions: Roolit ja oikeudet
-  label_member: JÃ¤sen
-  label_member_new: Uusi jÃ¤sen
-  label_member_plural: JÃ¤senet
-  label_tracker: Tapahtuma
-  label_tracker_plural: Tapahtumat
-  label_tracker_new: Uusi tapahtuma
-  label_workflow: TyÃ¶nkulku
-  label_issue_status: Tapahtuman tila
-  label_issue_status_plural: Tapahtumien tilat
-  label_issue_status_new: Uusi tila
-  label_issue_category: Tapahtumaluokka
-  label_issue_category_plural: Tapahtumaluokat
-  label_issue_category_new: Uusi luokka
-  label_custom_field: RÃ¤Ã¤tÃ¤lÃ¶ity kenttÃ¤
-  label_custom_field_plural: RÃ¤Ã¤tÃ¤lÃ¶idyt kentÃ¤t
-  label_custom_field_new: Uusi rÃ¤Ã¤tÃ¤lÃ¶ity kenttÃ¤
-  label_enumerations: Lista
-  label_enumeration_new: Uusi arvo
-  label_information: Tieto
-  label_information_plural: Tiedot
-  label_please_login: Kirjaudu ole hyvÃ¤
-  label_register: RekisterÃ¶idy
-  label_password_lost: Hukattu salasana
-  label_home: Koti
-  label_my_page: Omasivu
-  label_my_account: Oma tili
-  label_my_projects: Omat projektit
-  label_administration: YllÃ¤pito
-  label_login: Kirjaudu sisÃ¤Ã¤n
-  label_logout: Kirjaudu ulos
-  label_help: Ohjeet
-  label_reported_issues: Raportoidut tapahtumat
-  label_assigned_to_me_issues: Minulle nimetyt tapahtumat
-  label_last_login: Viimeinen yhteys
-  label_registered_on: RekisterÃ¶ity
-  label_activity: Historia
-  label_new: Uusi
-  label_logged_as: Kirjauduttu nimellÃ¤
-  label_environment: YmpÃ¤ristÃ¶
-  label_authentication: Varmennus
-  label_auth_source: Varmennustapa
-  label_auth_source_new: Uusi varmennustapa
-  label_auth_source_plural: Varmennustavat
-  label_subproject_plural: Aliprojektit
-  label_min_max_length: Min - Max pituudet
-  label_list: Lista
-  label_date: PÃ¤ivÃ¤
-  label_integer: Kokonaisluku
-  label_float: Liukuluku
-  label_boolean: Totuusarvomuuttuja
-  label_string: Merkkijono
-  label_text: PitkÃ¤ merkkijono
-  label_attribute: MÃ¤Ã¤re
-  label_attribute_plural: MÃ¤Ã¤reet
-  label_download: "%{count} Lataus"
-  label_download_plural: "%{count} Lataukset"
-  label_no_data: Ei tietoa nÃ¤ytettÃ¤vÃ¤ksi
-  label_change_status: Muutos tila
-  label_history: Historia
-  label_attachment: Tiedosto
-  label_attachment_new: Uusi tiedosto
-  label_attachment_delete: Poista tiedosto
-  label_attachment_plural: Tiedostot
-  label_report: Raportti
-  label_report_plural: Raportit
-  label_news: Uutinen
-  label_news_new: LisÃ¤Ã¤ uutinen
-  label_news_plural: Uutiset
-  label_news_latest: ViimeisimmÃ¤t uutiset
-  label_news_view_all: NÃ¤ytÃ¤ kaikki uutiset
-  label_settings: Asetukset
-  label_overview: Yleiskatsaus
-  label_version: Versio
-  label_version_new: Uusi versio
-  label_version_plural: Versiot
-  label_confirmation: Vahvistus
-  label_export_to: Vie
-  label_read: Lukee...
-  label_public_projects: Julkiset projektit
-  label_open_issues: avoin, yhteensÃ¤
-  label_open_issues_plural: avointa, yhteensÃ¤
-  label_closed_issues: suljettu
-  label_closed_issues_plural: suljettua
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_total: YhteensÃ¤
-  label_permissions: Oikeudet
-  label_current_status: Nykyinen tila
-  label_new_statuses_allowed: Uudet tilat sallittu
-  label_all: kaikki
-  label_none: ei mitÃ¤Ã¤n
-  label_nobody: ei kukaan
-  label_next: Seuraava
-  label_previous: Edellinen
-  label_used_by: KÃ¤ytetty
-  label_details: Yksityiskohdat
-  label_add_note: LisÃ¤Ã¤ muistiinpano
-  label_per_page: Per sivu
-  label_calendar: Kalenteri
-  label_months_from: kuukauden pÃ¤Ã¤ssÃ¤
-  label_gantt: Gantt
-  label_internal: SisÃ¤inen
-  label_last_changes: "viimeiset %{count} muutokset"
-  label_change_view_all: NÃ¤ytÃ¤ kaikki muutokset
-  label_personalize_page: Personoi tÃ¤mÃ¤ sivu
-  label_comment: Kommentti
-  label_comment_plural: Kommentit
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_comment_add: LisÃ¤Ã¤ kommentti
-  label_comment_added: Kommentti lisÃ¤tty
-  label_comment_delete: Poista kommentti
-  label_query: RÃ¤Ã¤tÃ¤lÃ¶ity haku
-  label_query_plural: RÃ¤Ã¤tÃ¤lÃ¶idyt haut
-  label_query_new: Uusi haku
-  label_filter_add: LisÃ¤Ã¤ suodatin
-  label_filter_plural: Suodattimet
-  label_equals: sama kuin
-  label_not_equals: eri kuin
-  label_in_less_than: pienempi kuin
-  label_in_more_than: suurempi kuin
-  label_today: tÃ¤nÃ¤Ã¤n
-  label_this_week: tÃ¤llÃ¤ viikolla
-  label_less_than_ago: vÃ¤hemmÃ¤n kuin pÃ¤ivÃ¤Ã¤ sitten
-  label_more_than_ago: enemÃ¤n kuin pÃ¤ivÃ¤Ã¤ sitten
-  label_ago: pÃ¤iviÃ¤ sitten
-  label_contains: sisÃ¤ltÃ¤Ã¤
-  label_not_contains: ei sisÃ¤llÃ¤
-  label_day_plural: pÃ¤ivÃ¤Ã¤
-  label_repository: Tietovarasto
-  label_repository_plural: Tietovarastot
-  label_browse: Selaus
-  label_modification: "%{count} muutos"
-  label_modification_plural: "%{count} muutettu"
-  label_revision: Versio
-  label_revision_plural: Versiot
-  label_added: lisÃ¤tty
-  label_modified: muokattu
-  label_deleted: poistettu
-  label_latest_revision: Viimeisin versio
-  label_latest_revision_plural: ViimeisimmÃ¤t versiot
-  label_view_revisions: NÃ¤ytÃ¤ versiot
-  label_max_size: Suurin koko
-  label_sort_highest: SiirrÃ¤ ylimmÃ¤iseksi
-  label_sort_higher: SiirrÃ¤ ylÃ¶s
-  label_sort_lower: SiirrÃ¤ alas
-  label_sort_lowest: SiirrÃ¤ alimmaiseksi
-  label_roadmap: Roadmap
-  label_roadmap_due_in: "MÃ¤Ã¤rÃ¤aika %{value}"
-  label_roadmap_overdue: "%{value} myÃ¶hÃ¤ssÃ¤"
-  label_roadmap_no_issues: Ei tapahtumia tÃ¤lle versiolle
-  label_search: Haku
-  label_result_plural: Tulokset
-  label_all_words: kaikki sanat
-  label_wiki: Wiki
-  label_wiki_edit: Wiki muokkaus
-  label_wiki_edit_plural: Wiki muokkaukset
-  label_wiki_page: Wiki sivu
-  label_wiki_page_plural: Wiki sivut
-  label_index_by_title: Hakemisto otsikoittain
-  label_index_by_date: Hakemisto pÃ¤ivittÃ¤in
-  label_current_version: Nykyinen versio
-  label_preview: Esikatselu
-  label_feed_plural: SyÃ¶tteet
-  label_changes_details: Kaikkien muutosten yksityiskohdat
-  label_issue_tracking: Tapahtumien seuranta
-  label_spent_time: KÃ¤ytetty aika
-  label_f_hour: "%{value} tunti"
-  label_f_hour_plural: "%{value} tuntia"
-  label_time_tracking: Ajan seuranta
-  label_change_plural: Muutokset
-  label_statistics: Tilastot
-  label_commits_per_month: Tapahtumaa per kuukausi
-  label_commits_per_author: Tapahtumaa per tekijÃ¤
-  label_view_diff: NÃ¤ytÃ¤ erot
-  label_diff_inline: sisÃ¤llÃ¶ssÃ¤
-  label_diff_side_by_side: vierekkÃ¤in
-  label_options: Valinnat
-  label_copy_workflow_from: Kopioi tyÃ¶nkulku
-  label_permissions_report: Oikeuksien raportti
-  label_watched_issues: Seurattavat tapahtumat
-  label_related_issues: LiittyvÃ¤t tapahtumat
-  label_applied_status: LisÃ¤tty tila
-  label_loading: Lataa...
-  label_relation_new: Uusi suhde
-  label_relation_delete: Poista suhde
-  label_relates_to: liittyy
-  label_duplicates: kopio
-  label_blocks: estÃ¤Ã¤
-  label_blocked_by: estetty
-  label_precedes: edeltÃ¤Ã¤
-  label_follows: seuraa
-  label_end_to_start: lopusta alkuun
-  label_end_to_end: lopusta loppuun
-  label_start_to_start: alusta alkuun
-  label_start_to_end: alusta loppuun
-  label_stay_logged_in: Pysy kirjautuneena
-  label_disabled: poistettu kÃ¤ytÃ¶stÃ¤
-  label_show_completed_versions: NÃ¤ytÃ¤ valmiit versiot
-  label_me: minÃ¤
-  label_board: Keskustelupalsta
-  label_board_new: Uusi keskustelupalsta
-  label_board_plural: Keskustelupalstat
-  label_topic_plural: Aiheet
-  label_message_plural: Viestit
-  label_message_last: Viimeisin viesti
-  label_message_new: Uusi viesti
-  label_reply_plural: Vastaukset
-  label_send_information: LÃ¤hetÃ¤ tilin tiedot kÃ¤yttÃ¤jÃ¤lle
-  label_year: Vuosi
-  label_month: Kuukausi
-  label_week: Viikko
-  label_language_based: Pohjautuen kÃ¤yttÃ¤jÃ¤n kieleen
-  label_sort_by: "Lajittele %{value}"
-  label_send_test_email: LÃ¤hetÃ¤ testi sÃ¤hkÃ¶posti
-  label_feeds_access_key_created_on: "RSS salasana luotiin %{value} sitten"
-  label_module_plural: Moduulit
-  label_added_time_by: "LisÃ¤nnyt %{author} %{age} sitten"
-  label_updated_time: "PÃ¤ivitetty %{value} sitten"
-  label_jump_to_a_project: Siirry projektiin...
-  label_file_plural: Tiedostot
-  label_changeset_plural: MuutosryhmÃ¤t
-  label_default_columns: Vakiosarakkeet
-  label_no_change_option: (Ei muutosta)
-  label_bulk_edit_selected_issues: Perusmuotoile valitut tapahtumat
-  label_theme: Teema
-  label_default: Vakio
-  label_search_titles_only: Hae vain otsikot
-  label_user_mail_option_all: "Kaikista tapahtumista kaikissa projekteistani"
-  label_user_mail_option_selected: "Kaikista tapahtumista vain valitsemistani projekteista..."
-  label_user_mail_no_self_notified: "En halua muistutusta muutoksista joita itse teen"
-  label_registration_activation_by_email: tilin aktivointi sÃ¤hkÃ¶postitse
-  label_registration_manual_activation: tilin aktivointi kÃ¤sin
-  label_registration_automatic_activation: tilin aktivointi automaattisesti
-  label_display_per_page: "Per sivu: %{value}"
-  label_age: IkÃ¤
-  label_change_properties: Vaihda asetuksia
-  label_general: Yleinen
-  
-  button_login: Kirjaudu
-  button_submit: LÃ¤hetÃ¤
-  button_save: Tallenna
-  button_check_all: Valitse kaikki
-  button_uncheck_all: Poista valinnat
-  button_delete: Poista
-  button_create: Luo
-  button_test: Testaa
-  button_edit: Muokkaa
-  button_add: LisÃ¤Ã¤
-  button_change: Muuta
-  button_apply: Ota kÃ¤yttÃ¶Ã¶n
-  button_clear: TyhjÃ¤Ã¤
-  button_lock: Lukitse
-  button_unlock: Vapauta
-  button_download: Lataa
-  button_list: Lista
-  button_view: NÃ¤ytÃ¤
-  button_move: SiirrÃ¤
-  button_back: Takaisin
-  button_cancel: Peruuta
-  button_activate: Aktivoi
-  button_sort: JÃ¤rjestÃ¤
-  button_log_time: Seuraa aikaa
-  button_rollback: Siirry takaisin tÃ¤hÃ¤n versioon
-  button_watch: Seuraa
-  button_unwatch: Ã„lÃ¤ seuraa
-  button_reply: Vastaa
-  button_archive: Arkistoi
-  button_unarchive: Palauta
-  button_reset: Nollaus
-  button_rename: Uudelleen nimeÃ¤
-  button_change_password: Vaihda salasana
-  button_copy: Kopioi
-  button_annotate: LisÃ¤Ã¤ selitys
-  button_update: PÃ¤ivitÃ¤
-  
-  status_active: aktiivinen
-  status_registered: rekisterÃ¶ity
-  status_locked: lukittu
-  
-  text_select_mail_notifications: Valitse tapahtumat joista tulisi lÃ¤hettÃ¤Ã¤ sÃ¤hkÃ¶postimuistutus.
-  text_regexp_info: esim. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 tarkoittaa, ei rajoitusta
-  text_project_destroy_confirmation: Oletko varma ettÃ¤ haluat poistaa tÃ¤mÃ¤n projektin ja kaikki siihen kuuluvat tiedot?
-  text_workflow_edit: Valitse rooli ja tapahtuma muokataksesi tyÃ¶nkulkua
-  text_are_you_sure: Oletko varma?
-  text_tip_issue_begin_day: tehtÃ¤vÃ¤ joka alkaa tÃ¤nÃ¤ pÃ¤ivÃ¤nÃ¤
-  text_tip_issue_end_day: tehtÃ¤vÃ¤ joka loppuu tÃ¤nÃ¤ pÃ¤ivÃ¤nÃ¤
-  text_tip_issue_begin_end_day: tehtÃ¤vÃ¤ joka alkaa ja loppuu tÃ¤nÃ¤ pÃ¤ivÃ¤nÃ¤
-  text_project_identifier_info: 'Pienet kirjaimet (a-z), numerot ja viivat ovat sallittu.<br />Tallentamisen jÃ¤lkeen tunnistetta ei voi muuttaa.'
-  text_caracters_maximum: "%{count} merkkiÃ¤ enintÃ¤Ã¤n."
-  text_caracters_minimum: "TÃ¤ytyy olla vÃ¤hintÃ¤Ã¤n %{count} merkkiÃ¤ pitkÃ¤."
-  text_length_between: "Pituus vÃ¤lillÃ¤ %{min} ja %{max} merkkiÃ¤."
-  text_tracker_no_workflow: TyÃ¶nkulkua ei mÃ¤Ã¤ritelty tÃ¤lle tapahtumalle
-  text_unallowed_characters: KiellettyjÃ¤ merkkejÃ¤
-  text_comma_separated: Useat arvot sallittu (pilkku eroteltuna).
-  text_issues_ref_in_commit_messages: LiitÃ¤n ja korjaan ongelmia syÃ¶tetyssÃ¤ viestissÃ¤
-  text_issue_added: "Issue %{id} has been reported by %{author}."
-  text_issue_updated: "Issue %{id} has been updated by %{author}."
-  text_wiki_destroy_confirmation: Oletko varma ettÃ¤ haluat poistaa tÃ¤mÃ¤n wiki:n ja kaikki sen sisÃ¤ltÃ¤mÃ¤n tiedon?
-  text_issue_category_destroy_question: "Jotkut tapahtumat (%{count}) ovat nimetty tÃ¤lle luokalle. MitÃ¤ haluat tehdÃ¤?"
-  text_issue_category_destroy_assignments: Poista luokan tehtÃ¤vÃ¤t
-  text_issue_category_reassign_to: Vaihda tapahtuma tÃ¤hÃ¤n luokkaan
-  text_user_mail_option: "Valitsemattomille projekteille, saat vain muistutuksen asioista joita seuraat tai olet mukana (esim. tapahtumat joissa olet tekijÃ¤ tai nimettynÃ¤)."
-  text_no_configuration_data: "Rooleja, tapahtumien tiloja ja tyÃ¶nkulkua ei vielÃ¤ olla mÃ¤Ã¤ritelty.\nOn erittÃ¤in suotavaa ladata vakioasetukset. Voit muuttaa sitÃ¤ latauksen jÃ¤lkeen."
-  text_load_default_configuration: Lataa vakioasetukset
-  
-  default_role_manager: PÃ¤Ã¤likkÃ¶
-  default_role_developer: KehittÃ¤jÃ¤
-  default_role_reporter: Tarkastelija
-  default_tracker_bug: Ohjelmointivirhe
-  default_tracker_feature: Ominaisuus
-  default_tracker_support: Tuki
-  default_issue_status_new: Uusi
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: HyvÃ¤ksytty
-  default_issue_status_feedback: Palaute
-  default_issue_status_closed: Suljettu
-  default_issue_status_rejected: HylÃ¤tty
-  default_doc_category_user: KÃ¤yttÃ¤jÃ¤ dokumentaatio
-  default_doc_category_tech: Tekninen dokumentaatio
-  default_priority_low: Matala
-  default_priority_normal: Normaali
-  default_priority_high: Korkea
-  default_priority_urgent: Kiireellinen
-  default_priority_immediate: ValitÃ¶n
-  default_activity_design: Suunnittelu
-  default_activity_development: Kehitys
-  
-  enumeration_issue_priorities: Tapahtuman tÃ¤rkeysjÃ¤rjestys
-  enumeration_doc_categories: Dokumentin luokat
-  enumeration_activities: Historia (ajan seuranta)
-  label_associated_revisions: LiittyvÃ¤t versiot
-  setting_user_format: KÃ¤yttÃ¤jien esitysmuoto
-  text_status_changed_by_changeset: "PÃ¤ivitetty muutosversioon %{value}."
-  text_issues_destroy_confirmation: 'Oletko varma ettÃ¤ haluat poistaa valitut tapahtumat ?'
-  label_more: LisÃ¤Ã¤
-  label_issue_added: Tapahtuma lisÃ¤tty
-  label_issue_updated: Tapahtuma pÃ¤ivitetty
-  label_document_added: Dokumentti lisÃ¤tty
-  label_message_posted: Viesti lisÃ¤tty
-  label_file_added: Tiedosto lisÃ¤tty
-  label_scm: SCM
-  text_select_project_modules: 'Valitse modulit jotka haluat kÃ¤yttÃ¶Ã¶n tÃ¤hÃ¤n projektiin:'
-  label_news_added: Uutinen lisÃ¤tty
-  project_module_boards: Keskustelupalsta
-  project_module_issue_tracking: Tapahtuman seuranta
-  project_module_wiki: Wiki
-  project_module_files: Tiedostot
-  project_module_documents: Dokumentit
-  project_module_repository: Tietovarasto
-  project_module_news: Uutiset
-  project_module_time_tracking: Ajan seuranta
-  text_file_repository_writable: Kirjoitettava tiedostovarasto
-  text_default_administrator_account_changed: Vakio hallinoijan tunnus muutettu
-  text_rmagick_available: RMagick saatavilla (valinnainen)
-  button_configure: Asetukset
-  label_plugins: LisÃ¤osat
-  label_ldap_authentication: LDAP tunnistautuminen
-  label_downloads_abbr: D/L
-  label_add_another_file: LisÃ¤Ã¤ uusi tiedosto
-  label_this_month: tÃ¤ssÃ¤ kuussa
-  text_destroy_time_entries_question: "%{hours} tuntia on raportoitu tapahtumasta jonka aiot poistaa. MitÃ¤ haluat tehdÃ¤ ?"
-  label_last_n_days: "viimeiset %{count} pÃ¤ivÃ¤Ã¤"
-  label_all_time: koko ajalta
-  error_issue_not_found_in_project: 'Tapahtumaa ei lÃ¶ytynyt tai se ei kuulu tÃ¤hÃ¤n projektiin'
-  label_this_year: tÃ¤nÃ¤ vuonna
-  text_assign_time_entries_to_project: MÃ¤Ã¤ritÃ¤ tunnit projektille
-  label_date_range: AikavÃ¤li
-  label_last_week: viime viikolla
-  label_yesterday: eilen
-  label_optional_description: LisÃ¤kuvaus
-  label_last_month: viime kuussa
-  text_destroy_time_entries: Poista raportoidut tunnit
-  text_reassign_time_entries: 'SiirrÃ¤ raportoidut tunnit tÃ¤lle tapahtumalle:'
-  label_chronological_order: AikajÃ¤rjestyksessÃ¤
-  label_date_to: ''
-  setting_activity_days_default: PÃ¤ivien esittÃ¤minen projektien historiassa
-  label_date_from: ''
-  label_in: ''
-  setting_display_subprojects_issues: NÃ¤ytÃ¤ aliprojektien tapahtumat pÃ¤Ã¤projektissa oletusarvoisesti
-  field_comments_sorting: NÃ¤ytÃ¤ kommentit
-  label_reverse_chronological_order: KÃ¤Ã¤nteisessÃ¤ aikajÃ¤rjestyksessÃ¤
-  label_preferences: Asetukset
-  setting_default_projects_public: Uudet projektit ovat oletuksena julkisia
-  label_overall_activity: Kokonaishistoria
-  error_scm_annotate: "MerkintÃ¤Ã¤ ei ole tai siihen ei voi lisÃ¤tÃ¤ selityksiÃ¤."
-  label_planning: Suunnittelu
-  text_subprojects_destroy_warning: "TÃ¤mÃ¤n aliprojekti(t): %{value} tullaan myÃ¶s poistamaan."
-  label_and_its_subprojects: "%{value} ja aliprojektit"
-  mail_body_reminder: "%{count} sinulle nimettyÃ¤ tapahtuma(a) erÃ¤Ã¤ntyy %{days} pÃ¤ivÃ¤ sisÃ¤Ã¤n:"
-  mail_subject_reminder: "%{count} tapahtuma(a) erÃ¤Ã¤ntyy %{days} lÃ¤hipÃ¤ivinÃ¤"
-  text_user_wrote: "%{value} kirjoitti:"
-  label_duplicated_by: kopioinut
-  setting_enabled_scm: Versionhallinta kÃ¤ytettÃ¤vissÃ¤
-  text_enumeration_category_reassign_to: 'SiirrÃ¤ tÃ¤ksi arvoksi:'
-  text_enumeration_destroy_question: "%{count} kohdetta on sijoitettu tÃ¤lle arvolle."
-  label_incoming_emails: Saapuvat sÃ¤hkÃ¶postiviestit
-  label_generate_key: Luo avain
-  setting_mail_handler_api_enabled: Ota kÃ¤yttÃ¶Ã¶n WS saapuville sÃ¤hkÃ¶posteille
-  setting_mail_handler_api_key: API avain
-  text_email_delivery_not_configured: "SÃ¤hkÃ¶postin jakelu ei ole mÃ¤Ã¤ritelty ja sÃ¤hkÃ¶postimuistutukset eivÃ¤t ole kÃ¤ytÃ¶ssÃ¤.\nKonfiguroi sÃ¤hkÃ¶postipalvelinasetukset (SMTP) config/configuration.yml tiedostosta ja uudelleenkÃ¤ynnistÃ¤ sovellus jotta asetukset astuvat voimaan."
-  field_parent_title: Aloitussivu
-  label_issue_watchers: Tapahtuman seuraajat
-  button_quote: Vastaa
-  setting_sequential_project_identifiers: Luo perÃ¤kkÃ¤iset projektien tunnisteet
-  notice_unable_delete_version: Version poisto epÃ¤onnistui
-  label_renamed: uudelleennimetty
-  label_copied: kopioitu
-  setting_plain_text_mail: vain muotoilematonta tekstiÃ¤ (ei HTML)
-  permission_view_files: NÃ¤ytÃ¤ tiedostot
-  permission_edit_issues: Muokkaa tapahtumia
-  permission_edit_own_time_entries: Muokka omia aikamerkintÃ¶jÃ¤
-  permission_manage_public_queries: Hallinnoi julkisia hakuja
-  permission_add_issues: LisÃ¤Ã¤ tapahtumia
-  permission_log_time: Lokita kÃ¤ytettyÃ¤ aikaa
-  permission_view_changesets: NÃ¤ytÃ¤ muutosryhmÃ¤t
-  permission_view_time_entries: NÃ¤ytÃ¤ kÃ¤ytetty aika
-  permission_manage_versions: Hallinnoi versioita
-  permission_manage_wiki: Hallinnoi wikiÃ¤
-  permission_manage_categories: Hallinnoi tapahtumien luokkia
-  permission_protect_wiki_pages: Suojaa wiki sivut
-  permission_comment_news: Kommentoi uutisia
-  permission_delete_messages: Poista viestit
-  permission_select_project_modules: Valitse projektin modulit
-  permission_manage_documents: Hallinnoi dokumentteja
-  permission_edit_wiki_pages: Muokkaa wiki sivuja
-  permission_add_issue_watchers: LisÃ¤Ã¤ seuraajia
-  permission_view_gantt: NÃ¤ytÃ¤ gantt kaavio
-  permission_move_issues: SiirrÃ¤ tapahtuma
-  permission_manage_issue_relations: Hallinoi tapahtuman suhteita
-  permission_delete_wiki_pages: Poista wiki sivuja
-  permission_manage_boards: Hallinnoi keskustelupalstaa
-  permission_delete_wiki_pages_attachments: Poista liitteitÃ¤
-  permission_view_wiki_edits: NÃ¤ytÃ¤ wiki historia
-  permission_add_messages: JÃ¤tÃ¤ viesti
-  permission_view_messages: NÃ¤ytÃ¤ viestejÃ¤
-  permission_manage_files: Hallinnoi tiedostoja
-  permission_edit_issue_notes: Muokkaa muistiinpanoja
-  permission_manage_news: Hallinnoi uutisia
-  permission_view_calendar: NÃ¤ytÃ¤ kalenteri
-  permission_manage_members: Hallinnoi jÃ¤seniÃ¤
-  permission_edit_messages: Muokkaa viestejÃ¤
-  permission_delete_issues: Poista tapahtumia
-  permission_view_issue_watchers: NÃ¤ytÃ¤ seuraaja lista
-  permission_manage_repository: Hallinnoi tietovarastoa
-  permission_commit_access: Tee pÃ¤Ã¤syoikeus
-  permission_browse_repository: Selaa tietovarastoa
-  permission_view_documents: NÃ¤ytÃ¤ dokumentit
-  permission_edit_project: Muokkaa projektia
-  permission_add_issue_notes: LisÃ¤Ã¤ muistiinpanoja
-  permission_save_queries: Tallenna hakuja
-  permission_view_wiki_pages: NÃ¤ytÃ¤ wiki
-  permission_rename_wiki_pages: UudelleennimeÃ¤ wiki sivuja
-  permission_edit_time_entries: Muokkaa aika lokeja
-  permission_edit_own_issue_notes: Muokkaa omia muistiinpanoja
-  setting_gravatar_enabled: KÃ¤ytÃ¤ Gravatar kÃ¤yttÃ¤jÃ¤ ikoneita
-  label_example: Esimerkki
-  text_repository_usernames_mapping: "Valitse pÃ¤ivittÃ¤Ã¤ksesi Redmine kÃ¤yttÃ¤jÃ¤ jokaiseen kÃ¤yttÃ¤jÃ¤Ã¤n joka lÃ¶ytyy tietovaraston lokista.\nKÃ¤yttÃ¤jÃ¤t joilla on sama Redmine ja tietovaraston kÃ¤yttÃ¤jÃ¤nimi tai sÃ¤hkÃ¶postiosoite, yhdistetÃ¤Ã¤n automaattisesti."
-  permission_edit_own_messages: Muokkaa omia viestejÃ¤
-  permission_delete_own_messages: Poista omia viestejÃ¤
-  label_user_activity: "KÃ¤yttÃ¤jÃ¤n %{value} historia"
-  label_updated_time_by: "Updated by %{author} %{age} ago"
-  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
-  setting_diff_max_lines_displayed: Max number of diff lines displayed
-  text_plugin_assets_writable: Plugin assets directory writable
-  warning_attachments_not_saved: "%{count} file(s) could not be saved."
-  button_create_and_continue: Create and continue
-  text_custom_field_possible_values_info: 'One line for each value'
-  label_display: Display
-  field_editable: Editable
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  field_watcher: Watcher
-  setting_openid: Allow OpenID login and registration
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: or login with OpenID
-  field_content: Content
-  label_descending: Descending
-  label_sort: Sort
-  label_ascending: Ascending
-  label_date_from_to: From %{start} to %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
-  text_wiki_page_reassign_children: Reassign child pages to this parent page
-  text_wiki_page_nullify_children: Keep child pages as root pages
-  text_wiki_page_destroy_children: Delete child pages and all their descendants
-  setting_password_min_length: Minimum password length
-  field_group_by: Group results by
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  label_wiki_content_added: Wiki page added
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
-  label_wiki_content_updated: Wiki page updated
-  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
-  permission_add_project: Create project
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  label_view_all_revisions: View all revisions
-  label_tag: Tag
-  label_branch: Branch
-  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
-  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
-  text_journal_changed: "%{label} changed from %{old} to %{new}"
-  text_journal_set_to: "%{label} set to %{value}"
-  text_journal_deleted: "%{label} deleted (%{old})"
-  label_group_plural: Groups
-  label_group: Group
-  label_group_new: New group
-  label_time_entry_plural: Spent time
-  text_journal_added: "%{label} %{value} added"
-  field_active: Active
-  enumeration_system_activity: System Activity
-  permission_delete_issue_watchers: Delete watchers
-  version_status_closed: closed
-  version_status_locked: locked
-  version_status_open: open
-  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
-  label_user_anonymous: Anonymous
-  button_move_and_follow: Move and follow
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_gravatar_default: Default Gravatar image
-  field_sharing: Sharing
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_system: With all projects
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_tree: With project tree
-  label_version_sharing_none: Not shared
-  error_can_not_archive_project: This project can not be archived
-  button_duplicate: Duplicate
-  button_copy_and_follow: Copy and follow
-  label_copy_source: Source
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Same as target
-  label_copy_target: Target
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  error_workflow_copy_source: Please select a source tracker or role
-  label_update_issue_done_ratios: Update issue done ratios
-  setting_start_of_week: Start calendars on
-  permission_view_issues: View Issues
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API access key
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_missing_api_access_key: Missing an API access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  button_show: Show
-  text_line_separated: Multiple values allowed (one line for each value).
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Tee viestien koodaus
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e503a43fce804a351af87e02ff0079c3add37355.svn-base
--- a/.svn/pristine/e5/e503a43fce804a351af87e02ff0079c3add37355.svn-base
+++ /dev/null
@@ -1,1 +0,0 @@
-the implicit plaintext part of the email
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e50a761d62eea449ace86c3d71d1d450b464aa81.svn-base
--- a/.svn/pristine/e5/e50a761d62eea449ace86c3d71d1d450b464aa81.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Niedziela",
- "PoniedziaÅ‚ek",
- "Wtorek",
- "Åšroda",
- "Czwartek",
- "PiÄ…tek",
- "Sobota",
- "Niedziela");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Nie",
- "Pon",
- "Wto",
- "Åšro",
- "Czw",
- "PiÄ…",
- "Sob",
- "Nie");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("StyczeÅ„",
- "Luty",
- "Marzec",
- "KwiecieÅ„",
- "Maj",
- "Czerwiec",
- "Lipiec",
- "SierpieÅ„",
- "WrzesieÅ„",
- "PaÅºdziernik",
- "Listopad",
- "GrudzieÅ„");
-
-// short month names
-Calendar._SMN = new Array
-("Sty",
- "Lut",
- "Mar",
- "Kwi",
- "Maj",
- "Cze",
- "Lip",
- "Sie",
- "Wrz",
- "PaÅº",
- "Lis",
- "Gru");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "O kalendarzu";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"Po ostatniÄ… wersjÄ™ odwiedÅº: http://www.dynarch.com/projects/calendar/\n" +
-"Rozpowszechniany pod licencjÄ… GNU LGPL.  Zobacz: http://gnu.org/licenses/lgpl.html z celu zapoznania siÄ™ ze szczegÃ³Å‚ami." +
-"\n\n" +
-"WybÃ³r daty:\n" +
-"- UÅ¼yj \xab, \xbb przyciskÃ³w by zaznaczyÄ‡ rok\n" +
-"- UÅ¼yj " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " przyciskÃ³w by zaznaczyÄ‡ miesiÄ…c\n" +
-"- Trzymaj wciÅ›niÄ™ty przycisk myszy na kaÅ¼dym z powyÅ¼szych przyciskÃ³w by przyÅ›pieszyÄ‡ zaznaczanie.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"WybÃ³r czasu:\n" +
-"- Kliknij na kaÅ¼dym przedziale czasu aby go powiÄ™kszyÄ‡\n" +
-"- lub kliknij z przyciskiem Shift by go zmniejszyÄ‡\n" +
-"- lub kliknij i przeciÄ…gnij dla szybszego zaznaczenia.";
-
-Calendar._TT["PREV_YEAR"] = "Poprz. rok (przytrzymaj dla menu)";
-Calendar._TT["PREV_MONTH"] = "Poprz. miesiÄ…c (przytrzymaj dla menu)";
-Calendar._TT["GO_TODAY"] = "IdÅº do Dzisiaj";
-Calendar._TT["NEXT_MONTH"] = "NastÄ™pny miesiÄ…c(przytrzymaj dla menu)";
-Calendar._TT["NEXT_YEAR"] = "NastÄ™pny rok (przytrzymaj dla menu)";
-Calendar._TT["SEL_DATE"] = "Zaznacz datÄ™";
-Calendar._TT["DRAG_TO_MOVE"] = "PrzeciÄ…gnij by przenieÅ›Ä‡";
-Calendar._TT["PART_TODAY"] = " (dzisiaj)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "PokaÅ¼ %s pierwszy";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Zamknij";
-Calendar._TT["TODAY"] = "Dzisiaj";
-Calendar._TT["TIME_PART"] = "(Shift-)Kliknij lub upuÅ›Ä‡ by zmieniÄ‡ wartoÅ›Ä‡";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%R-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Czas:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e54ebef30cd91954813654717934375e733126f9.svn-base
--- a/.svn/pristine/e5/e54ebef30cd91954813654717934375e733126f9.svn-base
+++ /dev/null
@@ -1,50 +0,0 @@
-<% fields_for :issue, @issue, :builder => TabularFormBuilder do |f| %>
-
-<div class="splitcontentleft">
-<% if @issue.new_record? || @allowed_statuses.any? %>
-<p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
-<% else %>
-<p><label><%= l(:field_status) %></label> <%= h(@issue.status.name) %></p>
-<% end %>
-
-<p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), {:required => true}, :disabled => !@issue.leaf? %></p>
-<p><%= f.select :assigned_to_id, principals_options_for_select(@issue.assignable_users, @issue.assigned_to), :include_blank => true %></p>
-<% unless @project.issue_categories.empty? %>
-<p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
-<%= prompt_to_remote(image_tag('add.png', :style => 'vertical-align: middle;'),
-                     l(:label_issue_category_new),
-                     'issue_category[name]',
-                     {:controller => 'issue_categories', :action => 'create', :project_id => @project},
-                     :title => l(:label_issue_category_new),
-                     :tabindex => 199) if authorize_for('issue_categories', 'new') %></p>
-<% end %>
-<% unless @issue.assignable_versions.empty? %>
-<p><%= f.select :fixed_version_id, version_options_for_select(@issue.assignable_versions, @issue.fixed_version), :include_blank => true %>
-<%= prompt_to_remote(image_tag('add.png', :style => 'vertical-align: middle;'),
-                     l(:label_version_new),
-                     'version[name]',
-                     {:controller => 'versions', :action => 'create', :project_id => @project},
-                     :title => l(:label_version_new),
-                     :tabindex => 200) if authorize_for('versions', 'new') %>
-</p>
-<% end %>
-</div>
-
-<div class="splitcontentright">
-<% if User.current.allowed_to?(:manage_subtasks, @project) %>
-<p id="parent_issue"><%= f.text_field :parent_issue_id, :size => 10 %></p>
-<div id="parent_issue_candidates" class="autocomplete"></div>
-<%= javascript_tag "observeParentIssueField('#{auto_complete_issues_path(:id => @issue, :project_id => @project) }')" %>
-<% end %>
-<p><%= f.text_field :start_date, :size => 10, :disabled => !@issue.leaf? %><%= calendar_for('issue_start_date') if @issue.leaf? %></p>
-<p><%= f.text_field :due_date, :size => 10, :disabled => !@issue.leaf? %><%= calendar_for('issue_due_date') if @issue.leaf? %></p>
-<p><%= f.text_field :estimated_hours, :size => 3, :disabled => !@issue.leaf? %> <%= l(:field_hours) %></p>
-<% if @issue.leaf? && Issue.use_field_for_done_ratio? %>
-<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
-<% end %>
-</div>
-
-<div style="clear:both;"> </div>
-<%= render :partial => 'issues/form_custom_fields' %>
-
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e57df997ff48c90646e41377ffe484e755bccea7.svn-base
--- a/.svn/pristine/e5/e57df997ff48c90646e41377ffe484e755bccea7.svn-base
+++ /dev/null
@@ -1,27 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class IssueCustomField < CustomField
-  has_and_belongs_to_many :projects, :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :foreign_key => "custom_field_id"
-  has_and_belongs_to_many :trackers, :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :foreign_key => "custom_field_id"
-  has_many :issues, :through => :issue_custom_values
-
-  def type_name
-    :label_issue_plural
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e57e448ff5e398f985d2656f35e0c4f0db003780.svn-base
--- /dev/null
+++ b/.svn/pristine/e5/e57e448ff5e398f985d2656f35e0c4f0db003780.svn-base
@@ -0,0 +1,106 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingGroupsTest < ActionController::IntegrationTest
+  def test_groups_resources
+    assert_routing(
+        { :method => 'get', :path => "/groups" },
+        { :controller => 'groups', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/groups.xml" },
+        { :controller => 'groups', :action => 'index', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/groups" },
+        { :controller => 'groups', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/groups.xml" },
+        { :controller => 'groups', :action => 'create', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/groups/new" },
+        { :controller => 'groups', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/groups/1/edit" },
+        { :controller => 'groups', :action => 'edit', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/groups/1/autocomplete_for_user" },
+        { :controller => 'groups', :action => 'autocomplete_for_user', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/groups/1/autocomplete_for_user.js" },
+        { :controller => 'groups', :action => 'autocomplete_for_user', :id => '1', :format => 'js' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/groups/1" },
+        { :controller => 'groups', :action => 'show', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/groups/1.xml" },
+        { :controller => 'groups', :action => 'show', :id => '1', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/groups/1" },
+        { :controller => 'groups', :action => 'update', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/groups/1.xml" },
+        { :controller => 'groups', :action => 'update', :id => '1', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/groups/1" },
+        { :controller => 'groups', :action => 'destroy', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/groups/1.xml" },
+        { :controller => 'groups', :action => 'destroy', :id => '1', :format => 'xml' }
+      )
+  end
+
+  def test_groups
+    assert_routing(
+        { :method => 'post', :path => "/groups/567/users" },
+        { :controller => 'groups', :action => 'add_users', :id => '567' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/groups/567/users.xml" },
+        { :controller => 'groups', :action => 'add_users', :id => '567', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/groups/567/users/12" },
+        { :controller => 'groups', :action => 'remove_user', :id => '567', :user_id => '12' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/groups/567/users/12.xml" },
+        { :controller => 'groups', :action => 'remove_user', :id => '567', :user_id => '12', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/groups/destroy_membership/567" },
+        { :controller => 'groups', :action => 'destroy_membership', :id => '567' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/groups/edit_membership/567" },
+        { :controller => 'groups', :action => 'edit_membership', :id => '567' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e58c2b42a5313477b70486289636b96261ea464c.svn-base
--- a/.svn/pristine/e5/e58c2b42a5313477b70486289636b96261ea464c.svn-base
+++ /dev/null
@@ -1,209 +0,0 @@
-class TimeEntryReportsController < ApplicationController
-  menu_item :issues
-  before_filter :find_optional_project
-  before_filter :load_available_criterias
-
-  helper :sort
-  include SortHelper
-  helper :issues
-  helper :timelog
-  include TimelogHelper
-  helper :custom_fields
-  include CustomFieldsHelper
-
-  def report
-    @criterias = params[:criterias] || []
-    @criterias = @criterias.select{|criteria| @available_criterias.has_key? criteria}
-    @criterias.uniq!
-    @criterias = @criterias[0,3]
-
-    @columns = (params[:columns] && %w(year month week day).include?(params[:columns])) ? params[:columns] : 'month'
-
-    retrieve_date_range
-
-    unless @criterias.empty?
-      sql_select = @criterias.collect{|criteria| @available_criterias[criteria][:sql] + " AS " + criteria}.join(', ')
-      sql_group_by = @criterias.collect{|criteria| @available_criterias[criteria][:sql]}.join(', ')
-      sql_condition = ''
-
-      if @project.nil?
-        sql_condition = Project.allowed_to_condition(User.current, :view_time_entries)
-      elsif @issue.nil?
-        sql_condition = @project.project_condition(Setting.display_subprojects_issues?)
-      else
-        sql_condition = "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}"
-      end
-
-      sql = "SELECT #{sql_select}, tyear, tmonth, tweek, spent_on, SUM(hours) AS hours"
-      sql << " FROM #{TimeEntry.table_name}"
-      sql << time_report_joins
-      sql << " WHERE"
-      sql << " (%s) AND" % sql_condition
-      sql << " (spent_on BETWEEN '%s' AND '%s')" % [ActiveRecord::Base.connection.quoted_date(@from), ActiveRecord::Base.connection.quoted_date(@to)]
-      sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek, spent_on"
-
-      @hours = ActiveRecord::Base.connection.select_all(sql)
-
-      @hours.each do |row|
-        case @columns
-        when 'year'
-          row['year'] = row['tyear']
-        when 'month'
-          row['month'] = "#{row['tyear']}-#{row['tmonth']}"
-        when 'week'
-          row['week'] = "#{row['tyear']}-#{row['tweek']}"
-        when 'day'
-          row['day'] = "#{row['spent_on']}"
-        end
-      end
-
-      @total_hours = @hours.inject(0) {|s,k| s = s + k['hours'].to_f}
-
-      @periods = []
-      # Date#at_beginning_of_ not supported in Rails 1.2.x
-      date_from = @from.to_time
-      # 100 columns max
-      while date_from <= @to.to_time && @periods.length < 100
-        case @columns
-        when 'year'
-          @periods << "#{date_from.year}"
-          date_from = (date_from + 1.year).at_beginning_of_year
-        when 'month'
-          @periods << "#{date_from.year}-#{date_from.month}"
-          date_from = (date_from + 1.month).at_beginning_of_month
-        when 'week'
-          @periods << "#{date_from.year}-#{date_from.to_date.cweek}"
-          date_from = (date_from + 7.day).at_beginning_of_week
-        when 'day'
-          @periods << "#{date_from.to_date}"
-          date_from = date_from + 1.day
-        end
-      end
-    end
-
-    respond_to do |format|
-      format.html { render :layout => !request.xhr? }
-      format.csv  { send_data(report_to_csv(@criterias, @periods, @hours), :type => 'text/csv; header=present', :filename => 'timelog.csv') }
-    end
-  end
-
-  private
-
-  # TODO: duplicated in TimelogController
-  def find_optional_project
-    if !params[:issue_id].blank?
-      @issue = Issue.find(params[:issue_id])
-      @project = @issue.project
-    elsif !params[:project_id].blank?
-      @project = Project.find(params[:project_id])
-    end
-    deny_access unless User.current.allowed_to?(:view_time_entries, @project, :global => true)
-  end
-
-  # Retrieves the date range based on predefined ranges or specific from/to param dates
-  # TODO: duplicated in TimelogController
-  def retrieve_date_range
-    @free_period = false
-    @from, @to = nil, nil
-
-    if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?)
-      case params[:period].to_s
-      when 'today'
-        @from = @to = Date.today
-      when 'yesterday'
-        @from = @to = Date.today - 1
-      when 'current_week'
-        @from = Date.today - (Date.today.cwday - 1)%7
-        @to = @from + 6
-      when 'last_week'
-        @from = Date.today - 7 - (Date.today.cwday - 1)%7
-        @to = @from + 6
-      when '7_days'
-        @from = Date.today - 7
-        @to = Date.today
-      when 'current_month'
-        @from = Date.civil(Date.today.year, Date.today.month, 1)
-        @to = (@from >> 1) - 1
-      when 'last_month'
-        @from = Date.civil(Date.today.year, Date.today.month, 1) << 1
-        @to = (@from >> 1) - 1
-      when '30_days'
-        @from = Date.today - 30
-        @to = Date.today
-      when 'current_year'
-        @from = Date.civil(Date.today.year, 1, 1)
-        @to = Date.civil(Date.today.year, 12, 31)
-      end
-    elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?))
-      begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end
-      begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end
-      @free_period = true
-    else
-      # default
-    end
-
-    @from, @to = @to, @from if @from && @to && @from > @to
-    @from ||= (TimeEntry.earilest_date_for_project(@project) || Date.today)
-    @to   ||= (TimeEntry.latest_date_for_project(@project) || Date.today)
-  end
-
-  def load_available_criterias
-    @available_criterias = { 'project' => {:sql => "#{TimeEntry.table_name}.project_id",
-                                          :klass => Project,
-                                          :label => :label_project},
-                             'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
-                                          :klass => Version,
-                                          :label => :label_version},
-                             'category' => {:sql => "#{Issue.table_name}.category_id",
-                                            :klass => IssueCategory,
-                                            :label => :field_category},
-                             'member' => {:sql => "#{TimeEntry.table_name}.user_id",
-                                         :klass => User,
-                                         :label => :label_member},
-                             'tracker' => {:sql => "#{Issue.table_name}.tracker_id",
-                                          :klass => Tracker,
-                                          :label => :label_tracker},
-                             'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
-                                           :klass => TimeEntryActivity,
-                                           :label => :label_activity},
-                             'issue' => {:sql => "#{TimeEntry.table_name}.issue_id",
-                                         :klass => Issue,
-                                         :label => :label_issue}
-                           }
-
-    # Add list and boolean custom fields as available criterias
-    custom_fields = (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields)
-    custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
-      @available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id)",
-                                             :format => cf.field_format,
-                                             :label => cf.name}
-    end if @project
-
-    # Add list and boolean time entry custom fields
-    TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
-      @available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id)",
-                                             :format => cf.field_format,
-                                             :label => cf.name}
-    end
-
-    # Add list and boolean time entry activity custom fields
-    TimeEntryActivityCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
-      @available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Enumeration' AND c.customized_id = #{TimeEntry.table_name}.activity_id)",
-                                             :format => cf.field_format,
-                                             :label => cf.name}
-    end
-
-    call_hook(:controller_timelog_available_criterias, { :available_criterias => @available_criterias, :project => @project })
-    @available_criterias
-  end
-
-  def time_report_joins
-    sql = ''
-    sql << " LEFT JOIN #{Issue.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id"
-    sql << " LEFT JOIN #{Project.table_name} ON #{TimeEntry.table_name}.project_id = #{Project.table_name}.id"
-    # TODO: rename hook
-    call_hook(:controller_timelog_time_report_joins, {:sql => sql} )
-    sql
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e58ec86b245f3ac57a759399f47d3d6b2bb03a42.svn-base
--- /dev/null
+++ b/.svn/pristine/e5/e58ec86b245f3ac57a759399f47d3d6b2bb03a42.svn-base
@@ -0,0 +1,129 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoryDarcsTest < ActiveSupport::TestCase
+  fixtures :projects
+
+  include Redmine::I18n
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
+  NUM_REV = 6
+
+  def setup
+    @project = Project.find(3)
+    @repository = Repository::Darcs.create(
+                      :project      => @project,
+                      :url          => REPOSITORY_PATH,
+                      :log_encoding => 'UTF-8'
+                      )
+    assert @repository
+  end
+
+  def test_blank_path_to_repository_error_message
+    set_language_if_valid 'en'
+    repo = Repository::Darcs.new(
+                          :project      => @project,
+                          :identifier   => 'test',
+                          :log_encoding => 'UTF-8'
+                        )
+    assert !repo.save
+    assert_include "Path to repository can't be blank",
+                   repo.errors.full_messages
+  end
+
+  def test_blank_path_to_repository_error_message_fr
+    set_language_if_valid 'fr'
+    str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)"
+    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
+    repo = Repository::Darcs.new(
+                          :project      => @project,
+                          :url          => "",
+                          :identifier   => 'test',
+                          :log_encoding => 'UTF-8'
+                        )
+    assert !repo.save
+    assert_include str, repo.errors.full_messages
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    def test_fetch_changesets_from_scratch
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_equal 13, @repository.filechanges.count
+      assert_equal "Initial commit.", @repository.changesets.find_by_revision('1').comments
+    end
+
+    def test_fetch_changesets_incremental
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      # Remove changesets with revision > 3
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 3}
+      @project.reload
+      assert_equal 3, @repository.changesets.count
+
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+    end
+
+    def test_entries
+      entries = @repository.entries
+      assert_kind_of Redmine::Scm::Adapters::Entries, entries
+    end
+
+    def test_entries_invalid_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      assert_nil @repository.entries('', '123')
+    end
+
+    def test_deleted_files_should_not_be_listed
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      entries = @repository.entries('sources')
+      assert entries.detect {|e| e.name == 'watchers_controller.rb'}
+      assert_nil entries.detect {|e| e.name == 'welcome_controller.rb'}
+    end
+
+    def test_cat
+      if @repository.scm.supports_cat?
+        assert_equal 0, @repository.changesets.count
+        @repository.fetch_changesets
+        @project.reload
+        assert_equal NUM_REV, @repository.changesets.count
+        cat = @repository.cat("sources/welcome_controller.rb", 2)
+        assert_not_nil cat
+        assert cat.include?('class WelcomeController < ApplicationController')
+      end
+    end
+  else
+    puts "Darcs test repository NOT FOUND. Skipping unit tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e5c904dde1892f8ff602788f810c1a9ce2872e82.svn-base
--- /dev/null
+++ b/.svn/pristine/e5/e5c904dde1892f8ff602788f810c1a9ce2872e82.svn-base
@@ -0,0 +1,314 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class TimelogController < ApplicationController
+  menu_item :issues
+
+  before_filter :find_project_for_new_time_entry, :only => [:create]
+  before_filter :find_time_entry, :only => [:show, :edit, :update]
+  before_filter :find_time_entries, :only => [:bulk_edit, :bulk_update, :destroy]
+  before_filter :authorize, :except => [:new, :index, :report]
+
+  before_filter :find_optional_project, :only => [:index, :report]
+  before_filter :find_optional_project_for_new_time_entry, :only => [:new]
+  before_filter :authorize_global, :only => [:new, :index, :report]
+
+  accept_rss_auth :index
+  accept_api_auth :index, :show, :create, :update, :destroy
+
+  rescue_from Query::StatementInvalid, :with => :query_statement_invalid
+
+  helper :sort
+  include SortHelper
+  helper :issues
+  include TimelogHelper
+  helper :custom_fields
+  include CustomFieldsHelper
+  helper :queries
+  include QueriesHelper
+
+  def index
+    @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
+    scope = time_entry_scope
+
+    sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria)
+    sort_update(@query.sortable_columns)
+
+    respond_to do |format|
+      format.html {
+        # Paginate results
+        @entry_count = scope.count
+        @entry_pages = Paginator.new @entry_count, per_page_option, params['page']
+        @entries = scope.all(
+          :include => [:project, :activity, :user, {:issue => :tracker}],
+          :order => sort_clause,
+          :limit  =>  @entry_pages.per_page,
+          :offset =>  @entry_pages.offset
+        )
+        @total_hours = scope.sum(:hours).to_f
+
+        render :layout => !request.xhr?
+      }
+      format.api  {
+        @entry_count = scope.count
+        @offset, @limit = api_offset_and_limit
+        @entries = scope.all(
+          :include => [:project, :activity, :user, {:issue => :tracker}],
+          :order => sort_clause,
+          :limit  => @limit,
+          :offset => @offset
+        )
+      }
+      format.atom {
+        entries = scope.all(
+          :include => [:project, :activity, :user, {:issue => :tracker}],
+          :order => "#{TimeEntry.table_name}.created_on DESC",
+          :limit => Setting.feeds_limit.to_i
+        )
+        render_feed(entries, :title => l(:label_spent_time))
+      }
+      format.csv {
+        # Export all entries
+        @entries = scope.all(
+          :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
+          :order => sort_clause
+        )
+        send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv')
+      }
+    end
+  end
+
+  def report
+    @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
+    scope = time_entry_scope
+
+    @report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], scope)
+
+    respond_to do |format|
+      format.html { render :layout => !request.xhr? }
+      format.csv  { send_data(report_to_csv(@report), :type => 'text/csv; header=present', :filename => 'timelog.csv') }
+    end
+  end
+
+  def show
+    respond_to do |format|
+      # TODO: Implement html response
+      format.html { render :nothing => true, :status => 406 }
+      format.api
+    end
+  end
+
+  def new
+    @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
+    @time_entry.safe_attributes = params[:time_entry]
+  end
+
+  def create
+    @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
+    @time_entry.safe_attributes = params[:time_entry]
+
+    call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
+
+    if @time_entry.save
+      respond_to do |format|
+        format.html {
+          flash[:notice] = l(:notice_successful_create)
+          if params[:continue]
+            if params[:project_id]
+              options = {
+                :time_entry => {:issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
+                :back_url => params[:back_url]
+              }
+              if @time_entry.issue
+                redirect_to new_project_issue_time_entry_path(@time_entry.project, @time_entry.issue, options)
+              else
+                redirect_to new_project_time_entry_path(@time_entry.project, options)
+              end
+            else
+              options = {
+                :time_entry => {:project_id => @time_entry.project_id, :issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
+                :back_url => params[:back_url]
+              }
+              redirect_to new_time_entry_path(options)
+            end
+          else
+            redirect_back_or_default project_time_entries_path(@time_entry.project)
+          end
+        }
+        format.api  { render :action => 'show', :status => :created, :location => time_entry_url(@time_entry) }
+      end
+    else
+      respond_to do |format|
+        format.html { render :action => 'new' }
+        format.api  { render_validation_errors(@time_entry) }
+      end
+    end
+  end
+
+  def edit
+    @time_entry.safe_attributes = params[:time_entry]
+  end
+
+  def update
+    @time_entry.safe_attributes = params[:time_entry]
+
+    call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
+
+    if @time_entry.save
+      respond_to do |format|
+        format.html {
+          flash[:notice] = l(:notice_successful_update)
+          redirect_back_or_default project_time_entries_path(@time_entry.project)
+        }
+        format.api  { render_api_ok }
+      end
+    else
+      respond_to do |format|
+        format.html { render :action => 'edit' }
+        format.api  { render_validation_errors(@time_entry) }
+      end
+    end
+  end
+
+  def bulk_edit
+    @available_activities = TimeEntryActivity.shared.active
+    @custom_fields = TimeEntry.first.available_custom_fields
+  end
+
+  def bulk_update
+    attributes = parse_params_for_bulk_time_entry_attributes(params)
+
+    unsaved_time_entry_ids = []
+    @time_entries.each do |time_entry|
+      time_entry.reload
+      time_entry.safe_attributes = attributes
+      call_hook(:controller_time_entries_bulk_edit_before_save, { :params => params, :time_entry => time_entry })
+      unless time_entry.save
+        # Keep unsaved time_entry ids to display them in flash error
+        unsaved_time_entry_ids << time_entry.id
+      end
+    end
+    set_flash_from_bulk_time_entry_save(@time_entries, unsaved_time_entry_ids)
+    redirect_back_or_default project_time_entries_path(@projects.first)
+  end
+
+  def destroy
+    destroyed = TimeEntry.transaction do
+      @time_entries.each do |t|
+        unless t.destroy && t.destroyed?
+          raise ActiveRecord::Rollback
+        end
+      end
+    end
+
+    respond_to do |format|
+      format.html {
+        if destroyed
+          flash[:notice] = l(:notice_successful_delete)
+        else
+          flash[:error] = l(:notice_unable_delete_time_entry)
+        end
+        redirect_back_or_default project_time_entries_path(@projects.first)
+      }
+      format.api  {
+        if destroyed
+          render_api_ok
+        else
+          render_validation_errors(@time_entries)
+        end
+      }
+    end
+  end
+
+private
+  def find_time_entry
+    @time_entry = TimeEntry.find(params[:id])
+    unless @time_entry.editable_by?(User.current)
+      render_403
+      return false
+    end
+    @project = @time_entry.project
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def find_time_entries
+    @time_entries = TimeEntry.find_all_by_id(params[:id] || params[:ids])
+    raise ActiveRecord::RecordNotFound if @time_entries.empty?
+    @projects = @time_entries.collect(&:project).compact.uniq
+    @project = @projects.first if @projects.size == 1
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def set_flash_from_bulk_time_entry_save(time_entries, unsaved_time_entry_ids)
+    if unsaved_time_entry_ids.empty?
+      flash[:notice] = l(:notice_successful_update) unless time_entries.empty?
+    else
+      flash[:error] = l(:notice_failed_to_save_time_entries,
+                        :count => unsaved_time_entry_ids.size,
+                        :total => time_entries.size,
+                        :ids => '#' + unsaved_time_entry_ids.join(', #'))
+    end
+  end
+
+  def find_optional_project_for_new_time_entry
+    if (project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])).present?
+      @project = Project.find(project_id)
+    end
+    if (issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])).present?
+      @issue = Issue.find(issue_id)
+      @project ||= @issue.project
+    end
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def find_project_for_new_time_entry
+    find_optional_project_for_new_time_entry
+    if @project.nil?
+      render_404
+    end
+  end
+
+  def find_optional_project
+    if !params[:issue_id].blank?
+      @issue = Issue.find(params[:issue_id])
+      @project = @issue.project
+    elsif !params[:project_id].blank?
+      @project = Project.find(params[:project_id])
+    end
+  end
+
+  # Returns the TimeEntry scope for index and report actions
+  def time_entry_scope
+    scope = TimeEntry.visible.where(@query.statement)
+    if @issue
+      scope = scope.on_issue(@issue)
+    elsif @project
+      scope = scope.on_project(@project, Setting.display_subprojects_issues?)
+    end
+    scope
+  end
+
+  def parse_params_for_bulk_time_entry_attributes(params)
+    attributes = (params[:time_entry] || {}).reject {|k,v| v.blank?}
+    attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'}
+    attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values]
+    attributes
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e5e737cf1acef41f150245d1f3e14b3ec1313b84.svn-base
--- /dev/null
+++ b/.svn/pristine/e5/e5e737cf1acef41f150245d1f3e14b3ec1313b84.svn-base
@@ -0,0 +1,41 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingGanttsTest < ActionController::IntegrationTest
+  def test_gantts
+    assert_routing(
+        { :method => 'get', :path => "/issues/gantt" },
+        { :controller => 'gantts', :action => 'show' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/gantt.pdf" },
+        { :controller => 'gantts', :action => 'show', :format => 'pdf' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/project-name/issues/gantt" },
+        { :controller => 'gantts', :action => 'show',
+          :project_id => 'project-name' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/project-name/issues/gantt.pdf" },
+        { :controller => 'gantts', :action => 'show',
+          :project_id => 'project-name', :format => 'pdf' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e5/e5e73f56cc8c107df23a1314f092764691036b13.svn-base
--- a/.svn/pristine/e5/e5e73f56cc8c107df23a1314f092764691036b13.svn-base
+++ /dev/null
@@ -1,120 +0,0 @@
-<%= error_messages_for 'custom_field' %>
-
-<script type="text/javascript">
-//<![CDATA[
-function toggle_custom_field_format() {
-  format = $("custom_field_field_format");
-  p_length = $("custom_field_min_length");
-  p_regexp = $("custom_field_regexp");
-  p_values = $("custom_field_possible_values");
-  p_searchable = $("custom_field_searchable");
-  p_default = $("custom_field_default_value");
-
-  p_default.setAttribute('type','text');
-  Element.show(p_default.parentNode);
-
-  switch (format.value) {
-    case "list":
-      Element.hide(p_length.parentNode);
-      Element.hide(p_regexp.parentNode);
-      if (p_searchable) Element.show(p_searchable.parentNode);
-      Element.show(p_values.parentNode);
-      break;
-    case "bool":
-      p_default.setAttribute('type','checkbox');
-      Element.hide(p_length.parentNode);
-      Element.hide(p_regexp.parentNode);
-      if (p_searchable) Element.hide(p_searchable.parentNode);
-      Element.hide(p_values.parentNode);
-      break;
-    case "date":
-      Element.hide(p_length.parentNode);
-      Element.hide(p_regexp.parentNode);
-      if (p_searchable) Element.hide(p_searchable.parentNode);
-      Element.hide(p_values.parentNode);
-      break;
-    case "float":
-    case "int":
-      Element.show(p_length.parentNode);
-      Element.show(p_regexp.parentNode);
-      if (p_searchable) Element.hide(p_searchable.parentNode);
-      Element.hide(p_values.parentNode);
-      break;
-    case "user":
-    case "version":
-      Element.hide(p_length.parentNode);
-      Element.hide(p_regexp.parentNode);
-      if (p_searchable) Element.hide(p_searchable.parentNode);
-      Element.hide(p_values.parentNode);
-      Element.hide(p_default.parentNode);
-      break;
-    default:
-      Element.show(p_length.parentNode);
-      Element.show(p_regexp.parentNode);
-      if (p_searchable) Element.show(p_searchable.parentNode);
-      Element.hide(p_values.parentNode);
-      break;
-  }
-}
-
-//]]>
-</script>
-
-<div class="box">
-<p><%= f.text_field :name, :required => true %></p>
-<p><%= f.select :field_format, custom_field_formats_for_select(@custom_field), {}, :onchange => "toggle_custom_field_format();",
-                                                                    :disabled => !@custom_field.new_record? %></p>
-<p><label for="custom_field_min_length"><%=l(:label_min_max_length)%></label>
-   <%= f.text_field :min_length, :size => 5, :no_label => true %> - 
-   <%= f.text_field :max_length, :size => 5, :no_label => true %><br />(<%=l(:text_min_max_length_info)%>)</p>
-<p><%= f.text_field :regexp, :size => 50 %><br />(<%=l(:text_regexp_info)%>)</p>
-<p>
-  <%= f.text_area :possible_values, :value => @custom_field.possible_values.to_a.join("\n"), :rows => 15 %>
-  <br /><em><%= l(:text_custom_field_possible_values_info) %></em>
-</p>
-<p><%= @custom_field.field_format == 'bool' ? f.check_box(:default_value) : f.text_field(:default_value) %></p>
-<%= call_hook(:view_custom_fields_form_upper_box, :custom_field => @custom_field, :form => f) %>
-</div>
-
-<div class="box">
-<% case @custom_field.class.name
-when "IssueCustomField" %>
-
-    <fieldset><legend><%=l(:label_tracker_plural)%></legend>
-    <% for tracker in @trackers %>
-      <%= check_box_tag "custom_field[tracker_ids][]",
-                        tracker.id,
-                        (@custom_field.trackers.include? tracker),
-                        :id => "custom_field_tracker_ids_#{tracker.id}" %>
-      <label class="no-css" for="custom_field_tracker_ids_<%=tracker.id%>">
-        <%= h(tracker.name) %>
-      </label>
-    <% end %>
-    <%= hidden_field_tag "custom_field[tracker_ids][]", '' %>
-    </fieldset>
-    &nbsp;
-    <p><%= f.check_box :is_required %></p>
-    <p><%= f.check_box :is_for_all %></p>
-    <p><%= f.check_box :is_filter %></p>
-    <p><%= f.check_box :searchable %></p>
-
-<% when "UserCustomField" %>
-    <p><%= f.check_box :is_required %></p>
-    <p><%= f.check_box :visible %></p>
-    <p><%= f.check_box :editable %></p>
-
-<% when "ProjectCustomField" %>
-    <p><%= f.check_box :is_required %></p>
-    <p><%= f.check_box :visible %></p>
-    <p><%= f.check_box :searchable %></p>
-
-<% when "TimeEntryCustomField" %>
-    <p><%= f.check_box :is_required %></p>
-
-<% else %>
-    <p><%= f.check_box :is_required %></p>
-
-<% end %>
-<%= call_hook(:"view_custom_fields_form_#{@custom_field.type.to_s.underscore}", :custom_field => @custom_field, :form => f) %>
-</div>
-<%= javascript_tag "toggle_custom_field_format();" %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e6/e63baa15db8de1b3cd93a2e693445907ecb64592.svn-base
--- /dev/null
+++ b/.svn/pristine/e6/e63baa15db8de1b3cd93a2e693445907ecb64592.svn-base
@@ -0,0 +1,65 @@
+<% roles = Role.find_all_givable %>
+<% projects = Project.active.all %>
+
+<div class="splitcontentleft">
+<% if @group.memberships.any? %>
+<table class="list memberships">
+  <thead><tr>
+    <th><%= l(:label_project) %></th>
+    <th><%= l(:label_role_plural) %></th>
+    <th style="width:15%"></th>
+  </tr></thead>
+  <tbody>
+  <% @group.memberships.each do |membership| %>
+  <% next if membership.new_record? %>
+  <tr id="member-<%= membership.id %>" class="<%= cycle 'odd', 'even' %> class">
+  <td class="project"><%= link_to_project membership.project %></td>
+  <td class="roles">
+    <span id="member-<%= membership.id %>-roles"><%=h membership.roles.sort.collect(&:to_s).join(', ') %></span>
+    <%= form_for(:membership, :remote => true,
+                 :url => { :action => 'edit_membership', :id => @group, :membership_id => membership },
+                 :html => { :id => "member-#{membership.id}-roles-form", :style => 'display:none;'}) do %>
+        <p><% roles.each do |role| %>
+        <label><%= check_box_tag 'membership[role_ids][]', role.id, membership.roles.include?(role) %> <%=h role %></label><br />
+        <% end %></p>
+        <p><%= submit_tag l(:button_change) %>
+        <%= link_to_function(
+              l(:button_cancel),
+              "$('#member-#{membership.id}-roles').show(); $('#member-#{membership.id}-roles-form').hide(); return false;"
+            ) %></p>
+    <% end %>
+  </td>
+  <td class="buttons">
+      <%= link_to_function(
+            l(:button_edit),
+            "$('#member-#{membership.id}-roles').hide(); $('#member-#{membership.id}-roles-form').show(); return false;",
+            :class => 'icon icon-edit'
+          ) %>
+      <%= delete_link({:controller => 'groups', :action => 'destroy_membership', :id => @group, :membership_id => membership},
+                      :remote => true,
+                      :method => :post) %>
+  </td>
+  </tr>
+<% end; reset_cycle %>
+  </tbody>
+</table>
+<% else %>
+<p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
+</div>
+
+<div class="splitcontentright">
+<% if projects.any? %>
+<fieldset><legend><%=l(:label_project_new)%></legend>
+<%= form_for(:membership, :remote => true, :url => { :action => 'edit_membership', :id => @group }) do %>
+<%= label_tag "membership_project_id", l(:description_choose_project), :class => "hidden-for-sighted" %>
+<%= select_tag 'membership[project_id]', options_for_membership_project_select(@group, projects) %>
+<p><%= l(:label_role_plural) %>:
+<% roles.each do |role| %>
+  <label><%= check_box_tag 'membership[role_ids][]', role.id %> <%=h role %></label>
+<% end %></p>
+<p><%= submit_tag l(:button_add) %></p>
+<% end %>
+</fieldset>
+<% end %>
+</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e6/e68980e453bcaeab54d767cd68eee8a10b8ecd17.svn-base
--- a/.svn/pristine/e6/e68980e453bcaeab54d767cd68eee8a10b8ecd17.svn-base
+++ /dev/null
@@ -1,120 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module AccessControl
-
-    class << self
-      def map
-        mapper = Mapper.new
-        yield mapper
-        @permissions ||= []
-        @permissions += mapper.mapped_permissions
-      end
-
-      def permissions
-        @permissions
-      end
-
-      # Returns the permission of given name or nil if it wasn't found
-      # Argument should be a symbol
-      def permission(name)
-        permissions.detect {|p| p.name == name}
-      end
-
-      # Returns the actions that are allowed by the permission of given name
-      def allowed_actions(permission_name)
-        perm = permission(permission_name)
-        perm ? perm.actions : []
-      end
-
-      def public_permissions
-        @public_permissions ||= @permissions.select {|p| p.public?}
-      end
-
-      def members_only_permissions
-        @members_only_permissions ||= @permissions.select {|p| p.require_member?}
-      end
-
-      def loggedin_only_permissions
-        @loggedin_only_permissions ||= @permissions.select {|p| p.require_loggedin?}
-      end
-
-      def available_project_modules
-        @available_project_modules ||= @permissions.collect(&:project_module).uniq.compact
-      end
-
-      def modules_permissions(modules)
-        @permissions.select {|p| p.project_module.nil? || modules.include?(p.project_module.to_s)}
-      end
-    end
-
-    class Mapper
-      def initialize
-        @project_module = nil
-      end
-
-      def permission(name, hash, options={})
-        @permissions ||= []
-        options.merge!(:project_module => @project_module)
-        @permissions << Permission.new(name, hash, options)
-      end
-
-      def project_module(name, options={})
-        @project_module = name
-        yield self
-        @project_module = nil
-      end
-
-      def mapped_permissions
-        @permissions
-      end
-    end
-
-    class Permission
-      attr_reader :name, :actions, :project_module
-
-      def initialize(name, hash, options)
-        @name = name
-        @actions = []
-        @public = options[:public] || false
-        @require = options[:require]
-        @project_module = options[:project_module]
-        hash.each do |controller, actions|
-          if actions.is_a? Array
-            @actions << actions.collect {|action| "#{controller}/#{action}"}
-          else
-            @actions << "#{controller}/#{actions}"
-          end
-        end
-        @actions.flatten!
-      end
-
-      def public?
-        @public
-      end
-
-      def require_member?
-        @require && @require == :member
-      end
-
-      def require_loggedin?
-        @require && (@require == :member || @require == :loggedin)
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e6/e69e1b12c742c2fed3eb747a9348573816cd63d1.svn-base
--- /dev/null
+++ b/.svn/pristine/e6/e69e1b12c742c2fed3eb747a9348573816cd63d1.svn-base
@@ -0,0 +1,274 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class RepositoriesCvsControllerTest < ActionController::TestCase
+  tests RepositoriesController
+
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :repositories, :enabled_modules
+
+  REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s
+  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
+  # CVS module
+  MODULE_NAME = 'test'
+  PRJ_ID = 3
+  NUM_REV = 7
+
+  def setup
+    Setting.default_language = 'en'
+    User.current = nil
+
+    @project = Project.find(PRJ_ID)
+    @repository  = Repository::Cvs.create(:project      => Project.find(PRJ_ID),
+                                          :root_url     => REPOSITORY_PATH,
+                                          :url          => MODULE_NAME,
+                                          :log_encoding => 'UTF-8')
+    assert @repository
+  end
+
+  if File.directory?(REPOSITORY_PATH)
+    def test_get_new
+      @request.session[:user_id] = 1
+      @project.repository.destroy
+      get :new, :project_id => 'subproject1', :repository_scm => 'Cvs'
+      assert_response :success
+      assert_template 'new'
+      assert_kind_of Repository::Cvs, assigns(:repository)
+      assert assigns(:repository).new_record?
+    end
+
+    def test_browse_root
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal 3, assigns(:entries).size
+
+      entry = assigns(:entries).detect {|e| e.name == 'images'}
+      assert_equal 'dir', entry.kind
+
+      entry = assigns(:entries).detect {|e| e.name == 'README'}
+      assert_equal 'file', entry.kind
+
+      assert_not_nil assigns(:changesets)
+      assert assigns(:changesets).size > 0
+    end
+
+    def test_browse_directory
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['images'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['add.png', 'delete.png', 'edit.png'], assigns(:entries).collect(&:name)
+      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
+      assert_not_nil entry
+      assert_equal 'file', entry.kind
+      assert_equal 'images/edit.png', entry.path
+    end
+
+    def test_browse_at_given_revision
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :show, :id => PRJ_ID, :path => repository_path_hash(['images'])[:param],
+          :rev => 1
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entries)
+      assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name)
+    end
+
+    def test_entry
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param]
+      assert_response :success
+      assert_template 'entry'
+      assert_no_tag :tag => 'td',
+                    :attributes => { :class => /line-code/},
+                    :content => /before_filter/
+    end
+
+    def test_entry_at_given_revision
+      # changesets must be loaded
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param],
+          :rev => 2
+      assert_response :success
+      assert_template 'entry'
+      # this line was removed in r3
+      assert_tag :tag => 'td',
+                 :attributes => { :class => /line-code/},
+                 :content => /before_filter/
+    end
+
+    def test_entry_not_found
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'zzz.c'])[:param]
+      assert_tag :tag => 'p',
+                 :attributes => { :id => /errorExplanation/ },
+                 :content => /The entry or revision was not found in the repository/
+    end
+
+    def test_entry_download
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param],
+          :format => 'raw'
+      assert_response :success
+    end
+
+    def test_directory_entry
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :entry, :id => PRJ_ID,
+          :path => repository_path_hash(['sources'])[:param]
+      assert_response :success
+      assert_template 'show'
+      assert_not_nil assigns(:entry)
+      assert_equal 'sources', assigns(:entry).name
+    end
+
+    def test_diff
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['inline', 'sbs'].each do |dt|
+        get :diff, :id => PRJ_ID, :rev => 3, :type => dt
+        assert_response :success
+        assert_template 'diff'
+        assert_tag :tag => 'td', :attributes => { :class => 'line-code diff_out' },
+                                 :content => /before_filter :require_login/
+        assert_tag :tag => 'td', :attributes => { :class => 'line-code diff_in' },
+                                 :content => /with one change/
+      end
+    end
+
+    def test_diff_new_files
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      ['inline', 'sbs'].each do |dt|
+        get :diff, :id => PRJ_ID, :rev => 1, :type => dt
+        assert_response :success
+        assert_template 'diff'
+        assert_tag :tag => 'td', :attributes => { :class => 'line-code diff_in' },
+                                 :content => /watched.remove_watcher/
+        assert_tag :tag => 'th', :attributes => { :class => 'filename' },
+                                 :content => /test\/README/
+        assert_tag :tag => 'th', :attributes => { :class => 'filename' },
+                                 :content => /test\/images\/delete.png	/
+        assert_tag :tag => 'th', :attributes => { :class => 'filename' },
+                                 :content => /test\/images\/edit.png/
+        assert_tag :tag => 'th', :attributes => { :class => 'filename' },
+                                 :content => /test\/sources\/watchers_controller.rb/
+      end
+    end
+
+    def test_annotate
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+      get :annotate, :id => PRJ_ID,
+          :path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param]
+      assert_response :success
+      assert_template 'annotate'
+
+      # 1.1 line
+      assert_select 'tr' do
+        assert_select 'th.line-num', :text => '21'
+        assert_select 'td.revision', :text => /1.1/
+        assert_select 'td.author', :text => /LANG/
+      end
+      # 1.2 line
+      assert_select 'tr' do
+        assert_select 'th.line-num', :text => '32'
+        assert_select 'td.revision', :text => /1.2/
+        assert_select 'td.author', :text => /LANG/
+      end
+    end
+
+    def test_destroy_valid_repository
+      @request.session[:user_id] = 1 # admin
+      assert_equal 0, @repository.changesets.count
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal NUM_REV, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+
+    def test_destroy_invalid_repository
+      @request.session[:user_id] = 1 # admin
+      @project.repository.destroy
+      @repository  = Repository::Cvs.create!(
+                              :project      => Project.find(PRJ_ID),
+                              :root_url     => "/invalid",
+                              :url          => MODULE_NAME,
+                              :log_encoding => 'UTF-8'
+                              )
+      @repository.fetch_changesets
+      @project.reload
+      assert_equal 0, @repository.changesets.count
+
+      assert_difference 'Repository.count', -1 do
+        delete :destroy, :id => @repository.id
+      end
+      assert_response 302
+      @project.reload
+      assert_nil @project.repository
+    end
+  else
+    puts "CVS test repository NOT FOUND. Skipping functional tests !!!"
+    def test_fake; assert true end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e6/e6b0db274ce059d213550c8e6860020fa512f648.svn-base
--- a/.svn/pristine/e6/e6b0db274ce059d213550c8e6860020fa512f648.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-<% form_tag({}) do -%>
-<%= hidden_field_tag 'back_url', url_for(params) %>
-<div class="autoscroll">
-<table class="list issues">
-    <thead><tr>
-        <th class="checkbox hide-when-print"><%= link_to image_tag('toggle_check.png'), {}, :onclick => 'toggleIssuesSelection(Element.up(this, "form")); return false;',
-                                                           :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
-        </th>
-    <%= sort_header_tag('id', :caption => '#', :default_order => 'desc') %>
-        <% query.columns.each do |column| %>
-          <%= column_header(column) %>
-        <% end %>
-  </tr></thead>
-  <% previous_group = false %>
-  <tbody>
-  <% issue_list(issues) do |issue, level| -%>
-  <% if @query.grouped? && (group = @query.group_by_column.value(issue)) != previous_group %>
-    <% reset_cycle %>
-    <tr class="group open">
-      <td colspan="<%= query.columns.size + 2 %>">
-        <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
-        <%= group.blank? ? 'None' : column_content(@query.group_by_column, issue) %> <span class="count">(<%= @issue_count_by_group[group] %>)</span>
-        <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}", "toggleAllRowGroups(this)", :class => 'toggle-all') %>
-      </td>
-    </tr>
-    <% previous_group = group %>
-  <% end %>
-  <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
-    <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
-    <td class="id"><%= link_to issue.id, :controller => 'issues', :action => 'show', :id => issue %></td>
-        <% query.columns.each do |column| %><%= content_tag 'td', column_content(column, issue), :class => column.css_classes %><% end %>
-  </tr>
-  <% end -%>
-  </tbody>
-</table>
-</div>
-<% end -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e6/e6c6e613ff0d2c3cc9757a8612a421623bc71bcc.svn-base
--- a/.svn/pristine/e6/e6c6e613ff0d2c3cc9757a8612a421623bc71bcc.svn-base
+++ /dev/null
@@ -1,147 +0,0 @@
-
-   __       _           _
-   /__\_   _| |__  _   _| |_ _ __ ___  ___
-  / \// | | | '_ \| | | | __| '__/ _ \/ _ \
- / _  \ |_| | |_) | |_| | |_| | |  __/  __/
- \/ \_/\__,_|_.__/ \__, |\__|_|  \___|\___|
-                  |___/
-
-  (c) 2006, 2007 Anupam Sengupta
-  http://rubytree.rubyforge.org
-
-Rubytree is a simple implementation of the generic Tree data structure.  This
-implementation is node-centric, where the individual nodes on the tree are the
-primary objects and drive the structure.
-
-== INSTALL:
-
-Rubytree is an open source project and is hosted at:
-
-   http://rubytree.rubyforge.org
-
-Rubytree can be downloaded as a Rubygem or as a tar/zip file from:
-
-   http://rubyforge.org/frs/?group_id=1215&release_id=8817
-
-The file-name is one of:
-
-    rubytree-<VERSION>.gem - The Rubygem
-    rubytree-<VERSION>.tgz - GZipped source files
-    rubytree-<VERSION>.zip - Zipped  source files
-
-Download the appropriate file-type for your system.
-
-It is recommended to install Rubytree as a Ruby Gem, as this is an easy way to
-keep the version updated, and keep multiple versions of the library available on
-your system.
-
-=== Installing the Gem
-
-To Install the Gem, from a Terminal/CLI command prompt, issue the command:
-
-   gem install rubytree
-
-This should install the gem file for Rubytree. Note that you may need to be a
-super-user (root) to successfully install the gem.
-
-=== Installing from the tgz/zip file
-
-Extract the archive file (tgz or zip) and run the following command from the
-top-level source directory:
-
-    ruby ./setup.rb
-
-You may need administrator/super-user privileges to complete the setup using
-this method.
-
-== DOCUMENTATION:
-
-The primary class for this implementation is Tree::TreeNode. See the
-class documentation for an usage example.
-
-From a command line/terminal prompt, you can issue the following command to view
-the text mode ri documentation:
-
-    ri Tree::TreeNode
-
-Documentation on the web is available at:
-
-http://rubytree.rubyforge.org/rdoc
-
-== EXAMPLE:
-
-The following code-snippet implements this tree structure:
-
-                 +------------+
-                 |    ROOT    |
-                 +-----+------+
-         +-------------+------------+
-         |                          |
- +-------+-------+          +-------+-------+
- |  CHILD 1      |          |  CHILD 2      |
- +-------+-------+          +---------------+
-         |
-         |
- +-------+-------+
- | GRANDCHILD 1  |
- +---------------+
-
- require 'tree'
-
- myTreeRoot = Tree::TreeNode.new("ROOT", "Root Content")
-
- myTreeRoot << Tree::TreeNode.new("CHILD1", "Child1 Content") << Tree::TreeNode.new("GRANDCHILD1", "GrandChild1 Content")
-
- myTreeRoot << Tree::TreeNode.new("CHILD2", "Child2 Content")
-
- myTreeRoot.printTree
-
- child1 = myTreeRoot["CHILD1"]
-
- grandChild1 = myTreeRoot["CHILD1"]["GRANDCHILD1"]
-
- siblingsOfChild1Array = child1.siblings
-
- immediateChildrenArray = myTreeRoot.children
-
- # Process all nodes
-
- myTreeRoot.each { |node| node.content.reverse }
-
- myTreeRoot.remove!(child1) # Remove the child
-
-== LICENSE:
-
-Rubytree is licensed under BSD license.
-
-Copyright (c) 2006, 2007 Anupam Sengupta
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-- Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-- Redistributions in binary form must reproduce the above copyright notice, this
-  list of conditions and the following disclaimer in the documentation and/or
-  other materials provided with the distribution.
-
-- Neither the name of the organization nor the names of its contributors may
-  be used to endorse or promote products derived from this software without
-  specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-(Document Revision: $Revision: 1.16 $ by $Author: anupamsg $)
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e7/e7308fa83b439f445a7c82514b48a81377b05e71.svn-base
--- /dev/null
+++ b/.svn/pristine/e7/e7308fa83b439f445a7c82514b48a81377b05e71.svn-base
@@ -0,0 +1,1083 @@
+# translated by Dzintars Bergs (dzintars.bergs@gmail.com)
+
+lv:
+  direction: ltr
+  date:
+    formats:
+      default: "%d.%m.%Y"
+      short: "%d %b"
+      long: "%d %B %Y"
+
+    day_names: [SvÄ“tdiena, Pirmdiena, Otrdiena, TreÅ¡diena, Ceturtdiena, Piektdiena, Sestdiena]
+    abbr_day_names: [Sv, Pr, Ot, Tr, Ct, Pk, St]
+
+    month_names: [~, JanvÄris, FebruÄris, Marts, AprÄ«lis , Maijs, JÅ«nijs, JÅ«lijs, Augusts, Septembris, Oktobris, Novembris, Decembris]
+    abbr_month_names: [~, Jan, Feb, Mar, Apr, Mai, JÅ«n, JÅ«l, Aug, Sep, Okt, Nov, Dec]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a, %d %b %Y, %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b, %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "rÄ«tÄ"
+    pm: "vakarÄ"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pus minÅ«te"
+      less_than_x_seconds:
+        one:   "mazÄk kÄ 1 sekunde"
+        other: "mazÄk kÄ %{count} sekundes"
+      x_seconds:
+        one:   "1 sekunde"
+        other: "%{count} sekundes"
+      less_than_x_minutes:
+        one:   "mazÄk kÄ minÅ«te"
+        other: "mazÄk kÄ %{count} minÅ«tes"
+      x_minutes:
+        one:   "1 minÅ«te"
+        other: "%{count} minÅ«tes"
+      about_x_hours:
+        one:   "aptuveni 1 stunda"
+        other: "aptuveni %{count} stundas"
+      x_hours:
+        one:   "1 stunda"
+        other: "%{count} stundas"
+      x_days:
+        one:   "1 diena"
+        other: "%{count} dienas"
+      about_x_months:
+        one:   "aptuveni 1 mÄ“nesis"
+        other: "aptuveni %{count} mÄ“neÅ¡i"
+      x_months:
+        one:   "1 mÄ“nesis"
+        other: "%{count} mÄ“neÅ¡i"
+      about_x_years:
+        one:   "aptuveni 1 gads"
+        other: "aptuveni %{count} gadi"
+      over_x_years:
+        one:   "ilgÄk par 1 gadu"
+        other: "ilgÄk par %{count} gadiem"
+      almost_x_years:
+        one:   "gandrÄ«z 1 gadu"
+        other: "gandrÄ«z %{count} gadus"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: " "
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Baits"
+            other: "Baiti"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  support:
+    array:
+      sentence_connector: "un"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "nav iekÄ¼auts sarakstÄ"
+        exclusion: "ir rezervÄ“ts"
+        invalid: "nederÄ«gs"
+        confirmation: "apstiprinÄjums nesakrÄ«t"
+        accepted: "jÄbÅ«t akceptÄ“tam"
+        empty: "nevar bÅ«t tukÅ¡s"
+        blank: "nevar bÅ«t neaizpildÄ«ts"
+        too_long: "ir pÄrÄk gara(Å¡) (maksimÄlais garums ir %{count} simboli)"
+        too_short: "ir pÄrÄk Ä«sa(s) (minimÄlais garums ir %{count} simboli)"
+        wrong_length: "ir nepareiza garuma (vajadzÄ“tu bÅ«t %{count} simboli)"
+        taken: "eksistÄ“"
+        not_a_number: "nav skaitlis"
+        not_a_date: "nav derÄ«gs datums"
+        greater_than: "jÄbÅ«t lielÄkam par %{count}"
+        greater_than_or_equal_to: "jÄbÅ«t lielÄkam vai vienÄdam ar %{count}"
+        equal_to: "jÄbÅ«t vienÄdam ar %{count}"
+        less_than: "jÄbÅ«t mazÄkam kÄ %{count}"
+        less_than_or_equal_to: "jÄbÅ«t mazÄkam vai vienÄdam ar %{count}"
+        odd: "jÄatÅ¡Ä·irÄs"
+        even: "jÄsakrÄ«t"
+        greater_than_start_date: "jÄbÅ«t vÄ“lÄkam par sÄkuma datumu"
+        not_same_project: "nepieder pie tÄ paÅ¡a projekta"
+        circular_dependency: "Å Ä« relÄcija radÄ«tu ciklisku atkarÄ«bu"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: IzvÄ“lieties
+
+  general_text_No: 'NÄ“'
+  general_text_Yes: 'JÄ'
+  general_text_no: 'nÄ“'
+  general_text_yes: 'jÄ'
+  general_lang_name: 'Latvian (LatvieÅ¡u)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '1'
+
+  notice_account_updated: Konts tika atjaunots veiksmÄ«gi.
+  notice_account_invalid_creditentials: Nepareizs lietotÄja vÄrds vai parole.
+  notice_account_password_updated: Parole tika veiksmÄ«gi atjaunota.
+  notice_account_wrong_password: Nepareiza parole
+  notice_account_register_done: Konts veiksmÄ«gi izveidots. Lai aktivizÄ“tu kontu, spiediet uz saites, kas Jums tika nosÅ«tÄ«ta.
+  notice_account_unknown_email: NezinÄms lietotÄjs
+  notice_can_t_change_password: Å is konts izmanto ÄrÄ“ju pilnvaroÅ¡anas avotu. Nav iespÄ“jams nomainÄ«t paroli.
+  notice_account_lost_email_sent: Jums tika nosÅ«tÄ«ts e-pasts ar instrukcijÄm, kÄ izveidot jaunu paroli.
+  notice_account_activated: JÅ«su konts ir aktivizÄ“ts. Varat pieslÄ“gties sistÄ“mai.
+  notice_successful_create: VeiksmÄ«ga izveide.
+  notice_successful_update: VeiksmÄ«ga atjaunoÅ¡ana.
+  notice_successful_delete: VeiksmÄ«ga dzÄ“Å¡ana.
+  notice_successful_connection: VeiksmÄ«gs savienojums.
+  notice_file_not_found: Lapa, ko JÅ«s mÄ“Ä£inÄt atvÄ“rt, neeksistÄ“ vai ir pÄrvietota.
+  notice_locking_conflict: Datus ir atjaunojis cits lietotÄjs.
+  notice_not_authorized: Jums nav tiesÄ«bu piekÄ¼Å«t Å¡ai lapai.
+  notice_email_sent: "E-pasts tika nosÅ«tÄ«ts uz %{value}"
+  notice_email_error: "KÄ¼Å«da sÅ«tot e-pastu (%{value})"
+  notice_feeds_access_key_reseted: JÅ«su RSS pieejas atslÄ“ga tika iestatÄ«ta sÄkuma stÄvoklÄ«.
+  notice_api_access_key_reseted: JÅ«su API pieejas atslÄ“ga tika iestatÄ«ta sÄkuma stÄvoklÄ«.
+  notice_failed_to_save_issues: "NeizdevÄs saglabÄt %{count} uzdevumu(us) no %{total} izvÄ“lÄ“ti: %{ids}."
+  notice_no_issue_selected: "Nav izvÄ“lÄ“ts uzdevums! LÅ«dzu, atzÄ«mÄ“jiet uzdevumus, kurus vÄ“laties rediÄ£Ä“t!"
+  notice_account_pending: "JÅ«su konts tika izveidots un Å¡obrÄ«d gaida administratora apstiprinÄjumu."
+  notice_default_data_loaded: NoklusÄ“tÄ konfigurÄcija tika veiksmÄ«gi ielÄdÄ“ta.
+  notice_unable_delete_version: NeizdevÄs dzÄ“st versiju.
+  notice_issue_done_ratios_updated: Uzdevuma izpildes koeficients atjaunots.
+
+  error_can_t_load_default_data: "Nevar ielÄdÄ“t noklusÄ“tos konfigurÄcijas datus: %{value}"
+  error_scm_not_found: "Ieraksts vai versija nebija repozitorijÄ."
+  error_scm_command_failed: "MÄ“Ä£inot piekÄ¼Å«t repozitorijam, notika kÄ¼Å«da: %{value}"
+  error_scm_annotate: "Ieraksts neeksistÄ“ vai tam nevar tikt pievienots paskaidrojums."
+  error_issue_not_found_in_project: 'Uzdevums netika atrasts vai nepieder Å¡im projektam.'
+  error_no_tracker_in_project: 'Neviens trakeris nav saistÄ«ts ar Å¡o projektu. PÄrbaudiet projekta iestatÄ«jumus.'
+  error_no_default_issue_status: 'Nav definÄ“ts uzdevuma noklusÄ“tais statuss. PÄrbaudiet konfigurÄciju (Ejat uz: "AdministrÄcija -> Uzdevumu statusi")!'
+  error_can_not_reopen_issue_on_closed_version: 'Nevar pievienot atsauksmi uzdevumam, kas saistÄ«ts ar slÄ“gtu versiju.'
+  error_can_not_archive_project: Å is projekts nevar tikt arhivÄ“ts
+  error_issue_done_ratios_not_updated: "Uzdevuma izpildes koeficients nav atjaunots."
+  error_workflow_copy_source: 'LÅ«dzu izvÄ“lieties avota trakeri vai lomu'
+  error_workflow_copy_target: 'LÅ«dzu izvÄ“lÄ“ties mÄ“rÄ·a trakeri(us) un lomu(as)'
+
+  warning_attachments_not_saved: "%{count} datnes netika saglabÄtas."
+
+  mail_subject_lost_password: "JÅ«su %{value} parole"
+  mail_body_lost_password: 'Lai mainÄ«tu paroli, spiediet uz Å¡Ä«s saites:'
+  mail_subject_register: "JÅ«su %{value} konta aktivizÄcija"
+  mail_body_register: 'Lai izveidotu kontu, spiediet uz Å¡Ä«s saites:'
+  mail_body_account_information_external: "Varat izmantot JÅ«su %{value} kontu, lai pieslÄ“gtos."
+  mail_body_account_information: JÅ«su konta informÄcija
+  mail_subject_account_activation_request: "%{value} konta aktivizÄcijas pieprasÄ«jums"
+  mail_body_account_activation_request: "Jauns lietotÄjs (%{value}) ir reÄ£istrÄ“ts. LietotÄja konts gaida JÅ«su apstiprinÄjumu:"
+  mail_subject_reminder: "%{count} uzdevums(i) sagaidÄms(i) tuvÄkajÄs %{days} dienÄs"
+  mail_body_reminder: "%{count} uzdevums(i), kurÅ¡(i) ir nozÄ«mÄ“ts(i) Jums, sagaidÄms(i) tuvÄkajÄs %{days} dienÄs:"
+  mail_subject_wiki_content_added: "'%{id}' Wiki lapa pievienota"
+  mail_body_wiki_content_added: "The '%{id}' Wiki lapu pievienojis %{author}."
+  mail_subject_wiki_content_updated: "'%{id}' Wiki lapa atjaunota"
+  mail_body_wiki_content_updated: "The '%{id}' Wiki lapu atjaunojis %{author}."
+
+
+  field_name: Nosaukums
+  field_description: Apraksts
+  field_summary: Kopsavilkums
+  field_is_required: NepiecieÅ¡ams
+  field_firstname: VÄrds
+  field_lastname: UzvÄrds
+  field_mail: "E-pasts"
+  field_filename: Datne
+  field_filesize: IzmÄ“rs
+  field_downloads: LejupielÄdes
+  field_author: Autors
+  field_created_on: Izveidots
+  field_updated_on: Atjaunots
+  field_field_format: FormÄts
+  field_is_for_all: Visiem projektiem
+  field_possible_values: IespÄ“jamÄs vÄ“rtÄ«bas
+  field_regexp: RegulÄrÄ izteiksme
+  field_min_length: MinimÄlais garums
+  field_max_length: MaksimÄlais garums
+  field_value: VÄ“rtÄ«ba
+  field_category: Kategorija
+  field_title: Nosaukums
+  field_project: Projekts
+  field_issue: Uzdevums
+  field_status: Statuss
+  field_notes: PiezÄ«mes
+  field_is_closed: Uzdevums slÄ“gts
+  field_is_default: NoklusÄ“tÄ vÄ“rtÄ«ba
+  field_tracker: Trakeris
+  field_subject: Temats
+  field_due_date: SagaidÄmais datums
+  field_assigned_to: PieÅ¡Ä·irts
+  field_priority: PrioritÄte
+  field_fixed_version: MÄ“rÄ·a versija
+  field_user: LietotÄjs
+  field_role: Loma
+  field_homepage: Vietne
+  field_is_public: Publisks
+  field_parent: ApakÅ¡projekts projektam
+  field_is_in_roadmap: CeÄ¼vedÄ« parÄdÄ«tie uzdevumi
+  field_login: PieslÄ“gties
+  field_mail_notification: "E-pasta paziÅ†ojumi"
+  field_admin: Administrators
+  field_last_login_on: PÄ“dÄ“jo reizi pieslÄ“dzies
+  field_language: Valoda
+  field_effective_date: Datums
+  field_password: Parole
+  field_new_password: JanÄ parole
+  field_password_confirmation: Paroles apstiprinÄjums
+  field_version: Versija
+  field_type: Tips
+  field_host: Hosts
+  field_port: Ports
+  field_account: Konts
+  field_base_dn: Base DN
+  field_attr_login: PieslÄ“gÅ¡anÄs atribÅ«ts
+  field_attr_firstname: VÄrda atribÅ«ts
+  field_attr_lastname: UzvÄrda atribÅ«ts
+  field_attr_mail: "E-pasta atribÅ«ts"
+  field_onthefly: "LietotÄja izveidoÅ¡ana on-the-fly"
+  field_start_date: SÄkuma datums
+  field_done_ratio: "% padarÄ«ti"
+  field_auth_source: PilnvaroÅ¡anas reÅ¾Ä«ms
+  field_hide_mail: "PaslÄ“pt manu e-pasta adresi"
+  field_comments: KomentÄrs
+  field_url: URL
+  field_start_page: SÄkuma lapa
+  field_subproject: ApakÅ¡projekts
+  field_hours: Stundas
+  field_activity: AktivitÄte
+  field_spent_on: Datums
+  field_identifier: Identifikators
+  field_is_filter: Izmantots kÄ filtrs
+  field_issue_to: SaistÄ«ts uzdevums
+  field_delay: KavÄ“jums
+  field_assignable: Uzdevums var tikt piesaistÄ«ts Å¡ai lomai
+  field_redirect_existing_links: PÄradresÄ“t eksistÄ“joÅ¡Äs saites
+  field_estimated_hours: ParedzÄ“tais laiks
+  field_column_names: Kolonnas
+  field_time_zone: Laika zona
+  field_searchable: MeklÄ“jams
+  field_default_value: NoklusÄ“tÄ vÄ“rtÄ«ba
+  field_comments_sorting: RÄdÄ«t komentÄrus
+  field_parent_title: VecÄka lapa
+  field_editable: RediÄ£Ä“jams
+  field_watcher: VÄ“rotÄjs
+  field_identity_url: OpenID URL
+  field_content: Saturs
+  field_group_by: GrupÄ“t rezultÄtus pÄ“c
+  field_sharing: KoplietoÅ¡ana
+
+  setting_app_title: Programmas nosaukums
+  setting_app_subtitle: Programmas apakÅ¡-nosaukums
+  setting_welcome_text: Sveiciena teksts
+  setting_default_language: NoklusÄ“tÄ valoda
+  setting_login_required: NepiecieÅ¡ama pilnvaroÅ¡ana
+  setting_self_registration: PaÅ¡reÄ£istrÄ“Å¡anÄs
+  setting_attachment_max_size: Pielikuma maksimÄlais izmÄ“rs
+  setting_issues_export_limit: Uzdevumu eksporta ierobeÅ¾ojums
+  setting_mail_from: "E-pasta adrese informÄcijas nosÅ«tÄ«Å¡anai"
+  setting_bcc_recipients: "SaÅ†Ä“mÄ“ju adreses neparÄdÄ«sies citu saÅ†Ä“mÄ“ju vÄ“stulÄ“s (bcc)"
+  setting_plain_text_mail: "VÄ“stule brÄ«vÄ tekstÄ (bez HTML)"
+  setting_host_name: Hosta nosaukums un piekÄ¼uves ceÄ¼Å¡
+  setting_text_formatting: Teksta formatÄ“Å¡ana
+  setting_wiki_compression: Wiki vÄ“stures saspieÅ¡ana
+  setting_feeds_limit: Barotnes satura ierobeÅ¾ojums
+  setting_default_projects_public: Jaunie projekti noklusÄ“ti ir publiski pieejami
+  setting_autofetch_changesets: "AutomÄtiski lietot jaunÄko versiju, pieslÄ“dzoties repozitorijam (Autofetch)"
+  setting_sys_api_enabled: IeslÄ“gt WS repozitoriju menedÅ¾mentam
+  setting_commit_ref_keywords: NorÄdes atslÄ“gvÄrdi
+  setting_commit_fix_keywords:  FiksÄ“joÅ¡ie atslÄ“gvÄrdi
+  setting_autologin: AutomÄtiskÄ pieslÄ“gÅ¡anÄs
+  setting_date_format: Datuma formÄts
+  setting_time_format: Laika formÄts
+  setting_cross_project_issue_relations: "AtÄ¼aut starp-projektu uzdevumu relÄcijas"
+  setting_issue_list_default_columns: NoklusÄ“ti rÄdÄ«tÄs kolonnas uzdevumu sarakstÄ
+  setting_emails_footer: "E-pastu kÄjene"
+  setting_protocol: Protokols
+  setting_per_page_options: Objekti vienÄ lapÄ
+  setting_user_format: LietotÄju rÄdÄ«Å¡anas formÄts
+  setting_activity_days_default: Dienus skaits aktivitÄÅ¡u rÄdÄ«Å¡anai aktivitÄÅ¡u sadaÄ¼Ä
+  setting_display_subprojects_issues: RÄdÄ«t apakÅ¡projekta uzdevumus galvenajÄ projektÄ pÄ“c noklusÄ“juma
+  setting_enabled_scm: Lietot SCM
+  setting_mail_handler_body_delimiters: "SaÄ«sinÄt pÄ“c vienas no Å¡im rindÄm"
+  setting_mail_handler_api_enabled: "Lietot WS ienÄkoÅ¡ajiem e-pastiem"
+  setting_mail_handler_api_key: API atslÄ“ga
+  setting_sequential_project_identifiers: Ä¢enerÄ“t secÄ«gus projektu identifikatorus
+  setting_gravatar_enabled: Izmantot Gravatar lietotÄju ikonas
+  setting_gravatar_default: NoklusÄ“tais Gravatar attÄ“ls
+  setting_diff_max_lines_displayed: MaksimÄlais rÄdÄ«to diff rindu skaits
+  setting_file_max_size_displayed: MaksimÄlais izmÄ“rs iekÄ¼autajiem teksta failiem
+  setting_repository_log_display_limit: MaksimÄlais Å¾urnÄla datnÄ“ rÄdÄ«to revÄ«ziju skaits
+  setting_openid: AtÄ¼aut OpenID pieslÄ“gÅ¡anos un reÄ£istrÄ“Å¡anos
+  setting_password_min_length: MinimÄlais paroles garums
+  setting_new_project_user_role_id: Loma, kura tiek pieÅ¡Ä·irta ne-administratora lietotÄjam, kurÅ¡ izveido projektu
+  setting_default_projects_modules: NoklusÄ“tie lietotie moduÄ¼i jaunam projektam
+  setting_issue_done_ratio: AprÄ“Ä·inÄt uzdevuma izpildes koeficientu ar
+  setting_issue_done_ratio_issue_field: uzdevuma lauku
+  setting_issue_done_ratio_issue_status: uzdevuma statusu
+  setting_start_of_week: SÄkt kalendÄru ar
+  setting_rest_api_enabled: Lietot REST web-servisu
+  setting_cache_formatted_text: KeÅ¡ot formatÄ“tu tekstu
+
+  permission_add_project: Izveidot projektu
+  permission_add_subprojects: Izveidot apakÅ¡projektu
+  permission_edit_project: RediÄ£Ä“t projektu
+  permission_select_project_modules: IzvÄ“lÄ“ties projekta moduÄ¼us
+  permission_manage_members: PÄrvaldÄ«t dalÄ«bniekus
+  permission_manage_project_activities: PÄrvaldÄ«t projekta aktivitÄtes
+  permission_manage_versions: PÄrvaldÄ«t versijas
+  permission_manage_categories: PÄrvaldÄ«t uzdevumu kategorijas
+  permission_view_issues: ApskatÄ«t uzdevumus
+  permission_add_issues: Pievienot uzdevumus
+  permission_edit_issues: RediÄ£Ä“t uzdevumus
+  permission_manage_issue_relations: PÄrvaldÄ«t uzdevumu relÄcijas
+  permission_add_issue_notes: Pievienot piezÄ«mes
+  permission_edit_issue_notes: RediÄ£Ä“t piezÄ«mes
+  permission_edit_own_issue_notes: RediÄ£Ä“t paÅ¡a piezÄ«mes
+  permission_move_issues: PÄrvietot uzdevumus
+  permission_delete_issues: DzÄ“st uzdevumus
+  permission_manage_public_queries: PÄrvaldÄ«t publiskos pieprasÄ«jumus
+  permission_save_queries: SaglabÄt pieprasÄ«jumus
+  permission_view_gantt: SkatÄ«t Ganta diagrammu
+  permission_view_calendar: SkatÄ«t kalendÄru
+  permission_view_issue_watchers: SkatÄ«t vÄ“rotÄju sarakstu
+  permission_add_issue_watchers: Pievienot vÄ“rotÄjus
+  permission_delete_issue_watchers: DzÄ“st vÄ“rotÄjus
+  permission_log_time: PiereÄ£istrÄ“t pavadÄ«to laiku
+  permission_view_time_entries: SkatÄ«t pavadÄ«to laiku
+  permission_edit_time_entries: RdiÄ£Ä“t laika reÄ£istrus
+  permission_edit_own_time_entries:  RediÄ£Ä“t savus laika reÄ£istrus
+  permission_manage_news: PÄrvaldÄ«t jaunumus
+  permission_comment_news: KomentÄ“t jaunumus
+  permission_view_documents: SkatÄ«t dokumentus
+  permission_manage_files: PÄrvaldÄ«t failus
+  permission_view_files: SkatÄ«t failus
+  permission_manage_wiki: PÄrvaldÄ«t wiki
+  permission_rename_wiki_pages: PÄrsaukt wiki lapas
+  permission_delete_wiki_pages: DzÄ“st wiki lapas
+  permission_view_wiki_pages: SkatÄ«t wiki
+  permission_view_wiki_edits: SkatÄ«t wiki vÄ“sturi
+  permission_edit_wiki_pages: RdiÄ£Ä“t wiki lapas
+  permission_delete_wiki_pages_attachments: DzÄ“st pielikumus
+  permission_protect_wiki_pages: Projekta wiki lapas
+  permission_manage_repository: PÄrvaldÄ«t repozitoriju
+  permission_browse_repository: PÄrlÅ«kot repozitoriju
+  permission_view_changesets: SkatÄ«t izmaiÅ†u kopumus
+  permission_commit_access: AtÄ¼aut piekÄ¼uvi
+  permission_manage_boards: PÄrvaldÄ«t ziÅ†ojumu dÄ“Ä¼us
+  permission_view_messages: SkatÄ«t ziÅ†as
+  permission_add_messages: PublicÄ“t ziÅ†as
+  permission_edit_messages: RediÄ£Ä“t ziÅ†as
+  permission_edit_own_messages: RediÄ£Ä“t savas ziÅ†as
+  permission_delete_messages: DzÄ“st ziÅ†as
+  permission_delete_own_messages: DzÄ“st savas ziÅ†as
+  permission_export_wiki_pages: EksportÄ“t Wiki lapas
+
+  project_module_issue_tracking: Uzdevumu uzskaite
+  project_module_time_tracking: Laika uzskaite
+  project_module_news: Jaunumi
+  project_module_documents: Dokumenti
+  project_module_files: Datnes
+  project_module_wiki: Wiki
+  project_module_repository: Repozitorijs
+  project_module_boards: ZiÅ†ojumu dÄ“Ä¼i
+
+  label_user: LietotÄjs
+  label_user_plural: LietotÄji
+  label_user_new: Jauns lietotÄjs
+  label_user_anonymous: AnonÄ«ms
+  label_project: Projekts
+  label_project_new: Jauns projekts
+  label_project_plural: Projekti
+  label_x_projects:
+    zero:  nav projektu
+    one:   1 projekts
+    other: "%{count} projekti"
+  label_project_all: Visi projekti
+  label_project_latest: JaunÄkie projekti
+  label_issue: Uzdevums
+  label_issue_new: Jauns uzdevums
+  label_issue_plural: Uzdevumi
+  label_issue_view_all: SkatÄ«t visus uzdevumus
+  label_issues_by: "KÄrtot pÄ“c %{value}"
+  label_issue_added: Uzdevums pievienots
+  label_issue_updated: Uzdevums atjaunots
+  label_document: Dokuments
+  label_document_new: Jauns dokuments
+  label_document_plural: Dokumenti
+  label_document_added: Dokuments pievienots
+  label_role: Loma
+  label_role_plural: Lomas
+  label_role_new: Jauna loma
+  label_role_and_permissions: Lomas un atÄ¼aujas
+  label_member: DalÄ«bnieks
+  label_member_new: Jauns dalÄ«bnieks
+  label_member_plural: DalÄ«bnieki
+  label_tracker: Trakeris
+  label_tracker_plural: Trakeri
+  label_tracker_new: Jauns trakeris
+  label_workflow: Darba gaita
+  label_issue_status: Uzdevuma statuss
+  label_issue_status_plural: Uzdevumu statusi
+  label_issue_status_new: Jauns statuss
+  label_issue_category: Uzdevuma kategorija
+  label_issue_category_plural: Uzdevumu kategorijas
+  label_issue_category_new: Jauna kategorija
+  label_custom_field: PielÄgojams lauks
+  label_custom_field_plural: PielÄgojami lauki
+  label_custom_field_new: Jauns pielÄgojams lauks
+  label_enumerations: UzskaitÄ«jumi
+  label_enumeration_new: Jauna vÄ“rtÄ«ba
+  label_information: InformÄcija
+  label_information_plural: InformÄcija
+  label_please_login: LÅ«dzu pieslÄ“dzieties
+  label_register: ReÄ£istrÄ“ties
+  label_login_with_open_id_option: vai pieslÄ“gties ar OpenID
+  label_password_lost: NozaudÄ“ta parole
+  label_home: SÄkums
+  label_my_page: Mana lapa
+  label_my_account: Mans konts
+  label_my_projects: Mani projekti
+  label_administration: AdministrÄcija
+  label_login: PieslÄ“gties
+  label_logout: AtslÄ“gties
+  label_help: PalÄ«dzÄ«ba
+  label_reported_issues: ZiÅ†otie uzdevumi
+  label_assigned_to_me_issues: Man piesaistÄ«tie uzdevumi
+  label_last_login: PÄ“dÄ“jÄ pieslÄ“gÅ¡anÄs
+  label_registered_on: ReÄ£istrÄ“jies
+  label_activity: AktivitÄte
+  label_overall_activity: KopÄ“jÄs aktivitÄtes
+  label_user_activity: "LietotÄja %{value} aktivitÄtes"
+  label_new: Jauns
+  label_logged_as: PieslÄ“dzies kÄ
+  label_environment: Vide
+  label_authentication: PilnvaroÅ¡ana
+  label_auth_source: PilnvaroÅ¡anas reÅ¾Ä«ms
+  label_auth_source_new: Jauns pilnvaroÅ¡anas reÅ¾Ä«ms
+  label_auth_source_plural: PilnvaroÅ¡anas reÅ¾Ä«mi
+  label_subproject_plural: ApakÅ¡projekti
+  label_subproject_new: Jauns apakÅ¡projekts
+  label_and_its_subprojects: "%{value} un tÄ apakÅ¡projekti"
+  label_min_max_length: MinimÄlais - MaksimÄlais garums
+  label_list: Saraksts
+  label_date: Datums
+  label_integer: Vesels skaitlis
+  label_float: DecimÄlskaitlis
+  label_boolean: Patiesuma vÄ“rtÄ«ba
+  label_string: Teksts
+  label_text: GarÅ¡ teksts
+  label_attribute: AtribÅ«ts
+  label_attribute_plural: AtribÅ«ti
+  label_no_data: Nav datu, ko parÄdÄ«t
+  label_change_status: MainÄ«t statusu
+  label_history: VÄ“sture
+  label_attachment: Pielikums
+  label_attachment_new: Jauns pielikums
+  label_attachment_delete: DzÄ“st pielikumu
+  label_attachment_plural: Pielikumi
+  label_file_added: Lauks pievienots
+  label_report: Atskaite
+  label_report_plural: Atskaites
+  label_news: ZiÅ†a
+  label_news_new: Pievienot ziÅ†u
+  label_news_plural: ZiÅ†as
+  label_news_latest: JaunÄkÄs ziÅ†as
+  label_news_view_all: SkatÄ«t visas ziÅ†as
+  label_news_added: ZiÅ†as pievienotas
+  label_settings: IestatÄ«jumi
+  label_overview: PÄrskats
+  label_version: Versija
+  label_version_new: Jauna versija
+  label_version_plural: Versijas
+  label_close_versions: AizvÄ“rt pabeigtÄs versijas
+  label_confirmation: ApstiprinÄjums
+  label_export_to: 'Pieejams arÄ«:'
+  label_read: LasÄ«t...
+  label_public_projects: Publiskie projekti
+  label_open_issues: atvÄ“rts
+  label_open_issues_plural: atvÄ“rti
+  label_closed_issues: slÄ“gts
+  label_closed_issues_plural: slÄ“gti
+  label_x_open_issues_abbr_on_total:
+    zero:  0 atvÄ“rti / %{total}
+    one:   1 atvÄ“rts / %{total}
+    other: "%{count} atvÄ“rti / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 atvÄ“rti
+    one:   1 atvÄ“rts
+    other: "%{count} atvÄ“rti"
+  label_x_closed_issues_abbr:
+    zero:  0 slÄ“gti
+    one:   1 slÄ“gts
+    other: "%{count} slÄ“gti"
+  label_total: KopÄ
+  label_permissions: AtÄ¼aujas
+  label_current_status: PaÅ¡reizÄ“jais statuss
+  label_new_statuses_allowed: Jauni statusi atÄ¼auti
+  label_all: visi
+  label_none: neviens
+  label_nobody: nekas
+  label_next: NÄkoÅ¡ais
+  label_previous: IepriekÅ¡Ä“jais
+  label_used_by: Izmanto
+  label_details: DetaÄ¼as
+  label_add_note: Pievienot piezÄ«mi
+  label_per_page: katrÄ lapÄ
+  label_calendar: KalendÄrs
+  label_months_from: mÄ“neÅ¡i no
+  label_gantt: Ganta diagramma
+  label_internal: IekÅ¡Ä“jais
+  label_last_changes: "pÄ“dÄ“jÄs %{count} izmaiÅ†as"
+  label_change_view_all: SkatÄ«t visas izmaiÅ†as
+  label_personalize_page: PielÄgot Å¡o lapu
+  label_comment: KomentÄrs
+  label_comment_plural: KomentÄri
+  label_x_comments:
+    zero: nav komentÄru
+    one: 1 komentÄrs
+    other: "%{count} komentÄri"
+  label_comment_add: Pievienot komentÄru
+  label_comment_added: KomentÄrs pievienots
+  label_comment_delete: DzÄ“st komentÄrus
+  label_query: PielÄgots pieprasÄ«jums
+  label_query_plural: PielÄgoti pieprasÄ«jumi
+  label_query_new: Jauns pieprasÄ«jums
+  label_filter_add: Pievienot filtru
+  label_filter_plural: Filtri
+  label_equals: ir
+  label_not_equals: nav
+  label_in_less_than: ir mazÄk kÄ
+  label_in_more_than: ir vairÄk kÄ
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: iekÅ¡
+  label_today: Å¡odien
+  label_all_time: visu laiku
+  label_yesterday: vakar
+  label_this_week: Å¡onedÄ“Ä¼
+  label_last_week: pagÄjuÅ¡o Å¡onedÄ“Ä¼
+  label_last_n_days: "pÄ“dÄ“jÄs %{count} dienas"
+  label_this_month: Å¡omÄ“nes
+  label_last_month: pagÄjuÅ¡o mÄ“nes
+  label_this_year: Å¡ogad
+  label_date_range: Datumu apgabals
+  label_less_than_ago: mazÄk kÄ dienas iepriekÅ¡
+  label_more_than_ago: vairÄk kÄ dienas iepriekÅ¡
+  label_ago: dienas iepriekÅ¡
+  label_contains: satur
+  label_not_contains: nesatur
+  label_day_plural: dienas
+  label_repository: Repozitorijs
+  label_repository_plural: Repozitoriji
+  label_browse: PÄrlÅ«kot
+  label_branch: Zars
+  label_tag: Birka
+  label_revision: RevÄ«zija
+  label_revision_plural: RevÄ«zijas
+  label_revision_id: "RevÄ«zija %{value}"
+  label_associated_revisions: SaistÄ«tÄs revÄ«zijas
+  label_added: pievienots
+  label_modified: modificÄ“ts
+  label_copied: nokopÄ“ts
+  label_renamed: pÄrsaukts
+  label_deleted: dzÄ“sts
+  label_latest_revision: PÄ“dÄ“jÄ revÄ«zija
+  label_latest_revision_plural: PÄ“dÄ“jÄs revÄ«zijas
+  label_view_revisions: SkatÄ«t revÄ«zijas
+  label_view_all_revisions: SkatÄ«t visas revÄ«zijas
+  label_max_size: MaksimÄlais izmÄ“rs
+  label_sort_highest: PÄrvietot uz augÅ¡u
+  label_sort_higher: PÄrvietot soli augÅ¡up
+  label_sort_lower: PÄrvietot uz leju
+  label_sort_lowest: PÄrvietot vienu soli uz leju
+  label_roadmap: CeÄ¼vedis
+  label_roadmap_due_in: "SagaidÄms pÄ“c %{value}"
+  label_roadmap_overdue: "nokavÄ“ts %{value}"
+  label_roadmap_no_issues: Å ai versijai nav uzdevumu
+  label_search: MeklÄ“t
+  label_result_plural: RezultÄti
+  label_all_words: Visi vÄrdi
+  label_wiki: Wiki
+  label_wiki_edit: Wiki labojums
+  label_wiki_edit_plural: Wiki labojumi
+  label_wiki_page: Wiki lapa
+  label_wiki_page_plural: Wiki lapas
+  label_index_by_title: IndeksÄ“t pÄ“c nosaukuma
+  label_index_by_date: IndeksÄ“t pÄ“c datuma
+  label_current_version: TekoÅ¡Ä versija
+  label_preview: PriekÅ¡skatÄ«jums
+  label_feed_plural: Barotnes
+  label_changes_details: Visu izmaiÅ†u detaÄ¼as
+  label_issue_tracking: Uzdevumu uzskaite
+  label_spent_time: PavadÄ«tais laiks
+  label_f_hour: "%{value} stunda"
+  label_f_hour_plural: "%{value} stundas"
+  label_time_tracking: Laika uzskaite
+  label_change_plural: IzmaiÅ†as
+  label_statistics: Statistika
+  label_commits_per_month: Nodevumi mÄ“nesÄ«
+  label_commits_per_author: Nodevumi no autora
+  label_view_diff: SkatÄ«t atÅ¡Ä·irÄ«bas
+  label_diff_inline: iekÄ¼auts
+  label_diff_side_by_side: blakus
+  label_options: Opcijas
+  label_copy_workflow_from: KopÄ“t darba plÅ«smu no
+  label_permissions_report: AtÄ¼auju atskaite
+  label_watched_issues: VÄ“rotie uzdevumi
+  label_related_issues: SaistÄ«tie uzdevumi
+  label_applied_status: PieÅ¡Ä·irtais statuss
+  label_loading: LÄdÄ“jas...
+  label_relation_new: Jauna relÄcija
+  label_relation_delete: DzÄ“st relÄciju
+  label_relates_to: saistÄ«ts ar
+  label_duplicates: dublikÄti
+  label_duplicated_by: dublÄ“jas ar
+  label_blocks: bloÄ·Ä“
+  label_blocked_by: nobloÄ·Ä“jis
+  label_precedes: pirms
+  label_follows: seko
+  label_end_to_start: no beigÄm uz sÄkumu
+  label_end_to_end: no beigÄm uz beigÄm
+  label_start_to_start: no sÄkuma uz sÄkumu
+  label_start_to_end: no sÄkuma uz beigÄm
+  label_stay_logged_in: AtcerÄ“ties mani
+  label_disabled: izslÄ“gts
+  label_show_completed_versions: RÄdÄ«t pabeigtÄs versijas
+  label_me: es
+  label_board: Forums
+  label_board_new: Jauns forums
+  label_board_plural: Forumi
+  label_board_locked: SlÄ“gts
+  label_board_sticky: SvarÄ«gs
+  label_topic_plural: TÄ“mas
+  label_message_plural: ZiÅ†as
+  label_message_last: PÄ“dÄ“jÄ ziÅ†a
+  label_message_new: Jauna ziÅ†a
+  label_message_posted: ZiÅ†a pievienota
+  label_reply_plural: Atbildes
+  label_send_information: SÅ«tÄ«t konta informÄciju lietotÄjam
+  label_year: Gads
+  label_month: MÄ“nesis
+  label_week: NedÄ“Ä¼a
+  label_date_from: No
+  label_date_to: Kam
+  label_language_based: Izmantot lietotÄja valodu
+  label_sort_by: "KÄrtot pÄ“c %{value}"
+  label_send_test_email: "SÅ«tÄ«t testa e-pastu"
+  label_feeds_access_key: RSS piekÄ¼uves atslÄ“ga
+  label_missing_feeds_access_key: TrÅ«kst RSS piekÄ¼uves atslÄ“gas
+  label_feeds_access_key_created_on: "RSS piekÄ¼uves atslÄ“ga izveidota pirms %{value}"
+  label_module_plural: ModuÄ¼i
+  label_added_time_by: "Pievienojis %{author} pirms %{age}"
+  label_updated_time_by: "Atjaunojis %{author} pirms %{age}"
+  label_updated_time: "Atjaunots pirms %{value}"
+  label_jump_to_a_project: PÄriet uz projektu...
+  label_file_plural: Datnes
+  label_changeset_plural: IzmaiÅ†u kopumi
+  label_default_columns: NoklusÄ“tÄs kolonnas
+  label_no_change_option: (Nav izmaiÅ†u)
+  label_bulk_edit_selected_issues: Labot visus izvÄ“lÄ“tos uzdevumus
+  label_theme: TÄ“ma
+  label_default: NoklusÄ“ts
+  label_search_titles_only: MeklÄ“t tikai nosaukumos
+  label_user_mail_option_all: "Par visiem notikumiem visos manos projektos"
+  label_user_mail_option_selected: "Par visiem notikumiem tikai izvÄ“lÄ“tajos projektos..."
+  label_user_mail_no_self_notified: "NeziÅ†ot man par izmaiÅ†Äm, kuras veicu es pats"
+  label_registration_activation_by_email: "konta aktivizÄcija caur e-pastu"
+  label_registration_manual_activation: manuÄlÄ konta aktivizÄcija
+  label_registration_automatic_activation: automÄtiskÄ konta aktivizÄcija
+  label_display_per_page: "RÄdÄ«t vienÄ lapÄ: %{value}"
+  label_age: Vecums
+  label_change_properties: MainÄ«t atribÅ«tus
+  label_general: Galvenais
+  label_more: VÄ“l
+  label_scm: SCM
+  label_plugins: SpraudÅ†i
+  label_ldap_authentication: LDAP pilnvaroÅ¡ana
+  label_downloads_abbr: L-lÄd.
+  label_optional_description: "Apraksts (neobligÄts)"
+  label_add_another_file: Pievienot citu failu
+  label_preferences: PriekÅ¡rocÄ«bas
+  label_chronological_order: HronoloÄ£iskÄ kÄrtÄ«bÄ
+  label_reverse_chronological_order: Apgriezti hronoloÄ£iskÄ kÄrtÄ«bÄ
+  label_planning: PlÄnoÅ¡ana
+  label_incoming_emails: "IenÄkoÅ¡ie e-pasti"
+  label_generate_key: Ä¢enerÄ“t atslÄ“gu
+  label_issue_watchers: VÄ“rotÄji
+  label_example: PiemÄ“rs
+  label_display: RÄdÄ«t
+  label_sort: KÄrtot
+  label_ascending: AugoÅ¡i
+  label_descending: DilstoÅ¡i
+  label_date_from_to: "No %{start} lÄ«dz %{end}"
+  label_wiki_content_added: Wiki lapa pievienota
+  label_wiki_content_updated: Wiki lapa atjaunota
+  label_group: Grupa
+  label_group_plural: Grupas
+  label_group_new: Jauna grupa
+  label_time_entry_plural: PavadÄ«tais laiks
+  label_version_sharing_none: Nav koplietoÅ¡anai
+  label_version_sharing_descendants: Ar apakÅ¡projektiem
+  label_version_sharing_hierarchy: Ar projektu hierarhiju
+  label_version_sharing_tree: Ar projekta koku
+  label_version_sharing_system: Ar visiem projektiem
+  label_update_issue_done_ratios: Atjaunot uzdevuma veikuma attiecÄ«bu
+  label_copy_source: Avots
+  label_copy_target: MÄ“rÄ·is
+  label_copy_same_as_target: TÄds pats kÄ mÄ“rÄ·is
+  label_display_used_statuses_only: "RÄdÄ«t tikai statusus, ko lieto Å¡is trakeris"
+  label_api_access_key: API pieejas atslÄ“ga
+  label_missing_api_access_key: TrÅ«kst API pieejas atslÄ“ga
+  label_api_access_key_created_on: "API pieejas atslÄ“ga izveidota pirms %{value}"
+
+  button_login: PieslÄ“gties
+  button_submit: NosÅ«tÄ«t
+  button_save: SaglabÄt
+  button_check_all: AtzÄ«mÄ“t visu
+  button_uncheck_all: NoÅ†emt visus atzÄ«mÄ“jumus
+  button_delete: DzÄ“st
+  button_create: Izveidot
+  button_create_and_continue: Izveidot un turpinÄt
+  button_test: TestÄ“t
+  button_edit: Labot
+  button_add: Pievienot
+  button_change: MainÄ«t
+  button_apply: ApstiprinÄt
+  button_clear: NotÄ«rÄ«t
+  button_lock: SlÄ“gt
+  button_unlock: AtslÄ“gt
+  button_download: LejuplÄdÄ“t
+  button_list: Saraksts
+  button_view: Skats
+  button_move: PÄrvietot
+  button_move_and_follow: PÄrvietot un sekot
+  button_back: AtpakaÄ¼
+  button_cancel: Atcelt
+  button_activate: AktivizÄ“t
+  button_sort: KÄrtot
+  button_log_time: Ilgs laiks
+  button_rollback: Atjaunot uz Å¡o versiju
+  button_watch: VÄ“rot
+  button_unwatch: NevÄ“rot
+  button_reply: AtbildÄ“t
+  button_archive: ArhivÄ“t
+  button_unarchive: AtarhivÄ“t
+  button_reset: AtiestatÄ«t
+  button_rename: PÄrsaukt
+  button_change_password: MainÄ«t paroli
+  button_copy: KopÄ“t
+  button_copy_and_follow: KopÄ“t un sekot
+  button_annotate: PierakstÄ«t paskaidrojumu
+  button_update: Atjaunot
+  button_configure: KonfigurÄ“t
+  button_quote: CitÄts
+  button_duplicate: DublÄ“t
+  button_show: RÄdÄ«t
+
+  status_active: aktÄ«vs
+  status_registered: reÄ£istrÄ“ts
+  status_locked: slÄ“gts
+
+  version_status_open: atvÄ“rta
+  version_status_locked: slÄ“gta
+  version_status_closed: aizvÄ“rta
+
+  field_active: AktÄ«vs
+
+  text_select_mail_notifications: "IzvÄ“lieties darbÄ«bas, par kurÄm vÄ“laties saÅ†emt ziÅ†ojumus e-pastÄ"
+  text_regexp_info: "piem. ^[A-Z0-9]+$"
+  text_min_max_length_info: "0 nozÄ«mÄ“, ka nav ierobeÅ¾ojumu"
+  text_project_destroy_confirmation: "Vai tieÅ¡Äm vÄ“laties dzÄ“st Å¡o projektu un ar to saistÄ«tos datus?"
+  text_subprojects_destroy_warning: "TÄ apakÅ¡projekts(i): %{value} arÄ« tiks dzÄ“sts(i)."
+  text_workflow_edit: Lai labotu darba plÅ«smu, izvÄ“lieties lomu un trakeri
+  text_are_you_sure: "Vai esat pÄrliecinÄts?"
+  text_journal_changed: "%{label} mainÄ«ts no %{old} uz %{new}"
+  text_journal_set_to: "%{label} iestatÄ«ts uz %{value}"
+  text_journal_deleted: "%{label} dzÄ“sts (%{old})"
+  text_journal_added: "%{label} %{value} pievienots"
+  text_tip_issue_begin_day: uzdevums sÄkas Å¡odien
+  text_tip_issue_end_day: uzdevums beidzas Å¡odien
+  text_tip_issue_begin_end_day: uzdevums sÄkas un beidzas Å¡odien
+  text_caracters_maximum: "%{count} simboli maksimÄli."
+  text_caracters_minimum: "JÄbÅ«t vismaz %{count} simbolu garumÄ."
+  text_length_between: "Garums starp %{min} un %{max} simboliem."
+  text_tracker_no_workflow: Å im trakerim nav definÄ“ta darba plÅ«sma
+  text_unallowed_characters: NeatÄ¼auti simboli
+  text_comma_separated: "AtÄ¼autas vairÄkas vÄ“rtÄ«bas (atdalÄ«t ar komatu)."
+  text_line_separated: "AtÄ¼autas vairÄkas vÄ“rtÄ«bas (rakstÄ«t katru savÄ rindÄ)."
+  text_issues_ref_in_commit_messages: "IzmaiÅ†u salÄ«dzinÄÅ¡ana izejot no ziÅ†ojumiem"
+  text_issue_added: "Uzdevumu %{id} pievienojis %{author}."
+  text_issue_updated: "Uzdevumu %{id} atjaunojis %{author}."
+  text_wiki_destroy_confirmation: "Vai esat droÅ¡s, ka vÄ“laties dzÄ“st Å¡o wiki un visu tÄs saturu?"
+  text_issue_category_destroy_question: "DaÅ¾i uzdevumi (%{count}) ir nozÄ«mÄ“ti Å¡ai kategorijai. Ko JÅ«s vÄ“laties darÄ«t?"
+  text_issue_category_destroy_assignments: DzÄ“st kategoriju nozÄ«mÄ“jumus
+  text_issue_category_reassign_to: NozÄ«mÄ“t uzdevumus Å¡ai kategorijai
+  text_user_mail_option: "No neizvÄ“lÄ“tajiem projektiem JÅ«s saÅ†emsiet ziÅ†ojumus e-pastÄ tikai par notikumiem, kuriem JÅ«s sekojat vai kuros esat iesaistÄ«ts."
+  text_no_configuration_data: "Lomas, trakeri, uzdevumu statusi un darba plÅ«smas vÄ“l nav konfigurÄ“tas.\nÄ»oti ieteicams ielÄdÄ“t noklusÄ“to konfigurÄciju. PÄ“c ielÄdÄ“Å¡anas to bÅ«s iespÄ“jams modificÄ“t."
+  text_load_default_configuration: IelÄdÄ“t noklusÄ“to konfigurÄciju
+  text_status_changed_by_changeset: "ApstiprinÄts izmaiÅ†u kopumÄ %{value}."
+  text_issues_destroy_confirmation: 'Vai tieÅ¡Äm vÄ“laties dzÄ“st izvÄ“lÄ“to uzdevumu(us)?'
+  text_select_project_modules: 'IzvÄ“lieties moduÄ¼us Å¡im projektam:'
+  text_default_administrator_account_changed: NoklusÄ“tais administratora konts mainÄ«ts
+  text_file_repository_writable: Pielikumu direktorijÄ atÄ¼auts rakstÄ«t
+  text_plugin_assets_writable: SpraudÅ†u kataloga direktorijÄ atÄ¼auts rakstÄ«t
+  text_rmagick_available: "RMagick pieejams (neobligÄts)"
+  text_destroy_time_entries_question: "%{hours} stundas tika ziÅ†otas par uzdevumu, ko vÄ“laties dzÄ“st. Ko darÄ«t?"
+  text_destroy_time_entries: DzÄ“st ziÅ†otÄs stundas
+  text_assign_time_entries_to_project: PieÅ¡Ä·irt ziÅ†otÄs stundas projektam
+  text_reassign_time_entries: 'PieÅ¡Ä·irt ziÅ†otÄs stundas uzdevumam:'
+  text_user_wrote: "%{value} rakstÄ«ja:"
+  text_enumeration_destroy_question: "%{count} objekti ir pieÅ¡Ä·irti Å¡ai vÄ“rtÄ«bai."
+  text_enumeration_category_reassign_to: 'PieÅ¡Ä·irt tos Å¡ai vÄ“rtÄ«bai:'
+  text_email_delivery_not_configured: "E-pastu nosÅ«tÄ«Å¡ana nav konfigurÄ“ta, un ziÅ†ojumi ir izslÄ“gti.\nKonfigurÄ“jiet savu SMTP serveri datnÄ“ config/configuration.yml un pÄrstartÄ“jiet lietotni."
+  text_repository_usernames_mapping: "IzvÄ“lieties vai atjaunojiet Redmine lietotÄju, saistÄ«tu ar katru lietotÄjvÄrdu, kas atrodams repozitorija Å¾urnÄlÄ.\nLietotÄji ar to paÅ¡u Redmine un repozitorija lietotÄjvÄrdu bÅ«s saistÄ«ti automÄtiski."
+  text_diff_truncated: '... Å is diff tika noÅ¡Ä·elts, jo tas pÄrsniedz maksimÄlo izmÄ“ru, ko var parÄdÄ«t.'
+  text_custom_field_possible_values_info: 'Katra vÄ“rtÄ«bas savÄ rindÄ'
+  text_wiki_page_destroy_question: "Å ij lapai ir %{descendants} apakÅ¡lapa(as) un pÄ“cnÄcÄ“ji. Ko darÄ«t?"
+  text_wiki_page_nullify_children: "PaturÄ“t apakÅ¡lapas kÄ pamatlapas"
+  text_wiki_page_destroy_children: "DzÄ“st apakÅ¡lapas un visus pÄ“cnÄcÄ“jus"
+  text_wiki_page_reassign_children: "PieÅ¡Ä·irt apakÅ¡lapas Å¡ai lapai"
+  text_own_membership_delete_confirmation: "JÅ«s tÅ«lÄ«t dzÄ“sÄ«siet daÅ¾as vai visas atÄ¼aujas, un Jums pÄ“c tam var nebÅ«t atÄ¼auja labot Å¡o projektu.\nVai turpinÄt?"
+
+  default_role_manager: MenedÅ¾eris
+  default_role_developer: IzstrÄdÄtÄjs
+  default_role_reporter: ZiÅ†otÄjs
+  default_tracker_bug: KÄ¼Å«da
+  default_tracker_feature: IezÄ«me
+  default_tracker_support: Atbalsts
+  default_issue_status_new: Jauns
+  default_issue_status_in_progress: AttÄ«stÄ«bÄ
+  default_issue_status_resolved: AtrisinÄts
+  default_issue_status_feedback: Atsauksmes
+  default_issue_status_closed: SlÄ“gts
+  default_issue_status_rejected: NoraidÄ«ts
+  default_doc_category_user: LietotÄja dokumentÄcija
+  default_doc_category_tech: TehniskÄ dokumentÄcija
+  default_priority_low: Zema
+  default_priority_normal: NormÄla
+  default_priority_high: Augsta
+  default_priority_urgent: Steidzama
+  default_priority_immediate: TÅ«lÄ«tÄ“ja
+  default_activity_design: Dizains
+  default_activity_development: IzstrÄdÄÅ¡ana
+
+  enumeration_issue_priorities: Uzdevumu prioritÄtes
+  enumeration_doc_categories: Dokumentu kategorijas
+  enumeration_activities: AktivitÄtes (laika uzskaite)
+  enumeration_system_activity: SistÄ“mas aktivitÄtes
+
+  error_can_not_delete_custom_field: Unable to delete custom field
+  permission_manage_subtasks: Manage subtasks
+  label_profile: Profile
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  field_parent_issue: Parent task
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_subtask_plural: Subtasks
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  label_project_copy_notifications: Send email notifications during the project copy
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: KodÄ“t ziÅ†ojumus
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 uzdevums
+    one:   1 uzdevums
+    other: "%{count} uzdevumi"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: visi
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: Ar apakÅ¡projektiem
+  label_cross_project_tree: Ar projekta koku
+  label_cross_project_hierarchy: Ar projektu hierarhiju
+  label_cross_project_system: Ar visiem projektiem
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: KopÄ
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e7/e735d81a3ddf113ea34dcc2d3e6455904085deeb.svn-base
--- a/.svn/pristine/e7/e735d81a3ddf113ea34dcc2d3e6455904085deeb.svn-base
+++ /dev/null
@@ -1,97 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module MimeType
-
-    MIME_TYPES = {
-      'text/plain' => 'txt,tpl,properties,patch,diff,ini,readme,install,upgrade',
-      'text/css' => 'css',
-      'text/html' => 'html,htm,xhtml',
-      'text/jsp' => 'jsp',
-      'text/x-c' => 'c,cpp,cc,h,hh',
-      'text/x-csharp' => 'cs',
-      'text/x-java' => 'java',
-      'text/x-javascript' => 'js',
-      'text/x-html-template' => 'rhtml',
-      'text/x-perl' => 'pl,pm',
-      'text/x-php' => 'php,php3,php4,php5',
-      'text/x-python' => 'py',
-      'text/x-ruby' => 'rb,rbw,ruby,rake,erb',
-      'text/x-csh' => 'csh',
-      'text/x-sh' => 'sh',
-      'text/xml' => 'xml,xsd,mxml',
-      'text/yaml' => 'yml,yaml',
-      'text/csv' => 'csv',
-      'text/x-po' => 'po',
-      'image/gif' => 'gif',
-      'image/jpeg' => 'jpg,jpeg,jpe',
-      'image/png' => 'png',
-      'image/tiff' => 'tiff,tif',
-      'image/x-ms-bmp' => 'bmp',
-      'image/x-xpixmap' => 'xpm',
-      'application/pdf' => 'pdf',
-      'application/rtf' => 'rtf',
-      'application/msword' => 'doc',
-      'application/vnd.ms-excel' => 'xls',
-      'application/vnd.ms-powerpoint' => 'ppt,pps',
-      'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
-      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
-      'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
-      'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx',
-      'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
-      'application/vnd.oasis.opendocument.text' => 'odt',
-      'application/vnd.oasis.opendocument.presentation' => 'odp',
-      'application/x-7z-compressed' => '7z',
-      'application/x-rar-compressed' => 'rar',
-      'application/x-tar' => 'tar',
-      'application/zip' => 'zip',
-      'application/x-gzip' => 'gz',
-    }.freeze
-
-    EXTENSIONS = MIME_TYPES.inject({}) do |map, (type, exts)|
-      exts.split(',').each {|ext| map[ext.strip] = type}
-      map
-    end
-
-    # returns mime type for name or nil if unknown
-    def self.of(name)
-      return nil unless name
-      m = name.to_s.match(/(^|\.)([^\.]+)$/)
-      EXTENSIONS[m[2].downcase] if m
-    end
-
-    # Returns the css class associated to
-    # the mime type of name
-    def self.css_class_of(name)
-      mime = of(name)
-      mime && mime.gsub('/', '-')
-    end
-
-    def self.main_mimetype_of(name)
-      mimetype = of(name)
-      mimetype.split('/').first if mimetype
-    end
-
-    # return true if mime-type for name is type/*
-    # otherwise false
-    def self.is_type?(type, name)
-      main_mimetype = main_mimetype_of(name)
-      type.to_s == main_mimetype
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e7/e77868c1cdde27df85411c7926b5e0864306b501.svn-base
--- a/.svn/pristine/e7/e77868c1cdde27df85411c7926b5e0864306b501.svn-base
+++ /dev/null
@@ -1,143 +0,0 @@
-module CodeRay
-module Styles
-  
-  # A colorful theme using CSS 3 colors (with alpha channel).
-  class Alpha < Style
-
-    register_for :alpha
-
-    code_background = 'hsl(0,0%,95%)'
-    numbers_background = 'hsl(180,65%,90%)'
-    border_color = 'silver'
-    normal_color = 'black'
-
-    CSS_MAIN_STYLES = <<-MAIN  # :nodoc:
-.CodeRay {
-  background-color: #{code_background};
-  border: 1px solid #{border_color};
-  color: #{normal_color};
-}
-.CodeRay pre {
-  margin: 0px;
-}
-
-span.CodeRay { white-space: pre; border: 0px; padding: 2px; }
-
-table.CodeRay { border-collapse: collapse; width: 100%; padding: 2px; }
-table.CodeRay td { padding: 2px 4px; vertical-align: top; }
-
-.CodeRay .line-numbers {
-  background-color: #{numbers_background};
-  color: gray;
-  text-align: right;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  user-select: none;
-}
-.CodeRay .line-numbers a {
-  background-color: #{numbers_background} !important;
-  color: gray !important;
-  text-decoration: none !important;
-}
-.CodeRay .line-numbers a:target { color: blue !important; }
-.CodeRay .line-numbers .highlighted { color: red !important; }
-.CodeRay .line-numbers .highlighted a { color: red !important; }
-.CodeRay span.line-numbers { padding: 0px 4px; }
-.CodeRay .line { display: block; float: left; width: 100%; }
-.CodeRay .code { width: 100%; }
-.CodeRay .code pre { overflow: auto; }
-    MAIN
-
-    TOKEN_COLORS = <<-'TOKENS'
-.debug { color: white !important; background: blue !important; }
-
-.annotation { color:#007 }
-.attribute-name { color:#b48 }
-.attribute-value { color:#700 }
-.binary { color:#509 }
-.char .content { color:#D20 }
-.char .delimiter { color:#710 }
-.char { color:#D20 }
-.class { color:#B06; font-weight:bold }
-.class-variable { color:#369 }
-.color { color:#0A0 }
-.comment { color:#777 }
-.comment .char { color:#444 }
-.comment .delimiter { color:#444 }
-.complex { color:#A08 }
-.constant { color:#036; font-weight:bold }
-.decorator { color:#B0B }
-.definition { color:#099; font-weight:bold }
-.delimiter { color:black }
-.directive { color:#088; font-weight:bold }
-.doc { color:#970 }
-.doc-string { color:#D42; font-weight:bold }
-.doctype { color:#34b }
-.entity { color:#800; font-weight:bold }
-.error { color:#F00; background-color:#FAA }
-.escape  { color:#666 }
-.exception { color:#C00; font-weight:bold }
-.float { color:#60E }
-.function { color:#06B; font-weight:bold }
-.global-variable { color:#d70 }
-.hex { color:#02b }
-.imaginary { color:#f00 }
-.include { color:#B44; font-weight:bold }
-.inline { background-color: hsla(0,0%,0%,0.07); color: black }
-.inline-delimiter { font-weight: bold; color: #666 }
-.instance-variable { color:#33B }
-.integer  { color:#00D }
-.key .char { color: #60f }
-.key .delimiter { color: #404 }
-.key { color: #606 }
-.keyword { color:#080; font-weight:bold }
-.label { color:#970; font-weight:bold }
-.local-variable { color:#963 }
-.namespace { color:#707; font-weight:bold }
-.octal { color:#40E }
-.operator { }
-.predefined { color:#369; font-weight:bold }
-.predefined-constant { color:#069 }
-.predefined-type { color:#0a5; font-weight:bold }
-.preprocessor { color:#579 }
-.pseudo-class { color:#00C; font-weight:bold }
-.regexp .content { color:#808 }
-.regexp .delimiter { color:#404 }
-.regexp .modifier { color:#C2C }
-.regexp { background-color:hsla(300,100%,50%,0.06); }
-.reserved { color:#080; font-weight:bold }
-.shell .content { color:#2B2 }
-.shell .delimiter { color:#161 }
-.shell { background-color:hsla(120,100%,50%,0.06); }
-.string .char { color: #b0b }
-.string .content { color: #D20 }
-.string .delimiter { color: #710 }
-.string .modifier { color: #E40 }
-.string { background-color:hsla(0,100%,50%,0.05); }
-.symbol .content { color:#A60 }
-.symbol .delimiter { color:#630 }
-.symbol { color:#A60 }
-.tag { color:#070 }
-.type { color:#339; font-weight:bold }
-.value { color: #088; }
-.variable  { color:#037 }
-
-.insert { background: hsla(120,100%,50%,0.12) }
-.delete { background: hsla(0,100%,50%,0.12) }
-.change { color: #bbf; background: #007; }
-.head { color: #f8f; background: #505 }
-.head .filename { color: white; }
-
-.delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
-.insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
-
-.insert .insert { color: #0c0; background:transparent; font-weight:bold }
-.delete .delete { color: #c00; background:transparent; font-weight:bold }
-.change .change { color: #88f }
-.head .head { color: #f4f }
-    TOKENS
-
-  end
-
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e7/e77d4ee988f0ee0cedc3ea42fee306534d1cb4e6.svn-base
--- a/.svn/pristine/e7/e77d4ee988f0ee0cedc3ea42fee306534d1cb4e6.svn-base
+++ /dev/null
@@ -1,553 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'iconv'
-require 'fpdf/chinese'
-require 'fpdf/japanese'
-require 'fpdf/korean'
-require 'core/rmagick'
-
-module Redmine
-  module Export
-    module PDF
-      include ActionView::Helpers::TextHelper
-      include ActionView::Helpers::NumberHelper
-      include IssuesHelper
-
-      class ITCPDF < TCPDF
-        include Redmine::I18n
-        attr_accessor :footer_date
-
-        def initialize(lang)
-          @@k_path_cache = Rails.root.join('tmp', 'pdf')
-          FileUtils.mkdir_p @@k_path_cache unless File::exist?(@@k_path_cache)
-          set_language_if_valid lang
-          pdf_encoding = l(:general_pdf_encoding).upcase
-          super('P', 'mm', 'A4', (pdf_encoding == 'UTF-8'), pdf_encoding)
-          case current_language.to_s.downcase
-          when 'vi'
-            @font_for_content = 'DejaVuSans'
-            @font_for_footer  = 'DejaVuSans'
-          else
-            case pdf_encoding
-            when 'UTF-8'
-              @font_for_content = 'FreeSans'
-              @font_for_footer  = 'FreeSans'
-            when 'CP949'
-              extend(PDF_Korean)
-              AddUHCFont()
-              @font_for_content = 'UHC'
-              @font_for_footer  = 'UHC'
-            when 'CP932', 'SJIS', 'SHIFT_JIS'
-              extend(PDF_Japanese)
-              AddSJISFont()
-              @font_for_content = 'SJIS'
-              @font_for_footer  = 'SJIS'
-            when 'GB18030'
-              extend(PDF_Chinese)
-              AddGBFont()
-              @font_for_content = 'GB'
-              @font_for_footer  = 'GB'
-            when 'BIG5'
-              extend(PDF_Chinese)
-              AddBig5Font()
-              @font_for_content = 'Big5'
-              @font_for_footer  = 'Big5'
-            else
-              @font_for_content = 'Arial'
-              @font_for_footer  = 'Helvetica'
-            end
-          end
-          SetCreator(Redmine::Info.app_name)
-          SetFont(@font_for_content)
-        end
-
-        def SetFontStyle(style, size)
-          SetFont(@font_for_content, style, size)
-        end
-
-        def SetTitle(txt)
-          txt = begin
-            utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
-            hextxt = "<FEFF"  # FEFF is BOM
-            hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
-            hextxt << ">"
-          rescue
-            txt
-          end || ''
-          super(txt)
-        end
-
-        def textstring(s)
-          # Format a text string
-          if s =~ /^</  # This means the string is hex-dumped.
-            return s
-          else
-            return '('+escape(s)+')'
-          end
-        end
-
-        def fix_text_encoding(txt)
-          RDMPdfEncoding::rdm_from_utf8(txt, l(:general_pdf_encoding))
-        end
-
-        def RDMCell(w ,h=0, txt='', border=0, ln=0, align='', fill=0, link='')
-          Cell(w, h, fix_text_encoding(txt), border, ln, align, fill, link)
-        end
-
-        def RDMMultiCell(w, h=0, txt='', border=0, align='', fill=0, ln=1)
-          MultiCell(w, h, fix_text_encoding(txt), border, align, fill, ln)
-        end
-
-        def RDMwriteHTMLCell(w, h, x, y, txt='', attachments=[], border=0, ln=1, fill=0)
-          @attachments = attachments
-          writeHTMLCell(w, h, x, y,
-            fix_text_encoding(
-              Redmine::WikiFormatting.to_html(Setting.text_formatting, txt)),
-            border, ln, fill)
-        end
-
-        def getImageFilename(attrname)
-          # attrname: general_pdf_encoding string file/uri name
-          atta = RDMPdfEncoding.attach(@attachments, attrname, l(:general_pdf_encoding))
-          if atta
-            return atta.diskfile
-          else
-            return nil
-          end
-        end
-
-        def Footer
-          SetFont(@font_for_footer, 'I', 8)
-          SetY(-15)
-          SetX(15)
-          RDMCell(0, 5, @footer_date, 0, 0, 'L')
-          SetY(-15)
-          SetX(-30)
-          RDMCell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
-        end
-      end
-
-      # Returns a PDF string of a list of issues
-      def issues_to_pdf(issues, project, query)
-        pdf = ITCPDF.new(current_language)
-        title = query.new_record? ? l(:label_issue_plural) : query.name
-        title = "#{project} - #{title}" if project
-        pdf.SetTitle(title)
-        pdf.alias_nb_pages
-        pdf.footer_date = format_date(Date.today)
-        pdf.SetAutoPageBreak(false)
-        pdf.AddPage("L")
-
-        # Landscape A4 = 210 x 297 mm
-        page_height   = 210
-        page_width    = 297
-        right_margin  = 10
-        bottom_margin = 20
-        col_id_width  = 10
-        row_height    = 5
-
-        # column widths
-        table_width = page_width - right_margin - 10  # fixed left margin
-        col_width = []
-        unless query.columns.empty?
-          col_width = query.columns.collect do |c|
-            (c.name == :subject || (c.is_a?(QueryCustomFieldColumn) &&
-              ['string', 'text'].include?(c.custom_field.field_format))) ? 4.0 : 1.0
-          end
-          ratio = (table_width - col_id_width) / col_width.inject(0) {|s,w| s += w}
-          col_width = col_width.collect {|w| w * ratio}
-        end
-
-        # title
-        pdf.SetFontStyle('B',11)
-        pdf.RDMCell(190,10, title)
-        pdf.Ln
-
-        # headers
-        pdf.SetFontStyle('B',8)
-        pdf.SetFillColor(230, 230, 230)
-
-        # render it background to find the max height used
-        base_x = pdf.GetX
-        base_y = pdf.GetY
-        max_height = issues_to_pdf_write_cells(pdf, query.columns, col_width, row_height, true)
-        pdf.Rect(base_x, base_y, table_width, max_height, 'FD');
-        pdf.SetXY(base_x, base_y);
-
-        # write the cells on page
-        pdf.RDMCell(col_id_width, row_height, "#", "T", 0, 'C', 1)
-        issues_to_pdf_write_cells(pdf, query.columns, col_width, row_height, true)
-        issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
-        pdf.SetY(base_y + max_height);
-
-        # rows
-        pdf.SetFontStyle('',8)
-        pdf.SetFillColor(255, 255, 255)
-        previous_group = false
-        issue_list(issues) do |issue, level|
-          if query.grouped? &&
-               (group = query.group_by_column.value(issue)) != previous_group
-            pdf.SetFontStyle('B',9)
-            pdf.RDMCell(277, row_height,
-              (group.blank? ? 'None' : group.to_s) + " (#{query.issue_count_by_group[group]})",
-              1, 1, 'L')
-            pdf.SetFontStyle('',8)
-            previous_group = group
-          end
-          # fetch all the row values
-          col_values = query.columns.collect do |column|
-            s = if column.is_a?(QueryCustomFieldColumn)
-              cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
-              show_value(cv)
-            else
-              value = issue.send(column.name)
-              if column.name == :subject
-                value = "  " * level + value
-              end
-              if value.is_a?(Date)
-                format_date(value)
-              elsif value.is_a?(Time)
-                format_time(value)
-              else
-                value
-              end
-            end
-            s.to_s
-          end
-
-          # render it off-page to find the max height used
-          base_x = pdf.GetX
-          base_y = pdf.GetY
-          pdf.SetY(2 * page_height)
-          max_height = issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
-          pdf.SetXY(base_x, base_y)
-
-          # make new page if it doesn't fit on the current one
-          space_left = page_height - base_y - bottom_margin
-          if max_height > space_left
-            pdf.AddPage("L")
-            base_x = pdf.GetX
-            base_y = pdf.GetY
-          end
-
-          # write the cells on page
-          pdf.RDMCell(col_id_width, row_height, issue.id.to_s, "T", 0, 'C', 1)
-          issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
-          issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
-          pdf.SetY(base_y + max_height);
-        end
-
-        if issues.size == Setting.issues_export_limit.to_i
-          pdf.SetFontStyle('B',10)
-          pdf.RDMCell(0, row_height, '...')
-        end
-        pdf.Output
-      end
-
-      # Renders MultiCells and returns the maximum height used
-      def issues_to_pdf_write_cells(pdf, col_values, col_widths,
-                                    row_height, head=false)
-        base_y = pdf.GetY
-        max_height = row_height
-        col_values.each_with_index do |column, i|
-          col_x = pdf.GetX
-          if head == true
-            pdf.RDMMultiCell(col_widths[i], row_height, column.caption, "T", 'L', 1)
-          else
-            pdf.RDMMultiCell(col_widths[i], row_height, column, "T", 'L', 1)
-          end
-          max_height = (pdf.GetY - base_y) if (pdf.GetY - base_y) > max_height
-          pdf.SetXY(col_x + col_widths[i], base_y);
-        end
-        return max_height
-      end
-
-      # Draw lines to close the row (MultiCell border drawing in not uniform)
-      def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y,
-                                     id_width, col_widths)
-        col_x = top_x + id_width
-        pdf.Line(col_x, top_y, col_x, lower_y)    # id right border
-        col_widths.each do |width|
-          col_x += width
-          pdf.Line(col_x, top_y, col_x, lower_y)  # columns right border
-        end
-        pdf.Line(top_x, top_y, top_x, lower_y)    # left border
-        pdf.Line(top_x, lower_y, col_x, lower_y)  # bottom border
-      end
-
-      # Returns a PDF string of a single issue
-      def issue_to_pdf(issue)
-        pdf = ITCPDF.new(current_language)
-        pdf.SetTitle("#{issue.project} - ##{issue.tracker} #{issue.id}")
-        pdf.alias_nb_pages
-        pdf.footer_date = format_date(Date.today)
-        pdf.AddPage
-        pdf.SetFontStyle('B',11)
-        buf = "#{issue.project} - #{issue.tracker} # #{issue.id}"
-        pdf.RDMMultiCell(190, 5, buf)
-        pdf.Ln
-        pdf.SetFontStyle('',8)
-        base_x = pdf.GetX
-        i = 1
-        issue.ancestors.each do |ancestor|
-          pdf.SetX(base_x + i)
-          buf = "#{ancestor.tracker} # #{ancestor.id} (#{ancestor.status.to_s}): #{ancestor.subject}"
-          pdf.RDMMultiCell(190 - i, 5, buf)
-          i += 1 if i < 35
-        end
-        pdf.Ln
-
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35,5, l(:field_status) + ":","LT")
-        pdf.SetFontStyle('',9)
-        pdf.RDMCell(60,5, issue.status.to_s,"RT")
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35,5, l(:field_priority) + ":","LT")
-        pdf.SetFontStyle('',9)
-        pdf.RDMCell(60,5, issue.priority.to_s,"RT")
-        pdf.Ln
-
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35,5, l(:field_author) + ":","L")
-        pdf.SetFontStyle('',9)
-        pdf.RDMCell(60,5, issue.author.to_s,"R")
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35,5, l(:field_category) + ":","L")
-        pdf.SetFontStyle('',9)
-        pdf.RDMCell(60,5, issue.category.to_s,"R")
-        pdf.Ln
-
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35,5, l(:field_created_on) + ":","L")
-        pdf.SetFontStyle('',9)
-        pdf.RDMCell(60,5, format_date(issue.created_on),"R")
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35,5, l(:field_assigned_to) + ":","L")
-        pdf.SetFontStyle('',9)
-        pdf.RDMCell(60,5, issue.assigned_to.to_s,"R")
-        pdf.Ln
-
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35,5, l(:field_updated_on) + ":","LB")
-        pdf.SetFontStyle('',9)
-        pdf.RDMCell(60,5, format_date(issue.updated_on),"RB")
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35,5, l(:field_due_date) + ":","LB")
-        pdf.SetFontStyle('',9)
-        pdf.RDMCell(60,5, format_date(issue.due_date),"RB")
-        pdf.Ln
-
-        for custom_value in issue.custom_field_values
-          pdf.SetFontStyle('B',9)
-          pdf.RDMCell(35,5, custom_value.custom_field.name + ":","L")
-          pdf.SetFontStyle('',9)
-          pdf.RDMMultiCell(155,5, (show_value custom_value),"R")
-        end
-
-        y0 = pdf.GetY
-
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35,5, l(:field_subject) + ":","LT")
-        pdf.SetFontStyle('',9)
-        pdf.RDMMultiCell(155,5, issue.subject,"RT")
-        pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY)
-
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(35+155, 5, l(:field_description), "LRT", 1)
-        pdf.SetFontStyle('',9)
-
-        # Set resize image scale
-        pdf.SetImageScale(1.6)
-        pdf.RDMwriteHTMLCell(35+155, 5, 0, 0,
-              issue.description.to_s, issue.attachments, "LRB")
-
-        unless issue.leaf?
-          # for CJK
-          truncate_length = ( l(:general_pdf_encoding).upcase == "UTF-8" ? 90 : 65 )
-  
-          pdf.SetFontStyle('B',9)
-          pdf.RDMCell(35+155,5, l(:label_subtask_plural) + ":", "LTR")
-          pdf.Ln
-          issue_list(issue.descendants.sort_by(&:lft)) do |child, level|
-            buf = truncate("#{child.tracker} # #{child.id}: #{child.subject}",
-                           :length => truncate_length)
-            level = 10 if level >= 10
-            pdf.SetFontStyle('',8)
-            pdf.RDMCell(35+135,5, (level >=1 ? "  " * level : "") + buf, "L")
-            pdf.SetFontStyle('B',8)
-            pdf.RDMCell(20,5, child.status.to_s, "R")
-            pdf.Ln
-          end
-        end
-
-        relations = issue.relations.select { |r| r.other_issue(issue).visible? }
-        unless relations.empty?
-          # for CJK
-          truncate_length = ( l(:general_pdf_encoding).upcase == "UTF-8" ? 80 : 60 )
-  
-          pdf.SetFontStyle('B',9)
-          pdf.RDMCell(35+155,5, l(:label_related_issues) + ":", "LTR")
-          pdf.Ln
-          relations.each do |relation|
-            buf = ""
-            buf += "#{l(relation.label_for(issue))} "
-            if relation.delay && relation.delay != 0
-              buf += "(#{l('datetime.distance_in_words.x_days', :count => relation.delay)}) "
-            end
-            if Setting.cross_project_issue_relations?
-              buf += "#{relation.other_issue(issue).project} - "
-            end
-            buf += "#{relation.other_issue(issue).tracker}" +
-                   " # #{relation.other_issue(issue).id}: #{relation.other_issue(issue).subject}"
-            buf = truncate(buf, :length => truncate_length)
-            pdf.SetFontStyle('', 8)
-            pdf.RDMCell(35+155-60, 5, buf, "L")
-            pdf.SetFontStyle('B',8)
-            pdf.RDMCell(20,5, relation.other_issue(issue).status.to_s, "")
-            pdf.RDMCell(20,5, format_date(relation.other_issue(issue).start_date), "")
-            pdf.RDMCell(20,5, format_date(relation.other_issue(issue).due_date), "R")
-            pdf.Ln
-          end
-        end
-        pdf.RDMCell(190,5, "", "T")
-        pdf.Ln
-
-        if issue.changesets.any? &&
-             User.current.allowed_to?(:view_changesets, issue.project)
-          pdf.SetFontStyle('B',9)
-          pdf.RDMCell(190,5, l(:label_associated_revisions), "B")
-          pdf.Ln
-          for changeset in issue.changesets
-            pdf.SetFontStyle('B',8)
-            csstr  = "#{l(:label_revision)} #{changeset.format_identifier} - "
-            csstr += format_time(changeset.committed_on) + " - " + changeset.author.to_s
-            pdf.RDMCell(190, 5, csstr)
-            pdf.Ln
-            unless changeset.comments.blank?
-              pdf.SetFontStyle('',8)
-              pdf.RDMwriteHTMLCell(190,5,0,0,
-                    changeset.comments.to_s, issue.attachments, "")
-            end
-            pdf.Ln
-          end
-        end
-
-        pdf.SetFontStyle('B',9)
-        pdf.RDMCell(190,5, l(:label_history), "B")
-        pdf.Ln
-        indice = 0
-        for journal in issue.journals.find(
-                          :all, :include => [:user, :details],
-                          :order => "#{Journal.table_name}.created_on ASC")
-          indice = indice + 1
-          pdf.SetFontStyle('B',8)
-          pdf.RDMCell(190,5,
-             "#" + indice.to_s +
-             " - " + format_time(journal.created_on) +
-             " - " + journal.user.name)
-          pdf.Ln
-          pdf.SetFontStyle('I',8)
-          for detail in journal.details
-            pdf.RDMMultiCell(190,5, "- " + show_detail(detail, true))
-          end
-          if journal.notes?
-            pdf.Ln unless journal.details.empty?
-            pdf.SetFontStyle('',8)
-            pdf.RDMwriteHTMLCell(190,5,0,0,
-                  journal.notes.to_s, issue.attachments, "")
-          end
-          pdf.Ln
-        end
-
-        if issue.attachments.any?
-          pdf.SetFontStyle('B',9)
-          pdf.RDMCell(190,5, l(:label_attachment_plural), "B")
-          pdf.Ln
-          for attachment in issue.attachments
-            pdf.SetFontStyle('',8)
-            pdf.RDMCell(80,5, attachment.filename)
-            pdf.RDMCell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
-            pdf.RDMCell(25,5, format_date(attachment.created_on),0,0,"R")
-            pdf.RDMCell(65,5, attachment.author.name,0,0,"R")
-            pdf.Ln
-          end
-        end
-        pdf.Output
-      end
-
-      # Returns a PDF string of a single wiki page
-      def wiki_to_pdf(page, project)
-        pdf = ITCPDF.new(current_language)
-        pdf.SetTitle("#{project} - #{page.title}")
-        pdf.alias_nb_pages
-        pdf.footer_date = format_date(Date.today)
-        pdf.AddPage
-        pdf.SetFontStyle('B',11)
-        pdf.RDMMultiCell(190,5,
-             "#{project} - #{page.title} - # #{page.content.version}")
-        pdf.Ln
-        # Set resize image scale
-        pdf.SetImageScale(1.6)
-        pdf.SetFontStyle('',9)
-        pdf.RDMwriteHTMLCell(190,5,0,0,
-              page.content.text.to_s, page.attachments, "TLRB")
-        if page.attachments.any?
-          pdf.Ln
-          pdf.SetFontStyle('B',9)
-          pdf.RDMCell(190,5, l(:label_attachment_plural), "B")
-          pdf.Ln
-          for attachment in page.attachments
-            pdf.SetFontStyle('',8)
-            pdf.RDMCell(80,5, attachment.filename)
-            pdf.RDMCell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
-            pdf.RDMCell(25,5, format_date(attachment.created_on),0,0,"R")
-            pdf.RDMCell(65,5, attachment.author.name,0,0,"R")
-            pdf.Ln
-          end
-        end
-        pdf.Output
-      end
-
-      class RDMPdfEncoding
-        def self.rdm_from_utf8(txt, encoding)
-          txt ||= ''
-          txt = Redmine::CodesetUtil.from_utf8(txt, encoding)
-          if txt.respond_to?(:force_encoding)
-            txt.force_encoding('ASCII-8BIT')
-          end
-          txt
-        end
-
-        def self.attach(attachments, filename, encoding)
-          filename_utf8 = Redmine::CodesetUtil.to_utf8(filename, encoding)
-          atta = nil
-          if filename_utf8 =~ /^[^\/"]+\.(gif|jpg|jpe|jpeg|png)$/i
-            atta = Attachment.latest_attach(attachments, filename_utf8)
-          end
-          if atta && atta.readable? && atta.visible?
-            return atta
-          else
-            return nil
-          end
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e7/e77ecc74553bd5c08ca184a88695f37ae32190fc.svn-base
--- a/.svn/pristine/e7/e77ecc74553bd5c08ca184a88695f37ae32190fc.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class ViewHelpersTest < ActionController::TestCase
-  tests AssetsController
-  
-  def setup
-    get :index
-  end
-  
-  def test_plugin_javascript_helpers
-    base_selector = "script[type='text/javascript']"
-    js_dir = "/plugin_assets/test_assets/javascripts"
-    assert_select "#{base_selector}[src='#{js_dir}/file.1.js']"
-    assert_select "#{base_selector}[src='#{js_dir}/file2.js']"
-  end
-
-  def test_plugin_stylesheet_helpers
-    base_selector = "link[media='screen'][rel='stylesheet'][type='text/css']"
-    css_dir = "/plugin_assets/test_assets/stylesheets"
-    assert_select "#{base_selector}[href='#{css_dir}/file.1.css']"
-    assert_select "#{base_selector}[href='#{css_dir}/file2.css']"
-  end
-
-  def test_plugin_image_helpers
-    assert_select "img[src='/plugin_assets/test_assets/images/image.png'][alt='Image']"
-  end
-
-  def test_plugin_layouts
-    get :index
-    assert_select "div[id='assets_layout']"
-  end  
-
-  def test_plugin_image_submit_helpers
-    assert_select "input[src='/plugin_assets/test_assets/images/image.png'][type='image']"
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e7/e788a5951a9b0031817bcfceb0ad2fbc3b5f9836.svn-base
--- /dev/null
+++ b/.svn/pristine/e7/e788a5951a9b0031817bcfceb0ad2fbc3b5f9836.svn-base
@@ -0,0 +1,115 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class TimeEntryQuery < Query
+
+  self.queried_class = TimeEntry
+
+  self.available_columns = [
+    QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
+    QueryColumn.new(:spent_on, :sortable => ["#{TimeEntry.table_name}.spent_on", "#{TimeEntry.table_name}.created_on"], :default_order => 'desc', :groupable => true),
+    QueryColumn.new(:user, :sortable => lambda {User.fields_for_order_statement}, :groupable => true),
+    QueryColumn.new(:activity, :sortable => "#{TimeEntryActivity.table_name}.position", :groupable => true),
+    QueryColumn.new(:issue, :sortable => "#{Issue.table_name}.id"),
+    QueryColumn.new(:comments),
+    QueryColumn.new(:hours, :sortable => "#{TimeEntry.table_name}.hours"),
+  ]
+
+  def initialize(attributes=nil, *args)
+    super attributes
+    self.filters ||= {}
+    add_filter('spent_on', '*') unless filters.present?
+  end
+
+  def initialize_available_filters
+    add_available_filter "spent_on", :type => :date_past
+
+    principals = []
+    if project
+      principals += project.principals.sort
+      unless project.leaf?
+        subprojects = project.descendants.visible.all
+        if subprojects.any?
+          add_available_filter "subproject_id",
+            :type => :list_subprojects,
+            :values => subprojects.collect{|s| [s.name, s.id.to_s] }
+          principals += Principal.member_of(subprojects)
+        end
+      end
+    else
+      if all_projects.any?
+        # members of visible projects
+        principals += Principal.member_of(all_projects)
+        # project filter
+        project_values = []
+        if User.current.logged? && User.current.memberships.any?
+          project_values << ["<< #{l(:label_my_projects).downcase} >>", "mine"]
+        end
+        project_values += all_projects_values
+        add_available_filter("project_id",
+          :type => :list, :values => project_values
+        ) unless project_values.empty?
+      end
+    end
+    principals.uniq!
+    principals.sort!
+    users = principals.select {|p| p.is_a?(User)}
+
+    users_values = []
+    users_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
+    users_values += users.collect{|s| [s.name, s.id.to_s] }
+    add_available_filter("user_id",
+      :type => :list_optional, :values => users_values
+    ) unless users_values.empty?
+
+    activities = (project ? project.activities : TimeEntryActivity.shared.active)
+    add_available_filter("activity_id",
+      :type => :list, :values => activities.map {|a| [a.name, a.id.to_s]}
+    ) unless activities.empty?
+
+    add_available_filter "comments", :type => :text
+    add_available_filter "hours", :type => :float
+
+    add_custom_fields_filters(TimeEntryCustomField.where(:is_filter => true).all)
+    add_associations_custom_fields_filters :project, :issue, :user
+  end
+
+  def available_columns
+    return @available_columns if @available_columns
+    @available_columns = self.class.available_columns.dup
+    @available_columns += TimeEntryCustomField.all.map {|cf| QueryCustomFieldColumn.new(cf) }
+    @available_columns += IssueCustomField.all.map {|cf| QueryAssociationCustomFieldColumn.new(:issue, cf) }
+    @available_columns
+  end
+
+  def default_columns_names
+    @default_columns_names ||= [:project, :spent_on, :user, :activity, :issue, :comments, :hours]
+  end
+
+  # Accepts :from/:to params as shortcut filters
+  def build_from_params(params)
+    super
+    if params[:from].present? && params[:to].present?
+      add_filter('spent_on', '><', [params[:from], params[:to]])
+    elsif params[:from].present?
+      add_filter('spent_on', '>=', [params[:from]])
+    elsif params[:to].present?
+      add_filter('spent_on', '<=', [params[:to]])
+    end
+    self
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e7/e797f09f8ee9ca99436baf7817780fe7558fef10.svn-base
--- a/.svn/pristine/e7/e797f09f8ee9ca99436baf7817780fe7558fef10.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-ï»¿// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("ÐÑÐ¼",
- "Ð”Ð°Ð²Ð°Ð°",
- "ÐœÑÐ³Ð¼Ð°Ñ€",
- "Ð›Ñ…Ð°Ð³Ð²Ð°",
- "ÐŸÒ¯Ñ€ÑÐ²",
- "Ð‘Ð°Ð°ÑÐ°Ð½",
- "Ð‘ÑÐ¼Ð±Ð°",
- "ÐÑÐ¼");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("ÐÑÐ¼",
- "Ð”Ð°Ð²",
- "ÐœÑÐ³",
- "Ð›Ñ…Ð°",
- "ÐŸÒ¯Ñ€",
- "Ð‘ÑÐ½",
- "Ð‘ÑÐ¼",
- "ÐÑÐ¼");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("1-Ñ€ ÑÐ°Ñ€",
- "2-Ñ€ ÑÐ°Ñ€",
- "3-Ñ€ ÑÐ°Ñ€",
- "4-Ñ€ ÑÐ°Ñ€",
- "5-Ñ€ ÑÐ°Ñ€",
- "6-Ñ€ ÑÐ°Ñ€",
- "7-Ñ€ ÑÐ°Ñ€",
- "8-Ñ€ ÑÐ°Ñ€",
- "9-Ñ€ ÑÐ°Ñ€",
- "10-Ñ€ ÑÐ°Ñ€",
- "11-Ñ€ ÑÐ°Ñ€",
- "12-Ñ€ ÑÐ°Ñ€");
-
-// short month names
-Calendar._SMN = new Array
-("1-Ñ€ ÑÐ°Ñ€",
- "2-Ñ€ ÑÐ°Ñ€",
- "3-Ñ€ ÑÐ°Ñ€",
- "4-Ñ€ ÑÐ°Ñ€",
- "5-Ñ€ ÑÐ°Ñ€",
- "6-Ñ€ ÑÐ°Ñ€",
- "7-Ñ€ ÑÐ°Ñ€",
- "8-Ñ€ ÑÐ°Ñ€",
- "9-Ñ€ ÑÐ°Ñ€",
- "10-Ñ€ ÑÐ°Ñ€",
- "11-Ñ€ ÑÐ°Ñ€",
- "12-Ñ€ ÑÐ°Ñ€");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ‹Ð½ Ñ‚ÑƒÑ…Ð°Ð¹";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "Ó¨Ð¼Ð½Ó©Ñ…. Ð¶Ð¸Ð»";
-Calendar._TT["PREV_MONTH"] = "Ó¨Ð¼Ð½Ó©Ñ…. ÑÐ°Ñ€";
-Calendar._TT["GO_TODAY"] = "Ó¨Ð½Ó©Ó©Ð´Ñ€Ð¸Ð¹Ð³ ÑÐ¾Ð½Ð³Ð¾";
-Calendar._TT["NEXT_MONTH"] = "Ð”Ð°Ñ€Ð°Ð° ÑÐ°Ñ€";
-Calendar._TT["NEXT_YEAR"] = "Ð”Ð°Ñ€Ð°Ð° Ð¶Ð¸Ð»";
-Calendar._TT["SEL_DATE"] = "Ó¨Ð´Ó©Ñ€ ÑÐ¾Ð½Ð³Ð¾Ñ…";
-Calendar._TT["DRAG_TO_MOVE"] = "Ð¥Ó©Ð´Ó©Ð»Ð³Ó©Ñ… Ð±Ð¾Ð» Ñ‡Ð¸Ñ€";
-Calendar._TT["PART_TODAY"] = " (Ó©Ð½Ó©Ó©Ð´Ó©Ñ€)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "%s -Ð³ ÑÑ…ÑÐ»Ð¶ Ð³Ð°Ñ€Ð³Ð°";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Ð¥Ð°Ð°Ñ…";
-Calendar._TT["TODAY"] = "Ó¨Ð½Ó©Ó©Ð´Ó©Ñ€";
-Calendar._TT["TIME_PART"] = "(Shift-)Click ÑÑÐ²ÑÐ» Ñ‡Ð¸Ñ€Ð¶ ÑƒÑ‚Ð³Ð¸Ð¹Ð³ Ó©Ó©Ñ€Ñ‡Ð¸Ð»";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "7 Ñ…Ð¾Ð½Ð¾Ð³";
-Calendar._TT["TIME"] = "Ð¦Ð°Ð³:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e7/e7c57199f09f372f673303ec05380ff197d1616b.svn-base
--- a/.svn/pristine/e7/e7c57199f09f372f673303ec05380ff197d1616b.svn-base
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-require File.expand_path('../../config/boot',  __FILE__)
-require 'commands/process/spinner'
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e8/e867d702d670ca00a87cd683a9e4a85aba9b478b.svn-base
--- a/.svn/pristine/e8/e867d702d670ca00a87cd683a9e4a85aba9b478b.svn-base
+++ /dev/null
@@ -1,45 +0,0 @@
-Description:
-  The plugin migration generator assists in working with schema additions 
-  required by plugins. Instead of running migrations from plugins directly,
-  the generator creates a regular Rails migration which will be responsible
-  for migrating the plugins from their current version to the latest version
-  installed.
-  
-  This is important because the set of application migrations remains an
-  accurate record of the state of the database, even as plugins are installed
-  and removed during the development process.
-
-Example:
-  ./script/generate plugin_migration [<plugin_name> <another_plugin_name> ...]
-
-  This will generate:
-
-    RAILS_ROOT
-      |- db
-          |-migrate
-              |- xxx_plugin_migrations.rb
-
-  which contains the migrations for the given plugin(s).
-  
-  
-Advanced Usage:
-
-There may be situations where you need *complete* control over the migrations
-of plugins in your application, migrating a certainly plugin down to X, and
-another plugin up to Y, where neither X or Y are the latest migrations for those
-plugins.
-
-For those unfortunate few, I have two pieces of advice:
-
- 1. Why? This is a code smell [http://c2.com/xp/CodeSmell.html].
- 
- 2. Well, OK. Don't panic. You can completely control plugin migrations by
-    creating your own migrations. To manually migrate a plugin to a specific
-    version, simply use
-    
-      Engines.plugins[:your_plugin_name].migrate(version)
-      
-    where version is the integer of the migration this plugin should end
-    up at.
-    
-With great power comes great responsibility. Use this wisely.
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e8/e86b4aa0a3e324955e92b3f7034e99d911b3a474.svn-base
--- a/.svn/pristine/e8/e86b4aa0a3e324955e92b3f7034e99d911b3a474.svn-base
+++ /dev/null
@@ -1,186 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-namespace :redmine do
-  namespace :email do
-
-    desc <<-END_DESC
-Read an email from standard input.
-
-General options:
-  unknown_user=ACTION      how to handle emails from an unknown user
-                           ACTION can be one of the following values:
-                           ignore: email is ignored (default)
-                           accept: accept as anonymous user
-                           create: create a user account
-  no_permission_check=1    disable permission checking when receiving
-                           the email
-
-Issue attributes control options:
-  project=PROJECT          identifier of the target project
-  status=STATUS            name of the target status
-  tracker=TRACKER          name of the target tracker
-  category=CATEGORY        name of the target category
-  priority=PRIORITY        name of the target priority
-  allow_override=ATTRS     allow email content to override attributes
-                           specified by previous options
-                           ATTRS is a comma separated list of attributes
-
-Examples:
-  # No project specified. Emails MUST contain the 'Project' keyword:
-  rake redmine:email:read RAILS_ENV="production" < raw_email
-
-  # Fixed project and default tracker specified, but emails can override
-  # both tracker and priority attributes:
-  rake redmine:email:read RAILS_ENV="production" \\
-                  project=foo \\
-                  tracker=bug \\
-                  allow_override=tracker,priority < raw_email
-END_DESC
-
-    task :read => :environment do
-      options = { :issue => {} }
-      %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
-      options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
-      options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
-      options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
-
-      MailHandler.receive(STDIN.read, options)
-    end
-
-    desc <<-END_DESC
-Read emails from an IMAP server.
-
-General options:
-  unknown_user=ACTION      how to handle emails from an unknown user
-                           ACTION can be one of the following values:
-                           ignore: email is ignored (default)
-                           accept: accept as anonymous user
-                           create: create a user account
-  no_permission_check=1    disable permission checking when receiving
-                           the email
-
-Available IMAP options:
-  host=HOST                IMAP server host (default: 127.0.0.1)
-  port=PORT                IMAP server port (default: 143)
-  ssl=SSL                  Use SSL? (default: false)
-  username=USERNAME        IMAP account
-  password=PASSWORD        IMAP password
-  folder=FOLDER            IMAP folder to read (default: INBOX)
-
-Issue attributes control options:
-  project=PROJECT          identifier of the target project
-  status=STATUS            name of the target status
-  tracker=TRACKER          name of the target tracker
-  category=CATEGORY        name of the target category
-  priority=PRIORITY        name of the target priority
-  allow_override=ATTRS     allow email content to override attributes
-                           specified by previous options
-                           ATTRS is a comma separated list of attributes
-
-Processed emails control options:
-  move_on_success=MAILBOX  move emails that were successfully received
-                           to MAILBOX instead of deleting them
-  move_on_failure=MAILBOX  move emails that were ignored to MAILBOX
-
-Examples:
-  # No project specified. Emails MUST contain the 'Project' keyword:
-
-  rake redmine:email:receive_imap RAILS_ENV="production" \\
-    host=imap.foo.bar username=redmine@example.net password=xxx
-
-
-  # Fixed project and default tracker specified, but emails can override
-  # both tracker and priority attributes:
-
-  rake redmine:email:receive_imap RAILS_ENV="production" \\
-    host=imap.foo.bar username=redmine@example.net password=xxx ssl=1 \\
-    project=foo \\
-    tracker=bug \\
-    allow_override=tracker,priority
-END_DESC
-
-    task :receive_imap => :environment do
-      imap_options = {:host => ENV['host'],
-                      :port => ENV['port'],
-                      :ssl => ENV['ssl'],
-                      :username => ENV['username'],
-                      :password => ENV['password'],
-                      :folder => ENV['folder'],
-                      :move_on_success => ENV['move_on_success'],
-                      :move_on_failure => ENV['move_on_failure']}
-
-      options = { :issue => {} }
-      %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
-      options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
-      options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
-      options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
-
-      Redmine::IMAP.check(imap_options, options)
-    end
-
-    desc <<-END_DESC
-Read emails from an POP3 server.
-
-Available POP3 options:
-  host=HOST                POP3 server host (default: 127.0.0.1)
-  port=PORT                POP3 server port (default: 110)
-  username=USERNAME        POP3 account
-  password=PASSWORD        POP3 password
-  apop=1                   use APOP authentication (default: false)
-  delete_unprocessed=1     delete messages that could not be processed
-                           successfully from the server (default
-                           behaviour is to leave them on the server)
-
-See redmine:email:receive_imap for more options and examples.
-END_DESC
-
-    task :receive_pop3 => :environment do
-      pop_options  = {:host => ENV['host'],
-                      :port => ENV['port'],
-                      :apop => ENV['apop'],
-                      :username => ENV['username'],
-                      :password => ENV['password'],
-                      :delete_unprocessed => ENV['delete_unprocessed']}
-
-      options = { :issue => {} }
-      %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
-      options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
-      options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
-      options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
-
-      Redmine::POP3.check(pop_options, options)
-    end
-
-    desc "Send a test email to the user with the provided login name"
-    task :test, [:login] => :environment do |task, args|
-      include Redmine::I18n
-      abort l(:notice_email_error, "Please include the user login to test with. Example: rake redmine:email:test[login]") if args[:login].blank?
-
-      user = User.find_by_login(args[:login])
-      abort l(:notice_email_error, "User #{args[:login]} not found") unless user && user.logged?
-
-      ActionMailer::Base.raise_delivery_errors = true
-      begin
-        Mailer.deliver_test(User.current)
-        puts l(:notice_email_sent, user.mail)
-      rescue Exception => e
-        abort l(:notice_email_error, e.message)
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e8/e88aba932f20a0c9bf3c41d56d6f0315fbfd93e2.svn-base
--- a/.svn/pristine/e8/e88aba932f20a0c9bf3c41d56d6f0315fbfd93e2.svn-base
+++ /dev/null
@@ -1,1068 +0,0 @@
-# Lithuanian translations for Ruby on Rails
-# by Laurynas Butkus (laurynas.butkus@gmail.com)
-# Redmine translation by Gediminas MuiÅ¾is gediminas.muizis@gmail.com
-#                      and Sergej Jegorov sergej.jegorov@gmail.com
-#					   and Gytis Gurklys gytis.gurklys@gmail.com
-lt:
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y-%m-%d"
-      short: "%b %d"
-      long: "%B %d, %Y"
-
-    day_names: [sekmadienis, pirmadienis, antradienis, treÄiadienis, ketvirtadienis, penktadienis, Å¡eÅ¡tadienis]
-#    standalone_day_names: [Sekmadienis, Pirmadienis, Antradienis, TreÄiadienis, Ketvirtadienis, Penktadienis, Å eÅ¡tadienis]
-    abbr_day_names: [Sek, Pir, Ant, Tre, Ket, Pen, Å eÅ¡]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, sausio, vasario, kovo, balandÅ¾io, geguÅ¾Ä—s, birÅ¾elio, liepos, rugpjÅ«Äio, rugsÄ—jo, spalio, lapkriÄio, gruodÅ¾io]
-    abbr_month_names: [~, Sau, Vas, Kov, Bal, Geg, Bir, Lie, Rgp, Rgs, Spa, Lap, Grd]
-    # Used in date_select and datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%a, %d %b %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "ryto"
-    pm: "vakaro"
-
-  datetime:
-    distance_in_words:
-      half_a_minute: "pusÄ— minutÄ—s"
-      less_than_x_seconds:
-        one:   "maÅ¾iau nei %{count} sekundÄ—"
-        few:   "maÅ¾iau nei %{count} sekundÅ¾iÅ³"
-        many:  "maÅ¾iau nei %{count} sekundÅ¾iÅ³"
-        other: "maÅ¾iau nei %{count} sekundÄ—s"
-      x_seconds:
-        one:   "%{count} sekundÄ—"
-        few:   "%{count} sekundÅ¾iÅ³"
-        many:  "%{count} sekundÅ¾iÅ³"
-        other: "%{count} sekundÄ—s"
-      less_than_x_minutes:
-        one:   "maÅ¾iau nei minutÄ—"
-        other: "maÅ¾iau nei %{count} minutÄ—s"
-      x_minutes:
-        one:   "1 minutÄ—"
-        other: "%{count} minutÄ—s"
-      about_x_hours:
-        one:   "apie 1 valanda"
-        other: "apie %{count} valandÅ³"
-      x_days:
-        one:   "1 diena"
-        other: "%{count} dienÅ³"
-      about_x_months:
-        one:   "apie 1 mÄ—nuo"
-        other: "apie %{count} mÄ—nesiai"
-      x_months:
-        one:   "1 mÄ—nuo"
-        other: "%{count} mÄ—nesiai"
-      about_x_years:
-        one:   "apie 1 metai"
-        other: "apie %{count} metÅ³"
-      over_x_years:
-        one:   "virÅ¡ 1 metÅ³"
-        other: "virÅ¡ %{count} metÅ³"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-    prompts:
-      year:   "Metai"
-      month:  "MÄ—nuo"
-      day:    "Diena"
-      hour:   "Valanda"
-      minute: "MinutÄ—"
-      second: "SekundÄ—s"
-
-  number:
-    format:
-      separator: ","
-      delimiter: " "
-      precision: 3
-      
-    currency:
-      format:
-        format: "%n %u"
-        unit: "Lt"
-        separator: ","
-        delimiter: " "
-        precision: 2
-        
-    percentage:
-      format:
-        delimiter: ""
-        
-    precision:
-      format:
-        delimiter: ""
-        
-    human:
-      format:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        # Storage units output formatting.
-        # %u is the storage unit, %n is the number (default: 2 MB)
-        format: "%n %u"
-        units:
-          byte:
-            one:   "baitas"
-            few:   "baitÅ³"
-            many:  "baitÅ³"
-            other: "baitai"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-# Used in array.to_sentence.
-  support:
-    array:
-      # Rails 2.2
-      sentence_connector: "ir"
-      skip_last_comma: true
-      # Rails 2.3
-      words_connector: ", "
-      two_words_connector: " ir "
-      last_word_connector: " ir "
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "IÅ¡saugant objektÄ… %{model} rasta %{count} klaida"
-          few:    "IÅ¡saugant objektÄ… %{model} rasta %{count} klaidÅ³"
-          many:   "IÅ¡saugant objektÄ… %{model} rasta %{count} klaidÅ³"
-          other:  "IÅ¡saugant objektÄ… %{model} rastos %{count} klaidos"
-        body: "Å iuose laukuose yra klaidÅ³:"
-
-      messages:
-        inclusion: "nenumatyta reikÅ¡mÄ—"
-        exclusion: "uÅ¾imtas"
-        invalid: "neteisingas"
-        confirmation: "neteisingai pakartotas"
-        accepted: "turi bÅ«ti patvirtintas"
-        empty: "negali bÅ«ti tuÅ¡Äias"
-        blank: "negali bÅ«ti tuÅ¡Äias"
-        too_long:
-          one:   "per ilgas (daugiausiai %{count} simbolius)"
-          few:   "per ilgas (daugiausiai %{count} simboliu)"
-          many:  "per ilgas (daugiausiai %{count} simboliu)"
-          other: "per ilgas (daugiausiai %{count} simboliai)"
-        too_short:
-          one:   "per trumpas (maÅ¾iausiai %{count} simbolius)"
-          few:   "per trumpas (maÅ¾iausiai %{count} simboliu)"
-          many:  "per trumpas (maÅ¾iausiai %{count} simboliu)"
-          other: "per trumpas (maÅ¾iausiai %{count} simboliai)"
-        wrong_length:
-          one:   "neteisingo ilgio (turi bÅ«ti lygiai %{count} simbolius)"
-          few:   "neteisingo ilgio (turi bÅ«ti lygiai %{count} simboliu)"
-          many:  "neteisingo ilgio (turi bÅ«ti lygiai %{count} simboliu)"
-          other: "neteisingo ilgio (turi bÅ«ti lygiai %{count} simboliai)"
-        taken: "jau uÅ¾imtas"
-        not_a_number: "ne skaiÄius"
-        not_a_date: "is not a valid date"
-        greater_than: "turi bÅ«ti didesnis uÅ¾ %{count}"
-        greater_than_or_equal_to: "turi bÅ«ti didesnis arba lygus %{count}"
-        equal_to: "turi bÅ«ti lygus %{count}"
-        less_than: "turi bÅ«ti maÅ¾esnis uÅ¾ %{count}"
-        less_than_or_equal_to: "turi bÅ«ti maÅ¾esnis arba lygus %{count}"
-        odd: "turi bÅ«ti nelyginis"
-        even: "turi bÅ«ti lyginis"
-        greater_than_start_date: "turi bÅ«ti didesnÄ— negu pradÅ¾ios data"
-        not_same_project: "nepriklauso tam paÄiam projektui"
-        circular_dependency: "Å is ryÅ¡ys sukurtÅ³ ciklinÄ™ priklausomybÄ™"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-    
-  actionview_instancetag_blank_option: praÅ¡om parinkti
-  
-  general_text_No: 'Ne'
-  general_text_Yes: 'Taip'
-  general_text_no: 'ne'
-  general_text_yes: 'taip'
-  general_lang_name: 'Lithuanian (lietuviÅ³)'
-  general_csv_separator: ';'
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: Paskyra buvo sÄ—kmingai atnaujinta.
-  notice_account_invalid_creditentials: Negaliojantis vartotojo vardas ar slaptaÅ¾odis
-  notice_account_password_updated: SlaptaÅ¾odis buvo sÄ—kmingai atnaujintas.
-  notice_account_wrong_password: Neteisingas slaptaÅ¾odis
-  notice_account_register_done: Paskyra buvo sÄ—kmingai sukurta. Kad aktyvintumÄ—te savo paskyrÄ…, paspauskite sÄ…sajÄ…, kuri jums buvo siÅ³sta elektroniniu paÅ¡tu.
-  notice_account_unknown_email: NeÅ¾inomas vartotojas.
-  notice_can_t_change_password: Å is praneÅ¡imas naudoja iÅ¡orinÄ¯ autentiÅ¡kumo nustatymo Å¡altinÄ¯. NeÄ¯manoma pakeisti slaptaÅ¾odÄ¯.
-  notice_account_lost_email_sent: Ä® JÅ«sÅ³ paÅ¡tÄ… iÅ¡siÅ³stas laiÅ¡kas su naujo slaptaÅ¾odÅ¾io pasirinkimo instrukcija.
-  notice_account_activated: JÅ«sÅ³ paskyra aktyvuota. Galite prisijungti.
-  notice_successful_create: SÄ—kmingas sukÅ«rimas.
-  notice_successful_update: SÄ—kmingas atnaujinimas.
-  notice_successful_delete: SÄ—kmingas panaikinimas.
-  notice_successful_connection: SÄ—kmingas susijungimas.
-  notice_file_not_found: Puslapis, Ä¯ kurÄ¯ ketinate Ä¯eiti, neegzistuoja arba yra paÅ¡alintas.
-  notice_locking_conflict: Duomenys atnaujinti kito vartotojo.
-  notice_not_authorized: JÅ«s neturite teisiÅ³ gauti prieigÄ… prie Å¡io puslapio.
-  notice_email_sent: "LaiÅ¡kas iÅ¡siÅ³stas %{value}"
-  notice_email_error: "LaiÅ¡ko siuntimo metu Ä¯vyko klaida (%{value})"
-  notice_feeds_access_key_reseted: JÅ«sÅ³ RSS raktas buvo atnaujintas.
-  notice_failed_to_save_issues: "Nepavyko iÅ¡saugoti %{count} problemos(Å³) iÅ¡ %{total} pasirinkto: %{ids}."
-  notice_no_issue_selected: "Nepasirinkta nÄ— viena problema! PraÅ¡om paÅ¾ymÄ—ti problemÄ…, kuriÄ… norite redaguoti."
-  notice_account_pending: "JÅ«sÅ³ paskyra buvo sukurta ir dabar laukiama administratoriaus patvirtinimo."
-  notice_default_data_loaded: Numatytoji konfiguracija sÄ—kmingai uÅ¾krauta.
-  notice_unable_delete_version: NeÄ¯manoma panaikinti versijÄ…
-  
-  error_can_t_load_default_data: "Numatytoji konfiguracija negali bÅ«ti uÅ¾krauta: %{value}"
-  error_scm_not_found: "Duomenys ir/ar pakeitimai saugykloje(repozitorojoje) neegzistuoja."
-  error_scm_command_failed: "Ä®vyko klaida jungiantis prie saugyklos: %{value}"
-  error_scm_annotate: "Ä®raÅ¡as neegzistuoja arba negalima jo atvaizduoti."
-  error_issue_not_found_in_project: 'Darbas nerastas arba nesuriÅ¡tas su Å¡iuo projektu'
-  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
-  error_no_default_issue_status: Nenustatyta numatytoji darbÅ³ bÅ«sena. PraÅ¡ome patikrinti konfigÅ«ravimÄ… ("Administravimas -> DarbÅ³ bÅ«senos").
-  error_can_not_reopen_issue_on_closed_version: UÅ¾darytai versijai priskirtas darbas negali bÅ«ti atnaujintas.
-  error_can_not_archive_project: Å io projekto negalima suarchyvuoti
-
-  warning_attachments_not_saved: "%{count} byla(Å³) negali bÅ«ti iÅ¡saugota."
-
-  mail_subject_lost_password: "JÅ«sÅ³ %{value} slaptaÅ¾odis"
-  mail_body_lost_password: 'NorÄ—dami pakeisti slaptaÅ¾odÄ¯, spauskite nuorodÄ…:'
-  mail_subject_register: "JÅ«sÅ³ %{value} paskyros aktyvavimas"
-  mail_body_register: 'NorÄ—dami aktyvuoti paskyrÄ…, spauskite nuorodÄ…:'
-  mail_body_account_information_external: "JÅ«s galite naudoti JÅ«sÅ³ %{value} paskyrÄ…, norÄ—dami prisijungti."
-  mail_body_account_information: Informacija apie JÅ«sÅ³ paskyrÄ…
-  mail_subject_account_activation_request: "%{value} paskyros aktyvavimo praÅ¡ymas"
-  mail_body_account_activation_request: "UÅ¾siregistravo naujas vartotojas (%{value}). Jo paskyra laukia jÅ«sÅ³ patvirtinimo:"
-  mail_subject_reminder: "%{count} darbas(ai) po keliÅ³ %{days} dienÅ³"
-  mail_body_reminder: "%{count} darbas(ai), kurie yra jums priskirti, baigiasi po %{days} dienÅ³(os):"
-  mail_subject_wiki_content_added: "'%{id}' pridÄ—tas wiki puslapis"
-  mail_body_wiki_content_added: "The '%{id}' wiki puslapi pridÄ—jo %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' atnaujintas wiki puslapis"
-  mail_body_wiki_content_updated: "The '%{id}' wiki puslapÄ¯ atnaujino %{author}."
-
-  gui_validation_error: 1 klaida
-  gui_validation_error_plural: "%{count} klaidÅ³(os)"
-  
-  field_name: Pavadinimas
-  field_description: ApraÅ¡as
-  field_summary: Santrauka
-  field_is_required: Reikalaujama
-  field_firstname: Vardas
-  field_lastname: PavardÄ—
-  field_mail: El.paÅ¡tas
-  field_filename: Byla
-  field_filesize: Dydis
-  field_downloads: Atsiuntimai
-  field_author: Autorius
-  field_created_on: Sukurta
-  field_updated_on: Atnaujinta
-  field_field_format: Formatas
-  field_is_for_all: Visiems projektams
-  field_possible_values: Galimos reikÅ¡mÄ—s
-  field_regexp: Pastovi iÅ¡raiÅ¡ka
-  field_min_length: Minimalus ilgis
-  field_max_length: Maksimalus ilgis
-  field_value: VertÄ—
-  field_category: Kategorija
-  field_title: Pavadinimas
-  field_project: Projektas
-  field_issue: Darbas
-  field_status: BÅ«sena
-  field_notes: Pastabos
-  field_is_closed: Darbas uÅ¾darytas
-  field_is_default: Numatytoji vertÄ—
-  field_tracker: PÄ—dsekys
-  field_subject: Tema
-  field_due_date: UÅ¾baigimo data
-  field_assigned_to: Paskirtas
-  field_priority: Prioritetas
-  field_fixed_version: TikslinÄ— versija
-  field_user: Vartotojas
-  field_role: Vaidmuo
-  field_homepage: Pagrindinis puslapis
-  field_is_public: VieÅ¡as
-  field_parent: Priklauso projektui
-  field_is_in_chlog: Darbai rodomi pokyÄiÅ³ Å¾urnale
-  field_is_in_roadmap: Darbai rodomi veiklos grafike
-  field_login: Registracijos vardas
-  field_mail_notification: Elektroninio paÅ¡to praneÅ¡imai
-  field_admin: Administratorius
-  field_last_login_on: Paskutinis ryÅ¡ys
-  field_language: Kalba
-  field_effective_date: Data
-  field_password: SlaptaÅ¾odis
-  field_new_password: Naujas slaptaÅ¾odis
-  field_password_confirmation: Patvirtinimas
-  field_version: Versija
-  field_type: Tipas
-  field_host: Pagrindinis kompiuteris
-  field_port: Prievadas
-  field_account: Paskyra
-  field_base_dn: Bazinis skiriamasis vardas (base DN)
-  field_attr_login: Registracijos vardo poÅ¾ymis (login)
-  field_attr_firstname: Vardo priskiria
-  field_attr_lastname: PavardÄ—s priskiria
-  field_attr_mail: Elektroninio paÅ¡to poÅ¾ymis
-  field_onthefly: Automatinis vartotojÅ³ registravimas
-  field_start_date: PradÄ—ti
-  field_done_ratio: "% atlikta"
-  field_auth_source: AutentiÅ¡kumo nustatymo bÅ«das
-  field_hide_mail: PaslÄ—pkite mano elektroninio paÅ¡to adresÄ…
-  field_comments: Komentaras
-  field_url: URL
-  field_start_page: PradÅ¾ios puslapis
-  field_subproject: Subprojektas
-  field_hours: valandos
-  field_activity: Veikla
-  field_spent_on: Data
-  field_identifier: Identifikuotojas
-  field_is_filter: Panaudotas kaip filtras
-  field_issue_to: SusijÄ™s darbas
-  field_delay: UÅ¾laikymas
-  field_assignable: Darbai gali bÅ«ti paskirti Å¡iam vaidmeniui
-  field_redirect_existing_links: Peradresuokite egzistuojanÄias sÄ…sajas
-  field_estimated_hours: Numatyta trukmÄ—
-  field_column_names: Skiltys
-  field_time_zone: Laiko juosta
-  field_searchable: Randamas
-  field_default_value: Numatytoji vertÄ—
-  field_comments_sorting: rodyti komentarus
-  field_parent_title: AukÅ¡tesnio lygio puslapis
-  field_editable: Redaguojamas
-  field_watcher: StebÄ—tojas
-  field_identity_url: OpenID URL
-  field_content: Turinys
-  field_group_by: Sugrupuoti pagal
-  field_active: Activis
-  field_sharing: Dalijimasis (Sharing)
-
-  setting_app_title: Programos pavadinimas
-  setting_app_subtitle: Programos paantraÅ¡tÄ—
-  setting_welcome_text: Pasveikinimas
-  setting_default_language: Numatytoji kalba
-  setting_login_required: Reikalingas autentiÅ¡kumo nustatymas
-  setting_self_registration: Saviregistracija
-  setting_attachment_max_size: Priedo maks. dydis
-  setting_issues_export_limit: DarbÅ³ eksportavimo riba
-  setting_mail_from: Emisijos elektroninio paÅ¡to adresas
-  setting_bcc_recipients: Akli tikslios kopijos gavÄ—jai (bcc)
-  setting_plain_text_mail: tik tekstas (be HTML)
-  setting_host_name: Pagrindinio kompiuterio vardas
-  setting_text_formatting: Teksto apipavidalinimas
-  setting_wiki_compression: Wiki istorijos suspaudimas
-  setting_feeds_limit: Perdavimo turinio riba
-  setting_default_projects_public: Naujas projektas vieÅ¡as pagal nutylÄ—jimÄ…
-  setting_autofetch_changesets: Automatinis pakeitimÅ³ siuntimas
-  setting_sys_api_enabled: Ä®galinkite WS sandÄ—lio vadybai
-  setting_commit_ref_keywords: Nurodymo reikÅ¡miniai Å¾odÅ¾iai
-  setting_commit_fix_keywords: Fiksavimo reikÅ¡miniai Å¾odÅ¾iai
-  setting_autologin: Autoregistracija
-  setting_date_format: Datos formatas
-  setting_time_format: Laiko formatas
-  setting_cross_project_issue_relations: Leisti tarprojektinius darbÅ³ ryÅ¡ius
-  setting_issue_list_default_columns: Numatytosios skiltys darbÅ³ sÄ…raÅ¡e
-  setting_emails_footer: elektroninio paÅ¡to puslapinÄ— poraÅ¡tÄ—
-  setting_protocol: Protokolas
-  setting_per_page_options: Ä®raÅ¡Å³ puslapyje nustatimas
-  setting_user_format: Vartotojo atvaizdavimo formatas
-  setting_activity_days_default: Atvaizduojamos dienos projekto veikloje
-  setting_display_subprojects_issues: Pagal nutylÄ—jimÄ… rodyti subprojektÅ³ darbus pagrindiniame projekte
-  setting_enabled_scm: Ä®galintas SCM
-  setting_mail_handler_api_enabled: Ä®galinti WS Ä¯einantiems laiÅ¡kams
-  setting_mail_handler_api_key: API raktas
-  setting_sequential_project_identifiers: Generuoti nuoseklius projekto identifikatorius
-  setting_gravatar_enabled: Naudoti Gravatar vartotojo paveiksliukus
-  setting_gravatar_default: Gravatar paveiksliukas pagal nutylÄ—jimÄ…
-  setting_diff_max_lines_displayed: Maksimalus rodomas eiluÄiu skaiÄius diff\'e
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_openid: Leisti OpenID prisijungimÄ… ir registracijÄ…
-  setting_password_min_length: Minimalus slaptaÅ¾odÅ¾io ilgis
-  setting_new_project_user_role_id: Vaidmuo, suteikiamas vartotojui (non-admin), kuris sukuria projektÄ…
-  setting_default_projects_modules: Nustatytieji naujam projektui priskirti moduliai
-
-  permission_add_project: Sukurti projektÄ…
-  permission_edit_project: Taisyti projektÄ…
-  permission_select_project_modules: Parinkti projekto modulius
-  permission_manage_members: Valdyti narius
-  permission_manage_versions: Valdyti versijas
-  permission_manage_categories: Valdyti darbÅ³ kategorijas
-  permission_add_issues: Sukurti darbus
-  permission_edit_issues: Redaguoti darbus
-  permission_manage_issue_relations: Valdyti darbÅ³ ryÅ¡ius
-  permission_add_issue_notes: Sukurti pastabas
-  permission_edit_issue_notes: Redaguoti pastabas
-  permission_edit_own_issue_notes: Redaguoti savo pastabas
-  permission_move_issues: Perkelti darbus
-  permission_delete_issues: PaÅ¡alinti darbus
-  permission_manage_public_queries: Valdyti vieÅ¡as uÅ¾klausas
-  permission_save_queries: IÅ¡saugoti uÅ¾klausas
-  permission_view_gantt: Matyti Gantt grafikÄ…
-  permission_view_calendar: Matyti kalendoriÅ³
-  permission_view_issue_watchers: Matyti stebÄ—tojÅ³ sÄ…raÅ¡Ä…
-  permission_add_issue_watchers: PridÄ—ti stebÄ—tojus
-  permission_delete_issue_watchers: PaÅ¡alinti stebÄ—tojus
-  permission_log_time: Regsitruoti dirbtÄ… laikÄ…
-  permission_view_time_entries: Matyti dirbtÄ… laikÄ…
-  permission_edit_time_entries: Redaguoti laiko Ä¯raÅ¡us
-  permission_edit_own_time_entries: Redguoti savo laiko Ä¯raÅ¡us
-  permission_manage_news: Valdyti naujienas
-  permission_comment_news: Komentuoti naujienas
-  permission_manage_documents: Valdyti dokumentus
-  permission_view_documents: Matyti dokumentus
-  permission_manage_files: Valdyti bylas
-  permission_view_files: Matyti bylas
-  permission_manage_wiki: Valdyti wiki
-  permission_rename_wiki_pages: Pevadinti wiki puslapius
-  permission_delete_wiki_pages: PaÅ¡alinti wiki puslapius
-  permission_view_wiki_pages: Matyti wiki
-  permission_view_wiki_edits: Matyti wiki istorijÄ…
-  permission_edit_wiki_pages: Redaguoti wiki puslapius
-  permission_delete_wiki_pages_attachments: PaÅ¡alinti priedus
-  permission_protect_wiki_pages: Apsaugoti wiki puslapius
-  permission_manage_repository: PaÅ¡alinti repository
-  permission_browse_repository: PerÅ¾iÅ«rÄ—ti repository
-  permission_view_changesets: Matyti pakeitimus
-  permission_commit_access: Commit access
-  permission_manage_boards: Valdyti boards
-  permission_view_messages: Matyti praneÅ¡imus
-  permission_add_messages: Post praneÅ¡imus
-  permission_edit_messages: Redaguoti praneÅ¡imus
-  permission_edit_own_messages: Redaguoti savo praneÅ¡imus
-  permission_delete_messages: PaÅ¡alinti praneÅ¡imus
-  permission_delete_own_messages: PaÅ¡alinti savo praneÅ¡imus
-  permission_delete_issue_watchers: PaÅ¡alinti stebÄ—tojus
-
-  project_module_issue_tracking: Darbu pÄ—dsekys
-  project_module_time_tracking: Laiko pÄ—dsekys
-  project_module_news: Naujienos
-  project_module_documents: Dokumentai
-  project_module_files: Rinkmenos
-  project_module_wiki: Wiki
-  project_module_repository: Saugykla
-  project_module_boards: Forumai
-  
-  label_user: Vartotojas
-  label_user_plural: Vartotojai
-  label_user_new: Naujas vartotojas
-  label_project: Projektas
-  label_project_new: Naujas projektas
-  label_project_plural: Projektai
-  label_x_projects:
-    zero:  nÄ—ra projektÅ³
-    one:   1 projektas
-    other: "%{count} projektÅ³"
-  label_project_all: Visi Projektai
-  label_project_latest: Paskutiniai projektai
-  label_issue: Darbas
-  label_issue_new: Naujas darbas
-  label_issue_plural: Darbai
-  label_issue_view_all: PerÅ¾iÅ«rÄ—ti visus darbus
-  label_issues_by: "Darbai pagal %{value}"
-  label_issue_added: Darbas pridÄ—tas
-  label_issue_updated: Darbas atnaujintas
-  label_document: Dokumentas
-  label_document_new: Naujas dokumentas
-  label_document_plural: Dokumentai
-  label_document_added: Dokumentas pridÄ—tas
-  label_role: Vaidmuo
-  label_role_plural: Vaidmenys
-  label_role_new: Naujas vaidmuo
-  label_role_and_permissions: Vaidmenys ir leidimai
-  label_member: Narys
-  label_member_new: Naujas narys
-  label_member_plural: Nariai
-  label_tracker: PÄ—dsekys
-  label_tracker_plural: PÄ—dsekiai
-  label_tracker_new: Naujas pÄ—dsekys
-  label_workflow: DarbÅ³ eiga
-  label_issue_status: Darbo bÅ«sena
-  label_issue_status_plural: DarbÅ³ bÅ«senos
-  label_issue_status_new: Nauja bÅ«sena
-  label_issue_category: Darbo kategorija
-  label_issue_category_plural: Darbo kategorijos
-  label_issue_category_new: Nauja kategorija
-  label_custom_field: Kliento laukas
-  label_custom_field_plural: Kliento laukai
-  label_custom_field_new: Naujas kliento laukas
-  label_enumerations: IÅ¡vardinimai
-  label_enumeration_new: Nauja vertÄ—
-  label_information: Informacija
-  label_information_plural: Informacija
-  label_please_login: PraÅ¡om prisijungti
-  label_register: UÅ¾siregistruoti
-  label_password_lost: Prarastas slaptaÅ¾odis
-  label_home: Pagrindinis
-  label_my_page: Mano puslapis
-  label_my_account: Mano paskyra
-  label_my_projects: Mano projektai
-  label_administration: Administravimas
-  label_login: Prisijungti
-  label_logout: Atsijungti
-  label_help: Pagalba
-  label_reported_issues: PraneÅ¡ti darbai
-  label_assigned_to_me_issues: Darbai, priskirti man
-  label_last_login: Paskutinis ryÅ¡ys
-  label_registered_on: UÅ¾registruota
-  label_activity: Veikla
-  label_overall_activity: Visa veikla
-  label_user_activity: "%{value}o veiksmai"
-  label_new: Naujas
-  label_logged_as: PrisijungÄ™s kaip
-  label_environment: Aplinka
-  label_authentication: AutentiÅ¡kumo nustatymas
-  label_auth_source: AutentiÅ¡kumo nustatymo bÅ«das
-  label_auth_source_new: Naujas autentiÅ¡kumo nustatymo bÅ«das
-  label_auth_source_plural: AutentiÅ¡kumo nustatymo bÅ«dai
-  label_subproject_plural: Subprojektai
-  label_and_its_subprojects: "%{value} projektas ir jo subprojektai"
-  label_min_max_length: Min - Maks ilgis
-  label_list: SÄ…raÅ¡as
-  label_date: Data
-  label_integer: Sveikasis skaiÄius
-  label_float: Float
-  label_boolean: Boolean
-  label_string: Tekstas
-  label_text: Ilgas tekstas
-  label_attribute: PoÅ¾ymis
-  label_attribute_plural: PoÅ¾ymiai
-  label_download: "%{count} persiuntimas"
-  label_download_plural: "%{count} persiuntimai"
-  label_no_data: NÄ—ra kÄ… atvaizduoti
-  label_change_status: Pakeitimo bÅ«sena
-  label_history: Istorija
-  label_attachment: Rinkmena
-  label_attachment_new: Nauja rinkmena
-  label_attachment_delete: PaÅ¡alinkite rinkmenÄ…
-  label_attachment_plural: Rinkmenos
-  label_file_added: Byla pridÄ—ta
-  label_report: Ataskaita
-  label_report_plural: Ataskaitos
-  label_news: Naujiena
-  label_news_new: PridÄ—kite naujienÄ…
-  label_news_plural: Naujienos
-  label_news_latest: PaskutinÄ—s naujienos
-  label_news_view_all: PerÅ¾iÅ«rÄ—ti visas naujienas
-  label_news_added: Naujiena pridÄ—ta
-  label_change_log: PakeitimÅ³ Å¾urnalas
-  label_settings: Nustatymai
-  label_overview: ApÅ¾valga
-  label_version: Versija
-  label_version_new: Nauja versija
-  label_version_plural: Versijos
-  label_confirmation: Patvirtinimas
-  label_export_to: Eksportuoti Ä¯
-  label_read: Skaitykite...
-  label_public_projects: VieÅ¡i projektai
-  label_open_issues: atidaryta
-  label_open_issues_plural: atidaryti
-  label_closed_issues: uÅ¾daryta
-  label_closed_issues_plural: uÅ¾daryti
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 uÅ¾darytu
-    one:   1 uÅ¾darytas
-    other: "%{count} uÅ¾darytu"
-  label_total: Bendra suma
-  label_permissions: Leidimai
-  label_current_status: Einamoji bÅ«sena
-  label_new_statuses_allowed: Naujos bÅ«senos galimos
-  label_all: visi
-  label_none: niekas
-  label_nobody: niekas
-  label_next: Kitas
-  label_previous: Ankstesnis
-  label_used_by: Naudotas
-  label_details: DetalÄ—s
-  label_add_note: PridÄ—kite pastabÄ…
-  label_per_page: Per puslapÄ¯
-  label_calendar: Kalendorius
-  label_months_from: mÄ—nesiai nuo
-  label_gantt: Gantt
-  label_internal: Vidinis
-  label_last_changes: "paskutiniai %{count}, pokyÄiai"
-  label_change_view_all: PerÅ¾iÅ«rÄ—ti visus pakeitimus
-  label_personalize_page: Suasmeninti Å¡Ä¯ puslapÄ¯
-  label_comment: Komentaras
-  label_comment_plural: Komentarai
-  label_x_comments:
-    zero: nÄ—ra komentarÅ³
-    one: 1 komentaras
-    other: "%{count} komentarÅ³"
-  label_comment_add: PridÄ—kite komentarÄ…
-  label_comment_added: Komentaras pridÄ—tas
-  label_comment_delete: PaÅ¡alinkite komentarus
-  label_query: UÅ¾klausa
-  label_query_plural: UÅ¾klausos
-  label_query_new: Nauja uÅ¾klausa
-  label_filter_add: PridÄ—ti filtrÄ…
-  label_filter_plural: Filtrai
-  label_equals: yra
-  label_not_equals: nÄ—ra
-  label_in_less_than: maÅ¾iau negu
-  label_in_more_than: daugiau negu
-  label_in: in
-  label_today: Å¡iandien
-  label_all_time: visas laikas
-  label_yesterday: vakar
-  label_this_week: Å¡iÄ… savaitÄ™
-  label_last_week: paskutinÄ— savaitÄ—
-  label_last_n_days: "paskutiniÅ³ %{count} dienÅ³"
-  label_this_month: Å¡is menuo
-  label_last_month: paskutinis menuo
-  label_this_year: Å¡iemet
-  label_date_range: DienÅ³ diapazonas
-  label_less_than_ago: maÅ¾iau negu dienomis prieÅ¡
-  label_more_than_ago: daugiau negu dienomis prieÅ¡
-  label_ago: dienomis prieÅ¡
-  label_contains: turi savyje
-  label_not_contains: neturi savyje
-  label_day_plural: dienos
-  label_repository: Saugykla
-  label_repository_plural: Saugyklos
-  label_browse: NarÅ¡yti
-  label_modification: "%{count} pakeitimas"
-  label_modification_plural: "%{count} pakeitimai"
-  label_revision: Revizija
-  label_revision_plural: Revizijos
-  label_associated_revisions: susijusios revizijos
-  label_added: pridÄ—tas
-  label_modified: pakeistas
-  label_copied: nukopijuotas
-  label_renamed: pervardintas
-  label_deleted: paÅ¡alintas
-  label_latest_revision: PaskutinÄ— revizija
-  label_latest_revision_plural: PaskutinÄ—s revizijos
-  label_view_revisions: PeÅ¾iÅ«rÄ—ti revizijas
-  label_max_size: Maksimalus dydis
-  label_sort_highest: Perkelti Ä¯ virÅ¡Å«nÄ™
-  label_sort_higher: Perkelti Ä¯ virÅ¡Å³
-  label_sort_lower: Perkelti Å¾emyn
-  label_sort_lowest: Perkelti Ä¯ apaÄiÄ…
-  label_roadmap: Veiklos grafikas
-  label_roadmap_due_in: "Baigiasi po %{value}"
-  label_roadmap_overdue: "%{value} vÄ—luojama"
-  label_roadmap_no_issues: Jokio darbo Å¡iai versijai nÄ—ra
-  label_search: IeÅ¡koti
-  label_result_plural: Rezultatai
-  label_all_words: Visi Å¾odÅ¾iai
-  label_wiki: Wiki
-  label_wiki_edit: Wiki redakcija
-  label_wiki_edit_plural: Wiki redakcijos
-  label_wiki_page: Wiki puslapis
-  label_wiki_page_plural: Wiki puslapiai
-  label_index_by_title: Indeksas prie pavadinimo
-  label_index_by_date: Indeksas prie datos
-  label_current_version: Einamoji versija
-  label_preview: PerÅ¾iÅ«ra
-  label_feed_plural: Ä®eitys(Feeds)
-  label_changes_details: VisÅ³ pakeitimÅ³ detalÄ—s
-  label_issue_tracking: DarbÅ³ sekimas
-  label_spent_time: Dirbtas laikas
-  label_f_hour: "%{value} valanda"
-  label_f_hour_plural: "%{value} valandÅ³"
-  label_time_tracking: Laiko sekimas
-  label_change_plural: Pakeitimai
-  label_statistics: Statistika
-  label_commits_per_month: Paveda(commit) per mÄ—nesÄ¯
-  label_commits_per_author: Autoriaus pavedos(commit)
-  label_view_diff: SkirtumÅ³ perÅ¾iÅ«ra
-  label_diff_inline: Ä¯terptas
-  label_diff_side_by_side: Å¡alia
-  label_options: Pasirinkimai
-  label_copy_workflow_from: Kopijuoti darbÅ³ eiga iÅ¡
-  label_permissions_report: LeidimÅ³ praneÅ¡imas
-  label_watched_issues: Stebimi darbai
-  label_related_issues: SusijÄ™ darbai
-  label_applied_status: Taikomoji bÅ«sena
-  label_loading: Kraunama...
-  label_relation_new: Naujas ryÅ¡ys
-  label_relation_delete: PaÅ¡alinkite ryÅ¡Ä¯
-  label_relates_to: susietas su
-  label_duplicates: dubliuoja
-  label_duplicated_by: dubliuojasi
-  label_blocks: blokuoja
-  label_blocked_by: blokuojasi
-  label_precedes: ankstesnÄ—
-  label_follows: seka
-  label_end_to_start: uÅ¾baigti, kad pradÄ—ti
-  label_end_to_end: uÅ¾baigti, kad pabaigti
-  label_start_to_start: pradÄ—kite pradÄ—ti
-  label_start_to_end: pradÄ—kite uÅ¾baigti
-  label_stay_logged_in: Likti prisijungus
-  label_disabled: iÅ¡jungta(as)
-  label_show_completed_versions: Parodyti uÅ¾baigtas versijas
-  label_me: aÅ¡
-  label_board: Forumas
-  label_board_new: Naujas forumas
-  label_board_plural: Forumai
-  label_topic_plural: Temos
-  label_message_plural: PraneÅ¡imai
-  label_message_last: Paskutinis praneÅ¡imas
-  label_message_new: Naujas praneÅ¡imas
-  label_message_posted: PraneÅ¡imas pridÄ—tas
-  label_reply_plural: Atsakymai
-  label_send_information: NusiÅ³sti paskyros informacijÄ… vartotojui
-  label_year: Metai
-  label_month: MÄ—nuo
-  label_week: SavaitÄ—
-  label_date_from: Nuo
-  label_date_to: Iki
-  label_language_based: PagrÄ¯sta vartotojo kalba
-  label_sort_by: "RÅ«Å¡iuoti pagal %{value}"
-  label_send_test_email: NusiÅ³sti bandomÄ…jÄ¯ elektroninÄ¯ laiÅ¡kÄ…
-  label_feeds_access_key_created_on: "RSS prieigos raktas sukurtas prieÅ¡ %{value}"
-  label_module_plural: Moduliai
-  label_added_time_by: "PridÄ—jo %{author} prieÅ¡ %{age}"
-  label_updated_time_by: "Atnaujino %{author} %{age} atgal"
-  label_updated_time: "Atnaujinta prieÅ¡ %{value}"
-  label_jump_to_a_project: Å uolis Ä¯ projektÄ…...
-  label_file_plural: Bylos
-  label_changeset_plural: Changesets
-  label_default_columns: Numatyti stulpeliai
-  label_no_change_option: (Jokio pakeitimo)
-  label_bulk_edit_selected_issues: Masinis pasirinktÅ³ darbÅ³(issues) redagavimas
-  label_theme: Tema
-  label_default: Numatyta(as)
-  label_search_titles_only: IeÅ¡koti pavadinimÅ³ tiktai
-  label_user_mail_option_all: "Bet kokiam Ä¯vykiui visuose mano projektuose"
-  label_user_mail_option_selected: "Bet kokiam Ä¯vykiui tiktai pasirinktuose projektuose ..."
-  label_user_mail_no_self_notified: "Nenoriu bÅ«ti informuotas apie pakeitimus, kuriuos pats atlieku"
-  label_registration_activation_by_email: "paskyros aktyvacija per e-paÅ¡tÄ…"
-  label_registration_manual_activation: "rankinÄ— paskyros aktyvacija"
-  label_registration_automatic_activation: "automatinÄ— paskyros aktyvacija"
-  label_display_per_page: "%{value} Ä¯raÅ¡Å³ puslapyje"
-  label_age: AmÅ¾ius
-  label_change_properties: Pakeisti nustatymus
-  label_general: Bendri
-  label_more: Daugiau
-  label_scm: SCM
-  label_plugins: Ä®skiepiai
-  label_ldap_authentication: LDAP autentifikacija
-  label_downloads_abbr: siunt.
-  label_optional_description: ApibÅ«dinimas (laisvai pasirenkamas)
-  label_add_another_file: PridÄ—ti kitÄ… bylÄ…
-  label_preferences: SavybÄ—s
-  label_chronological_order: Chronologine tvarka
-  label_reverse_chronological_order: Atbuline chronologine tvarka
-  label_planning: Planavimas
-  label_incoming_emails: Ä®einantys laiÅ¡kai
-  label_generate_key: Generuoti raktÄ…
-  label_issue_watchers: StebÄ—tojai
-  label_example: Pavyzdys
-  label_display: Display
-  label_login_with_open_id_option: arba prisijunkite su OpenID
-  label_descending: Descending
-  label_sort: RÅ«Å¡iuoti
-  label_ascending: Ascending
-  label_date_from_to: From %{start} to %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  label_wiki_content_added: Wiki puslapis pridÄ—tas
-  label_wiki_content_updated: Wiki puslapis atnaujintas
-  label_view_all_revisions: Rodyti visos revizijas
-  label_tag: Tag'as
-  label_branch: Branch'as
-  label_group_plural: GrupÄ—s
-  label_group: GrupÄ—
-  label_group_new: Nauja grupÄ—
-  label_time_entry_plural: Sprendimo laikas
-  label_user_anonymous: Anonimas
-  label_version_sharing_hierarchy: Su projekto hierarchija
-  label_version_sharing_system: Su visais projektais
-  label_version_sharing_descendants: Su subprojektais
-  label_version_sharing_tree: Su projekto medÅ¾iu
-  label_version_sharing_none: Nesidalinama
-
-  button_login: Registruotis
-  button_submit: Pateikti
-  button_save: IÅ¡saugoti
-  button_check_all: Å½ymÄ—ti visus
-  button_uncheck_all: AtÅ¾ymÄ—ti visus
-  button_delete: PaÅ¡alinti
-  button_create: Sukurti
-  button_create_and_continue: Sukurti ir tÄ™sti
-  button_test: Testas
-  button_edit: Redaguoti
-  button_add: PridÄ—ti
-  button_change: Keisti
-  button_apply: Pritaikyti
-  button_clear: IÅ¡valyti
-  button_lock: Rakinti
-  button_unlock: Atrakinti
-  button_download: AtsisiÅ³sti
-  button_list: SÄ…raÅ¡as
-  button_view: Å½iÅ«rÄ—ti
-  button_move: Perkelti
-  button_move_and_follow: Perkelti ir sekti
-  button_back: Atgal
-  button_cancel: AtÅ¡aukti
-  button_activate: Aktyvinti
-  button_sort: RÅ«Å¡iuoti
-  button_log_time: Dirbtas laikas
-  button_rollback: GrÄ¯Å¾ti Ä¯ Å¡iÄ… versijÄ…
-  button_watch: StebÄ—ti
-  button_unwatch: NestebÄ—ti
-  button_reply: Atsakyti
-  button_archive: Archyvuoti
-  button_unarchive: IÅ¡pakuoti
-  button_reset: Atstatyti
-  button_rename: Pervadinti
-  button_change_password: Pakeisti slaptaÅ¾odÄ¯
-  button_copy: Kopijuoti
-  button_annotate: RaÅ¡yti pastabÄ…
-  button_update: Atnaujinti
-  button_configure: KonfigÅ«ruoti
-  button_quote: Cituoti
-  button_duplicate: Dubliuoti
-  button_copy_and_follow: Kopijuoti ir laikytis
-
-  status_active: aktyvus
-  status_registered: uÅ¾registruotas
-  status_locked: uÅ¾rakintas
-
-  version_status_open: atidaryta
-  version_status_locked: uÅ¾rakinta
-  version_status_closed: uÅ¾daryta
-
-  text_select_mail_notifications: IÅ¡rinkite veiksmus, apie kuriuos bÅ«tÅ³ praneÅ¡ta elektroniniu paÅ¡tu.
-  text_regexp_info: pvz. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 reiÅ¡kia jokiÅ³ apribojimÅ³
-  text_project_destroy_confirmation: Ar esate Ä¯sitikinÄ™s, kad jÅ«s norite paÅ¡alinti Å¡Ä¯ projektÄ… ir visus susijusius duomenis?
-  text_subprojects_destroy_warning: "Å is(ie) subprojektas(ai): %{value} taip pat bus iÅ¡trintas(i)."
-  text_workflow_edit: IÅ¡rinkite vaidmenÄ¯ ir pÄ—dsekÄ¯, kad redaguotumÄ—te darbÅ³ eigÄ…
-  text_are_you_sure: Ar esate Ä¯sitikinÄ™s?
-  text_journal_changed: "%{label} pakeista iÅ¡ %{old} Ä¯ %{new}"
-  text_journal_set_to: "%{label} pakeista Ä¯ %{value}"
-  text_journal_deleted: "%{label} iÅ¡trintas (%{old})"
-  text_journal_added: "%{label} %{value} pridÄ—tas"
-  text_tip_issue_begin_day: uÅ¾duotis, prasidedanti Å¡iÄ… dienÄ…
-  text_tip_issue_end_day: uÅ¾duotis, pasibaigianti Å¡iÄ… dienÄ…
-  text_tip_issue_begin_end_day: uÅ¾duotis, prasidedanti ir pasibaigianti Å¡iÄ… dienÄ…
-  text_project_identifier_info: 'MaÅ¾osios raidÄ—s (a-z), skaiÄiai ir brÅ«kÅ¡niai galimi.<br/>IÅ¡saugojus, identifikuotojas negali bÅ«ti keiÄiamas.'
-  text_caracters_maximum: "%{count} simboliÅ³ maksimumas."
-  text_caracters_minimum: "Turi bÅ«ti maÅ¾iausiai %{count} simboliÅ³ ilgio."
-  text_length_between: "Ilgis tarp %{min} ir %{max} simboliÅ³."
-  text_tracker_no_workflow: Jokia darbÅ³ eiga neapibrÄ—Å¾ta Å¡iam pÄ—dsekiui
-  text_unallowed_characters: Neleistini simboliai
-  text_comma_separated: Leistinos kelios reikÅ¡mÄ—s (atskirtos kableliu).
-  text_issues_ref_in_commit_messages: DarbÅ³ pavedimÅ³(commit) nurodymas ir fiksavimas  praneÅ¡imuose
-  text_issue_added: "Darbas %{id} buvo praneÅ¡tas (by %{author})."
-  text_issue_updated: "Darbas %{id} buvo atnaujintas (by %{author})."
-  text_wiki_destroy_confirmation: Ar esate Ä¯sitikinÄ™s, kad jÅ«s norite paÅ¡alinti wiki ir visÄ… jos turinÄ¯?
-  text_issue_category_destroy_question: "Kai kurie darbai (%{count}) yra paskirti Å¡iai kategorijai. KÄ… jÅ«s norite daryti?"
-  text_issue_category_destroy_assignments: PaÅ¡alinti kategorijos uÅ¾duotis
-  text_issue_category_reassign_to: IÅ¡ naujo priskirti darbus Å¡iai kategorijai
-  text_user_mail_option: "neiÅ¡rinktiems projektams, jÅ«s tiktai gausite praneÅ¡imus apie Ä¯vykius, kuriuos jÅ«s stebite, arba Ä¯ kuriuos esate Ä¯trauktas (pvz. darbai, jÅ«s esate autorius ar Ä¯galiotinis)."
-  text_no_configuration_data: "Vaidmenys, pÄ—dsekiai, darbÅ³ bÅ«senos ir darbÅ³ eiga dar nebuvo konfigÅ«ruoti.\nGrieÅ¾tai rekomenduojam uÅ¾krauti numatytÄ…jÄ…(default)konfiguracijÄ…. UÅ¾krovus, galÄ—site jÄ… modifikuoti."
-  text_load_default_configuration: UÅ¾krauti numatytÄ…j konfiguracijÄ…
-  text_status_changed_by_changeset: "Pakeista %{value} revizijoje."
-  text_issues_destroy_confirmation: 'Ar jÅ«s tikrai norite sunaikinti paÅ¾ymÄ—tÄ…(us) darbÄ…(us)?'
-  text_select_project_modules: 'Parinkite modulius, kuriuos norite naudoti Å¡iame projekte:'
-  text_default_administrator_account_changed: Administratoriaus numatyta paskyra pakeista
-  text_file_repository_writable: Ä® rinkmenu saugyklÄ… galima saugoti (RW)
-  text_plugin_assets_writable: Ä®skiepiÅ³ 'assets' katalogas Ä¯raÅ¡omas
-  text_rmagick_available: RMagick pasiekiamas (pasirinktinai)
-  text_destroy_time_entries_question: Naikinamam darbui priskirta %{hours} valandÅ³. KÄ… jÅ«s noryte su jomis daryti?
-  text_destroy_time_entries: IÅ¡trinti paskelbtas valandas
-  text_assign_time_entries_to_project: Priskirti valandas prie projekto
-  text_reassign_time_entries: 'Priskirti paskelbtas valandas Å¡iam darbui:'
-  text_user_wrote: "%{value} paraÅ¡Ä—:"
-  text_enumeration_destroy_question: "%{count} objektai priskirti Å¡iai reikÅ¡mei."
-  text_enumeration_category_reassign_to: 'Priskirti juos Å¡iai reikÅ¡mei:'
-  text_email_delivery_not_configured: "El.paÅ¡to siuntimas nesukonfigÅ«ruotas, ir perspÄ—jimai neaktyvus.\nSukonfigÅ«ruokite savo SMTP serverÄ¯ byloje config/configuration.yml ir perleiskite programÄ… norÄ—dami pritaikyti pakeitimus."
-  text_repository_usernames_mapping: "Parinkite  ar atnaujinkite Redmine vartotojo vardÄ… kiekvienam saugyklos vardui, kuris paminÄ—tas saugyklos log'e.\nVartotojai, turintys tÄ… patÄ¯ Redmine ir saugyklos vardÄ… ar el.paÅ¡tÄ… automatiÅ¡kai suriÅ¡ti."
-  text_diff_truncated: "... Å is diff'as nukarpytas, nes jis virÅ¡ijo maksimalÅ³ rodomÄ… eiluÄiÅ³ skaiÄiÅ³."
-  text_custom_field_possible_values_info: 'Po vienÄ… eilutÄ™ kiekvienai reikÅ¡mei'
-  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
-  text_wiki_page_reassign_children: Priskirkite iÅ¡ naujo 'child' puslapius Å¡iam puslapiui
-  text_wiki_page_nullify_children: Laikyti child puslapius as root puslapius
-  text_wiki_page_destroy_children: PaÅ¡alinti child puslapius ir jÅ³ sekinius
-
-  default_role_manager: Vadovas
-  default_role_developer: Projektuotojas
-  default_role_reporter: PraneÅ¡Ä—jas
-  default_tracker_bug: Klaida
-  default_tracker_feature: YpatybÄ—
-  default_tracker_support: Palaikymas
-  default_issue_status_new: Naujas
-  default_issue_status_in_progress: Vykdomas
-  default_issue_status_resolved: IÅ¡sprÄ™stas
-  default_issue_status_feedback: GrÄ¯Å¾tamasis ryÅ¡ys
-  default_issue_status_closed: UÅ¾darytas
-  default_issue_status_rejected: Atmestas
-  default_doc_category_user: Vartotojo dokumentacija
-  default_doc_category_tech: TechninÄ— dokumentacija
-  default_priority_low: Å½emas
-  default_priority_normal: Normalus
-  default_priority_high: AukÅ¡tas
-  default_priority_urgent: Skubus
-  default_priority_immediate: NeatidÄ—liotinas
-  default_activity_design: Projektavimas
-  default_activity_development: Vystymas
-  
-  enumeration_issue_priorities: Darbo prioritetai
-  enumeration_doc_categories: Dokumento kategorijos
-  enumeration_activities: Veiklos (laiko sekimas)
-  enumeration_system_activity: Sistemos veikla
-  label_copy_source: Source
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Same as target
-  label_copy_target: Target
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  setting_start_of_week: Start calendars on
-  error_workflow_copy_source: Please select a source tracker or role
-  label_update_issue_done_ratios: Update issue done ratios
-  permission_view_issues: View Issues
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API access key
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_missing_api_access_key: Missing an API access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  button_show: Show
-  text_line_separated: Multiple values allowed (one line for each value).
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Commit praneÅ¡imÅ³ koduotÄ—
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e8/e8aa327e67355ce663b09a685e02ede1d8c6edd6.svn-base
--- /dev/null
+++ b/.svn/pristine/e8/e8aa327e67355ce663b09a685e02ede1d8c6edd6.svn-base
@@ -0,0 +1,151 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Helpers
+    class TimeReport
+      attr_reader :criteria, :columns, :hours, :total_hours, :periods
+
+      def initialize(project, issue, criteria, columns, time_entry_scope)
+        @project = project
+        @issue = issue
+
+        @criteria = criteria || []
+        @criteria = @criteria.select{|criteria| available_criteria.has_key? criteria}
+        @criteria.uniq!
+        @criteria = @criteria[0,3]
+
+        @columns = (columns && %w(year month week day).include?(columns)) ? columns : 'month'
+        @scope = time_entry_scope
+
+        run
+      end
+
+      def available_criteria
+        @available_criteria || load_available_criteria
+      end
+
+      private
+
+      def run
+        unless @criteria.empty?
+          time_columns = %w(tyear tmonth tweek spent_on)
+          @hours = []
+          @scope.sum(:hours,
+              :include => [:issue, :activity],
+              :group => @criteria.collect{|criteria| @available_criteria[criteria][:sql]} + time_columns,
+              :joins => @criteria.collect{|criteria| @available_criteria[criteria][:joins]}.compact).each do |hash, hours|
+            h = {'hours' => hours}
+            (@criteria + time_columns).each_with_index do |name, i|
+              h[name] = hash[i]
+            end
+            @hours << h
+          end
+          
+          @hours.each do |row|
+            case @columns
+            when 'year'
+              row['year'] = row['tyear']
+            when 'month'
+              row['month'] = "#{row['tyear']}-#{row['tmonth']}"
+            when 'week'
+              row['week'] = "#{row['spent_on'].cwyear}-#{row['tweek']}"
+            when 'day'
+              row['day'] = "#{row['spent_on']}"
+            end
+          end
+          
+          min = @hours.collect {|row| row['spent_on']}.min
+          @from = min ? min.to_date : Date.today
+
+          max = @hours.collect {|row| row['spent_on']}.max
+          @to = max ? max.to_date : Date.today
+          
+          @total_hours = @hours.inject(0) {|s,k| s = s + k['hours'].to_f}
+
+          @periods = []
+          # Date#at_beginning_of_ not supported in Rails 1.2.x
+          date_from = @from.to_time
+          # 100 columns max
+          while date_from <= @to.to_time && @periods.length < 100
+            case @columns
+            when 'year'
+              @periods << "#{date_from.year}"
+              date_from = (date_from + 1.year).at_beginning_of_year
+            when 'month'
+              @periods << "#{date_from.year}-#{date_from.month}"
+              date_from = (date_from + 1.month).at_beginning_of_month
+            when 'week'
+              @periods << "#{date_from.to_date.cwyear}-#{date_from.to_date.cweek}"
+              date_from = (date_from + 7.day).at_beginning_of_week
+            when 'day'
+              @periods << "#{date_from.to_date}"
+              date_from = date_from + 1.day
+            end
+          end
+        end
+      end
+
+      def load_available_criteria
+        @available_criteria = { 'project' => {:sql => "#{TimeEntry.table_name}.project_id",
+                                              :klass => Project,
+                                              :label => :label_project},
+                                 'status' => {:sql => "#{Issue.table_name}.status_id",
+                                              :klass => IssueStatus,
+                                              :label => :field_status},
+                                 'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
+                                              :klass => Version,
+                                              :label => :label_version},
+                                 'category' => {:sql => "#{Issue.table_name}.category_id",
+                                                :klass => IssueCategory,
+                                                :label => :field_category},
+                                 'user' => {:sql => "#{TimeEntry.table_name}.user_id",
+                                             :klass => User,
+                                             :label => :label_user},
+                                 'tracker' => {:sql => "#{Issue.table_name}.tracker_id",
+                                              :klass => Tracker,
+                                              :label => :label_tracker},
+                                 'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
+                                               :klass => TimeEntryActivity,
+                                               :label => :label_activity},
+                                 'issue' => {:sql => "#{TimeEntry.table_name}.issue_id",
+                                             :klass => Issue,
+                                             :label => :label_issue}
+                               }
+
+        # Add time entry custom fields
+        custom_fields = TimeEntryCustomField.all
+        # Add project custom fields
+        custom_fields += ProjectCustomField.all
+        # Add issue custom fields
+        custom_fields += (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields)
+        # Add time entry activity custom fields
+        custom_fields += TimeEntryActivityCustomField.all
+
+        # Add list and boolean custom fields as available criteria
+        custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
+          @available_criteria["cf_#{cf.id}"] = {:sql => "#{cf.join_alias}.value",
+                                                 :joins => cf.join_for_order_statement,
+                                                 :format => cf.field_format,
+                                                 :label => cf.name}
+        end
+
+        @available_criteria
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e8/e8fc419080a0a4bab2022b5cb881a3e0c59a807b.svn-base
--- a/.svn/pristine/e8/e8fc419080a0a4bab2022b5cb881a3e0c59a807b.svn-base
+++ /dev/null
@@ -1,42 +0,0 @@
-<%= call_hook :view_account_login_top %>
-<div id="login-form">
-<% form_tag({:action=> "login"}) do %>
-<%= back_url_hidden_field_tag %>
-<table>
-<tr>
-    <td align="right"><label for="username"><%=l(:field_login)%>:</label></td>
-    <td align="left"><%= text_field_tag 'username', nil, :tabindex => '1' %></td>
-</tr>
-<tr>
-    <td align="right"><label for="password"><%=l(:field_password)%>:</label></td>
-    <td align="left"><%= password_field_tag 'password', nil, :tabindex => '2' %></td>
-</tr>
-<% if Setting.openid? %>
-<tr>
-  <td align="right"><label for="openid_url"><%=l(:field_identity_url)%></label></td>
-  <td align="left"><%= text_field_tag "openid_url", nil, :tabindex => '3' %></td>
-</tr>
-<% end %>
-<tr>
-    <td></td>
-    <td align="left">
-        <% if Setting.autologin? %>
-        <label for="autologin"><%= check_box_tag 'autologin', 1, false, :tabindex => 4 %> <%= l(:label_stay_logged_in) %></label>
-        <% end %>
-    </td>
-</tr>
-<tr>
-    <td align="left">
-        <% if Setting.lost_password? %>
-            <%= link_to l(:label_password_lost), :controller => 'account', :action => 'lost_password' %>
-        <% end %>
-    </td>
-    <td align="right">
-        <input type="submit" name="login" value="<%=l(:button_login)%> &#187;" tabindex="5"/>
-    </td>
-</tr>
-</table>
-<%= javascript_tag "Form.Element.focus('username');" %>
-<% end %>
-</div>
-<%= call_hook :view_account_login_bottom %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e9/e9895d42866e8fe662252fd7f421c7dd0505d9a5.svn-base
--- /dev/null
+++ b/.svn/pristine/e9/e9895d42866e8fe662252fd7f421c7dd0505d9a5.svn-base
@@ -0,0 +1,38 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/views/builders/json'
+require 'redmine/views/builders/xml'
+
+module Redmine
+  module Views
+    module Builders
+      def self.for(format, request, response, &block)
+        builder = case format
+          when 'xml',  :xml;  Builders::Xml.new(request, response)
+          when 'json', :json; Builders::Json.new(request, response)
+          else; raise "No builder for format #{format}"
+        end
+        if block
+          block.call(builder)
+        else
+          builder
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e9/e9990f128dfb945f216de87f320fffbd740baf36.svn-base
--- a/.svn/pristine/e9/e9990f128dfb945f216de87f320fffbd740baf36.svn-base
+++ /dev/null
@@ -1,1984 +0,0 @@
-#!/usr/local/bin/ruby -w
-
-# = faster_csv.rb -- Faster CSV Reading and Writing
-#
-#  Created by James Edward Gray II on 2005-10-31.
-#  Copyright 2005 Gray Productions. All rights reserved.
-# 
-# See FasterCSV for documentation.
-
-if RUBY_VERSION >= "1.9"
-  abort <<-VERSION_WARNING.gsub(/^\s+/, "")
-  Please switch to Ruby 1.9's standard CSV library.  It's FasterCSV plus
-  support for Ruby 1.9's m17n encoding engine.
-  VERSION_WARNING
-end
-
-require "forwardable"
-require "English"
-require "enumerator"
-require "date"
-require "stringio"
-
-# 
-# This class provides a complete interface to CSV files and data.  It offers
-# tools to enable you to read and write to and from Strings or IO objects, as
-# needed.
-# 
-# == Reading
-# 
-# === From a File
-# 
-# ==== A Line at a Time
-# 
-#   FasterCSV.foreach("path/to/file.csv") do |row|
-#     # use row here...
-#   end
-# 
-# ==== All at Once
-# 
-#   arr_of_arrs = FasterCSV.read("path/to/file.csv")
-# 
-# === From a String
-# 
-# ==== A Line at a Time
-# 
-#   FasterCSV.parse("CSV,data,String") do |row|
-#     # use row here...
-#   end
-# 
-# ==== All at Once
-# 
-#   arr_of_arrs = FasterCSV.parse("CSV,data,String")
-# 
-# == Writing
-# 
-# === To a File
-# 
-#   FasterCSV.open("path/to/file.csv", "w") do |csv|
-#     csv << ["row", "of", "CSV", "data"]
-#     csv << ["another", "row"]
-#     # ...
-#   end
-# 
-# === To a String
-# 
-#   csv_string = FasterCSV.generate do |csv|
-#     csv << ["row", "of", "CSV", "data"]
-#     csv << ["another", "row"]
-#     # ...
-#   end
-# 
-# == Convert a Single Line
-# 
-#   csv_string = ["CSV", "data"].to_csv   # to CSV
-#   csv_array  = "CSV,String".parse_csv   # from CSV
-# 
-# == Shortcut Interface
-# 
-#   FCSV             { |csv_out| csv_out << %w{my data here} }  # to $stdout
-#   FCSV(csv = "")   { |csv_str| csv_str << %w{my data here} }  # to a String
-#   FCSV($stderr)    { |csv_err| csv_err << %w{my data here} }  # to $stderr
-# 
-class FasterCSV
-  # The version of the installed library.
-  VERSION = "1.5.0".freeze
-  
-  # 
-  # A FasterCSV::Row is part Array and part Hash.  It retains an order for the
-  # fields and allows duplicates just as an Array would, but also allows you to
-  # access fields by name just as you could if they were in a Hash.
-  # 
-  # All rows returned by FasterCSV will be constructed from this class, if
-  # header row processing is activated.
-  # 
-  class Row
-    # 
-    # Construct a new FasterCSV::Row from +headers+ and +fields+, which are
-    # expected to be Arrays.  If one Array is shorter than the other, it will be
-    # padded with +nil+ objects.
-    # 
-    # The optional +header_row+ parameter can be set to +true+ to indicate, via
-    # FasterCSV::Row.header_row?() and FasterCSV::Row.field_row?(), that this is
-    # a header row.  Otherwise, the row is assumes to be a field row.
-    # 
-    # A FasterCSV::Row object supports the following Array methods through
-    # delegation:
-    # 
-    # * empty?()
-    # * length()
-    # * size()
-    # 
-    def initialize(headers, fields, header_row = false)
-      @header_row = header_row
-      
-      # handle extra headers or fields
-      @row = if headers.size > fields.size
-        headers.zip(fields)
-      else
-        fields.zip(headers).map { |pair| pair.reverse }
-      end
-    end
-    
-    # Internal data format used to compare equality.
-    attr_reader :row
-    protected   :row
-
-    ### Array Delegation ###
-
-    extend Forwardable
-    def_delegators :@row, :empty?, :length, :size
-    
-    # Returns +true+ if this is a header row.
-    def header_row?
-      @header_row
-    end
-    
-    # Returns +true+ if this is a field row.
-    def field_row?
-      not header_row?
-    end
-    
-    # Returns the headers of this row.
-    def headers
-      @row.map { |pair| pair.first }
-    end
-    
-    # 
-    # :call-seq:
-    #   field( header )
-    #   field( header, offset )
-    #   field( index )
-    # 
-    # This method will fetch the field value by +header+ or +index+.  If a field
-    # is not found, +nil+ is returned.
-    # 
-    # When provided, +offset+ ensures that a header match occurrs on or later
-    # than the +offset+ index.  You can use this to find duplicate headers, 
-    # without resorting to hard-coding exact indices.
-    # 
-    def field(header_or_index, minimum_index = 0)
-      # locate the pair
-      finder = header_or_index.is_a?(Integer) ? :[] : :assoc
-      pair   = @row[minimum_index..-1].send(finder, header_or_index)
-
-      # return the field if we have a pair
-      pair.nil? ? nil : pair.last
-    end
-    alias_method :[], :field
-    
-    # 
-    # :call-seq:
-    #   []=( header, value )
-    #   []=( header, offset, value )
-    #   []=( index, value )
-    # 
-    # Looks up the field by the semantics described in FasterCSV::Row.field()
-    # and assigns the +value+.
-    # 
-    # Assigning past the end of the row with an index will set all pairs between
-    # to <tt>[nil, nil]</tt>.  Assigning to an unused header appends the new
-    # pair.
-    # 
-    def []=(*args)
-      value = args.pop
-      
-      if args.first.is_a? Integer
-        if @row[args.first].nil?  # extending past the end with index
-          @row[args.first] = [nil, value]
-          @row.map! { |pair| pair.nil? ? [nil, nil] : pair }
-        else                      # normal index assignment
-          @row[args.first][1] = value
-        end
-      else
-        index = index(*args)
-        if index.nil?             # appending a field
-          self << [args.first, value]
-        else                      # normal header assignment
-          @row[index][1] = value
-        end
-      end
-    end
-    
-    # 
-    # :call-seq:
-    #   <<( field )
-    #   <<( header_and_field_array )
-    #   <<( header_and_field_hash )
-    # 
-    # If a two-element Array is provided, it is assumed to be a header and field
-    # and the pair is appended.  A Hash works the same way with the key being
-    # the header and the value being the field.  Anything else is assumed to be
-    # a lone field which is appended with a +nil+ header.
-    # 
-    # This method returns the row for chaining.
-    # 
-    def <<(arg)
-      if arg.is_a?(Array) and arg.size == 2  # appending a header and name
-        @row << arg
-      elsif arg.is_a?(Hash)                  # append header and name pairs
-        arg.each { |pair| @row << pair }
-      else                                   # append field value
-        @row << [nil, arg]
-      end
-      
-      self  # for chaining
-    end
-    
-    # 
-    # A shortcut for appending multiple fields.  Equivalent to:
-    # 
-    #   args.each { |arg| faster_csv_row << arg }
-    # 
-    # This method returns the row for chaining.
-    # 
-    def push(*args)
-      args.each { |arg| self << arg }
-      
-      self  # for chaining
-    end
-    
-    # 
-    # :call-seq:
-    #   delete( header )
-    #   delete( header, offset )
-    #   delete( index )
-    # 
-    # Used to remove a pair from the row by +header+ or +index+.  The pair is
-    # located as described in FasterCSV::Row.field().  The deleted pair is 
-    # returned, or +nil+ if a pair could not be found.
-    # 
-    def delete(header_or_index, minimum_index = 0)
-      if header_or_index.is_a? Integer  # by index
-        @row.delete_at(header_or_index)
-      else                              # by header
-        @row.delete_at(index(header_or_index, minimum_index))
-      end
-    end
-    
-    # 
-    # The provided +block+ is passed a header and field for each pair in the row
-    # and expected to return +true+ or +false+, depending on whether the pair
-    # should be deleted.
-    # 
-    # This method returns the row for chaining.
-    # 
-    def delete_if(&block)
-      @row.delete_if(&block)
-      
-      self  # for chaining
-    end
-    
-    # 
-    # This method accepts any number of arguments which can be headers, indices,
-    # Ranges of either, or two-element Arrays containing a header and offset.  
-    # Each argument will be replaced with a field lookup as described in
-    # FasterCSV::Row.field().
-    # 
-    # If called with no arguments, all fields are returned.
-    # 
-    def fields(*headers_and_or_indices)
-      if headers_and_or_indices.empty?  # return all fields--no arguments
-        @row.map { |pair| pair.last }
-      else                              # or work like values_at()
-        headers_and_or_indices.inject(Array.new) do |all, h_or_i|
-          all + if h_or_i.is_a? Range
-            index_begin = h_or_i.begin.is_a?(Integer) ? h_or_i.begin :
-                                                        index(h_or_i.begin)
-            index_end   = h_or_i.end.is_a?(Integer)   ? h_or_i.end :
-                                                        index(h_or_i.end)
-            new_range   = h_or_i.exclude_end? ? (index_begin...index_end) :
-                                                (index_begin..index_end)
-            fields.values_at(new_range)
-          else
-            [field(*Array(h_or_i))]
-          end
-        end
-      end
-    end
-    alias_method :values_at, :fields
-    
-    # 
-    # :call-seq:
-    #   index( header )
-    #   index( header, offset )
-    # 
-    # This method will return the index of a field with the provided +header+.
-    # The +offset+ can be used to locate duplicate header names, as described in
-    # FasterCSV::Row.field().
-    # 
-    def index(header, minimum_index = 0)
-      # find the pair
-      index = headers[minimum_index..-1].index(header)
-      # return the index at the right offset, if we found one
-      index.nil? ? nil : index + minimum_index
-    end
-    
-    # Returns +true+ if +name+ is a header for this row, and +false+ otherwise.
-    def header?(name)
-      headers.include? name
-    end
-    alias_method :include?, :header?
-    
-    # 
-    # Returns +true+ if +data+ matches a field in this row, and +false+
-    # otherwise.
-    # 
-    def field?(data)
-      fields.include? data
-    end
-
-    include Enumerable
-    
-    # 
-    # Yields each pair of the row as header and field tuples (much like
-    # iterating over a Hash).
-    # 
-    # Support for Enumerable.
-    # 
-    # This method returns the row for chaining.
-    # 
-    def each(&block)
-      @row.each(&block)
-      
-      self  # for chaining
-    end
-    
-    # 
-    # Returns +true+ if this row contains the same headers and fields in the 
-    # same order as +other+.
-    # 
-    def ==(other)
-      @row == other.row
-    end
-    
-    # 
-    # Collapses the row into a simple Hash.  Be warning that this discards field
-    # order and clobbers duplicate fields.
-    # 
-    def to_hash
-      # flatten just one level of the internal Array
-      Hash[*@row.inject(Array.new) { |ary, pair| ary.push(*pair) }]
-    end
-    
-    # 
-    # Returns the row as a CSV String.  Headers are not used.  Equivalent to:
-    # 
-    #   faster_csv_row.fields.to_csv( options )
-    # 
-    def to_csv(options = Hash.new)
-      fields.to_csv(options)
-    end
-    alias_method :to_s, :to_csv
-    
-    # A summary of fields, by header.
-    def inspect
-      str = "#<#{self.class}"
-      each do |header, field|
-        str << " #{header.is_a?(Symbol) ? header.to_s : header.inspect}:" <<
-               field.inspect
-      end
-      str << ">"
-    end
-  end
-  
-  # 
-  # A FasterCSV::Table is a two-dimensional data structure for representing CSV
-  # documents.  Tables allow you to work with the data by row or column, 
-  # manipulate the data, and even convert the results back to CSV, if needed.
-  # 
-  # All tables returned by FasterCSV will be constructed from this class, if
-  # header row processing is activated.
-  # 
-  class Table
-    # 
-    # Construct a new FasterCSV::Table from +array_of_rows+, which are expected
-    # to be FasterCSV::Row objects.  All rows are assumed to have the same 
-    # headers.
-    # 
-    # A FasterCSV::Table object supports the following Array methods through
-    # delegation:
-    # 
-    # * empty?()
-    # * length()
-    # * size()
-    # 
-    def initialize(array_of_rows)
-      @table = array_of_rows
-      @mode  = :col_or_row
-    end
-    
-    # The current access mode for indexing and iteration.
-    attr_reader :mode
-    
-    # Internal data format used to compare equality.
-    attr_reader :table
-    protected   :table
-
-    ### Array Delegation ###
-
-    extend Forwardable
-    def_delegators :@table, :empty?, :length, :size
-    
-    # 
-    # Returns a duplicate table object, in column mode.  This is handy for 
-    # chaining in a single call without changing the table mode, but be aware 
-    # that this method can consume a fair amount of memory for bigger data sets.
-    # 
-    # This method returns the duplicate table for chaining.  Don't chain
-    # destructive methods (like []=()) this way though, since you are working
-    # with a duplicate.
-    # 
-    def by_col
-      self.class.new(@table.dup).by_col!
-    end
-    
-    # 
-    # Switches the mode of this table to column mode.  All calls to indexing and
-    # iteration methods will work with columns until the mode is changed again.
-    # 
-    # This method returns the table and is safe to chain.
-    # 
-    def by_col!
-      @mode = :col
-      
-      self
-    end
-    
-    # 
-    # Returns a duplicate table object, in mixed mode.  This is handy for 
-    # chaining in a single call without changing the table mode, but be aware 
-    # that this method can consume a fair amount of memory for bigger data sets.
-    # 
-    # This method returns the duplicate table for chaining.  Don't chain
-    # destructive methods (like []=()) this way though, since you are working
-    # with a duplicate.
-    # 
-    def by_col_or_row
-      self.class.new(@table.dup).by_col_or_row!
-    end
-    
-    # 
-    # Switches the mode of this table to mixed mode.  All calls to indexing and
-    # iteration methods will use the default intelligent indexing system until
-    # the mode is changed again.  In mixed mode an index is assumed to be a row
-    # reference while anything else is assumed to be column access by headers.
-    # 
-    # This method returns the table and is safe to chain.
-    # 
-    def by_col_or_row!
-      @mode = :col_or_row
-      
-      self
-    end
-    
-    # 
-    # Returns a duplicate table object, in row mode.  This is handy for chaining
-    # in a single call without changing the table mode, but be aware that this
-    # method can consume a fair amount of memory for bigger data sets.
-    # 
-    # This method returns the duplicate table for chaining.  Don't chain
-    # destructive methods (like []=()) this way though, since you are working
-    # with a duplicate.
-    # 
-    def by_row
-      self.class.new(@table.dup).by_row!
-    end
-    
-    # 
-    # Switches the mode of this table to row mode.  All calls to indexing and
-    # iteration methods will work with rows until the mode is changed again.
-    # 
-    # This method returns the table and is safe to chain.
-    # 
-    def by_row!
-      @mode = :row
-      
-      self
-    end
-    
-    # 
-    # Returns the headers for the first row of this table (assumed to match all
-    # other rows).  An empty Array is returned for empty tables.
-    # 
-    def headers
-      if @table.empty?
-        Array.new
-      else
-        @table.first.headers
-      end
-    end
-    
-    # 
-    # In the default mixed mode, this method returns rows for index access and
-    # columns for header access.  You can force the index association by first
-    # calling by_col!() or by_row!().
-    # 
-    # Columns are returned as an Array of values.  Altering that Array has no
-    # effect on the table.
-    # 
-    def [](index_or_header)
-      if @mode == :row or  # by index
-         (@mode == :col_or_row and index_or_header.is_a? Integer)
-        @table[index_or_header]
-      else                 # by header
-        @table.map { |row| row[index_or_header] }
-      end
-    end
-    
-    # 
-    # In the default mixed mode, this method assigns rows for index access and
-    # columns for header access.  You can force the index association by first
-    # calling by_col!() or by_row!().
-    # 
-    # Rows may be set to an Array of values (which will inherit the table's
-    # headers()) or a FasterCSV::Row.
-    # 
-    # Columns may be set to a single value, which is copied to each row of the 
-    # column, or an Array of values.  Arrays of values are assigned to rows top
-    # to bottom in row major order.  Excess values are ignored and if the Array
-    # does not have a value for each row the extra rows will receive a +nil+.
-    # 
-    # Assigning to an existing column or row clobbers the data.  Assigning to
-    # new columns creates them at the right end of the table.
-    # 
-    def []=(index_or_header, value)
-      if @mode == :row or  # by index
-         (@mode == :col_or_row and index_or_header.is_a? Integer)
-        if value.is_a? Array
-          @table[index_or_header] = Row.new(headers, value)
-        else
-          @table[index_or_header] = value
-        end
-      else                 # set column
-        if value.is_a? Array  # multiple values
-          @table.each_with_index do |row, i|
-            if row.header_row?
-              row[index_or_header] = index_or_header
-            else
-              row[index_or_header] = value[i]
-            end
-          end
-        else                  # repeated value
-          @table.each do |row|
-            if row.header_row?
-              row[index_or_header] = index_or_header
-            else
-              row[index_or_header] = value
-            end
-          end
-        end
-      end
-    end
-    
-    # 
-    # The mixed mode default is to treat a list of indices as row access,
-    # returning the rows indicated.  Anything else is considered columnar
-    # access.  For columnar access, the return set has an Array for each row
-    # with the values indicated by the headers in each Array.  You can force
-    # column or row mode using by_col!() or by_row!().
-    # 
-    # You cannot mix column and row access.
-    # 
-    def values_at(*indices_or_headers)
-      if @mode == :row or  # by indices
-         ( @mode == :col_or_row and indices_or_headers.all? do |index|
-                                      index.is_a?(Integer)         or
-                                      ( index.is_a?(Range)         and
-                                        index.first.is_a?(Integer) and
-                                        index.last.is_a?(Integer) )
-                                    end )
-        @table.values_at(*indices_or_headers)
-      else                 # by headers
-        @table.map { |row| row.values_at(*indices_or_headers) }
-      end
-    end
-
-    # 
-    # Adds a new row to the bottom end of this table.  You can provide an Array,
-    # which will be converted to a FasterCSV::Row (inheriting the table's
-    # headers()), or a FasterCSV::Row.
-    # 
-    # This method returns the table for chaining.
-    # 
-    def <<(row_or_array)
-      if row_or_array.is_a? Array  # append Array
-        @table << Row.new(headers, row_or_array)
-      else                         # append Row
-        @table << row_or_array
-      end
-      
-      self  # for chaining
-    end
-    
-    # 
-    # A shortcut for appending multiple rows.  Equivalent to:
-    # 
-    #   rows.each { |row| self << row }
-    # 
-    # This method returns the table for chaining.
-    # 
-    def push(*rows)
-      rows.each { |row| self << row }
-      
-      self  # for chaining
-    end
-
-    # 
-    # Removes and returns the indicated column or row.  In the default mixed
-    # mode indices refer to rows and everything else is assumed to be a column
-    # header.  Use by_col!() or by_row!() to force the lookup.
-    # 
-    def delete(index_or_header)
-      if @mode == :row or  # by index
-         (@mode == :col_or_row and index_or_header.is_a? Integer)
-        @table.delete_at(index_or_header)
-      else                 # by header
-        @table.map { |row| row.delete(index_or_header).last }
-      end
-    end
-    
-    # 
-    # Removes any column or row for which the block returns +true+.  In the
-    # default mixed mode or row mode, iteration is the standard row major
-    # walking of rows.  In column mode, interation will +yield+ two element
-    # tuples containing the column name and an Array of values for that column.
-    # 
-    # This method returns the table for chaining.
-    # 
-    def delete_if(&block)
-      if @mode == :row or @mode == :col_or_row  # by index
-        @table.delete_if(&block)
-      else                                      # by header
-        to_delete = Array.new
-        headers.each_with_index do |header, i|
-          to_delete << header if block[[header, self[header]]]
-        end
-        to_delete.map { |header| delete(header) }
-      end
-      
-      self  # for chaining
-    end
-    
-    include Enumerable
-    
-    # 
-    # In the default mixed mode or row mode, iteration is the standard row major
-    # walking of rows.  In column mode, interation will +yield+ two element
-    # tuples containing the column name and an Array of values for that column.
-    # 
-    # This method returns the table for chaining.
-    # 
-    def each(&block)
-      if @mode == :col
-        headers.each { |header| block[[header, self[header]]] }
-      else
-        @table.each(&block)
-      end
-      
-      self  # for chaining
-    end
-    
-    # Returns +true+ if all rows of this table ==() +other+'s rows.
-    def ==(other)
-      @table == other.table
-    end
-    
-    # 
-    # Returns the table as an Array of Arrays.  Headers will be the first row,
-    # then all of the field rows will follow.
-    # 
-    def to_a
-      @table.inject([headers]) do |array, row|
-        if row.header_row?
-          array
-        else
-          array + [row.fields]
-        end
-      end
-    end
-    
-    # 
-    # Returns the table as a complete CSV String.  Headers will be listed first,
-    # then all of the field rows.
-    # 
-    def to_csv(options = Hash.new)
-      @table.inject([headers.to_csv(options)]) do |rows, row|
-        if row.header_row?
-          rows
-        else
-          rows + [row.fields.to_csv(options)]
-        end
-      end.join
-    end
-    alias_method :to_s, :to_csv
-    
-    def inspect
-      "#<#{self.class} mode:#{@mode} row_count:#{to_a.size}>"
-    end
-  end
-
-  # The error thrown when the parser encounters illegal CSV formatting.
-  class MalformedCSVError < RuntimeError; end
-  
-  # 
-  # A FieldInfo Struct contains details about a field's position in the data
-  # source it was read from.  FasterCSV will pass this Struct to some blocks
-  # that make decisions based on field structure.  See 
-  # FasterCSV.convert_fields() for an example.
-  # 
-  # <b><tt>index</tt></b>::  The zero-based index of the field in its row.
-  # <b><tt>line</tt></b>::   The line of the data source this row is from.
-  # <b><tt>header</tt></b>:: The header for the column, when available.
-  # 
-  FieldInfo = Struct.new(:index, :line, :header)
-  
-  # A Regexp used to find and convert some common Date formats.
-  DateMatcher     = / \A(?: (\w+,?\s+)?\w+\s+\d{1,2},?\s+\d{2,4} |
-                            \d{4}-\d{2}-\d{2} )\z /x
-  # A Regexp used to find and convert some common DateTime formats.
-  DateTimeMatcher =
-    / \A(?: (\w+,?\s+)?\w+\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2},?\s+\d{2,4} |
-            \d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2} )\z /x
-  # 
-  # This Hash holds the built-in converters of FasterCSV that can be accessed by
-  # name.  You can select Converters with FasterCSV.convert() or through the
-  # +options+ Hash passed to FasterCSV::new().
-  # 
-  # <b><tt>:integer</tt></b>::    Converts any field Integer() accepts.
-  # <b><tt>:float</tt></b>::      Converts any field Float() accepts.
-  # <b><tt>:numeric</tt></b>::    A combination of <tt>:integer</tt> 
-  #                               and <tt>:float</tt>.
-  # <b><tt>:date</tt></b>::       Converts any field Date::parse() accepts.
-  # <b><tt>:date_time</tt></b>::  Converts any field DateTime::parse() accepts.
-  # <b><tt>:all</tt></b>::        All built-in converters.  A combination of 
-  #                               <tt>:date_time</tt> and <tt>:numeric</tt>.
-  # 
-  # This Hash is intetionally left unfrozen and users should feel free to add
-  # values to it that can be accessed by all FasterCSV objects.
-  # 
-  # To add a combo field, the value should be an Array of names.  Combo fields
-  # can be nested with other combo fields.
-  # 
-  Converters  = { :integer   => lambda { |f| Integer(f)        rescue f },
-                  :float     => lambda { |f| Float(f)          rescue f },
-                  :numeric   => [:integer, :float],
-                  :date      => lambda { |f|
-                    f =~ DateMatcher ? (Date.parse(f) rescue f) : f
-                  },
-                  :date_time => lambda { |f|
-                    f =~ DateTimeMatcher ? (DateTime.parse(f) rescue f) : f
-                  },
-                  :all       => [:date_time, :numeric] }
-
-  # 
-  # This Hash holds the built-in header converters of FasterCSV that can be
-  # accessed by name.  You can select HeaderConverters with
-  # FasterCSV.header_convert() or through the +options+ Hash passed to
-  # FasterCSV::new().
-  # 
-  # <b><tt>:downcase</tt></b>::  Calls downcase() on the header String.
-  # <b><tt>:symbol</tt></b>::    The header String is downcased, spaces are
-  #                              replaced with underscores, non-word characters
-  #                              are dropped, and finally to_sym() is called.
-  # 
-  # This Hash is intetionally left unfrozen and users should feel free to add
-  # values to it that can be accessed by all FasterCSV objects.
-  # 
-  # To add a combo field, the value should be an Array of names.  Combo fields
-  # can be nested with other combo fields.
-  # 
-  HeaderConverters = {
-    :downcase => lambda { |h| h.downcase },
-    :symbol   => lambda { |h|
-      h.downcase.tr(" ", "_").delete("^a-z0-9_").to_sym
-    }
-  }
-  
-  # 
-  # The options used when no overrides are given by calling code.  They are:
-  # 
-  # <b><tt>:col_sep</tt></b>::            <tt>","</tt>
-  # <b><tt>:row_sep</tt></b>::            <tt>:auto</tt>
-  # <b><tt>:quote_char</tt></b>::         <tt>'"'</tt>
-  # <b><tt>:converters</tt></b>::         +nil+
-  # <b><tt>:unconverted_fields</tt></b>:: +nil+
-  # <b><tt>:headers</tt></b>::            +false+
-  # <b><tt>:return_headers</tt></b>::     +false+
-  # <b><tt>:header_converters</tt></b>::  +nil+
-  # <b><tt>:skip_blanks</tt></b>::        +false+
-  # <b><tt>:force_quotes</tt></b>::       +false+
-  # 
-  DEFAULT_OPTIONS = { :col_sep            => ",",
-                      :row_sep            => :auto,
-                      :quote_char         => '"', 
-                      :converters         => nil,
-                      :unconverted_fields => nil,
-                      :headers            => false,
-                      :return_headers     => false,
-                      :header_converters  => nil,
-                      :skip_blanks        => false,
-                      :force_quotes       => false }.freeze
-  
-  # 
-  # This method will build a drop-in replacement for many of the standard CSV
-  # methods.  It allows you to write code like:
-  # 
-  #   begin
-  #     require "faster_csv"
-  #     FasterCSV.build_csv_interface
-  #   rescue LoadError
-  #     require "csv"
-  #   end
-  #   # ... use CSV here ...
-  # 
-  # This is not a complete interface with completely identical behavior.
-  # However, it is intended to be close enough that you won't notice the
-  # difference in most cases.  CSV methods supported are:
-  # 
-  # * foreach()
-  # * generate_line()
-  # * open()
-  # * parse()
-  # * parse_line()
-  # * readlines()
-  # 
-  # Be warned that this interface is slower than vanilla FasterCSV due to the
-  # extra layer of method calls.  Depending on usage, this can slow it down to 
-  # near CSV speeds.
-  # 
-  def self.build_csv_interface
-    Object.const_set(:CSV, Class.new).class_eval do
-      def self.foreach(path, rs = :auto, &block)  # :nodoc:
-        FasterCSV.foreach(path, :row_sep => rs, &block)
-      end
-      
-      def self.generate_line(row, fs = ",", rs = "")  # :nodoc:
-        FasterCSV.generate_line(row, :col_sep => fs, :row_sep => rs)
-      end
-      
-      def self.open(path, mode, fs = ",", rs = :auto, &block)  # :nodoc:
-        if block and mode.include? "r"
-          FasterCSV.open(path, mode, :col_sep => fs, :row_sep => rs) do |csv|
-            csv.each(&block)
-          end
-        else
-          FasterCSV.open(path, mode, :col_sep => fs, :row_sep => rs, &block)
-        end
-      end
-      
-      def self.parse(str_or_readable, fs = ",", rs = :auto, &block)  # :nodoc:
-        FasterCSV.parse(str_or_readable, :col_sep => fs, :row_sep => rs, &block)
-      end
-      
-      def self.parse_line(src, fs = ",", rs = :auto)  # :nodoc:
-        FasterCSV.parse_line(src, :col_sep => fs, :row_sep => rs)
-      end
-      
-      def self.readlines(path, rs = :auto)  # :nodoc:
-        FasterCSV.readlines(path, :row_sep => rs)
-      end
-    end
-  end
-  
-  # 
-  # This method allows you to serialize an Array of Ruby objects to a String or
-  # File of CSV data.  This is not as powerful as Marshal or YAML, but perhaps
-  # useful for spreadsheet and database interaction.
-  # 
-  # Out of the box, this method is intended to work with simple data objects or
-  # Structs.  It will serialize a list of instance variables and/or
-  # Struct.members().
-  # 
-  # If you need need more complicated serialization, you can control the process
-  # by adding methods to the class to be serialized.
-  # 
-  # A class method csv_meta() is responsible for returning the first row of the
-  # document (as an Array).  This row is considered to be a Hash of the form
-  # key_1,value_1,key_2,value_2,...  FasterCSV::load() expects to find a class
-  # key with a value of the stringified class name and FasterCSV::dump() will
-  # create this, if you do not define this method.  This method is only called
-  # on the first object of the Array.
-  # 
-  # The next method you can provide is an instance method called csv_headers().
-  # This method is expected to return the second line of the document (again as
-  # an Array), which is to be used to give each column a header.  By default,
-  # FasterCSV::load() will set an instance variable if the field header starts
-  # with an @ character or call send() passing the header as the method name and
-  # the field value as an argument.  This method is only called on the first
-  # object of the Array.
-  # 
-  # Finally, you can provide an instance method called csv_dump(), which will
-  # be passed the headers.  This should return an Array of fields that can be
-  # serialized for this object.  This method is called once for every object in
-  # the Array.
-  # 
-  # The +io+ parameter can be used to serialize to a File, and +options+ can be
-  # anything FasterCSV::new() accepts.
-  # 
-  def self.dump(ary_of_objs, io = "", options = Hash.new)
-    obj_template = ary_of_objs.first
-    
-    csv = FasterCSV.new(io, options)
-    
-    # write meta information
-    begin
-      csv << obj_template.class.csv_meta
-    rescue NoMethodError
-      csv << [:class, obj_template.class]
-    end
-
-    # write headers
-    begin
-      headers = obj_template.csv_headers
-    rescue NoMethodError
-      headers = obj_template.instance_variables.sort
-      if obj_template.class.ancestors.find { |cls| cls.to_s =~ /\AStruct\b/ }
-        headers += obj_template.members.map { |mem| "#{mem}=" }.sort
-      end
-    end
-    csv << headers
-    
-    # serialize each object
-    ary_of_objs.each do |obj|
-      begin
-        csv << obj.csv_dump(headers)
-      rescue NoMethodError
-        csv << headers.map do |var|
-          if var[0] == ?@
-            obj.instance_variable_get(var)
-          else
-            obj[var[0..-2]]
-          end
-        end
-      end
-    end
-    
-    if io.is_a? String
-      csv.string
-    else
-      csv.close
-    end
-  end
-  
-  # 
-  # :call-seq:
-  #   filter( options = Hash.new ) { |row| ... }
-  #   filter( input, options = Hash.new ) { |row| ... }
-  #   filter( input, output, options = Hash.new ) { |row| ... }
-  # 
-  # This method is a convenience for building Unix-like filters for CSV data.
-  # Each row is yielded to the provided block which can alter it as needed.  
-  # After the block returns, the row is appended to +output+ altered or not.
-  # 
-  # The +input+ and +output+ arguments can be anything FasterCSV::new() accepts
-  # (generally String or IO objects).  If not given, they default to 
-  # <tt>ARGF</tt> and <tt>$stdout</tt>.
-  # 
-  # The +options+ parameter is also filtered down to FasterCSV::new() after some
-  # clever key parsing.  Any key beginning with <tt>:in_</tt> or 
-  # <tt>:input_</tt> will have that leading identifier stripped and will only
-  # be used in the +options+ Hash for the +input+ object.  Keys starting with
-  # <tt>:out_</tt> or <tt>:output_</tt> affect only +output+.  All other keys 
-  # are assigned to both objects.
-  # 
-  # The <tt>:output_row_sep</tt> +option+ defaults to
-  # <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>).
-  # 
-  def self.filter(*args)
-    # parse options for input, output, or both
-    in_options, out_options = Hash.new, {:row_sep => $INPUT_RECORD_SEPARATOR}
-    if args.last.is_a? Hash
-      args.pop.each do |key, value|
-        case key.to_s
-        when /\Ain(?:put)?_(.+)\Z/
-          in_options[$1.to_sym] = value
-        when /\Aout(?:put)?_(.+)\Z/
-          out_options[$1.to_sym] = value
-        else
-          in_options[key]  = value
-          out_options[key] = value
-        end
-      end
-    end
-    # build input and output wrappers
-    input   = FasterCSV.new(args.shift || ARGF,    in_options)
-    output  = FasterCSV.new(args.shift || $stdout, out_options)
-    
-    # read, yield, write
-    input.each do |row|
-      yield row
-      output << row
-    end
-  end
-  
-  # 
-  # This method is intended as the primary interface for reading CSV files.  You
-  # pass a +path+ and any +options+ you wish to set for the read.  Each row of
-  # file will be passed to the provided +block+ in turn.
-  # 
-  # The +options+ parameter can be anything FasterCSV::new() understands.
-  # 
-  def self.foreach(path, options = Hash.new, &block)
-    open(path, "rb", options) do |csv|
-      csv.each(&block)
-    end
-  end
-
-  # 
-  # :call-seq:
-  #   generate( str, options = Hash.new ) { |faster_csv| ... }
-  #   generate( options = Hash.new ) { |faster_csv| ... }
-  # 
-  # This method wraps a String you provide, or an empty default String, in a 
-  # FasterCSV object which is passed to the provided block.  You can use the 
-  # block to append CSV rows to the String and when the block exits, the 
-  # final String will be returned.
-  # 
-  # Note that a passed String *is* modfied by this method.  Call dup() before
-  # passing if you need a new String.
-  # 
-  # The +options+ parameter can be anthing FasterCSV::new() understands.
-  # 
-  def self.generate(*args)
-    # add a default empty String, if none was given
-    if args.first.is_a? String
-      io = StringIO.new(args.shift)
-      io.seek(0, IO::SEEK_END)
-      args.unshift(io)
-    else
-      args.unshift("")
-    end
-    faster_csv = new(*args)  # wrap
-    yield faster_csv         # yield for appending
-    faster_csv.string        # return final String
-  end
-
-  # 
-  # This method is a shortcut for converting a single row (Array) into a CSV 
-  # String.
-  # 
-  # The +options+ parameter can be anthing FasterCSV::new() understands.
-  # 
-  # The <tt>:row_sep</tt> +option+ defaults to <tt>$INPUT_RECORD_SEPARATOR</tt>
-  # (<tt>$/</tt>) when calling this method.
-  # 
-  def self.generate_line(row, options = Hash.new)
-    options = {:row_sep => $INPUT_RECORD_SEPARATOR}.merge(options)
-    (new("", options) << row).string
-  end
-  
-  # 
-  # This method will return a FasterCSV instance, just like FasterCSV::new(), 
-  # but the instance will be cached and returned for all future calls to this 
-  # method for the same +data+ object (tested by Object#object_id()) with the
-  # same +options+.
-  # 
-  # If a block is given, the instance is passed to the block and the return
-  # value becomes the return value of the block.
-  # 
-  def self.instance(data = $stdout, options = Hash.new)
-    # create a _signature_ for this method call, data object and options
-    sig = [data.object_id] +
-          options.values_at(*DEFAULT_OPTIONS.keys.sort_by { |sym| sym.to_s })
-    
-    # fetch or create the instance for this signature
-    @@instances ||= Hash.new
-    instance    =   (@@instances[sig] ||= new(data, options))
-
-    if block_given?
-      yield instance  # run block, if given, returning result
-    else
-      instance        # or return the instance
-    end
-  end
-  
-  # 
-  # This method is the reading counterpart to FasterCSV::dump().  See that
-  # method for a detailed description of the process.
-  # 
-  # You can customize loading by adding a class method called csv_load() which 
-  # will be passed a Hash of meta information, an Array of headers, and an Array
-  # of fields for the object the method is expected to return.
-  # 
-  # Remember that all fields will be Strings after this load.  If you need
-  # something else, use +options+ to setup converters or provide a custom
-  # csv_load() implementation.
-  # 
-  def self.load(io_or_str, options = Hash.new)
-    csv = FasterCSV.new(io_or_str, options)
-    
-    # load meta information
-    meta = Hash[*csv.shift]
-    cls  = meta["class"].split("::").inject(Object) do |c, const|
-      c.const_get(const)
-    end
-    
-    # load headers
-    headers = csv.shift
-    
-    # unserialize each object stored in the file
-    results = csv.inject(Array.new) do |all, row|
-      begin
-        obj = cls.csv_load(meta, headers, row)
-      rescue NoMethodError
-        obj = cls.allocate
-        headers.zip(row) do |name, value|
-          if name[0] == ?@
-            obj.instance_variable_set(name, value)
-          else
-            obj.send(name, value)
-          end
-        end
-      end
-      all << obj
-    end
-    
-    csv.close unless io_or_str.is_a? String
-    
-    results
-  end
-  
-  # 
-  # :call-seq:
-  #   open( filename, mode="rb", options = Hash.new ) { |faster_csv| ... }
-  #   open( filename, mode="rb", options = Hash.new )
-  # 
-  # This method opens an IO object, and wraps that with FasterCSV.  This is
-  # intended as the primary interface for writing a CSV file.
-  # 
-  # You may pass any +args+ Ruby's open() understands followed by an optional
-  # Hash containing any +options+ FasterCSV::new() understands.
-  # 
-  # This method works like Ruby's open() call, in that it will pass a FasterCSV
-  # object to a provided block and close it when the block termminates, or it
-  # will return the FasterCSV object when no block is provided.  (*Note*: This
-  # is different from the standard CSV library which passes rows to the block.  
-  # Use FasterCSV::foreach() for that behavior.)
-  # 
-  # An opened FasterCSV object will delegate to many IO methods, for 
-  # convenience.  You may call:
-  # 
-  # * binmode()
-  # * close()
-  # * close_read()
-  # * close_write()
-  # * closed?()
-  # * eof()
-  # * eof?()
-  # * fcntl()
-  # * fileno()
-  # * flush()
-  # * fsync()
-  # * ioctl()
-  # * isatty()
-  # * pid()
-  # * pos()
-  # * reopen()
-  # * seek()
-  # * stat()
-  # * sync()
-  # * sync=()
-  # * tell()
-  # * to_i()
-  # * to_io()
-  # * tty?()
-  # 
-  def self.open(*args)
-    # find the +options+ Hash
-    options = if args.last.is_a? Hash then args.pop else Hash.new end
-    # default to a binary open mode
-    args << "rb" if args.size == 1
-    # wrap a File opened with the remaining +args+
-    csv     = new(File.open(*args), options)
-    
-    # handle blocks like Ruby's open(), not like the CSV library
-    if block_given?
-      begin
-        yield csv
-      ensure
-        csv.close
-      end
-    else
-      csv
-    end
-  end
-  
-  # 
-  # :call-seq:
-  #   parse( str, options = Hash.new ) { |row| ... }
-  #   parse( str, options = Hash.new )
-  # 
-  # This method can be used to easily parse CSV out of a String.  You may either
-  # provide a +block+ which will be called with each row of the String in turn,
-  # or just use the returned Array of Arrays (when no +block+ is given).
-  # 
-  # You pass your +str+ to read from, and an optional +options+ Hash containing
-  # anything FasterCSV::new() understands.
-  # 
-  def self.parse(*args, &block)
-    csv = new(*args)
-    if block.nil?  # slurp contents, if no block is given
-      begin
-        csv.read
-      ensure
-        csv.close
-      end
-    else           # or pass each row to a provided block
-      csv.each(&block)
-    end
-  end
-  
-  # 
-  # This method is a shortcut for converting a single line of a CSV String into 
-  # a into an Array.  Note that if +line+ contains multiple rows, anything 
-  # beyond the first row is ignored.
-  # 
-  # The +options+ parameter can be anthing FasterCSV::new() understands.
-  # 
-  def self.parse_line(line, options = Hash.new)
-    new(line, options).shift
-  end
-  
-  # 
-  # Use to slurp a CSV file into an Array of Arrays.  Pass the +path+ to the 
-  # file and any +options+ FasterCSV::new() understands.
-  # 
-  def self.read(path, options = Hash.new)
-    open(path, "rb", options) { |csv| csv.read }
-  end
-  
-  # Alias for FasterCSV::read().
-  def self.readlines(*args)
-    read(*args)
-  end
-  
-  # 
-  # A shortcut for:
-  # 
-  #   FasterCSV.read( path, { :headers           => true,
-  #                           :converters        => :numeric,
-  #                           :header_converters => :symbol }.merge(options) )
-  # 
-  def self.table(path, options = Hash.new)
-    read( path, { :headers           => true,
-                  :converters        => :numeric,
-                  :header_converters => :symbol }.merge(options) )
-  end
-  
-  # 
-  # This constructor will wrap either a String or IO object passed in +data+ for
-  # reading and/or writing.  In addition to the FasterCSV instance methods, 
-  # several IO methods are delegated.  (See FasterCSV::open() for a complete 
-  # list.)  If you pass a String for +data+, you can later retrieve it (after
-  # writing to it, for example) with FasterCSV.string().
-  # 
-  # Note that a wrapped String will be positioned at at the beginning (for 
-  # reading).  If you want it at the end (for writing), use 
-  # FasterCSV::generate().  If you want any other positioning, pass a preset 
-  # StringIO object instead.
-  # 
-  # You may set any reading and/or writing preferences in the +options+ Hash.  
-  # Available options are:
-  # 
-  # <b><tt>:col_sep</tt></b>::            The String placed between each field.
-  # <b><tt>:row_sep</tt></b>::            The String appended to the end of each
-  #                                       row.  This can be set to the special
-  #                                       <tt>:auto</tt> setting, which requests
-  #                                       that FasterCSV automatically discover
-  #                                       this from the data.  Auto-discovery
-  #                                       reads ahead in the data looking for
-  #                                       the next <tt>"\r\n"</tt>,
-  #                                       <tt>"\n"</tt>, or <tt>"\r"</tt>
-  #                                       sequence.  A sequence will be selected
-  #                                       even if it occurs in a quoted field,
-  #                                       assuming that you would have the same
-  #                                       line endings there.  If none of those
-  #                                       sequences is found, +data+ is
-  #                                       <tt>ARGF</tt>, <tt>STDIN</tt>,
-  #                                       <tt>STDOUT</tt>, or <tt>STDERR</tt>,
-  #                                       or the stream is only available for
-  #                                       output, the default
-  #                                       <tt>$INPUT_RECORD_SEPARATOR</tt>
-  #                                       (<tt>$/</tt>) is used.  Obviously,
-  #                                       discovery takes a little time.  Set
-  #                                       manually if speed is important.  Also
-  #                                       note that IO objects should be opened
-  #                                       in binary mode on Windows if this
-  #                                       feature will be used as the
-  #                                       line-ending translation can cause
-  #                                       problems with resetting the document
-  #                                       position to where it was before the
-  #                                       read ahead.
-  # <b><tt>:quote_char</tt></b>::         The character used to quote fields.
-  #                                       This has to be a single character
-  #                                       String.  This is useful for
-  #                                       application that incorrectly use
-  #                                       <tt>'</tt> as the quote character
-  #                                       instead of the correct <tt>"</tt>.
-  #                                       FasterCSV will always consider a
-  #                                       double sequence this character to be
-  #                                       an escaped quote.
-  # <b><tt>:encoding</tt></b>::           The encoding to use when parsing the
-  #                                       file. Defaults to your <tt>$KDOCE</tt>
-  #                                       setting. Valid values: <tt>`nâ€™</tt> or
-  #                                       <tt>`Nâ€™</tt> for none, <tt>`eâ€™</tt> or
-  #                                       <tt>`Eâ€™</tt> for EUC, <tt>`sâ€™</tt> or
-  #                                       <tt>`Sâ€™</tt> for SJIS, and
-  #                                       <tt>`uâ€™</tt> or <tt>`Uâ€™</tt> for UTF-8
-  #                                       (see Regexp.new()).
-  # <b><tt>:field_size_limit</tt></b>::   This is a maximum size FasterCSV will
-  #                                       read ahead looking for the closing
-  #                                       quote for a field.  (In truth, it
-  #                                       reads to the first line ending beyond
-  #                                       this size.)  If a quote cannot be
-  #                                       found within the limit FasterCSV will
-  #                                       raise a MalformedCSVError, assuming
-  #                                       the data is faulty.  You can use this
-  #                                       limit to prevent what are effectively
-  #                                       DoS attacks on the parser.  However,
-  #                                       this limit can cause a legitimate
-  #                                       parse to fail and thus is set to
-  #                                       +nil+, or off, by default.
-  # <b><tt>:converters</tt></b>::         An Array of names from the Converters
-  #                                       Hash and/or lambdas that handle custom
-  #                                       conversion.  A single converter
-  #                                       doesn't have to be in an Array.
-  # <b><tt>:unconverted_fields</tt></b>:: If set to +true+, an
-  #                                       unconverted_fields() method will be
-  #                                       added to all returned rows (Array or
-  #                                       FasterCSV::Row) that will return the
-  #                                       fields as they were before convertion.
-  #                                       Note that <tt>:headers</tt> supplied
-  #                                       by Array or String were not fields of
-  #                                       the document and thus will have an
-  #                                       empty Array attached.
-  # <b><tt>:headers</tt></b>::            If set to <tt>:first_row</tt> or 
-  #                                       +true+, the initial row of the CSV
-  #                                       file will be treated as a row of
-  #                                       headers.  If set to an Array, the
-  #                                       contents will be used as the headers.
-  #                                       If set to a String, the String is run
-  #                                       through a call of
-  #                                       FasterCSV::parse_line() with the same
-  #                                       <tt>:col_sep</tt>, <tt>:row_sep</tt>,
-  #                                       and <tt>:quote_char</tt> as this
-  #                                       instance to produce an Array of
-  #                                       headers.  This setting causes
-  #                                       FasterCSV.shift() to return rows as
-  #                                       FasterCSV::Row objects instead of
-  #                                       Arrays and FasterCSV.read() to return
-  #                                       FasterCSV::Table objects instead of
-  #                                       an Array of Arrays.
-  # <b><tt>:return_headers</tt></b>::     When +false+, header rows are silently
-  #                                       swallowed.  If set to +true+, header
-  #                                       rows are returned in a FasterCSV::Row
-  #                                       object with identical headers and
-  #                                       fields (save that the fields do not go
-  #                                       through the converters).
-  # <b><tt>:write_headers</tt></b>::      When +true+ and <tt>:headers</tt> is
-  #                                       set, a header row will be added to the
-  #                                       output.
-  # <b><tt>:header_converters</tt></b>::  Identical in functionality to
-  #                                       <tt>:converters</tt> save that the
-  #                                       conversions are only made to header
-  #                                       rows.
-  # <b><tt>:skip_blanks</tt></b>::        When set to a +true+ value, FasterCSV
-  #                                       will skip over any rows with no
-  #                                       content.
-  # <b><tt>:force_quotes</tt></b>::       When set to a +true+ value, FasterCSV
-  #                                       will quote all CSV fields it creates.
-  # 
-  # See FasterCSV::DEFAULT_OPTIONS for the default settings.
-  # 
-  # Options cannot be overriden in the instance methods for performance reasons,
-  # so be sure to set what you want here.
-  # 
-  def initialize(data, options = Hash.new)
-    # build the options for this read/write
-    options = DEFAULT_OPTIONS.merge(options)
-    
-    # create the IO object we will read from
-    @io = if data.is_a? String then StringIO.new(data) else data end
-    
-    init_separators(options)
-    init_parsers(options)
-    init_converters(options)
-    init_headers(options)
-    
-    unless options.empty?
-      raise ArgumentError, "Unknown options:  #{options.keys.join(', ')}."
-    end
-    
-    # track our own lineno since IO gets confused about line-ends is CSV fields
-    @lineno = 0
-  end
-  
-  # 
-  # The line number of the last row read from this file.  Fields with nested 
-  # line-end characters will not affect this count.
-  # 
-  attr_reader :lineno
-  
-  ### IO and StringIO Delegation ###
-  
-  extend Forwardable
-  def_delegators :@io, :binmode, :close, :close_read, :close_write, :closed?,
-                       :eof, :eof?, :fcntl, :fileno, :flush, :fsync, :ioctl,
-                       :isatty, :pid, :pos, :reopen, :seek, :stat, :string,
-                       :sync, :sync=, :tell, :to_i, :to_io, :tty?
-  
-  # Rewinds the underlying IO object and resets FasterCSV's lineno() counter.
-  def rewind
-    @headers = nil
-    @lineno  = 0
-    
-    @io.rewind
-  end
-
-  ### End Delegation ###
-  
-  # 
-  # The primary write method for wrapped Strings and IOs, +row+ (an Array or
-  # FasterCSV::Row) is converted to CSV and appended to the data source.  When a
-  # FasterCSV::Row is passed, only the row's fields() are appended to the
-  # output.
-  # 
-  # The data source must be open for writing.
-  # 
-  def <<(row)
-    # make sure headers have been assigned
-    if header_row? and [Array, String].include? @use_headers.class
-      parse_headers  # won't read data for Array or String
-      self << @headers if @write_headers
-    end
-    
-    # Handle FasterCSV::Row objects and Hashes
-    row = case row
-          when self.class::Row then row.fields
-          when Hash            then @headers.map { |header| row[header] }
-          else                      row
-          end
-
-    @headers =  row if header_row?
-    @lineno  += 1
-
-    @io << row.map(&@quote).join(@col_sep) + @row_sep  # quote and separate
-    
-    self  # for chaining
-  end
-  alias_method :add_row, :<<
-  alias_method :puts,    :<<
-  
-  # 
-  # :call-seq:
-  #   convert( name )
-  #   convert { |field| ... }
-  #   convert { |field, field_info| ... }
-  # 
-  # You can use this method to install a FasterCSV::Converters built-in, or 
-  # provide a block that handles a custom conversion.
-  # 
-  # If you provide a block that takes one argument, it will be passed the field
-  # and is expected to return the converted value or the field itself.  If your
-  # block takes two arguments, it will also be passed a FieldInfo Struct, 
-  # containing details about the field.  Again, the block should return a 
-  # converted field or the field itself.
-  # 
-  def convert(name = nil, &converter)
-    add_converter(:converters, self.class::Converters, name, &converter)
-  end
-
-  # 
-  # :call-seq:
-  #   header_convert( name )
-  #   header_convert { |field| ... }
-  #   header_convert { |field, field_info| ... }
-  # 
-  # Identical to FasterCSV.convert(), but for header rows.
-  # 
-  # Note that this method must be called before header rows are read to have any
-  # effect.
-  # 
-  def header_convert(name = nil, &converter)
-    add_converter( :header_converters,
-                   self.class::HeaderConverters,
-                   name,
-                   &converter )
-  end
-  
-  include Enumerable
-  
-  # 
-  # Yields each row of the data source in turn.
-  # 
-  # Support for Enumerable.
-  # 
-  # The data source must be open for reading.
-  # 
-  def each
-    while row = shift
-      yield row
-    end
-  end
-  
-  # 
-  # Slurps the remaining rows and returns an Array of Arrays.
-  # 
-  # The data source must be open for reading.
-  # 
-  def read
-    rows = to_a
-    if @use_headers
-      Table.new(rows)
-    else
-      rows
-    end
-  end
-  alias_method :readlines, :read
-  
-  # Returns +true+ if the next row read will be a header row.
-  def header_row?
-    @use_headers and @headers.nil?
-  end
-  
-  # 
-  # The primary read method for wrapped Strings and IOs, a single row is pulled
-  # from the data source, parsed and returned as an Array of fields (if header
-  # rows are not used) or a FasterCSV::Row (when header rows are used).
-  # 
-  # The data source must be open for reading.
-  # 
-  def shift
-    #########################################################################
-    ### This method is purposefully kept a bit long as simple conditional ###
-    ### checks are faster than numerous (expensive) method calls.         ###
-    #########################################################################
-    
-    # handle headers not based on document content
-    if header_row? and @return_headers and
-       [Array, String].include? @use_headers.class
-      if @unconverted_fields
-        return add_unconverted_fields(parse_headers, Array.new)
-      else
-        return parse_headers
-      end
-    end
-    
-    # begin with a blank line, so we can always add to it
-    line = String.new
-
-    # 
-    # it can take multiple calls to <tt>@io.gets()</tt> to get a full line,
-    # because of \r and/or \n characters embedded in quoted fields
-    # 
-    loop do
-      # add another read to the line
-      begin
-        line  += @io.gets(@row_sep)
-      rescue
-        return nil
-      end
-      # copy the line so we can chop it up in parsing
-      parse =  line.dup
-      parse.sub!(@parsers[:line_end], "")
-      
-      # 
-      # I believe a blank line should be an <tt>Array.new</tt>, not 
-      # CSV's <tt>[nil]</tt>
-      # 
-      if parse.empty?
-        @lineno += 1
-        if @skip_blanks
-          line = ""
-          next
-        elsif @unconverted_fields
-          return add_unconverted_fields(Array.new, Array.new)
-        elsif @use_headers
-          return FasterCSV::Row.new(Array.new, Array.new)
-        else
-          return Array.new
-        end
-      end
-
-      # parse the fields with a mix of String#split and regular expressions
-      csv           = Array.new
-      current_field = String.new
-      field_quotes  = 0
-      parse.split(@col_sep, -1).each do |match|
-        if current_field.empty? && match.count(@quote_and_newlines).zero?
-          csv           << (match.empty? ? nil : match)
-        elsif(current_field.empty? ? match[0] : current_field[0]) == @quote_char[0]
-          current_field << match
-          field_quotes += match.count(@quote_char)
-          if field_quotes % 2 == 0
-            in_quotes = current_field[@parsers[:quoted_field], 1]
-            raise MalformedCSVError unless in_quotes
-            current_field = in_quotes
-            current_field.gsub!(@quote_char * 2, @quote_char) # unescape contents
-            csv           << current_field
-            current_field =  String.new
-            field_quotes  =  0
-          else # we found a quoted field that spans multiple lines
-            current_field << @col_sep
-          end
-        elsif match.count("\r\n").zero?
-          raise MalformedCSVError, "Illegal quoting on line #{lineno + 1}."
-        else
-          raise MalformedCSVError, "Unquoted fields do not allow " +
-                                   "\\r or \\n (line #{lineno + 1})."
-        end
-      end
-
-      # if parse is empty?(), we found all the fields on the line...
-      if field_quotes % 2 == 0
-        @lineno += 1
-
-        # save fields unconverted fields, if needed...
-        unconverted = csv.dup if @unconverted_fields
-
-        # convert fields, if needed...
-        csv = convert_fields(csv) unless @use_headers or @converters.empty?
-        # parse out header rows and handle FasterCSV::Row conversions...
-        csv = parse_headers(csv)  if     @use_headers
-
-        # inject unconverted fields and accessor, if requested...
-        if @unconverted_fields and not csv.respond_to? :unconverted_fields
-          add_unconverted_fields(csv, unconverted)
-        end
-
-        # return the results
-        break csv
-      end
-      # if we're not empty?() but at eof?(), a quoted field wasn't closed...
-      if @io.eof?
-        raise MalformedCSVError, "Unclosed quoted field on line #{lineno + 1}."
-      elsif @field_size_limit and current_field.size >= @field_size_limit
-        raise MalformedCSVError, "Field size exceeded on line #{lineno + 1}."
-      end
-      # otherwise, we need to loop and pull some more data to complete the row
-    end
-  end
-  alias_method :gets,     :shift
-  alias_method :readline, :shift
-  
-  # Returns a simplified description of the key FasterCSV attributes.
-  def inspect
-    str = "<##{self.class} io_type:"
-    # show type of wrapped IO
-    if    @io == $stdout then str << "$stdout"
-    elsif @io == $stdin  then str << "$stdin"
-    elsif @io == $stderr then str << "$stderr"
-    else                      str << @io.class.to_s
-    end
-    # show IO.path(), if available
-    if @io.respond_to?(:path) and (p = @io.path)
-      str << " io_path:#{p.inspect}"
-    end
-    # show other attributes
-    %w[ lineno     col_sep     row_sep
-        quote_char skip_blanks encoding ].each do |attr_name|
-      if a = instance_variable_get("@#{attr_name}")
-        str << " #{attr_name}:#{a.inspect}"
-      end
-    end
-    if @use_headers
-      str << " headers:#{(@headers || true).inspect}"
-    end
-    str << ">"
-  end
-  
-  private
-  
-  # 
-  # Stores the indicated separators for later use.
-  # 
-  # If auto-discovery was requested for <tt>@row_sep</tt>, this method will read
-  # ahead in the <tt>@io</tt> and try to find one.  +ARGF+, +STDIN+, +STDOUT+,
-  # +STDERR+ and any stream open for output only with a default
-  # <tt>@row_sep</tt> of <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>).
-  # 
-  # This method also establishes the quoting rules used for CSV output.
-  # 
-  def init_separators(options)
-    # store the selected separators
-    @col_sep            = options.delete(:col_sep)
-    @row_sep            = options.delete(:row_sep)
-    @quote_char         = options.delete(:quote_char)
-    @quote_and_newlines = "#{@quote_char}\r\n"
-
-    if @quote_char.length != 1
-      raise ArgumentError, ":quote_char has to be a single character String"
-    end
-    
-    # automatically discover row separator when requested
-    if @row_sep == :auto
-      if [ARGF, STDIN, STDOUT, STDERR].include?(@io) or
-        (defined?(Zlib) and @io.class == Zlib::GzipWriter)
-        @row_sep = $INPUT_RECORD_SEPARATOR
-      else
-        begin
-          saved_pos = @io.pos  # remember where we were
-          while @row_sep == :auto
-            # 
-            # if we run out of data, it's probably a single line 
-            # (use a sensible default)
-            # 
-            if @io.eof?
-              @row_sep = $INPUT_RECORD_SEPARATOR
-              break
-            end
-      
-            # read ahead a bit
-            sample =  @io.read(1024)
-            sample += @io.read(1) if sample[-1..-1] == "\r" and not @io.eof?
-      
-            # try to find a standard separator
-            if sample =~ /\r\n?|\n/
-              @row_sep = $&
-              break
-            end
-          end
-          # tricky seek() clone to work around GzipReader's lack of seek()
-          @io.rewind
-          # reset back to the remembered position
-          while saved_pos > 1024  # avoid loading a lot of data into memory
-            @io.read(1024)
-            saved_pos -= 1024
-          end
-          @io.read(saved_pos) if saved_pos.nonzero?
-        rescue IOError  # stream not opened for reading
-          @row_sep = $INPUT_RECORD_SEPARATOR
-        end
-      end
-    end
-    
-    # establish quoting rules
-    do_quote = lambda do |field|
-      @quote_char                                      +
-      String(field).gsub(@quote_char, @quote_char * 2) +
-      @quote_char
-    end
-    @quote = if options.delete(:force_quotes)
-      do_quote
-    else
-      lambda do |field|
-        if field.nil?  # represent +nil+ fields as empty unquoted fields
-          ""
-        else
-          field = String(field)  # Stringify fields
-          # represent empty fields as empty quoted fields
-          if field.empty? or
-             field.count("\r\n#{@col_sep}#{@quote_char}").nonzero?
-            do_quote.call(field)
-          else
-            field  # unquoted field
-          end
-        end
-      end
-    end
-  end
-  
-  # Pre-compiles parsers and stores them by name for access during reads.
-  def init_parsers(options)
-    # store the parser behaviors
-    @skip_blanks      = options.delete(:skip_blanks)
-    @encoding         = options.delete(:encoding)  # nil will use $KCODE
-    @field_size_limit = options.delete(:field_size_limit)
-
-    # prebuild Regexps for faster parsing
-    esc_col_sep = Regexp.escape(@col_sep)
-    esc_row_sep = Regexp.escape(@row_sep)
-    esc_quote   = Regexp.escape(@quote_char)
-    @parsers = {
-      :any_field      => Regexp.new( "[^#{esc_col_sep}]+",
-                                     Regexp::MULTILINE,
-                                     @encoding ),
-      :quoted_field   => Regexp.new( "^#{esc_quote}(.*)#{esc_quote}$",
-                                     Regexp::MULTILINE,
-                                     @encoding ),
-      # safer than chomp!()
-      :line_end       => Regexp.new("#{esc_row_sep}\\z", nil, @encoding)
-    }
-  end
-  
-  # 
-  # Loads any converters requested during construction.
-  # 
-  # If +field_name+ is set <tt>:converters</tt> (the default) field converters
-  # are set.  When +field_name+ is <tt>:header_converters</tt> header converters
-  # are added instead.
-  # 
-  # The <tt>:unconverted_fields</tt> option is also actived for 
-  # <tt>:converters</tt> calls, if requested.
-  # 
-  def init_converters(options, field_name = :converters)
-    if field_name == :converters
-      @unconverted_fields = options.delete(:unconverted_fields)
-    end
-
-    instance_variable_set("@#{field_name}", Array.new)
-    
-    # find the correct method to add the coverters
-    convert = method(field_name.to_s.sub(/ers\Z/, ""))
-    
-    # load converters
-    unless options[field_name].nil?
-      # allow a single converter not wrapped in an Array
-      unless options[field_name].is_a? Array
-        options[field_name] = [options[field_name]]
-      end
-      # load each converter...
-      options[field_name].each do |converter|
-        if converter.is_a? Proc  # custom code block
-          convert.call(&converter)
-        else                     # by name
-          convert.call(converter)
-        end
-      end
-    end
-    
-    options.delete(field_name)
-  end
-  
-  # Stores header row settings and loads header converters, if needed.
-  def init_headers(options)
-    @use_headers    = options.delete(:headers)
-    @return_headers = options.delete(:return_headers)
-    @write_headers  = options.delete(:write_headers)
-
-    # headers must be delayed until shift(), in case they need a row of content
-    @headers = nil
-    
-    init_converters(options, :header_converters)
-  end
-  
-  # 
-  # The actual work method for adding converters, used by both 
-  # FasterCSV.convert() and FasterCSV.header_convert().
-  # 
-  # This method requires the +var_name+ of the instance variable to place the
-  # converters in, the +const+ Hash to lookup named converters in, and the
-  # normal parameters of the FasterCSV.convert() and FasterCSV.header_convert()
-  # methods.
-  # 
-  def add_converter(var_name, const, name = nil, &converter)
-    if name.nil?  # custom converter
-      instance_variable_get("@#{var_name}") << converter
-    else          # named converter
-      combo = const[name]
-      case combo
-      when Array  # combo converter
-        combo.each do |converter_name|
-          add_converter(var_name, const, converter_name)
-        end
-      else        # individual named converter
-        instance_variable_get("@#{var_name}") << combo
-      end
-    end
-  end
-  
-  # 
-  # Processes +fields+ with <tt>@converters</tt>, or <tt>@header_converters</tt>
-  # if +headers+ is passed as +true+, returning the converted field set.  Any
-  # converter that changes the field into something other than a String halts
-  # the pipeline of conversion for that field.  This is primarily an efficiency
-  # shortcut.
-  # 
-  def convert_fields(fields, headers = false)
-    # see if we are converting headers or fields
-    converters = headers ? @header_converters : @converters
-    
-    fields.enum_for(:each_with_index).map do |field, index|  # map_with_index
-      converters.each do |converter|
-        field = if converter.arity == 1  # straight field converter
-          converter[field]
-        else                             # FieldInfo converter
-          header = @use_headers && !headers ? @headers[index] : nil
-          converter[field, FieldInfo.new(index, lineno, header)]
-        end
-        break unless field.is_a? String  # short-curcuit pipeline for speed
-      end
-      field  # return final state of each field, converted or original
-    end
-  end
-  
-  # 
-  # This methods is used to turn a finished +row+ into a FasterCSV::Row.  Header
-  # rows are also dealt with here, either by returning a FasterCSV::Row with
-  # identical headers and fields (save that the fields do not go through the
-  # converters) or by reading past them to return a field row. Headers are also
-  # saved in <tt>@headers</tt> for use in future rows.
-  # 
-  # When +nil+, +row+ is assumed to be a header row not based on an actual row
-  # of the stream.
-  # 
-  def parse_headers(row = nil)
-    if @headers.nil?                # header row
-      @headers = case @use_headers  # save headers
-                 # Array of headers
-                 when Array  then @use_headers
-                 # CSV header String
-                 when String
-                   self.class.parse_line( @use_headers,
-                                          :col_sep    => @col_sep,
-                                          :row_sep    => @row_sep,
-                                          :quote_char => @quote_char )
-                 # first row is headers
-                 else             row
-                 end
-      
-      # prepare converted and unconverted copies
-      row      = @headers                       if row.nil?
-      @headers = convert_fields(@headers, true)
-      
-      if @return_headers                                     # return headers
-        return FasterCSV::Row.new(@headers, row, true)
-      elsif not [Array, String].include? @use_headers.class  # skip to field row
-        return shift
-      end
-    end
-
-    FasterCSV::Row.new(@headers, convert_fields(row))  # field row
-  end
-  
-  # 
-  # Thiw methods injects an instance variable <tt>unconverted_fields</tt> into
-  # +row+ and an accessor method for it called unconverted_fields().  The
-  # variable is set to the contents of +fields+.
-  # 
-  def add_unconverted_fields(row, fields)
-    class << row
-      attr_reader :unconverted_fields
-    end
-    row.instance_eval { @unconverted_fields = fields }
-    row
-  end
-end
-
-# Another name for FasterCSV.
-FCSV = FasterCSV
-
-# Another name for FasterCSV::instance().
-def FasterCSV(*args, &block)
-  FasterCSV.instance(*args, &block)
-end
-
-# Another name for FCSV::instance().
-def FCSV(*args, &block)
-  FCSV.instance(*args, &block)
-end
-
-class Array
-  # Equivalent to <tt>FasterCSV::generate_line(self, options)</tt>.
-  def to_csv(options = Hash.new)
-    FasterCSV.generate_line(self, options)
-  end
-end
-
-class String
-  # Equivalent to <tt>FasterCSV::parse_line(self, options)</tt>.
-  def parse_csv(options = Hash.new)
-    FasterCSV.parse_line(self, options)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/e9/e9fb13e0f0d6d422082491d6e14bdb1d021bb202.svn-base
--- a/.svn/pristine/e9/e9fb13e0f0d6d422082491d6e14bdb1d021bb202.svn-base
+++ /dev/null
@@ -1,824 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class QueryTest < ActiveSupport::TestCase
-  fixtures :projects, :enabled_modules, :users, :members,
-           :member_roles, :roles, :trackers, :issue_statuses,
-           :issue_categories, :enumerations, :issues,
-           :watchers, :custom_fields, :custom_values, :versions,
-           :queries,
-           :projects_trackers
-
-  def test_custom_fields_for_all_projects_should_be_available_in_global_queries
-    query = Query.new(:project => nil, :name => '_')
-    assert query.available_filters.has_key?('cf_1')
-    assert !query.available_filters.has_key?('cf_3')
-  end
-
-  def test_system_shared_versions_should_be_available_in_global_queries
-    Version.find(2).update_attribute :sharing, 'system'
-    query = Query.new(:project => nil, :name => '_')
-    assert query.available_filters.has_key?('fixed_version_id')
-    assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'}
-  end
-
-  def test_project_filter_in_global_queries
-    query = Query.new(:project => nil, :name => '_')
-    project_filter = query.available_filters["project_id"]
-    assert_not_nil project_filter
-    project_ids = project_filter[:values].map{|p| p[1]}
-    assert project_ids.include?("1")  #public project
-    assert !project_ids.include?("2") #private project user cannot see
-  end
-
-  def find_issues_with_query(query)
-    Issue.find :all,
-      :include => [ :assigned_to, :status, :tracker, :project, :priority ],
-      :conditions => query.statement
-  end
-
-  def assert_find_issues_with_query_is_successful(query)
-    assert_nothing_raised do
-      find_issues_with_query(query)
-    end
-  end
-
-  def assert_query_statement_includes(query, condition)
-    assert query.statement.include?(condition), "Query statement condition not found in: #{query.statement}"
-  end
-  
-  def assert_query_result(expected, query)
-    assert_nothing_raised do
-      assert_equal expected.map(&:id).sort, query.issues.map(&:id).sort
-      assert_equal expected.size, query.issue_count
-    end
-  end
-
-  def test_query_should_allow_shared_versions_for_a_project_query
-    subproject_version = Version.find(4)
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
-
-    assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
-  end
-
-  def test_query_with_multiple_custom_fields
-    query = Query.find(1)
-    assert query.valid?
-    assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
-    issues = find_issues_with_query(query)
-    assert_equal 1, issues.length
-    assert_equal Issue.find(3), issues.first
-  end
-
-  def test_operator_none
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('fixed_version_id', '!*', [''])
-    query.add_filter('cf_1', '!*', [''])
-    assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
-    assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
-    find_issues_with_query(query)
-  end
-
-  def test_operator_none_for_integer
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('estimated_hours', '!*', [''])
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    assert issues.all? {|i| !i.estimated_hours}
-  end
-
-  def test_operator_none_for_date
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('start_date', '!*', [''])
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    assert issues.all? {|i| i.start_date.nil?}
-  end
-
-  def test_operator_all
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('fixed_version_id', '*', [''])
-    query.add_filter('cf_1', '*', [''])
-    assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
-    assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
-    find_issues_with_query(query)
-  end
-
-  def test_operator_all_for_date
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('start_date', '*', [''])
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    assert issues.all? {|i| i.start_date.present?}
-  end
-
-  def test_numeric_filter_should_not_accept_non_numeric_values
-    query = Query.new(:name => '_')
-    query.add_filter('estimated_hours', '=', ['a'])
-
-    assert query.has_filter?('estimated_hours')
-    assert !query.valid?
-  end
-
-  def test_operator_is_on_float
-    Issue.update_all("estimated_hours = 171.2", "id=2")
-
-    query = Query.new(:name => '_')
-    query.add_filter('estimated_hours', '=', ['171.20'])
-    issues = find_issues_with_query(query)
-    assert_equal 1, issues.size
-    assert_equal 2, issues.first.id
-  end
-
-  def test_operator_greater_than
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('done_ratio', '>=', ['40'])
-    assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
-    find_issues_with_query(query)
-  end
-
-  def test_operator_greater_than_a_float
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('estimated_hours', '>=', ['40.5'])
-    assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
-    find_issues_with_query(query)
-  end
-
-  def test_operator_greater_than_on_custom_field
-    f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter("cf_#{f.id}", '>=', ['40'])
-    assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) >= 40.0")
-    find_issues_with_query(query)
-  end
-
-  def test_operator_lesser_than
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('done_ratio', '<=', ['30'])
-    assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
-    find_issues_with_query(query)
-  end
-
-  def test_operator_lesser_than_on_custom_field
-    f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter("cf_#{f.id}", '<=', ['30'])
-    assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) <= 30.0")
-    find_issues_with_query(query)
-  end
-
-  def test_operator_between
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('done_ratio', '><', ['30', '40'])
-    assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
-    find_issues_with_query(query)
-  end
-
-  def test_operator_between_on_custom_field
-    f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter("cf_#{f.id}", '><', ['30', '40'])
-    assert_include "CAST(custom_values.value AS decimal(60,3)) BETWEEN 30.0 AND 40.0", query.statement
-    find_issues_with_query(query)
-  end
-
-  def test_date_filter_should_not_accept_non_date_values
-    query = Query.new(:name => '_')
-    query.add_filter('created_on', '=', ['a'])
-
-    assert query.has_filter?('created_on')
-    assert !query.valid?
-  end
-
-  def test_date_filter_should_not_accept_invalid_date_values
-    query = Query.new(:name => '_')
-    query.add_filter('created_on', '=', ['2011-01-34'])
-
-    assert query.has_filter?('created_on')
-    assert !query.valid?
-  end
-
-  def test_relative_date_filter_should_not_accept_non_integer_values
-    query = Query.new(:name => '_')
-    query.add_filter('created_on', '>t-', ['a'])
-
-    assert query.has_filter?('created_on')
-    assert !query.valid?
-  end
-
-  def test_operator_date_equals
-    query = Query.new(:name => '_')
-    query.add_filter('due_date', '=', ['2011-07-10'])
-    assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
-    find_issues_with_query(query)
-  end
-
-  def test_operator_date_lesser_than
-    query = Query.new(:name => '_')
-    query.add_filter('due_date', '<=', ['2011-07-10'])
-    assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
-    find_issues_with_query(query)
-  end
-
-  def test_operator_date_greater_than
-    query = Query.new(:name => '_')
-    query.add_filter('due_date', '>=', ['2011-07-10'])
-    assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
-    find_issues_with_query(query)
-  end
-
-  def test_operator_date_between
-    query = Query.new(:name => '_')
-    query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
-    assert_match /issues\.due_date > '2011-06-22 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
-    find_issues_with_query(query)
-  end
-
-  def test_operator_in_more_than
-    Issue.find(7).update_attribute(:due_date, (Date.today + 15))
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', '>t+', ['15'])
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
-  end
-
-  def test_operator_in_less_than
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', '<t+', ['15'])
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
-  end
-
-  def test_operator_less_than_ago
-    Issue.find(7).update_attribute(:due_date, (Date.today - 3))
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', '>t-', ['3'])
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
-  end
-
-  def test_operator_more_than_ago
-    Issue.find(7).update_attribute(:due_date, (Date.today - 10))
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', '<t-', ['10'])
-    assert query.statement.include?("#{Issue.table_name}.due_date <=")
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
-  end
-
-  def test_operator_in
-    Issue.find(7).update_attribute(:due_date, (Date.today + 2))
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', 't+', ['2'])
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
-  end
-
-  def test_operator_ago
-    Issue.find(7).update_attribute(:due_date, (Date.today - 3))
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', 't-', ['3'])
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
-  end
-
-  def test_operator_today
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', 't', [''])
-    issues = find_issues_with_query(query)
-    assert !issues.empty?
-    issues.each {|issue| assert_equal Date.today, issue.due_date}
-  end
-
-  def test_operator_this_week_on_date
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', 'w', [''])
-    find_issues_with_query(query)
-  end
-
-  def test_operator_this_week_on_datetime
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('created_on', 'w', [''])
-    find_issues_with_query(query)
-  end
-
-  def test_operator_contains
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('subject', '~', ['uNable'])
-    assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
-    result = find_issues_with_query(query)
-    assert result.empty?
-    result.each {|issue| assert issue.subject.downcase.include?('unable') }
-  end
-
-  def test_range_for_this_week_with_week_starting_on_monday
-    I18n.locale = :fr
-    assert_equal '1', I18n.t(:general_first_day_of_week)
-
-    Date.stubs(:today).returns(Date.parse('2011-04-29'))
-
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', 'w', [''])
-    assert query.statement.match(/issues\.due_date > '2011-04-24 23:59:59(\.9+)?' AND issues\.due_date <= '2011-05-01 23:59:59(\.9+)?/), "range not found in #{query.statement}"
-    I18n.locale = :en
-  end
-
-  def test_range_for_this_week_with_week_starting_on_sunday
-    I18n.locale = :en
-    assert_equal '7', I18n.t(:general_first_day_of_week)
-
-    Date.stubs(:today).returns(Date.parse('2011-04-29'))
-
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('due_date', 'w', [''])
-    assert query.statement.match(/issues\.due_date > '2011-04-23 23:59:59(\.9+)?' AND issues\.due_date <= '2011-04-30 23:59:59(\.9+)?/), "range not found in #{query.statement}"
-  end
-
-  def test_operator_does_not_contains
-    query = Query.new(:project => Project.find(1), :name => '_')
-    query.add_filter('subject', '!~', ['uNable'])
-    assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
-    find_issues_with_query(query)
-  end
-
-  def test_filter_assigned_to_me
-    user = User.find(2)
-    group = Group.find(10)
-    User.current = user
-    i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user)
-    i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group)
-    i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
-    group.users << user
-
-    query = Query.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
-    result = query.issues
-    assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id)
-
-    assert result.include?(i1)
-    assert result.include?(i2)
-    assert !result.include?(i3)
-  end
-
-  def test_filter_watched_issues
-    User.current = User.find(1)
-    query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
-    result = find_issues_with_query(query)
-    assert_not_nil result
-    assert !result.empty?
-    assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
-    User.current = nil
-  end
-
-  def test_filter_unwatched_issues
-    User.current = User.find(1)
-    query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
-    result = find_issues_with_query(query)
-    assert_not_nil result
-    assert !result.empty?
-    assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
-    User.current = nil
-  end
-
-  def test_statement_should_be_nil_with_no_filters
-    q = Query.new(:name => '_')
-    q.filters = {}
-
-    assert q.valid?
-    assert_nil q.statement
-  end
-
-  def test_default_columns
-    q = Query.new
-    assert !q.columns.empty?
-  end
-
-  def test_set_column_names
-    q = Query.new
-    q.column_names = ['tracker', :subject, '', 'unknonw_column']
-    assert_equal [:tracker, :subject], q.columns.collect {|c| c.name}
-    c = q.columns.first
-    assert q.has_column?(c)
-  end
-
-  def test_groupable_columns_should_include_custom_fields
-    q = Query.new
-    assert q.groupable_columns.detect {|c| c.is_a? QueryCustomFieldColumn}
-  end
-
-  def test_grouped_with_valid_column
-    q = Query.new(:group_by => 'status')
-    assert q.grouped?
-    assert_not_nil q.group_by_column
-    assert_equal :status, q.group_by_column.name
-    assert_not_nil q.group_by_statement
-    assert_equal 'status', q.group_by_statement
-  end
-
-  def test_grouped_with_invalid_column
-    q = Query.new(:group_by => 'foo')
-    assert !q.grouped?
-    assert_nil q.group_by_column
-    assert_nil q.group_by_statement
-  end
-  
-  def test_sortable_columns_should_sort_assignees_according_to_user_format_setting
-    with_settings :user_format => 'lastname_coma_firstname' do
-      q = Query.new
-      assert q.sortable_columns.has_key?('assigned_to')
-      assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to']
-    end
-  end
-  
-  def test_sortable_columns_should_sort_authors_according_to_user_format_setting
-    with_settings :user_format => 'lastname_coma_firstname' do
-      q = Query.new
-      assert q.sortable_columns.has_key?('author')
-      assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author']
-    end
-  end
-
-  def test_default_sort
-    q = Query.new
-    assert_equal [], q.sort_criteria
-  end
-
-  def test_set_sort_criteria_with_hash
-    q = Query.new
-    q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
-    assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
-  end
-
-  def test_set_sort_criteria_with_array
-    q = Query.new
-    q.sort_criteria = [['priority', 'desc'], 'tracker']
-    assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
-  end
-
-  def test_create_query_with_sort
-    q = Query.new(:name => 'Sorted')
-    q.sort_criteria = [['priority', 'desc'], 'tracker']
-    assert q.save
-    q.reload
-    assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
-  end
-
-  def test_sort_by_string_custom_field_asc
-    q = Query.new
-    c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
-    assert c
-    assert c.sortable
-    issues = Issue.find :all,
-                        :include => [ :assigned_to, :status, :tracker, :project, :priority ],
-                        :conditions => q.statement,
-                        :order => "#{c.sortable} ASC"
-    values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
-    assert !values.empty?
-    assert_equal values.sort, values
-  end
-
-  def test_sort_by_string_custom_field_desc
-    q = Query.new
-    c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
-    assert c
-    assert c.sortable
-    issues = Issue.find :all,
-                        :include => [ :assigned_to, :status, :tracker, :project, :priority ],
-                        :conditions => q.statement,
-                        :order => "#{c.sortable} DESC"
-    values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
-    assert !values.empty?
-    assert_equal values.sort.reverse, values
-  end
-
-  def test_sort_by_float_custom_field_asc
-    q = Query.new
-    c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
-    assert c
-    assert c.sortable
-    issues = Issue.find :all,
-                        :include => [ :assigned_to, :status, :tracker, :project, :priority ],
-                        :conditions => q.statement,
-                        :order => "#{c.sortable} ASC"
-    values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
-    assert !values.empty?
-    assert_equal values.sort, values
-  end
-
-  def test_invalid_query_should_raise_query_statement_invalid_error
-    q = Query.new
-    assert_raise Query::StatementInvalid do
-      q.issues(:conditions => "foo = 1")
-    end
-  end
-
-  def test_issue_count
-    q = Query.new(:name => '_')
-    issue_count = q.issue_count
-    assert_equal q.issues.size, issue_count
-  end
-
-  def test_issue_count_with_archived_issues
-    p = Project.generate!( :status => Project::STATUS_ARCHIVED )
-    i = Issue.generate!( :project => p, :tracker => p.trackers.first )
-    assert !i.visible?
-
-    test_issue_count
-  end
-
-  def test_issue_count_by_association_group
-    q = Query.new(:name => '_', :group_by => 'assigned_to')
-    count_by_group = q.issue_count_by_group
-    assert_kind_of Hash, count_by_group
-    assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
-    assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
-    assert count_by_group.has_key?(User.find(3))
-  end
-
-  def test_issue_count_by_list_custom_field_group
-    q = Query.new(:name => '_', :group_by => 'cf_1')
-    count_by_group = q.issue_count_by_group
-    assert_kind_of Hash, count_by_group
-    assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
-    assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
-    assert count_by_group.has_key?('MySQL')
-  end
-
-  def test_issue_count_by_date_custom_field_group
-    q = Query.new(:name => '_', :group_by => 'cf_8')
-    count_by_group = q.issue_count_by_group
-    assert_kind_of Hash, count_by_group
-    assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
-    assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
-  end
-
-  def test_label_for
-    q = Query.new
-    assert_equal 'assigned_to', q.label_for('assigned_to_id')
-  end
-
-  def test_editable_by
-    admin = User.find(1)
-    manager = User.find(2)
-    developer = User.find(3)
-
-    # Public query on project 1
-    q = Query.find(1)
-    assert q.editable_by?(admin)
-    assert q.editable_by?(manager)
-    assert !q.editable_by?(developer)
-
-    # Private query on project 1
-    q = Query.find(2)
-    assert q.editable_by?(admin)
-    assert !q.editable_by?(manager)
-    assert q.editable_by?(developer)
-
-    # Private query for all projects
-    q = Query.find(3)
-    assert q.editable_by?(admin)
-    assert !q.editable_by?(manager)
-    assert q.editable_by?(developer)
-
-    # Public query for all projects
-    q = Query.find(4)
-    assert q.editable_by?(admin)
-    assert !q.editable_by?(manager)
-    assert !q.editable_by?(developer)
-  end
-
-  def test_visible_scope
-    query_ids = Query.visible(User.anonymous).map(&:id)
-
-    assert query_ids.include?(1), 'public query on public project was not visible'
-    assert query_ids.include?(4), 'public query for all projects was not visible'
-    assert !query_ids.include?(2), 'private query on public project was visible'
-    assert !query_ids.include?(3), 'private query for all projects was visible'
-    assert !query_ids.include?(7), 'public query on private project was visible'
-  end
-
-  context "#available_filters" do
-    setup do
-      @query = Query.new(:name => "_")
-    end
-
-    should "include users of visible projects in cross-project view" do
-      users = @query.available_filters["assigned_to_id"]
-      assert_not_nil users
-      assert users[:values].map{|u|u[1]}.include?("3")
-    end
-
-    should "include visible projects in cross-project view" do
-      projects = @query.available_filters["project_id"]
-      assert_not_nil projects
-      assert projects[:values].map{|u|u[1]}.include?("1")
-    end
-
-    context "'member_of_group' filter" do
-      should "be present" do
-        assert @query.available_filters.keys.include?("member_of_group")
-      end
-
-      should "be an optional list" do
-        assert_equal :list_optional, @query.available_filters["member_of_group"][:type]
-      end
-
-      should "have a list of the groups as values" do
-        Group.destroy_all # No fixtures
-        group1 = Group.generate!.reload
-        group2 = Group.generate!.reload
-
-        expected_group_list = [
-                               [group1.name, group1.id.to_s],
-                               [group2.name, group2.id.to_s]
-                              ]
-        assert_equal expected_group_list.sort, @query.available_filters["member_of_group"][:values].sort
-      end
-
-    end
-
-    context "'assigned_to_role' filter" do
-      should "be present" do
-        assert @query.available_filters.keys.include?("assigned_to_role")
-      end
-
-      should "be an optional list" do
-        assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type]
-      end
-
-      should "have a list of the Roles as values" do
-        assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
-        assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
-        assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
-      end
-
-      should "not include the built in Roles as values" do
-        assert ! @query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
-        assert ! @query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
-      end
-
-    end
-
-  end
-
-  context "#statement" do
-    context "with 'member_of_group' filter" do
-      setup do
-        Group.destroy_all # No fixtures
-        @user_in_group = User.generate!
-        @second_user_in_group = User.generate!
-        @user_in_group2 = User.generate!
-        @user_not_in_group = User.generate!
-
-        @group = Group.generate!.reload
-        @group.users << @user_in_group
-        @group.users << @second_user_in_group
-
-        @group2 = Group.generate!.reload
-        @group2.users << @user_in_group2
-
-      end
-
-      should "search assigned to for users in the group" do
-        @query = Query.new(:name => '_')
-        @query.add_filter('member_of_group', '=', [@group.id.to_s])
-
-        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')"
-        assert_find_issues_with_query_is_successful @query
-      end
-
-      should "search not assigned to any group member (none)" do
-        @query = Query.new(:name => '_')
-        @query.add_filter('member_of_group', '!*', [''])
-
-        # Users not in a group
-        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')"
-        assert_find_issues_with_query_is_successful @query
-      end
-
-      should "search assigned to any group member (all)" do
-        @query = Query.new(:name => '_')
-        @query.add_filter('member_of_group', '*', [''])
-
-        # Only users in a group
-        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')"
-        assert_find_issues_with_query_is_successful @query
-      end
-
-      should "return an empty set with = empty group" do
-        @empty_group = Group.generate!
-        @query = Query.new(:name => '_')
-        @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
-
-        assert_equal [], find_issues_with_query(@query)
-      end
-
-      should "return issues with ! empty group" do
-        @empty_group = Group.generate!
-        @query = Query.new(:name => '_')
-        @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
-
-        assert_find_issues_with_query_is_successful @query
-      end
-    end
-
-    context "with 'assigned_to_role' filter" do
-      setup do
-        @manager_role = Role.find_by_name('Manager')
-        @developer_role = Role.find_by_name('Developer')
-
-        @project = Project.generate!
-        @manager = User.generate!
-        @developer = User.generate!
-        @boss = User.generate!
-        @guest = User.generate!
-        User.add_to_project(@manager, @project, @manager_role)
-        User.add_to_project(@developer, @project, @developer_role)
-        User.add_to_project(@boss, @project, [@manager_role, @developer_role])
-        
-        @issue1 = Issue.generate_for_project!(@project, :assigned_to_id => @manager.id)
-        @issue2 = Issue.generate_for_project!(@project, :assigned_to_id => @developer.id)
-        @issue3 = Issue.generate_for_project!(@project, :assigned_to_id => @boss.id)
-        @issue4 = Issue.generate_for_project!(@project, :assigned_to_id => @guest.id)
-        @issue5 = Issue.generate_for_project!(@project)
-      end
-
-      should "search assigned to for users with the Role" do
-        @query = Query.new(:name => '_', :project => @project)
-        @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
-
-        assert_query_result [@issue1, @issue3], @query
-      end
-
-      should "search assigned to for users with the Role on the issue project" do
-        other_project = Project.generate!
-        User.add_to_project(@developer, other_project, @manager_role)
-        
-        @query = Query.new(:name => '_', :project => @project)
-        @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
-
-        assert_query_result [@issue1, @issue3], @query
-      end
-
-      should "return an empty set with empty role" do
-        @empty_role = Role.generate!
-        @query = Query.new(:name => '_', :project => @project)
-        @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
-
-        assert_query_result [], @query
-      end
-
-      should "search assigned to for users without the Role" do
-        @query = Query.new(:name => '_', :project => @project)
-        @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s])
-
-        assert_query_result [@issue2, @issue4, @issue5], @query
-      end
-
-      should "search assigned to for users not assigned to any Role (none)" do
-        @query = Query.new(:name => '_', :project => @project)
-        @query.add_filter('assigned_to_role', '!*', [''])
-
-        assert_query_result [@issue4, @issue5], @query
-      end
-
-      should "search assigned to for users assigned to any Role (all)" do
-        @query = Query.new(:name => '_', :project => @project)
-        @query.add_filter('assigned_to_role', '*', [''])
-
-        assert_query_result [@issue1, @issue2, @issue3], @query
-      end
-
-      should "return issues with ! empty role" do
-        @empty_role = Role.generate!
-        @query = Query.new(:name => '_', :project => @project)
-        @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s])
-
-        assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query
-      end
-    end
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ea/ea1722961c125100f4532f404db336110a651ed6.svn-base
--- a/.svn/pristine/ea/ea1722961c125100f4532f404db336110a651ed6.svn-base
+++ /dev/null
@@ -1,9 +0,0 @@
-<h2><%= link_to l(:label_custom_field_plural), :controller => 'custom_fields', :action => 'index' %>
-  &#187; <%= link_to l(@custom_field.type_name), :controller => 'custom_fields', :action => 'index', :tab => @custom_field.class.name %>
-  &#187; <%= l(:label_custom_field_new) %></h2>
-
-<% labelled_tabular_form_for :custom_field, @custom_field, :url => { :action => "new" } do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-<%= hidden_field_tag 'type', @custom_field.type %>
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ea/ea2191a28669b9785530a0c4d38a5256d47b0fa8.svn-base
--- a/.svn/pristine/ea/ea2191a28669b9785530a0c4d38a5256d47b0fa8.svn-base
+++ /dev/null
@@ -1,51 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::TrackersTest < ActionController::IntegrationTest
-  fixtures :trackers
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "/trackers" do
-    context "GET" do
-
-      should "return trackers" do
-        get '/trackers.xml'
-
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-        assert_tag :tag => 'trackers',
-          :attributes => {:type => 'array'},
-          :child => {
-            :tag => 'tracker',
-            :child => {
-              :tag => 'id',
-              :content => '2',
-              :sibling => {
-                :tag => 'name',
-                :content => 'Feature request'
-              }
-            }
-          }
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ea/ea3b1965ef29d190187f41e90f8052120d63b5ba.svn-base
--- /dev/null
+++ b/.svn/pristine/ea/ea3b1965ef29d190187f41e90f8052120d63b5ba.svn-base
@@ -0,0 +1,260 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ProjectMembersInheritanceTest < ActiveSupport::TestCase
+  fixtures :roles, :users
+
+  def setup
+    @parent = Project.generate!
+    @member = Member.create!(:principal => User.find(2), :project => @parent, :role_ids => [1, 2])
+    assert_equal 2, @member.reload.roles.size
+  end
+
+  def test_project_created_with_inherit_members_disabled_should_not_inherit_members
+    assert_no_difference 'Member.count' do
+      project = Project.generate_with_parent!(@parent, :inherit_members => false)
+
+      assert_equal 0, project.memberships.count
+    end
+  end
+
+  def test_project_created_with_inherit_members_should_inherit_members
+    assert_difference 'Member.count', 1 do
+      project = Project.generate_with_parent!(@parent, :inherit_members => true)
+      project.reload
+
+      assert_equal 1, project.memberships.count
+      member = project.memberships.first
+      assert_equal @member.principal, member.principal
+      assert_equal @member.roles.sort, member.roles.sort
+    end
+  end
+
+  def test_turning_on_inherit_members_should_inherit_members
+    Project.generate_with_parent!(@parent, :inherit_members => false)
+
+    assert_difference 'Member.count', 1 do
+      project = Project.order('id desc').first
+      project.inherit_members = true
+      project.save!
+      project.reload
+
+      assert_equal 1, project.memberships.count
+      member = project.memberships.first
+      assert_equal @member.principal, member.principal
+      assert_equal @member.roles.sort, member.roles.sort
+    end
+  end
+
+  def test_turning_off_inherit_members_should_remove_inherited_members
+    Project.generate_with_parent!(@parent, :inherit_members => true)
+
+    assert_difference 'Member.count', -1 do
+      project = Project.order('id desc').first
+      project.inherit_members = false
+      project.save!
+      project.reload
+
+      assert_equal 0, project.memberships.count
+    end
+  end
+
+  def test_moving_a_root_project_under_a_parent_should_inherit_members
+    Project.generate!(:inherit_members => true)
+    project = Project.order('id desc').first
+
+    assert_difference 'Member.count', 1 do
+      project.set_parent!(@parent)
+      project.reload
+
+      assert_equal 1, project.memberships.count
+      member = project.memberships.first
+      assert_equal @member.principal, member.principal
+      assert_equal @member.roles.sort, member.roles.sort
+    end
+  end
+
+  def test_moving_a_subproject_as_root_should_loose_inherited_members
+    Project.generate_with_parent!(@parent, :inherit_members => true)
+    project = Project.order('id desc').first
+
+    assert_difference 'Member.count', -1 do
+      project.set_parent!(nil)
+      project.reload
+
+      assert_equal 0, project.memberships.count
+    end
+  end
+
+  def test_moving_a_subproject_to_another_parent_should_change_inherited_members
+    other_parent = Project.generate!
+    other_member = Member.create!(:principal => User.find(4), :project => other_parent, :role_ids => [3])
+
+    Project.generate_with_parent!(@parent, :inherit_members => true)
+    project = Project.order('id desc').first
+    project.set_parent!(other_parent.reload)
+    project.reload
+
+    assert_equal 1, project.memberships.count
+    member = project.memberships.first
+    assert_equal other_member.principal, member.principal
+    assert_equal other_member.roles.sort, member.roles.sort
+  end
+
+  def test_inheritance_should_propagate_to_subprojects
+    project = Project.generate_with_parent!(@parent, :inherit_members => false)
+    subproject = Project.generate_with_parent!(project, :inherit_members => true)
+    project.reload
+
+    assert_difference 'Member.count', 2 do
+      project.inherit_members = true
+      project.save
+      project.reload
+      subproject.reload
+
+      assert_equal 1, project.memberships.count
+      assert_equal 1, subproject.memberships.count
+      member = subproject.memberships.first
+      assert_equal @member.principal, member.principal
+      assert_equal @member.roles.sort, member.roles.sort
+    end
+  end
+
+  def test_inheritance_removal_should_propagate_to_subprojects
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+    subproject = Project.generate_with_parent!(project, :inherit_members => true)
+    project.reload
+
+    assert_difference 'Member.count', -2 do
+      project.inherit_members = false
+      project.save
+      project.reload
+      subproject.reload
+
+      assert_equal 0, project.memberships.count
+      assert_equal 0, subproject.memberships.count
+    end
+  end
+
+  def test_adding_a_member_should_propagate
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+
+    assert_difference 'Member.count', 2 do
+      member = Member.create!(:principal => User.find(4), :project => @parent, :role_ids => [1, 3])
+
+      inherited_member = project.memberships.order('id desc').first
+      assert_equal member.principal, inherited_member.principal
+      assert_equal member.roles.sort, inherited_member.roles.sort
+    end
+  end
+
+  def test_adding_a_member_should_not_propagate_if_child_does_not_inherit
+    project = Project.generate_with_parent!(@parent, :inherit_members => false)
+
+    assert_difference 'Member.count', 1 do
+      member = Member.create!(:principal => User.find(4), :project => @parent, :role_ids => [1, 3])
+
+      assert_nil project.reload.memberships.detect {|m| m.principal == member.principal}
+    end
+  end
+
+  def test_removing_a_member_should_propagate
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+
+    assert_difference 'Member.count', -2 do
+      @member.reload.destroy
+      project.reload
+
+      assert_equal 0, project.memberships.count
+    end
+  end
+
+  def test_adding_a_group_member_should_propagate_with_its_users
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+    group = Group.generate!
+    user = User.find(4)
+    group.users << user
+
+    assert_difference 'Member.count', 4 do
+      assert_difference 'MemberRole.count', 8 do
+        member = Member.create!(:principal => group, :project => @parent, :role_ids => [1, 3])
+        project.reload
+  
+        inherited_group_member = project.memberships.detect {|m| m.principal == group}
+        assert_not_nil inherited_group_member
+        assert_equal member.roles.sort, inherited_group_member.roles.sort
+  
+        inherited_user_member = project.memberships.detect {|m| m.principal == user}
+        assert_not_nil inherited_user_member
+        assert_equal member.roles.sort, inherited_user_member.roles.sort
+      end
+    end
+  end
+
+  def test_removing_a_group_member_should_propagate
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+    group = Group.generate!
+    user = User.find(4)
+    group.users << user
+    member = Member.create!(:principal => group, :project => @parent, :role_ids => [1, 3])
+
+    assert_difference 'Member.count', -4 do
+      assert_difference 'MemberRole.count', -8 do
+        member.destroy
+        project.reload
+  
+        inherited_group_member = project.memberships.detect {|m| m.principal == group}
+        assert_nil inherited_group_member
+  
+        inherited_user_member = project.memberships.detect {|m| m.principal == user}
+        assert_nil inherited_user_member
+      end
+    end
+  end
+
+  def test_adding_user_who_use_is_already_a_member_to_parent_project_should_merge_roles
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+    user = User.find(4)
+    Member.create!(:principal => user, :project => project, :role_ids => [1, 2])
+
+    assert_difference 'Member.count', 1 do
+      Member.create!(:principal => User.find(4), :project => @parent.reload, :role_ids => [1, 3])
+
+      member = project.reload.memberships.detect {|m| m.principal == user}
+      assert_not_nil member
+      assert_equal [1, 2, 3], member.roles.uniq.sort.map(&:id)
+    end
+  end
+
+  def test_turning_on_inheritance_with_user_who_is_already_a_member_should_merge_roles
+    project = Project.generate_with_parent!(@parent)
+    user = @member.user
+    Member.create!(:principal => user, :project => project, :role_ids => [1, 3])
+    project.reload
+
+    assert_no_difference 'Member.count' do
+      project.inherit_members = true
+      project.save!
+
+      member = project.reload.memberships.detect {|m| m.principal == user}
+      assert_not_nil member
+      assert_equal [1, 2, 3], member.roles.uniq.sort.map(&:id)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ea/ea992c47f8d2112ec52008294e35e2cd3e7c1b5f.svn-base
--- /dev/null
+++ b/.svn/pristine/ea/ea992c47f8d2112ec52008294e35e2cd3e7c1b5f.svn-base
@@ -0,0 +1,22 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class GroupCustomField < CustomField
+  def type_name
+    :label_group_plural
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ea/eab1cd7b12156ed469f5471880818f7528dfed63.svn-base
--- /dev/null
+++ b/.svn/pristine/ea/eab1cd7b12156ed469f5471880818f7528dfed63.svn-base
@@ -0,0 +1,118 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Utils
+    class << self
+      # Returns the relative root url of the application
+      def relative_url_root
+        ActionController::Base.respond_to?('relative_url_root') ?
+          ActionController::Base.relative_url_root.to_s :
+          ActionController::Base.config.relative_url_root.to_s
+      end
+
+      # Sets the relative root url of the application
+      def relative_url_root=(arg)
+        if ActionController::Base.respond_to?('relative_url_root=')
+          ActionController::Base.relative_url_root=arg
+        else
+          ActionController::Base.config.relative_url_root = arg
+        end
+      end
+
+      # Generates a n bytes random hex string
+      # Example:
+      #   random_hex(4) # => "89b8c729"
+      def random_hex(n)
+        SecureRandom.hex(n)
+      end
+    end
+
+    module Shell
+      def shell_quote(str)
+        if Redmine::Platform.mswin?
+          '"' + str.gsub(/"/, '\\"') + '"'
+        else
+          "'" + str.gsub(/'/, "'\"'\"'") + "'"
+        end
+      end
+    end
+
+    module DateCalculation
+      # Returns the number of working days between from and to
+      def working_days(from, to)
+        days = (to - from).to_i
+        if days > 0
+          weeks = days / 7
+          result = weeks * (7 - non_working_week_days.size)
+          days_left = days - weeks * 7
+          start_cwday = from.cwday
+          days_left.times do |i|
+            unless non_working_week_days.include?(((start_cwday + i - 1) % 7) + 1)
+              result += 1
+            end
+          end
+          result
+        else
+          0
+        end
+      end
+
+      # Adds working days to the given date
+      def add_working_days(date, working_days)
+        if working_days > 0
+          weeks = working_days / (7 - non_working_week_days.size)
+          result = weeks * 7
+          days_left = working_days - weeks * (7 - non_working_week_days.size)
+          cwday = date.cwday
+          while days_left > 0
+            cwday += 1
+            unless non_working_week_days.include?(((cwday - 1) % 7) + 1)
+              days_left -= 1
+            end
+            result += 1
+          end
+          next_working_date(date + result)
+        else
+          date
+        end
+      end
+
+      # Returns the date of the first day on or after the given date that is a working day
+      def next_working_date(date)
+        cwday = date.cwday
+        days = 0
+        while non_working_week_days.include?(((cwday + days - 1) % 7) + 1)
+          days += 1
+        end
+        date + days
+      end
+
+      # Returns the index of non working week days (1=monday, 7=sunday)
+      def non_working_week_days
+        @non_working_week_days ||= begin
+          days = Setting.non_working_week_days
+          if days.is_a?(Array) && days.size < 7
+            days.map(&:to_i)
+          else
+            []
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ea/ead12a798cd7fbc9307a2825275198bbad223275.svn-base
--- a/.svn/pristine/ea/ead12a798cd7fbc9307a2825275198bbad223275.svn-base
+++ /dev/null
@@ -1,130 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Acts
-    module Searchable
-      def self.included(base) 
-        base.extend ClassMethods
-      end 
-
-      module ClassMethods
-        # Options:
-        # * :columns - a column or an array of columns to search
-        # * :project_key - project foreign key (default to project_id)
-        # * :date_column - name of the datetime column (default to created_on)
-        # * :sort_order - name of the column used to sort results (default to :date_column or created_on)
-        # * :permission - permission required to search the model (default to :view_"objects")
-        def acts_as_searchable(options = {})
-          return if self.included_modules.include?(Redmine::Acts::Searchable::InstanceMethods)
-  
-          cattr_accessor :searchable_options
-          self.searchable_options = options
-
-          if searchable_options[:columns].nil?
-            raise 'No searchable column defined.'
-          elsif !searchable_options[:columns].is_a?(Array)
-            searchable_options[:columns] = [] << searchable_options[:columns]
-          end
-
-          searchable_options[:project_key] ||= "#{table_name}.project_id"
-          searchable_options[:date_column] ||= "#{table_name}.created_on"
-          searchable_options[:order_column] ||= searchable_options[:date_column]
-          
-          # Should we search custom fields on this model ?
-          searchable_options[:search_custom_fields] = !reflect_on_association(:custom_values).nil?
-          
-          send :include, Redmine::Acts::Searchable::InstanceMethods
-        end
-      end
-
-      module InstanceMethods
-        def self.included(base)
-          base.extend ClassMethods
-        end
-
-        module ClassMethods
-          # Searches the model for the given tokens
-          # projects argument can be either nil (will search all projects), a project or an array of projects
-          # Returns the results and the results count
-          def search(tokens, projects=nil, options={})
-            # TODO: make user an argument
-            user = User.current
-            tokens = [] << tokens unless tokens.is_a?(Array)
-            projects = [] << projects unless projects.nil? || projects.is_a?(Array)
-            
-            find_options = {:include => searchable_options[:include]}
-            find_options[:order] = "#{searchable_options[:order_column]} " + (options[:before] ? 'DESC' : 'ASC')
-            
-            limit_options = {}
-            limit_options[:limit] = options[:limit] if options[:limit]
-            if options[:offset]
-              limit_options[:conditions] = "(#{searchable_options[:date_column]} " + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
-            end
-            
-            columns = searchable_options[:columns]
-            columns = columns[0..0] if options[:titles_only]
-            
-            token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
-            
-            if !options[:titles_only] && searchable_options[:search_custom_fields]
-              searchable_custom_field_ids = CustomField.find(:all,
-                                                             :select => 'id',
-                                                             :conditions => { :type => "#{self.name}CustomField",
-                                                                              :searchable => true }).collect(&:id)
-              if searchable_custom_field_ids.any?
-                custom_field_sql = "#{table_name}.id IN (SELECT customized_id FROM #{CustomValue.table_name}" +
-                  " WHERE customized_type='#{self.name}' AND customized_id=#{table_name}.id AND LOWER(value) LIKE ?" +
-                  " AND #{CustomValue.table_name}.custom_field_id IN (#{searchable_custom_field_ids.join(',')}))"
-                token_clauses << custom_field_sql
-              end
-            end
-            
-            sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(options[:all_words] ? ' AND ' : ' OR ')
-            
-            find_options[:conditions] = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
-            
-            scope = self
-            project_conditions = []
-            if searchable_options.has_key?(:permission)
-              project_conditions << Project.allowed_to_condition(user, searchable_options[:permission] || :view_project)
-            elsif respond_to?(:visible)
-              scope = scope.visible(user)
-            else
-              ActiveSupport::Deprecation.warn "acts_as_searchable with implicit :permission option is deprecated. Add a visible scope to the #{self.name} model or use explicit :permission option."
-              project_conditions << Project.allowed_to_condition(user, "view_#{self.name.underscore.pluralize}".to_sym)
-            end
-            # TODO: use visible scope options instead
-            project_conditions << "#{searchable_options[:project_key]} IN (#{projects.collect(&:id).join(',')})" unless projects.nil?
-            project_conditions = project_conditions.empty? ? nil : project_conditions.join(' AND ')
-            
-            results = []
-            results_count = 0
-            
-            with_scope(:find => {:conditions => project_conditions}) do
-              with_scope(:find => find_options) do
-                results_count = scope.count(:all)
-                results = scope.find(:all, limit_options)
-              end
-            end
-            [results, results_count]
-          end
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ea/ead648f8695b39d393ec1029db862f15de288d0d.svn-base
--- a/.svn/pristine/ea/ead648f8695b39d393ec1029db862f15de288d0d.svn-base
+++ /dev/null
@@ -1,44 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class AutoCompletesControllerTest < ActionController::TestCase
-  fixtures :projects, :issues, :issue_statuses,
-           :enumerations, :users, :issue_categories,
-           :trackers,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :auth_sources,
-           :enabled_modules,
-           :workflows,
-           :journals, :journal_details
-
-  def test_issues_should_not_be_case_sensitive
-    get :issues, :project_id => 'ecookbook', :q => 'ReCiPe'
-    assert_response :success
-    assert_not_nil assigns(:issues)
-    assert assigns(:issues).detect {|issue| issue.subject.match /recipe/}
-  end
-
-  def test_issues_should_return_issue_with_given_id
-    get :issues, :project_id => 'subproject1', :q => '13'
-    assert_response :success
-    assert_not_nil assigns(:issues)
-    assert assigns(:issues).include?(Issue.find(13))
-  end
-
-  def test_auto_complete_with_scope_all_and_cross_project_relations
-    Setting.cross_project_issue_relations = '1'
-    get :issues, :project_id => 'ecookbook', :q => '13', :scope => 'all'
-    assert_response :success
-    assert_not_nil assigns(:issues)
-    assert assigns(:issues).include?(Issue.find(13))
-  end
-
-  def test_auto_complete_with_scope_all_without_cross_project_relations
-    Setting.cross_project_issue_relations = '0'
-    get :issues, :project_id => 'ecookbook', :q => '13', :scope => 'all'
-    assert_response :success
-    assert_equal [], assigns(:issues)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/eb/eb223097a73640bc8df209f3cf1b3d589efdedb1.svn-base
--- a/.svn/pristine/eb/eb223097a73640bc8df209f3cf1b3d589efdedb1.svn-base
+++ /dev/null
@@ -1,34 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class TimeEntryActivity < Enumeration
-  has_many :time_entries, :foreign_key => 'activity_id'
-
-  OptionName = :enumeration_activities
-
-  def option_name
-    OptionName
-  end
-
-  def objects_count
-    time_entries.count
-  end
-
-  def transfer_relations(to)
-    time_entries.update_all("activity_id = #{to.id}")
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/eb/eb69c2ca8a8f994d660e1f0618205141bdb05f6b.svn-base
--- a/.svn/pristine/eb/eb69c2ca8a8f994d660e1f0618205141bdb05f6b.svn-base
+++ /dev/null
@@ -1,33 +0,0 @@
-<div class="contextual">
-<%= link_to l(:label_tracker_new), new_tracker_path, :class => 'icon icon-add' %>
-</div>
-
-<h2><%=l(:label_tracker_plural)%></h2>
-
-<table class="list">
-  <thead><tr>
-  <th><%=l(:label_tracker)%></th>
-  <th></th>
-  <th><%=l(:button_sort)%></th>
-  <th></th>
-  </tr></thead>
-  <tbody>
-<% for tracker in @trackers %>
-  <tr class="<%= cycle("odd", "even") %>">
-  <td><%= link_to h(tracker.name), edit_tracker_path(tracker) %></td>
-  <td align="center"><% unless tracker.workflows.count > 0 %><span class="icon icon-warning"><%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), {:controller => 'workflows', :action => 'edit', :tracker_id => tracker} %>)</span><% end %></td>
-  <td align="center" style="width:15%;"><%= reorder_links('tracker', {:action => 'update', :id => tracker}, :put) %></td>
-  <td class="buttons">
-    <%= link_to(l(:button_delete), tracker_path(tracker),
-                                   :method => :delete,
-                                   :confirm => l(:text_are_you_sure),
-                                   :class => 'icon icon-del') %>
-  </td>
-  </tr>
-<% end %>
-  </tbody>
-</table>
-
-<p class="pagination"><%= pagination_links_full @tracker_pages %></p>
-
-<% html_title(l(:label_tracker_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/eb/eb6cb0f6889f62dec8dd9c85a7fb5ed905af22c8.svn-base
--- /dev/null
+++ b/.svn/pristine/eb/eb6cb0f6889f62dec8dd9c85a7fb5ed905af22c8.svn-base
@@ -0,0 +1,97 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../test_case', __FILE__)
+require 'tmpdir'
+
+class RedminePmTest::RepositoryGitTest < RedminePmTest::TestCase
+  fixtures :projects, :users, :members, :roles, :member_roles
+
+  GIT_BIN = Redmine::Configuration['scm_git_command'] || "git"
+
+  def test_anonymous_read_on_public_repo_with_permission_should_succeed
+    assert_success "ls-remote", git_url
+  end
+
+  def test_anonymous_read_on_public_repo_without_permission_should_fail
+    Role.anonymous.remove_permission! :browse_repository
+    assert_failure "ls-remote", git_url
+  end
+
+  def test_invalid_credentials_should_fail
+    Project.find(1).update_attribute :is_public, false
+    with_credentials "dlopper", "foo" do
+      assert_success "ls-remote", git_url
+    end
+    with_credentials "dlopper", "wrong" do
+      assert_failure "ls-remote", git_url
+    end
+  end
+
+  def test_clone
+    Dir.mktmpdir do |dir|
+      Dir.chdir(dir) do
+        assert_success "clone", git_url
+      end
+    end
+  end
+
+  def test_write_commands
+    Role.find(2).add_permission! :commit_access
+    filename = random_filename
+
+    Dir.mktmpdir do |dir|
+      assert_success "clone", git_url, dir
+      Dir.chdir(dir) do
+        f = File.new(File.join(dir, filename), "w")
+        f.write "test file content"
+        f.close
+
+        with_credentials "dlopper", "foo" do
+          assert_success "add", filename
+          assert_success "commit -a --message Committing_a_file"
+          assert_success "push", git_url, "--all"
+        end
+      end
+    end
+
+    Dir.mktmpdir do |dir|
+      assert_success "clone", git_url, dir
+      Dir.chdir(dir) do
+        assert File.exists?(File.join(dir, "#{filename}"))
+      end
+    end
+  end
+
+  protected
+
+  def execute(*args)
+    a = [GIT_BIN]
+    super a, *args
+  end
+
+  def git_url(path=nil)
+    host = ENV['REDMINE_TEST_DAV_SERVER'] || '127.0.0.1'
+    credentials = nil
+    if username && password
+      credentials = "#{username}:#{password}"
+    end
+    url = "http://#{credentials}@#{host}/git/ecookbook"
+    url << "/#{path}" if path
+    url
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/eb/eb93ec8172fa40acff3b40f1f28de22acda650a7.svn-base
--- a/.svn/pristine/eb/eb93ec8172fa40acff3b40f1f28de22acda650a7.svn-base
+++ /dev/null
@@ -1,20 +0,0 @@
-<h2><%=l(:label_project_new)%></h2>
-
-<% labelled_tabular_form_for @project, :url => { :action => "copy" } do |f| %>
-<%= render :partial => 'form', :locals => { :f => f } %>
-
-<fieldset class="box"><legend><%= l(:button_copy) %></legend>
-  <label class="block"><%= check_box_tag 'only[]', 'members', true %> <%= l(:label_member_plural) %> (<%= @source_project.members.count %>)</label>
-  <label class="block"><%= check_box_tag 'only[]', 'versions', true %> <%= l(:label_version_plural) %> (<%= @source_project.versions.count %>)</label>
-  <label class="block"><%= check_box_tag 'only[]', 'issue_categories', true %> <%= l(:label_issue_category_plural) %> (<%= @source_project.issue_categories.count %>)</label>
-  <label class="block"><%= check_box_tag 'only[]', 'issues', true %> <%= l(:label_issue_plural) %> (<%= @source_project.issues.count %>)</label>
-  <label class="block"><%= check_box_tag 'only[]', 'queries', true %> <%= l(:label_query_plural) %> (<%= @source_project.queries.count %>)</label>
-  <label class="block"><%= check_box_tag 'only[]', 'boards', true %> <%= l(:label_board_plural) %> (<%= @source_project.boards.count %>)</label>
-  <label class="block"><%= check_box_tag 'only[]', 'wiki', true %> <%= l(:label_wiki_page_plural) %> (<%= @source_project.wiki.nil? ? 0 : @source_project.wiki.pages.count %>)</label>
-  <%= hidden_field_tag 'only[]', '' %>
-  <br />
-  <label class="block"><%= check_box_tag 'notifications', 1, params[:notifications] %> <%= l(:label_project_copy_notifications) %></label>
-</fieldset>
-
-<%= submit_tag l(:button_copy) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/eb/eba575f0f35d5fa34b9a800fc6641ac537b6126c.svn-base
--- a/.svn/pristine/eb/eba575f0f35d5fa34b9a800fc6641ac537b6126c.svn-base
+++ /dev/null
@@ -1,31 +0,0 @@
-<div class="contextual">
-<%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
-</div>
-
-<%= render_timelog_breadcrumb %>
-
-<h2><%= l(:label_spent_time) %></h2>
-
-<% form_tag({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %>
-<%= render :partial => 'date_range' %>
-<% end %>
-
-<div class="total-hours">
-<p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
-</div>
-
-<% unless @entries.empty? %>
-<%= render :partial => 'list', :locals => { :entries => @entries }%>
-<p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => params.merge({:issue_id => @issue, :key => User.current.rss_key}) %>
-  <%= f.link_to 'CSV', :url => params %>
-<% end %>
-<% end %>
-
-<% html_title l(:label_spent_time), l(:label_details) %>
-
-<% content_for :header_tags do %>
-    <%= auto_discovery_link_tag(:atom, {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :title => l(:label_spent_time)) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/eb/ebdd88daadf29dca84a991c2b00b03af07e7a917.svn-base
--- /dev/null
+++ b/.svn/pristine/eb/ebdd88daadf29dca84a991c2b00b03af07e7a917.svn-base
@@ -0,0 +1,22 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class MessageObserver < ActiveRecord::Observer
+  def after_create(message)
+    Mailer.message_posted(message).deliver if Setting.notified_events.include?('message_posted')
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/eb/ebfee87b692025d708fcb9b6e98c73314886e7fc.svn-base
--- /dev/null
+++ b/.svn/pristine/eb/ebfee87b692025d708fcb9b6e98c73314886e7fc.svn-base
@@ -0,0 +1,132 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class Journal < ActiveRecord::Base
+  belongs_to :journalized, :polymorphic => true
+  # added as a quick fix to allow eager loading of the polymorphic association
+  # since always associated to an issue, for now
+  belongs_to :issue, :foreign_key => :journalized_id
+
+  belongs_to :user
+  has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
+  attr_accessor :indice
+
+  acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
+                :description => :notes,
+                :author => :user,
+                :group => :issue,
+                :type => Proc.new {|o| (s = o.new_status) ? (s.is_closed? ? 'issue-closed' : 'issue-edit') : 'issue-note' },
+                :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
+
+  acts_as_activity_provider :type => 'issues',
+                            :author_key => :user_id,
+                            :find_options => {:include => [{:issue => :project}, :details, :user],
+                                              :conditions => "#{Journal.table_name}.journalized_type = 'Issue' AND" +
+                                                             " (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')"}
+
+  before_create :split_private_notes
+
+  scope :visible, lambda {|*args|
+    user = args.shift || User.current
+
+    includes(:issue => :project).
+      where(Issue.visible_condition(user, *args)).
+      where("(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(user, :view_private_notes, *args)}))", false)
+  }
+
+  def save(*args)
+    # Do not save an empty journal
+    (details.empty? && notes.blank?) ? false : super
+  end
+
+  # Returns the new status if the journal contains a status change, otherwise nil
+  def new_status
+    c = details.detect {|detail| detail.prop_key == 'status_id'}
+    (c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
+  end
+
+  def new_value_for(prop)
+    c = details.detect {|detail| detail.prop_key == prop}
+    c ? c.value : nil
+  end
+
+  def editable_by?(usr)
+    usr && usr.logged? && (usr.allowed_to?(:edit_issue_notes, project) || (self.user == usr && usr.allowed_to?(:edit_own_issue_notes, project)))
+  end
+
+  def project
+    journalized.respond_to?(:project) ? journalized.project : nil
+  end
+
+  def attachments
+    journalized.respond_to?(:attachments) ? journalized.attachments : nil
+  end
+
+  # Returns a string of css classes
+  def css_classes
+    s = 'journal'
+    s << ' has-notes' unless notes.blank?
+    s << ' has-details' unless details.blank?
+    s << ' private-notes' if private_notes?
+    s
+  end
+
+  def notify?
+    @notify != false
+  end
+
+  def notify=(arg)
+    @notify = arg
+  end
+
+  def recipients
+    notified = journalized.notified_users
+    if private_notes?
+      notified = notified.select {|user| user.allowed_to?(:view_private_notes, journalized.project)}
+    end
+    notified.map(&:mail)
+  end
+
+  def watcher_recipients
+    notified = journalized.notified_watchers
+    if private_notes?
+      notified = notified.select {|user| user.allowed_to?(:view_private_notes, journalized.project)}
+    end
+    notified.map(&:mail)
+  end
+
+  private
+
+  def split_private_notes
+    if private_notes?
+      if notes.present?
+        if details.any?
+          # Split the journal (notes/changes) so we don't have half-private journals
+          journal = Journal.new(:journalized => journalized, :user => user, :notes => nil, :private_notes => false)
+          journal.details = details
+          journal.save
+          self.details = []
+          self.created_on = journal.created_on
+        end
+      else
+        # Blank notes should not be private
+        self.private_notes = false
+      end
+    end
+    true
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ec/ec08ed5799ed2d9d7e3eaed4465f5f691c2309ee.svn-base
--- /dev/null
+++ b/.svn/pristine/ec/ec08ed5799ed2d9d7e3eaed4465f5f691c2309ee.svn-base
@@ -0,0 +1,193 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::WikiPagesTest < Redmine::ApiTest::Base
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :enabled_modules, :wikis, :wiki_pages, :wiki_contents,
+           :wiki_content_versions, :attachments
+
+  def setup
+    Setting.rest_api_enabled = '1'
+  end
+
+  test "GET /projects/:project_id/wiki/index.xml should return wiki pages" do
+    get '/projects/ecookbook/wiki/index.xml'
+    assert_response 200
+    assert_equal 'application/xml', response.content_type
+    assert_select 'wiki_pages[type=array]' do
+      assert_select 'wiki_page', :count => Wiki.find(1).pages.count
+      assert_select 'wiki_page' do
+        assert_select 'title', :text => 'CookBook_documentation'
+        assert_select 'version', :text => '3'
+        assert_select 'created_on'
+        assert_select 'updated_on'
+      end
+      assert_select 'wiki_page' do
+        assert_select 'title', :text => 'Page_with_an_inline_image'
+        assert_select 'parent[title=?]', 'CookBook_documentation'
+      end
+    end
+  end
+
+  test "GET /projects/:project_id/wiki/:title.xml should return wiki page" do
+    get '/projects/ecookbook/wiki/CookBook_documentation.xml'
+    assert_response 200
+    assert_equal 'application/xml', response.content_type
+    assert_select 'wiki_page' do
+      assert_select 'title', :text => 'CookBook_documentation'
+      assert_select 'version', :text => '3'
+      assert_select 'text'
+      assert_select 'author'
+      assert_select 'comments'
+      assert_select 'created_on'
+      assert_select 'updated_on'
+    end
+  end
+
+  test "GET /projects/:project_id/wiki/:title.xml?include=attachments should include attachments" do
+    get '/projects/ecookbook/wiki/Page_with_an_inline_image.xml?include=attachments'
+    assert_response 200
+    assert_equal 'application/xml', response.content_type
+    assert_select 'wiki_page' do
+      assert_select 'title', :text => 'Page_with_an_inline_image'
+      assert_select 'attachments[type=array]' do
+        assert_select 'attachment' do
+          assert_select 'id', :text => '3'
+          assert_select 'filename', :text => 'logo.gif'
+        end
+      end
+    end
+  end
+
+  test "GET /projects/:project_id/wiki/:title.xml with unknown title and edit permission should respond with 404" do
+    get '/projects/ecookbook/wiki/Invalid_Page.xml', {}, credentials('jsmith')
+    assert_response 404
+    assert_equal 'application/xml', response.content_type
+  end
+
+  test "GET /projects/:project_id/wiki/:title/:version.xml should return wiki page version" do
+    get '/projects/ecookbook/wiki/CookBook_documentation/2.xml'
+    assert_response 200
+    assert_equal 'application/xml', response.content_type
+    assert_select 'wiki_page' do
+      assert_select 'title', :text => 'CookBook_documentation'
+      assert_select 'version', :text => '2'
+      assert_select 'text'
+      assert_select 'author'
+      assert_select 'created_on'
+      assert_select 'updated_on'
+    end
+  end
+
+  test "GET /projects/:project_id/wiki/:title/:version.xml without permission should be denied" do
+    Role.anonymous.remove_permission! :view_wiki_edits
+
+    get '/projects/ecookbook/wiki/CookBook_documentation/2.xml'
+    assert_response 401
+    assert_equal 'application/xml', response.content_type
+  end
+
+  test "PUT /projects/:project_id/wiki/:title.xml should update wiki page" do
+    assert_no_difference 'WikiPage.count' do
+      assert_difference 'WikiContent::Version.count' do
+        put '/projects/ecookbook/wiki/CookBook_documentation.xml',
+          {:wiki_page => {:text => 'New content from API', :comments => 'API update'}},
+          credentials('jsmith')
+        assert_response 200
+      end
+    end
+
+    page = WikiPage.find(1)
+    assert_equal 'New content from API', page.content.text
+    assert_equal 4, page.content.version
+    assert_equal 'API update', page.content.comments
+    assert_equal 'jsmith', page.content.author.login
+  end
+
+  test "PUT /projects/:project_id/wiki/:title.xml with current versino should update wiki page" do
+    assert_no_difference 'WikiPage.count' do
+      assert_difference 'WikiContent::Version.count' do
+        put '/projects/ecookbook/wiki/CookBook_documentation.xml',
+          {:wiki_page => {:text => 'New content from API', :comments => 'API update', :version => '3'}},
+          credentials('jsmith')
+        assert_response 200
+      end
+    end
+
+    page = WikiPage.find(1)
+    assert_equal 'New content from API', page.content.text
+    assert_equal 4, page.content.version
+    assert_equal 'API update', page.content.comments
+    assert_equal 'jsmith', page.content.author.login
+  end
+
+  test "PUT /projects/:project_id/wiki/:title.xml with stale version should respond with 409" do
+    assert_no_difference 'WikiPage.count' do
+      assert_no_difference 'WikiContent::Version.count' do
+        put '/projects/ecookbook/wiki/CookBook_documentation.xml',
+          {:wiki_page => {:text => 'New content from API', :comments => 'API update', :version => '2'}},
+          credentials('jsmith')
+        assert_response 409
+      end
+    end
+  end
+
+  test "PUT /projects/:project_id/wiki/:title.xml should create the page if it does not exist" do
+    assert_difference 'WikiPage.count' do
+      assert_difference 'WikiContent::Version.count' do
+        put '/projects/ecookbook/wiki/New_page_from_API.xml',
+          {:wiki_page => {:text => 'New content from API', :comments => 'API create'}},
+          credentials('jsmith')
+        assert_response 201
+      end
+    end
+
+    page = WikiPage.order('id DESC').first
+    assert_equal 'New_page_from_API', page.title
+    assert_equal 'New content from API', page.content.text
+    assert_equal 1, page.content.version
+    assert_equal 'API create', page.content.comments
+    assert_equal 'jsmith', page.content.author.login
+    assert_nil page.parent
+  end
+
+  test "PUT /projects/:project_id/wiki/:title.xml with parent" do
+    assert_difference 'WikiPage.count' do
+      assert_difference 'WikiContent::Version.count' do
+        put '/projects/ecookbook/wiki/New_subpage_from_API.xml',
+          {:wiki_page => {:parent_title => 'CookBook_documentation', :text => 'New content from API', :comments => 'API create'}},
+          credentials('jsmith')
+        assert_response 201
+      end
+    end
+
+    page = WikiPage.order('id DESC').first
+    assert_equal 'New_subpage_from_API', page.title
+    assert_equal WikiPage.find(1), page.parent
+  end
+
+  test "DELETE /projects/:project_id/wiki/:title.xml should destroy the page" do
+    assert_difference 'WikiPage.count', -1 do
+      delete '/projects/ecookbook/wiki/CookBook_documentation.xml', {}, credentials('jsmith')
+      assert_response 200
+    end
+
+    assert_nil WikiPage.find_by_id(1)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ec/ec842fc17afa1fb04bc8ffad9cc30b0150dabde2.svn-base
--- a/.svn/pristine/ec/ec842fc17afa1fb04bc8ffad9cc30b0150dabde2.svn-base
+++ /dev/null
@@ -1,129 +0,0 @@
-// ** I18N
-
-// Calendar pt_BR language
-// Author: Adalberto Machado, <betosm@terra.com.br>
-// Review: Alexandre da Silva, <simpsomboy@gmail.com>
-// Encoding: UTF-8
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Domingo",
- "Segunda",
- "TerÃ§a",
- "Quarta",
- "Quinta",
- "Sexta",
- "Sabado",
- "Domingo");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Dom",
- "Seg",
- "Ter",
- "Qua",
- "Qui",
- "Sex",
- "Sab",
- "Dom");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("Janeiro",
- "Fevereiro",
- "MarÃ§o",
- "Abril",
- "Maio",
- "Junho",
- "Julho",
- "Agosto",
- "Setembro",
- "Outubro",
- "Novembro",
- "Dezembro");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Fev",
- "Mar",
- "Abr",
- "Mai",
- "Jun",
- "Jul",
- "Ago",
- "Set",
- "Out",
- "Nov",
- "Dez");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Sobre o calendÃ¡rio";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"Ãšltima versÃ£o visite: http://www.dynarch.com/projects/calendar/\n" +
-"DistribuÃ­do sobre GNU LGPL.  Veja http://gnu.org/licenses/lgpl.html para detalhes." +
-"\n\n" +
-"SeleÃ§Ã£o de data:\n" +
-"- Use os botÃµes \xab, \xbb para selecionar o ano\n" +
-"- Use os botÃµes " + String.fromCharCode(0x2039) + ", " + 
-String.fromCharCode(0x203a) + " para selecionar o mÃªs\n" +
-"- Segure o botÃ£o do mouse em qualquer um desses botÃµes para seleÃ§Ã£o rÃ¡pida.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"SeleÃ§Ã£o de hora:\n" +
-"- Clique em qualquer parte da hora para incrementar\n" +
-"- ou Shift-click para decrementar\n" +
-"- ou clique e segure para seleÃ§Ã£o rÃ¡pida.";
-
-Calendar._TT["PREV_YEAR"] = "Ant. ano (segure para menu)";
-Calendar._TT["PREV_MONTH"] = "Ant. mÃªs (segure para menu)";
-Calendar._TT["GO_TODAY"] = "Hoje";
-Calendar._TT["NEXT_MONTH"] = "PrÃ³x. mes (segure para menu)";
-Calendar._TT["NEXT_YEAR"] = "PrÃ³x. ano (segure para menu)";
-Calendar._TT["SEL_DATE"] = "Selecione a data";
-Calendar._TT["DRAG_TO_MOVE"] = "Arraste para mover";
-Calendar._TT["PART_TODAY"] = " (hoje)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Mostre %s primeiro";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Fechar";
-Calendar._TT["TODAY"] = "Hoje";
-Calendar._TT["TIME_PART"] = "(Shift-)Click ou arraste para mudar valor";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b";
-
-Calendar._TT["WK"] = "sm";
-Calendar._TT["TIME"] = "Hora:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ec/ecc2f40a6fcca9fb15429d3eca8763e39f1812bb.svn-base
--- /dev/null
+++ b/.svn/pristine/ec/ecc2f40a6fcca9fb15429d3eca8763e39f1812bb.svn-base
@@ -0,0 +1,12 @@
+class AddQueriesPermissions < ActiveRecord::Migration
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    Permission.create :controller => "projects", :action => "add_query", :description => "button_create", :sort => 600, :is_public => false, :mail_option => 0, :mail_enabled => 0
+  end
+
+  def self.down
+    Permission.where("controller=? and action=?", 'projects', 'add_query').first.destroy
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ec/eccd397cd94a8e11a0b2f72327549287bc13fcfa.svn-base
--- a/.svn/pristine/ec/eccd397cd94a8e11a0b2f72327549287bc13fcfa.svn-base
+++ /dev/null
@@ -1,1003 +0,0 @@
-# translated by Dzintars Bergs (dzintars.bergs@gmail.com)
-
-lv:
-  direction: ltr
-  date:
-    formats:
-      default: "%d.%m.%Y"
-      short: "%d %b"
-      long: "%d %B %Y"
-      
-    day_names: [SvÄ“tdiena, Pirmdiena, Otrdiena, TreÅ¡diena, Ceturtdiena, Piektdiena, Sestdiena]
-    abbr_day_names: [Sv, Pr, Ot, Tr, Ct, Pk, St]
-      
-    month_names: [~, JanvÄris, FebruÄris, Marts, AprÄ«lis , Maijs, JÅ«nijs, JÅ«lijs, Augusts, Septembris, Oktobris, Novembris, Decembris]
-    abbr_month_names: [~, Jan, Feb, Mar, Apr, Mai, JÅ«n, JÅ«l, Aug, Sep, Okt, Nov, Dec]
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%a, %d %b %Y, %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b, %H:%M"
-      long: "%B %d, %Y %H:%M"
-    am: "rÄ«tÄ"
-    pm: "vakarÄ"
-      
-  datetime:
-    distance_in_words:
-      half_a_minute: "pus minÅ«te"
-      less_than_x_seconds:
-        one:   "mazÄk kÄ 1 sekunde"
-        other: "mazÄk kÄ %{count} sekundes"
-      x_seconds:
-        one:   "1 sekunde"
-        other: "%{count} sekundes"
-      less_than_x_minutes:
-        one:   "mazÄk kÄ minÅ«te"
-        other: "mazÄk kÄ %{count} minÅ«tes"
-      x_minutes:
-        one:   "1 minÅ«te"
-        other: "%{count} minÅ«tes"
-      about_x_hours:
-        one:   "aptuveni 1 stunda"
-        other: "aptuveni %{count} stundas"
-      x_days:
-        one:   "1 diena"
-        other: "%{count} dienas"
-      about_x_months:
-        one:   "aptuveni 1 mÄ“nesis"
-        other: "aptuveni %{count} mÄ“neÅ¡i"
-      x_months:
-        one:   "1 mÄ“nesis"
-        other: "%{count} mÄ“neÅ¡i"
-      about_x_years:
-        one:   "aptuveni 1 gads"
-        other: "aptuveni %{count} gadi"
-      over_x_years:
-        one:   "ilgÄk par 1 gadu"
-        other: "ilgÄk par %{count} gadiem"
-      almost_x_years:
-        one:   "gandrÄ«z 1 gadu"
-        other: "gandrÄ«z %{count} gadus"
-
-  number:
-    format:
-      separator: "."
-      delimiter: ""
-      precision: 3
-    human:
-      format:
-        delimiter: " "
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Baits"
-            other: "Baiti"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-        
-  support:
-    array:
-      sentence_connector: "un"
-      skip_last_comma: false
-      
-  activerecord:
-    errors:
-      template:
-        header:
-          one:    "1 error prohibited this %{model} from being saved"
-          other:  "%{count} errors prohibited this %{model} from being saved"
-      messages:
-        inclusion: "nav iekÄ¼auts sarakstÄ"
-        exclusion: "ir rezervÄ“ts"
-        invalid: "nederÄ«gs"
-        confirmation: "apstiprinÄjums nesakrÄ«t"
-        accepted: "jÄbÅ«t akceptÄ“tam"
-        empty: "nevar bÅ«t tukÅ¡s"
-        blank: "nevar bÅ«t neaizpildÄ«ts"
-        too_long: "ir pÄrÄk gara(Å¡) (maksimÄlais garums ir %{count} simboli)"
-        too_short: "ir pÄrÄk Ä«sa(s) (minimÄlais garums ir %{count} simboli)"
-        wrong_length: "ir nepareiza garuma (vajadzÄ“tu bÅ«t %{count} simboli)"
-        taken: "eksistÄ“"
-        not_a_number: "nav skaitlis"
-        not_a_date: "nav derÄ«gs datums"
-        greater_than: "jÄbÅ«t lielÄkam par %{count}"
-        greater_than_or_equal_to: "jÄbÅ«t lielÄkam vai vienÄdam ar %{count}"
-        equal_to: "jÄbÅ«t vienÄdam ar %{count}"
-        less_than: "jÄbÅ«t mazÄkam kÄ %{count}"
-        less_than_or_equal_to: "jÄbÅ«t mazÄkam vai vienÄdam ar %{count}"
-        odd: "jÄatÅ¡Ä·irÄs"
-        even: "jÄsakrÄ«t"
-        greater_than_start_date: "jÄbÅ«t vÄ“lÄkam par sÄkuma datumu"
-        not_same_project: "nepieder pie tÄ paÅ¡a projekta"
-        circular_dependency: "Å Ä« relÄcija radÄ«tu ciklisku atkarÄ«bu"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  actionview_instancetag_blank_option: IzvÄ“lieties
-  
-  general_text_No: 'NÄ“'
-  general_text_Yes: 'JÄ'
-  general_text_no: 'nÄ“'
-  general_text_yes: 'jÄ'
-  general_lang_name: 'Latvian (LatvieÅ¡u)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-  
-  notice_account_updated: Konts tika atjaunots veiksmÄ«gi.
-  notice_account_invalid_creditentials: Nepareizs lietotÄja vÄrds vai parole.
-  notice_account_password_updated: Parole tika veiksmÄ«gi atjaunota.
-  notice_account_wrong_password: Nepareiza parole
-  notice_account_register_done: Konts veiksmÄ«gi izveidots. Lai aktivizÄ“tu kontu, spiediet uz saites, kas Jums tika nosÅ«tÄ«ta.
-  notice_account_unknown_email: NezinÄms lietotÄjs
-  notice_can_t_change_password: Å is konts izmanto ÄrÄ“ju pilnvaroÅ¡anas avotu. Nav iespÄ“jams nomainÄ«t paroli.
-  notice_account_lost_email_sent: Jums tika nosÅ«tÄ«ts e-pasts ar instrukcijÄm, kÄ izveidot jaunu paroli.
-  notice_account_activated: JÅ«su konts ir aktivizÄ“ts. Varat pieslÄ“gties sistÄ“mai.
-  notice_successful_create: VeiksmÄ«ga izveide.
-  notice_successful_update: VeiksmÄ«ga atjaunoÅ¡ana.
-  notice_successful_delete: VeiksmÄ«ga dzÄ“Å¡ana.
-  notice_successful_connection: VeiksmÄ«gs savienojums.
-  notice_file_not_found: Lapa, ko JÅ«s mÄ“Ä£inÄt atvÄ“rt, neeksistÄ“ vai ir pÄrvietota.
-  notice_locking_conflict: Datus ir atjaunojis cits lietotÄjs.
-  notice_not_authorized: Jums nav tiesÄ«bu piekÄ¼Å«t Å¡ai lapai.
-  notice_email_sent: "E-pasts tika nosÅ«tÄ«ts uz %{value}"
-  notice_email_error: "KÄ¼Å«da sÅ«tot e-pastu (%{value})"
-  notice_feeds_access_key_reseted: JÅ«su RSS pieejas atslÄ“ga tika iestatÄ«ta sÄkuma stÄvoklÄ«.
-  notice_api_access_key_reseted: JÅ«su API pieejas atslÄ“ga tika iestatÄ«ta sÄkuma stÄvoklÄ«.
-  notice_failed_to_save_issues: "NeizdevÄs saglabÄt %{count} uzdevumu(us) no %{total} izvÄ“lÄ“ti: %{ids}."
-  notice_no_issue_selected: "Nav izvÄ“lÄ“ts uzdevums! LÅ«dzu, atzÄ«mÄ“jiet uzdevumus, kurus vÄ“laties rediÄ£Ä“t!"
-  notice_account_pending: "JÅ«su konts tika izveidots un Å¡obrÄ«d gaida administratora apstiprinÄjumu."
-  notice_default_data_loaded: NoklusÄ“tÄ konfigurÄcija tika veiksmÄ«gi ielÄdÄ“ta.
-  notice_unable_delete_version: NeizdevÄs dzÄ“st versiju.
-  notice_issue_done_ratios_updated: Uzdevuma izpildes koeficients atjaunots.
-  
-  error_can_t_load_default_data: "Nevar ielÄdÄ“t noklusÄ“tos konfigurÄcijas datus: %{value}"
-  error_scm_not_found: "Ieraksts vai versija nebija repozitorijÄ."
-  error_scm_command_failed: "MÄ“Ä£inot piekÄ¼Å«t repozitorijam, notika kÄ¼Å«da: %{value}"
-  error_scm_annotate: "Ieraksts neeksistÄ“ vai tam nevar tikt pievienots paskaidrojums."
-  error_issue_not_found_in_project: 'Uzdevums netika atrasts vai nepieder Å¡im projektam.'
-  error_no_tracker_in_project: 'Neviens trakeris nav saistÄ«ts ar Å¡o projektu. PÄrbaudiet projekta iestatÄ«jumus.'
-  error_no_default_issue_status: 'Nav definÄ“ts uzdevuma noklusÄ“tais statuss. PÄrbaudiet konfigurÄciju (Ejat uz: "AdministrÄcija -> Uzdevumu statusi")!'
-  error_can_not_reopen_issue_on_closed_version: 'Nevar pievienot atsauksmi uzdevumam, kas saistÄ«ts ar slÄ“gtu versiju.'
-  error_can_not_archive_project: Å is projekts nevar tikt arhivÄ“ts
-  error_issue_done_ratios_not_updated: "Uzdevuma izpildes koeficients nav atjaunots."
-  error_workflow_copy_source: 'LÅ«dzu izvÄ“lieties avota trakeri vai lomu'
-  error_workflow_copy_target: 'LÅ«dzu izvÄ“lÄ“ties mÄ“rÄ·a trakeri(us) un lomu(as)'
-  
-  warning_attachments_not_saved: "%{count} datnes netika saglabÄtas."
-  
-  mail_subject_lost_password: "JÅ«su %{value} parole"
-  mail_body_lost_password: 'Lai mainÄ«tu paroli, spiediet uz Å¡Ä«s saites:'
-  mail_subject_register: "JÅ«su %{value} konta aktivizÄcija"
-  mail_body_register: 'Lai izveidotu kontu, spiediet uz Å¡Ä«s saites:'
-  mail_body_account_information_external: "Varat izmantot JÅ«su %{value} kontu, lai pieslÄ“gtos."
-  mail_body_account_information: JÅ«su konta informÄcija
-  mail_subject_account_activation_request: "%{value} konta aktivizÄcijas pieprasÄ«jums"
-  mail_body_account_activation_request: "Jauns lietotÄjs (%{value}) ir reÄ£istrÄ“ts. LietotÄja konts gaida JÅ«su apstiprinÄjumu:"
-  mail_subject_reminder: "%{count} uzdevums(i) sagaidÄms(i) tuvÄkajÄs %{days} dienÄs"
-  mail_body_reminder: "%{count} uzdevums(i), kurÅ¡(i) ir nozÄ«mÄ“ts(i) Jums, sagaidÄms(i) tuvÄkajÄs %{days} dienÄs:"
-  mail_subject_wiki_content_added: "'%{id}' Wiki lapa pievienota"
-  mail_body_wiki_content_added: "The '%{id}' Wiki lapu pievienojis %{author}."
-  mail_subject_wiki_content_updated: "'%{id}' Wiki lapa atjaunota"
-  mail_body_wiki_content_updated: "The '%{id}' Wiki lapu atjaunojis %{author}."
-  
-  gui_validation_error: 1 kÄ¼Å«da
-  gui_validation_error_plural: "%{count} kÄ¼Å«das"
-  
-  field_name: Nosaukums
-  field_description: Apraksts
-  field_summary: Kopsavilkums
-  field_is_required: NepiecieÅ¡ams
-  field_firstname: VÄrds
-  field_lastname: UzvÄrds
-  field_mail: "E-pasts"
-  field_filename: Datne
-  field_filesize: IzmÄ“rs
-  field_downloads: LejupielÄdes
-  field_author: Autors
-  field_created_on: Izveidots
-  field_updated_on: Atjaunots
-  field_field_format: FormÄts
-  field_is_for_all: Visiem projektiem
-  field_possible_values: IespÄ“jamÄs vÄ“rtÄ«bas
-  field_regexp: RegulÄrÄ izteiksme
-  field_min_length: MinimÄlais garums
-  field_max_length: MaksimÄlais garums
-  field_value: VÄ“rtÄ«ba
-  field_category: Kategorija
-  field_title: Nosaukums
-  field_project: Projekts
-  field_issue: Uzdevums
-  field_status: Statuss
-  field_notes: PiezÄ«mes
-  field_is_closed: Uzdevums slÄ“gts
-  field_is_default: NoklusÄ“tÄ vÄ“rtÄ«ba
-  field_tracker: Trakeris
-  field_subject: Temats
-  field_due_date: SagaidÄmais datums
-  field_assigned_to: PieÅ¡Ä·irts
-  field_priority: PrioritÄte
-  field_fixed_version: MÄ“rÄ·a versija
-  field_user: LietotÄjs
-  field_role: Loma
-  field_homepage: Vietne
-  field_is_public: Publisks
-  field_parent: ApakÅ¡projekts projektam
-  field_is_in_roadmap: CeÄ¼vedÄ« parÄdÄ«tie uzdevumi
-  field_login: PieslÄ“gties
-  field_mail_notification: "E-pasta paziÅ†ojumi"
-  field_admin: Administrators
-  field_last_login_on: PÄ“dÄ“jo reizi pieslÄ“dzies
-  field_language: Valoda
-  field_effective_date: Datums
-  field_password: Parole
-  field_new_password: JanÄ parole
-  field_password_confirmation: Paroles apstiprinÄjums
-  field_version: Versija
-  field_type: Tips
-  field_host: Hosts
-  field_port: Ports
-  field_account: Konts
-  field_base_dn: Base DN
-  field_attr_login: PieslÄ“gÅ¡anÄs atribÅ«ts
-  field_attr_firstname: VÄrda atribÅ«ts
-  field_attr_lastname: UzvÄrda atribÅ«ts
-  field_attr_mail: "E-pasta atribÅ«ts"
-  field_onthefly: "LietotÄja izveidoÅ¡ana on-the-fly"
-  field_start_date: SÄkuma datums
-  field_done_ratio: "% padarÄ«ti"
-  field_auth_source: PilnvaroÅ¡anas reÅ¾Ä«ms
-  field_hide_mail: "PaslÄ“pt manu e-pasta adresi"
-  field_comments: KomentÄrs
-  field_url: URL
-  field_start_page: SÄkuma lapa
-  field_subproject: ApakÅ¡projekts
-  field_hours: Stundas
-  field_activity: AktivitÄte
-  field_spent_on: Datums
-  field_identifier: Identifikators
-  field_is_filter: Izmantots kÄ filtrs
-  field_issue_to: SaistÄ«ts uzdevums
-  field_delay: KavÄ“jums
-  field_assignable: Uzdevums var tikt piesaistÄ«ts Å¡ai lomai
-  field_redirect_existing_links: PÄradresÄ“t eksistÄ“joÅ¡Äs saites
-  field_estimated_hours: ParedzÄ“tais laiks
-  field_column_names: Kolonnas
-  field_time_zone: Laika zona
-  field_searchable: MeklÄ“jams
-  field_default_value: NoklusÄ“tÄ vÄ“rtÄ«ba
-  field_comments_sorting: RÄdÄ«t komentÄrus
-  field_parent_title: VecÄka lapa
-  field_editable: RediÄ£Ä“jams
-  field_watcher: VÄ“rotÄjs
-  field_identity_url: OpenID URL
-  field_content: Saturs
-  field_group_by: GrupÄ“t rezultÄtus pÄ“c
-  field_sharing: KoplietoÅ¡ana
-  
-  setting_app_title: Programmas nosaukums
-  setting_app_subtitle: Programmas apakÅ¡-nosaukums
-  setting_welcome_text: Sveiciena teksts
-  setting_default_language: NoklusÄ“tÄ valoda
-  setting_login_required: NepiecieÅ¡ama pilnvaroÅ¡ana
-  setting_self_registration: PaÅ¡reÄ£istrÄ“Å¡anÄs
-  setting_attachment_max_size: Pielikuma maksimÄlais izmÄ“rs
-  setting_issues_export_limit: Uzdevumu eksporta ierobeÅ¾ojums
-  setting_mail_from: "E-pasta adrese informÄcijas nosÅ«tÄ«Å¡anai"
-  setting_bcc_recipients: "SaÅ†Ä“mÄ“ju adreses neparÄdÄ«sies citu saÅ†Ä“mÄ“ju vÄ“stulÄ“s (bcc)"
-  setting_plain_text_mail: "VÄ“stule brÄ«vÄ tekstÄ (bez HTML)"
-  setting_host_name: Hosta nosaukums un piekÄ¼uves ceÄ¼Å¡
-  setting_text_formatting: Teksta formatÄ“Å¡ana
-  setting_wiki_compression: Wiki vÄ“stures saspieÅ¡ana
-  setting_feeds_limit: Barotnes satura ierobeÅ¾ojums
-  setting_default_projects_public: Jaunie projekti noklusÄ“ti ir publiski pieejami
-  setting_autofetch_changesets: "AutomÄtiski lietot jaunÄko versiju, pieslÄ“dzoties repozitorijam (Autofetch)"
-  setting_sys_api_enabled: IeslÄ“gt WS repozitoriju menedÅ¾mentam
-  setting_commit_ref_keywords: NorÄdes atslÄ“gvÄrdi
-  setting_commit_fix_keywords:  FiksÄ“joÅ¡ie atslÄ“gvÄrdi
-  setting_autologin: AutomÄtiskÄ pieslÄ“gÅ¡anÄs
-  setting_date_format: Datuma formÄts
-  setting_time_format: Laika formÄts
-  setting_cross_project_issue_relations: "AtÄ¼aut starp-projektu uzdevumu relÄcijas"
-  setting_issue_list_default_columns: NoklusÄ“ti rÄdÄ«tÄs kolonnas uzdevumu sarakstÄ
-  setting_emails_footer: "E-pastu kÄjene"
-  setting_protocol: Protokols
-  setting_per_page_options: Objekti vienÄ lapÄ
-  setting_user_format: LietotÄju rÄdÄ«Å¡anas formÄts
-  setting_activity_days_default: Dienus skaits aktivitÄÅ¡u rÄdÄ«Å¡anai aktivitÄÅ¡u sadaÄ¼Ä
-  setting_display_subprojects_issues: RÄdÄ«t apakÅ¡projekta uzdevumus galvenajÄ projektÄ pÄ“c noklusÄ“juma
-  setting_enabled_scm: Lietot SCM
-  setting_mail_handler_body_delimiters: "SaÄ«sinÄt pÄ“c vienas no Å¡im rindÄm"
-  setting_mail_handler_api_enabled: "Lietot WS ienÄkoÅ¡ajiem e-pastiem"
-  setting_mail_handler_api_key: API atslÄ“ga
-  setting_sequential_project_identifiers: Ä¢enerÄ“t secÄ«gus projektu identifikatorus
-  setting_gravatar_enabled: Izmantot Gravatar lietotÄju ikonas
-  setting_gravatar_default: NoklusÄ“tais Gravatar attÄ“ls
-  setting_diff_max_lines_displayed: MaksimÄlais rÄdÄ«to diff rindu skaits
-  setting_file_max_size_displayed: MaksimÄlais izmÄ“rs iekÄ¼autajiem teksta failiem
-  setting_repository_log_display_limit: MaksimÄlais Å¾urnÄla datnÄ“ rÄdÄ«to revÄ«ziju skaits
-  setting_openid: AtÄ¼aut OpenID pieslÄ“gÅ¡anos un reÄ£istrÄ“Å¡anos
-  setting_password_min_length: MinimÄlais paroles garums
-  setting_new_project_user_role_id: Loma, kura tiek pieÅ¡Ä·irta ne-administratora lietotÄjam, kurÅ¡ izveido projektu
-  setting_default_projects_modules: NoklusÄ“tie lietotie moduÄ¼i jaunam projektam
-  setting_issue_done_ratio: AprÄ“Ä·inÄt uzdevuma izpildes koeficientu ar
-  setting_issue_done_ratio_issue_field: uzdevuma lauku
-  setting_issue_done_ratio_issue_status: uzdevuma statusu
-  setting_start_of_week: SÄkt kalendÄru ar
-  setting_rest_api_enabled: Lietot REST web-servisu
-  setting_cache_formatted_text: KeÅ¡ot formatÄ“tu tekstu
-  
-  permission_add_project: Izveidot projektu
-  permission_add_subprojects: Izveidot apakÅ¡projektu
-  permission_edit_project: RediÄ£Ä“t projektu
-  permission_select_project_modules: IzvÄ“lÄ“ties projekta moduÄ¼us
-  permission_manage_members: PÄrvaldÄ«t dalÄ«bniekus
-  permission_manage_project_activities: PÄrvaldÄ«t projekta aktivitÄtes
-  permission_manage_versions: PÄrvaldÄ«t versijas
-  permission_manage_categories: PÄrvaldÄ«t uzdevumu kategorijas
-  permission_view_issues: ApskatÄ«t uzdevumus
-  permission_add_issues: Pievienot uzdevumus
-  permission_edit_issues: RediÄ£Ä“t uzdevumus
-  permission_manage_issue_relations: PÄrvaldÄ«t uzdevumu relÄcijas
-  permission_add_issue_notes: Pievienot piezÄ«mes
-  permission_edit_issue_notes: RediÄ£Ä“t piezÄ«mes
-  permission_edit_own_issue_notes: RediÄ£Ä“t paÅ¡a piezÄ«mes
-  permission_move_issues: PÄrvietot uzdevumus
-  permission_delete_issues: DzÄ“st uzdevumus
-  permission_manage_public_queries: PÄrvaldÄ«t publiskos pieprasÄ«jumus
-  permission_save_queries: SaglabÄt pieprasÄ«jumus
-  permission_view_gantt: SkatÄ«t Ganta diagrammu
-  permission_view_calendar: SkatÄ«t kalendÄru
-  permission_view_issue_watchers: SkatÄ«t vÄ“rotÄju sarakstu
-  permission_add_issue_watchers: Pievienot vÄ“rotÄjus
-  permission_delete_issue_watchers: DzÄ“st vÄ“rotÄjus
-  permission_log_time: PiereÄ£istrÄ“t pavadÄ«to laiku
-  permission_view_time_entries: SkatÄ«t pavadÄ«to laiku
-  permission_edit_time_entries: RdiÄ£Ä“t laika reÄ£istrus
-  permission_edit_own_time_entries:  RediÄ£Ä“t savus laika reÄ£istrus
-  permission_manage_news: PÄrvaldÄ«t jaunumus
-  permission_comment_news: KomentÄ“t jaunumus
-  permission_manage_documents: PÄrvaldÄ«t dokumentus
-  permission_view_documents: SkatÄ«t dokumentus
-  permission_manage_files: PÄrvaldÄ«t failus
-  permission_view_files: SkatÄ«t failus
-  permission_manage_wiki: PÄrvaldÄ«t wiki
-  permission_rename_wiki_pages: PÄrsaukt wiki lapas
-  permission_delete_wiki_pages: DzÄ“st wiki lapas
-  permission_view_wiki_pages: SkatÄ«t wiki
-  permission_view_wiki_edits: SkatÄ«t wiki vÄ“sturi
-  permission_edit_wiki_pages: RdiÄ£Ä“t wiki lapas
-  permission_delete_wiki_pages_attachments: DzÄ“st pielikumus
-  permission_protect_wiki_pages: Projekta wiki lapas
-  permission_manage_repository: PÄrvaldÄ«t repozitoriju
-  permission_browse_repository: PÄrlÅ«kot repozitoriju
-  permission_view_changesets: SkatÄ«t izmaiÅ†u kopumus  
-  permission_commit_access: AtÄ¼aut piekÄ¼uvi
-  permission_manage_boards: PÄrvaldÄ«t ziÅ†ojumu dÄ“Ä¼us
-  permission_view_messages: SkatÄ«t ziÅ†as
-  permission_add_messages: PublicÄ“t ziÅ†as
-  permission_edit_messages: RediÄ£Ä“t ziÅ†as
-  permission_edit_own_messages: RediÄ£Ä“t savas ziÅ†as
-  permission_delete_messages: DzÄ“st ziÅ†as
-  permission_delete_own_messages: DzÄ“st savas ziÅ†as
-  permission_export_wiki_pages: EksportÄ“t Wiki lapas
-  
-  project_module_issue_tracking: Uzdevumu uzskaite
-  project_module_time_tracking: Laika uzskaite
-  project_module_news: Jaunumi
-  project_module_documents: Dokumenti
-  project_module_files: Datnes
-  project_module_wiki: Wiki
-  project_module_repository: Repozitorijs
-  project_module_boards: ZiÅ†ojumu dÄ“Ä¼i
-  
-  label_user: LietotÄjs
-  label_user_plural: LietotÄji
-  label_user_new: Jauns lietotÄjs
-  label_user_anonymous: AnonÄ«ms
-  label_project: Projekts
-  label_project_new: Jauns projekts
-  label_project_plural: Projekti
-  label_x_projects:
-    zero:  nav projektu
-    one:   1 projekts
-    other: "%{count} projekti"
-  label_project_all: Visi projekti
-  label_project_latest: JaunÄkie projekti
-  label_issue: Uzdevums
-  label_issue_new: Jauns uzdevums
-  label_issue_plural: Uzdevumi
-  label_issue_view_all: SkatÄ«t visus uzdevumus
-  label_issues_by: "KÄrtot pÄ“c %{value}"
-  label_issue_added: Uzdevums pievienots
-  label_issue_updated: Uzdevums atjaunots
-  label_document: Dokuments
-  label_document_new: Jauns dokuments
-  label_document_plural: Dokumenti
-  label_document_added: Dokuments pievienots
-  label_role: Loma
-  label_role_plural: Lomas
-  label_role_new: Jauna loma
-  label_role_and_permissions: Lomas un atÄ¼aujas
-  label_member: DalÄ«bnieks
-  label_member_new: Jauns dalÄ«bnieks
-  label_member_plural: DalÄ«bnieki
-  label_tracker: Trakeris
-  label_tracker_plural: Trakeri
-  label_tracker_new: Jauns trakeris
-  label_workflow: Darba gaita
-  label_issue_status: Uzdevuma statuss
-  label_issue_status_plural: Uzdevumu statusi
-  label_issue_status_new: Jauns statuss
-  label_issue_category: Uzdevuma kategorija
-  label_issue_category_plural: Uzdevumu kategorijas
-  label_issue_category_new: Jauna kategorija
-  label_custom_field: PielÄgojams lauks
-  label_custom_field_plural: PielÄgojami lauki
-  label_custom_field_new: Jauns pielÄgojams lauks
-  label_enumerations: UzskaitÄ«jumi
-  label_enumeration_new: Jauna vÄ“rtÄ«ba
-  label_information: InformÄcija
-  label_information_plural: InformÄcija
-  label_please_login: LÅ«dzu pieslÄ“dzieties
-  label_register: ReÄ£istrÄ“ties
-  label_login_with_open_id_option: vai pieslÄ“gties ar OpenID
-  label_password_lost: NozaudÄ“ta parole
-  label_home: SÄkums
-  label_my_page: Mana lapa
-  label_my_account: Mans konts
-  label_my_projects: Mani projekti
-  label_administration: AdministrÄcija
-  label_login: PieslÄ“gties
-  label_logout: AtslÄ“gties
-  label_help: PalÄ«dzÄ«ba
-  label_reported_issues: ZiÅ†otie uzdevumi
-  label_assigned_to_me_issues: Man piesaistÄ«tie uzdevumi
-  label_last_login: PÄ“dÄ“jÄ pieslÄ“gÅ¡anÄs
-  label_registered_on: ReÄ£istrÄ“jies
-  label_activity: AktivitÄte
-  label_overall_activity: KopÄ“jÄs aktivitÄtes
-  label_user_activity: "LietotÄja %{value} aktivitÄtes"
-  label_new: Jauns
-  label_logged_as: PieslÄ“dzies kÄ
-  label_environment: Vide
-  label_authentication: PilnvaroÅ¡ana
-  label_auth_source: PilnvaroÅ¡anas reÅ¾Ä«ms
-  label_auth_source_new: Jauns pilnvaroÅ¡anas reÅ¾Ä«ms
-  label_auth_source_plural: PilnvaroÅ¡anas reÅ¾Ä«mi
-  label_subproject_plural: ApakÅ¡projekti
-  label_subproject_new: Jauns apakÅ¡projekts
-  label_and_its_subprojects: "%{value} un tÄ apakÅ¡projekti"
-  label_min_max_length: MinimÄlais - MaksimÄlais garums
-  label_list: Saraksts
-  label_date: Datums
-  label_integer: Vesels skaitlis
-  label_float: DecimÄlskaitlis
-  label_boolean: Patiesuma vÄ“rtÄ«ba
-  label_string: Teksts
-  label_text: GarÅ¡ teksts
-  label_attribute: AtribÅ«ts
-  label_attribute_plural: AtribÅ«ti
-  label_download: "%{count} LejupielÄde"
-  label_download_plural: "%{count} LejupielÄdes"
-  label_no_data: Nav datu, ko parÄdÄ«t
-  label_change_status: MainÄ«t statusu
-  label_history: VÄ“sture
-  label_attachment: Pielikums
-  label_attachment_new: Jauns pielikums
-  label_attachment_delete: DzÄ“st pielikumu
-  label_attachment_plural: Pielikumi
-  label_file_added: Lauks pievienots
-  label_report: Atskaite
-  label_report_plural: Atskaites
-  label_news: ZiÅ†a
-  label_news_new: Pievienot ziÅ†u
-  label_news_plural: ZiÅ†as
-  label_news_latest: JaunÄkÄs ziÅ†as
-  label_news_view_all: SkatÄ«t visas ziÅ†as
-  label_news_added: ZiÅ†as pievienotas
-  label_settings: IestatÄ«jumi
-  label_overview: PÄrskats
-  label_version: Versija
-  label_version_new: Jauna versija
-  label_version_plural: Versijas
-  label_close_versions: AizvÄ“rt pabeigtÄs versijas
-  label_confirmation: ApstiprinÄjums
-  label_export_to: 'Pieejams arÄ«:'
-  label_read: LasÄ«t...
-  label_public_projects: Publiskie projekti
-  label_open_issues: atvÄ“rts
-  label_open_issues_plural: atvÄ“rti
-  label_closed_issues: slÄ“gts
-  label_closed_issues_plural: slÄ“gti
-  label_x_open_issues_abbr_on_total:
-    zero:  0 atvÄ“rti / %{total}
-    one:   1 atvÄ“rts / %{total}
-    other: "%{count} atvÄ“rti / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 atvÄ“rti
-    one:   1 atvÄ“rts
-    other: "%{count} atvÄ“rti"
-  label_x_closed_issues_abbr:
-    zero:  0 slÄ“gti
-    one:   1 slÄ“gts
-    other: "%{count} slÄ“gti"
-  label_total: KopÄ
-  label_permissions: AtÄ¼aujas
-  label_current_status: PaÅ¡reizÄ“jais statuss
-  label_new_statuses_allowed: Jauni statusi atÄ¼auti
-  label_all: visi
-  label_none: neviens
-  label_nobody: nekas
-  label_next: NÄkoÅ¡ais
-  label_previous: IepriekÅ¡Ä“jais
-  label_used_by: Izmanto
-  label_details: DetaÄ¼as
-  label_add_note: Pievienot piezÄ«mi
-  label_per_page: katrÄ lapÄ
-  label_calendar: KalendÄrs
-  label_months_from: mÄ“neÅ¡i no
-  label_gantt: Ganta diagramma
-  label_internal: IekÅ¡Ä“jais
-  label_last_changes: "pÄ“dÄ“jÄs %{count} izmaiÅ†as"
-  label_change_view_all: SkatÄ«t visas izmaiÅ†as
-  label_personalize_page: PielÄgot Å¡o lapu
-  label_comment: KomentÄrs
-  label_comment_plural: KomentÄri
-  label_x_comments:
-    zero: nav komentÄru
-    one: 1 komentÄrs
-    other: "%{count} komentÄri"
-  label_comment_add: Pievienot komentÄru
-  label_comment_added: KomentÄrs pievienots
-  label_comment_delete: DzÄ“st komentÄrus
-  label_query: PielÄgots pieprasÄ«jums
-  label_query_plural: PielÄgoti pieprasÄ«jumi
-  label_query_new: Jauns pieprasÄ«jums
-  label_filter_add: Pievienot filtru
-  label_filter_plural: Filtri
-  label_equals: ir
-  label_not_equals: nav
-  label_in_less_than: ir mazÄk kÄ
-  label_in_more_than: ir vairÄk kÄ
-  label_greater_or_equal: '>='
-  label_less_or_equal: '<='
-  label_in: iekÅ¡
-  label_today: Å¡odien
-  label_all_time: visu laiku
-  label_yesterday: vakar
-  label_this_week: Å¡onedÄ“Ä¼
-  label_last_week: pagÄjuÅ¡o Å¡onedÄ“Ä¼
-  label_last_n_days: "pÄ“dÄ“jÄs %{count} dienas"
-  label_this_month: Å¡omÄ“nes
-  label_last_month: pagÄjuÅ¡o mÄ“nes
-  label_this_year: Å¡ogad
-  label_date_range: Datumu apgabals
-  label_less_than_ago: mazÄk kÄ dienas iepriekÅ¡
-  label_more_than_ago: vairÄk kÄ dienas iepriekÅ¡
-  label_ago: dienas iepriekÅ¡
-  label_contains: satur
-  label_not_contains: nesatur
-  label_day_plural: dienas
-  label_repository: Repozitorijs
-  label_repository_plural: Repozitoriji
-  label_browse: PÄrlÅ«kot
-  label_modification: "%{count} izmaiÅ†a"
-  label_modification_plural: "%{count} izmaiÅ†as"
-  label_branch: Zars
-  label_tag: Birka 
-  label_revision: RevÄ«zija
-  label_revision_plural: RevÄ«zijas
-  label_revision_id: "RevÄ«zija %{value}"
-  label_associated_revisions: SaistÄ«tÄs revÄ«zijas
-  label_added: pievienots
-  label_modified: modificÄ“ts
-  label_copied: nokopÄ“ts
-  label_renamed: pÄrsaukts
-  label_deleted: dzÄ“sts
-  label_latest_revision: PÄ“dÄ“jÄ revÄ«zija
-  label_latest_revision_plural: PÄ“dÄ“jÄs revÄ«zijas
-  label_view_revisions: SkatÄ«t revÄ«zijas
-  label_view_all_revisions: SkatÄ«t visas revÄ«zijas
-  label_max_size: MaksimÄlais izmÄ“rs
-  label_sort_highest: PÄrvietot uz augÅ¡u
-  label_sort_higher: PÄrvietot soli augÅ¡up
-  label_sort_lower: PÄrvietot uz leju
-  label_sort_lowest: PÄrvietot vienu soli uz leju
-  label_roadmap: CeÄ¼vedis
-  label_roadmap_due_in: "SagaidÄms pÄ“c %{value}"
-  label_roadmap_overdue: "nokavÄ“ts %{value}"
-  label_roadmap_no_issues: Å ai versijai nav uzdevumu
-  label_search: MeklÄ“t
-  label_result_plural: RezultÄti
-  label_all_words: Visi vÄrdi
-  label_wiki: Wiki
-  label_wiki_edit: Wiki labojums
-  label_wiki_edit_plural: Wiki labojumi
-  label_wiki_page: Wiki lapa
-  label_wiki_page_plural: Wiki lapas
-  label_index_by_title: IndeksÄ“t pÄ“c nosaukuma
-  label_index_by_date: IndeksÄ“t pÄ“c datuma
-  label_current_version: TekoÅ¡Ä versija
-  label_preview: PriekÅ¡skatÄ«jums
-  label_feed_plural: Barotnes
-  label_changes_details: Visu izmaiÅ†u detaÄ¼as
-  label_issue_tracking: Uzdevumu uzskaite
-  label_spent_time: PavadÄ«tais laiks
-  label_f_hour: "%{value} stunda"
-  label_f_hour_plural: "%{value} stundas"
-  label_time_tracking: Laika uzskaite
-  label_change_plural: IzmaiÅ†as
-  label_statistics: Statistika
-  label_commits_per_month: Nodevumi mÄ“nesÄ«
-  label_commits_per_author: Nodevumi no autora
-  label_view_diff: SkatÄ«t atÅ¡Ä·irÄ«bas
-  label_diff_inline: iekÄ¼auts
-  label_diff_side_by_side: blakus
-  label_options: Opcijas
-  label_copy_workflow_from: KopÄ“t darba plÅ«smu no
-  label_permissions_report: AtÄ¼auju atskaite
-  label_watched_issues: VÄ“rotie uzdevumi
-  label_related_issues: SaistÄ«tie uzdevumi
-  label_applied_status: PieÅ¡Ä·irtais statuss
-  label_loading: LÄdÄ“jas...
-  label_relation_new: Jauna relÄcija
-  label_relation_delete: DzÄ“st relÄciju
-  label_relates_to: saistÄ«ts ar
-  label_duplicates: dublikÄti
-  label_duplicated_by: dublÄ“jas ar
-  label_blocks: bloÄ·Ä“
-  label_blocked_by: nobloÄ·Ä“jis
-  label_precedes: pirms
-  label_follows: seko
-  label_end_to_start: no beigÄm uz sÄkumu
-  label_end_to_end: no beigÄm uz beigÄm
-  label_start_to_start: no sÄkuma uz sÄkumu
-  label_start_to_end: no sÄkuma uz beigÄm
-  label_stay_logged_in: AtcerÄ“ties mani
-  label_disabled: izslÄ“gts
-  label_show_completed_versions: RÄdÄ«t pabeigtÄs versijas
-  label_me: es
-  label_board: Forums
-  label_board_new: Jauns forums
-  label_board_plural: Forumi
-  label_board_locked: SlÄ“gts
-  label_board_sticky: SvarÄ«gs
-  label_topic_plural: TÄ“mas
-  label_message_plural: ZiÅ†as
-  label_message_last: PÄ“dÄ“jÄ ziÅ†a
-  label_message_new: Jauna ziÅ†a
-  label_message_posted: ZiÅ†a pievienota
-  label_reply_plural: Atbildes
-  label_send_information: SÅ«tÄ«t konta informÄciju lietotÄjam
-  label_year: Gads
-  label_month: MÄ“nesis
-  label_week: NedÄ“Ä¼a
-  label_date_from: No
-  label_date_to: Kam
-  label_language_based: Izmantot lietotÄja valodu
-  label_sort_by: "KÄrtot pÄ“c %{value}"
-  label_send_test_email: "SÅ«tÄ«t testa e-pastu"
-  label_feeds_access_key: RSS piekÄ¼uves atslÄ“ga
-  label_missing_feeds_access_key: TrÅ«kst RSS piekÄ¼uves atslÄ“gas
-  label_feeds_access_key_created_on: "RSS piekÄ¼uves atslÄ“ga izveidota pirms %{value}"
-  label_module_plural: ModuÄ¼i
-  label_added_time_by: "Pievienojis %{author} pirms %{age}"
-  label_updated_time_by: "Atjaunojis %{author} pirms %{age}"
-  label_updated_time: "Atjaunots pirms %{value}"
-  label_jump_to_a_project: PÄriet uz projektu...
-  label_file_plural: Datnes
-  label_changeset_plural: IzmaiÅ†u kopumi
-  label_default_columns: NoklusÄ“tÄs kolonnas
-  label_no_change_option: (Nav izmaiÅ†u)
-  label_bulk_edit_selected_issues: Labot visus izvÄ“lÄ“tos uzdevumus
-  label_theme: TÄ“ma
-  label_default: NoklusÄ“ts
-  label_search_titles_only: MeklÄ“t tikai nosaukumos
-  label_user_mail_option_all: "Par visiem notikumiem visos manos projektos"
-  label_user_mail_option_selected: "Par visiem notikumiem tikai izvÄ“lÄ“tajos projektos..."
-  label_user_mail_no_self_notified: "NeziÅ†ot man par izmaiÅ†Äm, kuras veicu es pats"
-  label_registration_activation_by_email: "konta aktivizÄcija caur e-pastu"
-  label_registration_manual_activation: manuÄlÄ konta aktivizÄcija
-  label_registration_automatic_activation: automÄtiskÄ konta aktivizÄcija
-  label_display_per_page: "RÄdÄ«t vienÄ lapÄ: %{value}"
-  label_age: Vecums
-  label_change_properties: MainÄ«t atribÅ«tus
-  label_general: Galvenais
-  label_more: VÄ“l
-  label_scm: SCM
-  label_plugins: SpraudÅ†i
-  label_ldap_authentication: LDAP pilnvaroÅ¡ana
-  label_downloads_abbr: L-lÄd.
-  label_optional_description: "Apraksts (neobligÄts)"
-  label_add_another_file: Pievienot citu failu
-  label_preferences: PriekÅ¡rocÄ«bas
-  label_chronological_order: HronoloÄ£iskÄ kÄrtÄ«bÄ
-  label_reverse_chronological_order: Apgriezti hronoloÄ£iskÄ kÄrtÄ«bÄ
-  label_planning: PlÄnoÅ¡ana
-  label_incoming_emails: "IenÄkoÅ¡ie e-pasti"
-  label_generate_key: Ä¢enerÄ“t atslÄ“gu
-  label_issue_watchers: VÄ“rotÄji
-  label_example: PiemÄ“rs
-  label_display: RÄdÄ«t
-  label_sort: KÄrtot
-  label_ascending: AugoÅ¡i
-  label_descending: DilstoÅ¡i
-  label_date_from_to: "No %{start} lÄ«dz %{end}"
-  label_wiki_content_added: Wiki lapa pievienota
-  label_wiki_content_updated: Wiki lapa atjaunota
-  label_group: Grupa
-  label_group_plural: Grupas
-  label_group_new: Jauna grupa
-  label_time_entry_plural: PavadÄ«tais laiks
-  label_version_sharing_none: Nav koplietoÅ¡anai
-  label_version_sharing_descendants: Ar apakÅ¡projektiem
-  label_version_sharing_hierarchy: Ar projektu hierarhiju
-  label_version_sharing_tree: Ar projekta koku
-  label_version_sharing_system: Ar visiem projektiem
-  label_update_issue_done_ratios: Atjaunot uzdevuma veikuma attiecÄ«bu
-  label_copy_source: Avots
-  label_copy_target: MÄ“rÄ·is
-  label_copy_same_as_target: TÄds pats kÄ mÄ“rÄ·is
-  label_display_used_statuses_only: "RÄdÄ«t tikai statusus, ko lieto Å¡is trakeris"
-  label_api_access_key: API pieejas atslÄ“ga
-  label_missing_api_access_key: TrÅ«kst API pieejas atslÄ“ga
-  label_api_access_key_created_on: "API pieejas atslÄ“ga izveidota pirms %{value}"
-  
-  button_login: PieslÄ“gties
-  button_submit: NosÅ«tÄ«t
-  button_save: SaglabÄt
-  button_check_all: AtzÄ«mÄ“t visu
-  button_uncheck_all: NoÅ†emt visus atzÄ«mÄ“jumus
-  button_delete: DzÄ“st
-  button_create: Izveidot
-  button_create_and_continue: Izveidot un turpinÄt
-  button_test: TestÄ“t
-  button_edit: Labot
-  button_add: Pievienot
-  button_change: MainÄ«t
-  button_apply: ApstiprinÄt
-  button_clear: NotÄ«rÄ«t
-  button_lock: SlÄ“gt
-  button_unlock: AtslÄ“gt
-  button_download: LejuplÄdÄ“t
-  button_list: Saraksts
-  button_view: Skats
-  button_move: PÄrvietot
-  button_move_and_follow: PÄrvietot un sekot
-  button_back: AtpakaÄ¼
-  button_cancel: Atcelt
-  button_activate: AktivizÄ“t
-  button_sort: KÄrtot
-  button_log_time: Ilgs laiks
-  button_rollback: Atjaunot uz Å¡o versiju
-  button_watch: VÄ“rot
-  button_unwatch: NevÄ“rot
-  button_reply: AtbildÄ“t
-  button_archive: ArhivÄ“t
-  button_unarchive: AtarhivÄ“t
-  button_reset: AtiestatÄ«t
-  button_rename: PÄrsaukt
-  button_change_password: MainÄ«t paroli
-  button_copy: KopÄ“t
-  button_copy_and_follow: KopÄ“t un sekot
-  button_annotate: PierakstÄ«t paskaidrojumu
-  button_update: Atjaunot
-  button_configure: KonfigurÄ“t
-  button_quote: CitÄts
-  button_duplicate: DublÄ“t
-  button_show: RÄdÄ«t
-  
-  status_active: aktÄ«vs
-  status_registered: reÄ£istrÄ“ts
-  status_locked: slÄ“gts
-  
-  version_status_open: atvÄ“rta
-  version_status_locked: slÄ“gta
-  version_status_closed: aizvÄ“rta
-
-  field_active: AktÄ«vs
-  
-  text_select_mail_notifications: "IzvÄ“lieties darbÄ«bas, par kurÄm vÄ“laties saÅ†emt ziÅ†ojumus e-pastÄ"
-  text_regexp_info: "piem. ^[A-Z0-9]+$"
-  text_min_max_length_info: "0 nozÄ«mÄ“, ka nav ierobeÅ¾ojumu"
-  text_project_destroy_confirmation: "Vai tieÅ¡Äm vÄ“laties dzÄ“st Å¡o projektu un ar to saistÄ«tos datus?"
-  text_subprojects_destroy_warning: "TÄ apakÅ¡projekts(i): %{value} arÄ« tiks dzÄ“sts(i)."
-  text_workflow_edit: Lai labotu darba plÅ«smu, izvÄ“lieties lomu un trakeri
-  text_are_you_sure: "Vai esat pÄrliecinÄts?"
-  text_journal_changed: "%{label} mainÄ«ts no %{old} uz %{new}"
-  text_journal_set_to: "%{label} iestatÄ«ts uz %{value}"
-  text_journal_deleted: "%{label} dzÄ“sts (%{old})"
-  text_journal_added: "%{label} %{value} pievienots"
-  text_tip_issue_begin_day: uzdevums sÄkas Å¡odien
-  text_tip_issue_end_day: uzdevums beidzas Å¡odien
-  text_tip_issue_begin_end_day: uzdevums sÄkas un beidzas Å¡odien
-  text_project_identifier_info: 'Tikai mazie burti (a-z), cipari un domuzÄ«mes ir atÄ¼auti.<br />Kad saglabÄts, identifikators nevar tikt mainÄ«ts.'
-  text_caracters_maximum: "%{count} simboli maksimÄli."
-  text_caracters_minimum: "JÄbÅ«t vismaz %{count} simbolu garumÄ."
-  text_length_between: "Garums starp %{min} un %{max} simboliem."
-  text_tracker_no_workflow: Å im trakerim nav definÄ“ta darba plÅ«sma
-  text_unallowed_characters: NeatÄ¼auti simboli
-  text_comma_separated: "AtÄ¼autas vairÄkas vÄ“rtÄ«bas (atdalÄ«t ar komatu)."
-  text_line_separated: "AtÄ¼autas vairÄkas vÄ“rtÄ«bas (rakstÄ«t katru savÄ rindÄ)."
-  text_issues_ref_in_commit_messages: "IzmaiÅ†u salÄ«dzinÄÅ¡ana izejot no ziÅ†ojumiem"
-  text_issue_added: "Uzdevumu %{id} pievienojis %{author}."
-  text_issue_updated: "Uzdevumu %{id} atjaunojis %{author}."
-  text_wiki_destroy_confirmation: "Vai esat droÅ¡s, ka vÄ“laties dzÄ“st Å¡o wiki un visu tÄs saturu?"
-  text_issue_category_destroy_question: "DaÅ¾i uzdevumi (%{count}) ir nozÄ«mÄ“ti Å¡ai kategorijai. Ko JÅ«s vÄ“laties darÄ«t?"
-  text_issue_category_destroy_assignments: DzÄ“st kategoriju nozÄ«mÄ“jumus
-  text_issue_category_reassign_to: NozÄ«mÄ“t uzdevumus Å¡ai kategorijai
-  text_user_mail_option: "No neizvÄ“lÄ“tajiem projektiem JÅ«s saÅ†emsiet ziÅ†ojumus e-pastÄ tikai par notikumiem, kuriem JÅ«s sekojat vai kuros esat iesaistÄ«ts." 
-  text_no_configuration_data: "Lomas, trakeri, uzdevumu statusi un darba plÅ«smas vÄ“l nav konfigurÄ“tas.\nÄ»oti ieteicams ielÄdÄ“t noklusÄ“to konfigurÄciju. PÄ“c ielÄdÄ“Å¡anas to bÅ«s iespÄ“jams modificÄ“t."
-  text_load_default_configuration: IelÄdÄ“t noklusÄ“to konfigurÄciju
-  text_status_changed_by_changeset: "ApstiprinÄts izmaiÅ†u kopumÄ %{value}."
-  text_issues_destroy_confirmation: 'Vai tieÅ¡Äm vÄ“laties dzÄ“st izvÄ“lÄ“to uzdevumu(us)?'
-  text_select_project_modules: 'IzvÄ“lieties moduÄ¼us Å¡im projektam:'
-  text_default_administrator_account_changed: NoklusÄ“tais administratora konts mainÄ«ts
-  text_file_repository_writable: Pielikumu direktorijÄ atÄ¼auts rakstÄ«t
-  text_plugin_assets_writable: SpraudÅ†u kataloga direktorijÄ atÄ¼auts rakstÄ«t
-  text_rmagick_available: "RMagick pieejams (neobligÄts)"
-  text_destroy_time_entries_question: "%{hours} stundas tika ziÅ†otas par uzdevumu, ko vÄ“laties dzÄ“st. Ko darÄ«t?"
-  text_destroy_time_entries: DzÄ“st ziÅ†otÄs stundas
-  text_assign_time_entries_to_project: PieÅ¡Ä·irt ziÅ†otÄs stundas projektam
-  text_reassign_time_entries: 'PieÅ¡Ä·irt ziÅ†otÄs stundas uzdevumam:'
-  text_user_wrote: "%{value} rakstÄ«ja:"
-  text_enumeration_destroy_question: "%{count} objekti ir pieÅ¡Ä·irti Å¡ai vÄ“rtÄ«bai."
-  text_enumeration_category_reassign_to: 'PieÅ¡Ä·irt tos Å¡ai vÄ“rtÄ«bai:'
-  text_email_delivery_not_configured: "E-pastu nosÅ«tÄ«Å¡ana nav konfigurÄ“ta, un ziÅ†ojumi ir izslÄ“gti.\nKonfigurÄ“jiet savu SMTP serveri datnÄ“ config/configuration.yml un pÄrstartÄ“jiet lietotni."
-  text_repository_usernames_mapping: "IzvÄ“lieties vai atjaunojiet Redmine lietotÄju, saistÄ«tu ar katru lietotÄjvÄrdu, kas atrodams repozitorija Å¾urnÄlÄ.\nLietotÄji ar to paÅ¡u Redmine un repozitorija lietotÄjvÄrdu bÅ«s saistÄ«ti automÄtiski."
-  text_diff_truncated: '... Å is diff tika noÅ¡Ä·elts, jo tas pÄrsniedz maksimÄlo izmÄ“ru, ko var parÄdÄ«t.'
-  text_custom_field_possible_values_info: 'Katra vÄ“rtÄ«bas savÄ rindÄ'
-  text_wiki_page_destroy_question: "Å ij lapai ir %{descendants} apakÅ¡lapa(as) un pÄ“cnÄcÄ“ji. Ko darÄ«t?"
-  text_wiki_page_nullify_children: "PaturÄ“t apakÅ¡lapas kÄ pamatlapas"
-  text_wiki_page_destroy_children: "DzÄ“st apakÅ¡lapas un visus pÄ“cnÄcÄ“jus"
-  text_wiki_page_reassign_children: "PieÅ¡Ä·irt apakÅ¡lapas Å¡ai lapai"
-  text_own_membership_delete_confirmation: "JÅ«s tÅ«lÄ«t dzÄ“sÄ«siet daÅ¾as vai visas atÄ¼aujas, un Jums pÄ“c tam var nebÅ«t atÄ¼auja labot Å¡o projektu.\nVai turpinÄt?"
-  
-  default_role_manager: MenedÅ¾eris
-  default_role_developer: IzstrÄdÄtÄjs
-  default_role_reporter: ZiÅ†otÄjs
-  default_tracker_bug: KÄ¼Å«da
-  default_tracker_feature: IezÄ«me
-  default_tracker_support: Atbalsts
-  default_issue_status_new: Jauns
-  default_issue_status_in_progress: AttÄ«stÄ«bÄ
-  default_issue_status_resolved: AtrisinÄts
-  default_issue_status_feedback: Atsauksmes
-  default_issue_status_closed: SlÄ“gts
-  default_issue_status_rejected: NoraidÄ«ts
-  default_doc_category_user: LietotÄja dokumentÄcija
-  default_doc_category_tech: TehniskÄ dokumentÄcija
-  default_priority_low: Zema
-  default_priority_normal: NormÄla
-  default_priority_high: Augsta
-  default_priority_urgent: Steidzama
-  default_priority_immediate: TÅ«lÄ«tÄ“ja
-  default_activity_design: Dizains
-  default_activity_development: IzstrÄdÄÅ¡ana
-  
-  enumeration_issue_priorities: Uzdevumu prioritÄtes
-  enumeration_doc_categories: Dokumentu kategorijas
-  enumeration_activities: AktivitÄtes (laika uzskaite)
-  enumeration_system_activity: SistÄ“mas aktivitÄtes
-
-  error_can_not_delete_custom_field: Unable to delete custom field
-  permission_manage_subtasks: Manage subtasks
-  label_profile: Profile
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  field_parent_issue: Parent task
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_subtask_plural: Subtasks
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  label_project_copy_notifications: Send email notifications during the project copy
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: KodÄ“t ziÅ†ojumus
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ec/ecefbcb550b756f6256573a28f797d89d864d36f.svn-base
--- /dev/null
+++ b/.svn/pristine/ec/ecefbcb550b756f6256573a28f797d89d864d36f.svn-base
@@ -0,0 +1,22 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class ProjectCustomField < CustomField
+  def type_name
+    :label_project_plural
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ed/ed1fb7a49d065a062c38b048a383e12fc1982787.svn-base
--- /dev/null
+++ b/.svn/pristine/ed/ed1fb7a49d065a062c38b048a383e12fc1982787.svn-base
@@ -0,0 +1,19 @@
+# HG changeset patch
+# User tmaruyama
+# Date 1355872765 0
+# Node ID 8a13ebed1779c2e85fa644ecdd0de81996c969c4
+# Parent  5c3c5f917ae92f278fe42c6978366996595b0796
+Russian "about_x_hours" translation changed by Mikhail Velkin (#12640)
+
+diff --git a/config/locales/ru.yml b/config/locales/ru.yml
+--- a/config/locales/ru.yml
++++ b/config/locales/ru.yml
+@@ -115,7 +115,7 @@ ru:
+         one:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
+         few:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
+         many:  "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
+-        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
++        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
+       x_hours:
+         one:   "1 Ñ‡Ð°Ñ"
+         other: "%{count} Ñ‡Ð°ÑÐ¾Ð²"
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ed/ed54e17c309435857cb6c6ab5edf8effc7865259.svn-base
--- a/.svn/pristine/ed/ed54e17c309435857cb6c6ab5edf8effc7865259.svn-base
+++ /dev/null
@@ -1,16 +0,0 @@
-<h2><%=l(:label_attachment_new)%></h2>
-
-<%= error_messages_for 'attachment' %>
-<div class="box">
-<% form_tag(project_files_path(@project), :multipart => true, :class => "tabular") do %>
-
-<% if @versions.any? %>
-<p><label for="version_id"><%=l(:field_version)%></label>
-<%= select_tag "version_id", content_tag('option', '') +
-                             options_from_collection_for_select(@versions, "id", "name") %></p>
-<% end %>
-
-<p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
-</div>
-<%= submit_tag l(:button_add) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ed/ed57efbc247183b288b943a718082419611a4686.svn-base
--- a/.svn/pristine/ed/ed57efbc247183b288b943a718082419611a4686.svn-base
+++ /dev/null
@@ -1,88 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class Journal < ActiveRecord::Base
-  belongs_to :journalized, :polymorphic => true
-  # added as a quick fix to allow eager loading of the polymorphic association
-  # since always associated to an issue, for now
-  belongs_to :issue, :foreign_key => :journalized_id
-
-  belongs_to :user
-  has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
-  attr_accessor :indice
-
-  acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
-                :description => :notes,
-                :author => :user,
-                :type => Proc.new {|o| (s = o.new_status) ? (s.is_closed? ? 'issue-closed' : 'issue-edit') : 'issue-note' },
-                :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
-
-  acts_as_activity_provider :type => 'issues',
-                            :author_key => :user_id,
-                            :find_options => {:include => [{:issue => :project}, :details, :user],
-                                              :conditions => "#{Journal.table_name}.journalized_type = 'Issue' AND" +
-                                                             " (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')"}
-
-  named_scope :visible, lambda {|*args| {
-    :include => {:issue => :project},
-    :conditions => Issue.visible_condition(args.shift || User.current, *args)
-  }}
-
-  def save(*args)
-    # Do not save an empty journal
-    (details.empty? && notes.blank?) ? false : super
-  end
-
-  # Returns the new status if the journal contains a status change, otherwise nil
-  def new_status
-    c = details.detect {|detail| detail.prop_key == 'status_id'}
-    (c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
-  end
-
-  def new_value_for(prop)
-    c = details.detect {|detail| detail.prop_key == prop}
-    c ? c.value : nil
-  end
-
-  def editable_by?(usr)
-    usr && usr.logged? && (usr.allowed_to?(:edit_issue_notes, project) || (self.user == usr && usr.allowed_to?(:edit_own_issue_notes, project)))
-  end
-
-  def project
-    journalized.respond_to?(:project) ? journalized.project : nil
-  end
-
-  def attachments
-    journalized.respond_to?(:attachments) ? journalized.attachments : nil
-  end
-
-  # Returns a string of css classes
-  def css_classes
-    s = 'journal'
-    s << ' has-notes' unless notes.blank?
-    s << ' has-details' unless details.blank?
-    s
-  end
-
-  def notify?
-    @notify != false
-  end
-
-  def notify=(arg)
-    @notify = arg
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ed/ed6a51d1f0379f8074efb84ec3e558be74c26303.svn-base
--- /dev/null
+++ b/.svn/pristine/ed/ed6a51d1f0379f8074efb84ec3e558be74c26303.svn-base
@@ -0,0 +1,3 @@
+<fieldset class="preview"><legend><%= l(:label_preview) %></legend>
+<%= textilizable @text, :attachments => @attachments, :object => @previewed %>
+</fieldset>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ed/ede91cedae4ed5ab7969e06dc653df26e2ee78bf.svn-base
--- a/.svn/pristine/ed/ede91cedae4ed5ab7969e06dc653df26e2ee78bf.svn-base
+++ /dev/null
@@ -1,122 +0,0 @@
-# RedMine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'zlib'
-
-class WikiContent < ActiveRecord::Base
-  set_locking_column :version
-  belongs_to :page, :class_name => 'WikiPage', :foreign_key => 'page_id'
-  belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
-  validates_presence_of :text
-  validates_length_of :comments, :maximum => 255, :allow_nil => true
-
-  acts_as_versioned
-
-  def visible?(user=User.current)
-    page.visible?(user)
-  end
-
-  def project
-    page.project
-  end
-
-  def attachments
-    page.nil? ? [] : page.attachments
-  end
-
-  # Returns the mail adresses of users that should be notified
-  def recipients
-    notified = project.notified_users
-    notified.reject! {|user| !visible?(user)}
-    notified.collect(&:mail)
-  end
-
-  # Return true if the content is the current page content
-  def current_version?
-    true
-  end
-
-  class Version
-    belongs_to :page, :class_name => '::WikiPage', :foreign_key => 'page_id'
-    belongs_to :author, :class_name => '::User', :foreign_key => 'author_id'
-    attr_protected :data
-
-    acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"},
-                  :description => :comments,
-                  :datetime => :updated_on,
-                  :type => 'wiki-page',
-                  :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.page.wiki.project, :id => o.page.title, :version => o.version}}
-
-    acts_as_activity_provider :type => 'wiki_edits',
-                              :timestamp => "#{WikiContent.versioned_table_name}.updated_on",
-                              :author_key => "#{WikiContent.versioned_table_name}.author_id",
-                              :permission => :view_wiki_edits,
-                              :find_options => {:select => "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
-                                                           "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
-                                                           "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
-                                                           "#{WikiContent.versioned_table_name}.id",
-                                                :joins => "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
-                                                          "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
-                                                          "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"}
-
-    def text=(plain)
-      case Setting.wiki_compression
-      when 'gzip'
-      begin
-        self.data = Zlib::Deflate.deflate(plain, Zlib::BEST_COMPRESSION)
-        self.compression = 'gzip'
-      rescue
-        self.data = plain
-        self.compression = ''
-      end
-      else
-        self.data = plain
-        self.compression = ''
-      end
-      plain
-    end
-
-    def text
-      @text ||= case compression
-      when 'gzip'
-        str = Zlib::Inflate.inflate(data)
-        str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
-        str
-      else
-        # uncompressed data
-        data
-      end
-    end
-
-    def project
-      page.project
-    end
-
-    # Return true if the content is the current page content
-    def current_version?
-      page.content.version == self.version
-    end
-
-    # Returns the previous version or nil
-    def previous
-      @previous ||= WikiContent::Version.find(:first,
-                                              :order => 'version DESC',
-                                              :include => :author,
-                                              :conditions => ["wiki_content_id = ? AND version < ?", wiki_content_id, version])
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ee/ee30ef523618c637d188e55eacaa07da2f1a8a87.svn-base
--- /dev/null
+++ b/.svn/pristine/ee/ee30ef523618c637d188e55eacaa07da2f1a8a87.svn-base
@@ -0,0 +1,49 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::TokenAuthenticationTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules
+
+  def setup
+    Setting.rest_api_enabled = '1'
+    Setting.login_required = '1'
+  end
+
+  def teardown
+    Setting.rest_api_enabled = '0'
+    Setting.login_required = '0'
+  end
+
+  # Using the NewsController because it's a simple API.
+  context "get /news" do
+    context "in :xml format" do
+      should_allow_key_based_auth(:get, "/news.xml")
+    end
+
+    context "in :json format" do
+      should_allow_key_based_auth(:get, "/news.json")
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ee/ee581fa8b060e7dedfd4b98698527b98b2c543d6.svn-base
--- a/.svn/pristine/ee/ee581fa8b060e7dedfd4b98698527b98b2c543d6.svn-base
+++ /dev/null
@@ -1,1059 +0,0 @@
-# Vietnamese translation for Ruby on Rails
-# by
-#   Do Hai Bac (dohaibac@gmail.com)
-#   Dao Thanh Ngoc (ngocdaothanh@gmail.com, http://github.com/ngocdaothanh/rails-i18n/tree/master)
-
-vi:
-  number:
-    # Used in number_with_delimiter()
-    # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
-    format:
-      # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
-      separator: ","
-      # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three)
-      delimiter: "."
-      # Number of decimals, behind the separator (1 with a precision of 2 gives: 1.00)
-      precision: 3
-
-    # Used in number_to_currency()
-    currency:
-      format:
-        # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
-        format: "%n %u"
-        unit: "Ä‘á»“ng"
-        # These three are to override number.format and are optional
-        separator: ","
-        delimiter: "."
-        precision: 2
-
-    # Used in number_to_percentage()
-    percentage:
-      format:
-        # These three are to override number.format and are optional
-        # separator:
-        delimiter: ""
-        # precision:
-
-    # Used in number_to_precision()
-    precision:
-      format:
-        # These three are to override number.format and are optional
-        # separator:
-        delimiter: ""
-        # precision:
-
-    # Used in number_to_human_size()
-    human:
-      format:
-        # These three are to override number.format and are optional
-        # separator:
-        delimiter: ""
-        precision: 1
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "Byte"
-            other: "Bytes"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
-  datetime:
-    distance_in_words:
-      half_a_minute: "30 giÃ¢y"
-      less_than_x_seconds:
-        one:   "chÆ°a tá»›i 1 giÃ¢y"
-        other: "chÆ°a tá»›i %{count} giÃ¢y"
-      x_seconds:
-        one:   "1 giÃ¢y"
-        other: "%{count} giÃ¢y"
-      less_than_x_minutes:
-        one:   "chÆ°a tá»›i 1 phÃºt"
-        other: "chÆ°a tá»›i %{count} phÃºt"
-      x_minutes:
-        one:   "1 phÃºt"
-        other: "%{count} phÃºt"
-      about_x_hours:
-        one:   "khoáº£ng 1 giá»"
-        other: "khoáº£ng %{count} giá»"
-      x_days:
-        one:   "1 ngÃ y"
-        other: "%{count} ngÃ y"
-      about_x_months:
-        one:   "khoáº£ng 1 thÃ¡ng"
-        other: "khoáº£ng %{count} thÃ¡ng"
-      x_months:
-        one:   "1 thÃ¡ng"
-        other: "%{count} thÃ¡ng"
-      about_x_years:
-        one:   "khoáº£ng 1 nÄƒm"
-        other: "khoáº£ng %{count} nÄƒm"
-      over_x_years:
-        one:   "hÆ¡n 1 nÄƒm"
-        other: "hÆ¡n %{count} nÄƒm"
-      almost_x_years:
-        one:   "almost 1 year"
-        other: "almost %{count} years"
-    prompts:
-      year:   "NÄƒm"
-      month:  "ThÃ¡ng"
-      day:    "NgÃ y"
-      hour:   "Giá»"
-      minute: "PhÃºt"
-      second: "GiÃ¢y"
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:   "1 lá»—i ngÄƒn khÃ´ng cho lÆ°u %{model} nÃ y"
-          other: "%{count} lá»—i ngÄƒn khÃ´ng cho lÆ°u %{model} nÃ y"
-        # The variable :count is also available
-        body: "CÃ³ lá»—i vá»›i cÃ¡c má»¥c sau:"
-
-      # The values :model, :attribute and :value are always available for interpolation
-      # The value :count is available when applicable. Can be used for pluralization.
-      messages:
-        inclusion: "khÃ´ng cÃ³ trong danh sÃ¡ch"
-        exclusion: "Ä‘Ã£ Ä‘Æ°á»£c giÃ nh trÆ°á»›c"
-        invalid: "khÃ´ng há»£p lá»‡"
-        confirmation: "khÃ´ng khá»›p vá»›i xÃ¡c nháº­n"
-        accepted: "pháº£i Ä‘Æ°á»£c Ä‘á»“ng Ã½"
-        empty: "khÃ´ng thá»ƒ rá»—ng"
-        blank: "khÃ´ng thá»ƒ Ä‘á»ƒ tráº¯ng"
-        too_long: "quÃ¡ dÃ i (tá»‘i Ä‘a %{count} kÃ½ tá»±)"
-        too_short: "quÃ¡ ngáº¯n (tá»‘i thiá»ƒu %{count} kÃ½ tá»±)"
-        wrong_length: "Ä‘á»™ dÃ i khÃ´ng Ä‘Ãºng (pháº£i lÃ  %{count} kÃ½ tá»±)"
-        taken: "Ä‘Ã£ cÃ³"
-        not_a_number: "khÃ´ng pháº£i lÃ  sá»‘"
-        greater_than: "pháº£i lá»›n hÆ¡n %{count}"
-        greater_than_or_equal_to: "pháº£i lá»›n hÆ¡n hoáº·c báº±ng %{count}"
-        equal_to: "pháº£i báº±ng %{count}"
-        less_than: "pháº£i nhá» hÆ¡n %{count}"
-        less_than_or_equal_to: "pháº£i nhá» hÆ¡n hoáº·c báº±ng %{count}"
-        odd: "pháº£i lÃ  sá»‘ cháºµn"
-        even: "pháº£i lÃ  sá»‘ láº»"
-        greater_than_start_date: "pháº£i Ä‘i sau ngÃ y báº¯t Ä‘áº§u"
-        not_same_project: "khÃ´ng thuá»™c cÃ¹ng dá»± Ã¡n"
-        circular_dependency: "quan há»‡ cÃ³ thá»ƒ gÃ¢y ra láº·p vÃ´ táº­n"
-        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
-
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%d-%m-%Y"
-      short: "%d %b"
-      long: "%d %B, %Y"
-
-    day_names: ["Chá»§ nháº­t", "Thá»© hai", "Thá»© ba", "Thá»© tÆ°", "Thá»© nÄƒm", "Thá»© sÃ¡u", "Thá»© báº£y"]
-    abbr_day_names: ["Chá»§ nháº­t", "Thá»© hai", "Thá»© ba", "Thá»© tÆ°", "Thá»© nÄƒm", "Thá»© sÃ¡u", "Thá»© báº£y"]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, "ThÃ¡ng má»™t", "ThÃ¡ng hai", "ThÃ¡ng ba", "ThÃ¡ng tÆ°", "ThÃ¡ng nÄƒm", "ThÃ¡ng sÃ¡u", "ThÃ¡ng báº£y", "ThÃ¡ng tÃ¡m", "ThÃ¡ng chÃ­n", "ThÃ¡ng mÆ°á»i", "ThÃ¡ng mÆ°á»i má»™t", "ThÃ¡ng mÆ°á»i hai"]
-    abbr_month_names: [~, "ThÃ¡ng má»™t", "ThÃ¡ng hai", "ThÃ¡ng ba", "ThÃ¡ng tÆ°", "ThÃ¡ng nÄƒm", "ThÃ¡ng sÃ¡u", "ThÃ¡ng báº£y", "ThÃ¡ng tÃ¡m", "ThÃ¡ng chÃ­n", "ThÃ¡ng mÆ°á»i", "ThÃ¡ng mÆ°á»i má»™t", "ThÃ¡ng mÆ°á»i hai"]
-    # Used in date_select and datime_select.
-    order:
-      - :day
-      - :month
-      - :year
-
-  time:
-    formats:
-      default: "%a, %d %b %Y %H:%M:%S %z"
-      time: "%H:%M"
-      short: "%d %b %H:%M"
-      long: "%d %B, %Y %H:%M"
-    am: "sÃ¡ng"
-    pm: "chiá»u"
-
-  # Used in array.to_sentence.
-  support:
-    array:
-      words_connector: ", "
-      two_words_connector: " vÃ  "
-      last_word_connector: ", vÃ  "
-  
-  actionview_instancetag_blank_option: Vui lÃ²ng chá»n
-
-  general_text_No: 'KhÃ´ng'
-  general_text_Yes: 'CÃ³'
-  general_text_no: 'khÃ´ng'
-  general_text_yes: 'cÃ³'
-  general_lang_name: 'Tiáº¿ng Viá»‡t'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: UTF-8
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
-
-  notice_account_updated: Cáº­p nháº­t tÃ i khoáº£n thÃ nh cÃ´ng.
-  notice_account_invalid_creditentials: TÃ i khoáº£n hoáº·c máº­t mÃ£ khÃ´ng há»£p lá»‡
-  notice_account_password_updated: Cáº­p nháº­t máº­t mÃ£ thÃ nh cÃ´ng.
-  notice_account_wrong_password: Sai máº­t mÃ£
-  notice_account_register_done: TÃ i khoáº£n Ä‘Æ°á»£c táº¡o thÃ nh cÃ´ng. Äá»ƒ kÃ­ch hoáº¡t vui lÃ²ng lÃ m theo hÆ°á»›ng dáº«n trong email gá»­i Ä‘áº¿n báº¡n.
-  notice_account_unknown_email: KhÃ´ng rÃµ tÃ i khoáº£n.
-  notice_can_t_change_password: TÃ i khoáº£n Ä‘Æ°á»£c chá»©ng thá»±c tá»« nguá»“n bÃªn ngoÃ i. KhÃ´ng thá»ƒ Ä‘á»•i máº­t mÃ£ cho loáº¡i chá»©ng thá»±c nÃ y.
-  notice_account_lost_email_sent: ThÃ´ng tin Ä‘á»ƒ Ä‘á»•i máº­t mÃ£ má»›i Ä‘Ã£ gá»­i Ä‘áº¿n báº¡n qua email.
-  notice_account_activated: TÃ i khoáº£n vá»«a Ä‘Æ°á»£c kÃ­ch hoáº¡t. BÃ¢y giá» báº¡n cÃ³ thá»ƒ Ä‘Äƒng nháº­p.
-  notice_successful_create: Táº¡o thÃ nh cÃ´ng.
-  notice_successful_update: Cáº­p nháº­t thÃ nh cÃ´ng.
-  notice_successful_delete: XÃ³a thÃ nh cÃ´ng.
-  notice_successful_connection: Káº¿t ná»‘i thÃ nh cÃ´ng.
-  notice_file_not_found: Trang báº¡n cá»‘ xem khÃ´ng tá»“n táº¡i hoáº·c Ä‘Ã£ chuyá»ƒn.
-  notice_locking_conflict: ThÃ´ng tin Ä‘ang Ä‘Æ°á»£c cáº­p nháº­t bá»Ÿi ngÆ°á»i khÃ¡c. HÃ£y chÃ©p ná»™i dung cáº­p nháº­t cá»§a báº¡n vÃ o clipboard.
-  notice_not_authorized: Báº¡n khÃ´ng cÃ³ quyá»n xem trang nÃ y.
-  notice_email_sent: "Email Ä‘Ã£ Ä‘Æ°á»£c gá»­i tá»›i %{value}"
-  notice_email_error: "Lá»—i xáº£y ra khi gá»­i email (%{value})"
-  notice_feeds_access_key_reseted: MÃ£ sá»‘ chá»©ng thá»±c RSS Ä‘Ã£ Ä‘Æ°á»£c táº¡o láº¡i.
-  notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
-  notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
-  notice_account_pending: "ThÃ´ng tin tÃ i khoáº£n Ä‘Ã£ Ä‘Æ°á»£c táº¡o ra vÃ  Ä‘ang chá» chá»©ng thá»±c tá»« ban quáº£n trá»‹."
-  notice_default_data_loaded: ÄÃ£ náº¡p cáº¥u hÃ¬nh máº·c Ä‘á»‹nh.
-  notice_unable_delete_version: KhÃ´ng thá»ƒ xÃ³a phiÃªn báº£n.
-  
-  error_can_t_load_default_data: "KhÃ´ng thá»ƒ náº¡p cáº¥u hÃ¬nh máº·c Ä‘á»‹nh: %{value}"
-  error_scm_not_found: "The entry or revision was not found in the repository."
-  error_scm_command_failed: "Lá»—i xáº£y ra khi truy cáº­p vÃ o kho lÆ°u trá»¯: %{value}"
-  error_scm_annotate: "The entry does not exist or can not be annotated."
-  error_issue_not_found_in_project: 'Váº¥n Ä‘á» khÃ´ng tá»“n táº¡i hoáº·c khÃ´ng thuá»™c dá»± Ã¡n'
-  
-  mail_subject_lost_password: "%{value}: máº­t mÃ£ cá»§a báº¡n"
-  mail_body_lost_password: "Äá»ƒ Ä‘á»•i máº­t mÃ£, hÃ£y click chuá»™t vÃ o liÃªn káº¿t sau:"
-  mail_subject_register: "%{value}: kÃ­ch hoáº¡t tÃ i khoáº£n"
-  mail_body_register: "Äá»ƒ kÃ­ch hoáº¡t tÃ i khoáº£n, hÃ£y click chuá»™t vÃ o liÃªn káº¿t sau:"
-  mail_body_account_information_external: " Báº¡n cÃ³ thá»ƒ dÃ¹ng tÃ i khoáº£n %{value} Ä‘á»ƒ Ä‘Äƒng nháº­p."
-  mail_body_account_information: ThÃ´ng tin vá» tÃ i khoáº£n
-  mail_subject_account_activation_request: "%{value}: YÃªu cáº§u chá»©ng thá»±c tÃ i khoáº£n"
-  mail_body_account_activation_request: "NgÆ°á»i dÃ¹ng (%{value}) má»›i Ä‘Äƒng kÃ½ vÃ  cáº§n báº¡n xÃ¡c nháº­n:"
-  mail_subject_reminder: "%{count} váº¥n Ä‘á» háº¿t háº¡n trong cÃ¡c %{days} ngÃ y tá»›i"
-  mail_body_reminder: "%{count} váº¥n Ä‘á» gÃ¡n cho báº¡n sáº½ háº¿t háº¡n trong %{days} ngÃ y tá»›i:"
-  
-  gui_validation_error: 1 lá»—i
-  gui_validation_error_plural: "%{count} lá»—i"
-  
-  field_name: TÃªn
-  field_description: MÃ´ táº£
-  field_summary: TÃ³m táº¯t
-  field_is_required: Báº¯t buá»™c
-  field_firstname: TÃªn lÃ³t + TÃªn
-  field_lastname: Há»
-  field_mail: Email
-  field_filename: Táº­p tin
-  field_filesize: Cá»¡
-  field_downloads: Táº£i vá»
-  field_author: TÃ¡c giáº£
-  field_created_on: Táº¡o
-  field_updated_on: Cáº­p nháº­t
-  field_field_format: Äá»‹nh dáº¡ng
-  field_is_for_all: Cho má»i dá»± Ã¡n
-  field_possible_values: GiÃ¡ trá»‹ há»£p lá»‡
-  field_regexp: Biá»ƒu thá»©c chÃ­nh quy
-  field_min_length: Chiá»u dÃ i tá»‘i thiá»ƒu
-  field_max_length: Chiá»u dÃ i tá»‘i Ä‘a
-  field_value: GiÃ¡ trá»‹
-  field_category: Chá»§ Ä‘á»
-  field_title: TiÃªu Ä‘á»
-  field_project: Dá»± Ã¡n
-  field_issue: Váº¥n Ä‘á»
-  field_status: Tráº¡ng thÃ¡i
-  field_notes: Ghi chÃº
-  field_is_closed: Váº¥n Ä‘á» Ä‘Ã³ng
-  field_is_default: GiÃ¡ trá»‹ máº·c Ä‘á»‹nh
-  field_tracker: DÃ²ng váº¥n Ä‘á»
-  field_subject: Chá»§ Ä‘á»
-  field_due_date: Háº¿t háº¡n
-  field_assigned_to: GÃ¡n cho
-  field_priority: Æ¯u tiÃªn
-  field_fixed_version: PhiÃªn báº£n
-  field_user: NgÆ°á»i dÃ¹ng
-  field_role: Quyá»n
-  field_homepage: Trang chá»§
-  field_is_public: CÃ´ng cá»™ng
-  field_parent: Dá»± Ã¡n con cá»§a
-  field_is_in_roadmap: CÃ³ thá»ƒ tháº¥y trong Káº¿ hoáº¡ch
-  field_login: ÄÄƒng nháº­p
-  field_mail_notification: ThÃ´ng bÃ¡o qua email
-  field_admin: Quáº£n trá»‹
-  field_last_login_on: Káº¿t ná»‘i cuá»‘i
-  field_language: NgÃ´n ngá»¯
-  field_effective_date: NgÃ y
-  field_password: Máº­t mÃ£
-  field_new_password: Máº­t mÃ£ má»›i
-  field_password_confirmation: Kháº³ng Ä‘á»‹nh láº¡i
-  field_version: PhiÃªn báº£n
-  field_type: Kiá»ƒu
-  field_host: Host
-  field_port: Port
-  field_account: TÃ i khoáº£n
-  field_base_dn: Base DN
-  field_attr_login: Login attribute
-  field_attr_firstname: Firstname attribute
-  field_attr_lastname: Lastname attribute
-  field_attr_mail: Email attribute
-  field_onthefly: On-the-fly user creation
-  field_start_date: Báº¯t Ä‘áº§u
-  field_done_ratio: Tiáº¿n Ä‘á»™
-  field_auth_source: Authentication mode
-  field_hide_mail: KhÃ´ng lÃ m lá»™ email cá»§a báº¡n
-  field_comments: BÃ¬nh luáº­n
-  field_url: URL
-  field_start_page: Trang báº¯t Ä‘áº§u
-  field_subproject: Dá»± Ã¡n con
-  field_hours: Giá»
-  field_activity: Hoáº¡t Ä‘á»™ng
-  field_spent_on: NgÃ y
-  field_identifier: MÃ£ nháº­n dáº¡ng
-  field_is_filter: DÃ¹ng nhÆ° má»™t lá»c
-  field_issue_to: Váº¥n Ä‘á»n liÃªn quan
-  field_delay: Äá»™ trá»…
-  field_assignable: Váº¥n Ä‘á» cÃ³ thá»ƒ gÃ¡n cho vai trÃ² nÃ y
-  field_redirect_existing_links: Chuyá»ƒn hÆ°á»›ng trang Ä‘Ã£ cÃ³
-  field_estimated_hours: Thá»i gian Æ°á»›c Ä‘oÃ¡n
-  field_column_names: Cá»™t
-  field_time_zone: MÃºi giá»
-  field_searchable: TÃ¬m kiáº¿m Ä‘Æ°á»£c
-  field_default_value: GiÃ¡ trá»‹ máº·c Ä‘á»‹nh
-  field_comments_sorting: Liá»‡t kÃª bÃ¬nh luáº­n
-  field_parent_title: Trang máº¹
-  
-  setting_app_title: Tá»±a Ä‘á» á»©ng dá»¥ng
-  setting_app_subtitle: Tá»±a Ä‘á» nhá» cá»§a á»©ng dá»¥ng
-  setting_welcome_text: ThÃ´ng Ä‘iá»‡p chÃ o má»«ng
-  setting_default_language: NgÃ´n ngá»¯ máº·c Ä‘á»‹nh
-  setting_login_required: Cáº§n Ä‘Äƒng nháº­p
-  setting_self_registration: Tá»± chá»©ng thá»±c
-  setting_attachment_max_size: Cá»¡ tá»‘i Ä‘a cá»§a táº­p tin Ä‘Ã­nh kÃ¨m
-  setting_issues_export_limit: Issues export limit
-  setting_mail_from: Emission email address
-  setting_bcc_recipients: Táº¡o báº£n CC bÃ­ máº­t (bcc)
-  setting_host_name: TÃªn miá»n vÃ  Ä‘Æ°á»ng dáº«n
-  setting_text_formatting: Äá»‹nh dáº¡ng bÃ i viáº¿t
-  setting_wiki_compression: Wiki history compression
-  setting_feeds_limit: Giá»›i háº¡n ná»™i dung cá»§a feed
-  setting_default_projects_public: Dá»± Ã¡n máº·c Ä‘á»‹nh lÃ  cÃ´ng cá»™ng
-  setting_autofetch_changesets: Autofetch commits
-  setting_sys_api_enabled: Enable WS for repository management
-  setting_commit_ref_keywords: Tá»« khÃ³a tham kháº£o
-  setting_commit_fix_keywords: Tá»« khÃ³a chá»‰ váº¥n Ä‘á» Ä‘Ã£ giáº£i quyáº¿t
-  setting_autologin: Tá»± Ä‘á»™ng Ä‘Äƒng nháº­p
-  setting_date_format: Äá»‹nh dáº¡ng ngÃ y
-  setting_time_format: Äá»‹nh dáº¡ng giá»
-  setting_cross_project_issue_relations: Cho phÃ©p quan há»‡ chÃ©o giá»¯a cÃ¡c dá»± Ã¡n
-  setting_issue_list_default_columns: Default columns displayed on the issue list
-  setting_emails_footer: Chá»¯ kÃ½ cuá»‘i thÆ°
-  setting_protocol: Giao thá»©c
-  setting_per_page_options: Objects per page options
-  setting_user_format: Äá»‹nh dáº¡ng hiá»ƒn thá»‹ ngÆ°á»i dÃ¹ng
-  setting_activity_days_default: Days displayed on project activity
-  setting_display_subprojects_issues: Display subprojects issues on main projects by default
-  setting_enabled_scm: Enabled SCM
-  setting_mail_handler_api_enabled: Enable WS for incoming emails
-  setting_mail_handler_api_key: MÃ£ sá»‘ API
-  setting_sequential_project_identifiers: Tá»± sinh chuá»—i ID dá»± Ã¡n
-  
-  project_module_issue_tracking: Theo dÃµi váº¥n Ä‘á»
-  project_module_time_tracking: Theo dÃµi thá»i gian
-  project_module_news: Tin tá»©c
-  project_module_documents: TÃ i liá»‡u
-  project_module_files: Táº­p tin
-  project_module_wiki: Wiki
-  project_module_repository: Kho lÆ°u trá»¯
-  project_module_boards: Diá»…n Ä‘Ã n
-  
-  label_user: TÃ i khoáº£n
-  label_user_plural: TÃ i khoáº£n
-  label_user_new: TÃ i khoáº£n má»›i
-  label_project: Dá»± Ã¡n
-  label_project_new: Dá»± Ã¡n má»›i
-  label_project_plural: Dá»± Ã¡n
-  label_x_projects:
-    zero:  no projects
-    one:   1 project
-    other: "%{count} projects"
-  label_project_all: Má»i dá»± Ã¡n
-  label_project_latest: Dá»± Ã¡n má»›i nháº¥t
-  label_issue: Váº¥n Ä‘á»
-  label_issue_new: Táº¡o váº¥n Ä‘á» má»›i
-  label_issue_plural: Váº¥n Ä‘á»
-  label_issue_view_all: Táº¥t cáº£ váº¥n Ä‘á»
-  label_issues_by: "Váº¥n Ä‘á» cá»§a %{value}"
-  label_issue_added: ÄÃ£ thÃªm váº¥n Ä‘á»
-  label_issue_updated: Váº¥n Ä‘á» Ä‘Æ°á»£c cáº­p nháº­t
-  label_document: TÃ i liá»‡u
-  label_document_new: TÃ i liá»‡u má»›i
-  label_document_plural: TÃ i liá»‡u
-  label_document_added: ÄÃ£ thÃªm tÃ i liá»‡u
-  label_role: Vai trÃ²
-  label_role_plural: Vai trÃ²
-  label_role_new: Vai trÃ² má»›i
-  label_role_and_permissions: Vai trÃ² vÃ  Quyá»n háº¡n
-  label_member: ThÃ nh viÃªn
-  label_member_new: ThÃ nh viÃªn má»›i
-  label_member_plural: ThÃ nh viÃªn
-  label_tracker: DÃ²ng váº¥n Ä‘á»
-  label_tracker_plural: DÃ²ng váº¥n Ä‘á»
-  label_tracker_new: Táº¡o dÃ²ng váº¥n Ä‘á» má»›i
-  label_workflow: Workflow
-  label_issue_status: Issue status
-  label_issue_status_plural: Issue statuses
-  label_issue_status_new: New status
-  label_issue_category: Chá»§ Ä‘á»
-  label_issue_category_plural: Chá»§ Ä‘á»
-  label_issue_category_new: Chá»§ Ä‘á» má»›i
-  label_custom_field: Custom field
-  label_custom_field_plural: Custom fields
-  label_custom_field_new: New custom field
-  label_enumerations: Enumerations
-  label_enumeration_new: New value
-  label_information: ThÃ´ng tin
-  label_information_plural: ThÃ´ng tin
-  label_please_login: Vui lÃ²ng Ä‘Äƒng nháº­p
-  label_register: ÄÄƒng kÃ½
-  label_password_lost: Phá»¥c há»“i máº­t mÃ£
-  label_home: Trang chÃ­nh
-  label_my_page: Trang riÃªng
-  label_my_account: CÃ¡ nhÃ¢n
-  label_my_projects: Dá»± Ã¡n cá»§a báº¡n
-  label_administration: Quáº£n trá»‹
-  label_login: ÄÄƒng nháº­p
-  label_logout: ThoÃ¡t
-  label_help: GiÃºp Ä‘á»¡
-  label_reported_issues: Váº¥n Ä‘á» Ä‘Ã£ bÃ¡o cÃ¡o
-  label_assigned_to_me_issues: Váº¥n Ä‘á» gÃ¡n cho báº¡n
-  label_last_login: Káº¿t ná»‘i cuá»‘i
-  label_registered_on: NgÃ y tham gia
-  label_activity: Hoáº¡t Ä‘á»™ng
-  label_overall_activity: Táº¥t cáº£ hoáº¡t Ä‘á»™ng
-  label_new: Má»›i
-  label_logged_as: TÃ i khoáº£n &raquo;
-  label_environment: Environment
-  label_authentication: Authentication
-  label_auth_source: Authentication mode
-  label_auth_source_new: New authentication mode
-  label_auth_source_plural: Authentication modes
-  label_subproject_plural: Dá»± Ã¡n con
-  label_and_its_subprojects: "%{value} vÃ  dá»± Ã¡n con"
-  label_min_max_length: Min - Max length
-  label_list: List
-  label_date: NgÃ y
-  label_integer: Integer
-  label_float: Float
-  label_boolean: Boolean
-  label_string: Text
-  label_text: Long text
-  label_attribute: Attribute
-  label_attribute_plural: Attributes
-  label_download: "%{count} láº§n táº£i"
-  label_download_plural: "%{count} láº§n táº£i"
-  label_no_data: ChÆ°a cÃ³ thÃ´ng tin gÃ¬
-  label_change_status: Äá»•i tráº¡ng thÃ¡i
-  label_history: LÆ°á»£c sá»­
-  label_attachment: Táº­p tin
-  label_attachment_new: ThÃªm táº­p tin má»›i
-  label_attachment_delete: XÃ³a táº­p tin
-  label_attachment_plural: Táº­p tin
-  label_file_added: ÄÃ£ thÃªm táº­p tin
-  label_report: BÃ¡o cÃ¡o
-  label_report_plural: BÃ¡o cÃ¡o
-  label_news: Tin tá»©c
-  label_news_new: ThÃªm tin
-  label_news_plural: Tin tá»©c
-  label_news_latest: Tin má»›i
-  label_news_view_all: Xem má»i tin
-  label_news_added: ÄÃ£ thÃªm tin
-  label_settings: Thiáº¿t láº­p
-  label_overview: TÃ³m táº¯t
-  label_version: PhiÃªn báº£n
-  label_version_new: PhiÃªn báº£n má»›i
-  label_version_plural: PhiÃªn báº£n
-  label_confirmation: Kháº³ng Ä‘á»‹nh
-  label_export_to: 'Äá»‹nh dáº¡ng khÃ¡c cá»§a trang nÃ y:'
-  label_read: Read...
-  label_public_projects: CÃ¡c dá»± Ã¡n cÃ´ng cá»™ng
-  label_open_issues: má»Ÿ
-  label_open_issues_plural: má»Ÿ
-  label_closed_issues: Ä‘Ã³ng
-  label_closed_issues_plural: Ä‘Ã³ng
-  label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
-  label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
-  label_total: Tá»•ng cá»™ng
-  label_permissions: Quyá»n
-  label_current_status: Tráº¡ng thÃ¡i hiá»‡n táº¡i
-  label_new_statuses_allowed: Tráº¡ng thÃ¡i má»›i Ä‘Æ°á»£c phÃ©p
-  label_all: táº¥t cáº£
-  label_none: khÃ´ng
-  label_nobody: Cháº³ng ai
-  label_next: Sau
-  label_previous: TrÆ°á»›c
-  label_used_by: Used by
-  label_details: Chi tiáº¿t
-  label_add_note: ThÃªm ghi chÃº
-  label_per_page: Má»—i trang
-  label_calendar: Lá»‹ch
-  label_months_from: thÃ¡ng tá»«
-  label_gantt: Biá»ƒu Ä‘á»“ sá»± kiá»‡n
-  label_internal: Ná»™i bá»™
-  label_last_changes: "%{count} thay Ä‘á»•i cuá»‘i"
-  label_change_view_all: Xem má»i thay Ä‘á»•i
-  label_personalize_page: Äiá»u chá»‰nh trang nÃ y
-  label_comment: BÃ¬nh luáº­n
-  label_comment_plural: BÃ¬nh luáº­n
-  label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
-  label_comment_add: ThÃªm bÃ¬nh luáº­n
-  label_comment_added: ÄÃ£ thÃªm bÃ¬nh luáº­n
-  label_comment_delete: XÃ³a bÃ¬nh luáº­n
-  label_query: Truy váº¥n riÃªng
-  label_query_plural: Truy váº¥n riÃªng
-  label_query_new: Truy váº¥n má»›i
-  label_filter_add: ThÃªm lá»c
-  label_filter_plural: Bá»™ lá»c
-  label_equals: lÃ 
-  label_not_equals: khÃ´ng lÃ 
-  label_in_less_than: Ã­t hÆ¡n
-  label_in_more_than: nhiá»u hÆ¡n
-  label_in: trong
-  label_today: hÃ´m nay
-  label_all_time: má»i thá»i gian
-  label_yesterday: hÃ´m qua
-  label_this_week: tuáº§n nÃ y
-  label_last_week: tuáº§n trÆ°á»›c
-  label_last_n_days: "%{count} ngÃ y cuá»‘i"
-  label_this_month: thÃ¡ng nÃ y
-  label_last_month: thÃ¡ng cuá»‘i
-  label_this_year: nÄƒm nÃ y
-  label_date_range: Thá»i gian
-  label_less_than_ago: cÃ¡ch Ä‘Ã¢y dÆ°á»›i
-  label_more_than_ago: cÃ¡ch Ä‘Ã¢y hÆ¡n
-  label_ago: cÃ¡ch Ä‘Ã¢y
-  label_contains: chá»©a
-  label_not_contains: khÃ´ng chá»©a
-  label_day_plural: ngÃ y
-  label_repository: Kho lÆ°u trá»¯
-  label_repository_plural: Kho lÆ°u trá»¯
-  label_browse: Duyá»‡t
-  label_modification: "%{count} thay Ä‘á»•i"
-  label_modification_plural: "%{count} thay Ä‘á»•i"
-  label_revision: Báº£n Ä‘iá»u chá»‰nh
-  label_revision_plural: Báº£n Ä‘iá»u chá»‰nh
-  label_associated_revisions: Associated revisions
-  label_added: thÃªm
-  label_modified: Ä‘á»•i
-  label_copied: chÃ©p
-  label_renamed: Ä‘á»•i tÃªn
-  label_deleted: xÃ³a
-  label_latest_revision: Báº£n Ä‘iá»u chá»‰nh cuá»‘i cÃ¹ng
-  label_latest_revision_plural: Báº£n Ä‘iá»u chá»‰nh cuá»‘i cÃ¹ng
-  label_view_revisions: Xem cÃ¡c báº£n Ä‘iá»u chá»‰nh
-  label_max_size: Dung lÆ°á»£ng tá»‘i Ä‘a
-  label_sort_highest: LÃªn trÃªn cÃ¹ng
-  label_sort_higher: Dá»‹ch lÃªn
-  label_sort_lower: Dá»‹ch xuá»‘ng
-  label_sort_lowest: Xuá»‘ng dÆ°á»›i cÃ¹ng
-  label_roadmap: Káº¿ hoáº¡ch
-  label_roadmap_due_in: "Háº¿t háº¡n trong %{value}"
-  label_roadmap_overdue: "Trá»… %{value}"
-  label_roadmap_no_issues: KhÃ´ng cÃ³ váº¥n Ä‘á» cho phiÃªn báº£n nÃ y
-  label_search: TÃ¬m
-  label_result_plural: Káº¿t quáº£
-  label_all_words: Má»i tá»«
-  label_wiki: Wiki
-  label_wiki_edit: Wiki edit
-  label_wiki_edit_plural: Thay Ä‘á»•i wiki
-  label_wiki_page: Trang wiki
-  label_wiki_page_plural: Trang wiki
-  label_index_by_title: Danh sÃ¡ch theo tÃªn
-  label_index_by_date: Danh sÃ¡ch theo ngÃ y
-  label_current_version: Báº£n hiá»‡n táº¡i
-  label_preview: Xem trÆ°á»›c
-  label_feed_plural: Feeds
-  label_changes_details: Chi tiáº¿t cá»§a má»i thay Ä‘á»•i
-  label_issue_tracking: Váº¥n Ä‘á»
-  label_spent_time: Thá»i gian
-  label_f_hour: "%{value} giá»"
-  label_f_hour_plural: "%{value} giá»"
-  label_time_tracking: Theo dÃµi thá»i gian
-  label_change_plural: Thay Ä‘á»•i
-  label_statistics: Thá»‘ng kÃª
-  label_commits_per_month: Commits per month
-  label_commits_per_author: Commits per author
-  label_view_diff: So sÃ¡nh
-  label_diff_inline: inline
-  label_diff_side_by_side: side by side
-  label_options: TÃ¹y chá»n
-  label_copy_workflow_from: Copy workflow from
-  label_permissions_report: Thá»‘ng kÃª cÃ¡c quyá»n
-  label_watched_issues: Chá»§ Ä‘á» Ä‘ang theo dÃµi
-  label_related_issues: LiÃªn quan
-  label_applied_status: Tráº¡ng thÃ¡i Ã¡p dá»¥ng
-  label_loading: Äang xá»­ lÃ½...
-  label_relation_new: Quan há»‡ má»›i
-  label_relation_delete: XÃ³a quan há»‡
-  label_relates_to: liÃªn quan
-  label_duplicates: trÃ¹ng vá»›i
-  label_duplicated_by: bá»‹ trÃ¹ng bá»Ÿi
-  label_blocks: cháº·n
-  label_blocked_by: cháº·n bá»Ÿi
-  label_precedes: Ä‘i trÆ°á»›c
-  label_follows: Ä‘i sau
-  label_end_to_start: cuá»‘i tá»›i Ä‘áº§u
-  label_end_to_end: cuá»‘i tá»›i cuá»‘i
-  label_start_to_start: Ä‘áº§u tá»› Ä‘áº§u
-  label_start_to_end: Ä‘áº§u tá»›i cuá»‘i
-  label_stay_logged_in: LÆ°u thÃ´ng tin Ä‘Äƒng nháº­p
-  label_disabled: bá»‹ vÃ´ hiá»‡u
-  label_show_completed_versions: Xem phiÃªn báº£n Ä‘Ã£ xong
-  label_me: tÃ´i
-  label_board: Diá»…n Ä‘Ã n
-  label_board_new: Táº¡o diá»…n Ä‘Ã n má»›i
-  label_board_plural: Diá»…n Ä‘Ã n
-  label_topic_plural: Chá»§ Ä‘á»
-  label_message_plural: Diá»…n Ä‘Ã n
-  label_message_last: BÃ i cuá»‘i
-  label_message_new: Táº¡o bÃ i má»›i
-  label_message_posted: ÄÃ£ thÃªm bÃ i viáº¿t
-  label_reply_plural: Há»“i Ã¢m
-  label_send_information: Gá»­i thÃ´ng tin Ä‘áº¿n ngÆ°á»i dÃ¹ng qua email
-  label_year: NÄƒm
-  label_month: ThÃ¡ng
-  label_week: Tuáº§n
-  label_date_from: Tá»«
-  label_date_to: Äáº¿n
-  label_language_based: Theo ngÃ´n ngá»¯ ngÆ°á»i dÃ¹ng
-  label_sort_by: "Sáº¯p xáº¿p theo %{value}"
-  label_send_test_email: Send a test email
-  label_feeds_access_key_created_on: "MÃ£ chá»©ng thá»±c RSS Ä‘Æ°á»£c táº¡o ra cÃ¡ch Ä‘Ã¢y %{value}"
-  label_module_plural: MÃ´-Ä‘un
-  label_added_time_by: "thÃªm bá»Ÿi %{author} cÃ¡ch Ä‘Ã¢y %{age}"
-  label_updated_time: "Cáº­p nháº­t cÃ¡ch Ä‘Ã¢y %{value}"
-  label_jump_to_a_project: Nháº£y Ä‘áº¿n dá»± Ã¡n...
-  label_file_plural: Táº­p tin
-  label_changeset_plural: Thay Ä‘á»•i
-  label_default_columns: Cá»™t máº·c Ä‘á»‹nh
-  label_no_change_option: (khÃ´ng Ä‘á»•i)
-  label_bulk_edit_selected_issues: Sá»­a nhiá»u váº¥n Ä‘á»
-  label_theme: Giao diá»‡n
-  label_default: Máº·c Ä‘á»‹nh
-  label_search_titles_only: Chá»‰ tÃ¬m trong tá»±a Ä‘á»
-  label_user_mail_option_all: "Má»i sá»± kiá»‡n trÃªn má»i dá»± Ã¡n cá»§a báº¡n"
-  label_user_mail_option_selected: "Má»i sá»± kiá»‡n trÃªn cÃ¡c dá»± Ã¡n Ä‘Æ°á»£c chá»n..."
-  label_user_mail_no_self_notified: "Äá»«ng gá»­i email vá» cÃ¡c thay Ä‘á»•i do chÃ­nh báº¡n thá»±c hiá»‡n"
-  label_registration_activation_by_email: account activation by email
-  label_registration_manual_activation: manual account activation
-  label_registration_automatic_activation: automatic account activation
-  label_display_per_page: "má»—i trang: %{value}"
-  label_age: Age
-  label_change_properties: Thay Ä‘á»•i thuá»™c tÃ­nh
-  label_general: Tá»•ng quan
-  label_more: Chi tiáº¿t
-  label_scm: SCM
-  label_plugins: MÃ´-Ä‘un
-  label_ldap_authentication: Chá»©ng thá»±c LDAP
-  label_downloads_abbr: Táº£i vá»
-  label_optional_description: MÃ´ táº£ bá»• sung
-  label_add_another_file: ThÃªm táº­p tin khÃ¡c
-  label_preferences: Cáº¥u hÃ¬nh
-  label_chronological_order: BÃ i cÅ© xáº¿p trÆ°á»›c
-  label_reverse_chronological_order: BÃ i má»›i xáº¿p trÆ°á»›c
-  label_planning: Káº¿ hoáº¡ch
-  label_incoming_emails: Nháº­n mail
-  label_generate_key: Táº¡o mÃ£
-  label_issue_watchers: Theo dÃµi
-  
-  button_login: ÄÄƒng nháº­p
-  button_submit: Gá»­i
-  button_save: LÆ°u
-  button_check_all: ÄÃ¡nh dáº¥u táº¥t cáº£
-  button_uncheck_all: Bá» dáº¥u táº¥t cáº£
-  button_delete: XÃ³a
-  button_create: Táº¡o
-  button_test: Kiá»ƒm tra
-  button_edit: Sá»­a
-  button_add: ThÃªm
-  button_change: Äá»•i
-  button_apply: Ãp dá»¥ng
-  button_clear: XÃ³a
-  button_lock: KhÃ³a
-  button_unlock: Má»Ÿ khÃ³a
-  button_download: Táº£i vá»
-  button_list: Liá»‡t kÃª
-  button_view: Xem
-  button_move: Chuyá»ƒn
-  button_back: Quay láº¡i
-  button_cancel: Bá» qua
-  button_activate: KÃ­ch hoáº¡t
-  button_sort: Sáº¯p xáº¿p
-  button_log_time: ThÃªm thá»i gian
-  button_rollback: Quay trá»Ÿ láº¡i phiÃªn báº£n nÃ y
-  button_watch: Theo dÃµi
-  button_unwatch: Bá» theo dÃµi
-  button_reply: Tráº£ lá»i
-  button_archive: ÄÃ³ng bÄƒng
-  button_unarchive: Xáº£ bÄƒng
-  button_reset: Táº¡o láº¡i
-  button_rename: Äá»•i tÃªn
-  button_change_password: Äá»•i máº­t mÃ£
-  button_copy: ChÃ©p
-  button_annotate: ChÃº giáº£i
-  button_update: Cáº­p nháº­t
-  button_configure: Cáº¥u hÃ¬nh
-  button_quote: TrÃ­ch dáº«n
-  
-  status_active: hoáº¡t Ä‘á»™ng
-  status_registered: Ä‘Äƒng kÃ½
-  status_locked: khÃ³a
-  
-  text_select_mail_notifications: Chá»n hÃ nh Ä‘á»™ng Ä‘á»‘i vá»›i má»—i email thÃ´ng bÃ¡o sáº½ gá»­i.
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 Ä‘á»ƒ chá»‰ khÃ´ng háº¡n cháº¿
-  text_project_destroy_confirmation: Are you sure you want to delete this project and related data ?
-  text_subprojects_destroy_warning: "Its subproject(s): %{value} will be also deleted."
-  text_workflow_edit: Select a role and a tracker to edit the workflow
-  text_are_you_sure: Báº¡n cháº¯c chá»©?
-  text_tip_issue_begin_day: ngÃ y báº¯t Ä‘áº§u
-  text_tip_issue_end_day: ngÃ y káº¿t thÃºc
-  text_tip_issue_begin_end_day: báº¯t Ä‘áº§u vÃ  káº¿t thÃºc cÃ¹ng ngÃ y
-  text_project_identifier_info: 'Chá»‰ cho phÃ©p chá»¯ cÃ¡i thÆ°á»ng (a-z), con sá»‘ vÃ  dáº¥u gáº¡ch ngang.<br />Sau khi lÆ°u, chá»‰ sá»‘ ID khÃ´ng thá»ƒ thay Ä‘á»•i.'
-  text_caracters_maximum: "Tá»‘i Ä‘a %{count} kÃ½ tá»±."
-  text_caracters_minimum: "Pháº£i gá»“m Ã­t nháº¥t %{count} kÃ½ tá»±."
-  text_length_between: "Length between %{min} and %{max} characters."
-  text_tracker_no_workflow: No workflow defined for this tracker
-  text_unallowed_characters: KÃ½ tá»± khÃ´ng há»£p lá»‡
-  text_comma_separated: Multiple values allowed (comma separated).
-  text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
-  text_issue_added: "Issue %{id} has been reported by %{author}."
-  text_issue_updated: "Issue %{id} has been updated by %{author}."
-  text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ?
-  text_issue_category_destroy_question: "Some issues (%{count}) are assigned to this category. What do you want to do ?"
-  text_issue_category_destroy_assignments: Remove category assignments
-  text_issue_category_reassign_to: Reassign issues to this category
-  text_user_mail_option: "Vá»›i cÃ¡c dá»± Ã¡n khÃ´ng Ä‘Æ°á»£c chá»n, báº¡n chá»‰ cÃ³ thá»ƒ nháº­n Ä‘Æ°á»£c thÃ´ng bÃ¡o vá» cÃ¡c váº¥n Ä‘á» báº¡n Ä‘Äƒng kÃ½ theo dÃµi hoáº·c cÃ³ liÃªn quan Ä‘áº¿n báº¡n (cháº³ng háº¡n, váº¥n Ä‘á» Ä‘Æ°á»£c gÃ¡n cho báº¡n)."
-  text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
-  text_load_default_configuration: Load the default configuration
-  text_status_changed_by_changeset: "Applied in changeset %{value}."
-  text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s) ?'
-  text_select_project_modules: 'Chá»n cÃ¡c mÃ´-Ä‘un cho dá»± Ã¡n:'
-  text_default_administrator_account_changed: Default administrator account changed
-  text_file_repository_writable: File repository writable
-  text_rmagick_available: RMagick available (optional)
-  text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do ?"
-  text_destroy_time_entries: Delete reported hours
-  text_assign_time_entries_to_project: Assign reported hours to the project
-  text_reassign_time_entries: 'Reassign reported hours to this issue:'
-  text_user_wrote: "%{value} wrote:"
-  text_enumeration_destroy_question: "%{count} objects are assigned to this value."
-  text_enumeration_category_reassign_to: 'Reassign them to this value:'
-  text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
-  
-  default_role_manager: Äiá»u hÃ nh
-  default_role_developer: PhÃ¡t triá»ƒn
-  default_role_reporter: BÃ¡o cÃ¡o
-  default_tracker_bug: Lá»—i
-  default_tracker_feature: TÃ­nh nÄƒng
-  default_tracker_support: Há»— trá»£
-  default_issue_status_new: Má»›i
-  default_issue_status_in_progress: In Progress
-  default_issue_status_resolved: Quyáº¿t tÃ¢m
-  default_issue_status_feedback: Pháº£n há»“i
-  default_issue_status_closed: ÄÃ³ng
-  default_issue_status_rejected: Tá»« chá»‘i
-  default_doc_category_user: TÃ i liá»‡u ngÆ°á»i dÃ¹ng
-  default_doc_category_tech: TÃ i liá»‡u ká»¹ thuáº­t
-  default_priority_low: Tháº¥p
-  default_priority_normal: BÃ¬nh thÆ°á»ng
-  default_priority_high: Cao
-  default_priority_urgent: Kháº©n cáº¥p
-  default_priority_immediate: Trung bÃ¬nh
-  default_activity_design: Thiáº¿t káº¿
-  default_activity_development: PhÃ¡t triá»ƒn
-  
-  enumeration_issue_priorities: Má»©c Ä‘á»™ Æ°u tiÃªn váº¥n Ä‘á»
-  enumeration_doc_categories: Chá»§ Ä‘á» tÃ i liá»‡u
-  enumeration_activities: Hoáº¡t Ä‘á»™ng (theo dÃµi thá»i gian)
-  
-  setting_plain_text_mail: mail dáº¡ng text Ä‘Æ¡n giáº£n (khÃ´ng dÃ¹ng HTML)
-  setting_gravatar_enabled: DÃ¹ng biá»ƒu tÆ°á»£ng Gravatar
-  permission_edit_project: Chá»‰nh dá»± Ã¡n
-  permission_select_project_modules: Chá»n mÃ´-Ä‘un
-  permission_manage_members: Quáº£n lÃ½ thÃ nh viÃªn
-  permission_manage_versions: Quáº£n lÃ½ phiÃªn báº£n
-  permission_manage_categories: Quáº£n lÃ½ chá»§ Ä‘á»
-  permission_add_issues: ThÃªm váº¥n Ä‘á»
-  permission_edit_issues: Sá»­a váº¥n Ä‘á»
-  permission_manage_issue_relations: Quáº£n lÃ½ quan há»‡ váº¥n Ä‘á»
-  permission_add_issue_notes: ThÃªm chÃº thÃ­ch
-  permission_edit_issue_notes: Sá»­a chÃº thÃ­ch
-  permission_edit_own_issue_notes: Sá»­a chÃº thÃ­ch cÃ¡ nhÃ¢n
-  permission_move_issues: Chuyá»ƒn váº¥n Ä‘á»
-  permission_delete_issues: XÃ³a váº¥n Ä‘á»
-  permission_manage_public_queries: Quáº£n lÃ½ truy cáº¥n cÃ´ng cá»™ng
-  permission_save_queries: LÆ°u truy váº¥n
-  permission_view_gantt: Xem biá»ƒu Ä‘á»“ sá»± kiá»‡n
-  permission_view_calendar: Xem lá»‹ch
-  permission_view_issue_watchers: Xem cÃ¡c ngÆ°á»i theo dÃµi
-  permission_add_issue_watchers: ThÃªm ngÆ°á»i theo dÃµi
-  permission_log_time: LÆ°u thá»i gian Ä‘Ã£ tá»‘n
-  permission_view_time_entries: Xem thá»i gian Ä‘Ã£ tá»‘n
-  permission_edit_time_entries: Xem nháº­t kÃ½ thá»i gian
-  permission_edit_own_time_entries: Sá»­a thá»i gian Ä‘Ã£ lÆ°u
-  permission_manage_news: Quáº£n lÃ½ tin má»›i
-  permission_comment_news: ChÃº thÃ­ch vÃ o tin má»›i
-  permission_manage_documents: Quáº£n lÃ½ tÃ i liá»‡u
-  permission_view_documents: Xem tÃ i liá»‡u
-  permission_manage_files: Quáº£n lÃ½ táº­p tin
-  permission_view_files: Xem táº­p tin
-  permission_manage_wiki: Quáº£n lÃ½ wiki
-  permission_rename_wiki_pages: Äá»•i tÃªn trang wiki
-  permission_delete_wiki_pages: XÃ³a trang wiki
-  permission_view_wiki_pages: Xem wiki
-  permission_view_wiki_edits: Xem lÆ°á»£c sá»­ trang wiki
-  permission_edit_wiki_pages: Sá»­a trang wiki
-  permission_delete_wiki_pages_attachments: XÃ³a tá»‡p Ä‘Ã­nh kÃ¨m
-  permission_protect_wiki_pages: Báº£o vá»‡ trang wiki
-  permission_manage_repository: Quáº£n lÃ½ kho lÆ°u trá»¯
-  permission_browse_repository: Duyá»‡t kho lÆ°u trá»¯
-  permission_view_changesets: Xem cÃ¡c thay Ä‘á»•i
-  permission_commit_access: Truy cáº­p commit
-  permission_manage_boards: Quáº£n lÃ½ diá»…n Ä‘Ã n
-  permission_view_messages: Xem bÃ i viáº¿t
-  permission_add_messages: Gá»­i bÃ i viáº¿t
-  permission_edit_messages: Sá»­a bÃ i viáº¿t
-  permission_edit_own_messages: Sá»­a bÃ i viáº¿t cÃ¡ nhÃ¢n
-  permission_delete_messages: XÃ³a bÃ i viáº¿t
-  permission_delete_own_messages: XÃ³a bÃ i viáº¿t cÃ¡ nhÃ¢n
-  label_example: VÃ­ dá»¥
-  text_repository_usernames_mapping: "Chá»n hoáº·c cáº­p nháº­t Ã¡nh xáº¡ ngÆ°á»i dÃ¹ng há»‡ thá»‘ng vá»›i ngÆ°á»i dÃ¹ng trong kho lÆ°u trá»¯.\nNhá»¯ng trÆ°á»ng há»£p trÃ¹ng há»£p vá» tÃªn vÃ  email sáº½ Ä‘Æ°á»£c tá»± Ä‘á»™ng Ã¡nh xáº¡."
-  permission_delete_own_messages: Delete own messages
-  label_user_activity: "%{value}'s activity"
-  label_updated_time_by: "Updated by %{author} %{age} ago"
-  text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
-  setting_diff_max_lines_displayed: Max number of diff lines displayed
-  text_plugin_assets_writable: Plugin assets directory writable
-  warning_attachments_not_saved: "%{count} file(s) could not be saved."
-  button_create_and_continue: Create and continue
-  text_custom_field_possible_values_info: 'One line for each value'
-  label_display: Display
-  field_editable: Editable
-  setting_repository_log_display_limit: Maximum number of revisions displayed on file log
-  setting_file_max_size_displayed: Max size of text files displayed inline
-  field_watcher: Watcher
-  setting_openid: Allow OpenID login and registration
-  field_identity_url: OpenID URL
-  label_login_with_open_id_option: or login with OpenID
-  field_content: Content
-  label_descending: Descending
-  label_sort: Sort
-  label_ascending: Ascending
-  label_date_from_to: From %{start} to %{end}
-  label_greater_or_equal: ">="
-  label_less_or_equal: <=
-  text_wiki_page_destroy_question: This page has %{descendants} child page(s) and descendant(s). What do you want to do?
-  text_wiki_page_reassign_children: Reassign child pages to this parent page
-  text_wiki_page_nullify_children: Keep child pages as root pages
-  text_wiki_page_destroy_children: Delete child pages and all their descendants
-  setting_password_min_length: Minimum password length
-  field_group_by: Group results by
-  mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
-  label_wiki_content_added: Wiki page added
-  mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
-  mail_body_wiki_content_added: The '%{id}' wiki page has been added by %{author}.
-  label_wiki_content_updated: Wiki page updated
-  mail_body_wiki_content_updated: The '%{id}' wiki page has been updated by %{author}.
-  permission_add_project: Create project
-  setting_new_project_user_role_id: Role given to a non-admin user who creates a project
-  label_view_all_revisions: View all revisions
-  label_tag: Tag
-  label_branch: Branch
-  error_no_tracker_in_project: No tracker is associated to this project. Please check the Project settings.
-  error_no_default_issue_status: No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").
-  text_journal_changed: "%{label} changed from %{old} to %{new}"
-  text_journal_set_to: "%{label} set to %{value}"
-  text_journal_deleted: "%{label} deleted (%{old})"
-  label_group_plural: Groups
-  label_group: Group
-  label_group_new: New group
-  label_time_entry_plural: Spent time
-  text_journal_added: "%{label} %{value} added"
-  field_active: Active
-  enumeration_system_activity: System Activity
-  permission_delete_issue_watchers: Delete watchers
-  version_status_closed: closed
-  version_status_locked: locked
-  version_status_open: open
-  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
-  label_user_anonymous: Anonymous
-  button_move_and_follow: Move and follow
-  setting_default_projects_modules: Default enabled modules for new projects
-  setting_gravatar_default: Default Gravatar image
-  field_sharing: Sharing
-  label_version_sharing_hierarchy: With project hierarchy
-  label_version_sharing_system: With all projects
-  label_version_sharing_descendants: With subprojects
-  label_version_sharing_tree: With project tree
-  label_version_sharing_none: Not shared
-  error_can_not_archive_project: This project can not be archived
-  button_duplicate: Duplicate
-  button_copy_and_follow: Copy and follow
-  label_copy_source: Source
-  setting_issue_done_ratio: Calculate the issue done ratio with
-  setting_issue_done_ratio_issue_status: Use the issue status
-  error_issue_done_ratios_not_updated: Issue done ratios not updated.
-  error_workflow_copy_target: Please select target tracker(s) and role(s)
-  setting_issue_done_ratio_issue_field: Use the issue field
-  label_copy_same_as_target: Same as target
-  label_copy_target: Target
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  error_workflow_copy_source: Please select a source tracker or role
-  label_update_issue_done_ratios: Update issue done ratios
-  setting_start_of_week: Start calendars on
-  permission_view_issues: View Issues
-  label_display_used_statuses_only: Only display statuses that are used by this tracker
-  label_revision_id: Revision %{value}
-  label_api_access_key: API access key
-  label_api_access_key_created_on: API access key created %{value} ago
-  label_feeds_access_key: RSS access key
-  notice_api_access_key_reseted: Your API access key was reset.
-  setting_rest_api_enabled: Enable REST web service
-  label_missing_api_access_key: Missing an API access key
-  label_missing_feeds_access_key: Missing a RSS access key
-  button_show: Show
-  text_line_separated: Multiple values allowed (one line for each value).
-  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
-  permission_add_subprojects: Create subprojects
-  label_subproject_new: New subproject
-  text_own_membership_delete_confirmation: |-
-    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
-    Are you sure you want to continue?
-  label_close_versions: Close completed versions
-  label_board_sticky: Sticky
-  label_board_locked: Locked
-  permission_export_wiki_pages: Export wiki pages
-  setting_cache_formatted_text: Cache formatted text
-  permission_manage_project_activities: Manage project activities
-  error_unable_delete_issue_status: Unable to delete issue status
-  label_profile: Profile
-  permission_manage_subtasks: Manage subtasks
-  field_parent_issue: Parent task
-  label_subtask_plural: Subtasks
-  label_project_copy_notifications: Send email notifications during the project copy
-  error_can_not_delete_custom_field: Unable to delete custom field
-  error_unable_to_connect: Unable to connect (%{value})
-  error_can_not_remove_role: This role is in use and can not be deleted.
-  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
-  field_principal: Principal
-  label_my_page_block: My page block
-  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
-  text_zoom_out: Zoom out
-  text_zoom_in: Zoom in
-  notice_unable_delete_time_entry: Unable to delete time log entry.
-  label_overall_spent_time: Overall spent time
-  field_time_entries: Log time
-  project_module_gantt: Gantt
-  project_module_calendar: Calendar
-  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
-  text_are_you_sure_with_children: Delete issue and all child issues?
-  field_text: Text field
-  label_user_mail_option_only_owner: Only for things I am the owner of
-  setting_default_notification_option: Default notification option
-  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
-  label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
-  field_member_of_group: Assignee's group
-  field_assigned_to_role: Assignee's role
-  notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
-  field_visible: Visible
-  setting_emails_header: Emails header
-  setting_commit_logtime_activity_id: Activity for logged time
-  text_time_logged_by_changeset: Applied in changeset %{value}.
-  setting_commit_logtime_enabled: Enable time logging
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
-  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
-  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
-  label_my_queries: My custom queries
-  text_journal_changed_no_detail: "%{label} updated"
-  label_news_comment_added: Comment added to a news
-  button_expand_all: Expand all
-  button_collapse_all: Collapse all
-  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
-  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
-  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
-  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Non member
-  label_issue_note_added: Note added
-  label_issue_status_updated: Status updated
-  label_issue_priority_updated: Priority updated
-  label_issues_visibility_own: Issues created by or assigned to the user
-  field_issues_visibility: Issues visibility
-  label_issues_visibility_all: All issues
-  permission_set_own_issues_private: Set own issues public or private
-  field_is_private: Private
-  permission_set_issues_private: Set issues public or private
-  label_issues_visibility_public: All non private issues
-  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
-  field_commit_logs_encoding: Commit messages encoding
-  field_scm_path_encoding: Path encoding
-  text_scm_path_encoding_note: "Default: UTF-8"
-  field_path_to_repository: Path to repository
-  field_root_directory: Root directory
-  field_cvs_module: Module
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Command
-  text_scm_command_version: Version
-  label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
-  notice_issue_successful_create: Issue %{id} created.
-  label_between: between
-  setting_issue_group_assignment: Allow issue assignment to groups
-  label_diff: diff
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
-  description_query_sort_criteria_direction: Sort direction
-  description_project_scope: Search scope
-  description_filter: Filter
-  description_user_mail_notification: Mail notification settings
-  description_date_from: Enter start date
-  description_message_content: Message content
-  description_available_columns: Available Columns
-  description_date_range_interval: Choose range by selecting start and end date
-  description_issue_category_reassign: Choose issue category
-  description_search: Searchfield
-  description_notes: Notes
-  description_date_range_list: Choose range from list
-  description_choose_project: Projects
-  description_date_to: Enter end date
-  description_query_sort_criteria_attribute: Sort attribute
-  description_wiki_subpages_reassign: Choose new parent page
-  description_selected_columns: Selected Columns
-  label_parent_revision: Parent
-  label_child_revision: Child
-  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
-  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
-  button_edit_section: Edit this section
-  setting_repositories_encodings: Attachments and repositories encodings
-  description_all_columns: All Columns
-  button_export: Export
-  label_export_options: "%{export_format} export options"
-  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ee/ee7fe9ed41ae5054b215eb20ccb460e8dc835ca3.svn-base
--- a/.svn/pristine/ee/ee7fe9ed41ae5054b215eb20ccb460e8dc835ca3.svn-base
+++ /dev/null
@@ -1,31 +0,0 @@
---- 
-user_preferences_001: 
-  others: |
-    --- 
-    :my_page_layout: 
-      left: 
-      - latestnews
-      - documents
-      right: 
-      - issuesassignedtome
-      top: 
-      - calendar
-
-  id: 1
-  user_id: 1
-  hide_mail: true
-user_preferences_002: 
-  others: |
-    --- 
-    :my_page_layout: 
-      left: 
-      - latestnews
-      - documents
-      right: 
-      - issuesassignedtome
-      top: 
-      - calendar
-  
-  id: 2
-  user_id: 3
-  hide_mail: false
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ee/eeae244657a9490b90284a25f402eeaf38cbe9f8.svn-base
--- a/.svn/pristine/ee/eeae244657a9490b90284a25f402eeaf38cbe9f8.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-// ** I18N
-
-// Calendar ÐœÐš language
-// Author: Ilin Tatabitovski, <itatabitovski@gmail.com>
-// Encoding: UTF-8
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Ð½ÐµÐ´ÐµÐ»Ð°",
- "Ð¿Ð¾Ð½ÐµÐ´ÐµÐ»Ð½Ð¸Ðº",
- "Ð²Ñ‚Ð¾Ñ€Ð½Ð¸Ðº",
- "ÑÑ€ÐµÐ´Ð°",
- "Ñ‡ÐµÑ‚Ð²Ñ€Ñ‚Ð¾Ðº",
- "Ð¿ÐµÑ‚Ð¾Ðº",
- "ÑÐ°Ð±Ð¾Ñ‚Ð°",
- "Ð½ÐµÐ´ÐµÐ»Ð°");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Ð½ÐµÐ´",
- "Ð¿Ð¾Ð½",
- "Ð²Ñ‚Ð¾",
- "ÑÑ€Ðµ",
- "Ñ‡ÐµÑ‚",
- "Ð¿ÐµÑ‚",
- "ÑÐ°Ð±",
- "Ð½ÐµÐ´");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Ñ˜Ð°Ð½ÑƒÐ°Ñ€Ð¸",
- "Ñ„ÐµÐ²Ñ€ÑƒÐ°Ñ€Ð¸",
- "Ð¼Ð°Ñ€Ñ‚",
- "Ð°Ð¿Ñ€Ð¸Ð»",
- "Ð¼Ð°Ñ˜",
- "Ñ˜ÑƒÐ½Ð¸",
- "Ñ˜ÑƒÐ»Ð¸",
- "Ð°Ð²Ð³ÑƒÑÑ‚",
- "ÑÐµÐ¿Ñ‚ÐµÐ¼Ð²Ñ€Ð¸",
- "Ð¾ÐºÑ‚Ð¾Ð¼Ð²Ñ€Ð¸",
- "Ð½Ð¾ÐµÐ¼Ð²Ñ€Ð¸",
- "Ð´ÐµÐºÐµÐ¼Ð²Ñ€Ð¸");
-
-// short month names
-Calendar._SMN = new Array
-("Ñ˜Ð°Ð½",
- "Ñ„ÐµÐ²",
- "Ð¼Ð°Ñ€",
- "Ð°Ð¿Ñ€",
- "Ð¼Ð°Ñ˜",
- "Ñ˜ÑƒÐ½",
- "Ñ˜ÑƒÐ»",
- "Ð°Ð²Ð³",
- "ÑÐµÐ¿",
- "Ð¾ÐºÑ‚",
- "Ð½Ð¾Ðµ",
- "Ð´ÐµÐº");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Ð—Ð° ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ð¾Ñ‚";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"Ð—Ð° Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð° Ð²ÐµÑ€Ð·Ð¸Ñ˜Ð° Ð¿Ð¾ÑÐµÑ‚Ð¸: http://www.dynarch.com/projects/calendar/\n" +
-"Ð”Ð¸ÑÑ‚Ñ€Ð¸Ð±ÑƒÐ¸Ñ€Ð°Ð½Ð¾ Ð¿Ð¾Ð´ GNU LGPL.  Ð’Ð¸Ð´Ð¸ http://gnu.org/licenses/lgpl.html Ð·Ð° Ð´ÐµÑ‚Ð°Ð»Ð¸." +
-"\n\n" +
-"Ð‘Ð¸Ñ€Ð°ÑšÐµ Ð½Ð° Ð´Ð°Ñ‚Ð°:\n" +
-"- ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸ Ð³Ð¸ \xab, \xbb ÐºÐ¾Ð¿Ñ‡Ð¸ÑšÐ°Ñ‚Ð° Ð·Ð° Ð´Ð° Ð¸Ð·Ð±ÐµÑ€ÐµÑˆ Ð³Ð¾Ð´Ð¸Ð½Ð°\n" +
-"- ÐšÐ¾Ñ€Ð¸ÑÑ‚Ð¸ Ð³Ð¸ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ÐºÐ¾Ð¿Ñ‡Ð¸ÑšÐ°Ñ‚Ð° Ð·Ð° Ð´Ð° Ð¸Ð·Ð±ÐµÑ€Ðµ Ð¼ÐµÑÐµÑ†Ð¸\n" +
-"- Ð”Ñ€Ð¶Ð¸ Ð³Ð¾ Ð¿Ñ€Ð¸Ñ‚Ð¸ÑÐ½Ð°Ñ‚Ð¾ ÐºÐ¾Ð¿Ñ‡ÐµÑ‚Ð¾ Ð½Ð° Ð³Ð»ÑƒÐ²Ñ‡ÐµÑ‚Ð¾ Ð½Ð° Ð±Ð¸Ð»Ð¾ ÐºÐ¾Ðµ ÐºÐ¾Ð¿Ñ‡Ðµ Ð·Ð° Ð¿Ð¾Ð±Ñ€Ð·Ð¾ Ð±Ð¸Ñ€Ð°ÑšÐµ.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Ð‘Ð¸Ñ€Ð°ÑšÐµ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ:\n" +
-"- ÐšÐ»Ð¸Ðº Ð½Ð° Ð²Ñ€ÐµÐ¼ÐµÐ½ÑÐºÐ¸Ñ‚Ðµ Ð´ÐµÐ»Ð¾Ð²Ð¸ Ð·Ð° Ð´Ð° Ð³Ð¾ Ð·Ð³Ð¾Ð»ÐµÐ¼Ð¸Ñˆ\n" +
-"- Ð¸Ð»Ð¸ Shift-ÐºÐ»Ð¸Ðº Ð´Ð° Ð³Ð¾ Ð½Ð°Ð¼Ð°Ð»Ð¸Ñˆ\n" +
-"- Ð¸Ð»Ð¸ ÐºÐ»Ð¸Ðº Ð¸ Ð²Ð»ÐµÑ‡Ð¸ Ð·Ð° Ð¿Ð¾Ð±Ñ€Ð·Ð¾ Ð±Ð¸Ñ€Ð°ÑšÐµ.";
-
-Calendar._TT["PREV_YEAR"] = "ÐŸÑ€ÐµÑ‚Ñ…Ð¾Ð´Ð½Ð° Ð³Ð¾Ð´Ð¸Ð½Ð° (Ð´Ñ€Ð¶Ð¸ Ð·Ð° Ð¼ÐµÐ½Ð¸)";
-Calendar._TT["PREV_MONTH"] = "ÐŸÑ€ÐµÑ‚Ñ…Ð¾Ð´ÐµÐ½ Ð¼ÐµÑÐµÑ† (Ð´Ñ€Ð¶Ð¸ Ð·Ð° Ð¼ÐµÐ½Ð¸)";
-Calendar._TT["GO_TODAY"] = "Go Today";
-Calendar._TT["NEXT_MONTH"] = "Ð¡Ð»ÐµÐ´ÐµÐ½ Ð¼ÐµÑÐµÑ† (Ð´Ñ€Ð¶Ð¸ Ð·Ð° Ð¼ÐµÐ½Ð¸)";
-Calendar._TT["NEXT_YEAR"] = "Ð¡Ð»ÐµÐ´Ð½Ð° Ð³Ð¾Ð´Ð¸Ð½Ð° (Ð´Ñ€Ð¶Ð¸ Ð·Ð° Ð¼ÐµÐ½Ð¸)";
-Calendar._TT["SEL_DATE"] = "Ð˜Ð·Ð±ÐµÑ€Ð¸ Ð´Ð°Ñ‚Ð°";
-Calendar._TT["DRAG_TO_MOVE"] = "Ð’Ð»ÐµÑ‡Ð¸ Ð´Ð° Ð¿Ð¾Ð¼ÐµÑÑ‚Ð¸Ñˆ";
-Calendar._TT["PART_TODAY"] = " (Ð´ÐµÐ½ÐµÑ)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "ÐŸÑ€Ð¸ÐºÐ°Ð¶Ð¸ %s Ð¿Ñ€Ð²Ð¾";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Ð—Ð°Ñ‚Ð²Ð¾Ñ€Ð¸";
-Calendar._TT["TODAY"] = "Ð”ÐµÐ½ÐµÑ";
-Calendar._TT["TIME_PART"] = "(Shift-)ÐšÐ»Ð¸Ðº Ð¸Ð»Ð¸ Ð²Ð»ÐµÑ‡Ð¸ Ð·Ð° Ð´Ð° Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸Ñˆ Ð²Ñ€ÐµÐ´Ð½Ð¾ÑÑ‚";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b";
-
-Calendar._TT["WK"] = "Ð½ÐµÐ´";
-Calendar._TT["TIME"] = "Ð’Ñ€ÐµÐ¼Ðµ:";
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ee/eeb4e06614636c29295cbb5c3157a7ad6e968c68.svn-base
--- a/.svn/pristine/ee/eeb4e06614636c29295cbb5c3157a7ad6e968c68.svn-base
+++ /dev/null
@@ -1,2 +0,0 @@
-<p>This is a test email sent by Redmine.<br />
-Redmine URL: <%= auto_link(@url) %></p>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ef/ef01ace269b8f950664d9b52e99400c8a56e9cdf.svn-base
--- /dev/null
+++ b/.svn/pristine/ef/ef01ace269b8f950664d9b52e99400c8a56e9cdf.svn-base
@@ -0,0 +1,109 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class FilesControllerTest < ActionController::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :journals, :journal_details,
+           :attachments,
+           :versions
+
+  def setup
+    @request.session[:user_id] = nil
+    Setting.default_language = 'en'
+  end
+
+  def test_index
+    get :index, :project_id => 1
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:containers)
+
+    # file attached to the project
+    assert_tag :a, :content => 'project_file.zip',
+                   :attributes => { :href => '/attachments/download/8/project_file.zip' }
+
+    # file attached to a project's version
+    assert_tag :a, :content => 'version_file.zip',
+                   :attributes => { :href => '/attachments/download/9/version_file.zip' }
+  end
+
+  def test_new
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_tag 'select', :attributes => {:name => 'version_id'}
+  end
+
+  def test_new_without_versions
+    Version.delete_all
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+
+    assert_no_tag 'select', :attributes => {:name => 'version_id'}
+  end
+
+  def test_create_file
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+    ActionMailer::Base.deliveries.clear
+
+    with_settings :notified_events => %w(file_added) do
+      assert_difference 'Attachment.count' do
+        post :create, :project_id => 1, :version_id => '',
+             :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
+        assert_response :redirect
+      end
+    end
+    assert_redirected_to '/projects/ecookbook/files'
+    a = Attachment.order('created_on DESC').first
+    assert_equal 'testfile.txt', a.filename
+    assert_equal Project.find(1), a.container
+
+    mail = ActionMailer::Base.deliveries.last
+    assert_not_nil mail
+    assert_equal "[eCookbook] New file", mail.subject
+    assert_mail_body_match 'testfile.txt', mail
+  end
+
+  def test_create_version_file
+    set_tmp_attachments_directory
+    @request.session[:user_id] = 2
+
+    assert_difference 'Attachment.count' do
+      post :create, :project_id => 1, :version_id => '2',
+           :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
+      assert_response :redirect
+    end
+    assert_redirected_to '/projects/ecookbook/files'
+    a = Attachment.order('created_on DESC').first
+    assert_equal 'testfile.txt', a.filename
+    assert_equal Version.find(2), a.container
+  end
+
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ef/ef19c67700749f66ae99f78b3003842af950afbb.svn-base
--- a/.svn/pristine/ef/ef19c67700749f66ae99f78b3003842af950afbb.svn-base
+++ /dev/null
@@ -1,2 +0,0 @@
-module <%= class_name %>Helper
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f0/f0263c221f5ea74d2c30c55c3240a08d7cddc2f4.svn-base
--- /dev/null
+++ b/.svn/pristine/f0/f0263c221f5ea74d2c30c55c3240a08d7cddc2f4.svn-base
@@ -0,0 +1,116 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class TimeEntryActivityTest < ActiveSupport::TestCase
+  fixtures :enumerations, :time_entries, :custom_fields
+
+  include Redmine::I18n
+
+  def test_should_be_an_enumeration
+    assert TimeEntryActivity.ancestors.include?(Enumeration)
+  end
+
+  def test_objects_count
+    assert_equal 3, TimeEntryActivity.find_by_name("Design").objects_count
+    assert_equal 2, TimeEntryActivity.find_by_name("Development").objects_count
+  end
+
+  def test_option_name
+    assert_equal :enumeration_activities, TimeEntryActivity.new.option_name
+  end
+
+  def test_create_with_custom_field
+    field = TimeEntryActivityCustomField.find_by_name('Billable')
+    e = TimeEntryActivity.new(:name => 'Custom Data')
+    e.custom_field_values = {field.id => "1"}
+    assert e.save
+
+    e.reload
+    assert_equal "1", e.custom_value_for(field).value
+  end
+
+  def test_create_without_required_custom_field_should_fail
+    set_language_if_valid 'en'
+    field = TimeEntryActivityCustomField.find_by_name('Billable')
+    field.update_attribute(:is_required, true)
+
+    e = TimeEntryActivity.new(:name => 'Custom Data')
+    assert !e.save
+    assert_equal ["Billable can't be blank"], e.errors.full_messages
+  end
+
+  def test_create_with_required_custom_field_should_succeed
+    field = TimeEntryActivityCustomField.find_by_name('Billable')
+    field.update_attribute(:is_required, true)
+
+    e = TimeEntryActivity.new(:name => 'Custom Data')
+    e.custom_field_values = {field.id => "1"}
+    assert e.save
+  end
+
+  def test_update_with_required_custom_field_change
+    set_language_if_valid 'en'
+    field = TimeEntryActivityCustomField.find_by_name('Billable')
+    field.update_attribute(:is_required, true)
+
+    e = TimeEntryActivity.find(10)
+    assert e.available_custom_fields.include?(field)
+    # No change to custom field, record can be saved
+    assert e.save
+    # Blanking custom field, save should fail
+    e.custom_field_values = {field.id => ""}
+    assert !e.save
+    assert_equal ["Billable can't be blank"], e.errors.full_messages
+
+    # Update custom field to valid value, save should succeed
+    e.custom_field_values = {field.id => "0"}
+    assert e.save
+    e.reload
+    assert_equal "0", e.custom_value_for(field).value
+  end
+
+  def test_system_activity_with_child_in_use_should_be_in_use
+    project = Project.generate!
+    system_activity = TimeEntryActivity.create!(:name => 'Activity')
+    project_activity = TimeEntryActivity.create!(:name => 'Activity', :project => project, :parent_id => system_activity.id)
+
+    TimeEntry.generate!(:project => project, :activity => project_activity)
+
+    assert project_activity.in_use?
+    assert system_activity.in_use?
+  end
+
+  def test_destroying_a_system_activity_should_reassign_children_activities
+    project = Project.generate!
+    system_activity = TimeEntryActivity.create!(:name => 'Activity')
+    project_activity = TimeEntryActivity.create!(:name => 'Activity', :project => project, :parent_id => system_activity.id)
+
+    entries = [
+      TimeEntry.generate!(:project => project, :activity => system_activity),
+      TimeEntry.generate!(:project => project, :activity => project_activity)
+    ]
+
+    assert_difference 'TimeEntryActivity.count', -2 do
+      assert_nothing_raised do
+        assert system_activity.destroy(TimeEntryActivity.find_by_name('Development'))
+      end
+    end
+    assert entries.all? {|entry| entry.reload.activity.name == 'Development'}
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f0/f036a37a46cad981a63df7b8fce61d2e4da796f3.svn-base
--- a/.svn/pristine/f0/f036a37a46cad981a63df7b8fce61d2e4da796f3.svn-base
+++ /dev/null
@@ -1,312 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/abstract_adapter'
-
-module Redmine
-  module Scm
-    module Adapters
-      class BazaarAdapter < AbstractAdapter
-
-        # Bazaar executable name
-        BZR_BIN = Redmine::Configuration['scm_bazaar_command'] || "bzr"
-
-        class << self
-          def client_command
-            @@bin    ||= BZR_BIN
-          end
-
-          def sq_bin
-            @@sq_bin ||= shell_quote_command
-          end
-
-          def client_version
-            @@client_version ||= (scm_command_version || [])
-          end
-
-          def client_available
-            !client_version.empty?
-          end
-
-          def scm_command_version
-            scm_version = scm_version_from_command_line.dup
-            if scm_version.respond_to?(:force_encoding)
-              scm_version.force_encoding('ASCII-8BIT')
-            end
-            if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
-              m[2].scan(%r{\d+}).collect(&:to_i)
-            end
-          end
-
-          def scm_version_from_command_line
-            shellout("#{sq_bin} --version") { |io| io.read }.to_s
-          end
-        end
-
-        # Get info about the repository
-        def info
-          cmd_args = %w|revno|
-          cmd_args << bzr_target('')
-          info = nil
-          scm_cmd(*cmd_args) do |io|
-            if io.read =~ %r{^(\d+)\r?$}
-              info = Info.new({:root_url => url,
-                               :lastrev => Revision.new({
-                                 :identifier => $1
-                               })
-                             })
-            end
-          end
-          info
-        rescue ScmCommandAborted
-          return nil
-        end
-
-        # Returns an Entries collection
-        # or nil if the given path doesn't exist in the repository
-        def entries(path=nil, identifier=nil, options={})
-          path ||= ''
-          entries = Entries.new
-          identifier = -1 unless identifier && identifier.to_i > 0
-          cmd_args = %w|ls -v --show-ids|
-          cmd_args << "-r#{identifier.to_i}"
-          cmd_args << bzr_target(path)
-          scm_cmd(*cmd_args) do |io|
-            prefix = "#{url}/#{path}".gsub('\\', '/')
-            logger.debug "PREFIX: #{prefix}"
-            re = %r{^V\s+(#{Regexp.escape(prefix)})?(\/?)([^\/]+)(\/?)\s+(\S+)\r?$}
-            io.each_line do |line|
-              next unless line =~ re
-              entries << Entry.new({:name => $3.strip,
-                                    :path => ((path.empty? ? "" : "#{path}/") + $3.strip),
-                                    :kind => ($4.blank? ? 'file' : 'dir'),
-                                    :size => nil,
-                                    :lastrev => Revision.new(:revision => $5.strip)
-                                  })
-            end
-          end
-          if logger && logger.debug?
-            logger.debug("Found #{entries.size} entries in the repository for #{target(path)}")
-          end
-          entries.sort_by_name
-        rescue ScmCommandAborted
-          return nil
-        end
-
-        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
-          path ||= ''
-          identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : 'last:1'
-          identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1
-          revisions = Revisions.new
-          cmd_args = %w|log -v --show-ids|
-          cmd_args << "-r#{identifier_to}..#{identifier_from}"
-          cmd_args << bzr_target(path)
-          scm_cmd(*cmd_args) do |io|
-            revision = nil
-            parsing  = nil
-            io.each_line do |line|
-              if line =~ /^----/
-                revisions << revision if revision
-                revision = Revision.new(:paths => [], :message => '')
-                parsing = nil
-              else
-                next unless revision
-                if line =~ /^revno: (\d+)($|\s\[merge\]$)/
-                  revision.identifier = $1.to_i
-                elsif line =~ /^committer: (.+)$/
-                  revision.author = $1.strip
-                elsif line =~ /^revision-id:(.+)$/
-                  revision.scmid = $1.strip
-                elsif line =~ /^timestamp: (.+)$/
-                  revision.time = Time.parse($1).localtime
-                elsif line =~ /^    -----/
-                  # partial revisions
-                  parsing = nil unless parsing == 'message'
-                elsif line =~ /^(message|added|modified|removed|renamed):/
-                  parsing = $1
-                elsif line =~ /^  (.*)$/
-                  if parsing == 'message'
-                    revision.message << "#{$1}\n"
-                  else
-                    if $1 =~ /^(.*)\s+(\S+)$/
-                      path = $1.strip
-                      revid = $2
-                      case parsing
-                      when 'added'
-                        revision.paths << {:action => 'A', :path => "/#{path}", :revision => revid}
-                      when 'modified'
-                        revision.paths << {:action => 'M', :path => "/#{path}", :revision => revid}
-                      when 'removed'
-                        revision.paths << {:action => 'D', :path => "/#{path}", :revision => revid}
-                      when 'renamed'
-                        new_path = path.split('=>').last
-                        revision.paths << {:action => 'M', :path => "/#{new_path.strip}", :revision => revid} if new_path
-                      end
-                    end
-                  end
-                else
-                  parsing = nil
-                end
-              end
-            end
-            revisions << revision if revision
-          end
-          revisions
-        rescue ScmCommandAborted
-          return nil
-        end
-
-        def diff(path, identifier_from, identifier_to=nil)
-          path ||= ''
-          if identifier_to
-            identifier_to = identifier_to.to_i
-          else
-            identifier_to = identifier_from.to_i - 1
-          end
-          if identifier_from
-            identifier_from = identifier_from.to_i
-          end
-          diff = []
-          cmd_args = %w|diff|
-          cmd_args << "-r#{identifier_to}..#{identifier_from}"
-          cmd_args << bzr_target(path)
-          scm_cmd_no_raise(*cmd_args) do |io|
-            io.each_line do |line|
-              diff << line
-            end
-          end
-          diff
-        end
-
-        def cat(path, identifier=nil)
-          cat = nil
-          cmd_args = %w|cat|
-          cmd_args << "-r#{identifier.to_i}" if identifier && identifier.to_i > 0
-          cmd_args << bzr_target(path)
-          scm_cmd(*cmd_args) do |io|
-            io.binmode
-            cat = io.read
-          end
-          cat
-        rescue ScmCommandAborted
-          return nil
-        end
-
-        def annotate(path, identifier=nil)
-          blame = Annotate.new
-          cmd_args = %w|annotate -q --all|
-          cmd_args << "-r#{identifier.to_i}" if identifier && identifier.to_i > 0
-          cmd_args << bzr_target(path)
-          scm_cmd(*cmd_args) do |io|
-            author     = nil
-            identifier = nil
-            io.each_line do |line|
-              next unless line =~ %r{^(\d+) ([^|]+)\| (.*)$}
-              rev = $1
-              blame.add_line($3.rstrip,
-                 Revision.new(
-                  :identifier => rev,
-                  :revision   => rev,
-                  :author     => $2.strip
-                  ))
-            end
-          end
-          blame
-        rescue ScmCommandAborted
-          return nil
-        end
-
-        def self.branch_conf_path(path)
-          bcp = nil
-          m = path.match(%r{^(.*[/\\])\.bzr.*$})
-          if m
-            bcp = m[1]
-          else
-            bcp = path
-          end
-          bcp.gsub!(%r{[\/\\]$}, "")
-          if bcp
-            bcp = File.join(bcp, ".bzr", "branch", "branch.conf")
-          end
-          bcp
-        end
-
-        def append_revisions_only
-          return @aro if ! @aro.nil?
-          @aro = false
-          bcp = self.class.branch_conf_path(url)
-          if bcp && File.exist?(bcp)
-            begin
-              f = File::open(bcp, "r")
-              cnt = 0
-              f.each_line do |line|
-                l = line.chomp.to_s
-                if l =~ /^\s*append_revisions_only\s*=\s*(\w+)\s*$/
-                  str_aro = $1
-                  if str_aro.upcase == "TRUE"
-                    @aro = true
-                    cnt += 1
-                  elsif str_aro.upcase == "FALSE"
-                    @aro = false
-                    cnt += 1
-                  end
-                  if cnt > 1
-                    @aro = false
-                    break
-                  end
-                end
-              end
-            ensure
-              f.close
-            end
-          end
-          @aro
-        end
-
-        def scm_cmd(*args, &block)
-          full_args = []
-          full_args += args
-          ret = shellout(
-                   self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
-                   &block
-                   )
-          if $? && $?.exitstatus != 0
-            raise ScmCommandAborted, "bzr exited with non-zero status: #{$?.exitstatus}"
-          end
-          ret
-        end
-        private :scm_cmd
-
-        def scm_cmd_no_raise(*args, &block)
-          full_args = []
-          full_args += args
-          ret = shellout(
-                   self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
-                   &block
-                   )
-          ret
-        end
-        private :scm_cmd_no_raise
-
-        def bzr_target(path)
-          target(path, false)
-        end
-        private :bzr_target
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f0/f06269896f65f1e606b0906f13f624ded16897a7.svn-base
--- a/.svn/pristine/f0/f06269896f65f1e606b0906f13f624ded16897a7.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-* Fake HTTP method from OpenID server since they only support a GET. Eliminates the need to set an extra route to match the server's reply. [Josh Peek]
-
-* OpenID 2.0 recommends that forms should use the field name "openid_identifier" rather than "openid_url" [Josh Peek]
-
-* Return open_id_response.display_identifier to the application instead of .endpoints.claimed_id. [nbibler]
-
-* Add Timeout protection [Rick]
-
-* An invalid identity url passed through authenticate_with_open_id will no longer raise an InvalidOpenId exception. Instead it will return Result[:missing] to the completion block.
-
-* Allow a return_to option to be used instead of the requested url [Josh Peek]
-
-* Updated plugin to use Ruby OpenID 2.x.x [Josh Peek]
-
-* Tied plugin to ruby-openid 1.1.4 gem until we can make it compatible with 2.x [DHH]
-
-* Use URI instead of regexps to normalize the URL and gain free, better matching #8136 [dkubb]
-
-* Allow -'s in #normalize_url [Rick]
-
-* remove instance of mattr_accessor, it was breaking tests since they don't load ActiveSupport.  Fix Timeout test [Rick]
-
-* Throw a InvalidOpenId exception instead of just a RuntimeError when the URL can't be normalized [DHH]
-
-* Just use the path for the return URL, so extra query parameters don't interfere [DHH]
-
-* Added a new default database-backed store after experiencing trouble with the filestore on NFS. The file store is still available as an option [DHH]
-
-* Added normalize_url and applied it to all operations going through the plugin [DHH]
-
-* Removed open_id? as the idea of using the same input box for both OpenID and username has died -- use using_open_id? instead (which checks for the presence of params[:openid_url] by default) [DHH]
-
-* Added OpenIdAuthentication::Result to make it easier to deal with default situations where you don't care to do something particular for each error state [DHH]
-
-* Stop relying on root_url being defined, we can just grab the current url instead [DHH]
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f0/f06528e84b5415a40a72b9b0d4c4587fbdcb8aec.svn-base
--- a/.svn/pristine/f0/f06528e84b5415a40a72b9b0d4c4587fbdcb8aec.svn-base
+++ /dev/null
@@ -1,380 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * This file is part of DotClear.
- * Copyright (c) 2005 Nicolas Martin & Olivier Meunier and contributors. All
- * rights reserved.
- *
- * DotClear is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * DotClear is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with DotClear; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * ***** END LICENSE BLOCK *****
-*/
-
-/* Modified by JP LANG for textile formatting */
-
-function jsToolBar(textarea) {
-	if (!document.createElement) { return; }
-	
-	if (!textarea) { return; }
-	
-	if ((typeof(document["selection"]) == "undefined")
-	&& (typeof(textarea["setSelectionRange"]) == "undefined")) {
-		return;
-	}
-	
-	this.textarea = textarea;
-	
-	this.editor = document.createElement('div');
-	this.editor.className = 'jstEditor';
-	
-	this.textarea.parentNode.insertBefore(this.editor,this.textarea);
-	this.editor.appendChild(this.textarea);
-	
-	this.toolbar = document.createElement("div");
-	this.toolbar.className = 'jstElements';
-	this.editor.parentNode.insertBefore(this.toolbar,this.editor);
-	
-	// Dragable resizing (only for gecko)
-	if (this.editor.addEventListener)
-	{
-		this.handle = document.createElement('div');
-		this.handle.className = 'jstHandle';
-		var dragStart = this.resizeDragStart;
-		var This = this;
-		this.handle.addEventListener('mousedown',function(event) { dragStart.call(This,event); },false);
-		// fix memory leak in Firefox (bug #241518)
-		window.addEventListener('unload',function() { 
-				var del = This.handle.parentNode.removeChild(This.handle);
-				delete(This.handle);
-		},false);
-		
-		this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling);
-	}
-	
-	this.context = null;
-	this.toolNodes = {}; // lorsque la toolbar est dessinÃ©e , cet objet est garni 
-					// de raccourcis vers les Ã©lÃ©ments DOM correspondants aux outils.
-}
-
-function jsButton(title, fn, scope, className) {
-    if(typeof jsToolBar.strings == 'undefined') {
-      this.title = title || null;
-    } else {
-      this.title = jsToolBar.strings[title] || title || null;
-    }
-	this.fn = fn || function(){};
-	this.scope = scope || null;
-	this.className = className || null;
-}
-jsButton.prototype.draw = function() {
-	if (!this.scope) return null;
-	
-	var button = document.createElement('button');
-	button.setAttribute('type','button');
-	button.tabIndex = 200;
-	if (this.className) button.className = this.className;
-	button.title = this.title;
-	var span = document.createElement('span');
-	span.appendChild(document.createTextNode(this.title));
-	button.appendChild(span);
-	
-	if (this.icon != undefined) {
-		button.style.backgroundImage = 'url('+this.icon+')';
-	}
-	if (typeof(this.fn) == 'function') {
-		var This = this;
-		button.onclick = function() { try { This.fn.apply(This.scope, arguments) } catch (e) {} return false; };
-	}
-	return button;
-}
-
-function jsSpace(id) {
-	this.id = id || null;
-	this.width = null;
-}
-jsSpace.prototype.draw = function() {
-	var span = document.createElement('span');
-	if (this.id) span.id = this.id;
-	span.appendChild(document.createTextNode(String.fromCharCode(160)));
-	span.className = 'jstSpacer';
-	if (this.width) span.style.marginRight = this.width+'px';
-	
-	return span;
-} 
-
-function jsCombo(title, options, scope, fn, className) {
-	this.title = title || null;
-	this.options = options || null;
-	this.scope = scope || null;
-	this.fn = fn || function(){};
-	this.className = className || null;
-}
-jsCombo.prototype.draw = function() {
-	if (!this.scope || !this.options) return null;
-
-	var select = document.createElement('select');
-	if (this.className) select.className = className;
-	select.title = this.title;
-	
-	for (var o in this.options) {
-		//var opt = this.options[o];
-		var option = document.createElement('option');
-		option.value = o;
-		option.appendChild(document.createTextNode(this.options[o]));
-		select.appendChild(option);
-	}
-
-	var This = this;
-	select.onchange = function() {
-		try { 
-			This.fn.call(This.scope, this.value);
-		} catch (e) { alert(e); }
-
-		return false;
-	}
-
-	return select;
-}
-
-
-jsToolBar.prototype = {
-	base_url: '',
-	mode: 'wiki',
-	elements: {},
-	help_link: '',
-	
-	getMode: function() {
-		return this.mode;
-	},
-	
-	setMode: function(mode) {
-		this.mode = mode || 'wiki';
-	},
-	
-	switchMode: function(mode) {
-		mode = mode || 'wiki';
-		this.draw(mode);
-	},
-	
-	setHelpLink: function(link) {
-		this.help_link = link;
-	},
-	
-	button: function(toolName) {
-		var tool = this.elements[toolName];
-		if (typeof tool.fn[this.mode] != 'function') return null;
-		var b = new jsButton(tool.title, tool.fn[this.mode], this, 'jstb_'+toolName);
-		if (tool.icon != undefined) b.icon = tool.icon;
-		return b;
-	},
-	space: function(toolName) {
-		var tool = new jsSpace(toolName)
-		if (this.elements[toolName].width !== undefined)
-			tool.width = this.elements[toolName].width;
-		return tool;
-	},
-	combo: function(toolName) {
-		var tool = this.elements[toolName];
-		var length = tool[this.mode].list.length;
-
-		if (typeof tool[this.mode].fn != 'function' || length == 0) {
-			return null;
-		} else {
-			var options = {};
-			for (var i=0; i < length; i++) {
-				var opt = tool[this.mode].list[i];
-				options[opt] = tool.options[opt];
-			}
-			return new jsCombo(tool.title, options, this, tool[this.mode].fn);
-		}
-	},
-	draw: function(mode) {
-		this.setMode(mode);
-		
-		// Empty toolbar
-		while (this.toolbar.hasChildNodes()) {
-			this.toolbar.removeChild(this.toolbar.firstChild)
-		}
-		this.toolNodes = {}; // vide les raccourcis DOM/**/
-
-		var h = document.createElement('div');
-		h.className = 'help'
-		h.innerHTML = this.help_link;
-		'<a href="/help/wiki_syntax.html" onclick="window.open(\'/help/wiki_syntax.html\', \'\', \'resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\'); return false;">Aide</a>';
-		this.toolbar.appendChild(h);
-
-		// Draw toolbar elements
-		var b, tool, newTool;
-		
-		for (var i in this.elements) {
-			b = this.elements[i];
-
-			var disabled =
-			b.type == undefined || b.type == ''
-			|| (b.disabled != undefined && b.disabled)
-			|| (b.context != undefined && b.context != null && b.context != this.context);
-			
-			if (!disabled && typeof this[b.type] == 'function') {
-				tool = this[b.type](i);
-				if (tool) newTool = tool.draw();
-				if (newTool) {
-					this.toolNodes[i] = newTool; //mÃ©morise l'accÃ¨s DOM pour usage Ã©ventuel ultÃ©rieur
-					this.toolbar.appendChild(newTool);
-				}
-			}
-		}
-	},
-	
-	singleTag: function(stag,etag) {
-		stag = stag || null;
-		etag = etag || stag;
-		
-		if (!stag || !etag) { return; }
-		
-		this.encloseSelection(stag,etag);
-	},
-	
-	encloseLineSelection: function(prefix, suffix, fn) {
-		this.textarea.focus();
-		
-		prefix = prefix || '';
-		suffix = suffix || '';
-		
-		var start, end, sel, scrollPos, subst, res;
-		
-		if (typeof(document["selection"]) != "undefined") {
-			sel = document.selection.createRange().text;
-		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
-			start = this.textarea.selectionStart;
-			end = this.textarea.selectionEnd;
-			scrollPos = this.textarea.scrollTop;
-			// go to the start of the line
-			start = this.textarea.value.substring(0, start).replace(/[^\r\n]*$/g,'').length;
-			// go to the end of the line
-            end = this.textarea.value.length - this.textarea.value.substring(end, this.textarea.value.length).replace(/^[^\r\n]*/, '').length;
-			sel = this.textarea.value.substring(start, end);
-		}
-		
-		if (sel.match(/ $/)) { // exclude ending space char, if any
-			sel = sel.substring(0, sel.length - 1);
-			suffix = suffix + " ";
-		}
-		
-		if (typeof(fn) == 'function') {
-			res = (sel) ? fn.call(this,sel) : fn('');
-		} else {
-			res = (sel) ? sel : '';
-		}
-		
-		subst = prefix + res + suffix;
-		
-		if (typeof(document["selection"]) != "undefined") {
-			document.selection.createRange().text = subst;
-			var range = this.textarea.createTextRange();
-			range.collapse(false);
-			range.move('character', -suffix.length);
-			range.select();
-		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
-			this.textarea.value = this.textarea.value.substring(0, start) + subst +
-			this.textarea.value.substring(end);
-			if (sel) {
-				this.textarea.setSelectionRange(start + subst.length, start + subst.length);
-			} else {
-				this.textarea.setSelectionRange(start + prefix.length, start + prefix.length);
-			}
-			this.textarea.scrollTop = scrollPos;
-		}
-	},
-	
-	encloseSelection: function(prefix, suffix, fn) {
-		this.textarea.focus();
-		
-		prefix = prefix || '';
-		suffix = suffix || '';
-		
-		var start, end, sel, scrollPos, subst, res;
-		
-		if (typeof(document["selection"]) != "undefined") {
-			sel = document.selection.createRange().text;
-		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
-			start = this.textarea.selectionStart;
-			end = this.textarea.selectionEnd;
-			scrollPos = this.textarea.scrollTop;
-			sel = this.textarea.value.substring(start, end);
-		}
-		
-		if (sel.match(/ $/)) { // exclude ending space char, if any
-			sel = sel.substring(0, sel.length - 1);
-			suffix = suffix + " ";
-		}
-		
-		if (typeof(fn) == 'function') {
-			res = (sel) ? fn.call(this,sel) : fn('');
-		} else {
-			res = (sel) ? sel : '';
-		}
-		
-		subst = prefix + res + suffix;
-		
-		if (typeof(document["selection"]) != "undefined") {
-			document.selection.createRange().text = subst;
-			var range = this.textarea.createTextRange();
-			range.collapse(false);
-			range.move('character', -suffix.length);
-			range.select();
-//			this.textarea.caretPos -= suffix.length;
-		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
-			this.textarea.value = this.textarea.value.substring(0, start) + subst +
-			this.textarea.value.substring(end);
-			if (sel) {
-				this.textarea.setSelectionRange(start + subst.length, start + subst.length);
-			} else {
-				this.textarea.setSelectionRange(start + prefix.length, start + prefix.length);
-			}
-			this.textarea.scrollTop = scrollPos;
-		}
-	},
-	
-	stripBaseURL: function(url) {
-		if (this.base_url != '') {
-			var pos = url.indexOf(this.base_url);
-			if (pos == 0) {
-				url = url.substr(this.base_url.length);
-			}
-		}
-		
-		return url;
-	}
-};
-
-/** Resizer
--------------------------------------------------------- */
-jsToolBar.prototype.resizeSetStartH = function() {
-	this.dragStartH = this.textarea.offsetHeight + 0;
-};
-jsToolBar.prototype.resizeDragStart = function(event) {
-	var This = this;
-	this.dragStartY = event.clientY;
-	this.resizeSetStartH();
-	document.addEventListener('mousemove', this.dragMoveHdlr=function(event){This.resizeDragMove(event);}, false);
-	document.addEventListener('mouseup', this.dragStopHdlr=function(event){This.resizeDragStop(event);}, false);
-};
-
-jsToolBar.prototype.resizeDragMove = function(event) {
-	this.textarea.style.height = (this.dragStartH+event.clientY-this.dragStartY)+'px';
-};
-
-jsToolBar.prototype.resizeDragStop = function(event) {
-	document.removeEventListener('mousemove', this.dragMoveHdlr, false);
-	document.removeEventListener('mouseup', this.dragStopHdlr, false);
-};
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f0/f08dcd38ee8d5ba63486881b16a9b731dc527af3.svn-base
--- /dev/null
+++ b/.svn/pristine/f0/f08dcd38ee8d5ba63486881b16a9b731dc527af3.svn-base
@@ -0,0 +1,15 @@
+class AddEnumerationsPosition < ActiveRecord::Migration
+  def self.up
+    add_column(:enumerations, :position, :integer, :default => 1) unless Enumeration.column_names.include?('position')
+    Enumeration.all.group_by(&:opt).each do |opt, enums|
+      enums.each_with_index do |enum, i|
+        # do not call model callbacks
+        Enumeration.update_all "position = #{i+1}", {:id => enum.id}
+      end
+    end
+  end
+
+  def self.down
+    remove_column :enumerations, :position
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f0/f099ca9ea131cb68a0611e1432ccc45e7766a247.svn-base
--- /dev/null
+++ b/.svn/pristine/f0/f099ca9ea131cb68a0611e1432ccc45e7766a247.svn-base
@@ -0,0 +1,158 @@
+<%= render :partial => 'action_menu' %>
+
+<h2><%= issue_heading(@issue) %></h2>
+
+<div class="<%= @issue.css_classes %> details">
+  <% if @prev_issue_id || @next_issue_id %>
+    <div class="next-prev-links contextual">
+      <%= link_to_if @prev_issue_id,
+                     "\xc2\xab #{l(:label_previous)}",
+                     (@prev_issue_id ? issue_path(@prev_issue_id) : nil),
+                     :title => "##{@prev_issue_id}" %> |
+      <% if @issue_position && @issue_count %>
+        <span class="position"><%= l(:label_item_position, :position => @issue_position, :count => @issue_count) %></span> |
+      <% end %>
+      <%= link_to_if @next_issue_id,
+                     "#{l(:label_next)} \xc2\xbb",
+                     (@next_issue_id ? issue_path(@next_issue_id) : nil),
+                     :title => "##{@next_issue_id}" %>
+    </div>
+  <% end %>
+
+  <%= avatar(@issue.author, :size => "50") %>
+
+<div class="subject">
+<%= render_issue_subject_with_tree(@issue) %>
+</div>
+        <p class="author">
+        <%= authoring @issue.created_on, @issue.author %>.
+        <% if @issue.created_on != @issue.updated_on %>
+        <%= l(:label_updated_time, time_tag(@issue.updated_on)).html_safe %>.
+        <% end %>
+        </p>
+
+<table class="attributes">
+<%= issue_fields_rows do |rows|
+  rows.left l(:field_status), h(@issue.status.name), :class => 'status'
+  rows.left l(:field_priority), h(@issue.priority.name), :class => 'priority'
+
+  unless @issue.disabled_core_fields.include?('assigned_to_id')
+    rows.left l(:field_assigned_to), avatar(@issue.assigned_to, :size => "14").to_s.html_safe + (@issue.assigned_to ? link_to_user(@issue.assigned_to) : "-"), :class => 'assigned-to'
+  end
+  unless @issue.disabled_core_fields.include?('category_id')
+    rows.left l(:field_category), h(@issue.category ? @issue.category.name : "-"), :class => 'category'
+  end
+  unless @issue.disabled_core_fields.include?('fixed_version_id')
+    rows.left l(:field_fixed_version), (@issue.fixed_version ? link_to_version(@issue.fixed_version) : "-"), :class => 'fixed-version'
+  end
+
+  unless @issue.disabled_core_fields.include?('start_date')
+    rows.right l(:field_start_date), format_date(@issue.start_date), :class => 'start-date'
+  end
+  unless @issue.disabled_core_fields.include?('due_date')
+    rows.right l(:field_due_date), format_date(@issue.due_date), :class => 'due-date'
+  end
+  unless @issue.disabled_core_fields.include?('done_ratio')
+    rows.right l(:field_done_ratio), progress_bar(@issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%"), :class => 'progress'
+  end
+  unless @issue.disabled_core_fields.include?('estimated_hours')
+    unless @issue.estimated_hours.nil?
+      rows.right l(:field_estimated_hours), l_hours(@issue.estimated_hours), :class => 'estimated-hours'
+    end
+  end
+  if User.current.allowed_to?(:view_time_entries, @project)
+    rows.right l(:label_spent_time), (@issue.total_spent_hours > 0 ? link_to(l_hours(@issue.total_spent_hours), project_issue_time_entries_path(@project, @issue)) : "-"), :class => 'spent-time'
+  end
+end %>
+<%= render_custom_fields_rows(@issue) %>
+<%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
+</table>
+
+<% if @issue.description? || @issue.attachments.any? -%>
+<hr />
+<% if @issue.description? %>
+<div class="description">
+  <div class="contextual">
+  <%= link_to l(:button_quote), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon icon-comment' if authorize_for('issues', 'edit') %>
+  </div>
+
+  <p><strong><%=l(:field_description)%></strong></p>
+  <div class="wiki">
+  <%= textilizable @issue, :description, :attachments => @issue.attachments %>
+  </div>
+</div>
+<% end %>
+<%= link_to_attachments @issue, :thumbnails => true %>
+<% end -%>
+
+<%= call_hook(:view_issues_show_description_bottom, :issue => @issue) %>
+
+<% if !@issue.leaf? || User.current.allowed_to?(:manage_subtasks, @project) %>
+<hr />
+<div id="issue_tree">
+<div class="contextual">
+  <%= link_to_new_subtask(@issue) if User.current.allowed_to?(:manage_subtasks, @project) %>
+</div>
+<p><strong><%=l(:label_subtask_plural)%></strong></p>
+<%= render_descendants_tree(@issue) unless @issue.leaf? %>
+</div>
+<% end %>
+
+<% if @relations.present? || User.current.allowed_to?(:manage_issue_relations, @project) %>
+<hr />
+<div id="relations">
+<%= render :partial => 'relations' %>
+</div>
+<% end %>
+
+</div>
+
+<% if @changesets.present? %>
+<div id="issue-changesets">
+<h3><%=l(:label_associated_revisions)%></h3>
+<%= render :partial => 'changesets', :locals => { :changesets => @changesets} %>
+</div>
+<% end %>
+
+<% if @journals.present? %>
+<div id="history">
+<h3><%=l(:label_history)%></h3>
+<%= render :partial => 'history', :locals => { :issue => @issue, :journals => @journals } %>
+</div>
+<% end %>
+
+
+<div style="clear: both;"></div>
+<%= render :partial => 'action_menu' %>
+
+<div style="clear: both;"></div>
+<% if @issue.editable? %>
+  <div id="update" style="display:none;">
+  <h3><%= l(:button_update) %></h3>
+  <%= render :partial => 'edit' %>
+  </div>
+<% end %>
+
+<% other_formats_links do |f| %>
+  <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
+  <%= f.link_to 'PDF' %>
+<% end %>
+
+<% html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %>
+
+<% content_for :sidebar do %>
+  <%= render :partial => 'issues/sidebar' %>
+
+  <% if User.current.allowed_to?(:add_issue_watchers, @project) ||
+    (@issue.watchers.present? && User.current.allowed_to?(:view_issue_watchers, @project)) %>
+    <div id="watchers">
+      <%= render :partial => 'watchers/watchers', :locals => {:watched => @issue} %>
+    </div>
+  <% end %>
+<% end %>
+
+<% content_for :header_tags do %>
+    <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@issue.project} - #{@issue.tracker} ##{@issue.id}: #{@issue.subject}") %>
+<% end %>
+
+<%= context_menu issues_context_menu_path %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f0/f0b4f0a0f8c219fb1d126652b6764f0f3fbb1b80.svn-base
--- /dev/null
+++ b/.svn/pristine/f0/f0b4f0a0f8c219fb1d126652b6764f0f3fbb1b80.svn-base
@@ -0,0 +1,1102 @@
+# Estonian localization for Redmine
+# Copyright (C) 2012 Kaitseministeerium
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+et:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: ltr
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%d.%m.%Y"
+      short: "%d.%b"
+      long: "%d. %B %Y"
+
+    day_names: [PÃ¼hapÃ¤ev, EsmaspÃ¤ev, TeisipÃ¤ev, KolmapÃ¤ev, NeljapÃ¤ev, Reede, LaupÃ¤ev]
+    abbr_day_names: [P, E, T, K, N, R, L]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, Jaanuar, Veebruar, MÃ¤rts, Aprill, Mai, Juuni, Juuli, August, September, Oktoober, November, Detsember]
+    abbr_month_names: [~, jaan, veebr, mÃ¤rts, apr, mai, juuni, juuli, aug, sept, okt, nov, dets]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%d.%m.%Y %H:%M"
+      time: "%H:%M"
+      short: "%d.%b %H:%M"
+      long: "%d. %B %Y %H:%M %z"
+    am: "enne lÃµunat"
+    pm: "peale lÃµunat"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "pool minutit"
+      less_than_x_seconds:
+        one:   "vÃ¤hem kui sekund"
+        other: "vÃ¤hem kui %{count} sekundit"
+      x_seconds:
+        one:   "1 sekund"
+        other: "%{count} sekundit"
+      less_than_x_minutes:
+        one:   "vÃ¤hem kui minut"
+        other: "vÃ¤hem kui %{count} minutit"
+      x_minutes:
+        one:   "1 minut"
+        other: "%{count} minutit"
+      about_x_hours:
+        one:   "umbes tund"
+        other: "umbes %{count} tundi"
+      x_hours:
+        one:   "1 tund"
+        other: "%{count} tundi"
+      x_days:
+        one:   "1 pÃ¤ev"
+        other: "%{count} pÃ¤eva"
+      about_x_months:
+        one:   "umbes kuu"
+        other: "umbes %{count} kuud"
+      x_months:
+        one:   "1 kuu"
+        other: "%{count} kuud"
+      about_x_years:
+        one:   "umbes aasta"
+        other: "umbes %{count} aastat"
+      over_x_years:
+        one:   "rohkem kui aasta"
+        other: "rohkem kui %{count} aastat"
+      almost_x_years:
+        one:   "peaaegu aasta"
+        other: "peaaegu %{count} aastat"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "bait"
+            other: "baiti"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "ja"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one: "1 viga ei vÃµimaldanud selle %{model} salvestamist"
+          other: "%{count} viga ei vÃµimaldanud selle %{model} salvestamist"
+      messages:
+        inclusion: "ei ole nimekirjas"
+        exclusion: "on reserveeritud"
+        invalid: "ei sobi"
+        confirmation: "ei lange kinnitusega kokku"
+        accepted: "peab olema aktsepteeritud"
+        empty: "ei vÃµi olla tÃ¼hi"
+        blank: "ei vÃµi olla tÃ¤itmata"
+        too_long: "on liiga pikk (lubatud on kuni %{count} mÃ¤rki)"
+        too_short: "on liiga lÃ¼hike (vaja on vÃ¤hemalt %{count} mÃ¤rki)"
+        wrong_length: "on vale pikkusega (peaks olema %{count} mÃ¤rki)"
+        taken: "on juba vÃµetud"
+        not_a_number: "ei ole arv"
+        not_a_date: "ei ole korrektne kuupÃ¤ev"
+        greater_than: "peab olema suurem kui %{count}"
+        greater_than_or_equal_to: "peab olema vÃµrdne vÃµi suurem kui %{count}"
+        equal_to: "peab vÃµrduma %{count}-ga"
+        less_than: "peab olema vÃ¤iksem kui %{count}"
+        less_than_or_equal_to: "peab olema vÃµrdne vÃµi vÃ¤iksem kui %{count}"
+        odd: "peab olema paaritu arv"
+        even: "peab olema paarisarv"
+        greater_than_start_date: "peab olema suurem kui alguskuupÃ¤ev"
+        not_same_project: "ei kuulu sama projekti juurde"
+        circular_dependency: "See suhe looks vastastikuse sÃµltuvuse"
+        cant_link_an_issue_with_a_descendant: "Teemat ei saa sidustada tema enda alamteemaga"
+
+  actionview_instancetag_blank_option: "Palun vali"
+
+  general_text_No: "Ei"
+  general_text_Yes: "Jah"
+  general_text_no: "ei"
+  general_text_yes: "jah"
+  general_lang_name: "Eesti"
+  general_csv_separator: ","
+  general_csv_decimal_separator: "."
+  general_csv_encoding: ISO-8859-13
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: "1"
+
+  notice_account_updated: "Konto uuendamine Ãµnnestus."
+  notice_account_invalid_creditentials: "Sobimatu kasutajanimi vÃµi parool"
+  notice_account_password_updated: "Parooli uuendamine Ãµnnestus."
+  notice_account_wrong_password: "Vale parool"
+  notice_account_register_done: "Konto loomine Ãµnnestus. Konto aktiveerimiseks vajuta vastaval lingil Sulle saadetud e-kirjas."
+  notice_account_unknown_email: "Tundmatu kasutaja."
+  notice_can_t_change_password: "See konto kasutab vÃ¤list autentimisallikat. Siin ei saa selle konto parooli vahetada."
+  notice_account_lost_email_sent: "Sulle saadeti e-kiri parooli vahetamise juhistega."
+  notice_account_activated: "Su konto on aktiveeritud. Saad nÃ¼Ã¼d sisse logida."
+  notice_successful_create: "Loomine Ãµnnestus."
+  notice_successful_update: "Uuendamine Ãµnnestus."
+  notice_successful_delete: "Kustutamine Ãµnnestus."
+  notice_successful_connection: "Ãœhenduse loomine Ãµnnestus."
+  notice_file_not_found: "Sellist lehte ei leitud."
+  notice_locking_conflict: "Teine kasutaja uuendas vahepeal neid andmeid."
+  notice_not_authorized: "Sul ei ole sellele lehele ligipÃ¤Ã¤suks Ãµigusi."
+  notice_not_authorized_archived_project: "See projekt on arhiveeritud."
+  notice_email_sent: "%{value}-le saadeti kiri"
+  notice_email_error: "Kirja saatmisel tekkis viga (%{value})"
+  notice_feeds_access_key_reseted: "Sinu RSS juurdepÃ¤Ã¤suvÃµti nulliti."
+  notice_api_access_key_reseted: "Sinu API juurdepÃ¤Ã¤suvÃµti nulliti."
+  notice_failed_to_save_issues: "%{count} teemat %{total}-st ei Ãµnnestunud salvestada: %{ids}."
+  notice_failed_to_save_time_entries: "%{count} ajakulu kannet %{total}-st ei Ãµnnestunud salvestada: %{ids}."
+  notice_failed_to_save_members: "Liiget/liikmeid ei Ãµnnestunud salvestada: %{errors}."
+  notice_no_issue_selected: "Ãœhtegi teemat ei ole valitud! Palun vali teema(d), mida soovid muuta."
+  notice_account_pending: "Sinu konto on loodud ja ootab nÃ¼Ã¼d administraatori kinnitust."
+  notice_default_data_loaded: "Algseadistuste laadimine Ãµnnestus."
+  notice_unable_delete_version: "Versiooni kustutamine ei Ãµnnestunud."
+  notice_unable_delete_time_entry: "Ajakulu kande kustutamine ei Ãµnnestunud."
+  notice_issue_done_ratios_updated: "Teema edenemise astmed on uuendatud."
+  notice_gantt_chart_truncated: "Diagrammi kÃ¤rbiti kuna Ã¼letati kuvatavate objektide suurim hulk (%{max})"
+  notice_issue_successful_create: "Teema %{id} loodud."
+  notice_issue_update_conflict: "Teine kasutaja uuendas seda teemat Sinuga samaaegselt."
+  notice_account_deleted: "Sinu konto on lÃµplikult kustutatud."
+
+  error_can_t_load_default_data: "Algseadistusi ei saanud laadida: %{value}"
+  error_scm_not_found: "Seda sissekannet hoidlast ei leitud."
+  error_scm_command_failed: "Hoidla poole pÃ¶Ã¶rdumisel tekkis viga: %{value}"
+  error_scm_annotate: "Sissekannet ei eksisteeri vÃµi ei saa annoteerida."
+  error_scm_annotate_big_text_file: "Sissekannet ei saa annoteerida, kuna see on liiga pikk."
+  error_issue_not_found_in_project: "Teemat ei leitud vÃµi see ei kuulu siia projekti"
+  error_no_tracker_in_project: "Selle projektiga ei ole seostatud Ã¼htegi valdkonda. Palun vaata Ã¼le projekti seaded."
+  error_no_default_issue_status: 'Teema algolek on mÃ¤Ã¤ramata. Palun vaata asetused Ã¼le ("Seadistused -> Olekud").'
+  error_can_not_delete_custom_field: "Omaloodud vÃ¤lja kustutamine ei Ãµnnestunud"
+  error_can_not_delete_tracker: "See valdkond on mÃµnes teemas kasutusel ja seda ei saa kustutada."
+  error_can_not_remove_role: "See roll on mÃµnes projektis kasutusel ja seda ei saa kustutada."
+  error_can_not_reopen_issue_on_closed_version: "Suletud versiooni juurde kuulunud teemat ei saa taasavada"
+  error_can_not_archive_project: "Seda projekti ei saa arhiveerida"
+  error_issue_done_ratios_not_updated: "Teema edenemise astmed jÃ¤id uuendamata."
+  error_workflow_copy_source: "Palun vali algne valdkond vÃµi roll"
+  error_workflow_copy_target: "Palun vali sihtvaldkon(na)d vÃµi -roll(id)"
+  error_unable_delete_issue_status: "Oleku kustutamine ei Ãµnnestunud"
+  error_unable_to_connect: "Ãœhenduse loomine ei Ãµnnestunud (%{value})"
+  error_attachment_too_big: "Faili ei saa Ã¼les laadida, sest see on lubatust (%{max_size}) pikem"
+  warning_attachments_not_saved: "%{count} faili salvestamine ei Ãµnnestunud."
+
+  mail_subject_lost_password: "Sinu %{value} parool"
+  mail_body_lost_password: "Et vahetada oma parooli, vajuta jÃ¤rgmisele lingile:"
+  mail_subject_register: "Sinu %{value} konto aktiveerimine"
+  mail_body_register: "Et aktiveerida oma kontot, vajuta jÃ¤rgmisele lingile:"
+  mail_body_account_information_external: "Sisse logimiseks saad kasutada oma %{value} kontot."
+  mail_body_account_information: "Sinu konto teave"
+  mail_subject_account_activation_request: "%{value} konto aktiveerimise nÃµue"
+  mail_body_account_activation_request: "Registreerus uus kasutaja (%{value}). Konto avamine ootab Sinu kinnitust:"
+  mail_subject_reminder: "%{count} teema tÃ¤htaeg jÃµuab kÃ¤tte jÃ¤rgmise %{days} pÃ¤eva jooksul"
+  mail_body_reminder: "%{count} Sulle mÃ¤Ã¤ratud teema tÃ¤htaeg jÃµuab kÃ¤tte jÃ¤rgmise %{days} pÃ¤eva jooksul:"
+  mail_subject_wiki_content_added: "Lisati '%{id}' vikileht"
+  mail_body_wiki_content_added: "'%{id}' vikileht lisati %{author} poolt."
+  mail_subject_wiki_content_updated: "Uuendati '%{id}' vikilehte"
+  mail_body_wiki_content_updated: "'%{id}' vikilehte uuendati %{author} poolt."
+
+
+  field_name: "Nimi"
+  field_description: "Kirjeldus"
+  field_summary: "KokkuvÃµte"
+  field_is_required: "Kohustuslik"
+  field_firstname: "Eesnimi"
+  field_lastname: "Perekonnanimi"
+  field_mail: "E-post"
+  field_filename: "Fail"
+  field_filesize: "Pikkus"
+  field_downloads: "Allalaadimist"
+  field_author: "Autor"
+  field_created_on: "Loodud"
+  field_updated_on: "Uuendatud"
+  field_field_format: "TÃ¼Ã¼p"
+  field_is_for_all: "KÃµigile projektidele"
+  field_possible_values: "VÃµimalikud vÃ¤Ã¤rtused"
+  field_regexp: "Regulaarne avaldis"
+  field_min_length: "VÃ¤him pikkus"
+  field_max_length: "Suurim pikkus"
+  field_value: "VÃ¤Ã¤rtus"
+  field_category: "Kategooria"
+  field_title: "Pealkiri"
+  field_project: "Projekt"
+  field_issue: "Teema"
+  field_status: "Olek"
+  field_notes: "MÃ¤rkused"
+  field_is_closed: "Sulgeb teema"
+  field_is_default: "Algolek"
+  field_tracker: "Valdkond"
+  field_subject: "Teema"
+  field_due_date: "TÃ¤htaeg"
+  field_assigned_to: "Tegeleja"
+  field_priority: "Prioriteet"
+  field_fixed_version: "Sihtversioon"
+  field_user: "Kasutaja"
+  field_principal: "Vastutav isik"
+  field_role: "Roll"
+  field_homepage: "Koduleht"
+  field_is_public: "Avalik"
+  field_parent: "Emaprojekt"
+  field_is_in_roadmap: "Teemad on teekaardil nÃ¤ha"
+  field_login: "Kasutajanimi"
+  field_mail_notification: "Teated e-kirjaga"
+  field_admin: "Admin"
+  field_last_login_on: "Viimane Ã¼hendus"
+  field_language: "Keel"
+  field_effective_date: "TÃ¤htaeg"
+  field_password: "Parool"
+  field_new_password: "Uus parool"
+  field_password_confirmation: "Kinnitus"
+  field_version: "Versioon"
+  field_type: "TÃ¼Ã¼p"
+  field_host: "Server"
+  field_port: "Port"
+  field_account: "Konto"
+  field_base_dn: "Baas DN"
+  field_attr_login: "Kasutajanime atribuut"
+  field_attr_firstname: "Eesnime atribuut"
+  field_attr_lastname: "Perekonnanime atribuut"
+  field_attr_mail: "E-posti atribuut"
+  field_onthefly: "Kasutaja automaatne loomine"
+  field_start_date: "AlguskuupÃ¤ev"
+  field_done_ratio: "% tehtud"
+  field_auth_source: "Autentimise viis"
+  field_hide_mail: "Peida e-posti aadress"
+  field_comments: "Kommentaar"
+  field_url: "URL"
+  field_start_page: "Esileht"
+  field_subproject: "Alamprojekt"
+  field_hours: "tundi"
+  field_activity: "Tegevus"
+  field_spent_on: "KuupÃ¤ev"
+  field_identifier: "Tunnus"
+  field_is_filter: "Kasutatakse filtrina"
+  field_issue_to: "Seotud teema"
+  field_delay: "Viivitus"
+  field_assignable: "Saab mÃ¤Ã¤rata teemadega tegelema"
+  field_redirect_existing_links: "Suuna olemasolevad lingid ringi"
+  field_estimated_hours: "Eeldatav ajakulu"
+  field_column_names: "Veerud"
+  field_time_entries: "Ajakulu"
+  field_time_zone: "Ajatsoon"
+  field_searchable: "Otsitav"
+  field_default_value: "Vaikimisi"
+  field_comments_sorting: "Kommentaaride jÃ¤rjestus"
+  field_parent_title: "PÃ¤rineb lehest"
+  field_editable: "Muudetav"
+  field_watcher: "JÃ¤lgija"
+  field_identity_url: "OpenID URL"
+  field_content: "Sisu"
+  field_group_by: "Grupeeri tulemus"
+  field_sharing: "Teemade jagamine"
+  field_parent_issue: "PÃ¤rineb teemast"
+  field_member_of_group: "Tegeleja grupp"
+  field_assigned_to_role: "Tegeleja roll"
+  field_text: "TekstivÃ¤li"
+  field_visible: "NÃ¤htav"
+  field_warn_on_leaving_unsaved: "Hoiata salvestamata sisuga lehtedelt lahkumisel"
+  field_issues_visibility: "See roll nÃ¤eb"
+  field_is_private: "Privaatne"
+  field_commit_logs_encoding: "Sissekannete kodeering"
+  field_scm_path_encoding: "Teeraja mÃ¤rkide kodeering"
+  field_path_to_repository: "Hoidla teerada"
+  field_root_directory: "Juurkataloog"
+  field_cvsroot: "CVSROOT"
+  field_cvs_module: "Moodul"
+  field_repository_is_default: "Peamine hoidla"
+  field_multiple: "Korraga mitu vÃ¤Ã¤rtust"
+  field_auth_source_ldap_filter: "LDAP filter"
+
+  setting_app_title: "Veebilehe pealkiri"
+  setting_app_subtitle: "Veebilehe alampealkiri"
+  setting_welcome_text: "Tervitustekst"
+  setting_default_language: "Vaikimisi keel"
+  setting_login_required: "Autentimine kohustuslik"
+  setting_self_registration: "Omaloodud konto aktiveerimine"
+  setting_attachment_max_size: "Manuse suurim pikkus"
+  setting_issues_export_limit: "Teemade ekspordi limiit"
+  setting_mail_from: "Saatja e-posti aadress"
+  setting_bcc_recipients: "Saajaid ei nÃ¤idata (lÃ¤hevad BCC reale)"
+  setting_plain_text_mail: "E-kiri tavalise tekstina (ilma HTML-ta)"
+  setting_host_name: "Serveri nimi ja teerada"
+  setting_text_formatting: "Vormindamise abi"
+  setting_wiki_compression: "Viki ajaloo pakkimine"
+  setting_feeds_limit: "Atom voogude suurim objektide arv"
+  setting_default_projects_public: "Uued projektid on vaikimisi avalikud"
+  setting_autofetch_changesets: "Lae uuendused automaatselt"
+  setting_sys_api_enabled: "Hoidlate haldamine veebiteenuse kaudu"
+  setting_commit_ref_keywords: "Viitade vÃµtmesÃµnad"
+  setting_commit_fix_keywords: "Paranduste vÃµtmesÃµnad"
+  setting_autologin: "Automaatne sisselogimine"
+  setting_date_format: "KuupÃ¤evaformaat"
+  setting_time_format: "Ajaformaat"
+  setting_cross_project_issue_relations: "Luba siduda eri projektide teemasid"
+  setting_issue_list_default_columns: "Teemade nimekirja vaikimisi veerud"
+  setting_repositories_encodings: "Manuste ja hoidlate kodeering"
+  setting_emails_header: "E-kirja pÃ¤is"
+  setting_emails_footer: "E-kirja jalus"
+  setting_protocol: "Protokoll"
+  setting_per_page_options: "Objekte lehe kohta variandid"
+  setting_user_format: "Kasutaja nime esitamise vorm"
+  setting_activity_days_default: "Projektide ajalugu nÃ¤idatakse"
+  setting_display_subprojects_issues: "NÃ¤ita projektis vaikimisi ka alamprojektide teemasid"
+  setting_enabled_scm: "Kasutatavad lÃ¤htekoodi haldusvahendid"
+  setting_mail_handler_body_delimiters: "KÃ¤rbi e-kirja lÃµpp peale sellist rida"
+  setting_mail_handler_api_enabled: "E-kirjade vastuvÃµtt veebiteenuse kaudu"
+  setting_mail_handler_api_key: "Veebiteenuse API vÃµti"
+  setting_sequential_project_identifiers: "Genereeri jÃ¤rjestikused projektitunnused"
+  setting_gravatar_enabled: "Kasuta Gravatari kasutajaikoone"
+  setting_gravatar_default: "Vaikimisi kasutatav ikoon"
+  setting_diff_max_lines_displayed: "Enim korraga nÃ¤idatavaid erinevusi"
+  setting_file_max_size_displayed: "Kuvatava tekstifaili suurim pikkus"
+  setting_repository_log_display_limit: "Enim ajaloos nÃ¤idatavaid sissekandeid"
+  setting_openid: "Luba OpenID-ga registreerimine ja sisselogimine"
+  setting_password_min_length: "LÃ¼hima lubatud parooli pikkus"
+  setting_new_project_user_role_id: "Projekti looja roll oma projektis"
+  setting_default_projects_modules: "Vaikimisi moodulid uutes projektides"
+  setting_issue_done_ratio: "MÃ¤Ã¤ra teema edenemise aste"
+  setting_issue_done_ratio_issue_field: "kasutades vastavat vÃ¤lja"
+  setting_issue_done_ratio_issue_status: "kasutades teema olekut"
+  setting_start_of_week: "NÃ¤dala alguspÃ¤ev"
+  setting_rest_api_enabled: "Luba REST API kasutamine"
+  setting_cache_formatted_text: "Puhverda vormindatud teksti"
+  setting_default_notification_option: "Vaikimisi teavitatakse"
+  setting_commit_logtime_enabled: "Luba ajakulu sisestamine"
+  setting_commit_logtime_activity_id: "Tegevus kulunud ajal"
+  setting_gantt_items_limit: "Gantti diagrammi objektide suurim hulk"
+  setting_issue_group_assignment: "Luba teemade andmine gruppidele"
+  setting_default_issue_start_date_to_creation_date: "Uute teemade alguskuupÃ¤evaks teema loomise pÃ¤ev"
+  setting_commit_cross_project_ref: "Luba viiteid ja parandusi ka kÃµigi teiste projektide teemadele"
+  setting_unsubscribe: "Luba kasutajal oma konto kustutada"
+
+  permission_add_project: "Projekte luua"
+  permission_add_subprojects: "Alamprojekte luua"
+  permission_edit_project: "Projekte muuta"
+  permission_select_project_modules: "Projektimooduleid valida"
+  permission_manage_members: "Liikmeid hallata"
+  permission_manage_project_activities: "Projekti tegevusi hallata"
+  permission_manage_versions: "Versioone hallata"
+  permission_manage_categories: "Kategooriaid hallata"
+  permission_view_issues: "Teemasid nÃ¤ha"
+  permission_add_issues: "Teemasid lisada"
+  permission_edit_issues: "Teemasid uuendada"
+  permission_manage_issue_relations: "Teemade seoseid hallata"
+  permission_set_issues_private: "Teemasid avalikeks vÃµi privaatseiks seada"
+  permission_set_own_issues_private: "Omi teemasid avalikeks vÃµi privaatseiks seada"
+  permission_add_issue_notes: "MÃ¤rkusi lisada"
+  permission_edit_issue_notes: "MÃ¤rkusi muuta"
+  permission_edit_own_issue_notes: "Omi mÃ¤rkusi muuta"
+  permission_move_issues: "Teemasid teise projekti tÃµsta"
+  permission_delete_issues: "Teemasid kustutada"
+  permission_manage_public_queries: "Avalikke pÃ¤ringuid hallata"
+  permission_save_queries: "PÃ¤ringuid salvestada"
+  permission_view_gantt: "Gantti diagramme nÃ¤ha"
+  permission_view_calendar: "Kalendrit nÃ¤ha"
+  permission_view_issue_watchers: "JÃ¤lgijate nimekirja nÃ¤ha"
+  permission_add_issue_watchers: "JÃ¤lgijaid lisada"
+  permission_delete_issue_watchers: "JÃ¤lgijaid kustutada"
+  permission_log_time: "Ajakulu sisestada"
+  permission_view_time_entries: "Ajakulu nÃ¤ha"
+  permission_edit_time_entries: "Ajakulu kandeid muuta"
+  permission_edit_own_time_entries: "Omi ajakulu kandeid muuta"
+  permission_manage_news: "Uudiseid hallata"
+  permission_comment_news: "Uudiseid kommenteerida"
+  permission_view_documents: "Dokumente nÃ¤ha"
+  permission_manage_files: "Faile hallata"
+  permission_view_files: "Faile nÃ¤ha"
+  permission_manage_wiki: "Vikit hallata"
+  permission_rename_wiki_pages: "Vikilehti Ã¼mber nimetada"
+  permission_delete_wiki_pages: "Vikilehti kustutada"
+  permission_view_wiki_pages: "Vikit nÃ¤ha"
+  permission_view_wiki_edits: "Viki ajalugu nÃ¤ha"
+  permission_edit_wiki_pages: "Vikilehti muuta"
+  permission_delete_wiki_pages_attachments: "Manuseid kustutada"
+  permission_protect_wiki_pages: "Vikilehti kaitsta"
+  permission_manage_repository: "Hoidlaid hallata"
+  permission_browse_repository: "Hoidlaid sirvida"
+  permission_view_changesets: "Sissekandeid nÃ¤ha"
+  permission_commit_access: "Sissekandeid teha"
+  permission_manage_boards: "Foorumeid hallata"
+  permission_view_messages: "Postitusi nÃ¤ha"
+  permission_add_messages: "Postitusi lisada"
+  permission_edit_messages: "Postitusi muuta"
+  permission_edit_own_messages: "Omi postitusi muuta"
+  permission_delete_messages: "Postitusi kustutada"
+  permission_delete_own_messages: "Omi postitusi kustutada"
+  permission_export_wiki_pages: "Vikilehti eksportida"
+  permission_manage_subtasks: "Alamteemasid hallata"
+  permission_manage_related_issues: "Seotud teemasid hallata"
+
+  project_module_issue_tracking: "Teemade jÃ¤lgimine"
+  project_module_time_tracking: "Ajakulu arvestus"
+  project_module_news: "Uudised"
+  project_module_documents: "Dokumendid"
+  project_module_files: "Failid"
+  project_module_wiki: "Viki"
+  project_module_repository: "Hoidlad"
+  project_module_boards: "Foorumid"
+  project_module_calendar: "Kalender"
+  project_module_gantt: "Gantt"
+
+  label_user: "Kasutaja"
+  label_user_plural: "Kasutajad"
+  label_user_new: "Uus kasutaja"
+  label_user_anonymous: "AnonÃ¼Ã¼mne"
+  label_project: "Projekt"
+  label_project_new: "Uus projekt"
+  label_project_plural: "Projektid"
+  label_x_projects:
+    zero:  "pole projekte"
+    one:   "1 projekt"
+    other: "%{count} projekti"
+  label_project_all: "KÃµik projektid"
+  label_project_latest: "Viimased projektid"
+  label_issue: "Teema"
+  label_issue_new: "Uus teema"
+  label_issue_plural: "Teemad"
+  label_issue_view_all: "Teemade nimekiri"
+  label_issues_by: "Teemad %{value} jÃ¤rgi"
+  label_issue_added: "Teema lisatud"
+  label_issue_updated: "Teema uuendatud"
+  label_issue_note_added: "MÃ¤rkus lisatud"
+  label_issue_status_updated: "Olek uuendatud"
+  label_issue_priority_updated: "Prioriteet uuendatud"
+  label_document: "Dokument"
+  label_document_new: "Uus dokument"
+  label_document_plural: "Dokumendid"
+  label_document_added: "Dokument lisatud"
+  label_role: "Roll"
+  label_role_plural: "Rollid"
+  label_role_new: "Uus roll"
+  label_role_and_permissions: "Rollid ja Ãµigused"
+  label_role_anonymous: "AnonÃ¼Ã¼mne"
+  label_role_non_member: "Mitteliige"
+  label_member: "Liige"
+  label_member_new: "Uus liige"
+  label_member_plural: "Liikmed"
+  label_tracker: "Valdkond"
+  label_tracker_plural: "Valdkonnad"
+  label_tracker_new: "Uus valdkond"
+  label_workflow: "TÃ¶Ã¶vood"
+  label_issue_status: "Olek"
+  label_issue_status_plural: "Olekud"
+  label_issue_status_new: "Uus olek"
+  label_issue_category: "Kategooria"
+  label_issue_category_plural: "Kategooriad"
+  label_issue_category_new: "Uus kategooria"
+  label_custom_field: "Omaloodud vÃ¤li"
+  label_custom_field_plural: "Omaloodud vÃ¤ljad"
+  label_custom_field_new: "Uus vÃ¤li"
+  label_enumerations: "Loetelud"
+  label_enumeration_new: "Uus vÃ¤Ã¤rtus"
+  label_information: "Teave"
+  label_information_plural: "Teave"
+  label_please_login: "Palun logi sisse"
+  label_register: "Registreeru"
+  label_login_with_open_id_option: "vÃµi logi sisse OpenID-ga"
+  label_password_lost: "Kui parool on ununud..."
+  label_home: "Kodu"
+  label_my_page: "Oma leht"
+  label_my_account: "Oma konto"
+  label_my_projects: "Oma projektid"
+  label_my_page_block: "Uus blokk"
+  label_administration: "Seadistused"
+  label_login: "Logi sisse"
+  label_logout: "Logi vÃ¤lja"
+  label_help: "Abi"
+  label_reported_issues: "Minu poolt lisatud teemad"
+  label_assigned_to_me_issues: "Minu teha olevad teemad"
+  label_last_login: "Viimane Ã¼hendus"
+  label_registered_on: "Registreeritud"
+  label_activity: "Ajalugu"
+  label_overall_activity: "Ãœldine tegevuste ajalugu"
+  label_user_activity: "%{value} tegevuste ajalugu"
+  label_new: "Uus"
+  label_logged_as: "Sisse logitud kui"
+  label_environment: "Keskkond"
+  label_authentication: "Autentimine"
+  label_auth_source: "Autentimisallikas"
+  label_auth_source_new: "Uus autentimisallikas"
+  label_auth_source_plural: "Autentimisallikad"
+  label_subproject_plural: "Alamprojektid"
+  label_subproject_new: "Uus alamprojekt"
+  label_and_its_subprojects: "%{value} ja selle alamprojektid"
+  label_min_max_length: "Min.-maks. pikkus"
+  label_list: "Nimekiri"
+  label_date: "KuupÃ¤ev"
+  label_integer: "TÃ¤isarv"
+  label_float: "Ujukomaarv"
+  label_boolean: "TÃµevÃ¤Ã¤rtus"
+  label_string: "Tekst"
+  label_text: "Pikk tekst"
+  label_attribute: "Atribuut"
+  label_attribute_plural: "Atribuudid"
+  label_no_data: "Pole"
+  label_change_status: "Muuda olekut"
+  label_history: "Ajalugu"
+  label_attachment: "Fail"
+  label_attachment_new: "Uus fail"
+  label_attachment_delete: "Kustuta fail"
+  label_attachment_plural: "Failid"
+  label_file_added: "Fail lisatud"
+  label_report: "Aruanne"
+  label_report_plural: "Aruanded"
+  label_news: "Uudised"
+  label_news_new: "Lisa uudis"
+  label_news_plural: "Uudised"
+  label_news_latest: "Viimased uudised"
+  label_news_view_all: "KÃµik uudised"
+  label_news_added: "Uudis lisatud"
+  label_news_comment_added: "Kommentaar uudisele lisatud"
+  label_settings: "Seaded"
+  label_overview: "Ãœlevaade"
+  label_version: "Versioon"
+  label_version_new: "Uus versioon"
+  label_version_plural: "Versioonid"
+  label_close_versions: "Sulge lÃµpetatud versioonid"
+  label_confirmation: "Kinnitus"
+  label_export_to: "Samuti saadaval kujul:"
+  label_read: "Loe..."
+  label_public_projects: "Avalikud projektid"
+  label_open_issues: "avatud"
+  label_open_issues_plural: "avatud"
+  label_closed_issues: "suletud"
+  label_closed_issues_plural: "suletud"
+  label_x_open_issues_abbr_on_total:
+    zero:  "0 avatud / %{total}"
+    one:   "1 avatud / %{total}"
+    other: "%{count} avatud / %{total}"
+  label_x_open_issues_abbr:
+    zero:  "0 avatud"
+    one:   "1 avatud"
+    other: "%{count} avatud"
+  label_x_closed_issues_abbr:
+    zero:  "0 suletud"
+    one:   "1 suletud"
+    other: "%{count} suletud"
+  label_x_issues:
+    zero:  "0 teemat"
+    one:   "1 teema"
+    other: "%{count} teemat"
+  label_total: "Kokku"
+  label_permissions: "Ã•igused"
+  label_current_status: "Praegune olek"
+  label_new_statuses_allowed: "Uued lubatud olekud"
+  label_all: "kÃµik"
+  label_none: "pole"
+  label_nobody: "eikeegi"
+  label_next: "JÃ¤rgmine"
+  label_previous: "Eelmine"
+  label_used_by: "Kasutab"
+  label_details: "Ãœksikasjad"
+  label_add_note: "Lisa mÃ¤rkus"
+  label_per_page: "Lehe kohta"
+  label_calendar: "Kalender"
+  label_months_from: "kuu kaugusel"
+  label_gantt: "Gantt"
+  label_internal: "Sisemine"
+  label_last_changes: "viimased %{count} muudatust"
+  label_change_view_all: "KÃµik muudatused"
+  label_personalize_page: "Kujunda leht Ã¼mber"
+  label_comment: "Kommentaar"
+  label_comment_plural: "Kommentaarid"
+  label_x_comments:
+    zero: "kommentaare pole"
+    one: "1 kommentaar"
+    other: "%{count} kommentaari"
+  label_comment_add: "Lisa kommentaar"
+  label_comment_added: "Kommentaar lisatud"
+  label_comment_delete: "Kustuta kommentaar"
+  label_query: "Omaloodud pÃ¤ring"
+  label_query_plural: "Omaloodud pÃ¤ringud"
+  label_query_new: "Uus pÃ¤ring"
+  label_my_queries: "Mu omaloodud pÃ¤ringud"
+  label_filter_add: "Lisa filter"
+  label_filter_plural: "Filtrid"
+  label_equals: "on"
+  label_not_equals: "ei ole"
+  label_in_less_than: "on vÃ¤iksem kui"
+  label_in_more_than: "on suurem kui"
+  label_greater_or_equal: "suurem-vÃµrdne"
+  label_less_or_equal: "vÃ¤iksem-vÃµrdne"
+  label_between: "vahemikus"
+  label_in: "sisaldub hulgas"
+  label_today: "tÃ¤na"
+  label_all_time: "piirideta"
+  label_yesterday: "eile"
+  label_this_week: "sel nÃ¤dalal"
+  label_last_week: "eelmisel nÃ¤dalal"
+  label_last_n_days: "viimase %{count} pÃ¤eva jooksul"
+  label_this_month: "sel kuul"
+  label_last_month: "eelmisel kuul"
+  label_this_year: "sel aastal"
+  label_date_range: "KuupÃ¤evavahemik"
+  label_less_than_ago: "uuem kui"
+  label_more_than_ago: "vanem kui"
+  label_ago: "vanus"
+  label_contains: "sisaldab"
+  label_not_contains: "ei sisalda"
+  label_day_plural: "pÃ¤eva"
+  label_repository: "Hoidla"
+  label_repository_new: "Uus hoidla"
+  label_repository_plural: "Hoidlad"
+  label_browse: "Sirvi"
+  label_branch: "Haru"
+  label_tag: "Sildiga"
+  label_revision: "Sissekanne"
+  label_revision_plural: "Sissekanded"
+  label_revision_id: "Sissekande kood %{value}"
+  label_associated_revisions: "Seotud sissekanded"
+  label_added: "lisatud"
+  label_modified: "muudetud"
+  label_copied: "kopeeritud"
+  label_renamed: "Ã¼mber nimetatud"
+  label_deleted: "kustutatud"
+  label_latest_revision: "Viimane sissekanne"
+  label_latest_revision_plural: "Viimased sissekanded"
+  label_view_revisions: "Haru ajalugu"
+  label_view_all_revisions: "Kogu ajalugu"
+  label_max_size: "Suurim pikkus"
+  label_sort_highest: "Nihuta esimeseks"
+  label_sort_higher: "Nihuta Ã¼les"
+  label_sort_lower: "Nihuta alla"
+  label_sort_lowest: "Nihuta viimaseks"
+  label_roadmap: "Teekaart"
+  label_roadmap_due_in: "TÃ¤htaeg %{value}"
+  label_roadmap_overdue: "%{value} hiljaks jÃ¤Ã¤nud"
+  label_roadmap_no_issues: "Selles versioonis ei ole teemasid"
+  label_search: "Otsi"
+  label_result_plural: "Tulemused"
+  label_all_words: "KÃµik sÃµnad"
+  label_wiki: "Viki"
+  label_wiki_edit: "Viki muutmine"
+  label_wiki_edit_plural: "Viki muutmised"
+  label_wiki_page: "Vikileht"
+  label_wiki_page_plural: "Vikilehed"
+  label_index_by_title: "JÃ¤rjesta pealkirja jÃ¤rgi"
+  label_index_by_date: "JÃ¤rjesta kuupÃ¤eva jÃ¤rgi"
+  label_current_version: "Praegune versioon"
+  label_preview: "Eelvaade"
+  label_feed_plural: "Vood"
+  label_changes_details: "KÃµigi muudatuste Ã¼ksikasjad"
+  label_issue_tracking: "Teemade jÃ¤lgimine"
+  label_spent_time: "Kulutatud aeg"
+  label_overall_spent_time: "Kokku kulutatud aeg"
+  label_f_hour: "%{value} tund"
+  label_f_hour_plural: "%{value} tundi"
+  label_time_tracking: "Ajakulu arvestus"
+  label_change_plural: "Muudatused"
+  label_statistics: "Statistika"
+  label_commits_per_month: "Sissekandeid kuu kohta"
+  label_commits_per_author: "Sissekandeid autori kohta"
+  label_diff: "erinevused"
+  label_view_diff: "Vaata erinevusi"
+  label_diff_inline: "teksti sees"
+  label_diff_side_by_side: "kÃµrvuti"
+  label_options: "Valikud"
+  label_copy_workflow_from: "Kopeeri see tÃ¶Ã¶voog"
+  label_permissions_report: "Ã•iguste aruanne"
+  label_watched_issues: "JÃ¤lgitud teemad"
+  label_related_issues: "Seotud teemad"
+  label_applied_status: "Kehtestatud olek"
+  label_loading: "Laadimas..."
+  label_relation_new: "Uus seos"
+  label_relation_delete: "Kustuta seos"
+  label_relates_to: "seostub"
+  label_duplicates: "duplitseerib"
+  label_duplicated_by: "duplitseerija"
+  label_blocks: "blokeerib"
+  label_blocked_by: "blokeerija"
+  label_precedes: "eelneb"
+  label_follows: "jÃ¤rgneb"
+  label_end_to_start: "lÃµpust alguseni"
+  label_end_to_end: "lÃµpust lÃµpuni"
+  label_start_to_start: "algusest alguseni"
+  label_start_to_end: "algusest lÃµpuni"
+  label_stay_logged_in: "PÃ¼si sisselogituna"
+  label_disabled: "pole vÃµimalik"
+  label_show_completed_versions: "NÃ¤ita lÃµpetatud versioone"
+  label_me: "mina"
+  label_board: "Foorum"
+  label_board_new: "Uus foorum"
+  label_board_plural: "Foorumid"
+  label_board_locked: "Lukus"
+  label_board_sticky: "PÃ¼siteema"
+  label_topic_plural: "Teemad"
+  label_message_plural: "Postitused"
+  label_message_last: "Viimane postitus"
+  label_message_new: "Uus postitus"
+  label_message_posted: "Postitus lisatud"
+  label_reply_plural: "Vastused"
+  label_send_information: "Saada teave konto kasutajale"
+  label_year: "Aasta"
+  label_month: "Kuu"
+  label_week: "NÃ¤dal"
+  label_date_from: "Alates"
+  label_date_to: "Kuni"
+  label_language_based: "Kasutaja keele pÃµhjal"
+  label_sort_by: "Sorteeri %{value} jÃ¤rgi"
+  label_send_test_email: "Saada kontrollkiri"
+  label_feeds_access_key: "RSS juurdepÃ¤Ã¤suvÃµti"
+  label_missing_feeds_access_key: "RSS juurdepÃ¤Ã¤suvÃµti on puudu"
+  label_feeds_access_key_created_on: "RSS juurdepÃ¤Ã¤suvÃµti loodi %{value} tagasi"
+  label_module_plural: "Moodulid"
+  label_added_time_by: "Lisatud %{author} poolt %{age} tagasi"
+  label_updated_time_by: "Uuendatud %{author} poolt %{age} tagasi"
+  label_updated_time: "Uuendatud %{value} tagasi"
+  label_jump_to_a_project: "Ava projekt..."
+  label_file_plural: "Failid"
+  label_changeset_plural: "Muudatused"
+  label_default_columns: "Vaikimisi veerud"
+  label_no_change_option: "(Ei muutu)"
+  label_bulk_edit_selected_issues: "Muuda valitud teemasid korraga"
+  label_bulk_edit_selected_time_entries: "Muuda valitud ajakandeid korraga"
+  label_theme: "Visuaalne teema"
+  label_default: "Tavaline"
+  label_search_titles_only: "Ainult pealkirjadest"
+  label_user_mail_option_all: "KÃµigist tegevustest kÃµigis mu projektides"
+  label_user_mail_option_selected: "KÃµigist tegevustest ainult valitud projektides..."
+  label_user_mail_option_none: "Teavitusi ei saadeta"
+  label_user_mail_option_only_my_events: "Ainult mu jÃ¤lgitavatest vÃµi minuga seotud tegevustest"
+  label_user_mail_option_only_assigned: "Ainult minu teha olevate asjade kohta"
+  label_user_mail_option_only_owner: "Ainult mu oma asjade kohta"
+  label_user_mail_no_self_notified: "Ã„ra teavita mind mu enda tehtud muudatustest"
+  label_registration_activation_by_email: "e-kirjaga"
+  label_registration_manual_activation: "kÃ¤sitsi"
+  label_registration_automatic_activation: "automaatselt"
+  label_display_per_page: "Lehe kohta: %{value}"
+  label_age: "Vanus"
+  label_change_properties: "Muuda omadusi"
+  label_general: "Ãœldine"
+  label_more: "Rohkem"
+  label_scm: "LÃ¤htekoodi haldusvahend"
+  label_plugins: "Lisamoodulid"
+  label_ldap_authentication: "LDAP autentimine"
+  label_downloads_abbr: "A/L"
+  label_optional_description: "Teave"
+  label_add_another_file: "Lisa veel Ã¼ks fail"
+  label_preferences: "Eelistused"
+  label_chronological_order: "kronoloogiline"
+  label_reverse_chronological_order: "tagurpidi kronoloogiline"
+  label_planning: "Planeerimine"
+  label_incoming_emails: "Sissetulevad e-kirjad"
+  label_generate_key: "Genereeri vÃµti"
+  label_issue_watchers: "JÃ¤lgijad"
+  label_example: "NÃ¤ide"
+  label_display: "Kujundus"
+  label_sort: "Sorteeri"
+  label_ascending: "Kasvavalt"
+  label_descending: "Kahanevalt"
+  label_date_from_to: "Alates %{start} kuni %{end}"
+  label_wiki_content_added: "Vikileht lisatud"
+  label_wiki_content_updated: "Vikileht uuendatud"
+  label_group: "Grupp"
+  label_group_plural: "Grupid"
+  label_group_new: "Uus grupp"
+  label_time_entry_plural: "Kulutatud aeg"
+  label_version_sharing_none: "ei toimu"
+  label_version_sharing_descendants: "alamprojektidega"
+  label_version_sharing_hierarchy: "projektihierarhiaga"
+  label_version_sharing_tree: "projektipuuga"
+  label_version_sharing_system: "kÃµigi projektidega"
+  label_update_issue_done_ratios: "Uuenda edenemise astmeid"
+  label_copy_source: "Allikas"
+  label_copy_target: "Sihtkoht"
+  label_copy_same_as_target: "Sama mis sihtkoht"
+  label_display_used_statuses_only: "NÃ¤ita ainult selles valdkonnas kasutusel olekuid"
+  label_api_access_key: "API juurdepÃ¤Ã¤suvÃµti"
+  label_missing_api_access_key: "API juurdepÃ¤Ã¤suvÃµti on puudu"
+  label_api_access_key_created_on: "API juurdepÃ¤Ã¤suvÃµti loodi %{value} tagasi"
+  label_profile: "Profiil"
+  label_subtask_plural: "Alamteemad"
+  label_project_copy_notifications: "Saada projekti kopeerimise kohta teavituskiri"
+  label_principal_search: "Otsi kasutajat vÃµi gruppi:"
+  label_user_search: "Otsi kasutajat:"
+  label_additional_workflow_transitions_for_author: "Luba ka jÃ¤rgmisi Ã¼leminekuid kui kasutaja on teema looja"
+  label_additional_workflow_transitions_for_assignee: "Luba ka jÃ¤rgmisi Ã¼leminekuid kui kasutaja on teemaga tegeleja"
+  label_issues_visibility_all: "kÃµiki teemasid"
+  label_issues_visibility_public: "kÃµiki mitteprivaatseid teemasid"
+  label_issues_visibility_own: "enda poolt loodud vÃµi enda teha teemasid"
+  label_git_report_last_commit: "Viimase sissekande teave otse failinimekirja"
+  label_parent_revision: "Eellane"
+  label_child_revision: "JÃ¤rglane"
+  label_export_options: "%{export_format} ekspordivalikud"
+  label_copy_attachments: "Kopeeri manused"
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: "LÃµpetatud versioonid"
+  label_search_for_watchers: "Otsi lisamiseks jÃ¤lgijaid"
+
+  button_login: "Logi sisse"
+  button_submit: "Sisesta"
+  button_save: "Salvesta"
+  button_check_all: "MÃ¤rgi kÃµik"
+  button_uncheck_all: "Nulli valik"
+  button_collapse_all: "Voldi kÃµik kokku"
+  button_expand_all: "Voldi kÃµik lahti"
+  button_delete: "Kustuta"
+  button_create: "Loo"
+  button_create_and_continue: "Loo ja jÃ¤tka"
+  button_test: "Testi"
+  button_edit: "Muuda"
+  button_edit_associated_wikipage: "Muuda seotud vikilehte: %{page_title}"
+  button_add: "Lisa"
+  button_change: "Muuda"
+  button_apply: "Lae"
+  button_clear: "Puhasta"
+  button_lock: "Lukusta"
+  button_unlock: "Ava lukust"
+  button_download: "Lae alla"
+  button_list: "Listi"
+  button_view: "Vaata"
+  button_move: "TÃµsta"
+  button_move_and_follow: "TÃµsta ja jÃ¤rgne"
+  button_back: "Tagasi"
+  button_cancel: "Katkesta"
+  button_activate: "Aktiveeri"
+  button_sort: "Sorteeri"
+  button_log_time: "Ajakulu"
+  button_rollback: "Rulli tagasi sellesse versiooni"
+  button_watch: "JÃ¤lgi"
+  button_unwatch: "Ã„ra jÃ¤lgi"
+  button_reply: "Vasta"
+  button_archive: "Arhiveeri"
+  button_unarchive: "Arhiivist tagasi"
+  button_reset: "Nulli"
+  button_rename: "Nimeta Ã¼mber"
+  button_change_password: "Vaheta parool"
+  button_copy: "Kopeeri"
+  button_copy_and_follow: "Kopeeri ja jÃ¤rgne"
+  button_annotate: "Annoteeri"
+  button_update: "Muuda"
+  button_configure: "Konfigureeri"
+  button_quote: "Tsiteeri"
+  button_duplicate: "Duplitseeri"
+  button_show: "NÃ¤ita"
+  button_edit_section: "Muuda seda sektsiooni"
+  button_export: "Ekspordi"
+  button_delete_my_account: "Kustuta oma konto"
+
+  status_active: "aktiivne"
+  status_registered: "registreeritud"
+  status_locked: "lukus"
+
+  version_status_open: "avatud"
+  version_status_locked: "lukus"
+  version_status_closed: "suletud"
+
+  field_active: "Aktiivne"
+
+  text_select_mail_notifications: "Tegevused, millest peaks e-kirjaga teavitama"
+  text_regexp_info: "nt. ^[A-Z0-9]+$"
+  text_min_max_length_info: "0 tÃ¤hendab, et piiranguid ei ole"
+  text_project_destroy_confirmation: "Oled Sa kindel oma soovis see projekt tÃ¤ielikult kustutada?"
+  text_subprojects_destroy_warning: "Alamprojekt(id) - %{value} - kustutatakse samuti."
+  text_workflow_edit: "TÃ¶Ã¶voo muutmiseks vali roll ja valdkond"
+  text_are_you_sure: "Oled Sa kindel?"
+  text_journal_changed: "%{label} muudetud %{old} -> %{new}"
+  text_journal_changed_no_detail: "%{label} uuendatud"
+  text_journal_set_to: "%{label} uus vÃ¤Ã¤rtus on %{value}"
+  text_journal_deleted: "%{label} kustutatud (%{old})"
+  text_journal_added: "%{label} %{value} lisatud"
+  text_tip_issue_begin_day: "teema avamise pÃ¤ev"
+  text_tip_issue_end_day: "teema sulgemise pÃ¤ev"
+  text_tip_issue_begin_end_day: "teema avati ja sulgeti samal pÃ¤eval"
+  text_project_identifier_info: "Lubatud on ainult vÃ¤ikesed tÃ¤hed (a-z), numbrid ja kriipsud.<br />Peale salvestamist ei saa tunnust enam muuta."
+  text_caracters_maximum: "%{count} mÃ¤rki kÃµige rohkem."
+  text_caracters_minimum: "Peab olema vÃ¤hemalt %{count} mÃ¤rki pikk."
+  text_length_between: "Pikkus %{min} kuni %{max} mÃ¤rki."
+  text_tracker_no_workflow: "Selle valdkonna jaoks ei ole Ã¼htegi tÃ¶Ã¶voogu kirjeldatud"
+  text_unallowed_characters: "Lubamatud mÃ¤rgid"
+  text_comma_separated: "Lubatud erinevad vÃ¤Ã¤rtused (komaga eraldatult)."
+  text_line_separated: "Lubatud erinevad vÃ¤Ã¤rtused (igaÃ¼ks eraldi real)."
+  text_issues_ref_in_commit_messages: "Teemadele ja parandustele viitamine sissekannete mÃ¤rkustes"
+  text_issue_added: "%{author} lisas uue teema %{id}."
+  text_issue_updated: "%{author} uuendas teemat %{id}."
+  text_wiki_destroy_confirmation: "Oled Sa kindel oma soovis kustutada see Viki koos kogu sisuga?"
+  text_issue_category_destroy_question: "Kustutatavat kategooriat kasutab %{count} teema(t). Mis Sa soovid nendega ette vÃµtta?"
+  text_issue_category_destroy_assignments: "JÃ¤ta teemadel kategooria mÃ¤Ã¤ramata"
+  text_issue_category_reassign_to: "MÃ¤Ã¤ra teemad teise kategooriasse"
+  text_user_mail_option: "Valimata projektidest saad teavitusi ainult jÃ¤lgitavate vÃµi Sinuga seotud asjade kohta (nt. Sinu loodud vÃµi teha teemad)."
+  text_no_configuration_data: "Rollid, valdkonnad, olekud ja tÃ¶Ã¶vood ei ole veel seadistatud.\nVÃ¤ga soovitav on laadida vaikeasetused. Peale laadimist saad neid ise muuta."
+  text_load_default_configuration: "Lae vaikeasetused"
+  text_status_changed_by_changeset: "Kehtestatakse muudatuses %{value}."
+  text_time_logged_by_changeset: "Kehtestatakse muudatuses %{value}."
+  text_issues_destroy_confirmation: "Oled Sa kindel oma soovis valitud teema(d) kustutada?"
+  text_issues_destroy_descendants_confirmation: "See kustutab samuti %{count} alamteemat."
+  text_time_entries_destroy_confirmation: "Oled Sa kindel oma soovis valitud ajakulu kanne/kanded kustutada?"
+  text_select_project_modules: "Projektis kasutatavad moodulid"
+  text_default_administrator_account_changed: "Algne administraatori konto on muudetud"
+  text_file_repository_writable: "Manuste kataloog on kirjutatav"
+  text_plugin_assets_writable: "Lisamoodulite abifailide kataloog on kirjutatav"
+  text_rmagick_available: "RMagick on kasutatav (mittekohustuslik)"
+  text_destroy_time_entries_question: "Kustutatavatele teemadele oli kirja pandud %{hours} tundi. Mis Sa soovid ette vÃµtta?"
+  text_destroy_time_entries: "Kustuta need tunnid"
+  text_assign_time_entries_to_project: "Vii tunnid Ã¼le teise projekti"
+  text_reassign_time_entries: "MÃ¤Ã¤ra tunnid sellele teemale:"
+  text_user_wrote: "%{value} kirjutas:"
+  text_enumeration_destroy_question: "Selle vÃ¤Ã¤rtusega on seotud %{count} objekt(i)."
+  text_enumeration_category_reassign_to: "Seo nad teise vÃ¤Ã¤rtuse kÃ¼lge:"
+  text_email_delivery_not_configured: "E-kirjade saatmine ei ole seadistatud ja teavitusi ei saadeta.\nKonfigureeri oma SMTP server failis config/configuration.yml ja taaskÃ¤ivita Redmine."
+  text_repository_usernames_mapping: "Seosta Redmine kasutaja hoidlasse sissekannete tegijaga.\nSama nime vÃµi e-postiga kasutajad seostatakse automaatselt."
+  text_diff_truncated: "... Osa erinevusi jÃ¤i vÃ¤lja, sest neid on nÃ¤itamiseks liiga palju."
+  text_custom_field_possible_values_info: "Ãœks rida iga vÃ¤Ã¤rtuse jaoks"
+  text_wiki_page_destroy_question: "Sel lehel on %{descendants} jÃ¤rglasleht(e) ja jÃ¤reltulija(t). Mis Sa soovid ette vÃµtta?"
+  text_wiki_page_nullify_children: "Muuda jÃ¤rglaslehed uuteks juurlehtedeks"
+  text_wiki_page_destroy_children: "Kustuta jÃ¤rglaslehed ja kÃµik nende jÃ¤rglased"
+  text_wiki_page_reassign_children: "MÃ¤Ã¤ra jÃ¤rglaslehed teise lehe kÃ¼lge"
+  text_own_membership_delete_confirmation: "Sa vÃµtad endalt Ã¤ra osa vÃµi kÃµik Ãµigused ega saa edaspidi seda projekti vÃµib-olla enam muuta.\nOled Sa jÃ¤tkamises kindel?"
+  text_zoom_in: "Vaata lÃ¤hemalt"
+  text_zoom_out: "Vaata kaugemalt"
+  text_warn_on_leaving_unsaved: "Sel lehel on salvestamata teksti, mis lÃ¤heb kaduma, kui siit lehelt lahkud."
+  text_scm_path_encoding_note: "Vaikimisi UTF-8"
+  text_git_repository_note: "Hoidla peab olema paljas (bare) ja kohalik (nt. /gitrepo, c:\\gitrepo)"
+  text_mercurial_repository_note: "Hoidla peab olema kohalik (nt. /hgrepo, c:\\hgrepo)"
+  text_scm_command: "Hoidla poole pÃ¶Ã¶rdumise kÃ¤sk"
+  text_scm_command_version: "Versioon"
+  text_scm_config: "Hoidlate poole pÃ¶Ã¶rdumist saab konfigureerida failis config/configuration.yml. Peale selle muutmist taaskÃ¤ivita Redmine."
+  text_scm_command_not_available: "Hoidla poole pÃ¶Ã¶rdumine ebaÃµnnestus. Palun kontrolli seadistusi."
+  text_issue_conflict_resolution_overwrite: "Kehtesta oma muudatused (kÃµik mÃ¤rkused jÃ¤Ã¤vad, ent muu vÃµidakse Ã¼le kirjutada)"
+  text_issue_conflict_resolution_add_notes: "Lisa oma mÃ¤rkused, aga loobu teistest muudatustest"
+  text_issue_conflict_resolution_cancel: "Loobu kÃµigist muudatustest ja lae %{link} uuesti"
+  text_account_destroy_confirmation: "Oled Sa kindel?\nSu konto kustutatakse jÃ¤Ã¤davalt ja seda pole vÃµimalik taastada."
+
+  default_role_manager: "Haldaja"
+  default_role_developer: "Arendaja"
+  default_role_reporter: "Edastaja"
+  default_tracker_bug: "Veaparandus"
+  default_tracker_feature: "TÃ¤iendus"
+  default_tracker_support: "Klienditugi"
+  default_issue_status_new: "Avatud"
+  default_issue_status_in_progress: "TÃ¶Ã¶s"
+  default_issue_status_resolved: "Lahendatud"
+  default_issue_status_feedback: "Tagasiside"
+  default_issue_status_closed: "Suletud"
+  default_issue_status_rejected: "Tagasi lÃ¼katud"
+  default_doc_category_user: "Juhend lÃµppkasutajale"
+  default_doc_category_tech: "Tehniline dokumentatsioon"
+  default_priority_low: "Aega on"
+  default_priority_normal: "Tavaline"
+  default_priority_high: "Pakiline"
+  default_priority_urgent: "TÃ¤na vaja"
+  default_priority_immediate: "Kohe vaja"
+  default_activity_design: "Kavandamine"
+  default_activity_development: "Arendamine"
+
+  enumeration_issue_priorities: "Teemade prioriteedid"
+  enumeration_doc_categories: "Dokumentide kategooriad"
+  enumeration_activities: "Tegevused (ajakulu)"
+  enumeration_system_activity: "SÃ¼steemi aktiivsus"
+  description_filter: "Filter"
+  description_search: "OtsinguvÃ¤li"
+  description_choose_project: "Projektid"
+  description_project_scope: "Otsingu ulatus"
+  description_notes: "MÃ¤rkused"
+  description_message_content: "Postituse sisu"
+  description_query_sort_criteria_attribute: "Sorteerimise kriteerium"
+  description_query_sort_criteria_direction: "Sorteerimise suund"
+  description_user_mail_notification: "E-kirjaga teavitamise seaded"
+  description_available_columns: "Kasutatavad veerud"
+  description_selected_columns: "Valitud veerud"
+  description_all_columns: "KÃµik veerud"
+  description_issue_category_reassign: "Vali uus kategooria"
+  description_wiki_subpages_reassign: "Vali lehele uus vanem"
+  description_date_range_list: "Vali vahemik nimekirjast"
+  description_date_range_interval: "Vali vahemik algus- ja lÃµpukuupÃ¤eva abil"
+  description_date_from: "Sisesta alguskuupÃ¤ev"
+  description_date_to: "Sisesta lÃµpukuupÃ¤ev"
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: "Lubatud on ainult vÃ¤ikesed tÃ¤hed (a-z), numbrid ja kriipsud.<br />Peale salvestamist ei saa tunnust enam muuta."
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: "kÃµik"
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: "alamprojektidega"
+  label_cross_project_tree: "projektipuuga"
+  label_cross_project_hierarchy: "projektihierarhiaga"
+  label_cross_project_system: "kÃµigi projektidega"
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: "Kokku"
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f0/f0bee1a6f97328341c5f17af5852ef8e9b541a2f.svn-base
--- a/.svn/pristine/f0/f0bee1a6f97328341c5f17af5852ef8e9b541a2f.svn-base
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace :db do
-  desc 'Migrates installed plugins.'
-  task :migrate_plugins => :environment do
-    if Rails.respond_to?('plugins')
-      Rails.plugins.each do |plugin|
-        next unless plugin.respond_to?('migrate')
-        puts "Migrating #{plugin.name}..."
-        plugin.migrate
-      end
-    else
-      puts "Undefined method plugins for Rails!"
-      puts "Make sure engines plugin is installed."
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f0/f0fe31ac5f17043ea781f9726c23dec0ad91d555.svn-base
--- a/.svn/pristine/f0/f0fe31ac5f17043ea781f9726c23dec0ad91d555.svn-base
+++ /dev/null
@@ -1,68 +0,0 @@
-/* 
-	calendar-sk.js
-	language: Slovak
-	encoding: UTF-8
-	author: Stanislav Pach (stano.pach@seznam.cz)
-*/
-
-// ** I18N
-Calendar._DN  = new Array('NedeÄ¾a','Pondelok','Utorok','Streda','Å tvrtok','Piatok','Sobota','NedeÄ¾a');
-Calendar._SDN = new Array('Ne','Po','Ut','St','Å t','Pi','So','Ne');
-Calendar._MN  = new Array('JanuÃ¡r','FebruÃ¡r','Marec','AprÃ­l','MÃ¡j','JÃºn','JÃºl','August','September','OktÃ³ber','November','December');
-Calendar._SMN = new Array('Jan','Feb','Mar','Apr','MÃ¡j','JÃºn','JÃºl','Aug','Sep','Okt','Nov','Dec');
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "O komponente kalendÃ¡r";
-Calendar._TT["TOGGLE"] = "Zmena prvÃ©ho dÅˆa v tÃ½Å¾dni";
-Calendar._TT["PREV_YEAR"] = "PredchÃ¡dzajÃºci rok (pridrÅ¾ pre menu)";
-Calendar._TT["PREV_MONTH"] = "PredchÃ¡dzajÃºci mesiac (pridrÅ¾ pre menu)";
-Calendar._TT["GO_TODAY"] = "DneÅ¡nÃ½ dÃ¡tum";
-Calendar._TT["NEXT_MONTH"] = "ÄŽalÅ¡Ã­ mesiac (pridrÅ¾ pre menu)";
-Calendar._TT["NEXT_YEAR"] = "ÄŽalÅ¡Ã­ rok (pridrÅ¾ pre menu)";
-Calendar._TT["SEL_DATE"] = "ZvoÄ¾ dÃ¡tum";
-Calendar._TT["DRAG_TO_MOVE"] = "ChyÅ¥ a Å¥ahaj pre presun";
-Calendar._TT["PART_TODAY"] = " (dnes)";
-Calendar._TT["MON_FIRST"] = "UkÃ¡Å¾ ako prvnÃ½ Pondelok";
-//Calendar._TT["SUN_FIRST"] = "UkaÅ¾ jako prvnÃ­ NedÄ›li";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"VÃ½ber dÃ¡tumu:\n" +
-"- PouÅ¾ijte tlaÄÃ­tka \xab, \xbb pre voÄ¾bu roku\n" +
-"- PouÅ¾ijte tlaÄÃ­tka " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pre vÃ½ber mesiaca\n" +
-"- PodrÅ¾te tlaÄÃ­tko myÅ¡i na akomkoÄ¾vek z tÃ½chto tlaÄÃ­tok pre rÃ½chlejÅ¡Ã­ vÃ½ber.";
-
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"VÃ½ber Äasu:\n" +
-"- Kliknite na akÃºkoÄ¾vek ÄasÅ¥ z vÃ½beru Äasu pre zvÃ½Å¡enie.\n" +
-"- alebo Shift-klick pre znÃ­Å¾enie\n" +
-"- alebo kliknite a Å¥ahajte pre rÃ½chlejÅ¡Ã­ vÃ½ber.";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Zobraz %s ako prvÃ½";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "ZavrieÅ¥";
-Calendar._TT["TODAY"] = "Dnes";
-Calendar._TT["TIME_PART"] = "(Shift-)Klikni alebo Å¥ahaj pre zmenu hodnoty";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "tÃ½Å¾";
-Calendar._TT["TIME"] = "ÄŒas:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f1/f108ac16dd89fdc6a9b76af157a8c69b5dc81117.svn-base
--- a/.svn/pristine/f1/f108ac16dd89fdc6a9b76af157a8c69b5dc81117.svn-base
+++ /dev/null
@@ -1,22 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class VersionCustomField < CustomField
-  def type_name
-    :label_version_plural
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f1/f11f6b57f7e2388c7777d4dc34576404ddd5230b.svn-base
--- /dev/null
+++ b/.svn/pristine/f1/f11f6b57f7e2388c7777d4dc34576404ddd5230b.svn-base
@@ -0,0 +1,135 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module AccessControl
+
+    class << self
+      def map
+        mapper = Mapper.new
+        yield mapper
+        @permissions ||= []
+        @permissions += mapper.mapped_permissions
+      end
+
+      def permissions
+        @permissions
+      end
+
+      # Returns the permission of given name or nil if it wasn't found
+      # Argument should be a symbol
+      def permission(name)
+        permissions.detect {|p| p.name == name}
+      end
+
+      # Returns the actions that are allowed by the permission of given name
+      def allowed_actions(permission_name)
+        perm = permission(permission_name)
+        perm ? perm.actions : []
+      end
+
+      def public_permissions
+        @public_permissions ||= @permissions.select {|p| p.public?}
+      end
+
+      def members_only_permissions
+        @members_only_permissions ||= @permissions.select {|p| p.require_member?}
+      end
+
+      def loggedin_only_permissions
+        @loggedin_only_permissions ||= @permissions.select {|p| p.require_loggedin?}
+      end
+
+      def read_action?(action)
+        if action.is_a?(Symbol)
+          perm = permission(action)
+          !perm.nil? && perm.read?
+        else
+          s = "#{action[:controller]}/#{action[:action]}"
+          permissions.detect {|p| p.actions.include?(s) && !p.read?}.nil?
+        end
+      end
+
+      def available_project_modules
+        @available_project_modules ||= @permissions.collect(&:project_module).uniq.compact
+      end
+
+      def modules_permissions(modules)
+        @permissions.select {|p| p.project_module.nil? || modules.include?(p.project_module.to_s)}
+      end
+    end
+
+    class Mapper
+      def initialize
+        @project_module = nil
+      end
+
+      def permission(name, hash, options={})
+        @permissions ||= []
+        options.merge!(:project_module => @project_module)
+        @permissions << Permission.new(name, hash, options)
+      end
+
+      def project_module(name, options={})
+        @project_module = name
+        yield self
+        @project_module = nil
+      end
+
+      def mapped_permissions
+        @permissions
+      end
+    end
+
+    class Permission
+      attr_reader :name, :actions, :project_module
+
+      def initialize(name, hash, options)
+        @name = name
+        @actions = []
+        @public = options[:public] || false
+        @require = options[:require]
+        @read = options[:read] || false
+        @project_module = options[:project_module]
+        hash.each do |controller, actions|
+          if actions.is_a? Array
+            @actions << actions.collect {|action| "#{controller}/#{action}"}
+          else
+            @actions << "#{controller}/#{actions}"
+          end
+        end
+        @actions.flatten!
+      end
+
+      def public?
+        @public
+      end
+
+      def require_member?
+        @require && @require == :member
+      end
+
+      def require_loggedin?
+        @require && (@require == :member || @require == :loggedin)
+      end
+
+      def read?
+        @read
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f1/f1aa1c74cb4d4af415b3365a155de04ad0478b83.svn-base
--- /dev/null
+++ b/.svn/pristine/f1/f1aa1c74cb4d4af415b3365a155de04ad0478b83.svn-base
@@ -0,0 +1,1084 @@
+ro:
+  direction: ltr
+  date:
+    formats:
+      default: "%d-%m-%Y"
+      short: "%d %b"
+      long: "%d %B %Y"
+      only_day: "%e"
+
+    day_names: [DuminicÄƒ, Luni, Marti, Miercuri, Joi, Vineri, SÃ¢mbÄƒtÄƒ]
+    abbr_day_names: [Dum, Lun, Mar, Mie, Joi, Vin, SÃ¢m]
+
+    month_names: [~, Ianuarie, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie]
+    abbr_month_names: [~, Ian, Feb, Mar, Apr, Mai, Iun, Iul, Aug, Sep, Oct, Noi, Dec]
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%m/%d/%Y %I:%M %p"
+      time: "%I:%M %p"
+      short: "%d %b %H:%M"
+      long: "%B %d, %Y %H:%M"
+    am: "am"
+    pm: "pm"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "jumÄƒtate de minut"
+      less_than_x_seconds:
+        one:   "mai puÈ›in de o secundÄƒ"
+        other: "mai puÈ›in de %{count} secunde"
+      x_seconds:
+        one:   "o secundÄƒ"
+        other: "%{count} secunde"
+      less_than_x_minutes:
+        one:   "mai puÈ›in de un minut"
+        other: "mai puÈ›in de %{count} minute"
+      x_minutes:
+        one:   "un minut"
+        other: "%{count} minute"
+      about_x_hours:
+        one:   "aproximativ o orÄƒ"
+        other: "aproximativ %{count} ore"
+      x_hours:
+        one:   "1 orÄƒ"
+        other: "%{count} ore"
+      x_days:
+        one:   "o zi"
+        other: "%{count} zile"
+      about_x_months:
+        one:   "aproximativ o lunÄƒ"
+        other: "aproximativ %{count} luni"
+      x_months:
+        one:   "o luna"
+        other: "%{count} luni"
+      about_x_years:
+        one:   "aproximativ un an"
+        other: "aproximativ %{count} ani"
+      over_x_years:
+        one:   "peste un an"
+        other: "peste %{count} ani"
+      almost_x_years:
+        one:   "almost 1 year"
+        other: "almost %{count} years"
+
+  number:
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+
+    human:
+      format:
+        precision: 3
+        delimiter: ""
+      storage_units:
+        format: "%n %u"
+        units:
+          kb: KB
+          tb: TB
+          gb: GB
+          byte:
+            one: Byte
+            other: Bytes
+          mb: MB
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "È™i"
+      skip_last_comma: true
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "1 error prohibited this %{model} from being saved"
+          other:  "%{count} errors prohibited this %{model} from being saved"
+      messages:
+        inclusion: "nu este inclus Ã®n listÄƒ"
+        exclusion: "este rezervat"
+        invalid: "nu este valid"
+        confirmation: "nu este identicÄƒ"
+        accepted: "trebuie acceptat"
+        empty: "trebuie completat"
+        blank: "nu poate fi gol"
+        too_long: "este prea lung"
+        too_short: "este prea scurt"
+        wrong_length: "nu are lungimea corectÄƒ"
+        taken: "a fost luat deja"
+        not_a_number: "nu este un numÄƒr"
+        not_a_date: "nu este o datÄƒ validÄƒ"
+        greater_than: "trebuie sÄƒ fie mai mare de %{count}"
+        greater_than_or_equal_to: "trebuie sÄƒ fie mai mare sau egal cu %{count}"
+        equal_to: "trebuie sÄƒ fie egal cu {count}}"
+        less_than: "trebuie sÄƒ fie mai mic decat %{count}"
+        less_than_or_equal_to: "trebuie sÄƒ fie mai mic sau egal cu %{count}"
+        odd: "trebuie sÄƒ fie impar"
+        even: "trebuie sÄƒ fie par"
+        greater_than_start_date: "trebuie sÄƒ fie dupÄƒ data de Ã®nceput"
+        not_same_project: "trebuie sÄƒ aparÈ›inÄƒ aceluiaÈ™i proiect"
+        circular_dependency: "AceastÄƒ relaÈ›ie ar crea o dependenÈ›Äƒ circularÄƒ"
+        cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks"
+
+  actionview_instancetag_blank_option: SelectaÈ›i
+
+  general_text_No: 'Nu'
+  general_text_Yes: 'Da'
+  general_text_no: 'nu'
+  general_text_yes: 'da'
+  general_lang_name: 'RomÃ¢nÄƒ'
+  general_csv_separator: '.'
+  general_csv_decimal_separator: ','
+  general_csv_encoding: UTF-8
+  general_pdf_encoding: UTF-8
+  general_first_day_of_week: '2'
+
+  notice_account_updated: Cont actualizat.
+  notice_account_invalid_creditentials: Utilizator sau parola nevalidÄƒ
+  notice_account_password_updated: ParolÄƒ actualizatÄƒ.
+  notice_account_wrong_password: ParolÄƒ greÈ™itÄƒ
+  notice_account_register_done: Contul a fost creat. Pentru activare, urmaÈ›i legÄƒtura trimisÄƒ prin email.
+  notice_account_unknown_email: Utilizator necunoscut.
+  notice_can_t_change_password: Acest cont foloseÈ™te o sursÄƒ externÄƒ de autentificare. Nu se poate schimba parola.
+  notice_account_lost_email_sent: S-a trimis un email cu instrucÈ›iuni de schimbare a parolei.
+  notice_account_activated: Contul a fost activat. VÄƒ puteÈ›i autentifica acum.
+  notice_successful_create: Creat.
+  notice_successful_update: Actualizat.
+  notice_successful_delete: È˜ters.
+  notice_successful_connection: Conectat.
+  notice_file_not_found: Pagina pe care doriÈ›i sÄƒ o accesaÈ›i nu existÄƒ sau a fost È™tearsÄƒ.
+  notice_locking_conflict: Datele au fost actualizate de alt utilizator.
+  notice_not_authorized: Nu sunteÈ›i autorizat sa accesaÈ›i aceastÄƒ paginÄƒ.
+  notice_email_sent: "S-a trimis un email cÄƒtre %{value}"
+  notice_email_error: "A intervenit o eroare la trimiterea de email (%{value})"
+  notice_feeds_access_key_reseted: Cheia de acces RSS a fost resetatÄƒ.
+  notice_failed_to_save_issues: "Nu s-au putut salva %{count} tichete din cele %{total} selectate: %{ids}."
+  notice_no_issue_selected: "Niciun tichet selectat! VÄƒ rugÄƒm sÄƒ selectaÈ›i tichetele pe care doriÈ›i sÄƒ le editaÈ›i."
+  notice_account_pending: "Contul dumneavoastrÄƒ a fost creat È™i aÈ™teaptÄƒ aprobarea administratorului."
+  notice_default_data_loaded: S-a Ã®ncÄƒrcat configuraÈ›ia implicitÄƒ.
+  notice_unable_delete_version: Nu se poate È™terge versiunea.
+
+  error_can_t_load_default_data: "Nu s-a putut Ã®ncÄƒrca configuraÈ›ia implicitÄƒ: %{value}"
+  error_scm_not_found: "Nu s-a gÄƒsit articolul sau revizia Ã®n depozit."
+  error_scm_command_failed: "A intervenit o eroare la accesarea depozitului: %{value}"
+  error_scm_annotate: "Nu existÄƒ sau nu poate fi adnotatÄƒ."
+  error_issue_not_found_in_project: 'Tichetul nu a fost gÄƒsit sau nu aparÈ›ine acestui proiect'
+
+  warning_attachments_not_saved: "Nu s-au putut salva %{count} fiÈ™iere."
+
+  mail_subject_lost_password: "Parola dumneavoastrÄƒ: %{value}"
+  mail_body_lost_password: 'Pentru a schimba parola, accesaÈ›i:'
+  mail_subject_register: "Activarea contului %{value}"
+  mail_body_register: 'Pentru activarea contului, accesaÈ›i:'
+  mail_body_account_information_external: "PuteÈ›i folosi contul â€ž{value}}â€ pentru a vÄƒ autentifica."
+  mail_body_account_information: InformaÈ›ii despre contul dumneavoastrÄƒ
+  mail_subject_account_activation_request: "Cerere de activare a contului %{value}"
+  mail_body_account_activation_request: "S-a Ã®nregistrat un utilizator nou (%{value}). Contul aÈ™teaptÄƒ aprobarea dumneavoastrÄƒ:"
+  mail_subject_reminder: "%{count} tichete trebuie rezolvate Ã®n urmÄƒtoarele %{days} zile"
+  mail_body_reminder: "%{count} tichete atribuite dumneavoastrÄƒ trebuie rezolvate Ã®n urmÄƒtoarele %{days} zile:"
+
+
+  field_name: Nume
+  field_description: Descriere
+  field_summary: Rezumat
+  field_is_required: Obligatoriu
+  field_firstname: Prenume
+  field_lastname: Nume
+  field_mail: Email
+  field_filename: FiÈ™ier
+  field_filesize: MÄƒrime
+  field_downloads: DescÄƒrcÄƒri
+  field_author: Autor
+  field_created_on: Creat la
+  field_updated_on: Actualizat la
+  field_field_format: Format
+  field_is_for_all: Pentru toate proiectele
+  field_possible_values: Valori posibile
+  field_regexp: Expresie regularÄƒ
+  field_min_length: lungime minimÄƒ
+  field_max_length: lungime maximÄƒ
+  field_value: Valoare
+  field_category: Categorie
+  field_title: Titlu
+  field_project: Proiect
+  field_issue: Tichet
+  field_status: Stare
+  field_notes: Note
+  field_is_closed: Rezolvat
+  field_is_default: Implicit
+  field_tracker: Tip de tichet
+  field_subject: Subiect
+  field_due_date: Data finalizÄƒrii
+  field_assigned_to: Atribuit
+  field_priority: Prioritate
+  field_fixed_version: Versiune È›intÄƒ
+  field_user: Utilizator
+  field_role: Rol
+  field_homepage: Pagina principalÄƒ
+  field_is_public: Public
+  field_parent: Sub-proiect al
+  field_is_in_roadmap: Tichete afiÈ™ate Ã®n plan
+  field_login: Autentificare
+  field_mail_notification: NotificÄƒri prin e-mail
+  field_admin: Administrator
+  field_last_login_on: Ultima autentificare Ã®n
+  field_language: Limba
+  field_effective_date: Data
+  field_password: Parola
+  field_new_password: Parola nouÄƒ
+  field_password_confirmation: Confirmare
+  field_version: Versiune
+  field_type: Tip
+  field_host: GazdÄƒ
+  field_port: Port
+  field_account: Cont
+  field_base_dn: Base DN
+  field_attr_login: Atribut autentificare
+  field_attr_firstname: Atribut prenume
+  field_attr_lastname: Atribut nume
+  field_attr_mail: Atribut email
+  field_onthefly: Creare utilizator pe loc
+  field_start_date: Data Ã®nceperii
+  field_done_ratio: Realizat (%)
+  field_auth_source: Mod autentificare
+  field_hide_mail: Nu se afiÈ™eazÄƒ adresa de email
+  field_comments: Comentariu
+  field_url: URL
+  field_start_page: Pagina de start
+  field_subproject: Subproiect
+  field_hours: Ore
+  field_activity: Activitate
+  field_spent_on: Data
+  field_identifier: Identificator
+  field_is_filter: Filtru
+  field_issue_to: Tichet asociat
+  field_delay: ÃŽntÃ¢rziere
+  field_assignable: Se pot atribui tichete acestui rol
+  field_redirect_existing_links: RedirecÈ›ioneazÄƒ legÄƒturile existente
+  field_estimated_hours: Timp estimat
+  field_column_names: Coloane
+  field_time_zone: Fus orar
+  field_searchable: CÄƒutare
+  field_default_value: Valoare implicita
+  field_comments_sorting: AfiÈ™eazÄƒ comentarii
+  field_parent_title: Pagina superioara
+  field_editable: Modificabil
+  field_watcher: UrmÄƒreÈ™te
+  field_identity_url: URL OpenID
+  field_content: ConÈ›inut
+
+  setting_app_title: Titlu aplicaÈ›ie
+  setting_app_subtitle: Subtitlu aplicaÈ›ie
+  setting_welcome_text: Text de Ã®ntÃ¢mpinare
+  setting_default_language: Limba implicita
+  setting_login_required: Necesita autentificare
+  setting_self_registration: ÃŽnregistrare automatÄƒ
+  setting_attachment_max_size: MÄƒrime maxima ataÈ™ament
+  setting_issues_export_limit: LimitÄƒ de tichete exportate
+  setting_mail_from: Adresa de email a expeditorului
+  setting_bcc_recipients: AlÈ›i destinatari pentru email (BCC)
+  setting_plain_text_mail: Mesaje text (fÄƒrÄƒ HTML)
+  setting_host_name: Numele gazdei È™i calea
+  setting_text_formatting: Formatare text
+  setting_wiki_compression: Comprimare istoric Wiki
+  setting_feeds_limit: Limita de actualizÄƒri din feed
+  setting_default_projects_public: Proiectele noi sunt implicit publice
+  setting_autofetch_changesets: Preluare automatÄƒ a modificÄƒrilor din depozit
+  setting_sys_api_enabled: Activare WS pentru gestionat depozitul
+  setting_commit_ref_keywords: Cuvinte cheie pt. referire tichet
+  setting_commit_fix_keywords: Cuvinte cheie pt. rezolvare tichet
+  setting_autologin: Autentificare automatÄƒ
+  setting_date_format: Format datÄƒ
+  setting_time_format: Format orÄƒ
+  setting_cross_project_issue_relations: Permite legÄƒturi de tichete Ã®ntre proiecte
+  setting_issue_list_default_columns: Coloane implicite afiÈ™ate Ã®n lista de tichete
+  setting_emails_footer: Subsol email
+  setting_protocol: Protocol
+  setting_per_page_options: NumÄƒr de obiecte pe paginÄƒ
+  setting_user_format: Stil de afiÈ™are pentru utilizator
+  setting_activity_days_default: Se afiÈ™eazÄƒ zile Ã®n jurnalul proiectului
+  setting_display_subprojects_issues: AfiÈ™eazÄƒ implicit tichetele sub-proiectelor Ã®n proiectele principale
+  setting_enabled_scm: SCM activat
+  setting_mail_handler_api_enabled: Activare WS pentru email primit
+  setting_mail_handler_api_key: cheie API
+  setting_sequential_project_identifiers: GenereazÄƒ secvenÈ›ial identificatoarele de proiect
+  setting_gravatar_enabled: FoloseÈ™te poze Gravatar pentru utilizatori
+  setting_diff_max_lines_displayed: NumÄƒr maxim de linii de diferenÈ›Äƒ afiÈ™ate
+  setting_file_max_size_displayed: NumÄƒr maxim de fiÈ™iere text afiÈ™ate Ã®n paginÄƒ (inline)
+  setting_repository_log_display_limit: NumÄƒr maxim de revizii afiÈ™ate Ã®n istoricul fiÈ™ierului
+  setting_openid: Permite Ã®nregistrare È™i autentificare cu OpenID
+
+  permission_edit_project: EditeazÄƒ proiectul
+  permission_select_project_modules: Alege module pentru proiect
+  permission_manage_members: EditeazÄƒ membri
+  permission_manage_versions: EditeazÄƒ versiuni
+  permission_manage_categories: EditeazÄƒ categorii
+  permission_add_issues: AdaugÄƒ tichete
+  permission_edit_issues: EditeazÄƒ tichete
+  permission_manage_issue_relations: EditeazÄƒ relaÈ›ii tichete
+  permission_add_issue_notes: AdaugÄƒ note
+  permission_edit_issue_notes: EditeazÄƒ note
+  permission_edit_own_issue_notes: EditeazÄƒ notele proprii
+  permission_move_issues: MutÄƒ tichete
+  permission_delete_issues: È˜terge tichete
+  permission_manage_public_queries: EditeazÄƒ cÄƒutÄƒrile implicite
+  permission_save_queries: SalveazÄƒ cÄƒutÄƒrile
+  permission_view_gantt: AfiÈ™eazÄƒ Gantt
+  permission_view_calendar: AfiÈ™eazÄƒ calendarul
+  permission_view_issue_watchers: AfiÈ™eazÄƒ lista de persoane interesate
+  permission_add_issue_watchers: AdaugÄƒ persoane interesate
+  permission_log_time: ÃŽnregistreazÄƒ timpul de lucru
+  permission_view_time_entries: AfiÈ™eazÄƒ timpul de lucru
+  permission_edit_time_entries: EditeazÄƒ jurnalele cu timp de lucru
+  permission_edit_own_time_entries: EditeazÄƒ jurnalele proprii cu timpul de lucru
+  permission_manage_news: EditeazÄƒ È™tiri
+  permission_comment_news: ComenteazÄƒ È™tirile
+  permission_view_documents: AfiÈ™eazÄƒ documente
+  permission_manage_files: EditeazÄƒ fiÈ™iere
+  permission_view_files: AfiÈ™eazÄƒ fiÈ™iere
+  permission_manage_wiki: EditeazÄƒ wiki
+  permission_rename_wiki_pages: RedenumeÈ™te pagini wiki
+  permission_delete_wiki_pages: È˜terge pagini wiki
+  permission_view_wiki_pages: AfiÈ™eazÄƒ wiki
+  permission_view_wiki_edits: AfiÈ™eazÄƒ istoricul wiki
+  permission_edit_wiki_pages: EditeazÄƒ pagini wiki
+  permission_delete_wiki_pages_attachments: È˜terge ataÈ™amente
+  permission_protect_wiki_pages: BlocheazÄƒ pagini wiki
+  permission_manage_repository: GestioneazÄƒ depozitul
+  permission_browse_repository: RÄƒsfoieÈ™te depozitul
+  permission_view_changesets: AfiÈ™eazÄƒ modificÄƒrile din depozit
+  permission_commit_access: Acces commit
+  permission_manage_boards: EditeazÄƒ forum
+  permission_view_messages: AfiÈ™eazÄƒ mesaje
+  permission_add_messages: Scrie mesaje
+  permission_edit_messages: EditeazÄƒ mesaje
+  permission_edit_own_messages: EditeazÄƒ mesajele proprii
+  permission_delete_messages: È˜terge mesaje
+  permission_delete_own_messages: È˜terge mesajele proprii
+
+  project_module_issue_tracking: Tichete
+  project_module_time_tracking: Timp de lucru
+  project_module_news: È˜tiri
+  project_module_documents: Documente
+  project_module_files: FiÈ™iere
+  project_module_wiki: Wiki
+  project_module_repository: Depozit
+  project_module_boards: Forum
+
+  label_user: Utilizator
+  label_user_plural: Utilizatori
+  label_user_new: Utilizator nou
+  label_project: Proiect
+  label_project_new: Proiect nou
+  label_project_plural: Proiecte
+  label_x_projects:
+    zero:  niciun proiect
+    one:   un proiect
+    other: "%{count} proiecte"
+  label_project_all: Toate proiectele
+  label_project_latest: Proiecte noi
+  label_issue: Tichet
+  label_issue_new: Tichet nou
+  label_issue_plural: Tichete
+  label_issue_view_all: AfiÈ™eazÄƒ toate tichetele
+  label_issues_by: "SorteazÄƒ dupÄƒ %{value}"
+  label_issue_added: Adaugat
+  label_issue_updated: Actualizat
+  label_document: Document
+  label_document_new: Document nou
+  label_document_plural: Documente
+  label_document_added: AdÄƒugat
+  label_role: Rol
+  label_role_plural: Roluri
+  label_role_new: Rol nou
+  label_role_and_permissions: Roluri È™i permisiuni
+  label_member: Membru
+  label_member_new: membru nou
+  label_member_plural: Membri
+  label_tracker: Tip de tichet
+  label_tracker_plural: Tipuri de tichete
+  label_tracker_new: Tip nou de tichet
+  label_workflow: Mod de lucru
+  label_issue_status: Stare tichet
+  label_issue_status_plural: Stare tichete
+  label_issue_status_new: Stare nouÄƒ
+  label_issue_category: Categorie de tichet
+  label_issue_category_plural: Categorii de tichete
+  label_issue_category_new: Categorie nouÄƒ
+  label_custom_field: CÃ¢mp personalizat
+  label_custom_field_plural: CÃ¢mpuri personalizate
+  label_custom_field_new: CÃ¢mp nou personalizat
+  label_enumerations: EnumerÄƒri
+  label_enumeration_new: Valoare nouÄƒ
+  label_information: InformaÈ›ie
+  label_information_plural: InformaÈ›ii
+  label_please_login: VÄƒ rugÄƒm sÄƒ vÄƒ autentificaÈ›i
+  label_register: ÃŽnregistrare
+  label_login_with_open_id_option: sau autentificare cu OpenID
+  label_password_lost: ParolÄƒ uitatÄƒ
+  label_home: AcasÄƒ
+  label_my_page: Pagina mea
+  label_my_account: Contul meu
+  label_my_projects: Proiectele mele
+  label_administration: Administrare
+  label_login: Autentificare
+  label_logout: IeÈ™ire din cont
+  label_help: Ajutor
+  label_reported_issues: Tichete
+  label_assigned_to_me_issues: Tichetele mele
+  label_last_login: Ultima conectare
+  label_registered_on: ÃŽnregistrat la
+  label_activity: Activitate
+  label_overall_activity: Activitate - vedere de ansamblu
+  label_user_activity: "Activitate %{value}"
+  label_new: Nou
+  label_logged_as: Autentificat ca
+  label_environment: Mediu
+  label_authentication: Autentificare
+  label_auth_source: Mod de autentificare
+  label_auth_source_new: Nou
+  label_auth_source_plural: Moduri de autentificare
+  label_subproject_plural: Sub-proiecte
+  label_and_its_subprojects: "%{value} È™i sub-proiecte"
+  label_min_max_length: lungime min - max
+  label_list: ListÄƒ
+  label_date: DatÄƒ
+  label_integer: ÃŽntreg
+  label_float: Zecimal
+  label_boolean: Valoare logicÄƒ
+  label_string: Text
+  label_text: Text lung
+  label_attribute: Atribut
+  label_attribute_plural: Atribute
+  label_no_data: Nu existÄƒ date de afiÈ™at
+  label_change_status: SchimbÄƒ starea
+  label_history: Istoric
+  label_attachment: FiÈ™ier
+  label_attachment_new: FiÈ™ier nou
+  label_attachment_delete: È˜terge fiÈ™ier
+  label_attachment_plural: FiÈ™iere
+  label_file_added: AdÄƒugat
+  label_report: Raport
+  label_report_plural: Rapoarte
+  label_news: È˜tiri
+  label_news_new: AdaugÄƒ È™tire
+  label_news_plural: È˜tiri
+  label_news_latest: Ultimele È™tiri
+  label_news_view_all: AfiÈ™eazÄƒ toate È™tirile
+  label_news_added: AdÄƒugat
+  label_settings: SetÄƒri
+  label_overview: PaginÄƒ proiect
+  label_version: Versiune
+  label_version_new: Versiune nouÄƒ
+  label_version_plural: Versiuni
+  label_confirmation: Confirmare
+  label_export_to: 'Disponibil È™i Ã®n:'
+  label_read: CiteÈ™te...
+  label_public_projects: Proiecte publice
+  label_open_issues: deschis
+  label_open_issues_plural: deschise
+  label_closed_issues: Ã®nchis
+  label_closed_issues_plural: Ã®nchise
+  label_x_open_issues_abbr_on_total:
+    zero:  0 deschise / %{total}
+    one:   1 deschis / %{total}
+    other: "%{count} deschise / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 deschise
+    one:   1 deschis
+    other: "%{count} deschise"
+  label_x_closed_issues_abbr:
+    zero:  0 Ã®nchise
+    one:   1 Ã®nchis
+    other: "%{count} Ã®nchise"
+  label_total: Total
+  label_permissions: Permisiuni
+  label_current_status: Stare curentÄƒ
+  label_new_statuses_allowed: StÄƒri noi permise
+  label_all: toate
+  label_none: niciunul
+  label_nobody: nimeni
+  label_next: ÃŽnainte
+  label_previous: ÃŽnapoi
+  label_used_by: Folosit de
+  label_details: Detalii
+  label_add_note: AdaugÄƒ o notÄƒ
+  label_per_page: pe paginÄƒ
+  label_calendar: Calendar
+  label_months_from: luni de la
+  label_gantt: Gantt
+  label_internal: Intern
+  label_last_changes: "ultimele %{count} schimbÄƒri"
+  label_change_view_all: AfiÈ™eazÄƒ toate schimbÄƒrile
+  label_personalize_page: PersonalizeazÄƒ aceasta pagina
+  label_comment: Comentariu
+  label_comment_plural: Comentarii
+  label_x_comments:
+    zero: fara comentarii
+    one: 1 comentariu
+    other: "%{count} comentarii"
+  label_comment_add: AdaugÄƒ un comentariu
+  label_comment_added: AdÄƒugat
+  label_comment_delete: È˜terge comentariul
+  label_query: Cautare personalizata
+  label_query_plural: CÄƒutÄƒri personalizate
+  label_query_new: CÄƒutare nouÄƒ
+  label_filter_add: AdaugÄƒ filtru
+  label_filter_plural: Filtre
+  label_equals: este
+  label_not_equals: nu este
+  label_in_less_than: Ã®n mai puÈ›in de
+  label_in_more_than: Ã®n mai mult de
+  label_in: Ã®n
+  label_today: astÄƒzi
+  label_all_time: oricÃ¢nd
+  label_yesterday: ieri
+  label_this_week: sÄƒptÄƒmÃ¢na aceasta
+  label_last_week: sÄƒptÄƒmÃ¢na trecutÄƒ
+  label_last_n_days: "ultimele %{count} zile"
+  label_this_month: luna aceasta
+  label_last_month: luna trecutÄƒ
+  label_this_year: anul acesta
+  label_date_range: Perioada
+  label_less_than_ago: mai puÈ›in de ... zile
+  label_more_than_ago: mai mult de ... zile
+  label_ago: Ã®n urma
+  label_contains: conÈ›ine
+  label_not_contains: nu conÈ›ine
+  label_day_plural: zile
+  label_repository: Depozit
+  label_repository_plural: Depozite
+  label_browse: AfiÈ™eazÄƒ
+  label_revision: Revizie
+  label_revision_plural: Revizii
+  label_associated_revisions: Revizii asociate
+  label_added: adaugatÄƒ
+  label_modified: modificatÄƒ
+  label_copied: copiatÄƒ
+  label_renamed: redenumitÄƒ
+  label_deleted: È™tearsÄƒ
+  label_latest_revision: Ultima revizie
+  label_latest_revision_plural: Ultimele revizii
+  label_view_revisions: AfiÈ™eazÄƒ revizii
+  label_max_size: MÄƒrime maximÄƒ
+  label_sort_highest: Prima
+  label_sort_higher: ÃŽn sus
+  label_sort_lower: ÃŽn jos
+  label_sort_lowest: Ultima
+  label_roadmap: Planificare
+  label_roadmap_due_in: "De terminat Ã®n %{value}"
+  label_roadmap_overdue: "ÃŽntÃ¢rziat cu %{value}"
+  label_roadmap_no_issues: Nu existÄƒ tichete pentru aceastÄƒ versiune
+  label_search: CautÄƒ
+  label_result_plural: Rezultate
+  label_all_words: toate cuvintele
+  label_wiki: Wiki
+  label_wiki_edit: Editare Wiki
+  label_wiki_edit_plural: EditÄƒri Wiki
+  label_wiki_page: PaginÄƒ Wiki
+  label_wiki_page_plural: Pagini Wiki
+  label_index_by_title: SorteazÄƒ dupÄƒ titlu
+  label_index_by_date: SorteazÄƒ dupÄƒ datÄƒ
+  label_current_version: Versiunea curentÄƒ
+  label_preview: Previzualizare
+  label_feed_plural: Feed-uri
+  label_changes_details: Detaliile tuturor schimbÄƒrilor
+  label_issue_tracking: UrmÄƒrire tichete
+  label_spent_time: Timp alocat
+  label_f_hour: "%{value} orÄƒ"
+  label_f_hour_plural: "%{value} ore"
+  label_time_tracking: UrmÄƒrire timp de lucru
+  label_change_plural: SchimbÄƒri
+  label_statistics: Statistici
+  label_commits_per_month: Commit pe luna
+  label_commits_per_author: Commit per autor
+  label_view_diff: AfiÈ™eazÄƒ diferenÈ›ele
+  label_diff_inline: Ã®n linie
+  label_diff_side_by_side: una lÃ¢ngÄƒ alta
+  label_options: OpÈ›iuni
+  label_copy_workflow_from: CopiazÄƒ modul de lucru de la
+  label_permissions_report: Permisiuni
+  label_watched_issues: Tichete urmÄƒrite
+  label_related_issues: Tichete asociate
+  label_applied_status: Stare aplicatÄƒ
+  label_loading: ÃŽncarcÄƒ...
+  label_relation_new: Asociere nouÄƒ
+  label_relation_delete: È˜terge asocierea
+  label_relates_to: asociat cu
+  label_duplicates: duplicate
+  label_duplicated_by: la fel ca
+  label_blocks: blocÄƒri
+  label_blocked_by: blocat de
+  label_precedes: precede
+  label_follows: urmeazÄƒ
+  label_end_to_start: de la sfÃ¢rÈ™it la Ã®nceput
+  label_end_to_end: de la sfÃ¢rÈ™it la sfÃ¢rÈ™it
+  label_start_to_start: de la Ã®nceput la Ã®nceput
+  label_start_to_end: de la Ã®nceput la sfÃ¢rÈ™it
+  label_stay_logged_in: PÄƒstreazÄƒ autentificarea
+  label_disabled: dezactivat
+  label_show_completed_versions: AratÄƒ versiunile terminate
+  label_me: eu
+  label_board: Forum
+  label_board_new: Forum nou
+  label_board_plural: Forumuri
+  label_topic_plural: Subiecte
+  label_message_plural: Mesaje
+  label_message_last: Ultimul mesaj
+  label_message_new: Mesaj nou
+  label_message_posted: AdÄƒugat
+  label_reply_plural: RÄƒspunsuri
+  label_send_information: Trimite utilizatorului informaÈ›iile despre cont
+  label_year: An
+  label_month: LunÄƒ
+  label_week: SÄƒptÄƒmÃ¢nÄƒ
+  label_date_from: De la
+  label_date_to: La
+  label_language_based: Un funcÈ›ie de limba de afiÈ™are a utilizatorului
+  label_sort_by: "SorteazÄƒ dupÄƒ %{value}"
+  label_send_test_email: Trimite email de test
+  label_feeds_access_key_created_on: "Cheie de acces creatÄƒ acum %{value}"
+  label_module_plural: Module
+  label_added_time_by: "AdÄƒugat de %{author} acum %{age}"
+  label_updated_time_by: "Actualizat de %{author} acum %{age}"
+  label_updated_time: "Actualizat acum %{value}"
+  label_jump_to_a_project: Alege proiectul...
+  label_file_plural: FiÈ™iere
+  label_changeset_plural: SchimbÄƒri
+  label_default_columns: Coloane implicite
+  label_no_change_option: (fÄƒrÄƒ schimbÄƒri)
+  label_bulk_edit_selected_issues: EditeazÄƒ toate tichetele selectate
+  label_theme: Tema
+  label_default: ImplicitÄƒ
+  label_search_titles_only: CautÄƒ numai Ã®n titluri
+  label_user_mail_option_all: "Pentru orice eveniment, Ã®n toate proiectele mele"
+  label_user_mail_option_selected: " Pentru orice eveniment, Ã®n proiectele selectate..."
+  label_user_mail_no_self_notified: "Nu trimite notificÄƒri pentru modificÄƒrile mele"
+  label_registration_activation_by_email: activare cont prin email
+  label_registration_manual_activation: activare manualÄƒ a contului
+  label_registration_automatic_activation: activare automatÄƒ a contului
+  label_display_per_page: "pe paginÄƒ: %{value}"
+  label_age: vechime
+  label_change_properties: SchimbÄƒ proprietÄƒÈ›ile
+  label_general: General
+  label_more: Mai mult
+  label_scm: SCM
+  label_plugins: Plugin-uri
+  label_ldap_authentication: autentificare LDAP
+  label_downloads_abbr: D/L
+  label_optional_description: Descriere (opÈ›ionalÄƒ)
+  label_add_another_file: AdaugÄƒ alt fiÈ™ier
+  label_preferences: PreferinÈ›e
+  label_chronological_order: Ã®n ordine cronologicÄƒ
+  label_reverse_chronological_order: ÃŽn ordine invers cronologicÄƒ
+  label_planning: Planificare
+  label_incoming_emails: Mesaje primite
+  label_generate_key: GenereazÄƒ o cheie
+  label_issue_watchers: Cine urmÄƒreÈ™te
+  label_example: Exemplu
+  label_display: AfiÈ™eazÄƒ
+
+  label_sort: SorteazÄƒ
+  label_ascending: CrescÄƒtor
+  label_descending: DescrescÄƒtor
+  label_date_from_to: De la %{start} la %{end}
+
+  button_login: Autentificare
+  button_submit: Trimite
+  button_save: SalveazÄƒ
+  button_check_all: BifeazÄƒ tot
+  button_uncheck_all: DebifeazÄƒ tot
+  button_delete: È˜terge
+  button_create: CreeazÄƒ
+  button_create_and_continue: CreeazÄƒ È™i continua
+  button_test: TesteazÄƒ
+  button_edit: EditeazÄƒ
+  button_add: AdaugÄƒ
+  button_change: ModificÄƒ
+  button_apply: AplicÄƒ
+  button_clear: È˜terge
+  button_lock: BlocheazÄƒ
+  button_unlock: DeblocheazÄƒ
+  button_download: DescarcÄƒ
+  button_list: ListeazÄƒ
+  button_view: AfiÈ™eazÄƒ
+  button_move: MutÄƒ
+  button_back: ÃŽnapoi
+  button_cancel: AnuleazÄƒ
+  button_activate: ActiveazÄƒ
+  button_sort: SorteazÄƒ
+  button_log_time: ÃŽnregistreazÄƒ timpul de lucru
+  button_rollback: Revenire la aceastÄƒ versiune
+  button_watch: UrmÄƒresc
+  button_unwatch: Nu urmÄƒresc
+  button_reply: RÄƒspunde
+  button_archive: ArhiveazÄƒ
+  button_unarchive: DezarhiveazÄƒ
+  button_reset: ReseteazÄƒ
+  button_rename: RedenumeÈ™te
+  button_change_password: Schimbare parolÄƒ
+  button_copy: CopiazÄƒ
+  button_annotate: AdnoteazÄƒ
+  button_update: ActualizeazÄƒ
+  button_configure: ConfigureazÄƒ
+  button_quote: CiteazÄƒ
+
+  status_active: activ
+  status_registered: Ã®nregistrat
+  status_locked: blocat
+
+  text_select_mail_notifications: SelectaÈ›i acÈ›iunile notificate prin email.
+  text_regexp_info: ex. ^[A-Z0-9]+$
+  text_min_max_length_info: 0 Ã®nseamnÄƒ fÄƒrÄƒ restricÈ›ii
+  text_project_destroy_confirmation: Sigur doriÈ›i sÄƒ È™tergeÈ›i proiectul È™i toate datele asociate?
+  text_subprojects_destroy_warning: "Se vor È™terge È™i sub-proiectele: %{value}."
+  text_workflow_edit: SelectaÈ›i un rol È™i un tip de tichet pentru a edita modul de lucru
+  text_are_you_sure: SunteÈ›i sigur(Äƒ)?
+  text_tip_issue_begin_day: sarcinÄƒ care Ã®ncepe Ã®n aceastÄƒ zi
+  text_tip_issue_end_day: sarcinÄƒ care se terminÄƒ Ã®n aceastÄƒ zi
+  text_tip_issue_begin_end_day: sarcinÄƒ care Ã®ncepe È™i se terminÄƒ Ã®n aceastÄƒ zi
+  text_caracters_maximum: "maxim %{count} caractere."
+  text_caracters_minimum: "Trebuie sÄƒ fie minim %{count} caractere."
+  text_length_between: "Lungime Ã®ntre %{min} È™i %{max} caractere."
+  text_tracker_no_workflow: Nu sunt moduri de lucru pentru acest tip de tichet
+  text_unallowed_characters: Caractere nepermise
+  text_comma_separated: Sunt permise mai multe valori (separate cu virgulÄƒ).
+  text_issues_ref_in_commit_messages: Referire la tichete È™i rezolvare Ã®n textul mesajului
+  text_issue_added: "Tichetul %{id} a fost adÄƒugat de %{author}."
+  text_issue_updated: "Tichetul %{id} a fost actualizat de %{author}."
+  text_wiki_destroy_confirmation: Sigur doriÈ›i È™tergerea Wiki È™i a conÈ›inutului asociat?
+  text_issue_category_destroy_question: "AceastÄƒ categorie conÈ›ine (%{count}) tichete. Ce doriÈ›i sÄƒ faceÈ›i?"
+  text_issue_category_destroy_assignments: È˜terge apartenenÈ›a la categorie.
+  text_issue_category_reassign_to: Atribuie tichetele la aceastÄƒ categorie
+  text_user_mail_option: "Pentru proiectele care nu sunt selectate, veÈ›i primi notificÄƒri doar pentru ceea ce urmÄƒriÈ›i sau Ã®n ce sunteÈ›i implicat (ex: tichete create de dumneavoastrÄƒ sau care vÄƒ sunt atribuite)."
+  text_no_configuration_data: "Nu s-au configurat Ã®ncÄƒ rolurile, stÄƒrile tichetelor È™i modurile de lucru.\nEste recomandat sÄƒ Ã®ncÄƒrcaÈ›i configuraÈ›ia implicitÄƒ. O veÈ›i putea modifica ulterior."
+  text_load_default_configuration: ÃŽncarcÄƒ configuraÈ›ia implicitÄƒ
+  text_status_changed_by_changeset: "Aplicat Ã®n setul %{value}."
+  text_issues_destroy_confirmation: 'Sigur doriÈ›i sÄƒ È™tergeÈ›i tichetele selectate?'
+  text_select_project_modules: 'SelectaÈ›i modulele active pentru acest proiect:'
+  text_default_administrator_account_changed: S-a schimbat contul administratorului implicit
+  text_file_repository_writable: Se poate scrie Ã®n directorul de ataÈ™amente
+  text_plugin_assets_writable: Se poate scrie Ã®n directorul de plugin-uri
+  text_rmagick_available: Este disponibil RMagick (opÈ›ional)
+  text_destroy_time_entries_question: "%{hours} ore sunt Ã®nregistrate la tichetele pe care doriÈ›i sÄƒ le È™tergeÈ›i. Ce doriÈ›i sa faceÈ›i?"
+  text_destroy_time_entries: È˜terge orele Ã®nregistrate
+  text_assign_time_entries_to_project: Atribuie orele la proiect
+  text_reassign_time_entries: 'Atribuie orele Ã®nregistrate la tichetul:'
+  text_user_wrote: "%{value} a scris:"
+  text_enumeration_destroy_question: "AceastÄƒ valoare are %{count} obiecte."
+  text_enumeration_category_reassign_to: 'Atribuie la aceastÄƒ valoare:'
+  text_email_delivery_not_configured: "Trimiterea de emailuri nu este configuratÄƒ È™i ca urmare, notificÄƒrile sunt dezactivate.\nConfiguraÈ›i serverul SMTP Ã®n config/configuration.yml È™i reporniÈ›i aplicaÈ›ia pentru a le activa."
+  text_repository_usernames_mapping: "SelectaÈ›i sau modificaÈ›i contul Redmine echivalent contului din istoricul depozitului.\nUtilizatorii cu un cont (sau e-mail) identic Ã®n Redmine È™i depozit sunt echivalate automat."
+  text_diff_truncated: '... ComparaÈ›ia a fost trunchiatÄƒ pentru ca depÄƒÈ™eÈ™te lungimea maximÄƒ de text care poate fi afiÈ™at.'
+  text_custom_field_possible_values_info: 'O linie pentru fiecare valoare'
+
+  default_role_manager: Manager
+  default_role_developer: Dezvoltator
+  default_role_reporter: Creator de rapoarte
+  default_tracker_bug: Defect
+  default_tracker_feature: FuncÈ›ie
+  default_tracker_support: Suport
+  default_issue_status_new: Nou
+  default_issue_status_in_progress: In Progress
+  default_issue_status_resolved: Rezolvat
+  default_issue_status_feedback: AÈ™teaptÄƒ reacÈ›ii
+  default_issue_status_closed: ÃŽnchis
+  default_issue_status_rejected: Respins
+  default_doc_category_user: DocumentaÈ›ie
+  default_doc_category_tech: DocumentaÈ›ie tehnicÄƒ
+  default_priority_low: micÄƒ
+  default_priority_normal: normalÄƒ
+  default_priority_high: mare
+  default_priority_urgent: urgentÄƒ
+  default_priority_immediate: imediatÄƒ
+  default_activity_design: Design
+  default_activity_development: Dezvoltare
+
+  enumeration_issue_priorities: PrioritÄƒÈ›i tichete
+  enumeration_doc_categories: Categorii documente
+  enumeration_activities: ActivitÄƒÈ›i (timp de lucru)
+  label_greater_or_equal: ">="
+  label_less_or_equal: <=
+  text_wiki_page_destroy_question: AceastÄƒ paginÄƒ are %{descendants} pagini anterioare È™i descendenÈ›i. Ce doriÈ›i sÄƒ faceÈ›i?
+  text_wiki_page_reassign_children: Atribuie paginile la aceastÄƒ paginÄƒ
+  text_wiki_page_nullify_children: MenÈ›ine paginile ca È™i pagini iniÈ›iale (root)
+  text_wiki_page_destroy_children: È˜terge paginile È™i descendenÈ›ii
+  setting_password_min_length: Lungime minimÄƒ parolÄƒ
+  field_group_by: GrupeazÄƒ dupÄƒ
+  mail_subject_wiki_content_updated: "Pagina wiki '%{id}' a fost actualizatÄƒ"
+  label_wiki_content_added: AdÄƒugat
+  mail_subject_wiki_content_added: "Pagina wiki '%{id}' a fost adÄƒugatÄƒ"
+  mail_body_wiki_content_added: Pagina wiki '%{id}' a fost adÄƒugatÄƒ de %{author}.
+  label_wiki_content_updated: Actualizat
+  mail_body_wiki_content_updated: Pagina wiki '%{id}' a fost actualizatÄƒ de %{author}.
+  permission_add_project: CreazÄƒ proiect
+  setting_new_project_user_role_id: Rol atribuit utilizatorului non-admin care creazÄƒ un proiect.
+  label_view_all_revisions: AratÄƒ toate reviziile
+  label_tag: Tag
+  label_branch: Branch
+  error_no_tracker_in_project: Nu existÄƒ un tracker asociat cu proiectul. VerificaÈ›i vÄƒ rog setÄƒrile proiectului.
+  error_no_default_issue_status: Nu existÄƒ un status implicit al tichetelor. VerificaÈ›i vÄƒ rog configuraÈ›ia (MergeÈ›i la "Administrare -> StÄƒri tichete").
+  text_journal_changed: "%{label} schimbat din %{old} Ã®n %{new}"
+  text_journal_set_to: "%{label} setat ca %{value}"
+  text_journal_deleted: "%{label} È™ters (%{old})"
+  label_group_plural: Grupuri
+  label_group: Grup
+  label_group_new: Grup nou
+  label_time_entry_plural: Timp alocat
+  text_journal_added: "%{label} %{value} added"
+  field_active: Active
+  enumeration_system_activity: System Activity
+  permission_delete_issue_watchers: Delete watchers
+  version_status_closed: closed
+  version_status_locked: locked
+  version_status_open: open
+  error_can_not_reopen_issue_on_closed_version: An issue assigned to a closed version can not be reopened
+  label_user_anonymous: Anonymous
+  button_move_and_follow: Move and follow
+  setting_default_projects_modules: Default enabled modules for new projects
+  setting_gravatar_default: Default Gravatar image
+  field_sharing: Sharing
+  label_version_sharing_hierarchy: With project hierarchy
+  label_version_sharing_system: With all projects
+  label_version_sharing_descendants: With subprojects
+  label_version_sharing_tree: With project tree
+  label_version_sharing_none: Not shared
+  error_can_not_archive_project: This project can not be archived
+  button_duplicate: Duplicate
+  button_copy_and_follow: Copy and follow
+  label_copy_source: Source
+  setting_issue_done_ratio: Calculate the issue done ratio with
+  setting_issue_done_ratio_issue_status: Use the issue status
+  error_issue_done_ratios_not_updated: Issue done ratios not updated.
+  error_workflow_copy_target: Please select target tracker(s) and role(s)
+  setting_issue_done_ratio_issue_field: Use the issue field
+  label_copy_same_as_target: Same as target
+  label_copy_target: Target
+  notice_issue_done_ratios_updated: Issue done ratios updated.
+  error_workflow_copy_source: Please select a source tracker or role
+  label_update_issue_done_ratios: Update issue done ratios
+  setting_start_of_week: Start calendars on
+  permission_view_issues: View Issues
+  label_display_used_statuses_only: Only display statuses that are used by this tracker
+  label_revision_id: Revision %{value}
+  label_api_access_key: API access key
+  label_api_access_key_created_on: API access key created %{value} ago
+  label_feeds_access_key: RSS access key
+  notice_api_access_key_reseted: Your API access key was reset.
+  setting_rest_api_enabled: Enable REST web service
+  label_missing_api_access_key: Missing an API access key
+  label_missing_feeds_access_key: Missing a RSS access key
+  button_show: Show
+  text_line_separated: Multiple values allowed (one line for each value).
+  setting_mail_handler_body_delimiters: Truncate emails after one of these lines
+  permission_add_subprojects: Create subprojects
+  label_subproject_new: New subproject
+  text_own_membership_delete_confirmation: |-
+    You are about to remove some or all of your permissions and may no longer be able to edit this project after that.
+    Are you sure you want to continue?
+  label_close_versions: Close completed versions
+  label_board_sticky: Sticky
+  label_board_locked: Locked
+  permission_export_wiki_pages: Export wiki pages
+  setting_cache_formatted_text: Cache formatted text
+  permission_manage_project_activities: Manage project activities
+  error_unable_delete_issue_status: Unable to delete issue status
+  label_profile: Profile
+  permission_manage_subtasks: Manage subtasks
+  field_parent_issue: Parent task
+  label_subtask_plural: Subtasks
+  label_project_copy_notifications: Send email notifications during the project copy
+  error_can_not_delete_custom_field: Unable to delete custom field
+  error_unable_to_connect: Unable to connect (%{value})
+  error_can_not_remove_role: This role is in use and can not be deleted.
+  error_can_not_delete_tracker: This tracker contains issues and can't be deleted.
+  field_principal: Principal
+  label_my_page_block: My page block
+  notice_failed_to_save_members: "Failed to save member(s): %{errors}."
+  text_zoom_out: Zoom out
+  text_zoom_in: Zoom in
+  notice_unable_delete_time_entry: Unable to delete time log entry.
+  label_overall_spent_time: Overall spent time
+  field_time_entries: Log time
+  project_module_gantt: Gantt
+  project_module_calendar: Calendar
+  button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
+  field_text: Text field
+  label_user_mail_option_only_owner: Only for things I am the owner of
+  setting_default_notification_option: Default notification option
+  label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
+  label_user_mail_option_only_assigned: Only for things I am assigned to
+  label_user_mail_option_none: No events
+  field_member_of_group: Assignee's group
+  field_assigned_to_role: Assignee's role
+  notice_not_authorized_archived_project: The project you're trying to access has been archived.
+  label_principal_search: "Search for user or group:"
+  label_user_search: "Search for user:"
+  field_visible: Visible
+  setting_commit_logtime_activity_id: Activity for logged time
+  text_time_logged_by_changeset: Applied in changeset %{value}.
+  setting_commit_logtime_enabled: Enable time logging
+  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+  field_warn_on_leaving_unsaved: Warn me when leaving a page with unsaved text
+  text_warn_on_leaving_unsaved: The current page contains unsaved text that will be lost if you leave this page.
+  label_my_queries: My custom queries
+  text_journal_changed_no_detail: "%{label} updated"
+  label_news_comment_added: Comment added to a news
+  button_expand_all: Expand all
+  button_collapse_all: Collapse all
+  label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
+  label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
+  label_bulk_edit_selected_time_entries: Bulk edit selected time entries
+  text_time_entries_destroy_confirmation: Are you sure you want to delete the selected time entr(y/ies)?
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: Note added
+  label_issue_status_updated: Status updated
+  label_issue_priority_updated: Priority updated
+  label_issues_visibility_own: Issues created by or assigned to the user
+  field_issues_visibility: Issues visibility
+  label_issues_visibility_all: All issues
+  permission_set_own_issues_private: Set own issues public or private
+  field_is_private: Private
+  permission_set_issues_private: Set issues public or private
+  label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
+  field_commit_logs_encoding: Codare pentru mesaje
+  field_scm_path_encoding: Path encoding
+  text_scm_path_encoding_note: "Default: UTF-8"
+  field_path_to_repository: Path to repository
+  field_root_directory: Root directory
+  field_cvs_module: Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: Command
+  text_scm_command_version: Version
+  label_git_report_last_commit: Report last commit for files and directories
+  notice_issue_successful_create: Issue %{id} created.
+  label_between: between
+  setting_issue_group_assignment: Allow issue assignment to groups
+  label_diff: diff
+  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  description_query_sort_criteria_direction: Sort direction
+  description_project_scope: Search scope
+  description_filter: Filter
+  description_user_mail_notification: Mail notification settings
+  description_date_from: Enter start date
+  description_message_content: Message content
+  description_available_columns: Available Columns
+  description_date_range_interval: Choose range by selecting start and end date
+  description_issue_category_reassign: Choose issue category
+  description_search: Searchfield
+  description_notes: Notes
+  description_date_range_list: Choose range from list
+  description_choose_project: Projects
+  description_date_to: Enter end date
+  description_query_sort_criteria_attribute: Sort attribute
+  description_wiki_subpages_reassign: Choose new parent page
+  description_selected_columns: Selected Columns
+  label_parent_revision: Parent
+  label_child_revision: Child
+  error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
+  setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
+  button_edit_section: Edit this section
+  setting_repositories_encodings: Attachments and repositories encodings
+  description_all_columns: All Columns
+  button_export: Export
+  label_export_options: "%{export_format} export options"
+  error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
+  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  label_x_issues:
+    zero:  0 tichet
+    one:   1 tichet
+    other: "%{count} tichete"
+  label_repository_new: New repository
+  field_repository_is_default: Main repository
+  label_copy_attachments: Copy attachments
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: Completed versions
+  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_multiple: Multiple values
+  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
+  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
+  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
+  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
+  field_auth_source_ldap_filter: LDAP filter
+  label_search_for_watchers: Search for watchers to add
+  notice_account_deleted: Your account has been permanently deleted.
+  setting_unsubscribe: Allow users to delete their own account
+  button_delete_my_account: Delete my account
+  text_account_destroy_confirmation: |-
+    Are you sure you want to proceed?
+    Your account will be permanently deleted, with no way to reactivate it.
+  error_session_expired: Your session has expired. Please login again.
+  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
+  setting_session_lifetime: Session maximum lifetime
+  setting_session_timeout: Session inactivity timeout
+  label_session_expiration: Session expiration
+  permission_close_project: Close / reopen the project
+  label_show_closed_projects: View closed projects
+  button_close: Close
+  button_reopen: Reopen
+  project_status_active: active
+  project_status_closed: closed
+  project_status_archived: archived
+  text_project_closed: This project is closed and read-only.
+  notice_user_successful_create: User %{id} created.
+  field_core_fields: Standard fields
+  field_timeout: Timeout (in seconds)
+  setting_thumbnails_enabled: Display attachment thumbnails
+  setting_thumbnails_size: Thumbnails size (in pixels)
+  label_status_transitions: Status transitions
+  label_fields_permissions: Fields permissions
+  label_readonly: Read-only
+  label_required: Required
+  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  field_board_parent: Parent forum
+  label_attribute_of_project: Project's %{name}
+  label_attribute_of_author: Author's %{name}
+  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_fixed_version: Target version's %{name}
+  label_copy_subtasks: Copy subtasks
+  label_copied_to: copied to
+  label_copied_from: copied from
+  label_any_issues_in_project: any issues in project
+  label_any_issues_not_in_project: any issues not in project
+  field_private_notes: Private notes
+  permission_view_private_notes: View private notes
+  permission_set_notes_private: Set notes as private
+  label_no_issues_in_project: no issues in project
+  label_any: toate
+  label_last_n_weeks: last %{count} weeks
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_cross_project_descendants: With subprojects
+  label_cross_project_tree: With project tree
+  label_cross_project_hierarchy: With project hierarchy
+  label_cross_project_system: With all projects
+  button_hide: Hide
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f2/f2015be9c3b679bedb2c24e4bc1e2d51751badea.svn-base
--- /dev/null
+++ b/.svn/pristine/f2/f2015be9c3b679bedb2c24e4bc1e2d51751badea.svn-base
@@ -0,0 +1,134 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redcloth3'
+require 'digest/md5'
+
+module Redmine
+  module WikiFormatting
+    module Textile
+      class Formatter < RedCloth3
+        include ActionView::Helpers::TagHelper
+        include Redmine::WikiFormatting::LinksHelper
+
+        alias :inline_auto_link :auto_link!
+        alias :inline_auto_mailto :auto_mailto!
+
+        # auto_link rule after textile rules so that it doesn't break !image_url! tags
+        RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto]
+
+        def initialize(*args)
+          super
+          self.hard_breaks=true
+          self.no_span_caps=true
+          self.filter_styles=false
+        end
+
+        def to_html(*rules)
+          @toc = []
+          super(*RULES).to_s
+        end
+
+        def get_section(index)
+          section = extract_sections(index)[1]
+          hash = Digest::MD5.hexdigest(section)
+          return section, hash
+        end
+
+        def update_section(index, update, hash=nil)
+          t = extract_sections(index)
+          if hash.present? && hash != Digest::MD5.hexdigest(t[1])
+            raise Redmine::WikiFormatting::StaleSectionError
+          end
+          t[1] = update unless t[1].blank?
+          t.reject(&:blank?).join "\n\n"
+        end
+
+        def extract_sections(index)
+          @pre_list = []
+          text = self.dup
+          rip_offtags text, false, false
+          before = ''
+          s = ''
+          after = ''
+          i = 0
+          l = 1
+          started = false
+          ended = false
+          text.scan(/(((?:.*?)(\A|\r?\n\s*\r?\n))(h(\d+)(#{A}#{C})\.(?::(\S+))?[ \t](.*?)$)|.*)/m).each do |all, content, lf, heading, level|
+            if heading.nil?
+              if ended
+                after << all
+              elsif started
+                s << all
+              else
+                before << all
+              end
+              break
+            end
+            i += 1
+            if ended
+              after << all
+            elsif i == index
+              l = level.to_i
+              before << content
+              s << heading
+              started = true
+            elsif i > index
+              s << content
+              if level.to_i > l
+                s << heading
+              else
+                after << heading
+                ended = true
+              end
+            else
+              before << all
+            end
+          end
+          sections = [before.strip, s.strip, after.strip]
+          sections.each {|section| smooth_offtags_without_code_highlighting section}
+          sections
+        end
+
+      private
+
+        # Patch for RedCloth.  Fixed in RedCloth r128 but _why hasn't released it yet.
+        # <a href="http://code.whytheluckystiff.net/redcloth/changeset/128">http://code.whytheluckystiff.net/redcloth/changeset/128</a>
+        def hard_break( text )
+          text.gsub!( /(.)\n(?!\n|\Z| *([#*=]+(\s|$)|[{|]))/, "\\1<br />" ) if hard_breaks
+        end
+
+        alias :smooth_offtags_without_code_highlighting :smooth_offtags
+        # Patch to add code highlighting support to RedCloth
+        def smooth_offtags( text )
+          unless @pre_list.empty?
+            ## replace <pre> content
+            text.gsub!(/<redpre#(\d+)>/) do
+              content = @pre_list[$1.to_i]
+              if content.match(/<code\s+class="(\w+)">\s?(.+)/m)
+                content = "<code class=\"#{$1} syntaxhl\">" +
+                  Redmine::SyntaxHighlighting.highlight_by_language($2, $1)
+              end
+              content
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f2/f21e899ada67cb1a2a7766f40a5bf4e791cace76.svn-base
--- /dev/null
+++ b/.svn/pristine/f2/f21e899ada67cb1a2a7766f40a5bf4e791cace76.svn-base
@@ -0,0 +1,108 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  class CustomFieldFormat
+    include Redmine::I18n
+
+    cattr_accessor :available
+    @@available = {}
+
+    attr_accessor :name, :order, :label, :edit_as, :class_names
+
+    def initialize(name, options={})
+      self.name = name
+      self.label = options[:label] || "label_#{name}".to_sym
+      self.order = options[:order] || self.class.available_formats.size
+      self.edit_as = options[:edit_as] || name
+      self.class_names = options[:only]
+    end
+
+    def format(value)
+      send "format_as_#{name}", value
+    end
+
+    def format_as_date(value)
+      begin; format_date(value.to_date); rescue; value end
+    end
+
+    def format_as_bool(value)
+      l(value == "1" ? :general_text_Yes : :general_text_No)
+    end
+
+    ['string','text','int','float','list'].each do |name|
+      define_method("format_as_#{name}") {|value|
+        return value
+      }
+    end
+
+    ['user', 'version'].each do |name|
+      define_method("format_as_#{name}") {|value|
+        return value.blank? ? "" : name.classify.constantize.find_by_id(value.to_i).to_s
+      }
+    end
+
+    class << self
+      def map(&block)
+        yield self
+      end
+
+      # Registers a custom field format
+      def register(*args)
+        custom_field_format = args.first
+        unless custom_field_format.is_a?(Redmine::CustomFieldFormat)
+          custom_field_format = Redmine::CustomFieldFormat.new(*args)
+        end
+        @@available[custom_field_format.name] = custom_field_format unless @@available.keys.include?(custom_field_format.name)
+      end
+
+      def available_formats
+        @@available.keys
+      end
+
+      def find_by_name(name)
+        @@available[name.to_s]
+      end
+
+      def label_for(name)
+        format = @@available[name.to_s]
+        format.label if format
+      end
+
+      # Return an array of custom field formats which can be used in select_tag
+      def as_select(class_name=nil)
+        fields = @@available.values
+        fields = fields.select {|field| field.class_names.nil? || field.class_names.include?(class_name)}
+        fields.sort {|a,b|
+          a.order <=> b.order
+        }.collect {|custom_field_format|
+          [ l(custom_field_format.label), custom_field_format.name ]
+        }
+      end
+
+      def format_value(value, field_format)
+        return "" unless value && !value.empty?
+
+        if format_type = find_by_name(field_format)
+          format_type.format(value)
+        else
+          value
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f2/f27bb39050f591f3c57d417ae9850d8d1e41d5e6.svn-base
--- /dev/null
+++ b/.svn/pristine/f2/f27bb39050f591f3c57d417ae9850d8d1e41d5e6.svn-base
@@ -0,0 +1,60 @@
+<h2><%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)).html_safe %></h2>
+<p class="subtitle"><%= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %></p>
+
+<div id="activity">
+<% @events_by_day.keys.sort.reverse.each do |day| %>
+<h3><%= format_activity_day(day) %></h3>
+<dl>
+<% sort_activity_events(@events_by_day[day]).each do |e, in_group| -%>
+  <dt class="<%= e.event_type %> <%= "grouped" if in_group %> <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
+  <%= avatar(e.event_author, :size => "24") if e.respond_to?(:event_author) %>
+  <span class="time"><%= format_time(e.event_datetime, false) %></span>
+  <%= content_tag('span', h(e.project), :class => 'project') if @project.nil? || @project != e.project %>
+  <%= link_to format_activity_title(e.event_title), e.event_url %>
+  </dt>
+  <dd class="<%= "grouped" if in_group %>"><span class="description"><%= format_activity_description(e.event_description) %></span>
+  <span class="author"><%= link_to_user(e.event_author) if e.respond_to?(:event_author) %></span></dd>
+<% end -%>
+</dl>
+<% end -%>
+</div>
+
+<%= content_tag('p', l(:label_no_data), :class => 'nodata') if @events_by_day.empty? %>
+
+<div style="float:left;">
+<%= link_to_content_update("\xc2\xab " + l(:label_previous),
+                   params.merge(:from => @date_to - @days - 1),
+                   :title => l(:label_date_from_to, :start => format_date(@date_to - 2*@days), :end => format_date(@date_to - @days - 1))) %>
+</div>
+<div style="float:right;">
+<%= link_to_content_update(l(:label_next) + " \xc2\xbb",
+                   params.merge(:from => @date_to + @days - 1),
+                   :title => l(:label_date_from_to, :start => format_date(@date_to), :end => format_date(@date_to + @days - 1))) unless @date_to >= Date.today %>
+</div>
+&nbsp;
+<% other_formats_links do |f| %>
+  <%= f.link_to 'Atom', :url => params.merge(:from => nil, :key => User.current.rss_key) %>
+<% end %>
+
+<% content_for :header_tags do %>
+<%= auto_discovery_link_tag(:atom, params.merge(:format => 'atom', :from => nil, :key => User.current.rss_key)) %>
+<% end %>
+
+<% content_for :sidebar do %>
+<%= form_tag({}, :method => :get) do %>
+<h3><%= l(:label_activity) %></h3>
+<p><% @activity.event_types.each do |t| %>
+<%= check_box_tag "show_#{t}", 1, @activity.scope.include?(t) %>
+<label for="show_<%=t%>"><%= link_to(l("label_#{t.singularize}_plural"), {"show_#{t}" => 1, :user_id => params[:user_id], :from => params[:from]})%></label>
+<br />
+<% end %></p>
+<% if @project && @project.descendants.active.any? %>
+    <%= hidden_field_tag 'with_subprojects', 0 %>
+    <p><label><%= check_box_tag 'with_subprojects', 1, @with_subprojects %> <%=l(:label_subproject_plural)%></label></p>
+<% end %>
+<%= hidden_field_tag('user_id', params[:user_id]) unless params[:user_id].blank? %>
+<p><%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %></p>
+<% end %>
+<% end %>
+
+<% html_title(l(:label_activity), @author) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f2/f27f2a3983c5eccb0f9f3926141c53148d9de116.svn-base
--- /dev/null
+++ b/.svn/pristine/f2/f27f2a3983c5eccb0f9f3926141c53148d9de116.svn-base
@@ -0,0 +1,29 @@
+<% if issues && issues.any? %>
+<%= form_tag({}) do %>
+  <table class="list issues">
+    <thead><tr>
+    <th>#</th>
+    <th><%=l(:field_project)%></th>
+    <th><%=l(:field_tracker)%></th>
+    <th><%=l(:field_subject)%></th>
+    </tr></thead>
+    <tbody>
+    <% for issue in issues %>
+    <tr id="issue-<%= h(issue.id) %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %>">
+      <td class="id">
+        <%= check_box_tag("ids[]", issue.id, false, :style => 'display:none;', :id => nil) %>
+        <%= link_to issue.id, issue_path(issue) %>
+      </td>
+      <td class="project"><%= link_to_project(issue.project) %></td>
+      <td class="tracker"><%=h issue.tracker %></td>
+      <td class="subject">
+        <%= link_to truncate(issue.subject, :length => 60), issue_path(issue) %> (<%=h issue.status %>)
+      </td>
+    </tr>
+    <% end %>
+    </tbody>
+  </table>
+<% end %>
+<% else %>
+  <p class="nodata"><%= l(:label_no_data) %></p>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f3/f30cc0647876cb77a493a4e5745be36df8d841df.svn-base
--- a/.svn/pristine/f3/f30cc0647876cb77a493a4e5745be36df8d841df.svn-base
+++ /dev/null
@@ -1,240 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class UsersController < ApplicationController
-  layout 'admin'
-
-  before_filter :require_admin, :except => :show
-  before_filter :find_user, :only => [:show, :edit, :update, :destroy, :edit_membership, :destroy_membership]
-  accept_api_auth :index, :show, :create, :update, :destroy
-
-  helper :sort
-  include SortHelper
-  helper :custom_fields
-  include CustomFieldsHelper
-
-  def index
-    sort_init 'login', 'asc'
-    sort_update %w(login firstname lastname mail admin created_on last_login_on)
-
-    case params[:format]
-    when 'xml', 'json'
-      @offset, @limit = api_offset_and_limit
-    else
-      @limit = per_page_option
-    end
-
-    scope = User
-    scope = scope.in_group(params[:group_id].to_i) if params[:group_id].present?
-
-    @status = params[:status] ? params[:status].to_i : 1
-    c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status])
-
-    unless params[:name].blank?
-      name = "%#{params[:name].strip.downcase}%"
-      c << ["LOWER(login) LIKE ? OR LOWER(firstname) LIKE ? OR LOWER(lastname) LIKE ? OR LOWER(mail) LIKE ?", name, name, name, name]
-    end
-
-    @user_count = scope.count(:conditions => c.conditions)
-    @user_pages = Paginator.new self, @user_count, @limit, params['page']
-    @offset ||= @user_pages.current.offset
-    @users =  scope.find :all,
-                        :order => sort_clause,
-                        :conditions => c.conditions,
-                        :limit  =>  @limit,
-                        :offset =>  @offset
-
-    respond_to do |format|
-      format.html {
-        @groups = Group.all.sort
-        render :layout => !request.xhr?
-      }
-      format.api
-    end	
-  end
-
-  def show
-    # show projects based on current user visibility
-    @memberships = @user.memberships.all(:conditions => Project.visible_condition(User.current))
-
-    events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 10)
-    @events_by_day = events.group_by(&:event_date)
-
-    unless User.current.admin?
-      if !@user.active? || (@user != User.current  && @memberships.empty? && events.empty?)
-        render_404
-        return
-      end
-    end
-
-    respond_to do |format|
-      format.html { render :layout => 'base' }
-      format.api
-    end
-  end
-
-  def new
-    @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option)
-    @auth_sources = AuthSource.find(:all)
-  end
-
-  verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
-  def create
-    @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option)
-    @user.safe_attributes = params[:user]
-    @user.admin = params[:user][:admin] || false
-    @user.login = params[:user][:login]
-    @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation] unless @user.auth_source_id
-
-    # TODO: Similar to My#account
-    @user.pref.attributes = params[:pref]
-    @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
-
-    if @user.save
-      @user.pref.save
-      @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
-
-      Mailer.deliver_account_information(@user, params[:user][:password]) if params[:send_information]
-
-      respond_to do |format|
-        format.html {
-          flash[:notice] = l(:notice_successful_create)
-          redirect_to(params[:continue] ?
-            {:controller => 'users', :action => 'new'} :
-            {:controller => 'users', :action => 'edit', :id => @user}
-          )
-        }
-        format.api  { render :action => 'show', :status => :created, :location => user_url(@user) }
-      end
-    else
-      @auth_sources = AuthSource.find(:all)
-      # Clear password input
-      @user.password = @user.password_confirmation = nil
-
-      respond_to do |format|
-        format.html { render :action => 'new' }
-        format.api  { render_validation_errors(@user) }
-      end
-    end
-  end
-
-  def edit
-    @auth_sources = AuthSource.find(:all)
-    @membership ||= Member.new
-  end
-
-  verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
-  def update
-    @user.admin = params[:user][:admin] if params[:user][:admin]
-    @user.login = params[:user][:login] if params[:user][:login]
-    if params[:user][:password].present? && (@user.auth_source_id.nil? || params[:user][:auth_source_id].blank?)
-      @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation]
-    end
-    @user.safe_attributes = params[:user]
-    # Was the account actived ? (do it before User#save clears the change)
-    was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE])
-    # TODO: Similar to My#account
-    @user.pref.attributes = params[:pref]
-    @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
-
-    if @user.save
-      @user.pref.save
-      @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
-
-      if was_activated
-        Mailer.deliver_account_activated(@user)
-      elsif @user.active? && params[:send_information] && !params[:user][:password].blank? && @user.auth_source_id.nil?
-        Mailer.deliver_account_information(@user, params[:user][:password])
-      end
-
-      respond_to do |format|
-        format.html {
-          flash[:notice] = l(:notice_successful_update)
-          redirect_to :back
-        }
-        format.api  { head :ok }
-      end
-    else
-      @auth_sources = AuthSource.find(:all)
-      @membership ||= Member.new
-      # Clear password input
-      @user.password = @user.password_confirmation = nil
-
-      respond_to do |format|
-        format.html { render :action => :edit }
-        format.api  { render_validation_errors(@user) }
-      end
-    end
-  rescue ::ActionController::RedirectBackError
-    redirect_to :controller => 'users', :action => 'edit', :id => @user
-  end
-
-  verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
-  def destroy
-    @user.destroy
-    respond_to do |format|
-      format.html { redirect_to(users_url) }
-      format.api  { head :ok }
-    end
-  end
-
-  def edit_membership
-    @membership = Member.edit_membership(params[:membership_id], params[:membership], @user)
-    @membership.save if request.post?
-    respond_to do |format|
-      if @membership.valid?
-        format.html { redirect_to :controller => 'users', :action => 'edit', :id => @user, :tab => 'memberships' }
-        format.js {
-          render(:update) {|page|
-            page.replace_html "tab-content-memberships", :partial => 'users/memberships'
-            page.visual_effect(:highlight, "member-#{@membership.id}")
-          }
-        }
-      else
-        format.js {
-          render(:update) {|page|
-            page.alert(l(:notice_failed_to_save_members, :errors => @membership.errors.full_messages.join(', ')))
-          }
-        }
-      end
-    end
-  end
-
-  def destroy_membership
-    @membership = Member.find(params[:membership_id])
-    if request.post? && @membership.deletable?
-      @membership.destroy
-    end
-    respond_to do |format|
-      format.html { redirect_to :controller => 'users', :action => 'edit', :id => @user, :tab => 'memberships' }
-      format.js { render(:update) {|page| page.replace_html "tab-content-memberships", :partial => 'users/memberships'} }
-    end
-  end
-
-  private
-
-  def find_user
-    if params[:id] == 'current'
-      require_login || return
-      @user = User.current
-    else
-      @user = User.find(params[:id])
-    end
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f3/f3202e275b36fcaa2493cbc5897c69215e65214b.svn-base
--- /dev/null
+++ b/.svn/pristine/f3/f3202e275b36fcaa2493cbc5897c69215e65214b.svn-base
@@ -0,0 +1,186 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class DocumentsControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :enabled_modules, :documents, :enumerations,
+           :groups_users, :attachments
+
+  def setup
+    User.current = nil
+  end
+
+  def test_index
+    # Sets a default category
+    e = Enumeration.find_by_name('Technical documentation')
+    e.update_attributes(:is_default => true)
+
+    get :index, :project_id => 'ecookbook'
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:grouped)
+
+    # Default category selected in the new document form
+    assert_tag :select, :attributes => {:name => 'document[category_id]'},
+                        :child => {:tag => 'option', :attributes => {:selected => 'selected'},
+                                                     :content => 'Technical documentation'}
+
+    assert ! DocumentCategory.find(16).active?
+    assert_no_tag :option, :attributes => {:value => '16'},
+                           :parent => {:tag => 'select', :attributes => {:id => 'document_category_id'} }
+  end
+
+  def test_index_grouped_by_date
+    get :index, :project_id => 'ecookbook', :sort_by => 'date'
+    assert_response :success
+    assert_tag 'h3', :content => '2007-02-12'
+  end
+
+  def test_index_grouped_by_title
+    get :index, :project_id => 'ecookbook', :sort_by => 'title'
+    assert_response :success
+    assert_tag 'h3', :content => 'T'
+  end
+
+  def test_index_grouped_by_author
+    get :index, :project_id => 'ecookbook', :sort_by => 'author'
+    assert_response :success
+    assert_tag 'h3', :content => 'John Smith'
+  end
+
+  def test_index_with_long_description
+    # adds a long description to the first document
+    doc = documents(:documents_001)
+    doc.update_attributes(:description => <<LOREM)
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut egestas, mi vehicula varius varius, ipsum massa fermentum orci, eget tristique ante sem vel mi. Nulla facilisi. Donec enim libero, luctus ac sagittis sit amet, vehicula sagittis magna. Duis ultrices molestie ante, eget scelerisque sem iaculis vitae. Etiam fermentum mauris vitae metus pharetra condimentum fermentum est pretium. Proin sollicitudin elementum quam quis pharetra.  Aenean facilisis nunc quis elit volutpat mollis. Aenean eleifend varius euismod. Ut dolor est, congue eget dapibus eget, elementum eu odio. Integer et lectus neque, nec scelerisque nisi. EndOfLineHere
+
+Vestibulum non velit mi. Aliquam scelerisque libero ut nulla fringilla a sollicitudin magna rhoncus.  Praesent a nunc lorem, ac porttitor eros. Sed ac diam nec neque interdum adipiscing quis quis justo. Donec arcu nunc, fringilla eu dictum at, venenatis ac sem. Vestibulum quis elit urna, ac mattis sapien. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+LOREM
+
+    get :index, :project_id => 'ecookbook'
+    assert_response :success
+    assert_template 'index'
+
+    # should only truncate on new lines to avoid breaking wiki formatting
+    assert_select '.wiki p', :text => (doc.description.split("\n").first + '...')
+    assert_select '.wiki p', :text => Regexp.new(Regexp.escape("EndOfLineHere..."))
+  end
+
+  def test_show
+    get :show, :id => 1
+    assert_response :success
+    assert_template 'show'
+  end
+
+  def test_new
+    @request.session[:user_id] = 2
+    get :new, :project_id => 1
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_create_with_one_attachment
+    ActionMailer::Base.deliveries.clear
+    @request.session[:user_id] = 2
+    set_tmp_attachments_directory
+
+    with_settings :notified_events => %w(document_added) do
+      post :create, :project_id => 'ecookbook',
+               :document => { :title => 'DocumentsControllerTest#test_post_new',
+                              :description => 'This is a new document',
+                              :category_id => 2},
+               :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
+    end
+    assert_redirected_to '/projects/ecookbook/documents'
+
+    document = Document.find_by_title('DocumentsControllerTest#test_post_new')
+    assert_not_nil document
+    assert_equal Enumeration.find(2), document.category
+    assert_equal 1, document.attachments.size
+    assert_equal 'testfile.txt', document.attachments.first.filename
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_create_with_failure
+    @request.session[:user_id] = 2
+    assert_no_difference 'Document.count' do
+      post :create, :project_id => 'ecookbook', :document => { :title => ''}
+    end
+    assert_response :success
+    assert_template 'new'
+  end
+
+  def test_create_non_default_category
+    @request.session[:user_id] = 2
+    category2 = Enumeration.find_by_name('User documentation')
+    category2.update_attributes(:is_default => true)
+    category1 = Enumeration.find_by_name('Uncategorized')
+    post :create,
+         :project_id => 'ecookbook',
+         :document => { :title => 'no default',
+                        :description => 'This is a new document',
+                        :category_id => category1.id }
+    assert_redirected_to '/projects/ecookbook/documents'
+    doc = Document.find_by_title('no default')
+    assert_not_nil doc
+    assert_equal category1.id, doc.category_id
+    assert_equal category1, doc.category
+  end
+
+  def test_edit
+    @request.session[:user_id] = 2
+    get :edit, :id => 1
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_update
+    @request.session[:user_id] = 2
+    put :update, :id => 1, :document => {:title => 'test_update'}
+    assert_redirected_to '/documents/1'
+    document = Document.find(1)
+    assert_equal 'test_update', document.title
+  end
+
+  def test_update_with_failure
+    @request.session[:user_id] = 2
+    put :update, :id => 1, :document => {:title => ''}
+    assert_response :success
+    assert_template 'edit'
+  end
+
+  def test_destroy
+    @request.session[:user_id] = 2
+    assert_difference 'Document.count', -1 do
+      delete :destroy, :id => 1
+    end
+    assert_redirected_to '/projects/ecookbook/documents'
+    assert_nil Document.find_by_id(1)
+  end
+
+  def test_add_attachment
+    @request.session[:user_id] = 2
+    assert_difference 'Attachment.count' do
+      post :add_attachment, :id => 1,
+        :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
+    end
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal Document.find(1), attachment.container
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f3/f33c6880e8251726611101bca6cb50a4896db55f.svn-base
--- a/.svn/pristine/f3/f33c6880e8251726611101bca6cb50a4896db55f.svn-base
+++ /dev/null
@@ -1,91 +0,0 @@
-### From http://svn.geekdaily.org/public/rails/plugins/generally_useful/tasks/coverage_via_rcov.rake
-
-namespace :test do
-  desc 'Measures test coverage'
-  task :coverage do
-    rm_f "coverage"
-    rm_f "coverage.data"
-    rcov = "rcov --rails --aggregate coverage.data --text-summary -Ilib --html --exclude gems/"
-    files = Dir.glob("test/**/*_test.rb").join(" ")
-    system("#{rcov} #{files}")
-    system("open coverage/index.html") if PLATFORM['darwin']
-  end
-
-  desc 'Run unit and functional scm tests'
-  task :scm do
-    errors = %w(test:scm:units test:scm:functionals).collect do |task|
-      begin
-        Rake::Task[task].invoke
-        nil
-      rescue => e
-        task
-      end
-    end.compact
-    abort "Errors running #{errors.to_sentence(:locale => :en)}!" if errors.any?
-  end
-
-  namespace :scm do
-    namespace :setup do
-      desc "Creates directory for test repositories"
-      task :create_dir do
-        FileUtils.mkdir_p Rails.root + '/tmp/test'
-      end
-
-      supported_scms = [:subversion, :cvs, :bazaar, :mercurial, :git, :darcs, :filesystem]
-
-      desc "Creates a test subversion repository"
-      task :subversion => :create_dir do
-        repo_path = "tmp/test/subversion_repository"
-        system "svnadmin create #{repo_path}"
-        system "gunzip < test/fixtures/repositories/subversion_repository.dump.gz | svnadmin load #{repo_path}"
-      end
-
-      desc "Creates a test mercurial repository"
-      task :mercurial => :create_dir do
-        repo_path = "tmp/test/mercurial_repository"
-        bundle_path = "test/fixtures/repositories/mercurial_repository.hg"
-        system "hg init #{repo_path}"
-        system "hg -R #{repo_path} pull #{bundle_path}"
-      end
-
-      (supported_scms - [:subversion, :mercurial]).each do |scm|
-        desc "Creates a test #{scm} repository"
-        task scm => :create_dir do
-          # system "gunzip < test/fixtures/repositories/#{scm}_repository.tar.gz | tar -xv -C tmp/test"
-          system "tar -xvz -C tmp/test -f test/fixtures/repositories/#{scm}_repository.tar.gz"
-        end
-      end
-
-      desc "Creates all test repositories"
-      task :all => supported_scms
-    end
-
-    desc "Updates installed test repositories"
-    task :update do
-      require 'fileutils'
-      Dir.glob("tmp/test/*_repository").each do |dir|
-        next unless File.basename(dir) =~ %r{^(.+)_repository$} && File.directory?(dir)
-        scm = $1
-        next unless fixture = Dir.glob("test/fixtures/repositories/#{scm}_repository.*").first
-        next if File.stat(dir).ctime > File.stat(fixture).mtime
-
-        FileUtils.rm_rf dir
-        Rake::Task["test:scm:setup:#{scm}"].execute
-      end
-    end
-
-    Rake::TestTask.new(:units => "db:test:prepare") do |t|
-      t.libs << "test"
-      t.verbose = true
-      t.test_files = FileList['test/unit/repository*_test.rb'] + FileList['test/unit/lib/redmine/scm/**/*_test.rb']
-    end
-    Rake::Task['test:scm:units'].comment = "Run the scm unit tests"
-
-    Rake::TestTask.new(:functionals => "db:test:prepare") do |t|
-      t.libs << "test"
-      t.verbose = true
-      t.test_files = FileList['test/functional/repositories*_test.rb']
-    end
-    Rake::Task['test:scm:functionals'].comment = "Run the scm functional tests"
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f3/f34e33a2a42b339063ea92067802d190a2825630.svn-base
--- a/.svn/pristine/f3/f34e33a2a42b339063ea92067802d190a2825630.svn-base
+++ /dev/null
@@ -1,43 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class UserPreferenceTest < ActiveSupport::TestCase
-  fixtures :users, :user_preferences
-
-  def test_create
-    user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
-    user.login = "newuser"
-    user.password, user.password_confirmation = "password", "password"
-    assert user.save
-
-    assert_kind_of UserPreference, user.pref
-    assert_kind_of Hash, user.pref.others
-    assert user.pref.save
-  end
-
-  def test_update
-    user = User.find(1)
-    assert_equal true, user.pref.hide_mail
-    user.pref['preftest'] = 'value'
-    assert user.pref.save
-
-    user.reload
-    assert_equal 'value', user.pref['preftest']
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f3/f3620e1d272f7f0206e16d61dc2fdc4a8da59a95.svn-base
--- a/.svn/pristine/f3/f3620e1d272f7f0206e16d61dc2fdc4a8da59a95.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%=l(:label_auth_source_new)%> (<%= h(@auth_source.auth_method_name) %>)</h2>
-
-<% form_tag({:action => 'create'}, :class => "tabular") do %>
-  <%= render :partial => 'form' %>
-  <%= submit_tag l(:button_create) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f3/f36627f1ceebd181333d428d96386397035bb171.svn-base
--- a/.svn/pristine/f3/f36627f1ceebd181333d428d96386397035bb171.svn-base
+++ /dev/null
@@ -1,68 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module SearchHelper
-  def highlight_tokens(text, tokens)
-    return text unless text && tokens && !tokens.empty?
-    re_tokens = tokens.collect {|t| Regexp.escape(t)}
-    regexp = Regexp.new "(#{re_tokens.join('|')})", Regexp::IGNORECASE
-    result = ''
-    text.split(regexp).each_with_index do |words, i|
-      if result.length > 1200
-        # maximum length of the preview reached
-        result << '...'
-        break
-      end
-      words = words.mb_chars
-      if i.even?
-        result << h(words.length > 100 ? "#{words.slice(0..44)} ... #{words.slice(-45..-1)}" : words)
-      else
-        t = (tokens.index(words.downcase) || 0) % 4
-        result << content_tag('span', h(words), :class => "highlight token-#{t}")
-      end
-    end
-    result
-  end
-
-  def type_label(t)
-    l("label_#{t.singularize}_plural", :default => t.to_s.humanize)
-  end
-
-  def project_select_tag
-    options = [[l(:label_project_all), 'all']]
-    options << [l(:label_my_projects), 'my_projects'] unless User.current.memberships.empty?
-    options << [l(:label_and_its_subprojects, @project.name), 'subprojects'] unless @project.nil? || @project.descendants.active.empty?
-    options << [@project.name, ''] unless @project.nil?
-    label_tag("scope", l(:description_project_scope), :class => "hidden-for-sighted") +
-    select_tag('scope', options_for_select(options, params[:scope].to_s)) if options.size > 1
-  end
-
-  def render_results_by_type(results_by_type)
-    links = []
-    # Sorts types by results count
-    results_by_type.keys.sort {|a, b| results_by_type[b] <=> results_by_type[a]}.each do |t|
-      c = results_by_type[t]
-      next if c == 0
-      text = "#{type_label(t)} (#{c})"
-      links << link_to(h(text), :q => params[:q], :titles_only => params[:titles_only],
-                       :all_words => params[:all_words], :scope => params[:scope], t => 1)
-    end
-    ('<ul>' + links.map {|link| content_tag('li', link)}.join(' ') + '</ul>') unless links.empty?
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f3/f388a468f7bcce147f8cf82b4b0549106c8cc56a.svn-base
--- a/.svn/pristine/f3/f388a468f7bcce147f8cf82b4b0549106c8cc56a.svn-base
+++ /dev/null
@@ -1,100 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-require 'documents_controller'
-
-# Re-raise errors caught by the controller.
-class DocumentsController; def rescue_action(e) raise e end; end
-
-class DocumentsControllerTest < ActionController::TestCase
-  fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :documents, :enumerations
-
-  def setup
-    @controller = DocumentsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    User.current = nil
-  end
-
-  def test_index
-    # Sets a default category
-    e = Enumeration.find_by_name('Technical documentation')
-    e.update_attributes(:is_default => true)
-
-    get :index, :project_id => 'ecookbook'
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:grouped)
-
-    # Default category selected in the new document form
-    assert_tag :select, :attributes => {:name => 'document[category_id]'},
-                        :child => {:tag => 'option', :attributes => {:selected => 'selected'},
-                                                     :content => 'Technical documentation'}
-
-    assert ! DocumentCategory.find(16).active?
-    assert_no_tag :option, :attributes => {:value => '16'},
-                           :parent => {:tag => 'select', :attributes => {:id => 'document_category_id'} }
-  end
-
-  def test_index_with_long_description
-    # adds a long description to the first document
-    doc = documents(:documents_001)
-    doc.update_attributes(:description => <<LOREM)
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut egestas, mi vehicula varius varius, ipsum massa fermentum orci, eget tristique ante sem vel mi. Nulla facilisi. Donec enim libero, luctus ac sagittis sit amet, vehicula sagittis magna. Duis ultrices molestie ante, eget scelerisque sem iaculis vitae. Etiam fermentum mauris vitae metus pharetra condimentum fermentum est pretium. Proin sollicitudin elementum quam quis pharetra.  Aenean facilisis nunc quis elit volutpat mollis. Aenean eleifend varius euismod. Ut dolor est, congue eget dapibus eget, elementum eu odio. Integer et lectus neque, nec scelerisque nisi. EndOfLineHere
-
-Vestibulum non velit mi. Aliquam scelerisque libero ut nulla fringilla a sollicitudin magna rhoncus.  Praesent a nunc lorem, ac porttitor eros. Sed ac diam nec neque interdum adipiscing quis quis justo. Donec arcu nunc, fringilla eu dictum at, venenatis ac sem. Vestibulum quis elit urna, ac mattis sapien. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
-LOREM
-
-    get :index, :project_id => 'ecookbook'
-    assert_response :success
-    assert_template 'index'
-
-    # should only truncate on new lines to avoid breaking wiki formatting
-    assert_select '.wiki p', :text => (doc.description.split("\n").first + '...')
-    assert_select '.wiki p', :text => Regexp.new(Regexp.escape("EndOfLineHere..."))
-  end
-
-  def test_new_with_one_attachment
-    ActionMailer::Base.deliveries.clear
-    Setting.notified_events << 'document_added'
-    @request.session[:user_id] = 2
-    set_tmp_attachments_directory
-
-    post :new, :project_id => 'ecookbook',
-               :document => { :title => 'DocumentsControllerTest#test_post_new',
-                              :description => 'This is a new document',
-                              :category_id => 2},
-               :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
-
-    assert_redirected_to '/projects/ecookbook/documents'
-
-    document = Document.find_by_title('DocumentsControllerTest#test_post_new')
-    assert_not_nil document
-    assert_equal Enumeration.find(2), document.category
-    assert_equal 1, document.attachments.size
-    assert_equal 'testfile.txt', document.attachments.first.filename
-    assert_equal 1, ActionMailer::Base.deliveries.size
-  end
-
-  def test_destroy
-    @request.session[:user_id] = 2
-    post :destroy, :id => 1
-    assert_redirected_to '/projects/ecookbook/documents'
-    assert_nil Document.find_by_id(1)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f3/f3c118af336d1f061b825e2d660d96a9847739fa.svn-base
--- a/.svn/pristine/f3/f3c118af336d1f061b825e2d660d96a9847739fa.svn-base
+++ /dev/null
@@ -1,52 +0,0 @@
-require File.expand_path('../../../../../../test_helper', __FILE__)
-begin
-  require 'mocha'
-
-  class DarcsAdapterTest < ActiveSupport::TestCase
-    REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
-
-    if File.directory?(REPOSITORY_PATH)
-      def setup
-        @adapter = Redmine::Scm::Adapters::DarcsAdapter.new(REPOSITORY_PATH)
-      end
-
-      def test_darcsversion
-        to_test = { "1.0.9 (release)\n"  => [1,0,9] ,
-                    "2.2.0 (release)\n"  => [2,2,0] }
-        to_test.each do |s, v|
-          test_darcsversion_for(s, v)
-        end
-      end
-
-      def test_revisions
-        id1 = '20080308225258-98289-761f654d669045eabee90b91b53a21ce5593cadf.gz'
-        revs = @adapter.revisions('', nil, nil, {:with_path => true})
-        assert_equal 6, revs.size
-        assert_equal id1, revs[5].scmid
-        paths = revs[5].paths
-        assert_equal 5, paths.size
-        assert_equal 'A', paths[0][:action]
-        assert_equal '/README', paths[0][:path]
-        assert_equal 'A', paths[1][:action]
-        assert_equal '/images', paths[1][:path]
-      end
-
-      private
-
-      def test_darcsversion_for(darcsversion, version)
-        @adapter.class.expects(:darcs_binary_version_from_command_line).returns(darcsversion)
-        assert_equal version, @adapter.class.darcs_binary_version
-      end
-
-    else
-      puts "Darcs test repository NOT FOUND. Skipping unit tests !!!"
-      def test_fake; assert true end
-    end
-  end
-
-rescue LoadError
-  class DarcsMochaFake < ActiveSupport::TestCase
-    def test_fake; assert(false, "Requires mocha to run those tests")  end
-  end
-end
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f4/f407af2cff71c3deb4c9cfcec5a547c555ebddb3.svn-base
--- /dev/null
+++ b/.svn/pristine/f4/f407af2cff71c3deb4c9cfcec5a547c555ebddb3.svn-base
@@ -0,0 +1,23 @@
+<% if @statuses.empty? or rows.empty? %>
+    <p><i><%=l(:label_no_data)%></i></p>
+<% else %>
+<table class="list">
+<thead><tr>
+<th style="width:25%"></th>
+<th align="center" style="width:25%"><%=l(:label_open_issues_plural)%></th>
+<th align="center" style="width:25%"><%=l(:label_closed_issues_plural)%></th>
+<th align="center" style="width:25%"><%=l(:label_total)%></th>
+</tr></thead>
+<tbody>
+<% for row in rows %>
+<tr class="<%= cycle("odd", "even") %>">
+  <td><%= link_to h(row.name), aggregate_path(@project, field_name, row) %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o") %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c") %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*") %></td>
+</tr>
+<% end %>
+</tbody>
+</table>
+<% end
+  reset_cycle %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f4/f43305298989567d96f5b7cd3fec323aa70a3dd0.svn-base
--- /dev/null
+++ b/.svn/pristine/f4/f43305298989567d96f5b7cd3fec323aa70a3dd0.svn-base
@@ -0,0 +1,62 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingQueriesTest < ActionController::IntegrationTest
+  def test_queries
+    assert_routing(
+        { :method => 'get', :path => "/queries.xml" },
+        { :controller => 'queries', :action => 'index', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/queries.json" },
+        { :controller => 'queries', :action => 'index', :format => 'json' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/queries/new" },
+        { :controller => 'queries', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/queries" },
+        { :controller => 'queries', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/queries/1/edit" },
+        { :controller => 'queries', :action => 'edit', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/queries/1" },
+        { :controller => 'queries', :action => 'update', :id => '1' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/queries/1" },
+        { :controller => 'queries', :action => 'destroy', :id => '1' }
+      )
+  end
+
+  def test_queries_scoped_under_project
+    assert_routing(
+        { :method => 'get', :path => "/projects/redmine/queries/new" },
+        { :controller => 'queries', :action => 'new', :project_id => 'redmine' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/redmine/queries" },
+        { :controller => 'queries', :action => 'create', :project_id => 'redmine' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f4/f467515460b9eb22b10f740b88d1c4243cdd2fcb.svn-base
--- a/.svn/pristine/f4/f467515460b9eb22b10f740b88d1c4243cdd2fcb.svn-base
+++ /dev/null
@@ -1,8 +0,0 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class BackwardsCompatibilityTest < Test::Unit::TestCase
-  def test_rails_module_plugin_method_should_delegate_to_engines_plugins
-    assert_nothing_raised { Rails.plugins }
-    assert_equal Engines.plugins, Rails.plugins 
-  end
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f4/f477bf3402d32b68d566290356d0f3926584dab7.svn-base
--- /dev/null
+++ b/.svn/pristine/f4/f477bf3402d32b68d566290356d0f3926584dab7.svn-base
@@ -0,0 +1,490 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class MailHandler < ActionMailer::Base
+  include ActionView::Helpers::SanitizeHelper
+  include Redmine::I18n
+
+  class UnauthorizedAction < StandardError; end
+  class MissingInformation < StandardError; end
+
+  attr_reader :email, :user
+
+  def self.receive(email, options={})
+    @@handler_options = options.dup
+
+    @@handler_options[:issue] ||= {}
+
+    if @@handler_options[:allow_override].is_a?(String)
+      @@handler_options[:allow_override] = @@handler_options[:allow_override].split(',').collect(&:strip)
+    end
+    @@handler_options[:allow_override] ||= []
+    # Project needs to be overridable if not specified
+    @@handler_options[:allow_override] << 'project' unless @@handler_options[:issue].has_key?(:project)
+    # Status overridable by default
+    @@handler_options[:allow_override] << 'status' unless @@handler_options[:issue].has_key?(:status)
+
+    @@handler_options[:no_account_notice] = (@@handler_options[:no_account_notice].to_s == '1')
+    @@handler_options[:no_notification] = (@@handler_options[:no_notification].to_s == '1')
+    @@handler_options[:no_permission_check] = (@@handler_options[:no_permission_check].to_s == '1')
+
+    email.force_encoding('ASCII-8BIT') if email.respond_to?(:force_encoding)
+    super(email)
+  end
+
+  def logger
+    Rails.logger
+  end
+
+  cattr_accessor :ignored_emails_headers
+  @@ignored_emails_headers = {
+    'X-Auto-Response-Suppress' => 'oof',
+    'Auto-Submitted' => /^auto-/
+  }
+
+  # Processes incoming emails
+  # Returns the created object (eg. an issue, a message) or false
+  def receive(email)
+    @email = email
+    sender_email = email.from.to_a.first.to_s.strip
+    # Ignore emails received from the application emission address to avoid hell cycles
+    if sender_email.downcase == Setting.mail_from.to_s.strip.downcase
+      if logger && logger.info
+        logger.info  "MailHandler: ignoring email from Redmine emission address [#{sender_email}]"
+      end
+      return false
+    end
+    # Ignore auto generated emails
+    self.class.ignored_emails_headers.each do |key, ignored_value|
+      value = email.header[key]
+      if value
+        value = value.to_s.downcase
+        if (ignored_value.is_a?(Regexp) && value.match(ignored_value)) || value == ignored_value
+          if logger && logger.info
+            logger.info "MailHandler: ignoring email with #{key}:#{value} header"
+          end
+          return false
+        end
+      end
+    end
+    @user = User.find_by_mail(sender_email) if sender_email.present?
+    if @user && !@user.active?
+      if logger && logger.info
+        logger.info  "MailHandler: ignoring email from non-active user [#{@user.login}]"
+      end
+      return false
+    end
+    if @user.nil?
+      # Email was submitted by an unknown user
+      case @@handler_options[:unknown_user]
+      when 'accept'
+        @user = User.anonymous
+      when 'create'
+        @user = create_user_from_email
+        if @user
+          if logger && logger.info
+            logger.info "MailHandler: [#{@user.login}] account created"
+          end
+          add_user_to_group(@@handler_options[:default_group])
+          unless @@handler_options[:no_account_notice]
+            Mailer.account_information(@user, @user.password).deliver
+          end
+        else
+          if logger && logger.error
+            logger.error "MailHandler: could not create account for [#{sender_email}]"
+          end
+          return false
+        end
+      else
+        # Default behaviour, emails from unknown users are ignored
+        if logger && logger.info
+          logger.info  "MailHandler: ignoring email from unknown user [#{sender_email}]"
+        end
+        return false
+      end
+    end
+    User.current = @user
+    dispatch
+  end
+
+  private
+
+  MESSAGE_ID_RE = %r{^<?redmine\.([a-z0-9_]+)\-(\d+)\.\d+@}
+  ISSUE_REPLY_SUBJECT_RE = %r{\[[^\]]*#(\d+)\]}
+  MESSAGE_REPLY_SUBJECT_RE = %r{\[[^\]]*msg(\d+)\]}
+
+  def dispatch
+    headers = [email.in_reply_to, email.references].flatten.compact
+    subject = email.subject.to_s
+    if headers.detect {|h| h.to_s =~ MESSAGE_ID_RE}
+      klass, object_id = $1, $2.to_i
+      method_name = "receive_#{klass}_reply"
+      if self.class.private_instance_methods.collect(&:to_s).include?(method_name)
+        send method_name, object_id
+      else
+        # ignoring it
+      end
+    elsif m = subject.match(ISSUE_REPLY_SUBJECT_RE)
+      receive_issue_reply(m[1].to_i)
+    elsif m = subject.match(MESSAGE_REPLY_SUBJECT_RE)
+      receive_message_reply(m[1].to_i)
+    else
+      dispatch_to_default
+    end
+  rescue ActiveRecord::RecordInvalid => e
+    # TODO: send a email to the user
+    logger.error e.message if logger
+    false
+  rescue MissingInformation => e
+    logger.error "MailHandler: missing information from #{user}: #{e.message}" if logger
+    false
+  rescue UnauthorizedAction => e
+    logger.error "MailHandler: unauthorized attempt from #{user}" if logger
+    false
+  end
+
+  def dispatch_to_default
+    receive_issue
+  end
+
+  # Creates a new issue
+  def receive_issue
+    project = target_project
+    # check permission
+    unless @@handler_options[:no_permission_check]
+      raise UnauthorizedAction unless user.allowed_to?(:add_issues, project)
+    end
+
+    issue = Issue.new(:author => user, :project => project)
+    issue.safe_attributes = issue_attributes_from_keywords(issue)
+    issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)}
+    issue.subject = cleaned_up_subject
+    if issue.subject.blank?
+      issue.subject = '(no subject)'
+    end
+    issue.description = cleaned_up_text_body
+
+    # add To and Cc as watchers before saving so the watchers can reply to Redmine
+    add_watchers(issue)
+    issue.save!
+    add_attachments(issue)
+    logger.info "MailHandler: issue ##{issue.id} created by #{user}" if logger && logger.info
+    issue
+  end
+
+  # Adds a note to an existing issue
+  def receive_issue_reply(issue_id, from_journal=nil)
+    issue = Issue.find_by_id(issue_id)
+    return unless issue
+    # check permission
+    unless @@handler_options[:no_permission_check]
+      unless user.allowed_to?(:add_issue_notes, issue.project) ||
+               user.allowed_to?(:edit_issues, issue.project)
+        raise UnauthorizedAction
+      end
+    end
+
+    # ignore CLI-supplied defaults for new issues
+    @@handler_options[:issue].clear
+
+    journal = issue.init_journal(user)
+    if from_journal && from_journal.private_notes?
+      # If the received email was a reply to a private note, make the added note private
+      issue.private_notes = true
+    end
+    issue.safe_attributes = issue_attributes_from_keywords(issue)
+    issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)}
+    journal.notes = cleaned_up_text_body
+    add_attachments(issue)
+    issue.save!
+    if logger && logger.info
+      logger.info "MailHandler: issue ##{issue.id} updated by #{user}"
+    end
+    journal
+  end
+
+  # Reply will be added to the issue
+  def receive_journal_reply(journal_id)
+    journal = Journal.find_by_id(journal_id)
+    if journal && journal.journalized_type == 'Issue'
+      receive_issue_reply(journal.journalized_id, journal)
+    end
+  end
+
+  # Receives a reply to a forum message
+  def receive_message_reply(message_id)
+    message = Message.find_by_id(message_id)
+    if message
+      message = message.root
+
+      unless @@handler_options[:no_permission_check]
+        raise UnauthorizedAction unless user.allowed_to?(:add_messages, message.project)
+      end
+
+      if !message.locked?
+        reply = Message.new(:subject => cleaned_up_subject.gsub(%r{^.*msg\d+\]}, '').strip,
+                            :content => cleaned_up_text_body)
+        reply.author = user
+        reply.board = message.board
+        message.children << reply
+        add_attachments(reply)
+        reply
+      else
+        if logger && logger.info
+          logger.info "MailHandler: ignoring reply from [#{sender_email}] to a locked topic"
+        end
+      end
+    end
+  end
+
+  def add_attachments(obj)
+    if email.attachments && email.attachments.any?
+      email.attachments.each do |attachment|
+        obj.attachments << Attachment.create(:container => obj,
+                          :file => attachment.decoded,
+                          :filename => attachment.filename,
+                          :author => user,
+                          :content_type => attachment.mime_type)
+      end
+    end
+  end
+
+  # Adds To and Cc as watchers of the given object if the sender has the
+  # appropriate permission
+  def add_watchers(obj)
+    if user.allowed_to?("add_#{obj.class.name.underscore}_watchers".to_sym, obj.project)
+      addresses = [email.to, email.cc].flatten.compact.uniq.collect {|a| a.strip.downcase}
+      unless addresses.empty?
+        watchers = User.active.where('LOWER(mail) IN (?)', addresses).all
+        watchers.each {|w| obj.add_watcher(w)}
+      end
+    end
+  end
+
+  def get_keyword(attr, options={})
+    @keywords ||= {}
+    if @keywords.has_key?(attr)
+      @keywords[attr]
+    else
+      @keywords[attr] = begin
+        if (options[:override] || @@handler_options[:allow_override].include?(attr.to_s)) &&
+              (v = extract_keyword!(plain_text_body, attr, options[:format]))
+          v
+        elsif !@@handler_options[:issue][attr].blank?
+          @@handler_options[:issue][attr]
+        end
+      end
+    end
+  end
+
+  # Destructively extracts the value for +attr+ in +text+
+  # Returns nil if no matching keyword found
+  def extract_keyword!(text, attr, format=nil)
+    keys = [attr.to_s.humanize]
+    if attr.is_a?(Symbol)
+      if user && user.language.present?
+        keys << l("field_#{attr}", :default => '', :locale =>  user.language)
+      end
+      if Setting.default_language.present?
+        keys << l("field_#{attr}", :default => '', :locale =>  Setting.default_language)
+      end
+    end
+    keys.reject! {|k| k.blank?}
+    keys.collect! {|k| Regexp.escape(k)}
+    format ||= '.+'
+    keyword = nil
+    regexp = /^(#{keys.join('|')})[ \t]*:[ \t]*(#{format})\s*$/i
+    if m = text.match(regexp)
+      keyword = m[2].strip
+      text.gsub!(regexp, '')
+    end
+    keyword
+  end
+
+  def target_project
+    # TODO: other ways to specify project:
+    # * parse the email To field
+    # * specific project (eg. Setting.mail_handler_target_project)
+    target = Project.find_by_identifier(get_keyword(:project))
+    raise MissingInformation.new('Unable to determine target project') if target.nil?
+    target
+  end
+
+  # Returns a Hash of issue attributes extracted from keywords in the email body
+  def issue_attributes_from_keywords(issue)
+    assigned_to = (k = get_keyword(:assigned_to, :override => true)) && find_assignee_from_keyword(k, issue)
+
+    attrs = {
+      'tracker_id' => (k = get_keyword(:tracker)) && issue.project.trackers.named(k).first.try(:id),
+      'status_id' =>  (k = get_keyword(:status)) && IssueStatus.named(k).first.try(:id),
+      'priority_id' => (k = get_keyword(:priority)) && IssuePriority.named(k).first.try(:id),
+      'category_id' => (k = get_keyword(:category)) && issue.project.issue_categories.named(k).first.try(:id),
+      'assigned_to_id' => assigned_to.try(:id),
+      'fixed_version_id' => (k = get_keyword(:fixed_version, :override => true)) &&
+                                issue.project.shared_versions.named(k).first.try(:id),
+      'start_date' => get_keyword(:start_date, :override => true, :format => '\d{4}-\d{2}-\d{2}'),
+      'due_date' => get_keyword(:due_date, :override => true, :format => '\d{4}-\d{2}-\d{2}'),
+      'estimated_hours' => get_keyword(:estimated_hours, :override => true),
+      'done_ratio' => get_keyword(:done_ratio, :override => true, :format => '(\d|10)?0')
+    }.delete_if {|k, v| v.blank? }
+
+    if issue.new_record? && attrs['tracker_id'].nil?
+      attrs['tracker_id'] = issue.project.trackers.first.try(:id)
+    end
+
+    attrs
+  end
+
+  # Returns a Hash of issue custom field values extracted from keywords in the email body
+  def custom_field_values_from_keywords(customized)
+    customized.custom_field_values.inject({}) do |h, v|
+      if keyword = get_keyword(v.custom_field.name, :override => true)
+        h[v.custom_field.id.to_s] = v.custom_field.value_from_keyword(keyword, customized)
+      end
+      h
+    end
+  end
+
+  # Returns the text/plain part of the email
+  # If not found (eg. HTML-only email), returns the body with tags removed
+  def plain_text_body
+    return @plain_text_body unless @plain_text_body.nil?
+
+    part = email.text_part || email.html_part || email
+    @plain_text_body = Redmine::CodesetUtil.to_utf8(part.body.decoded, part.charset)
+
+    # strip html tags and remove doctype directive
+    @plain_text_body = strip_tags(@plain_text_body.strip)
+    @plain_text_body.sub! %r{^<!DOCTYPE .*$}, ''
+    @plain_text_body
+  end
+
+  def cleaned_up_text_body
+    cleanup_body(plain_text_body)
+  end
+
+  def cleaned_up_subject
+    subject = email.subject.to_s
+    subject.strip[0,255]
+  end
+
+  def self.full_sanitizer
+    @full_sanitizer ||= HTML::FullSanitizer.new
+  end
+
+  def self.assign_string_attribute_with_limit(object, attribute, value, limit=nil)
+    limit ||= object.class.columns_hash[attribute.to_s].limit || 255
+    value = value.to_s.slice(0, limit)
+    object.send("#{attribute}=", value)
+  end
+
+  # Returns a User from an email address and a full name
+  def self.new_user_from_attributes(email_address, fullname=nil)
+    user = User.new
+
+    # Truncating the email address would result in an invalid format
+    user.mail = email_address
+    assign_string_attribute_with_limit(user, 'login', email_address, User::LOGIN_LENGTH_LIMIT)
+
+    names = fullname.blank? ? email_address.gsub(/@.*$/, '').split('.') : fullname.split
+    assign_string_attribute_with_limit(user, 'firstname', names.shift, 30)
+    assign_string_attribute_with_limit(user, 'lastname', names.join(' '), 30)
+    user.lastname = '-' if user.lastname.blank?
+
+    password_length = [Setting.password_min_length.to_i, 10].max
+    user.password = Redmine::Utils.random_hex(password_length / 2 + 1)
+    user.language = Setting.default_language
+    user.mail_notification = 'only_my_events'
+
+    unless user.valid?
+      user.login = "user#{Redmine::Utils.random_hex(6)}" unless user.errors[:login].blank?
+      user.firstname = "-" unless user.errors[:firstname].blank?
+      (puts user.errors[:lastname];user.lastname  = "-") unless user.errors[:lastname].blank?
+    end
+
+    user
+  end
+
+  # Creates a User for the +email+ sender
+  # Returns the user or nil if it could not be created
+  def create_user_from_email
+    from = email.header['from'].to_s
+    addr, name = from, nil
+    if m = from.match(/^"?(.+?)"?\s+<(.+@.+)>$/)
+      addr, name = m[2], m[1]
+    end
+    if addr.present?
+      user = self.class.new_user_from_attributes(addr, name)
+      if @@handler_options[:no_notification]
+        user.mail_notification = 'none'
+      end
+      if user.save
+        user
+      else
+        logger.error "MailHandler: failed to create User: #{user.errors.full_messages}" if logger
+        nil
+      end
+    else
+      logger.error "MailHandler: failed to create User: no FROM address found" if logger
+      nil
+    end
+  end
+
+	# Adds the newly created user to default group
+  def add_user_to_group(default_group)
+    if default_group.present?
+      default_group.split(',').each do |group_name|
+        if group = Group.named(group_name).first
+          group.users << @user
+        elsif logger
+          logger.warn "MailHandler: could not add user to [#{group_name}], group not found"
+        end
+      end
+    end
+  end
+
+  # Removes the email body of text after the truncation configurations.
+  def cleanup_body(body)
+    delimiters = Setting.mail_handler_body_delimiters.to_s.split(/[\r\n]+/).reject(&:blank?).map {|s| Regexp.escape(s)}
+    unless delimiters.empty?
+      regex = Regexp.new("^[> ]*(#{ delimiters.join('|') })\s*[\r\n].*", Regexp::MULTILINE)
+      body = body.gsub(regex, '')
+    end
+    body.strip
+  end
+
+  def find_assignee_from_keyword(keyword, issue)
+    keyword = keyword.to_s.downcase
+    assignable = issue.assignable_users
+    assignee = nil
+    assignee ||= assignable.detect {|a|
+                   a.mail.to_s.downcase == keyword ||
+                     a.login.to_s.downcase == keyword
+                 }
+    if assignee.nil? && keyword.match(/ /)
+      firstname, lastname = *(keyword.split) # "First Last Throwaway"
+      assignee ||= assignable.detect {|a|
+                     a.is_a?(User) && a.firstname.to_s.downcase == firstname &&
+                       a.lastname.to_s.downcase == lastname
+                   }
+    end
+    if assignee.nil?
+      assignee ||= assignable.detect {|a| a.name.downcase == keyword}
+    end
+    assignee
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f4/f4bd9cf8c7227a2836ae6369246ebcb1a93c4265.svn-base
--- /dev/null
+++ b/.svn/pristine/f4/f4bd9cf8c7227a2836ae6369246ebcb1a93c4265.svn-base
@@ -0,0 +1,47 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'builder'
+
+module Redmine
+  module Views
+    module Builders
+      class Xml < ::Builder::XmlMarkup
+        def initialize(request, response)
+          super()
+          instruct!
+        end
+
+        def output
+          target!
+        end
+
+        def method_missing(sym, *args, &block)
+          if args.size == 1 && args.first.is_a?(::Time)
+            __send__ sym, args.first.xmlschema, &block
+          else
+            super
+          end
+        end
+
+        def array(name, options={}, &block)
+          __send__ name, (options || {}).merge(:type => 'array'), &block
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f5/f567519f5d8f3ccd15069929ebb16c826537f452.svn-base
--- /dev/null
+++ b/.svn/pristine/f5/f567519f5d8f3ccd15069929ebb16c826537f452.svn-base
@@ -0,0 +1,106 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class QueriesController < ApplicationController
+  menu_item :issues
+  before_filter :find_query, :except => [:new, :create, :index]
+  before_filter :find_optional_project, :only => [:new, :create]
+
+  accept_api_auth :index
+
+  include QueriesHelper
+
+  def index
+    case params[:format]
+    when 'xml', 'json'
+      @offset, @limit = api_offset_and_limit
+    else
+      @limit = per_page_option
+    end
+
+    @query_count = IssueQuery.visible.count
+    @query_pages = Paginator.new @query_count, @limit, params['page']
+    @queries = IssueQuery.visible.all(:limit => @limit, :offset => @offset, :order => "#{Query.table_name}.name")
+
+    respond_to do |format|
+      format.api
+    end
+  end
+
+  def new
+    @query = IssueQuery.new
+    @query.user = User.current
+    @query.project = @project
+    @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
+    @query.build_from_params(params)
+  end
+
+  def create
+    @query = IssueQuery.new(params[:query])
+    @query.user = User.current
+    @query.project = params[:query_is_for_all] ? nil : @project
+    @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
+    @query.build_from_params(params)
+    @query.column_names = nil if params[:default_columns]
+
+    if @query.save
+      flash[:notice] = l(:notice_successful_create)
+      redirect_to _project_issues_path(@project, :query_id => @query)
+    else
+      render :action => 'new', :layout => !request.xhr?
+    end
+  end
+
+  def edit
+  end
+
+  def update
+    @query.attributes = params[:query]
+    @query.project = nil if params[:query_is_for_all]
+    @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
+    @query.build_from_params(params)
+    @query.column_names = nil if params[:default_columns]
+
+    if @query.save
+      flash[:notice] = l(:notice_successful_update)
+      redirect_to _project_issues_path(@project, :query_id => @query)
+    else
+      render :action => 'edit'
+    end
+  end
+
+  def destroy
+    @query.destroy
+    redirect_to _project_issues_path(@project, :set_filter => 1)
+  end
+
+private
+  def find_query
+    @query = IssueQuery.find(params[:id])
+    @project = @query.project
+    render_403 unless @query.editable_by?(User.current)
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+
+  def find_optional_project
+    @project = Project.find(params[:project_id]) if params[:project_id]
+    render_403 unless User.current.allowed_to?(:save_queries, @project, :global => true)
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f5/f57cb4b2fd4e8b282707982829017761e21ff080.svn-base
--- /dev/null
+++ b/.svn/pristine/f5/f57cb4b2fd4e8b282707982829017761e21ff080.svn-base
@@ -0,0 +1,103 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Ciphering
+    def self.included(base)
+      base.extend ClassMethods
+    end
+
+    class << self
+      def encrypt_text(text)
+        if cipher_key.blank? || text.blank?
+          text
+        else
+          c = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
+          iv = c.random_iv
+          c.encrypt
+          c.key = cipher_key
+          c.iv = iv
+          e = c.update(text.to_s)
+          e << c.final
+          "aes-256-cbc:" + [e, iv].map {|v| Base64.encode64(v).strip}.join('--')
+        end
+      end
+
+      def decrypt_text(text)
+        if text && match = text.match(/\Aaes-256-cbc:(.+)\Z/)
+          if cipher_key.blank?
+            logger.error "Attempt to decrypt a ciphered text with no cipher key configured in config/configuration.yml" if logger
+            return text
+          end
+          text = match[1]
+          c = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
+          e, iv = text.split("--").map {|s| Base64.decode64(s)}
+          c.decrypt
+          c.key = cipher_key
+          c.iv = iv
+          d = c.update(e)
+          d << c.final
+        else
+          text
+        end
+      end
+
+      def cipher_key
+        key = Redmine::Configuration['database_cipher_key'].to_s
+        key.blank? ? nil : Digest::SHA256.hexdigest(key)
+      end
+      
+      def logger
+        Rails.logger
+      end
+    end
+
+    module ClassMethods
+      def encrypt_all(attribute)
+        transaction do
+          all.each do |object|
+            clear = object.send(attribute)
+            object.send "#{attribute}=", clear
+            raise(ActiveRecord::Rollback) unless object.save(:validation => false)
+          end
+        end ? true : false
+      end
+
+      def decrypt_all(attribute)
+        transaction do
+          all.each do |object|
+            clear = object.send(attribute)
+            object.send :write_attribute, attribute, clear
+            raise(ActiveRecord::Rollback) unless object.save(:validation => false)
+          end
+        end
+      end ? true : false
+    end
+
+    private
+
+    # Returns the value of the given ciphered attribute
+    def read_ciphered_attribute(attribute)
+      Redmine::Ciphering.decrypt_text(read_attribute(attribute))
+    end
+
+    # Sets the value of the given ciphered attribute
+    def write_ciphered_attribute(attribute, value)
+      write_attribute(attribute, Redmine::Ciphering.encrypt_text(value))
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f5/f58a566574c2a05cde87f16c23c2fc9af55a3297.svn-base
--- a/.svn/pristine/f5/f58a566574c2a05cde87f16c23c2fc9af55a3297.svn-base
+++ /dev/null
@@ -1,37 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class WorkflowTest < ActiveSupport::TestCase
-  fixtures :roles, :trackers, :issue_statuses
-
-  def test_copy
-    Workflow.delete_all
-    Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 2)
-    Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 3, :assignee => true)
-    Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 4, :author => true)
-
-    assert_difference 'Workflow.count', 3 do
-      Workflow.copy(Tracker.find(2), Role.find(1), Tracker.find(3), Role.find(2))
-    end
-
-    assert Workflow.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false})
-    assert Workflow.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 3, :author => false, :assignee => true})
-    assert Workflow.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 4, :author => true, :assignee => false})
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f5/f5ab1d07c740e8d415c8b82041e81fc8bd2e6f97.svn-base
--- a/.svn/pristine/f5/f5ab1d07c740e8d415c8b82041e81fc8bd2e6f97.svn-base
+++ /dev/null
@@ -1,1088 +0,0 @@
-# Chinese (Taiwan) translations for Ruby on Rails
-# by tsechingho (http://github.com/tsechingho)
-# See http://github.com/svenfuchs/rails-i18n/ for details.
-
-"zh-TW":
-  direction: ltr
-  date:
-    formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
-      default: "%Y-%m-%d"
-      short: "%b%dæ—¥"
-      long: "%Yå¹´%b%dæ—¥"
-
-    day_names: [æ˜ŸæœŸæ—¥, æ˜ŸæœŸä¸€, æ˜ŸæœŸäºŒ, æ˜ŸæœŸä¸‰, æ˜ŸæœŸå››, æ˜ŸæœŸäº”, æ˜ŸæœŸå…­]
-    abbr_day_names: [æ—¥, ä¸€, äºŒ, ä¸‰, å››, äº”, å…­]
-
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
-    month_names: [~, ä¸€æœˆ, äºŒæœˆ, ä¸‰æœˆ, å››æœˆ, äº”æœˆ, å…­æœˆ, ä¸ƒæœˆ, å…«æœˆ, ä¹æœˆ, åæœˆ, åä¸€æœˆ, åäºŒæœˆ]
-    abbr_month_names: [~, 1æœˆ, 2æœˆ, 3æœˆ, 4æœˆ, 5æœˆ, 6æœˆ, 7æœˆ, 8æœˆ, 9æœˆ, 10æœˆ, 11æœˆ, 12æœˆ]
-    # ä½¿ç”¨æ–¼ date_select èˆ‡ datime_select.
-    order:
-      - :year
-      - :month
-      - :day
-
-  time:
-    formats:
-      default: "%Yå¹´%b%dæ—¥ %A %H:%M:%S %Z"
-      time: "%H:%M"
-      short: "%b%dæ—¥ %H:%M"
-      long: "%Yå¹´%b%dæ—¥ %H:%M"
-    am: "AM"
-    pm: "PM"
-
-# ä½¿ç”¨æ–¼ array.to_sentence.
-  support:
-    array:
-      words_connector: ", "
-      two_words_connector: " å’Œ "
-      last_word_connector: ", å’Œ "
-      sentence_connector: "ä¸”"
-      skip_last_comma: false
-
-  number:
-    # ä½¿ç”¨æ–¼ number_with_delimiter()
-    # åŒæ™‚ä¹Ÿæ˜¯ 'currency', 'percentage', 'precision', èˆ‡ 'human' çš„é è¨­å€¼
-    format:
-      # è¨­å®šå°æ•¸é»žåˆ†éš”å­—å…ƒï¼Œä»¥ä½¿ç”¨æ›´é«˜çš„æº–ç¢ºåº¦ (ä¾‹å¦‚ï¼š 1.0 / 2.0 == 0.5)
-      separator: "."
-      # åƒåˆ†ä½ç¬¦è™Ÿ (ä¾‹å¦‚ï¼šä¸€ç™¾è¬æ˜¯ 1,000,000) (å‡ä»¥ä¸‰å€‹ä½æ•¸ä¾†åˆ†çµ„)
-      delimiter: ","
-      # å°æ•¸é»žåˆ†éš”å­—å…ƒå¾Œä¹‹ç²¾ç¢ºä½æ•¸ (æ•¸å­— 1 æ­é… 2 ä½ç²¾ç¢ºä½æ•¸ç‚ºï¼š 1.00)
-      precision: 3
-
-    # ä½¿ç”¨æ–¼ number_to_currency()
-    currency:
-      format:
-        # è²¨å¹£ç¬¦è™Ÿçš„ä½ç½®? %u æ˜¯è²¨å¹£ç¬¦è™Ÿ, %n æ˜¯æ•¸å€¼ (é è¨­å€¼ï¼š $5.00)
-        format: "%u%n"
-        unit: "NT$"
-        # ä¸‹åˆ—ä¸‰å€‹é¸é …è¨­å®š, è‹¥æœ‰è¨­å®šå€¼å°‡æœƒå–ä»£ number.format æˆç‚ºé è¨­å€¼
-        separator: "."
-        delimiter: ","
-        precision: 2
-
-    # ä½¿ç”¨æ–¼ number_to_percentage()
-    percentage:
-      format:
-        # ä¸‹åˆ—ä¸‰å€‹é¸é …è¨­å®š, è‹¥æœ‰è¨­å®šå€¼å°‡æœƒå–ä»£ number.format æˆç‚ºé è¨­å€¼
-        # separator:
-        delimiter: ""
-        # precision:
-
-    # ä½¿ç”¨æ–¼ number_to_precision()
-    precision:
-      format:
-        # ä¸‹åˆ—ä¸‰å€‹é¸é …è¨­å®š, è‹¥æœ‰è¨­å®šå€¼å°‡æœƒå–ä»£ number.format æˆç‚ºé è¨­å€¼
-        # separator:
-        delimiter: ""
-        # precision:
-
-    # ä½¿ç”¨æ–¼ number_to_human_size()
-    human:
-      format:
-        # ä¸‹åˆ—ä¸‰å€‹é¸é …è¨­å®š, è‹¥æœ‰è¨­å®šå€¼å°‡æœƒå–ä»£ number.format æˆç‚ºé è¨­å€¼
-        # separator:
-        delimiter: ""
-        precision: 1
-        # å„²å­˜å–®ä½è¼¸å‡ºæ ¼å¼.
-        # %u æ˜¯å„²å­˜å–®ä½, %n æ˜¯æ•¸å€¼ (é è¨­å€¼: 2 MB)
-      storage_units:
-        format: "%n %u"
-        units:
-          byte:
-            one: "ä½å…ƒçµ„ (B)"
-            other: "ä½å…ƒçµ„ (B)"
-          kb: "KB"
-          mb: "MB"
-          gb: "GB"
-          tb: "TB"
-
-  # ä½¿ç”¨æ–¼ distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
-  datetime:
-    distance_in_words:
-      half_a_minute: "åŠåˆ†é˜"
-      less_than_x_seconds:
-        one: "å°æ–¼ 1 ç§’"
-        other: "å°æ–¼ %{count} ç§’"
-      x_seconds:
-        one: "1 ç§’"
-        other: "%{count} ç§’"
-      less_than_x_minutes:
-        one: "å°æ–¼ 1 åˆ†é˜"
-        other: "å°æ–¼ %{count} åˆ†é˜"
-      x_minutes:
-        one: "1 åˆ†é˜"
-        other: "%{count} åˆ†é˜"
-      about_x_hours:
-        one: "ç´„ 1 å°æ™‚"
-        other: "ç´„ %{count} å°æ™‚"
-      x_days:
-        one: "1 å¤©"
-        other: "%{count} å¤©"
-      about_x_months:
-        one: "ç´„ 1 å€‹æœˆ"
-        other: "ç´„ %{count} å€‹æœˆ"
-      x_months:
-        one: "1 å€‹æœˆ"
-        other: "%{count} å€‹æœˆ"
-      about_x_years:
-        one: "ç´„ 1 å¹´"
-        other: "ç´„ %{count} å¹´"
-      over_x_years:
-        one: "è¶…éŽ 1 å¹´"
-        other: "è¶…éŽ %{count} å¹´"
-      almost_x_years:
-        one:   "å°‡è¿‘ 1 å¹´"
-        other: "å°‡è¿‘ %{count} å¹´"
-    prompts:
-      year:   "å¹´"
-      month:  "æœˆ"
-      day:    "æ—¥"
-      hour:   "æ™‚"
-      minute: "åˆ†"
-      second: "ç§’"
-
-  activerecord:
-    errors:
-      template:
-        header:
-          one:   "æœ‰ 1 å€‹éŒ¯èª¤ç™¼ç”Ÿä½¿å¾—ã€Œ%{model}ã€ç„¡æ³•è¢«å„²å­˜ã€‚"
-          other: "æœ‰ %{count} å€‹éŒ¯èª¤ç™¼ç”Ÿä½¿å¾—ã€Œ%{model}ã€ç„¡æ³•è¢«å„²å­˜ã€‚"
-        # The variable :count is also available
-        body: "ä¸‹é¢æ‰€åˆ—æ¬„ä½æœ‰å•é¡Œï¼š"
-      # The values :model, :attribute and :value are always available for interpolation
-      # The value :count is available when applicable. Can be used for pluralization.
-      messages:
-        inclusion: "æ²’æœ‰åŒ…å«åœ¨åˆ—è¡¨ä¸­"
-        exclusion: "æ˜¯è¢«ä¿ç•™çš„"
-        invalid: "æ˜¯ç„¡æ•ˆçš„"
-        confirmation: "ä¸ç¬¦åˆç¢ºèªå€¼"
-        accepted: "å¿…é¡»æ˜¯å¯è¢«æŽ¥å—çš„"
-        empty: "ä¸èƒ½ç•™ç©º"
-        blank: "ä¸èƒ½æ˜¯ç©ºç™½å­—å…ƒ"
-        too_long: "éŽé•·ï¼ˆæœ€é•·æ˜¯ %{count} å€‹å­—ï¼‰"
-        too_short: "éŽçŸ­ï¼ˆæœ€çŸ­æ˜¯ %{count} å€‹å­—ï¼‰"
-        wrong_length: "å­—æ•¸éŒ¯èª¤ï¼ˆå¿…é ˆæ˜¯ %{count} å€‹å­—ï¼‰"
-        taken: "å·²ç¶“è¢«ä½¿ç”¨"
-        not_a_number: "ä¸æ˜¯æ•¸å­—"
-        greater_than: "å¿…é ˆå¤§æ–¼ %{count}"
-        greater_than_or_equal_to: "å¿…é ˆå¤§æ–¼æˆ–ç­‰æ–¼ %{count}"
-        equal_to: "å¿…é ˆç­‰æ–¼ %{count}"
-        less_than: "å¿…é ˆå°æ–¼ %{count}"
-        less_than_or_equal_to: "å¿…é ˆå°æ–¼æˆ–ç­‰æ–¼ %{count}"
-        odd: "å¿…é ˆæ˜¯å¥‡æ•¸"
-        even: "å¿…é ˆæ˜¯å¶æ•¸"
-        # Append your own errors here or at the model/attributes scope.
-        greater_than_start_date: "å¿…é ˆåœ¨é–‹å§‹æ—¥æœŸä¹‹å¾Œ"
-        not_same_project: "ä¸å±¬æ–¼åŒä¸€å€‹å°ˆæ¡ˆ"
-        circular_dependency: "é€™å€‹é—œè¯æœƒå°Žè‡´ç’°ç‹€ç›¸ä¾"
-        cant_link_an_issue_with_a_descendant: "å•é¡Œç„¡æ³•è¢«é€£çµè‡³è‡ªå·±çš„å­ä»»å‹™"
-
-      # You can define own errors for models or model attributes.
-      # The values :model, :attribute and :value are always available for interpolation.
-      #
-      # For example,
-      #   models:
-      #     user:
-      #       blank: "This is a custom blank message for %{model}: %{attribute}"
-      #       attributes:
-      #         login:
-      #           blank: "This is a custom blank message for User login"
-      # Will define custom blank validation message for User model and
-      # custom blank validation message for login attribute of User model.
-      #models:
-
-    # Translate model names. Used in Model.human_name().
-    #models:
-      # For example,
-      #   user: "Dude"
-      # will translate User model name to "Dude"
-
-    # Translate model attribute names. Used in Model.human_attribute_name(attribute).
-    #attributes:
-      # For example,
-      #   user:
-      #     login: "Handle"
-      # will translate User attribute "login" as "Handle"
-
-  actionview_instancetag_blank_option: è«‹é¸æ“‡
-
-  general_text_No: 'å¦'
-  general_text_Yes: 'æ˜¯'
-  general_text_no: 'å¦'
-  general_text_yes: 'æ˜¯'
-  general_lang_name: 'Traditional Chinese (ç¹é«”ä¸­æ–‡)'
-  general_csv_separator: ','
-  general_csv_decimal_separator: '.'
-  general_csv_encoding: Big5
-  general_pdf_encoding: Big5
-  general_first_day_of_week: '7'
-
-  notice_account_updated: å¸³æˆ¶æ›´æ–°è³‡è¨Šå·²å„²å­˜
-  notice_account_invalid_creditentials: å¸³æˆ¶æˆ–å¯†ç¢¼ä¸æ­£ç¢º
-  notice_account_password_updated: å¸³æˆ¶æ–°å¯†ç¢¼å·²å„²å­˜
-  notice_account_wrong_password: å¯†ç¢¼ä¸æ­£ç¢º
-  notice_account_register_done: å¸³è™Ÿå·²å»ºç«‹æˆåŠŸã€‚æ¬²å•Ÿç”¨æ‚¨çš„å¸³è™Ÿï¼Œè«‹é»žæ“Šç³»çµ±ç¢ºèªä¿¡å‡½ä¸­çš„å•Ÿç”¨é€£çµã€‚
-  notice_account_unknown_email: æœªçŸ¥çš„ä½¿ç”¨è€…
-  notice_can_t_change_password: é€™å€‹å¸³è™Ÿä½¿ç”¨å¤–éƒ¨èªè­‰æ–¹å¼ï¼Œç„¡æ³•è®Šæ›´å…¶å¯†ç¢¼ã€‚
-  notice_account_lost_email_sent: åŒ…å«é¸æ“‡æ–°å¯†ç¢¼æŒ‡ç¤ºçš„é›»å­éƒµä»¶ï¼Œå·²ç¶“å¯„å‡ºçµ¦æ‚¨ã€‚
-  notice_account_activated: æ‚¨çš„å¸³è™Ÿå·²ç¶“å•Ÿç”¨ï¼Œå¯ç”¨å®ƒç™»å…¥ç³»çµ±ã€‚
-  notice_successful_create: å»ºç«‹æˆåŠŸ
-  notice_successful_update: æ›´æ–°æˆåŠŸ
-  notice_successful_delete: åˆªé™¤æˆåŠŸ
-  notice_successful_connection: é€£ç·šæˆåŠŸ
-  notice_file_not_found: æ‚¨æƒ³è¦å­˜å–çš„é é¢å·²ç¶“ä¸å­˜åœ¨æˆ–è¢«æ¬ç§»è‡³å…¶ä»–ä½ç½®ã€‚
-  notice_locking_conflict: è³‡æ–™å·²è¢«å…¶ä»–ä½¿ç”¨è€…æ›´æ–°ã€‚
-  notice_not_authorized: ä½ æœªè¢«æŽˆæ¬Šå­˜å–æ­¤é é¢ã€‚
-  notice_not_authorized_archived_project: æ‚¨æ¬²å­˜å–çš„å°ˆæ¡ˆå·²ç¶“è¢«æ­¸æª”å°å­˜ã€‚
-  notice_email_sent: "éƒµä»¶å·²ç¶“æˆåŠŸå¯„é€è‡³ä»¥ä¸‹æ”¶ä»¶è€…ï¼š %{value}"
-  notice_email_error: "å¯„é€éƒµä»¶çš„éŽç¨‹ä¸­ç™¼ç”ŸéŒ¯èª¤ (%{value})"
-  notice_feeds_access_key_reseted: æ‚¨çš„ RSS å­˜å–é‡‘é‘°å·²è¢«é‡æ–°è¨­å®šã€‚
-  notice_api_access_key_reseted: æ‚¨çš„ API å­˜å–é‡‘é‘°å·²è¢«é‡æ–°è¨­å®šã€‚
-  notice_failed_to_save_issues: " %{count} å€‹å•é¡Œå„²å­˜å¤±æ•—ï¼ˆç¸½å…±é¸å– %{total} å€‹å•é¡Œï¼‰ï¼š %{ids} ã€‚"
-  notice_failed_to_save_members: "æˆå“¡å„²å­˜å¤±æ•—: %{errors}."
-  notice_no_issue_selected: "æœªé¸æ“‡ä»»ä½•å•é¡Œï¼è«‹å‹¾é¸æ‚¨æƒ³è¦ç·¨è¼¯çš„å•é¡Œã€‚"
-  notice_account_pending: "æ‚¨çš„å¸³è™Ÿå·²ç¶“å»ºç«‹ï¼Œæ­£åœ¨ç­‰å¾…ç®¡ç†å“¡çš„å¯©æ ¸ã€‚"
-  notice_default_data_loaded: é è¨­çµ„æ…‹å·²è¼‰å…¥æˆåŠŸã€‚
-  notice_unable_delete_version: ç„¡æ³•åˆªé™¤ç‰ˆæœ¬ã€‚
-  notice_unable_delete_time_entry: ç„¡æ³•åˆªé™¤å·¥æ™‚è¨˜éŒ„é …ç›®ã€‚
-  notice_issue_done_ratios_updated: å•é¡Œå®Œæˆç™¾åˆ†æ¯”å·²æ›´æ–°ã€‚
-  notice_gantt_chart_truncated: "ç”±æ–¼é …ç›®æ•¸é‡è¶…éŽå¯é¡¯ç¤ºæ•¸é‡çš„æœ€å¤§å€¼ (%{max})ï¼Œæ•…æ­¤ç”˜ç‰¹åœ–å°¾éƒ¨å·²è¢«æˆªæ–·"
-  notice_issue_successful_create: "å•é¡Œ %{id} å·²å»ºç«‹ã€‚"
-
-  error_can_t_load_default_data: "ç„¡æ³•è¼‰å…¥é è¨­çµ„æ…‹ï¼š %{value}"
-  error_scm_not_found: "åœ¨å„²å­˜æ©Ÿåˆ¶ä¸­æ‰¾ä¸åˆ°é€™å€‹é …ç›®æˆ–ä¿®è¨‚ç‰ˆã€‚"
-  error_scm_command_failed: "å˜—è©¦å­˜å–å„²å­˜æ©Ÿåˆ¶æ™‚ç™¼ç”ŸéŒ¯èª¤ï¼š %{value}"
-  error_scm_annotate: "é …ç›®ä¸å­˜åœ¨æˆ–é …ç›®ç„¡æ³•è¢«åŠ ä¸Šé™„è¨»ã€‚"
-  error_scm_annotate_big_text_file: æ­¤é …ç›®ç„¡æ³•è¢«æ¨™è¨»ï¼Œå› ç‚ºå®ƒå·²ç¶“è¶…éŽæœ€å¤§çš„æ–‡å­—æª”å¤§å°ã€‚
-  error_issue_not_found_in_project: 'è©²å•é¡Œä¸å­˜åœ¨æˆ–ä¸å±¬æ–¼æ­¤å°ˆæ¡ˆ'
-  error_no_tracker_in_project: 'æ­¤å°ˆæ¡ˆå°šæœªæŒ‡å®šè¿½è¹¤æ¨™ç±¤ã€‚è«‹æª¢æŸ¥å°ˆæ¡ˆçš„è¨­å®šè³‡è¨Šã€‚'
-  error_no_default_issue_status: 'å°šæœªå®šç¾©å•é¡Œç‹€æ…‹çš„é è¨­å€¼ã€‚è«‹æ‚¨å‰å¾€ã€Œç¶²ç«™ç®¡ç†ã€->ã€Œå•é¡Œç‹€æ…‹æ¸…å–®ã€é é¢ï¼Œæª¢æŸ¥ç›¸é—œçµ„æ…‹è¨­å®šã€‚'
-  error_can_not_delete_custom_field: ç„¡æ³•åˆªé™¤è‡ªè¨‚æ¬„ä½
-  error_can_not_delete_tracker: "æ­¤è¿½è¹¤æ¨™ç±¤å·²åŒ…å«å•é¡Œï¼Œç„¡æ³•è¢«åˆªé™¤ã€‚"
-  error_can_not_remove_role: "æ­¤è§’è‰²å·²è¢«ä½¿ç”¨ï¼Œç„¡æ³•å°‡å…¶åˆªé™¤ã€‚"
-  error_can_not_reopen_issue_on_closed_version: 'æŒ‡æ´¾çµ¦ã€Œå·²çµæŸã€ç‰ˆæœ¬çš„å•é¡Œï¼Œç„¡æ³•å†å°‡å…¶ç‹€æ…‹è®Šæ›´ç‚ºã€Œé€²è¡Œä¸­ã€'
-  error_can_not_archive_project: æ­¤å°ˆæ¡ˆç„¡æ³•è¢«æ­¸æª”
-  error_issue_done_ratios_not_updated: "å•é¡Œå®Œæˆç™¾åˆ†æ¯”æœªæ›´æ–°ã€‚"
-  error_workflow_copy_source: 'è«‹é¸æ“‡ä¸€å€‹ä¾†æºå•é¡Œè¿½è¹¤æ¨™ç±¤æˆ–è§’è‰²'
-  error_workflow_copy_target: 'è«‹é¸æ“‡ä¸€å€‹ï¼ˆæˆ–å¤šå€‹ï¼‰ç›®çš„å•é¡Œè¿½è¹¤æ¨™ç±¤æˆ–è§’è‰²'
-  error_unable_delete_issue_status: 'ç„¡æ³•åˆªé™¤å•é¡Œç‹€æ…‹'
-  error_unable_to_connect: "ç„¡æ³•é€£ç·šè‡³ï¼ˆ%{value}ï¼‰"
-  error_attachment_too_big: "é€™å€‹æª”æ¡ˆç„¡æ³•è¢«ä¸Šå‚³ï¼Œå› ç‚ºå®ƒå·²ç¶“è¶…éŽæœ€å¤§çš„æª”æ¡ˆå¤§å° (%{max_size})"
-  warning_attachments_not_saved: "%{count} å€‹é™„åŠ æª”æ¡ˆç„¡æ³•è¢«å„²å­˜ã€‚"
-
-  mail_subject_lost_password: æ‚¨çš„ Redmine ç¶²ç«™å¯†ç¢¼
-  mail_body_lost_password: 'æ¬²è®Šæ›´æ‚¨çš„ Redmine ç¶²ç«™å¯†ç¢¼, è«‹é»žé¸ä»¥ä¸‹éˆçµ:'
-  mail_subject_register: å•Ÿç”¨æ‚¨çš„ Redmine å¸³è™Ÿ
-  mail_body_register: 'æ¬²å•Ÿç”¨æ‚¨çš„ Redmine å¸³è™Ÿ, è«‹é»žé¸ä»¥ä¸‹éˆçµ:'
-  mail_body_account_information_external: "æ‚¨å¯ä»¥ä½¿ç”¨ %{value} å¸³è™Ÿç™»å…¥ Redmine ç¶²ç«™ã€‚"
-  mail_body_account_information: æ‚¨çš„ Redmine å¸³è™Ÿè³‡è¨Š
-  mail_subject_account_activation_request: Redmine å¸³è™Ÿå•Ÿç”¨éœ€æ±‚é€šçŸ¥
-  mail_body_account_activation_request: "æœ‰ä½æ–°ç”¨æˆ¶ (%{value}) å·²ç¶“å®Œæˆè¨»å†Šï¼Œæ­£ç­‰å€™æ‚¨çš„å¯©æ ¸ï¼š"
-  mail_subject_reminder: "æ‚¨æœ‰ %{count} å€‹å•é¡Œå³å°‡åˆ°æœŸ (%{days})"
-  mail_body_reminder: "%{count} å€‹æŒ‡æ´¾çµ¦æ‚¨çš„å•é¡Œï¼Œå°‡æ–¼ %{days} å¤©ä¹‹å…§åˆ°æœŸï¼š"
-  mail_subject_wiki_content_added: "'%{id}' wiki é é¢å·²è¢«æ–°å¢ž"
-  mail_body_wiki_content_added: "æ­¤ '%{id}' wiki é é¢å·²è¢« %{author} æ–°å¢žã€‚"
-  mail_subject_wiki_content_updated: "'%{id}' wiki é é¢å·²è¢«æ›´æ–°"
-  mail_body_wiki_content_updated: "æ­¤ '%{id}' wiki é é¢å·²è¢« %{author} æ›´æ–°ã€‚"
-
-  gui_validation_error: 1 å€‹éŒ¯èª¤
-  gui_validation_error_plural: "%{count} å€‹éŒ¯èª¤"
-
-  field_name: åç¨±
-  field_description: æ¦‚è¿°
-  field_summary: æ‘˜è¦
-  field_is_required: å¿…å¡«
-  field_firstname: åå­—
-  field_lastname: å§“æ°
-  field_mail: é›»å­éƒµä»¶
-  field_filename: æª”æ¡ˆåç¨±
-  field_filesize: å¤§å°
-  field_downloads: ä¸‹è¼‰æ¬¡æ•¸
-  field_author: ä½œè€…
-  field_created_on: å»ºç«‹æ—¥æœŸ
-  field_updated_on: æ›´æ–°
-  field_field_format: æ ¼å¼
-  field_is_for_all: çµ¦å…¨éƒ¨çš„å°ˆæ¡ˆ
-  field_possible_values: å¯èƒ½å€¼
-  field_regexp: æ­£è¦è¡¨ç¤ºå¼
-  field_min_length: æœ€å°é•·åº¦
-  field_max_length: æœ€å¤§é•·åº¦
-  field_value: å€¼
-  field_category: åˆ†é¡ž
-  field_title: æ¨™é¡Œ
-  field_project: å°ˆæ¡ˆ
-  field_issue: å•é¡Œ
-  field_status: ç‹€æ…‹
-  field_notes: ç­†è¨˜
-  field_is_closed: å•é¡Œå·²çµæŸ
-  field_is_default: é è¨­å€¼
-  field_tracker: è¿½è¹¤æ¨™ç±¤
-  field_subject: ä¸»æ—¨
-  field_due_date: å®Œæˆæ—¥æœŸ
-  field_assigned_to: åˆ†æ´¾çµ¦
-  field_priority: å„ªå…ˆæ¬Š
-  field_fixed_version: ç‰ˆæœ¬
-  field_user: ç”¨æˆ¶
-  field_principal: åŽŸå‰‡
-  field_role: è§’è‰²
-  field_homepage: ç¶²ç«™é¦–é 
-  field_is_public: å…¬é–‹
-  field_parent: çˆ¶å°ˆæ¡ˆ
-  field_is_in_roadmap: å•é¡Œé¡¯ç¤ºæ–¼ç‰ˆæœ¬è—åœ–ä¸­
-  field_login: å¸³æˆ¶åç¨±
-  field_mail_notification: é›»å­éƒµä»¶æé†’é¸é …
-  field_admin: ç®¡ç†è€…
-  field_last_login_on: æœ€è¿‘é€£ç·šæ—¥æœŸ
-  field_language: èªžç³»
-  field_effective_date: æ—¥æœŸ
-  field_password: ç›®å‰å¯†ç¢¼
-  field_new_password: æ–°å¯†ç¢¼
-  field_password_confirmation: ç¢ºèªæ–°å¯†ç¢¼
-  field_version: ç‰ˆæœ¬
-  field_type: Type
-  field_host: Host
-  field_port: é€£æŽ¥åŸ 
-  field_account: å¸³æˆ¶
-  field_base_dn: Base DN
-  field_attr_login: ç™»å…¥å±¬æ€§
-  field_attr_firstname: åå­—å±¬æ€§
-  field_attr_lastname: å§“æ°å±¬æ€§
-  field_attr_mail: é›»å­éƒµä»¶ä¿¡ç®±å±¬æ€§
-  field_onthefly: å³æ™‚å»ºç«‹ä½¿ç”¨è€…
-  field_start_date: é–‹å§‹æ—¥æœŸ
-  field_done_ratio: å®Œæˆç™¾åˆ†æ¯”
-  field_auth_source: èªè­‰æ¨¡å¼
-  field_hide_mail: éš±è—æˆ‘çš„é›»å­éƒµä»¶
-  field_comments: å›žæ‡‰
-  field_url: ç¶²å€
-  field_start_page: é¦–é 
-  field_subproject: å­å°ˆæ¡ˆ
-  field_hours: å°æ™‚
-  field_activity: æ´»å‹•
-  field_spent_on: æ—¥æœŸ
-  field_identifier: ä»£ç¢¼
-  field_is_filter: ç”¨ä¾†ä½œç‚ºéŽæ¿¾å™¨
-  field_issue_to: ç›¸é—œå•é¡Œ
-  field_delay: é€¾æœŸ
-  field_assignable: å•é¡Œå¯è¢«åˆ†æ´¾è‡³æ­¤è§’è‰²
-  field_redirect_existing_links: é‡æ–°å°Žå‘ç¾æœ‰é€£çµ
-  field_estimated_hours: é ä¼°å·¥æ™‚
-  field_column_names: æ¬„ä½
-  field_time_entries: è€—ç”¨å·¥æ™‚
-  field_time_zone: æ™‚å€
-  field_searchable: å¯ç”¨åšæœå°‹æ¢ä»¶
-  field_default_value: é è¨­å€¼
-  field_comments_sorting: å›žæ‡‰æŽ’åº
-  field_parent_title: çˆ¶é é¢
-  field_editable: å¯ç·¨è¼¯
-  field_watcher: è§€å¯Ÿè€…
-  field_identity_url: OpenID ç¶²å€
-  field_content: å…§å®¹
-  field_group_by: çµæžœåˆ†çµ„æ–¹å¼
-  field_sharing: å…±ç”¨
-  field_parent_issue: çˆ¶ä»»å‹™
-  field_member_of_group: "è¢«æŒ‡æ´¾è€…çš„ç¾¤çµ„"
-  field_assigned_to_role: "è¢«æŒ‡æ´¾è€…çš„è§’è‰²"
-  field_text: å…§å®¹æ–‡å­—
-  field_visible: å¯è¢«çœ‹è¦‹
-  field_warn_on_leaving_unsaved: "æé†’æˆ‘å°‡è¦é›¢é–‹çš„é é¢ä¸­å°šæœ‰æœªå„²å­˜çš„è³‡æ–™"
-  field_issues_visibility: å•é¡Œå¯è¦‹åº¦
-  field_is_private: ç§äºº
-  field_commit_logs_encoding: èªå¯è¨Šæ¯ç·¨ç¢¼
-  field_scm_path_encoding: è·¯å¾‘ç·¨ç¢¼
-  field_path_to_repository: å„²å­˜æ©Ÿåˆ¶è·¯å¾‘
-  field_root_directory: æ ¹è³‡æ–™å¤¾
-  field_cvsroot: CVSROOT
-  field_cvs_module: æ¨¡çµ„
-
-  setting_app_title: æ¨™é¡Œ
-  setting_app_subtitle: å‰¯æ¨™é¡Œ
-  setting_welcome_text: æ­¡è¿Žè©ž
-  setting_default_language: é è¨­èªžç³»
-  setting_login_required: éœ€è¦é©—è­‰
-  setting_self_registration: è¨»å†Šé¸é …
-  setting_attachment_max_size: é™„ä»¶å¤§å°é™åˆ¶
-  setting_issues_export_limit: å•é¡ŒåŒ¯å‡ºé™åˆ¶
-  setting_mail_from: å¯„ä»¶è€…é›»å­éƒµä»¶
-  setting_bcc_recipients: ä½¿ç”¨å¯†ä»¶å‰¯æœ¬ (BCC)
-  setting_plain_text_mail: ç´”æ–‡å­—éƒµä»¶ (ä¸å« HTML)
-  setting_host_name: ä¸»æ©Ÿåç¨±
-  setting_text_formatting: æ–‡å­—æ ¼å¼
-  setting_wiki_compression: å£“ç¸® Wiki æ­·å²æ–‡ç« 
-  setting_feeds_limit: RSS æ–°èžé™åˆ¶
-  setting_autofetch_changesets: è‡ªå‹•æ“·å–èªå¯
-  setting_default_projects_public: æ–°å»ºç«‹ä¹‹å°ˆæ¡ˆé è¨­ç‚ºã€Œå…¬é–‹ã€
-  setting_sys_api_enabled: å•Ÿç”¨ç®¡ç†å„²å­˜æ©Ÿåˆ¶çš„ç¶²é æœå‹™ (Web Service)
-  setting_commit_ref_keywords: èªå¯ç”¨æ–¼åƒç…§ä¹‹é—œéµå­—
-  setting_commit_fix_keywords: èªå¯ç”¨æ–¼ä¿®æ­£ä¹‹é—œéµå­—
-  setting_autologin: è‡ªå‹•ç™»å…¥
-  setting_date_format: æ—¥æœŸæ ¼å¼
-  setting_time_format: æ™‚é–“æ ¼å¼
-  setting_cross_project_issue_relations: å…è¨±é—œè¯è‡³å…¶å®ƒå°ˆæ¡ˆçš„å•é¡Œ
-  setting_issue_list_default_columns: é è¨­é¡¯ç¤ºæ–¼å•é¡Œæ¸…å–®çš„æ¬„ä½
-  setting_repositories_encodings: é™„åŠ æª”æ¡ˆèˆ‡å„²å­˜æ©Ÿåˆ¶çš„ç·¨ç¢¼
-  setting_emails_header: é›»å­éƒµä»¶å‰é ­èªªæ˜Ž
-  setting_emails_footer: é›»å­éƒµä»¶é™„å¸¶èªªæ˜Ž
-  setting_protocol: å”å®š
-  setting_per_page_options: æ¯é é¡¯ç¤ºå€‹æ•¸é¸é …
-  setting_user_format: ä½¿ç”¨è€…é¡¯ç¤ºæ ¼å¼
-  setting_activity_days_default: å°ˆæ¡ˆæ´»å‹•é¡¯ç¤ºå¤©æ•¸
-  setting_display_subprojects_issues: é è¨­æ–¼çˆ¶å°ˆæ¡ˆä¸­é¡¯ç¤ºå­å°ˆæ¡ˆçš„å•é¡Œ
-  setting_enabled_scm: å•Ÿç”¨çš„ SCM
-  setting_mail_handler_body_delimiters: "æˆªåŽ»éƒµä»¶ä¸­åŒ…å«ä¸‹åˆ—å€¼ä¹‹å¾Œçš„å…§å®¹"
-  setting_mail_handler_api_enabled: å•Ÿç”¨è™•ç†å‚³å…¥é›»å­éƒµä»¶çš„æœå‹™
-  setting_mail_handler_api_key: API é‡‘é‘°
-  setting_sequential_project_identifiers: å¾ªåºç”¢ç”Ÿå°ˆæ¡ˆè­˜åˆ¥ç¢¼
-  setting_gravatar_enabled: å•Ÿç”¨ Gravatar å…¨çƒèªè­‰å¤§é ­åƒ
-  setting_gravatar_default: é è¨­å…¨çƒèªè­‰å¤§é ­åƒåœ–ç‰‡
-  setting_diff_max_lines_displayed: å·®ç•°é¡¯ç¤ºè¡Œæ•¸ä¹‹æœ€å¤§å€¼
-  setting_file_max_size_displayed: æª”æ¡ˆå…§å®¹é¡¯ç¤ºå¤§å°ä¹‹æœ€å¤§å€¼
-  setting_repository_log_display_limit: ä¿®è¨‚ç‰ˆé¡¯ç¤ºæ•¸ç›®ä¹‹æœ€å¤§å€¼
-  setting_openid: å…è¨±ä½¿ç”¨ OpenID ç™»å…¥èˆ‡è¨»å†Š
-  setting_password_min_length: å¯†ç¢¼æœ€å°é•·åº¦
-  setting_new_project_user_role_id: ç®¡ç†è€…ä»¥å¤–ä¹‹ç”¨æˆ¶å»ºç«‹æ–°å°ˆæ¡ˆæ™‚ï¼Œå°‡è¢«æŒ‡æ´¾çš„è§’è‰²
-  setting_default_projects_modules: æ–°å°ˆæ¡ˆé è¨­å•Ÿç”¨çš„æ¨¡çµ„
-  setting_issue_done_ratio: è¨ˆç®—å•é¡Œå®Œæˆç™¾åˆ†æ¯”ä¹‹æ–¹å¼
-  setting_issue_done_ratio_issue_field: ä¾æ“šå•é¡Œå®Œæˆç™¾åˆ†æ¯”æ¬„ä½
-  setting_issue_done_ratio_issue_status: ä¾æ“šå•é¡Œç‹€æ…‹
-  setting_start_of_week: é€±çš„ç¬¬ä¸€å¤©
-  setting_rest_api_enabled: å•Ÿç”¨ REST ç¶²è·¯æœå‹™æŠ€è¡“ï¼ˆWeb Serviceï¼‰
-  setting_cache_formatted_text: å¿«å–å·²æ ¼å¼åŒ–æ–‡å­—
-  setting_default_notification_option: é è¨­é€šçŸ¥é¸é …
-  setting_commit_logtime_enabled: å•Ÿç”¨èªå¯ä¸­çš„æ™‚é–“è¨˜éŒ„
-  setting_commit_logtime_activity_id: æ™‚é–“è¨˜éŒ„å°æ‡‰çš„æ´»å‹•
-  setting_gantt_items_limit: ç”˜ç‰¹åœ–ä¸­é …ç›®é¡¯ç¤ºæ•¸é‡çš„æœ€å¤§å€¼
-  setting_issue_group_assignment: å…è¨±å•é¡Œè¢«æŒ‡æ´¾è‡³ç¾¤çµ„
-  setting_default_issue_start_date_to_creation_date: è¨­å®šæ–°å•é¡Œçš„èµ·å§‹æ—¥æœŸç‚ºä»Šå¤©çš„æ—¥æœŸ
-
-  permission_add_project: å»ºç«‹å°ˆæ¡ˆ
-  permission_add_subprojects: å»ºç«‹å­å°ˆæ¡ˆ
-  permission_edit_project: ç·¨è¼¯å°ˆæ¡ˆ
-  permission_select_project_modules: é¸æ“‡å°ˆæ¡ˆæ¨¡çµ„
-  permission_manage_members: ç®¡ç†æˆå“¡
-  permission_manage_project_activities: ç®¡ç†å°ˆæ¡ˆæ´»å‹•
-  permission_manage_versions: ç®¡ç†ç‰ˆæœ¬
-  permission_manage_categories: ç®¡ç†å•é¡Œåˆ†é¡ž
-  permission_view_issues: æª¢è¦–å•é¡Œ
-  permission_add_issues: æ–°å¢žå•é¡Œ
-  permission_edit_issues: ç·¨è¼¯å•é¡Œ
-  permission_manage_issue_relations: ç®¡ç†å•é¡Œé—œè¯
-  permission_set_issues_private: è¨­å®šå•é¡Œç‚ºå…¬é–‹æˆ–ç§äºº
-  permission_set_own_issues_private: è¨­å®šè‡ªå·±çš„å•é¡Œç‚ºå…¬é–‹æˆ–ç§äºº
-  permission_add_issue_notes: æ–°å¢žç­†è¨˜
-  permission_edit_issue_notes: ç·¨è¼¯ç­†è¨˜
-  permission_edit_own_issue_notes: ç·¨è¼¯è‡ªå·±çš„ç­†è¨˜
-  permission_move_issues: æ¬ç§»å•é¡Œ
-  permission_delete_issues: åˆªé™¤å•é¡Œ
-  permission_manage_public_queries: ç®¡ç†å…¬é–‹æŸ¥è©¢
-  permission_save_queries: å„²å­˜æŸ¥è©¢
-  permission_view_gantt: æª¢è¦–ç”˜ç‰¹åœ–
-  permission_view_calendar: æª¢è¦–æ—¥æ›†
-  permission_view_issue_watchers: æª¢è¦–ç›£çœ‹è€…æ¸…å–®
-  permission_add_issue_watchers: æ–°å¢žç›£çœ‹è€…
-  permission_delete_issue_watchers: åˆªé™¤ç›£çœ‹è€…
-  permission_log_time: ç´€éŒ„è€—ç”¨å·¥æ™‚
-  permission_view_time_entries: æª¢è¦–è€—ç”¨å·¥æ™‚
-  permission_edit_time_entries: ç·¨è¼¯å·¥æ™‚ç´€éŒ„
-  permission_edit_own_time_entries: ç·¨è¼¯è‡ªå·±çš„å·¥æ™‚è¨˜éŒ„
-  permission_manage_news: ç®¡ç†æ–°èž
-  permission_comment_news: å›žæ‡‰æ–°èž
-  permission_manage_documents: ç®¡ç†æ–‡ä»¶
-  permission_view_documents: æª¢è¦–æ–‡ä»¶
-  permission_manage_files: ç®¡ç†æª”æ¡ˆ
-  permission_view_files: æª¢è¦–æª”æ¡ˆ
-  permission_manage_wiki: ç®¡ç† wiki
-  permission_rename_wiki_pages: é‡æ–°å‘½å wiki é é¢
-  permission_delete_wiki_pages: åˆªé™¤ wiki é é¢
-  permission_view_wiki_pages: æª¢è¦– wiki
-  permission_view_wiki_edits: æª¢è¦– wiki æ­·å²
-  permission_edit_wiki_pages: ç·¨è¼¯ wiki é é¢
-  permission_delete_wiki_pages_attachments: åˆªé™¤é™„ä»¶
-  permission_protect_wiki_pages: å°ˆæ¡ˆ wiki é é¢
-  permission_manage_repository: ç®¡ç†å„²å­˜æ©Ÿåˆ¶
-  permission_browse_repository: ç€è¦½å„²å­˜æ©Ÿåˆ¶
-  permission_view_changesets: æª¢è¦–è®Šæ›´é›†
-  permission_commit_access: å­˜å–èªå¯
-  permission_manage_boards: ç®¡ç†è¨Žè«–ç‰ˆ
-  permission_view_messages: æª¢è¦–è¨Šæ¯
-  permission_add_messages: æ–°å¢žè¨Šæ¯
-  permission_edit_messages: ç·¨è¼¯è¨Šæ¯
-  permission_edit_own_messages: ç·¨è¼¯è‡ªå·±çš„è¨Šæ¯
-  permission_delete_messages: åˆªé™¤è¨Šæ¯
-  permission_delete_own_messages: åˆªé™¤è‡ªå·±çš„è¨Šæ¯
-  permission_export_wiki_pages: åŒ¯å‡º wiki é é¢
-  permission_manage_subtasks: ç®¡ç†å­ä»»å‹™
-
-  project_module_issue_tracking: å•é¡Œè¿½è¹¤
-  project_module_time_tracking: å·¥æ™‚è¿½è¹¤
-  project_module_news: æ–°èž
-  project_module_documents: æ–‡ä»¶
-  project_module_files: æª”æ¡ˆ
-  project_module_wiki: Wiki
-  project_module_repository: ç‰ˆæœ¬æŽ§ç®¡
-  project_module_boards: è¨Žè«–å€
-  project_module_calendar: æ—¥æ›†
-  project_module_gantt: ç”˜ç‰¹åœ–
-
-  label_user: ç”¨æˆ¶
-  label_user_plural: ç”¨æˆ¶æ¸…å–®
-  label_user_new: å»ºç«‹æ–°ç”¨æˆ¶
-  label_user_anonymous: åŒ¿åç”¨æˆ¶
-  label_project: å°ˆæ¡ˆ
-  label_project_new: å»ºç«‹æ–°å°ˆæ¡ˆ
-  label_project_plural: å°ˆæ¡ˆæ¸…å–®
-  label_x_projects:
-    zero:  ç„¡å°ˆæ¡ˆ
-    one:   1 å€‹å°ˆæ¡ˆ
-    other: "%{count} å€‹å°ˆæ¡ˆ"
-  label_project_all: å…¨éƒ¨çš„å°ˆæ¡ˆ
-  label_project_latest: æœ€è¿‘çš„å°ˆæ¡ˆ
-  label_issue: å•é¡Œ
-  label_issue_new: å»ºç«‹æ–°å•é¡Œ
-  label_issue_plural: å•é¡Œæ¸…å–®
-  label_issue_view_all: æª¢è¦–æ‰€æœ‰å•é¡Œ
-  label_issues_by: "å•é¡ŒæŒ‰ %{value} åˆ†çµ„é¡¯ç¤º"
-  label_issue_added: å•é¡Œå·²æ–°å¢ž
-  label_issue_updated: å•é¡Œå·²æ›´æ–°
-  label_issue_note_added: ç­†è¨˜å·²æ–°å¢ž
-  label_issue_status_updated: ç‹€æ…‹å·²æ›´æ–°
-  label_issue_priority_updated: å„ªå…ˆæ¬Šå·²æ›´æ–°
-  label_document: æ–‡ä»¶
-  label_document_new: å»ºç«‹æ–°æ–‡ä»¶
-  label_document_plural: æ–‡ä»¶
-  label_document_added: æ–‡ä»¶å·²æ–°å¢ž
-  label_role: è§’è‰²
-  label_role_plural: è§’è‰²
-  label_role_new: å»ºç«‹æ–°è§’è‰²
-  label_role_and_permissions: è§’è‰²èˆ‡æ¬Šé™
-  label_role_anonymous: åŒ¿åè€…
-  label_role_non_member: éžæœƒå“¡
-  label_member: æˆå“¡
-  label_member_new: å»ºç«‹æ–°æˆå“¡
-  label_member_plural: æˆå“¡
-  label_tracker: è¿½è¹¤æ¨™ç±¤
-  label_tracker_plural: è¿½è¹¤æ¨™ç±¤æ¸…å–®
-  label_tracker_new: å»ºç«‹æ–°çš„è¿½è¹¤æ¨™ç±¤
-  label_workflow: æµç¨‹
-  label_issue_status: å•é¡Œç‹€æ…‹
-  label_issue_status_plural: å•é¡Œç‹€æ…‹æ¸…å–®
-  label_issue_status_new: å»ºç«‹æ–°ç‹€æ…‹
-  label_issue_category: å•é¡Œåˆ†é¡ž
-  label_issue_category_plural: å•é¡Œåˆ†é¡žæ¸…å–®
-  label_issue_category_new: å»ºç«‹æ–°åˆ†é¡ž
-  label_custom_field: è‡ªè¨‚æ¬„ä½
-  label_custom_field_plural: è‡ªè¨‚æ¬„ä½æ¸…å–®
-  label_custom_field_new: å»ºç«‹æ–°è‡ªè¨‚æ¬„ä½
-  label_enumerations: åˆ—èˆ‰å€¼æ¸…å–®
-  label_enumeration_new: å»ºç«‹æ–°åˆ—èˆ‰å€¼
-  label_information: è³‡è¨Š
-  label_information_plural: è³‡è¨Š
-  label_please_login: è«‹å…ˆç™»å…¥
-  label_register: è¨»å†Š
-  label_login_with_open_id_option: æˆ–ä½¿ç”¨ OpenID ç™»å…¥
-  label_password_lost: éºå¤±å¯†ç¢¼
-  label_home: ç¶²ç«™é¦–é 
-  label_my_page: å¸³æˆ¶é¦–é 
-  label_my_account: æˆ‘çš„å¸³æˆ¶
-  label_my_projects: æˆ‘çš„å°ˆæ¡ˆ
-  label_my_page_block: å¸³æˆ¶é¦–é å€å¡Š
-  label_administration: ç¶²ç«™ç®¡ç†
-  label_login: ç™»å…¥
-  label_logout: ç™»å‡º
-  label_help: èªªæ˜Ž
-  label_reported_issues: æˆ‘é€šå ±çš„å•é¡Œ
-  label_assigned_to_me_issues: åˆ†æ´¾çµ¦æˆ‘çš„å•é¡Œ
-  label_last_login: æœ€è¿‘ä¸€æ¬¡é€£ç·š
-  label_registered_on: è¨»å†Šæ–¼
-  label_activity: æ´»å‹•
-  label_overall_activity: æ•´é«”æ´»å‹•
-  label_user_activity: "%{value} çš„æ´»å‹•"
-  label_new: å»ºç«‹æ–°çš„...
-  label_logged_as: ç›®å‰ç™»å…¥
-  label_environment: ç’°å¢ƒ
-  label_authentication: èªè­‰
-  label_auth_source: èªè­‰æ¨¡å¼
-  label_auth_source_new: å»ºç«‹æ–°èªè­‰æ¨¡å¼
-  label_auth_source_plural: èªè­‰æ¨¡å¼æ¸…å–®
-  label_subproject_plural: å­å°ˆæ¡ˆ
-  label_subproject_new: å»ºç«‹å­å°ˆæ¡ˆ
-  label_and_its_subprojects: "%{value} èˆ‡å…¶å­å°ˆæ¡ˆ"
-  label_min_max_length: æœ€å° - æœ€å¤§ é•·åº¦
-  label_list: æ¸…å–®
-  label_date: æ—¥æœŸ
-  label_integer: æ•´æ•¸
-  label_float: æµ®é»žæ•¸
-  label_boolean: å¸ƒæž—
-  label_string: æ–‡å­—
-  label_text: é•·æ–‡å­—
-  label_attribute: å±¬æ€§
-  label_attribute_plural: å±¬æ€§
-  label_download: "%{count} å€‹ä¸‹è¼‰"
-  label_download_plural: "%{count} å€‹ä¸‹è¼‰"
-  label_no_data: æ²’æœ‰ä»»ä½•è³‡æ–™å¯ä¾›é¡¯ç¤º
-  label_change_status: è®Šæ›´ç‹€æ…‹
-  label_history: æ­·å²
-  label_attachment: æª”æ¡ˆ
-  label_attachment_new: å»ºç«‹æ–°æª”æ¡ˆ
-  label_attachment_delete: åˆªé™¤æª”æ¡ˆ
-  label_attachment_plural: æª”æ¡ˆ
-  label_file_added: æª”æ¡ˆå·²æ–°å¢ž
-  label_report: å ±å‘Š
-  label_report_plural: å ±å‘Š
-  label_news: æ–°èž
-  label_news_new: å»ºç«‹æ–°èž
-  label_news_plural: æ–°èž
-  label_news_latest: æœ€è¿‘æ–°èž
-  label_news_view_all: æª¢è¦–å…¨éƒ¨çš„æ–°èž
-  label_news_added: æ–°èžå·²æ–°å¢ž
-  label_news_comment_added: å›žæ‡‰å·²åŠ å…¥æ–°èž
-  label_settings: è¨­å®š
-  label_overview: æ¦‚è§€
-  label_version: ç‰ˆæœ¬
-  label_version_new: å»ºç«‹æ–°ç‰ˆæœ¬
-  label_version_plural: ç‰ˆæœ¬
-  label_close_versions: çµæŸå·²å®Œæˆçš„ç‰ˆæœ¬
-  label_confirmation: ç¢ºèª
-  label_export_to: åŒ¯å‡ºè‡³
-  label_read: è®€å–...
-  label_public_projects: å…¬é–‹å°ˆæ¡ˆ
-  label_open_issues: é€²è¡Œä¸­
-  label_open_issues_plural: é€²è¡Œä¸­
-  label_closed_issues: å·²çµæŸ
-  label_closed_issues_plural: å·²çµæŸ
-  label_x_open_issues_abbr_on_total:
-    zero:  0 é€²è¡Œä¸­ / å…± %{total}
-    one:   1 é€²è¡Œä¸­ / å…± %{total}
-    other: "%{count} é€²è¡Œä¸­ / å…± %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 é€²è¡Œä¸­
-    one:   1 é€²è¡Œä¸­
-    other: "%{count} é€²è¡Œä¸­"
-  label_x_closed_issues_abbr:
-    zero:  0 å·²çµæŸ
-    one:   1 å·²çµæŸ
-    other: "%{count} å·²çµæŸ"
-  label_total: ç¸½è¨ˆ
-  label_permissions: æ¬Šé™
-  label_current_status: ç›®å‰ç‹€æ…‹
-  label_new_statuses_allowed: å¯è®Šæ›´è‡³ä»¥ä¸‹ç‹€æ…‹
-  label_all: å…¨éƒ¨
-  label_none: ç©ºå€¼
-  label_nobody: ç„¡å
-  label_next: ä¸‹ä¸€é 
-  label_previous: ä¸Šä¸€é 
-  label_used_by: Used by
-  label_details: æ˜Žç´°
-  label_add_note: åŠ å…¥ä¸€å€‹æ–°ç­†è¨˜
-  label_per_page: æ¯é 
-  label_calendar: æ—¥æ›†
-  label_months_from: å€‹æœˆ, é–‹å§‹æœˆä»½
-  label_gantt: ç”˜ç‰¹åœ–
-  label_internal: å…§éƒ¨
-  label_last_changes: "æœ€è¿‘ %{count} å€‹è®Šæ›´"
-  label_change_view_all: æª¢è¦–å…¨éƒ¨çš„è®Šæ›´
-  label_personalize_page: è‡ªè¨‚ç‰ˆé¢
-  label_comment: å›žæ‡‰
-  label_comment_plural: å›žæ‡‰
-  label_x_comments:
-    zero: ç„¡å›žæ‡‰
-    one: 1 å€‹å›žæ‡‰
-    other: "%{count} å€‹å›žæ‡‰"
-  label_comment_add: åŠ å…¥æ–°å›žæ‡‰
-  label_comment_added: æ–°å›žæ‡‰å·²åŠ å…¥
-  label_comment_delete: åˆªé™¤å›žæ‡‰
-  label_query: è‡ªè¨‚æŸ¥è©¢
-  label_query_plural: è‡ªè¨‚æŸ¥è©¢
-  label_query_new: å»ºç«‹æ–°æŸ¥è©¢
-  label_my_queries: æˆ‘çš„è‡ªè¨‚æŸ¥è©¢
-  label_filter_add: åŠ å…¥æ–°ç¯©é¸æ¢ä»¶
-  label_filter_plural: ç¯©é¸æ¢ä»¶
-  label_equals: ç­‰æ–¼
-  label_not_equals: ä¸ç­‰æ–¼
-  label_in_less_than: åœ¨å°æ–¼
-  label_in_more_than: åœ¨å¤§æ–¼
-  label_greater_or_equal: "å¤§æ–¼ç­‰æ–¼ (>=)"
-  label_less_or_equal: "å°æ–¼ç­‰æ–¼ (<=)"
-  label_between: å€é–“
-  label_in: åœ¨
-  label_today: ä»Šå¤©
-  label_all_time: å…¨éƒ¨
-  label_yesterday: æ˜¨å¤©
-  label_this_week: æœ¬é€±
-  label_last_week: ä¸Šé€±
-  label_last_n_days: "éŽåŽ» %{count} å¤©"
-  label_this_month: é€™å€‹æœˆ
-  label_last_month: ä¸Šå€‹æœˆ
-  label_this_year: ä»Šå¹´
-  label_date_range: æ—¥æœŸå€é–“
-  label_less_than_ago: å°æ–¼å¹¾å¤©ä¹‹å‰
-  label_more_than_ago: å¤§æ–¼å¹¾å¤©ä¹‹å‰
-  label_ago: å¤©ä»¥å‰
-  label_contains: åŒ…å«
-  label_not_contains: ä¸åŒ…å«
-  label_day_plural: å¤©
-  label_repository: å„²å­˜æ©Ÿåˆ¶
-  label_repository_plural: å„²å­˜æ©Ÿåˆ¶æ¸…å–®
-  label_browse: ç€è¦½
-  label_modification: "%{count} è®Šæ›´"
-  label_modification_plural: "%{count} è®Šæ›´"
-  label_branch: åˆ†æ”¯
-  label_tag: æ¨™ç±¤
-  label_revision: ä¿®è¨‚ç‰ˆ
-  label_revision_plural: ä¿®è¨‚ç‰ˆæ¸…å–®
-  label_revision_id: "ä¿®è¨‚ç‰ˆ %{value}"
-  label_associated_revisions: é—œè¯çš„ä¿®è¨‚ç‰ˆ
-  label_added: å·²æ–°å¢ž
-  label_modified: å·²ä¿®æ”¹
-  label_copied: å·²è¤‡è£½
-  label_renamed: å·²é‡æ–°å‘½å
-  label_deleted: å·²åˆªé™¤
-  label_latest_revision: æœ€æ–°çš„ä¿®è¨‚ç‰ˆ
-  label_latest_revision_plural: æœ€æ–°çš„ä¿®è¨‚ç‰ˆæ¸…å–®
-  label_view_revisions: æª¢è¦–ä¿®è¨‚ç‰ˆæ¸…å–®
-  label_view_all_revisions: æª¢è¦–æ‰€æœ‰çš„çš„ä¿®è¨‚ç‰ˆæ¸…å–®
-  label_max_size: æœ€å¤§é•·åº¦
-  label_sort_highest: ç§»å‹•è‡³é–‹é ­
-  label_sort_higher: å¾€ä¸Šç§»å‹•
-  label_sort_lower: å¾€ä¸‹ç§»å‹•
-  label_sort_lowest: ç§»å‹•è‡³çµå°¾
-  label_roadmap: ç‰ˆæœ¬è—åœ–
-  label_roadmap_due_in: "å‰©é¤˜ %{value}"
-  label_roadmap_overdue: "é€¾æœŸ %{value}"
-  label_roadmap_no_issues: æ­¤ç‰ˆæœ¬å°šæœªåŒ…å«ä»»ä½•å•é¡Œ
-  label_search: æœå°‹
-  label_result_plural: çµæžœ
-  label_all_words: åŒ…å«å…¨éƒ¨çš„å­—è©ž
-  label_wiki: Wiki
-  label_wiki_edit: Wiki ç·¨è¼¯
-  label_wiki_edit_plural: Wiki ç·¨è¼¯
-  label_wiki_page: Wiki ç¶²é 
-  label_wiki_page_plural: Wiki ç¶²é 
-  label_index_by_title: ä¾æ¨™é¡Œç´¢å¼•
-  label_index_by_date: ä¾æ—¥æœŸç´¢å¼•
-  label_current_version: ç¾è¡Œç‰ˆæœ¬
-  label_preview: é è¦½
-  label_feed_plural: Feeds
-  label_changes_details: æ‰€æœ‰è®Šæ›´çš„æ˜Žç´°
-  label_issue_tracking: å•é¡Œè¿½è¹¤
-  label_spent_time: è€—ç”¨å·¥æ™‚
-  label_overall_spent_time: æ•´é«”è€—ç”¨å·¥æ™‚
-  label_f_hour: "%{value} å°æ™‚"
-  label_f_hour_plural: "%{value} å°æ™‚"
-  label_time_tracking: å·¥æ™‚è¿½è¹¤
-  label_change_plural: è®Šæ›´
-  label_statistics: çµ±è¨ˆè³‡è¨Š
-  label_commits_per_month: ä¾æœˆä»½çµ±è¨ˆèªå¯
-  label_commits_per_author: ä¾ä½œè€…çµ±è¨ˆèªå¯
-  label_view_diff: æª¢è¦–å·®ç•°
-  label_diff: å·®ç•°
-  label_diff_inline: ç›´åˆ—
-  label_diff_side_by_side: ä¸¦æŽ’
-  label_options: é¸é …æ¸…å–®
-  label_copy_workflow_from: å¾žä»¥ä¸‹è¿½è¹¤æ¨™ç±¤è¤‡è£½å·¥ä½œæµç¨‹
-  label_permissions_report: æ¬Šé™å ±è¡¨
-  label_watched_issues: ç›£çœ‹ä¸­çš„å•é¡Œæ¸…å–®
-  label_related_issues: ç›¸é—œçš„å•é¡Œæ¸…å–®
-  label_applied_status: å·²å¥—ç”¨ç‹€æ…‹
-  label_loading: è¼‰å…¥ä¸­...
-  label_relation_new: å»ºç«‹æ–°é—œè¯
-  label_relation_delete: åˆªé™¤é—œè¯
-  label_relates_to: é—œè¯è‡³
-  label_duplicates: å·²é‡è¤‡
-  label_duplicated_by: èˆ‡å¾Œé¢æ‰€åˆ—å•é¡Œé‡è¤‡
-  label_blocks: é˜»æ“‹
-  label_blocked_by: è¢«é˜»æ“‹
-  label_precedes: å„ªå…ˆæ–¼
-  label_follows: è·Ÿéš¨æ–¼
-  label_end_to_start: çµæŸâ”€é–‹å§‹
-  label_end_to_end: çµæŸâ”€çµæŸ
-  label_start_to_start: é–‹å§‹â”€é–‹å§‹
-  label_start_to_end: é–‹å§‹â”€çµæŸ
-  label_stay_logged_in: ç¶­æŒå·²ç™»å…¥ç‹€æ…‹
-  label_disabled: é—œé–‰
-  label_show_completed_versions: é¡¯ç¤ºå·²å®Œæˆçš„ç‰ˆæœ¬
-  label_me: æˆ‘è‡ªå·±
-  label_board: è«–å£‡
-  label_board_new: å»ºç«‹æ–°è«–å£‡
-  label_board_plural: è«–å£‡
-  label_board_locked: éŽ–å®š
-  label_board_sticky: ç½®é ‚
-  label_topic_plural: è¨Žè«–ä¸»é¡Œ
-  label_message_plural: è¨Šæ¯
-  label_message_last: ä¸Šä¸€å°è¨Šæ¯
-  label_message_new: å»ºç«‹æ–°è¨Šæ¯
-  label_message_posted: è¨Šæ¯å·²æ–°å¢ž
-  label_reply_plural: å›žæ‡‰
-  label_send_information: å¯„é€å¸³æˆ¶è³‡è¨Šé›»å­éƒµä»¶çµ¦ç”¨æˆ¶
-  label_year: å¹´
-  label_month: æœˆ
-  label_week: é€±
-  label_date_from: é–‹å§‹
-  label_date_to: çµæŸ
-  label_language_based: ä¾ç”¨æˆ¶ä¹‹èªžç³»æ±ºå®š
-  label_sort_by: "æŒ‰ %{value} æŽ’åº"
-  label_send_test_email: å¯„é€æ¸¬è©¦éƒµä»¶
-  label_feeds_access_key: RSS å­˜å–é‡‘é‘°
-  label_missing_feeds_access_key: æ‰¾ä¸åˆ° RSS å­˜å–é‡‘é‘°
-  label_feeds_access_key_created_on: "RSS å­˜å–éµå»ºç«‹æ–¼ %{value} ä¹‹å‰"
-  label_module_plural: æ¨¡çµ„
-  label_added_time_by: "æ˜¯ç”± %{author} æ–¼ %{age} å‰åŠ å…¥"
-  label_updated_time_by: "æ˜¯ç”± %{author} æ–¼ %{age} å‰æ›´æ–°"
-  label_updated_time: "æ–¼ %{value} å‰æ›´æ–°"
-  label_jump_to_a_project: é¸æ“‡æ¬²å‰å¾€çš„å°ˆæ¡ˆ...
-  label_file_plural: æª”æ¡ˆæ¸…å–®
-  label_changeset_plural: è®Šæ›´é›†æ¸…å–®
-  label_default_columns: é è¨­æ¬„ä½æ¸…å–®
-  label_no_change_option: (ç¶­æŒä¸è®Š)
-  label_bulk_edit_selected_issues: å¤§é‡ç·¨è¼¯é¸å–çš„å•é¡Œ
-  label_bulk_edit_selected_time_entries: å¤§é‡ç·¨è¼¯é¸å–çš„å·¥æ™‚é …ç›®
-  label_theme: ç•«é¢ä¸»é¡Œ
-  label_default: é è¨­
-  label_search_titles_only: åƒ…æœå°‹æ¨™é¡Œ
-  label_user_mail_option_all: "æé†’èˆ‡æˆ‘çš„å°ˆæ¡ˆæœ‰é—œçš„å…¨éƒ¨äº‹ä»¶"
-  label_user_mail_option_selected: "åªæé†’æˆ‘æ‰€é¸æ“‡å°ˆæ¡ˆä¸­çš„äº‹ä»¶..."
-  label_user_mail_option_none: "å–æ¶ˆæé†’"
-  label_user_mail_option_only_my_events: "åªæé†’æˆ‘è§€å¯Ÿä¸­æˆ–åƒèˆ‡ä¸­çš„äº‹ç‰©"
-  label_user_mail_option_only_assigned: "åªæé†’æˆ‘è¢«æŒ‡æ´¾çš„äº‹ç‰©"
-  label_user_mail_option_only_owner: "åªæé†’æˆ‘ä½œç‚ºæ“æœ‰è€…çš„äº‹ç‰©"
-  label_user_mail_no_self_notified: "ä¸æé†’æˆ‘è‡ªå·±æ‰€åšçš„è®Šæ›´"
-  label_registration_activation_by_email: é€éŽé›»å­éƒµä»¶å•Ÿç”¨å¸³æˆ¶
-  label_registration_manual_activation: æ‰‹å‹•å•Ÿç”¨å¸³æˆ¶
-  label_registration_automatic_activation: è‡ªå‹•å•Ÿç”¨å¸³æˆ¶
-  label_display_per_page: "æ¯é é¡¯ç¤º: %{value} å€‹"
-  label_age: å¹´é½¡
-  label_change_properties: è®Šæ›´å±¬æ€§
-  label_general: ä¸€èˆ¬
-  label_more: æ›´å¤š Â»
-  label_scm: ç‰ˆæœ¬æŽ§ç®¡
-  label_plugins: é™„åŠ å…ƒä»¶
-  label_ldap_authentication: LDAP èªè­‰
-  label_downloads_abbr: ä¸‹è¼‰
-  label_optional_description: é¡å¤–çš„èªªæ˜Ž
-  label_add_another_file: å¢žåŠ å…¶ä»–æª”æ¡ˆ
-  label_preferences: åå¥½é¸é …
-  label_chronological_order: ä»¥æ™‚é–“ç”±é è‡³è¿‘æŽ’åº
-  label_reverse_chronological_order: ä»¥æ™‚é–“ç”±è¿‘è‡³é æŽ’åº
-  label_planning: è¨ˆåŠƒè¡¨
-  label_incoming_emails: å‚³å…¥çš„é›»å­éƒµä»¶
-  label_generate_key: ç”¢ç”Ÿé‡‘é‘°
-  label_issue_watchers: ç›£çœ‹è€…
-  label_example: ç¯„ä¾‹
-  label_display: é¡¯ç¤º
-  label_sort: æŽ’åº
-  label_ascending: éžå¢žæŽ’åº
-  label_descending: éžæ¸›æŽ’åº
-  label_date_from_to: èµ· %{start} è¿„ %{end}
-  label_wiki_content_added: Wiki é é¢å·²æ–°å¢ž
-  label_wiki_content_updated: Wiki é é¢å·²æ›´æ–°
-  label_group: ç¾¤çµ„
-  label_group_plural: ç¾¤çµ„æ¸…å–®
-  label_group_new: å»ºç«‹æ–°ç¾¤çµ„
-  label_time_entry_plural: è€—ç”¨å·¥æ™‚
-  label_version_sharing_none: ä¸å…±ç”¨
-  label_version_sharing_descendants: èˆ‡å­å°ˆæ¡ˆå…±ç”¨
-  label_version_sharing_hierarchy: èˆ‡å°ˆæ¡ˆéšŽå±¤æž¶æ§‹å…±ç”¨
-  label_version_sharing_tree: èˆ‡å°ˆæ¡ˆæ¨¹å…±ç”¨
-  label_version_sharing_system: èˆ‡å…¨éƒ¨çš„å°ˆæ¡ˆå…±ç”¨
-  label_update_issue_done_ratios: æ›´æ–°å•é¡Œå®Œæˆç™¾åˆ†æ¯”
-  label_copy_source: ä¾†æº
-  label_copy_target: ç›®çš„åœ°
-  label_copy_same_as_target: èˆ‡ç›®çš„åœ°ç›¸åŒ
-  label_display_used_statuses_only: åƒ…é¡¯ç¤ºæ­¤è¿½è¹¤æ¨™ç±¤æ‰€ä½¿ç”¨ä¹‹ç‹€æ…‹
-  label_api_access_key: API å­˜å–é‡‘é‘°
-  label_missing_api_access_key: æ‰¾ä¸åˆ° API å­˜å–é‡‘é‘°
-  label_api_access_key_created_on: "API å­˜å–é‡‘é‘°å»ºç«‹æ–¼ %{value} ä¹‹å‰"
-  label_profile: é…ç½®æ¦‚æ³
-  label_subtask_plural: å­ä»»å‹™
-  label_project_copy_notifications: åœ¨è¤‡è£½å°ˆæ¡ˆçš„éŽç¨‹ä¸­ï¼Œå‚³é€é€šçŸ¥éƒµä»¶
-  label_principal_search: "æœå°‹ç”¨æˆ¶æˆ–ç¾¤çµ„ï¼š"
-  label_user_search: "æœå°‹ç”¨æˆ¶ï¼š"
-  label_additional_workflow_transitions_for_author: ç”¨æˆ¶ç‚ºä½œè€…æ™‚é¡å¤–å…è¨±çš„æµç¨‹è½‰æ›
-  label_additional_workflow_transitions_for_assignee: ç”¨æˆ¶ç‚ºè¢«æŒ‡å®šè€…æ™‚é¡å¤–å…è¨±çš„æµç¨‹è½‰æ›
-  label_issues_visibility_all: æ‰€æœ‰å•é¡Œ
-  label_issues_visibility_public: æ‰€æœ‰éžç§äººå•é¡Œ
-  label_issues_visibility_own: ä½¿ç”¨è€…æ‰€å»ºç«‹çš„æˆ–è¢«æŒ‡æ´¾çš„å•é¡Œ
-  label_git_report_last_commit: å ±å‘Šæœ€å¾Œèªå¯çš„æ–‡ä»¶å’Œç›®éŒ„
-  label_parent_revision: çˆ¶é …
-  label_child_revision: å­é …
-  label_export_options: %{export_format} åŒ¯å‡ºé¸é …
-
-  button_login: ç™»å…¥
-  button_submit: é€å‡º
-  button_save: å„²å­˜
-  button_check_all: å…¨é¸
-  button_uncheck_all: å…¨ä¸é¸
-  button_collapse_all: å…¨éƒ¨æ‘ºç–Š
-  button_expand_all: å…¨éƒ¨å±•é–‹
-  button_delete: åˆªé™¤
-  button_create: å»ºç«‹
-  button_create_and_continue: ç¹¼çºŒå»ºç«‹
-  button_test: æ¸¬è©¦
-  button_edit: ç·¨è¼¯
-  button_edit_associated_wikipage: "ç·¨è¼¯ç›¸é—œ Wiki é é¢: %{page_title}"
-  button_add: æ–°å¢ž
-  button_change: ä¿®æ”¹
-  button_apply: å¥—ç”¨
-  button_clear: æ¸…é™¤
-  button_lock: éŽ–å®š
-  button_unlock: è§£é™¤éŽ–å®š
-  button_download: ä¸‹è¼‰
-  button_list: æ¸…å–®
-  button_view: æª¢è¦–
-  button_move: ç§»å‹•
-  button_move_and_follow: ç§»å‹•å¾Œè·Ÿéš¨
-  button_back: è¿”å›ž
-  button_cancel: å–æ¶ˆ
-  button_activate: å•Ÿç”¨
-  button_sort: æŽ’åº
-  button_log_time: è¨˜éŒ„æ™‚é–“
-  button_rollback: é‚„åŽŸè‡³æ­¤ç‰ˆæœ¬
-  button_watch: è§€å¯Ÿ
-  button_unwatch: å–æ¶ˆè§€å¯Ÿ
-  button_reply: å›žæ‡‰
-  button_archive: æ­¸æª”
-  button_unarchive: å–æ¶ˆæ­¸æª”
-  button_reset: å›žå¾©
-  button_rename: é‡æ–°å‘½å
-  button_change_password: è®Šæ›´å¯†ç¢¼
-  button_copy: è¤‡è£½
-  button_copy_and_follow: è¤‡è£½å¾Œè·Ÿéš¨
-  button_annotate: è¨»è§£
-  button_update: æ›´æ–°
-  button_configure: è¨­å®š
-  button_quote: å¼•ç”¨
-  button_duplicate: é‡è£½
-  button_show: é¡¯ç¤º
-  button_edit_section: ç·¨è¼¯æ­¤å€å¡Š
-  button_export: åŒ¯å‡º
-
-  status_active: æ´»å‹•ä¸­
-  status_registered: è¨»å†Šå®Œæˆ
-  status_locked: éŽ–å®šä¸­
-
-  version_status_open: é€²è¡Œä¸­
-  version_status_locked: å·²éŽ–å®š
-  version_status_closed: å·²çµæŸ
-
-  field_active: æ´»å‹•ä¸­
-
-  text_select_mail_notifications: é¸æ“‡æ¬²å¯„é€æé†’é€šçŸ¥éƒµä»¶ä¹‹å‹•ä½œ
-  text_regexp_info: eg. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 ä»£è¡¨ã€Œä¸é™åˆ¶ã€
-  text_project_destroy_confirmation: æ‚¨ç¢ºå®šè¦åˆªé™¤é€™å€‹å°ˆæ¡ˆå’Œå…¶ä»–ç›¸é—œè³‡æ–™ï¼Ÿ
-  text_subprojects_destroy_warning: "ä¸‹åˆ—å­å°ˆæ¡ˆï¼š %{value} å°‡ä¸€ä½µè¢«åˆªé™¤ã€‚"
-  text_workflow_edit: é¸æ“‡è§’è‰²èˆ‡è¿½è¹¤æ¨™ç±¤ä»¥è¨­å®šå…¶å·¥ä½œæµç¨‹
-  text_are_you_sure: ç¢ºå®šåŸ·è¡Œï¼Ÿ
-  text_are_you_sure_with_children: "ç¢ºå®šåˆªé™¤æ­¤å•é¡ŒåŠå…¶å­å•é¡Œï¼Ÿ"
-  text_journal_changed: "%{label} å¾ž %{old} è®Šæ›´ç‚º %{new}"
-  text_journal_changed_no_detail: "%{label} å·²æ›´æ–°"
-  text_journal_set_to: "%{label} è¨­å®šç‚º %{value}"
-  text_journal_deleted: "%{label} å·²åˆªé™¤ (%{old})"
-  text_journal_added: "%{label} %{value} å·²æ–°å¢ž"
-  text_tip_issue_begin_day: ä»Šå¤©èµ·å§‹çš„å•é¡Œ
-  text_tip_issue_end_day: ä»Šå¤©æˆªæ­¢çš„çš„å•é¡Œ
-  text_tip_issue_begin_end_day: ä»Šå¤©èµ·å§‹èˆ‡æˆªæ­¢çš„å•é¡Œ
-  text_project_identifier_info: 'åªå…è¨±å°å¯«è‹±æ–‡å­—æ¯ï¼ˆa-zï¼‰ã€é˜¿æ‹‰ä¼¯æ•¸å­—èˆ‡é€£å­—ç¬¦è™Ÿï¼ˆ-ï¼‰ã€‚<br />å„²å­˜å¾Œï¼Œä»£ç¢¼ä¸å¯å†è¢«æ›´æ”¹ã€‚'
-  text_caracters_maximum: "æœ€å¤š %{count} å€‹å­—å…ƒ."
-  text_caracters_minimum: "é•·åº¦å¿…é ˆå¤§æ–¼ %{count} å€‹å­—å…ƒ."
-  text_length_between: "é•·åº¦å¿…é ˆä»‹æ–¼ %{min} è‡³ %{max} å€‹å­—å…ƒä¹‹é–“."
-  text_tracker_no_workflow: æ­¤è¿½è¹¤æ¨™ç±¤å°šæœªå®šç¾©å·¥ä½œæµç¨‹
-  text_unallowed_characters: ä¸å…è¨±çš„å­—å…ƒ
-  text_comma_separated: å¯è¼¸å…¥å¤šå€‹å€¼ï¼ˆé ˆä»¥é€—è™Ÿåˆ†éš”ï¼‰ã€‚
-  text_line_separated: å¯è¼¸å…¥å¤šå€‹å€¼ï¼ˆé ˆä»¥æ›è¡Œç¬¦è™Ÿåˆ†éš”ï¼Œå³æ¯åˆ—åªèƒ½è¼¸å…¥ä¸€å€‹å€¼ï¼‰ã€‚
-  text_issues_ref_in_commit_messages: èªå¯è¨Šæ¯ä¸­åƒç…§(æˆ–ä¿®æ­£)å•é¡Œä¹‹é—œéµå­—
-  text_issue_added: "å•é¡Œ %{id} å·²è¢« %{author} é€šå ±ã€‚"
-  text_issue_updated: "å•é¡Œ %{id} å·²è¢« %{author} æ›´æ–°ã€‚"
-  text_wiki_destroy_confirmation: æ‚¨ç¢ºå®šè¦åˆªé™¤é€™å€‹ wiki å’Œå…¶ä¸­çš„æ‰€æœ‰å…§å®¹ï¼Ÿ
-  text_issue_category_destroy_question: "æœ‰ (%{count}) å€‹å•é¡Œè¢«æŒ‡æ´¾åˆ°æ­¤åˆ†é¡ž. è«‹é¸æ“‡æ‚¨æƒ³è¦çš„å‹•ä½œï¼Ÿ"
-  text_issue_category_destroy_assignments: ç§»é™¤é€™äº›å•é¡Œçš„åˆ†é¡ž
-  text_issue_category_reassign_to: é‡æ–°æŒ‡æ´¾é€™äº›å•é¡Œè‡³å…¶å®ƒåˆ†é¡ž
-  text_user_mail_option: "å°æ–¼é‚£äº›æœªè¢«é¸æ“‡çš„å°ˆæ¡ˆï¼Œå°‡åªæœƒæŽ¥æ”¶åˆ°æ‚¨æ­£åœ¨è§€å¯Ÿä¸­ï¼Œæˆ–æ˜¯åƒèˆ‡ä¸­çš„å•é¡Œé€šçŸ¥ã€‚ï¼ˆã€Œåƒèˆ‡ä¸­çš„å•é¡Œã€åŒ…å«æ‚¨å»ºç«‹çš„æˆ–æ˜¯æŒ‡æ´¾çµ¦æ‚¨çš„å•é¡Œï¼‰"
-  text_no_configuration_data: "è§’è‰²ã€è¿½è¹¤æ¨™ç±¤ã€å•é¡Œç‹€æ…‹èˆ‡æµç¨‹å°šæœªè¢«è¨­å®šå®Œæˆã€‚\nå¼·çƒˆå»ºè­°æ‚¨å…ˆè¼‰å…¥é è¨­çš„çµ„æ…‹ã€‚å°‡é è¨­çµ„æ…‹è¼‰å…¥ä¹‹å¾Œï¼Œæ‚¨å¯å†è®Šæ›´å…¶ä¸­ä¹‹å€¼ã€‚"
-  text_load_default_configuration: è¼‰å…¥é è¨­çµ„æ…‹
-  text_status_changed_by_changeset: "å·²å¥—ç”¨è‡³è®Šæ›´é›† %{value}."
-  text_time_logged_by_changeset: "ç´€éŒ„æ–¼è®Šæ›´é›† %{value}."
-  text_issues_destroy_confirmation: 'ç¢ºå®šåˆªé™¤å·²é¸æ“‡çš„å•é¡Œï¼Ÿ'
-  text_issues_destroy_descendants_confirmation: "é€™éº¼åšå°‡æœƒä¸€ä½µåˆªé™¤ %{count} å­ä»»å‹™ã€‚"
-  text_time_entries_destroy_confirmation: æ‚¨ç¢ºå®šè¦åˆªé™¤æ‰€é¸æ“‡çš„å·¥æ™‚ç´€éŒ„ï¼Ÿ
-  text_select_project_modules: 'é¸æ“‡æ­¤å°ˆæ¡ˆå¯ä½¿ç”¨ä¹‹æ¨¡çµ„ï¼š'
-  text_default_administrator_account_changed: å·²è®Šæ›´é è¨­ç®¡ç†å“¡å¸³è™Ÿå…§å®¹
-  text_file_repository_writable: å¯å¯«å…¥é™„åŠ æª”æ¡ˆç›®éŒ„
-  text_plugin_assets_writable: å¯å¯«å…¥é™„åŠ å…ƒä»¶ç›®éŒ„
-  text_rmagick_available: å¯ä½¿ç”¨ RMagick (é¸é…)
-  text_destroy_time_entries_question: æ‚¨å³å°‡åˆªé™¤çš„å•é¡Œå·²å ±å·¥ %{hours} å°æ™‚. æ‚¨çš„é¸æ“‡æ˜¯ï¼Ÿ
-  text_destroy_time_entries: åˆªé™¤å·²å ±å·¥çš„æ™‚æ•¸
-  text_assign_time_entries_to_project: æŒ‡å®šå·²å ±å·¥çš„æ™‚æ•¸è‡³å°ˆæ¡ˆä¸­
-  text_reassign_time_entries: 'é‡æ–°æŒ‡å®šå·²å ±å·¥çš„æ™‚æ•¸è‡³æ­¤å•é¡Œï¼š'
-  text_user_wrote: "%{value} å…ˆå‰æåˆ°:"
-  text_enumeration_destroy_question: "ç›®å‰æœ‰ %{count} å€‹ç‰©ä»¶ä½¿ç”¨æ­¤åˆ—èˆ‰å€¼ã€‚"
-  text_enumeration_category_reassign_to: 'é‡æ–°è¨­å®šå…¶åˆ—èˆ‰å€¼ç‚ºï¼š'
-  text_email_delivery_not_configured: "æ‚¨å°šæœªè¨­å®šé›»å­éƒµä»¶å‚³é€æ–¹å¼ï¼Œå› æ­¤æé†’é¸é …å·²è¢«åœç”¨ã€‚\nè«‹åœ¨ config/configuration.yml ä¸­è¨­å®š SMTP ä¹‹å¾Œï¼Œé‡æ–°å•Ÿå‹• Redmineï¼Œä»¥å•Ÿç”¨é›»å­éƒµä»¶æé†’é¸é …ã€‚"
-  text_repository_usernames_mapping: "é¸æ“‡æˆ–æ›´æ–° Redmine ä½¿ç”¨è€…èˆ‡å„²å­˜æ©Ÿåˆ¶ç´€éŒ„ä½¿ç”¨è€…ä¹‹å°æ‡‰é—œä¿‚ã€‚\nå„²å­˜æ©Ÿåˆ¶ä¸­ä¹‹ä½¿ç”¨è€…å¸³è™Ÿæˆ–é›»å­éƒµä»¶ä¿¡ç®±ï¼Œèˆ‡ Redmine è¨­å®šç›¸åŒè€…ï¼Œå°‡è‡ªå‹•ç”¢ç”Ÿå°æ‡‰é—œä¿‚ã€‚"
-  text_diff_truncated: '... é€™ä»½å·®ç•°å·²è¢«æˆªçŸ­ä»¥ç¬¦åˆé¡¯ç¤ºè¡Œæ•¸ä¹‹æœ€å¤§å€¼'
-  text_custom_field_possible_values_info: 'ä¸€åˆ—è¼¸å…¥ä¸€å€‹å€¼'
-  text_wiki_page_destroy_question: "æ­¤é é¢åŒ…å« %{descendants} å€‹å­é é¢åŠå»¶ä¼¸é é¢ã€‚ è«‹é¸æ“‡æ‚¨æƒ³è¦çš„å‹•ä½œ?"
-  text_wiki_page_nullify_children: "ä¿ç•™æ‰€æœ‰å­é é¢ç•¶ä½œæ ¹é é¢"
-  text_wiki_page_destroy_children: "åˆªé™¤æ‰€æœ‰å­é é¢åŠå…¶å»¶ä¼¸é é¢"
-  text_wiki_page_reassign_children: "é‡æ–°æŒ‡å®šæ‰€æœ‰çš„å­é é¢ä¹‹çˆ¶é é¢è‡³æ­¤é é¢"
-  text_own_membership_delete_confirmation: "æ‚¨åœ¨å°ˆæ¡ˆä¸­ï¼Œæ‰€æ“æœ‰çš„éƒ¨åˆ†æˆ–å…¨éƒ¨æ¬Šé™å³å°‡è¢«ç§»é™¤ï¼Œåœ¨é€™ä¹‹å¾Œå¯èƒ½ç„¡æ³•å†æ¬¡ç·¨è¼¯æ­¤å°ˆæ¡ˆã€‚\næ‚¨ç¢ºå®šè¦ç¹¼çºŒåŸ·è¡Œé€™å€‹å‹•ä½œï¼Ÿ"
-  text_zoom_in: æ”¾å¤§
-  text_zoom_out: ç¸®å°
-  text_warn_on_leaving_unsaved: "è‹¥æ‚¨é›¢é–‹é€™å€‹é é¢ï¼Œæ­¤é é¢æ‰€åŒ…å«çš„æœªå„²å­˜è³‡æ–™å°‡æœƒéºå¤±ã€‚"
-  text_scm_path_encoding_note: "é è¨­: UTF-8"
-  text_git_repository_note: å„²å­˜æ©Ÿåˆ¶æ˜¯æœ¬æ©Ÿçš„ç©º(bare)ç›®éŒ„ (å³ï¼š /gitrepo, c:\gitrepo)
-  text_mercurial_repository_note: æœ¬æ©Ÿå„²å­˜æ©Ÿåˆ¶ (å³ï¼š /hgrepo, c:\hgrepo)
-  text_scm_command: å‘½ä»¤
-  text_scm_command_version: ç‰ˆæœ¬
-  text_scm_config: æ‚¨å¯ä»¥åœ¨ config/configuration.yml ä¸­è¨­å®š SCM å‘½ä»¤ã€‚è«‹åœ¨ç·¨è¼¯è©²æª”æ¡ˆä¹‹å¾Œé‡æ–°å•Ÿå‹• Redmine æ‡‰ç”¨ç¨‹å¼ã€‚
-  text_scm_command_not_available: SCM å‘½ä»¤ç„¡æ³•ä½¿ç”¨ã€‚è«‹æª¢æŸ¥ç®¡ç†é¢æ¿ä¸­çš„è¨­å®šã€‚
-
-  default_role_manager: ç®¡ç†äººå“¡
-  default_role_developer: é–‹ç™¼äººå“¡
-  default_role_reporter: å ±å‘Šäººå“¡
-  default_tracker_bug: è‡­èŸ²
-  default_tracker_feature: åŠŸèƒ½
-  default_tracker_support: æ”¯æ´
-  default_issue_status_new: æ–°å»ºç«‹
-  default_issue_status_in_progress: å¯¦ä½œä¸­
-  default_issue_status_resolved: å·²è§£æ±º
-  default_issue_status_feedback: å·²å›žæ‡‰
-  default_issue_status_closed: å·²çµæŸ
-  default_issue_status_rejected: å·²æ‹’çµ•
-  default_doc_category_user: ä½¿ç”¨æ‰‹å†Š
-  default_doc_category_tech: æŠ€è¡“æ–‡ä»¶
-  default_priority_low: ä½Ž
-  default_priority_normal: æ­£å¸¸
-  default_priority_high: é«˜
-  default_priority_urgent: é€Ÿ
-  default_priority_immediate: æ€¥
-  default_activity_design: è¨­è¨ˆ
-  default_activity_development: é–‹ç™¼
-
-  enumeration_issue_priorities: å•é¡Œå„ªå…ˆæ¬Š
-  enumeration_doc_categories: æ–‡ä»¶åˆ†é¡ž
-  enumeration_activities: æ´»å‹• (æ™‚é–“è¿½è¹¤)
-  enumeration_system_activity: ç³»çµ±æ´»å‹•
-  description_filter: ç¯©é¸æ¢ä»¶
-  description_search: æœå°‹æ¬„ä½
-  description_choose_project: å°ˆæ¡ˆæ¸…å–®
-  description_project_scope: æœå°‹ç¯„åœ
-  description_notes: ç­†è¨˜
-  description_message_content: è¨Šæ¯å…§å®¹
-  description_query_sort_criteria_attribute: æŽ’åºå±¬æ€§
-  description_query_sort_criteria_direction: æŽ’åˆ—é †åº
-  description_user_mail_notification: éƒµä»¶é€šçŸ¥è¨­å®š
-  description_available_columns: å¯ç”¨æ¬„ä½
-  description_selected_columns: å·²é¸å–çš„æ¬„ä½
-  description_all_columns: æ‰€æœ‰æ¬„ä½
-  description_issue_category_reassign: é¸æ“‡å•é¡Œåˆ†é¡ž
-  description_wiki_subpages_reassign: é¸æ“‡æ–°çš„çˆ¶é é¢
-  description_date_range_list: å¾žæ¸…å–®ä¸­é¸å–ç¯„åœ
-  description_date_range_interval: é¸æ“‡èµ·å§‹èˆ‡çµæŸæ—¥æœŸä»¥è¨­å®šç¯„åœå€é–“
-  description_date_from: è¼¸å…¥èµ·å§‹æ—¥æœŸ
-  description_date_to: è¼¸å…¥çµæŸæ—¥æœŸ
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f5/f5ada035c7d5ce2734e191045efdfc2d9fd551ae.svn-base
--- a/.svn/pristine/f5/f5ada035c7d5ce2734e191045efdfc2d9fd551ae.svn-base
+++ /dev/null
@@ -1,291 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'redmine/scm/adapters/abstract_adapter'
-require 'uri'
-
-module Redmine
-  module Scm
-    module Adapters
-      class SubversionAdapter < AbstractAdapter
-
-        # SVN executable name
-        SVN_BIN = Redmine::Configuration['scm_subversion_command'] || "svn"
-
-        class << self
-          def client_command
-            @@bin    ||= SVN_BIN
-          end
-
-          def sq_bin
-            @@sq_bin ||= shell_quote_command
-          end
-
-          def client_version
-            @@client_version ||= (svn_binary_version || [])
-          end
-
-          def client_available
-            # --xml options are introduced in 1.3.
-            # http://subversion.apache.org/docs/release-notes/1.3.html
-            client_version_above?([1, 3])
-          end
-
-          def svn_binary_version
-            scm_version = scm_version_from_command_line.dup
-            if scm_version.respond_to?(:force_encoding)
-              scm_version.force_encoding('ASCII-8BIT')
-            end
-            if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
-              m[2].scan(%r{\d+}).collect(&:to_i)
-            end
-          end
-
-          def scm_version_from_command_line
-            shellout("#{sq_bin} --version") { |io| io.read }.to_s
-          end
-        end
-
-        # Get info about the svn repository
-        def info
-          cmd = "#{self.class.sq_bin} info --xml #{target}"
-          cmd << credentials_string
-          info = nil
-          shellout(cmd) do |io|
-            output = io.read
-            if output.respond_to?(:force_encoding)
-              output.force_encoding('UTF-8')
-            end
-            begin
-              doc = ActiveSupport::XmlMini.parse(output)
-              # root_url = doc.elements["info/entry/repository/root"].text
-              info = Info.new({:root_url => doc['info']['entry']['repository']['root']['__content__'],
-                               :lastrev => Revision.new({
-                                 :identifier => doc['info']['entry']['commit']['revision'],
-                                 :time => Time.parse(doc['info']['entry']['commit']['date']['__content__']).localtime,
-                                 :author => (doc['info']['entry']['commit']['author'] ? doc['info']['entry']['commit']['author']['__content__'] : "")
-                               })
-                             })
-            rescue
-            end
-          end
-          return nil if $? && $?.exitstatus != 0
-          info
-        rescue CommandFailed
-          return nil
-        end
-
-        # Returns an Entries collection
-        # or nil if the given path doesn't exist in the repository
-        def entries(path=nil, identifier=nil, options={})
-          path ||= ''
-          identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
-          entries = Entries.new
-          cmd = "#{self.class.sq_bin} list --xml #{target(path)}@#{identifier}"
-          cmd << credentials_string
-          shellout(cmd) do |io|
-            output = io.read
-            if output.respond_to?(:force_encoding)
-              output.force_encoding('UTF-8')
-            end
-            begin
-              doc = ActiveSupport::XmlMini.parse(output)
-              each_xml_element(doc['lists']['list'], 'entry') do |entry|
-                commit = entry['commit']
-                commit_date = commit['date']
-                # Skip directory if there is no commit date (usually that
-                # means that we don't have read access to it)
-                next if entry['kind'] == 'dir' && commit_date.nil?
-                name = entry['name']['__content__']
-                entries << Entry.new({:name => URI.unescape(name),
-                            :path => ((path.empty? ? "" : "#{path}/") + name),
-                            :kind => entry['kind'],
-                            :size => ((s = entry['size']) ? s['__content__'].to_i : nil),
-                            :lastrev => Revision.new({
-                              :identifier => commit['revision'],
-                              :time => Time.parse(commit_date['__content__'].to_s).localtime,
-                              :author => ((a = commit['author']) ? a['__content__'] : nil)
-                              })
-                            })
-              end
-            rescue Exception => e
-              logger.error("Error parsing svn output: #{e.message}")
-              logger.error("Output was:\n #{output}")
-            end
-          end
-          return nil if $? && $?.exitstatus != 0
-          logger.debug("Found #{entries.size} entries in the repository for #{target(path)}") if logger && logger.debug?
-          entries.sort_by_name
-        end
-
-        def properties(path, identifier=nil)
-          # proplist xml output supported in svn 1.5.0 and higher
-          return nil unless self.class.client_version_above?([1, 5, 0])
-
-          identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
-          cmd = "#{self.class.sq_bin} proplist --verbose --xml #{target(path)}@#{identifier}"
-          cmd << credentials_string
-          properties = {}
-          shellout(cmd) do |io|
-            output = io.read
-            if output.respond_to?(:force_encoding)
-              output.force_encoding('UTF-8')
-            end
-            begin
-              doc = ActiveSupport::XmlMini.parse(output)
-              each_xml_element(doc['properties']['target'], 'property') do |property|
-                properties[ property['name'] ] = property['__content__'].to_s
-              end
-            rescue
-            end
-          end
-          return nil if $? && $?.exitstatus != 0
-          properties
-        end
-
-        def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
-          path ||= ''
-          identifier_from = (identifier_from && identifier_from.to_i > 0) ? identifier_from.to_i : "HEAD"
-          identifier_to = (identifier_to && identifier_to.to_i > 0) ? identifier_to.to_i : 1
-          revisions = Revisions.new
-          cmd = "#{self.class.sq_bin} log --xml -r #{identifier_from}:#{identifier_to}"
-          cmd << credentials_string
-          cmd << " --verbose " if  options[:with_paths]
-          cmd << " --limit #{options[:limit].to_i}" if options[:limit]
-          cmd << ' ' + target(path)
-          shellout(cmd) do |io|
-            output = io.read
-            if output.respond_to?(:force_encoding)
-              output.force_encoding('UTF-8')
-            end
-            begin
-              doc = ActiveSupport::XmlMini.parse(output)
-              each_xml_element(doc['log'], 'logentry') do |logentry|
-                paths = []
-                each_xml_element(logentry['paths'], 'path') do |path|
-                  paths << {:action => path['action'],
-                            :path => path['__content__'],
-                            :from_path => path['copyfrom-path'],
-                            :from_revision => path['copyfrom-rev']
-                            }
-                end if logentry['paths'] && logentry['paths']['path']
-                paths.sort! { |x,y| x[:path] <=> y[:path] }
-
-                revisions << Revision.new({:identifier => logentry['revision'],
-                              :author => (logentry['author'] ? logentry['author']['__content__'] : ""),
-                              :time => Time.parse(logentry['date']['__content__'].to_s).localtime,
-                              :message => logentry['msg']['__content__'],
-                              :paths => paths
-                            })
-              end
-            rescue
-            end
-          end
-          return nil if $? && $?.exitstatus != 0
-          revisions
-        end
-
-        def diff(path, identifier_from, identifier_to=nil, type="inline")
-          path ||= ''
-          identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : ''
-
-          identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : (identifier_from.to_i - 1)
-
-          cmd = "#{self.class.sq_bin} diff -r "
-          cmd << "#{identifier_to}:"
-          cmd << "#{identifier_from}"
-          cmd << " #{target(path)}@#{identifier_from}"
-          cmd << credentials_string
-          diff = []
-          shellout(cmd) do |io|
-            io.each_line do |line|
-              diff << line
-            end
-          end
-          return nil if $? && $?.exitstatus != 0
-          diff
-        end
-
-        def cat(path, identifier=nil)
-          identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
-          cmd = "#{self.class.sq_bin} cat #{target(path)}@#{identifier}"
-          cmd << credentials_string
-          cat = nil
-          shellout(cmd) do |io|
-            io.binmode
-            cat = io.read
-          end
-          return nil if $? && $?.exitstatus != 0
-          cat
-        end
-
-        def annotate(path, identifier=nil)
-          identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
-          cmd = "#{self.class.sq_bin} blame #{target(path)}@#{identifier}"
-          cmd << credentials_string
-          blame = Annotate.new
-          shellout(cmd) do |io|
-            io.each_line do |line|
-              next unless line =~ %r{^\s*(\d+)\s*(\S+)\s(.*)$}
-              rev = $1
-              blame.add_line($3.rstrip,
-                   Revision.new(
-                      :identifier => rev,
-                      :revision   => rev,
-                      :author     => $2.strip
-                      ))
-            end
-          end
-          return nil if $? && $?.exitstatus != 0
-          blame
-        end
-
-        private
-
-        def credentials_string
-          str = ''
-          str << " --username #{shell_quote(@login)}" unless @login.blank?
-          str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
-          str << " --no-auth-cache --non-interactive"
-          str
-        end
-
-        # Helper that iterates over the child elements of a xml node
-        # MiniXml returns a hash when a single child is found
-        # or an array of hashes for multiple children
-        def each_xml_element(node, name)
-          if node && node[name]
-            if node[name].is_a?(Hash)
-              yield node[name]
-            else
-              node[name].each do |element|
-                yield element
-              end
-            end
-          end
-        end
-
-        def target(path = '')
-          base = path.match(/^\//) ? root_url : url
-          uri = "#{base}/#{path}"
-          uri = URI.escape(URI.escape(uri), '[]')
-          shell_quote(uri.gsub(/[?<>\*]/, ''))
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f6/f62006a748496bdfe8f98a95967ea18642e17172.svn-base
--- a/.svn/pristine/f6/f62006a748496bdfe8f98a95967ea18642e17172.svn-base
+++ /dev/null
@@ -1,127 +0,0 @@
-// ** I18N
-
-// Calendar EN language
-// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Pazar",
- "Pazartesi",
- "SalÄ±",
- "Ã‡arÅŸamba",
- "PerÅŸembe",
- "Cuma",
- "Cumartesi",
- "Pazar");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Paz",
- "Pzt",
- "Sal",
- "Ã‡ar",
- "Per",
- "Cum",
- "Cmt",
- "Paz");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Ocak",
- "Åžubat",
- "Mart",
- "Nisan",
- "MayÄ±s",
- "Haziran",
- "Temmuz",
- "AÄŸustos",
- "EylÃ¼l",
- "Ekim",
- "KasÄ±m",
- "AralÄ±k");
-
-// short month names
-Calendar._SMN = new Array
-("Oca",
- "Åžub",
- "Mar",
- "Nis",
- "May",
- "Haz",
- "Tem",
- "AÄŸu",
- "Eyl",
- "Eki",
- "Kas",
- "Ara");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Takvim hakkÄ±nda";
-
-Calendar._TT["ABOUT"] =
-"DHTML Tarih/Zaman SeÃ§ici\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Tarih SeÃ§imi:\n" +
-"- YÄ±l seÃ§mek iÃ§in \xab, \xbb tuÅŸlarÄ±nÄ± kullanÄ±n\n" +
-"- AyÄ± seÃ§mek iÃ§in " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " tuÅŸlarÄ±nÄ± kullanÄ±n\n" +
-"- HÄ±zlÄ± seÃ§im iÃ§in yukardaki butonlarÄ±n Ã¼zerinde farenin tuÅŸuna basÄ±lÄ± tutun.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Zaman SeÃ§imi:\n" +
-"- ArttÄ±rmak iÃ§in herhangi bir zaman bÃ¶lÃ¼mÃ¼ne tÄ±klayÄ±n\n" +
-"- ya da azaltmak iÃ§in Shift+tÄ±kla yapÄ±n\n" +
-"- ya da daha hÄ±zlÄ± bir seÃ§im iÃ§in tÄ±klayÄ±n ve sÃ¼rÃ¼kleyin.";
-
-Calendar._TT["PREV_YEAR"] = "Ã–ncki yÄ±l (Menu iÃ§in basÄ±lÄ± tutun)";
-Calendar._TT["PREV_MONTH"] = "Ã–nceki ay (Menu iÃ§in basÄ±lÄ± tutun)";
-Calendar._TT["GO_TODAY"] = "BugÃ¼ne Git";
-Calendar._TT["NEXT_MONTH"] = "Sonraki Ay (Menu iÃ§in basÄ±lÄ± tutun)";
-Calendar._TT["NEXT_YEAR"] = "Next year (Menu iÃ§in basÄ±lÄ± tutun)";
-Calendar._TT["SEL_DATE"] = "Tarih seÃ§in";
-Calendar._TT["DRAG_TO_MOVE"] = "TaÅŸÄ±mak iÃ§in sÃ¼rÃ¼kleyin";
-Calendar._TT["PART_TODAY"] = " (bugÃ¼n)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "%s : Ã¶nce gÃ¶ster";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "1,0";
-
-Calendar._TT["CLOSE"] = "Kapat";
-Calendar._TT["TODAY"] = "BugÃ¼n";
-Calendar._TT["TIME_PART"] = "DeÄŸeri deÄŸiÅŸtirmek iÃ§in (Shift-)tÄ±kla veya sÃ¼rÃ¼kle";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "Hafta";
-Calendar._TT["TIME"] = "Saat:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f6/f68e9832a00415902044b669a5f1909504e0ef9d.svn-base
--- /dev/null
+++ b/.svn/pristine/f6/f68e9832a00415902044b669a5f1909504e0ef9d.svn-base
@@ -0,0 +1,1148 @@
+html {overflow-y:scroll;}
+body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
+
+h1, h2, h3, h4 {font-family: "Trebuchet MS", Verdana, sans-serif;padding: 2px 10px 1px 0px;margin: 0 0 10px 0;}
+#content h1, h2, h3, h4 {color: #555;}
+h2, .wiki h1 {font-size: 20px;}
+h3, .wiki h2 {font-size: 16px;}
+h4, .wiki h3 {font-size: 13px;}
+h4 {border-bottom: 1px dotted #bbb;}
+
+/***** Layout *****/
+#wrapper {background: white;}
+
+#top-menu {background: #3E5B76; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;}
+#top-menu ul {margin: 0;  padding: 0;}
+#top-menu li {
+  float:left;
+  list-style-type:none;
+  margin: 0px 0px 0px 0px;
+  padding: 0px 0px 0px 0px;
+  white-space:nowrap;
+}
+#top-menu a {color: #fff; margin-right: 8px; font-weight: bold;}
+#top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
+
+#account {float:right;}
+
+#header {min-height:5.3em;margin:0;background-color:#628DB6;color:#f8f8f8; padding: 4px 8px 20px 6px; position:relative;}
+#header a {color:#f8f8f8;}
+#header h1 a.ancestor { font-size: 80%; }
+#quick-search {float:right;}
+
+#main-menu {position: absolute;  bottom: 0px;  left:6px; margin-right: -500px;}
+#main-menu ul {margin: 0;  padding: 0;}
+#main-menu li {
+  float:left;
+  list-style-type:none;
+  margin: 0px 2px 0px 0px;
+  padding: 0px 0px 0px 0px;
+  white-space:nowrap;
+}
+#main-menu li a {
+  display: block;
+  color: #fff;
+  text-decoration: none;
+  font-weight: bold;
+  margin: 0;
+  padding: 4px 10px 4px 10px;
+}
+#main-menu li a:hover {background:#759FCF; color:#fff;}
+#main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;}
+
+#admin-menu ul {margin: 0;  padding: 0;}
+#admin-menu li {margin: 0;  padding: 0 0 6px 0; list-style-type:none;}
+
+#admin-menu a { background-position: 0% 40%; background-repeat: no-repeat; padding-left: 20px; padding-top: 2px; padding-bottom: 3px;}
+#admin-menu a.projects { background-image: url(../images/projects.png); }
+#admin-menu a.users { background-image: url(../images/user.png); }
+#admin-menu a.groups { background-image: url(../images/group.png); }
+#admin-menu a.roles { background-image: url(../images/database_key.png); }
+#admin-menu a.trackers { background-image: url(../images/ticket.png); }
+#admin-menu a.issue_statuses { background-image: url(../images/ticket_edit.png); }
+#admin-menu a.workflows { background-image: url(../images/ticket_go.png); }
+#admin-menu a.custom_fields { background-image: url(../images/textfield.png); }
+#admin-menu a.enumerations { background-image: url(../images/text_list_bullets.png); }
+#admin-menu a.settings { background-image: url(../images/changeset.png); }
+#admin-menu a.plugins { background-image: url(../images/plugin.png); }
+#admin-menu a.info { background-image: url(../images/help.png); }
+#admin-menu a.server_authentication { background-image: url(../images/server_key.png); }
+
+#main {background-color:#EEEEEE;}
+
+#sidebar{ float: right; width: 22%; position: relative; z-index: 9; padding: 0; margin: 0;}
+* html #sidebar{ width: 22%; }
+#sidebar h3{ font-size: 14px; margin-top:14px; color: #666;  }
+#sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
+* html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
+#sidebar .contextual { margin-right: 1em; }
+
+#content { width: 75%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; }
+* html #content{ width: 75%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
+html>body #content { min-height: 600px; }
+* html body #content { height: 600px; } /* IE */
+
+#main.nosidebar #sidebar{ display: none; }
+#main.nosidebar #content{ width: auto; border-right: 0; }
+
+#footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
+
+#login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
+#login-form table td {padding: 6px;}
+#login-form label {font-weight: bold;}
+#login-form input#username, #login-form input#password { width: 300px; }
+
+div.modal { border-radius:5px; background:#fff; z-index:50; padding:4px;}
+div.modal h3.title {display:none;}
+div.modal p.buttons {text-align:right; margin-bottom:0;}
+
+input#openid_url { background: url(../images/openid-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; padding-left: 18px; }
+
+.clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+
+/***** Links *****/
+a, a:link, a:visited{ color: #169; text-decoration: none; }
+a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
+a img{ border: 0; }
+
+a.issue.closed, a.issue.closed:link, a.issue.closed:visited { color: #999; text-decoration: line-through; }
+a.project.closed, a.project.closed:link, a.project.closed:visited { color: #999; }
+a.user.locked, a.user.locked:link, a.user.locked:visited {color: #999;}
+
+#sidebar a.selected {line-height:1.7em; padding:1px 3px 2px 2px; margin-left:-2px; background-color:#9DB9D5; color:#fff; border-radius:2px;}
+#sidebar a.selected:hover {text-decoration:none;}
+#admin-menu a {line-height:1.7em;}
+#admin-menu a.selected {padding-left: 20px !important; background-position: 2px 40%;}
+
+a.collapsible {padding-left: 12px; background: url(../images/arrow_expanded.png) no-repeat -3px 40%;}
+a.collapsible.collapsed {background: url(../images/arrow_collapsed.png) no-repeat -5px 40%;}
+
+a#toggle-completed-versions {color:#999;}
+/***** Tables *****/
+table.list { border: 1px solid #e4e4e4;  border-collapse: collapse; width: 100%; margin-bottom: 4px; }
+table.list th {  background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
+table.list td { vertical-align: top; padding-right:10px; }
+table.list td.id { width: 2%; text-align: center;}
+table.list td.checkbox { width: 15px; padding: 2px 0 0 0; }
+table.list td.checkbox input {padding:0px;}
+table.list td.buttons { width: 15%; white-space:nowrap; text-align: right; }
+table.list td.buttons a { padding-right: 0.6em; }
+table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; }
+
+tr.project td.name a { white-space:nowrap; }
+tr.project.closed, tr.project.archived { color: #aaa; }
+tr.project.closed a, tr.project.archived a { color: #aaa; }
+
+tr.project.idnt td.name span {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
+tr.project.idnt-1 td.name {padding-left: 0.5em;}
+tr.project.idnt-2 td.name {padding-left: 2em;}
+tr.project.idnt-3 td.name {padding-left: 3.5em;}
+tr.project.idnt-4 td.name {padding-left: 5em;}
+tr.project.idnt-5 td.name {padding-left: 6.5em;}
+tr.project.idnt-6 td.name {padding-left: 8em;}
+tr.project.idnt-7 td.name {padding-left: 9.5em;}
+tr.project.idnt-8 td.name {padding-left: 11em;}
+tr.project.idnt-9 td.name {padding-left: 12.5em;}
+
+tr.issue { text-align: center; white-space: nowrap; }
+tr.issue td.subject, tr.issue td.category, td.assigned_to, tr.issue td.string, tr.issue td.text, tr.issue td.relations { white-space: normal; }
+tr.issue td.subject, tr.issue td.relations { text-align: left; }
+tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
+tr.issue td.relations span {white-space: nowrap;}
+table.issues td.description {color:#777; font-size:90%; padding:4px 4px 4px 24px; text-align:left; white-space:normal;}
+table.issues td.description pre {white-space:normal;}
+
+tr.issue.idnt td.subject a {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
+tr.issue.idnt-1 td.subject {padding-left: 0.5em;}
+tr.issue.idnt-2 td.subject {padding-left: 2em;}
+tr.issue.idnt-3 td.subject {padding-left: 3.5em;}
+tr.issue.idnt-4 td.subject {padding-left: 5em;}
+tr.issue.idnt-5 td.subject {padding-left: 6.5em;}
+tr.issue.idnt-6 td.subject {padding-left: 8em;}
+tr.issue.idnt-7 td.subject {padding-left: 9.5em;}
+tr.issue.idnt-8 td.subject {padding-left: 11em;}
+tr.issue.idnt-9 td.subject {padding-left: 12.5em;}
+
+tr.entry { border: 1px solid #f8f8f8; }
+tr.entry td { white-space: nowrap; }
+tr.entry td.filename { width: 30%; }
+tr.entry td.filename_no_report { width: 70%; }
+tr.entry td.size { text-align: right; font-size: 90%; }
+tr.entry td.revision, tr.entry td.author { text-align: center; }
+tr.entry td.age { text-align: right; }
+tr.entry.file td.filename a { margin-left: 16px; }
+tr.entry.file td.filename_no_report a { margin-left: 16px; }
+
+tr span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
+tr.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
+
+tr.changeset { height: 20px }
+tr.changeset ul, ol { margin-top: 0px; margin-bottom: 0px; }
+tr.changeset td.revision_graph { width: 15%; background-color: #fffffb; }
+tr.changeset td.author { text-align: center; width: 15%; white-space:nowrap;}
+tr.changeset td.committed_on { text-align: center; width: 15%; white-space:nowrap;}
+
+table.files tr.file td { text-align: center; }
+table.files tr.file td.filename { text-align: left; padding-left: 24px; }
+table.files tr.file td.digest { font-size: 80%; }
+
+table.members td.roles, table.memberships td.roles { width: 45%; }
+
+tr.message { height: 2.6em; }
+tr.message td.subject { padding-left: 20px; }
+tr.message td.created_on { white-space: nowrap; }
+tr.message td.last_message { font-size: 80%; white-space: nowrap; }
+tr.message.locked td.subject { background: url(../images/locked.png) no-repeat 0 1px; }
+tr.message.sticky td.subject { background: url(../images/bullet_go.png) no-repeat 0 1px; font-weight: bold; }
+
+tr.version.closed, tr.version.closed a { color: #999; }
+tr.version td.name { padding-left: 20px; }
+tr.version.shared td.name { background: url(../images/link.png) no-repeat 0% 70%; }
+tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; }
+
+tr.user td { width:13%; }
+tr.user td.email { width:18%; }
+tr.user td { white-space: nowrap; }
+tr.user.locked, tr.user.registered { color: #aaa; }
+tr.user.locked a, tr.user.registered a { color: #aaa; }
+
+table.permissions td.role {color:#999;font-size:90%;font-weight:normal !important;text-align:center;vertical-align:bottom;}
+
+tr.wiki-page-version td.updated_on, tr.wiki-page-version td.author {text-align:center;}
+
+tr.time-entry { text-align: center; white-space: nowrap; }
+tr.time-entry td.issue, tr.time-entry td.comments { text-align: left; white-space: normal; }
+td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
+td.hours .hours-dec { font-size: 0.9em; }
+
+table.plugins td { vertical-align: middle; }
+table.plugins td.configure { text-align: right; padding-right: 1em; }
+table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; }
+table.plugins span.description { display: block; font-size: 0.9em; }
+table.plugins span.url { display: block; font-size: 0.9em; }
+
+table.list tbody tr.group td { padding: 0.8em 0 0.5em 0.3em; font-weight: bold; border-bottom: 1px solid #ccc; }
+table.list tbody tr.group span.count {position:relative; top:-1px; color:#fff; font-size:10px; background:#9DB9D5; padding:0px 6px 1px 6px; border-radius:3px; margin-left:4px;}
+tr.group a.toggle-all { color: #aaa; font-size: 80%; font-weight: normal; display:none;}
+tr.group:hover a.toggle-all { display:inline;}
+a.toggle-all:hover {text-decoration:none;}
+
+table.list tbody tr:hover { background-color:#ffffdd; }
+table.list tbody tr.group:hover { background-color:inherit; }
+table td {padding:2px;}
+table p {margin:0;}
+.odd {background-color:#f6f7f8;}
+.even {background-color: #fff;}
+
+a.sort { padding-right: 16px; background-position: 100% 50%; background-repeat: no-repeat; }
+a.sort.asc  { background-image: url(../images/sort_asc.png); }
+a.sort.desc { background-image: url(../images/sort_desc.png); }
+
+table.attributes { width: 100% }
+table.attributes th { vertical-align: top; text-align: left; }
+table.attributes td { vertical-align: top; }
+
+table.boards a.board, h3.comments { background: url(../images/comment.png) no-repeat 0% 50%; padding-left: 20px; }
+table.boards td.topic-count, table.boards td.message-count {text-align:center;}
+table.boards td.last-message {font-size:80%;}
+
+table.messages td.author, table.messages td.created_on, table.messages td.reply-count {text-align:center;}
+
+table.query-columns {
+  border-collapse: collapse;
+  border: 0;
+}
+
+table.query-columns td.buttons {
+  vertical-align: middle;
+  text-align: center;
+}
+
+td.center {text-align:center;}
+
+h3.version { background: url(../images/package.png) no-repeat 0% 50%; padding-left: 20px; }
+
+div.issues h3 { background: url(../images/ticket.png) no-repeat 0% 50%; padding-left: 20px; }
+div.members h3 { background: url(../images/group.png) no-repeat 0% 50%; padding-left: 20px; }
+div.news h3 { background: url(../images/news.png) no-repeat 0% 50%; padding-left: 20px; }
+div.projects h3 { background: url(../images/projects.png) no-repeat 0% 50%; padding-left: 20px; }
+
+#watchers ul {margin: 0;  padding: 0;}
+#watchers li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;}
+#watchers select {width: 95%; display: block;}
+#watchers a.delete {opacity: 0.4; vertical-align: middle;}
+#watchers a.delete:hover {opacity: 1;}
+#watchers img.gravatar {margin: 0 4px 2px 0;}
+
+span#watchers_inputs {overflow:auto; display:block;}
+span.search_for_watchers {display:block;}
+span.search_for_watchers, span.add_attachment {font-size:80%; line-height:2.5em;}
+span.search_for_watchers a, span.add_attachment a {padding-left:16px; background: url(../images/bullet_add.png) no-repeat 0 50%; }
+
+
+.highlight { background-color: #FCFD8D;}
+.highlight.token-1 { background-color: #faa;}
+.highlight.token-2 { background-color: #afa;}
+.highlight.token-3 { background-color: #aaf;}
+
+.box{
+  padding:6px;
+  margin-bottom: 10px;
+  background-color:#f6f6f6;
+  color:#505050;
+  line-height:1.5em;
+  border: 1px solid #e4e4e4;
+}
+
+div.square {
+  border: 1px solid #999;
+  float: left;
+  margin: .3em .4em 0 .4em;
+  overflow: hidden;
+  width: .6em; height: .6em;
+}
+.contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
+.contextual input, .contextual select {font-size:0.9em;}
+.message .contextual { margin-top: 0; }
+
+.splitcontent {overflow:auto;}
+.splitcontentleft{float:left; width:49%;}
+.splitcontentright{float:right; width:49%;}
+form {display: inline;}
+input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
+fieldset {border: 1px solid #e4e4e4; margin:0;}
+legend {color: #484848;}
+hr { width: 100%; height: 1px; background: #ccc; border: 0;}
+blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;}
+blockquote blockquote { margin-left: 0;}
+acronym  { border-bottom: 1px dotted; cursor: help; }
+textarea.wiki-edit {width:99%; resize:vertical;}
+li p {margin-top: 0;}
+div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;}
+p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
+p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; }
+p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; }
+
+div.issue div.subject div div { padding-left: 16px; }
+div.issue div.subject p {margin: 0; margin-bottom: 0.1em; font-size: 90%; color: #999;}
+div.issue div.subject>div>p { margin-top: 0.5em; }
+div.issue div.subject h3 {margin: 0; margin-bottom: 0.1em;}
+div.issue span.private { position:relative; bottom: 2px; text-transform: uppercase; background: #d22; color: #fff; font-weight:bold; padding: 0px 2px 0px 2px; font-size: 60%; margin-right: 2px; border-radius: 2px;}
+div.issue .next-prev-links {color:#999;}
+div.issue table.attributes th {width:22%;}
+div.issue table.attributes td {width:28%;}
+
+#issue_tree table.issues, #relations table.issues { border: 0; }
+#issue_tree td.checkbox, #relations td.checkbox {display:none;}
+#relations td.buttons {padding:0;}
+
+fieldset.collapsible { border-width: 1px 0 0 0; font-size: 0.9em; }
+fieldset.collapsible>legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; }
+fieldset.collapsible.collapsed>legend { background-image: url(../images/arrow_collapsed.png); }
+
+fieldset#date-range p { margin: 2px 0 2px 0; }
+fieldset#filters table { border-collapse: collapse; }
+fieldset#filters table td { padding: 0; vertical-align: middle; }
+fieldset#filters tr.filter { height: 2.1em; }
+fieldset#filters td.field { width:230px; }
+fieldset#filters td.operator { width:180px; }
+fieldset#filters td.operator select {max-width:170px;}
+fieldset#filters td.values { white-space:nowrap; }
+fieldset#filters td.values select {min-width:130px;}
+fieldset#filters td.values input {height:1em;}
+fieldset#filters td.add-filter { text-align: right; vertical-align: top; }
+
+.toggle-multiselect {background: url(../images/bullet_toggle_plus.png) no-repeat 0% 40%; padding-left:8px; margin-left:0; cursor:pointer;}
+.buttons { font-size: 0.9em; margin-bottom: 1.4em; margin-top: 1em; }
+
+div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
+div#issue-changesets div.changeset { padding: 4px;}
+div#issue-changesets div.changeset { border-bottom: 1px solid #ddd; }
+div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
+
+.journal ul.details img {margin:0 0 -3px 4px;}
+div.journal {overflow:auto;}
+div.journal.private-notes {border-left:2px solid #d22; padding-left:4px; margin-left:-6px;}
+
+div#activity dl, #search-results { margin-left: 2em; }
+div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
+div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
+div#activity dt.me .time { border-bottom: 1px solid #999; }
+div#activity dt .time { color: #777; font-size: 80%; }
+div#activity dd .description, #search-results dd .description { font-style: italic; }
+div#activity span.project:after, #search-results span.project:after { content: " -"; }
+div#activity dd span.description, #search-results dd span.description { display:block; color: #808080; }
+div#activity dt.grouped {margin-left:5em;}
+div#activity dd.grouped {margin-left:9em;}
+
+#search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
+
+div#search-results-counts {float:right;}
+div#search-results-counts ul { margin-top: 0.5em; }
+div#search-results-counts  li { list-style-type:none; float: left; margin-left: 1em; }
+
+dt.issue { background-image: url(../images/ticket.png); }
+dt.issue-edit { background-image: url(../images/ticket_edit.png); }
+dt.issue-closed { background-image: url(../images/ticket_checked.png); }
+dt.issue-note { background-image: url(../images/ticket_note.png); }
+dt.changeset { background-image: url(../images/changeset.png); }
+dt.news { background-image: url(../images/news.png); }
+dt.message { background-image: url(../images/message.png); }
+dt.reply { background-image: url(../images/comments.png); }
+dt.wiki-page { background-image: url(../images/wiki_edit.png); }
+dt.attachment { background-image: url(../images/attachment.png); }
+dt.document { background-image: url(../images/document.png); }
+dt.project { background-image: url(../images/projects.png); }
+dt.time-entry { background-image: url(../images/time.png); }
+
+#search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); }
+
+div#roadmap .related-issues { margin-bottom: 1em; }
+div#roadmap .related-issues td.checkbox { display: none; }
+div#roadmap .wiki h1:first-child { display: none; }
+div#roadmap .wiki h1 { font-size: 120%; }
+div#roadmap .wiki h2 { font-size: 110%; }
+body.controller-versions.action-show div#roadmap .related-issues {width:70%;}
+
+div#version-summary { float:right; width:28%; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
+div#version-summary fieldset { margin-bottom: 1em; }
+div#version-summary fieldset.time-tracking table { width:100%; }
+div#version-summary th, div#version-summary td.total-hours { text-align: right; }
+
+table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; }
+table#time-report tbody tr.subtotal { font-style: italic; color:#777;}
+table#time-report tbody tr.subtotal td.hours { color:#b0b0b0; }
+table#time-report tbody tr.total { font-weight: bold; background-color:#EEEEEE; border-top:1px solid #e4e4e4;}
+table#time-report .hours-dec { font-size: 0.9em; }
+
+div.wiki-page .contextual a {opacity: 0.4}
+div.wiki-page .contextual a:hover {opacity: 1}
+
+form .attributes select { width: 60%; }
+input#issue_subject { width: 99%; }
+select#issue_done_ratio { width: 95px; }
+
+ul.projects {margin:0; padding-left:1em;}
+ul.projects ul {padding-left:1.6em;}
+ul.projects.root {margin:0; padding:0;}
+ul.projects li {list-style-type:none;}
+
+#projects-index ul.projects ul.projects { border-left: 3px solid #e0e0e0; padding-left:1em;}
+#projects-index ul.projects li.root {margin-bottom: 1em;}
+#projects-index ul.projects li.child {margin-top: 1em;}
+#projects-index ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
+.my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; }
+
+#notified-projects ul, #tracker_project_ids ul {max-height:250px; overflow-y:auto;}
+
+#related-issues li img {vertical-align:middle;}
+
+ul.properties {padding:0; font-size: 0.9em; color: #777;}
+ul.properties li {list-style-type:none;}
+ul.properties li span {font-style:italic;}
+
+.total-hours { font-size: 110%; font-weight: bold; }
+.total-hours span.hours-int { font-size: 120%; }
+
+.autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em;}
+#user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select, #user_identity_url { width: 90%; }
+
+#workflow_copy_form select { width: 200px; }
+table.transitions td.enabled {background: #bfb;}
+table.fields_permissions select {font-size:90%}
+table.fields_permissions td.readonly {background:#ddd;}
+table.fields_permissions td.required {background:#d88;}
+
+textarea#custom_field_possible_values {width: 99%}
+textarea#custom_field_default_value {width: 99%}
+
+input#content_comments {width: 99%}
+
+p.pagination {margin-top:8px; font-size: 90%}
+
+/***** Tabular forms ******/
+.tabular p{
+  margin: 0;
+  padding: 3px 0 3px 0;
+  padding-left: 180px; /* width of left column containing the label elements */
+  min-height: 1.8em;
+  clear:left;
+}
+
+html>body .tabular p {overflow:hidden;}
+
+.tabular label{
+  font-weight: bold;
+  float: left;
+  text-align: right;
+  /* width of left column */
+  margin-left: -180px;
+  /* width of labels. Should be smaller than left column to create some right margin */
+  width: 175px;
+}
+
+.tabular label.floating{
+  font-weight: normal;
+  margin-left: 0px;
+  text-align: left;
+  width: 270px;
+}
+
+.tabular label.block{
+  font-weight: normal;
+  margin-left: 0px !important;
+  text-align: left;
+  float: none;
+  display: block;
+  width: auto;
+}
+
+.tabular label.inline{
+  font-weight: normal;
+  float:none;
+  margin-left: 5px !important;
+  width: auto;
+}
+
+label.no-css {
+  font-weight: inherit;
+  float:none;
+  text-align:left;
+  margin-left:0px;
+  width:auto;
+}
+input#time_entry_comments { width: 90%;}
+
+#preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
+
+.tabular.settings p{ padding-left: 300px; }
+.tabular.settings label{ margin-left: -300px; width: 295px; }
+.tabular.settings textarea { width: 99%; }
+
+.settings.enabled_scm table {width:100%}
+.settings.enabled_scm td.scm_name{ font-weight: bold; }
+
+fieldset.settings label { display: block; }
+fieldset#notified_events .parent { padding-left: 20px; }
+
+span.required {color: #bb0000;}
+.summary {font-style: italic;}
+
+#attachments_fields input.description {margin-left:4px; width:340px;}
+#attachments_fields span {display:block; white-space:nowrap;}
+#attachments_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../images/attachment.png) no-repeat 1px 50%; padding-left:18px;}
+#attachments_fields .ajax-waiting input.filename {background:url(../images/hourglass.png) no-repeat 0px 50%;}
+#attachments_fields .ajax-loading input.filename {background:url(../images/loading.gif) no-repeat 0px 50%;}
+#attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; }
+a.remove-upload {background: url(../images/delete.png) no-repeat 1px 50%; width:1px; display:inline-block; padding-left:16px;}
+a.remove-upload:hover {text-decoration:none !important;}
+
+div.fileover { background-color: lavender; }
+
+div.attachments { margin-top: 12px; }
+div.attachments p { margin:4px 0 2px 0; }
+div.attachments img { vertical-align: middle; }
+div.attachments span.author { font-size: 0.9em; color: #888; }
+
+div.thumbnails {margin-top:0.6em;}
+div.thumbnails div {background:#fff;border:2px solid #ddd;display:inline-block;margin-right:2px;}
+div.thumbnails img {margin: 3px;}
+
+p.other-formats { text-align: right; font-size:0.9em; color: #666; }
+.other-formats span + span:before { content: "| "; }
+
+a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
+
+em.info {font-style:normal;font-size:90%;color:#888;display:block;}
+em.info.error {padding-left:20px; background:url(../images/exclamation.png) no-repeat 0 50%;}
+
+textarea.text_cf {width:90%;}
+
+#tab-content-modules fieldset p {margin:3px 0 4px 0;}
+
+#tab-content-members .splitcontentleft, #tab-content-memberships .splitcontentleft, #tab-content-users .splitcontentleft {width: 64%;}
+#tab-content-members .splitcontentright, #tab-content-memberships .splitcontentright, #tab-content-users .splitcontentright {width: 34%;}
+#tab-content-members fieldset, #tab-content-memberships fieldset, #tab-content-users fieldset {padding:1em; margin-bottom: 1em;}
+#tab-content-members fieldset legend, #tab-content-memberships fieldset legend, #tab-content-users fieldset legend {font-weight: bold;}
+#tab-content-members fieldset label, #tab-content-memberships fieldset label, #tab-content-users fieldset label {display: block;}
+#tab-content-members #principals, #tab-content-users #principals {max-height: 400px; overflow: auto;}
+
+#users_for_watcher {height: 200px; overflow:auto;}
+#users_for_watcher label {display: block;}
+
+table.members td.group { padding-left: 20px; background: url(../images/group.png) no-repeat 0% 50%; }
+
+input#principal_search, input#user_search {width:90%}
+
+input.autocomplete {
+  background: #fff url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px;
+  border:1px solid #9EB1C2; border-radius:2px; height:1.5em;
+}
+input.autocomplete.ajax-loading {
+  background-image: url(../images/loading.gif);
+}
+
+/***** Flash & error messages ****/
+#errorExplanation, div.flash, .nodata, .warning, .conflict {
+  padding: 4px 4px 4px 30px;
+  margin-bottom: 12px;
+  font-size: 1.1em;
+  border: 2px solid;
+}
+
+div.flash {margin-top: 8px;}
+
+div.flash.error, #errorExplanation {
+  background: url(../images/exclamation.png) 8px 50% no-repeat;
+  background-color: #ffe3e3;
+  border-color: #dd0000;
+  color: #880000;
+}
+
+div.flash.notice {
+  background: url(../images/true.png) 8px 5px no-repeat;
+  background-color: #dfffdf;
+  border-color: #9fcf9f;
+  color: #005f00;
+}
+
+div.flash.warning, .conflict {
+  background: url(../images/warning.png) 8px 5px no-repeat;
+  background-color: #FFEBC1;
+  border-color: #FDBF3B;
+  color: #A6750C;
+  text-align: left;
+}
+
+.nodata, .warning {
+  text-align: center;
+  background-color: #FFEBC1;
+  border-color: #FDBF3B;
+  color: #A6750C;
+}
+
+#errorExplanation ul { font-size: 0.9em;}
+#errorExplanation h2, #errorExplanation p { display: none; }
+
+.conflict-details {font-size:80%;}
+
+/***** Ajax indicator ******/
+#ajax-indicator {
+position: absolute; /* fixed not supported by IE */
+background-color:#eee;
+border: 1px solid #bbb;
+top:35%;
+left:40%;
+width:20%;
+font-weight:bold;
+text-align:center;
+padding:0.6em;
+z-index:100;
+opacity: 0.5;
+}
+
+html>body #ajax-indicator { position: fixed; }
+
+#ajax-indicator span {
+background-position: 0% 40%;
+background-repeat: no-repeat;
+background-image: url(../images/loading.gif);
+padding-left: 26px;
+vertical-align: bottom;
+}
+
+/***** Calendar *****/
+table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;}
+table.cal thead th {width: 14%; background-color:#EEEEEE; padding: 4px; }
+table.cal thead th.week-number {width: auto;}
+table.cal tbody tr {height: 100px;}
+table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
+table.cal td.week-number { background-color:#EEEEEE; padding: 4px; border:none; font-size: 1em;}
+table.cal td p.day-num {font-size: 1.1em; text-align:right;}
+table.cal td.odd p.day-num {color: #bbb;}
+table.cal td.today {background:#ffffdd;}
+table.cal td.today p.day-num {font-weight: bold;}
+table.cal .starting a, p.cal.legend .starting {background: url(../images/bullet_go.png) no-repeat -1px -2px; padding-left:16px;}
+table.cal .ending a, p.cal.legend .ending {background: url(../images/bullet_end.png) no-repeat -1px -2px; padding-left:16px;}
+table.cal .starting.ending a, p.cal.legend .starting.ending {background: url(../images/bullet_diamond.png) no-repeat -1px -2px; padding-left:16px;}
+p.cal.legend span {display:block;}
+
+/***** Tooltips ******/
+.tooltip{position:relative;z-index:24;}
+.tooltip:hover{z-index:25;color:#000;}
+.tooltip span.tip{display: none; text-align:left;}
+
+div.tooltip:hover span.tip{
+display:block;
+position:absolute;
+top:12px; left:24px; width:270px;
+border:1px solid #555;
+background-color:#fff;
+padding: 4px;
+font-size: 0.8em;
+color:#505050;
+}
+
+img.ui-datepicker-trigger {
+  cursor: pointer;
+  vertical-align: middle;
+  margin-left: 4px;
+}
+
+/***** Progress bar *****/
+table.progress {
+  border-collapse: collapse;
+  border-spacing: 0pt;
+  empty-cells: show;
+  text-align: center;
+  float:left;
+  margin: 1px 6px 1px 0px;
+}
+
+table.progress td { height: 1em; }
+table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
+table.progress td.done { background: #D3EDD3 none repeat scroll 0%; }
+table.progress td.todo { background: #eee none repeat scroll 0%; }
+p.percent {font-size: 80%;}
+p.progress-info {clear: left; font-size: 80%; margin-top:-4px; color:#777;}
+
+#roadmap table.progress td { height: 1.2em; }
+/***** Tabs *****/
+#content .tabs {height: 2.6em; margin-bottom:1.2em; position:relative; overflow:hidden;}
+#content .tabs ul {margin:0; position:absolute; bottom:0; padding-left:0.5em; width: 2000px; border-bottom: 1px solid #bbbbbb;}
+#content .tabs ul li {
+  float:left;
+  list-style-type:none;
+  white-space:nowrap;
+  margin-right:4px;
+  background:#fff;
+  position:relative;
+  margin-bottom:-1px;
+}
+#content .tabs ul li a{
+  display:block;
+  font-size: 0.9em;
+  text-decoration:none;
+  line-height:1.3em;
+  padding:4px 6px 4px 6px;
+  border: 1px solid #ccc;
+  border-bottom: 1px solid #bbbbbb;
+  background-color: #f6f6f6;
+  color:#999;
+  font-weight:bold;
+  border-top-left-radius:3px;
+  border-top-right-radius:3px;
+}
+
+#content .tabs ul li a:hover {
+  background-color: #ffffdd;
+  text-decoration:none;
+}
+
+#content .tabs ul li a.selected {
+  background-color: #fff;
+  border: 1px solid #bbbbbb;
+  border-bottom: 1px solid #fff;
+  color:#444;
+}
+
+#content .tabs ul li a.selected:hover {background-color: #fff;}
+
+div.tabs-buttons { position:absolute; right: 0; width: 48px; height: 24px; background: white; bottom: 0; border-bottom: 1px solid #bbbbbb; }
+
+button.tab-left, button.tab-right {
+  font-size: 0.9em;
+  cursor: pointer;
+  height:24px;
+  border: 1px solid #ccc;
+  border-bottom: 1px solid #bbbbbb;
+  position:absolute;
+  padding:4px;
+  width: 20px;
+  bottom: -1px;
+}
+
+button.tab-left {
+  right: 20px;
+  background: #eeeeee url(../images/bullet_arrow_left.png) no-repeat 50% 50%;
+  border-top-left-radius:3px;
+}
+
+button.tab-right {
+  right: 0;
+  background: #eeeeee url(../images/bullet_arrow_right.png) no-repeat 50% 50%;
+  border-top-right-radius:3px;
+}
+
+/***** Diff *****/
+.diff_out { background: #fcc; }
+.diff_out span { background: #faa; }
+.diff_in { background: #cfc; }
+.diff_in span { background: #afa; }
+
+.text-diff {
+  padding: 1em;
+  background-color:#f6f6f6;
+  color:#505050;
+  border: 1px solid #e4e4e4;
+}
+
+/***** Wiki *****/
+div.wiki table {
+  border-collapse: collapse;
+  margin-bottom: 1em;
+}
+
+div.wiki table, div.wiki td, div.wiki th {
+  border: 1px solid #bbb;
+  padding: 4px;
+}
+
+div.wiki .noborder, div.wiki .noborder td, div.wiki .noborder th {border:0;}
+
+div.wiki .external {
+  background-position: 0% 60%;
+  background-repeat: no-repeat;
+  padding-left: 12px;
+  background-image: url(../images/external.png);
+}
+
+div.wiki a.new {color: #b73535;}
+
+div.wiki ul, div.wiki ol {margin-bottom:1em;}
+
+div.wiki pre {
+  margin: 1em 1em 1em 1.6em;
+  padding: 8px;
+  background-color: #fafafa;
+  border: 1px solid #e2e2e2;
+  width:auto;
+  overflow-x: auto;
+  overflow-y: hidden;
+}
+
+div.wiki ul.toc {
+  background-color: #ffffdd;
+  border: 1px solid #e4e4e4;
+  padding: 4px;
+  line-height: 1.2em;
+  margin-bottom: 12px;
+  margin-right: 12px;
+  margin-left: 0;
+  display: table
+}
+* html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */
+
+div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
+div.wiki ul.toc.left  { float: left; margin-right: 12px; margin-left: 0; width: auto; }
+div.wiki ul.toc ul { margin: 0; padding: 0; }
+div.wiki ul.toc li {list-style-type:none; margin: 0; font-size:12px;}
+div.wiki ul.toc li li {margin-left: 1.5em; font-size:10px;}
+div.wiki ul.toc a {
+  font-size: 0.9em;
+  font-weight: normal;
+  text-decoration: none;
+  color: #606060;
+}
+div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;}
+
+a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; }
+a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; }
+h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; }
+
+div.wiki img { vertical-align: middle; }
+
+/***** My page layout *****/
+.block-receiver {
+  border:1px dashed #c0c0c0;
+  margin-bottom: 20px;
+  padding: 15px 0 15px 0;
+}
+
+.mypage-box {
+  margin:0 0 20px 0;
+  color:#505050;
+  line-height:1.5em;
+}
+
+.handle {cursor: move;}
+
+a.close-icon {
+  display:block;
+  margin-top:3px;
+  overflow:hidden;
+  width:12px;
+  height:12px;
+  background-repeat: no-repeat;
+  cursor:pointer;
+  background-image:url('../images/close.png');
+}
+a.close-icon:hover {background-image:url('../images/close_hl.png');}
+
+/***** Gantt chart *****/
+.gantt_hdr {
+  position:absolute;
+  top:0;
+  height:16px;
+  border-top: 1px solid #c0c0c0;
+  border-bottom: 1px solid #c0c0c0;
+  border-right: 1px solid #c0c0c0;
+  text-align: center;
+  overflow: hidden;
+}
+
+.gantt_hdr.nwday {background-color:#f1f1f1;}
+
+.gantt_subjects { font-size: 0.8em; }
+.gantt_subjects div { line-height:16px;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; }
+
+.task {
+  position: absolute;
+  height:8px;
+  font-size:0.8em;
+  color:#888;
+  padding:0;
+  margin:0;
+  line-height:16px;
+  white-space:nowrap;
+}
+
+.task.label {width:100%;}
+.task.label.project, .task.label.version { font-weight: bold; }
+
+.task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
+.task_done { background:#00c600 url(../images/task_done.png); border: 1px solid #00c600; }
+.task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
+
+.task_todo.parent { background: #888; border: 1px solid #888; height: 3px;}
+.task_late.parent, .task_done.parent { height: 3px;}
+.task.parent.marker.starting  { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; left: 0px; top: -1px;}
+.task.parent.marker.ending { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; right: 0px; top: -1px;}
+
+.version.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
+.version.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
+.version.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
+.version.marker { background-image:url(../images/version_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
+
+.project.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
+.project.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
+.project.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
+.project.marker { background-image:url(../images/project_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
+
+.version-behind-schedule a, .issue-behind-schedule a {color: #f66914;}
+.version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;}
+
+/***** Icons *****/
+.icon {
+  background-position: 0% 50%;
+  background-repeat: no-repeat;
+  padding-left: 20px;
+  padding-top: 2px;
+  padding-bottom: 3px;
+}
+
+.icon-add { background-image: url(../images/add.png); }
+.icon-edit { background-image: url(../images/edit.png); }
+.icon-copy { background-image: url(../images/copy.png); }
+.icon-duplicate { background-image: url(../images/duplicate.png); }
+.icon-del { background-image: url(../images/delete.png); }
+.icon-move { background-image: url(../images/move.png); }
+.icon-save { background-image: url(../images/save.png); }
+.icon-cancel { background-image: url(../images/cancel.png); }
+.icon-multiple { background-image: url(../images/table_multiple.png); }
+.icon-folder { background-image: url(../images/folder.png); }
+.open .icon-folder { background-image: url(../images/folder_open.png); }
+.icon-package { background-image: url(../images/package.png); }
+.icon-user { background-image: url(../images/user.png); }
+.icon-projects { background-image: url(../images/projects.png); }
+.icon-help { background-image: url(../images/help.png); }
+.icon-attachment  { background-image: url(../images/attachment.png); }
+.icon-history  { background-image: url(../images/history.png); }
+.icon-time  { background-image: url(../images/time.png); }
+.icon-time-add  { background-image: url(../images/time_add.png); }
+.icon-stats  { background-image: url(../images/stats.png); }
+.icon-warning  { background-image: url(../images/warning.png); }
+.icon-fav  { background-image: url(../images/fav.png); }
+.icon-fav-off  { background-image: url(../images/fav_off.png); }
+.icon-reload  { background-image: url(../images/reload.png); }
+.icon-lock  { background-image: url(../images/locked.png); }
+.icon-unlock  { background-image: url(../images/unlock.png); }
+.icon-checked  { background-image: url(../images/true.png); }
+.icon-details  { background-image: url(../images/zoom_in.png); }
+.icon-report  { background-image: url(../images/report.png); }
+.icon-comment  { background-image: url(../images/comment.png); }
+.icon-summary  { background-image: url(../images/lightning.png); }
+.icon-server-authentication { background-image: url(../images/server_key.png); }
+.icon-issue { background-image: url(../images/ticket.png); }
+.icon-zoom-in { background-image: url(../images/zoom_in.png); }
+.icon-zoom-out { background-image: url(../images/zoom_out.png); }
+.icon-passwd { background-image: url(../images/textfield_key.png); }
+.icon-test { background-image: url(../images/bullet_go.png); }
+
+.icon-file { background-image: url(../images/files/default.png); }
+.icon-file.text-plain { background-image: url(../images/files/text.png); }
+.icon-file.text-x-c { background-image: url(../images/files/c.png); }
+.icon-file.text-x-csharp { background-image: url(../images/files/csharp.png); }
+.icon-file.text-x-java { background-image: url(../images/files/java.png); }
+.icon-file.text-x-javascript { background-image: url(../images/files/js.png); }
+.icon-file.text-x-php { background-image: url(../images/files/php.png); }
+.icon-file.text-x-ruby { background-image: url(../images/files/ruby.png); }
+.icon-file.text-xml { background-image: url(../images/files/xml.png); }
+.icon-file.text-css { background-image: url(../images/files/css.png); }
+.icon-file.text-html { background-image: url(../images/files/html.png); }
+.icon-file.image-gif { background-image: url(../images/files/image.png); }
+.icon-file.image-jpeg { background-image: url(../images/files/image.png); }
+.icon-file.image-png { background-image: url(../images/files/image.png); }
+.icon-file.image-tiff { background-image: url(../images/files/image.png); }
+.icon-file.application-pdf { background-image: url(../images/files/pdf.png); }
+.icon-file.application-zip { background-image: url(../images/files/zip.png); }
+.icon-file.application-x-gzip { background-image: url(../images/files/zip.png); }
+
+img.gravatar {
+  padding: 2px;
+  border: solid 1px #d5d5d5;
+  background: #fff;
+  vertical-align: middle;
+}
+
+div.issue img.gravatar {
+  float: left;
+  margin: 0 6px 0 0;
+  padding: 5px;
+}
+
+div.issue table img.gravatar {
+  height: 14px;
+  width: 14px;
+  padding: 2px;
+  float: left;
+  margin: 0 0.5em 0 0;
+}
+
+h2 img.gravatar {margin: -2px 4px -4px 0;}
+h3 img.gravatar {margin: -4px 4px -4px 0;}
+h4 img.gravatar {margin: -6px 4px -4px 0;}
+td.username img.gravatar {margin: 0 0.5em 0 0; vertical-align: top;}
+#activity dt img.gravatar {float: left; margin: 0 1em 1em 0;}
+/* Used on 12px Gravatar img tags without the icon background */
+.icon-gravatar {float: left; margin-right: 4px;}
+
+#activity dt, .journal {clear: left;}
+
+.journal-link {float: right;}
+
+h2 img { vertical-align:middle; }
+
+.hascontextmenu { cursor: context-menu; }
+
+/************* CodeRay styles *************/
+.syntaxhl div {display: inline;}
+.syntaxhl .line-numbers {padding: 2px 4px 2px 4px; background-color: #eee; margin:0px 5px 0px 0px;}
+.syntaxhl .code pre { overflow: auto }
+.syntaxhl .debug { color: white !important; background: blue !important; }
+
+.syntaxhl .annotation { color:#007 }
+.syntaxhl .attribute-name { color:#b48 }
+.syntaxhl .attribute-value { color:#700 }
+.syntaxhl .binary { color:#509 }
+.syntaxhl .char .content { color:#D20 }
+.syntaxhl .char .delimiter { color:#710 }
+.syntaxhl .char { color:#D20 }
+.syntaxhl .class { color:#258; font-weight:bold }
+.syntaxhl .class-variable { color:#369 }
+.syntaxhl .color { color:#0A0 }
+.syntaxhl .comment { color:#385 }
+.syntaxhl .comment .char { color:#385 }
+.syntaxhl .comment .delimiter { color:#385 }
+.syntaxhl .complex { color:#A08 }
+.syntaxhl .constant { color:#258; font-weight:bold }
+.syntaxhl .decorator { color:#B0B }
+.syntaxhl .definition { color:#099; font-weight:bold }
+.syntaxhl .delimiter { color:black }
+.syntaxhl .directive { color:#088; font-weight:bold }
+.syntaxhl .doc { color:#970 }
+.syntaxhl .doc-string { color:#D42; font-weight:bold }
+.syntaxhl .doctype { color:#34b }
+.syntaxhl .entity { color:#800; font-weight:bold }
+.syntaxhl .error { color:#F00; background-color:#FAA }
+.syntaxhl .escape  { color:#666 }
+.syntaxhl .exception { color:#C00; font-weight:bold }
+.syntaxhl .float { color:#06D }
+.syntaxhl .function { color:#06B; font-weight:bold }
+.syntaxhl .global-variable { color:#d70 }
+.syntaxhl .hex { color:#02b }
+.syntaxhl .imaginary { color:#f00 }
+.syntaxhl .include { color:#B44; font-weight:bold }
+.syntaxhl .inline { background-color: hsla(0,0%,0%,0.07); color: black }
+.syntaxhl .inline-delimiter { font-weight: bold; color: #666 }
+.syntaxhl .instance-variable { color:#33B }
+.syntaxhl .integer  { color:#06D }
+.syntaxhl .key .char { color: #60f }
+.syntaxhl .key .delimiter { color: #404 }
+.syntaxhl .key { color: #606 }
+.syntaxhl .keyword { color:#939; font-weight:bold }
+.syntaxhl .label { color:#970; font-weight:bold }
+.syntaxhl .local-variable { color:#963 }
+.syntaxhl .namespace { color:#707; font-weight:bold }
+.syntaxhl .octal { color:#40E }
+.syntaxhl .operator { }
+.syntaxhl .predefined { color:#369; font-weight:bold }
+.syntaxhl .predefined-constant { color:#069 }
+.syntaxhl .predefined-type { color:#0a5; font-weight:bold }
+.syntaxhl .preprocessor { color:#579 }
+.syntaxhl .pseudo-class { color:#00C; font-weight:bold }
+.syntaxhl .regexp .content { color:#808 }
+.syntaxhl .regexp .delimiter { color:#404 }
+.syntaxhl .regexp .modifier { color:#C2C }
+.syntaxhl .regexp { background-color:hsla(300,100%,50%,0.06); }
+.syntaxhl .reserved { color:#080; font-weight:bold }
+.syntaxhl .shell .content { color:#2B2 }
+.syntaxhl .shell .delimiter { color:#161 }
+.syntaxhl .shell { background-color:hsla(120,100%,50%,0.06); }
+.syntaxhl .string .char { color: #46a }
+.syntaxhl .string .content { color: #46a }
+.syntaxhl .string .delimiter { color: #46a }
+.syntaxhl .string .modifier { color: #46a }
+.syntaxhl .symbol .content { color:#d33 }
+.syntaxhl .symbol .delimiter { color:#d33 }
+.syntaxhl .symbol { color:#d33 }
+.syntaxhl .tag { color:#070 }
+.syntaxhl .type { color:#339; font-weight:bold }
+.syntaxhl .value { color: #088; }
+.syntaxhl .variable  { color:#037 }
+
+.syntaxhl .insert { background: hsla(120,100%,50%,0.12) }
+.syntaxhl .delete { background: hsla(0,100%,50%,0.12) }
+.syntaxhl .change { color: #bbf; background: #007; }
+.syntaxhl .head { color: #f8f; background: #505 }
+.syntaxhl .head .filename { color: white; }
+
+.syntaxhl .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
+.syntaxhl .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
+
+.syntaxhl .insert .insert { color: #0c0; background:transparent; font-weight:bold }
+.syntaxhl .delete .delete { color: #c00; background:transparent; font-weight:bold }
+.syntaxhl .change .change { color: #88f }
+.syntaxhl .head .head { color: #f4f }
+
+/***** Media print specific styles *****/
+@media print {
+  #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; }
+  #main { background: #fff; }
+  #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
+  #wiki_add_attachment { display:none; }
+  .hide-when-print { display: none; }
+  .autoscroll {overflow-x: visible;}
+  table.list {margin-top:0.5em;}
+  table.list th, table.list td {border: 1px solid #aaa;}
+}
+
+/* Accessibility specific styles */
+.hidden-for-sighted {
+  position:absolute;
+  left:-10000px;
+  top:auto;
+  width:1px;
+  height:1px;
+  overflow:hidden;
+}
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f6/f6adde640ee0f6699f4137e3cbfb95a7427fe4fa.svn-base
--- a/.svn/pristine/f6/f6adde640ee0f6699f4137e3cbfb95a7427fe4fa.svn-base
+++ /dev/null
@@ -1,30 +0,0 @@
-/.project
-/.loadpath
-/config/additional_environment.rb
-/config/configuration.yml
-/config/database.yml
-/config/email.yml
-/config/initializers/session_store.rb
-/coverage
-/db/*.db
-/db/*.sqlite3
-/db/schema.rb
-/files/*
-/lib/redmine/scm/adapters/mercurial/redminehelper.pyc
-/lib/redmine/scm/adapters/mercurial/redminehelper.pyo
-/log/*.log*
-/log/mongrel_debug
-/public/dispatch.*
-/public/plugin_assets
-/tmp/*
-/tmp/cache/*
-/tmp/sessions/*
-/tmp/sockets/*
-/tmp/test/*
-/vendor/rails
-*.rbc
-
-/.bundle
-/Gemfile.lock
-/Gemfile.local
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f6/f6ef1fd188a246198832677eccb65f1bec39a729.svn-base
--- /dev/null
+++ b/.svn/pristine/f6/f6ef1fd188a246198832677eccb65f1bec39a729.svn-base
@@ -0,0 +1,59 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingAuthSourcesTest < ActionController::IntegrationTest
+  def test_auth_sources
+    assert_routing(
+        { :method => 'get', :path => "/auth_sources" },
+        { :controller => 'auth_sources', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/auth_sources/new" },
+        { :controller => 'auth_sources', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/auth_sources" },
+        { :controller => 'auth_sources', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/auth_sources/1234/edit" },
+        { :controller => 'auth_sources', :action => 'edit',
+          :id => '1234' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/auth_sources/1234" },
+        { :controller => 'auth_sources', :action => 'update',
+          :id => '1234' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/auth_sources/1234" },
+        { :controller => 'auth_sources', :action => 'destroy',
+          :id => '1234' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/auth_sources/1234/test_connection" },
+        { :controller => 'auth_sources', :action => 'test_connection',
+          :id => '1234' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/auth_sources/autocomplete_for_new_user" },
+        { :controller => 'auth_sources', :action => 'autocomplete_for_new_user' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f7/f71915a7023c35e460772e471f889ad3127c400c.svn-base
--- a/.svn/pristine/f7/f71915a7023c35e460772e471f889ad3127c400c.svn-base
+++ /dev/null
@@ -1,128 +0,0 @@
-// ** I18N
-
-// Calendar LT language
-// Author: Gediminas MuiÅ¾is, <gediminas.muizis@elgama.eu>
-// Encoding: UTF-8
-// Distributed under the same terms as the calendar itself.
-// Ver: 0.2
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Sekmadienis",
- "Pirmadienis",
- "Antradienis",
- "TreÄiadienis",
- "Ketvirtadienis",
- "Penktadienis",
- "Å eÅ¡tadienis",
- "Sekmadienis");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Sek",
- "Pir",
- "Ant",
- "Tre",
- "Ket",
- "Pen",
- "Å eÅ¡",
- "Sek");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 1;
-
-// full month names
-Calendar._MN = new Array
-("Sausis",
- "Vasaris",
- "Kovas",
- "Balandis",
- "GeguÅ¾Ä—",
- "BirÅ¾elis",
- "Liepa",
- "RudpjÅ«tis",
- "RugsÄ—jis",
- "Spalis",
- "Lapkritis",
- "Gruodis");
-
-// short month names
-Calendar._SMN = new Array
-("Sau",
- "Vas",
- "Kov",
- "Bal",
- "Geg",
- "BrÅ¾",
- "Lie",
- "Rgp",
- "Rgs",
- "Spl",
- "Lap",
- "Grd");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "Apie kalendoriÅ³";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Datos pasirinkimas:\n" +
-"- Naudoti \xab, \xbb mygtukus norint pasirinkti metus\n" +
-"- Naudoti " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " mygtukus norint pasirinkti mÄ—nesÄ¯\n" +
-"- PAlaikykite nuspaudÄ™ bet kurÄ¯ nygtukÄ… norÄ—dami iÅ¡kviesti greitÄ…jÄ¯ meniu.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Datos pasirinkimas:\n" +
-"- Paspaudus ant valandos ar minutÄ—s, jÅ³ reikÅ¡mÄ—s padidÄ—ja\n" +
-"- arba Shift-paspaudimas norint sumaÅ¾inti reikÅ¡mÄ™\n" +
-"- arba paspauskite ir tempkite norint greiÄiau keisti reikÅ¡mÄ™.";
-
-Calendar._TT["PREV_YEAR"] = "Ankst. metai (laikyti, norint iÅ¡kviesti meniu)";
-Calendar._TT["PREV_MONTH"] = "Ankst. mÄ—nuo (laikyti, norint iÅ¡kviesti meniu)";
-Calendar._TT["GO_TODAY"] = "Å iandien";
-Calendar._TT["NEXT_MONTH"] = "Kitas mÄ—nuo (laikyti, norint iÅ¡kviesti meniu)";
-Calendar._TT["NEXT_YEAR"] = "Kiti metai (laikyti, norint iÅ¡kviesti meniu)";
-Calendar._TT["SEL_DATE"] = "Pasirinkti datÄ…";
-Calendar._TT["DRAG_TO_MOVE"] = "Perkelkite pÄ—lyte";
-Calendar._TT["PART_TODAY"] = " (Å¡iandien)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "Rodyti %s pirmiau";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "UÅ¾daryti";
-Calendar._TT["TODAY"] = "Å iandien";
-Calendar._TT["TIME_PART"] = "(Shift-)Spausti ar tempti, norint pakeisti reikÅ¡mÄ™";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "sav";
-Calendar._TT["TIME"] = "Laikas:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f7/f72d15e7793c4539e89571293a216e4135d03c64.svn-base
--- a/.svn/pristine/f7/f72d15e7793c4539e89571293a216e4135d03c64.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
-module CodeRay
-module Encoders
-  
-  load :html
-  
-  # Wraps HTML output into a DIV element, using inline styles by default.
-  # 
-  # See Encoders::HTML for available options.
-  class Div < HTML
-    
-    FILE_EXTENSION = 'div.html'
-    
-    register_for :div
-    
-    DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
-      :css          => :style,
-      :wrap         => :div,
-      :line_numbers => false
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f7/f756220d88e0b1f85f12b2d05c2b0e7f2c78a4d3.svn-base
--- /dev/null
+++ b/.svn/pristine/f7/f756220d88e0b1f85f12b2d05c2b0e7f2c78a4d3.svn-base
@@ -0,0 +1,182 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../../test_helper', __FILE__)
+
+class Redmine::MenuManager::MapperTest < ActiveSupport::TestCase
+  context "Mapper#initialize" do
+    should "be tested"
+  end
+
+  def test_push_onto_root
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
+
+    menu_mapper.exists?(:test_overview)
+  end
+
+  def test_push_onto_parent
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
+
+    assert menu_mapper.exists?(:test_child)
+    assert_equal :test_child, menu_mapper.find(:test_child).name
+  end
+
+  def test_push_onto_grandparent
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
+    menu_mapper.push :test_grandchild, { :controller => 'projects', :action => 'show'}, {:parent => :test_child}
+
+    assert menu_mapper.exists?(:test_grandchild)
+    grandchild = menu_mapper.find(:test_grandchild)
+    assert_equal :test_grandchild, grandchild.name
+    assert_equal :test_child, grandchild.parent.name
+  end
+
+  def test_push_first
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {:first => true}
+
+    root = menu_mapper.find(:root)
+    assert_equal 5, root.children.size
+    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
+      assert_not_nil root.children[position]
+      assert_equal name, root.children[position].name
+    end
+
+  end
+
+  def test_push_before
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {:before => :test_fourth}
+
+    root = menu_mapper.find(:root)
+    assert_equal 5, root.children.size
+    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
+      assert_not_nil root.children[position]
+      assert_equal name, root.children[position].name
+    end
+
+  end
+
+  def test_push_after
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {:after => :test_third}
+
+    root = menu_mapper.find(:root)
+    assert_equal 5, root.children.size
+    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
+      assert_not_nil root.children[position]
+      assert_equal name, root.children[position].name
+    end
+
+  end
+
+  def test_push_last
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {:last => true}
+    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
+
+    root = menu_mapper.find(:root)
+    assert_equal 5, root.children.size
+    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
+      assert_not_nil root.children[position]
+      assert_equal name, root.children[position].name
+    end
+
+  end
+
+  def test_exists_for_child_node
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
+    menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview }
+
+    assert menu_mapper.exists?(:test_child)
+  end
+
+  def test_exists_for_invalid_node
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
+
+    assert !menu_mapper.exists?(:nothing)
+  end
+
+  def test_find
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
+
+    item = menu_mapper.find(:test_overview)
+    assert_equal :test_overview, item.name
+    assert_equal({:controller => 'projects', :action => 'show'}, item.url)
+  end
+
+  def test_find_missing
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
+
+    item = menu_mapper.find(:nothing)
+    assert_equal nil, item
+  end
+
+  def test_delete
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
+    assert_not_nil menu_mapper.delete(:test_overview)
+
+    assert_nil menu_mapper.find(:test_overview)
+  end
+
+  def test_delete_missing
+    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
+    assert_nil menu_mapper.delete(:test_missing)
+  end
+
+  test 'deleting all items' do
+    # Exposed by deleting :last items
+    Redmine::MenuManager.map :test_menu do |menu|
+      menu.push :not_last, Redmine::Info.help_url
+      menu.push :administration, { :controller => 'projects', :action => 'show'}, {:last => true}
+      menu.push :help, Redmine::Info.help_url, :last => true
+    end
+
+    assert_nothing_raised do
+      Redmine::MenuManager.map :test_menu do |menu|
+        menu.delete(:administration)
+        menu.delete(:help)
+        menu.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
+     end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f7/f758fe470e3cc5243a9e779c6dc8af90264614da.svn-base
--- a/.svn/pristine/f7/f758fe470e3cc5243a9e779c6dc8af90264614da.svn-base
+++ /dev/null
@@ -1,64 +0,0 @@
-= AwesomeNestedSet
-
-Awesome Nested Set is an implementation of the nested set pattern for ActiveRecord models. It is replacement for acts_as_nested_set and BetterNestedSet, but awesomer.
-
-== What makes this so awesome?
-
-This is a new implementation of nested set based off of BetterNestedSet that fixes some bugs, removes tons of duplication, adds a few useful methods, and adds STI support.
-
-== Installation
-
-If you are on Rails 2.1 or later:
-
-  script/plugin install git://github.com/collectiveidea/awesome_nested_set.git
-  
-== Usage
-
-To make use of awesome_nested_set, your model needs to have 3 fields: lft, rgt, and parent_id:
-
-  class CreateCategories < ActiveRecord::Migration
-    def self.up
-      create_table :categories do |t|
-        t.string :name
-        t.integer :parent_id
-        t.integer :lft
-        t.integer :rgt
-      end
-    end
-
-    def self.down
-      drop_table :categories
-    end
-  end
-
-Enable the nested set functionality by declaring acts_as_nested_set on your model
-
-  class Category < ActiveRecord::Base
-    acts_as_nested_set
-  end
-  
-Run `rake rdoc` to generate the API docs and see CollectiveIdea::Acts::NestedSet::SingletonMethods for more info.
-
-== View Helper
-
-The view helper is called #nested_set_options. 
-
-Example usage:
-
-  <%= f.select :parent_id, nested_set_options(Category, @category) {|i| "#{'-' * i.level} #{i.name}" } %>
-
-  <%= select_tag 'parent_id', options_for_select(nested_set_options(Category) {|i| "#{'-' * i.level} #{i.name}" } ) %>
-
-See CollectiveIdea::Acts::NestedSet::Helper for more information about the helpers.
-
-== References
-
-You can learn more about nested sets at:
-
-  http://www.dbmsmag.com/9603d06.html
-  http://threebit.net/tutorials/nestedset/tutorial1.html
-  http://api.rubyonrails.com/classes/ActiveRecord/Acts/NestedSet/ClassMethods.html
-  http://opensource.symetrie.com/trac/better_nested_set/
-
-
-Copyright (c) 2008 Collective Idea, released under the MIT license
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f7/f75cc0973adb64fe86bec853f1ce941fdd75f24d.svn-base
--- /dev/null
+++ b/.svn/pristine/f7/f75cc0973adb64fe86bec853f1ce941fdd75f24d.svn-base
@@ -0,0 +1,111 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class SearchController < ApplicationController
+  before_filter :find_optional_project
+
+  def index
+    @question = params[:q] || ""
+    @question.strip!
+    @all_words = params[:all_words] ? params[:all_words].present? : true
+    @titles_only = params[:titles_only] ? params[:titles_only].present? : false
+
+    projects_to_search =
+      case params[:scope]
+      when 'all'
+        nil
+      when 'my_projects'
+        User.current.memberships.collect(&:project)
+      when 'subprojects'
+        @project ? (@project.self_and_descendants.active.all) : nil
+      else
+        @project
+      end
+
+    offset = nil
+    begin; offset = params[:offset].to_time if params[:offset]; rescue; end
+
+    # quick jump to an issue
+    if (m = @question.match(/^#?(\d+)$/)) && (issue = Issue.visible.find_by_id(m[1].to_i))
+      redirect_to issue_path(issue)
+      return
+    end
+
+    @object_types = Redmine::Search.available_search_types.dup
+    if projects_to_search.is_a? Project
+      # don't search projects
+      @object_types.delete('projects')
+      # only show what the user is allowed to view
+      @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
+    end
+
+    @scope = @object_types.select {|t| params[t]}
+    @scope = @object_types if @scope.empty?
+
+    # extract tokens from the question
+    # eg. hello "bye bye" => ["hello", "bye bye"]
+    @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
+    # tokens must be at least 2 characters long
+    @tokens = @tokens.uniq.select {|w| w.length > 1 }
+
+    if !@tokens.empty?
+      # no more than 5 tokens to search for
+      @tokens.slice! 5..-1 if @tokens.size > 5
+
+      @results = []
+      @results_by_type = Hash.new {|h,k| h[k] = 0}
+
+      limit = 10
+      @scope.each do |s|
+        r, c = s.singularize.camelcase.constantize.search(@tokens, projects_to_search,
+          :all_words => @all_words,
+          :titles_only => @titles_only,
+          :limit => (limit+1),
+          :offset => offset,
+          :before => params[:previous].nil?)
+        @results += r
+        @results_by_type[s] += c
+      end
+      @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
+      if params[:previous].nil?
+        @pagination_previous_date = @results[0].event_datetime if offset && @results[0]
+        if @results.size > limit
+          @pagination_next_date = @results[limit-1].event_datetime
+          @results = @results[0, limit]
+        end
+      else
+        @pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
+        if @results.size > limit
+          @pagination_previous_date = @results[-(limit)].event_datetime
+          @results = @results[-(limit), limit]
+        end
+      end
+    else
+      @question = ""
+    end
+    render :layout => false if request.xhr?
+  end
+
+private
+  def find_optional_project
+    return true unless params[:id]
+    @project = Project.find(params[:id])
+    check_project_privacy
+  rescue ActiveRecord::RecordNotFound
+    render_404
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f7/f767b8d14c7249c0fabe9ba271f45b37cfcab811.svn-base
--- a/.svn/pristine/f7/f767b8d14c7249c0fabe9ba271f45b37cfcab811.svn-base
+++ /dev/null
@@ -1,60 +0,0 @@
-# Tests in this file ensure that:
-#
-# * plugin views are found
-# * views in the application take precedence over those in plugins
-# * views in subsequently loaded plugins take precendence over those in previously loaded plugins
-# * this works for namespaced views accordingly
-
-require File.dirname(__FILE__) + '/../test_helper'
-
-class ViewLoadingTest < ActionController::TestCase
-  def setup
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-  end
-
-  # plugin views should be found
-
- 	def test_WITH_a_view_defined_only_in_a_plugin_IT_should_find_the_view
-	  get_action_on_controller :a_view, :alpha_plugin
-    assert_response_body 'alpha_plugin/a_view'
-  end
-	
-	def test_WITH_a_namespaced_view_defined_only_in_a_plugin_IT_should_find_the_view
-	  get_action_on_controller :a_view, :alpha_plugin, :namespace
-    assert_response_body 'namespace/alpha_plugin/a_view'
-  end
-
-  # app takes precedence over plugins
-	
-	def test_WITH_a_view_defined_in_both_app_and_plugin_IT_should_find_the_one_in_app
-	  get_action_on_controller :a_view, :app_and_plugin
-    assert_response_body 'app_and_plugin/a_view (from app)'
-  end
-	
-	def test_WITH_a_namespaced_view_defined_in_both_app_and_plugin_IT_should_find_the_one_in_app
-	  get_action_on_controller :a_view, :app_and_plugin, :namespace
-    assert_response_body 'namespace/app_and_plugin/a_view (from app)'
-  end
-
-  # subsequently loaded plugins take precendence over previously loaded plugins
-	
-	def test_WITH_a_view_defined_in_two_plugins_IT_should_find_the_latter_of_both
-	  get_action_on_controller :a_view, :shared_plugin
-    assert_response_body 'shared_plugin/a_view (from beta_plugin)'
-  end
-	
-	def test_WITH_a_namespaced_view_defined_in_two_plugins_IT_should_find_the_latter_of_both
-	  get_action_on_controller :a_view, :shared_plugin, :namespace
-    assert_response_body 'namespace/shared_plugin/a_view (from beta_plugin)'
-  end
-  
-  # layouts loaded from plugins
-
-  def test_should_be_able_to_load_a_layout_from_a_plugin
-    get_action_on_controller :action_with_layout, :alpha_plugin
-    assert_response_body 'rendered in AlphaPluginController#action_with_layout (with plugin layout)'
-  end
-	
-end
-	
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f7/f78ddc144c31f10580290509649e50dda2f4e570.svn-base
--- /dev/null
+++ b/.svn/pristine/f7/f78ddc144c31f10580290509649e50dda2f4e570.svn-base
@@ -0,0 +1,139 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class JournalObserverTest < ActiveSupport::TestCase
+  fixtures :issues, :issue_statuses, :journals, :journal_details, :projects,
+           :projects_trackers, :trackers, :enabled_modules, :enumerations,
+           :users, :roles
+
+  def setup
+    ActionMailer::Base.deliveries.clear
+    @journal = Journal.find 1
+  end
+
+  # context: issue_updated notified_events
+  def test_create_should_send_email_notification_with_issue_updated
+    issue = Issue.first
+    user = User.first
+    journal = issue.init_journal(user, issue)
+
+    with_settings :notified_events => %w(issue_updated) do
+      assert journal.save
+    end
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_create_should_not_send_email_notification_with_notify_set_to_false
+    issue = Issue.first
+    user = User.first
+    journal = issue.init_journal(user, issue)
+    journal.notify = false
+
+    with_settings :notified_events => %w(issue_updated) do
+      assert journal.save
+    end
+    assert_equal 0, ActionMailer::Base.deliveries.size
+  end
+
+  def test_create_should_not_send_email_notification_without_issue_updated
+    issue = Issue.first
+    user = User.first
+    journal = issue.init_journal(user, issue)
+
+    with_settings :notified_events => [] do
+      assert journal.save
+    end
+    assert_equal 0, ActionMailer::Base.deliveries.size
+  end
+
+  # context: issue_note_added notified_events
+  def test_create_should_send_email_notification_with_issue_note_added
+    issue = Issue.first
+    user = User.first
+    journal = issue.init_journal(user, issue)
+    journal.notes = 'This update has a note'
+
+    with_settings :notified_events => %w(issue_note_added) do
+      assert journal.save
+    end
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_create_should_not_send_email_notification_without_issue_note_added
+    issue = Issue.first
+    user = User.first
+    journal = issue.init_journal(user, issue)
+    journal.notes = 'This update has a note'
+
+    with_settings :notified_events => [] do
+      assert journal.save
+    end
+    assert_equal 0, ActionMailer::Base.deliveries.size
+  end
+
+  # context: issue_status_updated notified_events
+  def test_create_should_send_email_notification_with_issue_status_updated
+    issue = Issue.first
+    user = User.first
+    issue.init_journal(user, issue)
+    issue.status = IssueStatus.last
+
+    with_settings :notified_events => %w(issue_status_updated) do
+      assert issue.save
+    end
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_create_should_not_send_email_notification_without_issue_status_updated
+    issue = Issue.first
+    user = User.first
+    issue.init_journal(user, issue)
+    issue.status = IssueStatus.last
+
+    with_settings :notified_events => [] do
+      assert issue.save
+    end
+    assert_equal 0, ActionMailer::Base.deliveries.size
+  end
+
+  # context: issue_priority_updated notified_events
+  def test_create_should_send_email_notification_with_issue_priority_updated
+    issue = Issue.first
+    user = User.first
+    issue.init_journal(user, issue)
+    issue.priority = IssuePriority.last
+
+    with_settings :notified_events => %w(issue_priority_updated) do
+      assert issue.save
+    end
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
+  def test_create_should_not_send_email_notification_without_issue_priority_updated
+    issue = Issue.first
+    user = User.first
+    issue.init_journal(user, issue)
+    issue.priority = IssuePriority.last
+
+    with_settings :notified_events => [] do
+      assert issue.save
+    end
+    assert_equal 0, ActionMailer::Base.deliveries.size
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f7/f7d49732b9c4387f067e29bcd9d719f802bacd6a.svn-base
--- a/.svn/pristine/f7/f7d49732b9c4387f067e29bcd9d719f802bacd6a.svn-base
+++ /dev/null
@@ -1,302 +0,0 @@
-require 'set'
-
-module CodeRay
-module Encoders
-  
-  # = HTML Encoder
-  #
-  # This is CodeRay's most important highlighter:
-  # It provides save, fast XHTML generation and CSS support.
-  #
-  # == Usage
-  #
-  #  require 'coderay'
-  #  puts CodeRay.scan('Some /code/', :ruby).html  #-> a HTML page
-  #  puts CodeRay.scan('Some /code/', :ruby).html(:wrap => :span)
-  #  #-> <span class="CodeRay"><span class="co">Some</span> /code/</span>
-  #  puts CodeRay.scan('Some /code/', :ruby).span  #-> the same
-  #  
-  #  puts CodeRay.scan('Some code', :ruby).html(
-  #    :wrap => nil,
-  #    :line_numbers => :inline,
-  #    :css => :style
-  #  )
-  #
-  # == Options
-  #
-  # === :tab_width
-  # Convert \t characters to +n+ spaces (a number.)
-  # 
-  # Default: 8
-  #
-  # === :css
-  # How to include the styles; can be :class or :style.
-  #
-  # Default: :class
-  #
-  # === :wrap
-  # Wrap in :page, :div, :span or nil.
-  #
-  # You can also use Encoders::Div and Encoders::Span.
-  #
-  # Default: nil
-  #
-  # === :title
-  # 
-  # The title of the HTML page (works only when :wrap is set to :page.)
-  #
-  # Default: 'CodeRay output'
-  #
-  # === :line_numbers
-  # Include line numbers in :table, :inline, or nil (no line numbers)
-  #
-  # Default: nil
-  #
-  # === :line_number_anchors
-  # Adds anchors and links to the line numbers. Can be false (off), true (on),
-  # or a prefix string that will be prepended to the anchor name.
-  #
-  # The prefix must consist only of letters, digits, and underscores.
-  #
-  # Default: true, default prefix name: "line"
-  #
-  # === :line_number_start
-  # Where to start with line number counting.
-  #
-  # Default: 1
-  #
-  # === :bold_every
-  # Make every +n+-th number appear bold.
-  #
-  # Default: 10
-  #
-  # === :highlight_lines
-  # 
-  # Highlights certain line numbers.
-  # Can be any Enumerable, typically just an Array or Range, of numbers.
-  # 
-  # Bolding is deactivated when :highlight_lines is set. It only makes sense
-  # in combination with :line_numbers.
-  #
-  # Default: nil
-  #
-  # === :hint
-  # Include some information into the output using the title attribute.
-  # Can be :info (show token kind on mouse-over), :info_long (with full path)
-  # or :debug (via inspect).
-  #
-  # Default: false
-  class HTML < Encoder
-    
-    register_for :html
-    
-    FILE_EXTENSION = 'snippet.html'
-    
-    DEFAULT_OPTIONS = {
-      :tab_width => 8,
-      
-      :css   => :class,
-      :style => :alpha,
-      :wrap  => nil,
-      :title => 'CodeRay output',
-      
-      :line_numbers        => nil,
-      :line_number_anchors => 'n',
-      :line_number_start   => 1,
-      :bold_every          => 10,
-      :highlight_lines     => nil,
-      
-      :hint => false,
-    }
-    
-    autoload :Output,    'coderay/encoders/html/output'
-    autoload :CSS,       'coderay/encoders/html/css'
-    autoload :Numbering, 'coderay/encoders/html/numbering'
-    
-    attr_reader :css
-    
-  protected
-    
-    HTML_ESCAPE = {  #:nodoc:
-      '&' => '&amp;',
-      '"' => '&quot;',
-      '>' => '&gt;',
-      '<' => '&lt;',
-    }
-    
-    # This was to prevent illegal HTML.
-    # Strange chars should still be avoided in codes.
-    evil_chars = Array(0x00...0x20) - [?\n, ?\t, ?\s]
-    evil_chars.each { |i| HTML_ESCAPE[i.chr] = ' ' }
-    #ansi_chars = Array(0x7f..0xff)
-    #ansi_chars.each { |i| HTML_ESCAPE[i.chr] = '&#%d;' % i }
-    # \x9 (\t) and \xA (\n) not included
-    #HTML_ESCAPE_PATTERN = /[\t&"><\0-\x8\xB-\x1f\x7f-\xff]/
-    HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1f]/
-    
-    TOKEN_KIND_TO_INFO = Hash.new do |h, kind|
-      h[kind] = kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
-    end
-    
-    TRANSPARENT_TOKEN_KINDS = Set[
-      :delimiter, :modifier, :content, :escape, :inline_delimiter,
-    ]
-    
-    # Generate a hint about the given +kinds+ in a +hint+ style.
-    #
-    # +hint+ may be :info, :info_long or :debug.
-    def self.token_path_to_hint hint, kinds
-      kinds = Array kinds
-      title =
-        case hint
-        when :info
-          kinds = kinds[1..-1] if TRANSPARENT_TOKEN_KINDS.include? kinds.first
-          TOKEN_KIND_TO_INFO[kinds.first]
-        when :info_long
-          kinds.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
-        when :debug
-          kinds.inspect
-        end
-      title ? " title=\"#{title}\"" : ''
-    end
-    
-    def setup options
-      super
-      
-      if options[:wrap] || options[:line_numbers]
-        @real_out = @out
-        @out = ''
-      end
-      
-      @HTML_ESCAPE = HTML_ESCAPE.dup
-      @HTML_ESCAPE["\t"] = ' ' * options[:tab_width]
-      
-      @opened = []
-      @last_opened = nil
-      @css = CSS.new options[:style]
-      
-      hint = options[:hint]
-      if hint && ![:debug, :info, :info_long].include?(hint)
-        raise ArgumentError, "Unknown value %p for :hint; \
-          expected :info, :info_long, :debug, false, or nil." % hint
-      end
-      
-      css_classes = TokenKinds
-      case options[:css]
-      when :class
-        @span_for_kind = Hash.new do |h, k|
-          if k.is_a? ::Symbol
-            kind = k_dup = k
-          else
-            kind = k.first
-            k_dup = k.dup
-          end
-          if kind != :space && (hint || css_class = css_classes[kind])
-            title = HTML.token_path_to_hint hint, k if hint
-            css_class ||= css_classes[kind]
-            h[k_dup] = "<span#{title}#{" class=\"#{css_class}\"" if css_class}>"
-          else
-            h[k_dup] = nil
-          end
-        end
-      when :style
-        @span_for_kind = Hash.new do |h, k|
-          kind = k.is_a?(Symbol) ? k : k.first
-          h[k.is_a?(Symbol) ? k : k.dup] =
-            if kind != :space && (hint || css_classes[kind])
-              title = HTML.token_path_to_hint hint, k if hint
-              style = @css.get_style Array(k).map { |c| css_classes[c] }
-              "<span#{title}#{" style=\"#{style}\"" if style}>"
-            end
-        end
-      else
-        raise ArgumentError, "Unknown value %p for :css." % options[:css]
-      end
-      
-      @set_last_opened = options[:hint] || options[:css] == :style
-    end
-    
-    def finish options
-      unless @opened.empty?
-        warn '%d tokens still open: %p' % [@opened.size, @opened] if $CODERAY_DEBUG
-        @out << '</span>' while @opened.pop
-        @last_opened = nil
-      end
-      
-      @out.extend Output
-      @out.css = @css
-      if options[:line_numbers]
-        Numbering.number! @out, options[:line_numbers], options
-      end
-      @out.wrap! options[:wrap]
-      @out.apply_title! options[:title]
-      
-      if defined?(@real_out) && @real_out
-        @real_out << @out
-        @out = @real_out
-      end
-      
-      super
-    end
-    
-  public
-    
-    def text_token text, kind
-      if text =~ /#{HTML_ESCAPE_PATTERN}/o
-        text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
-      end
-      if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
-        @out << style << text << '</span>'
-      else
-        @out << text
-      end
-    end
-    
-    # token groups, eg. strings
-    def begin_group kind
-      @out << (@span_for_kind[@last_opened ? [kind, *@opened] : kind] || '<span>')
-      @opened << kind
-      @last_opened = kind if @set_last_opened
-    end
-    
-    def end_group kind
-      if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
-        warn 'Malformed token stream: Trying to close a token (%p) ' \
-          'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
-      end
-      if @opened.pop
-        @out << '</span>'
-        @last_opened = @opened.last if @last_opened
-      end
-    end
-    
-    # whole lines to be highlighted, eg. a deleted line in a diff
-    def begin_line kind
-      if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
-        if style['class="']
-          @out << style.sub('class="', 'class="line ')
-        else
-          @out << style.sub('>', ' class="line">')
-        end
-      else
-        @out << '<span class="line">'
-      end
-      @opened << kind
-      @last_opened = kind if @options[:css] == :style
-    end
-    
-    def end_line kind
-      if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
-        warn 'Malformed token stream: Trying to close a line (%p) ' \
-          'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
-      end
-      if @opened.pop
-        @out << '</span>'
-        @last_opened = @opened.last if @last_opened
-      end
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f8/f85a0a8308f568f41116e7ba4ea3c465193b95f6.svn-base
--- a/.svn/pristine/f8/f85a0a8308f568f41116e7ba4ea3c465193b95f6.svn-base
+++ /dev/null
@@ -1,56 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class TimelogHelperTest < ActionView::TestCase
-  include TimelogHelper
-  include ActionView::Helpers::TextHelper
-  include ActionView::Helpers::DateHelper
-
-  fixtures :projects, :roles, :enabled_modules, :users,
-                      :repositories, :changesets,
-                      :trackers, :issue_statuses, :issues, :versions, :documents,
-                      :wikis, :wiki_pages, :wiki_contents,
-                      :boards, :messages,
-                      :attachments,
-                      :enumerations
-
-  def setup
-    super
-  end
-
-  def test_activities_collection_for_select_options_should_return_array_of_activity_names_and_ids
-    activities = activity_collection_for_select_options
-    assert activities.include?(["Design", 9])
-    assert activities.include?(["Development", 10])
-  end
-
-  def test_activities_collection_for_select_options_should_not_include_inactive_activities
-    activities = activity_collection_for_select_options
-    assert !activities.include?(["Inactive Activity", 14])
-  end
-
-  def test_activities_collection_for_select_options_should_use_the_projects_override
-    project = Project.find(1)
-    override_activity = TimeEntryActivity.create!({:name => "Design override", :parent => TimeEntryActivity.find_by_name("Design"), :project => project})
-
-    activities = activity_collection_for_select_options(nil, project)
-    assert !activities.include?(["Design", 9]), "System activity found in: " + activities.inspect
-    assert activities.include?(["Design override", override_activity.id]), "Override activity not found in: " + activities.inspect
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f8/f868e11e49aa1ebab883f07d048bd42ffcb7e3b1.svn-base
--- /dev/null
+++ b/.svn/pristine/f8/f868e11e49aa1ebab883f07d048bd42ffcb7e3b1.svn-base
@@ -0,0 +1,23 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class WikiRedirect < ActiveRecord::Base
+  belongs_to :wiki
+
+  validates_presence_of :title, :redirects_to
+  validates_length_of :title, :redirects_to, :maximum => 255
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f8/f890810254315df22a74b5e02dde109dedd9847a.svn-base
--- /dev/null
+++ b/.svn/pristine/f8/f890810254315df22a74b5e02dde109dedd9847a.svn-base
@@ -0,0 +1,22 @@
+class AddRepositoriesPermissions < ActiveRecord::Migration
+  # model removed
+  class Permission < ActiveRecord::Base; end
+
+  def self.up
+    Permission.create :controller => "repositories", :action => "show", :description => "button_view", :sort => 1450, :is_public => true
+    Permission.create :controller => "repositories", :action => "browse", :description => "label_browse", :sort => 1460, :is_public => true
+    Permission.create :controller => "repositories", :action => "entry", :description => "entry", :sort => 1462, :is_public => true
+    Permission.create :controller => "repositories", :action => "revisions", :description => "label_view_revisions", :sort => 1470, :is_public => true
+    Permission.create :controller => "repositories", :action => "revision", :description => "label_view_revisions", :sort => 1472, :is_public => true
+    Permission.create :controller => "repositories", :action => "diff", :description => "diff", :sort => 1480, :is_public => true
+  end
+
+  def self.down
+    Permission.where("controller=? and action=?", 'repositories', 'show').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'browse').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'entry').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'revisions').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'revision').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'diff').first.destroy
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f8/f897bedafc089b1fd8d90f9d7c464aac7a4e2491.svn-base
--- a/.svn/pristine/f8/f897bedafc089b1fd8d90f9d7c464aac7a4e2491.svn-base
+++ /dev/null
@@ -1,11 +0,0 @@
-begin
-  require('htmlentities') 
-rescue LoadError
-  # This gem is not required - just nice to have.
-end
-require('cgi')
-require 'rfpdf'
-
-# Mime::Type.register "application/pdf", :pdf
-ActionView::Template::register_template_handler 'rfpdf', RFPDF::TemplateHandlers::Base
-
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f8/f8dc8b2a006317a75e69425034f4d279286333a1.svn-base
--- a/.svn/pristine/f8/f8dc8b2a006317a75e69425034f4d279286333a1.svn-base
+++ /dev/null
@@ -1,152 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../../test_helper', __FILE__)
-
-class ApiTest::TimeEntriesTest < ActionController::IntegrationTest
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows,
-           :time_entries
-
-  def setup
-    Setting.rest_api_enabled = '1'
-  end
-
-  context "GET /time_entries.xml" do
-    should "return time entries" do
-      get '/time_entries.xml', {}, :authorization => credentials('jsmith')
-      assert_response :success
-      assert_equal 'application/xml', @response.content_type
-      assert_tag :tag => 'time_entries',
-        :child => {:tag => 'time_entry', :child => {:tag => 'id', :content => '2'}}
-    end
-
-    context "with limit" do
-      should "return limited results" do
-        get '/time_entries.xml?limit=2', {}, :authorization => credentials('jsmith')
-        assert_response :success
-        assert_equal 'application/xml', @response.content_type
-        assert_tag :tag => 'time_entries',
-          :children => {:count => 2}
-      end
-    end
-  end
-
-  context "GET /time_entries/2.xml" do
-    should "return requested time entry" do
-      get '/time_entries/2.xml', {}, :authorization => credentials('jsmith')
-      assert_response :success
-      assert_equal 'application/xml', @response.content_type
-      assert_tag :tag => 'time_entry',
-        :child => {:tag => 'id', :content => '2'}
-    end
-  end
-
-  context "POST /time_entries.xml" do
-    context "with issue_id" do
-      should "return create time entry" do
-        assert_difference 'TimeEntry.count' do
-          post '/time_entries.xml', {:time_entry => {:issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, :authorization => credentials('jsmith')
-        end
-        assert_response :created
-        assert_equal 'application/xml', @response.content_type
-
-        entry = TimeEntry.first(:order => 'id DESC')
-        assert_equal 'jsmith', entry.user.login
-        assert_equal Issue.find(1), entry.issue
-        assert_equal Project.find(1), entry.project
-        assert_equal Date.parse('2010-12-02'), entry.spent_on
-        assert_equal 3.5, entry.hours
-        assert_equal TimeEntryActivity.find(11), entry.activity
-      end
-    end
-
-    context "with project_id" do
-      should "return create time entry" do
-        assert_difference 'TimeEntry.count' do
-          post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, :authorization => credentials('jsmith')
-        end
-        assert_response :created
-        assert_equal 'application/xml', @response.content_type
-
-        entry = TimeEntry.first(:order => 'id DESC')
-        assert_equal 'jsmith', entry.user.login
-        assert_nil entry.issue
-        assert_equal Project.find(1), entry.project
-        assert_equal Date.parse('2010-12-02'), entry.spent_on
-        assert_equal 3.5, entry.hours
-        assert_equal TimeEntryActivity.find(11), entry.activity
-      end
-    end
-
-    context "with invalid parameters" do
-      should "return errors" do
-        assert_no_difference 'TimeEntry.count' do
-          post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :activity_id => '11'}}, :authorization => credentials('jsmith')
-        end
-        assert_response :unprocessable_entity
-        assert_equal 'application/xml', @response.content_type
-
-        assert_tag 'errors', :child => {:tag => 'error', :content => "Hours can't be blank"}
-      end
-    end
-  end
-
-  context "PUT /time_entries/2.xml" do
-    context "with valid parameters" do
-      should "update time entry" do
-        assert_no_difference 'TimeEntry.count' do
-          put '/time_entries/2.xml', {:time_entry => {:comments => 'API Update'}}, :authorization => credentials('jsmith')
-        end
-        assert_response :ok
-        assert_equal 'API Update', TimeEntry.find(2).comments
-      end
-    end
-
-    context "with invalid parameters" do
-      should "return errors" do
-        assert_no_difference 'TimeEntry.count' do
-          put '/time_entries/2.xml', {:time_entry => {:hours => '', :comments => 'API Update'}}, :authorization => credentials('jsmith')
-        end
-        assert_response :unprocessable_entity
-        assert_equal 'application/xml', @response.content_type
-
-        assert_tag 'errors', :child => {:tag => 'error', :content => "Hours can't be blank"}
-      end
-    end
-  end
-
-  context "DELETE /time_entries/2.xml" do
-    should "destroy time entry" do
-      assert_difference 'TimeEntry.count', -1 do
-        delete '/time_entries/2.xml', {}, :authorization => credentials('jsmith')
-      end
-      assert_response :ok
-      assert_nil TimeEntry.find_by_id(2)
-    end
-  end
-
-  def credentials(user, password=nil)
-    ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f8/f8e3393c3af527d599685daf189e7b5311a95a64.svn-base
--- /dev/null
+++ b/.svn/pristine/f8/f8e3393c3af527d599685daf189e7b5311a95a64.svn-base
@@ -0,0 +1,72 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::JsonpTest < Redmine::ApiTest::Base
+  fixtures :trackers
+
+  def test_should_ignore_jsonp_callback_with_jsonp_disabled
+    with_settings :jsonp_enabled => '0' do
+      get '/trackers.json?jsonp=handler'
+    end
+
+    assert_response :success
+    assert_match %r{^\{"trackers":.+\}$}, response.body
+    assert_equal 'application/json; charset=utf-8', response.headers['Content-Type']
+  end
+
+  def test_jsonp_should_accept_callback_param
+    with_settings :jsonp_enabled => '1' do
+      get '/trackers.json?callback=handler'
+    end
+
+    assert_response :success
+    assert_match %r{^handler\(\{"trackers":.+\}\)$}, response.body
+    assert_equal 'application/javascript; charset=utf-8', response.headers['Content-Type']
+  end
+
+  def test_jsonp_should_accept_jsonp_param
+    with_settings :jsonp_enabled => '1' do
+      get '/trackers.json?jsonp=handler'
+    end
+
+    assert_response :success
+    assert_match %r{^handler\(\{"trackers":.+\}\)$}, response.body
+    assert_equal 'application/javascript; charset=utf-8', response.headers['Content-Type']
+  end
+
+  def test_jsonp_should_strip_invalid_characters_from_callback
+    with_settings :jsonp_enabled => '1' do
+      get '/trackers.json?callback=+-aA$1_'
+    end
+
+    assert_response :success
+    assert_match %r{^aA1_\(\{"trackers":.+\}\)$}, response.body
+    assert_equal 'application/javascript; charset=utf-8', response.headers['Content-Type']
+  end
+
+  def test_jsonp_without_callback_should_return_json
+    with_settings :jsonp_enabled => '1' do
+      get '/trackers.json?callback='
+    end
+
+    assert_response :success
+    assert_match %r{^\{"trackers":.+\}$}, response.body
+    assert_equal 'application/json; charset=utf-8', response.headers['Content-Type']
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f9/f992af412d2338b0910671c99f9c86c6772cdf7c.svn-base
--- /dev/null
+++ b/.svn/pristine/f9/f992af412d2338b0910671c99f9c86c6772cdf7c.svn-base
@@ -0,0 +1,45 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/views/builders/structure'
+
+module Redmine
+  module Views
+    module Builders
+      class Json < Structure
+        attr_accessor :jsonp
+
+        def initialize(request, response)
+          super
+          callback = request.params[:callback] || request.params[:jsonp]
+          if callback && Setting.jsonp_enabled?
+            self.jsonp = callback.to_s.gsub(/[^a-zA-Z0-9_]/, '')
+          end
+        end
+
+        def output
+          json = @struct.first.to_json
+          if jsonp.present?
+            json = "#{jsonp}(#{json})"
+            response.content_type = 'application/javascript'
+          end
+          json
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f9/f9aeb8c692c8cedd603babe04b14a070c2aa1c72.svn-base
--- a/.svn/pristine/f9/f9aeb8c692c8cedd603babe04b14a070c2aa1c72.svn-base
+++ /dev/null
@@ -1,23 +0,0 @@
---- 
-changes_001: 
-  id: 1
-  changeset_id: 100
-  action: A
-  path: /test/some/path/in/the/repo
-  from_path:
-  from_revision:
-changes_002: 
-  id: 2
-  changeset_id: 100
-  action: A
-  path: /test/some/path/elsewhere/in/the/repo
-  from_path:
-  from_revision:
-changes_003: 
-  id: 3
-  changeset_id: 101
-  action: M
-  path: /test/some/path/in/the/repo
-  from_path:
-  from_revision:
-  
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/f9/f9b3f76db9f5a36a5f6043baf3d5f6ff7ea59433.svn-base
--- /dev/null
+++ b/.svn/pristine/f9/f9b3f76db9f5a36a5f6043baf3d5f6ff7ea59433.svn-base
@@ -0,0 +1,25 @@
+# HG changeset patch
+# User tmaruyama
+# Date 1362559296 0
+# Node ID ee54942e0289c30bea1b1973750b698b1ee7c466
+# Parent  738777832f379f6f099c25251593fc57bc17f586
+fix some Japanese "issue" translations (#13350)
+
+Contributed by Go MAEDA.
+
+diff --git a/config/locales/ja.yml b/config/locales/ja.yml
+--- a/config/locales/ja.yml
++++ b/config/locales/ja.yml
+@@ -904,9 +904,9 @@ ja:
+   text_journal_set_to: "%{label} ã‚’ %{value} ã«ã‚»ãƒƒãƒˆ"
+   text_journal_deleted: "%{label} ã‚’å‰Šé™¤ (%{old})"
+   text_journal_added: "%{label} %{value} ã‚’è¿½åŠ "
+-  text_tip_issue_begin_day: ã“ã®æ—¥ã«é–‹å§‹ã™ã‚‹ã‚¿ã‚¹ã‚¯
+-  text_tip_issue_end_day: ã“ã®æ—¥ã«çµ‚äº†ã™ã‚‹ã‚¿ã‚¹ã‚¯
+-  text_tip_issue_begin_end_day: ã“ã®æ—¥ã®ã†ã¡ã«é–‹å§‹ã—ã¦çµ‚äº†ã™ã‚‹ã‚¿ã‚¹ã‚¯
++  text_tip_issue_begin_day: ã“ã®æ—¥ã«é–‹å§‹ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
++  text_tip_issue_end_day: ã“ã®æ—¥ã«çµ‚äº†ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
++  text_tip_issue_begin_end_day: ã“ã®æ—¥ã«é–‹å§‹ãƒ»çµ‚äº†ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
+   text_caracters_maximum: "æœ€å¤§%{count}æ–‡å­—ã§ã™ã€‚"
+   text_caracters_minimum: "æœ€ä½Ž%{count}æ–‡å­—ã®é•·ã•ãŒå¿…è¦ã§ã™"
+   text_length_between: "é•·ã•ã¯%{min}ã‹ã‚‰%{max}æ–‡å­—ã¾ã§ã§ã™ã€‚"
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fa/fa1ed3a060024a3911e7dcef012f4c68185e0ea3.svn-base
--- /dev/null
+++ b/.svn/pristine/fa/fa1ed3a060024a3911e7dcef012f4c68185e0ea3.svn-base
@@ -0,0 +1,116 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class BoardTest < ActiveSupport::TestCase
+  fixtures :projects, :boards, :messages, :attachments, :watchers
+
+  include Redmine::I18n
+
+  def setup
+    @project = Project.find(1)
+  end
+
+  def test_create
+    board = Board.new(:project => @project, :name => 'Test board', :description => 'Test board description')
+    assert board.save
+    board.reload
+    assert_equal 'Test board', board.name
+    assert_equal 'Test board description', board.description
+    assert_equal @project, board.project
+    assert_equal 0, board.topics_count
+    assert_equal 0, board.messages_count
+    assert_nil board.last_message
+    # last position
+    assert_equal @project.boards.size, board.position
+  end
+
+  def test_parent_should_be_in_same_project
+    set_language_if_valid 'en'
+    board = Board.new(:project_id => 3, :name => 'Test', :description => 'Test', :parent_id => 1)
+    assert !board.save
+    assert_include "Parent forum is invalid", board.errors.full_messages
+  end
+
+  def test_valid_parents_should_not_include_self_nor_a_descendant
+    board1 = Board.generate!(:project_id => 3)
+    board2 = Board.generate!(:project_id => 3, :parent => board1)
+    board3 = Board.generate!(:project_id => 3, :parent => board2)
+    board4 = Board.generate!(:project_id => 3)
+
+    assert_equal [board4], board1.reload.valid_parents.sort_by(&:id)
+    assert_equal [board1, board4], board2.reload.valid_parents.sort_by(&:id)
+    assert_equal [board1, board2, board4], board3.reload.valid_parents.sort_by(&:id)
+    assert_equal [board1, board2, board3], board4.reload.valid_parents.sort_by(&:id)
+  end
+
+  def test_position_should_be_assigned_with_parent_scope
+    parent1 = Board.generate!(:project_id => 3)
+    parent2 = Board.generate!(:project_id => 3)
+    child1 = Board.generate!(:project_id => 3, :parent => parent1)
+    child2 = Board.generate!(:project_id => 3, :parent => parent1)
+
+    assert_equal 1, parent1.reload.position
+    assert_equal 1, child1.reload.position
+    assert_equal 2, child2.reload.position
+    assert_equal 2, parent2.reload.position
+  end
+
+  def test_board_tree_should_yield_boards_with_level
+    parent1 = Board.generate!(:project_id => 3)
+    parent2 = Board.generate!(:project_id => 3)
+    child1 = Board.generate!(:project_id => 3, :parent => parent1)
+    child2 = Board.generate!(:project_id => 3, :parent => parent1)
+    child3 = Board.generate!(:project_id => 3, :parent => child1)
+
+    tree = Board.board_tree(Project.find(3).boards)
+
+    assert_equal [
+      [parent1, 0],
+      [child1,  1],
+      [child3,  2],
+      [child2,  1],
+      [parent2, 0]
+    ], tree
+  end
+
+  def test_destroy
+    board = Board.find(1)
+    assert_difference 'Message.count', -6 do
+      assert_difference 'Attachment.count', -1 do
+        assert_difference 'Watcher.count', -1 do
+          assert board.destroy
+        end
+      end
+    end
+    assert_equal 0, Message.count(:conditions => {:board_id => 1})
+  end
+
+  def test_destroy_should_nullify_children
+    parent = Board.generate!(:project => @project)
+    child = Board.generate!(:project => @project, :parent => parent)
+    assert_equal parent, child.parent
+
+    assert parent.destroy
+    child.reload
+    assert_nil child.parent
+    assert_nil child.parent_id
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fa/faa06e26aeea9f7627ae814543492f9d35051460.svn-base
--- /dev/null
+++ b/.svn/pristine/fa/faa06e26aeea9f7627ae814543492f9d35051460.svn-base
@@ -0,0 +1,55 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module SyntaxHighlighting
+
+    class << self
+      attr_reader :highlighter
+      delegate :highlight_by_filename, :highlight_by_language, :to => :highlighter
+
+      def highlighter=(name)
+        if name.is_a?(Module)
+          @highlighter = name
+        else
+          @highlighter = const_get(name)
+        end
+      end
+    end
+
+    module CodeRay
+      require 'coderay'
+
+      class << self
+        # Highlights +text+ as the content of +filename+
+        # Should not return line numbers nor outer pre tag
+        def highlight_by_filename(text, filename)
+          language = ::CodeRay::FileType[filename]
+          language ? ::CodeRay.scan(text, language).html(:break_lines => true) : ERB::Util.h(text)
+        end
+
+        # Highlights +text+ using +language+ syntax
+        # Should not return outer pre tag
+        def highlight_by_language(text, language)
+          ::CodeRay.scan(text, language).html(:wrap => :span)
+        end
+      end
+    end
+  end
+
+  SyntaxHighlighting.highlighter = 'CodeRay'
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fa/fab553c0a3c9a998f2e8320cf6ed96e7fb3e898d.svn-base
--- /dev/null
+++ b/.svn/pristine/fa/fab553c0a3c9a998f2e8320cf6ed96e7fb3e898d.svn-base
@@ -0,0 +1,38 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class TimeEntryActivity < Enumeration
+  has_many :time_entries, :foreign_key => 'activity_id'
+
+  OptionName = :enumeration_activities
+
+  def option_name
+    OptionName
+  end
+
+  def objects
+    TimeEntry.where(:activity_id => self_and_descendants(1).map(&:id))
+  end
+
+  def objects_count
+    objects.count
+  end
+
+  def transfer_relations(to)
+    objects.update_all(:activity_id => to.id)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fa/fae6aa29a415564c269ced790046953485df6633.svn-base
--- /dev/null
+++ b/.svn/pristine/fa/fae6aa29a415564c269ced790046953485df6633.svn-base
@@ -0,0 +1,27 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::InfoTest < ActiveSupport::TestCase
+  def test_environment
+    env = Redmine::Info.environment
+
+    assert_kind_of String, env
+    assert_match 'Redmine version', env
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fa/fafc777bb67f933889320268007fe8033f0b89cb.svn-base
--- a/.svn/pristine/fa/fafc777bb67f933889320268007fe8033f0b89cb.svn-base
+++ /dev/null
@@ -1,225 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require 'diff'
-require 'enumerator'
-
-class WikiPage < ActiveRecord::Base
-  belongs_to :wiki
-  has_one :content, :class_name => 'WikiContent', :foreign_key => 'page_id', :dependent => :destroy
-  acts_as_attachable :delete_permission => :delete_wiki_pages_attachments
-  acts_as_tree :dependent => :nullify, :order => 'title'
-
-  acts_as_watchable
-  acts_as_event :title => Proc.new {|o| "#{l(:label_wiki)}: #{o.title}"},
-                :description => :text,
-                :datetime => :created_on,
-                :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.wiki.project, :id => o.title}}
-
-  acts_as_searchable :columns => ['title', "#{WikiContent.table_name}.text"],
-                     :include => [{:wiki => :project}, :content],
-                     :permission => :view_wiki_pages,
-                     :project_key => "#{Wiki.table_name}.project_id"
-
-  attr_accessor :redirect_existing_links
-
-  validates_presence_of :title
-  validates_format_of :title, :with => /^[^,\.\/\?\;\|\s]*$/
-  validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false
-  validates_associated :content
-
-  validate :validate_parent_title
-  before_destroy :remove_redirects
-  before_save    :handle_redirects
-
-  # eager load information about last updates, without loading text
-  named_scope :with_updated_on, {
-    :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
-    :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id"
-  }
-
-  # Wiki pages that are protected by default
-  DEFAULT_PROTECTED_PAGES = %w(sidebar)
-
-  def after_initialize
-    if new_record? && DEFAULT_PROTECTED_PAGES.include?(title.to_s.downcase)
-      self.protected = true
-    end
-  end
-
-  def visible?(user=User.current)
-    !user.nil? && user.allowed_to?(:view_wiki_pages, project)
-  end
-
-  def title=(value)
-    value = Wiki.titleize(value)
-    @previous_title = read_attribute(:title) if @previous_title.blank?
-    write_attribute(:title, value)
-  end
-
-  def handle_redirects
-    self.title = Wiki.titleize(title)
-    # Manage redirects if the title has changed
-    if !@previous_title.blank? && (@previous_title != title) && !new_record?
-      # Update redirects that point to the old title
-      wiki.redirects.find_all_by_redirects_to(@previous_title).each do |r|
-        r.redirects_to = title
-        r.title == r.redirects_to ? r.destroy : r.save
-      end
-      # Remove redirects for the new title
-      wiki.redirects.find_all_by_title(title).each(&:destroy)
-      # Create a redirect to the new title
-      wiki.redirects << WikiRedirect.new(:title => @previous_title, :redirects_to => title) unless redirect_existing_links == "0"
-      @previous_title = nil
-    end
-  end
-
-  def remove_redirects
-    # Remove redirects to this page
-    wiki.redirects.find_all_by_redirects_to(title).each(&:destroy)
-  end
-
-  def pretty_title
-    WikiPage.pretty_title(title)
-  end
-
-  def content_for_version(version=nil)
-    result = content.versions.find_by_version(version.to_i) if version
-    result ||= content
-    result
-  end
-
-  def diff(version_to=nil, version_from=nil)
-    version_to = version_to ? version_to.to_i : self.content.version
-    version_from = version_from ? version_from.to_i : version_to - 1
-    version_to, version_from = version_from, version_to unless version_from < version_to
-
-    content_to = content.versions.find_by_version(version_to)
-    content_from = content.versions.find_by_version(version_from)
-
-    (content_to && content_from) ? WikiDiff.new(content_to, content_from) : nil
-  end
-
-  def annotate(version=nil)
-    version = version ? version.to_i : self.content.version
-    c = content.versions.find_by_version(version)
-    c ? WikiAnnotate.new(c) : nil
-  end
-
-  def self.pretty_title(str)
-    (str && str.is_a?(String)) ? str.tr('_', ' ') : str
-  end
-
-  def project
-    wiki.project
-  end
-
-  def text
-    content.text if content
-  end
-
-  def updated_on
-    unless @updated_on
-      if time = read_attribute(:updated_on)
-        # content updated_on was eager loaded with the page
-        @updated_on = Time.parse(time) rescue nil
-      else
-        @updated_on = content && content.updated_on
-      end
-    end
-    @updated_on
-  end
-
-  # Returns true if usr is allowed to edit the page, otherwise false
-  def editable_by?(usr)
-    !protected? || usr.allowed_to?(:protect_wiki_pages, wiki.project)
-  end
-
-  def attachments_deletable?(usr=User.current)
-    editable_by?(usr) && super(usr)
-  end
-
-  def parent_title
-    @parent_title || (self.parent && self.parent.pretty_title)
-  end
-
-  def parent_title=(t)
-    @parent_title = t
-    parent_page = t.blank? ? nil : self.wiki.find_page(t)
-    self.parent = parent_page
-  end
-
-  protected
-
-  def validate_parent_title
-    errors.add(:parent_title, :invalid) if !@parent_title.blank? && parent.nil?
-    errors.add(:parent_title, :circular_dependency) if parent && (parent == self || parent.ancestors.include?(self))
-    errors.add(:parent_title, :not_same_project) if parent && (parent.wiki_id != wiki_id)
-  end
-end
-
-class WikiDiff < Redmine::Helpers::Diff
-  attr_reader :content_to, :content_from
-
-  def initialize(content_to, content_from)
-    @content_to = content_to
-    @content_from = content_from
-    super(content_to.text, content_from.text)
-  end
-end
-
-class WikiAnnotate
-  attr_reader :lines, :content
-
-  def initialize(content)
-    @content = content
-    current = content
-    current_lines = current.text.split(/\r?\n/)
-    @lines = current_lines.collect {|t| [nil, nil, t]}
-    positions = []
-    current_lines.size.times {|i| positions << i}
-    while (current.previous)
-      d = current.previous.text.split(/\r?\n/).diff(current.text.split(/\r?\n/)).diffs.flatten
-      d.each_slice(3) do |s|
-        sign, line = s[0], s[1]
-        if sign == '+' && positions[line] && positions[line] != -1
-          if @lines[positions[line]][0].nil?
-            @lines[positions[line]][0] = current.version
-            @lines[positions[line]][1] = current.author
-          end
-        end
-      end
-      d.each_slice(3) do |s|
-        sign, line = s[0], s[1]
-        if sign == '-'
-          positions.insert(line, -1)
-        else
-          positions[line] = nil
-        end
-      end
-      positions.compact!
-      # Stop if every line is annotated
-      break unless @lines.detect { |line| line[0].nil? }
-      current = current.previous
-    end
-    @lines.each { |line|
-      line[0] ||= current.version
-      # if the last known version is > 1 (eg. history was cleared), we don't know the author
-      line[1] ||= current.author if current.version == 1
-    }
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fb/fb0370610c36e942e95f18248151b66c8bb1d28d.svn-base
--- /dev/null
+++ b/.svn/pristine/fb/fb0370610c36e942e95f18248151b66c8bb1d28d.svn-base
@@ -0,0 +1,147 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class JournalsControllerTest < ActionController::TestCase
+  fixtures :projects, :users, :members, :member_roles, :roles, :issues, :journals, :journal_details, :enabled_modules,
+    :trackers, :issue_statuses, :enumerations, :custom_fields, :custom_values, :custom_fields_projects
+
+  def setup
+    User.current = nil
+  end
+
+  def test_index
+    get :index, :project_id => 1
+    assert_response :success
+    assert_not_nil assigns(:journals)
+    assert_equal 'application/atom+xml', @response.content_type
+  end
+
+  def test_index_should_return_privates_notes_with_permission_only
+    journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
+    @request.session[:user_id] = 2
+
+    get :index, :project_id => 1
+    assert_response :success
+    assert_include journal, assigns(:journals)
+
+    Role.find(1).remove_permission! :view_private_notes
+    get :index, :project_id => 1
+    assert_response :success
+    assert_not_include journal, assigns(:journals)
+  end
+
+  def test_diff
+    get :diff, :id => 3, :detail_id => 4
+    assert_response :success
+    assert_template 'diff'
+
+    assert_tag 'span',
+      :attributes => {:class => 'diff_out'},
+      :content => /removed/
+    assert_tag 'span',
+      :attributes => {:class => 'diff_in'},
+      :content => /added/
+  end
+
+  def test_reply_to_issue
+    @request.session[:user_id] = 2
+    xhr :get, :new, :id => 6
+    assert_response :success
+    assert_template 'new'
+    assert_equal 'text/javascript', response.content_type
+    assert_include '> This is an issue', response.body
+  end
+
+  def test_reply_to_issue_without_permission
+    @request.session[:user_id] = 7
+    xhr :get, :new, :id => 6
+    assert_response 403
+  end
+
+  def test_reply_to_note
+    @request.session[:user_id] = 2
+    xhr :get, :new, :id => 6, :journal_id => 4
+    assert_response :success
+    assert_template 'new'
+    assert_equal 'text/javascript', response.content_type
+    assert_include '> A comment with a private version', response.body
+  end
+
+  def test_reply_to_private_note_should_fail_without_permission
+    journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true)
+    @request.session[:user_id] = 2
+
+    xhr :get, :new, :id => 2, :journal_id => journal.id
+    assert_response :success
+    assert_template 'new'
+    assert_equal 'text/javascript', response.content_type
+    assert_include '> Privates notes', response.body
+
+    Role.find(1).remove_permission! :view_private_notes
+    xhr :get, :new, :id => 2, :journal_id => journal.id
+    assert_response 404
+  end
+
+  def test_edit_xhr
+    @request.session[:user_id] = 1
+    xhr :get, :edit, :id => 2
+    assert_response :success
+    assert_template 'edit'
+    assert_equal 'text/javascript', response.content_type
+    assert_include 'textarea', response.body
+  end
+
+  def test_edit_private_note_should_fail_without_permission
+    journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true)
+    @request.session[:user_id] = 2
+    Role.find(1).add_permission! :edit_issue_notes
+
+    xhr :get, :edit, :id => journal.id
+    assert_response :success
+    assert_template 'edit'
+    assert_equal 'text/javascript', response.content_type
+    assert_include 'textarea', response.body
+
+    Role.find(1).remove_permission! :view_private_notes
+    xhr :get, :edit, :id => journal.id
+    assert_response 404
+  end
+
+  def test_update_xhr
+    @request.session[:user_id] = 1
+    xhr :post, :edit, :id => 2, :notes => 'Updated notes'
+    assert_response :success
+    assert_template 'update'
+    assert_equal 'text/javascript', response.content_type
+    assert_equal 'Updated notes', Journal.find(2).notes
+    assert_include 'journal-2-notes', response.body
+  end
+
+  def test_update_xhr_with_empty_notes_should_delete_the_journal
+    @request.session[:user_id] = 1
+    assert_difference 'Journal.count', -1 do
+      xhr :post, :edit, :id => 2, :notes => ''
+      assert_response :success
+      assert_template 'update'
+      assert_equal 'text/javascript', response.content_type
+    end
+    assert_nil Journal.find_by_id(2)
+    assert_include 'change-2', response.body
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fb/fb44c6e118ba1da9fa2fdfb5c015150a0c9a67d4.svn-base
--- /dev/null
+++ b/.svn/pristine/fb/fb44c6e118ba1da9fa2fdfb5c015150a0c9a67d4.svn-base
@@ -0,0 +1,1244 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'forwardable'
+require 'cgi'
+
+module ApplicationHelper
+  include Redmine::WikiFormatting::Macros::Definitions
+  include Redmine::I18n
+  include GravatarHelper::PublicMethods
+  include Redmine::Pagination::Helper
+
+  extend Forwardable
+  def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
+
+  # Return true if user is authorized for controller/action, otherwise false
+  def authorize_for(controller, action)
+    User.current.allowed_to?({:controller => controller, :action => action}, @project)
+  end
+
+  # Display a link if user is authorized
+  #
+  # @param [String] name Anchor text (passed to link_to)
+  # @param [Hash] options Hash params. This will checked by authorize_for to see if the user is authorized
+  # @param [optional, Hash] html_options Options passed to link_to
+  # @param [optional, Hash] parameters_for_method_reference Extra parameters for link_to
+  def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
+    link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
+  end
+
+  # Displays a link to user's account page if active
+  def link_to_user(user, options={})
+    if user.is_a?(User)
+      name = h(user.name(options[:format]))
+      if user.active? || (User.current.admin? && user.logged?)
+        link_to name, user_path(user), :class => user.css_classes
+      else
+        name
+      end
+    else
+      h(user.to_s)
+    end
+  end
+
+  # Displays a link to +issue+ with its subject.
+  # Examples:
+  #
+  #   link_to_issue(issue)                        # => Defect #6: This is the subject
+  #   link_to_issue(issue, :truncate => 6)        # => Defect #6: This i...
+  #   link_to_issue(issue, :subject => false)     # => Defect #6
+  #   link_to_issue(issue, :project => true)      # => Foo - Defect #6
+  #   link_to_issue(issue, :subject => false, :tracker => false)     # => #6
+  #
+  def link_to_issue(issue, options={})
+    title = nil
+    subject = nil
+    text = options[:tracker] == false ? "##{issue.id}" : "#{issue.tracker} ##{issue.id}"
+    if options[:subject] == false
+      title = truncate(issue.subject, :length => 60)
+    else
+      subject = issue.subject
+      if options[:truncate]
+        subject = truncate(subject, :length => options[:truncate])
+      end
+    end
+    s = link_to text, issue_path(issue), :class => issue.css_classes, :title => title
+    s << h(": #{subject}") if subject
+    s = h("#{issue.project} - ") + s if options[:project]
+    s
+  end
+
+  # Generates a link to an attachment.
+  # Options:
+  # * :text - Link text (default to attachment filename)
+  # * :download - Force download (default: false)
+  def link_to_attachment(attachment, options={})
+    text = options.delete(:text) || attachment.filename
+    route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path
+    html_options = options.slice!(:only_path)
+    url = send(route_method, attachment, attachment.filename, options)
+    link_to text, url, html_options
+  end
+
+  # Generates a link to a SCM revision
+  # Options:
+  # * :text - Link text (default to the formatted revision)
+  def link_to_revision(revision, repository, options={})
+    if repository.is_a?(Project)
+      repository = repository.repository
+    end
+    text = options.delete(:text) || format_revision(revision)
+    rev = revision.respond_to?(:identifier) ? revision.identifier : revision
+    link_to(
+        h(text),
+        {:controller => 'repositories', :action => 'revision', :id => repository.project, :repository_id => repository.identifier_param, :rev => rev},
+        :title => l(:label_revision_id, format_revision(revision))
+      )
+  end
+
+  # Generates a link to a message
+  def link_to_message(message, options={}, html_options = nil)
+    link_to(
+      truncate(message.subject, :length => 60),
+      board_message_path(message.board_id, message.parent_id || message.id, {
+        :r => (message.parent_id && message.id),
+        :anchor => (message.parent_id ? "message-#{message.id}" : nil)
+      }.merge(options)),
+      html_options
+    )
+  end
+
+  # Generates a link to a project if active
+  # Examples:
+  #
+  #   link_to_project(project)                          # => link to the specified project overview
+  #   link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options
+  #   link_to_project(project, {}, :class => "project") # => html options with default url (project overview)
+  #
+  def link_to_project(project, options={}, html_options = nil)
+    if project.archived?
+      h(project.name)
+    elsif options.key?(:action)
+      ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0."
+      url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
+      link_to project.name, url, html_options
+    else
+      link_to project.name, project_path(project, options), html_options
+    end
+  end
+
+  # Generates a link to a project settings if active
+  def link_to_project_settings(project, options={}, html_options=nil)
+    if project.active?
+      link_to project.name, settings_project_path(project, options), html_options
+    elsif project.archived?
+      h(project.name)
+    else
+      link_to project.name, project_path(project, options), html_options
+    end
+  end
+
+  def wiki_page_path(page, options={})
+    url_for({:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title}.merge(options))
+  end
+
+  def thumbnail_tag(attachment)
+    link_to image_tag(thumbnail_path(attachment)),
+      named_attachment_path(attachment, attachment.filename),
+      :title => attachment.filename
+  end
+
+  def toggle_link(name, id, options={})
+    onclick = "$('##{id}').toggle(); "
+    onclick << (options[:focus] ? "$('##{options[:focus]}').focus(); " : "this.blur(); ")
+    onclick << "return false;"
+    link_to(name, "#", :onclick => onclick)
+  end
+
+  def image_to_function(name, function, html_options = {})
+    html_options.symbolize_keys!
+    tag(:input, html_options.merge({
+        :type => "image", :src => image_path(name),
+        :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
+        }))
+  end
+
+  def format_activity_title(text)
+    h(truncate_single_line(text, :length => 100))
+  end
+
+  def format_activity_day(date)
+    date == User.current.today ? l(:label_today).titleize : format_date(date)
+  end
+
+  def format_activity_description(text)
+    h(truncate(text.to_s, :length => 120).gsub(%r{[\r\n]*<(pre|code)>.*$}m, '...')
+       ).gsub(/[\r\n]+/, "<br />").html_safe
+  end
+
+  def format_version_name(version)
+    if version.project == @project
+      h(version)
+    else
+      h("#{version.project} - #{version}")
+    end
+  end
+
+  def due_date_distance_in_words(date)
+    if date
+      l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date))
+    end
+  end
+
+  # Renders a tree of projects as a nested set of unordered lists
+  # The given collection may be a subset of the whole project tree
+  # (eg. some intermediate nodes are private and can not be seen)
+  def render_project_nested_lists(projects)
+    s = ''
+    if projects.any?
+      ancestors = []
+      original_project = @project
+      projects.sort_by(&:lft).each do |project|
+        # set the project environment to please macros.
+        @project = project
+        if (ancestors.empty? || project.is_descendant_of?(ancestors.last))
+          s << "<ul class='projects #{ ancestors.empty? ? 'root' : nil}'>\n"
+        else
+          ancestors.pop
+          s << "</li>"
+          while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
+            ancestors.pop
+            s << "</ul></li>\n"
+          end
+        end
+        classes = (ancestors.empty? ? 'root' : 'child')
+        s << "<li class='#{classes}'><div class='#{classes}'>"
+        s << h(block_given? ? yield(project) : project.name)
+        s << "</div>\n"
+        ancestors << project
+      end
+      s << ("</li></ul>\n" * ancestors.size)
+      @project = original_project
+    end
+    s.html_safe
+  end
+
+  def render_page_hierarchy(pages, node=nil, options={})
+    content = ''
+    if pages[node]
+      content << "<ul class=\"pages-hierarchy\">\n"
+      pages[node].each do |page|
+        content << "<li>"
+        content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title, :version => nil},
+                           :title => (options[:timestamp] && page.updated_on ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
+        content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id]
+        content << "</li>\n"
+      end
+      content << "</ul>\n"
+    end
+    content.html_safe
+  end
+
+  # Renders flash messages
+  def render_flash_messages
+    s = ''
+    flash.each do |k,v|
+      s << content_tag('div', v.html_safe, :class => "flash #{k}", :id => "flash_#{k}")
+    end
+    s.html_safe
+  end
+
+  # Renders tabs and their content
+  def render_tabs(tabs)
+    if tabs.any?
+      render :partial => 'common/tabs', :locals => {:tabs => tabs}
+    else
+      content_tag 'p', l(:label_no_data), :class => "nodata"
+    end
+  end
+
+  # Renders the project quick-jump box
+  def render_project_jump_box
+    return unless User.current.logged?
+    projects = User.current.memberships.collect(&:project).compact.select(&:active?).uniq
+    if projects.any?
+      options =
+        ("<option value=''>#{ l(:label_jump_to_a_project) }</option>" +
+         '<option value="" disabled="disabled">---</option>').html_safe
+
+      options << project_tree_options_for_select(projects, :selected => @project) do |p|
+        { :value => project_path(:id => p, :jump => current_menu_item) }
+      end
+
+      select_tag('project_quick_jump_box', options, :onchange => 'if (this.value != \'\') { window.location = this.value; }')
+    end
+  end
+
+  def project_tree_options_for_select(projects, options = {})
+    s = ''
+    project_tree(projects) do |project, level|
+      name_prefix = (level > 0 ? '&nbsp;' * 2 * level + '&#187; ' : '').html_safe
+      tag_options = {:value => project.id}
+      if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project))
+        tag_options[:selected] = 'selected'
+      else
+        tag_options[:selected] = nil
+      end
+      tag_options.merge!(yield(project)) if block_given?
+      s << content_tag('option', name_prefix + h(project), tag_options)
+    end
+    s.html_safe
+  end
+
+  # Yields the given block for each project with its level in the tree
+  #
+  # Wrapper for Project#project_tree
+  def project_tree(projects, &block)
+    Project.project_tree(projects, &block)
+  end
+
+  def principals_check_box_tags(name, principals)
+    s = ''
+    principals.each do |principal|
+      s << "<label>#{ check_box_tag name, principal.id, false, :id => nil } #{h principal}</label>\n"
+    end
+    s.html_safe
+  end
+
+  # Returns a string for users/groups option tags
+  def principals_options_for_select(collection, selected=nil)
+    s = ''
+    if collection.include?(User.current)
+      s << content_tag('option', "<< #{l(:label_me)} >>", :value => User.current.id)
+    end
+    groups = ''
+    collection.sort.each do |element|
+      selected_attribute = ' selected="selected"' if option_value_selected?(element, selected)
+      (element.is_a?(Group) ? groups : s) << %(<option value="#{element.id}"#{selected_attribute}>#{h element.name}</option>)
+    end
+    unless groups.empty?
+      s << %(<optgroup label="#{h(l(:label_group_plural))}">#{groups}</optgroup>)
+    end
+    s.html_safe
+  end
+
+  # Options for the new membership projects combo-box
+  def options_for_membership_project_select(principal, projects)
+    options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
+    options << project_tree_options_for_select(projects) do |p|
+      {:disabled => principal.projects.to_a.include?(p)}
+    end
+    options
+  end
+
+  # Truncates and returns the string as a single line
+  def truncate_single_line(string, *args)
+    truncate(string.to_s, *args).gsub(%r{[\r\n]+}m, ' ')
+  end
+
+  # Truncates at line break after 250 characters or options[:length]
+  def truncate_lines(string, options={})
+    length = options[:length] || 250
+    if string.to_s =~ /\A(.{#{length}}.*?)$/m
+      "#{$1}..."
+    else
+      string
+    end
+  end
+
+  def anchor(text)
+    text.to_s.gsub(' ', '_')
+  end
+
+  def html_hours(text)
+    text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>').html_safe
+  end
+
+  def authoring(created, author, options={})
+    l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)).html_safe
+  end
+
+  def time_tag(time)
+    text = distance_of_time_in_words(Time.now, time)
+    if @project
+      link_to(text, {:controller => 'activities', :action => 'index', :id => @project, :from => User.current.time_to_date(time)}, :title => format_time(time))
+    else
+      content_tag('acronym', text, :title => format_time(time))
+    end
+  end
+
+  def syntax_highlight_lines(name, content)
+    lines = []
+    syntax_highlight(name, content).each_line { |line| lines << line }
+    lines
+  end
+
+  def syntax_highlight(name, content)
+    Redmine::SyntaxHighlighting.highlight_by_filename(content, name)
+  end
+
+  def to_path_param(path)
+    str = path.to_s.split(%r{[/\\]}).select{|p| !p.blank?}.join("/")
+    str.blank? ? nil : str
+  end
+
+  def reorder_links(name, url, method = :post)
+    link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)),
+            url.merge({"#{name}[move_to]" => 'highest'}),
+            :method => method, :title => l(:label_sort_highest)) +
+    link_to(image_tag('1uparrow.png',   :alt => l(:label_sort_higher)),
+            url.merge({"#{name}[move_to]" => 'higher'}),
+           :method => method, :title => l(:label_sort_higher)) +
+    link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)),
+            url.merge({"#{name}[move_to]" => 'lower'}),
+            :method => method, :title => l(:label_sort_lower)) +
+    link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)),
+            url.merge({"#{name}[move_to]" => 'lowest'}),
+           :method => method, :title => l(:label_sort_lowest))
+  end
+
+  def breadcrumb(*args)
+    elements = args.flatten
+    elements.any? ? content_tag('p', (args.join(" \xc2\xbb ") + " \xc2\xbb ").html_safe, :class => 'breadcrumb') : nil
+  end
+
+  def other_formats_links(&block)
+    concat('<p class="other-formats">'.html_safe + l(:label_export_to))
+    yield Redmine::Views::OtherFormatsBuilder.new(self)
+    concat('</p>'.html_safe)
+  end
+
+  def page_header_title
+    if @project.nil? || @project.new_record?
+      h(Setting.app_title)
+    else
+      b = []
+      ancestors = (@project.root? ? [] : @project.ancestors.visible.all)
+      if ancestors.any?
+        root = ancestors.shift
+        b << link_to_project(root, {:jump => current_menu_item}, :class => 'root')
+        if ancestors.size > 2
+          b << "\xe2\x80\xa6"
+          ancestors = ancestors[-2, 2]
+        end
+        b += ancestors.collect {|p| link_to_project(p, {:jump => current_menu_item}, :class => 'ancestor') }
+      end
+      b << h(@project)
+      b.join(" \xc2\xbb ").html_safe
+    end
+  end
+
+  def html_title(*args)
+    if args.empty?
+      title = @html_title || []
+      title << @project.name if @project
+      title << Setting.app_title unless Setting.app_title == title.last
+      title.select {|t| !t.blank? }.join(' - ')
+    else
+      @html_title ||= []
+      @html_title += args
+    end
+  end
+
+  # Returns the theme, controller name, and action as css classes for the
+  # HTML body.
+  def body_css_classes
+    css = []
+    if theme = Redmine::Themes.theme(Setting.ui_theme)
+      css << 'theme-' + theme.name
+    end
+
+    css << 'controller-' + controller_name
+    css << 'action-' + action_name
+    css.join(' ')
+  end
+
+  def accesskey(s)
+    @used_accesskeys ||= []
+    key = Redmine::AccessKeys.key_for(s)
+    return nil if @used_accesskeys.include?(key)
+    @used_accesskeys << key
+    key
+  end
+
+  # Formats text according to system settings.
+  # 2 ways to call this method:
+  # * with a String: textilizable(text, options)
+  # * with an object and one of its attribute: textilizable(issue, :description, options)
+  def textilizable(*args)
+    options = args.last.is_a?(Hash) ? args.pop : {}
+    case args.size
+    when 1
+      obj = options[:object]
+      text = args.shift
+    when 2
+      obj = args.shift
+      attr = args.shift
+      text = obj.send(attr).to_s
+    else
+      raise ArgumentError, 'invalid arguments to textilizable'
+    end
+    return '' if text.blank?
+    project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
+    only_path = options.delete(:only_path) == false ? false : true
+
+    text = text.dup
+    macros = catch_macros(text)
+    text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr)
+
+    @parsed_headings = []
+    @heading_anchors = {}
+    @current_section = 0 if options[:edit_section_links]
+
+    parse_sections(text, project, obj, attr, only_path, options)
+    text = parse_non_pre_blocks(text, obj, macros) do |text|
+      [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name|
+        send method_name, text, project, obj, attr, only_path, options
+      end
+    end
+    parse_headings(text, project, obj, attr, only_path, options)
+
+    if @parsed_headings.any?
+      replace_toc(text, @parsed_headings)
+    end
+
+    text.html_safe
+  end
+
+  def parse_non_pre_blocks(text, obj, macros)
+    s = StringScanner.new(text)
+    tags = []
+    parsed = ''
+    while !s.eos?
+      s.scan(/(.*?)(<(\/)?(pre|code)(.*?)>|\z)/im)
+      text, full_tag, closing, tag = s[1], s[2], s[3], s[4]
+      if tags.empty?
+        yield text
+        inject_macros(text, obj, macros) if macros.any?
+      else
+        inject_macros(text, obj, macros, false) if macros.any?
+      end
+      parsed << text
+      if tag
+        if closing
+          if tags.last == tag.downcase
+            tags.pop
+          end
+        else
+          tags << tag.downcase
+        end
+        parsed << full_tag
+      end
+    end
+    # Close any non closing tags
+    while tag = tags.pop
+      parsed << "</#{tag}>"
+    end
+    parsed
+  end
+
+  def parse_inline_attachments(text, project, obj, attr, only_path, options)
+    # when using an image link, try to use an attachment, if possible
+    attachments = options[:attachments] || []
+    attachments += obj.attachments if obj.respond_to?(:attachments)
+    if attachments.present?
+      text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m|
+        filename, ext, alt, alttext = $1.downcase, $2, $3, $4
+        # search for the picture in attachments
+        if found = Attachment.latest_attach(attachments, filename)
+          image_url = download_named_attachment_path(found, found.filename, :only_path => only_path)
+          desc = found.description.to_s.gsub('"', '')
+          if !desc.blank? && alttext.blank?
+            alt = " title=\"#{desc}\" alt=\"#{desc}\""
+          end
+          "src=\"#{image_url}\"#{alt}"
+        else
+          m
+        end
+      end
+    end
+  end
+
+  # Wiki links
+  #
+  # Examples:
+  #   [[mypage]]
+  #   [[mypage|mytext]]
+  # wiki links can refer other project wikis, using project name or identifier:
+  #   [[project:]] -> wiki starting page
+  #   [[project:|mytext]]
+  #   [[project:mypage]]
+  #   [[project:mypage|mytext]]
+  def parse_wiki_links(text, project, obj, attr, only_path, options)
+    text.gsub!(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m|
+      link_project = project
+      esc, all, page, title = $1, $2, $3, $5
+      if esc.nil?
+        if page =~ /^([^\:]+)\:(.*)$/
+          identifier, page = $1, $2
+          link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier)
+          title ||= identifier if page.blank?
+        end
+
+        if link_project && link_project.wiki
+          # extract anchor
+          anchor = nil
+          if page =~ /^(.+?)\#(.+)$/
+            page, anchor = $1, $2
+          end
+          anchor = sanitize_anchor_name(anchor) if anchor.present?
+          # check if page exists
+          wiki_page = link_project.wiki.find_page(page)
+          url = if anchor.present? && wiki_page.present? && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) && obj.page == wiki_page
+            "##{anchor}"
+          else
+            case options[:wiki_links]
+            when :local; "#{page.present? ? Wiki.titleize(page) : ''}.html" + (anchor.present? ? "##{anchor}" : '')
+            when :anchor; "##{page.present? ? Wiki.titleize(page) : title}" + (anchor.present? ? "_#{anchor}" : '') # used for single-file wiki export
+            else
+              wiki_page_id = page.present? ? Wiki.titleize(page) : nil
+              parent = wiki_page.nil? && obj.is_a?(WikiContent) && obj.page && project == link_project ? obj.page.title : nil
+              url_for(:only_path => only_path, :controller => 'wiki', :action => 'show', :project_id => link_project, 
+               :id => wiki_page_id, :version => nil, :anchor => anchor, :parent => parent)
+            end
+          end
+          link_to(title.present? ? title.html_safe : h(page), url, :class => ('wiki-page' + (wiki_page ? '' : ' new')))
+        else
+          # project or wiki doesn't exist
+          all
+        end
+      else
+        all
+      end
+    end
+  end
+
+  # Redmine links
+  #
+  # Examples:
+  #   Issues:
+  #     #52 -> Link to issue #52
+  #   Changesets:
+  #     r52 -> Link to revision 52
+  #     commit:a85130f -> Link to scmid starting with a85130f
+  #   Documents:
+  #     document#17 -> Link to document with id 17
+  #     document:Greetings -> Link to the document with title "Greetings"
+  #     document:"Some document" -> Link to the document with title "Some document"
+  #   Versions:
+  #     version#3 -> Link to version with id 3
+  #     version:1.0.0 -> Link to version named "1.0.0"
+  #     version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
+  #   Attachments:
+  #     attachment:file.zip -> Link to the attachment of the current object named file.zip
+  #   Source files:
+  #     source:some/file -> Link to the file located at /some/file in the project's repository
+  #     source:some/file@52 -> Link to the file's revision 52
+  #     source:some/file#L120 -> Link to line 120 of the file
+  #     source:some/file@52#L120 -> Link to line 120 of the file's revision 52
+  #     export:some/file -> Force the download of the file
+  #   Forum messages:
+  #     message#1218 -> Link to message with id 1218
+  #
+  #   Links can refer other objects from other projects, using project identifier:
+  #     identifier:r52
+  #     identifier:document:"Some document"
+  #     identifier:version:1.0.0
+  #     identifier:source:some/file
+  def parse_redmine_links(text, default_project, obj, attr, only_path, options)
+    text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-_]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m|
+      leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, $2, $3, $4, $5, $10, $11, $8 || $12 || $18, $14 || $19, $15, $17
+      link = nil
+      project = default_project
+      if project_identifier
+        project = Project.visible.find_by_identifier(project_identifier)
+      end
+      if esc.nil?
+        if prefix.nil? && sep == 'r'
+          if project
+            repository = nil
+            if repo_identifier
+              repository = project.repositories.detect {|repo| repo.identifier == repo_identifier}
+            else
+              repository = project.repository
+            end
+            # project.changesets.visible raises an SQL error because of a double join on repositories
+            if repository && (changeset = Changeset.visible.find_by_repository_id_and_revision(repository.id, identifier))
+              link = link_to(h("#{project_prefix}#{repo_prefix}r#{identifier}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.revision},
+                                        :class => 'changeset',
+                                        :title => truncate_single_line(changeset.comments, :length => 100))
+            end
+          end
+        elsif sep == '#'
+          oid = identifier.to_i
+          case prefix
+          when nil
+            if oid.to_s == identifier && issue = Issue.visible.find_by_id(oid, :include => :status)
+              anchor = comment_id ? "note-#{comment_id}" : nil
+              link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid, :anchor => anchor},
+                                        :class => issue.css_classes,
+                                        :title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})")
+            end
+          when 'document'
+            if document = Document.visible.find_by_id(oid)
+              link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
+                                                :class => 'document'
+            end
+          when 'version'
+            if version = Version.visible.find_by_id(oid)
+              link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
+                                              :class => 'version'
+            end
+          when 'message'
+            if message = Message.visible.find_by_id(oid, :include => :parent)
+              link = link_to_message(message, {:only_path => only_path}, :class => 'message')
+            end
+          when 'forum'
+            if board = Board.visible.find_by_id(oid)
+              link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
+                                             :class => 'board'
+            end
+          when 'news'
+            if news = News.visible.find_by_id(oid)
+              link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
+                                            :class => 'news'
+            end
+          when 'project'
+            if p = Project.visible.find_by_id(oid)
+              link = link_to_project(p, {:only_path => only_path}, :class => 'project')
+            end
+          end
+        elsif sep == ':'
+          # removes the double quotes if any
+          name = identifier.gsub(%r{^"(.*)"$}, "\\1")
+          case prefix
+          when 'document'
+            if project && document = project.documents.visible.find_by_title(name)
+              link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
+                                                :class => 'document'
+            end
+          when 'version'
+            if project && version = project.versions.visible.find_by_name(name)
+              link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
+                                              :class => 'version'
+            end
+          when 'forum'
+            if project && board = project.boards.visible.find_by_name(name)
+              link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
+                                             :class => 'board'
+            end
+          when 'news'
+            if project && news = project.news.visible.find_by_title(name)
+              link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
+                                            :class => 'news'
+            end
+          when 'commit', 'source', 'export'
+            if project
+              repository = nil
+              if name =~ %r{^(([a-z0-9\-_]+)\|)(.+)$}
+                repo_prefix, repo_identifier, name = $1, $2, $3
+                repository = project.repositories.detect {|repo| repo.identifier == repo_identifier}
+              else
+                repository = project.repository
+              end
+              if prefix == 'commit'
+                if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first)
+                  link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier},
+                                               :class => 'changeset',
+                                               :title => truncate_single_line(changeset.comments, :length => 100)
+                end
+              else
+                if repository && User.current.allowed_to?(:browse_repository, project)
+                  name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$}
+                  path, rev, anchor = $1, $3, $5
+                  link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param,
+                                                          :path => to_path_param(path),
+                                                          :rev => rev,
+                                                          :anchor => anchor},
+                                                         :class => (prefix == 'export' ? 'source download' : 'source')
+                end
+              end
+              repo_prefix = nil
+            end
+          when 'attachment'
+            attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
+            if attachments && attachment = Attachment.latest_attach(attachments, name)
+              link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment')
+            end
+          when 'project'
+            if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first
+              link = link_to_project(p, {:only_path => only_path}, :class => 'project')
+            end
+          end
+        end
+      end
+      (leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}"))
+    end
+  end
+
+  HEADING_RE = /(<h(\d)( [^>]+)?>(.+?)<\/h(\d)>)/i unless const_defined?(:HEADING_RE)
+
+  def parse_sections(text, project, obj, attr, only_path, options)
+    return unless options[:edit_section_links]
+    text.gsub!(HEADING_RE) do
+      heading = $1
+      @current_section += 1
+      if @current_section > 1
+        content_tag('div',
+          link_to(image_tag('edit.png'), options[:edit_section_links].merge(:section => @current_section)),
+          :class => 'contextual',
+          :title => l(:button_edit_section)) + heading.html_safe
+      else
+        heading
+      end
+    end
+  end
+
+  # Headings and TOC
+  # Adds ids and links to headings unless options[:headings] is set to false
+  def parse_headings(text, project, obj, attr, only_path, options)
+    return if options[:headings] == false
+
+    text.gsub!(HEADING_RE) do
+      level, attrs, content = $2.to_i, $3, $4
+      item = strip_tags(content).strip
+      anchor = sanitize_anchor_name(item)
+      # used for single-file wiki export
+      anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version))
+      @heading_anchors[anchor] ||= 0
+      idx = (@heading_anchors[anchor] += 1)
+      if idx > 1
+        anchor = "#{anchor}-#{idx}"
+      end
+      @parsed_headings << [level, anchor, item]
+      "<a name=\"#{anchor}\"></a>\n<h#{level} #{attrs}>#{content}<a href=\"##{anchor}\" class=\"wiki-anchor\">&para;</a></h#{level}>"
+    end
+  end
+
+  MACROS_RE = /(
+                (!)?                        # escaping
+                (
+                \{\{                        # opening tag
+                ([\w]+)                     # macro name
+                (\(([^\n\r]*?)\))?          # optional arguments
+                ([\n\r].*?[\n\r])?          # optional block of text
+                \}\}                        # closing tag
+                )
+               )/mx unless const_defined?(:MACROS_RE)
+
+  MACRO_SUB_RE = /(
+                  \{\{
+                  macro\((\d+)\)
+                  \}\}
+                  )/x unless const_defined?(:MACRO_SUB_RE)
+
+  # Extracts macros from text
+  def catch_macros(text)
+    macros = {}
+    text.gsub!(MACROS_RE) do
+      all, macro = $1, $4.downcase
+      if macro_exists?(macro) || all =~ MACRO_SUB_RE
+        index = macros.size
+        macros[index] = all
+        "{{macro(#{index})}}"
+      else
+        all
+      end
+    end
+    macros
+  end
+
+  # Executes and replaces macros in text
+  def inject_macros(text, obj, macros, execute=true)
+    text.gsub!(MACRO_SUB_RE) do
+      all, index = $1, $2.to_i
+      orig = macros.delete(index)
+      if execute && orig && orig =~ MACROS_RE
+        esc, all, macro, args, block = $2, $3, $4.downcase, $6.to_s, $7.try(:strip)
+        if esc.nil?
+          h(exec_macro(macro, obj, args, block) || all)
+        else
+          h(all)
+        end
+      elsif orig
+        h(orig)
+      else
+        h(all)
+      end
+    end
+  end
+
+  TOC_RE = /<p>\{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE)
+
+  # Renders the TOC with given headings
+  def replace_toc(text, headings)
+    text.gsub!(TOC_RE) do
+      # Keep only the 4 first levels
+      headings = headings.select{|level, anchor, item| level <= 4}
+      if headings.empty?
+        ''
+      else
+        div_class = 'toc'
+        div_class << ' right' if $1 == '>'
+        div_class << ' left' if $1 == '<'
+        out = "<ul class=\"#{div_class}\"><li>"
+        root = headings.map(&:first).min
+        current = root
+        started = false
+        headings.each do |level, anchor, item|
+          if level > current
+            out << '<ul><li>' * (level - current)
+          elsif level < current
+            out << "</li></ul>\n" * (current - level) + "</li><li>"
+          elsif started
+            out << '</li><li>'
+          end
+          out << "<a href=\"##{anchor}\">#{item}</a>"
+          current = level
+          started = true
+        end
+        out << '</li></ul>' * (current - root)
+        out << '</li></ul>'
+      end
+    end
+  end
+
+  # Same as Rails' simple_format helper without using paragraphs
+  def simple_format_without_paragraph(text)
+    text.to_s.
+      gsub(/\r\n?/, "\n").                    # \r\n and \r -> \n
+      gsub(/\n\n+/, "<br /><br />").          # 2+ newline  -> 2 br
+      gsub(/([^\n]\n)(?=[^\n])/, '\1<br />'). # 1 newline   -> br
+      html_safe
+  end
+
+  def lang_options_for_select(blank=true)
+    (blank ? [["(auto)", ""]] : []) + languages_options
+  end
+
+  def label_tag_for(name, option_tags = nil, options = {})
+    label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
+    content_tag("label", label_text)
+  end
+
+  def labelled_form_for(*args, &proc)
+    args << {} unless args.last.is_a?(Hash)
+    options = args.last
+    if args.first.is_a?(Symbol)
+      options.merge!(:as => args.shift)
+    end
+    options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
+    form_for(*args, &proc)
+  end
+
+  def labelled_fields_for(*args, &proc)
+    args << {} unless args.last.is_a?(Hash)
+    options = args.last
+    options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
+    fields_for(*args, &proc)
+  end
+
+  def labelled_remote_form_for(*args, &proc)
+    ActiveSupport::Deprecation.warn "ApplicationHelper#labelled_remote_form_for is deprecated and will be removed in Redmine 2.2."
+    args << {} unless args.last.is_a?(Hash)
+    options = args.last
+    options.merge!({:builder => Redmine::Views::LabelledFormBuilder, :remote => true})
+    form_for(*args, &proc)
+  end
+
+  def error_messages_for(*objects)
+    html = ""
+    objects = objects.map {|o| o.is_a?(String) ? instance_variable_get("@#{o}") : o}.compact
+    errors = objects.map {|o| o.errors.full_messages}.flatten
+    if errors.any?
+      html << "<div id='errorExplanation'><ul>\n"
+      errors.each do |error|
+        html << "<li>#{h error}</li>\n"
+      end
+      html << "</ul></div>\n"
+    end
+    html.html_safe
+  end  
+
+  def delete_link(url, options={})
+    options = {
+      :method => :delete,
+      :data => {:confirm => l(:text_are_you_sure)},
+      :class => 'icon icon-del'
+    }.merge(options)
+
+    link_to l(:button_delete), url, options
+  end
+
+  def preview_link(url, form, target='preview', options={})
+    content_tag 'a', l(:label_preview), {
+        :href => "#", 
+        :onclick => %|submitPreview("#{escape_javascript url_for(url)}", "#{escape_javascript form}", "#{escape_javascript target}"); return false;|, 
+        :accesskey => accesskey(:preview)
+      }.merge(options)
+  end
+
+  def link_to_function(name, function, html_options={})
+    content_tag(:a, name, {:href => '#', :onclick => "#{function}; return false;"}.merge(html_options))
+  end
+
+  # Helper to render JSON in views
+  def raw_json(arg)
+    arg.to_json.to_s.gsub('/', '\/').html_safe
+  end
+
+  def back_url
+    url = params[:back_url]
+    if url.nil? && referer = request.env['HTTP_REFERER']
+      url = CGI.unescape(referer.to_s)
+    end
+    url
+  end
+
+  def back_url_hidden_field_tag
+    url = back_url
+    hidden_field_tag('back_url', url, :id => nil) unless url.blank?
+  end
+
+  def check_all_links(form_name)
+    link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
+    " | ".html_safe +
+    link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
+  end
+
+  def progress_bar(pcts, options={})
+    pcts = [pcts, pcts] unless pcts.is_a?(Array)
+    pcts = pcts.collect(&:round)
+    pcts[1] = pcts[1] - pcts[0]
+    pcts << (100 - pcts[1] - pcts[0])
+    width = options[:width] || '100px;'
+    legend = options[:legend] || ''
+    content_tag('table',
+      content_tag('tr',
+        (pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0]}%;", :class => 'closed') : ''.html_safe) +
+        (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : ''.html_safe) +
+        (pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : ''.html_safe)
+      ), :class => 'progress', :style => "width: #{width};").html_safe +
+      content_tag('p', legend, :class => 'percent').html_safe
+  end
+
+  def checked_image(checked=true)
+    if checked
+      image_tag 'toggle_check.png'
+    end
+  end
+
+  def context_menu(url)
+    unless @context_menu_included
+      content_for :header_tags do
+        javascript_include_tag('context_menu') +
+          stylesheet_link_tag('context_menu')
+      end
+      if l(:direction) == 'rtl'
+        content_for :header_tags do
+          stylesheet_link_tag('context_menu_rtl')
+        end
+      end
+      @context_menu_included = true
+    end
+    javascript_tag "contextMenuInit('#{ url_for(url) }')"
+  end
+
+  def calendar_for(field_id)
+    include_calendar_headers_tags
+    javascript_tag("$(function() { $('##{field_id}').datepicker(datepickerOptions); });")
+  end
+
+  def include_calendar_headers_tags
+    unless @calendar_headers_tags_included
+      @calendar_headers_tags_included = true
+      content_for :header_tags do
+        start_of_week = Setting.start_of_week
+        start_of_week = l(:general_first_day_of_week, :default => '1') if start_of_week.blank?
+        # Redmine uses 1..7 (monday..sunday) in settings and locales
+        # JQuery uses 0..6 (sunday..saturday), 7 needs to be changed to 0
+        start_of_week = start_of_week.to_i % 7
+
+        tags = javascript_tag(
+                   "var datepickerOptions={dateFormat: 'yy-mm-dd', firstDay: #{start_of_week}, " +
+                     "showOn: 'button', buttonImageOnly: true, buttonImage: '" + 
+                     path_to_image('/images/calendar.png') +
+                     "', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true};")
+        jquery_locale = l('jquery.locale', :default => current_language.to_s)
+        unless jquery_locale == 'en'
+          tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js") 
+        end
+        tags
+      end
+    end
+  end
+
+  # Overrides Rails' stylesheet_link_tag with themes and plugins support.
+  # Examples:
+  #   stylesheet_link_tag('styles') # => picks styles.css from the current theme or defaults
+  #   stylesheet_link_tag('styles', :plugin => 'foo) # => picks styles.css from plugin's assets
+  #
+  def stylesheet_link_tag(*sources)
+    options = sources.last.is_a?(Hash) ? sources.pop : {}
+    plugin = options.delete(:plugin)
+    sources = sources.map do |source|
+      if plugin
+        "/plugin_assets/#{plugin}/stylesheets/#{source}"
+      elsif current_theme && current_theme.stylesheets.include?(source)
+        current_theme.stylesheet_path(source)
+      else
+        source
+      end
+    end
+    super sources, options
+  end
+
+  # Overrides Rails' image_tag with themes and plugins support.
+  # Examples:
+  #   image_tag('image.png') # => picks image.png from the current theme or defaults
+  #   image_tag('image.png', :plugin => 'foo) # => picks image.png from plugin's assets
+  #
+  def image_tag(source, options={})
+    if plugin = options.delete(:plugin)
+      source = "/plugin_assets/#{plugin}/images/#{source}"
+    elsif current_theme && current_theme.images.include?(source)
+      source = current_theme.image_path(source)
+    end
+    super source, options
+  end
+
+  # Overrides Rails' javascript_include_tag with plugins support
+  # Examples:
+  #   javascript_include_tag('scripts') # => picks scripts.js from defaults
+  #   javascript_include_tag('scripts', :plugin => 'foo) # => picks scripts.js from plugin's assets
+  #
+  def javascript_include_tag(*sources)
+    options = sources.last.is_a?(Hash) ? sources.pop : {}
+    if plugin = options.delete(:plugin)
+      sources = sources.map do |source|
+        if plugin
+          "/plugin_assets/#{plugin}/javascripts/#{source}"
+        else
+          source
+        end
+      end
+    end
+    super sources, options
+  end
+
+  def content_for(name, content = nil, &block)
+    @has_content ||= {}
+    @has_content[name] = true
+    super(name, content, &block)
+  end
+
+  def has_content?(name)
+    (@has_content && @has_content[name]) || false
+  end
+
+  def sidebar_content?
+    has_content?(:sidebar) || view_layouts_base_sidebar_hook_response.present?
+  end
+
+  def view_layouts_base_sidebar_hook_response
+    @view_layouts_base_sidebar_hook_response ||= call_hook(:view_layouts_base_sidebar)
+  end
+
+  def email_delivery_enabled?
+    !!ActionMailer::Base.perform_deliveries
+  end
+
+  # Returns the avatar image tag for the given +user+ if avatars are enabled
+  # +user+ can be a User or a string that will be scanned for an email address (eg. 'joe <joe@foo.bar>')
+  def avatar(user, options = { })
+    if Setting.gravatar_enabled?
+      options.merge!({:ssl => (request && request.ssl?), :default => Setting.gravatar_default})
+      email = nil
+      if user.respond_to?(:mail)
+        email = user.mail
+      elsif user.to_s =~ %r{<(.+?)>}
+        email = $1
+      end
+      return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil
+    else
+      ''
+    end
+  end
+
+  def sanitize_anchor_name(anchor)
+    if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java'
+      anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
+    else
+      # TODO: remove when ruby1.8 is no longer supported
+      anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
+    end
+  end
+
+  # Returns the javascript tags that are included in the html layout head
+  def javascript_heads
+    tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application')
+    unless User.current.pref.warn_on_leaving_unsaved == '0'
+      tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
+    end
+    tags
+  end
+
+  def favicon
+    "<link rel='shortcut icon' href='#{image_path('/favicon.ico')}' />".html_safe
+  end
+
+  def robot_exclusion_tag
+    '<meta name="robots" content="noindex,follow,noarchive" />'.html_safe
+  end
+
+  # Returns true if arg is expected in the API response
+  def include_in_api_response?(arg)
+    unless @included_in_api_response
+      param = params[:include]
+      @included_in_api_response = param.is_a?(Array) ? param.collect(&:to_s) : param.to_s.split(',')
+      @included_in_api_response.collect!(&:strip)
+    end
+    @included_in_api_response.include?(arg.to_s)
+  end
+
+  # Returns options or nil if nometa param or X-Redmine-Nometa header
+  # was set in the request
+  def api_meta(options)
+    if params[:nometa].present? || request.headers['X-Redmine-Nometa']
+      # compatibility mode for activeresource clients that raise
+      # an error when unserializing an array with attributes
+      nil
+    else
+      options
+    end
+  end
+
+  private
+
+  def wiki_helper
+    helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
+    extend helper
+    return self
+  end
+
+  def link_to_content_update(text, url_params = {}, html_options = {})
+    link_to(text, url_params, html_options)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fb/fb7ef041bbcc8eadd98d7fb619e196b16fec91c6.svn-base
--- a/.svn/pristine/fb/fb7ef041bbcc8eadd98d7fb619e196b16fec91c6.svn-base
+++ /dev/null
@@ -1,56 +0,0 @@
-require File.expand_path('../../test_helper', __FILE__)
-
-class LayoutTest < ActionController::IntegrationTest
-  fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
-           :projects_trackers,
-           :roles,
-           :member_roles,
-           :members,
-           :enabled_modules,
-           :workflows
-
-  test "browsing to a missing page should render the base layout" do
-    get "/users/100000000"
-
-    assert_response :not_found
-
-    # UsersController uses the admin layout by default
-    assert_select "#admin-menu", :count => 0
-  end
-
-  test "browsing to an unauthorized page should render the base layout" do
-    change_user_password('miscuser9', 'test')
-
-    log_user('miscuser9','test')
-
-    get "/admin"
-    assert_response :forbidden
-    assert_select "#admin-menu", :count => 0
-  end
-
-  def test_top_menu_and_search_not_visible_when_login_required
-    with_settings :login_required => '1' do
-      get '/'
-      assert_select "#top-menu > ul", 0
-      assert_select "#quick-search", 0
-    end
-  end
-
-  def test_top_menu_and_search_visible_when_login_not_required
-    with_settings :login_required => '0' do
-      get '/'
-      assert_select "#top-menu > ul"
-      assert_select "#quick-search"
-    end
-  end
-
-  def test_wiki_formatter_header_tags
-    Role.anonymous.add_permission! :add_issues
-
-    get '/projects/ecookbook/issues/new'
-    assert_tag :script,
-      :attributes => {:src => %r{^/javascripts/jstoolbar/textile.js}},
-      :parent => {:tag => 'head'}
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fb/fb9d18ab27c8a24a4ea968203d6a7cfafe3bd575.svn-base
--- a/.svn/pristine/fb/fb9d18ab27c8a24a4ea968203d6a7cfafe3bd575.svn-base
+++ /dev/null
@@ -1,137 +0,0 @@
-<%= render :partial => 'action_menu' %>
-
-<h2><%= issue_heading(@issue) %></h2>
-
-<div class="<%= @issue.css_classes %> details">
-        <%= avatar(@issue.author, :size => "50") %>
-
-<div class="subject">
-<%= render_issue_subject_with_tree(@issue) %>
-</div>
-        <p class="author">
-        <%= authoring @issue.created_on, @issue.author %>.
-        <% if @issue.created_on != @issue.updated_on %>
-        <%= l(:label_updated_time, time_tag(@issue.updated_on)) %>.
-        <% end %>
-        </p>
-
-<table class="attributes">
-<tr>
-    <th class="status"><%=l(:field_status)%>:</th><td class="status"><%= h(@issue.status.name) %></td>
-    <th class="start-date"><%=l(:field_start_date)%>:</th><td class="start-date"><%= format_date(@issue.start_date) %></td>
-</tr>
-<tr>
-    <th class="priority"><%=l(:field_priority)%>:</th><td class="priority"><%= h(@issue.priority.name) %></td>
-    <th class="due-date"><%=l(:field_due_date)%>:</th><td class="due-date"><%= format_date(@issue.due_date) %></td>
-</tr>
-<tr>
-    <th class="assigned-to"><%=l(:field_assigned_to)%>:</th><td class="assigned-to"><%= avatar(@issue.assigned_to, :size => "14") %><%= @issue.assigned_to ? link_to_user(@issue.assigned_to) : "-" %></td>
-    <th class="progress"><%=l(:field_done_ratio)%>:</th><td class="progress"><%= progress_bar @issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%" %></td>
-</tr>
-<tr>
-    <th class="category"><%=l(:field_category)%>:</th><td class="category"><%=h(@issue.category ? @issue.category.name : "-") %></td>
-    <% if User.current.allowed_to?(:view_time_entries, @project) %>
-    <th class="spent-time"><%=l(:label_spent_time)%>:</th>
-    <td class="spent-time"><%= @issue.spent_hours > 0 ? (link_to l_hours(@issue.spent_hours), {:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue}) : "-" %></td>
-    <% end %>
-</tr>
-<tr>
-    <th class="fixed-version"><%=l(:field_fixed_version)%>:</th><td class="fixed-version"><%= @issue.fixed_version ? link_to_version(@issue.fixed_version) : "-" %></td>
-    <% if @issue.estimated_hours %>
-    <th class="estimated-hours"><%=l(:field_estimated_hours)%>:</th><td class="estimated-hours"><%= l_hours(@issue.estimated_hours) %></td>
-    <% end %>
-</tr>
-<%= render_custom_fields_rows(@issue) %>
-<%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
-</table>
-
-<% if @issue.description? || @issue.attachments.any? -%>
-<hr />
-<% if @issue.description? %>
-  <div class="contextual">
-  <%= link_to_remote_if_authorized(l(:button_quote), { :url => {:controller => 'journals', :action => 'new', :id => @issue} }, :class => 'icon icon-comment') %>
-  </div>
-
-  <p><strong><%=l(:field_description)%></strong></p>
-  <div class="wiki">
-  <%= textilizable @issue, :description, :attachments => @issue.attachments %>
-  </div>
-<% end %>
-<%= link_to_attachments @issue %>
-<% end -%>
-
-<%= call_hook(:view_issues_show_description_bottom, :issue => @issue) %>
-
-<% if !@issue.leaf? || User.current.allowed_to?(:manage_subtasks, @project) %>
-<hr />
-<div id="issue_tree">
-<div class="contextual">
-  <%= link_to(l(:button_add), {:controller => 'issues', :action => 'new', :project_id => @project, :issue => {:parent_issue_id => @issue}}) if User.current.allowed_to?(:manage_subtasks, @project) %>
-</div>
-<p><strong><%=l(:label_subtask_plural)%></strong></p>
-<%= render_descendants_tree(@issue) unless @issue.leaf? %>
-</div>
-<% end %>
-
-<% if @relations.present? || User.current.allowed_to?(:manage_issue_relations, @project) %>
-<hr />
-<div id="relations">
-<%= render :partial => 'relations' %>
-</div>
-<% end %>
-
-</div>
-
-<% if @changesets.present? %>
-<div id="issue-changesets">
-<h3><%=l(:label_associated_revisions)%></h3>
-<%= render :partial => 'changesets', :locals => { :changesets => @changesets} %>
-</div>
-<% end %>
-
-<% if @journals.present? %>
-<div id="history">
-<h3><%=l(:label_history)%></h3>
-<%= render :partial => 'history', :locals => { :issue => @issue, :journals => @journals } %>
-</div>
-<% end %>
-
-
-<div style="clear: both;"></div>
-<%= render :partial => 'action_menu' %>
-
-<div style="clear: both;"></div>
-<% if authorize_for('issues', 'edit') %>
-  <div id="update" style="display:none;">
-  <h3><%= l(:button_update) %></h3>
-  <%= render :partial => 'edit' %>
-  </div>
-<% end %>
-
-<% other_formats_links do |f| %>
-  <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
-  <%= f.link_to 'PDF' %>
-<% end %>
-
-<% html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %>
-
-<% content_for :sidebar do %>
-  <%= render :partial => 'issues/sidebar' %>
-
-  <% if User.current.allowed_to?(:add_issue_watchers, @project) ||
-    (@issue.watchers.present? && User.current.allowed_to?(:view_issue_watchers, @project)) %>
-    <div id="watchers">
-      <%= render :partial => 'watchers/watchers', :locals => {:watched => @issue} %>
-    </div>
-  <% end %>
-<% end %>
-
-<% content_for :header_tags do %>
-    <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@issue.project} - #{@issue.tracker} ##{@issue.id}: #{@issue.subject}") %>
-    <%= stylesheet_link_tag 'scm' %>
-    <%= javascript_include_tag 'context_menu' %>
-    <%= stylesheet_link_tag 'context_menu' %>
-    <%= stylesheet_link_tag 'context_menu_rtl' if l(:direction) == 'rtl' %>
-<% end %>
-<div id="context-menu" style="display: none;"></div>
-<%= javascript_tag "new ContextMenu('#{issues_context_menu_path}')" %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fb/fbda7b3c7252d9de68731cba763258954d380bbf.svn-base
--- /dev/null
+++ b/.svn/pristine/fb/fbda7b3c7252d9de68731cba763258954d380bbf.svn-base
@@ -0,0 +1,69 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class QueriesHelperTest < ActionView::TestCase
+  include QueriesHelper
+  include Redmine::I18n
+
+  fixtures :projects, :enabled_modules, :users, :members,
+           :member_roles, :roles, :trackers, :issue_statuses,
+           :issue_categories, :enumerations, :issues,
+           :watchers, :custom_fields, :custom_values, :versions,
+           :queries,
+           :projects_trackers,
+           :custom_fields_trackers
+
+  def test_filters_options_should_be_ordered
+    set_language_if_valid 'en'
+    query = IssueQuery.new
+    filter_count = query.available_filters.size
+    fo = filters_options(query)
+    assert_equal filter_count + 1, fo.size
+    assert_equal [], fo[0]
+
+    expected_order = [
+      "Status",
+      "Project",
+      "Tracker",
+      "Priority"
+    ]
+    assert_equal expected_order, (fo.map(&:first) & expected_order)
+  end
+
+  def test_filters_options_should_be_ordered_with_custom_fields
+    set_language_if_valid 'en'
+    field = UserCustomField.create!(
+              :name => 'order test', :field_format => 'string',
+              :is_for_all => true, :is_filter => true
+            )
+    query = IssueQuery.new
+    filter_count = query.available_filters.size
+    fo = filters_options(query)
+    assert_equal filter_count + 1, fo.size
+
+    expected_order = [
+      "Searchable field",
+      "Database",
+      "Project's Development status",
+      "Author's order test",
+      "Assignee's order test"
+    ]
+    assert_equal expected_order, (fo.map(&:first) & expected_order)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fc/fc2507eb1a52514c446bec6339656a06784ed796.svn-base
--- a/.svn/pristine/fc/fc2507eb1a52514c446bec6339656a06784ed796.svn-base
+++ /dev/null
@@ -1,35 +0,0 @@
-$:.unshift File.dirname(__FILE__) unless $:.include? '.'
-
-ROOT = '.'
-LIB_ROOT = File.join ROOT, 'lib'
-
-task :default => :test
-
-if File.directory? 'rake_tasks'
-  
-  # load rake tasks from subfolder
-  for task_file in Dir['rake_tasks/*.rake'].sort
-    load task_file
-  end
-  
-else
-  
-  # fallback tasks when rake_tasks folder is not present (eg. in the distribution package)
-  desc 'Run CodeRay tests (basic)'
-  task :test do
-    ruby './test/functional/suite.rb'
-    ruby './test/functional/for_redcloth.rb'
-  end
-  
-  gem 'rdoc' if defined? gem
-  require 'rdoc/task'
-  desc 'Generate documentation for CodeRay'
-  Rake::RDocTask.new :doc do |rd|
-    rd.title = 'CodeRay Documentation'
-    rd.main = 'README_INDEX.rdoc'
-    rd.rdoc_files.add Dir['lib']
-    rd.rdoc_files.add rd.main
-    rd.rdoc_dir = 'doc'
-  end
-  
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fc/fc277d46aec92e52e80545393ffb429147c03880.svn-base
--- /dev/null
+++ b/.svn/pristine/fc/fc277d46aec92e52e80545393ffb429147c03880.svn-base
@@ -0,0 +1,128 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require 'redmine/scm/adapters/bazaar_adapter'
+
+class Repository::Bazaar < Repository
+  attr_protected :root_url
+  validates_presence_of :url, :log_encoding
+
+  def self.human_attribute_name(attribute_key_name, *args)
+    attr_name = attribute_key_name.to_s
+    if attr_name == "url"
+      attr_name = "path_to_repository"
+    end
+    super(attr_name, *args)
+  end
+
+  def self.scm_adapter_class
+    Redmine::Scm::Adapters::BazaarAdapter
+  end
+
+  def self.scm_name
+    'Bazaar'
+  end
+
+  def entry(path=nil, identifier=nil)
+    scm.bzr_path_encodig = log_encoding
+    scm.entry(path, identifier)
+  end
+
+  def cat(path, identifier=nil)
+    scm.bzr_path_encodig = log_encoding
+    scm.cat(path, identifier)
+  end
+
+  def annotate(path, identifier=nil)
+    scm.bzr_path_encodig = log_encoding
+    scm.annotate(path, identifier)
+  end
+
+  def diff(path, rev, rev_to)
+    scm.bzr_path_encodig = log_encoding
+    scm.diff(path, rev, rev_to)
+  end
+
+  def entries(path=nil, identifier=nil)
+    scm.bzr_path_encodig = log_encoding
+    entries = scm.entries(path, identifier)
+    if entries
+      entries.each do |e|
+        next if e.lastrev.revision.blank?
+        # Set the filesize unless browsing a specific revision
+        if identifier.nil? && e.is_file?
+          full_path = File.join(root_url, e.path)
+          e.size = File.stat(full_path).size if File.file?(full_path)
+        end
+        c = Change.find(
+               :first,
+               :include    => :changeset,
+               :conditions => [
+                   "#{Change.table_name}.revision = ? and #{Changeset.table_name}.repository_id = ?",
+                   e.lastrev.revision,
+                   id
+                   ],
+               :order => "#{Changeset.table_name}.revision DESC")
+        if c
+          e.lastrev.identifier = c.changeset.revision
+          e.lastrev.name       = c.changeset.revision
+          e.lastrev.author     = c.changeset.committer
+        end
+      end
+    end
+    load_entries_changesets(entries)
+    entries
+  end
+
+  def fetch_changesets
+    scm.bzr_path_encodig = log_encoding
+    scm_info = scm.info
+    if scm_info
+      # latest revision found in database
+      db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
+      # latest revision in the repository
+      scm_revision = scm_info.lastrev.identifier.to_i
+      if db_revision < scm_revision
+        logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
+        identifier_from = db_revision + 1
+        while (identifier_from <= scm_revision)
+          # loads changesets by batches of 200
+          identifier_to = [identifier_from + 199, scm_revision].min
+          revisions = scm.revisions('', identifier_to, identifier_from)
+          transaction do
+            revisions.reverse_each do |revision|
+              changeset = Changeset.create(:repository   => self,
+                                           :revision     => revision.identifier,
+                                           :committer    => revision.author,
+                                           :committed_on => revision.time,
+                                           :scmid        => revision.scmid,
+                                           :comments     => revision.message)
+
+              revision.paths.each do |change|
+                Change.create(:changeset => changeset,
+                              :action    => change[:action],
+                              :path      => change[:path],
+                              :revision  => change[:revision])
+              end
+            end
+          end unless revisions.nil?
+          identifier_from = identifier_to + 1
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fc/fc555949e682fe2780b0d574c835d1ef48063ebb.svn-base
--- a/.svn/pristine/fc/fc555949e682fe2780b0d574c835d1ef48063ebb.svn-base
+++ /dev/null
@@ -1,129 +0,0 @@
-// ** I18N
-
-// Calendar BS language
-// Autor: Ernad HusremoviÄ‡ <hernad@bring.out.ba>
-//
-// Preuzeto od Dragan Matic, <kkid@panforma.co.yu>
-// Encoding: any
-// Distributed under the same terms as the calendar itself.
-
-// For translators: please use UTF-8 if possible.  We strongly believe that
-// Unicode is the answer to a real internationalized world.  Also please
-// include your contact information in the header, as can be seen above.
-
-// full day names
-Calendar._DN = new Array
-("Nedjelja",
- "Ponedeljak",
- "Utorak",
- "Srijeda",
- "ÄŒetvrtak",
- "Petak",
- "Subota",
- "Nedelja");
-
-// Please note that the following array of short day names (and the same goes
-// for short month names, _SMN) isn't absolutely necessary.  We give it here
-// for exemplification on how one can customize the short day names, but if
-// they are simply the first N letters of the full name you can simply say:
-//
-//   Calendar._SDN_len = N; // short day name length
-//   Calendar._SMN_len = N; // short month name length
-//
-// If N = 3 then this is not needed either since we assume a value of 3 if not
-// present, to be compatible with translation files that were written before
-// this feature.
-
-// short day names
-Calendar._SDN = new Array
-("Ned",
- "Pon",
- "Uto",
- "Sri",
- "ÄŒet",
- "Pet",
- "Sub",
- "Ned");
-
-// First day of the week. "0" means display Sunday first, "1" means display
-// Monday first, etc.
-Calendar._FD = 0;
-
-// full month names
-Calendar._MN = new Array
-("Januar",
- "Februar",
- "Mart",
- "April",
- "Maj",
- "Jun",
- "Jul",
- "Avgust",
- "Septembar",
- "Oktobar",
- "Novembar",
- "Decembar");
-
-// short month names
-Calendar._SMN = new Array
-("Jan",
- "Feb",
- "Mar",
- "Apr",
- "Maj",
- "Jun",
- "Jul",
- "Avg",
- "Sep",
- "Okt",
- "Nov",
- "Dec");
-
-// tooltips
-Calendar._TT = {};
-Calendar._TT["INFO"] = "O kalendaru";
-
-Calendar._TT["ABOUT"] =
-"DHTML Date/Time Selector\n" +
-"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
-"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
-"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
-"\n\n" +
-"Date selection:\n" +
-"- Use the \xab, \xbb buttons to select year\n" +
-"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
-"- Hold mouse button on any of the above buttons for faster selection.";
-Calendar._TT["ABOUT_TIME"] = "\n\n" +
-"Time selection:\n" +
-"- Click on any of the time parts to increase it\n" +
-"- or Shift-click to decrease it\n" +
-"- or click and drag for faster selection.";
-
-Calendar._TT["PREV_YEAR"] = "Preth. godina (drÅ¾i pritisnuto za meni)";
-Calendar._TT["PREV_MONTH"] = "Preth. mjesec (drÅ¾i pritisnuto za meni)";
-Calendar._TT["GO_TODAY"] = "Na danaÅ¡nji dan";
-Calendar._TT["NEXT_MONTH"] = "Naredni mjesec (drÅ¾i pritisnuto za meni)";
-Calendar._TT["NEXT_YEAR"] = "Naredna godina (drÅ¾i prisnuto za meni)";
-Calendar._TT["SEL_DATE"] = "Izbor datuma";
-Calendar._TT["DRAG_TO_MOVE"] = "Prevucite za izmjenu";
-Calendar._TT["PART_TODAY"] = " (danas)";
-
-// the following is to inform that "%s" is to be the first day of week
-// %s will be replaced with the day name.
-Calendar._TT["DAY_FIRST"] = "PrikaÅ¾i %s prvo";
-
-// This may be locale-dependent.  It specifies the week-end days, as an array
-// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
-// means Monday, etc.
-Calendar._TT["WEEKEND"] = "0,6";
-
-Calendar._TT["CLOSE"] = "Zatvori";
-Calendar._TT["TODAY"] = "Danas";
-Calendar._TT["TIME_PART"] = "(Shift-)Klik ili prevlaÄenje za izmjenu vrijednosti";
-
-// date formats
-Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y";
-Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
-
-Calendar._TT["WK"] = "wk";
-Calendar._TT["TIME"] = "Vrijeme:";
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fc/fc6f47b58bfa56e7e03288bcdf7475367e1fb37d.svn-base
--- a/.svn/pristine/fc/fc6f47b58bfa56e7e03288bcdf7475367e1fb37d.svn-base
+++ /dev/null
@@ -1,45 +0,0 @@
-<div class="contextual">
-<%= link_to l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add' %>
-</div>
-
-<h2><%=l(:label_project_plural)%></h2>
-
-<% form_tag({}, :method => :get) do %>
-<fieldset><legend><%= l(:label_filter_plural) %></legend>
-<label for='status'><%= l(:field_status) %> :</label>
-<%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;"  %>
-<label for='name'><%= l(:label_project) %>:</label>
-<%= text_field_tag 'name', params[:name], :size => 30 %>
-<%= submit_tag l(:button_apply), :class => "small", :name => nil %>
-<%= link_to l(:button_clear), {:controller => 'admin', :action => 'projects'}, :class => 'icon icon-reload' %>
-</fieldset>
-<% end %>
-&nbsp;
-
-<div class="autoscroll">
-<table class="list">
-  <thead><tr>
-  <th><%=l(:label_project)%></th>
-  <th><%=l(:field_is_public)%></th>
-  <th><%=l(:field_created_on)%></th>
-  <th></th>
-  </tr></thead>
-  <tbody>
-<% project_tree(@projects) do |project, level| %>
-  <tr class="<%= cycle("odd", "even") %> <%= project.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
-  <td class="name"><span><%= link_to_project(project, {:action => 'settings'}, :title => project.short_description) %></span></td>
-  <td align="center"><%= checked_image project.is_public? %></td>
-  <td align="center"><%= format_date(project.created_on) %></td>
-  <td class="buttons">
-    <%= link_to(l(:button_archive), { :controller => 'projects', :action => 'archive', :id => project, :status => params[:status] }, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-lock') if project.active? %>
-    <%= link_to(l(:button_unarchive), { :controller => 'projects', :action => 'unarchive', :id => project, :status => params[:status] }, :method => :post, :class => 'icon icon-unlock') if !project.active? && (project.parent.nil? || project.parent.active?) %>
-    <%= link_to(l(:button_copy), { :controller => 'projects', :action => 'copy', :id => project }, :class => 'icon icon-copy') %>
-    <%= link_to(l(:button_delete), project_destroy_confirm_path(project), :class => 'icon icon-del') %>
-  </td>
-  </tr>
-<% end %>
-  </tbody>
-</table>
-</div>
-
-<% html_title(l(:label_project_plural)) -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fc/fc76a054eee69ed8d40059f29968dde646077194.svn-base
--- a/.svn/pristine/fc/fc76a054eee69ed8d40059f29968dde646077194.svn-base
+++ /dev/null
@@ -1,42 +0,0 @@
-<% form_tag(project_project_enumerations_path(@project), :method => :put, :class => "tabular") do %>
-
-<table class="list">
-  <thead><tr>
-    <th><%= l(:field_name) %></th>
-    <th><%= l(:enumeration_system_activity) %></th>
-    <% TimeEntryActivity.new.available_custom_fields.each do |value| %>
-    <th><%= h value.name %></th>
-    <% end %>
-    <th style="width:15%;"><%= l(:field_active) %></th>
-  </tr></thead>
-
-  <% @project.activities(true).each do |enumeration| %>
-  <% fields_for "enumerations[#{enumeration.id}]", enumeration do |ff| %>
-  <tr class="<%= cycle('odd', 'even') %>">
-    <td>
-      <%= ff.hidden_field :parent_id, :value => enumeration.id unless enumeration.project %>
-      <%= h(enumeration) %>
-    </td>
-    <td align="center" style="width:15%;"><%= checked_image !enumeration.project %></td>
-    <% enumeration.custom_field_values.each do |value| %>
-    <td align="center">
-      <%= custom_field_tag "enumerations[#{enumeration.id}]", value %>
-    </td>
-    <% end %>
-    <td align="center" style="width:15%;">
-      <%= ff.check_box :active %>
-    </td>
-  </tr>
-  <% end %>
-  <% end %>
-</table>
-
-<div class="contextual">
-<%= link_to(l(:button_reset), project_project_enumerations_path(@project),
-            :method => :delete,
-            :confirm => l(:text_are_you_sure),
-            :class => 'icon icon-del') %>
-</div>
-
-<%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fc/fc770db4db5a22614ed5ce3040fd496687aca860.svn-base
--- /dev/null
+++ b/.svn/pristine/fc/fc770db4db5a22614ed5ce3040fd496687aca860.svn-base
@@ -0,0 +1,240 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingTimelogsTest < ActionController::IntegrationTest
+  def test_timelogs_global
+    assert_routing(
+        { :method => 'get', :path => "/time_entries" },
+        { :controller => 'timelog', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/time_entries.csv" },
+        { :controller => 'timelog', :action => 'index', :format => 'csv' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/time_entries.atom" },
+        { :controller => 'timelog', :action => 'index', :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/time_entries/new" },
+        { :controller => 'timelog', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/time_entries/22/edit" },
+        { :controller => 'timelog', :action => 'edit', :id => '22' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/time_entries" },
+        { :controller => 'timelog', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/time_entries/22" },
+        { :controller => 'timelog', :action => 'update', :id => '22' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/time_entries/55" },
+        { :controller => 'timelog', :action => 'destroy', :id => '55' }
+      )
+  end
+
+  def test_timelogs_scoped_under_project
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/time_entries" },
+        { :controller => 'timelog', :action => 'index', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/time_entries.csv" },
+        { :controller => 'timelog', :action => 'index', :project_id => '567',
+          :format => 'csv' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/time_entries.atom" },
+        { :controller => 'timelog', :action => 'index', :project_id => '567',
+          :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/time_entries/new" },
+        { :controller => 'timelog', :action => 'new', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/projects/567/time_entries/22/edit" },
+        { :controller => 'timelog', :action => 'edit',
+          :id => '22', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/projects/567/time_entries" },
+        { :controller => 'timelog', :action => 'create',
+          :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/projects/567/time_entries/22" },
+        { :controller => 'timelog', :action => 'update',
+          :id => '22', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/projects/567/time_entries/55" },
+        { :controller => 'timelog', :action => 'destroy',
+          :id => '55', :project_id => '567' }
+      )
+  end
+
+  def test_timelogs_scoped_under_issues
+    assert_routing(
+        { :method => 'get', :path => "/issues/234/time_entries" },
+        { :controller => 'timelog', :action => 'index', :issue_id => '234' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/234/time_entries.csv" },
+        { :controller => 'timelog', :action => 'index', :issue_id => '234',
+          :format => 'csv' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/234/time_entries.atom" },
+        { :controller => 'timelog', :action => 'index', :issue_id => '234',
+          :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/234/time_entries/new" },
+        { :controller => 'timelog', :action => 'new', :issue_id => '234' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/issues/234/time_entries/22/edit" },
+        { :controller => 'timelog', :action => 'edit', :id => '22',
+          :issue_id => '234' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/issues/234/time_entries" },
+        { :controller => 'timelog', :action => 'create', :issue_id => '234' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/issues/234/time_entries/22" },
+        { :controller => 'timelog', :action => 'update', :id => '22',
+          :issue_id => '234' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/issues/234/time_entries/55" },
+        { :controller => 'timelog', :action => 'destroy', :id => '55',
+          :issue_id => '234' }
+      )
+  end
+
+  def test_timelogs_scoped_under_project_and_issues
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/ecookbook/issues/234/time_entries" },
+        { :controller => 'timelog', :action => 'index',
+          :issue_id => '234', :project_id => 'ecookbook' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/ecookbook/issues/234/time_entries.csv" },
+        { :controller => 'timelog', :action => 'index',
+          :issue_id => '234', :project_id => 'ecookbook', :format => 'csv' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/ecookbook/issues/234/time_entries.atom" },
+        { :controller => 'timelog', :action => 'index',
+          :issue_id => '234', :project_id => 'ecookbook', :format => 'atom' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/ecookbook/issues/234/time_entries/new" },
+        { :controller => 'timelog', :action => 'new',
+          :issue_id => '234', :project_id => 'ecookbook' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/ecookbook/issues/234/time_entries/22/edit" },
+        { :controller => 'timelog', :action => 'edit', :id => '22',
+          :issue_id => '234', :project_id => 'ecookbook' }
+      )
+    assert_routing(
+        { :method => 'post',
+          :path => "/projects/ecookbook/issues/234/time_entries" },
+        { :controller => 'timelog', :action => 'create',
+          :issue_id => '234', :project_id => 'ecookbook' }
+      )
+    assert_routing(
+        { :method => 'put',
+          :path => "/projects/ecookbook/issues/234/time_entries/22" },
+        { :controller => 'timelog', :action => 'update', :id => '22',
+          :issue_id => '234', :project_id => 'ecookbook' }
+      )
+    assert_routing(
+        { :method => 'delete',
+          :path => "/projects/ecookbook/issues/234/time_entries/55" },
+        { :controller => 'timelog', :action => 'destroy', :id => '55',
+          :issue_id => '234', :project_id => 'ecookbook' }
+      )
+  end
+
+  def test_timelogs_report
+    assert_routing(
+        { :method => 'get',
+          :path => "/time_entries/report" },
+        { :controller => 'timelog', :action => 'report' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/time_entries/report.csv" },
+        { :controller => 'timelog', :action => 'report', :format => 'csv' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/issues/234/time_entries/report" },
+        { :controller => 'timelog', :action => 'report', :issue_id => '234' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/issues/234/time_entries/report.csv" },
+        { :controller => 'timelog', :action => 'report', :issue_id => '234',
+          :format => 'csv' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/567/time_entries/report" },
+        { :controller => 'timelog', :action => 'report', :project_id => '567' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/projects/567/time_entries/report.csv" },
+        { :controller => 'timelog', :action => 'report', :project_id => '567',
+          :format => 'csv' }
+      )
+  end
+
+  def test_timelogs_bulk_edit
+    assert_routing(
+        { :method => 'delete',
+          :path => "/time_entries/destroy" },
+        { :controller => 'timelog', :action => 'destroy' }
+      )
+    assert_routing(
+        { :method => 'post',
+          :path => "/time_entries/bulk_update" },
+        { :controller => 'timelog', :action => 'bulk_update' }
+      )
+    assert_routing(
+        { :method => 'get',
+          :path => "/time_entries/bulk_edit" },
+        { :controller => 'timelog', :action => 'bulk_edit' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fc/fcdff04c6de4b2e2832edf1ac8e1080f0bd88be1.svn-base
--- a/.svn/pristine/fc/fcdff04c6de4b2e2832edf1ac8e1080f0bd88be1.svn-base
+++ /dev/null
@@ -1,49 +0,0 @@
-<h2><%= l(:label_bulk_edit_selected_time_entries) %></h2>
-
-<ul><%= @time_entries.collect {|i| content_tag('li', link_to(h("#{i.spent_on.strftime("%Y-%m-%d")} -- #{i.project}:  #{l(:label_f_hour_plural, :value => i.hours)}"), { :action => 'edit', :id => i }))} %></ul>
-
-<% form_tag(:action => 'bulk_update') do %>
-<%= @time_entries.collect {|i| hidden_field_tag('ids[]', i.id)}.join %>
-<div class="box tabular">
-  <fieldset class="attributes">
-  <legend><%= l(:label_change_properties) %></legend>
-  <div>
-    <p>
-      <label><%= l(:field_issue) %></label>
-      <%= text_field :time_entry, :issue_id, :size => 6 %>
-    </p>
-
-    <p>
-      <label><%= l(:field_spent_on) %></label>
-      <%= text_field :time_entry, :spent_on, :size => 10 %><%= calendar_for('time_entry_spent_on') %>
-    </p>
-
-    <p>
-      <label><%= l(:field_hours) %></label>
-      <%= text_field :time_entry, :hours, :size => 6 %>
-    </p>
-
-    <% if @available_activities.any? %>
-    <p>
-      <label><%= l(:field_activity) %></label>
-      <%= select_tag('time_entry[activity_id]', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@available_activities, :id, :name)) %>
-    </p>
-    <% end %>
-
-    <p>
-      <label><%= l(:field_comments) %></label>
-      <%= text_field(:time_entry, :comments, :size => 100) %>
-    </p>
-
-    <% @custom_fields.each do |custom_field| %>
-      <p><label><%= h(custom_field.name) %></label> <%= custom_field_tag_for_bulk_edit('time_entry', custom_field, @projects) %></p>
-    <% end %>
-
-    <%= call_hook(:view_time_entries_bulk_edit_details_bottom, { :time_entries => @time_entries }) %>
-  </div>
-
-  </fieldset>
-</div>
-
-<p><%= submit_tag l(:button_submit) %></p>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fc/fce0d89d5b88d079f5970994503e60b140fbf5f1.svn-base
--- a/.svn/pristine/fc/fce0d89d5b88d079f5970994503e60b140fbf5f1.svn-base
+++ /dev/null
@@ -1,28 +0,0 @@
-<% selected_tab = params[:tab] ? params[:tab].to_s : tabs.first[:name] %>
-
-<div class="tabs">
-  <ul>
-  <% tabs.each do |tab| -%>
-    <li><%= link_to l(tab[:label]), { :tab => tab[:name] },
-                                    :id => "tab-#{tab[:name]}",
-                                    :class => (tab[:name] != selected_tab ? nil : 'selected'),
-                                    :onclick => "showTab('#{tab[:name]}'); this.blur(); return false;" %></li>
-  <% end -%>
-  </ul>
-  <div class="tabs-buttons" style="display:none;">
-    <button class="tab-left" onclick="moveTabLeft(this);"></button>
-    <button class="tab-right" onclick="moveTabRight(this);"></button>
-  </div>
-</div>
-
-<script>
-  Event.observe(window, 'load', function() { displayTabsButtons(); });
-  Event.observe(window, 'resize', function() { displayTabsButtons(); });
-</script>
-
-<% tabs.each do |tab| -%>
-  <%= content_tag('div', render(:partial => tab[:partial], :locals => {:tab => tab} ),
-                       :id => "tab-content-#{tab[:name]}",
-                       :style => (tab[:name] != selected_tab ? 'display:none' : nil),
-                       :class => 'tab-content') %>
-<% end -%>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fd/fd17adbe8ddb5fa8d4ce1ceca6975396fcf0109b.svn-base
--- a/.svn/pristine/fd/fd17adbe8ddb5fa8d4ce1ceca6975396fcf0109b.svn-base
+++ /dev/null
@@ -1,152 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-module Redmine
-  module Hook
-    include ActionController::UrlWriter
-
-    @@listener_classes = []
-    @@listeners = nil
-    @@hook_listeners = {}
-
-    class << self
-      # Adds a listener class.
-      # Automatically called when a class inherits from Redmine::Hook::Listener.
-      def add_listener(klass)
-        raise "Hooks must include Singleton module." unless klass.included_modules.include?(Singleton)
-        @@listener_classes << klass
-        clear_listeners_instances
-      end
-
-      # Returns all the listerners instances.
-      def listeners
-        @@listeners ||= @@listener_classes.collect {|listener| listener.instance}
-      end
-
-      # Returns the listeners instances for the given hook.
-      def hook_listeners(hook)
-        @@hook_listeners[hook] ||= listeners.select {|listener| listener.respond_to?(hook)}
-      end
-
-      # Clears all the listeners.
-      def clear_listeners
-        @@listener_classes = []
-        clear_listeners_instances
-      end
-
-      # Clears all the listeners instances.
-      def clear_listeners_instances
-        @@listeners = nil
-        @@hook_listeners = {}
-      end
-
-      # Calls a hook.
-      # Returns the listeners response.
-      def call_hook(hook, context={})
-        [].tap do |response|
-          hls = hook_listeners(hook)
-          if hls.any?
-            hls.each {|listener| response << listener.send(hook, context)}
-          end
-        end
-      end
-    end
-
-    # Base class for hook listeners.
-    class Listener
-      include Singleton
-      include Redmine::I18n
-
-      # Registers the listener
-      def self.inherited(child)
-        Redmine::Hook.add_listener(child)
-        super
-      end
-
-    end
-
-    # Listener class used for views hooks.
-    # Listeners that inherit this class will include various helpers by default.
-    class ViewListener < Listener
-      include ERB::Util
-      include ActionView::Helpers::TagHelper
-      include ActionView::Helpers::FormHelper
-      include ActionView::Helpers::FormTagHelper
-      include ActionView::Helpers::FormOptionsHelper
-      include ActionView::Helpers::JavaScriptHelper
-      include ActionView::Helpers::PrototypeHelper
-      include ActionView::Helpers::NumberHelper
-      include ActionView::Helpers::UrlHelper
-      include ActionView::Helpers::AssetTagHelper
-      include ActionView::Helpers::TextHelper
-      include ActionController::UrlWriter
-      include ApplicationHelper
-
-      # Default to creating links using only the path.  Subclasses can
-      # change this default as needed
-      def self.default_url_options
-        {:only_path => true }
-      end
-
-      # Helper method to directly render a partial using the context:
-      #
-      #   class MyHook < Redmine::Hook::ViewListener
-      #     render_on :view_issues_show_details_bottom, :partial => "show_more_data"
-      #   end
-      #
-      def self.render_on(hook, options={})
-        define_method hook do |context|
-          context[:controller].send(:render_to_string, {:locals => context}.merge(options))
-        end
-      end
-    end
-
-    # Helper module included in ApplicationHelper and ActionController so that
-    # hooks can be called in views like this:
-    #
-    #   <%= call_hook(:some_hook) %>
-    #   <%= call_hook(:another_hook, :foo => 'bar') %>
-    #
-    # Or in controllers like:
-    #   call_hook(:some_hook)
-    #   call_hook(:another_hook, :foo => 'bar')
-    #
-    # Hooks added to views will be concatenated into a string. Hooks added to
-    # controllers will return an array of results.
-    #
-    # Several objects are automatically added to the call context:
-    #
-    # * project => current project
-    # * request => Request instance
-    # * controller => current Controller instance
-    #
-    module Helper
-      def call_hook(hook, context={})
-        if is_a?(ActionController::Base)
-          default_context = {:controller => self, :project => @project, :request => request}
-          Redmine::Hook.call_hook(hook, default_context.merge(context))
-        else
-          default_context = {:controller => controller, :project => @project, :request => request}
-          Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ')
-        end
-      end
-    end
-  end
-end
-
-ApplicationHelper.send(:include, Redmine::Hook::Helper)
-ActionController::Base.send(:include, Redmine::Hook::Helper)
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fd/fd1d523c594bd4b054ab83cfa0a889d70d5c4b29.svn-base
--- /dev/null
+++ b/.svn/pristine/fd/fd1d523c594bd4b054ab83cfa0a889d70d5c4b29.svn-base
@@ -0,0 +1,1186 @@
+#
+# Translated by Saadat Mutallimova
+# Data Processing Center of the Ministry of Communication and Information Technologies
+# 
+az:
+  direction: ltr
+  date:
+    formats:
+      default: "%d.%m.%Y"
+      short: "%d %b"
+      long: "%d %B %Y"
+
+    day_names: [bazar, bazar ertÉ™si, Ã§É™rÅŸÉ™nbÉ™ axÅŸamÄ±, Ã§É™rÅŸÉ™nbÉ™, cÃ¼mÉ™ axÅŸamÄ±, cÃ¼mÉ™, ÅŸÉ™nbÉ™]
+    standalone_day_names: [Bazar, Bazar ertÉ™si, Ã‡É™rÅŸÉ™nbÉ™ axÅŸamÄ±, Ã‡É™rÅŸÉ™nbÉ™, CÃ¼mÉ™ axÅŸamÄ±, CÃ¼mÉ™, ÅžÉ™nbÉ™]
+    abbr_day_names: [B, Be, Ã‡a, Ã‡, Ca, C, Åž]
+
+    month_names: [~, yanvar, fevral, mart, aprel, may, iyun, iyul, avqust, sentyabr, oktyabr, noyabr, dekabr]
+    # see russian gem for info on "standalone" day names
+    standalone_month_names: [~, Yanvar, Fevral, Mart, Aprel, May, Ä°yun, Ä°yul, Avqust, Sentyabr, Oktyabr, Noyabr, Dekabr]
+    abbr_month_names: [~, yan., fev., mart, apr., may, iyun, iyul, avq., sent., okt., noy., dek.]
+    standalone_abbr_month_names: [~, yan., fev., mart, apr., may, iyun, iyul, avq., sent., okt., noy., dek.]
+
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a, %d %b %Y, %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b, %H:%M"
+      long: "%d %B %Y, %H:%M"
+
+    am: "sÉ™hÉ™r"
+    pm: "axÅŸam"
+
+  number:
+    format:
+      separator: ","
+      delimiter: " "
+      precision: 3
+
+    currency:
+      format:
+        format: "%n %u"
+        unit: "man."
+        separator: "."
+        delimiter: " "
+        precision: 2
+
+    percentage:
+      format:
+        delimiter: ""
+
+    precision:
+      format:
+        delimiter: ""
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      # Rails 2.2
+      # storage_units: [Ð±Ð°Ð¹Ñ‚, ÐšÐ‘, ÐœÐ‘, Ð“Ð‘, Ð¢Ð‘]
+
+      # Rails 2.3
+      storage_units:
+        # Storage units output formatting.
+        # %u is the storage unit, %n is the number (default: 2 MB)
+        format: "%n %u"
+        units:
+          byte:
+            one:   "bayt"
+            few:   "bayt"
+            many:  "bayt"
+            other: "bayt"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "bir dÉ™qiqÉ™dÉ™n az"
+      less_than_x_seconds:
+        one:   "%{count} saniyÉ™dÉ™n az"
+        few:   "%{count} saniyÉ™dÉ™n az"
+        many:  "%{count} saniyÉ™dÉ™n az"
+        other: "%{count} saniyÉ™dÉ™n az"
+      x_seconds:
+        one:   "%{count} saniyÉ™"
+        few:   "%{count} saniyÉ™"
+        many:  "%{count} saniyÉ™"
+        other: "%{count} saniyÉ™"
+      less_than_x_minutes:
+        one:   "%{count} dÉ™qiqÉ™dÉ™n az"
+        few:   "%{count} dÉ™qiqÉ™dÉ™n az"
+        many:  "%{count} dÉ™qiqÉ™dÉ™n az"
+        other: "%{count} dÉ™qiqÉ™dÉ™n az"
+      x_minutes:
+        one:   "%{count} dÉ™qiqÉ™"
+        few:   "%{count} dÉ™qiqÉ™"
+        many:  "%{count} dÉ™qiqÉ™"
+        other: "%{count} dÉ™qiqÉ™"
+      about_x_hours:
+        one:   "tÉ™xminÉ™n %{count} saat"
+        few:   "tÉ™xminÉ™n %{count} saat"
+        many:  "tÉ™xminÉ™n %{count} saat"
+        other: "tÉ™xminÉ™n %{count} saat"
+      x_hours:
+        one:   "1 saat"
+        other: "%{count} saat"
+      x_days:
+        one:   "%{count} gÃ¼n"
+        few:   "%{count} gÃ¼n"
+        many:  "%{count} gÃ¼n"
+        other: "%{count} gÃ¼n"
+      about_x_months:
+        one:   "tÉ™xminÉ™n %{count} ay"
+        few:   "tÉ™xminÉ™n %{count} ay"
+        many:  "tÉ™xminÉ™n %{count} ay"
+        other: "tÉ™xminÉ™n %{count} ay"
+      x_months:
+        one:   "%{count} ay"
+        few:   "%{count} ay"
+        many:  "%{count} ay"
+        other: "%{count} ay"
+      about_x_years:
+        one:   "tÉ™xminÉ™n %{count} il"
+        few:   "tÉ™xminÉ™n %{count} il"
+        many:  "tÉ™xminÉ™n %{count} il"
+        other: "tÉ™xminÉ™n %{count} il"
+      over_x_years:
+        one:   "%{count} ildÉ™n Ã§ox"
+        few:   "%{count} ildÉ™n Ã§ox"
+        many:  "%{count} ildÉ™n Ã§ox"
+        other: "%{count} ildÉ™n Ã§ox"
+      almost_x_years:
+        one:   "tÉ™xminÉ™n 1 il"
+        few:   "tÉ™xminÉ™n %{count} il"
+        many:  "tÉ™xminÉ™n %{count} il"
+        other: "tÉ™xminÉ™n %{count} il"
+    prompts:
+      year: "Ä°l"
+      month: "Ay"
+      day: "GÃ¼n"
+      hour: "Saat"
+      minute: "DÉ™qiqÉ™"
+      second: "SaniyÉ™"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:   "%{model}: %{count} sÉ™hvÉ™ gÃ¶rÉ™ yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±"
+          few:   "%{model}: %{count} sÉ™hvlÉ™rÉ™ gÃ¶rÉ™ yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±"
+          many:  "%{model}: %{count} sÉ™hvlÉ™rÉ™ gÃ¶rÉ™ yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±"
+          other: "%{model}: %{count} sÉ™hvÉ™ gÃ¶rÉ™ yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±"
+
+        body: "ProblemlÉ™r aÅŸaÄŸÄ±dakÄ± sahÉ™lÉ™rdÉ™ yarandÄ±:"
+
+      messages:
+        inclusion: "nÉ™zÉ™rdÉ™ tutulmamÄ±ÅŸ tÉ™yinata malikdir"
+        exclusion: "ehtiyata gÃ¶tÃ¼rÃ¼lmÉ™miÅŸ tÉ™yinata malikdir"
+        invalid: "dÃ¼zgÃ¼n tÉ™yinat deyildir"
+        confirmation: "tÉ™sdiq ilÉ™ Ã¼st-Ã¼stÉ™ dÃ¼ÅŸmÃ¼r"
+        accepted: "tÉ™sdiq etmÉ™k lazÄ±mdÄ±r"
+        empty: "boÅŸ saxlanÄ±la bilmÉ™z"
+        blank: "boÅŸ saxlanÄ±la bilmÉ™z"
+        too_long:
+          one:   "Ã§ox bÃ¶yÃ¼k uzunluq (%{count} simvoldan Ã§ox ola bilmÉ™z)"
+          few:   "Ã§ox bÃ¶yÃ¼k uzunluq (%{count} simvoldan Ã§ox ola bilmÉ™z)"
+          many:  "Ã§ox bÃ¶yÃ¼k uzunluq (%{count} simvoldan Ã§ox ola bilmÉ™z)"
+          other: "Ã§ox bÃ¶yÃ¼k uzunluq (%{count} simvoldan Ã§ox ola bilmÉ™z)"
+        too_short:
+          one:   "uzunluq kifayÉ™t qÉ™dÉ™r deyildir (%{count} simvoldan az ola bilmÉ™z)"
+          few:   "uzunluq kifayÉ™t qÉ™dÉ™r deyildir (%{count} simvoldan az ola bilmÉ™z)"
+          many:  "uzunluq kifayÉ™t qÉ™dÉ™r deyildir (%{count} simvoldan az ola bilmÉ™z)"
+          other: "uzunluq kifayÉ™t qÉ™dÉ™r deyildir (%{count} simvoldan az ola bilmÉ™z)"
+        wrong_length:
+          one:   "dÃ¼zgÃ¼n olmayan uzunluq (tam %{count} simvol ola bilÉ™r)"
+          few:   "dÃ¼zgÃ¼n olmayan uzunluq (tam %{count} simvol ola bilÉ™r)"
+          many:  "dÃ¼zgÃ¼n olmayan uzunluq (tam %{count} simvol ola bilÉ™r)"
+          other: "dÃ¼zgÃ¼n olmayan uzunluq (tam %{count} simvol ola bilÉ™r)"
+        taken: "artÄ±q mÃ¶vcuddur"
+        not_a_number: "say kimi hesab edilmir"
+        greater_than: "%{count} Ã§ox tÉ™yinata malik ola bilÉ™r"
+        greater_than_or_equal_to: "%{count} Ã§ox vÉ™ ya ona bÉ™rabÉ™r tÉ™yinata malik ola bilÉ™r"
+        equal_to: "yalnÄ±z %{count} bÉ™rabÉ™r tÉ™yinata malik ola bilÉ™r"
+        less_than: "%{count} az tÉ™yinata malik ola bilÉ™r"
+        less_than_or_equal_to: "%{count} az vÉ™ ya ona bÉ™rabÉ™r tÉ™yinata malik ola bilÉ™r"
+        odd: "yalnÄ±z tÉ™k tÉ™yinata malik ola bilÉ™r"
+        even: "yalnÄ±z cÃ¼t tÉ™yinata malik ola bilÉ™r"
+        greater_than_start_date: "baÅŸlanÄŸÄ±c tarixindÉ™n sonra olmalÄ±dÄ±r"
+        not_same_project: "tÉ™kcÉ™ bir layihÉ™yÉ™ aid deyildir"
+        circular_dependency: "BelÉ™ É™laqÉ™ dÃ¶vri asÄ±lÄ±lÄ±ÄŸa gÉ™tirib Ã§Ä±xaracaq"
+        cant_link_an_issue_with_a_descendant: "TapÅŸÄ±rÄ±q Ã¶zÃ¼nÃ¼n alt tapÅŸÄ±rÄ±ÄŸÄ± ilÉ™ É™laqÉ™li ola bilmÉ™z"
+
+  support:
+    array:
+      # Rails 2.2
+      sentence_connector: "vÉ™"
+      skip_last_comma: true
+
+      # Rails 2.3
+      words_connector: ", "
+      two_words_connector: " vÉ™"
+      last_word_connector: " vÉ™ "
+
+  actionview_instancetag_blank_option: SeÃ§im edin
+
+  button_activate: AktivlÉ™ÅŸdirmÉ™k
+  button_add: ÆlavÉ™ etmÉ™k
+  button_annotate: MÃ¼É™lliflik
+  button_apply: TÉ™tbiq etmÉ™k
+  button_archive: ArxivlÉ™ÅŸdirmÉ™k
+  button_back: GeriyÉ™
+  button_cancel: Ä°mtina
+  button_change_password: Parolu dÉ™yiÅŸmÉ™k
+  button_change: DÉ™yiÅŸmÉ™k
+  button_check_all: HamÄ±nÄ± qeyd etmÉ™k
+  button_clear: TÉ™mizlÉ™mÉ™k
+  button_configure: ParametlÉ™r
+  button_copy: SÃ¼rÉ™tini Ã§Ä±xarmaq
+  button_create: Yaratmaq
+  button_create_and_continue: Yaratmaq vÉ™ davam etmÉ™k
+  button_delete: SilmÉ™k
+  button_download: YÃ¼klÉ™mÉ™k
+  button_edit: RedaktÉ™ etmÉ™k
+  button_edit_associated_wikipage: "ÆlaqÉ™li wiki-sÉ™hifÉ™ni redaktÉ™ etmÉ™k: %{page_title}"
+  button_list: SiyahÄ±
+  button_lock: Bloka salmaq
+  button_login: GiriÅŸ
+  button_log_time: SÉ™rf olunan vaxt
+  button_move: Yerini dÉ™yiÅŸmÉ™k
+  button_quote: Sitat gÉ™tirmÉ™k
+  button_rename: AdÄ±nÄ± dÉ™yiÅŸmÉ™k
+  button_reply: Cavablamaq
+  button_reset: SÄ±fÄ±rlamaq
+  button_rollback: Bu versiyaya qayÄ±tmaq
+  button_save: Yadda saxlamaq
+  button_sort: Ã‡eÅŸidlÉ™mÉ™k
+  button_submit: QÉ™bul etmÉ™k
+  button_test: Yoxlamaq
+  button_unarchive: ArxivdÉ™n Ã§Ä±xarmaq
+  button_uncheck_all: TÉ™mizlÉ™mÉ™k
+  button_unlock: Blokdan Ã§Ä±xarmaq
+  button_unwatch: Ä°zlÉ™mÉ™mÉ™k
+  button_update: YenilÉ™mÉ™k
+  button_view: Baxmaq
+  button_watch: Ä°zlÉ™mÉ™k
+
+  default_activity_design: LayihÉ™nin hazÄ±rlanmasÄ±
+  default_activity_development: HazÄ±rlanma prosesi
+  default_doc_category_tech: Texniki sÉ™nÉ™dlÉ™ÅŸmÉ™
+  default_doc_category_user: Ä°stifadÉ™Ã§i sÉ™nÉ™di
+  default_issue_status_in_progress: Ä°ÅŸlÉ™nmÉ™kdÉ™dir
+  default_issue_status_closed: BaÄŸlanÄ±b
+  default_issue_status_feedback: Æks É™laqÉ™
+  default_issue_status_new: Yeni
+  default_issue_status_rejected: RÉ™dd etmÉ™
+  default_issue_status_resolved: HÉ™ll edilib
+  default_priority_high: YÃ¼ksÉ™k
+  default_priority_immediate: TÉ™xirsiz
+  default_priority_low: AÅŸaÄŸÄ±
+  default_priority_normal: Normal
+  default_priority_urgent: TÉ™cili
+  default_role_developer: HazÄ±rlayan
+  default_role_manager: Menecer
+  default_role_reporter: Reportyor
+  default_tracker_bug: SÉ™hv
+  default_tracker_feature: TÉ™kmillÉ™ÅŸmÉ™
+  default_tracker_support: DÉ™stÉ™k
+
+  enumeration_activities: HÉ™rÉ™kÉ™tlÉ™r (vaxtÄ±n uÃ§otu)
+  enumeration_doc_categories: SÉ™nÉ™dlÉ™rin kateqoriyasÄ±
+  enumeration_issue_priorities: TapÅŸÄ±rÄ±qlarÄ±n prioriteti
+
+  error_can_not_remove_role: Bu rol istifadÉ™ edilir vÉ™ silinÉ™ bilmÉ™z.
+  error_can_not_delete_custom_field: SazlanmÄ±ÅŸ sahÉ™ni silmÉ™k mÃ¼mkÃ¼n deyildir
+  error_can_not_delete_tracker: Bu treker tapÅŸÄ±rÄ±qlardan ibarÉ™t olduÄŸu Ã¼Ã§Ã¼n silinÉ™ bilmÉ™z.
+  error_can_t_load_default_data: "Susmaya gÃ¶rÉ™ konfiqurasiya yÃ¼klÉ™nmÉ™miÅŸdir: %{value}"
+  error_issue_not_found_in_project: TapÅŸÄ±rÄ±q tapÄ±lmamÄ±ÅŸdÄ±r vÉ™ ya bu layihÉ™yÉ™ bÉ™rkidilmÉ™miÅŸdir
+  error_scm_annotate: "VerilÉ™nlÉ™r mÃ¶vcud deyildir vÉ™ ya imzalana bilmÉ™z."
+  error_scm_command_failed: "SaxlayÄ±cÄ±ya giriÅŸ imkanÄ± sÉ™hvi: %{value}"
+  error_scm_not_found: SaxlayÄ±cÄ±da yazÄ± vÉ™/ vÉ™ ya dÃ¼zÉ™liÅŸ yoxdur.
+  error_unable_to_connect: QoÅŸulmaq mÃ¼mkÃ¼n deyildir (%{value})
+  error_unable_delete_issue_status: TapÅŸÄ±rÄ±ÄŸÄ±n statusunu silmÉ™k mÃ¼mkÃ¼n deyildir
+
+  field_account: Ä°stifadÉ™Ã§i hesabÄ±
+  field_activity: FÉ™aliyyÉ™t
+  field_admin: Ä°nzibatÃ§Ä±
+  field_assignable: TapÅŸÄ±rÄ±q bu rola tÉ™yin edilÉ™ bilÉ™r
+  field_assigned_to: TÉ™yin edilib
+  field_attr_firstname: Ad
+  field_attr_lastname: Soyad
+  field_attr_login: Atribut Login
+  field_attr_mail: e-poÃ§t
+  field_author: MÃ¼É™llif
+  field_auth_source: Autentifikasiya rejimi
+  field_base_dn: BaseDN
+  field_category: Kateqoriya
+  field_column_names: SÃ¼tunlar
+  field_comments: ÅžÉ™rhlÉ™r
+  field_comments_sorting: ÅžÉ™rhlÉ™rin tÉ™sviri
+  field_content: Content
+  field_created_on: YaradÄ±lÄ±b
+  field_default_value: Susmaya gÃ¶rÉ™ tÉ™yinat
+  field_delay: TÉ™xirÉ™ salmaq
+  field_description: TÉ™svir
+  field_done_ratio: HazÄ±rlÄ±q
+  field_downloads: YÃ¼klÉ™mÉ™lÉ™r
+  field_due_date: YerinÉ™ yetirilmÉ™ tarixi
+  field_editable: RedaktÉ™ edilÉ™n
+  field_effective_date: Tarix
+  field_estimated_hours: VaxtÄ±n dÉ™yÉ™rlÉ™ndirilmÉ™si
+  field_field_format: Format
+  field_filename: Fayl
+  field_filesize: Ã–lÃ§Ã¼
+  field_firstname: Ad
+  field_fixed_version: Variant
+  field_hide_mail: E-poÃ§tumu gizlÉ™t
+  field_homepage: BaÅŸlanÄŸÄ±c sÉ™hifÉ™
+  field_host: Kompyuter
+  field_hours: saat
+  field_identifier: Unikal identifikator
+  field_identity_url: OpenID URL
+  field_is_closed: TapÅŸÄ±rÄ±q baÄŸlanÄ±b
+  field_is_default: Susmaya gÃ¶rÉ™ tapÅŸÄ±rÄ±q
+  field_is_filter: Filtr kimi istifadÉ™ edilir
+  field_is_for_all: BÃ¼tÃ¼n layihÉ™lÉ™r Ã¼Ã§Ã¼n
+  field_is_in_roadmap: Operativ planda É™ks olunan tapÅŸÄ±rÄ±qlar
+  field_is_public: ÃœmÃ¼maÃ§Ä±q
+  field_is_required: MÃ¼tlÉ™q
+  field_issue_to: ÆlaqÉ™li tapÅŸÄ±rÄ±qlar
+  field_issue: TapÅŸÄ±rÄ±q
+  field_language: Dil
+  field_last_login_on: Son qoÅŸulma
+  field_lastname: Soyad
+  field_login: Ä°stifadÉ™Ã§i
+  field_mail: e-poÃ§t
+  field_mail_notification: e-poÃ§t ilÉ™ bildiriÅŸ
+  field_max_length: maksimal uzunluq
+  field_min_length: minimal uzunluq
+  field_name: Ad
+  field_new_password: Yeni parol
+  field_notes: Qeyd
+  field_onthefly: Tez bir zamanda istifadÉ™Ã§inin yaradÄ±lmasÄ±
+  field_parent_title: Valideyn sÉ™hifÉ™
+  field_parent: Valideyn layihÉ™
+  field_parent_issue: Valideyn tapÅŸÄ±rÄ±q
+  field_password_confirmation: TÉ™sdiq 
+  field_password: Parol
+  field_port: Port
+  field_possible_values: MÃ¼mkÃ¼n olan tÉ™yinatlar
+  field_priority: Prioritet
+  field_project: LayihÉ™
+  field_redirect_existing_links: MÃ¶vcud olan istinadlarÄ± istiqamÉ™tlÉ™ndirmÉ™k
+  field_regexp: MÃ¼ntÉ™zÉ™m ifadÉ™
+  field_role: Rol
+  field_searchable: AxtarÄ±ÅŸ Ã¼Ã§Ã¼n aÃ§Ä±qdÄ±r
+  field_spent_on: Tarix
+  field_start_date: BaÅŸlanÄ±b
+  field_start_page: BaÅŸlanÄŸÄ±c sÉ™hifÉ™
+  field_status: Status
+  field_subject: MÃ¶vzu
+  field_subproject: AltlayihÉ™
+  field_summary: QÄ±sa tÉ™svir
+  field_text: MÉ™tn sahÉ™si
+  field_time_entries: SÉ™rf olunan zaman
+  field_time_zone: Saat qurÅŸaÄŸÄ±
+  field_title: BaÅŸlÄ±q
+  field_tracker: Treker
+  field_type: Tip
+  field_updated_on: YenilÉ™nib
+  field_url: URL
+  field_user: Ä°stifadÉ™Ã§i
+  field_value: TÉ™yinat
+  field_version: Variant
+  field_watcher: NÉ™zarÉ™tÃ§i
+
+  general_csv_decimal_separator: ','
+  general_csv_encoding: UTF-8
+  general_csv_separator: ';'
+  general_first_day_of_week: '1'
+  general_lang_name: 'Azerbaijanian (Azeri)'
+  general_pdf_encoding: UTF-8
+  general_text_no: 'xeyr'
+  general_text_No: 'Xeyr'
+  general_text_yes: 'bÉ™li'
+  general_text_Yes: 'BÉ™li'
+
+  label_activity: GÃ¶rÃ¼lÉ™n iÅŸlÉ™r
+  label_add_another_file: Bir fayl daha É™lavÉ™ etmÉ™k
+  label_added_time_by: "ÆlavÉ™ etdi %{author} %{age} É™vvÉ™l"
+  label_added: É™lavÉ™ edilib
+  label_add_note: Qeydi É™lavÉ™ etmÉ™k
+  label_administration: Ä°nzibatÃ§Ä±lÄ±q
+  label_age: YaÅŸ
+  label_ago: gÃ¼n É™vvÉ™l
+  label_all_time: hÉ™r zaman
+  label_all_words: BÃ¼tÃ¼n sÃ¶zlÉ™r
+  label_all: hamÄ±
+  label_and_its_subprojects: "%{value} vÉ™ bÃ¼tÃ¼n altlayihÉ™lÉ™r"
+  label_applied_status: TÉ™tbiq olunan status
+  label_ascending: Artmaya gÃ¶rÉ™
+  label_assigned_to_me_issues: MÉ™nim tapÅŸÄ±rÄ±qlarÄ±m
+  label_associated_revisions: ÆlaqÉ™li redaksiyalar
+  label_attachment: Fayl
+  label_attachment_delete: FaylÄ± silmÉ™k
+  label_attachment_new: Yeni fayl
+  label_attachment_plural: Fayllar
+  label_attribute: Atribut
+  label_attribute_plural: Atributlar
+  label_authentication: Autentifikasiya
+  label_auth_source: AutentifikasiyanÄ±n rejimi
+  label_auth_source_new: AutentifikasiyanÄ±n yeni rejimi
+  label_auth_source_plural: AutentifikasiyanÄ±n rejimlÉ™ri
+  label_blocked_by: bloklanÄ±r
+  label_blocks: bloklayÄ±r
+  label_board: Forum
+  label_board_new: Yeni forum
+  label_board_plural: Forumlar
+  label_boolean: MÉ™ntiqi
+  label_browse: BaxÄ±ÅŸ
+  label_bulk_edit_selected_issues: SeÃ§ilÉ™n bÃ¼tÃ¼n tapÅŸÄ±rÄ±qlarÄ± redaktÉ™ etmÉ™k
+  label_calendar: TÉ™qvim
+  label_calendar_filter: O cÃ¼mlÉ™dÉ™n
+  label_calendar_no_assigned: MÉ™nim deyil
+  label_change_plural: DÉ™yiÅŸikliklÉ™r
+  label_change_properties: XassÉ™lÉ™ri dÉ™yiÅŸmÉ™k
+  label_change_status: Statusu dÉ™yiÅŸmÉ™k
+  label_change_view_all: BÃ¼tÃ¼n dÉ™yiÅŸikliklÉ™rÉ™ baxmaq
+  label_changes_details: BÃ¼tÃ¼n dÉ™yiÅŸikliklÉ™rÉ™ gÃ¶rÉ™ tÉ™fsilatlar
+  label_changeset_plural: DÉ™yiÅŸikliklÉ™r
+  label_chronological_order: Xronoloji ardÄ±cÄ±llÄ±q ilÉ™
+  label_closed_issues: BaÄŸlÄ±dÄ±r
+  label_closed_issues_plural: baÄŸlÄ±dÄ±r
+  label_closed_issues_plural2: baÄŸlÄ±dÄ±r
+  label_closed_issues_plural5: baÄŸlÄ±dÄ±r
+  label_comment: ÅŸÉ™rhlÉ™r
+  label_comment_add: ÅžÉ™rhlÉ™ri qeyd etmÉ™k
+  label_comment_added: ÆlavÉ™ olunmuÅŸ ÅŸÉ™rhlÉ™r
+  label_comment_delete: ÅžÉ™rhi silmÉ™k
+  label_comment_plural: ÅžÉ™rhlÉ™r
+  label_comment_plural2: ÅžÉ™rhlÉ™r
+  label_comment_plural5: ÅŸÉ™rhlÉ™rin
+  label_commits_per_author: Ä°stifadÉ™Ã§i Ã¼zÉ™rindÉ™ dÉ™yiÅŸikliklÉ™r
+  label_commits_per_month: Ay Ã¼zÉ™rindÉ™ dÉ™yiÅŸikliklÉ™r
+  label_confirmation: TÉ™sdiq 
+  label_contains: tÉ™rkibi
+  label_copied: surÉ™ti kÃ¶Ã§Ã¼rÃ¼lÃ¼b
+  label_copy_workflow_from: gÃ¶rÃ¼lÉ™n iÅŸlÉ™rin ardÄ±cÄ±llÄ±ÄŸÄ±nÄ±n surÉ™tini kÃ¶Ã§Ã¼rmÉ™k
+  label_current_status: Cari status
+  label_current_version: Cari variant
+  label_custom_field: Sazlanan sahÉ™
+  label_custom_field_new: Yeni sazlanan sahÉ™
+  label_custom_field_plural: Sazlanan sahÉ™lÉ™r
+  label_date_from: Ð¡
+  label_date_from_to: Ð¡ %{start} Ð¿Ð¾ %{end}
+  label_date_range: vaxt intervalÄ±
+  label_date_to: Ã¼zrÉ™
+  label_date: Tarix
+  label_day_plural: gÃ¼n
+  label_default: Susmaya gÃ¶rÉ™
+  label_default_columns: Susmaya gÃ¶rÉ™ sÃ¼tunlar
+  label_deleted: silinib
+  label_descending: Azalmaya gÃ¶rÉ™
+  label_details: TÉ™fsilatlar
+  label_diff_inline: mÉ™tndÉ™
+  label_diff_side_by_side: YanaÅŸÄ±
+  label_disabled: sÃ¶ndÃ¼rÃ¼lÃ¼b
+  label_display: TÉ™svir
+  label_display_per_page: "SÉ™hifÉ™yÉ™: %{value}"
+  label_document: SÉ™nÉ™d
+  label_document_added: SÉ™nÉ™d É™lavÉ™ edilib
+  label_document_new: Yeni sÉ™nÉ™d
+  label_document_plural: SÉ™nÉ™dlÉ™r
+  label_downloads_abbr: YÃ¼klÉ™mÉ™lÉ™r
+  label_duplicated_by: Ã§oxaldÄ±lÄ±r
+  label_duplicates: Ã§oxaldÄ±r
+  label_end_to_end: sondan sona doÄŸru
+  label_end_to_start: sondan É™vvÉ™lÉ™ doÄŸru
+  label_enumeration_new: Yeni qiymÉ™t
+  label_enumerations: QiymÉ™tlÉ™rin siyahÄ±sÄ±
+  label_environment: MÃ¼hit
+  label_equals: sayÄ±lÄ±r
+  label_example: NÃ¼munÉ™
+  label_export_to: ixrac etmÉ™k 
+  label_feed_plural: RSS
+  label_feeds_access_key_created_on: "RSS-É™ giriÅŸ aÃ§arÄ± %{value} É™vvÉ™l yaradÄ±lÄ±b"
+  label_f_hour: "%{value} saat"
+  label_f_hour_plural: "%{value} saat"
+  label_file_added: Fayl É™lavÉ™ edilib
+  label_file_plural: Fayllar
+  label_filter_add: Filtr É™lavÉ™ etmÉ™k
+  label_filter_plural: FiltrlÉ™r
+  label_float: HÉ™qiqi É™dÉ™d
+  label_follows: ÆvvÉ™lki
+  label_gantt: Qant diaqrammasÄ±
+  label_general: Ãœmumi
+  label_generate_key: AÃ§arÄ± generasiya etmÉ™k
+  label_greater_or_equal: ">="
+  label_help: KÃ¶mÉ™k
+  label_history: TarixÃ§É™
+  label_home: Ana sÉ™hifÉ™
+  label_incoming_emails: MÉ™lumatlarÄ±n qÉ™bulu
+  label_index_by_date: SÉ™hifÉ™lÉ™rin tarixÃ§É™si
+  label_index_by_title: BaÅŸlÄ±q
+  label_information_plural: Ä°nformasiya
+  label_information: Ä°nformasiya
+  label_in_less_than: az
+  label_in_more_than: Ã§ox
+  label_integer: Tam
+  label_internal: Daxili
+  label_in: da (dÉ™)
+  label_issue: TapÅŸÄ±rÄ±q
+  label_issue_added: TapÅŸÄ±rÄ±q É™lavÉ™ edilib
+  label_issue_category_new: Yeni kateqoriya
+  label_issue_category_plural: TapÅŸÄ±rÄ±ÄŸÄ±n kateqoriyasÄ±
+  label_issue_category: TapÅŸÄ±rÄ±ÄŸÄ±n kateqoriyasÄ±
+  label_issue_new: Yeni tapÅŸÄ±rÄ±q
+  label_issue_plural: TapÅŸÄ±rÄ±qlar
+  label_issues_by: "%{value} Ã¼zrÉ™ Ã§eÅŸidlÉ™mÉ™k"
+  label_issue_status_new: Yeni status
+  label_issue_status_plural: TapÅŸÄ±rÄ±qlarÄ±n statusu
+  label_issue_status: TapÅŸÄ±rÄ±ÄŸÄ±n statusu
+  label_issue_tracking: TapÅŸÄ±rÄ±qlar
+  label_issue_updated: TapÅŸÄ±rÄ±q yenilÉ™nib
+  label_issue_view_all: BÃ¼tÃ¼n tapÅŸÄ±rÄ±qlara baxmaq
+  label_issue_watchers: NÉ™zarÉ™tÃ§ilÉ™r
+  label_jump_to_a_project: ... layihÉ™yÉ™ keÃ§id
+  label_language_based: Dilin É™sasÄ±nda
+  label_last_changes: "%{count} az dÉ™yiÅŸiklik"
+  label_last_login: Sonuncu qoÅŸulma
+  label_last_month: sonuncu ay
+  label_last_n_days: "son %{count} gÃ¼n"
+  label_last_week: sonuncu hÉ™ftÉ™
+  label_latest_revision: Sonuncu redaksiya
+  label_latest_revision_plural: Sonuncu redaksiyalar
+  label_ldap_authentication: LDAP vasitÉ™silÉ™ avtorizasiya
+  label_less_or_equal: <=
+  label_less_than_ago: gÃ¼ndÉ™n az
+  label_list: SiyahÄ±
+  label_loading: YÃ¼klÉ™mÉ™...
+  label_logged_as: Daxil olmusunuz
+  label_login: Daxil olmaq
+  label_login_with_open_id_option: vÉ™ ya OpenID vasitÉ™silÉ™ daxil olmaq
+  label_logout: Ã‡Ä±xÄ±ÅŸ
+  label_max_size: Maksimal Ã¶lÃ§Ã¼
+  label_member_new: Yeni iÅŸtirakÃ§Ä±
+  label_member: Ä°ÅŸtirakÃ§Ä±
+  label_member_plural: Ä°ÅŸtirakÃ§Ä±lar
+  label_message_last: Sonuncu mÉ™lumat
+  label_message_new: Yeni mÉ™lumat
+  label_message_plural: MÉ™lumatlar
+  label_message_posted: MÉ™lumat É™lavÉ™ olunub
+  label_me: mÉ™nÉ™
+  label_min_max_length: Minimal - maksimal uzunluq
+  label_modified: dÉ™yiÅŸilib
+  label_module_plural: Modullar
+  label_months_from: ay
+  label_month: Ay
+  label_more_than_ago: gÃ¼ndÉ™n É™vvÉ™l
+  label_more: Ã‡ox
+  label_my_account: MÉ™nim hesabÄ±m
+  label_my_page: MÉ™nim sÉ™hifÉ™m
+  label_my_page_block: MÉ™nim sÉ™hifÉ™min bloku
+  label_my_projects: MÉ™nim layihÉ™lÉ™rim
+  label_new: Yeni
+  label_new_statuses_allowed: Ä°cazÉ™ verilÉ™n yeni statuslar
+  label_news_added: XÉ™bÉ™r É™lavÉ™ edilib
+  label_news_latest: Son xÉ™bÉ™rlÉ™r
+  label_news_new: XÉ™bÉ™r É™lavÉ™ etmÉ™k
+  label_news_plural: XÉ™bÉ™rlÉ™r
+  label_news_view_all: BÃ¼tÃ¼n xÉ™bÉ™rlÉ™rÉ™ baxmaq
+  label_news: XÉ™bÉ™rlÉ™r
+  label_next: NÃ¶vbÉ™ti
+  label_nobody: heÃ§ kim
+  label_no_change_option: (DÉ™yiÅŸiklik yoxdur)
+  label_no_data: TÉ™svir Ã¼Ã§Ã¼n verilÉ™nlÉ™r yoxdur
+  label_none: yoxdur
+  label_not_contains: mÃ¶vcud deyil
+  label_not_equals: sayÄ±lmÄ±r
+  label_open_issues: aÃ§Ä±qdÄ±r
+  label_open_issues_plural: aÃ§Ä±qdÄ±r
+  label_open_issues_plural2: aÃ§Ä±qdÄ±r
+  label_open_issues_plural5: aÃ§Ä±qdÄ±r
+  label_optional_description: TÉ™svir (vacib deyil)
+  label_options: Opsiyalar
+  label_overall_activity: GÃ¶rÃ¼lÉ™n iÅŸlÉ™rin toplu hesabatÄ±
+  label_overview: BaxÄ±ÅŸ
+  label_password_lost: Parolun bÉ™rpasÄ±
+  label_permissions_report: GiriÅŸ hÃ¼quqlarÄ± Ã¼zrÉ™ hesabat 
+  label_permissions: GiriÅŸ hÃ¼quqlarÄ±
+  label_per_page: SÉ™hifÉ™yÉ™
+  label_personalize_page: bu sÉ™hifÉ™ni fÉ™rdilÉ™ÅŸdirmÉ™k
+  label_planning: PlanlaÅŸdÄ±rma
+  label_please_login: XahiÅŸ edirik, daxil olun.
+  label_plugins: Modullar
+  label_precedes: nÃ¶vbÉ™ti
+  label_preferences: ÃœstÃ¼nlÃ¼k
+  label_preview: Ä°lkin baxÄ±ÅŸ
+  label_previous: ÆvvÉ™lki
+  label_profile: Profil
+  label_project: LayihÉ™
+  label_project_all: BÃ¼tÃ¼n layihÉ™lÉ™r
+  label_project_copy_notifications: LayihÉ™nin surÉ™tinin Ã§Ä±xarÄ±lmasÄ± zamanÄ± elektron poÃ§t ilÉ™ bildiriÅŸ gÃ¶ndÉ™rmÉ™k
+  label_project_latest: Son layihÉ™lÉ™r
+  label_project_new: Yeni layihÉ™
+  label_project_plural: LayihÉ™lÉ™r
+  label_project_plural2: layihÉ™ni
+  label_project_plural5: layihÉ™lÉ™ri
+  label_public_projects: Ãœmumi layihÉ™lÉ™r
+  label_query: Yadda saxlanÄ±lmÄ±ÅŸ sorÄŸu
+  label_query_new: Yeni sorÄŸu
+  label_query_plural: Yadda saxlanÄ±lmÄ±ÅŸ sorÄŸular
+  label_read: Oxu...
+  label_register: Qeydiyyat
+  label_registered_on: Qeydiyyatdan keÃ§ib
+  label_registration_activation_by_email: e-poÃ§t Ã¼zrÉ™ hesabÄ±mÄ±n aktivlÉ™ÅŸdirilmÉ™si
+  label_registration_automatic_activation: uÃ§ot qeydlÉ™rinin avtomatik aktivlÉ™ÅŸdirilmÉ™si
+  label_registration_manual_activation: uÃ§ot qeydlÉ™rini É™l ilÉ™ aktivlÉ™ÅŸdirmÉ™k
+  label_related_issues: ÆlaqÉ™li tapÅŸÄ±rÄ±qlar
+  label_relates_to: É™laqÉ™lidir
+  label_relation_delete: ÆlaqÉ™ni silmÉ™k
+  label_relation_new: Yeni mÃ¼nasibÉ™t
+  label_renamed: adÄ±nÄ± dÉ™yiÅŸmÉ™k
+  label_reply_plural: Cavablar
+  label_report: Hesabat
+  label_report_plural: Hesabatlar
+  label_reported_issues: YaradÄ±lan tapÅŸÄ±rÄ±qlar
+  label_repository: SaxlayÄ±cÄ±
+  label_repository_plural: SaxlayÄ±cÄ±
+  label_result_plural: NÉ™ticÉ™lÉ™r
+  label_reverse_chronological_order: Æks ardÄ±cÄ±llÄ±qda
+  label_revision: Redaksiya
+  label_revision_plural: Redaksiyalar
+  label_roadmap: Operativ plan
+  label_roadmap_due_in: "%{value} mÃ¼ddÉ™tindÉ™"
+  label_roadmap_no_issues: bu versiya Ã¼Ã§Ã¼n tapÅŸÄ±rÄ±q yoxdur
+  label_roadmap_overdue: "gecikmÉ™ %{value}"
+  label_role: Rol
+  label_role_and_permissions: Rollar vÉ™ giriÅŸ hÃ¼quqlarÄ±
+  label_role_new: Yeni rol
+  label_role_plural: Rollar
+  label_scm: SaxlayÄ±cÄ±nÄ±n tipi
+  label_search: AxtarÄ±ÅŸ
+  label_search_titles_only: Ancaq adlarda axtarmaq
+  label_send_information: Ä°stifadÉ™Ã§iyÉ™ uÃ§ot qeydlÉ™ri Ã¼zrÉ™ informasiyanÄ± gÃ¶ndÉ™rmÉ™k
+  label_send_test_email: Yoxlama Ã¼Ã§Ã¼n email gÃ¶ndÉ™rmÉ™k
+  label_settings: Sazlamalar
+  label_show_completed_versions: BitmiÅŸ variantlarÄ± gÃ¶stÉ™rmÉ™k
+  label_sort: Ã‡eÅŸidlÉ™mÉ™k
+  label_sort_by: "%{value} Ã¼zrÉ™ Ã§eÅŸidlÉ™mÉ™k"
+  label_sort_higher: YuxarÄ±
+  label_sort_highest: ÆvvÉ™lÉ™ qayÄ±t
+  label_sort_lower: AÅŸaÄŸÄ±
+  label_sort_lowest: Sona qayÄ±t
+  label_spent_time: SÉ™rf olunan vaxt
+  label_start_to_end: É™vvÉ™ldÉ™n axÄ±ra doÄŸru
+  label_start_to_start: É™vvÉ™ldÉ™n É™vvÉ™lÉ™ doÄŸru
+  label_statistics: Statistika
+  label_stay_logged_in: SistemdÉ™ qalmaq
+  label_string: MÉ™tn
+  label_subproject_plural: AltlayihÉ™lÉ™r
+  label_subtask_plural: Alt tapÅŸÄ±rÄ±qlar
+  label_text: Uzun mÉ™tn 
+  label_theme: MÃ¶vzu
+  label_this_month: bu ay
+  label_this_week: bu hÉ™ftÉ™
+  label_this_year: bu il
+  label_time_tracking: VaxtÄ±n uÃ§otu
+  label_timelog_today: Bu gÃ¼nÉ™ sÉ™rf olunan vaxt
+  label_today: bu gÃ¼n
+  label_topic_plural: MÃ¶vzular
+  label_total: CÉ™mi
+  label_tracker: Treker
+  label_tracker_new: Yeni treker
+  label_tracker_plural: TrekerlÉ™r
+  label_updated_time: "%{value} É™vvÉ™l yenilÉ™nib"
+  label_updated_time_by: "%{author} %{age} É™vvÉ™l yenilÉ™nib"
+  label_used_by: Ä°stifadÉ™ olunur
+  label_user: Ä°stifasdÉ™Ã§i
+  label_user_activity: "Ä°stifadÉ™Ã§inin gÃ¶rdÃ¼yÃ¼ iÅŸlÉ™r %{value}"
+  label_user_mail_no_self_notified: "TÉ™rÉ™fimdÉ™n edilÉ™n dÉ™yiÅŸikliklÉ™r haqqÄ±nda mÉ™ni xÉ™bÉ™rdar etmÉ™mÉ™k"
+  label_user_mail_option_all: "MÉ™nim layihÉ™lÉ™rimdÉ™ki bÃ¼tÃ¼n hadisÉ™lÉ™r haqqÄ±nda"
+  label_user_mail_option_selected: "YalnÄ±z seÃ§ilÉ™n layihÉ™dÉ™ki bÃ¼tÃ¼n hadisÉ™lÉ™r haqqÄ±nda..."
+  label_user_mail_option_only_owner: YalnÄ±z sahibi olduÄŸum obyektlÉ™r Ã¼Ã§Ã¼n
+  label_user_mail_option_only_my_events: YalnÄ±z izlÉ™diyim vÉ™ ya iÅŸtirak etdiyim obyektlÉ™r Ã¼Ã§Ã¼n
+  label_user_mail_option_only_assigned: YalnÄ±z mÉ™nÉ™ tÉ™yin edilÉ™n obyektlÉ™r Ã¼Ã§Ã¼n
+  label_user_new: Yeni istifadÉ™Ã§i
+  label_user_plural: Ä°stifadÉ™Ã§ilÉ™r
+  label_version: Variant
+  label_version_new: Yeni variant
+  label_version_plural: Variantlar
+  label_view_diff: FÉ™rqlÉ™rÉ™ baxmaq
+  label_view_revisions: Redaksiyalara baxmaq
+  label_watched_issues: TapÅŸÄ±rÄ±ÄŸÄ±n izlÉ™nilmÉ™si
+  label_week: HÉ™ftÉ™
+  label_wiki: Wiki
+  label_wiki_edit: Wiki-nin redaktÉ™si
+  label_wiki_edit_plural: Wiki
+  label_wiki_page: Wiki sÉ™hifÉ™si
+  label_wiki_page_plural: Wiki sÉ™hifÉ™lÉ™ri
+  label_workflow: GÃ¶rÃ¼lÉ™n iÅŸlÉ™rin ardÄ±cÄ±llÄ±ÄŸÄ±
+  label_x_closed_issues_abbr:
+    zero:  "0 baÄŸlÄ±dÄ±r"
+    one:   "1 baÄŸlanÄ±b"
+    few:   "%{count} baÄŸlÄ±dÄ±r"
+    many:  "%{count} baÄŸlÄ±dÄ±r"
+    other: "%{count} baÄŸlÄ±dÄ±r"
+  label_x_comments:
+    zero:  "ÅŸÉ™rh yoxdur"
+    one:   "1 ÅŸÉ™rh"
+    few:   "%{count} ÅŸÉ™rhlÉ™r"
+    many:  "%{count} ÅŸÉ™rh"
+    other: "%{count} ÅŸÉ™rh"
+  label_x_open_issues_abbr:
+    zero:  "0 aÃ§Ä±qdÄ±r"
+    one:   "1 aÃ§Ä±q"
+    few:   "%{count} aÃ§Ä±qdÄ±r"
+    many:  "%{count} aÃ§Ä±qdÄ±r"
+    other: "%{count} aÃ§Ä±qdÄ±r"
+  label_x_open_issues_abbr_on_total:
+    zero:  "0 aÃ§Ä±qdÄ±r / %{total}"
+    one:   "1 aÃ§Ä±qdÄ±r / %{total}"
+    few:   "%{count} aÃ§Ä±qdÄ±r / %{total}"
+    many:  "%{count} aÃ§Ä±qdÄ±r / %{total}"
+    other: "%{count} aÃ§Ä±qdÄ±r / %{total}"
+  label_x_projects:
+    zero:  "layihÉ™lÉ™r yoxdur"
+    one:   "1 layihÉ™"
+    few:   "%{count} layihÉ™"
+    many:  "%{count} layihÉ™"
+    other: "%{count} layihÉ™"
+  label_year: Ä°l
+  label_yesterday: dÃ¼nÉ™n
+
+  mail_body_account_activation_request: "Yeni istifadÉ™Ã§i qeydiyyatdan keÃ§ib (%{value}). UÃ§ot qeydi Sizin tÉ™sdiqinizi gÃ¶zlÉ™yir:"
+  mail_body_account_information: Sizin uÃ§ot qeydiniz haqqÄ±nda informasiya
+  mail_body_account_information_external: "Siz Ã¶zÃ¼nÃ¼zÃ¼n %{value} uÃ§ot qeydinizi giriÅŸ Ã¼Ã§Ã¼n istifadÉ™ edÉ™ bilÉ™rsiniz."
+  mail_body_lost_password: 'Parolun dÉ™yiÅŸdirilmÉ™si Ã¼Ã§Ã¼n aÅŸaÄŸÄ±dakÄ± linkÉ™ keÃ§in:'
+  mail_body_register: 'UÃ§ot qeydinin aktivlÉ™ÅŸdirilmÉ™si Ã¼Ã§Ã¼n aÅŸaÄŸÄ±dakÄ± linkÉ™ keÃ§in:'
+  mail_body_reminder: "nÃ¶vbÉ™ti %{days} gÃ¼n Ã¼Ã§Ã¼n SizÉ™ tÉ™yin olunan %{count}:"
+  mail_subject_account_activation_request: "SistemdÉ™ istifadÉ™Ã§inin aktivlÉ™ÅŸdirilmÉ™si Ã¼Ã§Ã¼n sorÄŸu %{value}"
+  mail_subject_lost_password: "Sizin %{value} parolunuz"
+  mail_subject_register: "UÃ§ot qeydinin aktivlÉ™ÅŸdirilmÉ™si %{value}"
+  mail_subject_reminder: "yaxÄ±n %{days} gÃ¼n Ã¼Ã§Ã¼n SizÉ™ tÉ™yin olunan %{count}"
+
+  notice_account_activated: Sizin uÃ§ot qeydiniz aktivlÉ™ÅŸdirilib. SistemÉ™ daxil ola bilÉ™rsiniz.
+  notice_account_invalid_creditentials: Ä°stifadÉ™Ã§i adÄ± vÉ™ ya parolu dÃ¼zgÃ¼n deyildir
+  notice_account_lost_email_sent: SizÉ™ yeni parolun seÃ§imi ilÉ™ baÄŸlÄ± tÉ™limatÄ± É™ks etdirÉ™n mÉ™ktub gÃ¶ndÉ™rilmiÅŸdir.
+  notice_account_password_updated: Parol mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yenilÉ™ndi.
+  notice_account_pending: "Sizin uÃ§ot qeydiniz yaradÄ±ldÄ± vÉ™ inzibatÃ§Ä±nÄ±n tÉ™sdiqini gÃ¶zlÉ™yir."
+  notice_account_register_done: UÃ§ot qeydi mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yaradÄ±ldÄ±. Sizin uÃ§ot qeydinizin aktivlÉ™ÅŸdirilmÉ™si Ã¼Ã§Ã¼n elektron poÃ§tunuza gÃ¶ndÉ™rilÉ™n linkÉ™ keÃ§in.
+  notice_account_unknown_email: NamÉ™lum istifadÉ™Ã§i.
+  notice_account_updated: UÃ§ot qeydi mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yenilÉ™ndi.
+  notice_account_wrong_password: Parol dÃ¼zgÃ¼n deyildir
+  notice_can_t_change_password: Bu uÃ§ot qeydi Ã¼Ã§Ã¼n xarici autentifikasiya mÉ™nbÉ™yi istifadÉ™ olunur. Parolu dÉ™yiÅŸmÉ™k mÃ¼mkÃ¼n deyildir.
+  notice_default_data_loaded: Susmaya gÃ¶rÉ™ konfiqurasiya yÃ¼klÉ™nilmiÅŸdir.
+  notice_email_error: "MÉ™ktubun gÃ¶ndÉ™rilmÉ™si zamanÄ± sÉ™hv baÅŸ vermiÅŸdi (%{value})"
+  notice_email_sent: "MÉ™ktub gÃ¶ndÉ™rilib %{value}"
+  notice_failed_to_save_issues: "SeÃ§ilÉ™n %{total} iÃ§É™risindÉ™n %{count} bÉ™ndlÉ™ri saxlamaq mÃ¼mkÃ¼n olmadÄ±: %{ids}."
+  notice_failed_to_save_members: "Ä°ÅŸtirakÃ§Ä±nÄ± (larÄ±) yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±: %{errors}."
+  notice_feeds_access_key_reseted: Sizin RSS giriÅŸ aÃ§arÄ±nÄ±z sÄ±fÄ±rlanmÄ±ÅŸdÄ±r.
+  notice_file_not_found: Daxil olmaÄŸa Ã§alÄ±ÅŸdÄ±ÄŸÄ±nÄ±z sÉ™hifÉ™ mÃ¶vcud deyildir vÉ™ ya silinib.
+  notice_locking_conflict: Ä°nformasiya digÉ™r istifadÉ™Ã§i tÉ™rÉ™findÉ™n yenilÉ™nib.
+  notice_no_issue_selected: "HeÃ§ bir tapÅŸÄ±rÄ±q seÃ§ilmÉ™yib! XahiÅŸ edirik, redaktÉ™ etmÉ™k istÉ™diyiniz tapÅŸÄ±rÄ±ÄŸÄ± qeyd edin."
+  notice_not_authorized: Sizin bu sÉ™hifÉ™yÉ™ daxil olmaq hÃ¼ququnuz yoxdur.
+  notice_successful_connection: QoÅŸulma mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yerinÉ™ yetirilib.
+  notice_successful_create: Yaratma mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yerinÉ™ yetirildi.
+  notice_successful_delete: SilinmÉ™ mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yerinÉ™ yetirildi.
+  notice_successful_update: YenilÉ™mÉ™ mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yerinÉ™ yetirildi.
+  notice_unable_delete_version: VariantÄ± silmÉ™k mÃ¼mkÃ¼n olmadÄ±.
+
+  permission_add_issues: TapÅŸÄ±rÄ±qlarÄ±n É™lavÉ™ edilmÉ™si
+  permission_add_issue_notes: QeydlÉ™rin É™lavÉ™ edilmÉ™si
+  permission_add_issue_watchers: NÉ™zarÉ™tÃ§ilÉ™rin É™lavÉ™ edilmÉ™si
+  permission_add_messages: MÉ™lumatlarÄ±n gÃ¶ndÉ™rilmÉ™si
+  permission_browse_repository: SaxlayÄ±cÄ±ya baxÄ±ÅŸ
+  permission_comment_news: XÉ™bÉ™rlÉ™rÉ™ ÅŸÉ™rh
+  permission_commit_access: SaxlayÄ±cÄ±da fayllarÄ±n dÉ™yiÅŸdirilmÉ™si
+  permission_delete_issues: TapÅŸÄ±rÄ±qlarÄ±n silinmÉ™si
+  permission_delete_messages: MÉ™lumatlarÄ±n silinmÉ™si
+  permission_delete_own_messages: ÅžÉ™xsi mÉ™lumatlarÄ±n silinmÉ™si
+  permission_delete_wiki_pages: Wiki-sÉ™hifÉ™lÉ™rin silinmÉ™si
+  permission_delete_wiki_pages_attachments: BÉ™rkidilÉ™n fayllarÄ±n silinmÉ™si
+  permission_edit_issue_notes: QeydlÉ™rin redaktÉ™ edilmÉ™si
+  permission_edit_issues: TapÅŸÄ±rÄ±qlarÄ±n redaktÉ™ edilmÉ™si
+  permission_edit_messages: MÉ™lumatlarÄ±n redaktÉ™ edilmÉ™si
+  permission_edit_own_issue_notes: ÅžÉ™xsi qeydlÉ™rin redaktÉ™ edilmÉ™si
+  permission_edit_own_messages: ÅžÉ™xsi mÉ™lumatlarÄ±n redaktÉ™ edilmÉ™si
+  permission_edit_own_time_entries: ÅžÉ™xsi vaxt uÃ§otunun redaktÉ™ edilmÉ™si
+  permission_edit_project: LayihÉ™lÉ™rin redaktÉ™ edilmÉ™si
+  permission_edit_time_entries: Vaxt uÃ§otunun redaktÉ™ edilmÉ™si
+  permission_edit_wiki_pages: Wiki-sÉ™hifÉ™nin redaktÉ™ edilmÉ™si
+  permission_export_wiki_pages: Wiki-sÉ™hifÉ™nin ixracÄ±
+  permission_log_time: SÉ™rf olunan vaxtÄ±n uÃ§otu
+  permission_view_changesets: SaxlayÄ±cÄ± dÉ™yiÅŸikliklÉ™rinÉ™ baxÄ±ÅŸ 
+  permission_view_time_entries: SÉ™rf olunan vaxta baxÄ±ÅŸ
+  permission_manage_project_activities: LayihÉ™ Ã¼Ã§Ã¼n hÉ™rÉ™kÉ™t tiplÉ™rinin idarÉ™ edilmÉ™si
+  permission_manage_boards: ForumlarÄ±n idarÉ™ edilmÉ™si
+  permission_manage_categories: TapÅŸÄ±rÄ±q kateqoriyalarÄ±nÄ±n idarÉ™ edilmÉ™si
+  permission_manage_files: FayllarÄ±n idarÉ™ edilmÉ™si
+  permission_manage_issue_relations: TapÅŸÄ±rÄ±q baÄŸlantÄ±larÄ±nÄ±n idarÉ™ edilmÉ™si
+  permission_manage_members: Ä°ÅŸtirakÃ§Ä±larÄ±n idarÉ™ edilmÉ™si
+  permission_manage_news: XÉ™bÉ™rlÉ™rin idarÉ™ edilmÉ™si
+  permission_manage_public_queries: Ãœmumi sorÄŸularÄ±n idarÉ™ edilmÉ™si
+  permission_manage_repository: SaxlayÄ±cÄ±nÄ±n idarÉ™ edilmÉ™si
+  permission_manage_subtasks: Alt tapÅŸÄ±rÄ±qlarÄ±n idarÉ™ edilmÉ™si
+  permission_manage_versions: VariantlarÄ±n idarÉ™ edilmÉ™si
+  permission_manage_wiki: Wiki-nin idarÉ™ edilmÉ™si
+  permission_move_issues: TapÅŸÄ±rÄ±qlarÄ±n kÃ¶Ã§Ã¼rÃ¼lmÉ™si
+  permission_protect_wiki_pages: Wiki-sÉ™hifÉ™lÉ™rin bloklanmasÄ±
+  permission_rename_wiki_pages: Wiki-sÉ™hifÉ™lÉ™rin adÄ±nÄ±n dÉ™yiÅŸdirilmÉ™si
+  permission_save_queries: SorÄŸularÄ±n yadda saxlanÄ±lmasÄ±
+  permission_select_project_modules: LayihÉ™ modulunun seÃ§imi
+  permission_view_calendar: TÉ™qvimÉ™ baxÄ±ÅŸ
+  permission_view_documents: SÉ™nÉ™dlÉ™rÉ™ baxÄ±ÅŸ
+  permission_view_files: Fayllara baxÄ±ÅŸ
+  permission_view_gantt: Qant diaqramÄ±na baxÄ±ÅŸ
+  permission_view_issue_watchers: NÉ™zarÉ™tÃ§ilÉ™rin siyahÄ±larÄ±na baxÄ±ÅŸ
+  permission_view_messages: MÉ™lumatlara baxÄ±ÅŸ
+  permission_view_wiki_edits: Wiki tarixÃ§É™sinÉ™ baxÄ±ÅŸ
+  permission_view_wiki_pages: Wiki-yÉ™ baxÄ±ÅŸ
+
+  project_module_boards: Forumlar
+  project_module_documents: SÉ™nÉ™dlÉ™r
+  project_module_files: Fayllar
+  project_module_issue_tracking: TapÅŸÄ±rÄ±qlar
+  project_module_news: XÉ™bÉ™rlÉ™r
+  project_module_repository: SaxlayÄ±cÄ±
+  project_module_time_tracking: VaxtÄ±n uÃ§otu
+  project_module_wiki: Wiki
+  project_module_gantt: Qant diaqramÄ±
+  project_module_calendar: TÉ™qvim
+
+  setting_activity_days_default: GÃ¶rÃ¼lÉ™n iÅŸlÉ™rdÉ™ É™ks olunan gÃ¼nlÉ™rin sayÄ±
+  setting_app_subtitle: ÆlavÉ™nin sÉ™rlÃ¶vhÉ™si
+  setting_app_title: ÆlavÉ™nin adÄ±
+  setting_attachment_max_size: YerlÉ™ÅŸdirmÉ™nin maksimal Ã¶lÃ§Ã¼sÃ¼
+  setting_autofetch_changesets: SaxlayÄ±cÄ±nÄ±n dÉ™yiÅŸikliklÉ™rini avtomatik izlÉ™mÉ™k
+  setting_autologin: Avtomatik giriÅŸ
+  setting_bcc_recipients: Gizli surÉ™tlÉ™ri istifadÉ™ etmÉ™k (BCC)
+  setting_cache_formatted_text: FormatlaÅŸdÄ±rÄ±lmÄ±ÅŸ mÉ™tnin heÅŸlÉ™nmÉ™si
+  setting_commit_fix_keywords: AÃ§ar sÃ¶zlÉ™rin tÉ™yini
+  setting_commit_ref_keywords: AxtarÄ±ÅŸ Ã¼Ã§Ã¼n aÃ§ar sÃ¶zlÉ™r
+  setting_cross_project_issue_relations: LayihÉ™lÉ™r Ã¼zrÉ™ tapÅŸÄ±rÄ±qlarÄ±n kÉ™siÅŸmÉ™sinÉ™ icazÉ™ vermÉ™k
+  setting_date_format: Tarixin formatÄ±
+  setting_default_language: Susmaya gÃ¶rÉ™ dil
+  setting_default_notification_option: Susmaya gÃ¶rÉ™ xÉ™bÉ™rdarlÄ±q Ã¼sulu
+  setting_default_projects_public: Yeni layihÉ™lÉ™r Ã¼mumaÃ§Ä±q hesab edilir
+  setting_diff_max_lines_displayed: diff Ã¼Ã§Ã¼n sÉ™tirlÉ™rin maksimal sayÄ± 
+  setting_display_subprojects_issues: Susmaya gÃ¶rÉ™ altlayihÉ™lÉ™rin É™ks olunmasÄ±
+  setting_emails_footer: MÉ™ktubun sÉ™tiraltÄ± qeydlÉ™ri
+  setting_enabled_scm: Daxil edilÉ™n SCM
+  setting_feeds_limit: RSS axÄ±nÄ± Ã¼Ã§Ã¼n baÅŸlÄ±qlarÄ±n sayÄ±nÄ±n mÉ™hdudlaÅŸdÄ±rÄ±lmasÄ±
+  setting_file_max_size_displayed: Æks olunma Ã¼Ã§Ã¼n mÉ™tn faylÄ±nÄ±n maksimal Ã¶lÃ§Ã¼sÃ¼
+  setting_gravatar_enabled: Ä°stifadÉ™Ã§i avatarÄ±nÄ± Gravatar-dan istifadÉ™ etmÉ™k
+  setting_host_name: Kompyuterin adÄ±
+  setting_issue_list_default_columns: Susmaya gÃ¶rÉ™ tapÅŸÄ±rÄ±qlarÄ±n siyahÄ±sÄ±nda É™ks oluna sÃ¼tunlar
+  setting_issues_export_limit: Ä°xrac olunan tapÅŸÄ±rÄ±qlar Ã¼zrÉ™ mÉ™hdudiyyÉ™tlÉ™r
+  setting_login_required: Autentifikasiya vacibdir
+  setting_mail_from: Ã‡Ä±xan e-poÃ§t Ã¼nvanÄ±
+  setting_mail_handler_api_enabled: Daxil olan mÉ™lumatlar Ã¼Ã§Ã¼n veb-servisi qoÅŸmaq
+  setting_mail_handler_api_key: API aÃ§ar
+  setting_openid: GiriÅŸ vÉ™ qeydiyyat Ã¼Ã§Ã¼n OpenID izacÉ™ vermÉ™k
+  setting_per_page_options: SÉ™hifÉ™ Ã¼Ã§Ã¼n qeydlÉ™rin sayÄ±
+  setting_plain_text_mail: YalnÄ±z sadÉ™ mÉ™tn (HTML olmadan)
+  setting_protocol: Protokol
+  setting_repository_log_display_limit: DÉ™yiÅŸikliklÉ™r jurnalÄ±nda É™ks olunan redaksiyalarÄ±n maksimal sayÄ±
+  setting_self_registration: Ã–zÃ¼nÃ¼qeydiyyat
+  setting_sequential_project_identifiers: LayihÉ™lÉ™rin ardÄ±cÄ±l identifikatorlarÄ±nÄ± generasiya etmÉ™k
+  setting_sys_api_enabled: SaxlayÄ±cÄ±nÄ±n idarÉ™ edilmÉ™si Ã¼Ã§Ã¼n veb-servisi qoÅŸmaq
+  setting_text_formatting: MÉ™tnin formatlaÅŸdÄ±rÄ±lmasÄ±
+  setting_time_format: VaxtÄ±n formatÄ±
+  setting_user_format: AdÄ±n É™ks olunma formatÄ±
+  setting_welcome_text: Salamlama mÉ™tni 
+  setting_wiki_compression: Wiki tarixÃ§É™sinin sÄ±xlaÅŸdÄ±rÄ±lmasÄ±
+
+  status_active: aktivdir
+  status_locked: bloklanÄ±b
+  status_registered: qeydiyyatdan keÃ§ib
+
+  text_are_you_sure: Siz É™minsinizmi?
+  text_assign_time_entries_to_project: Qeydiyyata alÄ±nmÄ±ÅŸ vaxtÄ± layihÉ™yÉ™ bÉ™rkitmÉ™k
+  text_caracters_maximum: "Maksimum %{count} simvol."
+  text_caracters_minimum: "%{count} simvoldan az olmamalÄ±dÄ±r."
+  text_comma_separated: Bir neÃ§É™ qiymÉ™t mÃ¼mkÃ¼ndÃ¼r (vergÃ¼l vasitÉ™silÉ™).
+  text_custom_field_possible_values_info: 'HÉ™r sÉ™tirÉ™ bir qiymÉ™t'
+  text_default_administrator_account_changed: Ä°nzibatÃ§Ä±nÄ±n uÃ§ot qeydi susmaya gÃ¶rÉ™ dÉ™yiÅŸmiÅŸdir
+  text_destroy_time_entries_question: "Bu tapÅŸÄ±rÄ±q Ã¼Ã§Ã¼n sÉ™rf olunan vaxta gÃ¶rÉ™ %{hours} saat qeydiyyata alÄ±nÄ±b. Siz nÉ™ etmÉ™k istÉ™yirsiniz?"
+  text_destroy_time_entries: Qeydiyyata alÄ±nmÄ±ÅŸ vaxtÄ± silmÉ™k
+  text_diff_truncated: '... Bu diff mÉ™hduddur, Ã§Ã¼nki É™ks olunan maksimal Ã¶lÃ§Ã¼nÃ¼ keÃ§ir.'
+  text_email_delivery_not_configured: "PoÃ§t serveri ilÉ™ iÅŸin parametrlÉ™ri sazlanmayÄ±b vÉ™ e-poÃ§t ilÉ™ bildiriÅŸ funksiyasÄ± aktiv deyildir.\nSizin SMTP-server Ã¼Ã§Ã¼n parametrlÉ™ri config/configuration.yml faylÄ±ndan sazlaya bilÉ™rsiniz. DÉ™yiÅŸikliklÉ™rin tÉ™tbiq edilmÉ™si Ã¼Ã§Ã¼n É™lavÉ™ni yenidÉ™n baÅŸladÄ±n."
+  text_enumeration_category_reassign_to: 'Onlara aÅŸaÄŸÄ±dakÄ± qiymÉ™tlÉ™ri tÉ™yin etmÉ™k:'
+  text_enumeration_destroy_question: "%{count} obyekt bu qiymÉ™tlÉ™ baÄŸlÄ±dÄ±r."
+  text_file_repository_writable: QeydÉ™ giriÅŸ imkanÄ± olan saxlayÄ±cÄ±
+  text_issue_added: "Yeni tapÅŸÄ±rÄ±q yaradÄ±lÄ±b %{id} (%{author})."
+  text_issue_category_destroy_assignments: KateqoriyanÄ±n tÉ™yinatÄ±nÄ± silmÉ™k
+  text_issue_category_destroy_question: "Bir neÃ§É™ tapÅŸÄ±rÄ±q (%{count}) bu kateqoriya Ã¼Ã§Ã¼n tÉ™yin edilib. Siz nÉ™ etmÉ™k istÉ™yirsiniz?"
+  text_issue_category_reassign_to: Bu kateqoriya Ã¼Ã§Ã¼n tapÅŸÄ±rÄ±ÄŸÄ± yenidÉ™n tÉ™yin etmÉ™k
+  text_issues_destroy_confirmation: 'SeÃ§ilÉ™n tapÅŸÄ±rÄ±qlarÄ± silmÉ™k istÉ™diyinizÉ™ É™minsinizmi?'
+  text_issues_ref_in_commit_messages: MÉ™lumatÄ±n mÉ™tnindÉ™n Ã§Ä±xÄ±ÅŸ edÉ™rÉ™k tapÅŸÄ±rÄ±qlarÄ±n statuslarÄ±nÄ±n tutuÅŸdurulmasÄ± vÉ™ dÉ™yiÅŸdirilmÉ™si
+  text_issue_updated: "TapÅŸÄ±rÄ±q %{id} yenilÉ™nib (%{author})."
+  text_journal_changed: "Parametr %{label} %{old} - %{new} dÉ™yiÅŸib"
+  text_journal_deleted: "Parametrin %{old} qiymÉ™ti %{label} silinib"
+  text_journal_set_to: "%{label} parametri %{value} dÉ™yiÅŸib"
+  text_length_between: "%{min} vÉ™ %{max} simvollar arasÄ±ndakÄ± uzunluq."
+  text_load_default_configuration: Susmaya gÃ¶rÉ™ konfiqurasiyanÄ± yÃ¼klÉ™mÉ™k
+  text_min_max_length_info: 0 mÉ™hdudiyyÉ™tlÉ™rin olmadÄ±ÄŸÄ±nÄ± bildirir
+  text_no_configuration_data: "Rollar, trekerlÉ™r, tapÅŸÄ±rÄ±qlarÄ±n statuslarÄ± vÉ™ operativ plan konfiqurasiya olunmayÄ±blar.\nSusmaya gÃ¶rÉ™ konfiqurasiyanÄ±n yÃ¼klÉ™nmÉ™si tÉ™kidlÉ™ xahiÅŸ olunur. Siz onu sonradan dÉ™yiÅŸÉ™ bilÉ™rsiniz."
+  text_plugin_assets_writable: Modullar kataloqu qeyd Ã¼Ã§Ã¼n aÃ§Ä±qdÄ±r
+  text_project_destroy_confirmation: Siz bu layihÉ™ vÉ™ ona aid olan bÃ¼tÃ¼n informasiyanÄ± silmÉ™k istÉ™diyinizÉ™ É™minsinizmi?
+  text_reassign_time_entries: 'Qeydiyyata alÄ±nmÄ±ÅŸ vaxtÄ± aÅŸaÄŸÄ±dakÄ± tapÅŸÄ±rÄ±ÄŸa keÃ§ir:'
+  text_regexp_info: "mÉ™sÉ™lÉ™n: ^[A-Z0-9]+$"
+  text_repository_usernames_mapping: "SaxlayÄ±cÄ±nÄ±n jurnalÄ±nda tapÄ±lan adlarla baÄŸlÄ± olan Redmine istifadÉ™Ã§isini seÃ§in vÉ™ ya yenilÉ™yin.\nEyni ad vÉ™ e-poÃ§ta sahib olan istifadÉ™Ã§ilÉ™r Redmine vÉ™ saxlayÄ±cÄ±da avtomatik É™laqÉ™lÉ™ndirilir."
+  text_rmagick_available: RMagick istifadÉ™si mÃ¼mkÃ¼ndÃ¼r (opsional olaraq)
+  text_select_mail_notifications: Elektron poÃ§ta bildiriÅŸlÉ™rin gÃ¶ndÉ™rilmÉ™si seÃ§im edÉ™cÉ™yiniz hÉ™rÉ™kÉ™tlÉ™rdÉ™n asÄ±lÄ±dÄ±r.
+  text_select_project_modules: 'LayihÉ™dÉ™ istifadÉ™ olunacaq modullarÄ± seÃ§in:'
+  text_status_changed_by_changeset: "%{value} redaksiyada reallaÅŸdÄ±rÄ±lÄ±b."
+  text_subprojects_destroy_warning: "AltlayihÉ™lÉ™r: %{value} hÉ™mÃ§inin silinÉ™cÉ™k."
+  text_tip_issue_begin_day: tapÅŸÄ±rÄ±ÄŸÄ±n baÅŸlanÄŸÄ±c tarixi
+  text_tip_issue_begin_end_day: elÉ™ hÉ™min gÃ¼n tapÅŸÄ±rÄ±ÄŸÄ±n baÅŸlanÄŸÄ±c vÉ™ bitmÉ™ tarixi
+  text_tip_issue_end_day: tapÅŸÄ±rÄ±ÄŸÄ±n baÅŸa Ã§atma tarixi
+  text_tracker_no_workflow: Bu treker Ã¼Ã§Ã¼n hÉ™rÉ™kÉ™tlÉ™rin ardÄ±cÄ±llÄ±ÄŸÄ± mÃ¼É™yyÉ™n edimÉ™yib
+  text_unallowed_characters: QadaÄŸan edilmiÅŸ simvollar
+  text_user_mail_option: "SeÃ§ilmÉ™yÉ™n layihÉ™lÉ™r Ã¼Ã§Ã¼n Siz yalnÄ±z baxdÄ±ÄŸÄ±nÄ±z vÉ™ ya iÅŸtirak etdiyiniz layihÉ™lÉ™r barÉ™dÉ™ bildiriÅŸ alacaqsÄ±nÄ±z mÉ™sÉ™lÉ™n, mÃ¼É™llifi olduÄŸunuz layihÉ™lÉ™r vÉ™ ya o layihÉ™lÉ™r ki, SizÉ™ tÉ™yin edilib)."
+  text_user_wrote: "%{value} yazÄ±b:"
+  text_wiki_destroy_confirmation: Siz bu Wiki vÉ™ onun tÉ™rkibindÉ™kilÉ™ri silmÉ™k istÉ™diyinizÉ™ É™minsinizmi?
+  text_workflow_edit: VÉ™ziyyÉ™tlÉ™rin ardÄ±cÄ±llÄ±ÄŸÄ±nÄ± redaktÉ™ etmÉ™k Ã¼Ã§Ã¼n rol vÉ™ trekeri seÃ§in
+
+  warning_attachments_not_saved: "faylÄ±n (larÄ±n) %{count} yadda saxlamaq mÃ¼mkÃ¼n deyildir."
+  text_wiki_page_destroy_question: Bu sÉ™hifÉ™ %{descendants} yaxÄ±n vÉ™ Ã§ox yaxÄ±n sÉ™hifÉ™lÉ™rÉ™ malikdir. Siz nÉ™ etmÉ™k istÉ™yirsiniz?
+  text_wiki_page_reassign_children: Cari sÉ™hifÉ™ Ã¼Ã§Ã¼n yaxÄ±n sÉ™hifÉ™lÉ™ri yenidÉ™n tÉ™yin etmÉ™k
+  text_wiki_page_nullify_children: YaxÄ±n sÉ™hifÉ™lÉ™ri baÅŸ sÉ™hifÉ™lÉ™r etmÉ™k
+  text_wiki_page_destroy_children: YaxÄ±n vÉ™ Ã§ox yaxÄ±n sÉ™hifÉ™lÉ™ri silmÉ™k
+  setting_password_min_length: Parolun minimal uzunluÄŸu
+  field_group_by: NÉ™ticÉ™lÉ™ri qruplaÅŸdÄ±rmaq
+  mail_subject_wiki_content_updated: "Wiki-sÉ™hifÉ™ '%{id}' yenilÉ™nmiÅŸdir"
+  label_wiki_content_added: Wiki-sÉ™hifÉ™ É™lavÉ™ olunub
+  mail_subject_wiki_content_added: "Wiki-sÉ™hifÉ™  '%{id}' É™lavÉ™ edilib"
+  mail_body_wiki_content_added: "%{author} Wiki-sÉ™hifÉ™ni '%{id}' É™lavÉ™ edib."
+  label_wiki_content_updated: Wiki-sÉ™hifÉ™ yenilÉ™nib
+  mail_body_wiki_content_updated: "%{author} Wiki-sÉ™hifÉ™ni '%{id}' yenilÉ™yib."
+  permission_add_project: LayihÉ™nin yaradÄ±lmasÄ±
+  setting_new_project_user_role_id: LayihÉ™ni yaradan istifadÉ™Ã§iyÉ™ tÉ™yin olunan rol
+  label_view_all_revisions: BÃ¼tÃ¼n yoxlamalarÄ± gÃ¶stÉ™rmÉ™k
+  label_tag: NiÅŸan
+  label_branch: ÅžÃ¶bÉ™
+  error_no_tracker_in_project: Bu layihÉ™ ilÉ™ heÃ§ bir treker assosiasiya olunmayÄ±b. LayihÉ™nin sazlamalarÄ±nÄ± yoxlayÄ±n.
+  error_no_default_issue_status: Susmaya gÃ¶rÉ™ tapÅŸÄ±rÄ±qlarÄ±n statusu mÃ¼É™yyÉ™n edilmÉ™yib. SazlamalarÄ± yoxlayÄ±n (bax. "Ä°nzibatÃ§Ä±lÄ±q -> TapÅŸÄ±rÄ±qlarÄ±n statusu").
+  label_group_plural: Qruplar
+  label_group: Qrup
+  label_group_new: Yeni qrup
+  label_time_entry_plural: SÉ™rf olunan vaxt
+  text_journal_added: "%{label} %{value} É™lavÉ™ edilib"
+  field_active: Aktiv
+  enumeration_system_activity: Sistemli
+  permission_delete_issue_watchers: NÉ™zarÉ™tÃ§ilÉ™rin silinmÉ™si
+  version_status_closed: BaÄŸlanÄ±b
+  version_status_locked: bloklanÄ±b
+  version_status_open: aÃ§Ä±qdÄ±r
+  error_can_not_reopen_issue_on_closed_version: BaÄŸlÄ± varianta tÉ™yin edilÉ™n tapÅŸÄ±rÄ±q yenidÉ™n aÃ§Ä±q ola bilmÉ™z
+  label_user_anonymous: Anonim
+  button_move_and_follow: YerlÉ™ÅŸdirmÉ™k vÉ™ keÃ§id
+  setting_default_projects_modules: Yeni layihÉ™lÉ™r Ã¼Ã§Ã¼n susmaya gÃ¶rÉ™ daxil edilÉ™n modullar
+  setting_gravatar_default: Susmaya gÃ¶rÉ™ Gravatar tÉ™sviri
+  field_sharing: BirgÉ™ istifadÉ™
+  label_version_sharing_hierarchy: LayihÉ™lÉ™rin iyerarxiyasÄ±na gÃ¶rÉ™
+  label_version_sharing_system: bÃ¼tÃ¼n layihÉ™lÉ™r ilÉ™
+  label_version_sharing_descendants: Alt layihÉ™lÉ™r ilÉ™
+  label_version_sharing_tree: LayihÉ™lÉ™rin iyerarxiyasÄ± ilÉ™
+  label_version_sharing_none: BirgÉ™ istifadÉ™ olmadan
+  error_can_not_archive_project: Bu layihÉ™ arxivlÉ™ÅŸdirilÉ™ bilmÉ™z
+  button_duplicate: TÉ™krarlamaq
+  button_copy_and_follow: SurÉ™tini Ã§Ä±xarmaq vÉ™ davam etmÉ™k
+  label_copy_source: MÉ™nbÉ™
+  setting_issue_done_ratio: SahÉ™nin kÃ¶mÉ™yi ilÉ™ tapÅŸÄ±rÄ±ÄŸÄ±n hazÄ±rlÄ±ÄŸÄ±nÄ± nÉ™zÉ™rÉ™ almaq
+  setting_issue_done_ratio_issue_status: TapÅŸÄ±rÄ±ÄŸÄ±n statusu
+  error_issue_done_ratios_not_updated: TapÅŸÄ±rÄ±qlarÄ±n hazÄ±rlÄ±q parametri yenilÉ™nmÉ™yib
+  error_workflow_copy_target: MÉ™qsÉ™dÉ™ uyÄŸun trekerlÉ™ri vÉ™ rollarÄ± seÃ§in
+  setting_issue_done_ratio_issue_field: TapÅŸÄ±rÄ±ÄŸÄ±n hazÄ±rlÄ±q sÉ™viyyÉ™si
+  label_copy_same_as_target: MÉ™qsÉ™ddÉ™ olduÄŸu kimi
+  label_copy_target: MÉ™qsÉ™d
+  notice_issue_done_ratios_updated: Parametr &laquo;hazÄ±rlÄ±q&raquo; yenilÉ™nib.
+  error_workflow_copy_source: Cari trekeri vÉ™ ya rolu seÃ§in
+  label_update_issue_done_ratios: TapÅŸÄ±rÄ±ÄŸÄ±n hazÄ±rlÄ±q sÉ™viyyÉ™sini yenilÉ™mÉ™k
+  setting_start_of_week: HÉ™ftÉ™nin birinci gÃ¼nÃ¼
+  label_api_access_key: API-yÉ™ giriÅŸ aÃ§arÄ±
+  text_line_separated: BÄ°r neÃ§É™ qiymÉ™t icazÉ™ verilib (hÉ™r sÉ™tirÉ™ bir qiymÉ™t).
+  label_revision_id: Yoxlama %{value}
+  permission_view_issues: TapÅŸÄ±rÄ±qlara baxÄ±ÅŸ
+  label_display_used_statuses_only: YalnÄ±z bu trekerdÉ™ istifadÉ™ olunan statuslarÄ± É™ks etdirmÉ™k
+  label_api_access_key_created_on: API-yÉ™ giriÅŸ aÃ§arÄ± %{value} É™vvÉ™l aradÄ±lÄ±b
+  label_feeds_access_key: RSS giriÅŸ aÃ§arÄ±
+  notice_api_access_key_reseted: Sizin API giriÅŸ aÃ§arÄ±nÄ±z sÄ±fÄ±rlanÄ±b.
+  setting_rest_api_enabled: REST veb-servisini qoÅŸmaq
+  button_show: GÃ¶stÉ™rmÉ™k
+  label_missing_api_access_key: API-yÉ™ giriÅŸ aÃ§arÄ± mÃ¶vcud deyildir
+  label_missing_feeds_access_key: RSS-É™ giriÅŸ aÃ§arÄ± mÃ¶vcud deyildir
+  setting_mail_handler_body_delimiters: Bu sÉ™tirlÉ™rin birindÉ™n sonra mÉ™ktubu qÄ±saltmaq
+  permission_add_subprojects: Alt layihÉ™lÉ™rin yaradÄ±lmasÄ±
+  label_subproject_new: Yeni alt layihÉ™
+  text_own_membership_delete_confirmation: |-
+    Siz bÉ™zi vÉ™ ya bÃ¼tÃ¼n hÃ¼quqlarÄ± silmÉ™yÉ™ Ã§alÄ±ÅŸÄ±rsÄ±nÄ±z, nÉ™ticÉ™dÉ™ bu layihÉ™ni redaktÉ™ etmÉ™k hÃ¼ququnu da itirÉ™ bilÉ™rsiniz. Davam etmÉ™k istÉ™diyinizÉ™ É™minsinizmi?
+    
+  label_close_versions: BaÅŸa Ã§atmÄ±ÅŸ variantlarÄ± baÄŸlamaq
+  label_board_sticky: BÉ™rkidilib
+  label_board_locked: BloklanÄ±b
+  field_principal: Ad
+  text_zoom_out: UzaqlaÅŸdÄ±rmaq
+  text_zoom_in: YaxÄ±nlaÅŸdÄ±rmaq
+  notice_unable_delete_time_entry: JurnalÄ±n qeydini silmÉ™k mÃ¼mkÃ¼n deyildir.
+  label_overall_spent_time: CÉ™mi sÉ™rf olunan vaxt
+  label_user_mail_option_none: HadisÉ™ yoxdur
+  field_member_of_group: TÉ™yin olunmuÅŸ qrup 
+  field_assigned_to_role: TÉ™yin olunmuÅŸ rol
+  notice_not_authorized_archived_project: SorÄŸulanan layihÉ™ arxivlÉ™ÅŸdirilib.
+  label_principal_search: "Ä°stifadÉ™Ã§ini vÉ™ ya qrupu tapmaq:"
+  label_user_search: "Ä°stifadÉ™Ã§ini tapmaq:"
+  field_visible: GÃ¶rÃ¼nmÉ™ dÉ™rÉ™cÉ™si
+  setting_emails_header: MÉ™ktubun baÅŸlÄ±ÄŸÄ±
+
+  setting_commit_logtime_activity_id: VaxtÄ±n uÃ§otu Ã¼Ã§Ã¼n gÃ¶rÃ¼lÉ™n hÉ™rÉ™kÉ™tlÉ™r
+  text_time_logged_by_changeset: "%{value} redaksiyada nÉ™zÉ™rÉ™ alÄ±nÄ±b."
+  setting_commit_logtime_enabled: Vaxt uÃ§otunu qoÅŸmaq
+  notice_gantt_chart_truncated: Æks oluna bilÉ™cÉ™k elementlÉ™rin maksimal sayÄ± artdÄ±ÄŸÄ±na gÃ¶rÉ™ diaqram kÉ™silÉ™cÉ™k (%{max})
+  setting_gantt_items_limit: Qant diaqramÄ±nda É™ks olunan elementlÉ™rin maksimal sayÄ± 
+  field_warn_on_leaving_unsaved: Yadda saxlanÄ±lmayan mÉ™tnin sÉ™hifÉ™si baÄŸlanan zaman xÉ™bÉ™rdarlÄ±q etmÉ™k
+  text_warn_on_leaving_unsaved: TÉ™rk etmÉ™k istÉ™diyiniz cari sÉ™hifÉ™dÉ™ yadda saxlanÄ±lmayan vÉ™ itÉ™ bilÉ™cÉ™k mÉ™tn vardÄ±r.
+  label_my_queries: MÉ™nim yadda saxlanÄ±lan sorÄŸularÄ±m
+  text_journal_changed_no_detail: "%{label} yenilÉ™nib"
+  label_news_comment_added: XÉ™bÉ™rÉ™ ÅŸÉ™rh É™lavÉ™ olunub
+  button_expand_all: HamÄ±sÄ±nÄ± aÃ§
+  button_collapse_all: HamÄ±sÄ±nÄ± Ã§evir
+  label_additional_workflow_transitions_for_assignee: Ä°stifadÉ™Ã§i icraÃ§Ä± olduÄŸu zaman É™lavÉ™ keÃ§idlÉ™r 
+  label_additional_workflow_transitions_for_author: Ä°stifadÉ™Ã§i mÃ¼É™llif olduÄŸu zaman É™lavÉ™ keÃ§idlÉ™r 
+  label_bulk_edit_selected_time_entries: SÉ™rf olunan vaxtÄ±n seÃ§ilÉ™n qeydlÉ™rinin kÃ¼tlÉ™vi ÅŸÉ™kildÉ™ dÉ™yiÅŸdirilmÉ™si
+  text_time_entries_destroy_confirmation: Siz sÉ™rf olunan vaxtÄ±n seÃ§ilÉ™n qeydlÉ™rini silmÉ™k istÉ™diyinizÉ™ É™minsinizmi?
+  label_role_anonymous: Anonim
+  label_role_non_member: Ä°ÅŸtirakÃ§Ä± deyil
+  label_issue_note_added: Qeyd É™lavÉ™ olunub
+  label_issue_status_updated: Status yenilÉ™nib
+  label_issue_priority_updated: Prioritet yenilÉ™nib
+  label_issues_visibility_own: Ä°stifadÉ™Ã§i Ã¼Ã§Ã¼n yaradÄ±lan vÉ™ ya ona tÉ™yin olunan tapÅŸÄ±rÄ±qlar
+  field_issues_visibility: TapÅŸÄ±rÄ±qlarÄ±n gÃ¶rÃ¼nmÉ™ dÉ™rÉ™cÉ™si
+  label_issues_visibility_all: BÃ¼tÃ¼n tapÅŸÄ±rÄ±qlar
+  permission_set_own_issues_private: ÅžÉ™xsi tapÅŸÄ±rÄ±qlar Ã¼Ã§Ã¼n gÃ¶rÃ¼nmÉ™ dÉ™rÉ™cÉ™sinin (Ã¼mumi/ÅŸÉ™xsi) qurulmasÄ±
+  field_is_private: ÅžÉ™xsi
+  permission_set_issues_private: TapÅŸÄ±rÄ±qlar Ã¼Ã§Ã¼n gÃ¶rÃ¼nmÉ™ dÉ™rÉ™cÉ™sinin (Ã¼mumi/ÅŸÉ™xsi) qurulmasÄ±
+  label_issues_visibility_public: YalnÄ±z Ã¼mumi tapÅŸÄ±rÄ±qlar
+  text_issues_destroy_descendants_confirmation: HÉ™mÃ§inin %{count} tapÅŸÄ±rÄ±q (lar) silinÉ™cÉ™k.
+  field_commit_logs_encoding: SaxlayÄ±cÄ±da ÅŸÉ™rhlÉ™rin kodlaÅŸdÄ±rÄ±lmasÄ±
+  field_scm_path_encoding: Yolun kodlaÅŸdÄ±rÄ±lmasÄ±
+  text_scm_path_encoding_note: "Susmaya gÃ¶rÉ™: UTF-8"
+  field_path_to_repository: SaxlayÄ±cÄ±ya yol
+  field_root_directory: KÃ¶k direktoriya
+  field_cvs_module: Modul
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Lokal saxlayÄ±cÄ± (mÉ™sÉ™lÉ™n, /hgrepo, c:\hgrepo)
+  text_scm_command: Komanda
+  text_scm_command_version: Variant
+  label_git_report_last_commit: Fayllar vÉ™ direktoriyalar Ã¼Ã§Ã¼n son dÉ™yiÅŸikliklÉ™ri gÃ¶stÉ™rmÉ™k
+  text_scm_config: Siz config/configuration.yml faylÄ±nda SCM komandasÄ±nÄ± sazlaya bilÉ™rsiniz. XahiÅŸ olunur, bu faylÄ±n redaktÉ™sindÉ™n sonra É™lavÉ™ni iÅŸÉ™ salÄ±n.
+  text_scm_command_not_available: VariantlarÄ±n nÉ™zarÉ™t sisteminin komandasÄ±na giriÅŸ mÃ¼mkÃ¼n deyildir. XahiÅŸ olunur, inzibatÃ§Ä± panelindÉ™ki sazlamalarÄ± yoxlayÄ±n.
+  notice_issue_successful_create: TapÅŸÄ±rÄ±q %{id} yaradÄ±lÄ±b.
+  label_between: arasÄ±nda
+  setting_issue_group_assignment: Ä°stifadÉ™Ã§i qruplarÄ±na tÉ™yinata icazÉ™ vermÉ™k 
+  label_diff: FÉ™rq(diff)
+  text_git_repository_note: "Saxlama yerini gÃ¶stÉ™rin (mÉ™s: /gitrepo, c:\\gitrepo)"
+  description_query_sort_criteria_direction: Ã‡eÅŸidlÉ™mÉ™ qaydasÄ±
+  description_project_scope: LayihÉ™nin hÉ™cmi
+  description_filter: Filtr
+  description_user_mail_notification: E-poÃ§t Mail xÉ™bÉ™rdarlÄ±qlarÄ±nÄ±n sazlamasÄ±
+  description_date_from: BaÅŸlama tarixini daxil edin
+  description_message_content: MesajÄ±n kontenti
+  description_available_columns: MÃ¶vcud sÃ¼tunlar
+  description_date_range_interval: TarixlÉ™r diapazonunu seÃ§in
+  description_issue_category_reassign: MÉ™sÉ™lÉ™nin kateqoriyasÄ±nÄ± seÃ§in
+  description_search: AxtarÄ±ÅŸ sahÉ™si
+  description_notes: Qeyd
+  description_date_range_list: SiyahÄ±dan diapazonu seÃ§in
+  description_choose_project: LayihÉ™lÉ™r
+  description_date_to: YerinÉ™ yetirilmÉ™ tarixini daxil edin
+  description_query_sort_criteria_attribute: Ã‡eÅŸidlÉ™mÉ™ meyarlarÄ±
+  description_wiki_subpages_reassign: Yeni valideyn sÉ™hifÉ™sini seÃ§mÉ™k
+  description_selected_columns: SeÃ§ilmiÅŸ sÃ¼tunlar
+  label_parent_revision: Valideyn
+  label_child_revision: Æsas
+  error_scm_annotate_big_text_file: MÉ™tn faylÄ±nÄ±n maksimal Ã¶lÃ§Ã¼sÃ¼ artdÄ±ÄŸÄ±na gÃ¶rÉ™ ÅŸÉ™rh mÃ¼mkÃ¼n deyildir.
+  setting_default_issue_start_date_to_creation_date: Yeni tapÅŸÄ±rÄ±qlar Ã¼Ã§Ã¼n cari tarixi baÅŸlanÄŸÄ±c tarixi kimi istifadÉ™ etmÉ™k
+  button_edit_section: Bu bÃ¶lmÉ™ni redaktÉ™ etmÉ™k
+  setting_repositories_encodings: ÆlavÉ™lÉ™rin vÉ™ saxlayÄ±cÄ±larÄ±n kodlaÅŸdÄ±rÄ±lmasÄ±
+  description_all_columns: BÃ¼tÃ¼n sÃ¼tunlar
+  button_export: Ä°xrac
+  label_export_options: "%{export_format} ixracÄ±n parametrlÉ™ri"
+  error_attachment_too_big: FaylÄ±n maksimal Ã¶lÃ§Ã¼sÃ¼ artdÄ±ÄŸÄ±na gÃ¶rÉ™ bu faylÄ± yÃ¼klÉ™mÉ™k mÃ¼mkÃ¼n deyildir (%{max_size})
+  notice_failed_to_save_time_entries: "SÉ™hv N %{ids}. %{total} giriÅŸdÉ™n %{count} yaddaÅŸa saxlanÄ±la bilmÉ™di."
+  label_x_issues:
+    zero:  0 TapÅŸÄ±rÄ±q
+    one:   1 TapÅŸÄ±rÄ±q
+    few:   "%{count} TapÅŸÄ±rÄ±q"
+    many:  "%{count} TapÅŸÄ±rÄ±q"
+    other: "%{count} TapÅŸÄ±rÄ±q"
+  label_repository_new: Yeni saxlayÄ±cÄ±
+  field_repository_is_default: Susmaya gÃ¶rÉ™ saxlayÄ±cÄ±
+  label_copy_attachments: ÆlavÉ™nin surÉ™tini Ã§Ä±xarmaq
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: BaÅŸa Ã§atdÄ±rÄ±lmÄ±ÅŸ variantlar
+  text_project_identifier_info: YalnÄ±z kiÃ§ik latÄ±n hÉ™rflÉ™rinÉ™ (a-z), rÉ™qÉ™mlÉ™rÉ™, tire vÉ™ Ã§icgilÉ™rÉ™ icazÉ™ verilir.<br />Yadda saxladÄ±qdan sonra identifikatoru dÉ™yiÅŸmÉ™k olmaz.
+  field_multiple: Ã‡oxsaylÄ± qiymÉ™tlÉ™r
+  setting_commit_cross_project_ref: DigÉ™r bÃ¼tÃ¼n layihÉ™lÉ™rdÉ™ tapÅŸÄ±rÄ±qlarÄ± dÃ¼zÉ™ltmÉ™k vÉ™ istinad etmÉ™k
+  text_issue_conflict_resolution_add_notes: QeydlÉ™rimi É™lavÉ™ etmÉ™k vÉ™ mÉ™nim dÉ™yiÅŸikliklÉ™rimdÉ™n imtina etmÉ™k
+  text_issue_conflict_resolution_overwrite: DÉ™yiÅŸikliklÉ™rimi tÉ™tbiq etmÉ™k (É™vvÉ™lki bÃ¼tÃ¼n qeydlÉ™r yadda saxlanacaq, lakin bÉ™zi qeydlÉ™r yenidÉ™n yazÄ±la bilÉ™r)
+  notice_issue_update_conflict: TapÅŸÄ±rÄ±ÄŸÄ± redaktÉ™ etdiyiniz zaman kimsÉ™ onu artÄ±q dÉ™yiÅŸib.
+  text_issue_conflict_resolution_cancel: MÉ™nim dÉ™yiÅŸikliklÉ™rimi lÉ™ÄŸv etmÉ™k vÉ™ tapÅŸÄ±rÄ±ÄŸÄ± yenidÉ™n gÃ¶stÉ™rmÉ™k %{link}
+  permission_manage_related_issues: ÆlaqÉ™li tapÅŸÄ±rÄ±qlarÄ±n idarÉ™ edilmÉ™si
+  field_auth_source_ldap_filter: LDAP filtri
+  label_search_for_watchers: NÉ™zarÉ™tÃ§ilÉ™ri axtarmaq 
+  notice_account_deleted: "Sizin uÃ§ot qeydiniz tam olaraq silinib" 
+  setting_unsubscribe: "Ä°stifadÉ™Ã§ilÉ™rÉ™ ÅŸÉ™xsi uÃ§ot qeydlÉ™rini silmÉ™yÉ™ icazÉ™ vermÉ™k" 
+  button_delete_my_account: "MÉ™nim uÃ§ot qeydlÉ™rimi silmÉ™k" 
+  text_account_destroy_confirmation: "Sizin uÃ§ot qeydiniz bir daha bÉ™rpa edilmÉ™dÉ™n tam olaraq silinÉ™cÉ™k.\nDavam etmÉ™k istÉ™diyinizÉ™ É™minsinizmi?" 
+  error_session_expired: Sizin sessiya bitmiÅŸdir. XahiÅŸ edirik yenidÉ™n daxil olun.
+  text_session_expiration_settings: "DiqqÉ™t: bu sazlamalarÄ±n dÉ™yiÅŸmÉ™yi cari sessiyanÄ±n baÄŸlanmasÄ±na Ã§Ä±xara bilÉ™r."
+  setting_session_lifetime: SessiyanÄ±n maksimal Session maximum hÉ™yat mÃ¼ddÉ™ti
+  setting_session_timeout: SessiyanÄ±n qeyri aktivlik mÃ¼ddÉ™ti
+  label_session_expiration: SessiyanÄ±n bitmÉ™si
+  permission_close_project: LayihÉ™ni baÄŸla / yenidÉ™n aÃ§
+  label_show_closed_projects: BaÄŸlÄ± layihÉ™lÉ™rÉ™ baxmaq
+  button_close: BaÄŸla
+  button_reopen: YenidÉ™n aÃ§
+  project_status_active: aktiv
+  project_status_closed: baÄŸlÄ±
+  project_status_archived: arxiv
+  text_project_closed: Bu layihÉ™ baÄŸlÄ±dÄ± vÉ™ yalnÄ±z oxuma olar.
+  notice_user_successful_create: Ä°stifadÉ™Ã§i %{id} yaradÄ±ldÄ±.
+  field_core_fields: Standart sahÉ™lÉ™r
+  field_timeout: Zaman aÅŸÄ±mÄ± (saniyÉ™ ilÉ™)
+  setting_thumbnails_enabled: ÆlavÉ™lÉ™rin kiÃ§ik ÅŸÉ™klini gÃ¶stÉ™r
+  setting_thumbnails_size: KiÃ§ik ÅŸÉ™killÉ™rin Ã¶lÃ§Ã¼sÃ¼ (piksel ilÉ™)
+  label_status_transitions: Status keÃ§idlÉ™ri
+  label_fields_permissions: SahÉ™lÉ™rin icazÉ™lÉ™ri
+  label_readonly: Ancaq oxumaq Ã¼Ã§Ã¼n
+  label_required: TÉ™lÉ™b olunur
+  text_repository_identifier_info: YalnÄ±z kiÃ§ik latÄ±n hÉ™rflÉ™rinÉ™ (a-z), rÉ™qÉ™mlÉ™rÉ™, tire vÉ™ Ã§icgilÉ™rÉ™ icazÉ™ verilir.<br />Yadda saxladÄ±qdan sonra identifikatoru dÉ™yiÅŸmÉ™k olmaz.
+  field_board_parent: Ana forum
+  label_attribute_of_project: LayihÉ™ %{name}
+  label_attribute_of_author: MÃ¼É™llif %{name}
+  label_attribute_of_assigned_to: TÉ™yin edilib %{name}
+  label_attribute_of_fixed_version: Æsas versiya %{name}
+  label_copy_subtasks: Alt tapÅŸÄ±rÄ±ÄŸÄ±n surÉ™tini Ã§Ä±xarmaq
+  label_cross_project_hierarchy: With project hierarchy
+  permission_edit_documents: Edit documents
+  button_hide: Hide
+  text_turning_multiple_off: If you disable multiple values, multiple values will be removed in order to preserve only one value per item.
+  label_any: any
+  label_cross_project_system: With all projects
+  label_last_n_weeks: last %{count} weeks
+  label_in_the_past_days: in the past
+  label_copied_to: Copied to
+  permission_set_notes_private: Set notes as private
+  label_in_the_next_days: in the next
+  label_attribute_of_issue: Issue's %{name}
+  label_any_issues_in_project: any issues in project
+  label_cross_project_descendants: With subprojects
+  field_private_notes: Private notes
+  setting_jsonp_enabled: Enable JSONP support
+  label_gantt_progress_line: Progress line
+  permission_add_documents: Add documents
+  permission_view_private_notes: View private notes
+  label_attribute_of_user: User's %{name}
+  permission_delete_documents: Delete documents
+  field_inherit_members: Inherit members
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_no_issues_in_project: no issues in project
+  label_copied_from: Copied from
+  setting_non_working_week_days: Non-working days
+  label_any_issues_not_in_project: any issues not in project
+  label_cross_project_tree: With project tree
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: CÉ™mi
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fd/fd3783c6b45fc6689032dd3ff2fb71c9e008341a.svn-base
--- a/.svn/pristine/fd/fd3783c6b45fc6689032dd3ff2fb71c9e008341a.svn-base
+++ /dev/null
@@ -1,6 +0,0 @@
-<h2><%= l(:label_board) %></h2>
-
-<% labelled_tabular_form_for :board, @board, :url => {:action => 'edit', :id => @board} do |f| %>
-  <%= render :partial => 'form', :locals => {:f => f} %>
-  <%= submit_tag l(:button_save) %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fd/fd3cf4d6d773d3c54f6502ba7ca3721b3e053fbc.svn-base
--- a/.svn/pristine/fd/fd3cf4d6d773d3c54f6502ba7ca3721b3e053fbc.svn-base
+++ /dev/null
@@ -1,446 +0,0 @@
-# encoding: utf-8
-
-# This file includes UTF-8 "Felix SchÃ¤fer".
-# We need to consider Ruby 1.9 compatibility.
-
-require File.expand_path('../../../../../../test_helper', __FILE__)
-begin
-  require 'mocha'
-
-  class GitAdapterTest < ActiveSupport::TestCase
-    REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
-
-    FELIX_UTF8 = "Felix SchÃ¤fer"
-    FELIX_HEX  = "Felix Sch\xC3\xA4fer"
-    CHAR_1_HEX = "\xc3\x9c"
-
-    ## Ruby uses ANSI api to fork a process on Windows.
-    ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
-    ## and these are incompatible with ASCII.
-    # WINDOWS_PASS = Redmine::Platform.mswin?
-    WINDOWS_PASS = false
-
-    ## Git, Mercurial and CVS path encodings are binary.
-    ## Subversion supports URL encoding for path.
-    ## Redmine Mercurial adapter and extension use URL encoding.
-    ## Git accepts only binary path in command line parameter.
-    ## So, there is no way to use binary command line parameter in JRuby.
-    JRUBY_SKIP     = (RUBY_PLATFORM == 'java')
-    JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
-
-    if File.directory?(REPOSITORY_PATH)
-      def setup
-        adapter_class = Redmine::Scm::Adapters::GitAdapter
-        assert adapter_class
-        assert adapter_class.client_command
-        assert_equal true, adapter_class.client_available
-        assert_equal true, adapter_class.client_version_above?([1])
-        assert_equal true, adapter_class.client_version_above?([1, 0])
-
-        @adapter = Redmine::Scm::Adapters::GitAdapter.new(
-                      REPOSITORY_PATH,
-                      nil,
-                      nil,
-                      nil,
-                      'ISO-8859-1'
-                      )
-        assert @adapter
-        @char_1        = CHAR_1_HEX.dup
-        if @char_1.respond_to?(:force_encoding)
-          @char_1.force_encoding('UTF-8')
-        end
-      end
-
-      def test_scm_version
-        to_test = { "git version 1.7.3.4\n"             => [1,7,3,4],
-                    "1.6.1\n1.7\n1.8"                   => [1,6,1],
-                    "1.6.2\r\n1.8.1\r\n1.9.1"           => [1,6,2]}
-        to_test.each do |s, v|
-          test_scm_version_for(s, v)
-        end
-      end
-
-      def test_branches
-        brs = []
-        @adapter.branches.each do |b|
-          brs << b
-        end
-        assert_equal 4, brs.length
-        assert_equal 'latin-1-path-encoding', brs[0].to_s 
-        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', brs[0].revision
-        assert_equal brs[0].scmid, brs[0].revision
-        assert_equal 'master', brs[1].to_s
-        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', brs[1].revision
-        assert_equal brs[1].scmid, brs[1].revision
-        assert_equal 'test-latin-1', brs[2].to_s
-        assert_equal '67e7792ce20ccae2e4bb73eed09bb397819c8834', brs[2].revision
-        assert_equal brs[2].scmid, brs[2].revision
-        assert_equal 'test_branch', brs[3].to_s
-        assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', brs[3].revision
-        assert_equal brs[3].scmid, brs[3].revision
-      end
-
-      def test_tags
-        assert_equal  [
-              "tag00.lightweight",
-              "tag01.annotated",
-            ], @adapter.tags
-      end
-
-      def test_getting_all_revisions
-        assert_equal 21, @adapter.revisions('',nil,nil,:all => true).length
-      end
-
-      def test_getting_certain_revisions
-        assert_equal 1, @adapter.revisions('','899a15d^','899a15d').length
-      end
-
-      def test_revisions_reverse
-        revs1 = @adapter.revisions('',nil,nil,{:all => true, :reverse => true })
-        assert_equal 21, revs1.length
-        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[0].identifier
-        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[20].identifier
-      end
-
-      def test_revisions_reverse_with_time
-        since2 = Time.gm(2010, 9, 30, 0, 0, 0)
-        revs2  = @adapter.revisions('', nil, nil,
-                                    {:all => true, :since => since2, :reverse => true})
-        assert_equal 6, revs2.length
-        assert_equal '67e7792ce20ccae2e4bb73eed09bb397819c8834', revs2[0].identifier
-        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[5].identifier
-      end
-
-      def test_revisions_master_all
-        revs1 = []
-        @adapter.revisions('', nil, "master",{}) do |rev|
-          revs1 << rev
-        end
-        assert_equal 15, revs1.length
-        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 0].identifier
-        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier
-
-        revs2 = []
-        @adapter.revisions('', nil, "master",
-                                    {:reverse => true}) do |rev|
-          revs2 << rev
-        end
-        assert_equal 15, revs2.length
-        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier
-        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier
-      end
-
-      def test_revisions_master_merged_rev
-        revs1 = []
-        @adapter.revisions('',
-                           "713f4944648826f558cf548222f813dabe7cbb04",
-                           "master",
-                           {:reverse => true}) do |rev|
-          revs1 << rev
-        end
-        assert_equal 8, revs1.length
-        assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', revs1[ 0].identifier
-        assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 1].identifier
-        # 4a07fe31b is not a child of 713f49446
-        assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 2].identifier
-        # Merged revision
-        assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 3].identifier
-        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier
-
-        revs2 = []
-        @adapter.revisions('',
-                           "fba357b886984ee71185ad2065e65fc0417d9b92",
-                           "master",
-                           {:reverse => true}) do |rev|
-          revs2 << rev
-        end
-        assert_equal 7, revs2.length
-        assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs2[ 0].identifier
-        # 4a07fe31b is not a child of fba357b8869
-        assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs2[ 1].identifier
-        # Merged revision
-        assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs2[ 2].identifier
-        assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier
-      end
-
-      def test_revisions_branch_latin_1_path_encoding_all
-        revs1 = []
-        @adapter.revisions('', nil, "latin-1-path-encoding",{}) do |rev|
-          revs1 << rev
-        end
-        assert_equal 8, revs1.length
-        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[ 0].identifier
-        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier
-
-        revs2 = []
-        @adapter.revisions('', nil, "latin-1-path-encoding",
-                                    {:reverse => true}) do |rev|
-          revs2 << rev
-        end
-        assert_equal 8, revs2.length
-        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier
-        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier
-      end
-
-      def test_revisions_branch_latin_1_path_encoding_with_rev
-        revs1 = []
-        @adapter.revisions('',
-                           '7234cb2750b63f47bff735edc50a1c0a433c2518',
-                           "latin-1-path-encoding",
-                           {:reverse => true}) do |rev|
-          revs1 << rev
-        end
-        assert_equal 7, revs1.length
-        assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 0].identifier
-        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier
-
-        revs2 = []
-        @adapter.revisions('',
-                           '57ca437c0acbbcb749821fdf3726a1367056d364',
-                           "latin-1-path-encoding",
-                           {:reverse => true}) do |rev|
-          revs2 << rev
-        end
-        assert_equal 3, revs2.length
-        assert_equal '4fc55c43bf3d3dc2efb66145365ddc17639ce81e', revs2[ 0].identifier
-        assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier
-      end
-
-      def test_revisions_invalid_rev
-        revs1 = []
-        @adapter.revisions('',
-                                    '1234abcd',
-                                    "master",
-                                    {:reverse => true}) do |rev|
-          revs1 << rev
-        end
-        assert_equal [], revs1
-      end
-
-      def test_getting_revisions_with_spaces_in_filename
-        assert_equal 1, @adapter.revisions("filemane with spaces.txt",
-                                           nil, nil, :all => true).length
-      end
-
-      def test_parents
-        revs1 = []
-        @adapter.revisions('',
-                           nil,
-                           "master",
-                           {:reverse => true}) do |rev|
-          revs1 << rev
-        end
-        assert_equal 15, revs1.length
-        assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
-                     revs1[0].identifier
-        assert_equal nil, revs1[0].parents
-        assert_equal "899a15dba03a3b350b89c3f537e4bbe02a03cdc9",
-                     revs1[1].identifier
-        assert_equal 1, revs1[1].parents.length
-        assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
-                     revs1[1].parents[0]
-        assert_equal "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
-                     revs1[10].identifier
-        assert_equal 2, revs1[10].parents.length
-        assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8",
-                     revs1[10].parents[0]
-        assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da",
-                     revs1[10].parents[1]
-      end
-
-      def test_getting_revisions_with_leading_and_trailing_spaces_in_filename
-        assert_equal " filename with a leading space.txt ",
-           @adapter.revisions(" filename with a leading space.txt ",
-                               nil, nil, :all => true)[0].paths[0][:path]
-      end
-
-      def test_getting_entries_with_leading_and_trailing_spaces_in_filename
-        assert_equal " filename with a leading space.txt ",
-           @adapter.entries('',
-                   '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c')[3].name
-      end
-
-      def test_annotate
-        annotate = @adapter.annotate('sources/watchers_controller.rb')
-        assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
-        assert_equal 41, annotate.lines.size
-        assert_equal "# This program is free software; you can redistribute it and/or",
-                     annotate.lines[4].strip
-        assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
-                      annotate.revisions[4].identifier
-        assert_equal "jsmith", annotate.revisions[4].author
-      end
-
-      def test_annotate_moved_file
-        annotate = @adapter.annotate('renamed_test.txt')
-        assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
-        assert_equal 2, annotate.lines.size
-      end
-
-      def test_last_rev
-        last_rev = @adapter.lastrev("README",
-                                    "4f26664364207fa8b1af9f8722647ab2d4ac5d43")
-        assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.scmid
-        assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.identifier
-        assert_equal "Adam Soltys <asoltys@gmail.com>", last_rev.author
-        assert_equal "2009-06-24 05:27:38".to_time, last_rev.time
-      end
-
-      def test_last_rev_with_spaces_in_filename
-        last_rev = @adapter.lastrev("filemane with spaces.txt",
-                                    "ed5bb786bbda2dee66a2d50faf51429dbc043a7b")
-        str_felix_utf8 = FELIX_UTF8.dup
-        str_felix_hex  = FELIX_HEX.dup
-        last_rev_author = last_rev.author
-        if last_rev_author.respond_to?(:force_encoding)
-          last_rev_author.force_encoding('UTF-8')
-        end
-        assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.scmid
-        assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.identifier
-        assert_equal "#{str_felix_utf8} <felix@fachschaften.org>",
-                       last_rev.author
-        assert_equal "#{str_felix_hex} <felix@fachschaften.org>",
-                       last_rev.author
-        assert_equal "2010-09-18 19:59:46".to_time, last_rev.time
-      end
-
-      def test_latin_1_path
-        if WINDOWS_PASS
-          #
-        elsif JRUBY_SKIP
-          puts JRUBY_SKIP_STR
-        else
-          p2 = "latin-1-dir/test-#{@char_1}-2.txt"
-          ['4fc55c43bf3d3dc2efb66145365ddc17639ce81e', '4fc55c43bf3'].each do |r1|
-            assert @adapter.diff(p2, r1)
-            assert @adapter.cat(p2, r1)
-            assert_equal 1, @adapter.annotate(p2, r1).lines.length
-            ['64f1f3e89ad1cb57976ff0ad99a107012ba3481d', '64f1f3e89ad1cb5797'].each do |r2|
-              assert @adapter.diff(p2, r1, r2)
-            end
-          end
-        end
-      end
-
-      def test_entries_tag
-        entries1 = @adapter.entries(nil, 'tag01.annotated',
-                                    options = {:report_last_commit => true})
-        assert entries1
-        assert_equal 3, entries1.size
-        assert_equal 'sources', entries1[1].name
-        assert_equal 'sources', entries1[1].path
-        assert_equal 'dir', entries1[1].kind
-        readme = entries1[2]
-        assert_equal 'README', readme.name
-        assert_equal 'README', readme.path
-        assert_equal 'file', readme.kind
-        assert_equal 27, readme.size
-        assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', readme.lastrev.identifier
-        assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time
-      end
-
-      def test_entries_branch
-        entries1 = @adapter.entries(nil, 'test_branch',
-                                    options = {:report_last_commit => true})
-        assert entries1
-        assert_equal 4, entries1.size
-        assert_equal 'sources', entries1[1].name
-        assert_equal 'sources', entries1[1].path
-        assert_equal 'dir', entries1[1].kind
-        readme = entries1[2]
-        assert_equal 'README', readme.name
-        assert_equal 'README', readme.path
-        assert_equal 'file', readme.kind
-        assert_equal 159, readme.size
-        assert_equal '713f4944648826f558cf548222f813dabe7cbb04', readme.lastrev.identifier
-        assert_equal Time.gm(2009, 6, 19, 4, 37, 23), readme.lastrev.time
-      end
-
-      def test_entries_latin_1_files
-        entries1 = @adapter.entries('latin-1-dir', '64f1f3e8')
-        assert entries1
-        assert_equal 3, entries1.size
-        f1 = entries1[1]
-        assert_equal "test-#{@char_1}-2.txt", f1.name
-        assert_equal "latin-1-dir/test-#{@char_1}-2.txt", f1.path
-        assert_equal 'file', f1.kind
-      end
-
-      def test_entries_latin_1_dir
-        if WINDOWS_PASS
-          #
-        elsif JRUBY_SKIP
-          puts JRUBY_SKIP_STR
-        else
-          entries1 = @adapter.entries("latin-1-dir/test-#{@char_1}-subdir",
-                                      '1ca7f5ed')
-          assert entries1
-          assert_equal 3, entries1.size
-          f1 = entries1[1]
-          assert_equal "test-#{@char_1}-2.txt", f1.name
-          assert_equal "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-2.txt", f1.path
-          assert_equal 'file', f1.kind
-        end
-      end
-
-      def test_path_encoding_default_utf8
-        adpt1 = Redmine::Scm::Adapters::GitAdapter.new(
-                                  REPOSITORY_PATH
-                                )
-        assert_equal "UTF-8", adpt1.path_encoding
-        adpt2 = Redmine::Scm::Adapters::GitAdapter.new(
-                                  REPOSITORY_PATH,
-                                  nil,
-                                  nil,
-                                  nil,
-                                  ""
-                                )
-        assert_equal "UTF-8", adpt2.path_encoding
-      end
-
-      def test_cat_path_invalid
-        assert_nil @adapter.cat('invalid')
-      end
-
-      def test_cat_revision_invalid
-        assert     @adapter.cat('README')
-        assert_nil @adapter.cat('README', 'abcd1234efgh')
-      end
-
-      def test_diff_path_invalid
-        assert_equal [], @adapter.diff('invalid', '713f4944648826f5')
-      end
-
-      def test_diff_revision_invalid
-        assert_nil @adapter.diff(nil, 'abcd1234efgh')
-        assert_nil @adapter.diff(nil, '713f4944648826f5', 'abcd1234efgh')
-        assert_nil @adapter.diff(nil, 'abcd1234efgh', '713f4944648826f5')
-      end
-
-      def test_annotate_path_invalid
-        assert_nil @adapter.annotate('invalid')
-      end
-
-      def test_annotate_revision_invalid
-        assert     @adapter.annotate('README')
-        assert_nil @adapter.annotate('README', 'abcd1234efgh')
-      end
-
-      private
-
-      def test_scm_version_for(scm_command_version, version)
-        @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
-        assert_equal version, @adapter.class.scm_command_version
-      end
-
-    else
-      puts "Git test repository NOT FOUND. Skipping unit tests !!!"
-      def test_fake; assert true end
-    end
-  end
-
-rescue LoadError
-  class GitMochaFake < ActiveSupport::TestCase
-    def test_fake; assert(false, "Requires mocha to run those tests")  end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fd/fd672f720e53aab0a0184fd9c83dcdbc26d28825.svn-base
--- /dev/null
+++ b/.svn/pristine/fd/fd672f720e53aab0a0184fd9c83dcdbc26d28825.svn-base
@@ -0,0 +1,601 @@
+module CollectiveIdea #:nodoc:
+  module Acts #:nodoc:
+    module NestedSet #:nodoc:
+
+      # This acts provides Nested Set functionality. Nested Set is a smart way to implement
+      # an _ordered_ tree, with the added feature that you can select the children and all of their
+      # descendants with a single query. The drawback is that insertion or move need some complex
+      # sql queries. But everything is done here by this module!
+      #
+      # Nested sets are appropriate each time you want either an orderd tree (menus,
+      # commercial categories) or an efficient way of querying big trees (threaded posts).
+      #
+      # == API
+      #
+      # Methods names are aligned with acts_as_tree as much as possible to make replacment from one
+      # by another easier.
+      #
+      #   item.children.create(:name => "child1")
+      #
+
+      # Configuration options are:
+      #
+      # * +:parent_column+ - specifies the column name to use for keeping the position integer (default: parent_id)
+      # * +:left_column+ - column name for left boundry data, default "lft"
+      # * +:right_column+ - column name for right boundry data, default "rgt"
+      # * +:scope+ - restricts what is to be considered a list. Given a symbol, it'll attach "_id"
+      #   (if it hasn't been already) and use that as the foreign key restriction. You
+      #   can also pass an array to scope by multiple attributes.
+      #   Example: <tt>acts_as_nested_set :scope => [:notable_id, :notable_type]</tt>
+      # * +:dependent+ - behavior for cascading destroy. If set to :destroy, all the
+      #   child objects are destroyed alongside this object by calling their destroy
+      #   method. If set to :delete_all (default), all the child objects are deleted
+      #   without calling their destroy method.
+      # * +:counter_cache+ adds a counter cache for the number of children.
+      #   defaults to false.
+      #   Example: <tt>acts_as_nested_set :counter_cache => :children_count</tt>
+      #
+      # See CollectiveIdea::Acts::NestedSet::Model::ClassMethods for a list of class methods and
+      # CollectiveIdea::Acts::NestedSet::Model for a list of instance methods added
+      # to acts_as_nested_set models
+      def acts_as_nested_set(options = {})
+        options = {
+          :parent_column => 'parent_id',
+          :left_column => 'lft',
+          :right_column => 'rgt',
+          :dependent => :delete_all, # or :destroy
+          :counter_cache => false,
+          :order => 'id'
+        }.merge(options)
+
+        if options[:scope].is_a?(Symbol) && options[:scope].to_s !~ /_id$/
+          options[:scope] = "#{options[:scope]}_id".intern
+        end
+
+        class_attribute :acts_as_nested_set_options
+        self.acts_as_nested_set_options = options
+
+        include CollectiveIdea::Acts::NestedSet::Model
+        include Columns
+        extend Columns
+
+        belongs_to :parent, :class_name => self.base_class.to_s,
+          :foreign_key => parent_column_name,
+          :counter_cache => options[:counter_cache],
+          :inverse_of => :children
+        has_many :children, :class_name => self.base_class.to_s,
+          :foreign_key => parent_column_name, :order => left_column_name,
+          :inverse_of => :parent,
+          :before_add    => options[:before_add],
+          :after_add     => options[:after_add],
+          :before_remove => options[:before_remove],
+          :after_remove  => options[:after_remove]
+
+        attr_accessor :skip_before_destroy
+
+        before_create  :set_default_left_and_right
+        before_save    :store_new_parent
+        after_save     :move_to_new_parent
+        before_destroy :destroy_descendants
+
+        # no assignment to structure fields
+        [left_column_name, right_column_name].each do |column|
+          module_eval <<-"end_eval", __FILE__, __LINE__
+            def #{column}=(x)
+              raise ActiveRecord::ActiveRecordError, "Unauthorized assignment to #{column}: it's an internal field handled by acts_as_nested_set code, use move_to_* methods instead."
+            end
+          end_eval
+        end
+
+        define_model_callbacks :move
+      end
+
+      module Model
+        extend ActiveSupport::Concern
+
+        module ClassMethods
+          # Returns the first root
+          def root
+            roots.first
+          end
+
+          def roots
+            where(parent_column_name => nil).order(quoted_left_column_name)
+          end
+
+          def leaves
+            where("#{quoted_right_column_name} - #{quoted_left_column_name} = 1").order(quoted_left_column_name)
+          end
+
+          def valid?
+            left_and_rights_valid? && no_duplicates_for_columns? && all_roots_valid?
+          end
+
+          def left_and_rights_valid?
+            joins("LEFT OUTER JOIN #{quoted_table_name} AS parent ON " +
+                "#{quoted_table_name}.#{quoted_parent_column_name} = parent.#{primary_key}").
+            where(
+                "#{quoted_table_name}.#{quoted_left_column_name} IS NULL OR " +
+                "#{quoted_table_name}.#{quoted_right_column_name} IS NULL OR " +
+                "#{quoted_table_name}.#{quoted_left_column_name} >= " +
+                  "#{quoted_table_name}.#{quoted_right_column_name} OR " +
+                "(#{quoted_table_name}.#{quoted_parent_column_name} IS NOT NULL AND " +
+                  "(#{quoted_table_name}.#{quoted_left_column_name} <= parent.#{quoted_left_column_name} OR " +
+                  "#{quoted_table_name}.#{quoted_right_column_name} >= parent.#{quoted_right_column_name}))"
+            ).count == 0
+          end
+
+          def no_duplicates_for_columns?
+            scope_string = Array(acts_as_nested_set_options[:scope]).map do |c|
+              connection.quote_column_name(c)
+            end.push(nil).join(", ")
+            [quoted_left_column_name, quoted_right_column_name].all? do |column|
+              # No duplicates
+              select("#{scope_string}#{column}, COUNT(#{column})").
+                  group("#{scope_string}#{column}").
+                  having("COUNT(#{column}) > 1").
+                  first.nil?
+            end
+          end
+
+          # Wrapper for each_root_valid? that can deal with scope.
+          def all_roots_valid?
+            if acts_as_nested_set_options[:scope]
+              roots.group(scope_column_names).group_by{|record| scope_column_names.collect{|col| record.send(col.to_sym)}}.all? do |scope, grouped_roots|
+                each_root_valid?(grouped_roots)
+              end
+            else
+              each_root_valid?(roots)
+            end
+          end
+
+          def each_root_valid?(roots_to_validate)
+            left = right = 0
+            roots_to_validate.all? do |root|
+              (root.left > left && root.right > right).tap do
+                left = root.left
+                right = root.right
+              end
+            end
+          end
+
+          # Rebuilds the left & rights if unset or invalid.
+          # Also very useful for converting from acts_as_tree.
+          def rebuild!(validate_nodes = true)
+            # Don't rebuild a valid tree.
+            return true if valid?
+
+            scope = lambda{|node|}
+            if acts_as_nested_set_options[:scope]
+              scope = lambda{|node|
+                scope_column_names.inject(""){|str, column_name|
+                  str << "AND #{connection.quote_column_name(column_name)} = #{connection.quote(node.send(column_name.to_sym))} "
+                }
+              }
+            end
+            indices = {}
+
+            set_left_and_rights = lambda do |node|
+              # set left
+              node[left_column_name] = indices[scope.call(node)] += 1
+              # find
+              where(["#{quoted_parent_column_name} = ? #{scope.call(node)}", node]).order(acts_as_nested_set_options[:order]).each{|n| set_left_and_rights.call(n) }
+              # set right
+              node[right_column_name] = indices[scope.call(node)] += 1
+              node.save!(:validate => validate_nodes)
+            end
+
+            # Find root node(s)
+            root_nodes = where("#{quoted_parent_column_name} IS NULL").order(acts_as_nested_set_options[:order]).each do |root_node|
+              # setup index for this scope
+              indices[scope.call(root_node)] ||= 0
+              set_left_and_rights.call(root_node)
+            end
+          end
+
+          # Iterates over tree elements and determines the current level in the tree.
+          # Only accepts default ordering, odering by an other column than lft
+          # does not work. This method is much more efficent than calling level
+          # because it doesn't require any additional database queries.
+          #
+          # Example:
+          #    Category.each_with_level(Category.root.self_and_descendants) do |o, level|
+          #
+          def each_with_level(objects)
+            path = [nil]
+            objects.each do |o|
+              if o.parent_id != path.last
+                # we are on a new level, did we decent or ascent?
+                if path.include?(o.parent_id)
+                  # remove wrong wrong tailing paths elements
+                  path.pop while path.last != o.parent_id
+                else
+                  path << o.parent_id
+                end
+              end
+              yield(o, path.length - 1)
+            end
+          end
+        end
+
+        # Any instance method that returns a collection makes use of Rails 2.1's named_scope (which is bundled for Rails 2.0), so it can be treated as a finder.
+        #
+        #   category.self_and_descendants.count
+        #   category.ancestors.find(:all, :conditions => "name like '%foo%'")
+
+        # Value of the parent column
+        def parent_id
+          self[parent_column_name]
+        end
+
+        # Value of the left column
+        def left
+          self[left_column_name]
+        end
+
+        # Value of the right column
+        def right
+          self[right_column_name]
+        end
+
+        # Returns true if this is a root node.
+        def root?
+          parent_id.nil?
+        end
+
+        def leaf?
+          new_record? || (right - left == 1)
+        end
+
+        # Returns true is this is a child node
+        def child?
+          !parent_id.nil?
+        end
+
+        # Returns root
+        def root
+          self_and_ancestors.where(parent_column_name => nil).first
+        end
+
+        # Returns the array of all parents and self
+        def self_and_ancestors
+          nested_set_scope.where([
+            "#{self.class.quoted_table_name}.#{quoted_left_column_name} <= ? AND #{self.class.quoted_table_name}.#{quoted_right_column_name} >= ?", left, right
+          ])
+        end
+
+        # Returns an array of all parents
+        def ancestors
+          without_self self_and_ancestors
+        end
+
+        # Returns the array of all children of the parent, including self
+        def self_and_siblings
+          nested_set_scope.where(parent_column_name => parent_id)
+        end
+
+        # Returns the array of all children of the parent, except self
+        def siblings
+          without_self self_and_siblings
+        end
+
+        # Returns a set of all of its nested children which do not have children
+        def leaves
+          descendants.where("#{self.class.quoted_table_name}.#{quoted_right_column_name} - #{self.class.quoted_table_name}.#{quoted_left_column_name} = 1")
+        end
+
+        # Returns the level of this object in the tree
+        # root level is 0
+        def level
+          parent_id.nil? ? 0 : ancestors.count
+        end
+
+        # Returns a set of itself and all of its nested children
+        def self_and_descendants
+          nested_set_scope.where([
+            "#{self.class.quoted_table_name}.#{quoted_left_column_name} >= ? AND #{self.class.quoted_table_name}.#{quoted_right_column_name} <= ?", left, right
+          ])
+        end
+
+        # Returns a set of all of its children and nested children
+        def descendants
+          without_self self_and_descendants
+        end
+
+        def is_descendant_of?(other)
+          other.left < self.left && self.left < other.right && same_scope?(other)
+        end
+
+        def is_or_is_descendant_of?(other)
+          other.left <= self.left && self.left < other.right && same_scope?(other)
+        end
+
+        def is_ancestor_of?(other)
+          self.left < other.left && other.left < self.right && same_scope?(other)
+        end
+
+        def is_or_is_ancestor_of?(other)
+          self.left <= other.left && other.left < self.right && same_scope?(other)
+        end
+
+        # Check if other model is in the same scope
+        def same_scope?(other)
+          Array(acts_as_nested_set_options[:scope]).all? do |attr|
+            self.send(attr) == other.send(attr)
+          end
+        end
+
+        # Find the first sibling to the left
+        def left_sibling
+          siblings.where(["#{self.class.quoted_table_name}.#{quoted_left_column_name} < ?", left]).
+                  order("#{self.class.quoted_table_name}.#{quoted_left_column_name} DESC").last
+        end
+
+        # Find the first sibling to the right
+        def right_sibling
+          siblings.where(["#{self.class.quoted_table_name}.#{quoted_left_column_name} > ?", left]).first
+        end
+
+        # Shorthand method for finding the left sibling and moving to the left of it.
+        def move_left
+          move_to_left_of left_sibling
+        end
+
+        # Shorthand method for finding the right sibling and moving to the right of it.
+        def move_right
+          move_to_right_of right_sibling
+        end
+
+        # Move the node to the left of another node (you can pass id only)
+        def move_to_left_of(node)
+          move_to node, :left
+        end
+
+        # Move the node to the left of another node (you can pass id only)
+        def move_to_right_of(node)
+          move_to node, :right
+        end
+
+        # Move the node to the child of another node (you can pass id only)
+        def move_to_child_of(node)
+          move_to node, :child
+        end
+
+        # Move the node to root nodes
+        def move_to_root
+          move_to nil, :root
+        end
+
+        def move_possible?(target)
+          self != target && # Can't target self
+          same_scope?(target) && # can't be in different scopes
+          # !(left..right).include?(target.left..target.right) # this needs tested more
+          # detect impossible move
+          !((left <= target.left && right >= target.left) or (left <= target.right && right >= target.right))
+        end
+
+        def to_text
+          self_and_descendants.map do |node|
+            "#{'*'*(node.level+1)} #{node.id} #{node.to_s} (#{node.parent_id}, #{node.left}, #{node.right})"
+          end.join("\n")
+        end
+
+      protected
+
+        def without_self(scope)
+          scope.where(["#{self.class.quoted_table_name}.#{self.class.primary_key} != ?", self])
+        end
+
+        # All nested set queries should use this nested_set_scope, which performs finds on
+        # the base ActiveRecord class, using the :scope declared in the acts_as_nested_set
+        # declaration.
+        def nested_set_scope(options = {})
+          options = {:order => "#{self.class.quoted_table_name}.#{quoted_left_column_name}"}.merge(options)
+          scopes = Array(acts_as_nested_set_options[:scope])
+          options[:conditions] = scopes.inject({}) do |conditions,attr|
+            conditions.merge attr => self[attr]
+          end unless scopes.empty?
+          self.class.base_class.scoped options
+        end
+
+        def store_new_parent
+          @move_to_new_parent_id = send("#{parent_column_name}_changed?") ? parent_id : false
+          true # force callback to return true
+        end
+
+        def move_to_new_parent
+          if @move_to_new_parent_id.nil?
+            move_to_root
+          elsif @move_to_new_parent_id
+            move_to_child_of(@move_to_new_parent_id)
+          end
+        end
+
+        # on creation, set automatically lft and rgt to the end of the tree
+        def set_default_left_and_right
+          highest_right_row = nested_set_scope(:order => "#{quoted_right_column_name} desc").limit(1).lock(true).first
+          maxright = highest_right_row ? (highest_right_row[right_column_name] || 0) : 0
+          # adds the new node to the right of all existing nodes
+          self[left_column_name] = maxright + 1
+          self[right_column_name] = maxright + 2
+        end
+
+        def in_tenacious_transaction(&block)
+          retry_count = 0
+          begin
+            transaction(&block)
+          rescue ActiveRecord::StatementInvalid => error
+            raise unless connection.open_transactions.zero?
+            raise unless error.message =~ /Deadlock found when trying to get lock|Lock wait timeout exceeded/
+            raise unless retry_count < 10
+            retry_count += 1
+            logger.info "Deadlock detected on retry #{retry_count}, restarting transaction"
+            sleep(rand(retry_count)*0.1) # Aloha protocol
+            retry
+          end
+        end
+
+        # Prunes a branch off of the tree, shifting all of the elements on the right
+        # back to the left so the counts still work.
+        def destroy_descendants
+          return if right.nil? || left.nil? || skip_before_destroy
+
+          in_tenacious_transaction do
+            reload_nested_set
+            # select the rows in the model that extend past the deletion point and apply a lock
+            self.class.base_class.
+              select("id").
+              where("#{quoted_left_column_name} >= ?", left).
+              lock(true).
+              all
+
+            if acts_as_nested_set_options[:dependent] == :destroy
+              descendants.each do |model|
+                model.skip_before_destroy = true
+                model.destroy
+              end
+            else
+              nested_set_scope.delete_all(
+                ["#{quoted_left_column_name} > ? AND #{quoted_right_column_name} < ?",
+                  left, right]
+              )
+            end
+
+            # update lefts and rights for remaining nodes
+            diff = right - left + 1
+            nested_set_scope.update_all(
+              ["#{quoted_left_column_name} = (#{quoted_left_column_name} - ?)", diff],
+              ["#{quoted_left_column_name} > ?", right]
+            )
+            nested_set_scope.update_all(
+              ["#{quoted_right_column_name} = (#{quoted_right_column_name} - ?)", diff],
+              ["#{quoted_right_column_name} > ?", right]
+              )
+              
+reload
+              # Don't allow multiple calls to destroy to corrupt the set
+            self.skip_before_destroy = true
+          end
+        end
+
+        # reload left, right, and parent
+        def reload_nested_set
+          reload(
+            :select => "#{quoted_left_column_name}, #{quoted_right_column_name}, #{quoted_parent_column_name}",
+            :lock => true
+          )
+        end
+
+        def move_to(target, position)
+          raise ActiveRecord::ActiveRecordError, "You cannot move a new node" if self.new_record?
+          run_callbacks :move do
+            in_tenacious_transaction do
+              if target.is_a? self.class.base_class
+                target.reload_nested_set
+              elsif position != :root
+                # load object if node is not an object
+                target = nested_set_scope.find(target)
+              end
+              self.reload_nested_set
+
+              unless position == :root || move_possible?(target)
+                raise ActiveRecord::ActiveRecordError, "Impossible move, target node cannot be inside moved tree."
+              end
+
+              bound = case position
+                when :child;  target[right_column_name]
+                when :left;   target[left_column_name]
+                when :right;  target[right_column_name] + 1
+                when :root;   1
+                else raise ActiveRecord::ActiveRecordError, "Position should be :child, :left, :right or :root ('#{position}' received)."
+              end
+
+              if bound > self[right_column_name]
+                bound = bound - 1
+                other_bound = self[right_column_name] + 1
+              else
+                other_bound = self[left_column_name] - 1
+              end
+
+              # there would be no change
+              return if bound == self[right_column_name] || bound == self[left_column_name]
+
+              # we have defined the boundaries of two non-overlapping intervals,
+              # so sorting puts both the intervals and their boundaries in order
+              a, b, c, d = [self[left_column_name], self[right_column_name], bound, other_bound].sort
+
+              # select the rows in the model between a and d, and apply a lock
+              self.class.base_class.select('id').lock(true).where(
+                ["#{quoted_left_column_name} >= :a and #{quoted_right_column_name} <= :d", {:a => a, :d => d}]
+              )
+
+              new_parent = case position
+                when :child;  target.id
+                when :root;   nil
+                else          target[parent_column_name]
+              end
+
+              self.nested_set_scope.update_all([
+                "#{quoted_left_column_name} = CASE " +
+                  "WHEN #{quoted_left_column_name} BETWEEN :a AND :b " +
+                    "THEN #{quoted_left_column_name} + :d - :b " +
+                  "WHEN #{quoted_left_column_name} BETWEEN :c AND :d " +
+                    "THEN #{quoted_left_column_name} + :a - :c " +
+                  "ELSE #{quoted_left_column_name} END, " +
+                "#{quoted_right_column_name} = CASE " +
+                  "WHEN #{quoted_right_column_name} BETWEEN :a AND :b " +
+                    "THEN #{quoted_right_column_name} + :d - :b " +
+                  "WHEN #{quoted_right_column_name} BETWEEN :c AND :d " +
+                    "THEN #{quoted_right_column_name} + :a - :c " +
+                  "ELSE #{quoted_right_column_name} END, " +
+                "#{quoted_parent_column_name} = CASE " +
+                  "WHEN #{self.class.base_class.primary_key} = :id THEN :new_parent " +
+                  "ELSE #{quoted_parent_column_name} END",
+                {:a => a, :b => b, :c => c, :d => d, :id => self.id, :new_parent => new_parent}
+              ])
+            end
+            target.reload_nested_set if target
+            self.reload_nested_set
+          end
+        end
+
+      end
+
+      # Mixed into both classes and instances to provide easy access to the column names
+      module Columns
+        def left_column_name
+          acts_as_nested_set_options[:left_column]
+        end
+
+        def right_column_name
+          acts_as_nested_set_options[:right_column]
+        end
+
+        def parent_column_name
+          acts_as_nested_set_options[:parent_column]
+        end
+
+        def scope_column_names
+          Array(acts_as_nested_set_options[:scope])
+        end
+
+        def quoted_left_column_name
+          connection.quote_column_name(left_column_name)
+        end
+
+        def quoted_right_column_name
+          connection.quote_column_name(right_column_name)
+        end
+
+        def quoted_parent_column_name
+          connection.quote_column_name(parent_column_name)
+        end
+
+        def quoted_scope_column_names
+          scope_column_names.collect {|column_name| connection.quote_column_name(column_name) }
+        end
+      end
+
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fd/fd67b936cb5a4fcd00d856837e6795e5d9c87b69.svn-base
--- a/.svn/pristine/fd/fd67b936cb5a4fcd00d856837e6795e5d9c87b69.svn-base
+++ /dev/null
@@ -1,119 +0,0 @@
-# The engines plugin makes it trivial to share public assets using plugins. 
-# To do this, include an <tt>assets</tt> directory within your plugin, and put
-# your javascripts, stylesheets and images in subdirectories of that folder:
-#
-#   my_plugin
-#     |- init.rb
-#     |- lib/
-#     |- assets/
-#          |- javascripts/
-#          |    |- my_functions.js
-#          |
-#          |- stylesheets/
-#          |    |- my_styles.css
-#          |
-#          |- images/
-#               |- my_face.jpg
-#
-# Files within the <tt>asset</tt> structure are automatically mirrored into
-# a publicly-accessible folder each time your application starts (see
-# Engines::Assets#mirror_assets).
-#
-#
-# == Using plugin assets in views
-#
-# It's also simple to use Rails' helpers in your views to use plugin assets.
-# The default helper methods have been enhanced by the engines plugin to accept
-# a <tt>:plugin</tt> option, indicating the plugin containing the desired asset.
-#
-# For example, it's easy to use plugin assets in your layouts:
-#
-#   <%= stylesheet_link_tag "my_styles", :plugin => "my_plugin", :media => "screen" %>
-#   <%= javascript_include_tag "my_functions", :plugin => "my_plugin" %>
-# 
-# ... and similarly in views and partials, it's easy to use plugin images:
-#
-#   <%= image_tag "my_face", :plugin => "my_plugin" %>
-#   <!-- or -->
-#   <%= image_path "my_face", :plugin => "my_plugin" %>
-#
-# Where the default helpers allow the specification of more than one file (i.e. the
-# javascript and stylesheet helpers), you can do similarly for multiple assets from 
-# within a single plugin.
-#
-# ---
-#
-# This module enhances four of the methods from ActionView::Helpers::AssetTagHelper:
-#
-#  * stylesheet_link_tag
-#  * javascript_include_tag
-#  * image_path
-#  * image_tag
-#
-# Each one of these methods now accepts the key/value pair <tt>:plugin => "plugin_name"</tt>,
-# which can be used to specify the originating plugin for any assets.
-#
-module Engines::RailsExtensions::AssetHelpers
-  def self.included(base) #:nodoc:
-    base.class_eval do
-      [:stylesheet_link_tag, :javascript_include_tag, :image_path, :image_tag].each do |m|
-        alias_method_chain m, :engine_additions
-      end
-    end
-  end
-
-  # Adds plugin functionality to Rails' default stylesheet_link_tag method.
-  def stylesheet_link_tag_with_engine_additions(*sources)
-    stylesheet_link_tag_without_engine_additions(*Engines::RailsExtensions::AssetHelpers.pluginify_sources("stylesheets", *sources))
-  end
-
-  # Adds plugin functionality to Rails' default javascript_include_tag method.  
-  def javascript_include_tag_with_engine_additions(*sources)
-    javascript_include_tag_without_engine_additions(*Engines::RailsExtensions::AssetHelpers.pluginify_sources("javascripts", *sources))
-  end
-
-  #--
-  # Our modified image_path now takes a 'plugin' option, though it doesn't require it
-  #++
-
-  # Adds plugin functionality to Rails' default image_path method.
-  def image_path_with_engine_additions(source, options={})
-    options.stringify_keys!
-    source = Engines::RailsExtensions::AssetHelpers.plugin_asset_path(options["plugin"], "images", source) if options["plugin"]
-    image_path_without_engine_additions(source)
-  end
-
-  # Adds plugin functionality to Rails' default image_tag method.
-  def image_tag_with_engine_additions(source, options={})
-    options.stringify_keys!
-    if options["plugin"]
-      source = Engines::RailsExtensions::AssetHelpers.plugin_asset_path(options["plugin"], "images", source)
-      options.delete("plugin")
-    end
-    image_tag_without_engine_additions(source, options)
-  end
-
-  #--
-  # The following are methods on this module directly because of the weird-freaky way
-  # Rails creates the helper instance that views actually get
-  #++
-
-  # Convert sources to the paths for the given plugin, if any plugin option is given
-  def self.pluginify_sources(type, *sources)
-    options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { }
-    sources.map! { |s| plugin_asset_path(options["plugin"], type, s) } if options["plugin"]
-    options.delete("plugin") # we don't want it appearing in the HTML
-    sources << options # re-add options      
-  end  
-
-  # Returns the publicly-addressable relative URI for the given asset, type and plugin
-  def self.plugin_asset_path(plugin_name, type, asset)
-    raise "No plugin called '#{plugin_name}' - please use the full name of a loaded plugin." if Engines.plugins[plugin_name].nil?
-    "#{ActionController::Base.relative_url_root}/#{Engines.plugins[plugin_name].public_asset_directory}/#{type}/#{asset}"
-  end
-  
-end
-
-module ::ActionView::Helpers::AssetTagHelper #:nodoc:
-  include Engines::RailsExtensions::AssetHelpers
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fd/fdc1344d7f646f61fa7506b2b2b25effb91b6273.svn-base
--- a/.svn/pristine/fd/fdc1344d7f646f61fa7506b2b2b25effb91b6273.svn-base
+++ /dev/null
@@ -1,50 +0,0 @@
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-class PreviewsController < ApplicationController
-  before_filter :find_project
-
-  def issue
-    @issue = @project.issues.find_by_id(params[:id]) unless params[:id].blank?
-    if @issue
-      @attachements = @issue.attachments
-      @description = params[:issue] && params[:issue][:description]
-      if @description && @description.gsub(/(\r?\n|\n\r?)/, "\n") == @issue.description.to_s.gsub(/(\r?\n|\n\r?)/, "\n")
-        @description = nil
-      end
-      @notes = params[:notes]
-    else
-      @description = (params[:issue] ? params[:issue][:description] : nil)
-    end
-    render :layout => false
-  end
-
-  def news
-    @text = (params[:news] ? params[:news][:description] : nil)
-    render :partial => 'common/preview'
-  end
-
-  private
-
-  def find_project
-    project_id = (params[:issue] && params[:issue][:project_id]) || params[:project_id]
-    @project = Project.find(project_id)
-  rescue ActiveRecord::RecordNotFound
-    render_404
-  end
-
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fd/fdfe5659f8fae8662194ea302cbaaa172aeab193.svn-base
--- a/.svn/pristine/fd/fdfe5659f8fae8662194ea302cbaaa172aeab193.svn-base
+++ /dev/null
@@ -1,168 +0,0 @@
-# encoding: utf-8
-#
-# Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-require File.expand_path('../../test_helper', __FILE__)
-
-class AttachmentTest < ActiveSupport::TestCase
-  fixtures :users, :projects, :roles, :members, :member_roles,
-           :enabled_modules, :issues, :trackers, :attachments
-  
-  class MockFile
-    attr_reader :original_filename, :content_type, :content, :size
-    
-    def initialize(attributes)
-      @original_filename = attributes[:original_filename]
-      @content_type = attributes[:content_type]
-      @content = attributes[:content] || "Content"
-      @size = content.size
-    end
-  end
-
-  def setup
-    set_tmp_attachments_directory
-  end
-
-  def test_create
-    a = Attachment.new(:container => Issue.find(1),
-                       :file => uploaded_test_file("testfile.txt", "text/plain"),
-                       :author => User.find(1))
-    assert a.save
-    assert_equal 'testfile.txt', a.filename
-    assert_equal 59, a.filesize
-    assert_equal 'text/plain', a.content_type
-    assert_equal 0, a.downloads
-    assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
-    assert File.exist?(a.diskfile)
-    assert_equal 59, File.size(a.diskfile)
-  end
-
-  def test_destroy
-    a = Attachment.new(:container => Issue.find(1),
-                       :file => uploaded_test_file("testfile.txt", "text/plain"),
-                       :author => User.find(1))
-    assert a.save
-    assert_equal 'testfile.txt', a.filename
-    assert_equal 59, a.filesize
-    assert_equal 'text/plain', a.content_type
-    assert_equal 0, a.downloads
-    assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
-    diskfile = a.diskfile
-    assert File.exist?(diskfile)
-    assert_equal 59, File.size(a.diskfile)
-    assert a.destroy
-    assert !File.exist?(diskfile)
-  end
-
-  def test_create_should_auto_assign_content_type
-    a = Attachment.new(:container => Issue.find(1),
-                       :file => uploaded_test_file("testfile.txt", ""),
-                       :author => User.find(1))
-    assert a.save
-    assert_equal 'text/plain', a.content_type
-  end
-
-  def test_identical_attachments_at_the_same_time_should_not_overwrite
-    a1 = Attachment.create!(:container => Issue.find(1),
-                            :file => uploaded_test_file("testfile.txt", ""),
-                            :author => User.find(1))
-    a2 = Attachment.create!(:container => Issue.find(1),
-                            :file => uploaded_test_file("testfile.txt", ""),
-                            :author => User.find(1))
-    assert a1.disk_filename != a2.disk_filename
-  end
-  
-  def test_filename_should_be_basenamed
-    a = Attachment.new(:file => MockFile.new(:original_filename => "path/to/the/file"))
-    assert_equal 'file', a.filename
-  end
-  
-  def test_filename_should_be_sanitized
-    a = Attachment.new(:file => MockFile.new(:original_filename => "valid:[] invalid:?%*|\"'<>chars"))
-    assert_equal 'valid_[] invalid_chars', a.filename
-  end
-
-  def test_diskfilename
-    assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
-    assert_equal 'test_file.txt', Attachment.disk_filename("test_file.txt")[13..-1]
-    assert_equal '770c509475505f37c2b8fb6030434d6b.txt', Attachment.disk_filename("test_accentuÃ©.txt")[13..-1]
-    assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentuÃ©")[13..-1]
-    assert_equal 'cbb5b0f30978ba03731d61f9f6d10011', Attachment.disk_filename("test_accentuÃ©.Ã§a")[13..-1]
-  end
-
-  context "Attachmnet.attach_files" do
-    should "attach the file" do
-      issue = Issue.first
-      assert_difference 'Attachment.count' do
-        Attachment.attach_files(issue,
-          '1' => {
-            'file' => uploaded_test_file('testfile.txt', 'text/plain'),
-            'description' => 'test'
-          })
-      end
-
-      attachment = Attachment.first(:order => 'id DESC')
-      assert_equal issue, attachment.container
-      assert_equal 'testfile.txt', attachment.filename
-      assert_equal 59, attachment.filesize
-      assert_equal 'test', attachment.description
-      assert_equal 'text/plain', attachment.content_type
-      assert File.exists?(attachment.diskfile)
-      assert_equal 59, File.size(attachment.diskfile)
-    end
-
-    should "add unsaved files to the object as unsaved attachments" do
-      # Max size of 0 to force Attachment creation failures
-      with_settings(:attachment_max_size => 0) do
-        @project = Project.generate!
-        response = Attachment.attach_files(@project, {
-                                             '1' => {'file' => mock_file, 'description' => 'test'},
-                                             '2' => {'file' => mock_file, 'description' => 'test'}
-                                           })
-
-        assert response[:unsaved].present?
-        assert_equal 2, response[:unsaved].length
-        assert response[:unsaved].first.new_record?
-        assert response[:unsaved].second.new_record?
-        assert_equal response[:unsaved], @project.unsaved_attachments
-      end
-    end
-  end
-
-  def test_latest_attach
-    Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
-    a1 = Attachment.find(16)
-    assert_equal "testfile.png", a1.filename
-    assert a1.readable?
-    assert (! a1.visible?(User.anonymous))
-    assert a1.visible?(User.find(2))
-    a2 = Attachment.find(17)
-    assert_equal "testfile.PNG", a2.filename
-    assert a2.readable?
-    assert (! a2.visible?(User.anonymous))
-    assert a2.visible?(User.find(2))
-    assert a1.created_on < a2.created_on
-
-    la1 = Attachment.latest_attach([a1, a2], "testfile.png")
-    assert_equal 17, la1.id
-    la2 = Attachment.latest_attach([a1, a2], "Testfile.PNG")
-    assert_equal 17, la2.id
-
-    set_tmp_attachments_directory
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fe/fe0465ebb05e92c484a2edd16cfdf129d7d41205.svn-base
--- a/.svn/pristine/fe/fe0465ebb05e92c484a2edd16cfdf129d7d41205.svn-base
+++ /dev/null
@@ -1,81 +0,0 @@
-module CodeRay
-module Scanners
-  
-  load :html
-  load :ruby
-  
-  # Scanner for HTML ERB templates.
-  class ERB < Scanner
-    
-    register_for :erb
-    title 'HTML ERB Template'
-    
-    KINDS_NOT_LOC = HTML::KINDS_NOT_LOC
-    
-    ERB_RUBY_BLOCK = /
-      (<%(?!%)[-=\#]?)
-      ((?>
-        [^\-%]*    # normal*
-        (?>        # special
-          (?: %(?!>) | -(?!%>) )
-          [^\-%]*  # normal*
-        )*
-      ))
-      ((?: -?%> )?)
-    /x  # :nodoc:
-    
-    START_OF_ERB = /
-      <%(?!%)
-    /x  # :nodoc:
-    
-  protected
-    
-    def setup
-      @ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true
-      @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true, :keep_state => true
-    end
-    
-    def reset_instance
-      super
-      @html_scanner.reset
-    end
-    
-    def scan_tokens encoder, options
-      
-      until eos?
-        
-        if (match = scan_until(/(?=#{START_OF_ERB})/o) || scan_rest) and not match.empty?
-          @html_scanner.tokenize match, :tokens => encoder
-          
-        elsif match = scan(/#{ERB_RUBY_BLOCK}/o)
-          start_tag = self[1]
-          code = self[2]
-          end_tag = self[3]
-          
-          encoder.begin_group :inline
-          encoder.text_token start_tag, :inline_delimiter
-          
-          if start_tag == '<%#'
-            encoder.text_token code, :comment
-          else
-            @ruby_scanner.tokenize code, :tokens => encoder
-          end unless code.empty?
-          
-          encoder.text_token end_tag, :inline_delimiter unless end_tag.empty?
-          encoder.end_group :inline
-          
-        else
-          raise_inspect 'else-case reached!', encoder
-          
-        end
-        
-      end
-      
-      encoder
-      
-    end
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fe/fe2e55a5ec8942da65be048ad7fee177c1286f80.svn-base
--- /dev/null
+++ b/.svn/pristine/fe/fe2e55a5ec8942da65be048ad7fee177c1286f80.svn-base
@@ -0,0 +1,9 @@
+class AddProjectsInheritMembers < ActiveRecord::Migration
+  def up
+    add_column :projects, :inherit_members, :boolean, :default => false, :null => false
+  end
+
+  def down
+    remove_column :projects, :inherit_members
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fe/fe4ff1d0091ede8f5bbe79d77084f595941f18d8.svn-base
--- /dev/null
+++ b/.svn/pristine/fe/fe4ff1d0091ede8f5bbe79d77084f595941f18d8.svn-base
@@ -0,0 +1,1093 @@
+# Chinese (China) translations for Ruby on Rails
+# by tsechingho (http://github.com/tsechingho)
+zh:
+  # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
+  direction: ltr
+  jquery:
+    locale: "zh-CN"
+  date:
+    formats:
+      # Use the strftime parameters for formats.
+      # When no format has been given, it uses default.
+      # You can provide other formats here if you like!
+      default: "%Y-%m-%d"
+      short: "%b%dæ—¥"
+      long: "%Yå¹´%b%dæ—¥"
+
+    day_names: [æ˜ŸæœŸå¤©, æ˜ŸæœŸä¸€, æ˜ŸæœŸäºŒ, æ˜ŸæœŸä¸‰, æ˜ŸæœŸå››, æ˜ŸæœŸäº”, æ˜ŸæœŸå…­]
+    abbr_day_names: [æ—¥, ä¸€, äºŒ, ä¸‰, å››, äº”, å…­]
+
+    # Don't forget the nil at the beginning; there's no such thing as a 0th month
+    month_names: [~, ä¸€æœˆ, äºŒæœˆ, ä¸‰æœˆ, å››æœˆ, äº”æœˆ, å…­æœˆ, ä¸ƒæœˆ, å…«æœˆ, ä¹æœˆ, åæœˆ, åä¸€æœˆ, åäºŒæœˆ]
+    abbr_month_names: [~, 1æœˆ, 2æœˆ, 3æœˆ, 4æœˆ, 5æœˆ, 6æœˆ, 7æœˆ, 8æœˆ, 9æœˆ, 10æœˆ, 11æœˆ, 12æœˆ]
+    # Used in date_select and datime_select.
+    order:
+      - :year
+      - :month
+      - :day
+
+  time:
+    formats:
+      default: "%Yå¹´%b%dæ—¥ %A %H:%M:%S"
+      time: "%H:%M"
+      short: "%b%dæ—¥ %H:%M"
+      long: "%Yå¹´%b%dæ—¥ %H:%M"
+    am: "ä¸Šåˆ"
+    pm: "ä¸‹åˆ"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "åŠåˆ†é’Ÿ"
+      less_than_x_seconds:
+        one: "ä¸€ç§’å†…"
+        other: "å°‘äºŽ %{count} ç§’"
+      x_seconds:
+        one: "ä¸€ç§’"
+        other: "%{count} ç§’"
+      less_than_x_minutes:
+        one: "ä¸€åˆ†é’Ÿå†…"
+        other: "å°‘äºŽ %{count} åˆ†é’Ÿ"
+      x_minutes:
+        one: "ä¸€åˆ†é’Ÿ"
+        other: "%{count} åˆ†é’Ÿ"
+      about_x_hours:
+        one: "å¤§çº¦ä¸€å°æ—¶"
+        other: "å¤§çº¦ %{count} å°æ—¶"
+      x_hours:
+        one:   "1 å°æ—¶"
+        other: "%{count} å°æ—¶"
+      x_days:
+        one: "ä¸€å¤©"
+        other: "%{count} å¤©"
+      about_x_months:
+        one: "å¤§çº¦ä¸€ä¸ªæœˆ"
+        other: "å¤§çº¦ %{count} ä¸ªæœˆ"
+      x_months:
+        one: "ä¸€ä¸ªæœˆ"
+        other: "%{count} ä¸ªæœˆ"
+      about_x_years:
+        one: "å¤§çº¦ä¸€å¹´"
+        other: "å¤§çº¦ %{count} å¹´"
+      over_x_years:
+        one: "è¶…è¿‡ä¸€å¹´"
+        other: "è¶…è¿‡ %{count} å¹´"
+      almost_x_years:
+        one:   "å°†è¿‘ 1 å¹´"
+        other: "å°†è¿‘ %{count} å¹´"
+
+  number:
+    # Default format for numbers
+    format:
+      separator: "."
+      delimiter: ""
+      precision: 3
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      storage_units:
+        format: "%n %u"
+        units:
+          byte:
+            one: "Byte"
+            other: "Bytes"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+# Used in array.to_sentence.
+  support:
+    array:
+      sentence_connector: "å’Œ"
+      skip_last_comma: false
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:    "ç”±äºŽå‘ç”Ÿäº†ä¸€ä¸ªé”™è¯¯ %{model} æ— æ³•ä¿å­˜"
+          other:  "%{count} ä¸ªé”™è¯¯ä½¿å¾— %{model} æ— æ³•ä¿å­˜"
+      messages:
+        inclusion: "ä¸åŒ…å«äºŽåˆ—è¡¨ä¸­"
+        exclusion: "æ˜¯ä¿ç•™å…³é”®å­—"
+        invalid: "æ˜¯æ— æ•ˆçš„"
+        confirmation: "ä¸Žç¡®è®¤å€¼ä¸åŒ¹é…"
+        accepted: "å¿…é¡»æ˜¯å¯è¢«æŽ¥å—çš„"
+        empty: "ä¸èƒ½ç•™ç©º"
+        blank: "ä¸èƒ½ä¸ºç©ºå­—ç¬¦"
+        too_long: "è¿‡é•¿ï¼ˆæœ€é•¿ä¸º %{count} ä¸ªå­—ç¬¦ï¼‰"
+        too_short: "è¿‡çŸ­ï¼ˆæœ€çŸ­ä¸º %{count} ä¸ªå­—ç¬¦ï¼‰"
+        wrong_length: "é•¿åº¦éžæ³•ï¼ˆå¿…é¡»ä¸º %{count} ä¸ªå­—ç¬¦ï¼‰"
+        taken: "å·²ç»è¢«ä½¿ç”¨"
+        not_a_number: "ä¸æ˜¯æ•°å­—"
+        not_a_date: "ä¸æ˜¯åˆæ³•æ—¥æœŸ"
+        greater_than: "å¿…é¡»å¤§äºŽ %{count}"
+        greater_than_or_equal_to: "å¿…é¡»å¤§äºŽæˆ–ç­‰äºŽ %{count}"
+        equal_to: "å¿…é¡»ç­‰äºŽ %{count}"
+        less_than: "å¿…é¡»å°äºŽ %{count}"
+        less_than_or_equal_to: "å¿…é¡»å°äºŽæˆ–ç­‰äºŽ %{count}"
+        odd: "å¿…é¡»ä¸ºå•æ•°"
+        even: "å¿…é¡»ä¸ºåŒæ•°"
+        greater_than_start_date: "å¿…é¡»åœ¨èµ·å§‹æ—¥æœŸä¹‹åŽ"
+        not_same_project: "ä¸å±žäºŽåŒä¸€ä¸ªé¡¹ç›®"
+        circular_dependency: "æ­¤å…³è”å°†å¯¼è‡´å¾ªçŽ¯ä¾èµ–"
+        cant_link_an_issue_with_a_descendant: "é—®é¢˜ä¸èƒ½å…³è”åˆ°å®ƒçš„å­ä»»åŠ¡"
+
+  actionview_instancetag_blank_option: è¯·é€‰æ‹©
+
+  general_text_No: 'å¦'
+  general_text_Yes: 'æ˜¯'
+  general_text_no: 'å¦'
+  general_text_yes: 'æ˜¯'
+  general_lang_name: 'Simplified Chinese (ç®€ä½“ä¸­æ–‡)'
+  general_csv_separator: ','
+  general_csv_decimal_separator: '.'
+  general_csv_encoding: gb18030
+  general_pdf_encoding: gb18030
+  general_first_day_of_week: '7'
+
+  notice_account_updated: å¸å·æ›´æ–°æˆåŠŸ
+  notice_account_invalid_creditentials: æ— æ•ˆçš„ç”¨æˆ·åæˆ–å¯†ç 
+  notice_account_password_updated: å¯†ç æ›´æ–°æˆåŠŸ
+  notice_account_wrong_password: å¯†ç é”™è¯¯
+  notice_account_register_done: å¸å·åˆ›å»ºæˆåŠŸï¼Œè¯·ä½¿ç”¨æ³¨å†Œç¡®è®¤é‚®ä»¶ä¸­çš„é“¾æŽ¥æ¥æ¿€æ´»æ‚¨çš„å¸å·ã€‚
+  notice_account_unknown_email: æœªçŸ¥ç”¨æˆ·
+  notice_can_t_change_password: è¯¥å¸å·ä½¿ç”¨äº†å¤–éƒ¨è®¤è¯ï¼Œå› æ­¤æ— æ³•æ›´æ”¹å¯†ç ã€‚
+  notice_account_lost_email_sent: ç³»ç»Ÿå·²å°†å¼•å¯¼æ‚¨è®¾ç½®æ–°å¯†ç çš„é‚®ä»¶å‘é€ç»™æ‚¨ã€‚
+  notice_account_activated: æ‚¨çš„å¸å·å·²è¢«æ¿€æ´»ã€‚æ‚¨çŽ°åœ¨å¯ä»¥ç™»å½•äº†ã€‚
+  notice_successful_create: åˆ›å»ºæˆåŠŸ
+  notice_successful_update: æ›´æ–°æˆåŠŸ
+  notice_successful_delete: åˆ é™¤æˆåŠŸ
+  notice_successful_connection: è¿žæŽ¥æˆåŠŸ
+  notice_file_not_found: æ‚¨è®¿é—®çš„é¡µé¢ä¸å­˜åœ¨æˆ–å·²è¢«åˆ é™¤ã€‚
+  notice_locking_conflict: æ•°æ®å·²è¢«å¦ä¸€ä½ç”¨æˆ·æ›´æ–°
+  notice_not_authorized: å¯¹ä¸èµ·ï¼Œæ‚¨æ— æƒè®¿é—®æ­¤é¡µé¢ã€‚
+  notice_not_authorized_archived_project: è¦è®¿é—®çš„é¡¹ç›®å·²ç»å½’æ¡£ã€‚
+  notice_email_sent: "é‚®ä»¶å·²å‘é€è‡³ %{value}"
+  notice_email_error: "å‘é€é‚®ä»¶æ—¶å‘ç”Ÿé”™è¯¯ (%{value})"
+  notice_feeds_access_key_reseted: æ‚¨çš„RSSå­˜å–é”®å·²è¢«é‡ç½®ã€‚
+  notice_api_access_key_reseted: æ‚¨çš„APIè®¿é—®é”®å·²è¢«é‡ç½®ã€‚
+  notice_failed_to_save_issues: "%{count} ä¸ªé—®é¢˜ä¿å­˜å¤±è´¥ï¼ˆå…±é€‰æ‹© %{total} ä¸ªé—®é¢˜ï¼‰ï¼š%{ids}."
+  notice_failed_to_save_members: "æˆå‘˜ä¿å­˜å¤±è´¥: %{errors}."
+  notice_no_issue_selected: "æœªé€‰æ‹©ä»»ä½•é—®é¢˜ï¼è¯·é€‰æ‹©æ‚¨è¦ç¼–è¾‘çš„é—®é¢˜ã€‚"
+  notice_account_pending: "æ‚¨çš„å¸å·å·²è¢«æˆåŠŸåˆ›å»ºï¼Œæ­£åœ¨ç­‰å¾…ç®¡ç†å‘˜çš„å®¡æ ¸ã€‚"
+  notice_default_data_loaded: æˆåŠŸè½½å…¥é»˜è®¤è®¾ç½®ã€‚
+  notice_unable_delete_version: æ— æ³•åˆ é™¤ç‰ˆæœ¬
+  notice_unable_delete_time_entry: æ— æ³•åˆ é™¤å·¥æ—¶
+  notice_issue_done_ratios_updated: é—®é¢˜å®Œæˆåº¦å·²æ›´æ–°ã€‚
+  notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})"
+
+  error_can_t_load_default_data: "æ— æ³•è½½å…¥é»˜è®¤è®¾ç½®ï¼š%{value}"
+  error_scm_not_found: "ç‰ˆæœ¬åº“ä¸­ä¸å­˜åœ¨è¯¥æ¡ç›®å’Œï¼ˆæˆ–ï¼‰å…¶ä¿®è®¢ç‰ˆæœ¬ã€‚"
+  error_scm_command_failed: "è®¿é—®ç‰ˆæœ¬åº“æ—¶å‘ç”Ÿé”™è¯¯ï¼š%{value}"
+  error_scm_annotate: "è¯¥æ¡ç›®ä¸å­˜åœ¨æˆ–æ— æ³•è¿½æº¯ã€‚"
+  error_issue_not_found_in_project: 'é—®é¢˜ä¸å­˜åœ¨æˆ–ä¸å±žäºŽæ­¤é¡¹ç›®'
+  error_no_tracker_in_project: è¯¥é¡¹ç›®æœªè®¾å®šè·Ÿè¸ªæ ‡ç­¾ï¼Œè¯·æ£€æŸ¥é¡¹ç›®é…ç½®ã€‚
+  error_no_default_issue_status: æœªè®¾ç½®é»˜è®¤çš„é—®é¢˜çŠ¶æ€ã€‚è¯·æ£€æŸ¥ç³»ç»Ÿè®¾ç½®ï¼ˆ"ç®¡ç†" -> "é—®é¢˜çŠ¶æ€"ï¼‰ã€‚
+  error_can_not_delete_custom_field: æ— æ³•åˆ é™¤è‡ªå®šä¹‰å±žæ€§
+  error_can_not_delete_tracker: "è¯¥è·Ÿè¸ªæ ‡ç­¾å·²åŒ…å«é—®é¢˜,æ— æ³•åˆ é™¤"
+  error_can_not_remove_role: "è¯¥è§’è‰²æ­£åœ¨ä½¿ç”¨ä¸­ï¼Œæ— æ³•åˆ é™¤"
+  error_can_not_reopen_issue_on_closed_version: è¯¥é—®é¢˜è¢«å…³è”åˆ°ä¸€ä¸ªå·²ç»å…³é—­çš„ç‰ˆæœ¬ï¼Œå› æ­¤æ— æ³•é‡æ–°æ‰“å¼€ã€‚
+  error_can_not_archive_project: è¯¥é¡¹ç›®æ— æ³•è¢«å­˜æ¡£
+  error_issue_done_ratios_not_updated: é—®é¢˜å®Œæˆåº¦æœªèƒ½è¢«æ›´æ–°ã€‚
+  error_workflow_copy_source: è¯·é€‰æ‹©ä¸€ä¸ªæºè·Ÿè¸ªæ ‡ç­¾æˆ–è€…è§’è‰²
+  error_workflow_copy_target: è¯·é€‰æ‹©ç›®æ ‡è·Ÿè¸ªæ ‡ç­¾å’Œè§’è‰²
+  error_unable_delete_issue_status: 'æ— æ³•åˆ é™¤é—®é¢˜çŠ¶æ€'
+  error_unable_to_connect: "æ— æ³•è¿žæŽ¥ (%{value})"
+  warning_attachments_not_saved: "%{count} ä¸ªæ–‡ä»¶ä¿å­˜å¤±è´¥"
+
+  mail_subject_lost_password: "æ‚¨çš„ %{value} å¯†ç "
+  mail_body_lost_password: 'è¯·ç‚¹å‡»ä»¥ä¸‹é“¾æŽ¥æ¥ä¿®æ”¹æ‚¨çš„å¯†ç ï¼š'
+  mail_subject_register: "%{value}å¸å·æ¿€æ´»"
+  mail_body_register: 'è¯·ç‚¹å‡»ä»¥ä¸‹é“¾æŽ¥æ¥æ¿€æ´»æ‚¨çš„å¸å·ï¼š'
+  mail_body_account_information_external: "æ‚¨å¯ä»¥ä½¿ç”¨æ‚¨çš„ %{value} å¸å·æ¥ç™»å½•ã€‚"
+  mail_body_account_information: æ‚¨çš„å¸å·ä¿¡æ¯
+  mail_subject_account_activation_request: "%{value}å¸å·æ¿€æ´»è¯·æ±‚"
+  mail_body_account_activation_request: "æ–°ç”¨æˆ·ï¼ˆ%{value}ï¼‰å·²å®Œæˆæ³¨å†Œï¼Œæ­£åœ¨ç­‰å€™æ‚¨çš„å®¡æ ¸ï¼š"
+  mail_subject_reminder: "%{count} ä¸ªé—®é¢˜éœ€è¦å°½å¿«è§£å†³ (%{days})"
+  mail_body_reminder: "æŒ‡æ´¾ç»™æ‚¨çš„ %{count} ä¸ªé—®é¢˜éœ€è¦åœ¨ %{days} å¤©å†…å®Œæˆï¼š"
+  mail_subject_wiki_content_added: "'%{id}' wikié¡µé¢å·²æ·»åŠ "
+  mail_body_wiki_content_added: "'%{id}' wikié¡µé¢å·²ç”± %{author} æ·»åŠ ã€‚"
+  mail_subject_wiki_content_updated: "'%{id}' wikié¡µé¢å·²æ›´æ–°ã€‚"
+  mail_body_wiki_content_updated: "'%{id}' wikié¡µé¢å·²ç”± %{author} æ›´æ–°ã€‚"
+
+
+  field_name: åç§°
+  field_description: æè¿°
+  field_summary: æ‘˜è¦
+  field_is_required: å¿…å¡«
+  field_firstname: åå­—
+  field_lastname: å§“æ°
+  field_mail: é‚®ä»¶åœ°å€
+  field_filename: æ–‡ä»¶
+  field_filesize: å¤§å°
+  field_downloads: ä¸‹è½½æ¬¡æ•°
+  field_author: ä½œè€…
+  field_created_on: åˆ›å»ºäºŽ
+  field_updated_on: æ›´æ–°äºŽ
+  field_field_format: æ ¼å¼
+  field_is_for_all: ç”¨äºŽæ‰€æœ‰é¡¹ç›®
+  field_possible_values: å¯èƒ½çš„å€¼
+  field_regexp: æ­£åˆ™è¡¨è¾¾å¼
+  field_min_length: æœ€å°é•¿åº¦
+  field_max_length: æœ€å¤§é•¿åº¦
+  field_value: å€¼
+  field_category: ç±»åˆ«
+  field_title: æ ‡é¢˜
+  field_project: é¡¹ç›®
+  field_issue: é—®é¢˜
+  field_status: çŠ¶æ€
+  field_notes: è¯´æ˜Ž
+  field_is_closed: å·²å…³é—­çš„é—®é¢˜
+  field_is_default: é»˜è®¤å€¼
+  field_tracker: è·Ÿè¸ª
+  field_subject: ä¸»é¢˜
+  field_due_date: è®¡åˆ’å®Œæˆæ—¥æœŸ
+  field_assigned_to: æŒ‡æ´¾ç»™
+  field_priority: ä¼˜å…ˆçº§
+  field_fixed_version: ç›®æ ‡ç‰ˆæœ¬
+  field_user: ç”¨æˆ·
+  field_principal: ç”¨æˆ·/ç”¨æˆ·ç»„
+  field_role: è§’è‰²
+  field_homepage: ä¸»é¡µ
+  field_is_public: å…¬å¼€
+  field_parent: ä¸Šçº§é¡¹ç›®
+  field_is_in_roadmap: åœ¨è·¯çº¿å›¾ä¸­æ˜¾ç¤º
+  field_login: ç™»å½•å
+  field_mail_notification: é‚®ä»¶é€šçŸ¥
+  field_admin: ç®¡ç†å‘˜
+  field_last_login_on: æœ€åŽç™»å½•
+  field_language: è¯­è¨€
+  field_effective_date: æ—¥æœŸ
+  field_password: å¯†ç 
+  field_new_password: æ–°å¯†ç 
+  field_password_confirmation: ç¡®è®¤
+  field_version: ç‰ˆæœ¬
+  field_type: ç±»åž‹
+  field_host: ä¸»æœº
+  field_port: ç«¯å£
+  field_account: å¸å·
+  field_base_dn: Base DN
+  field_attr_login: ç™»å½•åå±žæ€§
+  field_attr_firstname: åå­—å±žæ€§
+  field_attr_lastname: å§“æ°å±žæ€§
+  field_attr_mail: é‚®ä»¶å±žæ€§
+  field_onthefly: å³æ—¶ç”¨æˆ·ç”Ÿæˆ
+  field_start_date: å¼€å§‹æ—¥æœŸ
+  field_done_ratio: "% å®Œæˆ"
+  field_auth_source: è®¤è¯æ¨¡å¼
+  field_hide_mail: éšè—æˆ‘çš„é‚®ä»¶åœ°å€
+  field_comments: æ³¨é‡Š
+  field_url: URL
+  field_start_page: èµ·å§‹é¡µ
+  field_subproject: å­é¡¹ç›®
+  field_hours: å°æ—¶
+  field_activity: æ´»åŠ¨
+  field_spent_on: æ—¥æœŸ
+  field_identifier: æ ‡è¯†
+  field_is_filter: ä½œä¸ºè¿‡æ»¤æ¡ä»¶
+  field_issue_to: ç›¸å…³é—®é¢˜
+  field_delay: å»¶æœŸ
+  field_assignable: é—®é¢˜å¯æŒ‡æ´¾ç»™æ­¤è§’è‰²
+  field_redirect_existing_links: é‡å®šå‘åˆ°çŽ°æœ‰é“¾æŽ¥
+  field_estimated_hours: é¢„æœŸæ—¶é—´
+  field_column_names: åˆ—
+  field_time_entries: å·¥æ—¶
+  field_time_zone: æ—¶åŒº
+  field_searchable: å¯ç”¨ä½œæœç´¢æ¡ä»¶
+  field_default_value: é»˜è®¤å€¼
+  field_comments_sorting: æ˜¾ç¤ºæ³¨é‡Š
+  field_parent_title: ä¸Šçº§é¡µé¢
+  field_editable: å¯ç¼–è¾‘
+  field_watcher: è·Ÿè¸ªè€…
+  field_identity_url: OpenID URL
+  field_content: å†…å®¹
+  field_group_by: æ ¹æ®æ­¤æ¡ä»¶åˆ†ç»„
+  field_sharing: å…±äº«
+  field_parent_issue: çˆ¶ä»»åŠ¡
+  field_member_of_group: ç”¨æˆ·ç»„çš„æˆå‘˜
+  field_assigned_to_role: è§’è‰²çš„æˆå‘˜
+  field_text: æ–‡æœ¬å­—æ®µ
+  field_visible: å¯è§çš„
+
+  setting_app_title: åº”ç”¨ç¨‹åºæ ‡é¢˜
+  setting_app_subtitle: åº”ç”¨ç¨‹åºå­æ ‡é¢˜
+  setting_welcome_text: æ¬¢è¿Žæ–‡å­—
+  setting_default_language: é»˜è®¤è¯­è¨€
+  setting_login_required: è¦æ±‚è®¤è¯
+  setting_self_registration: å…è®¸è‡ªæ³¨å†Œ
+  setting_attachment_max_size: é™„ä»¶å¤§å°é™åˆ¶
+  setting_issues_export_limit: é—®é¢˜å¯¼å‡ºæ¡ç›®çš„é™åˆ¶
+  setting_mail_from: é‚®ä»¶å‘ä»¶äººåœ°å€
+  setting_bcc_recipients: ä½¿ç”¨å¯†ä»¶æŠ„é€ (bcc)
+  setting_plain_text_mail: çº¯æ–‡æœ¬ï¼ˆæ— HTMLï¼‰
+  setting_host_name: ä¸»æœºåç§°
+  setting_text_formatting: æ–‡æœ¬æ ¼å¼
+  setting_wiki_compression: åŽ‹ç¼©WikiåŽ†å²æ–‡æ¡£
+  setting_feeds_limit: RSS Feedå†…å®¹æ¡æ•°é™åˆ¶
+  setting_default_projects_public: æ–°å»ºé¡¹ç›®é»˜è®¤ä¸ºå…¬å¼€é¡¹ç›®
+  setting_autofetch_changesets: è‡ªåŠ¨èŽ·å–ç¨‹åºå˜æ›´
+  setting_sys_api_enabled: å¯ç”¨ç”¨äºŽç‰ˆæœ¬åº“ç®¡ç†çš„Web Service
+  setting_commit_ref_keywords: ç”¨äºŽå¼•ç”¨é—®é¢˜çš„å…³é”®å­—
+  setting_commit_fix_keywords: ç”¨äºŽè§£å†³é—®é¢˜çš„å…³é”®å­—
+  setting_autologin: è‡ªåŠ¨ç™»å½•
+  setting_date_format: æ—¥æœŸæ ¼å¼
+  setting_time_format: æ—¶é—´æ ¼å¼
+  setting_cross_project_issue_relations: å…è®¸ä¸åŒé¡¹ç›®ä¹‹é—´çš„é—®é¢˜å…³è”
+  setting_issue_list_default_columns: é—®é¢˜åˆ—è¡¨ä¸­æ˜¾ç¤ºçš„é»˜è®¤åˆ—
+  setting_emails_header: é‚®ä»¶å¤´
+  setting_emails_footer: é‚®ä»¶ç­¾å
+  setting_protocol: åè®®
+  setting_per_page_options: æ¯é¡µæ˜¾ç¤ºæ¡ç›®ä¸ªæ•°çš„è®¾ç½®
+  setting_user_format: ç”¨æˆ·æ˜¾ç¤ºæ ¼å¼
+  setting_activity_days_default: åœ¨é¡¹ç›®æ´»åŠ¨ä¸­æ˜¾ç¤ºçš„å¤©æ•°
+  setting_display_subprojects_issues: åœ¨é¡¹ç›®é¡µé¢ä¸Šé»˜è®¤æ˜¾ç¤ºå­é¡¹ç›®çš„é—®é¢˜
+  setting_enabled_scm: å¯ç”¨ SCM
+  setting_mail_handler_body_delimiters: åœ¨è¿™äº›è¡Œä¹‹åŽæˆªæ–­é‚®ä»¶
+  setting_mail_handler_api_enabled: å¯ç”¨ç”¨äºŽæŽ¥æ”¶é‚®ä»¶çš„æœåŠ¡
+  setting_mail_handler_api_key: API key
+  setting_sequential_project_identifiers: é¡ºåºäº§ç”Ÿé¡¹ç›®æ ‡è¯†
+  setting_gravatar_enabled: ä½¿ç”¨Gravatarç”¨æˆ·å¤´åƒ
+  setting_gravatar_default: é»˜è®¤çš„Gravatarå¤´åƒ
+  setting_diff_max_lines_displayed: æŸ¥çœ‹å·®åˆ«é¡µé¢ä¸Šæ˜¾ç¤ºçš„æœ€å¤§è¡Œæ•°
+  setting_file_max_size_displayed: å…è®¸ç›´æŽ¥æ˜¾ç¤ºçš„æœ€å¤§æ–‡æœ¬æ–‡ä»¶
+  setting_repository_log_display_limit: åœ¨æ–‡ä»¶å˜æ›´è®°å½•é¡µé¢ä¸Šæ˜¾ç¤ºçš„æœ€å¤§ä¿®è®¢ç‰ˆæœ¬æ•°é‡
+  setting_openid: å…è®¸ä½¿ç”¨OpenIDç™»å½•å’Œæ³¨å†Œ
+  setting_password_min_length: æœ€çŸ­å¯†ç é•¿åº¦
+  setting_new_project_user_role_id: éžç®¡ç†å‘˜ç”¨æˆ·æ–°å»ºé¡¹ç›®æ—¶å°†è¢«èµ‹äºˆçš„ï¼ˆåœ¨è¯¥é¡¹ç›®ä¸­çš„ï¼‰è§’è‰²
+  setting_default_projects_modules: æ–°å»ºé¡¹ç›®é»˜è®¤å¯ç”¨çš„æ¨¡å—
+  setting_issue_done_ratio: è®¡ç®—é—®é¢˜å®Œæˆåº¦ï¼š
+  setting_issue_done_ratio_issue_field: ä½¿ç”¨é—®é¢˜ï¼ˆçš„å®Œæˆåº¦ï¼‰å±žæ€§
+  setting_issue_done_ratio_issue_status: ä½¿ç”¨é—®é¢˜çŠ¶æ€
+  setting_start_of_week: æ—¥åŽ†å¼€å§‹äºŽ
+  setting_rest_api_enabled: å¯ç”¨REST web service
+  setting_cache_formatted_text: ç¼“å­˜æ ¼å¼åŒ–æ–‡å­—
+  setting_default_notification_option: é»˜è®¤æé†’é€‰é¡¹
+  setting_commit_logtime_enabled: æ¿€æ´»æ—¶é—´æ—¥å¿—
+  setting_commit_logtime_activity_id: è®°å½•çš„æ´»åŠ¨
+  setting_gantt_items_limit: åœ¨ç”˜ç‰¹å›¾ä¸Šæ˜¾ç¤ºçš„æœ€å¤§è®°å½•æ•°
+
+  permission_add_project: æ–°å»ºé¡¹ç›®
+  permission_add_subprojects: æ–°å»ºå­é¡¹ç›®
+  permission_edit_project: ç¼–è¾‘é¡¹ç›®
+  permission_select_project_modules: é€‰æ‹©é¡¹ç›®æ¨¡å—
+  permission_manage_members: ç®¡ç†æˆå‘˜
+  permission_manage_project_activities: ç®¡ç†é¡¹ç›®æ´»åŠ¨
+  permission_manage_versions: ç®¡ç†ç‰ˆæœ¬
+  permission_manage_categories: ç®¡ç†é—®é¢˜ç±»åˆ«
+  permission_view_issues: æŸ¥çœ‹é—®é¢˜
+  permission_add_issues: æ–°å»ºé—®é¢˜
+  permission_edit_issues: æ›´æ–°é—®é¢˜
+  permission_manage_issue_relations: ç®¡ç†é—®é¢˜å…³è”
+  permission_add_issue_notes: æ·»åŠ è¯´æ˜Ž
+  permission_edit_issue_notes: ç¼–è¾‘è¯´æ˜Ž
+  permission_edit_own_issue_notes: ç¼–è¾‘è‡ªå·±çš„è¯´æ˜Ž
+  permission_move_issues: ç§»åŠ¨é—®é¢˜
+  permission_delete_issues: åˆ é™¤é—®é¢˜
+  permission_manage_public_queries: ç®¡ç†å…¬å¼€çš„æŸ¥è¯¢
+  permission_save_queries: ä¿å­˜æŸ¥è¯¢
+  permission_view_gantt: æŸ¥çœ‹ç”˜ç‰¹å›¾
+  permission_view_calendar: æŸ¥çœ‹æ—¥åŽ†
+  permission_view_issue_watchers: æŸ¥çœ‹è·Ÿè¸ªè€…åˆ—è¡¨
+  permission_add_issue_watchers: æ·»åŠ è·Ÿè¸ªè€…
+  permission_delete_issue_watchers: åˆ é™¤è·Ÿè¸ªè€…
+  permission_log_time: ç™»è®°å·¥æ—¶
+  permission_view_time_entries: æŸ¥çœ‹è€—æ—¶
+  permission_edit_time_entries: ç¼–è¾‘è€—æ—¶
+  permission_edit_own_time_entries: ç¼–è¾‘è‡ªå·±çš„è€—æ—¶
+  permission_manage_news: ç®¡ç†æ–°é—»
+  permission_comment_news: ä¸ºæ–°é—»æ·»åŠ è¯„è®º
+  permission_view_documents: æŸ¥çœ‹æ–‡æ¡£
+  permission_manage_files: ç®¡ç†æ–‡ä»¶
+  permission_view_files: æŸ¥çœ‹æ–‡ä»¶
+  permission_manage_wiki: ç®¡ç†Wiki
+  permission_rename_wiki_pages: é‡å®šå‘/é‡å‘½åWikié¡µé¢
+  permission_delete_wiki_pages: åˆ é™¤Wikié¡µé¢
+  permission_view_wiki_pages: æŸ¥çœ‹Wiki
+  permission_view_wiki_edits: æŸ¥çœ‹WikiåŽ†å²è®°å½•
+  permission_edit_wiki_pages: ç¼–è¾‘Wikié¡µé¢
+  permission_delete_wiki_pages_attachments: åˆ é™¤é™„ä»¶
+  permission_protect_wiki_pages: ä¿æŠ¤Wikié¡µé¢
+  permission_manage_repository: ç®¡ç†ç‰ˆæœ¬åº“
+  permission_browse_repository: æµè§ˆç‰ˆæœ¬åº“
+  permission_view_changesets: æŸ¥çœ‹å˜æ›´
+  permission_commit_access: è®¿é—®æäº¤ä¿¡æ¯
+  permission_manage_boards: ç®¡ç†è®¨è®ºåŒº
+  permission_view_messages: æŸ¥çœ‹å¸–å­
+  permission_add_messages: å‘è¡¨å¸–å­
+  permission_edit_messages: ç¼–è¾‘å¸–å­
+  permission_edit_own_messages: ç¼–è¾‘è‡ªå·±çš„å¸–å­
+  permission_delete_messages: åˆ é™¤å¸–å­
+  permission_delete_own_messages: åˆ é™¤è‡ªå·±çš„å¸–å­
+  permission_export_wiki_pages: å¯¼å‡º wiki é¡µé¢
+  permission_manage_subtasks: ç®¡ç†å­ä»»åŠ¡
+
+  project_module_issue_tracking: é—®é¢˜è·Ÿè¸ª
+  project_module_time_tracking: æ—¶é—´è·Ÿè¸ª
+  project_module_news: æ–°é—»
+  project_module_documents: æ–‡æ¡£
+  project_module_files: æ–‡ä»¶
+  project_module_wiki: Wiki
+  project_module_repository: ç‰ˆæœ¬åº“
+  project_module_boards: è®¨è®ºåŒº
+  project_module_calendar: æ—¥åŽ†
+  project_module_gantt: ç”˜ç‰¹å›¾
+
+  label_user: ç”¨æˆ·
+  label_user_plural: ç”¨æˆ·
+  label_user_new: æ–°å»ºç”¨æˆ·
+  label_user_anonymous: åŒ¿åç”¨æˆ·
+  label_project: é¡¹ç›®
+  label_project_new: æ–°å»ºé¡¹ç›®
+  label_project_plural: é¡¹ç›®
+  label_x_projects:
+    zero:  æ— é¡¹ç›®
+    one:   1 ä¸ªé¡¹ç›®
+    other: "%{count} ä¸ªé¡¹ç›®"
+  label_project_all: æ‰€æœ‰çš„é¡¹ç›®
+  label_project_latest: æœ€è¿‘çš„é¡¹ç›®
+  label_issue: é—®é¢˜
+  label_issue_new: æ–°å»ºé—®é¢˜
+  label_issue_plural: é—®é¢˜
+  label_issue_view_all: æŸ¥çœ‹æ‰€æœ‰é—®é¢˜
+  label_issues_by: "æŒ‰ %{value} åˆ†ç»„æ˜¾ç¤ºé—®é¢˜"
+  label_issue_added: é—®é¢˜å·²æ·»åŠ 
+  label_issue_updated: é—®é¢˜å·²æ›´æ–°
+  label_document: æ–‡æ¡£
+  label_document_new: æ–°å»ºæ–‡æ¡£
+  label_document_plural: æ–‡æ¡£
+  label_document_added: æ–‡æ¡£å·²æ·»åŠ 
+  label_role: è§’è‰²
+  label_role_plural: è§’è‰²
+  label_role_new: æ–°å»ºè§’è‰²
+  label_role_and_permissions: è§’è‰²å’Œæƒé™
+  label_member: æˆå‘˜
+  label_member_new: æ–°å»ºæˆå‘˜
+  label_member_plural: æˆå‘˜
+  label_tracker: è·Ÿè¸ªæ ‡ç­¾
+  label_tracker_plural: è·Ÿè¸ªæ ‡ç­¾
+  label_tracker_new: æ–°å»ºè·Ÿè¸ªæ ‡ç­¾
+  label_workflow: å·¥ä½œæµç¨‹
+  label_issue_status: é—®é¢˜çŠ¶æ€
+  label_issue_status_plural: é—®é¢˜çŠ¶æ€
+  label_issue_status_new: æ–°å»ºé—®é¢˜çŠ¶æ€
+  label_issue_category: é—®é¢˜ç±»åˆ«
+  label_issue_category_plural: é—®é¢˜ç±»åˆ«
+  label_issue_category_new: æ–°å»ºé—®é¢˜ç±»åˆ«
+  label_custom_field: è‡ªå®šä¹‰å±žæ€§
+  label_custom_field_plural: è‡ªå®šä¹‰å±žæ€§
+  label_custom_field_new: æ–°å»ºè‡ªå®šä¹‰å±žæ€§
+  label_enumerations: æžšä¸¾å€¼
+  label_enumeration_new: æ–°å»ºæžšä¸¾å€¼
+  label_information: ä¿¡æ¯
+  label_information_plural: ä¿¡æ¯
+  label_please_login: è¯·ç™»å½•
+  label_register: æ³¨å†Œ
+  label_login_with_open_id_option: æˆ–ä½¿ç”¨OpenIDç™»å½•
+  label_password_lost: å¿˜è®°å¯†ç 
+  label_home: ä¸»é¡µ
+  label_my_page: æˆ‘çš„å·¥ä½œå°
+  label_my_account: æˆ‘çš„å¸å·
+  label_my_projects: æˆ‘çš„é¡¹ç›®
+  label_my_page_block: æˆ‘çš„å·¥ä½œå°æ¨¡å—
+  label_administration: ç®¡ç†
+  label_login: ç™»å½•
+  label_logout: é€€å‡º
+  label_help: å¸®åŠ©
+  label_reported_issues: å·²æŠ¥å‘Šçš„é—®é¢˜
+  label_assigned_to_me_issues: æŒ‡æ´¾ç»™æˆ‘çš„é—®é¢˜
+  label_last_login: æœ€åŽç™»å½•
+  label_registered_on: æ³¨å†ŒäºŽ
+  label_activity: æ´»åŠ¨
+  label_overall_activity: æ´»åŠ¨æ¦‚è§ˆ
+  label_user_activity: "%{value} çš„æ´»åŠ¨"
+  label_new: æ–°å»º
+  label_logged_as: ç™»å½•ä¸º
+  label_environment: çŽ¯å¢ƒ
+  label_authentication: è®¤è¯
+  label_auth_source: è®¤è¯æ¨¡å¼
+  label_auth_source_new: æ–°å»ºè®¤è¯æ¨¡å¼
+  label_auth_source_plural: è®¤è¯æ¨¡å¼
+  label_subproject_plural: å­é¡¹ç›®
+  label_subproject_new: æ–°å»ºå­é¡¹ç›®
+  label_and_its_subprojects: "%{value} åŠå…¶å­é¡¹ç›®"
+  label_min_max_length: æœ€å° - æœ€å¤§ é•¿åº¦
+  label_list: åˆ—è¡¨
+  label_date: æ—¥æœŸ
+  label_integer: æ•´æ•°
+  label_float: æµ®ç‚¹æ•°
+  label_boolean: å¸ƒå°”å€¼
+  label_string: å­—ç¬¦ä¸²
+  label_text: æ–‡æœ¬
+  label_attribute: å±žæ€§
+  label_attribute_plural: å±žæ€§
+  label_no_data: æ²¡æœ‰ä»»ä½•æ•°æ®å¯ä¾›æ˜¾ç¤º
+  label_change_status: å˜æ›´çŠ¶æ€
+  label_history: åŽ†å²è®°å½•
+  label_attachment: æ–‡ä»¶
+  label_attachment_new: æ–°å»ºæ–‡ä»¶
+  label_attachment_delete: åˆ é™¤æ–‡ä»¶
+  label_attachment_plural: æ–‡ä»¶
+  label_file_added: æ–‡ä»¶å·²æ·»åŠ 
+  label_report: æŠ¥è¡¨
+  label_report_plural: æŠ¥è¡¨
+  label_news: æ–°é—»
+  label_news_new: æ·»åŠ æ–°é—»
+  label_news_plural: æ–°é—»
+  label_news_latest: æœ€è¿‘çš„æ–°é—»
+  label_news_view_all: æŸ¥çœ‹æ‰€æœ‰æ–°é—»
+  label_news_added: æ–°é—»å·²æ·»åŠ 
+  label_settings: é…ç½®
+  label_overview: æ¦‚è¿°
+  label_version: ç‰ˆæœ¬
+  label_version_new: æ–°å»ºç‰ˆæœ¬
+  label_version_plural: ç‰ˆæœ¬
+  label_close_versions: å…³é—­å·²å®Œæˆçš„ç‰ˆæœ¬
+  label_confirmation: ç¡®è®¤
+  label_export_to: å¯¼å‡º
+  label_read: è¯»å–...
+  label_public_projects: å…¬å¼€çš„é¡¹ç›®
+  label_open_issues: æ‰“å¼€
+  label_open_issues_plural: æ‰“å¼€
+  label_closed_issues: å·²å…³é—­
+  label_closed_issues_plural: å·²å…³é—­
+  label_x_open_issues_abbr_on_total:
+    zero:  0 æ‰“å¼€ / %{total}
+    one:   1 æ‰“å¼€ / %{total}
+    other: "%{count} æ‰“å¼€ / %{total}"
+  label_x_open_issues_abbr:
+    zero:  0 æ‰“å¼€
+    one:   1 æ‰“å¼€
+    other: "%{count} æ‰“å¼€"
+  label_x_closed_issues_abbr:
+    zero:  0 å·²å…³é—­
+    one:   1 å·²å…³é—­
+    other: "%{count} å·²å…³é—­"
+  label_total: åˆè®¡
+  label_permissions: æƒé™
+  label_current_status: å½“å‰çŠ¶æ€
+  label_new_statuses_allowed: å…è®¸çš„æ–°çŠ¶æ€
+  label_all: å…¨éƒ¨
+  label_none: æ— 
+  label_nobody: æ— äºº
+  label_next: ä¸‹ä¸€é¡µ
+  label_previous: ä¸Šä¸€é¡µ
+  label_used_by: ä½¿ç”¨ä¸­
+  label_details: è¯¦æƒ…
+  label_add_note: æ·»åŠ è¯´æ˜Ž
+  label_per_page: æ¯é¡µ
+  label_calendar: æ—¥åŽ†
+  label_months_from: ä¸ªæœˆä»¥æ¥
+  label_gantt: ç”˜ç‰¹å›¾
+  label_internal: å†…éƒ¨
+  label_last_changes: "æœ€è¿‘çš„ %{count} æ¬¡å˜æ›´"
+  label_change_view_all: æŸ¥çœ‹æ‰€æœ‰å˜æ›´
+  label_personalize_page: ä¸ªæ€§åŒ–å®šåˆ¶æœ¬é¡µ
+  label_comment: è¯„è®º
+  label_comment_plural: è¯„è®º
+  label_x_comments:
+    zero: æ— è¯„è®º
+    one: 1 æ¡è¯„è®º
+    other: "%{count} æ¡è¯„è®º"
+  label_comment_add: æ·»åŠ è¯„è®º
+  label_comment_added: è¯„è®ºå·²æ·»åŠ 
+  label_comment_delete: åˆ é™¤è¯„è®º
+  label_query: è‡ªå®šä¹‰æŸ¥è¯¢
+  label_query_plural: è‡ªå®šä¹‰æŸ¥è¯¢
+  label_query_new: æ–°å»ºæŸ¥è¯¢
+  label_filter_add: å¢žåŠ è¿‡æ»¤å™¨
+  label_filter_plural: è¿‡æ»¤å™¨
+  label_equals: ç­‰äºŽ
+  label_not_equals: ä¸ç­‰äºŽ
+  label_in_less_than: å‰©ä½™å¤©æ•°å°äºŽ
+  label_in_more_than: å‰©ä½™å¤©æ•°å¤§äºŽ
+  label_greater_or_equal: '>='
+  label_less_or_equal: '<='
+  label_in: å‰©ä½™å¤©æ•°
+  label_today: ä»Šå¤©
+  label_all_time: å…¨éƒ¨æ—¶é—´
+  label_yesterday: æ˜¨å¤©
+  label_this_week: æœ¬å‘¨
+  label_last_week: ä¸Šå‘¨
+  label_last_n_days: "æœ€åŽ %{count} å¤©"
+  label_this_month: æœ¬æœˆ
+  label_last_month: ä¸Šæœˆ
+  label_this_year: ä»Šå¹´
+  label_date_range: æ—¥æœŸèŒƒå›´
+  label_less_than_ago: ä¹‹å‰å¤©æ•°å°‘äºŽ
+  label_more_than_ago: ä¹‹å‰å¤©æ•°å¤§äºŽ
+  label_ago: ä¹‹å‰å¤©æ•°
+  label_contains: åŒ…å«
+  label_not_contains: ä¸åŒ…å«
+  label_day_plural: å¤©
+  label_repository: ç‰ˆæœ¬åº“
+  label_repository_plural: ç‰ˆæœ¬åº“
+  label_browse: æµè§ˆ
+  label_branch: åˆ†æ”¯
+  label_tag: æ ‡ç­¾
+  label_revision: ä¿®è®¢
+  label_revision_plural: ä¿®è®¢
+  label_revision_id: ä¿®è®¢ %{value}
+  label_associated_revisions: ç›¸å…³ä¿®è®¢ç‰ˆæœ¬
+  label_added: å·²æ·»åŠ 
+  label_modified: å·²ä¿®æ”¹
+  label_copied: å·²å¤åˆ¶
+  label_renamed: å·²é‡å‘½å
+  label_deleted: å·²åˆ é™¤
+  label_latest_revision: æœ€è¿‘çš„ä¿®è®¢ç‰ˆæœ¬
+  label_latest_revision_plural: æœ€è¿‘çš„ä¿®è®¢ç‰ˆæœ¬
+  label_view_revisions: æŸ¥çœ‹ä¿®è®¢
+  label_view_all_revisions: æŸ¥çœ‹æ‰€æœ‰ä¿®è®¢
+  label_max_size: æœ€å¤§å°ºå¯¸
+  label_sort_highest: ç½®é¡¶
+  label_sort_higher: ä¸Šç§»
+  label_sort_lower: ä¸‹ç§»
+  label_sort_lowest: ç½®åº•
+  label_roadmap: è·¯çº¿å›¾
+  label_roadmap_due_in: "æˆªæ­¢æ—¥æœŸåˆ°  %{value}"
+  label_roadmap_overdue: "%{value} å»¶æœŸ"
+  label_roadmap_no_issues: è¯¥ç‰ˆæœ¬æ²¡æœ‰é—®é¢˜
+  label_search: æœç´¢
+  label_result_plural: ç»“æžœ
+  label_all_words: æ‰€æœ‰å•è¯
+  label_wiki: Wiki
+  label_wiki_edit: Wiki ç¼–è¾‘
+  label_wiki_edit_plural: Wiki ç¼–è¾‘è®°å½•
+  label_wiki_page: Wiki é¡µé¢
+  label_wiki_page_plural: Wiki é¡µé¢
+  label_index_by_title: æŒ‰æ ‡é¢˜ç´¢å¼•
+  label_index_by_date: æŒ‰æ—¥æœŸç´¢å¼•
+  label_current_version: å½“å‰ç‰ˆæœ¬
+  label_preview: é¢„è§ˆ
+  label_feed_plural: Feeds
+  label_changes_details: æ‰€æœ‰å˜æ›´çš„è¯¦æƒ…
+  label_issue_tracking: é—®é¢˜è·Ÿè¸ª
+  label_spent_time: è€—æ—¶
+  label_overall_spent_time: æ€»ä½“è€—æ—¶
+  label_f_hour: "%{value} å°æ—¶"
+  label_f_hour_plural: "%{value} å°æ—¶"
+  label_time_tracking: æ—¶é—´è·Ÿè¸ª
+  label_change_plural: å˜æ›´
+  label_statistics: ç»Ÿè®¡
+  label_commits_per_month: æ¯æœˆæäº¤æ¬¡æ•°
+  label_commits_per_author: æ¯ç”¨æˆ·æäº¤æ¬¡æ•°
+  label_view_diff: æŸ¥çœ‹å·®åˆ«
+  label_diff_inline: ç›´åˆ—
+  label_diff_side_by_side: å¹¶æŽ’
+  label_options: é€‰é¡¹
+  label_copy_workflow_from: ä»Žä»¥ä¸‹é€‰é¡¹å¤åˆ¶å·¥ä½œæµç¨‹
+  label_permissions_report: æƒé™æŠ¥è¡¨
+  label_watched_issues: è·Ÿè¸ªçš„é—®é¢˜
+  label_related_issues: ç›¸å…³çš„é—®é¢˜
+  label_applied_status: åº”ç”¨åŽçš„çŠ¶æ€
+  label_loading: è½½å…¥ä¸­...
+  label_relation_new: æ–°å»ºå…³è”
+  label_relation_delete: åˆ é™¤å…³è”
+  label_relates_to: å…³è”åˆ°
+  label_duplicates: é‡å¤
+  label_duplicated_by: ä¸Žå…¶é‡å¤
+  label_blocks: é˜»æŒ¡
+  label_blocked_by: è¢«é˜»æŒ¡
+  label_precedes: ä¼˜å…ˆäºŽ
+  label_follows: è·ŸéšäºŽ
+  label_end_to_start: ç»“æŸ-å¼€å§‹
+  label_end_to_end: ç»“æŸ-ç»“æŸ
+  label_start_to_start: å¼€å§‹-å¼€å§‹
+  label_start_to_end: å¼€å§‹-ç»“æŸ
+  label_stay_logged_in: ä¿æŒç™»å½•çŠ¶æ€
+  label_disabled: ç¦ç”¨
+  label_show_completed_versions: æ˜¾ç¤ºå·²å®Œæˆçš„ç‰ˆæœ¬
+  label_me: æˆ‘
+  label_board: è®¨è®ºåŒº
+  label_board_new: æ–°å»ºè®¨è®ºåŒº
+  label_board_plural: è®¨è®ºåŒº
+  label_board_locked: é”å®š
+  label_board_sticky: ç½®é¡¶
+  label_topic_plural: ä¸»é¢˜
+  label_message_plural: å¸–å­
+  label_message_last: æœ€æ–°çš„å¸–å­
+  label_message_new: æ–°è´´
+  label_message_posted: å‘å¸–æˆåŠŸ
+  label_reply_plural: å›žå¤
+  label_send_information: ç»™ç”¨æˆ·å‘é€å¸å·ä¿¡æ¯
+  label_year: å¹´
+  label_month: æœˆ
+  label_week: å‘¨
+  label_date_from: ä»Ž
+  label_date_to: åˆ°
+  label_language_based: æ ¹æ®ç”¨æˆ·çš„è¯­è¨€
+  label_sort_by: "æ ¹æ® %{value} æŽ’åº"
+  label_send_test_email: å‘é€æµ‹è¯•é‚®ä»¶
+  label_feeds_access_key: RSSå­˜å–é”®
+  label_missing_feeds_access_key: ç¼ºå°‘RSSå­˜å–é”®
+  label_feeds_access_key_created_on: "RSSå­˜å–é”®æ˜¯åœ¨ %{value} ä¹‹å‰å»ºç«‹çš„"
+  label_module_plural: æ¨¡å—
+  label_added_time_by: "ç”± %{author} åœ¨ %{age} ä¹‹å‰æ·»åŠ "
+  label_updated_time: " æ›´æ–°äºŽ %{value} ä¹‹å‰"
+  label_updated_time_by: "ç”± %{author} æ›´æ–°äºŽ %{age} ä¹‹å‰"
+  label_jump_to_a_project: é€‰æ‹©ä¸€ä¸ªé¡¹ç›®...
+  label_file_plural: æ–‡ä»¶
+  label_changeset_plural: å˜æ›´
+  label_default_columns: é»˜è®¤åˆ—
+  label_no_change_option: (ä¸å˜)
+  label_bulk_edit_selected_issues: æ‰¹é‡ä¿®æ”¹é€‰ä¸­çš„é—®é¢˜
+  label_theme: ä¸»é¢˜
+  label_default: é»˜è®¤
+  label_search_titles_only: ä»…åœ¨æ ‡é¢˜ä¸­æœç´¢
+  label_user_mail_option_all: "æ”¶å–æˆ‘çš„é¡¹ç›®çš„æ‰€æœ‰é€šçŸ¥"
+  label_user_mail_option_selected: "æ”¶å–é€‰ä¸­é¡¹ç›®çš„æ‰€æœ‰é€šçŸ¥..."
+  label_user_mail_option_none: "ä¸æ”¶å–ä»»ä½•é€šçŸ¥"
+  label_user_mail_option_only_my_events: "åªæ”¶å–æˆ‘è·Ÿè¸ªæˆ–å‚ä¸Žçš„é¡¹ç›®çš„é€šçŸ¥"
+  label_user_mail_option_only_assigned: "åªæ”¶å–åˆ†é…ç»™æˆ‘çš„"
+  label_user_mail_option_only_owner: åªæ”¶å–ç”±æˆ‘åˆ›å»ºçš„
+  label_user_mail_no_self_notified: "ä¸è¦å‘é€å¯¹æˆ‘è‡ªå·±æäº¤çš„ä¿®æ”¹çš„é€šçŸ¥"
+  label_registration_activation_by_email: é€šè¿‡é‚®ä»¶è®¤è¯æ¿€æ´»å¸å·
+  label_registration_manual_activation: æ‰‹åŠ¨æ¿€æ´»å¸å·
+  label_registration_automatic_activation: è‡ªåŠ¨æ¿€æ´»å¸å·
+  label_display_per_page: "æ¯é¡µæ˜¾ç¤ºï¼š%{value}"
+  label_age: æäº¤æ—¶é—´
+  label_change_properties: ä¿®æ”¹å±žæ€§
+  label_general: ä¸€èˆ¬
+  label_more: æ›´å¤š
+  label_scm: SCM
+  label_plugins: æ’ä»¶
+  label_ldap_authentication: LDAP è®¤è¯
+  label_downloads_abbr: D/L
+  label_optional_description: å¯é€‰çš„æè¿°
+  label_add_another_file: æ·»åŠ å…¶å®ƒæ–‡ä»¶
+  label_preferences: é¦–é€‰é¡¹
+  label_chronological_order: æŒ‰æ—¶é—´é¡ºåº
+  label_reverse_chronological_order: æŒ‰æ—¶é—´é¡ºåºï¼ˆå€’åºï¼‰
+  label_planning: è®¡åˆ’
+  label_incoming_emails: æŽ¥æ”¶é‚®ä»¶
+  label_generate_key: ç”Ÿæˆä¸€ä¸ªkey
+  label_issue_watchers: è·Ÿè¸ªè€…
+  label_example: ç¤ºä¾‹
+  label_display: æ˜¾ç¤º
+  label_sort: æŽ’åº
+  label_ascending: å‡åº
+  label_descending: é™åº
+  label_date_from_to: ä»Ž %{start} åˆ° %{end}
+  label_wiki_content_added: Wiki é¡µé¢å·²æ·»åŠ 
+  label_wiki_content_updated: Wiki é¡µé¢å·²æ›´æ–°
+  label_group: ç»„
+  label_group_plural: ç»„
+  label_group_new: æ–°å»ºç»„
+  label_time_entry_plural: è€—æ—¶
+  label_version_sharing_none: ä¸å…±äº«
+  label_version_sharing_descendants: ä¸Žå­é¡¹ç›®å…±äº«
+  label_version_sharing_hierarchy: ä¸Žé¡¹ç›®ç»§æ‰¿å±‚æ¬¡å…±äº«
+  label_version_sharing_tree: ä¸Žé¡¹ç›®æ ‘å…±äº«
+  label_version_sharing_system: ä¸Žæ‰€æœ‰é¡¹ç›®å…±äº«
+  label_update_issue_done_ratios: æ›´æ–°é—®é¢˜çš„å®Œæˆåº¦
+  label_copy_source: æº
+  label_copy_target: ç›®æ ‡
+  label_copy_same_as_target: ä¸Žç›®æ ‡ä¸€è‡´
+  label_display_used_statuses_only: åªæ˜¾ç¤ºè¢«æ­¤è·Ÿè¸ªæ ‡ç­¾ä½¿ç”¨çš„çŠ¶æ€
+  label_api_access_key: APIè®¿é—®é”®
+  label_missing_api_access_key: ç¼ºå°‘APIè®¿é—®é”®
+  label_api_access_key_created_on: APIè®¿é—®é”®æ˜¯åœ¨ %{value} ä¹‹å‰å»ºç«‹çš„
+  label_profile: ç®€ä»‹
+  label_subtask_plural: å­ä»»åŠ¡
+  label_project_copy_notifications: å¤åˆ¶é¡¹ç›®æ—¶å‘é€é‚®ä»¶é€šçŸ¥
+  label_principal_search: "æœç´¢ç”¨æˆ·æˆ–ç»„ï¼š"
+  label_user_search: "æœç´¢ç”¨æˆ·ï¼š"
+
+  button_login: ç™»å½•
+  button_submit: æäº¤
+  button_save: ä¿å­˜
+  button_check_all: å…¨é€‰
+  button_uncheck_all: æ¸…é™¤
+  button_delete: åˆ é™¤
+  button_create: åˆ›å»º
+  button_create_and_continue: åˆ›å»ºå¹¶ç»§ç»­
+  button_test: æµ‹è¯•
+  button_edit: ç¼–è¾‘
+  button_edit_associated_wikipage: "ç¼–è¾‘ç›¸å…³wikié¡µé¢: %{page_title}"
+  button_add: æ–°å¢ž
+  button_change: ä¿®æ”¹
+  button_apply: åº”ç”¨
+  button_clear: æ¸…é™¤
+  button_lock: é”å®š
+  button_unlock: è§£é”
+  button_download: ä¸‹è½½
+  button_list: åˆ—è¡¨
+  button_view: æŸ¥çœ‹
+  button_move: ç§»åŠ¨
+  button_move_and_follow: ç§»åŠ¨å¹¶è½¬åˆ°æ–°é—®é¢˜
+  button_back: è¿”å›ž
+  button_cancel: å–æ¶ˆ
+  button_activate: æ¿€æ´»
+  button_sort: æŽ’åº
+  button_log_time: ç™»è®°å·¥æ—¶
+  button_rollback: æ¢å¤åˆ°è¿™ä¸ªç‰ˆæœ¬
+  button_watch: è·Ÿè¸ª
+  button_unwatch: å–æ¶ˆè·Ÿè¸ª
+  button_reply: å›žå¤
+  button_archive: å­˜æ¡£
+  button_unarchive: å–æ¶ˆå­˜æ¡£
+  button_reset: é‡ç½®
+  button_rename: é‡å‘½å/é‡å®šå‘
+  button_change_password: ä¿®æ”¹å¯†ç 
+  button_copy: å¤åˆ¶
+  button_copy_and_follow: å¤åˆ¶å¹¶è½¬åˆ°æ–°é—®é¢˜
+  button_annotate: è¿½æº¯
+  button_update: æ›´æ–°
+  button_configure: é…ç½®
+  button_quote: å¼•ç”¨
+  button_duplicate: å‰¯æœ¬
+  button_show: æ˜¾ç¤º
+
+  status_active: æ´»åŠ¨çš„
+  status_registered: å·²æ³¨å†Œ
+  status_locked: å·²é”å®š
+
+  version_status_open: æ‰“å¼€
+  version_status_locked: é”å®š
+  version_status_closed: å…³é—­
+
+  field_active: æ´»åŠ¨
+
+  text_select_mail_notifications: é€‰æ‹©éœ€è¦å‘é€é‚®ä»¶é€šçŸ¥çš„åŠ¨ä½œ
+  text_regexp_info: ä¾‹å¦‚ï¼š^[A-Z0-9]+$
+  text_min_max_length_info: 0 è¡¨ç¤ºæ²¡æœ‰é™åˆ¶
+  text_project_destroy_confirmation: æ‚¨ç¡®ä¿¡è¦åˆ é™¤è¿™ä¸ªé¡¹ç›®ä»¥åŠæ‰€æœ‰ç›¸å…³çš„æ•°æ®å—ï¼Ÿ
+  text_subprojects_destroy_warning: "ä»¥ä¸‹å­é¡¹ç›®ä¹Ÿå°†è¢«åŒæ—¶åˆ é™¤ï¼š%{value}"
+  text_workflow_edit: é€‰æ‹©è§’è‰²å’Œè·Ÿè¸ªæ ‡ç­¾æ¥ç¼–è¾‘å·¥ä½œæµç¨‹
+  text_are_you_sure: æ‚¨ç¡®å®šï¼Ÿ
+  text_journal_changed: "%{label} ä»Ž %{old} å˜æ›´ä¸º %{new}"
+  text_journal_set_to: "%{label} è¢«è®¾ç½®ä¸º %{value}"
+  text_journal_deleted: "%{label} å·²åˆ é™¤ (%{old})"
+  text_journal_added: "%{label} %{value} å·²æ·»åŠ "
+  text_tip_issue_begin_day: ä»Šå¤©å¼€å§‹çš„ä»»åŠ¡
+  text_tip_issue_end_day: ä»Šå¤©ç»“æŸçš„ä»»åŠ¡
+  text_tip_issue_begin_end_day: ä»Šå¤©å¼€å§‹å¹¶ç»“æŸçš„ä»»åŠ¡
+  text_caracters_maximum: "æœ€å¤š %{count} ä¸ªå­—ç¬¦ã€‚"
+  text_caracters_minimum: "è‡³å°‘éœ€è¦ %{count} ä¸ªå­—ç¬¦ã€‚"
+  text_length_between: "é•¿åº¦å¿…é¡»åœ¨ %{min} åˆ° %{max} ä¸ªå­—ç¬¦ä¹‹é—´ã€‚"
+  text_tracker_no_workflow: æ­¤è·Ÿè¸ªæ ‡ç­¾æœªå®šä¹‰å·¥ä½œæµç¨‹
+  text_unallowed_characters: éžæ³•å­—ç¬¦
+  text_comma_separated: å¯ä»¥ä½¿ç”¨å¤šä¸ªå€¼ï¼ˆç”¨é€—å·,åˆ†å¼€ï¼‰ã€‚
+  text_line_separated: å¯ä»¥ä½¿ç”¨å¤šä¸ªå€¼ï¼ˆæ¯è¡Œä¸€ä¸ªå€¼ï¼‰ã€‚
+  text_issues_ref_in_commit_messages: åœ¨æäº¤ä¿¡æ¯ä¸­å¼•ç”¨å’Œè§£å†³é—®é¢˜
+  text_issue_added: "é—®é¢˜ %{id} å·²ç”± %{author} æäº¤ã€‚"
+  text_issue_updated: "é—®é¢˜ %{id} å·²ç”± %{author} æ›´æ–°ã€‚"
+  text_wiki_destroy_confirmation: æ‚¨ç¡®å®šè¦åˆ é™¤è¿™ä¸ª wiki åŠå…¶æ‰€æœ‰å†…å®¹å—ï¼Ÿ
+  text_issue_category_destroy_question: "æœ‰ä¸€äº›é—®é¢˜ï¼ˆ%{count} ä¸ªï¼‰å±žäºŽæ­¤ç±»åˆ«ã€‚æ‚¨æƒ³è¿›è¡Œå“ªç§æ“ä½œï¼Ÿ"
+  text_issue_category_destroy_assignments: åˆ é™¤é—®é¢˜çš„æ‰€å±žç±»åˆ«ï¼ˆé—®é¢˜å˜ä¸ºæ— ç±»åˆ«ï¼‰
+  text_issue_category_reassign_to: ä¸ºé—®é¢˜é€‰æ‹©å…¶å®ƒç±»åˆ«
+  text_user_mail_option: "å¯¹äºŽæ²¡æœ‰é€‰ä¸­çš„é¡¹ç›®ï¼Œæ‚¨å°†åªä¼šæ”¶åˆ°æ‚¨è·Ÿè¸ªæˆ–å‚ä¸Žçš„é¡¹ç›®çš„é€šçŸ¥ï¼ˆæ¯”å¦‚è¯´ï¼Œæ‚¨æ˜¯é—®é¢˜çš„æŠ¥å‘Šè€…, æˆ–è¢«æŒ‡æ´¾è§£å†³æ­¤é—®é¢˜ï¼‰ã€‚"
+  text_no_configuration_data: "è§’è‰²ã€è·Ÿè¸ªæ ‡ç­¾ã€é—®é¢˜çŠ¶æ€å’Œå·¥ä½œæµç¨‹è¿˜æ²¡æœ‰è®¾ç½®ã€‚\nå¼ºçƒˆå»ºè®®æ‚¨å…ˆè½½å…¥é»˜è®¤è®¾ç½®ï¼Œç„¶åŽåœ¨æ­¤åŸºç¡€ä¸Šè¿›è¡Œä¿®æ”¹ã€‚"
+  text_load_default_configuration: è½½å…¥é»˜è®¤è®¾ç½®
+  text_status_changed_by_changeset: "å·²åº”ç”¨åˆ°å˜æ›´åˆ—è¡¨ %{value}."
+  text_time_logged_by_changeset: "å·²åº”ç”¨åˆ°ä¿®è®¢ç‰ˆæœ¬ %{value}."
+  text_issues_destroy_confirmation: 'æ‚¨ç¡®å®šè¦åˆ é™¤é€‰ä¸­çš„é—®é¢˜å—ï¼Ÿ'
+  text_select_project_modules: 'è¯·é€‰æ‹©æ­¤é¡¹ç›®å¯ä»¥ä½¿ç”¨çš„æ¨¡å—ï¼š'
+  text_default_administrator_account_changed: é»˜è®¤çš„ç®¡ç†å‘˜å¸å·å·²æ”¹å˜
+  text_file_repository_writable: é™„ä»¶è·¯å¾„å¯å†™
+  text_plugin_assets_writable: æ’ä»¶çš„é™„ä»¶è·¯å¾„å¯å†™
+  text_rmagick_available: RMagick å¯ç”¨ï¼ˆå¯é€‰çš„ï¼‰
+  text_destroy_time_entries_question: æ‚¨è¦åˆ é™¤çš„é—®é¢˜å·²ç»ä¸ŠæŠ¥äº† %{hours} å°æ—¶çš„å·¥ä½œé‡ã€‚æ‚¨æƒ³è¿›è¡Œé‚£ç§æ“ä½œï¼Ÿ
+  text_destroy_time_entries: åˆ é™¤ä¸ŠæŠ¥çš„å·¥ä½œé‡
+  text_assign_time_entries_to_project: å°†å·²ä¸ŠæŠ¥çš„å·¥ä½œé‡æäº¤åˆ°é¡¹ç›®ä¸­
+  text_reassign_time_entries: 'å°†å·²ä¸ŠæŠ¥çš„å·¥ä½œé‡æŒ‡å®šåˆ°æ­¤é—®é¢˜ï¼š'
+  text_user_wrote: "%{value} å†™åˆ°ï¼š"
+  text_enumeration_destroy_question: "%{count} ä¸ªå¯¹è±¡è¢«å…³è”åˆ°äº†è¿™ä¸ªæžšä¸¾å€¼ã€‚"
+  text_enumeration_category_reassign_to: 'å°†å®ƒä»¬å…³è”åˆ°æ–°çš„æžšä¸¾å€¼ï¼š'
+  text_email_delivery_not_configured: "é‚®ä»¶å‚æ•°å°šæœªé…ç½®ï¼Œå› æ­¤é‚®ä»¶é€šçŸ¥åŠŸèƒ½å·²è¢«ç¦ç”¨ã€‚\nè¯·åœ¨config/configuration.ymlä¸­é…ç½®æ‚¨çš„SMTPæœåŠ¡å™¨ä¿¡æ¯å¹¶é‡æ–°å¯åŠ¨ä»¥ä½¿å…¶ç”Ÿæ•ˆã€‚"
+  text_repository_usernames_mapping: "é€‰æ‹©æˆ–æ›´æ–°ä¸Žç‰ˆæœ¬åº“ä¸­çš„ç”¨æˆ·åå¯¹åº”çš„Redmineç”¨æˆ·ã€‚\nç‰ˆæœ¬åº“ä¸­ä¸ŽRedmineä¸­çš„åŒåç”¨æˆ·å°†è¢«è‡ªåŠ¨å¯¹åº”ã€‚"
+  text_diff_truncated: '... å·®åˆ«å†…å®¹è¶…è¿‡äº†å¯æ˜¾ç¤ºçš„æœ€å¤§è¡Œæ•°å¹¶å·²è¢«æˆªæ–­'
+  text_custom_field_possible_values_info: 'æ¯é¡¹æ•°å€¼ä¸€è¡Œ'
+  text_wiki_page_destroy_question: æ­¤é¡µé¢æœ‰ %{descendants} ä¸ªå­é¡µé¢å’Œä¸‹çº§é¡µé¢ã€‚æ‚¨æƒ³è¿›è¡Œé‚£ç§æ“ä½œï¼Ÿ
+  text_wiki_page_nullify_children: å°†å­é¡µé¢ä¿ç•™ä¸ºæ ¹é¡µé¢
+  text_wiki_page_destroy_children: åˆ é™¤å­é¡µé¢åŠå…¶æ‰€æœ‰ä¸‹çº§é¡µé¢
+  text_wiki_page_reassign_children: å°†å­é¡µé¢çš„ä¸Šçº§é¡µé¢è®¾ç½®ä¸º
+  text_own_membership_delete_confirmation: ä½ æ­£åœ¨åˆ é™¤ä½ çŽ°æœ‰çš„æŸäº›æˆ–å…¨éƒ¨æƒé™ï¼Œå¦‚æžœè¿™æ ·åšäº†ä½ å¯èƒ½å°†ä¼šå†ä¹Ÿæ— æ³•ç¼–è¾‘è¯¥é¡¹ç›®äº†ã€‚ä½ ç¡®å®šè¦ç»§ç»­å—ï¼Ÿ
+  text_zoom_in: æ”¾å¤§
+  text_zoom_out: ç¼©å°
+
+  default_role_manager: ç®¡ç†äººå‘˜
+  default_role_developer: å¼€å‘äººå‘˜
+  default_role_reporter: æŠ¥å‘Šäººå‘˜
+  default_tracker_bug: é”™è¯¯
+  default_tracker_feature: åŠŸèƒ½
+  default_tracker_support: æ”¯æŒ
+  default_issue_status_new: æ–°å»º
+  default_issue_status_in_progress: è¿›è¡Œä¸­
+  default_issue_status_resolved: å·²è§£å†³
+  default_issue_status_feedback: åé¦ˆ
+  default_issue_status_closed: å·²å…³é—­
+  default_issue_status_rejected: å·²æ‹’ç»
+  default_doc_category_user: ç”¨æˆ·æ–‡æ¡£
+  default_doc_category_tech: æŠ€æœ¯æ–‡æ¡£
+  default_priority_low: ä½Ž
+  default_priority_normal: æ™®é€š
+  default_priority_high: é«˜
+  default_priority_urgent: ç´§æ€¥
+  default_priority_immediate: ç«‹åˆ»
+  default_activity_design: è®¾è®¡
+  default_activity_development: å¼€å‘
+
+  enumeration_issue_priorities: é—®é¢˜ä¼˜å…ˆçº§
+  enumeration_doc_categories: æ–‡æ¡£ç±»åˆ«
+  enumeration_activities: æ´»åŠ¨ï¼ˆæ—¶é—´è·Ÿè¸ªï¼‰
+  enumeration_system_activity: ç³»ç»Ÿæ´»åŠ¨
+
+  field_warn_on_leaving_unsaved: å½“ç¦»å¼€æœªä¿å­˜å†…å®¹çš„é¡µé¢æ—¶ï¼Œæç¤ºæˆ‘
+  text_warn_on_leaving_unsaved: è‹¥ç¦»å¼€å½“å‰é¡µé¢ï¼Œåˆ™è¯¥é¡µé¢å†…æœªä¿å­˜çš„å†…å®¹å°†ä¸¢å¤±ã€‚
+  label_my_queries: æˆ‘çš„è‡ªå®šä¹‰æŸ¥è¯¢
+  text_journal_changed_no_detail: "%{label} å·²æ›´æ–°ã€‚"
+  label_news_comment_added: æ·»åŠ åˆ°æ–°é—»çš„è¯„è®º
+  button_expand_all: å±•å¼€æ‰€æœ‰
+  button_collapse_all: åˆæ‹¢æ‰€æœ‰
+  label_additional_workflow_transitions_for_assignee: å½“ç”¨æˆ·æ˜¯é—®é¢˜çš„åˆ†é…å¯¹è±¡æ—¶æ‰€å…è®¸çš„é—®é¢˜çŠ¶æ€è½¬æ¢
+  label_additional_workflow_transitions_for_author: å½“ç”¨æˆ·æ˜¯é—®é¢˜ä½œè€…æ—¶æ‰€å…è®¸çš„é—®é¢˜çŠ¶æ€è½¬æ¢
+  label_bulk_edit_selected_time_entries: æ‰¹é‡ä¿®æ”¹é€‰å®šçš„æ—¶é—´æ¡ç›®
+  text_time_entries_destroy_confirmation: æ˜¯å¦ç¡®å®šè¦åˆ é™¤é€‰å®šçš„æ—¶é—´æ¡ç›®ï¼Ÿ
+  label_role_anonymous: Anonymous
+  label_role_non_member: Non member
+  label_issue_note_added: é—®é¢˜å¤‡æ³¨å·²æ·»åŠ 
+  label_issue_status_updated: é—®é¢˜çŠ¶æ€æ›´æ–°
+  label_issue_priority_updated: é—®é¢˜ä¼˜å…ˆçº§æ›´æ–°
+  label_issues_visibility_own: åˆ›å»ºæˆ–åˆ†é…ç»™ç”¨æˆ·çš„é—®é¢˜
+  field_issues_visibility: é—®é¢˜å¯è§
+  label_issues_visibility_all: å…¨éƒ¨é—®é¢˜
+  permission_set_own_issues_private: è®¾ç½®è‡ªå·±çš„é—®é¢˜ä¸ºå…¬å¼€æˆ–ç§æœ‰
+  field_is_private: ç§æœ‰
+  permission_set_issues_private: è®¾ç½®é—®é¢˜ä¸ºå…¬å¼€æˆ–ç§æœ‰
+  label_issues_visibility_public: å…¨éƒ¨éžç§æœ‰é—®é¢˜
+  text_issues_destroy_descendants_confirmation: æ­¤æ“ä½œåŒæ—¶ä¼šåˆ é™¤ %{count} ä¸ªå­ä»»åŠ¡ã€‚
+
+  field_commit_logs_encoding: æäº¤æ³¨é‡Šçš„ç¼–ç 
+  field_scm_path_encoding: è·¯å¾„ç¼–ç 
+  text_scm_path_encoding_note: "é»˜è®¤: UTF-8"
+  field_path_to_repository: åº“è·¯å¾„
+  field_root_directory: æ ¹ç›®å½•
+  field_cvs_module: CVS Module
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: æœ¬åœ°åº“ (e.g. /hgrepo, c:\hgrepo)
+  text_scm_command: å‘½ä»¤
+  text_scm_command_version: ç‰ˆæœ¬
+  label_git_report_last_commit: æŠ¥å‘Šæœ€åŽä¸€æ¬¡æ–‡ä»¶/ç›®å½•æäº¤
+  text_scm_config: æ‚¨å¯ä»¥åœ¨config/configuration.ymlä¸­é…ç½®æ‚¨çš„SCMå‘½ä»¤ã€‚ è¯·åœ¨ç¼–è¾‘åŽï¼Œé‡å¯Redmineåº”ç”¨ã€‚
+  text_scm_command_not_available: Scmå‘½ä»¤ä¸å¯ç”¨ã€‚ è¯·æ£€æŸ¥ç®¡ç†é¢æ¿çš„é…ç½®ã€‚
+  text_git_repository_note: åº“ä¸­æ— å†…å®¹ã€‚(e.g. /gitrepo, c:\gitrepo)
+  notice_issue_successful_create: é—®é¢˜ %{id} å·²åˆ›å»ºã€‚
+  label_between: ä»‹äºŽ
+  setting_issue_group_assignment: å…è®¸é—®é¢˜è¢«åˆ†é…ç»™ç»„
+  label_diff: diff
+  description_query_sort_criteria_direction: æŽ’åºæ–¹å¼
+  description_project_scope: æœç´¢èŒƒå›´
+  description_filter: è¿‡æ»¤å™¨
+  description_user_mail_notification: é‚®ä»¶é€šçŸ¥è®¾ç½®
+  description_date_from: è¾“å…¥å¼€å§‹æ—¥æœŸ
+  description_message_content: ä¿¡æ¯å†…å®¹
+  description_available_columns: å¤‡é€‰åˆ—
+  description_date_range_interval: æŒ‰å¼€å§‹æ—¥æœŸå’Œç»“æŸæ—¥æœŸé€‰æ‹©èŒƒå›´
+  description_issue_category_reassign: é€‰æ‹©é—®é¢˜ç±»åˆ«
+  description_search: æœç´¢å­—æ®µ
+  description_notes: æ‰¹æ³¨
+  description_date_range_list: ä»Žåˆ—è¡¨ä¸­é€‰æ‹©èŒƒå›´
+  description_choose_project: é¡¹ç›®
+  description_date_to: è¾“å…¥ç»“æŸæ—¥æœŸ
+  description_query_sort_criteria_attribute: æŽ’åºæ–¹å¼
+  description_wiki_subpages_reassign: é€‰æ‹©çˆ¶é¡µé¢
+  description_selected_columns: å·²é€‰åˆ—
+  label_parent_revision: çˆ¶ä¿®è®¢
+  label_child_revision: å­ä¿®è®¢
+  error_scm_annotate_big_text_file: è¾“å…¥æ–‡æœ¬å†…å®¹è¶…é•¿ï¼Œæ— æ³•è¾“å…¥ã€‚
+  setting_default_issue_start_date_to_creation_date: ä½¿ç”¨å½“å‰æ—¥æœŸä½œä¸ºæ–°é—®é¢˜çš„å¼€å§‹æ—¥æœŸ
+  button_edit_section: ç¼–è¾‘æ­¤åŒºåŸŸ
+  setting_repositories_encodings: é™„ä»¶å’Œç‰ˆæœ¬åº“ç¼–ç 
+  description_all_columns: æ‰€æœ‰åˆ—
+  button_export: å¯¼å‡º
+  label_export_options: "%{export_format} å¯¼å‡ºé€‰é¡¹"
+  error_attachment_too_big: è¯¥æ–‡ä»¶æ— æ³•ä¸Šä¼ ã€‚è¶…è¿‡æ–‡ä»¶å¤§å°é™åˆ¶ (%{max_size})
+  notice_failed_to_save_time_entries: "æ— æ³•ä¿å­˜ä¸‹åˆ—æ‰€é€‰å–çš„ %{total} ä¸ªé¡¹ç›®ä¸­çš„ %{count} å·¥æ—¶ï¼š %{ids}ã€‚"
+  label_x_issues:
+    zero:  0 é—®é¢˜
+    one:   1 é—®é¢˜
+    other: "%{count} é—®é¢˜"
+  label_repository_new: æ–°å»ºç‰ˆæœ¬åº“
+  field_repository_is_default: ä¸»ç‰ˆæœ¬åº“
+  label_copy_attachments: å¤åˆ¶é™„ä»¶
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: å·²å®Œæˆçš„ç‰ˆæœ¬
+  text_project_identifier_info: ä»…å°å†™å­—æ¯ï¼ˆa-zï¼‰ã€æ•°å­—ã€ç ´æŠ˜å·ï¼ˆ-ï¼‰å’Œä¸‹åˆ’çº¿ï¼ˆ_ï¼‰å¯ä»¥ä½¿ç”¨ã€‚<br />ä¸€æ—¦ä¿å­˜ï¼Œæ ‡è¯†æ— æ³•ä¿®æ”¹ã€‚
+  field_multiple: å¤šé‡å–å€¼
+  setting_commit_cross_project_ref: å…è®¸å¼•ç”¨/ä¿®å¤æ‰€æœ‰å…¶ä»–é¡¹ç›®çš„é—®é¢˜
+  text_issue_conflict_resolution_add_notes: æ·»åŠ è¯´æ˜Žå¹¶å–æ¶ˆæˆ‘çš„å…¶ä»–å˜æ›´å¤„ç†ã€‚
+  text_issue_conflict_resolution_overwrite: ç›´æŽ¥å¥—ç”¨æˆ‘çš„å˜æ›´ ï¼ˆå…ˆå‰çš„è¯´æ˜Žå°†è¢«ä¿ç•™ï¼Œä½†æ˜¯æŸäº›å˜æ›´å†…å®¹å¯èƒ½ä¼šè¢«è¦†ç›–ï¼‰
+  notice_issue_update_conflict: å½“æ‚¨æ­£åœ¨ç¼–è¾‘è¿™ä¸ªé—®é¢˜çš„æ—¶å€™ï¼Œå®ƒå·²ç»è¢«å…¶ä»–äººæŠ¢å…ˆä¸€æ­¥æ›´æ–°è¿‡äº†ã€‚
+  text_issue_conflict_resolution_cancel: å–æ¶ˆæˆ‘æ‰€æœ‰çš„å˜æ›´å¹¶é‡æ–°åˆ·æ–°æ˜¾ç¤º %{link} ã€‚
+  permission_manage_related_issues: ç›¸å…³é—®é¢˜ç®¡ç†
+  field_auth_source_ldap_filter: LDAP è¿‡æ»¤å™¨
+  label_search_for_watchers: é€šè¿‡æŸ¥æ‰¾æ–¹å¼æ·»åŠ è·Ÿè¸ªè€…
+  notice_account_deleted: æ‚¨çš„è´¦å·å·²è¢«æ°¸ä¹…åˆ é™¤ï¼ˆè´¦å·å·²æ— æ³•æ¢å¤ï¼‰ã€‚
+  setting_unsubscribe: å…è®¸ç”¨æˆ·é€€è®¢
+  button_delete_my_account: åˆ é™¤æˆ‘çš„è´¦å·
+  text_account_destroy_confirmation: |-
+    ç¡®å®šç»§ç»­å¤„ç†ï¼Ÿ
+    æ‚¨çš„è´¦å·ä¸€æ—¦åˆ é™¤ï¼Œå°†æ— æ³•å†æ¬¡æ¿€æ´»ä½¿ç”¨ã€‚
+  error_session_expired: æ‚¨çš„ä¼šè¯å·²è¿‡æœŸã€‚è¯·é‡æ–°ç™»é™†ã€‚
+  text_session_expiration_settings: "è­¦å‘Šï¼š æ›´æ”¹è¿™äº›è®¾ç½®å°†ä¼šä½¿åŒ…æ‹¬ä½ åœ¨å†…çš„å½“å‰ä¼šè¯å¤±æ•ˆã€‚"
+  setting_session_lifetime: ä¼šè¯æœ€å¤§æœ‰æ•ˆæ—¶é—´
+  setting_session_timeout: ä¼šè¯é—²ç½®è¶…æ—¶
+  label_session_expiration: ä¼šè¯è¿‡æœŸ
+  permission_close_project: å…³é—­/é‡å¼€é¡¹ç›®
+  label_show_closed_projects: æŸ¥çœ‹å·²å…³é—­çš„é¡¹ç›®
+  button_close: å…³é—­
+  button_reopen: é‡å¼€
+  project_status_active: å·²æ¿€æ´»
+  project_status_closed: å·²å…³é—­
+  project_status_archived: å·²å­˜æ¡£
+  text_project_closed: å½“å‰é¡¹ç›®å·²è¢«å…³é—­ã€‚å½“å‰é¡¹ç›®åªè¯»ã€‚
+  notice_user_successful_create: ç”¨æˆ· %{id} å·²åˆ›å»ºã€‚
+  field_core_fields: æ ‡å‡†å­—æ®µ
+  field_timeout: è¶…æ—¶ (ç§’)
+  setting_thumbnails_enabled: æ˜¾ç¤ºé™„ä»¶ç•¥ç¼©å›¾
+  setting_thumbnails_size: ç•¥ç¼©å›¾å°ºå¯¸ (åƒç´ )
+  label_status_transitions: çŠ¶æ€è½¬æ¢
+  label_fields_permissions: å­—æ®µæƒé™
+  label_readonly: åªè¯»
+  label_required: å¿…å¡«
+  text_repository_identifier_info: ä»…å°å†™å­—æ¯ï¼ˆa-zï¼‰ã€æ•°å­—ã€ç ´æŠ˜å·ï¼ˆ-ï¼‰å’Œä¸‹åˆ’çº¿ï¼ˆ_ï¼‰å¯ä»¥ä½¿ç”¨ã€‚<br />ä¸€æ—¦ä¿å­˜ï¼Œæ ‡è¯†æ— æ³•ä¿®æ”¹ã€‚
+  field_board_parent: çˆ¶è®ºå›
+  label_attribute_of_project: é¡¹ç›® %{name}
+  label_attribute_of_author: ä½œè€… %{name}
+  label_attribute_of_assigned_to: åˆ†é…ç»™ %{name}
+  label_attribute_of_fixed_version: ç›®æ ‡ç‰ˆæœ¬ %{name}
+  label_copy_subtasks: å¤åˆ¶å­ä»»åŠ¡
+  label_copied_to: å¤åˆ¶åˆ°
+  label_copied_from: å¤åˆ¶äºŽ
+  label_any_issues_in_project: é¡¹ç›®å†…ä»»æ„é—®é¢˜
+  label_any_issues_not_in_project: é¡¹ç›®å¤–ä»»æ„é—®é¢˜
+  field_private_notes: ç§æœ‰æ³¨è§£
+  permission_view_private_notes: æŸ¥çœ‹ç§æœ‰æ³¨è§£
+  permission_set_notes_private: è®¾ç½®ä¸ºç§æœ‰æ³¨è§£
+  label_no_issues_in_project: é¡¹ç›®å†…æ— ç›¸å…³é—®é¢˜
+  label_any: å…¨éƒ¨
+  label_last_n_weeks: ä¸Š %{count} å‘¨å‰
+  setting_cross_project_subtasks: æ”¯æŒè·¨é¡¹ç›®å­ä»»åŠ¡
+  label_cross_project_descendants: ä¸Žå­é¡¹ç›®å…±äº«
+  label_cross_project_tree: ä¸Žé¡¹ç›®æ ‘å…±äº«
+  label_cross_project_hierarchy: ä¸Žé¡¹ç›®ç»§æ‰¿å±‚æ¬¡å…±äº«
+  label_cross_project_system: ä¸Žæ‰€æœ‰é¡¹ç›®å…±äº«
+  button_hide: éšè—
+  setting_non_working_week_days: Non-working days
+  label_in_the_next_days: in the next
+  label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: åˆè®¡
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/fe/fe616c1a4677a1989f6035ef3d43e4954fce98ea.svn-base
--- /dev/null
+++ b/.svn/pristine/fe/fe616c1a4677a1989f6035ef3d43e4954fce98ea.svn-base
@@ -0,0 +1,51 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class RoutingEnumerationsTest < ActionController::IntegrationTest
+  def test_enumerations
+    assert_routing(
+        { :method => 'get', :path => "/enumerations" },
+        { :controller => 'enumerations', :action => 'index' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/enumerations/new" },
+        { :controller => 'enumerations', :action => 'new' }
+      )
+    assert_routing(
+        { :method => 'post', :path => "/enumerations" },
+        { :controller => 'enumerations', :action => 'create' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/enumerations/2/edit" },
+        { :controller => 'enumerations', :action => 'edit', :id => '2' }
+      )
+    assert_routing(
+        { :method => 'put', :path => "/enumerations/2" },
+        { :controller => 'enumerations', :action => 'update', :id => '2' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/enumerations/2" },
+        { :controller => 'enumerations', :action => 'destroy', :id => '2' }
+      )
+    assert_routing(
+        { :method => 'get', :path => "/enumerations/issue_priorities.xml" },
+        { :controller => 'enumerations', :action => 'index', :type => 'issue_priorities', :format => 'xml' }
+      )
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ff/ff068acc0413b56f4b540c721950411f34fdcce5.svn-base
--- a/.svn/pristine/ff/ff068acc0413b56f4b540c721950411f34fdcce5.svn-base
+++ /dev/null
@@ -1,27 +0,0 @@
-<h2><%=l(:label_issue_new)%></h2>
-
-<% labelled_tabular_form_for :issue, @issue, :url => {:controller => 'issues', :action => 'create', :project_id => @project},
-                             :html => {:multipart => true, :id => 'issue-form', :class => 'tabular new-issue-form'} do |f| %>
-    <%= error_messages_for 'issue' %>
-    <div class="box">
-    <%= render :partial => 'issues/form', :locals => {:f => f} %>
-    </div>
-    <%= submit_tag l(:button_create) %>
-    <%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
-    <%= link_to_remote l(:label_preview),
-                       { :url => preview_issue_path(:project_id => @project),
-                         :method => 'post',
-                         :update => 'preview',
-                         :with => "Form.serialize('issue-form')",
-                         :complete => "Element.scrollTo('preview')"
-                       }, :accesskey => accesskey(:preview) %>
-
-    <%= javascript_tag "Form.Element.focus('issue_subject');" %>
-<% end %>
-
-<div id="preview" class="wiki"></div>
-
-<% content_for :header_tags do %>
-    <%= stylesheet_link_tag 'scm' %>
-    <%= robot_exclusion_tag %>
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ff/ff1c47ab3a4a85cdc878d408e530d4ba3db0f578.svn-base
--- /dev/null
+++ b/.svn/pristine/ff/ff1c47ab3a4a85cdc878d408e530d4ba3db0f578.svn-base
@@ -0,0 +1,149 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class Redmine::ApiTest::AttachmentsTest < Redmine::ApiTest::Base
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :attachments
+
+  def setup
+    Setting.rest_api_enabled = '1'
+    set_fixtures_attachments_directory
+  end
+
+  def teardown
+    set_tmp_attachments_directory
+  end
+
+  test "GET /attachments/:id.xml should return the attachment" do
+    get '/attachments/7.xml', {}, credentials('jsmith')
+    assert_response :success
+    assert_equal 'application/xml', @response.content_type
+    assert_tag :tag => 'attachment',
+      :child => {
+        :tag => 'id',
+        :content => '7',
+        :sibling => {
+          :tag => 'filename',
+          :content => 'archive.zip',
+          :sibling => {
+            :tag => 'content_url',
+            :content => 'http://www.example.com/attachments/download/7/archive.zip'
+          }
+        }
+      }
+  end
+
+  test "GET /attachments/:id.xml should deny access without credentials" do
+    get '/attachments/7.xml'
+    assert_response 401
+    set_tmp_attachments_directory
+  end
+
+  test "GET /attachments/download/:id/:filename should return the attachment content" do
+    get '/attachments/download/7/archive.zip', {}, credentials('jsmith')
+    assert_response :success
+    assert_equal 'application/octet-stream', @response.content_type
+    set_tmp_attachments_directory
+  end
+
+  test "GET /attachments/download/:id/:filename should deny access without credentials" do
+    get '/attachments/download/7/archive.zip'
+    assert_response 302
+    set_tmp_attachments_directory
+  end
+
+  test "POST /uploads.xml should return the token" do
+    set_tmp_attachments_directory
+    assert_difference 'Attachment.count' do
+      post '/uploads.xml', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
+      assert_response :created
+      assert_equal 'application/xml', response.content_type
+    end
+
+    xml = Hash.from_xml(response.body)
+    assert_kind_of Hash, xml['upload']
+    token = xml['upload']['token']
+    assert_not_nil token
+
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal token, attachment.token
+    assert_nil attachment.container
+    assert_equal 2, attachment.author_id
+    assert_equal 'File content'.size, attachment.filesize
+    assert attachment.content_type.blank?
+    assert attachment.filename.present?
+    assert_match /\d+_[0-9a-z]+/, attachment.diskfile
+    assert File.exist?(attachment.diskfile)
+    assert_equal 'File content', File.read(attachment.diskfile)
+  end
+
+  test "POST /uploads.json should return the token" do
+    set_tmp_attachments_directory
+    assert_difference 'Attachment.count' do
+      post '/uploads.json', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
+      assert_response :created
+      assert_equal 'application/json', response.content_type
+    end
+
+    json = ActiveSupport::JSON.decode(response.body)
+    assert_kind_of Hash, json['upload']
+    token = json['upload']['token']
+    assert_not_nil token
+
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal token, attachment.token
+  end
+
+  test "POST /uploads.xml should accept :filename param as the attachment filename" do
+    set_tmp_attachments_directory
+    assert_difference 'Attachment.count' do
+      post '/uploads.xml?filename=test.txt', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
+      assert_response :created
+    end
+
+    attachment = Attachment.order('id DESC').first
+    assert_equal 'test.txt', attachment.filename
+    assert_match /_test\.txt$/, attachment.diskfile
+  end
+
+  test "POST /uploads.xml should not accept other content types" do
+    set_tmp_attachments_directory
+    assert_no_difference 'Attachment.count' do
+      post '/uploads.xml', 'PNG DATA', {"CONTENT_TYPE" => 'image/png'}.merge(credentials('jsmith'))
+      assert_response 406
+    end
+  end
+
+  test "POST /uploads.xml should return errors if file is too big" do
+    set_tmp_attachments_directory
+    with_settings :attachment_max_size => 1 do
+      assert_no_difference 'Attachment.count' do
+        post '/uploads.xml', ('x' * 2048), {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
+        assert_response 422
+        assert_tag 'error', :content => /exceeds the maximum allowed file size/
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ff/ff62b4bdd41363f9cdc9bf0c3cbe24d3f90f2713.svn-base
--- a/.svn/pristine/ff/ff62b4bdd41363f9cdc9bf0c3cbe24d3f90f2713.svn-base
+++ /dev/null
@@ -1,18 +0,0 @@
-<div class="autoscroll">
-<table class="filecontent syntaxhl">
-<tbody>
-<% line_num = 1 %>
-<% syntax_highlight(filename, Redmine::CodesetUtil.to_utf8_by_setting(content)).each_line do |line| %>
-  <tr>
-    <th class="line-num" id="L<%= line_num %>">
-      <a href="#L<%= line_num %>"><%= line_num %></a>
-    </th>
-    <td class="line-code">
-      <pre><%= line %></pre>
-    </td>
-  </tr>
-  <% line_num += 1 %>
-<% end %>
-</tbody>
-</table>
-</div>
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ff/ff7c7a78022ec834d13d1e81c3b7d935dfcd48bf.svn-base
--- a/.svn/pristine/ff/ff7c7a78022ec834d13d1e81c3b7d935dfcd48bf.svn-base
+++ /dev/null
@@ -1,25 +0,0 @@
-module CodeRay
-module Encoders
-  
-  load :token_kind_filter
-  
-  # A simple Filter that removes all tokens of the :comment kind.
-  # 
-  # Alias: +remove_comments+
-  # 
-  # Usage:
-  #  CodeRay.scan('print # foo', :ruby).comment_filter.text
-  #  #-> "print "
-  # 
-  # See also: TokenKindFilter, LinesOfCode
-  class CommentFilter < TokenKindFilter
-    
-    register_for :comment_filter
-    
-    DEFAULT_OPTIONS = superclass::DEFAULT_OPTIONS.merge \
-      :exclude => [:comment, :docstring]
-    
-  end
-  
-end
-end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ff/ffca1425f1aa4e1091d7e6036ce643ffe45832ab.svn-base
--- /dev/null
+++ b/.svn/pristine/ff/ffca1425f1aa4e1091d7e6036ce643ffe45832ab.svn-base
@@ -0,0 +1,19 @@
+class CreateProjectsTrackers < ActiveRecord::Migration
+  def self.up
+    create_table :projects_trackers, :id => false do |t|
+      t.column :project_id, :integer, :default => 0, :null => false
+      t.column :tracker_id, :integer, :default => 0, :null => false
+    end
+    add_index :projects_trackers, :project_id, :name => :projects_trackers_project_id
+
+    # Associates all trackers to all projects (as it was before)
+    tracker_ids = Tracker.all.collect(&:id)
+    Project.all.each do |project|
+      project.tracker_ids = tracker_ids
+    end
+  end
+
+  def self.down
+    drop_table :projects_trackers
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd .svn/pristine/ff/ffce98a27e5a6dc82e77f6a0e106be536bad8666.svn-base
--- /dev/null
+++ b/.svn/pristine/ff/ffce98a27e5a6dc82e77f6a0e106be536bad8666.svn-base
@@ -0,0 +1,568 @@
+# Copyright (c) 2005 Rick Olson
+# 
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+# 
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module ActiveRecord #:nodoc:
+  module Acts #:nodoc:
+    # Specify this act if you want to save a copy of the row in a versioned table.  This assumes there is a 
+    # versioned table ready and that your model has a version field.  This works with optimistic locking if the lock_version
+    # column is present as well.
+    #
+    # The class for the versioned model is derived the first time it is seen. Therefore, if you change your database schema you have to restart
+    # your container for the changes to be reflected. In development mode this usually means restarting WEBrick.
+    #
+    #   class Page < ActiveRecord::Base
+    #     # assumes pages_versions table
+    #     acts_as_versioned
+    #   end
+    #
+    # Example:
+    #
+    #   page = Page.create(:title => 'hello world!')
+    #   page.version       # => 1
+    #
+    #   page.title = 'hello world'
+    #   page.save
+    #   page.version       # => 2
+    #   page.versions.size # => 2
+    #
+    #   page.revert_to(1)  # using version number
+    #   page.title         # => 'hello world!'
+    #
+    #   page.revert_to(page.versions.last) # using versioned instance
+    #   page.title         # => 'hello world'
+    #
+    #   page.versions.earliest # efficient query to find the first version
+    #   page.versions.latest   # efficient query to find the most recently created version
+    #
+    #
+    # Simple Queries to page between versions
+    #
+    #   page.versions.before(version) 
+    #   page.versions.after(version)
+    #
+    # Access the previous/next versions from the versioned model itself
+    #
+    #   version = page.versions.latest
+    #   version.previous # go back one version
+    #   version.next     # go forward one version
+    #
+    # See ActiveRecord::Acts::Versioned::ClassMethods#acts_as_versioned for configuration options
+    module Versioned
+      CALLBACKS = [:set_new_version, :save_version_on_create, :save_version?, :clear_altered_attributes]
+      def self.included(base) # :nodoc:
+        base.extend ClassMethods
+      end
+
+      module ClassMethods
+        # == Configuration options
+        #
+        # * <tt>class_name</tt> - versioned model class name (default: PageVersion in the above example)
+        # * <tt>table_name</tt> - versioned model table name (default: page_versions in the above example)
+        # * <tt>foreign_key</tt> - foreign key used to relate the versioned model to the original model (default: page_id in the above example)
+        # * <tt>inheritance_column</tt> - name of the column to save the model's inheritance_column value for STI.  (default: versioned_type)
+        # * <tt>version_column</tt> - name of the column in the model that keeps the version number (default: version)
+        # * <tt>sequence_name</tt> - name of the custom sequence to be used by the versioned model.
+        # * <tt>limit</tt> - number of revisions to keep, defaults to unlimited
+        # * <tt>if</tt> - symbol of method to check before saving a new version.  If this method returns false, a new version is not saved.
+        #   For finer control, pass either a Proc or modify Model#version_condition_met?
+        #
+        #     acts_as_versioned :if => Proc.new { |auction| !auction.expired? }
+        #
+        #   or...
+        #
+        #     class Auction
+        #       def version_condition_met? # totally bypasses the <tt>:if</tt> option
+        #         !expired?
+        #       end
+        #     end
+        #
+        # * <tt>if_changed</tt> - Simple way of specifying attributes that are required to be changed before saving a model.  This takes
+        #   either a symbol or array of symbols.  WARNING - This will attempt to overwrite any attribute setters you may have.
+        #   Use this instead if you want to write your own attribute setters (and ignore if_changed):
+        # 
+        #     def name=(new_name)
+        #       write_changed_attribute :name, new_name
+        #     end
+        #
+        # * <tt>extend</tt> - Lets you specify a module to be mixed in both the original and versioned models.  You can also just pass a block
+        #   to create an anonymous mixin:
+        #
+        #     class Auction
+        #       acts_as_versioned do
+        #         def started?
+        #           !started_at.nil?
+        #         end
+        #       end
+        #     end
+        #
+        #   or...
+        #
+        #     module AuctionExtension
+        #       def started?
+        #         !started_at.nil?
+        #       end
+        #     end
+        #     class Auction
+        #       acts_as_versioned :extend => AuctionExtension
+        #     end
+        #
+        #  Example code:
+        #
+        #    @auction = Auction.find(1)
+        #    @auction.started?
+        #    @auction.versions.first.started?
+        #
+        # == Database Schema
+        #
+        # The model that you're versioning needs to have a 'version' attribute. The model is versioned 
+        # into a table called #{model}_versions where the model name is singlular. The _versions table should 
+        # contain all the fields you want versioned, the same version column, and a #{model}_id foreign key field.
+        #
+        # A lock_version field is also accepted if your model uses Optimistic Locking.  If your table uses Single Table inheritance,
+        # then that field is reflected in the versioned model as 'versioned_type' by default.
+        #
+        # Acts_as_versioned comes prepared with the ActiveRecord::Acts::Versioned::ActMethods::ClassMethods#create_versioned_table 
+        # method, perfect for a migration.  It will also create the version column if the main model does not already have it.
+        #
+        #   class AddVersions < ActiveRecord::Migration
+        #     def self.up
+        #       # create_versioned_table takes the same options hash
+        #       # that create_table does
+        #       Post.create_versioned_table
+        #     end
+        # 
+        #     def self.down
+        #       Post.drop_versioned_table
+        #     end
+        #   end
+        # 
+        # == Changing What Fields Are Versioned
+        #
+        # By default, acts_as_versioned will version all but these fields: 
+        # 
+        #   [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
+        #
+        # You can add or change those by modifying #non_versioned_columns.  Note that this takes strings and not symbols.
+        #
+        #   class Post < ActiveRecord::Base
+        #     acts_as_versioned
+        #     self.non_versioned_columns << 'comments_count'
+        #   end
+        # 
+        def acts_as_versioned(options = {}, &extension)
+          # don't allow multiple calls
+          return if self.included_modules.include?(ActiveRecord::Acts::Versioned::ActMethods)
+
+          send :include, ActiveRecord::Acts::Versioned::ActMethods
+
+          cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column, 
+            :version_column, :max_version_limit, :track_altered_attributes, :version_condition, :version_sequence_name, :non_versioned_columns,
+            :version_association_options
+
+          # legacy
+          alias_method :non_versioned_fields,  :non_versioned_columns
+          alias_method :non_versioned_fields=, :non_versioned_columns=
+
+          class << self
+            alias_method :non_versioned_fields,  :non_versioned_columns
+            alias_method :non_versioned_fields=, :non_versioned_columns=
+          end
+
+          send :attr_accessor, :altered_attributes
+
+          self.versioned_class_name         = options[:class_name]  || "Version"
+          self.versioned_foreign_key        = options[:foreign_key] || self.to_s.foreign_key
+          self.versioned_table_name         = options[:table_name]  || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_versions#{table_name_suffix}"
+          self.versioned_inheritance_column = options[:inheritance_column] || "versioned_#{inheritance_column}"
+          self.version_column               = options[:version_column]     || 'version'
+          self.version_sequence_name        = options[:sequence_name]
+          self.max_version_limit            = options[:limit].to_i
+          self.version_condition            = options[:if] || true
+          self.non_versioned_columns        = [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column]
+          self.version_association_options  = {
+                                                :class_name  => "#{self.to_s}::#{versioned_class_name}",
+                                                :foreign_key => versioned_foreign_key,
+                                                :dependent   => :delete_all
+                                              }.merge(options[:association_options] || {})
+
+          if block_given?
+            extension_module_name = "#{versioned_class_name}Extension"
+            silence_warnings do
+              self.const_set(extension_module_name, Module.new(&extension))
+            end
+
+            options[:extend] = self.const_get(extension_module_name)
+          end
+
+          class_eval do
+            has_many :versions, version_association_options do
+              # finds earliest version of this record
+              def earliest
+                @earliest ||= order('version').first
+              end
+
+              # find latest version of this record
+              def latest
+                @latest ||= order('version desc').first
+              end
+            end
+            before_save  :set_new_version
+            after_create :save_version_on_create
+            after_update :save_version
+            after_save   :clear_old_versions
+            after_save   :clear_altered_attributes
+
+            unless options[:if_changed].nil?
+              self.track_altered_attributes = true
+              options[:if_changed] = [options[:if_changed]] unless options[:if_changed].is_a?(Array)
+              options[:if_changed].each do |attr_name|
+                define_method("#{attr_name}=") do |value|
+                  write_changed_attribute attr_name, value
+                end
+              end
+            end
+
+            include options[:extend] if options[:extend].is_a?(Module)
+          end
+
+          # create the dynamic versioned model
+          const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
+            def self.reloadable? ; false ; end
+            # find first version before the given version
+            def self.before(version)
+              order('version desc').
+                where("#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version).
+                first
+            end
+
+            # find first version after the given version.
+            def self.after(version)
+              order('version').
+                where("#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version).
+                first
+            end
+
+            def previous
+              self.class.before(self)
+            end
+
+            def next
+              self.class.after(self)
+            end
+
+            def versions_count
+              page.version
+            end
+          end
+
+          versioned_class.cattr_accessor :original_class
+          versioned_class.original_class = self
+          versioned_class.table_name = versioned_table_name
+          versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym, 
+            :class_name  => "::#{self.to_s}", 
+            :foreign_key => versioned_foreign_key
+          versioned_class.send :include, options[:extend]         if options[:extend].is_a?(Module)
+          versioned_class.set_sequence_name version_sequence_name if version_sequence_name
+        end
+      end
+
+      module ActMethods
+        def self.included(base) # :nodoc:
+          base.extend ClassMethods
+        end
+
+        # Finds a specific version of this record
+        def find_version(version = nil)
+          self.class.find_version(id, version)
+        end
+
+        # Saves a version of the model if applicable
+        def save_version
+          save_version_on_create if save_version?
+        end
+
+        # Saves a version of the model in the versioned table.  This is called in the after_save callback by default
+        def save_version_on_create
+          rev = self.class.versioned_class.new
+          self.clone_versioned_model(self, rev)
+          rev.version = send(self.class.version_column)
+          rev.send("#{self.class.versioned_foreign_key}=", self.id)
+          rev.save
+        end
+
+        # Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
+        # Override this method to set your own criteria for clearing old versions.
+        def clear_old_versions
+          return if self.class.max_version_limit == 0
+          excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
+          if excess_baggage > 0
+            sql = "DELETE FROM #{self.class.versioned_table_name} WHERE version <= #{excess_baggage} AND #{self.class.versioned_foreign_key} = #{self.id}"
+            self.class.versioned_class.connection.execute sql
+          end
+        end
+
+        def versions_count
+          version
+        end
+
+        # Reverts a model to a given version.  Takes either a version number or an instance of the versioned model
+        def revert_to(version)
+          if version.is_a?(self.class.versioned_class)
+            return false unless version.send(self.class.versioned_foreign_key) == self.id and !version.new_record?
+          else
+            return false unless version = versions.find_by_version(version)
+          end
+          self.clone_versioned_model(version, self)
+          self.send("#{self.class.version_column}=", version.version)
+          true
+        end
+
+        # Reverts a model to a given version and saves the model.
+        # Takes either a version number or an instance of the versioned model
+        def revert_to!(version)
+          revert_to(version) ? save_without_revision : false
+        end
+
+        # Temporarily turns off Optimistic Locking while saving.  Used when reverting so that a new version is not created.
+        def save_without_revision
+          save_without_revision!
+          true
+        rescue
+          false
+        end
+
+        def save_without_revision!
+          without_locking do
+            without_revision do
+              save!
+            end
+          end
+        end
+
+        # Returns an array of attribute keys that are versioned.  See non_versioned_columns
+        def versioned_attributes
+          self.attributes.keys.select { |k| !self.class.non_versioned_columns.include?(k) }
+        end
+
+        # If called with no parameters, gets whether the current model has changed and needs to be versioned.
+        # If called with a single parameter, gets whether the parameter has changed.
+        def changed?(attr_name = nil)
+          attr_name.nil? ?
+            (!self.class.track_altered_attributes || (altered_attributes && altered_attributes.length > 0)) :
+            (altered_attributes && altered_attributes.include?(attr_name.to_s))
+        end
+
+        # keep old dirty? method
+        alias_method :dirty?, :changed?
+
+        # Clones a model.  Used when saving a new version or reverting a model's version.
+        def clone_versioned_model(orig_model, new_model)
+          self.versioned_attributes.each do |key|
+            new_model.send("#{key}=", orig_model.send(key)) if orig_model.respond_to?(key)
+          end
+
+					if self.class.columns_hash.include?(self.class.inheritance_column)
+            if orig_model.is_a?(self.class.versioned_class)
+              new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
+            elsif new_model.is_a?(self.class.versioned_class)
+              new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
+            end
+          end
+        end
+
+        # Checks whether a new version shall be saved or not.  Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
+        def save_version?
+          version_condition_met? && changed?
+        end
+
+        # Checks condition set in the :if option to check whether a revision should be created or not.  Override this for
+        # custom version condition checking.
+        def version_condition_met?
+          case
+          when version_condition.is_a?(Symbol)
+            send(version_condition)
+          when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
+            version_condition.call(self)
+          else
+            version_condition
+          end
+        end
+
+        # Executes the block with the versioning callbacks disabled.
+        #
+        #   @foo.without_revision do
+        #     @foo.save
+        #   end
+        #
+        def without_revision(&block)
+          self.class.without_revision(&block)
+        end
+
+        # Turns off optimistic locking for the duration of the block
+        #
+        #   @foo.without_locking do
+        #     @foo.save
+        #   end
+        #
+        def without_locking(&block)
+          self.class.without_locking(&block)
+        end
+
+        def empty_callback() end #:nodoc:
+
+        protected
+          # sets the new version before saving, unless you're using optimistic locking.  In that case, let it take care of the version.
+          def set_new_version
+            self.send("#{self.class.version_column}=", self.next_version) if new_record? || (!locking_enabled? && save_version?)
+          end
+
+          # Gets the next available version for the current record, or 1 for a new record
+          def next_version
+            return 1 if new_record?
+            (versions.calculate(:max, :version) || 0) + 1
+          end
+
+          # clears current changed attributes.  Called after save.
+          def clear_altered_attributes
+            self.altered_attributes = []
+          end
+
+          def write_changed_attribute(attr_name, attr_value)
+            # Convert to db type for comparison. Avoids failing Float<=>String comparisons.
+            attr_value_for_db = self.class.columns_hash[attr_name.to_s].type_cast(attr_value)
+            (self.altered_attributes ||= []) << attr_name.to_s unless self.changed?(attr_name) || self.send(attr_name) == attr_value_for_db
+            write_attribute(attr_name, attr_value_for_db)
+          end
+
+        module ClassMethods
+          # Finds a specific version of a specific row of this model
+          def find_version(id, version = nil)
+            return find(id) unless version
+
+            conditions = ["#{versioned_foreign_key} = ? AND version = ?", id, version]
+            options = { :conditions => conditions, :limit => 1 }
+
+            if result = find_versions(id, options).first
+              result
+            else
+              raise RecordNotFound, "Couldn't find #{name} with ID=#{id} and VERSION=#{version}"
+            end
+          end
+
+          # Finds versions of a specific model.  Takes an options hash like <tt>find</tt>
+          def find_versions(id, options = {})
+            versioned_class.all({
+              :conditions => ["#{versioned_foreign_key} = ?", id],
+              :order      => 'version' }.merge(options))
+          end
+
+          # Returns an array of columns that are versioned.  See non_versioned_columns
+          def versioned_columns
+            self.columns.select { |c| !non_versioned_columns.include?(c.name) }
+          end
+
+          # Returns an instance of the dynamic versioned model
+          def versioned_class
+            const_get versioned_class_name
+          end
+
+          # Rake migration task to create the versioned table using options passed to acts_as_versioned
+          def create_versioned_table(create_table_options = {})
+            # create version column in main table if it does not exist
+            if !self.content_columns.find { |c| %w(version lock_version).include? c.name }
+              self.connection.add_column table_name, :version, :integer
+            end
+
+            self.connection.create_table(versioned_table_name, create_table_options) do |t|
+              t.column versioned_foreign_key, :integer
+              t.column :version, :integer
+            end
+
+            updated_col = nil
+            self.versioned_columns.each do |col| 
+              updated_col = col if !updated_col && %(updated_at updated_on).include?(col.name)
+              self.connection.add_column versioned_table_name, col.name, col.type, 
+                :limit => col.limit, 
+                :default => col.default,
+                :scale => col.scale,
+                :precision => col.precision
+            end
+
+            if type_col = self.columns_hash[inheritance_column]
+              self.connection.add_column versioned_table_name, versioned_inheritance_column, type_col.type, 
+                :limit => type_col.limit, 
+                :default => type_col.default,
+                :scale => type_col.scale,
+                :precision => type_col.precision
+            end
+
+            if updated_col.nil?
+              self.connection.add_column versioned_table_name, :updated_at, :timestamp
+            end
+          end
+
+          # Rake migration task to drop the versioned table
+          def drop_versioned_table
+            self.connection.drop_table versioned_table_name
+          end
+
+          # Executes the block with the versioning callbacks disabled.
+          #
+          #   Foo.without_revision do
+          #     @foo.save
+          #   end
+          #
+          def without_revision(&block)
+            class_eval do 
+              CALLBACKS.each do |attr_name|
+                alias_method "orig_#{attr_name}".to_sym, attr_name
+                alias_method attr_name, :empty_callback
+              end
+            end
+            block.call
+          ensure
+            class_eval do 
+              CALLBACKS.each do |attr_name|
+                alias_method attr_name, "orig_#{attr_name}".to_sym
+              end
+            end
+          end
+
+          # Turns off optimistic locking for the duration of the block
+          #
+          #   Foo.without_locking do
+          #     @foo.save
+          #   end
+          #
+          def without_locking(&block)
+            current = ActiveRecord::Base.lock_optimistically
+            ActiveRecord::Base.lock_optimistically = false if current
+            result = block.call
+            ActiveRecord::Base.lock_optimistically = true if current
+            result
+          end
+        end
+      end
+    end
+  end
+end
+
+ActiveRecord::Base.send :include, ActiveRecord::Acts::Versioned
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd .svn/wc.db
Binary file .svn/wc.db has changed
diff -r 0a574315af3e -r 4f746d8966dd Gemfile
--- a/Gemfile
+++ b/Gemfile
@@ -1,9 +1,9 @@
-source 'http://rubygems.org'
+source 'https://rubygems.org'
 
 gem "rails", "3.2.13"
 gem "jquery-rails", "~> 2.0.2"
 gem "i18n", "~> 0.6.0"
-gem "coderay", "~> 1.0.6"
+gem "coderay", "~> 1.0.9"
 gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
 gem "builder", "3.0.0"
 
@@ -28,43 +28,47 @@
   end
 end
 
-# Database gems
-platforms :mri, :mingw do
-  group :postgresql do
-    gem "pg", ">= 0.11.0"
-  end
-
-  group :sqlite do
-    gem "sqlite3"
-  end
+platforms :jruby do
+  # jruby-openssl is bundled with JRuby 1.7.0
+  gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
+  gem "activerecord-jdbc-adapter", "1.2.5"
 end
 
-platforms :mri_18, :mingw_18 do
-  group :mysql do
-    gem "mysql", "~> 2.8.1"
+# Include database gems for the adapters found in the database
+# configuration file
+require 'erb'
+require 'yaml'
+database_file = File.join(File.dirname(__FILE__), "config/database.yml")
+if File.exist?(database_file)
+  database_config = YAML::load(ERB.new(IO.read(database_file)).result)
+  adapters = database_config.values.map {|c| c['adapter']}.compact.uniq
+  if adapters.any?
+    adapters.each do |adapter|
+      case adapter
+      when 'mysql2'
+        gem "mysql2", "~> 0.3.11", :platforms => [:mri, :mingw]
+        gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
+      when 'mysql'
+        gem "mysql", "~> 2.8.1", :platforms => [:mri, :mingw]
+        gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
+      when /postgresql/
+        gem "pg", ">= 0.11.0", :platforms => [:mri, :mingw]
+        gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
+      when /sqlite3/
+        gem "sqlite3", :platforms => [:mri, :mingw]
+        gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
+      when /sqlserver/
+        gem "tiny_tds", "~> 0.5.1", :platforms => [:mri, :mingw]
+        gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
+      else
+        warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems")
+      end
+    end
+  else
+    warn("No adapter found in config/database.yml, please configure it first")
   end
-end
-
-platforms :mri_19, :mingw_19 do
-  group :mysql do
-    gem "mysql2", "~> 0.3.11"
-  end
-end
-
-platforms :jruby do
-  gem "jruby-openssl"
-
-  group :mysql do
-    gem "activerecord-jdbcmysql-adapter"
-  end
-
-  group :postgresql do
-    gem "activerecord-jdbcpostgresql-adapter"
-  end
-
-  group :sqlite do
-    gem "activerecord-jdbcsqlite3-adapter"
-  end
+else
+  warn("Please configure your config/database.yml first")
 end
 
 group :development do
@@ -73,13 +77,10 @@
 end
 
 group :test do
-  gem "shoulda", "~> 2.11"
-  # Shoulda does not work nice on Ruby 1.9.3 and JRuby 1.7.
-  # It seems to need test-unit explicitely.
-  platforms = [:mri_19]
-  platforms << :jruby if defined?(JRUBY_VERSION) && JRUBY_VERSION >= "1.7"
-  gem "test-unit", :platforms => platforms
+  gem "shoulda", "~> 3.3.2"
   gem "mocha", "~> 0.13.3"
+  gem 'capybara', '~> 2.0.0'
+  gem 'nokogiri', '< 1.6.0'
 end
 
 local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/account_controller.rb
--- a/app/controllers/account_controller.rb
+++ b/app/controllers/account_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,7 +25,9 @@
   # Login request and validation
   def login
     if request.get?
-      logout_user
+      if User.current.logged?
+        redirect_to home_url
+      end
     else
       authenticate_user
     end
@@ -36,15 +38,20 @@
 
   # Log out current user and redirect to welcome page
   def logout
-    logout_user
-    redirect_to home_url
+    if User.current.anonymous?
+      redirect_to home_url
+    elsif request.post?
+      logout_user
+      redirect_to home_url
+    end
+    # display the logout form
   end
 
   # Lets user choose a new password
   def lost_password
-    redirect_to(home_url) && return unless Setting.lost_password?
+    (redirect_to(home_url); return) unless Setting.lost_password?
     if params[:token]
-      @token = Token.find_by_action_and_value("recovery", params[:token].to_s)
+      @token = Token.find_token("recovery", params[:token].to_s)
       if @token.nil? || @token.expired?
         redirect_to home_url
         return
@@ -92,11 +99,11 @@
 
   # User self-registration
   def register
-    redirect_to(home_url) && return unless Setting.self_registration? || session[:auth_source_registration]
+    (redirect_to(home_url); return) unless Setting.self_registration? || session[:auth_source_registration]
 
     if request.get?
       session[:auth_source_registration] = nil
-      @user = User.new(:language => Setting.default_language)
+      @user = User.new(:language => current_language.to_s)
 
       @ssamr_user_details = SsamrUserDetail.new
 
@@ -116,7 +123,7 @@
           session[:auth_source_registration] = nil
           self.logged_user = @user
           flash[:notice] = l(:notice_account_activated)
-          redirect_to :controller => 'my', :action => 'account'
+          redirect_to my_account_path
         end
       else
         @user.login = params[:user][:login]
@@ -145,11 +152,11 @@
 
   # Token based account activation
   def activate
-    redirect_to(home_url) && return unless Setting.self_registration? && params[:token]
-    token = Token.find_by_action_and_value('register', params[:token])
-    redirect_to(home_url) && return unless token and !token.expired?
+    (redirect_to(home_url); return) unless Setting.self_registration? && params[:token].present?
+    token = Token.find_token('register', params[:token].to_s)
+    (redirect_to(home_url); return) unless token and !token.expired?
     user = token.user
-    redirect_to(home_url) && return unless user.registered?
+    (redirect_to(home_url); return) unless user.registered?
     user.activate
     if user.save
       token.destroy
@@ -182,12 +189,14 @@
   end
 
   def open_id_authenticate(openid_url)
-    authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => signin_url, :method => :post) do |result, identity_url, registration|
+    back_url = signin_url(:autologin => params[:autologin])
+
+    authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => back_url, :method => :post) do |result, identity_url, registration|
       if result.successful?
         user = User.find_or_initialize_by_identity_url(identity_url)
         if user.new_record?
           # Self-registration off
-          redirect_to(home_url) && return unless Setting.self_registration?
+          (redirect_to(home_url); return) unless Setting.self_registration?
 
           # Create on the fly
           user.login = registration['nickname'] unless registration['nickname'].nil?
@@ -231,12 +240,11 @@
       set_autologin_cookie(user)
     end
     call_hook(:controller_account_success_authentication_after, {:user => user })
-    redirect_back_or_default :controller => 'my', :action => 'page'
+    redirect_back_or_default my_page_path
   end
 
   def set_autologin_cookie(user)
     token = Token.create(:user => user, :action => 'autologin')
-    cookie_name = Redmine::Configuration['autologin_cookie_name'] || 'autologin'
     cookie_options = {
       :value => token.value,
       :expires => 1.year.from_now,
@@ -244,7 +252,7 @@
       :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
       :httponly => true
     }
-    cookies[cookie_name] = cookie_options
+    cookies[autologin_cookie_name] = cookie_options
   end
 
   # Onthefly creation failed, display the registration form to fill/fix attributes
@@ -283,7 +291,7 @@
     if user.save
       self.logged_user = user
       flash[:notice] = l(:notice_account_activated)
-      redirect_to :controller => 'my', :action => 'account'
+      redirect_to my_account_path
     else
       yield if block_given?
     end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/activities_controller.rb
--- a/app/controllers/activities_controller.rb
+++ b/app/controllers/activities_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/admin_controller.rb
--- a/app/controllers/admin_controller.rb
+++ b/app/controllers/admin_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -23,19 +23,18 @@
 
   before_filter :require_admin
   helper :sort
-  include SortHelper	
+  include SortHelper
 
   def index
     @no_configuration_data = Redmine::DefaultData::Loader::no_data?
   end
-	
+
   def projects
     @status = params[:status] || 1
 
-    scope = Project.status(@status)
+    scope = Project.status(@status).order('lft')
     scope = scope.like(params[:name]) if params[:name].present?
-
-    @projects = scope.all(:order => 'lft')
+    @projects = scope.all
 
     render :action => "projects", :layout => false if request.xhr?
   end
@@ -55,7 +54,7 @@
         flash[:error] = l(:error_can_t_load_default_data, e.message)
       end
     end
-    redirect_to :action => 'index'
+    redirect_to admin_path
   end
 
   def test_email
@@ -69,7 +68,7 @@
       flash[:error] = l(:notice_email_error, e.message)
     end
     ActionMailer::Base.raise_delivery_errors = raise_delivery_errors
-    redirect_to :controller => 'settings', :action => 'edit', :tab => 'notifications'
+    redirect_to settings_path(:tab => 'notifications')
   end
 
   def info
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/application_controller.rb
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -22,6 +22,9 @@
 
 class ApplicationController < ActionController::Base
   include Redmine::I18n
+  include Redmine::Pagination
+  include RoutesHelper
+  helper :routes
 
   class_attribute :accept_api_auth_actions
   class_attribute :accept_rss_auth_actions
@@ -32,7 +35,7 @@
   protect_from_forgery
   def handle_unverified_request
     super
-    cookies.delete(:autologin)
+    cookies.delete(autologin_cookie_name)
   end
 
   before_filter :session_expiration, :user_setup, :check_if_login_required, :set_localization
@@ -124,10 +127,14 @@
     user
   end
 
+  def autologin_cookie_name
+    Redmine::Configuration['autologin_cookie_name'].presence || 'autologin'
+  end
+
   def try_to_autologin
-    if cookies[:autologin] && Setting.autologin?
+    if cookies[autologin_cookie_name] && Setting.autologin?
       # auto-login feature starts a new session
-      user = User.try_to_autologin(cookies[:autologin])
+      user = User.try_to_autologin(cookies[autologin_cookie_name])
       if user
         reset_session
         start_user_session(user)
@@ -150,7 +157,7 @@
   # Logs out current user
   def logout_user
     if User.current.logged?
-      cookies.delete :autologin
+      cookies.delete(autologin_cookie_name)
       Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
       self.logged_user = nil
     end
@@ -300,6 +307,16 @@
     render_404
   end
 
+  def find_attachments
+    if (attachments = params[:attachments]).present?
+      att = attachments.values.collect do |attachment|
+        Attachment.find_by_token( attachment[:token] ) if attachment[:token].present?
+      end
+      att.compact!
+    end
+    @attachments = att || []
+  end
+
   # make sure that the user is a member of the project (or admin) if project is private
   # used as a before_filter for actions that do not require any particular permission on the project
   def check_project_privacy
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/attachments_controller.rb
--- a/app/controllers/attachments_controller.rb
+++ b/app/controllers/attachments_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -91,15 +91,17 @@
     @attachment = Attachment.new(:file => request.raw_post)
     @attachment.author = User.current
     @attachment.filename = params[:filename].presence || Redmine::Utils.random_hex(16)
+    saved = @attachment.save
 
-    if @attachment.save
-      respond_to do |format|
-        format.api { render :action => 'upload', :status => :created }
-      end
-    else
-      respond_to do |format|
-        format.api { render_validation_errors(@attachment) }
-      end
+    respond_to do |format|
+      format.js
+      format.api {
+        if saved
+          render :action => 'upload', :status => :created
+        else
+          render_validation_errors(@attachment)
+        end
+      }
     end
   end
 
@@ -107,9 +109,17 @@
     if @attachment.container.respond_to?(:init_journal)
       @attachment.container.init_journal(User.current)
     end
-    # Make sure association callbacks are called
-    @attachment.container.attachments.delete(@attachment)
-    redirect_to_referer_or project_path(@project)
+    if @attachment.container
+      # Make sure association callbacks are called
+      @attachment.container.attachments.delete(@attachment)
+    else
+      @attachment.destroy
+    end
+
+    respond_to do |format|
+      format.html { redirect_to_referer_or project_path(@project) }
+      format.js
+    end
   end
 
   def toggle_active
@@ -132,7 +142,12 @@
 
   # Checks that the file exists and is readable
   def file_readable
-    @attachment.readable? ? true : render_404
+    if @attachment.readable?
+      true
+    else
+      logger.error "Cannot send attachment, #{@attachment.diskfile} does not exist or is unreadable."
+      render_404
+    end
   end
 
   def read_authorize
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/auth_sources_controller.rb
--- a/app/controllers/auth_sources_controller.rb
+++ b/app/controllers/auth_sources_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -20,57 +20,77 @@
   menu_item :ldap_authentication
 
   before_filter :require_admin
+  before_filter :find_auth_source, :only => [:edit, :update, :test_connection, :destroy]
 
   def index
-    @auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 10
+    @auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25
   end
 
   def new
     klass_name = params[:type] || 'AuthSourceLdap'
     @auth_source = AuthSource.new_subclass_instance(klass_name, params[:auth_source])
+    render_404 unless @auth_source
   end
 
   def create
     @auth_source = AuthSource.new_subclass_instance(params[:type], params[:auth_source])
     if @auth_source.save
       flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index'
+      redirect_to auth_sources_path
     else
       render :action => 'new'
     end
   end
 
   def edit
-    @auth_source = AuthSource.find(params[:id])
   end
 
   def update
-    @auth_source = AuthSource.find(params[:id])
     if @auth_source.update_attributes(params[:auth_source])
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
+      redirect_to auth_sources_path
     else
       render :action => 'edit'
     end
   end
 
   def test_connection
-    @auth_source = AuthSource.find(params[:id])
     begin
       @auth_source.test_connection
       flash[:notice] = l(:notice_successful_connection)
     rescue Exception => e
       flash[:error] = l(:error_unable_to_connect, e.message)
     end
-    redirect_to :action => 'index'
+    redirect_to auth_sources_path
   end
 
   def destroy
-    @auth_source = AuthSource.find(params[:id])
-    unless @auth_source.users.find(:first)
+    unless @auth_source.users.exists?
       @auth_source.destroy
       flash[:notice] = l(:notice_successful_delete)
     end
-    redirect_to :action => 'index'
+    redirect_to auth_sources_path
+  end
+
+  def autocomplete_for_new_user
+    results = AuthSource.search(params[:term])
+
+    render :json => results.map {|result| {
+      'value' => result[:login],
+      'label' => "#{result[:login]} (#{result[:firstname]} #{result[:lastname]})",
+      'login' => result[:login].to_s,
+      'firstname' => result[:firstname].to_s,
+      'lastname' => result[:lastname].to_s,
+      'mail' => result[:mail].to_s,
+      'auth_source_id' => result[:auth_source_id].to_s
+    }}
+  end
+
+  private
+
+  def find_auth_source
+    @auth_source = AuthSource.find(params[:id])
+  rescue ActiveRecord::RecordNotFound
+    render_404
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/auto_completes_controller.rb
--- a/app/controllers/auto_completes_controller.rb
+++ b/app/controllers/auto_completes_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -23,10 +23,10 @@
     q = (params[:q] || params[:term]).to_s.strip
     if q.present?
       scope = (params[:scope] == "all" || @project.nil? ? Issue : @project.issues).visible
-      if q.match(/^\d+$/)
-        @issues << scope.find_by_id(q.to_i)
+      if q.match(/\A#?(\d+)\z/)
+        @issues << scope.find_by_id($1.to_i)
       end
-      @issues += scope.where("LOWER(#{Issue.table_name}.subject) LIKE ?", "%#{q.downcase}%").order("#{Issue.table_name}.id DESC").limit(10).all
+      @issues += scope.where("LOWER(#{Issue.table_name}.subject) LIKE LOWER(?)", "%#{q}%").order("#{Issue.table_name}.id DESC").limit(10).all
       @issues.compact!
     end
     render :layout => false
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/boards_controller.rb
--- a/app/controllers/boards_controller.rb
+++ b/app/controllers/boards_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -37,17 +37,17 @@
     respond_to do |format|
       format.html {
         sort_init 'updated_on', 'desc'
-        sort_update	'created_on' => "#{Message.table_name}.created_on",
+        sort_update 'created_on' => "#{Message.table_name}.created_on",
                     'replies' => "#{Message.table_name}.replies_count",
                     'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)"
 
         @topic_count = @board.topics.count
-        @topic_pages = Paginator.new self, @topic_count, per_page_option, params['page']
+        @topic_pages = Paginator.new @topic_count, per_page_option, params['page']
         @topics =  @board.topics.
           reorder("#{Message.table_name}.sticky DESC").
           includes(:last_reply).
-          limit(@topic_pages.items_per_page).
-          offset(@topic_pages.current.offset).
+          limit(@topic_pages.per_page).
+          offset(@topic_pages.offset).
           order(sort_clause).
           preload(:author, {:last_reply => :author}).
           all
@@ -55,9 +55,11 @@
         render :action => 'show', :layout => !request.xhr?
       }
       format.atom {
-        @messages = @board.messages.find :all, :order => 'created_on DESC',
-                                               :include => [:author, :board],
-                                               :limit => Setting.feeds_limit.to_i
+        @messages = @board.messages.
+          reorder('created_on DESC').
+          includes(:author, :board).
+          limit(Setting.feeds_limit.to_i).
+          all
         render_feed(@messages, :title => "#{@project}: #{@board}")
       }
     end
@@ -98,7 +100,7 @@
 
 private
   def redirect_to_settings_in_projects
-    redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'boards'
+    redirect_to settings_project_path(@project, :tab => 'boards')
   end
 
   def find_board_if_available
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/calendars_controller.rb
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/comments_controller.rb
--- a/app/controllers/comments_controller.rb
+++ b/app/controllers/comments_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -32,12 +32,12 @@
       flash[:notice] = l(:label_comment_added)
     end
 
-    redirect_to :controller => 'news', :action => 'show', :id => @news
+    redirect_to news_path(@news)
   end
 
   def destroy
     @news.comments.find(params[:comment_id]).destroy
-    redirect_to :controller => 'news', :action => 'show', :id => @news
+    redirect_to news_path(@news)
   end
 
   private
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/context_menus_controller.rb
--- a/app/controllers/context_menus_controller.rb
+++ b/app/controllers/context_menus_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -21,6 +21,7 @@
 
   def issues
     @issues = Issue.visible.all(:conditions => {:id => params[:ids]}, :include => :project)
+    (render_404; return) unless @issues.present?
     if (@issues.size == 1)
       @issue = @issues.first
     end
@@ -74,6 +75,8 @@
   def time_entries
     @time_entries = TimeEntry.all(
        :conditions => {:id => params[:ids]}, :include => :project)
+    (render_404; return) unless @time_entries.present?
+
     @projects = @time_entries.collect(&:project).compact.uniq
     @project = @projects.first if @projects.size == 1
     @activities = TimeEntryActivity.shared.active
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/custom_fields_controller.rb
--- a/app/controllers/custom_fields_controller.rb
+++ b/app/controllers/custom_fields_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -23,7 +23,7 @@
   before_filter :find_custom_field, :only => [:edit, :update, :destroy]
 
   def index
-    @custom_fields_by_type = CustomField.find(:all).group_by {|f| f.class.name }
+    @custom_fields_by_type = CustomField.all.group_by {|f| f.class.name }
     @tab = params[:tab] || 'IssueCustomField'
   end
 
@@ -31,10 +31,10 @@
   end
 
   def create
-    if request.post? and @custom_field.save
+    if @custom_field.save
       flash[:notice] = l(:notice_successful_create)
       call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field)
-      redirect_to :action => 'index', :tab => @custom_field.class.name
+      redirect_to custom_fields_path(:tab => @custom_field.class.name)
     else
       render :action => 'new'
     end
@@ -44,21 +44,22 @@
   end
 
   def update
-    if request.put? and @custom_field.update_attributes(params[:custom_field])
+    if @custom_field.update_attributes(params[:custom_field])
       flash[:notice] = l(:notice_successful_update)
       call_hook(:controller_custom_fields_edit_after_save, :params => params, :custom_field => @custom_field)
-      redirect_to :action => 'index', :tab => @custom_field.class.name
+      redirect_to custom_fields_path(:tab => @custom_field.class.name)
     else
       render :action => 'edit'
     end
   end
 
   def destroy
-    @custom_field.destroy
-    redirect_to :action => 'index', :tab => @custom_field.class.name
-  rescue
-    flash[:error] = l(:error_can_not_delete_custom_field)
-    redirect_to :action => 'index'
+    begin
+      @custom_field.destroy
+    rescue
+      flash[:error] = l(:error_can_not_delete_custom_field)
+    end
+    redirect_to custom_fields_path(:tab => @custom_field.class.name)
   end
 
   private
@@ -67,6 +68,8 @@
     @custom_field = CustomField.new_subclass_instance(params[:type], params[:custom_field])
     if @custom_field.nil?
       render_404
+    else
+      @custom_field.default_value = nil
     end
   end
 
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/documents_controller.rb
--- a/app/controllers/documents_controller.rb
+++ b/app/controllers/documents_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -27,7 +27,7 @@
 
   def index
     @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
-    documents = @project.documents.find :all, :include => [:attachments, :category]
+    documents = @project.documents.includes(:attachments, :category).all
     case @sort_by
     when 'date'
       @grouped = documents.group_by {|d| d.updated_on.to_date }
@@ -43,7 +43,7 @@
   end
 
   def show
-    @attachments = @document.attachments.find(:all, :order => "created_on DESC")
+    @attachments = @document.attachments.all
   end
 
   def new
@@ -58,7 +58,7 @@
     if @document.save
       render_attachment_warning_if_needed(@document)
       flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index', :project_id => @project
+      redirect_to project_documents_path(@project)
     else
       render :action => 'new'
     end
@@ -71,7 +71,7 @@
     @document.safe_attributes = params[:document]
     if request.put? and @document.save
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'show', :id => @document
+      redirect_to document_path(@document)
     else
       render :action => 'edit'
     end
@@ -79,7 +79,7 @@
 
   def destroy
     @document.destroy if request.delete?
-    redirect_to :controller => 'documents', :action => 'index', :project_id => @project
+    redirect_to project_documents_path(@project)
   end
 
   def add_attachment
@@ -89,6 +89,6 @@
     if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added')
       Mailer.attachments_added(attachments[:files]).deliver
     end
-    redirect_to :action => 'show', :id => @document
+    redirect_to document_path(@document)
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/enumerations_controller.rb
--- a/app/controllers/enumerations_controller.rb
+++ b/app/controllers/enumerations_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -46,7 +46,7 @@
   def create
     if request.post? && @enumeration.save
       flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index'
+      redirect_to enumerations_path
     else
       render :action => 'new'
     end
@@ -58,7 +58,7 @@
   def update
     if request.put? && @enumeration.update_attributes(params[:enumeration])
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
+      redirect_to enumerations_path
     else
       render :action => 'edit'
     end
@@ -68,16 +68,16 @@
     if !@enumeration.in_use?
       # No associated objects
       @enumeration.destroy
-      redirect_to :action => 'index'
+      redirect_to enumerations_path
       return
     elsif params[:reassign_to_id]
       if reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id])
         @enumeration.destroy(reassign_to)
-        redirect_to :action => 'index'
+        redirect_to enumerations_path
         return
       end
     end
-    @enumerations = @enumeration.class.all - [@enumeration]
+    @enumerations = @enumeration.class.system.all - [@enumeration]
   end
 
   private
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/files_controller.rb
--- a/app/controllers/files_controller.rb
+++ b/app/controllers/files_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -32,8 +32,8 @@
                 'size' => "#{Attachment.table_name}.filesize",
                 'downloads' => "#{Attachment.table_name}.downloads"
 
-    @containers = [ Project.find(@project.id, :include => :attachments, :order => sort_clause)]
-    @containers += @project.versions.find(:all, :include => :attachments, :order => sort_clause).sort.reverse
+    @containers = [ Project.includes(:attachments).reorder(sort_clause).find(@project.id)]
+    @containers += @project.versions.includes(:attachments).reorder(sort_clause).all.sort.reverse
     render :layout => !request.xhr?
   end
 
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/gantts_controller.rb
--- a/app/controllers/gantts_controller.rb
+++ b/app/controllers/gantts_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/groups_controller.rb
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -84,7 +84,7 @@
     @group.destroy
 
     respond_to do |format|
-      format.html { redirect_to(groups_url) }
+      format.html { redirect_to(groups_path) }
       format.api  { render_api_ok }
     end
   end
@@ -93,7 +93,7 @@
     @users = User.find_all_by_id(params[:user_id] || params[:user_ids])
     @group.users << @users if request.post?
     respond_to do |format|
-      format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
+      format.html { redirect_to edit_group_path(@group, :tab => 'users') }
       format.js
       format.api { render_api_ok }
     end
@@ -102,22 +102,23 @@
   def remove_user
     @group.users.delete(User.find(params[:user_id])) if request.delete?
     respond_to do |format|
-      format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'users' }
+      format.html { redirect_to edit_group_path(@group, :tab => 'users') }
       format.js
       format.api { render_api_ok }
     end
   end
 
   def autocomplete_for_user
-    @users = User.active.not_in_group(@group).like(params[:q]).all(:limit => 100)
-    render :layout => false
+    respond_to do |format|
+      format.js
+    end
   end
 
   def edit_membership
     @membership = Member.edit_membership(params[:membership_id], params[:membership], @group)
     @membership.save if request.post?
     respond_to do |format|
-      format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'memberships' }
+      format.html { redirect_to edit_group_path(@group, :tab => 'memberships') }
       format.js
     end
   end
@@ -125,7 +126,7 @@
   def destroy_membership
     Member.find(params[:membership_id]).destroy if request.post?
     respond_to do |format|
-      format.html { redirect_to :controller => 'groups', :action => 'edit', :id => @group, :tab => 'memberships' }
+      format.html { redirect_to edit_group_path(@group, :tab => 'memberships') }
       format.js
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/issue_categories_controller.rb
--- a/app/controllers/issue_categories_controller.rb
+++ b/app/controllers/issue_categories_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -26,14 +26,14 @@
 
   def index
     respond_to do |format|
-      format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project }
+      format.html { redirect_to_settings_in_projects }
       format.api { @categories = @project.issue_categories.all }
     end
   end
 
   def show
     respond_to do |format|
-      format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project }
+      format.html { redirect_to_settings_in_projects }
       format.api
     end
   end
@@ -55,7 +55,7 @@
       respond_to do |format|
         format.html do
           flash[:notice] = l(:notice_successful_create)
-          redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project
+          redirect_to_settings_in_projects
         end
         format.js
         format.api { render :action => 'show', :status => :created, :location => issue_category_path(@category) }
@@ -78,7 +78,7 @@
       respond_to do |format|
         format.html {
           flash[:notice] = l(:notice_successful_update)
-          redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project
+          redirect_to_settings_in_projects
         }
         format.api { render_api_ok }
       end
@@ -99,7 +99,7 @@
       end
       @category.destroy(reassign_to)
       respond_to do |format|
-        format.html { redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories' }
+        format.html { redirect_to_settings_in_projects }
         format.api { render_api_ok }
       end
       return
@@ -107,7 +107,12 @@
     @categories = @project.issue_categories - [@category]
   end
 
-private
+  private
+
+  def redirect_to_settings_in_projects
+    redirect_to settings_project_path(@project, :tab => 'categories')
+  end
+
   # Wrap ApplicationController's find_model_object method to set
   # @category instead of just @issue_category
   def find_model_object
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/issue_relations_controller.rb
--- a/app/controllers/issue_relations_controller.rb
+++ b/app/controllers/issue_relations_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -48,9 +48,9 @@
     saved = @relation.save
 
     respond_to do |format|
-      format.html { redirect_to :controller => 'issues', :action => 'show', :id => @issue }
+      format.html { redirect_to issue_path(@issue) }
       format.js {
-        @relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
+        @relations = @issue.reload.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
       }
       format.api {
         if saved
@@ -67,7 +67,7 @@
     @relation.destroy
 
     respond_to do |format|
-      format.html { redirect_to issue_path } # TODO : does this really work since @issue is always nil? What is it useful to?
+      format.html { redirect_to issue_path(@relation.issue_from) }
       format.js
       format.api  { render_api_ok }
     end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/issue_statuses_controller.rb
--- a/app/controllers/issue_statuses_controller.rb
+++ b/app/controllers/issue_statuses_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,7 +25,7 @@
   def index
     respond_to do |format|
       format.html {
-        @issue_status_pages, @issue_statuses = paginate :issue_statuses, :per_page => 25, :order => "position"
+        @issue_status_pages, @issue_statuses = paginate IssueStatus.sorted, :per_page => 25
         render :action => "index", :layout => false if request.xhr?
       }
       format.api {
@@ -42,7 +42,7 @@
     @issue_status = IssueStatus.new(params[:issue_status])
     if request.post? && @issue_status.save
       flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index'
+      redirect_to issue_statuses_path
     else
       render :action => 'new'
     end
@@ -56,7 +56,7 @@
     @issue_status = IssueStatus.find(params[:id])
     if request.put? && @issue_status.update_attributes(params[:issue_status])
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
+      redirect_to issue_statuses_path
     else
       render :action => 'edit'
     end
@@ -64,11 +64,11 @@
 
   def destroy
     IssueStatus.find(params[:id]).destroy
-    redirect_to :action => 'index'
+    redirect_to issue_statuses_path
   rescue
     flash[:error] = l(:error_unable_delete_issue_status)
-    redirect_to :action => 'index'
-  end  	
+    redirect_to issue_statuses_path
+  end
 
   def update_issue_done_ratio
     if request.post? && IssueStatus.update_issue_done_ratios
@@ -76,6 +76,6 @@
     else
       flash[:error] =  l(:error_issue_done_ratios_not_updated)
     end
-    redirect_to :action => 'index'
+    redirect_to issue_statuses_path
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/issues_controller.rb
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -21,11 +21,11 @@
 
   before_filter :find_issue, :only => [:show, :edit, :update]
   before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
-  before_filter :find_project, :only => [:new, :create]
+  before_filter :find_project, :only => [:new, :create, :update_form]
   before_filter :authorize, :except => [:index]
   before_filter :find_optional_project, :only => [:index]
   before_filter :check_for_default_issue_status, :only => [:new, :create]
-  before_filter :build_new_issue_from_params, :only => [:new, :create]
+  before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form]
   accept_rss_auth :index, :show
   accept_api_auth :index, :show, :create, :update, :destroy
 
@@ -71,8 +71,8 @@
       end
 
       @issue_count = @query.issue_count
-      @issue_pages = Paginator.new self, @issue_count, @limit, params['page']
-      @offset ||= @issue_pages.current.offset
+      @issue_pages = Paginator.new @issue_count, @limit, params['page']
+      @offset ||= @issue_pages.offset
       @issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
                               :order => sort_clause,
                               :offset => @offset,
@@ -85,8 +85,8 @@
           Issue.load_visible_relations(@issues) if include_in_api_response?('relations')
         }
         format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
-        format.csv  { send_data(issues_to_csv(@issues, @project, @query, params), :type => 'text/csv; header=present', :filename => 'export.csv') }
-        format.pdf  { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'export.pdf') }
+        format.csv  { send_data(query_to_csv(@issues, @query, params), :type => 'text/csv; header=present', :filename => 'issues.csv') }
+        format.pdf  { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'issues.pdf') }
       end
     else
       respond_to do |format|
@@ -132,7 +132,6 @@
   def new
     respond_to do |format|
       format.html { render :action => 'new', :layout => !request.xhr? }
-      format.js { render :partial => 'update_form' }
     end
   end
 
@@ -154,8 +153,12 @@
         format.html {
           render_attachment_warning_if_needed(@issue)
           flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("##{@issue.id}", issue_path(@issue), :title => @issue.subject))
-          redirect_to(params[:continue] ?  { :action => 'new', :project_id => @issue.project, :issue => {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?} } :
-                      { :action => 'show', :id => @issue })
+          if params[:continue]
+            attrs = {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?}
+            redirect_to new_project_issue_path(@issue.project, :issue => attrs)
+          else
+            redirect_to issue_path(@issue)
+          end
         }
         format.api  { render :action => 'show', :status => :created, :location => issue_url(@issue) }
       end
@@ -196,7 +199,7 @@
       flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record?
 
       respond_to do |format|
-        format.html { redirect_back_or_default({:action => 'show', :id => @issue}) }
+        format.html { redirect_back_or_default issue_path(@issue) }
         format.api  { render_api_ok }
       end
     else
@@ -207,6 +210,11 @@
     end
   end
 
+  # Updates the issue form when changing the project, status or tracker
+  # on issue creation/update
+  def update_form
+  end
+
   # Bulk edit/copy a set of issues
   def bulk_edit
     @issues.sort!
@@ -279,12 +287,12 @@
 
     if params[:follow]
       if @issues.size == 1 && moved_issues.size == 1
-        redirect_to :controller => 'issues', :action => 'show', :id => moved_issues.first
+        redirect_to issue_path(moved_issues.first)
       elsif moved_issues.map(&:project).uniq.size == 1
-        redirect_to :controller => 'issues', :action => 'index', :project_id => moved_issues.map(&:project).first
+        redirect_to project_issues_path(moved_issues.map(&:project).first)
       end
     else
-      redirect_back_or_default({:controller => 'issues', :action => 'index', :project_id => @project})
+      redirect_back_or_default _project_issues_path(@project)
     end
   end
 
@@ -317,7 +325,7 @@
       end
     end
     respond_to do |format|
-      format.html { redirect_back_or_default(:action => 'index', :project_id => @project) }
+      format.html { redirect_back_or_default _project_issues_path(@project) }
       format.api  { render_api_ok }
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/journals_controller.rb
--- a/app/controllers/journals_controller.rb
+++ b/app/controllers/journals_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -80,7 +80,7 @@
       @journal.destroy if @journal.details.empty? && @journal.notes.blank?
       call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params})
       respond_to do |format|
-        format.html { redirect_to :controller => 'issues', :action => 'show', :id => @journal.journalized_id }
+        format.html { redirect_to issue_path(@journal.journalized) }
         format.js { render :action => 'update' }
       end
     else
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/mail_handler_controller.rb
--- a/app/controllers/mail_handler_controller.rb
+++ b/app/controllers/mail_handler_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/members_controller.rb
--- a/app/controllers/members_controller.rb
+++ b/app/controllers/members_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -32,8 +32,8 @@
       format.api {
         @offset, @limit = api_offset_and_limit
         @member_count = @project.member_principals.count
-        @member_pages = Paginator.new self, @member_count, @limit, params['page']
-        @offset ||= @member_pages.current.offset
+    @member_pages = Paginator.new @member_count, @limit, params['page']
+    @offset ||= @member_pages.offset
         @members =  @project.member_principals.all(
           :order => "#{Member.table_name}.id",
           :limit  =>  @limit,
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/messages_controller.rb
--- a/app/controllers/messages_controller.rb
+++ b/app/controllers/messages_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -19,6 +19,7 @@
   menu_item :boards
   default_search_scope :messages
   before_filter :find_board, :only => [:new, :preview]
+  before_filter :find_attachments, :only => [:preview]
   before_filter :find_message, :except => [:new, :preview]
   before_filter :authorize, :except => [:preview, :edit, :destroy]
 
@@ -39,11 +40,13 @@
     end
 
     @reply_count = @topic.children.count
-    @reply_pages = Paginator.new self, @reply_count, REPLIES_PER_PAGE, page
-    @replies =  @topic.children.find(:all, :include => [:author, :attachments, {:board => :project}],
-                                           :order => "#{Message.table_name}.created_on ASC",
-                                           :limit => @reply_pages.items_per_page,
-                                           :offset => @reply_pages.current.offset)
+    @reply_pages = Paginator.new @reply_count, REPLIES_PER_PAGE, page
+    @replies =  @topic.children.
+      includes(:author, :attachments, {:board => :project}).
+      reorder("#{Message.table_name}.created_on ASC").
+      limit(@reply_pages.per_page).
+      offset(@reply_pages.offset).
+      all
 
     @reply = Message.new(:subject => "RE: #{@message.subject}")
     render :action => "show", :layout => false if request.xhr?
@@ -115,7 +118,6 @@
 
   def preview
     message = @board.messages.find_by_id(params[:id])
-    @attachements = message.attachments if message
     @text = (params[:message] || params[:reply])[:content]
     @previewed = message
     render :partial => 'common/preview'
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/my_controller.rb
--- a/app/controllers/my_controller.rb
+++ b/app/controllers/my_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -94,7 +94,7 @@
         @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
         set_language_if_valid @user.language
         flash[:notice] = l(:notice_account_updated)
-        redirect_to :action => 'account'
+        redirect_to my_account_path
         return
       end
     end
@@ -104,7 +104,7 @@
   def destroy
     @user = User.current
     unless @user.own_account_deletable?
-      redirect_to :action => 'account'
+      redirect_to my_account_path
       return
     end
 
@@ -123,7 +123,7 @@
     @user = User.current
     unless @user.change_password_allowed?
       flash[:error] = l(:notice_can_t_change_password)
-      redirect_to :action => 'account'
+      redirect_to my_account_path
       return
     end
     if request.post?
@@ -131,7 +131,7 @@
         @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
         if @user.save
           flash[:notice] = l(:notice_account_password_updated)
-          redirect_to :action => 'account'
+          redirect_to my_account_path
         end
       else
         flash[:error] = l(:notice_account_wrong_password)
@@ -149,7 +149,7 @@
       User.current.rss_key
       flash[:notice] = l(:notice_feeds_access_key_reseted)
     end
-    redirect_to :action => 'account'
+    redirect_to my_account_path
   end
 
   # Create a new API key
@@ -162,7 +162,7 @@
       User.current.api_key
       flash[:notice] = l(:notice_api_access_key_reseted)
     end
-    redirect_to :action => 'account'
+    redirect_to my_account_path
   end
 
   # User's page layout configuration
@@ -192,7 +192,7 @@
       @user.pref[:my_page_layout] = layout
       @user.pref.save
     end
-    redirect_to :action => 'page_layout'
+    redirect_to my_page_layout_path
   end
 
   # Remove a block to user's page
@@ -205,7 +205,7 @@
     %w(top left right).each {|f| (layout[f] ||= []).delete block }
     @user.pref[:my_page_layout] = layout
     @user.pref.save
-    redirect_to :action => 'page_layout'
+    redirect_to my_page_layout_path
   end
 
   # Change blocks order on user's page
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/news_controller.rb
--- a/app/controllers/news_controller.rb
+++ b/app/controllers/news_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -40,8 +40,8 @@
     scope = @project ? @project.news.visible : News.visible
 
     @news_count = scope.count
-    @news_pages = Paginator.new self, @news_count, @limit, params['page']
-    @offset ||= @news_pages.current.offset
+    @news_pages = Paginator.new @news_count, @limit, params['page']
+    @offset ||= @news_pages.offset
     @newss = scope.all(:include => [:author, :project],
                                        :order => "#{News.table_name}.created_on DESC",
                                        :offset => @offset,
@@ -73,7 +73,7 @@
     if @news.save
       render_attachment_warning_if_needed(@news)
       flash[:notice] = l(:notice_successful_create)
-      redirect_to :controller => 'news', :action => 'index', :project_id => @project
+      redirect_to project_news_index_path(@project)
     else
       render :action => 'new'
     end
@@ -88,7 +88,7 @@
     if @news.save
       render_attachment_warning_if_needed(@news)
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'show', :id => @news
+      redirect_to news_path(@news)
     else
       render :action => 'edit'
     end
@@ -96,7 +96,7 @@
 
   def destroy
     @news.destroy
-    redirect_to :action => 'index', :project_id => @project
+    redirect_to project_news_index_path(@project)
   end
 
   private
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/previews_controller.rb
--- a/app/controllers/previews_controller.rb
+++ b/app/controllers/previews_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,12 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 class PreviewsController < ApplicationController
-  before_filter :find_project
+  before_filter :find_project, :find_attachments
 
   def issue
     @issue = @project.issues.find_by_id(params[:id]) unless params[:id].blank?
     if @issue
-      @attachements = @issue.attachments
       @description = params[:issue] && params[:issue][:description]
       if @description && @description.gsub(/(\r?\n|\n\r?)/, "\n") == @issue.description.to_s.gsub(/(\r?\n|\n\r?)/, "\n")
         @description = nil
@@ -37,7 +36,6 @@
   def news
     if params[:id].present? && news = News.visible.find_by_id(params[:id])
       @previewed = news
-      @attachments = news.attachments
     end
     @text = (params[:news] ? params[:news][:description] : nil)
     render :partial => 'common/preview'
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/project_enumerations_controller.rb
--- a/app/controllers/project_enumerations_controller.rb
+++ b/app/controllers/project_enumerations_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -29,7 +29,7 @@
       flash[:notice] = l(:notice_successful_update)
     end
 
-    redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project
+    redirect_to settings_project_path(@project, :tab => 'activities')
   end
 
   def destroy
@@ -37,7 +37,6 @@
       time_entry_activity.destroy(time_entry_activity.parent)
     end
     flash[:notice] = l(:notice_successful_update)
-    redirect_to :controller => 'projects', :action => 'settings', :tab => 'activities', :id => @project
+    redirect_to settings_project_path(@project, :tab => 'activities')
   end
-
 end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/projects_controller.rb
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -43,6 +43,7 @@
   helper :repositories
   include RepositoriesHelper
   include ProjectsHelper
+  helper :members
   include ActivitiesHelper
   helper :activities
 
@@ -70,11 +71,10 @@
       format.api  {
         @offset, @limit = api_offset_and_limit
         @project_count = Project.visible.count
-        @projects = Project.visible.all(:offset => @offset, :limit => @limit, :order => 'lft')
+        @projects = Project.visible.offset(@offset).limit(@limit).order('lft').all
       }
       format.atom {
-        projects = Project.visible.find(:all, :order => 'created_on DESC',
-                                              :limit => Setting.feeds_limit.to_i)
+        projects = Project.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all
         render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}")
       }
     end
@@ -91,14 +91,14 @@
   end
 
   def new
-    @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
+    @issue_custom_fields = IssueCustomField.sorted.all
     @trackers = Tracker.sorted.all
     @project = Project.new
     @project.safe_attributes = params[:project]
   end
 
   def create
-    @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
+    @issue_custom_fields = IssueCustomField.sorted.all
     @trackers = Tracker.sorted.all
     @project = Project.new
     @project.safe_attributes = params[:project]
@@ -114,10 +114,12 @@
       respond_to do |format|
         format.html {
           flash[:notice] = l(:notice_successful_create)
-          redirect_to(params[:continue] ?
-            {:controller => 'projects', :action => 'new', :project => {:parent_id => @project.parent_id}.reject {|k,v| v.nil?}} :
-            {:controller => 'projects', :action => 'settings', :id => @project}
-          )
+          if params[:continue]
+            attrs = {:parent_id => @project.parent_id}.reject {|k,v| v.nil?}
+            redirect_to new_project_path(attrs)
+          else
+            redirect_to settings_project_path(@project)
+          end
         }
         format.api  { render :action => 'show', :status => :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) }
       end
@@ -127,15 +129,11 @@
         format.api  { render_validation_errors(@project) }
       end
     end
-
   end
 
   def copy
-    @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
+    @issue_custom_fields = IssueCustomField.sorted.all
     @trackers = Tracker.sorted.all
-    @root_projects = Project.find(:all,
-                                  :conditions => "parent_id IS NULL AND status = #{Project::STATUS_ACTIVE}",
-                                  :order => 'name')
     @source_project = Project.find(params[:id])
     if request.get?
       @project = Project.copy_from(@source_project)
@@ -147,13 +145,13 @@
         if validate_parent_id && @project.copy(@source_project, :only => params[:only])
           @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
           flash[:notice] = l(:notice_successful_create)
-          redirect_to :controller => 'projects', :action => 'settings', :id => @project
+          redirect_to settings_project_path(@project)
         elsif !@project.new_record?
           # Project was created
           # But some objects were not copied due to validation failures
           # (eg. issues from disabled trackers)
           # TODO: inform about that
-          redirect_to :controller => 'projects', :action => 'settings', :id => @project
+          redirect_to settings_project_path(@project)
         end
       end
     end
@@ -164,14 +162,14 @@
 
   # Show @project
   def show
-    if params[:jump]
-      # try to redirect to the requested menu item
-      redirect_to_project_menu_item(@project, params[:jump]) && return
+    # try to redirect to the requested menu item
+    if params[:jump] && redirect_to_project_menu_item(@project, params[:jump])
+      return
     end
 
     @users_by_role = @project.users_by_role
     @subprojects = @project.children.visible.all
-    @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
+    @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").all
     @trackers = @project.rolled_up_trackers
 
     cond = @project.project_condition(Setting.display_subprojects_issues?)
@@ -192,7 +190,7 @@
   end
 
   def settings
-    @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
+    @issue_custom_fields = IssueCustomField.sorted.all
     @issue_category ||= IssueCategory.new
     @member ||= @project.members.new
     @trackers = Tracker.sorted.all
@@ -209,7 +207,7 @@
       respond_to do |format|
         format.html {
           flash[:notice] = l(:notice_successful_update)
-          redirect_to :action => 'settings', :id => @project
+          redirect_to settings_project_path(@project)
         }
         format.api  { render_api_ok }
       end
@@ -235,7 +233,7 @@
   def modules
     @project.enabled_module_names = params[:enabled_module_names]
     flash[:notice] = l(:notice_successful_update)
-    redirect_to :action => 'settings', :id => @project, :tab => 'modules'
+    redirect_to settings_project_path(@project, :tab => 'modules')
   end
 
   def archive
@@ -244,12 +242,12 @@
         flash[:error] = l(:error_can_not_archive_project)
       end
     end
-    redirect_to(url_for(:controller => 'admin', :action => 'projects', :status => params[:status]))
+    redirect_to admin_projects_path(:status => params[:status])
   end
 
   def unarchive
     @project.unarchive if request.post? && !@project.active?
-    redirect_to(url_for(:controller => 'admin', :action => 'projects', :status => params[:status]))
+    redirect_to admin_projects_path(:status => params[:status])
   end
 
   def close
@@ -268,7 +266,7 @@
     if api_request? || params[:confirm]
       @project_to_destroy.destroy
       respond_to do |format|
-        format.html { redirect_to :controller => 'admin', :action => 'projects' }
+        format.html { redirect_to admin_projects_path }
         format.api  { render_api_ok }
       end
     end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/queries_controller.rb
--- a/app/controllers/queries_controller.rb
+++ b/app/controllers/queries_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -32,35 +32,34 @@
       @limit = per_page_option
     end
 
-    @query_count = Query.visible.count
-    @query_pages = Paginator.new self, @query_count, @limit, params['page']
-    @queries = Query.visible.all(:limit => @limit, :offset => @offset, :order => "#{Query.table_name}.name")
+    @query_count = IssueQuery.visible.count
+    @query_pages = Paginator.new @query_count, @limit, params['page']
+    @queries = IssueQuery.visible.all(:limit => @limit, :offset => @offset, :order => "#{Query.table_name}.name")
 
     respond_to do |format|
-      format.html { render :nothing => true }
       format.api
     end
   end
 
   def new
-    @query = Query.new
+    @query = IssueQuery.new
     @query.user = User.current
     @query.project = @project
     @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
-    build_query_from_params
+    @query.build_from_params(params)
   end
 
   def create
-    @query = Query.new(params[:query])
+    @query = IssueQuery.new(params[:query])
     @query.user = User.current
     @query.project = params[:query_is_for_all] ? nil : @project
     @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
-    build_query_from_params
+    @query.build_from_params(params)
     @query.column_names = nil if params[:default_columns]
 
     if @query.save
       flash[:notice] = l(:notice_successful_create)
-      redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
+      redirect_to _project_issues_path(@project, :query_id => @query)
     else
       render :action => 'new', :layout => !request.xhr?
     end
@@ -73,12 +72,12 @@
     @query.attributes = params[:query]
     @query.project = nil if params[:query_is_for_all]
     @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
-    build_query_from_params
+    @query.build_from_params(params)
     @query.column_names = nil if params[:default_columns]
 
     if @query.save
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
+      redirect_to _project_issues_path(@project, :query_id => @query)
     else
       render :action => 'edit'
     end
@@ -86,12 +85,12 @@
 
   def destroy
     @query.destroy
-    redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1
+    redirect_to _project_issues_path(@project, :set_filter => 1)
   end
 
 private
   def find_query
-    @query = Query.find(params[:id])
+    @query = IssueQuery.find(params[:id])
     @project = @query.project
     render_403 unless @query.editable_by?(User.current)
   rescue ActiveRecord::RecordNotFound
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/reports_controller.rb
--- a/app/controllers/reports_controller.rb
+++ b/app/controllers/reports_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -90,6 +90,6 @@
   private
 
   def find_issue_statuses
-    @statuses = IssueStatus.find(:all, :order => 'position')
+    @statuses = IssueStatus.sorted.all
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/repositories_controller.rb
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -139,13 +139,14 @@
 
   def revisions
     @changeset_count = @repository.changesets.count
-    @changeset_pages = Paginator.new self, @changeset_count,
+    @changeset_pages = Paginator.new @changeset_count,
                                      per_page_option,
                                      params['page']
-    @changesets = @repository.changesets.find(:all,
-                       :limit  =>  @changeset_pages.items_per_page,
-                       :offset =>  @changeset_pages.current.offset,
-                       :include => [:user, :repository, :parents])
+    @changesets = @repository.changesets.
+      limit(@changeset_pages.per_page).
+      offset(@changeset_pages.offset).
+      includes(:user, :repository, :parents).
+      all
 
     respond_to do |format|
       format.html { render :layout => false if request.xhr? }
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/roles_controller.rb
--- a/app/controllers/roles_controller.rb
+++ b/app/controllers/roles_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -26,7 +26,7 @@
   def index
     respond_to do |format|
       format.html {
-        @role_pages, @roles = paginate :roles, :per_page => 25, :order => 'builtin, position'
+        @role_pages, @roles = paginate Role.sorted, :per_page => 25
         render :action => "index", :layout => false if request.xhr?
       }
       format.api {
@@ -58,7 +58,7 @@
         @role.workflow_rules.copy(copy_from)
       end
       flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index'
+      redirect_to roles_path
     else
       @roles = Role.sorted.all
       render :action => 'new'
@@ -71,7 +71,7 @@
   def update
     if request.put? and @role.update_attributes(params[:role])
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
+      redirect_to roles_path
     else
       render :action => 'edit'
     end
@@ -79,10 +79,10 @@
 
   def destroy
     @role.destroy
-    redirect_to :action => 'index'
+    redirect_to roles_path
   rescue
     flash[:error] =  l(:error_can_not_remove_role)
-    redirect_to :action => 'index'
+    redirect_to roles_path
   end
 
   def permissions
@@ -94,7 +94,7 @@
         role.save
       end
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
+      redirect_to roles_path
     end
   end
 
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/search_controller.rb
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,9 +18,6 @@
 class SearchController < ApplicationController
   before_filter :find_optional_project
 
-  helper :messages
-  include MessagesHelper
-
   def index
     @question = params[:q] || ""
     @question.strip!
@@ -43,8 +40,8 @@
     begin; offset = params[:offset].to_time if params[:offset]; rescue; end
 
     # quick jump to an issue
-    if @question.match(/^#?(\d+)$/) && Issue.visible.find_by_id($1.to_i)
-      redirect_to :controller => "issues", :action => "show", :id => $1
+    if (m = @question.match(/^#?(\d+)$/)) && (issue = Issue.visible.find_by_id(m[1].to_i))
+      redirect_to issue_path(issue)
       return
     end
 
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/settings_controller.rb
--- a/app/controllers/settings_controller.rb
+++ b/app/controllers/settings_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -19,6 +19,8 @@
   layout 'admin'
   menu_item :plugins, :only => :plugin
 
+  helper :queries
+
   before_filter :require_admin
 
   def index
@@ -36,7 +38,7 @@
         Setting[name] = value
       end
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'edit', :tab => params[:tab]
+      redirect_to settings_path(:tab => params[:tab])
     else
       @options = {}
       user_format = User::USER_FORMATS.collect{|key, value| [key, value[:setting_order]]}.sort{|a, b| a[1] <=> b[1]}
@@ -52,10 +54,15 @@
 
   def plugin
     @plugin = Redmine::Plugin.find(params[:id])
+    unless @plugin.configurable?
+      render_404
+      return
+    end
+
     if request.post?
       Setting.send "plugin_#{@plugin.id}=", params[:settings]
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'plugin', :id => @plugin.id
+      redirect_to plugin_settings_path(@plugin)
     else
       @partial = @plugin.settings[:partial]
       @settings = Setting.send "plugin_#{@plugin.id}"
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/sys_controller.rb
--- a/app/controllers/sys_controller.rb
+++ b/app/controllers/sys_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/timelog_controller.rb
--- a/app/controllers/timelog_controller.rb
+++ b/app/controllers/timelog_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,41 +30,34 @@
   accept_rss_auth :index
   accept_api_auth :index, :show, :create, :update, :destroy
 
+  rescue_from Query::StatementInvalid, :with => :query_statement_invalid
+
   helper :sort
   include SortHelper
   helper :issues
   include TimelogHelper
   helper :custom_fields
   include CustomFieldsHelper
+  helper :queries
+  include QueriesHelper
 
   def index
-    sort_init 'spent_on', 'desc'
-    sort_update 'spent_on' => ['spent_on', "#{TimeEntry.table_name}.created_on"],
-                'user' => 'user_id',
-                'activity' => 'activity_id',
-                'project' => "#{Project.table_name}.name",
-                'issue' => 'issue_id',
-                'hours' => 'hours'
+    @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
+    scope = time_entry_scope
 
-    retrieve_date_range
-
-    scope = TimeEntry.visible.spent_between(@from, @to)
-    if @issue
-      scope = scope.on_issue(@issue)
-    elsif @project
-      scope = scope.on_project(@project, Setting.display_subprojects_issues?)
-    end
+    sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria)
+    sort_update(@query.sortable_columns)
 
     respond_to do |format|
       format.html {
         # Paginate results
         @entry_count = scope.count
-        @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
+        @entry_pages = Paginator.new @entry_count, per_page_option, params['page']
         @entries = scope.all(
           :include => [:project, :activity, :user, {:issue => :tracker}],
           :order => sort_clause,
-          :limit  =>  @entry_pages.items_per_page,
-          :offset =>  @entry_pages.current.offset
+          :limit  =>  @entry_pages.per_page,
+          :offset =>  @entry_pages.offset
         )
         @total_hours = scope.sum(:hours).to_f
 
@@ -94,14 +87,16 @@
           :include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
           :order => sort_clause
         )
-        send_data(entries_to_csv(@entries), :type => 'text/csv; header=present', :filename => 'timelog.csv')
+        send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv')
       }
     end
   end
 
   def report
-    retrieve_date_range
-    @report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], @from, @to)
+    @query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
+    scope = time_entry_scope
+
+    @report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], scope)
 
     respond_to do |format|
       format.html { render :layout => !request.xhr? }
@@ -134,16 +129,24 @@
           flash[:notice] = l(:notice_successful_create)
           if params[:continue]
             if params[:project_id]
-              redirect_to :action => 'new', :project_id => @time_entry.project, :issue_id => @time_entry.issue,
+              options = {
                 :time_entry => {:issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
                 :back_url => params[:back_url]
+              }
+              if @time_entry.issue
+                redirect_to new_project_issue_time_entry_path(@time_entry.project, @time_entry.issue, options)
+              else
+                redirect_to new_project_time_entry_path(@time_entry.project, options)
+              end
             else
-              redirect_to :action => 'new',
+              options = {
                 :time_entry => {:project_id => @time_entry.project_id, :issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
                 :back_url => params[:back_url]
+              }
+              redirect_to new_time_entry_path(options)
             end
           else
-            redirect_back_or_default :action => 'index', :project_id => @time_entry.project
+            redirect_back_or_default project_time_entries_path(@time_entry.project)
           end
         }
         format.api  { render :action => 'show', :status => :created, :location => time_entry_url(@time_entry) }
@@ -169,7 +172,7 @@
       respond_to do |format|
         format.html {
           flash[:notice] = l(:notice_successful_update)
-          redirect_back_or_default :action => 'index', :project_id => @time_entry.project
+          redirect_back_or_default project_time_entries_path(@time_entry.project)
         }
         format.api  { render_api_ok }
       end
@@ -200,7 +203,7 @@
       end
     end
     set_flash_from_bulk_time_entry_save(@time_entries, unsaved_time_entry_ids)
-    redirect_back_or_default({:controller => 'timelog', :action => 'index', :project_id => @projects.first})
+    redirect_back_or_default project_time_entries_path(@projects.first)
   end
 
   def destroy
@@ -219,7 +222,7 @@
         else
           flash[:error] = l(:notice_unable_delete_time_entry)
         end
-        redirect_back_or_default(:action => 'index', :project_id => @projects.first)
+        redirect_back_or_default project_time_entries_path(@projects.first)
       }
       format.api  {
         if destroyed
@@ -291,51 +294,15 @@
     end
   end
 
-  # Retrieves the date range based on predefined ranges or specific from/to param dates
-  def retrieve_date_range
-    @free_period = false
-    @from, @to = nil, nil
-
-    if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?)
-      case params[:period].to_s
-      when 'today'
-        @from = @to = Date.today
-      when 'yesterday'
-        @from = @to = Date.today - 1
-      when 'current_week'
-        @from = Date.today - (Date.today.cwday - 1)%7
-        @to = @from + 6
-      when 'last_week'
-        @from = Date.today - 7 - (Date.today.cwday - 1)%7
-        @to = @from + 6
-      when 'last_2_weeks'
-        @from = Date.today - 14 - (Date.today.cwday - 1)%7
-        @to = @from + 13
-      when '7_days'
-        @from = Date.today - 7
-        @to = Date.today
-      when 'current_month'
-        @from = Date.civil(Date.today.year, Date.today.month, 1)
-        @to = (@from >> 1) - 1
-      when 'last_month'
-        @from = Date.civil(Date.today.year, Date.today.month, 1) << 1
-        @to = (@from >> 1) - 1
-      when '30_days'
-        @from = Date.today - 30
-        @to = Date.today
-      when 'current_year'
-        @from = Date.civil(Date.today.year, 1, 1)
-        @to = Date.civil(Date.today.year, 12, 31)
-      end
-    elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?))
-      begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end
-      begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end
-      @free_period = true
-    else
-      # default
+  # Returns the TimeEntry scope for index and report actions
+  def time_entry_scope
+    scope = TimeEntry.visible.where(@query.statement)
+    if @issue
+      scope = scope.on_issue(@issue)
+    elsif @project
+      scope = scope.on_project(@project, Setting.display_subprojects_issues?)
     end
-
-    @from, @to = @to, @from if @from && @to && @from > @to
+    scope
   end
 
   def parse_params_for_bulk_time_entry_attributes(params)
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/trackers_controller.rb
--- a/app/controllers/trackers_controller.rb
+++ b/app/controllers/trackers_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,7 +25,7 @@
   def index
     respond_to do |format|
       format.html {
-        @tracker_pages, @trackers = paginate :trackers, :per_page => 10, :order => 'position'
+        @tracker_pages, @trackers = paginate Tracker.sorted, :per_page => 25
         render :action => "index", :layout => false if request.xhr?
       }
       format.api {
@@ -36,19 +36,19 @@
 
   def new
     @tracker ||= Tracker.new(params[:tracker])
-    @trackers = Tracker.find :all, :order => 'position'
-    @projects = Project.find(:all)
+    @trackers = Tracker.sorted.all
+    @projects = Project.all
   end
 
   def create
     @tracker = Tracker.new(params[:tracker])
-    if request.post? and @tracker.save
+    if @tracker.save
       # workflow copy
       if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from]))
         @tracker.workflow_rules.copy(copy_from)
       end
       flash[:notice] = l(:notice_successful_create)
-      redirect_to :action => 'index'
+      redirect_to trackers_path
       return
     end
     new
@@ -57,14 +57,14 @@
 
   def edit
     @tracker ||= Tracker.find(params[:id])
-    @projects = Project.find(:all)
+    @projects = Project.all
   end
 
   def update
     @tracker = Tracker.find(params[:id])
-    if request.put? and @tracker.update_attributes(params[:tracker])
+    if @tracker.update_attributes(params[:tracker])
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'index'
+      redirect_to trackers_path
       return
     end
     edit
@@ -78,7 +78,7 @@
     else
       @tracker.destroy
     end
-    redirect_to :action => 'index'
+    redirect_to trackers_path
   end
 
   def fields
@@ -92,7 +92,7 @@
         end
       end
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'fields'
+      redirect_to fields_trackers_path
       return
     end
     @trackers = Tracker.sorted.all
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/users_controller.rb
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -45,12 +45,9 @@
     scope = scope.in_group(params[:group_id]) if params[:group_id].present?
 
     @user_count = scope.count
-    @user_pages = Paginator.new self, @user_count, @limit, params['page']
-    @offset ||= @user_pages.current.offset
-    @users =  scope.find :all,
-                        :order => sort_clause,
-                        :limit  =>  @limit,
-                        :offset =>  @offset
+    @user_pages = Paginator.new @user_count, @limit, params['page']
+    @offset ||= @user_pages.offset
+    @users =  scope.order(sort_clause).limit(@limit).offset(@offset).all
 
     respond_to do |format|
       format.html {
@@ -58,7 +55,7 @@
         render :layout => !request.xhr?
       }
       format.api
-    end	
+    end
   end
 
   def show
@@ -89,7 +86,7 @@
 
   def new      
     @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option)
-    @auth_sources = AuthSource.find(:all)
+    @auth_sources = AuthSource.all
 
     @ssamr_user_details = SsamrUserDetail.new
   end
@@ -124,15 +121,16 @@
       respond_to do |format|
         format.html {
           flash[:notice] = l(:notice_user_successful_create, :id => view_context.link_to(@user.login, user_path(@user)))
-          redirect_to(params[:continue] ?
-            {:controller => 'users', :action => 'new'} :
-            {:controller => 'users', :action => 'edit', :id => @user}
-          )
+          if params[:continue]
+            redirect_to new_user_path
+          else
+            redirect_to edit_user_path(@user)
+          end
         }
         format.api  { render :action => 'show', :status => :created, :location => user_url(@user) }
       end
     else
-      @auth_sources = AuthSource.find(:all)
+      @auth_sources = AuthSource.all
       # Clear password input
       @user.password = @user.password_confirmation = nil
 
@@ -144,7 +142,7 @@
   end
 
   def edit
-    
+    @auth_sources = AuthSource.all
     @ssamr_user_details = @user.ssamr_user_detail
     
     if @user.ssamr_user_detail == nil
@@ -153,7 +151,6 @@
       @selected_institution_id = @user.ssamr_user_detail.institution_id.to_i    
     end
     
-    @auth_sources = AuthSource.find(:all)
     @membership ||= Member.new
   end
 
@@ -208,7 +205,7 @@
         format.api  { render_api_ok }
       end
     else
-      @auth_sources = AuthSource.find(:all)
+      @auth_sources = AuthSource.all
       @membership ||= Member.new
       # Clear password input
       @user.password = @user.password_confirmation = nil
@@ -223,7 +220,7 @@
   def destroy
     @user.destroy
     respond_to do |format|
-      format.html { redirect_back_or_default(users_url) }
+      format.html { redirect_back_or_default(users_path) }
       format.api  { render_api_ok }
     end
   end
@@ -232,7 +229,7 @@
     @membership = Member.edit_membership(params[:membership_id], params[:membership], @user)
     @membership.save
     respond_to do |format|
-      format.html { redirect_to :controller => 'users', :action => 'edit', :id => @user, :tab => 'memberships' }
+      format.html { redirect_to edit_user_path(@user, :tab => 'memberships') }
       format.js
     end
   end
@@ -243,7 +240,7 @@
       @membership.destroy
     end
     respond_to do |format|
-      format.html { redirect_to :controller => 'users', :action => 'edit', :id => @user, :tab => 'memberships' }
+      format.html { redirect_to edit_user_path(@user, :tab => 'memberships') }
       format.js
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/versions_controller.rb
--- a/app/controllers/versions_controller.rb
+++ b/app/controllers/versions_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -31,7 +31,7 @@
   def index
     respond_to do |format|
       format.html {
-        @trackers = @project.trackers.find(:all, :order => 'position')
+        @trackers = @project.trackers.sorted.all
         retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?})
         @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
         project_ids = @with_subprojects ? @project.self_and_descendants.collect(&:id) : [@project.id]
@@ -64,9 +64,10 @@
   def show
     respond_to do |format|
       format.html {
-        @issues = @version.fixed_issues.visible.find(:all,
-          :include => [:status, :tracker, :priority],
-          :order => "#{Tracker.table_name}.position, #{Issue.table_name}.id")
+        @issues = @version.fixed_issues.visible.
+          includes(:status, :tracker, :priority).
+          reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id").
+          all
       }
       format.api
     end
@@ -95,7 +96,7 @@
         respond_to do |format|
           format.html do
             flash[:notice] = l(:notice_successful_create)
-            redirect_back_or_default :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
+            redirect_back_or_default settings_project_path(@project, :tab => 'versions')
           end
           format.js
           format.api do
@@ -124,7 +125,7 @@
         respond_to do |format|
           format.html {
             flash[:notice] = l(:notice_successful_update)
-            redirect_back_or_default :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
+            redirect_back_or_default settings_project_path(@project, :tab => 'versions')
           }
           format.api  { render_api_ok }
         end
@@ -141,21 +142,21 @@
     if request.put?
       @project.close_completed_versions
     end
-    redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
+    redirect_to settings_project_path(@project, :tab => 'versions')
   end
 
   def destroy
     if @version.fixed_issues.empty?
       @version.destroy
       respond_to do |format|
-        format.html { redirect_back_or_default :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project }
+        format.html { redirect_back_or_default settings_project_path(@project, :tab => 'versions') }
         format.api  { render_api_ok }
       end
     else
       respond_to do |format|
         format.html {
           flash[:error] = l(:notice_unable_delete_version)
-          redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
+          redirect_to settings_project_path(@project, :tab => 'versions')
         }
         format.api  { head :unprocessable_entity }
       end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/watchers_controller.rb
--- a/app/controllers/watchers_controller.rb
+++ b/app/controllers/watchers_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,35 +16,36 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 class WatchersController < ApplicationController
-  before_filter :find_project
-  before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch]
-  before_filter :authorize, :only => [:new, :destroy]
+  before_filter :require_login, :find_watchables, :only => [:watch, :unwatch]
 
   def watch
-    if @watched.respond_to?(:visible?) && !@watched.visible?(User.current)
-      render_403
-    else
-      set_watcher(User.current, true)
-    end
+    set_watcher(@watchables, User.current, true)
   end
 
   def unwatch
-    set_watcher(User.current, false)
+    set_watcher(@watchables, User.current, false)
   end
 
+  before_filter :find_project, :authorize, :only => [:new, :create, :append, :destroy, :autocomplete_for_user]
+  accept_api_auth :create, :destroy
+
   def new
   end
 
   def create
-    if params[:watcher].is_a?(Hash) && request.post?
-      user_ids = params[:watcher][:user_ids] || [params[:watcher][:user_id]]
-      user_ids.each do |user_id|
-        Watcher.create(:watchable => @watched, :user_id => user_id)
-      end
+    user_ids = []
+    if params[:watcher].is_a?(Hash)
+      user_ids << (params[:watcher][:user_ids] || params[:watcher][:user_id])
+    else
+      user_ids << params[:user_id]
+    end
+    user_ids.flatten.compact.uniq.each do |user_id|
+      Watcher.create(:watchable => @watched, :user_id => user_id)
     end
     respond_to do |format|
       format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}}
       format.js
+      format.api { render_api_ok }
     end
   end
 
@@ -56,22 +57,24 @@
   end
 
   def destroy
-    @watched.set_watcher(User.find(params[:user_id]), false) if request.post?
+    @watched.set_watcher(User.find(params[:user_id]), false)
     respond_to do |format|
       format.html { redirect_to :back }
       format.js
+      format.api { render_api_ok }
     end
   end
 
   def autocomplete_for_user
-    @users = User.active.like(params[:q]).find(:all, :limit => 100)
+    @users = User.active.sorted.like(params[:q]).limit(100).all
     if @watched
       @users -= @watched.watcher_users
     end
     render :layout => false
   end
 
-private
+  private
+
   def find_project
     if params[:object_type] && params[:object_id]
       klass = Object.const_get(params[:object_type].camelcase)
@@ -85,11 +88,22 @@
     render_404
   end
 
-  def set_watcher(user, watching)
-    @watched.set_watcher(user, watching)
+  def find_watchables
+    klass = Object.const_get(params[:object_type].camelcase) rescue nil
+    if klass && klass.respond_to?('watched_by')
+      @watchables = klass.find_all_by_id(Array.wrap(params[:object_id]))
+      raise Unauthorized if @watchables.any? {|w| w.respond_to?(:visible?) && !w.visible?}
+    end
+    render_404 unless @watchables.present?
+  end
+
+  def set_watcher(watchables, user, watching)
+    watchables.each do |watchable|
+      watchable.set_watcher(user, watching)
+    end
     respond_to do |format|
       format.html { redirect_to_referer_or {render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true}}
-      format.js { render :partial => 'set_watcher', :locals => {:user => user, :watched => @watched} }
+      format.js { render :partial => 'set_watcher', :locals => {:user => user, :watched => watchables} }
     end
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/welcome_controller.rb
--- a/app/controllers/welcome_controller.rb
+++ b/app/controllers/welcome_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/wiki_controller.rb
--- a/app/controllers/wiki_controller.rb
+++ b/app/controllers/wiki_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -37,6 +37,7 @@
   before_filter :find_existing_or_new_page, :only => [:show, :edit, :update]
   before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version]
   accept_api_auth :index, :show, :update, :destroy
+  before_filter :find_attachments, :only => [:preview]
 
   helper :attachments
   include AttachmentsHelper
@@ -159,10 +160,10 @@
       call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
 
       respond_to do |format|
-        format.html { redirect_to :action => 'show', :project_id => @project, :id => @page.title }
+        format.html { redirect_to project_wiki_page_path(@project, @page.title) }
         format.api {
           if was_new_page
-            render :action => 'show', :status => :created, :location => url_for(:controller => 'wiki', :action => 'show', :project_id => @project, :id => @page.title)
+            render :action => 'show', :status => :created, :location => project_wiki_page_path(@project, @page.title)
           else
             render_api_ok
           end
@@ -199,25 +200,26 @@
     @original_title = @page.pretty_title
     if request.post? && @page.update_attributes(params[:wiki_page])
       flash[:notice] = l(:notice_successful_update)
-      redirect_to :action => 'show', :project_id => @project, :id => @page.title
+      redirect_to project_wiki_page_path(@project, @page.title)
     end
   end
 
   def protect
     @page.update_attribute :protected, params[:protected]
-    redirect_to :action => 'show', :project_id => @project, :id => @page.title
+    redirect_to project_wiki_page_path(@project, @page.title)
   end
 
   # show page history
   def history
     @version_count = @page.content.versions.count
-    @version_pages = Paginator.new self, @version_count, per_page_option, params['page']
+    @version_pages = Paginator.new @version_count, per_page_option, params['page']
     # don't load text
-    @versions = @page.content.versions.find :all,
-                                            :select => "id, author_id, comments, updated_on, version",
-                                            :order => 'version DESC',
-                                            :limit  =>  @version_pages.items_per_page + 1,
-                                            :offset =>  @version_pages.current.offset
+    @versions = @page.content.versions.
+      select("id, author_id, comments, updated_on, version").
+      reorder('version DESC').
+      limit(@version_pages.per_page + 1).
+      offset(@version_pages.offset).
+      all
 
     render :layout => false if request.xhr?
   end
@@ -260,7 +262,7 @@
     end
     @page.destroy
     respond_to do |format|
-      format.html { redirect_to :action => 'index', :project_id => @project }
+      format.html { redirect_to project_wiki_index_path(@project) }
       format.api { render_api_ok }
     end
   end
@@ -270,7 +272,7 @@
 
     @content = @page.content_for_version(params[:version])
     @content.destroy
-    redirect_to_referer_or :action => 'history', :id => @page.title, :project_id => @project
+    redirect_to_referer_or history_project_wiki_page_path(@project, @page.title)
   end
 
   # Export wiki to a single pdf or html file
@@ -292,7 +294,7 @@
     # page is nil when previewing a new page
     return render_403 unless page.nil? || editable?(page)
     if page
-      @attachements = page.attachments
+      @attachments += page.attachments
       @previewed = page.content
     end
     @text = params[:content][:text]
@@ -349,6 +351,6 @@
   end
 
   def load_pages_for_index
-    @pages = @wiki.pages.with_updated_on.order("#{WikiPage.table_name}.title").includes(:wiki => :project).includes(:parent).all
+    @pages = @wiki.pages.with_updated_on.reorder("#{WikiPage.table_name}.title").includes(:wiki => :project).includes(:parent).all
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/wikis_controller.rb
--- a/app/controllers/wikis_controller.rb
+++ b/app/controllers/wikis_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,7 +30,7 @@
   def destroy
     if request.post? && params[:confirm] && @project.wiki
       @project.wiki.destroy
-      redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'wiki'
+      redirect_to settings_project_path(@project, :tab => 'wiki')
     end
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/controllers/workflows_controller.rb
--- a/app/controllers/workflows_controller.rb
+++ b/app/controllers/workflows_controller.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -38,7 +38,7 @@
         }
       }
       if @role.save
-        redirect_to :action => 'edit', :role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only]
+        redirect_to workflows_edit_path(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
         return
       end
     end
@@ -64,7 +64,7 @@
 
     if request.post? && @role && @tracker
       WorkflowPermission.replace_permissions(@tracker, @role, params[:permissions] || {})
-      redirect_to :action => 'permissions', :role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only]
+      redirect_to workflows_permissions_path(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
       return
     end
 
@@ -106,12 +106,12 @@
     if request.post?
       if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?)
         flash.now[:error] = l(:error_workflow_copy_source)
-      elsif @target_trackers.nil? || @target_roles.nil?
+      elsif @target_trackers.blank? || @target_roles.blank?
         flash.now[:error] = l(:error_workflow_copy_target)
       else
         WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles)
         flash[:notice] = l(:notice_successful_update)
-        redirect_to :action => 'copy', :source_tracker_id => @source_tracker, :source_role_id => @source_role
+        redirect_to workflows_copy_path(:source_tracker_id => @source_tracker, :source_role_id => @source_role)
       end
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/account_helper.rb
--- a/app/helpers/account_helper.rb
+++ b/app/helpers/account_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/activities_helper.rb
--- a/app/helpers/activities_helper.rb
+++ b/app/helpers/activities_helper.rb
@@ -1,3 +1,21 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 module ActivitiesHelper
 
@@ -147,5 +165,18 @@
     threshold = insthash.values.sort.last(count).first
     insthash.keys.select { |k| insthash[k] >= threshold }.sample(count)
   end
+  
+  def sort_activity_events(events)
+    events_by_group = events.group_by(&:event_group)
+    sorted_events = []
+    events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each do |event|
+      if group_events = events_by_group.delete(event.event_group)
+        group_events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each_with_index do |e, i|
+          sorted_events << [e, i > 0]
+        end
+      end
+    end
+    sorted_events
+  end
 
 end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/admin_helper.rb
--- a/app/helpers/admin_helper.rb
+++ b/app/helpers/admin_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/application_helper.rb
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,6 +24,7 @@
   include Redmine::WikiFormatting::Macros::Definitions
   include Redmine::I18n
   include GravatarHelper::PublicMethods
+  include Redmine::Pagination::Helper
 
   extend Forwardable
   def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
@@ -90,14 +91,10 @@
   # * :download - Force download (default: false)
   def link_to_attachment(attachment, options={})
     text = options.delete(:text) || attachment.filename
-    action = options.delete(:download) ? 'download' : 'show'
-    opt_only_path = {}
-    opt_only_path[:only_path] = (options[:only_path] == false ? false : true)
-    options.delete(:only_path)
-    link_to(h(text),
-           {:controller => 'attachments', :action => action,
-            :id => attachment, :filename => attachment.filename}.merge(opt_only_path),
-           options)
+    route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path
+    html_options = options.slice!(:only_path)
+    url = send(route_method, attachment, attachment.filename, options)
+    link_to text, url, html_options
   end
 
   # Generates a link to a SCM revision
@@ -119,13 +116,11 @@
   # Generates a link to a message
   def link_to_message(message, options={}, html_options = nil)
     link_to(
-      h(truncate(message.subject, :length => 60)),
-      { :controller => 'messages', :action => 'show',
-        :board_id => message.board_id,
-        :id => (message.parent_id || message.id),
+      truncate(message.subject, :length => 60),
+      board_message_path(message.board_id, message.parent_id || message.id, {
         :r => (message.parent_id && message.id),
         :anchor => (message.parent_id ? "message-#{message.id}" : nil)
-      }.merge(options),
+      }.merge(options)),
       html_options
     )
   end
@@ -134,16 +129,29 @@
   # Examples:
   #
   #   link_to_project(project)                          # => link to the specified project overview
-  #   link_to_project(project, :action=>'settings')     # => link to project settings
   #   link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options
   #   link_to_project(project, {}, :class => "project") # => html options with default url (project overview)
   #
   def link_to_project(project, options={}, html_options = nil)
     if project.archived?
-      h(project)
+      h(project.name)
+    elsif options.key?(:action)
+      ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0."
+      url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
+      link_to project.name, url, html_options
     else
-      url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
-      link_to(h(project), url, html_options)
+      link_to project.name, project_path(project, options), html_options
+    end
+  end
+
+  # Generates a link to a project settings if active
+  def link_to_project_settings(project, options={}, html_options=nil)
+    if project.active?
+      link_to project.name, settings_project_path(project, options), html_options
+    elsif project.archived?
+      h(project.name)
+    else
+      link_to project.name, project_path(project, options), html_options
     end
   end
 
@@ -152,8 +160,8 @@
   end
 
   def thumbnail_tag(attachment)
-    link_to image_tag(url_for(:controller => 'attachments', :action => 'thumbnail', :id => attachment)),
-      {:controller => 'attachments', :action => 'show', :id => attachment, :filename => attachment.filename},
+    link_to image_tag(thumbnail_path(attachment)),
+      named_attachment_path(attachment, attachment.filename),
       :title => attachment.filename
   end
 
@@ -187,7 +195,7 @@
 
   def format_version_name(version)
     if version.project == @project
-    	h(version)
+      h(version)
     else
       h("#{version.project} - #{version}")
     end
@@ -341,7 +349,7 @@
   def options_for_membership_project_select(principal, projects)
     options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
     options << project_tree_options_for_select(projects) do |p|
-      {:disabled => principal.projects.include?(p)}
+      {:disabled => principal.projects.to_a.include?(p)}
     end
     options
   end
@@ -397,59 +405,6 @@
     str.blank? ? nil : str
   end
 
-  def pagination_links_full(paginator, count=nil, options={})
-    page_param = options.delete(:page_param) || :page
-    per_page_links = options.delete(:per_page_links)
-    url_param = params.dup
-
-    html = ''
-    if paginator.current.previous
-      # \xc2\xab(utf-8) = &#171;
-      html << link_to_content_update(
-                   "\xc2\xab " + l(:label_previous),
-                   url_param.merge(page_param => paginator.current.previous)) + ' '
-    end
-
-    html << (pagination_links_each(paginator, options) do |n|
-      link_to_content_update(n.to_s, url_param.merge(page_param => n))
-    end || '')
-
-    if paginator.current.next
-      # \xc2\xbb(utf-8) = &#187;
-      html << ' ' + link_to_content_update(
-                      (l(:label_next) + " \xc2\xbb"),
-                      url_param.merge(page_param => paginator.current.next))
-    end
-
-    unless count.nil?
-      html << " (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})"
-      if per_page_links != false && links = per_page_links(paginator.items_per_page, count)
-	      html << " | #{links}"
-      end
-    end
-
-    html.html_safe
-  end
-
-  def per_page_links(selected=nil, item_count=nil)
-    values = Setting.per_page_options_array
-    if item_count && values.any?
-      if item_count > values.first
-        max = values.detect {|value| value >= item_count} || item_count
-      else
-        max = item_count
-      end
-      values = values.select {|value| value <= max || value == selected}
-    end
-    if values.empty? || (values.size == 1 && values.first == selected)
-      return nil
-    end
-    links = values.collect do |n|
-      n == selected ? n : link_to_content_update(n, params.merge(:per_page => n))
-    end
-    l(:label_display_per_page, links.join(', '))
-  end
-
   def reorder_links(name, url, method = :post)
     link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)),
             url.merge({"#{name}[move_to]" => 'highest'}),
@@ -529,7 +484,11 @@
   end
 
   def accesskey(s)
-    Redmine::AccessKeys.key_for s
+    @used_accesskeys ||= []
+    key = Redmine::AccessKeys.key_for(s)
+    return nil if @used_accesskeys.include?(key)
+    @used_accesskeys << key
+    key
   end
 
   # Formats text according to system settings.
@@ -617,8 +576,7 @@
         filename, ext, alt, alttext = $1.downcase, $2, $3, $4
         # search for the picture in attachments
         if found = Attachment.latest_attach(attachments, filename)
-          image_url = url_for :only_path => only_path, :controller => 'attachments',
-                              :action => 'download', :id => found
+          image_url = download_named_attachment_path(found, found.filename, :only_path => only_path)
           desc = found.description.to_s.gsub('"', '')
           if !desc.blank? && alttext.blank?
             alt = " title=\"#{desc}\" alt=\"#{desc}\""
@@ -647,9 +605,9 @@
       esc, all, page, title = $1, $2, $3, $5
       if esc.nil?
         if page =~ /^([^\:]+)\:(.*)$/
-          link_project = Project.find_by_identifier($1) || Project.find_by_name($1)
-          page = $2
-          title ||= $1 if page.blank?
+          identifier, page = $1, $2
+          link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier)
+          title ||= identifier if page.blank?
         end
 
         if link_project && link_project.wiki
@@ -814,14 +772,14 @@
                 repository = project.repository
               end
               if prefix == 'commit'
-                if repository && (changeset = Changeset.visible.find(:first, :conditions => ["repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%"]))
+                if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first)
                   link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier},
                                                :class => 'changeset',
-                                               :title => truncate_single_line(h(changeset.comments), :length => 100)
+                                               :title => truncate_single_line(changeset.comments, :length => 100)
                 end
               else
                 if repository && User.current.allowed_to?(:browse_repository, project)
-                  name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
+                  name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$}
                   path, rev, anchor = $1, $3, $5
                   link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param,
                                                           :path => to_path_param(path),
@@ -835,11 +793,10 @@
           when 'attachment'
             attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
             if attachments && attachment = Attachment.latest_attach(attachments, name)
-              link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
-                                                     :class => 'attachment'
+              link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment')
             end
           when 'project'
-            if p = Project.visible.find(:first, :conditions => ["identifier = :s OR LOWER(name) = :s", {:s => name.downcase}])
+            if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first
               link = link_to_project(p, {:only_path => only_path}, :class => 'project')
             end
           end
@@ -1092,7 +1049,7 @@
         (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : ''.html_safe) +
         (pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : ''.html_safe)
       ), :class => 'progress', :style => "width: #{width};").html_safe +
-      content_tag('p', legend, :class => 'pourcent').html_safe
+      content_tag('p', legend, :class => 'percent').html_safe
   end
 
   def checked_image(checked=true)
@@ -1136,7 +1093,7 @@
                    "var datepickerOptions={dateFormat: 'yy-mm-dd', firstDay: #{start_of_week}, " +
                      "showOn: 'button', buttonImageOnly: true, buttonImage: '" +
                      path_to_image('/images/calendar.png') +
-                     "', showButtonPanel: true};")
+                     "', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true};")
         jquery_locale = l('jquery.locale', :default => current_language.to_s)
         unless jquery_locale == 'en'
           tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js")
@@ -1240,7 +1197,7 @@
 
   def sanitize_anchor_name(anchor)
     if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java'
-      anchor.gsub(%r{[^\p{Word}\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
+      anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
     else
       # TODO: remove when ruby1.8 is no longer supported
       anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
@@ -1249,7 +1206,7 @@
 
   # Returns the javascript tags that are included in the html layout head
   def javascript_heads
-    tags = javascript_include_tag('jquery-1.7.2-ui-1.8.21-ujs-2.0.3', 'application')
+    tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application')
     unless User.current.pref.warn_on_leaving_unsaved == '0'
       tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });")
     end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/attachments_helper.rb
--- a/app/helpers/attachments_helper.rb
+++ b/app/helpers/attachments_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/auth_sources_helper.rb
--- a/app/helpers/auth_sources_helper.rb
+++ b/app/helpers/auth_sources_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/boards_helper.rb
--- a/app/helpers/boards_helper.rb
+++ b/app/helpers/boards_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/calendars_helper.rb
--- a/app/helpers/calendars_helper.rb
+++ b/app/helpers/calendars_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/context_menus_helper.rb
--- a/app/helpers/context_menus_helper.rb
+++ b/app/helpers/context_menus_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -36,7 +36,7 @@
 
   def bulk_update_custom_field_context_menu_link(field, text, value)
     context_menu_link h(text),
-      {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'custom_field_values' => {field.id => value}}, :back_url => @back},
+      bulk_update_issues_path(:ids => @issue_ids, :issue => {'custom_field_values' => {field.id => value}}, :back_url => @back),
       :method => :post,
       :selected => (@issue && @issue.custom_field_value(field) == value)
   end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/custom_fields_helper.rb
--- a/app/helpers/custom_fields_helper.rb
+++ b/app/helpers/custom_fields_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,7 +24,7 @@
   end
 
   # Return custom field html tag corresponding to its format
-  def custom_field_tag(name, custom_value)	
+  def custom_field_tag(name, custom_value)
     custom_field = custom_value.custom_field
     field_name = "#{name}[custom_field_values][#{custom_field.id}]"
     field_name << "[]" if custom_field.multiple?
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/documents_helper.rb
--- a/app/helpers/documents_helper.rb
+++ b/app/helpers/documents_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/enumerations_helper.rb
--- a/app/helpers/enumerations_helper.rb
+++ b/app/helpers/enumerations_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/gantt_helper.rb
--- a/app/helpers/gantt_helper.rb
+++ b/app/helpers/gantt_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,19 +24,19 @@
     when :in
       if gantt.zoom < 4
         link_to_content_update l(:text_zoom_in),
-          params.merge(gantt.params.merge(:zoom => (gantt.zoom+1))),
+          params.merge(gantt.params.merge(:zoom => (gantt.zoom + 1))),
           :class => 'icon icon-zoom-in'
       else
-        content_tag('span', l(:text_zoom_in), :class => 'icon icon-zoom-in').html_safe
+        content_tag(:span, l(:text_zoom_in), :class => 'icon icon-zoom-in').html_safe
       end
 
     when :out
       if gantt.zoom > 1
         link_to_content_update l(:text_zoom_out),
-          params.merge(gantt.params.merge(:zoom => (gantt.zoom-1))),
+          params.merge(gantt.params.merge(:zoom => (gantt.zoom - 1))),
           :class => 'icon icon-zoom-out'
       else
-        content_tag('span', l(:text_zoom_out), :class => 'icon icon-zoom-out').html_safe
+        content_tag(:span, l(:text_zoom_out), :class => 'icon icon-zoom-out').html_safe
       end
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/groups_helper.rb
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,4 +24,19 @@
             {:name => 'memberships', :partial => 'groups/memberships', :label => :label_project_plural}
             ]
   end
+
+  def render_principals_for_new_group_users(group)
+    scope = User.active.sorted.not_in_group(group).like(params[:q])
+    principal_count = scope.count
+    principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
+    principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
+
+    s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals')
+
+    links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
+      link_to text, autocomplete_for_user_group_path(group, parameters.merge(:q => params[:q], :format => 'js')), :remote => true
+    }
+
+    s + content_tag('p', links, :class => 'pagination')
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/issue_categories_helper.rb
--- a/app/helpers/issue_categories_helper.rb
+++ b/app/helpers/issue_categories_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/issue_relations_helper.rb
--- a/app/helpers/issue_relations_helper.rb
+++ b/app/helpers/issue_relations_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/issue_statuses_helper.rb
--- a/app/helpers/issue_statuses_helper.rb
+++ b/app/helpers/issue_statuses_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/issues_helper.rb
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -184,7 +184,7 @@
 
   def sidebar_queries
     unless @sidebar_queries
-      @sidebar_queries = Query.visible.all(
+      @sidebar_queries = IssueQuery.visible.all(
         :order => "#{Query.table_name}.name ASC",
         # Project specific queries and global queries
         :conditions => (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id])
@@ -347,6 +347,9 @@
 
   # Find the name of an associated record stored in the field attribute
   def find_name_by_reflection(field, id)
+    unless id.present?
+      return nil
+    end
     association = Issue.reflect_on_association(field.to_sym)
     if association
       record = association.class_name.constantize.find_by_id(id)
@@ -370,44 +373,4 @@
       end
     end
   end
-
-  def issues_to_csv(issues, project, query, options={})
-    decimal_separator = l(:general_csv_decimal_separator)
-    encoding = l(:general_csv_encoding)
-    columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns)
-    if options[:description]
-      if description = query.available_columns.detect {|q| q.name == :description}
-        columns << description
-      end
-    end
-
-    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
-      # csv header fields
-      csv << [ "#" ] + columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
-
-      # csv lines
-      issues.each do |issue|
-        col_values = columns.collect do |column|
-          s = if column.is_a?(QueryCustomFieldColumn)
-            cv = issue.custom_field_values.detect {|v| v.custom_field_id == column.custom_field.id}
-            show_value(cv)
-          else
-            value = column.value(issue)
-            if value.is_a?(Date)
-              format_date(value)
-            elsif value.is_a?(Time)
-              format_time(value)
-            elsif value.is_a?(Float)
-              ("%.2f" % value).gsub('.', decimal_separator)
-            else
-              value
-            end
-          end
-          s.to_s
-        end
-        csv << [ issue.id.to_s ] + col_values.collect {|c| Redmine::CodesetUtil.from_utf8(c.to_s, encoding) }
-      end
-    end
-    export
-  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/journals_helper.rb
--- a/app/helpers/journals_helper.rb
+++ b/app/helpers/journals_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/mail_handler_helper.rb
--- a/app/helpers/mail_handler_helper.rb
+++ b/app/helpers/mail_handler_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/members_helper.rb
--- a/app/helpers/members_helper.rb
+++ b/app/helpers/members_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,4 +18,18 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 module MembersHelper
+  def render_principals_for_new_members(project)
+    scope = Principal.active.sorted.not_member_of(project).like(params[:q])
+    principal_count = scope.count
+    principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
+    principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
+
+    s = content_tag('div', principals_check_box_tags('membership[user_ids][]', principals), :id => 'principals')
+
+    links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
+      link_to text, autocomplete_project_memberships_path(project, parameters.merge(:q => params[:q], :format => 'js')), :remote => true
+    }
+
+    s + content_tag('p', links, :class => 'pagination')
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/messages_helper.rb
--- a/app/helpers/messages_helper.rb
+++ b/app/helpers/messages_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/my_helper.rb
--- a/app/helpers/my_helper.rb
+++ b/app/helpers/my_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,4 +25,54 @@
     user.projects.select { |p| p.visible? }.map { |p| p.members.map { |m| m.user_id } }.flatten.sort.uniq.reject { |i| user.id == i }
   end
 
+  def calendar_items(startdt, enddt)
+    Issue.visible.
+      where(:project_id => User.current.projects.map(&:id)).
+      where("(start_date>=? and start_date<=?) or (due_date>=? and due_date<=?)", startdt, enddt, startdt, enddt).
+      includes(:project, :tracker, :priority, :assigned_to).
+      all
+  end
+
+  def documents_items
+    Document.visible.order("#{Document.table_name}.created_on DESC").limit(10).all
+  end
+
+  def issuesassignedtome_items
+    Issue.visible.open.
+      where(:assigned_to_id => ([User.current.id] + User.current.group_ids)).
+      limit(10).
+      includes(:status, :project, :tracker, :priority).
+      order("#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC").
+      all
+  end
+
+  def issuesreportedbyme_items
+    Issue.visible.
+      where(:author_id => User.current.id).
+      limit(10).
+      includes(:status, :project, :tracker).
+      order("#{Issue.table_name}.updated_on DESC").
+      all
+  end
+
+  def issueswatched_items
+    Issue.visible.on_active_project.watched_by(User.current.id).recently_updated.limit(10).all
+  end
+
+  def news_items
+    News.visible.
+      where(:project_id => User.current.projects.map(&:id)).
+      limit(10).
+      includes(:project, :author).
+      order("#{News.table_name}.created_on DESC").
+      all
+  end
+
+  def timelog_items
+    TimeEntry.
+      where("#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", User.current.id, Date.today - 6, Date.today).
+      includes(:activity, :project, {:issue => [:tracker, :status]}).
+      order("#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC").
+      all
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/news_helper.rb
--- a/app/helpers/news_helper.rb
+++ b/app/helpers/news_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/projects_helper.rb
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/queries_helper.rb
--- a/app/helpers/queries_helper.rb
+++ b/app/helpers/queries_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,32 +24,35 @@
 
   def filters_options(query)
     options = [[]]
-    sorted_options = query.available_filters.sort do |a, b|
-      ord = 0
-      if !(a[1][:order] == 20 && b[1][:order] == 20) 
-        ord = a[1][:order] <=> b[1][:order]
-      else
-        cn = (CustomField::CUSTOM_FIELDS_NAMES.index(a[1][:field].class.name) <=>
-                CustomField::CUSTOM_FIELDS_NAMES.index(b[1][:field].class.name))
-        if cn != 0
-          ord = cn
-        else
-          f = (a[1][:field] <=> b[1][:field])
-          if f != 0
-            ord = f
-          else
-            # assigned_to or author 
-            ord = (a[0] <=> b[0])
-          end
-        end
-      end
-      ord
-    end
-    options += sorted_options.map do |field, field_options|
+    options += query.available_filters.map do |field, field_options|
       [field_options[:name], field]
     end
   end
 
+  def query_filters_hidden_tags(query)
+    tags = ''.html_safe
+    query.filters.each do |field, options|
+      tags << hidden_field_tag("f[]", field, :id => nil)
+      tags << hidden_field_tag("op[#{field}]", options[:operator], :id => nil)
+      options[:values].each do |value|
+        tags << hidden_field_tag("v[#{field}][]", value, :id => nil)
+      end
+    end
+    tags
+  end
+
+  def query_columns_hidden_tags(query)
+    tags = ''.html_safe
+    query.columns.each do |column|
+      tags << hidden_field_tag("c[]", column.name, :id => nil)
+    end
+    tags
+  end
+
+  def query_hidden_tags(query)
+    query_filters_hidden_tags(query) + query_columns_hidden_tags(query)
+  end
+
   def available_block_columns_tags(query)
     tags = ''.html_safe
     query.available_block_columns.each do |column|
@@ -58,6 +61,19 @@
     tags
   end
 
+  def query_available_inline_columns_options(query)
+    (query.available_inline_columns - query.columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
+  end
+
+  def query_selected_inline_columns_options(query)
+    (query.inline_columns & query.available_inline_columns).reject(&:frozen?).collect {|column| [column.caption, column.name]}
+  end
+
+  def render_query_columns_selection(query, options={})
+    tag_name = (options[:name] || 'c') + '[]'
+    render :partial => 'queries/columns', :locals => {:query => query, :tag_name => tag_name}
+  end
+
   def column_header(column)
     column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption,
                                                         :default_order => column.default_order) :
@@ -88,7 +104,9 @@
     when 'Date'
       format_date(value)
     when 'Fixnum'
-      if column.name == :done_ratio
+      if column.name == :id
+        link_to value, issue_path(issue)
+      elsif column.name == :done_ratio
         progress_bar(value, :width => '80px')
       else
         value.to_s
@@ -106,7 +124,7 @@
     when 'FalseClass'
       l(:general_text_No)
     when 'Issue'
-      link_to_issue(value, :subject => false)
+      value.visible? ? link_to_issue(value) : "##{value.id}"
     when 'IssueRelation'
       other = value.other_issue(issue)
       content_tag('span',
@@ -117,26 +135,71 @@
     end
   end
 
+  def csv_content(column, issue)
+    value = column.value(issue)
+    if value.is_a?(Array)
+      value.collect {|v| csv_value(column, issue, v)}.compact.join(', ')
+    else
+      csv_value(column, issue, value)
+    end
+  end
+
+  def csv_value(column, issue, value)
+    case value.class.name
+    when 'Time'
+      format_time(value)
+    when 'Date'
+      format_date(value)
+    when 'Float'
+      sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator))
+    when 'IssueRelation'
+      other = value.other_issue(issue)
+      l(value.label_for(issue)) + " ##{other.id}"
+    else
+      value.to_s
+    end
+  end
+
+  def query_to_csv(items, query, options={})
+    encoding = l(:general_csv_encoding)
+    columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns)
+    query.available_block_columns.each do |column|
+      if options[column.name].present?
+        columns << column
+      end
+    end
+
+    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
+      # csv header fields
+      csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) }
+      # csv lines
+      items.each do |item|
+        csv << columns.collect {|c| Redmine::CodesetUtil.from_utf8(csv_content(c, item), encoding) }
+      end
+    end
+    export
+  end
+
   # Retrieve query from session or build a new query
   def retrieve_query
     if !params[:query_id].blank?
       cond = "project_id IS NULL"
       cond << " OR project_id = #{@project.id}" if @project
-      @query = Query.find(params[:query_id], :conditions => cond)
+      @query = IssueQuery.find(params[:query_id], :conditions => cond)
       raise ::Unauthorized unless @query.visible?
       @query.project = @project
       session[:query] = {:id => @query.id, :project_id => @query.project_id}
       sort_clear
     elsif api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
       # Give it a name, required to be valid
-      @query = Query.new(:name => "_")
+      @query = IssueQuery.new(:name => "_")
       @query.project = @project
-      build_query_from_params
+      @query.build_from_params(params)
       session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
     else
       # retrieve from session
-      @query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
-      @query ||= Query.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
+      @query = IssueQuery.find_by_id(session[:query][:id]) if session[:query][:id]
+      @query ||= IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
       @query.project = @project
     end
   end
@@ -144,10 +207,10 @@
   def retrieve_query_from_session
     if session[:query]
       if session[:query][:id]
-        @query = Query.find_by_id(session[:query][:id])
+        @query = IssueQuery.find_by_id(session[:query][:id])
         return unless @query
       else
-        @query = Query.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
+        @query = IssueQuery.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
       end
       if session[:query].has_key?(:project_id)
         @query.project_id = session[:query][:project_id]
@@ -157,17 +220,4 @@
       @query
     end
   end
-
-  def build_query_from_params
-    if params[:fields] || params[:f]
-      @query.filters = {}
-      @query.add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v])
-    else
-      @query.available_filters.keys.each do |field|
-        @query.add_short_filter(field, params[field]) if params[field]
-      end
-    end
-    @query.group_by = params[:group_by] || (params[:query] && params[:query][:group_by])
-    @query.column_names = params[:c] || (params[:query] && params[:query][:column_names])
-  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/reports_helper.rb
--- a/app/helpers/reports_helper.rb
+++ b/app/helpers/reports_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -35,4 +35,9 @@
     a = aggregate data, criteria
     a > 0 ? link_to(h(a), *args) : '-'
   end
+
+  def aggregate_path(project, field, row, options={})
+    parameters = {:set_filter => 1, :subproject_id => '!*', field => row.id}.merge(options)
+    project_issues_path(row.is_a?(Project) ? row : project, parameters)
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/repositories_helper.rb
--- a/app/helpers/repositories_helper.rb
+++ b/app/helpers/repositories_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -43,7 +43,7 @@
   end
 
   def render_changeset_changes
-    changes = @changeset.filechanges.find(:all, :limit => 1000, :order => 'path').collect do |change|
+    changes = @changeset.filechanges.limit(1000).reorder('path').all.collect do |change|
       case change.action
       when 'A'
         # Detects moved/copied files
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/roles_helper.rb
--- a/app/helpers/roles_helper.rb
+++ b/app/helpers/roles_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/routes_helper.rb
--- /dev/null
+++ b/app/helpers/routes_helper.rb
@@ -0,0 +1,39 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module RoutesHelper
+
+  # Returns the path to project issues or to the cross-project
+  # issue list if project is nil
+  def _project_issues_path(project, *args)
+    if project
+      project_issues_path(project, *args)
+    else
+      issues_path(*args)
+    end
+  end
+
+  def _project_calendar_path(project, *args)
+    project ? project_calendar_path(project, *args) : issues_calendar_path(*args)
+  end
+
+  def _project_gantt_path(project, *args)
+    project ? project_gantt_path(project, *args) : issues_gantt_path(*args)
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/search_helper.rb
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/settings_helper.rb
--- a/app/helpers/settings_helper.rb
+++ b/app/helpers/settings_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -53,7 +53,7 @@
           check_box_tag(
              "settings[#{setting}][]",
              value,
-             Setting.send(setting).include?(value),
+             setting_values.include?(value),
              :id => nil
            ) + text.to_s,
           :class => (options[:inline] ? 'inline' : 'block')
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/sort_helper.rb
--- a/app/helpers/sort_helper.rb
+++ b/app/helpers/sort_helper.rb
@@ -80,12 +80,13 @@
       @criteria.collect {|k,o| k + (o ? '' : ':desc')}.join(',')
     end
 
+    # Returns an array of SQL fragments used to sort the list
     def to_sql
       sql = @criteria.collect do |k,o|
         if s = @available_criteria[k]
-          (o ? s.to_a : s.to_a.collect {|c| append_desc(c)}).join(', ')
+          (o ? s.to_a : s.to_a.collect {|c| append_desc(c)})
         end
-      end.compact.join(', ')
+      end.flatten.compact
       sql.blank? ? nil : sql
     end
 
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/timelog_helper.rb
--- a/app/helpers/timelog_helper.rb
+++ b/app/helpers/timelog_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -56,10 +56,10 @@
   end
 
   def select_hours(data, criteria, value)
-  	if value.to_s.empty?
-  		data.select {|row| row[criteria].blank? }
+    if value.to_s.empty?
+      data.select {|row| row[criteria].blank? }
     else
-    	data.select {|row| row[criteria].to_s == value.to_s}
+      data.select {|row| row[criteria].to_s == value.to_s}
     end
   end
 
@@ -86,49 +86,6 @@
                         value)
   end
 
-  def entries_to_csv(entries)
-    decimal_separator = l(:general_csv_decimal_separator)
-    custom_fields = TimeEntryCustomField.find(:all)
-    export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
-      # csv header fields
-      headers = [l(:field_spent_on),
-                 l(:field_user),
-                 l(:field_activity),
-                 l(:field_project),
-                 l(:field_issue),
-                 l(:field_tracker),
-                 l(:field_subject),
-                 l(:field_hours),
-                 l(:field_comments)
-                 ]
-      # Export custom fields
-      headers += custom_fields.collect(&:name)
-
-      csv << headers.collect {|c| Redmine::CodesetUtil.from_utf8(
-                                     c.to_s,
-                                     l(:general_csv_encoding) )  }
-      # csv lines
-      entries.each do |entry|
-        fields = [format_date(entry.spent_on),
-                  entry.user,
-                  entry.activity,
-                  entry.project,
-                  (entry.issue ? entry.issue.id : nil),
-                  (entry.issue ? entry.issue.tracker : nil),
-                  (entry.issue ? entry.issue.subject : nil),
-                  entry.hours.to_s.gsub('.', decimal_separator),
-                  entry.comments
-                  ]
-        fields += custom_fields.collect {|f| show_value(entry.custom_field_values.detect {|v| v.custom_field_id == f.id}) }
-
-        csv << fields.collect {|c| Redmine::CodesetUtil.from_utf8(
-                                     c.to_s,
-                                     l(:general_csv_encoding) )  }
-      end
-    end
-    export
-  end
-
   def format_criteria_value(criteria_options, value)
     if value.blank?
       "[#{l(:label_none)}]"
@@ -150,14 +107,14 @@
       # Column headers
       headers = report.criteria.collect {|criteria| l(report.available_criteria[criteria][:label]) }
       headers += report.periods
-      headers << l(:label_total)
+      headers << l(:label_total_time)
       csv << headers.collect {|c| Redmine::CodesetUtil.from_utf8(
                                     c.to_s,
                                     l(:general_csv_encoding) ) }
       # Content
       report_criteria_to_csv(csv, report.available_criteria, report.columns, report.criteria, report.periods, report.hours)
       # Total row
-      str_total = Redmine::CodesetUtil.from_utf8(l(:label_total), l(:general_csv_encoding))
+      str_total = Redmine::CodesetUtil.from_utf8(l(:label_total_time), l(:general_csv_encoding))
       row = [ str_total ] + [''] * (report.criteria.size - 1)
       total = 0
       report.periods.each do |period|
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/trackers_helper.rb
--- a/app/helpers/trackers_helper.rb
+++ b/app/helpers/trackers_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/users_helper.rb
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/versions_helper.rb
--- a/app/helpers/versions_helper.rb
+++ b/app/helpers/versions_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/watchers_helper.rb
--- a/app/helpers/watchers_helper.rb
+++ b/app/helpers/watchers_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -20,24 +20,31 @@
 module WatchersHelper
 
   def watcher_tag(object, user, options={})
-    content_tag("span", watcher_link(object, user), :class => watcher_css(object))
+    ActiveSupport::Deprecation.warn "#watcher_tag is deprecated and will be removed in Redmine 3.0. Use #watcher_link instead."
+    watcher_link(object, user)
   end
 
-  def watcher_link(object, user)
-    return '' unless user && user.logged? && object.respond_to?('watched_by?')
-    watched = object.watched_by?(user)
-    url = {:controller => 'watchers',
-           :action => (watched ? 'unwatch' : 'watch'),
-           :object_type => object.class.to_s.underscore,
-           :object_id => object.id}
-    link_to((watched ? l(:button_unwatch) : l(:button_watch)), url,
-            :remote => true, :method => 'post', :class => (watched ? 'icon icon-fav' : 'icon icon-fav-off'))
+  def watcher_link(objects, user)
+    return '' unless user && user.logged?
+    objects = Array.wrap(objects)
 
+    watched = objects.any? {|object| object.watched_by?(user)}
+    css = [watcher_css(objects), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ')
+    text = watched ? l(:button_unwatch) : l(:button_watch)
+    url = watch_path(
+      :object_type => objects.first.class.to_s.underscore,
+      :object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort)
+    )
+    method = watched ? 'delete' : 'post'
+
+    link_to text, url, :remote => true, :method => method, :class => css
   end
 
   # Returns the css class used to identify watch links for a given +object+
-  def watcher_css(object)
-    "#{object.class.to_s.underscore}-#{object.id}-watcher"
+  def watcher_css(objects)
+    objects = Array.wrap(objects)
+    id = (objects.size == 1 ? objects.first.id : 'bulk')
+    "#{objects.first.class.to_s.underscore}-#{id}-watcher"
   end
 
   # Returns a comma separated list of users watching the given object
@@ -56,11 +63,11 @@
                :user_id => user}
         s << ' '
         s << link_to(image_tag('delete.png'), url,
-                     :remote => true, :method => 'post', :style => "vertical-align: middle", :class => "delete")
+                     :remote => true, :method => 'delete', :class => "delete")
       end
-      content << content_tag('li', s)
+      content << content_tag('li', s, :class => "user-#{user.id}")
     end
-    content.present? ? content_tag('ul', content) : content
+    content.present? ? content_tag('ul', content, :class => 'watchers') : content
   end
 
   def watchers_checkboxes(object, users, checked=nil)
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/welcome_helper.rb
--- a/app/helpers/welcome_helper.rb
+++ b/app/helpers/welcome_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/wiki_helper.rb
--- a/app/helpers/wiki_helper.rb
+++ b/app/helpers/wiki_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/helpers/workflows_helper.rb
--- a/app/helpers/workflows_helper.rb
+++ b/app/helpers/workflows_helper.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/attachment.rb
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,6 +16,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require "digest/md5"
+require "fileutils"
 
 class Attachment < ActiveRecord::Base
   belongs_to :container, :polymorphic => true
@@ -92,9 +93,6 @@
 
   def filename=(arg)
     write_attribute :filename, sanitize_filename(arg.to_s)
-    if new_record? && disk_filename.blank?
-      self.disk_filename = Attachment.disk_filename(filename)
-    end
     filename
   end
 
@@ -102,7 +100,13 @@
   # and computes its MD5 hash
   def files_to_final_location
     if @temp_file && (@temp_file.size > 0)
+      self.disk_directory = target_directory
+      self.disk_filename = Attachment.disk_filename(filename, disk_directory)
       logger.info("Saving attachment '#{self.diskfile}' (#{@temp_file.size} bytes)")
+      path = File.dirname(diskfile)
+      unless File.directory?(path)
+        FileUtils.mkdir_p(path)
+      end
       md5 = Digest::MD5.new
       File.open(diskfile, "wb") do |f|
         if @temp_file.respond_to?(:read)
@@ -134,7 +138,7 @@
 
   # Returns file's location on disk
   def diskfile
-    File.join(self.class.storage_path, disk_filename.to_s)
+    File.join(self.class.storage_path, disk_directory.to_s, disk_filename.to_s)
   end
 
   def title
@@ -154,11 +158,19 @@
   end
 
   def visible?(user=User.current)
-    container && container.attachments_visible?(user)
+    if container_id
+      container && container.attachments_visible?(user)
+    else
+      author == user
+    end
   end
 
   def deletable?(user=User.current)
-    container && container.attachments_deletable?(user)
+    if container_id
+      container && container.attachments_deletable?(user)
+    else
+      author == user
+    end
   end
 
   def image?
@@ -251,6 +263,26 @@
     Attachment.where("created_on < ? AND (container_type IS NULL OR container_type = '')", Time.now - age).destroy_all
   end
 
+  # Moves an existing attachment to its target directory
+  def move_to_target_directory!
+    if !new_record? & readable?
+      src = diskfile
+      self.disk_directory = target_directory
+      dest = diskfile
+      if src != dest && FileUtils.mkdir_p(File.dirname(dest)) && FileUtils.mv(src, dest)
+        update_column :disk_directory, disk_directory
+      end
+    end
+  end
+
+  # Moves existing attachments that are stored at the root of the files
+  # directory (ie. created before Redmine 2.3) to their target subdirectories
+  def self.move_from_root_to_target_directory
+    Attachment.where("disk_directory IS NULL OR disk_directory = ''").find_each do |attachment|
+      attachment.move_to_target_directory!
+    end
+  end
+
   private
 
   # Physically deletes the file from the file system
@@ -268,8 +300,15 @@
     @filename = just_filename.gsub(/[\/\?\%\*\:\|\"\'<>]+/, '_')
   end
 
-  # Returns an ASCII or hashed filename
-  def self.disk_filename(filename)
+  # Returns the subdirectory in which the attachment will be saved
+  def target_directory
+    time = created_on || DateTime.now
+    time.strftime("%Y/%m")
+  end
+
+  # Returns an ASCII or hashed filename that do not
+  # exists yet in the given subdirectory
+  def self.disk_filename(filename, directory=nil)
     timestamp = DateTime.now.strftime("%y%m%d%H%M%S")
     ascii = ''
     if filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
@@ -279,7 +318,7 @@
       # keep the extension if any
       ascii << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$}
     end
-    while File.exist?(File.join(@@storage_path, "#{timestamp}_#{ascii}"))
+    while File.exist?(File.join(storage_path, directory.to_s, "#{timestamp}_#{ascii}"))
       timestamp.succ!
     end
     "#{timestamp}_#{ascii}"
diff -r 0a574315af3e -r 4f746d8966dd app/models/auth_source.rb
--- a/app/models/auth_source.rb
+++ b/app/models/auth_source.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -48,6 +48,24 @@
     write_ciphered_attribute(:account_password, arg)
   end
 
+  def searchable?
+    false
+  end
+
+  def self.search(q)
+    results = []
+    AuthSource.all.each do |source|
+      begin
+        if source.searchable?
+          results += source.search(q)
+        end
+      rescue AuthSourceException => e
+        logger.error "Error while searching users in #{source.name}: #{e.message}"
+      end
+    end
+    results
+  end
+
   def allow_password_changes?
     self.class.allow_password_changes?
   end
diff -r 0a574315af3e -r 4f746d8966dd app/models/auth_source_ldap.rb
--- a/app/models/auth_source_ldap.rb
+++ b/app/models/auth_source_ldap.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -15,7 +15,6 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
-require 'iconv'
 require 'net/ldap'
 require 'net/ldap/dn'
 require 'timeout'
@@ -64,6 +63,32 @@
     "LDAP"
   end
 
+  # Returns true if this source can be searched for users
+  def searchable?
+    !account.to_s.include?("$login") && %w(login firstname lastname mail).all? {|a| send("attr_#{a}?")}
+  end
+
+  # Searches the source for users and returns an array of results
+  def search(q)
+    q = q.to_s.strip
+    return [] unless searchable? && q.present?
+
+    results = []
+    search_filter = base_filter & Net::LDAP::Filter.begins(self.attr_login, q)
+    ldap_con = initialize_ldap_con(self.account, self.account_password)
+    ldap_con.search(:base => self.base_dn,
+                    :filter => search_filter,
+                    :attributes => ['dn', self.attr_login, self.attr_firstname, self.attr_lastname, self.attr_mail],
+                    :size => 10) do |entry|
+      attrs = get_user_attributes_from_ldap_entry(entry)
+      attrs[:login] = AuthSourceLdap.get_attr(entry, self.attr_login)
+      results << attrs
+    end
+    results
+  rescue Net::LDAP::LdapError => e
+    raise AuthSourceException.new(e.message)
+  end
+
   private
 
   def with_timeout(&block)
@@ -84,6 +109,14 @@
     nil
   end
 
+  def base_filter
+    filter = Net::LDAP::Filter.eq("objectClass", "*")
+    if f = ldap_filter
+      filter = filter & f
+    end
+    filter
+  end
+
   def validate_filter
     if filter.present? && ldap_filter.nil?
       errors.add(:filter, :invalid)
@@ -140,14 +173,8 @@
     else
       ldap_con = initialize_ldap_con(self.account, self.account_password)
     end
-    login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
-    object_filter = Net::LDAP::Filter.eq( "objectClass", "*" )
     attrs = {}
-
-    search_filter = object_filter & login_filter
-    if f = ldap_filter
-      search_filter = search_filter & f
-    end
+    search_filter = base_filter & Net::LDAP::Filter.eq(self.attr_login, login)
 
     ldap_con.search( :base => self.base_dn,
                      :filter => search_filter,
diff -r 0a574315af3e -r 4f746d8966dd app/models/board.rb
--- a/app/models/board.rb
+++ b/app/models/board.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,8 +30,9 @@
   validates_length_of :description, :maximum => 255
   validate :validate_board
 
-  scope :visible, lambda {|*args| { :include => :project,
-                                          :conditions => Project.allowed_to_condition(args.shift || User.current, :view_messages, *args) } }
+  scope :visible, lambda {|*args|
+    includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
+  }
 
   safe_attributes 'name', 'description', 'parent_id', 'move_to'
 
diff -r 0a574315af3e -r 4f746d8966dd app/models/change.rb
--- a/app/models/change.rb
+++ b/app/models/change.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/changeset.rb
--- a/app/models/changeset.rb
+++ b/app/models/changeset.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -15,8 +15,6 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
-require 'iconv'
-
 class Changeset < ActiveRecord::Base
   belongs_to :repository
   belongs_to :user
@@ -49,9 +47,9 @@
   validates_uniqueness_of :revision, :scope => :repository_id
   validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
 
-  scope :visible,
-     lambda {|*args| { :include => {:repository => :project},
-                                          :conditions => Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args) } }
+  scope :visible, lambda {|*args|
+    includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args))
+  }
 
   after_create :scan_for_issues
   before_create :before_create_cs
diff -r 0a574315af3e -r 4f746d8966dd app/models/comment.rb
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/comment_observer.rb
--- a/app/models/comment_observer.rb
+++ b/app/models/comment_observer.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/custom_field.rb
--- a/app/models/custom_field.rb
+++ b/app/models/custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -29,6 +29,9 @@
 
   validate :validate_custom_field
   before_validation :set_searchable
+  after_save :handle_multiplicity_change
+
+  scope :sorted, lambda { order("#{table_name}.position ASC") }
 
   CUSTOM_FIELDS_TABS = [
     {:name => 'IssueCustomField', :partial => 'custom_fields/index',
@@ -169,7 +172,7 @@
       keyword
     end
   end
- 
+
   # Returns a ORDER BY clause that can used to sort customized
   # objects by their value of the custom field.
   # Returns nil if the custom field can not be used for sorting.
@@ -178,18 +181,12 @@
     case field_format
       when 'string', 'text', 'list', 'date', 'bool'
         # COALESCE is here to make sure that blank and NULL values are sorted equally
-        "COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" +
-          " WHERE cv_sort.customized_type='#{self.class.customized_class.base_class.name}'" +
-          " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" +
-          " AND cv_sort.custom_field_id=#{id} LIMIT 1), '')"
+        "COALESCE(#{join_alias}.value, '')"
       when 'int', 'float'
         # Make the database cast values into numeric
         # Postgresql will raise an error if a value can not be casted!
         # CustomValue validations should ensure that it doesn't occur
-        "(SELECT CAST(cv_sort.value AS decimal(60,3)) FROM #{CustomValue.table_name} cv_sort" +
-          " WHERE cv_sort.customized_type='#{self.class.customized_class.base_class.name}'" +
-          " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" +
-          " AND cv_sort.custom_field_id=#{id} AND cv_sort.value <> '' AND cv_sort.value IS NOT NULL LIMIT 1)"
+        "CAST(CASE #{join_alias}.value WHEN '' THEN '0' ELSE #{join_alias}.value END AS decimal(30,3))"
       when 'user', 'version'
         value_class.fields_for_order_statement(value_join_alias)
       else
@@ -199,16 +196,13 @@
 
   # Returns a GROUP BY clause that can used to group by custom value
   # Returns nil if the custom field can not be used for grouping.
-  def group_statement 
+  def group_statement
     return nil if multiple?
     case field_format
       when 'list', 'date', 'bool', 'int'
         order_statement
       when 'user', 'version'
-        "COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" +
-          " WHERE cv_sort.customized_type='#{self.class.customized_class.base_class.name}'" +
-          " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" +
-          " AND cv_sort.custom_field_id=#{id} LIMIT 1), '')"
+        "COALESCE(#{join_alias}.value, '')"
       else
         nil
     end
@@ -227,7 +221,26 @@
             " AND #{join_alias}_2.customized_id = #{join_alias}.customized_id" +
             " AND #{join_alias}_2.custom_field_id = #{join_alias}.custom_field_id)" +
           " LEFT OUTER JOIN #{value_class.table_name} #{value_join_alias}" +
-          " ON CAST(#{join_alias}.value as decimal(60,0)) = #{value_join_alias}.id"
+          " ON CAST(CASE #{join_alias}.value WHEN '' THEN '0' ELSE #{join_alias}.value END AS decimal(30,0)) = #{value_join_alias}.id"
+      when 'int', 'float'
+        "LEFT OUTER JOIN #{CustomValue.table_name} #{join_alias}" +
+          " ON #{join_alias}.customized_type = '#{self.class.customized_class.base_class.name}'" +
+          " AND #{join_alias}.customized_id = #{self.class.customized_class.table_name}.id" +
+          " AND #{join_alias}.custom_field_id = #{id}" +
+          " AND #{join_alias}.value <> ''" +
+          " AND #{join_alias}.id = (SELECT max(#{join_alias}_2.id) FROM #{CustomValue.table_name} #{join_alias}_2" +
+            " WHERE #{join_alias}_2.customized_type = #{join_alias}.customized_type" +
+            " AND #{join_alias}_2.customized_id = #{join_alias}.customized_id" +
+            " AND #{join_alias}_2.custom_field_id = #{join_alias}.custom_field_id)"
+      when 'string', 'text', 'list', 'date', 'bool'
+        "LEFT OUTER JOIN #{CustomValue.table_name} #{join_alias}" +
+          " ON #{join_alias}.customized_type = '#{self.class.customized_class.base_class.name}'" +
+          " AND #{join_alias}.customized_id = #{self.class.customized_class.table_name}.id" +
+          " AND #{join_alias}.custom_field_id = #{id}" +
+          " AND #{join_alias}.id = (SELECT max(#{join_alias}_2.id) FROM #{CustomValue.table_name} #{join_alias}_2" +
+            " WHERE #{join_alias}_2.customized_type = #{join_alias}.customized_type" +
+            " AND #{join_alias}_2.customized_id = #{join_alias}.customized_id" +
+            " AND #{join_alias}_2.custom_field_id = #{join_alias}.custom_field_id)"
       else
         nil
     end
@@ -262,7 +275,7 @@
 
   # to move in project_custom_field
   def self.for_all
-    find(:all, :conditions => ["is_for_all=?", true], :order => 'position')
+    where(:is_for_all => true).order('position').all
   end
 
   def type_name
@@ -323,4 +336,20 @@
     end
     errs
   end
+
+  # Removes multiple values for the custom field after setting the multiple attribute to false
+  # We kepp the value with the highest id for each customized object
+  def handle_multiplicity_change
+    if !new_record? && multiple_was && !multiple
+      ids = custom_values.
+        where("EXISTS(SELECT 1 FROM #{CustomValue.table_name} cve WHERE cve.custom_field_id = #{CustomValue.table_name}.custom_field_id" +
+          " AND cve.customized_type = #{CustomValue.table_name}.customized_type AND cve.customized_id = #{CustomValue.table_name}.customized_id" +
+          " AND cve.id > #{CustomValue.table_name}.id)").
+        pluck(:id)
+
+      if ids.any?
+        custom_values.where(:id => ids).delete_all
+      end
+    end
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/models/custom_field_value.rb
--- a/app/models/custom_field_value.rb
+++ b/app/models/custom_field_value.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/custom_value.rb
--- a/app/models/custom_value.rb
+++ b/app/models/custom_value.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/document.rb
--- a/app/models/document.rb
+++ b/app/models/document.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -19,19 +19,20 @@
   include Redmine::SafeAttributes
   belongs_to :project
   belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
-  acts_as_attachable :delete_permission => :manage_documents
+  acts_as_attachable :delete_permission => :delete_documents
 
   acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
   acts_as_event :title => Proc.new {|o| "#{l(:label_document)}: #{o.title}"},
-                :author => Proc.new {|o| (a = o.attachments.find(:first, :order => "#{Attachment.table_name}.created_on ASC")) ? a.author : nil },
+                :author => Proc.new {|o| o.attachments.reorder("#{Attachment.table_name}.created_on ASC").first.try(:author) },
                 :url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}}
   acts_as_activity_provider :find_options => {:include => :project}
 
   validates_presence_of :project, :title, :category
   validates_length_of :title, :maximum => 60
 
-  scope :visible, lambda {|*args| { :include => :project,
-                                          :conditions => Project.allowed_to_condition(args.shift || User.current, :view_documents, *args) } }
+  scope :visible, lambda {|*args|
+    includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_documents, *args))
+  }
 
   safe_attributes 'category_id', 'title', 'description'
 
diff -r 0a574315af3e -r 4f746d8966dd app/models/document_category.rb
--- a/app/models/document_category.rb
+++ b/app/models/document_category.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/document_category_custom_field.rb
--- a/app/models/document_category_custom_field.rb
+++ b/app/models/document_category_custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/document_observer.rb
--- a/app/models/document_observer.rb
+++ b/app/models/document_observer.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/enabled_module.rb
--- a/app/models/enabled_module.rb
+++ b/app/models/enabled_module.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/enumeration.rb
--- a/app/models/enumeration.rb
+++ b/app/models/enumeration.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,7 +24,7 @@
 
   acts_as_list :scope => 'type = \'#{type}\''
   acts_as_customizable
-  acts_as_tree :order => 'position ASC'
+  acts_as_tree :order => "#{Enumeration.table_name}.position ASC"
 
   before_destroy :check_integrity
   before_save    :check_default
@@ -35,9 +35,10 @@
   validates_uniqueness_of :name, :scope => [:type, :project_id]
   validates_length_of :name, :maximum => 30
 
-  scope :shared, where(:project_id => nil)
-  scope :sorted, order("#{table_name}.position ASC")
-  scope :active, where(:active => true)
+  scope :shared, lambda { where(:project_id => nil) }
+  scope :sorted, lambda { order("#{table_name}.position ASC") }
+  scope :active, lambda { where(:active => true) }
+  scope :system, lambda { where(:project_id => nil) }
   scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
 
   def self.default
diff -r 0a574315af3e -r 4f746d8966dd app/models/group.rb
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,11 +25,12 @@
 
   validates_presence_of :lastname
   validates_uniqueness_of :lastname, :case_sensitive => false
-  validates_length_of :lastname, :maximum => 30
+  validates_length_of :lastname, :maximum => 255
 
   before_destroy :remove_references_before_destroy
 
-  scope :sorted, order("#{table_name}.lastname ASC")
+  scope :sorted, lambda { order("#{table_name}.lastname ASC") }
+  scope :named, lambda {|arg| where("LOWER(#{table_name}.lastname) = LOWER(?)", arg.to_s.strip)}
 
   safe_attributes 'name',
     'user_ids',
@@ -62,8 +63,11 @@
 
   def user_removed(user)
     members.each do |member|
-      MemberRole.find(:all, :include => :member,
-                            :conditions => ["#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids]).each(&:destroy)
+      MemberRole.
+        includes(:member).
+        where("#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids).
+        all.
+        each(&:destroy)
     end
   end
 
diff -r 0a574315af3e -r 4f746d8966dd app/models/group_custom_field.rb
--- a/app/models/group_custom_field.rb
+++ b/app/models/group_custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/issue.rb
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -67,24 +67,31 @@
 
   validates_length_of :subject, :maximum => 255
   validates_inclusion_of :done_ratio, :in => 0..100
-  validates_numericality_of :estimated_hours, :allow_nil => true
+  validates :estimated_hours, :numericality => {:greater_than_or_equal_to => 0, :allow_nil => true, :message => :invalid}
+  validates :start_date, :date => true
+  validates :due_date, :date => true
   validate :validate_issue, :validate_required_fields
 
-  scope :visible,
-        lambda {|*args| { :include => :project,
-                          :conditions => Issue.visible_condition(args.shift || User.current, *args) } }
+  scope :visible, lambda {|*args|
+    includes(:project).where(Issue.visible_condition(args.shift || User.current, *args))
+  }
 
   scope :open, lambda {|*args|
     is_closed = args.size > 0 ? !args.first : false
-    {:conditions => ["#{IssueStatus.table_name}.is_closed = ?", is_closed], :include => :status}
+    includes(:status).where("#{IssueStatus.table_name}.is_closed = ?", is_closed)
   }
 
-  scope :recently_updated, :order => "#{Issue.table_name}.updated_on DESC"
-  scope :on_active_project, :include => [:status, :project, :tracker],
-                            :conditions => ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"]
+  scope :recently_updated, lambda { order("#{Issue.table_name}.updated_on DESC") }
+  scope :on_active_project, lambda {
+    includes(:status, :project, :tracker).where("#{Project.table_name}.status = ?", Project::STATUS_ACTIVE)
+  }
+  scope :fixed_version, lambda {|versions|
+    ids = [versions].flatten.compact.map {|v| v.is_a?(Version) ? v.id : v}
+    ids.any? ? where(:fixed_version_id => ids) : where('1=0')
+  }
 
   before_create :default_assign
-  before_save :close_duplicates, :update_done_ratio_from_issue_status, :force_updated_on_change
+  before_save :close_duplicates, :update_done_ratio_from_issue_status, :force_updated_on_change, :update_closed_on
   after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?} 
   after_save :reschedule_following_issues, :update_nested_set_attributes, :update_parent_attributes, :create_journal
   # Should be after_create but would be called before previous after_save callbacks
@@ -133,6 +140,11 @@
     end
   end
 
+  # Returns true if user or current user is allowed to edit or add a note to the issue
+  def editable?(user=User.current)
+    user.allowed_to?(:edit_issues, project) || user.allowed_to?(:add_issue_notes, project)
+  end
+
   def initialize(attributes=nil, *args)
     super
     if new_record?
@@ -143,6 +155,13 @@
     end
   end
 
+  def create_or_update
+    super
+  ensure
+    @status_was = nil
+  end
+  private :create_or_update
+
   # AR#Persistence#destroy would raise and RecordNotFound exception
   # if the issue was already deleted or updated (non matching lock_version).
   # This is a problem when bulk deleting issues or deleting a project
@@ -165,10 +184,12 @@
     super
   end
 
+  alias :base_reload :reload
   def reload(*args)
     @workflow_rule_by_attribute = nil
     @assignable_versions = nil
-    super
+    @relations = nil
+    base_reload(*args)
   end
 
   # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
@@ -526,14 +547,6 @@
   end
 
   def validate_issue
-    if due_date.nil? && @attributes['due_date'].present?
-      errors.add :due_date, :not_a_date
-    end
-
-    if start_date.nil? && @attributes['start_date'].present?
-      errors.add :start_date, :not_a_date
-    end
-
     if due_date && start_date && due_date < start_date
       errors.add :due_date, :greater_than_start_date
     end
@@ -563,6 +576,8 @@
     elsif @parent_issue
       if !valid_parent_project?(@parent_issue)
         errors.add :parent_issue_id, :invalid
+      elsif (@parent_issue != parent) && (all_dependent_issues.include?(@parent_issue) || @parent_issue.all_dependent_issues.include?(self))
+        errors.add :parent_issue_id, :invalid
       elsif !new_record?
         # moving an existing issue
         if @parent_issue.root_id != root_id
@@ -633,6 +648,14 @@
     scope
   end
 
+  # Returns the initial status of the issue
+  # Returns nil for a new issue
+  def status_was
+    if status_id_was && status_id_was.to_i > 0
+      @status_was ||= IssueStatus.find_by_id(status_id_was)
+    end
+  end
+
   # Return true if the issue is closed, otherwise false
   def closed?
     self.status.is_closed?
@@ -653,9 +676,7 @@
   # Return true if the issue is being closed
   def closing?
     if !new_record? && status_id_changed?
-      status_was = IssueStatus.find_by_id(status_id_was)
-      status_new = IssueStatus.find_by_id(status_id)
-      if status_was && status_new && !status_was.is_closed? && status_new.is_closed?
+      if status_was && status && !status_was.is_closed? && status.is_closed?
         return true
       end
     end
@@ -785,7 +806,7 @@
   end
 
   def relations
-    @relations ||= IssueRelations.new(self, (relations_from + relations_to).sort)
+    @relations ||= IssueRelation::Relations.new(self, (relations_from + relations_to).sort)
   end
 
   # Preloads relations for a collection of issues
@@ -822,7 +843,7 @@
           relations_from.select {|relation| relation.issue_from_id == issue.id} +
           relations_to.select {|relation| relation.issue_to_id == issue.id}
 
-        issue.instance_variable_set "@relations", IssueRelations.new(issue, relations.sort)
+        issue.instance_variable_set "@relations", IssueRelation::Relations.new(issue, relations.sort)
       end
     end
   end
@@ -832,14 +853,18 @@
     IssueRelation.find(relation_id, :conditions => ["issue_to_id = ? OR issue_from_id = ?", id, id])
   end
 
+  # Returns all the other issues that depend on the issue
   def all_dependent_issues(except=[])
     except << self
     dependencies = []
-    relations_from.each do |relation|
-      if relation.issue_to && !except.include?(relation.issue_to)
-        dependencies << relation.issue_to
-        dependencies += relation.issue_to.all_dependent_issues(except)
-      end
+    dependencies += relations_from.map(&:issue_to)
+    dependencies += children unless leaf?
+    dependencies.compact!
+    dependencies -= except
+    dependencies += dependencies.map {|issue| issue.all_dependent_issues(except)}.flatten
+    if parent
+      dependencies << parent
+      dependencies += parent.all_dependent_issues(except + parent.descendants)
     end
     dependencies
   end
@@ -873,7 +898,7 @@
     @soonest_start = nil if reload
     @soonest_start ||= (
         relations_to(reload).collect{|relation| relation.successor_soonest_start} +
-        ancestors.collect(&:soonest_start)
+        [(@parent_issue || parent).try(:soonest_start)]
       ).compact.max
   end
 
@@ -936,7 +961,7 @@
 
   # Returns a string of css classes that apply to the issue
   def css_classes
-    s = "issue status-#{status_id} #{priority.try(:css_classes)}"
+    s = "issue tracker-#{tracker_id} status-#{status_id} #{priority.try(:css_classes)}"
     s << ' closed' if closed?
     s << ' overdue' if overdue?
     s << ' child' if child?
@@ -1005,8 +1030,8 @@
     end
   end
 
-	# Returns true if issue's project is a valid
-	# parent issue project
+  # Returns true if issue's project is a valid
+  # parent issue project
   def valid_parent_project?(issue=parent)
     return true if issue.nil? || issue.project_id == project_id
 
@@ -1128,20 +1153,27 @@
     end
 
     unless @copied_from.leaf? || @copy_options[:subtasks] == false
-      @copied_from.children.each do |child|
+      copy_options = (@copy_options || {}).merge(:subtasks => false)
+      copied_issue_ids = {@copied_from.id => self.id}
+      @copied_from.reload.descendants.reorder("#{Issue.table_name}.lft").each do |child|
+        # Do not copy self when copying an issue as a descendant of the copied issue
+        next if child == self
+        # Do not copy subtasks of issues that were not copied
+        next unless copied_issue_ids[child.parent_id]
+        # Do not copy subtasks that are not visible to avoid potential disclosure of private data
         unless child.visible?
-          # Do not copy subtasks that are not visible to avoid potential disclosure of private data
           logger.error "Subtask ##{child.id} was not copied during ##{@copied_from.id} copy because it is not visible to the current user" if logger
           next
         end
-        copy = Issue.new.copy_from(child, @copy_options)
+        copy = Issue.new.copy_from(child, copy_options)
         copy.author = author
         copy.project = project
-        copy.parent_issue_id = id
-        # Children subtasks are copied recursively
+        copy.parent_issue_id = copied_issue_ids[child.parent_id]
         unless copy.save
           logger.error "Could not copy subtask ##{child.id} while copying ##{@copied_from.id} to ##{id} due to validation errors: #{copy.errors.full_messages.join(', ')}" if logger
+          next
         end
+        copied_issue_ids[child.id] = copy.id
       end
     end
     @after_create_from_copy_handled = true
@@ -1303,10 +1335,23 @@
     end
   end
 
-  # Make sure updated_on is updated when adding a note
+  # Make sure updated_on is updated when adding a note and set updated_on now
+  # so we can set closed_on with the same value on closing
   def force_updated_on_change
-    if @current_journal
+    if @current_journal || changed?
       self.updated_on = current_time_from_proper_timezone
+      if new_record?
+        self.created_on = updated_on
+      end
+    end
+  end
+
+  # Callback for setting closed_on when the issue is closed.
+  # The closed_on attribute stores the time of the last closing
+  # and is preserved when the issue is reopened.
+  def update_closed_on
+    if closing? || (new_record? && closed?)
+      self.closed_on = updated_on
     end
   end
 
@@ -1316,7 +1361,7 @@
     if @current_journal
       # attributes changes
       if @attributes_before_change
-        (Issue.column_names - %w(id root_id lft rgt lock_version created_on updated_on)).each {|c|
+        (Issue.column_names - %w(id root_id lft rgt lock_version created_on updated_on closed_on)).each {|c|
           before = @attributes_before_change[c]
           after = send(c)
           next if before == after || (before.blank? && after.blank?)
diff -r 0a574315af3e -r 4f746d8966dd app/models/issue_category.rb
--- a/app/models/issue_category.rb
+++ b/app/models/issue_category.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,7 +24,7 @@
   validates_presence_of :name
   validates_uniqueness_of :name, :scope => [:project_id]
   validates_length_of :name, :maximum => 30
-  
+
   safe_attributes 'name', 'assigned_to_id'
 
   scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
@@ -35,7 +35,7 @@
   # If a category is specified, issues are reassigned to this category
   def destroy(reassign_to = nil)
     if reassign_to && reassign_to.is_a?(IssueCategory) && reassign_to.project == self.project
-      Issue.update_all("category_id = #{reassign_to.id}", "category_id = #{id}")
+      Issue.update_all({:category_id => reassign_to.id}, {:category_id => id})
     end
     destroy_without_reassign
   end
diff -r 0a574315af3e -r 4f746d8966dd app/models/issue_custom_field.rb
--- a/app/models/issue_custom_field.rb
+++ b/app/models/issue_custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/issue_observer.rb
--- a/app/models/issue_observer.rb
+++ b/app/models/issue_observer.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/issue_priority.rb
--- a/app/models/issue_priority.rb
+++ b/app/models/issue_priority.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/issue_priority_custom_field.rb
--- a/app/models/issue_priority_custom_field.rb
+++ b/app/models/issue_priority_custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/issue_query.rb
--- /dev/null
+++ b/app/models/issue_query.rb
@@ -0,0 +1,405 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class IssueQuery < Query
+
+  self.queried_class = Issue
+
+  self.available_columns = [
+    QueryColumn.new(:id, :sortable => "#{Issue.table_name}.id", :default_order => 'desc', :caption => '#', :frozen => true),
+    QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
+    QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position", :groupable => true),
+    QueryColumn.new(:parent, :sortable => ["#{Issue.table_name}.root_id", "#{Issue.table_name}.lft ASC"], :default_order => 'desc', :caption => :field_parent_issue),
+    QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true),
+    QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc', :groupable => true),
+    QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
+    QueryColumn.new(:author, :sortable => lambda {User.fields_for_order_statement("authors")}, :groupable => true),
+    QueryColumn.new(:assigned_to, :sortable => lambda {User.fields_for_order_statement}, :groupable => true),
+    QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'),
+    QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true),
+    QueryColumn.new(:fixed_version, :sortable => lambda {Version.fields_for_order_statement}, :groupable => true),
+    QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date"),
+    QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date"),
+    QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours"),
+    QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true),
+    QueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc'),
+    QueryColumn.new(:closed_on, :sortable => "#{Issue.table_name}.closed_on", :default_order => 'desc'),
+    QueryColumn.new(:relations, :caption => :label_related_issues),
+    QueryColumn.new(:description, :inline => false)
+  ]
+
+  scope :visible, lambda {|*args|
+    user = args.shift || User.current
+    base = Project.allowed_to_condition(user, :view_issues, *args)
+    user_id = user.logged? ? user.id : 0
+
+    includes(:project).where("(#{table_name}.project_id IS NULL OR (#{base})) AND (#{table_name}.is_public = ? OR #{table_name}.user_id = ?)", true, user_id)
+  }
+
+  def initialize(attributes=nil, *args)
+    super attributes
+    self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} }
+  end
+
+  # Returns true if the query is visible to +user+ or the current user.
+  def visible?(user=User.current)
+    (project.nil? || user.allowed_to?(:view_issues, project)) && (self.is_public? || self.user_id == user.id)
+  end
+
+  def initialize_available_filters
+    principals = []
+    subprojects = []
+    versions = []
+    categories = []
+    issue_custom_fields = []
+    
+    if project
+      principals += project.principals.sort
+      unless project.leaf?
+        subprojects = project.descendants.visible.all
+        principals += Principal.member_of(subprojects)
+      end
+      versions = project.shared_versions.all
+      categories = project.issue_categories.all
+      issue_custom_fields = project.all_issue_custom_fields
+    else
+      if all_projects.any?
+        principals += Principal.member_of(all_projects)
+      end
+      versions = Version.visible.find_all_by_sharing('system')
+      issue_custom_fields = IssueCustomField.where(:is_filter => true, :is_for_all => true).all
+    end
+    principals.uniq!
+    principals.sort!
+    users = principals.select {|p| p.is_a?(User)}
+
+
+    add_available_filter "status_id",
+      :type => :list_status, :values => IssueStatus.sorted.all.collect{|s| [s.name, s.id.to_s] }
+
+    if project.nil?
+      project_values = []
+      if User.current.logged? && User.current.memberships.any?
+        project_values << ["<< #{l(:label_my_projects).downcase} >>", "mine"]
+      end
+      project_values += all_projects_values
+      add_available_filter("project_id",
+        :type => :list, :values => project_values
+      ) unless project_values.empty?
+    end
+
+    add_available_filter "tracker_id",
+      :type => :list, :values => trackers.collect{|s| [s.name, s.id.to_s] }
+    add_available_filter "priority_id",
+      :type => :list, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s] }
+
+    author_values = []
+    author_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
+    author_values += users.collect{|s| [s.name, s.id.to_s] }
+    add_available_filter("author_id",
+      :type => :list, :values => author_values
+    ) unless author_values.empty?
+
+    assigned_to_values = []
+    assigned_to_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
+    assigned_to_values += (Setting.issue_group_assignment? ?
+                              principals : users).collect{|s| [s.name, s.id.to_s] }
+    add_available_filter("assigned_to_id",
+      :type => :list_optional, :values => assigned_to_values
+    ) unless assigned_to_values.empty?
+
+    group_values = Group.all.collect {|g| [g.name, g.id.to_s] }
+    add_available_filter("member_of_group",
+      :type => :list_optional, :values => group_values
+    ) unless group_values.empty?
+
+    role_values = Role.givable.collect {|r| [r.name, r.id.to_s] }
+    add_available_filter("assigned_to_role",
+      :type => :list_optional, :values => role_values
+    ) unless role_values.empty?
+
+    if versions.any?
+      add_available_filter "fixed_version_id",
+        :type => :list_optional,
+        :values => versions.sort.collect{|s| ["#{s.project.name} - #{s.name}", s.id.to_s] }
+    end
+
+    if categories.any?
+      add_available_filter "category_id",
+        :type => :list_optional,
+        :values => categories.collect{|s| [s.name, s.id.to_s] }
+    end
+
+    add_available_filter "subject", :type => :text
+    add_available_filter "created_on", :type => :date_past
+    add_available_filter "updated_on", :type => :date_past
+    add_available_filter "closed_on", :type => :date_past
+    add_available_filter "start_date", :type => :date
+    add_available_filter "due_date", :type => :date
+    add_available_filter "estimated_hours", :type => :float
+    add_available_filter "done_ratio", :type => :integer
+
+    if User.current.allowed_to?(:set_issues_private, nil, :global => true) ||
+      User.current.allowed_to?(:set_own_issues_private, nil, :global => true)
+      add_available_filter "is_private",
+        :type => :list,
+        :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]]
+    end
+
+    if User.current.logged?
+      add_available_filter "watcher_id",
+        :type => :list, :values => [["<< #{l(:label_me)} >>", "me"]]
+    end
+
+    if subprojects.any?
+      add_available_filter "subproject_id",
+        :type => :list_subprojects,
+        :values => subprojects.collect{|s| [s.name, s.id.to_s] }
+    end
+
+    add_custom_fields_filters(issue_custom_fields)
+
+    add_associations_custom_fields_filters :project, :author, :assigned_to, :fixed_version
+
+    IssueRelation::TYPES.each do |relation_type, options|
+      add_available_filter relation_type, :type => :relation, :label => options[:name]
+    end
+
+    Tracker.disabled_core_fields(trackers).each {|field|
+      delete_available_filter field
+    }
+  end
+
+  def available_columns
+    return @available_columns if @available_columns
+    @available_columns = self.class.available_columns.dup
+    @available_columns += (project ?
+                            project.all_issue_custom_fields :
+                            IssueCustomField.all
+                           ).collect {|cf| QueryCustomFieldColumn.new(cf) }
+
+    if User.current.allowed_to?(:view_time_entries, project, :global => true)
+      index = nil
+      @available_columns.each_with_index {|column, i| index = i if column.name == :estimated_hours}
+      index = (index ? index + 1 : -1)
+      # insert the column after estimated_hours or at the end
+      @available_columns.insert index, QueryColumn.new(:spent_hours,
+        :sortable => "COALESCE((SELECT SUM(hours) FROM #{TimeEntry.table_name} WHERE #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id), 0)",
+        :default_order => 'desc',
+        :caption => :label_spent_time
+      )
+    end
+
+    if User.current.allowed_to?(:set_issues_private, nil, :global => true) ||
+      User.current.allowed_to?(:set_own_issues_private, nil, :global => true)
+      @available_columns << QueryColumn.new(:is_private, :sortable => "#{Issue.table_name}.is_private")
+    end
+
+    disabled_fields = Tracker.disabled_core_fields(trackers).map {|field| field.sub(/_id$/, '')}
+    @available_columns.reject! {|column|
+      disabled_fields.include?(column.name.to_s)
+    }
+
+    @available_columns
+  end
+
+  def default_columns_names
+    @default_columns_names ||= begin
+      default_columns = Setting.issue_list_default_columns.map(&:to_sym)
+
+      project.present? ? default_columns : [:project] | default_columns
+    end
+  end
+
+  # Returns the issue count
+  def issue_count
+    Issue.visible.count(:include => [:status, :project], :conditions => statement)
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the issue count by group or nil if query is not grouped
+  def issue_count_by_group
+    r = nil
+    if grouped?
+      begin
+        # Rails3 will raise an (unexpected) RecordNotFound if there's only a nil group value
+        r = Issue.visible.count(:joins => joins_for_order_statement(group_by_statement), :group => group_by_statement, :include => [:status, :project], :conditions => statement)
+      rescue ActiveRecord::RecordNotFound
+        r = {nil => issue_count}
+      end
+      c = group_by_column
+      if c.is_a?(QueryCustomFieldColumn)
+        r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h}
+      end
+    end
+    r
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the issues
+  # Valid options are :order, :offset, :limit, :include, :conditions
+  def issues(options={})
+    order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?)
+
+    issues = Issue.visible.where(options[:conditions]).all(
+      :include => ([:status, :project] + (options[:include] || [])).uniq,
+      :conditions => statement,
+      :order => order_option,
+      :joins => joins_for_order_statement(order_option.join(',')),
+      :limit  => options[:limit],
+      :offset => options[:offset]
+    )
+
+    if has_column?(:spent_hours)
+      Issue.load_visible_spent_hours(issues)
+    end
+    if has_column?(:relations)
+      Issue.load_visible_relations(issues)
+    end
+    issues
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the issues ids
+  def issue_ids(options={})
+    order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?)
+
+    Issue.visible.scoped(:conditions => options[:conditions]).scoped(:include => ([:status, :project] + (options[:include] || [])).uniq,
+                     :conditions => statement,
+                     :order => order_option,
+                     :joins => joins_for_order_statement(order_option.join(',')),
+                     :limit  => options[:limit],
+                     :offset => options[:offset]).find_ids
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the journals
+  # Valid options are :order, :offset, :limit
+  def journals(options={})
+    Journal.visible.all(
+      :include => [:details, :user, {:issue => [:project, :author, :tracker, :status]}],
+      :conditions => statement,
+      :order => options[:order],
+      :limit => options[:limit],
+      :offset => options[:offset]
+    )
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  # Returns the versions
+  # Valid options are :conditions
+  def versions(options={})
+    Version.visible.where(options[:conditions]).all(
+      :include => :project,
+      :conditions => project_statement
+    )
+  rescue ::ActiveRecord::StatementInvalid => e
+    raise StatementInvalid.new(e.message)
+  end
+
+  def sql_for_watcher_id_field(field, operator, value)
+    db_table = Watcher.table_name
+    "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND " +
+      sql_for_field(field, '=', value, db_table, 'user_id') + ')'
+  end
+
+  def sql_for_member_of_group_field(field, operator, value)
+    if operator == '*' # Any group
+      groups = Group.all
+      operator = '=' # Override the operator since we want to find by assigned_to
+    elsif operator == "!*"
+      groups = Group.all
+      operator = '!' # Override the operator since we want to find by assigned_to
+    else
+      groups = Group.find_all_by_id(value)
+    end
+    groups ||= []
+
+    members_of_groups = groups.inject([]) {|user_ids, group|
+      user_ids + group.user_ids + [group.id]
+    }.uniq.compact.sort.collect(&:to_s)
+
+    '(' + sql_for_field("assigned_to_id", operator, members_of_groups, Issue.table_name, "assigned_to_id", false) + ')'
+  end
+
+  def sql_for_assigned_to_role_field(field, operator, value)
+    case operator
+    when "*", "!*" # Member / Not member
+      sw = operator == "!*" ? 'NOT' : ''
+      nl = operator == "!*" ? "#{Issue.table_name}.assigned_to_id IS NULL OR" : ''
+      "(#{nl} #{Issue.table_name}.assigned_to_id #{sw} IN (SELECT DISTINCT #{Member.table_name}.user_id FROM #{Member.table_name}" +
+        " WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id))"
+    when "=", "!"
+      role_cond = value.any? ?
+        "#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")" :
+        "1=0"
+
+      sw = operator == "!" ? 'NOT' : ''
+      nl = operator == "!" ? "#{Issue.table_name}.assigned_to_id IS NULL OR" : ''
+      "(#{nl} #{Issue.table_name}.assigned_to_id #{sw} IN (SELECT DISTINCT #{Member.table_name}.user_id FROM #{Member.table_name}, #{MemberRole.table_name}" +
+        " WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id AND #{Member.table_name}.id = #{MemberRole.table_name}.member_id AND #{role_cond}))"
+    end
+  end
+
+  def sql_for_is_private_field(field, operator, value)
+    op = (operator == "=" ? 'IN' : 'NOT IN')
+    va = value.map {|v| v == '0' ? connection.quoted_false : connection.quoted_true}.uniq.join(',')
+
+    "#{Issue.table_name}.is_private #{op} (#{va})"
+  end
+
+  def sql_for_relations(field, operator, value, options={})
+    relation_options = IssueRelation::TYPES[field]
+    return relation_options unless relation_options
+
+    relation_type = field
+    join_column, target_join_column = "issue_from_id", "issue_to_id"
+    if relation_options[:reverse] || options[:reverse]
+      relation_type = relation_options[:reverse] || relation_type
+      join_column, target_join_column = target_join_column, join_column
+    end
+
+    sql = case operator
+      when "*", "!*"
+        op = (operator == "*" ? 'IN' : 'NOT IN')
+        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}')"
+      when "=", "!"
+        op = (operator == "=" ? 'IN' : 'NOT IN')
+        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = #{value.first.to_i})"
+      when "=p", "=!p", "!p"
+        op = (operator == "!p" ? 'NOT IN' : 'IN')
+        comp = (operator == "=!p" ? '<>' : '=')
+        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})"
+      end
+
+    if relation_options[:sym] == field && !options[:reverse]
+      sqls = [sql, sql_for_relations(field, operator, value, :reverse => true)]
+      sqls.join(["!", "!*", "!p"].include?(operator) ? " AND " : " OR ")
+    else
+      sql
+    end
+  end
+
+  IssueRelation::TYPES.keys.each do |relation_type|
+    alias_method "sql_for_#{relation_type}_field".to_sym, :sql_for_relations
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd app/models/issue_relation.rb
--- a/app/models/issue_relation.rb
+++ b/app/models/issue_relation.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -15,21 +15,21 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
-# Class used to represent the relations of an issue
-class IssueRelations < Array
-  include Redmine::I18n
+class IssueRelation < ActiveRecord::Base
+  # Class used to represent the relations of an issue
+  class Relations < Array
+    include Redmine::I18n
 
-  def initialize(issue, *args)
-    @issue = issue
-    super(*args)
+    def initialize(issue, *args)
+      @issue = issue
+      super(*args)
+    end
+
+    def to_s(*args)
+      map {|relation| "#{l(relation.label_for(@issue))} ##{relation.other_issue(@issue).id}"}.join(', ')
+    end
   end
 
-  def to_s(*args)
-    map {|relation| "#{l(relation.label_for(@issue))} ##{relation.other_issue(@issue).id}"}.join(', ')
-  end
-end
-
-class IssueRelation < ActiveRecord::Base
   belongs_to :issue_from, :class_name => 'Issue', :foreign_key => 'issue_from_id'
   belongs_to :issue_to, :class_name => 'Issue', :foreign_key => 'issue_to_id'
 
diff -r 0a574315af3e -r 4f746d8966dd app/models/issue_status.rb
--- a/app/models/issue_status.rb
+++ b/app/models/issue_status.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -28,7 +28,7 @@
   validates_length_of :name, :maximum => 30
   validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true
 
-  scope :sorted, order("#{table_name}.position ASC")
+  scope :sorted, lambda { order("#{table_name}.position ASC") }
   scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
 
   def update_default
diff -r 0a574315af3e -r 4f746d8966dd app/models/journal.rb
--- a/app/models/journal.rb
+++ b/app/models/journal.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -28,6 +28,7 @@
   acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
                 :description => :notes,
                 :author => :user,
+                :group => :issue,
                 :type => Proc.new {|o| (s = o.new_status) ? (s.is_closed? ? 'issue-closed' : 'issue-edit') : 'issue-note' },
                 :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
 
diff -r 0a574315af3e -r 4f746d8966dd app/models/journal_detail.rb
--- a/app/models/journal_detail.rb
+++ b/app/models/journal_detail.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -27,10 +27,13 @@
   end
 
   def normalize(v)
-    if v == true
+    case v
+    when true
       "1"
-    elsif v == false
+    when false
       "0"
+    when Date
+      v.strftime("%Y-%m-%d")
     else
       v
     end
diff -r 0a574315af3e -r 4f746d8966dd app/models/journal_observer.rb
--- a/app/models/journal_observer.rb
+++ b/app/models/journal_observer.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/mail_handler.rb
--- a/app/models/mail_handler.rb
+++ b/app/models/mail_handler.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -38,7 +38,9 @@
     # Status overridable by default
     @@handler_options[:allow_override] << 'status' unless @@handler_options[:issue].has_key?(:status)
 
-    @@handler_options[:no_permission_check] = (@@handler_options[:no_permission_check].to_s == '1' ? true : false)
+    @@handler_options[:no_account_notice] = (@@handler_options[:no_account_notice].to_s == '1')
+    @@handler_options[:no_notification] = (@@handler_options[:no_notification].to_s == '1')
+    @@handler_options[:no_permission_check] = (@@handler_options[:no_permission_check].to_s == '1')
 
     email.force_encoding('ASCII-8BIT') if email.respond_to?(:force_encoding)
     super(email)
@@ -97,7 +99,10 @@
           if logger && logger.info
             logger.info "MailHandler: [#{@user.login}] account created"
           end
-          Mailer.account_information(@user, @user.password).deliver
+          add_user_to_group(@@handler_options[:default_group])
+          unless @@handler_options[:no_account_notice]
+            Mailer.account_information(@user, @user.password).deliver
+          end
         else
           if logger && logger.error
             logger.error "MailHandler: could not create account for [#{sender_email}]"
@@ -107,7 +112,7 @@
       else
         # Default behaviour, emails from unknown users are ignored
         if logger && logger.info
-          logger.info  "MailHandler: ignoring email from unknown user [#{sender_email}]" 
+          logger.info  "MailHandler: ignoring email from unknown user [#{sender_email}]"
         end
         return false
       end
@@ -264,7 +269,7 @@
     if user.allowed_to?("add_#{obj.class.name.underscore}_watchers".to_sym, obj.project)
       addresses = [email.to, email.cc].flatten.compact.uniq.collect {|a| a.strip.downcase}
       unless addresses.empty?
-        watchers = User.active.find(:all, :conditions => ['LOWER(mail) IN (?)', addresses])
+        watchers = User.active.where('LOWER(mail) IN (?)', addresses).all
         watchers.each {|w| obj.add_watcher(w)}
       end
     end
@@ -338,7 +343,7 @@
     }.delete_if {|k, v| v.blank? }
 
     if issue.new_record? && attrs['tracker_id'].nil?
-      attrs['tracker_id'] = issue.project.trackers.find(:first).try(:id)
+      attrs['tracker_id'] = issue.project.trackers.first.try(:id)
     end
 
     attrs
@@ -396,18 +401,19 @@
     assign_string_attribute_with_limit(user, 'login', email_address, User::LOGIN_LENGTH_LIMIT)
 
     names = fullname.blank? ? email_address.gsub(/@.*$/, '').split('.') : fullname.split
-    assign_string_attribute_with_limit(user, 'firstname', names.shift)
-    assign_string_attribute_with_limit(user, 'lastname', names.join(' '))
+    assign_string_attribute_with_limit(user, 'firstname', names.shift, 30)
+    assign_string_attribute_with_limit(user, 'lastname', names.join(' '), 30)
     user.lastname = '-' if user.lastname.blank?
 
     password_length = [Setting.password_min_length.to_i, 10].max
     user.password = Redmine::Utils.random_hex(password_length / 2 + 1)
     user.language = Setting.default_language
+    user.mail_notification = 'only_my_events'
 
     unless user.valid?
       user.login = "user#{Redmine::Utils.random_hex(6)}" unless user.errors[:login].blank?
       user.firstname = "-" unless user.errors[:firstname].blank?
-      user.lastname  = "-" unless user.errors[:lastname].blank?
+      (puts user.errors[:lastname];user.lastname  = "-") unless user.errors[:lastname].blank?
     end
 
     user
@@ -423,6 +429,9 @@
     end
     if addr.present?
       user = self.class.new_user_from_attributes(addr, name)
+      if @@handler_options[:no_notification]
+        user.mail_notification = 'none'
+      end
       if user.save
         user
       else
@@ -435,6 +444,19 @@
     end
   end
 
+	# Adds the newly created user to default group
+  def add_user_to_group(default_group)
+    if default_group.present?
+      default_group.split(',').each do |group_name|
+        if group = Group.named(group_name).first
+          group.users << @user
+        elsif logger
+          logger.warn "MailHandler: could not add user to [#{group_name}], group not found"
+        end
+      end
+    end
+  end
+
   # Removes the email body of text after the truncation configurations.
   def cleanup_body(body)
     delimiters = Setting.mail_handler_body_delimiters.to_s.split(/[\r\n]+/).reject(&:blank?).map {|s| Regexp.escape(s)}
@@ -455,7 +477,7 @@
                  }
     if assignee.nil? && keyword.match(/ /)
       firstname, lastname = *(keyword.split) # "First Last Throwaway"
-      assignee ||= assignable.detect {|a| 
+      assignee ||= assignable.detect {|a|
                      a.is_a?(User) && a.firstname.to_s.downcase == firstname &&
                        a.lastname.to_s.downcase == lastname
                    }
diff -r 0a574315af3e -r 4f746d8966dd app/models/mailer.rb
--- a/app/models/mailer.rb
+++ b/app/models/mailer.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -280,7 +280,7 @@
   #   Mailer.account_activation_request(user).deliver => sends an email to all active administrators
   def account_activation_request(user)
     # Send the email to all active administrators
-    recipients = User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
+    recipients = User.active.where(:admin => true).all.collect { |u| u.mail }.compact
     @user = user
     @url = url_for(:controller => 'users', :action => 'index',
                          :status => User::STATUS_REGISTERED,
diff -r 0a574315af3e -r 4f746d8966dd app/models/member.rb
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -27,7 +27,6 @@
   validate :validate_role
 
   before_destroy :set_issue_category_nil
-  after_destroy :unwatch_from_permission_change
 
   def role
   end
@@ -52,7 +51,6 @@
     member_roles_to_destroy = member_roles.select {|mr| !ids.include?(mr.role_id)}
     if member_roles_to_destroy.any?
       member_roles_to_destroy.each(&:destroy)
-      unwatch_from_permission_change
     end
   end
 
@@ -97,18 +95,19 @@
     @membership
   end
 
+  # Finds or initilizes a Member for the given project and principal
+  def self.find_or_new(project, principal)
+    project_id = project.is_a?(Project) ? project.id : project
+    principal_id = principal.is_a?(Principal) ? principal.id : principal
+
+    member = Member.find_by_project_id_and_user_id(project_id, principal_id)
+    member ||= Member.new(:project_id => project_id, :user_id => principal_id)
+    member
+  end
+
   protected
 
   def validate_role
     errors.add_on_empty :role if member_roles.empty? && roles.empty?
   end
-
-  private
-
-  # Unwatch things that the user is no longer allowed to view inside project
-  def unwatch_from_permission_change
-    if user
-      Watcher.prune(:user => user, :project => project)
-    end
-  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/models/member_role.rb
--- a/app/models/member_role.rb
+++ b/app/models/member_role.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -21,8 +21,8 @@
 
   after_destroy :remove_member_if_empty
 
-  after_create :add_role_to_group_users
-  after_destroy :remove_role_from_group_users
+  after_create :add_role_to_group_users, :add_role_to_subprojects
+  after_destroy :remove_inherited_roles
 
   validates_presence_of :role
   validate :validate_role_member
@@ -44,21 +44,28 @@
   end
 
   def add_role_to_group_users
-    if member.principal.is_a?(Group)
+    if member.principal.is_a?(Group) && !inherited?
       member.principal.users.each do |user|
-        user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id)
+        user_member = Member.find_or_new(member.project_id, user.id)
         user_member.member_roles << MemberRole.new(:role => role, :inherited_from => id)
         user_member.save!
       end
     end
   end
 
-  def remove_role_from_group_users
-    MemberRole.find(:all, :conditions => { :inherited_from => id }).group_by(&:member).each do |member, member_roles|
-      member_roles.each(&:destroy)
-      if member && member.user
-        Watcher.prune(:user => member.user, :project => member.project)
+  def add_role_to_subprojects
+    member.project.children.each do |subproject|
+      if subproject.inherit_members?
+        child_member = Member.find_or_new(subproject.id, member.user_id)
+        child_member.member_roles << MemberRole.new(:role => role, :inherited_from => id)
+        child_member.save!
       end
     end
   end
+
+  def remove_inherited_roles
+    MemberRole.where(:inherited_from => id).all.group_by(&:member).each do |member, member_roles|
+      member_roles.each(&:destroy)
+    end
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/models/message.rb
--- a/app/models/message.rb
+++ b/app/models/message.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -29,6 +29,7 @@
                      :date_column => "#{table_name}.created_on"
   acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"},
                 :description => :content,
+                :group => :parent,
                 :type => Proc.new {|o| o.parent_id.nil? ? 'message' : 'reply'},
                 :url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id}.merge(o.parent_id.nil? ? {:id => o.id} :
                                                                                                                                        {:id => o.parent_id, :r => o.id, :anchor => "message-#{o.id}"})}
@@ -45,8 +46,9 @@
   after_update :update_messages_board
   after_destroy :reset_counters!
 
-  scope :visible, lambda {|*args| { :include => {:board => :project},
-                                          :conditions => Project.allowed_to_condition(args.shift || User.current, :view_messages, *args) } }
+  scope :visible, lambda {|*args|
+    includes(:board => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
+  }
 
   safe_attributes 'subject', 'content'
   safe_attributes 'locked', 'sticky', 'board_id',
@@ -65,7 +67,7 @@
 
   def update_messages_board
     if board_id_changed?
-      Message.update_all("board_id = #{board_id}", ["id = ? OR parent_id = ?", root.id, root.id])
+      Message.update_all({:board_id => board_id}, ["id = ? OR parent_id = ?", root.id, root.id])
       Board.reset_counters!(board_id_was)
       Board.reset_counters!(board_id)
     end
diff -r 0a574315af3e -r 4f746d8966dd app/models/message_observer.rb
--- a/app/models/message_observer.rb
+++ b/app/models/message_observer.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/news.rb
--- a/app/models/news.rb
+++ b/app/models/news.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -34,10 +34,9 @@
 
   after_create :add_author_as_watcher
 
-  scope :visible, lambda {|*args| {
-    :include => :project,
-    :conditions => Project.allowed_to_condition(args.shift || User.current, :view_news, *args)
-  }}
+  scope :visible, lambda {|*args|
+    includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args))
+  }
 
   safe_attributes 'title', 'summary', 'description'
 
@@ -50,6 +49,10 @@
     user.allowed_to?(:comment_news, project)
   end
 
+  def recipients
+    project.users.select {|user| user.notify_about?(self)}.map(&:mail)
+  end
+
   # returns latest news for projects visible by user
   def self.latest(user = User.current, count = 5)
     visible(user).includes([:author, :project]).order("#{News.table_name}.created_on DESC").limit(count).all
diff -r 0a574315af3e -r 4f746d8966dd app/models/news_observer.rb
--- a/app/models/news_observer.rb
+++ b/app/models/news_observer.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/principal.rb
--- a/app/models/principal.rb
+++ b/app/models/principal.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,13 +18,19 @@
 class Principal < ActiveRecord::Base
   self.table_name = "#{table_name_prefix}users#{table_name_suffix}"
 
+  # Account statuses
+  STATUS_ANONYMOUS  = 0
+  STATUS_ACTIVE     = 1
+  STATUS_REGISTERED = 2
+  STATUS_LOCKED     = 3
+
   has_many :members, :foreign_key => 'user_id', :dependent => :destroy
   has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status<>#{Project::STATUS_ARCHIVED}", :order => "#{Project.table_name}.name"
   has_many :projects, :through => :memberships
   has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
 
   # Groups and active users
-  scope :active, :conditions => "#{Principal.table_name}.status = 1"
+  scope :active, lambda { where(:status => STATUS_ACTIVE) }
 
   scope :like, lambda {|q|
     q = q.to_s
@@ -51,7 +57,7 @@
       where("1=0")
     else
       ids = projects.map(&:id)
-      where("#{Principal.table_name}.status = 1 AND #{Principal.table_name}.id IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE project_id IN (?))", ids)
+      active.uniq.joins(:members).where("#{Member.table_name}.project_id IN (?)", ids)
     end
   }
   # Principals that are not members of projects
@@ -64,6 +70,7 @@
       where("#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE project_id IN (?))", ids)
     end
   }
+  scope :sorted, lambda { order(*Principal.fields_for_order_statement)}
 
   before_create :set_default_empty_values
 
@@ -82,6 +89,15 @@
     end
   end
 
+  # Returns an array of fields names than can be used to make an order statement for principals.
+  # Users are sorted before Groups.
+  # Examples:
+  def self.fields_for_order_statement(table=nil)
+    table ||= table_name
+    columns = ['type DESC'] + (User.name_formatter[:order] - ['id']) + ['lastname', 'id']
+    columns.uniq.map {|field| "#{table}.#{field}"}
+  end
+
   protected
 
   # Make sure we don't try to insert NULL values (see #4632)
diff -r 0a574315af3e -r 4f746d8966dd app/models/project.rb
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -28,11 +28,11 @@
 
   # Specific overidden Activities
   has_many :time_entry_activities
-  has_many :members, :include => [:principal, :roles], :conditions => "#{User.table_name}.type='User' AND #{User.table_name}.status=#{User::STATUS_ACTIVE}"
+  has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}"
   has_many :memberships, :class_name => 'Member'
   has_many :member_principals, :class_name => 'Member',
                                :include => :principal,
-                               :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{User::STATUS_ACTIVE})"
+                               :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE})"
   has_many :users, :through => :members
   has_many :principals, :through => :member_principals, :source => :principal
 
@@ -42,7 +42,7 @@
   has_many :issue_changes, :through => :issues, :source => :journals
   has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC"
   has_many :time_entries, :dependent => :delete_all
-  has_many :queries, :dependent => :delete_all
+  has_many :queries, :class_name => 'IssueQuery', :dependent => :delete_all
   has_many :documents, :dependent => :destroy
   has_many :news, :dependent => :destroy, :include => :author
   has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name"
@@ -77,19 +77,22 @@
   validates_length_of :homepage, :maximum => 255
   validates_length_of :identifier, :in => 1..IDENTIFIER_MAX_LENGTH
   # donwcase letters, digits, dashes but not digits only
-  validates_format_of :identifier, :with => /^(?!\d+$)[a-z0-9\-_]*$/, :if => Proc.new { |p| p.identifier_changed? }
+  validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? }
   # reserved words
   validates_exclusion_of :identifier, :in => %w( new )
 
   after_save :update_position_under_parent, :if => Proc.new {|project| project.name_changed?}
+  after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?}
   before_destroy :delete_all_members
 
-  scope :has_module, lambda { |mod| { :conditions => ["#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s] } }
-  scope :active, { :conditions => "#{Project.table_name}.status = #{STATUS_ACTIVE}"}
-  scope :status, lambda {|arg| arg.blank? ? {} : {:conditions => {:status => arg.to_i}} }
-  scope :all_public, { :conditions => { :is_public => true } }
-  scope :visible, lambda {|*args| {:conditions => Project.visible_condition(args.shift || User.current, *args) }}
+  scope :has_module, lambda {|mod|
+    where("#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s)
+  }
+  scope :active, lambda { where(:status => STATUS_ACTIVE) }
+  scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) }
+  scope :all_public, lambda { where(:is_public => true) }
   scope :visible_roots, lambda { { :conditions => Project.root_visible_by(User.current) } }
+  scope :visible, lambda {|*args| where(Project.visible_condition(args.shift || User.current, *args)) }
   scope :allowed_to, lambda {|*args| 
     user = User.current
     permission = nil
@@ -99,14 +102,14 @@
       user = args.shift
       permission = args.shift
     end
-    { :conditions => Project.allowed_to_condition(user, permission, *args) }
+    where(Project.allowed_to_condition(user, permission, *args))
   }
   scope :like, lambda {|arg|
     if arg.blank?
-      {}
+      where(nil)
     else
       pattern = "%#{arg.to_s.strip.downcase}%"
-      {:conditions => ["LOWER(identifier) LIKE :p OR LOWER(name) LIKE :p", {:p => pattern}]}
+      where("LOWER(identifier) LIKE :p OR LOWER(name) LIKE :p", :p => pattern)
     end
   }
 
@@ -124,7 +127,12 @@
       self.enabled_module_names = Setting.default_projects_modules
     end
     if !initialized.key?('trackers') && !initialized.key?('tracker_ids')
-      self.trackers = Tracker.sorted.all
+      default = Setting.default_projects_tracker_ids
+      if default.is_a?(Array)
+        self.trackers = Tracker.where(:id => default.map(&:to_i)).sorted.all
+      else
+        self.trackers = Tracker.sorted.all
+      end
     end
   end
 
@@ -139,8 +147,8 @@
   # returns latest created projects
   # non public projects will be returned only if user is a member of those
   def self.latest(user=nil, count=5)
-    visible(user).find(:all, :limit => count, :order => "created_on DESC")	
-  end	
+    visible(user).limit(count).order("created_on DESC").all
+  end
 
   # Returns true if the project is visible to +user+ or to the current user.
   def visible?(user=User.current)
@@ -282,6 +290,7 @@
     self.find(*args)
   end
 
+  alias :base_reload :reload
   def reload(*args)
     @shared_versions = nil
     @rolled_up_versions = nil
@@ -292,7 +301,9 @@
     @allowed_parents = nil
     @allowed_permissions = nil
     @actions_allowed = nil
-    super
+    @start_date = nil
+    @due_date = nil
+    base_reload(*args)
   end
 
   def to_param
@@ -313,9 +324,12 @@
     # Check that there is no issue of a non descendant project that is assigned
     # to one of the project or descendant versions
     v_ids = self_and_descendants.collect {|p| p.version_ids}.flatten
-    if v_ids.any? && Issue.find(:first, :include => :project,
-                                        :conditions => ["(#{Project.table_name}.lft < ? OR #{Project.table_name}.rgt > ?)" +
-                                                        " AND #{Issue.table_name}.fixed_version_id IN (?)", lft, rgt, v_ids])
+    if v_ids.any? &&
+      Issue.
+        includes(:project).
+        where("#{Project.table_name}.lft < ? OR #{Project.table_name}.rgt > ?", lft, rgt).
+        where("#{Issue.table_name}.fixed_version_id IN (?)", v_ids).
+        exists?
       return false
     end
     Project.transaction do
@@ -343,7 +357,7 @@
   # by the current user
   def allowed_parents
     return @allowed_parents if @allowed_parents
-    @allowed_parents = Project.find(:all, :conditions => Project.allowed_to_condition(User.current, :add_subprojects))
+    @allowed_parents = Project.where(Project.allowed_to_condition(User.current, :add_subprojects)).all
     @allowed_parents = @allowed_parents - self_and_descendants
     if User.current.allowed_to?(:add_project, nil, :global => true) || (!new_record? && parent.nil?)
       @allowed_parents << nil
@@ -411,16 +425,19 @@
   # Returns an array of the trackers used by the project and its active sub projects
   def rolled_up_trackers
     @rolled_up_trackers ||=
-      Tracker.find(:all, :joins => :projects,
-                         :select => "DISTINCT #{Tracker.table_name}.*",
-                         :conditions => ["#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt],
-                         :order => "#{Tracker.table_name}.position")
+      Tracker.
+        joins(:projects).
+        joins("JOIN #{EnabledModule.table_name} ON #{EnabledModule.table_name}.project_id = #{Project.table_name}.id AND #{EnabledModule.table_name}.name = 'issue_tracking'").
+        select("DISTINCT #{Tracker.table_name}.*").
+        where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> #{STATUS_ARCHIVED}", lft, rgt).
+        sorted.
+        all
   end
 
   # Closes open and locked project versions that are completed
   def close_completed_versions
     Version.transaction do
-      versions.find(:all, :conditions => {:status => %w(open locked)}).each do |version|
+      versions.where(:status => %w(open locked)).all.each do |version|
         if version.completed?
           version.update_attribute(:status, 'closed')
         end
@@ -457,7 +474,7 @@
 
   # Returns a hash of project users grouped by role
   def users_by_role
-    members.find(:all, :include => [:user, :roles]).inject({}) do |h, m|
+    members.includes(:user, :roles).all.inject({}) do |h, m|
       m.roles.each do |r|
         h[r] ||= []
         h[r] << m.user
@@ -550,20 +567,20 @@
 
   # The earliest start date of a project, based on it's issues and versions
   def start_date
-    [
+    @start_date ||= [
      issues.minimum('start_date'),
-     shared_versions.collect(&:effective_date),
-     shared_versions.collect(&:start_date)
-    ].flatten.compact.min
+     shared_versions.minimum('effective_date'),
+     Issue.fixed_version(shared_versions).minimum('start_date')
+    ].compact.min
   end
 
   # The latest due date of an issue or version
   def due_date
-    [
+    @due_date ||= [
      issues.maximum('due_date'),
-     shared_versions.collect(&:effective_date),
-     shared_versions.collect {|v| v.fixed_issues.maximum('due_date')}
-    ].flatten.compact.max
+     shared_versions.maximum('effective_date'),
+     Issue.fixed_version(shared_versions).maximum('due_date')
+    ].compact.max
   end
 
   def overdue?
@@ -579,7 +596,7 @@
       total / self_and_descendants.count
     else
       if versions.count > 0
-        total = versions.collect(&:completed_pourcent).sum
+        total = versions.collect(&:completed_percent).sum
 
         total / versions.count
       else
@@ -662,6 +679,9 @@
   safe_attributes 'enabled_module_names',
     :if => lambda {|project, user| project.new_record? || user.allowed_to?(:select_project_modules, project) }
 
+  safe_attributes 'inherit_members',
+    :if => lambda {|project, user| project.parent.nil? || project.parent.visible?(user)}
+
   # Returns an array of projects that are in this project's hierarchy
   #
   # Example: parents, children, siblings
@@ -673,7 +693,7 @@
 
   # Returns an auto-generated project identifier based on the last identifier used
   def self.next_identifier
-    p = Project.find(:first, :order => 'created_on DESC')
+    p = Project.order('id DESC').first
     p.nil? ? nil : p.identifier.to_s.succ
   end
 
@@ -710,27 +730,17 @@
     end
   end
 
-
-  # Copies +project+ and returns the new instance.  This will not save
-  # the copy
+  # Returns a new unsaved Project instance with attributes copied from +project+
   def self.copy_from(project)
-    begin
-      project = project.is_a?(Project) ? project : Project.find(project)
-      if project
-        # clear unique attributes
-        attributes = project.attributes.dup.except('id', 'name', 'identifier', 'status', 'parent_id', 'lft', 'rgt')
-        copy = Project.new(attributes)
-        copy.enabled_modules = project.enabled_modules
-        copy.trackers = project.trackers
-        copy.custom_values = project.custom_values.collect {|v| v.clone}
-        copy.issue_custom_fields = project.issue_custom_fields
-        return copy
-      else
-        return nil
-      end
-    rescue ActiveRecord::RecordNotFound
-      return nil
-    end
+    project = project.is_a?(Project) ? project : Project.find(project)
+    # clear unique attributes
+    attributes = project.attributes.dup.except('id', 'name', 'identifier', 'status', 'parent_id', 'lft', 'rgt')
+    copy = Project.new(attributes)
+    copy.enabled_modules = project.enabled_modules
+    copy.trackers = project.trackers
+    copy.custom_values = project.custom_values.collect {|v| v.clone}
+    copy.issue_custom_fields = project.issue_custom_fields
+    copy
   end
 
   # Yields the given block for each project with its level in the tree
@@ -747,6 +757,44 @@
 
   private
 
+  def after_parent_changed(parent_was)
+    remove_inherited_member_roles
+    add_inherited_member_roles
+  end
+
+  def update_inherited_members
+    if parent
+      if inherit_members? && !inherit_members_was
+        remove_inherited_member_roles
+        add_inherited_member_roles
+      elsif !inherit_members? && inherit_members_was
+        remove_inherited_member_roles
+      end
+    end
+  end
+
+  def remove_inherited_member_roles
+    member_roles = memberships.map(&:member_roles).flatten
+    member_role_ids = member_roles.map(&:id)
+    member_roles.each do |member_role|
+      if member_role.inherited_from && !member_role_ids.include?(member_role.inherited_from)
+        member_role.destroy
+      end
+    end
+  end
+
+  def add_inherited_member_roles
+    if inherit_members? && parent
+      parent.memberships.each do |parent_member|
+        member = Member.find_or_new(self.id, parent_member.user_id)
+        parent_member.member_roles.each do |parent_member_role|
+          member.member_roles << MemberRole.new(:role => parent_member_role.role, :inherited_from => parent_member_role.id)
+        end
+        member.save!
+      end
+    end
+  end
+
   # Copies wiki from +project+
   def copy_wiki(project)
     # Check that the source project has a wiki first
@@ -808,10 +856,13 @@
 
     # Get issues sorted by root_id, lft so that parent issues
     # get copied before their children
-    project.issues.find(:all, :order => 'root_id, lft').each do |issue|
+    project.issues.reorder('root_id, lft').all.each do |issue|
       new_issue = Issue.new
       new_issue.copy_from(issue, :subtasks => false, :link => false)
       new_issue.project = self
+      # Changing project resets the custom field values
+      # TODO: handle this in Issue#project=
+      new_issue.custom_field_values = issue.custom_field_values.inject({}) {|h,v| h[v.custom_field_id] = v.value; h}
       # Reassign fixed_versions by name, since names are unique per project
       if issue.fixed_version && issue.fixed_version.project == project
         new_issue.fixed_version = self.versions.detect {|v| v.name == issue.fixed_version.name}
@@ -894,7 +945,7 @@
   # Copies queries from +project+
   def copy_queries(project)
     project.queries.each do |query|
-      new_query = ::Query.new
+      new_query = IssueQuery.new
       new_query.attributes = query.attributes.dup.except("id", "project_id", "sort_criteria")
       new_query.sort_criteria = query.sort_criteria if query.sort_criteria
       new_query.project = self
@@ -951,13 +1002,11 @@
   def system_activities_and_project_overrides(include_inactive=false)
     if include_inactive
       return TimeEntryActivity.shared.
-        find(:all,
-             :conditions => ["id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)]) +
+        where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all +
         self.time_entry_activities
     else
       return TimeEntryActivity.shared.active.
-        find(:all,
-             :conditions => ["id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)]) +
+        where("id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)).all +
         self.time_entry_activities.active
     end
   end
@@ -976,6 +1025,7 @@
 
   # Inserts/moves the project so that target's children or root projects stay alphabetically sorted
   def set_or_update_position_under(target_parent)
+    parent_was = parent
     sibs = (target_parent.nil? ? self.class.roots : target_parent.children)
     to_be_inserted_before = sibs.sort_by {|c| c.name.to_s.downcase}.detect {|c| c.name.to_s.downcase > name.to_s.downcase }
 
@@ -992,5 +1042,8 @@
       # move_to_child_of adds the project in last (ie.right) position
       move_to_child_of(target_parent)
     end
+    if parent_was != target_parent
+      after_parent_changed(parent_was)
+    end
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/models/project_custom_field.rb
--- a/app/models/project_custom_field.rb
+++ b/app/models/project_custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/query.rb
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -28,11 +28,12 @@
     end
     self.default_order = options[:default_order]
     @inline = options.key?(:inline) ? options[:inline] : true
-    @caption_key = options[:caption] || "field_#{name}"
+    @caption_key = options[:caption] || "field_#{name}".to_sym
+    @frozen = options[:frozen]
   end
 
   def caption
-    l(@caption_key)
+    @caption_key.is_a?(Symbol) ? l(@caption_key) : @caption_key
   end
 
   # Returns true if the column is sortable, otherwise false
@@ -48,8 +49,12 @@
     @inline
   end
 
-  def value(issue)
-    issue.send name
+  def frozen?
+    @frozen
+  end
+
+  def value(object)
+    object.send name
   end
 
   def css_classes
@@ -75,8 +80,8 @@
     @cf
   end
 
-  def value(issue)
-    cv = issue.custom_values.select {|v| v.custom_field_id == @cf.id}.collect {|v| @cf.cast_value(v.value)}
+  def value(object)
+    cv = object.custom_values.select {|v| v.custom_field_id == @cf.id}.collect {|v| @cf.cast_value(v.value)}
     cv.size > 1 ? cv.sort {|a,b| a.to_s <=> b.to_s} : cv.first
   end
 
@@ -85,6 +90,28 @@
   end
 end
 
+class QueryAssociationCustomFieldColumn < QueryCustomFieldColumn
+
+  def initialize(association, custom_field)
+    super(custom_field)
+    self.name = "#{association}.cf_#{custom_field.id}".to_sym
+    # TODO: support sorting/grouping by association custom field
+    self.sortable = false
+    self.groupable = false
+    @association = association
+  end
+
+  def value(object)
+    if assoc = object.send(@association)
+      super(assoc)
+    end
+  end
+
+  def css_classes
+    @css_classes ||= "#{@association}_cf_#{@cf.id} #{@cf.field_format}"
+  end
+end
+
 class Query < ActiveRecord::Base
   class StatementInvalid < ::ActiveRecord::StatementInvalid
   end
@@ -101,85 +128,89 @@
   validates_length_of :name, :maximum => 255
   validate :validate_query_filters
 
-  @@operators = { "="   => :label_equals,
-                  "!"   => :label_not_equals,
-                  "o"   => :label_open_issues,
-                  "c"   => :label_closed_issues,
-                  "!*"  => :label_none,
-                  "*"   => :label_any,
-                  ">="  => :label_greater_or_equal,
-                  "<="  => :label_less_or_equal,
-                  "><"  => :label_between,
-                  "<t+" => :label_in_less_than,
-                  ">t+" => :label_in_more_than,
-                  "><t+"=> :label_in_the_next_days,
-                  "t+"  => :label_in,
-                  "t"   => :label_today,
-                  "w"   => :label_this_week,
-                  ">t-" => :label_less_than_ago,
-                  "<t-" => :label_more_than_ago,
-                  "><t-"=> :label_in_the_past_days,
-                  "t-"  => :label_ago,
-                  "~"   => :label_contains,
-                  "!~"  => :label_not_contains,
-                  "=p"  => :label_any_issues_in_project,
-                  "=!p" => :label_any_issues_not_in_project,
-                  "!p"  => :label_no_issues_in_project}
+  class_attribute :operators
+  self.operators = {
+    "="   => :label_equals,
+    "!"   => :label_not_equals,
+    "o"   => :label_open_issues,
+    "c"   => :label_closed_issues,
+    "!*"  => :label_none,
+    "*"   => :label_any,
+    ">="  => :label_greater_or_equal,
+    "<="  => :label_less_or_equal,
+    "><"  => :label_between,
+    "<t+" => :label_in_less_than,
+    ">t+" => :label_in_more_than,
+    "><t+"=> :label_in_the_next_days,
+    "t+"  => :label_in,
+    "t"   => :label_today,
+    "ld"  => :label_yesterday,
+    "w"   => :label_this_week,
+    "lw"  => :label_last_week,
+    "l2w" => [:label_last_n_weeks, {:count => 2}],
+    "m"   => :label_this_month,
+    "lm"  => :label_last_month,
+    "y"   => :label_this_year,
+    ">t-" => :label_less_than_ago,
+    "<t-" => :label_more_than_ago,
+    "><t-"=> :label_in_the_past_days,
+    "t-"  => :label_ago,
+    "~"   => :label_contains,
+    "!~"  => :label_not_contains,
+    "=p"  => :label_any_issues_in_project,
+    "=!p" => :label_any_issues_not_in_project,
+    "!p"  => :label_no_issues_in_project
+  }
 
-  cattr_reader :operators
+  class_attribute :operators_by_filter_type
+  self.operators_by_filter_type = {
+    :list => [ "=", "!" ],
+    :list_status => [ "o", "=", "!", "c", "*" ],
+    :list_optional => [ "=", "!", "!*", "*" ],
+    :list_subprojects => [ "*", "!*", "=" ],
+    :date => [ "=", ">=", "<=", "><", "<t+", ">t+", "><t+", "t+", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", ">t-", "<t-", "><t-", "t-", "!*", "*" ],
+    :date_past => [ "=", ">=", "<=", "><", ">t-", "<t-", "><t-", "t-", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "!*", "*" ],
+    :string => [ "=", "~", "!", "!~", "!*", "*" ],
+    :text => [  "~", "!~", "!*", "*" ],
+    :integer => [ "=", ">=", "<=", "><", "!*", "*" ],
+    :float => [ "=", ">=", "<=", "><", "!*", "*" ],
+    :relation => ["=", "=p", "=!p", "!p", "!*", "*"]
+  }
 
-  @@operators_by_filter_type = { :list => [ "=", "!" ],
-                                 :list_status => [ "o", "=", "!", "c", "*" ],
-                                 :list_optional => [ "=", "!", "!*", "*" ],
-                                 :list_subprojects => [ "*", "!*", "=" ],
-                                 :date => [ "=", ">=", "<=", "><", "<t+", ">t+", "><t+", "t+", "t", "w", ">t-", "<t-", "><t-", "t-", "!*", "*" ],
-                                 :date_past => [ "=", ">=", "<=", "><", ">t-", "<t-", "><t-", "t-", "t", "w", "!*", "*" ],
-                                 :string => [ "=", "~", "!", "!~", "!*", "*" ],
-                                 :text => [  "~", "!~", "!*", "*" ],
-                                 :integer => [ "=", ">=", "<=", "><", "!*", "*" ],
-                                 :float => [ "=", ">=", "<=", "><", "!*", "*" ],
-                                 :relation => ["=", "=p", "=!p", "!p", "!*", "*"]}
+  class_attribute :available_columns
+  self.available_columns = []
 
-  cattr_reader :operators_by_filter_type
+  class_attribute :queried_class
 
-  @@available_columns = [
-    QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
-    QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position", :groupable => true),
-    QueryColumn.new(:parent, :sortable => ["#{Issue.table_name}.root_id", "#{Issue.table_name}.lft ASC"], :default_order => 'desc', :caption => :field_parent_issue),
-    QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true),
-    QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc', :groupable => true),
-    QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
-    QueryColumn.new(:author, :sortable => lambda {User.fields_for_order_statement("authors")}, :groupable => true),
-    QueryColumn.new(:assigned_to, :sortable => lambda {User.fields_for_order_statement}, :groupable => true),
-    QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'),
-    QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true),
-    QueryColumn.new(:fixed_version, :sortable => lambda {Version.fields_for_order_statement}, :groupable => true),
-    QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date"),
-    QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date"),
-    QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours"),
-    QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true),
-    QueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc'),
-    QueryColumn.new(:relations, :caption => :label_related_issues),
-    QueryColumn.new(:description, :inline => false)
-  ]
-  cattr_reader :available_columns
-
-  scope :visible, lambda {|*args|
-    user = args.shift || User.current
-    base = Project.allowed_to_condition(user, :view_issues, *args)
-    user_id = user.logged? ? user.id : 0
-    {
-      :conditions => ["(#{table_name}.project_id IS NULL OR (#{base})) AND (#{table_name}.is_public = ? OR #{table_name}.user_id = ?)", true, user_id],
-      :include => :project
-    }
-  }
+  def queried_table_name
+    @queried_table_name ||= self.class.queried_class.table_name
+  end
 
   def initialize(attributes=nil, *args)
     super attributes
-    self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} }
     @is_for_all = project.nil?
   end
 
+  # Builds the query from the given params
+  def build_from_params(params)
+    if params[:fields] || params[:f]
+      self.filters = {}
+      add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v])
+    else
+      available_filters.keys.each do |field|
+        add_short_filter(field, params[field]) if params[field]
+      end
+    end
+    self.group_by = params[:group_by] || (params[:query] && params[:query][:group_by])
+    self.column_names = params[:c] || (params[:query] && params[:query][:column_names])
+    self
+  end
+
+  # Builds a new query from the given params and attributes
+  def self.build_from_params(params, attributes={})
+    new(attributes).build_from_params(params)
+  end
+
   def validate_query_filters
     filters.each_key do |field|
       if values_for(field)
@@ -202,7 +233,7 @@
           # filter requires one or more values
           (values_for(field) and !values_for(field).first.blank?) or
           # filter doesn't require any value
-          ["o", "c", "!*", "*", "t", "w"].include? operator_for(field)
+          ["o", "c", "!*", "*", "t", "ld", "w", "lw", "l2w", "m", "lm", "y"].include? operator_for(field)
     end if filters
   end
 
@@ -211,11 +242,6 @@
     errors.add(:base, m)
   end
 
-  # Returns true if the query is visible to +user+ or the current user.
-  def visible?(user=User.current)
-    (project.nil? || user.allowed_to?(:view_issues, project)) && (self.is_public? || self.user_id == user.id)
-  end
-
   def editable_by?(user)
     return false unless user
     # Admin can edit them all and regular users can edit their private queries
@@ -225,154 +251,12 @@
   end
 
   def trackers
-    @trackers ||= project.nil? ? Tracker.find(:all, :order => 'position') : project.rolled_up_trackers
+    @trackers ||= project.nil? ? Tracker.sorted.all : project.rolled_up_trackers
   end
 
   # Returns a hash of localized labels for all filter operators
   def self.operators_labels
-    operators.inject({}) {|h, operator| h[operator.first] = l(operator.last); h}
-  end
-
-  def available_filters
-    return @available_filters if @available_filters
-    @available_filters = {
-      "status_id" => {
-        :type => :list_status, :order => 0,
-        :values => IssueStatus.find(:all, :order => 'position').collect{|s| [s.name, s.id.to_s] }
-       },
-      "tracker_id" => {
-        :type => :list, :order => 2, :values => trackers.collect{|s| [s.name, s.id.to_s] }
-       },
-      "priority_id" => {
-        :type => :list, :order => 3, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s] }
-       },
-      "subject" => { :type => :text, :order => 8 },
-      "created_on" => { :type => :date_past, :order => 9 },
-      "updated_on" => { :type => :date_past, :order => 10 },
-      "start_date" => { :type => :date, :order => 11 },
-      "due_date" => { :type => :date, :order => 12 },
-      "estimated_hours" => { :type => :float, :order => 13 },
-      "done_ratio" =>  { :type => :integer, :order => 14 }
-    }
-    IssueRelation::TYPES.each do |relation_type, options|
-      @available_filters[relation_type] = {
-        :type => :relation, :order => @available_filters.size + 100,
-        :label => options[:name]
-      }
-    end
-    principals = []
-    if project
-      principals += project.principals.sort
-      unless project.leaf?
-        subprojects = project.descendants.visible.all
-        if subprojects.any?
-          @available_filters["subproject_id"] = {
-            :type => :list_subprojects, :order => 13,
-            :values => subprojects.collect{|s| [s.name, s.id.to_s] }
-          }
-          principals += Principal.member_of(subprojects)
-        end
-      end
-    else
-      if all_projects.any?
-        # members of visible projects
-        principals += Principal.member_of(all_projects)
-        # project filter
-        project_values = []
-        if User.current.logged? && User.current.memberships.any?
-          project_values << ["<< #{l(:label_my_projects).downcase} >>", "mine"]
-        end
-        project_values += all_projects_values
-        @available_filters["project_id"] = {
-          :type => :list, :order => 1, :values => project_values
-        } unless project_values.empty?
-      end
-    end
-    principals.uniq!
-    principals.sort!
-    users = principals.select {|p| p.is_a?(User)}
-
-    assigned_to_values = []
-    assigned_to_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
-    assigned_to_values += (Setting.issue_group_assignment? ?
-                              principals : users).collect{|s| [s.name, s.id.to_s] }
-    @available_filters["assigned_to_id"] = {
-      :type => :list_optional, :order => 4, :values => assigned_to_values
-    } unless assigned_to_values.empty?
-
-    author_values = []
-    author_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
-    author_values += users.collect{|s| [s.name, s.id.to_s] }
-    @available_filters["author_id"] = {
-      :type => :list, :order => 5, :values => author_values
-    } unless author_values.empty?
-
-    group_values = Group.all.collect {|g| [g.name, g.id.to_s] }
-    @available_filters["member_of_group"] = {
-      :type => :list_optional, :order => 6, :values => group_values
-    } unless group_values.empty?
-
-    role_values = Role.givable.collect {|r| [r.name, r.id.to_s] }
-    @available_filters["assigned_to_role"] = {
-      :type => :list_optional, :order => 7, :values => role_values
-    } unless role_values.empty?
-
-    if User.current.logged?
-      @available_filters["watcher_id"] = {
-        :type => :list, :order => 15, :values => [["<< #{l(:label_me)} >>", "me"]]
-      }
-    end
-
-    if project
-      # project specific filters
-      categories = project.issue_categories.all
-      unless categories.empty?
-        @available_filters["category_id"] = {
-          :type => :list_optional, :order => 6,
-          :values => categories.collect{|s| [s.name, s.id.to_s] }
-        }
-      end
-      versions = project.shared_versions.all
-      unless versions.empty?
-        @available_filters["fixed_version_id"] = {
-          :type => :list_optional, :order => 7,
-          :values => versions.sort.collect{|s| ["#{s.project.name} - #{s.name}", s.id.to_s] }
-        }
-      end
-      add_custom_fields_filters(project.all_issue_custom_fields)
-    else
-      # global filters for cross project issue list
-      system_shared_versions = Version.visible.find_all_by_sharing('system')
-      unless system_shared_versions.empty?
-        @available_filters["fixed_version_id"] = {
-          :type => :list_optional, :order => 7,
-          :values => system_shared_versions.sort.collect{|s|
-                                       ["#{s.project.name} - #{s.name}", s.id.to_s]
-                                     }
-        }
-      end
-      add_custom_fields_filters(
-                   IssueCustomField.find(:all,
-                                         :conditions => {
-                                            :is_filter => true,
-                                            :is_for_all => true
-                                         }))
-    end
-    add_associations_custom_fields_filters :project, :author, :assigned_to, :fixed_version
-    if User.current.allowed_to?(:set_issues_private, nil, :global => true) ||
-      User.current.allowed_to?(:set_own_issues_private, nil, :global => true)
-      @available_filters["is_private"] = {
-        :type => :list, :order => 16,
-        :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]]
-      }
-    end
-    Tracker.disabled_core_fields(trackers).each {|field|
-      @available_filters.delete field
-    }
-    @available_filters.each do |field, options|
-      options[:name] ||= l(options[:label] || "field_#{field}".gsub(/_id$/, ''))
-    end
-    @available_filters
+    operators.inject({}) {|h, operator| h[operator.first] = l(*operator.last); h}
   end
 
   # Returns a representation of the available filters for JSON serialization
@@ -399,17 +283,43 @@
     @all_projects_values = values
   end
 
-  def add_filter(field, operator, values)
+  # Adds available filters
+  def initialize_available_filters
+    # implemented by sub-classes
+  end
+  protected :initialize_available_filters
+
+  # Adds an available filter
+  def add_available_filter(field, options)
+    @available_filters ||= ActiveSupport::OrderedHash.new
+    @available_filters[field] = options
+    @available_filters
+  end
+
+  # Removes an available filter
+  def delete_available_filter(field)
+    if @available_filters
+      @available_filters.delete(field)
+    end
+  end
+
+  # Return a hash of available filters
+  def available_filters
+    unless @available_filters
+      initialize_available_filters
+      @available_filters.each do |field, options|
+        options[:name] ||= l(options[:label] || "field_#{field}".gsub(/_id$/, ''))
+      end
+    end
+    @available_filters
+  end
+
+  def add_filter(field, operator, values=nil)
     # values must be an array
     return unless values.nil? || values.is_a?(Array)
     # check if field is defined as an available filter
     if available_filters.has_key? field
       filter_options = available_filters[field]
-      # check if operator is allowed for that filter
-      #if @@operators_by_filter_type[filter_options[:type]].include? operator
-      #  allowed_values = values & ([""] + (filter_options[:values] || []).collect {|val| val[1]})
-      #  filters[field] = {:operator => operator, :values => allowed_values } if (allowed_values.first and !allowed_values.first.empty?) or ["o", "c", "!*", "*", "t"].include? operator
-      #end
       filters[field] = {:operator => operator, :values => (values || [''])}
     end
   end
@@ -417,9 +327,10 @@
   def add_short_filter(field, expression)
     return unless expression && available_filters.has_key?(field)
     field_type = available_filters[field][:type]
-    @@operators_by_filter_type[field_type].sort.reverse.detect do |operator|
+    operators_by_filter_type[field_type].sort.reverse.detect do |operator|
       next unless expression =~ /^#{Regexp.escape(operator)}(.*)$/
-      add_filter field, operator, $1.present? ? $1.split('|') : ['']
+      values = $1
+      add_filter field, operator, values.present? ? values.split('|') : ['']
     end || add_filter(field, '=', expression.split('|'))
   end
 
@@ -457,43 +368,6 @@
     label ||= l("field_#{field.to_s.gsub(/_id$/, '')}", :default => field)
   end
 
-  def available_columns
-    return @available_columns if @available_columns
-    @available_columns = ::Query.available_columns.dup
-    @available_columns += (project ?
-                            project.all_issue_custom_fields :
-                            IssueCustomField.find(:all)
-                           ).collect {|cf| QueryCustomFieldColumn.new(cf) }
-
-    if User.current.allowed_to?(:view_time_entries, project, :global => true)
-      index = nil
-      @available_columns.each_with_index {|column, i| index = i if column.name == :estimated_hours}
-      index = (index ? index + 1 : -1)
-      # insert the column after estimated_hours or at the end
-      @available_columns.insert index, QueryColumn.new(:spent_hours,
-        :sortable => "(SELECT COALESCE(SUM(hours), 0) FROM #{TimeEntry.table_name} WHERE #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id)",
-        :default_order => 'desc',
-        :caption => :label_spent_time
-      )
-    end
-
-    if User.current.allowed_to?(:set_issues_private, nil, :global => true) ||
-      User.current.allowed_to?(:set_own_issues_private, nil, :global => true)
-      @available_columns << QueryColumn.new(:is_private, :sortable => "#{Issue.table_name}.is_private")
-    end
-
-    disabled_fields = Tracker.disabled_core_fields(trackers).map {|field| field.sub(/_id$/, '')}
-    @available_columns.reject! {|column|
-      disabled_fields.include?(column.name.to_s)
-    }
-
-    @available_columns
-  end
-
-  def self.available_columns=(v)
-    self.available_columns = (v)
-  end
-
   def self.add_available_column(column)
     self.available_columns << (column) if column.is_a?(QueryColumn)
   end
@@ -505,17 +379,18 @@
 
   # Returns a Hash of columns and the key for sorting
   def sortable_columns
-    {'id' => "#{Issue.table_name}.id"}.merge(available_columns.inject({}) {|h, column|
-                                               h[column.name.to_s] = column.sortable
-                                               h
-                                             })
+    available_columns.inject({}) {|h, column|
+      h[column.name.to_s] = column.sortable
+      h
+    }
   end
 
   def columns
     # preserve the column_names order
-    (has_default_columns? ? default_columns_names : column_names).collect do |name|
+    cols = (has_default_columns? ? default_columns_names : column_names).collect do |name|
        available_columns.find { |col| col.name == name }
     end.compact
+    available_columns.select(&:frozen?) | cols
   end
 
   def inline_columns
@@ -535,11 +410,7 @@
   end
 
   def default_columns_names
-    @default_columns_names ||= begin
-      default_columns = Setting.issue_list_default_columns.map(&:to_sym)
-
-      project.present? ? default_columns : [:project] | default_columns
-    end
+    []
   end
 
   def column_names=(names)
@@ -645,7 +516,7 @@
       operator = operator_for(field)
 
       # "me" value subsitution
-      if %w(assigned_to_id author_id watcher_id).include?(field)
+      if %w(assigned_to_id author_id user_id watcher_id).include?(field)
         if v.delete("me")
           if User.current.logged?
             v.push(User.current.id.to_s)
@@ -670,7 +541,7 @@
         filters_clauses << send("sql_for_#{field}_field", field, operator, v)
       else
         # regular field
-        filters_clauses << '(' + sql_for_field(field, operator, v, Issue.table_name, field) + ')'
+        filters_clauses << '(' + sql_for_field(field, operator, v, queried_table_name, field) + ')'
       end
     end if filters and valid?
 
@@ -680,182 +551,6 @@
     filters_clauses.any? ? filters_clauses.join(' AND ') : nil
   end
 
-  # Returns the issue count
-  def issue_count
-    Issue.visible.count(:include => [:status, :project], :conditions => statement)
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  # Returns the issue count by group or nil if query is not grouped
-  def issue_count_by_group
-    r = nil
-    if grouped?
-      begin
-        # Rails3 will raise an (unexpected) RecordNotFound if there's only a nil group value
-        r = Issue.visible.count(:group => group_by_statement, :include => [:status, :project], :conditions => statement)
-      rescue ActiveRecord::RecordNotFound
-        r = {nil => issue_count}
-      end
-      c = group_by_column
-      if c.is_a?(QueryCustomFieldColumn)
-        r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h}
-      end
-    end
-    r
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  # Returns the issues
-  # Valid options are :order, :offset, :limit, :include, :conditions
-  def issues(options={})
-    order_option = [group_by_sort_order, options[:order]].reject {|s| s.blank?}.join(',')
-    order_option = nil if order_option.blank?
-
-    issues = Issue.visible.scoped(:conditions => options[:conditions]).find :all, :include => ([:status, :project] + (options[:include] || [])).uniq,
-                     :conditions => statement,
-                     :order => order_option,
-                     :joins => joins_for_order_statement(order_option),
-                     :limit  => options[:limit],
-                     :offset => options[:offset]
-
-    if has_column?(:spent_hours)
-      Issue.load_visible_spent_hours(issues)
-    end
-    if has_column?(:relations)
-      Issue.load_visible_relations(issues)
-    end
-    issues
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  # Returns the issues ids
-  def issue_ids(options={})
-    order_option = [group_by_sort_order, options[:order]].reject {|s| s.blank?}.join(',')
-    order_option = nil if order_option.blank?
-
-    Issue.visible.scoped(:conditions => options[:conditions]).scoped(:include => ([:status, :project] + (options[:include] || [])).uniq,
-                     :conditions => statement,
-                     :order => order_option,
-                     :joins => joins_for_order_statement(order_option),
-                     :limit  => options[:limit],
-                     :offset => options[:offset]).find_ids
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  # Returns the journals
-  # Valid options are :order, :offset, :limit
-  def journals(options={})
-    Journal.visible.find :all, :include => [:details, :user, {:issue => [:project, :author, :tracker, :status]}],
-                       :conditions => statement,
-                       :order => options[:order],
-                       :limit => options[:limit],
-                       :offset => options[:offset]
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  # Returns the versions
-  # Valid options are :conditions
-  def versions(options={})
-    Version.visible.scoped(:conditions => options[:conditions]).find :all, :include => :project, :conditions => project_statement
-  rescue ::ActiveRecord::StatementInvalid => e
-    raise StatementInvalid.new(e.message)
-  end
-
-  def sql_for_watcher_id_field(field, operator, value)
-    db_table = Watcher.table_name
-    "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND " +
-      sql_for_field(field, '=', value, db_table, 'user_id') + ')'
-  end
-
-  def sql_for_member_of_group_field(field, operator, value)
-    if operator == '*' # Any group
-      groups = Group.all
-      operator = '=' # Override the operator since we want to find by assigned_to
-    elsif operator == "!*"
-      groups = Group.all
-      operator = '!' # Override the operator since we want to find by assigned_to
-    else
-      groups = Group.find_all_by_id(value)
-    end
-    groups ||= []
-
-    members_of_groups = groups.inject([]) {|user_ids, group|
-      if group && group.user_ids.present?
-        user_ids << group.user_ids
-      end
-      user_ids.flatten.uniq.compact
-    }.sort.collect(&:to_s)
-
-    '(' + sql_for_field("assigned_to_id", operator, members_of_groups, Issue.table_name, "assigned_to_id", false) + ')'
-  end
-
-  def sql_for_assigned_to_role_field(field, operator, value)
-    case operator
-    when "*", "!*" # Member / Not member
-      sw = operator == "!*" ? 'NOT' : ''
-      nl = operator == "!*" ? "#{Issue.table_name}.assigned_to_id IS NULL OR" : ''
-      "(#{nl} #{Issue.table_name}.assigned_to_id #{sw} IN (SELECT DISTINCT #{Member.table_name}.user_id FROM #{Member.table_name}" +
-        " WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id))"
-    when "=", "!"
-      role_cond = value.any? ?
-        "#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")" :
-        "1=0"
-
-      sw = operator == "!" ? 'NOT' : ''
-      nl = operator == "!" ? "#{Issue.table_name}.assigned_to_id IS NULL OR" : ''
-      "(#{nl} #{Issue.table_name}.assigned_to_id #{sw} IN (SELECT DISTINCT #{Member.table_name}.user_id FROM #{Member.table_name}, #{MemberRole.table_name}" +
-        " WHERE #{Member.table_name}.project_id = #{Issue.table_name}.project_id AND #{Member.table_name}.id = #{MemberRole.table_name}.member_id AND #{role_cond}))"
-    end
-  end
-
-  def sql_for_is_private_field(field, operator, value)
-    op = (operator == "=" ? 'IN' : 'NOT IN')
-    va = value.map {|v| v == '0' ? connection.quoted_false : connection.quoted_true}.uniq.join(',')
-
-    "#{Issue.table_name}.is_private #{op} (#{va})"
-  end
-
-  def sql_for_relations(field, operator, value, options={})
-    relation_options = IssueRelation::TYPES[field]
-    return relation_options unless relation_options
-
-    relation_type = field
-    join_column, target_join_column = "issue_from_id", "issue_to_id"
-    if relation_options[:reverse] || options[:reverse]
-      relation_type = relation_options[:reverse] || relation_type
-      join_column, target_join_column = target_join_column, join_column
-    end
-
-    sql = case operator
-      when "*", "!*"
-        op = (operator == "*" ? 'IN' : 'NOT IN')
-        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}')"
-      when "=", "!"
-        op = (operator == "=" ? 'IN' : 'NOT IN')
-        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = #{value.first.to_i})"
-      when "=p", "=!p", "!p"
-        op = (operator == "!p" ? 'NOT IN' : 'IN')
-        comp = (operator == "=!p" ? '<>' : '=')
-        "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})"
-      end
-
-    if relation_options[:sym] == field && !options[:reverse]
-      sqls = [sql, sql_for_relations(field, operator, value, :reverse => true)]
-      sqls.join(["!", "!*", "!p"].include?(operator) ? " AND " : " OR ")
-    else
-      sql
-    end
-  end
-
-  IssueRelation::TYPES.keys.each do |relation_type|
-    alias_method "sql_for_#{relation_type}_field".to_sym, :sql_for_relations
-  end
-
   private
 
   def sql_for_custom_field(field, operator, value, custom_field_id)
@@ -875,15 +570,18 @@
       not_in = 'NOT'
     end
     customized_key = "id"
-    customized_class = Issue
+    customized_class = queried_class
     if field =~ /^(.+)\.cf_/
       assoc = $1
       customized_key = "#{assoc}_id"
-      customized_class = Issue.reflect_on_association(assoc.to_sym).klass.base_class rescue nil
-      raise "Unknown Issue association #{assoc}" unless customized_class
+      customized_class = queried_class.reflect_on_association(assoc.to_sym).klass.base_class rescue nil
+      raise "Unknown #{queried_class.name} association #{assoc}" unless customized_class
     end
-    "#{Issue.table_name}.#{customized_key} #{not_in} IN (SELECT #{customized_class.table_name}.id FROM #{customized_class.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='#{customized_class}' AND #{db_table}.customized_id=#{customized_class.table_name}.id AND #{db_table}.custom_field_id=#{custom_field_id} WHERE " +
-      sql_for_field(field, operator, value, db_table, db_field, true) + ')'
+    where = sql_for_field(field, operator, value, db_table, db_field, true)
+    if operator =~ /[<>]/
+      where = "(#{where}) AND #{db_table}.#{db_field} <> ''"
+    end
+    "#{queried_table_name}.#{customized_key} #{not_in} IN (SELECT #{customized_class.table_name}.id FROM #{customized_class.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='#{customized_class}' AND #{db_table}.customized_id=#{customized_class.table_name}.id AND #{db_table}.custom_field_id=#{custom_field_id} WHERE #{where})"
   end
 
   # Helper method to generate the WHERE sql for a +field+, +operator+ and a +value+
@@ -897,13 +595,13 @@
           sql = date_clause(db_table, db_field, (Date.parse(value.first) rescue nil), (Date.parse(value.first) rescue nil))
         when :integer
           if is_custom_filter
-            sql = "(#{db_table}.#{db_field} <> '' AND CAST(#{db_table}.#{db_field} AS decimal(60,3)) = #{value.first.to_i})"
+            sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) = #{value.first.to_i})"
           else
             sql = "#{db_table}.#{db_field} = #{value.first.to_i}"
           end
         when :float
           if is_custom_filter
-            sql = "(#{db_table}.#{db_field} <> '' AND CAST(#{db_table}.#{db_field} AS decimal(60,3)) BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5})"
+            sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5})"
           else
             sql = "#{db_table}.#{db_field} BETWEEN #{value.first.to_f - 1e-5} AND #{value.first.to_f + 1e-5}"
           end
@@ -932,7 +630,7 @@
         sql = date_clause(db_table, db_field, (Date.parse(value.first) rescue nil), nil)
       else
         if is_custom_filter
-          sql = "(#{db_table}.#{db_field} <> '' AND CAST(#{db_table}.#{db_field} AS decimal(60,3)) >= #{value.first.to_f})"
+          sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) >= #{value.first.to_f})"
         else
           sql = "#{db_table}.#{db_field} >= #{value.first.to_f}"
         end
@@ -942,7 +640,7 @@
         sql = date_clause(db_table, db_field, nil, (Date.parse(value.first) rescue nil))
       else
         if is_custom_filter
-          sql = "(#{db_table}.#{db_field} <> '' AND CAST(#{db_table}.#{db_field} AS decimal(60,3)) <= #{value.first.to_f})"
+          sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) <= #{value.first.to_f})"
         else
           sql = "#{db_table}.#{db_field} <= #{value.first.to_f}"
         end
@@ -952,15 +650,15 @@
         sql = date_clause(db_table, db_field, (Date.parse(value[0]) rescue nil), (Date.parse(value[1]) rescue nil))
       else
         if is_custom_filter
-          sql = "(#{db_table}.#{db_field} <> '' AND CAST(#{db_table}.#{db_field} AS decimal(60,3)) BETWEEN #{value[0].to_f} AND #{value[1].to_f})"
+          sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) BETWEEN #{value[0].to_f} AND #{value[1].to_f})"
         else
           sql = "#{db_table}.#{db_field} BETWEEN #{value[0].to_f} AND #{value[1].to_f}"
         end
       end
     when "o"
-      sql = "#{Issue.table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_false})" if field == "status_id"
+      sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_false})" if field == "status_id"
     when "c"
-      sql = "#{Issue.table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_true})" if field == "status_id"
+      sql = "#{queried_table_name}.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_true})" if field == "status_id"
     when "><t-"
       # between today - n days and today
       sql = relative_date_clause(db_table, db_field, - value.first.to_i, 0)
@@ -988,12 +686,39 @@
     when "t"
       # = today
       sql = relative_date_clause(db_table, db_field, 0, 0)
+    when "ld"
+      # = yesterday
+      sql = relative_date_clause(db_table, db_field, -1, -1)
     when "w"
       # = this week
       first_day_of_week = l(:general_first_day_of_week).to_i
       day_of_week = Date.today.cwday
       days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
       sql = relative_date_clause(db_table, db_field, - days_ago, - days_ago + 6)
+    when "lw"
+      # = last week
+      first_day_of_week = l(:general_first_day_of_week).to_i
+      day_of_week = Date.today.cwday
+      days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
+      sql = relative_date_clause(db_table, db_field, - days_ago - 7, - days_ago - 1)
+    when "l2w"
+      # = last 2 weeks
+      first_day_of_week = l(:general_first_day_of_week).to_i
+      day_of_week = Date.today.cwday
+      days_ago = (day_of_week >= first_day_of_week ? day_of_week - first_day_of_week : day_of_week + 7 - first_day_of_week)
+      sql = relative_date_clause(db_table, db_field, - days_ago - 14, - days_ago - 1)
+    when "m"
+      # = this month
+      date = Date.today
+      sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month)
+    when "lm"
+      # = last month
+      date = Date.today.prev_month
+      sql = date_clause(db_table, db_field, date.beginning_of_month, date.end_of_month)
+    when "y"
+      # = this year
+      date = Date.today
+      sql = date_clause(db_table, db_field, date.beginning_of_year, date.end_of_year)
     when "~"
       sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
     when "!~"
@@ -1007,31 +732,30 @@
 
   def add_custom_fields_filters(custom_fields, assoc=nil)
     return unless custom_fields.present?
-    @available_filters ||= {}
 
-    custom_fields.select(&:is_filter?).each do |field|
+    custom_fields.select(&:is_filter?).sort.each do |field|
       case field.field_format
       when "text"
-        options = { :type => :text, :order => 20 }
+        options = { :type => :text }
       when "list"
-        options = { :type => :list_optional, :values => field.possible_values, :order => 20}
+        options = { :type => :list_optional, :values => field.possible_values }
       when "date"
-        options = { :type => :date, :order => 20 }
+        options = { :type => :date }
       when "bool"
-        options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], :order => 20 }
+        options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]] }
       when "int"
-        options = { :type => :integer, :order => 20 }
+        options = { :type => :integer }
       when "float"
-        options = { :type => :float, :order => 20 }
+        options = { :type => :float }
       when "user", "version"
         next unless project
         values = field.possible_values_options(project)
         if User.current.logged? && field.field_format == 'user'
           values.unshift ["<< #{l(:label_me)} >>", "me"]
         end
-        options = { :type => :list_optional, :values => values, :order => 20}
+        options = { :type => :list_optional, :values => values }
       else
-        options = { :type => :string, :order => 20 }
+        options = { :type => :string }
       end
       filter_id = "cf_#{field.id}"
       filter_name = field.name
@@ -1039,7 +763,7 @@
         filter_id = "#{assoc}.#{filter_id}"
         filter_name = l("label_attribute_of_#{assoc}", :name => filter_name)
       end
-      @available_filters[filter_id] = options.merge({
+      add_available_filter filter_id, options.merge({
                :name => filter_name,
                :format => field.field_format,
                :field => field
@@ -1050,7 +774,7 @@
   def add_associations_custom_fields_filters(*associations)
     fields_by_class = CustomField.where(:is_filter => true).group_by(&:class)
     associations.each do |assoc|
-      association_klass = Issue.reflect_on_association(assoc).klass
+      association_klass = queried_class.reflect_on_association(assoc).klass
       fields_by_class.each do |field_class, fields|
         if field_class.customized_class <= association_klass
           add_custom_fields_filters(fields, assoc)
@@ -1091,7 +815,7 @@
 
     if order_options
       if order_options.include?('authors')
-        joins << "LEFT OUTER JOIN #{User.table_name} authors ON authors.id = #{Issue.table_name}.author_id"
+        joins << "LEFT OUTER JOIN #{User.table_name} authors ON authors.id = #{queried_table_name}.author_id"
       end
       order_options.scan(/cf_\d+/).uniq.each do |name|
         column = available_columns.detect {|c| c.name.to_s == name}
diff -r 0a574315af3e -r 4f746d8966dd app/models/repository.rb
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -42,7 +42,7 @@
   validates_uniqueness_of :identifier, :scope => :project_id, :allow_blank => true
   validates_exclusion_of :identifier, :in => %w(show entry raw changes annotate diff show stats graph)
   # donwcase letters, digits, dashes, underscores but not digits only
-  validates_format_of :identifier, :with => /^(?!\d+$)[a-z0-9\-_]*$/, :allow_blank => true
+  validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :allow_blank => true
   # Checks if the SCM is enabled when creating a repository
   validate :repo_create_validation, :on => :create
 
@@ -234,12 +234,15 @@
   def find_changeset_by_name(name)
     return nil if name.blank?
     s = name.to_s
-    changesets.find(:first, :conditions => (s.match(/^\d*$/) ?
-          ["revision = ?", s] : ["revision LIKE ?", s + '%']))
+    if s.match(/^\d*$/)
+      changesets.where("revision = ?", s).first
+    else
+      changesets.where("revision LIKE ?", s + '%').first
+    end
   end
 
   def latest_changeset
-    @latest_changeset ||= changesets.find(:first)
+    @latest_changeset ||= changesets.first
   end
 
   # Returns the latest changesets for +path+
@@ -301,7 +304,7 @@
       return @found_committer_users[committer] if @found_committer_users.has_key?(committer)
 
       user = nil
-      c = changesets.find(:first, :conditions => {:committer => committer}, :include => :user)
+      c = changesets.where(:committer => committer).includes(:user).first
       if c && c.user
         user = c.user
       elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/
@@ -337,7 +340,7 @@
 
   # scan changeset comments to find related and fixed issues for all repositories
   def self.scan_changesets_for_issue_ids
-    find(:all).each(&:scan_changesets_for_issue_ids)
+    all.each(&:scan_changesets_for_issue_ids)
   end
 
   def self.scm_name
diff -r 0a574315af3e -r 4f746d8966dd app/models/repository/bazaar.rb
--- a/app/models/repository/bazaar.rb
+++ b/app/models/repository/bazaar.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/repository/cvs.rb
--- a/app/models/repository/cvs.rb
+++ b/app/models/repository/cvs.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/repository/darcs.rb
--- a/app/models/repository/darcs.rb
+++ b/app/models/repository/darcs.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/repository/filesystem.rb
--- a/app/models/repository/filesystem.rb
+++ b/app/models/repository/filesystem.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # FileSystem adapter
 # File written by Paul Rivier, at Demotera.
diff -r 0a574315af3e -r 4f746d8966dd app/models/repository/git.rb
--- a/app/models/repository/git.rb
+++ b/app/models/repository/git.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 # Copyright (C) 2007  Patrick Aljord patcito@Å‹mail.com
 #
 # This program is free software; you can redistribute it and/or
@@ -251,8 +251,7 @@
       :conditions => [
         "scmid IN (?)",
         revisions.map!{|c| c.scmid}
-      ],
-      :order => 'committed_on DESC'
+      ]
     )
   end
 
diff -r 0a574315af3e -r 4f746d8966dd app/models/repository/mercurial.rb
--- a/app/models/repository/mercurial.rb
+++ b/app/models/repository/mercurial.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -92,11 +92,12 @@
   # Sqlite3 and PostgreSQL pass.
   # Is this MySQL bug?
   def latest_changesets(path, rev, limit=10)
-    changesets.find(:all,
-                    :include    => :user,
-                    :conditions => latest_changesets_cond(path, rev, limit),
-                    :limit      => limit,
-                    :order      => "#{Changeset.table_name}.id DESC")
+    changesets.
+      includes(:user).
+      where(latest_changesets_cond(path, rev, limit)).
+      limit(limit).
+      order("#{Changeset.table_name}.id DESC").
+      all
   end
 
   def latest_changesets_cond(path, rev, limit)
diff -r 0a574315af3e -r 4f746d8966dd app/models/repository/subversion.rb
--- a/app/models/repository/subversion.rb
+++ b/app/models/repository/subversion.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -20,7 +20,7 @@
 class Repository::Subversion < Repository
   attr_protected :root_url
   validates_presence_of :url
-  validates_format_of :url, :with => /^(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
+  validates_format_of :url, :with => /\A(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
 
   def self.scm_adapter_class
     Redmine::Scm::Adapters::SubversionAdapter
diff -r 0a574315af3e -r 4f746d8966dd app/models/role.rb
--- a/app/models/role.rb
+++ b/app/models/role.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -39,8 +39,8 @@
     ['own', :label_issues_visibility_own]
   ]
 
-  scope :sorted, order("#{table_name}.builtin ASC, #{table_name}.position ASC")
-  scope :givable, order("#{table_name}.position ASC").where(:builtin => 0)
+  scope :sorted, lambda { order("#{table_name}.builtin ASC, #{table_name}.position ASC") }
+  scope :givable, lambda { order("#{table_name}.position ASC").where(:builtin => 0) }
   scope :builtin, lambda { |*args|
     compare = (args.first == true ? 'not' : '')
     where("#{compare} builtin = 0")
diff -r 0a574315af3e -r 4f746d8966dd app/models/setting.rb
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,15 +18,15 @@
 class Setting < ActiveRecord::Base
 
   DATE_FORMATS = [
-	'%Y-%m-%d',
-	'%d/%m/%Y',
-	'%d.%m.%Y',
-	'%d-%m-%Y',
-	'%m/%d/%Y',
-	'%d %b %Y',
-	'%d %B %Y',
-	'%b %d, %Y',
-	'%B %d, %Y'
+        '%Y-%m-%d',
+        '%d/%m/%Y',
+        '%d.%m.%Y',
+        '%d-%m-%Y',
+        '%m/%d/%Y',
+        '%d %b %Y',
+        '%d %B %Y',
+        '%b %d, %Y',
+        '%B %d, %Y'
     ]
 
   TIME_FORMATS = [
diff -r 0a574315af3e -r 4f746d8966dd app/models/time_entry.rb
--- a/app/models/time_entry.rb
+++ b/app/models/time_entry.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,6 +30,7 @@
   acts_as_event :title => Proc.new {|o| "#{l_hours(o.hours)} (#{(o.issue || o.project).event_title})"},
                 :url => Proc.new {|o| {:controller => 'timelog', :action => 'index', :project_id => o.project, :issue_id => o.issue}},
                 :author => :user,
+                :group => :issue,
                 :description => :comments
 
   acts_as_activity_provider :timestamp => "#{table_name}.created_on",
@@ -39,30 +40,28 @@
   validates_presence_of :user_id, :activity_id, :project_id, :hours, :spent_on
   validates_numericality_of :hours, :allow_nil => true, :message => :invalid
   validates_length_of :comments, :maximum => 255, :allow_nil => true
+  validates :spent_on, :date => true
   before_validation :set_project_if_nil
   validate :validate_time_entry
 
-  scope :visible, lambda {|*args| {
-    :include => :project,
-    :conditions => Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args)
-  }}
-  scope :on_issue, lambda {|issue| {
-    :include => :issue,
-    :conditions => "#{Issue.table_name}.root_id = #{issue.root_id} AND #{Issue.table_name}.lft >= #{issue.lft} AND #{Issue.table_name}.rgt <= #{issue.rgt}"
-  }}
-  scope :on_project, lambda {|project, include_subprojects| {
-    :include => :project,
-    :conditions => project.project_condition(include_subprojects)
-  }}
+  scope :visible, lambda {|*args|
+    includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args))
+  }
+  scope :on_issue, lambda {|issue|
+    includes(:issue).where("#{Issue.table_name}.root_id = #{issue.root_id} AND #{Issue.table_name}.lft >= #{issue.lft} AND #{Issue.table_name}.rgt <= #{issue.rgt}")
+  }
+  scope :on_project, lambda {|project, include_subprojects|
+    includes(:project).where(project.project_condition(include_subprojects))
+  }
   scope :spent_between, lambda {|from, to|
     if from && to
-     {:conditions => ["#{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", from, to]}
+     where("#{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", from, to)
     elsif from
-     {:conditions => ["#{TimeEntry.table_name}.spent_on >= ?", from]}
+     where("#{TimeEntry.table_name}.spent_on >= ?", from)
     elsif to
-     {:conditions => ["#{TimeEntry.table_name}.spent_on <= ?", to]}
+     where("#{TimeEntry.table_name}.spent_on <= ?", to)
     else
-     {}
+     where(nil)
     end
   }
 
diff -r 0a574315af3e -r 4f746d8966dd app/models/time_entry_activity.rb
--- a/app/models/time_entry_activity.rb
+++ b/app/models/time_entry_activity.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,11 +24,15 @@
     OptionName
   end
 
+  def objects
+    TimeEntry.where(:activity_id => self_and_descendants(1).map(&:id))
+  end
+
   def objects_count
-    time_entries.count
+    objects.count
   end
 
   def transfer_relations(to)
-    time_entries.update_all("activity_id = #{to.id}")
+    objects.update_all(:activity_id => to.id)
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/models/time_entry_activity_custom_field.rb
--- a/app/models/time_entry_activity_custom_field.rb
+++ b/app/models/time_entry_activity_custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/time_entry_custom_field.rb
--- a/app/models/time_entry_custom_field.rb
+++ b/app/models/time_entry_custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/time_entry_query.rb
--- /dev/null
+++ b/app/models/time_entry_query.rb
@@ -0,0 +1,115 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class TimeEntryQuery < Query
+
+  self.queried_class = TimeEntry
+
+  self.available_columns = [
+    QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
+    QueryColumn.new(:spent_on, :sortable => ["#{TimeEntry.table_name}.spent_on", "#{TimeEntry.table_name}.created_on"], :default_order => 'desc', :groupable => true),
+    QueryColumn.new(:user, :sortable => lambda {User.fields_for_order_statement}, :groupable => true),
+    QueryColumn.new(:activity, :sortable => "#{TimeEntryActivity.table_name}.position", :groupable => true),
+    QueryColumn.new(:issue, :sortable => "#{Issue.table_name}.id"),
+    QueryColumn.new(:comments),
+    QueryColumn.new(:hours, :sortable => "#{TimeEntry.table_name}.hours"),
+  ]
+
+  def initialize(attributes=nil, *args)
+    super attributes
+    self.filters ||= {}
+    add_filter('spent_on', '*') unless filters.present?
+  end
+
+  def initialize_available_filters
+    add_available_filter "spent_on", :type => :date_past
+
+    principals = []
+    if project
+      principals += project.principals.sort
+      unless project.leaf?
+        subprojects = project.descendants.visible.all
+        if subprojects.any?
+          add_available_filter "subproject_id",
+            :type => :list_subprojects,
+            :values => subprojects.collect{|s| [s.name, s.id.to_s] }
+          principals += Principal.member_of(subprojects)
+        end
+      end
+    else
+      if all_projects.any?
+        # members of visible projects
+        principals += Principal.member_of(all_projects)
+        # project filter
+        project_values = []
+        if User.current.logged? && User.current.memberships.any?
+          project_values << ["<< #{l(:label_my_projects).downcase} >>", "mine"]
+        end
+        project_values += all_projects_values
+        add_available_filter("project_id",
+          :type => :list, :values => project_values
+        ) unless project_values.empty?
+      end
+    end
+    principals.uniq!
+    principals.sort!
+    users = principals.select {|p| p.is_a?(User)}
+
+    users_values = []
+    users_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
+    users_values += users.collect{|s| [s.name, s.id.to_s] }
+    add_available_filter("user_id",
+      :type => :list_optional, :values => users_values
+    ) unless users_values.empty?
+
+    activities = (project ? project.activities : TimeEntryActivity.shared.active)
+    add_available_filter("activity_id",
+      :type => :list, :values => activities.map {|a| [a.name, a.id.to_s]}
+    ) unless activities.empty?
+
+    add_available_filter "comments", :type => :text
+    add_available_filter "hours", :type => :float
+
+    add_custom_fields_filters(TimeEntryCustomField.where(:is_filter => true).all)
+    add_associations_custom_fields_filters :project, :issue, :user
+  end
+
+  def available_columns
+    return @available_columns if @available_columns
+    @available_columns = self.class.available_columns.dup
+    @available_columns += TimeEntryCustomField.all.map {|cf| QueryCustomFieldColumn.new(cf) }
+    @available_columns += IssueCustomField.all.map {|cf| QueryAssociationCustomFieldColumn.new(:issue, cf) }
+    @available_columns
+  end
+
+  def default_columns_names
+    @default_columns_names ||= [:project, :spent_on, :user, :activity, :issue, :comments, :hours]
+  end
+
+  # Accepts :from/:to params as shortcut filters
+  def build_from_params(params)
+    super
+    if params[:from].present? && params[:to].present?
+      add_filter('spent_on', '><', [params[:from], params[:to]])
+    elsif params[:from].present?
+      add_filter('spent_on', '>=', [params[:from]])
+    elsif params[:to].present?
+      add_filter('spent_on', '<=', [params[:to]])
+    end
+    self
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd app/models/token.rb
--- a/app/models/token.rb
+++ b/app/models/token.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -37,11 +37,43 @@
     Token.delete_all ["action NOT IN (?) AND created_on < ?", ['feeds', 'api'], Time.now - @@validity_time]
   end
 
-private
+  # Returns the active user who owns the key for the given action
+  def self.find_active_user(action, key, validity_days=nil)
+    user = find_user(action, key, validity_days)
+    if user && user.active?
+      user
+    end
+  end
+
+  # Returns the user who owns the key for the given action
+  def self.find_user(action, key, validity_days=nil)
+    token = find_token(action, key, validity_days)
+    if token
+      token.user
+    end
+  end
+
+  # Returns the token for action and key with an optional
+  # validity duration (in number of days)
+  def self.find_token(action, key, validity_days=nil)
+    action = action.to_s
+    key = key.to_s
+    return nil unless action.present? && key =~ /\A[a-z0-9]+\z/i
+
+    token = Token.where(:action => action, :value => key).first
+    if token && (token.action == action) && (token.value == key) && token.user
+      if validity_days.nil? || (token.created_on > validity_days.days.ago)
+        token
+      end
+    end
+  end
+
   def self.generate_token_value
     Redmine::Utils.random_hex(20)
   end
 
+  private
+
   # Removes obsolete tokens (same user and action)
   def delete_previous_tokens
     if user
diff -r 0a574315af3e -r 4f746d8966dd app/models/tracker.rb
--- a/app/models/tracker.rb
+++ b/app/models/tracker.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -35,13 +35,13 @@
   has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :association_foreign_key => 'custom_field_id'
   acts_as_list
 
-  attr_protected :field_bits
+  attr_protected :fields_bits
 
   validates_presence_of :name
   validates_uniqueness_of :name
   validates_length_of :name, :maximum => 30
 
-  scope :sorted, order("#{table_name}.position ASC")
+  scope :sorted, lambda { order("#{table_name}.position ASC") }
   scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
 
   def to_s; name end
diff -r 0a574315af3e -r 4f746d8966dd app/models/user.rb
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -20,12 +20,6 @@
 class User < Principal
   include Redmine::SafeAttributes
 
-  # Account statuses
-  STATUS_ANONYMOUS  = 0
-  STATUS_ACTIVE     = 1
-  STATUS_REGISTERED = 2
-  STATUS_LOCKED     = 3
-
   # Different ways of displaying/sorting users
   USER_FORMATS = {
     :firstname_lastname => {
@@ -82,8 +76,8 @@
   has_one :api_token, :class_name => 'Token', :conditions => "action='api'"
   belongs_to :auth_source
 
-  scope :logged, :conditions => "#{User.table_name}.status <> #{STATUS_ANONYMOUS}"
-  scope :status, lambda {|arg| arg.blank? ? {} : {:conditions => {:status => arg.to_i}} }
+  scope :logged, lambda { where("#{User.table_name}.status <> #{STATUS_ANONYMOUS}") }
+  scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) }
 
   has_one :ssamr_user_detail, :dependent => :destroy, :class_name => 'SsamrUserDetail'
   accepts_nested_attributes_for :ssamr_user_detail
@@ -103,12 +97,11 @@
   validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
   validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, :case_sensitive => false
   validates_uniqueness_of :mail, :if => Proc.new { |user| user.mail_changed? && user.mail.present? }, :case_sensitive => false
-  
-  # Login must contain lettres, numbers, underscores only
-  validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
+  # Login must contain letters, numbers, underscores only
+  validates_format_of :login, :with => /\A[a-z0-9_\-@\.]*\z/i
   validates_length_of :login, :maximum => LOGIN_LENGTH_LIMIT
   validates_length_of :firstname, :lastname, :maximum => 30
-  validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_blank => true
+  validates_format_of :mail, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true
   validates_length_of :mail, :maximum => MAIL_LENGTH_LIMIT, :allow_nil => true
   validates_confirmation_of :password, :allow_nil => true
   validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true
@@ -128,6 +121,7 @@
     group_id = group.is_a?(Group) ? group.id : group.to_i
     where("#{User.table_name}.id NOT IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id)
   }
+  scope :sorted, lambda { order(*User.fields_for_order_statement)}
 
   def set_mail_notification
     self.mail_notification = Setting.default_notification_option if self.mail_notification.blank?
@@ -141,10 +135,12 @@
     end
   end
 
+  alias :base_reload :reload
   def reload(*args)
     @name = nil
     @projects_by_role = nil
-    super
+    @membership_by_project_id = nil
+    base_reload(*args)
   end
 
   def mail=(arg)
@@ -162,7 +158,7 @@
       begin
         write_attribute(:identity_url, OpenIdAuthentication.normalize_identifier(url))
       rescue OpenIdAuthentication::InvalidOpenId
-        # Invlaid url, don't save
+        # Invalid url, don't save
       end
     end
     self.read_attribute(:identity_url)
@@ -173,19 +169,13 @@
     login = login.to_s
     password = password.to_s
 
-    # Make sure no one can sign in with an empty password
-    return nil if password.empty?
+    # Make sure no one can sign in with an empty login or password
+    return nil if login.empty? || password.empty?
     user = find_by_login(login)
     if user
       # user is already in local database
-      return nil if !user.active?
-      if user.auth_source
-        # user has an external authentication method
-        return nil unless user.auth_source.authenticate(login, password)
-      else
-        # authentication with local password
-        return nil unless user.check_password?(password)
-      end
+      return nil unless user.active?
+      return nil unless user.check_password?(password)
     else
       # user is not yet registered, try to authenticate with available sources
       attrs = AuthSource.authenticate(login, password)
@@ -199,7 +189,7 @@
         end
       end
     end
-    user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
+    user.update_column(:last_login_on, Time.now) if user && !user.new_record?
     user
   rescue => text
     raise text
@@ -207,14 +197,10 @@
 
   # Returns the user who matches the given autologin +key+ or nil
   def self.try_to_autologin(key)
-    tokens = Token.find_all_by_action_and_value('autologin', key.to_s)
-    # Make sure there's only 1 token that matches the key
-    if tokens.size == 1
-      token = tokens.first
-      if (token.created_on > Setting.autologin.to_i.day.ago) && token.user && token.user.active?
-        token.user.update_attribute(:last_login_on, Time.now)
-        token.user
-      end
+    user = Token.find_active_user('autologin', key, Setting.autologin.to_i)
+    if user
+      user.update_column(:last_login_on, Time.now)
+      user
     end
   end
 
@@ -371,23 +357,24 @@
   # Find a user account by matching the exact login and then a case-insensitive
   # version.  Exact matches will be given priority.
   def self.find_by_login(login)
-    # First look for an exact match
-    user = where(:login => login).all.detect {|u| u.login == login}
-    unless user
-      # Fail over to case-insensitive if none was found
-      user = where("LOWER(login) = ?", login.to_s.downcase).first
+    if login.present?
+      login = login.to_s
+      # First look for an exact match
+      user = where(:login => login).all.detect {|u| u.login == login}
+      unless user
+        # Fail over to case-insensitive if none was found
+        user = where("LOWER(login) = ?", login.downcase).first
+      end
+      user
     end
-    user
   end
 
   def self.find_by_rss_key(key)
-    token = Token.find_by_action_and_value('feeds', key.to_s)
-    token && token.user.active? ? token.user : nil
+    Token.find_active_user('feeds', key)
   end
 
   def self.find_by_api_key(key)
-    token = Token.find_by_action_and_value('api', key.to_s)
-    token && token.user.active? ? token.user : nil
+    Token.find_active_user('api', key)
   end
 
   # Makes find_by_mail case-insensitive
@@ -441,6 +428,17 @@
     !logged?
   end
 
+  # Returns user's membership for the given project
+  # or nil if the user is not a member of project
+  def membership(project)
+    project_id = project.is_a?(Project) ? project.id : project
+
+    @membership_by_project_id ||= Hash.new {|h, project_id|
+      h[project_id] = memberships.where(:project_id => project_id).first
+    }
+    @membership_by_project_id[project_id]
+  end
+
   # Return user's roles for project
   def roles_for_project(project)
     roles = []
@@ -448,7 +446,7 @@
     return roles if project.nil? || project.archived?
     if logged?
       # Find project membership
-      membership = memberships.detect {|m| m.project_id == project.id}
+      membership = membership(project)
       if membership
         roles = membership.roles
       else
@@ -464,7 +462,7 @@
 
   # Return true if the user is a member of project
   def member_of?(project)
-    !roles_for_project(project).detect {|role| role.member?}.nil?
+    projects.to_a.include?(project)
   end
 
   # Returns a hash of user's projects grouped by roles
@@ -577,47 +575,35 @@
   #
   # TODO: only supports Issue events currently
   def notify_about?(object)
-    case mail_notification
-    when 'all'
+    if mail_notification == 'all'
       true
-    when 'selected'
-      # user receives notifications for created/assigned issues on unselected projects
-      if object.is_a?(Issue) && (object.author == self || is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was))
+    elsif mail_notification.blank? || mail_notification == 'none'
+      false
+    else
+      case object
+      when Issue
+        case mail_notification
+        when 'selected', 'only_my_events'
+          # user receives notifications for created/assigned issues on unselected projects
+          object.author == self || is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was)
+        when 'only_assigned'
+          is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was)
+        when 'only_owner'
+          object.author == self
+        end
+      when News
+        # always send to project members except when mail_notification is set to 'none'
         true
-      else
-        false
       end
-    when 'none'
-      false
-    when 'only_my_events'
-      if object.is_a?(Issue) && (object.author == self || is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was))
-        true
-      else
-        false
-      end
-    when 'only_assigned'
-      if object.is_a?(Issue) && (is_or_belongs_to?(object.assigned_to) || is_or_belongs_to?(object.assigned_to_was))
-        true
-      else
-        false
-      end
-    when 'only_owner'
-      if object.is_a?(Issue) && object.author == self
-        true
-      else
-        false
-      end
-    else
-      false
     end
   end
 
   def self.current=(user)
-    @current_user = user
+    Thread.current[:current_user] = user
   end
 
   def self.current
-    @current_user ||= User.anonymous
+    Thread.current[:current_user] ||= User.anonymous
   end
 
   # Returns the anonymous user.  If the anonymous user does not exist, it is created.  There can be only
@@ -698,7 +684,7 @@
 
   def validate_anonymous_uniqueness
     # There should be only one AnonymousUser in the database
-    errors.add :base, 'An anonymous user already exists.' if AnonymousUser.find(:first)
+    errors.add :base, 'An anonymous user already exists.' if AnonymousUser.exists?
   end
 
   def available_custom_fields
@@ -717,6 +703,10 @@
     UserPreference.new(:user => self)
   end
 
+  def member_of?(project)
+    false
+  end
+
   # Anonymous user can not be destroyed
   def destroy
     false
diff -r 0a574315af3e -r 4f746d8966dd app/models/user_custom_field.rb
--- a/app/models/user_custom_field.rb
+++ b/app/models/user_custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/user_preference.rb
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/version.rb
--- a/app/models/version.rb
+++ b/app/models/version.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,13 +30,12 @@
   validates_presence_of :name
   validates_uniqueness_of :name, :scope => [:project_id]
   validates_length_of :name, :maximum => 60
-  validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :not_a_date, :allow_nil => true
+  validates :effective_date, :date => true
   validates_inclusion_of :status, :in => VERSION_STATUSES
   validates_inclusion_of :sharing, :in => VERSION_SHARINGS
-  validate :validate_version
 
   scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
-  scope :open, where(:status => 'open')
+  scope :open, lambda { where(:status => 'open') }
   scope :visible, lambda {|*args|
     includes(:project).where(Project.allowed_to_condition(args.first || User.current, :view_issues))
   }
@@ -48,7 +47,8 @@
     'wiki_page_title',
     'status',
     'sharing',
-    'custom_field_values'
+    'custom_field_values',
+    'custom_fields'
 
   # Returns true if +user+ or current user is allowed to view the version
   def visible?(user=User.current)
@@ -97,10 +97,10 @@
   end
 
   def behind_schedule?
-    if completed_pourcent == 100
+    if completed_percent == 100
       return false
     elsif due_date && start_date
-      done_date = start_date + ((due_date - start_date+1)* completed_pourcent/100).floor
+      done_date = start_date + ((due_date - start_date+1)* completed_percent/100).floor
       return done_date <= Date.today
     else
       false # No issues so it's not late
@@ -109,7 +109,7 @@
 
   # Returns the completion percentage of this version based on the amount of open/closed issues
   # and the time spent on the open issues.
-  def completed_pourcent
+  def completed_percent
     if issues_count == 0
       0
     elsif open_issues_count == 0
@@ -119,8 +119,14 @@
     end
   end
 
+  # TODO: remove in Redmine 3.0
+  def completed_pourcent
+    ActiveSupport::Deprecation.warn "Version#completed_pourcent is deprecated and will be removed in Redmine 3.0. Please use #completed_percent instead."
+    completed_percent
+  end
+
   # Returns the percentage of issues that have been marked as 'closed'.
-  def closed_pourcent
+  def closed_percent
     if issues_count == 0
       0
     else
@@ -128,6 +134,12 @@
     end
   end
 
+  # TODO: remove in Redmine 3.0
+  def closed_pourcent
+    ActiveSupport::Deprecation.warn "Version#closed_pourcent is deprecated and will be removed in Redmine 3.0. Please use #closed_percent instead."
+    closed_percent
+  end
+
   # Returns true if the version is overdue: due date reached and some open issues
   def overdue?
     effective_date && (effective_date < Date.today) && (open_issues_count > 0)
@@ -275,10 +287,4 @@
       progress
     end
   end
-
-  def validate_version
-    if effective_date.nil? && @attributes['effective_date'].present?
-      errors.add :effective_date, :not_a_date
-    end
-  end
 end
diff -r 0a574315af3e -r 4f746d8966dd app/models/version_custom_field.rb
--- a/app/models/version_custom_field.rb
+++ b/app/models/version_custom_field.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/watcher.rb
--- a/app/models/watcher.rb
+++ b/app/models/watcher.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -29,7 +29,7 @@
       prune_single_user(options[:user], options)
     else
       pruned = 0
-      User.find(:all, :conditions => "id IN (SELECT DISTINCT user_id FROM #{table_name})").each do |user|
+      User.where("id IN (SELECT DISTINCT user_id FROM #{table_name})").all.each do |user|
         pruned += prune_single_user(user, options)
       end
       pruned
@@ -47,7 +47,7 @@
   def self.prune_single_user(user, options={})
     return unless user.is_a?(User)
     pruned = 0
-    find(:all, :conditions => {:user_id => user.id}).each do |watcher|
+    where(:user_id => user.id).all.each do |watcher|
       next if watcher.watchable.nil?
 
       if options.has_key?(:project)
diff -r 0a574315af3e -r 4f746d8966dd app/models/wiki.rb
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,7 +24,7 @@
   acts_as_watchable
 
   validates_presence_of :start_page
-  validates_format_of :start_page, :with => /^[^,\.\/\?\;\|\:]*$/
+  validates_format_of :start_page, :with => /\A[^,\.\/\?\;\|\:]*\z/
 
   safe_attributes 'start_page'
 
diff -r 0a574315af3e -r 4f746d8966dd app/models/wiki_content.rb
--- a/app/models/wiki_content.rb
+++ b/app/models/wiki_content.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -59,6 +59,7 @@
                   :description => :comments,
                   :datetime => :updated_on,
                   :type => 'wiki-page',
+                  :group => :page,
                   :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.page.wiki.project, :id => o.page.title, :version => o.version}}
 
     acts_as_activity_provider :type => 'wiki_edits',
diff -r 0a574315af3e -r 4f746d8966dd app/models/wiki_content_observer.rb
--- a/app/models/wiki_content_observer.rb
+++ b/app/models/wiki_content_observer.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/wiki_page.rb
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -40,7 +40,7 @@
   attr_accessor :redirect_existing_links
 
   validates_presence_of :title
-  validates_format_of :title, :with => /^[^,\.\/\?\;\|\s]*$/
+  validates_format_of :title, :with => /\A[^,\.\/\?\;\|\s]*\z/
   validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false
   validates_associated :content
 
@@ -49,9 +49,9 @@
   before_save    :handle_redirects
 
   # eager load information about last updates, without loading text
-  scope :with_updated_on, {
-    :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on, #{WikiContent.table_name}.version",
-    :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id"
+  scope :with_updated_on, lambda {
+    select("#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on, #{WikiContent.table_name}.version").
+      joins("LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id")
   }
 
   # Wiki pages that are protected by default
diff -r 0a574315af3e -r 4f746d8966dd app/models/wiki_redirect.rb
--- a/app/models/wiki_redirect.rb
+++ b/app/models/wiki_redirect.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/workflow_permission.rb
--- a/app/models/workflow_permission.rb
+++ b/app/models/workflow_permission.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/models/workflow_rule.rb
--- a/app/models/workflow_rule.rb
+++ b/app/models/workflow_rule.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -62,8 +62,8 @@
     else
       transaction do
         delete_all :tracker_id => target_tracker.id, :role_id => target_role.id
-        connection.insert "INSERT INTO #{WorkflowRule.table_name} (tracker_id, role_id, old_status_id, new_status_id, author, assignee, field_name, rule, type)" +
-                          " SELECT #{target_tracker.id}, #{target_role.id}, old_status_id, new_status_id, author, assignee, field_name, rule, type" +
+        connection.insert "INSERT INTO #{WorkflowRule.table_name} (tracker_id, role_id, old_status_id, new_status_id, author, assignee, field_name, #{connection.quote_column_name 'rule'}, type)" +
+                          " SELECT #{target_tracker.id}, #{target_role.id}, old_status_id, new_status_id, author, assignee, field_name, #{connection.quote_column_name 'rule'}, type" +
                           " FROM #{WorkflowRule.table_name}" +
                           " WHERE tracker_id = #{source_tracker.id} AND role_id = #{source_role.id}"
       end
diff -r 0a574315af3e -r 4f746d8966dd app/models/workflow_transition.rb
--- a/app/models/workflow_transition.rb
+++ b/app/models/workflow_transition.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd app/views/account/logout.html.erb
--- /dev/null
+++ b/app/views/account/logout.html.erb
@@ -0,0 +1,3 @@
+<%= form_tag(signout_path) do %>
+  <p><%= submit_tag l(:label_logout) %></p>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/activities/index.html.erb
--- a/app/views/activities/index.html.erb
+++ b/app/views/activities/index.html.erb
@@ -15,13 +15,14 @@
 <% @events_by_day.keys.sort.reverse.each do |day| %>
 <h3><%= format_activity_day(day) %></h3>
 <dl>
-<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
-  <dt class="<%= e.event_type %>  <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
+<% sort_activity_events(@events_by_day[day]).each do |e, in_group| -%>
+  <dt class="<%= e.event_type %> <%= "grouped" if in_group %> <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
   <%= avatar(e.event_author, :size => "24") if e.respond_to?(:event_author) %>
   <span class="time"><%= format_time(e.event_datetime, false) %></span>
   <%= content_tag('span', h(e.project), :class => 'project') if @project.nil? || @project != e.project %>
-  <%= link_to format_activity_title(e.event_title), e.event_url %></dt>
-  <dd><span class="description"><%= format_activity_description(e.event_description) %></span>
+  <%= link_to format_activity_title(e.event_title), e.event_url %>
+  </dt>
+  <dd class="<%= "grouped" if in_group %>"><span class="description"><%= format_activity_description(e.event_description) %></span>
   <span class="author"><%= link_to_user(e.event_author) if e.respond_to?(:event_author) %></span></dd>
 <% end -%>
 </dl>
@@ -54,7 +55,7 @@
 <h3><%= l(:label_activity) %></h3>
 <p><% @activity.event_types.each do |t| %>
 <%= check_box_tag "show_#{t}", 1, @activity.scope.include?(t) %>
-<label for="show_<%=t%>"><%= link_to(l("label_#{t.singularize}_plural"), {"show_#{t}" => 1, :user_id => params[:user_id]})%></label>
+<label for="show_<%=t%>"><%= link_to(l("label_#{t.singularize}_plural"), {"show_#{t}" => 1, :user_id => params[:user_id], :from => params[:from]})%></label>
 <br />
 <% end %></p>
 <% if @project && @project.descendants.active.any? %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/admin/plugins.html.erb
--- a/app/views/admin/plugins.html.erb
+++ b/app/views/admin/plugins.html.erb
@@ -3,14 +3,14 @@
 <% if @plugins.any? %>
 <table class="list plugins">
     <% @plugins.each do |plugin| %>
-        <tr class="<%= cycle('odd', 'even') %>">
+        <tr id="plugin-<%= plugin.id %>" class="<%= cycle('odd', 'even') %>">
         <td><span class="name"><%=h plugin.name %></span>
             <%= content_tag('span', h(plugin.description), :class => 'description') unless plugin.description.blank? %>
             <%= content_tag('span', link_to(h(plugin.url), plugin.url), :class => 'url') unless plugin.url.blank? %>
         </td>
         <td class="author"><%= plugin.author_url.blank? ? h(plugin.author) : link_to(h(plugin.author), plugin.author_url) %></td>
         <td class="version"><%=h plugin.version %></td>
-        <td class="configure"><%= link_to(l(:button_configure), :controller => 'settings', :action => 'plugin', :id => plugin.id) if plugin.configurable? %></td>
+        <td class="configure"><%= link_to(l(:button_configure), plugin_settings_path(plugin)) if plugin.configurable? %></td>
         </tr>
     <% end %>
 </table>
diff -r 0a574315af3e -r 4f746d8966dd app/views/admin/projects.html.erb
--- a/app/views/admin/projects.html.erb
+++ b/app/views/admin/projects.html.erb
@@ -27,7 +27,7 @@
   <tbody>
 <% project_tree(@projects) do |project, level| %>
   <tr class="<%= cycle("odd", "even") %> <%= project.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
-  <td class="name"><span><%= link_to_project(project, {:action => (project.active? ? 'settings' : 'show')}, :title => project.short_description) %></span></td>
+  <td class="name"><span><%= link_to_project_settings(project, {}, :title => project.short_description) %></span></td>
   <td align="center"><%= checked_image project.is_public? %></td>
   <td align="center"><%= format_date(project.created_on) %></td>
   <td class="buttons">
diff -r 0a574315af3e -r 4f746d8966dd app/views/attachments/_form.html.erb
--- a/app/views/attachments/_form.html.erb
+++ b/app/views/attachments/_form.html.erb
@@ -1,19 +1,31 @@
+<span id="attachments_fields">
 <% if defined?(container) && container && container.saved_attachments %>
   <% container.saved_attachments.each_with_index do |attachment, i| %>
-    <span class="icon icon-attachment" style="display:block; line-height:1.5em;">
-      <%= h(attachment.filename) %> (<%= number_to_human_size(attachment.filesize) %>)
-      <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.id}.#{attachment.digest}" %>
+    <span id="attachments_p<%= i %>">
+      <%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename') +
+          text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description') +
+          link_to('&nbsp;'.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %>
+      <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %>
     </span>
   <% end %>
 <% end %>
-<span id="attachments_fields">
-  <span>
-    <%= file_field_tag 'attachments[1][file]', :id => nil, :class => 'file',
-          :onchange => "checkFileSize(this, #{Setting.attachment_max_size.to_i.kilobytes}, '#{escape_javascript(l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)))}');"  -%>
-    <nobr><%= text_field_tag 'attachments[1][description]', '', :id => nil, :class => 'description', :maxlength => 255, :placeholder => l(:label_optional_description) %>
-    <%= link_to_function(image_tag('delete.png'), 'removeFileField(this)', :title => (l(:button_delete))) %></nobr>
-  </span>
+</span>
+<span class="add_attachment">
+<%= file_field_tag 'attachments[dummy][file]',
+      :id => nil,
+      :class => 'file_selector',
+      :multiple => true,
+      :onchange => 'addInputFiles(this);',
+      :data => {
+        :max_file_size => Setting.attachment_max_size.to_i.kilobytes,
+        :max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)),
+        :max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i,
+        :upload_path => uploads_path(:format => 'js'),
+        :description_placeholder => l(:label_optional_description)
+      } %>
+(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
 </span>
 
-<span class="add_attachment"><%= link_to l(:label_add_another_file), '#', :onclick => 'addFileField(); return false;', :class => 'add_attachment' %>
-(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)</span>
+<% content_for :header_tags do %>
+  <%= javascript_include_tag 'attachments' %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/attachments/destroy.js.erb
--- /dev/null
+++ b/app/views/attachments/destroy.js.erb
@@ -0,0 +1,1 @@
+$('#attachments_<%= j params[:attachment_id] %>').remove();
diff -r 0a574315af3e -r 4f746d8966dd app/views/attachments/upload.js.erb
--- /dev/null
+++ b/app/views/attachments/upload.js.erb
@@ -0,0 +1,9 @@
+var fileSpan = $('#attachments_<%= j params[:attachment_id] %>');
+$('<input>', { type: 'hidden', name: 'attachments[<%= j params[:attachment_id] %>][token]' } ).val('<%= j @attachment.token %>').appendTo(fileSpan);
+fileSpan.find('a.remove-upload')
+  .attr({
+    "data-remote": true,
+    "data-method": 'delete',
+    href: '<%= j attachment_path(@attachment, :attachment_id => params[:attachment_id], :format => 'js') %>'
+  })
+  .off('click');
diff -r 0a574315af3e -r 4f746d8966dd app/views/auth_sources/_form.html.erb
--- a/app/views/auth_sources/_form.html.erb
+++ b/app/views/auth_sources/_form.html.erb
@@ -1,13 +1,6 @@
 <%= error_messages_for 'auth_source' %>
 
-<div class="box">
-<!--[form:auth_source]-->
-<p><label for="auth_source_name"><%=l(:field_name)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'name'  %></p>
-
-<p><label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label>
-<%= check_box 'auth_source', 'onthefly_register' %></p>
+<div class="box tabular">
+  <p><%= f.text_field :name, :required => true %></p>
+  <p><%= f.check_box :onthefly_register, :label => :field_onthefly %></p>
 </div>
-
-<!--[eoform:auth_source]-->
-
diff -r 0a574315af3e -r 4f746d8966dd app/views/auth_sources/_form_auth_source_ldap.html.erb
--- a/app/views/auth_sources/_form_auth_source_ldap.html.erb
+++ b/app/views/auth_sources/_form_auth_source_ldap.html.erb
@@ -1,50 +1,24 @@
 <%= error_messages_for 'auth_source' %>
 
-<div class="box">
-<!--[form:auth_source]-->
-<p><label for="auth_source_name"><%=l(:field_name)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'name'  %></p>
-
-<p><label for="auth_source_host"><%=l(:field_host)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'host'  %></p>
-
-<p><label for="auth_source_port"><%=l(:field_port)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'port', :size => 6 %> <%= check_box 'auth_source', 'tls'  %> LDAPS</p>
-
-<p><label for="auth_source_account"><%=l(:field_account)%></label>
-<%= text_field 'auth_source', 'account'  %></p>
-
-<p><label for="auth_source_account_password"><%=l(:field_password)%></label>
-<%= password_field 'auth_source', 'account_password', :name => 'ignore',
-                                           :value => ((@auth_source.new_record? || @auth_source.account_password.blank?) ? '' : ('x'*15)),
-                                           :onfocus => "this.value=''; this.name='auth_source[account_password]';",
-                                           :onchange => "this.name='auth_source[account_password]';" %></p>
-
-<p><label for="auth_source_base_dn"><%=l(:field_base_dn)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'base_dn', :size => 60 %></p>
-
-<p><label for="auth_source_custom_filter"><%=l(:field_auth_source_ldap_filter)%></label>
-<%= text_field 'auth_source', 'filter', :size => 60 %></p>
-
-<p><label for="auth_source_timeout"><%=l(:field_timeout)%></label>
-<%= text_field 'auth_source', 'timeout', :size => 4 %></p>
-
-<p><label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label>
-<%= check_box 'auth_source', 'onthefly_register' %></p>
+<div class="box tabular">
+  <p><%= f.text_field :name, :required => true %></p>
+  <p><%= f.text_field :host, :required => true %></p>
+  <p><%= f.text_field :port, :required => true, :size => 6 %> <%= f.check_box :tls, :no_label => true %> LDAPS</p>
+  <p><%= f.text_field :account %></p>
+  <p><%= f.password_field :account_password, :label => :field_password,
+           :name => 'dummy_password',
+           :value => ((@auth_source.new_record? || @auth_source.account_password.blank?) ? '' : ('x'*15)),
+           :onfocus => "this.value=''; this.name='auth_source[account_password]';",
+           :onchange => "this.name='auth_source[account_password]';" %></p>
+  <p><%= f.text_field :base_dn, :required => true, :size => 60 %></p>
+  <p><%= f.text_field :filter, :size => 60, :label => :field_auth_source_ldap_filter %></p>
+  <p><%= f.text_field :timeout, :size => 4 %></p>
+  <p><%= f.check_box :onthefly_register, :label => :field_onthefly %></p>
 </div>
 
-<fieldset class="box"><legend><%=l(:label_attribute_plural)%></legend>
-<p><label for="auth_source_attr_login"><%=l(:field_login)%> <span class="required">*</span></label>
-<%= text_field 'auth_source', 'attr_login', :size => 20  %></p>
-
-<p><label for="auth_source_attr_firstname"><%=l(:field_firstname)%></label>
-<%= text_field 'auth_source', 'attr_firstname', :size => 20  %></p>
-
-<p><label for="auth_source_attr_lastname"><%=l(:field_lastname)%></label>
-<%= text_field 'auth_source', 'attr_lastname', :size => 20  %></p>
-
-<p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label>
-<%= text_field 'auth_source', 'attr_mail', :size => 20  %></p>
+<fieldset class="box tabular"><legend><%=l(:label_attribute_plural)%></legend>
+  <p><%= f.text_field :attr_login, :required => true, :size => 20 %></p>
+  <p><%= f.text_field :attr_firstname, :size => 20 %></p>
+  <p><%= f.text_field :attr_lastname, :size => 20 %></p>
+  <p><%= f.text_field :attr_mail, :size => 20 %></p>
 </fieldset>
-<!--[eoform:auth_source]-->
-
diff -r 0a574315af3e -r 4f746d8966dd app/views/auth_sources/edit.html.erb
--- a/app/views/auth_sources/edit.html.erb
+++ b/app/views/auth_sources/edit.html.erb
@@ -1,6 +1,6 @@
 <h2><%=l(:label_auth_source)%> (<%= h(@auth_source.auth_method_name) %>)</h2>
 
-<%= form_tag({:action => 'update', :id => @auth_source}, :method => :put, :class => "tabular") do %>
-  <%= render :partial => auth_source_partial_name(@auth_source) %>
+<%= labelled_form_for @auth_source, :as => :auth_source, :url => auth_source_path(@auth_source), :html => {:id => 'auth_source_form'} do |f| %>
+  <%= render :partial => auth_source_partial_name(@auth_source), :locals => { :f => f } %>
   <%= submit_tag l(:button_save) %>
 <% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/auth_sources/index.html.erb
--- a/app/views/auth_sources/index.html.erb
+++ b/app/views/auth_sources/index.html.erb
@@ -20,7 +20,7 @@
     <td align="center"><%= h source.host %></td>
     <td align="center"><%= h source.users.count %></td>
     <td class="buttons">
-      <%= link_to l(:button_test), {:action => 'test_connection', :id => source}, :class => 'icon icon-test' %>
+      <%= link_to l(:button_test), try_connection_auth_source_path(source), :class => 'icon icon-test' %>
       <%= delete_link auth_source_path(source) %>
     </td>
   </tr>
diff -r 0a574315af3e -r 4f746d8966dd app/views/auth_sources/new.html.erb
--- a/app/views/auth_sources/new.html.erb
+++ b/app/views/auth_sources/new.html.erb
@@ -1,7 +1,7 @@
 <h2><%=l(:label_auth_source_new)%> (<%= h(@auth_source.auth_method_name) %>)</h2>
 
-<%= form_tag({:action => 'create'}, :class => "tabular") do %>
+<%= labelled_form_for @auth_source, :as => :auth_source, :url => auth_sources_path, :html => {:id => 'auth_source_form'} do |f| %>
   <%= hidden_field_tag 'type', @auth_source.type %>
-  <%= render :partial => auth_source_partial_name(@auth_source) %>
+  <%= render :partial => auth_source_partial_name(@auth_source), :locals => { :f => f } %>
   <%= submit_tag l(:button_create) %>
 <% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/boards/index.html.erb
--- a/app/views/boards/index.html.erb
+++ b/app/views/boards/index.html.erb
@@ -11,7 +11,7 @@
 <% Board.board_tree(@boards) do |board, level| %>
   <tr class="<%= cycle 'odd', 'even' %>">
     <td style="padding-left: <%= level * 18 %>px;">
-      <%= link_to h(board.name), {:action => 'show', :id => board}, :class => "board"  %><br />
+      <%= link_to h(board.name), project_board_path(board.project, board), :class => "board" %><br />
       <%=h board.description %>
     </td>
     <td class="topic-count"><%= board.topics_count %></td>
diff -r 0a574315af3e -r 4f746d8966dd app/views/boards/show.html.erb
--- a/app/views/boards/show.html.erb
+++ b/app/views/boards/show.html.erb
@@ -1,20 +1,20 @@
 <%= board_breadcrumb(@board) %>
 
 <div class="contextual">
-<%= link_to_if_authorized l(:label_message_new),
-                          {:controller => 'messages', :action => 'new', :board_id => @board},
-                          :class => 'icon icon-add',
-                          :onclick => 'showAndScrollTo("add-message", "message_subject"); return false;' %>
-<%= watcher_tag(@board, User.current) %>
+<%= link_to l(:label_message_new),
+            new_board_message_path(@board),
+            :class => 'icon icon-add',
+            :onclick => 'showAndScrollTo("add-message", "message_subject"); return false;' if User.current.allowed_to?(:add_messages, @board.project) %>
+<%= watcher_link(@board, User.current) %>
 </div>
 
 <div id="add-message" style="display:none;">
-<% if authorize_for('messages', 'new') %>
-<h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%= l(:label_message_new) %></h2>
-<%= form_for @message, :url => {:controller => 'messages', :action => 'new', :board_id => @board}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
+<% if User.current.allowed_to?(:add_messages, @board.project) %>
+<h2><%= link_to h(@board.name), project_board_path(@project, @board) %> &#187; <%= l(:label_message_new) %></h2>
+<%= form_for @message, :url => new_board_message_path(@board), :html => {:multipart => true, :id => 'message-form'} do |f| %>
   <%= render :partial => 'messages/form', :locals => {:f => f} %>
   <p><%= submit_tag l(:button_create) %>
-  <%= preview_link({:controller => 'messages', :action => 'preview', :board_id => @board}, 'message-form') %> |
+  <%= preview_link(preview_board_message_path(@board), 'message-form') %> |
   <%= link_to l(:button_cancel), "#", :onclick => '$("#add-message").hide(); return false;' %></p>
 <% end %>
 <div id="preview" class="wiki"></div>
@@ -36,7 +36,7 @@
   <tbody>
   <% @topics.each do |topic| %>
     <tr class="message <%= cycle 'odd', 'even' %> <%= topic.sticky? ? 'sticky' : '' %> <%= topic.locked? ? 'locked' : '' %>">
-      <td class="subject"><%= link_to h(topic.subject), { :controller => 'messages', :action => 'show', :board_id => @board, :id => topic } %></td>
+      <td class="subject"><%= link_to h(topic.subject), board_message_path(@board, topic) %></td>
       <td class="author"><%= link_to_user(topic.author) %></td>
       <td class="created_on"><%= format_time(topic.created_on) %></td>
       <td class="reply-count"><%= topic.replies_count %></td>
diff -r 0a574315af3e -r 4f746d8966dd app/views/common/_diff.html.erb
--- a/app/views/common/_diff.html.erb
+++ b/app/views/common/_diff.html.erb
@@ -10,7 +10,7 @@
 <thead>
 <tr>
   <th colspan="4" class="filename">
-    <%= h(Redmine::CodesetUtil.to_utf8_by_setting(table_file.file_name)) %>
+    <%= table_file.file_name %>
   </th>
 </tr>
 </thead>
@@ -24,11 +24,11 @@
 <tr>
   <th class="line-num"><%= line.nb_line_left %></th>
   <td class="line-code <%= line.type_diff_left %>">
-    <pre><%= Redmine::CodesetUtil.to_utf8_by_setting(line.html_line_left).html_safe %></pre>
+    <pre><%= line.html_line_left.html_safe %></pre>
   </td>
   <th class="line-num"><%= line.nb_line_right %></th>
   <td class="line-code <%= line.type_diff_right %>">
-    <pre><%= Redmine::CodesetUtil.to_utf8_by_setting(line.html_line_right).html_safe %></pre>
+    <pre><%= line.html_line_right.html_safe %></pre>
   </td>
 </tr>
 <% end -%>
@@ -40,7 +40,7 @@
 <thead>
   <tr>
     <th colspan="3" class="filename">
-      <%= h(Redmine::CodesetUtil.to_utf8_by_setting(table_file.file_name)) %>
+      <%= table_file.file_name %>
     </th>
   </tr>
 </thead>
@@ -55,7 +55,7 @@
   <th class="line-num"><%= line.nb_line_left %></th>
   <th class="line-num"><%= line.nb_line_right %></th>
   <td class="line-code <%= line.type_diff %>">
-    <pre><%= Redmine::CodesetUtil.to_utf8_by_setting(line.html_line).html_safe %></pre>
+    <pre><%= line.html_line.html_safe %></pre>
   </td>
 </tr>
 <% end -%>
diff -r 0a574315af3e -r 4f746d8966dd app/views/common/_preview.html.erb
--- a/app/views/common/_preview.html.erb
+++ b/app/views/common/_preview.html.erb
@@ -1,3 +1,3 @@
 <fieldset class="preview"><legend><%= l(:label_preview) %></legend>
-<%= textilizable @text, :attachments => @attachements, :object => @previewed %>
+<%= textilizable @text, :attachments => @attachments, :object => @previewed %>
 </fieldset>
diff -r 0a574315af3e -r 4f746d8966dd app/views/context_menus/issues.html.erb
--- a/app/views/context_menus/issues.html.erb
+++ b/app/views/context_menus/issues.html.erb
@@ -1,59 +1,59 @@
 <ul>
   <%= call_hook(:view_issues_context_menu_start, {:issues => @issues, :can => @can, :back => @back }) %>
 
-<% if !@issue.nil? -%>
-  <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
-          :class => 'icon-edit', :disabled => !@can[:edit] %></li>
-<% else %>
-  <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'bulk_edit', :ids => @issue_ids},
-          :class => 'icon-edit', :disabled => !@can[:edit] %></li>
-<% end %>
+  <% if @issue -%>
+    <li><%= context_menu_link l(:button_edit), edit_issue_path(@issue),
+            :class => 'icon-edit', :disabled => !@can[:edit] %></li>
+  <% else %>
+    <li><%= context_menu_link l(:button_edit), bulk_edit_issues_path(:ids => @issue_ids),
+            :class => 'icon-edit', :disabled => !@can[:edit] %></li>
+  <% end %>
 
   <% if @allowed_statuses.present? %>
   <li class="folder">
     <a href="#" class="submenu"><%= l(:field_status) %></a>
     <ul>
     <% @allowed_statuses.each do |s| -%>
-        <li><%= context_menu_link h(s.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {:status_id => s}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link h(s.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {:status_id => s}, :back_url => @back), :method => :post,
                                   :selected => (@issue && s == @issue.status), :disabled => !@can[:update] %></li>
     <% end -%>
     </ul>
   </li>
   <% end %>
 
-  <% unless @trackers.nil? %>
+  <% if @trackers.present? %>
   <li class="folder">
     <a href="#" class="submenu"><%= l(:field_tracker) %></a>
     <ul>
     <% @trackers.each do |t| -%>
-        <li><%= context_menu_link h(t.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'tracker_id' => t}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link h(t.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {'tracker_id' => t}, :back_url => @back), :method => :post,
                                   :selected => (@issue && t == @issue.tracker), :disabled => !@can[:edit] %></li>
     <% end -%>
     </ul>
   </li>
   <% end %>
 
-  <% if @safe_attributes.include?('priority_id') -%>
+  <% if @safe_attributes.include?('priority_id') && @priorities.present? -%>
   <li class="folder">
     <a href="#" class="submenu"><%= l(:field_priority) %></a>
     <ul>
     <% @priorities.each do |p| -%>
-        <li><%= context_menu_link h(p.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'priority_id' => p}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link h(p.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {'priority_id' => p}, :back_url => @back), :method => :post,
                                   :selected => (@issue && p == @issue.priority), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
     <% end -%>
     </ul>
   </li>
   <% end %>
 
-  <% if @safe_attributes.include?('fixed_version_id') && @versions.any? -%>
+  <% if @safe_attributes.include?('fixed_version_id') && @versions.present? -%>
   <li class="folder">
     <a href="#" class="submenu"><%= l(:field_fixed_version) %></a>
     <ul>
     <% @versions.sort.each do |v| -%>
-        <li><%= context_menu_link format_version_name(v), {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'fixed_version_id' => v}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link format_version_name(v), bulk_update_issues_path(:ids => @issue_ids, :issue => {'fixed_version_id' => v}, :back_url => @back), :method => :post,
                                   :selected => (@issue && v == @issue.fixed_version), :disabled => !@can[:update] %></li>
     <% end -%>
-        <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'fixed_version_id' => 'none'}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link l(:label_none), bulk_update_issues_path(:ids => @issue_ids, :issue => {'fixed_version_id' => 'none'}, :back_url => @back), :method => :post,
                                   :selected => (@issue && @issue.fixed_version.nil?), :disabled => !@can[:update] %></li>
     </ul>
   </li>
@@ -64,14 +64,14 @@
     <a href="#" class="submenu"><%= l(:field_assigned_to) %></a>
     <ul>
     <% if @assignables.include?(User.current) %>
-        <li><%= context_menu_link "<< #{l(:label_me)} >>", {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'assigned_to_id' => User.current}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link "<< #{l(:label_me)} >>", bulk_update_issues_path(:ids => @issue_ids, :issue => {'assigned_to_id' => User.current}, :back_url => @back), :method => :post,
                                   :disabled => !@can[:update] %></li>
     <% end %>
     <% @assignables.each do |u| -%>
-        <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'assigned_to_id' => u}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link h(u.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {'assigned_to_id' => u}, :back_url => @back), :method => :post,
                                   :selected => (@issue && u == @issue.assigned_to), :disabled => !@can[:update] %></li>
     <% end -%>
-        <li><%= context_menu_link l(:label_nobody), {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'assigned_to_id' => 'none'}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link l(:label_nobody), bulk_update_issues_path(:ids => @issue_ids, :issue => {'assigned_to_id' => 'none'}, :back_url => @back), :method => :post,
                                   :selected => (@issue && @issue.assigned_to.nil?), :disabled => !@can[:update] %></li>
     </ul>
   </li>
@@ -82,10 +82,10 @@
     <a href="#" class="submenu"><%= l(:field_category) %></a>
     <ul>
     <% @project.issue_categories.each do |u| -%>
-        <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'category_id' => u}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link h(u.name), bulk_update_issues_path(:ids => @issue_ids, :issue => {'category_id' => u}, :back_url => @back), :method => :post,
                                   :selected => (@issue && u == @issue.category), :disabled => !@can[:update] %></li>
     <% end -%>
-        <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'category_id' => 'none'}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link l(:label_none), bulk_update_issues_path(:ids => @issue_ids, :issue => {'category_id' => 'none'}, :back_url => @back), :method => :post,
                                   :selected => (@issue && @issue.category.nil?), :disabled => !@can[:update] %></li>
     </ul>
   </li>
@@ -96,7 +96,7 @@
     <a href="#" class="submenu"><%= l(:field_done_ratio) %></a>
     <ul>
     <% (0..10).map{|x|x*10}.each do |p| -%>
-        <li><%= context_menu_link "#{p}%", {:controller => 'issues', :action => 'bulk_update', :ids => @issue_ids, :issue => {'done_ratio' => p}, :back_url => @back}, :method => :post,
+        <li><%= context_menu_link "#{p}%", bulk_update_issues_path(:ids => @issue_ids, :issue => {'done_ratio' => p}, :back_url => @back), :method => :post,
                                       :selected => (@issue && p == @issue.done_ratio), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
     <% end -%>
     </ul>
@@ -104,7 +104,7 @@
   <% end %>
 
   <% @options_by_custom_field.each do |field, options| %>
-    <li class="folder">
+    <li class="folder cf_<%= field.id %>">
       <a href="#" class="submenu"><%= h(field.name) %></a>
       <ul>
       <% options.each do |text, value| %>
@@ -117,21 +117,19 @@
     </li>
   <% end %>
 
-<% if !@issue.nil? %>
-  <% if @can[:log_time] -%>
-  <li><%= context_menu_link l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue},
-          :class => 'icon-time-add' %></li>
-  <% end %>
-  <% if User.current.logged? %>
-  <li><%= watcher_link(@issue, User.current) %></li>
-  <% end %>
+<% if User.current.logged? %>
+  <li><%= watcher_link(@issues, User.current) %></li>
 <% end %>
 
 <% if @issue.present? %>
-  <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue},
+  <% if @can[:log_time] -%>
+  <li><%= context_menu_link l(:button_log_time), new_issue_time_entry_path(@issue),
+          :class => 'icon-time-add' %></li>
+  <% end %>
+  <li><%= context_menu_link l(:button_copy), project_copy_issue_path(@project, @issue),
           :class => 'icon-copy', :disabled => !@can[:copy] %></li>
 <% else %>
-  <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'bulk_edit', :ids => @issue_ids, :copy => '1'},
+  <li><%= context_menu_link l(:button_copy), bulk_edit_issues_path(:ids => @issue_ids, :copy => '1'),
                           :class => 'icon-copy', :disabled => !@can[:move] %></li>
 <% end %>													
   <li><%= context_menu_link l(:button_delete), issues_path(:ids => @issue_ids, :back_url => @back),
diff -r 0a574315af3e -r 4f746d8966dd app/views/custom_fields/_form.html.erb
--- a/app/views/custom_fields/_form.html.erb
+++ b/app/views/custom_fields/_form.html.erb
@@ -5,7 +5,12 @@
 <p><%= f.select :field_format, custom_field_formats_for_select(@custom_field), {}, :disabled => !@custom_field.new_record? %></p>
 
 <% if @custom_field.format_in? 'list', 'user', 'version' %>
-<p><%= f.check_box :multiple, :disabled => @custom_field.multiple && !@custom_field.new_record? %></p>
+<p>
+  <%= f.check_box :multiple %>
+  <% if !@custom_field.new_record? && @custom_field.multiple %>
+  <em class="info"><%= l(:text_turning_multiple_off) %></em>
+  <% end %>
+</p>
 <% end %>
 
 <% unless @custom_field.format_in? 'list', 'bool', 'date', 'user', 'version' %>
@@ -22,8 +27,17 @@
 </p>
 <% end %>
 
-<% unless @custom_field.format_in? 'user', 'version' %>
-<p><%= @custom_field.field_format == 'bool' ? f.check_box(:default_value) : f.text_field(:default_value) %></p>
+<% case @custom_field.field_format %>
+<% when 'bool' %>
+  <p><%= f.check_box(:default_value) %></p>
+<% when 'text' %>
+  <p><%= f.text_area(:default_value, :rows => 8) %></p>
+<% when 'date' %>
+  <p><%= f.text_field(:default_value, :size => 10) %></p>
+  <%= calendar_for('custom_field_default_value') %>
+<% when 'user', 'version' %>
+<% else %>
+  <p><%= f.text_field(:default_value) %></p>
 <% end %>
 
 <%= call_hook(:view_custom_fields_form_upper_box, :custom_field => @custom_field, :form => f) %>
@@ -73,6 +87,7 @@
 
 <% when "TimeEntryCustomField" %>
     <p><%= f.check_box :is_required %></p>
+    <p><%= f.check_box :is_filter %></p>
 
 <% else %>
     <p><%= f.check_box :is_required %></p>
@@ -80,3 +95,5 @@
 <% end %>
 <%= call_hook(:"view_custom_fields_form_#{@custom_field.type.to_s.underscore}", :custom_field => @custom_field, :form => f) %>
 </div>
+
+<% include_calendar_headers_tags %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/documents/index.html.erb
--- a/app/views/documents/index.html.erb
+++ b/app/views/documents/index.html.erb
@@ -1,6 +1,6 @@
 <div class="contextual">
 <%= link_to l(:label_document_new), new_project_document_path(@project), :class => 'icon icon-add',
-      :onclick => 'showAndScrollTo("add-document", "document_title"); return false;' if User.current.allowed_to?(:manage_documents, @project) %>
+      :onclick => 'showAndScrollTo("add-document", "document_title"); return false;' if User.current.allowed_to?(:add_documents, @project) %>
 </div>
 
 <div id="add-document" style="display:none;">
diff -r 0a574315af3e -r 4f746d8966dd app/views/documents/show.html.erb
--- a/app/views/documents/show.html.erb
+++ b/app/views/documents/show.html.erb
@@ -1,6 +1,8 @@
 <div class="contextual">
-<% if User.current.allowed_to?(:manage_documents, @project) %>
+<% if User.current.allowed_to?(:edit_documents, @project) %>
 <%= link_to l(:button_edit), edit_document_path(@document), :class => 'icon icon-edit', :accesskey => accesskey(:edit) %>
+<% end %>
+<% if User.current.allowed_to?(:delete_documents, @project) %>
 <%= delete_link document_path(@document) %>
 <% end %>
 </div>
@@ -10,7 +12,7 @@
 <p><em><%=h @document.category.name %><br />
 <%= format_date @document.created_on %></em></p>
 <div class="wiki">
-<%= textilizable @document.description, :attachments => @document.attachments %>
+<%= textilizable @document, :description, :attachments => @document.attachments %>
 </div>
 
 <h3><%= l(:label_attachment_plural) %></h3>
diff -r 0a574315af3e -r 4f746d8966dd app/views/gantts/show.html.erb
--- a/app/views/gantts/show.html.erb
+++ b/app/views/gantts/show.html.erb
@@ -12,6 +12,39 @@
     <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
   </div>
 </fieldset>
+<fieldset class="collapsible collapsed">
+  <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
+  <div style="display: none;">
+    <table>
+      <tr>
+        <td>
+          <fieldset>
+            <legend><%= l(:label_related_issues) %></legend>
+            <label>
+              <%= check_box_tag "draw_rels", params["draw_rels"], params[:set_filter].blank? || params[:draw_rels] %>
+              <% rels = [IssueRelation::TYPE_BLOCKS, IssueRelation::TYPE_PRECEDES] %>
+              <% rels.each do |rel| %>
+                <% color = Redmine::Helpers::Gantt::DRAW_TYPES[rel][:color] %>
+                <%= content_tag(:span, '&nbsp;&nbsp;&nbsp;'.html_safe,
+                                :style => "background-color: #{color}") %>
+                <%= l(IssueRelation::TYPES[rel][:name]) %>
+              <% end %>
+            </label>
+          </fieldset>
+        </td>
+        <td>
+          <fieldset>
+            <legend><%= l(:label_gantt_progress_line) %></legend>
+            <label>
+              <%= check_box_tag "draw_progress_line", params[:draw_progress_line], params[:draw_progress_line] %>
+              <%= l(:label_display) %>
+            </label>
+          </fieldset>
+        </td>
+      </tr>
+    </table>
+  </div>
+</fieldset>
 
 <p class="contextual">
   <%= gantt_zoom_link(@gantt, :in) %>
@@ -39,18 +72,18 @@
   @gantt.zoom.times { zoom = zoom * 2 }
 
   subject_width = 330
-  header_heigth = 18
+  header_height = 18
 
-  headers_height = header_heigth
+  headers_height = header_height
   show_weeks = false
   show_days  = false
 
   if @gantt.zoom > 1
     show_weeks = true
-    headers_height = 2 * header_heigth
+    headers_height = 2 * header_height
     if @gantt.zoom > 2
         show_days = true
-        headers_height = 3 * header_heigth
+        headers_height = 3 * header_height
     end
   end
 
@@ -102,7 +135,7 @@
 </td>
 
 <td>
-<div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;">
+<div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;" id="gantt_area">
 <%
   style  = ""
   style += "width: #{g_width - 1}px;"
@@ -115,7 +148,7 @@
 <%
   month_f = @gantt.date_from
   left = 0
-  height = (show_weeks ? header_heigth : header_heigth + g_height)
+  height = (show_weeks ? header_height : header_height + g_height)
 %>
 <% @gantt.months.times do %>
   <%
@@ -140,7 +173,7 @@
 <% if show_weeks %>
   <%
     left = 0
-    height = (show_days ? header_heigth - 1 : header_heigth - 1 + g_height)
+    height = (show_days ? header_height - 1 : header_height - 1 + g_height)
   %>
   <% if @gantt.date_from.cwday == 1 %>
     <%
@@ -189,7 +222,7 @@
 <% if show_days %>
   <%
     left = 0
-    height = g_height + header_heigth - 1
+    height = g_height + header_height - 1
     wday = @gantt.date_from.cwday
   %>
   <% (@gantt.date_to - @gantt.date_from + 1).to_i.times do %>
@@ -229,9 +262,17 @@
     style += "width:10px;"
     style += "border-left: 1px dashed red;"
   %>
-  <%= content_tag(:div, '&nbsp;'.html_safe, :style => style) %>
+  <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :id => 'today_line') %>
 <% end %>
-
+<%
+  style  = ""
+  style += "position: absolute;"
+  style += "height: #{g_height}px;"
+  style += "top: #{headers_height + 1}px;"
+  style += "left: 0px;"
+  style += "width: #{g_width - 1}px;"
+%>
+<%= content_tag(:div, '', :style => style, :id => "gantt_draw_area") %>
 </div>
 </td>
 </tr>
@@ -261,3 +302,18 @@
 <% end %>
 
 <% html_title(l(:label_gantt)) -%>
+
+<% content_for :header_tags do %>
+  <%= javascript_include_tag 'raphael' %>
+  <%= javascript_include_tag 'gantt' %>
+<% end %>
+
+<%= javascript_tag do %>
+  var issue_relation_type = <%= raw Redmine::Helpers::Gantt::DRAW_TYPES.to_json %>;
+  $(document).ready(drawGanttHandler);
+  $(window).resize(drawGanttHandler);
+  $(function() {
+    $("#draw_rels").change(drawGanttHandler);
+    $("#draw_progress_line").change(drawGanttHandler);
+  });
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/groups/_form.html.erb
--- a/app/views/groups/_form.html.erb
+++ b/app/views/groups/_form.html.erb
@@ -1,7 +1,7 @@
 <%= error_messages_for @group %>
 
 <div class="box tabular">
-  <p><%= f.text_field :name %></p>
+  <p><%= f.text_field :name, :required => true, :size => 60 %></p>
   <% @group.custom_field_values.each do |value| %>
     <p><%= custom_field_tag_with_label :group, value %></p>
   <% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/groups/_memberships.html.erb
--- a/app/views/groups/_memberships.html.erb
+++ b/app/views/groups/_memberships.html.erb
@@ -1,5 +1,5 @@
 <% roles = Role.find_all_givable %>
-<% projects = Project.active.find(:all, :order => 'lft') %>
+<% projects = Project.active.all %>
 
 <div class="splitcontentleft">
 <% if @group.memberships.any? %>
@@ -13,7 +13,7 @@
   <% @group.memberships.each do |membership| %>
   <% next if membership.new_record? %>
   <tr id="member-<%= membership.id %>" class="<%= cycle 'odd', 'even' %> class">
-  <td class="project"><%=h membership.project %></td>
+  <td class="project"><%= link_to_project membership.project %></td>
   <td class="roles">
     <span id="member-<%= membership.id %>-roles"><%=h membership.roles.sort.collect(&:to_s).join(', ') %></span>
     <%= form_for(:membership, :remote => true,
diff -r 0a574315af3e -r 4f746d8966dd app/views/groups/_users.html.erb
--- a/app/views/groups/_users.html.erb
+++ b/app/views/groups/_users.html.erb
@@ -22,22 +22,18 @@
 </div>
 
 <div class="splitcontentright">
-<% users = User.active.not_in_group(@group).all(:limit => 100) %>
-<% if users.any? %>
   <%= form_for(@group, :remote => true, :url => group_users_path(@group),
                :html => {:method => :post}) do |f| %>
     <fieldset><legend><%=l(:label_user_new)%></legend>
 
     <p><%= label_tag "user_search", l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
-    <%= javascript_tag "observeSearchfield('user_search', 'users', '#{ escape_javascript autocomplete_for_user_group_path(@group) }')" %>
+    <%= javascript_tag "observeSearchfield('user_search', null, '#{ escape_javascript autocomplete_for_user_group_path(@group) }')" %>
 
     <div id="users">
-      <%= principals_check_box_tags 'user_ids[]', users %>
+      <%= render_principals_for_new_group_users(@group) %>
     </div>
 
     <p><%= submit_tag l(:button_add) %></p>
     </fieldset>
   <% end %>
-<% end %>
-
 </div>
diff -r 0a574315af3e -r 4f746d8966dd app/views/groups/autocomplete_for_user.html.erb
--- a/app/views/groups/autocomplete_for_user.html.erb
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= principals_check_box_tags 'user_ids[]', @users %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/groups/autocomplete_for_user.js.erb
--- /dev/null
+++ b/app/views/groups/autocomplete_for_user.js.erb
@@ -0,0 +1,1 @@
+$('#users').html('<%= escape_javascript(render_principals_for_new_group_users(@group)) %>');
diff -r 0a574315af3e -r 4f746d8966dd app/views/groups/index.html.erb
--- a/app/views/groups/index.html.erb
+++ b/app/views/groups/index.html.erb
@@ -19,6 +19,7 @@
     <td class="buttons"><%= delete_link group %></td>
   </tr>
 <% end %>
+  </tbody>
 </table>
 <% else %>
 <p class="nodata"><%= l(:label_no_data) %></p>
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/_action_menu.html.erb
--- a/app/views/issues/_action_menu.html.erb
+++ b/app/views/issues/_action_menu.html.erb
@@ -1,7 +1,7 @@
 <div class="contextual">
-<%= link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "issue_notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %>
+<%= link_to l(:button_update), edit_issue_path(@issue), :onclick => 'showAndScrollTo("update", "issue_notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit) if @issue.editable? %>
 <%= link_to l(:button_log_time), new_issue_time_entry_path(@issue), :class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project) %>
-<%= watcher_tag(@issue, User.current) %>
-<%= link_to_if_authorized l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue}, :class => 'icon icon-copy' %>
+<%= watcher_link(@issue, User.current) %>
+<%= link_to l(:button_copy), project_copy_issue_path(@project, @issue), :class => 'icon icon-copy' if User.current.allowed_to?(:add_issues, @project) %>
 <%= link_to l(:button_delete), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if User.current.allowed_to?(:delete_issues, @project) %>
 </div>
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/_list.html.erb
--- a/app/views/issues/_list.html.erb
+++ b/app/views/issues/_list.html.erb
@@ -9,7 +9,6 @@
                               :onclick => 'toggleIssuesSelection(this); return false;',
                               :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
       </th>
-      <%= sort_header_tag('id', :caption => '#', :default_order => 'desc') %>
       <% query.inline_columns.each do |column| %>
         <%= column_header(column) %>
       <% end %>
@@ -32,13 +31,12 @@
   <% end %>
   <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
     <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
-    <td class="id"><%= link_to issue.id, issue_path(issue) %></td>
     <%= raw query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, issue)}</td>"}.join %>
   </tr>
   <% @query.block_columns.each do |column|
        if (text = column_content(column, issue)) && text.present? -%>
   <tr class="<%= current_cycle %>">
-    <td colspan="<%= @query.inline_columns.size + 2 %>" class="<%= column.css_classes %>"><%= text %></td>
+    <td colspan="<%= @query.inline_columns.size + 1 %>" class="<%= column.css_classes %>"><%= text %></td>
   </tr>
   <% end -%>
   <% end -%>
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/_list_simple.html.erb
--- a/app/views/issues/_list_simple.html.erb
+++ b/app/views/issues/_list_simple.html.erb
@@ -12,12 +12,12 @@
     <tr id="issue-<%= h(issue.id) %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %>">
       <td class="id">
         <%= check_box_tag("ids[]", issue.id, false, :style => 'display:none;', :id => nil) %>
-        <%= link_to(h(issue.id), :controller => 'issues', :action => 'show', :id => issue) %>
+        <%= link_to issue.id, issue_path(issue) %>
       </td>
       <td class="project"><%= link_to_project(issue.project) %></td>
       <td class="tracker"><%=h issue.tracker %></td>
       <td class="subject">
-        <%= link_to h(truncate(issue.subject, :length => 60)), :controller => 'issues', :action => 'show', :id => issue %> (<%=h issue.status %>)
+        <%= link_to truncate(issue.subject, :length => 60), issue_path(issue) %> (<%=h issue.status %>)
       </td>
     </tr>
     <% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/_relations.html.erb
--- a/app/views/issues/_relations.html.erb
+++ b/app/views/issues/_relations.html.erb
@@ -10,22 +10,25 @@
 <form>
 <table class="list issues">
 <% @relations.each do |relation| %>
-<tr class="issue hascontextmenu" id="relation-<%= relation.id %>">
-<td class="checkbox"><%= check_box_tag("ids[]", relation.other_issue(@issue).id, false, :id => nil) %></td>
-<td class="subject"><%= l(relation.label_for(@issue)) %> <%= "(#{l('datetime.distance_in_words.x_days', :count => relation.delay)})" if relation.delay && relation.delay != 0 %>
-    <%= h(relation.other_issue(@issue).project) + ' - ' if Setting.cross_project_issue_relations? %>
-    <%= link_to_issue(relation.other_issue(@issue), :truncate => 60) %>
-</td>
-<td class="status"><%=h relation.other_issue(@issue).status.name %></td>
-<td class="start_date"><%= format_date(relation.other_issue(@issue).start_date) %></td>
-<td class="due_date"><%= format_date(relation.other_issue(@issue).due_date) %></td>
-<td class="buttons"><%= link_to image_tag('link_break.png'),
-                                {:controller => 'issue_relations', :action => 'destroy', :id => relation},
-                                :remote => true,
-                                :method => :delete,
-                                :data => {:confirm => l(:text_are_you_sure)},
-                                :title => l(:label_relation_delete) if User.current.allowed_to?(:manage_issue_relations, @project) %></td>
-</tr>
+  <% other_issue = relation.other_issue(@issue) -%>
+  <tr class="issue hascontextmenu" id="relation-<%= relation.id %>">
+  <td class="checkbox"><%= check_box_tag("ids[]", other_issue.id, false, :id => nil) %></td>
+  <td class="subject">
+    <%= l(relation.label_for(@issue)) %>
+    <%= "(#{l('datetime.distance_in_words.x_days', :count => relation.delay)})" if relation.delay && relation.delay != 0 %>
+    <%= h(other_issue.project) + ' - ' if Setting.cross_project_issue_relations? %>
+    <%= link_to_issue(other_issue, :truncate => 60) %>
+  </td>
+  <td class="status"><%=h other_issue.status.name %></td>
+  <td class="start_date"><%= format_date(other_issue.start_date) %></td>
+  <td class="due_date"><%= format_date(other_issue.due_date) %></td>
+  <td class="buttons"><%= link_to image_tag('link_break.png'),
+                                  relation_path(relation),
+                                  :remote => true,
+                                  :method => :delete,
+                                  :data => {:confirm => l(:text_are_you_sure)},
+                                  :title => l(:label_relation_delete) if User.current.allowed_to?(:manage_issue_relations, @project) %></td>
+  </tr>
 <% end %>
 </table>
 </form>
@@ -33,7 +36,7 @@
 
 <%= form_for @relation, {
                  :as => :relation, :remote => true,
-                 :url => {:controller => 'issue_relations', :action => 'create', :issue_id => @issue},
+                 :url => issue_relations_path(@issue),
                  :method => :post,
                  :html => {:id => 'new-relation-form', :style => (@relation ? '' : 'display: none;')}
                } do |f| %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/_sidebar.html.erb
--- a/app/views/issues/_sidebar.html.erb
+++ b/app/views/issues/_sidebar.html.erb
@@ -1,15 +1,15 @@
 <h3><%= l(:label_issue_plural) %></h3>
-<%= link_to l(:label_issue_view_all), { :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1 } %><br />
+<%= link_to l(:label_issue_view_all), _project_issues_path(@project, :set_filter => 1) %><br />
 <% if @project %>
-<%= link_to l(:field_summary), :controller => 'reports', :action => 'issue_report', :id => @project %><br />
+<%= link_to l(:field_summary), project_issues_report_path(@project) %><br />
 <% end %>
 <%= call_hook(:view_issues_sidebar_issues_bottom) %>
 
 <% if User.current.allowed_to?(:view_calendar, @project, :global => true) %>
-  <%= link_to(l(:label_calendar), :controller => 'calendars', :action => 'show', :project_id => @project) %><br />
+  <%= link_to l(:label_calendar), _project_calendar_path(@project) %><br />
 <% end %>
 <% if User.current.allowed_to?(:view_gantt, @project, :global => true) %>
-  <%= link_to(l(:label_gantt), :controller => 'gantts', :action => 'show', :project_id => @project) %><br />
+  <%= link_to l(:label_gantt), _project_gantt_path(@project) %><br />
 <% end %>
 <%= call_hook(:view_issues_sidebar_planning_bottom) %>
 
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/_update_form.js.erb
--- a/app/views/issues/_update_form.js.erb
+++ /dev/null
@@ -1,7 +0,0 @@
-$('#all_attributes').html('<%= escape_javascript(render :partial => 'form') %>');
-
-<% if User.current.allowed_to?(:log_time, @issue.project) %>
-  $('#log_time').show();
-<% else %>
-  $('#log_time').hide();
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/bulk_edit.html.erb
--- a/app/views/issues/bulk_edit.html.erb
+++ b/app/views/issues/bulk_edit.html.erb
@@ -1,13 +1,12 @@
 <h2><%= @copy ? l(:button_copy) : l(:label_bulk_edit_selected_issues) %></h2>
 
-<ul><%= @issues.collect {|i|
-            content_tag('li',
-                        link_to(h("#{i.tracker} ##{i.id}"),
-                                { :action => 'show', :id => i }
-                            ) + h(": #{i.subject}"))
-         }.join("\n").html_safe %></ul>
+<ul id="bulk-selection">
+<% @issues.each do |issue| %>
+  <%= content_tag 'li', link_to_issue(issue) %>
+<% end %>
+</ul>
 
-<%= form_tag({:action => 'bulk_update'}, :id => 'bulk_edit_form') do %>
+<%= form_tag(bulk_update_issues_path, :id => 'bulk_edit_form') do %>
 <%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join("\n").html_safe %>
 <div class="box tabular">
 <fieldset class="attributes">
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/index.api.rsb
--- a/app/views/issues/index.api.rsb
+++ b/app/views/issues/index.api.rsb
@@ -23,6 +23,7 @@
 
       api.created_on issue.created_on
       api.updated_on issue.updated_on
+      api.closed_on  issue.closed_on
 
       api.array :relations do
         issue.relations.each do |relation|
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/index.html.erb
--- a/app/views/issues/index.html.erb
+++ b/app/views/issues/index.html.erb
@@ -24,7 +24,7 @@
         <table>
           <tr>
             <td><%= l(:field_column_names) %></td>
-            <td><%= render :partial => 'queries/columns', :locals => {:query => @query} %></td>
+            <td><%= render_query_columns_selection(@query) %></td>
           </tr>
           <tr>
             <td><label for='group_by'><%= l(:field_group_by) %></label></td>
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/show.api.rsb
--- a/app/views/issues/show.api.rsb
+++ b/app/views/issues/show.api.rsb
@@ -22,6 +22,7 @@
 
   api.created_on @issue.created_on
   api.updated_on @issue.updated_on
+  api.closed_on @issue.closed_on
 
   render_api_issue_children(@issue, api) if include_in_api_response?('children')
 
@@ -64,4 +65,10 @@
       end
     end
   end if include_in_api_response?('journals')
+
+  api.array :watchers do
+    @issue.watcher_users.each do |user|
+      api.user :id => user.id, :name => user.name
+    end
+  end if include_in_api_response?('watchers') && User.current.allowed_to?(:view_issue_watchers, @issue.project)
 end
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/show.html.erb
--- a/app/views/issues/show.html.erb
+++ b/app/views/issues/show.html.erb
@@ -61,7 +61,7 @@
     end
   end
   if User.current.allowed_to?(:view_time_entries, @project)
-    rows.right l(:label_spent_time), (@issue.total_spent_hours > 0 ? (link_to l_hours(@issue.total_spent_hours), {:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue}) : "-"), :class => 'spent-time'
+    rows.right l(:label_spent_time), (@issue.total_spent_hours > 0 ? link_to(l_hours(@issue.total_spent_hours), project_issue_time_entries_path(@project, @issue)) : "-"), :class => 'spent-time'
   end
 end %>
 <%= render_custom_fields_rows(@issue) %>
@@ -73,11 +73,7 @@
 <% if @issue.description? %>
 <div class="description">
   <div class="contextual">
-  <%= link_to l(:button_quote),
-              {:controller => 'journals', :action => 'new', :id => @issue},
-              :remote => true,
-              :method => 'post',
-              :class => 'icon icon-comment' if authorize_for('issues', 'edit') %>
+  <%= link_to l(:button_quote), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon icon-comment' if authorize_for('issues', 'edit') %>
   </div>
 
   <p><strong><%=l(:field_description)%></strong></p>
@@ -130,7 +126,7 @@
 <%= render :partial => 'action_menu' %>
 
 <div style="clear: both;"></div>
-<% if authorize_for('issues', 'edit') %>
+<% if @issue.editable? %>
   <div id="update" style="display:none;">
   <h3><%= l(:button_update) %></h3>
   <%= render :partial => 'edit' %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/issues/update_form.js.erb
--- /dev/null
+++ b/app/views/issues/update_form.js.erb
@@ -0,0 +1,7 @@
+$('#all_attributes').html('<%= escape_javascript(render :partial => 'form') %>');
+
+<% if User.current.allowed_to?(:log_time, @issue.project) %>
+  $('#log_time').show();
+<% else %>
+  $('#log_time').hide();
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/layouts/base.html.erb
--- a/app/views/layouts/base.html.erb
+++ b/app/views/layouts/base.html.erb
@@ -7,7 +7,7 @@
 <meta name="keywords" content="audio,music,software,research,UK,sound,repository,code,redmine" />
 <%= csrf_meta_tag %>
 <%= favicon %>
-<%= stylesheet_link_tag 'jquery/jquery-ui-1.8.21', 'application', :media => 'all' %>
+<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', :media => 'all' %>
 <%= stylesheet_platform_font_tag %>
 <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
 <%= javascript_heads %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/members/autocomplete.html.erb
--- a/app/views/members/autocomplete.html.erb
+++ /dev/null
@@ -1,1 +0,0 @@
-<%= principals_check_box_tags 'membership[user_ids][]', @principals %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/members/autocomplete.js.erb
--- /dev/null
+++ b/app/views/members/autocomplete.js.erb
@@ -0,0 +1,1 @@
+$('#principals_for_new_member').html('<%= escape_javascript(render_principals_for_new_members(@project)) %>');
diff -r 0a574315af3e -r 4f746d8966dd app/views/messages/show.html.erb
--- a/app/views/messages/show.html.erb
+++ b/app/views/messages/show.html.erb
@@ -1,7 +1,7 @@
 <%= board_breadcrumb(@message) %>
 
 <div class="contextual">
-    <%= watcher_tag(@topic, User.current) %>
+    <%= watcher_link(@topic, User.current) %>
     <%= link_to(
           l(:button_quote),
           {:action => 'quote', :id => @topic},
diff -r 0a574315af3e -r 4f746d8966dd app/views/my/blocks/_calendar.html.erb
--- a/app/views/my/blocks/_calendar.html.erb
+++ b/app/views/my/blocks/_calendar.html.erb
@@ -1,8 +1,6 @@
 <h3><%= l(:label_calendar) %></h3>
 
 <% calendar = Redmine::Helpers::Calendar.new(Date.today, current_language, :week)
-   calendar.events = Issue.visible.find :all,
-                     :conditions => ["#{Issue.table_name}.project_id in (#{@user.projects.collect{|m| m.id}.join(',')}) AND ((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?))", calendar.startdt, calendar.enddt, calendar.startdt, calendar.enddt],
-                     :include => [:project, :tracker, :priority, :assigned_to] unless @user.projects.empty? %>
+   calendar.events = calendar_items(calendar.startdt, calendar.enddt) %>
 
 <%= render :partial => 'common/calendar', :locals => {:calendar => calendar } %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/my/blocks/_documents.html.erb
--- a/app/views/my/blocks/_documents.html.erb
+++ b/app/views/my/blocks/_documents.html.erb
@@ -1,9 +1,3 @@
 <h3><%=l(:label_document_plural)%></h3>
 
-<% project_ids = @user.projects.select {|p| @user.allowed_to?(:view_documents, p)}.collect(&:id) %>
-<%= render(:partial => 'documents/document',
-           :collection => Document.find(:all,
-                         :limit => 10,
-                         :order => "#{Document.table_name}.created_on DESC",
-                         :conditions => "#{Document.table_name}.project_id in (#{project_ids.join(',')})",
-                         :include => [:project])) unless project_ids.empty? %>
\ No newline at end of file
+<%= render :partial => 'documents/document', :collection => documents_items %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/my/blocks/_issuesassignedtome.html.erb
--- a/app/views/my/blocks/_issuesassignedtome.html.erb
+++ b/app/views/my/blocks/_issuesassignedtome.html.erb
@@ -1,10 +1,6 @@
 <h3><%=l(:label_assigned_to_me_issues)%> (<%= Issue.visible.open.count(:conditions => {:assigned_to_id => ([User.current.id] + User.current.group_ids)})%>)</h3>
 
-<% assigned_issues = Issue.visible.open.find(:all,
-                                :conditions => {:assigned_to_id => ([User.current.id] + User.current.group_ids)},
-                                :limit => 10,
-                                :include => [ :status, :project, :tracker, :priority ],
-                                :order => "#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC") %>
+<% assigned_issues = issuesassignedtome_items %>
 <%= render :partial => 'issues/list_simple', :locals => { :issues => assigned_issues } %>
 <% if assigned_issues.length > 0 %>
 <p class="small"><%= link_to l(:label_issue_view_all), :controller => 'issues',
diff -r 0a574315af3e -r 4f746d8966dd app/views/my/blocks/_issuesreportedbyme.html.erb
--- a/app/views/my/blocks/_issuesreportedbyme.html.erb
+++ b/app/views/my/blocks/_issuesreportedbyme.html.erb
@@ -1,10 +1,6 @@
 <h3><%=l(:label_reported_issues)%> (<%= Issue.visible.count(:conditions => { :author_id => User.current.id }) %>)</h3>
 
-<% reported_issues = Issue.visible.find(:all,
-                                :conditions => { :author_id => User.current.id },
-                                :limit => 10,
-                                :include => [ :status, :project, :tracker ],
-                                :order => "#{Issue.table_name}.updated_on DESC") %>
+<% reported_issues = issuesreportedbyme_items %>
 <%= render :partial => 'issues/list_simple', :locals => { :issues => reported_issues } %>
 <% if reported_issues.length > 0 %>
 <p class="small"><%= link_to l(:label_issue_view_all), :controller => 'issues',
diff -r 0a574315af3e -r 4f746d8966dd app/views/my/blocks/_issueswatched.html.erb
--- a/app/views/my/blocks/_issueswatched.html.erb
+++ b/app/views/my/blocks/_issueswatched.html.erb
@@ -1,5 +1,5 @@
 <h3><%=l(:label_watched_issues)%> (<%= Issue.visible.watched_by(user.id).count %>)</h3>
-<% watched_issues = Issue.visible.on_active_project.watched_by(user.id).recently_updated.limit(10) %>
+<% watched_issues = issueswatched_items %>
 
 <%= render :partial => 'issues/list_simple', :locals => { :issues => watched_issues } %>
 <% if watched_issues.length > 0 %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/my/blocks/_news.html.erb
--- a/app/views/my/blocks/_news.html.erb
+++ b/app/views/my/blocks/_news.html.erb
@@ -1,8 +1,3 @@
 <h3><%=l(:label_news_latest)%></h3>
 
-<%= render(:partial => 'news/news',
-            :collection => News.find(:all,
-                                     :limit => 10,
-                                     :order => "#{News.table_name}.created_on DESC",
-                                     :conditions => "#{News.table_name}.project_id in (#{@user.projects.collect{|m| m.id}.join(',')})",
-                                     :include => [:project, :author])) unless @user.projects.empty? %>
+<%= render :partial => 'news/news', :collection => news_items %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/my/blocks/_timelog.html.erb
--- a/app/views/my/blocks/_timelog.html.erb
+++ b/app/views/my/blocks/_timelog.html.erb
@@ -1,14 +1,11 @@
 <h3><%=l(:label_spent_time)%> (<%= l(:label_last_n_days, 7) %>)</h3>
 <%
-entries = TimeEntry.find(:all,
-        :conditions => ["#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", @user.id, Date.today - 6, Date.today],
-        :include => [:activity, :project, {:issue => [:tracker, :status]}],
-        :order => "#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC")
+entries = timelog_items
 entries_by_day = entries.group_by(&:spent_on)
 %>
 
 <div class="total-hours">
-<p><%= l(:label_total) %>: <%= html_hours("%.2f" % entries.sum(&:hours).to_f) %></p>
+<p><%= l(:label_total_time) %>: <%= html_hours("%.2f" % entries.sum(&:hours).to_f) %></p>
 </div>
 
 <% if entries.any? %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/news/show.html.erb
--- a/app/views/news/show.html.erb
+++ b/app/views/news/show.html.erb
@@ -1,5 +1,5 @@
 <div class="contextual">
-<%= watcher_tag(@news, User.current) %>
+<%= watcher_link(@news, User.current) %>
 <%= link_to(l(:button_edit),
       edit_news_path(@news),
       :class => 'icon icon-edit',
diff -r 0a574315af3e -r 4f746d8966dd app/views/previews/issue.html.erb
--- a/app/views/previews/issue.html.erb
+++ b/app/views/previews/issue.html.erb
@@ -1,11 +1,11 @@
 <% if @notes %>
   <fieldset class="preview"><legend><%= l(:field_notes) %></legend>
-    <%= textilizable @notes, :attachments => @attachements, :object => @issue %>
+    <%= textilizable @notes, :attachments => @attachments, :object => @issue %>
   </fieldset>
 <% end %>
 
 <% if @description %>
   <fieldset class="preview"><legend><%= l(:field_description) %></legend>
-    <%= textilizable @description, :attachments => @attachements, :object => @issue %>
+    <%= textilizable @description, :attachments => @attachments, :object => @issue %>
   </fieldset>
 <% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/projects/_form.html.erb
--- a/app/views/projects/_form.html.erb
+++ b/app/views/projects/_form.html.erb
@@ -7,12 +7,8 @@
   <em class="info"> <%= l(:text_project_name_info).html_safe %></em>
 </p>
 
-<% unless @project.allowed_parents.compact.empty? %>
-    <p><%= label(:project, :parent_id, l(:field_parent)) %><%= parent_project_select_tag(@project) %></p>
-<% end %>
-
-<p><%= f.text_area :description, :rows => 5, :class => 'wiki-edit' %></p>
-<p><%= f.text_field :identifier, :required => true, :size => 60, :disabled => @project.identifier_frozen? %>
+<p><%= f.text_area :description, :rows => 8, :class => 'wiki-edit' %></p>
+<p><%= f.text_field :identifier, :required => true, :size => 60, :disabled => @project.identifier_frozen?, :maxlength => Project::IDENTIFIER_MAX_LENGTH %>
 <% unless @project.identifier_frozen? %>
   <br />
   <em class="info"><%= l(:text_length_between, :min => 1, :max => Project::IDENTIFIER_MAX_LENGTH) %> <%= l(:text_project_identifier_info).html_safe %></em>
@@ -36,6 +32,15 @@
 <br>
   <em class="info"><%= l(:text_project_visibility_info) %></em>
 </p>
+
+<% unless @project.allowed_parents.compact.empty? %>
+    <p><%= label(:project, :parent_id, l(:field_parent)) %><%= parent_project_select_tag(@project) %></p>
+<% end %>
+
+<% if @project.safe_attribute? 'inherit_members' %>
+<p><%= f.check_box :inherit_members %></p>
+<% end %>
+
 <%= wikitoolbar_for 'project_description' %>
 
 <% @project.custom_field_values.each do |value| %>
@@ -88,3 +93,23 @@
 <% end %>
 <% end %>
 <!--[eoform:project]-->
+
+<% unless @project.identifier_frozen? %>
+  <% content_for :header_tags do %>
+    <%= javascript_include_tag 'project_identifier' %>
+  <% end %>
+<% end %>
+
+<% if !User.current.admin? && @project.inherit_members? && @project.parent && User.current.member_of?(@project.parent) %>
+  <%= javascript_tag do %>
+    $(document).ready(function() {
+      $("#project_inherit_members").change(function(){
+        if (!$(this).is(':checked')) {
+          if (!confirm("<%= escape_javascript(l(:text_own_membership_delete_confirmation)) %>")) {
+            $("#project_inherit_members").attr("checked", true);
+          }
+        }
+      });
+    });
+  <% end %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/projects/settings/_members.html.erb
--- a/app/views/projects/settings/_members.html.erb
+++ b/app/views/projects/settings/_members.html.erb
@@ -1,6 +1,6 @@
 <%= error_messages_for 'member' %>
 <% roles = Role.find_all_givable
-   members = @project.member_principals.find(:all, :include => [:roles, :principal]).sort %>
+   members = @project.member_principals.includes(:roles, :principal).all.sort %>
 
 <div class="splitcontentleft">
 <% if members.any? %>
@@ -51,18 +51,16 @@
 <% end %>
 </div>
 
-<% principals = Principal.active.not_member_of(@project).all(:limit => 100, :order => 'type, login, lastname ASC') %>
-
 <div class="splitcontentright">
-<% if roles.any? && principals.any? %>
+<% if roles.any? %>
   <%= form_for(@member, {:as => :membership, :url => project_memberships_path(@project), :remote => true, :method => :post}) do |f| %>
     <fieldset><legend><%=l(:label_member_new)%></legend>
 
     <p><%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %></p>
-    <%= javascript_tag "observeSearchfield('principal_search', 'principals', '#{ escape_javascript autocomplete_project_memberships_path(@project) }')" %>
+    <%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_project_memberships_path(@project, :format => 'js') }')" %>
 
-    <div id="principals">
-      <%= principals_check_box_tags 'membership[user_ids][]', principals %>
+    <div id="principals_for_new_member">
+      <%= render_principals_for_new_members(@project) %>
     </div>
 
     <p><%= l(:label_role_plural) %>:
diff -r 0a574315af3e -r 4f746d8966dd app/views/projects/settings/_modules.html.erb
--- a/app/views/projects/settings/_modules.html.erb
+++ b/app/views/projects/settings/_modules.html.erb
@@ -3,8 +3,7 @@
             :html => {:id => 'modules-form',
                       :method => :post} do |f| %>
 
-<div class="box">
-<fieldset>
+<fieldset class="box">
 <legend><%= l(:text_select_project_modules) %></legend>
 
 <% Redmine::AccessControl.available_project_modules.each do |m| %>
@@ -12,9 +11,8 @@
  <%= l_or_humanize(m, :prefix => "project_module_") %></label></p>
 <% end %>
 </fieldset>
-</div>
+<p><%= check_all_links 'modules-form' %></p>
 
-<p><%= check_all_links 'modules-form' %></p>
 <p><%= submit_tag l(:button_save) %></p>
 
 <% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/projects/show.html.erb
--- a/app/views/projects/show.html.erb
+++ b/app/views/projects/show.html.erb
@@ -1,6 +1,6 @@
 <div class="contextual">
   <% if User.current.allowed_to?(:add_subprojects, @project) %>
-    <%= link_to l(:label_subproject_new), {:controller => 'projects', :action => 'new', :parent_id => @project}, :class => 'icon icon-add' %>
+    <%= link_to l(:label_subproject_new), new_project_path(:parent_id => @project), :class => 'icon icon-add' %>
   <% end %>
   <% if User.current.allowed_to?(:close_project, @project) %>
     <% if @project.active? %>
@@ -57,7 +57,7 @@
   <% end %>
   <% if @subprojects.any? %>
     <li><%=l(:label_subproject_plural)%>:
-      <%= @subprojects.collect{|p| link_to(h(p), :action => 'show', :id => p)}.join(", ").html_safe %></li>
+      <%= @subprojects.collect{|p| link_to p, project_path(p)}.join(", ").html_safe %></li>
   <% end %>
   <% @project.visible_custom_field_values.each do |custom_value| %>
   <% if !custom_value.value.blank? %>
@@ -72,21 +72,19 @@
     <h3><%=l(:label_issue_tracking)%></h3>
     <ul>
     <% for tracker in @trackers %>
-      <li><%= link_to h(tracker.name), :controller => 'issues', :action => 'index', :project_id => @project,
-                                                :set_filter => 1,
-                                                "tracker_id" => tracker.id %>:
+      <li><%= link_to h(tracker.name), project_issues_path(@project, :set_filter => 1, :tracker_id => tracker.id) %>:
           <%= l(:label_x_open_issues_abbr_on_total, :count => @open_issues_by_tracker[tracker].to_i,
                                                     :total => @total_issues_by_tracker[tracker].to_i) %>
       </li>
     <% end %>
     </ul>
     <p>
-      <%= link_to l(:label_issue_view_all), :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1 %>
+      <%= link_to l(:label_issue_view_all), project_issues_path(@project, :set_filter => 1) %>
       <% if User.current.allowed_to?(:view_calendar, @project, :global => true) %>
-        | <%= link_to(l(:label_calendar), :controller => 'calendars', :action => 'show', :project_id => @project) %>
+        | <%= link_to l(:label_calendar), project_calendar_path(@project) %>
       <% end %>
       <% if User.current.allowed_to?(:view_gantt, @project, :global => true) %>
-        | <%= link_to(l(:label_gantt), :controller => 'gantts', :action => 'show', :project_id => @project) %>
+        | <%= link_to l(:label_gantt), project_gantt_path(@project) %>
       <% end %>
     </p>
   </div>
@@ -103,7 +101,7 @@
   <div class="news box">
     <h3><%=l(:label_news_latest)%></h3>
     <%= render :partial => 'news/news', :collection => @news %>
-    <p><%= link_to l(:label_news_view_all), :controller => 'news', :action => 'index', :project_id => @project %></p>
+    <p><%= link_to l(:label_news_view_all), project_news_index_path(@project) %></p>
   </div>
   <% end %>
 
diff -r 0a574315af3e -r 4f746d8966dd app/views/queries/_columns.html.erb
--- a/app/views/queries/_columns.html.erb
+++ b/app/views/queries/_columns.html.erb
@@ -4,7 +4,7 @@
       <%= label_tag "available_columns", l(:description_available_columns) %>
       <br />
       <%= select_tag 'available_columns',
-              options_for_select((query.available_inline_columns - query.columns).collect {|column| [column.caption, column.name]}),
+              options_for_select(query_available_inline_columns_options(query)),
               :multiple => true, :size => 10, :style => "width:150px",
               :ondblclick => "moveOptions(this.form.available_columns, this.form.selected_columns);" %>
     </td>
@@ -17,10 +17,10 @@
     <td>
       <%= label_tag "selected_columns", l(:description_selected_columns) %>
       <br />
-      <%= select_tag((defined?(tag_name) ? tag_name : 'c[]'),
-              options_for_select(query.inline_columns.collect {|column| [column.caption, column.name]}),
+      <%= select_tag tag_name,
+              options_for_select(query_selected_inline_columns_options(query)),
               :id => 'selected_columns', :multiple => true, :size => 10, :style => "width:150px",
-              :ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);") %>
+              :ondblclick => "moveOptions(this.form.selected_columns, this.form.available_columns);" %>
     </td>
     <td class="buttons">
       <input type="button" value="&#8593;" onclick="moveOptionUp(this.form.selected_columns);" /><br />
diff -r 0a574315af3e -r 4f746d8966dd app/views/queries/_form.html.erb
--- a/app/views/queries/_form.html.erb
+++ b/app/views/queries/_form.html.erb
@@ -49,7 +49,7 @@
 
 <%= content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %>
 <legend><%= l(:field_column_names) %></legend>
-<%= render :partial => 'queries/columns', :locals => {:query => query}%>
+<%= render_query_columns_selection(query) %>
 <% end %>
 
 </div>
diff -r 0a574315af3e -r 4f746d8966dd app/views/reports/_details.html.erb
--- a/app/views/reports/_details.html.erb
+++ b/app/views/reports/_details.html.erb
@@ -15,36 +15,13 @@
 <tbody>
 <% for row in rows %>
 <tr class="<%= cycle("odd", "even") %>">
-  <td><%= link_to h(row.name), :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
-                                                :set_filter => 1,
-                                                :subproject_id => '!*',
-                                                "#{field_name}" => row.id %></td>
+  <td><%= link_to h(row.name), aggregate_path(@project, field_name, row) %></td>
   <% for status in @statuses %>
-    <td align="center"><%= aggregate_link data, { field_name => row.id, "status_id" => status.id },
-                                                :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
-                                                :set_filter => 1,
-                                                :subproject_id => '!*',
-                                                "status_id" => status.id,
-                                                "#{field_name}" => row.id %></td>
+    <td align="center"><%= aggregate_link data, { field_name => row.id, "status_id" => status.id }, aggregate_path(@project, field_name, row, :status_id => status.id) %></td>
   <% end %>
-  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 },
-                                                :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
-                                                :set_filter => 1,
-                                                :subproject_id => '!*',
-                                                "#{field_name}" => row.id,
-                                                "status_id" => "o" %></td>
-  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 },
-                                                :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
-                                                :set_filter => 1,
-                                                :subproject_id => '!*',
-                                                "#{field_name}" => row.id,
-                                                "status_id" => "c" %></td>
-  <td align="center"><%= aggregate_link data, { field_name => row.id },
-                                                :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
-                                                :set_filter => 1,
-                                                :subproject_id => '!*',
-                                                "#{field_name}" => row.id,
-                                                "status_id" => "*" %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o") %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c") %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*") %></td>
 </tr>
 <% end %>
 </tbody>
diff -r 0a574315af3e -r 4f746d8966dd app/views/reports/_simple.html.erb
--- a/app/views/reports/_simple.html.erb
+++ b/app/views/reports/_simple.html.erb
@@ -11,28 +11,10 @@
 <tbody>
 <% for row in rows %>
 <tr class="<%= cycle("odd", "even") %>">
-  <td><%= link_to h(row.name), :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
-                                                :set_filter => 1,
-                                                :subproject_id => '!*',
-                                                "#{field_name}" => row.id %></td>
-  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 },
-                                                :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
-                                                :set_filter => 1,
-                                                :subproject_id => '!*',
-                                                "#{field_name}" => row.id,
-                                                "status_id" => "o" %></td>
-  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 },
-                                                :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
-                                                :set_filter => 1,
-                                                :subproject_id => '!*',
-                                                "#{field_name}" => row.id,
-                                                "status_id" => "c" %></td>
-  <td align="center"><%= aggregate_link data, { field_name => row.id },
-                                                :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
-                                                :set_filter => 1,
-                                                :subproject_id => '!*',
-                                                "#{field_name}" => row.id,
-                                                "status_id" => "*" %></td>
+  <td><%= link_to h(row.name), aggregate_path(@project, field_name, row) %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 }, aggregate_path(@project, field_name, row, :status_id => "o") %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 }, aggregate_path(@project, field_name, row, :status_id => "c") %></td>
+  <td align="center"><%= aggregate_link data, { field_name => row.id }, aggregate_path(@project, field_name, row, :status_id => "*") %></td>
 </tr>
 <% end %>
 </tbody>
diff -r 0a574315af3e -r 4f746d8966dd app/views/reports/issue_report.html.erb
--- a/app/views/reports/issue_report.html.erb
+++ b/app/views/reports/issue_report.html.erb
@@ -1,31 +1,31 @@
 <h2><%=l(:label_report_plural)%></h2>
 
 <div class="splitcontentleft">
-<h3><%=l(:field_tracker)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), :action => 'issue_report_details', :detail => 'tracker' %></h3>
+<h3><%=l(:field_tracker)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'tracker') %></h3>
 <%= render :partial => 'simple', :locals => { :data => @issues_by_tracker, :field_name => "tracker_id", :rows => @trackers } %>
 <br />
-<h3><%=l(:field_priority)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), :action => 'issue_report_details', :detail => 'priority' %></h3>
+<h3><%=l(:field_priority)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'priority') %></h3>
 <%= render :partial => 'simple', :locals => { :data => @issues_by_priority, :field_name => "priority_id", :rows => @priorities } %>
 <br />
-<h3><%=l(:field_assigned_to)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), :action => 'issue_report_details', :detail => 'assigned_to' %></h3>
+<h3><%=l(:field_assigned_to)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'assigned_to') %></h3>
 <%= render :partial => 'simple', :locals => { :data => @issues_by_assigned_to, :field_name => "assigned_to_id", :rows => @assignees } %>
 <br />
-<h3><%=l(:field_author)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), :action => 'issue_report_details', :detail => 'author' %></h3>
+<h3><%=l(:field_author)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'author') %></h3>
 <%= render :partial => 'simple', :locals => { :data => @issues_by_author, :field_name => "author_id", :rows => @authors } %>
 <br />
 <%= call_hook(:view_reports_issue_report_split_content_left, :project => @project) %>
 </div>
 
 <div class="splitcontentright">
-<h3><%=l(:field_version)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), :action => 'issue_report_details', :detail => 'version' %></h3>
+<h3><%=l(:field_version)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'version') %></h3>
 <%= render :partial => 'simple', :locals => { :data => @issues_by_version, :field_name => "fixed_version_id", :rows => @versions } %>
 <br />
 <% if @project.children.any? %>
-<h3><%=l(:field_subproject)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), :action => 'issue_report_details', :detail => 'subproject' %></h3>
+<h3><%=l(:field_subproject)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'subproject') %></h3>
 <%= render :partial => 'simple', :locals => { :data => @issues_by_subproject, :field_name => "project_id", :rows => @subprojects } %>
 <br />
 <% end %>
-<h3><%=l(:field_category)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), :action => 'issue_report_details', :detail => 'category' %></h3>
+<h3><%=l(:field_category)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), project_issues_report_details_path(@project, :detail => 'category') %></h3>
 <%= render :partial => 'simple', :locals => { :data => @issues_by_category, :field_name => "category_id", :rows => @categories } %>
 <br />
 <%= call_hook(:view_reports_issue_report_split_content_right, :project => @project) %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/reports/issue_report_details.html.erb
--- a/app/views/reports/issue_report_details.html.erb
+++ b/app/views/reports/issue_report_details.html.erb
@@ -3,5 +3,5 @@
 <h3><%=@report_title%></h3>
 <%= render :partial => 'details', :locals => { :data => @data, :field_name => @field, :rows => @rows } %>
 <br />
-<%= link_to l(:button_back), :action => 'issue_report' %>
+<%= link_to l(:button_back), project_issues_report_path(@project) %>
 
diff -r 0a574315af3e -r 4f746d8966dd app/views/roles/index.html.erb
--- a/app/views/roles/index.html.erb
+++ b/app/views/roles/index.html.erb
@@ -1,6 +1,6 @@
 <div class="contextual">
 <%= link_to l(:label_role_new), new_role_path, :class => 'icon icon-add' %>
-<%= link_to l(:label_permissions_report), {:action => 'permissions'}, :class => 'icon icon-summary' %>
+<%= link_to l(:label_permissions_report), permissions_roles_path, :class => 'icon icon-summary' %>
 </div>
 
 <h2><%=l(:label_role_plural)%></h2>
diff -r 0a574315af3e -r 4f746d8966dd app/views/settings/_authentication.html.erb
--- a/app/views/settings/_authentication.html.erb
+++ b/app/views/settings/_authentication.html.erb
@@ -19,6 +19,8 @@
 <p><%= setting_check_box :openid, :disabled => !Object.const_defined?(:OpenID) %></p>
 
 <p><%= setting_check_box :rest_api_enabled %></p>
+
+<p><%= setting_check_box :jsonp_enabled %></p>
 </div>
 
 <fieldset class="box">
diff -r 0a574315af3e -r 4f746d8966dd app/views/settings/_issues.html.erb
--- a/app/views/settings/_issues.html.erb
+++ b/app/views/settings/_issues.html.erb
@@ -22,11 +22,9 @@
 
 <fieldset class="box">
 	<legend><%= l(:setting_issue_list_default_columns) %></legend>
-  <%= render :partial => 'queries/columns',
-             :locals => {
-               :query => Query.new(:column_names => Setting.issue_list_default_columns),
-               :tag_name => 'settings[issue_list_default_columns][]'
-             } %>
+  <%= render_query_columns_selection(
+        IssueQuery.new(:column_names => Setting.issue_list_default_columns),
+        :name => 'settings[issue_list_default_columns]') %>
 </fieldset>
 
 <%= submit_tag l(:button_save) %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/settings/_projects.html.erb
--- a/app/views/settings/_projects.html.erb
+++ b/app/views/settings/_projects.html.erb
@@ -6,6 +6,9 @@
 <p><%= setting_multiselect(:default_projects_modules,
         Redmine::AccessControl.available_project_modules.collect {|m| [l_or_humanize(m, :prefix => "project_module_"), m.to_s]}) %></p>
 
+<p><%= setting_multiselect(:default_projects_tracker_ids,
+        Tracker.sorted.all.collect {|t| [t.name, t.id.to_s]}) %></p>
+
 <p><%= setting_check_box :sequential_project_identifiers %></p>
 
 <p><%= setting_select :new_project_user_role_id,
diff -r 0a574315af3e -r 4f746d8966dd app/views/settings/_repositories.html.erb
--- a/app/views/settings/_repositories.html.erb
+++ b/app/views/settings/_repositories.html.erb
@@ -68,7 +68,7 @@
 <p><%= setting_text_field :commit_fix_keywords, :size => 30 %>
 &nbsp;<%= l(:label_applied_status) %>: <%= setting_select :commit_fix_status_id,
                                                           [["", 0]] +
-                                                              IssueStatus.find(:all).collect{
+                                                              IssueStatus.sorted.all.collect{
                                                                  |status| [status.name, status.id.to_s]
                                                               },
                                                           :label => false %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/settings/plugin.html.erb
--- a/app/views/settings/plugin.html.erb
+++ b/app/views/settings/plugin.html.erb
@@ -2,7 +2,7 @@
 
 <div id="settings">
 <%= form_tag({:action => 'plugin'}) do %>
-<div class="box tabular">
+<div class="box tabular settings">
 <%= render :partial => @partial, :locals => {:settings => @settings}%>
 </div>
 <%= submit_tag l(:button_apply) %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/timelog/_date_range.html.erb
--- a/app/views/timelog/_date_range.html.erb
+++ b/app/views/timelog/_date_range.html.erb
@@ -1,42 +1,34 @@
-<fieldset id="date-range" class="collapsible">
-<legend onclick="toggleFieldset(this);"><%= l(:label_date_range) %></legend>
-<div>
-<p>
-<%= label_tag "period_type_list", l(:description_date_range_list), :class => "hidden-for-sighted" %>
-<%= radio_button_tag 'period_type', '1', !@free_period, :onclick => '$("#from,#to").attr("disabled", true);$("#period").removeAttr("disabled");', :id => "period_type_list"%>
-<%= select_tag 'period', options_for_period_select(params[:period]),
-                         :onchange => 'this.form.submit();',
-                         :onfocus => '$("#period_type_1").attr("checked", true);',
-                         :disabled => @free_period %>
-</p>
-<p>
-<%= label_tag "period_type_interval", l(:description_date_range_interval), :class => "hidden-for-sighted" %>
-<%= radio_button_tag 'period_type', '2', @free_period, :onclick => '$("#from,#to").removeAttr("disabled");$("#period").attr("disabled", true);', :id => "period_type_interval" %>
-<%= l(:label_date_from_to,
-        :start => ((label_tag "from", l(:description_date_from), :class => "hidden-for-sighted") + 
-            text_field_tag('from', @from, :size => 10, :disabled => !@free_period) + calendar_for('from')),
-        :end => ((label_tag "to", l(:description_date_to), :class => "hidden-for-sighted") +
-            text_field_tag('to', @to, :size => 10, :disabled => !@free_period) + calendar_for('to'))).html_safe %>
-</p>
+<div id="query_form_content" class="hide-when-print">
+  <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
+    <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
+    <div style="<%= @query.new_record? ? "" : "display: none;" %>">
+      <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
+    </div>
+  </fieldset>
+  <fieldset class="collapsible collapsed">
+    <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
+    <div style="display: none;">
+      <table>
+        <tr>
+          <td><%= l(:field_column_names) %></td>
+          <td><%= render_query_columns_selection(@query) %></td>
+        </tr>
+      </table>
+    </div>
+  </fieldset>
 </div>
-</fieldset>
-<p class="buttons">
-  <%= link_to_function l(:button_apply), '$("#query_form").submit()', :class => 'icon icon-checked' %>
-  <%= link_to l(:button_clear), {:controller => controller_name, :action => action_name, :project_id => @project, :issue_id => @issue}, :class => 'icon icon-reload' %>
+
+<p class="buttons hide-when-print">
+  <%= link_to_function l(:button_apply), 'submit_query_form("query_form")', :class => 'icon icon-checked' %>
+  <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue}, :class => 'icon icon-reload'  %>
 </p>
 
 <div class="tabs">
-<% url_params = @free_period ? { :from => @from, :to => @to } : { :period => params[:period] } %>
+<% query_params = params.slice(:f, :op, :v, :sort) %>
 <ul>
-    <li><%= link_to(l(:label_details), url_params.merge({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue }),
+    <li><%= link_to(l(:label_details), query_params.merge({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue }),
                                        :class => (action_name == 'index' ? 'selected' : nil)) %></li>
-    <li><%= link_to(l(:label_report), url_params.merge({:controller => 'timelog', :action => 'report', :project_id => @project, :issue_id => @issue}),
+    <li><%= link_to(l(:label_report), query_params.merge({:controller => 'timelog', :action => 'report', :project_id => @project, :issue_id => @issue}),
                                        :class => (action_name == 'report' ? 'selected' : nil)) %></li>
 </ul>
 </div>
-
-<%= javascript_tag do %>
-$('#from, #to').change(function(){
-  $('#period_type_interval').attr('checked', true); $('#from,#to').removeAttr('disabled'); $('#period').attr('disabled', true);
-});
-<% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/timelog/_form.html.erb
--- a/app/views/timelog/_form.html.erb
+++ b/app/views/timelog/_form.html.erb
@@ -2,22 +2,31 @@
 <%= back_url_hidden_field_tag %>
 
 <div class="box tabular">
-	<% if @time_entry.new_record? %>
-	  <% if params[:project_id] || @time_entry.issue %>
-	    <%= f.hidden_field :project_id %>
-	  <% else %>
-	    <p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project), :required => true %></p>
-	  <% end %>
-	<% end %>
-	<p><%= f.text_field :issue_id, :size => 6 %> <em><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></em></p>
-	<p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
-	<p><%= f.text_field :hours, :size => 6, :required => true %></p>
-	<p><%= f.text_field :comments, :size => 100, :maxlength => 255 %></p>
-	<p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
-	<% @time_entry.custom_field_values.each do |value| %>
-	  <p><%= custom_field_tag_with_label :time_entry, value %></p>
-	<% end %>
-	<%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
+  <% if @time_entry.new_record? %>
+    <% if params[:project_id] || @time_entry.issue %>
+      <%= f.hidden_field :project_id %>
+    <% else %>
+      <p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project), :required => true %></p>
+    <% end %>
+  <% end %>
+  <p>
+    <%= f.text_field :issue_id, :size => 6 %>
+    <span id="time_entry_issue"><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></span>
+  </p>
+  <p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
+  <p><%= f.text_field :hours, :size => 6, :required => true %></p>
+  <p><%= f.text_field :comments, :size => 100, :maxlength => 255 %></p>
+  <p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
+  <% @time_entry.custom_field_values.each do |value| %>
+    <p><%= custom_field_tag_with_label :time_entry, value %></p>
+  <% end %>
+  <%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
 </div>
 
-<%= javascript_tag "observeAutocompleteField('time_entry_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (@project ? nil : 'all'))}')" %>
+<%= javascript_tag do %>
+  observeAutocompleteField('time_entry_issue_id', '<%= escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (@project ? nil : 'all'))%>', {
+    select: function(event, ui) {
+      $('#time_entry_issue').text(ui.item.label);
+    }
+  });
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/timelog/_list.html.erb
--- a/app/views/timelog/_list.html.erb
+++ b/app/views/timelog/_list.html.erb
@@ -3,49 +3,35 @@
 <div class="autoscroll">
 <table class="list time-entries">
 <thead>
-<tr>
-<th class="checkbox hide-when-print">
-  <%= link_to image_tag('toggle_check.png'),
-    {},
-    :onclick => 'toggleIssuesSelection(this); return false;',
-    :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
-</th>
-<%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %>
-<%= sort_header_tag('user', :caption => l(:label_member)) %>
-<%= sort_header_tag('activity', :caption => l(:label_activity)) %>
-<%= sort_header_tag('project', :caption => l(:label_project)) %>
-<%= sort_header_tag('issue', :caption => l(:label_issue), :default_order => 'desc') %>
-<th><%= l(:field_comments) %></th>
-<%= sort_header_tag('hours', :caption => l(:field_hours)) %>
-<th></th>
-</tr>
+  <tr>
+    <th class="checkbox hide-when-print">
+      <%= link_to image_tag('toggle_check.png'),
+        {},
+        :onclick => 'toggleIssuesSelection(this); return false;',
+        :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
+    </th>
+    <% @query.inline_columns.each do |column| %>
+      <%= column_header(column) %>
+    <% end %>
+    <th></th>
+  </tr>
 </thead>
 <tbody>
 <% entries.each do |entry| -%>
-<tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
-<td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
-<td class="spent_on"><%= format_date(entry.spent_on) %></td>
-<td class="user"><%= link_to_user(entry.user) %></td>
-<td class="activity"><%=h entry.activity %></td>
-<td class="project"><%= link_to_project(entry.project) %></td>
-<td class="subject">
-<% if entry.issue -%>
-<%= entry.issue.visible? ? link_to_issue(entry.issue, :truncate => 50) : "##{entry.issue.id}" -%>
-<% end -%>
-</td>
-<td class="comments"><%=h entry.comments %></td>
-<td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
-<td align="center">
-<% if entry.editable_by?(User.current) -%>
-    <%= link_to image_tag('edit.png'), edit_time_entry_path(entry),
-                                       :title => l(:button_edit) %>
-    <%= link_to image_tag('delete.png'), time_entry_path(entry),
-                                         :data => {:confirm => l(:text_are_you_sure)},
-                                         :method => :delete,
-                                         :title => l(:button_delete) %>
-<% end -%>
-</td>
-</tr>
+  <tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
+    <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
+    <%= raw @query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, entry)}</td>"}.join %>
+    <td align="center">
+    <% if entry.editable_by?(User.current) -%>
+        <%= link_to image_tag('edit.png'), edit_time_entry_path(entry),
+                                           :title => l(:button_edit) %>
+        <%= link_to image_tag('delete.png'), time_entry_path(entry),
+                                             :data => {:confirm => l(:text_are_you_sure)},
+                                             :method => :delete,
+                                             :title => l(:button_delete) %>
+    <% end -%>
+    </td>
+  </tr>
 <% end -%>
 </tbody>
 </table>
diff -r 0a574315af3e -r 4f746d8966dd app/views/timelog/bulk_edit.html.erb
--- a/app/views/timelog/bulk_edit.html.erb
+++ b/app/views/timelog/bulk_edit.html.erb
@@ -1,13 +1,13 @@
 <h2><%= l(:label_bulk_edit_selected_time_entries) %></h2>
 
-<ul>
-<%= @time_entries.collect {|i| content_tag('li', 
-        link_to(h("#{i.spent_on.strftime("%Y-%m-%d")} - #{i.project}:  #{l(:label_f_hour_plural, :value => i.hours)}"),
-                { :action => 'edit', :id => i })
-     )}.join("\n").html_safe %>
+<ul id="bulk-selection">
+<% @time_entries.each do |entry| %>
+  <%= content_tag 'li',
+        link_to("#{format_date(entry.spent_on)} - #{entry.project}: #{l(:label_f_hour_plural, :value => entry.hours)}", edit_time_entry_path(entry)) %>
+<% end %>
 </ul>
 
-<%= form_tag(:action => 'bulk_update') do %>
+<%= form_tag(bulk_update_time_entries_path, :id => 'bulk_edit_form') do %>
 <%= @time_entries.collect {|i| hidden_field_tag('ids[]', i.id)}.join.html_safe %>
 <div class="box tabular">
   <div>
diff -r 0a574315af3e -r 4f746d8966dd app/views/timelog/index.html.erb
--- a/app/views/timelog/index.html.erb
+++ b/app/views/timelog/index.html.erb
@@ -13,7 +13,7 @@
 <% end %>
 
 <div class="total-hours">
-<p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
+<p><%= l(:label_total_time) %>: <%= html_hours(l_hours(@total_hours)) %></p>
 </div>
 
 <% unless @entries.empty? %>
@@ -22,8 +22,23 @@
 
 <% other_formats_links do |f| %>
   <%= f.link_to 'Atom', :url => params.merge({:issue_id => @issue, :key => User.current.rss_key}) %>
-  <%= f.link_to 'CSV', :url => params %>
+  <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
 <% end %>
+
+<div id="csv-export-options" style="display:none;">
+  <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
+  <%= form_tag(params.slice(:project_id, :issue_id).merge(:format => 'csv', :page=>nil), :method => :get, :id => 'csv-export-form') do %>
+  <%= query_hidden_tags @query %>
+  <p>
+    <label><%= radio_button_tag 'columns', '', true %> <%= l(:description_selected_columns) %></label><br />
+    <label><%= radio_button_tag 'columns', 'all' %> <%= l(:description_all_columns) %></label>
+  </p>
+  <p class="buttons">
+    <%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);" %>
+    <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
+  </p>
+  <% end %>
+</div>
 <% end %>
 
 <% html_title l(:label_spent_time), l(:label_details) %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/timelog/report.html.erb
--- a/app/views/timelog/report.html.erb
+++ b/app/views/timelog/report.html.erb
@@ -30,7 +30,7 @@
 
 <% unless @report.criteria.empty? %>
 <div class="total-hours">
-<p><%= l(:label_total) %>: <%= html_hours(l_hours(@report.total_hours)) %></p>
+<p><%= l(:label_total_time) %>: <%= html_hours(l_hours(@report.total_hours)) %></p>
 </div>
 
 <% unless @report.hours.empty? %>
@@ -45,13 +45,13 @@
 <% @report.periods.each do |period| %>
   <th class="period" width="<%= columns_width %>%"><%= period %></th>
 <% end %>
-  <th class="total" width="<%= columns_width %>%"><%= l(:label_total) %></th>
+  <th class="total" width="<%= columns_width %>%"><%= l(:label_total_time) %></th>
 </tr>
 </thead>
 <tbody>
 <%= render :partial => 'report_criteria', :locals => {:criterias => @report.criteria, :hours => @report.hours, :level => 0} %>
   <tr class="total">
-  <td><%= l(:label_total) %></td>
+  <td><%= l(:label_total_time) %></td>
   <%= ('<td></td>' * (@report.criteria.size - 1)).html_safe %>
   <% total = 0 -%>
   <% @report.periods.each do |period| -%>
diff -r 0a574315af3e -r 4f746d8966dd app/views/trackers/fields.html.erb
--- a/app/views/trackers/fields.html.erb
+++ b/app/views/trackers/fields.html.erb
@@ -1,7 +1,7 @@
 <h2><%= link_to l(:label_tracker_plural), trackers_path %> &#187; <%= l(:field_summary) %></h2>
 
 <% if @trackers.any? %>
-  <%= form_tag({}) do %>
+  <%= form_tag fields_trackers_path do %>
     <div class="autoscroll">
     <table class="list">
     <thead>
diff -r 0a574315af3e -r 4f746d8966dd app/views/trackers/index.html.erb
--- a/app/views/trackers/index.html.erb
+++ b/app/views/trackers/index.html.erb
@@ -1,6 +1,6 @@
 <div class="contextual">
 <%= link_to l(:label_tracker_new), new_tracker_path, :class => 'icon icon-add' %>
-<%= link_to l(:field_summary), {:action => 'fields'}, :class => 'icon icon-summary' %>
+<%= link_to l(:field_summary), fields_trackers_path, :class => 'icon icon-summary' %>
 </div>
 
 <h2><%=l(:label_tracker_plural)%></h2>
@@ -16,8 +16,16 @@
 <% for tracker in @trackers %>
   <tr class="<%= cycle("odd", "even") %>">
   <td><%= link_to h(tracker.name), edit_tracker_path(tracker) %></td>
-  <td align="center"><% unless tracker.workflow_rules.count > 0 %><span class="icon icon-warning"><%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), {:controller => 'workflows', :action => 'edit', :tracker_id => tracker} %>)</span><% end %></td>
-  <td align="center" style="width:15%;"><%= reorder_links('tracker', {:action => 'update', :id => tracker}, :put) %></td>
+  <td align="center">
+    <% unless tracker.workflow_rules.count > 0 %>
+      <span class="icon icon-warning">
+        <%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), workflows_edit_path(:tracker_id => tracker) %>)
+      </span>
+    <% end %>
+  </td>
+  <td align="center" style="width:15%;">
+    <%= reorder_links('tracker', {:action => 'update', :id => tracker}, :put) %>
+  </td>
   <td class="buttons">
     <%= delete_link tracker_path(tracker) %>
   </td>
diff -r 0a574315af3e -r 4f746d8966dd app/views/users/_memberships.html.erb
--- a/app/views/users/_memberships.html.erb
+++ b/app/views/users/_memberships.html.erb
@@ -1,5 +1,5 @@
 <% roles = Role.find_all_givable %>
-<% projects = Project.active.find(:all, :order => 'lft') %>
+<% projects = Project.active.all %>
 
 <div class="splitcontentleft">
 <% if @user.memberships.any? %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/users/index.html.erb
--- a/app/views/users/index.html.erb
+++ b/app/views/users/index.html.erb
@@ -4,7 +4,7 @@
 
 <h2><%=l(:label_user_plural)%></h2>
 
-<%= form_tag({}, :method => :get) do %>
+<%= form_tag(users_path, :method => :get) do %>
 <fieldset><legend><%= l(:label_filter_plural) %></legend>
 <label for='status'><%= l(:field_status) %>:</label>
 <%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;"  %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/users/new.html.erb
--- a/app/views/users/new.html.erb
+++ b/app/views/users/new.html.erb
@@ -10,3 +10,21 @@
     <%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
   </p>
 <% end %>
+
+<% if @auth_sources.present? && @auth_sources.any?(&:searchable?) %>
+  <%= javascript_tag do %>
+    observeAutocompleteField('user_login', '<%= escape_javascript autocomplete_for_new_user_auth_sources_path %>', {
+      select: function(event, ui) {
+        $('input#user_firstname').val(ui.item.firstname);
+        $('input#user_lastname').val(ui.item.lastname);
+        $('input#user_mail').val(ui.item.mail);
+        $('select#user_auth_source_id option').each(function(){
+          if ($(this).attr('value') == ui.item.auth_source_id) {
+            $(this).attr('selected', true);
+            $('select#user_auth_source_id').trigger('change');
+          }
+        });
+      }
+    });
+  <% end %>
+<% end %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/users/show.api.rsb
--- a/app/views/users/show.api.rsb
+++ b/app/views/users/show.api.rsb
@@ -1,11 +1,12 @@
 api.user do
   api.id         @user.id
-  api.login      @user.login if User.current.admin?
+  api.login      @user.login if User.current.admin? || (User.current == @user)
   api.firstname  @user.firstname
   api.lastname   @user.lastname
   api.mail       @user.mail if User.current.admin? || !@user.pref.hide_mail
   api.created_on @user.created_on
   api.last_login_on @user.last_login_on
+  api.api_key    @user.api_key if User.current.admin? || (User.current == @user)
 
   render_api_custom_values @user.visible_custom_field_values, api
 
diff -r 0a574315af3e -r 4f746d8966dd app/views/versions/_overview.html.erb
--- a/app/views/versions/_overview.html.erb
+++ b/app/views/versions/_overview.html.erb
@@ -16,7 +16,7 @@
 <% end %>
 
 <% if version.issues_count > 0 %>
-    <%= progress_bar([version.closed_pourcent, version.completed_pourcent], :width => '40em', :legend => ('%0.0f%' % version.completed_pourcent)) %>
+    <%= progress_bar([version.closed_percent, version.completed_percent], :width => '40em', :legend => ('%0.0f%' % version.completed_percent)) %>
     <p class="progress-info">
     	  <%= link_to(l(:label_x_issues, :count => version.issues_count), 
               project_issues_path(version.project, :status_id => '*', :fixed_version_id => version, :set_filter => 1)) %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/watchers/_new.html.erb
--- a/app/views/watchers/_new.html.erb
+++ b/app/views/watchers/_new.html.erb
@@ -2,8 +2,9 @@
 
 <%= form_tag({:controller => 'watchers',
               :action => (watched ? 'create' : 'append'),
-              :object_type => watched.class.name.underscore,
-              :object_id => watched},
+              :object_type => (watched && watched.class.name.underscore),
+              :object_id => watched,
+              :project_id => @project},
              :remote => true,
              :method => :post,
              :id => 'new-watcher-form') do %>
@@ -11,8 +12,9 @@
   <p><%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
   <%= javascript_tag "observeSearchfield('user_search', 'users_for_watcher', '#{ escape_javascript url_for(:controller => 'watchers',
                  :action => 'autocomplete_for_user',
-                 :object_type => watched.class.name.underscore,
-                 :object_id => watched) }')" %>
+                 :object_type => (watched && watched.class.name.underscore),
+                 :object_id => watched,
+                 :project_id => @project) }')" %>
 
   <div id="users_for_watcher">
     <%= principals_check_box_tags 'watcher[user_ids][]', (watched ? watched.addable_watcher_users : User.active.all(:limit => 100)) %>
diff -r 0a574315af3e -r 4f746d8966dd app/views/watchers/_set_watcher.js.erb
--- a/app/views/watchers/_set_watcher.js.erb
+++ b/app/views/watchers/_set_watcher.js.erb
@@ -1,2 +1,2 @@
 <% selector = ".#{watcher_css(watched)}" %>
-$("<%= selector %>").each(function(){$(this).html("<%= escape_javascript watcher_link(watched, user) %>")});
+$("<%= selector %>").each(function(){$(this).replaceWith("<%= escape_javascript watcher_link(watched, user) %>")});
diff -r 0a574315af3e -r 4f746d8966dd app/views/wiki/date_index.html.erb
--- a/app/views/wiki/date_index.html.erb
+++ b/app/views/wiki/date_index.html.erb
@@ -1,5 +1,5 @@
 <div class="contextual">
-<%= watcher_tag(@wiki, User.current) %>
+<%= watcher_link(@wiki, User.current) %>
 </div>
 
 <h2><%= l(:label_index_by_date) %></h2>
diff -r 0a574315af3e -r 4f746d8966dd app/views/wiki/index.html.erb
--- a/app/views/wiki/index.html.erb
+++ b/app/views/wiki/index.html.erb
@@ -1,5 +1,5 @@
 <div class="contextual">
-<%= watcher_tag(@wiki, User.current) %>
+<%= watcher_link(@wiki, User.current) %>
 </div>
 
 <h2><%= l(:label_index_by_title) %></h2>
diff -r 0a574315af3e -r 4f746d8966dd app/views/wiki/show.html.erb
--- a/app/views/wiki/show.html.erb
+++ b/app/views/wiki/show.html.erb
@@ -2,7 +2,7 @@
 <% if @editable %>
 <% if @content.current_version? %>
   <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %>
-  <%= watcher_tag(@page, User.current) %>
+  <%= watcher_link(@page, User.current) %>
   <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
   <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
   <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') %>
diff -r 0a574315af3e -r 4f746d8966dd config/configuration.yml.example
--- a/config/configuration.yml.example
+++ b/config/configuration.yml.example
@@ -133,6 +133,12 @@
   scm_bazaar_command:
   scm_darcs_command:
 
+  # Absolute path to the SCM commands errors (stderr) log file.
+  # The default is to log in the 'log' directory of your Redmine instance.
+  # Example:
+  # scm_stderr_log_file: /var/log/redmine_scm_stderr.log
+  scm_stderr_log_file:
+
   # Key used to encrypt sensitive data in the database (SCM and LDAP passwords).
   # If you don't want to enable data encryption, just leave it blank.
   # WARNING: losing/changing this key will make encrypted data unreadable.
@@ -188,6 +194,9 @@
   #
   rmagick_font_path:
 
+  # Maximum number of simultaneous AJAX uploads
+  #max_concurrent_ajax_uploads: 2
+
 # specific configuration options for production environment
 # that overrides the default ones
 production:
diff -r 0a574315af3e -r 4f746d8966dd config/database.yml.example
--- a/config/database.yml.example
+++ b/config/database.yml.example
@@ -1,9 +1,10 @@
-# Default setup is given for MySQL with ruby1.8. If you're running Redmine
-# with MySQL and ruby1.9, replace the adapter name with `mysql2`.
-# Examples for PostgreSQL and SQLite3 can be found at the end.
+# Default setup is given for MySQL with ruby1.9. If you're running Redmine
+# with MySQL and ruby1.8, replace the adapter name with `mysql`.
+# Examples for PostgreSQL, SQLite3 and SQL Server can be found at the end.
+# Line indentation must be 2 spaces (no tabs).
 
 production:
-  adapter: mysql
+  adapter: mysql2
   database: redmine
   host: localhost
   username: root
@@ -11,7 +12,7 @@
   encoding: utf8
 
 development:
-  adapter: mysql
+  adapter: mysql2
   database: redmine_development
   host: localhost
   username: root
@@ -22,20 +23,30 @@
 # re-generated from your development database when you run "rake".
 # Do not set this db to the same as development or production.
 test:
-  adapter: mysql
+  adapter: mysql2
   database: redmine_test
   host: localhost
   username: root
   password: ""
   encoding: utf8
 
-test_pgsql:
-  adapter: postgresql
-  database: redmine_test
-  host: localhost
-  username: postgres
-  password: "postgres"
+# PostgreSQL configuration example
+#production:
+#  adapter: postgresql
+#  database: redmine
+#  host: localhost
+#  username: postgres
+#  password: "postgres"
 
-test_sqlite3:
-  adapter: sqlite3
-  database: db/test.sqlite3
+# SQLite3 configuration example
+#production:
+#  adapter: sqlite3
+#  database: db/redmine.sqlite3
+
+# SQL Server configuration example
+#production:
+#  adapter: sqlserver
+#  database: redmine
+#  host: localhost
+#  username: jenkins
+#  password: jenkins
diff -r 0a574315af3e -r 4f746d8966dd config/locales/ar.yml
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -50,8 +50,8 @@
         one:   "Ø­ÙˆØ§Ù„ÙŠ Ø³Ø§Ø¹Ø©"
         other: "Ø³Ø§Ø¹Ø§Øª %{count}Ø­ÙˆØ§Ù„ÙŠ "
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "%{count} Ø³Ø§Ø¹Ø©"
+        other: "%{count} Ø³Ø§Ø¹Ø§Øª"
       x_days:
         one:   "ÙŠÙˆÙ…"
         other: "%{count} Ø£ÙŠØ§Ù…"
@@ -211,8 +211,6 @@
   mail_subject_wiki_content_updated: "'%{id}' ØªÙ… ØªØ­Ø¯ÙŠØ« ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ"
   mail_body_wiki_content_updated: "The '%{id}'ØªÙ… ØªØ­Ø¯ÙŠØ« ØµÙØ­Ø© ÙˆÙŠÙƒÙŠ Ù…Ù† Ù‚Ø¨Ù„ %{author}."
 
-  gui_validation_error: Ø®Ø·Ø£
-  gui_validation_error_plural: "%{count}Ø£Ø®Ø·Ø§Ø¡"
 
   field_name: Ø§Ù„Ø§Ø³Ù…
   field_description: Ø§Ù„ÙˆØµÙ
@@ -413,7 +411,6 @@
   permission_edit_own_time_entries: ØªØ¹Ø¯ÙŠÙ„ Ø§Ù„Ø¯Ø®ÙˆÙ„Ø§Øª Ø§Ù„Ø´Ø®ØµÙŠØ©
   permission_manage_news: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ø§Ø®Ø¨Ø§Ø±
   permission_comment_news: Ø§Ø®Ø¨Ø§Ø± Ø§Ù„ØªØ¹Ù„ÙŠÙ‚Ø§Øª
-  permission_manage_documents: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª
   permission_view_documents: Ø¹Ø±Ø¶ Ø§Ù„Ù…Ø³ØªÙ†Ø¯Ø§Øª
   permission_manage_files: Ø§Ø¯Ø§Ø±Ø© Ø§Ù„Ù…Ù„ÙØ§Øª
   permission_view_files: Ø¹Ø±Ø¶ Ø§Ù„Ù…Ù„ÙØ§Øª
@@ -543,8 +540,6 @@
   label_text: Ù†Øµ Ø·ÙˆÙŠÙ„
   label_attribute: Ø³Ù…Ø©
   label_attribute_plural: Ø§Ù„Ø³Ù…Ø§Øª
-  label_download: "ØªØ­Ù…ÙŠÙ„"
-  label_download_plural: "ØªØ­Ù…ÙŠÙ„"
   label_no_data: Ù„Ø§ ØªÙˆØ¬Ø¯ Ø¨ÙŠØ§Ù†Ø§Øª Ù„Ù„Ø¹Ø±Ø¶
   label_change_status: ØªØºÙŠÙŠØ± Ø§Ù„ÙˆØ¶Ø¹
   label_history: Ø§Ù„ØªØ§Ø±ÙŠØ®
@@ -650,8 +645,6 @@
   label_repository: Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹
   label_repository_plural: Ø§Ù„Ù…Ø³ØªÙˆØ¯Ø¹Ø§Øª
   label_browse: ØªØµÙØ­
-  label_modification: "%{count} ØªØºÙŠØ±"
-  label_modification_plural: "%{count}ØªØºÙŠØ±Ø§Øª "
   label_branch: ÙØ±Ø¹
   label_tag: Ø±Ø¨Ø·
   label_revision: Ù…Ø±Ø§Ø¬Ø¹Ø©
@@ -1081,3 +1074,16 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ø§Ù„Ø¥Ø¬Ù…Ø§Ù„ÙŠ
diff -r 0a574315af3e -r 4f746d8966dd config/locales/az.yml
--- /dev/null
+++ b/config/locales/az.yml
@@ -0,0 +1,1186 @@
+#
+# Translated by Saadat Mutallimova
+# Data Processing Center of the Ministry of Communication and Information Technologies
+# 
+az:
+  direction: ltr
+  date:
+    formats:
+      default: "%d.%m.%Y"
+      short: "%d %b"
+      long: "%d %B %Y"
+
+    day_names: [bazar, bazar ertÉ™si, Ã§É™rÅŸÉ™nbÉ™ axÅŸamÄ±, Ã§É™rÅŸÉ™nbÉ™, cÃ¼mÉ™ axÅŸamÄ±, cÃ¼mÉ™, ÅŸÉ™nbÉ™]
+    standalone_day_names: [Bazar, Bazar ertÉ™si, Ã‡É™rÅŸÉ™nbÉ™ axÅŸamÄ±, Ã‡É™rÅŸÉ™nbÉ™, CÃ¼mÉ™ axÅŸamÄ±, CÃ¼mÉ™, ÅžÉ™nbÉ™]
+    abbr_day_names: [B, Be, Ã‡a, Ã‡, Ca, C, Åž]
+
+    month_names: [~, yanvar, fevral, mart, aprel, may, iyun, iyul, avqust, sentyabr, oktyabr, noyabr, dekabr]
+    # see russian gem for info on "standalone" day names
+    standalone_month_names: [~, Yanvar, Fevral, Mart, Aprel, May, Ä°yun, Ä°yul, Avqust, Sentyabr, Oktyabr, Noyabr, Dekabr]
+    abbr_month_names: [~, yan., fev., mart, apr., may, iyun, iyul, avq., sent., okt., noy., dek.]
+    standalone_abbr_month_names: [~, yan., fev., mart, apr., may, iyun, iyul, avq., sent., okt., noy., dek.]
+
+    order:
+      - :day
+      - :month
+      - :year
+
+  time:
+    formats:
+      default: "%a, %d %b %Y, %H:%M:%S %z"
+      time: "%H:%M"
+      short: "%d %b, %H:%M"
+      long: "%d %B %Y, %H:%M"
+
+    am: "sÉ™hÉ™r"
+    pm: "axÅŸam"
+
+  number:
+    format:
+      separator: ","
+      delimiter: " "
+      precision: 3
+
+    currency:
+      format:
+        format: "%n %u"
+        unit: "man."
+        separator: "."
+        delimiter: " "
+        precision: 2
+
+    percentage:
+      format:
+        delimiter: ""
+
+    precision:
+      format:
+        delimiter: ""
+
+    human:
+      format:
+        delimiter: ""
+        precision: 3
+      # Rails 2.2
+      # storage_units: [Ð±Ð°Ð¹Ñ‚, ÐšÐ‘, ÐœÐ‘, Ð“Ð‘, Ð¢Ð‘]
+
+      # Rails 2.3
+      storage_units:
+        # Storage units output formatting.
+        # %u is the storage unit, %n is the number (default: 2 MB)
+        format: "%n %u"
+        units:
+          byte:
+            one:   "bayt"
+            few:   "bayt"
+            many:  "bayt"
+            other: "bayt"
+          kb: "KB"
+          mb: "MB"
+          gb: "GB"
+          tb: "TB"
+
+  datetime:
+    distance_in_words:
+      half_a_minute: "bir dÉ™qiqÉ™dÉ™n az"
+      less_than_x_seconds:
+        one:   "%{count} saniyÉ™dÉ™n az"
+        few:   "%{count} saniyÉ™dÉ™n az"
+        many:  "%{count} saniyÉ™dÉ™n az"
+        other: "%{count} saniyÉ™dÉ™n az"
+      x_seconds:
+        one:   "%{count} saniyÉ™"
+        few:   "%{count} saniyÉ™"
+        many:  "%{count} saniyÉ™"
+        other: "%{count} saniyÉ™"
+      less_than_x_minutes:
+        one:   "%{count} dÉ™qiqÉ™dÉ™n az"
+        few:   "%{count} dÉ™qiqÉ™dÉ™n az"
+        many:  "%{count} dÉ™qiqÉ™dÉ™n az"
+        other: "%{count} dÉ™qiqÉ™dÉ™n az"
+      x_minutes:
+        one:   "%{count} dÉ™qiqÉ™"
+        few:   "%{count} dÉ™qiqÉ™"
+        many:  "%{count} dÉ™qiqÉ™"
+        other: "%{count} dÉ™qiqÉ™"
+      about_x_hours:
+        one:   "tÉ™xminÉ™n %{count} saat"
+        few:   "tÉ™xminÉ™n %{count} saat"
+        many:  "tÉ™xminÉ™n %{count} saat"
+        other: "tÉ™xminÉ™n %{count} saat"
+      x_hours:
+        one:   "1 saat"
+        other: "%{count} saat"
+      x_days:
+        one:   "%{count} gÃ¼n"
+        few:   "%{count} gÃ¼n"
+        many:  "%{count} gÃ¼n"
+        other: "%{count} gÃ¼n"
+      about_x_months:
+        one:   "tÉ™xminÉ™n %{count} ay"
+        few:   "tÉ™xminÉ™n %{count} ay"
+        many:  "tÉ™xminÉ™n %{count} ay"
+        other: "tÉ™xminÉ™n %{count} ay"
+      x_months:
+        one:   "%{count} ay"
+        few:   "%{count} ay"
+        many:  "%{count} ay"
+        other: "%{count} ay"
+      about_x_years:
+        one:   "tÉ™xminÉ™n %{count} il"
+        few:   "tÉ™xminÉ™n %{count} il"
+        many:  "tÉ™xminÉ™n %{count} il"
+        other: "tÉ™xminÉ™n %{count} il"
+      over_x_years:
+        one:   "%{count} ildÉ™n Ã§ox"
+        few:   "%{count} ildÉ™n Ã§ox"
+        many:  "%{count} ildÉ™n Ã§ox"
+        other: "%{count} ildÉ™n Ã§ox"
+      almost_x_years:
+        one:   "tÉ™xminÉ™n 1 il"
+        few:   "tÉ™xminÉ™n %{count} il"
+        many:  "tÉ™xminÉ™n %{count} il"
+        other: "tÉ™xminÉ™n %{count} il"
+    prompts:
+      year: "Ä°l"
+      month: "Ay"
+      day: "GÃ¼n"
+      hour: "Saat"
+      minute: "DÉ™qiqÉ™"
+      second: "SaniyÉ™"
+
+  activerecord:
+    errors:
+      template:
+        header:
+          one:   "%{model}: %{count} sÉ™hvÉ™ gÃ¶rÉ™ yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±"
+          few:   "%{model}: %{count} sÉ™hvlÉ™rÉ™ gÃ¶rÉ™ yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±"
+          many:  "%{model}: %{count} sÉ™hvlÉ™rÉ™ gÃ¶rÉ™ yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±"
+          other: "%{model}: %{count} sÉ™hvÉ™ gÃ¶rÉ™ yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±"
+
+        body: "ProblemlÉ™r aÅŸaÄŸÄ±dakÄ± sahÉ™lÉ™rdÉ™ yarandÄ±:"
+
+      messages:
+        inclusion: "nÉ™zÉ™rdÉ™ tutulmamÄ±ÅŸ tÉ™yinata malikdir"
+        exclusion: "ehtiyata gÃ¶tÃ¼rÃ¼lmÉ™miÅŸ tÉ™yinata malikdir"
+        invalid: "dÃ¼zgÃ¼n tÉ™yinat deyildir"
+        confirmation: "tÉ™sdiq ilÉ™ Ã¼st-Ã¼stÉ™ dÃ¼ÅŸmÃ¼r"
+        accepted: "tÉ™sdiq etmÉ™k lazÄ±mdÄ±r"
+        empty: "boÅŸ saxlanÄ±la bilmÉ™z"
+        blank: "boÅŸ saxlanÄ±la bilmÉ™z"
+        too_long:
+          one:   "Ã§ox bÃ¶yÃ¼k uzunluq (%{count} simvoldan Ã§ox ola bilmÉ™z)"
+          few:   "Ã§ox bÃ¶yÃ¼k uzunluq (%{count} simvoldan Ã§ox ola bilmÉ™z)"
+          many:  "Ã§ox bÃ¶yÃ¼k uzunluq (%{count} simvoldan Ã§ox ola bilmÉ™z)"
+          other: "Ã§ox bÃ¶yÃ¼k uzunluq (%{count} simvoldan Ã§ox ola bilmÉ™z)"
+        too_short:
+          one:   "uzunluq kifayÉ™t qÉ™dÉ™r deyildir (%{count} simvoldan az ola bilmÉ™z)"
+          few:   "uzunluq kifayÉ™t qÉ™dÉ™r deyildir (%{count} simvoldan az ola bilmÉ™z)"
+          many:  "uzunluq kifayÉ™t qÉ™dÉ™r deyildir (%{count} simvoldan az ola bilmÉ™z)"
+          other: "uzunluq kifayÉ™t qÉ™dÉ™r deyildir (%{count} simvoldan az ola bilmÉ™z)"
+        wrong_length:
+          one:   "dÃ¼zgÃ¼n olmayan uzunluq (tam %{count} simvol ola bilÉ™r)"
+          few:   "dÃ¼zgÃ¼n olmayan uzunluq (tam %{count} simvol ola bilÉ™r)"
+          many:  "dÃ¼zgÃ¼n olmayan uzunluq (tam %{count} simvol ola bilÉ™r)"
+          other: "dÃ¼zgÃ¼n olmayan uzunluq (tam %{count} simvol ola bilÉ™r)"
+        taken: "artÄ±q mÃ¶vcuddur"
+        not_a_number: "say kimi hesab edilmir"
+        greater_than: "%{count} Ã§ox tÉ™yinata malik ola bilÉ™r"
+        greater_than_or_equal_to: "%{count} Ã§ox vÉ™ ya ona bÉ™rabÉ™r tÉ™yinata malik ola bilÉ™r"
+        equal_to: "yalnÄ±z %{count} bÉ™rabÉ™r tÉ™yinata malik ola bilÉ™r"
+        less_than: "%{count} az tÉ™yinata malik ola bilÉ™r"
+        less_than_or_equal_to: "%{count} az vÉ™ ya ona bÉ™rabÉ™r tÉ™yinata malik ola bilÉ™r"
+        odd: "yalnÄ±z tÉ™k tÉ™yinata malik ola bilÉ™r"
+        even: "yalnÄ±z cÃ¼t tÉ™yinata malik ola bilÉ™r"
+        greater_than_start_date: "baÅŸlanÄŸÄ±c tarixindÉ™n sonra olmalÄ±dÄ±r"
+        not_same_project: "tÉ™kcÉ™ bir layihÉ™yÉ™ aid deyildir"
+        circular_dependency: "BelÉ™ É™laqÉ™ dÃ¶vri asÄ±lÄ±lÄ±ÄŸa gÉ™tirib Ã§Ä±xaracaq"
+        cant_link_an_issue_with_a_descendant: "TapÅŸÄ±rÄ±q Ã¶zÃ¼nÃ¼n alt tapÅŸÄ±rÄ±ÄŸÄ± ilÉ™ É™laqÉ™li ola bilmÉ™z"
+
+  support:
+    array:
+      # Rails 2.2
+      sentence_connector: "vÉ™"
+      skip_last_comma: true
+
+      # Rails 2.3
+      words_connector: ", "
+      two_words_connector: " vÉ™"
+      last_word_connector: " vÉ™ "
+
+  actionview_instancetag_blank_option: SeÃ§im edin
+
+  button_activate: AktivlÉ™ÅŸdirmÉ™k
+  button_add: ÆlavÉ™ etmÉ™k
+  button_annotate: MÃ¼É™lliflik
+  button_apply: TÉ™tbiq etmÉ™k
+  button_archive: ArxivlÉ™ÅŸdirmÉ™k
+  button_back: GeriyÉ™
+  button_cancel: Ä°mtina
+  button_change_password: Parolu dÉ™yiÅŸmÉ™k
+  button_change: DÉ™yiÅŸmÉ™k
+  button_check_all: HamÄ±nÄ± qeyd etmÉ™k
+  button_clear: TÉ™mizlÉ™mÉ™k
+  button_configure: ParametlÉ™r
+  button_copy: SÃ¼rÉ™tini Ã§Ä±xarmaq
+  button_create: Yaratmaq
+  button_create_and_continue: Yaratmaq vÉ™ davam etmÉ™k
+  button_delete: SilmÉ™k
+  button_download: YÃ¼klÉ™mÉ™k
+  button_edit: RedaktÉ™ etmÉ™k
+  button_edit_associated_wikipage: "ÆlaqÉ™li wiki-sÉ™hifÉ™ni redaktÉ™ etmÉ™k: %{page_title}"
+  button_list: SiyahÄ±
+  button_lock: Bloka salmaq
+  button_login: GiriÅŸ
+  button_log_time: SÉ™rf olunan vaxt
+  button_move: Yerini dÉ™yiÅŸmÉ™k
+  button_quote: Sitat gÉ™tirmÉ™k
+  button_rename: AdÄ±nÄ± dÉ™yiÅŸmÉ™k
+  button_reply: Cavablamaq
+  button_reset: SÄ±fÄ±rlamaq
+  button_rollback: Bu versiyaya qayÄ±tmaq
+  button_save: Yadda saxlamaq
+  button_sort: Ã‡eÅŸidlÉ™mÉ™k
+  button_submit: QÉ™bul etmÉ™k
+  button_test: Yoxlamaq
+  button_unarchive: ArxivdÉ™n Ã§Ä±xarmaq
+  button_uncheck_all: TÉ™mizlÉ™mÉ™k
+  button_unlock: Blokdan Ã§Ä±xarmaq
+  button_unwatch: Ä°zlÉ™mÉ™mÉ™k
+  button_update: YenilÉ™mÉ™k
+  button_view: Baxmaq
+  button_watch: Ä°zlÉ™mÉ™k
+
+  default_activity_design: LayihÉ™nin hazÄ±rlanmasÄ±
+  default_activity_development: HazÄ±rlanma prosesi
+  default_doc_category_tech: Texniki sÉ™nÉ™dlÉ™ÅŸmÉ™
+  default_doc_category_user: Ä°stifadÉ™Ã§i sÉ™nÉ™di
+  default_issue_status_in_progress: Ä°ÅŸlÉ™nmÉ™kdÉ™dir
+  default_issue_status_closed: BaÄŸlanÄ±b
+  default_issue_status_feedback: Æks É™laqÉ™
+  default_issue_status_new: Yeni
+  default_issue_status_rejected: RÉ™dd etmÉ™
+  default_issue_status_resolved: HÉ™ll edilib
+  default_priority_high: YÃ¼ksÉ™k
+  default_priority_immediate: TÉ™xirsiz
+  default_priority_low: AÅŸaÄŸÄ±
+  default_priority_normal: Normal
+  default_priority_urgent: TÉ™cili
+  default_role_developer: HazÄ±rlayan
+  default_role_manager: Menecer
+  default_role_reporter: Reportyor
+  default_tracker_bug: SÉ™hv
+  default_tracker_feature: TÉ™kmillÉ™ÅŸmÉ™
+  default_tracker_support: DÉ™stÉ™k
+
+  enumeration_activities: HÉ™rÉ™kÉ™tlÉ™r (vaxtÄ±n uÃ§otu)
+  enumeration_doc_categories: SÉ™nÉ™dlÉ™rin kateqoriyasÄ±
+  enumeration_issue_priorities: TapÅŸÄ±rÄ±qlarÄ±n prioriteti
+
+  error_can_not_remove_role: Bu rol istifadÉ™ edilir vÉ™ silinÉ™ bilmÉ™z.
+  error_can_not_delete_custom_field: SazlanmÄ±ÅŸ sahÉ™ni silmÉ™k mÃ¼mkÃ¼n deyildir
+  error_can_not_delete_tracker: Bu treker tapÅŸÄ±rÄ±qlardan ibarÉ™t olduÄŸu Ã¼Ã§Ã¼n silinÉ™ bilmÉ™z.
+  error_can_t_load_default_data: "Susmaya gÃ¶rÉ™ konfiqurasiya yÃ¼klÉ™nmÉ™miÅŸdir: %{value}"
+  error_issue_not_found_in_project: TapÅŸÄ±rÄ±q tapÄ±lmamÄ±ÅŸdÄ±r vÉ™ ya bu layihÉ™yÉ™ bÉ™rkidilmÉ™miÅŸdir
+  error_scm_annotate: "VerilÉ™nlÉ™r mÃ¶vcud deyildir vÉ™ ya imzalana bilmÉ™z."
+  error_scm_command_failed: "SaxlayÄ±cÄ±ya giriÅŸ imkanÄ± sÉ™hvi: %{value}"
+  error_scm_not_found: SaxlayÄ±cÄ±da yazÄ± vÉ™/ vÉ™ ya dÃ¼zÉ™liÅŸ yoxdur.
+  error_unable_to_connect: QoÅŸulmaq mÃ¼mkÃ¼n deyildir (%{value})
+  error_unable_delete_issue_status: TapÅŸÄ±rÄ±ÄŸÄ±n statusunu silmÉ™k mÃ¼mkÃ¼n deyildir
+
+  field_account: Ä°stifadÉ™Ã§i hesabÄ±
+  field_activity: FÉ™aliyyÉ™t
+  field_admin: Ä°nzibatÃ§Ä±
+  field_assignable: TapÅŸÄ±rÄ±q bu rola tÉ™yin edilÉ™ bilÉ™r
+  field_assigned_to: TÉ™yin edilib
+  field_attr_firstname: Ad
+  field_attr_lastname: Soyad
+  field_attr_login: Atribut Login
+  field_attr_mail: e-poÃ§t
+  field_author: MÃ¼É™llif
+  field_auth_source: Autentifikasiya rejimi
+  field_base_dn: BaseDN
+  field_category: Kateqoriya
+  field_column_names: SÃ¼tunlar
+  field_comments: ÅžÉ™rhlÉ™r
+  field_comments_sorting: ÅžÉ™rhlÉ™rin tÉ™sviri
+  field_content: Content
+  field_created_on: YaradÄ±lÄ±b
+  field_default_value: Susmaya gÃ¶rÉ™ tÉ™yinat
+  field_delay: TÉ™xirÉ™ salmaq
+  field_description: TÉ™svir
+  field_done_ratio: HazÄ±rlÄ±q
+  field_downloads: YÃ¼klÉ™mÉ™lÉ™r
+  field_due_date: YerinÉ™ yetirilmÉ™ tarixi
+  field_editable: RedaktÉ™ edilÉ™n
+  field_effective_date: Tarix
+  field_estimated_hours: VaxtÄ±n dÉ™yÉ™rlÉ™ndirilmÉ™si
+  field_field_format: Format
+  field_filename: Fayl
+  field_filesize: Ã–lÃ§Ã¼
+  field_firstname: Ad
+  field_fixed_version: Variant
+  field_hide_mail: E-poÃ§tumu gizlÉ™t
+  field_homepage: BaÅŸlanÄŸÄ±c sÉ™hifÉ™
+  field_host: Kompyuter
+  field_hours: saat
+  field_identifier: Unikal identifikator
+  field_identity_url: OpenID URL
+  field_is_closed: TapÅŸÄ±rÄ±q baÄŸlanÄ±b
+  field_is_default: Susmaya gÃ¶rÉ™ tapÅŸÄ±rÄ±q
+  field_is_filter: Filtr kimi istifadÉ™ edilir
+  field_is_for_all: BÃ¼tÃ¼n layihÉ™lÉ™r Ã¼Ã§Ã¼n
+  field_is_in_roadmap: Operativ planda É™ks olunan tapÅŸÄ±rÄ±qlar
+  field_is_public: ÃœmÃ¼maÃ§Ä±q
+  field_is_required: MÃ¼tlÉ™q
+  field_issue_to: ÆlaqÉ™li tapÅŸÄ±rÄ±qlar
+  field_issue: TapÅŸÄ±rÄ±q
+  field_language: Dil
+  field_last_login_on: Son qoÅŸulma
+  field_lastname: Soyad
+  field_login: Ä°stifadÉ™Ã§i
+  field_mail: e-poÃ§t
+  field_mail_notification: e-poÃ§t ilÉ™ bildiriÅŸ
+  field_max_length: maksimal uzunluq
+  field_min_length: minimal uzunluq
+  field_name: Ad
+  field_new_password: Yeni parol
+  field_notes: Qeyd
+  field_onthefly: Tez bir zamanda istifadÉ™Ã§inin yaradÄ±lmasÄ±
+  field_parent_title: Valideyn sÉ™hifÉ™
+  field_parent: Valideyn layihÉ™
+  field_parent_issue: Valideyn tapÅŸÄ±rÄ±q
+  field_password_confirmation: TÉ™sdiq 
+  field_password: Parol
+  field_port: Port
+  field_possible_values: MÃ¼mkÃ¼n olan tÉ™yinatlar
+  field_priority: Prioritet
+  field_project: LayihÉ™
+  field_redirect_existing_links: MÃ¶vcud olan istinadlarÄ± istiqamÉ™tlÉ™ndirmÉ™k
+  field_regexp: MÃ¼ntÉ™zÉ™m ifadÉ™
+  field_role: Rol
+  field_searchable: AxtarÄ±ÅŸ Ã¼Ã§Ã¼n aÃ§Ä±qdÄ±r
+  field_spent_on: Tarix
+  field_start_date: BaÅŸlanÄ±b
+  field_start_page: BaÅŸlanÄŸÄ±c sÉ™hifÉ™
+  field_status: Status
+  field_subject: MÃ¶vzu
+  field_subproject: AltlayihÉ™
+  field_summary: QÄ±sa tÉ™svir
+  field_text: MÉ™tn sahÉ™si
+  field_time_entries: SÉ™rf olunan zaman
+  field_time_zone: Saat qurÅŸaÄŸÄ±
+  field_title: BaÅŸlÄ±q
+  field_tracker: Treker
+  field_type: Tip
+  field_updated_on: YenilÉ™nib
+  field_url: URL
+  field_user: Ä°stifadÉ™Ã§i
+  field_value: TÉ™yinat
+  field_version: Variant
+  field_watcher: NÉ™zarÉ™tÃ§i
+
+  general_csv_decimal_separator: ','
+  general_csv_encoding: UTF-8
+  general_csv_separator: ';'
+  general_first_day_of_week: '1'
+  general_lang_name: 'Azerbaijanian (Azeri)'
+  general_pdf_encoding: UTF-8
+  general_text_no: 'xeyr'
+  general_text_No: 'Xeyr'
+  general_text_yes: 'bÉ™li'
+  general_text_Yes: 'BÉ™li'
+
+  label_activity: GÃ¶rÃ¼lÉ™n iÅŸlÉ™r
+  label_add_another_file: Bir fayl daha É™lavÉ™ etmÉ™k
+  label_added_time_by: "ÆlavÉ™ etdi %{author} %{age} É™vvÉ™l"
+  label_added: É™lavÉ™ edilib
+  label_add_note: Qeydi É™lavÉ™ etmÉ™k
+  label_administration: Ä°nzibatÃ§Ä±lÄ±q
+  label_age: YaÅŸ
+  label_ago: gÃ¼n É™vvÉ™l
+  label_all_time: hÉ™r zaman
+  label_all_words: BÃ¼tÃ¼n sÃ¶zlÉ™r
+  label_all: hamÄ±
+  label_and_its_subprojects: "%{value} vÉ™ bÃ¼tÃ¼n altlayihÉ™lÉ™r"
+  label_applied_status: TÉ™tbiq olunan status
+  label_ascending: Artmaya gÃ¶rÉ™
+  label_assigned_to_me_issues: MÉ™nim tapÅŸÄ±rÄ±qlarÄ±m
+  label_associated_revisions: ÆlaqÉ™li redaksiyalar
+  label_attachment: Fayl
+  label_attachment_delete: FaylÄ± silmÉ™k
+  label_attachment_new: Yeni fayl
+  label_attachment_plural: Fayllar
+  label_attribute: Atribut
+  label_attribute_plural: Atributlar
+  label_authentication: Autentifikasiya
+  label_auth_source: AutentifikasiyanÄ±n rejimi
+  label_auth_source_new: AutentifikasiyanÄ±n yeni rejimi
+  label_auth_source_plural: AutentifikasiyanÄ±n rejimlÉ™ri
+  label_blocked_by: bloklanÄ±r
+  label_blocks: bloklayÄ±r
+  label_board: Forum
+  label_board_new: Yeni forum
+  label_board_plural: Forumlar
+  label_boolean: MÉ™ntiqi
+  label_browse: BaxÄ±ÅŸ
+  label_bulk_edit_selected_issues: SeÃ§ilÉ™n bÃ¼tÃ¼n tapÅŸÄ±rÄ±qlarÄ± redaktÉ™ etmÉ™k
+  label_calendar: TÉ™qvim
+  label_calendar_filter: O cÃ¼mlÉ™dÉ™n
+  label_calendar_no_assigned: MÉ™nim deyil
+  label_change_plural: DÉ™yiÅŸikliklÉ™r
+  label_change_properties: XassÉ™lÉ™ri dÉ™yiÅŸmÉ™k
+  label_change_status: Statusu dÉ™yiÅŸmÉ™k
+  label_change_view_all: BÃ¼tÃ¼n dÉ™yiÅŸikliklÉ™rÉ™ baxmaq
+  label_changes_details: BÃ¼tÃ¼n dÉ™yiÅŸikliklÉ™rÉ™ gÃ¶rÉ™ tÉ™fsilatlar
+  label_changeset_plural: DÉ™yiÅŸikliklÉ™r
+  label_chronological_order: Xronoloji ardÄ±cÄ±llÄ±q ilÉ™
+  label_closed_issues: BaÄŸlÄ±dÄ±r
+  label_closed_issues_plural: baÄŸlÄ±dÄ±r
+  label_closed_issues_plural2: baÄŸlÄ±dÄ±r
+  label_closed_issues_plural5: baÄŸlÄ±dÄ±r
+  label_comment: ÅŸÉ™rhlÉ™r
+  label_comment_add: ÅžÉ™rhlÉ™ri qeyd etmÉ™k
+  label_comment_added: ÆlavÉ™ olunmuÅŸ ÅŸÉ™rhlÉ™r
+  label_comment_delete: ÅžÉ™rhi silmÉ™k
+  label_comment_plural: ÅžÉ™rhlÉ™r
+  label_comment_plural2: ÅžÉ™rhlÉ™r
+  label_comment_plural5: ÅŸÉ™rhlÉ™rin
+  label_commits_per_author: Ä°stifadÉ™Ã§i Ã¼zÉ™rindÉ™ dÉ™yiÅŸikliklÉ™r
+  label_commits_per_month: Ay Ã¼zÉ™rindÉ™ dÉ™yiÅŸikliklÉ™r
+  label_confirmation: TÉ™sdiq 
+  label_contains: tÉ™rkibi
+  label_copied: surÉ™ti kÃ¶Ã§Ã¼rÃ¼lÃ¼b
+  label_copy_workflow_from: gÃ¶rÃ¼lÉ™n iÅŸlÉ™rin ardÄ±cÄ±llÄ±ÄŸÄ±nÄ±n surÉ™tini kÃ¶Ã§Ã¼rmÉ™k
+  label_current_status: Cari status
+  label_current_version: Cari variant
+  label_custom_field: Sazlanan sahÉ™
+  label_custom_field_new: Yeni sazlanan sahÉ™
+  label_custom_field_plural: Sazlanan sahÉ™lÉ™r
+  label_date_from: Ð¡
+  label_date_from_to: Ð¡ %{start} Ð¿Ð¾ %{end}
+  label_date_range: vaxt intervalÄ±
+  label_date_to: Ã¼zrÉ™
+  label_date: Tarix
+  label_day_plural: gÃ¼n
+  label_default: Susmaya gÃ¶rÉ™
+  label_default_columns: Susmaya gÃ¶rÉ™ sÃ¼tunlar
+  label_deleted: silinib
+  label_descending: Azalmaya gÃ¶rÉ™
+  label_details: TÉ™fsilatlar
+  label_diff_inline: mÉ™tndÉ™
+  label_diff_side_by_side: YanaÅŸÄ±
+  label_disabled: sÃ¶ndÃ¼rÃ¼lÃ¼b
+  label_display: TÉ™svir
+  label_display_per_page: "SÉ™hifÉ™yÉ™: %{value}"
+  label_document: SÉ™nÉ™d
+  label_document_added: SÉ™nÉ™d É™lavÉ™ edilib
+  label_document_new: Yeni sÉ™nÉ™d
+  label_document_plural: SÉ™nÉ™dlÉ™r
+  label_downloads_abbr: YÃ¼klÉ™mÉ™lÉ™r
+  label_duplicated_by: Ã§oxaldÄ±lÄ±r
+  label_duplicates: Ã§oxaldÄ±r
+  label_end_to_end: sondan sona doÄŸru
+  label_end_to_start: sondan É™vvÉ™lÉ™ doÄŸru
+  label_enumeration_new: Yeni qiymÉ™t
+  label_enumerations: QiymÉ™tlÉ™rin siyahÄ±sÄ±
+  label_environment: MÃ¼hit
+  label_equals: sayÄ±lÄ±r
+  label_example: NÃ¼munÉ™
+  label_export_to: ixrac etmÉ™k 
+  label_feed_plural: RSS
+  label_feeds_access_key_created_on: "RSS-É™ giriÅŸ aÃ§arÄ± %{value} É™vvÉ™l yaradÄ±lÄ±b"
+  label_f_hour: "%{value} saat"
+  label_f_hour_plural: "%{value} saat"
+  label_file_added: Fayl É™lavÉ™ edilib
+  label_file_plural: Fayllar
+  label_filter_add: Filtr É™lavÉ™ etmÉ™k
+  label_filter_plural: FiltrlÉ™r
+  label_float: HÉ™qiqi É™dÉ™d
+  label_follows: ÆvvÉ™lki
+  label_gantt: Qant diaqrammasÄ±
+  label_general: Ãœmumi
+  label_generate_key: AÃ§arÄ± generasiya etmÉ™k
+  label_greater_or_equal: ">="
+  label_help: KÃ¶mÉ™k
+  label_history: TarixÃ§É™
+  label_home: Ana sÉ™hifÉ™
+  label_incoming_emails: MÉ™lumatlarÄ±n qÉ™bulu
+  label_index_by_date: SÉ™hifÉ™lÉ™rin tarixÃ§É™si
+  label_index_by_title: BaÅŸlÄ±q
+  label_information_plural: Ä°nformasiya
+  label_information: Ä°nformasiya
+  label_in_less_than: az
+  label_in_more_than: Ã§ox
+  label_integer: Tam
+  label_internal: Daxili
+  label_in: da (dÉ™)
+  label_issue: TapÅŸÄ±rÄ±q
+  label_issue_added: TapÅŸÄ±rÄ±q É™lavÉ™ edilib
+  label_issue_category_new: Yeni kateqoriya
+  label_issue_category_plural: TapÅŸÄ±rÄ±ÄŸÄ±n kateqoriyasÄ±
+  label_issue_category: TapÅŸÄ±rÄ±ÄŸÄ±n kateqoriyasÄ±
+  label_issue_new: Yeni tapÅŸÄ±rÄ±q
+  label_issue_plural: TapÅŸÄ±rÄ±qlar
+  label_issues_by: "%{value} Ã¼zrÉ™ Ã§eÅŸidlÉ™mÉ™k"
+  label_issue_status_new: Yeni status
+  label_issue_status_plural: TapÅŸÄ±rÄ±qlarÄ±n statusu
+  label_issue_status: TapÅŸÄ±rÄ±ÄŸÄ±n statusu
+  label_issue_tracking: TapÅŸÄ±rÄ±qlar
+  label_issue_updated: TapÅŸÄ±rÄ±q yenilÉ™nib
+  label_issue_view_all: BÃ¼tÃ¼n tapÅŸÄ±rÄ±qlara baxmaq
+  label_issue_watchers: NÉ™zarÉ™tÃ§ilÉ™r
+  label_jump_to_a_project: ... layihÉ™yÉ™ keÃ§id
+  label_language_based: Dilin É™sasÄ±nda
+  label_last_changes: "%{count} az dÉ™yiÅŸiklik"
+  label_last_login: Sonuncu qoÅŸulma
+  label_last_month: sonuncu ay
+  label_last_n_days: "son %{count} gÃ¼n"
+  label_last_week: sonuncu hÉ™ftÉ™
+  label_latest_revision: Sonuncu redaksiya
+  label_latest_revision_plural: Sonuncu redaksiyalar
+  label_ldap_authentication: LDAP vasitÉ™silÉ™ avtorizasiya
+  label_less_or_equal: <=
+  label_less_than_ago: gÃ¼ndÉ™n az
+  label_list: SiyahÄ±
+  label_loading: YÃ¼klÉ™mÉ™...
+  label_logged_as: Daxil olmusunuz
+  label_login: Daxil olmaq
+  label_login_with_open_id_option: vÉ™ ya OpenID vasitÉ™silÉ™ daxil olmaq
+  label_logout: Ã‡Ä±xÄ±ÅŸ
+  label_max_size: Maksimal Ã¶lÃ§Ã¼
+  label_member_new: Yeni iÅŸtirakÃ§Ä±
+  label_member: Ä°ÅŸtirakÃ§Ä±
+  label_member_plural: Ä°ÅŸtirakÃ§Ä±lar
+  label_message_last: Sonuncu mÉ™lumat
+  label_message_new: Yeni mÉ™lumat
+  label_message_plural: MÉ™lumatlar
+  label_message_posted: MÉ™lumat É™lavÉ™ olunub
+  label_me: mÉ™nÉ™
+  label_min_max_length: Minimal - maksimal uzunluq
+  label_modified: dÉ™yiÅŸilib
+  label_module_plural: Modullar
+  label_months_from: ay
+  label_month: Ay
+  label_more_than_ago: gÃ¼ndÉ™n É™vvÉ™l
+  label_more: Ã‡ox
+  label_my_account: MÉ™nim hesabÄ±m
+  label_my_page: MÉ™nim sÉ™hifÉ™m
+  label_my_page_block: MÉ™nim sÉ™hifÉ™min bloku
+  label_my_projects: MÉ™nim layihÉ™lÉ™rim
+  label_new: Yeni
+  label_new_statuses_allowed: Ä°cazÉ™ verilÉ™n yeni statuslar
+  label_news_added: XÉ™bÉ™r É™lavÉ™ edilib
+  label_news_latest: Son xÉ™bÉ™rlÉ™r
+  label_news_new: XÉ™bÉ™r É™lavÉ™ etmÉ™k
+  label_news_plural: XÉ™bÉ™rlÉ™r
+  label_news_view_all: BÃ¼tÃ¼n xÉ™bÉ™rlÉ™rÉ™ baxmaq
+  label_news: XÉ™bÉ™rlÉ™r
+  label_next: NÃ¶vbÉ™ti
+  label_nobody: heÃ§ kim
+  label_no_change_option: (DÉ™yiÅŸiklik yoxdur)
+  label_no_data: TÉ™svir Ã¼Ã§Ã¼n verilÉ™nlÉ™r yoxdur
+  label_none: yoxdur
+  label_not_contains: mÃ¶vcud deyil
+  label_not_equals: sayÄ±lmÄ±r
+  label_open_issues: aÃ§Ä±qdÄ±r
+  label_open_issues_plural: aÃ§Ä±qdÄ±r
+  label_open_issues_plural2: aÃ§Ä±qdÄ±r
+  label_open_issues_plural5: aÃ§Ä±qdÄ±r
+  label_optional_description: TÉ™svir (vacib deyil)
+  label_options: Opsiyalar
+  label_overall_activity: GÃ¶rÃ¼lÉ™n iÅŸlÉ™rin toplu hesabatÄ±
+  label_overview: BaxÄ±ÅŸ
+  label_password_lost: Parolun bÉ™rpasÄ±
+  label_permissions_report: GiriÅŸ hÃ¼quqlarÄ± Ã¼zrÉ™ hesabat 
+  label_permissions: GiriÅŸ hÃ¼quqlarÄ±
+  label_per_page: SÉ™hifÉ™yÉ™
+  label_personalize_page: bu sÉ™hifÉ™ni fÉ™rdilÉ™ÅŸdirmÉ™k
+  label_planning: PlanlaÅŸdÄ±rma
+  label_please_login: XahiÅŸ edirik, daxil olun.
+  label_plugins: Modullar
+  label_precedes: nÃ¶vbÉ™ti
+  label_preferences: ÃœstÃ¼nlÃ¼k
+  label_preview: Ä°lkin baxÄ±ÅŸ
+  label_previous: ÆvvÉ™lki
+  label_profile: Profil
+  label_project: LayihÉ™
+  label_project_all: BÃ¼tÃ¼n layihÉ™lÉ™r
+  label_project_copy_notifications: LayihÉ™nin surÉ™tinin Ã§Ä±xarÄ±lmasÄ± zamanÄ± elektron poÃ§t ilÉ™ bildiriÅŸ gÃ¶ndÉ™rmÉ™k
+  label_project_latest: Son layihÉ™lÉ™r
+  label_project_new: Yeni layihÉ™
+  label_project_plural: LayihÉ™lÉ™r
+  label_project_plural2: layihÉ™ni
+  label_project_plural5: layihÉ™lÉ™ri
+  label_public_projects: Ãœmumi layihÉ™lÉ™r
+  label_query: Yadda saxlanÄ±lmÄ±ÅŸ sorÄŸu
+  label_query_new: Yeni sorÄŸu
+  label_query_plural: Yadda saxlanÄ±lmÄ±ÅŸ sorÄŸular
+  label_read: Oxu...
+  label_register: Qeydiyyat
+  label_registered_on: Qeydiyyatdan keÃ§ib
+  label_registration_activation_by_email: e-poÃ§t Ã¼zrÉ™ hesabÄ±mÄ±n aktivlÉ™ÅŸdirilmÉ™si
+  label_registration_automatic_activation: uÃ§ot qeydlÉ™rinin avtomatik aktivlÉ™ÅŸdirilmÉ™si
+  label_registration_manual_activation: uÃ§ot qeydlÉ™rini É™l ilÉ™ aktivlÉ™ÅŸdirmÉ™k
+  label_related_issues: ÆlaqÉ™li tapÅŸÄ±rÄ±qlar
+  label_relates_to: É™laqÉ™lidir
+  label_relation_delete: ÆlaqÉ™ni silmÉ™k
+  label_relation_new: Yeni mÃ¼nasibÉ™t
+  label_renamed: adÄ±nÄ± dÉ™yiÅŸmÉ™k
+  label_reply_plural: Cavablar
+  label_report: Hesabat
+  label_report_plural: Hesabatlar
+  label_reported_issues: YaradÄ±lan tapÅŸÄ±rÄ±qlar
+  label_repository: SaxlayÄ±cÄ±
+  label_repository_plural: SaxlayÄ±cÄ±
+  label_result_plural: NÉ™ticÉ™lÉ™r
+  label_reverse_chronological_order: Æks ardÄ±cÄ±llÄ±qda
+  label_revision: Redaksiya
+  label_revision_plural: Redaksiyalar
+  label_roadmap: Operativ plan
+  label_roadmap_due_in: "%{value} mÃ¼ddÉ™tindÉ™"
+  label_roadmap_no_issues: bu versiya Ã¼Ã§Ã¼n tapÅŸÄ±rÄ±q yoxdur
+  label_roadmap_overdue: "gecikmÉ™ %{value}"
+  label_role: Rol
+  label_role_and_permissions: Rollar vÉ™ giriÅŸ hÃ¼quqlarÄ±
+  label_role_new: Yeni rol
+  label_role_plural: Rollar
+  label_scm: SaxlayÄ±cÄ±nÄ±n tipi
+  label_search: AxtarÄ±ÅŸ
+  label_search_titles_only: Ancaq adlarda axtarmaq
+  label_send_information: Ä°stifadÉ™Ã§iyÉ™ uÃ§ot qeydlÉ™ri Ã¼zrÉ™ informasiyanÄ± gÃ¶ndÉ™rmÉ™k
+  label_send_test_email: Yoxlama Ã¼Ã§Ã¼n email gÃ¶ndÉ™rmÉ™k
+  label_settings: Sazlamalar
+  label_show_completed_versions: BitmiÅŸ variantlarÄ± gÃ¶stÉ™rmÉ™k
+  label_sort: Ã‡eÅŸidlÉ™mÉ™k
+  label_sort_by: "%{value} Ã¼zrÉ™ Ã§eÅŸidlÉ™mÉ™k"
+  label_sort_higher: YuxarÄ±
+  label_sort_highest: ÆvvÉ™lÉ™ qayÄ±t
+  label_sort_lower: AÅŸaÄŸÄ±
+  label_sort_lowest: Sona qayÄ±t
+  label_spent_time: SÉ™rf olunan vaxt
+  label_start_to_end: É™vvÉ™ldÉ™n axÄ±ra doÄŸru
+  label_start_to_start: É™vvÉ™ldÉ™n É™vvÉ™lÉ™ doÄŸru
+  label_statistics: Statistika
+  label_stay_logged_in: SistemdÉ™ qalmaq
+  label_string: MÉ™tn
+  label_subproject_plural: AltlayihÉ™lÉ™r
+  label_subtask_plural: Alt tapÅŸÄ±rÄ±qlar
+  label_text: Uzun mÉ™tn 
+  label_theme: MÃ¶vzu
+  label_this_month: bu ay
+  label_this_week: bu hÉ™ftÉ™
+  label_this_year: bu il
+  label_time_tracking: VaxtÄ±n uÃ§otu
+  label_timelog_today: Bu gÃ¼nÉ™ sÉ™rf olunan vaxt
+  label_today: bu gÃ¼n
+  label_topic_plural: MÃ¶vzular
+  label_total: CÉ™mi
+  label_tracker: Treker
+  label_tracker_new: Yeni treker
+  label_tracker_plural: TrekerlÉ™r
+  label_updated_time: "%{value} É™vvÉ™l yenilÉ™nib"
+  label_updated_time_by: "%{author} %{age} É™vvÉ™l yenilÉ™nib"
+  label_used_by: Ä°stifadÉ™ olunur
+  label_user: Ä°stifasdÉ™Ã§i
+  label_user_activity: "Ä°stifadÉ™Ã§inin gÃ¶rdÃ¼yÃ¼ iÅŸlÉ™r %{value}"
+  label_user_mail_no_self_notified: "TÉ™rÉ™fimdÉ™n edilÉ™n dÉ™yiÅŸikliklÉ™r haqqÄ±nda mÉ™ni xÉ™bÉ™rdar etmÉ™mÉ™k"
+  label_user_mail_option_all: "MÉ™nim layihÉ™lÉ™rimdÉ™ki bÃ¼tÃ¼n hadisÉ™lÉ™r haqqÄ±nda"
+  label_user_mail_option_selected: "YalnÄ±z seÃ§ilÉ™n layihÉ™dÉ™ki bÃ¼tÃ¼n hadisÉ™lÉ™r haqqÄ±nda..."
+  label_user_mail_option_only_owner: YalnÄ±z sahibi olduÄŸum obyektlÉ™r Ã¼Ã§Ã¼n
+  label_user_mail_option_only_my_events: YalnÄ±z izlÉ™diyim vÉ™ ya iÅŸtirak etdiyim obyektlÉ™r Ã¼Ã§Ã¼n
+  label_user_mail_option_only_assigned: YalnÄ±z mÉ™nÉ™ tÉ™yin edilÉ™n obyektlÉ™r Ã¼Ã§Ã¼n
+  label_user_new: Yeni istifadÉ™Ã§i
+  label_user_plural: Ä°stifadÉ™Ã§ilÉ™r
+  label_version: Variant
+  label_version_new: Yeni variant
+  label_version_plural: Variantlar
+  label_view_diff: FÉ™rqlÉ™rÉ™ baxmaq
+  label_view_revisions: Redaksiyalara baxmaq
+  label_watched_issues: TapÅŸÄ±rÄ±ÄŸÄ±n izlÉ™nilmÉ™si
+  label_week: HÉ™ftÉ™
+  label_wiki: Wiki
+  label_wiki_edit: Wiki-nin redaktÉ™si
+  label_wiki_edit_plural: Wiki
+  label_wiki_page: Wiki sÉ™hifÉ™si
+  label_wiki_page_plural: Wiki sÉ™hifÉ™lÉ™ri
+  label_workflow: GÃ¶rÃ¼lÉ™n iÅŸlÉ™rin ardÄ±cÄ±llÄ±ÄŸÄ±
+  label_x_closed_issues_abbr:
+    zero:  "0 baÄŸlÄ±dÄ±r"
+    one:   "1 baÄŸlanÄ±b"
+    few:   "%{count} baÄŸlÄ±dÄ±r"
+    many:  "%{count} baÄŸlÄ±dÄ±r"
+    other: "%{count} baÄŸlÄ±dÄ±r"
+  label_x_comments:
+    zero:  "ÅŸÉ™rh yoxdur"
+    one:   "1 ÅŸÉ™rh"
+    few:   "%{count} ÅŸÉ™rhlÉ™r"
+    many:  "%{count} ÅŸÉ™rh"
+    other: "%{count} ÅŸÉ™rh"
+  label_x_open_issues_abbr:
+    zero:  "0 aÃ§Ä±qdÄ±r"
+    one:   "1 aÃ§Ä±q"
+    few:   "%{count} aÃ§Ä±qdÄ±r"
+    many:  "%{count} aÃ§Ä±qdÄ±r"
+    other: "%{count} aÃ§Ä±qdÄ±r"
+  label_x_open_issues_abbr_on_total:
+    zero:  "0 aÃ§Ä±qdÄ±r / %{total}"
+    one:   "1 aÃ§Ä±qdÄ±r / %{total}"
+    few:   "%{count} aÃ§Ä±qdÄ±r / %{total}"
+    many:  "%{count} aÃ§Ä±qdÄ±r / %{total}"
+    other: "%{count} aÃ§Ä±qdÄ±r / %{total}"
+  label_x_projects:
+    zero:  "layihÉ™lÉ™r yoxdur"
+    one:   "1 layihÉ™"
+    few:   "%{count} layihÉ™"
+    many:  "%{count} layihÉ™"
+    other: "%{count} layihÉ™"
+  label_year: Ä°l
+  label_yesterday: dÃ¼nÉ™n
+
+  mail_body_account_activation_request: "Yeni istifadÉ™Ã§i qeydiyyatdan keÃ§ib (%{value}). UÃ§ot qeydi Sizin tÉ™sdiqinizi gÃ¶zlÉ™yir:"
+  mail_body_account_information: Sizin uÃ§ot qeydiniz haqqÄ±nda informasiya
+  mail_body_account_information_external: "Siz Ã¶zÃ¼nÃ¼zÃ¼n %{value} uÃ§ot qeydinizi giriÅŸ Ã¼Ã§Ã¼n istifadÉ™ edÉ™ bilÉ™rsiniz."
+  mail_body_lost_password: 'Parolun dÉ™yiÅŸdirilmÉ™si Ã¼Ã§Ã¼n aÅŸaÄŸÄ±dakÄ± linkÉ™ keÃ§in:'
+  mail_body_register: 'UÃ§ot qeydinin aktivlÉ™ÅŸdirilmÉ™si Ã¼Ã§Ã¼n aÅŸaÄŸÄ±dakÄ± linkÉ™ keÃ§in:'
+  mail_body_reminder: "nÃ¶vbÉ™ti %{days} gÃ¼n Ã¼Ã§Ã¼n SizÉ™ tÉ™yin olunan %{count}:"
+  mail_subject_account_activation_request: "SistemdÉ™ istifadÉ™Ã§inin aktivlÉ™ÅŸdirilmÉ™si Ã¼Ã§Ã¼n sorÄŸu %{value}"
+  mail_subject_lost_password: "Sizin %{value} parolunuz"
+  mail_subject_register: "UÃ§ot qeydinin aktivlÉ™ÅŸdirilmÉ™si %{value}"
+  mail_subject_reminder: "yaxÄ±n %{days} gÃ¼n Ã¼Ã§Ã¼n SizÉ™ tÉ™yin olunan %{count}"
+
+  notice_account_activated: Sizin uÃ§ot qeydiniz aktivlÉ™ÅŸdirilib. SistemÉ™ daxil ola bilÉ™rsiniz.
+  notice_account_invalid_creditentials: Ä°stifadÉ™Ã§i adÄ± vÉ™ ya parolu dÃ¼zgÃ¼n deyildir
+  notice_account_lost_email_sent: SizÉ™ yeni parolun seÃ§imi ilÉ™ baÄŸlÄ± tÉ™limatÄ± É™ks etdirÉ™n mÉ™ktub gÃ¶ndÉ™rilmiÅŸdir.
+  notice_account_password_updated: Parol mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yenilÉ™ndi.
+  notice_account_pending: "Sizin uÃ§ot qeydiniz yaradÄ±ldÄ± vÉ™ inzibatÃ§Ä±nÄ±n tÉ™sdiqini gÃ¶zlÉ™yir."
+  notice_account_register_done: UÃ§ot qeydi mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yaradÄ±ldÄ±. Sizin uÃ§ot qeydinizin aktivlÉ™ÅŸdirilmÉ™si Ã¼Ã§Ã¼n elektron poÃ§tunuza gÃ¶ndÉ™rilÉ™n linkÉ™ keÃ§in.
+  notice_account_unknown_email: NamÉ™lum istifadÉ™Ã§i.
+  notice_account_updated: UÃ§ot qeydi mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yenilÉ™ndi.
+  notice_account_wrong_password: Parol dÃ¼zgÃ¼n deyildir
+  notice_can_t_change_password: Bu uÃ§ot qeydi Ã¼Ã§Ã¼n xarici autentifikasiya mÉ™nbÉ™yi istifadÉ™ olunur. Parolu dÉ™yiÅŸmÉ™k mÃ¼mkÃ¼n deyildir.
+  notice_default_data_loaded: Susmaya gÃ¶rÉ™ konfiqurasiya yÃ¼klÉ™nilmiÅŸdir.
+  notice_email_error: "MÉ™ktubun gÃ¶ndÉ™rilmÉ™si zamanÄ± sÉ™hv baÅŸ vermiÅŸdi (%{value})"
+  notice_email_sent: "MÉ™ktub gÃ¶ndÉ™rilib %{value}"
+  notice_failed_to_save_issues: "SeÃ§ilÉ™n %{total} iÃ§É™risindÉ™n %{count} bÉ™ndlÉ™ri saxlamaq mÃ¼mkÃ¼n olmadÄ±: %{ids}."
+  notice_failed_to_save_members: "Ä°ÅŸtirakÃ§Ä±nÄ± (larÄ±) yadda saxlamaq mÃ¼mkÃ¼n olmadÄ±: %{errors}."
+  notice_feeds_access_key_reseted: Sizin RSS giriÅŸ aÃ§arÄ±nÄ±z sÄ±fÄ±rlanmÄ±ÅŸdÄ±r.
+  notice_file_not_found: Daxil olmaÄŸa Ã§alÄ±ÅŸdÄ±ÄŸÄ±nÄ±z sÉ™hifÉ™ mÃ¶vcud deyildir vÉ™ ya silinib.
+  notice_locking_conflict: Ä°nformasiya digÉ™r istifadÉ™Ã§i tÉ™rÉ™findÉ™n yenilÉ™nib.
+  notice_no_issue_selected: "HeÃ§ bir tapÅŸÄ±rÄ±q seÃ§ilmÉ™yib! XahiÅŸ edirik, redaktÉ™ etmÉ™k istÉ™diyiniz tapÅŸÄ±rÄ±ÄŸÄ± qeyd edin."
+  notice_not_authorized: Sizin bu sÉ™hifÉ™yÉ™ daxil olmaq hÃ¼ququnuz yoxdur.
+  notice_successful_connection: QoÅŸulma mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yerinÉ™ yetirilib.
+  notice_successful_create: Yaratma mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yerinÉ™ yetirildi.
+  notice_successful_delete: SilinmÉ™ mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yerinÉ™ yetirildi.
+  notice_successful_update: YenilÉ™mÉ™ mÃ¼vÉ™ffÉ™qiyyÉ™tlÉ™ yerinÉ™ yetirildi.
+  notice_unable_delete_version: VariantÄ± silmÉ™k mÃ¼mkÃ¼n olmadÄ±.
+
+  permission_add_issues: TapÅŸÄ±rÄ±qlarÄ±n É™lavÉ™ edilmÉ™si
+  permission_add_issue_notes: QeydlÉ™rin É™lavÉ™ edilmÉ™si
+  permission_add_issue_watchers: NÉ™zarÉ™tÃ§ilÉ™rin É™lavÉ™ edilmÉ™si
+  permission_add_messages: MÉ™lumatlarÄ±n gÃ¶ndÉ™rilmÉ™si
+  permission_browse_repository: SaxlayÄ±cÄ±ya baxÄ±ÅŸ
+  permission_comment_news: XÉ™bÉ™rlÉ™rÉ™ ÅŸÉ™rh
+  permission_commit_access: SaxlayÄ±cÄ±da fayllarÄ±n dÉ™yiÅŸdirilmÉ™si
+  permission_delete_issues: TapÅŸÄ±rÄ±qlarÄ±n silinmÉ™si
+  permission_delete_messages: MÉ™lumatlarÄ±n silinmÉ™si
+  permission_delete_own_messages: ÅžÉ™xsi mÉ™lumatlarÄ±n silinmÉ™si
+  permission_delete_wiki_pages: Wiki-sÉ™hifÉ™lÉ™rin silinmÉ™si
+  permission_delete_wiki_pages_attachments: BÉ™rkidilÉ™n fayllarÄ±n silinmÉ™si
+  permission_edit_issue_notes: QeydlÉ™rin redaktÉ™ edilmÉ™si
+  permission_edit_issues: TapÅŸÄ±rÄ±qlarÄ±n redaktÉ™ edilmÉ™si
+  permission_edit_messages: MÉ™lumatlarÄ±n redaktÉ™ edilmÉ™si
+  permission_edit_own_issue_notes: ÅžÉ™xsi qeydlÉ™rin redaktÉ™ edilmÉ™si
+  permission_edit_own_messages: ÅžÉ™xsi mÉ™lumatlarÄ±n redaktÉ™ edilmÉ™si
+  permission_edit_own_time_entries: ÅžÉ™xsi vaxt uÃ§otunun redaktÉ™ edilmÉ™si
+  permission_edit_project: LayihÉ™lÉ™rin redaktÉ™ edilmÉ™si
+  permission_edit_time_entries: Vaxt uÃ§otunun redaktÉ™ edilmÉ™si
+  permission_edit_wiki_pages: Wiki-sÉ™hifÉ™nin redaktÉ™ edilmÉ™si
+  permission_export_wiki_pages: Wiki-sÉ™hifÉ™nin ixracÄ±
+  permission_log_time: SÉ™rf olunan vaxtÄ±n uÃ§otu
+  permission_view_changesets: SaxlayÄ±cÄ± dÉ™yiÅŸikliklÉ™rinÉ™ baxÄ±ÅŸ 
+  permission_view_time_entries: SÉ™rf olunan vaxta baxÄ±ÅŸ
+  permission_manage_project_activities: LayihÉ™ Ã¼Ã§Ã¼n hÉ™rÉ™kÉ™t tiplÉ™rinin idarÉ™ edilmÉ™si
+  permission_manage_boards: ForumlarÄ±n idarÉ™ edilmÉ™si
+  permission_manage_categories: TapÅŸÄ±rÄ±q kateqoriyalarÄ±nÄ±n idarÉ™ edilmÉ™si
+  permission_manage_files: FayllarÄ±n idarÉ™ edilmÉ™si
+  permission_manage_issue_relations: TapÅŸÄ±rÄ±q baÄŸlantÄ±larÄ±nÄ±n idarÉ™ edilmÉ™si
+  permission_manage_members: Ä°ÅŸtirakÃ§Ä±larÄ±n idarÉ™ edilmÉ™si
+  permission_manage_news: XÉ™bÉ™rlÉ™rin idarÉ™ edilmÉ™si
+  permission_manage_public_queries: Ãœmumi sorÄŸularÄ±n idarÉ™ edilmÉ™si
+  permission_manage_repository: SaxlayÄ±cÄ±nÄ±n idarÉ™ edilmÉ™si
+  permission_manage_subtasks: Alt tapÅŸÄ±rÄ±qlarÄ±n idarÉ™ edilmÉ™si
+  permission_manage_versions: VariantlarÄ±n idarÉ™ edilmÉ™si
+  permission_manage_wiki: Wiki-nin idarÉ™ edilmÉ™si
+  permission_move_issues: TapÅŸÄ±rÄ±qlarÄ±n kÃ¶Ã§Ã¼rÃ¼lmÉ™si
+  permission_protect_wiki_pages: Wiki-sÉ™hifÉ™lÉ™rin bloklanmasÄ±
+  permission_rename_wiki_pages: Wiki-sÉ™hifÉ™lÉ™rin adÄ±nÄ±n dÉ™yiÅŸdirilmÉ™si
+  permission_save_queries: SorÄŸularÄ±n yadda saxlanÄ±lmasÄ±
+  permission_select_project_modules: LayihÉ™ modulunun seÃ§imi
+  permission_view_calendar: TÉ™qvimÉ™ baxÄ±ÅŸ
+  permission_view_documents: SÉ™nÉ™dlÉ™rÉ™ baxÄ±ÅŸ
+  permission_view_files: Fayllara baxÄ±ÅŸ
+  permission_view_gantt: Qant diaqramÄ±na baxÄ±ÅŸ
+  permission_view_issue_watchers: NÉ™zarÉ™tÃ§ilÉ™rin siyahÄ±larÄ±na baxÄ±ÅŸ
+  permission_view_messages: MÉ™lumatlara baxÄ±ÅŸ
+  permission_view_wiki_edits: Wiki tarixÃ§É™sinÉ™ baxÄ±ÅŸ
+  permission_view_wiki_pages: Wiki-yÉ™ baxÄ±ÅŸ
+
+  project_module_boards: Forumlar
+  project_module_documents: SÉ™nÉ™dlÉ™r
+  project_module_files: Fayllar
+  project_module_issue_tracking: TapÅŸÄ±rÄ±qlar
+  project_module_news: XÉ™bÉ™rlÉ™r
+  project_module_repository: SaxlayÄ±cÄ±
+  project_module_time_tracking: VaxtÄ±n uÃ§otu
+  project_module_wiki: Wiki
+  project_module_gantt: Qant diaqramÄ±
+  project_module_calendar: TÉ™qvim
+
+  setting_activity_days_default: GÃ¶rÃ¼lÉ™n iÅŸlÉ™rdÉ™ É™ks olunan gÃ¼nlÉ™rin sayÄ±
+  setting_app_subtitle: ÆlavÉ™nin sÉ™rlÃ¶vhÉ™si
+  setting_app_title: ÆlavÉ™nin adÄ±
+  setting_attachment_max_size: YerlÉ™ÅŸdirmÉ™nin maksimal Ã¶lÃ§Ã¼sÃ¼
+  setting_autofetch_changesets: SaxlayÄ±cÄ±nÄ±n dÉ™yiÅŸikliklÉ™rini avtomatik izlÉ™mÉ™k
+  setting_autologin: Avtomatik giriÅŸ
+  setting_bcc_recipients: Gizli surÉ™tlÉ™ri istifadÉ™ etmÉ™k (BCC)
+  setting_cache_formatted_text: FormatlaÅŸdÄ±rÄ±lmÄ±ÅŸ mÉ™tnin heÅŸlÉ™nmÉ™si
+  setting_commit_fix_keywords: AÃ§ar sÃ¶zlÉ™rin tÉ™yini
+  setting_commit_ref_keywords: AxtarÄ±ÅŸ Ã¼Ã§Ã¼n aÃ§ar sÃ¶zlÉ™r
+  setting_cross_project_issue_relations: LayihÉ™lÉ™r Ã¼zrÉ™ tapÅŸÄ±rÄ±qlarÄ±n kÉ™siÅŸmÉ™sinÉ™ icazÉ™ vermÉ™k
+  setting_date_format: Tarixin formatÄ±
+  setting_default_language: Susmaya gÃ¶rÉ™ dil
+  setting_default_notification_option: Susmaya gÃ¶rÉ™ xÉ™bÉ™rdarlÄ±q Ã¼sulu
+  setting_default_projects_public: Yeni layihÉ™lÉ™r Ã¼mumaÃ§Ä±q hesab edilir
+  setting_diff_max_lines_displayed: diff Ã¼Ã§Ã¼n sÉ™tirlÉ™rin maksimal sayÄ± 
+  setting_display_subprojects_issues: Susmaya gÃ¶rÉ™ altlayihÉ™lÉ™rin É™ks olunmasÄ±
+  setting_emails_footer: MÉ™ktubun sÉ™tiraltÄ± qeydlÉ™ri
+  setting_enabled_scm: Daxil edilÉ™n SCM
+  setting_feeds_limit: RSS axÄ±nÄ± Ã¼Ã§Ã¼n baÅŸlÄ±qlarÄ±n sayÄ±nÄ±n mÉ™hdudlaÅŸdÄ±rÄ±lmasÄ±
+  setting_file_max_size_displayed: Æks olunma Ã¼Ã§Ã¼n mÉ™tn faylÄ±nÄ±n maksimal Ã¶lÃ§Ã¼sÃ¼
+  setting_gravatar_enabled: Ä°stifadÉ™Ã§i avatarÄ±nÄ± Gravatar-dan istifadÉ™ etmÉ™k
+  setting_host_name: Kompyuterin adÄ±
+  setting_issue_list_default_columns: Susmaya gÃ¶rÉ™ tapÅŸÄ±rÄ±qlarÄ±n siyahÄ±sÄ±nda É™ks oluna sÃ¼tunlar
+  setting_issues_export_limit: Ä°xrac olunan tapÅŸÄ±rÄ±qlar Ã¼zrÉ™ mÉ™hdudiyyÉ™tlÉ™r
+  setting_login_required: Autentifikasiya vacibdir
+  setting_mail_from: Ã‡Ä±xan e-poÃ§t Ã¼nvanÄ±
+  setting_mail_handler_api_enabled: Daxil olan mÉ™lumatlar Ã¼Ã§Ã¼n veb-servisi qoÅŸmaq
+  setting_mail_handler_api_key: API aÃ§ar
+  setting_openid: GiriÅŸ vÉ™ qeydiyyat Ã¼Ã§Ã¼n OpenID izacÉ™ vermÉ™k
+  setting_per_page_options: SÉ™hifÉ™ Ã¼Ã§Ã¼n qeydlÉ™rin sayÄ±
+  setting_plain_text_mail: YalnÄ±z sadÉ™ mÉ™tn (HTML olmadan)
+  setting_protocol: Protokol
+  setting_repository_log_display_limit: DÉ™yiÅŸikliklÉ™r jurnalÄ±nda É™ks olunan redaksiyalarÄ±n maksimal sayÄ±
+  setting_self_registration: Ã–zÃ¼nÃ¼qeydiyyat
+  setting_sequential_project_identifiers: LayihÉ™lÉ™rin ardÄ±cÄ±l identifikatorlarÄ±nÄ± generasiya etmÉ™k
+  setting_sys_api_enabled: SaxlayÄ±cÄ±nÄ±n idarÉ™ edilmÉ™si Ã¼Ã§Ã¼n veb-servisi qoÅŸmaq
+  setting_text_formatting: MÉ™tnin formatlaÅŸdÄ±rÄ±lmasÄ±
+  setting_time_format: VaxtÄ±n formatÄ±
+  setting_user_format: AdÄ±n É™ks olunma formatÄ±
+  setting_welcome_text: Salamlama mÉ™tni 
+  setting_wiki_compression: Wiki tarixÃ§É™sinin sÄ±xlaÅŸdÄ±rÄ±lmasÄ±
+
+  status_active: aktivdir
+  status_locked: bloklanÄ±b
+  status_registered: qeydiyyatdan keÃ§ib
+
+  text_are_you_sure: Siz É™minsinizmi?
+  text_assign_time_entries_to_project: Qeydiyyata alÄ±nmÄ±ÅŸ vaxtÄ± layihÉ™yÉ™ bÉ™rkitmÉ™k
+  text_caracters_maximum: "Maksimum %{count} simvol."
+  text_caracters_minimum: "%{count} simvoldan az olmamalÄ±dÄ±r."
+  text_comma_separated: Bir neÃ§É™ qiymÉ™t mÃ¼mkÃ¼ndÃ¼r (vergÃ¼l vasitÉ™silÉ™).
+  text_custom_field_possible_values_info: 'HÉ™r sÉ™tirÉ™ bir qiymÉ™t'
+  text_default_administrator_account_changed: Ä°nzibatÃ§Ä±nÄ±n uÃ§ot qeydi susmaya gÃ¶rÉ™ dÉ™yiÅŸmiÅŸdir
+  text_destroy_time_entries_question: "Bu tapÅŸÄ±rÄ±q Ã¼Ã§Ã¼n sÉ™rf olunan vaxta gÃ¶rÉ™ %{hours} saat qeydiyyata alÄ±nÄ±b. Siz nÉ™ etmÉ™k istÉ™yirsiniz?"
+  text_destroy_time_entries: Qeydiyyata alÄ±nmÄ±ÅŸ vaxtÄ± silmÉ™k
+  text_diff_truncated: '... Bu diff mÉ™hduddur, Ã§Ã¼nki É™ks olunan maksimal Ã¶lÃ§Ã¼nÃ¼ keÃ§ir.'
+  text_email_delivery_not_configured: "PoÃ§t serveri ilÉ™ iÅŸin parametrlÉ™ri sazlanmayÄ±b vÉ™ e-poÃ§t ilÉ™ bildiriÅŸ funksiyasÄ± aktiv deyildir.\nSizin SMTP-server Ã¼Ã§Ã¼n parametrlÉ™ri config/configuration.yml faylÄ±ndan sazlaya bilÉ™rsiniz. DÉ™yiÅŸikliklÉ™rin tÉ™tbiq edilmÉ™si Ã¼Ã§Ã¼n É™lavÉ™ni yenidÉ™n baÅŸladÄ±n."
+  text_enumeration_category_reassign_to: 'Onlara aÅŸaÄŸÄ±dakÄ± qiymÉ™tlÉ™ri tÉ™yin etmÉ™k:'
+  text_enumeration_destroy_question: "%{count} obyekt bu qiymÉ™tlÉ™ baÄŸlÄ±dÄ±r."
+  text_file_repository_writable: QeydÉ™ giriÅŸ imkanÄ± olan saxlayÄ±cÄ±
+  text_issue_added: "Yeni tapÅŸÄ±rÄ±q yaradÄ±lÄ±b %{id} (%{author})."
+  text_issue_category_destroy_assignments: KateqoriyanÄ±n tÉ™yinatÄ±nÄ± silmÉ™k
+  text_issue_category_destroy_question: "Bir neÃ§É™ tapÅŸÄ±rÄ±q (%{count}) bu kateqoriya Ã¼Ã§Ã¼n tÉ™yin edilib. Siz nÉ™ etmÉ™k istÉ™yirsiniz?"
+  text_issue_category_reassign_to: Bu kateqoriya Ã¼Ã§Ã¼n tapÅŸÄ±rÄ±ÄŸÄ± yenidÉ™n tÉ™yin etmÉ™k
+  text_issues_destroy_confirmation: 'SeÃ§ilÉ™n tapÅŸÄ±rÄ±qlarÄ± silmÉ™k istÉ™diyinizÉ™ É™minsinizmi?'
+  text_issues_ref_in_commit_messages: MÉ™lumatÄ±n mÉ™tnindÉ™n Ã§Ä±xÄ±ÅŸ edÉ™rÉ™k tapÅŸÄ±rÄ±qlarÄ±n statuslarÄ±nÄ±n tutuÅŸdurulmasÄ± vÉ™ dÉ™yiÅŸdirilmÉ™si
+  text_issue_updated: "TapÅŸÄ±rÄ±q %{id} yenilÉ™nib (%{author})."
+  text_journal_changed: "Parametr %{label} %{old} - %{new} dÉ™yiÅŸib"
+  text_journal_deleted: "Parametrin %{old} qiymÉ™ti %{label} silinib"
+  text_journal_set_to: "%{label} parametri %{value} dÉ™yiÅŸib"
+  text_length_between: "%{min} vÉ™ %{max} simvollar arasÄ±ndakÄ± uzunluq."
+  text_load_default_configuration: Susmaya gÃ¶rÉ™ konfiqurasiyanÄ± yÃ¼klÉ™mÉ™k
+  text_min_max_length_info: 0 mÉ™hdudiyyÉ™tlÉ™rin olmadÄ±ÄŸÄ±nÄ± bildirir
+  text_no_configuration_data: "Rollar, trekerlÉ™r, tapÅŸÄ±rÄ±qlarÄ±n statuslarÄ± vÉ™ operativ plan konfiqurasiya olunmayÄ±blar.\nSusmaya gÃ¶rÉ™ konfiqurasiyanÄ±n yÃ¼klÉ™nmÉ™si tÉ™kidlÉ™ xahiÅŸ olunur. Siz onu sonradan dÉ™yiÅŸÉ™ bilÉ™rsiniz."
+  text_plugin_assets_writable: Modullar kataloqu qeyd Ã¼Ã§Ã¼n aÃ§Ä±qdÄ±r
+  text_project_destroy_confirmation: Siz bu layihÉ™ vÉ™ ona aid olan bÃ¼tÃ¼n informasiyanÄ± silmÉ™k istÉ™diyinizÉ™ É™minsinizmi?
+  text_reassign_time_entries: 'Qeydiyyata alÄ±nmÄ±ÅŸ vaxtÄ± aÅŸaÄŸÄ±dakÄ± tapÅŸÄ±rÄ±ÄŸa keÃ§ir:'
+  text_regexp_info: "mÉ™sÉ™lÉ™n: ^[A-Z0-9]+$"
+  text_repository_usernames_mapping: "SaxlayÄ±cÄ±nÄ±n jurnalÄ±nda tapÄ±lan adlarla baÄŸlÄ± olan Redmine istifadÉ™Ã§isini seÃ§in vÉ™ ya yenilÉ™yin.\nEyni ad vÉ™ e-poÃ§ta sahib olan istifadÉ™Ã§ilÉ™r Redmine vÉ™ saxlayÄ±cÄ±da avtomatik É™laqÉ™lÉ™ndirilir."
+  text_rmagick_available: RMagick istifadÉ™si mÃ¼mkÃ¼ndÃ¼r (opsional olaraq)
+  text_select_mail_notifications: Elektron poÃ§ta bildiriÅŸlÉ™rin gÃ¶ndÉ™rilmÉ™si seÃ§im edÉ™cÉ™yiniz hÉ™rÉ™kÉ™tlÉ™rdÉ™n asÄ±lÄ±dÄ±r.
+  text_select_project_modules: 'LayihÉ™dÉ™ istifadÉ™ olunacaq modullarÄ± seÃ§in:'
+  text_status_changed_by_changeset: "%{value} redaksiyada reallaÅŸdÄ±rÄ±lÄ±b."
+  text_subprojects_destroy_warning: "AltlayihÉ™lÉ™r: %{value} hÉ™mÃ§inin silinÉ™cÉ™k."
+  text_tip_issue_begin_day: tapÅŸÄ±rÄ±ÄŸÄ±n baÅŸlanÄŸÄ±c tarixi
+  text_tip_issue_begin_end_day: elÉ™ hÉ™min gÃ¼n tapÅŸÄ±rÄ±ÄŸÄ±n baÅŸlanÄŸÄ±c vÉ™ bitmÉ™ tarixi
+  text_tip_issue_end_day: tapÅŸÄ±rÄ±ÄŸÄ±n baÅŸa Ã§atma tarixi
+  text_tracker_no_workflow: Bu treker Ã¼Ã§Ã¼n hÉ™rÉ™kÉ™tlÉ™rin ardÄ±cÄ±llÄ±ÄŸÄ± mÃ¼É™yyÉ™n edimÉ™yib
+  text_unallowed_characters: QadaÄŸan edilmiÅŸ simvollar
+  text_user_mail_option: "SeÃ§ilmÉ™yÉ™n layihÉ™lÉ™r Ã¼Ã§Ã¼n Siz yalnÄ±z baxdÄ±ÄŸÄ±nÄ±z vÉ™ ya iÅŸtirak etdiyiniz layihÉ™lÉ™r barÉ™dÉ™ bildiriÅŸ alacaqsÄ±nÄ±z mÉ™sÉ™lÉ™n, mÃ¼É™llifi olduÄŸunuz layihÉ™lÉ™r vÉ™ ya o layihÉ™lÉ™r ki, SizÉ™ tÉ™yin edilib)."
+  text_user_wrote: "%{value} yazÄ±b:"
+  text_wiki_destroy_confirmation: Siz bu Wiki vÉ™ onun tÉ™rkibindÉ™kilÉ™ri silmÉ™k istÉ™diyinizÉ™ É™minsinizmi?
+  text_workflow_edit: VÉ™ziyyÉ™tlÉ™rin ardÄ±cÄ±llÄ±ÄŸÄ±nÄ± redaktÉ™ etmÉ™k Ã¼Ã§Ã¼n rol vÉ™ trekeri seÃ§in
+
+  warning_attachments_not_saved: "faylÄ±n (larÄ±n) %{count} yadda saxlamaq mÃ¼mkÃ¼n deyildir."
+  text_wiki_page_destroy_question: Bu sÉ™hifÉ™ %{descendants} yaxÄ±n vÉ™ Ã§ox yaxÄ±n sÉ™hifÉ™lÉ™rÉ™ malikdir. Siz nÉ™ etmÉ™k istÉ™yirsiniz?
+  text_wiki_page_reassign_children: Cari sÉ™hifÉ™ Ã¼Ã§Ã¼n yaxÄ±n sÉ™hifÉ™lÉ™ri yenidÉ™n tÉ™yin etmÉ™k
+  text_wiki_page_nullify_children: YaxÄ±n sÉ™hifÉ™lÉ™ri baÅŸ sÉ™hifÉ™lÉ™r etmÉ™k
+  text_wiki_page_destroy_children: YaxÄ±n vÉ™ Ã§ox yaxÄ±n sÉ™hifÉ™lÉ™ri silmÉ™k
+  setting_password_min_length: Parolun minimal uzunluÄŸu
+  field_group_by: NÉ™ticÉ™lÉ™ri qruplaÅŸdÄ±rmaq
+  mail_subject_wiki_content_updated: "Wiki-sÉ™hifÉ™ '%{id}' yenilÉ™nmiÅŸdir"
+  label_wiki_content_added: Wiki-sÉ™hifÉ™ É™lavÉ™ olunub
+  mail_subject_wiki_content_added: "Wiki-sÉ™hifÉ™  '%{id}' É™lavÉ™ edilib"
+  mail_body_wiki_content_added: "%{author} Wiki-sÉ™hifÉ™ni '%{id}' É™lavÉ™ edib."
+  label_wiki_content_updated: Wiki-sÉ™hifÉ™ yenilÉ™nib
+  mail_body_wiki_content_updated: "%{author} Wiki-sÉ™hifÉ™ni '%{id}' yenilÉ™yib."
+  permission_add_project: LayihÉ™nin yaradÄ±lmasÄ±
+  setting_new_project_user_role_id: LayihÉ™ni yaradan istifadÉ™Ã§iyÉ™ tÉ™yin olunan rol
+  label_view_all_revisions: BÃ¼tÃ¼n yoxlamalarÄ± gÃ¶stÉ™rmÉ™k
+  label_tag: NiÅŸan
+  label_branch: ÅžÃ¶bÉ™
+  error_no_tracker_in_project: Bu layihÉ™ ilÉ™ heÃ§ bir treker assosiasiya olunmayÄ±b. LayihÉ™nin sazlamalarÄ±nÄ± yoxlayÄ±n.
+  error_no_default_issue_status: Susmaya gÃ¶rÉ™ tapÅŸÄ±rÄ±qlarÄ±n statusu mÃ¼É™yyÉ™n edilmÉ™yib. SazlamalarÄ± yoxlayÄ±n (bax. "Ä°nzibatÃ§Ä±lÄ±q -> TapÅŸÄ±rÄ±qlarÄ±n statusu").
+  label_group_plural: Qruplar
+  label_group: Qrup
+  label_group_new: Yeni qrup
+  label_time_entry_plural: SÉ™rf olunan vaxt
+  text_journal_added: "%{label} %{value} É™lavÉ™ edilib"
+  field_active: Aktiv
+  enumeration_system_activity: Sistemli
+  permission_delete_issue_watchers: NÉ™zarÉ™tÃ§ilÉ™rin silinmÉ™si
+  version_status_closed: BaÄŸlanÄ±b
+  version_status_locked: bloklanÄ±b
+  version_status_open: aÃ§Ä±qdÄ±r
+  error_can_not_reopen_issue_on_closed_version: BaÄŸlÄ± varianta tÉ™yin edilÉ™n tapÅŸÄ±rÄ±q yenidÉ™n aÃ§Ä±q ola bilmÉ™z
+  label_user_anonymous: Anonim
+  button_move_and_follow: YerlÉ™ÅŸdirmÉ™k vÉ™ keÃ§id
+  setting_default_projects_modules: Yeni layihÉ™lÉ™r Ã¼Ã§Ã¼n susmaya gÃ¶rÉ™ daxil edilÉ™n modullar
+  setting_gravatar_default: Susmaya gÃ¶rÉ™ Gravatar tÉ™sviri
+  field_sharing: BirgÉ™ istifadÉ™
+  label_version_sharing_hierarchy: LayihÉ™lÉ™rin iyerarxiyasÄ±na gÃ¶rÉ™
+  label_version_sharing_system: bÃ¼tÃ¼n layihÉ™lÉ™r ilÉ™
+  label_version_sharing_descendants: Alt layihÉ™lÉ™r ilÉ™
+  label_version_sharing_tree: LayihÉ™lÉ™rin iyerarxiyasÄ± ilÉ™
+  label_version_sharing_none: BirgÉ™ istifadÉ™ olmadan
+  error_can_not_archive_project: Bu layihÉ™ arxivlÉ™ÅŸdirilÉ™ bilmÉ™z
+  button_duplicate: TÉ™krarlamaq
+  button_copy_and_follow: SurÉ™tini Ã§Ä±xarmaq vÉ™ davam etmÉ™k
+  label_copy_source: MÉ™nbÉ™
+  setting_issue_done_ratio: SahÉ™nin kÃ¶mÉ™yi ilÉ™ tapÅŸÄ±rÄ±ÄŸÄ±n hazÄ±rlÄ±ÄŸÄ±nÄ± nÉ™zÉ™rÉ™ almaq
+  setting_issue_done_ratio_issue_status: TapÅŸÄ±rÄ±ÄŸÄ±n statusu
+  error_issue_done_ratios_not_updated: TapÅŸÄ±rÄ±qlarÄ±n hazÄ±rlÄ±q parametri yenilÉ™nmÉ™yib
+  error_workflow_copy_target: MÉ™qsÉ™dÉ™ uyÄŸun trekerlÉ™ri vÉ™ rollarÄ± seÃ§in
+  setting_issue_done_ratio_issue_field: TapÅŸÄ±rÄ±ÄŸÄ±n hazÄ±rlÄ±q sÉ™viyyÉ™si
+  label_copy_same_as_target: MÉ™qsÉ™ddÉ™ olduÄŸu kimi
+  label_copy_target: MÉ™qsÉ™d
+  notice_issue_done_ratios_updated: Parametr &laquo;hazÄ±rlÄ±q&raquo; yenilÉ™nib.
+  error_workflow_copy_source: Cari trekeri vÉ™ ya rolu seÃ§in
+  label_update_issue_done_ratios: TapÅŸÄ±rÄ±ÄŸÄ±n hazÄ±rlÄ±q sÉ™viyyÉ™sini yenilÉ™mÉ™k
+  setting_start_of_week: HÉ™ftÉ™nin birinci gÃ¼nÃ¼
+  label_api_access_key: API-yÉ™ giriÅŸ aÃ§arÄ±
+  text_line_separated: BÄ°r neÃ§É™ qiymÉ™t icazÉ™ verilib (hÉ™r sÉ™tirÉ™ bir qiymÉ™t).
+  label_revision_id: Yoxlama %{value}
+  permission_view_issues: TapÅŸÄ±rÄ±qlara baxÄ±ÅŸ
+  label_display_used_statuses_only: YalnÄ±z bu trekerdÉ™ istifadÉ™ olunan statuslarÄ± É™ks etdirmÉ™k
+  label_api_access_key_created_on: API-yÉ™ giriÅŸ aÃ§arÄ± %{value} É™vvÉ™l aradÄ±lÄ±b
+  label_feeds_access_key: RSS giriÅŸ aÃ§arÄ±
+  notice_api_access_key_reseted: Sizin API giriÅŸ aÃ§arÄ±nÄ±z sÄ±fÄ±rlanÄ±b.
+  setting_rest_api_enabled: REST veb-servisini qoÅŸmaq
+  button_show: GÃ¶stÉ™rmÉ™k
+  label_missing_api_access_key: API-yÉ™ giriÅŸ aÃ§arÄ± mÃ¶vcud deyildir
+  label_missing_feeds_access_key: RSS-É™ giriÅŸ aÃ§arÄ± mÃ¶vcud deyildir
+  setting_mail_handler_body_delimiters: Bu sÉ™tirlÉ™rin birindÉ™n sonra mÉ™ktubu qÄ±saltmaq
+  permission_add_subprojects: Alt layihÉ™lÉ™rin yaradÄ±lmasÄ±
+  label_subproject_new: Yeni alt layihÉ™
+  text_own_membership_delete_confirmation: |-
+    Siz bÉ™zi vÉ™ ya bÃ¼tÃ¼n hÃ¼quqlarÄ± silmÉ™yÉ™ Ã§alÄ±ÅŸÄ±rsÄ±nÄ±z, nÉ™ticÉ™dÉ™ bu layihÉ™ni redaktÉ™ etmÉ™k hÃ¼ququnu da itirÉ™ bilÉ™rsiniz. Davam etmÉ™k istÉ™diyinizÉ™ É™minsinizmi?
+    
+  label_close_versions: BaÅŸa Ã§atmÄ±ÅŸ variantlarÄ± baÄŸlamaq
+  label_board_sticky: BÉ™rkidilib
+  label_board_locked: BloklanÄ±b
+  field_principal: Ad
+  text_zoom_out: UzaqlaÅŸdÄ±rmaq
+  text_zoom_in: YaxÄ±nlaÅŸdÄ±rmaq
+  notice_unable_delete_time_entry: JurnalÄ±n qeydini silmÉ™k mÃ¼mkÃ¼n deyildir.
+  label_overall_spent_time: CÉ™mi sÉ™rf olunan vaxt
+  label_user_mail_option_none: HadisÉ™ yoxdur
+  field_member_of_group: TÉ™yin olunmuÅŸ qrup 
+  field_assigned_to_role: TÉ™yin olunmuÅŸ rol
+  notice_not_authorized_archived_project: SorÄŸulanan layihÉ™ arxivlÉ™ÅŸdirilib.
+  label_principal_search: "Ä°stifadÉ™Ã§ini vÉ™ ya qrupu tapmaq:"
+  label_user_search: "Ä°stifadÉ™Ã§ini tapmaq:"
+  field_visible: GÃ¶rÃ¼nmÉ™ dÉ™rÉ™cÉ™si
+  setting_emails_header: MÉ™ktubun baÅŸlÄ±ÄŸÄ±
+
+  setting_commit_logtime_activity_id: VaxtÄ±n uÃ§otu Ã¼Ã§Ã¼n gÃ¶rÃ¼lÉ™n hÉ™rÉ™kÉ™tlÉ™r
+  text_time_logged_by_changeset: "%{value} redaksiyada nÉ™zÉ™rÉ™ alÄ±nÄ±b."
+  setting_commit_logtime_enabled: Vaxt uÃ§otunu qoÅŸmaq
+  notice_gantt_chart_truncated: Æks oluna bilÉ™cÉ™k elementlÉ™rin maksimal sayÄ± artdÄ±ÄŸÄ±na gÃ¶rÉ™ diaqram kÉ™silÉ™cÉ™k (%{max})
+  setting_gantt_items_limit: Qant diaqramÄ±nda É™ks olunan elementlÉ™rin maksimal sayÄ± 
+  field_warn_on_leaving_unsaved: Yadda saxlanÄ±lmayan mÉ™tnin sÉ™hifÉ™si baÄŸlanan zaman xÉ™bÉ™rdarlÄ±q etmÉ™k
+  text_warn_on_leaving_unsaved: TÉ™rk etmÉ™k istÉ™diyiniz cari sÉ™hifÉ™dÉ™ yadda saxlanÄ±lmayan vÉ™ itÉ™ bilÉ™cÉ™k mÉ™tn vardÄ±r.
+  label_my_queries: MÉ™nim yadda saxlanÄ±lan sorÄŸularÄ±m
+  text_journal_changed_no_detail: "%{label} yenilÉ™nib"
+  label_news_comment_added: XÉ™bÉ™rÉ™ ÅŸÉ™rh É™lavÉ™ olunub
+  button_expand_all: HamÄ±sÄ±nÄ± aÃ§
+  button_collapse_all: HamÄ±sÄ±nÄ± Ã§evir
+  label_additional_workflow_transitions_for_assignee: Ä°stifadÉ™Ã§i icraÃ§Ä± olduÄŸu zaman É™lavÉ™ keÃ§idlÉ™r 
+  label_additional_workflow_transitions_for_author: Ä°stifadÉ™Ã§i mÃ¼É™llif olduÄŸu zaman É™lavÉ™ keÃ§idlÉ™r 
+  label_bulk_edit_selected_time_entries: SÉ™rf olunan vaxtÄ±n seÃ§ilÉ™n qeydlÉ™rinin kÃ¼tlÉ™vi ÅŸÉ™kildÉ™ dÉ™yiÅŸdirilmÉ™si
+  text_time_entries_destroy_confirmation: Siz sÉ™rf olunan vaxtÄ±n seÃ§ilÉ™n qeydlÉ™rini silmÉ™k istÉ™diyinizÉ™ É™minsinizmi?
+  label_role_anonymous: Anonim
+  label_role_non_member: Ä°ÅŸtirakÃ§Ä± deyil
+  label_issue_note_added: Qeyd É™lavÉ™ olunub
+  label_issue_status_updated: Status yenilÉ™nib
+  label_issue_priority_updated: Prioritet yenilÉ™nib
+  label_issues_visibility_own: Ä°stifadÉ™Ã§i Ã¼Ã§Ã¼n yaradÄ±lan vÉ™ ya ona tÉ™yin olunan tapÅŸÄ±rÄ±qlar
+  field_issues_visibility: TapÅŸÄ±rÄ±qlarÄ±n gÃ¶rÃ¼nmÉ™ dÉ™rÉ™cÉ™si
+  label_issues_visibility_all: BÃ¼tÃ¼n tapÅŸÄ±rÄ±qlar
+  permission_set_own_issues_private: ÅžÉ™xsi tapÅŸÄ±rÄ±qlar Ã¼Ã§Ã¼n gÃ¶rÃ¼nmÉ™ dÉ™rÉ™cÉ™sinin (Ã¼mumi/ÅŸÉ™xsi) qurulmasÄ±
+  field_is_private: ÅžÉ™xsi
+  permission_set_issues_private: TapÅŸÄ±rÄ±qlar Ã¼Ã§Ã¼n gÃ¶rÃ¼nmÉ™ dÉ™rÉ™cÉ™sinin (Ã¼mumi/ÅŸÉ™xsi) qurulmasÄ±
+  label_issues_visibility_public: YalnÄ±z Ã¼mumi tapÅŸÄ±rÄ±qlar
+  text_issues_destroy_descendants_confirmation: HÉ™mÃ§inin %{count} tapÅŸÄ±rÄ±q (lar) silinÉ™cÉ™k.
+  field_commit_logs_encoding: SaxlayÄ±cÄ±da ÅŸÉ™rhlÉ™rin kodlaÅŸdÄ±rÄ±lmasÄ±
+  field_scm_path_encoding: Yolun kodlaÅŸdÄ±rÄ±lmasÄ±
+  text_scm_path_encoding_note: "Susmaya gÃ¶rÉ™: UTF-8"
+  field_path_to_repository: SaxlayÄ±cÄ±ya yol
+  field_root_directory: KÃ¶k direktoriya
+  field_cvs_module: Modul
+  field_cvsroot: CVSROOT
+  text_mercurial_repository_note: Lokal saxlayÄ±cÄ± (mÉ™sÉ™lÉ™n, /hgrepo, c:\hgrepo)
+  text_scm_command: Komanda
+  text_scm_command_version: Variant
+  label_git_report_last_commit: Fayllar vÉ™ direktoriyalar Ã¼Ã§Ã¼n son dÉ™yiÅŸikliklÉ™ri gÃ¶stÉ™rmÉ™k
+  text_scm_config: Siz config/configuration.yml faylÄ±nda SCM komandasÄ±nÄ± sazlaya bilÉ™rsiniz. XahiÅŸ olunur, bu faylÄ±n redaktÉ™sindÉ™n sonra É™lavÉ™ni iÅŸÉ™ salÄ±n.
+  text_scm_command_not_available: VariantlarÄ±n nÉ™zarÉ™t sisteminin komandasÄ±na giriÅŸ mÃ¼mkÃ¼n deyildir. XahiÅŸ olunur, inzibatÃ§Ä± panelindÉ™ki sazlamalarÄ± yoxlayÄ±n.
+  notice_issue_successful_create: TapÅŸÄ±rÄ±q %{id} yaradÄ±lÄ±b.
+  label_between: arasÄ±nda
+  setting_issue_group_assignment: Ä°stifadÉ™Ã§i qruplarÄ±na tÉ™yinata icazÉ™ vermÉ™k 
+  label_diff: FÉ™rq(diff)
+  text_git_repository_note: "Saxlama yerini gÃ¶stÉ™rin (mÉ™s: /gitrepo, c:\\gitrepo)"
+  description_query_sort_criteria_direction: Ã‡eÅŸidlÉ™mÉ™ qaydasÄ±
+  description_project_scope: LayihÉ™nin hÉ™cmi
+  description_filter: Filtr
+  description_user_mail_notification: E-poÃ§t Mail xÉ™bÉ™rdarlÄ±qlarÄ±nÄ±n sazlamasÄ±
+  description_date_from: BaÅŸlama tarixini daxil edin
+  description_message_content: MesajÄ±n kontenti
+  description_available_columns: MÃ¶vcud sÃ¼tunlar
+  description_date_range_interval: TarixlÉ™r diapazonunu seÃ§in
+  description_issue_category_reassign: MÉ™sÉ™lÉ™nin kateqoriyasÄ±nÄ± seÃ§in
+  description_search: AxtarÄ±ÅŸ sahÉ™si
+  description_notes: Qeyd
+  description_date_range_list: SiyahÄ±dan diapazonu seÃ§in
+  description_choose_project: LayihÉ™lÉ™r
+  description_date_to: YerinÉ™ yetirilmÉ™ tarixini daxil edin
+  description_query_sort_criteria_attribute: Ã‡eÅŸidlÉ™mÉ™ meyarlarÄ±
+  description_wiki_subpages_reassign: Yeni valideyn sÉ™hifÉ™sini seÃ§mÉ™k
+  description_selected_columns: SeÃ§ilmiÅŸ sÃ¼tunlar
+  label_parent_revision: Valideyn
+  label_child_revision: Æsas
+  error_scm_annotate_big_text_file: MÉ™tn faylÄ±nÄ±n maksimal Ã¶lÃ§Ã¼sÃ¼ artdÄ±ÄŸÄ±na gÃ¶rÉ™ ÅŸÉ™rh mÃ¼mkÃ¼n deyildir.
+  setting_default_issue_start_date_to_creation_date: Yeni tapÅŸÄ±rÄ±qlar Ã¼Ã§Ã¼n cari tarixi baÅŸlanÄŸÄ±c tarixi kimi istifadÉ™ etmÉ™k
+  button_edit_section: Bu bÃ¶lmÉ™ni redaktÉ™ etmÉ™k
+  setting_repositories_encodings: ÆlavÉ™lÉ™rin vÉ™ saxlayÄ±cÄ±larÄ±n kodlaÅŸdÄ±rÄ±lmasÄ±
+  description_all_columns: BÃ¼tÃ¼n sÃ¼tunlar
+  button_export: Ä°xrac
+  label_export_options: "%{export_format} ixracÄ±n parametrlÉ™ri"
+  error_attachment_too_big: FaylÄ±n maksimal Ã¶lÃ§Ã¼sÃ¼ artdÄ±ÄŸÄ±na gÃ¶rÉ™ bu faylÄ± yÃ¼klÉ™mÉ™k mÃ¼mkÃ¼n deyildir (%{max_size})
+  notice_failed_to_save_time_entries: "SÉ™hv N %{ids}. %{total} giriÅŸdÉ™n %{count} yaddaÅŸa saxlanÄ±la bilmÉ™di."
+  label_x_issues:
+    zero:  0 TapÅŸÄ±rÄ±q
+    one:   1 TapÅŸÄ±rÄ±q
+    few:   "%{count} TapÅŸÄ±rÄ±q"
+    many:  "%{count} TapÅŸÄ±rÄ±q"
+    other: "%{count} TapÅŸÄ±rÄ±q"
+  label_repository_new: Yeni saxlayÄ±cÄ±
+  field_repository_is_default: Susmaya gÃ¶rÉ™ saxlayÄ±cÄ±
+  label_copy_attachments: ÆlavÉ™nin surÉ™tini Ã§Ä±xarmaq
+  label_item_position: "%{position}/%{count}"
+  label_completed_versions: BaÅŸa Ã§atdÄ±rÄ±lmÄ±ÅŸ variantlar
+  text_project_identifier_info: YalnÄ±z kiÃ§ik latÄ±n hÉ™rflÉ™rinÉ™ (a-z), rÉ™qÉ™mlÉ™rÉ™, tire vÉ™ Ã§icgilÉ™rÉ™ icazÉ™ verilir.<br />Yadda saxladÄ±qdan sonra identifikatoru dÉ™yiÅŸmÉ™k olmaz.
+  field_multiple: Ã‡oxsaylÄ± qiymÉ™tlÉ™r
+  setting_commit_cross_project_ref: DigÉ™r bÃ¼tÃ¼n layihÉ™lÉ™rdÉ™ tapÅŸÄ±rÄ±qlarÄ± dÃ¼zÉ™ltmÉ™k vÉ™ istinad etmÉ™k
+  text_issue_conflict_resolution_add_notes: QeydlÉ™rimi É™lavÉ™ etmÉ™k vÉ™ mÉ™nim dÉ™yiÅŸikliklÉ™rimdÉ™n imtina etmÉ™k
+  text_issue_conflict_resolution_overwrite: DÉ™yiÅŸikliklÉ™rimi tÉ™tbiq etmÉ™k (É™vvÉ™lki bÃ¼tÃ¼n qeydlÉ™r yadda saxlanacaq, lakin bÉ™zi qeydlÉ™r yenidÉ™n yazÄ±la bilÉ™r)
+  notice_issue_update_conflict: TapÅŸÄ±rÄ±ÄŸÄ± redaktÉ™ etdiyiniz zaman kimsÉ™ onu artÄ±q dÉ™yiÅŸib.
+  text_issue_conflict_resolution_cancel: MÉ™nim dÉ™yiÅŸikliklÉ™rimi lÉ™ÄŸv etmÉ™k vÉ™ tapÅŸÄ±rÄ±ÄŸÄ± yenidÉ™n gÃ¶stÉ™rmÉ™k %{link}
+  permission_manage_related_issues: ÆlaqÉ™li tapÅŸÄ±rÄ±qlarÄ±n idarÉ™ edilmÉ™si
+  field_auth_source_ldap_filter: LDAP filtri
+  label_search_for_watchers: NÉ™zarÉ™tÃ§ilÉ™ri axtarmaq 
+  notice_account_deleted: "Sizin uÃ§ot qeydiniz tam olaraq silinib" 
+  setting_unsubscribe: "Ä°stifadÉ™Ã§ilÉ™rÉ™ ÅŸÉ™xsi uÃ§ot qeydlÉ™rini silmÉ™yÉ™ icazÉ™ vermÉ™k" 
+  button_delete_my_account: "MÉ™nim uÃ§ot qeydlÉ™rimi silmÉ™k" 
+  text_account_destroy_confirmation: "Sizin uÃ§ot qeydiniz bir daha bÉ™rpa edilmÉ™dÉ™n tam olaraq silinÉ™cÉ™k.\nDavam etmÉ™k istÉ™diyinizÉ™ É™minsinizmi?" 
+  error_session_expired: Sizin sessiya bitmiÅŸdir. XahiÅŸ edirik yenidÉ™n daxil olun.
+  text_session_expiration_settings: "DiqqÉ™t: bu sazlamalarÄ±n dÉ™yiÅŸmÉ™yi cari sessiyanÄ±n baÄŸlanmasÄ±na Ã§Ä±xara bilÉ™r."
+  setting_session_lifetime: SessiyanÄ±n maksimal Session maximum hÉ™yat mÃ¼ddÉ™ti
+  setting_session_timeout: SessiyanÄ±n qeyri aktivlik mÃ¼ddÉ™ti
+  label_session_expiration: SessiyanÄ±n bitmÉ™si
+  permission_close_project: LayihÉ™ni baÄŸla / yenidÉ™n aÃ§
+  label_show_closed_projects: BaÄŸlÄ± layihÉ™lÉ™rÉ™ baxmaq
+  button_close: BaÄŸla
+  button_reopen: YenidÉ™n aÃ§
+  project_status_active: aktiv
+  project_status_closed: baÄŸlÄ±
+  project_status_archived: arxiv
+  text_project_closed: Bu layihÉ™ baÄŸlÄ±dÄ± vÉ™ yalnÄ±z oxuma olar.
+  notice_user_successful_create: Ä°stifadÉ™Ã§i %{id} yaradÄ±ldÄ±.
+  field_core_fields: Standart sahÉ™lÉ™r
+  field_timeout: Zaman aÅŸÄ±mÄ± (saniyÉ™ ilÉ™)
+  setting_thumbnails_enabled: ÆlavÉ™lÉ™rin kiÃ§ik ÅŸÉ™klini gÃ¶stÉ™r
+  setting_thumbnails_size: KiÃ§ik ÅŸÉ™killÉ™rin Ã¶lÃ§Ã¼sÃ¼ (piksel ilÉ™)
+  label_status_transitions: Status keÃ§idlÉ™ri
+  label_fields_permissions: SahÉ™lÉ™rin icazÉ™lÉ™ri
+  label_readonly: Ancaq oxumaq Ã¼Ã§Ã¼n
+  label_required: TÉ™lÉ™b olunur
+  text_repository_identifier_info: YalnÄ±z kiÃ§ik latÄ±n hÉ™rflÉ™rinÉ™ (a-z), rÉ™qÉ™mlÉ™rÉ™, tire vÉ™ Ã§icgilÉ™rÉ™ icazÉ™ verilir.<br />Yadda saxladÄ±qdan sonra identifikatoru dÉ™yiÅŸmÉ™k olmaz.
+  field_board_parent: Ana forum
+  label_attribute_of_project: LayihÉ™ %{name}
+  label_attribute_of_author: MÃ¼É™llif %{name}
+  label_attribute_of_assigned_to: TÉ™yin edilib %{name}
+  label_attribute_of_fixed_version: Æsas versiya %{name}
+  label_copy_subtasks: Alt tapÅŸÄ±rÄ±ÄŸÄ±n surÉ™tini Ã§Ä±xarmaq
+  label_cross_project_hierarchy: With project hierarchy
+  permission_edit_documents: Edit documents
+  button_hide: Hide
+  text_turning_multiple_off: If you disable multiple values, multiple values will be removed in order to preserve only one value per item.
+  label_any: any
+  label_cross_project_system: With all projects
+  label_last_n_weeks: last %{count} weeks
+  label_in_the_past_days: in the past
+  label_copied_to: Copied to
+  permission_set_notes_private: Set notes as private
+  label_in_the_next_days: in the next
+  label_attribute_of_issue: Issue's %{name}
+  label_any_issues_in_project: any issues in project
+  label_cross_project_descendants: With subprojects
+  field_private_notes: Private notes
+  setting_jsonp_enabled: Enable JSONP support
+  label_gantt_progress_line: Progress line
+  permission_add_documents: Add documents
+  permission_view_private_notes: View private notes
+  label_attribute_of_user: User's %{name}
+  permission_delete_documents: Delete documents
+  field_inherit_members: Inherit members
+  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_no_issues_in_project: no issues in project
+  label_copied_from: Copied from
+  setting_non_working_week_days: Non-working days
+  label_any_issues_not_in_project: any issues not in project
+  label_cross_project_tree: With project tree
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: CÉ™mi
diff -r 0a574315af3e -r 4f746d8966dd config/locales/bg.yml
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -51,8 +51,8 @@
         one:   "Ð¾ÐºÐ¾Ð»Ð¾ 1 Ñ‡Ð°Ñ"
         other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 Ñ‡Ð°Ñ"
+        other: "%{count} Ñ‡Ð°ÑÐ°"
       x_days:
         one:   "1 Ð´ÐµÐ½"
         other: "%{count} Ð´ÐµÐ½Ð°"
@@ -180,7 +180,7 @@
   notice_account_deleted: Ð’Ð°ÑˆÐ¸ÑÑ‚ Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ð±ÐµÑˆÐµ Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½Ð°Ñ‚ Ð±ÐµÐ· Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð²ÑŠÐ·ÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ.
   notice_user_successful_create: ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» %{id} Ðµ ÑÑŠÐ·Ð´Ð°Ð´ÐµÐ½.
 
-  error_can_t_load_default_data: "Ð“Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð·Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¸Ð¼ÐµÑ€Ð½Ð°Ñ‚Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ: %{value}"
+  error_can_t_load_default_data: "Ð“Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð·Ð°Ñ€ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð½Ð°Ñ‡Ð°Ð»Ð½Ð°Ñ‚Ð° Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ: %{value}"
   error_scm_not_found: ÐÐµÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð°Ñ‰ Ð¾Ð±ÐµÐºÑ‚ Ð² Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÑ‚Ð¾.
   error_scm_command_failed: "Ð“Ñ€ÐµÑˆÐºÐ° Ð¿Ñ€Ð¸ Ð¾Ð¿Ð¸Ñ‚ Ð·Ð° ÐºÐ¾Ð¼ÑƒÐ½Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ: %{value}"
   error_scm_annotate: "ÐžÐ±ÐµÐºÑ‚ÑŠÑ‚ Ð½Ðµ ÑÑŠÑ‰ÐµÑÑ‚Ð²ÑƒÐ²Ð° Ð¸Ð»Ð¸ Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±ÑŠÐ´Ðµ Ð°Ð½Ð¾Ñ‚Ð¸Ñ€Ð°Ð½."
@@ -217,9 +217,6 @@
   mail_subject_wiki_content_updated: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð°"
   mail_body_wiki_content_updated: Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð°Ñ‚Ð° '%{id}' Ð±ÐµÑˆÐµ Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð° Ð¾Ñ‚ %{author}.
 
-  gui_validation_error: 1 Ð³Ñ€ÐµÑˆÐºÐ°
-  gui_validation_error_plural: "%{count} Ð³Ñ€ÐµÑˆÐºÐ¸"
-
   field_name: Ð˜Ð¼Ðµ
   field_description: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ
   field_summary: ÐÐ½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ
@@ -233,6 +230,7 @@
   field_author: ÐÐ²Ñ‚Ð¾Ñ€
   field_created_on: ÐžÑ‚ Ð´Ð°Ñ‚Ð°
   field_updated_on: ÐžÐ±Ð½Ð¾Ð²ÐµÐ½Ð°
+  field_closed_on: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð°
   field_field_format: Ð¢Ð¸Ð¿
   field_is_for_all: Ð—Ð° Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
   field_possible_values: Ð’ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¸ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚Ð¸
@@ -249,7 +247,7 @@
   field_is_closed: Ð—Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð°
   field_is_default: Ð¡ÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
   field_tracker: Ð¢Ñ€Ð°ÐºÐµÑ€
-  field_subject: ÐžÑ‚Ð½Ð¾ÑÐ½Ð¾
+  field_subject: Ð—Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ
   field_due_date: ÐšÑ€Ð°Ð¹Ð½Ð° Ð´Ð°Ñ‚Ð°
   field_assigned_to: Ð’ÑŠÐ·Ð»Ð¾Ð¶ÐµÐ½Ð° Ð½Ð°
   field_priority: ÐŸÑ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚
@@ -333,6 +331,7 @@
   field_timeout: Ð¢Ð°Ð¹Ð¼Ð°ÑƒÑ‚ (Ð² ÑÐµÐºÑƒÐ½Ð´Ð¸)
   field_board_parent: Ð Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸ Ñ„Ð¾Ñ€ÑƒÐ¼
   field_private_notes: Ð›Ð¸Ñ‡Ð½Ð¸ Ð±ÐµÐ»ÐµÐ¶ÐºÐ¸
+  field_inherit_members: ÐÐ°ÑÐ»ÐµÐ´ÑÐ²Ð°Ð½Ðµ Ð½Ð° Ñ‡Ð»ÐµÐ½Ð¾Ð²ÐµÑ‚Ðµ Ð½Ð° Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑÐºÐ¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚
 
   setting_app_title: Ð—Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ
   setting_app_subtitle: ÐžÐ¿Ð¸ÑÐ°Ð½Ð¸Ðµ
@@ -361,7 +360,7 @@
   setting_cross_project_subtasks: ÐŸÐ¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¾Ñ‚ Ð´Ñ€ÑƒÐ³Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
   setting_issue_list_default_columns: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ð¸ ÐºÐ¾Ð»Ð¾Ð½Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ
   setting_repositories_encodings: ÐšÐ¾Ð´Ð¾Ð²Ð° Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½Ð¸Ñ‚Ðµ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ Ð¸ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°Ñ‚Ð°
-  setting_emails_header: Emails header
+  setting_emails_header: Email header
   setting_emails_footer: ÐŸÐ¾Ð´Ñ‚ÐµÐºÑÑ‚ Ð·Ð° e-mail
   setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
   setting_per_page_options: ÐžÐ¿Ñ†Ð¸Ð¸ Ð·Ð° ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ€Ð°Ð½Ðµ
@@ -401,6 +400,8 @@
   setting_thumbnails_enabled: ÐŸÐ¾ÐºÐ°Ð·Ð²Ð°Ð½Ðµ Ð½Ð° Ð¼Ð¸Ð½Ð¸Ð°Ñ‚ÑŽÑ€Ð¸ Ð½Ð° Ð¿Ñ€Ð¸ÐºÐ°Ñ‡ÐµÐ½Ð¸Ñ‚Ðµ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ
   setting_thumbnails_size: Ð Ð°Ð·Ð¼ÐµÑ€ Ð½Ð° Ð¼Ð¸Ð½Ð¸Ð°Ñ‚ÑŽÑ€Ð¸Ñ‚Ðµ (Ð² Ð¿Ð¸ÐºÑÐµÐ»Ð¸)
   setting_non_working_week_days: ÐÐµ Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸ Ð´Ð½Ð¸
+  setting_jsonp_enabled: Ð Ð°Ð·Ñ€ÐµÑˆÐ°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð´Ñ€ÑŠÐ¶ÐºÐ° Ð½Ð° JSONP
+  setting_default_projects_tracker_ids: Ð¢Ñ€Ð°ÐºÐµÑ€Ð¸ Ð¿Ð¾ Ð¿Ð¾Ð´Ñ€Ð°Ð·Ð±Ð¸Ñ€Ð°Ð½Ðµ Ð·Ð° Ð½Ð¾Ð²Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
 
   permission_add_project: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚
   permission_add_subprojects: Ð¡ÑŠÐ·Ð´Ð°Ð²Ð°Ð½Ðµ Ð½Ð° Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
@@ -437,8 +438,10 @@
   permission_edit_own_time_entries: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° ÑÐ¾Ð±ÑÑ‚Ð²ÐµÐ½Ð¸Ñ‚Ðµ time logs
   permission_manage_news: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð½Ð¾Ð²Ð¸Ð½Ð¸
   permission_comment_news: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð½Ð¾Ð²Ð¸Ð½Ð¸
-  permission_manage_documents: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
   permission_view_documents: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  permission_add_documents: Ð”Ð¾Ð±Ð°Ð²ÑÐ½Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  permission_edit_documents: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð°Ð½Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
+  permission_delete_documents: Ð˜Ð·Ñ‚Ñ€Ð¸Ð²Ð°Ð½Ðµ Ð½Ð° Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
   permission_manage_files: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
   permission_view_files: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ Ð½Ð° Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ
   permission_manage_wiki: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð½Ð° wiki
@@ -569,8 +572,6 @@
   label_text: Ð”ÑŠÐ»ÑŠÐ³ Ñ‚ÐµÐºÑÑ‚
   label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
   label_attribute_plural: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸
-  label_download: "%{count} Ð¸Ð·Ñ‚ÐµÐ³Ð»ÑÐ½Ðµ"
-  label_download_plural: "%{count} Ð¸Ð·Ñ‚ÐµÐ³Ð»ÑÐ½Ð¸Ñ"
   label_no_data: ÐÑÐ¼Ð° Ð¸Ð·Ñ…Ð¾Ð´Ð½Ð¸ Ð´Ð°Ð½Ð½Ð¸
   label_change_status: ÐŸÑ€Ð¾Ð¼ÑÐ½Ð° Ð½Ð° ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸ÐµÑ‚Ð¾
   label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ
@@ -619,11 +620,12 @@
     one:   1 Ð·Ð°Ð´Ð°Ñ‡Ð°
     other: "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸"
   label_total: ÐžÐ±Ñ‰Ð¾
+  label_total_time: ÐžÐ±Ñ‰Ð¾
   label_permissions: ÐŸÑ€Ð°Ð²Ð°
   label_current_status: Ð¢ÐµÐºÑƒÑ‰Ð¾ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ðµ
   label_new_statuses_allowed: ÐŸÐ¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸ ÑÑŠÑÑ‚Ð¾ÑÐ½Ð¸Ñ
   label_all: Ð²ÑÐ¸Ñ‡ÐºÐ¸
-  label_any: ÐºÐ¾ÑÑ‚Ð¾ Ð¸ Ð´Ð° Ðµ
+  label_any: Ð±ÐµÐ· Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ
   label_none: Ð½Ð¸ÐºÐ°ÐºÐ²Ð¸
   label_nobody: Ð½Ð¸ÐºÐ¾Ð¹
   label_next: Ð¡Ð»ÐµÐ´Ð²Ð°Ñ‰
@@ -688,8 +690,6 @@
   label_repository_new: ÐÐ¾Ð²Ð¾ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
   label_repository_plural: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ð°
   label_browse: Ð Ð°Ð·Ð³Ð»ÐµÐ¶Ð´Ð°Ð½Ðµ
-  label_modification: "%{count} Ð¿Ñ€Ð¾Ð¼ÑÐ½Ð°"
-  label_modification_plural: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
   label_branch: Ñ€Ð°Ð±Ð¾Ñ‚ÐµÐ½ Ð²Ð°Ñ€Ð¸Ð°Ð½Ñ‚
   label_tag: Ð’ÐµÑ€ÑÐ¸Ñ
   label_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ
@@ -884,13 +884,16 @@
   label_readonly: Ð¡Ð°Ð¼Ð¾ Ð·Ð° Ñ‡ÐµÑ‚ÐµÐ½Ðµ
   label_required: Ð—Ð°Ð´ÑŠÐ»Ð¶Ð¸Ñ‚ÐµÐ»Ð½Ð¾
   label_attribute_of_project: Project's %{name}
+  label_attribute_of_issue: Issue's %{name}
   label_attribute_of_author: Author's %{name}
   label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_user: User's %{name}
   label_attribute_of_fixed_version: Target version's %{name}
   label_cross_project_descendants: Ð¡ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
   label_cross_project_tree: Ð¡ Ð´ÑŠÑ€Ð²Ð¾ Ð½Ð° Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸Ñ‚Ðµ
   label_cross_project_hierarchy: Ð¡ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð½Ð° Ð¹ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ
   label_cross_project_system: Ð¡ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
+  label_gantt_progress_line: Ð›Ð¸Ð½Ð¸Ñ Ð½Ð° Ð¸Ð·Ð¿ÑŠÐ»Ð½ÐµÐ½Ð¸ÐµÑ‚Ð¾
 
   button_login: Ð’Ñ…Ð¾Ð´
   button_submit: Ð˜Ð·Ð¿Ñ€Ð°Ñ‰Ð°Ð½Ðµ
@@ -1034,6 +1037,8 @@
   text_account_destroy_confirmation: "Ð¡Ð¸Ð³ÑƒÑ€ÐµÐ½/Ð½Ð° Ð»Ð¸ ÑÑ‚Ðµ, Ñ‡Ðµ Ð¶ÐµÐ»Ð°ÐµÑ‚Ðµ Ð´Ð° Ð¿Ñ€Ð¾Ð´ÑŠÐ»Ð¶Ð¸Ñ‚Ðµ?\nÐ’Ð°ÑˆÐ¸ÑÑ‚ Ð¿Ñ€Ð¾Ñ„Ð¸Ð» Ñ‰Ðµ Ð±ÑŠÐ´Ðµ Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½Ð°Ñ‚ Ð±ÐµÐ· Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚ Ð·Ð° Ð²ÑŠÐ·ÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ðµ."
   text_session_expiration_settings: "Ð’Ð½Ð¸Ð¼Ð°Ð½Ð¸Ðµ: Ð¿Ñ€Ð¾Ð¼ÑÐ½Ð°Ñ‚Ð° Ð½Ð° Ñ‚ÐµÐ·Ð¸ ÑƒÑÑ‚Ð°Ð½Ð¾Ð²ÑÐ²Ð°Ð½Ð¾Ñ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‚Ð¸ Ð²ÑÐ¸Ñ‡ÐºÐ¸ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¸ ÑÐµÑÐ¸Ð¸, Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÐµÐ»Ð½Ð¾ Ð¸ Ð²Ð°ÑˆÐ°Ñ‚Ð°."
   text_project_closed: Ð¢Ð¾Ð·Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚ Ðµ Ð·Ð°Ñ‚Ð²Ð¾Ñ€ÐµÐ½ Ð¸ Ðµ ÑÐ°Ð¼Ð¾ Ð·Ð° Ñ‡ÐµÑ‚ÐµÐ½Ðµ.
+  text_turning_multiple_off: ÐÐºÐ¾ Ð·Ð°Ð±Ñ€Ð°Ð½Ð¸Ñ‚Ðµ Ð²ÑŠÐ·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑ‚Ñ‚Ð° Ð·Ð° Ð¿Ð¾Ð²ÐµÑ‡Ðµ Ð¾Ñ‚ ÐµÐ´Ð½Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚, Ð¿Ð¾Ð²ÐµÑ‡ÐµÑ‚Ð¾ ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚Ð¸ Ñ‰Ðµ Ð±ÑŠÐ´Ð°Ñ‚
+    Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð½Ð°Ñ‚Ð¸ Ñ Ñ†ÐµÐ» Ð´Ð° Ð¾ÑÑ‚Ð°Ð½Ðµ ÑÐ°Ð¼Ð¾ Ð¿Ð¾ ÐµÐ´Ð½Ð° ÑÑ‚Ð¾Ð¹Ð½Ð¾ÑÑ‚ Ð·Ð° Ð¿Ð¾Ð»Ðµ.
 
   default_role_manager: ÐœÐµÐ½Ð¸Ð´Ð¶ÑŠÑ€
   default_role_developer: Ð Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸Ðº
diff -r 0a574315af3e -r 4f746d8966dd config/locales/bs.yml
--- a/config/locales/bs.yml
+++ b/config/locales/bs.yml
@@ -49,8 +49,8 @@
         one:   "oko 1 sahat"
         other: "oko %{count} sahata"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 sahat"
+        other: "%{count} sahata"
       x_days:
         one:   "1 dan"
         other: "%{count} dana"
@@ -198,8 +198,6 @@
   mail_subject_reminder: "%{count} aktivnost(i) u kaÅ¡njenju u narednim %{days} danima"
   mail_body_reminder: "%{count} aktivnost(i) koje su dodjeljenje vama u narednim %{days} danima:"
 
-  gui_validation_error: 1 greÅ¡ka
-  gui_validation_error_plural: "%{count} greÅ¡aka"
 
   field_name: Ime
   field_description: Opis
@@ -357,7 +355,6 @@
   permission_edit_own_time_entries: Ispravka svog utroÅ¡ka vremena
   permission_manage_news: Upravljaj novostima
   permission_comment_news: Komentiraj novosti
-  permission_manage_documents: Upravljaj dokumentima
   permission_view_documents: Pregled dokumenata
   permission_manage_files: Upravljaj fajlovima
   permission_view_files: Pregled fajlova
@@ -477,8 +474,6 @@
   label_text: Dugi tekst
   label_attribute: Atribut
   label_attribute_plural: Atributi
-  label_download: "%{count} download"
-  label_download_plural: "%{count} download-i"
   label_no_data: Nema podataka za prikaz
   label_change_status: Promjeni status
   label_history: Istorija
@@ -578,8 +573,6 @@
   label_repository: Repozitorij
   label_repository_plural: Repozitoriji
   label_browse: Listaj
-  label_modification: "%{count} promjena"
-  label_modification_plural: "%{count} promjene"
   label_revision: Revizija
   label_revision_plural: Revizije
   label_associated_revisions: Doddjeljene revizije
@@ -946,7 +939,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -987,8 +979,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1095,3 +1085,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ukupno
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/ca.yml
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -53,8 +53,8 @@
         one:   "aproximadament 1 hora"
         other: "aproximadament %{count} hores"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 hora"
+        other: "%{count} hores"
       x_days:
         one:   "1 dia"
         other: "%{count} dies"
@@ -209,8 +209,6 @@
   mail_subject_wiki_content_updated: "S'ha actualitzat la pÃ gina wiki Â«%{id}Â»"
   mail_body_wiki_content_updated: "En %{author} ha actualitzat la pÃ gina wiki Â«%{id}Â»."
 
-  gui_validation_error: 1 error
-  gui_validation_error_plural: "%{count} errors"
 
   field_name: Nom
   field_description: DescripciÃ³
@@ -388,7 +386,6 @@
   permission_edit_own_time_entries: Edita els registres de temps propis
   permission_manage_news: Gestiona les noticies
   permission_comment_news: Comenta les noticies
-  permission_manage_documents: Gestiona els documents
   permission_view_documents: Visualitza els documents
   permission_manage_files: Gestiona els fitxers
   permission_view_files: Visualitza els fitxers
@@ -514,8 +511,6 @@
   label_text: Text llarg
   label_attribute: Atribut
   label_attribute_plural: Atributs
-  label_download: "%{count} baixada"
-  label_download_plural: "%{count} baixades"
   label_no_data: Sense dades a mostrar
   label_change_status: "Canvia l'estat"
   label_history: Historial
@@ -618,8 +613,6 @@
   label_repository: DipÃ²sit
   label_repository_plural: DipÃ²sits
   label_browse: Navega
-  label_modification: "%{count} canvi"
-  label_modification_plural: "%{count} canvis"
   label_branch: Branca
   label_tag: Etiqueta
   label_revision: RevisiÃ³
@@ -935,7 +928,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -976,8 +968,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1084,3 +1074,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/cs.yml
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -55,8 +55,8 @@
         one:   "asi 1 hodina"
         other: "asi %{count} hodin"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 hodina"
+        other: "%{count} hodin"
       x_days:
         one:   "1 den"
         other: "%{count} dnÅ¯"
@@ -161,10 +161,10 @@
   notice_successful_update: ÃšspÄ›Å¡nÄ› aktualizovÃ¡no.
   notice_successful_delete: ÃšspÄ›Å¡nÄ› odstranÄ›no.
   notice_successful_connection: ÃšspÄ›Å¡nÃ© pÅ™ipojenÃ­.
-  notice_file_not_found: StrÃ¡nka na kterou se snaÅ¾Ã­te zobrazit neexistuje nebo byla smazÃ¡na.
+  notice_file_not_found: StrÃ¡nka, kterou se snaÅ¾Ã­te zobrazit, neexistuje nebo byla smazÃ¡na.
   notice_locking_conflict: Ãšdaje byly zmÄ›nÄ›ny jinÃ½m uÅ¾ivatelem.
   notice_not_authorized: NemÃ¡te dostateÄnÃ¡ prÃ¡va pro zobrazenÃ­ tÃ©to strÃ¡nky.
-  notice_not_authorized_archived_project: Projekt ke kterÃ©mu se snaÅ¾Ã­te pÅ™istupovat byl archivovÃ¡n.
+  notice_not_authorized_archived_project: Projekt, ke kterÃ©mu se snaÅ¾Ã­te pÅ™istupovat, byl archivovÃ¡n.
   notice_email_sent: "Na adresu %{value} byl odeslÃ¡n email"
   notice_email_error: "PÅ™i odesÃ­lÃ¡nÃ­ emailu nastala chyba (%{value})"
   notice_feeds_access_key_reseted: VÃ¡Å¡ klÃ­Ä pro pÅ™Ã­stup k RSS byl resetovÃ¡n.
@@ -175,7 +175,7 @@
   notice_account_pending: "VÃ¡Å¡ ÃºÄet byl vytvoÅ™en, nynÃ­ ÄekÃ¡ na schvÃ¡lenÃ­ administrÃ¡torem."
   notice_default_data_loaded: VÃ½chozÃ­ konfigurace ÃºspÄ›Å¡nÄ› nahrÃ¡na.
   notice_unable_delete_version: Nemohu odstanit verzi
-  notice_unable_delete_time_entry: Nelze smazat Äas ze zÃ¡znamu.
+  notice_unable_delete_time_entry: Nelze smazat zÃ¡znam Äasu.
   notice_issue_done_ratios_updated: Koeficienty dokonÄenÃ­ Ãºkolu byly aktualizovÃ¡ny.
   notice_gantt_chart_truncated: Graf byl oÅ™Ã­znut, poÄet poloÅ¾ek pÅ™esÃ¡hl limit pro zobrazenÃ­ (%{max})
 
@@ -185,15 +185,15 @@
   error_scm_annotate: "PoloÅ¾ka neexistuje nebo nemÅ¯Å¾e bÃ½t komentovÃ¡na."
   error_issue_not_found_in_project: 'Ãškol nebyl nalezen nebo nepatÅ™Ã­ k tomuto projektu'
   error_no_tracker_in_project: Å½Ã¡dnÃ¡ fronta nebyla pÅ™iÅ™azena tomuto projektu. ProsÃ­m zkontroluje nastavenÃ­ projektu.
-  error_no_default_issue_status: NenÃ­ nastaven vÃ½chozÃ­ stav Ãºkolu. ProsÃ­m zkontrolujte nastavenÃ­ ("Administrace -> Stavy ÃºkolÅ¯").
+  error_no_default_issue_status: NenÃ­ nastaven vÃ½chozÃ­ stav ÃºkolÅ¯. ProsÃ­m zkontrolujte nastavenÃ­ ("Administrace -> Stavy ÃºkolÅ¯").
   error_can_not_delete_custom_field: Nelze smazat volitelnÃ© pole
-  error_can_not_delete_tracker: Tato fronta obsahuje Ãºkoly a nemÅ¯Å¾e bÃ½t smazÃ¡n.
+  error_can_not_delete_tracker: Tato fronta obsahuje Ãºkoly a nemÅ¯Å¾e bÃ½t smazÃ¡na.
   error_can_not_remove_role: Tato role je prÃ¡vÄ› pouÅ¾Ã­vanÃ¡ a nelze ji smazat.
   error_can_not_reopen_issue_on_closed_version: Ãškol pÅ™iÅ™azenÃ½ k uzavÅ™enÃ© verzi nemÅ¯Å¾e bÃ½t znovu otevÅ™en
   error_can_not_archive_project: Tento projekt nemÅ¯Å¾e bÃ½t archivovÃ¡n
   error_issue_done_ratios_not_updated: Koeficient dokonÄenÃ­ Ãºkolu nebyl aktualizovÃ¡n.
-  error_workflow_copy_source: ProsÃ­m vyberte zdrojovou frontu nebo roly
-  error_workflow_copy_target: ProsÃ­m vyberte cÃ­lovou frontu(y) a roly(e)
+  error_workflow_copy_source: ProsÃ­m vyberte zdrojovou frontu nebo roli
+  error_workflow_copy_target: ProsÃ­m vyberte cÃ­lovou frontu(y) a roli(e)
   error_unable_delete_issue_status: Nelze smazat stavy ÃºkolÅ¯
   error_unable_to_connect: Nelze se pÅ™ipojit (%{value})
   warning_attachments_not_saved: "%{count} soubor(Å¯) nebylo moÅ¾nÃ© uloÅ¾it."
@@ -207,14 +207,12 @@
   mail_subject_account_activation_request: "Aktivace %{value} ÃºÄtu"
   mail_body_account_activation_request: "Byl zaregistrovÃ¡n novÃ½ uÅ¾ivatel %{value}. Aktivace jeho ÃºÄtu zÃ¡visÃ­ na vaÅ¡em potvrzenÃ­."
   mail_subject_reminder: "%{count} Ãºkol(Å¯) mÃ¡ termÃ­n bÄ›hem nÄ›kolik dnÃ­ (%{days})"
-  mail_body_reminder: "%{count} Ãºkol(Å¯), kterÃ© mÃ¡te pÅ™iÅ™azeny mÃ¡ termÃ­n bÄ›hem nÄ›kolik dnÃ­ (%{days}):"
+  mail_body_reminder: "%{count} Ãºkol(Å¯), kterÃ© mÃ¡te pÅ™iÅ™azeny mÃ¡ termÃ­n bÄ›hem nÄ›kolika dnÃ­ (%{days}):"
   mail_subject_wiki_content_added: "'%{id}' Wiki strÃ¡nka byla pÅ™idÃ¡na"
   mail_body_wiki_content_added: "'%{id}' Wiki strÃ¡nka byla pÅ™idÃ¡na od %{author}."
   mail_subject_wiki_content_updated: "'%{id}' Wiki strÃ¡nka byla aktualizovÃ¡na"
   mail_body_wiki_content_updated: "'%{id}' Wiki strÃ¡nka byla aktualizovÃ¡na od %{author}."
 
-  gui_validation_error: 1 chyba
-  gui_validation_error_plural: "%{count} chyb(y)"
 
   field_name: NÃ¡zev
   field_description: Popis
@@ -293,7 +291,7 @@
   field_issue_to: SouvisejÃ­cÃ­ Ãºkol
   field_delay: ZpoÅ¾dÄ›nÃ­
   field_assignable: Ãškoly mohou bÃ½t pÅ™iÅ™azeny tÃ©to roli
-  field_redirect_existing_links: PÅ™esmÄ›rovat stvÃ¡vajÃ­cÃ­ odkazy
+  field_redirect_existing_links: PÅ™esmÄ›rovat stÃ¡vajÃ­cÃ­ odkazy
   field_estimated_hours: OdhadovanÃ¡ doba
   field_column_names: Sloupce
   field_time_entries: ZaznamenanÃ½ Äas
@@ -323,7 +321,7 @@
   setting_attachment_max_size: MaximÃ¡lnÃ­ velikost pÅ™Ã­lohy
   setting_issues_export_limit: Limit pro export ÃºkolÅ¯
   setting_mail_from: OdesÃ­lat emaily z adresy
-  setting_bcc_recipients: PÅ™Ã­jemci skrytÃ© kopie (bcc)
+  setting_bcc_recipients: PÅ™Ã­jemci jako skrytÃ¡ kopie (bcc)
   setting_plain_text_mail: pouze prostÃ½ text (ne HTML)
   setting_host_name: JmÃ©no serveru
   setting_text_formatting: FormÃ¡tovÃ¡nÃ­ textu
@@ -339,8 +337,8 @@
   setting_time_format: FormÃ¡t Äasu
   setting_cross_project_issue_relations: Povolit vazby ÃºkolÅ¯ napÅ™Ã­Ä projekty
   setting_issue_list_default_columns: VÃ½chozÃ­ sloupce zobrazenÃ© v seznamu ÃºkolÅ¯
-  setting_emails_header: HlaviÄka emailÅ¯
-  setting_emails_footer: PatiÄka emailÅ¯
+  setting_emails_header: ZÃ¡hlavÃ­ emailÅ¯
+  setting_emails_footer: ZÃ¡patÃ­ emailÅ¯
   setting_protocol: Protokol
   setting_per_page_options: PovolenÃ© poÄty Å™Ã¡dkÅ¯ na strÃ¡nce
   setting_user_format: FormÃ¡t zobrazenÃ­ uÅ¾ivatele
@@ -353,7 +351,7 @@
   setting_sequential_project_identifiers: Generovat sekvenÄnÃ­ identifikÃ¡tory projektÅ¯
   setting_gravatar_enabled: PouÅ¾Ã­t uÅ¾ivatelskÃ© ikony Gravatar
   setting_gravatar_default: VÃ½chozÃ­ Gravatar
-  setting_diff_max_lines_displayed: MaximÃ¡lnÃ­ poÄet zobrazenÃ½ch Å™Ã¡dkÅ¯ rozdÃ­lÅ¯
+  setting_diff_max_lines_displayed: MaximÃ¡lnÃ­ poÄet zobrazenÃ½ch Å™Ã¡dkÅ¯ rozdÃ­lu
   setting_file_max_size_displayed: MaximÃ¡lnÃ­ velikost textovÃ½ch souborÅ¯ zobrazenÃ½ch pÅ™Ã­mo na strÃ¡nce
   setting_repository_log_display_limit: MaximÃ¡lnÃ­ poÄet revizÃ­ zobrazenÃ½ch v logu souboru
   setting_openid: UmoÅ¾nit pÅ™ihlaÅ¡ovÃ¡nÃ­ a registrace s OpenID
@@ -369,7 +367,7 @@
   setting_default_notification_option: VÃ½chozÃ­ nastavenÃ­ oznÃ¡menÃ­
   setting_commit_logtime_enabled: Povolit zapisovÃ¡nÃ­ Äasu
   setting_commit_logtime_activity_id: Aktivita pro zapsanÃ½ Äas
-  setting_gantt_items_limit: MaximÃ¡lnÃ­ poÄet poloÅ¾ek zobrazenÃ½ na ganttovÄ› grafu
+  setting_gantt_items_limit: MaximÃ¡lnÃ­ poÄet poloÅ¾ek zobrazenÃ½ na ganttovÄ› diagramu
 
   permission_add_project: VytvoÅ™it projekt
   permission_add_subprojects: VytvoÅ™it podprojekty
@@ -390,18 +388,17 @@
   permission_delete_issues: MazÃ¡nÃ­ ÃºkolÅ¯
   permission_manage_public_queries: SprÃ¡va veÅ™ejnÃ½ch dotazÅ¯
   permission_save_queries: UklÃ¡dÃ¡nÃ­ dotazÅ¯
-  permission_view_gantt: ZobrazenÃ© Ganttova diagramu
+  permission_view_gantt: ZobrazenÃ­ ganttova diagramu
   permission_view_calendar: ProhlÃ­Å¾enÃ­ kalendÃ¡Å™e
-  permission_view_issue_watchers: ZobrazenÃ­ seznamu sledujÃ­cÃ­h uÅ¾ivatelÅ¯
+  permission_view_issue_watchers: ZobrazenÃ­ seznamu sledujÃ­cÃ­ch uÅ¾ivatelÅ¯
   permission_add_issue_watchers: PÅ™idÃ¡nÃ­ sledujÃ­cÃ­ch uÅ¾ivatelÅ¯
-  permission_delete_issue_watchers: Smazat pÅ™ihlÃ­Å¾ejÃ­cÃ­
+  permission_delete_issue_watchers: Smazat sledujÃ­cÃ­ uÅ¾ivatele
   permission_log_time: ZaznamenÃ¡vÃ¡nÃ­ strÃ¡venÃ©ho Äasu
   permission_view_time_entries: ZobrazenÃ­ strÃ¡venÃ©ho Äasu
   permission_edit_time_entries: UpravovÃ¡nÃ­ zÃ¡znamÅ¯ o strÃ¡venÃ©m Äasu
   permission_edit_own_time_entries: UpravovÃ¡nÃ­ vlastnÃ­ch zÃ¡zamÅ¯ o strÃ¡venÃ©m Äase
   permission_manage_news: SpravovÃ¡nÃ­ novinek
   permission_comment_news: KomentovÃ¡nÃ­ novinek
-  permission_manage_documents: SprÃ¡va dokumentÅ¯
   permission_view_documents: ProhlÃ­Å¾enÃ­ dokumentÅ¯
   permission_manage_files: SpravovÃ¡nÃ­ souborÅ¯
   permission_view_files: ProhlÃ­Å¾enÃ­ souborÅ¯
@@ -425,7 +422,7 @@
   permission_delete_messages: MazÃ¡nÃ­ zprÃ¡v
   permission_delete_own_messages: Smazat vlastnÃ­ zprÃ¡vy
   permission_export_wiki_pages: Exportovat Wiki strÃ¡nky
-  permission_manage_subtasks: Spravovat podÃºkoly
+  permission_manage_subtasks: Spravovat dÃ­lÄÃ­ Ãºkoly
 
   project_module_issue_tracking: SledovÃ¡nÃ­ ÃºkolÅ¯
   project_module_time_tracking: SledovÃ¡nÃ­ Äasu
@@ -486,7 +483,7 @@
   label_enumeration_new: NovÃ¡ hodnota
   label_information: Informace
   label_information_plural: Informace
-  label_please_login: ProsÃ­m pÅ™ihlaÅ¡te se
+  label_please_login: PÅ™ihlaÅ¡te se, prosÃ­m
   label_register: Registrovat
   label_login_with_open_id_option: nebo se pÅ™ihlaÅ¡te s OpenID
   label_password_lost: ZapomenutÃ© heslo
@@ -527,8 +524,6 @@
   label_text: DlouhÃ½ text
   label_attribute: Atribut
   label_attribute_plural: Atributy
-  label_download: "%{count} staÅ¾enÃ­"
-  label_download_plural: "%{count} staÅ¾enÃ­"
   label_no_data: Å½Ã¡dnÃ© poloÅ¾ky
   label_change_status: ZmÄ›nit stav
   label_history: Historie
@@ -586,7 +581,7 @@
   label_per_page: Na strÃ¡nku
   label_calendar: KalendÃ¡Å™
   label_months_from: mÄ›sÃ­cÅ¯ od
-  label_gantt: GanttÅ¯v graf
+  label_gantt: GanttÅ¯v diagram
   label_internal: InternÃ­
   label_last_changes: "poslednÃ­ch %{count} zmÄ›n"
   label_change_view_all: Zobrazit vÅ¡echny zmÄ›ny
@@ -631,8 +626,6 @@
   label_repository: RepozitÃ¡Å™
   label_repository_plural: RepozitÃ¡Å™e
   label_browse: ProchÃ¡zet
-  label_modification: "%{count} zmÄ›na"
-  label_modification_plural: "%{count} zmÄ›n"
   label_branch: VÄ›tev
   label_tag: Tag
   label_revision: Revize
@@ -695,9 +688,9 @@
   label_relation_delete: Odstranit souvislost
   label_relates_to: souvisejÃ­cÃ­ s
   label_duplicates: duplikuje
-  label_duplicated_by: zduplikovÃ¡n
+  label_duplicated_by: duplikovÃ¡n
   label_blocks: blokuje
-  label_blocked_by: zablokovÃ¡n
+  label_blocked_by: blokovÃ¡n
   label_precedes: pÅ™edchÃ¡zÃ­
   label_follows: nÃ¡sleduje
   label_end_to_start: od konce do zaÄÃ¡tku
@@ -706,12 +699,12 @@
   label_start_to_end: od zaÄÃ¡tku do konce
   label_stay_logged_in: ZÅ¯stat pÅ™ihlÃ¡Å¡enÃ½
   label_disabled: zakÃ¡zÃ¡n
-  label_show_completed_versions: UkÃ¡zat dokonÄenÃ© verze
+  label_show_completed_versions: Zobrazit dokonÄenÃ© verze
   label_me: jÃ¡
   label_board: FÃ³rum
   label_board_new: NovÃ© fÃ³rum
   label_board_plural: FÃ³ra
-  label_board_locked: UzamÄeno
+  label_board_locked: ZamÄeno
   label_board_sticky: NÃ¡lepka
   label_topic_plural: TÃ©mata
   label_message_plural: ZprÃ¡vy
@@ -725,7 +718,7 @@
   label_week: TÃ½den
   label_date_from: Od
   label_date_to: Do
-  label_language_based: Podle vÃ½chozÃ­ho jazyku
+  label_language_based: Podle vÃ½chozÃ­ho jazyka
   label_sort_by: "SeÅ™adit podle %{value}"
   label_send_test_email: Poslat testovacÃ­ email
   label_feeds_access_key: PÅ™Ã­stupovÃ½ klÃ­Ä pro RSS
@@ -737,7 +730,7 @@
   label_updated_time: "AktualizovÃ¡no pÅ™ed %{value}"
   label_jump_to_a_project: Vyberte projekt...
   label_file_plural: Soubory
-  label_changeset_plural: Changesety
+  label_changeset_plural: Sady zmÄ›n
   label_default_columns: VÃ½chozÃ­ sloupce
   label_no_change_option: (beze zmÄ›ny)
   label_bulk_edit_selected_issues: HromadnÃ¡ Ãºprava vybranÃ½ch ÃºkolÅ¯
@@ -747,9 +740,9 @@
   label_user_mail_option_all: "Pro vÅ¡echny udÃ¡losti vÅ¡ech mÃ½ch projektÅ¯"
   label_user_mail_option_selected: "Pro vÅ¡echny udÃ¡losti vybranÃ½ch projektÅ¯..."
   label_user_mail_option_none: "Å½Ã¡dnÃ© udÃ¡losti"
-  label_user_mail_option_only_my_events: "Jen pro vÄ›ci co sleduji nebo jsem v nich zapojen"
-  label_user_mail_option_only_assigned: "Jen pro vÅ¡eci kterÃ½m sem pÅ™iÅ™azen"
-  label_user_mail_option_only_owner: "Jen pro vÄ›ci kterÃ© vlastnÃ­m"
+  label_user_mail_option_only_my_events: "Jen pro vÄ›ci, co sleduji nebo jsem v nich zapojen"
+  label_user_mail_option_only_assigned: "Jen pro vÄ›ci, ke kterÃ½m sem pÅ™iÅ™azen"
+  label_user_mail_option_only_owner: "Jen pro vÄ›ci, kterÃ© vlastnÃ­m"
   label_user_mail_no_self_notified: "NezasÃ­lat informace o mnou vytvoÅ™enÃ½ch zmÄ›nÃ¡ch"
   label_registration_activation_by_email: aktivace ÃºÄtu emailem
   label_registration_manual_activation: manuÃ¡lnÃ­ aktivace ÃºÄtu
@@ -798,7 +791,7 @@
   label_missing_api_access_key: ChybÄ›jÃ­cÃ­ pÅ™Ã­stupovÃ½ klÃ­Ä API
   label_api_access_key_created_on: API pÅ™Ã­stupovÃ½ klÃ­Ä vytvoÅ™en %{value}
   label_profile: Profil
-  label_subtask_plural: PodÃºkol
+  label_subtask_plural: DÃ­lÄÃ­ Ãºkoly
   label_project_copy_notifications: Odeslat email oznÃ¡menÃ­ v prÅ¯bÄ›hu kopie projektu
   label_principal_search: "Hledat uÅ¾ivatele nebo skupinu:"
   label_user_search: "Hledat uÅ¾ivatele:"
@@ -835,7 +828,7 @@
   button_unwatch: Nesledovat
   button_reply: OdpovÄ›dÄ›t
   button_archive: Archivovat
-  button_unarchive: Odarchivovat
+  button_unarchive: Dearchivovat
   button_reset: Resetovat
   button_rename: PÅ™ejmenovat
   button_change_password: ZmÄ›nit heslo
@@ -850,18 +843,18 @@
 
   status_active: aktivnÃ­
   status_registered: registrovanÃ½
-  status_locked: uzamÄenÃ½
+  status_locked: zamÄenÃ½
 
   version_status_open: otevÅ™enÃ½
-  version_status_locked: uzamÄenÃ½
+  version_status_locked: zamÄenÃ½
   version_status_closed: zavÅ™enÃ½
 
   field_active: AktivnÃ­
 
-  text_select_mail_notifications: Vyberte akci pÅ™i kterÃ© bude zaslÃ¡no upozornÄ›nÃ­ emailem.
+  text_select_mail_notifications: Vyberte akci, pÅ™i kterÃ© bude zaslÃ¡no upozornÄ›nÃ­ emailem.
   text_regexp_info: napÅ™. ^[A-Z0-9]+$
   text_min_max_length_info: 0 znamenÃ¡ bez limitu
-  text_project_destroy_confirmation: Jste si jisti, Å¾e chcete odstranit tento projekt a vÅ¡echna souvisejÃ­cÃ­ data ?
+  text_project_destroy_confirmation: Jste si jisti, Å¾e chcete odstranit tento projekt a vÅ¡echna souvisejÃ­cÃ­ data?
   text_subprojects_destroy_warning: "Jeho podprojek(y): %{value} budou takÃ© smazÃ¡ny."
   text_workflow_edit: Vyberte roli a frontu k editaci prÅ¯bÄ›hu prÃ¡ce
   text_are_you_sure: Jste si jisti?
@@ -879,7 +872,7 @@
   text_unallowed_characters: NepovolenÃ© znaky
   text_comma_separated: Povoleno vÃ­ce hodnot (oddÄ›lÄ›nÃ© ÄÃ¡rkou).
   text_line_separated: VÃ­ce hodnot povoleno (jeden Å™Ã¡dek pro kaÅ¾dou hodnotu).
-  text_issues_ref_in_commit_messages: OdkazovÃ¡nÃ­ a opravovÃ¡nÃ­ ÃºkolÅ¯ ve zprÃ¡vÃ¡ch commitÅ¯
+  text_issues_ref_in_commit_messages: OdkazovÃ¡nÃ­ a opravovÃ¡nÃ­ ÃºkolÅ¯ v poznÃ¡mkÃ¡ch commitÅ¯
   text_issue_added: "Ãškol %{id} byl vytvoÅ™en uÅ¾ivatelem %{author}."
   text_issue_updated: "Ãškol %{id} byl aktualizovÃ¡n uÅ¾ivatelem %{author}."
   text_wiki_destroy_confirmation: Opravdu si pÅ™ejete odstranit tuto Wiki a celÃ½ jejÃ­ obsah?
@@ -889,30 +882,30 @@
   text_user_mail_option: "U projektÅ¯, kterÃ© nebyly vybrÃ¡ny, budete dostÃ¡vat oznÃ¡menÃ­ pouze o vaÅ¡ich Äi o sledovanÃ½ch poloÅ¾kÃ¡ch (napÅ™. o poloÅ¾kÃ¡ch jejichÅ¾ jste autor nebo ke kterÃ½m jste pÅ™iÅ™azen(a))."
   text_no_configuration_data: "Role, fronty, stavy ÃºkolÅ¯ ani prÅ¯bÄ›h prÃ¡ce nebyly zatÃ­m nakonfigurovÃ¡ny.\nVelice doporuÄujeme nahrÃ¡t vÃ½chozÃ­ konfiguraci. Po tÃ© si mÅ¯Å¾ete vÅ¡e upravit"
   text_load_default_configuration: NahrÃ¡t vÃ½chozÃ­ konfiguraci
-  text_status_changed_by_changeset: "PouÅ¾ito v changesetu %{value}."
-  text_time_logged_by_changeset: AplikovÃ¡no v changesetu %{value}.
+  text_status_changed_by_changeset: "PouÅ¾ito v sadÄ› zmÄ›n %{value}."
+  text_time_logged_by_changeset: AplikovÃ¡no v sadÄ› zmÄ›n %{value}.
   text_issues_destroy_confirmation: 'Opravdu si pÅ™ejete odstranit vÅ¡echny zvolenÃ© Ãºkoly?'
   text_select_project_modules: 'AktivnÃ­ moduly v tomto projektu:'
   text_default_administrator_account_changed: VÃ½chozÃ­ nastavenÃ­ administrÃ¡torskÃ©ho ÃºÄtu zmÄ›nÄ›no
   text_file_repository_writable: Povolen zÃ¡pis do adresÃ¡Å™e uklÃ¡dÃ¡nÃ­ souborÅ¯
   text_plugin_assets_writable: MoÅ¾nost zÃ¡pisu do adresÃ¡Å™e plugin assets
   text_rmagick_available: RMagick k dispozici (volitelnÃ©)
-  text_destroy_time_entries_question: "U ÃºkolÅ¯, kterÃ© chcete odstranit je evidovÃ¡no %{hours} prÃ¡ce. Co chete udÄ›lat?"
-  text_destroy_time_entries: Odstranit evidovanÃ© hodiny.
-  text_assign_time_entries_to_project: PÅ™iÅ™adit evidovanÃ© hodiny projektu
-  text_reassign_time_entries: 'PÅ™eÅ™adit evidovanÃ© hodiny k tomuto Ãºkolu:'
+  text_destroy_time_entries_question: "U ÃºkolÅ¯, kterÃ© chcete odstranit, je evidovÃ¡no %{hours} prÃ¡ce. Co chete udÄ›lat?"
+  text_destroy_time_entries: Odstranit zaznamenanÃ© hodiny.
+  text_assign_time_entries_to_project: PÅ™iÅ™adit zaznamenanÃ© hodiny projektu
+  text_reassign_time_entries: 'PÅ™eÅ™adit zaznamenanÃ© hodiny k tomuto Ãºkolu:'
   text_user_wrote: "%{value} napsal:"
   text_enumeration_destroy_question: "NÄ›kolik (%{count}) objektÅ¯ je pÅ™iÅ™azeno k tÃ©to hodnotÄ›."
   text_enumeration_category_reassign_to: 'PÅ™eÅ™adit je do tÃ©to:'
   text_email_delivery_not_configured: "DoruÄovÃ¡nÃ­ e-mailÅ¯ nenÃ­ nastaveno a odesÃ­lÃ¡nÃ­ notifikacÃ­ je zakÃ¡zÃ¡no.\nNastavte VÃ¡Å¡ SMTP server v souboru config/configuration.yml a restartujte aplikaci."
-  text_repository_usernames_mapping: "Vybrat nebo upravit mapovÃ¡nÃ­ mezi Redmine uÅ¾ivateli a uÅ¾ivatelskÃ½mi jmÃ©ny nalezenÃ½mi v logu repozitÃ¡Å™e.\nUÅ¾ivatelÃ© se shodnÃ½m Redmine uÅ¾ivatelskÃ½m jmÃ©nem a uÅ¾ivatelskÃ½m jmÃ©nem v repozitÃ¡Å™i jsou mapovanÃ­ automaticky."
+  text_repository_usernames_mapping: "Vybrat nebo upravit mapovÃ¡nÃ­ mezi Redmine uÅ¾ivateli a uÅ¾ivatelskÃ½mi jmÃ©ny nalezenÃ½mi v logu repozitÃ¡Å™e.\nUÅ¾ivatelÃ© se shodnÃ½m Redmine uÅ¾ivatelskÃ½m jmÃ©nem a uÅ¾ivatelskÃ½m jmÃ©nem v repozitÃ¡Å™i jsou mapovÃ¡ni automaticky."
   text_diff_truncated: '... RozdÃ­lovÃ½ soubor je zkrÃ¡cen, protoÅ¾e jeho dÃ©lka pÅ™esahuje max. limit.'
   text_custom_field_possible_values_info: 'KaÅ¾dÃ¡ hodnota na novÃ©m Å™Ã¡dku'
   text_wiki_page_destroy_question: Tato strÃ¡nka mÃ¡ %{descendants} podstrÃ¡nek a potomkÅ¯. Co chcete udÄ›lat?
   text_wiki_page_nullify_children: Ponechat podstrÃ¡nky jako koÅ™enovÃ© strÃ¡nky
   text_wiki_page_destroy_children: Smazat podstrÃ¡nky a vÅ¡echny jejich potomky
   text_wiki_page_reassign_children: PÅ™iÅ™adit podstrÃ¡nky k tomuto rodiÄi
-  text_own_membership_delete_confirmation: "ChystÃ¡te se odebrat si nÄ›kterÃ¡ nebo vÅ¡echny svÃ¡ oprÃ¡vnÄ›nÃ­ a potom jiÅ¾ nemusÃ­te bÃ½t schopni upravit tento projekt.\nOpravdu chcete pokraÄovat?"
+  text_own_membership_delete_confirmation: "ChystÃ¡te se odebrat si nÄ›kterÃ¡ nebo vÅ¡echna svÃ¡ oprÃ¡vnÄ›nÃ­, potom jiÅ¾ nemusÃ­te bÃ½t schopni upravit tento projekt.\nOpravdu chcete pokraÄovat?"
   text_zoom_in: PÅ™iblÃ­Å¾it
   text_zoom_out: OddÃ¡lit
 
@@ -966,7 +959,7 @@
   field_is_private: SoukromÃ½
   permission_set_issues_private: Nastavit Ãºkoly jako veÅ™ejnÃ© nebo soukromÃ©
   label_issues_visibility_public: VÅ¡echny Ãºkoly, kterÃ© nejsou soukromÃ©
-  text_issues_destroy_descendants_confirmation: "%{count} podÃºkol(Å¯) bude rovnÄ›Å¾ smazÃ¡n(o)."
+  text_issues_destroy_descendants_confirmation: "%{count} dÃ­lÄÃ­(ch) Ãºkol(Å¯) bude rovnÄ›Å¾ smazÃ¡n(o)."
   field_commit_logs_encoding: KÃ³dovÃ¡nÃ­ zprÃ¡v pÅ™i commitu
   field_scm_path_encoding: KÃ³dovÃ¡nÃ­ cesty SCM
   text_scm_path_encoding_note: "VÃ½chozÃ­: UTF-8"
@@ -1004,14 +997,14 @@
   description_selected_columns: VybranÃ½ sloupec
   label_parent_revision: RodiÄ
   label_child_revision: Potomek
-  error_scm_annotate_big_text_file: Vstup nemÅ¯Å¾e bÃ½t anotovÃ¡n, protoÅ¾e pÅ™ekraÄuje povolenou velikost textovÃ©ho souboru
+  error_scm_annotate_big_text_file: Vstup nemÅ¯Å¾e bÃ½t komentovÃ¡n, protoÅ¾e pÅ™ekraÄuje povolenou velikost textovÃ©ho souboru
   setting_default_issue_start_date_to_creation_date: PouÅ¾ij aktuÃ¡lnÃ­ datum jako poÄÃ¡teÄnÃ­ datum pro novÃ© Ãºkoly
-  button_edit_section: Uprav tuto sekci
+  button_edit_section: Uprav tuto ÄÃ¡st
   setting_repositories_encodings: KÃ³dovÃ¡nÃ­ pÅ™Ã­loh a repositÃ¡Å™Å¯
   description_all_columns: VÅ¡echny sloupce
   button_export: Export
   label_export_options: "nastavenÃ­ exportu %{export_format}"
-  error_attachment_too_big: Soubor nemÅ¯Å¾e bÃ½t nahrÃ¡n, protoÅ¾e jeho velikost je vÄ›tÅ¡Ã­ neÅ¾ maximum (%{max_size})
+  error_attachment_too_big: Soubor nemÅ¯Å¾e bÃ½t nahrÃ¡n, protoÅ¾e jeho velikost je vÄ›tÅ¡Ã­ neÅ¾ maximÃ¡lnÃ­ (%{max_size})
   notice_failed_to_save_time_entries: "Chyba pÅ™i uklÃ¡dÃ¡nÃ­ %{count} Äasov(Ã½ch/Ã©ho) zÃ¡znam(Å¯) z %{total} vybranÃ©ho: %{ids}."
   label_x_issues:
     zero:  0 Ãškol
@@ -1024,7 +1017,7 @@
   label_completed_versions: DokonÄenÃ© verze
   text_project_identifier_info: Jsou povolena pouze malÃ¡ pÃ­smena (a-z), ÄÃ­slice, pomlÄky a podtrÅ¾Ã­tka.<br />Po uloÅ¾enÃ­ jiÅ¾ nelze identifikÃ¡tor mÄ›nit.
   field_multiple: VÃ­ce hodnot
-  setting_commit_cross_project_ref: Povolit reference a opravy ÃºklÅ¯ ze vÅ¡ech ostatnÃ­ch projektÅ¯
+  setting_commit_cross_project_ref: Povolit reference a opravy ÃºkolÅ¯ ze vÅ¡ech ostatnÃ­ch projektÅ¯
   text_issue_conflict_resolution_add_notes: PÅ™idat moje poznÃ¡mky a zahodit ostatnÃ­ zmÄ›ny
   text_issue_conflict_resolution_overwrite: PÅ™esto pÅ™ijmout moje Ãºpravy (pÅ™edchozÃ­ poznÃ¡mky budou zachovÃ¡ny, ale nÄ›kterÃ© zmÄ›ny mohou bÃ½t pÅ™epsÃ¡ny)
   notice_issue_update_conflict: BÄ›hem vaÅ¡ich Ãºprav byl Ãºkol aktualizovÃ¡n jinÃ½m uÅ¾ivatelem.
@@ -1066,18 +1059,18 @@
   label_attribute_of_author: Autorovo %{name}
   label_attribute_of_assigned_to: "%{name} pÅ™iÅ™azenÃ©(ho)"
   label_attribute_of_fixed_version: CÃ­lovÃ¡ verze %{name}
-  label_copy_subtasks: KopÃ­rovat podÃºkoly
+  label_copy_subtasks: KopÃ­rovat dÃ­lÄÃ­ Ãºkoly
   label_copied_to: zkopÃ­rovÃ¡no do
   label_copied_from: zkopÃ­rovÃ¡no z
   label_any_issues_in_project: jakÃ©koli Ãºkoly v projektu
-  label_any_issues_not_in_project: jakÃ©koli Ãºkoly mimo projektu
+  label_any_issues_not_in_project: jakÃ©koli Ãºkoly mimo projekt
   field_private_notes: SoukromÃ© poznÃ¡mky
   permission_view_private_notes: Zobrazit soukromÃ© poznÃ¡mky
   permission_set_notes_private: Nastavit poznÃ¡mky jako soukromÃ©
   label_no_issues_in_project: Å¾Ã¡dnÃ© Ãºkoly v projektu
   label_any: vÅ¡e
   label_last_n_weeks: poslednÃ­ %{count} tÃ½dny
-  setting_cross_project_subtasks: Povolit podÃºkoly napÅ™Ã­Ä projekty
+  setting_cross_project_subtasks: Povolit dÃ­lÄÃ­ Ãºkoly napÅ™Ã­Ä projekty
   label_cross_project_descendants: S podprojekty
   label_cross_project_tree: Se stromem projektu
   label_cross_project_hierarchy: S hierarchiÃ­ projektu
@@ -1086,3 +1079,16 @@
   setting_non_working_week_days: Dny pracovnÃ­ho volna/klidu
   label_in_the_next_days: v pÅ™Ã­stÃ­ch
   label_in_the_past_days: v minulÃ½ch
+  label_attribute_of_user: "%{name} uÅ¾ivatel(e/ky)"
+  text_turning_multiple_off: JestliÅ¾e zakÃ¡Å¾ete vÃ­ce hodnot, 
+    hodnoty budou smazÃ¡ny za ÃºÄelem rezervace pouze jedinÃ© hodnoty na poloÅ¾ku.    
+  label_attribute_of_issue: "%{name} Ãºkolu"
+  permission_add_documents: PÅ™idat dokument
+  permission_edit_documents: Upravit dokumenty
+  permission_delete_documents: Smazet dokumenty
+  label_gantt_progress_line: VÃ½vojovÃ¡ ÄÃ¡ra
+  setting_jsonp_enabled: Povolit podporu JSONP
+  field_inherit_members: ZdÄ›dit Äleny
+  field_closed_on: UzavÅ™eno
+  setting_default_projects_tracker_ids: VÃ½chozÃ­ fronta pro novÃ© projekty
+  label_total_time: Celkem
diff -r 0a574315af3e -r 4f746d8966dd config/locales/da.yml
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -52,8 +52,8 @@
         one:  "cirka en time"
         other: "cirka %{count} timer"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 time"
+        other: "%{count} timer"
       x_days:
         one:  "en dag"
         other: "%{count} dage"
@@ -197,8 +197,6 @@
   mail_subject_account_activation_request: "%{value} kontoaktivering"
   mail_body_account_activation_request: "En ny bruger (%{value}) er registreret. Godkend venligst kontoen:"
 
-  gui_validation_error: 1 fejl
-  gui_validation_error_plural: "%{count} fejl"
 
   field_name: Navn
   field_description: Beskrivelse
@@ -401,8 +399,6 @@
   label_text: Lang tekst
   label_attribute: Attribut
   label_attribute_plural: Attributter
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
   label_no_data: Ingen data at vise
   label_change_status: Ã†ndringsstatus
   label_history: Historik
@@ -502,8 +498,6 @@
   label_repository: Repository
   label_repository_plural: Repositories
   label_browse: Gennemse
-  label_modification: "%{count} Ã¦ndring"
-  label_modification_plural: "%{count} Ã¦ndringer"
   label_revision: Revision
   label_revision_plural: Revisioner
   label_associated_revisions: Tilknyttede revisioner
@@ -760,7 +754,6 @@
   field_parent_title: Siden over
   text_email_delivery_not_configured: "Email-afsendelse er ikke indstillet og notifikationer er defor slÃ¥et fra.\nKonfigurÃ©r din SMTP server i config/configuration.yml og genstart applikationen for at aktivere email-afsendelse."
   permission_protect_wiki_pages: Beskyt wiki sider
-  permission_manage_documents: AdministrÃ©r dokumenter
   permission_add_issue_watchers: TilfÃ¸j overvÃ¥gere
   warning_attachments_not_saved: "der var %{count} fil(er), som ikke kunne gemmes."
   permission_comment_news: KommentÃ©r nyheder
@@ -949,7 +942,6 @@
   label_principal_search: "SÃ¸g efter bruger eller gruppe:"
   label_user_search: "SÃ¸g efter bruger:"
   field_visible: Synlig
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Aktivitet for registreret tid
   text_time_logged_by_changeset: Anvendt i changeset %{value}.
   setting_commit_logtime_enabled: Aktiver tidsregistrering
@@ -991,8 +983,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1099,3 +1089,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/de.yml
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -53,8 +53,8 @@
         one: 'etwa 1 Stunde'
         other: 'etwa %{count} Stunden'
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 Stunde"
+        other: "%{count} Stunden"
       x_days:
         one: '1 Tag'
         other: '%{count} Tagen'
@@ -144,957 +144,959 @@
         greater_than_start_date: "muss grÃ¶ÃŸer als Anfangsdatum sein"
         not_same_project: "gehÃ¶rt nicht zum selben Projekt"
         circular_dependency: "Diese Beziehung wÃ¼rde eine zyklische AbhÃ¤ngigkeit erzeugen"
-        cant_link_an_issue_with_a_descendant: "Ein Ticket kann nicht mit einer ihrer Unteraufgaben verlinkt werden"
+        cant_link_an_issue_with_a_descendant: "Ein Ticket kann nicht mit einer Ihrer Unteraufgaben verlinkt werden"
 
   actionview_instancetag_blank_option: Bitte auswÃ¤hlen
 
+  button_activate: Aktivieren
+  button_add: HinzufÃ¼gen
+  button_annotate: Annotieren
+  button_apply: Anwenden
+  button_archive: Archivieren
+  button_back: ZurÃ¼ck
+  button_cancel: Abbrechen
+  button_change: Wechseln
+  button_change_password: Kennwort Ã¤ndern
+  button_check_all: Alles auswÃ¤hlen
+  button_clear: ZurÃ¼cksetzen
+  button_close: SchlieÃŸen
+  button_collapse_all: Alle einklappen
+  button_configure: Konfigurieren
+  button_copy: Kopieren
+  button_copy_and_follow: Kopieren und Ticket anzeigen
+  button_create: Anlegen
+  button_create_and_continue: Anlegen und weiter
+  button_delete: LÃ¶schen
+  button_delete_my_account: Mein Benutzerkonto lÃ¶schen 
+  button_download: Download
+  button_duplicate: Duplizieren
+  button_edit: Bearbeiten
+  button_edit_associated_wikipage: "ZugehÃ¶rige Wikiseite bearbeiten: %{page_title}"
+  button_edit_section: Diesen Bereich bearbeiten
+  button_expand_all: Alle ausklappen
+  button_export: Exportieren
+  button_hide: Verstecken
+  button_list: Liste
+  button_lock: Sperren
+  button_log_time: Aufwand buchen
+  button_login: Anmelden
+  button_move: Verschieben
+  button_move_and_follow: Verschieben und Ticket anzeigen
+  button_quote: Zitieren
+  button_rename: Umbenennen
+  button_reopen: Ã–ffnen
+  button_reply: Antworten
+  button_reset: ZurÃ¼cksetzen
+  button_rollback: Auf diese Version zurÃ¼cksetzen
+  button_save: Speichern
+  button_show: Anzeigen
+  button_sort: Sortieren
+  button_submit: OK
+  button_test: Testen
+  button_unarchive: Entarchivieren
+  button_uncheck_all: Alles abwÃ¤hlen
+  button_unlock: Entsperren
+  button_unwatch: Nicht beobachten
+  button_update: Bearbeiten
+  button_view: Anzeigen
+  button_watch: Beobachten
+
+  default_activity_design: Design
+  default_activity_development: Entwicklung
+  default_doc_category_tech: Technische Dokumentation
+  default_doc_category_user: Benutzerdokumentation
+  default_issue_status_closed: Erledigt
+  default_issue_status_feedback: Feedback
+  default_issue_status_in_progress: In Bearbeitung
+  default_issue_status_new: Neu
+  default_issue_status_rejected: Abgewiesen
+  default_issue_status_resolved: GelÃ¶st
+  default_priority_high: Hoch
+  default_priority_immediate: Sofort
+  default_priority_low: Niedrig
+  default_priority_normal: Normal
+  default_priority_urgent: Dringend
+  default_role_developer: Entwickler
+  default_role_manager: Manager
+  default_role_reporter: Reporter
+  default_tracker_bug: Fehler
+  default_tracker_feature: Feature
+  default_tracker_support: UnterstÃ¼tzung
+
+  description_all_columns: Alle Spalten
+  description_available_columns: VerfÃ¼gbare Spalten
+  description_choose_project: Projekte
+  description_date_from: Startdatum eintragen
+  description_date_range_interval: Zeitraum durch Start- und Enddatum festlegen
+  description_date_range_list: Zeitraum aus einer Liste wÃ¤hlen
+  description_date_to: Enddatum eintragen
+  description_filter: Filter
+  description_issue_category_reassign: Neue Kategorie wÃ¤hlen
+  description_message_content: Nachrichteninhalt
+  description_notes: Kommentare
+  description_project_scope: Suchbereich
+  description_query_sort_criteria_attribute: Sortierattribut
+  description_query_sort_criteria_direction: Sortierrichtung
+  description_search: Suchfeld
+  description_selected_columns: AusgewÃ¤hlte Spalten
+  description_user_mail_notification: Mailbenachrichtigungseinstellung
+  description_wiki_subpages_reassign: Neue Elternseite wÃ¤hlen
+
+  enumeration_activities: AktivitÃ¤ten (Zeiterfassung)
+  enumeration_doc_categories: Dokumentenkategorien
+  enumeration_issue_priorities: Ticket-PrioritÃ¤ten
+  enumeration_system_activity: System-AktivitÃ¤t
+
+  error_attachment_too_big: Diese Datei kann nicht hochgeladen werden, da sie die maximale DateigrÃ¶ÃŸe von (%{max_size}) Ã¼berschreitet.
+  error_can_not_archive_project: Dieses Projekt kann nicht archiviert werden.
+  error_can_not_delete_custom_field: Kann das benutzerdefinierte Feld nicht lÃ¶schen.
+  error_can_not_delete_tracker: Dieser Tracker enthÃ¤lt Tickets und kann nicht gelÃ¶scht werden.
+  error_can_not_remove_role: Diese Rolle wird verwendet und kann nicht gelÃ¶scht werden.
+  error_can_not_reopen_issue_on_closed_version: Das Ticket ist einer abgeschlossenen Version zugeordnet und kann daher nicht wieder geÃ¶ffnet werden.
+  error_can_t_load_default_data: "Die Standard-Konfiguration konnte nicht geladen werden: %{value}"
+  error_issue_done_ratios_not_updated: Der Ticket-Fortschritt wurde nicht aktualisiert.
+  error_issue_not_found_in_project: 'Das Ticket wurde nicht gefunden oder gehÃ¶rt nicht zu diesem Projekt.'
+  error_no_default_issue_status: Es ist kein Status als Standard definiert. Bitte Ã¼berprÃ¼fen Sie Ihre Konfiguration (unter "Administration -> Ticket-Status").
+  error_no_tracker_in_project: Diesem Projekt ist kein Tracker zugeordnet. Bitte Ã¼berprÃ¼fen Sie die Projekteinstellungen.
+  error_scm_annotate: "Der Eintrag existiert nicht oder kann nicht annotiert werden."
+  error_scm_annotate_big_text_file: Der Eintrag kann nicht umgesetzt werden, da er die maximale TextlÃ¤nge Ã¼berschreitet.
+  error_scm_command_failed: "Beim Zugriff auf das Projektarchiv ist ein Fehler aufgetreten: %{value}"
+  error_scm_not_found: Eintrag und/oder Revision existiert nicht im Projektarchiv.
+  error_session_expired: Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.
+  error_unable_delete_issue_status: "Der Ticket-Status konnte nicht gelÃ¶scht werden."
+  error_unable_to_connect: Fehler beim Verbinden (%{value})
+  error_workflow_copy_source: Bitte wÃ¤hlen Sie einen Quell-Tracker und eine Quell-Rolle.
+  error_workflow_copy_target: Bitte wÃ¤hlen Sie die Ziel-Tracker und -Rollen.
+
+  field_account: Konto
+  field_active: Aktiv
+  field_activity: AktivitÃ¤t
+  field_admin: Administrator
+  field_assignable: Tickets kÃ¶nnen dieser Rolle zugewiesen werden
+  field_assigned_to: Zugewiesen an
+  field_assigned_to_role: ZustÃ¤ndigkeitsrolle
+  field_attr_firstname: Vorname-Attribut
+  field_attr_lastname: Name-Attribut
+  field_attr_login: Mitgliedsname-Attribut
+  field_attr_mail: E-Mail-Attribut
+  field_auth_source: Authentifizierungs-Modus
+  field_auth_source_ldap_filter: LDAP-Filter
+  field_author: Autor
+  field_base_dn: Base DN
+  field_board_parent: Ãœbergeordnetes Forum
+  field_category: Kategorie
+  field_column_names: Spalten
+  field_closed_on: Geschlossen am
+  field_comments: Kommentar
+  field_comments_sorting: Kommentare anzeigen
+  field_commit_logs_encoding: Kodierung der Commit-Log-Meldungen
+  field_content: Inhalt
+  field_core_fields: Standardwerte
+  field_created_on: Angelegt
+  field_cvs_module: Modul
+  field_cvsroot: CVSROOT
+  field_default_value: Standardwert
+  field_delay: Pufferzeit
+  field_description: Beschreibung
+  field_done_ratio: "% erledigt"
+  field_downloads: Downloads
+  field_due_date: Abgabedatum
+  field_editable: Bearbeitbar
+  field_effective_date: Datum
+  field_estimated_hours: GeschÃ¤tzter Aufwand
+  field_field_format: Format
+  field_filename: Datei
+  field_filesize: GrÃ¶ÃŸe
+  field_firstname: Vorname
+  field_fixed_version: Zielversion
+  field_group_by: Gruppiere Ergebnisse nach
+  field_hide_mail: E-Mail-Adresse nicht anzeigen
+  field_homepage: Projekt-Homepage
+  field_host: Host
+  field_hours: Stunden
+  field_identifier: Kennung
+  field_identity_url: OpenID-URL
+  field_inherit_members: Benutzer vererben
+  field_is_closed: Ticket geschlossen
+  field_is_default: Standardeinstellung
+  field_is_filter: Als Filter benutzen
+  field_is_for_all: FÃ¼r alle Projekte
+  field_is_in_roadmap: In der Roadmap anzeigen
+  field_is_private: Privat
+  field_is_public: Ã–ffentlich
+  field_is_required: Erforderlich
+  field_issue: Ticket
+  field_issue_to: ZugehÃ¶riges Ticket
+  field_issues_visibility: Ticket Sichtbarkeit
+  field_language: Sprache
+  field_last_login_on: Letzte Anmeldung
+  field_lastname: Nachname
+  field_login: Mitgliedsname
+  field_mail: E-Mail
+  field_mail_notification: Mailbenachrichtigung
+  field_max_length: Maximale LÃ¤nge
+  field_member_of_group: ZustÃ¤ndigkeitsgruppe
+  field_min_length: Minimale LÃ¤nge
+  field_multiple: Mehrere Werte
+  field_name: Name
+  field_new_password: Neues Kennwort
+  field_notes: Kommentare
+  field_onthefly: On-the-fly-Benutzererstellung
+  field_parent: Unterprojekt von
+  field_parent_issue: Ãœbergeordnete Aufgabe
+  field_parent_title: Ãœbergeordnete Seite
+  field_password: Kennwort
+  field_password_confirmation: BestÃ¤tigung
+  field_path_to_repository: Pfad zum Repository
+  field_port: Port
+  field_possible_values: MÃ¶gliche Werte
+  field_principal: Auftraggeber
+  field_priority: PrioritÃ¤t
+  field_private_notes: Privater Kommentar
+  field_project: Projekt
+  field_redirect_existing_links: Existierende Links umleiten
+  field_regexp: RegulÃ¤rer Ausdruck
+  field_repository_is_default: Haupt-Repository
+  field_role: Rolle
+  field_root_directory: Wurzelverzeichnis
+  field_scm_path_encoding: Pfad-Kodierung
+  field_searchable: Durchsuchbar
+  field_sharing: Gemeinsame Verwendung
+  field_spent_on: Datum
+  field_start_date: Beginn
+  field_start_page: Hauptseite
+  field_status: Status
+  field_subject: Thema
+  field_subproject: Unterprojekt von
+  field_summary: Zusammenfassung
+  field_text: Textfeld
+  field_time_entries: Logzeit
+  field_time_zone: Zeitzone
+  field_timeout: Auszeit (in Sekunden)
+  field_title: Titel
+  field_tracker: Tracker
+  field_type: Typ
+  field_updated_on: Aktualisiert
+  field_url: URL
+  field_user: Benutzer
+  field_value: Wert
+  field_version: Version
+  field_visible: Sichtbar
+  field_warn_on_leaving_unsaved: Vor dem Verlassen einer Seite mit ungesichertem Text im Editor warnen
+  field_watcher: Beobachter
+
+  general_csv_decimal_separator: ','
+  general_csv_encoding: ISO-8859-1
+  general_csv_separator: ';'
+  general_first_day_of_week: '1'
+  general_lang_name: 'Deutsch'
+  general_pdf_encoding: UTF-8
   general_text_No: 'Nein'
   general_text_Yes: 'Ja'
   general_text_no: 'nein'
   general_text_yes: 'ja'
-  general_lang_name: 'Deutsch'
-  general_csv_separator: ';'
-  general_csv_decimal_separator: ','
-  general_csv_encoding: ISO-8859-1
-  general_pdf_encoding: UTF-8
-  general_first_day_of_week: '1'
 
-  notice_account_updated: Konto wurde erfolgreich aktualisiert.
-  notice_account_invalid_creditentials: Benutzer oder Kennwort ist ungÃ¼ltig.
-  notice_account_password_updated: Kennwort wurde erfolgreich aktualisiert.
-  notice_account_wrong_password: Falsches Kennwort.
-  notice_account_register_done: Konto wurde erfolgreich angelegt.
-  notice_account_unknown_email: Unbekannter Benutzer.
-  notice_can_t_change_password: Dieses Konto verwendet eine externe Authentifizierungs-Quelle. UnmÃ¶glich, das Kennwort zu Ã¤ndern.
-  notice_account_lost_email_sent: Eine E-Mail mit Anweisungen, ein neues Kennwort zu wÃ¤hlen, wurde Ihnen geschickt.
-  notice_account_activated: Ihr Konto ist aktiviert. Sie kÃ¶nnen sich jetzt anmelden.
-  notice_successful_create: Erfolgreich angelegt
-  notice_successful_update: Erfolgreich aktualisiert.
-  notice_successful_delete: Erfolgreich gelÃ¶scht.
-  notice_successful_connection: Verbindung erfolgreich.
-  notice_file_not_found: Anhang existiert nicht oder ist gelÃ¶scht worden.
-  notice_locking_conflict: Datum wurde von einem anderen Benutzer geÃ¤ndert.
-  notice_not_authorized: Sie sind nicht berechtigt, auf diese Seite zuzugreifen.
-  notice_email_sent: "Eine E-Mail wurde an %{value} gesendet."
-  notice_email_error: "Beim Senden einer E-Mail ist ein Fehler aufgetreten (%{value})."
-  notice_feeds_access_key_reseted: Ihr Atom-ZugriffsschlÃ¼ssel wurde zurÃ¼ckgesetzt.
-  notice_api_access_key_reseted: Ihr API-ZugriffsschlÃ¼ssel wurde zurÃ¼ckgesetzt.
-  notice_failed_to_save_issues: "%{count} von %{total} ausgewÃ¤hlten Tickets konnte(n) nicht gespeichert werden: %{ids}."
-  notice_failed_to_save_members: "Benutzer konnte nicht gespeichert werden: %{errors}."
-  notice_no_issue_selected: "Kein Ticket ausgewÃ¤hlt! Bitte wÃ¤hlen Sie die Tickets, die Sie bearbeiten mÃ¶chten."
-  notice_account_pending: "Ihr Konto wurde erstellt und wartet jetzt auf die Genehmigung des Administrators."
-  notice_default_data_loaded: Die Standard-Konfiguration wurde erfolgreich geladen.
-  notice_unable_delete_version: Die Version konnte nicht gelÃ¶scht werden.
-  notice_unable_delete_time_entry: Der Zeiterfassungseintrag konnte nicht gelÃ¶scht werden.
-  notice_issue_done_ratios_updated: Der Ticket-Fortschritt wurde aktualisiert.
-
-  error_can_t_load_default_data: "Die Standard-Konfiguration konnte nicht geladen werden: %{value}"
-  error_scm_not_found: Eintrag und/oder Revision existiert nicht im Projektarchiv.
-  error_scm_command_failed: "Beim Zugriff auf das Projektarchiv ist ein Fehler aufgetreten: %{value}"
-  error_scm_annotate: "Der Eintrag existiert nicht oder kann nicht annotiert werden."
-  error_issue_not_found_in_project: 'Das Ticket wurde nicht gefunden oder gehÃ¶rt nicht zu diesem Projekt.'
-  error_no_tracker_in_project: Diesem Projekt ist kein Tracker zugeordnet. Bitte Ã¼berprÃ¼fen Sie die Projekteinstellungen.
-  error_no_default_issue_status: Es ist kein Status als Standard definiert. Bitte Ã¼berprÃ¼fen Sie Ihre Konfiguration (unter "Administration -> Ticket-Status").
-  error_can_not_delete_custom_field: Kann das benutzerdefinierte Feld nicht lÃ¶schen.
-  error_can_not_delete_tracker: Dieser Tracker enthÃ¤lt Tickets und kann nicht gelÃ¶scht werden.
-  error_can_not_remove_role: Diese Rolle wird verwendet und kann nicht gelÃ¶scht werden.
-  error_can_not_reopen_issue_on_closed_version: Das Ticket ist einer abgeschlossenen Version zugeordnet und kann daher nicht wieder geÃ¶ffnet werden.
-  error_can_not_archive_project: Dieses Projekt kann nicht archiviert werden.
-  error_issue_done_ratios_not_updated: Der Ticket-Fortschritt wurde nicht aktualisiert.
-  error_workflow_copy_source: Bitte wÃ¤hlen Sie einen Quell-Tracker und eine Quell-Rolle.
-  error_workflow_copy_target: Bitte wÃ¤hlen Sie die Ziel-Tracker und -Rollen.
-  error_unable_delete_issue_status: "Der Ticket-Status konnte nicht gelÃ¶scht werden."
-  error_unable_to_connect: Fehler beim Verbinden (%{value})
-  warning_attachments_not_saved: "%{count} Datei(en) konnten nicht gespeichert werden."
-
-  mail_subject_lost_password: "Ihr %{value} Kennwort"
-  mail_body_lost_password: 'Benutzen Sie den folgenden Link, um Ihr Kennwort zu Ã¤ndern:'
-  mail_subject_register: "%{value} Kontoaktivierung"
-  mail_body_register: 'Um Ihr Konto zu aktivieren, benutzen Sie folgenden Link:'
-  mail_body_account_information_external: "Sie kÃ¶nnen sich mit Ihrem Konto %{value} anmelden."
-  mail_body_account_information: Ihre Konto-Informationen
-  mail_subject_account_activation_request: "Antrag auf %{value} Kontoaktivierung"
-  mail_body_account_activation_request: "Ein neuer Benutzer (%{value}) hat sich registriert. Sein Konto wartet auf Ihre Genehmigung:"
-  mail_subject_reminder: "%{count} Tickets mÃ¼ssen in den nÃ¤chsten %{days} Tagen abgegeben werden"
-  mail_body_reminder: "%{count} Tickets, die Ihnen zugewiesen sind, mÃ¼ssen in den nÃ¤chsten %{days} Tagen abgegeben werden:"
-  mail_subject_wiki_content_added: "Wiki-Seite '%{id}' hinzugefÃ¼gt"
-  mail_body_wiki_content_added: "Die Wiki-Seite '%{id}' wurde von %{author} hinzugefÃ¼gt."
-  mail_subject_wiki_content_updated: "Wiki-Seite '%{id}' erfolgreich aktualisiert"
-  mail_body_wiki_content_updated: "Die Wiki-Seite '%{id}' wurde von %{author} aktualisiert."
-
-  gui_validation_error: 1 Fehler
-  gui_validation_error_plural: "%{count} Fehler"
-
-  field_name: Name
-  field_description: Beschreibung
-  field_summary: Zusammenfassung
-  field_is_required: Erforderlich
-  field_firstname: Vorname
-  field_lastname: Nachname
-  field_mail: E-Mail
-  field_filename: Datei
-  field_filesize: GrÃ¶ÃŸe
-  field_downloads: Downloads
-  field_author: Autor
-  field_created_on: Angelegt
-  field_updated_on: Aktualisiert
-  field_field_format: Format
-  field_is_for_all: FÃ¼r alle Projekte
-  field_possible_values: MÃ¶gliche Werte
-  field_regexp: RegulÃ¤rer Ausdruck
-  field_min_length: Minimale LÃ¤nge
-  field_max_length: Maximale LÃ¤nge
-  field_value: Wert
-  field_category: Kategorie
-  field_title: Titel
-  field_project: Projekt
-  field_issue: Ticket
-  field_status: Status
-  field_notes: Kommentare
-  field_is_closed: Ticket geschlossen
-  field_is_default: Standardeinstellung
-  field_tracker: Tracker
-  field_subject: Thema
-  field_due_date: Abgabedatum
-  field_assigned_to: Zugewiesen an
-  field_priority: PrioritÃ¤t
-  field_fixed_version: Zielversion
-  field_user: Benutzer
-  field_principal: Auftraggeber
-  field_role: Rolle
-  field_homepage: Projekt-Homepage
-  field_is_public: Ã–ffentlich
-  field_parent: Unterprojekt von
-  field_is_in_roadmap: In der Roadmap anzeigen
-  field_login: Mitgliedsname
-  field_mail_notification: Mailbenachrichtigung
-  field_admin: Administrator
-  field_last_login_on: Letzte Anmeldung
-  field_language: Sprache
-  field_effective_date: Datum
-  field_password: Kennwort
-  field_new_password: Neues Kennwort
-  field_password_confirmation: BestÃ¤tigung
-  field_version: Version
-  field_type: Typ
-  field_host: Host
-  field_port: Port
-  field_account: Konto
-  field_base_dn: Base DN
-  field_attr_login: Mitgliedsname-Attribut
-  field_attr_firstname: Vorname-Attribut
-  field_attr_lastname: Name-Attribut
-  field_attr_mail: E-Mail-Attribut
-  field_onthefly: On-the-fly-Benutzererstellung
-  field_start_date: Beginn
-  field_done_ratio: "% erledigt"
-  field_auth_source: Authentifizierungs-Modus
-  field_hide_mail: E-Mail-Adresse nicht anzeigen
-  field_comments: Kommentar
-  field_url: URL
-  field_start_page: Hauptseite
-  field_subproject: Unterprojekt von
-  field_hours: Stunden
-  field_activity: AktivitÃ¤t
-  field_spent_on: Datum
-  field_identifier: Kennung
-  field_is_filter: Als Filter benutzen
-  field_issue_to: ZugehÃ¶riges Ticket
-  field_delay: Pufferzeit
-  field_assignable: Tickets kÃ¶nnen dieser Rolle zugewiesen werden
-  field_redirect_existing_links: Existierende Links umleiten
-  field_estimated_hours: GeschÃ¤tzter Aufwand
-  field_column_names: Spalten
-  field_time_entries: Logzeit
-  field_time_zone: Zeitzone
-  field_searchable: Durchsuchbar
-  field_default_value: Standardwert
-  field_comments_sorting: Kommentare anzeigen
-  field_parent_title: Ãœbergeordnete Seite
-  field_editable: Bearbeitbar
-  field_watcher: Beobachter
-  field_identity_url: OpenID-URL
-  field_content: Inhalt
-  field_group_by: Gruppiere Ergebnisse nach
-  field_sharing: Gemeinsame Verwendung
-  field_parent_issue: Ãœbergeordnete Aufgabe
-
-  setting_app_title: Applikations-Titel
-  setting_app_subtitle: Applikations-Untertitel
-  setting_welcome_text: Willkommenstext
-  setting_default_language: Standardsprache
-  setting_login_required: Authentifizierung erforderlich
-  setting_self_registration: Anmeldung ermÃ¶glicht
-  setting_attachment_max_size: Max. DateigrÃ¶ÃŸe
-  setting_issues_export_limit: Max. Anzahl Tickets bei CSV/PDF-Export
-  setting_mail_from: E-Mail-Absender
-  setting_bcc_recipients: E-Mails als Blindkopie (BCC) senden
-  setting_plain_text_mail: Nur reinen Text (kein HTML) senden
-  setting_host_name: Hostname
-  setting_text_formatting: Textformatierung
-  setting_wiki_compression: Wiki-Historie komprimieren
-  setting_feeds_limit: Max. Anzahl EintrÃ¤ge pro Atom-Feed
-  setting_default_projects_public: Neue Projekte sind standardmÃ¤ÃŸig Ã¶ffentlich
-  setting_autofetch_changesets: Changesets automatisch abrufen
-  setting_sys_api_enabled: Webservice zur Verwaltung der Projektarchive benutzen
-  setting_commit_ref_keywords: SchlÃ¼sselwÃ¶rter (Beziehungen)
-  setting_commit_fix_keywords: SchlÃ¼sselwÃ¶rter (Status)
-  setting_autologin: Automatische Anmeldung
-  setting_date_format: Datumsformat
-  setting_time_format: Zeitformat
-  setting_cross_project_issue_relations: Ticket-Beziehungen zwischen Projekten erlauben
-  setting_issue_list_default_columns: Standard-Spalten in der Ticket-Auflistung
-  setting_emails_footer: E-Mail-FuÃŸzeile
-  setting_protocol: Protokoll
-  setting_per_page_options: Objekte pro Seite
-  setting_user_format: Benutzer-Anzeigeformat
-  setting_activity_days_default: Anzahl Tage pro Seite der Projekt-AktivitÃ¤t
-  setting_display_subprojects_issues: Tickets von Unterprojekten im Hauptprojekt anzeigen
-  setting_enabled_scm: Aktivierte Versionskontrollsysteme
-  setting_mail_handler_body_delimiters: "Schneide E-Mails nach einer dieser Zeilen ab"
-  setting_mail_handler_api_enabled: Abruf eingehender E-Mails aktivieren
-  setting_mail_handler_api_key: API-SchlÃ¼ssel
-  setting_sequential_project_identifiers: Fortlaufende Projektkennungen generieren
-  setting_gravatar_enabled: Gravatar-Benutzerbilder benutzen
-  setting_gravatar_default: Standard-Gravatar-Bild
-  setting_diff_max_lines_displayed: Maximale Anzahl anzuzeigender Diff-Zeilen
-  setting_file_max_size_displayed: Maximale GrÃ¶ÃŸe inline angezeigter Textdateien
-  setting_repository_log_display_limit: Maximale Anzahl anzuzeigender Revisionen in der Historie einer Datei
-  setting_openid: Erlaube OpenID-Anmeldung und -Registrierung
-  setting_password_min_length: MindestlÃ¤nge des Kennworts
-  setting_new_project_user_role_id: Rolle, die einem Nicht-Administrator zugeordnet wird, der ein Projekt erstellt
-  setting_default_projects_modules: StandardmÃ¤ÃŸig aktivierte Module fÃ¼r neue Projekte
-  setting_issue_done_ratio: Berechne den Ticket-Fortschritt mittels
-  setting_issue_done_ratio_issue_field: Ticket-Feld %-erledigt
-  setting_issue_done_ratio_issue_status: Ticket-Status
-  setting_start_of_week: Wochenanfang
-  setting_rest_api_enabled: REST-Schnittstelle aktivieren
-  setting_cache_formatted_text: Formatierten Text im Cache speichern
-
-  permission_add_project: Projekt erstellen
-  permission_add_subprojects: Unterprojekte erstellen
-  permission_edit_project: Projekt bearbeiten
-  permission_select_project_modules: Projektmodule auswÃ¤hlen
-  permission_manage_members: Mitglieder verwalten
-  permission_manage_project_activities: AktivitÃ¤ten (Zeiterfassung) verwalten
-  permission_manage_versions: Versionen verwalten
-  permission_manage_categories: Ticket-Kategorien verwalten
-  permission_view_issues: Tickets anzeigen
-  permission_add_issues: Tickets hinzufÃ¼gen
-  permission_edit_issues: Tickets bearbeiten
-  permission_manage_issue_relations: Ticket-Beziehungen verwalten
-  permission_add_issue_notes: Kommentare hinzufÃ¼gen
-  permission_edit_issue_notes: Kommentare bearbeiten
-  permission_edit_own_issue_notes: Eigene Kommentare bearbeiten
-  permission_move_issues: Tickets verschieben
-  permission_delete_issues: Tickets lÃ¶schen
-  permission_manage_public_queries: Ã–ffentliche Filter verwalten
-  permission_save_queries: Filter speichern
-  permission_view_gantt: Gantt-Diagramm ansehen
-  permission_view_calendar: Kalender ansehen
-  permission_view_issue_watchers: Liste der Beobachter ansehen
-  permission_add_issue_watchers: Beobachter hinzufÃ¼gen
-  permission_delete_issue_watchers: Beobachter lÃ¶schen
-  permission_log_time: AufwÃ¤nde buchen
-  permission_view_time_entries: Gebuchte AufwÃ¤nde ansehen
-  permission_edit_time_entries: Gebuchte AufwÃ¤nde bearbeiten
-  permission_edit_own_time_entries: Selbst gebuchte AufwÃ¤nde bearbeiten
-  permission_manage_news: News verwalten
-  permission_comment_news: News kommentieren
-  permission_manage_documents: Dokumente verwalten
-  permission_view_documents: Dokumente ansehen
-  permission_manage_files: Dateien verwalten
-  permission_view_files: Dateien ansehen
-  permission_manage_wiki: Wiki verwalten
-  permission_rename_wiki_pages: Wiki-Seiten umbenennen
-  permission_delete_wiki_pages: Wiki-Seiten lÃ¶schen
-  permission_view_wiki_pages: Wiki ansehen
-  permission_view_wiki_edits: Wiki-Versionsgeschichte ansehen
-  permission_edit_wiki_pages: Wiki-Seiten bearbeiten
-  permission_delete_wiki_pages_attachments: AnhÃ¤nge lÃ¶schen
-  permission_protect_wiki_pages: Wiki-Seiten schÃ¼tzen
-  permission_manage_repository: Projektarchiv verwalten
-  permission_browse_repository: Projektarchiv ansehen
-  permission_view_changesets: Changesets ansehen
-  permission_commit_access: Commit-Zugriff (Ã¼ber WebDAV)
-  permission_manage_boards: Foren verwalten
-  permission_view_messages: ForenbeitrÃ¤ge ansehen
-  permission_add_messages: ForenbeitrÃ¤ge hinzufÃ¼gen
-  permission_edit_messages: ForenbeitrÃ¤ge bearbeiten
-  permission_edit_own_messages: Eigene ForenbeitrÃ¤ge bearbeiten
-  permission_delete_messages: ForenbeitrÃ¤ge lÃ¶schen
-  permission_delete_own_messages: Eigene ForenbeitrÃ¤ge lÃ¶schen
-  permission_export_wiki_pages: Wiki-Seiten exportieren
-  permission_manage_subtasks: Unteraufgaben verwalten
-
-  project_module_issue_tracking: Ticket-Verfolgung
-  project_module_time_tracking: Zeiterfassung
-  project_module_news: News
-  project_module_documents: Dokumente
-  project_module_files: Dateien
-  project_module_wiki: Wiki
-  project_module_repository: Projektarchiv
-  project_module_boards: Foren
-  project_module_calendar: Kalender
-  project_module_gantt: Gantt
-
-  label_user: Benutzer
-  label_user_plural: Benutzer
-  label_user_new: Neuer Benutzer
-  label_user_anonymous: Anonym
+  label_home_heading: Hauptseite
+  label_activity: AktivitÃ¤t
+  label_add_another_file: Eine weitere Datei hinzufÃ¼gen
+  label_add_note: Kommentar hinzufÃ¼gen
+  label_added: hinzugefÃ¼gt
+  label_added_time_by: "Von %{author} vor %{age} hinzugefÃ¼gt"
+  label_additional_workflow_transitions_for_assignee: ZusÃ¤tzliche Berechtigungen wenn der Benutzer der Zugewiesene ist
+  label_additional_workflow_transitions_for_author: ZusÃ¤tzliche Berechtigungen wenn der Benutzer der Autor ist
+  label_administration: Administration
+  label_age: GeÃ¤ndert vor
+  label_ago: vor
+  label_all: alle
+  label_all_time: gesamter Zeitraum
+  label_all_words: Alle WÃ¶rter
+  label_and_its_subprojects: "%{value} und dessen Unterprojekte"
+  label_any: alle
+  label_any_issues_in_project: irgendein Ticket im Projekt
+  label_any_issues_not_in_project: irgendein Ticket nicht im Projekt
+  label_api_access_key: API-ZugriffsschlÃ¼ssel
+  label_api_access_key_created_on: Der API-ZugriffsschlÃ¼ssel wurde vor %{value} erstellt
+  label_applied_status: Zugewiesener Status
+  label_ascending: Aufsteigend
+  label_assigned_to_me_issues: Mir zugewiesene Tickets
+  label_associated_revisions: ZugehÃ¶rige Revisionen
+  label_attachment: Datei
+  label_attachment_delete: Anhang lÃ¶schen
+  label_attachment_new: Neue Datei
+  label_attachment_plural: Dateien
+  label_attribute: Attribut
+  label_attribute_of_assigned_to: "%{name} des Bearbeiters"
+  label_attribute_of_author: "%{name} des Autors"
+  label_attribute_of_fixed_version: "%{name} der Zielversion"
+  label_attribute_of_issue: "%{name} des Tickets"
+  label_attribute_of_project: "%{name} des Projekts"
+  label_attribute_of_user: "%{name} des Benutzers"
+  label_attribute_plural: Attribute
+  label_auth_source: Authentifizierungs-Modus
+  label_auth_source_new: Neuer Authentifizierungs-Modus
+  label_auth_source_plural: Authentifizierungs-Arten
+  label_authentication: Authentifizierung
+  label_between: zwischen
+  label_blocked_by: Blockiert durch
+  label_blocks: Blockiert
+  label_board: Forum
+  label_board_locked: Gesperrt
+  label_board_new: Neues Forum
+  label_board_plural: Foren
+  label_board_sticky: Wichtig (immer oben)
+  label_boolean: Boolean
+  label_branch: Zweig
+  label_browse: Codebrowser
+  label_bulk_edit_selected_issues: Alle ausgewÃ¤hlten Tickets bearbeiten
+  label_bulk_edit_selected_time_entries: AusgewÃ¤hlte ZeitaufwÃ¤nde bearbeiten
+  label_calendar: Kalender
+  label_change_plural: Ã„nderungen
+  label_change_properties: Eigenschaften Ã¤ndern
+  label_change_status: Statuswechsel
+  label_change_view_all: Alle Ã„nderungen anzeigen
+  label_changes_details: Details aller Ã„nderungen
+  label_changeset_plural: Changesets
+  label_child_revision: Nachfolger
+  label_chronological_order: in zeitlicher Reihenfolge
+  label_close_versions: VollstÃ¤ndige Versionen schlieÃŸen
+  label_closed_issues: geschlossen
+  label_closed_issues_plural: geschlossen
+  label_comment: Kommentar
+  label_comment_add: Kommentar hinzufÃ¼gen
+  label_comment_added: Kommentar hinzugefÃ¼gt
+  label_comment_delete: Kommentar lÃ¶schen
+  label_comment_plural: Kommentare
+  label_commits_per_author: Ãœbertragungen pro Autor
+  label_commits_per_month: Ãœbertragungen pro Monat
+  label_completed_versions: Abgeschlossene Versionen
+  label_confirmation: BestÃ¤tigung
+  label_contains: enthÃ¤lt
+  label_copied: kopiert
+  label_copied_from: Kopiert von
+  label_copied_to: Kopiert nach
+  label_copy_attachments: AnhÃ¤nge kopieren
+  label_copy_same_as_target: So wie das Ziel
+  label_copy_source: Quelle
+  label_copy_subtasks: Unteraufgaben kopieren
+  label_copy_target: Ziel
+  label_copy_workflow_from: Workflow kopieren von
+  label_cross_project_descendants: Mit Unterprojekten
+  label_cross_project_hierarchy: Mit Projekthierarchie
+  label_cross_project_system: Mit allen Projekten
+  label_cross_project_tree: Mit Projektbaum
+  label_current_status: GegenwÃ¤rtiger Status
+  label_current_version: GegenwÃ¤rtige Version
+  label_custom_field: Benutzerdefiniertes Feld
+  label_custom_field_new: Neues Feld
+  label_custom_field_plural: Benutzerdefinierte Felder
+  label_date: Datum
+  label_date_from: Von
+  label_date_from_to: von %{start} bis %{end}
+  label_date_range: Zeitraum
+  label_date_to: Bis
+  label_day_plural: Tage
+  label_default: Standard
+  label_default_columns: Standard-Spalten
+  label_deleted: gelÃ¶scht
+  label_descending: Absteigend
+  label_details: Details
+  label_diff: diff
+  label_diff_inline: einspaltig
+  label_diff_side_by_side: nebeneinander
+  label_disabled: gesperrt
+  label_display: Anzeige
+  label_display_per_page: "Pro Seite: %{value}"
+  label_display_used_statuses_only: Zeige nur Status an, die von diesem Tracker verwendet werden
+  label_document: Dokument
+  label_document_added: Dokument hinzugefÃ¼gt
+  label_document_new: Neues Dokument
+  label_document_plural: Dokumente
+  label_downloads_abbr: D/L
+  label_duplicated_by: Dupliziert durch
+  label_duplicates: Duplikat von
+  label_end_to_end: Ende - Ende
+  label_end_to_start: Ende - Anfang
+  label_enumeration_new: Neuer Wert
+  label_enumerations: AufzÃ¤hlungen
+  label_environment: Umgebung
+  label_equals: ist
+  label_example: Beispiel
+  label_export_options: "%{export_format} Export-Eigenschaften"
+  label_export_to: "Auch abrufbar als:"
+  label_f_hour: "%{value} Stunde"
+  label_f_hour_plural: "%{value} Stunden"
+  label_feed_plural: Feeds
+  label_feeds_access_key: Atom-ZugriffsschlÃ¼ssel
+  label_feeds_access_key_created_on: "Atom-ZugriffsschlÃ¼ssel vor %{value} erstellt"
+  label_fields_permissions: Feldberechtigungen
+  label_file_added: Datei hinzugefÃ¼gt
+  label_file_plural: Dateien
+  label_filter_add: Filter hinzufÃ¼gen
+  label_filter_plural: Filter
+  label_float: FlieÃŸkommazahl
+  label_follows: Nachfolger von
+  label_gantt: Gantt-Diagramm
+  label_gantt_progress_line: Fortschrittslinie
+  label_general: Allgemein
+  label_generate_key: Generieren
+  label_git_report_last_commit: Bericht des letzten Commits fÃ¼r Dateien und Verzeichnisse
+  label_greater_or_equal: ">="
+  label_group: Gruppe
+  label_group_new: Neue Gruppe
+  label_group_plural: Gruppen
+  label_help: Hilfe
+  label_history: Historie
+  label_home: Hauptseite
+  label_in: in
+  label_in_less_than: in weniger als
+  label_in_more_than: in mehr als
+  label_in_the_next_days: in den nÃ¤chsten
+  label_in_the_past_days: in den letzten
+  label_incoming_emails: Eingehende E-Mails
+  label_index_by_date: Seiten nach Datum sortiert
+  label_index_by_title: Seiten nach Titel sortiert
+  label_information: Information
+  label_information_plural: Informationen
+  label_integer: Zahl
+  label_internal: Intern
+  label_issue: Ticket
+  label_issue_added: Ticket hinzugefÃ¼gt
+  label_issue_category: Ticket-Kategorie
+  label_issue_category_new: Neue Kategorie
+  label_issue_category_plural: Ticket-Kategorien
+  label_issue_new: Neues Ticket
+  label_issue_note_added: Notiz hinzugefÃ¼gt
+  label_issue_plural: Tickets
+  label_issue_priority_updated: PrioritÃ¤t aktualisiert
+  label_issue_status: Ticket-Status
+  label_issue_status_new: Neuer Status
+  label_issue_status_plural: Ticket-Status
+  label_issue_status_updated: Status aktualisiert
+  label_issue_tracking: Tickets
+  label_issue_updated: Ticket aktualisiert
+  label_issue_view_all: Alle Tickets anzeigen
+  label_issue_watchers: Beobachter
+  label_issues_by: "Tickets pro %{value}"
+  label_issues_visibility_all: Alle Tickets
+  label_issues_visibility_own: Tickets die folgender Benutzer erstellt hat oder die ihm zugewiesen sind
+  label_issues_visibility_public: Alle Ã¶ffentlichen Tickets
+  label_item_position: "%{position}/%{count}"
+  label_jump_to_a_project: Zu einem Projekt springen...
+  label_language_based: SprachabhÃ¤ngig
+  label_last_changes: "%{count} letzte Ã„nderungen"
+  label_last_login: Letzte Anmeldung
+  label_last_month: voriger Monat
+  label_last_n_days: "die letzten %{count} Tage"
+  label_last_n_weeks: letzte %{count} Wochen
+  label_last_week: vorige Woche
+  label_latest_revision: Aktuellste Revision
+  label_latest_revision_plural: Aktuellste Revisionen
+  label_ldap_authentication: LDAP-Authentifizierung
+  label_less_or_equal: "<="
+  label_less_than_ago: vor weniger als
+  label_list: Liste
+  label_loading: Lade...
+  label_logged_as: Angemeldet als
+  label_login: Anmelden
+  label_login_with_open_id_option: oder mit OpenID anmelden
+  label_logout: Abmelden
+  label_max_size: Maximale GrÃ¶ÃŸe
+  label_me: ich
+  label_member: Mitglied
+  label_member_new: Neues Mitglied
+  label_member_plural: Mitglieder
+  label_message_last: Letzter Forenbeitrag
+  label_message_new: Neues Thema
+  label_message_plural: ForenbeitrÃ¤ge
+  label_message_posted: Forenbeitrag hinzugefÃ¼gt
+  label_min_max_length: LÃ¤nge (Min. - Max.)
+  label_missing_api_access_key: Der API-ZugriffsschlÃ¼ssel fehlt.
+  label_missing_feeds_access_key: Der Atom-ZugriffsschlÃ¼ssel fehlt.
+  label_modified: geÃ¤ndert
+  label_module_plural: Module
+  label_month: Monat
+  label_months_from: Monate ab
+  label_more: Mehr
+  label_more_than_ago: vor mehr als
+  label_my_account: Mein Konto
+  label_my_page: Meine Seite
+  label_my_page_block: VerfÃ¼gbare Widgets
+  label_my_projects: Meine Projekte
+  label_my_queries: Meine eigenen Abfragen
+  label_new: Neu
+  label_new_statuses_allowed: Neue Berechtigungen
+  label_news: News
+  label_news_added: News hinzugefÃ¼gt
+  label_news_comment_added: Kommentar zu einer News hinzugefÃ¼gt
+  label_news_latest: Letzte News
+  label_news_new: News hinzufÃ¼gen
+  label_news_plural: News
+  label_news_view_all: Alle News anzeigen
+  label_next: Weiter
+  label_no_change_option: (Keine Ã„nderung)
+  label_no_data: Nichts anzuzeigen
+  label_no_issues_in_project: keine Tickets im Projekt
+  label_nobody: Niemand
+  label_none: kein
+  label_not_contains: enthÃ¤lt nicht
+  label_not_equals: ist nicht
+  label_open_issues: offen
+  label_open_issues_plural: offen
+  label_optional_description: Beschreibung (optional)
+  label_options: Optionen
+  label_overall_activity: AktivitÃ¤ten aller Projekte anzeigen
+  label_overall_spent_time: Aufgewendete Zeit aller Projekte anzeigen
+  label_overview: Ãœbersicht
+  label_parent_revision: VorgÃ¤nger
+  label_password_lost: Kennwort vergessen
+  label_per_page: Pro Seite
+  label_permissions: Berechtigungen
+  label_permissions_report: BerechtigungsÃ¼bersicht
+  label_personalize_page: Diese Seite anpassen
+  label_planning: Terminplanung
+  label_please_login: Anmelden
+  label_plugins: Plugins
+  label_precedes: VorgÃ¤nger von
+  label_preferences: PrÃ¤ferenzen
+  label_preview: Vorschau
+  label_previous: ZurÃ¼ck
+  label_principal_search: "Nach Benutzer oder Gruppe suchen:"
+  label_profile: Profil
   label_project: Projekt
+  label_project_all: Alle Projekte
+  label_project_copy_notifications: Sende Mailbenachrichtigungen beim Kopieren des Projekts.
+  label_project_latest: Neueste Projekte
   label_project_new: Neues Projekt
   label_project_plural: Projekte
+  label_public_projects: Ã–ffentliche Projekte
+  label_query: Benutzerdefinierte Abfrage
+  label_query_new: Neue Abfrage
+  label_query_plural: Benutzerdefinierte Abfragen
+  label_read: Lesen...
+  label_readonly: Nur-Lese-Zugriff
+  label_register: Registrieren
+  label_registered_on: Angemeldet am
+  label_registration_activation_by_email: Kontoaktivierung durch E-Mail
+  label_registration_automatic_activation: Automatische Kontoaktivierung
+  label_registration_manual_activation: Manuelle Kontoaktivierung
+  label_related_issues: ZugehÃ¶rige Tickets
+  label_relates_to: Beziehung mit
+  label_relation_delete: Beziehung lÃ¶schen
+  label_relation_new: Neue Beziehung
+  label_renamed: umbenannt
+  label_reply_plural: Antworten
+  label_report: Bericht
+  label_report_plural: Berichte
+  label_reported_issues: Erstellte Tickets
+  label_repository: Projektarchiv
+  label_repository_new: Neues Repository
+  label_repository_plural: Projektarchive
+  label_required: Erforderlich
+  label_result_plural: Resultate
+  label_reverse_chronological_order: in umgekehrter zeitlicher Reihenfolge
+  label_revision: Revision
+  label_revision_id: Revision %{value}
+  label_revision_plural: Revisionen
+  label_roadmap: Roadmap
+  label_roadmap_due_in: "FÃ¤llig in %{value}"
+  label_roadmap_no_issues: Keine Tickets fÃ¼r diese Version
+  label_roadmap_overdue: "%{value} verspÃ¤tet"
+  label_role: Rolle
+  label_role_and_permissions: Rollen und Rechte
+  label_role_anonymous: Anonymous
+  label_role_new: Neue Rolle
+  label_role_non_member: Nichtmitglied
+  label_role_plural: Rollen
+  label_scm: Versionskontrollsystem
+  label_search: Suche
+  label_search_for_watchers: Nach hinzufÃ¼gbaren Beobachtern suchen
+  label_search_titles_only: Nur Titel durchsuchen
+  label_send_information: Sende Kontoinformationen an Benutzer
+  label_send_test_email: Test-E-Mail senden
+  label_session_expiration: Ende einer Sitzung
+  label_settings: Konfiguration
+  label_show_closed_projects: Geschlossene Projekte anzeigen
+  label_show_completed_versions: Abgeschlossene Versionen anzeigen
+  label_sort: Sortierung
+  label_sort_by: "Sortiert nach %{value}"
+  label_sort_higher: Eins hÃ¶her
+  label_sort_highest: An den Anfang
+  label_sort_lower: Eins tiefer
+  label_sort_lowest: Ans Ende
+  label_spent_time: Aufgewendete Zeit
+  label_start_to_end: Anfang - Ende
+  label_start_to_start: Anfang - Anfang
+  label_statistics: Statistiken
+  label_status_transitions: StatusÃ¤nderungen
+  label_stay_logged_in: Angemeldet bleiben
+  label_string: Text
+  label_subproject_new: Neues Unterprojekt
+  label_subproject_plural: Unterprojekte
+  label_subtask_plural: Unteraufgaben
+  label_tag: Markierung
+  label_text: Langer Text
+  label_theme: Stil
+  label_this_month: aktueller Monat
+  label_this_week: aktuelle Woche
+  label_this_year: aktuelles Jahr
+  label_time_entry_plural: BenÃ¶tigte Zeit
+  label_time_tracking: Zeiterfassung
+  label_today: heute
+  label_topic_plural: Themen
+  label_total: Gesamtzahl
+  label_tracker: Tracker
+  label_tracker_new: Neuer Tracker
+  label_tracker_plural: Tracker
+  label_update_issue_done_ratios: Ticket-Fortschritt aktualisieren
+  label_updated_time: "Vor %{value} aktualisiert"
+  label_updated_time_by: "Von %{author} vor %{age} aktualisiert"
+  label_used_by: Benutzt von
+  label_user: Benutzer
+  label_user_activity: "AktivitÃ¤t von %{value}"
+  label_user_anonymous: Anonym
+  label_user_mail_no_self_notified: "Ich mÃ¶chte nicht Ã¼ber Ã„nderungen benachrichtigt werden, die ich selbst durchfÃ¼hre."
+  label_user_mail_option_all: "FÃ¼r alle Ereignisse in all meinen Projekten"
+  label_user_mail_option_none: Keine Ereignisse
+  label_user_mail_option_only_assigned: Nur fÃ¼r Aufgaben fÃ¼r die ich zustÃ¤ndig bin
+  label_user_mail_option_only_my_events: Nur fÃ¼r Aufgaben die ich beobachte oder an welchen ich mitarbeite
+  label_user_mail_option_only_owner: Nur fÃ¼r Aufgaben die ich angelegt habe
+  label_user_mail_option_selected: "FÃ¼r alle Ereignisse in den ausgewÃ¤hlten Projekten..."
+  label_user_new: Neuer Benutzer
+  label_user_plural: Benutzer
+  label_user_search: "Nach Benutzer suchen:"
+  label_version: Version
+  label_version_new: Neue Version
+  label_version_plural: Versionen
+  label_version_sharing_descendants: Mit Unterprojekten
+  label_version_sharing_hierarchy: Mit Projekthierarchie
+  label_version_sharing_none: Nicht gemeinsam verwenden
+  label_version_sharing_system: Mit allen Projekten
+  label_version_sharing_tree: Mit Projektbaum
+  label_view_all_revisions: Alle Revisionen anzeigen
+  label_view_diff: Unterschiede anzeigen
+  label_view_revisions: Revisionen anzeigen
+  label_watched_issues: Beobachtete Tickets
+  label_week: Woche
+  label_wiki: Wiki
+  label_wiki_content_added: Wiki-Seite hinzugefÃ¼gt
+  label_wiki_content_updated: Wiki-Seite aktualisiert
+  label_wiki_edit: Wiki-Bearbeitung
+  label_wiki_edit_plural: Wiki-Bearbeitungen
+  label_wiki_page: Wiki-Seite
+  label_wiki_page_plural: Wiki-Seiten
+  label_workflow: Workflow
+  label_x_closed_issues_abbr:
+    zero:  0 geschlossen
+    one:   1 geschlossen
+    other: "%{count} geschlossen"
+  label_x_comments:
+    zero: keine Kommentare
+    one: 1 Kommentar
+    other: "%{count} Kommentare"
+  label_x_issues:
+    zero:  0 Tickets
+    one:   1 Ticket
+    other: "%{count} Tickets"
+  label_x_open_issues_abbr:
+    zero:  0 offen
+    one:   1 offen
+    other: "%{count} offen"
+  label_x_open_issues_abbr_on_total:
+    zero:  0 offen / %{total}
+    one:   1 offen / %{total}
+    other: "%{count} offen / %{total}"
   label_x_projects:
     zero:  keine Projekte
     one:   1 Projekt
     other: "%{count} Projekte"
-  label_project_all: Alle Projekte
-  label_project_latest: Neueste Projekte
-  label_issue: Ticket
-  label_issue_new: Neues Ticket
-  label_issue_plural: Tickets
-  label_issue_view_all: Alle Tickets anzeigen
-  label_issues_by: "Tickets von %{value}"
-  label_issue_added: Ticket hinzugefÃ¼gt
-  label_issue_updated: Ticket aktualisiert
-  label_document: Dokument
-  label_document_new: Neues Dokument
-  label_document_plural: Dokumente
-  label_document_added: Dokument hinzugefÃ¼gt
-  label_role: Rolle
-  label_role_plural: Rollen
-  label_role_new: Neue Rolle
-  label_role_and_permissions: Rollen und Rechte
-  label_member: Mitglied
-  label_member_new: Neues Mitglied
-  label_member_plural: Mitglieder
-  label_tracker: Tracker
-  label_tracker_plural: Tracker
-  label_tracker_new: Neuer Tracker
-  label_workflow: Workflow
-  label_issue_status: Ticket-Status
-  label_issue_status_plural: Ticket-Status
-  label_issue_status_new: Neuer Status
-  label_issue_category: Ticket-Kategorie
-  label_issue_category_plural: Ticket-Kategorien
-  label_issue_category_new: Neue Kategorie
-  label_custom_field: Benutzerdefiniertes Feld
-  label_custom_field_plural: Benutzerdefinierte Felder
-  label_custom_field_new: Neues Feld
-  label_enumerations: AufzÃ¤hlungen
-  label_enumeration_new: Neuer Wert
-  label_information: Information
-  label_information_plural: Informationen
-  label_please_login: Anmelden
-  label_register: Registrieren
-  label_login_with_open_id_option: oder mit OpenID anmelden
-  label_password_lost: Kennwort vergessen
-  label_home: Hauptseite
-  label_home_heading: Hauptseite
-  label_my_page: Meine Seite
-  label_my_account: Mein Konto
-  label_my_projects: Meine Projekte
-  label_my_page_block: Bereich "Meine Seite"
-  label_administration: Administration
-  label_login: Anmelden
-  label_logout: Abmelden
-  label_help: Hilfe
-  label_reported_issues: Gemeldete Tickets
-  label_assigned_to_me_issues: Mir zugewiesen
-  label_last_login: Letzte Anmeldung
-  label_registered_on: Angemeldet am
-  label_activity: AktivitÃ¤t
-  label_overall_activity: AktivitÃ¤ten aller Projekte anzeigen
-  label_user_activity: "AktivitÃ¤t von %{value}"
-  label_new: Neu
-  label_logged_as: Angemeldet als
-  label_environment: Umgebung
-  label_authentication: Authentifizierung
-  label_auth_source: Authentifizierungs-Modus
-  label_auth_source_new: Neuer Authentifizierungs-Modus
-  label_auth_source_plural: Authentifizierungs-Arten
-  label_subproject_plural: Unterprojekte
-  label_subproject_new: Neues Unterprojekt
-  label_and_its_subprojects: "%{value} und dessen Unterprojekte"
-  label_min_max_length: LÃ¤nge (Min. - Max.)
-  label_list: Liste
-  label_date: Datum
-  label_integer: Zahl
-  label_float: FlieÃŸkommazahl
-  label_boolean: Boolean
-  label_string: Text
-  label_text: Langer Text
-  label_attribute: Attribut
-  label_attribute_plural: Attribute
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
-  label_no_data: Nichts anzuzeigen
-  label_change_status: Statuswechsel
-  label_history: Historie
-  label_attachment: Datei
-  label_attachment_new: Neue Datei
-  label_attachment_delete: Anhang lÃ¶schen
-  label_attachment_plural: Dateien
-  label_file_added: Datei hinzugefÃ¼gt
-  label_report: Bericht
-  label_report_plural: Berichte
-  label_news: News
-  label_news_new: News hinzufÃ¼gen
-  label_news_plural: News
-  label_news_latest: Letzte News
-  label_news_view_all: Alle News anzeigen
-  label_news_added: News hinzugefÃ¼gt
-  label_settings: Konfiguration
-  label_overview: Ãœbersicht
-  label_version: Version
-  label_version_new: Neue Version
-  label_version_plural: Versionen
-  label_close_versions: VollstÃ¤ndige Versionen schlieÃŸen
-  label_confirmation: BestÃ¤tigung
-  label_export_to: "Auch abrufbar als:"
-  label_read: Lesen...
-  label_public_projects: Ã–ffentliche Projekte
-  label_open_issues: offen
-  label_open_issues_plural: offen
-  label_closed_issues: geschlossen
-  label_closed_issues_plural: geschlossen
-  label_x_open_issues_abbr_on_total:
-    zero:  0 offen / %{total}
-    one:   1 offen / %{total}
-    other: "%{count} offen / %{total}"
-  label_x_open_issues_abbr:
-    zero:  0 offen
-    one:   1 offen
-    other: "%{count} offen"
-  label_x_closed_issues_abbr:
-    zero:  0 geschlossen
-    one:   1 geschlossen
-    other: "%{count} geschlossen"
-  label_total: Gesamtzahl
-  label_permissions: Berechtigungen
-  label_current_status: GegenwÃ¤rtiger Status
-  label_new_statuses_allowed: Neue Berechtigungen
-  label_all: alle
-  label_none: kein
-  label_nobody: Niemand
-  label_next: Weiter
-  label_previous: ZurÃ¼ck
-  label_used_by: Benutzt von
-  label_details: Details
-  label_add_note: Kommentar hinzufÃ¼gen
-  label_per_page: Pro Seite
-  label_calendar: Kalender
-  label_months_from: Monate ab
-  label_gantt: Gantt-Diagramm
-  label_internal: Intern
-  label_last_changes: "%{count} letzte Ã„nderungen"
-  label_change_view_all: Alle Ã„nderungen anzeigen
-  label_personalize_page: Diese Seite anpassen
-  label_comment: Kommentar
-  label_comment_plural: Kommentare
-  label_x_comments:
-    zero: keine Kommentare
-    one: 1 Kommentar
-    other: "%{count} Kommentare"
-  label_comment_add: Kommentar hinzufÃ¼gen
-  label_comment_added: Kommentar hinzugefÃ¼gt
-  label_comment_delete: Kommentar lÃ¶schen
-  label_query: Benutzerdefinierte Abfrage
-  label_query_plural: Benutzerdefinierte Berichte
-  label_query_new: Neuer Bericht
-  label_filter_add: Filter hinzufÃ¼gen
-  label_filter_plural: Filter
-  label_equals: ist
-  label_not_equals: ist nicht
-  label_in_less_than: in weniger als
-  label_in_more_than: in mehr als
-  label_greater_or_equal: ">="
-  label_less_or_equal: "<="
-  label_in: an
-  label_today: heute
-  label_all_time: gesamter Zeitraum
+  label_year: Jahr
   label_yesterday: gestern
-  label_this_week: aktuelle Woche
-  label_last_week: vorige Woche
-  label_last_n_days: "die letzten %{count} Tage"
-  label_this_month: aktueller Monat
-  label_last_month: voriger Monat
-  label_this_year: aktuelles Jahr
-  label_date_range: Zeitraum
-  label_less_than_ago: vor weniger als
-  label_more_than_ago: vor mehr als
-  label_ago: vor
-  label_contains: enthÃ¤lt
-  label_not_contains: enthÃ¤lt nicht
-  label_day_plural: Tage
-  label_repository: Projektarchiv
-  label_repository_plural: Projektarchive
-  label_browse: Codebrowser
-  label_modification: "%{count} Ã„nderung"
-  label_modification_plural: "%{count} Ã„nderungen"
-  label_branch: Zweig
-  label_tag: Markierung
-  label_revision: Revision
-  label_revision_plural: Revisionen
-  label_revision_id: Revision %{value}
-  label_associated_revisions: ZugehÃ¶rige Revisionen
-  label_added: hinzugefÃ¼gt
-  label_modified: geÃ¤ndert
-  label_copied: kopiert
-  label_renamed: umbenannt
-  label_deleted: gelÃ¶scht
-  label_latest_revision: Aktuellste Revision
-  label_latest_revision_plural: Aktuellste Revisionen
-  label_view_revisions: Revisionen anzeigen
-  label_view_all_revisions: Alle Revisionen anzeigen
-  label_max_size: Maximale GrÃ¶ÃŸe
-  label_sort_highest: An den Anfang
-  label_sort_higher: Eins hÃ¶her
-  label_sort_lower: Eins tiefer
-  label_sort_lowest: Ans Ende
-  label_roadmap: Roadmap
-  label_roadmap_due_in: "FÃ¤llig in %{value}"
-  label_roadmap_overdue: "%{value} verspÃ¤tet"
-  label_roadmap_no_issues: Keine Tickets fÃ¼r diese Version
-  label_search: Suche
-  label_result_plural: Resultate
-  label_all_words: Alle WÃ¶rter
-  label_wiki: Wiki
-  label_wiki_edit: Wiki-Bearbeitung
-  label_wiki_edit_plural: Wiki-Bearbeitungen
-  label_wiki_page: Wiki-Seite
-  label_wiki_page_plural: Wiki-Seiten
-  label_index_by_title: Seiten nach Titel sortiert
-  label_index_by_date: Seiten nach Datum sortiert
-  label_current_version: GegenwÃ¤rtige Version
-  label_preview: Vorschau
-  label_feed_plural: Feeds
-  label_changes_details: Details aller Ã„nderungen
-  label_issue_tracking: Tickets
-  label_spent_time: Aufgewendete Zeit
-  label_overall_spent_time: Aufgewendete Zeit aller Projekte anzeigen
-  label_f_hour: "%{value} Stunde"
-  label_f_hour_plural: "%{value} Stunden"
-  label_time_tracking: Zeiterfassung
-  label_change_plural: Ã„nderungen
-  label_statistics: Statistiken
-  label_commits_per_month: Ãœbertragungen pro Monat
-  label_commits_per_author: Ãœbertragungen pro Autor
-  label_view_diff: Unterschiede anzeigen
-  label_diff_inline: einspaltig
-  label_diff_side_by_side: nebeneinander
-  label_options: Optionen
-  label_copy_workflow_from: Workflow kopieren von
-  label_permissions_report: BerechtigungsÃ¼bersicht
-  label_watched_issues: Beobachtete Tickets
-  label_related_issues: ZugehÃ¶rige Tickets
-  label_applied_status: Zugewiesener Status
-  label_loading: Lade...
-  label_relation_new: Neue Beziehung
-  label_relation_delete: Beziehung lÃ¶schen
-  label_relates_to: Beziehung mit
-  label_duplicates: Duplikat von
-  label_duplicated_by: Dupliziert durch
-  label_blocks: Blockiert
-  label_blocked_by: Blockiert durch
-  label_precedes: VorgÃ¤nger von
-  label_follows: Folgt
-  label_end_to_start: Ende - Anfang
-  label_end_to_end: Ende - Ende
-  label_start_to_start: Anfang - Anfang
-  label_start_to_end: Anfang - Ende
-  label_stay_logged_in: Angemeldet bleiben
-  label_disabled: gesperrt
-  label_show_completed_versions: Abgeschlossene Versionen anzeigen
-  label_me: ich
-  label_board: Forum
-  label_board_new: Neues Forum
-  label_board_plural: Foren
-  label_board_locked: Gesperrt
-  label_board_sticky: Wichtig (immer oben)
-  label_topic_plural: Themen
-  label_message_plural: ForenbeitrÃ¤ge
-  label_message_last: Letzter Forenbeitrag
-  label_message_new: Neues Thema
-  label_message_posted: Forenbeitrag hinzugefÃ¼gt
-  label_reply_plural: Antworten
-  label_send_information: Sende Kontoinformationen an Benutzer
-  label_year: Jahr
-  label_month: Monat
-  label_week: Woche
-  label_date_from: Von
-  label_date_to: Bis
-  label_language_based: SprachabhÃ¤ngig
-  label_sort_by: "Sortiert nach %{value}"
-  label_send_test_email: Test-E-Mail senden
-  label_feeds_access_key: RSS-ZugriffsschlÃ¼ssel
-  label_missing_feeds_access_key: Der RSS-ZugriffsschlÃ¼ssel fehlt.
-  label_feeds_access_key_created_on: "Atom-ZugriffsschlÃ¼ssel vor %{value} erstellt"
-  label_module_plural: Module
-  label_added_time_by: "Von %{author} vor %{age} hinzugefÃ¼gt"
-  label_updated_time_by: "Von %{author} vor %{age} aktualisiert"
-  label_updated_time: "Vor %{value} aktualisiert"
-  label_jump_to_a_project: Zu einem Projekt springen...
-  label_file_plural: Dateien
-  label_changeset_plural: Changesets
-  label_default_columns: Standard-Spalten
-  label_no_change_option: (Keine Ã„nderung)
-  label_bulk_edit_selected_issues: Alle ausgewÃ¤hlten Tickets bearbeiten
-  label_theme: Stil
-  label_default: Standard
-  label_search_titles_only: Nur Titel durchsuchen
-  label_user_mail_option_all: "FÃ¼r alle Ereignisse in all meinen Projekten"
-  label_user_mail_option_selected: "FÃ¼r alle Ereignisse in den ausgewÃ¤hlten Projekten..."
-  label_user_mail_no_self_notified: "Ich mÃ¶chte nicht Ã¼ber Ã„nderungen benachrichtigt werden, die ich selbst durchfÃ¼hre."
-  label_registration_activation_by_email: Kontoaktivierung durch E-Mail
-  label_registration_manual_activation: Manuelle Kontoaktivierung
-  label_registration_automatic_activation: Automatische Kontoaktivierung
-  label_display_per_page: "Pro Seite: %{value}"
-  label_age: GeÃ¤ndert vor
-  label_change_properties: Eigenschaften Ã¤ndern
-  label_general: Allgemein
-  label_more: Mehr
-  label_scm: Versionskontrollsystem
-  label_plugins: Plugins
-  label_ldap_authentication: LDAP-Authentifizierung
-  label_downloads_abbr: D/L
-  label_optional_description: Beschreibung (optional)
-  label_add_another_file: Eine weitere Datei hinzufÃ¼gen
-  label_preferences: PrÃ¤ferenzen
-  label_chronological_order: in zeitlicher Reihenfolge
-  label_reverse_chronological_order: in umgekehrter zeitlicher Reihenfolge
-  label_planning: Terminplanung
-  label_incoming_emails: Eingehende E-Mails
-  label_generate_key: Generieren
-  label_issue_watchers: Beobachter
-  label_example: Beispiel
-  label_display: Anzeige
-  label_sort: Sortierung
-  label_ascending: Aufsteigend
-  label_descending: Absteigend
-  label_date_from_to: von %{start} bis %{end}
-  label_wiki_content_added: Die Wiki-Seite wurde erfolgreich hinzugefÃ¼gt.
-  label_wiki_content_updated: Die Wiki-Seite wurde erfolgreich aktualisiert.
-  label_group: Gruppe
-  label_group_plural: Gruppen
-  label_group_new: Neue Gruppe
-  label_time_entry_plural: BenÃ¶tigte Zeit
-  label_version_sharing_none: Nicht gemeinsam verwenden
-  label_version_sharing_descendants: Mit Unterprojekten
-  label_version_sharing_hierarchy: Mit Projekthierarchie
-  label_version_sharing_tree: Mit Projektbaum
-  label_version_sharing_system: Mit allen Projekten
-  label_update_issue_done_ratios: Ticket-Fortschritt aktualisieren
-  label_copy_source: Quelle
-  label_copy_target: Ziel
-  label_copy_same_as_target: So wie das Ziel
-  label_display_used_statuses_only: Zeige nur Status an, die von diesem Tracker verwendet werden
-  label_api_access_key: API-ZugriffsschlÃ¼ssel
-  label_missing_api_access_key: Der API-ZugriffsschlÃ¼ssel fehlt.
-  label_api_access_key_created_on: Der API-ZugriffsschlÃ¼ssel wurde vor %{value} erstellt
-  label_profile: Profil
-  label_subtask_plural: Unteraufgaben
-  label_project_copy_notifications: Sende Mailbenachrichtigungen beim Kopieren des Projekts.
-  label_principal_search: "Nach Benutzer oder Gruppe suchen:"
-  label_user_search: "Nach Benutzer suchen:"
 
-  button_login: Anmelden
-  button_submit: OK
-  button_save: Speichern
-  button_check_all: Alles auswÃ¤hlen
-  button_uncheck_all: Alles abwÃ¤hlen
-  button_delete: LÃ¶schen
-  button_create: Anlegen
-  button_create_and_continue: Anlegen und weiter
-  button_test: Testen
-  button_edit: Bearbeiten
-  button_edit_associated_wikipage: "ZugehÃ¶rige Wikiseite bearbeiten: %{page_title}"
-  button_add: HinzufÃ¼gen
-  button_change: Wechseln
-  button_apply: Anwenden
-  button_clear: ZurÃ¼cksetzen
-  button_lock: Sperren
-  button_unlock: Entsperren
-  button_download: Download
-  button_list: Liste
-  button_view: Anzeigen
-  button_move: Verschieben
-  button_move_and_follow: Verschieben und Ticket anzeigen
-  button_back: ZurÃ¼ck
-  button_cancel: Abbrechen
-  button_activate: Aktivieren
-  button_sort: Sortieren
-  button_log_time: Aufwand buchen
-  button_rollback: Auf diese Version zurÃ¼cksetzen
-  button_watch: Beobachten
-  button_unwatch: Nicht beobachten
-  button_reply: Antworten
-  button_archive: Archivieren
-  button_unarchive: Entarchivieren
-  button_reset: ZurÃ¼cksetzen
-  button_rename: Umbenennen
-  button_change_password: Kennwort Ã¤ndern
-  button_copy: Kopieren
-  button_copy_and_follow: Kopieren und Ticket anzeigen
-  button_annotate: Annotieren
-  button_update: Bearbeiten
-  button_configure: Konfigurieren
-  button_quote: Zitieren
-  button_duplicate: Duplizieren
-  button_show: Anzeigen
+  mail_body_account_activation_request: "Ein neuer Benutzer (%{value}) hat sich registriert. Sein Konto wartet auf Ihre Genehmigung:"
+  mail_body_account_information: Ihre Konto-Informationen
+  mail_body_account_information_external: "Sie kÃ¶nnen sich mit Ihrem Konto %{value} anmelden."
+  mail_body_lost_password: 'Benutzen Sie den folgenden Link, um Ihr Kennwort zu Ã¤ndern:'
+  mail_body_register: 'Um Ihr Konto zu aktivieren, benutzen Sie folgenden Link:'
+  mail_body_reminder: "%{count} Tickets, die Ihnen zugewiesen sind, mÃ¼ssen in den nÃ¤chsten %{days} Tagen abgegeben werden:"
+  mail_body_wiki_content_added: "Die Wiki-Seite '%{id}' wurde von %{author} hinzugefÃ¼gt."
+  mail_body_wiki_content_updated: "Die Wiki-Seite '%{id}' wurde von %{author} aktualisiert."
+  mail_subject_account_activation_request: "Antrag auf %{value} Kontoaktivierung"
+  mail_subject_lost_password: "Ihr %{value} Kennwort"
+  mail_subject_register: "%{value} Kontoaktivierung"
+  mail_subject_reminder: "%{count} Tickets mÃ¼ssen in den nÃ¤chsten %{days} Tagen abgegeben werden"
+  mail_subject_wiki_content_added: "Wiki-Seite '%{id}' hinzugefÃ¼gt"
+  mail_subject_wiki_content_updated: "Wiki-Seite '%{id}' erfolgreich aktualisiert"
+
+  notice_account_activated: Ihr Konto ist aktiviert. Sie kÃ¶nnen sich jetzt anmelden.
+  notice_account_deleted: Ihr Benutzerkonto wurde unwiderruflich gelÃ¶scht.
+  notice_account_invalid_creditentials: Benutzer oder Kennwort ist ungÃ¼ltig.
+  notice_account_lost_email_sent: Eine E-Mail mit Anweisungen, ein neues Kennwort zu wÃ¤hlen, wurde Ihnen geschickt.
+  notice_account_password_updated: Kennwort wurde erfolgreich aktualisiert.
+  notice_account_pending: "Ihr Konto wurde erstellt und wartet jetzt auf die Genehmigung des Administrators."
+  notice_account_register_done: Konto wurde erfolgreich angelegt.
+  notice_account_unknown_email: Unbekannter Benutzer.
+  notice_account_updated: Konto wurde erfolgreich aktualisiert.
+  notice_account_wrong_password: Falsches Kennwort.
+  notice_api_access_key_reseted: Ihr API-ZugriffsschlÃ¼ssel wurde zurÃ¼ckgesetzt.
+  notice_can_t_change_password: Dieses Konto verwendet eine externe Authentifizierungs-Quelle. UnmÃ¶glich, das Kennwort zu Ã¤ndern.
+  notice_default_data_loaded: Die Standard-Konfiguration wurde erfolgreich geladen.
+  notice_email_error: "Beim Senden einer E-Mail ist ein Fehler aufgetreten (%{value})."
+  notice_email_sent: "Eine E-Mail wurde an %{value} gesendet."
+  notice_failed_to_save_issues: "%{count} von %{total} ausgewÃ¤hlten Tickets konnte(n) nicht gespeichert werden: %{ids}."
+  notice_failed_to_save_members: "Benutzer konnte nicht gespeichert werden: %{errors}."
+  notice_failed_to_save_time_entries: "Gescheitert %{count} ZeiteintrÃ¤ge fÃ¼r %{total} von ausgewÃ¤hlten: %{ids} zu speichern." 
+  notice_feeds_access_key_reseted: Ihr Atom-ZugriffsschlÃ¼ssel wurde zurÃ¼ckgesetzt.
+  notice_file_not_found: Anhang existiert nicht oder ist gelÃ¶scht worden.
+  notice_gantt_chart_truncated: Die Grafik ist unvollstÃ¤ndig, da das Maximum der anzeigbaren Aufgaben Ã¼berschritten wurde (%{max})
+  notice_issue_done_ratios_updated: Der Ticket-Fortschritt wurde aktualisiert.
+  notice_issue_successful_create: Ticket %{id} erstellt.
+  notice_issue_update_conflict: Das Ticket wurde von einem anderen Nutzer Ã¼berarbeitet wÃ¤hrend Ihrer Bearbeitung.
+  notice_locking_conflict: Datum wurde von einem anderen Benutzer geÃ¤ndert.
+  notice_no_issue_selected: "Kein Ticket ausgewÃ¤hlt! Bitte wÃ¤hlen Sie die Tickets, die Sie bearbeiten mÃ¶chten."
+  notice_not_authorized: Sie sind nicht berechtigt, auf diese Seite zuzugreifen.
+  notice_not_authorized_archived_project: Das Projekt wurde archiviert und ist daher nicht nicht verfÃ¼gbar.
+  notice_successful_connection: Verbindung erfolgreich.
+  notice_successful_create: Erfolgreich angelegt
+  notice_successful_delete: Erfolgreich gelÃ¶scht.
+  notice_successful_update: Erfolgreich aktualisiert.
+  notice_unable_delete_time_entry: Der Zeiterfassungseintrag konnte nicht gelÃ¶scht werden.
+  notice_unable_delete_version: Die Version konnte nicht gelÃ¶scht werden.
+  notice_user_successful_create: Benutzer %{id} angelegt.
+
+  permission_add_issue_notes: Kommentare hinzufÃ¼gen
+  permission_add_issue_watchers: Beobachter hinzufÃ¼gen
+  permission_add_issues: Tickets hinzufÃ¼gen
+  permission_add_messages: ForenbeitrÃ¤ge hinzufÃ¼gen
+  permission_add_project: Projekt erstellen
+  permission_add_subprojects: Unterprojekte erstellen
+  permission_add_documents: Dokumente hinzufÃ¼gen
+  permission_browse_repository: Projektarchiv ansehen
+  permission_close_project: SchlieÃŸen / erneutes Ã–ffnen eines Projekts
+  permission_comment_news: News kommentieren
+  permission_commit_access: Commit-Zugriff
+  permission_delete_issue_watchers: Beobachter lÃ¶schen
+  permission_delete_issues: Tickets lÃ¶schen
+  permission_delete_messages: ForenbeitrÃ¤ge lÃ¶schen
+  permission_delete_own_messages: Eigene ForenbeitrÃ¤ge lÃ¶schen
+  permission_delete_wiki_pages: Wiki-Seiten lÃ¶schen
+  permission_delete_wiki_pages_attachments: AnhÃ¤nge lÃ¶schen
+  permission_delete_documents: Dokumente lÃ¶schen
+  permission_edit_issue_notes: Kommentare bearbeiten
+  permission_edit_issues: Tickets bearbeiten
+  permission_edit_messages: ForenbeitrÃ¤ge bearbeiten
+  permission_edit_own_issue_notes: Eigene Kommentare bearbeiten
+  permission_edit_own_messages: Eigene ForenbeitrÃ¤ge bearbeiten
+  permission_edit_own_time_entries: Selbst gebuchte AufwÃ¤nde bearbeiten
+  permission_edit_project: Projekt bearbeiten
+  permission_edit_time_entries: Gebuchte AufwÃ¤nde bearbeiten
+  permission_edit_wiki_pages: Wiki-Seiten bearbeiten
+  permission_edit_documents: Dokumente bearbeiten
+  permission_export_wiki_pages: Wiki-Seiten exportieren
+  permission_log_time: AufwÃ¤nde buchen
+  permission_manage_boards: Foren verwalten
+  permission_manage_categories: Ticket-Kategorien verwalten
+  permission_manage_files: Dateien verwalten
+  permission_manage_issue_relations: Ticket-Beziehungen verwalten
+  permission_manage_members: Mitglieder verwalten
+  permission_manage_news: News verwalten
+  permission_manage_project_activities: AktivitÃ¤ten (Zeiterfassung) verwalten
+  permission_manage_public_queries: Ã–ffentliche Filter verwalten
+  permission_manage_related_issues: ZugehÃ¶rige Tickets verwalten
+  permission_manage_repository: Projektarchiv verwalten
+  permission_manage_subtasks: Unteraufgaben verwalten
+  permission_manage_versions: Versionen verwalten
+  permission_manage_wiki: Wiki verwalten
+  permission_move_issues: Tickets verschieben
+  permission_protect_wiki_pages: Wiki-Seiten schÃ¼tzen
+  permission_rename_wiki_pages: Wiki-Seiten umbenennen
+  permission_save_queries: Filter speichern
+  permission_select_project_modules: Projektmodule auswÃ¤hlen
+  permission_set_issues_private: Tickets privat oder Ã¶ffentlich markieren
+  permission_set_notes_private: Kommentar als privat markieren
+  permission_set_own_issues_private: Eigene Tickets privat oder Ã¶ffentlich markieren
+  permission_view_calendar: Kalender ansehen
+  permission_view_changesets: Changesets ansehen
+  permission_view_documents: Dokumente ansehen
+  permission_view_files: Dateien ansehen
+  permission_view_gantt: Gantt-Diagramm ansehen
+  permission_view_issue_watchers: Liste der Beobachter ansehen
+  permission_view_issues: Tickets anzeigen
+  permission_view_messages: ForenbeitrÃ¤ge ansehen
+  permission_view_private_notes: Private Kommentare sehen
+  permission_view_time_entries: Gebuchte AufwÃ¤nde ansehen
+  permission_view_wiki_edits: Wiki-Versionsgeschichte ansehen
+  permission_view_wiki_pages: Wiki ansehen
+
+  project_module_boards: Foren
+  project_module_calendar: Kalender
+  project_module_documents: Dokumente
+  project_module_files: Dateien
+  project_module_gantt: Gantt
+  project_module_issue_tracking: Ticket-Verfolgung
+  project_module_news: News
+  project_module_repository: Projektarchiv
+  project_module_time_tracking: Zeiterfassung
+  project_module_wiki: Wiki
+  project_status_active: aktiv
+  project_status_archived: archiviert
+  project_status_closed: geschlossen
+
+  setting_activity_days_default: Anzahl Tage pro Seite der Projekt-AktivitÃ¤t
+  setting_app_subtitle: Applikations-Untertitel
+  setting_app_title: Applikations-Titel
+  setting_attachment_max_size: Max. DateigrÃ¶ÃŸe
+  setting_autofetch_changesets: Changesets automatisch abrufen
+  setting_autologin: Automatische Anmeldung
+  setting_bcc_recipients: E-Mails als Blindkopie (BCC) senden
+  setting_cache_formatted_text: Formatierten Text im Cache speichern
+  setting_commit_cross_project_ref: Erlauben auf Tickets aller anderen Projekte zu referenzieren
+  setting_commit_fix_keywords: SchlÃ¼sselwÃ¶rter (Status)
+  setting_commit_logtime_activity_id: AktivitÃ¤t fÃ¼r die Zeiterfassung
+  setting_commit_logtime_enabled: Aktiviere Zeitlogging
+  setting_commit_ref_keywords: SchlÃ¼sselwÃ¶rter (Beziehungen)
+  setting_cross_project_issue_relations: Ticket-Beziehungen zwischen Projekten erlauben
+  setting_cross_project_subtasks: ProjektÃ¼bergreifende Unteraufgaben erlauben
+  setting_date_format: Datumsformat
+  setting_default_issue_start_date_to_creation_date: Aktuelles Datum als Beginn fÃ¼r neue Tickets verwenden
+  setting_default_language: Standardsprache
+  setting_default_notification_option: Standard Benachrichtigungsoptionen
+  setting_default_projects_modules: StandardmÃ¤ÃŸig aktivierte Module fÃ¼r neue Projekte
+  setting_default_projects_public: Neue Projekte sind standardmÃ¤ÃŸig Ã¶ffentlich
+  setting_diff_max_lines_displayed: Maximale Anzahl anzuzeigender Diff-Zeilen
+  setting_display_subprojects_issues: Tickets von Unterprojekten im Hauptprojekt anzeigen
+  setting_emails_footer: E-Mail-FuÃŸzeile
+  setting_emails_header: E-Mail-Kopfzeile
+  setting_enabled_scm: Aktivierte Versionskontrollsysteme
+  setting_feeds_limit: Max. Anzahl EintrÃ¤ge pro Atom-Feed
+  setting_file_max_size_displayed: Maximale GrÃ¶ÃŸe inline angezeigter Textdateien
+  setting_gantt_items_limit: Maximale Anzahl von Aufgaben die im Gantt-Chart angezeigt werden
+  setting_gravatar_default: Standard-Gravatar-Bild
+  setting_gravatar_enabled: Gravatar-Benutzerbilder benutzen
+  setting_host_name: Hostname
+  setting_issue_done_ratio: Berechne den Ticket-Fortschritt mittels
+  setting_issue_done_ratio_issue_field: Ticket-Feld %-erledigt
+  setting_issue_done_ratio_issue_status: Ticket-Status
+  setting_issue_group_assignment: Ticketzuweisung an Gruppen erlauben
+  setting_issue_list_default_columns: Standard-Spalten in der Ticket-Auflistung
+  setting_issues_export_limit: Max. Anzahl Tickets bei CSV/PDF-Export
+  setting_jsonp_enabled: JSONP UnterstÃ¼tzung aktivieren
+  setting_login_required: Authentifizierung erforderlich
+  setting_mail_from: E-Mail-Absender
+  setting_mail_handler_api_enabled: Abruf eingehender E-Mails aktivieren
+  setting_mail_handler_api_key: API-SchlÃ¼ssel
+  setting_mail_handler_body_delimiters: "Schneide E-Mails nach einer dieser Zeilen ab"
+  setting_new_project_user_role_id: Rolle, die einem Nicht-Administrator zugeordnet wird, der ein Projekt erstellt
+  setting_non_working_week_days: Arbeitsfreie Tage
+  setting_openid: Erlaube OpenID-Anmeldung und -Registrierung
+  setting_password_min_length: MindestlÃ¤nge des Kennworts
+  setting_per_page_options: Objekte pro Seite
+  setting_plain_text_mail: Nur reinen Text (kein HTML) senden
+  setting_protocol: Protokoll
+  setting_repositories_encodings: Enkodierung von AnhÃ¤ngen und Repositories
+  setting_repository_log_display_limit: Maximale Anzahl anzuzeigender Revisionen in der Historie einer Datei
+  setting_rest_api_enabled: REST-Schnittstelle aktivieren
+  setting_self_registration: Anmeldung ermÃ¶glicht
+  setting_sequential_project_identifiers: Fortlaufende Projektkennungen generieren
+  setting_session_lifetime: LÃ¤ngste Dauer einer Sitzung
+  setting_session_timeout: ZeitÃ¼berschreitung bei InaktivitÃ¤t
+  setting_start_of_week: Wochenanfang
+  setting_sys_api_enabled: Webservice zur Verwaltung der Projektarchive benutzen
+  setting_text_formatting: Textformatierung
+  setting_thumbnails_enabled: Vorschaubilder von DateianhÃ¤ngen anzeigen
+  setting_thumbnails_size: GrÃ¶ÃŸe der Vorschaubilder (in Pixel)
+  setting_time_format: Zeitformat
+  setting_unsubscribe: Erlaubt Benutzern das eigene Benutzerkonto zu lÃ¶schen
+  setting_user_format: Benutzer-Anzeigeformat
+  setting_welcome_text: Willkommenstext
+  setting_wiki_compression: Wiki-Historie komprimieren
+  setting_default_projects_tracker_ids: StandardmÃ¤ÃŸig aktivierte Tracker fÃ¼r neue Projekte
 
   status_active: aktiv
+  status_locked: gesperrt
   status_registered: nicht aktivierte
-  status_locked: gesperrt
 
-  version_status_open: offen
-  version_status_locked: gesperrt
-  version_status_closed: abgeschlossen
-
-  field_active: Aktiv
-
-  text_select_mail_notifications: Bitte wÃ¤hlen Sie die Aktionen aus, fÃ¼r die eine Mailbenachrichtigung gesendet werden soll.
-  text_regexp_info: z. B. ^[A-Z0-9]+$
-  text_min_max_length_info: 0 heiÃŸt keine BeschrÃ¤nkung
-  text_project_destroy_confirmation: Sind Sie sicher, dass sie das Projekt lÃ¶schen wollen?
-  text_subprojects_destroy_warning: "Dessen Unterprojekte (%{value}) werden ebenfalls gelÃ¶scht."
-  text_workflow_edit: Workflow zum Bearbeiten auswÃ¤hlen
+  text_account_destroy_confirmation: MÃ¶chten Sie wirklich fortfahren?\nIhr Benutzerkonto wird fÃ¼r immer gelÃ¶scht und kann nicht wiederhergestellt werden.
   text_are_you_sure: Sind Sie sicher?
-  text_journal_changed: "%{label} wurde von %{old} zu %{new} geÃ¤ndert"
-  text_journal_set_to: "%{label} wurde auf %{value} gesetzt"
-  text_journal_deleted: "%{label} %{old} wurde gelÃ¶scht"
-  text_journal_added: "%{label} %{value} wurde hinzugefÃ¼gt"
-  text_tip_issue_begin_day: Aufgabe, die an diesem Tag beginnt
-  text_tip_issue_end_day: Aufgabe, die an diesem Tag endet
-  text_tip_issue_begin_end_day: Aufgabe, die an diesem Tag beginnt und endet
-  text_project_identifier_info: 'Kleinbuchstaben (a-z), Ziffern, Binde- und Unterstriche erlaubt.<br />Einmal gespeichert, kann die Kennung nicht mehr geÃ¤ndert werden.'
+  text_assign_time_entries_to_project: Gebuchte AufwÃ¤nde dem Projekt zuweisen
   text_caracters_maximum: "Max. %{count} Zeichen."
   text_caracters_minimum: "Muss mindestens %{count} Zeichen lang sein."
+  text_comma_separated: Mehrere Werte erlaubt (durch Komma getrennt).
+  text_custom_field_possible_values_info: 'Eine Zeile pro Wert'
+  text_default_administrator_account_changed: Administrator-Kennwort geÃ¤ndert
+  text_destroy_time_entries: Gebuchte AufwÃ¤nde lÃ¶schen
+  text_destroy_time_entries_question: Es wurden bereits %{hours} Stunden auf dieses Ticket gebucht. Was soll mit den AufwÃ¤nden geschehen?
+  text_diff_truncated: '... Dieser Diff wurde abgeschnitten, weil er die maximale Anzahl anzuzeigender Zeilen Ã¼berschreitet.'
+  text_email_delivery_not_configured: "Der SMTP-Server ist nicht konfiguriert und Mailbenachrichtigungen sind ausgeschaltet.\nNehmen Sie die Einstellungen fÃ¼r Ihren SMTP-Server in config/configuration.yml vor und starten Sie die Applikation neu."
+  text_enumeration_category_reassign_to: 'Die Objekte stattdessen diesem Wert zuordnen:'
+  text_enumeration_destroy_question: "%{count} Objekt(e) sind diesem Wert zugeordnet."
+  text_file_repository_writable: Verzeichnis fÃ¼r Dateien beschreibbar
+  text_git_repository_note: Repository steht fÃ¼r sich alleine (bare) und liegt lokal (z.B. /gitrepo, c:\gitrepo)
+  text_issue_added: "Ticket %{id} wurde erstellt von %{author}."
+  text_issue_category_destroy_assignments: Kategorie-Zuordnung entfernen
+  text_issue_category_destroy_question: "Einige Tickets (%{count}) sind dieser Kategorie zugeodnet. Was mÃ¶chten Sie tun?"
+  text_issue_category_reassign_to: Tickets dieser Kategorie zuordnen
+  text_issue_conflict_resolution_add_notes: Meine Ã„nderungen Ã¼bernehmen und alle anderen Ã„nderungen verwerfen
+  text_issue_conflict_resolution_cancel: Meine Ã„nderungen verwerfen und %{link} neu anzeigen
+  text_issue_conflict_resolution_overwrite: Meine Ã„nderungen trotzdem Ã¼bernehmen (vorherige Notizen bleiben erhalten aber manche kÃ¶nnen Ã¼berschrieben werden)
+  text_issue_updated: "Ticket %{id} wurde aktualisiert von %{author}."
+  text_issues_destroy_confirmation: 'Sind Sie sicher, dass Sie die ausgewÃ¤hlten Tickets lÃ¶schen mÃ¶chten?'
+  text_issues_destroy_descendants_confirmation: Dies wird auch %{count} Unteraufgabe/n lÃ¶schen.
+  text_issues_ref_in_commit_messages: Ticket-Beziehungen und -Status in Commit-Log-Meldungen
+  text_journal_added: "%{label} %{value} wurde hinzugefÃ¼gt"
+  text_journal_changed: "%{label} wurde von %{old} zu %{new} geÃ¤ndert"
+  text_journal_changed_no_detail: "%{label} aktualisiert"
+  text_journal_deleted: "%{label} %{old} wurde gelÃ¶scht"
+  text_journal_set_to: "%{label} wurde auf %{value} gesetzt"
   text_length_between: "LÃ¤nge zwischen %{min} und %{max} Zeichen."
+  text_line_separated: Mehrere Werte sind erlaubt (eine Zeile pro Wert).
+  text_load_default_configuration: Standard-Konfiguration laden
+  text_mercurial_repository_note: Lokales repository (e.g. /hgrepo, c:\hgrepo)
+  text_min_max_length_info: 0 heiÃŸt keine BeschrÃ¤nkung
+  text_no_configuration_data: "Rollen, Tracker, Ticket-Status und Workflows wurden noch nicht konfiguriert.\nEs ist sehr zu empfehlen, die Standard-Konfiguration zu laden. Sobald sie geladen ist, kÃ¶nnen Sie sie abÃ¤ndern."
+  text_own_membership_delete_confirmation: "Sie sind dabei, einige oder alle Ihre Berechtigungen zu entfernen. Es ist mÃ¶glich, dass Sie danach das Projekt nicht mehr ansehen oder bearbeiten dÃ¼rfen.\nSind Sie sicher, dass Sie dies tun mÃ¶chten?"
+  text_plugin_assets_writable: Verzeichnis fÃ¼r Plugin-Assets beschreibbar
+  text_project_closed: Dieses Projekt ist geschlossen und kann nicht bearbeitet werden.
+  text_project_destroy_confirmation: Sind Sie sicher, dass Sie das Projekt lÃ¶schen wollen?
+  text_project_identifier_info: 'Kleinbuchstaben (a-z), Ziffern, Binde- und Unterstriche erlaubt, muss mit einem Kleinbuchstaben beginnen.<br />Einmal gespeichert, kann die Kennung nicht mehr geÃ¤ndert werden.'
+  text_reassign_time_entries: 'Gebuchte AufwÃ¤nde diesem Ticket zuweisen:'
+  text_regexp_info: z. B. ^[A-Z0-9]+$
+  text_repository_identifier_info: 'Kleinbuchstaben (a-z), Ziffern, Binde- und Unterstriche erlaubt.<br />Einmal gespeichert, kann die Kennung nicht mehr geÃ¤ndert werden.'
+  text_repository_usernames_mapping: "Bitte legen Sie die Zuordnung der Redmine-Benutzer zu den Benutzernamen der Commit-Log-Meldungen des Projektarchivs fest.\nBenutzer mit identischen Redmine- und Projektarchiv-Benutzernamen oder -E-Mail-Adressen werden automatisch zugeordnet."
+  text_rmagick_available: RMagick verfÃ¼gbar (optional)
+  text_scm_command: Kommando
+  text_scm_command_not_available: SCM-Kommando ist nicht verfÃ¼gbar. Bitte prÃ¼fen Sie die Einstellungen im Administrationspanel.
+  text_scm_command_version: Version
+  text_scm_config: Die SCM-Kommandos kÃ¶nnen in der in config/configuration.yml konfiguriert werden. Redmine muss anschlieÃŸend neu gestartet werden.
+  text_scm_path_encoding_note: "Standard: UTF-8"
+  text_select_mail_notifications: Bitte wÃ¤hlen Sie die Aktionen aus, fÃ¼r die eine Mailbenachrichtigung gesendet werden soll.
+  text_select_project_modules: 'Bitte wÃ¤hlen Sie die Module aus, die in diesem Projekt aktiviert sein sollen:'
+  text_session_expiration_settings: "Achtung: Ã„nderungen kÃ¶nnen aktuelle Sitzungen beenden, Ihre eingeschlossen!" 
+  text_status_changed_by_changeset: "Status geÃ¤ndert durch Changeset %{value}."
+  text_subprojects_destroy_warning: "Dessen Unterprojekte (%{value}) werden ebenfalls gelÃ¶scht."
+  text_time_entries_destroy_confirmation: Sind Sie sicher, dass Sie die ausgewÃ¤hlten ZeitaufwÃ¤nde lÃ¶schen mÃ¶chten?
+  text_time_logged_by_changeset: Angewendet in Changeset %{value}.
+  text_tip_issue_begin_day: Aufgabe, die an diesem Tag beginnt
+  text_tip_issue_begin_end_day: Aufgabe, die an diesem Tag beginnt und endet
+  text_tip_issue_end_day: Aufgabe, die an diesem Tag endet
   text_tracker_no_workflow: Kein Workflow fÃ¼r diesen Tracker definiert.
+  text_turning_multiple_off: Wenn Sie die Mehrfachauswahl deaktivieren, werden Felder mit Mehrfachauswahl bereinigt.
+    Dadurch wird sichergestellt, dass lediglich ein Wert pro Feld ausgewÃ¤hlt ist.
   text_unallowed_characters: Nicht erlaubte Zeichen
-  text_comma_separated: Mehrere Werte erlaubt (durch Komma getrennt).
-  text_line_separated: Mehrere Werte sind erlaubt (eine Zeile pro Wert).
-  text_issues_ref_in_commit_messages: Ticket-Beziehungen und -Status in Commit-Log-Meldungen
-  text_issue_added: "Ticket %{id} wurde erstellt von %{author}."
-  text_issue_updated: "Ticket %{id} wurde aktualisiert von %{author}."
+  text_user_mail_option: "FÃ¼r nicht ausgewÃ¤hlte Projekte werden Sie nur Benachrichtigungen fÃ¼r Dinge erhalten, die Sie beobachten oder an denen Sie beteiligt sind (z. B. Tickets, deren Autor Sie sind oder die Ihnen zugewiesen sind)."
+  text_user_wrote: "%{value} schrieb:"
+  text_warn_on_leaving_unsaved: Die aktuellen Ã„nderungen gehen verloren, wenn Sie diese Seite verlassen.
   text_wiki_destroy_confirmation: Sind Sie sicher, dass Sie dieses Wiki mit sÃ¤mtlichem Inhalt lÃ¶schen mÃ¶chten?
-  text_issue_category_destroy_question: "Einige Tickets (%{count}) sind dieser Kategorie zugeodnet. Was mÃ¶chten Sie tun?"
-  text_issue_category_destroy_assignments: Kategorie-Zuordnung entfernen
-  text_issue_category_reassign_to: Tickets dieser Kategorie zuordnen
-  text_user_mail_option: "FÃ¼r nicht ausgewÃ¤hlte Projekte werden Sie nur Benachrichtigungen fÃ¼r Dinge erhalten, die Sie beobachten oder an denen Sie beteiligt sind (z. B. Tickets, deren Autor Sie sind oder die Ihnen zugewiesen sind)."
-  text_no_configuration_data: "Rollen, Tracker, Ticket-Status und Workflows wurden noch nicht konfiguriert.\nEs ist sehr zu empfehlen, die Standard-Konfiguration zu laden. Sobald sie geladen ist, kÃ¶nnen Sie sie abÃ¤ndern."
-  text_load_default_configuration: Standard-Konfiguration laden
-  text_status_changed_by_changeset: "Status geÃ¤ndert durch Changeset %{value}."
-  text_issues_destroy_confirmation: 'Sind Sie sicher, dass Sie die ausgewÃ¤hlten Tickets lÃ¶schen mÃ¶chten?'
-  text_select_project_modules: 'Bitte wÃ¤hlen Sie die Module aus, die in diesem Projekt aktiviert sein sollen:'
-  text_default_administrator_account_changed: Administrator-Kennwort geÃ¤ndert
-  text_file_repository_writable: Verzeichnis fÃ¼r Dateien beschreibbar
-  text_plugin_assets_writable: Verzeichnis fÃ¼r Plugin-Assets beschreibbar
-  text_rmagick_available: RMagick verfÃ¼gbar (optional)
-  text_destroy_time_entries_question: Es wurden bereits %{hours} Stunden auf dieses Ticket gebucht. Was soll mit den AufwÃ¤nden geschehen?
-  text_destroy_time_entries: Gebuchte AufwÃ¤nde lÃ¶schen
-  text_assign_time_entries_to_project: Gebuchte AufwÃ¤nde dem Projekt zuweisen
-  text_reassign_time_entries: 'Gebuchte AufwÃ¤nde diesem Ticket zuweisen:'
-  text_user_wrote: "%{value} schrieb:"
-  text_enumeration_destroy_question: "%{count} Objekt(e) sind diesem Wert zugeordnet."
-  text_enumeration_category_reassign_to: 'Die Objekte stattdessen diesem Wert zuordnen:'
-  text_email_delivery_not_configured: "Der SMTP-Server ist nicht konfiguriert und Mailbenachrichtigungen sind ausgeschaltet.\nNehmen Sie die Einstellungen fÃ¼r Ihren SMTP-Server in config/configuration.yml vor und starten Sie die Applikation neu."
-  text_repository_usernames_mapping: "Bitte legen Sie die Zuordnung der Redmine-Benutzer zu den Benutzernamen der Commit-Log-Meldungen des Projektarchivs fest.\nBenutzer mit identischen Redmine- und Projektarchiv-Benutzernamen oder -E-Mail-Adressen werden automatisch zugeordnet."
-  text_diff_truncated: '... Dieser Diff wurde abgeschnitten, weil er die maximale Anzahl anzuzeigender Zeilen Ã¼berschreitet.'
-  text_custom_field_possible_values_info: 'Eine Zeile pro Wert'
+  text_wiki_page_destroy_children: LÃ¶sche alle Unterseiten
   text_wiki_page_destroy_question: "Diese Seite hat %{descendants} Unterseite(n). Was mÃ¶chten Sie tun?"
   text_wiki_page_nullify_children: Verschiebe die Unterseiten auf die oberste Ebene
-  text_wiki_page_destroy_children: LÃ¶sche alle Unterseiten
   text_wiki_page_reassign_children: Ordne die Unterseiten dieser Seite zu
-  text_own_membership_delete_confirmation: "Sie sind dabei, einige oder alle Ihre Berechtigungen zu entfernen. Es ist mÃ¶glich, dass Sie danach das Projekt nicht mehr ansehen oder bearbeiten dÃ¼rfen.\nSind Sie sicher, dass Sie dies tun mÃ¶chten?"
-  text_zoom_in: Zoom in
-  text_zoom_out: Zoom out
+  text_workflow_edit: Workflow zum Bearbeiten auswÃ¤hlen
+  text_zoom_in: Ansicht vergrÃ¶ÃŸern
+  text_zoom_out: Ansicht verkleinern
 
-  default_role_manager: Manager
-  default_role_developer: Entwickler
-  default_role_reporter: Reporter
-  default_tracker_bug: Fehler
-  default_tracker_feature: Feature
-  default_tracker_support: UnterstÃ¼tzung
-  default_issue_status_new: Neu
-  default_issue_status_in_progress: In Bearbeitung
-  default_issue_status_resolved: GelÃ¶st
-  default_issue_status_feedback: Feedback
-  default_issue_status_closed: Erledigt
-  default_issue_status_rejected: Abgewiesen
-  default_doc_category_user: Benutzerdokumentation
-  default_doc_category_tech: Technische Dokumentation
-  default_priority_low: Niedrig
-  default_priority_normal: Normal
-  default_priority_high: Hoch
-  default_priority_urgent: Dringend
-  default_priority_immediate: Sofort
-  default_activity_design: Design
-  default_activity_development: Entwicklung
+  version_status_closed: abgeschlossen
+  version_status_locked: gesperrt
+  version_status_open: offen
 
-  enumeration_issue_priorities: Ticket-PrioritÃ¤ten
-  enumeration_doc_categories: Dokumentenkategorien
-  enumeration_activities: AktivitÃ¤ten (Zeiterfassung)
-  enumeration_system_activity: System-AktivitÃ¤t
-
-  field_text: Textfeld
-  label_user_mail_option_only_owner: Nur fÃ¼r Aufgaben die ich angelegt habe
-  setting_default_notification_option: Standard Benachrichtigungsoptionen
-  label_user_mail_option_only_my_events: Nur fÃ¼r Aufgaben die ich beobachte oder an welchen ich mitarbeite
-  label_user_mail_option_only_assigned: Nur fÃ¼r Aufgaben fÃ¼r die ich zustÃ¤ndig bin.
-  notice_not_authorized_archived_project: Das Projekt wurde archiviert und ist daher nicht nicht verfÃ¼gbar.
-  label_user_mail_option_none: keine Ereignisse
-  field_member_of_group: ZustÃ¤ndigkeitsgruppe
-  field_assigned_to_role: ZustÃ¤ndigkeitsrolle
-  field_visible: Sichtbar
-  setting_emails_header: E-Mail Betreffzeile
-  setting_commit_logtime_activity_id: AktivitÃ¤t fÃ¼r die Zeiterfassung
-  text_time_logged_by_changeset: Angewendet in Changeset %{value}.
-  setting_commit_logtime_enabled: Aktiviere Zeitlogging
-  notice_gantt_chart_truncated: Die Grafik ist unvollstÃ¤ndig, da das Maximum der anzeigbaren Aufgaben Ã¼berschritten wurde (%{max})
-  setting_gantt_items_limit: Maximale Anzahl von Aufgaben die im Gantt-Chart angezeigt werden.
-  field_warn_on_leaving_unsaved: vor dem Verlassen einer Seite mit ungesichertem Text im Editor warnen
-  text_warn_on_leaving_unsaved: Die aktuellen Ã„nderungen gehen verloren, wenn Sie diese Seite verlassen.
-  label_my_queries: Meine eigenen Abfragen
-  text_journal_changed_no_detail: "%{label} aktualisiert"
-  label_news_comment_added: Kommentar zu einer News hinzugefÃ¼gt
-  button_expand_all: Alle ausklappen
-  button_collapse_all: Alle einklappen
-  label_additional_workflow_transitions_for_assignee: ZusÃ¤tzliche Berechtigungen wenn der Benutzer der Zugewiesene ist
-  label_additional_workflow_transitions_for_author: ZusÃ¤tzliche Berechtigungen wenn der Benutzer der Autor ist
-  label_bulk_edit_selected_time_entries: AusgewÃ¤hlte ZeitaufwÃ¤nde bearbeiten
-  text_time_entries_destroy_confirmation: Sind Sie sicher, dass Sie die ausgewÃ¤hlten ZeitaufwÃ¤nde lÃ¶schen mÃ¶chten?
-  label_role_anonymous: Anonymous
-  label_role_non_member: Nichtmitglied
-  label_issue_note_added: Notiz hinzugefÃ¼gt
-  label_issue_status_updated: Status aktualisiert
-  label_issue_priority_updated: PrioritÃ¤t aktualisiert
-  label_issues_visibility_own: Tickets die folgender User erstellt hat oder die ihm zugewiesen sind
-  field_issues_visibility: Ticket Sichtbarkeit
-  label_issues_visibility_all: Alle Tickets
-  permission_set_own_issues_private: Eigene Tickets privat oder Ã¶ffentlich markieren
-  field_is_private: Privat
-  permission_set_issues_private: Tickets privat oder Ã¶ffentlich markieren
-  label_issues_visibility_public: Alle Ã¶ffentlichen Tickets
-  text_issues_destroy_descendants_confirmation: Dies wird auch %{count} Unteraufgabe/n lÃ¶schen.
-  field_commit_logs_encoding: Kodierung der Commit-Log-Meldungen
-  field_scm_path_encoding: Pfad Kodierung
-  text_scm_path_encoding_note: "Standard: UTF-8"
-  field_path_to_repository: Pfad zum repository
-  field_root_directory: Wurzelverzeichnis
-  field_cvs_module: Modul
-  field_cvsroot: CVSROOT
-  text_mercurial_repository_note: Lokales repository (e.g. /hgrepo, c:\hgrepo)
-  text_scm_command: Kommando
-  text_scm_command_version: Version
-  label_git_report_last_commit: Bericht des letzten Commits fÃ¼r Dateien und Verzeichnisse
-  text_scm_config: Die SCM-Kommandos kÃ¶nnen in der in config/configuration.yml konfiguriert werden. Redmine muss anschlieÃŸend neu gestartet werden.
-  text_scm_command_not_available: Scm Kommando ist nicht verfÃ¼gbar. Bitte prÃ¼fen Sie die Einstellungen im Administrationspanel.
-
-  notice_issue_successful_create: Ticket %{id} erstellt.
-  label_between: zwischen
-  setting_issue_group_assignment: Ticketzuweisung an Gruppen erlauben
-  label_diff: diff
-  text_git_repository_note: Repository steht fÃ¼r sich alleine (bare) und liegt lokal (z.B. /gitrepo, c:\gitrepo)
-
-  description_filter: Filter
-  description_search: Suchfeld
-  description_choose_project: Projekte
-  description_project_scope: Suchbereich
-  description_notes: Kommentare
-  description_message_content: Nachrichteninhalt
-  description_query_sort_criteria_attribute: Sortierattribut
-  description_query_sort_criteria_direction: Sortierrichtung
-  description_user_mail_notification: Mailbenachrichtigungseinstellung
-  description_available_columns: VerfÃ¼gbare Spalten
-  description_selected_columns: AusgewÃ¤hlte Spalten
-  description_issue_category_reassign: Neue Kategorie wÃ¤hlen
-  description_wiki_subpages_reassign: Neue Elternseite wÃ¤hlen
-  description_date_range_list: Zeitraum aus einer Liste wÃ¤hlen
-  description_date_range_interval: Zeitraum durch Start- und Enddatum festlegen
-  description_date_from: Startdatum eintragen
-  description_date_to: Enddatum eintragen
-
-  label_parent_revision: VorgÃ¤nger
-  label_child_revision: Nachfolger
-  error_scm_annotate_big_text_file: Der Eintrag kann nicht umgesetzt werden, da er die maximale TextlÃ¤nge Ã¼berschreitet.
-  setting_default_issue_start_date_to_creation_date: Aktuelles Datum als Beginn fÃ¼r neue Tickets verwenden
-  button_edit_section: Diesen Bereich bearbeiten
-  setting_repositories_encodings: Encoding von AnhÃ¤ngen und Repositories
-  description_all_columns: Alle Spalten
-  button_export: Exportieren
-  label_export_options: "%{export_format} Export-Eigenschaften"
-  error_attachment_too_big: Diese Datei kann nicht hochgeladen werden, da sie die maximale DateigrÃ¶ÃŸe von (%{max_size}) Ã¼berschreitet.
-  notice_failed_to_save_time_entries: "Gescheitert %{count} ZeiteintrÃ¤ge fÃ¼r %{total} von ausgewÃ¤hlten: %{ids} zu speichern." 
-  label_x_issues:
-    zero:  0 Tickets
-    one:   1 Ticket
-    other: "%{count} Tickets"
-  label_repository_new: Neues Repository
-  field_repository_is_default: Haupt-Repository
-  label_copy_attachments: AnhÃ¤nge Kopieren
-  label_item_position: "%{position}/%{count}"
-  label_completed_versions: Abgeschlossene Versionen
-  field_multiple: Mehrere Werte
-  setting_commit_cross_project_ref: Erlauben auf Tickets aller anderen Projekte zu referenzieren
-  text_issue_conflict_resolution_add_notes: Meine Ã„nderungen Ã¼bernehmen und alle anderen Ã„nderungen verwerfen
-  text_issue_conflict_resolution_overwrite: Meine Ã„nderungen trotzdem Ã¼bernehmen (vorherige Notizen bleiben erhalten aber manche kÃ¶nnen Ã¼berschrieben werden)
-  notice_issue_update_conflict: Das Ticket wurde von einem anderen Nutzer Ã¼berarbeitet wÃ¤hrend Ihrer Bearbeitung.
-  text_issue_conflict_resolution_cancel: Meine Ã„nderungen verwerfen und %{link} neu anzeigen
-  permission_manage_related_issues: ZugehÃ¶rige Tickets verwalten
-  field_auth_source_ldap_filter: LDAP Filter
-  label_search_for_watchers: Nach hinzufÃ¼gbaren Beobachtern suchen
-  notice_account_deleted: Ihr Benutzerkonto wurde unwiderruflich gelÃ¶scht.
-  setting_unsubscribe: Erlaubt Benutzern das eigene Benutzerkonto zu lÃ¶schen
-  button_delete_my_account: Mein Benutzerkonto lÃ¶schen 
-  text_account_destroy_confirmation: MÃ¶chten Sie wirklich fortfahren?\nIhr Benutzerkonto wird fÃ¼r immer gelÃ¶scht und kann nicht wiederhergestellt werden.
-  error_session_expired: Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.
-  text_session_expiration_settings: "Achtung: Ã„nderungen kÃ¶nnen aktuelle Sitzungen beenden, Ihre eingeschlossen!" 
-  setting_session_lifetime: LÃ¤ngste Dauer einer Sitzung
-  setting_session_timeout: ZeitÃ¼berschreitung bei InaktivitÃ¤t
-  label_session_expiration: Ende einer Sitzung
-  permission_close_project: SchlieÃŸen / erneutes Ã–ffnen eines Projekts
-  label_show_closed_projects: Geschlossene Projekte anzeigen
-  button_close: SchlieÃŸen
-  button_reopen: Ã–ffnen
-  project_status_active: aktiv
-  project_status_closed: geschlossen
-  project_status_archived: archiviert
-  text_project_closed: Dieses Projekt ist geschlossen und kann nicht bearbeitet werden.
-  notice_user_successful_create: Benutzer %{id} angelegt.
-  field_core_fields: Standardwerte
-  field_timeout: Auszeit (in Sekunden)
-  setting_thumbnails_enabled: Vorschaubilder von DateianhÃ¤ngen anzeigen
-  setting_thumbnails_size: GrÃ¶ÃŸe der Vorschaubilder (in Pixel)
-  label_status_transitions: StatusÃ¤nderungen
-  label_fields_permissions: Feldberechtigungen
-  label_readonly: Nur-Lese-Zugriff
-  label_required: Erforderlich
-  text_repository_identifier_info: 'Kleinbuchstaben (a-z), Ziffern, Binde- und Unterstriche erlaubt.<br />Einmal gespeichert, kann die Kennung nicht mehr geÃ¤ndert werden.'
-  field_board_parent: Ãœbergeordnetes Forum
-  label_attribute_of_project: "%{name} des Projekts"
-  label_attribute_of_author: "%{name} des Autors"
-  label_attribute_of_assigned_to: "%{name} des Bearbeiters"
-  label_attribute_of_fixed_version: "%{name} der Zielversion"
-  label_copy_subtasks: Unteraufgaben kopieren
-  label_copied_to: Kopiert nach
-  label_copied_from: Kopiert von
-  label_any_issues_in_project: irgendein Ticket im Projekt
-  label_any_issues_not_in_project: irgendein Ticket nicht im Projekt
-  field_private_notes: Privater Kommentar
-  permission_view_private_notes: Private Kommentare sehen
-  permission_set_notes_private: Kommentar als privat markieren
-  label_no_issues_in_project: keine Tickets im Projekt
-  label_any: alle
-  label_last_n_weeks: letzte %{count} Wochen
-  setting_cross_project_subtasks: ProjektÃ¼bergreifende Unteraufgaben erlauben
-  label_cross_project_descendants: Mit Unterprojekten
-  label_cross_project_tree: Mit Projektbaum
-  label_cross_project_hierarchy: Mit Projekthierarchie
-  label_cross_project_system: Mit allen Projekten
-  button_hide: Verstecken
-  setting_non_working_week_days: Arbeitsfreie Tage
-  label_in_the_next_days: in den nÃ¤chsten
-  label_in_the_past_days: in den letzten
+  warning_attachments_not_saved: "%{count} Datei(en) konnten nicht gespeichert werden."
+  label_total_time: Gesamtzeit
diff -r 0a574315af3e -r 4f746d8966dd config/locales/el.yml
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -52,8 +52,8 @@
         one:   "Ï€ÎµÏÎ¯Ï€Î¿Ï… 1 ÏŽÏÎ±"
         other: "Ï€ÎµÏÎ¯Ï€Î¿Ï… %{count} ÏŽÏÎµÏ‚"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 ÏŽÏÎ±"
+        other: "%{count} ÏŽÏÎµÏ‚"
       x_days:
         one:   "1 Î·Î¼Î­ÏÎ±"
         other: "%{count} Î·Î¼Î­ÏÎµÏ‚"
@@ -194,8 +194,6 @@
   mail_subject_wiki_content_updated: "'ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î· ÏƒÎµÎ»Î¯Î´Î± wiki %{id}' "
   mail_body_wiki_content_updated: "Î— ÏƒÎµÎ»Î¯Î´Î± wiki  '%{id}' ÎµÎ½Î·Î¼ÎµÏÏŽÎ¸Î·ÎºÎµ Î±Ï€ÏŒ Ï„Î¿Î½ %{author}."
 
-  gui_validation_error: 1 ÏƒÏ†Î¬Î»Î¼Î±
-  gui_validation_error_plural: "%{count} ÏƒÏ†Î¬Î»Î¼Î±Ï„Î±"
 
   field_name: ÎŒÎ½Î¿Î¼Î±
   field_description: Î ÎµÏÎ¹Î³ÏÎ±Ï†Î®
@@ -356,7 +354,6 @@
   permission_edit_own_time_entries: Î•Ï€ÎµÎ¾ÎµÏÎ³Î±ÏƒÎ¯Î± Î´Î¹ÎºÎ¿Ï Î¼Î¿Ï… Î¹ÏƒÏ„Î¿ÏÎ¹ÎºÎ¿Ï Ï‡ÏÏŒÎ½Î¿Ï…
   permission_manage_news: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î½Î­Ï‰Î½
   permission_comment_news: Î£Ï‡Î¿Î»Î¹Î±ÏƒÎ¼ÏŒÏ‚ Î½Î­Ï‰Î½
-  permission_manage_documents: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· ÎµÎ³Î³ÏÎ¬Ï†Ï‰Î½
   permission_view_documents: Î ÏÎ¿Î²Î¿Î»Î® ÎµÎ³Î³ÏÎ¬Ï†Ï‰Î½
   permission_manage_files: Î”Î¹Î±Ï‡ÎµÎ¯ÏÎ¹ÏƒÎ· Î±ÏÏ‡ÎµÎ¯Ï‰Î½
   permission_view_files: Î ÏÎ¿Î²Î¿Î»Î® Î±ÏÏ‡ÎµÎ¯Ï‰Î½
@@ -475,8 +472,6 @@
   label_text: ÎœÎ±ÎºÏÎ¿ÏƒÎºÎµÎ»Î­Ï‚ ÎºÎµÎ¯Î¼ÎµÎ½Î¿
   label_attribute: Î™Î´Î¹ÏŒÏ„Î·Ï„Î±
   label_attribute_plural: Î™Î´Î¹ÏŒÏ„Î·Ï„ÎµÏ‚
-  label_download: "%{count} ÎœÎµÏ„Î±Ï†ÏŒÏÏ„Ï‰ÏƒÎ·"
-  label_download_plural: "%{count} ÎœÎµÏ„Î±Ï†Î¿ÏÏ„ÏŽÏƒÎµÎ¹Ï‚"
   label_no_data: Î”ÎµÎ½ Ï…Ï€Î¬ÏÏ‡Î¿Ï…Î½ Î´ÎµÎ´Î¿Î¼Î­Î½Î±
   label_change_status: Î‘Î»Î»Î±Î³Î® ÎºÎ±Ï„Î¬ÏƒÏ„Î±ÏƒÎ·Ï‚
   label_history: Î™ÏƒÏ„Î¿ÏÎ¹ÎºÏŒ
@@ -578,8 +573,6 @@
   label_repository: Î‘Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î¿
   label_repository_plural: Î‘Ï€Î¿Î¸ÎµÏ„Î®ÏÎ¹Î±
   label_browse: Î Î»Î¿Î®Î³Î·ÏƒÎ·
-  label_modification: "%{count} Ï„ÏÎ¿Ï€Î¿Ï€Î¿Î¯Î·ÏƒÎ·"
-  label_modification_plural: "%{count} Ï„ÏÎ¿Ï€Î¿Ï€Î¿Î¹Î®ÏƒÎµÎ¹Ï‚"
   label_branch: Branch
   label_tag: Tag
   label_revision: Î‘Î½Î±Î¸ÎµÏŽÏÎ·ÏƒÎ·
@@ -933,7 +926,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -974,8 +966,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1082,3 +1072,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Î£ÏÎ½Î¿Î»Î¿
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/en.yml
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -221,9 +221,6 @@
   mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
   mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
 
-  gui_validation_error: 1 error
-  gui_validation_error_plural: "%{count} errors"
-
   field_ssamr_user_detail:
     description: User Description  
     institution: Institution
@@ -243,6 +240,7 @@
   field_author: Author
   field_created_on: Created
   field_updated_on: Updated
+  field_closed_on: Closed
   field_field_format: Format
   field_is_for_all: For all projects
   field_possible_values: Possible values
@@ -345,6 +343,7 @@
   field_board_parent: Parent forum
   field_private_notes: Private notes
   field_public_or_private: "Public or Private?"
+  field_inherit_members: Inherit members
 
   setting_external_repository: "Select this if the project's main repository is hosted somewhere else"
   setting_external_repository_url: "The URL of the existing external repository. Must be publicly accessible without a password"
@@ -378,8 +377,8 @@
   setting_cross_project_subtasks: Allow cross-project subtasks
   setting_issue_list_default_columns: Default columns displayed on the issue list
   setting_repositories_encodings: Attachments and repositories encodings
-  setting_emails_header: Emails header
-  setting_emails_footer: Emails footer
+  setting_emails_header: Email header
+  setting_emails_footer: Email footer
   setting_protocol: Protocol
   setting_per_page_options: Objects per page options
   setting_user_format: Users display format
@@ -421,6 +420,8 @@
   setting_thumbnails_enabled: Display attachment thumbnails
   setting_thumbnails_size: Thumbnails size (in pixels)
   setting_non_working_week_days: Non-working days
+  setting_jsonp_enabled: Enable JSONP support
+  setting_default_projects_tracker_ids: Default trackers for new projects
 
   permission_add_project: Create project
   permission_add_subprojects: Create subprojects
@@ -457,10 +458,12 @@
   permission_edit_own_time_entries: Edit own time logs
   permission_manage_news: Manage news
   permission_comment_news: Comment news
-  permission_manage_documents: Manage documents
   permission_view_documents: View documents
   permission_manage_files: Manage downloads
   permission_view_files: View downloads
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
   permission_manage_wiki: Manage wiki
   permission_rename_wiki_pages: Rename wiki pages
   permission_delete_wiki_pages: Delete wiki pages
@@ -613,8 +616,6 @@
   label_text: Long text
   label_attribute: Attribute
   label_attribute_plural: Attributes
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
   label_no_data: No data to display
   label_change_status: Change status
   label_history: History
@@ -665,6 +666,7 @@
     one:   1 issue
     other: "%{count} issues"
   label_total: Total
+  label_total_time: Total time
   label_permissions: Permissions
   label_current_status: Current status
   label_new_statuses_allowed: New statuses allowed
@@ -735,8 +737,6 @@
   label_is_external_repository: Track an external repository
   label_repository_plural: Repositories
   label_explore_projects: Explore projects
-  label_modification: "%{count} change"
-  label_modification_plural: "%{count} changes"
   label_branch: Branch
   label_tag: Tag
   label_revision: Revision
@@ -939,13 +939,16 @@
   label_readonly: Read-only
   label_required: Required
   label_attribute_of_project: "Project's %{name}"
+  label_attribute_of_issue: "Issue's %{name}"
   label_attribute_of_author: "Author's %{name}"
   label_attribute_of_assigned_to: "Assignee's %{name}"
+  label_attribute_of_user: "User's %{name}"
   label_attribute_of_fixed_version: "Target version's %{name}"
   label_cross_project_descendants: With subprojects
   label_cross_project_tree: With project tree
   label_cross_project_hierarchy: With project hierarchy
   label_cross_project_system: With all projects
+  label_gantt_progress_line: Progress line
 
   button_login: Login
   button_submit: Submit
@@ -1094,14 +1097,15 @@
   text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
   text_scm_command: Command
   text_scm_command_version: Version
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
   text_issue_conflict_resolution_overwrite: "Apply my changes anyway (previous notes will be kept but some changes may be overwritten)"
   text_issue_conflict_resolution_add_notes: "Add my notes and discard my other changes"
   text_issue_conflict_resolution_cancel: "Discard all my changes and redisplay %{link}"
   text_account_destroy_confirmation: "Are you sure you want to proceed?\nYour account will be permanently deleted, with no way to reactivate it."
   text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
   text_project_closed: This project is closed and read-only.
+  text_turning_multiple_off: "If you disable multiple values, multiple values will be removed in order to preserve only one value per item."
   text_settings_repo_explanation: <b>External repositories</b><p>Normally your project's primary repository will be the Mercurial repository hosted at this site.<p>However, if you already have your project hosted somewhere else, you can specify your existing external repository's URL here &ndash; then this site will track that repository in a read-only &ldquo;mirror&rdquo; copy.  External Mercurial, git and Subversion repositories can be tracked. Note that you cannot switch to an external repository if you have already made any commits to the repository hosted here.
   text_settings_repo_is_internal: Currently the repository hosted at this site is the primary repository for this project.
   text_settings_repo_is_external: Currently the repository hosted at this site is a read-only copy of an external repository.
diff -r 0a574315af3e -r 4f746d8966dd config/locales/es.yml
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -80,8 +80,8 @@
         one:  "alrededor de 1 hora"
         other: "alrededor de %{count} horas"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 hora"
+        other: "%{count} horas"
       x_days:
         one:  "1 dÃ­a"
         other: "%{count} dÃ­as"
@@ -203,7 +203,7 @@
   button_list: Listar
   button_lock: Bloquear
   button_log_time: Tiempo dedicado
-  button_login: ConexiÃ³n
+  button_login: Acceder
   button_move: Mover
   button_quote: Citar
   button_rename: Renombrar
@@ -345,8 +345,6 @@
   general_text_Yes: 'SÃ­'
   general_text_no: 'no'
   general_text_yes: 'sÃ­'
-  gui_validation_error: 1 error
-  gui_validation_error_plural: "%{count} errores"
   label_activity: Actividad
   label_add_another_file: AÃ±adir otro fichero
   label_add_note: AÃ±adir una nota
@@ -439,8 +437,6 @@
   label_document_added: Documento aÃ±adido
   label_document_new: Nuevo documento
   label_document_plural: Documentos
-  label_download: "%{count} Descarga"
-  label_download_plural: "%{count} Descargas"
   label_downloads_abbr: D/L
   label_duplicated_by: duplicada por
   label_duplicates: duplicada de
@@ -508,8 +504,8 @@
   label_list: Lista
   label_loading: Cargando...
   label_logged_as: Conectado como
-  label_login: ConexiÃ³n
-  label_logout: DesconexiÃ³n
+  label_login: Iniciar sesiÃ³n
+  label_logout: Terminar sesiÃ³n
   label_max_size: TamaÃ±o mÃ¡ximo
   label_me: yo mismo
   label_member: Miembro
@@ -520,8 +516,6 @@
   label_message_plural: Mensajes
   label_message_posted: Mensaje aÃ±adido
   label_min_max_length: Longitud mÃ­n - mÃ¡x
-  label_modification: "%{count} modificaciÃ³n"
-  label_modification_plural: "%{count} modificaciones"
   label_modified: modificado
   label_module_plural: MÃ³dulos
   label_month: Mes
@@ -558,7 +552,7 @@
   label_permissions_report: Informe de permisos
   label_personalize_page: Personalizar esta pÃ¡gina
   label_planning: PlanificaciÃ³n
-  label_please_login: ConexiÃ³n
+  label_please_login: Por favor, inicie sesiÃ³n
   label_plugins: Extensiones
   label_precedes: anterior a
   label_preferences: Preferencias
@@ -622,7 +616,7 @@
   label_start_to_end: principio a fin
   label_start_to_start: principio a principio
   label_statistics: EstadÃ­sticas
-  label_stay_logged_in: Recordar conexiÃ³n
+  label_stay_logged_in: Mantener la sesiÃ³n abierta
   label_string: Texto
   label_subproject_plural: Proyectos secundarios
   label_text: Texto largo
@@ -720,7 +714,6 @@
   permission_log_time: Anotar tiempo dedicado
   permission_manage_boards: Administrar foros
   permission_manage_categories: Administrar categorÃ­as de peticiones
-  permission_manage_documents: Administrar documentos
   permission_manage_files: Administrar ficheros
   permission_manage_issue_relations: Administrar relaciÃ³n con otras peticiones
   permission_manage_members: Administrar miembros
@@ -757,7 +750,7 @@
   setting_app_title: TÃ­tulo de la aplicaciÃ³n
   setting_attachment_max_size: TamaÃ±o mÃ¡ximo del fichero
   setting_autofetch_changesets: Autorellenar los commits del repositorio
-  setting_autologin: ConexiÃ³n automÃ¡tica
+  setting_autologin: Inicio de sesiÃ³n automÃ¡tico
   setting_bcc_recipients: Ocultar las copias de carbÃ³n (bcc)
   setting_commit_fix_keywords: Palabras clave para la correcciÃ³n
   setting_commit_ref_keywords: Palabras clave para la referencia
@@ -1119,3 +1112,15 @@
   setting_non_working_week_days: DÃ­as no laborables
   label_in_the_next_days: en los prÃ³ximos
   label_in_the_past_days: en los anteriores
+  label_attribute_of_user: "%{name} del usuario"
+  text_turning_multiple_off: Si desactiva los valores mÃºltiples, Ã©stos serÃ¡n eliminados para dejar un Ãºnico valor por elemento.
+  label_attribute_of_issue: "%{name} de la peticiÃ³n"
+  permission_add_documents: AÃ±adir documentos
+  permission_edit_documents: Editar documentos
+  permission_delete_documents: Borrar documentos
+  label_gantt_progress_line: LÃ­nea de progreso
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
diff -r 0a574315af3e -r 4f746d8966dd config/locales/et.yml
--- a/config/locales/et.yml
+++ b/config/locales/et.yml
@@ -67,8 +67,8 @@
         one:   "umbes tund"
         other: "umbes %{count} tundi"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 tund"
+        other: "%{count} tundi"
       x_days:
         one:   "1 pÃ¤ev"
         other: "%{count} pÃ¤eva"
@@ -231,8 +231,6 @@
   mail_subject_wiki_content_updated: "Uuendati '%{id}' vikilehte"
   mail_body_wiki_content_updated: "'%{id}' vikilehte uuendati %{author} poolt."
 
-  gui_validation_error: "1 viga"
-  gui_validation_error_plural: "%{count} viga"
 
   field_name: "Nimi"
   field_description: "Kirjeldus"
@@ -438,7 +436,6 @@
   permission_edit_own_time_entries: "Omi ajakulu kandeid muuta"
   permission_manage_news: "Uudiseid hallata"
   permission_comment_news: "Uudiseid kommenteerida"
-  permission_manage_documents: "Dokumente hallata"
   permission_view_documents: "Dokumente nÃ¤ha"
   permission_manage_files: "Faile hallata"
   permission_view_files: "Faile nÃ¤ha"
@@ -569,8 +566,6 @@
   label_text: "Pikk tekst"
   label_attribute: "Atribuut"
   label_attribute_plural: "Atribuudid"
-  label_download: "%{count} allalaadimine"
-  label_download_plural: "%{count} allalaadimist"
   label_no_data: "Pole"
   label_change_status: "Muuda olekut"
   label_history: "Ajalugu"
@@ -681,8 +676,6 @@
   label_repository_new: "Uus hoidla"
   label_repository_plural: "Hoidlad"
   label_browse: "Sirvi"
-  label_modification: "%{count} muudatus"
-  label_modification_plural: "%{count} muudatust"
   label_branch: "Haru"
   label_tag: "Sildiga"
   label_revision: "Sissekanne"
@@ -1094,3 +1087,16 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: "Kokku"
diff -r 0a574315af3e -r 4f746d8966dd config/locales/eu.yml
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -53,8 +53,8 @@
         one:   "ordu 1 inguru"
         other: "%{count} ordu inguru"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "ordu 1"
+        other: "%{count} ordu"
       x_days:
         one:   "egun 1"
         other: "%{count} egun"
@@ -202,8 +202,6 @@
   mail_subject_wiki_content_updated: "'%{id}' wiki orria eguneratu da"
   mail_body_wiki_content_updated: "%{author}-(e)k '%{id}' wiki orria eguneratu du."
 
-  gui_validation_error: akats 1
-  gui_validation_error_plural: "%{count} akats"
 
   field_name: Izena
   field_description: Deskribapena
@@ -376,7 +374,6 @@
   permission_edit_own_time_entries: Nork bere denbora egunkariak editatu
   permission_manage_news: Berriak kudeatu
   permission_comment_news: Berrien iruzkinak egin
-  permission_manage_documents: Dokumentuak kudeatu
   permission_view_documents: Dokumentuak ikusi
   permission_manage_files: Fitxategiak kudeatu
   permission_view_files: Fitxategiak ikusi
@@ -497,8 +494,6 @@
   label_text: Testu luzea
   label_attribute: Atributua
   label_attribute_plural: Atributuak
-  label_download: "Deskarga %{count}"
-  label_download_plural: "%{count} Deskarga"
   label_no_data: Ez dago erakusteko daturik
   label_change_status: Egoera aldatu
   label_history: Historikoa
@@ -601,8 +596,6 @@
   label_repository: Biltegia
   label_repository_plural: Biltegiak
   label_browse: Arakatu
-  label_modification: "aldaketa %{count}"
-  label_modification_plural: "%{count} aldaketa"
   label_branch: Adarra
   label_tag: Etiketa
   label_revision: Berrikuspena
@@ -975,8 +968,6 @@
   text_scm_command: Komandoa
   text_scm_command_version: Bertsioa
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1083,3 +1074,18 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Guztira
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd config/locales/fa.yml
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -50,8 +50,8 @@
         one:   "Ù†Ø²Ø¯ÛŒÚ© 1 Ø³Ø§Ø¹Øª"
         other: "Ù†Ø²Ø¯ÛŒÚ© %{count} Ø³Ø§Ø¹Øª"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 Ø³Ø§Ø¹Øª"
+        other: "%{count} Ø³Ø§Ø¹Øª"
       x_days:
         one:   "1 Ø±ÙˆØ²"
         other: "%{count} Ø±ÙˆØ²"
@@ -208,8 +208,6 @@
   mail_subject_wiki_content_updated: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø¨Ø±ÙˆØ² Ø´Ø¯"
   mail_body_wiki_content_updated: "Ø¨Ø±Ú¯Ù‡ ÙˆÛŒÚ©ÛŒ Â«%{id}Â» Ø¨Ù‡ Ø¯Ø³Øª %{author} Ø¨Ø±ÙˆØ² Ø´Ø¯."
 
-  gui_validation_error: 1 Ø§ÛŒØ±Ø§Ø¯
-  gui_validation_error_plural: "%{count} Ø§ÛŒØ±Ø§Ø¯"
 
   field_name: Ù†Ø§Ù…
   field_description: ÛŒØ§Ø¯Ø¯Ø§Ø´Øª
@@ -396,7 +394,6 @@
   permission_edit_own_time_entries: ÙˆÛŒØ±Ø§ÛŒØ´ Ø²Ù…Ø§Ù† Ú¯Ø°Ø§Ø´ØªÙ‡ Ø´Ø¯Ù‡ Ø®ÙˆØ¯
   permission_manage_news: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
   permission_comment_news: Ú¯Ø°Ø§Ø´ØªÙ† Ø¯ÛŒØ¯Ú¯Ø§Ù‡ Ø±ÙˆÛŒ Ø±ÙˆÛŒØ¯Ø§Ø¯Ù‡Ø§
-  permission_manage_documents: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù†ÙˆØ´ØªØ§Ø±Ù‡Ø§
   permission_view_documents: Ø¯ÛŒØ¯Ù† Ù†ÙˆØ´ØªØ§Ø±Ù‡Ø§
   permission_manage_files: Ø³Ø±Ù¾Ø±Ø³ØªÛŒ Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§
   permission_view_files: Ø¯ÛŒØ¯Ù† Ù¾Ø±ÙˆÙ†Ø¯Ù‡â€ŒÙ‡Ø§
@@ -521,8 +518,6 @@
   label_text: Ù†ÙˆØ´ØªÙ‡ Ø¨Ù„Ù†Ø¯
   label_attribute: Ù†Ø´Ø§Ù†Ù‡
   label_attribute_plural: Ù†Ø´Ø§Ù†Ù‡
-  label_download: "%{count} Ø¨Ø§Ø± Ø¯Ø±ÛŒØ§ÙØª Ø´Ø¯Ù‡"
-  label_download_plural: "%{count} Ø¨Ø§Ø± Ø¯Ø±ÛŒØ§ÙØª Ø´Ø¯Ù‡"
   label_no_data: Ù‡ÛŒÚ† Ø¯Ø§Ø¯Ù‡â€ŒØ§ÛŒ Ø¨Ø±Ø§ÛŒ Ù†Ù…Ø§ÛŒØ´ Ù†ÛŒØ³Øª
   label_change_status: Ø¬Ø§ÛŒÚ¯Ø²ÛŒÙ†ÛŒ ÙˆØ¶Ø¹ÛŒØª
   label_history: Ù¾ÛŒØ´ÛŒÙ†Ù‡
@@ -625,8 +620,6 @@
   label_repository: Ø§Ù†Ø¨Ø§Ø±Ù‡
   label_repository_plural: Ø§Ù†Ø¨Ø§Ø±Ù‡
   label_browse: Ú†Ø±ÛŒØ¯Ù†
-  label_modification: "%{count} Ø¬Ø§ÛŒÚ¯Ø°Ø§Ø±ÛŒ"
-  label_modification_plural: "%{count} Ø¬Ø§ÛŒÚ¯Ø°Ø§Ø±ÛŒ"
   label_branch: Ø´Ø§Ø®Ù‡
   label_tag: Ø¨Ø±Ú†Ø³Ø¨
   label_revision: Ø¨Ø§Ø²Ø¨ÛŒÙ†ÛŒ
@@ -975,8 +968,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1083,3 +1074,18 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ø¬Ù…Ù„Ù‡
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd config/locales/fi.yml
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -95,8 +95,8 @@
         one:   "noin tunti"
         other: "noin %{count} tuntia"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 tunti"
+        other: "%{count} tuntia"
       x_days:
         one:   "pÃ¤ivÃ¤"
         other: "%{count} pÃ¤ivÃ¤Ã¤"
@@ -205,8 +205,6 @@
   mail_subject_account_activation_request: "%{value} tilin aktivointi pyyntÃ¶"
   mail_body_account_activation_request: "Uusi kÃ¤yttÃ¤jÃ¤ (%{value}) on rekisterÃ¶itynyt. HÃ¤nen tili odottaa hyvÃ¤ksyntÃ¤Ã¤si:"
 
-  gui_validation_error: 1 virhe
-  gui_validation_error_plural: "%{count} virhettÃ¤"
 
   field_name: Nimi
   field_description: Kuvaus
@@ -397,8 +395,6 @@
   label_text: PitkÃ¤ merkkijono
   label_attribute: MÃ¤Ã¤re
   label_attribute_plural: MÃ¤Ã¤reet
-  label_download: "%{count} Lataus"
-  label_download_plural: "%{count} Lataukset"
   label_no_data: Ei tietoa nÃ¤ytettÃ¤vÃ¤ksi
   label_change_status: Muutos tila
   label_history: Historia
@@ -487,8 +483,6 @@
   label_repository: Tietovarasto
   label_repository_plural: Tietovarastot
   label_browse: Selaus
-  label_modification: "%{count} muutos"
-  label_modification_plural: "%{count} muutettu"
   label_revision: Versio
   label_revision_plural: Versiot
   label_added: lisÃ¤tty
@@ -779,7 +773,6 @@
   permission_comment_news: Kommentoi uutisia
   permission_delete_messages: Poista viestit
   permission_select_project_modules: Valitse projektin modulit
-  permission_manage_documents: Hallinnoi dokumentteja
   permission_edit_wiki_pages: Muokkaa wiki sivuja
   permission_add_issue_watchers: LisÃ¤Ã¤ seuraajia
   permission_view_gantt: NÃ¤ytÃ¤ gantt kaavio
@@ -954,7 +947,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -995,8 +987,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1103,3 +1093,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: YhteensÃ¤
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/fr.yml
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -224,8 +224,6 @@
   mail_subject_wiki_content_updated: "Page wiki '%{id}' mise Ã  jour"
   mail_body_wiki_content_updated: "La page wiki '%{id}' a Ã©tÃ© mise Ã  jour par %{author}."
 
-  gui_validation_error: 1 erreur
-  gui_validation_error_plural: "%{count} erreurs"
 
   field_name: Nom
   field_description: Description
@@ -240,6 +238,7 @@
   field_author: Auteur
   field_created_on: "CrÃ©Ã© "
   field_updated_on: "Mis-Ã -jour "
+  field_closed_on: FermÃ©
   field_field_format: Format
   field_is_for_all: Pour tous les projets
   field_possible_values: Valeurs possibles
@@ -331,6 +330,7 @@
   field_timeout: "Timeout (en secondes)"
   field_board_parent: Forum parent
   field_private_notes: Notes privÃ©es
+  field_inherit_members: HÃ©riter les membres
 
   setting_app_title: Titre de l'application
   setting_app_subtitle: Sous-titre de l'application
@@ -396,6 +396,8 @@
   setting_thumbnails_enabled: Afficher les vignettes des images
   setting_thumbnails_size: Taille des vignettes (en pixels)
   setting_non_working_week_days: Jours non travaillÃ©s
+  setting_jsonp_enabled: Activer le support JSONP
+  setting_default_projects_tracker_ids: Trackers par dÃ©faut pour les nouveaux projets
 
   permission_add_project: CrÃ©er un projet
   permission_add_subprojects: CrÃ©er des sous-projets
@@ -431,8 +433,10 @@
   permission_edit_own_time_entries: Modifier son propre temps passÃ©
   permission_manage_news: GÃ©rer les annonces
   permission_comment_news: Commenter les annonces
-  permission_manage_documents: GÃ©rer les documents
   permission_view_documents: Voir les documents
+  permission_add_documents: Ajouter des documents
+  permission_edit_documents: Modifier les documents
+  permission_delete_documents: Supprimer les documents
   permission_manage_files: GÃ©rer les fichiers
   permission_view_files: Voir les fichiers
   permission_manage_wiki: GÃ©rer le wiki
@@ -562,8 +566,6 @@
   label_text: Texte long
   label_attribute: Attribut
   label_attribute_plural: Attributs
-  label_download: "%{count} tÃ©lÃ©chargement"
-  label_download_plural: "%{count} tÃ©lÃ©chargements"
   label_no_data: Aucune donnÃ©e Ã  afficher
   label_change_status: Changer le statut
   label_history: Historique
@@ -611,6 +613,7 @@
     one:   1 demande
     other: "%{count} demandes"
   label_total: Total
+  label_total_time: Temps total
   label_permissions: Permissions
   label_current_status: Statut actuel
   label_new_statuses_allowed: Nouveaux statuts autorisÃ©s
@@ -677,8 +680,6 @@
   label_repository_new: Nouveau dÃ©pÃ´t
   label_repository_plural: DÃ©pÃ´ts
   label_browse: Parcourir
-  label_modification: "%{count} modification"
-  label_modification_plural: "%{count} modifications"
   label_revision: "RÃ©vision "
   label_revision_plural: RÃ©visions
   label_associated_revisions: RÃ©visions associÃ©es
@@ -858,13 +859,16 @@
   label_readonly: Lecture
   label_required: Obligatoire
   label_attribute_of_project: "%{name} du projet"
+  label_attribute_of_issue: "%{name} de la demande"
   label_attribute_of_author: "%{name} de l'auteur"
   label_attribute_of_assigned_to: "%{name} de l'assignÃ©"
+  label_attribute_of_user: "%{name} de l'utilisateur"
   label_attribute_of_fixed_version: "%{name} de la version cible"
   label_cross_project_descendants: Avec les sous-projets
   label_cross_project_tree: Avec tout l'arbre
   label_cross_project_hierarchy: Avec toute la hiÃ©rarchie
   label_cross_project_system: Avec tous les projets
+  label_gantt_progress_line: Ligne de progression
 
   button_login: Connexion
   button_submit: Soumettre
@@ -940,7 +944,7 @@
   text_tip_issue_begin_day: tÃ¢che commenÃ§ant ce jour
   text_tip_issue_end_day: tÃ¢che finissant ce jour
   text_tip_issue_begin_end_day: tÃ¢che commenÃ§ant et finissant ce jour
-  text_project_identifier_info: 'Seuls les lettres minuscules (a-z), chiffres, tirets et underscore sont autorisÃ©s.<br />Un fois sauvegardÃ©, l''identifiant ne pourra plus Ãªtre modifiÃ©.'
+  text_project_identifier_info: 'Seuls les lettres minuscules (a-z), chiffres, tirets et underscore sont autorisÃ©s, doit commencer par une minuscule.<br />Un fois sauvegardÃ©, l''identifiant ne pourra plus Ãªtre modifiÃ©.'
   text_caracters_maximum: "%{count} caractÃ¨res maximum."
   text_caracters_minimum: "%{count} caractÃ¨res minimum."
   text_length_between: "Longueur comprise entre %{min} et %{max} caractÃ¨res."
@@ -990,6 +994,7 @@
   text_account_destroy_confirmation: "ÃŠtes-vous sÃ»r de vouloir continuer ?\nVotre compte sera dÃ©finitivement supprimÃ©, sans aucune possibilitÃ© de le rÃ©activer."
   text_session_expiration_settings: "Attention : le changement de ces paramÃ¨tres peut entrainer l'expiration des sessions utilisateurs en cours, y compris la vÃ´tre."
   text_project_closed: Ce projet est fermÃ© et accessible en lecture seule.
+  text_turning_multiple_off: "Si vous dÃ©sactivez les valeurs multiples, les valeurs multiples seront supprimÃ©es pour n'en conserver qu'une par objet."
 
   default_role_manager: "Manager "
   default_role_developer: "DÃ©veloppeur "
diff -r 0a574315af3e -r 4f746d8966dd config/locales/gl.yml
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -91,8 +91,8 @@
         one: 'aproximadamente unha hora'
         other: '%{count} horas'
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 hora"
+        other: "%{count} horas"
       x_days:
         one: '1 dÃ­a'
         other: '%{count} dÃ­as'
@@ -320,8 +320,6 @@
   general_text_Yes: 'Si'
   general_text_no: 'non'
   general_text_yes: 'si'
-  gui_validation_error: 1 erro
-  gui_validation_error_plural: "%{count} erros"
   label_activity: Actividade
   label_add_another_file: Engadir outro arquivo
   label_add_note: Engadir unha nota
@@ -414,8 +412,6 @@
   label_document_added: Documento engadido
   label_document_new: Novo documento
   label_document_plural: Documentos
-  label_download: "%{count} Descarga"
-  label_download_plural: "%{count} Descargas"
   label_downloads_abbr: D/L
   label_duplicated_by: duplicada por
   label_duplicates: duplicada de
@@ -495,8 +491,6 @@
   label_message_plural: Mensaxes
   label_message_posted: Mensaxe engadida
   label_min_max_length: Lonxitude mÃ­n - mÃ¡x
-  label_modification: "%{count} modificaciÃ³n"
-  label_modification_plural: "%{count} modificaciÃ³ns"
   label_modified: modificado
   label_module_plural: MÃ³dulos
   label_month: Mes
@@ -695,7 +689,6 @@
   permission_log_time: Anotar tempo dedicado
   permission_manage_boards: Administrar foros
   permission_manage_categories: Administrar categorÃ­as de peticiÃ³ns
-  permission_manage_documents: Administrar documentos
   permission_manage_files: Administrar arquivos
   permission_manage_issue_relations: Administrar relaciÃ³n con outras peticiÃ³ns
   permission_manage_members: Administrar membros
@@ -944,7 +937,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -985,8 +977,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1093,3 +1083,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/he.yml
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -56,8 +56,8 @@
         one: '×‘×¢×¨×š ×©×¢×” ××—×ª'
         other: '×‘×¢×¨×š %{count} ×©×¢×•×ª'
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 ×©×¢×”"
+        other: "%{count} ×©×¢×•×ª"
       x_days:
         one: '×™×•× ××—×“'
         other: '%{count} ×™×ž×™×'
@@ -212,8 +212,6 @@
   mail_subject_wiki_content_updated: "×“×£ ×”Ö¾wiki â€'%{id}' ×¢×•×“×›×Ÿ"
   mail_body_wiki_content_updated: ×“×£ ×”Ö¾wiki â€'%{id}' ×¢×•×“×›×Ÿ ×¢"×™ %{author}.
 
-  gui_validation_error: ×©×’×™××” 1
-  gui_validation_error_plural: "%{count} ×©×’×™××•×ª"
 
   field_name: ×©×
   field_description: ×ª×™××•×¨
@@ -393,7 +391,6 @@
   permission_edit_own_time_entries: ×¢×¨×™×›×ª ×¨×™×©×•× ×”×–×ž× ×™× ×©×œ ×¢×¦×ž×•
   permission_manage_news: × ×™×”×•×œ ×—×“×©×•×ª
   permission_comment_news: ×ª×’×•×‘×” ×œ×—×“×©×•×ª
-  permission_manage_documents: × ×™×”×•×œ ×ž×¡×ž×›×™×
   permission_view_documents: ×¦×¤×™×” ×‘×ž×¡×ž×›×™×
   permission_manage_files: × ×™×”×•×œ ×§×‘×¦×™×
   permission_view_files: ×¦×¤×™×” ×‘×§×‘×¦×™×
@@ -519,8 +516,6 @@
   label_text: ×˜×§×¡×˜ ××¨×•×š
   label_attribute: ×ª×›×•× ×”
   label_attribute_plural: ×ª×›×•× ×•×ª
-  label_download: "×”×•×¨×“×” %{count}"
-  label_download_plural: "%{count} ×”×•×¨×“×•×ª"
   label_no_data: ××™×Ÿ ×ž×™×“×¢ ×œ×”×¦×™×’
   label_change_status: ×©× ×” ×ž×¦×‘
   label_history: ×”×™×¡×˜×•×¨×™×”
@@ -623,8 +618,6 @@
   label_repository: ×ž××’×¨
   label_repository_plural: ×ž××’×¨×™×
   label_browse: ×¡×™×™×¨
-  label_modification: "×©×™× ×•×™ %{count}"
-  label_modification_plural: "%{count} ×©×™× ×•×™×™×"
   label_branch: ×¢× ×£
   label_tag: ×¡×™×ž×•×Ÿ
   label_revision: ×ž×”×“×•×¨×”
@@ -938,7 +931,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -979,8 +971,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1087,3 +1077,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: ×¡×”"×›
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/hr.yml
--- a/config/locales/hr.yml
+++ b/config/locales/hr.yml
@@ -49,8 +49,8 @@
         one:   "oko sat vremena"
         other: "oko %{count} sati"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 sata"
+        other: "%{count} sati"
       x_days:
         one:   "1 dan"
         other: "%{count} dana"
@@ -195,8 +195,6 @@
   mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
   mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
 
-  gui_validation_error: 1 pogreÅ¡ka
-  gui_validation_error_plural: "%{count} pogreÅ¡aka"
 
   field_name: Ime
   field_description: Opis
@@ -368,7 +366,6 @@
   permission_edit_own_time_entries: Edit own time logs
   permission_manage_news: Upravljaj novostima
   permission_comment_news: Komentiraj novosti
-  permission_manage_documents: Upravljaj dokumentima
   permission_view_documents: Pregledaj dokumente
   permission_manage_files: Upravljaj datotekama
   permission_view_files: Pregledaj datoteke
@@ -489,8 +486,6 @@
   label_text: Long text
   label_attribute: Atribut
   label_attribute_plural: Atributi
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
   label_no_data: Nema podataka za prikaz
   label_change_status: Promjena statusa
   label_history: Povijest
@@ -592,8 +587,6 @@
   label_repository: SkladiÅ¡te
   label_repository_plural: SkladiÅ¡ta
   label_browse: Pregled
-  label_modification: "%{count} promjena"
-  label_modification_plural: "%{count} promjena"
   label_branch: Branch
   label_tag: Tag
   label_revision: Revizija
@@ -934,7 +927,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -975,8 +967,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1083,3 +1073,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ukupno
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/hu.yml
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -51,8 +51,8 @@
         one: 'csaknem 1 Ã³rÃ¡ja'
         other: 'csaknem %{count} Ã³rÃ¡ja'
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 Ã³ra"
+        other: "%{count} Ã³ra"
       x_days:
         one: '1 napja'
         other: '%{count} napja'
@@ -203,8 +203,6 @@
   mail_subject_account_activation_request: Redmine azonosÃ­tÃ³ aktivÃ¡lÃ¡si kÃ©relem
   mail_body_account_activation_request: "Egy Ãºj felhasznÃ¡lÃ³ (%{value}) regisztrÃ¡lt, azonosÃ­tÃ³ja jÃ³vÃ¡hasgyÃ¡sra vÃ¡rakozik:"
 
-  gui_validation_error: 1 hiba
-  gui_validation_error_plural: "%{count} hiba"
 
   field_name: NÃ©v
   field_description: LeÃ­rÃ¡s
@@ -415,8 +413,6 @@
   label_text: HosszÃº szÃ¶veg
   label_attribute: TulajdonsÃ¡g
   label_attribute_plural: TulajdonsÃ¡gok
-  label_download: "%{count} LetÃ¶ltÃ©s"
-  label_download_plural: "%{count} LetÃ¶ltÃ©s"
   label_no_data: Nincs megjelenÃ­thetÅ‘ adat
   label_change_status: StÃ¡tusz mÃ³dosÃ­tÃ¡sa
   label_history: TÃ¶rtÃ©net
@@ -516,8 +512,6 @@
   label_repository: ForrÃ¡skÃ³d
   label_repository_plural: ForrÃ¡skÃ³dok
   label_browse: TallÃ³z
-  label_modification: "%{count} vÃ¡ltozÃ¡s"
-  label_modification_plural: "%{count} vÃ¡ltozÃ¡s"
   label_revision: RevÃ­ziÃ³
   label_revision_plural: RevÃ­ziÃ³k
   label_associated_revisions: Kapcsolt revÃ­ziÃ³k
@@ -777,7 +771,6 @@
   permission_comment_news: HÃ­rek kommentelÃ©se
   permission_delete_messages: Ãœzenetek tÃ¶rlÃ©se
   permission_select_project_modules: Projekt modulok kezelÃ©se
-  permission_manage_documents: Dokumentumok kezelÃ©se
   permission_edit_wiki_pages: Wiki oldalak szerkesztÃ©se
   permission_add_issue_watchers: MegfigyelÅ‘k felvÃ©tele
   permission_view_gantt: Gannt diagramm megtekintÃ©se
@@ -993,8 +986,6 @@
   text_scm_command: Parancs
   text_scm_command_version: VerziÃ³
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1101,3 +1092,18 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ã–sszesen
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd config/locales/id.yml
--- a/config/locales/id.yml
+++ b/config/locales/id.yml
@@ -47,8 +47,8 @@
         one:   "sekitar sejam"
         other: "sekitar %{count} jam"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 jam"
+        other: "%{count} jam"
       x_days:
         one:   "sehari"
         other: "%{count} hari"
@@ -195,8 +195,6 @@
   mail_subject_wiki_content_updated: "'%{id}' halaman wiki sudah diperbarui"
   mail_body_wiki_content_updated: "The '%{id}' halaman wiki sudah diperbarui oleh %{author}."
 
-  gui_validation_error: 1 kesalahan
-  gui_validation_error_plural: "%{count} kesalahan"
 
   field_name: Nama
   field_description: Deskripsi
@@ -361,7 +359,6 @@
   permission_edit_own_time_entries: Sunting catatan waktu saya
   permission_manage_news: Atur berita
   permission_comment_news: Komentari berita
-  permission_manage_documents: Atur dokumen
   permission_view_documents: Tampilkan dokumen
   permission_manage_files: Atur berkas
   permission_view_files: Tampilkan berkas
@@ -481,8 +478,6 @@
   label_text: Long text
   label_attribute: Atribut
   label_attribute_plural: Atribut
-  label_download: "%{count} Unduhan"
-  label_download_plural: "%{count} Unduhan"
   label_no_data: Tidak ada data untuk ditampilkan
   label_change_status: Status perubahan
   label_history: Riwayat
@@ -584,8 +579,6 @@
   label_repository: Repositori
   label_repository_plural: Repositori
   label_browse: Jelajah
-  label_modification: "%{count} perubahan"
-  label_modification_plural: "%{count} perubahan"
   label_branch: Cabang
   label_tag: Tag
   label_revision: Revisi
@@ -937,7 +930,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -978,8 +970,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1086,3 +1076,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/it.yml
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -55,8 +55,8 @@
         one:  "circa un'ora"
         other: "circa %{count} ore"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 ora"
+        other: "%{count} ore"
       x_days:
         one:  "1 giorno"
         other: "%{count} giorni"
@@ -176,8 +176,6 @@
   mail_subject_register: "Attivazione utente %{value}"
   mail_body_register: "Per attivare l'utente, usa il seguente collegamento:"
 
-  gui_validation_error: 1 errore
-  gui_validation_error_plural: "%{count} errori"
 
   field_name: Nome
   field_description: Descrizione
@@ -357,8 +355,6 @@
   label_text: Testo esteso
   label_attribute: Attributo
   label_attribute_plural: Attributi
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Download"
   label_no_data: Nessun dato disponibile
   label_change_status: Cambia stato
   label_history: Cronologia
@@ -446,8 +442,6 @@
   label_day_plural: giorni
   label_repository: Repository
   label_browse: Sfoglia
-  label_modification: "%{count} modifica"
-  label_modification_plural: "%{count} modifiche"
   label_revision: Versione
   label_revision_plural: Versioni
   label_added: aggiunto
@@ -589,8 +583,8 @@
   text_unallowed_characters: Caratteri non permessi
   text_comma_separated: Valori multipli permessi (separati da virgole).
   text_issues_ref_in_commit_messages: Segnalazioni di riferimento e chiusura nei messaggi di commit
-  text_issue_added: "E' stata segnalata l'anomalia %{id} da %{author}."
-  text_issue_updated: "L'anomalia %{id} Ã¨ stata aggiornata da %{author}."
+  text_issue_added: "%{author} ha aggiunto la segnalazione %{id}."
+  text_issue_updated: "La segnalazione %{id} Ã¨ stata aggiornata da %{author}."
   text_wiki_destroy_confirmation: Sicuro di voler eliminare questo wiki e tutti i suoi contenuti?
   text_issue_category_destroy_question: "Alcune segnalazioni (%{count}) risultano assegnate a questa categoria. Cosa vuoi fare ?"
   text_issue_category_destroy_assignments: Rimuovi le assegnazioni a questa categoria
@@ -759,7 +753,6 @@
   permission_comment_news: Commenta notizie
   permission_delete_messages: Elimina messaggi
   permission_select_project_modules: Seleziona moduli progetto
-  permission_manage_documents: Gestisci documenti
   permission_edit_wiki_pages: Modifica pagine wiki
   permission_add_issue_watchers: Aggiungi osservatori
   permission_view_gantt: Vedi diagrammi gantt
@@ -1009,77 +1002,87 @@
   button_export: Esporta
   label_export_options: "%{export_format} opzioni per l'export"
   error_attachment_too_big: Questo file non puÃ² essere caricato in quanto la sua dimensione supera la massima consentita (%{max_size})
-  notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
+  notice_failed_to_save_time_entries: "Non ho potuto salvare %{count} registrazioni di tempo impiegato su %{total} selezionate: %{ids}."
   label_x_issues:
     zero:  0 segnalazione
     one:   1 segnalazione
     other: "%{count} segnalazioni"
-  label_repository_new: New repository
-  field_repository_is_default: Main repository
-  label_copy_attachments: Copy attachments
+  label_repository_new: Nuovo repository
+  field_repository_is_default: Repository principale
+  label_copy_attachments: Copia allegati
   label_item_position: "%{position}/%{count}"
   label_completed_versions: Completed versions
-  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
-  field_multiple: Multiple values
+  text_project_identifier_info: Consentiti solo lettere minuscole (a-z), numeri, trattini e trattini bassi.<br />Una volta salvato, l'identificatore non puÃ² essere modificato.
+  field_multiple: Valori multipli
   setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
-  text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
-  text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
-  notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
-  text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
-  permission_manage_related_issues: Manage related issues
-  field_auth_source_ldap_filter: LDAP filter
-  label_search_for_watchers: Search for watchers to add
-  notice_account_deleted: Your account has been permanently deleted.
-  setting_unsubscribe: Allow users to delete their own account
-  button_delete_my_account: Delete my account
-  text_account_destroy_confirmation: |-
-    Are you sure you want to proceed?
-    Your account will be permanently deleted, with no way to reactivate it.
-  error_session_expired: Your session has expired. Please login again.
-  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
-  setting_session_lifetime: Session maximum lifetime
-  setting_session_timeout: Session inactivity timeout
-  label_session_expiration: Session expiration
-  permission_close_project: Close / reopen the project
-  label_show_closed_projects: View closed projects
-  button_close: Close
-  button_reopen: Reopen
-  project_status_active: active
-  project_status_closed: closed
-  project_status_archived: archived
-  text_project_closed: This project is closed and read-only.
-  notice_user_successful_create: User %{id} created.
-  field_core_fields: Standard fields
-  field_timeout: Timeout (in seconds)
-  setting_thumbnails_enabled: Display attachment thumbnails
-  setting_thumbnails_size: Thumbnails size (in pixels)
-  label_status_transitions: Status transitions
-  label_fields_permissions: Fields permissions
-  label_readonly: Read-only
-  label_required: Required
-  text_repository_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  text_issue_conflict_resolution_add_notes: Aggiunge le mie note e non salvare le mie ulteriori modifiche
+  text_issue_conflict_resolution_overwrite: Applica comunque le mie modifiche (le note precedenti verranno mantenute ma alcuni cambiamenti potrebbero essere sovrascritti)
+  notice_issue_update_conflict: La segnalazione Ã¨ stata aggiornata da un altro utente mentre la stavi editando.
+  text_issue_conflict_resolution_cancel: Cancella ogni modifica e rivisualizza %{link}
+  permission_manage_related_issues: Gestisci relative segnalazioni
+  field_auth_source_ldap_filter: Filtro LDAP
+  label_search_for_watchers: Cerca osservatori da aggiungere
+  notice_account_deleted: Il tuo account sarÃ  definitivamente rimosso.
+  setting_unsubscribe: Consentire agli utenti di cancellare il proprio account
+  button_delete_my_account: Cancella il mio account
+  text_account_destroy_confirmation: "Sei sicuro di voler procedere?\nIl tuo account sarÃ  definitivamente cancellato, senza alcuna possibilitÃ  di ripristino."
+  error_session_expired: "La tua sessione Ã¨ scaduta. Effettua nuovamente il login."
+  text_session_expiration_settings: "Attenzione: la modifica di queste impostazioni puÃ² far scadere le sessioni correnti, compresa la tua."
+  setting_session_lifetime: Massima durata di una sessione
+  setting_session_timeout: Timeout di inattivitÃ  di una sessione
+  label_session_expiration: Scadenza sessione
+  permission_close_project: Chiusura / riapertura progetto
+  label_show_closed_projects: Vedi progetti chiusi
+  button_close: Chiudi
+  button_reopen: Riapri
+  project_status_active: attivo
+  project_status_closed: chiuso
+  project_status_archived: archiviato
+  text_project_closed: Questo progetto Ã¨ chiuso e in sola lettura.
+  notice_user_successful_create: Creato utente %{id}.
+  field_core_fields: Campi standard
+  field_timeout: Timeout (in secondi)
+  setting_thumbnails_enabled: Mostra miniature degli allegati
+  setting_thumbnails_size: Dimensioni delle miniature (in pixels)
+  label_status_transitions: Transizioni di stato
+  label_fields_permissions: Permessi sui campi
+  label_readonly: Sola lettura
+  label_required: Richiesto
+  text_repository_identifier_info: Consentiti solo lettere minuscole (a-z), numeri, trattini e trattini bassi.<br />Una volta salvato, ll'identificatore non puÃ² essere modificato.
   field_board_parent: Parent forum
   label_attribute_of_project: Project's %{name}
   label_attribute_of_author: Author's %{name}
-  label_attribute_of_assigned_to: Assignee's %{name}
+  label_attribute_of_assigned_to: Assegnatari %{name}
   label_attribute_of_fixed_version: Target version's %{name}
-  label_copy_subtasks: Copy subtasks
-  label_copied_to: copied to
-  label_copied_from: copied from
-  label_any_issues_in_project: any issues in project
-  label_any_issues_not_in_project: any issues not in project
-  field_private_notes: Private notes
-  permission_view_private_notes: View private notes
-  permission_set_notes_private: Set notes as private
-  label_no_issues_in_project: no issues in project
+  label_copy_subtasks: Copia sottoattivitÃ 
+  label_copied_to: copia a
+  label_copied_from: copia da
+  label_any_issues_in_project: ogni segnalazione del progetto
+  label_any_issues_not_in_project: ogni segnalazione non nel progetto
+  field_private_notes: Note private
+  permission_view_private_notes: Visualizza note private
+  permission_set_notes_private: Imposta note come private
+  label_no_issues_in_project: progetto privo di segnalazioni
   label_any: tutti
-  label_last_n_weeks: last %{count} weeks
-  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_last_n_weeks: ultime %{count} settimane
+  setting_cross_project_subtasks: Consenti sottoattivitÃ  cross-project
   label_cross_project_descendants: Con sottoprogetti
   label_cross_project_tree: Con progetto padre
   label_cross_project_hierarchy: Con gerarchia progetto
   label_cross_project_system: Con tutti i progetti
-  button_hide: Hide
-  setting_non_working_week_days: Non-working days
-  label_in_the_next_days: in the next
-  label_in_the_past_days: in the past
+  button_hide: Nascondi
+  setting_non_working_week_days: Giorni non lavorativi
+  label_in_the_next_days: nei prossimi
+  label_in_the_past_days: nei passati
+  label_attribute_of_user: Utente %{name}
+  text_turning_multiple_off: Disabilitando valori multipli, i valori multipli verranno rimossi, in modo da mantenere un solo valore per item.
+  label_attribute_of_issue: Segnalazione %{name}
+  permission_add_documents: Aggiungi documenti
+  permission_edit_documents: Edita documenti
+  permission_delete_documents: Cancella documenti
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Abilita supporto a JSONP
+  field_inherit_members: Eredita membri
+  field_closed_on: Chiuso
+  setting_default_projects_tracker_ids: Trackers di default per nuovi progetti
+  label_total_time: Totale
diff -r 0a574315af3e -r 4f746d8966dd config/locales/ja.yml
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -176,7 +176,7 @@
   notice_account_invalid_creditentials: ãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚‚ã—ãã¯ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒç„¡åŠ¹ã§ã™
   notice_account_password_updated: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚
   notice_account_wrong_password: ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒé•ã„ã¾ã™
-  notice_account_register_done: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚
+  notice_account_register_done: ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚æœ‰åŠ¹ã«ã™ã‚‹ã«ã¯é€ä¿¡ã—ãŸãƒ¡ãƒ¼ãƒ«ã«ã‚ã‚‹ãƒªãƒ³ã‚¯ã‚’ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„ã€‚
   notice_account_unknown_email: ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒå­˜åœ¨ã—ã¾ã›ã‚“ã€‚
   notice_can_t_change_password: ã“ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã§ã¯å¤–éƒ¨èªè¨¼ã‚’ä½¿ã£ã¦ã„ã¾ã™ã€‚ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã¯å¤‰æ›´ã§ãã¾ã›ã‚“ã€‚
   notice_account_lost_email_sent: æ–°ã—ã„ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã—ãŸã€‚
@@ -238,8 +238,6 @@
   mail_subject_wiki_content_updated: "Wikiãƒšãƒ¼ã‚¸ %{id} ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ"
   mail_body_wiki_content_updated: "%{author} ã«ã‚ˆã£ã¦Wikiãƒšãƒ¼ã‚¸ %{id} ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
 
-  gui_validation_error: 1ä»¶ã®ã‚¨ãƒ©ãƒ¼
-  gui_validation_error_plural: "%{count}ä»¶ã®ã‚¨ãƒ©ãƒ¼"
 
   field_name: åç§°
   field_description: èª¬æ˜Ž
@@ -403,6 +401,7 @@
   setting_commit_logtime_enabled: ã‚³ãƒŸãƒƒãƒˆæ™‚ã«ä½œæ¥­æ™‚é–“ã‚’è¨˜éŒ²ã™ã‚‹
   setting_commit_logtime_activity_id: ä½œæ¥­æ™‚é–“ã®ä½œæ¥­åˆ†é¡ž
   setting_gantt_items_limit: ã‚¬ãƒ³ãƒˆãƒãƒ£ãƒ¼ãƒˆæœ€å¤§è¡¨ç¤ºé …ç›®æ•°
+  setting_default_projects_tracker_ids: æ–°è¦ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã«ãŠã„ã¦ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§æœ‰åŠ¹ã«ãªã‚‹ãƒˆãƒ©ãƒƒã‚«ãƒ¼
 
   permission_add_project: ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®è¿½åŠ 
   permission_add_subprojects: ã‚µãƒ–ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®è¿½åŠ 
@@ -434,7 +433,6 @@
   permission_manage_project_activities: ä½œæ¥­åˆ†é¡ž (æ™‚é–“ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°) ã®ç®¡ç†
   permission_manage_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã®ç®¡ç†
   permission_comment_news: ãƒ‹ãƒ¥ãƒ¼ã‚¹ã¸ã®ã‚³ãƒ¡ãƒ³ãƒˆ
-  permission_manage_documents: æ–‡æ›¸ã®ç®¡ç†
   permission_view_documents: æ–‡æ›¸ã®é–²è¦§
   permission_manage_files: ãƒ•ã‚¡ã‚¤ãƒ«ã®ç®¡ç†
   permission_view_files: ãƒ•ã‚¡ã‚¤ãƒ«ã®é–²è¦§
@@ -450,7 +448,7 @@
   permission_manage_repository: ãƒªãƒã‚¸ãƒˆãƒªã®ç®¡ç†
   permission_browse_repository: ãƒªãƒã‚¸ãƒˆãƒªã®é–²è¦§
   permission_view_changesets: æ›´æ–°å±¥æ­´ã®é–²è¦§
-  permission_commit_access: ã‚³ãƒŸãƒƒãƒˆã®é–²è¦§
+  permission_commit_access: ã‚³ãƒŸãƒƒãƒˆæ¨©é™
   permission_manage_boards: ãƒ•ã‚©ãƒ¼ãƒ©ãƒ ã®ç®¡ç†
   permission_view_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®é–²è¦§
   permission_add_messages: ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®è¿½åŠ 
@@ -561,8 +559,6 @@
   label_text: é•·ã„ãƒ†ã‚­ã‚¹ãƒˆ
   label_attribute: å±žæ€§
   label_attribute_plural: å±žæ€§
-  label_download: "%{count}ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
-  label_download_plural: "%{count}ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
   label_no_data: è¡¨ç¤ºã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãŒã‚ã‚Šã¾ã›ã‚“
   label_change_status: ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®å¤‰æ›´
   label_history: å±¥æ­´
@@ -667,8 +663,6 @@
   label_repository: ãƒªãƒã‚¸ãƒˆãƒª
   label_repository_plural: ãƒªãƒã‚¸ãƒˆãƒª
   label_browse: ãƒ–ãƒ©ã‚¦ã‚º
-  label_modification: "%{count}ç‚¹ã®å¤‰æ›´"
-  label_modification_plural: "%{count}ç‚¹ã®å¤‰æ›´"
   label_branch: ãƒ–ãƒ©ãƒ³ãƒ
   label_tag: ã‚¿ã‚°
   label_revision: ãƒªãƒ“ã‚¸ãƒ§ãƒ³
@@ -841,6 +835,7 @@
   label_git_report_last_commit: ãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®æœ€æ–°ã‚³ãƒŸãƒƒãƒˆã‚’è¡¨ç¤ºã™ã‚‹
   label_parent_revision: è¦ª
   label_child_revision: å­
+  label_gantt_progress_line: ã‚¤ãƒŠã‚ºãƒžç·š
 
   button_login: ãƒ­ã‚°ã‚¤ãƒ³
   button_submit: é€ä¿¡
@@ -863,7 +858,7 @@
   button_unlock: ã‚¢ãƒ³ãƒ­ãƒƒã‚¯
   button_download: ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰
   button_list: ä¸€è¦§
-  button_view: è¦‹ã‚‹
+  button_view: è¡¨ç¤º
   button_move: ç§»å‹•
   button_move_and_follow: ç§»å‹•å¾Œè¡¨ç¤º
   button_back: æˆ»ã‚‹
@@ -911,9 +906,9 @@
   text_journal_set_to: "%{label} ã‚’ %{value} ã«ã‚»ãƒƒãƒˆ"
   text_journal_deleted: "%{label} ã‚’å‰Šé™¤ (%{old})"
   text_journal_added: "%{label} %{value} ã‚’è¿½åŠ "
-  text_tip_issue_begin_day: ã“ã®æ—¥ã«é–‹å§‹ã™ã‚‹ã‚¿ã‚¹ã‚¯
-  text_tip_issue_end_day: ã“ã®æ—¥ã«çµ‚äº†ã™ã‚‹ã‚¿ã‚¹ã‚¯
-  text_tip_issue_begin_end_day: ã“ã®æ—¥ã®ã†ã¡ã«é–‹å§‹ã—ã¦çµ‚äº†ã™ã‚‹ã‚¿ã‚¹ã‚¯
+  text_tip_issue_begin_day: ã“ã®æ—¥ã«é–‹å§‹ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
+  text_tip_issue_end_day: ã“ã®æ—¥ã«çµ‚äº†ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
+  text_tip_issue_begin_end_day: ã“ã®æ—¥ã«é–‹å§‹ãƒ»çµ‚äº†ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
   text_caracters_maximum: "æœ€å¤§%{count}æ–‡å­—ã§ã™ã€‚"
   text_caracters_minimum: "æœ€ä½Ž%{count}æ–‡å­—ã®é•·ã•ãŒå¿…è¦ã§ã™"
   text_length_between: "é•·ã•ã¯%{min}ã‹ã‚‰%{max}æ–‡å­—ã¾ã§ã§ã™ã€‚"
@@ -1048,7 +1043,7 @@
   label_copy_attachments: æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ã‚³ãƒ”ãƒ¼
   label_item_position: "%{position}/%{count}"
   label_completed_versions: å®Œäº†ã—ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³
-  text_project_identifier_info: ã‚¢ãƒ«ãƒ•ã‚¡ãƒ™ãƒƒãƒˆå°æ–‡å­—(a-z)ãƒ»æ•°å­—ãƒ»ãƒã‚¤ãƒ•ãƒ³ãƒ»ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢ãŒä½¿ãˆã¾ã™ã€‚<br />è­˜åˆ¥å­ã¯å¾Œã§å¤‰æ›´ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã€‚
+  text_project_identifier_info: ã‚¢ãƒ«ãƒ•ã‚¡ãƒ™ãƒƒãƒˆå°æ–‡å­—(a-z)ãƒ»æ•°å­—ãƒ»ãƒã‚¤ãƒ•ãƒ³ãƒ»ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢ãŒä½¿ãˆã¾ã™ã€‚æœ€åˆã®æ–‡å­—ã¯ã‚¢ãƒ«ãƒ•ã‚¡ãƒ™ãƒƒãƒˆã®å°æ–‡å­—ã«ã—ã¦ãã ã•ã„ã€‚<br />è­˜åˆ¥å­ã¯å¾Œã§å¤‰æ›´ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã€‚
   field_multiple: è¤‡æ•°é¸æŠžå¯
   setting_commit_cross_project_ref: ç•°ãªã‚‹ãƒ—ãƒ­ã‚¸ã‚§ã‚¯ãƒˆã®ãƒã‚±ãƒƒãƒˆã®å‚ç…§/ä¿®æ­£ã‚’è¨±å¯
   text_issue_conflict_resolution_add_notes: è‡ªåˆ†ã®ç·¨é›†å†…å®¹ã‚’ç ´æ£„ã—æ³¨è¨˜ã®ã¿è¿½åŠ 
@@ -1112,3 +1107,13 @@
   setting_non_working_week_days: ä¼‘æ¥­æ—¥
   label_in_the_next_days: ä»Šå¾Œâ—‹æ—¥
   label_in_the_past_days: éŽåŽ»â—‹æ—¥
+  label_attribute_of_user: ãƒ¦ãƒ¼ã‚¶ãƒ¼ã® %{name}
+  text_turning_multiple_off: ã“ã®è¨­å®šã‚’ç„¡åŠ¹ã«ã™ã‚‹ã¨ã€è¤‡æ•°é¸æŠžã•ã‚Œã¦ã„ã‚‹å€¤ã®ã†ã¡1å€‹ã ã‘ãŒä¿æŒã•ã‚Œæ®‹ã‚Šã¯é¸æŠžè§£é™¤ã•ã‚Œã¾ã™ã€‚
+  label_attribute_of_issue: ãƒã‚±ãƒƒãƒˆã® %{name}
+  permission_add_documents: æ–‡æ›¸ã®è¿½åŠ 
+  permission_edit_documents: æ–‡æ›¸ã®ç·¨é›†
+  permission_delete_documents: æ–‡æ›¸ã®å‰Šé™¤
+  setting_jsonp_enabled: JSONPã‚’æœ‰åŠ¹ã«ã™ã‚‹
+  field_inherit_members: ãƒ¡ãƒ³ãƒãƒ¼ã‚’ç¶™æ‰¿
+  field_closed_on: çµ‚äº†æ—¥
+  label_total_time: åˆè¨ˆ
diff -r 0a574315af3e -r 4f746d8966dd config/locales/ko.yml
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -50,8 +50,8 @@
         one:   "ì•½ í•œì‹œê°„"
         other: "ì•½ %{count}ì‹œê°„"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 ì‹œê°„"
+        other: "%{count} ì‹œê°„"
       x_days:
         one:   "í•˜ë£¨"
         other: "%{count}ì¼"
@@ -231,15 +231,13 @@
   mail_body_account_information: ê³„ì • ì •ë³´
   mail_subject_account_activation_request: "%{value} ê³„ì • í™œì„±í™” ìš”ì²­"
   mail_body_account_activation_request: "ìƒˆ ì‚¬ìš©ìž(%{value})ê°€ ë“±ë¡ë˜ì—ˆìŠµë‹ˆë‹¤. ê´€ë¦¬ìžë‹˜ì˜ ìŠ¹ì¸ì„ ê¸°ë‹¤ë¦¬ê³  ìžˆìŠµë‹ˆë‹¤.:"
-  mail_body_reminder: "ë‹¹ì‹ ì´ ë§¡ê³  ìžˆëŠ” ì¼ê° %{count}ê°œì˜ ì™„ë£Œ ê¸°í•œì´ %{days}ì¼ í›„ ìž…ë‹ˆë‹¤."
+  mail_body_reminder: "ë‹¹ì‹ ì´ ë§¡ê³  ìžˆëŠ” ì¼ê° %{count}ê°œì˜ ì™„ë£Œê¸°í•œì´ %{days}ì¼ í›„ ìž…ë‹ˆë‹¤."
   mail_subject_reminder: "ë‚´ì¼ì´ ë§Œê¸°ì¸ ì¼ê° %{count}ê°œ (%{days})"
   mail_subject_wiki_content_added: "ìœ„í‚¤íŽ˜ì´ì§€ '%{id}'ì´(ê°€) ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
   mail_subject_wiki_content_updated: "'ìœ„í‚¤íŽ˜ì´ì§€ %{id}'ì´(ê°€) ìˆ˜ì •ë˜ì—ˆìŠµë‹ˆë‹¤."
   mail_body_wiki_content_added: "%{author}ì´(ê°€) ìœ„í‚¤íŽ˜ì´ì§€ '%{id}'ì„(ë¥¼) ì¶”ê°€í•˜ì˜€ìŠµë‹ˆë‹¤."
   mail_body_wiki_content_updated: "%{author}ì´(ê°€) ìœ„í‚¤íŽ˜ì´ì§€ '%{id}'ì„(ë¥¼) ìˆ˜ì •í•˜ì˜€ìŠµë‹ˆë‹¤."
 
-  gui_validation_error: ì—ëŸ¬
-  gui_validation_error_plural: "%{count}ê°œ ì—ëŸ¬"
 
   field_name: ì´ë¦„
   field_description: ì„¤ëª…
@@ -271,7 +269,7 @@
   field_is_default: ê¸°ë³¸ê°’
   field_tracker: ìœ í˜•
   field_subject: ì œëª©
-  field_due_date: ì™„ë£Œ ê¸°í•œ
+  field_due_date: ì™„ë£Œê¸°í•œ
   field_assigned_to: ë‹´ë‹¹ìž
   field_priority: ìš°ì„ ìˆœìœ„
   field_fixed_version: ëª©í‘œë²„ì „
@@ -326,7 +324,7 @@
   field_comments_sorting: ëŒ“ê¸€ ì •ë ¬
   field_parent_title: ìƒìœ„ ì œëª©
   field_editable: íŽ¸ì§‘ê°€ëŠ¥
-  field_watcher: ì¼ê°ì§€í‚´ì´
+  field_watcher: ì¼ê°ê´€ëžŒìž
   field_identity_url: OpenID URL
   field_content: ë‚´ìš©
   field_group_by: ê²°ê³¼ë¥¼ ë¬¶ì–´ ë³´ì—¬ì¤„ ê¸°ì¤€
@@ -392,15 +390,14 @@
   permission_save_queries: ê²€ìƒ‰ì–‘ì‹ ì €ìž¥
   permission_view_gantt: Ganttì°¨íŠ¸ ë³´ê¸°
   permission_view_calendar: ë‹¬ë ¥ ë³´ê¸°
-  permission_view_issue_watchers: ì¼ê°ì§€í‚´ì´ ë³´ê¸°
-  permission_add_issue_watchers: ì¼ê°ì§€í‚´ì´ ì¶”ê°€
+  permission_view_issue_watchers: ì¼ê°ê´€ëžŒìž ë³´ê¸°
+  permission_add_issue_watchers: ì¼ê°ê´€ëžŒìž ì¶”ê°€
   permission_log_time: ìž‘ì—…ì‹œê°„ ê¸°ë¡
   permission_view_time_entries: ì‹œê°„ìž…ë ¥ ë³´ê¸°
   permission_edit_time_entries: ì‹œê°„ìž…ë ¥ íŽ¸ì§‘
   permission_edit_own_time_entries: ë‚´ ì‹œê°„ìž…ë ¥ íŽ¸ì§‘
   permission_manage_news: ë‰´ìŠ¤ ê´€ë¦¬
   permission_comment_news: ë‰´ìŠ¤ì— ëŒ“ê¸€ë‹¬ê¸°
-  permission_manage_documents: ë¬¸ì„œ ê´€ë¦¬
   permission_view_documents: ë¬¸ì„œ ë³´ê¸°
   permission_manage_files: íŒŒì¼ê´€ë¦¬
   permission_view_files: íŒŒì¼ë³´ê¸°
@@ -460,9 +457,9 @@
   label_role_plural: ì—­í• 
   label_role_new: ìƒˆ ì—­í• 
   label_role_and_permissions: ì—­í•  ë° ê¶Œí•œ
-  label_member: ë‹´ë‹¹ìž
-  label_member_new: ìƒˆ ë‹´ë‹¹ìž
-  label_member_plural: ë‹´ë‹¹ìž
+  label_member: êµ¬ì„±ì›
+  label_member_new: ìƒˆ êµ¬ì„±ì›
+  label_member_plural: êµ¬ì„±ì›
   label_tracker: ì¼ê° ìœ í˜•
   label_tracker_plural: ì¼ê° ìœ í˜•
   label_tracker_new: ìƒˆ ì¼ê° ìœ í˜•
@@ -519,8 +516,6 @@
   label_text: í…ìŠ¤íŠ¸
   label_attribute: ì†ì„±
   label_attribute_plural: ì†ì„±
-  label_download: "%{count}íšŒ ë‹¤ìš´ë¡œë“œ"
-  label_download_plural: "%{count}íšŒ ë‹¤ìš´ë¡œë“œ"
   label_no_data: í‘œì‹œí•  ë°ì´í„°ê°€ ì—†ìŠµë‹ˆë‹¤.
   label_change_status: ìƒíƒœ ë³€ê²½
   label_history: ì´ë ¥
@@ -622,8 +617,6 @@
   label_repository: ì €ìž¥ì†Œ
   label_repository_plural: ì €ìž¥ì†Œ
   label_browse: ì €ìž¥ì†Œ ë‘˜ëŸ¬ë³´ê¸°
-  label_modification: "%{count} ë³€ê²½"
-  label_modification_plural: "%{count} ë³€ê²½"
   label_revision: ê°œì •íŒ
   label_revision_plural: ê°œì •íŒ
   label_associated_revisions: ê´€ë ¨ëœ ê°œì •íŒë“¤
@@ -668,8 +661,8 @@
   label_commits_per_month: ì›”ë³„ ì»¤ë°‹ ë‚´ì—­
   label_commits_per_author: ì €ìžë³„ ì»¤ë°‹ ë‚´ì—­
   label_view_diff: ì°¨ì´ì  ë³´ê¸°
-  label_diff_inline: í•œì¤„ë¡œ
-  label_diff_side_by_side: ë‘ì¤„ë¡œ
+  label_diff_inline: ë‘ì¤„ë¡œ
+  label_diff_side_by_side: í•œì¤„ë¡œ
   label_options: ì˜µì…˜
   label_copy_workflow_from: ì—…ë¬´íë¦„ ë³µì‚¬í•˜ê¸°
   label_permissions_report: ê¶Œí•œ ë³´ê³ ì„œ
@@ -749,7 +742,7 @@
   label_planning: í”„ë¡œì íŠ¸ê³„íš
   label_incoming_emails: ìˆ˜ì‹  ë©”ì¼
   label_generate_key: í‚¤ ìƒì„±
-  label_issue_watchers: ì¼ê°ì§€í‚´ì´
+  label_issue_watchers: ì¼ê°ê´€ëžŒìž
   label_example: ì˜ˆ
   label_display: í‘œì‹œë°©ì‹
   label_sort: ì •ë ¬
@@ -795,7 +788,7 @@
   button_change_password: ë¹„ë°€ë²ˆí˜¸ ë°”ê¾¸ê¸°
   button_copy: ë³µì‚¬
   button_annotate: ì´ë ¥í•´ì„¤
-  button_update: ìˆ˜ì •
+  button_update: ì—…ë°ì´íŠ¸
   button_configure: ì„¤ì •
   button_quote: ëŒ“ê¸€ë‹¬ê¸°
 
@@ -894,7 +887,7 @@
   text_journal_added: "%{label}ì— %{value}ì´(ê°€) ì¶”ê°€ë˜ì—ˆìŠµë‹ˆë‹¤."
   field_active: ì‚¬ìš©ì¤‘
   enumeration_system_activity: ì‹œìŠ¤í…œ ìž‘ì—…
-  permission_delete_issue_watchers: ì¼ê°ì§€í‚´ì´ ì§€ìš°ê¸°
+  permission_delete_issue_watchers: ì¼ê°ê´€ëžŒìž ì§€ìš°ê¸°
   version_status_closed: ë‹«íž˜
   version_status_locked: ìž ê¹€
   version_status_open: ì§„í–‰
@@ -1010,7 +1003,7 @@
   permission_set_own_issues_private: "ìžì‹ ì˜ ì¼ê°ì„ ê³µê°œë‚˜ ë¹„ê³µê°œë¡œ ì„¤ì •"
   field_is_private: "ë¹„ê³µê°œ"
   permission_set_issues_private: "ì¼ê°ì„ ê³µê°œë‚˜ ë¹„ê³µê°œë¡œ ì„¤ì •"
-  label_issues_visibility_public: "ëª¨ë“  ë¹„ê³µê°œ ì¼ê°"
+  label_issues_visibility_public: "ë¹„ê³µê°œ ì¼ê° ì œì™¸"
   text_issues_destroy_descendants_confirmation: "%{count} ê°œì˜ í•˜ìœ„ ì¼ê°ì„ ì‚­ì œí•  ê²ƒìž…ë‹ˆë‹¤."
   field_commit_logs_encoding: "ì»¤ë°‹(commit) ê¸°ë¡ ì¸ì½”ë”©"
   field_scm_path_encoding: "ê²½ë¡œ ì¸ì½”ë”©"
@@ -1077,7 +1070,7 @@
   text_issue_conflict_resolution_cancel: "ë³€ê²½ë‚´ìš©ì„ ë˜ëŒë¦¬ê³  ë‹¤ì‹œ í‘œì‹œ %{link}"
   permission_manage_related_issues: ì—°ê²°ëœ ì¼ê° ê´€ë¦¬
   field_auth_source_ldap_filter: LDAP í•„í„°
-  label_search_for_watchers: ì¶”ê°€í•  ì¼ê°ì§€í‚´ì´ ê²€ìƒ‰
+  label_search_for_watchers: ì¶”ê°€í•  ì¼ê°ê´€ëžŒìž ê²€ìƒ‰
   notice_account_deleted: ë‹¹ì‹ ì˜ ê³„ì •ì´ ì™„ì „ížˆ ì‚­ì œë˜ì—ˆìŠµë‹ˆë‹¤.
   setting_unsubscribe: ì‚¬ìš©ìžë“¤ì´ ìžì‹ ì˜ ê³„ì •ì„ ì‚­ì œí† ë¡ í—ˆìš©
   button_delete_my_account: ë‚˜ì˜ ê³„ì • ì‚­ì œ
@@ -1120,7 +1113,7 @@
   field_private_notes: ë¹„ê³µê°œ ë§ê¸€
   permission_view_private_notes: ë¹„ê³µê°œ ë§ê¸€ ë³´ê¸°
   permission_set_notes_private: ë§ê¸€ì„ ë¹„ê³µê°œë¡œ ì„¤ì •
-  label_no_issues_in_project: ë‹¤ìŒ í”„ë¡œì íŠ¸ ë‚´ì—ì„œ í•´ë‹¹ ì¼ê° ì—†ìŒ
+  label_no_issues_in_project: ë‹¤ìŒ í”„ë¡œì íŠ¸ì˜ ì¼ê° ì œì™¸
   label_any: ëª¨ë‘
   label_last_n_weeks: ìµœê·¼ %{count} ì£¼
   setting_cross_project_subtasks: ë‹¤ë¥¸ í”„ë¡œì íŠ¸ì˜ ì¼ê°ì„ ìƒìœ„ ì¼ê°ìœ¼ë¡œ ì§€ì •í•˜ëŠ” ê²ƒì„ í—ˆìš©
@@ -1132,3 +1125,15 @@
   setting_non_working_week_days: ë¹„ê·¼ë¬´ì¼ (non-working days)
   label_in_the_next_days: ë‹¤ìŒ
   label_in_the_past_days: ì§€ë‚œ
+  label_attribute_of_user: "ì‚¬ìš©ìžì˜ %{name}"
+  text_turning_multiple_off: ë³µìˆ˜ì„ íƒì„ ë¹„í™œì„±í™”í•˜ë©´, í•˜ë‚˜ì˜ ê°’ì„ ì œì™¸í•œ ë‚˜ë¨¸ì§€ ê°’ë“¤ì´ ì§€ì›Œì§‘ë‹ˆë‹¤.
+  label_attribute_of_issue: "ì¼ê°ì˜ %{name}"
+  permission_add_documents: ë¬¸ì„œ ì¶”ê°€
+  permission_edit_documents: ë¬¸ì„œ íŽ¸ì§‘
+  permission_delete_documents: ë¬¸ì„œ ì‚­ì œ
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: JSONP í—ˆìš©
+  field_inherit_members: ìƒìœ„ í”„ë¡œì íŠ¸ë¡œë¶€í„° êµ¬ì„±ì›ì„ ìƒì†
+  field_closed_on: ì™„ë£Œì¼
+  setting_default_projects_tracker_ids: ìƒˆ í”„ë¡œì íŠ¸ì— ê¸°ë³¸ì ìœ¼ë¡œ ì¶”ê°€í•  ì¼ê° ìœ í˜•
+  label_total_time: í•©ê³„
diff -r 0a574315af3e -r 4f746d8966dd config/locales/lt.yml
--- a/config/locales/lt.yml
+++ b/config/locales/lt.yml
@@ -1,8 +1,10 @@
 # Lithuanian translations for Ruby on Rails
 # by Laurynas Butkus (laurynas.butkus@gmail.com)
 # Redmine translation by Gediminas MuiÅ¾is gediminas.muizis@gmail.com
-#                      and Sergej Jegorov sergej.jegorov@gmail.com
-#					   and Gytis Gurklys gytis.gurklys@gmail.com
+# and Sergej Jegorov sergej.jegorov@gmail.com
+# and Gytis Gurklys gytis.gurklys@gmail.com
+# and Andrius KriuÄkovas andrius.kriuckovas@gmail.com
+
 lt:
   direction: ltr
   date:
@@ -228,8 +230,8 @@
   notice_default_data_loaded: Numatytoji konfiguracija sÄ—kmingai uÅ¾krauta.
   notice_unable_delete_version: NeÄ¯manoma panaikinti versijÄ….
   notice_unable_delete_time_entry: NeÄ¯mano iÅ¡trinti laiko Å¾urnalo Ä¯raÅ¡Ä….
-  notice_issue_done_ratios_updated: Issue done ratios updated.
-  notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
+  notice_issue_done_ratios_updated: Problemos baigtumo rodikliai atnaujinti.
+  notice_gantt_chart_truncated: Grafikas buvo sutrumpintas, kadangi jis virÅ¡ija maksimalÅ³ (%{max}) leistinÅ³ atvaizduoti elementÅ³ kiekÄ¯
   notice_issue_successful_create: Darbas %{id} sukurtas.
 
   error_can_t_load_default_data: "Numatytoji konfiguracija negali bÅ«ti uÅ¾krauta: %{value}"
@@ -241,16 +243,16 @@
   error_no_tracker_in_project: 'Joks pÄ—dsekys nesusietas su Å¡iuo projektu. PraÅ¡om patikrinti Projekto nustatymus.'
   error_no_default_issue_status: Nenustatyta numatytoji darbÅ³ bÅ«sena. PraÅ¡ome patikrinti konfigÅ«ravimÄ… ("Administravimas -> DarbÅ³ bÅ«senos").
   error_can_not_delete_custom_field: Negalima iÅ¡trinti kliento lauko
-  error_can_not_delete_tracker: "This tracker contains issues and cannot be deleted."
-  error_can_not_remove_role: "This role is in use and cannot be deleted."
+  error_can_not_delete_tracker: "Å is pÄ—dsekys turi Ä¯raÅ¡us ir todÄ—l negali bÅ«ti iÅ¡trintas."
+  error_can_not_remove_role: "Å i rolÄ— yra naudojama ir negali bÅ«ti iÅ¡trinta."
   error_can_not_reopen_issue_on_closed_version: UÅ¾darytai versijai priskirtas darbas negali bÅ«ti atnaujintas.
   error_can_not_archive_project: Å io projekto negalima suarchyvuoti
-  error_issue_done_ratios_not_updated: "Issue done ratios not updated."
-  error_workflow_copy_source: 'Please select a source tracker or role'
-  error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
+  error_issue_done_ratios_not_updated: "Ä®raÅ¡o baigtumo rodikliai nebuvo atnaujinti. "
+  error_workflow_copy_source: 'PraÅ¡ome pasirinkti pirminÄ¯ Å¡altinio seklÄ¯ arba rolÄ™'
+  error_workflow_copy_target: 'PraÅ¡ome pasirinkti galutinÄ¯ paskirties seklÄ¯(-ius) arba rolÄ™(-s)'
   error_unable_delete_issue_status: 'Negalima iÅ¡trinti darbo statuso'
   error_unable_to_connect: Negalima prisijungti (%{value})
-  error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})"
+  error_attachment_too_big: "Å i byla negali bÅ«ti Ä¯kelta, nes virÅ¡ija maksimaliÄ… (%{max_size}) leistinÄ… bylos apimtÄ¯"
   warning_attachments_not_saved: "%{count} byla(Å³) negali bÅ«ti iÅ¡saugota."
 
   mail_subject_lost_password: "JÅ«sÅ³ %{value} slaptaÅ¾odis"
@@ -268,8 +270,6 @@
   mail_subject_wiki_content_updated: "'%{id}' atnaujintas wiki puslapis"
   mail_body_wiki_content_updated: "'%{id}' wiki puslapÄ¯ atnaujino %{author}."
 
-  gui_validation_error: 1 klaida
-  gui_validation_error_plural: "%{count} klaidÅ³(os)"
 
   field_name: Pavadinimas
   field_description: ApraÅ¡as
@@ -433,7 +433,7 @@
   setting_cache_formatted_text: PaslÄ—pti formatuotÄ… tekstÄ…
   setting_default_notification_option: Numatytosios praneÅ¡imÅ³ nuostatos
   setting_commit_logtime_enabled: Ä®jungti laiko registravimÄ…
-  setting_commit_logtime_activity_id: Activity for logged time
+  setting_commit_logtime_activity_id: Laiko Ä¯raÅ¡Å³ veikla
   setting_gantt_items_limit: Maksimalus rodmenÅ³ skaiÄius rodomas Gantt'o grafike
   setting_issue_group_assignment: Leisti darbo priskirimÄ… grupÄ—ms
   setting_default_issue_start_date_to_creation_date: Naudoti dabartinÄ™ datÄ… kaip naujÅ³ darbÅ³ pradÅ¾ios datÄ…
@@ -470,7 +470,6 @@
   permission_edit_own_time_entries: Redguoti savo laiko Ä¯raÅ¡us
   permission_manage_news: Valdyti naujienas
   permission_comment_news: Komentuoti naujienas
-  permission_manage_documents: Valdyti dokumentus
   permission_view_documents: Matyti dokumentus
   permission_manage_files: Valdyti failus
   permission_view_files: Matyti failus
@@ -601,8 +600,6 @@
   label_text: Ilgas tekstas
   label_attribute: PoÅ¾ymis
   label_attribute_plural: PoÅ¾ymiai
-  label_download: "%{count} persiuntimas"
-  label_download_plural: "%{count} persiuntimai"
   label_no_data: NÄ—ra kÄ… atvaizduoti
   label_change_status: Pakeitimo bÅ«sena
   label_history: Istorija
@@ -708,8 +705,6 @@
   label_repository: Saugykla
   label_repository_plural: Saugyklos
   label_browse: NarÅ¡yti
-  label_modification: "%{count} pakeitimas"
-  label_modification_plural: "%{count} pakeitimai"
   label_branch: Å aka
   label_tag: Tag
   label_revision: Revizija
@@ -885,8 +880,8 @@
   label_issues_visibility_public: Visi vieÅ¡i darbai
   label_issues_visibility_own: Darbai, sukurti vartotojo arba jam priskirti
   label_git_report_last_commit: Nurodyti paskutinÄ¯ failÅ³ ir katalogÅ³ pakeitimÄ…
-  label_parent_revision: Parent
-  label_child_revision: Child
+  label_parent_revision: PirminÄ— revizija
+  label_child_revision: Sekanti revizija
   label_export_options: "%{export_format} eksportavimo nustatymai"
 
   button_login: Registruotis
@@ -999,25 +994,22 @@
   text_enumeration_destroy_question: "%{count} objektai(Å³) priskirti Å¡iai reikÅ¡mei."
   text_enumeration_category_reassign_to: 'Priskirti juos Å¡iai reikÅ¡mei:'
   text_email_delivery_not_configured: "El.paÅ¡to siuntimas nesukonfigÅ«ruotas, ir perspÄ—jimai neaktyvus.\nSukonfigÅ«ruokite savo SMTP serverÄ¯ byloje config/configuration.yml ir perleiskite programÄ… norÄ—dami pritaikyti pakeitimus."
-  text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
   text_repository_usernames_mapping: "Parinkite ar atnaujinkite Redmine vartotojÄ…, kuris paminÄ—tas saugyklos log'e.\nVartotojai, turintys tÄ… patÄ¯ Redmine ir saugyklos vardÄ… ar el.paÅ¡tÄ… yra automatiÅ¡kai suriÅ¡ti."
   text_diff_truncated: "... Å is diff'as nukarpytas, nes jis virÅ¡ijo maksimalÅ³ rodomÅ³ eiluÄiÅ³ skaiÄiÅ³."
   text_custom_field_possible_values_info: 'Po vienÄ… eilutÄ™ kiekvienai reikÅ¡mei'
-  text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
+  text_wiki_page_destroy_question: "Å is puslapis turi %{descendants} susijusiÅ³ arba iÅ¡vestiniÅ³ puslapiÅ³. KÄ… norÄ—tumÄ—te daryti?"
   text_wiki_page_nullify_children: Laikyti child puslapius kaip pagrindinius puslapius
   text_wiki_page_destroy_children: "PaÅ¡alinti child puslapius ir jÅ³ palikuonis"
   text_wiki_page_reassign_children: "Priskirkite iÅ¡ naujo 'child' puslapius Å¡iam pagrindiniam puslapiui"
-  text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
+  text_own_membership_delete_confirmation: "JÅ«s esate pasiruoÅ¡Ä™s panaikinti dalÄ¯ arba visus leidimus ir po Å¡io pakeitimo galite prarasti Å¡io projekto redagavimo galimybÄ™. \n Ar jÅ«s esate Ä¯sitikinÄ™s ir tÄ™sti?"
   text_zoom_in: Priartinti
   text_zoom_out: Nutolinti
   text_warn_on_leaving_unsaved: "Dabartinis puslapis turi neiÅ¡saugoto teksto, kuris bus prarastas, jeigu paliksite Å¡Ä¯ puslapÄ¯."
   text_scm_path_encoding_note: "Numatytasis: UTF-8"
-  text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
+  text_git_repository_note: Saugykla (repository) yra plika ir vietinÄ— (pvz. /gitrepo, c:\gitrepo)
   text_mercurial_repository_note: VietinÄ— saugykla (e.g. /hgrepo, c:\hgrepo)
   text_scm_command: Komanda
   text_scm_command_version: Versija
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
 
   default_role_manager: Vadovas
   default_role_developer: Projektuotojas
@@ -1079,7 +1071,7 @@
   label_completed_versions: UÅ¾baigtos versijos
   text_project_identifier_info: LeidÅ¾iamos tik maÅ¾osios raidÄ—s (a-z), skaitmenys, brÅ«kÅ¡neliai ir pabraukimo simboliai.<br />KartÄ… iÅ¡saugojus pakeitimai negalimi
   field_multiple: Keletas reikÅ¡miÅ³
-  setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
+  setting_commit_cross_project_ref: Leisti visÅ³ kitÅ³ projektÅ³ Ä¯raÅ¡us susieti nuorodomis ir sutaisyti
   text_issue_conflict_resolution_add_notes: IÅ¡saugoti mano Å¾inutÄ™ ir atmesti likusius mano pataisymus
   text_issue_conflict_resolution_overwrite: IÅ¡saugoti mano pakeitimus (ankstesniÅ³ pakeitimÅ³ Å¾inutÄ—s bus iÅ¡saugotos, taÄiau kai kurie pakeitimai bus perraÅ¡yti)
   notice_issue_update_conflict: Darbas buvo pakoreguotas kito vartotojo kol jÅ«s atlikote pakeitimus.
@@ -1141,3 +1133,17 @@
   setting_non_working_week_days: Nedarbo dienos
   label_in_the_next_days: per ateinanÄias
   label_in_the_past_days: per paskutines
+  label_attribute_of_user: Vartotojo %{name}
+  text_turning_multiple_off: Jei jÅ«s iÅ¡jungsite keliÅ³ reikÅ¡miÅ³ pasirinkimÄ…, visos iÅ¡vardintos reikÅ¡mÄ—s bus paÅ¡alintos ir palikta tik viena reikÅ¡mÄ— kiekvienam laukui.
+  label_attribute_of_issue: Ä®raÅ¡ai %{name}
+  permission_add_documents: PridÄ—ti dokumentus
+  permission_edit_documents: Redaguoti dokumentus
+  permission_delete_documents: Trinti dokumentus
+  label_gantt_progress_line: Progreso linija
+  setting_jsonp_enabled: Ä®galinti JSONP palaikymÄ…
+  field_inherit_members: PaveldÄ—ti narius
+  field_closed_on: UÅ¾darytas
+  setting_default_projects_tracker_ids: Sekliai pagal nutylÄ—jimÄ… naujiems projektams
+  label_total_time: IÅ¡ viso
+  text_scm_config: JÅ«s galite pakeisti SCM komandas byloje config/configuration.yml. PraÅ¡ome perkrauti programÄ… po redagavimo, idant Ä¯galinti pakeitimus.
+  text_scm_command_not_available: SCM komanda nepasiekiama. Patikrinkite administravimo skydelio nustatymus.
diff -r 0a574315af3e -r 4f746d8966dd config/locales/lv.yml
--- a/config/locales/lv.yml
+++ b/config/locales/lv.yml
@@ -46,8 +46,8 @@
         one:   "aptuveni 1 stunda"
         other: "aptuveni %{count} stundas"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 stunda"
+        other: "%{count} stundas"
       x_days:
         one:   "1 diena"
         other: "%{count} dienas"
@@ -194,8 +194,6 @@
   mail_subject_wiki_content_updated: "'%{id}' Wiki lapa atjaunota"
   mail_body_wiki_content_updated: "The '%{id}' Wiki lapu atjaunojis %{author}."
 
-  gui_validation_error: 1 kÄ¼Å«da
-  gui_validation_error_plural: "%{count} kÄ¼Å«das"
 
   field_name: Nosaukums
   field_description: Apraksts
@@ -370,7 +368,6 @@
   permission_edit_own_time_entries:  RediÄ£Ä“t savus laika reÄ£istrus
   permission_manage_news: PÄrvaldÄ«t jaunumus
   permission_comment_news: KomentÄ“t jaunumus
-  permission_manage_documents: PÄrvaldÄ«t dokumentus
   permission_view_documents: SkatÄ«t dokumentus
   permission_manage_files: PÄrvaldÄ«t failus
   permission_view_files: SkatÄ«t failus
@@ -492,8 +489,6 @@
   label_text: GarÅ¡ teksts
   label_attribute: AtribÅ«ts
   label_attribute_plural: AtribÅ«ti
-  label_download: "%{count} LejupielÄde"
-  label_download_plural: "%{count} LejupielÄdes"
   label_no_data: Nav datu, ko parÄdÄ«t
   label_change_status: MainÄ«t statusu
   label_history: VÄ“sture
@@ -596,8 +591,6 @@
   label_repository: Repozitorijs
   label_repository_plural: Repozitoriji
   label_browse: PÄrlÅ«kot
-  label_modification: "%{count} izmaiÅ†a"
-  label_modification_plural: "%{count} izmaiÅ†as"
   label_branch: Zars
   label_tag: Birka
   label_revision: RevÄ«zija
@@ -927,7 +920,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -968,8 +960,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1076,3 +1066,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: KopÄ
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/mk.yml
--- a/config/locales/mk.yml
+++ b/config/locales/mk.yml
@@ -50,8 +50,8 @@
         one:   "Ð¾ÐºÐ¾Ð»Ñƒ 1 Ñ‡Ð°Ñ"
         other: "Ð¾ÐºÐ¾Ð»Ñƒ %{count} Ñ‡Ð°ÑÐ°"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 Ñ‡Ð°Ñ"
+        other: "%{count} Ñ‡Ð°ÑÐ°"
       x_days:
         one:   "1 Ð´ÐµÐ½"
         other: "%{count} Ð´ÐµÐ½Ð°"
@@ -207,8 +207,6 @@
   mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
   mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
 
-  gui_validation_error: 1 Ð³Ñ€ÐµÑˆÐºÐ°
-  gui_validation_error_plural: "%{count} Ð³Ñ€ÐµÑˆÐºÐ¸"
 
   field_name: Ð˜Ð¼Ðµ
   field_description: ÐžÐ¿Ð¸Ñ
@@ -329,7 +327,6 @@
   setting_time_format: Ð¤Ð¾Ñ€Ð¼Ð°Ñ‚ Ð½Ð° Ð²Ñ€ÐµÐ¼Ðµ
   setting_cross_project_issue_relations: Ð”Ð¾Ð·Ð²Ð¾Ð»Ð¸ Ñ€ÐµÐ»Ð°Ñ†Ð¸Ð¸ Ð½Ð° Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð¼ÐµÑ“Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¸
   setting_issue_list_default_columns: Default columns displayed on the issue list
-  setting_emails_footer: Emails footer
   setting_protocol: ÐŸÑ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»
   setting_per_page_options: Objects per page options
   setting_user_format: ÐŸÑ€Ð¸ÐºÐ°Ð· Ð½Ð° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸Ñ†Ð¸Ñ‚Ðµ
@@ -386,7 +383,6 @@
   permission_edit_own_time_entries: Ð£Ñ€ÐµÐ´ÑƒÐ²Ð°Ñ˜ ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¸ Ð±ÐµÐ»ÐµÑˆÐºÐ¸ Ð·Ð° Ð¿Ð¾Ñ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾ Ð²Ñ€ÐµÐ¼Ðµ
   permission_manage_news: Manage news
   permission_comment_news: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð°Ñ˜ Ð½Ð° Ð²ÐµÑÑ‚Ð¸
-  permission_manage_documents: Manage documents
   permission_view_documents: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸
   permission_manage_files: Manage files
   permission_view_files: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´ÑƒÐ²Ð°Ñ˜ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ¸
@@ -512,8 +508,6 @@
   label_text: Ð”Ð¾Ð»Ð³ Ñ‚ÐµÐºÑÑ‚
   label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
   label_attribute_plural: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸
-  label_download: "%{count} Ð¿Ñ€ÐµÐ²Ð·ÐµÐ¼Ð°ÑšÐµ"
-  label_download_plural: "%{count} Ð¿Ñ€ÐµÐ²Ð·ÐµÐ¼Ð°ÑšÐ°"
   label_no_data: ÐÐµÐ¼Ð° Ð¿Ð¾Ð´Ð°Ñ‚Ð¾Ñ†Ð¸ Ð·Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð¶ÑƒÐ²Ð°ÑšÐµ
   label_change_status: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
   label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°
@@ -616,8 +610,6 @@
   label_repository: Ð¡ÐºÐ»Ð°Ð´Ð¸ÑˆÑ‚Ðµ
   label_repository_plural: Ð¡ÐºÐ»Ð°Ð´Ð¸ÑˆÑ‚Ð°
   label_browse: ÐŸÑ€ÐµÐ»Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ˜
-  label_modification: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
-  label_modification_plural: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð¸"
   label_branch: Ð“Ñ€Ð°Ð½ÐºÐ°
   label_tag: Tag
   label_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
@@ -933,7 +925,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -974,8 +965,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1082,3 +1071,20 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ð’ÐºÑƒÐ¿Ð½Ð¾
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_footer: Email footer
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/mn.yml
--- a/config/locales/mn.yml
+++ b/config/locales/mn.yml
@@ -51,8 +51,8 @@
         one:   "1 Ñ†Ð°Ð³ Ð¾Ñ€Ñ‡Ð¸Ð¼"
         other: "Ð¾Ð¹Ñ€Ð¾Ð»Ñ†Ð¾Ð¾Ð³Ð¾Ð¾Ñ€ %{count} Ñ†Ð°Ð³"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 Ñ†Ð°Ð³"
+        other: "%{count} Ñ†Ð°Ð³"
       x_days:
         one:   "1 Ó©Ð´Ó©Ñ€"
         other: "%{count} Ó©Ð´Ó©Ñ€"
@@ -200,8 +200,6 @@
   mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
   mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
 
-  gui_validation_error: 1 Ð°Ð»Ð´Ð°Ð°
-  gui_validation_error_plural: "%{count} Ð°Ð»Ð´Ð°Ð°"
 
   field_name: ÐÑÑ€
   field_description: Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ€
@@ -376,7 +374,6 @@
   permission_edit_own_time_entries: Ó¨Ó©Ñ€Ð¸Ð¹Ð½ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð½Ñ‹ Ð»Ð¾Ð³ÑƒÑƒÐ´Ñ‹Ð³ Ð·Ð°ÑÐ²Ð°Ñ€Ð»Ð°Ñ…
   permission_manage_news: ÐœÑÐ´ÑÑ Ð¼ÑÐ´ÑÑÐ»Ð»Ò¯Ò¯Ð´
   permission_comment_news: ÐœÑÐ´ÑÑÐ½Ð´ Ñ‚Ð°Ð¹Ð»Ð±Ð°Ñ€ Ò¯Ð»Ð´ÑÑÑ…
-  permission_manage_documents: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ÑƒÑƒÐ´
   permission_view_documents: Ð‘Ð¸Ñ‡Ð¸Ð³ Ð±Ð°Ñ€Ð¸Ð¼Ñ‚ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
   permission_manage_files: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´
   permission_view_files: Ð¤Ð°Ð¹Ð»ÑƒÑƒÐ´Ñ‹Ð³ Ñ…Ð°Ñ€Ð°Ñ…
@@ -498,8 +495,6 @@
   label_text: Ð£Ñ€Ñ‚ Ñ‚ÐµÐºÑÑ‚
   label_attribute: ÐÑ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚
   label_attribute_plural: ÐÑ‚Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚ÑƒÑƒÐ´
-  label_download: "%{count} Ð¢Ð°Ñ‚Ð°Ð¶ Ð°Ð²ÑÐ°Ð½ Ð·Ò¯Ð¹Ð»"
-  label_download_plural: "%{count} Ð¢Ð°Ñ‚Ð°Ð¶ Ð°Ð²ÑÐ°Ð½ Ð·Ò¯Ð¹Ð»Ñ"
   label_no_data: Ò®Ð·Ò¯Ò¯Ð»ÑÑ… Ó©Ð³Ó©Ð³Ð´Ó©Ð» Ð±Ð°Ð¹Ñ…Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð½Ð°
   label_change_status: Ð¢Ó©Ð»Ð²Ð¸Ð¹Ð³ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…
   label_history: Ð¢Ò¯Ò¯Ñ…
@@ -602,8 +597,6 @@
   label_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸
   label_repository_plural: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€ÑƒÑƒÐ´
   label_browse: Ò®Ð·ÑÑ…
-  label_modification: "%{count} Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚"
-  label_modification_plural: "%{count} Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚Ò¯Ò¯Ð´"
   label_branch: Ð¡Ð°Ð»Ð±Ð°Ñ€
   label_tag: Ð¨Ð¾ÑˆÐ³Ð¾
   label_revision: Ð¥ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€
@@ -934,7 +927,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -975,8 +967,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1083,3 +1073,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: ÐÐ¸Ð¹Ñ‚
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/nl.yml
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -50,7 +50,7 @@
         other: "ongeveer %{count} uren"
       x_hours:
         one:   "1 uur"
-        other: "%{count} hours"
+        other: "%{count} uren"
       x_days:
         one:   "1 dag"
         other: "%{count} dagen"
@@ -291,8 +291,6 @@
   general_text_Yes: 'Ja'
   general_text_no: 'nee'
   general_text_yes: 'ja'
-  gui_validation_error: 1 fout
-  gui_validation_error_plural: "%{count} fouten"
   label_activity: Activiteit
   label_add_another_file: Ander bestand toevoegen
   label_add_note: Voeg een notitie toe
@@ -345,9 +343,9 @@
     one:   1 open
     other: "%{count} open"
   label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
+    zero:  0 gesloten
+    one:   1 gesloten
+    other: "%{count} gesloten"
   label_comment: Commentaar
   label_comment_add: Voeg commentaar toe
   label_comment_added: Commentaar toegevoegd
@@ -385,8 +383,6 @@
   label_document_added: Document toegevoegd
   label_document_new: Nieuw document
   label_document_plural: Documenten
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
   label_downloads_abbr: D/L
   label_duplicated_by: gedupliceerd door
   label_duplicates: dupliceert
@@ -466,8 +462,6 @@
   label_message_plural: Berichten
   label_message_posted: Bericht toegevoegd
   label_min_max_length: Min-max lengte
-  label_modification: "%{count} wijziging"
-  label_modification_plural: "%{count} wijzigingen"
   label_modified: gewijzigd
   label_module_plural: Modules
   label_month: Maand
@@ -666,7 +660,6 @@
   permission_log_time: Gespendeerde tijd loggen
   permission_manage_boards: Forums beheren
   permission_manage_categories: Issue-categorieÃ«n beheren
-  permission_manage_documents: Documenten beheren
   permission_manage_files: Bestanden beheren
   permission_manage_issue_relations: Issuerelaties beheren
   permission_manage_members: Leden beheren
@@ -916,7 +909,6 @@
   label_principal_search: "Zoek naar gebruiker of groep:"
   label_user_search: "Zoek naar gebruiker:"
   field_visible: Zichtbaar
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Standaard activiteit voor tijdregistratie
   text_time_logged_by_changeset: Toegepast in changeset %{value}.
   setting_commit_logtime_enabled: Activeer tijdregistratie
@@ -1031,7 +1023,7 @@
   text_project_closed: Dit project is gesloten en op alleen-lezen
   notice_user_successful_create: Gebruiker %{id} aangemaakt.
   field_core_fields: Standaard verleden
-  field_timeout: Timeout (in seconds)
+  field_timeout: Timeout (in seconden)
   setting_thumbnails_enabled: Geef bijlage miniaturen weer
   setting_thumbnails_size: Grootte miniaturen (in pixels)
   label_status_transitions: Status transitie
@@ -1045,22 +1037,35 @@
   label_attribute_of_assigned_to: Toegewezen %{name}
   label_attribute_of_fixed_version: Target versions %{name}
   label_copy_subtasks: Kopieer subtaken
-  label_copied_to: copied to
-  label_copied_from: copied from
+  label_copied_to: gekopieerd naar
+  label_copied_from: gekopieerd van
   label_any_issues_in_project: any issues in project
   label_any_issues_not_in_project: any issues not in project
-  field_private_notes: Private notes
-  permission_view_private_notes: View private notes
-  permission_set_notes_private: Set notes as private
-  label_no_issues_in_project: no issues in project
+  field_private_notes: PrivÃ© notities
+  permission_view_private_notes: Bekijk privÃ© notities
+  permission_set_notes_private: Maak notities privÃ©
+  label_no_issues_in_project: geen issues in project
   label_any: alle
-  label_last_n_weeks: last %{count} weeks
-  setting_cross_project_subtasks: Allow cross-project subtasks
+  label_last_n_weeks: afgelopen %{count} weken
+  setting_cross_project_subtasks: Sta subtaken in andere projecten toe
   label_cross_project_descendants: Met subprojecten
   label_cross_project_tree: Met project boom
   label_cross_project_hierarchy: Met project hiÃ«rarchie
   label_cross_project_system: Met alle projecten
-  button_hide: Hide
-  setting_non_working_week_days: Non-working days
-  label_in_the_next_days: in the next
-  label_in_the_past_days: in the past
+  button_hide: Verberg
+  setting_non_working_week_days: Niet-werkdagen
+  label_in_the_next_days: in de volgende
+  label_in_the_past_days: in de afgelopen
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: Bij het uitschakelen van meerdere waardes zal er maar een waarde bewaard blijven.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Voeg documenten toe
+  permission_edit_documents: Bewerk documenten
+  permission_delete_documents: Verwijder documenten
+  label_gantt_progress_line: Voortgangslijn
+  setting_jsonp_enabled: Schakel JSONP support in
+  field_inherit_members: Neem leden over
+  field_closed_on: Gesloten
+  setting_default_projects_tracker_ids: Standaard trackers voor nieuwe projecten
+  label_total_time: Totaal
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/no.yml
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -44,8 +44,8 @@
         one: "rundt 1 time"
         other: "rundt %{count} timer"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 time"
+        other: "%{count} timer"
       x_days:
         one: "1 dag"
         other: "%{count} dager"
@@ -174,8 +174,6 @@
   mail_subject_reminder: "%{count} sak(er) har frist de kommende %{days} dagene"
   mail_body_reminder: "%{count} sak(er) som er tildelt deg har frist de kommende %{days} dager:"
 
-  gui_validation_error: 1 feil
-  gui_validation_error_plural: "%{count} feil"
 
   field_name: Navn
   field_description: Beskrivelse
@@ -386,8 +384,6 @@
   label_text: Lang tekst
   label_attribute: Attributt
   label_attribute_plural: Attributter
-  label_download: "%{count} Nedlasting"
-  label_download_plural: "%{count} Nedlastinger"
   label_no_data: Ingen data Ã¥ vise
   label_change_status: Endre status
   label_history: Historikk
@@ -487,8 +483,6 @@
   label_repository: Depot
   label_repository_plural: Depoter
   label_browse: Utforsk
-  label_modification: "%{count} endring"
-  label_modification_plural: "%{count} endringer"
   label_revision: Revisjon
   label_revision_plural: Revisjoner
   label_associated_revisions: Assosierte revisjoner
@@ -745,7 +739,6 @@
   permission_comment_news: Kommentere nyheter
   permission_delete_messages: Slette meldinger
   permission_select_project_modules: Velge prosjektmoduler
-  permission_manage_documents: Administrere dokumenter
   permission_edit_wiki_pages: Redigere wiki-sider
   permission_add_issue_watchers: Legge til overvÃ¥kere
   permission_view_gantt: Vise gantt-diagram
@@ -1072,3 +1065,16 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Totalt
diff -r 0a574315af3e -r 4f746d8966dd config/locales/pl.yml
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -82,8 +82,8 @@
         one:   "okoÅ‚o godziny"
         other: "okoÅ‚o %{count} godzin"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 godzina"
+        other: "%{count} godzin"
       x_days:
         one:   "1 dzieÅ„"
         other: "%{count} dni"
@@ -102,8 +102,9 @@
         few:   "ponad %{count} lata"
         other: "ponad %{count} lat"
       almost_x_years:
-        one:   "prawie rok"
-        other: "prawie %{count} lata"
+        one:   "prawie 1 rok"
+        few:   "prawie %{count} lata"
+        other: "prawie %{count} lat"
 
   activerecord:
     errors:
@@ -134,7 +135,7 @@
         even: "musi byÄ‡ parzyste"
         greater_than_start_date: "musi byÄ‡ wiÄ™ksze niÅ¼ poczÄ…tkowa data"
         not_same_project: "nie naleÅ¼y do tego samego projektu"
-        circular_dependency: "Ta relacja moÅ¼e wytworzyÄ‡ koÅ‚owÄ… zaleÅ¼noÅ›Ä‡"
+        circular_dependency: "Ta relacja moÅ¼e wytworzyÄ‡ zapÄ™tlonÄ… zaleÅ¼noÅ›Ä‡"
         cant_link_an_issue_with_a_descendant: "Zagadnienie nie moÅ¼e zostaÄ‡ powiÄ…zane z jednym z wÅ‚asnych podzagadnieÅ„"
 
   support:
@@ -145,6 +146,9 @@
   # Keep this line in order to avoid problems with Windows Notepad UTF-8 EF-BB-BFidea...
   # Best regards from Lublin@Poland :-)
   # PL translation by Mariusz@Olejnik.net,
+  # Wiktor Wandachowicz <siryes@gmail.com>, 2010
+
+  actionview_instancetag_blank_option: ProszÄ™ wybraÄ‡
   actionview_instancetag_blank_option: ProszÄ™ wybierz
 
   button_activate: Aktywuj
@@ -189,7 +193,7 @@
   default_activity_development: RozwÃ³j
   default_doc_category_tech: Dokumentacja techniczna
   default_doc_category_user: Dokumentacja uÅ¼ytkownika
-  default_issue_status_in_progress: W Toku
+  default_issue_status_in_progress: W toku
   default_issue_status_closed: ZamkniÄ™ty
   default_issue_status_feedback: OdpowiedÅº
   default_issue_status_new: Nowy
@@ -202,7 +206,7 @@
   default_priority_urgent: Pilny
   default_role_developer: Programista
   default_role_manager: Kierownik
-  default_role_reporter: Wprowadzajacy
+  default_role_reporter: ZgÅ‚aszajÄ…cy
   default_tracker_bug: BÅ‚Ä…d
   default_tracker_feature: Zadanie
   default_tracker_support: Wsparcie
@@ -210,7 +214,7 @@
   enumeration_doc_categories: Kategorie dokumentÃ³w
   enumeration_issue_priorities: Priorytety zagadnieÅ„
   error_can_t_load_default_data: "DomyÅ›lna konfiguracja nie moÅ¼e byÄ‡ zaÅ‚adowana: %{value}"
-  error_issue_not_found_in_project: 'Zaganienie nie zostaÅ‚o znalezione lub nie naleÅ¼y do tego projektu'
+  error_issue_not_found_in_project: 'Zagadnienie nie zostaÅ‚o znalezione lub nie naleÅ¼y do tego projektu'
   error_scm_annotate: "Wpis nie istnieje lub nie moÅ¼na do niego dodawaÄ‡ adnotacji."
   error_scm_command_failed: "WystÄ…piÅ‚ bÅ‚Ä…d przy prÃ³bie dostÄ™pu do repozytorium: %{value}"
   error_scm_not_found: "Obiekt lub wersja nie zostaÅ‚y znalezione w repozytorium."
@@ -218,11 +222,11 @@
   field_activity: AktywnoÅ›Ä‡
   field_admin: Administrator
   field_assignable: Zagadnienia mogÄ… byÄ‡ przypisane do tej roli
-  field_assigned_to: Przydzielony do
+  field_assigned_to: Przypisany do
   field_attr_firstname: ImiÄ™ atrybut
   field_attr_lastname: Nazwisko atrybut
   field_attr_login: Login atrybut
-  field_attr_mail: Email atrybut
+  field_attr_mail: E-mail atrybut
   field_auth_source: Tryb identyfikacji
   field_author: Autor
   field_base_dn: Base DN
@@ -244,11 +248,11 @@
   field_filesize: Rozmiar
   field_firstname: ImiÄ™
   field_fixed_version: Wersja docelowa
-  field_hide_mail: Ukryj mÃ³j adres email
+  field_hide_mail: Ukryj mÃ³j adres e-mail
   field_homepage: Strona www
   field_host: Host
   field_hours: Godzin
-  field_identifier: Identifikator
+  field_identifier: Identyfikator
   field_is_closed: Zagadnienie zamkniÄ™te
   field_is_default: DomyÅ›lny status
   field_is_filter: Atrybut filtrowania
@@ -262,15 +266,15 @@
   field_last_login_on: Ostatnie poÅ‚Ä…czenie
   field_lastname: Nazwisko
   field_login: Login
-  field_mail: Email
-  field_mail_notification: Powiadomienia Email
+  field_mail: E-mail
+  field_mail_notification: Powiadomienia e-mail
   field_max_length: Maksymalna dÅ‚ugoÅ›Ä‡
   field_min_length: Minimalna dÅ‚ugoÅ›Ä‡
   field_name: Nazwa
   field_new_password: Nowe hasÅ‚o
   field_notes: Notatki
   field_onthefly: Tworzenie uÅ¼ytkownika w locie
-  field_parent: Nadprojekt
+  field_parent: Projekt nadrzÄ™dny
   field_parent_title: Strona rodzica
   field_password: HasÅ‚o
   field_password_confirmation: Potwierdzenie
@@ -283,7 +287,7 @@
   field_role: Rola
   field_searchable: Przeszukiwalne
   field_spent_on: Data
-  field_start_date: Start
+  field_start_date: Data rozpoczÄ™cia
   field_start_page: Strona startowa
   field_status: Status
   field_subject: Temat
@@ -310,10 +314,7 @@
   general_text_Yes: 'Tak'
   general_text_no: 'nie'
   general_text_yes: 'tak'
-  gui_validation_error: 1 bÅ‚Ä…d
-  gui_validation_error_plural234: "%{count} bÅ‚Ä™dy"
-  gui_validation_error_plural5: "%{count} bÅ‚Ä™dÃ³w"
-  gui_validation_error_plural: "%{count} bÅ‚Ä™dÃ³w"
+
   label_activity: AktywnoÅ›Ä‡
   label_add_another_file: Dodaj kolejny plik
   label_add_note: Dodaj notatkÄ™
@@ -339,7 +340,7 @@
   label_auth_source_new: Nowy tryb identyfikacji
   label_auth_source_plural: Tryby identyfikacji
   label_authentication: Identyfikacja
-  label_blocked_by: zablokowane przez
+  label_blocked_by: blokowane przez
   label_blocks: blokuje
   label_board: Forum
   label_board_new: Nowe forum
@@ -360,42 +361,46 @@
   label_closed_issues_plural5: zamkniÄ™te
   label_closed_issues_plural: zamkniÄ™te
   label_x_open_issues_abbr_on_total:
-    zero:  0 open / %{total}
-    one:   1 open / %{total}
-    other: "%{count} open / %{total}"
+    zero:  0 otwartych / %{total}
+    one:   1 otwarty / %{total}
+    few:   "%{count} otwarte / %{total}"
+    other: "%{count} otwartych / %{total}"
   label_x_open_issues_abbr:
-    zero:  0 open
-    one:   1 open
-    other: "%{count} open"
+    zero:  0 otwartych
+    one:   1 otwarty
+    few:   "%{count} otwarte"
+    other: "%{count} otwartych"
   label_x_closed_issues_abbr:
-    zero:  0 closed
-    one:   1 closed
-    other: "%{count} closed"
+    zero:  0 zamkniÄ™tych
+    one:   1 zamkniÄ™ty
+    few:   "%{count} zamkniÄ™te"
+    other: "%{count} zamkniÄ™tych"
   label_comment: Komentarz
   label_comment_add: Dodaj komentarz
   label_comment_added: Komentarz dodany
   label_comment_delete: UsuÅ„ komentarze
   label_comment_plural234: Komentarze
-  label_comment_plural5: Komentarze
+  label_comment_plural5: Komentarzy
   label_comment_plural: Komentarze
   label_x_comments:
-    zero: no comments
-    one: 1 comment
-    other: "%{count} comments"
+    zero: brak komentarzy
+    one: 1 komentarz
+    few: "%{count} komentarze"
+    other: "%{count} komentarzy"
   label_commits_per_author: Zatwierdzenia wedÅ‚ug autorÃ³w
   label_commits_per_month: Zatwierdzenia wedÅ‚ug miesiÄ™cy
   label_confirmation: Potwierdzenie
   label_contains: zawiera
   label_copied: skopiowano
-  label_copy_workflow_from: Kopiuj przepÅ‚yw z
+  label_copy_workflow_from: Kopiuj przepÅ‚yw pracy z
   label_current_status: Obecny status
   label_current_version: Obecna wersja
-  label_custom_field: Dowolne pole
-  label_custom_field_new: Nowe dowolne pole
-  label_custom_field_plural: Dowolne pola
+  label_custom_field: Pole niestandardowe
+  label_custom_field_new: Nowe pole niestandardowe
+  label_custom_field_plural: Pola niestandardowe
   label_date: Data
-  label_date_from: Z
-  label_date_range: Zakres datowy
+  label_date_from: Od
+  label_date_range: Zakres dat
   label_date_to: Do
   label_day_plural: dni
   label_default: DomyÅ›lne
@@ -410,10 +415,6 @@
   label_document_added: Dodano dokument
   label_document_new: Nowy dokument
   label_document_plural: Dokumenty
-  label_download: "%{count} Pobranie"
-  label_download_plural234: "%{count} Pobrania"
-  label_download_plural5: "%{count} PobraÅ„"
-  label_download_plural: "%{count} Pobrania"
   label_downloads_abbr: Pobieranie
   label_duplicated_by: zduplikowane przez
   label_duplicates: duplikuje
@@ -427,13 +428,13 @@
   label_export_to: Eksportuj do
   label_f_hour: "%{value} godzina"
   label_f_hour_plural: "%{value} godzin"
-  label_feed_plural: IloÅ›Ä‡ RSS
-  label_feeds_access_key_created_on: "Klucz dostÄ™pu RSS stworzony %{value} dni temu"
+  label_feed_plural: IloÅ›Ä‡ Atom
+  label_feeds_access_key_created_on: "Klucz dostÄ™pu do kanaÅ‚u Atom stworzony %{value} temu"
   label_file_added: Dodano plik
   label_file_plural: Pliki
   label_filter_add: Dodaj filtr
   label_filter_plural: Filtry
-  label_float: Liczba rzeczywista
+  label_float: Liczba zmiennoprzecinkowa
   label_follows: nastÄ™puje po
   label_gantt: Gantt
   label_general: OgÃ³lne
@@ -493,10 +494,6 @@
   label_message_plural: WiadomoÅ›ci
   label_message_posted: Dodano wiadomoÅ›Ä‡
   label_min_max_length: Min - Maks dÅ‚ugoÅ›Ä‡
-  label_modification: "%{count} modyfikacja"
-  label_modification_plural234: "%{count} modyfikacje"
-  label_modification_plural5: "%{count} modyfikacji"
-  label_modification_plural: "%{count} modyfikacje"
   label_modified: zmodyfikowane
   label_module_plural: ModuÅ‚y
   label_month: MiesiÄ…c
@@ -523,7 +520,7 @@
   label_not_equals: rÃ³Å¼ni siÄ™
   label_open_issues: otwarte
   label_open_issues_plural234: otwarte
-  label_open_issues_plural5: otwarte
+  label_open_issues_plural5: otwartych
   label_open_issues_plural: otwarte
   label_optional_description: Opcjonalny opis
   label_options: Opcje
@@ -533,7 +530,7 @@
   label_per_page: Na stronÄ™
   label_permissions: Uprawnienia
   label_permissions_report: Raport uprawnieÅ„
-  label_personalize_page: Personalizuj tÄ… stronÄ™
+  label_personalize_page: Personalizuj tÄ™ stronÄ™
   label_planning: Planowanie
   label_please_login: Zaloguj siÄ™
   label_plugins: Wtyczki
@@ -550,7 +547,8 @@
   label_project_plural: Projekty
   label_x_projects:
     zero:  brak projektÃ³w
-    one:   jeden projekt
+    one:   1 projekt
+    few:   "%{count} projekty"
     other: "%{count} projektÃ³w"
   label_public_projects: Projekty publiczne
   label_query: Kwerenda
@@ -566,7 +564,7 @@
   label_relates_to: powiÄ…zane z
   label_relation_delete: UsuÅ„ powiÄ…zanie
   label_relation_new: Nowe powiÄ…zanie
-  label_renamed: przemianowano
+  label_renamed: zmieniono nazwÄ™
   label_reply_plural: Odpowiedzi
   label_report: Raport
   label_report_plural: Raporty
@@ -582,14 +580,14 @@
   label_roadmap_no_issues: Brak zagadnieÅ„ do tej wersji
   label_roadmap_overdue: "%{value} spÃ³Åºnienia"
   label_role: Rola
-  label_role_and_permissions: Role i Uprawnienia
+  label_role_and_permissions: Role i uprawnienia
   label_role_new: Nowa rola
   label_role_plural: Role
   label_scm: SCM
   label_search: Szukaj
   label_search_titles_only: Przeszukuj tylko tytuÅ‚y
   label_send_information: WyÅ›lij informacjÄ™ uÅ¼ytkownikowi
-  label_send_test_email: WyÅ›lij prÃ³bny email
+  label_send_test_email: WyÅ›lij prÃ³bny e-mail
   label_settings: Ustawienia
   label_show_completed_versions: PokaÅ¼ kompletne wersje
   label_sort_by: "Sortuj po %{value}"
@@ -621,7 +619,7 @@
   label_user: UÅ¼ytkownik
   label_user_mail_no_self_notified: "Nie chcÄ™ powiadomieÅ„ o zmianach, ktÃ³re sam wprowadzam."
   label_user_mail_option_all: "Dla kaÅ¼dego zdarzenia w kaÅ¼dym moim projekcie"
-  label_user_mail_option_selected: "Tylko dla kaÅ¼dego zdarzenia w wybranych projektach..."
+  label_user_mail_option_selected: "Dla kaÅ¼dego zdarzenia w wybranych projektach..."
   label_user_new: Nowy uÅ¼ytkownik
   label_user_plural: UÅ¼ytkownicy
   label_version: Wersja
@@ -636,12 +634,12 @@
   label_wiki_edit_plural: Edycje wiki
   label_wiki_page: Strona wiki
   label_wiki_page_plural: Strony wiki
-  label_workflow: PrzepÅ‚yw
+  label_workflow: PrzepÅ‚yw pracy
   label_year: Rok
   label_yesterday: wczoraj
   mail_body_account_activation_request: "Zarejestrowano nowego uÅ¼ytkownika: (%{value}). Konto oczekuje na twoje zatwierdzenie:"
   mail_body_account_information: Twoje konto
-  mail_body_account_information_external: "MoÅ¼esz uÅ¼yÄ‡ twojego %{value} konta do zalogowania."
+  mail_body_account_information_external: "MoÅ¼esz uÅ¼yÄ‡ Twojego konta %{value} do zalogowania."
   mail_body_lost_password: 'W celu zmiany swojego hasÅ‚a uÅ¼yj poniÅ¼szego odnoÅ›nika:'
   mail_body_register: 'W celu aktywacji Twojego konta, uÅ¼yj poniÅ¼szego odnoÅ›nika:'
   mail_body_reminder: "Wykaz przypisanych do Ciebie zagadnieÅ„, ktÃ³rych termin wypada w ciÄ…gu nastÄ™pnych %{count} dni"
@@ -651,23 +649,23 @@
   mail_subject_reminder: "Uwaga na terminy, masz zagadnienia do obsÅ‚uÅ¼enia w ciÄ…gu nastÄ™pnych %{count} dni! (%{days})"
   notice_account_activated: Twoje konto zostaÅ‚o aktywowane. MoÅ¼esz siÄ™ zalogowaÄ‡.
   notice_account_invalid_creditentials: ZÅ‚y uÅ¼ytkownik lub hasÅ‚o
-  notice_account_lost_email_sent: Email z instrukcjami zmiany hasÅ‚a zostaÅ‚ wysÅ‚any do Ciebie.
+  notice_account_lost_email_sent: E-mail z instrukcjami zmiany hasÅ‚a zostaÅ‚ wysÅ‚any do Ciebie.
   notice_account_password_updated: HasÅ‚o prawidÅ‚owo zmienione.
   notice_account_pending: "Twoje konto zostaÅ‚o utworzone i oczekuje na zatwierdzenie administratora."
-  notice_account_register_done: Konto prawidÅ‚owo stworzone.
+  notice_account_register_done: Konto prawidÅ‚owo utworzone.
   notice_account_unknown_email: Nieznany uÅ¼ytkownik.
   notice_account_updated: Konto prawidÅ‚owo zaktualizowane.
   notice_account_wrong_password: ZÅ‚e hasÅ‚o
   notice_can_t_change_password: To konto ma zewnÄ™trzne ÅºrÃ³dÅ‚o identyfikacji. Nie moÅ¼esz zmieniÄ‡ hasÅ‚a.
   notice_default_data_loaded: DomyÅ›lna konfiguracja zostaÅ‚a pomyÅ›lnie zaÅ‚adowana.
-  notice_email_error: "WystÄ…piÅ‚ bÅ‚Ä…d w trakcie wysyÅ‚ania maila (%{value})"
-  notice_email_sent: "Email zostaÅ‚ wysÅ‚any do %{value}"
+  notice_email_error: "WystÄ…piÅ‚ bÅ‚Ä…d w trakcie wysyÅ‚ania e-maila (%{value})"
+  notice_email_sent: "E-mail zostaÅ‚ wysÅ‚any do %{value}"
   notice_failed_to_save_issues: "BÅ‚Ä…d podczas zapisu zagadnieÅ„ %{count} z %{total} zaznaczonych: %{ids}."
-  notice_feeds_access_key_reseted: TwÃ³j klucz dostÄ™pu RSS zostaÅ‚ zrestetowany.
+  notice_feeds_access_key_reseted: TwÃ³j klucz dostÄ™pu do kanaÅ‚u Atom zostaÅ‚ zresetowany.
   notice_file_not_found: Strona do ktÃ³rej prÃ³bujesz siÄ™ dostaÄ‡ nie istnieje lub zostaÅ‚a usuniÄ™ta.
   notice_locking_conflict: Dane poprawione przez innego uÅ¼ytkownika.
   notice_no_issue_selected: "Nie wybrano zagadnienia! Zaznacz zagadnienie, ktÃ³re chcesz edytowaÄ‡."
-  notice_not_authorized: Nie jesteÅ› autoryzowany by zobaczyÄ‡ stronÄ™.
+  notice_not_authorized: Nie posiadasz autoryzacji do oglÄ…dania tej strony.
   notice_successful_connection: Udane nawiÄ…zanie poÅ‚Ä…czenia.
   notice_successful_create: Utworzenie zakoÅ„czone sukcesem.
   notice_successful_delete: UsuniÄ™cie zakoÅ„czone sukcesem.
@@ -696,8 +694,7 @@
   permission_edit_wiki_pages: Edycja stron wiki
   permission_log_time: Zapisywanie przepracowanego czasu
   permission_manage_boards: ZarzÄ…dzanie forami
-  permission_manage_categories: ZarzÄ…dzanie kategoriami zaganieÅ„
-  permission_manage_documents: ZarzÄ…dzanie dokumentami
+  permission_manage_categories: ZarzÄ…dzanie kategoriami zagadnieÅ„
   permission_manage_files: ZarzÄ…dzanie plikami
   permission_manage_issue_relations: ZarzÄ…dzanie powiÄ…zaniami zagadnieÅ„
   permission_manage_members: ZarzÄ…dzanie uczestnikami
@@ -734,7 +731,7 @@
   setting_app_title: TytuÅ‚ aplikacji
   setting_attachment_max_size: Maks. rozm. zaÅ‚Ä…cznika
   setting_autofetch_changesets: Automatyczne pobieranie zmian
-  setting_autologin: Auto logowanie
+  setting_autologin: Automatyczne logowanie
   setting_bcc_recipients: Odbiorcy kopii tajnej (kt/bcc)
   setting_commit_fix_keywords: SÅ‚owa zmieniajÄ…ce status
   setting_commit_ref_keywords: SÅ‚owa tworzÄ…ce powiÄ…zania
@@ -745,24 +742,24 @@
   setting_display_subprojects_issues: DomyÅ›lnie pokazuj zagadnienia podprojektÃ³w w gÅ‚Ã³wnym projekcie
   setting_emails_footer: Stopka e-mail
   setting_enabled_scm: DostÄ™pny SCM
-  setting_feeds_limit: Limit danych RSS
+  setting_feeds_limit: Limit danych Atom
   setting_gravatar_enabled: UÅ¼ywaj ikon uÅ¼ytkownikÃ³w Gravatar
   setting_host_name: Nazwa hosta i Å›cieÅ¼ka
   setting_issue_list_default_columns: DomyÅ›lne kolumny wyÅ›wietlane na liÅ›cie zagadnieÅ„
   setting_issues_export_limit: Limit eksportu zagadnieÅ„
-  setting_login_required: Identyfikacja wymagana
-  setting_mail_from: Adres email wysyÅ‚ki
+  setting_login_required: Wymagane zalogowanie
+  setting_mail_from: Adres e-mail wysyÅ‚ki
   setting_mail_handler_api_enabled: Uaktywnij usÅ‚ugi sieciowe (WebServices) dla poczty przychodzÄ…cej
   setting_mail_handler_api_key: Klucz API
   setting_per_page_options: Opcje iloÅ›ci obiektÃ³w na stronie
   setting_plain_text_mail: tylko tekst (bez HTML)
-  setting_protocol: ProtokoÅ‚
+  setting_protocol: ProtokÃ³Å‚
   setting_self_registration: Samodzielna rejestracja uÅ¼ytkownikÃ³w
   setting_sequential_project_identifiers: Generuj sekwencyjne identyfikatory projektÃ³w
   setting_sys_api_enabled: WÅ‚Ä…czenie WS do zarzÄ…dzania repozytorium
   setting_text_formatting: Formatowanie tekstu
   setting_time_format: Format czasu
-  setting_user_format: Personalny format wyÅ›wietlania
+  setting_user_format: WÅ‚asny format wyÅ›wietlania
   setting_welcome_text: Tekst powitalny
   setting_wiki_compression: Kompresja historii Wiki
   status_active: aktywny
@@ -772,43 +769,43 @@
   text_assign_time_entries_to_project: Przypisz wpisy dziennika do projektu
   text_caracters_maximum: "%{count} znakÃ³w maksymalnie."
   text_caracters_minimum: "Musi byÄ‡ nie krÃ³tsze niÅ¼ %{count} znakÃ³w."
-  text_comma_separated: Wielokrotne wartoÅ›ci dozwolone (rozdzielone przecinkami).
+  text_comma_separated: Dozwolone wielokrotne wartoÅ›ci (rozdzielone przecinkami).
   text_default_administrator_account_changed: Zmieniono domyÅ›lne hasÅ‚o administratora
   text_destroy_time_entries: UsuÅ„ wpisy dziennika
   text_destroy_time_entries_question: Przepracowano %{hours} godzin przy zagadnieniu, ktÃ³re chcesz usunÄ…Ä‡. Co chcesz zrobiÄ‡?
-  text_email_delivery_not_configured: "Dostarczanie poczty elektronicznej nie zostaÅ‚o skonfigurowane, wiÄ™c powiadamianie jest nieaktywne.\nSkonfiguruj serwer SMTP w config/configuration.yml  a nastÄ™pnie zrestartuj aplikacjÄ™ i uaktywnij to."
+  text_email_delivery_not_configured: "Dostarczanie poczty elektronicznej nie zostaÅ‚o skonfigurowane, wiÄ™c powiadamianie jest nieaktywne.\nSkonfiguruj serwer SMTP w config/email.yml a nastÄ™pnie zrestartuj aplikacjÄ™ i uaktywnij to."
   text_enumeration_category_reassign_to: 'ZmieÅ„ przypisanie na tÄ… wartoÅ›Ä‡:'
-  text_enumeration_destroy_question: "%{count} obiektÃ³w jest przypisana do tej wartoÅ›ci."
+  text_enumeration_destroy_question: "%{count} obiektÃ³w jest przypisanych do tej wartoÅ›ci."
   text_file_repository_writable: Zapisywalne repozytorium plikÃ³w
-  text_issue_added: "Zagadnienie %{id} zostaÅ‚o wprowadzone (by %{author})."
+  text_issue_added: "Zagadnienie %{id} zostaÅ‚o wprowadzone (przez %{author})."
   text_issue_category_destroy_assignments: UsuÅ„ przydziaÅ‚y kategorii
-  text_issue_category_destroy_question: "Zagadnienia (%{count}) sÄ… przypisane do tej kategorii. Co chcesz zrobiÄ‡?"
+  text_issue_category_destroy_question: "Do tej kategorii sÄ… przypisane zagadnienia (%{count}). Co chcesz zrobiÄ‡?"
   text_issue_category_reassign_to: Przydziel zagadnienie do tej kategorii
-  text_issue_updated: "Zagadnienie %{id} zostaÅ‚o zaktualizowane (by %{author})."
-  text_issues_destroy_confirmation: 'Czy jestes pewien, Å¼e chcesz usunÄ…Ä‡ wskazane zagadnienia?'
+  text_issue_updated: "Zagadnienie %{id} zostaÅ‚o zaktualizowane (przez %{author})."
+  text_issues_destroy_confirmation: 'Czy jesteÅ› pewien, Å¼e chcesz usunÄ…Ä‡ wskazane zagadnienia?'
   text_issues_ref_in_commit_messages: OdwoÅ‚ania do zagadnieÅ„ w komentarzach zatwierdzeÅ„
   text_length_between: "DÅ‚ugoÅ›Ä‡ pomiÄ™dzy %{min} i %{max} znakÃ³w."
   text_load_default_configuration: ZaÅ‚aduj domyÅ›lnÄ… konfiguracjÄ™
   text_min_max_length_info: 0 oznacza brak restrykcji
-  text_no_configuration_data: "Role uÅ¼ytkownikÃ³w, typy zagadnieÅ„, statusy zagadnieÅ„ oraz przepÅ‚yw pracy nie zostaÅ‚y jeszcze skonfigurowane.\nJest wysoce rekomendowane by zaÅ‚adowaÄ‡ domyÅ›lnÄ… konfiguracjÄ™. Po zaÅ‚adowaniu bÄ™dzie moÅ¼liwoÅ›Ä‡ edycji tych danych."
+  text_no_configuration_data: "Role uÅ¼ytkownikÃ³w, typy zagadnieÅ„, statusy zagadnieÅ„ oraz przepÅ‚yw pracy nie zostaÅ‚y jeszcze skonfigurowane.\nWysoce zalecane jest by zaÅ‚adowaÄ‡ domyÅ›lnÄ… konfiguracjÄ™. Po zaÅ‚adowaniu bÄ™dzie moÅ¼liwoÅ›Ä‡ edycji tych danych."
   text_project_destroy_confirmation: JesteÅ› pewien, Å¼e chcesz usunÄ…Ä‡ ten projekt i wszystkie powiÄ…zane dane?
   text_reassign_time_entries: 'Przepnij przepracowany czas do tego zagadnienia:'
   text_regexp_info: np. ^[A-Z0-9]+$
-  text_repository_usernames_mapping: "Wybierz lub uaktualnij przyporzÄ…dkowanie uÅ¼ytkownikÃ³w Redmine do uÅ¼ytkownikÃ³w repozytorium.\nUÅ¼ytkownicy z takÄ… samÄ… nazwÄ… lub adresem email sÄ… przyporzÄ…dkowani automatycznie."
+  text_repository_usernames_mapping: "Wybierz lub uaktualnij przyporzÄ…dkowanie uÅ¼ytkownikÃ³w Redmine do uÅ¼ytkownikÃ³w repozytorium.\nUÅ¼ytkownicy z takÄ… samÄ… nazwÄ… lub adresem e-mail sÄ… przyporzÄ…dkowani automatycznie."
   text_rmagick_available: RMagick dostÄ™pne (opcjonalnie)
-  text_select_mail_notifications: Zaznacz czynnoÅ›ci przy ktÃ³rych uÅ¼ytkownik powinien byÄ‡ powiadomiony mailem.
+  text_select_mail_notifications: Zaznacz czynnoÅ›ci przy ktÃ³rych uÅ¼ytkownik powinien byÄ‡ powiadomiony e-mailem.
   text_select_project_modules: 'Wybierz moduÅ‚y do aktywacji w tym projekcie:'
   text_status_changed_by_changeset: "Zastosowane w zmianach %{value}."
   text_subprojects_destroy_warning: "Podprojekt(y): %{value} zostanÄ… takÅ¼e usuniÄ™te."
   text_tip_issue_begin_day: zadanie zaczynajÄ…ce siÄ™ dzisiaj
   text_tip_issue_begin_end_day: zadanie zaczynajÄ…ce i koÅ„czÄ…ce siÄ™ dzisiaj
   text_tip_issue_end_day: zadanie koÅ„czÄ…ce siÄ™ dzisiaj
-  text_tracker_no_workflow: Brak przepÅ‚ywu zdefiniowanego dla tego typu zagadnienia
+  text_tracker_no_workflow: Brak przepÅ‚ywu pracy zdefiniowanego dla tego typu zagadnienia
   text_unallowed_characters: Niedozwolone znaki
-  text_user_mail_option: "W przypadku niezaznaczonych projektÃ³w, bÄ™dziesz otrzymywaÅ‚ powiadomienia tylko na temat zagadnieÅ„, ktÃ³re obserwujesz, lub w ktÃ³rych bierzesz udziaÅ‚ (np. jesteÅ› autorem lub adresatem)."
-  text_user_wrote: "%{value} napisaÅ‚:"
-  text_wiki_destroy_confirmation: JesteÅ› pewien, Å¼e chcesz usunÄ…Ä‡ to wiki i caÅ‚Ä… jego zawartoÅ›Ä‡ ?
-  text_workflow_edit: Zaznacz rolÄ™ i typ zagadnienia do edycji przepÅ‚ywu
+  text_user_mail_option: "W przypadku niezaznaczonych projektÃ³w, bÄ™dziesz otrzymywaÅ‚ powiadomienia tylko na temat zagadnieÅ„ ktÃ³re obserwujesz, lub w ktÃ³rych bierzesz udziaÅ‚ (np. jesteÅ› autorem lub adresatem)."
+  text_user_wrote: "%{value} napisaÅ‚(a):"
+  text_wiki_destroy_confirmation: JesteÅ› pewien, Å¼e chcesz usunÄ…Ä‡ to wiki i caÅ‚Ä… jego zawartoÅ›Ä‡?
+  text_workflow_edit: Zaznacz rolÄ™ i typ zagadnienia do edycji przepÅ‚ywu pracy
 
   label_user_activity: "AktywnoÅ›Ä‡: %{value}"
   label_updated_time_by: "Uaktualnione przez %{author} %{age} temu"
@@ -851,7 +848,7 @@
   label_tag: SÅ‚owo kluczowe
   label_branch: GaÅ‚Ä…Åº
   error_no_tracker_in_project: Projekt nie posiada powiÄ…zanych typÃ³w zagadnieÅ„. SprawdÅº ustawienia projektu.
-  error_no_default_issue_status: Nie zdefiniowano domyÅ›lnego statusu zagadnieÅ„. SprawdÅº konfiguracjÄ™ (PrzejdÅº do "Administracja -> Statusy zagadnieÅ„).
+  error_no_default_issue_status: Nie zdefiniowano domyÅ›lnego statusu zagadnieÅ„. SprawdÅº konfiguracjÄ™ (PrzejdÅº do "Administracja -> Statusy zagadnieÅ„").
   text_journal_changed: "Zmieniono %{label} z %{old} na %{new}"
   text_journal_set_to: "Ustawiono %{label} na %{value}"
   text_journal_deleted: "UsuniÄ™to %{label} (%{old})"
@@ -861,7 +858,7 @@
   label_time_entry_plural: Przepracowany czas
   text_journal_added: "Dodano %{label} %{value}"
   field_active: Aktywne
-  enumeration_system_activity: AktywnoÅ›Ä‡ Systemowa
+  enumeration_system_activity: AktywnoÅ›Ä‡ systemowa
   button_copy_and_follow: Kopiuj i przejdÅº do kopii zagadnienia
   button_duplicate: Duplikuj
   button_move_and_follow: PrzenieÅ› i przejdÅº do zagadnienia
@@ -879,9 +876,9 @@
   label_copy_source: Å¹rÃ³dÅ‚o
   label_copy_target: Cel
   label_display_used_statuses_only: WyÅ›wietlaj tylko statusy uÅ¼ywane przez ten typ zagadnienia
-  label_feeds_access_key: Klucz dostÄ™pu do RSS
+  label_feeds_access_key: Klucz dostÄ™pu do kanaÅ‚u Atom
   label_missing_api_access_key: Brakuje klucza dostÄ™pu do API
-  label_missing_feeds_access_key: Brakuje klucza dostÄ™pu do RSS
+  label_missing_feeds_access_key: Brakuje klucza dostÄ™pu do kanaÅ‚u Atom
   label_revision_id: Rewizja %{value}
   label_subproject_new: Nowy podprojekt
   label_update_issue_done_ratios: Uaktualnij % wykonania
@@ -922,7 +919,7 @@
   permission_manage_subtasks: ZarzÄ…dzanie podzagadnieniami
   field_parent_issue: Zagadnienie nadrzÄ™dne
   label_subtask_plural: Podzagadnienia
-  label_project_copy_notifications: WyÅ›lij powiadomienia mailowe przy kopiowaniu projektu
+  label_project_copy_notifications: WyÅ›lij powiadomienia e-mailowe przy kopiowaniu projektu
   error_can_not_delete_custom_field: Nie moÅ¼na usunÄ…Ä‡ tego pola
   error_unable_to_connect: Nie moÅ¼na poÅ‚Ä…czyÄ‡ (%{value})
   error_can_not_remove_role: Ta rola przypisana jest niektÃ³rym uÅ¼ytkownikom i nie moÅ¼e zostaÄ‡ usuniÄ™ta.
@@ -930,8 +927,8 @@
   field_principal: PrzeÅ‚oÅ¼ony
   label_my_page_block: Elementy
   notice_failed_to_save_members: "Nie moÅ¼na zapisaÄ‡ uczestnikÃ³w: %{errors}."
-  text_zoom_out: Zmniejsz czcionkÄ™
-  text_zoom_in: PowiÄ™ksz czcionkÄ™
+  text_zoom_out: Zmniejsz
+  text_zoom_in: PowiÄ™ksz
   notice_unable_delete_time_entry: Nie moÅ¼na usunÄ…Ä‡ wpisu z dziennika.
   label_overall_spent_time: Przepracowany czas
   field_time_entries: Dziennik
@@ -943,14 +940,13 @@
   setting_default_notification_option: Default notification option
   label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
   label_user_mail_option_only_assigned: Only for things I am assigned to
-  label_user_mail_option_none: No events
+  label_user_mail_option_none: "Tylko to, co obserwujÄ™ lub w czym biorÄ™ udziaÅ‚"
   field_member_of_group: Assignee's group
   field_assigned_to_role: Assignee's role
   notice_not_authorized_archived_project: The project you're trying to access has been archived.
-  label_principal_search: "Search for user or group:"
-  label_user_search: "Search for user:"
+  label_principal_search: "Szukaj uÅ¼ytkownika lub grupy:"
+  label_user_search: "Szukaj uÅ¼ytkownika:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -991,8 +987,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1035,7 +1029,7 @@
   label_copy_attachments: Copy attachments
   label_item_position: "%{position}/%{count}"
   label_completed_versions: Completed versions
-  text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
+  text_project_identifier_info: 'Dozwolone maÅ‚e litery (a-z), liczby i myÅ›lniki.<br />Raz zapisany, identyfikator nie moÅ¼e byÄ‡ zmieniony.'
   field_multiple: Multiple values
   setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
   text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
@@ -1099,3 +1093,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: OgÃ³Å‚em
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/pt-BR.yml
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -122,8 +122,8 @@
     errors:
       template:
         header:
-          one: "model nÃ£o pode ser salvo: 1 erro"
-          other: "model nÃ£o pode ser salvo: %{count} erros."
+          one: "modelo nÃ£o pode ser salvo: 1 erro"
+          other: "modelo nÃ£o pode ser salvo: %{count} erros."
         body: "Por favor, verifique os seguintes campos:"
       messages:
         inclusion: "nÃ£o estÃ¡ incluso na lista"
@@ -134,7 +134,7 @@
         empty: "nÃ£o pode ficar vazio"
         blank: "nÃ£o pode ficar vazio"
         too_long: "Ã© muito longo (mÃ¡ximo: %{count} caracteres)"
-        too_short: "Ã© muito curto (mÃ­nimon: %{count} caracteres)"
+        too_short: "Ã© muito curto (mÃ­nimo: %{count} caracteres)"
         wrong_length: "deve ter %{count} caracteres"
         taken: "nÃ£o estÃ¡ disponÃ­vel"
         not_a_number: "nÃ£o Ã© um nÃºmero"
@@ -206,8 +206,6 @@
   mail_subject_reminder: "%{count} tarefa(s) com data prevista para os prÃ³ximos %{days} dias"
   mail_body_reminder: "%{count} tarefa(s) para vocÃª com data prevista para os prÃ³ximos %{days} dias:"
 
-  gui_validation_error: 1 erro
-  gui_validation_error_plural: "%{count} erros"
 
   field_name: Nome
   field_description: DescriÃ§Ã£o
@@ -425,8 +423,6 @@
   label_text: Texto longo
   label_attribute: Atributo
   label_attribute_plural: Atributos
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
   label_no_data: Nenhuma informaÃ§Ã£o disponÃ­vel
   label_change_status: Alterar situaÃ§Ã£o
   label_history: HistÃ³rico
@@ -526,8 +522,6 @@
   label_repository: RepositÃ³rio
   label_repository_plural: RepositÃ³rios
   label_browse: Procurar
-  label_modification: "%{count} alteraÃ§Ã£o"
-  label_modification_plural: "%{count} alteraÃ§Ãµes"
   label_revision: RevisÃ£o
   label_revision_plural: RevisÃµes
   label_associated_revisions: RevisÃµes associadas
@@ -780,7 +774,6 @@
   permission_comment_news: Comentar notÃ­cias
   permission_delete_messages: Excluir mensagens
   permission_select_project_modules: Selecionar mÃ³dulos de projeto
-  permission_manage_documents: Gerenciar documentos
   permission_edit_wiki_pages: Editar pÃ¡ginas wiki
   permission_add_issue_watchers: Adicionar observadores
   permission_view_gantt: Ver grÃ¡fico gantt
@@ -887,12 +880,12 @@
   label_copy_source: Origem
   setting_issue_done_ratio: Calcular o percentual de conclusÃ£o da tarefa
   setting_issue_done_ratio_issue_status: Usar a situaÃ§Ã£o da tarefa
-  error_issue_done_ratios_not_updated: O pecentual de conclusÃ£o das tarefas nÃ£o foi atualizado.
+  error_issue_done_ratios_not_updated: O percentual de conclusÃ£o das tarefas nÃ£o foi atualizado.
   error_workflow_copy_target: Por favor, selecione os tipos de tarefa e os papÃ©is alvo
   setting_issue_done_ratio_issue_field: Use o campo da tarefa
   label_copy_same_as_target: Mesmo alvo
   label_copy_target: Alvo
-  notice_issue_done_ratios_updated: Percentual de conslusÃ£o atualizados.
+  notice_issue_done_ratios_updated: Percentual de conclusÃ£o atualizados.
   error_workflow_copy_source: Por favor, selecione um tipo de tarefa e papel de origem
   label_update_issue_done_ratios: Atualizar percentual de conclusÃ£o das tarefas
   setting_start_of_week: InÃ­cio da semana
@@ -905,7 +898,7 @@
   label_api_access_key_created_on: Chave de acesso a API criado a %{value} atrÃ¡s
   label_feeds_access_key: Chave de acesso ao RSS
   notice_api_access_key_reseted: Sua chave de acesso a API foi redefinida.
-  setting_rest_api_enabled: Habilitar REST web service
+  setting_rest_api_enabled: Habilitar a api REST
   label_missing_api_access_key: Chave de acesso a API faltando
   label_missing_feeds_access_key: Chave de acesso ao RSS faltando
   text_line_separated: MÃºltiplos valores permitidos (uma linha para cada valor).
@@ -923,7 +916,7 @@
   permission_manage_project_activities: Gerenciar atividades do projeto
   error_unable_delete_issue_status: NÃ£o foi possÃ­vel excluir situaÃ§Ã£o da tarefa
   label_profile: Perfil
-  permission_manage_subtasks: Gerenciar subtarefas
+  permission_manage_subtasks: Gerenciar sub-tarefas
   field_parent_issue: Tarefa pai
   label_subtask_plural: Subtarefas
   label_project_copy_notifications: Enviar notificaÃ§Ãµes por e-mail ao copiar projeto
@@ -1071,7 +1064,7 @@
   notice_user_successful_create: UsuÃ¡rio %{id} criado.
   field_core_fields: campos padrÃ£o
   field_timeout: Tempo de espera (em segundos)
-  setting_thumbnails_enabled: exibir miniaturas de anexos
+  setting_thumbnails_enabled: Exibir miniaturas de anexos
   setting_thumbnails_size: Tamanho das miniaturas (em pixels)
   label_status_transitions: Estados das transiÃ§Ãµes
   label_fields_permissions: PermissÃµes de campos
@@ -1090,16 +1083,28 @@
   label_any_issues_not_in_project: todas as questÃµes que nÃ£o estÃ£o em projeto
   field_private_notes: notas privadas
   permission_view_private_notes: Ver notas privadas
-  permission_set_notes_private: Defina notas como privada
+  permission_set_notes_private: Permitir alterar notas para privada
   label_no_issues_in_project: sem problemas em projeto
   label_any: todos
   label_last_n_weeks: "Ãºltimas %{count} semanas"
-  setting_cross_project_subtasks: Permitir cruzamento de sub-tarefas entre projetos 
-  label_cross_project_descendants: Com sub-projetos
-  label_cross_project_tree: Com a Ã¡rvore do projeto
-  label_cross_project_hierarchy: Com a hierarquia do projeto
-  label_cross_project_system: Com todos os projetos
+  setting_cross_project_subtasks: Permitir cruzamento de sub-tarefas entre projetos
+  label_cross_project_descendants: com sub-Projetos
+  label_cross_project_tree: Com uma Ãrvore fazer o Projeto
+  label_cross_project_hierarchy: Com uma hierarquia fazer o Projeto
+  label_cross_project_system: Com de Todos os Projetos
   button_hide: Esconder
   setting_non_working_week_days: dias nÃ£o Ãºteis
   label_in_the_next_days: na prÃ³xima
   label_in_the_past_days: no passado
+  label_attribute_of_user: UsuÃ¡rio %{name}
+  text_turning_multiple_off: Se vocÃª desativar vÃ¡rios valores, vÃ¡rios valores serÃ£o removidas, a fim de preservar a somente um valor por item.
+  label_attribute_of_issue: EmissÃ£o de %{name}
+  permission_add_documents: Adicionar documentos
+  permission_edit_documents: Editar documentos
+  permission_delete_documents: excluir documentos
+  label_gantt_progress_line: Linha de progresso
+  setting_jsonp_enabled: Ativar suporte JSONP
+  field_inherit_members: Herdar membros
+  field_closed_on: Fechado
+  setting_default_projects_tracker_ids: Tipos padrÃµes para novos projeto
+  label_total_time: Total
diff -r 0a574315af3e -r 4f746d8966dd config/locales/pt.yml
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -194,8 +194,6 @@
   mail_subject_reminder: "%{count} tarefa(s) para entregar nos prÃ³ximos %{days} dias"
   mail_body_reminder: "%{count} tarefa(s) que estÃ£o atribuÃ­das a si estÃ£o agendadas para estarem completas nos prÃ³ximos %{days} dias:"
 
-  gui_validation_error: 1 erro
-  gui_validation_error_plural: "%{count} erros"
 
   field_name: Nome
   field_description: DescriÃ§Ã£o
@@ -410,8 +408,6 @@
   label_text: Texto longo
   label_attribute: Atributo
   label_attribute_plural: Atributos
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
   label_no_data: Sem dados para mostrar
   label_change_status: Mudar estado
   label_history: HistÃ³rico
@@ -511,8 +507,6 @@
   label_repository: RepositÃ³rio
   label_repository_plural: RepositÃ³rios
   label_browse: Navegar
-  label_modification: "%{count} alteraÃ§Ã£o"
-  label_modification_plural: "%{count} alteraÃ§Ãµes"
   label_revision: RevisÃ£o
   label_revision_plural: RevisÃµes
   label_associated_revisions: RevisÃµes associadas
@@ -764,7 +758,6 @@
   permission_comment_news: Comentar notÃ­cias
   permission_delete_messages: Apagar mensagens
   permission_select_project_modules: Seleccionar mÃ³dulos do projecto
-  permission_manage_documents: Gerir documentos
   permission_edit_wiki_pages: Editar pÃ¡ginas de wiki
   permission_add_issue_watchers: Adicionar observadores
   permission_view_gantt: ver diagrama de Gantt
@@ -943,7 +936,7 @@
   setting_commit_logtime_activity_id: Actividade para tempo registado
   text_time_logged_by_changeset: Aplicado no conjunto de alteraÃ§Ãµes %{value}.
   setting_commit_logtime_enabled: Activar registo de tempo
-  notice_gantt_chart_truncated: O grÃ¡fico foi truncado porque excede o nÃºmero mÃ¡ximo de itens visÃ­vel (%{mÃ¡x.})
+  notice_gantt_chart_truncated: O grÃ¡fico foi truncado porque excede o nÃºmero mÃ¡ximo de itens visÃ­veis (%{max.})
   setting_gantt_items_limit: NÃºmero mÃ¡ximo de itens exibidos no grÃ¡fico Gantt
   field_warn_on_leaving_unsaved: Avisar-me quando deixar uma pÃ¡gina com texto por salvar
   text_warn_on_leaving_unsaved: A pÃ¡gina actual contÃ©m texto por salvar que serÃ¡ perdido caso saia desta pÃ¡gina.
@@ -1016,7 +1009,7 @@
   error_attachment_too_big: Este ficheiro nÃ£o pode ser carregado pois excede o tamanho mÃ¡ximo permitido por ficheiro (%{max_size})
   notice_failed_to_save_time_entries: "Falha ao guardar %{count} registo(s) de tempo dos %{total} seleccionados: %{ids}."
   label_x_issues:
-    zero:  0 tarefa
+    zero:  0 tarefas
     one:   1 tarefa
     other: "%{count} tarefas"
   label_repository_new: Novo repositÃ³rio
@@ -1088,3 +1081,16 @@
   setting_non_working_week_days: Dias nÃ£o Ãºteis
   label_in_the_next_days: no futuro
   label_in_the_past_days: no passado
+  label_attribute_of_user: Do utilizador %{name}
+  text_turning_multiple_off: Se desactivar a escolha mÃºltipla,
+    a escolha mÃºltipla serÃ¡ apagada de modo a manter apenas um valor por item.
+  label_attribute_of_issue: Tarefa de %{name}
+  permission_add_documents: Adicionar documentos
+  permission_edit_documents: Editar documentos
+  permission_delete_documents: Apagar documentos
+  label_gantt_progress_line: Barra de progresso
+  setting_jsonp_enabled: Activar suporte JSONP
+  field_inherit_members: Herdar membros
+  field_closed_on: Fechado
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
diff -r 0a574315af3e -r 4f746d8966dd config/locales/ro.yml
--- a/config/locales/ro.yml
+++ b/config/locales/ro.yml
@@ -10,10 +10,8 @@
     day_names: [DuminicÄƒ, Luni, Marti, Miercuri, Joi, Vineri, SÃ¢mbÄƒtÄƒ]
     abbr_day_names: [Dum, Lun, Mar, Mie, Joi, Vin, SÃ¢m]
 
-    # Don't forget the nil at the beginning; there's no such thing as a 0th month
     month_names: [~, Ianuarie, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie]
     abbr_month_names: [~, Ian, Feb, Mar, Apr, Mai, Iun, Iul, Aug, Sep, Oct, Noi, Dec]
-    # Used in date_select and datime_select.
     order:
       - :day
       - :month
@@ -47,8 +45,8 @@
         one:   "aproximativ o orÄƒ"
         other: "aproximativ %{count} ore"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 orÄƒ"
+        other: "%{count} ore"
       x_days:
         one:   "o zi"
         other: "%{count} zile"
@@ -184,8 +182,6 @@
   mail_subject_reminder: "%{count} tichete trebuie rezolvate Ã®n urmÄƒtoarele %{days} zile"
   mail_body_reminder: "%{count} tichete atribuite dumneavoastrÄƒ trebuie rezolvate Ã®n urmÄƒtoarele %{days} zile:"
 
-  gui_validation_error: o eroare
-  gui_validation_error_plural: "%{count} erori"
 
   field_name: Nume
   field_description: Descriere
@@ -342,7 +338,6 @@
   permission_edit_own_time_entries: EditeazÄƒ jurnalele proprii cu timpul de lucru
   permission_manage_news: EditeazÄƒ È™tiri
   permission_comment_news: ComenteazÄƒ È™tirile
-  permission_manage_documents: EditeazÄƒ documente
   permission_view_documents: AfiÈ™eazÄƒ documente
   permission_manage_files: EditeazÄƒ fiÈ™iere
   permission_view_files: AfiÈ™eazÄƒ fiÈ™iere
@@ -461,8 +456,6 @@
   label_text: Text lung
   label_attribute: Atribut
   label_attribute_plural: Atribute
-  label_download: "%{count} descÄƒrcare"
-  label_download_plural: "%{count} descÄƒrcÄƒri"
   label_no_data: Nu existÄƒ date de afiÈ™at
   label_change_status: SchimbÄƒ starea
   label_history: Istoric
@@ -562,8 +555,6 @@
   label_repository: Depozit
   label_repository_plural: Depozite
   label_browse: AfiÈ™eazÄƒ
-  label_modification: "%{count} schimbare"
-  label_modification_plural: "%{count} schimbÄƒri"
   label_revision: Revizie
   label_revision_plural: Revizii
   label_associated_revisions: Revizii asociate
@@ -930,7 +921,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -971,8 +961,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1079,3 +1067,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/ru.yml
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -117,8 +117,10 @@
         many:  "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
         other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
       x_hours:
-        one:   "1 Ñ‡Ð°Ñ"
-        other: "%{count} Ñ‡Ð°ÑÐ¾Ð²"
+        one:   "%{count} Ñ‡Ð°Ñ"
+        few:   "%{count} Ñ‡Ð°ÑÐ°"
+        many:  "%{count} Ñ‡Ð°ÑÐ¾Ð²"
+        other: "%{count} Ñ‡Ð°ÑÐ°"
       x_days:
         one:   "%{count} Ð´ÐµÐ½ÑŒ"
         few:   "%{count} Ð´Ð½Ñ"
@@ -145,7 +147,7 @@
         many:  "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð»ÐµÑ‚"
         other: "Ð±Ð¾Ð»ÑŒÑˆÐµ %{count} Ð»ÐµÑ‚"
       almost_x_years:
-        one:   "Ð¿Ð¾Ñ‡Ñ‚Ð¸ 1 Ð³Ð¾Ð´"
+        one:   "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´"
         few:   "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´Ð°"
         many:  "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð»ÐµÑ‚"
         other: "Ð¿Ð¾Ñ‡Ñ‚Ð¸ %{count} Ð³Ð¾Ð´Ð°"
@@ -399,11 +401,6 @@
   general_text_yes: 'Ð´Ð°'
   general_text_Yes: 'Ð”Ð°'
 
-  gui_validation_error: 1 Ð¾ÑˆÐ¸Ð±ÐºÐ°
-  gui_validation_error_plural: "%{count} Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
-  gui_validation_error_plural2: "%{count} Ð¾ÑˆÐ¸Ð±ÐºÐ¸"
-  gui_validation_error_plural5: "%{count} Ð¾ÑˆÐ¸Ð±Ð¾Ðº"
-
   label_activity: Ð”ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ
   label_add_another_file: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ ÐµÑ‰Ñ‘ Ð¾Ð´Ð¸Ð½ Ñ„Ð°Ð¹Ð»
   label_added_time_by: "Ð”Ð¾Ð±Ð°Ð²Ð¸Ð»(Ð°) %{author} %{age} Ð½Ð°Ð·Ð°Ð´"
@@ -490,10 +487,6 @@
   label_document_added: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
   label_document_new: ÐÐ¾Ð²Ñ‹Ð¹ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚
   label_document_plural: Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
-  label_download: "%{count} Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ°"
-  label_download_plural: "%{count} ÑÐºÐ°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ð¹"
-  label_download_plural2: "%{count} Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸"
-  label_download_plural5: "%{count} Ð·Ð°Ð³Ñ€ÑƒÐ·Ð¾Ðº"
   label_downloads_abbr: Ð¡ÐºÐ°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ð¹
   label_duplicated_by: Ð´ÑƒÐ±Ð»Ð¸Ñ€ÑƒÐµÑ‚ÑÑ
   label_duplicates: Ð´ÑƒÐ±Ð»Ð¸Ñ€ÑƒÐµÑ‚
@@ -576,10 +569,6 @@
   label_message_posted: Ð”Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¾ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ðµ
   label_me: Ð¼Ð½Ðµ
   label_min_max_length: ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ - Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°
-  label_modification: "%{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ"
-  label_modification_plural: "%{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹"
-  label_modification_plural2: "%{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ"
-  label_modification_plural5: "%{count} Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹"
   label_modified: Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¾
   label_module_plural: ÐœÐ¾Ð´ÑƒÐ»Ð¸
   label_months_from: Ð¼ÐµÑÑÑ†ÐµÐ²(Ñ†Ð°) Ñ
@@ -825,7 +814,6 @@
   permission_manage_project_activities: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ‚Ð¸Ð¿Ð°Ð¼Ð¸ Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ð¹ Ð´Ð»Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°
   permission_manage_boards: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ„Ð¾Ñ€ÑƒÐ¼Ð°Ð¼Ð¸
   permission_manage_categories: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸ÑÐ¼Ð¸ Ð·Ð°Ð´Ð°Ñ‡
-  permission_manage_documents: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ð¼Ð¸
   permission_manage_files: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸
   permission_manage_issue_relations: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑÐ²ÑÐ·Ñ‹Ð²Ð°Ð½Ð¸ÐµÐ¼ Ð·Ð°Ð´Ð°Ñ‡
   permission_manage_members: Ð£Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ°Ð¼Ð¸
@@ -1123,11 +1111,10 @@
   error_attachment_too_big: Ð­Ñ‚Ð¾Ñ‚ Ñ„Ð°Ð¹Ð» Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ Ð¸Ð·-Ð·Ð° Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° Ñ„Ð°Ð¹Ð»Ð° (%{max_size})
   notice_failed_to_save_time_entries: "ÐÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ ÑÐ¾Ñ…Ñ€Ð°Ð½Ð¸Ñ‚ÑŒ %{count} Ð·Ð°Ñ‚Ñ€Ð°Ñ‡ÐµÐ½Ð½Ð¾Ðµ Ð²Ñ€ÐµÐ¼Ñ Ð´Ð»Ñ %{total} Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ…: %{ids}."
   label_x_issues:
-    zero:  0 Ð—Ð°Ð´Ð°Ñ‡
-    one:   1 Ð—Ð°Ð´Ð°Ñ‡Ð°
-    few:   "%{count} Ð—Ð°Ð´Ð°Ñ‡"
-    many:  "%{count} Ð—Ð°Ð´Ð°Ñ‡"
-    other: "%{count} Ð—Ð°Ð´Ð°Ñ‡"
+    one:   "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð°"
+    few:   "%{count} Ð·Ð°Ð´Ð°Ñ‡Ð¸"
+    many:  "%{count} Ð·Ð°Ð´Ð°Ñ‡"
+    other: "%{count} Ð—Ð°Ð´Ð°Ñ‡Ð¸"
   label_repository_new: ÐÐ¾Ð²Ð¾Ðµ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ
   field_repository_is_default: Ð¥Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰Ðµ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ
   label_copy_attachments: ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ
@@ -1185,13 +1172,29 @@
   permission_set_notes_private: Ð Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ðµ Ð¿Ñ€Ð¸Ð²Ð°Ñ‚Ð½Ñ‹Ñ… ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÐµÐ²
   label_no_issues_in_project: Ð½ÐµÑ‚ Ð·Ð°Ð´Ð°Ñ‡ Ð² Ð¿Ñ€Ð¾ÐµÐºÑ‚Ðµ
   label_any: Ð²ÑÐµ
-  label_last_n_weeks: Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ %{count} Ð½ÐµÐ´ÐµÐ»ÑŒ
+  label_last_n_weeks:
+    one:   "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½ÑÑ %{count} Ð½ÐµÐ´ÐµÐ»Ñ"
+    few:   "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ %{count} Ð½ÐµÐ´ÐµÐ»Ð¸"
+    many:  "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ %{count} Ð½ÐµÐ´ÐµÐ»ÑŒ"
+    other: "Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ðµ %{count} Ð½ÐµÐ´ÐµÐ»Ð¸"
   setting_cross_project_subtasks: Ð Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð¿Ð¾Ð´Ð·Ð°Ð´Ð°Ñ‡Ð¸ Ð² Ð¼ÐµÐ¶Ð´Ñƒ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
   label_cross_project_descendants: Ð¡ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
   label_cross_project_tree: Ð¡ Ð´ÐµÑ€ÐµÐ²Ð¾Ð¼ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
   label_cross_project_hierarchy: Ð¡ Ð¸ÐµÑ€Ð°Ñ€Ñ…Ð¸ÐµÐ¹ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
   label_cross_project_system: Ð¡Ð¾ Ð²ÑÐµÐ¼Ð¸ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸
   button_hide: Ð¡ÐºÑ€Ñ‹Ñ‚ÑŒ
-  setting_non_working_week_days: ÐÐµ Ñ€Ð°Ð±Ð¾Ñ‡Ð¸Ðµ Ð´Ð½Ð¸
+  setting_non_working_week_days: ÐÐµÑ€Ð°Ð±Ð¾Ñ‡Ð¸Ðµ Ð´Ð½Ð¸
   label_in_the_next_days: Ð² ÑÑ€ÐµÐ´ÑƒÑŽÑ‰Ð¸Ðµ Ð´Ð½Ð¸
   label_in_the_past_days: Ð² Ð¿Ñ€Ð¾ÑˆÐ»Ñ‹Ðµ Ð´Ð½Ð¸
+  label_attribute_of_user: ÐŸÐ¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ %{name}
+  text_turning_multiple_off: Ð•ÑÐ»Ð¸ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ð¼Ð½Ð¾Ð¶ÐµÑÑ‚Ð²ÐµÐ½Ð½Ñ‹Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ, Ð»Ð¸ÑˆÐ½Ð¸Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ð· ÑÐ¿Ð¸ÑÐºÐ° Ð±ÑƒÐ´ÑƒÑ‚ ÑƒÐ´Ð°Ð»ÐµÐ½Ñ‹, Ñ‡Ñ‚Ð¾Ð±Ñ‹ Ð¾ÑÑ‚Ð°Ð»Ð¾ÑÑŒ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð¿Ð¾ Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÑŽ.
+  label_attribute_of_issue: Ð—Ð°Ð´Ð°Ñ‡Ð° %{name}
+  permission_add_documents: Ð”Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
+  permission_edit_documents: Ð ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
+  permission_delete_documents: Ð£Ð´Ð°Ð»Ð¸Ñ‚ÑŒ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ñ‹
+  label_gantt_progress_line: Ð›Ð¸Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ð³Ñ€ÐµÑÑÐ°
+  setting_jsonp_enabled: ÐŸÐ¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ° JSONP
+  field_inherit_members: ÐÐ°ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÑŒ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ¾Ð²
+  field_closed_on: Ð—Ð°ÐºÑ€Ñ‹Ñ‚Ð°
+  setting_default_projects_tracker_ids: Ð¢Ñ€ÐµÐºÐµÑ€Ñ‹ Ð¿Ð¾ ÑƒÐ¼Ð¾Ð»Ñ‡Ð°Ð½Ð¸ÑŽ Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²
+  label_total_time: ÐžÐ±Ñ‰ÐµÐµ Ð²Ñ€ÐµÐ¼Ñ
diff -r 0a574315af3e -r 4f746d8966dd config/locales/sk.yml
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -2,9 +2,6 @@
   direction: ltr
   date:
     formats:
-      # Use the strftime parameters for formats.
-      # When no format has been given, it uses default.
-      # You can provide other formats here if you like!
       default: "%Y-%m-%d"
       short: "%b %d"
       long: "%B %d, %Y"
@@ -49,8 +46,8 @@
         one:   "okolo 1 hodiny"
         other: "okolo %{count} hodÃ­n"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 hodina"
+        other: "%{count} hodÃ­n"
       x_days:
         one:   "1 deÅˆ"
         other: "%{count} dnÃ­"
@@ -183,8 +180,6 @@
   mail_subject_account_activation_request: "AktivÃ¡cia %{value} ÃºÄtu"
   mail_body_account_activation_request: "Bol zaregistrovanÃ½ novÃ½ uÅ¾ivateÄ¾ %{value}. AktivÃ¡cia jeho ÃºÄtu zÃ¡visÃ­ na vaÅ¡om potvrdenÃ­."
 
-  gui_validation_error: 1 chyba
-  gui_validation_error_plural: "%{count} chyb(y)"
 
   field_name: NÃ¡zov
   field_description: Popis
@@ -394,8 +389,6 @@
   label_text: DlhÃ½ text
   label_attribute: Atribut
   label_attribute_plural: Atributy
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloady"
   label_no_data: Å½iadnÃ© poloÅ¾ky
   label_change_status: ZmeniÅ¥ stav
   label_history: HistÃ³ria
@@ -495,8 +488,6 @@
   label_repository: RepozitÃ¡r
   label_repository_plural: RepozitÃ¡re
   label_browse: PrechÃ¡dzaÅ¥
-  label_modification: "%{count} zmena"
-  label_modification_plural: "%{count} zmien"
   label_revision: RevÃ­zia
   label_revision_plural: RevÃ­ziÃ­
   label_associated_revisions: SÃºvisiace verzie
@@ -758,7 +749,6 @@
   permission_comment_news: Komentovanie noviniek
   permission_delete_messages: Mazanie sprÃ¡v
   permission_select_project_modules: VoÄ¾ba projektovÃ½ch modulov
-  permission_manage_documents: SprÃ¡va dokumentov
   permission_edit_wiki_pages: Ãšprava Wiki strÃ¡niek
   permission_add_issue_watchers: Pridanie pozorovateÄ¾ov
   permission_view_gantt: Zobrazenie Ganttovho diagramu
@@ -933,7 +923,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -974,8 +963,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1082,3 +1069,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Celkovo
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/sl.yml
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -50,8 +50,8 @@
         one:   "okrog 1. ure"
         other: "okrog %{count} ur"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 ura"
+        other: "%{count} ur"
       x_days:
         one:   "1 dan"
         other: "%{count} dni"
@@ -184,8 +184,6 @@
   mail_subject_reminder: "%{count} zahtevek(zahtevki) zapadejo v naslednjih %{days} dneh"
   mail_body_reminder: "%{count} zahtevek(zahtevki), ki so vam dodeljeni bodo zapadli v naslednjih %{days} dneh:"
 
-  gui_validation_error: 1 napaka
-  gui_validation_error_plural: "%{count} napak"
 
   field_name: Ime
   field_description: Opis
@@ -335,7 +333,6 @@
   permission_edit_own_time_entries: Uredi beleÅ¾ko lastnega Äasa
   permission_manage_news: Uredi novice
   permission_comment_news: Komentiraj novice
-  permission_manage_documents: Uredi dokumente
   permission_view_documents: Poglej dokumente
   permission_manage_files: Uredi datoteke
   permission_view_files: Poglej datoteke
@@ -453,8 +450,6 @@
   label_text: Dolgo besedilo
   label_attribute: Lastnost
   label_attribute_plural: Lastnosti
-  label_download: "%{count} Prenos"
-  label_download_plural: "%{count} Prenosi"
   label_no_data: Ni podatkov za prikaz
   label_change_status: Spremeni stanje
   label_history: Zgodovina
@@ -554,8 +549,6 @@
   label_repository: Shramba
   label_repository_plural: Shrambe
   label_browse: Prebrskaj
-  label_modification: "%{count} sprememba"
-  label_modification_plural: "%{count} spremembe"
   label_revision: Revizija
   label_revision_plural: Revizije
   label_associated_revisions: Povezane revizije
@@ -1082,3 +1075,16 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Skupaj
diff -r 0a574315af3e -r 4f746d8966dd config/locales/sq.yml
--- a/config/locales/sq.yml
+++ b/config/locales/sq.yml
@@ -50,8 +50,8 @@
         one:   "about 1 hour"
         other: "about %{count} hours"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 ore"
+        other: "%{count} ore"
       x_days:
         one:   "1 day"
         other: "%{count} days"
@@ -214,8 +214,6 @@
   mail_subject_wiki_content_updated: "'%{id}' wiki page eshte modifikuar"
   mail_body_wiki_content_updated: "The '%{id}' wiki page eshte modifikuar nga %{author}."
 
-  gui_validation_error: 1 error
-  gui_validation_error_plural: "%{count} gabime"
 
   field_name: Emri
   field_description: Pershkrimi
@@ -353,8 +351,6 @@
   setting_cross_project_issue_relations: Allow cross-project issue relations
   setting_issue_list_default_columns: Default columns displayed on the issue list
   setting_repositories_encodings: Attachments and repositories encodings
-  setting_emails_header: Emails header
-  setting_emails_footer: Emails footer
   setting_protocol: Protocol
   setting_per_page_options: Objects per page options
   setting_user_format: Users display format
@@ -421,7 +417,6 @@
   permission_edit_own_time_entries: Edit own time logs
   permission_manage_news: Manage news
   permission_comment_news: Comment news
-  permission_manage_documents: Manage documents
   permission_view_documents: View documents
   permission_manage_files: Manage files
   permission_view_files: View files
@@ -552,8 +547,6 @@
   label_text: Long text
   label_attribute: Attribute
   label_attribute_plural: Attributes
-  label_download: "%{count} Download"
-  label_download_plural: "%{count} Downloads"
   label_no_data: No data to display
   label_change_status: Change status
   label_history: Histori
@@ -664,8 +657,6 @@
   label_repository_new: New repository
   label_repository_plural: Repositories
   label_browse: Browse
-  label_modification: "%{count} ndryshim"
-  label_modification_plural: "%{count} ndryshime"
   label_branch: Dege
   label_tag: Tag
   label_revision: Revizion
@@ -978,8 +969,6 @@
   text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
   text_scm_command: Command
   text_scm_command_version: Version
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   text_issue_conflict_resolution_overwrite: "Apply my changes anyway (previous notes will be kept but some changes may be overwritten)"
   text_issue_conflict_resolution_add_notes: "Add my notes and discard my other changes"
   text_issue_conflict_resolution_cancel: "Discard all my changes and redisplay %{link}"
@@ -1077,3 +1066,20 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Total
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_footer: Email footer
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/sr-YU.yml
--- a/config/locales/sr-YU.yml
+++ b/config/locales/sr-YU.yml
@@ -53,8 +53,8 @@
         one:   "pribliÅ¾no jedan sat"
         other: "pribliÅ¾no %{count} sati"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 sat"
+        other: "%{count} sati"
       x_days:
         one:   "jedan dan"
         other: "%{count} dana"
@@ -209,8 +209,6 @@
   mail_subject_wiki_content_updated: "Wiki stranica '%{id}' je aÅ¾urirana"
   mail_body_wiki_content_updated: "%{author} je aÅ¾urirao wiki stranicu '%{id}'."
 
-  gui_validation_error: jedna greÅ¡ka
-  gui_validation_error_plural: "%{count} greÅ¡aka"
 
   field_name: Naziv
   field_description: Opis
@@ -290,7 +288,7 @@
   field_delay: KaÅ¡njenje
   field_assignable: Problem moÅ¾e biti dodeljen ovoj ulozi
   field_redirect_existing_links: Preusmeri postojeÄ‡e veze
-  field_estimated_hours: Proteklo vreme
+  field_estimated_hours: Procenjeno vreme 
   field_column_names: Kolone
   field_time_zone: Vremenska zona
   field_searchable: MoÅ¾e da se pretraÅ¾uje
@@ -387,7 +385,6 @@
   permission_edit_own_time_entries: Izmena sopstvenog utroÅ¡enog vremena
   permission_manage_news: Upravljanje vestima
   permission_comment_news: Komentarisanje vesti
-  permission_manage_documents: Upravljanje dokumentima
   permission_view_documents: Pregledanje dokumenata
   permission_manage_files: Upravljanje datotekama
   permission_view_files: Pregledanje datoteka
@@ -511,8 +508,6 @@
   label_text: Dugi tekst
   label_attribute: Osobina
   label_attribute_plural: Osobine
-  label_download: "%{count} preuzimanje"
-  label_download_plural: "%{count} preuzimanja"
   label_no_data: Nema podataka za prikazivanje
   label_change_status: Promena statusa
   label_history: Istorija
@@ -615,8 +610,6 @@
   label_repository: SpremiÅ¡te
   label_repository_plural: SpremiÅ¡ta
   label_browse: Pregledanje
-  label_modification: "%{count} promena"
-  label_modification_plural: "%{count} promena"
   label_branch: Grana
   label_tag: Oznaka
   label_revision: Revizija
@@ -976,8 +969,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1084,3 +1075,18 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ukupno
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd config/locales/sr.yml
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -51,8 +51,8 @@
         one:   "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ Ñ˜ÐµÐ´Ð°Ð½ ÑÐ°Ñ‚"
         other: "Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð½Ð¾ %{count} ÑÐ°Ñ‚Ð¸"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 ÑÐ°Ñ‚"
+        other: "%{count} ÑÐ°Ñ‚Ð¸"
       x_days:
         one:   "Ñ˜ÐµÐ´Ð°Ð½ Ð´Ð°Ð½"
         other: "%{count} Ð´Ð°Ð½Ð°"
@@ -207,8 +207,6 @@
   mail_subject_wiki_content_updated: "Wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð° '%{id}' Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð½Ð°"
   mail_body_wiki_content_updated: "%{author} Ñ˜Ðµ Ð°Ð¶ÑƒÑ€Ð¸Ñ€Ð°Ð¾ wiki ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ñƒ '%{id}'."
 
-  gui_validation_error: Ñ˜ÐµÐ´Ð½Ð° Ð³Ñ€ÐµÑˆÐºÐ°
-  gui_validation_error_plural: "%{count} Ð³Ñ€ÐµÑˆÐ°ÐºÐ°"
 
   field_name: ÐÐ°Ð·Ð¸Ð²
   field_description: ÐžÐ¿Ð¸Ñ
@@ -385,7 +383,6 @@
   permission_edit_own_time_entries: Ð˜Ð·Ð¼ÐµÐ½Ð° ÑÐ¾Ð¿ÑÑ‚Ð²ÐµÐ½Ð¾Ð³ ÑƒÑ‚Ñ€Ð¾ÑˆÐµÐ½Ð¾Ð³ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð°
   permission_manage_news: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð²ÐµÑÑ‚Ð¸Ð¼Ð°
   permission_comment_news: ÐšÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸ÑÐ°ÑšÐµ Ð²ÐµÑÑ‚Ð¸
-  permission_manage_documents: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð¸Ð¼Ð°
   permission_view_documents: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ð°Ñ‚Ð°
   permission_manage_files: Ð£Ð¿Ñ€Ð°Ð²Ñ™Ð°ÑšÐµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°Ð¼Ð°
   permission_view_files: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐ°
@@ -509,8 +506,6 @@
   label_text: Ð”ÑƒÐ³Ð¸ Ñ‚ÐµÐºÑÑ‚
   label_attribute: ÐžÑÐ¾Ð±Ð¸Ð½Ð°
   label_attribute_plural: ÐžÑÐ¾Ð±Ð¸Ð½Ðµ
-  label_download: "%{count} Ð¿Ñ€ÐµÑƒÐ·Ð¸Ð¼Ð°ÑšÐµ"
-  label_download_plural: "%{count} Ð¿Ñ€ÐµÑƒÐ·Ð¸Ð¼Ð°ÑšÐ°"
   label_no_data: ÐÐµÐ¼Ð° Ð¿Ð¾Ð´Ð°Ñ‚Ð°ÐºÐ° Ð·Ð° Ð¿Ñ€Ð¸ÐºÐ°Ð·Ð¸Ð²Ð°ÑšÐµ
   label_change_status: ÐŸÑ€Ð¾Ð¼ÐµÐ½Ð° ÑÑ‚Ð°Ñ‚ÑƒÑÐ°
   label_history: Ð˜ÑÑ‚Ð¾Ñ€Ð¸Ñ˜Ð°
@@ -613,8 +608,6 @@
   label_repository: Ð¡Ð¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ðµ
   label_repository_plural: Ð¡Ð¿Ñ€ÐµÐ¼Ð¸ÑˆÑ‚Ð°
   label_browse: ÐŸÑ€ÐµÐ³Ð»ÐµÐ´Ð°ÑšÐµ
-  label_modification: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°"
-  label_modification_plural: "%{count} Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ð°"
   label_branch: Ð“Ñ€Ð°Ð½Ð°
   label_tag: ÐžÐ·Ð½Ð°ÐºÐ°
   label_revision: Ð ÐµÐ²Ð¸Ð·Ð¸Ñ˜Ð°
@@ -934,7 +927,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -975,8 +967,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1083,3 +1073,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ð£ÐºÑƒÐ¿Ð½Ð¾
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/sv.yml
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -215,10 +215,10 @@
   notice_unable_delete_version: Denna version var inte mÃ¶jlig att ta bort.
   notice_unable_delete_time_entry: Tidloggning kunde inte tas bort.
   notice_issue_done_ratios_updated: "% klart uppdaterade."
-  notice_gantt_chart_truncated: "Schemat fÃ¶rminskades eftersom det Ã¶verskrider det maximala antalet aktiviteter som fÃ¥r visas (%{max})"
-  notice_issue_successful_create: Ã„rende %{id} skapades.
-  notice_issue_update_conflict: Detta Ã¤rende har uppdaterats av en annan anvÃ¤ndare samtidigt som du redigerade det.
-  notice_account_deleted: Ditt konto har avslutats permanent.
+  notice_gantt_chart_truncated: "Schemat fÃ¶rminskades eftersom det Ã¶verskrider det maximala antalet aktiviteter som kan visas (%{max})"
+  notice_issue_successful_create: "Ã„rende %{id} skapades."
+  notice_issue_update_conflict: "Detta Ã¤rende har uppdaterats av en annan anvÃ¤ndare samtidigt som du redigerade det."
+  notice_account_deleted: "Ditt konto har avslutats permanent."
   notice_user_successful_create: "AnvÃ¤ndare %{id} skapad."
 
   error_can_t_load_default_data: "Standardkonfiguration gick inte att lÃ¤sa in: %{value}"
@@ -239,7 +239,7 @@
   error_workflow_copy_target: 'VÃ¤nligen vÃ¤lj Ã¤rendetyp(er) och roll(er) fÃ¶r mÃ¥l'
   error_unable_delete_issue_status: 'Ã„rendestatus kunde inte tas bort'
   error_unable_to_connect: "Kan inte ansluta (%{value})"
-  error_attachment_too_big: Denna fil kan inte laddas upp eftersom den Ã¶verstiger maximalt tillÃ¥ten filstorlek (%{max_size})
+  error_attachment_too_big: "Denna fil kan inte laddas upp eftersom den Ã¶verstiger maximalt tillÃ¥ten filstorlek (%{max_size})"
   error_session_expired: "Din session har gÃ¥tt ut. VÃ¤nligen logga in pÃ¥ nytt."
   warning_attachments_not_saved: "%{count} fil(er) kunde inte sparas."
 
@@ -258,8 +258,6 @@
   mail_subject_wiki_content_updated: "'%{id}' wikisida har uppdaterats"
   mail_body_wiki_content_updated: "The '%{id}' wikisida har uppdaterats av %{author}."
 
-  gui_validation_error: 1 fel
-  gui_validation_error_plural: "%{count} fel"
 
   field_name: Namn
   field_description: Beskrivning
@@ -274,6 +272,7 @@
   field_author: FÃ¶rfattare
   field_created_on: Skapad
   field_updated_on: Uppdaterad
+  field_closed_on: StÃ¤ngd
   field_field_format: Format
   field_is_for_all: FÃ¶r alla projekt
   field_possible_values: MÃ¶jliga vÃ¤rden
@@ -374,6 +373,7 @@
   field_timeout: "Timeout (i sekunder)"
   field_board_parent: FÃ¶rÃ¤lderforum
   field_private_notes: Privata anteckningar
+  field_inherit_members: Ã„rv medlemmar
 
   setting_app_title: Applikationsrubrik
   setting_app_subtitle: Applikationsunderrubrik
@@ -442,6 +442,8 @@
   setting_thumbnails_enabled: Visa miniatyrbilder av bilagor
   setting_thumbnails_size: Storlek pÃ¥ miniatyrbilder (i pixlar)
   setting_non_working_week_days: Lediga dagar
+  setting_jsonp_enabled: Aktivera JSONP-stÃ¶d
+  setting_default_projects_tracker_ids: StandardÃ¤rendetyper fÃ¶r nya projekt
 
   permission_add_project: Skapa projekt
   permission_add_subprojects: Skapa underprojekt
@@ -458,9 +460,9 @@
   permission_manage_issue_relations: Hantera Ã¤renderelationer
   permission_set_issues_private: SÃ¤tta Ã¤renden publika eller privata
   permission_set_own_issues_private: SÃ¤tta egna Ã¤renden publika eller privata
-  permission_add_issue_notes: LÃ¤gga till Ã¤rendenotering
-  permission_edit_issue_notes: Ã„ndra Ã¤rendenoteringar
-  permission_edit_own_issue_notes: Ã„ndra egna Ã¤rendenoteringar
+  permission_add_issue_notes: LÃ¤gga till Ã¤rendeanteckning
+  permission_edit_issue_notes: Ã„ndra Ã¤rendeanteckningar
+  permission_edit_own_issue_notes: Ã„ndra egna Ã¤rendeanteckningar
   permission_view_private_notes: Visa privata anteckningar
   permission_set_notes_private: StÃ¤lla in anteckningar som privata
   permission_move_issues: Flytta Ã¤renden
@@ -478,8 +480,10 @@
   permission_edit_own_time_entries: Ã„ndra egna tidloggningar
   permission_manage_news: Hantera nyheter
   permission_comment_news: Kommentera nyheter
-  permission_manage_documents: Hantera dokument
   permission_view_documents: Visa dokument
+  permission_add_documents: LÃ¤gga till dokument
+  permission_edit_documents: Ã„ndra dokument
+  permission_delete_documents: Ta bort dokument
   permission_manage_files: Hantera filer
   permission_view_files: Visa filer
   permission_manage_wiki: Hantera wiki
@@ -610,8 +614,6 @@
   label_text: LÃ¥ng text
   label_attribute: Attribut
   label_attribute_plural: Attribut
-  label_download: "%{count} Nerladdning"
-  label_download_plural: "%{count} Nerladdningar"
   label_no_data: Ingen data att visa
   label_change_status: Ã„ndra status
   label_history: Historia
@@ -660,11 +662,13 @@
     one:   1 Ã¤rende
     other: "%{count} Ã¤renden"
   label_total: Total
+  label_total_time: Total tid
   label_permissions: BehÃ¶righeter
   label_current_status: Nuvarande status
   label_new_statuses_allowed: Nya tillÃ¥tna statusvÃ¤rden
   label_all: alla
-  label_none: ingen
+  label_any: vad/vem som helst
+  label_none: inget/ingen
   label_nobody: ingen
   label_next: NÃ¤sta
   label_previous: FÃ¶regÃ¥ende
@@ -728,8 +732,6 @@
   label_repository_new: Nytt versionsarkiv
   label_repository_plural: Versionsarkiv
   label_browse: BlÃ¤ddra
-  label_modification: "%{count} Ã¤ndring"
-  label_modification_plural: "%{count} Ã¤ndringar"
   label_branch: Branch
   label_tag: Tag
   label_revision: Revision
@@ -791,13 +793,13 @@
   label_loading: Laddar...
   label_relation_new: Ny relation
   label_relation_delete: Ta bort relation
-  label_relates_to: relaterar till
-  label_duplicates: kopierar
-  label_duplicated_by: kopierad av
-  label_blocks: blockerar
-  label_blocked_by: blockerad av
-  label_precedes: kommer fÃ¶re
-  label_follows: fÃ¶ljer
+  label_relates_to: Relaterar till
+  label_duplicates: Kopierar
+  label_duplicated_by: Kopierad av
+  label_blocks: Blockerar
+  label_blocked_by: Blockerad av
+  label_precedes: Kommer fÃ¶re
+  label_follows: FÃ¶ljer
   label_copied_to: Kopierad till
   label_copied_from: Kopierad frÃ¥n
   label_end_to_start: slut till start
@@ -924,9 +926,16 @@
   label_readonly: Skrivskyddad
   label_required: NÃ¶dvÃ¤ndig
   label_attribute_of_project: Projektets %{name}
+  label_attribute_of_issue: Ã„rendets %{name}
   label_attribute_of_author: FÃ¶rfattarens %{name}
-  label_attribute_of_assigned_to: Tilldelads %{name}
+  label_attribute_of_assigned_to: Tilldelad anvÃ¤ndares %{name}
+  label_attribute_of_user: AnvÃ¤ndarens %{name}
   label_attribute_of_fixed_version: MÃ¥lversionens %{name}
+  label_cross_project_descendants: Med underprojekt
+  label_cross_project_tree: Med projekttrÃ¤d
+  label_cross_project_hierarchy: Med projekthierarki
+  label_cross_project_system: Med alla projekt
+  label_gantt_progress_line: Framstegslinje
 
   button_login: Logga in
   button_submit: Skicka
@@ -1010,7 +1019,7 @@
   text_tip_issue_begin_day: Ã¤rende som bÃ¶rjar denna dag
   text_tip_issue_end_day: Ã¤rende som slutar denna dag
   text_tip_issue_begin_end_day: Ã¤rende som bÃ¶rjar och slutar denna dag
-  text_project_identifier_info: Ã„ndast gemener (a-z), siffror, streck och understreck Ã¤r tillÃ¥tna.<br />NÃ¤r identifieraren sparats kan den inte Ã¤ndras.
+  text_project_identifier_info: 'Endast gemener (a-z), siffror, streck och understreck Ã¤r tillÃ¥tna, mÃ¥ste bÃ¶rja med en bokstav.<br />NÃ¤r identifieraren sparats kan den inte Ã¤ndras.'
   text_caracters_maximum: "max %{count} tecken."
   text_caracters_minimum: "MÃ¥ste vara minst %{count} tecken lÃ¥ng."
   text_length_between: "LÃ¤ngd mellan %{min} och %{max} tecken."
@@ -1056,7 +1065,7 @@
   text_own_membership_delete_confirmation: "NÃ¥gra av, eller alla, dina behÃ¶righeter kommer att tas bort och du kanske inte lÃ¤ngre kommer kunna gÃ¶ra Ã¤ndringar i det hÃ¤r projektet.\nVill du verkligen fortsÃ¤tta?"
   text_zoom_out: Zooma ut
   text_zoom_in: Zooma in
-  text_warn_on_leaving_unsaved: Nuvarande sida innehÃ¥ller osparad text som kommer fÃ¶rsvinna om du lÃ¤mnar sidan.
+  text_warn_on_leaving_unsaved: "Nuvarande sida innehÃ¥ller osparad text som kommer fÃ¶rsvinna om du lÃ¤mnar sidan."
   text_scm_path_encoding_note: "Standard: UTF-8"
   text_git_repository_note: Versionsarkiv Ã¤r tomt och lokalt (t.ex. /gitrepo, c:\gitrepo)
   text_mercurial_repository_note: Lokalt versionsarkiv (t.ex. /hgrepo, c:\hgrepo)
@@ -1064,12 +1073,13 @@
   text_scm_command_version: Version
   text_scm_config: Du kan konfigurera dina scm-kommando i config/configuration.yml. VÃ¤nligen starta om applikationen nÃ¤r Ã¤ndringar gjorts.
   text_scm_command_not_available: Scm-kommando Ã¤r inte tillgÃ¤ngligt. VÃ¤nligen kontrollera instÃ¤llningarna i administratÃ¶rspanelen.
-  text_issue_conflict_resolution_overwrite: AnvÃ¤nd mina Ã¤ndringar i alla fall (tidigare anteckningar kommer behÃ¥llas men nÃ¥gra Ã¤ndringar kan bli Ã¶verskrivna)
-  text_issue_conflict_resolution_add_notes: LÃ¤gg till mina anteckningar och kasta mina andra Ã¤ndringar
-  text_issue_conflict_resolution_cancel: Kasta alla mina Ã¤ndringar och visa igen %{link}
+  text_issue_conflict_resolution_overwrite: "AnvÃ¤nd mina Ã¤ndringar i alla fall (tidigare anteckningar kommer behÃ¥llas men nÃ¥gra Ã¤ndringar kan bli Ã¶verskrivna)"
+  text_issue_conflict_resolution_add_notes: "LÃ¤gg till mina anteckningar och kasta mina andra Ã¤ndringar"
+  text_issue_conflict_resolution_cancel: "Kasta alla mina Ã¤ndringar och visa igen %{link}"
   text_account_destroy_confirmation: "Ã„r du sÃ¤ker pÃ¥ att du vill fortsÃ¤tta?\nDitt konto kommer tas bort permanent, utan mÃ¶jlighet att Ã¥teraktivera det."
   text_session_expiration_settings: "Varning: Ã¤ndring av dessa instÃ¤llningar kan fÃ¥ alla nuvarande sessioner, inklusive din egen, att gÃ¥ ut."
   text_project_closed: Detta projekt Ã¤r stÃ¤ngt och skrivskyddat.
+  text_turning_multiple_off: "Om du inaktiverar mÃ¶jligheten till flera vÃ¤rden kommer endast ett vÃ¤rde per objekt behÃ¥llas."
 
   default_role_manager: Projektledare
   default_role_developer: Utvecklare
@@ -1115,9 +1125,4 @@
   description_date_range_interval: Ange intervall genom att vÃ¤lja start- och slutdatum
   description_date_from: Ange startdatum
   description_date_to: Ange slutdatum
-  text_repository_identifier_info: Ã„ndast gemener (a-z), siffror, streck och understreck Ã¤r tillÃ¥tna.<br />NÃ¤r identifieraren sparats kan den inte Ã¤ndras.
-  label_any: alla
-  label_cross_project_descendants: Med underprojekt
-  label_cross_project_tree: Med projekttrÃ¤d
-  label_cross_project_hierarchy: Med projekthierarki
-  label_cross_project_system: Med alla projekt
+  text_repository_identifier_info: 'Endast gemener (a-z), siffror, streck och understreck Ã¤r tillÃ¥tna.<br />NÃ¤r identifieraren sparats kan den inte Ã¤ndras.'
diff -r 0a574315af3e -r 4f746d8966dd config/locales/th.yml
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -180,8 +180,6 @@
   mail_subject_account_activation_request: "à¸à¸£à¸¸à¸“à¸²à¹€à¸›à¸´à¸”à¸šà¸±à¸à¸Šà¸µ %{value}"
   mail_body_account_activation_request: "à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰à¹ƒà¸«à¸¡à¹ˆ (%{value}) à¹„à¸”à¹‰à¸¥à¸‡à¸—à¸°à¹€à¸šà¸µà¸¢à¸™. à¸šà¸±à¸à¸Šà¸µà¸‚à¸­à¸‡à¹€à¸‚à¸²à¸à¸³à¸¥à¸±à¸‡à¸£à¸­à¸­à¸™à¸¸à¸¡à¸±à¸•à¸´:"
 
-  gui_validation_error: 1 à¸‚à¹‰à¸­à¸œà¸´à¸”à¸žà¸¥à¸²à¸”
-  gui_validation_error_plural: "%{count} à¸‚à¹‰à¸­à¸œà¸´à¸”à¸žà¸¥à¸²à¸”"
 
   field_name: à¸Šà¸·à¹ˆà¸­
   field_description: à¸£à¸²à¸¢à¸¥à¸°à¹€à¸­à¸µà¸¢à¸”
@@ -392,8 +390,6 @@
   label_text: à¸‚à¹‰à¸­à¸„à¸§à¸²à¸¡à¸‚à¸™à¸²à¸”à¸¢à¸²à¸§
   label_attribute: à¸„à¸¸à¸“à¸¥à¸±à¸à¸©à¸“à¸°
   label_attribute_plural: à¸„à¸¸à¸“à¸¥à¸±à¸à¸©à¸“à¸°
-  label_download: "%{count} à¸”à¸²à¸§à¸™à¹Œà¹‚à¸«à¸¥à¸”"
-  label_download_plural: "%{count} à¸”à¸²à¸§à¸™à¹Œà¹‚à¸«à¸¥à¸”"
   label_no_data: à¸ˆà¸³à¸™à¸§à¸™à¸‚à¹‰à¸­à¸¡à¸¹à¸¥à¸—à¸µà¹ˆà¹à¸ªà¸”à¸‡
   label_change_status: à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¸ªà¸–à¸²à¸™à¸°
   label_history: à¸›à¸£à¸°à¸§à¸±à¸•à¸´
@@ -493,8 +489,6 @@
   label_repository: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
   label_repository_plural: à¸—à¸µà¹ˆà¹€à¸à¹‡à¸šà¸•à¹‰à¸™à¸‰à¸šà¸±à¸š
   label_browse: à¹€à¸›à¸´à¸”à¸«à¸²
-  label_modification: "%{count} à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡"
-  label_modification_plural: "%{count} à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡"
   label_revision: à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚
   label_revision_plural: à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚
   label_associated_revisions: à¸à¸²à¸£à¹à¸à¹‰à¹„à¸‚à¸—à¸µà¹ˆà¹€à¸à¸µà¹ˆà¸¢à¸§à¸‚à¹‰à¸­à¸‡
@@ -755,7 +749,6 @@
   permission_comment_news: Comment news
   permission_delete_messages: Delete messages
   permission_select_project_modules: Select project modules
-  permission_manage_documents: Manage documents
   permission_edit_wiki_pages: Edit wiki pages
   permission_add_issue_watchers: Add watchers
   permission_view_gantt: View gantt chart
@@ -930,7 +923,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -971,8 +963,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1079,3 +1069,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: à¸ˆà¸³à¸™à¸§à¸™à¸£à¸§à¸¡
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/tr.yml
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -56,8 +56,8 @@
         one: 'yaklaÅŸÄ±k 1 saat'
         other: 'yaklaÅŸÄ±k %{count} saat'
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 saat"
+        other: "%{count} saat"
       x_days:
         one: '1 gÃ¼n'
         other: '%{count} gÃ¼n'
@@ -204,8 +204,6 @@
   mail_subject_account_activation_request: "%{value} hesabÄ± etkinleÅŸtirme isteÄŸi"
   mail_body_account_activation_request: "Yeni bir kullanÄ±cÄ± (%{value}) kaydedildi. Hesap onaylanmayÄ± bekliyor:"
 
-  gui_validation_error: 1 hata
-  gui_validation_error_plural: "%{count} hata"
 
   field_name: Ä°sim
   field_description: Yorum
@@ -414,8 +412,6 @@
   label_text: Uzun Metin
   label_attribute: Nitelik
   label_attribute_plural: Nitelikler
-  label_download: "%{count} indirme"
-  label_download_plural: "%{count} indirme"
   label_no_data: GÃ¶sterilecek veri yok
   label_change_status: DeÄŸiÅŸim Durumu
   label_history: GeÃ§miÅŸ
@@ -515,8 +511,6 @@
   label_repository: Depo
   label_repository_plural: Depolar
   label_browse: GÃ¶zat
-  label_modification: "%{count} deÄŸiÅŸim"
-  label_modification_plural: "%{count} deÄŸiÅŸim"
   label_revision: DeÄŸiÅŸiklik
   label_revision_plural: DeÄŸiÅŸiklikler
   label_associated_revisions: BirleÅŸtirilmiÅŸ deÄŸiÅŸiklikler
@@ -779,7 +773,6 @@
   permission_comment_news: Haberlere yorum yapma
   permission_delete_messages: Mesaj silme
   permission_select_project_modules: Proje modÃ¼llerini seÃ§me
-  permission_manage_documents: Belgeleri yÃ¶netme
   permission_edit_wiki_pages: Wiki sayfalarÄ±nÄ± dÃ¼zenleme
   permission_add_issue_watchers: TakipÃ§i ekleme
   permission_view_gantt: Ä°ÅŸ-Zaman Ã§izelgesi gÃ¶rme
@@ -993,8 +986,6 @@
   text_scm_command: Komut
   text_scm_command_version: SÃ¼rÃ¼m
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1101,3 +1092,18 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Toplam
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
diff -r 0a574315af3e -r 4f746d8966dd config/locales/uk.yml
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -174,8 +174,6 @@
   mail_subject_account_activation_request: "Ð—Ð°Ð¿Ð¸Ñ‚ Ð½Ð° Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–ÑŽ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ Ð·Ð°Ð¿Ð¸ÑÑƒ %{value}"
   mail_body_account_activation_request: "ÐÐ¾Ð²Ð¸Ð¹ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡ (%{value}) Ð·Ð°Ñ€ÐµÑ”ÑÑ‚Ñ€ÑƒÐ²Ð°Ð²ÑÑ. Ð™Ð¾Ð³Ð¾ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¸Ð¹ Ð·Ð°Ð¿Ð¸Ñ Ñ‡ÐµÐºÐ°Ñ” Ð½Ð° Ð²Ð°ÑˆÐµ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ:"
 
-  gui_validation_error: 1 Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°
-  gui_validation_error_plural: "%{count} Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸(Ð¾Ðº)"
 
   field_name: Ð†Ð¼'Ñ
   field_description: ÐžÐ¿Ð¸Ñ
@@ -364,8 +362,6 @@
   label_text: Ð”Ð¾Ð²Ð³Ð¸Ð¹ Ñ‚ÐµÐºÑÑ‚
   label_attribute: ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ‚
   label_attribute_plural: Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¸
-  label_download: "%{count} Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð¾"
-  label_download_plural: "%{count} Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½ÑŒ"
   label_no_data: ÐÐµÐ¼Ð°Ñ” Ð´Ð°Ð½Ð¸Ñ… Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ
   label_change_status: Ð—Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ ÑÑ‚Ð°Ñ‚ÑƒÑ
   label_history: Ð†ÑÑ‚Ð¾Ñ€Ñ–Ñ
@@ -454,8 +450,6 @@
   label_day_plural: Ð´Ð½Ñ–Ð²(Ñ)
   label_repository: Ð ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ð¹
   label_browse: ÐŸÑ€Ð¾Ð³Ð»ÑÐ½ÑƒÑ‚Ð¸
-  label_modification: "%{count} Ð·Ð¼Ñ–Ð½Ð°"
-  label_modification_plural: "%{count} Ð·Ð¼Ñ–Ð½"
   label_revision: Ð’ÐµÑ€ÑÑ–Ñ
   label_revision_plural: Ð’ÐµÑ€ÑÑ–Ð¹
   label_added: Ð´Ð¾Ð´Ð°Ð½Ð¾
@@ -755,7 +749,6 @@
   permission_comment_news: Comment news
   permission_delete_messages: Delete messages
   permission_select_project_modules: Select project modules
-  permission_manage_documents: Manage documents
   permission_edit_wiki_pages: Edit wiki pages
   permission_add_issue_watchers: Add watchers
   permission_view_gantt: View gantt chart
@@ -930,7 +923,6 @@
   label_principal_search: "Search for user or group:"
   label_user_search: "Search for user:"
   field_visible: Visible
-  setting_emails_header: Emails header
   setting_commit_logtime_activity_id: Activity for logged time
   text_time_logged_by_changeset: Applied in changeset %{value}.
   setting_commit_logtime_enabled: Enable time logging
@@ -971,8 +963,6 @@
   text_scm_command: Command
   text_scm_command_version: Version
   label_git_report_last_commit: Report last commit for files and directories
-  text_scm_config: You can configure your scm commands in config/configuration.yml. Please restart the application after editing it.
-  text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
   notice_issue_successful_create: Issue %{id} created.
   label_between: between
   setting_issue_group_assignment: Allow issue assignment to groups
@@ -1077,3 +1067,19 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Ð’ÑÑŒÐ¾Ð³Ð¾
+  text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
+  text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
+  setting_emails_header: Email header
diff -r 0a574315af3e -r 4f746d8966dd config/locales/vi.yml
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -236,16 +236,13 @@
   mail_subject_account_activation_request: "%{value}: YÃªu cáº§u chá»©ng thá»±c tÃ i khoáº£n"
   mail_body_account_activation_request: "NgÆ°á»i dÃ¹ng (%{value}) má»›i Ä‘Äƒng kÃ½ vÃ  cáº§n báº¡n xÃ¡c nháº­n:"
   mail_subject_reminder: "%{count} váº¥n Ä‘á» háº¿t háº¡n trong cÃ¡c %{days} ngÃ y tá»›i"
-  mail_body_reminder: "%{count} váº¥n Ä‘á» gÃ¡n cho báº¡n sáº½ háº¿t háº¡n trong %{days} ngÃ y tá»›i:"
+  mail_body_reminder: "%{count} cÃ´ng viá»‡c báº¡n Ä‘Æ°á»£c phÃ¢n cÃ´ng sáº½ háº¿t háº¡n trong %{days} ngÃ y tá»›i:"
 
-  gui_validation_error: 1 lá»—i
-  gui_validation_error_plural: "%{count} lá»—i"
-
-  field_name: TÃªn
+  field_name: TÃªn dá»± Ã¡n
   field_description: MÃ´ táº£
   field_summary: TÃ³m táº¯t
   field_is_required: Báº¯t buá»™c
-  field_firstname: TÃªn lÃ³t + TÃªn
+  field_firstname: TÃªn Ä‘á»‡m vÃ  TÃªn
   field_lastname: Há»
   field_mail: Email
   field_filename: Táº­p tin
@@ -269,11 +266,11 @@
   field_notes: Ghi chÃº
   field_is_closed: Váº¥n Ä‘á» Ä‘Ã³ng
   field_is_default: GiÃ¡ trá»‹ máº·c Ä‘á»‹nh
-  field_tracker: DÃ²ng váº¥n Ä‘á»
+  field_tracker: Kiá»ƒu váº¥n Ä‘á»
   field_subject: Chá»§ Ä‘á»
   field_due_date: Háº¿t háº¡n
-  field_assigned_to: GÃ¡n cho
-  field_priority: Æ¯u tiÃªn
+  field_assigned_to: PhÃ¢n cÃ´ng cho
+  field_priority: Má»©c Æ°u tiÃªn
   field_fixed_version: PhiÃªn báº£n
   field_user: NgÆ°á»i dÃ¹ng
   field_role: Quyá»n
@@ -287,9 +284,9 @@
   field_last_login_on: Káº¿t ná»‘i cuá»‘i
   field_language: NgÃ´n ngá»¯
   field_effective_date: NgÃ y
-  field_password: Máº­t mÃ£
-  field_new_password: Máº­t mÃ£ má»›i
-  field_password_confirmation: Kháº³ng Ä‘á»‹nh láº¡i
+  field_password: Máº­t kháº©u
+  field_new_password: Máº­t kháº©u má»›i
+  field_password_confirmation: Nháº­p láº¡i máº­t kháº©u
   field_version: PhiÃªn báº£n
   field_type: Kiá»ƒu
   field_host: Host
@@ -304,7 +301,7 @@
   field_start_date: Báº¯t Ä‘áº§u
   field_done_ratio: Tiáº¿n Ä‘á»™
   field_auth_source: Cháº¿ Ä‘á»™ xÃ¡c thá»±c
-  field_hide_mail: KhÃ´ng lÃ m lá»™ email cá»§a báº¡n
+  field_hide_mail: KhÃ´ng hiá»‡n email cá»§a tÃ´i
   field_comments: BÃ¬nh luáº­n
   field_url: URL
   field_start_page: Trang báº¯t Ä‘áº§u
@@ -313,12 +310,12 @@
   field_activity: Hoáº¡t Ä‘á»™ng
   field_spent_on: NgÃ y
   field_identifier: MÃ£ nháº­n dáº¡ng
-  field_is_filter: DÃ¹ng nhÆ° má»™t lá»c
-  field_issue_to: Váº¥n Ä‘á»n liÃªn quan
+  field_is_filter: DÃ¹ng nhÆ° bá»™ lá»c
+  field_issue_to: Váº¥n Ä‘á» liÃªn quan
   field_delay: Äá»™ trá»…
   field_assignable: Váº¥n Ä‘á» cÃ³ thá»ƒ gÃ¡n cho vai trÃ² nÃ y
   field_redirect_existing_links: Chuyá»ƒn hÆ°á»›ng trang Ä‘Ã£ cÃ³
-  field_estimated_hours: Thá»i gian Æ°á»›c Ä‘oÃ¡n
+  field_estimated_hours: Thá»i gian Æ°á»›c lÆ°á»£ng
   field_column_names: Cá»™t
   field_time_zone: MÃºi giá»
   field_searchable: TÃ¬m kiáº¿m Ä‘Æ°á»£c
@@ -340,7 +337,7 @@
   setting_text_formatting: Äá»‹nh dáº¡ng bÃ i viáº¿t
   setting_wiki_compression: NÃ©n lá»‹ch sá»­ Wiki
   setting_feeds_limit: Giá»›i háº¡n ná»™i dung cá»§a feed
-  setting_default_projects_public: Dá»± Ã¡n máº·c Ä‘á»‹nh lÃ  cÃ´ng cá»™ng
+  setting_default_projects_public: Dá»± Ã¡n máº·c Ä‘á»‹nh lÃ  public
   setting_autofetch_changesets: Tá»± Ä‘á»™ng tÃ¬m náº¡p commits
   setting_sys_api_enabled: Cho phÃ©p WS quáº£n lÃ½ kho chá»©a
   setting_commit_ref_keywords: Tá»« khÃ³a tham kháº£o
@@ -400,9 +397,9 @@
   label_member: ThÃ nh viÃªn
   label_member_new: ThÃ nh viÃªn má»›i
   label_member_plural: ThÃ nh viÃªn
-  label_tracker: DÃ²ng váº¥n Ä‘á»
-  label_tracker_plural: DÃ²ng váº¥n Ä‘á»
-  label_tracker_new: Táº¡o dÃ²ng váº¥n Ä‘á» má»›i
+  label_tracker: Kiá»ƒu váº¥n Ä‘á»
+  label_tracker_plural: Kiá»ƒu váº¥n Ä‘á»
+  label_tracker_new: Táº¡o kiá»ƒu váº¥n Ä‘á» má»›i
   label_workflow: Quy trÃ¬nh lÃ m viá»‡c
   label_issue_status: Tráº¡ng thÃ¡i váº¥n Ä‘á»
   label_issue_status_plural: Tráº¡ng thÃ¡i váº¥n Ä‘á»
@@ -429,8 +426,8 @@
   label_login: ÄÄƒng nháº­p
   label_logout: ThoÃ¡t
   label_help: GiÃºp Ä‘á»¡
-  label_reported_issues: Váº¥n Ä‘á» Ä‘Ã£ bÃ¡o cÃ¡o
-  label_assigned_to_me_issues: Váº¥n Ä‘á» gÃ¡n cho báº¡n
+  label_reported_issues: CÃ´ng viá»‡c báº¡n phÃ¢n cÃ´ng
+  label_assigned_to_me_issues: CÃ´ng viá»‡c Ä‘Æ°á»£c phÃ¢n cÃ´ng
   label_last_login: Káº¿t ná»‘i cuá»‘i
   label_registered_on: NgÃ y tham gia
   label_activity: Hoáº¡t Ä‘á»™ng
@@ -454,8 +451,6 @@
   label_text: VÄƒn báº£n dÃ i
   label_attribute: Thuá»™c tÃ­nh
   label_attribute_plural: CÃ¡c thuá»™c tÃ­nh
-  label_download: "%{count} láº§n táº£i"
-  label_download_plural: "%{count} láº§n táº£i"
   label_no_data: ChÆ°a cÃ³ thÃ´ng tin gÃ¬
   label_change_status: Äá»•i tráº¡ng thÃ¡i
   label_history: LÆ°á»£c sá»­
@@ -501,7 +496,7 @@
   label_permissions: Quyá»n
   label_current_status: Tráº¡ng thÃ¡i hiá»‡n táº¡i
   label_new_statuses_allowed: Tráº¡ng thÃ¡i má»›i Ä‘Æ°á»£c phÃ©p
-  label_all: táº¥t cáº£
+  label_all: Táº¥t cáº£
   label_none: khÃ´ng
   label_nobody: Cháº³ng ai
   label_next: Sau
@@ -555,8 +550,6 @@
   label_repository: Kho lÆ°u trá»¯
   label_repository_plural: Kho lÆ°u trá»¯
   label_browse: Duyá»‡t
-  label_modification: "%{count} thay Ä‘á»•i"
-  label_modification_plural: "%{count} thay Ä‘á»•i"
   label_revision: Báº£n Ä‘iá»u chá»‰nh
   label_revision_plural: Báº£n Ä‘iá»u chá»‰nh
   label_associated_revisions: CÃ¡c báº£n Ä‘iá»u chá»‰nh Ä‘Æ°á»£c ghÃ©p
@@ -624,8 +617,8 @@
   label_start_to_start: Ä‘áº§u tá»› Ä‘áº§u
   label_start_to_end: Ä‘áº§u tá»›i cuá»‘i
   label_stay_logged_in: LÆ°u thÃ´ng tin Ä‘Äƒng nháº­p
-  label_disabled: bá»‹ vÃ´ hiá»‡u
-  label_show_completed_versions: Xem phiÃªn báº£n Ä‘Ã£ xong
+  label_disabled: Bá»‹ vÃ´ hiá»‡u
+  label_show_completed_versions: Xem phiÃªn báº£n Ä‘Ã£ hoÃ n thÃ nh
   label_me: tÃ´i
   label_board: Diá»…n Ä‘Ã n
   label_board_new: Táº¡o diá»…n Ä‘Ã n má»›i
@@ -646,8 +639,8 @@
   label_sort_by: "Sáº¯p xáº¿p theo %{value}"
   label_send_test_email: Gá»­i má»™t email kiá»ƒm tra
   label_feeds_access_key_created_on: "MÃ£ chá»©ng thá»±c RSS Ä‘Æ°á»£c táº¡o ra cÃ¡ch Ä‘Ã¢y %{value}"
-  label_module_plural: MÃ´-Ä‘un
-  label_added_time_by: "thÃªm bá»Ÿi %{author} cÃ¡ch Ä‘Ã¢y %{age}"
+  label_module_plural: Module
+  label_added_time_by: "ThÃªm bá»Ÿi %{author} cÃ¡ch Ä‘Ã¢y %{age}"
   label_updated_time: "Cáº­p nháº­t cÃ¡ch Ä‘Ã¢y %{value}"
   label_jump_to_a_project: Nháº£y Ä‘áº¿n dá»± Ã¡n...
   label_file_plural: Táº­p tin
@@ -658,9 +651,9 @@
   label_theme: Giao diá»‡n
   label_default: Máº·c Ä‘á»‹nh
   label_search_titles_only: Chá»‰ tÃ¬m trong tá»±a Ä‘á»
-  label_user_mail_option_all: "Má»i sá»± kiá»‡n trÃªn má»i dá»± Ã¡n cá»§a báº¡n"
+  label_user_mail_option_all: "Má»i sá»± kiá»‡n trÃªn má»i dá»± Ã¡n cá»§a tÃ´i"
   label_user_mail_option_selected: "Má»i sá»± kiá»‡n trÃªn cÃ¡c dá»± Ã¡n Ä‘Æ°á»£c chá»n..."
-  label_user_mail_no_self_notified: "Äá»«ng gá»­i email vá» cÃ¡c thay Ä‘á»•i do chÃ­nh báº¡n thá»±c hiá»‡n"
+  label_user_mail_no_self_notified: "Äá»«ng gá»­i email vá» cÃ¡c thay Ä‘á»•i do chÃ­nh tÃ´i thá»±c hiá»‡n"
   label_registration_activation_by_email: kÃ­ch hoáº¡t tÃ i khoáº£n qua email
   label_registration_manual_activation: kÃ­ch hoáº¡t tÃ i khoáº£n thá»§ cÃ´ng
   label_registration_automatic_activation: kÃ­ch hoáº¡t tÃ i khoáº£n tá»± Ä‘á»™ng
@@ -670,9 +663,9 @@
   label_general: Tá»•ng quan
   label_more: Chi tiáº¿t
   label_scm: SCM
-  label_plugins: MÃ´-Ä‘un
+  label_plugins: Module
   label_ldap_authentication: Chá»©ng thá»±c LDAP
-  label_downloads_abbr: Táº£i vá»
+  label_downloads_abbr: Sá»‘ lÆ°á»£ng Download
   label_optional_description: MÃ´ táº£ bá»• sung
   label_add_another_file: ThÃªm táº­p tin khÃ¡c
   label_preferences: Cáº¥u hÃ¬nh
@@ -716,17 +709,17 @@
   button_reset: Táº¡o láº¡i
   button_rename: Äá»•i tÃªn
   button_change_password: Äá»•i máº­t mÃ£
-  button_copy: ChÃ©p
+  button_copy: Sao chÃ©p
   button_annotate: ChÃº giáº£i
   button_update: Cáº­p nháº­t
   button_configure: Cáº¥u hÃ¬nh
   button_quote: TrÃ­ch dáº«n
 
-  status_active: hoáº¡t Ä‘á»™ng
-  status_registered: Ä‘Äƒng kÃ½
-  status_locked: khÃ³a
+  status_active: Äang hoáº¡t Ä‘á»™ng
+  status_registered: Má»›i Ä‘Äƒng kÃ½
+  status_locked: ÄÃ£ khÃ³a
 
-  text_select_mail_notifications: Chá»n hÃ nh Ä‘á»™ng Ä‘á»‘i vá»›i má»—i email thÃ´ng bÃ¡o sáº½ gá»­i.
+  text_select_mail_notifications: Chá»n hÃ nh Ä‘á»™ng Ä‘á»‘i vá»›i má»—i email sáº½ gá»­i.
   text_regexp_info: eg. ^[A-Z0-9]+$
   text_min_max_length_info: 0 Ä‘á»ƒ chá»‰ khÃ´ng háº¡n cháº¿
   text_project_destroy_confirmation: Báº¡n cÃ³ cháº¯c cháº¯n muá»‘n xÃ³a dá»± Ã¡n nÃ y vÃ  cÃ¡c dá»¯ liá»‡u liÃªn quan ?
@@ -754,7 +747,7 @@
   text_load_default_configuration: Náº¡p láº¡i cáº¥u hÃ¬nh máº·c Ä‘á»‹nh
   text_status_changed_by_changeset: "Ãp dá»¥ng trong changeset : %{value}."
   text_issues_destroy_confirmation: 'Báº¡n cÃ³ cháº¯c cháº¯n muá»‘n xÃ³a cÃ¡c váº¥n Ä‘á» Ä‘Ã£ chá»n ?'
-  text_select_project_modules: 'Chá»n cÃ¡c mÃ´-Ä‘un cho dá»± Ã¡n:'
+  text_select_project_modules: 'Chá»n cÃ¡c module cho dá»± Ã¡n:'
   text_default_administrator_account_changed: Thay Ä‘á»•i tÃ i khoáº£n quáº£n trá»‹ máº·c Ä‘á»‹nh
   text_file_repository_writable: Cho phÃ©p ghi thÆ° má»¥c Ä‘Ã­nh kÃ¨m
   text_rmagick_available: Tráº¡ng thÃ¡i RMagick
@@ -767,17 +760,17 @@
   text_enumeration_category_reassign_to: 'GÃ¡n láº¡i giÃ¡ trá»‹ nÃ y:'
   text_email_delivery_not_configured: "Cáº¥u hÃ¬nh gá»­i Email chÆ°a Ä‘Æ°á»£c Ä‘áº·t, vÃ  chá»©c nÄƒng thÃ´ng bÃ¡o bá»‹ loáº¡i bá».\nCáº¥u hÃ¬nh mÃ¡y chá»§ SMTP cá»§a báº¡n á»Ÿ file config/configuration.yml vÃ  khá»Ÿi Ä‘á»™ng láº¡i Ä‘á»ƒ kÃ­ch hoáº¡t chÃºng."
 
-  default_role_manager: Äiá»u hÃ nh
-  default_role_developer: PhÃ¡t triá»ƒn
+  default_role_manager: 'Äiá»u hÃ nh '
+  default_role_developer: 'PhÃ¡t triá»ƒn '
   default_role_reporter: BÃ¡o cÃ¡o
   default_tracker_bug: Lá»—i
   default_tracker_feature: TÃ­nh nÄƒng
   default_tracker_support: Há»— trá»£
   default_issue_status_new: Má»›i
   default_issue_status_in_progress: Äang tiáº¿n hÃ nh
-  default_issue_status_resolved: Quyáº¿t tÃ¢m
+  default_issue_status_resolved: ÄÃ£ Ä‘Æ°á»£c giáº£i quyáº¿t
   default_issue_status_feedback: Pháº£n há»“i
-  default_issue_status_closed: ÄÃ³ng
+  default_issue_status_closed: ÄÃ£ Ä‘Ã³ng
   default_issue_status_rejected: Tá»« chá»‘i
   default_doc_category_user: TÃ i liá»‡u ngÆ°á»i dÃ¹ng
   default_doc_category_tech: TÃ i liá»‡u ká»¹ thuáº­t
@@ -790,13 +783,13 @@
   default_activity_development: PhÃ¡t triá»ƒn
 
   enumeration_issue_priorities: Má»©c Ä‘á»™ Æ°u tiÃªn váº¥n Ä‘á»
-  enumeration_doc_categories: Chá»§ Ä‘á» tÃ i liá»‡u
-  enumeration_activities: Hoáº¡t Ä‘á»™ng (theo dÃµi thá»i gian)
+  enumeration_doc_categories: Danh má»¥c tÃ i liá»‡u
+  enumeration_activities: Hoáº¡t Ä‘á»™ng
 
-  setting_plain_text_mail: mail dáº¡ng text Ä‘Æ¡n giáº£n (khÃ´ng dÃ¹ng HTML)
+  setting_plain_text_mail: Mail dáº¡ng text Ä‘Æ¡n giáº£n (khÃ´ng dÃ¹ng HTML)
   setting_gravatar_enabled: DÃ¹ng biá»ƒu tÆ°á»£ng Gravatar
   permission_edit_project: Chá»‰nh dá»± Ã¡n
-  permission_select_project_modules: Chá»n mÃ´-Ä‘un
+  permission_select_project_modules: Chá»n Module
   permission_manage_members: Quáº£n lÃ½ thÃ nh viÃªn
   permission_manage_versions: Quáº£n lÃ½ phiÃªn báº£n
   permission_manage_categories: Quáº£n lÃ½ chá»§ Ä‘á»
@@ -808,19 +801,18 @@
   permission_edit_own_issue_notes: Sá»­a chÃº thÃ­ch cÃ¡ nhÃ¢n
   permission_move_issues: Chuyá»ƒn váº¥n Ä‘á»
   permission_delete_issues: XÃ³a váº¥n Ä‘á»
-  permission_manage_public_queries: Quáº£n lÃ½ truy cáº¥n cÃ´ng cá»™ng
+  permission_manage_public_queries: Quáº£n lÃ½ truy váº¥n cÃ´ng cá»™ng
   permission_save_queries: LÆ°u truy váº¥n
   permission_view_gantt: Xem biá»ƒu Ä‘á»“ sá»± kiá»‡n
   permission_view_calendar: Xem lá»‹ch
-  permission_view_issue_watchers: Xem cÃ¡c ngÆ°á»i theo dÃµi
+  permission_view_issue_watchers: Xem nhá»¯ng ngÆ°á»i theo dÃµi
   permission_add_issue_watchers: ThÃªm ngÆ°á»i theo dÃµi
-  permission_log_time: LÆ°u thá»i gian Ä‘Ã£ tá»‘n
-  permission_view_time_entries: Xem thá»i gian Ä‘Ã£ tá»‘n
+  permission_log_time: LÆ°u thá»i gian Ä‘Ã£ qua
+  permission_view_time_entries: Xem thá»i gian Ä‘Ã£ qua
   permission_edit_time_entries: Xem nháº­t kÃ½ thá»i gian
   permission_edit_own_time_entries: Sá»­a thá»i gian Ä‘Ã£ lÆ°u
   permission_manage_news: Quáº£n lÃ½ tin má»›i
   permission_comment_news: ChÃº thÃ­ch vÃ o tin má»›i
-  permission_manage_documents: Quáº£n lÃ½ tÃ i liá»‡u
   permission_view_documents: Xem tÃ i liá»‡u
   permission_manage_files: Quáº£n lÃ½ táº­p tin
   permission_view_files: Xem táº­p tin
@@ -844,7 +836,7 @@
   permission_delete_messages: XÃ³a bÃ i viáº¿t
   permission_delete_own_messages: XÃ³a bÃ i viáº¿t cÃ¡ nhÃ¢n
   label_example: VÃ­ dá»¥
-  text_repository_usernames_mapping: "Chá»n hoáº·c cáº­p nháº­t Ã¡nh xáº¡ ngÆ°á»i dÃ¹ng há»‡ thá»‘ng vá»›i ngÆ°á»i dÃ¹ng trong kho lÆ°u trá»¯.\nNhá»¯ng trÆ°á»ng há»£p trÃ¹ng há»£p vá» tÃªn vÃ  email sáº½ Ä‘Æ°á»£c tá»± Ä‘á»™ng Ã¡nh xáº¡."
+  text_repository_usernames_mapping: "Lá»±a chá»n hoáº·c cáº­p nháº­t Ã¡nh xáº¡ ngÆ°á»i dÃ¹ng há»‡ thá»‘ng vá»›i ngÆ°á»i dÃ¹ng trong kho lÆ°u trá»¯.\nKhi ngÆ°á»i dÃ¹ng trÃ¹ng há»£p vá» tÃªn vÃ  email sáº½ Ä‘Æ°á»£c tá»± Ä‘á»™ng Ã¡nh xáº¡."
   permission_delete_own_messages: XÃ³a thÃ´ng Ä‘iá»‡p
   label_user_activity: "%{value} hoáº¡t Ä‘á»™ng"
   label_updated_time_by: "Cáº­p nháº­t bá»Ÿi %{author} cÃ¡ch Ä‘Ã¢y %{age}"
@@ -1137,3 +1129,15 @@
   setting_non_working_week_days: CÃ¡c ngÃ y khÃ´ng lÃ m viá»‡c
   label_in_the_next_days: Trong tÆ°Æ¡ng lai
   label_in_the_past_days: Trong quÃ¡ khá»©
+  label_attribute_of_user: "Cá»§a ngÆ°á»i dÃ¹ng %{name}"
+  text_turning_multiple_off: Náº¿u báº¡n vÃ´ hiá»‡u hÃ³a nhiá»u giÃ¡ trá»‹, chÃºng sáº½ bá»‹ loáº¡i bá» Ä‘á»ƒ duy trÃ¬ chá»‰ cÃ³ má»™t giÃ¡ trá»‹ cho má»—i má»¥c.
+  label_attribute_of_issue: "Váº¥n Ä‘á» cá»§a %{name}"
+  permission_add_documents: ThÃªm tÃ i liá»‡u
+  permission_edit_documents: Soáº¡n tháº£o tÃ i liá»‡u
+  permission_delete_documents: XÃ³a tÃ i liá»‡u
+  label_gantt_progress_line: Tiáº¿n Ä‘á»™
+  setting_jsonp_enabled: Cho phÃ©p trá»£ giÃºp JSONP
+  field_inherit_members: CÃ¡c thÃ nh viÃªn káº¿ thá»«a
+  field_closed_on: ÄÃ£ Ä‘Ã³ng
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: Tá»•ng cá»™ng
diff -r 0a574315af3e -r 4f746d8966dd config/locales/zh-TW.yml
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -4,6 +4,8 @@
 
 "zh-TW":
   direction: ltr
+  jquery:
+    locale: "zh-TW"
   date:
     formats:
       # Use the strftime parameters for formats.
@@ -121,8 +123,8 @@
         one: "ç´„ 1 å°æ™‚"
         other: "ç´„ %{count} å°æ™‚"
       x_hours:
-        one:   "1 hour"
-        other: "%{count} hours"
+        one:   "1 å°æ™‚"
+        other: "%{count} å°æ™‚"
       x_days:
         one: "1 å¤©"
         other: "%{count} å¤©"
@@ -298,8 +300,6 @@
   mail_subject_wiki_content_updated: "'%{id}' wiki é é¢å·²è¢«æ›´æ–°"
   mail_body_wiki_content_updated: "æ­¤ '%{id}' wiki é é¢å·²è¢« %{author} æ›´æ–°ã€‚"
 
-  gui_validation_error: 1 å€‹éŒ¯èª¤
-  gui_validation_error_plural: "%{count} å€‹éŒ¯èª¤"
 
   field_name: åç¨±
   field_description: æ¦‚è¿°
@@ -313,7 +313,8 @@
   field_downloads: ä¸‹è¼‰æ¬¡æ•¸
   field_author: ä½œè€…
   field_created_on: å»ºç«‹æ—¥æœŸ
-  field_updated_on: æ›´æ–°
+  field_updated_on: æ›´æ–°æ—¥æœŸ
+  field_closed_on: çµæŸæ—¥æœŸ
   field_field_format: æ ¼å¼
   field_is_for_all: çµ¦å…¨éƒ¨çš„å°ˆæ¡ˆ
   field_possible_values: å¯èƒ½å€¼
@@ -414,6 +415,7 @@
   field_timeout: "é€¾æ™‚ (å–®ä½: ç§’)"
   field_board_parent: çˆ¶è«–å£‡
   field_private_notes: ç§äººç­†è¨˜
+  field_inherit_members: ç¹¼æ‰¿çˆ¶å°ˆæ¡ˆæˆå“¡
 
   setting_app_title: æ¨™é¡Œ
   setting_app_subtitle: å‰¯æ¨™é¡Œ
@@ -482,6 +484,8 @@
   setting_thumbnails_enabled: é¡¯ç¤ºé™„åŠ æª”æ¡ˆçš„ç¸®åœ–
   setting_thumbnails_size: "ç¸®åœ–å¤§å° (å–®ä½: åƒç´  pixels)"
   setting_non_working_week_days: éžå·¥ä½œæ—¥
+  setting_jsonp_enabled: å•Ÿç”¨ JSONP æ”¯æ´
+  setting_default_projects_tracker_ids: æ–°å°ˆæ¡ˆé è¨­ä½¿ç”¨çš„è¿½è¹¤æ¨™ç±¤
 
   permission_add_project: å»ºç«‹å°ˆæ¡ˆ
   permission_add_subprojects: å»ºç«‹å­å°ˆæ¡ˆ
@@ -518,8 +522,10 @@
   permission_edit_own_time_entries: ç·¨è¼¯è‡ªå·±çš„å·¥æ™‚è¨˜éŒ„
   permission_manage_news: ç®¡ç†æ–°èž
   permission_comment_news: å›žæ‡‰æ–°èž
-  permission_manage_documents: ç®¡ç†æ–‡ä»¶
   permission_view_documents: æª¢è¦–æ–‡ä»¶
+  permission_add_documents: æ–°å¢žæ–‡ä»¶
+  permission_edit_documents: ç·¨è¼¯æ–‡ä»¶
+  permission_delete_documents: åˆªé™¤æ–‡ä»¶
   permission_manage_files: ç®¡ç†æª”æ¡ˆ
   permission_view_files: æª¢è¦–æª”æ¡ˆ
   permission_manage_wiki: ç®¡ç† wiki
@@ -650,8 +656,6 @@
   label_text: é•·æ–‡å­—
   label_attribute: å±¬æ€§
   label_attribute_plural: å±¬æ€§
-  label_download: "%{count} å€‹ä¸‹è¼‰"
-  label_download_plural: "%{count} å€‹ä¸‹è¼‰"
   label_no_data: æ²’æœ‰ä»»ä½•è³‡æ–™å¯ä¾›é¡¯ç¤º
   label_change_status: è®Šæ›´ç‹€æ…‹
   label_history: æ­·å²
@@ -769,8 +773,6 @@
   label_repository_new: å»ºç«‹æ–°å„²å­˜æ©Ÿåˆ¶
   label_repository_plural: å„²å­˜æ©Ÿåˆ¶æ¸…å–®
   label_browse: ç€è¦½
-  label_modification: "%{count} è®Šæ›´"
-  label_modification_plural: "%{count} è®Šæ›´"
   label_branch: åˆ†æ”¯
   label_tag: æ¨™ç±¤
   label_revision: ä¿®è¨‚ç‰ˆ
@@ -965,13 +967,16 @@
   label_readonly: å”¯è®€
   label_required: å¿…å¡«
   label_attribute_of_project: "å°ˆæ¡ˆæ˜¯ %{name}"
+  label_attribute_of_issue: "å•é¡Œæ˜¯ %{name}"
   label_attribute_of_author: "ä½œè€…æ˜¯ %{name}"
   label_attribute_of_assigned_to: "è¢«æŒ‡æ´¾è€…æ˜¯ %{name}"
+  label_attribute_of_user: "ç”¨æˆ¶æ˜¯ %{name}"
   label_attribute_of_fixed_version: "ç‰ˆæœ¬æ˜¯ %{name}"
   label_cross_project_descendants: èˆ‡å­å°ˆæ¡ˆå…±ç”¨
   label_cross_project_tree: èˆ‡å°ˆæ¡ˆæ¨¹å…±ç”¨
   label_cross_project_hierarchy: èˆ‡å°ˆæ¡ˆéšŽå±¤æž¶æ§‹å…±ç”¨
   label_cross_project_system: èˆ‡å…¨éƒ¨çš„å°ˆæ¡ˆå…±ç”¨
+  label_gantt_progress_line: é€²åº¦ç·š
 
   button_login: ç™»å…¥
   button_submit: é€å‡º
@@ -1117,6 +1122,7 @@
     æ‚¨çš„å¸³æˆ¶å°‡æœƒè¢«æ°¸ä¹…åˆªé™¤ï¼Œä¸”ç„¡æ³•è¢«é‡æ–°å•Ÿç”¨ã€‚
   text_session_expiration_settings: "è­¦å‘Šï¼šè®Šæ›´é€™äº›è¨­å®šå°‡æœƒå°Žè‡´åŒ…å«æ‚¨åœ¨å…§çš„æ‰€æœ‰å·¥ä½œéšŽæ®µéŽæœŸã€‚"
   text_project_closed: æ­¤å°ˆæ¡ˆå·²è¢«é—œé–‰ï¼Œåƒ…ä¾›å”¯è®€ä½¿ç”¨ã€‚
+  text_turning_multiple_off: "è‹¥æ‚¨åœç”¨å¤šé‡å€¼è¨­å®šï¼Œé‡è¤‡çš„å€¼å°‡æœƒè¢«ç§»é™¤ï¼Œä»¥ä½¿æ¯å€‹é …ç›®åƒ…ä¿ç•™ä¸€å€‹å€¼ã€‚"
 
   default_role_manager: ç®¡ç†äººå“¡
   default_role_developer: é–‹ç™¼äººå“¡
@@ -1163,3 +1169,4 @@
   description_date_from: è¼¸å…¥èµ·å§‹æ—¥æœŸ
   description_date_to: è¼¸å…¥çµæŸæ—¥æœŸ
   text_repository_identifier_info: 'åƒ…å…è¨±ä½¿ç”¨å°å¯«è‹±æ–‡å­—æ¯ (a-z), é˜¿æ‹‰ä¼¯æ•¸å­—, è™›ç·šèˆ‡åº•ç·šã€‚<br />ä¸€æ—¦å„²å­˜ä¹‹å¾Œ, ä»£ç¢¼ä¾¿ç„¡æ³•å†æ¬¡è¢«æ›´æ”¹ã€‚'
+  label_total_time: ç¸½è¨ˆ
diff -r 0a574315af3e -r 4f746d8966dd config/locales/zh.yml
--- a/config/locales/zh.yml
+++ b/config/locales/zh.yml
@@ -212,8 +212,6 @@
   mail_subject_wiki_content_updated: "'%{id}' wikié¡µé¢å·²æ›´æ–°ã€‚"
   mail_body_wiki_content_updated: "'%{id}' wikié¡µé¢å·²ç”± %{author} æ›´æ–°ã€‚"
 
-  gui_validation_error: 1 ä¸ªé”™è¯¯
-  gui_validation_error_plural: "%{count} ä¸ªé”™è¯¯"
 
   field_name: åç§°
   field_description: æè¿°
@@ -400,7 +398,6 @@
   permission_edit_own_time_entries: ç¼–è¾‘è‡ªå·±çš„è€—æ—¶
   permission_manage_news: ç®¡ç†æ–°é—»
   permission_comment_news: ä¸ºæ–°é—»æ·»åŠ è¯„è®º
-  permission_manage_documents: ç®¡ç†æ–‡æ¡£
   permission_view_documents: æŸ¥çœ‹æ–‡æ¡£
   permission_manage_files: ç®¡ç†æ–‡ä»¶
   permission_view_files: æŸ¥çœ‹æ–‡ä»¶
@@ -526,8 +523,6 @@
   label_text: æ–‡æœ¬
   label_attribute: å±žæ€§
   label_attribute_plural: å±žæ€§
-  label_download: "%{count} æ¬¡ä¸‹è½½"
-  label_download_plural: "%{count} æ¬¡ä¸‹è½½"
   label_no_data: æ²¡æœ‰ä»»ä½•æ•°æ®å¯ä¾›æ˜¾ç¤º
   label_change_status: å˜æ›´çŠ¶æ€
   label_history: åŽ†å²è®°å½•
@@ -630,8 +625,6 @@
   label_repository: ç‰ˆæœ¬åº“
   label_repository_plural: ç‰ˆæœ¬åº“
   label_browse: æµè§ˆ
-  label_modification: "%{count} ä¸ªæ›´æ–°"
-  label_modification_plural: "%{count} ä¸ªæ›´æ–°"
   label_branch: åˆ†æ”¯
   label_tag: æ ‡ç­¾
   label_revision: ä¿®è®¢
@@ -1086,3 +1079,16 @@
   setting_non_working_week_days: Non-working days
   label_in_the_next_days: in the next
   label_in_the_past_days: in the past
+  label_attribute_of_user: User's %{name}
+  text_turning_multiple_off: If you disable multiple values, multiple values will be
+    removed in order to preserve only one value per item.
+  label_attribute_of_issue: Issue's %{name}
+  permission_add_documents: Add documents
+  permission_edit_documents: Edit documents
+  permission_delete_documents: Delete documents
+  label_gantt_progress_line: Progress line
+  setting_jsonp_enabled: Enable JSONP support
+  field_inherit_members: Inherit members
+  field_closed_on: Closed
+  setting_default_projects_tracker_ids: Default trackers for new projects
+  label_total_time: åˆè®¡
diff -r 0a574315af3e -r 4f746d8966dd config/routes.rb
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,47 +18,47 @@
 RedmineApp::Application.routes.draw do
   root :to => 'welcome#index', :as => 'home'
 
-  match 'login', :to => 'account#login', :as => 'signin'
-  match 'logout', :to => 'account#logout', :as => 'signout'
+  match 'login', :to => 'account#login', :as => 'signin', :via => [:get, :post]
+  match 'logout', :to => 'account#logout', :as => 'signout', :via => [:get, :post]
   match 'account/register', :to => 'account#register', :via => [:get, :post], :as => 'register'
   match 'account/lost_password', :to => 'account#lost_password', :via => [:get, :post], :as => 'lost_password'
   match 'account/activate', :to => 'account#activate', :via => :get
 
-  match '/news/preview', :controller => 'previews', :action => 'news', :as => 'preview_news'
-  match '/issues/preview/new/:project_id', :to => 'previews#issue', :as => 'preview_new_issue'
-  match '/issues/preview/edit/:id', :to => 'previews#issue', :as => 'preview_edit_issue'
-  match '/issues/preview', :to => 'previews#issue', :as => 'preview_issue'
+  match '/news/preview', :controller => 'previews', :action => 'news', :as => 'preview_news', :via => [:get, :post, :put]
+  match '/issues/preview/new/:project_id', :to => 'previews#issue', :as => 'preview_new_issue', :via => [:get, :post, :put]
+  match '/issues/preview/edit/:id', :to => 'previews#issue', :as => 'preview_edit_issue', :via => [:get, :post, :put]
+  match '/issues/preview', :to => 'previews#issue', :as => 'preview_issue', :via => [:get, :post, :put]
 
   match 'projects/:id/wiki', :to => 'wikis#edit', :via => :post
   match 'projects/:id/wiki/destroy', :to => 'wikis#destroy', :via => [:get, :post]
 
-  match 'boards/:board_id/topics/new', :to => 'messages#new', :via => [:get, :post]
+  match 'boards/:board_id/topics/new', :to => 'messages#new', :via => [:get, :post], :as => 'new_board_message'
   get 'boards/:board_id/topics/:id', :to => 'messages#show', :as => 'board_message'
   match 'boards/:board_id/topics/quote/:id', :to => 'messages#quote', :via => [:get, :post]
   get 'boards/:board_id/topics/:id/edit', :to => 'messages#edit'
 
-  post 'boards/:board_id/topics/preview', :to => 'messages#preview'
+  post 'boards/:board_id/topics/preview', :to => 'messages#preview', :as => 'preview_board_message'
   post 'boards/:board_id/topics/:id/replies', :to => 'messages#reply'
   post 'boards/:board_id/topics/:id/edit', :to => 'messages#edit'
   post 'boards/:board_id/topics/:id/destroy', :to => 'messages#destroy'
 
   # Misc issue routes. TODO: move into resources
   match '/issues/auto_complete', :to => 'auto_completes#issues', :via => :get, :as => 'auto_complete_issues'
-  match '/issues/context_menu', :to => 'context_menus#issues', :as => 'issues_context_menu'
-  match '/issues/changes', :to => 'journals#index', :as => 'issue_changes'
+  match '/issues/context_menu', :to => 'context_menus#issues', :as => 'issues_context_menu', :via => [:get, :post]
+  match '/issues/changes', :to => 'journals#index', :as => 'issue_changes', :via => :get
   match '/issues/:id/quoted', :to => 'journals#new', :id => /\d+/, :via => :post, :as => 'quoted_issue'
 
   match '/journals/diff/:id', :to => 'journals#diff', :id => /\d+/, :via => :get
   match '/journals/edit/:id', :to => 'journals#edit', :id => /\d+/, :via => [:get, :post]
 
-  match '/projects/:project_id/issues/gantt', :to => 'gantts#show'
-  match '/issues/gantt', :to => 'gantts#show'
+  get '/projects/:project_id/issues/gantt', :to => 'gantts#show', :as => 'project_gantt'
+  get '/issues/gantt', :to => 'gantts#show'
 
-  match '/projects/:project_id/issues/calendar', :to => 'calendars#show'
-  match '/issues/calendar', :to => 'calendars#show'
+  get '/projects/:project_id/issues/calendar', :to => 'calendars#show', :as => 'project_calendar'
+  get '/issues/calendar', :to => 'calendars#show'
 
-  match 'projects/:id/issues/report', :to => 'reports#issue_report', :via => :get
-  match 'projects/:id/issues/report/:detail', :to => 'reports#issue_report_details', :via => :get
+  get 'projects/:id/issues/report', :to => 'reports#issue_report', :as => 'project_issues_report'
+  get 'projects/:id/issues/report/:detail', :to => 'reports#issue_report_details', :as => 'project_issues_report_details'
 
   match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post]
   match 'my/account/destroy', :controller => 'my', :action => 'destroy', :via => [:get, :post]
@@ -77,20 +77,21 @@
   match 'users/:id/memberships/:membership_id', :to => 'users#destroy_membership', :via => :delete
   match 'users/:id/memberships', :to => 'users#edit_membership', :via => :post, :as => 'user_memberships'
 
-  match 'watchers/new', :controller=> 'watchers', :action => 'new', :via => :get
-  match 'watchers', :controller=> 'watchers', :action => 'create', :via => :post
-  match 'watchers/append', :controller=> 'watchers', :action => 'append', :via => :post
-  match 'watchers/destroy', :controller=> 'watchers', :action => 'destroy', :via => :post
-  match 'watchers/watch', :controller=> 'watchers', :action => 'watch', :via => :post
-  match 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch', :via => :post
-  match 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user', :via => :get
-
-  match 'projects/:id/settings/:tab', :to => "projects#settings"
+  post 'watchers/watch', :to => 'watchers#watch', :as => 'watch'
+  delete 'watchers/watch', :to => 'watchers#unwatch'
+  get 'watchers/new', :to => 'watchers#new'
+  post 'watchers', :to => 'watchers#create'
+  post 'watchers/append', :to => 'watchers#append'
+  delete 'watchers', :to => 'watchers#destroy'
+  get 'watchers/autocomplete_for_user', :to => 'watchers#autocomplete_for_user'
+  # Specific routes for issue watchers API
+  post 'issues/:object_id/watchers', :to => 'watchers#create', :object_type => 'issue'
+  delete 'issues/:object_id/watchers/:user_id' => 'watchers#destroy', :object_type => 'issue'
   match 'projects/:id/overview', :to => "projects#overview"
 
   resources :projects do
     member do
-      get 'settings'
+      get 'settings(/:tab)', :action => 'settings', :as => 'settings'
       post 'modules'
       post 'archive'
       post 'unarchive'
@@ -99,20 +100,22 @@
       match 'copy', :via => [:get, :post]
     end
 
-    resources :members, :shallow => true, :controller => 'members', :only => [:index, :show, :new, :create, :update, :destroy] do
-      collection do
+    shallow do
+      resources :memberships, :controller => 'members', :only => [:index, :show, :new, :create, :update, :destroy] do
         get 'autocomplete'
       end
     end
-    resources :memberships, :shallow => true, :controller => 'members', :only => [:index, :show, :new, :create, :update, :destroy] do
-      collection do
-        get 'autocomplete'
+    shallow do
+      resources :members, :shallow => true, :controller => 'members', :only => [:index, :show, :new, :create, :update, :destroy] do
+        collection do
+          get 'autocomplete'
+        end
       end
     end
 
     resource :enumerations, :controller => 'project_enumerations', :only => [:update, :destroy]
 
-    match 'issues/:copy_from/copy', :to => 'issues#new'
+    get 'issues/:copy_from/copy', :to => 'issues#new', :as => 'copy_issue'
     resources :issues, :only => [:index, :new, :create] do
       resources :time_entries, :controller => 'timelog' do
         collection do
@@ -121,7 +124,7 @@
       end
     end
     # issue form update
-    match 'issues/new', :controller => 'issues', :action => 'new', :via => [:put, :post], :as => 'issue_form'
+    match 'issues/update_form', :controller => 'issues', :action => 'update_form', :via => [:put, :post], :as => 'issue_form'
 
     resources :files, :only => [:index, :new, :create]
 
@@ -130,26 +133,30 @@
         put 'close_completed'
       end
     end
-    match 'versions.:format', :to => 'versions#index'
-    match 'roadmap', :to => 'versions#index', :format => false
-    match 'versions', :to => 'versions#index'
+    get 'versions.:format', :to => 'versions#index'
+    get 'roadmap', :to => 'versions#index', :format => false
+    get 'versions', :to => 'versions#index'
 
     resources :news, :except => [:show, :edit, :update, :destroy]
     resources :time_entries, :controller => 'timelog' do
       get 'report', :on => :collection
     end
     resources :queries, :only => [:new, :create]
-    resources :issue_categories, :shallow => true
+    shallow do
+      resources :issue_categories
+    end
     resources :documents, :except => [:show, :edit, :update, :destroy]
     resources :boards
-    resources :repositories, :shallow => true, :except => [:index, :show] do
-      member do
-        match 'committers', :via => [:get, :post]
+    shallow do
+      resources :repositories, :except => [:index, :show] do
+        member do
+          match 'committers', :via => [:get, :post]
+        end
       end
     end
-
+  
     match 'wiki/index', :controller => 'wiki', :action => 'index', :via => :get
-    resources :wiki, :except => [:index, :new, :create] do
+    resources :wiki, :except => [:index, :new, :create], :as => 'wiki_page' do
       member do
         get 'rename'
         post 'rename'
@@ -165,7 +172,7 @@
       end
     end
     match 'wiki', :controller => 'wiki', :action => 'show', :via => :get
-    get 'wiki/:id/:version', :to => 'wiki#show'
+    get 'wiki/:id/:version', :to => 'wiki#show', :constraints => {:version => /\d+/}
     delete 'wiki/:id/:version', :to => 'wiki#destroy_version'
     get 'wiki/:id/:version/annotate', :to => 'wiki#annotate'
     get 'wiki/:id/:version/diff', :to => 'wiki#diff'
@@ -181,7 +188,9 @@
         get 'report'
       end
     end
-    resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
+    shallow do
+      resources :relations, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
+    end
   end
   match '/issues', :controller => 'issues', :action => 'destroy', :via => :delete
 
@@ -202,7 +211,7 @@
     post 'add_attachment', :on => :member
   end
 
-  match '/time_entries/context_menu', :to => 'context_menus#time_entries', :as => :time_entries_context_menu
+  match '/time_entries/context_menu', :to => 'context_menus#time_entries', :as => :time_entries_context_menu, :via => [:get, :post]
 
   resources :time_entries, :controller => 'timelog', :except => :destroy do
     collection do
@@ -215,9 +224,6 @@
   # TODO: delete /time_entries for bulk deletion
   match '/time_entries/destroy', :to => 'timelog#destroy', :via => :delete
 
-  # TODO: port to be part of the resources route(s)
-  match 'projects/:id/settings/:tab', :to => 'projects#settings', :via => :get
-
   get 'projects/:id/activity', :to => 'activities#index'
   get 'projects/:id/activity.:format', :to => 'activities#index'
   get 'activity', :to => 'activities#index'
@@ -271,11 +277,11 @@
   get 'projects/:id/repository', :to => 'repositories#show', :path => nil
 
   # additional routes for having the file name at the end of url
-  match 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/, :via => :get
-  match 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/, :via => :get
-  match 'attachments/download/:id', :controller => 'attachments', :action => 'download', :id => /\d+/, :via => :get
+  get 'attachments/:id/:filename', :to => 'attachments#show', :id => /\d+/, :filename => /.*/, :as => 'named_attachment'
+  get 'attachments/download/:id/:filename', :to => 'attachments#download', :id => /\d+/, :filename => /.*/, :as => 'download_named_attachment'
+  get 'attachments/download/:id', :to => 'attachments#download', :id => /\d+/
+  get 'attachments/thumbnail/:id(/:size)', :to => 'attachments#thumbnail', :id => /\d+/, :size => /\d+/, :as => 'thumbnail'
   match 'attachments/toggle_active/:id', :controller => 'attachments', :action => 'toggle_active', :id => /\d+/, :via => :get
-  match 'attachments/thumbnail/:id(/:size)', :controller => 'attachments', :action => 'thumbnail', :id => /\d+/, :via => :get, :size => /\d+/
   resources :attachments, :only => [:show, :destroy]
 
   resources :groups do
@@ -322,7 +328,10 @@
 
   resources :auth_sources do
     member do
-      get 'test_connection'
+      get 'test_connection', :as => 'try_connection'
+    end
+    collection do
+      get 'autocomplete_for_new_user'
     end
   end
 
@@ -332,7 +341,7 @@
   match 'workflows/copy', :controller => 'workflows', :action => 'copy', :via => [:get, :post]
   match 'settings', :controller => 'settings', :action => 'index', :via => :get
   match 'settings/edit', :controller => 'settings', :action => 'edit', :via => [:get, :post]
-  match 'settings/plugin/:id', :controller => 'settings', :action => 'plugin', :via => [:get, :post]
+  match 'settings/plugin/:id', :controller => 'settings', :action => 'plugin', :via => [:get, :post], :as => 'plugin_settings'
 
   match 'sys/projects', :to => 'sys#projects', :via => :get
   match 'sys/projects/:id/repository', :to => 'sys#create_project_repository', :via => :post
diff -r 0a574315af3e -r 4f746d8966dd config/settings.yml
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -183,6 +183,9 @@
   - boards
   - calendar
   - gantt
+default_projects_tracker_ids:
+  serialized: true
+  default: 
 # Role given to a non-admin user who creates a project
 new_project_user_role_id:
   format: int
@@ -215,6 +218,8 @@
   default: ''
 rest_api_enabled:
   default: 0
+jsonp_enabled:
+  default: 0
 default_notification_option:
   default: 'only_my_events'
 emails_header:
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/001_setup.rb
--- a/db/migrate/001_setup.rb
+++ b/db/migrate/001_setup.rb
@@ -1,4 +1,4 @@
-# redMine - project management software
+# Redmine - project management software
 # Copyright (C) 2006  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
@@ -292,7 +292,6 @@
                        :lastname => "Admin",
                        :mail => "admin@example.net",
                        :mail_notification => true,
-                       :language => "en",
                        :status => 1
   end
 
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/002_issue_move.rb
--- a/db/migrate/002_issue_move.rb
+++ b/db/migrate/002_issue_move.rb
@@ -7,6 +7,6 @@
   end
 
   def self.down
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'move_issues']).destroy
+    Permission.where("controller=? and action=?", 'projects', 'move_issues').first.destroy
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/003_issue_add_note.rb
--- a/db/migrate/003_issue_add_note.rb
+++ b/db/migrate/003_issue_add_note.rb
@@ -7,6 +7,6 @@
   end
 
   def self.down
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'issues', 'add_note']).destroy
+    Permission.where("controller=? and action=?", 'issues', 'add_note').first.destroy
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/004_export_pdf.rb
--- a/db/migrate/004_export_pdf.rb
+++ b/db/migrate/004_export_pdf.rb
@@ -8,7 +8,7 @@
   end
 
   def self.down
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'export_issues_pdf']).destroy
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'issues', 'export_pdf']).destroy
+    Permission.where("controller=? and action=?", 'projects', 'export_issues_pdf').first.destroy
+    Permission.where("controller=? and action=?", 'issues', 'export_pdf').first.destroy
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/006_calendar_and_activity.rb
--- a/db/migrate/006_calendar_and_activity.rb
+++ b/db/migrate/006_calendar_and_activity.rb
@@ -9,8 +9,8 @@
   end
 
   def self.down
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'activity']).destroy
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'calendar']).destroy
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'gantt']).destroy
+    Permission.where("controller=? and action=?", 'projects', 'activity').first.destroy
+    Permission.where("controller=? and action=?", 'projects', 'calendar').first.destroy
+    Permission.where("controller=? and action=?", 'projects', 'gantt').first.destroy
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/007_create_journals.rb
--- a/db/migrate/007_create_journals.rb
+++ b/db/migrate/007_create_journals.rb
@@ -28,7 +28,7 @@
     Permission.create :controller => "issues", :action => "history", :description => "label_history", :sort => 1006, :is_public => true, :mail_option => 0, :mail_enabled => 0
 
     # data migration
-    IssueHistory.find(:all, :include => :issue).each {|h|
+    IssueHistory.all.each {|h|
       j = Journal.new(:journalized => h.issue, :user_id => h.author_id, :notes => h.notes, :created_on => h.created_on)
       j.details << JournalDetail.new(:property => 'attr', :prop_key => 'status_id', :value => h.status_id)
       j.save
@@ -51,6 +51,6 @@
 
     add_index "issue_histories", ["issue_id"], :name => "issue_histories_issue_id"
 
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'issues', 'history']).destroy
+    Permission.where("controller=? and action=?", 'issues', 'history').first.destroy
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/012_add_comments_permissions.rb
--- a/db/migrate/012_add_comments_permissions.rb
+++ b/db/migrate/012_add_comments_permissions.rb
@@ -8,7 +8,7 @@
   end
 
   def self.down
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'news', 'add_comment']).destroy
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'news', 'destroy_comment']).destroy
+    Permission.where("controller=? and action=?", 'news', 'add_comment').first.destroy
+    Permission.where("controller=? and action=?", 'news', 'destroy_comment').first.destroy
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/014_add_queries_permissions.rb
--- a/db/migrate/014_add_queries_permissions.rb
+++ b/db/migrate/014_add_queries_permissions.rb
@@ -7,6 +7,6 @@
   end
 
   def self.down
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'add_query']).destroy
+    Permission.where("controller=? and action=?", 'projects', 'add_query').first.destroy
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/016_add_repositories_permissions.rb
--- a/db/migrate/016_add_repositories_permissions.rb
+++ b/db/migrate/016_add_repositories_permissions.rb
@@ -12,11 +12,11 @@
   end
 
   def self.down
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'repositories', 'show']).destroy
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'repositories', 'browse']).destroy
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'repositories', 'entry']).destroy
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'repositories', 'revisions']).destroy
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'repositories', 'revision']).destroy
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'repositories', 'diff']).destroy
+    Permission.where("controller=? and action=?", 'repositories', 'show').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'browse').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'entry').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'revisions').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'revision').first.destroy
+    Permission.where("controller=? and action=?", 'repositories', 'diff').first.destroy
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/019_add_issue_status_position.rb
--- a/db/migrate/019_add_issue_status_position.rb
+++ b/db/migrate/019_add_issue_status_position.rb
@@ -1,7 +1,7 @@
 class AddIssueStatusPosition < ActiveRecord::Migration
   def self.up
     add_column :issue_statuses, :position, :integer, :default => 1
-    IssueStatus.find(:all).each_with_index {|status, i| status.update_attribute(:position, i+1)}
+    IssueStatus.all.each_with_index {|status, i| status.update_attribute(:position, i+1)}
   end
 
   def self.down
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/021_add_tracker_position.rb
--- a/db/migrate/021_add_tracker_position.rb
+++ b/db/migrate/021_add_tracker_position.rb
@@ -1,7 +1,7 @@
 class AddTrackerPosition < ActiveRecord::Migration
   def self.up
     add_column :trackers, :position, :integer, :default => 1
-    Tracker.find(:all).each_with_index {|tracker, i| tracker.update_attribute(:position, i+1)}
+    Tracker.all.each_with_index {|tracker, i| tracker.update_attribute(:position, i+1)}
   end
 
   def self.down
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/022_serialize_possibles_values.rb
--- a/db/migrate/022_serialize_possibles_values.rb
+++ b/db/migrate/022_serialize_possibles_values.rb
@@ -1,6 +1,6 @@
 class SerializePossiblesValues < ActiveRecord::Migration
   def self.up
-    CustomField.find(:all).each do |field|
+    CustomField.all.each do |field|
       if field.possible_values and field.possible_values.is_a? String
         field.possible_values = field.possible_values.split('|')
         field.save
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/024_add_roadmap_permission.rb
--- a/db/migrate/024_add_roadmap_permission.rb
+++ b/db/migrate/024_add_roadmap_permission.rb
@@ -7,6 +7,6 @@
   end
 
   def self.down
-    Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'roadmap']).destroy
+    Permission.where("controller=? and action=?", 'projects', 'roadmap').first.destroy
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/065_add_settings_updated_on.rb
--- a/db/migrate/065_add_settings_updated_on.rb
+++ b/db/migrate/065_add_settings_updated_on.rb
@@ -2,7 +2,7 @@
   def self.up
     add_column :settings, :updated_on, :timestamp
     # set updated_on
-    Setting.find(:all).each(&:save)
+    Setting.all.each(&:save)
   end
 
   def self.down
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/068_create_enabled_modules.rb
--- a/db/migrate/068_create_enabled_modules.rb
+++ b/db/migrate/068_create_enabled_modules.rb
@@ -7,7 +7,7 @@
     add_index :enabled_modules, [:project_id], :name => :enabled_modules_project_id
 
     # Enable all modules for existing projects
-    Project.find(:all).each do |project|
+    Project.all.each do |project|
       project.enabled_module_names = Redmine::AccessControl.available_project_modules
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/072_add_enumerations_position.rb
--- a/db/migrate/072_add_enumerations_position.rb
+++ b/db/migrate/072_add_enumerations_position.rb
@@ -1,7 +1,7 @@
 class AddEnumerationsPosition < ActiveRecord::Migration
   def self.up
     add_column(:enumerations, :position, :integer, :default => 1) unless Enumeration.column_names.include?('position')
-    Enumeration.find(:all).group_by(&:opt).each do |opt, enums|
+    Enumeration.all.group_by(&:opt).each do |opt, enums|
       enums.each_with_index do |enum, i|
         # do not call model callbacks
         Enumeration.update_all "position = #{i+1}", {:id => enum.id}
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/078_add_custom_fields_position.rb
--- a/db/migrate/078_add_custom_fields_position.rb
+++ b/db/migrate/078_add_custom_fields_position.rb
@@ -1,7 +1,7 @@
 class AddCustomFieldsPosition < ActiveRecord::Migration
   def self.up
     add_column(:custom_fields, :position, :integer, :default => 1)
-    CustomField.find(:all).group_by(&:type).each  do |t, fields|
+    CustomField.all.group_by(&:type).each  do |t, fields|
       fields.each_with_index do |field, i|
         # do not call model callbacks
         CustomField.update_all "position = #{i+1}", {:id => field.id}
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/081_create_projects_trackers.rb
--- a/db/migrate/081_create_projects_trackers.rb
+++ b/db/migrate/081_create_projects_trackers.rb
@@ -7,8 +7,8 @@
     add_index :projects_trackers, :project_id, :name => :projects_trackers_project_id
 
     # Associates all trackers to all projects (as it was before)
-    tracker_ids = Tracker.find(:all).collect(&:id)
-    Project.find(:all).each do |project|
+    tracker_ids = Tracker.all.collect(&:id)
+    Project.all.each do |project|
       project.tracker_ids = tracker_ids
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/091_change_changesets_revision_to_string.rb
--- a/db/migrate/091_change_changesets_revision_to_string.rb
+++ b/db/migrate/091_change_changesets_revision_to_string.rb
@@ -1,9 +1,32 @@
 class ChangeChangesetsRevisionToString < ActiveRecord::Migration
   def self.up
+    # Some backends (eg. SQLServer 2012) do not support changing the type
+    # of an indexed column so the index needs to be dropped first
+    # BUT this index is renamed with some backends (at least SQLite3) for
+    # some (unknown) reasons, thus we check for the other name as well
+    # so we don't end up with 2 identical indexes
+    if index_exists? :changesets, [:repository_id, :revision], :name => :changesets_repos_rev
+      remove_index  :changesets, :name => :changesets_repos_rev
+    end
+    if index_exists? :changesets, [:repository_id, :revision], :name => :altered_changesets_repos_rev
+      remove_index  :changesets, :name => :altered_changesets_repos_rev
+    end
+
     change_column :changesets, :revision, :string, :null => false
+
+    add_index :changesets, [:repository_id, :revision], :unique => true, :name => :changesets_repos_rev
   end
 
   def self.down
+    if index_exists? :changesets, :changesets_repos_rev
+      remove_index  :changesets, :name => :changesets_repos_rev
+    end
+    if index_exists? :changesets, [:repository_id, :revision], :name => :altered_changesets_repos_rev
+      remove_index  :changesets, :name => :altered_changesets_repos_rev
+    end
+
     change_column :changesets, :revision, :integer, :null => false
+
+    add_index :changesets, [:repository_id, :revision], :unique => true, :name => :changesets_repos_rev
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/096_add_commit_access_permission.rb
--- a/db/migrate/096_add_commit_access_permission.rb
+++ b/db/migrate/096_add_commit_access_permission.rb
@@ -1,12 +1,12 @@
 class AddCommitAccessPermission < ActiveRecord::Migration
   def self.up
-    Role.find(:all).select { |r| not r.builtin? }.each do |r|
+    Role.all.select { |r| not r.builtin? }.each do |r|
       r.add_permission!(:commit_access)
     end
   end
 
   def self.down
-    Role.find(:all).select { |r| not r.builtin? }.each do |r|
+    Role.all.select { |r| not r.builtin? }.each do |r|
       r.remove_permission!(:commit_access)
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/097_add_view_wiki_edits_permission.rb
--- a/db/migrate/097_add_view_wiki_edits_permission.rb
+++ b/db/migrate/097_add_view_wiki_edits_permission.rb
@@ -1,12 +1,12 @@
 class AddViewWikiEditsPermission < ActiveRecord::Migration
   def self.up
-    Role.find(:all).each do |r|
+    Role.all.each do |r|
       r.add_permission!(:view_wiki_edits) if r.has_permission?(:view_wiki_pages)
     end
   end
 
   def self.down
-    Role.find(:all).each do |r|
+    Role.all.each do |r|
       r.remove_permission!(:view_wiki_edits)
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/099_add_delete_wiki_pages_attachments_permission.rb
--- a/db/migrate/099_add_delete_wiki_pages_attachments_permission.rb
+++ b/db/migrate/099_add_delete_wiki_pages_attachments_permission.rb
@@ -1,12 +1,12 @@
 class AddDeleteWikiPagesAttachmentsPermission < ActiveRecord::Migration
   def self.up
-    Role.find(:all).each do |r|
+    Role.all.each do |r|
       r.add_permission!(:delete_wiki_pages_attachments) if r.has_permission?(:edit_wiki_pages)
     end
   end
 
   def self.down
-    Role.find(:all).each do |r|
+    Role.all.each do |r|
       r.remove_permission!(:delete_wiki_pages_attachments)
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20090312194159_add_projects_trackers_unique_index.rb
--- a/db/migrate/20090312194159_add_projects_trackers_unique_index.rb
+++ b/db/migrate/20090312194159_add_projects_trackers_unique_index.rb
@@ -10,7 +10,7 @@
 
   # Removes duplicates in projects_trackers table
   def self.remove_duplicates
-    Project.find(:all).each do |project|
+    Project.all.each do |project|
       ids = project.trackers.collect(&:id)
       unless ids == ids.uniq
         project.trackers.clear
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20090503121505_populate_member_roles.rb
--- a/db/migrate/20090503121505_populate_member_roles.rb
+++ b/db/migrate/20090503121505_populate_member_roles.rb
@@ -1,7 +1,7 @@
 class PopulateMemberRoles < ActiveRecord::Migration
   def self.up
     MemberRole.delete_all
-    Member.find(:all).each do |member|
+    Member.all.each do |member|
       MemberRole.create!(:member_id => member.id, :role_id => member.role_id)
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20091114105931_add_view_issues_permission.rb
--- a/db/migrate/20091114105931_add_view_issues_permission.rb
+++ b/db/migrate/20091114105931_add_view_issues_permission.rb
@@ -1,12 +1,12 @@
 class AddViewIssuesPermission < ActiveRecord::Migration
   def self.up
-    Role.find(:all).each do |r|
+    Role.all.each do |r|
       r.add_permission!(:view_issues)
     end
   end
 
   def self.down
-    Role.find(:all).each do |r|
+    Role.all.each do |r|
       r.remove_permission!(:view_issues)
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb
--- a/db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb
+++ b/db/migrate/20100819172912_enable_calendar_and_gantt_modules_where_appropriate.rb
@@ -1,6 +1,6 @@
 class EnableCalendarAndGanttModulesWhereAppropriate < ActiveRecord::Migration
   def self.up
-    EnabledModule.find(:all, :conditions => ["name = ?", 'issue_tracking']).each do |e|
+    EnabledModule.where(:name => 'issue_tracking').all.each do |e|
       EnabledModule.create(:name => 'calendar', :project_id => e.project_id)
       EnabledModule.create(:name => 'gantt', :project_id => e.project_id)
     end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20121209123234_add_queries_type.rb
--- /dev/null
+++ b/db/migrate/20121209123234_add_queries_type.rb
@@ -0,0 +1,9 @@
+class AddQueriesType < ActiveRecord::Migration
+  def up
+    add_column :queries, :type, :string
+  end
+
+  def down
+    remove_column :queries, :type
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20121209123358_update_queries_to_sti.rb
--- /dev/null
+++ b/db/migrate/20121209123358_update_queries_to_sti.rb
@@ -0,0 +1,9 @@
+class UpdateQueriesToSti < ActiveRecord::Migration
+  def up
+    ::Query.update_all :type => 'IssueQuery'
+  end
+
+  def down
+    ::Query.update_all :type => nil
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20121213084931_add_attachments_disk_directory.rb
--- /dev/null
+++ b/db/migrate/20121213084931_add_attachments_disk_directory.rb
@@ -0,0 +1,9 @@
+class AddAttachmentsDiskDirectory < ActiveRecord::Migration
+  def up
+    add_column :attachments, :disk_directory, :string
+  end
+
+  def down
+    remove_column :attachments, :disk_directory
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20130110122628_split_documents_permissions.rb
--- /dev/null
+++ b/db/migrate/20130110122628_split_documents_permissions.rb
@@ -0,0 +1,23 @@
+class SplitDocumentsPermissions < ActiveRecord::Migration
+  def up
+    # :manage_documents permission split into 3 permissions:
+    # :add_documents, :edit_documents and :delete_documents
+    Role.all.each do |role|
+      if role.has_permission?(:manage_documents)
+        role.add_permission! :add_documents, :edit_documents, :delete_documents
+        role.remove_permission! :manage_documents
+      end
+    end
+  end
+
+  def down
+    Role.all.each do |role|
+      if role.has_permission?(:add_documents) ||
+          role.has_permission?(:edit_documents) ||
+          role.has_permission?(:delete_documents)
+        role.remove_permission! :add_documents, :edit_documents, :delete_documents
+        role.add_permission! :manage_documents
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20130201184705_add_unique_index_on_tokens_value.rb
--- /dev/null
+++ b/db/migrate/20130201184705_add_unique_index_on_tokens_value.rb
@@ -0,0 +1,15 @@
+class AddUniqueIndexOnTokensValue < ActiveRecord::Migration
+  def up
+    say_with_time "Adding unique index on tokens, this may take some time..." do
+      # Just in case
+      duplicates = Token.connection.select_values("SELECT value FROM #{Token.table_name} GROUP BY value HAVING COUNT(id) > 1")
+      Token.where(:value => duplicates).delete_all
+  
+      add_index :tokens, :value, :unique => true, :name => 'tokens_value'
+    end
+  end
+
+  def down
+    remove_index :tokens, :name => 'tokens_value'
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20130202090625_add_projects_inherit_members.rb
--- /dev/null
+++ b/db/migrate/20130202090625_add_projects_inherit_members.rb
@@ -0,0 +1,9 @@
+class AddProjectsInheritMembers < ActiveRecord::Migration
+  def up
+    add_column :projects, :inherit_members, :boolean, :default => false, :null => false
+  end
+
+  def down
+    remove_column :projects, :inherit_members
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20130207175206_add_unique_index_on_custom_fields_trackers.rb
--- /dev/null
+++ b/db/migrate/20130207175206_add_unique_index_on_custom_fields_trackers.rb
@@ -0,0 +1,24 @@
+class AddUniqueIndexOnCustomFieldsTrackers < ActiveRecord::Migration
+  def up
+    table_name = "#{CustomField.table_name_prefix}custom_fields_trackers#{CustomField.table_name_suffix}"
+    duplicates = CustomField.connection.select_rows("SELECT custom_field_id, tracker_id FROM #{table_name} GROUP BY custom_field_id, tracker_id HAVING COUNT(*) > 1")
+    duplicates.each do |custom_field_id, tracker_id|
+      # Removes duplicate rows
+      CustomField.connection.execute("DELETE FROM #{table_name} WHERE custom_field_id=#{custom_field_id} AND tracker_id=#{tracker_id}")
+      # And insert one
+      CustomField.connection.execute("INSERT INTO #{table_name} (custom_field_id, tracker_id) VALUES (#{custom_field_id}, #{tracker_id})")
+    end
+
+    if index_exists? :custom_fields_trackers, [:custom_field_id, :tracker_id]
+      remove_index :custom_fields_trackers, [:custom_field_id, :tracker_id]
+    end
+    add_index :custom_fields_trackers, [:custom_field_id, :tracker_id], :unique => true
+  end
+
+  def down
+    if index_exists? :custom_fields_trackers, [:custom_field_id, :tracker_id]
+      remove_index :custom_fields_trackers, [:custom_field_id, :tracker_id]
+    end
+    add_index :custom_fields_trackers, [:custom_field_id, :tracker_id]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20130207181455_add_unique_index_on_custom_fields_projects.rb
--- /dev/null
+++ b/db/migrate/20130207181455_add_unique_index_on_custom_fields_projects.rb
@@ -0,0 +1,24 @@
+class AddUniqueIndexOnCustomFieldsProjects < ActiveRecord::Migration
+  def up
+    table_name = "#{CustomField.table_name_prefix}custom_fields_projects#{CustomField.table_name_suffix}"
+    duplicates = CustomField.connection.select_rows("SELECT custom_field_id, project_id FROM #{table_name} GROUP BY custom_field_id, project_id HAVING COUNT(*) > 1")
+    duplicates.each do |custom_field_id, project_id|
+      # Removes duplicate rows
+      CustomField.connection.execute("DELETE FROM #{table_name} WHERE custom_field_id=#{custom_field_id} AND project_id=#{project_id}")
+      # And insert one
+      CustomField.connection.execute("INSERT INTO #{table_name} (custom_field_id, project_id) VALUES (#{custom_field_id}, #{project_id})")
+    end
+
+    if index_exists? :custom_fields_projects, [:custom_field_id, :project_id]
+      remove_index :custom_fields_projects, [:custom_field_id, :project_id]
+    end
+    add_index :custom_fields_projects, [:custom_field_id, :project_id], :unique => true
+  end
+
+  def down
+    if index_exists? :custom_fields_projects, [:custom_field_id, :project_id]
+      remove_index :custom_fields_projects, [:custom_field_id, :project_id]
+    end
+    add_index :custom_fields_projects, [:custom_field_id, :project_id]
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20130215073721_change_users_lastname_length_to_255.rb
--- /dev/null
+++ b/db/migrate/20130215073721_change_users_lastname_length_to_255.rb
@@ -0,0 +1,9 @@
+class ChangeUsersLastnameLengthTo255 < ActiveRecord::Migration
+  def self.up
+    change_column :users, :lastname, :string, :limit => 255, :default => '', :null => false
+  end
+
+  def self.down
+    change_column :users, :lastname, :string, :limit => 30, :default => '', :null => false
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20130215111127_add_issues_closed_on.rb
--- /dev/null
+++ b/db/migrate/20130215111127_add_issues_closed_on.rb
@@ -0,0 +1,9 @@
+class AddIssuesClosedOn < ActiveRecord::Migration
+  def up
+    add_column :issues, :closed_on, :datetime, :default => nil
+  end
+
+  def down
+    remove_column :issues, :closed_on
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20130215111141_populate_issues_closed_on.rb
--- /dev/null
+++ b/db/migrate/20130215111141_populate_issues_closed_on.rb
@@ -0,0 +1,25 @@
+class PopulateIssuesClosedOn < ActiveRecord::Migration
+  def up
+    closed_status_ids = IssueStatus.where(:is_closed => true).pluck(:id)
+    if closed_status_ids.any?
+      # First set closed_on for issues that have been closed once
+      closed_status_values = closed_status_ids.map {|status_id| "'#{status_id}'"}.join(',')
+      subselect = "SELECT MAX(#{Journal.table_name}.created_on)" +
+        " FROM #{Journal.table_name}, #{JournalDetail.table_name}" +
+        " WHERE #{Journal.table_name}.id = #{JournalDetail.table_name}.journal_id" +
+        " AND #{Journal.table_name}.journalized_type = 'Issue' AND #{Journal.table_name}.journalized_id = #{Issue.table_name}.id" +
+        " AND #{JournalDetail.table_name}.property = 'attr' AND #{JournalDetail.table_name}.prop_key = 'status_id'" +
+        " AND #{JournalDetail.table_name}.old_value NOT IN (#{closed_status_values})" +
+        " AND #{JournalDetail.table_name}.value IN (#{closed_status_values})"
+      Issue.update_all "closed_on = (#{subselect})"
+
+      # Then set closed_on for closed issues that weren't up updated by the above UPDATE
+      # No journal was found so we assume that they were closed on creation
+      Issue.update_all "closed_on = created_on", {:status_id => closed_status_ids, :closed_on => nil}
+    end
+  end
+
+  def down
+    Issue.update_all :closed_on => nil
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd db/migrate/20130217094251_remove_issues_default_fk_values.rb
--- /dev/null
+++ b/db/migrate/20130217094251_remove_issues_default_fk_values.rb
@@ -0,0 +1,19 @@
+class RemoveIssuesDefaultFkValues < ActiveRecord::Migration
+  def up
+    change_column_default :issues, :tracker_id, nil
+    change_column_default :issues, :project_id, nil
+    change_column_default :issues, :status_id, nil
+    change_column_default :issues, :assigned_to_id, nil
+    change_column_default :issues, :priority_id, nil
+    change_column_default :issues, :author_id, nil
+  end
+
+  def down
+    change_column_default :issues, :tracker_id, 0
+    change_column_default :issues, :project_id, 0
+    change_column_default :issues, :status_id, 0
+    change_column_default :issues, :assigned_to_id, 0
+    change_column_default :issues, :priority_id, 0
+    change_column_default :issues, :author_id, 0
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd doc/CHANGELOG
--- a/doc/CHANGELOG
+++ b/doc/CHANGELOG
@@ -1,9 +1,143 @@
 == Redmine changelog
 
 Redmine - project management software
-Copyright (C) 2006-2012  Jean-Philippe Lang
+Copyright (C) 2006-2013  Jean-Philippe Lang
 http://www.redmine.org/
 
+== 2013-05-01 v2.3.1
+
+* Defect #12650: Lost text after selection in issue list with IE
+* Defect #12684: Hotkey for Issue-Edit doesn't work as expected
+* Defect #13405: Commit link title is escaped twice when using "commit:" prefix
+* Defect #13541: Can't access SCM when log/production.scm.stderr.log is not writable
+* Defect #13579: Datepicker uses Simplified Chinese in Traditional Chinese locale
+* Defect #13584: Missing Portuguese jQuery UI date picker
+* Defect #13586: Circular loop testing prevents precedes/follows relation between subtasks
+* Defect #13618: CSV export of spent time ignores filters and columns selection
+* Defect #13630: PDF export generates the issue id twice
+* Defect #13644: Diff - Internal Error
+* Defect #13712: Fix email rake tasks to also support no_account_notice and default_group options
+* Defect #13811: Broken javascript in IE7 ; recurrence of #12195
+* Defect #13823: Trailing comma in javascript files
+* Patch #13531: Traditional Chinese translation for 2.3-stable
+* Patch #13552: Dutch translations for 2.3-stable
+* Patch #13678: Lithuanian translation for 2.3-stable
+
+== 2013-03-19 v2.3.0
+
+* Defect #3107: Issue with two digit year on Logtime
+* Defect #3371: Autologin does not work when using openid
+* Defect #3676: www. generates broken link in formatted text
+* Defect #4700: Adding news does not send notification to all project members
+* Defect #5329: Time entries report broken on first week of year
+* Defect #8794: Circular loop when using relations and subtasks
+* Defect #9475: German Translation "My custom queries" and "Custom queries"
+* Defect #9549: Only 100 users are displayed when adding new project members
+* Defect #10277: Redmine wikitext URL-into-link creation with hyphen is wrong
+* Defect #10364: Custom field float separator in CSV export
+* Defect #10930: rake redmine:load_default_data error in 2.0 with SQLServer
+* Defect #10977: Redmine shouldn't require all database gems
+* Defect #12528: Handle temporary failures gracefully in the external mail handler script
+* Defect #12629: Wrong German "label_issues_by" translation
+* Defect #12641: Diff outputs become ??? in some non ASCII words.
+* Defect #12707: Typo in app/models/tracker.rb
+* Defect #12716: Attachment description lost when issue validation fails
+* Defect #12735: Negative duration allowed
+* Defect #12736: Negative start/due dates allowed
+* Defect #12968: Subtasks don't resepect following/precedes
+* Defect #13006: Filter "Assignee's group" doesn't work with group assignments
+* Defect #13022: Image pointing towards /logout signs out user
+* Defect #13059: Custom fields are listed two times in workflow/Fields permission
+* Defect #13076: Project overview page shows trackers from subprojects with disabled issue module
+* Defect #13119: custom_field_values are not reloaded on #reload
+* Defect #13154: After upgrade to 2.2.2 ticket list on some projects fails
+* Defect #13188: Forms are not updated after changing the status field without "Add issues" permission
+* Defect #13251: Adding a "follows" relation may not refresh relations list
+* Defect #13272: translation missing: setting_default_projects_tracker_ids
+* Defect #13328: Copying an issue as a child of itself creates an extra issue
+* Defect #13335: Autologin does not work with custom autologin cookie name
+* Defect #13350: Japanese mistranslation fix
+* Feature #824: Add "closed_on" issue field (storing time of last closing) & add it as a column and filter on the issue list.
+* Feature #1766: Custom fields should become addable to Spent Time list/report
+* Feature #3436: Show relations in Gantt diagram
+* Feature #3957: Ajax file upload with progress bar
+* Feature #5298: Store attachments in sub directories
+* Feature #5605: Subprojects should (optionally) inherit Members from their parent
+* Feature #6727: Add/remove issue watchers via REST API
+* Feature #7159: Bulk watch/unwatch issues from the context menu
+* Feature #8529: Get the API key of the user through REST API
+* Feature #8579: Multiple file upload with HTML5 / Drag-and-Drop
+* Feature #10191: Add Filters For Spent time's Details and Report
+* Feature #10286: Auto-populate fields while creating a new user with LDAP
+* Feature #10352: Preview should already display the freshly attached images
+* Feature #11498: Add --no-account-notice option for the mail handler script
+* Feature #12122: Gantt progress lines (html only)
+* Feature #12228: JRuby 1.7.2 support
+* Feature #12251: Custom fields: 'Multiple values' should be able to be checked and then unchecked
+* Feature #12401: Split "Manage documents" permission into create, edit and delete permissions
+* Feature #12542: Group events in the activity view
+* Feature #12665: Link to a file in a repository branch
+* Feature #12713: Microsoft SQLServer support
+* Feature #12787: Remove "Warning - iconv will be deprecated in the future, use String#encode instead."
+* Feature #12843: Add links to projects in Group projects list
+* Feature #12898: Handle GET /issues/context_menu parameters nicely to prevent returning error 500 to crawlers
+* Feature #12992: Make JSONP support optional and disabled by default
+* Feature #13174: Raise group name maximum length to 255 characters
+* Feature #13175: Possibility to define the default enable trackers when creating a project
+* Feature #13329: Ruby 2.0 support
+* Feature #13337: Split translation "label_total"
+* Feature #13340: Mail handler: option to add created user to default group
+* Feature #13341: Mail handler: --no-notification option to disable notifications to the created user
+* Patch #7202: Polish translation for v1.0.4
+* Patch #7851: Italian translation for 'issue'
+* Patch #9225: Generate project identifier automatically with JavaScript
+* Patch #10916: Optimisation in issues relations display
+* Patch #12485: Don't force english language for default admin account
+* Patch #12499: Use lambda in model scopes
+* Patch #12611: Login link unexpected logs you out
+* Patch #12626: Updated Japanese translations for button_view and permission_commit_access
+* Patch #12640: Russian "about_x_hours" translation change
+* Patch #12645: Russian numeric translation
+* Patch #12660: Consistent German translation for my page
+* Patch #12708: Restructured german translation (Cleanup)
+* Patch #12721: Optimize MenuManager a bit
+* Patch #12725: Change pourcent to percent (#12724)
+* Patch #12754: Updated Japanese translation for notice_account_register_done
+* Patch #12788: Copyright for 2013
+* Patch #12806: Serbian translation change
+* Patch #12810: Swedish Translation change
+* Patch #12910: Plugin settings div should perhaps have 'settings' CSS class
+* Patch #12911: Fix 500 error for requests to the settings path for non-configurable plugins
+* Patch #12926: Bulgarian translation (r11218)
+* Patch #12927: Swedish Translation for r11244
+* Patch #12967: Change Spanish login/logout translations
+* Patch #12988: Russian translation for trunk
+* Patch #13080: German translation of label_in
+* Patch #13098: Small datepicker improvements
+* Patch #13152: Locale file for Azerbaijanian language
+* Patch #13155: Add login to /users/:id API for current user
+* Patch #13173: Put source :rubygems url HTTP secure
+* Patch #13190: Bulgarian translation (r11404)
+* Patch #13198: Traditional Chinese language file (to r11426)
+* Patch #13203: German translation change for follow and precedes is inconsitent
+* Patch #13206: Portuguese translation file
+* Patch #13246: Some german translation patches
+* Patch #13280: German translation (r11478)
+* Patch #13301: Performance: avoid querying all memberships in User#roles_for_project
+* Patch #13309: Add "tracker-[id]" CSS class to issues
+* Patch #13324: fixing some pt-br locales
+* Patch #13339: Complete language Vietnamese file
+* Patch #13391: Czech translation update
+* Patch #13399: Fixed some wrong or confusing translation in Korean locale
+* Patch #13414: Bulgarian translation (r11567)
+* Patch #13420: Korean translation for 2.3 (r11583)
+* Patch #13437: German translation of setting_emails_header
+* Patch #13438: English translation
+* Patch #13447: German translation - some patches
+* Patch #13450: Czech translation
+* Patch #13475: fixing some pt-br locales
+* Patch #13514: fixing some pt-br locales
+
 == 2013-03-19 v2.2.4
 
 * Upgrade to Rails 3.2.13
diff -r 0a574315af3e -r 4f746d8966dd doc/INSTALL
--- a/doc/INSTALL
+++ b/doc/INSTALL
@@ -1,20 +1,21 @@
 == Redmine installation
 
 Redmine - project management software
-Copyright (C) 2006-2012  Jean-Philippe Lang
+Copyright (C) 2006-2013  Jean-Philippe Lang
 http://www.redmine.org/
 
 
 == Requirements
 
-* Ruby 1.8.7, 1.9.2 or 1.9.3
+* Ruby 1.8.7, 1.9.2, 1.9.3 or 2.0.0
 * RubyGems
 * Bundler >= 1.0.21
 
 * A database:
   * MySQL (tested with MySQL 5.1)
   * PostgreSQL (tested with PostgreSQL 9.1)
-  * SQLite3 (tested with SQLite 3.6)
+  * SQLite3 (tested with SQLite 3.7)
+  * SQLServer (tested with SQLServer 2012)
 
 Optional:
 * SCM binaries (e.g. svn, git...), for repository browsing (must be available in PATH)
@@ -24,25 +25,31 @@
 
 1. Uncompress the program archive
 
-2. Install the required gems by running:
+2. Create an empty utf8 encoded database: "redmine" for example
+
+3. Configure the database parameters in config/database.yml
+   for the "production" environment (default database is MySQL and ruby1.9)
+
+   If you're running Redmine with MySQL and ruby1.8, replace the adapter name
+   with `mysql`
+
+4. Install the required gems by running:
      bundle install --without development test
 
    If ImageMagick is not installed on your system, you should skip the installation
    of the rmagick gem using:
      bundle install --without development test rmagick
 
+   Only the gems that are needed by the adapters you've specified in your database
+   configuration file are actually installed (eg. if your config/database.yml
+   uses the 'mysql2' adapter, then only the mysql2 gem will be installed). Don't
+   forget to re-run `bundle install` when you change config/database.yml for using
+   other database adapters.
+
    If you need to load some gems that are not required by Redmine core (eg. fcgi),
    you can create a file named Gemfile.local at the root of your redmine directory.
    It will be loaded automatically when running `bundle install`.
 
-3. Create an empty utf8 encoded database: "redmine" for example
-
-4. Configure the database parameters in config/database.yml
-   for the "production" environment (default database is MySQL and ruby1.8)
-
-   If you're running Redmine with MySQL and ruby1.9, replace the adapter name
-   with `mysql2`
-
 5. Generate a session store secret
    
    Redmine stores session data in cookies by default, which requires
diff -r 0a574315af3e -r 4f746d8966dd doc/README_FOR_APP
--- a/doc/README_FOR_APP
+++ b/doc/README_FOR_APP
@@ -6,7 +6,7 @@
 
 = License
 
-Copyright (C) 2006-2012  Jean-Philippe Lang
+Copyright (C) 2006-2013  Jean-Philippe Lang
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd doc/RUNNING_TESTS
--- a/doc/RUNNING_TESTS
+++ b/doc/RUNNING_TESTS
@@ -9,7 +9,7 @@
 
 Run `rake --tasks test` to see available tests.
 Run `rake test` to run the entire test suite (except the tests for the
-Apache perl module Redmine.pm, see below).
+Apache perl module Redmine.pm and Capybara tests, see below).
 
 You can run `ruby test/unit/issue_test.rb` for running a single test case.
 
@@ -58,3 +58,12 @@
 
 If you svn server is not running on localhost, you can use the REDMINE_TEST_DAV_SERVER
 environment variable to specify another host.
+
+Running Capybara tests
+======================
+
+You need to have PhantomJS WebDriver listening on port 4444:
+`phantomjs --webdriver 4444`
+
+Capybara tests can be run with:
+`rake test:ui`
diff -r 0a574315af3e -r 4f746d8966dd doc/UPGRADING
--- a/doc/UPGRADING
+++ b/doc/UPGRADING
@@ -1,7 +1,7 @@
 == Redmine upgrade
 
 Redmine - project management software
-Copyright (C) 2006-2012  Jean-Philippe Lang
+Copyright (C) 2006-2013  Jean-Philippe Lang
 http://www.redmine.org/
 
 
@@ -32,6 +32,16 @@
    of the rmagick gem using:
      bundle install --without development test rmagick
 
+   Only the gems that are needed by the adapters you've specified in your database
+   configuration file are actually installed (eg. if your config/database.yml
+   uses the 'mysql2' adapter, then only the mysql2 gem will be installed). Don't
+   forget to re-run `bundle install` when you change config/database.yml for using
+   other database adapters.
+
+   If you need to load some gems that are not required by Redmine core (eg. fcgi),
+   you can create a file named Gemfile.local at the root of your redmine directory.
+   It will be loaded automatically when running `bundle install`.
+
 6. Generate a session store secret
    
    Redmine stores session data in cookies by default, which requires
diff -r 0a574315af3e -r 4f746d8966dd extra/mail_handler/rdm-mailhandler.rb
--- a/extra/mail_handler/rdm-mailhandler.rb
+++ b/extra/mail_handler/rdm-mailhandler.rb
@@ -23,9 +23,10 @@
 end
 
 class RedmineMailHandler
-  VERSION = '0.2.1'
+  VERSION = '0.2.3'
 
-  attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :no_permission_check, :url, :key, :no_check_certificate
+  attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :default_group, :no_permission_check,
+    :url, :key, :no_check_certificate, :no_account_notice, :no_notification
 
   def initialize
     self.issue_attributes = {}
@@ -40,11 +41,6 @@
       opts.on("-k", "--key KEY",              "Redmine API key") {|v| self.key = v}
       opts.separator("")
       opts.separator("General options:")
-      opts.on("--unknown-user ACTION",        "how to handle emails from an unknown user",
-                                              "ACTION can be one of the following values:",
-                                              "* ignore: email is ignored (default)",
-                                              "* accept: accept as anonymous user",
-                                              "* create: create a user account") {|v| self.unknown_user = v}
       opts.on("--no-permission-check",        "disable permission checking when receiving",
                                               "the email") {self.no_permission_check = '1'}
       opts.on("--key-file FILE",              "path to a file that contains the Redmine",
@@ -56,6 +52,19 @@
       opts.on("-v", "--verbose",              "show extra information") {self.verbose = true}
       opts.on("-V", "--version",              "show version information and exit") {puts VERSION; exit}
       opts.separator("")
+      opts.separator("User creation options:")
+      opts.on("--unknown-user ACTION",        "how to handle emails from an unknown user",
+                                              "ACTION can be one of the following values:",
+                                              "* ignore: email is ignored (default)",
+                                              "* accept: accept as anonymous user",
+                                              "* create: create a user account") {|v| self.unknown_user = v}
+      opts.on("--default-group GROUP",        "add created user to GROUP (none by default)",
+                                              "GROUP can be a comma separated list of groups") { |v| self.default_group = v}
+      opts.on("--no-account-notice",          "don't send account information to the newly",
+                                              "created user") { |v| self.no_account_notice = '1'}
+      opts.on("--no-notification",            "disable email notifications for the created",
+                                              "user") { |v| self.no_notification = '1'}
+      opts.separator("")
       opts.separator("Issue attributes control options:")
       opts.on("-p", "--project PROJECT",      "identifier of the target project") {|v| self.issue_attributes['project'] = v}
       opts.on("-s", "--status STATUS",        "name of the target status") {|v| self.issue_attributes['status'] = v}
@@ -95,11 +104,19 @@
     data = { 'key' => key, 'email' => email,
                            'allow_override' => allow_override,
                            'unknown_user' => unknown_user,
+                           'default_group' => default_group,
+                           'no_account_notice' => no_account_notice,
+                           'no_notification' => no_notification,
                            'no_permission_check' => no_permission_check}
     issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
 
     debug "Posting to #{uri}..."
-    response = Net::HTTPS.post_form(URI.parse(uri), data, headers, :no_check_certificate => no_check_certificate)
+    begin
+      response = Net::HTTPS.post_form(URI.parse(uri), data, headers, :no_check_certificate => no_check_certificate)
+    rescue SystemCallError => e # connection refused, etc.
+      warn "An error occured while contacting your Redmine server: #{e.message}"
+      return 75 # temporary failure
+    end
     debug "Response received: #{response.code}"
 
     case response.code.to_i
diff -r 0a574315af3e -r 4f746d8966dd extra/sample_plugin/test/integration/routing_test.rb
--- a/extra/sample_plugin/test/integration/routing_test.rb
+++ b/extra/sample_plugin/test/integration/routing_test.rb
@@ -1,7 +1,7 @@
 
 require File.expand_path(File.dirname(__FILE__) + '../../../../../test/test_helper')
 
-class SamplePluginRoutingTest < ActionController::IntegrationTest
+class SamplePluginRoutingTest < ActionDispatch::IntegrationTest
   def test_example
     assert_routing(
         { :method => 'get', :path => "/projects/1234/hello" },
diff -r 0a574315af3e -r 4f746d8966dd extra/svn/Redmine.pm
--- a/extra/svn/Redmine.pm
+++ b/extra/svn/Redmine.pm
@@ -388,9 +388,9 @@
     $sth->execute($project_id);
     my $ret = 0;
     if (my @row = $sth->fetchrow_array) {
-    	if ($row[0] eq "1" || $row[0] eq "t") {
-    		$ret = 1;
-    	}
+      if ($row[0] eq "1" || $row[0] eq "t") {
+        $ret = 1;
+      }
     }
     $sth->finish();
     undef $sth;
@@ -467,9 +467,9 @@
       }
 
       unless ($auth_source_id) {
-	  			my $method = $r->method;
+          my $method = $r->method;
           my $salted_password = Digest::SHA::sha1_hex($salt.$pass_digest);
-					if ($hashed_password eq $salted_password && (($access_mode eq "R" && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/) ) {
+          if ($hashed_password eq $salted_password && (($access_mode eq "R" && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/) ) {
               $ret = 1;
               last;
           }
diff -r 0a574315af3e -r 4f746d8966dd lib/generators/redmine_plugin/templates/en_rails_i18n.yml
--- a/lib/generators/redmine_plugin/templates/en_rails_i18n.yml
+++ b/lib/generators/redmine_plugin/templates/en_rails_i18n.yml
@@ -1,3 +1,3 @@
 # English strings go here for Rails i18n
 en:
-  my_label: "My label"
+  # my_label: "My label"
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb
--- a/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb
+++ b/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb
--- a/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb
+++ b/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -78,6 +78,7 @@
           end
           if attachments.is_a?(Array)
             attachments.each do |attachment|
+              next unless attachment.is_a?(Hash)
               a = nil
               if file = attachment['file']
                 next unless file.size > 0
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb
--- a/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb
+++ b/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -32,6 +32,7 @@
                                    :order => "#{CustomField.table_name}.position",
                                    :dependent => :delete_all,
                                    :validate => false
+
           send :include, Redmine::Acts::Customizable::InstanceMethods
           validate :validate_custom_field_values
           after_save :save_custom_field_values
@@ -41,11 +42,11 @@
       module InstanceMethods
         def self.included(base)
           base.extend ClassMethods
+          base.send :alias_method_chain, :reload, :custom_fields
         end
 
         def available_custom_fields
-          CustomField.find(:all, :conditions => "type = '#{self.class.name}CustomField'",
-                                 :order => 'position')
+          CustomField.where("type = '#{self.class.name}CustomField'").sorted.all
         end
 
         # Sets the values of the object's custom fields
@@ -153,6 +154,12 @@
           @custom_field_values_changed = true
         end
 
+        def reload_with_custom_fields(*args)
+          @custom_field_values = nil
+          @custom_field_values_changed = false
+          reload_without_custom_fields(*args)
+        end
+
         module ClassMethods
         end
       end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/acts_as_event/lib/acts_as_event.rb
--- a/lib/plugins/acts_as_event/lib/acts_as_event.rb
+++ b/lib/plugins/acts_as_event/lib/acts_as_event.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -63,6 +63,11 @@
           event_datetime.to_date
         end
 
+        def event_group
+          group = event_options[:group] ? send(event_options[:group]) : self
+          group || self
+        end
+
         def event_url(options = {})
           option = event_options[:url]
           if option.is_a?(Proc)
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/acts_as_list/lib/active_record/acts/list.rb
--- a/lib/plugins/acts_as_list/lib/active_record/acts/list.rb
+++ b/lib/plugins/acts_as_list/lib/active_record/acts/list.rb
@@ -177,17 +177,17 @@
         # Return the next higher item in the list.
         def higher_item
           return nil unless in_list?
-          acts_as_list_class.find(:first, :conditions =>
+          acts_as_list_class.where(
             "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i - 1).to_s}"
-          )
+          ).first
         end
 
         # Return the next lower item in the list.
         def lower_item
           return nil unless in_list?
-          acts_as_list_class.find(:first, :conditions =>
+          acts_as_list_class.where(
             "#{scope_condition} AND #{position_column} = #{(send(position_column).to_i + 1).to_s}"
-          )
+          ).first
         end
 
         # Test if this record is in a list
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb
--- a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb
+++ b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -72,14 +72,8 @@
             tokens = [] << tokens unless tokens.is_a?(Array)
             projects = [] << projects unless projects.nil? || projects.is_a?(Array)
 
-            find_options = {:include => searchable_options[:include]}
-            find_options[:order] = "#{searchable_options[:order_column]} " + (options[:before] ? 'DESC' : 'ASC')
-
             limit_options = {}
             limit_options[:limit] = options[:limit] if options[:limit]
-            if options[:offset]
-              limit_options[:conditions] = "(#{searchable_options[:date_column]} " + (options[:before] ? '<' : '>') + "'#{connection.quoted_date(options[:offset])}')"
-            end
 
             columns = searchable_options[:columns]
             columns = columns[0..0] if options[:titles_only]
@@ -87,10 +81,7 @@
             token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"}
 
             if !options[:titles_only] && searchable_options[:search_custom_fields]
-              searchable_custom_field_ids = CustomField.find(:all,
-                                                             :select => 'id',
-                                                             :conditions => { :type => "#{self.name}CustomField",
-                                                                              :searchable => true }).collect(&:id)
+              searchable_custom_field_ids = CustomField.where(:type => "#{self.name}CustomField", :searchable => true).pluck(:id)
               if searchable_custom_field_ids.any?
                 custom_field_sql = "#{table_name}.id IN (SELECT customized_id FROM #{CustomValue.table_name}" +
                   " WHERE customized_type='#{self.name}' AND customized_id=#{table_name}.id AND LOWER(value) LIKE ?" +
@@ -101,9 +92,9 @@
 
             sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(options[:all_words] ? ' AND ' : ' OR ')
 
-            find_options[:conditions] = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
+            tokens_conditions = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort]
 
-            scope = self
+            scope = self.scoped
             project_conditions = []
             if searchable_options.has_key?(:permission)
               project_conditions << Project.allowed_to_condition(user, searchable_options[:permission] || :view_project)
@@ -120,9 +111,19 @@
             results = []
             results_count = 0
 
-            scope = scope.scoped({:conditions => project_conditions}).scoped(find_options)
-            results_count = scope.count(:all)
-            results = scope.find(:all, limit_options)
+            scope = scope.
+              includes(searchable_options[:include]).
+              order("#{searchable_options[:order_column]} " + (options[:before] ? 'DESC' : 'ASC')).
+              where(project_conditions).
+              where(tokens_conditions)
+
+            results_count = scope.count
+
+            scope_with_limit = scope.limit(options[:limit])
+            if options[:offset]
+              scope_with_limit = scope_with_limit.where("#{searchable_options[:date_column]} #{options[:before] ? '<' : '>'} ?", options[:offset])
+            end
+            results = scope_with_limit.all
 
             [results, results_count]
           end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb
--- a/lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb
+++ b/lib/plugins/acts_as_tree/lib/active_record/acts/tree.rb
@@ -46,17 +46,9 @@
           belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
           has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => configuration[:dependent]
 
-          class_eval <<-EOV
-            include ActiveRecord::Acts::Tree::InstanceMethods
+          scope :roots, where("#{configuration[:foreign_key]} IS NULL").order(configuration[:order])
 
-            def self.roots
-              find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
-            end
-
-            def self.root
-              find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
-            end
-          EOV
+          send :include, ActiveRecord::Acts::Tree::InstanceMethods
         end
       end
 
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb
--- a/lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb
+++ b/lib/plugins/acts_as_versioned/lib/acts_as_versioned.rb
@@ -216,12 +216,12 @@
             has_many :versions, version_association_options do
               # finds earliest version of this record
               def earliest
-                @earliest ||= find(:first, :order => 'version')
+                @earliest ||= order('version').first
               end
 
               # find latest version of this record
               def latest
-                @latest ||= find(:first, :order => 'version desc')
+                @latest ||= order('version desc').first
               end
             end
             before_save  :set_new_version
@@ -248,14 +248,16 @@
             def self.reloadable? ; false ; end
             # find first version before the given version
             def self.before(version)
-              find :first, :order => 'version desc',
-                :conditions => ["#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version]
+              order('version desc').
+                where("#{original_class.versioned_foreign_key} = ? and version < ?", version.send(original_class.versioned_foreign_key), version.version).
+                first
             end
 
             # find first version after the given version.
             def self.after(version)
-              find :first, :order => 'version',
-                :conditions => ["#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version]
+              order('version').
+                where("#{original_class.versioned_foreign_key} = ? and version > ?", version.send(original_class.versioned_foreign_key), version.version).
+                first
             end
 
             def previous
@@ -467,9 +469,9 @@
 
           # Finds versions of a specific model.  Takes an options hash like <tt>find</tt>
           def find_versions(id, options = {})
-            versioned_class.find :all, {
+            versioned_class.all({
               :conditions => ["#{versioned_foreign_key} = ?", id],
-              :order      => 'version' }.merge(options)
+              :order      => 'version' }.merge(options))
           end
 
           # Returns an array of columns that are versioned.  See non_versioned_columns
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb
--- a/lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb
+++ b/lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb
@@ -413,7 +413,7 @@
 
         # on creation, set automatically lft and rgt to the end of the tree
         def set_default_left_and_right
-          highest_right_row = nested_set_scope(:order => "#{quoted_right_column_name} desc").find(:first, :limit => 1,:lock => true )
+          highest_right_row = nested_set_scope(:order => "#{quoted_right_column_name} desc").limit(1).lock(true).first
           maxright = highest_right_row ? (highest_right_row[right_column_name] || 0) : 0
           # adds the new node to the right of all existing nodes
           self[left_column_name] = maxright + 1
@@ -443,11 +443,11 @@
           in_tenacious_transaction do
             reload_nested_set
             # select the rows in the model that extend past the deletion point and apply a lock
-            self.class.base_class.find(:all,
-              :select => "id",
-              :conditions => ["#{quoted_left_column_name} >= ?", left],
-              :lock => true
-            )
+            self.class.base_class.
+              select("id").
+              where("#{quoted_left_column_name} >= ?", left).
+              lock(true).
+              all
 
             if acts_as_nested_set_options[:dependent] == :destroy
               descendants.each do |model|
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/CHANGELOG
--- a/lib/plugins/classic_pagination/CHANGELOG
+++ /dev/null
@@ -1,152 +0,0 @@
-* Exported the changelog of Pagination code for historical reference.
-
-* Imported some patches from Rails Trac (others closed as "wontfix"):
-  #8176, #7325, #7028, #4113. Documentation is much cleaner now and there
-  are some new unobtrusive features!
-
-* Extracted Pagination from Rails trunk (r6795)
-
-#
-# ChangeLog for /trunk/actionpack/lib/action_controller/pagination.rb 
-# 
-# Generated by Trac 0.10.3
-# 05/20/07 23:48:02
-#
-
-09/03/06 23:28:54 david [4953]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	Docs and deprecation
-
-08/07/06 12:40:14 bitsweat [4715]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	Deprecate direct usage of @params. Update ActionView::Base for
-	instance var deprecation.
-
-06/21/06 02:16:11 rick [4476]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	Fix indent in pagination documentation. Closes #4990.  [Kevin Clark]
-
-04/25/06 17:42:48 marcel [4268]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	Remove all remaining references to @params in the documentation.
-
-03/16/06 06:38:08 rick [3899]
-	* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified)
-	trivial documentation patch for #pagination_links [Francois
-	Beausoleil] closes #4258
-
-02/20/06 03:15:22 david [3620]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	* trunk/actionpack/test/activerecord/pagination_test.rb (modified)
-	* trunk/activerecord/CHANGELOG (modified)
-	* trunk/activerecord/lib/active_record/base.rb (modified)
-	* trunk/activerecord/test/base_test.rb (modified)
-	Added :count option to pagination that'll make it possible for the
-	ActiveRecord::Base.count call to using something else than * for the
-	count. Especially important for count queries using DISTINCT #3839
-	[skaes]. Added :select option to Base.count that'll allow you to
-	select something else than * to be counted on. Especially important
-	for count queries using DISTINCT (closes #3839) [skaes].
-
-02/09/06 09:17:40 nzkoz [3553]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	* trunk/actionpack/test/active_record_unit.rb (added)
-	* trunk/actionpack/test/activerecord (added)
-	* trunk/actionpack/test/activerecord/active_record_assertions_test.rb (added)
-	* trunk/actionpack/test/activerecord/pagination_test.rb (added)
-	* trunk/actionpack/test/controller/active_record_assertions_test.rb (deleted)
-	* trunk/actionpack/test/fixtures/companies.yml (added)
-	* trunk/actionpack/test/fixtures/company.rb (added)
-	* trunk/actionpack/test/fixtures/db_definitions (added)
-	* trunk/actionpack/test/fixtures/db_definitions/sqlite.sql (added)
-	* trunk/actionpack/test/fixtures/developer.rb (added)
-	* trunk/actionpack/test/fixtures/developers_projects.yml (added)
-	* trunk/actionpack/test/fixtures/developers.yml (added)
-	* trunk/actionpack/test/fixtures/project.rb (added)
-	* trunk/actionpack/test/fixtures/projects.yml (added)
-	* trunk/actionpack/test/fixtures/replies.yml (added)
-	* trunk/actionpack/test/fixtures/reply.rb (added)
-	* trunk/actionpack/test/fixtures/topic.rb (added)
-	* trunk/actionpack/test/fixtures/topics.yml (added)
-	* Fix pagination problems when using include
-	* Introduce Unit Tests for pagination
-	* Allow count to work with :include by using count distinct.
-
-	[Kevin Clark &amp; Jeremy Hopple]
-
-11/05/05 02:10:29 bitsweat [2878]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	Update paginator docs.  Closes #2744.
-
-10/16/05 15:42:03 minam [2649]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	Update/clean up AP documentation (rdoc)
-
-08/31/05 00:13:10 ulysses [2078]
-	* trunk/actionpack/CHANGELOG (modified)
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	Add option to specify the singular name used by pagination. Closes
-	#1960
-
-08/23/05 14:24:15 minam [2041]
-	* trunk/actionpack/CHANGELOG (modified)
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	Add support for :include with pagination (subject to existing
-	constraints for :include with :limit and :offset) #1478
-	[michael@schubert.cx]
-
-07/15/05 20:27:38 david [1839]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified)
-	More pagination speed #1334 [Stefan Kaes]
-
-07/14/05 08:02:01 david [1832]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified)
-	* trunk/actionpack/test/controller/addresses_render_test.rb (modified)
-	Made pagination faster #1334 [Stefan Kaes]
-
-04/13/05 05:40:22 david [1159]
-	* trunk/actionpack/CHANGELOG (modified)
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	* trunk/activerecord/lib/active_record/base.rb (modified)
-	Fixed pagination to work with joins #1034 [scott@sigkill.org]
-
-04/02/05 09:11:17 david [1067]
-	* trunk/actionpack/CHANGELOG (modified)
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	* trunk/actionpack/lib/action_controller/scaffolding.rb (modified)
-	* trunk/actionpack/lib/action_controller/templates/scaffolds/list.rhtml (modified)
-	* trunk/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb (modified)
-	* trunk/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml (modified)
-	Added pagination for scaffolding (10 items per page) #964
-	[mortonda@dgrmm.net]
-
-03/31/05 14:46:11 david [1048]
-	* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified)
-	Improved the message display on the exception handler pages #963
-	[Johan Sorensen]
-
-03/27/05 00:04:07 david [1017]
-	* trunk/actionpack/CHANGELOG (modified)
-	* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified)
-	Fixed that pagination_helper would ignore :params #947 [Sebastian
-	Kanthak]
-
-03/22/05 13:09:44 david [976]
-	* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified)
-	Fixed documentation and prepared for 0.11.0 release
-
-03/21/05 14:35:36 david [967]
-	* trunk/actionpack/lib/action_controller/pagination.rb (modified)
-	* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (modified)
-	Tweaked the documentation
-
-03/20/05 23:12:05 david [949]
-	* trunk/actionpack/CHANGELOG (modified)
-	* trunk/actionpack/lib/action_controller.rb (modified)
-	* trunk/actionpack/lib/action_controller/pagination.rb (added)
-	* trunk/actionpack/lib/action_view/helpers/pagination_helper.rb (added)
-	* trunk/activesupport/lib/active_support/core_ext/kernel.rb (added)
-	Added pagination support through both a controller and helper add-on
-	#817 [Sam Stephenson]
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/README
--- a/lib/plugins/classic_pagination/README
+++ /dev/null
@@ -1,18 +0,0 @@
-Pagination
-==========
-
-To install:
-
-  script/plugin install svn://errtheblog.com/svn/plugins/classic_pagination
-
-This code was extracted from Rails trunk after the release 1.2.3.
-WARNING: this code is dead. It is unmaintained, untested and full of cruft.
-
-There is a much better pagination plugin called will_paginate.
-Install it like this and glance through the README:
-
-  script/plugin install svn://errtheblog.com/svn/plugins/will_paginate
-
-It doesn't have the same API, but is in fact much nicer. You can
-have both plugins installed until you change your controller/view code that
-handles pagination. Then, simply uninstall classic_pagination.
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/Rakefile
--- a/lib/plugins/classic_pagination/Rakefile
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
-
-desc 'Default: run unit tests.'
-task :default => :test
-
-desc 'Test the classic_pagination plugin.'
-Rake::TestTask.new(:test) do |t|
-  t.libs << 'lib'
-  t.pattern = 'test/**/*_test.rb'
-  t.verbose = true
-end
-
-desc 'Generate documentation for the classic_pagination plugin.'
-Rake::RDocTask.new(:rdoc) do |rdoc|
-  rdoc.rdoc_dir = 'rdoc'
-  rdoc.title    = 'Pagination'
-  rdoc.options << '--line-numbers' << '--inline-source'
-  rdoc.rdoc_files.include('README')
-  rdoc.rdoc_files.include('lib/**/*.rb')
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/init.rb
--- a/lib/plugins/classic_pagination/init.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-#--
-# Copyright (c) 2004-2006 David Heinemeier Hansson
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#++
-
-require 'pagination'
-require 'pagination_helper'
-
-ActionController::Base.class_eval do
-  include ActionController::Pagination
-end
-
-ActionView::Base.class_eval do
-  include ActionView::Helpers::PaginationHelper
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/install.rb
--- a/lib/plugins/classic_pagination/install.rb
+++ /dev/null
@@ -1,1 +0,0 @@
-puts "\n\n" + File.read(File.dirname(__FILE__) + '/README')
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/lib/pagination.rb
--- a/lib/plugins/classic_pagination/lib/pagination.rb
+++ /dev/null
@@ -1,405 +0,0 @@
-module ActionController
-  # === Action Pack pagination for Active Record collections
-  #
-  # The Pagination module aids in the process of paging large collections of
-  # Active Record objects. It offers macro-style automatic fetching of your
-  # model for multiple views, or explicit fetching for single actions. And if
-  # the magic isn't flexible enough for your needs, you can create your own
-  # paginators with a minimal amount of code.
-  #
-  # The Pagination module can handle as much or as little as you wish. In the
-  # controller, have it automatically query your model for pagination; or,
-  # if you prefer, create Paginator objects yourself.
-  #
-  # Pagination is included automatically for all controllers.
-  #
-  # For help rendering pagination links, see 
-  # ActionView::Helpers::PaginationHelper.
-  #
-  # ==== Automatic pagination for every action in a controller
-  #
-  #   class PersonController < ApplicationController   
-  #     model :person
-  #
-  #     paginate :people, :order => 'last_name, first_name',
-  #              :per_page => 20
-  #     
-  #     # ...
-  #   end
-  #
-  # Each action in this controller now has access to a <tt>@people</tt>
-  # instance variable, which is an ordered collection of model objects for the
-  # current page (at most 20, sorted by last name and first name), and a 
-  # <tt>@person_pages</tt> Paginator instance. The current page is determined
-  # by the <tt>params[:page]</tt> variable.
-  #
-  # ==== Pagination for a single action
-  #
-  #   def list
-  #     @person_pages, @people =
-  #       paginate :people, :order => 'last_name, first_name'
-  #   end
-  #
-  # Like the previous example, but explicitly creates <tt>@person_pages</tt>
-  # and <tt>@people</tt> for a single action, and uses the default of 10 items
-  # per page.
-  #
-  # ==== Custom/"classic" pagination 
-  #
-  #   def list
-  #     @person_pages = Paginator.new self, Person.count, 10, params[:page]
-  #     @people = Person.find :all, :order => 'last_name, first_name', 
-  #                           :limit  =>  @person_pages.items_per_page,
-  #                           :offset =>  @person_pages.current.offset
-  #   end
-  # 
-  # Explicitly creates the paginator from the previous example and uses 
-  # Paginator#to_sql to retrieve <tt>@people</tt> from the model.
-  #
-  module Pagination
-    unless const_defined?(:OPTIONS)
-      # A hash holding options for controllers using macro-style pagination
-      OPTIONS = Hash.new
-  
-      # The default options for pagination
-      DEFAULT_OPTIONS = {
-        :class_name => nil,
-        :singular_name => nil,
-        :per_page   => 10,
-        :conditions => nil,
-        :order_by   => nil,
-        :order      => nil,
-        :join       => nil,
-        :joins      => nil,
-        :count      => nil,
-        :include    => nil,
-        :select     => nil,
-        :group      => nil,
-        :parameter  => 'page'
-      }
-    else
-      DEFAULT_OPTIONS[:group] = nil
-    end
-      
-    def self.included(base) #:nodoc:
-      super
-      base.extend(ClassMethods)
-    end
-  
-    def self.validate_options!(collection_id, options, in_action) #:nodoc:
-      options.merge!(DEFAULT_OPTIONS) {|key, old, new| old}
-
-      valid_options = DEFAULT_OPTIONS.keys
-      valid_options << :actions unless in_action
-    
-      unknown_option_keys = options.keys - valid_options
-      raise ActionController::ActionControllerError,
-            "Unknown options: #{unknown_option_keys.join(', ')}" unless
-              unknown_option_keys.empty?
-
-      options[:singular_name] ||= ActiveSupport::Inflector.singularize(collection_id.to_s)
-      options[:class_name]  ||= ActiveSupport::Inflector.camelize(options[:singular_name])
-    end
-
-    # Returns a paginator and a collection of Active Record model instances
-    # for the paginator's current page. This is designed to be used in a
-    # single action; to automatically paginate multiple actions, consider
-    # ClassMethods#paginate.
-    #
-    # +options+ are:
-    # <tt>:singular_name</tt>:: the singular name to use, if it can't be inferred by singularizing the collection name
-    # <tt>:class_name</tt>:: the class name to use, if it can't be inferred by
-    #                        camelizing the singular name
-    # <tt>:per_page</tt>::   the maximum number of items to include in a 
-    #                        single page. Defaults to 10
-    # <tt>:conditions</tt>:: optional conditions passed to Model.find(:all, *params) and
-    #                        Model.count
-    # <tt>:order</tt>::      optional order parameter passed to Model.find(:all, *params)
-    # <tt>:order_by</tt>::   (deprecated, used :order) optional order parameter passed to Model.find(:all, *params)
-    # <tt>:joins</tt>::      optional joins parameter passed to Model.find(:all, *params)
-    #                        and Model.count
-    # <tt>:join</tt>::       (deprecated, used :joins or :include) optional join parameter passed to Model.find(:all, *params)
-    #                        and Model.count
-    # <tt>:include</tt>::    optional eager loading parameter passed to Model.find(:all, *params)
-    #                        and Model.count
-    # <tt>:select</tt>::     :select parameter passed to Model.find(:all, *params)
-    #
-    # <tt>:count</tt>::      parameter passed as :select option to Model.count(*params)
-    #
-    # <tt>:group</tt>::     :group parameter passed to Model.find(:all, *params). It forces the use of DISTINCT instead of plain COUNT to come up with the total number of records
-    #
-    def paginate(collection_id, options={})
-      Pagination.validate_options!(collection_id, options, true)
-      paginator_and_collection_for(collection_id, options)
-    end
-
-    # These methods become class methods on any controller 
-    module ClassMethods
-      # Creates a +before_filter+ which automatically paginates an Active
-      # Record model for all actions in a controller (or certain actions if
-      # specified with the <tt>:actions</tt> option).
-      #
-      # +options+ are the same as PaginationHelper#paginate, with the addition 
-      # of:
-      # <tt>:actions</tt>:: an array of actions for which the pagination is
-      #                     active. Defaults to +nil+ (i.e., every action)
-      def paginate(collection_id, options={})
-        Pagination.validate_options!(collection_id, options, false)
-        module_eval do
-          before_filter :create_paginators_and_retrieve_collections
-          OPTIONS[self] ||= Hash.new
-          OPTIONS[self][collection_id] = options
-        end
-      end
-    end
-
-    def create_paginators_and_retrieve_collections #:nodoc:
-      Pagination::OPTIONS[self.class].each do |collection_id, options|
-        next unless options[:actions].include? action_name if
-          options[:actions]
-
-        paginator, collection = 
-          paginator_and_collection_for(collection_id, options)
-
-        paginator_name = "@#{options[:singular_name]}_pages"
-        self.instance_variable_set(paginator_name, paginator)
-
-        collection_name = "@#{collection_id.to_s}"
-        self.instance_variable_set(collection_name, collection)     
-      end
-    end
-  
-    # Returns the total number of items in the collection to be paginated for
-    # the +model+ and given +conditions+. Override this method to implement a
-    # custom counter.
-    def count_collection_for_pagination(model, options)
-      model.count(:conditions => options[:conditions],
-                  :joins => options[:join] || options[:joins],
-                  :include => options[:include],
-                  :select => (options[:group] ? "DISTINCT #{options[:group]}" : options[:count]))
-    end
-    
-    # Returns a collection of items for the given +model+ and +options[conditions]+,
-    # ordered by +options[order]+, for the current page in the given +paginator+.
-    # Override this method to implement a custom finder.
-    def find_collection_for_pagination(model, options, paginator)
-      model.find(:all, :conditions => options[:conditions],
-                 :order => options[:order_by] || options[:order],
-                 :joins => options[:join] || options[:joins], :include => options[:include],
-                 :select => options[:select], :limit => options[:per_page],
-                 :group => options[:group], :offset => paginator.current.offset)
-    end
-  
-    protected :create_paginators_and_retrieve_collections,
-              :count_collection_for_pagination,
-              :find_collection_for_pagination
-
-    def paginator_and_collection_for(collection_id, options) #:nodoc:
-      klass = options[:class_name].constantize
-      page  = params[options[:parameter]]
-      count = count_collection_for_pagination(klass, options)
-      paginator = Paginator.new(self, count, options[:per_page], page)
-      collection = find_collection_for_pagination(klass, options, paginator)
-    
-      return paginator, collection 
-    end
-      
-    private :paginator_and_collection_for
-
-    # A class representing a paginator for an Active Record collection.
-    class Paginator
-      include Enumerable
-
-      # Creates a new Paginator on the given +controller+ for a set of items
-      # of size +item_count+ and having +items_per_page+ items per page.
-      # Raises ArgumentError if items_per_page is out of bounds (i.e., less
-      # than or equal to zero). The page CGI parameter for links defaults to
-      # "page" and can be overridden with +page_parameter+.
-      def initialize(controller, item_count, items_per_page, current_page=1)
-        raise ArgumentError, 'must have at least one item per page' if
-          items_per_page <= 0
-
-        @controller = controller
-        @item_count = item_count || 0
-        @items_per_page = items_per_page
-        @pages = {}
-        
-        self.current_page = current_page
-      end
-      attr_reader :controller, :item_count, :items_per_page
-      
-      # Sets the current page number of this paginator. If +page+ is a Page
-      # object, its +number+ attribute is used as the value; if the page does 
-      # not belong to this Paginator, an ArgumentError is raised.
-      def current_page=(page)
-        if page.is_a? Page
-          raise ArgumentError, 'Page/Paginator mismatch' unless
-            page.paginator == self
-        end
-        page = page.to_i
-        @current_page_number = has_page_number?(page) ? page : 1
-      end
-
-      # Returns a Page object representing this paginator's current page.
-      def current_page
-        @current_page ||= self[@current_page_number]
-      end
-      alias current :current_page
-
-      # Returns a new Page representing the first page in this paginator.
-      def first_page
-        @first_page ||= self[1]
-      end
-      alias first :first_page
-
-      # Returns a new Page representing the last page in this paginator.
-      def last_page
-        @last_page ||= self[page_count] 
-      end
-      alias last :last_page
-
-      # Returns the number of pages in this paginator.
-      def page_count
-        @page_count ||= @item_count.zero? ? 1 :
-                          (q,r=@item_count.divmod(@items_per_page); r==0? q : q+1)
-      end
-
-      alias length :page_count
-
-      # Returns true if this paginator contains the page of index +number+.
-      def has_page_number?(number)
-        number >= 1 and number <= page_count
-      end
-
-      # Returns a new Page representing the page with the given index
-      # +number+.
-      def [](number)
-        @pages[number] ||= Page.new(self, number)
-      end
-
-      # Successively yields all the paginator's pages to the given block.
-      def each(&block)
-        page_count.times do |n|
-          yield self[n+1]
-        end
-      end
-
-      # A class representing a single page in a paginator.
-      class Page
-        include Comparable
-
-        # Creates a new Page for the given +paginator+ with the index
-        # +number+. If +number+ is not in the range of valid page numbers or
-        # is not a number at all, it defaults to 1.
-        def initialize(paginator, number)
-          @paginator = paginator
-          @number = number.to_i
-          @number = 1 unless @paginator.has_page_number? @number
-        end
-        attr_reader :paginator, :number
-        alias to_i :number
-
-        # Compares two Page objects and returns true when they represent the 
-        # same page (i.e., their paginators are the same and they have the
-        # same page number).
-        def ==(page)
-          return false if page.nil?
-          @paginator == page.paginator and 
-            @number == page.number
-        end
-
-        # Compares two Page objects and returns -1 if the left-hand page comes
-        # before the right-hand page, 0 if the pages are equal, and 1 if the
-        # left-hand page comes after the right-hand page. Raises ArgumentError
-        # if the pages do not belong to the same Paginator object.
-        def <=>(page)
-          raise ArgumentError unless @paginator == page.paginator
-          @number <=> page.number
-        end
-
-        # Returns the item offset for the first item in this page.
-        def offset
-          @paginator.items_per_page * (@number - 1)
-        end
-        
-        # Returns the number of the first item displayed.
-        def first_item
-          offset + 1
-        end
-        
-        # Returns the number of the last item displayed.
-        def last_item
-          [@paginator.items_per_page * @number, @paginator.item_count].min
-        end
-
-        # Returns true if this page is the first page in the paginator.
-        def first?
-          self == @paginator.first
-        end
-
-        # Returns true if this page is the last page in the paginator.
-        def last?
-          self == @paginator.last
-        end
-
-        # Returns a new Page object representing the page just before this
-        # page, or nil if this is the first page.
-        def previous
-          if first? then nil else @paginator[@number - 1] end
-        end
-
-        # Returns a new Page object representing the page just after this
-        # page, or nil if this is the last page.
-        def next
-          if last? then nil else @paginator[@number + 1] end
-        end
-
-        # Returns a new Window object for this page with the specified 
-        # +padding+.
-        def window(padding=2)
-          Window.new(self, padding)
-        end
-
-        # Returns the limit/offset array for this page.
-        def to_sql
-          [@paginator.items_per_page, offset]
-        end
-        
-        def to_param #:nodoc:
-          @number.to_s
-        end
-      end
-
-      # A class for representing ranges around a given page.
-      class Window
-        # Creates a new Window object for the given +page+ with the specified
-        # +padding+.
-        def initialize(page, padding=2)
-          @paginator = page.paginator
-          @page = page
-          self.padding = padding
-        end
-        attr_reader :paginator, :page
-
-        # Sets the window's padding (the number of pages on either side of the
-        # window page).
-        def padding=(padding)
-          @padding = padding < 0 ? 0 : padding
-          # Find the beginning and end pages of the window
-          @first = @paginator.has_page_number?(@page.number - @padding) ?
-            @paginator[@page.number - @padding] : @paginator.first
-          @last =  @paginator.has_page_number?(@page.number + @padding) ?
-            @paginator[@page.number + @padding] : @paginator.last
-        end
-        attr_reader :padding, :first, :last
-
-        # Returns an array of Page objects in the current window.
-        def pages
-          (@first.number..@last.number).to_a.collect! {|n| @paginator[n]}
-        end
-        alias to_a :pages
-      end
-    end
-
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/lib/pagination_helper.rb
--- a/lib/plugins/classic_pagination/lib/pagination_helper.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-module ActionView
-  module Helpers
-    # Provides methods for linking to ActionController::Pagination objects using a simple generator API.  You can optionally
-    # also build your links manually using ActionView::Helpers::AssetHelper#link_to like so:
-    #
-    # <%= link_to "Previous page", { :page => paginator.current.previous } if paginator.current.previous %>
-    # <%= link_to "Next page", { :page => paginator.current.next } if paginator.current.next %>
-    module PaginationHelper
-      unless const_defined?(:DEFAULT_OPTIONS)
-        DEFAULT_OPTIONS = {
-          :name => :page,
-          :window_size => 2,
-          :always_show_anchors => true,
-          :link_to_current_page => false,
-          :params => {}
-        }
-      end
-
-      # Creates a basic HTML link bar for the given +paginator+.  Links will be created
-      # for the next and/or previous page and for a number of other pages around the current
-      # pages position. The +html_options+ hash is passed to +link_to+ when the links are created.
-      #
-      # ==== Options
-      # <tt>:name</tt>::                 the routing name for this paginator
-      #                                  (defaults to +page+)
-      # <tt>:prefix</tt>::               prefix for pagination links
-      #                                  (i.e. Older Pages: 1 2 3 4)
-      # <tt>:suffix</tt>::               suffix for pagination links
-      #                                  (i.e. 1 2 3 4 <- Older Pages)
-      # <tt>:window_size</tt>::          the number of pages to show around 
-      #                                  the current page (defaults to <tt>2</tt>)
-      # <tt>:always_show_anchors</tt>::  whether or not the first and last
-      #                                  pages should always be shown
-      #                                  (defaults to +true+)
-      # <tt>:link_to_current_page</tt>:: whether or not the current page
-      #                                  should be linked to (defaults to
-      #                                  +false+)
-      # <tt>:params</tt>::               any additional routing parameters
-      #                                  for page URLs
-      #
-      # ==== Examples
-      #  # We'll assume we have a paginator setup in @person_pages...
-      #
-      #  pagination_links(@person_pages)
-      #  # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a>  ... <a href="/?page=10/">10</a>
-      #
-      #  pagination_links(@person_pages, :link_to_current_page => true)
-      #  # => <a href="/?page=1/">1</a> <a href="/?page=2/">2</a> <a href="/?page=3/">3</a>  ... <a href="/?page=10/">10</a>
-      #
-      #  pagination_links(@person_pages, :always_show_anchors => false)
-      #  # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> 
-      #
-      #  pagination_links(@person_pages, :window_size => 1)
-      #  # => 1 <a href="/?page=2/">2</a>  ... <a href="/?page=10/">10</a>
-      #
-      #  pagination_links(@person_pages, :params => { :viewer => "flash" })
-      #  # => 1 <a href="/?page=2&amp;viewer=flash/">2</a> <a href="/?page=3&amp;viewer=flash/">3</a>  ... 
-      #  #    <a href="/?page=10&amp;viewer=flash/">10</a>
-      def pagination_links(paginator, options={}, html_options={})
-        name = options[:name] || DEFAULT_OPTIONS[:name]
-        params = (options[:params] || DEFAULT_OPTIONS[:params]).clone
-        
-        prefix = options[:prefix] || ''
-        suffix = options[:suffix] || ''
-
-        pagination_links_each(paginator, options, prefix, suffix) do |n|
-          params[name] = n
-          link_to(n.to_s, params, html_options)
-        end
-      end
-
-      # Iterate through the pages of a given +paginator+, invoking a
-      # block for each page number that needs to be rendered as a link.
-      # 
-      # ==== Options
-      # <tt>:window_size</tt>::          the number of pages to show around 
-      #                                  the current page (defaults to +2+)
-      # <tt>:always_show_anchors</tt>::  whether or not the first and last
-      #                                  pages should always be shown
-      #                                  (defaults to +true+)
-      # <tt>:link_to_current_page</tt>:: whether or not the current page
-      #                                  should be linked to (defaults to
-      #                                  +false+)
-      #
-      # ==== Example
-      #  # Turn paginated links into an Ajax call
-      #  pagination_links_each(paginator, page_options) do |link|
-      #    options = { :url => {:action => 'list'}, :update => 'results' }
-      #    html_options = { :href => url_for(:action => 'list') }
-      #
-      #    link_to_remote(link.to_s, options, html_options)
-      #  end
-      def pagination_links_each(paginator, options, prefix = nil, suffix = nil)
-        options = DEFAULT_OPTIONS.merge(options)
-        link_to_current_page = options[:link_to_current_page]
-        always_show_anchors = options[:always_show_anchors]
-
-        current_page = paginator.current_page
-        window_pages = current_page.window(options[:window_size]).pages
-        return if window_pages.length <= 1 unless link_to_current_page
-        
-        first, last = paginator.first, paginator.last
-        
-        html = ''
-
-        html << prefix if prefix
-
-        if always_show_anchors and not (wp_first = window_pages[0]).first?
-          html << yield(first.number)
-          html << ' ... ' if wp_first.number - first.number > 1
-          html << ' '
-        end
-          
-        window_pages.each do |page|
-          if current_page == page && !link_to_current_page
-            html << page.number.to_s
-          else
-            html << yield(page.number)
-          end
-          html << ' '
-        end
-        
-        if always_show_anchors and not (wp_last = window_pages[-1]).last? 
-          html << ' ... ' if last.number - wp_last.number > 1
-          html << yield(last.number)
-        end
-
-        html << suffix if suffix
-
-        html
-      end
-      
-    end # PaginationHelper
-  end # Helpers
-end # ActionView
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/companies.yml
--- a/lib/plugins/classic_pagination/test/fixtures/companies.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-thirty_seven_signals:
-  id: 1
-  name: 37Signals
-  rating: 4
-
-TextDrive:
-  id: 2
-  name: TextDrive
-  rating: 4
-
-PlanetArgon:
-  id: 3
-  name: Planet Argon
-  rating: 4
-
-Google:
-  id: 4
-  name: Google
-  rating: 4
-  
-Ionist:
-  id: 5
-  name: Ioni.st
-  rating: 4
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/company.rb
--- a/lib/plugins/classic_pagination/test/fixtures/company.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-class Company < ActiveRecord::Base
-  attr_protected :rating
-  set_sequence_name :companies_nonstd_seq
-
-  validates_presence_of :name
-  def validate
-    errors.add('rating', 'rating should not be 2') if rating == 2
-  end  
-end
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/developer.rb
--- a/lib/plugins/classic_pagination/test/fixtures/developer.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class Developer < ActiveRecord::Base
-  has_and_belongs_to_many :projects
-end
-
-class DeVeLoPeR < ActiveRecord::Base
-  self.table_name = "developers"
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/developers.yml
--- a/lib/plugins/classic_pagination/test/fixtures/developers.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-david:
-  id: 1
-  name: David
-  salary: 80000
-
-jamis:
-  id: 2
-  name: Jamis
-  salary: 150000
-
-<% for digit in 3..10 %>
-dev_<%= digit %>:
-  id: <%= digit %>
-  name: fixture_<%= digit %>
-  salary: 100000
-<% end %>
-
-poor_jamis:
-  id: 11
-  name: Jamis
-  salary: 9000
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/developers_projects.yml
--- a/lib/plugins/classic_pagination/test/fixtures/developers_projects.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-david_action_controller:
-  developer_id: 1
-  project_id: 2
-  joined_on: 2004-10-10
-
-david_active_record:
-  developer_id: 1
-  project_id: 1
-  joined_on: 2004-10-10
-
-jamis_active_record:
-  developer_id: 2
-  project_id: 1
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/project.rb
--- a/lib/plugins/classic_pagination/test/fixtures/project.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class Project < ActiveRecord::Base
-  has_and_belongs_to_many :developers, :uniq => true
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/projects.yml
--- a/lib/plugins/classic_pagination/test/fixtures/projects.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-action_controller:
-  id: 2
-  name: Active Controller
-
-active_record:
-  id: 1
-  name: Active Record
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/replies.yml
--- a/lib/plugins/classic_pagination/test/fixtures/replies.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-witty_retort:
-  id: 1
-  topic_id: 1
-  content: Birdman is better!
-  created_at: <%= 6.hours.ago.to_s(:db) %>
-  updated_at: nil
-  
-another:
-  id: 2
-  topic_id: 2
-  content: Nuh uh!
-  created_at: <%= 1.hour.ago.to_s(:db) %>
-  updated_at: nil
\ No newline at end of file
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/reply.rb
--- a/lib/plugins/classic_pagination/test/fixtures/reply.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class Reply < ActiveRecord::Base
-  belongs_to :topic, :include => [:replies]
-  
-  validates_presence_of :content
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/schema.sql
--- a/lib/plugins/classic_pagination/test/fixtures/schema.sql
+++ /dev/null
@@ -1,42 +0,0 @@
-CREATE TABLE 'companies' (
-  'id' INTEGER PRIMARY KEY NOT NULL,
-  'name' TEXT DEFAULT NULL,
-  'rating' INTEGER DEFAULT 1
-);
-
-CREATE TABLE 'replies' (
-  'id' INTEGER PRIMARY KEY NOT NULL, 
-  'content' text, 
-  'created_at' datetime, 
-  'updated_at' datetime, 
-  'topic_id' integer
-);
-
-CREATE TABLE 'topics' (
-  'id' INTEGER PRIMARY KEY NOT NULL, 
-  'title' varchar(255), 
-  'subtitle' varchar(255), 
-  'content' text, 
-  'created_at' datetime, 
-  'updated_at' datetime
-);
-
-CREATE TABLE 'developers' (
-  'id' INTEGER PRIMARY KEY NOT NULL,
-  'name' TEXT DEFAULT NULL,
-  'salary' INTEGER DEFAULT 70000,
-  'created_at' DATETIME DEFAULT NULL,
-  'updated_at' DATETIME DEFAULT NULL
-);
-
-CREATE TABLE 'projects' (
-  'id' INTEGER PRIMARY KEY NOT NULL,
-  'name' TEXT DEFAULT NULL
-);
-
-CREATE TABLE 'developers_projects' (
-  'developer_id' INTEGER NOT NULL,
-  'project_id' INTEGER NOT NULL,
-  'joined_on' DATE DEFAULT NULL,
-  'access_level' INTEGER DEFAULT 1
-);
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/topic.rb
--- a/lib/plugins/classic_pagination/test/fixtures/topic.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class Topic < ActiveRecord::Base
-  has_many :replies, :include => [:user], :dependent => :destroy
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/fixtures/topics.yml
--- a/lib/plugins/classic_pagination/test/fixtures/topics.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-futurama:
-  id: 1
-  title: Isnt futurama awesome?
-  subtitle: It really is, isnt it.
-  content: I like futurama
-  created_at: <%= 1.day.ago.to_s(:db) %>
-  updated_at:
-  
-harvey_birdman:
-  id: 2
-  title: Harvey Birdman is the king of all men
-  subtitle: yup
-  content: It really is
-  created_at: <%= 2.hours.ago.to_s(:db) %>
-  updated_at:
-
-rails:
-  id: 3
-  title: Rails is nice
-  subtitle: It makes me happy
-  content: except when I have to hack internals to fix pagination. even then really.
-  created_at: <%= 20.minutes.ago.to_s(:db) %>
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/helper.rb
--- a/lib/plugins/classic_pagination/test/helper.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-require 'test/unit'
-
-unless defined?(ActiveRecord)
-  plugin_root = File.join(File.dirname(__FILE__), '..')
-
-  # first look for a symlink to a copy of the framework
-  if framework_root = ["#{plugin_root}/rails", "#{plugin_root}/../../rails"].find { |p| File.directory? p }
-    puts "found framework root: #{framework_root}"
-    # this allows for a plugin to be tested outside an app
-    $:.unshift "#{framework_root}/activesupport/lib", "#{framework_root}/activerecord/lib", "#{framework_root}/actionpack/lib"
-  else
-    # is the plugin installed in an application?
-    app_root = plugin_root + '/../../..'
-
-    if File.directory? app_root + '/config'
-      puts 'using config/boot.rb'
-      ENV['RAILS_ENV'] = 'test'
-      require File.expand_path(app_root + '/config/boot')
-    else
-      # simply use installed gems if available
-      puts 'using rubygems'
-      require 'rubygems'
-      gem 'actionpack'; gem 'activerecord'
-    end
-  end
-
-  %w(action_pack active_record action_controller active_record/fixtures action_controller/test_process).each {|f| require f}
-
-  Dependencies.load_paths.unshift "#{plugin_root}/lib"
-end
-
-# Define the connector
-class ActiveRecordTestConnector
-  cattr_accessor :able_to_connect
-  cattr_accessor :connected
-
-  # Set our defaults
-  self.connected = false
-  self.able_to_connect = true
-
-  class << self
-    def setup
-      unless self.connected || !self.able_to_connect
-        setup_connection
-        load_schema
-        require_fixture_models
-        self.connected = true
-      end
-    rescue Exception => e  # errors from ActiveRecord setup
-      $stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}"
-      #$stderr.puts "  #{e.backtrace.join("\n  ")}\n"
-      self.able_to_connect = false
-    end
-
-    private
-
-    def setup_connection
-      if Object.const_defined?(:ActiveRecord)
-        defaults = { :database => ':memory:' }
-        begin
-          options = defaults.merge :adapter => 'sqlite3', :timeout => 500
-          ActiveRecord::Base.establish_connection(options)
-          ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options }
-          ActiveRecord::Base.connection
-        rescue Exception  # errors from establishing a connection
-          $stderr.puts 'SQLite 3 unavailable; trying SQLite 2.'
-          options = defaults.merge :adapter => 'sqlite'
-          ActiveRecord::Base.establish_connection(options)
-          ActiveRecord::Base.configurations = { 'sqlite2_ar_integration' => options }
-          ActiveRecord::Base.connection
-        end
-
-        Object.send(:const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')) unless Object.const_defined?(:QUOTED_TYPE)
-      else
-        raise "Can't setup connection since ActiveRecord isn't loaded."
-      end
-    end
-
-    # Load actionpack sqlite tables
-    def load_schema
-      File.read(File.dirname(__FILE__) + "/fixtures/schema.sql").split(';').each do |sql|
-        ActiveRecord::Base.connection.execute(sql) unless sql.blank?
-      end
-    end
-
-    def require_fixture_models
-      Dir.glob(File.dirname(__FILE__) + "/fixtures/*.rb").each {|f| require f}
-    end
-  end
-end
-
-# Test case for inheritance
-class ActiveRecordTestCase < Test::Unit::TestCase
-  # Set our fixture path
-  if ActiveRecordTestConnector.able_to_connect
-    self.fixture_path = "#{File.dirname(__FILE__)}/fixtures/"
-    self.use_transactional_fixtures = false
-  end
-
-  def self.fixtures(*args)
-    super if ActiveRecordTestConnector.connected
-  end
-
-  def run(*args)
-    super if ActiveRecordTestConnector.connected
-  end
-
-  # Default so Test::Unit::TestCase doesn't complain
-  def test_truth
-  end
-end
-
-ActiveRecordTestConnector.setup
-ActionController::Routing::Routes.reload rescue nil
-ActionController::Routing::Routes.draw do |map|
-  map.connect ':controller/:action/:id'
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/pagination_helper_test.rb
--- a/lib/plugins/classic_pagination/test/pagination_helper_test.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require File.dirname(__FILE__) + '/helper'
-require File.dirname(__FILE__) + '/../init'
-
-class PaginationHelperTest < Test::Unit::TestCase
-  include ActionController::Pagination
-  include ActionView::Helpers::PaginationHelper
-  include ActionView::Helpers::UrlHelper
-  include ActionView::Helpers::TagHelper
-
-  def setup
-    @controller = Class.new do
-      attr_accessor :url, :request
-      def url_for(options, *parameters_for_method_reference)
-        url
-      end
-    end
-    @controller = @controller.new
-    @controller.url = "http://www.example.com"
-  end
-
-  def test_pagination_links
-    total, per_page, page = 30, 10, 1
-    output = pagination_links Paginator.new(@controller, total, per_page, page)
-    assert_equal "1 <a href=\"http://www.example.com\">2</a> <a href=\"http://www.example.com\">3</a> ", output
-  end
-
-  def test_pagination_links_with_prefix
-    total, per_page, page = 30, 10, 1
-    output = pagination_links Paginator.new(@controller, total, per_page, page), :prefix => 'Newer '
-    assert_equal "Newer 1 <a href=\"http://www.example.com\">2</a> <a href=\"http://www.example.com\">3</a> ", output
-  end
-
-  def test_pagination_links_with_suffix
-    total, per_page, page = 30, 10, 1
-    output = pagination_links Paginator.new(@controller, total, per_page, page), :suffix => 'Older'
-    assert_equal "1 <a href=\"http://www.example.com\">2</a> <a href=\"http://www.example.com\">3</a> Older", output
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/classic_pagination/test/pagination_test.rb
--- a/lib/plugins/classic_pagination/test/pagination_test.rb
+++ /dev/null
@@ -1,177 +0,0 @@
-require File.dirname(__FILE__) + '/helper'
-require File.dirname(__FILE__) + '/../init'
-
-class PaginationTest < ActiveRecordTestCase
-  fixtures :topics, :replies, :developers, :projects, :developers_projects
-  
-  class PaginationController < ActionController::Base
-    if respond_to? :view_paths=
-      self.view_paths = [ "#{File.dirname(__FILE__)}/../fixtures/" ]
-    else
-      self.template_root = [ "#{File.dirname(__FILE__)}/../fixtures/" ]
-    end
-    
-    def simple_paginate
-      @topic_pages, @topics = paginate(:topics)
-      render :nothing => true
-    end
-    
-    def paginate_with_per_page
-      @topic_pages, @topics = paginate(:topics, :per_page => 1)
-      render :nothing => true
-    end
-    
-    def paginate_with_order
-      @topic_pages, @topics = paginate(:topics, :order => 'created_at asc')
-      render :nothing => true
-    end
-    
-    def paginate_with_order_by
-      @topic_pages, @topics = paginate(:topics, :order_by => 'created_at asc')
-      render :nothing => true
-    end
-    
-    def paginate_with_include_and_order
-      @topic_pages, @topics = paginate(:topics, :include => :replies, :order => 'replies.created_at asc, topics.created_at asc')
-      render :nothing => true
-    end
-    
-    def paginate_with_conditions
-      @topic_pages, @topics = paginate(:topics, :conditions => ["created_at > ?", 30.minutes.ago])
-      render :nothing => true
-    end
-    
-    def paginate_with_class_name
-      @developer_pages, @developers = paginate(:developers, :class_name => "DeVeLoPeR")
-      render :nothing => true
-    end
-    
-    def paginate_with_singular_name
-      @developer_pages, @developers = paginate()
-      render :nothing => true
-    end
-    
-    def paginate_with_joins
-      @developer_pages, @developers = paginate(:developers, 
-                                             :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
-                                             :conditions => 'project_id=1')        
-      render :nothing => true
-    end
-    
-    def paginate_with_join
-      @developer_pages, @developers = paginate(:developers, 
-                                             :join => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
-                                             :conditions => 'project_id=1')        
-      render :nothing => true
-    end
-     
-    def paginate_with_join_and_count
-      @developer_pages, @developers = paginate(:developers, 
-                                             :join => 'd LEFT JOIN developers_projects ON d.id = developers_projects.developer_id',
-                                             :conditions => 'project_id=1',
-                                             :count => "d.id")        
-      render :nothing => true
-    end
-
-    def paginate_with_join_and_group
-      @developer_pages, @developers = paginate(:developers, 
-                                             :join => 'INNER JOIN developers_projects ON developers.id = developers_projects.developer_id',
-                                             :group => 'developers.id')
-      render :nothing => true
-    end
-    
-    def rescue_errors(e) raise e end
-
-    def rescue_action(e) raise end
-    
-  end
-  
-  def setup
-    @controller = PaginationController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-    super
-  end
-
-  # Single Action Pagination Tests
-
-  def test_simple_paginate
-    get :simple_paginate
-    assert_equal 1, assigns(:topic_pages).page_count
-    assert_equal 3, assigns(:topics).size
-  end
-  
-  def test_paginate_with_per_page
-    get :paginate_with_per_page
-    assert_equal 1, assigns(:topics).size
-    assert_equal 3, assigns(:topic_pages).page_count
-  end
-  
-  def test_paginate_with_order
-    get :paginate_with_order
-    expected = [topics(:futurama),
-               topics(:harvey_birdman),
-               topics(:rails)]
-    assert_equal expected, assigns(:topics)
-    assert_equal 1, assigns(:topic_pages).page_count
-  end
-  
-  def test_paginate_with_order_by
-    get :paginate_with_order
-    expected = assigns(:topics)
-    get :paginate_with_order_by
-    assert_equal expected, assigns(:topics)  
-    assert_equal 1, assigns(:topic_pages).page_count    
-  end
-  
-  def test_paginate_with_conditions
-    get :paginate_with_conditions
-    expected = [topics(:rails)]
-    assert_equal expected, assigns(:topics)
-    assert_equal 1, assigns(:topic_pages).page_count
-  end
-  
-  def test_paginate_with_class_name
-    get :paginate_with_class_name
-    
-    assert assigns(:developers).size > 0
-    assert_equal DeVeLoPeR, assigns(:developers).first.class
-  end
-      
-  def test_paginate_with_joins
-    get :paginate_with_joins
-    assert_equal 2, assigns(:developers).size
-    developer_names = assigns(:developers).map { |d| d.name }
-    assert developer_names.include?('David')
-    assert developer_names.include?('Jamis')
-  end
-  
-  def test_paginate_with_join_and_conditions
-    get :paginate_with_joins
-    expected = assigns(:developers)
-    get :paginate_with_join
-    assert_equal expected, assigns(:developers)
-  end
-  
-  def test_paginate_with_join_and_count
-    get :paginate_with_joins
-    expected = assigns(:developers)
-    get :paginate_with_join_and_count
-    assert_equal expected, assigns(:developers)
-  end
-  
-  def test_paginate_with_include_and_order
-    get :paginate_with_include_and_order
-    expected = Topic.find(:all, :include => 'replies', :order => 'replies.created_at asc, topics.created_at asc', :limit => 10)
-    assert_equal expected, assigns(:topics)
-  end
-
-  def test_paginate_with_join_and_group
-    get :paginate_with_join_and_group
-    assert_equal 2, assigns(:developers).size
-    assert_equal 2, assigns(:developer_pages).item_count
-    developer_names = assigns(:developers).map { |d| d.name }
-    assert developer_names.include?('David')
-    assert developer_names.include?('Jamis')
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/plugins/rfpdf/lib/tcpdf.rb
--- a/lib/plugins/rfpdf/lib/tcpdf.rb
+++ b/lib/plugins/rfpdf/lib/tcpdf.rb
@@ -39,9 +39,6 @@
 # @package com.tecnick.tcpdf
 #
  
-@@version = "1.53.0.TC031"
-@@fpdf_charwidths = {}
-
 PDF_PRODUCER = 'TCPDF via RFPDF 1.53.0.TC031 (http://tcpdf.sourceforge.net)'
 
 module TCPDFFontDescriptor
@@ -79,6 +76,9 @@
     Rails.logger
   end
 
+  @@version = "1.53.0.TC031"
+  @@fpdf_charwidths = {}
+
   cattr_accessor :k_cell_height_ratio
   @@k_cell_height_ratio = 1.25
 
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine.rb
--- a/lib/redmine.rb
+++ b/lib/redmine.rb
@@ -1,16 +1,21 @@
-require 'redmine/access_control'
-require 'redmine/menu_manager'
-require 'redmine/activity'
-require 'redmine/search'
-require 'redmine/custom_field_format'
-require 'redmine/mime_type'
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require 'redmine/core_ext'
-require 'redmine/themes'
-require 'redmine/hook'
-require 'redmine/plugin'
-require 'redmine/notifiable'
-require 'redmine/wiki_formatting'
-require 'redmine/scm/base'
 
 begin
   require 'RMagick' unless Object.const_defined?(:Magick)
@@ -18,6 +23,41 @@
   # RMagick is not available
 end
 
+require 'redmine/scm/base'
+require 'redmine/access_control'
+require 'redmine/access_keys'
+require 'redmine/activity'
+require 'redmine/activity/fetcher'
+require 'redmine/ciphering'
+require 'redmine/codeset_util'
+require 'redmine/custom_field_format'
+require 'redmine/i18n'
+require 'redmine/menu_manager'
+require 'redmine/notifiable'
+require 'redmine/platform'
+require 'redmine/mime_type'
+require 'redmine/notifiable'
+require 'redmine/search'
+require 'redmine/syntax_highlighting'
+require 'redmine/thumbnail'
+require 'redmine/unified_diff'
+require 'redmine/utils'
+require 'redmine/version'
+require 'redmine/wiki_formatting'
+
+require 'redmine/default_data/loader'
+require 'redmine/helpers/calendar'
+require 'redmine/helpers/diff'
+require 'redmine/helpers/gantt'
+require 'redmine/helpers/time_report'
+require 'redmine/views/other_formats_builder'
+require 'redmine/views/labelled_form_builder'
+require 'redmine/views/builders'
+
+require 'redmine/themes'
+require 'redmine/hook'
+require 'redmine/plugin'
+
 if RUBY_VERSION < '1.9'
   require 'fastercsv'
 else
@@ -75,7 +115,7 @@
     map.permission :manage_subtasks, {}
     map.permission :set_issues_private, {}
     map.permission :set_own_issues_private, {}, :require => :loggedin
-    map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new], :attachments => :upload}
+    map.permission :add_issue_notes, {:issues => [:edit, :update, :update_form], :journals => [:new], :attachments => :upload}
     map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
     map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
     map.permission :view_private_notes, {}, :read => true, :require => :member
@@ -87,7 +127,7 @@
     map.permission :save_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
     # Watchers
     map.permission :view_issue_watchers, {}, :read => true
-    map.permission :add_issue_watchers, {:watchers => :new}
+    map.permission :add_issue_watchers, {:watchers => [:new, :create, :append, :autocomplete_for_user]}
     map.permission :delete_issue_watchers, {:watchers => :destroy}
   end
 
@@ -106,7 +146,9 @@
   end
 
   map.project_module :documents do |map|
-    map.permission :manage_documents, {:documents => [:new, :create, :edit, :update, :destroy, :add_attachment]}, :require => :loggedin
+    map.permission :add_documents, {:documents => [:new, :create, :add_attachment]}, :require => :loggedin
+    map.permission :edit_documents, {:documents => [:edit, :update, :add_attachment]}, :require => :loggedin
+    map.permission :delete_documents, {:documents => [:destroy]}, :require => :loggedin
     map.permission :view_documents, {:documents => [:index, :show, :download]}, :read => true
   end
 
@@ -166,7 +208,7 @@
   menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
   menu.push :register, :register_path, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
   menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
-  menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
+  menu.push :logout, :signout_path, :html => {:method => 'post'}, :if => Proc.new { User.current.logged? }
 end
 
 Redmine::MenuManager.map :application_menu do |menu|
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/about.rb
--- a/lib/redmine/about.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Redmine
-  class About
-    def self.print_plugin_info
-      plugins = Redmine::Plugin.registered_plugins
-
-      if !plugins.empty?
-        column_with = plugins.map {|internal_name, plugin| plugin.name.length}.max
-        puts "\nAbout your Redmine plugins"
-
-        plugins.each do |internal_name, plugin|
-          puts sprintf("%-#{column_with}s   %s", plugin.name, plugin.version)
-        end
-      end
-    end
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/access_control.rb
--- a/lib/redmine/access_control.rb
+++ b/lib/redmine/access_control.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/access_keys.rb
--- a/lib/redmine/access_keys.rb
+++ b/lib/redmine/access_keys.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/activity.rb
--- a/lib/redmine/activity.rb
+++ b/lib/redmine/activity.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/activity/fetcher.rb
--- a/lib/redmine/activity/fetcher.rb
+++ b/lib/redmine/activity/fetcher.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/ciphering.rb
--- a/lib/redmine/ciphering.rb
+++ b/lib/redmine/ciphering.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/codeset_util.rb
--- a/lib/redmine/codeset_util.rb
+++ b/lib/redmine/codeset_util.rb
@@ -1,4 +1,6 @@
-require 'iconv'
+if RUBY_VERSION < '1.9'
+  require 'iconv'
+end
 
 module Redmine
   module CodesetUtil
@@ -100,10 +102,20 @@
       end
       encodings = Setting.repositories_encodings.split(',').collect(&:strip)
       encodings.each do |encoding|
-        begin
-          return Iconv.conv('UTF-8', encoding, str)
-        rescue Iconv::Failure
-          # do nothing here and try the next encoding
+        if str.respond_to?(:force_encoding)
+          begin
+            str.force_encoding(encoding)
+            utf8 = str.encode('UTF-8')
+            return utf8 if utf8.valid_encoding?
+          rescue
+            # do nothing here and try the next encoding
+          end
+        else
+          begin
+            return Iconv.conv('UTF-8', encoding, str)
+          rescue Iconv::Failure
+            # do nothing here and try the next encoding
+          end
         end
       end
       str = self.replace_invalid_utf8(str)
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/configuration.rb
--- a/lib/redmine/configuration.rb
+++ b/lib/redmine/configuration.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -20,7 +20,8 @@
 
     # Configuration default values
     @defaults = {
-      'email_delivery' => nil
+      'email_delivery' => nil,
+      'max_concurrent_ajax_uploads' => 2
     }
 
     @config = nil
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/core_ext/active_record.rb
--- a/lib/redmine/core_ext/active_record.rb
+++ b/lib/redmine/core_ext/active_record.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -38,3 +38,15 @@
     end
   end
 end
+
+class DateValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    before_type_cast = record.attributes_before_type_cast[attribute.to_s]
+    if before_type_cast.is_a?(String) && before_type_cast.present?
+      # TODO: #*_date_before_type_cast returns a Mysql::Time with ruby1.8+mysql gem
+      unless before_type_cast =~ /\A\d{4}-\d{2}-\d{2}( 00:00:00)?\z/ && value
+        record.errors.add attribute, :not_a_date
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/core_ext/date/calculations.rb
--- a/lib/redmine/core_ext/date/calculations.rb
+++ b/lib/redmine/core_ext/date/calculations.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/core_ext/string/conversions.rb
--- a/lib/redmine/core_ext/string/conversions.rb
+++ b/lib/redmine/core_ext/string/conversions.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/core_ext/string/inflections.rb
--- a/lib/redmine/core_ext/string/inflections.rb
+++ b/lib/redmine/core_ext/string/inflections.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/custom_field_format.rb
--- a/lib/redmine/custom_field_format.rb
+++ b/lib/redmine/custom_field_format.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/default_data/loader.rb
--- a/lib/redmine/default_data/loader.rb
+++ b/lib/redmine/default_data/loader.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -26,10 +26,10 @@
         # Returns true if no data is already loaded in the database
         # otherwise false
         def no_data?
-          !Role.find(:first, :conditions => {:builtin => 0}) &&
-            !Tracker.find(:first) &&
-            !IssueStatus.find(:first) &&
-            !Enumeration.find(:first)
+          !Role.where(:builtin => 0).exists? &&
+            !Tracker.exists? &&
+            !IssueStatus.exists? &&
+            !Enumeration.exists?
         end
 
         # Loads the default data
@@ -139,15 +139,15 @@
             rejected  = IssueStatus.create!(:name => l(:default_issue_status_rejected), :is_closed => true, :is_default => false, :position => 6)
 
             # Workflow
-            Tracker.find(:all).each { |t|
-              IssueStatus.find(:all).each { |os|
-                IssueStatus.find(:all).each { |ns|
+            Tracker.all.each { |t|
+              IssueStatus.all.each { |os|
+                IssueStatus.all.each { |ns|
                   WorkflowTransition.create!(:tracker_id => t.id, :role_id => manager.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
                 }
               }
             }
 
-            Tracker.find(:all).each { |t|
+            Tracker.all.each { |t|
               [new, in_progress, resolved, feedback].each { |os|
                 [in_progress, resolved, feedback, closed].each { |ns|
                   WorkflowTransition.create!(:tracker_id => t.id, :role_id => developer.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
@@ -155,7 +155,7 @@
               }
             }
 
-            Tracker.find(:all).each { |t|
+            Tracker.all.each { |t|
               [new, in_progress, resolved, feedback].each { |os|
                 [closed].each { |ns|
                   WorkflowTransition.create!(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/export/pdf.rb
--- a/lib/redmine/export/pdf.rb
+++ b/lib/redmine/export/pdf.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,12 +17,15 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
-require 'iconv'
 require 'tcpdf'
 require 'fpdf/chinese'
 require 'fpdf/japanese'
 require 'fpdf/korean'
 
+if RUBY_VERSION < '1.9'
+  require 'iconv'
+end
+
 module Redmine
   module Export
     module PDF
@@ -86,7 +89,7 @@
 
         def SetTitle(txt)
           txt = begin
-            utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
+            utf16txt = to_utf16(txt)
             hextxt = "<FEFF"  # FEFF is BOM
             hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
             hextxt << ">"
@@ -116,6 +119,15 @@
           html
         end
 
+        # Encodes an UTF-8 string to UTF-16BE
+        def to_utf16(str)
+          if str.respond_to?(:encode)
+            str.encode('UTF-16BE')
+          else
+            Iconv.conv('UTF-16BE', 'UTF-8', str)
+          end
+        end
+
         def RDMCell(w ,h=0, txt='', border=0, ln=0, align='', fill=0, link='')
           Cell(w, h, fix_text_encoding(txt), border, ln, align, fill, link)
         end
@@ -160,7 +172,7 @@
 
         def bookmark_title(txt)
           txt = begin
-            utf16txt = Iconv.conv('UTF-16BE', 'UTF-8', txt)
+            utf16txt = to_utf16(txt)
             hextxt = "<FEFF"  # FEFF is BOM
             hextxt << utf16txt.unpack("C*").map {|x| sprintf("%02X",x) }.join
             hextxt << ">"
@@ -368,7 +380,7 @@
         col_width
       end
 
-      def render_table_header(pdf, query, col_width, row_height, col_id_width, table_width)
+      def render_table_header(pdf, query, col_width, row_height, table_width)
         # headers
         pdf.SetFontStyle('B',8)
         pdf.SetFillColor(230, 230, 230)
@@ -377,13 +389,12 @@
         base_x = pdf.GetX
         base_y = pdf.GetY
         max_height = issues_to_pdf_write_cells(pdf, query.inline_columns, col_width, row_height, true)
-        pdf.Rect(base_x, base_y, table_width + col_id_width, max_height, 'FD');
+        pdf.Rect(base_x, base_y, table_width, max_height, 'FD');
         pdf.SetXY(base_x, base_y);
 
         # write the cells on page
-        pdf.RDMCell(col_id_width, row_height, "#", "T", 0, 'C', 1)
         issues_to_pdf_write_cells(pdf, query.inline_columns, col_width, row_height, true)
-        issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
+        issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, 0, col_width)
         pdf.SetY(base_y + max_height);
 
         # rows
@@ -405,22 +416,22 @@
         # Landscape A4 = 210 x 297 mm
         page_height   = 210
         page_width    = 297
+        left_margin   = 10
         right_margin  = 10
         bottom_margin = 20
-        col_id_width  = 10
         row_height    = 4
 
         # column widths
-        table_width = page_width - right_margin - 10  # fixed left margin
+        table_width = page_width - right_margin - left_margin
         col_width = []
         unless query.inline_columns.empty?
-          col_width = calc_col_width(issues, query, table_width - col_id_width, pdf)
+          col_width = calc_col_width(issues, query, table_width, pdf)
           table_width = col_width.inject(0) {|s,v| s += v}
         end
 
-				# use full width if the description is displayed
+        # use full width if the description is displayed
         if table_width > 0 && query.has_column?(:description)
-          col_width = col_width.map {|w| w = w * (page_width - right_margin - 10 - col_id_width) / table_width}
+          col_width = col_width.map {|w| w * (page_width - right_margin - left_margin) / table_width}
           table_width = col_width.inject(0) {|s,v| s += v}
         end
 
@@ -428,7 +439,7 @@
         pdf.SetFontStyle('B',11)
         pdf.RDMCell(190,10, title)
         pdf.Ln
-        render_table_header(pdf, query, col_width, row_height, col_id_width, table_width)
+        render_table_header(pdf, query, col_width, row_height, table_width)
         previous_group = false
         issue_list(issues) do |issue, level|
           if query.grouped? &&
@@ -437,7 +448,7 @@
             group_label = group.blank? ? 'None' : group.to_s.dup
             group_label << " (#{query.issue_count_by_group[group]})"
             pdf.Bookmark group_label, 0, -1
-            pdf.RDMCell(table_width + col_id_width, row_height * 2, group_label, 1, 1, 'L')
+            pdf.RDMCell(table_width, row_height * 2, group_label, 1, 1, 'L')
             pdf.SetFontStyle('',8)
             previous_group = group
           end
@@ -456,15 +467,14 @@
           space_left = page_height - base_y - bottom_margin
           if max_height > space_left
             pdf.AddPage("L")
-            render_table_header(pdf, query, col_width, row_height, col_id_width, table_width)
+            render_table_header(pdf, query, col_width, row_height, table_width)
             base_x = pdf.GetX
             base_y = pdf.GetY
           end
 
           # write the cells on page
-          pdf.RDMCell(col_id_width, row_height, issue.id.to_s, "T", 0, 'C', 1)
           issues_to_pdf_write_cells(pdf, col_values, col_width, row_height)
-          issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, col_id_width, col_width)
+          issues_to_pdf_draw_borders(pdf, base_x, base_y, base_y + max_height, 0, col_width)
           pdf.SetY(base_y + max_height);
 
           if query.has_column?(:description) && issue.description?
@@ -501,9 +511,11 @@
       end
 
       # Draw lines to close the row (MultiCell border drawing in not uniform)
+      #
+      #  parameter "col_id_width" is not used. it is kept for compatibility.
       def issues_to_pdf_draw_borders(pdf, top_x, top_y, lower_y,
-                                     id_width, col_widths)
-        col_x = top_x + id_width
+                                     col_id_width, col_widths)
+        col_x = top_x
         pdf.Line(col_x, top_y, col_x, lower_y)    # id right border
         col_widths.each do |width|
           col_x += width
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/helpers/calendar.rb
--- a/lib/redmine/helpers/calendar.rb
+++ b/lib/redmine/helpers/calendar.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/helpers/diff.rb
--- a/lib/redmine/helpers/diff.rb
+++ b/lib/redmine/helpers/diff.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/helpers/gantt.rb
--- a/lib/redmine/helpers/gantt.rb
+++ b/lib/redmine/helpers/gantt.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -23,6 +23,12 @@
       include Redmine::I18n
       include Redmine::Utils::DateCalculation
 
+      # Relation types that are rendered
+      DRAW_TYPES = {
+        IssueRelation::TYPE_BLOCKS   => { :landscape_margin => 16, :color => '#F34F4F' },
+        IssueRelation::TYPE_PRECEDES => { :landscape_margin => 20, :color => '#628FEA' }
+      }.freeze
+
       # :nodoc:
       # Some utility methods for the PDF export
       class PDF
@@ -136,6 +142,20 @@
         )
       end
 
+      # Returns a hash of the relations between the issues that are present on the gantt
+      # and that should be displayed, grouped by issue ids.
+      def relations
+        return @relations if @relations
+        if issues.any?
+          issue_ids = issues.map(&:id)
+          @relations = IssueRelation.
+            where(:issue_from_id => issue_ids, :issue_to_id => issue_ids, :relation_type => DRAW_TYPES.keys).
+            group_by(&:issue_from_id)
+        else
+          @relations = {}
+        end
+      end
+
       # Return all the project nodes that will be displayed
       def projects
         return @projects if @projects
@@ -277,7 +297,6 @@
             pdf_task(options, coords, :label => label, :markers => true, :height => 0.8)
           end
         else
-          ActiveRecord::Base.logger.debug "Gantt#line_for_project was not given a project with a start_date"
           ''
         end
       end
@@ -289,10 +308,18 @@
           html_class << 'icon icon-package '
           html_class << (version.behind_schedule? ? 'version-behind-schedule' : '') << " "
           html_class << (version.overdue? ? 'version-overdue' : '')
+          html_class << ' version-closed' unless version.open?
+          if version.start_date && version.due_date && version.completed_pourcent
+            progress_date = calc_progress_date(version.start_date,
+                                               version.due_date, version.completed_pourcent)
+            html_class << ' behind-start-date' if progress_date < self.date_from
+            html_class << ' over-end-date' if progress_date > self.date_to
+          end
           s = view.link_to_version(version).html_safe
           subject = view.content_tag(:span, s,
                                      :class => html_class).html_safe
-          html_subject(options, subject, :css => "version-name")
+          html_subject(options, subject, :css => "version-name",
+                       :id => "version-#{version.id}")
         when :image
           image_subject(options, version.to_s_with_project)
         when :pdf
@@ -303,24 +330,24 @@
 
       def line_for_version(version, options)
         # Skip versions that don't have a start_date
-        if version.is_a?(Version) && version.start_date && version.due_date
+        if version.is_a?(Version) && version.due_date && version.start_date
           options[:zoom] ||= 1
           options[:g_width] ||= (self.date_to - self.date_from + 1) * options[:zoom]
           coords = coordinates(version.start_date,
-                               version.due_date, version.completed_pourcent,
+                               version.due_date, version.completed_percent,
                                options[:zoom])
-          label = "#{h version} #{h version.completed_pourcent.to_i.to_s}%"
+          label = "#{h version} #{h version.completed_percent.to_i.to_s}%"
           label = h("#{version.project} -") + label unless @project && @project == version.project
           case options[:format]
           when :html
-            html_task(options, coords, :css => "version task", :label => label, :markers => true)
+            html_task(options, coords, :css => "version task",
+                      :label => label, :markers => true, :version => version)
           when :image
             image_task(options, coords, :label => label, :markers => true, :height => 3)
           when :pdf
             pdf_task(options, coords, :label => label, :markers => true, :height => 0.8)
           end
         else
-          ActiveRecord::Base.logger.debug "Gantt#line_for_version was not given a version with a start_date"
           ''
         end
       end
@@ -336,6 +363,13 @@
           css_classes << ' issue-overdue' if issue.overdue?
           css_classes << ' issue-behind-schedule' if issue.behind_schedule?
           css_classes << ' icon icon-issue' unless Setting.gravatar_enabled? && issue.assigned_to
+          css_classes << ' issue-closed' if issue.closed?
+          if issue.start_date && issue.due_before && issue.done_ratio
+            progress_date = calc_progress_date(issue.start_date,
+                                               issue.due_before, issue.done_ratio)
+            css_classes << ' behind-start-date' if progress_date < self.date_from
+            css_classes << ' over-end-date' if progress_date > self.date_to
+          end
           s = "".html_safe
           if issue.assigned_to.present?
             assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name
@@ -347,7 +381,7 @@
           s << view.link_to_issue(issue).html_safe
           subject = view.content_tag(:span, s, :class => css_classes).html_safe
           html_subject(options, subject, :css => "issue-subject",
-                       :title => issue.subject) + "\n"
+                       :title => issue.subject, :id => "issue-#{issue.id}") + "\n"
         when :image
           image_subject(options, issue.subject)
         when :pdf
@@ -378,7 +412,6 @@
             pdf_task(options, coords, :label => label)
         end
         else
-          ActiveRecord::Base.logger.debug "GanttHelper#line_for_issue was not given an issue with a due_before"
           ''
         end
       end
@@ -611,7 +644,7 @@
             coords[:bar_end] = self.date_to - self.date_from + 1
           end
           if progress
-            progress_date = start_date + (end_date - start_date + 1) * (progress / 100.0)
+            progress_date = calc_progress_date(start_date, end_date, progress)
             if progress_date > self.date_from && progress_date > start_date
               if progress_date < self.date_to
                 coords[:bar_progress_end] = progress_date - self.date_from
@@ -638,7 +671,11 @@
         coords
       end
 
-      # Sorts a collection of issues by start_date, due_date, id for gantt rendering
+      def calc_progress_date(start_date, end_date, progress)
+        start_date + (end_date - start_date + 1) * (progress / 100.0)
+      end
+
+      # TODO: Sorts a collection of issues by start_date, due_date, id for gantt rendering
       def sort_issues!(issues)
         issues.sort! { |a, b| gantt_issue_compare(a, b) }
       end
@@ -678,9 +715,10 @@
       def html_subject(params, subject, options={})
         style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;"
         style << "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width]
-        output = view.content_tag('div', subject,
+        output = view.content_tag(:div, subject,
                                   :class => options[:css], :style => style,
-                                  :title => options[:title])
+                                  :title => options[:title],
+                                  :id => options[:id])
         @subjects << output
         output
       end
@@ -705,6 +743,16 @@
         params[:image].text(params[:indent], params[:top] + 2, subject)
       end
 
+      def issue_relations(issue)
+        rels = {}
+        if relations[issue.id]
+          relations[issue.id].each do |relation|
+            (rels[relation.relation_type] ||= []) << relation.issue_to_id
+          end
+        end
+        rels
+      end
+
       def html_task(params, coords, options={})
         output = ''
         # Renders the task bar, with progress and late
@@ -714,9 +762,18 @@
           style << "top:#{params[:top]}px;"
           style << "left:#{coords[:bar_start]}px;"
           style << "width:#{width}px;"
-          output << view.content_tag(:div, '&nbsp;'.html_safe,
-                                     :style => style,
-                                     :class => "#{options[:css]} task_todo")
+          html_id = "task-todo-issue-#{options[:issue].id}" if options[:issue]
+          html_id = "task-todo-version-#{options[:version].id}" if options[:version]
+          content_opt = {:style => style,
+                         :class => "#{options[:css]} task_todo",
+                         :id => html_id}
+          if options[:issue]
+            rels = issue_relations(options[:issue])
+            if rels.present?
+              content_opt[:data] = {"rels" => rels.to_json}
+            end
+          end
+          output << view.content_tag(:div, '&nbsp;'.html_safe, content_opt)
           if coords[:bar_late_end]
             width = coords[:bar_late_end] - coords[:bar_start] - 2
             style = ""
@@ -733,9 +790,12 @@
             style << "top:#{params[:top]}px;"
             style << "left:#{coords[:bar_start]}px;"
             style << "width:#{width}px;"
+            html_id = "task-done-issue-#{options[:issue].id}" if options[:issue]
+            html_id = "task-done-version-#{options[:version].id}" if options[:version]
             output << view.content_tag(:div, '&nbsp;'.html_safe,
                                        :style => style,
-                                       :class => "#{options[:css]} task_done")
+                                       :class => "#{options[:css]} task_done",
+                                       :id => html_id)
           end
         end
         # Renders the markers
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/helpers/time_report.rb
--- a/lib/redmine/helpers/time_report.rb
+++ b/lib/redmine/helpers/time_report.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,9 +18,9 @@
 module Redmine
   module Helpers
     class TimeReport
-      attr_reader :criteria, :columns, :from, :to, :hours, :total_hours, :periods
+      attr_reader :criteria, :columns, :hours, :total_hours, :periods
 
-      def initialize(project, issue, criteria, columns, from, to)
+      def initialize(project, issue, criteria, columns, time_entry_scope)
         @project = project
         @issue = issue
 
@@ -30,8 +30,7 @@
         @criteria = @criteria[0,3]
 
         @columns = (columns && %w(year month week day).include?(columns)) ? columns : 'month'
-        @from = from
-        @to = to
+        @scope = time_entry_scope
 
         run
       end
@@ -44,15 +43,12 @@
 
       def run
         unless @criteria.empty?
-          scope = TimeEntry.visible.spent_between(@from, @to)
-          if @issue
-            scope = scope.on_issue(@issue)
-          elsif @project
-            scope = scope.on_project(@project, Setting.display_subprojects_issues?)
-          end
           time_columns = %w(tyear tmonth tweek spent_on)
           @hours = []
-          scope.sum(:hours, :include => :issue, :group => @criteria.collect{|criteria| @available_criteria[criteria][:sql]} + time_columns).each do |hash, hours|
+          @scope.sum(:hours,
+              :include => [:issue, :activity],
+              :group => @criteria.collect{|criteria| @available_criteria[criteria][:sql]} + time_columns,
+              :joins => @criteria.collect{|criteria| @available_criteria[criteria][:joins]}.compact).each do |hash, hours|
             h = {'hours' => hours}
             (@criteria + time_columns).each_with_index do |name, i|
               h[name] = hash[i]
@@ -67,21 +63,17 @@
             when 'month'
               row['month'] = "#{row['tyear']}-#{row['tmonth']}"
             when 'week'
-              row['week'] = "#{row['tyear']}-#{row['tweek']}"
+              row['week'] = "#{row['spent_on'].cwyear}-#{row['tweek']}"
             when 'day'
               row['day'] = "#{row['spent_on']}"
             end
           end
           
-          if @from.nil?
-            min = @hours.collect {|row| row['spent_on']}.min
-            @from = min ? min.to_date : Date.today
-          end
+          min = @hours.collect {|row| row['spent_on']}.min
+          @from = min ? min.to_date : Date.today
 
-          if @to.nil?
-            max = @hours.collect {|row| row['spent_on']}.max
-            @to = max ? max.to_date : Date.today
-          end
+          max = @hours.collect {|row| row['spent_on']}.max
+          @to = max ? max.to_date : Date.today
           
           @total_hours = @hours.inject(0) {|s,k| s = s + k['hours'].to_f}
 
@@ -98,7 +90,7 @@
               @periods << "#{date_from.year}-#{date_from.month}"
               date_from = (date_from + 1.month).at_beginning_of_month
             when 'week'
-              @periods << "#{date_from.year}-#{date_from.to_date.cweek}"
+              @periods << "#{date_from.to_date.cwyear}-#{date_from.to_date.cweek}"
               date_from = (date_from + 7.day).at_beginning_of_week
             when 'day'
               @periods << "#{date_from.to_date}"
@@ -121,9 +113,9 @@
                                  'category' => {:sql => "#{Issue.table_name}.category_id",
                                                 :klass => IssueCategory,
                                                 :label => :field_category},
-                                 'member' => {:sql => "#{TimeEntry.table_name}.user_id",
+                                 'user' => {:sql => "#{TimeEntry.table_name}.user_id",
                                              :klass => User,
-                                             :label => :label_member},
+                                             :label => :label_user},
                                  'tracker' => {:sql => "#{Issue.table_name}.tracker_id",
                                               :klass => Tracker,
                                               :label => :label_tracker},
@@ -135,24 +127,19 @@
                                              :label => :label_issue}
                                }
 
+        # Add time entry custom fields
+        custom_fields = TimeEntryCustomField.all
+        # Add project custom fields
+        custom_fields += ProjectCustomField.all
+        # Add issue custom fields
+        custom_fields += (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields)
+        # Add time entry activity custom fields
+        custom_fields += TimeEntryActivityCustomField.all
+
         # Add list and boolean custom fields as available criteria
-        custom_fields = (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields)
         custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
-          @available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id ORDER BY c.value LIMIT 1)",
-                                                 :format => cf.field_format,
-                                                 :label => cf.name}
-        end if @project
-
-        # Add list and boolean time entry custom fields
-        TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
-          @available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id ORDER BY c.value LIMIT 1)",
-                                                 :format => cf.field_format,
-                                                 :label => cf.name}
-        end
-
-        # Add list and boolean time entry activity custom fields
-        TimeEntryActivityCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
-          @available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Enumeration' AND c.customized_id = #{TimeEntry.table_name}.activity_id ORDER BY c.value LIMIT 1)",
+          @available_criteria["cf_#{cf.id}"] = {:sql => "#{cf.join_alias}.value",
+                                                 :joins => cf.join_for_order_statement,
                                                  :format => cf.field_format,
                                                  :label => cf.name}
         end
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/hook.rb
--- a/lib/redmine/hook.rb
+++ b/lib/redmine/hook.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/i18n.rb
--- a/lib/redmine/i18n.rb
+++ b/lib/redmine/i18n.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/imap.rb
--- a/lib/redmine/imap.rb
+++ b/lib/redmine/imap.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/menu_manager.rb
--- a/lib/redmine/menu_manager.rb
+++ b/lib/redmine/menu_manager.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -190,20 +190,17 @@
 
       # Checks if a user is allowed to access the menu item by:
       #
+      # * Checking the url target (project only)
       # * Checking the conditions of the item
-      # * Checking the url target (project only)
       def allowed_node?(node, user, project)
+        if project && user && !user.allowed_to?(node.url, project)
+          return false
+        end
         if node.condition && !node.condition.call(project)
           # Condition that doesn't pass
           return false
         end
-
-        if project
-          return user && user.allowed_to?(node.url, project)
-        else
-          # outside a project, all menu items allowed
-          return true
-        end
+        return true
       end
     end
 
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/mime_type.rb
--- a/lib/redmine/mime_type.rb
+++ b/lib/redmine/mime_type.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/pagination.rb
--- /dev/null
+++ b/lib/redmine/pagination.rb
@@ -0,0 +1,244 @@
+# encoding: utf-8
+#
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+module Redmine
+  module Pagination
+    class Paginator
+      attr_reader :item_count, :per_page, :page, :page_param
+
+      def initialize(*args)
+        if args.first.is_a?(ActionController::Base)
+          args.shift
+          ActiveSupport::Deprecation.warn "Paginator no longer takes a controller instance as the first argument. Remove it from #new arguments."
+        end
+        item_count, per_page, page, page_param = *args
+
+        @item_count = item_count
+        @per_page = per_page
+        page = (page || 1).to_i
+        if page < 1
+          page = 1
+        end
+        @page = page
+        @page_param = page_param || :page
+      end
+
+      def offset
+        (page - 1) * per_page
+      end
+
+      def first_page
+        if item_count > 0
+          1
+        end
+      end
+
+      def previous_page
+        if page > 1
+          page - 1
+        end
+      end
+
+      def next_page
+        if last_item < item_count
+          page + 1
+        end
+      end
+
+      def last_page
+        if item_count > 0
+          (item_count - 1) / per_page + 1
+        end
+      end
+
+      def first_item
+        item_count == 0 ? 0 : (offset + 1)
+      end
+
+      def last_item
+        l = first_item + per_page - 1
+        l > item_count ? item_count : l
+      end
+
+      def linked_pages
+        pages = []
+        if item_count > 0
+          pages += [first_page, page, last_page]
+          pages += ((page-2)..(page+2)).to_a.select {|p| p > first_page && p < last_page}
+        end
+        pages = pages.compact.uniq.sort
+        if pages.size > 1
+          pages
+        else
+          []
+        end
+      end
+
+      def items_per_page
+        ActiveSupport::Deprecation.warn "Paginator#items_per_page will be removed. Use #per_page instead."
+        per_page
+      end
+
+      def current
+        ActiveSupport::Deprecation.warn "Paginator#current will be removed. Use .offset instead of .current.offset."
+        self
+      end
+    end
+
+    # Paginates the given scope or model. Returns a Paginator instance and
+    # the collection of objects for the current page.
+    #
+    # Options:
+    #   :parameter     name of the page parameter
+    #
+    # Examples:
+    #   @user_pages, @users = paginate User.where(:status => 1)
+    #
+    def paginate(scope, options={})
+      options = options.dup
+      finder_options = options.extract!(
+        :conditions,
+        :order,
+        :joins,
+        :include,
+        :select
+      )
+      if scope.is_a?(Symbol) || finder_options.values.compact.any?
+        return deprecated_paginate(scope, finder_options, options)
+      end
+
+      paginator = paginator(scope.count, options)
+      collection = scope.limit(paginator.per_page).offset(paginator.offset).to_a
+
+      return paginator, collection
+    end
+
+    def deprecated_paginate(arg, finder_options, options={})
+      ActiveSupport::Deprecation.warn "#paginate with a Symbol and/or find options is depreceted and will be removed. Use a scope instead."
+      klass = arg.is_a?(Symbol) ? arg.to_s.classify.constantize : arg
+      scope = klass.scoped(finder_options)
+      paginate(scope, options)
+    end
+
+    def paginator(item_count, options={})
+      options.assert_valid_keys :parameter, :per_page
+
+      page_param = options[:parameter] || :page
+      page = (params[page_param] || 1).to_i
+      per_page = options[:per_page] || per_page_option
+      Paginator.new(item_count, per_page, page, page_param)
+    end
+
+    module Helper
+      include Redmine::I18n
+
+      # Renders the pagination links for the given paginator.
+      #
+      # Options:
+      #   :per_page_links    if set to false, the "Per page" links are not rendered
+      #
+      def pagination_links_full(*args)
+        pagination_links_each(*args) do |text, parameters, options|
+          if block_given?
+            yield text, parameters, options
+          else
+            link_to text, params.merge(parameters), options
+          end
+        end
+      end
+
+      # Yields the given block with the text and parameters
+      # for each pagination link and returns a string that represents the links
+      def pagination_links_each(paginator, count=nil, options={}, &block)
+        options.assert_valid_keys :per_page_links
+
+        per_page_links = options.delete(:per_page_links)
+        per_page_links = false if count.nil?
+        page_param = paginator.page_param
+
+        html = ''
+        if paginator.previous_page
+          # \xc2\xab(utf-8) = &#171;
+          text = "\xc2\xab " + l(:label_previous)
+          html << yield(text, {page_param => paginator.previous_page}, :class => 'previous') + ' '
+        end
+
+        previous = nil
+        paginator.linked_pages.each do |page|
+          if previous && previous != page - 1
+            html << content_tag('span', '...', :class => 'spacer') + ' '
+          end
+          if page == paginator.page
+            html << content_tag('span', page.to_s, :class => 'current page')
+          else
+            html << yield(page.to_s, {page_param => page}, :class => 'page')
+          end
+          html << ' '
+          previous = page
+        end
+
+        if paginator.next_page
+          # \xc2\xbb(utf-8) = &#187;
+          text = l(:label_next) + " \xc2\xbb"
+          html << yield(text, {page_param => paginator.next_page}, :class => 'next') + ' '
+        end
+
+        html << content_tag('span', "(#{paginator.first_item}-#{paginator.last_item}/#{paginator.item_count})", :class => 'items') + ' '
+
+        if per_page_links != false && links = per_page_links(paginator, &block)
+          html << content_tag('span', links.to_s, :class => 'per-page')
+        end
+
+        html.html_safe
+      end
+
+      # Renders the "Per page" links.
+      def per_page_links(paginator, &block)
+        values = per_page_options(paginator.per_page, paginator.item_count)
+        if values.any?
+          links = values.collect do |n|
+            if n == paginator.per_page
+              content_tag('span', n.to_s)
+            else
+              yield(n, :per_page => n, paginator.page_param => nil)
+            end
+          end
+          l(:label_display_per_page, links.join(', ')).html_safe
+        end
+      end
+
+      def per_page_options(selected=nil, item_count=nil)
+        options = Setting.per_page_options_array
+        if item_count && options.any?
+          if item_count > options.first
+            max = options.detect {|value| value >= item_count} || item_count
+          else
+            max = item_count
+          end
+          options = options.select {|value| value <= max || value == selected}
+        end
+        if options.empty? || (options.size == 1 && options.first == selected)
+          []
+        else
+          options
+        end
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/platform.rb
--- a/lib/redmine/platform.rb
+++ b/lib/redmine/platform.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/plugin.rb
--- a/lib/redmine/plugin.rb
+++ b/lib/redmine/plugin.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -145,6 +145,10 @@
       File.join(self.class.public_directory, id.to_s)
     end
 
+    def to_param
+      id
+    end
+
     def assets_directory
       File.join(directory, 'assets')
     end
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/pop3.rb
--- a/lib/redmine/pop3.rb
+++ b/lib/redmine/pop3.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/safe_attributes.rb
--- a/lib/redmine/safe_attributes.rb
+++ b/lib/redmine/safe_attributes.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/scm/adapters/abstract_adapter.rb
--- a/lib/redmine/scm/adapters/abstract_adapter.rb
+++ b/lib/redmine/scm/adapters/abstract_adapter.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,6 +17,10 @@
 
 require 'cgi'
 
+if RUBY_VERSION < '1.9'
+  require 'iconv'
+end
+
 module Redmine
   module Scm
     module Adapters
@@ -214,13 +218,39 @@
           Rails.logger
         end
 
+        # Path to the file where scm stderr output is logged
+        # Returns nil if the log file is not writable
+        def self.stderr_log_file
+          if @stderr_log_file.nil?
+            writable = false
+            path = Redmine::Configuration['scm_stderr_log_file'].presence
+            path ||= Rails.root.join("log/#{Rails.env}.scm.stderr.log").to_s
+            if File.exists?(path)
+              if File.file?(path) && File.writable?(path) 
+                writable = true
+              else
+                logger.warn("SCM log file (#{path}) is not writable")
+              end
+            else
+              begin
+                File.open(path, "w") {}
+                writable = true
+              rescue => e
+                logger.warn("SCM log file (#{path}) cannot be created: #{e.message}")
+              end
+            end
+            @stderr_log_file = writable ? path : false
+          end
+          @stderr_log_file || nil
+        end
+
         def self.shellout(cmd, options = {}, &block)
           if logger && logger.debug?
             logger.debug "Shelling out: #{strip_credential(cmd)}"
-          end
-          if Rails.env == 'development'
-            # Capture stderr when running in dev environment
-            cmd = "#{cmd} 2>>#{shell_quote(Rails.root.join('log/scm.stderr.log').to_s)}"
+            # Capture stderr in a log file
+            if stderr_log_file
+              cmd = "#{cmd} 2>>#{shell_quote(stderr_log_file)}"
+            end
           end
           begin
             mode = "r+"
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/scm/adapters/bazaar_adapter.rb
--- a/lib/redmine/scm/adapters/bazaar_adapter.rb
+++ b/lib/redmine/scm/adapters/bazaar_adapter.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -104,13 +104,13 @@
             re = %r{^V\s+(#{Regexp.escape(prefix)})?(\/?)([^\/]+)(\/?)\s+(\S+)\r?$}
             io.each_line do |line|
               next unless line =~ re
-              name_locale = $3.strip
+              name_locale, slash, revision = $3.strip, $4, $5.strip
               name = scm_iconv('UTF-8', @path_encoding, name_locale)
               entries << Entry.new({:name => name,
                                     :path => ((path.empty? ? "" : "#{path}/") + name),
-                                    :kind => ($4.blank? ? 'file' : 'dir'),
+                                    :kind => (slash.blank? ? 'file' : 'dir'),
                                     :size => nil,
-                                    :lastrev => Revision.new(:revision => $5.strip)
+                                    :lastrev => Revision.new(:revision => revision)
                                   })
             end
           end
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/scm/adapters/darcs_adapter.rb
--- a/lib/redmine/scm/adapters/darcs_adapter.rb
+++ b/lib/redmine/scm/adapters/darcs_adapter.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/scm/adapters/filesystem_adapter.rb
--- a/lib/redmine/scm/adapters/filesystem_adapter.rb
+++ b/lib/redmine/scm/adapters/filesystem_adapter.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # FileSystem adapter
 # File written by Paul Rivier, at Demotera.
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/scm/adapters/git_adapter.rb
--- a/lib/redmine/scm/adapters/git_adapter.rb
+++ b/lib/redmine/scm/adapters/git_adapter.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/scm/adapters/mercurial_adapter.rb
--- a/lib/redmine/scm/adapters/mercurial_adapter.rb
+++ b/lib/redmine/scm/adapters/mercurial_adapter.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/scm/adapters/subversion_adapter.rb
--- a/lib/redmine/scm/adapters/subversion_adapter.rb
+++ b/lib/redmine/scm/adapters/subversion_adapter.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/scm/base.rb
--- a/lib/redmine/scm/base.rb
+++ b/lib/redmine/scm/base.rb
@@ -4,7 +4,7 @@
       class << self
 
         def all
-          @scms
+          @scms || []
         end
 
         # Add a new SCM adapter and repository
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/search.rb
--- a/lib/redmine/search.rb
+++ b/lib/redmine/search.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/subclass_factory.rb
--- a/lib/redmine/subclass_factory.rb
+++ b/lib/redmine/subclass_factory.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/syntax_highlighting.rb
--- a/lib/redmine/syntax_highlighting.rb
+++ b/lib/redmine/syntax_highlighting.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -33,7 +33,6 @@
 
     module CodeRay
       require 'coderay'
-      require 'coderay/helpers/file_type'
 
       class << self
         # Highlights +text+ as the content of +filename+
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/themes.rb
--- a/lib/redmine/themes.rb
+++ b/lib/redmine/themes.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/thumbnail.rb
--- a/lib/redmine/thumbnail.rb
+++ b/lib/redmine/thumbnail.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/unified_diff.rb
--- a/lib/redmine/unified_diff.rb
+++ b/lib/redmine/unified_diff.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -28,17 +28,9 @@
       lines = 0
       @truncated = false
       diff_table = DiffTable.new(diff_type, diff_style)
-      diff.each do |line|
-        line_encoding = nil
-        if line.respond_to?(:force_encoding)
-          line_encoding = line.encoding
-          # TODO: UTF-16 and Japanese CP932 which is imcompatible with ASCII
-          #       In Japan, diffrence between file path encoding
-          #       and file contents encoding is popular.
-          line.force_encoding('ASCII-8BIT')
-        end
-        unless diff_table.add_line line
-          line.force_encoding(line_encoding) if line_encoding
+      diff.each do |line_raw|
+        line = Redmine::CodesetUtil.to_utf8_by_setting(line_raw)
+        unless diff_table.add_line(line)
           self << diff_table if diff_table.length > 0
           diff_table = DiffTable.new(diff_type, diff_style)
         end
@@ -83,7 +75,7 @@
           @parsing = true
         end
       else
-        if line =~ /^[^\+\-\s@\\]/
+        if line =~ %r{^[^\+\-\s@\\]}
           @parsing = false
           return false
         elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
@@ -207,10 +199,20 @@
         while starting < max && line_left[starting] == line_right[starting]
           starting += 1
         end
+        if (! "".respond_to?(:force_encoding)) && starting < line_left.size
+          while line_left[starting].ord.between?(128, 191) && starting > 0
+            starting -= 1
+          end
+        end
         ending = -1
         while ending >= -(max - starting) && line_left[ending] == line_right[ending]
           ending -= 1
         end
+        if (! "".respond_to?(:force_encoding)) && ending > (-1 * line_left.size)
+          while line_left[ending].ord.between?(128, 191) && ending > -1
+            ending -= 1
+          end
+        end
         unless starting == 0 && ending == -1
           [starting, ending]
         end
@@ -268,6 +270,12 @@
     private
 
     def line_to_html(line, offsets)
+      html = line_to_html_raw(line, offsets)
+      html.force_encoding('UTF-8') if html.respond_to?(:force_encoding)
+      html
+    end
+
+    def line_to_html_raw(line, offsets)
       if offsets
         s = ''
         unless offsets.first == 0
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/utils.rb
--- a/lib/redmine/utils.rb
+++ b/lib/redmine/utils.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/version.rb
--- a/lib/redmine/version.rb
+++ b/lib/redmine/version.rb
@@ -3,8 +3,8 @@
 module Redmine
   module VERSION #:nodoc:
     MAJOR = 2
-    MINOR = 2
-    TINY  = 4
+    MINOR = 3
+    TINY  = 1
 
     # Branch values:
     # * official release: nil
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/views/api_template_handler.rb
--- a/lib/redmine/views/api_template_handler.rb
+++ b/lib/redmine/views/api_template_handler.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/views/builders.rb
--- a/lib/redmine/views/builders.rb
+++ b/lib/redmine/views/builders.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -15,6 +15,9 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
+require 'redmine/views/builders/json'
+require 'redmine/views/builders/xml'
+
 module Redmine
   module Views
     module Builders
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/views/builders/json.rb
--- a/lib/redmine/views/builders/json.rb
+++ b/lib/redmine/views/builders/json.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -15,7 +15,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
-require 'blankslate'
+require 'redmine/views/builders/structure'
 
 module Redmine
   module Views
@@ -25,7 +25,10 @@
 
         def initialize(request, response)
           super
-          self.jsonp = (request.params[:callback] || request.params[:jsonp]).to_s.gsub(/[^a-zA-Z0-9_]/, '')
+          callback = request.params[:callback] || request.params[:jsonp]
+          if callback && Setting.jsonp_enabled?
+            self.jsonp = callback.to_s.gsub(/[^a-zA-Z0-9_]/, '')
+          end
         end
 
         def output
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/views/builders/structure.rb
--- a/lib/redmine/views/builders/structure.rb
+++ b/lib/redmine/views/builders/structure.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/views/builders/xml.rb
--- a/lib/redmine/views/builders/xml.rb
+++ b/lib/redmine/views/builders/xml.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/views/labelled_form_builder.rb
--- a/lib/redmine/views/labelled_form_builder.rb
+++ b/lib/redmine/views/labelled_form_builder.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/views/my_page/block.rb
--- a/lib/redmine/views/my_page/block.rb
+++ b/lib/redmine/views/my_page/block.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/views/other_formats_builder.rb
--- a/lib/redmine/views/other_formats_builder.rb
+++ b/lib/redmine/views/other_formats_builder.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/wiki_formatting.rb
--- a/lib/redmine/wiki_formatting.rb
+++ b/lib/redmine/wiki_formatting.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -86,7 +86,7 @@
       AUTO_LINK_RE = %r{
                       (                          # leading text
                         <\w+.*?>|                # leading HTML tag, or
-                        [^=<>!:'"/]|             # leading punctuation, or
+                        [\s\(\[,;]|              # leading punctuation, or
                         ^                        # beginning of line
                       )
                       (
@@ -95,7 +95,7 @@
                         (?:www\.)                # www.*
                       )
                       (
-                        (\S+?)                   # url
+                        ([^<]\S*?)               # url
                         (\/)?                    # slash
                       )
                       ((?:&gt;)?|[^[:alnum:]_\=\/;\(\)]*?)               # post
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/wiki_formatting/macros.rb
--- a/lib/redmine/wiki_formatting/macros.rb
+++ b/lib/redmine/wiki_formatting/macros.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/wiki_formatting/textile/formatter.rb
--- a/lib/redmine/wiki_formatting/textile/formatter.rb
+++ b/lib/redmine/wiki_formatting/textile/formatter.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/redmine/wiki_formatting/textile/helper.rb
--- a/lib/redmine/wiki_formatting/textile/helper.rb
+++ b/lib/redmine/wiki_formatting/textile/helper.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -23,10 +23,7 @@
           heads_for_wiki_formatter
           # Is there a simple way to link to a public resource?
           url = "#{Redmine::Utils.relative_url_root}/help/wiki_syntax.html"
-          help_link = link_to(l(:setting_text_formatting), url,
-            :onclick => "window.open(\"#{ url }\", \"\", \"resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\"); return false;")
-
-          javascript_tag("var wikiToolbar = new jsToolBar(document.getElementById('#{field_id}')); wikiToolbar.setHelpLink('#{escape_javascript help_link}'); wikiToolbar.draw();")
+          javascript_tag("var wikiToolbar = new jsToolBar(document.getElementById('#{field_id}')); wikiToolbar.setHelpLink('#{escape_javascript url}'); wikiToolbar.draw();")
         end
 
         def initial_page_content(page)
diff -r 0a574315af3e -r 4f746d8966dd lib/tasks/ci.rake
--- a/lib/tasks/ci.rake
+++ b/lib/tasks/ci.rake
@@ -8,72 +8,56 @@
   Rake::Task["ci:teardown"].invoke
 end
 
-# Tasks can be hooked into by redefining them in a plugin
 namespace :ci do
-  desc "Setup Redmine for a new build."
+  desc "Setup Redmine for a new build"
   task :setup do
-    Rake::Task["ci:dump_environment"].invoke
     Rake::Task["tmp:clear"].invoke
-    Rake::Task["db:create"].invoke
+    Rake::Task["log:clear"].invoke
+    Rake::Task["db:create:all"].invoke
     Rake::Task["db:migrate"].invoke
     Rake::Task["db:schema:dump"].invoke
+    Rake::Task["test:scm:setup:all"].invoke
     Rake::Task["test:scm:update"].invoke
   end
 
   desc "Build Redmine"
   task :build do
     Rake::Task["test"].invoke
+    #Rake::Task["test:ui"].invoke unless RUBY_VERSION < '1.9'
   end
 
-  # Use this to cleanup after building or run post-build analysis.
   desc "Finish the build"
   task :teardown do
   end
+end
 
-  desc "Creates and configures the databases for the CI server"
-  task :database do
-    path = 'config/database.yml'
-    unless File.exists?(path)
-      database = ENV['DATABASE_ADAPTER']
-      ruby = ENV['RUBY_VER'].gsub('.', '').gsub('-', '')
-      branch = ENV['BRANCH'].gsub('.', '').gsub('-', '')
-      dev_db_name = "ci_#{branch}_#{ruby}_dev"
-      test_db_name = "ci_#{branch}_#{ruby}_test"
+desc "Creates database.yml for the CI server"
+file 'config/database.yml' do
+  require 'yaml'
+  database = ENV['DATABASE_ADAPTER']
+  ruby = ENV['RUBY_VER'].gsub('.', '').gsub('-', '')
+  branch = ENV['BRANCH'].gsub('.', '').gsub('-', '')
+  dev_db_name = "ci_#{branch}_#{ruby}_dev"
+  test_db_name = "ci_#{branch}_#{ruby}_test"
 
-      case database
-      when 'mysql'
-        raise "Error creating databases" unless
-          system(%|mysql -u jenkins --password=jenkins -e 'create database #{dev_db_name} character set utf8;'|) &&
-          system(%|mysql -u jenkins --password=jenkins -e 'create database #{test_db_name} character set utf8;'|)
-        dev_conf =  { 'adapter' => (RUBY_VERSION >= '1.9' ? 'mysql2' : 'mysql'), 'database' => dev_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins', 'encoding' => 'utf8' }
-        test_conf = { 'adapter' => (RUBY_VERSION >= '1.9' ? 'mysql2' : 'mysql'), 'database' => test_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins', 'encoding' => 'utf8' }
-      when 'postgresql'
-        raise "Error creating databases" unless
-          system(%|psql -U jenkins -d postgres -c "create database #{dev_db_name} owner jenkins encoding 'UTF8';"|) &&
-          system(%|psql -U jenkins -d postgres -c "create database #{test_db_name} owner jenkins encoding 'UTF8';"|)
-        dev_conf =  { 'adapter' => 'postgresql', 'database' => dev_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins' }
-        test_conf = { 'adapter' => 'postgresql', 'database' => test_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins' }
-      when 'sqlite3'
-        dev_conf =  { 'adapter' => 'sqlite3', 'database' => "db/#{dev_db_name}.sqlite3" }
-        test_conf = { 'adapter' => 'sqlite3', 'database' => "db/#{test_db_name}.sqlite3" }
-      else
-        raise "Unknown database"
-      end
-
-      File.open(path, 'w') do |f|
-        f.write YAML.dump({'development' => dev_conf, 'test' => test_conf})
-      end
-    end
+  case database
+  when 'mysql'
+    dev_conf =  {'adapter' => (RUBY_VERSION >= '1.9' ? 'mysql2' : 'mysql'), 'database' => dev_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins', 'encoding' => 'utf8'}
+    test_conf = dev_conf.merge('database' => test_db_name)
+  when 'postgresql'
+    dev_conf =  {'adapter' => 'postgresql', 'database' => dev_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins'}
+    test_conf = dev_conf.merge('database' => test_db_name)
+  when 'sqlite3'
+    dev_conf =  {'adapter' => 'sqlite3', 'database' => "db/#{dev_db_name}.sqlite3"}
+    test_conf = dev_conf.merge('database' => "db/#{test_db_name}.sqlite3")
+  when 'sqlserver'
+    dev_conf =  {'adapter' => 'sqlserver', 'database' => dev_db_name, 'host' => 'mssqlserver', 'port' => 1433, 'username' => 'jenkins', 'password' => 'jenkins'}
+    test_conf = dev_conf.merge('database' => test_db_name)
+  else
+    abort "Unknown database"
   end
 
-  desc "Dump the environment information to a BUILD_ENVIRONMENT ENV variable for debugging"
-  task :dump_environment do
-
-    ENV['BUILD_ENVIRONMENT'] = ['ruby -v', 'gem -v', 'gem list'].collect do |command|
-      result = `#{command}`
-      "$ #{command}\n#{result}"
-    end.join("\n")
-
+  File.open('config/database.yml', 'w') do |f|
+    f.write YAML.dump({'development' => dev_conf, 'test' => test_conf})
   end
 end
-
diff -r 0a574315af3e -r 4f746d8966dd lib/tasks/ciphering.rake
--- a/lib/tasks/ciphering.rake
+++ b/lib/tasks/ciphering.rake
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/tasks/email.rake
--- a/lib/tasks/email.rake
+++ b/lib/tasks/email.rake
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -29,6 +29,8 @@
                            create: create a user account
   no_permission_check=1    disable permission checking when receiving
                            the email
+  no_account_notice=1      disable new user account notification
+  default_group=foo,bar    adds created user to foo and bar groups
 
 Issue attributes control options:
   project=PROJECT          identifier of the target project
@@ -58,6 +60,8 @@
       options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
       options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
       options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
+      options[:no_account_notice] = ENV['no_account_notice'] if ENV['no_account_notice']
+      options[:default_group] = ENV['default_group'] if ENV['default_group']
 
       MailHandler.receive(STDIN.read, options)
     end
@@ -73,6 +77,8 @@
                            create: create a user account
   no_permission_check=1    disable permission checking when receiving
                            the email
+  no_account_notice=1      disable new user account notification
+  default_group=foo,bar    adds created user to foo and bar groups
 
 Available IMAP options:
   host=HOST                IMAP server host (default: 127.0.0.1)
@@ -129,6 +135,8 @@
       options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
       options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
       options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
+      options[:no_account_notice] = ENV['no_account_notice'] if ENV['no_account_notice']
+      options[:default_group] = ENV['default_group'] if ENV['default_group']
 
       Redmine::IMAP.check(imap_options, options)
     end
@@ -162,6 +170,8 @@
       options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
       options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
       options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
+      options[:no_account_notice] = ENV['no_account_notice'] if ENV['no_account_notice']
+      options[:default_group] = ENV['default_group'] if ENV['default_group']
 
       Redmine::POP3.check(pop_options, options)
     end
diff -r 0a574315af3e -r 4f746d8966dd lib/tasks/locales.rake
--- a/lib/tasks/locales.rake
+++ b/lib/tasks/locales.rake
@@ -43,7 +43,15 @@
     files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
     files.sort.each do |file|
       puts "parsing #{file}..."
-      file_strings = YAML.load(File.read(file))
+      file_strings = YAML.load_file(file)
+      unless file_strings.is_a?(Hash)
+        puts "#{file}: content is not a Hash (#{file_strings.class.name})"
+        next
+      end
+      unless file_strings.keys.size == 1
+        puts "#{file}: content has multiple keys (#{file_strings.keys.size})"
+        next
+      end
       file_strings = file_strings[file_strings.keys.first]
 
       file_strings.each do |key, string|
diff -r 0a574315af3e -r 4f746d8966dd lib/tasks/migrate_from_mantis.rake
--- a/lib/tasks/migrate_from_mantis.rake
+++ b/lib/tasks/migrate_from_mantis.rake
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,7 +18,7 @@
 desc 'Mantis migration script'
 
 require 'active_record'
-require 'iconv'
+require 'iconv' if RUBY_VERSION < '1.9'
 require 'pp'
 
 namespace :redmine do
@@ -30,7 +30,7 @@
       assigned_status = IssueStatus.find_by_position(2)
       resolved_status = IssueStatus.find_by_position(3)
       feedback_status = IssueStatus.find_by_position(4)
-      closed_status = IssueStatus.find :first, :conditions => { :is_closed => true }
+      closed_status = IssueStatus.where(:is_closed => true).first
       STATUS_MAPPING = {10 => DEFAULT_STATUS,  # new
                         20 => feedback_status, # feedback
                         30 => DEFAULT_STATUS,  # acknowledged
@@ -53,7 +53,7 @@
       TRACKER_BUG = Tracker.find_by_position(1)
       TRACKER_FEATURE = Tracker.find_by_position(2)
 
-      roles = Role.find(:all, :conditions => {:builtin => 0}, :order => 'position ASC')
+      roles = Role.where(:builtin => 0).order('position ASC').all
       manager_role = roles[0]
       developer_role = roles[1]
       DEFAULT_ROLE = roles.last
@@ -241,7 +241,7 @@
       User.delete_all "login <> 'admin'"
       users_map = {}
       users_migrated = 0
-      MantisUser.find(:all).each do |user|
+      MantisUser.all.each do |user|
         u = User.new :firstname => encode(user.firstname),
                      :lastname => encode(user.lastname),
                      :mail => user.email,
@@ -263,7 +263,7 @@
       projects_map = {}
       versions_map = {}
       categories_map = {}
-      MantisProject.find(:all).each do |project|
+      MantisProject.all.each do |project|
         p = Project.new :name => encode(project.name),
                         :description => encode(project.description)
         p.identifier = project.identifier
@@ -347,7 +347,7 @@
         bug.bug_files.each do |file|
           a = Attachment.new :created_on => file.date_added
           a.file = file
-          a.author = User.find :first
+          a.author = User.first
           a.container = i
           a.save
         end
@@ -365,7 +365,7 @@
 
       # Bug relationships
       print "Migrating bug relations"
-      MantisBugRelationship.find(:all).each do |relation|
+      MantisBugRelationship.all.each do |relation|
         next unless issues_map[relation.source_bug_id] && issues_map[relation.destination_bug_id]
         r = IssueRelation.new :relation_type => RELATION_TYPE_MAPPING[relation.relationship_type]
         r.issue_from = Issue.find_by_id(issues_map[relation.source_bug_id])
@@ -379,7 +379,7 @@
       # News
       print "Migrating news"
       News.destroy_all
-      MantisNews.find(:all, :conditions => 'project_id > 0').each do |news|
+      MantisNews.where('project_id > 0').all.each do |news|
         next unless projects_map[news.project_id]
         n = News.new :project_id => projects_map[news.project_id],
                      :title => encode(news.headline[0..59]),
@@ -395,7 +395,7 @@
       # Custom fields
       print "Migrating custom fields"
       IssueCustomField.destroy_all
-      MantisCustomField.find(:all).each do |field|
+      MantisCustomField.all.each do |field|
         f = IssueCustomField.new :name => field.name[0..29],
                                  :field_format => CUSTOM_FIELD_TYPE_MAPPING[field.format],
                                  :min_length => field.length_min,
@@ -407,7 +407,7 @@
         print '.'
         STDOUT.flush
         # Trackers association
-        f.trackers = Tracker.find :all
+        f.trackers = Tracker.all
 
         # Projects association
         field.projects.each do |project|
@@ -440,9 +440,7 @@
     end
 
     def self.encoding(charset)
-      @ic = Iconv.new('UTF-8', charset)
-    rescue Iconv::InvalidEncoding
-      return false
+      @charset = charset
     end
 
     def self.establish_connection(params)
@@ -454,9 +452,12 @@
     end
 
     def self.encode(text)
-      @ic.iconv text
-    rescue
-      text
+      if RUBY_VERSION < '1.9'
+        @ic ||= Iconv.new('UTF-8', @charset)
+        @ic.iconv text
+      else
+        text.to_s.force_encoding(@charset).encode('UTF-8')
+      end
     end
   end
 
diff -r 0a574315af3e -r 4f746d8966dd lib/tasks/migrate_from_trac.rake
--- a/lib/tasks/migrate_from_trac.rake
+++ b/lib/tasks/migrate_from_trac.rake
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,7 +16,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require 'active_record'
-require 'iconv'
+require 'iconv' if RUBY_VERSION < '1.9'
 require 'pp'
 
 namespace :redmine do
@@ -30,7 +30,7 @@
         assigned_status = IssueStatus.find_by_position(2)
         resolved_status = IssueStatus.find_by_position(3)
         feedback_status = IssueStatus.find_by_position(4)
-        closed_status = IssueStatus.find :first, :conditions => { :is_closed => true }
+        closed_status = IssueStatus.where(:is_closed => true).first
         STATUS_MAPPING = {'new' => DEFAULT_STATUS,
                           'reopened' => feedback_status,
                           'assigned' => assigned_status,
@@ -61,7 +61,7 @@
                            'patch' =>TRACKER_FEATURE
                            }
 
-        roles = Role.find(:all, :conditions => {:builtin => 0}, :order => 'position ASC')
+        roles = Role.where(:builtin => 0).order('position ASC').all
         manager_role = roles[0]
         developer_role = roles[1]
         DEFAULT_ROLE = roles.last
@@ -257,7 +257,7 @@
           u.password = 'trac'
           u.admin = true if TracPermission.find_by_username_and_action(username, 'admin')
           # finally, a default user is used if the new user is not valid
-          u = User.find(:first) unless u.save
+          u = User.first unless u.save
         end
         # Make sure he is a member of the project
         if project_member && !u.member_of?(@target_project)
@@ -390,7 +390,7 @@
         # Components
         print "Migrating components"
         issues_category_map = {}
-        TracComponent.find(:all).each do |component|
+        TracComponent.all.each do |component|
         print '.'
         STDOUT.flush
           c = IssueCategory.new :project => @target_project,
@@ -404,7 +404,7 @@
         # Milestones
         print "Migrating milestones"
         version_map = {}
-        TracMilestone.find(:all).each do |milestone|
+        TracMilestone.all.each do |milestone|
           print '.'
           STDOUT.flush
           # First we try to find the wiki page...
@@ -443,18 +443,18 @@
                                         :field_format => 'string')
 
           next if f.new_record?
-          f.trackers = Tracker.find(:all)
+          f.trackers = Tracker.all
           f.projects << @target_project
           custom_field_map[field.name] = f
         end
         puts
 
         # Trac 'resolution' field as a Redmine custom field
-        r = IssueCustomField.find(:first, :conditions => { :name => "Resolution" })
+        r = IssueCustomField.where(:name => "Resolution").first
         r = IssueCustomField.new(:name => 'Resolution',
                                  :field_format => 'list',
                                  :is_filter => true) if r.nil?
-        r.trackers = Tracker.find(:all)
+        r.trackers = Tracker.all
         r.projects << @target_project
         r.possible_values = (r.possible_values + %w(fixed invalid wontfix duplicate worksforme)).flatten.compact.uniq
         r.save!
@@ -549,7 +549,7 @@
         # Wiki
         print "Migrating wiki"
         if wiki.save
-          TracWikiPage.find(:all, :order => 'name, version').each do |page|
+          TracWikiPage.order('name, version').all.each do |page|
             # Do not migrate Trac manual wiki pages
             next if TRAC_WIKI_PAGES.include?(page.name)
             wiki_edit_count += 1
@@ -603,10 +603,7 @@
       end
 
       def self.encoding(charset)
-        @ic = Iconv.new('UTF-8', charset)
-      rescue Iconv::InvalidEncoding
-        puts "Invalid encoding!"
-        return false
+        @charset = charset
       end
 
       def self.set_trac_directory(path)
@@ -713,11 +710,13 @@
         end
       end
 
-    private
       def self.encode(text)
-        @ic.iconv text
-      rescue
-        text
+        if RUBY_VERSION < '1.9'
+          @ic ||= Iconv.new('UTF-8', @charset)
+          @ic.iconv text
+        else
+          text.to_s.force_encoding(@charset).encode('UTF-8')
+        end
       end
     end
 
diff -r 0a574315af3e -r 4f746d8966dd lib/tasks/redmine.rake
--- a/lib/tasks/redmine.rake
+++ b/lib/tasks/redmine.rake
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -21,6 +21,11 @@
     task :prune => :environment do
       Attachment.prune
     end
+
+    desc 'Moves attachments stored at the root of the file directory (ie. created before Redmine 2.3) to their subdirectories'
+    task :move_to_subdirectories => :environment do
+      Attachment.move_from_root_to_target_directory
+    end
   end
 
   namespace :tokens do
diff -r 0a574315af3e -r 4f746d8966dd lib/tasks/reminder.rake
--- a/lib/tasks/reminder.rake
+++ b/lib/tasks/reminder.rake
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd lib/tasks/testing.rake
--- a/lib/tasks/testing.rake
+++ b/lib/tasks/testing.rake
@@ -100,4 +100,11 @@
     t.test_files = FileList['test/integration/routing/*_test.rb']
   end
   Rake::Task['test:rdm_routing'].comment = "Run the routing tests"
+
+  Rake::TestTask.new(:ui => "db:test:prepare") do |t|
+    t.libs << "test"
+    t.verbose = true
+    t.test_files = FileList['test/ui/**/*_test.rb']
+  end
+  Rake::Task['test:ui'].comment = "Run the UI tests with Capybara (PhantomJS listening on port 4444 is required)"
 end
diff -r 0a574315af3e -r 4f746d8966dd public/images/hourglass.png
Binary file public/images/hourglass.png has changed
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/application.js
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -1,5 +1,5 @@
 /* Redmine - project management software
-   Copyright (C) 2006-2012  Jean-Philippe Lang */
+   Copyright (C) 2006-2013  Jean-Philippe Lang */
 
 function checkAll(id, checked) {
   if (checked) {
@@ -14,12 +14,12 @@
   $(selector).each(function(index) {
     if (!$(this).is(':checked')) { all_checked = false; }
   });
-  $(selector).attr('checked', !all_checked)
+  $(selector).attr('checked', !all_checked);
 }
 
 function showAndScrollTo(id, focus) {
   $('#'+id).show();
-  if (focus!=null) {
+  if (focus !== null) {
     $('#'+focus).focus();
   }
   $('html, body').animate({scrollTop: $('#'+id).offset().top}, 100);
@@ -131,10 +131,10 @@
   select = tr.find('td.operator select');
   for (i=0;i<operators.length;i++){
     var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]);
-    if (operators[i] == operator) {option.attr('selected', true)};
+    if (operators[i] == operator) { option.attr('selected', true); }
     select.append(option);
   }
-  select.change(function(){toggleOperator(field)});
+  select.change(function(){ toggleOperator(field); });
 
   switch (filterOptions['type']){
   case "list":
@@ -146,7 +146,7 @@
       ' <span class="toggle-multiselect">&nbsp;</span></span>'
     );
     select = tr.find('td.values select');
-    if (values.length > 1) {select.attr('multiple', true)};
+    if (values.length > 1) { select.attr('multiple', true); }
     for (i=0;i<filterValues.length;i++){
       var filterValue = filterValues[i];
       var option = $('<option>');
@@ -189,7 +189,7 @@
       var filterValue = allProjects[i];
       var option = $('<option>');
       option.val(filterValue[1]).text(filterValue[0]);
-      if (values[0] == filterValue[1]) {option.attr('selected', true)};
+      if (values[0] == filterValue[1]) { option.attr('selected', true); }
       select.append(option);
     }
   case "integer":
@@ -242,7 +242,13 @@
     case "!*":
     case "*":
     case "t":
+    case "ld":
     case "w":
+    case "lw":
+    case "l2w":
+    case "m":
+    case "lm":
+    case "y":
     case "o":
     case "c":
       enableValues(field, []);
@@ -284,40 +290,6 @@
   $('#'+id).submit();
 }
 
-var fileFieldCount = 1;
-function addFileField() {
-  var fields = $('#attachments_fields');
-  if (fields.children().length >= 10) return false;
-  fileFieldCount++;
-  var s = fields.children('span').first().clone();
-  s.children('input.file').attr('name', "attachments[" + fileFieldCount + "][file]").val('');
-  s.children('input.description').attr('name', "attachments[" + fileFieldCount + "][description]").val('');
-  fields.append(s);
-}
-
-function removeFileField(el) {
-  var fields = $('#attachments_fields');
-  var s = $(el).parents('span').first();
-  if (fields.children().length > 1) {
-    s.remove();
-  } else {
-    s.children('input.file').val('');
-    s.children('input.description').val('');
-  }
-}
-
-function checkFileSize(el, maxSize, message) {
-  var files = el.files;
-  if (files) {
-    for (var i=0; i<files.length; i++) {
-      if (files[i].size > maxSize) {
-        alert(message);
-        el.value = "";
-      }
-    }
-  }
-}
-
 function showTab(name) {
   $('div#content .tab-content').hide();
   $('div.tabs a').removeClass('selected');
@@ -380,7 +352,7 @@
 
 function showModal(id, width) {
   var el = $('#'+id).first();
-  if (el.length == 0 || el.is(':visible')) {return;}
+  if (el.length === 0 || el.is(':visible')) {return;}
   var title = el.find('h3.title').text();
   el.dialog({
     width: width,
@@ -484,18 +456,22 @@
   });
 }
 
-function observeAutocompleteField(fieldId, url) {
+function observeAutocompleteField(fieldId, url, options) {
   $(document).ready(function() {
-    $('#'+fieldId).autocomplete({
+    $('#'+fieldId).autocomplete($.extend({
       source: url,
-      minLength: 2
-    });
+      minLength: 2,
+      search: function(){$('#'+fieldId).addClass('ajax-loading');},
+      response: function(){$('#'+fieldId).removeClass('ajax-loading');}
+    }, options));
+    $('#'+fieldId).addClass('autocomplete');
   });
 }
 
 function observeSearchfield(fieldId, targetId, url) {
   $('#'+fieldId).each(function() {
     var $this = $(this);
+    $this.addClass('autocomplete');
     $this.attr('data-value-was', $this.val());
     var check = function() {
       var val = $this.val();
@@ -505,7 +481,7 @@
           url: url,
           type: 'get',
           data: {q: $this.val()},
-          success: function(data){ $('#'+targetId).html(data); },
+          success: function(data){ if(targetId) $('#'+targetId).html(data); },
           beforeSend: function(){ $this.addClass('ajax-loading'); },
           complete: function(){ $this.removeClass('ajax-loading'); }
         });
@@ -570,18 +546,21 @@
     });
     if (warn) {return warnLeavingUnsavedMessage;}
   };
-};
+}
 
-$(document).ready(function(){
-  $('#ajax-indicator').bind('ajaxSend', function(){
-    if ($('.ajax-loading').length == 0) {
+function setupAjaxIndicator() {
+
+  $('#ajax-indicator').bind('ajaxSend', function(event, xhr, settings) {
+  
+    if ($('.ajax-loading').length === 0 && settings.contentType != 'application/octet-stream') {
       $('#ajax-indicator').show();
     }
   });
-  $('#ajax-indicator').bind('ajaxStop', function(){
+  
+  $('#ajax-indicator').bind('ajaxStop', function() {
     $('#ajax-indicator').hide();
   });
-});
+}
 
 function hideOnLoad() {
   $('.hol').hide();
@@ -601,6 +580,12 @@
   });
 }
 
+function blockEventPropagation(event) {
+  event.stopPropagation();
+  event.preventDefault();
+}
+
+$(document).ready(setupAjaxIndicator);
 $(document).ready(hideOnLoad);
 $(document).ready(addFormObserversForDoubleSubmit);
 
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/attachments.js
--- /dev/null
+++ b/public/javascripts/attachments.js
@@ -0,0 +1,188 @@
+/* Redmine - project management software
+   Copyright (C) 2006-2013  Jean-Philippe Lang */
+
+function addFile(inputEl, file, eagerUpload) {
+
+  if ($('#attachments_fields').children().length < 10) {
+
+    var attachmentId = addFile.nextAttachmentId++;
+
+    var fileSpan = $('<span>', { id: 'attachments_' + attachmentId });
+
+    fileSpan.append(
+        $('<input>', { type: 'text', 'class': 'filename readonly', name: 'attachments[' + attachmentId + '][filename]', readonly: 'readonly'} ).val(file.name),
+        $('<input>', { type: 'text', 'class': 'description', name: 'attachments[' + attachmentId + '][description]', maxlength: 255, placeholder: $(inputEl).data('description-placeholder') } ).toggle(!eagerUpload),
+        $('<a>&nbsp</a>').attr({ href: "#", 'class': 'remove-upload' }).click(removeFile).toggle(!eagerUpload)
+    ).appendTo('#attachments_fields');
+
+    if(eagerUpload) {
+      ajaxUpload(file, attachmentId, fileSpan, inputEl);
+    }
+
+    return attachmentId;
+  }
+  return null;
+}
+
+addFile.nextAttachmentId = 1;
+
+function ajaxUpload(file, attachmentId, fileSpan, inputEl) {
+
+  function onLoadstart(e) {
+    fileSpan.removeClass('ajax-waiting');
+    fileSpan.addClass('ajax-loading');
+    $('input:submit', $(this).parents('form')).attr('disabled', 'disabled');
+  }
+
+  function onProgress(e) {
+    if(e.lengthComputable) {
+      this.progressbar( 'value', e.loaded * 100 / e.total );
+    }
+  }
+
+  function actualUpload(file, attachmentId, fileSpan, inputEl) {
+
+    ajaxUpload.uploading++;
+
+    uploadBlob(file, $(inputEl).data('upload-path'), attachmentId, {
+        loadstartEventHandler: onLoadstart.bind(progressSpan),
+        progressEventHandler: onProgress.bind(progressSpan)
+      })
+      .done(function(result) {
+        progressSpan.progressbar( 'value', 100 ).remove();
+        fileSpan.find('input.description, a').css('display', 'inline-block');
+      })
+      .fail(function(result) {
+        progressSpan.text(result.statusText);
+      }).always(function() {
+        ajaxUpload.uploading--;
+        fileSpan.removeClass('ajax-loading');
+        var form = fileSpan.parents('form');
+        if (form.queue('upload').length == 0 && ajaxUpload.uploading == 0) {
+          $('input:submit', form).removeAttr('disabled');
+        }
+        form.dequeue('upload');
+      });
+  }
+
+  var progressSpan = $('<div>').insertAfter(fileSpan.find('input.filename'));
+  progressSpan.progressbar();
+  fileSpan.addClass('ajax-waiting');
+
+  var maxSyncUpload = $(inputEl).data('max-concurrent-uploads');
+
+  if(maxSyncUpload == null || maxSyncUpload <= 0 || ajaxUpload.uploading < maxSyncUpload)
+    actualUpload(file, attachmentId, fileSpan, inputEl);
+  else
+    $(inputEl).parents('form').queue('upload', actualUpload.bind(this, file, attachmentId, fileSpan, inputEl));
+}
+
+ajaxUpload.uploading = 0;
+
+function removeFile() {
+  $(this).parent('span').remove();
+  return false;
+}
+
+function uploadBlob(blob, uploadUrl, attachmentId, options) {
+
+  var actualOptions = $.extend({
+    loadstartEventHandler: $.noop,
+    progressEventHandler: $.noop
+  }, options);
+
+  uploadUrl = uploadUrl + '?attachment_id=' + attachmentId;
+  if (blob instanceof window.File) {
+    uploadUrl += '&filename=' + encodeURIComponent(blob.name);
+  }
+
+  return $.ajax(uploadUrl, {
+    type: 'POST',
+    contentType: 'application/octet-stream',
+    beforeSend: function(jqXhr) {
+      jqXhr.setRequestHeader('Accept', 'application/js');
+    },
+    xhr: function() {
+      var xhr = $.ajaxSettings.xhr();
+      xhr.upload.onloadstart = actualOptions.loadstartEventHandler;
+      xhr.upload.onprogress = actualOptions.progressEventHandler;
+      return xhr;
+    },
+    data: blob,
+    cache: false,
+    processData: false
+  });
+}
+
+function addInputFiles(inputEl) {
+  var clearedFileInput = $(inputEl).clone().val('');
+
+  if (inputEl.files) {
+    // upload files using ajax
+    uploadAndAttachFiles(inputEl.files, inputEl);
+    $(inputEl).remove();
+  } else {
+    // browser not supporting the file API, upload on form submission
+    var attachmentId;
+    var aFilename = inputEl.value.split(/\/|\\/);
+    attachmentId = addFile(inputEl, { name: aFilename[ aFilename.length - 1 ] }, false);
+    if (attachmentId) {
+      $(inputEl).attr({ name: 'attachments[' + attachmentId + '][file]', style: 'display:none;' }).appendTo('#attachments_' + attachmentId);
+    }
+  }
+
+  clearedFileInput.insertAfter('#attachments_fields');
+}
+
+function uploadAndAttachFiles(files, inputEl) {
+
+  var maxFileSize = $(inputEl).data('max-file-size');
+  var maxFileSizeExceeded = $(inputEl).data('max-file-size-message');
+
+  var sizeExceeded = false;
+  $.each(files, function() {
+    if (this.size && maxFileSize && this.size > parseInt(maxFileSize)) {sizeExceeded=true;}
+  });
+  if (sizeExceeded) {
+    window.alert(maxFileSizeExceeded);
+  } else {
+    $.each(files, function() {addFile(inputEl, this, true);});
+  }
+}
+
+function handleFileDropEvent(e) {
+
+  $(this).removeClass('fileover');
+  blockEventPropagation(e);
+
+  if ($.inArray('Files', e.dataTransfer.types) > -1) {
+    uploadAndAttachFiles(e.dataTransfer.files, $('input:file.file_selector'));
+  }
+}
+
+function dragOverHandler(e) {
+  $(this).addClass('fileover');
+  blockEventPropagation(e);
+}
+
+function dragOutHandler(e) {
+  $(this).removeClass('fileover');
+  blockEventPropagation(e);
+}
+
+function setupFileDrop() {
+  if (window.File && window.FileList && window.ProgressEvent && window.FormData) {
+
+    $.event.fixHooks.drop = { props: [ 'dataTransfer' ] };
+
+    $('form div.box').has('input:file').each(function() {
+      $(this).on({
+          dragover: dragOverHandler,
+          dragleave: dragOutHandler,
+          drop: handleFileDropEvent
+      });
+    });
+  }
+}
+
+$(document).ready(setupFileDrop);
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/context_menu.js
--- a/public/javascripts/context_menu.js
+++ b/public/javascripts/context_menu.js
@@ -186,7 +186,7 @@
 function contextMenuClearDocumentSelection() {
   // TODO
   if (document.selection) {
-    document.selection.clear(); // IE
+    document.selection.empty(); // IE
   } else {
     window.getSelection().removeAllRanges();
   }
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/gantt.js
--- /dev/null
+++ b/public/javascripts/gantt.js
@@ -0,0 +1,172 @@
+var draw_gantt = null;
+var draw_top;
+var draw_right;
+var draw_left;
+
+var rels_stroke_width = 2;
+
+function setDrawArea() {
+  draw_top   = $("#gantt_draw_area").position().top;
+  draw_right = $("#gantt_draw_area").width();
+  draw_left  = $("#gantt_area").scrollLeft();
+}
+
+function getRelationsArray() {
+  var arr = new Array();
+  $.each($('div.task_todo[data-rels]'), function(index_div, element) {
+    var element_id = $(element).attr("id");
+    if (element_id != null) {
+      var issue_id = element_id.replace("task-todo-issue-", "");
+      var data_rels = $(element).data("rels");
+      for (rel_type_key in data_rels) {
+        $.each(data_rels[rel_type_key], function(index_issue, element_issue) {
+          arr.push({issue_from: issue_id, issue_to: element_issue,
+                    rel_type: rel_type_key});
+        });
+      }
+    }
+  });
+  return arr;
+}
+
+function drawRelations() {
+  var arr = getRelationsArray();
+  $.each(arr, function(index_issue, element_issue) {
+    var issue_from = $("#task-todo-issue-" + element_issue["issue_from"]);
+    var issue_to   = $("#task-todo-issue-" + element_issue["issue_to"]);
+    if (issue_from.size() == 0 || issue_to.size() == 0) {
+      return;
+    }
+    var issue_height = issue_from.height();
+    var issue_from_top   = issue_from.position().top  + (issue_height / 2) - draw_top;
+    var issue_from_right = issue_from.position().left + issue_from.width();
+    var issue_to_top   = issue_to.position().top  + (issue_height / 2) - draw_top;
+    var issue_to_left  = issue_to.position().left;
+    var color = issue_relation_type[element_issue["rel_type"]]["color"];
+    var landscape_margin = issue_relation_type[element_issue["rel_type"]]["landscape_margin"];
+    var issue_from_right_rel = issue_from_right + landscape_margin;
+    var issue_to_left_rel    = issue_to_left    - landscape_margin;
+    draw_gantt.path(["M", issue_from_right + draw_left,     issue_from_top,
+                     "L", issue_from_right_rel + draw_left, issue_from_top])
+                   .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+    if (issue_from_right_rel < issue_to_left_rel) {
+      draw_gantt.path(["M", issue_from_right_rel + draw_left, issue_from_top,
+                       "L", issue_from_right_rel + draw_left, issue_to_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+      draw_gantt.path(["M", issue_from_right_rel + draw_left, issue_to_top,
+                       "L", issue_to_left + draw_left,        issue_to_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+    } else {
+      var issue_middle_top = issue_to_top +
+                                (issue_height *
+                                   ((issue_from_top > issue_to_top) ? 1 : -1));
+      draw_gantt.path(["M", issue_from_right_rel + draw_left, issue_from_top,
+                       "L", issue_from_right_rel + draw_left, issue_middle_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+      draw_gantt.path(["M", issue_from_right_rel + draw_left, issue_middle_top,
+                       "L", issue_to_left_rel + draw_left,    issue_middle_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+      draw_gantt.path(["M", issue_to_left_rel + draw_left, issue_middle_top,
+                       "L", issue_to_left_rel + draw_left, issue_to_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+      draw_gantt.path(["M", issue_to_left_rel + draw_left, issue_to_top,
+                       "L", issue_to_left + draw_left,     issue_to_top])
+                     .attr({stroke: color,
+                          "stroke-width": rels_stroke_width
+                          });
+    }
+    draw_gantt.path(["M", issue_to_left + draw_left, issue_to_top,
+                     "l", -4 * rels_stroke_width, -2 * rels_stroke_width,
+                     "l", 0, 4 * rels_stroke_width, "z"])
+                   .attr({stroke: "none",
+                          fill: color,
+                          "stroke-linecap": "butt",
+                          "stroke-linejoin": "miter"
+                          });
+  });
+}
+
+function getProgressLinesArray() {
+  var arr = new Array();
+  var today_left = $('#today_line').position().left;
+  arr.push({left: today_left, top: 0});
+  $.each($('div.issue-subject, div.version-name'), function(index, element) {
+    var t = $(element).position().top - draw_top ;
+    var h = ($(element).height() / 9);
+    var element_top_upper  = t - h;
+    var element_top_center = t + (h * 3);
+    var element_top_lower  = t + (h * 8);
+    var issue_closed   = $(element).children('span').hasClass('issue-closed');
+    var version_closed = $(element).children('span').hasClass('version-closed');
+    if (issue_closed || version_closed) {
+      arr.push({left: today_left, top: element_top_center});
+    } else {
+      var issue_done = $("#task-done-" + $(element).attr("id"));
+      var is_behind_start = $(element).children('span').hasClass('behind-start-date');
+      var is_over_end     = $(element).children('span').hasClass('over-end-date');
+      if (is_over_end) {
+        arr.push({left: draw_right, top: element_top_upper, is_right_edge: true});
+        arr.push({left: draw_right, top: element_top_lower, is_right_edge: true, none_stroke: true});
+      } else if (issue_done.size() > 0) {
+        var done_left = issue_done.first().position().left +
+                           issue_done.first().width();
+        arr.push({left: done_left, top: element_top_center});
+      } else if (is_behind_start) {
+        arr.push({left: 0 , top: element_top_upper, is_left_edge: true});
+        arr.push({left: 0 , top: element_top_lower, is_left_edge: true, none_stroke: true});
+      } else {
+        var todo_left = today_left;
+        var issue_todo = $("#task-todo-" + $(element).attr("id"));
+        if (issue_todo.size() > 0){
+          todo_left = issue_todo.first().position().left;
+        }
+        arr.push({left: Math.min(today_left, todo_left), top: element_top_center});
+      }
+    }
+  });
+  return arr;
+}
+
+function drawGanttProgressLines() {
+  var arr = getProgressLinesArray();
+  var color = $("#today_line")
+                    .css("border-left-color");
+  var i;
+  for(i = 1 ; i < arr.length ; i++) {
+    if (!("none_stroke" in arr[i]) &&
+        (!("is_right_edge" in arr[i - 1] && "is_right_edge" in arr[i]) &&
+         !("is_left_edge"  in arr[i - 1] && "is_left_edge"  in arr[i]))
+        ) {
+      var x1 = (arr[i - 1].left == 0) ? 0 : arr[i - 1].left + draw_left;
+      var x2 = (arr[i].left == 0)     ? 0 : arr[i].left     + draw_left;
+      draw_gantt.path(["M", x1, arr[i - 1].top,
+                       "L", x2, arr[i].top])
+                   .attr({stroke: color, "stroke-width": 2});
+    }
+  }
+}
+
+function drawGanttHandler() {
+  var folder = document.getElementById('gantt_draw_area');
+  if(draw_gantt != null)
+    draw_gantt.clear();
+  else
+    draw_gantt = Raphael(folder);
+  setDrawArea();
+  if ($("#draw_progress_line").attr('checked'))
+    drawGanttProgressLines();
+  if ($("#draw_rels").attr('checked'))
+    drawRelations();
+}
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/i18n/jquery.ui.datepicker-az.js
--- /dev/null
+++ b/public/javascripts/i18n/jquery.ui.datepicker-az.js
@@ -0,0 +1,23 @@
+/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */
+/* Written by Jamil Najafov (necefov33@gmail.com). */
+jQuery(function($) {
+	$.datepicker.regional['az'] = {
+		closeText: 'BaÄŸla',
+		prevText: '&#x3C;Geri',
+		nextText: 'Ä°rÉ™li&#x3E;',
+		currentText: 'BugÃ¼n',
+		monthNames: ['Yanvar','Fevral','Mart','Aprel','May','Ä°yun',
+		'Ä°yul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'],
+		monthNamesShort: ['Yan','Fev','Mar','Apr','May','Ä°yun',
+		'Ä°yul','Avq','Sen','Okt','Noy','Dek'],
+		dayNames: ['Bazar','Bazar ertÉ™si','Ã‡É™rÅŸÉ™nbÉ™ axÅŸamÄ±','Ã‡É™rÅŸÉ™nbÉ™','CÃ¼mÉ™ axÅŸamÄ±','CÃ¼mÉ™','ÅžÉ™nbÉ™'],
+		dayNamesShort: ['B','Be','Ã‡a','Ã‡','Ca','C','Åž'],
+		dayNamesMin: ['B','B','Ã‡','Ð¡','Ã‡','C','Åž'],
+		weekHeader: 'Hf',
+		dateFormat: 'dd.mm.yy',
+		firstDay: 1,
+		isRTL: false,
+		showMonthAfterYear: false,
+		yearSuffix: ''};
+	$.datepicker.setDefaults($.datepicker.regional['az']);
+});
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/i18n/jquery.ui.datepicker-pt.js
--- /dev/null
+++ b/public/javascripts/i18n/jquery.ui.datepicker-pt.js
@@ -0,0 +1,22 @@
+/* Portuguese initialisation for the jQuery UI date picker plugin. */
+jQuery(function($){
+	$.datepicker.regional['pt'] = {
+		closeText: 'Fechar',
+		prevText: '&#x3C;Anterior',
+		nextText: 'Seguinte',
+		currentText: 'Hoje',
+		monthNames: ['Janeiro','Fevereiro','MarÃ§o','Abril','Maio','Junho',
+		'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
+		monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun',
+		'Jul','Ago','Set','Out','Nov','Dez'],
+		dayNames: ['Domingo','Segunda-feira','TerÃ§a-feira','Quarta-feira','Quinta-feira','Sexta-feira','SÃ¡bado'],
+		dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','SÃ¡b'],
+		dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','SÃ¡b'],
+		weekHeader: 'Sem',
+		dateFormat: 'dd/mm/yy',
+		firstDay: 0,
+		isRTL: false,
+		showMonthAfterYear: false,
+		yearSuffix: ''};
+	$.datepicker.setDefaults($.datepicker.regional['pt']);
+});
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/jquery-1.7.2-ui-1.8.21-ujs-2.0.3.js
--- a/public/javascripts/jquery-1.7.2-ui-1.8.21-ujs-2.0.3.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/*! jQuery v1.7.2 jquery.com | jquery.org/license */
-(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test("Â ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
-a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
-.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
-
-/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.core.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;return!b.href||!g||f.nodeName.toLowerCase()!=="map"?!1:(h=a("img[usemap=#"+g+"]")[0],!!h&&d(h))}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.ui=a.ui||{};if(a.ui.version)return;a.extend(a.ui,{version:"1.8.21",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;return a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0),/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){return a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)}),c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){return c===b?g["inner"+d].call(this):this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){return typeof b!="number"?g["outer"+d].call(this,b):this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));c.offsetHeight,a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!d||!a.element[0].parentNode)return;for(var e=0;e<d.length;e++)a.options[d[e][0]]&&d[e][1].apply(a.element,c)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(b,c){if(a(b).css("overflow")==="hidden")return!1;var d=c&&c==="left"?"scrollLeft":"scrollTop",e=!1;return b[d]>0?!0:(b[d]=1,e=b[d]>0,b[d]=0,e)},isOverAxis:function(a,b,c){return a>b&&a<b+c},isOver:function(b,c,d,e,f,g){return a.ui.isOverAxis(b,d,f)&&a.ui.isOverAxis(c,e,g)}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.widget.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){if(a.cleanData){var c=a.cleanData;a.cleanData=function(b){for(var d=0,e;(e=b[d])!=null;d++)try{a(e).triggerHandler("remove")}catch(f){}c(b)}}else{var d=a.fn.remove;a.fn.remove=function(b,c){return this.each(function(){return c||(!b||a.filter(b,[this]).length)&&a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(b){}}),d.call(a(this),b,c)})}}a.widget=function(b,c,d){var e=b.split(".")[0],f;b=b.split(".")[1],f=e+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][f]=function(c){return!!a.data(c,b)},a[e]=a[e]||{},a[e][b]=function(a,b){arguments.length&&this._createWidget(a,b)};var g=new c;g.options=a.extend(!0,{},g.options),a[e][b].prototype=a.extend(!0,g,{namespace:e,widgetName:b,widgetEventPrefix:a[e][b].prototype.widgetEventPrefix||b,widgetBaseClass:f},d),a.widget.bridge(b,a[e][b])},a.widget.bridge=function(c,d){a.fn[c]=function(e){var f=typeof e=="string",g=Array.prototype.slice.call(arguments,1),h=this;return e=!f&&g.length?a.extend.apply(null,[!0,e].concat(g)):e,f&&e.charAt(0)==="_"?h:(f?this.each(function(){var d=a.data(this,c),f=d&&a.isFunction(d[e])?d[e].apply(d,g):d;if(f!==d&&f!==b)return h=f,!1}):this.each(function(){var b=a.data(this,c);b?b.option(e||{})._init():a.data(this,c,new d(e,this))}),h)}},a.Widget=function(a,b){arguments.length&&this._createWidget(a,b)},a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(b,c){a.data(c,this.widgetName,this),this.element=a(c),this.options=a.extend(!0,{},this.options,this._getCreateOptions(),b);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()}),this._create(),this._trigger("create"),this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName),this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled "+"ui-state-disabled")},widget:function(){return this.element},option:function(c,d){var e=c;if(arguments.length===0)return a.extend({},this.options);if(typeof c=="string"){if(d===b)return this.options[c];e={},e[c]=d}return this._setOptions(e),this},_setOptions:function(b){var c=this;return a.each(b,function(a,b){c._setOption(a,b)}),this},_setOption:function(a,b){return this.options[a]=b,a==="disabled"&&this.widget()[b?"addClass":"removeClass"](this.widgetBaseClass+"-disabled"+" "+"ui-state-disabled").attr("aria-disabled",b),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(b,c,d){var e,f,g=this.options[b];d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent;if(f)for(e in f)e in c||(c[e]=f[e]);return this.element.trigger(c,d),!(a.isFunction(g)&&g.call(this.element[0],c,d)===!1||c.isDefaultPrevented())}}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.mouse.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){var c=!1;a(document).mouseup(function(a){c=!1}),a.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var b=this;this.element.bind("mousedown."+this.widgetName,function(a){return b._mouseDown(a)}).bind("click."+this.widgetName,function(c){if(!0===a.data(c.target,b.widgetName+".preventClickEvent"))return a.removeData(c.target,b.widgetName+".preventClickEvent"),c.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(b){if(c)return;this._mouseStarted&&this._mouseUp(b),this._mouseDownEvent=b;var d=this,e=b.which==1,f=typeof this.options.cancel=="string"&&b.target.nodeName?a(b.target).closest(this.options.cancel).length:!1;if(!e||f||!this._mouseCapture(b))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){d.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)){this._mouseStarted=this._mouseStart(b)!==!1;if(!this._mouseStarted)return b.preventDefault(),!0}return!0===a.data(b.target,this.widgetName+".preventClickEvent")&&a.removeData(b.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(a){return d._mouseMove(a)},this._mouseUpDelegate=function(a){return d._mouseUp(a)},a(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),b.preventDefault(),c=!0,!0},_mouseMove:function(b){return!a.browser.msie||document.documentMode>=9||!!b.button?this._mouseStarted?(this._mouseDrag(b),b.preventDefault()):(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b)),!this._mouseStarted):this._mouseUp(b)},_mouseUp:function(b){return a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b)),!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.position.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;return i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1],this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]===e)return;var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0},top:function(b,c){if(c.at[1]===e)return;var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];return!c||!c.ownerDocument?null:b?a.isFunction(b)?this.each(function(c){a(this).offset(b.call(this,c,a(this).offset()))}):this.each(function(){a.offset.setOffset(this,b)}):h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&a.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.draggable.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!this.element.data("draggable"))return;return this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy(),this},_mouseCapture:function(b){var c=this.options;return this.helper||c.disabled||a(b.target).is(".ui-resizable-handle")?!1:(this.handle=this._getHandle(b),this.handle?(c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(b){var c=this.options;return this.helper=this._createHelper(b),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment(),this._trigger("start",b)===!1?(this._clear(),!1):(this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b),!0)},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1)return this._mouseUp({}),!1;this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";return a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);var d=this.element[0],e=!1;while(d&&(d=d.parentNode))d==document&&(e=!0);if(!e&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var f=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){f._trigger("stop",b)!==!1&&f._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){return this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b),a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;return a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)}),c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute"),d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.left<h[0]&&(f=h[0]+this.offset.click.left),b.pageY-this.offset.click.top<h[1]&&(g=h[1]+this.offset.click.top),b.pageX-this.offset.click.left>h[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.top<h[1]||j-this.offset.click.top>h[3]?j-this.offset.click.top<h[1]?j+c.grid[1]:j-c.grid[1]:j:j;var k=c.grid[0]?this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0]:this.originalPageX;f=h?k-this.offset.click.left<h[0]||k-this.offset.click.left>h[2]?k-this.offset.click.left<h[0]?k+c.grid[0]:k-c.grid[0]:k:k}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(b,c,d){return d=d||this._uiHash(),a.ui.plugin.call(this,b,[c,d]),b=="drag"&&(this.positionAbs=this._convertPositionTo("absolute")),a.Widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(a){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),a.extend(a.ui.draggable,{version:"1.8.21"}),a.ui.plugin.add("draggable","connectToSortable",{start:function(b,c){var d=a(this).data("draggable"),e=d.options,f=a.extend({},c,{item:d.element});d.sortables=[],a(e.connectToSortable).each(function(){var c=a.data(this,"sortable");c&&!c.options.disabled&&(d.sortables.push({instance:c,shouldRevert:c.options.revert}),c.refreshPositions(),c._trigger("activate",b,f))})},stop:function(b,c){var d=a(this).data("draggable"),e=a.extend({},c,{item:d.element});a.each(d.sortables,function(){this.instance.isOver?(this.instance.isOver=0,d.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(b),this.instance.options.helper=this.instance.options._helper,d.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",b,e))})},drag:function(b,c){var d=a(this).data("draggable"),e=this,f=function(b){var c=this.offset.click.top,d=this.offset.click.left,e=this.positionAbs.top,f=this.positionAbs.left,g=b.height,h=b.width,i=b.top,j=b.left;return a.ui.isOver(e+c,f+d,i,j,g,h)};a.each(d.sortables,function(f){this.instance.positionAbs=d.positionAbs,this.instance.helperProportions=d.helperProportions,this.instance.offset.click=d.offset.click,this.instance._intersectsWith(this.instance.containerCache)?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=a(e).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return c.helper[0]},b.target=this.instance.currentItem[0],this.instance._mouseCapture(b,!0),this.instance._mouseStart(b,!0,!0),this.instance.offset.click.top=d.offset.click.top,this.instance.offset.click.left=d.offset.click.left,this.instance.offset.parent.left-=d.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=d.offset.parent.top-this.instance.offset.parent.top,d._trigger("toSortable",b),d.dropped=this.instance.element,d.currentItem=d.element,this.instance.fromOutside=d),this.instance.currentItem&&this.instance._mouseDrag(b)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",b,this.instance._uiHash(this.instance)),this.instance._mouseStop(b,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),d._trigger("fromSortable",b),d.dropped=!1)})}}),a.ui.plugin.add("draggable","cursor",{start:function(b,c){var d=a("body"),e=a(this).data("draggable").options;d.css("cursor")&&(e._cursor=d.css("cursor")),d.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;d._cursor&&a("body").css("cursor",d._cursor)}}),a.ui.plugin.add("draggable","opacity",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("opacity")&&(e._opacity=d.css("opacity")),d.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;d._opacity&&a(c.helper).css("opacity",d._opacity)}}),a.ui.plugin.add("draggable","scroll",{start:function(b,c){var d=a(this).data("draggable");d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"&&(d.overflowOffset=d.scrollParent.offset())},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=!1;if(d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"){if(!e.axis||e.axis!="x")d.overflowOffset.top+d.scrollParent[0].offsetHeight-b.pageY<e.scrollSensitivity?d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop+e.scrollSpeed:b.pageY-d.overflowOffset.top<e.scrollSensitivity&&(d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop-e.scrollSpeed);if(!e.axis||e.axis!="y")d.overflowOffset.left+d.scrollParent[0].offsetWidth-b.pageX<e.scrollSensitivity?d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft+e.scrollSpeed:b.pageX-d.overflowOffset.left<e.scrollSensitivity&&(d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft-e.scrollSpeed)}else{if(!e.axis||e.axis!="x")b.pageY-a(document).scrollTop()<e.scrollSensitivity?f=a(document).scrollTop(a(document).scrollTop()-e.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<e.scrollSensitivity&&(f=a(document).scrollTop(a(document).scrollTop()+e.scrollSpeed));if(!e.axis||e.axis!="y")b.pageX-a(document).scrollLeft()<e.scrollSensitivity?f=a(document).scrollLeft(a(document).scrollLeft()-e.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<e.scrollSensitivity&&(f=a(document).scrollLeft(a(document).scrollLeft()+e.scrollSpeed))}f!==!1&&a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(d,b)}}),a.ui.plugin.add("draggable","snap",{start:function(b,c){var d=a(this).data("draggable"),e=d.options;d.snapElements=[],a(e.snap.constructor!=String?e.snap.items||":data(draggable)":e.snap).each(function(){var b=a(this),c=b.offset();this!=d.element[0]&&d.snapElements.push({item:this,width:b.outerWidth(),height:b.outerHeight(),top:c.top,left:c.left})})},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=e.snapTolerance,g=c.offset.left,h=g+d.helperProportions.width,i=c.offset.top,j=i+d.helperProportions.height;for(var k=d.snapElements.length-1;k>=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f<g&&g<m+f&&n-f<i&&i<o+f||l-f<g&&g<m+f&&n-f<j&&j<o+f||l-f<h&&h<m+f&&n-f<i&&i<o+f||l-f<h&&h<m+f&&n-f<j&&j<o+f)){d.snapElements[k].snapping&&d.options.snap.release&&d.options.snap.release.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=!1;continue}if(e.snapMode!="inner"){var p=Math.abs(n-j)<=f,q=Math.abs(o-i)<=f,r=Math.abs(l-h)<=f,s=Math.abs(m-g)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n-d.helperProportions.height,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l-d.helperProportions.width}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m}).left-d.margins.left)}var t=p||q||r||s;if(e.snapMode!="outer"){var p=Math.abs(n-i)<=f,q=Math.abs(o-j)<=f,r=Math.abs(l-g)<=f,s=Math.abs(m-h)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o-d.helperProportions.height,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m-d.helperProportions.width}).left-d.margins.left)}!d.snapElements[k].snapping&&(p||q||r||s||t)&&d.options.snap.snap&&d.options.snap.snap.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=p||q||r||s||t}}}),a.ui.plugin.add("draggable","stack",{start:function(b,c){var d=a(this).data("draggable").options,e=a.makeArray(a(d.stack)).sort(function(b,c){return(parseInt(a(b).css("zIndex"),10)||0)-(parseInt(a(c).css("zIndex"),10)||0)});if(!e.length)return;var f=parseInt(e[0].style.zIndex)||0;a(e).each(function(a){this.style.zIndex=f+a}),this[0].style.zIndex=f+e.length}}),a.ui.plugin.add("draggable","zIndex",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("zIndex")&&(e._zIndex=d.css("zIndex")),d.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;d._zIndex&&a(c.helper).css("zIndex",d._zIndex)}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.droppable.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var b=this.options,c=b.accept;this.isover=0,this.isout=1,this.accept=a.isFunction(c)?c:function(a){return a.is(c)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},a.ui.ddmanager.droppables[b.scope]=a.ui.ddmanager.droppables[b.scope]||[],a.ui.ddmanager.droppables[b.scope].push(this),b.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c<b.length;c++)b[c]==this&&b.splice(c,1);return this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable"),this},_setOption:function(b,c){b=="accept"&&(this.accept=a.isFunction(c)?c:function(a){return a.is(c)}),a.Widget.prototype._setOption.apply(this,arguments)},_activate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),c&&this._trigger("activate",b,this.ui(c))},_deactivate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),c&&this._trigger("deactivate",b,this.ui(c))},_over:function(b){var c=a.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return;this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",b,this.ui(c)))},_out:function(b){var c=a.ui.ddmanager.current;if(!c||(c.currentItem||c.element)[0]==this.element[0])return;this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",b,this.ui(c)))},_drop:function(b,c){var d=c||a.ui.ddmanager.current;if(!d||(d.currentItem||d.element)[0]==this.element[0])return!1;var e=!1;return this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var b=a.data(this,"droppable");if(b.options.greedy&&!b.options.disabled&&b.options.scope==d.options.scope&&b.accept.call(b.element[0],d.currentItem||d.element)&&a.ui.intersect(d,a.extend(b,{offset:b.element.offset()}),b.options.tolerance))return e=!0,!1}),e?!1:this.accept.call(this.element[0],d.currentItem||d.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",b,this.ui(d)),this.element):!1},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}}),a.extend(a.ui.droppable,{version:"1.8.21"}),a.ui.intersect=function(b,c,d){if(!c.offset)return!1;var e=(b.positionAbs||b.position.absolute).left,f=e+b.helperProportions.width,g=(b.positionAbs||b.position.absolute).top,h=g+b.helperProportions.height,i=c.offset.left,j=i+c.proportions.width,k=c.offset.top,l=k+c.proportions.height;switch(d){case"fit":return i<=e&&f<=j&&k<=g&&h<=l;case"intersect":return i<e+b.helperProportions.width/2&&f-b.helperProportions.width/2<j&&k<g+b.helperProportions.height/2&&h-b.helperProportions.height/2<l;case"pointer":var m=(b.positionAbs||b.position.absolute).left+(b.clickOffset||b.offset.click).left,n=(b.positionAbs||b.position.absolute).top+(b.clickOffset||b.offset.click).top,o=a.ui.isOver(n,m,k,i,c.proportions.height,c.proportions.width);return o;case"touch":return(g>=k&&g<=l||h>=k&&h<=l||g<k&&h>l)&&(e>=i&&e<=j||f>=i&&f<=j||e<i&&f>j);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();g:for(var h=0;h<d.length;h++){if(d[h].options.disabled||b&&!d[h].accept.call(d[h].element[0],b.currentItem||b.element))continue;for(var i=0;i<f.length;i++)if(f[i]==d[h].element[0]){d[h].proportions.height=0;continue g}d[h].visible=d[h].element.css("display")!="none";if(!d[h].visible)continue;e=="mousedown"&&d[h]._activate.call(d[h],c),d[h].offset=d[h].element.offset(),d[h].proportions={width:d[h].element[0].offsetWidth,height:d[h].element[0].offsetHeight}}},drop:function(b,c){var d=!1;return a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){if(!this.options)return;!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)&&(d=this._drop.call(this,c)||d),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],b.currentItem||b.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,c))}),d},dragStart:function(b,c){b.element.parents(":not(body,html)").bind("scroll.droppable",function(){b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)})},drag:function(b,c){b.options.refreshPositions&&a.ui.ddmanager.prepareOffsets(b,c),a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){if(this.options.disabled||this.greedyChild||!this.visible)return;var d=a.ui.intersect(b,this,this.options.tolerance),e=!d&&this.isover==1?"isout":d&&this.isover==0?"isover":null;if(!e)return;var f;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");g.length&&(f=a.data(g[0],"droppable"),f.greedyChild=e=="isover"?1:0)}f&&e=="isover"&&(f.isover=0,f.isout=1,f._out.call(f,c)),this[e]=1,this[e=="isout"?"isover":"isout"]=0,this[e=="isover"?"_over":"_out"].call(this,c),f&&e=="isout"&&(f.isout=0,f.isover=1,f._over.call(f,c))})},dragStop:function(b,c){b.element.parents(":not(body,html)").unbind("scroll.droppable"),b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)}}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.resizable.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.widget("ui.resizable",a.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var b=this,c=this.options;this.element.addClass("ui-resizable"),a.extend(this,{_aspectRatio:!!c.aspectRatio,aspectRatio:c.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:c.helper||c.ghost||c.animate?c.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(a('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e<d.length;e++){var f=a.trim(d[e]),g="ui-resizable-"+f,h=a('<div class="ui-resizable-handle '+g+'"></div>');h.css({zIndex:c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){if(c.disabled)return;a(this).removeClass("ui-resizable-autohide"),b._handles.show()},function(){if(c.disabled)return;b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}return this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement),this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");return a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b),!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);return l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui()),!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}return a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),e<h.maxWidth&&(h.maxWidth=e),g<h.maxHeight&&(h.maxHeight=g);this._vBoundaries=h},_updateCache:function(a){var b=this.options;this.offset=this.helper.offset(),d(a.left)&&(this.position.left=a.left),d(a.top)&&(this.position.top=a.top),d(a.height)&&(this.size.height=a.height),d(a.width)&&(this.size.width=a.width)},_updateRatio:function(a,b){var c=this.options,e=this.position,f=this.size,g=this.axis;return d(a.height)?a.width=a.height*this.aspectRatio:d(a.width)&&(a.height=a.width/this.aspectRatio),g=="sw"&&(a.left=e.left+(f.width-a.width),a.top=null),g=="nw"&&(a.top=e.top+(f.height-a.height),a.left=e.left+(f.width-a.width)),a},_respectSize:function(a,b){var c=this.helper,e=this._vBoundaries,f=this._aspectRatio||b.shiftKey,g=this.axis,h=d(a.width)&&e.maxWidth&&e.maxWidth<a.width,i=d(a.height)&&e.maxHeight&&e.maxHeight<a.height,j=d(a.width)&&e.minWidth&&e.minWidth>a.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;return p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null),a},_proportionallyResize:function(){var b=this.options;if(!this._proportionallyResizeElements.length)return;var c=this.helper||this.element;for(var d=0;d<this._proportionallyResizeElements.length;d++){var e=this._proportionallyResizeElements[d];if(!this.borderDif){var f=[e.css("borderTopWidth"),e.css("borderRightWidth"),e.css("borderBottomWidth"),e.css("borderLeftWidth")],g=[e.css("paddingTop"),e.css("paddingRight"),e.css("paddingBottom"),e.css("paddingLeft")];this.borderDif=a.map(f,function(a,b){var c=parseInt(a,10)||0,d=parseInt(g[b],10)||0;return c+d})}if(!a.browser.msie||!a(c).is(":hidden")&&!a(c).parents(":hidden").length)e.css({height:c.height()-this.borderDif[0]-this.borderDif[2]||0,width:c.width()-this.borderDif[1]-this.borderDif[3]||0});else continue}},_renderProxy:function(){var b=this.element,c=this.options;this.elementOffset=b.offset();if(this._helper){this.helper=this.helper||a('<div style="overflow:hidden;"></div>');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.21"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10)})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,d){a(b).each(function(){var b=a(this),e=a(this).data("resizable-alsoresize"),f={},g=d&&d.length?d:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(g,function(a,b){var c=(e[b]||0)+(h[b]||0);c&&c>=0&&(f[b]=c||null)}),b.css(f)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!i)return;e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/d.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*d.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.selectable.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("<div class='ui-selectable-helper'></div>")},destroy:function(){return this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy(),this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(this.options.disabled)return;var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");return d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element}),!1}})},_mouseDrag:function(b){var c=this;this.dragged=!0;if(this.options.disabled)return;var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}return this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!i||i.element==c.element[0])return;var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.right<e||i.top>h||i.bottom<f):d.tolerance=="fit"&&(j=i.left>e&&i.right<g&&i.top>f&&i.bottom<h),j?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,c._trigger("selecting",b,{selecting:i.element}))):(i.selecting&&((b.metaKey||b.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),c._trigger("unselecting",b,{unselecting:i.element}))),i.selected&&!b.metaKey&&!b.ctrlKey&&!i.startselected&&(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,c._trigger("unselecting",b,{unselecting:i.element})))}),!1},_mouseStop:function(b){var c=this;this.dragged=!1;var d=this.options;return a(".ui-unselecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-unselecting"),d.unselecting=!1,d.startselected=!1,c._trigger("unselected",b,{unselected:d.element})}),a(".ui-selecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected"),d.selecting=!1,d.selected=!0,d.startselected=!0,c._trigger("selected",b,{selected:d.element})}),this._trigger("stop",b),this.helper.remove(),!1}}),a.extend(a.ui.selectable,{version:"1.8.21"})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.sortable.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.widget("ui.sortable",a.ui.mouse,{widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},destroy:function(){a.Widget.prototype.destroy.call(this),this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--)this.items[b].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f)return e=a(this),!1});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}return this.currentItem=e,this._removeCurrentsFromItems(),!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));return a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b),!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY<c.scrollSensitivity?this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop+c.scrollSpeed:b.pageY-this.overflowOffset.top<c.scrollSensitivity&&(this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop-c.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-b.pageX<c.scrollSensitivity?this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft+c.scrollSpeed:b.pageX-this.overflowOffset.left<c.scrollSensitivity&&(this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft-c.scrollSpeed)):(b.pageY-a(document).scrollTop()<c.scrollSensitivity?d=a(document).scrollTop(a(document).scrollTop()-c.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<c.scrollSensitivity&&(d=a(document).scrollTop(a(document).scrollTop()+c.scrollSpeed)),b.pageX-a(document).scrollLeft()<c.scrollSensitivity?d=a(document).scrollLeft(a(document).scrollLeft()-c.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<c.scrollSensitivity&&(d=a(document).scrollLeft(a(document).scrollLeft()+c.scrollSpeed))),d!==!1&&a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var e=this.items.length-1;e>=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}return this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(b,c){if(!b)return;a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"="),d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")}),d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+j<i&&b+k>f&&b+k<g;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?l:f<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<g&&h<d+this.helperProportions.height/2&&e-this.helperProportions.height/2<i},_intersectsWithPointer:function(b){var c=this.options.axis==="x"||a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top,b.height),d=this.options.axis==="y"||a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left,b.width),e=c&&d,f=this._getDragVerticalDirection(),g=this._getDragHorizontalDirection();return e?this.floating?g&&g=="right"||f=="down"?2:1:f&&(f=="down"?2:1):!1},_intersectsWithSides:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top+b.height/2,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left+b.width/2,b.width),e=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();return this.floating&&f?f=="right"&&d||f=="left"&&!d:e&&(e=="down"&&c||e=="up"&&!c)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){return this._refreshItems(a),this.refreshPositions(),this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(b){this.items=[],this.containers=[this];var c=this.items,d=this,e=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]],f=this._connectWith();if(f&&this.ready)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i<m;i++){var n=a(l[i]);n.data(this.widgetName+"-item",k),c.push({item:n,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var c=this.items.length-1;c>=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return e||(b.style.visibility="hidden"),b},update:function(a,b){if(e&&!d.forcePlaceholderSize)return;b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!c)return;if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.containers[d].floating?this.items[i].item.offset().left:this.items[i].item.offset().top;Math.abs(j-h)<f&&(f=Math.abs(j-h),g=this.items[i],this.direction=j-h>0?"down":"up")}if(!g&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[d],g?this._rearrange(b,g,null,!0):this._rearrange(b,null,this.containers[d].element,!0),this._trigger("change",b,this._uiHash()),this.containers[d]._trigger("change",b,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1}},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;return d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]),d[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(d[0].style.width==""||c.forceHelperSize)&&d.width(this.currentItem.width()),(d[0].style.height==""||c.forceHelperSize)&&d.height(this.currentItem.height()),d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)){var c=a(b.containment)[0],d=a(b.containment).offset(),e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var f=b.pageX,g=b.pageY;if(this.originalPosition){this.containment&&(b.pageX-this.offset.click.left<this.containment[0]&&(f=this.containment[0]+this.offset.click.left),b.pageY-this.offset.click.top<this.containment[1]&&(g=this.containment[1]+this.offset.click.top),b.pageX-this.offset.click.left>this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.top<this.containment[1]||h-this.offset.click.top>this.containment[3]?h-this.offset.click.top<this.containment[1]?h+c.grid[1]:h-c.grid[1]:h:h;var i=this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0];f=this.containment?i-this.offset.click.left<this.containment[0]||i-this.offset.click.left>this.containment[2]?i-this.offset.click.left<this.containment[0]?i+c.grid[0]:i-c.grid[0]:i:i}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_rearrange:function(a,b,c,d){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var e=this,f=this.counter;window.setTimeout(function(){f==e.counter&&e.refreshPositions(!d)},0)},_clear:function(b,c){this.reverting=!1;var d=[],e=this;!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var f in this._storedCSS)if(this._storedCSS[f]=="auto"||this._storedCSS[f]=="static")this._storedCSS[f]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!c&&d.push(function(a){this._trigger("receive",a,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!c&&d.push(function(a){this._trigger("update",a,this._uiHash())});if(!a.ui.contains(this.element[0],this.currentItem[0])){c||d.push(function(a){this._trigger("remove",a,this._uiHash())});for(var f=this.containers.length-1;f>=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}return!1}c||this._trigger("beforeStop",b,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!c){for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){a.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(b){var c=b||this;return{helper:c.helper,placeholder:c.placeholder||a([]),position:c.position,originalPosition:c.originalPosition,offset:c.positionAbs,item:c.currentItem,sender:b?b.element:null}}}),a.extend(a.ui.sortable,{version:"1.8.21"})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.accordion.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:!0,clearStyle:!1,collapsible:!1,event:"click",fillSpace:!1,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var b=this,c=b.options;b.running=0,b.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"),b.headers=b.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){if(c.disabled)return;a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){if(c.disabled)return;a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){if(c.disabled)return;a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){if(c.disabled)return;a(this).removeClass("ui-state-focus")}),b.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(c.navigation){var d=b.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var e=d.closest(".ui-accordion-header");e.length?b.active=e:b.active=d.closest(".ui-accordion-content").prev()}}b.active=b._findActive(b.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"),b.active.next().addClass("ui-accordion-content-active"),b._createIcons(),b.resize(),b.element.attr("role","tablist"),b.headers.attr("role","tab").bind("keydown.accordion",function(a){return b._keydown(a)}).next().attr("role","tabpanel"),b.headers.not(b.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide(),b.active.length?b.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):b.headers.eq(0).attr("tabIndex",0),a.browser.safari||b.headers.find("a").attr("tabIndex",-1),c.event&&b.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(a){b._clickHandler.call(b,a,this),a.preventDefault()})},_createIcons:function(){var b=this.options;b.icons&&(a("<span></span>").addClass("ui-icon "+b.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(b.icons.header).toggleClass(b.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove(),this.element.removeClass("ui-accordion-icons")},destroy:function(){var b=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"),this.headers.find("a").removeAttr("tabIndex"),this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");return(b.autoHeight||b.fillHeight)&&c.css("height",""),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b=="active"&&this.activate(c),b=="icons"&&(this._destroyIcons(),c&&this._createIcons()),b=="disabled"&&this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(b){if(this.options.disabled||b.altKey||b.ctrlKey)return;var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:b.target},b.target),b.preventDefault()}return f?(a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus(),!1):!0},resize:function(){var b=this.options,c;if(b.fillSpace){if(a.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height(),a.browser.msie&&this.element.parent().css("overflow",d),this.headers.each(function(){c-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else b.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c));return this},activate:function(a){this.options.active=a;var b=this._findActive(a)[0];return this._clickHandler({target:b},b),this},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===!1?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,c){var d=this.options;if(d.disabled)return;if(!b.target){if(!d.collapsible)return;this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),this.active.next().addClass("ui-accordion-content-active");var e=this.active.next(),f={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:e},g=this.active=a([]);this._toggle(g,e,f);return}var h=a(b.currentTarget||c),i=h[0]===this.active[0];d.active=d.collapsible&&i?!1:this.headers.index(h);if(this.running||!d.collapsible&&i)return;var j=this.active,g=h.next(),e=this.active.next(),f={options:d,newHeader:i&&d.collapsible?a([]):h,oldHeader:this.active,newContent:i&&d.collapsible?a([]):g,oldContent:e},k=this.headers.index(this.active[0])>this.headers.index(h[0]);this.active=i?a([]):h,this._toggle(g,e,f,i,k),j.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),i||(h.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),h.next().addClass("ui-accordion-content-active"));return},_toggle:function(b,c,d,e,f){var g=this,h=g.options;g.toShow=b,g.toHide=c,g.data=d;var i=function(){if(!g)return;return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data),g.running=c.size()===0?b.size():c.size();if(h.animated){var j={};h.collapsible&&e?j={toShow:a([]),toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace}:j={toShow:b,toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace},h.proxied||(h.proxied=h.animated),h.proxiedDuration||(h.proxiedDuration=h.duration),h.animated=a.isFunction(h.proxied)?h.proxied(j):h.proxied,h.duration=a.isFunction(h.proxiedDuration)?h.proxiedDuration(j):h.proxiedDuration;var k=a.ui.accordion.animations,l=h.duration,m=h.animated;m&&!k[m]&&!a.easing[m]&&(m="slide"),k[m]||(k[m]=function(a){this.slide(a,{easing:m,duration:l||700})}),k[m](j)}else h.collapsible&&e?b.toggle():(c.hide(),b.show()),i(!0);c.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur(),b.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(this.running)return;this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data)}}),a.extend(a.ui.accordion,{version:"1.8.21",animations:{slide:function(b,c){b=a.extend({easing:"swing",duration:300},b,c);if(!b.toHide.size()){b.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},b);return}if(!b.toShow.size()){b.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},b);return}var d=b.toShow.css("overflow"),e=0,f={},g={},h=["height","paddingTop","paddingBottom"],i,j=b.toShow;i=j[0].style.width,j.width(j.parent().width()-parseFloat(j.css("paddingLeft"))-parseFloat(j.css("paddingRight"))-(parseFloat(j.css("borderLeftWidth"))||0)-(parseFloat(j.css("borderRightWidth"))||0)),a.each(h,function(c,d){g[d]="hide";var e=(""+a.css(b.toShow[0],d)).match(/^([\d+-.]+)(.*)$/);f[d]={value:e[1],unit:e[2]||"px"}}),b.toShow.css({height:0,overflow:"hidden"}).show(),b.toHide.filter(":hidden").each(b.complete).end().filter(":visible").animate(g,{step:function(a,c){c.prop=="height"&&(e=c.end-c.start===0?0:(c.now-c.start)/(c.end-c.start)),b.toShow[0].style[c.prop]=e*f[c.prop].value+f[c.prop].unit},duration:b.duration,easing:b.easing,complete:function(){b.autoHeight||b.toShow.css("height",""),b.toShow.css({width:i,overflow:d}),b.complete()}})},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1e3:200})}}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.autocomplete.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.isMultiLine=this.element.is("textarea"),this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(b.options.disabled||b.element.propAttr("readOnly"))return;d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._keyEvent("previous",c);break;case e.DOWN:b._keyEvent("next",c);break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){if(b.options.disabled)return;b.selectedItem=null,b.previous=b.element.val()}).bind("blur.autocomplete",function(a){if(b.options.disabled)return;clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150)}),this._initSource(),this.menu=a("<ul></ul>").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,c,d;a.isArray(this.options.source)?(c=this.options.source,this.source=function(b,d){d(a.ui.autocomplete.filter(c,b.term))}):typeof this.options.source=="string"?(d=this.options.source,this.source=function(c,e){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:d,data:c,dataType:"json",success:function(a,b){e(a)},error:function(){e([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)===!1)return;return this._search(a)},_search:function(a){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.source({term:a},this._response())},_response:function(){var a=this,b=++c;return function(d){b===c&&a.__response(d),a.pending--,a.pending||a.element.removeClass("ui-autocomplete-loading")}},__response:function(a){!this.options.disabled&&a&&a.length?(a=this._normalize(a),this._suggest(a),this._trigger("open")):this.close()},close:function(a){clearTimeout(this.closing),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.deactivate(),this._trigger("close",a))},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(b){return b.length&&b[0].label&&b[0].value?b:a.map(b,function(b){return typeof b=="string"?{label:b,value:b}:a.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(b){var c=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(c,b),this.menu.deactivate(),this.menu.refresh(),c.show(),this._resizeMenu(),c.position(a.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(b,c){var d=this;a.each(c,function(a,c){d._renderItem(b,c)})},_renderItem:function(b,c){return a("<li></li>").data("item.autocomplete",c).append(a("<a></a>").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible")){this.search(null,b);return}if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)},widget:function(){return this.menu.element},_keyEvent:function(a,b){if(!this.isMultiLine||this.menu.element.is(":visible"))this._move(a,b),b.preventDefault()}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})})(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){if(!a(c.target).closest(".ui-menu-item a").length)return;c.preventDefault(),b.select(c)}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){if(!this.active)return;this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active){this.activate(c,this.element.children(b));return}var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:first")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[a.fn.prop?"prop":"attr"]("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})}(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.button.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){var c,d,e,f,g="ui-button ui-widget ui-state-default ui-corner-all",h="ui-state-hover ui-state-active ",i="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",j=function(){var b=a(this).find(":ui-button");setTimeout(function(){b.button("refresh")},1)},k=function(b){var c=b.name,d=b.form,e=a([]);return c&&(d?e=a(d).find("[name='"+c+"']"):e=a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form})),e};a.widget("ui.button",{options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",j),typeof this.options.disabled!="boolean"?this.options.disabled=!!this.element.propAttr("disabled"):this.element.propAttr("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var b=this,h=this.options,i=this.type==="checkbox"||this.type==="radio",l="ui-state-hover"+(i?"":" ui-state-active"),m="ui-state-focus";h.label===null&&(h.label=this.buttonElement.html()),this.buttonElement.addClass(g).attr("role","button").bind("mouseenter.button",function(){if(h.disabled)return;a(this).addClass("ui-state-hover"),this===c&&a(this).addClass("ui-state-active")}).bind("mouseleave.button",function(){if(h.disabled)return;a(this).removeClass(l)}).bind("click.button",function(a){h.disabled&&(a.preventDefault(),a.stopImmediatePropagation())}),this.element.bind("focus.button",function(){b.buttonElement.addClass(m)}).bind("blur.button",function(){b.buttonElement.removeClass(m)}),i&&(this.element.bind("change.button",function(){if(f)return;b.refresh()}),this.buttonElement.bind("mousedown.button",function(a){if(h.disabled)return;f=!1,d=a.pageX,e=a.pageY}).bind("mouseup.button",function(a){if(h.disabled)return;if(d!==a.pageX||e!==a.pageY)f=!0})),this.type==="checkbox"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).toggleClass("ui-state-active"),b.buttonElement.attr("aria-pressed",b.element[0].checked)}):this.type==="radio"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).addClass("ui-state-active"),b.buttonElement.attr("aria-pressed","true");var c=b.element[0];k(c).not(c).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown.button",function(){if(h.disabled)return!1;a(this).addClass("ui-state-active"),c=this,a(document).one("mouseup",function(){c=null})}).bind("mouseup.button",function(){if(h.disabled)return!1;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(b){if(h.disabled)return!1;(b.keyCode==a.ui.keyCode.SPACE||b.keyCode==a.ui.keyCode.ENTER)&&a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(b){b.keyCode===a.ui.keyCode.SPACE&&a(this).click()})),this._setOption("disabled",h.disabled),this._resetButton()},_determineButtonType:function(){this.element.is(":checkbox")?this.type="checkbox":this.element.is(":radio")?this.type="radio":this.element.is("input")?this.type="input":this.type="button";if(this.type==="checkbox"||this.type==="radio"){var a=this.element.parents().filter(":last"),b="label[for='"+this.element.attr("id")+"']";this.buttonElement=a.find(b),this.buttonElement.length||(a=a.length?a.siblings():this.element.siblings(),this.buttonElement=a.filter(b),this.buttonElement.length||(this.buttonElement=a.find(b))),this.element.addClass("ui-helper-hidden-accessible");var c=this.element.is(":checked");c&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.attr("aria-pressed",c)}else this.buttonElement=this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(g+" "+h+" "+i).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title"),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);if(b==="disabled"){c?this.element.propAttr("disabled",!0):this.element.propAttr("disabled",!1);return}this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b),this.type==="radio"?k(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):this.type==="checkbox"&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if(this.type==="input"){this.options.label&&this.element.val(this.options.label);return}var b=this.buttonElement.removeClass(i),c=a("<span></span>",this.element[0].ownerDocument).addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary,f=[];d.primary||d.secondary?(this.options.text&&f.push("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary")),d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>"),d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>"),this.options.text||(f.push(e?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||b.attr("title",c))):f.push("ui-button-text-only"),b.addClass(f.join(" "))}}),a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c),a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"),a.Widget.prototype.destroy.call(this)}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.dialog.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){var c="ui-dialog ui-widget ui-widget-content ui-corner-all ",d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},e={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},f=a.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c=a(this).css(b).offset().top;c<0&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.options.title=this.options.title||this.originalTitle;var b=this,d=b.options,e=d.title||"&#160;",f=a.ui.dialog.getTitleId(b.element),g=(b.uiDialog=a("<div></div>")).appendTo(document.body).hide().addClass(c+d.dialogClass).css({zIndex:d.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(c){d.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(a){b.moveToTop(!1,a)}),h=b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g),i=(b.uiDialogTitlebar=a("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),j=a('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){j.addClass("ui-state-hover")},function(){j.removeClass("ui-state-hover")}).focus(function(){j.addClass("ui-state-focus")}).blur(function(){j.removeClass("ui-state-focus")}).click(function(a){return b.close(a),!1}).appendTo(i),k=(b.uiDialogTitlebarCloseText=a("<span></span>")).addClass("ui-icon ui-icon-closethick").text(d.closeText).appendTo(j),l=a("<span></span>").addClass("ui-dialog-title").attr("id",f).html(e).prependTo(i);a.isFunction(d.beforeclose)&&!a.isFunction(d.beforeClose)&&(d.beforeClose=d.beforeclose),i.find("*").add(i).disableSelection(),d.draggable&&a.fn.draggable&&b._makeDraggable(),d.resizable&&a.fn.resizable&&b._makeResizable(),b._createButtons(d.buttons),b._isOpen=!1,a.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;return a.overlay&&a.overlay.destroy(),a.uiDialog.hide(),a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),a.uiDialog.remove(),a.originalTitle&&a.element.attr("title",a.originalTitle),a},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1===c._trigger("beforeClose",b))return;return c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!==c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d),c},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this,e=d.options,f;return e.modal&&!b||!e.stack&&!e.modal?d._trigger("focus",c):(e.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=e.zIndex),d.overlay&&(a.ui.dialog.maxZ+=1,d.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),f={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()},a.ui.dialog.maxZ+=1,d.uiDialog.css("z-index",a.ui.dialog.maxZ),d.element.attr(f),d._trigger("focus",c),d)},open:function(){if(this._isOpen)return;var b=this,c=b.options,d=b.uiDialog;return b.overlay=c.modal?new a.ui.dialog.overlay(b):null,b._size(),b._position(c.position),d.show(c.show),b.moveToTop(!0),c.modal&&d.bind("keydown.ui-dialog",function(b){if(b.keyCode!==a.ui.keyCode.TAB)return;var c=a(":tabbable",this),d=c.filter(":first"),e=c.filter(":last");if(b.target===e[0]&&!b.shiftKey)return d.focus(1),!1;if(b.target===d[0]&&b.shiftKey)return e.focus(1),!1}),a(b.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(),b._isOpen=!0,b._trigger("open"),b},_createButtons:function(b){var c=this,d=!1,e=a("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=a("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);c.uiDialog.find(".ui-dialog-buttonpane").remove(),typeof b=="object"&&b!==null&&a.each(b,function(){return!(d=!0)}),d&&(a.each(b,function(b,d){d=a.isFunction(d)?{click:d,text:b}:d;var e=a('<button type="button"></button>').click(function(){d.click.apply(c.element[0],arguments)}).appendTo(g);a.each(d,function(a,b){if(a==="click")return;a in f?e[a](b):e.attr(a,b)}),a.fn.button&&e.button()}),e.appendTo(c.uiDialog))},_makeDraggable:function(){function f(a){return{position:a.position,offset:a.offset}}var b=this,c=b.options,d=a(document),e;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,g){e=c.height==="auto"?"auto":a(this).height(),a(this).height(a(this).height()).addClass("ui-dialog-dragging"),b._trigger("dragStart",d,f(g))},drag:function(a,c){b._trigger("drag",a,f(c))},stop:function(g,h){c.position=[h.position.left-d.scrollLeft(),h.position.top-d.scrollTop()],a(this).removeClass("ui-dialog-dragging").height(e),b._trigger("dragStop",g,f(h)),a.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function h(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}c=c===b?this.options.resizable:c;var d=this,e=d.options,f=d.uiDialog.css("position"),g=typeof c=="string"?c:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:g,start:function(b,c){a(this).addClass("ui-dialog-resizing"),d._trigger("resizeStart",b,h(c))},resize:function(a,b){d._trigger("resize",a,h(b))},stop:function(b,c){a(this).removeClass("ui-dialog-resizing"),e.height=a(this).height(),e.width=a(this).width(),d._trigger("resizeStop",b,h(c)),a.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if(typeof b=="string"||typeof b=="object"&&"0"in b)c=b.split?b.split(" "):[b[0],b[1]],c.length===1&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b)),e||this.uiDialog.hide()},_setOptions:function(b){var c=this,f={},g=!1;a.each(b,function(a,b){c._setOption(a,b),a in d&&(g=!0),a in e&&(f[a]=b)}),g&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,d){var e=this,f=e.uiDialog;switch(b){case"beforeclose":b="beforeClose";break;case"buttons":e._createButtons(d);break;case"closeText":e.uiDialogTitlebarCloseText.text(""+d);break;case"dialogClass":f.removeClass(e.options.dialogClass).addClass(c+d);break;case"disabled":d?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case"draggable":var g=f.is(":data(draggable)");g&&!d&&f.draggable("destroy"),!g&&d&&e._makeDraggable();break;case"position":e._position(d);break;case"resizable":var h=f.is(":data(resizable)");h&&!d&&f.resizable("destroy"),h&&typeof d=="string"&&f.resizable("option","handles",d),!h&&d!==!1&&e._makeResizable(d);break;case"title":a(".ui-dialog-title",e.uiDialogTitlebar).html(""+(d||"&#160;"))}a.Widget.prototype._setOption.apply(e,arguments)},_size:function(){var b=this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),b.minWidth>b.width&&(b.width=b.minWidth),c=this.uiDialog.css({height:"auto",width:b.width}).height(),d=Math.max(0,b.minHeight-c);if(b.height==="auto")if(a.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();var f=this.element.css("height","auto").height();e||this.uiDialog.hide(),this.element.height(Math.max(f,d))}else this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),a.extend(a.ui.dialog,{version:"1.8.21",uuid:0,maxZ:0,getTitleId:function(a){var b=a.attr("id");return b||(this.uuid+=1,b=this.uuid),"ui-dialog-title-"+b},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}}),a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){this.instances.length===0&&(setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()<a.ui.dialog.overlay.maxZ)return!1})},1),a(document).bind("keydown.dialog-overlay",function(c){b.options.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}),a(window).bind("resize.dialog-overlay",a.ui.dialog.overlay.resize));var c=(this.oldInstances.pop()||a("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});return a.fn.bgiframe&&c.bgiframe(),this.instances.push(c),c},destroy:function(b){var c=a.inArray(b,this.instances);c!=-1&&this.oldInstances.push(this.instances.splice(c,1)[0]),this.instances.length===0&&a([document,window]).unbind(".dialog-overlay"),b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))}),this.maxZ=d},height:function(){var b,c;return a.browser.msie&&a.browser.version<7?(b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),b<c?a(window).height()+"px":b+"px"):a(document).height()+"px"},width:function(){var b,c;return a.browser.msie?(b=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),c=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth),b<c?a(window).width()+"px":b+"px"):a(document).width()+"px"},resize:function(){var b=a([]);a.each(a.ui.dialog.overlay.instances,function(){b=b.add(this)}),b.css({width:0,height:0}).css({width:a.ui.dialog.overlay.width(),height:a.ui.dialog.overlay.height()})}}),a.extend(a.ui.dialog.overlay.prototype,{destroy:function(){a.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.slider.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){var c=5;a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var b=this,d=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",g=d.values&&d.values.length||1,h=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(d.disabled?" ui-slider-disabled ui-disabled":"")),this.range=a([]),d.range&&(d.range===!0&&(d.values||(d.values=[this._valueMin(),this._valueMin()]),d.values.length&&d.values.length!==2&&(d.values=[d.values[0],d.values[0]])),this.range=a("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;i<g;i+=1)h.push(f);this.handles=e.add(a(h.join("")).appendTo(b.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(a){a.preventDefault()}).hover(function(){d.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){d.disabled?a(this).blur():(a(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),a(this).addClass("ui-state-focus"))}).blur(function(){a(this).removeClass("ui-state-focus")}),this.handles.each(function(b){a(this).data("index.ui-slider-handle",b)}),this.handles.keydown(function(d){var e=a(this).data("index.ui-slider-handle"),f,g,h,i;if(b.options.disabled)return;switch(d.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:d.preventDefault();if(!b._keySliding){b._keySliding=!0,a(this).addClass("ui-state-active"),f=b._start(d,e);if(f===!1)return}}i=b.options.step,b.options.values&&b.options.values.length?g=h=b.values(e):g=h=b.value();switch(d.keyCode){case a.ui.keyCode.HOME:h=b._valueMin();break;case a.ui.keyCode.END:h=b._valueMax();break;case a.ui.keyCode.PAGE_UP:h=b._trimAlignValue(g+(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.PAGE_DOWN:h=b._trimAlignValue(g-(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(g===b._valueMax())return;h=b._trimAlignValue(g+i);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(g===b._valueMin())return;h=b._trimAlignValue(g-i)}b._slide(d,e,h)}).keyup(function(c){var d=a(this).data("index.ui-slider-handle");b._keySliding&&(b._keySliding=!1,b._stop(c,d),b._change(c,d),a(this).removeClass("ui-state-active"))}),this._refreshValue(),this._animateOff=!1},destroy:function(){return this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"),this._mouseDestroy(),this},_mouseCapture:function(b){var c=this.options,d,e,f,g,h,i,j,k,l;return c.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),d={x:b.pageX,y:b.pageY},e=this._normValueFromMouse(d),f=this._valueMax()-this._valueMin()+1,h=this,this.handles.each(function(b){var c=Math.abs(e-h.values(b));f>c&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i),j===!1?!1:(this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0,!0))},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);return this._slide(a,this._handleIndex,c),!1},_mouseStop:function(a){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;return this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e,this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};return this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c<d)&&(c=d),c!==this.values(b)&&(e=this.values(),e[b]=c,f=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e}),d=this.values(b?0:1),f!==!1&&this.values(b,c,!0))):c!==this.value()&&(f=this._trigger("slide",a,{handle:this.handles[b],value:c}),f!==!1&&this.value(c))},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("change",a,c)}},value:function(a){if(arguments.length){this.options.value=this._trimAlignValue(a),this._refreshValue(),this._change(null,0);return}return this._value()},values:function(b,c){var d,e,f;if(arguments.length>1){this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);return}if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f<d.length;f+=1)d[f]=this._trimAlignValue(e[f]),this._change(null,f);this._refreshValue()},_setOption:function(b,c){var d,e=0;a.isArray(this.options.values)&&(e=this.options.values.length),a.Widget.prototype._setOption.apply(this,arguments);switch(b){case"disabled":c?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.propAttr("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.propAttr("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(d=0;d<e;d+=1)this._change(null,d);this._animateOff=!1}},_value:function(){var a=this.options.value;return a=this._trimAlignValue(a),a},_values:function(a){var b,c,d;if(arguments.length)return b=this.options.values[a],b=this._trimAlignValue(b),b;c=this.options.values.slice();for(d=0;d<c.length;d+=1)c[d]=this._trimAlignValue(c[d]);return c},_trimAlignValue:function(a){if(a<=this._valueMin())return this._valueMin();if(a>=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;return Math.abs(c)*2>=b&&(d+=c>0?b:-b),parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.21"})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.tabs.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){function e(){return++c}function f(){return++d}var c=0,d=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:!1,cookie:null,collapsible:!1,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash)return e.selected=a,!1}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1)return this.blur(),!1;e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected"))return e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur(),!1;if(!f.length)return e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur(),!1}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){return typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$='"+a+"']"))),a},destroy:function(){var b=this.options;return this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie),this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);return j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e])),this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();return d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1<this.anchors.length?1:-1)),c.disabled=a.map(a.grep(c.disabled,function(a,c){return a!=b}),function(a,c){return a>=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0])),this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)==-1)return;return this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b])),this},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;return a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a]))),this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;return this.anchors.eq(a).trigger(this.options.event+".tabs"),this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs")){this.element.dequeue("tabs");return}this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}return this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs"),this},abort:function(){return this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup(),this},url:function(a,b){return this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b),this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.21"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a<c.anchors.length?a:0)},a),b&&b.stopPropagation()}),f=c._unrotate||(c._unrotate=b?function(a){e()}:function(a){a.clientX&&c.rotate(null)});return a?(this.element.bind("tabsshow",e),this.anchors.bind(d.event+".tabs",f),e()):(clearTimeout(c.rotation),this.element.unbind("tabsshow",e),this.anchors.unbind(d.event+".tabs",f),delete this._rotate,delete this._unrotate),this}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.datepicker.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function($,undefined){function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function bindHover(a){var b="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return a.bind("mouseout",function(a){var c=$(a.target).closest(b);if(!c.length)return;c.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){var d=$(c.target).closest(b);if($.datepicker._isDisabledDatepicker(instActive.inline?a.parent()[0]:instActive.input[0])||!d.length)return;d.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),d.addClass("ui-state-hover"),d.hasClass("ui-datepicker-prev")&&d.addClass("ui-datepicker-prev-hover"),d.hasClass("ui-datepicker-next")&&d.addClass("ui-datepicker-next-hover")})}function extendRemove(a,b){$.extend(a,b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}function isArray(a){return a&&($.browser.safari&&typeof a=="object"&&a.length||a.constructor&&a.constructor.toString().match(/\Array\(\)/))}$.extend($.ui,{datepicker:{version:"1.8.21"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){return extendRemove(this._defaults,a||{}),this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);if(c.hasClass(this.markerClassName))return;this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a)},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$('<span class="'+this._appendClass+'">'+c+"</span>"),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('<button type="button"></button>').addClass(this._triggerClass).html(g==""?f:$("<img/>").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){return $.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=a[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(a[0])):$.datepicker._showDatepicker(a[0]),!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;d<a.length;d++)a[d].length>b&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);if(c.hasClass(this.markerClassName))return;c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block")},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+g+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}return this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f),this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!b.hasClass(this.markerClassName))return;var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!b.hasClass(this.markerClassName))return;var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!b.hasClass(this.markerClassName))return;var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return!0;return!1},_getInst:function(a){try{return $.data(a,PROP_NAME)}catch(b){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(a,b,c){var d=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?$.extend({},$.datepicker._defaults):d?b=="all"?$.extend({},d.settings):this._get(d,b):null;var e=b||{};typeof b=="string"&&(e={},e[b]=c);if(d){this._curInst==d&&this._hideDatepicker();var f=this._getDateDatepicker(a,!0),g=this._getMinMaxDate(d,"min"),h=this._getMinMaxDate(d,"max");extendRemove(d.settings,e),g!==null&&e.dateFormat!==undefined&&e.minDate===undefined&&(d.settings.minDate=this._formatDate(d,g)),h!==null&&e.dateFormat!==undefined&&e.maxDate===undefined&&(d.settings.maxDate=this._formatDate(d,h)),this._attachments($(a),d),this._autoSize(d),this._setDate(d,f),this._updateAlternate(d),this._updateDatepicker(d)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){var b=this._getInst(a);b&&this._updateDatepicker(b)},_setDateDatepicker:function(a,b){var c=this._getInst(a);c&&(this._setDate(c,b),this._updateDatepicker(c),this._updateAlternate(c))},_getDateDatepicker:function(a,b){var c=this._getInst(a);return c&&!c.inline&&this._setDateFromField(c,b),c?this._getDate(c):null},_doKeyDown:function(a){var b=$.datepicker._getInst(a.target),c=!0,d=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=!0;if($.datepicker._datepickerShowing)switch(a.keyCode){case 9:$.datepicker._hideDatepicker(),c=!1;break;case 13:var e=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",b.dpDiv);e[0]&&$.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,e[0]);var f=$.datepicker._get(b,"onSelect");if(f){var g=$.datepicker._formatDate(b);f.apply(b.input?b.input[0]:null,[g,b])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 35:(a.ctrlKey||a.metaKey)&&$.datepicker._clearDate(a.target),c=a.ctrlKey||a.metaKey;break;case 36:(a.ctrlKey||a.metaKey)&&$.datepicker._gotoToday(a.target),c=a.ctrlKey||a.metaKey;break;case 37:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?1:-1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 38:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,-7,"D"),c=a.ctrlKey||a.metaKey;break;case 39:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?-1:1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 40:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,7,"D"),c=a.ctrlKey||a.metaKey;break;default:c=!1}else a.keyCode==36&&a.ctrlKey?$.datepicker._showDatepicker(this):c=!1;c&&(a.preventDefault(),a.stopPropagation())},_doKeyPress:function(a){var b=$.datepicker._getInst(a.target);if($.datepicker._get(b,"constrainInput")){var c=$.datepicker._possibleChars($.datepicker._get(b,"dateFormat")),d=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||d<" "||!c||c.indexOf(d)>-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(d){$.datepicker.log(d)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if($.datepicker._isDisabledDatepicker(a)||$.datepicker._lastInput==a)return;var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){return e|=$(this).css("position")=="fixed",!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a));var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+$(document).scrollLeft(),i=document.documentElement.clientHeight+$(document).scrollTop();return b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0),b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!b||a&&b!=$.data(a,PROP_NAME))return;if(this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=function(){$.datepicker._tidyDialog(b)};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,e):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,e),c||e(),this._datepickerShowing=!1;var f=this._get(b,"onClose");f&&f.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!$.datepicker._curInst)return;var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);if(this._isDisabledDatepicker(d[0]))return;this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e)},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if($(d).hasClass(this._unselectableClass)||this._isDisabledDatepicker(e[0]))return;var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();return b.setMonth(0),b.setDate(1),Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1<a.length&&a.charAt(s+1)==b;return c&&s++,c},o=function(a){var c=n(a),d=a=="@"?14:a=="!"?20:a=="y"&&c?4:a=="o"?3:2,e=new RegExp("^\\d{1,"+d+"}"),f=b.substring(r).match(e);if(!f)throw"Missing number at position "+r;return r+=f[0].length,parseInt(f[0],10)},p=function(a,c,d){var e=$.map(n(a)?d:c,function(a,b){return[[b,a]]}).sort(function(a,b){return-(a[1].length-b[1].length)}),f=-1;$.each(e,function(a,c){var d=c[1];if(b.substr(r,d.length).toLowerCase()==d.toLowerCase())return f=c[0],r+=d.length,!1});if(f!=-1)return f+1;throw"Unknown name at position "+r},q=function(){if(b.charAt(r)!=a.charAt(s))throw"Unexpected literal at position "+r;r++},r=0;for(var s=0;s<a.length;s++)if(m)a.charAt(s)=="'"&&!n("'")?m=!1:q();else switch(a.charAt(s)){case"d":k=o("d");break;case"D":p("D",e,f);break;case"o":l=o("o");break;case"m":j=o("m");break;case"M":j=p("M",g,h);break;case"y":i=o("y");break;case"@":var t=new Date(o("@"));i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"!":var t=new Date((o("!")-this._ticksTo1970)/1e4);i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"'":n("'")?q():m=!0;break;default:q()}if(r<b.length)throw"Extra/unparsed characters found in date: "+b.substring(r);i==-1?i=(new Date).getFullYear():i<100&&(i+=(new Date).getFullYear()-(new Date).getFullYear()%100+(i<=d?0:-100));if(l>-1){j=1,k=l;do{var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}while(!0)}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+1<a.length&&a.charAt(m+1)==b;return c&&m++,c},i=function(a,b,c){var d=""+b;if(h(a))while(d.length<c)d="0"+d;return d},j=function(a,b,c,d){return h(a)?d[b]:c[b]},k="",l=!1;if(b)for(var m=0;m<a.length;m++)if(l)a.charAt(m)=="'"&&!h("'")?l=!1:k+=a.charAt(m);else switch(a.charAt(m)){case"d":k+=i("d",b.getDate(),2);break;case"D":k+=j("D",b.getDay(),d,e);break;case"o":k+=i("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":k+=i("m",b.getMonth()+1,2);break;case"M":k+=j("M",b.getMonth(),f,g);break;case"y":k+=h("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case"@":k+=b.getTime();break;case"!":k+=b.getTime()*1e4+this._ticksTo1970;break;case"'":h("'")?k+="'":l=!0;break;default:k+=a.charAt(m)}return k},_possibleChars:function(a){var b="",c=!1,d=function(b){var c=e+1<a.length&&a.charAt(e+1)==b;return c&&e++,c};for(var e=0;e<a.length;e++)if(c)a.charAt(e)=="'"&&!d("'")?c=!1:b+=a.charAt(e);else switch(a.charAt(e)){case"d":case"m":case"y":case"@":b+="0123456789";break;case"D":case"M":return null;case"'":d("'")?b+="'":c=!0;break;default:b+=a.charAt(e)}return b},_get:function(a,b){return a.settings[b]!==undefined?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()==a.lastVal)return;var c=this._get(a,"dateFormat"),d=a.lastVal=a.input?a.input.val():null,e,f;e=f=this._getDefaultDate(a);var g=this._getFormatConfig(a);try{e=this.parseDate(c,d,g)||f}catch(h){this.log(h),d=b?"":d}a.selectedDay=e.getDate(),a.drawMonth=a.selectedMonth=e.getMonth(),a.drawYear=a.selectedYear=e.getFullYear(),a.currentDay=d?e.getDate():0,a.currentMonth=d?e.getMonth():0,a.currentYear=d?e.getFullYear():0,this._adjustInstDate(a)},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var d=function(a){var b=new Date;return b.setDate(b.getDate()+a),b},e=function(b){try{return $.datepicker.parseDate($.datepicker._get(a,"dateFormat"),b,$.datepicker._getFormatConfig(a))}catch(c){}var d=(b.toLowerCase().match(/^c/)?$.datepicker._getDate(a):null)||new Date,e=d.getFullYear(),f=d.getMonth(),g=d.getDate(),h=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,i=h.exec(b);while(i){switch(i[2]||"d"){case"d":case"D":g+=parseInt(i[1],10);break;case"w":case"W":g+=parseInt(i[1],10)*7;break;case"m":case"M":f+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f));break;case"y":case"Y":e+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f))}i=h.exec(b)}return new Date(e,f,g)},f=b==null||b===""?c:typeof b=="string"?e(b):typeof b=="number"?isNaN(b)?c:d(b):new Date(b.getTime());return f=f&&f.toString()=="Invalid Date"?c:f,f&&(f.setHours(0),f.setMinutes(0),f.setSeconds(0),f.setMilliseconds(0)),this._daylightSavingAdjust(f)},_daylightSavingAdjust:function(a){return a?(a.setHours(a.getHours()>12?a.getHours()+2:0),a):null},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&p<l?l:p;while(this._daylightSavingAdjust(new Date(o,n,1))>p)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', -"+i+", 'M');\""+' title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>":e?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', +"+i+", 'M');\""+' title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>":e?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+dpuuid+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>",x=d?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?w:"")+(this._isInRange(a,v)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._gotoToday('#"+a.id+"');\""+">"+u+"</button>":"")+(c?"":w)+"</div>":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L<g[0];L++){var M="";this.maxRows=4;for(var N=0;N<g[1];N++){var O=this._daylightSavingAdjust(new Date(o,n,a.selectedDay)),P=" ui-corner-all",Q="";if(j){Q+='<div class="ui-datepicker-group';if(g[1]>1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+P+'">'+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var R=z?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="<th"+((S+y+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+A[T]+'">'+C[T]+"</span></th>"}Q+=R+"</tr></thead><tbody>";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z<X;Z++){Q+="<tr>";var _=z?'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(Y)+"</td>":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Y<l||m&&Y>m;_+='<td class="'+((S+y+6)%7>=5?" ui-datepicker-week-end":"")+(bb?" ui-datepicker-other-month":"")+(Y.getTime()==O.getTime()&&n==a.selectedMonth&&a._keyEvent||J.getTime()==Y.getTime()&&J.getTime()==O.getTime()?" "+this._dayOverClass:"")+(bc?" "+this._unselectableClass+" ui-state-disabled":"")+(bb&&!G?"":" "+ba[1]+(Y.getTime()==k.getTime()?" "+this._currentClass:"")+(Y.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!bb||G)&&ba[2]?' title="'+ba[2]+'"':"")+(bc?"":' onclick="DP_jQuery_'+dpuuid+".datepicker._selectDay('#"+a.id+"',"+Y.getMonth()+","+Y.getFullYear()+', this);return false;"')+">"+(bb&&!G?"&#xa0;":bc?'<span class="ui-state-default">'+Y.getDate()+"</span>":'<a class="ui-state-default'+(Y.getTime()==b.getTime()?" ui-state-highlight":"")+(Y.getTime()==k.getTime()?" ui-state-active":"")+(bb?" ui-priority-secondary":"")+'" href="#">'+Y.getDate()+"</a>")+"</td>",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+"</tr>"}n++,n>11&&(n=0,o++),Q+="</tbody></table>"+(j?"</div>"+(g[0]>0&&N==g[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),M+=Q}K+=M}return K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""),a._keyEvent=!1,K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this._get(a,"showMonthAfterYear"),l='<div class="ui-datepicker-title">',m="";if(f||!i)m+='<span class="ui-datepicker-month">'+g[b]+"</span>";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" "+">";for(var p=0;p<12;p++)(!n||p>=d.getMonth())&&(!o||p<=e.getMonth())&&(m+='<option value="'+p+'"'+(p==b?' selected="selected"':"")+">"+h[p]+"</option>");m+="</select>"}k||(l+=m+(f||!i||!j?"&#xa0;":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+='<span class="ui-datepicker-year">'+c+"</span>";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" "+">";for(;t<=u;t++)a.yearshtml+='<option value="'+t+'"'+(t==c?' selected="selected"':"")+">"+t+"</option>";a.yearshtml+="</select>",l+=a.yearshtml,a.yearshtml=null}}return l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?"&#xa0;":"")+m),l+="</div>",l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&b<c?c:b;return e=d&&e>d?d:e,e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));return b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth())),this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");return b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10),{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);return typeof a!="string"||a!="isDisabled"&&a!="getDate"&&a!="widget"?a=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b)):this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)}):$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.21",window["DP_jQuery_"+dpuuid]=$})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.progressbar.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=a("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove(),a.Widget.prototype.destroy.apply(this,arguments)},value:function(a){return a===b?this._value():(this._setOption("value",a),this)},_setOption:function(b,c){b==="value"&&(this.options.value=c,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;return typeof a!="number"&&(a=0),Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change")),this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%"),this.element.attr("aria-valuenow",a)}}),a.extend(a.ui.progressbar,{version:"1.8.21"})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.core.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-jQuery.effects||function(a,b){function c(b){var c;return b&&b.constructor==Array&&b.length==3?b:(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))?[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)]:(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))?[parseFloat(c[1])*2.55,parseFloat(c[2])*2.55,parseFloat(c[3])*2.55]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))?[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)]:(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))?[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)]:(c=/rgba\(0, 0, 0, 0\)/.exec(b))?e.transparent:e[a.trim(b).toLowerCase()]}function d(b,d){var e;do{e=a.curCSS(b,d);if(e!=""&&e!="transparent"||a.nodeName(b,"body"))break;d="backgroundColor"}while(b=b.parentNode);return c(e)}function h(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]]){var e=a.length;while(e--)c=a[e],typeof a[c]=="string"&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c])}else for(c in a)typeof a[c]=="string"&&(b[c]=a[c]);return b}function i(b){var c,d;for(c in b)d=b[c],(d==null||a.isFunction(d)||c in g||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function k(b,c,d,e){typeof b=="object"&&(e=c,d=null,c=b,b=c.effect),a.isFunction(c)&&(e=c,d=null,c={});if(typeof c=="number"||a.fx.speeds[c])e=d,d=c,c={};return a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:typeof d=="number"?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,e=e||c.complete,[b,c,d,e]}function l(b){return!b||typeof b=="number"||a.fx.speeds[b]?!0:typeof b=="string"&&!a.effects[b]?!0:!1}a.effects={},a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(b,e){a.fx.step[e]=function(a){a.colorInit||(a.start=d(a.elem,e),a.end=c(a.end),a.colorInit=!0),a.elem.style[e]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var e={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},f=["add","remove","toggle"],g={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(b,c,d,e){return a.isFunction(d)&&(e=d,d=null),this.queue(function(){var g=a(this),k=g.attr("style")||" ",l=i(h.call(this)),m,n=g.attr("class")||"";a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),m=i(h.call(this)),g.attr("class",n),g.animate(j(l,m),{queue:!1,duration:c,easing:d,complete:function(){a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),typeof g.attr("style")=="object"?(g.attr("style").cssText="",g.attr("style").cssText=k):g.attr("style",k),e&&e.apply(this,arguments),a.dequeue(this)}})})},a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{add:b},c,d,e]):this._addClass(b)},_removeClass:a.fn.removeClass,removeClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{remove:b},c,d,e]):this._removeClass(b)},_toggleClass:a.fn.toggleClass,toggleClass:function(c,d,e,f,g){return typeof d=="boolean"||d===b?e?a.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):a.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(b,c,d,e,f){return a.effects.animateClass.apply(this,[{add:c,remove:b},d,e,f])}}),a.extend(a.effects,{version:"1.8.21",save:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.data("ec.storage."+b[c],a[0].style[b[c]])},restore:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.css(b[c],a.data("ec.storage."+b[c]))},setMode:function(a,b){return b=="toggle"&&(b=a.is(":hidden")?"show":"hide"),b},getBaseline:function(a,b){var c,d;switch(a[0]){case"top":c=0;break;case"middle":c=.5;break;case"bottom":c=1;break;default:c=a[0]/b.height}switch(a[1]){case"left":d=0;break;case"center":d=.5;break;case"right":d=1;break;default:d=a[1]/b.width}return{x:d,y:c}},createWrapper:function(b){if(b.parent().is(".ui-effects-wrapper"))return b.parent();var c={width:b.outerWidth(!0),height:b.outerHeight(!0),"float":b.css("float")},d=a("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e=document.activeElement;try{e.id}catch(f){e=document.body}return b.wrap(d),(b[0]===e||a.contains(b[0],e))&&a(e).focus(),d=b.parent(),b.css("position")=="static"?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),d.css(c).show()},removeWrapper:function(b){var c,d=document.activeElement;return b.parent().is(".ui-effects-wrapper")?(c=b.parent().replaceWith(b),(b[0]===d||a.contains(b[0],d))&&a(d).focus(),c):b},setTransition:function(b,c,d,e){return e=e||{},a.each(c,function(a,c){var f=b.cssUnit(c);f[0]>0&&(e[c]=f[0]*d+f[1])}),e}}),a.fn.extend({effect:function(b,c,d,e){var f=k.apply(this,arguments),g={options:f[1],duration:f[2],callback:f[3]},h=g.options.mode,i=a.effects[b];return a.fx.off||!i?h?this[h](g.duration,g.callback):this.each(function(){g.callback&&g.callback.call(this)}):i.call(this,g)},_show:a.fn.show,show:function(a){if(l(a))return this._show.apply(this,arguments);var b=k.apply(this,arguments);return b[1].mode="show",this.effect.apply(this,b)},_hide:a.fn.hide,hide:function(a){if(l(a))return this._hide.apply(this,arguments);var b=k.apply(this,arguments);return b[1].mode="hide",this.effect.apply(this,b)},__toggle:a.fn.toggle,toggle:function(b){if(l(b)||typeof b=="boolean"||a.isFunction(b))return this.__toggle.apply(this,arguments);var c=k.apply(this,arguments);return c[1].mode="toggle",this.effect.apply(this,c)},cssUnit:function(b){var c=this.css(b),d=[];return a.each(["em","px","%","pt"],function(a,b){c.indexOf(b)>0&&(d=[parseFloat(c),b])}),d}}),a.easing.jswing=a.easing.swing,a.extend(a.easing,{def:"easeOutQuad",swing:function(b,c,d,e,f){return a.easing[a.easing.def](b,c,d,e,f)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b+c:d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b+c:-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b*b+c:d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return b==0?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){return b==0?c:b==e?c+d:(b/=e/2)<1?d/2*Math.pow(2,10*(b-1))+c:d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){return(b/=e/2)<1?-d/2*(Math.sqrt(1-b*b)-1)+c:d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g))+c},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*b)*Math.sin((b*e-f)*2*Math.PI/g)+d+c},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e/2)==2)return c+d;g||(g=e*.3*1.5);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return b<1?-0.5*h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)+c:h*Math.pow(2,-10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)*.5+d+c},easeInBack:function(a,c,d,e,f,g){return g==b&&(g=1.70158),e*(c/=f)*c*((g+1)*c-g)+d},easeOutBack:function(a,c,d,e,f,g){return g==b&&(g=1.70158),e*((c=c/f-1)*c*((g+1)*c+g)+1)+d},easeInOutBack:function(a,c,d,e,f,g){return g==b&&(g=1.70158),(c/=f/2)<1?e/2*c*c*(((g*=1.525)+1)*c-g)+d:e/2*((c-=2)*c*(((g*=1.525)+1)*c+g)+2)+d},easeInBounce:function(b,c,d,e,f){return e-a.easing.easeOutBounce(b,f-c,0,e,f)+d},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*7.5625*b*b+c:b<2/2.75?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:b<2.5/2.75?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(b,c,d,e,f){return c<f/2?a.easing.easeInBounce(b,c*2,0,e,f)*.5+d:a.easing.easeOutBounce(b,c*2-f,0,e,f)*.5+e*.5+d}})}(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.blind.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.blind=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=f=="vertical"?"height":"width",i=f=="vertical"?g.height():g.width();e=="show"&&g.css(h,0);var j={};j[h]=e=="show"?i:0,g.animate(j,b.duration,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.bounce.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.bounce=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"up",g=b.options.distance||20,h=b.options.times||5,i=b.duration||250;/show|hide/.test(e)&&d.push("opacity"),a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",g=b.options.distance||(j=="top"?c.outerHeight({margin:!0})/3:c.outerWidth({margin:!0})/3);e=="show"&&c.css("opacity",0).css(j,k=="pos"?-g:g),e=="hide"&&(g=g/(h*2)),e!="hide"&&h--;if(e=="show"){var l={opacity:1};l[j]=(k=="pos"?"+=":"-=")+g,c.animate(l,i/2,b.options.easing),g=g/2,h--}for(var m=0;m<h;m++){var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing),g=e=="hide"?g*2:g/2}if(e=="hide"){var l={opacity:0};l[j]=(k=="pos"?"-=":"+=")+g,c.animate(l,i/2,b.options.easing,function(){c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}else{var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}c.queue("fx",function(){c.dequeue()}),c.dequeue()})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.clip.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.clip=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","height","width"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=c[0].tagName=="IMG"?g:c,i={size:f=="vertical"?"height":"width",position:f=="vertical"?"top":"left"},j=f=="vertical"?h.height():h.width();e=="show"&&(h.css(i.size,0),h.css(i.position,j/2));var k={};k[i.size]=e=="show"?j:0,k[i.position]=e=="show"?0:j/2,h.animate(k,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()}})})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.drop.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.drop=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","opacity"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0})/2:c.outerWidth({margin:!0})/2);e=="show"&&c.css("opacity",0).css(g,h=="pos"?-i:i);var j={opacity:e=="show"?1:0};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.explode.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.explode=function(b){return this.queue(function(){var c=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3,d=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?a(this).is(":visible")?"hide":"show":b.options.mode;var e=a(this).show().css("visibility","hidden"),f=e.offset();f.top-=parseInt(e.css("marginTop"),10)||0,f.left-=parseInt(e.css("marginLeft"),10)||0;var g=e.outerWidth(!0),h=e.outerHeight(!0);for(var i=0;i<c;i++)for(var j=0;j<d;j++)e.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-j*(g/d),top:-i*(h/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/d,height:h/c,left:f.left+j*(g/d)+(b.options.mode=="show"?(j-Math.floor(d/2))*(g/d):0),top:f.top+i*(h/c)+(b.options.mode=="show"?(i-Math.floor(c/2))*(h/c):0),opacity:b.options.mode=="show"?0:1}).animate({left:f.left+j*(g/d)+(b.options.mode=="show"?0:(j-Math.floor(d/2))*(g/d)),top:f.top+i*(h/c)+(b.options.mode=="show"?0:(i-Math.floor(c/2))*(h/c)),opacity:b.options.mode=="show"?1:0},b.duration||500);setTimeout(function(){b.options.mode=="show"?e.css({visibility:"visible"}):e.css({visibility:"visible"}).hide(),b.callback&&b.callback.apply(e[0]),e.dequeue(),a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.fade.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.fade=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.fold.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.fold=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.size||15,g=!!b.options.horizFirst,h=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(c,d),c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),j=e=="show"!=g,k=j?["width","height"]:["height","width"],l=j?[i.width(),i.height()]:[i.height(),i.width()],m=/([0-9]+)%/.exec(f);m&&(f=parseInt(m[1],10)/100*l[e=="hide"?0:1]),e=="show"&&i.css(g?{height:0,width:f}:{height:f,width:0});var n={},p={};n[k[0]]=e=="show"?l[0]:f,p[k[1]]=e=="show"?l[1]:0,i.animate(n,h,b.options.easing).animate(p,h,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.highlight.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.highlight=function(b){return this.queue(function(){var c=a(this),d=["backgroundImage","backgroundColor","opacity"],e=a.effects.setMode(c,b.options.mode||"show"),f={backgroundColor:c.css("backgroundColor")};e=="hide"&&(f.opacity=0),a.effects.save(c,d),c.show().css({backgroundImage:"none",backgroundColor:b.options.color||"#ffff99"}).animate(f,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),e=="show"&&!a.support.opacity&&this.style.removeAttribute("filter"),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.pulsate.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.pulsate=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"show"),e=(b.options.times||5)*2-1,f=b.duration?b.duration/2:a.fx.speeds._default/2,g=c.is(":visible"),h=0;g||(c.css("opacity",0).show(),h=1),(d=="hide"&&g||d=="show"&&!g)&&e--;for(var i=0;i<e;i++)c.animate({opacity:h},f,b.options.easing),h=(h+1)%2;c.animate({opacity:h},f,b.options.easing,function(){h==0&&c.hide(),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}).dequeue()})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.scale.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.puff=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide"),e=parseInt(b.options.percent,10)||150,f=e/100,g={height:c.height(),width:c.width()};a.extend(b.options,{fade:!0,mode:d,percent:d=="hide"?e:100,from:d=="hide"?g:{height:g.height*f,width:g.width*f}}),c.effect("scale",b.options,b.duration,b.callback),c.dequeue()})},a.effects.scale=function(b){return this.queue(function(){var c=a(this),d=a.extend(!0,{},b.options),e=a.effects.setMode(c,b.options.mode||"effect"),f=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:e=="hide"?0:100),g=b.options.direction||"both",h=b.options.origin;e!="effect"&&(d.origin=h||["middle","center"],d.restore=!0);var i={height:c.height(),width:c.width()};c.from=b.options.from||(e=="show"?{height:0,width:0}:i);var j={y:g!="horizontal"?f/100:1,x:g!="vertical"?f/100:1};c.to={height:i.height*j.y,width:i.width*j.x},b.options.fade&&(e=="show"&&(c.from.opacity=0,c.to.opacity=1),e=="hide"&&(c.from.opacity=1,c.to.opacity=0)),d.from=c.from,d.to=c.to,d.mode=e,c.effect("size",d,b.duration,b.callback),c.dequeue()})},a.effects.size=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","width","height","overflow","opacity"],e=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],g=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],i=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],j=a.effects.setMode(c,b.options.mode||"effect"),k=b.options.restore||!1,l=b.options.scale||"both",m=b.options.origin,n={height:c.height(),width:c.width()};c.from=b.options.from||n,c.to=b.options.to||n;if(m){var p=a.effects.getBaseline(m,n);c.from.top=(n.height-c.from.height)*p.y,c.from.left=(n.width-c.from.width)*p.x,c.to.top=(n.height-c.to.height)*p.y,c.to.left=(n.width-c.to.width)*p.x}var q={from:{y:c.from.height/n.height,x:c.from.width/n.width},to:{y:c.to.height/n.height,x:c.to.width/n.width}};if(l=="box"||l=="both")q.from.y!=q.to.y&&(d=d.concat(h),c.from=a.effects.setTransition(c,h,q.from.y,c.from),c.to=a.effects.setTransition(c,h,q.to.y,c.to)),q.from.x!=q.to.x&&(d=d.concat(i),c.from=a.effects.setTransition(c,i,q.from.x,c.from),c.to=a.effects.setTransition(c,i,q.to.x,c.to));(l=="content"||l=="both")&&q.from.y!=q.to.y&&(d=d.concat(g),c.from=a.effects.setTransition(c,g,q.from.y,c.from),c.to=a.effects.setTransition(c,g,q.to.y,c.to)),a.effects.save(c,k?d:e),c.show(),a.effects.createWrapper(c),c.css("overflow","hidden").css(c.from);if(l=="content"||l=="both")h=h.concat(["marginTop","marginBottom"]).concat(g),i=i.concat(["marginLeft","marginRight"]),f=d.concat(h).concat(i),c.find("*[width]").each(function(){var c=a(this);k&&a.effects.save(c,f);var d={height:c.height(),width:c.width()};c.from={height:d.height*q.from.y,width:d.width*q.from.x},c.to={height:d.height*q.to.y,width:d.width*q.to.x},q.from.y!=q.to.y&&(c.from=a.effects.setTransition(c,h,q.from.y,c.from),c.to=a.effects.setTransition(c,h,q.to.y,c.to)),q.from.x!=q.to.x&&(c.from=a.effects.setTransition(c,i,q.from.x,c.from),c.to=a.effects.setTransition(c,i,q.to.x,c.to)),c.css(c.from),c.animate(c.to,b.duration,b.options.easing,function(){k&&a.effects.restore(c,f)})});c.animate(c.to,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){c.to.opacity===0&&c.css("opacity",c.from.opacity),j=="hide"&&c.hide(),a.effects.restore(c,k?d:e),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.shake.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.shake=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"left",g=b.options.distance||20,h=b.options.times||3,i=b.duration||b.options.duration||140;a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",l={},m={},n={};l[j]=(k=="pos"?"-=":"+=")+g,m[j]=(k=="pos"?"+=":"-=")+g*2,n[j]=(k=="pos"?"-=":"+=")+g*2,c.animate(l,i,b.options.easing);for(var p=1;p<h;p++)c.animate(m,i,b.options.easing).animate(n,i,b.options.easing);c.animate(m,i,b.options.easing).animate(l,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}),c.dequeue()})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.slide.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.slide=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"show"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c).css({overflow:"hidden"});var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0}):c.outerWidth({margin:!0}));e=="show"&&c.css(g,h=="pos"?isNaN(i)?"-"+i:-i:i);var j={};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.effects.transfer.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.effects.transfer=function(b){return this.queue(function(){var c=a(this),d=a(b.options.to),e=d.offset(),f={top:e.top,left:e.left,height:d.innerHeight(),width:d.innerWidth()},g=c.offset(),h=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);;
-
-/* JQuery UJS 2.0.3 */
-(function(a,b){var c=function(){var b=a(document).data("events");return b&&b.click&&a.grep(b.click,function(a){return a.namespace==="rails"}).length};if(c()){a.error("jquery-ujs has already been loaded!")}var d;a.rails=d={linkClickSelector:"a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]",inputChangeSelector:"select[data-remote], input[data-remote], textarea[data-remote]",formSubmitSelector:"form",formInputClickSelector:"form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])",disableSelector:"input[data-disable-with], button[data-disable-with], textarea[data-disable-with]",enableSelector:"input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled",requiredInputSelector:"input[name][required]:not([disabled]),textarea[name][required]:not([disabled])",fileInputSelector:"input:file",linkDisableSelector:"a[data-disable-with]",CSRFProtection:function(b){var c=a('meta[name="csrf-token"]').attr("content");if(c)b.setRequestHeader("X-CSRF-Token",c)},fire:function(b,c,d){var e=a.Event(c);b.trigger(e,d);return e.result!==false},confirm:function(a){return confirm(a)},ajax:function(b){return a.ajax(b)},href:function(a){return a.attr("href")},handleRemote:function(c){var e,f,g,h,i,j,k,l;if(d.fire(c,"ajax:before")){h=c.data("cross-domain");i=h===b?null:h;j=c.data("with-credentials")||null;k=c.data("type")||a.ajaxSettings&&a.ajaxSettings.dataType;if(c.is("form")){e=c.attr("method");f=c.attr("action");g=c.serializeArray();var m=c.data("ujs:submit-button");if(m){g.push(m);c.data("ujs:submit-button",null)}}else if(c.is(d.inputChangeSelector)){e=c.data("method");f=c.data("url");g=c.serialize();if(c.data("params"))g=g+"&"+c.data("params")}else{e=c.data("method");f=d.href(c);g=c.data("params")||null}l={type:e||"GET",data:g,dataType:k,beforeSend:function(a,e){if(e.dataType===b){a.setRequestHeader("accept","*/*;q=0.5, "+e.accepts.script)}return d.fire(c,"ajax:beforeSend",[a,e])},success:function(a,b,d){c.trigger("ajax:success",[a,b,d])},complete:function(a,b){c.trigger("ajax:complete",[a,b])},error:function(a,b,d){c.trigger("ajax:error",[a,b,d])},xhrFields:{withCredentials:j},crossDomain:i};if(f){l.url=f}var n=d.ajax(l);c.trigger("ajax:send",n);return n}else{return false}},handleMethod:function(c){var e=d.href(c),f=c.data("method"),g=c.attr("target"),h=a("meta[name=csrf-token]").attr("content"),i=a("meta[name=csrf-param]").attr("content"),j=a('<form method="post" action="'+e+'"></form>'),k='<input name="_method" value="'+f+'" type="hidden" />';if(i!==b&&h!==b){k+='<input name="'+i+'" value="'+h+'" type="hidden" />'}if(g){j.attr("target",g)}j.hide().append(k).appendTo("body");j.submit()},disableFormElements:function(b){b.find(d.disableSelector).each(function(){var b=a(this),c=b.is("button")?"html":"val";b.data("ujs:enable-with",b[c]());b[c](b.data("disable-with"));b.prop("disabled",true)})},enableFormElements:function(b){b.find(d.enableSelector).each(function(){var b=a(this),c=b.is("button")?"html":"val";if(b.data("ujs:enable-with"))b[c](b.data("ujs:enable-with"));b.prop("disabled",false)})},allowAction:function(a){var b=a.data("confirm"),c=false,e;if(!b){return true}if(d.fire(a,"confirm")){c=d.confirm(b);e=d.fire(a,"confirm:complete",[c])}return c&&e},blankInputs:function(b,c,d){var e=a(),f,g,h=c||"input,textarea";b.find(h).each(function(){f=a(this);g=f.is(":checkbox,:radio")?f.is(":checked"):f.val();if(g==!!d){e=e.add(f)}});return e.length?e:false},nonBlankInputs:function(a,b){return d.blankInputs(a,b,true)},stopEverything:function(b){a(b.target).trigger("ujs:everythingStopped");b.stopImmediatePropagation();return false},callFormSubmitBindings:function(c,d){var e=c.data("events"),f=true;if(e!==b&&e["submit"]!==b){a.each(e["submit"],function(a,b){if(typeof b.handler==="function")return f=b.handler(d)})}return f},disableElement:function(a){a.data("ujs:enable-with",a.html());a.html(a.data("disable-with"));a.bind("click.railsDisable",function(a){return d.stopEverything(a)})},enableElement:function(a){if(a.data("ujs:enable-with")!==b){a.html(a.data("ujs:enable-with"));a.data("ujs:enable-with",false)}a.unbind("click.railsDisable")}};if(d.fire(a(document),"rails:attachBindings")){a.ajaxPrefilter(function(a,b,c){if(!a.crossDomain){d.CSRFProtection(c)}});a(document).delegate(d.linkDisableSelector,"ajax:complete",function(){d.enableElement(a(this))});a(document).delegate(d.linkClickSelector,"click.rails",function(c){var e=a(this),f=e.data("method"),g=e.data("params");if(!d.allowAction(e))return d.stopEverything(c);if(e.is(d.linkDisableSelector))d.disableElement(e);if(e.data("remote")!==b){if((c.metaKey||c.ctrlKey)&&(!f||f==="GET")&&!g){return true}if(d.handleRemote(e)===false){d.enableElement(e)}return false}else if(e.data("method")){d.handleMethod(e);return false}});a(document).delegate(d.inputChangeSelector,"change.rails",function(b){var c=a(this);if(!d.allowAction(c))return d.stopEverything(b);d.handleRemote(c);return false});a(document).delegate(d.formSubmitSelector,"submit.rails",function(c){var e=a(this),f=e.data("remote")!==b,g=d.blankInputs(e,d.requiredInputSelector),h=d.nonBlankInputs(e,d.fileInputSelector);if(!d.allowAction(e))return d.stopEverything(c);if(g&&e.attr("novalidate")==b&&d.fire(e,"ajax:aborted:required",[g])){return d.stopEverything(c)}if(f){if(h){setTimeout(function(){d.disableFormElements(e)},13);return d.fire(e,"ajax:aborted:file",[h])}if(!a.support.submitBubbles&&a().jquery<"1.7"&&d.callFormSubmitBindings(e,c)===false)return d.stopEverything(c);d.handleRemote(e);return false}else{setTimeout(function(){d.disableFormElements(e)},13)}});a(document).delegate(d.formInputClickSelector,"click.rails",function(b){var c=a(this);if(!d.allowAction(c))return d.stopEverything(b);var e=c.attr("name"),f=e?{name:e,value:c.val()}:null;c.closest("form").data("ujs:submit-button",f)});a(document).delegate(d.formSubmitSelector,"ajax:beforeSend.rails",function(b){if(this==b.target)d.disableFormElements(a(this))});a(document).delegate(d.formSubmitSelector,"ajax:complete.rails",function(b){if(this==b.target)d.enableFormElements(a(this))});a(function(){csrf_token=a("meta[name=csrf-token]").attr("content");csrf_param=a("meta[name=csrf-param]").attr("content");a('form input[name="'+csrf_param+'"]').val(csrf_token)})}})(jQuery)
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/jquery-1.8.3-ui-1.9.2-ujs-2.0.3.js
--- /dev/null
+++ b/public/javascripts/jquery-1.8.3-ui-1.9.2-ujs-2.0.3.js
@@ -0,0 +1,11 @@
+/*! jQuery v1.8.3 jquery.com | jquery.org/license */
+(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r<i;r++)v.event.add(t,n,u[n][r])}o.data&&(o.data=v.extend({},o.data))}function Ot(e,t){var n;if(t.nodeType!==1)return;t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),n==="object"?(t.parentNode&&(t.outerHTML=e.outerHTML),v.support.html5Clone&&e.innerHTML&&!v.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):n==="input"&&Et.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):n==="option"?t.selected=e.defaultSelected:n==="input"||n==="textarea"?t.defaultValue=e.defaultValue:n==="script"&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(v.expando)}function Mt(e){return typeof e.getElementsByTagName!="undefined"?e.getElementsByTagName("*"):typeof e.querySelectorAll!="undefined"?e.querySelectorAll("*"):[]}function _t(e){Et.test(e.type)&&(e.defaultChecked=e.checked)}function Qt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Jt.length;while(i--){t=Jt[i]+n;if(t in e)return t}return r}function Gt(e,t){return e=t||e,v.css(e,"display")==="none"||!v.contains(e.ownerDocument,e)}function Yt(e,t){var n,r,i=[],s=0,o=e.length;for(;s<o;s++){n=e[s];if(!n.style)continue;i[s]=v._data(n,"olddisplay"),t?(!i[s]&&n.style.display==="none"&&(n.style.display=""),n.style.display===""&&Gt(n)&&(i[s]=v._data(n,"olddisplay",nn(n.nodeName)))):(r=Dt(n,"display"),!i[s]&&r!=="none"&&v._data(n,"olddisplay",r))}for(s=0;s<o;s++){n=e[s];if(!n.style)continue;if(!t||n.style.display==="none"||n.style.display==="")n.style.display=t?i[s]||"":"none"}return e}function Zt(e,t,n){var r=Rt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function en(e,t,n,r){var i=n===(r?"border":"content")?4:t==="width"?1:0,s=0;for(;i<4;i+=2)n==="margin"&&(s+=v.css(e,n+$t[i],!0)),r?(n==="content"&&(s-=parseFloat(Dt(e,"padding"+$t[i]))||0),n!=="margin"&&(s-=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0)):(s+=parseFloat(Dt(e,"padding"+$t[i]))||0,n!=="padding"&&(s+=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0));return s}function tn(e,t,n){var r=t==="width"?e.offsetWidth:e.offsetHeight,i=!0,s=v.support.boxSizing&&v.css(e,"boxSizing")==="border-box";if(r<=0||r==null){r=Dt(e,t);if(r<0||r==null)r=e.style[t];if(Ut.test(r))return r;i=s&&(v.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+en(e,t,n||(s?"border":"content"),i)+"px"}function nn(e){if(Wt[e])return Wt[e];var t=v("<"+e+">").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write("<!doctype html><html><body>"),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<a;u++)r=o[u],s=/^\+/.test(r),s&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[s?"unshift":"push"](n)}}function kn(e,n,r,i,s,o){s=s||n.dataTypes[0],o=o||{},o[s]=!0;var u,a=e[s],f=0,l=a?a.length:0,c=e===Sn;for(;f<l&&(c||!u);f++)u=a[f](n,r,i),typeof u=="string"&&(!c||o[u]?u=t:(n.dataTypes.unshift(u),u=kn(e,n,r,i,u,o)));return(c||!u)&&!o["*"]&&(u=kn(e,n,r,i,"*",o)),u}function Ln(e,n){var r,i,s=v.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((s[r]?e:i||(i={}))[r]=n[r]);i&&v.extend(!0,e,i)}function An(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes,l=e.responseFields;for(s in l)s in r&&(n[l[s]]=r[s]);while(f[0]==="*")f.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(s in a)if(a[s]&&a[s].test(i)){f.unshift(s);break}if(f[0]in r)o=f[0];else{for(s in r){if(!f[0]||e.converters[s+" "+f[0]]){o=s;break}u||(u=s)}o=o||u}if(o)return o!==f[0]&&f.unshift(o),r[o]}function On(e,t){var n,r,i,s,o=e.dataTypes.slice(),u=o[0],a={},f=0;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(o[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=o[++f];)if(i!=="*"){if(u!=="*"&&u!==i){n=a[u+" "+i]||a["* "+i];if(!n)for(r in a){s=r.split(" ");if(s[1]===i){n=a[u+" "+s[0]]||a["* "+s[0]];if(n){n===!0?n=a[r]:a[r]!==!0&&(i=s[0],o.splice(f--,0,i));break}}}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(l){return{state:"parsererror",error:n?l:"No conversion from "+u+" to "+i}}}u=i}return{state:"success",data:t}}function Fn(){try{return new e.XMLHttpRequest}catch(t){}}function In(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function $n(){return setTimeout(function(){qn=t},0),qn=v.now()}function Jn(e,t){v.each(t,function(t,n){var r=(Vn[t]||[]).concat(Vn["*"]),i=0,s=r.length;for(;i<s;i++)if(r[i].call(e,t,n))return})}function Kn(e,t,n){var r,i=0,s=0,o=Xn.length,u=v.Deferred().always(function(){delete a.elem}),a=function(){var t=qn||$n(),n=Math.max(0,f.startTime+f.duration-t),r=n/f.duration||0,i=1-r,s=0,o=f.tweens.length;for(;s<o;s++)f.tweens[s].run(i);return u.notifyWith(e,[f,i,n]),i<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n<r;n++)f.tweens[n].run(1);return t?u.resolveWith(e,[f,t]):u.rejectWith(e,[f,t]),this}}),l=f.props;Qn(l,f.opts.specialEasing);for(;i<o;i++){r=Xn[i].call(f,e,l,f.opts);if(r)return r}return Jn(f,l),v.isFunction(f.opts.start)&&f.opts.start.call(e,f),v.fx.timer(v.extend(a,{anim:f,queue:f.opts.queue,elem:e})),f.progress(f.opts.progress).done(f.opts.done,f.opts.complete).fail(f.opts.fail).always(f.opts.always)}function Qn(e,t){var n,r,i,s,o;for(n in e){r=v.camelCase(n),i=t[r],s=e[n],v.isArray(s)&&(i=s[1],s=e[n]=s[0]),n!==r&&(e[r]=s,delete e[n]),o=v.cssHooks[r];if(o&&"expand"in o){s=o.expand(s),delete e[r];for(n in s)n in e||(e[n]=s[n],t[n]=i)}else t[r]=i}}function Gn(e,t,n){var r,i,s,o,u,a,f,l,c,h=this,p=e.style,d={},m=[],g=e.nodeType&&Gt(e);n.queue||(l=v._queueHooks(e,"fx"),l.unqueued==null&&(l.unqueued=0,c=l.empty.fire,l.empty.fire=function(){l.unqueued||c()}),l.unqueued++,h.always(function(){h.always(function(){l.unqueued--,v.queue(e,"fx").length||l.empty.fire()})})),e.nodeType===1&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],v.css(e,"display")==="inline"&&v.css(e,"float")==="none"&&(!v.support.inlineBlockNeedsLayout||nn(e.nodeName)==="inline"?p.display="inline-block":p.zoom=1)),n.overflow&&(p.overflow="hidden",v.support.shrinkWrapBlocks||h.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t){s=t[r];if(Un.exec(s)){delete t[r],a=a||s==="toggle";if(s===(g?"hide":"show"))continue;m.push(r)}}o=m.length;if(o){u=v._data(e,"fxshow")||v._data(e,"fxshow",{}),"hidden"in u&&(g=u.hidden),a&&(u.hidden=!g),g?v(e).show():h.done(function(){v(e).hide()}),h.done(function(){var t;v.removeData(e,"fxshow",!0);for(t in d)v.style(e,t,d[t])});for(r=0;r<o;r++)i=m[r],f=h.createTween(i,g?u[i]:0),d[i]=u[i]||v.style(e,i),i in u||(u[i]=f.start,g&&(f.end=f.start,f.start=i==="width"||i==="height"?1:0))}}function Yn(e,t,n,r,i){return new Yn.prototype.init(e,t,n,r,i)}function Zn(e,t){var n,r={height:e},i=0;t=t?1:0;for(;i<4;i+=2-t)n=$t[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function tr(e){return v.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:!1}var n,r,i=e.document,s=e.location,o=e.navigator,u=e.jQuery,a=e.$,f=Array.prototype.push,l=Array.prototype.slice,c=Array.prototype.indexOf,h=Object.prototype.toString,p=Object.prototype.hasOwnProperty,d=String.prototype.trim,v=function(e,t){return new v.fn.init(e,t,n)},m=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,g=/\S/,y=/\s+/,b=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,w=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a<f;a++)if((e=arguments[a])!=null)for(n in e){r=u[n],i=e[n];if(u===i)continue;l&&i&&(v.isPlainObject(i)||(s=v.isArray(i)))?(s?(s=!1,o=r&&v.isArray(r)?r:[]):o=r&&v.isPlainObject(r)?r:{},u[n]=v.extend(l,o,i)):i!==t&&(u[n]=i)}return u},v.extend({noConflict:function(t){return e.$===v&&(e.$=a),t&&e.jQuery===v&&(e.jQuery=u),v},isReady:!1,readyWait:1,holdReady:function(e){e?v.readyWait++:v.ready(!0)},ready:function(e){if(e===!0?--v.readyWait:v.isReady)return;if(!i.body)return setTimeout(v.ready,1);v.isReady=!0;if(e!==!0&&--v.readyWait>0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s<o;)if(n.apply(e[s++],r)===!1)break}else if(u){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;s<o;)if(n.call(e[s],s,e[s++])===!1)break;return e},trim:d&&!d.call("\ufeff\u00a0")?function(e){return e==null?"":d.call(e)}:function(e){return e==null?"":(e+"").replace(b,"")},makeArray:function(e,t){var n,r=t||[];return e!=null&&(n=v.type(e),e.length==null||n==="string"||n==="function"||n==="regexp"||v.isWindow(e)?f.call(r,e):v.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(c)return c.call(t,e,n);r=t.length,n=n?n<0?Math.max(0,r+n):n:0;for(;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,s=0;if(typeof r=="number")for(;s<r;s++)e[i++]=n[s];else while(n[s]!==t)e[i++]=n[s++];return e.length=i,e},grep:function(e,t,n){var r,i=[],s=0,o=e.length;n=!!n;for(;s<o;s++)r=!!t(e[s],s),n!==r&&i.push(e[s]);return i},map:function(e,n,r){var i,s,o=[],u=0,a=e.length,f=e instanceof v||a!==t&&typeof a=="number"&&(a>0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u<a;u++)i=n(e[u],u,r),i!=null&&(o[o.length]=i);else for(s in e)i=n(e[s],s,r),i!=null&&(o[o.length]=i);return o.concat.apply([],o)},guid:1,proxy:function(e,n){var r,i,s;return typeof n=="string"&&(r=e[n],n=e,e=r),v.isFunction(e)?(i=l.call(arguments,2),s=function(){return e.apply(n,i.concat(l.call(arguments)))},s.guid=e.guid=e.guid||v.guid++,s):t},access:function(e,n,r,i,s,o,u){var a,f=r==null,l=0,c=e.length;if(r&&typeof r=="object"){for(l in r)v.access(e,n,l,r[l],1,o,i);s=1}else if(i!==t){a=u===t&&v.isFunction(i),f&&(a?(a=n,n=function(e,t,n){return a.call(v(e),n)}):(n.call(e,i),n=null));if(n)for(;l<c;l++)n(e[l],r,a?i.call(e[l],l,n(e[l],r)):i,u);s=1}return s?e:f?n.call(e):c?n(e[0],r):o},now:function(){return(new Date).getTime()}}),v.ready.promise=function(t){if(!r){r=v.Deferred();if(i.readyState==="complete")setTimeout(v.ready,1);else if(i.addEventListener)i.addEventListener("DOMContentLoaded",A,!1),e.addEventListener("load",v.ready,!1);else{i.attachEvent("onreadystatechange",A),e.attachEvent("onload",v.ready);var n=!1;try{n=e.frameElement==null&&i.documentElement}catch(s){}n&&n.doScroll&&function o(){if(!v.isReady){try{n.doScroll("left")}catch(e){return setTimeout(o,50)}v.ready()}}()}}return r.promise(t)},v.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){O["[object "+t+"]"]=t.toLowerCase()}),n=v(i);var M={};v.Callbacks=function(e){e=typeof e=="string"?M[e]||_(e):v.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){n=e.memory&&t,r=!0,u=s||0,s=0,o=a.length,i=!0;for(;a&&u<o;u++)if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}i=!1,a&&(f?f.length&&l(f.shift()):n?a=[]:c.disable())},c={add:function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this},remove:function(){return a&&v.each(arguments,function(e,t){var n;while((n=v.inArray(t,a,n))>-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t<r;t++)n[t]&&v.isFunction(n[t].promise)?n[t].promise().done(o(t,f,n)).fail(s.reject).progress(o(t,a,u)):--i}return i||s.resolveWith(f,n),s.promise()}}),v.support=function(){var t,n,r,s,o,u,a,f,l,c,h,p=i.createElement("div");p.setAttribute("className","t"),p.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i<s;i++)delete r[t[i]];if(!(n?B:v.isEmptyObject)(r))return}}if(!n){delete u[a].data;if(!B(u[a]))return}o?v.cleanData([e],!0):v.support.deleteExpando||u!=u.window?delete u[a]:u[a]=null},_data:function(e,t,n){return v.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&v.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),v.fn.extend({data:function(e,n){var r,i,s,o,u,a=this[0],f=0,l=null;if(e===t){if(this.length){l=v.data(a);if(a.nodeType===1&&!v._data(a,"parsedAttrs")){s=a.attributes;for(u=s.length;f<u;f++)o=s[f].name,o.indexOf("data-")||(o=v.camelCase(o.substring(5)),H(a,o,l[o]));v._data(a,"parsedAttrs",!0)}}return l}return typeof e=="object"?this.each(function(){v.data(this,e)}):(r=e.split(".",2),r[1]=r[1]?"."+r[1]:"",i=r[1]+"!",v.access(this,function(n){if(n===t)return l=this.triggerHandler("getData"+i,[r[0]]),l===t&&a&&(l=v.data(a,e),l=H(a,e,l)),l===t&&r[1]?this.data(r[0]):l;r[1]=n,this.each(function(){var t=v(this);t.triggerHandler("setData"+i,r),v.data(this,e,n),t.triggerHandler("changeData"+i,r)})},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length<r?v.queue(this[0],e):n===t?this:this.each(function(){var t=v.queue(this,e,n);v._queueHooks(this,e),e==="fx"&&t[0]!=="inprogress"&&v.dequeue(this,e)})},dequeue:function(e){return this.each(function(){v.dequeue(this,e)})},delay:function(e,t){return e=v.fx?v.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,s=v.Deferred(),o=this,u=this.length,a=function(){--i||s.resolveWith(o,[o])};typeof e!="string"&&(n=e,e=t),e=e||"fx";while(u--)r=v._data(o[u],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(a));return a(),s.promise(n)}});var j,F,I,q=/[\t\r\n]/g,R=/\r/g,U=/^(?:button|input)$/i,z=/^(?:button|input|object|select|textarea)$/i,W=/^a(?:rea|)$/i,X=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,V=v.support.getSetAttribute;v.fn.extend({attr:function(e,t){return v.access(this,v.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<r;n++){i=this[n];if(i.nodeType===1)if(!i.className&&t.length===1)i.className=e;else{s=" "+i.className+" ";for(o=0,u=t.length;o<u;o++)s.indexOf(" "+t[o]+" ")<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u<a;u++){i=this[u];if(i.nodeType===1&&i.className){r=(" "+i.className+" ").replace(q," ");for(s=0,o=n.length;s<o;s++)while(r.indexOf(" "+n[s]+" ")>=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n<r;n++)if(this[n].nodeType===1&&(" "+this[n].className+" ").replace(q," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a<u;a++){n=r[a];if((n.selected||a===i)&&(v.support.optDisabled?!n.disabled:n.getAttribute("disabled")===null)&&(!n.parentNode.disabled||!v.nodeName(n.parentNode,"optgroup"))){t=v(n).val();if(s)return t;o.push(t)}}return o},set:function(e,t){var n=v.makeArray(t);return v(e).find("option").each(function(){this.selected=v.inArray(v(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o<r.length;o++)i=r[o],i&&(n=v.propFix[i]||i,s=X.test(i),s||v.attr(e,i,""),e.removeAttribute(V?i:n),s&&n in e&&(e[n]=!1))}},attrHooks:{type:{set:function(e,t){if(U.test(e.nodeName)&&e.parentNode)v.error("type property can't be changed");else if(!v.support.radioValue&&t==="radio"&&v.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return j&&v.nodeName(e,"button")?j.get(e,t):t in e?e.value:null},set:function(e,t,n){if(j&&v.nodeName(e,"button"))return j.set(e,t,n);e.value=t}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2)return;return o=u!==1||!v.isXMLDoc(e),o&&(n=v.propFix[n]||n,s=v.propHooks[n]),r!==t?s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r:s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):z.test(e.nodeName)||W.test(e.nodeName)&&e.href?0:t}}}}),F={get:function(e,n){var r,i=v.prop(e,n);return i===!0||typeof i!="boolean"&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?v.removeAttr(e,n):(r=v.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},V||(I={name:!0,id:!0,coords:!0},j=v.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(I[n]?r.value!=="":r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=i.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},v.each(["width","height"],function(e,t){v.attrHooks[t]=v.extend(v.attrHooks[t],{set:function(e,n){if(n==="")return e.setAttribute(t,"auto"),n}})}),v.attrHooks.contenteditable={get:j.get,set:function(e,t,n){t===""&&(t="false"),j.set(e,t,n)}}),v.support.hrefNormalized||v.each(["href","src","width","height"],function(e,n){v.attrHooks[n]=v.extend(v.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return r===null?t:r}})}),v.support.style||(v.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=t+""}}),v.support.optSelected||(v.propHooks.selected=v.extend(v.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),v.support.enctype||(v.propFix.enctype="encoding"),v.support.checkOn||v.each(["radio","checkbox"],function(){v.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),v.each(["radio","checkbox"],function(){v.valHooks[this]=v.extend(v.valHooks[this],{set:function(e,t){if(v.isArray(t))return e.checked=v.inArray(v(e).val(),t)>=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f<n.length;f++){l=J.exec(n[f])||[],c=l[1],h=(l[2]||"").split(".").sort(),g=v.event.special[c]||{},c=(s?g.delegateType:g.bindType)||c,g=v.event.special[c]||{},p=v.extend({type:c,origType:l[1],data:i,handler:r,guid:r.guid,selector:s,needsContext:s&&v.expr.match.needsContext.test(s),namespace:h.join(".")},d),m=a[c];if(!m){m=a[c]=[],m.delegateCount=0;if(!g.setup||g.setup.call(e,i,h,u)===!1)e.addEventListener?e.addEventListener(c,u,!1):e.attachEvent&&e.attachEvent("on"+c,u)}g.add&&(g.add.call(e,p),p.handler.guid||(p.handler.guid=r.guid)),s?m.splice(m.delegateCount++,0,p):m.push(p),v.event.global[c]=!0}e=null},global:{},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,m,g=v.hasData(e)&&v._data(e);if(!g||!(h=g.events))return;t=v.trim(Z(t||"")).split(" ");for(s=0;s<t.length;s++){o=J.exec(t[s])||[],u=a=o[1],f=o[2];if(!u){for(u in h)v.event.remove(e,u+t[s],n,r,!0);continue}p=v.event.special[u]||{},u=(r?p.delegateType:p.bindType)||u,d=h[u]||[],l=d.length,f=f?new RegExp("(^|\\.)"+f.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(c=0;c<d.length;c++)m=d[c],(i||a===m.origType)&&(!n||n.guid===m.guid)&&(!f||f.test(m.namespace))&&(!r||r===m.selector||r==="**"&&m.selector)&&(d.splice(c--,1),m.selector&&d.delegateCount--,p.remove&&p.remove.call(e,m));d.length===0&&l!==d.length&&((!p.teardown||p.teardown.call(e,f,g.handle)===!1)&&v.removeEvent(e,u,g.handle),delete h[u])}v.isEmptyObject(h)&&(delete g.handle,v.removeData(e,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,s,o){if(!s||s.nodeType!==3&&s.nodeType!==8){var u,a,f,l,c,h,p,d,m,g,y=n.type||n,b=[];if(Y.test(y+v.event.triggered))return;y.indexOf("!")>=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f<m.length&&!n.isPropagationStopped();f++)l=m[f][0],n.type=m[f][1],d=(v._data(l,"events")||{})[n.type]&&v._data(l,"handle"),d&&d.apply(l,r),d=h&&l[h],d&&v.acceptData(l)&&d.apply&&d.apply(l,r)===!1&&n.preventDefault();return n.type=y,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(s.ownerDocument,r)===!1)&&(y!=="click"||!v.nodeName(s,"a"))&&v.acceptData(s)&&h&&s[y]&&(y!=="focus"&&y!=="blur"||n.target.offsetWidth!==0)&&!v.isWindow(s)&&(c=s[h],c&&(s[h]=null),v.event.triggered=y,s[y](),v.event.triggered=t,c&&(s[h]=c)),n.result}return},dispatch:function(n){n=v.event.fix(n||e.event);var r,i,s,o,u,a,f,c,h,p,d=(v._data(this,"events")||{})[n.type]||[],m=d.delegateCount,g=l.call(arguments),y=!n.exclusive&&!n.namespace,b=v.event.special[n.type]||{},w=[];g[0]=n,n.delegateTarget=this;if(b.preDispatch&&b.preDispatch.call(this,n)===!1)return;if(m&&(!n.button||n.type!=="click"))for(s=n.target;s!=this;s=s.parentNode||this)if(s.disabled!==!0||n.type!=="click"){u={},f=[];for(r=0;r<m;r++)c=d[r],h=c.selector,u[h]===t&&(u[h]=c.needsContext?v(h,this).index(s)>=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r<w.length&&!n.isPropagationStopped();r++){a=w[r],n.currentTarget=a.elem;for(i=0;i<a.matches.length&&!n.isImmediatePropagationStopped();i++){c=a.matches[i];if(y||!n.namespace&&!c.namespace||n.namespace_re&&n.namespace_re.test(c.namespace))n.data=c.data,n.handleObj=c,o=((v.event.special[c.origType]||{}).handle||c.handler).apply(a.elem,g),o!==t&&(n.result=o,o===!1&&(n.preventDefault(),n.stopPropagation()))}}return b.postDispatch&&b.postDispatch.call(this,n),n.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return e.which==null&&(e.which=t.charCode!=null?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,s,o,u=n.button,a=n.fromElement;return e.pageX==null&&n.clientX!=null&&(r=e.target.ownerDocument||i,s=r.documentElement,o=r.body,e.pageX=n.clientX+(s&&s.scrollLeft||o&&o.scrollLeft||0)-(s&&s.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(s&&s.scrollTop||o&&o.scrollTop||0)-(s&&s.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?n.toElement:a),!e.which&&u!==t&&(e.which=u&1?1:u&2?3:u&4?2:0),e}},fix:function(e){if(e[v.expando])return e;var t,n,r=e,s=v.event.fixHooks[e.type]||{},o=s.props?this.props.concat(s.props):this.props;e=v.Event(r);for(t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||i),e.target.nodeType===3&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,r):e},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){v.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=v.extend(new v.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?v.event.trigger(i,null,t):v.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},v.event.handle=v.event.dispatch,v.removeEvent=i.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]=="undefined"&&(e[r]=null),e.detachEvent(r,n))},v.Event=function(e,t){if(!(this instanceof v.Event))return new v.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?tt:et):this.type=e,t&&v.extend(this,t),this.timeStamp=e&&e.timeStamp||v.now(),this[v.expando]=!0},v.Event.prototype={preventDefault:function(){this.isDefaultPrevented=tt;var e=this.originalEvent;if(!e)return;e.preventDefault?e.preventDefault():e.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=tt;var e=this.originalEvent;if(!e)return;e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=tt,this.stopPropagation()},isDefaultPrevented:et,isPropagationStopped:et,isImmediatePropagationStopped:et},v.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){v.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,s=e.handleObj,o=s.selector;if(!i||i!==r&&!v.contains(r,i))e.type=s.origType,n=s.handler.apply(this,arguments),e.type=t;return n}}}),v.support.submitBubbles||(v.event.special.submit={setup:function(){if(v.nodeName(this,"form"))return!1;v.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=v.nodeName(n,"input")||v.nodeName(n,"button")?n.form:t;r&&!v._data(r,"_submit_attached")&&(v.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),v._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&v.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){if(v.nodeName(this,"form"))return!1;v.event.remove(this,"._submit")}}),v.support.changeBubbles||(v.event.special.change={setup:function(){if($.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")v.event.add(this,"propertychange._change",function(e){e.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),v.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),v.event.simulate("change",this,e,!0)});return!1}v.event.add(this,"beforeactivate._change",function(e){var t=e.target;$.test(t.nodeName)&&!v._data(t,"_change_attached")&&(v.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&v.event.simulate("change",this.parentNode,e,!0)}),v._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||t.type!=="radio"&&t.type!=="checkbox")return e.handleObj.handler.apply(this,arguments)},teardown:function(){return v.event.remove(this,"._change"),!$.test(this.nodeName)}}),v.support.focusinBubbles||v.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){v.event.simulate(t,e.target,v.event.fix(e),!0)};v.event.special[t]={setup:function(){n++===0&&i.addEventListener(e,r,!0)},teardown:function(){--n===0&&i.removeEventListener(e,r,!0)}}}),v.fn.extend({on:function(e,n,r,i,s){var o,u;if(typeof e=="object"){typeof n!="string"&&(r=r||n,n=t);for(u in e)this.on(u,n,r,e[u],s);return this}r==null&&i==null?(i=n,r=n=t):i==null&&(typeof n=="string"?(i=r,r=t):(i=r,r=n,n=t));if(i===!1)i=et;else if(!i)return this;return s===1&&(o=i,i=function(e){return v().off(e),o.apply(this,arguments)},i.guid=o.guid||(o.guid=v.guid++)),this.each(function(){v.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,s;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,v(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if(typeof e=="object"){for(s in e)this.off(s,n,e[s]);return this}if(n===!1||typeof n=="function")r=n,n=t;return r===!1&&(r=et),this.each(function(){v.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return v(this.context).on(e,this.selector,t,n),this},die:function(e,t){return v(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){v.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return v.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||v.guid++,r=0,i=function(n){var i=(v._data(this,"lastToggle"+e.guid)||0)%r;return v._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};i.guid=n;while(r<t.length)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),v.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){v.fn[t]=function(e,n){return n==null&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u<a;u++)if(s=e[u])if(!n||n(s,r,i))o.push(s),f&&t.push(u);return o}function ct(e,t,n,r,i,s){return r&&!r[d]&&(r=ct(r)),i&&!i[d]&&(i=ct(i,s)),N(function(s,o,u,a){var f,l,c,h=[],p=[],d=o.length,v=s||dt(t||"*",u.nodeType?[u]:u,[]),m=e&&(s||!t)?lt(v,h,e,u,a):v,g=n?i||(s?e:d||r)?[]:o:m;n&&n(m,g,u,a);if(r){f=lt(g,p),r(f,[],u,a),l=f.length;while(l--)if(c=f[l])g[p[l]]=!(m[p[l]]=c)}if(s){if(i||e){if(i){f=[],l=g.length;while(l--)(c=g[l])&&f.push(m[l]=c);i(null,g=[],f,a)}l=g.length;while(l--)(c=g[l])&&(f=i?T.call(s,c):h[l])>-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a<s;a++)if(n=i.relative[e[a].type])h=[at(ft(h),n)];else{n=i.filter[e[a].type].apply(null,e[a].matches);if(n[d]){r=++a;for(;r<s;r++)if(i.relative[e[r].type])break;return ct(a>1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a<r&&ht(e.slice(a,r)),r<s&&ht(e=e.slice(r)),r<s&&e.join(""))}h.push(n)}return ft(h)}function pt(e,t){var r=t.length>0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r<i;r++)nt(e,t[r],n);return n}function vt(e,t,n,r,s){var o,u,f,l,c,h=ut(e),p=h.length;if(!r&&h.length===1){u=h[0]=h[0].slice(0);if(u.length>2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;t<n;t++)if(this[t]===e)return t;return-1},N=function(e,t){return e[d]=t==null||t,e},C=function(){var e={},t=[];return N(function(n,r){return t.push(n)>i.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="<a name='"+d+"'></a><div name='"+d+"'></div>",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:st(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:st(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},f=y.compareDocumentPosition?function(e,t){return e===t?(l=!0,0):(!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition:e.compareDocumentPosition(t)&4)?-1:1}:function(e,t){if(e===t)return l=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return ot(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var f=0;f<n&&f<r;f++)if(i[f]!==s[f])return ot(i[f],s[f]);return f===n?ot(e,s[f],-1):ot(i[f],t,1)},[0,0].sort(f),h=!l,nt.uniqueSort=function(e){var t,n=[],r=1,i=0;l=h,e.sort(f);if(l){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e},nt.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a=nt.compile=function(e,t){var n,r=[],i=[],s=A[d][e+" "];if(!s){t||(t=ut(e)),n=t.length;while(n--)s=ht(t[n]),s[d]?r.push(s):i.push(s);s=A(e,pt(i,r))}return s},g.querySelectorAll&&function(){var e,t=vt,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[":focus"],s=[":active"],u=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector||y.oMatchesSelector||y.msMatchesSelector;K(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'/>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t<n;t++)if(v.contains(u[t],this))return!0});o=this.pushStack("","find",e);for(t=0,n=this.length;t<n;t++){r=o.length,v.find(e,this[t],o);if(t>0)for(i=r;i<o.length;i++)for(s=0;s<r;s++)if(o[s]===o[i]){o.splice(i--,1);break}}return o},has:function(e){var t,n=v(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(v.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1),"not",e)},filter:function(e){return this.pushStack(ft(this,e,!0),"filter",e)},is:function(e){return!!e&&(typeof e=="string"?st.test(e)?v(e,this.context).index(this[0])>=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r<i;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&n.nodeType!==11){if(o?o.index(n)>-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<tbody/i,gt=/<|&#?\w+;/,yt=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,wt=new RegExp("<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Nt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X<div>","</div>"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(s){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return ut(this[0])?this.length?this.pushStack(v(v.isFunction(e)?e():e),"replaceWith",e):this:v.isFunction(e)?this.each(function(t){var n=v(this),r=n.html();n.replaceWith(e.call(this,t,r))}):(typeof e!="string"&&(e=v(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;v(this).remove(),t?v(t).before(e):v(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,s,o,u,a=0,f=e[0],l=[],c=this.length;if(!v.support.checkClone&&c>1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a<c;a++)r.call(n&&v.nodeName(this[a],"table")?Lt(this[a],"tbody"):this[a],a===u?o:v.clone(o,!0,!0))}o=s=null,l.length&&v.each(l,function(e,t){t.src?v.ajax?v.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):v.error("no ajax"):v.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Tt,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),v.buildFragment=function(e,n,r){var s,o,u,a=e[0];return n=n||i,n=!n.nodeType&&n[0]||n,n=n.ownerDocument||n,e.length===1&&typeof a=="string"&&a.length<512&&n===i&&a.charAt(0)==="<"&&!bt.test(a)&&(v.support.checkClone||!St.test(a))&&(v.support.html5Clone||!wt.test(a))&&(o=!0,s=v.fragments[a],u=s!==t),s||(s=n.createDocumentFragment(),v.clean(e,n,s,r),o&&(v.fragments[a]=u&&s)),{fragment:s,cacheable:o}},v.fragments={},v.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){v.fn[e]=function(n){var r,i=0,s=[],o=v(n),u=o.length,a=this.length===1&&this[0].parentNode;if((a==null||a&&a.nodeType===11&&a.childNodes.length===1)&&u===1)return o[t](this[0]),this;for(;i<u;i++)r=(i>0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1></$2>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]==="<table>"&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("<div>").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r<i;r++)n=e[r],Vn[n]=Vn[n]||[],Vn[n].unshift(t)},prefilter:function(e,t){t?Xn.unshift(e):Xn.push(e)}}),v.Tween=Yn,Yn.prototype={constructor:Yn,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(v.cssNumber[n]?"":"px")},cur:function(){var e=Yn.propHooks[this.prop];return e&&e.get?e.get(this):Yn.propHooks._default.get(this)},run:function(e){var t,n=Yn.propHooks[this.prop];return this.options.duration?this.pos=t=v.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Yn.propHooks._default.set(this),this}},Yn.prototype.init.prototype=Yn.prototype,Yn.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=v.css(e.elem,e.prop,!1,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){v.fx.step[e.prop]?v.fx.step[e.prop](e):e.elem.style&&(e.elem.style[v.cssProps[e.prop]]!=null||v.cssHooks[e.prop])?v.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Yn.propHooks.scrollTop=Yn.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},v.each(["toggle","show","hide"],function(e,t){var n=v.fn[t];v.fn[t]=function(r,i,s){return r==null||typeof r=="boolean"||!e&&v.isFunction(r)&&v.isFunction(i)?n.apply(this,arguments):this.animate(Zn(t,!0),r,i,s)}}),v.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Gt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=v.isEmptyObject(e),s=v.speed(t,n,r),o=function(){var t=Kn(this,v.extend({},e),s);i&&t.stop(!0)};return i||s.queue===!1?this.each(o):this.queue(s.queue,o)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return typeof e!="string"&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=e!=null&&e+"queueHooks",s=v.timers,o=v._data(this);if(n)o[n]&&o[n].stop&&i(o[n]);else for(n in o)o[n]&&o[n].stop&&Wn.test(n)&&i(o[n]);for(n=s.length;n--;)s[n].elem===this&&(e==null||s[n].queue===e)&&(s[n].anim.stop(r),t=!1,s.splice(n,1));(t||!r)&&v.dequeue(this,e)})}}),v.each({slideDown:Zn("show"),slideUp:Zn("hide"),slideToggle:Zn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){v.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),v.speed=function(e,t,n){var r=e&&typeof e=="object"?v.extend({},e):{complete:n||!n&&t||v.isFunction(e)&&e,duration:e,easing:n&&t||t&&!v.isFunction(t)&&t};r.duration=v.fx.off?0:typeof r.duration=="number"?r.duration:r.duration in v.fx.speeds?v.fx.speeds[r.duration]:v.fx.speeds._default;if(r.queue==null||r.queue===!0)r.queue="fx";return r.old=r.complete,r.complete=function(){v.isFunction(r.old)&&r.old.call(this),r.queue&&v.dequeue(this,r.queue)},r},v.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},v.timers=[],v.fx=Yn.prototype.init,v.fx.tick=function(){var e,n=v.timers,r=0;qn=v.now();for(;r<n.length;r++)e=n[r],!e()&&n[r]===e&&n.splice(r--,1);n.length||v.fx.stop(),qn=t},v.fx.timer=function(e){e()&&v.timers.push(e)&&!Rn&&(Rn=setInterval(v.fx.tick,v.fx.interval))},v.fx.interval=13,v.fx.stop=function(){clearInterval(Rn),Rn=null},v.fx.speeds={slow:600,fast:200,_default:400},v.fx.step={},v.expr&&v.expr.filters&&(v.expr.filters.animated=function(e){return v.grep(v.timers,function(t){return e===t.elem}).length});var er=/^(?:body|html)$/i;v.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){v.offset.setOffset(this,e,t)});var n,r,i,s,o,u,a,f={top:0,left:0},l=this[0],c=l&&l.ownerDocument;if(!c)return;return(r=c.body)===l?v.offset.bodyOffset(l):(n=c.documentElement,v.contains(n,l)?(typeof l.getBoundingClientRect!="undefined"&&(f=l.getBoundingClientRect()),i=tr(c),s=n.clientTop||r.clientTop||0,o=n.clientLeft||r.clientLeft||0,u=i.pageYOffset||n.scrollTop,a=i.pageXOffset||n.scrollLeft,{top:f.top+u-s,left:f.left+a-o}):f)},v.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return v.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(v.css(e,"marginTop"))||0,n+=parseFloat(v.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=v.css(e,"position");r==="static"&&(e.style.position="relative");var i=v(e),s=i.offset(),o=v.css(e,"top"),u=v.css(e,"left"),a=(r==="absolute"||r==="fixed")&&v.inArray("auto",[o,u])>-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window);
+
+/*! jQuery UI - v1.9.2 - 2012-12-26
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
+* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
+(function(e,t){function i(t,n){var r,i,o,u=t.nodeName.toLowerCase();return"area"===u?(r=t.parentNode,i=r.name,!t.href||!i||r.nodeName.toLowerCase()!=="map"?!1:(o=e("img[usemap=#"+i+"]")[0],!!o&&s(o))):(/input|select|textarea|button|object/.test(u)?!t.disabled:"a"===u?t.href||n:n)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().andSelf().filter(function(){return e.css(this,"visibility")==="hidden"}).length}var n=0,r=/^ui-id-\d+$/;e.ui=e.ui||{};if(e.ui.version)return;e.extend(e.ui,{version:"1.9.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({_focus:e.fn.focus,focus:function(t,n){return typeof t=="number"?this.each(function(){var r=this;setTimeout(function(){e(r).focus(),n&&n.call(r)},t)}):this._focus.apply(this,arguments)},scrollParent:function(){var t;return e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?t=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):t=this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(n){if(n!==t)return this.css("zIndex",n);if(this.length){var r=e(this[0]),i,s;while(r.length&&r[0]!==document){i=r.css("position");if(i==="absolute"||i==="relative"||i==="fixed"){s=parseInt(r.css("zIndex"),10);if(!isNaN(s)&&s!==0)return s}r=r.parent()}}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){r.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),r=isNaN(n);return(r||n>=0)&&i(t,!r)}}),e(function(){var t=document.body,n=t.appendChild(n=document.createElement("div"));n.offsetHeight,e.extend(n.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),e.support.minHeight=n.offsetHeight===100,e.support.selectstart="onselectstart"in n,t.removeChild(n).style.display="none"}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(n,r){function u(t,n,r,s){return e.each(i,function(){n-=parseFloat(e.css(t,"padding"+this))||0,r&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var i=r==="Width"?["Left","Right"]:["Top","Bottom"],s=r.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+r]=function(n){return n===t?o["inner"+r].call(this):this.each(function(){e(this).css(s,u(this,n)+"px")})},e.fn["outer"+r]=function(t,n){return typeof t!="number"?o["outer"+r].call(this,t):this.each(function(){e(this).css(s,u(this,t,!0,n)+"px")})}}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),function(){var t=/msie ([\w.]+)/.exec(navigator.userAgent.toLowerCase())||[];e.ui.ie=t.length?!0:!1,e.ui.ie6=parseFloat(t[1],10)===6}(),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r)s.plugins[i]=s.plugins[i]||[],s.plugins[i].push([n,r[i]])},call:function(e,t,n){var r,i=e.plugins[t];if(!i||!e.element[0].parentNode||e.element[0].parentNode.nodeType===11)return;for(r=0;r<i.length;r++)e.options[i[r][0]]&&i[r][1].apply(e.element,n)}},contains:e.contains,hasScroll:function(t,n){if(e(t).css("overflow")==="hidden")return!1;var r=n&&n==="left"?"scrollLeft":"scrollTop",i=!1;return t[r]>0?!0:(t[r]=1,i=t[r]>0,t[r]=0,i)},isOverAxis:function(e,t,n){return e>t&&e<t+n},isOver:function(t,n,r,i,s,o){return e.ui.isOverAxis(t,r,s)&&e.ui.isOverAxis(n,i,o)}})})(jQuery);(function(e,t){var n=0,r=Array.prototype.slice,i=e.cleanData;e.cleanData=function(t){for(var n=0,r;(r=t[n])!=null;n++)try{e(r).triggerHandler("remove")}catch(s){}i(t)},e.widget=function(t,n,r){var i,s,o,u,a=t.split(".")[0];t=t.split(".")[1],i=a+"-"+t,r||(r=n,n=e.Widget),e.expr[":"][i.toLowerCase()]=function(t){return!!e.data(t,i)},e[a]=e[a]||{},s=e[a][t],o=e[a][t]=function(e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)},e.extend(o,s,{version:r.version,_proto:e.extend({},r),_childConstructors:[]}),u=new n,u.options=e.widget.extend({},u.options),e.each(r,function(t,i){e.isFunction(i)&&(r[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},r=function(e){return n.prototype[t].apply(this,e)};return function(){var t=this._super,n=this._superApply,s;return this._super=e,this._superApply=r,s=i.apply(this,arguments),this._super=t,this._superApply=n,s}}())}),o.prototype=e.widget.extend(u,{widgetEventPrefix:s?u.widgetEventPrefix:t},r,{constructor:o,namespace:a,widgetName:t,widgetBaseClass:i,widgetFullName:i}),s?(e.each(s._childConstructors,function(t,n){var r=n.prototype;e.widget(r.namespace+"."+r.widgetName,o,n._proto)}),delete s._childConstructors):n._childConstructors.push(o),e.widget.bridge(t,o)},e.widget.extend=function(n){var i=r.call(arguments,1),s=0,o=i.length,u,a;for(;s<o;s++)for(u in i[s])a=i[s][u],i[s].hasOwnProperty(u)&&a!==t&&(e.isPlainObject(a)?n[u]=e.isPlainObject(n[u])?e.widget.extend({},n[u],a):e.widget.extend({},a):n[u]=a);return n},e.widget.bridge=function(n,i){var s=i.prototype.widgetFullName||n;e.fn[n]=function(o){var u=typeof o=="string",a=r.call(arguments,1),f=this;return o=!u&&a.length?e.widget.extend.apply(null,[o].concat(a)):o,u?this.each(function(){var r,i=e.data(this,s);if(!i)return e.error("cannot call methods on "+n+" prior to initialization; "+"attempted to call method '"+o+"'");if(!e.isFunction(i[o])||o.charAt(0)==="_")return e.error("no such method '"+o+"' for "+n+" widget instance");r=i[o].apply(i,a);if(r!==i&&r!==t)return f=r&&r.jquery?f.pushStack(r.get()):r,!1}):this.each(function(){var t=e.data(this,s);t?t.option(o||{})._init():e.data(this,s,new i(o,this))}),f}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetName,this),e.data(r,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===r&&this.destroy()}}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u<s.length-1;u++)o[s[u]]=o[s[u]]||{},o=o[s[u]];n=s.pop();if(r===t)return o[n]===t?null:o[n];o[n]=r}else{if(r===t)return this.options[n]===t?null:this.options[n];i[n]=r}}return this._setOptions(i),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,e==="disabled"&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(t,n,r){var i,s=this;typeof t!="boolean"&&(r=n,n=t,t=!1),r?(n=i=e(n),this.bindings=this.bindings.add(n)):(r=n,n=this.element,i=this.widget()),e.each(r,function(r,o){function u(){if(!t&&(s.options.disabled===!0||e(this).hasClass("ui-state-disabled")))return;return(typeof o=="string"?s[o]:o).apply(s,arguments)}typeof o!="string"&&(u.guid=o.guid=o.guid||u.guid||e.guid++);var a=r.match(/^(\w+)\s*(.*)$/),f=a[1]+s.eventNamespace,l=a[2];l?i.delegate(l,f,u):n.bind(f,u)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function n(){return(typeof e=="string"?r[e]:e).apply(r,arguments)}var r=this;return setTimeout(n,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,n,r){var i,s,o=this.options[t];r=r||{},n=e.Event(n),n.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),n.target=this.element[0],s=n.originalEvent;if(s)for(i in s)i in n||(n[i]=s[i]);return this.element.trigger(n,r),!(e.isFunction(o)&&o.apply(this.element[0],[n].concat(r))===!1||n.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,n){e.Widget.prototype["_"+t]=function(r,i,s){typeof i=="string"&&(i={effect:i});var o,u=i?i===!0||typeof i=="number"?n:i.effect||n:t;i=i||{},typeof i=="number"&&(i={duration:i}),o=!e.isEmptyObject(i),i.complete=s,i.delay&&r.delay(i.delay),o&&e.effects&&(e.effects.effect[u]||e.uiBackCompat!==!1&&e.effects[u])?r[t](i):u!==t&&r[u]?r[u](i.duration,i.easing,s):r.queue(function(n){e(this)[t](),s&&s.call(r[0]),n()})}}),e.uiBackCompat!==!1&&(e.Widget.prototype._getCreateOptions=function(){return e.metadata&&e.metadata.get(this.element[0])[this.widgetName]})})(jQuery);(function(e,t){var n=!1;e(document).mouseup(function(e){n=!1}),e.widget("ui.mouse",{version:"1.9.2",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(n){if(!0===e.data(n.target,t.widgetName+".preventClickEvent"))return e.removeData(n.target,t.widgetName+".preventClickEvent"),n.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(n)return;this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var r=this,i=t.which===1,s=typeof this.options.cancel=="string"&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;if(!i||s||!this._mouseCapture(t))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){r.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)){this._mouseStarted=this._mouseStart(t)!==!1;if(!this._mouseStarted)return t.preventDefault(),!0}return!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return r._mouseMove(e)},this._mouseUpDelegate=function(e){return r._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),n=!0,!0},_mouseMove:function(t){return!e.ui.ie||document.documentMode>=9||!!t.button?this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted):this._mouseUp(t)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(e){return this.mouseDelayMet},_mouseStart:function(e){},_mouseDrag:function(e){},_mouseStop:function(e){},_mouseCapture:function(e){return!0}})})(jQuery);(function(e,t){function h(e,t,n){return[parseInt(e[0],10)*(l.test(e[0])?t/100:1),parseInt(e[1],10)*(l.test(e[1])?n/100:1)]}function p(t,n){return parseInt(e.css(t,n),10)||0}e.ui=e.ui||{};var n,r=Math.max,i=Math.abs,s=Math.round,o=/left|center|right/,u=/top|center|bottom/,a=/[\+\-]\d+%?/,f=/^\w+/,l=/%$/,c=e.fn.position;e.position={scrollbarWidth:function(){if(n!==t)return n;var r,i,s=e("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return e("body").append(s),r=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,r===i&&(i=s[0].clientWidth),s.remove(),n=r-i},getScrollInfo:function(t){var n=t.isWindow?"":t.element.css("overflow-x"),r=t.isWindow?"":t.element.css("overflow-y"),i=n==="scroll"||n==="auto"&&t.width<t.element[0].scrollWidth,s=r==="scroll"||r==="auto"&&t.height<t.element[0].scrollHeight;return{width:i?e.position.scrollbarWidth():0,height:s?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var n=e(t||window),r=e.isWindow(n[0]);return{element:n,isWindow:r,offset:n.offset()||{left:0,top:0},scrollLeft:n.scrollLeft(),scrollTop:n.scrollTop(),width:r?n.width():n.outerWidth(),height:r?n.height():n.outerHeight()}}},e.fn.position=function(t){if(!t||!t.of)return c.apply(this,arguments);t=e.extend({},t);var n,l,d,v,m,g=e(t.of),y=e.position.getWithinInfo(t.within),b=e.position.getScrollInfo(y),w=g[0],E=(t.collision||"flip").split(" "),S={};return w.nodeType===9?(l=g.width(),d=g.height(),v={top:0,left:0}):e.isWindow(w)?(l=g.width(),d=g.height(),v={top:g.scrollTop(),left:g.scrollLeft()}):w.preventDefault?(t.at="left top",l=d=0,v={top:w.pageY,left:w.pageX}):(l=g.outerWidth(),d=g.outerHeight(),v=g.offset()),m=e.extend({},v),e.each(["my","at"],function(){var e=(t[this]||"").split(" "),n,r;e.length===1&&(e=o.test(e[0])?e.concat(["center"]):u.test(e[0])?["center"].concat(e):["center","center"]),e[0]=o.test(e[0])?e[0]:"center",e[1]=u.test(e[1])?e[1]:"center",n=a.exec(e[0]),r=a.exec(e[1]),S[this]=[n?n[0]:0,r?r[0]:0],t[this]=[f.exec(e[0])[0],f.exec(e[1])[0]]}),E.length===1&&(E[1]=E[0]),t.at[0]==="right"?m.left+=l:t.at[0]==="center"&&(m.left+=l/2),t.at[1]==="bottom"?m.top+=d:t.at[1]==="center"&&(m.top+=d/2),n=h(S.at,l,d),m.left+=n[0],m.top+=n[1],this.each(function(){var o,u,a=e(this),f=a.outerWidth(),c=a.outerHeight(),w=p(this,"marginLeft"),x=p(this,"marginTop"),T=f+w+p(this,"marginRight")+b.width,N=c+x+p(this,"marginBottom")+b.height,C=e.extend({},m),k=h(S.my,a.outerWidth(),a.outerHeight());t.my[0]==="right"?C.left-=f:t.my[0]==="center"&&(C.left-=f/2),t.my[1]==="bottom"?C.top-=c:t.my[1]==="center"&&(C.top-=c/2),C.left+=k[0],C.top+=k[1],e.support.offsetFractions||(C.left=s(C.left),C.top=s(C.top)),o={marginLeft:w,marginTop:x},e.each(["left","top"],function(r,i){e.ui.position[E[r]]&&e.ui.position[E[r]][i](C,{targetWidth:l,targetHeight:d,elemWidth:f,elemHeight:c,collisionPosition:o,collisionWidth:T,collisionHeight:N,offset:[n[0]+k[0],n[1]+k[1]],my:t.my,at:t.at,within:y,elem:a})}),e.fn.bgiframe&&a.bgiframe(),t.using&&(u=function(e){var n=v.left-C.left,s=n+l-f,o=v.top-C.top,u=o+d-c,h={target:{element:g,left:v.left,top:v.top,width:l,height:d},element:{element:a,left:C.left,top:C.top,width:f,height:c},horizontal:s<0?"left":n>0?"right":"center",vertical:u<0?"top":o>0?"bottom":"middle"};l<f&&i(n+s)<l&&(h.horizontal="center"),d<c&&i(o+u)<d&&(h.vertical="middle"),r(i(n),i(s))>r(i(o),i(u))?h.important="horizontal":h.important="vertical",t.using.call(this,e,h)}),a.offset(e.extend(C,{using:u}))})},e.ui.position={fit:{left:function(e,t){var n=t.within,i=n.isWindow?n.scrollLeft:n.offset.left,s=n.width,o=e.left-t.collisionPosition.marginLeft,u=i-o,a=o+t.collisionWidth-s-i,f;t.collisionWidth>s?u>0&&a<=0?(f=e.left+u+t.collisionWidth-s-i,e.left+=u-f):a>0&&u<=0?e.left=i:u>a?e.left=i+s-t.collisionWidth:e.left=i:u>0?e.left+=u:a>0?e.left-=a:e.left=r(e.left-o,e.left)},top:function(e,t){var n=t.within,i=n.isWindow?n.scrollTop:n.offset.top,s=t.within.height,o=e.top-t.collisionPosition.marginTop,u=i-o,a=o+t.collisionHeight-s-i,f;t.collisionHeight>s?u>0&&a<=0?(f=e.top+u+t.collisionHeight-s-i,e.top+=u-f):a>0&&u<=0?e.top=i:u>a?e.top=i+s-t.collisionHeight:e.top=i:u>0?e.top+=u:a>0?e.top-=a:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var n=t.within,r=n.offset.left+n.scrollLeft,s=n.width,o=n.isWindow?n.scrollLeft:n.offset.left,u=e.left-t.collisionPosition.marginLeft,a=u-o,f=u+t.collisionWidth-s-o,l=t.my[0]==="left"?-t.elemWidth:t.my[0]==="right"?t.elemWidth:0,c=t.at[0]==="left"?t.targetWidth:t.at[0]==="right"?-t.targetWidth:0,h=-2*t.offset[0],p,d;if(a<0){p=e.left+l+c+h+t.collisionWidth-s-r;if(p<0||p<i(a))e.left+=l+c+h}else if(f>0){d=e.left-t.collisionPosition.marginLeft+l+c+h-o;if(d>0||i(d)<f)e.left+=l+c+h}},top:function(e,t){var n=t.within,r=n.offset.top+n.scrollTop,s=n.height,o=n.isWindow?n.scrollTop:n.offset.top,u=e.top-t.collisionPosition.marginTop,a=u-o,f=u+t.collisionHeight-s-o,l=t.my[1]==="top",c=l?-t.elemHeight:t.my[1]==="bottom"?t.elemHeight:0,h=t.at[1]==="top"?t.targetHeight:t.at[1]==="bottom"?-t.targetHeight:0,p=-2*t.offset[1],d,v;a<0?(v=e.top+c+h+p+t.collisionHeight-s-r,e.top+c+h+p>a&&(v<0||v<i(a))&&(e.top+=c+h+p)):f>0&&(d=e.top-t.collisionPosition.marginTop+c+h+p-o,e.top+c+h+p>f&&(d>0||i(d)<f)&&(e.top+=c+h+p))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,n,r,i,s,o=document.getElementsByTagName("body")[0],u=document.createElement("div");t=document.createElement(o?"div":"body"),r={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},o&&e.extend(r,{position:"absolute",left:"-1000px",top:"-1000px"});for(s in r)t.style[s]=r[s];t.appendChild(u),n=o||document.documentElement,n.insertBefore(t,n.firstChild),u.style.cssText="position: absolute; left: 10.7432222px;",i=e(u).offset().left,e.support.offsetFractions=i>10&&i<11,t.innerHTML="",n.removeChild(t)}(),e.uiBackCompat!==!1&&function(e){var n=e.fn.position;e.fn.position=function(r){if(!r||!r.offset)return n.call(this,r);var i=r.offset.split(" "),s=r.at.split(" ");return i.length===1&&(i[1]=i[0]),/^\d/.test(i[0])&&(i[0]="+"+i[0]),/^\d/.test(i[1])&&(i[1]="+"+i[1]),s.length===1&&(/left|center|right/.test(s[0])?s[1]="center":(s[1]=s[0],s[0]="center")),n.call(this,e.extend(r,{at:s[0]+i[0]+" "+s[1]+i[1],offset:t}))}}(jQuery)})(jQuery);(function(e,t){e.widget("ui.draggable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var n=this.options;return this.helper||n.disabled||e(t.target).is(".ui-resizable-handle")?!1:(this.handle=this._getHandle(t),this.handle?(e(n.iframeFix===!0?"iframe":n.iframeFix).each(function(){e('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),n.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,n){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===!1)return this._mouseUp({}),!1;this.position=r.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";return e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n=!1;e.ui.ddmanager&&!this.options.dropBehaviour&&(n=e.ui.ddmanager.drop(this,t)),this.dropped&&(n=this.dropped,this.dropped=!1);var r=this.element[0],i=!1;while(r&&(r=r.parentNode))r==document&&(i=!0);if(!i&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!n||this.options.revert=="valid"&&n||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,n)){var s=this;e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){s._trigger("stop",t)!==!1&&s._clear()})}else this._trigger("stop",t)!==!1&&this._clear();return!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){var n=!this.options.handle||!e(this.options.handle,this.element).length?!0:!1;return e(this.options.handle,this.element).find("*").andSelf().each(function(){this==t.target&&(n=!0)}),n},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return r.parents("body").length||r.appendTo(n.appendTo=="parent"?this.element[0].parentNode:n.appendTo),r[0]!=this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))&&r.css("position","absolute"),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[t.containment=="document"?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t.containment=="document"?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(t.containment=="document"?0:e(window).scrollLeft())+e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(t.containment=="document"?0:e(window).scrollTop())+(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)&&t.containment.constructor!=Array){var n=e(t.containment),r=n[0];if(!r)return;var i=n.offset(),s=e(r).css("overflow")!="hidden";this.containment=[(parseInt(e(r).css("borderLeftWidth"),10)||0)+(parseInt(e(r).css("paddingLeft"),10)||0),(parseInt(e(r).css("borderTopWidth"),10)||0)+(parseInt(e(r).css("paddingTop"),10)||0),(s?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(e(r).css("borderLeftWidth"),10)||0)-(parseInt(e(r).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(s?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(e(r).css("borderTopWidth"),10)||0)-(parseInt(e(r).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=n}else t.containment.constructor==Array&&(this.containment=t.containment)},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName),s=t.pageX,o=t.pageY;if(this.originalPosition){var u;if(this.containment){if(this.relative_container){var a=this.relative_container.offset();u=[this.containment[0]+a.left,this.containment[1]+a.top,this.containment[2]+a.left,this.containment[3]+a.top]}else u=this.containment;t.pageX-this.offset.click.left<u[0]&&(s=u[0]+this.offset.click.left),t.pageY-this.offset.click.top<u[1]&&(o=u[1]+this.offset.click.top),t.pageX-this.offset.click.left>u[2]&&(s=u[2]+this.offset.click.left),t.pageY-this.offset.click.top>u[3]&&(o=u[3]+this.offset.click.top)}if(n.grid){var f=n.grid[1]?this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1]:this.originalPageY;o=u?f-this.offset.click.top<u[1]||f-this.offset.click.top>u[3]?f-this.offset.click.top<u[1]?f+n.grid[1]:f-n.grid[1]:f:f;var l=n.grid[0]?this.originalPageX+Math.round((s-this.originalPageX)/n.grid[0])*n.grid[0]:this.originalPageX;s=u?l-this.offset.click.left<u[0]||l-this.offset.click.left>u[2]?l-this.offset.click.left<u[0]?l+n.grid[0]:l-n.grid[0]:l:l}}return{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():i?0:r.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:r.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,n,r){return r=r||this._uiHash(),e.ui.plugin.call(this,t,[n,r]),t=="drag"&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,n,r)},plugins:{},_uiHash:function(e){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,n){var r=e(this).data("draggable"),i=r.options,s=e.extend({},n,{item:r.element});r.sortables=[],e(i.connectToSortable).each(function(){var n=e.data(this,"sortable");n&&!n.options.disabled&&(r.sortables.push({instance:n,shouldRevert:n.options.revert}),n.refreshPositions(),n._trigger("activate",t,s))})},stop:function(t,n){var r=e(this).data("draggable"),i=e.extend({},n,{item:r.element});e.each(r.sortables,function(){this.instance.isOver?(this.instance.isOver=0,r.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,r.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,i))})},drag:function(t,n){var r=e(this).data("draggable"),i=this,s=function(t){var n=this.offset.click.top,r=this.offset.click.left,i=this.positionAbs.top,s=this.positionAbs.left,o=t.height,u=t.width,a=t.top,f=t.left;return e.ui.isOver(i+n,s+r,a,f,o,u)};e.each(r.sortables,function(s){var o=!1,u=this;this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(o=!0,e.each(r.sortables,function(){return this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this!=u&&this.instance._intersectsWith(this.instance.containerCache)&&e.ui.contains(u.instance.element[0],this.instance.element[0])&&(o=!1),o})),o?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(i).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return n.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=r.offset.click.top,this.instance.offset.click.left=r.offset.click.left,this.instance.offset.parent.left-=r.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=r.offset.parent.top-this.instance.offset.parent.top,r._trigger("toSortable",t),r.dropped=this.instance.element,r.currentItem=r.element,this.instance.fromOutside=r),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),r._trigger("fromSortable",t),r.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,n){var r=e("body"),i=e(this).data("draggable").options;r.css("cursor")&&(i._cursor=r.css("cursor")),r.css("cursor",i.cursor)},stop:function(t,n){var r=e(this).data("draggable").options;r._cursor&&e("body").css("cursor",r._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,n){var r=e(n.helper),i=e(this).data("draggable").options;r.css("opacity")&&(i._opacity=r.css("opacity")),r.css("opacity",i.opacity)},stop:function(t,n){var r=e(this).data("draggable").options;r._opacity&&e(n.helper).css("opacity",r._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(t,n){var r=e(this).data("draggable");r.scrollParent[0]!=document&&r.scrollParent[0].tagName!="HTML"&&(r.overflowOffset=r.scrollParent.offset())},drag:function(t,n){var r=e(this).data("draggable"),i=r.options,s=!1;if(r.scrollParent[0]!=document&&r.scrollParent[0].tagName!="HTML"){if(!i.axis||i.axis!="x")r.overflowOffset.top+r.scrollParent[0].offsetHeight-t.pageY<i.scrollSensitivity?r.scrollParent[0].scrollTop=s=r.scrollParent[0].scrollTop+i.scrollSpeed:t.pageY-r.overflowOffset.top<i.scrollSensitivity&&(r.scrollParent[0].scrollTop=s=r.scrollParent[0].scrollTop-i.scrollSpeed);if(!i.axis||i.axis!="y")r.overflowOffset.left+r.scrollParent[0].offsetWidth-t.pageX<i.scrollSensitivity?r.scrollParent[0].scrollLeft=s=r.scrollParent[0].scrollLeft+i.scrollSpeed:t.pageX-r.overflowOffset.left<i.scrollSensitivity&&(r.scrollParent[0].scrollLeft=s=r.scrollParent[0].scrollLeft-i.scrollSpeed)}else{if(!i.axis||i.axis!="x")t.pageY-e(document).scrollTop()<i.scrollSensitivity?s=e(document).scrollTop(e(document).scrollTop()-i.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<i.scrollSensitivity&&(s=e(document).scrollTop(e(document).scrollTop()+i.scrollSpeed));if(!i.axis||i.axis!="y")t.pageX-e(document).scrollLeft()<i.scrollSensitivity?s=e(document).scrollLeft(e(document).scrollLeft()-i.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<i.scrollSensitivity&&(s=e(document).scrollLeft(e(document).scrollLeft()+i.scrollSpeed))}s!==!1&&e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(r,t)}}),e.ui.plugin.add("draggable","snap",{start:function(t,n){var r=e(this).data("draggable"),i=r.options;r.snapElements=[],e(i.snap.constructor!=String?i.snap.items||":data(draggable)":i.snap).each(function(){var t=e(this),n=t.offset();this!=r.element[0]&&r.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:n.top,left:n.left})})},drag:function(t,n){var r=e(this).data("draggable"),i=r.options,s=i.snapTolerance,o=n.offset.left,u=o+r.helperProportions.width,a=n.offset.top,f=a+r.helperProportions.height;for(var l=r.snapElements.length-1;l>=0;l--){var c=r.snapElements[l].left,h=c+r.snapElements[l].width,p=r.snapElements[l].top,d=p+r.snapElements[l].height;if(!(c-s<o&&o<h+s&&p-s<a&&a<d+s||c-s<o&&o<h+s&&p-s<f&&f<d+s||c-s<u&&u<h+s&&p-s<a&&a<d+s||c-s<u&&u<h+s&&p-s<f&&f<d+s)){r.snapElements[l].snapping&&r.options.snap.release&&r.options.snap.release.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[l].item})),r.snapElements[l].snapping=!1;continue}if(i.snapMode!="inner"){var v=Math.abs(p-f)<=s,m=Math.abs(d-a)<=s,g=Math.abs(c-u)<=s,y=Math.abs(h-o)<=s;v&&(n.position.top=r._convertPositionTo("relative",{top:p-r.helperProportions.height,left:0}).top-r.margins.top),m&&(n.position.top=r._convertPositionTo("relative",{top:d,left:0}).top-r.margins.top),g&&(n.position.left=r._convertPositionTo("relative",{top:0,left:c-r.helperProportions.width}).left-r.margins.left),y&&(n.position.left=r._convertPositionTo("relative",{top:0,left:h}).left-r.margins.left)}var b=v||m||g||y;if(i.snapMode!="outer"){var v=Math.abs(p-a)<=s,m=Math.abs(d-f)<=s,g=Math.abs(c-o)<=s,y=Math.abs(h-u)<=s;v&&(n.position.top=r._convertPositionTo("relative",{top:p,left:0}).top-r.margins.top),m&&(n.position.top=r._convertPositionTo("relative",{top:d-r.helperProportions.height,left:0}).top-r.margins.top),g&&(n.position.left=r._convertPositionTo("relative",{top:0,left:c}).left-r.margins.left),y&&(n.position.left=r._convertPositionTo("relative",{top:0,left:h-r.helperProportions.width}).left-r.margins.left)}!r.snapElements[l].snapping&&(v||m||g||y||b)&&r.options.snap.snap&&r.options.snap.snap.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[l].item})),r.snapElements[l].snapping=v||m||g||y||b}}}),e.ui.plugin.add("draggable","stack",{start:function(t,n){var r=e(this).data("draggable").options,i=e.makeArray(e(r.stack)).sort(function(t,n){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(n).css("zIndex"),10)||0)});if(!i.length)return;var s=parseInt(i[0].style.zIndex)||0;e(i).each(function(e){this.style.zIndex=s+e}),this[0].style.zIndex=s+i.length}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,n){var r=e(n.helper),i=e(this).data("draggable").options;r.css("zIndex")&&(i._zIndex=r.css("zIndex")),r.css("zIndex",i.zIndex)},stop:function(t,n){var r=e(this).data("draggable").options;r._zIndex&&e(n.helper).css("zIndex",r._zIndex)}})})(jQuery);(function(e,t){e.widget("ui.droppable",{version:"1.9.2",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var t=this.options,n=t.accept;this.isover=0,this.isout=1,this.accept=e.isFunction(n)?n:function(e){return e.is(n)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},e.ui.ddmanager.droppables[t.scope]=e.ui.ddmanager.droppables[t.scope]||[],e.ui.ddmanager.droppables[t.scope].push(this),t.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){var t=e.ui.ddmanager.droppables[this.options.scope];for(var n=0;n<t.length;n++)t[n]==this&&t.splice(n,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,n){t=="accept"&&(this.accept=e.isFunction(n)?n:function(e){return e.is(n)}),e.Widget.prototype._setOption.apply(this,arguments)},_activate:function(t){var n=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),n&&this._trigger("activate",t,this.ui(n))},_deactivate:function(t){var n=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),n&&this._trigger("deactivate",t,this.ui(n))},_over:function(t){var n=e.ui.ddmanager.current;if(!n||(n.currentItem||n.element)[0]==this.element[0])return;this.accept.call(this.element[0],n.currentItem||n.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(n)))},_out:function(t){var n=e.ui.ddmanager.current;if(!n||(n.currentItem||n.element)[0]==this.element[0])return;this.accept.call(this.element[0],n.currentItem||n.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(n)))},_drop:function(t,n){var r=n||e.ui.ddmanager.current;if(!r||(r.currentItem||r.element)[0]==this.element[0])return!1;var i=!1;return this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var t=e.data(this,"droppable");if(t.options.greedy&&!t.options.disabled&&t.options.scope==r.options.scope&&t.accept.call(t.element[0],r.currentItem||r.element)&&e.ui.intersect(r,e.extend(t,{offset:t.element.offset()}),t.options.tolerance))return i=!0,!1}),i?!1:this.accept.call(this.element[0],r.currentItem||r.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(r)),this.element):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(t,n,r){if(!n.offset)return!1;var i=(t.positionAbs||t.position.absolute).left,s=i+t.helperProportions.width,o=(t.positionAbs||t.position.absolute).top,u=o+t.helperProportions.height,a=n.offset.left,f=a+n.proportions.width,l=n.offset.top,c=l+n.proportions.height;switch(r){case"fit":return a<=i&&s<=f&&l<=o&&u<=c;case"intersect":return a<i+t.helperProportions.width/2&&s-t.helperProportions.width/2<f&&l<o+t.helperProportions.height/2&&u-t.helperProportions.height/2<c;case"pointer":var h=(t.positionAbs||t.position.absolute).left+(t.clickOffset||t.offset.click).left,p=(t.positionAbs||t.position.absolute).top+(t.clickOffset||t.offset.click).top,d=e.ui.isOver(p,h,l,a,n.proportions.height,n.proportions.width);return d;case"touch":return(o>=l&&o<=c||u>=l&&u<=c||o<l&&u>c)&&(i>=a&&i<=f||s>=a&&s<=f||i<a&&s>f);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,n){var r=e.ui.ddmanager.droppables[t.options.scope]||[],i=n?n.type:null,s=(t.currentItem||t.element).find(":data(droppable)").andSelf();e:for(var o=0;o<r.length;o++){if(r[o].options.disabled||t&&!r[o].accept.call(r[o].element[0],t.currentItem||t.element))continue;for(var u=0;u<s.length;u++)if(s[u]==r[o].element[0]){r[o].proportions.height=0;continue e}r[o].visible=r[o].element.css("display")!="none";if(!r[o].visible)continue;i=="mousedown"&&r[o]._activate.call(r[o],n),r[o].offset=r[o].element.offset(),r[o].proportions={width:r[o].element[0].offsetWidth,height:r[o].element[0].offsetHeight}}},drop:function(t,n){var r=!1;return e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options)return;!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance)&&(r=this._drop.call(this,n)||r),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,n))}),r},dragStart:function(t,n){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,n)})},drag:function(t,n){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,n),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(this.options.disabled||this.greedyChild||!this.visible)return;var r=e.ui.intersect(t,this,this.options.tolerance),i=!r&&this.isover==1?"isout":r&&this.isover==0?"isover":null;if(!i)return;var s;if(this.options.greedy){var o=this.options.scope,u=this.element.parents(":data(droppable)").filter(function(){return e.data(this,"droppable").options.scope===o});u.length&&(s=e.data(u[0],"droppable"),s.greedyChild=i=="isover"?1:0)}s&&i=="isover"&&(s.isover=0,s.isout=1,s._out.call(s,n)),this[i]=1,this[i=="isout"?"isover":"isout"]=0,this[i=="isover"?"_over":"_out"].call(this,n),s&&i=="isout"&&(s.isout=0,s.isover=1,s._over.call(s,n))})},dragStop:function(t,n){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,n)}}})(jQuery);(function(e,t){e.widget("ui.resizable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var t=this,n=this.options;this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!n.aspectRatio,aspectRatio:n.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:n.helper||n.ghost||n.animate?n.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=n.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var r=this.handles.split(",");this.handles={};for(var i=0;i<r.length;i++){var s=e.trim(r[i]),o="ui-resizable-"+s,u=e('<div class="ui-resizable-handle '+o+'"></div>');u.css({zIndex:n.zIndex}),"se"==s&&u.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(u)}}this._renderAxis=function(t){t=t||this.element;for(var n in this.handles){this.handles[n].constructor==String&&(this.handles[n]=e(this.handles[n],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var r=e(this.handles[n],this.element),i=0;i=/sw|ne|nw|se|n|s/.test(n)?r.outerHeight():r.outerWidth();var s=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");t.css(s,i),this._proportionallyResize()}if(!e(this.handles[n]).length)continue}},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!t.resizing){if(this.className)var e=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);t.axis=e&&e[1]?e[1]:"se"}}),n.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(n.disabled)return;e(this).removeClass("ui-resizable-autohide"),t._handles.show()}).mouseleave(function(){if(n.disabled)return;t.resizing||(e(this).addClass("ui-resizable-autohide"),t._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){t(this.element);var n=this.element;this.originalElement.css({position:n.css("position"),width:n.outerWidth(),height:n.outerHeight(),top:n.css("top"),left:n.css("left")}).insertAfter(n),n.remove()}return this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_mouseCapture:function(t){var n=!1;for(var r in this.handles)e(this.handles[r])[0]==t.target&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(t){var r=this.options,i=this.element.position(),s=this.element;this.resizing=!0,this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()},(s.is(".ui-draggable")||/absolute/.test(s.css("position")))&&s.css({position:"absolute",top:i.top,left:i.left}),this._renderProxy();var o=n(this.helper.css("left")),u=n(this.helper.css("top"));r.containment&&(o+=e(r.containment).scrollLeft()||0,u+=e(r.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:o,top:u},this.size=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalSize=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalPosition={left:o,top:u},this.sizeDiff={width:s.outerWidth()-s.width(),height:s.outerHeight()-s.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio=typeof r.aspectRatio=="number"?r.aspectRatio:this.originalSize.width/this.originalSize.height||1;var a=e(".ui-resizable-"+this.axis).css("cursor");return e("body").css("cursor",a=="auto"?this.axis+"-resize":a),s.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(e){var t=this.helper,n=this.options,r={},i=this,s=this.originalMousePosition,o=this.axis,u=e.pageX-s.left||0,a=e.pageY-s.top||0,f=this._change[o];if(!f)return!1;var l=f.apply(this,[e,u,a]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey)l=this._updateRatio(l,e);return l=this._respectSize(l,e),this._propagate("resize",e),t.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",e,this.ui()),!1},_mouseStop:function(t){this.resizing=!1;var n=this.options,r=this;if(this._helper){var i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&e.ui.hasScroll(i[0],"left")?0:r.sizeDiff.height,u=s?0:r.sizeDiff.width,a={width:r.helper.width()-u,height:r.helper.height()-o},f=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,l=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;n.animate||this.element.css(e.extend(a,{top:l,left:f})),r.helper.height(r.size.height),r.helper.width(r.size.width),this._helper&&!n.animate&&this._proportionallyResize()}return e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t=this.options,n,i,s,o,u;u={minWidth:r(t.minWidth)?t.minWidth:0,maxWidth:r(t.maxWidth)?t.maxWidth:Infinity,minHeight:r(t.minHeight)?t.minHeight:0,maxHeight:r(t.maxHeight)?t.maxHeight:Infinity};if(this._aspectRatio||e)n=u.minHeight*this.aspectRatio,s=u.minWidth/this.aspectRatio,i=u.maxHeight*this.aspectRatio,o=u.maxWidth/this.aspectRatio,n>u.minWidth&&(u.minWidth=n),s>u.minHeight&&(u.minHeight=s),i<u.maxWidth&&(u.maxWidth=i),o<u.maxHeight&&(u.maxHeight=o);this._vBoundaries=u},_updateCache:function(e){var t=this.options;this.offset=this.helper.offset(),r(e.left)&&(this.position.left=e.left),r(e.top)&&(this.position.top=e.top),r(e.height)&&(this.size.height=e.height),r(e.width)&&(this.size.width=e.width)},_updateRatio:function(e,t){var n=this.options,i=this.position,s=this.size,o=this.axis;return r(e.height)?e.width=e.height*this.aspectRatio:r(e.width)&&(e.height=e.width/this.aspectRatio),o=="sw"&&(e.left=i.left+(s.width-e.width),e.top=null),o=="nw"&&(e.top=i.top+(s.height-e.height),e.left=i.left+(s.width-e.width)),e},_respectSize:function(e,t){var n=this.helper,i=this._vBoundaries,s=this._aspectRatio||t.shiftKey,o=this.axis,u=r(e.width)&&i.maxWidth&&i.maxWidth<e.width,a=r(e.height)&&i.maxHeight&&i.maxHeight<e.height,f=r(e.width)&&i.minWidth&&i.minWidth>e.width,l=r(e.height)&&i.minHeight&&i.minHeight>e.height;f&&(e.width=i.minWidth),l&&(e.height=i.minHeight),u&&(e.width=i.maxWidth),a&&(e.height=i.maxHeight);var c=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,p=/sw|nw|w/.test(o),d=/nw|ne|n/.test(o);f&&p&&(e.left=c-i.minWidth),u&&p&&(e.left=c-i.maxWidth),l&&d&&(e.top=h-i.minHeight),a&&d&&(e.top=h-i.maxHeight);var v=!e.width&&!e.height;return v&&!e.left&&e.top?e.top=null:v&&!e.top&&e.left&&(e.left=null),e},_proportionallyResize:function(){var t=this.options;if(!this._proportionallyResizeElements.length)return;var n=this.helper||this.element;for(var r=0;r<this._proportionallyResizeElements.length;r++){var i=this._proportionallyResizeElements[r];if(!this.borderDif){var s=[i.css("borderTopWidth"),i.css("borderRightWidth"),i.css("borderBottomWidth"),i.css("borderLeftWidth")],o=[i.css("paddingTop"),i.css("paddingRight"),i.css("paddingBottom"),i.css("paddingLeft")];this.borderDif=e.map(s,function(e,t){var n=parseInt(e,10)||0,r=parseInt(o[t],10)||0;return n+r})}i.css({height:n.height()-this.borderDif[0]-this.borderDif[2]||0,width:n.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var t=this.element,n=this.options;this.elementOffset=t.offset();if(this._helper){this.helper=this.helper||e('<div style="overflow:hidden;"></div>');var r=e.ui.ie6?1:0,i=e.ui.ie6?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+i,height:this.element.outerHeight()+i,position:"absolute",left:this.elementOffset.left-r+"px",top:this.elementOffset.top-r+"px",zIndex:++n.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(e,t,n){return{width:this.originalSize.width+t}},w:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{top:s.top+n,height:i.height-n}},s:function(e,t,n){return{height:this.originalSize.height+n}},se:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},sw:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,n,r]))},ne:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},nw:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,n,r]))}},_propagate:function(t,n){e.ui.plugin.call(this,t,[n,this.ui()]),t!="resize"&&this._trigger(t,n,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","alsoResize",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=function(t){e(t).each(function(){var t=e(this);t.data("resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};typeof i.alsoResize=="object"&&!i.alsoResize.parentNode?i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)}):s(i.alsoResize)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.originalSize,o=r.originalPosition,u={height:r.size.height-s.height||0,width:r.size.width-s.width||0,top:r.position.top-o.top||0,left:r.position.left-o.left||0},a=function(t,r){e(t).each(function(){var t=e(this),i=e(this).data("resizable-alsoresize"),s={},o=r&&r.length?r:t.parents(n.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var n=(i[t]||0)+(u[t]||0);n&&n>=0&&(s[t]=n||null)}),t.css(s)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?e.each(i.alsoResize,function(e,t){a(e,t)}):a(i.alsoResize)},stop:function(t,n){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","animate",{stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r._proportionallyResizeElements,o=s.length&&/textarea/i.test(s[0].nodeName),u=o&&e.ui.hasScroll(s[0],"left")?0:r.sizeDiff.height,a=o?0:r.sizeDiff.width,f={width:r.size.width-a,height:r.size.height-u},l=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,c=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;r.element.animate(e.extend(f,c&&l?{top:c,left:l}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var n={width:parseInt(r.element.css("width"),10),height:parseInt(r.element.css("height"),10),top:parseInt(r.element.css("top"),10),left:parseInt(r.element.css("left"),10)};s&&s.length&&e(s[0]).css({width:n.width,height:n.height}),r._updateCache(n),r._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(t,r){var i=e(this).data("resizable"),s=i.options,o=i.element,u=s.containment,a=u instanceof e?u.get(0):/parent/.test(u)?o.parent().get(0):u;if(!a)return;i.containerElement=e(a);if(/document/.test(u)||u==document)i.containerOffset={left:0,top:0},i.containerPosition={left:0,top:0},i.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight};else{var f=e(a),l=[];e(["Top","Right","Left","Bottom"]).each(function(e,t){l[e]=n(f.css("padding"+t))}),i.containerOffset=f.offset(),i.containerPosition=f.position(),i.containerSize={height:f.innerHeight()-l[3],width:f.innerWidth()-l[1]};var c=i.containerOffset,h=i.containerSize.height,p=i.containerSize.width,d=e.ui.hasScroll(a,"left")?a.scrollWidth:p,v=e.ui.hasScroll(a)?a.scrollHeight:h;i.parentData={element:a,left:c.left,top:c.top,width:d,height:v}}},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.containerSize,o=r.containerOffset,u=r.size,a=r.position,f=r._aspectRatio||t.shiftKey,l={top:0,left:0},c=r.containerElement;c[0]!=document&&/static/.test(c.css("position"))&&(l=o),a.left<(r._helper?o.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-o.left:r.position.left-l.left),f&&(r.size.height=r.size.width/r.aspectRatio),r.position.left=i.helper?o.left:0),a.top<(r._helper?o.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-o.top:r.position.top),f&&(r.size.width=r.size.height*r.aspectRatio),r.position.top=r._helper?o.top:0),r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top;var h=Math.abs((r._helper?r.offset.left-l.left:r.offset.left-l.left)+r.sizeDiff.width),p=Math.abs((r._helper?r.offset.top-l.top:r.offset.top-o.top)+r.sizeDiff.height),d=r.containerElement.get(0)==r.element.parent().get(0),v=/relative|absolute/.test(r.containerElement.css("position"));d&&v&&(h-=r.parentData.left),h+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-h,f&&(r.size.height=r.size.width/r.aspectRatio)),p+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-p,f&&(r.size.width=r.size.height*r.aspectRatio))},stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.position,o=r.containerOffset,u=r.containerPosition,a=r.containerElement,f=e(r.helper),l=f.offset(),c=f.outerWidth()-r.sizeDiff.width,h=f.outerHeight()-r.sizeDiff.height;r._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h}),r._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h})}}),e.ui.plugin.add("resizable","ghost",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size;r.ghost=r.originalElement.clone(),r.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:""),r.ghost.appendTo(r.helper)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.ghost.css({position:"relative",height:r.size.height,width:r.size.width})},stop:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.helper&&r.helper.get(0).removeChild(r.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size,o=r.originalSize,u=r.originalPosition,a=r.axis,f=i._aspectRatio||t.shiftKey;i.grid=typeof i.grid=="number"?[i.grid,i.grid]:i.grid;var l=Math.round((s.width-o.width)/(i.grid[0]||1))*(i.grid[0]||1),c=Math.round((s.height-o.height)/(i.grid[1]||1))*(i.grid[1]||1);/^(se|s|e)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c):/^(ne)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c):/^(sw)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.left=u.left-l):(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c,r.position.left=u.left-l)}});var n=function(e){return parseInt(e,10)||0},r=function(e){return!isNaN(parseInt(e,10))}})(jQuery);(function(e,t){e.widget("ui.selectable",e.ui.mouse,{version:"1.9.2",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var t=this;this.element.addClass("ui-selectable"),this.dragged=!1;var n;this.refresh=function(){n=e(t.options.filter,t.element[0]),n.addClass("ui-selectee"),n.each(function(){var t=e(this),n=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:n.left,top:n.top,right:n.left+t.outerWidth(),bottom:n.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=n.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;var r=this.options;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.clientX,top:t.clientY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().andSelf().each(function(){var r=e.data(this,"selectable-item");if(r){var i=!t.metaKey&&!t.ctrlKey||!r.$element.hasClass("ui-selected");return r.$element.removeClass(i?"ui-unselecting":"ui-selected").addClass(i?"ui-selecting":"ui-unselecting"),r.unselecting=!i,r.selecting=i,r.selected=i,i?n._trigger("selecting",t,{selecting:r.element}):n._trigger("unselecting",t,{unselecting:r.element}),!1}})},_mouseDrag:function(t){var n=this;this.dragged=!0;if(this.options.disabled)return;var r=this.options,i=this.opos[0],s=this.opos[1],o=t.pageX,u=t.pageY;if(i>o){var a=o;o=i,i=a}if(s>u){var a=u;u=s,s=a}return this.helper.css({left:i,top:s,width:o-i,height:u-s}),this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!a||a.element==n.element[0])return;var f=!1;r.tolerance=="touch"?f=!(a.left>o||a.right<i||a.top>u||a.bottom<s):r.tolerance=="fit"&&(f=a.left>i&&a.right<o&&a.top>s&&a.bottom<u),f?(a.selected&&(a.$element.removeClass("ui-selected"),a.selected=!1),a.unselecting&&(a.$element.removeClass("ui-unselecting"),a.unselecting=!1),a.selecting||(a.$element.addClass("ui-selecting"),a.selecting=!0,n._trigger("selecting",t,{selecting:a.element}))):(a.selecting&&((t.metaKey||t.ctrlKey)&&a.startselected?(a.$element.removeClass("ui-selecting"),a.selecting=!1,a.$element.addClass("ui-selected"),a.selected=!0):(a.$element.removeClass("ui-selecting"),a.selecting=!1,a.startselected&&(a.$element.addClass("ui-unselecting"),a.unselecting=!0),n._trigger("unselecting",t,{unselecting:a.element}))),a.selected&&!t.metaKey&&!t.ctrlKey&&!a.startselected&&(a.$element.removeClass("ui-selected"),a.selected=!1,a.$element.addClass("ui-unselecting"),a.unselecting=!0,n._trigger("unselecting",t,{unselecting:a.element})))}),!1},_mouseStop:function(t){var n=this;this.dragged=!1;var r=this.options;return e(".ui-unselecting",this.element[0]).each(function(){var r=e.data(this,"selectable-item");r.$element.removeClass("ui-unselecting"),r.unselecting=!1,r.startselected=!1,n._trigger("unselected",t,{unselected:r.element})}),e(".ui-selecting",this.element[0]).each(function(){var r=e.data(this,"selectable-item");r.$element.removeClass("ui-selecting").addClass("ui-selected"),r.selecting=!1,r.selected=!0,r.startselected=!0,n._trigger("selected",t,{selected:r.element})}),this._trigger("stop",t),this.helper.remove(),!1}})})(jQuery);(function(e,t){e.widget("ui.sortable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(t);var i=null,s=e(t.target).parents().each(function(){if(e.data(this,r.widgetName+"-item")==r)return i=e(this),!1});e.data(t.target,r.widgetName+"-item")==r&&(i=e(t.target));if(!i)return!1;if(this.options.handle&&!n){var o=!1;e(this.options.handle,i).find("*").andSelf().each(function(){this==t.target&&(o=!0)});if(!o)return!1}return this.currentItem=i,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),i.containment&&this._setContainment(),i.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",i.cursor)),i.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",i.opacity)),i.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",i.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(var s=this.containers.length-1;s>=0;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var n=this.options,r=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<n.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+n.scrollSpeed:t.pageY-this.overflowOffset.top<n.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-n.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<n.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+n.scrollSpeed:t.pageX-this.overflowOffset.left<n.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-n.scrollSpeed)):(t.pageY-e(document).scrollTop()<n.scrollSensitivity?r=e(document).scrollTop(e(document).scrollTop()-n.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<n.scrollSensitivity&&(r=e(document).scrollTop(e(document).scrollTop()+n.scrollSpeed)),t.pageX-e(document).scrollLeft()<n.scrollSensitivity?r=e(document).scrollLeft(e(document).scrollLeft()-n.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<n.scrollSensitivity&&(r=e(document).scrollLeft(e(document).scrollLeft()+n.scrollSpeed))),r!==!1&&e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var i=this.items.length-1;i>=0;i--){var s=this.items[i],o=s.item[0],u=this._intersectsWithPointer(s);if(!u)continue;if(s.instance!==this.currentContainer)continue;if(o!=this.currentItem[0]&&this.placeholder[u==1?"next":"prev"]()[0]!=o&&!e.contains(this.placeholder[0],o)&&(this.options.type=="semi-dynamic"?!e.contains(this.element[0],o):!0)){this.direction=u==1?"down":"up";if(this.options.tolerance!="pointer"&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+f<a&&t+l>s&&t+l<o;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?c:s<t+this.helperProportions.width/2&&n-this.helperProportions.width/2<o&&u<r+this.helperProportions.height/2&&i-this.helperProportions.height/2<a},_intersectsWithPointer:function(t){var n=this.options.axis==="x"||e.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),r=this.options.axis==="y"||e.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),i=n&&r,s=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return i?this.floating?o&&o=="right"||s=="down"?2:1:s&&(s=="down"?2:1):!1},_intersectsWithSides:function(t){var n=e.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),r=e.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),i=this._getDragVerticalDirection(),s=this._getDragHorizontalDirection();return this.floating&&s?s=="right"&&r||s=="left"&&!r:i&&(i=="down"&&n||i=="up"&&!n)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return e!=0&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!=0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor==String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n=[],r=[],i=this._connectWith();if(i&&t)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&r.push([e.isFunction(a.options.items)?a.options.items.call(a.element):e(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a])}}r.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var s=r.length-1;s>=0;s--)r[s][0].each(function(){n.push(this)});return e(n)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var n=0;n<t.length;n++)if(t[n]==e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var n=this.items,r=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],i=this._connectWith();if(i&&this.ready)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&(r.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a))}}for(var s=r.length-1;s>=0;s--){var f=r[s][1],l=r[s][0];for(var u=0,c=l.length;u<c;u++){var h=e(l[u]);h.data(this.widgetName+"-item",f),n.push({item:h,instance:f,width:0,height:0,left:0,top:0})}}},refreshPositions:function(t){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var n=this.items.length-1;n>=0;n--){var r=this.items[n];if(r.instance!=this.currentContainer&&this.currentContainer&&r.item[0]!=this.currentItem[0])continue;var i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item;t||(r.width=i.outerWidth(),r.height=i.outerHeight());var s=i.offset();r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var n=this.containers.length-1;n>=0;n--){var s=this.containers[n].element.offset();this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight()}return this},_createPlaceholder:function(t){t=t||this;var n=t.options;if(!n.placeholder||n.placeholder.constructor==String){var r=n.placeholder;n.placeholder={element:function(){var n=e(document.createElement(t.currentItem[0].nodeName)).addClass(r||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return r||(n.style.visibility="hidden"),n},update:function(e,i){if(r&&!n.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}}}t.placeholder=e(n.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),n.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n=null,r=null;for(var i=this.containers.length-1;i>=0;i--){if(e.contains(this.currentItem[0],this.containers[i].element[0]))continue;if(this._intersectsWith(this.containers[i].containerCache)){if(n&&e.contains(this.containers[i].element[0],n.element[0]))continue;n=this.containers[i],r=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0)}if(!n)return;if(this.containers.length===1)this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1;else{var s=1e4,o=null,u=this.containers[r].floating?"left":"top",a=this.containers[r].floating?"width":"height",f=this.positionAbs[u]+this.offset.click[u];for(var l=this.items.length-1;l>=0;l--){if(!e.contains(this.containers[r].element[0],this.items[l].item[0]))continue;if(this.items[l].item[0]==this.currentItem[0])continue;var c=this.items[l].item.offset()[u],h=!1;Math.abs(c-f)>Math.abs(c+this.items[l][a]-f)&&(h=!0,c+=this.items[l][a]),Math.abs(c-f)<s&&(s=Math.abs(c-f),o=this.items[l],this.direction=h?"up":"down")}if(!o&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[r],o?this._rearrange(t,o,null,!0):this._rearrange(t,null,this.containers[r].element,!0),this._trigger("change",t,this._uiHash()),this.containers[r]._trigger("change",t,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1}},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t,this.currentItem])):n.helper=="clone"?this.currentItem.clone():this.currentItem;return r.parents("body").length||e(n.appendTo!="parent"?n.appendTo:this.currentItem[0].parentNode)[0].appendChild(r[0]),r[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(r[0].style.width==""||n.forceHelperSize)&&r.width(this.currentItem.width()),(r[0].style.height==""||n.forceHelperSize)&&r.height(this.currentItem.height()),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)){var n=e(t.containment)[0],r=e(t.containment).offset(),i=e(n).css("overflow")!="hidden";this.containment=[r.left+(parseInt(e(n).css("borderLeftWidth"),10)||0)+(parseInt(e(n).css("paddingLeft"),10)||0)-this.margins.left,r.top+(parseInt(e(n).css("borderTopWidth"),10)||0)+(parseInt(e(n).css("paddingTop"),10)||0)-this.margins.top,r.left+(i?Math.max(n.scrollWidth,n.offsetWidth):n.offsetWidth)-(parseInt(e(n).css("borderLeftWidth"),10)||0)-(parseInt(e(n).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,r.top+(i?Math.max(n.scrollHeight,n.offsetHeight):n.offsetHeight)-(parseInt(e(n).css("borderTopWidth"),10)||0)-(parseInt(e(n).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var s=t.pageX,o=t.pageY;if(this.originalPosition){this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(s=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(o=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top));if(n.grid){var u=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1];o=this.containment?u-this.offset.click.top<this.containment[1]||u-this.offset.click.top>this.containment[3]?u-this.offset.click.top<this.containment[1]?u+n.grid[1]:u-n.grid[1]:u:u;var a=this.originalPageX+Math.round((s-this.originalPageX)/n.grid[0])*n.grid[0];s=this.containment?a-this.offset.click.left<this.containment[0]||a-this.offset.click.left>this.containment[2]?a-this.offset.click.left<this.containment[0]?a+n.grid[0]:a-n.grid[0]:a:a}}return{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():i?0:r.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:r.scrollLeft())}},_rearrange:function(e,t,n,r){n?n[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var i=this.counter;this._delay(function(){i==this.counter&&this.refreshPositions(!r)})},_clear:function(t,n){this.reverting=!1;var r=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var i in this._storedCSS)if(this._storedCSS[i]=="auto"||this._storedCSS[i]=="static")this._storedCSS[i]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!n&&r.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!n&&r.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(n||(r.push(function(e){this._trigger("remove",e,this._uiHash())}),r.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),r.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer))));for(var i=this.containers.length-1;i>=0;i--)n||r.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(r.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(var i=0;i<r.length;i++)r[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}n||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!n){for(var i=0;i<r.length;i++)r[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var n=t||this;return{helper:n.helper,placeholder:n.placeholder||e([]),position:n.position,originalPosition:n.originalPosition,offset:n.positionAbs,item:n.currentItem,sender:t?t.element:null}}})})(jQuery);(function(e,t){var n=0,r={},i={};r.height=r.paddingTop=r.paddingBottom=r.borderTopWidth=r.borderBottomWidth="hide",i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="show",e.widget("ui.accordion",{version:"1.9.2",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var t=this.accordionId="ui-accordion-"+(this.element.attr("id")||++n),r=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset"),this.headers=this.element.find(r.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this._hoverable(this.headers),this._focusable(this.headers),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").hide(),!r.collapsible&&(r.active===!1||r.active==null)&&(r.active=0),r.active<0&&(r.active+=this.headers.length),this.active=this._findActive(r.active).addClass("ui-accordion-header-active ui-state-active").toggleClass("ui-corner-all ui-corner-top"),this.active.next().addClass("ui-accordion-content-active").show(),this._createIcons(),this.refresh(),this.element.attr("role","tablist"),this.headers.attr("role","tab").each(function(n){var r=e(this),i=r.attr("id"),s=r.next(),o=s.attr("id");i||(i=t+"-header-"+n,r.attr("id",i)),o||(o=t+"-panel-"+n,s.attr("id",o)),r.attr("aria-controls",o),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._on(this.headers,{keydown:"_keydown"}),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._setupEvents(r.event)},_getCreateEventData:function(){return{header:this.active,content:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("<span>").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this.options.heightStyle!=="content"&&e.css("height","")},_setOption:function(e,t){if(e==="active"){this._activate(t);return}e==="event"&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),e==="collapsible"&&!t&&this.options.active===!1&&this._activate(0),e==="icons"&&(this._destroyIcons(),t&&this._createIcons()),e==="disabled"&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)},_keydown:function(t){if(t.altKey||t.ctrlKey)return;var n=e.ui.keyCode,r=this.headers.length,i=this.headers.index(t.target),s=!1;switch(t.keyCode){case n.RIGHT:case n.DOWN:s=this.headers[(i+1)%r];break;case n.LEFT:case n.UP:s=this.headers[(i-1+r)%r];break;case n.SPACE:case n.ENTER:this._eventHandler(t);break;case n.HOME:s=this.headers[0];break;case n.END:s=this.headers[r-1]}s&&(e(t.target).attr("tabIndex",-1),e(s).attr("tabIndex",0),s.focus(),t.preventDefault())},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t,n,r=this.options.heightStyle,i=this.element.parent();r==="fill"?(e.support.minHeight||(n=i.css("overflow"),i.css("overflow","hidden")),t=i.height(),this.element.siblings(":visible").each(function(){var n=e(this),r=n.css("position");if(r==="absolute"||r==="fixed")return;t-=n.outerHeight(!0)}),n&&i.css("overflow",n),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):r==="auto"&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var n=this._findActive(t)[0];if(n===this.active[0])return;n=n||this.active[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return typeof t=="number"?this.headers.eq(t):e()},_setupEvents:function(t){var n={};if(!t)return;e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._on(this.headers,n)},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i[0]===r[0],o=s&&n.collapsible,u=o?e():i.next(),a=r.next(),f={oldHeader:r,oldPanel:a,newHeader:o?e():i,newPanel:u};t.preventDefault();if(s&&!n.collapsible||this._trigger("beforeActivate",t,f)===!1)return;n.active=o?!1:this.headers.index(i),this.active=s?e():i,this._toggle(f),r.removeClass("ui-accordion-header-active ui-state-active"),n.icons&&r.children(".ui-accordion-header-icon").removeClass(n.icons.activeHeader).addClass(n.icons.header),s||(i.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),n.icons&&i.children(".ui-accordion-header-icon").removeClass(n.icons.header).addClass(n.icons.activeHeader),i.next().addClass("ui-accordion-content-active"))},_toggle:function(t){var n=t.newPanel,r=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=n,this.prevHide=r,this.options.animate?this._animate(n,r,t):(r.hide(),n.show(),this._toggleComplete(t)),r.attr({"aria-expanded":"false","aria-hidden":"true"}),r.prev().attr("aria-selected","false"),n.length&&r.length?r.prev().attr("tabIndex",-1):n.length&&this.headers.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),n.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(e,t,n){var s,o,u,a=this,f=0,l=e.length&&(!t.length||e.index()<t.index()),c=this.options.animate||{},h=l&&c.down||c,p=function(){a._toggleComplete(n)};typeof h=="number"&&(u=h),typeof h=="string"&&(o=h),o=o||h.easing||c.easing,u=u||h.duration||c.duration;if(!t.length)return e.animate(i,u,o,p);if(!e.length)return t.animate(r,u,o,p);s=e.show().outerHeight(),t.animate(r,{duration:u,easing:o,step:function(e,t){t.now=Math.round(e)}}),e.hide().animate(i,{duration:u,easing:o,complete:p,step:function(e,n){n.now=Math.round(e),n.prop!=="height"?f+=n.now:a.options.heightStyle!=="content"&&(n.now=Math.round(s-t.outerHeight()-f),f=0)}})},_toggleComplete:function(e){var t=e.oldPanel;t.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),t.length&&(t.parent()[0].className=t.parent()[0].className),this._trigger("activate",null,e)}}),e.uiBackCompat!==!1&&(function(e,t){e.extend(t.options,{navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}});var n=t._create;t._create=function(){if(this.options.navigation){var t=this,r=this.element.find(this.options.header),i=r.next(),s=r.add(i).find("a").filter(this.options.navigationFilter)[0];s&&r.add(i).each(function(n){if(e.contains(this,s))return t.options.active=Math.floor(n/2),!1})}n.call(this)}}(jQuery,jQuery.ui.accordion.prototype),function(e,t){e.extend(t.options,{heightStyle:null,autoHeight:!0,clearStyle:!1,fillSpace:!1});var n=t._create,r=t._setOption;e.extend(t,{_create:function(){this.options.heightStyle=this.options.heightStyle||this._mergeHeightStyle(),n.call(this)},_setOption:function(e){if(e==="autoHeight"||e==="clearStyle"||e==="fillSpace")this.options.heightStyle=this._mergeHeightStyle();r.apply(this,arguments)},_mergeHeightStyle:function(){var e=this.options;if(e.fillSpace)return"fill";if(e.clearStyle)return"content";if(e.autoHeight)return"auto"}})}(jQuery,jQuery.ui.accordion.prototype),function(e,t){e.extend(t.options.icons,{activeHeader:null,headerSelected:"ui-icon-triangle-1-s"});var n=t._createIcons;t._createIcons=function(){this.options.icons&&(this.options.icons.activeHeader=this.options.icons.activeHeader||this.options.icons.headerSelected),n.call(this)}}(jQuery,jQuery.ui.accordion.prototype),function(e,t){t.activate=t._activate;var n=t._findActive;t._findActive=function(e){return e===-1&&(e=!1),e&&typeof e!="number"&&(e=this.headers.index(this.headers.filter(e)),e===-1&&(e=!1)),n.call(this,e)}}(jQuery,jQuery.ui.accordion.prototype),jQuery.ui.accordion.prototype.resize=jQuery.ui.accordion.prototype.refresh,function(e,t){e.extend(t.options,{change:null,changestart:null});var n=t._trigger;t._trigger=function(e,t,r){var i=n.apply(this,arguments);return i?(e==="beforeActivate"?i=n.call(this,"changestart",t,{oldHeader:r.oldHeader,oldContent:r.oldPanel,newHeader:r.newHeader,newContent:r.newPanel}):e==="activate"&&(i=n.call(this,"change",t,{oldHeader:r.oldHeader,oldContent:r.oldPanel,newHeader:r.newHeader,newContent:r.newPanel})),i):!1}}(jQuery,jQuery.ui.accordion.prototype),function(e,t){e.extend(t.options,{animate:null,animated:"slide"});var n=t._create;t._create=function(){var e=this.options;e.animate===null&&(e.animated?e.animated==="slide"?e.animate=300:e.animated==="bounceslide"?e.animate={duration:200,down:{easing:"easeOutBounce",duration:1e3}}:e.animate=e.animated:e.animate=!1),n.call(this)}}(jQuery,jQuery.ui.accordion.prototype))})(jQuery);(function(e,t){var n=0;e.widget("ui.autocomplete",{version:"1.9.2",defaultElement:"<input>",options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var t,n,r;this.isMultiLine=this._isMultiLine(),this.valueMethod=this.element[this.element.is("input,textarea")?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(i){if(this.element.prop("readOnly")){t=!0,r=!0,n=!0;return}t=!1,r=!1,n=!1;var s=e.ui.keyCode;switch(i.keyCode){case s.PAGE_UP:t=!0,this._move("previousPage",i);break;case s.PAGE_DOWN:t=!0,this._move("nextPage",i);break;case s.UP:t=!0,this._keyEvent("previous",i);break;case s.DOWN:t=!0,this._keyEvent("next",i);break;case s.ENTER:case s.NUMPAD_ENTER:this.menu.active&&(t=!0,i.preventDefault(),this.menu.select(i));break;case s.TAB:this.menu.active&&this.menu.select(i);break;case s.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(i),i.preventDefault());break;default:n=!0,this._searchTimeout(i)}},keypress:function(r){if(t){t=!1,r.preventDefault();return}if(n)return;var i=e.ui.keyCode;switch(r.keyCode){case i.PAGE_UP:this._move("previousPage",r);break;case i.PAGE_DOWN:this._move("nextPage",r);break;case i.UP:this._keyEvent("previous",r);break;case i.DOWN:this._keyEvent("next",r)}},input:function(e){if(r){r=!1,e.preventDefault();return}this._searchTimeout(e)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}clearTimeout(this.searching),this.close(e),this._change(e)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete").appendTo(this.document.find(this.options.appendTo||"body")[0]).menu({input:e(),role:null}).zIndex(this.element.zIndex()+1).hide().data("menu"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var n=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(r){r.target!==t.element[0]&&r.target!==n&&!e.contains(n,r.target)&&t.close()})})},menufocus:function(t,n){if(this.isNewMenu){this.isNewMenu=!1;if(t.originalEvent&&/^mouse/.test(t.originalEvent.type)){this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)});return}}var r=n.item.data("ui-autocomplete-item")||n.item.data("item.autocomplete");!1!==this._trigger("focus",t,{item:r})?t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(r.value):this.liveRegion.text(r.value)},menuselect:function(e,t){var n=t.item.data("ui-autocomplete-item")||t.item.data("item.autocomplete"),r=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=r,this._delay(function(){this.previous=r,this.selectedItem=n})),!1!==this._trigger("select",e,{item:n})&&this._value(n.value),this.term=this._value(),this.close(e),this.selectedItem=n}}),this.liveRegion=e("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertAfter(this.element),e.fn.bgiframe&&this.menu.element.bgiframe(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),e==="source"&&this._initSource(),e==="appendTo"&&this.menu.element.appendTo(this.document.find(t||"body")[0]),e==="disabled"&&t&&this.xhr&&this.xhr.abort()},_isMultiLine:function(){return this.element.is("textarea")?!0:this.element.is("input")?!1:this.element.prop("isContentEditable")},_initSource:function(){var t,n,r=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(n,r){r(e.ui.autocomplete.filter(t,n.term))}):typeof this.options.source=="string"?(n=this.options.source,this.source=function(t,i){r.xhr&&r.xhr.abort(),r.xhr=e.ajax({url:n,data:t,dataType:"json",success:function(e){i(e)},error:function(){i([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){e=e!=null?e:this._value(),this.term=this._value();if(e.length<this.options.minLength)return this.close(t);if(this._trigger("search",t)===!1)return;return this._search(e)},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var e=this,t=++n;return function(r){t===n&&e.__response(r),e.pending--,e.pending||e.element.removeClass("ui-autocomplete-loading")}},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return typeof t=="string"?{label:t,value:t}:e.extend({label:t.label||t.value,value:t.value||t.label},t)})},_suggest:function(t){var n=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(n,t),this.menu.refresh(),n.show(),this._resizeMenu(),n.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,n){var r=this;e.each(n,function(e,n){r._renderItemData(t,n)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,n){return e("<li>").append(e("<a>").text(n.label)).appendTo(t)},_move:function(e,t){if(!this.menu.element.is(":visible")){this.search(null,t);return}if(this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)){this._value(this.term),this.menu.blur();return}this.menu[e](t)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){if(!this.isMultiLine||this.menu.element.is(":visible"))this._move(e,t),t.preventDefault()}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,n){var r=new RegExp(e.ui.autocomplete.escapeRegex(n),"i");return e.grep(t,function(e){return r.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var t;this._superApply(arguments);if(this.options.disabled||this.cancelSearch)return;e&&e.length?t=this.options.messages.results(e.length):t=this.options.messages.noResults,this.liveRegion.text(t)}})})(jQuery);(function(e,t){var n,r,i,s,o="ui-button ui-widget ui-state-default ui-corner-all",u="ui-state-hover ui-state-active ",a="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",f=function(){var t=e(this).find(":ui-button");setTimeout(function(){t.button("refresh")},1)},l=function(t){var n=t.name,r=t.form,i=e([]);return n&&(r?i=e(r).find("[name='"+n+"']"):i=e("[name='"+n+"']",t.ownerDocument).filter(function(){return!this.form})),i};e.widget("ui.button",{version:"1.9.2",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,f),typeof this.options.disabled!="boolean"?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var t=this,u=this.options,a=this.type==="checkbox"||this.type==="radio",c=a?"":"ui-state-active",h="ui-state-focus";u.label===null&&(u.label=this.type==="input"?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(o).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){if(u.disabled)return;this===n&&e(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){if(u.disabled)return;e(this).removeClass(c)}).bind("click"+this.eventNamespace,function(e){u.disabled&&(e.preventDefault(),e.stopImmediatePropagation())}),this.element.bind("focus"+this.eventNamespace,function(){t.buttonElement.addClass(h)}).bind("blur"+this.eventNamespace,function(){t.buttonElement.removeClass(h)}),a&&(this.element.bind("change"+this.eventNamespace,function(){if(s)return;t.refresh()}),this.buttonElement.bind("mousedown"+this.eventNamespace,function(e){if(u.disabled)return;s=!1,r=e.pageX,i=e.pageY}).bind("mouseup"+this.eventNamespace,function(e){if(u.disabled)return;if(r!==e.pageX||i!==e.pageY)s=!0})),this.type==="checkbox"?this.buttonElement.bind("click"+this.eventNamespace,function(){if(u.disabled||s)return!1;e(this).toggleClass("ui-state-active"),t.buttonElement.attr("aria-pressed",t.element[0].checked)}):this.type==="radio"?this.buttonElement.bind("click"+this.eventNamespace,function(){if(u.disabled||s)return!1;e(this).addClass("ui-state-active"),t.buttonElement.attr("aria-pressed","true");var n=t.element[0];l(n).not(n).map(function(){return e(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){if(u.disabled)return!1;e(this).addClass("ui-state-active"),n=this,t.document.one("mouseup",function(){n=null})}).bind("mouseup"+this.eventNamespace,function(){if(u.disabled)return!1;e(this).removeClass("ui-state-active")}).bind("keydown"+this.eventNamespace,function(t){if(u.disabled)return!1;(t.keyCode===e.ui.keyCode.SPACE||t.keyCode===e.ui.keyCode.ENTER)&&e(this).addClass("ui-state-active")}).bind("keyup"+this.eventNamespace,function(){e(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(t){t.keyCode===e.ui.keyCode.SPACE&&e(this).click()})),this._setOption("disabled",u.disabled),this._resetButton()},_determineButtonType:function(){var e,t,n;this.element.is("[type=checkbox]")?this.type="checkbox":this.element.is("[type=radio]")?this.type="radio":this.element.is("input")?this.type="input":this.type="button",this.type==="checkbox"||this.type==="radio"?(e=this.element.parents().last(),t="label[for='"+this.element.attr("id")+"']",this.buttonElement=e.find(t),this.buttonElement.length||(e=e.length?e.siblings():this.element.siblings(),this.buttonElement=e.filter(t),this.buttonElement.length||(this.buttonElement=e.find(t))),this.element.addClass("ui-helper-hidden-accessible"),n=this.element.is(":checked"),n&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",n)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(o+" "+u+" "+a).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(e,t){this._super(e,t);if(e==="disabled"){t?this.element.prop("disabled",!0):this.element.prop("disabled",!1);return}this._resetButton()},refresh:function(){var t=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOption("disabled",t),this.type==="radio"?l(this.element[0]).each(function(){e(this).is(":checked")?e(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):e(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):this.type==="checkbox"&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if(this.type==="input"){this.options.label&&this.element.val(this.options.label);return}var t=this.buttonElement.removeClass(a),n=e("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(t.empty()).text(),r=this.options.icons,i=r.primary&&r.secondary,s=[];r.primary||r.secondary?(this.options.text&&s.push("ui-button-text-icon"+(i?"s":r.primary?"-primary":"-secondary")),r.primary&&t.prepend("<span class='ui-button-icon-primary ui-icon "+r.primary+"'></span>"),r.secondary&&t.append("<span class='ui-button-icon-secondary ui-icon "+r.secondary+"'></span>"),this.options.text||(s.push(i?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||t.attr("title",e.trim(n)))):s.push("ui-button-text-only"),t.addClass(s.join(" "))}}),e.widget("ui.buttonset",{version:"1.9.2",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(e,t){e==="disabled"&&this.buttons.button("option",e,t),this._super(e,t)},refresh:function(){var t=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(t?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(t?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})})(jQuery);(function($,undefined){function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function bindHover(e){var t="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(t,"mouseout",function(){$(this).removeClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!=-1&&$(this).removeClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!=-1&&$(this).removeClass("ui-datepicker-next-hover")}).delegate(t,"mouseover",function(){$.datepicker._isDisabledDatepicker(instActive.inline?e.parent()[0]:instActive.input[0])||($(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),$(this).addClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!=-1&&$(this).addClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!=-1&&$(this).addClass("ui-datepicker-next-hover"))})}function extendRemove(e,t){$.extend(e,t);for(var n in t)if(t[n]==null||t[n]==undefined)e[n]=t[n];return e}$.extend($.ui,{datepicker:{version:"1.9.2"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return extendRemove(this._defaults,e||{}),this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(e,t){var n=e[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:n,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:t,dpDiv:t?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(e,t){var n=$(e);t.append=$([]),t.trigger=$([]);if(n.hasClass(this.markerClassName))return;this._attachments(n,t),n.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),this._autoSize(t),$.data(e,PROP_NAME,t),t.settings.disabled&&this._disableDatepicker(e)},_attachments:function(e,t){var n=this._get(t,"appendText"),r=this._get(t,"isRTL");t.append&&t.append.remove(),n&&(t.append=$('<span class="'+this._appendClass+'">'+n+"</span>"),e[r?"before":"after"](t.append)),e.unbind("focus",this._showDatepicker),t.trigger&&t.trigger.remove();var i=this._get(t,"showOn");(i=="focus"||i=="both")&&e.focus(this._showDatepicker);if(i=="button"||i=="both"){var s=this._get(t,"buttonText"),o=this._get(t,"buttonImage");t.trigger=$(this._get(t,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:o,alt:s,title:s}):$('<button type="button"></button>').addClass(this._triggerClass).html(o==""?s:$("<img/>").attr({src:o,alt:s,title:s}))),e[r?"before":"after"](t.trigger),t.trigger.click(function(){return $.datepicker._datepickerShowing&&$.datepicker._lastInput==e[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=e[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(e[0])):$.datepicker._showDatepicker(e[0]),!1})}},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t=new Date(2009,11,20),n=this._get(e,"dateFormat");if(n.match(/[DM]/)){var r=function(e){var t=0,n=0;for(var r=0;r<e.length;r++)e[r].length>t&&(t=e[r].length,n=r);return n};t.setMonth(r(this._get(e,n.match(/MM/)?"monthNames":"monthNamesShort"))),t.setDate(r(this._get(e,n.match(/DD/)?"dayNames":"dayNamesShort"))+20-t.getDay())}e.input.attr("size",this._formatDate(e,t).length)}},_inlineDatepicker:function(e,t){var n=$(e);if(n.hasClass(this.markerClassName))return;n.addClass(this.markerClassName).append(t.dpDiv).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),$.data(e,PROP_NAME,t),this._setDate(t,this._getDefaultDate(t),!0),this._updateDatepicker(t),this._updateAlternate(t),t.settings.disabled&&this._disableDatepicker(e),t.dpDiv.css("display","block")},_dialogDatepicker:function(e,t,n,r,i){var s=this._dialogInst;if(!s){this.uuid+=1;var o="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+o+'" style="position: absolute; top: -100px; width: 0px;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),s=this._dialogInst=this._newInst(this._dialogInput,!1),s.settings={},$.data(this._dialogInput[0],PROP_NAME,s)}extendRemove(s.settings,r||{}),t=t&&t.constructor==Date?this._formatDate(s,t):t,this._dialogInput.val(t),this._pos=i?i.length?i:[i.pageX,i.pageY]:null;if(!this._pos){var u=document.documentElement.clientWidth,a=document.documentElement.clientHeight,f=document.documentElement.scrollLeft||document.body.scrollLeft,l=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[u/2-100+f,a/2-150+l]}return this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),s.settings.onSelect=n,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,s),this},_destroyDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();$.removeData(e,PROP_NAME),r=="input"?(n.append.remove(),n.trigger.remove(),t.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(r=="div"||r=="span")&&t.removeClass(this.markerClassName).empty()},_enableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!1,n.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().removeClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t})},_disableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!0,n.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().addClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t}),this._disabledInputs[this._disabledInputs.length]=e},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;t<this._disabledInputs.length;t++)if(this._disabledInputs[t]==e)return!0;return!1},_getInst:function(e){try{return $.data(e,PROP_NAME)}catch(t){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(e,t,n){var r=this._getInst(e);if(arguments.length==2&&typeof t=="string")return t=="defaults"?$.extend({},$.datepicker._defaults):r?t=="all"?$.extend({},r.settings):this._get(r,t):null;var i=t||{};typeof t=="string"&&(i={},i[t]=n);if(r){this._curInst==r&&this._hideDatepicker();var s=this._getDateDatepicker(e,!0),o=this._getMinMaxDate(r,"min"),u=this._getMinMaxDate(r,"max");extendRemove(r.settings,i),o!==null&&i.dateFormat!==undefined&&i.minDate===undefined&&(r.settings.minDate=this._formatDate(r,o)),u!==null&&i.dateFormat!==undefined&&i.maxDate===undefined&&(r.settings.maxDate=this._formatDate(r,u)),this._attachments($(e),r),this._autoSize(r),this._setDate(r,s),this._updateAlternate(r),this._updateDatepicker(r)}},_changeDatepicker:function(e,t,n){this._optionDatepicker(e,t,n)},_refreshDatepicker:function(e){var t=this._getInst(e);t&&this._updateDatepicker(t)},_setDateDatepicker:function(e,t){var n=this._getInst(e);n&&(this._setDate(n,t),this._updateDatepicker(n),this._updateAlternate(n))},_getDateDatepicker:function(e,t){var n=this._getInst(e);return n&&!n.inline&&this._setDateFromField(n,t),n?this._getDate(n):null},_doKeyDown:function(e){var t=$.datepicker._getInst(e.target),n=!0,r=t.dpDiv.is(".ui-datepicker-rtl");t._keyEvent=!0;if($.datepicker._datepickerShowing)switch(e.keyCode){case 9:$.datepicker._hideDatepicker(),n=!1;break;case 13:var i=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",t.dpDiv);i[0]&&$.datepicker._selectDay(e.target,t.selectedMonth,t.selectedYear,i[0]);var s=$.datepicker._get(t,"onSelect");if(s){var o=$.datepicker._formatDate(t);s.apply(t.input?t.input[0]:null,[o,t])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(e.target,e.ctrlKey?-$.datepicker._get(t,"stepBigMonths"):-$.datepicker._get(t,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(e.target,e.ctrlKey?+$.datepicker._get(t,"stepBigMonths"):+$.datepicker._get(t,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&$.datepicker._clearDate(e.target),n=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&$.datepicker._gotoToday(e.target),n=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,r?1:-1,"D"),n=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&$.datepicker._adjustDate(e.target,e.ctrlKey?-$.datepicker._get(t,"stepBigMonths"):-$.datepicker._get(t,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,-7,"D"),n=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,r?-1:1,"D"),n=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&$.datepicker._adjustDate(e.target,e.ctrlKey?+$.datepicker._get(t,"stepBigMonths"):+$.datepicker._get(t,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&$.datepicker._adjustDate(e.target,7,"D"),n=e.ctrlKey||e.metaKey;break;default:n=!1}else e.keyCode==36&&e.ctrlKey?$.datepicker._showDatepicker(this):n=!1;n&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(e){var t=$.datepicker._getInst(e.target);if($.datepicker._get(t,"constrainInput")){var n=$.datepicker._possibleChars($.datepicker._get(t,"dateFormat")),r=String.fromCharCode(e.charCode==undefined?e.keyCode:e.charCode);return e.ctrlKey||e.metaKey||r<" "||!n||n.indexOf(r)>-1}},_doKeyUp:function(e){var t=$.datepicker._getInst(e.target);if(t.input.val()!=t.lastVal)try{var n=$.datepicker.parseDate($.datepicker._get(t,"dateFormat"),t.input?t.input.val():null,$.datepicker._getFormatConfig(t));n&&($.datepicker._setDateFromField(t),$.datepicker._updateAlternate(t),$.datepicker._updateDatepicker(t))}catch(r){$.datepicker.log(r)}return!0},_showDatepicker:function(e){e=e.target||e,e.nodeName.toLowerCase()!="input"&&(e=$("input",e.parentNode)[0]);if($.datepicker._isDisabledDatepicker(e)||$.datepicker._lastInput==e)return;var t=$.datepicker._getInst(e);$.datepicker._curInst&&$.datepicker._curInst!=t&&($.datepicker._curInst.dpDiv.stop(!0,!0),t&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var n=$.datepicker._get(t,"beforeShow"),r=n?n.apply(e,[e,t]):{};if(r===!1)return;extendRemove(t.settings,r),t.lastVal=null,$.datepicker._lastInput=e,$.datepicker._setDateFromField(t),$.datepicker._inDialog&&(e.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(e),$.datepicker._pos[1]+=e.offsetHeight);var i=!1;$(e).parents().each(function(){return i|=$(this).css("position")=="fixed",!i});var s={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,t.dpDiv.empty(),t.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(t),s=$.datepicker._checkOffset(t,s,i),t.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":i?"fixed":"absolute",display:"none",left:s.left+"px",top:s.top+"px"});if(!t.inline){var o=$.datepicker._get(t,"showAnim"),u=$.datepicker._get(t,"duration"),a=function(){var e=t.dpDiv.find("iframe.ui-datepicker-cover");if(!!e.length){var n=$.datepicker._getBorders(t.dpDiv);e.css({left:-n[0],top:-n[1],width:t.dpDiv.outerWidth(),height:t.dpDiv.outerHeight()})}};t.dpDiv.zIndex($(e).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&($.effects.effect[o]||$.effects[o])?t.dpDiv.show(o,$.datepicker._get(t,"showOptions"),u,a):t.dpDiv[o||"show"](o?u:null,a),(!o||!u)&&a(),t.input.is(":visible")&&!t.input.is(":disabled")&&t.input.focus(),$.datepicker._curInst=t}},_updateDatepicker:function(e){this.maxRows=4;var t=$.datepicker._getBorders(e.dpDiv);instActive=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var n=e.dpDiv.find("iframe.ui-datepicker-cover");!n.length||n.css({left:-t[0],top:-t[1],width:e.dpDiv.outerWidth(),height:e.dpDiv.outerHeight()}),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var r=this._getNumberOfMonths(e),i=r[1],s=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),i>1&&e.dpDiv.addClass("ui-datepicker-multi-"+i).css("width",s*i+"em"),e.dpDiv[(r[0]!=1||r[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e==$.datepicker._curInst&&$.datepicker._datepickerShowing&&e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&e.input[0]!=document.activeElement&&e.input.focus();if(e.yearshtml){var o=e.yearshtml;setTimeout(function(){o===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),o=e.yearshtml=null},0)}},_getBorders:function(e){var t=function(e){return{thin:1,medium:2,thick:3}[e]||e};return[parseFloat(t(e.css("border-left-width"))),parseFloat(t(e.css("border-top-width")))]},_checkOffset:function(e,t,n){var r=e.dpDiv.outerWidth(),i=e.dpDiv.outerHeight(),s=e.input?e.input.outerWidth():0,o=e.input?e.input.outerHeight():0,u=document.documentElement.clientWidth+(n?0:$(document).scrollLeft()),a=document.documentElement.clientHeight+(n?0:$(document).scrollTop());return t.left-=this._get(e,"isRTL")?r-s:0,t.left-=n&&t.left==e.input.offset().left?$(document).scrollLeft():0,t.top-=n&&t.top==e.input.offset().top+o?$(document).scrollTop():0,t.left-=Math.min(t.left,t.left+r>u&&u>r?Math.abs(t.left+r-u):0),t.top-=Math.min(t.top,t.top+i>a&&a>i?Math.abs(i+o):0),t},_findPos:function(e){var t=this._getInst(e),n=this._get(t,"isRTL");while(e&&(e.type=="hidden"||e.nodeType!=1||$.expr.filters.hidden(e)))e=e[n?"previousSibling":"nextSibling"];var r=$(e).offset();return[r.left,r.top]},_hideDatepicker:function(e){var t=this._curInst;if(!t||e&&t!=$.data(e,PROP_NAME))return;if(this._datepickerShowing){var n=this._get(t,"showAnim"),r=this._get(t,"duration"),i=function(){$.datepicker._tidyDialog(t)};$.effects&&($.effects.effect[n]||$.effects[n])?t.dpDiv.hide(n,$.datepicker._get(t,"showOptions"),r,i):t.dpDiv[n=="slideDown"?"slideUp":n=="fadeIn"?"fadeOut":"hide"](n?r:null,i),n||i(),this._datepickerShowing=!1;var s=this._get(t,"onClose");s&&s.apply(t.input?t.input[0]:null,[t.input?t.input.val():"",t]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(!$.datepicker._curInst)return;var t=$(e.target),n=$.datepicker._getInst(t[0]);(t[0].id!=$.datepicker._mainDivId&&t.parents("#"+$.datepicker._mainDivId).length==0&&!t.hasClass($.datepicker.markerClassName)&&!t.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||t.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=n)&&$.datepicker._hideDatepicker()},_adjustDate:function(e,t,n){var r=$(e),i=this._getInst(r[0]);if(this._isDisabledDatepicker(r[0]))return;this._adjustInstDate(i,t+(n=="M"?this._get(i,"showCurrentAtPos"):0),n),this._updateDatepicker(i)},_gotoToday:function(e){var t=$(e),n=this._getInst(t[0]);if(this._get(n,"gotoCurrent")&&n.currentDay)n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear;else{var r=new Date;n.selectedDay=r.getDate(),n.drawMonth=n.selectedMonth=r.getMonth(),n.drawYear=n.selectedYear=r.getFullYear()}this._notifyChange(n),this._adjustDate(t)},_selectMonthYear:function(e,t,n){var r=$(e),i=this._getInst(r[0]);i["selected"+(n=="M"?"Month":"Year")]=i["draw"+(n=="M"?"Month":"Year")]=parseInt(t.options[t.selectedIndex].value,10),this._notifyChange(i),this._adjustDate(r)},_selectDay:function(e,t,n,r){var i=$(e);if($(r).hasClass(this._unselectableClass)||this._isDisabledDatepicker(i[0]))return;var s=this._getInst(i[0]);s.selectedDay=s.currentDay=$("a",r).html(),s.selectedMonth=s.currentMonth=t,s.selectedYear=s.currentYear=n,this._selectDate(e,this._formatDate(s,s.currentDay,s.currentMonth,s.currentYear))},_clearDate:function(e){var t=$(e),n=this._getInst(t[0]);this._selectDate(t,"")},_selectDate:function(e,t){var n=$(e),r=this._getInst(n[0]);t=t!=null?t:this._formatDate(r),r.input&&r.input.val(t),this._updateAlternate(r);var i=this._get(r,"onSelect");i?i.apply(r.input?r.input[0]:null,[t,r]):r.input&&r.input.trigger("change"),r.inline?this._updateDatepicker(r):(this._hideDatepicker(),this._lastInput=r.input[0],typeof r.input[0]!="object"&&r.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var t=this._get(e,"altField");if(t){var n=this._get(e,"altFormat")||this._get(e,"dateFormat"),r=this._getDate(e),i=this.formatDate(n,r,this._getFormatConfig(e));$(t).each(function(){$(this).val(i)})}},noWeekends:function(e){var t=e.getDay();return[t>0&&t<6,""]},iso8601Week:function(e){var t=new Date(e.getTime());t.setDate(t.getDate()+4-(t.getDay()||7));var n=t.getTime();return t.setMonth(0),t.setDate(1),Math.floor(Math.round((n-t)/864e5)/7)+1},parseDate:function(e,t,n){if(e==null||t==null)throw"Invalid arguments";t=typeof t=="object"?t.toString():t+"";if(t=="")return null;var r=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff;r=typeof r!="string"?r:(new Date).getFullYear()%100+parseInt(r,10);var i=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,s=(n?n.dayNames:null)||this._defaults.dayNames,o=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,u=(n?n.monthNames:null)||this._defaults.monthNames,a=-1,f=-1,l=-1,c=-1,h=!1,p=function(t){var n=y+1<e.length&&e.charAt(y+1)==t;return n&&y++,n},d=function(e){var n=p(e),r=e=="@"?14:e=="!"?20:e=="y"&&n?4:e=="o"?3:2,i=new RegExp("^\\d{1,"+r+"}"),s=t.substring(g).match(i);if(!s)throw"Missing number at position "+g;return g+=s[0].length,parseInt(s[0],10)},v=function(e,n,r){var i=$.map(p(e)?r:n,function(e,t){return[[t,e]]}).sort(function(e,t){return-(e[1].length-t[1].length)}),s=-1;$.each(i,function(e,n){var r=n[1];if(t.substr(g,r.length).toLowerCase()==r.toLowerCase())return s=n[0],g+=r.length,!1});if(s!=-1)return s+1;throw"Unknown name at position "+g},m=function(){if(t.charAt(g)!=e.charAt(y))throw"Unexpected literal at position "+g;g++},g=0;for(var y=0;y<e.length;y++)if(h)e.charAt(y)=="'"&&!p("'")?h=!1:m();else switch(e.charAt(y)){case"d":l=d("d");break;case"D":v("D",i,s);break;case"o":c=d("o");break;case"m":f=d("m");break;case"M":f=v("M",o,u);break;case"y":a=d("y");break;case"@":var b=new Date(d("@"));a=b.getFullYear(),f=b.getMonth()+1,l=b.getDate();break;case"!":var b=new Date((d("!")-this._ticksTo1970)/1e4);a=b.getFullYear(),f=b.getMonth()+1,l=b.getDate();break;case"'":p("'")?m():h=!0;break;default:m()}if(g<t.length){var w=t.substr(g);if(!/^\s+/.test(w))throw"Extra/unparsed characters found in date: "+w}a==-1?a=(new Date).getFullYear():a<100&&(a+=(new Date).getFullYear()-(new Date).getFullYear()%100+(a<=r?0:-100));if(c>-1){f=1,l=c;do{var E=this._getDaysInMonth(a,f-1);if(l<=E)break;f++,l-=E}while(!0)}var b=this._daylightSavingAdjust(new Date(a,f-1,l));if(b.getFullYear()!=a||b.getMonth()+1!=f||b.getDate()!=l)throw"Invalid date";return b},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(e,t,n){if(!t)return"";var r=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,i=(n?n.dayNames:null)||this._defaults.dayNames,s=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,o=(n?n.monthNames:null)||this._defaults.monthNames,u=function(t){var n=h+1<e.length&&e.charAt(h+1)==t;return n&&h++,n},a=function(e,t,n){var r=""+t;if(u(e))while(r.length<n)r="0"+r;return r},f=function(e,t,n,r){return u(e)?r[t]:n[t]},l="",c=!1;if(t)for(var h=0;h<e.length;h++)if(c)e.charAt(h)=="'"&&!u("'")?c=!1:l+=e.charAt(h);else switch(e.charAt(h)){case"d":l+=a("d",t.getDate(),2);break;case"D":l+=f("D",t.getDay(),r,i);break;case"o":l+=a("o",Math.round(((new Date(t.getFullYear(),t.getMonth(),t.getDate())).getTime()-(new Date(t.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":l+=a("m",t.getMonth()+1,2);break;case"M":l+=f("M",t.getMonth(),s,o);break;case"y":l+=u("y")?t.getFullYear():(t.getYear()%100<10?"0":"")+t.getYear()%100;break;case"@":l+=t.getTime();break;case"!":l+=t.getTime()*1e4+this._ticksTo1970;break;case"'":u("'")?l+="'":c=!0;break;default:l+=e.charAt(h)}return l},_possibleChars:function(e){var t="",n=!1,r=function(t){var n=i+1<e.length&&e.charAt(i+1)==t;return n&&i++,n};for(var i=0;i<e.length;i++)if(n)e.charAt(i)=="'"&&!r("'")?n=!1:t+=e.charAt(i);else switch(e.charAt(i)){case"d":case"m":case"y":case"@":t+="0123456789";break;case"D":case"M":return null;case"'":r("'")?t+="'":n=!0;break;default:t+=e.charAt(i)}return t},_get:function(e,t){return e.settings[t]!==undefined?e.settings[t]:this._defaults[t]},_setDateFromField:function(e,t){if(e.input.val()==e.lastVal)return;var n=this._get(e,"dateFormat"),r=e.lastVal=e.input?e.input.val():null,i,s;i=s=this._getDefaultDate(e);var o=this._getFormatConfig(e);try{i=this.parseDate(n,r,o)||s}catch(u){this.log(u),r=t?"":r}e.selectedDay=i.getDate(),e.drawMonth=e.selectedMonth=i.getMonth(),e.drawYear=e.selectedYear=i.getFullYear(),e.currentDay=r?i.getDate():0,e.currentMonth=r?i.getMonth():0,e.currentYear=r?i.getFullYear():0,this._adjustInstDate(e)},_getDefaultDate:function(e){return this._restrictMinMax(e,this._determineDate(e,this._get(e,"defaultDate"),new Date))},_determineDate:function(e,t,n){var r=function(e){var t=new Date;return t.setDate(t.getDate()+e),t},i=function(t){try{return $.datepicker.parseDate($.datepicker._get(e,"dateFormat"),t,$.datepicker._getFormatConfig(e))}catch(n){}var r=(t.toLowerCase().match(/^c/)?$.datepicker._getDate(e):null)||new Date,i=r.getFullYear(),s=r.getMonth(),o=r.getDate(),u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,a=u.exec(t);while(a){switch(a[2]||"d"){case"d":case"D":o+=parseInt(a[1],10);break;case"w":case"W":o+=parseInt(a[1],10)*7;break;case"m":case"M":s+=parseInt(a[1],10),o=Math.min(o,$.datepicker._getDaysInMonth(i,s));break;case"y":case"Y":i+=parseInt(a[1],10),o=Math.min(o,$.datepicker._getDaysInMonth(i,s))}a=u.exec(t)}return new Date(i,s,o)},s=t==null||t===""?n:typeof t=="string"?i(t):typeof t=="number"?isNaN(t)?n:r(t):new Date(t.getTime());return s=s&&s.toString()=="Invalid Date"?n:s,s&&(s.setHours(0),s.setMinutes(0),s.setSeconds(0),s.setMilliseconds(0)),this._daylightSavingAdjust(s)},_daylightSavingAdjust:function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},_setDate:function(e,t,n){var r=!t,i=e.selectedMonth,s=e.selectedYear,o=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=o.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=o.getMonth(),e.drawYear=e.selectedYear=e.currentYear=o.getFullYear(),(i!=e.selectedMonth||s!=e.selectedYear)&&!n&&this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(r?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&e.input.val()==""?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(e){var t=this._get(e,"stepMonths"),n="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,-t,"M")},next:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,+t,"M")},hide:function(){window["DP_jQuery_"+dpuuid].datepicker._hideDatepicker()},today:function(){window["DP_jQuery_"+dpuuid].datepicker._gotoToday(n)},selectDay:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectDay(n,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"Y"),!1}};$(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t=new Date;t=this._daylightSavingAdjust(new Date(t.getFullYear(),t.getMonth(),t.getDate()));var n=this._get(e,"isRTL"),r=this._get(e,"showButtonPanel"),i=this._get(e,"hideIfNoPrevNext"),s=this._get(e,"navigationAsDateFormat"),o=this._getNumberOfMonths(e),u=this._get(e,"showCurrentAtPos"),a=this._get(e,"stepMonths"),f=o[0]!=1||o[1]!=1,l=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),c=this._getMinMaxDate(e,"min"),h=this._getMinMaxDate(e,"max"),p=e.drawMonth-u,d=e.drawYear;p<0&&(p+=12,d--);if(h){var v=this._daylightSavingAdjust(new Date(h.getFullYear(),h.getMonth()-o[0]*o[1]+1,h.getDate()));v=c&&v<c?c:v;while(this._daylightSavingAdjust(new Date(d,p,1))>v)p--,p<0&&(p=11,d--)}e.drawMonth=p,e.drawYear=d;var m=this._get(e,"prevText");m=s?this.formatDate(m,this._daylightSavingAdjust(new Date(d,p-a,1)),this._getFormatConfig(e)):m;var g=this._canAdjustMonth(e,-1,d,p)?'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click" title="'+m+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"e":"w")+'">'+m+"</span></a>":i?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+m+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"e":"w")+'">'+m+"</span></a>",y=this._get(e,"nextText");y=s?this.formatDate(y,this._daylightSavingAdjust(new Date(d,p+a,1)),this._getFormatConfig(e)):y;var b=this._canAdjustMonth(e,1,d,p)?'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click" title="'+y+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"w":"e")+'">'+y+"</span></a>":i?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+y+'"><span class="ui-icon ui-icon-circle-triangle-'+(n?"w":"e")+'">'+y+"</span></a>",w=this._get(e,"currentText"),E=this._get(e,"gotoCurrent")&&e.currentDay?l:t;w=s?this.formatDate(w,E,this._getFormatConfig(e)):w;var S=e.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">'+this._get(e,"closeText")+"</button>",x=r?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(n?S:"")+(this._isInRange(e,E)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click">'+w+"</button>":"")+(n?"":S)+"</div>":"",T=parseInt(this._get(e,"firstDay"),10);T=isNaN(T)?0:T;var N=this._get(e,"showWeek"),C=this._get(e,"dayNames"),k=this._get(e,"dayNamesShort"),L=this._get(e,"dayNamesMin"),A=this._get(e,"monthNames"),O=this._get(e,"monthNamesShort"),M=this._get(e,"beforeShowDay"),_=this._get(e,"showOtherMonths"),D=this._get(e,"selectOtherMonths"),P=this._get(e,"calculateWeek")||this.iso8601Week,H=this._getDefaultDate(e),B="";for(var j=0;j<o[0];j++){var F="";this.maxRows=4;for(var I=0;I<o[1];I++){var q=this._daylightSavingAdjust(new Date(d,p,e.selectedDay)),R=" ui-corner-all",U="";if(f){U+='<div class="ui-datepicker-group';if(o[1]>1)switch(I){case 0:U+=" ui-datepicker-group-first",R=" ui-corner-"+(n?"right":"left");break;case o[1]-1:U+=" ui-datepicker-group-last",R=" ui-corner-"+(n?"left":"right");break;default:U+=" ui-datepicker-group-middle",R=""}U+='">'}U+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+R+'">'+(/all|left/.test(R)&&j==0?n?b:g:"")+(/all|right/.test(R)&&j==0?n?g:b:"")+this._generateMonthYearHeader(e,p,d,c,h,j>0||I>0,A,O)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var z=N?'<th class="ui-datepicker-week-col">'+this._get(e,"weekHeader")+"</th>":"";for(var W=0;W<7;W++){var X=(W+T)%7;z+="<th"+((W+T+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+C[X]+'">'+L[X]+"</span></th>"}U+=z+"</tr></thead><tbody>";var V=this._getDaysInMonth(d,p);d==e.selectedYear&&p==e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,V));var J=(this._getFirstDayOfMonth(d,p)-T+7)%7,K=Math.ceil((J+V)/7),Q=f?this.maxRows>K?this.maxRows:K:K;this.maxRows=Q;var G=this._daylightSavingAdjust(new Date(d,p,1-J));for(var Y=0;Y<Q;Y++){U+="<tr>";var Z=N?'<td class="ui-datepicker-week-col">'+this._get(e,"calculateWeek")(G)+"</td>":"";for(var W=0;W<7;W++){var et=M?M.apply(e.input?e.input[0]:null,[G]):[!0,""],tt=G.getMonth()!=p,nt=tt&&!D||!et[0]||c&&G<c||h&&G>h;Z+='<td class="'+((W+T+6)%7>=5?" ui-datepicker-week-end":"")+(tt?" ui-datepicker-other-month":"")+(G.getTime()==q.getTime()&&p==e.selectedMonth&&e._keyEvent||H.getTime()==G.getTime()&&H.getTime()==q.getTime()?" "+this._dayOverClass:"")+(nt?" "+this._unselectableClass+" ui-state-disabled":"")+(tt&&!_?"":" "+et[1]+(G.getTime()==l.getTime()?" "+this._currentClass:"")+(G.getTime()==t.getTime()?" ui-datepicker-today":""))+'"'+((!tt||_)&&et[2]?' title="'+et[2]+'"':"")+(nt?"":' data-handler="selectDay" data-event="click" data-month="'+G.getMonth()+'" data-year="'+G.getFullYear()+'"')+">"+(tt&&!_?"&#xa0;":nt?'<span class="ui-state-default">'+G.getDate()+"</span>":'<a class="ui-state-default'+(G.getTime()==t.getTime()?" ui-state-highlight":"")+(G.getTime()==l.getTime()?" ui-state-active":"")+(tt?" ui-priority-secondary":"")+'" href="#">'+G.getDate()+"</a>")+"</td>",G.setDate(G.getDate()+1),G=this._daylightSavingAdjust(G)}U+=Z+"</tr>"}p++,p>11&&(p=0,d++),U+="</tbody></table>"+(f?"</div>"+(o[0]>0&&I==o[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),F+=U}B+=F}return B+=x+($.ui.ie6&&!e.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""),e._keyEvent=!1,B},_generateMonthYearHeader:function(e,t,n,r,i,s,o,u){var a=this._get(e,"changeMonth"),f=this._get(e,"changeYear"),l=this._get(e,"showMonthAfterYear"),c='<div class="ui-datepicker-title">',h="";if(s||!a)h+='<span class="ui-datepicker-month">'+o[t]+"</span>";else{var p=r&&r.getFullYear()==n,d=i&&i.getFullYear()==n;h+='<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';for(var v=0;v<12;v++)(!p||v>=r.getMonth())&&(!d||v<=i.getMonth())&&(h+='<option value="'+v+'"'+(v==t?' selected="selected"':"")+">"+u[v]+"</option>");h+="</select>"}l||(c+=h+(s||!a||!f?"&#xa0;":""));if(!e.yearshtml){e.yearshtml="";if(s||!f)c+='<span class="ui-datepicker-year">'+n+"</span>";else{var m=this._get(e,"yearRange").split(":"),g=(new Date).getFullYear(),y=function(e){var t=e.match(/c[+-].*/)?n+parseInt(e.substring(1),10):e.match(/[+-].*/)?g+parseInt(e,10):parseInt(e,10);return isNaN(t)?g:t},b=y(m[0]),w=Math.max(b,y(m[1]||""));b=r?Math.max(b,r.getFullYear()):b,w=i?Math.min(w,i.getFullYear()):w,e.yearshtml+='<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';for(;b<=w;b++)e.yearshtml+='<option value="'+b+'"'+(b==n?' selected="selected"':"")+">"+b+"</option>";e.yearshtml+="</select>",c+=e.yearshtml,e.yearshtml=null}}return c+=this._get(e,"yearSuffix"),l&&(c+=(s||!a||!f?"&#xa0;":"")+h),c+="</div>",c},_adjustInstDate:function(e,t,n){var r=e.drawYear+(n=="Y"?t:0),i=e.drawMonth+(n=="M"?t:0),s=Math.min(e.selectedDay,this._getDaysInMonth(r,i))+(n=="D"?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(r,i,s)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),(n=="M"||n=="Y")&&this._notifyChange(e)},_restrictMinMax:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max"),i=n&&t<n?n:t;return i=r&&i>r?r:i,i},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return t==null?[1,1]:typeof t=="number"?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return(new Date(e,t,1)).getDay()},_canAdjustMonth:function(e,t,n,r){var i=this._getNumberOfMonths(e),s=this._daylightSavingAdjust(new Date(n,r+(t<0?t:i[0]*i[1]),1));return t<0&&s.setDate(this._getDaysInMonth(s.getFullYear(),s.getMonth())),this._isInRange(e,s)},_isInRange:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max");return(!n||t.getTime()>=n.getTime())&&(!r||t.getTime()<=r.getTime())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t=typeof t!="string"?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,n,r){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var i=t?typeof t=="object"?t:this._daylightSavingAdjust(new Date(r,n,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),i,this._getFormatConfig(e))}}),$.fn.datepicker=function(e){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find(document.body).append($.datepicker.dpDiv),$.datepicker.initialized=!0);var t=Array.prototype.slice.call(arguments,1);return typeof e!="string"||e!="isDisabled"&&e!="getDate"&&e!="widget"?e=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t)):this.each(function(){typeof e=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this].concat(t)):$.datepicker._attachDatepicker(this,e)}):$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.9.2",window["DP_jQuery_"+dpuuid]=$})(jQuery);(function(e,t){var n="ui-dialog ui-widget ui-widget-content ui-corner-all ",r={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.9.2",options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var n=e(this).css(t).offset().top;n<0&&e(this).css("top",t.top-n)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.oldPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.options.title=this.options.title||this.originalTitle;var t=this,r=this.options,i=r.title||"&#160;",s,o,u,a,f;s=(this.uiDialog=e("<div>")).addClass(n+r.dialogClass).css({display:"none",outline:0,zIndex:r.zIndex}).attr("tabIndex",-1).keydown(function(n){r.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===e.ui.keyCode.ESCAPE&&(t.close(n),n.preventDefault())}).mousedown(function(e){t.moveToTop(!1,e)}).appendTo("body"),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(s),o=(this.uiDialogTitlebar=e("<div>")).addClass("ui-dialog-titlebar  ui-widget-header  ui-corner-all  ui-helper-clearfix").bind("mousedown",function(){s.focus()}).prependTo(s),u=e("<a href='#'></a>").addClass("ui-dialog-titlebar-close  ui-corner-all").attr("role","button").click(function(e){e.preventDefault(),t.close(e)}).appendTo(o),(this.uiDialogTitlebarCloseText=e("<span>")).addClass("ui-icon ui-icon-closethick").text(r.closeText).appendTo(u),a=e("<span>").uniqueId().addClass("ui-dialog-title").html(i).prependTo(o),f=(this.uiDialogButtonPane=e("<div>")).addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),(this.uiButtonSet=e("<div>")).addClass("ui-dialog-buttonset").appendTo(f),s.attr({role:"dialog","aria-labelledby":a.attr("id")}),o.find("*").add(o).disableSelection(),this._hoverable(u),this._focusable(u),r.draggable&&e.fn.draggable&&this._makeDraggable(),r.resizable&&e.fn.resizable&&this._makeResizable(),this._createButtons(r.buttons),this._isOpen=!1,e.fn.bgiframe&&s.bgiframe(),this._on(s,{keydown:function(t){if(!r.modal||t.keyCode!==e.ui.keyCode.TAB)return;var n=e(":tabbable",s),i=n.filter(":first"),o=n.filter(":last");if(t.target===o[0]&&!t.shiftKey)return i.focus(1),!1;if(t.target===i[0]&&t.shiftKey)return o.focus(1),!1}})},_init:function(){this.options.autoOpen&&this.open()},_destroy:function(){var e,t=this.oldPosition;this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},close:function(t){var n=this,r,i;if(!this._isOpen)return;if(!1===this._trigger("beforeClose",t))return;return this._isOpen=!1,this.overlay&&this.overlay.destroy(),this.options.hide?this._hide(this.uiDialog,this.options.hide,function(){n._trigger("close",t)}):(this.uiDialog.hide(),this._trigger("close",t)),e.ui.dialog.overlay.resize(),this.options.modal&&(r=0,e(".ui-dialog").each(function(){this!==n.uiDialog[0]&&(i=e(this).css("z-index"),isNaN(i)||(r=Math.max(r,i)))}),e.ui.dialog.maxZ=r),this},isOpen:function(){return this._isOpen},moveToTop:function(t,n){var r=this.options,i;return r.modal&&!t||!r.stack&&!r.modal?this._trigger("focus",n):(r.zIndex>e.ui.dialog.maxZ&&(e.ui.dialog.maxZ=r.zIndex),this.overlay&&(e.ui.dialog.maxZ+=1,e.ui.dialog.overlay.maxZ=e.ui.dialog.maxZ,this.overlay.$el.css("z-index",e.ui.dialog.overlay.maxZ)),i={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},e.ui.dialog.maxZ+=1,this.uiDialog.css("z-index",e.ui.dialog.maxZ),this.element.attr(i),this._trigger("focus",n),this)},open:function(){if(this._isOpen)return;var t,n=this.options,r=this.uiDialog;return this._size(),this._position(n.position),r.show(n.show),this.overlay=n.modal?new e.ui.dialog.overlay(this):null,this.moveToTop(!0),t=this.element.find(":tabbable"),t.length||(t=this.uiDialogButtonPane.find(":tabbable"),t.length||(t=r)),t.eq(0).focus(),this._isOpen=!0,this._trigger("open"),this},_createButtons:function(t){var n=this,r=!1;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),typeof t=="object"&&t!==null&&e.each(t,function(){return!(r=!0)}),r?(e.each(t,function(t,r){var i,s;r=e.isFunction(r)?{click:r,text:t}:r,r=e.extend({type:"button"},r),s=r.click,r.click=function(){s.apply(n.element[0],arguments)},i=e("<button></button>",r).appendTo(n.uiButtonSet),e.fn.button&&i.button()}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog)):this.uiDialog.removeClass("ui-dialog-buttons")},_makeDraggable:function(){function r(e){return{position:e.position,offset:e.offset}}var t=this,n=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(n,i){e(this).addClass("ui-dialog-dragging"),t._trigger("dragStart",n,r(i))},drag:function(e,n){t._trigger("drag",e,r(n))},stop:function(i,s){n.position=[s.position.left-t.document.scrollLeft(),s.position.top-t.document.scrollTop()],e(this).removeClass("ui-dialog-dragging"),t._trigger("dragStop",i,r(s)),e.ui.dialog.overlay.resize()}})},_makeResizable:function(n){function u(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}n=n===t?this.options.resizable:n;var r=this,i=this.options,s=this.uiDialog.css("position"),o=typeof n=="string"?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:i.maxWidth,maxHeight:i.maxHeight,minWidth:i.minWidth,minHeight:this._minHeight(),handles:o,start:function(t,n){e(this).addClass("ui-dialog-resizing"),r._trigger("resizeStart",t,u(n))},resize:function(e,t){r._trigger("resize",e,u(t))},stop:function(t,n){e(this).removeClass("ui-dialog-resizing"),i.height=e(this).height(),i.width=e(this).width(),r._trigger("resizeStop",t,u(n)),e.ui.dialog.overlay.resize()}}).css("position",s).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var e=this.options;return e.height==="auto"?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(t){var n=[],r=[0,0],i;if(t){if(typeof t=="string"||typeof t=="object"&&"0"in t)n=t.split?t.split(" "):[t[0],t[1]],n.length===1&&(n[1]=n[0]),e.each(["left","top"],function(e,t){+n[e]===n[e]&&(r[e]=n[e],n[e]=t)}),t={my:n[0]+(r[0]<0?r[0]:"+"+r[0])+" "+n[1]+(r[1]<0?r[1]:"+"+r[1]),at:n.join(" ")};t=e.extend({},e.ui.dialog.prototype.options.position,t)}else t=e.ui.dialog.prototype.options.position;i=this.uiDialog.is(":visible"),i||this.uiDialog.show(),this.uiDialog.position(t),i||this.uiDialog.hide()},_setOptions:function(t){var n=this,s={},o=!1;e.each(t,function(e,t){n._setOption(e,t),e in r&&(o=!0),e in i&&(s[e]=t)}),o&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",s)},_setOption:function(t,r){var i,s,o=this.uiDialog;switch(t){case"buttons":this._createButtons(r);break;case"closeText":this.uiDialogTitlebarCloseText.text(""+r);break;case"dialogClass":o.removeClass(this.options.dialogClass).addClass(n+r);break;case"disabled":r?o.addClass("ui-dialog-disabled"):o.removeClass("ui-dialog-disabled");break;case"draggable":i=o.is(":data(draggable)"),i&&!r&&o.draggable("destroy"),!i&&r&&this._makeDraggable();break;case"position":this._position(r);break;case"resizable":s=o.is(":data(resizable)"),s&&!r&&o.resizable("destroy"),s&&typeof r=="string"&&o.resizable("option","handles",r),!s&&r!==!1&&this._makeResizable(r);break;case"title":e(".ui-dialog-title",this.uiDialogTitlebar).html(""+(r||"&#160;"))}this._super(t,r)},_size:function(){var t,n,r,i=this.options,s=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),i.minWidth>i.width&&(i.width=i.minWidth),t=this.uiDialog.css({height:"auto",width:i.width}).outerHeight(),n=Math.max(0,i.minHeight-t),i.height==="auto"?e.support.minHeight?this.element.css({minHeight:n,height:"auto"}):(this.uiDialog.show(),r=this.element.css("height","auto").height(),s||this.uiDialog.hide(),this.element.height(Math.max(r,n))):this.element.height(Math.max(i.height-t,0)),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),e.extend(e.ui.dialog,{uuid:0,maxZ:0,getTitleId:function(e){var t=e.attr("id");return t||(this.uuid+=1,t=this.uuid),"ui-dialog-title-"+t},overlay:function(t){this.$el=e.ui.dialog.overlay.create(t)}}),e.extend(e.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:e.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(e){return e+".dialog-overlay"}).join(" "),create:function(t){this.instances.length===0&&(setTimeout(function(){e.ui.dialog.overlay.instances.length&&e(document).bind(e.ui.dialog.overlay.events,function(t){if(e(t.target).zIndex()<e.ui.dialog.overlay.maxZ)return!1})},1),e(window).bind("resize.dialog-overlay",e.ui.dialog.overlay.resize));var n=this.oldInstances.pop()||e("<div>").addClass("ui-widget-overlay");return e(document).bind("keydown.dialog-overlay",function(r){var i=e.ui.dialog.overlay.instances;i.length!==0&&i[i.length-1]===n&&t.options.closeOnEscape&&!r.isDefaultPrevented()&&r.keyCode&&r.keyCode===e.ui.keyCode.ESCAPE&&(t.close(r),r.preventDefault())}),n.appendTo(document.body).css({width:this.width(),height:this.height()}),e.fn.bgiframe&&n.bgiframe(),this.instances.push(n),n},destroy:function(t){var n=e.inArray(t,this.instances),r=0;n!==-1&&this.oldInstances.push(this.instances.splice(n,1)[0]),this.instances.length===0&&e([document,window]).unbind(".dialog-overlay"),t.height(0).width(0).remove(),e.each(this.instances,function(){r=Math.max(r,this.css("z-index"))}),this.maxZ=r},height:function(){var t,n;return e.ui.ie?(t=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),n=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),t<n?e(window).height()+"px":t+"px"):e(document).height()+"px"},width:function(){var t,n;return e.ui.ie?(t=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),n=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth),t<n?e(window).width()+"px":t+"px"):e(document).width()+"px"},resize:function(){var t=e([]);e.each(e.ui.dialog.overlay.instances,function(){t=t.add(this)}),t.css({width:0,height:0}).css({width:e.ui.dialog.overlay.width(),height:e.ui.dialog.overlay.height()})}}),e.extend(e.ui.dialog.overlay.prototype,{destroy:function(){e.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);(function(e,t){var n=!1;e.widget("ui.menu",{version:"1.9.2",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,e.proxy(function(e){this.options.disabled&&e.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(e){e.preventDefault()},"click .ui-state-disabled > a":function(e){e.preventDefault()},"click .ui-menu-item:has(a)":function(t){var r=e(t.target).closest(".ui-menu-item");!n&&r.not(".ui-state-disabled").length&&(n=!0,this.select(t),r.has(".ui-menu").length?this.expand(t):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&this.active.parents(".ui-menu").length===1&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var n=e(t.currentTarget);n.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(t,n)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var n=this.active||this.element.children(".ui-menu-item").eq(0);t||this.focus(e,n)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){e(t.target).closest(".ui-menu").length||this.collapseAll(t),n=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").andSelf().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){function a(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var n,r,i,s,o,u=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:u=!1,r=this.previousFilter||"",i=String.fromCharCode(t.keyCode),s=!1,clearTimeout(this.filterTimer),i===r?s=!0:i=r+i,o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())}),n=s&&n.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):n,n.length||(i=String.fromCharCode(t.keyCode),o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())})),n.length?(this.focus(t,n),n.length>1?(this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}u&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(e):this.select(e))},refresh:function(){var t,n=this.options.icons.submenu,r=this.element.find(this.options.menus);r.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),r=t.prev("a"),i=e("<span>").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);r.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",r.attr("id"))}),t=r.add(this.element),t.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),t.children(":not(.ui-menu-item)").each(function(){var t=e(this);/[^\-Ã¢â‚¬â€Ã¢â‚¬â€œ\s]/.test(t.text())||t.addClass("ui-widget-content ui-menu-divider")}),t.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},focus:function(e,t){var n,r;this.blur(e,e&&e.type==="focus"),this._scrollIntoView(t),this.active=t.first(),r=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",r.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),e&&e.type==="keydown"?this._close():this.timer=this._delay(function(){this._close()},this.delay),n=t.children(".ui-menu"),n.length&&/^mouse/.test(e.type)&&this._startOpening(n),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var n,r,i,s,o,u;this._hasScroll()&&(n=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,r=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,i=t.offset().top-this.activeMenu.offset().top-n-r,s=this.activeMenu.scrollTop(),o=this.activeMenu.height(),u=t.height(),i<0?this.activeMenu.scrollTop(s+i):i+u>o&&this.activeMenu.scrollTop(s+i-o+u))},blur:function(e,t){t||clearTimeout(this.timer);if(!this.active)return;this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active})},_startOpening:function(e){clearTimeout(this.timer);if(e.attr("aria-hidden")!=="true")return;this.timer=this._delay(function(){this._close(),this._open(e)},this.delay)},_open:function(t){var n=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(n)},collapseAll:function(t,n){clearTimeout(this.timer),this.timer=this._delay(function(){var r=n?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));r.length||(r=this.element),this._close(r),this.blur(t),this.activeMenu=r},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,n){var r;this.active&&(e==="first"||e==="last"?r=this.active[e==="first"?"prevAll":"nextAll"](".ui-menu-item").eq(-1):r=this.active[e+"All"](".ui-menu-item").eq(0));if(!r||!r.length||!this.active)r=this.activeMenu.children(".ui-menu-item")[t]();this.focus(n,r)},nextPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isLastItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r-i<0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())},previousPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isFirstItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r+i>0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item").first())},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||e(t.target).closest(".ui-menu-item");var n={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,n)}})})(jQuery);(function(e,t){e.widget("ui.progressbar",{version:"1.9.2",options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=e("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return e===t?this._value():(this._setOption("value",e),this)},_setOption:function(e,t){e==="value"&&(this.options.value=t,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),this._super(e,t)},_value:function(){var e=this.options.value;return typeof e!="number"&&(e=0),Math.min(this.options.max,Math.max(this.min,e))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var e=this.value(),t=this._percentage();this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),this.valueDiv.toggle(e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(t.toFixed(0)+"%"),this.element.attr("aria-valuenow",e)}})})(jQuery);(function(e,t){var n=5;e.widget("ui.slider",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var t,r,i=this.options,s=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),o="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",u=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(i.disabled?" ui-slider-disabled ui-disabled":"")),this.range=e([]),i.range&&(i.range===!0&&(i.values||(i.values=[this._valueMin(),this._valueMin()]),i.values.length&&i.values.length!==2&&(i.values=[i.values[0],i.values[0]])),this.range=e("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(i.range==="min"||i.range==="max"?" ui-slider-range-"+i.range:""))),r=i.values&&i.values.length||1;for(t=s.length;t<r;t++)u.push(o);this.handles=s.add(e(u.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(e){e.preventDefault()}).mouseenter(function(){i.disabled||e(this).addClass("ui-state-hover")}).mouseleave(function(){e(this).removeClass("ui-state-hover")}).focus(function(){i.disabled?e(this).blur():(e(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),e(this).addClass("ui-state-focus"))}).blur(function(){e(this).removeClass("ui-state-focus")}),this.handles.each(function(t){e(this).data("ui-slider-handle-index",t)}),this._on(this.handles,{keydown:function(t){var r,i,s,o,u=e(t.target).data("ui-slider-handle-index");switch(t.keyCode){case e.ui.keyCode.HOME:case e.ui.keyCode.END:case e.ui.keyCode.PAGE_UP:case e.ui.keyCode.PAGE_DOWN:case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:t.preventDefault();if(!this._keySliding){this._keySliding=!0,e(t.target).addClass("ui-state-active"),r=this._start(t,u);if(r===!1)return}}o=this.options.step,this.options.values&&this.options.values.length?i=s=this.values(u):i=s=this.value();switch(t.keyCode){case e.ui.keyCode.HOME:s=this._valueMin();break;case e.ui.keyCode.END:s=this._valueMax();break;case e.ui.keyCode.PAGE_UP:s=this._trimAlignValue(i+(this._valueMax()-this._valueMin())/n);break;case e.ui.keyCode.PAGE_DOWN:s=this._trimAlignValue(i-(this._valueMax()-this._valueMin())/n);break;case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:if(i===this._valueMax())return;s=this._trimAlignValue(i+o);break;case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(i===this._valueMin())return;s=this._trimAlignValue(i-o)}this._slide(t,u,s)},keyup:function(t){var n=e(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,n),this._change(t,n),e(t.target).removeClass("ui-state-active"))}}),this._refreshValue(),this._animateOff=!1},_destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(t){var n,r,i,s,o,u,a,f,l=this,c=this.options;return c.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),n={x:t.pageX,y:t.pageY},r=this._normValueFromMouse(n),i=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var n=Math.abs(r-l.values(t));i>n&&(i=n,s=e(this),o=t)}),c.range===!0&&this.values(1)===c.min&&(o+=1,s=e(this.handles[o])),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n<r)&&(n=r),n!==this.values(t)&&(i=this.values(),i[t]=n,s=this._trigger("slide",e,{handle:this.handles[t],value:n,values:i}),r=this.values(t?0:1),s!==!1&&this.values(t,n,!0))):n!==this.value()&&(s=this._trigger("slide",e,{handle:this.handles[t],value:n}),s!==!1&&this.value(n))},_stop:function(e,t){var n={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("stop",e,n)},_change:function(e,t){if(!this._keySliding&&!this._mouseSliding){var n={handle:this.handles[t],value:this.value()};this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("change",e,n)}},value:function(e){if(arguments.length){this.options.value=this._trimAlignValue(e),this._refreshValue(),this._change(null,0);return}return this._value()},values:function(t,n){var r,i,s;if(arguments.length>1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s<r.length;s+=1)r[s]=this._trimAlignValue(i[s]),this._change(null,s);this._refreshValue()},_setOption:function(t,n){var r,i=0;e.isArray(this.options.values)&&(i=this.options.values.length),e.Widget.prototype._setOption.apply(this,arguments);switch(t){case"disabled":n?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.prop("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.prop("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(r=0;r<i;r+=1)this._change(null,r);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1}},_value:function(){var e=this.options.value;return e=this._trimAlignValue(e),e},_values:function(e){var t,n,r;if(arguments.length)return t=this.options.values[e],t=this._trimAlignValue(t),t;n=this.options.values.slice();for(r=0;r<n.length;r+=1)n[r]=this._trimAlignValue(n[r]);return n},_trimAlignValue:function(e){if(e<=this._valueMin())return this._valueMin();if(e>=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))}})})(jQuery);(function(e){function t(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.widget("ui.spinner",{version:"1.9.2",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e<r.min?r.min:e},_stop:function(e){if(!this.spinning)return;clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",e)},_setOption:function(e,t){if(e==="culture"||e==="numberFormat"){var n=this._parse(this.element.val());this.options[e]=t,this.element.val(this._format(n));return}(e==="max"||e==="min"||e==="step")&&typeof t=="string"&&(t=this._parse(t)),this._super(e,t),e==="disabled"&&(t?(this.element.prop("disabled",!0),this.buttons.button("disable")):(this.element.prop("disabled",!1),this.buttons.button("enable")))},_setOptions:t(function(e){this._super(e),this._value(this.element.val())}),_parse:function(e){return typeof e=="string"&&e!==""&&(e=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(e,10,this.options.culture):+e),e===""||isNaN(e)?null:e},_format:function(e){return e===""?"":window.Globalize&&this.options.numberFormat?Globalize.format(e,this.options.numberFormat,this.options.culture):e},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},_value:function(e,t){var n;e!==""&&(n=this._parse(e),n!==null&&(t||(n=this._adjustValue(n)),e=this._format(n))),this.element.val(e),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:t(function(e){this._stepUp(e)}),_stepUp:function(e){this._spin((e||1)*this.options.step)},stepDown:t(function(e){this._stepDown(e)}),_stepDown:function(e){this._spin((e||1)*-this.options.step)},pageUp:t(function(e){this._stepUp((e||1)*this.options.page)}),pageDown:t(function(e){this._stepDown((e||1)*this.options.page)}),value:function(e){if(!arguments.length)return this._parse(this.element.val());t(this._value).call(this,e)},widget:function(){return this.uiSpinner}})})(jQuery);(function(e,t){function i(){return++n}function s(e){return e.hash.length>1&&e.href.replace(r,"")===location.href.replace(r,"").replace(/\s/g,"%20")}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.9.2",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t=this,n=this.options,r=n.active,i=location.hash.substring(1);this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",n.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs();if(r===null){i&&this.tabs.each(function(t,n){if(e(n).attr("aria-controls")===i)return r=t,!1}),r===null&&(r=this.tabs.index(this.tabs.filter(".ui-tabs-active")));if(r===null||r===-1)r=this.tabs.length?0:!1}r!==!1&&(r=this.tabs.index(this.tabs.eq(r)),r===-1&&(r=n.collapsible?!1:0)),n.active=r,!n.collapsible&&n.active===!1&&this.anchors.length&&(n.active=0),e.isArray(n.disabled)&&(n.disabled=e.unique(n.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(this.options.active):this.active=e(),this._refresh(),this.active.length&&this.load(n.active)},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,n=this.tablist.children(":has(a[href])");t.disabled=e.map(n.filter(".ui-state-disabled"),function(e){return n.index(e)}),this._processTabs(),t.active===!1||!this.anchors.length?(t.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("<div>").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r,i=this.element.parent();t==="fill"?(e.support.minHeight||(r=i.css("overflow"),i.css("overflow","hidden")),n=i.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),r&&i.css("overflow",r),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n):t.removeAttr("aria-controls")}),this.panels.show(),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}}),e.uiBackCompat!==!1&&(e.ui.tabs.prototype._ui=function(e,t){return{tab:e,panel:t,index:this.anchors.index(e)}},e.widget("ui.tabs",e.ui.tabs,{url:function(e,t){this.anchors.eq(e).attr("href",t)}}),e.widget("ui.tabs",e.ui.tabs,{options:{ajaxOptions:null,cache:!1},_create:function(){this._super();var t=this;this._on({tabsbeforeload:function(n,r){if(e.data(r.tab[0],"cache.tabs")){n.preventDefault();return}r.jqXHR.success(function(){t.options.cache&&e.data(r.tab[0],"cache.tabs",!0)})}})},_ajaxSettings:function(t,n,r){var i=this.options.ajaxOptions;return e.extend({},i,{error:function(e,t){try{i.error(e,t,r.tab.closest("li").index(),r.tab[0])}catch(n){}}},this._superApply(arguments))},_setOption:function(e,t){e==="cache"&&t===!1&&this.anchors.removeData("cache.tabs"),this._super(e,t)},_destroy:function(){this.anchors.removeData("cache.tabs"),this._super()},url:function(e){this.anchors.eq(e).removeData("cache.tabs"),this._superApply(arguments)}}),e.widget("ui.tabs",e.ui.tabs,{abort:function(){this.xhr&&this.xhr.abort()}}),e.widget("ui.tabs",e.ui.tabs,{options:{spinner:"<em>Loading&#8230;</em>"},_create:function(){this._super(),this._on({tabsbeforeload:function(e,t){if(e.target!==this.element[0]||!this.options.spinner)return;var n=t.tab.find("span"),r=n.html();n.html(this.options.spinner),t.jqXHR.complete(function(){n.html(r)})}})}}),e.widget("ui.tabs",e.ui.tabs,{options:{enable:null,disable:null},enable:function(t){var n=this.options,r;if(t&&n.disabled===!0||e.isArray(n.disabled)&&e.inArray(t,n.disabled)!==-1)r=!0;this._superApply(arguments),r&&this._trigger("enable",null,this._ui(this.anchors[t],this.panels[t]))},disable:function(t){var n=this.options,r;if(t&&n.disabled===!1||e.isArray(n.disabled)&&e.inArray(t,n.disabled)===-1)r=!0;this._superApply(arguments),r&&this._trigger("disable",null,this._ui(this.anchors[t],this.panels[t]))}}),e.widget("ui.tabs",e.ui.tabs,{options:{add:null,remove:null,tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},add:function(n,r,i){i===t&&(i=this.anchors.length);var s,o,u=this.options,a=e(u.tabTemplate.replace(/#\{href\}/g,n).replace(/#\{label\}/g,r)),f=n.indexOf("#")?this._tabId(a):n.replace("#","");return a.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",!0),a.attr("aria-controls",f),s=i>=this.tabs.length,o=this.element.find("#"+f),o.length||(o=this._createPanel(f),s?i>0?o.insertAfter(this.panels.eq(-1)):o.appendTo(this.element):o.insertBefore(this.panels[i])),o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(),s?a.appendTo(this.tablist):a.insertBefore(this.tabs[i]),u.disabled=e.map(u.disabled,function(e){return e>=i?++e:e}),this.refresh(),this.tabs.length===1&&u.active===!1&&this.option("active",0),this._trigger("add",null,this._ui(this.anchors[i],this.panels[i])),this},remove:function(t){t=this._getIndex(t);var n=this.options,r=this.tabs.eq(t).remove(),i=this._getPanelForTab(r).remove();return r.hasClass("ui-tabs-active")&&this.anchors.length>2&&this._activate(t+(t+1<this.anchors.length?1:-1)),n.disabled=e.map(e.grep(n.disabled,function(e){return e!==t}),function(e){return e>=t?--e:e}),this.refresh(),this._trigger("remove",null,this._ui(r.find("a")[0],i[0])),this}}),e.widget("ui.tabs",e.ui.tabs,{length:function(){return this.anchors.length}}),e.widget("ui.tabs",e.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(t){var n=t.is("li")?t.find("a[href]"):t;return n=n[0],e(n).closest("li").attr("aria-controls")||n.title&&n.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+i()}}),e.widget("ui.tabs",e.ui.tabs,{options:{panelTemplate:"<div></div>"},_createPanel:function(t){return e(this.options.panelTemplate).attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)}}),e.widget("ui.tabs",e.ui.tabs,{_create:function(){var e=this.options;e.active===null&&e.selected!==t&&(e.active=e.selected===-1?!1:e.selected),this._super(),e.selected=e.active,e.selected===!1&&(e.selected=-1)},_setOption:function(e,t){if(e!=="selected")return this._super(e,t);var n=this.options;this._super("active",t===-1?!1:t),n.selected=n.active,n.selected===!1&&(n.selected=-1)},_eventHandler:function(){this._superApply(arguments),this.options.selected=this.options.active,this.options.selected===!1&&(this.options.selected=-1)}}),e.widget("ui.tabs",e.ui.tabs,{options:{show:null,select:null},_create:function(){this._super(),this.options.active!==!1&&this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))},_trigger:function(e,t,n){var r,i,s=this._superApply(arguments);return s?(e==="beforeActivate"?(r=n.newTab.length?n.newTab:n.oldTab,i=n.newPanel.length?n.newPanel:n.oldPanel,s=this._super("select",t,{tab:r.find(".ui-tabs-anchor")[0],panel:i[0],index:r.closest("li").index()})):e==="activate"&&n.newTab.length&&(s=this._super("show",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()})),s):!1}}),e.widget("ui.tabs",e.ui.tabs,{select:function(e){e=this._getIndex(e);if(e===-1){if(!this.options.collapsible||this.options.selected===-1)return;e=this.options.selected}this.anchors.eq(e).trigger(this.options.event+this.eventNamespace)}}),function(){var t=0;e.widget("ui.tabs",e.ui.tabs,{options:{cookie:null},_create:function(){var e=this.options,t;e.active==null&&e.cookie&&(t=parseInt(this._cookie(),10),t===-1&&(t=!1),e.active=t),this._super()},_cookie:function(n){var r=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++t)];return arguments.length&&(r.push(n===!1?-1:n),r.push(this.options.cookie)),e.cookie.apply(null,r)},_refresh:function(){this._super(),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_eventHandler:function(){this._superApply(arguments),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super(),this.options.cookie&&this._cookie(null,this.options.cookie)}})}(),e.widget("ui.tabs",e.ui.tabs,{_trigger:function(t,n,r){var i=e.extend({},r);return t==="load"&&(i.panel=i.panel[0],i.tab=i.tab.find(".ui-tabs-anchor")[0]),this._super(t,n,i)}}),e.widget("ui.tabs",e.ui.tabs,{options:{fx:null},_getFx:function(){var t,n,r=this.options.fx;return r&&(e.isArray(r)?(t=r[0],n=r[1]):t=n=r),r?{show:n,hide:t}:null},_toggle:function(e,t){function o(){n.running=!1,n._trigger("activate",e,t)}function u(){t.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&s.show?r.animate(s.show,s.show.duration,function(){o()}):(r.show(),o())}var n=this,r=t.newPanel,i=t.oldPanel,s=this._getFx();if(!s)return this._super(e,t);n.running=!0,i.length&&s.hide?i.animate(s.hide,s.hide.duration,function(){t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),i.hide(),u())}}))})(jQuery);(function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.9.2",options:{content:function(){return e(this).attr("title")},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=this,r=e(t?t.target:this.element).closest(this.options.items);if(!r.length||r.data("ui-tooltip-id"))return;r.attr("title")&&r.data("ui-tooltip-title",r.attr("title")),r.data("ui-tooltip-open",!0),t&&t.type==="mouseover"&&r.parents().each(function(){var t=e(this),r;t.data("ui-tooltip-open")&&(r=e.Event("blur"),r.target=r.currentTarget=this,n.close(r,!0)),t.attr("title")&&(t.uniqueId(),n.parents[this.id]={element:this,title:t.attr("title")},t.attr("title",""))}),this._updateContent(r,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this,s=t?t.type:null;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("ui-tooltip-open"))return;i._delay(function(){t&&(t.type=s),this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function f(e){a.of=e;if(s.is(":hidden"))return;s.position(a)}var s,o,u,a=e.extend({},this.options.position);if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:f}),f(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this.options.show&&this.options.show.delay&&(u=setInterval(function(){s.is(":visible")&&(f(a.of),clearInterval(u))},e.fx.interval)),this._trigger("open",t,{tooltip:s}),o={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}},remove:function(){this._removeTooltip(s)}};if(!t||t.type==="mouseover")o.mouseleave="close";if(!t||t.type==="focusin")o.focusout="close";this._on(!0,r,o)},close:function(t){var n=this,i=e(t?t.currentTarget:this.element),s=this._find(i);if(this.closing)return;i.data("ui-tooltip-title")&&i.attr("title",i.data("ui-tooltip-title")),r(i),s.stop(!0),this._hide(s,this.options.hide,function(){n._removeTooltip(e(this))}),i.removeData("ui-tooltip-open"),this._off(i,"mouseleave focusout keyup"),i[0]!==this.element[0]&&this._off(i,"remove"),this._off(this.document,"mousemove"),t&&t.type==="mouseleave"&&e.each(this.parents,function(t,r){e(r.element).attr("title",r.title),delete n.parents[t]}),this.closing=!0,this._trigger("close",t,{tooltip:s}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("<div>").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("<div>").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),e.fn.bgiframe&&i.bgiframe(),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})})(jQuery);jQuery.effects||function(e,t){var n=e.uiBackCompat!==!1,r="ui-effects-";e.effects={effect:{}},function(t,n){function p(e,t,n){var r=a[t.type]||{};return e==null?n||!t.def?null:t.def:(e=r.floor?~~e:parseFloat(e),isNaN(e)?t.def:r.mod?(e+r.mod)%r.mod:0>e?0:r.max<e?r.max:e)}function d(e){var n=o(),r=n._rgba=[];return e=e.toLowerCase(),h(s,function(t,i){var s,o=i.re.exec(e),a=o&&i.parse(o),f=i.space||"rgba";if(a)return s=n[f](a),n[u[f].cache]=s[u[f].cache],r=n._rgba=s._rgba,!1}),r.length?(r.join()==="0,0,0,0"&&t.extend(r,c.transparent),n):c[e]}function v(e,t,n){return n=(n+1)%1,n*6<1?e+(t-e)*n*6:n*2<1?t:n*3<2?e+(t-e)*(2/3-n)*6:e}var r="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),i=/^([\-+])=\s*(\d+\.?\d*)/,s=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1],e[2],e[3],e[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(e){return[e[1]*2.55,e[2]*2.55,e[3]*2.55,e[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(e){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(e){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(e){return[e[1],e[2]/100,e[3]/100,e[4]]}}],o=t.Color=function(e,n,r,i){return new t.Color.fn.parse(e,n,r,i)},u={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},a={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},f=o.support={},l=t("<p>")[0],c,h=t.each;l.style.cssText="background-color:rgba(1,1,1,.5)",f.rgba=l.style.backgroundColor.indexOf("rgba")>-1,h(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),o.fn=t.extend(o.prototype,{parse:function(r,i,s,a){if(r===n)return this._rgba=[null,null,null,null],this;if(r.jquery||r.nodeType)r=t(r).css(i),i=n;var f=this,l=t.type(r),v=this._rgba=[];i!==n&&(r=[r,i,s,a],l="array");if(l==="string")return this.parse(d(r)||c._default);if(l==="array")return h(u.rgba.props,function(e,t){v[t.idx]=p(r[t.idx],t)}),this;if(l==="object")return r instanceof o?h(u,function(e,t){r[t.cache]&&(f[t.cache]=r[t.cache].slice())}):h(u,function(t,n){var i=n.cache;h(n.props,function(e,t){if(!f[i]&&n.to){if(e==="alpha"||r[e]==null)return;f[i]=n.to(f._rgba)}f[i][t.idx]=p(r[e],t,!0)}),f[i]&&e.inArray(null,f[i].slice(0,3))<0&&(f[i][3]=1,n.from&&(f._rgba=n.from(f[i])))}),this},is:function(e){var t=o(e),n=!0,r=this;return h(u,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],h(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return h(u,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=o(e),r=n._space(),i=u[r],s=this.alpha()===0?o("transparent"):this,f=s[i.cache]||i.to(s._rgba),l=f.slice();return n=n[i.cache],h(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],u=a[r.type]||{};if(o===null)return;s===null?l[i]=o:(u.mod&&(o-s>u.mod/2?s+=u.mod:s-o>u.mod/2&&(s-=u.mod)),l[i]=p((o-s)*t+s,r))}),this[r](l)},blend:function(e){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=o(e)._rgba;return o(t.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var e="rgba(",n=t.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),e="rgb("),e+n.join()+")"},toHslaString:function(){var e="hsla(",n=t.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),e="hsl("),e+n.join()+")"},toHexString:function(e){var n=this._rgba.slice(),r=n.pop();return e&&n.push(~~(r*255)),"#"+t.map(n,function(e){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),o.fn.parse.prototype=o.fn,u.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,f===0||f===1?c=f:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},u.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s;return[Math.round(v(o,s,t+1/3)*255),Math.round(v(o,s,t)*255),Math.round(v(o,s,t-1/3)*255),i]},h(u,function(e,r){var s=r.props,u=r.cache,a=r.to,f=r.from;o.fn[e]=function(e){a&&!this[u]&&(this[u]=a(this._rgba));if(e===n)return this[u].slice();var r,i=t.type(e),l=i==="array"||i==="object"?e:arguments,c=this[u].slice();return h(s,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=c[t.idx]),c[t.idx]=p(n,t)}),f?(r=o(f(c)),r[u]=c,r):o(c)},h(s,function(n,r){if(o.fn[n])return;o.fn[n]=function(s){var o=t.type(s),u=n==="alpha"?this._hsla?"hsla":"rgba":e,a=this[u](),f=a[r.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=t.type(s)),s==null&&r.empty?this:(o==="string"&&(l=i.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[r.idx]=s,this[u](a)))}})}),h(r,function(e,n){t.cssHooks[n]={set:function(e,r){var i,s,u="";if(t.type(r)!=="string"||(i=d(r))){r=o(i||r);if(!f.rgba&&r._rgba[3]!==1){s=n==="backgroundColor"?e.parentNode:e;while((u===""||u==="transparent")&&s&&s.style)try{u=t.css(s,"backgroundColor"),s=s.parentNode}catch(a){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{e.style[n]=r}catch(l){}}},t.fx.step[n]=function(e){e.colorInit||(e.start=o(e.elem,n),e.end=o(e.end),e.colorInit=!0),t.cssHooks[n].set(e.elem,e.start.transition(e.end,e.pos))}}),t.cssHooks.borderColor={expand:function(e){var t={};return h(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},c=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(){var t=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,n={},r,i;if(t&&t.length&&t[0]&&t[t[0]]){i=t.length;while(i--)r=t[i],typeof t[r]=="string"&&(n[e.camelCase(r)]=t[r])}else for(r in t)typeof t[r]=="string"&&(n[r]=t[r]);return n}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").andSelf():r;f=f.map(function(){var t=e(this);return{el:t,start:i.call(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i.call(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=jQuery.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass(t)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function i(t,n,r,i){e.isPlainObject(t)&&(n=t,t=t.effect),t={effect:t},n==null&&(n={}),e.isFunction(n)&&(i=n,r=null,n={});if(typeof n=="number"||e.fx.speeds[n])i=r,r=n,n={};return e.isFunction(r)&&(i=r,r=null),n&&e.extend(t,n),r=r||n.duration,t.duration=e.fx.off?0:typeof r=="number"?r:r in e.fx.speeds?e.fx.speeds[r]:e.fx.speeds._default,t.complete=i||n.complete,t}function s(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]?n&&e.effects[t]?!1:!0:!1}e.extend(e.effects,{version:"1.9.2",save:function(e,t){for(var n=0;n<t.length;n++)t[n]!==null&&e.data(r+t[n],e[0].style[t[n]])},restore:function(e,n){var i,s;for(s=0;s<n.length;s++)n[s]!==null&&(i=e.data(r+n[s]),i===t&&(i=""),e.css(n[s],i))},setMode:function(e,t){return t==="toggle"&&(t=e.is(":hidden")?"show":"hide"),t},getBaseline:function(e,t){var n,r;switch(e[0]){case"top":n=0;break;case"middle":n=.5;break;case"bottom":n=1;break;default:n=e[0]/t.height}switch(e[1]){case"left":r=0;break;case"center":r=.5;break;case"right":r=1;break;default:r=e[1]/t.width}return{x:r,y:n}},createWrapper:function(t){if(t.parent().is(".ui-effects-wrapper"))return t.parent();var n={width:t.outerWidth(!0),height:t.outerHeight(!0),"float":t.css("float")},r=e("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(){function a(n){function u(){e.isFunction(i)&&i.call(r[0]),e.isFunction(n)&&n()}var r=e(this),i=t.complete,s=t.mode;(r.is(":hidden")?s==="hide":s==="show")?u():o.call(r[0],t,u)}var t=i.apply(this,arguments),r=t.mode,s=t.queue,o=e.effects.effect[t.effect],u=!o&&n&&e.effects[t.effect];return e.fx.off||!o&&!u?r?this[r](t.duration,t.complete):this.each(function(){t.complete&&t.complete.call(this)}):o?s===!1?this.each(a):this.queue(s||"fx",a):u.call(this,{options:t,duration:t.duration,callback:t.complete,mode:t.mode})},_show:e.fn.show,show:function(e){if(s(e))return this._show.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(s(e))return this._hide.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(s(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=i.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery);(function(e,t){var n=/up|down|vertical/,r=/up|left|vertical|horizontal/;e.effects.effect.blind=function(t,i){var s=e(this),o=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(s,t.mode||"hide"),a=t.direction||"up",f=n.test(a),l=f?"height":"width",c=f?"top":"left",h=r.test(a),p={},d=u==="show",v,m,g;s.parent().is(".ui-effects-wrapper")?e.effects.save(s.parent(),o):e.effects.save(s,o),s.show(),v=e.effects.createWrapper(s).css({overflow:"hidden"}),m=v[l](),g=parseFloat(v.css(c))||0,p[l]=d?m:0,h||(s.css(f?"bottom":"right",0).css(f?"top":"left","auto").css({position:"absolute"}),p[c]=d?g:m+g),d&&(v.css(l,0),h||v.css(c,g+m)),v.animate(p,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){u==="hide"&&s.hide(),e.effects.restore(s,o),e.effects.removeWrapper(s),i()}})}})(jQuery);(function(e,t){e.effects.effect.bounce=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=s==="hide",u=s==="show",a=t.direction||"up",f=t.distance,l=t.times||5,c=l*2+(u||o?1:0),h=t.duration/c,p=t.easing,d=a==="up"||a==="down"?"top":"left",v=a==="up"||a==="left",m,g,y,b=r.queue(),w=b.length;(u||o)&&i.push("opacity"),e.effects.save(r,i),r.show(),e.effects.createWrapper(r),f||(f=r[d==="top"?"outerHeight":"outerWidth"]()/3),u&&(y={opacity:1},y[d]=0,r.css("opacity",0).css(d,v?-f*2:f*2).animate(y,h,p)),o&&(f/=Math.pow(2,l-1)),y={},y[d]=0;for(m=0;m<l;m++)g={},g[d]=(v?"-=":"+=")+f,r.animate(g,h,p).animate(y,h,p),f=o?f*2:f/2;o&&(g={opacity:0},g[d]=(v?"-=":"+=")+f,r.animate(g,h,p)),r.queue(function(){o&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}),w>1&&b.splice.apply(b,[1,0].concat(b.splice(w,c+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.clip=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"vertical",a=u==="vertical",f=a?"height":"width",l=a?"top":"left",c={},h,p,d;e.effects.save(r,i),r.show(),h=e.effects.createWrapper(r).css({overflow:"hidden"}),p=r[0].tagName==="IMG"?h:r,d=p[f](),o&&(p.css(f,0),p.css(l,d/2)),c[f]=o?d:0,c[l]=o?0:d/2,p.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o||r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.drop=function(t,n){var r=e(this),i=["position","top","bottom","left","right","opacity","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left"?"pos":"neg",l={opacity:o?1:0},c;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),c=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0)/2,o&&r.css("opacity",0).css(a,f==="pos"?-c:c),l[a]=(o?f==="pos"?"+=":"-=":f==="pos"?"-=":"+=")+c,r.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.explode=function(t,n){function y(){c.push(this),c.length===r*i&&b()}function b(){s.css({visibility:"visible"}),e(c).remove(),u||s.hide(),n()}var r=t.pieces?Math.round(Math.sqrt(t.pieces)):3,i=r,s=e(this),o=e.effects.setMode(s,t.mode||"hide"),u=o==="show",a=s.show().css("visibility","hidden").offset(),f=Math.ceil(s.outerWidth()/i),l=Math.ceil(s.outerHeight()/r),c=[],h,p,d,v,m,g;for(h=0;h<r;h++){v=a.top+h*l,g=h-(r-1)/2;for(p=0;p<i;p++)d=a.left+p*f,m=p-(i-1)/2,s.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-p*f,top:-h*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:f,height:l,left:d+(u?m*f:0),top:v+(u?g*l:0),opacity:u?0:1}).animate({left:d+(u?0:m*f),top:v+(u?0:g*l),opacity:u?1:0},t.duration||500,t.easing,y)}}})(jQuery);(function(e,t){e.effects.effect.fade=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"toggle");r.animate({opacity:i},{queue:!1,duration:t.duration,easing:t.easing,complete:n})}})(jQuery);(function(e,t){e.effects.effect.fold=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=s==="hide",a=t.size||15,f=/([0-9]+)%/.exec(a),l=!!t.horizFirst,c=o!==l,h=c?["width","height"]:["height","width"],p=t.duration/2,d,v,m={},g={};e.effects.save(r,i),r.show(),d=e.effects.createWrapper(r).css({overflow:"hidden"}),v=c?[d.width(),d.height()]:[d.height(),d.width()],f&&(a=parseInt(f[1],10)/100*v[u?0:1]),o&&d.css(l?{height:0,width:a}:{height:a,width:0}),m[h[0]]=o?v[0]:a,g[h[1]]=o?v[1]:0,d.animate(m,p,t.easing).animate(g,p,t.easing,function(){u&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()})}})(jQuery);(function(e,t){e.effects.effect.highlight=function(t,n){var r=e(this),i=["backgroundImage","backgroundColor","opacity"],s=e.effects.setMode(r,t.mode||"show"),o={backgroundColor:r.css("backgroundColor")};s==="hide"&&(o.opacity=0),e.effects.save(r,i),r.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),n()}})}})(jQuery);(function(e,t){e.effects.effect.pulsate=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"show"),s=i==="show",o=i==="hide",u=s||i==="hide",a=(t.times||5)*2+(u?1:0),f=t.duration/a,l=0,c=r.queue(),h=c.length,p;if(s||!r.is(":visible"))r.css("opacity",0).show(),l=1;for(p=1;p<a;p++)r.animate({opacity:l},f,t.easing),l=1-l;r.animate({opacity:l},f,t.easing),r.queue(function(){o&&r.hide(),n()}),h>1&&c.splice.apply(c,[1,0].concat(c.splice(h,a+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.puff=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"hide"),s=i==="hide",o=parseInt(t.percent,10)||150,u=o/100,a={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:i,complete:n,percent:s?o:100,from:s?a:{height:a.height*u,width:a.width*u,outerHeight:a.outerHeight*u,outerWidth:a.outerWidth*u}}),r.effect(t)},e.effects.effect.scale=function(t,n){var r=e(this),i=e.extend(!0,{},t),s=e.effects.setMode(r,t.mode||"effect"),o=parseInt(t.percent,10)||(parseInt(t.percent,10)===0?0:s==="hide"?0:100),u=t.direction||"both",a=t.origin,f={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},l={y:u!=="horizontal"?o/100:1,x:u!=="vertical"?o/100:1};i.effect="size",i.queue=!1,i.complete=n,s!=="effect"&&(i.origin=a||["middle","center"],i.restore=!0),i.from=t.from||(s==="show"?{height:0,width:0,outerHeight:0,outerWidth:0}:f),i.to={height:f.height*l.y,width:f.width*l.x,outerHeight:f.outerHeight*l.y,outerWidth:f.outerWidth*l.x},i.fade&&(s==="show"&&(i.from.opacity=0,i.to.opacity=1),s==="hide"&&(i.from.opacity=1,i.to.opacity=0)),r.effect(i)},e.effects.effect.size=function(t,n){var r,i,s,o=e(this),u=["position","top","bottom","left","right","width","height","overflow","opacity"],a=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],l=["fontSize"],c=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],h=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(o,t.mode||"effect"),d=t.restore||p!=="effect",v=t.scale||"both",m=t.origin||["middle","center"],g=o.css("position"),y=d?u:a,b={height:0,width:0,outerHeight:0,outerWidth:0};p==="show"&&o.show(),r={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},t.mode==="toggle"&&p==="show"?(o.from=t.to||b,o.to=t.from||r):(o.from=t.from||(p==="show"?b:r),o.to=t.to||(p==="hide"?b:r)),s={from:{y:o.from.height/r.height,x:o.from.width/r.width},to:{y:o.to.height/r.height,x:o.to.width/r.width}};if(v==="box"||v==="both")s.from.y!==s.to.y&&(y=y.concat(c),o.from=e.effects.setTransition(o,c,s.from.y,o.from),o.to=e.effects.setTransition(o,c,s.to.y,o.to)),s.from.x!==s.to.x&&(y=y.concat(h),o.from=e.effects.setTransition(o,h,s.from.x,o.from),o.to=e.effects.setTransition(o,h,s.to.x,o.to));(v==="content"||v==="both")&&s.from.y!==s.to.y&&(y=y.concat(l).concat(f),o.from=e.effects.setTransition(o,l,s.from.y,o.from),o.to=e.effects.setTransition(o,l,s.to.y,o.to)),e.effects.save(o,y),o.show(),e.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),m&&(i=e.effects.getBaseline(m,r),o.from.top=(r.outerHeight-o.outerHeight())*i.y,o.from.left=(r.outerWidth-o.outerWidth())*i.x,o.to.top=(r.outerHeight-o.to.outerHeight)*i.y,o.to.left=(r.outerWidth-o.to.outerWidth)*i.x),o.css(o.from);if(v==="content"||v==="both")c=c.concat(["marginTop","marginBottom"]).concat(l),h=h.concat(["marginLeft","marginRight"]),f=u.concat(c).concat(h),o.find("*[width]").each(function(){var n=e(this),r={height:n.height(),width:n.width(),outerHeight:n.outerHeight(),outerWidth:n.outerWidth()};d&&e.effects.save(n,f),n.from={height:r.height*s.from.y,width:r.width*s.from.x,outerHeight:r.outerHeight*s.from.y,outerWidth:r.outerWidth*s.from.x},n.to={height:r.height*s.to.y,width:r.width*s.to.x,outerHeight:r.height*s.to.y,outerWidth:r.width*s.to.x},s.from.y!==s.to.y&&(n.from=e.effects.setTransition(n,c,s.from.y,n.from),n.to=e.effects.setTransition(n,c,s.to.y,n.to)),s.from.x!==s.to.x&&(n.from=e.effects.setTransition(n,h,s.from.x,n.from),n.to=e.effects.setTransition(n,h,s.to.x,n.to)),n.css(n.from),n.animate(n.to,t.duration,t.easing,function(){d&&e.effects.restore(n,f)})});o.animate(o.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o.to.opacity===0&&o.css("opacity",o.from.opacity),p==="hide"&&o.hide(),e.effects.restore(o,y),d||(g==="static"?o.css({position:"relative",top:o.to.top,left:o.to.left}):e.each(["top","left"],function(e,t){o.css(t,function(t,n){var r=parseInt(n,10),i=e?o.to.left:o.to.top;return n==="auto"?i+"px":r+i+"px"})})),e.effects.removeWrapper(o),n()}})}})(jQuery);(function(e,t){e.effects.effect.shake=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=t.direction||"left",u=t.distance||20,a=t.times||3,f=a*2+1,l=Math.round(t.duration/f),c=o==="up"||o==="down"?"top":"left",h=o==="up"||o==="left",p={},d={},v={},m,g=r.queue(),y=g.length;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),p[c]=(h?"-=":"+=")+u,d[c]=(h?"+=":"-=")+u*2,v[c]=(h?"-=":"+=")+u*2,r.animate(p,l,t.easing);for(m=1;m<a;m++)r.animate(d,l,t.easing).animate(v,l,t.easing);r.animate(d,l,t.easing).animate(p,l/2,t.easing).queue(function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}),y>1&&g.splice.apply(g,[1,0].concat(g.splice(y,f+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.slide=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height"],s=e.effects.setMode(r,t.mode||"show"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left",l,c={};e.effects.save(r,i),r.show(),l=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(r).css({overflow:"hidden"}),o&&r.css(a,f?isNaN(l)?"-"+l:-l:l),c[a]=(o?f?"+=":"-=":f?"-=":"+=")+l,r.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.transfer=function(t,n){var r=e(this),i=e(t.to),s=i.css("position")==="fixed",o=e("body"),u=s?o.scrollTop():0,a=s?o.scrollLeft():0,f=i.offset(),l={top:f.top-u,left:f.left-a,height:i.innerHeight(),width:i.innerWidth()},c=r.offset(),h=e('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(t.className).css({top:c.top-u,left:c.left-a,height:r.innerHeight(),width:r.innerWidth(),position:s?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){h.remove(),n()})}})(jQuery);
+
+/* JQuery UJS 2.0.3 */
+(function(a,b){var c=function(){var b=a(document).data("events");return b&&b.click&&a.grep(b.click,function(a){return a.namespace==="rails"}).length};if(c()){a.error("jquery-ujs has already been loaded!")}var d;a.rails=d={linkClickSelector:"a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]",inputChangeSelector:"select[data-remote], input[data-remote], textarea[data-remote]",formSubmitSelector:"form",formInputClickSelector:"form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])",disableSelector:"input[data-disable-with], button[data-disable-with], textarea[data-disable-with]",enableSelector:"input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled",requiredInputSelector:"input[name][required]:not([disabled]),textarea[name][required]:not([disabled])",fileInputSelector:"input:file",linkDisableSelector:"a[data-disable-with]",CSRFProtection:function(b){var c=a('meta[name="csrf-token"]').attr("content");if(c)b.setRequestHeader("X-CSRF-Token",c)},fire:function(b,c,d){var e=a.Event(c);b.trigger(e,d);return e.result!==false},confirm:function(a){return confirm(a)},ajax:function(b){return a.ajax(b)},href:function(a){return a.attr("href")},handleRemote:function(c){var e,f,g,h,i,j,k,l;if(d.fire(c,"ajax:before")){h=c.data("cross-domain");i=h===b?null:h;j=c.data("with-credentials")||null;k=c.data("type")||a.ajaxSettings&&a.ajaxSettings.dataType;if(c.is("form")){e=c.attr("method");f=c.attr("action");g=c.serializeArray();var m=c.data("ujs:submit-button");if(m){g.push(m);c.data("ujs:submit-button",null)}}else if(c.is(d.inputChangeSelector)){e=c.data("method");f=c.data("url");g=c.serialize();if(c.data("params"))g=g+"&"+c.data("params")}else{e=c.data("method");f=d.href(c);g=c.data("params")||null}l={type:e||"GET",data:g,dataType:k,beforeSend:function(a,e){if(e.dataType===b){a.setRequestHeader("accept","*/*;q=0.5, "+e.accepts.script)}return d.fire(c,"ajax:beforeSend",[a,e])},success:function(a,b,d){c.trigger("ajax:success",[a,b,d])},complete:function(a,b){c.trigger("ajax:complete",[a,b])},error:function(a,b,d){c.trigger("ajax:error",[a,b,d])},xhrFields:{withCredentials:j},crossDomain:i};if(f){l.url=f}var n=d.ajax(l);c.trigger("ajax:send",n);return n}else{return false}},handleMethod:function(c){var e=d.href(c),f=c.data("method"),g=c.attr("target"),h=a("meta[name=csrf-token]").attr("content"),i=a("meta[name=csrf-param]").attr("content"),j=a('<form method="post" action="'+e+'"></form>'),k='<input name="_method" value="'+f+'" type="hidden" />';if(i!==b&&h!==b){k+='<input name="'+i+'" value="'+h+'" type="hidden" />'}if(g){j.attr("target",g)}j.hide().append(k).appendTo("body");j.submit()},disableFormElements:function(b){b.find(d.disableSelector).each(function(){var b=a(this),c=b.is("button")?"html":"val";b.data("ujs:enable-with",b[c]());b[c](b.data("disable-with"));b.prop("disabled",true)})},enableFormElements:function(b){b.find(d.enableSelector).each(function(){var b=a(this),c=b.is("button")?"html":"val";if(b.data("ujs:enable-with"))b[c](b.data("ujs:enable-with"));b.prop("disabled",false)})},allowAction:function(a){var b=a.data("confirm"),c=false,e;if(!b){return true}if(d.fire(a,"confirm")){c=d.confirm(b);e=d.fire(a,"confirm:complete",[c])}return c&&e},blankInputs:function(b,c,d){var e=a(),f,g,h=c||"input,textarea";b.find(h).each(function(){f=a(this);g=f.is(":checkbox,:radio")?f.is(":checked"):f.val();if(g==!!d){e=e.add(f)}});return e.length?e:false},nonBlankInputs:function(a,b){return d.blankInputs(a,b,true)},stopEverything:function(b){a(b.target).trigger("ujs:everythingStopped");b.stopImmediatePropagation();return false},callFormSubmitBindings:function(c,d){var e=c.data("events"),f=true;if(e!==b&&e["submit"]!==b){a.each(e["submit"],function(a,b){if(typeof b.handler==="function")return f=b.handler(d)})}return f},disableElement:function(a){a.data("ujs:enable-with",a.html());a.html(a.data("disable-with"));a.bind("click.railsDisable",function(a){return d.stopEverything(a)})},enableElement:function(a){if(a.data("ujs:enable-with")!==b){a.html(a.data("ujs:enable-with"));a.data("ujs:enable-with",false)}a.unbind("click.railsDisable")}};if(d.fire(a(document),"rails:attachBindings")){a.ajaxPrefilter(function(a,b,c){if(!a.crossDomain){d.CSRFProtection(c)}});a(document).delegate(d.linkDisableSelector,"ajax:complete",function(){d.enableElement(a(this))});a(document).delegate(d.linkClickSelector,"click.rails",function(c){var e=a(this),f=e.data("method"),g=e.data("params");if(!d.allowAction(e))return d.stopEverything(c);if(e.is(d.linkDisableSelector))d.disableElement(e);if(e.data("remote")!==b){if((c.metaKey||c.ctrlKey)&&(!f||f==="GET")&&!g){return true}if(d.handleRemote(e)===false){d.enableElement(e)}return false}else if(e.data("method")){d.handleMethod(e);return false}});a(document).delegate(d.inputChangeSelector,"change.rails",function(b){var c=a(this);if(!d.allowAction(c))return d.stopEverything(b);d.handleRemote(c);return false});a(document).delegate(d.formSubmitSelector,"submit.rails",function(c){var e=a(this),f=e.data("remote")!==b,g=d.blankInputs(e,d.requiredInputSelector),h=d.nonBlankInputs(e,d.fileInputSelector);if(!d.allowAction(e))return d.stopEverything(c);if(g&&e.attr("novalidate")==b&&d.fire(e,"ajax:aborted:required",[g])){return d.stopEverything(c)}if(f){if(h){setTimeout(function(){d.disableFormElements(e)},13);return d.fire(e,"ajax:aborted:file",[h])}if(!a.support.submitBubbles&&a().jquery<"1.7"&&d.callFormSubmitBindings(e,c)===false)return d.stopEverything(c);d.handleRemote(e);return false}else{setTimeout(function(){d.disableFormElements(e)},13)}});a(document).delegate(d.formInputClickSelector,"click.rails",function(b){var c=a(this);if(!d.allowAction(c))return d.stopEverything(b);var e=c.attr("name"),f=e?{name:e,value:c.val()}:null;c.closest("form").data("ujs:submit-button",f)});a(document).delegate(d.formSubmitSelector,"ajax:beforeSend.rails",function(b){if(this==b.target)d.disableFormElements(a(this))});a(document).delegate(d.formSubmitSelector,"ajax:complete.rails",function(b){if(this==b.target)d.enableFormElements(a(this))});a(function(){csrf_token=a("meta[name=csrf-token]").attr("content");csrf_param=a("meta[name=csrf-param]").attr("content");a('form input[name="'+csrf_param+'"]').val(csrf_token)})}})(jQuery)
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/jstoolbar/jstoolbar-textile.min.js
--- a/public/javascripts/jstoolbar/jstoolbar-textile.min.js
+++ b/public/javascripts/jstoolbar/jstoolbar-textile.min.js
@@ -1,1 +1,2 @@
-function jsToolBar(e){if(!document.createElement){return}if(!e){return}if(typeof document["selection"]=="undefined"&&typeof e["setSelectionRange"]=="undefined"){return}this.textarea=e;this.editor=document.createElement("div");this.editor.className="jstEditor";this.textarea.parentNode.insertBefore(this.editor,this.textarea);this.editor.appendChild(this.textarea);this.toolbar=document.createElement("div");this.toolbar.className="jstElements";this.editor.parentNode.insertBefore(this.toolbar,this.editor);if(this.editor.addEventListener&&navigator.appVersion.match(/\bMSIE\b/)){this.handle=document.createElement("div");this.handle.className="jstHandle";var t=this.resizeDragStart;var n=this;this.handle.addEventListener("mousedown",function(e){t.call(n,e)},false);window.addEventListener("unload",function(){var e=n.handle.parentNode.removeChild(n.handle);delete n.handle},false);this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling)}this.context=null;this.toolNodes={}}function jsButton(e,t,n,r){if(typeof jsToolBar.strings=="undefined"){this.title=e||null}else{this.title=jsToolBar.strings[e]||e||null}this.fn=t||function(){};this.scope=n||null;this.className=r||null}function jsSpace(e){this.id=e||null;this.width=null}function jsCombo(e,t,n,r,i){this.title=e||null;this.options=t||null;this.scope=n||null;this.fn=r||function(){};this.className=i||null}jsButton.prototype.draw=function(){if(!this.scope)return null;var e=document.createElement("button");e.setAttribute("type","button");e.tabIndex=200;if(this.className)e.className=this.className;e.title=this.title;var t=document.createElement("span");t.appendChild(document.createTextNode(this.title));e.appendChild(t);if(this.icon!=undefined){e.style.backgroundImage="url("+this.icon+")"}if(typeof this.fn=="function"){var n=this;e.onclick=function(){try{n.fn.apply(n.scope,arguments)}catch(e){}return false}}return e};jsSpace.prototype.draw=function(){var e=document.createElement("span");if(this.id)e.id=this.id;e.appendChild(document.createTextNode(String.fromCharCode(160)));e.className="jstSpacer";if(this.width)e.style.marginRight=this.width+"px";return e};jsCombo.prototype.draw=function(){if(!this.scope||!this.options)return null;var e=document.createElement("select");if(this.className)e.className=className;e.title=this.title;for(var t in this.options){var n=document.createElement("option");n.value=t;n.appendChild(document.createTextNode(this.options[t]));e.appendChild(n)}var r=this;e.onchange=function(){try{r.fn.call(r.scope,this.value)}catch(e){alert(e)}return false};return e};jsToolBar.prototype={base_url:"",mode:"wiki",elements:{},help_link:"",getMode:function(){return this.mode},setMode:function(e){this.mode=e||"wiki"},switchMode:function(e){e=e||"wiki";this.draw(e)},setHelpLink:function(e){this.help_link=e},button:function(e){var t=this.elements[e];if(typeof t.fn[this.mode]!="function")return null;var n=new jsButton(t.title,t.fn[this.mode],this,"jstb_"+e);if(t.icon!=undefined)n.icon=t.icon;return n},space:function(e){var t=new jsSpace(e);if(this.elements[e].width!==undefined)t.width=this.elements[e].width;return t},combo:function(e){var t=this.elements[e];var n=t[this.mode].list.length;if(typeof t[this.mode].fn!="function"||n==0){return null}else{var r={};for(var i=0;i<n;i++){var s=t[this.mode].list[i];r[s]=t.options[s]}return new jsCombo(t.title,r,this,t[this.mode].fn)}},draw:function(e){this.setMode(e);while(this.toolbar.hasChildNodes()){this.toolbar.removeChild(this.toolbar.firstChild)}this.toolNodes={};var t=document.createElement("div");t.className="help";t.innerHTML=this.help_link;"<a href=\"/help/wiki_syntax.html\" onclick=\"window.open('/help/wiki_syntax.html', '', 'resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes'); return false;\">Aide</a>";this.toolbar.appendChild(t);var n,r,i;for(var s in this.elements){n=this.elements[s];var o=n.type==undefined||n.type==""||n.disabled!=undefined&&n.disabled||n.context!=undefined&&n.context!=null&&n.context!=this.context;if(!o&&typeof this[n.type]=="function"){r=this[n.type](s);if(r)i=r.draw();if(i){this.toolNodes[s]=i;this.toolbar.appendChild(i)}}}},singleTag:function(e,t){e=e||null;t=t||e;if(!e||!t){return}this.encloseSelection(e,t)},encloseLineSelection:function(e,t,n){this.textarea.focus();e=e||"";t=t||"";var r,i,s,o,u,a;if(typeof document["selection"]!="undefined"){s=document.selection.createRange().text}else if(typeof this.textarea["setSelectionRange"]!="undefined"){r=this.textarea.selectionStart;i=this.textarea.selectionEnd;o=this.textarea.scrollTop;r=this.textarea.value.substring(0,r).replace(/[^\r\n]*$/g,"").length;i=this.textarea.value.length-this.textarea.value.substring(i,this.textarea.value.length).replace(/^[^\r\n]*/,"").length;s=this.textarea.value.substring(r,i)}if(s.match(/ $/)){s=s.substring(0,s.length-1);t=t+" "}if(typeof n=="function"){a=s?n.call(this,s):n("")}else{a=s?s:""}u=e+a+t;if(typeof document["selection"]!="undefined"){document.selection.createRange().text=u;var f=this.textarea.createTextRange();f.collapse(false);f.move("character",-t.length);f.select()}else if(typeof this.textarea["setSelectionRange"]!="undefined"){this.textarea.value=this.textarea.value.substring(0,r)+u+this.textarea.value.substring(i);if(s){this.textarea.setSelectionRange(r+u.length,r+u.length)}else{this.textarea.setSelectionRange(r+e.length,r+e.length)}this.textarea.scrollTop=o}},encloseSelection:function(e,t,n){this.textarea.focus();e=e||"";t=t||"";var r,i,s,o,u,a;if(typeof document["selection"]!="undefined"){s=document.selection.createRange().text}else if(typeof this.textarea["setSelectionRange"]!="undefined"){r=this.textarea.selectionStart;i=this.textarea.selectionEnd;o=this.textarea.scrollTop;s=this.textarea.value.substring(r,i)}if(s.match(/ $/)){s=s.substring(0,s.length-1);t=t+" "}if(typeof n=="function"){a=s?n.call(this,s):n("")}else{a=s?s:""}u=e+a+t;if(typeof document["selection"]!="undefined"){document.selection.createRange().text=u;var f=this.textarea.createTextRange();f.collapse(false);f.move("character",-t.length);f.select()}else if(typeof this.textarea["setSelectionRange"]!="undefined"){this.textarea.value=this.textarea.value.substring(0,r)+u+this.textarea.value.substring(i);if(s){this.textarea.setSelectionRange(r+u.length,r+u.length)}else{this.textarea.setSelectionRange(r+e.length,r+e.length)}this.textarea.scrollTop=o}},stripBaseURL:function(e){if(this.base_url!=""){var t=e.indexOf(this.base_url);if(t==0){e=e.substr(this.base_url.length)}}return e}};jsToolBar.prototype.resizeSetStartH=function(){this.dragStartH=this.textarea.offsetHeight+0};jsToolBar.prototype.resizeDragStart=function(e){var t=this;this.dragStartY=e.clientY;this.resizeSetStartH();document.addEventListener("mousemove",this.dragMoveHdlr=function(e){t.resizeDragMove(e)},false);document.addEventListener("mouseup",this.dragStopHdlr=function(e){t.resizeDragStop(e)},false)};jsToolBar.prototype.resizeDragMove=function(e){this.textarea.style.height=this.dragStartH+e.clientY-this.dragStartY+"px"};jsToolBar.prototype.resizeDragStop=function(e){document.removeEventListener("mousemove",this.dragMoveHdlr,false);document.removeEventListener("mouseup",this.dragStopHdlr,false)};jsToolBar.prototype.elements.strong={type:"button",title:"Strong",fn:{wiki:function(){this.singleTag("*")}}};jsToolBar.prototype.elements.em={type:"button",title:"Italic",fn:{wiki:function(){this.singleTag("_")}}};jsToolBar.prototype.elements.ins={type:"button",title:"Underline",fn:{wiki:function(){this.singleTag("+")}}};jsToolBar.prototype.elements.del={type:"button",title:"Deleted",fn:{wiki:function(){this.singleTag("-")}}};jsToolBar.prototype.elements.code={type:"button",title:"Code",fn:{wiki:function(){this.singleTag("@")}}};jsToolBar.prototype.elements.space1={type:"space"};jsToolBar.prototype.elements.h1={type:"button",title:"Heading 1",fn:{wiki:function(){this.encloseLineSelection("h1. ","",function(e){e=e.replace(/^h\d+\.\s+/,"");return e})}}};jsToolBar.prototype.elements.h2={type:"button",title:"Heading 2",fn:{wiki:function(){this.encloseLineSelection("h2. ","",function(e){e=e.replace(/^h\d+\.\s+/,"");return e})}}};jsToolBar.prototype.elements.h3={type:"button",title:"Heading 3",fn:{wiki:function(){this.encloseLineSelection("h3. ","",function(e){e=e.replace(/^h\d+\.\s+/,"");return e})}}};jsToolBar.prototype.elements.space2={type:"space"};jsToolBar.prototype.elements.ul={type:"button",title:"Unordered list",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^)[#-]?\s*/g,"$1* ")})}}};jsToolBar.prototype.elements.ol={type:"button",title:"Ordered list",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^)[*-]?\s*/g,"$1# ")})}}};jsToolBar.prototype.elements.space3={type:"space"};jsToolBar.prototype.elements.bq={type:"button",title:"Quote",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^) *([^\n]*)/g,"$1> $2")})}}};jsToolBar.prototype.elements.unbq={type:"button",title:"Unquote",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^) *[>]? *([^\n]*)/g,"$1$2")})}}};jsToolBar.prototype.elements.pre={type:"button",title:"Preformatted text",fn:{wiki:function(){this.encloseLineSelection("<pre>\n","\n</pre>")}}};jsToolBar.prototype.elements.space4={type:"space"};jsToolBar.prototype.elements.link={type:"button",title:"Wiki link",fn:{wiki:function(){this.encloseSelection("[[","]]")}}};jsToolBar.prototype.elements.img={type:"button",title:"Image",fn:{wiki:function(){this.encloseSelection("!","!")}}}
\ No newline at end of file
+function jsToolBar(e){if(!document.createElement){return}if(!e){return}if(typeof document["selection"]=="undefined"&&typeof e["setSelectionRange"]=="undefined"){return}this.textarea=e;this.editor=document.createElement("div");this.editor.className="jstEditor";this.textarea.parentNode.insertBefore(this.editor,this.textarea);this.editor.appendChild(this.textarea);this.toolbar=document.createElement("div");this.toolbar.className="jstElements";this.editor.parentNode.insertBefore(this.toolbar,this.editor);if(this.editor.addEventListener&&navigator.appVersion.match(/\bMSIE\b/)){this.handle=document.createElement("div");this.handle.className="jstHandle";var t=this.resizeDragStart;var n=this;this.handle.addEventListener("mousedown",function(e){t.call(n,e)},false);window.addEventListener("unload",function(){var e=n.handle.parentNode.removeChild(n.handle);delete n.handle},false);this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling)}this.context=null;this.toolNodes={}}function jsButton(e,t,n,r){if(typeof jsToolBar.strings=="undefined"){this.title=e||null}else{this.title=jsToolBar.strings[e]||e||null}this.fn=t||function(){};this.scope=n||null;this.className=r||null}function jsSpace(e){this.id=e||null;this.width=null}function jsCombo(e,t,n,r,i){this.title=e||null;this.options=t||null;this.scope=n||null;this.fn=r||function(){};this.className=i||null}jsButton.prototype.draw=function(){if(!this.scope)return null;var e=document.createElement("button");e.setAttribute("type","button");e.tabIndex=200;if(this.className)e.className=this.className;e.title=this.title;var t=document.createElement("span");t.appendChild(document.createTextNode(this.title));e.appendChild(t);if(this.icon!=undefined){e.style.backgroundImage="url("+this.icon+")"}if(typeof this.fn=="function"){var n=this;e.onclick=function(){try{n.fn.apply(n.scope,arguments)}catch(e){}return false}}return e};jsSpace.prototype.draw=function(){var e=document.createElement("span");if(this.id)e.id=this.id;e.appendChild(document.createTextNode(String.fromCharCode(160)));e.className="jstSpacer";if(this.width)e.style.marginRight=this.width+"px";return e};jsCombo.prototype.draw=function(){if(!this.scope||!this.options)return null;var e=document.createElement("select");if(this.className)e.className=className;e.title=this.title;for(var t in this.options){var n=document.createElement("option");n.value=t;n.appendChild(document.createTextNode(this.options[t]));e.appendChild(n)}var r=this;e.onchange=function(){try{r.fn.call(r.scope,this.value)}catch(e){alert(e)}return false};return e};jsToolBar.prototype={base_url:"",mode:"wiki",elements:{},help_link:"",getMode:function(){return this.mode},setMode:function(e){this.mode=e||"wiki"},switchMode:function(e){e=e||"wiki";this.draw(e)},setHelpLink:function(e){this.help_link=e},button:function(e){var t=this.elements[e];if(typeof t.fn[this.mode]!="function")return null;var n=new jsButton(t.title,t.fn[this.mode],this,"jstb_"+e);if(t.icon!=undefined)n.icon=t.icon;return n},space:function(e){var t=new jsSpace(e);if(this.elements[e].width!==undefined)t.width=this.elements[e].width;return t},combo:function(e){var t=this.elements[e];var n=t[this.mode].list.length;if(typeof t[this.mode].fn!="function"||n==0){return null}else{var r={};for(var i=0;i<n;i++){var s=t[this.mode].list[i];r[s]=t.options[s]}return new jsCombo(t.title,r,this,t[this.mode].fn)}},draw:function(e){this.setMode(e);while(this.toolbar.hasChildNodes()){this.toolbar.removeChild(this.toolbar.firstChild)}this.toolNodes={};var t,n,r;for(var i in this.elements){t=this.elements[i];var s=t.type==undefined||t.type==""||t.disabled!=undefined&&t.disabled||t.context!=undefined&&t.context!=null&&t.context!=this.context;if(!s&&typeof this[t.type]=="function"){n=this[t.type](i);if(n)r=n.draw();if(r){this.toolNodes[i]=r;this.toolbar.appendChild(r)}}}},singleTag:function(e,t){e=e||null;t=t||e;if(!e||!t){return}this.encloseSelection(e,t)},encloseLineSelection:function(e,t,n){this.textarea.focus();e=e||"";t=t||"";var r,i,s,o,u,a;if(typeof document["selection"]!="undefined"){s=document.selection.createRange().text}else if(typeof this.textarea["setSelectionRange"]!="undefined"){r=this.textarea.selectionStart;i=this.textarea.selectionEnd;o=this.textarea.scrollTop;r=this.textarea.value.substring(0,r).replace(/[^\r\n]*$/g,"").length;i=this.textarea.value.length-this.textarea.value.substring(i,this.textarea.value.length).replace(/^[^\r\n]*/,"").length;s=this.textarea.value.substring(r,i)}if(s.match(/ $/)){s=s.substring(0,s.length-1);t=t+" "}if(typeof n=="function"){a=s?n.call(this,s):n("")}else{a=s?s:""}u=e+a+t;if(typeof document["selection"]!="undefined"){document.selection.createRange().text=u;var f=this.textarea.createTextRange();f.collapse(false);f.move("character",-t.length);f.select()}else if(typeof this.textarea["setSelectionRange"]!="undefined"){this.textarea.value=this.textarea.value.substring(0,r)+u+this.textarea.value.substring(i);if(s){this.textarea.setSelectionRange(r+u.length,r+u.length)}else{this.textarea.setSelectionRange(r+e.length,r+e.length)}this.textarea.scrollTop=o}},encloseSelection:function(e,t,n){this.textarea.focus();e=e||"";t=t||"";var r,i,s,o,u,a;if(typeof document["selection"]!="undefined"){s=document.selection.createRange().text}else if(typeof this.textarea["setSelectionRange"]!="undefined"){r=this.textarea.selectionStart;i=this.textarea.selectionEnd;o=this.textarea.scrollTop;s=this.textarea.value.substring(r,i)}if(s.match(/ $/)){s=s.substring(0,s.length-1);t=t+" "}if(typeof n=="function"){a=s?n.call(this,s):n("")}else{a=s?s:""}u=e+a+t;if(typeof document["selection"]!="undefined"){document.selection.createRange().text=u;var f=this.textarea.createTextRange();f.collapse(false);f.move("character",-t.length);f.select()}else if(typeof this.textarea["setSelectionRange"]!="undefined"){this.textarea.value=this.textarea.value.substring(0,r)+u+this.textarea.value.substring(i);if(s){this.textarea.setSelectionRange(r+u.length,r+u.length)}else{this.textarea.setSelectionRange(r+e.length,r+e.length)}this.textarea.scrollTop=o}},stripBaseURL:function(e){if(this.base_url!=""){var t=e.indexOf(this.base_url);if(t==0){e=e.substr(this.base_url.length)}}return e}};jsToolBar.prototype.resizeSetStartH=function(){this.dragStartH=this.textarea.offsetHeight+0};jsToolBar.prototype.resizeDragStart=function(e){var t=this;this.dragStartY=e.clientY;this.resizeSetStartH();document.addEventListener("mousemove",this.dragMoveHdlr=function(e){t.resizeDragMove(e)},false);document.addEventListener("mouseup",this.dragStopHdlr=function(e){t.resizeDragStop(e)},false)};jsToolBar.prototype.resizeDragMove=function(e){this.textarea.style.height=this.dragStartH+e.clientY-this.dragStartY+"px"};jsToolBar.prototype.resizeDragStop=function(e){document.removeEventListener("mousemove",this.dragMoveHdlr,false);document.removeEventListener("mouseup",this.dragStopHdlr,false)};
+jsToolBar.prototype.elements.strong={type:"button",title:"Strong",fn:{wiki:function(){this.singleTag("*")}}};jsToolBar.prototype.elements.em={type:"button",title:"Italic",fn:{wiki:function(){this.singleTag("_")}}};jsToolBar.prototype.elements.ins={type:"button",title:"Underline",fn:{wiki:function(){this.singleTag("+")}}};jsToolBar.prototype.elements.del={type:"button",title:"Deleted",fn:{wiki:function(){this.singleTag("-")}}};jsToolBar.prototype.elements.code={type:"button",title:"Code",fn:{wiki:function(){this.singleTag("@")}}};jsToolBar.prototype.elements.space1={type:"space"};jsToolBar.prototype.elements.h1={type:"button",title:"Heading 1",fn:{wiki:function(){this.encloseLineSelection("h1. ","",function(e){e=e.replace(/^h\d+\.\s+/,"");return e})}}};jsToolBar.prototype.elements.h2={type:"button",title:"Heading 2",fn:{wiki:function(){this.encloseLineSelection("h2. ","",function(e){e=e.replace(/^h\d+\.\s+/,"");return e})}}};jsToolBar.prototype.elements.h3={type:"button",title:"Heading 3",fn:{wiki:function(){this.encloseLineSelection("h3. ","",function(e){e=e.replace(/^h\d+\.\s+/,"");return e})}}};jsToolBar.prototype.elements.space2={type:"space"};jsToolBar.prototype.elements.ul={type:"button",title:"Unordered list",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^)[#-]?\s*/g,"$1* ")})}}};jsToolBar.prototype.elements.ol={type:"button",title:"Ordered list",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^)[*-]?\s*/g,"$1# ")})}}};jsToolBar.prototype.elements.space3={type:"space"};jsToolBar.prototype.elements.bq={type:"button",title:"Quote",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^) *([^\n]*)/g,"$1> $2")})}}};jsToolBar.prototype.elements.unbq={type:"button",title:"Unquote",fn:{wiki:function(){this.encloseLineSelection("","",function(e){e=e.replace(/\r/g,"");return e.replace(/(\n|^) *[>]? *([^\n]*)/g,"$1$2")})}}};jsToolBar.prototype.elements.pre={type:"button",title:"Preformatted text",fn:{wiki:function(){this.encloseLineSelection("<pre>\n","\n</pre>")}}};jsToolBar.prototype.elements.space4={type:"space"};jsToolBar.prototype.elements.link={type:"button",title:"Wiki link",fn:{wiki:function(){this.encloseSelection("[[","]]")}}};jsToolBar.prototype.elements.img={type:"button",title:"Image",fn:{wiki:function(){this.encloseSelection("!","!")}}};jsToolBar.prototype.elements.space5={type:"space"};jsToolBar.prototype.elements.help={type:"button",title:"Help",fn:{wiki:function(){window.open(this.help_link,"","resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes")}}}
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/jstoolbar/jstoolbar.js
--- a/public/javascripts/jstoolbar/jstoolbar.js
+++ b/public/javascripts/jstoolbar/jstoolbar.js
@@ -207,12 +207,6 @@
 		}
 		this.toolNodes = {}; // vide les raccourcis DOM/**/
 
-		var h = document.createElement('div');
-		h.className = 'help'
-		h.innerHTML = this.help_link;
-		'<a href="/help/wiki_syntax.html" onclick="window.open(\'/help/wiki_syntax.html\', \'\', \'resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\'); return false;">Aide</a>';
-		this.toolbar.appendChild(h);
-
 		// Draw toolbar elements
 		var b, tool, newTool;
 		
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/jstoolbar/lang/jstoolbar-az.js
--- /dev/null
+++ b/public/javascripts/jstoolbar/lang/jstoolbar-az.js
@@ -0,0 +1,16 @@
+jsToolBar.strings = {};
+jsToolBar.strings['Strong'] = 'Strong';
+jsToolBar.strings['Italic'] = 'Italic';
+jsToolBar.strings['Underline'] = 'Underline';
+jsToolBar.strings['Deleted'] = 'Deleted';
+jsToolBar.strings['Code'] = 'Inline Code';
+jsToolBar.strings['Heading 1'] = 'Heading 1';
+jsToolBar.strings['Heading 2'] = 'Heading 2';
+jsToolBar.strings['Heading 3'] = 'Heading 3';
+jsToolBar.strings['Unordered list'] = 'Unordered list';
+jsToolBar.strings['Ordered list'] = 'Ordered list';
+jsToolBar.strings['Quote'] = 'Quote';
+jsToolBar.strings['Unquote'] = 'Remove Quote';
+jsToolBar.strings['Preformatted text'] = 'Preformatted text';
+jsToolBar.strings['Wiki link'] = 'Link to a Wiki page';
+jsToolBar.strings['Image'] = 'Image';
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/jstoolbar/lang/jstoolbar-lt.js
--- a/public/javascripts/jstoolbar/lang/jstoolbar-lt.js
+++ b/public/javascripts/jstoolbar/lang/jstoolbar-lt.js
@@ -9,8 +9,8 @@
 jsToolBar.strings['Heading 3'] = 'Heading 3';
 jsToolBar.strings['Unordered list'] = 'Nenumeruotas sÄ…raÅ¡as';
 jsToolBar.strings['Ordered list'] = 'Numeruotas sÄ…raÅ¡as';
-jsToolBar.strings['Quote'] = 'Quote';
-jsToolBar.strings['Unquote'] = 'Remove Quote';
+jsToolBar.strings['Quote'] = 'Cituoti';
+jsToolBar.strings['Unquote'] = 'PaÅ¡alinti citavimÄ…';
 jsToolBar.strings['Preformatted text'] = 'Preformatuotas tekstas';
 jsToolBar.strings['Wiki link'] = 'Nuoroda Ä¯ Wiki puslapÄ¯';
 jsToolBar.strings['Image'] = 'Paveikslas';
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/jstoolbar/textile.js
--- a/public/javascripts/jstoolbar/textile.js
+++ b/public/javascripts/jstoolbar/textile.js
@@ -198,3 +198,14 @@
 		wiki: function() { this.encloseSelection("!", "!") }
 	}
 }
+
+// spacer
+jsToolBar.prototype.elements.space5 = {type: 'space'}
+// help
+jsToolBar.prototype.elements.help = {
+	type: 'button',
+	title: 'Help',
+	fn: {
+		wiki: function() { window.open(this.help_link, '', 'resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes') }
+	}
+}
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/project_identifier.js
--- /dev/null
+++ b/public/javascripts/project_identifier.js
@@ -0,0 +1,78 @@
+// Automatic project identifier generation
+
+function generateProjectIdentifier(identifier, maxlength) {
+  var diacriticsMap = [
+    {'base':'a', 'letters':/[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g},
+    {'base':'aa','letters':/[\uA733\uA732]/g},
+    {'base':'ae','letters':/[\u00E4\u00E6\u01FD\u01E3\u00C4\u00C6\u01FC\u01E2]/g},
+    {'base':'ao','letters':/[\uA735\uA734]/g},
+    {'base':'au','letters':/[\uA737\uA736]/g},
+    {'base':'av','letters':/[\uA739\uA73B\uA738\uA73A]/g},
+    {'base':'ay','letters':/[\uA73D\uA73C]/g},
+    {'base':'b', 'letters':/[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g},
+    {'base':'c', 'letters':/[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g},
+    {'base':'d', 'letters':/[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g},
+    {'base':'dz','letters':/[\u01F3\u01C6\u01F1\u01C4\u01F2\u01C5]/g},
+    {'base':'e', 'letters':/[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g},
+    {'base':'f', 'letters':/[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g},
+    {'base':'g', 'letters':/[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g},
+    {'base':'h', 'letters':/[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g},
+    {'base':'hv','letters':/[\u0195]/g},
+    {'base':'i', 'letters':/[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g},
+    {'base':'j', 'letters':/[\u006A\u24D9\uFF4A\u0135\u01F0\u0249\u004A\u24BF\uFF2A\u0134\u0248]/g},
+    {'base':'k', 'letters':/[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g},
+    {'base':'l', 'letters':/[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g},
+    {'base':'lj','letters':/[\u01C9\u01C7\u01C8]/g},
+    {'base':'m', 'letters':/[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g},
+    {'base':'n', 'letters':/[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g},
+    {'base':'nj','letters':/[\u01CC\u01CA\u01CB]/g},
+    {'base':'o', 'letters':/[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g},
+    {'base':'oe','letters': /[\u00F6\u0153\u00D6\u0152]/g},
+    {'base':'oi','letters':/[\u01A3\u01A2]/g},
+    {'base':'ou','letters':/[\u0223\u0222]/g},
+    {'base':'oo','letters':/[\uA74F\uA74E]/g},
+    {'base':'p','letters':/[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g},
+    {'base':'q','letters':/[\u0071\u24E0\uFF51\u024B\uA757\uA759\u0051\u24C6\uFF31\uA756\uA758\u024A]/g},
+    {'base':'r','letters':/[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g},
+    {'base':'s','letters':/[\u0073\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g},
+    {'base':'ss','letters':/[\u00DF]/g},
+    {'base':'t','letters':/[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g},
+    {'base':'tz','letters':/[\uA729\uA728]/g},
+    {'base':'u','letters':/[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g},
+    {'base':'ue','letters':/[\u00FC\u00DC]/g},
+    {'base':'v','letters':/[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g},
+    {'base':'vy','letters':/[\uA761\uA760]/g},
+    {'base':'w','letters':/[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g},
+    {'base':'x','letters':/[\u0078\u24E7\uFF58\u1E8B\u1E8D\u0058\u24CD\uFF38\u1E8A\u1E8C]/g},
+    {'base':'y','letters':/[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g},
+    {'base':'z','letters':/[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g}
+  ];
+
+  for(var i=0; i<diacriticsMap.length; i++) {
+    identifier = identifier.replace(diacriticsMap[i].letters, diacriticsMap[i].base);
+  }
+  identifier = identifier.replace(/[^a-z0-9_]+/gi, '-'); // remaining non-alphanumeric => hyphen
+  identifier = identifier.replace(/^[-_\d]*|[-_]*$/g, ''); // remove hyphens/underscores and numbers at beginning and hyphens/underscores at end
+  identifier = identifier.toLowerCase(); // to lower
+  identifier = identifier.substr(0, maxlength); // max characters
+  return identifier;
+}
+
+function autoFillProjectIdentifier() {
+  var locked = ($('#project_identifier').val() != '');
+  var maxlength = parseInt($('#project_identifier').attr('maxlength'));
+
+  $('#project_name').keyup(function(){
+    if(!locked) {
+      $('#project_identifier').val(generateProjectIdentifier($('#project_name').val(), maxlength));
+    }
+  });
+
+  $('#project_identifier').keyup(function(){
+    locked = ($('#project_identifier').val() != '' && $('#project_identifier').val() != generateProjectIdentifier($('#project_name').val(), maxlength));
+  });
+}
+
+$(document).ready(function(){
+  autoFillProjectIdentifier();
+});
diff -r 0a574315af3e -r 4f746d8966dd public/javascripts/revision_graph.js
--- a/public/javascripts/revision_graph.js
+++ b/public/javascripts/revision_graph.js
@@ -43,7 +43,7 @@
         revisionGraph.circle(x, y, 3)
             .attr({
                 fill: colors[commit.space],
-                stroke: 'none',
+                stroke: 'none'
             }).toFront();
         // paths to parents
         $.each(commit.parent_scmids, function(index, parent_scmid) {
diff -r 0a574315af3e -r 4f746d8966dd public/stylesheets/application.css
--- a/public/stylesheets/application.css
+++ b/public/stylesheets/application.css
@@ -213,7 +213,7 @@
 tr.wiki-page-version td.updated_on, tr.wiki-page-version td.author {text-align:center;}
 
 tr.time-entry { text-align: center; white-space: nowrap; }
-tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; white-space: normal; }
+tr.time-entry td.issue, tr.time-entry td.comments { text-align: left; white-space: normal; }
 td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
 td.hours .hours-dec { font-size: 0.9em; }
 
@@ -275,7 +275,7 @@
 #watchers ul {margin: 0;  padding: 0;}
 #watchers li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;}
 #watchers select {width: 95%; display: block;}
-#watchers a.delete {opacity: 0.4;}
+#watchers a.delete {opacity: 0.4; vertical-align: middle;}
 #watchers a.delete:hover {opacity: 1;}
 #watchers img.gravatar {margin: 0 4px 2px 0;}
 
@@ -347,8 +347,8 @@
 #relations td.buttons {padding:0;}
 
 fieldset.collapsible { border-width: 1px 0 0 0; font-size: 0.9em; }
-fieldset.collapsible legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; }
-fieldset.collapsible.collapsed legend { background-image: url(../images/arrow_collapsed.png); }
+fieldset.collapsible>legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; }
+fieldset.collapsible.collapsed>legend { background-image: url(../images/arrow_collapsed.png); }
 
 fieldset#date-range p { margin: 2px 0 2px 0; }
 fieldset#filters table { border-collapse: collapse; }
@@ -383,6 +383,8 @@
 div#activity dd .description, #search-results dd .description { font-style: italic; }
 div#activity span.project:after, div#news span.project:after, #search-results span.project:after { content: " -"; }
 div#activity dd span.description, #search-results dd span.description { display:block; color: #808080; }
+div#activity dt.grouped {margin-left:5em;}
+div#activity dd.grouped {margin-left:9em;}
 
 div#members dl { margin-left: 2em; }
 div#members dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
@@ -496,10 +498,11 @@
 table.fields_permissions td.required {background:#d88;}
 
 textarea#custom_field_possible_values {width: 99%}
+textarea#custom_field_default_value {width: 99%}
+
 input#content_comments {width: 99%}
 
-.pagination {font-size: 90%}
-p.pagination {margin-top:8px;}
+p.pagination {margin-top:8px; font-size: 90%}
 
 /***** Tabular forms ******/
 .tabular p{
@@ -581,11 +584,18 @@
 span.required {color: #bb0000;}
 .summary {font-style: italic;}
 
-#attachments_fields input.description {margin-left: 8px; width:340px;}
+#attachments_fields input.description {margin-left:4px; width:340px;}
 #attachments_fields span {display:block; white-space:nowrap;}
 #attachments_fields input[type=text] {margin-left: 8px; }
 
-#attachments_fields img {vertical-align: middle;}
+#attachments_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../images/attachment.png) no-repeat 1px 50%; padding-left:18px;}
+#attachments_fields .ajax-waiting input.filename {background:url(../images/hourglass.png) no-repeat 0px 50%;}
+#attachments_fields .ajax-loading input.filename {background:url(../images/loading.gif) no-repeat 0px 50%;}
+#attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; }
+a.remove-upload {background: url(../images/delete.png) no-repeat 1px 50%; width:1px; display:inline-block; padding-left:16px;}
+a.remove-upload:hover {text-decoration:none !important;}
+
+div.fileover { background-color: lavender; }
 
 div.attachments { margin-top: 12px; }
 div.attachments p { margin:4px 0 2px 0; }
@@ -607,30 +617,30 @@
 
 textarea.text_cf {width:90%;}
 
-/* Project members tab */
-div#tab-content-members .splitcontentleft, div#tab-content-memberships .splitcontentleft, div#tab-content-users .splitcontentleft { width: 64% }
-div#tab-content-members .splitcontentright, div#tab-content-memberships .splitcontentright, div#tab-content-users .splitcontentright { width: 34% }
-div#tab-content-members fieldset, div#tab-content-memberships fieldset, div#tab-content-users fieldset { padding:1em; margin-bottom: 1em; }
-div#tab-content-members fieldset legend, div#tab-content-memberships fieldset legend, div#tab-content-users fieldset legend { font-weight: bold; }
-div#tab-content-members fieldset label, div#tab-content-memberships fieldset label, div#tab-content-users fieldset label { display: block; }
-div#tab-content-members fieldset div, div#tab-content-users fieldset div { max-height: 400px; overflow:auto; }
+#tab-content-modules fieldset p {margin:3px 0 4px 0;}
+
+#tab-content-members .splitcontentleft, #tab-content-memberships .splitcontentleft, #tab-content-users .splitcontentleft {width: 64%;}
+#tab-content-members .splitcontentright, #tab-content-memberships .splitcontentright, #tab-content-users .splitcontentright {width: 34%;}
+#tab-content-members fieldset, #tab-content-memberships fieldset, #tab-content-users fieldset {padding:1em; margin-bottom: 1em;}
+#tab-content-members fieldset legend, #tab-content-memberships fieldset legend, #tab-content-users fieldset legend {font-weight: bold;}
+#tab-content-members fieldset label, #tab-content-memberships fieldset label, #tab-content-users fieldset label {display: block;}
+#tab-content-members #principals, #tab-content-users #principals {max-height: 400px; overflow: auto;}
 
 #users_for_watcher {height: 200px; overflow:auto;}
 #users_for_watcher label {display: block;}
 
 table.members td.group { padding-left: 20px; background: url(../images/group.png) no-repeat 0% 50%; }
 
-input#principal_search, input#user_search {width:100%}
-input#principal_search, input#user_search {
-  background: url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px;
-  border:1px solid #9EB1C2; border-radius:3px; height:1.5em; width:95%;
+input#principal_search, input#user_search {width:90%}
+
+input.autocomplete {
+  background: #fff url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px;
+  border:1px solid #9EB1C2; border-radius:2px; height:1.5em;
 }
-input#principal_search.ajax-loading, input#user_search.ajax-loading {
+input.autocomplete.ajax-loading {
   background-image: url(../images/loading.gif);
 }
 
-* html div#tab-content-members fieldset div { height: 450px; }
-
 /***** Flash & error messages ****/
 #errorExplanation, div.flash, .nodata, .warning, .conflict {
   padding: 4px 4px 4px 30px;
@@ -752,7 +762,7 @@
 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
 table.progress td.done { background: #D3EDD3 none repeat scroll 0%; }
 table.progress td.todo { background: #eee none repeat scroll 0%; }
-p.pourcent {font-size: 80%;}
+p.percent {font-size: 80%;}
 p.progress-info {clear: left; font-size: 80%; margin-top:-4px; color:#777;}
 
 #roadmap table.progress td { height: 1.2em; }
@@ -1183,13 +1193,13 @@
 .syntaxhl .type { color:#339; font-weight:bold }
 .syntaxhl .value { color: #088; }
 .syntaxhl .variable  { color:#037 }
- 
+
 .syntaxhl .insert { background: hsla(120,100%,50%,0.12) }
 .syntaxhl .delete { background: hsla(0,100%,50%,0.12) }
 .syntaxhl .change { color: #bbf; background: #007; }
 .syntaxhl .head { color: #f8f; background: #505 }
 .syntaxhl .head .filename { color: white; }
- 
+
 .syntaxhl .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
 .syntaxhl .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
 
diff -r 0a574315af3e -r 4f746d8966dd public/stylesheets/jquery/images/ui-bg_gloss-wave_35_759fcf_500x100.png
Binary file public/stylesheets/jquery/images/ui-bg_gloss-wave_35_759fcf_500x100.png has changed
diff -r 0a574315af3e -r 4f746d8966dd public/stylesheets/jquery/jquery-ui-1.8.21.css
--- a/public/stylesheets/jquery/jquery-ui-1.8.21.css
+++ /dev/null
@@ -1,563 +0,0 @@
-/*!
- * jQuery UI CSS Framework 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Theming/API
- */
-
-/* Layout helpers
-----------------------------------*/
-.ui-helper-hidden { display: none; }
-.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
-.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
-.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
-.ui-helper-clearfix:after { clear: both; }
-.ui-helper-clearfix { zoom: 1; }
-.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
-
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-disabled { cursor: default !important; }
-
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Overlays */
-.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
-
-
-/*!
- * jQuery UI CSS Framework 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Theming/API
- *
- * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=759fcf&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=628db6&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=628db6&iconColorDefault=759fcf&bgColorHover=eef5fd&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=628db6&fcHover=628db6&iconColorHover=759fcf&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=628db6&fcActive=628db6&iconColorActive=759fcf&bgColorHighlight=759fcf&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=628db6&fcHighlight=363636&iconColorHighlight=759fcf&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
- */
-
-
-/* Component containers
-----------------------------------*/
-.ui-widget { font-family: Verdana, sans-serif; font-size: 1.1em; }
-.ui-widget .ui-widget { font-size: 1em; }
-.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana, sans-serif; font-size: 1em; }
-.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
-.ui-widget-content a { color: #333333; }
-.ui-widget-header { border: 1px solid #628db6; background: #759fcf url(images/ui-bg_gloss-wave_35_759fcf_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
-.ui-widget-header a { color: #ffffff; }
-
-/* Interaction states
-----------------------------------*/
-.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #628db6; }
-.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #628db6; text-decoration: none; }
-.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #628db6; background: #eef5fd url(images/ui-bg_glass_100_eef5fd_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #628db6; }
-.ui-state-hover a, .ui-state-hover a:hover { color: #628db6; text-decoration: none; }
-.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #628db6; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #628db6; }
-.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #628db6; text-decoration: none; }
-.ui-widget :active { outline: none; }
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  {border: 1px solid #628db6; background: #759fcf url(images/ui-bg_highlight-soft_75_759fcf_1x100.png) 50% top repeat-x; color: #363636; }
-.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
-.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
-.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
-.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
-.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
-.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
-.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
-.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
-.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
-.ui-state-default .ui-icon { background-image: url(images/ui-icons_759fcf_256x240.png); }
-.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_759fcf_256x240.png); }
-.ui-state-active .ui-icon {background-image: url(images/ui-icons_759fcf_256x240.png); }
-.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_759fcf_256x240.png); }
-.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
-
-/* positioning */
-.ui-icon-carat-1-n { background-position: 0 0; }
-.ui-icon-carat-1-ne { background-position: -16px 0; }
-.ui-icon-carat-1-e { background-position: -32px 0; }
-.ui-icon-carat-1-se { background-position: -48px 0; }
-.ui-icon-carat-1-s { background-position: -64px 0; }
-.ui-icon-carat-1-sw { background-position: -80px 0; }
-.ui-icon-carat-1-w { background-position: -96px 0; }
-.ui-icon-carat-1-nw { background-position: -112px 0; }
-.ui-icon-carat-2-n-s { background-position: -128px 0; }
-.ui-icon-carat-2-e-w { background-position: -144px 0; }
-.ui-icon-triangle-1-n { background-position: 0 -16px; }
-.ui-icon-triangle-1-ne { background-position: -16px -16px; }
-.ui-icon-triangle-1-e { background-position: -32px -16px; }
-.ui-icon-triangle-1-se { background-position: -48px -16px; }
-.ui-icon-triangle-1-s { background-position: -64px -16px; }
-.ui-icon-triangle-1-sw { background-position: -80px -16px; }
-.ui-icon-triangle-1-w { background-position: -96px -16px; }
-.ui-icon-triangle-1-nw { background-position: -112px -16px; }
-.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
-.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
-.ui-icon-arrow-1-n { background-position: 0 -32px; }
-.ui-icon-arrow-1-ne { background-position: -16px -32px; }
-.ui-icon-arrow-1-e { background-position: -32px -32px; }
-.ui-icon-arrow-1-se { background-position: -48px -32px; }
-.ui-icon-arrow-1-s { background-position: -64px -32px; }
-.ui-icon-arrow-1-sw { background-position: -80px -32px; }
-.ui-icon-arrow-1-w { background-position: -96px -32px; }
-.ui-icon-arrow-1-nw { background-position: -112px -32px; }
-.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
-.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
-.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
-.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
-.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
-.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
-.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
-.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
-.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
-.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
-.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
-.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
-.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
-.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
-.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
-.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
-.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
-.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
-.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
-.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
-.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
-.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
-.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
-.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
-.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
-.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
-.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
-.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
-.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
-.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
-.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
-.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
-.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
-.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
-.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
-.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
-.ui-icon-arrow-4 { background-position: 0 -80px; }
-.ui-icon-arrow-4-diag { background-position: -16px -80px; }
-.ui-icon-extlink { background-position: -32px -80px; }
-.ui-icon-newwin { background-position: -48px -80px; }
-.ui-icon-refresh { background-position: -64px -80px; }
-.ui-icon-shuffle { background-position: -80px -80px; }
-.ui-icon-transfer-e-w { background-position: -96px -80px; }
-.ui-icon-transferthick-e-w { background-position: -112px -80px; }
-.ui-icon-folder-collapsed { background-position: 0 -96px; }
-.ui-icon-folder-open { background-position: -16px -96px; }
-.ui-icon-document { background-position: -32px -96px; }
-.ui-icon-document-b { background-position: -48px -96px; }
-.ui-icon-note { background-position: -64px -96px; }
-.ui-icon-mail-closed { background-position: -80px -96px; }
-.ui-icon-mail-open { background-position: -96px -96px; }
-.ui-icon-suitcase { background-position: -112px -96px; }
-.ui-icon-comment { background-position: -128px -96px; }
-.ui-icon-person { background-position: -144px -96px; }
-.ui-icon-print { background-position: -160px -96px; }
-.ui-icon-trash { background-position: -176px -96px; }
-.ui-icon-locked { background-position: -192px -96px; }
-.ui-icon-unlocked { background-position: -208px -96px; }
-.ui-icon-bookmark { background-position: -224px -96px; }
-.ui-icon-tag { background-position: -240px -96px; }
-.ui-icon-home { background-position: 0 -112px; }
-.ui-icon-flag { background-position: -16px -112px; }
-.ui-icon-calendar { background-position: -32px -112px; }
-.ui-icon-cart { background-position: -48px -112px; }
-.ui-icon-pencil { background-position: -64px -112px; }
-.ui-icon-clock { background-position: -80px -112px; }
-.ui-icon-disk { background-position: -96px -112px; }
-.ui-icon-calculator { background-position: -112px -112px; }
-.ui-icon-zoomin { background-position: -128px -112px; }
-.ui-icon-zoomout { background-position: -144px -112px; }
-.ui-icon-search { background-position: -160px -112px; }
-.ui-icon-wrench { background-position: -176px -112px; }
-.ui-icon-gear { background-position: -192px -112px; }
-.ui-icon-heart { background-position: -208px -112px; }
-.ui-icon-star { background-position: -224px -112px; }
-.ui-icon-link { background-position: -240px -112px; }
-.ui-icon-cancel { background-position: 0 -128px; }
-.ui-icon-plus { background-position: -16px -128px; }
-.ui-icon-plusthick { background-position: -32px -128px; }
-.ui-icon-minus { background-position: -48px -128px; }
-.ui-icon-minusthick { background-position: -64px -128px; }
-.ui-icon-close { background-position: -80px -128px; }
-.ui-icon-closethick { background-position: -96px -128px; }
-.ui-icon-key { background-position: -112px -128px; }
-.ui-icon-lightbulb { background-position: -128px -128px; }
-.ui-icon-scissors { background-position: -144px -128px; }
-.ui-icon-clipboard { background-position: -160px -128px; }
-.ui-icon-copy { background-position: -176px -128px; }
-.ui-icon-contact { background-position: -192px -128px; }
-.ui-icon-image { background-position: -208px -128px; }
-.ui-icon-video { background-position: -224px -128px; }
-.ui-icon-script { background-position: -240px -128px; }
-.ui-icon-alert { background-position: 0 -144px; }
-.ui-icon-info { background-position: -16px -144px; }
-.ui-icon-notice { background-position: -32px -144px; }
-.ui-icon-help { background-position: -48px -144px; }
-.ui-icon-check { background-position: -64px -144px; }
-.ui-icon-bullet { background-position: -80px -144px; }
-.ui-icon-radio-off { background-position: -96px -144px; }
-.ui-icon-radio-on { background-position: -112px -144px; }
-.ui-icon-pin-w { background-position: -128px -144px; }
-.ui-icon-pin-s { background-position: -144px -144px; }
-.ui-icon-play { background-position: 0 -160px; }
-.ui-icon-pause { background-position: -16px -160px; }
-.ui-icon-seek-next { background-position: -32px -160px; }
-.ui-icon-seek-prev { background-position: -48px -160px; }
-.ui-icon-seek-end { background-position: -64px -160px; }
-.ui-icon-seek-start { background-position: -80px -160px; }
-/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
-.ui-icon-seek-first { background-position: -80px -160px; }
-.ui-icon-stop { background-position: -96px -160px; }
-.ui-icon-eject { background-position: -112px -160px; }
-.ui-icon-volume-off { background-position: -128px -160px; }
-.ui-icon-volume-on { background-position: -144px -160px; }
-.ui-icon-power { background-position: 0 -176px; }
-.ui-icon-signal-diag { background-position: -16px -176px; }
-.ui-icon-signal { background-position: -32px -176px; }
-.ui-icon-battery-0 { background-position: -48px -176px; }
-.ui-icon-battery-1 { background-position: -64px -176px; }
-.ui-icon-battery-2 { background-position: -80px -176px; }
-.ui-icon-battery-3 { background-position: -96px -176px; }
-.ui-icon-circle-plus { background-position: 0 -192px; }
-.ui-icon-circle-minus { background-position: -16px -192px; }
-.ui-icon-circle-close { background-position: -32px -192px; }
-.ui-icon-circle-triangle-e { background-position: -48px -192px; }
-.ui-icon-circle-triangle-s { background-position: -64px -192px; }
-.ui-icon-circle-triangle-w { background-position: -80px -192px; }
-.ui-icon-circle-triangle-n { background-position: -96px -192px; }
-.ui-icon-circle-arrow-e { background-position: -112px -192px; }
-.ui-icon-circle-arrow-s { background-position: -128px -192px; }
-.ui-icon-circle-arrow-w { background-position: -144px -192px; }
-.ui-icon-circle-arrow-n { background-position: -160px -192px; }
-.ui-icon-circle-zoomin { background-position: -176px -192px; }
-.ui-icon-circle-zoomout { background-position: -192px -192px; }
-.ui-icon-circle-check { background-position: -208px -192px; }
-.ui-icon-circlesmall-plus { background-position: 0 -208px; }
-.ui-icon-circlesmall-minus { background-position: -16px -208px; }
-.ui-icon-circlesmall-close { background-position: -32px -208px; }
-.ui-icon-squaresmall-plus { background-position: -48px -208px; }
-.ui-icon-squaresmall-minus { background-position: -64px -208px; }
-.ui-icon-squaresmall-close { background-position: -80px -208px; }
-.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
-.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
-.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
-.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
-.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
-.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Corner radius */
-.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
-.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
-.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
-.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
-
-/* Overlays */
-.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
-.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*!
- * jQuery UI Resizable 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Resizable#theming
- */
-.ui-resizable { position: relative;}
-.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
-.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
-.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
-.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
-.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
-.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
-.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
-.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
-.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
-.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*!
- * jQuery UI Selectable 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Selectable#theming
- */
-.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
-/*!
- * jQuery UI Accordion 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Accordion#theming
- */
-/* IE/Win - Fix animation bug - #4615 */
-.ui-accordion { width: 100%; }
-.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
-.ui-accordion .ui-accordion-li-fix { display: inline; }
-.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
-.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
-.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
-.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
-.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
-.ui-accordion .ui-accordion-content-active { display: block; }
-/*!
- * jQuery UI Autocomplete 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Autocomplete#theming
- */
-.ui-autocomplete { position: absolute; cursor: default; }	
-
-/* workarounds */
-* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
-
-/*
- * jQuery UI Menu 1.8.22
- *
- * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Menu#theming
- */
-.ui-menu {
-	list-style:none;
-	padding: 2px;
-	margin: 0;
-	display:block;
-	float: left;
-}
-.ui-menu .ui-menu {
-	margin-top: -3px;
-}
-.ui-menu .ui-menu-item {
-	margin:0;
-	padding: 0;
-	zoom: 1;
-	float: left;
-	clear: left;
-	width: 100%;
-}
-.ui-menu .ui-menu-item a {
-	text-decoration:none;
-	display:block;
-	padding:.2em .4em;
-	line-height:1.5;
-	zoom:1;
-}
-.ui-menu .ui-menu-item a.ui-state-hover,
-.ui-menu .ui-menu-item a.ui-state-active {
-	font-weight: normal;
-	margin: -1px;
-}
-/*!
- * jQuery UI Button 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Button#theming
- */
-.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
-.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
-button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
-.ui-button-icons-only { width: 3.4em; } 
-button.ui-button-icons-only { width: 3.7em; } 
-
-/*button text element */
-.ui-button .ui-button-text { display: block; line-height: 1.4;  }
-.ui-button-text-only .ui-button-text { padding: .4em 1em; }
-.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
-.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
-.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
-.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
-/* no icon support for input elements, provide padding by default */
-input.ui-button { padding: .4em 1em; }
-
-/*button icon element(s) */
-.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
-.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
-.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
-.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
-.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
-
-/*button sets*/
-.ui-buttonset { margin-right: 7px; }
-.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
-
-/* workarounds */
-button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
-/*!
- * jQuery UI Dialog 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Dialog#theming
- */
-.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
-.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative;  }
-.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } 
-.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
-.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
-.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
-.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
-.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
-.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
-.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
-.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
-.ui-draggable .ui-dialog-titlebar { cursor: move; }
-/*!
- * jQuery UI Slider 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Slider#theming
- */
-.ui-slider { position: relative; text-align: left; }
-.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
-.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
-
-.ui-slider-horizontal { height: .8em; }
-.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
-.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
-.ui-slider-horizontal .ui-slider-range-min { left: 0; }
-.ui-slider-horizontal .ui-slider-range-max { right: 0; }
-
-.ui-slider-vertical { width: .8em; height: 100px; }
-.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
-.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
-.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
-.ui-slider-vertical .ui-slider-range-max { top: 0; }/*!
- * jQuery UI Tabs 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Tabs#theming
- */
-.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
-.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
-.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
-.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
-.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
-.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
-.ui-tabs .ui-tabs-hide { display: none !important; }
-/*!
- * jQuery UI Datepicker 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Datepicker#theming
- */
-.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
-.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
-.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
-.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
-.ui-datepicker .ui-datepicker-prev { left:2px; }
-.ui-datepicker .ui-datepicker-next { right:2px; }
-.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
-.ui-datepicker .ui-datepicker-next-hover { right:1px; }
-.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px;  }
-.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
-.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
-.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
-.ui-datepicker select.ui-datepicker-month, 
-.ui-datepicker select.ui-datepicker-year { width: 49%;}
-.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
-.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
-.ui-datepicker td { border: 0; padding: 1px; }
-.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
-.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
-.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
-
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi { width:auto; }
-.ui-datepicker-multi .ui-datepicker-group { float:left; }
-.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
-.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
-.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
-.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
-.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
-
-/* RTL support */
-.ui-datepicker-rtl { direction: rtl; }
-.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
-.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
-.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
-.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
-.ui-datepicker-rtl .ui-datepicker-group { float:right; }
-.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
-.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
-
-/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
-.ui-datepicker-cover {
-    position: absolute; /*must have*/
-    z-index: -1; /*must have*/
-    filter: mask(); /*must have*/
-    top: -4px; /*must have*/
-    left: -4px; /*must have*/
-    width: 200px; /*must have*/
-    height: 200px; /*must have*/
-}/*!
- * jQuery UI Progressbar 1.8.22
- *
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Progressbar#theming
- */
-.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
-.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
diff -r 0a574315af3e -r 4f746d8966dd public/stylesheets/jquery/jquery-ui-1.9.2.css
--- /dev/null
+++ b/public/stylesheets/jquery/jquery-ui-1.9.2.css
@@ -0,0 +1,5 @@
+/*! jQuery UI - v1.9.2 - 2012-12-26
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2C%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=759fcf&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=628db6&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=628db6&iconColorDefault=759fcf&bgColorHover=eef5fd&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=628db6&fcHover=628db6&iconColorHover=759fcf&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=628db6&fcActive=628db6&iconColorActive=759fcf&bgColorHighlight=759fcf&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=628db6&fcHighlight=363636&iconColorHighlight=759fcf&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
+* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;zoom:1}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto;zoom:1}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}* html .ui-autocomplete{width:1px}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:1.4}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0em}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current{float:right}.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;width:300px;overflow:hidden}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto;zoom:1}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em;zoom:1}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}* html .ui-tooltip{background-image:none}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #628db6;background:#759fcf url(images/ui-bg_gloss-wave_35_759fcf_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;background:#f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#628db6}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#628db6;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #628db6;background:#eef5fd url(images/ui-bg_glass_100_eef5fd_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#628db6}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#628db6;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #628db6;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#628db6}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#628db6;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #628db6;background:#759fcf url(images/ui-bg_highlight-soft_75_759fcf_1x100.png) 50% top repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_759fcf_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_ffd27a_256x240.png)}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}
diff -r 0a574315af3e -r 4f746d8966dd public/stylesheets/jstoolbar.css
--- a/public/stylesheets/jstoolbar.css
+++ b/public/stylesheets/jstoolbar.css
@@ -95,3 +95,6 @@
 .jstb_img {
     background-image: url(../images/jstoolbar/bt_img.png);
 }
+.jstb_help {
+    background-image: url(../images/help.png);
+}
diff -r 0a574315af3e -r 4f746d8966dd test/extra/redmine_pm/repository_git_test.rb
--- a/test/extra/redmine_pm/repository_git_test.rb
+++ b/test/extra/redmine_pm/repository_git_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/extra/redmine_pm/repository_subversion_test.rb
--- a/test/extra/redmine_pm/repository_subversion_test.rb
+++ b/test/extra/redmine_pm/repository_subversion_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/extra/redmine_pm/test_case.rb
--- a/test/extra/redmine_pm/test_case.rb
+++ b/test/extra/redmine_pm/test_case.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/attachments.yml
--- a/test/fixtures/attachments.yml
+++ b/test/fixtures/attachments.yml
@@ -4,6 +4,7 @@
   downloads: 0
   content_type: text/plain
   disk_filename: 060719210727_error281.txt
+  disk_directory: "2006/07"
   container_id: 3
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 1
@@ -16,6 +17,7 @@
   downloads: 0
   content_type: text/plain
   disk_filename: 060719210727_document.txt
+  disk_directory: "2006/07"
   container_id: 1
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 2
@@ -28,6 +30,7 @@
   downloads: 0
   content_type: image/gif
   disk_filename: 060719210727_logo.gif
+  disk_directory: "2006/07"
   container_id: 4
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 3
@@ -42,6 +45,7 @@
   container_id: 3
   downloads: 0
   disk_filename: 060719210727_source.rb
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 4
   filesize: 153
@@ -55,6 +59,7 @@
   container_id: 3
   downloads: 0
   disk_filename: 060719210727_changeset_iso8859-1.diff
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 5
   filesize: 687
@@ -67,6 +72,7 @@
   container_id: 3
   downloads: 0
   disk_filename: 060719210727_archive.zip
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 6
   filesize: 157
@@ -79,6 +85,7 @@
   container_id: 4
   downloads: 0
   disk_filename: 060719210727_archive.zip
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 7
   filesize: 157
@@ -91,6 +98,7 @@
   container_id: 1
   downloads: 0
   disk_filename: 060719210727_project_file.zip
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 8
   filesize: 320
@@ -103,6 +111,7 @@
   container_id: 1
   downloads: 0
   disk_filename: 060719210727_archive.zip
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 9
   filesize: 452
@@ -115,6 +124,7 @@
   container_id: 2
   downloads: 0
   disk_filename: 060719210727_picture.jpg
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 10
   filesize: 452
@@ -127,6 +137,7 @@
   container_id: 1
   downloads: 0
   disk_filename: 060719210727_picture.jpg
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 11
   filesize: 452
@@ -139,6 +150,7 @@
   container_id: 1
   downloads: 0
   disk_filename: 060719210727_version_file.zip
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 12
   filesize: 452
@@ -151,6 +163,7 @@
   container_id: 1
   downloads: 0
   disk_filename: 060719210727_foo.zip
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 13
   filesize: 452
@@ -163,6 +176,7 @@
   container_id: 3
   downloads: 0
   disk_filename: 060719210727_changeset_utf8.diff
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   id: 14
   filesize: 687
@@ -176,6 +190,7 @@
   container_id: 14
   downloads: 0
   disk_filename: 060719210727_changeset_utf8.diff
+  disk_directory: "2006/07"
   digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
   filesize: 687
   filename: private.diff
@@ -187,6 +202,7 @@
   downloads: 0
   created_on: 2010-11-23 16:14:50 +09:00
   disk_filename: 101123161450_testfile_1.png
+  disk_directory: "2010/11"
   container_id: 14
   digest: 8e0294de2441577c529f170b6fb8f638
   id: 16
@@ -200,6 +216,7 @@
   downloads: 0
   created_on: 2010-12-23 16:14:50 +09:00
   disk_filename: 101223161450_testfile_2.png
+  disk_directory: "2010/12"
   container_id: 14
   digest: 6bc2963e8d7ea0d3e68d12d1fba3d6ca
   id: 17
@@ -213,6 +230,7 @@
   downloads: 0
   created_on: 2011-01-23 16:14:50 +09:00
   disk_filename: 101123161450_testfile_1.png
+  disk_directory: "2010/11"
   container_id: 14
   digest: 8e0294de2441577c529f170b6fb8f638
   id: 18
@@ -226,6 +244,7 @@
   downloads: 0
   created_on: 2011-02-23 16:14:50 +09:00
   disk_filename: 101223161450_testfile_2.png
+  disk_directory: "2010/12"
   container_id: 14
   digest: 6bc2963e8d7ea0d3e68d12d1fba3d6ca
   id: 19
@@ -234,3 +253,17 @@
   filename: Testãƒ†ã‚¹ãƒˆ.PNG
   filesize: 3582
   author_id: 2
+attachments_020: 
+  content_type: text/plain
+  downloads: 0
+  created_on: 2012-05-12 16:14:50 +09:00
+  disk_filename: 120512161450_root_attachment.txt
+  disk_directory:
+  container_id: 14
+  digest: b0fe2abdb2599743d554a61d7da7ff74
+  id: 20
+  container_type: Issue
+  description: ""
+  filename: root_attachment.txt
+  filesize: 54
+  author_id: 2
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/changesets.yml
--- a/test/fixtures/changesets.yml
+++ b/test/fixtures/changesets.yml
@@ -3,8 +3,9 @@
   commit_date: 2007-04-11
   committed_on: 2007-04-11 15:14:44 +02:00
   revision: 1
+  scmid: 691322a8eb01e11fd7
   id: 100
-  comments: My very first commit
+  comments: 'My very first commit do not escaping #<>&'
   repository_id: 10
   committer: dlopper
   user_id: 3
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/diffs/issue-12641-ja.diff
--- /dev/null
+++ b/test/fixtures/diffs/issue-12641-ja.diff
@@ -0,0 +1,25 @@
+# HG changeset patch
+# User tmaruyama
+# Date 1362559296 0
+# Node ID ee54942e0289c30bea1b1973750b698b1ee7c466
+# Parent  738777832f379f6f099c25251593fc57bc17f586
+fix some Japanese "issue" translations (#13350)
+
+Contributed by Go MAEDA.
+
+diff --git a/config/locales/ja.yml b/config/locales/ja.yml
+--- a/config/locales/ja.yml
++++ b/config/locales/ja.yml
+@@ -904,9 +904,9 @@ ja:
+   text_journal_set_to: "%{label} ã‚’ %{value} ã«ã‚»ãƒƒãƒˆ"
+   text_journal_deleted: "%{label} ã‚’å‰Šé™¤ (%{old})"
+   text_journal_added: "%{label} %{value} ã‚’è¿½åŠ "
+-  text_tip_issue_begin_day: ã“ã®æ—¥ã«é–‹å§‹ã™ã‚‹ã‚¿ã‚¹ã‚¯
+-  text_tip_issue_end_day: ã“ã®æ—¥ã«çµ‚äº†ã™ã‚‹ã‚¿ã‚¹ã‚¯
+-  text_tip_issue_begin_end_day: ã“ã®æ—¥ã®ã†ã¡ã«é–‹å§‹ã—ã¦çµ‚äº†ã™ã‚‹ã‚¿ã‚¹ã‚¯
++  text_tip_issue_begin_day: ã“ã®æ—¥ã«é–‹å§‹ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
++  text_tip_issue_end_day: ã“ã®æ—¥ã«çµ‚äº†ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
++  text_tip_issue_begin_end_day: ã“ã®æ—¥ã«é–‹å§‹ãƒ»çµ‚äº†ã™ã‚‹ãƒã‚±ãƒƒãƒˆ
+   text_caracters_maximum: "æœ€å¤§%{count}æ–‡å­—ã§ã™ã€‚"
+   text_caracters_minimum: "æœ€ä½Ž%{count}æ–‡å­—ã®é•·ã•ãŒå¿…è¦ã§ã™"
+   text_length_between: "é•·ã•ã¯%{min}ã‹ã‚‰%{max}æ–‡å­—ã¾ã§ã§ã™ã€‚"
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/diffs/issue-12641-ru.diff
--- /dev/null
+++ b/test/fixtures/diffs/issue-12641-ru.diff
@@ -0,0 +1,19 @@
+# HG changeset patch
+# User tmaruyama
+# Date 1355872765 0
+# Node ID 8a13ebed1779c2e85fa644ecdd0de81996c969c4
+# Parent  5c3c5f917ae92f278fe42c6978366996595b0796
+Russian "about_x_hours" translation changed by Mikhail Velkin (#12640)
+
+diff --git a/config/locales/ru.yml b/config/locales/ru.yml
+--- a/config/locales/ru.yml
++++ b/config/locales/ru.yml
+@@ -115,7 +115,7 @@ ru:
+         one:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
+         few:   "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
+         many:  "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
+-        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ°"
++        other: "Ð¾ÐºÐ¾Ð»Ð¾ %{count} Ñ‡Ð°ÑÐ¾Ð²"
+       x_hours:
+         one:   "1 Ñ‡Ð°Ñ"
+         other: "%{count} Ñ‡Ð°ÑÐ¾Ð²"
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/diffs/issue-13644-1.diff
--- /dev/null
+++ b/test/fixtures/diffs/issue-13644-1.diff
@@ -0,0 +1,7 @@
+--- a.txt	2013-04-05 14:19:39.000000000 +0900
++++ b.txt	2013-04-05 14:19:51.000000000 +0900
+@@ -1,3 +1,3 @@
+ aaaa
+-æ—¥æœ¬
++æ—¥æœ¬èªž
+ bbbb
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/diffs/issue-13644-2.diff
--- /dev/null
+++ b/test/fixtures/diffs/issue-13644-2.diff
@@ -0,0 +1,7 @@
+--- a.txt	2013-04-05 14:19:39.000000000 +0900
++++ b.txt	2013-04-05 14:19:51.000000000 +0900
+@@ -1,3 +1,3 @@
+ aaaa
+-æ—¥æœ¬
++ã«ã£ã½ã‚“æ—¥æœ¬
+ bbbb
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/files/060719210727_archive.zip
Binary file test/fixtures/files/060719210727_archive.zip has changed
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/files/060719210727_changeset_iso8859-1.diff
--- a/test/fixtures/files/060719210727_changeset_iso8859-1.diff
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: trunk/app/controllers/issues_controller.rb
-===================================================================
---- trunk/app/controllers/issues_controller.rb	(révision 1483)
-+++ trunk/app/controllers/issues_controller.rb	(révision 1484)
-@@ -149,7 +149,7 @@
-         attach_files(@issue, params[:attachments])
-         flash[:notice] = 'Demande créée avec succès'
-         Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
--        redirect_to :controller => 'issues', :action => 'show', :id => @issue,  :project_id => @project
-+        redirect_to :controller => 'issues', :action => 'show', :id => @issue
-         return
-       end		
-     end	
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/files/060719210727_changeset_utf8.diff
--- a/test/fixtures/files/060719210727_changeset_utf8.diff
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: trunk/app/controllers/issues_controller.rb
-===================================================================
---- trunk/app/controllers/issues_controller.rb	(rÃ©vision 1483)
-+++ trunk/app/controllers/issues_controller.rb	(rÃ©vision 1484)
-@@ -149,7 +149,7 @@
-         attach_files(@issue, params[:attachments])
-         flash[:notice] = 'Demande crÃ©Ã©e avec succÃ¨s'
-         Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
--        redirect_to :controller => 'issues', :action => 'show', :id => @issue,  :project_id => @project
-+        redirect_to :controller => 'issues', :action => 'show', :id => @issue
-         return
-       end		
-     end	
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/files/060719210727_source.rb
--- a/test/fixtures/files/060719210727_source.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# The Greeter class
-class Greeter
-  def initialize(name)
-    @name = name.capitalize
-  end
-
-  def salute
-    puts "Hello #{@name}!" 
-  end
-end
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/files/101123161450_testfile_1.png
Binary file test/fixtures/files/101123161450_testfile_1.png has changed
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/files/101223161450_testfile_2.png
Binary file test/fixtures/files/101223161450_testfile_2.png has changed
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/issues.yml
--- a/test/fixtures/issues.yml
+++ b/test/fixtures/issues.yml
@@ -152,6 +152,7 @@
   root_id: 8
   lft: 1
   rgt: 2
+  closed_on: <%= 3.days.ago.to_s(:db) %>
 issues_009: 
   created_on: <%= 1.minute.ago.to_s(:db) %>
   project_id: 5
@@ -209,6 +210,7 @@
   root_id: 11
   lft: 1
   rgt: 2
+  closed_on: <%= 1.day.ago.to_s(:db) %>
 issues_012: 
   created_on: <%= 3.days.ago.to_s(:db) %>
   project_id: 1
@@ -228,6 +230,7 @@
   root_id: 12
   lft: 1
   rgt: 2
+  closed_on: <%= 1.day.ago.to_s(:db) %>
 issues_013:
   created_on: <%= 5.days.ago.to_s(:db) %>
   project_id: 3
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/journal_details.yml
--- a/test/fixtures/journal_details.yml
+++ b/test/fixtures/journal_details.yml
@@ -14,7 +14,7 @@
   prop_key: done_ratio
   journal_id: 1
 journal_details_003:
-  old_value: nil
+  old_value:
   property: attr
   id: 3
   value: "6"
@@ -35,7 +35,7 @@
   prop_key: 2
   journal_id: 3
 journal_details_006:
-  old_value: nil
+  old_value:
   property: attachment
   id: 6
   value: 060719210727_picture.jpg
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/queries.yml
--- a/test/fixtures/queries.yml
+++ b/test/fixtures/queries.yml
@@ -1,6 +1,7 @@
 --- 
 queries_001: 
   id: 1
+  type: IssueQuery
   project_id: 1
   is_public: true
   name: Multiple custom fields query
@@ -23,6 +24,7 @@
   column_names: 
 queries_002: 
   id: 2
+  type: IssueQuery
   project_id: 1
   is_public: false
   name: Private query for cookbook
@@ -41,6 +43,7 @@
   column_names: 
 queries_003: 
   id: 3
+  type: IssueQuery
   project_id: 
   is_public: false
   name: Private query for all projects
@@ -55,6 +58,7 @@
   column_names: 
 queries_004: 
   id: 4
+  type: IssueQuery
   project_id: 
   is_public: true
   name: Public query for all projects
@@ -69,6 +73,7 @@
   column_names: 
 queries_005: 
   id: 5
+  type: IssueQuery
   project_id: 
   is_public: true
   name: Open issues by priority and tracker
@@ -89,6 +94,7 @@
       - asc
 queries_006: 
   id: 6
+  type: IssueQuery
   project_id: 
   is_public: true
   name: Open issues grouped by tracker
@@ -108,6 +114,7 @@
       - desc
 queries_007: 
   id: 7
+  type: IssueQuery
   project_id: 2
   is_public: true
   name: Public query for project 2
@@ -122,6 +129,7 @@
   column_names: 
 queries_008: 
   id: 8
+  type: IssueQuery
   project_id: 2
   is_public: false
   name: Private query for project 2
@@ -136,6 +144,7 @@
   column_names: 
 queries_009: 
   id: 9
+  type: IssueQuery
   project_id: 
   is_public: true
   name: Open issues grouped by list custom field
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/roles.yml
--- a/test/fixtures/roles.yml
+++ b/test/fixtures/roles.yml
@@ -38,7 +38,9 @@
     - :manage_news
     - :comment_news
     - :view_documents
-    - :manage_documents
+    - :add_documents
+    - :edit_documents
+    - :delete_documents
     - :view_wiki_pages
     - :export_wiki_pages
     - :view_wiki_edits
@@ -89,7 +91,9 @@
     - :manage_news
     - :comment_news
     - :view_documents
-    - :manage_documents
+    - :add_documents
+    - :edit_documents
+    - :delete_documents
     - :view_wiki_pages
     - :view_wiki_edits
     - :edit_wiki_pages
@@ -131,7 +135,9 @@
     - :manage_news
     - :comment_news
     - :view_documents
-    - :manage_documents
+    - :add_documents
+    - :edit_documents
+    - :delete_documents
     - :view_wiki_pages
     - :view_wiki_edits
     - :edit_wiki_pages
@@ -163,7 +169,6 @@
     - :view_time_entries
     - :comment_news
     - :view_documents
-    - :manage_documents
     - :view_wiki_pages
     - :view_wiki_edits
     - :edit_wiki_pages
diff -r 0a574315af3e -r 4f746d8966dd test/fixtures/users.yml
--- a/test/fixtures/users.yml
+++ b/test/fixtures/users.yml
@@ -29,7 +29,7 @@
   admin: true
   mail: admin@somenet.foo
   lastname: Admin
-  firstname: redMine
+  firstname: Redmine
   id: 1
   auth_source_id: 
   mail_notification: all
@@ -105,12 +105,15 @@
   login: ''
   type: AnonymousUser
 users_007: 
+  # A user who does not belong to any project
   id: 7
   created_on: 2006-07-19 19:33:19 +02:00
   status: 1
   last_login_on: 
-  language: ''
-  hashed_password: 1
+  language: 'en'
+  # password = foo
+  salt: 7599f9963ec07b5a3b55b354407120c0
+  hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
   updated_on: 2006-07-19 19:33:19 +02:00
   admin: false
   mail: someone@foo.bar
diff -r 0a574315af3e -r 4f746d8966dd test/functional/account_controller_openid_test.rb
--- a/test/functional/account_controller_openid_test.rb
+++ b/test/functional/account_controller_openid_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/account_controller_test.rb
--- a/test/functional/account_controller_test.rb
+++ b/test/functional/account_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,18 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'account_controller'
-
-# Re-raise errors caught by the controller.
-class AccountController; def rescue_action(e) raise e end; end
 
 class AccountControllerTest < ActionController::TestCase
   fixtures :users, :roles
 
   def setup
-    @controller = AccountController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
@@ -40,6 +33,14 @@
     assert_select 'input[name=password]'
   end
 
+  def test_get_login_while_logged_in_should_redirect_to_home
+    @request.session[:user_id] = 2
+
+    get :login
+    assert_redirected_to '/'
+    assert_equal 2, @request.session[:user_id]
+  end
+
   def test_login_should_redirect_to_back_url_param
     # request.uri is "test.host" in test environment
     post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http://test.host/issues/show/1'
@@ -79,9 +80,18 @@
     assert_response 302
   end
 
+  def test_get_logout_should_not_logout
+    @request.session[:user_id] = 2
+    get :logout
+    assert_response :success
+    assert_template 'logout'
+
+    assert_equal 2, @request.session[:user_id]
+  end
+
   def test_logout
     @request.session[:user_id] = 2
-    get :logout
+    post :logout
     assert_redirected_to '/'
     assert_nil @request.session[:user_id]
   end
@@ -90,7 +100,7 @@
     @controller.expects(:reset_session).once
 
     @request.session[:user_id] = 2
-    get :logout
+    post :logout
     assert_response 302
   end
 
@@ -101,8 +111,21 @@
       assert_template 'register'
       assert_not_nil assigns(:user)
 
-      assert_tag 'input', :attributes => {:name => 'user[password]'}
-      assert_tag 'input', :attributes => {:name => 'user[password_confirmation]'}
+      assert_select 'input[name=?]', 'user[password]'
+      assert_select 'input[name=?]', 'user[password_confirmation]'
+    end
+  end
+
+  def test_get_register_should_detect_user_language
+    with_settings :self_registration => '3' do
+      @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
+      get :register
+      assert_response :success
+      assert_not_nil assigns(:user)
+      assert_equal 'fr', assigns(:user).language
+      assert_select 'select[name=?]', 'user[language]' do
+        assert_select 'option[value=fr][selected=selected]'
+      end
     end
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/activities_controller_test.rb
--- a/test/functional/activities_controller_test.rb
+++ b/test/functional/activities_controller_test.rb
@@ -1,3 +1,20 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../test_helper', __FILE__)
 
 class ActivitiesControllerTest < ActionController::TestCase
@@ -9,7 +26,6 @@
            :members,
            :groups_users,
            :enabled_modules,
-           :workflows,
            :journals, :journal_details
 
 
@@ -19,16 +35,8 @@
     assert_template 'index'
     assert_not_nil assigns(:events_by_day)
 
-    assert_tag :tag => "h3",
-               :content => /#{2.days.ago.to_date.day}/,
-               :sibling => { :tag => "dl",
-                 :child => { :tag => "dt",
-                   :attributes => { :class => /issue-edit/ },
-                   :child => { :tag => "a",
-                     :content => /(#{IssueStatus.find(2).name})/,
-                   }
-                 }
-               }
+    assert_select 'h3', :text => /#{2.days.ago.to_date.day}/
+    assert_select 'dl dt.issue-edit a', :text => /(#{IssueStatus.find(2).name})/
   end
 
   def test_project_index_with_invalid_project_id_should_respond_404
@@ -42,16 +50,8 @@
     assert_template 'index'
     assert_not_nil assigns(:events_by_day)
 
-    assert_tag :tag => "h3",
-               :content => /#{3.day.ago.to_date.day}/,
-               :sibling => { :tag => "dl",
-                 :child => { :tag => "dt",
-                   :attributes => { :class => /issue/ },
-                   :child => { :tag => "a",
-                     :content => /Can&#x27;t print recipes/,
-                   }
-                 }
-               }
+    assert_select 'h3', :text => /#{3.days.ago.to_date.day}/
+    assert_select 'dl dt.issue a', :text => /Can&#x27;t print recipes/
   end
 
   def test_global_index
@@ -63,16 +63,9 @@
 
     i5 = Issue.find(5)
     d5 = User.find(1).time_to_date(i5.created_on)
-    assert_tag :tag => "h3",
-               :content => /#{d5.day}/,
-               :sibling => { :tag => "dl",
-                 :child => { :tag => "dt",
-                   :attributes => { :class => /issue/ },
-                   :child => { :tag => "a",
-                     :content => /Subproject issue/,
-                   }
-                 }
-               }
+
+    assert_select 'h3', :text => /#{d5.day}/
+    assert_select 'dl dt.issue a', :text => /Subproject issue/
   end
 
   def test_user_index
@@ -87,16 +80,8 @@
     i1 = Issue.find(1)
     d1 = User.find(1).time_to_date(i1.created_on)
 
-    assert_tag :tag => "h3",
-               :content => /#{d1.day}/,
-               :sibling => { :tag => "dl",
-                 :child => { :tag => "dt",
-                   :attributes => { :class => /issue/ },
-                   :child => { :tag => "a",
-                     :content => /Can&#x27;t print recipes/,
-                   }
-                 }
-               }
+    assert_select 'h3', :text => /#{d1.day}/
+    assert_select 'dl dt.issue a', :text => /Can&#x27;t print recipes/
   end
 
   def test_user_index_with_invalid_user_id_should_respond_404
@@ -109,14 +94,13 @@
     assert_response :success
     assert_template 'common/feed'
 
-    assert_tag :tag => 'link', :parent =>  {:tag => 'feed', :parent => nil },
-        :attributes => {:rel => 'self', :href => 'http://test.host/activity.atom?with_subprojects=0'}
-    assert_tag :tag => 'link', :parent =>  {:tag => 'feed', :parent => nil },
-        :attributes => {:rel => 'alternate', :href => 'http://test.host/activity?with_subprojects=0'}
-
-    assert_tag :tag => 'entry', :child => {
-      :tag => 'link',
-      :attributes => {:href => 'http://test.host/issues/11'}}
+    assert_select 'feed' do
+      assert_select 'link[rel=self][href=?]', 'http://test.host/activity.atom?with_subprojects=0'
+      assert_select 'link[rel=alternate][href=?]', 'http://test.host/activity?with_subprojects=0'
+      assert_select 'entry' do
+        assert_select 'link[href=?]', 'http://test.host/issues/11'
+      end
+    end
   end
 
   def test_index_atom_feed_with_explicit_selection
@@ -133,21 +117,21 @@
     assert_response :success
     assert_template 'common/feed'
 
-    assert_tag :tag => 'link', :parent =>  {:tag => 'feed', :parent => nil },
-        :attributes => {:rel => 'self', :href => 'http://test.host/activity.atom?show_changesets=1&amp;show_documents=1&amp;show_files=1&amp;show_issues=1&amp;show_messages=1&amp;show_news=1&amp;show_time_entries=1&amp;show_wiki_edits=1&amp;with_subprojects=0'}
-    assert_tag :tag => 'link', :parent => {:tag => 'feed', :parent => nil },
-        :attributes => {:rel => 'alternate', :href => 'http://test.host/activity?show_changesets=1&amp;show_documents=1&amp;show_files=1&amp;show_issues=1&amp;show_messages=1&amp;show_news=1&amp;show_time_entries=1&amp;show_wiki_edits=1&amp;with_subprojects=0'}
-
-    assert_tag :tag => 'entry', :child => {
-      :tag => 'link',
-      :attributes => {:href => 'http://test.host/issues/11'}}
+    assert_select 'feed' do
+      assert_select 'link[rel=self][href=?]', 'http://test.host/activity.atom?show_changesets=1&amp;show_documents=1&amp;show_files=1&amp;show_issues=1&amp;show_messages=1&amp;show_news=1&amp;show_time_entries=1&amp;show_wiki_edits=1&amp;with_subprojects=0'
+      assert_select 'link[rel=alternate][href=?]', 'http://test.host/activity?show_changesets=1&amp;show_documents=1&amp;show_files=1&amp;show_issues=1&amp;show_messages=1&amp;show_news=1&amp;show_time_entries=1&amp;show_wiki_edits=1&amp;with_subprojects=0'
+      assert_select 'entry' do
+        assert_select 'link[href=?]', 'http://test.host/issues/11'
+      end
+    end
   end
 
   def test_index_atom_feed_with_one_item_type
     get :index, :format => 'atom', :show_issues => '1'
     assert_response :success
     assert_template 'common/feed'
-    assert_tag :tag => 'title', :content => /Issues/
+
+    assert_select 'title', :text => /Issues/
   end
 
   def test_index_should_show_private_notes_with_permission_only
diff -r 0a574315af3e -r 4f746d8966dd test/functional/admin_controller_test.rb
--- a/test/functional/admin_controller_test.rb
+++ b/test/functional/admin_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -27,15 +27,13 @@
 
   def test_index
     get :index
-    assert_no_tag :tag => 'div',
-                  :attributes => { :class => /nodata/ }
+    assert_select 'div.nodata', 0
   end
 
   def test_index_with_no_configuration_data
     delete_configuration_data
     get :index
-    assert_tag :tag => 'div',
-               :attributes => { :class => /nodata/ }
+    assert_select 'div.nodata'
   end
 
   def test_projects
@@ -90,7 +88,7 @@
     ActionMailer::Base.deliveries.clear
 
     get :test_email
-    assert_redirected_to '/settings/edit?tab=notifications'
+    assert_redirected_to '/settings?tab=notifications'
     mail = ActionMailer::Base.deliveries.last
     assert_not_nil mail
     user = User.find(1)
@@ -100,7 +98,7 @@
   def test_test_email_failure_should_display_the_error
     Mailer.stubs(:test_email).raises(Exception, 'Some error message')
     get :test_email
-    assert_redirected_to '/settings/edit?tab=notifications'
+    assert_redirected_to '/settings?tab=notifications'
     assert_match /Some error message/, flash[:error]
   end
 
@@ -128,8 +126,14 @@
     assert_response :success
     assert_template 'plugins'
 
-    assert_tag :td, :child => { :tag => 'span', :content => 'Foo plugin' }
-    assert_tag :td, :child => { :tag => 'span', :content => 'Bar' }
+    assert_select 'tr#plugin-foo' do
+      assert_select 'td span.name', :text => 'Foo plugin'
+      assert_select 'td.configure a[href=/settings/plugin/foo]'
+    end
+    assert_select 'tr#plugin-bar' do
+      assert_select 'td span.name', :text => 'Bar'
+      assert_select 'td.configure a', 0
+    end
   end
 
   def test_info
@@ -145,8 +149,7 @@
 
     get :index
     assert_response :success
-    assert_tag :a, :attributes => { :href => '/foo/bar' },
-                   :content => 'Test'
+    assert_select 'div#admin-menu a[href=/foo/bar]', :text => 'Test'
 
     Redmine::MenuManager.map :admin_menu do |menu|
       menu.delete :test_admin_menu_plugin_extension
diff -r 0a574315af3e -r 4f746d8966dd test/functional/attachments_controller_test.rb
--- a/test/functional/attachments_controller_test.rb
+++ b/test/functional/attachments_controller_test.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,10 +18,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'attachments_controller'
-
-# Re-raise errors caught by the controller.
-class AttachmentsController; def rescue_action(e) raise e end; end
 
 class AttachmentsControllerTest < ActionController::TestCase
   fixtures :users, :projects, :roles, :members, :member_roles,
@@ -29,9 +25,6 @@
            :versions, :wiki_pages, :wikis, :documents
 
   def setup
-    @controller = AttachmentsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
     set_fixtures_attachments_directory
   end
@@ -57,7 +50,7 @@
     set_tmp_attachments_directory
   end
 
-  def test_show_diff_replcace_cannot_convert_content
+  def test_show_diff_replace_cannot_convert_content
     with_settings :repositories_encodings => 'UTF-8' do
       ['inline', 'sbs'].each do |dt|
         # 060719210727_changeset_iso8859-1.diff
@@ -159,7 +152,7 @@
                :sibling => { :tag => 'td', :content => /#{str_japanese}/ }
   end
 
-  def test_show_text_file_replcace_cannot_convert_content
+  def test_show_text_file_replace_cannot_convert_content
     set_tmp_attachments_directory
     with_settings :repositories_encodings => 'UTF-8' do
       a = Attachment.new(:container => Issue.find(1),
@@ -230,12 +223,21 @@
     set_tmp_attachments_directory
   end
 
-  def test_show_file_without_container_should_be_denied
+  def test_show_file_without_container_should_be_allowed_to_author
     set_tmp_attachments_directory
     attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
 
     @request.session[:user_id] = 2
     get :show, :id => attachment.id
+    assert_response 200
+  end
+
+  def test_show_file_without_container_should_be_denied_to_other_users
+    set_tmp_attachments_directory
+    attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
+
+    @request.session[:user_id] = 3
+    get :show, :id => attachment.id
     assert_response 403
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/auth_sources_controller_test.rb
--- a/test/functional/auth_sources_controller_test.rb
+++ b/test/functional/auth_sources_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -42,8 +42,15 @@
     assert_equal AuthSourceLdap, source.class
     assert source.new_record?
 
-    assert_tag 'input', :attributes => {:name => 'type', :value => 'AuthSourceLdap'}
-    assert_tag 'input', :attributes => {:name => 'auth_source[host]'}
+    assert_select 'form#auth_source_form' do
+      assert_select 'input[name=type][value=AuthSourceLdap]'
+      assert_select 'input[name=?]', 'auth_source[host]'
+    end
+  end
+
+  def test_new_with_invalid_type_should_respond_with_404
+    get :new, :type => 'foo'
+    assert_response 404
   end
 
   def test_create
@@ -52,7 +59,7 @@
       assert_redirected_to '/auth_sources'
     end
 
-    source = AuthSourceLdap.first(:order => 'id DESC')
+    source = AuthSourceLdap.order('id DESC').first
     assert_equal 'Test', source.name
     assert_equal '127.0.0.1', source.host
     assert_equal 389, source.port
@@ -74,7 +81,23 @@
     assert_response :success
     assert_template 'edit'
 
-    assert_tag 'input', :attributes => {:name => 'auth_source[host]'}
+    assert_select 'form#auth_source_form' do
+      assert_select 'input[name=?]', 'auth_source[host]'
+    end
+  end
+
+  def test_edit_should_not_contain_password
+    AuthSource.find(1).update_column :account_password, 'secret'
+
+    get :edit, :id => 1
+    assert_response :success
+    assert_select 'input[value=secret]', 0
+    assert_select 'input[name=dummy_password][value=?]', /x+/
+  end
+
+  def test_edit_invalid_should_respond_with_404
+    get :edit, :id => 99
+    assert_response 404
   end
 
   def test_update
@@ -96,6 +119,7 @@
   def test_destroy
     assert_difference 'AuthSourceLdap.count', -1 do
       delete :destroy, :id => 1
+      assert_redirected_to '/auth_sources'
     end
   end
 
@@ -104,6 +128,7 @@
 
     assert_no_difference 'AuthSourceLdap.count' do
       delete :destroy, :id => 1
+      assert_redirected_to '/auth_sources'
     end
   end
 
@@ -124,4 +149,20 @@
     assert_not_nil flash[:error]
     assert_include 'Something went wrong', flash[:error]
   end
+
+  def test_autocomplete_for_new_user
+    AuthSource.expects(:search).with('foo').returns([
+      {:login => 'foo1', :firstname => 'John', :lastname => 'Smith', :mail => 'foo1@example.net', :auth_source_id => 1},
+      {:login => 'Smith', :firstname => 'John', :lastname => 'Doe', :mail => 'foo2@example.net', :auth_source_id => 1}
+    ])
+
+    get :autocomplete_for_new_user, :term => 'foo'
+    assert_response :success
+    assert_equal 'application/json', response.content_type
+    json = ActiveSupport::JSON.decode(response.body)
+    assert_kind_of Array, json
+    assert_equal 2, json.size
+    assert_equal 'foo1', json.first['value']
+    assert_equal 'foo1 (John Smith)', json.first['label']
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/auto_completes_controller_test.rb
--- a/test/functional/auto_completes_controller_test.rb
+++ b/test/functional/auto_completes_controller_test.rb
@@ -1,3 +1,20 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../test_helper', __FILE__)
 
 class AutoCompletesControllerTest < ActionController::TestCase
@@ -9,7 +26,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :journals, :journal_details
 
   def test_issues_should_not_be_case_sensitive
@@ -33,6 +49,13 @@
     assert assigns(:issues).include?(Issue.find(13))
   end
 
+  def test_issues_should_return_issue_with_given_id_preceded_with_hash
+    get :issues, :project_id => 'subproject1', :q => '#13'
+    assert_response :success
+    assert_not_nil assigns(:issues)
+    assert assigns(:issues).include?(Issue.find(13))
+  end
+
   def test_auto_complete_with_scope_all_should_search_other_projects
     get :issues, :project_id => 'ecookbook', :q => '13', :scope => 'all'
     assert_response :success
diff -r 0a574315af3e -r 4f746d8966dd test/functional/boards_controller_test.rb
--- a/test/functional/boards_controller_test.rb
+++ b/test/functional/boards_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -90,8 +90,9 @@
     assert_response :success
     assert_template 'show'
 
-    assert_tag 'form', :attributes => {:id => 'message-form'}
-    assert_tag 'input', :attributes => {:name => 'message[subject]'}
+    assert_select 'form#message-form' do
+      assert_select 'input[name=?]', 'message[subject]'
+    end
   end
 
   def test_show_atom
diff -r 0a574315af3e -r 4f746d8966dd test/functional/calendars_controller_test.rb
--- a/test/functional/calendars_controller_test.rb
+++ b/test/functional/calendars_controller_test.rb
@@ -1,3 +1,20 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../test_helper', __FILE__)
 
 class CalendarsControllerTest < ActionController::TestCase
@@ -9,13 +26,20 @@
            :members,
            :enabled_modules
 
-  def test_calendar
+  def test_show
     get :show, :project_id => 1
     assert_response :success
     assert_template 'calendar'
     assert_not_nil assigns(:calendar)
   end
 
+  def test_show_should_run_custom_queries
+    @query = IssueQuery.create!(:name => 'Calendar', :is_public => true)
+
+    get :show, :query_id => @query.id
+    assert_response :success
+  end
+
   def test_cross_project_calendar
     get :show
     assert_response :success
@@ -23,58 +47,38 @@
     assert_not_nil assigns(:calendar)
   end
 
-  context "GET :show" do
-    should "run custom queries" do
-      @query = Query.create!(:name => 'Calendar', :is_public => true)
-
-      get :show, :query_id => @query.id
-      assert_response :success
-    end
-
-  end
-
   def test_week_number_calculation
     Setting.start_of_week = 7
 
     get :show, :month => '1', :year => '2010'
     assert_response :success
 
-    assert_tag :tag => 'tr',
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'week-number'}, :content => '53'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'odd'}, :content => '27'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '2'}
+    assert_select 'tr' do
+      assert_select 'td.week-number', :text => '53'
+      assert_select 'td.odd', :text => '27'
+      assert_select 'td.even', :text => '2'
+    end
 
-    assert_tag :tag => 'tr',
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'week-number'}, :content => '1'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'odd'}, :content => '3'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '9'}
-
+    assert_select 'tr' do
+      assert_select 'td.week-number', :text => '1'
+      assert_select 'td.odd', :text => '3'
+      assert_select 'td.even', :text => '9'
+    end
 
     Setting.start_of_week = 1
     get :show, :month => '1', :year => '2010'
     assert_response :success
 
-    assert_tag :tag => 'tr',
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'week-number'}, :content => '53'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '28'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '3'}
+    assert_select 'tr' do
+      assert_select 'td.week-number', :text => '53'
+      assert_select 'td.even', :text => '28'
+      assert_select 'td.even', :text => '3'
+    end
 
-    assert_tag :tag => 'tr',
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'week-number'}, :content => '1'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '4'},
-      :descendant => {:tag => 'td',
-                      :attributes => {:class => 'even'}, :content => '10'}
-
+    assert_select 'tr' do
+      assert_select 'td.week-number', :text => '1'
+      assert_select 'td.even', :text => '4'
+      assert_select 'td.even', :text => '10'
+    end
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/comments_controller_test.rb
--- a/test/functional/comments_controller_test.rb
+++ b/test/functional/comments_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/context_menus_controller_test.rb
--- a/test/functional/context_menus_controller_test.rb
+++ b/test/functional/context_menus_controller_test.rb
@@ -1,3 +1,20 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../test_helper', __FILE__)
 
 class ContextMenusControllerTest < ActionController::TestCase
@@ -21,34 +38,21 @@
     get :issues, :ids => [1]
     assert_response :success
     assert_template 'context_menu'
-    assert_tag :tag => 'a', :content => 'Edit',
-                            :attributes => { :href => '/issues/1/edit',
-                                             :class => 'icon-edit' }
-    assert_tag :tag => 'a', :content => 'Closed',
-                            :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bstatus_id%5D=5',
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Immediate',
-                            :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
-                                             :class => '' }
-    assert_no_tag :tag => 'a', :content => 'Inactive Priority'
+
+    assert_select 'a.icon-edit[href=?]', '/issues/1/edit', :text => 'Edit'
+    assert_select 'a.icon-copy[href=?]', '/projects/ecookbook/issues/1/copy', :text => 'Copy'
+    assert_select 'a.icon-del[href=?]', '/issues?ids%5B%5D=1', :text => 'Delete'
+
+    # Statuses
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bstatus_id%5D=5', :text => 'Closed'
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8', :text => 'Immediate'
+    # No inactive priorities
+    assert_select 'a', :text => /Inactive Priority/, :count => 0
     # Versions
-    assert_tag :tag => 'a', :content => '2.0',
-                            :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
-                            :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
-                                             :class => '' }
-
-    assert_tag :tag => 'a', :content => 'Dave Lopper',
-                            :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Copy',
-                            :attributes => { :href => '/projects/ecookbook/issues/1/copy',
-                                             :class => 'icon-copy' }
-    assert_no_tag :tag => 'a', :content => 'Move'
-    assert_tag :tag => 'a', :content => 'Delete',
-                            :attributes => { :href => '/issues?ids%5B%5D=1',
-                                             :class => 'icon-del' }
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3', :text => '2.0'
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4', :text => 'eCookbook Subproject 1 - 2.0'
+    # Assignees
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3', :text => 'Dave Lopper'
   end
 
   def test_context_menu_one_issue_by_anonymous
@@ -69,25 +73,14 @@
     assert_equal [1, 2], assigns(:issues).map(&:id).sort
 
     ids = assigns(:issues).map(&:id).sort.map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
-    assert_tag :tag => 'a', :content => 'Edit',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}",
-                                             :class => 'icon-edit' }
-    assert_tag :tag => 'a', :content => 'Closed',
-                            :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Immediate',
-                            :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Dave Lopper',
-                            :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=3",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Copy',
-                            :attributes => { :href => "/issues/bulk_edit?copy=1&amp;#{ids}",
-                                             :class => 'icon-copy' }
-    assert_no_tag :tag => 'a', :content => 'Move'
-    assert_tag :tag => 'a', :content => 'Delete',
-                            :attributes => { :href => "/issues?#{ids}",
-                                             :class => 'icon-del' }
+
+    assert_select 'a.icon-edit[href=?]', "/issues/bulk_edit?#{ids}", :text => 'Edit'
+    assert_select 'a.icon-copy[href=?]', "/issues/bulk_edit?copy=1&amp;#{ids}", :text => 'Copy'
+    assert_select 'a.icon-del[href=?]', "/issues?#{ids}", :text => 'Delete'
+
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5", :text => 'Closed'
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8", :text => 'Immediate'
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=3", :text => 'Dave Lopper'
   end
 
   def test_context_menu_multiple_issues_of_different_projects
@@ -99,21 +92,13 @@
     assert_equal [1, 2, 6], assigns(:issues).map(&:id).sort
 
     ids = assigns(:issues).map(&:id).sort.map {|i| "ids%5B%5D=#{i}"}.join('&amp;')
-    assert_tag :tag => 'a', :content => 'Edit',
-                            :attributes => { :href => "/issues/bulk_edit?#{ids}",
-                                             :class => 'icon-edit' }
-    assert_tag :tag => 'a', :content => 'Closed',
-                            :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Immediate',
-                            :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'John Smith',
-                            :attributes => { :href => "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=2",
-                                             :class => '' }
-    assert_tag :tag => 'a', :content => 'Delete',
-                            :attributes => { :href => "/issues?#{ids}",
-                                             :class => 'icon-del' }
+
+    assert_select 'a.icon-edit[href=?]', "/issues/bulk_edit?#{ids}", :text => 'Edit'
+    assert_select 'a.icon-del[href=?]', "/issues?#{ids}", :text => 'Delete'
+
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bstatus_id%5D=5", :text => 'Closed'
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bpriority_id%5D=8", :text => 'Immediate'
+    assert_select 'a[href=?]', "/issues/bulk_update?#{ids}&amp;issue%5Bassigned_to_id%5D=2", :text => 'John Smith'
   end
 
   def test_context_menu_should_include_list_custom_fields
@@ -122,17 +107,14 @@
     @request.session[:user_id] = 2
     get :issues, :ids => [1]
 
-    assert_tag 'a',
-      :content => 'List',
-      :attributes => {:href => '#'},
-      :sibling => {:tag => 'ul', :children => {:count => 3}}
-
-    assert_tag 'a',
-      :content => 'Foo',
-      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=Foo"}
-    assert_tag 'a',
-      :content => 'none',
-      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=__none__"}
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'List'
+      assert_select 'ul' do
+        assert_select 'a', 3
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=Foo", :text => 'Foo'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=__none__", :text => 'none'
+      end
+    end
   end
 
   def test_context_menu_should_not_include_null_value_for_required_custom_fields
@@ -141,10 +123,13 @@
     @request.session[:user_id] = 2
     get :issues, :ids => [1, 2]
 
-    assert_tag 'a',
-      :content => 'List',
-      :attributes => {:href => '#'},
-      :sibling => {:tag => 'ul', :children => {:count => 2}}
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'List'
+      assert_select 'ul' do
+        assert_select 'a', 2
+        assert_select 'a', :text => 'none', :count => 0
+      end
+    end
   end
 
   def test_context_menu_on_single_issue_should_select_current_custom_field_value
@@ -156,13 +141,13 @@
     @request.session[:user_id] = 2
     get :issues, :ids => [1]
 
-    assert_tag 'a',
-      :content => 'List',
-      :attributes => {:href => '#'},
-      :sibling => {:tag => 'ul', :children => {:count => 3}}
-    assert_tag 'a',
-      :content => 'Bar',
-      :attributes => {:class => /icon-checked/}
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'List'
+      assert_select 'ul' do
+        assert_select 'a', 3
+        assert_select 'a.icon-checked', :text => 'Bar'
+      end
+    end
   end
 
   def test_context_menu_should_include_bool_custom_fields
@@ -171,14 +156,15 @@
     @request.session[:user_id] = 2
     get :issues, :ids => [1]
 
-    assert_tag 'a',
-      :content => 'Bool',
-      :attributes => {:href => '#'},
-      :sibling => {:tag => 'ul', :children => {:count => 3}}
-
-    assert_tag 'a',
-      :content => 'Yes',
-      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=1"}
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'Bool'
+      assert_select 'ul' do
+        assert_select 'a', 3
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=0", :text => 'No'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=1", :text => 'Yes'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=__none__", :text => 'none'
+      end
+    end
   end
 
   def test_context_menu_should_include_user_custom_fields
@@ -187,14 +173,14 @@
     @request.session[:user_id] = 2
     get :issues, :ids => [1]
 
-    assert_tag 'a',
-      :content => 'User',
-      :attributes => {:href => '#'},
-      :sibling => {:tag => 'ul', :children => {:count => Project.find(1).members.count + 1}}
-
-    assert_tag 'a',
-      :content => 'John Smith',
-      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=2"}
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'User'
+      assert_select 'ul' do
+        assert_select 'a', Project.find(1).members.count + 1
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=2", :text => 'John Smith'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=__none__", :text => 'none'
+      end
+    end
   end
 
   def test_context_menu_should_include_version_custom_fields
@@ -202,14 +188,14 @@
     @request.session[:user_id] = 2
     get :issues, :ids => [1]
 
-    assert_tag 'a',
-      :content => 'Version',
-      :attributes => {:href => '#'},
-      :sibling => {:tag => 'ul', :children => {:count => Project.find(1).shared_versions.count + 1}}
-
-    assert_tag 'a',
-      :content => '2.0',
-      :attributes => {:href => "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=3"}
+    assert_select "li.cf_#{field.id}" do
+      assert_select 'a[href=#]', :text => 'Version'
+      assert_select 'ul' do
+        assert_select 'a', Project.find(1).shared_versions.count + 1
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=3", :text => '2.0'
+        assert_select 'a[href=?]', "/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bcustom_field_values%5D%5B#{field.id}%5D=__none__", :text => 'none'
+      end
+    end
   end
 
   def test_context_menu_by_assignable_user_should_include_assigned_to_me_link
@@ -218,9 +204,7 @@
     assert_response :success
     assert_template 'context_menu'
 
-    assert_tag :tag => 'a', :content => / me /,
-                            :attributes => { :href => '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=2',
-                                             :class => '' }
+    assert_select 'a[href=?]', '/issues/bulk_update?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=2', :text => / me /
   end
 
   def test_context_menu_should_propose_shared_versions_for_issues_from_different_projects
@@ -232,7 +216,7 @@
     assert_template 'context_menu'
 
     assert_include version, assigns(:versions)
-    assert_tag :tag => 'a', :content => 'eCookbook - Shared'
+    assert_select 'a', :text => 'eCookbook - Shared'
   end
 
   def test_context_menu_issue_visibility
@@ -241,16 +225,21 @@
     assert_template 'context_menu'
     assert_equal [1], assigns(:issues).collect(&:id)
   end
-  
+
+  def test_should_respond_with_404_without_ids
+    get :issues
+    assert_response 404
+  end
+
   def test_time_entries_context_menu
     @request.session[:user_id] = 2
     get :time_entries, :ids => [1, 2]
     assert_response :success
     assert_template 'time_entries'
-    assert_tag 'a', :content => 'Edit'
-    assert_no_tag 'a', :content => 'Edit', :attributes => {:class => /disabled/}
+
+    assert_select 'a:not(.disabled)', :text => 'Edit'
   end
-  
+
   def test_time_entries_context_menu_without_edit_permission
     @request.session[:user_id] = 2
     Role.find_by_name('Manager').remove_permission! :edit_time_entries
@@ -258,6 +247,6 @@
     get :time_entries, :ids => [1, 2]
     assert_response :success
     assert_template 'time_entries'
-    assert_tag 'a', :content => 'Edit', :attributes => {:class => /disabled/}
+    assert_select 'a.disabled', :text => 'Edit'
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/custom_fields_controller_test.rb
--- a/test/functional/custom_fields_controller_test.rb
+++ b/test/functional/custom_fields_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -56,6 +56,30 @@
     end
   end
 
+  def test_default_value_should_be_an_input_for_string_custom_field
+    get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'string'}
+    assert_response :success
+    assert_select 'input[name=?]', 'custom_field[default_value]'
+  end
+
+  def test_default_value_should_be_a_textarea_for_text_custom_field
+    get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'text'}
+    assert_response :success
+    assert_select 'textarea[name=?]', 'custom_field[default_value]'
+  end
+
+  def test_default_value_should_be_a_checkbox_for_bool_custom_field
+    get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'bool'}
+    assert_response :success
+    assert_select 'input[name=?][type=checkbox]', 'custom_field[default_value]'
+  end
+
+  def test_default_value_should_not_be_present_for_user_custom_field
+    get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'user'}
+    assert_response :success
+    assert_select '[name=?]', 'custom_field[default_value]', 0
+  end
+
   def test_new_js
     get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'list'}, :format => 'js'
     assert_response :success
diff -r 0a574315af3e -r 4f746d8966dd test/functional/documents_controller_test.rb
--- a/test/functional/documents_controller_test.rb
+++ b/test/functional/documents_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/enumerations_controller_test.rb
--- a/test/functional/enumerations_controller_test.rb
+++ b/test/functional/enumerations_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -117,7 +117,7 @@
   end
 
   def test_destroy_enumeration_in_use_with_reassignment
-    issue = Issue.find(:first, :conditions => {:priority_id => 4})
+    issue = Issue.where(:priority_id => 4).first
     assert_difference 'IssuePriority.count', -1 do
       delete :destroy, :id => 4, :reassign_to_id => 6
     end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/files_controller_test.rb
--- a/test/functional/files_controller_test.rb
+++ b/test/functional/files_controller_test.rb
@@ -1,3 +1,20 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../test_helper', __FILE__)
 
 class FilesControllerTest < ActionController::TestCase
@@ -8,15 +25,11 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :journals, :journal_details,
            :attachments,
            :versions
 
   def setup
-    @controller = FilesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     @request.session[:user_id] = nil
     Setting.default_language = 'en'
   end
@@ -68,7 +81,7 @@
       end
     end
     assert_redirected_to '/projects/ecookbook/files'
-    a = Attachment.find(:first, :order => 'created_on DESC')
+    a = Attachment.order('created_on DESC').first
     assert_equal 'testfile.txt', a.filename
     assert_equal Project.find(1), a.container
 
@@ -88,7 +101,7 @@
       assert_response :redirect
     end
     assert_redirected_to '/projects/ecookbook/files'
-    a = Attachment.find(:first, :order => 'created_on DESC')
+    a = Attachment.order('created_on DESC').first
     assert_equal 'testfile.txt', a.filename
     assert_equal Version.find(2), a.container
   end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/gantts_controller_test.rb
--- a/test/functional/gantts_controller_test.rb
+++ b/test/functional/gantts_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,83 +25,98 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :versions
 
-    def test_gantt_should_work
-      i2 = Issue.find(2)
-      i2.update_attribute(:due_date, 1.month.from_now)
-      get :show, :project_id => 1
+  def test_gantt_should_work
+    i2 = Issue.find(2)
+    i2.update_attribute(:due_date, 1.month.from_now)
+    get :show, :project_id => 1
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_not_nil assigns(:gantt)
+    # Issue with start and due dates
+    i = Issue.find(1)
+    assert_not_nil i.due_date
+    assert_select "div a.issue", /##{i.id}/
+    # Issue with on a targeted version should not be in the events but loaded in the html
+    i = Issue.find(2)
+    assert_select "div a.issue", /##{i.id}/
+  end
+
+  def test_gantt_should_work_without_issue_due_dates
+    Issue.update_all("due_date = NULL")
+    get :show, :project_id => 1
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_not_nil assigns(:gantt)
+  end
+
+  def test_gantt_should_work_without_issue_and_version_due_dates
+    Issue.update_all("due_date = NULL")
+    Version.update_all("effective_date = NULL")
+    get :show, :project_id => 1
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_not_nil assigns(:gantt)
+  end
+
+  def test_gantt_should_work_cross_project
+    get :show
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_not_nil assigns(:gantt)
+    assert_not_nil assigns(:gantt).query
+    assert_nil assigns(:gantt).project
+  end
+
+  def test_gantt_should_not_disclose_private_projects
+    get :show
+    assert_response :success
+    assert_template 'gantts/show'
+    assert_tag 'a', :content => /eCookbook/
+    # Root private project
+    assert_no_tag 'a', {:content => /OnlineStore/}
+    # Private children of a public project
+    assert_no_tag 'a', :content => /Private child of eCookbook/
+  end
+
+  def test_gantt_should_display_relations
+    IssueRelation.delete_all
+    issue1 = Issue.generate!(:start_date => 1.day.from_now, :due_date => 3.day.from_now)
+    issue2 = Issue.generate!(:start_date => 1.day.from_now, :due_date => 3.day.from_now)
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => 'precedes')
+
+    get :show
+    assert_response :success
+
+    relations = assigns(:gantt).relations
+    assert_kind_of Hash, relations
+    assert relations.present?
+    assert_select 'div.task_todo[id=?][data-rels*=?]', "task-todo-issue-#{issue1.id}", issue2.id.to_s
+    assert_select 'div.task_todo[id=?]:not([data-rels])', "task-todo-issue-#{issue2.id}"
+  end
+
+  def test_gantt_should_export_to_pdf
+    get :show, :project_id => 1, :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', @response.content_type
+    assert @response.body.starts_with?('%PDF')
+    assert_not_nil assigns(:gantt)
+  end
+
+  def test_gantt_should_export_to_pdf_cross_project
+    get :show, :format => 'pdf'
+    assert_response :success
+    assert_equal 'application/pdf', @response.content_type
+    assert @response.body.starts_with?('%PDF')
+    assert_not_nil assigns(:gantt)
+  end
+
+  if Object.const_defined?(:Magick)
+    def test_gantt_should_export_to_png
+      get :show, :project_id => 1, :format => 'png'
       assert_response :success
-      assert_template 'gantts/show'
-      assert_not_nil assigns(:gantt)
-      # Issue with start and due dates
-      i = Issue.find(1)
-      assert_not_nil i.due_date
-      assert_select "div a.issue", /##{i.id}/
-      # Issue with on a targeted version should not be in the events but loaded in the html
-      i = Issue.find(2)
-      assert_select "div a.issue", /##{i.id}/
+      assert_equal 'image/png', @response.content_type
     end
-
-    def test_gantt_should_work_without_issue_due_dates
-      Issue.update_all("due_date = NULL")
-      get :show, :project_id => 1
-      assert_response :success
-      assert_template 'gantts/show'
-      assert_not_nil assigns(:gantt)
-    end
-
-    def test_gantt_should_work_without_issue_and_version_due_dates
-      Issue.update_all("due_date = NULL")
-      Version.update_all("effective_date = NULL")
-      get :show, :project_id => 1
-      assert_response :success
-      assert_template 'gantts/show'
-      assert_not_nil assigns(:gantt)
-    end
-
-    def test_gantt_should_work_cross_project
-      get :show
-      assert_response :success
-      assert_template 'gantts/show'
-      assert_not_nil assigns(:gantt)
-      assert_not_nil assigns(:gantt).query
-      assert_nil assigns(:gantt).project
-    end
-
-    def test_gantt_should_not_disclose_private_projects
-      get :show
-      assert_response :success
-      assert_template 'gantts/show'
-      assert_tag 'a', :content => /eCookbook/
-      # Root private project
-      assert_no_tag 'a', {:content => /OnlineStore/}
-      # Private children of a public project
-      assert_no_tag 'a', :content => /Private child of eCookbook/
-    end
-
-    def test_gantt_should_export_to_pdf
-      get :show, :project_id => 1, :format => 'pdf'
-      assert_response :success
-      assert_equal 'application/pdf', @response.content_type
-      assert @response.body.starts_with?('%PDF')
-      assert_not_nil assigns(:gantt)
-    end
-
-    def test_gantt_should_export_to_pdf_cross_project
-      get :show, :format => 'pdf'
-      assert_response :success
-      assert_equal 'application/pdf', @response.content_type
-      assert @response.body.starts_with?('%PDF')
-      assert_not_nil assigns(:gantt)
-    end
-
-    if Object.const_defined?(:Magick)
-      def test_gantt_should_export_to_png
-        get :show, :project_id => 1, :format => 'png'
-        assert_response :success
-        assert_equal 'image/png', @response.content_type
-      end
-    end
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/groups_controller_test.rb
--- a/test/functional/groups_controller_test.rb
+++ b/test/functional/groups_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -79,8 +79,11 @@
     get :edit, :id => 10
     assert_response :success
     assert_template 'edit'
-    assert_tag 'div', :attributes => {:id => 'tab-content-users'}
-    assert_tag 'div', :attributes => {:id => 'tab-content-memberships'}
+
+    assert_select 'div#tab-content-users'
+    assert_select 'div#tab-content-memberships' do
+      assert_select 'a', :text => 'Private child of eCookbook'
+    end
   end
 
   def test_update
@@ -192,11 +195,8 @@
   end
 
   def test_autocomplete_for_user
-    get :autocomplete_for_user, :id => 10, :q => 'mis'
+    get :autocomplete_for_user, :id => 10, :q => 'smi', :format => 'js'
     assert_response :success
-    users = assigns(:users)
-    assert_not_nil users
-    assert users.any?
-    assert !users.include?(Group.find(10).users.first)
+    assert_include 'John Smith', response.body
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/issue_categories_controller_test.rb
--- a/test/functional/issue_categories_controller_test.rb
+++ b/test/functional/issue_categories_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,19 +16,12 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'issue_categories_controller'
-
-# Re-raise errors caught by the controller.
-class IssueCategoriesController; def rescue_action(e) raise e end; end
 
 class IssueCategoriesControllerTest < ActionController::TestCase
   fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, :issue_categories,
            :issues
 
   def setup
-    @controller = IssueCategoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
     @request.session[:user_id] = 2
   end
@@ -133,7 +126,7 @@
   end
 
   def test_destroy_category_in_use_with_reassignment
-    issue = Issue.find(:first, :conditions => {:category_id => 1})
+    issue = Issue.where(:category_id => 1).first
     delete :destroy, :id => 1, :todo => 'reassign', :reassign_to_id => 2
     assert_redirected_to '/projects/ecookbook/settings/categories'
     assert_nil IssueCategory.find_by_id(1)
@@ -142,7 +135,7 @@
   end
 
   def test_destroy_category_in_use_without_reassignment
-    issue = Issue.find(:first, :conditions => {:category_id => 1})
+    issue = Issue.where(:category_id => 1).first
     delete :destroy, :id => 1, :todo => 'nullify'
     assert_redirected_to '/projects/ecookbook/settings/categories'
     assert_nil IssueCategory.find_by_id(1)
diff -r 0a574315af3e -r 4f746d8966dd test/functional/issue_relations_controller_test.rb
--- a/test/functional/issue_relations_controller_test.rb
+++ b/test/functional/issue_relations_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -28,7 +28,8 @@
            :issue_relations,
            :enabled_modules,
            :enumerations,
-           :trackers
+           :trackers,
+           :projects_trackers
 
   def setup
     User.current = nil
@@ -87,6 +88,17 @@
     end
   end
 
+  def test_create_follows_relation_should_update_relations_list
+    issue1 = Issue.generate!(:subject => 'Followed issue', :start_date => Date.yesterday, :due_date => Date.today)
+    issue2 = Issue.generate!
+
+    assert_difference 'IssueRelation.count' do
+      xhr :post, :create, :issue_id => issue2.id,
+                 :relation => {:issue_to_id => issue1.id, :relation_type => 'follows', :delay => ''}
+    end
+    assert_match /Followed issue/, response.body
+  end
+
   def test_should_create_relations_with_visible_issues_only
     Setting.cross_project_issue_relations = '1'
     assert_nil Issue.visible(User.find(3)).find_by_id(4)
diff -r 0a574315af3e -r 4f746d8966dd test/functional/issue_statuses_controller_test.rb
--- a/test/functional/issue_statuses_controller_test.rb
+++ b/test/functional/issue_statuses_controller_test.rb
@@ -1,17 +1,26 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../test_helper', __FILE__)
-require 'issue_statuses_controller'
-
-# Re-raise errors caught by the controller.
-class IssueStatusesController; def rescue_action(e) raise e end; end
-
 
 class IssueStatusesControllerTest < ActionController::TestCase
   fixtures :issue_statuses, :issues, :users
 
   def setup
-    @controller = IssueStatusesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
     @request.session[:user_id] = 1 # admin
   end
@@ -45,7 +54,7 @@
       post :create, :issue_status => {:name => 'New status'}
     end
     assert_redirected_to :action => 'index'
-    status = IssueStatus.find(:first, :order => 'id DESC')
+    status = IssueStatus.order('id DESC').first
     assert_equal 'New status', status.name
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/issues_controller_test.rb
--- a/test/functional/issues_controller_test.rb
+++ b/test/functional/issues_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,7 +16,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'issues_controller'
 
 class IssuesControllerTest < ActionController::TestCase
   fixtures :projects,
@@ -48,9 +47,6 @@
   include Redmine::I18n
 
   def setup
-    @controller = IssuesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
@@ -331,7 +327,7 @@
   end
 
   def test_index_with_cross_project_query_in_session_should_show_project_issues
-    q = Query.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
+    q = IssueQuery.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
     @request.session[:query] = {:id => q.id, :project_id => 1}
 
     with_settings :display_subprojects_issues => '0' do
@@ -345,7 +341,7 @@
   end
 
   def test_private_query_should_not_be_available_to_other_users
-    q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
+    q = IssueQuery.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
     @request.session[:user_id] = 3
 
     get :index, :query_id => q.id
@@ -353,7 +349,7 @@
   end
 
   def test_private_query_should_be_available_to_its_user
-    q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
+    q = IssueQuery.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
     @request.session[:user_id] = 2
 
     get :index, :query_id => q.id
@@ -361,7 +357,7 @@
   end
 
   def test_public_query_should_be_available_to_other_users
-    q = Query.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
+    q = IssueQuery.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
     @request.session[:user_id] = 3
 
     get :index, :query_id => q.id
@@ -384,7 +380,7 @@
     assert_equal 'text/csv; header=present', @response.content_type
     assert @response.body.starts_with?("#,")
     lines = @response.body.chomp.split("\n")
-    assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
+    assert_equal assigns(:query).columns.size, lines[0].split(',').size
   end
 
   def test_index_csv_with_project
@@ -395,13 +391,18 @@
   end
 
   def test_index_csv_with_description
-    get :index, :format => 'csv', :description => '1'
-    assert_response :success
-    assert_not_nil assigns(:issues)
-    assert_equal 'text/csv; header=present', @response.content_type
-    assert @response.body.starts_with?("#,")
-    lines = @response.body.chomp.split("\n")
-    assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
+    Issue.generate!(:description => 'test_index_csv_with_description')
+
+    with_settings :default_language => 'en' do
+      get :index, :format => 'csv', :description => '1'
+      assert_response :success
+      assert_not_nil assigns(:issues)
+    end
+
+    assert_equal 'text/csv; header=present', response.content_type
+    headers = response.body.chomp.split("\n").first.split(',')
+    assert_include 'Description', headers
+    assert_include 'test_index_csv_with_description', response.body
   end
 
   def test_index_csv_with_spent_time_column
@@ -420,9 +421,9 @@
     assert_response :success
     assert_not_nil assigns(:issues)
     assert_equal 'text/csv; header=present', @response.content_type
-    assert @response.body.starts_with?("#,")
-    lines = @response.body.chomp.split("\n")
-    assert_equal assigns(:query).available_inline_columns.size + 1, lines[0].split(',').size
+    assert_match /\A#,/, response.body
+    lines = response.body.chomp.split("\n")
+    assert_equal assigns(:query).available_inline_columns.size, lines[0].split(',').size
   end
 
   def test_index_csv_with_multi_column_field
@@ -437,6 +438,25 @@
     assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
   end
 
+  def test_index_csv_should_format_float_custom_fields_with_csv_decimal_separator
+    field = IssueCustomField.create!(:name => 'Float', :is_for_all => true, :tracker_ids => [1], :field_format => 'float')
+    issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id => '185.6'})
+
+    with_settings :default_language => 'fr' do
+      get :index, :format => 'csv', :columns => 'all'
+      assert_response :success
+      issue_line = response.body.chomp.split("\n").map {|line| line.split(';')}.detect {|line| line[0]==issue.id.to_s}
+      assert_include '185,60', issue_line
+    end
+
+    with_settings :default_language => 'en' do
+      get :index, :format => 'csv', :columns => 'all'
+      assert_response :success
+      issue_line = response.body.chomp.split("\n").map {|line| line.split(',')}.detect {|line| line[0]==issue.id.to_s}
+      assert_include '185.60', issue_line
+    end
+  end
+
   def test_index_csv_big_5
     with_settings :default_language => "zh-TW" do
       str_utf8  = "\xe4\xb8\x80\xe6\x9c\x88"
@@ -457,8 +477,8 @@
       if str_utf8.respond_to?(:force_encoding)
         s1.force_encoding('Big5')
       end
-      assert lines[0].include?(s1)
-      assert lines[1].include?(str_big5)
+      assert_include s1, lines[0]
+      assert_include str_big5, lines[1]
     end
   end
 
@@ -670,7 +690,7 @@
 
     # query should use specified columns
     query = assigns(:query)
-    assert_kind_of Query, query
+    assert_kind_of IssueQuery, query
     assert_equal columns, query.column_names.map(&:to_s)
 
     # columns should be stored in session
@@ -692,18 +712,18 @@
 
     # query should use specified columns
     query = assigns(:query)
-    assert_kind_of Query, query
-    assert_equal [:project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
+    assert_kind_of IssueQuery, query
+    assert_equal [:id, :project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
   end
 
   def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
     Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
-    columns = ['tracker', 'subject', 'assigned_to']
+    columns = ['id', 'tracker', 'subject', 'assigned_to']
     get :index, :set_filter => 1, :c => columns
 
     # query should use specified columns
     query = assigns(:query)
-    assert_kind_of Query, query
+    assert_kind_of IssueQuery, query
     assert_equal columns.map(&:to_sym), query.columns.map(&:name)
   end
 
@@ -714,7 +734,7 @@
 
     # query should use specified columns
     query = assigns(:query)
-    assert_kind_of Query, query
+    assert_kind_of IssueQuery, query
     assert_equal columns, query.column_names.map(&:to_s)
 
     assert_select 'table.issues td.cf_2.string'
@@ -899,24 +919,25 @@
     get :show, :id => 1
     assert_response :success
 
-    assert_tag 'form', :attributes => {:id => 'issue-form'}
-    assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
-    assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
-    assert_tag 'input', :attributes => {:name => 'issue[subject]'}
-    assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
-    assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
-    assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
-    assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
-    assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
-    assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
-    assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
-    assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
-    assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]'
+      assert_select 'select[name=?]', 'issue[project_id]'
+      assert_select 'select[name=?]', 'issue[tracker_id]'
+      assert_select 'input[name=?]', 'issue[subject]'
+      assert_select 'textarea[name=?]', 'issue[description]'
+      assert_select 'select[name=?]', 'issue[status_id]'
+      assert_select 'select[name=?]', 'issue[priority_id]'
+      assert_select 'select[name=?]', 'issue[assigned_to_id]'
+      assert_select 'select[name=?]', 'issue[category_id]'
+      assert_select 'select[name=?]', 'issue[fixed_version_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]'
+      assert_select 'input[name=?]', 'issue[start_date]'
+      assert_select 'input[name=?]', 'issue[due_date]'
+      assert_select 'select[name=?]', 'issue[done_ratio]'
+      assert_select 'input[name=?]', 'issue[custom_field_values][2]'
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
+      assert_select 'textarea[name=?]', 'issue[notes]'
+    end
   end
 
   def test_show_should_display_update_form_with_minimal_permissions
@@ -927,24 +948,25 @@
     get :show, :id => 1
     assert_response :success
 
-    assert_tag 'form', :attributes => {:id => 'issue-form'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
-    assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[status_id]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
-    assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
-    assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
-    assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]', 0
+      assert_select 'select[name=?]', 'issue[project_id]', 0
+      assert_select 'select[name=?]', 'issue[tracker_id]', 0
+      assert_select 'input[name=?]', 'issue[subject]', 0
+      assert_select 'textarea[name=?]', 'issue[description]', 0
+      assert_select 'select[name=?]', 'issue[status_id]', 0
+      assert_select 'select[name=?]', 'issue[priority_id]', 0
+      assert_select 'select[name=?]', 'issue[assigned_to_id]', 0
+      assert_select 'select[name=?]', 'issue[category_id]', 0
+      assert_select 'select[name=?]', 'issue[fixed_version_id]', 0
+      assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
+      assert_select 'input[name=?]', 'issue[start_date]', 0
+      assert_select 'input[name=?]', 'issue[due_date]', 0
+      assert_select 'select[name=?]', 'issue[done_ratio]', 0
+      assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
+      assert_select 'textarea[name=?]', 'issue[notes]'
+    end
   end
 
   def test_show_should_display_update_form_with_workflow_permissions
@@ -954,24 +976,25 @@
     get :show, :id => 1
     assert_response :success
 
-    assert_tag 'form', :attributes => {:id => 'issue-form'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
-    assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
-    assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
-    assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
-    assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
-    assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
-    assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]', 0
+      assert_select 'select[name=?]', 'issue[project_id]', 0
+      assert_select 'select[name=?]', 'issue[tracker_id]', 0
+      assert_select 'input[name=?]', 'issue[subject]', 0
+      assert_select 'textarea[name=?]', 'issue[description]', 0
+      assert_select 'select[name=?]', 'issue[status_id]'
+      assert_select 'select[name=?]', 'issue[priority_id]', 0
+      assert_select 'select[name=?]', 'issue[assigned_to_id]'
+      assert_select 'select[name=?]', 'issue[category_id]', 0
+      assert_select 'select[name=?]', 'issue[fixed_version_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
+      assert_select 'input[name=?]', 'issue[start_date]', 0
+      assert_select 'input[name=?]', 'issue[due_date]', 0
+      assert_select 'select[name=?]', 'issue[done_ratio]'
+      assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
+      assert_select 'textarea[name=?]', 'issue[notes]'
+    end
   end
 
   def test_show_should_not_display_update_form_without_permissions
@@ -1004,7 +1027,7 @@
     get :show, :id => 1
 
     assert_select 'form#issue-form[method=post][enctype=multipart/form-data]' do
-      assert_select 'input[type=file][name=?]', 'attachments[1][file]'
+      assert_select 'input[type=file][name=?]', 'attachments[dummy][file]'
     end
   end
 
@@ -1140,7 +1163,7 @@
   end
 
   def test_show_should_display_prev_next_links_with_saved_query_in_session
-    query = Query.create!(:name => 'test', :is_public => true,  :user_id => 1,
+    query = IssueQuery.create!(:name => 'test', :is_public => true,  :user_id => 1,
       :filters => {'status_id' => {:values => ['5'], :operator => '='}},
       :sort_criteria => [['id', 'asc']])
     @request.session[:query] = {:id => query.id, :project_id => nil}
@@ -1232,7 +1255,7 @@
     CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
     CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
 
-    query = Query.create!(:name => 'test', :is_public => true,  :user_id => 1, :filters => {},
+    query = IssueQuery.create!(:name => 'test', :is_public => true,  :user_id => 1, :filters => {},
       :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
     @request.session[:query] = {:id => query.id, :project_id => nil}
 
@@ -1420,33 +1443,41 @@
     assert @response.body.starts_with?('%PDF')
   end
 
+  def test_show_invalid_should_respond_with_404
+    get :show, :id => 999
+    assert_response 404
+  end
+
   def test_get_new
     @request.session[:user_id] = 2
     get :new, :project_id => 1, :tracker_id => 1
     assert_response :success
     assert_template 'new'
 
-    assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
-    assert_tag 'input', :attributes => {:name => 'issue[subject]'}
-    assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
-    assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
-    assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
-    assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
-    assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
-    assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
-    assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
-    assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]'
+      assert_select 'select[name=?]', 'issue[project_id]', 0
+      assert_select 'select[name=?]', 'issue[tracker_id]'
+      assert_select 'input[name=?]', 'issue[subject]'
+      assert_select 'textarea[name=?]', 'issue[description]'
+      assert_select 'select[name=?]', 'issue[status_id]'
+      assert_select 'select[name=?]', 'issue[priority_id]'
+      assert_select 'select[name=?]', 'issue[assigned_to_id]'
+      assert_select 'select[name=?]', 'issue[category_id]'
+      assert_select 'select[name=?]', 'issue[fixed_version_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]'
+      assert_select 'input[name=?]', 'issue[start_date]'
+      assert_select 'input[name=?]', 'issue[due_date]'
+      assert_select 'select[name=?]', 'issue[done_ratio]'
+      assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]'
+    end
 
     # Be sure we don't display inactive IssuePriorities
     assert ! IssuePriority.find(15).active?
-    assert_no_tag :option, :attributes => {:value => '15'},
-                           :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
+    assert_select 'select[name=?]', 'issue[priority_id]' do
+      assert_select 'option[value=15]', 0
+    end
   end
 
   def test_get_new_with_minimal_permissions
@@ -1458,22 +1489,24 @@
     assert_response :success
     assert_template 'new'
 
-    assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
-    assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
-    assert_tag 'input', :attributes => {:name => 'issue[subject]'}
-    assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
-    assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
-    assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
-    assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
-    assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
-    assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
-    assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
-    assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
+    assert_select 'form#issue-form' do
+      assert_select 'input[name=?]', 'issue[is_private]', 0
+      assert_select 'select[name=?]', 'issue[project_id]', 0
+      assert_select 'select[name=?]', 'issue[tracker_id]'
+      assert_select 'input[name=?]', 'issue[subject]'
+      assert_select 'textarea[name=?]', 'issue[description]'
+      assert_select 'select[name=?]', 'issue[status_id]'
+      assert_select 'select[name=?]', 'issue[priority_id]'
+      assert_select 'select[name=?]', 'issue[assigned_to_id]'
+      assert_select 'select[name=?]', 'issue[category_id]'
+      assert_select 'select[name=?]', 'issue[fixed_version_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
+      assert_select 'input[name=?]', 'issue[start_date]'
+      assert_select 'input[name=?]', 'issue[due_date]'
+      assert_select 'select[name=?]', 'issue[done_ratio]'
+      assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
+      assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
+    end
   end
 
   def test_get_new_with_list_custom_field
@@ -1568,8 +1601,7 @@
     get :new, :project_id => 1, :tracker_id => 1
 
     assert_select 'form[id=issue-form][method=post][enctype=multipart/form-data]' do
-      assert_select 'input[name=?][type=file]', 'attachments[1][file]'
-      assert_select 'input[name=?][maxlength=255]', 'attachments[1][description]'
+      assert_select 'input[name=?][type=file]', 'attachments[dummy][file]'
     end
   end
 
@@ -1663,9 +1695,9 @@
     assert_error_tag :content => /No tracker/
   end
 
-  def test_update_new_form
+  def test_update_form_for_new_issue
     @request.session[:user_id] = 2
-    xhr :post, :new, :project_id => 1,
+    xhr :post, :update_form, :project_id => 1,
                      :issue => {:tracker_id => 2,
                                 :subject => 'This is the test_new issue',
                                 :description => 'This is the description',
@@ -1682,14 +1714,14 @@
     assert_equal 'This is the test_new issue', issue.subject
   end
 
-  def test_update_new_form_should_propose_transitions_based_on_initial_status
+  def test_update_form_for_new_issue_should_propose_transitions_based_on_initial_status
     @request.session[:user_id] = 2
     WorkflowTransition.delete_all
     WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
     WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
     WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
 
-    xhr :post, :new, :project_id => 1,
+    xhr :post, :update_form, :project_id => 1,
                      :issue => {:tracker_id => 1,
                                 :status_id => 5,
                                 :subject => 'This is an issue'}
@@ -1720,7 +1752,7 @@
     assert_equal 2, issue.status_id
     assert_equal Date.parse('2010-11-07'), issue.start_date
     assert_nil issue.estimated_hours
-    v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
+    v = issue.custom_values.where(:custom_field_id => 2).first
     assert_not_nil v
     assert_equal 'Value for field 2', v.value
   end
@@ -2082,19 +2114,15 @@
     assert_response :success
     assert_template 'new'
 
-    assert_tag :textarea, :attributes => { :name => 'issue[description]' },
-                          :content => "\nThis is a description"
-    assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
-                        :child => { :tag => 'option', :attributes => { :selected => 'selected',
-                                                                       :value => '6' },
-                                                      :content => 'High' }
+    assert_select 'textarea[name=?]', 'issue[description]', :text => 'This is a description'
+    assert_select 'select[name=?]', 'issue[priority_id]' do
+      assert_select 'option[value=6][selected=selected]', :text => 'High'
+    end
     # Custom fields
-    assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
-                        :child => { :tag => 'option', :attributes => { :selected => 'selected',
-                                                                       :value => 'Oracle' },
-                                                      :content => 'Oracle' }
-    assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
-                                        :value => 'Value for field 2'}
+    assert_select 'select[name=?]', 'issue[custom_field_values][1]' do
+      assert_select 'option[value=Oracle][selected=selected]', :text => 'Oracle'
+    end
+    assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Value for field 2'
   end
 
   def test_post_create_with_failure_should_preserve_watchers
@@ -2107,9 +2135,9 @@
     assert_response :success
     assert_template 'new'
 
-    assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '2', :checked => nil}
-    assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '3', :checked => 'checked'}
-    assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '8', :checked => 'checked'}
+    assert_select 'input[name=?][value=2]:not(checked)', 'issue[watcher_user_ids][]'
+    assert_select 'input[name=?][value=3][checked=checked]', 'issue[watcher_user_ids][]'
+    assert_select 'input[name=?][value=8][checked=checked]', 'issue[watcher_user_ids][]'
   end
 
   def test_post_create_should_ignore_non_safe_attributes
@@ -2163,8 +2191,8 @@
     assert File.exists?(attachment.diskfile)
     assert_nil attachment.container
 
-    assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
-    assert_tag 'span', :content => /testfile.txt/
+    assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
   end
 
   def test_post_create_with_failure_should_keep_saved_attachments
@@ -2182,8 +2210,8 @@
       end
     end
 
-    assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
-    assert_tag 'span', :content => /testfile.txt/
+    assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
   end
 
   def test_post_create_should_attach_saved_attachments
@@ -2218,10 +2246,10 @@
         get :new, :project_id => 1
         assert_response :success
         assert_template 'new'
-        assert_tag :tag => 'select',
-          :attributes => {:name => 'issue[status_id]'},
-          :children => {:count => 1},
-          :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
+        assert_select 'select[name=?]', 'issue[status_id]' do
+          assert_select 'option', 1
+          assert_select 'option[value=?]', IssueStatus.default.id.to_s
+        end
       end
 
       should "accept default status" do
@@ -2349,13 +2377,13 @@
     assert_equal orig.subject, assigns(:issue).subject
     assert assigns(:issue).copy?
 
-    assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
-    assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
-      :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}, :content => 'eCookbook'}
-    assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
-      :child => {:tag => 'option', :attributes => {:value => '2', :selected => nil}, :content => 'OnlineStore'}
-    assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
+    assert_select 'form[id=issue-form][action=/projects/ecookbook/issues]' do
+      assert_select 'select[name=?]', 'issue[project_id]' do
+        assert_select 'option[value=1][selected=selected]', :text => 'eCookbook'
+        assert_select 'option[value=2]:not([selected])', :text => 'OnlineStore'
+      end
+      assert_select 'input[name=copy_from][value=1]'
+    end
 
     # "New issue" menu item should not link to copy
     assert_select '#main-menu a.new-issue[href=/projects/ecookbook/issues/new]'
@@ -2367,7 +2395,7 @@
     assert issue.attachments.count > 0
     get :new, :project_id => 1, :copy_from => 3
 
-    assert_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
+    assert_select 'input[name=copy_attachments][type=checkbox][checked=checked][value=1]'
   end
 
   def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
@@ -2376,7 +2404,7 @@
     issue.attachments.delete_all
     get :new, :project_id => 1, :copy_from => 3
 
-    assert_no_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
+    assert_select 'input[name=copy_attachments]', 0
   end
 
   def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
@@ -2523,13 +2551,13 @@
     assert_not_nil assigns(:issue)
     assert assigns(:issue).copy?
 
-    assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
-    assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
-    assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
-      :child => {:tag => 'option', :attributes => {:value => '1', :selected => nil}, :content => 'eCookbook'}
-    assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
-      :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}, :content => 'OnlineStore'}
-    assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
+    assert_select 'form#issue-form[action=/projects/ecookbook/issues]' do
+      assert_select 'select[name=?]', 'issue[project_id]' do
+        assert_select 'option[value=1]:not([selected])', :text => 'eCookbook'
+        assert_select 'option[value=2][selected=selected]', :text => 'OnlineStore'
+      end
+      assert_select 'input[name=copy_from][value=1]'
+    end
   end
 
   def test_create_as_copy_on_project_without_permission_should_ignore_target_project
@@ -2554,8 +2582,9 @@
 
     # Be sure we don't display inactive IssuePriorities
     assert ! IssuePriority.find(15).active?
-    assert_no_tag :option, :attributes => {:value => '15'},
-                           :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
+    assert_select 'select[name=?]', 'issue[priority_id]' do
+      assert_select 'option[value=15]', 0
+    end
   end
 
   def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
@@ -2563,7 +2592,7 @@
     Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
     
     get :edit, :id => 1
-    assert_tag 'input', :attributes => {:name => 'time_entry[hours]'}
+    assert_select 'input[name=?]', 'time_entry[hours]'
   end
 
   def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
@@ -2571,13 +2600,13 @@
     Role.find_by_name('Manager').remove_permission! :log_time
     
     get :edit, :id => 1
-    assert_no_tag 'input', :attributes => {:name => 'time_entry[hours]'}
+    assert_select 'input[name=?]', 'time_entry[hours]', 0
   end
 
   def test_get_edit_with_params
     @request.session[:user_id] = 2
     get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
-        :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
+        :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => 10 }
     assert_response :success
     assert_template 'edit'
 
@@ -2585,22 +2614,20 @@
     assert_not_nil issue
 
     assert_equal 5, issue.status_id
-    assert_tag :select, :attributes => { :name => 'issue[status_id]' },
-                        :child => { :tag => 'option',
-                                    :content => 'Closed',
-                                    :attributes => { :selected => 'selected' } }
+    assert_select 'select[name=?]', 'issue[status_id]' do
+      assert_select 'option[value=5][selected=selected]', :text => 'Closed'
+    end
 
     assert_equal 7, issue.priority_id
-    assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
-                        :child => { :tag => 'option',
-                                    :content => 'Urgent',
-                                    :attributes => { :selected => 'selected' } }
-
-    assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
-    assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
-                        :child => { :tag => 'option',
-                                    :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
-    assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
+    assert_select 'select[name=?]', 'issue[priority_id]' do
+      assert_select 'option[value=7][selected=selected]', :text => 'Urgent'
+    end
+
+    assert_select 'input[name=?][value=2.5]', 'time_entry[hours]'
+    assert_select 'select[name=?]', 'time_entry[activity_id]' do
+      assert_select 'option[value=10][selected=selected]', :text => 'Development'
+    end
+    assert_select 'input[name=?][value=test_get_edit_with_params]', 'time_entry[comments]'
   end
 
   def test_get_edit_with_multi_custom_field
@@ -2615,18 +2642,17 @@
     assert_response :success
     assert_template 'edit'
 
-    assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]', :multiple => 'multiple'}
-    assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
-      :child => {:tag => 'option', :attributes => {:value => 'MySQL', :selected => 'selected'}}
-    assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
-      :child => {:tag => 'option', :attributes => {:value => 'PostgreSQL', :selected => nil}}
-    assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
-      :child => {:tag => 'option', :attributes => {:value => 'Oracle', :selected => 'selected'}}
+    assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
+      assert_select 'option', 3
+      assert_select 'option[value=MySQL][selected=selected]'
+      assert_select 'option[value=Oracle][selected=selected]'
+      assert_select 'option[value=PostgreSQL]:not([selected])'
+    end
   end
 
-  def test_update_edit_form
+  def test_update_form_for_existing_issue
     @request.session[:user_id] = 2
-    xhr :put, :new, :project_id => 1,
+    xhr :put, :update_form, :project_id => 1,
                              :id => 1,
                              :issue => {:tracker_id => 2,
                                         :subject => 'This is the test_new issue',
@@ -2645,9 +2671,9 @@
     assert_equal 'This is the test_new issue', issue.subject
   end
 
-  def test_update_edit_form_should_keep_issue_author
+  def test_update_form_for_existing_issue_should_keep_issue_author
     @request.session[:user_id] = 3
-    xhr :put, :new, :project_id => 1, :id => 1, :issue => {:subject => 'Changed'}
+    xhr :put, :update_form, :project_id => 1, :id => 1, :issue => {:subject => 'Changed'}
     assert_response :success
     assert_equal 'text/javascript', response.content_type
 
@@ -2657,14 +2683,14 @@
     assert_not_equal User.current, issue.author
   end
 
-  def test_update_edit_form_should_propose_transitions_based_on_initial_status
+  def test_update_form_for_existing_issue_should_propose_transitions_based_on_initial_status
     @request.session[:user_id] = 2
     WorkflowTransition.delete_all
     WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
     WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
     WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
 
-    xhr :put, :new, :project_id => 1,
+    xhr :put, :update_form, :project_id => 1,
                     :id => 2,
                     :issue => {:tracker_id => 2,
                                :status_id => 5,
@@ -2674,9 +2700,9 @@
     assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
   end
 
-  def test_update_edit_form_with_project_change
+  def test_update_form_for_existing_issue_with_project_change
     @request.session[:user_id] = 2
-    xhr :put, :new, :project_id => 1,
+    xhr :put, :update_form, :project_id => 1,
                              :id => 1,
                              :issue => {:project_id => 2,
                                         :tracker_id => 2,
@@ -2831,7 +2857,7 @@
     assert_redirected_to :action => 'show', :id => '1'
     issue.reload
     assert_equal 2, issue.status_id
-    j = Journal.find(:first, :order => 'id DESC')
+    j = Journal.order('id DESC').first
     assert_equal 'Assigned to dlopper', j.notes
     assert_equal 2, j.details.size
 
@@ -2848,7 +2874,7 @@
          :id => 1,
          :issue => { :notes => notes }
     assert_redirected_to :action => 'show', :id => '1'
-    j = Journal.find(:first, :order => 'id DESC')
+    j = Journal.order('id DESC').first
     assert_equal notes, j.notes
     assert_equal 0, j.details.size
     assert_equal User.anonymous, j.user
@@ -2904,7 +2930,7 @@
 
     issue = Issue.find(1)
 
-    j = Journal.find(:first, :order => 'id DESC')
+    j = Journal.order('id DESC').first
     assert_equal '2.5 hours added', j.notes
     assert_equal 0, j.details.size
 
@@ -2943,7 +2969,7 @@
     end
 
     assert_redirected_to :action => 'show', :id => '1'
-    j = Issue.find(1).journals.find(:first, :order => 'id DESC')
+    j = Issue.find(1).journals.reorder('id DESC').first
     assert j.notes.blank?
     assert_equal 1, j.details.size
     assert_equal 'testfile.txt', j.details.first.value
@@ -2982,8 +3008,8 @@
     assert File.exists?(attachment.diskfile)
     assert_nil attachment.container
 
-    assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
-    assert_tag 'span', :content => /testfile.txt/
+    assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
   end
 
   def test_put_update_with_failure_should_keep_saved_attachments
@@ -3001,8 +3027,8 @@
       end
     end
 
-    assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
-    assert_tag 'span', :content => /testfile.txt/
+    assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
   end
 
   def test_put_update_should_attach_saved_attachments
@@ -3092,8 +3118,8 @@
     assert_template 'edit'
 
     assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
-    assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
-    assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
+    assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
+    assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2z'
   end
 
   def test_put_update_with_invalid_spent_time_comments_only
@@ -3111,8 +3137,8 @@
 
     assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
     assert_error_tag :descendant => {:content => /Hours can&#x27;t be blank/}
-    assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
-    assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
+    assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
+    assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'this is my comment'
   end
 
   def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
@@ -3167,23 +3193,34 @@
     assert_response :success
     assert_template 'bulk_edit'
 
-    assert_tag :select, :attributes => {:name => 'issue[project_id]'}
-    assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
-
-    # Project specific custom field, date type
-    field = CustomField.find(9)
-    assert !field.is_for_all?
-    assert_equal 'date', field.field_format
-    assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
-
-    # System wide custom field
-    assert CustomField.find(1).is_for_all?
-    assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
-
-    # Be sure we don't display inactive IssuePriorities
-    assert ! IssuePriority.find(15).active?
-    assert_no_tag :option, :attributes => {:value => '15'},
-                           :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
+    assert_select 'ul#bulk-selection' do
+      assert_select 'li', 2
+      assert_select 'li a', :text => 'Bug #1'
+    end
+
+    assert_select 'form#bulk_edit_form[action=?]', '/issues/bulk_update' do
+      assert_select 'input[name=?]', 'ids[]', 2
+      assert_select 'input[name=?][value=1][type=hidden]', 'ids[]'
+
+      assert_select 'select[name=?]', 'issue[project_id]'
+      assert_select 'input[name=?]', 'issue[parent_issue_id]'
+  
+      # Project specific custom field, date type
+      field = CustomField.find(9)
+      assert !field.is_for_all?
+      assert_equal 'date', field.field_format
+      assert_select 'input[name=?]', 'issue[custom_field_values][9]'
+  
+      # System wide custom field
+      assert CustomField.find(1).is_for_all?
+      assert_select 'select[name=?]', 'issue[custom_field_values][1]'
+  
+      # Be sure we don't display inactive IssuePriorities
+      assert ! IssuePriority.find(15).active?
+      assert_select 'select[name=?]', 'issue[priority_id]' do
+        assert_select 'option[value=15]', 0
+      end
+    end
   end
 
   def test_get_bulk_edit_on_different_projects
@@ -3193,13 +3230,13 @@
     assert_template 'bulk_edit'
 
     # Can not set issues from different projects as children of an issue
-    assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
+    assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
 
     # Project specific custom field, date type
     field = CustomField.find(9)
     assert !field.is_for_all?
     assert !field.project_ids.include?(Issue.find(6).project_id)
-    assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
+    assert_select 'input[name=?]', 'issue[custom_field_values][9]', 0
   end
 
   def test_get_bulk_edit_with_user_custom_field
@@ -3210,12 +3247,9 @@
     assert_response :success
     assert_template 'bulk_edit'
 
-    assert_tag :select,
-      :attributes => {:name => "issue[custom_field_values][#{field.id}]", :class => 'user_cf'},
-      :children => {
-        :only => {:tag => 'option'},
-        :count => Project.find(1).users.count + 2 # "no change" + "none" options
-      }
+    assert_select 'select.user_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
+      assert_select 'option', Project.find(1).users.count + 2 # "no change" + "none" options
+    end
   end
 
   def test_get_bulk_edit_with_version_custom_field
@@ -3226,12 +3260,9 @@
     assert_response :success
     assert_template 'bulk_edit'
 
-    assert_tag :select,
-      :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
-      :children => {
-        :only => {:tag => 'option'},
-        :count => Project.find(1).shared_versions.count + 2 # "no change" + "none" options
-      }
+    assert_select 'select.version_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
+      assert_select 'option', Project.find(1).shared_versions.count + 2 # "no change" + "none" options
+    end
   end
 
   def test_get_bulk_edit_with_multi_custom_field
@@ -3243,12 +3274,9 @@
     assert_response :success
     assert_template 'bulk_edit'
 
-    assert_tag :select,
-      :attributes => {:name => "issue[custom_field_values][1][]"},
-      :children => {
-        :only => {:tag => 'option'},
-        :count => field.possible_values.size + 1 # "none" options
-      }
+    assert_select 'select[name=?]', 'issue[custom_field_values][1][]' do
+      assert_select 'option', field.possible_values.size + 1 # "none" options
+    end
   end
 
   def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
@@ -3267,8 +3295,9 @@
     assert_not_nil statuses
     assert_equal [1, 3], statuses.map(&:id).sort
 
-    assert_tag 'select', :attributes => {:name => 'issue[status_id]'},
-      :children => {:count => 3} # 2 statuses + "no change" option
+    assert_select 'select[name=?]', 'issue[status_id]' do
+      assert_select 'option', 3 # 2 statuses + "no change" option
+    end
   end
 
   def test_bulk_edit_should_propose_target_project_open_shared_versions
@@ -3277,9 +3306,10 @@
     assert_response :success
     assert_template 'bulk_edit'
     assert_equal Project.find(1).shared_versions.open.all.sort, assigns(:versions).sort
-    assert_tag 'select',
-      :attributes => {:name => 'issue[fixed_version_id]'},
-      :descendant => {:tag => 'option', :content => '2.0'}
+
+    assert_select 'select[name=?]', 'issue[fixed_version_id]' do
+      assert_select 'option', :text => '2.0'
+    end
   end
 
   def test_bulk_edit_should_propose_target_project_categories
@@ -3288,9 +3318,10 @@
     assert_response :success
     assert_template 'bulk_edit'
     assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
-    assert_tag 'select',
-      :attributes => {:name => 'issue[category_id]'},
-      :descendant => {:tag => 'option', :content => 'Recipes'}
+
+    assert_select 'select[name=?]', 'issue[category_id]' do
+      assert_select 'option', :text => 'Recipes'
+    end
   end
 
   def test_bulk_update
@@ -3306,7 +3337,7 @@
     assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
 
     issue = Issue.find(1)
-    journal = issue.journals.find(:first, :order => 'created_on DESC')
+    journal = issue.journals.reorder('created_on DESC').first
     assert_equal '125', issue.custom_value_for(2).value
     assert_equal 'Bulk editing', journal.notes
     assert_equal 1, journal.details.size
@@ -3341,7 +3372,7 @@
     assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
 
     issue = Issue.find(1)
-    journal = issue.journals.find(:first, :order => 'created_on DESC')
+    journal = issue.journals.reorder('created_on DESC').first
     assert_equal '125', issue.custom_value_for(2).value
     assert_equal 'Bulk editing', journal.notes
     assert_equal 1, journal.details.size
@@ -3443,6 +3474,8 @@
   end
 
   def test_bulk_update_parent_id
+    IssueRelation.delete_all
+
     @request.session[:user_id] = 2
     post :bulk_update, :ids => [1, 3],
       :notes => 'Bulk editing parent',
@@ -3466,7 +3499,7 @@
     assert_response 302
 
     issue = Issue.find(1)
-    journal = issue.journals.find(:first, :order => 'created_on DESC')
+    journal = issue.journals.reorder('created_on DESC').first
     assert_equal '777', issue.custom_value_for(2).value
     assert_equal 1, journal.details.size
     assert_equal '125', journal.details.first.old_value
@@ -3778,8 +3811,10 @@
     assert_template 'destroy'
     assert_not_nil assigns(:hours)
     assert Issue.find_by_id(1) && Issue.find_by_id(3)
-    assert_tag 'form',
-      :descendant => {:tag => 'input', :attributes => {:name => '_method', :value => 'delete'}}
+
+    assert_select 'form' do
+      assert_select 'input[name=_method][value=delete]'
+    end
   end
 
   def test_destroy_issues_and_destroy_time_entries
@@ -3845,10 +3880,19 @@
     assert_response 302
   end
 
+  def test_destroy_invalid_should_respond_with_404
+    @request.session[:user_id] = 2
+    assert_no_difference 'Issue.count' do
+      delete :destroy, :id => 999
+    end
+    assert_response 404
+  end
+
   def test_default_search_scope
     get :index
-    assert_tag :div, :attributes => {:id => 'quick-search'},
-                     :child => {:tag => 'form',
-                                :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
+
+    assert_select 'div#quick-search form' do
+      assert_select 'input[name=issues][value=1][type=hidden]'
+    end
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/issues_controller_transaction_test.rb
--- a/test/functional/issues_controller_transaction_test.rb
+++ b/test/functional/issues_controller_transaction_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -19,6 +19,7 @@
 require 'issues_controller'
 
 class IssuesControllerTransactionTest < ActionController::TestCase
+  tests IssuesController
   fixtures :projects,
            :users,
            :roles,
@@ -46,9 +47,6 @@
   self.use_transactional_fixtures = false
 
   def setup
-    @controller = IssuesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
@@ -106,7 +104,7 @@
     assert_template 'edit'
     attachment = Attachment.first(:order => 'id DESC')
     assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
-    assert_tag 'span', :content => /testfile.txt/
+    assert_tag 'input', :attributes => {:name => 'attachments[p0][filename]', :value => 'testfile.txt'}
   end
 
   def test_update_stale_issue_without_notes_should_not_show_add_notes_option
@@ -254,7 +252,7 @@
   end
 
   def test_index_should_rescue_invalid_sql_query
-    Query.any_instance.stubs(:statement).returns("INVALID STATEMENT")
+    IssueQuery.any_instance.stubs(:statement).returns("INVALID STATEMENT")
 
     get :index
     assert_response 500
diff -r 0a574315af3e -r 4f746d8966dd test/functional/journals_controller_test.rb
--- a/test/functional/journals_controller_test.rb
+++ b/test/functional/journals_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,19 +16,12 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'journals_controller'
-
-# Re-raise errors caught by the controller.
-class JournalsController; def rescue_action(e) raise e end; end
 
 class JournalsControllerTest < ActionController::TestCase
   fixtures :projects, :users, :members, :member_roles, :roles, :issues, :journals, :journal_details, :enabled_modules,
     :trackers, :issue_statuses, :enumerations, :custom_fields, :custom_values, :custom_fields_projects
 
   def setup
-    @controller = JournalsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/mail_handler_controller_test.rb
--- a/test/functional/mail_handler_controller_test.rb
+++ b/test/functional/mail_handler_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,10 +16,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'mail_handler_controller'
-
-# Re-raise errors caught by the controller.
-class MailHandlerController; def rescue_action(e) raise e end; end
 
 class MailHandlerControllerTest < ActionController::TestCase
   fixtures :users, :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :issue_statuses,
@@ -28,9 +24,6 @@
   FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
 
   def setup
-    @controller = MailHandlerController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/members_controller_test.rb
--- a/test/functional/members_controller_test.rb
+++ b/test/functional/members_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,19 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'members_controller'
-
-# Re-raise errors caught by the controller.
-class MembersController; def rescue_action(e) raise e end; end
-
 
 class MembersControllerTest < ActionController::TestCase
   fixtures :projects, :members, :member_roles, :roles, :users
 
   def setup
-    @controller = MembersController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
     @request.session[:user_id] = 2
   end
@@ -112,11 +104,8 @@
   end
 
   def test_autocomplete
-    get :autocomplete, :project_id => 1, :q => 'mis'
+    get :autocomplete, :project_id => 1, :q => 'mis', :format => 'js'
     assert_response :success
-    assert_template 'autocomplete'
-
-    assert_tag :label, :content => /User Misc/,
-                       :child => { :tag => 'input', :attributes => { :name => 'membership[user_ids][]', :value => '8' } }
+    assert_include 'User Misc', response.body
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/messages_controller_test.rb
--- a/test/functional/messages_controller_test.rb
+++ b/test/functional/messages_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,18 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'messages_controller'
-
-# Re-raise errors caught by the controller.
-class MessagesController; def rescue_action(e) raise e end; end
 
 class MessagesControllerTest < ActionController::TestCase
   fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
 
   def setup
-    @controller = MessagesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
@@ -93,6 +86,12 @@
     assert_template 'new'
   end
 
+  def test_get_new_with_invalid_board
+    @request.session[:user_id] = 2
+    get :new, :board_id => 99
+    assert_response 404
+  end
+
   def test_post_new
     @request.session[:user_id] = 2
     ActionMailer::Base.deliveries.clear
@@ -164,7 +163,7 @@
   def test_reply
     @request.session[:user_id] = 2
     post :reply, :board_id => 1, :id => 1, :reply => { :content => 'This is a test reply', :subject => 'Test reply' }
-    reply = Message.find(:first, :order => 'id DESC')
+    reply = Message.order('id DESC').first
     assert_redirected_to "/boards/1/topics/1?r=#{reply.id}"
     assert Message.find_by_subject('Test reply')
   end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/my_controller_test.rb
--- a/test/functional/my_controller_test.rb
+++ b/test/functional/my_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,20 +16,13 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'my_controller'
-
-# Re-raise errors caught by the controller.
-class MyController; def rescue_action(e) raise e end; end
 
 class MyControllerTest < ActionController::TestCase
   fixtures :users, :user_preferences, :roles, :projects, :members, :member_roles,
   :issues, :issue_statuses, :trackers, :enumerations, :custom_fields, :auth_sources
 
   def setup
-    @controller = MyController.new
-    @request    = ActionController::TestRequest.new
     @request.session[:user_id] = 2
-    @response   = ActionController::TestResponse.new
   end
 
   def test_index
@@ -58,6 +51,17 @@
     end
   end
 
+  def test_page_with_all_blocks
+    blocks = MyController::BLOCKS.keys
+    preferences = User.find(2).pref
+    preferences[:my_page_layout] = {'top' => blocks}
+    preferences.save!
+
+    get :page
+    assert_response :success
+    assert_select 'div.mypage-box', blocks.size
+  end
+
   def test_my_account_should_show_editable_custom_fields
     get :account
     assert_response :success
diff -r 0a574315af3e -r 4f746d8966dd test/functional/news_controller_test.rb
--- a/test/functional/news_controller_test.rb
+++ b/test/functional/news_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,18 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'news_controller'
-
-# Re-raise errors caught by the controller.
-class NewsController; def rescue_action(e) raise e end; end
 
 class NewsControllerTest < ActionController::TestCase
   fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news, :comments
 
   def setup
-    @controller = NewsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/previews_controller_test.rb
--- a/test/functional/previews_controller_test.rb
+++ b/test/functional/previews_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,7 +25,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :journals, :journal_details,
            :news
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/project_enumerations_controller_test.rb
--- a/test/functional/project_enumerations_controller_test.rb
+++ b/test/functional/project_enumerations_controller_test.rb
@@ -1,3 +1,20 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../test_helper', __FILE__)
 
 class ProjectEnumerationsControllerTest < ActionController::TestCase
@@ -8,7 +25,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :custom_fields, :custom_fields_projects,
            :custom_fields_trackers, :custom_values,
            :time_entries
@@ -75,14 +91,14 @@
 
     project_activity = TimeEntryActivity.new({
                                                :name => 'Project Specific',
-                                               :parent => TimeEntryActivity.find(:first),
+                                               :parent => TimeEntryActivity.first,
                                                :project => Project.find(1),
                                                :active => true
                                              })
     assert project_activity.save
     project_activity_two = TimeEntryActivity.new({
                                                    :name => 'Project Specific Two',
-                                                   :parent => TimeEntryActivity.find(:last),
+                                                   :parent => TimeEntryActivity.last,
                                                    :project => Project.find(1),
                                                    :active => true
                                                  })
@@ -156,14 +172,14 @@
     @request.session[:user_id] = 2 # manager
     project_activity = TimeEntryActivity.new({
                                                :name => 'Project Specific',
-                                               :parent => TimeEntryActivity.find(:first),
+                                               :parent => TimeEntryActivity.first,
                                                :project => Project.find(1),
                                                :active => true
                                              })
     assert project_activity.save
     project_activity_two = TimeEntryActivity.new({
                                                    :name => 'Project Specific Two',
-                                                   :parent => TimeEntryActivity.find(:last),
+                                                   :parent => TimeEntryActivity.last,
                                                    :project => Project.find(1),
                                                    :active => true
                                                  })
diff -r 0a574315af3e -r 4f746d8966dd test/functional/projects_controller_test.rb
--- a/test/functional/projects_controller_test.rb
+++ b/test/functional/projects_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,10 +16,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'projects_controller'
-
-# Re-raise errors caught by the controller.
-class ProjectsController; def rescue_action(e) raise e end; end
 
 class ProjectsControllerTest < ActionController::TestCase
   fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
@@ -27,29 +23,27 @@
            :attachments, :custom_fields, :custom_values, :time_entries
 
   def setup
-    @controller = ProjectsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     @request.session[:user_id] = nil
     Setting.default_language = 'en'
   end
 
-  def test_index
+  def test_index_by_anonymous_should_not_show_private_projects
     get :index
     assert_response :success
     assert_template 'index'
-    assert_not_nil assigns(:projects)
+    projects = assigns(:projects)
+    assert_not_nil projects
+    assert projects.all?(&:is_public?)
 
-    assert_tag :ul, :child => {:tag => 'li',
-                               :descendant => {:tag => 'a', :content => 'eCookbook'},
-                               :child => { :tag => 'ul',
-                                           :descendant => { :tag => 'a',
-                                                            :content => 'Child of private child'
-                                                           }
-                                          }
-                               }
-
-    assert_no_tag :a, :content => /Private child of eCookbook/
+    assert_select 'ul' do
+      assert_select 'li' do
+        assert_select 'a', :text => 'eCookbook'
+        assert_select 'ul' do
+          assert_select 'a', :text => 'Child of private child'
+        end
+      end
+    end
+    assert_select 'a', :text => /Private child of eCookbook/, :count => 0
   end
 
   def test_index_atom
@@ -60,239 +54,237 @@
     assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_condition(User.current))
   end
 
-  context "#index" do
-    context "by non-admin user with view_time_entries permission" do
-      setup do
-        @request.session[:user_id] = 3
-      end
-      should "show overall spent time link" do
-        get :index
-        assert_template 'index'
-        assert_tag :a, :attributes => {:href => '/time_entries'}
-      end
-    end
+  test "#index by non-admin user with view_time_entries permission should show overall spent time link" do
+    @request.session[:user_id] = 3
+    get :index
+    assert_template 'index'
+    assert_select 'a[href=?]', '/time_entries'
+  end
 
-    context "by non-admin user without view_time_entries permission" do
-      setup do
-        Role.find(2).remove_permission! :view_time_entries
-        Role.non_member.remove_permission! :view_time_entries
-        Role.anonymous.remove_permission! :view_time_entries
-        @request.session[:user_id] = 3
-      end
-      should "not show overall spent time link" do
-        get :index
-        assert_template 'index'
-        assert_no_tag :a, :attributes => {:href => '/time_entries'}
-      end
+  test "#index by non-admin user without view_time_entries permission should not show overall spent time link" do
+    Role.find(2).remove_permission! :view_time_entries
+    Role.non_member.remove_permission! :view_time_entries
+    Role.anonymous.remove_permission! :view_time_entries
+    @request.session[:user_id] = 3
+
+    get :index
+    assert_template 'index'
+    assert_select 'a[href=?]', '/time_entries', 0
+  end
+
+  test "#new by admin user should accept get" do
+    @request.session[:user_id] = 1
+
+    get :new
+    assert_response :success
+    assert_template 'new'
+  end
+
+  test "#new by non-admin user with add_project permission should accept get" do
+    Role.non_member.add_permission! :add_project
+    @request.session[:user_id] = 9
+
+    get :new
+    assert_response :success
+    assert_template 'new'
+    assert_select 'select[name=?]', 'project[parent_id]', 0
+  end
+
+  test "#new by non-admin user with add_subprojects permission should accept get" do
+    Role.find(1).remove_permission! :add_project
+    Role.find(1).add_permission! :add_subprojects
+    @request.session[:user_id] = 2
+
+    get :new, :parent_id => 'ecookbook'
+    assert_response :success
+    assert_template 'new'
+
+    assert_select 'select[name=?]', 'project[parent_id]' do
+      # parent project selected
+      assert_select 'option[value=1][selected=selected]'
+      # no empty value
+      assert_select 'option[value=]', 0
     end
   end
 
-  context "#new" do
-    context "by admin user" do
-      setup do
-        @request.session[:user_id] = 1
-      end
+  test "#create by admin user should create a new project" do
+    @request.session[:user_id] = 1
 
-      should "accept get" do
-        get :new
-        assert_response :success
-        assert_template 'new'
-      end
+    post :create,
+      :project => {
+        :name => "blog",
+        :description => "weblog",
+        :homepage => 'http://weblog',
+        :identifier => "blog",
+        :is_public => 1,
+        :custom_field_values => { '3' => 'Beta' },
+        :tracker_ids => ['1', '3'],
+        # an issue custom field that is not for all project
+        :issue_custom_field_ids => ['9'],
+        :enabled_module_names => ['issue_tracking', 'news', 'repository']
+      }
+    assert_redirected_to '/projects/blog/settings'
 
+    project = Project.find_by_name('blog')
+    assert_kind_of Project, project
+    assert project.active?
+    assert_equal 'weblog', project.description
+    assert_equal 'http://weblog', project.homepage
+    assert_equal true, project.is_public?
+    assert_nil project.parent
+    assert_equal 'Beta', project.custom_value_for(3).value
+    assert_equal [1, 3], project.trackers.map(&:id).sort
+    assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
+    assert project.issue_custom_fields.include?(IssueCustomField.find(9))
+  end
+
+  test "#create by admin user should create a new subproject" do
+    @request.session[:user_id] = 1
+
+    assert_difference 'Project.count' do
+      post :create, :project => { :name => "blog",
+                               :description => "weblog",
+                               :identifier => "blog",
+                               :is_public => 1,
+                               :custom_field_values => { '3' => 'Beta' },
+                               :parent_id => 1
+                              }
+      assert_redirected_to '/projects/blog/settings'
     end
 
-    context "by non-admin user with add_project permission" do
-      setup do
-        Role.non_member.add_permission! :add_project
-        @request.session[:user_id] = 9
-      end
+    project = Project.find_by_name('blog')
+    assert_kind_of Project, project
+    assert_equal Project.find(1), project.parent
+  end
 
-      should "accept get" do
-        get :new
-        assert_response :success
-        assert_template 'new'
-        assert_no_tag :select, :attributes => {:name => 'project[parent_id]'}
-      end
+  test "#create by admin user should continue" do
+    @request.session[:user_id] = 1
+
+    assert_difference 'Project.count' do
+      post :create, :project => {:name => "blog", :identifier => "blog"}, :continue => 'Create and continue'
+    end
+    assert_redirected_to '/projects/new'
+  end
+
+  test "#create by non-admin user with add_project permission should create a new project" do
+    Role.non_member.add_permission! :add_project
+    @request.session[:user_id] = 9
+
+    post :create, :project => { :name => "blog",
+                             :description => "weblog",
+                             :identifier => "blog",
+                             :is_public => 1,
+                             :custom_field_values => { '3' => 'Beta' },
+                             :tracker_ids => ['1', '3'],
+                             :enabled_module_names => ['issue_tracking', 'news', 'repository']
+                            }
+
+    assert_redirected_to '/projects/blog/settings'
+
+    project = Project.find_by_name('blog')
+    assert_kind_of Project, project
+    assert_equal 'weblog', project.description
+    assert_equal true, project.is_public?
+    assert_equal [1, 3], project.trackers.map(&:id).sort
+    assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
+
+    # User should be added as a project member
+    assert User.find(9).member_of?(project)
+    assert_equal 1, project.members.size
+  end
+
+  test "#create by non-admin user with add_project permission should fail with parent_id" do
+    Role.non_member.add_permission! :add_project
+    @request.session[:user_id] = 9
+
+    assert_no_difference 'Project.count' do
+      post :create, :project => { :name => "blog",
+                               :description => "weblog",
+                               :identifier => "blog",
+                               :is_public => 1,
+                               :custom_field_values => { '3' => 'Beta' },
+                               :parent_id => 1
+                              }
+    end
+    assert_response :success
+    project = assigns(:project)
+    assert_kind_of Project, project
+    assert_not_nil project.errors[:parent_id]
+  end
+
+  test "#create by non-admin user with add_subprojects permission should create a project with a parent_id" do
+    Role.find(1).remove_permission! :add_project
+    Role.find(1).add_permission! :add_subprojects
+    @request.session[:user_id] = 2
+
+    post :create, :project => { :name => "blog",
+                             :description => "weblog",
+                             :identifier => "blog",
+                             :is_public => 1,
+                             :custom_field_values => { '3' => 'Beta' },
+                             :parent_id => 1
+                            }
+    assert_redirected_to '/projects/blog/settings'
+    project = Project.find_by_name('blog')
+  end
+
+  test "#create by non-admin user with add_subprojects permission should fail without parent_id" do
+    Role.find(1).remove_permission! :add_project
+    Role.find(1).add_permission! :add_subprojects
+    @request.session[:user_id] = 2
+
+    assert_no_difference 'Project.count' do
+      post :create, :project => { :name => "blog",
+                               :description => "weblog",
+                               :identifier => "blog",
+                               :is_public => 1,
+                               :custom_field_values => { '3' => 'Beta' }
+                              }
+    end
+    assert_response :success
+    project = assigns(:project)
+    assert_kind_of Project, project
+    assert_not_nil project.errors[:parent_id]
+  end
+
+  test "#create by non-admin user with add_subprojects permission should fail with unauthorized parent_id" do
+    Role.find(1).remove_permission! :add_project
+    Role.find(1).add_permission! :add_subprojects
+    @request.session[:user_id] = 2
+
+    assert !User.find(2).member_of?(Project.find(6))
+    assert_no_difference 'Project.count' do
+      post :create, :project => { :name => "blog",
+                               :description => "weblog",
+                               :identifier => "blog",
+                               :is_public => 1,
+                               :custom_field_values => { '3' => 'Beta' },
+                               :parent_id => 6
+                              }
+    end
+    assert_response :success
+    project = assigns(:project)
+    assert_kind_of Project, project
+    assert_not_nil project.errors[:parent_id]
+  end
+
+  def test_create_subproject_with_inherit_members_should_inherit_members
+    Role.find_by_name('Manager').add_permission! :add_subprojects
+    parent = Project.find(1)
+    @request.session[:user_id] = 2
+
+    assert_difference 'Project.count' do
+      post :create, :project => {
+        :name => 'inherited', :identifier => 'inherited', :parent_id => parent.id, :inherit_members => '1'
+      }
+      assert_response 302
     end
 
-    context "by non-admin user with add_subprojects permission" do
-      setup do
-        Role.find(1).remove_permission! :add_project
-        Role.find(1).add_permission! :add_subprojects
-        @request.session[:user_id] = 2
-      end
-
-      should "accept get" do
-        get :new, :parent_id => 'ecookbook'
-        assert_response :success
-        assert_template 'new'
-        # parent project selected
-        assert_tag :select, :attributes => {:name => 'project[parent_id]'},
-                            :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}}
-        # no empty value
-        assert_no_tag :select, :attributes => {:name => 'project[parent_id]'},
-                               :child => {:tag => 'option', :attributes => {:value => ''}}
-      end
-    end
-
-  end
-
-  context "POST :create" do
-    context "by admin user" do
-      setup do
-        @request.session[:user_id] = 1
-      end
-
-      should "create a new project" do
-        post :create,
-          :project => {
-            :name => "blog",
-            :description => "weblog",
-            :homepage => 'http://weblog',
-            :identifier => "blog",
-            :is_public => 1,
-            :custom_field_values => { '3' => 'Beta' },
-            :tracker_ids => ['1', '3'],
-            # an issue custom field that is not for all project
-            :issue_custom_field_ids => ['9'],
-            :enabled_module_names => ['issue_tracking', 'news', 'repository']
-          }
-        assert_redirected_to '/projects/blog/settings'
-
-        project = Project.find_by_name('blog')
-        assert_kind_of Project, project
-        assert project.active?
-        assert_equal 'weblog', project.description
-        assert_equal 'http://weblog', project.homepage
-        assert_equal true, project.is_public?
-        assert_nil project.parent
-        assert_equal 'Beta', project.custom_value_for(3).value
-        assert_equal [1, 3], project.trackers.map(&:id).sort
-        assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
-        assert project.issue_custom_fields.include?(IssueCustomField.find(9))
-      end
-
-      should "create a new subproject" do
-        post :create, :project => { :name => "blog",
-                                 :description => "weblog",
-                                 :identifier => "blog",
-                                 :is_public => 1,
-                                 :custom_field_values => { '3' => 'Beta' },
-                                 :parent_id => 1
-                                }
-        assert_redirected_to '/projects/blog/settings'
-
-        project = Project.find_by_name('blog')
-        assert_kind_of Project, project
-        assert_equal Project.find(1), project.parent
-      end
-
-      should "continue" do
-        assert_difference 'Project.count' do
-          post :create, :project => {:name => "blog", :identifier => "blog"}, :continue => 'Create and continue'
-        end
-        assert_redirected_to '/projects/new?'
-      end
-    end
-
-    context "by non-admin user with add_project permission" do
-      setup do
-        Role.non_member.add_permission! :add_project
-        @request.session[:user_id] = 9
-      end
-
-      should "accept create a Project" do
-        post :create, :project => { :name => "blog",
-                                 :description => "weblog",
-                                 :identifier => "blog",
-                                 :is_public => 1,
-                                 :custom_field_values => { '3' => 'Beta' },
-                                 :tracker_ids => ['1', '3'],
-                                 :enabled_module_names => ['issue_tracking', 'news', 'repository']
-                                }
-
-        assert_redirected_to '/projects/blog/settings'
-
-        project = Project.find_by_name('blog')
-        assert_kind_of Project, project
-        assert_equal 'weblog', project.description
-        assert_equal true, project.is_public?
-        assert_equal [1, 3], project.trackers.map(&:id).sort
-        assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
-
-        # User should be added as a project member
-        assert User.find(9).member_of?(project)
-        assert_equal 1, project.members.size
-      end
-
-      should "fail with parent_id" do
-        assert_no_difference 'Project.count' do
-          post :create, :project => { :name => "blog",
-                                   :description => "weblog",
-                                   :identifier => "blog",
-                                   :is_public => 1,
-                                   :custom_field_values => { '3' => 'Beta' },
-                                   :parent_id => 1
-                                  }
-        end
-        assert_response :success
-        project = assigns(:project)
-        assert_kind_of Project, project
-        assert_not_nil project.errors[:parent_id]
-      end
-    end
-
-    context "by non-admin user with add_subprojects permission" do
-      setup do
-        Role.find(1).remove_permission! :add_project
-        Role.find(1).add_permission! :add_subprojects
-        @request.session[:user_id] = 2
-      end
-
-      should "create a project with a parent_id" do
-        post :create, :project => { :name => "blog",
-                                 :description => "weblog",
-                                 :identifier => "blog",
-                                 :is_public => 1,
-                                 :custom_field_values => { '3' => 'Beta' },
-                                 :parent_id => 1
-                                }
-        assert_redirected_to '/projects/blog/settings'
-        project = Project.find_by_name('blog')
-      end
-
-      should "fail without parent_id" do
-        assert_no_difference 'Project.count' do
-          post :create, :project => { :name => "blog",
-                                   :description => "weblog",
-                                   :identifier => "blog",
-                                   :is_public => 1,
-                                   :custom_field_values => { '3' => 'Beta' }
-                                  }
-        end
-        assert_response :success
-        project = assigns(:project)
-        assert_kind_of Project, project
-        assert_not_nil project.errors[:parent_id]
-      end
-
-      should "fail with unauthorized parent_id" do
-        assert !User.find(2).member_of?(Project.find(6))
-        assert_no_difference 'Project.count' do
-          post :create, :project => { :name => "blog",
-                                   :description => "weblog",
-                                   :identifier => "blog",
-                                   :is_public => 1,
-                                   :custom_field_values => { '3' => 'Beta' },
-                                   :parent_id => 6
-                                  }
-        end
-        assert_response :success
-        project = assigns(:project)
-        assert_kind_of Project, project
-        assert_not_nil project.errors[:parent_id]
-      end
-    end
+    project = Project.order('id desc').first
+    assert_equal 'inherited', project.name
+    assert_equal parent, project.parent
+    assert project.memberships.count > 0
+    assert_equal parent.memberships.count, project.memberships.count
   end
 
   def test_create_should_preserve_modules_on_validation_failure
@@ -325,7 +317,7 @@
     assert_not_nil assigns(:project)
     assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
 
-    assert_tag 'li', :content => /Development status/
+    assert_select 'li', :text => /Development status/
   end
 
   def test_show_should_not_display_hidden_custom_fields
@@ -335,7 +327,7 @@
     assert_template 'show'
     assert_not_nil assigns(:project)
 
-    assert_no_tag 'li', :content => /Development status/
+    assert_select 'li', :text => /Development status/, :count => 0
   end
 
   def test_show_should_not_fail_when_custom_values_are_nil
@@ -355,22 +347,22 @@
     get :show, :id => 'ecookbook'
     assert_response 403
     assert_nil assigns(:project)
-    assert_tag :tag => 'p', :content => /archived/
+    assert_select 'p', :text => /archived/
   end
 
-  def test_private_subprojects_hidden
+  def test_show_should_not_show_private_subprojects_that_are_not_visible
     get :show, :id => 'ecookbook'
     assert_response :success
     assert_template 'show'
-    assert_no_tag :tag => 'a', :content => /Private child/
+    assert_select 'a', :text => /Private child/, :count => 0
   end
 
-  def test_private_subprojects_visible
+  def test_show_should_show_private_subprojects_that_are_visible
     @request.session[:user_id] = 2 # manager who is a member of the private subproject
     get :show, :id => 'ecookbook'
     assert_response :success
     assert_template 'show'
-    assert_tag :tag => 'a', :content => /Private child/
+    assert_select 'a', :text => /Private child/
   end
 
   def test_settings
@@ -380,6 +372,15 @@
     assert_template 'settings'
   end
 
+  def test_settings_of_subproject
+    @request.session[:user_id] = 2
+    get :settings, :id => 'private-child'
+    assert_response :success
+    assert_template 'settings'
+
+    assert_select 'input[type=checkbox][name=?]', 'project[inherit_members]'
+  end
+
   def test_settings_should_be_denied_for_member_on_closed_project
     Project.find(1).close
     @request.session[:user_id] = 2 # manager
@@ -438,22 +439,37 @@
     assert_equal ['documents', 'issue_tracking', 'repository'], Project.find(1).enabled_module_names.sort
   end
 
-  def test_destroy_without_confirmation
+  def test_destroy_leaf_project_without_confirmation_should_show_confirmation
     @request.session[:user_id] = 1 # admin
-    delete :destroy, :id => 1
-    assert_response :success
-    assert_template 'destroy'
-    assert_not_nil Project.find_by_id(1)
-    assert_tag :tag => 'strong',
-               :content => ['Private child of eCookbook',
+
+    assert_no_difference 'Project.count' do
+      delete :destroy, :id => 2
+      assert_response :success
+      assert_template 'destroy'
+    end
+  end
+
+  def test_destroy_without_confirmation_should_show_confirmation_with_subprojects
+    @request.session[:user_id] = 1 # admin
+
+    assert_no_difference 'Project.count' do
+      delete :destroy, :id => 1
+      assert_response :success
+      assert_template 'destroy'
+    end
+    assert_select 'strong',
+                  :text => ['Private child of eCookbook',
                             'Child of private child, eCookbook Subproject 1',
                             'eCookbook Subproject 2'].join(', ')
   end
 
-  def test_destroy
+  def test_destroy_with_confirmation_should_destroy_the_project_and_subprojects
     @request.session[:user_id] = 1 # admin
-    delete :destroy, :id => 1, :confirm => 1
-    assert_redirected_to '/admin/projects'
+
+    assert_difference 'Project.count', -5 do
+      delete :destroy, :id => 1, :confirm => 1
+      assert_redirected_to '/admin/projects'
+    end
     assert_nil Project.find_by_id(1)
   end
 
@@ -499,12 +515,11 @@
     CustomField.delete_all
     parent = nil
     6.times do |i|
-      p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")
-      p.set_parent!(parent)
+      p = Project.generate_with_parent!(parent)
       get :show, :id => p
-      assert_tag :h1, :parent => { :attributes => {:id => 'header'}},
-                      :children => { :count => [i, 3].min,
-                                     :only => { :tag => 'a' } }
+      assert_select '#header h1' do
+        assert_select 'a', :count => [i, 3].min
+      end
 
       parent = p
     end
@@ -519,8 +534,7 @@
     assert_equal Project.find(1).description, assigns(:project).description
     assert_nil assigns(:project).id
 
-    assert_tag :tag => 'input',
-      :attributes => {:name => 'project[enabled_module_names][]', :value => 'issue_tracking'}
+    assert_select 'input[name=?][value=?]', 'project[enabled_module_names][]', 'issue_tracking', 1
   end
 
   def test_get_copy_with_invalid_source_should_respond_with_404
diff -r 0a574315af3e -r 4f746d8966dd test/functional/queries_controller_test.rb
--- a/test/functional/queries_controller_test.rb
+++ b/test/functional/queries_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,6 +24,12 @@
     User.current = nil
   end
 
+  def test_index
+    get :index
+    # HTML response not implemented
+    assert_response 406
+  end
+
   def test_new_project_query
     @request.session[:user_id] = 2
     get :new, :project_id => 1
@@ -108,7 +114,7 @@
     assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
     assert !q.is_public?
     assert !q.has_default_columns?
-    assert_equal [:tracker, :subject, :priority, :category], q.columns.collect {|c| c.name}
+    assert_equal [:id, :tracker, :subject, :priority, :category], q.columns.collect {|c| c.name}
     assert q.valid?
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/reports_controller_test.rb
--- a/test/functional/reports_controller_test.rb
+++ b/test/functional/reports_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,12 +25,8 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :versions
 
-  def setup
-  end
-
   def test_get_issue_report
     get :issue_report, :id => 1
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/repositories_bazaar_controller_test.rb
--- a/test/functional/repositories_bazaar_controller_test.rb
+++ b/test/functional/repositories_bazaar_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/repositories_controller_test.rb
--- a/test/functional/repositories_controller_test.rb
+++ b/test/functional/repositories_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,10 +16,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'repositories_controller'
-
-# Re-raise errors caught by the controller.
-class RepositoriesController; def rescue_action(e) raise e end; end
 
 class RepositoriesControllerTest < ActionController::TestCase
   fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
@@ -27,9 +23,6 @@
            :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
 
   def setup
-    @controller = RepositoriesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/repositories_cvs_controller_test.rb
--- a/test/functional/repositories_cvs_controller_test.rb
+++ b/test/functional/repositories_cvs_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/repositories_darcs_controller_test.rb
--- a/test/functional/repositories_darcs_controller_test.rb
+++ b/test/functional/repositories_darcs_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/repositories_filesystem_controller_test.rb
--- a/test/functional/repositories_filesystem_controller_test.rb
+++ b/test/functional/repositories_filesystem_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -109,7 +109,8 @@
     end
 
     def test_show_utf16
-      with_settings :repositories_encodings => 'UTF-16' do
+      enc = (RUBY_VERSION == "1.9.2" ? 'UTF-16LE' : 'UTF-16')
+      with_settings :repositories_encodings => enc do
         get :entry, :id => PRJ_ID,
             :path => repository_path_hash(['japanese', 'utf-16.txt'])[:param]
         assert_response :success
diff -r 0a574315af3e -r 4f746d8966dd test/functional/repositories_git_controller_test.rb
--- a/test/functional/repositories_git_controller_test.rb
+++ b/test/functional/repositories_git_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/repositories_mercurial_controller_test.rb
--- a/test/functional/repositories_mercurial_controller_test.rb
+++ b/test/functional/repositories_mercurial_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/repositories_subversion_controller_test.rb
--- a/test/functional/repositories_subversion_controller_test.rb
+++ b/test/functional/repositories_subversion_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/roles_controller_test.rb
--- a/test/functional/roles_controller_test.rb
+++ b/test/functional/roles_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -21,9 +21,6 @@
   fixtures :roles, :users, :members, :member_roles, :workflows, :trackers
 
   def setup
-    @controller = RolesController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
     @request.session[:user_id] = 1 # admin
   end
@@ -34,7 +31,7 @@
     assert_template 'index'
 
     assert_not_nil assigns(:roles)
-    assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
+    assert_equal Role.order('builtin, position').all, assigns(:roles)
 
     assert_tag :tag => 'a', :attributes => { :href => '/roles/1/edit' },
                             :content => 'Manager'
@@ -163,7 +160,7 @@
     assert_template 'permissions'
 
     assert_not_nil assigns(:roles)
-    assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
+    assert_equal Role.order('builtin, position').all, assigns(:roles)
 
     assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
                                                  :name => 'permissions[3][]',
diff -r 0a574315af3e -r 4f746d8966dd test/functional/search_controller_test.rb
--- a/test/functional/search_controller_test.rb
+++ b/test/functional/search_controller_test.rb
@@ -1,8 +1,21 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../test_helper', __FILE__)
-require 'search_controller'
-
-# Re-raise errors caught by the controller.
-class SearchController; def rescue_action(e) raise e end; end
 
 class SearchControllerTest < ActionController::TestCase
   fixtures :projects, :enabled_modules, :roles, :users, :members, :member_roles,
@@ -11,9 +24,6 @@
            :repositories, :changesets
 
   def setup
-    @controller = SearchController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/sessions_test.rb
--- a/test/functional/sessions_test.rb
+++ b/test/functional/sessions_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/functional/settings_controller_test.rb
--- a/test/functional/settings_controller_test.rb
+++ b/test/functional/settings_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,18 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'settings_controller'
-
-# Re-raise errors caught by the controller.
-class SettingsController; def rescue_action(e) raise e end; end
 
 class SettingsControllerTest < ActionController::TestCase
   fixtures :users
 
   def setup
-    @controller = SettingsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
     @request.session[:user_id] = 1 # admin
   end
@@ -79,7 +72,7 @@
                               :notified_events => %w(issue_added issue_updated news_added),
                               :emails_footer => 'Test footer'
                               }
-    assert_redirected_to '/settings/edit'
+    assert_redirected_to '/settings'
     assert_equal 'functional@test.foo', Setting.mail_from
     assert !Setting.bcc_recipients?
     assert_equal %w(issue_added issue_updated news_added), Setting.notified_events
@@ -108,11 +101,31 @@
     assert_response 404
   end
 
+  def test_get_non_configurable_plugin_settings
+    Redmine::Plugin.register(:foo) {}
+
+    get :plugin, :id => 'foo'
+    assert_response 404
+
+    Redmine::Plugin.clear
+  end
+
   def test_post_plugin_settings
     Setting.expects(:plugin_foo=).with({'sample_setting' => 'Value'}).returns(true)
-    Redmine::Plugin.register(:foo) {}
+    Redmine::Plugin.register(:foo) do
+      settings :partial => 'not blank' # so that configurable? is true
+    end
 
     post :plugin, :id => 'foo', :settings => {'sample_setting' => 'Value'}
     assert_redirected_to '/settings/plugin/foo'
   end
+
+  def test_post_non_configurable_plugin_settings
+    Redmine::Plugin.register(:foo) {}
+
+    post :plugin, :id => 'foo', :settings => {'sample_setting' => 'Value'}
+    assert_response 404
+
+    Redmine::Plugin.clear
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/sys_controller_test.rb
--- a/test/functional/sys_controller_test.rb
+++ b/test/functional/sys_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,19 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'sys_controller'
-require 'mocha'
-
-# Re-raise errors caught by the controller.
-class SysController; def rescue_action(e) raise e end; end
 
 class SysControllerTest < ActionController::TestCase
   fixtures :projects, :repositories, :enabled_modules
 
   def setup
-    @controller = SysController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     Setting.sys_api_enabled = '1'
     Setting.enabled_scm = %w(Subversion Git)
   end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/time_entry_reports_controller_test.rb
--- a/test/functional/time_entry_reports_controller_test.rb
+++ b/test/functional/time_entry_reports_controller_test.rb
@@ -1,4 +1,21 @@
 # -*- coding: utf-8 -*-
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../test_helper', __FILE__)
 
 class TimeEntryReportsControllerTest < ActionController::TestCase
@@ -73,7 +90,7 @@
   end
 
   def test_report_two_criteria
-    get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criteria => ["member", "activity"]
+    get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criteria => ["user", "activity"]
     assert_response :success
     assert_template 'report'
     assert_not_nil assigns(:report)
@@ -91,7 +108,7 @@
   end
 
   def test_report_one_day
-    get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criteria => ["member", "activity"]
+    get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criteria => ["user", "activity"]
     assert_response :success
     assert_template 'report'
     assert_not_nil assigns(:report)
@@ -99,7 +116,7 @@
   end
 
   def test_report_at_issue_level
-    get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criteria => ["member", "activity"]
+    get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criteria => ["user", "activity"]
     assert_response :success
     assert_template 'report'
     assert_not_nil assigns(:report)
@@ -108,22 +125,62 @@
       :attributes => {:action => "/projects/ecookbook/issues/1/time_entries/report", :id => 'query_form'}
   end
 
-  def test_report_custom_field_criteria
-    get :report, :project_id => 1, :criteria => ['project', 'cf_1', 'cf_7']
+  def test_report_by_week_should_use_commercial_year
+    TimeEntry.delete_all
+    TimeEntry.generate!(:hours => '2', :spent_on => '2009-12-25') # 2009-52
+    TimeEntry.generate!(:hours => '4', :spent_on => '2009-12-31') # 2009-53
+    TimeEntry.generate!(:hours => '8', :spent_on => '2010-01-01') # 2009-53
+    TimeEntry.generate!(:hours => '16', :spent_on => '2010-01-05') # 2010-1
+
+    get :report, :columns => 'week', :from => "2009-12-25", :to => "2010-01-05", :criteria => ["project"]
+    assert_response :success
+
+    assert_select '#time-report thead tr' do
+      assert_select 'th:nth-child(1)', :text => 'Project'
+      assert_select 'th:nth-child(2)', :text => '2009-52'
+      assert_select 'th:nth-child(3)', :text => '2009-53'
+      assert_select 'th:nth-child(4)', :text => '2010-1'
+      assert_select 'th:nth-child(5)', :text => 'Total time'
+    end
+    assert_select '#time-report tbody tr' do
+      assert_select 'td:nth-child(1)', :text => 'eCookbook'
+      assert_select 'td:nth-child(2)', :text => '2.00'
+      assert_select 'td:nth-child(3)', :text => '12.00'
+      assert_select 'td:nth-child(4)', :text => '16.00'
+      assert_select 'td:nth-child(5)', :text => '30.00' # Total
+    end
+  end
+
+  def test_report_should_propose_association_custom_fields
+    get :report
+    assert_response :success
+    assert_template 'report'
+
+    assert_select 'select[name=?]', 'criteria[]' do
+      assert_select 'option[value=cf_1]', {:text => 'Database'}, 'Issue custom field not found'
+      assert_select 'option[value=cf_3]', {:text => 'Development status'}, 'Project custom field not found'
+      assert_select 'option[value=cf_7]', {:text => 'Billable'}, 'TimeEntryActivity custom field not found'
+    end
+  end
+
+  def test_report_with_association_custom_fields
+    get :report, :criteria => ['cf_1', 'cf_3', 'cf_7']
     assert_response :success
     assert_template 'report'
     assert_not_nil assigns(:report)
     assert_equal 3, assigns(:report).criteria.size
     assert_equal "162.90", "%.2f" % assigns(:report).total_hours
-    # Custom field column
-    assert_tag :tag => 'th', :content => 'Database'
+
+    # Custom fields columns
+    assert_select 'th', :text => 'Database'
+    assert_select 'th', :text => 'Development status'
+    assert_select 'th', :text => 'Billable'
+
     # Custom field row
-    assert_tag :tag => 'td', :content => 'MySQL',
-                             :sibling => { :tag => 'td', :attributes => { :class => 'hours' },
-                                                         :child => { :tag => 'span', :attributes => { :class => 'hours hours-int' },
-                                                                                     :content => '1' }}
-    # Second custom field column
-    assert_tag :tag => 'th', :content => 'Billable'
+    assert_select 'tr' do
+      assert_select 'td', :text => 'MySQL'
+      assert_select 'td.hours', :text => '1.00'
+    end
   end
 
   def test_report_one_criteria_no_result
@@ -144,29 +201,27 @@
 
   def test_report_all_projects_csv_export
     get :report, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30",
-        :criteria => ["project", "member", "activity"], :format => "csv"
+        :criteria => ["project", "user", "activity"], :format => "csv"
     assert_response :success
     assert_equal 'text/csv; header=present', @response.content_type
     lines = @response.body.chomp.split("\n")
     # Headers
-    assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total',
-                 lines.first
+    assert_equal 'Project,User,Activity,2007-3,2007-4,Total time', lines.first
     # Total row
-    assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
+    assert_equal 'Total time,"","",154.25,8.65,162.90', lines.last
   end
 
   def test_report_csv_export
     get :report, :project_id => 1, :columns => 'month',
         :from => "2007-01-01", :to => "2007-06-30",
-        :criteria => ["project", "member", "activity"], :format => "csv"
+        :criteria => ["project", "user", "activity"], :format => "csv"
     assert_response :success
     assert_equal 'text/csv; header=present', @response.content_type
     lines = @response.body.chomp.split("\n")
     # Headers
-    assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total',
-                 lines.first
+    assert_equal 'Project,User,Activity,2007-3,2007-4,Total time', lines.first
     # Total row
-    assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
+    assert_equal 'Total time,"","",154.25,8.65,162.90', lines.last
   end
 
   def test_csv_big_5
@@ -196,12 +251,12 @@
 
     get :report, :project_id => 1, :columns => 'day',
         :from => "2011-11-11", :to => "2011-11-11",
-        :criteria => ["member"], :format => "csv"
+        :criteria => ["user"], :format => "csv"
     assert_response :success
     assert_equal 'text/csv; header=present', @response.content_type
     lines = @response.body.chomp.split("\n")    
     # Headers
-    s1 = "\xa6\xa8\xad\xfb,2011-11-11,\xc1`\xadp"
+    s1 = "\xa5\xce\xa4\xe1,2011-11-11,\xc1`\xadp"
     s2 = "\xc1`\xadp"
     if s1.respond_to?(:force_encoding)
       s1.force_encoding('Big5')
@@ -247,12 +302,12 @@
 
     get :report, :project_id => 1, :columns => 'day',
         :from => "2011-11-11", :to => "2011-11-11",
-        :criteria => ["member"], :format => "csv"
+        :criteria => ["user"], :format => "csv"
     assert_response :success
     assert_equal 'text/csv; header=present', @response.content_type
     lines = @response.body.chomp.split("\n")    
     # Headers
-    s1 = "\xa6\xa8\xad\xfb,2011-11-11,\xc1`\xadp"
+    s1 = "\xa5\xce\xa4\xe1,2011-11-11,\xc1`\xadp"
     if s1.respond_to?(:force_encoding)
       s1.force_encoding('Big5')
     end
@@ -288,13 +343,13 @@
 
       get :report, :project_id => 1, :columns => 'day',
           :from => "2011-11-11", :to => "2011-11-11",
-          :criteria => ["member"], :format => "csv"
+          :criteria => ["user"], :format => "csv"
       assert_response :success
       assert_equal 'text/csv; header=present', @response.content_type
       lines = @response.body.chomp.split("\n")    
       # Headers
-      s1 = "Membre;2011-11-11;Total"
-      s2 = "Total"
+      s1 = "Utilisateur;2011-11-11;Temps total"
+      s2 = "Temps total"
       if s1.respond_to?(:force_encoding)
         s1.force_encoding('ISO-8859-1')
         s2.force_encoding('ISO-8859-1')
diff -r 0a574315af3e -r 4f746d8966dd test/functional/timelog_controller_test.rb
--- a/test/functional/timelog_controller_test.rb
+++ b/test/functional/timelog_controller_test.rb
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,25 +17,17 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'timelog_controller'
-
-# Re-raise errors caught by the controller.
-class TimelogController; def rescue_action(e) raise e end; end
 
 class TimelogControllerTest < ActionController::TestCase
   fixtures :projects, :enabled_modules, :roles, :members,
            :member_roles, :issues, :time_entries, :users,
            :trackers, :enumerations, :issue_statuses,
-           :custom_fields, :custom_values
+           :custom_fields, :custom_values,
+           :projects_trackers, :custom_fields_trackers,
+           :custom_fields_projects
 
   include Redmine::I18n
 
-  def setup
-    @controller = TimelogController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-  end
-
   def test_new_with_project_id
     @request.session[:user_id] = 3
     get :new, :project_id => 1
@@ -303,13 +295,20 @@
     assert_response :success
     assert_template 'bulk_edit'
 
-    # System wide custom field
-    assert_tag :select, :attributes => {:name => 'time_entry[custom_field_values][10]'}
+    assert_select 'ul#bulk-selection' do
+      assert_select 'li', 2
+      assert_select 'li a', :text => '03/23/2007 - eCookbook: 4.25 hours'
+    end
 
-    # Activities
-    assert_select 'select[name=?]', 'time_entry[activity_id]' do
-      assert_select 'option[value=]', :text => '(No change)'
-      assert_select 'option[value=9]', :text => 'Design'
+    assert_select 'form#bulk_edit_form[action=?]', '/time_entries/bulk_update' do
+      # System wide custom field
+      assert_select 'select[name=?]', 'time_entry[custom_field_values][10]'
+  
+      # Activities
+      assert_select 'select[name=?]', 'time_entry[activity_id]' do
+        assert_select 'option[value=]', :text => '(No change)'
+        assert_select 'option[value=9]', :text => 'Design'
+      end
     end
   end
 
@@ -440,14 +439,26 @@
     assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
     assert_not_nil assigns(:total_hours)
     assert_equal "162.90", "%.2f" % assigns(:total_hours)
-    # display all time by default
-    assert_nil assigns(:from)
-    assert_nil assigns(:to)
     assert_tag :form,
       :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
   end
 
   def test_index_at_project_level_with_date_range
+    get :index, :project_id => 'ecookbook',
+      :f => ['spent_on'],
+      :op => {'spent_on' => '><'},
+      :v => {'spent_on' => ['2007-03-20', '2007-04-30']}
+    assert_response :success
+    assert_template 'index'
+    assert_not_nil assigns(:entries)
+    assert_equal 3, assigns(:entries).size
+    assert_not_nil assigns(:total_hours)
+    assert_equal "12.90", "%.2f" % assigns(:total_hours)
+    assert_tag :form,
+      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
+  end
+
+  def test_index_at_project_level_with_date_range_using_from_and_to_params
     get :index, :project_id => 'ecookbook', :from => '2007-03-20', :to => '2007-04-30'
     assert_response :success
     assert_template 'index'
@@ -455,116 +466,23 @@
     assert_equal 3, assigns(:entries).size
     assert_not_nil assigns(:total_hours)
     assert_equal "12.90", "%.2f" % assigns(:total_hours)
-    assert_equal '2007-03-20'.to_date, assigns(:from)
-    assert_equal '2007-04-30'.to_date, assigns(:to)
     assert_tag :form,
       :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
   end
 
   def test_index_at_project_level_with_period
-    get :index, :project_id => 'ecookbook', :period => '7_days'
+    get :index, :project_id => 'ecookbook',
+      :f => ['spent_on'],
+      :op => {'spent_on' => '>t-'},
+      :v => {'spent_on' => ['7']}
     assert_response :success
     assert_template 'index'
     assert_not_nil assigns(:entries)
     assert_not_nil assigns(:total_hours)
-    assert_equal Date.today - 7, assigns(:from)
-    assert_equal Date.today, assigns(:to)
     assert_tag :form,
       :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
   end
 
-  def test_index_one_day
-    get :index, :project_id => 'ecookbook', :from => "2007-03-23", :to => "2007-03-23"
-    assert_response :success
-    assert_template 'index'
-    assert_not_nil assigns(:total_hours)
-    assert_equal "4.25", "%.2f" % assigns(:total_hours)
-    assert_tag :form,
-      :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
-  end
-
-  def test_index_from_a_date
-    get :index, :project_id => 'ecookbook', :from => "2007-03-23", :to => ""
-    assert_equal '2007-03-23'.to_date, assigns(:from)
-    assert_nil assigns(:to)
-  end
-
-  def test_index_to_a_date
-    get :index, :project_id => 'ecookbook', :from => "", :to => "2007-03-23"
-    assert_nil assigns(:from)
-    assert_equal '2007-03-23'.to_date, assigns(:to)
-  end
-
-  def test_index_today
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => 'today'
-    assert_equal '2011-12-15'.to_date, assigns(:from)
-    assert_equal '2011-12-15'.to_date, assigns(:to)
-  end
-
-  def test_index_yesterday
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => 'yesterday'
-    assert_equal '2011-12-14'.to_date, assigns(:from)
-    assert_equal '2011-12-14'.to_date, assigns(:to)
-  end
-
-  def test_index_current_week
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => 'current_week'
-    assert_equal '2011-12-12'.to_date, assigns(:from)
-    assert_equal '2011-12-18'.to_date, assigns(:to)
-  end
-
-  def test_index_last_week
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => 'last_week'
-    assert_equal '2011-12-05'.to_date, assigns(:from)
-    assert_equal '2011-12-11'.to_date, assigns(:to)
-  end
-
-  def test_index_last_2_week
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => 'last_2_weeks'
-    assert_equal '2011-11-28'.to_date, assigns(:from)
-    assert_equal '2011-12-11'.to_date, assigns(:to)
-  end
-
-  def test_index_7_days
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => '7_days'
-    assert_equal '2011-12-08'.to_date, assigns(:from)
-    assert_equal '2011-12-15'.to_date, assigns(:to)
-  end
-
-  def test_index_current_month
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => 'current_month'
-    assert_equal '2011-12-01'.to_date, assigns(:from)
-    assert_equal '2011-12-31'.to_date, assigns(:to)
-  end
-
-  def test_index_last_month
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => 'last_month'
-    assert_equal '2011-11-01'.to_date, assigns(:from)
-    assert_equal '2011-11-30'.to_date, assigns(:to)
-  end
-
-  def test_index_30_days
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => '30_days'
-    assert_equal '2011-11-15'.to_date, assigns(:from)
-    assert_equal '2011-12-15'.to_date, assigns(:to)
-  end
-
-  def test_index_current_year
-    Date.stubs(:today).returns('2011-12-15'.to_date)
-    get :index, :period => 'current_year'
-    assert_equal '2011-01-01'.to_date, assigns(:from)
-    assert_equal '2011-12-31'.to_date, assigns(:to)
-  end
-
   def test_index_at_issue_level
     get :index, :issue_id => 1
     assert_response :success
@@ -587,15 +505,41 @@
     t2 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-16', :created_on => '2012-06-16 20:05:00', :activity_id => 10)
     t3 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-15', :created_on => '2012-06-16 20:10:00', :activity_id => 10)
 
-    get :index, :project_id => 1, :from => '2012-06-15', :to => '2012-06-16'
+    get :index, :project_id => 1,
+      :f => ['spent_on'],
+      :op => {'spent_on' => '><'},
+      :v => {'spent_on' => ['2012-06-15', '2012-06-16']}
     assert_response :success
     assert_equal [t2, t1, t3], assigns(:entries)
 
-    get :index, :project_id => 1, :from => '2012-06-15', :to => '2012-06-16', :sort => 'spent_on'
+    get :index, :project_id => 1,
+      :f => ['spent_on'],
+      :op => {'spent_on' => '><'},
+      :v => {'spent_on' => ['2012-06-15', '2012-06-16']},
+      :sort => 'spent_on'
     assert_response :success
     assert_equal [t3, t1, t2], assigns(:entries)
   end
 
+  def test_index_with_filter_on_issue_custom_field
+    issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {2 => 'filter_on_issue_custom_field'})
+    entry = TimeEntry.generate!(:issue => issue, :hours => 2.5)
+
+    get :index, :f => ['issue.cf_2'], :op => {'issue.cf_2' => '='}, :v => {'issue.cf_2' => ['filter_on_issue_custom_field']}
+    assert_response :success
+    assert_equal [entry], assigns(:entries)
+  end
+
+  def test_index_with_issue_custom_field_column
+    issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {2 => 'filter_on_issue_custom_field'})
+    entry = TimeEntry.generate!(:issue => issue, :hours => 2.5)
+
+    get :index, :c => %w(project spent_on issue comments hours issue.cf_2)
+    assert_response :success
+    assert_include :'issue.cf_2', assigns(:query).column_names
+    assert_select 'td.issue_cf_2', :text => 'filter_on_issue_custom_field'
+  end
+
   def test_index_atom_feed
     get :index, :project_id => 1, :format => 'atom'
     assert_response :success
@@ -604,186 +548,57 @@
     assert assigns(:items).first.is_a?(TimeEntry)
   end
 
-  def test_index_all_projects_csv_export
+  def test_index_at_project_level_should_include_csv_export_dialog
+    get :index, :project_id => 'ecookbook', 
+      :f => ['spent_on'],
+      :op => {'spent_on' => '>='},
+      :v => {'spent_on' => ['2007-04-01']},
+      :c => ['spent_on', 'user']
+    assert_response :success
+
+    assert_select '#csv-export-options' do
+      assert_select 'form[action=?][method=get]', '/projects/ecookbook/time_entries.csv' do
+        # filter
+        assert_select 'input[name=?][value=?]', 'f[]', 'spent_on'
+        assert_select 'input[name=?][value=?]', 'op[spent_on]', '&gt;='
+        assert_select 'input[name=?][value=?]', 'v[spent_on][]', '2007-04-01'
+        # columns
+        assert_select 'input[name=?][value=?]', 'c[]', 'spent_on'
+        assert_select 'input[name=?][value=?]', 'c[]', 'user'
+        assert_select 'input[name=?]', 'c[]', 2
+      end
+    end
+  end
+
+  def test_index_cross_project_should_include_csv_export_dialog
+    get :index
+    assert_response :success
+
+    assert_select '#csv-export-options' do
+      assert_select 'form[action=?][method=get]', '/time_entries.csv'
+    end
+  end
+
+  def test_index_at_issue_level_should_include_csv_export_dialog
+    get :index, :project_id => 'ecookbook', :issue_id => 3
+    assert_response :success
+
+    assert_select '#csv-export-options' do
+      assert_select 'form[action=?][method=get]', '/projects/ecookbook/issues/3/time_entries.csv'
+    end
+  end
+
+  def test_index_csv_all_projects
     Setting.date_format = '%m/%d/%Y'
     get :index, :format => 'csv'
     assert_response :success
-    assert_equal 'text/csv; header=present', @response.content_type
-    assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment,Overtime\n")
-    assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\",\"\"\n")
+    assert_equal 'text/csv; header=present', response.content_type
   end
 
-  def test_index_csv_export
+  def test_index_csv
     Setting.date_format = '%m/%d/%Y'
     get :index, :project_id => 1, :format => 'csv'
     assert_response :success
-    assert_equal 'text/csv; header=present', @response.content_type
-    assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment,Overtime\n")
-    assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\",\"\"\n")
-  end
-
-  def test_index_csv_export_with_multi_custom_field
-    field = TimeEntryCustomField.create!(:name => 'Test', :field_format => 'list',
-      :multiple => true, :possible_values => ['value1', 'value2'])
-    entry = TimeEntry.find(1)
-    entry.custom_field_values = {field.id => ['value1', 'value2']}
-    entry.save!
-
-    get :index, :project_id => 1, :format => 'csv'
-    assert_response :success
-    assert_include '"value1, value2"', @response.body
-  end
-
-  def test_csv_big_5
-    user = User.find_by_id(3)
-    user.language = "zh-TW"
-    assert user.save
-    str_utf8  = "\xe4\xb8\x80\xe6\x9c\x88"
-    str_big5  = "\xa4@\xa4\xeb"
-    if str_utf8.respond_to?(:force_encoding)
-      str_utf8.force_encoding('UTF-8')
-      str_big5.force_encoding('Big5')
-    end
-    @request.session[:user_id] = 3
-    post :create, :project_id => 1,
-                :time_entry => {:comments => str_utf8,
-                                # Not the default activity
-                                :activity_id => '11',
-                                :issue_id => '',
-                                :spent_on => '2011-11-10',
-                                :hours => '7.3'}
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-
-    t = TimeEntry.find_by_comments(str_utf8)
-    assert_not_nil t
-    assert_equal 11, t.activity_id
-    assert_equal 7.3, t.hours
-    assert_equal 3, t.user_id
-
-    get :index, :project_id => 1, :format => 'csv',
-        :from => '2011-11-10', :to => '2011-11-10'
-    assert_response :success
-    assert_equal 'text/csv; header=present', @response.content_type
-    ar = @response.body.chomp.split("\n")
-    s1 = "\xa4\xe9\xb4\xc1"
-    if str_utf8.respond_to?(:force_encoding)
-      s1.force_encoding('Big5')
-    end
-    assert ar[0].include?(s1)
-    assert ar[1].include?(str_big5)
-  end
-
-  def test_csv_cannot_convert_should_be_replaced_big_5
-    user = User.find_by_id(3)
-    user.language = "zh-TW"
-    assert user.save
-    str_utf8  = "\xe4\xbb\xa5\xe5\x86\x85"
-    if str_utf8.respond_to?(:force_encoding)
-      str_utf8.force_encoding('UTF-8')
-    end
-    @request.session[:user_id] = 3
-    post :create, :project_id => 1,
-                :time_entry => {:comments => str_utf8,
-                                # Not the default activity
-                                :activity_id => '11',
-                                :issue_id => '',
-                                :spent_on => '2011-11-10',
-                                :hours => '7.3'}
-    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
-
-    t = TimeEntry.find_by_comments(str_utf8)
-    assert_not_nil t
-    assert_equal 11, t.activity_id
-    assert_equal 7.3, t.hours
-    assert_equal 3, t.user_id
-
-    get :index, :project_id => 1, :format => 'csv',
-        :from => '2011-11-10', :to => '2011-11-10'
-    assert_response :success
-    assert_equal 'text/csv; header=present', @response.content_type
-    ar = @response.body.chomp.split("\n")
-    s1 = "\xa4\xe9\xb4\xc1"
-    if str_utf8.respond_to?(:force_encoding)
-      s1.force_encoding('Big5')
-    end
-    assert ar[0].include?(s1)
-    s2 = ar[1].split(",")[8]
-    if s2.respond_to?(:force_encoding)
-      s3 = "\xa5H?"
-      s3.force_encoding('Big5')
-      assert_equal s3, s2
-    elsif RUBY_PLATFORM == 'java'
-      assert_equal "??", s2
-    else
-      assert_equal "\xa5H???", s2
-    end
-  end
-
-  def test_csv_tw
-    with_settings :default_language => "zh-TW" do
-      str1  = "test_csv_tw"
-      user = User.find_by_id(3)
-      te1 = TimeEntry.create(:spent_on => '2011-11-10',
-                             :hours    => 999.9,
-                             :project  => Project.find(1),
-                             :user     => user,
-                             :activity => TimeEntryActivity.find_by_name('Design'),
-                             :comments => str1)
-      te2 = TimeEntry.find_by_comments(str1)
-      assert_not_nil te2
-      assert_equal 999.9, te2.hours
-      assert_equal 3, te2.user_id
-
-      get :index, :project_id => 1, :format => 'csv',
-          :from => '2011-11-10', :to => '2011-11-10'
-      assert_response :success
-      assert_equal 'text/csv; header=present', @response.content_type
-
-      ar = @response.body.chomp.split("\n")
-      s2 = ar[1].split(",")[7]
-      assert_equal '999.9', s2
-
-      str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
-      if str_tw.respond_to?(:force_encoding)
-        str_tw.force_encoding('UTF-8')
-      end
-      assert_equal str_tw, l(:general_lang_name)
-      assert_equal ',', l(:general_csv_separator)
-      assert_equal '.', l(:general_csv_decimal_separator)
-    end
-  end
-
-  def test_csv_fr
-    with_settings :default_language => "fr" do
-      str1  = "test_csv_fr"
-      user = User.find_by_id(3)
-      te1 = TimeEntry.create(:spent_on => '2011-11-10',
-                             :hours    => 999.9,
-                             :project  => Project.find(1),
-                             :user     => user,
-                             :activity => TimeEntryActivity.find_by_name('Design'),
-                             :comments => str1)
-      te2 = TimeEntry.find_by_comments(str1)
-      assert_not_nil te2
-      assert_equal 999.9, te2.hours
-      assert_equal 3, te2.user_id
-
-      get :index, :project_id => 1, :format => 'csv',
-          :from => '2011-11-10', :to => '2011-11-10'
-      assert_response :success
-      assert_equal 'text/csv; header=present', @response.content_type
-
-      ar = @response.body.chomp.split("\n")
-      s2 = ar[1].split(";")[7]
-      assert_equal '999,9', s2
-
-      str_fr = "Fran\xc3\xa7ais"
-      if str_fr.respond_to?(:force_encoding)
-        str_fr.force_encoding('UTF-8')
-      end
-      assert_equal str_fr, l(:general_lang_name)
-      assert_equal ';', l(:general_csv_separator)
-      assert_equal ',', l(:general_csv_decimal_separator)
-    end
+    assert_equal 'text/csv; header=present', response.content_type
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/trackers_controller_test.rb
--- a/test/functional/trackers_controller_test.rb
+++ b/test/functional/trackers_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,18 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'trackers_controller'
-
-# Re-raise errors caught by the controller.
-class TrackersController; def rescue_action(e) raise e end; end
 
 class TrackersControllerTest < ActionController::TestCase
   fixtures :trackers, :projects, :projects_trackers, :users, :issues, :custom_fields
 
   def setup
-    @controller = TrackersController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
     @request.session[:user_id] = 1 # admin
   end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/users_controller_test.rb
--- a/test/functional/users_controller_test.rb
+++ b/test/functional/users_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,10 +16,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'users_controller'
-
-# Re-raise errors caught by the controller.
-class UsersController; def rescue_action(e) raise e end; end
 
 class UsersControllerTest < ActionController::TestCase
   include Redmine::I18n
@@ -29,9 +25,6 @@
            :auth_sources
 
   def setup
-    @controller = UsersController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
     @request.session[:user_id] = 1 # admin
   end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/versions_controller_test.rb
--- a/test/functional/versions_controller_test.rb
+++ b/test/functional/versions_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,18 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'versions_controller'
-
-# Re-raise errors caught by the controller.
-class VersionsController; def rescue_action(e) raise e end; end
 
 class VersionsControllerTest < ActionController::TestCase
   fixtures :projects, :versions, :issues, :users, :roles, :members, :member_roles, :enabled_modules, :issue_statuses, :issue_categories
 
   def setup
-    @controller = VersionsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/watchers_controller_test.rb
--- a/test/functional/watchers_controller_test.rb
+++ b/test/functional/watchers_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,23 +16,16 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'watchers_controller'
-
-# Re-raise errors caught by the controller.
-class WatchersController; def rescue_action(e) raise e end; end
 
 class WatchersControllerTest < ActionController::TestCase
   fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
            :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers
 
   def setup
-    @controller = WatchersController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
-  def test_watch
+  def test_watch_a_single_object
     @request.session[:user_id] = 3
     assert_difference('Watcher.count') do
       xhr :post, :watch, :object_type => 'issue', :object_id => '1'
@@ -42,6 +35,27 @@
     assert Issue.find(1).watched_by?(User.find(3))
   end
 
+  def test_watch_a_collection_with_a_single_object
+    @request.session[:user_id] = 3
+    assert_difference('Watcher.count') do
+      xhr :post, :watch, :object_type => 'issue', :object_id => ['1']
+      assert_response :success
+      assert_include '$(".issue-1-watcher")', response.body
+    end
+    assert Issue.find(1).watched_by?(User.find(3))
+  end
+
+  def test_watch_a_collection_with_multiple_objects
+    @request.session[:user_id] = 3
+    assert_difference('Watcher.count', 2) do
+      xhr :post, :watch, :object_type => 'issue', :object_id => ['1', '3']
+      assert_response :success
+      assert_include '$(".issue-bulk-watcher")', response.body
+    end
+    assert Issue.find(1).watched_by?(User.find(3))
+    assert Issue.find(3).watched_by?(User.find(3))
+  end
+
   def test_watch_should_be_denied_without_permission
     Role.find(2).remove_permission! :view_issues
     @request.session[:user_id] = 3
@@ -70,13 +84,27 @@
   def test_unwatch
     @request.session[:user_id] = 3
     assert_difference('Watcher.count', -1) do
-      xhr :post, :unwatch, :object_type => 'issue', :object_id => '2'
+      xhr :delete, :unwatch, :object_type => 'issue', :object_id => '2'
       assert_response :success
       assert_include '$(".issue-2-watcher")', response.body
     end
     assert !Issue.find(1).watched_by?(User.find(3))
   end
 
+  def test_unwatch_a_collection_with_multiple_objects
+    @request.session[:user_id] = 3
+    Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
+    Watcher.create!(:user_id => 3, :watchable => Issue.find(3))
+
+    assert_difference('Watcher.count', -2) do
+      xhr :delete, :unwatch, :object_type => 'issue', :object_id => ['1', '3']
+      assert_response :success
+      assert_include '$(".issue-bulk-watcher")', response.body
+    end
+    assert !Issue.find(1).watched_by?(User.find(3))
+    assert !Issue.find(3).watched_by?(User.find(3))
+  end
+
   def test_new
     @request.session[:user_id] = 2
     xhr :get, :new, :object_type => 'issue', :object_id => '2'
@@ -84,7 +112,7 @@
     assert_match /ajax-modal/, response.body
   end
 
-  def test_new_for_new_record_with_id
+  def test_new_for_new_record_with_project_id
     @request.session[:user_id] = 2
     xhr :get, :new, :project_id => 1
     assert_response :success
@@ -92,7 +120,7 @@
     assert_match /ajax-modal/, response.body
   end
 
-  def test_new_for_new_record_with_identifier
+  def test_new_for_new_record_with_project_identifier
     @request.session[:user_id] = 2
     xhr :get, :new, :project_id => 'ecookbook'
     assert_response :success
@@ -124,7 +152,8 @@
   end
 
   def test_autocomplete_on_watchable_creation
-    xhr :get, :autocomplete_for_user, :q => 'mi'
+    @request.session[:user_id] = 2
+    xhr :get, :autocomplete_for_user, :q => 'mi', :project_id => 'ecookbook'
     assert_response :success
     assert_select 'input', :count => 4
     assert_select 'input[name=?][value=1]', 'watcher[user_ids][]'
@@ -134,7 +163,8 @@
   end
 
   def test_autocomplete_on_watchable_update
-    xhr :get, :autocomplete_for_user, :q => 'mi', :object_id => '2' , :object_type => 'issue'
+    @request.session[:user_id] = 2
+    xhr :get, :autocomplete_for_user, :q => 'mi', :object_id => '2' , :object_type => 'issue', :project_id => 'ecookbook'
     assert_response :success
     assert_select 'input', :count => 3
     assert_select 'input[name=?][value=2]', 'watcher[user_ids][]'
@@ -146,7 +176,7 @@
   def test_append
     @request.session[:user_id] = 2
     assert_no_difference 'Watcher.count' do
-      xhr :post, :append, :watcher => {:user_ids => ['4', '7']}
+      xhr :post, :append, :watcher => {:user_ids => ['4', '7']}, :project_id => 'ecookbook'
       assert_response :success
       assert_include 'watchers_inputs', response.body
       assert_include 'issue[watcher_user_ids][]', response.body
@@ -156,7 +186,7 @@
   def test_remove_watcher
     @request.session[:user_id] = 2
     assert_difference('Watcher.count', -1) do
-      xhr :post, :destroy, :object_type => 'issue', :object_id => '2', :user_id => '3'
+      xhr :delete, :destroy, :object_type => 'issue', :object_id => '2', :user_id => '3'
       assert_response :success
       assert_match /watchers/, response.body
     end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/welcome_controller_test.rb
--- a/test/functional/welcome_controller_test.rb
+++ b/test/functional/welcome_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,18 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'welcome_controller'
-
-# Re-raise errors caught by the controller.
-class WelcomeController; def rescue_action(e) raise e end; end
 
 class WelcomeControllerTest < ActionController::TestCase
   fixtures :projects, :news, :users, :members
 
   def setup
-    @controller = WelcomeController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
@@ -37,7 +30,7 @@
     assert_template 'index'
     assert_not_nil assigns(:news)
     assert_not_nil assigns(:projects)
-    assert !assigns(:projects).include?(Project.find(:first, :conditions => {:is_public => false}))
+    assert !assigns(:projects).include?(Project.where(:is_public => false).first)
   end
 
   def test_browser_language
@@ -92,6 +85,13 @@
       :content => %r{warnLeavingUnsaved}
   end
 
+  def test_logout_link_should_post
+    @request.session[:user_id] = 2
+
+    get :index
+    assert_select 'a[href=/logout][data-method=post]', :text => 'Sign out'
+  end
+
   def test_call_hook_mixed_in
     assert @controller.respond_to?(:call_hook)
   end
diff -r 0a574315af3e -r 4f746d8966dd test/functional/wiki_controller_test.rb
--- a/test/functional/wiki_controller_test.rb
+++ b/test/functional/wiki_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,10 +16,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'wiki_controller'
-
-# Re-raise errors caught by the controller.
-class WikiController; def rescue_action(e) raise e end; end
 
 class WikiControllerTest < ActionController::TestCase
   fixtures :projects, :users, :roles, :members, :member_roles,
@@ -27,9 +23,6 @@
            :wiki_content_versions, :attachments
 
   def setup
-    @controller = WikiController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
@@ -60,7 +53,7 @@
     assert_tag :tag => 'h1', :content => /Another page/
     # Included page with an inline image
     assert_tag :tag => 'p', :content => /This is an inline image/
-    assert_tag :tag => 'img', :attributes => { :src => '/attachments/download/3',
+    assert_tag :tag => 'img', :attributes => { :src => '/attachments/download/3/logo.gif',
                                                :alt => 'This is a logo' }
   end
 
@@ -592,7 +585,7 @@
     # Line 5
     assert_tag :tag => 'tr', :child => {
       :tag => 'th', :attributes => {:class => 'line-num'}, :content => '5', :sibling => {
-        :tag => 'td', :attributes => {:class => 'author'}, :content => /redMine Admin/, :sibling => {
+        :tag => 'td', :attributes => {:class => 'author'}, :content => /Redmine Admin/, :sibling => {
           :tag => 'td', :content => /Some updated \[\[documentation\]\] here/
         }
       }
diff -r 0a574315af3e -r 4f746d8966dd test/functional/wikis_controller_test.rb
--- a/test/functional/wikis_controller_test.rb
+++ b/test/functional/wikis_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,18 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'wikis_controller'
-
-# Re-raise errors caught by the controller.
-class WikisController; def rescue_action(e) raise e end; end
 
 class WikisControllerTest < ActionController::TestCase
   fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :wikis
 
   def setup
-    @controller = WikisController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/functional/workflows_controller_test.rb
--- a/test/functional/workflows_controller_test.rb
+++ b/test/functional/workflows_controller_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,18 +16,11 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../test_helper', __FILE__)
-require 'workflows_controller'
-
-# Re-raise errors caught by the controller.
-class WorkflowsController; def rescue_action(e) raise e end; end
 
 class WorkflowsControllerTest < ActionController::TestCase
   fixtures :roles, :trackers, :workflows, :users, :issue_statuses
 
   def setup
-    @controller = WorkflowsController.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
     User.current = nil
     @request.session[:user_id] = 1 # admin
   end
@@ -102,9 +95,9 @@
       }
     assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
 
-    assert_equal 3, WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2})
-    assert_not_nil  WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
-    assert_nil      WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4})
+    assert_equal 3, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
+    assert_not_nil  WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
+    assert_nil      WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4).first
   end
 
   def test_post_edit_with_additional_transitions
@@ -115,18 +108,18 @@
       }
     assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
 
-    assert_equal 4, WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2})
+    assert_equal 4, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
 
-    w = WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5})
+    w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5).first
     assert ! w.author
     assert ! w.assignee
-    w = WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1})
+    w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1).first
     assert w.author
     assert ! w.assignee
-    w = WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
+    w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
     assert ! w.author
     assert w.assignee
-    w = WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4})
+    w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4).first
     assert w.author
     assert w.assignee
   end
@@ -304,9 +297,32 @@
     assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 3)
   end
 
+  def test_post_copy_with_incomplete_source_specification_should_fail
+    assert_no_difference 'WorkflowRule.count' do
+      post :copy,
+        :source_tracker_id => '', :source_role_id => '2',
+        :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
+      assert_response 200
+      assert_select 'div.flash.error', :text => 'Please select a source tracker or role' 
+    end
+  end
+
+  def test_post_copy_with_incomplete_target_specification_should_fail
+    assert_no_difference 'WorkflowRule.count' do
+      post :copy,
+        :source_tracker_id => '1', :source_role_id => '2',
+        :target_tracker_ids => ['2', '3']
+      assert_response 200
+      assert_select 'div.flash.error', :text => 'Please select target tracker(s) and role(s)'
+    end
+  end
+
   # Returns an array of status transitions that can be compared
   def status_transitions(conditions)
-    WorkflowTransition.find(:all, :conditions => conditions,
-                        :order => 'tracker_id, role_id, old_status_id, new_status_id').collect {|w| [w.old_status, w.new_status_id]}
+    WorkflowTransition.
+      where(conditions).
+      order('tracker_id, role_id, old_status_id, new_status_id').
+      all.
+      collect {|w| [w.old_status, w.new_status_id]}
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/integration/account_test.rb
--- a/test/integration/account_test.rb
+++ b/test/integration/account_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -45,7 +45,7 @@
     # User logs in with 'autologin' checked
     post '/login', :username => user.login, :password => 'admin', :autologin => 1
     assert_redirected_to '/my/page'
-    token = Token.find :first
+    token = Token.first
     assert_not_nil token
     assert_equal user, token.user
     assert_equal 'autologin', token.action
@@ -68,6 +68,33 @@
     assert_not_nil user.reload.last_login_on
   end
 
+  def test_autologin_should_use_autologin_cookie_name
+    Token.delete_all
+    Redmine::Configuration.stubs(:[]).with('autologin_cookie_name').returns('custom_autologin')
+    Redmine::Configuration.stubs(:[]).with('autologin_cookie_path').returns('/')
+    Redmine::Configuration.stubs(:[]).with('autologin_cookie_secure').returns(false)
+
+    with_settings :autologin => '7' do
+      assert_difference 'Token.count' do
+        post '/login', :username => 'admin', :password => 'admin', :autologin => 1
+      end
+      assert_response 302
+      assert cookies['custom_autologin'].present?
+      token = cookies['custom_autologin']
+  
+      # Session is cleared
+      reset!
+      cookies['custom_autologin'] = token
+      get '/my/page'
+      assert_response :success
+
+      assert_difference 'Token.count', -1 do
+        post '/logout'
+      end
+      assert cookies['custom_autologin'].blank?
+    end
+  end
+
   def test_lost_password
     Token.delete_all
 
@@ -79,7 +106,7 @@
     post "account/lost_password", :mail => 'jSmith@somenet.foo'
     assert_redirected_to "/login"
 
-    token = Token.find(:first)
+    token = Token.first
     assert_equal 'recovery', token.action
     assert_equal 'jsmith@somenet.foo', token.user.mail
     assert !token.expired?
@@ -137,7 +164,7 @@
     assert_redirected_to '/login'
     assert !User.find_by_login('newuser').active?
 
-    token = Token.find(:first)
+    token = Token.first
     assert_equal 'register', token.action
     assert_equal 'newuser@foo.bar', token.user.mail
     assert !token.expired?
diff -r 0a574315af3e -r 4f746d8966dd test/integration/admin_test.rb
--- a/test/integration/admin_test.rb
+++ b/test/integration/admin_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,8 +24,7 @@
            :roles,
            :member_roles,
            :members,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   def test_add_user
     log_user("admin", "admin")
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/attachments_test.rb
--- a/test/integration/api_test/attachments_test.rb
+++ b/test/integration/api_test/attachments_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::AttachmentsTest < ActionController::IntegrationTest
+class Redmine::ApiTest::AttachmentsTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
@@ -25,7 +25,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :attachments
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/authentication_test.rb
--- a/test/integration/api_test/authentication_test.rb
+++ b/test/integration/api_test/authentication_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::AuthenticationTest < ActionController::IntegrationTest
+class Redmine::ApiTest::AuthenticationTest < Redmine::ApiTest::Base
   fixtures :users
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/disabled_rest_api_test.rb
--- a/test/integration/api_test/disabled_rest_api_test.rb
+++ b/test/integration/api_test/disabled_rest_api_test.rb
@@ -1,14 +1,30 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::DisabledRestApiTest < ActionController::IntegrationTest
+class Redmine::ApiTest::DisabledRestApiTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
            :roles,
            :member_roles,
            :members,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   def setup
     Setting.rest_api_enabled = '0'
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/enumerations_test.rb
--- a/test/integration/api_test/enumerations_test.rb
+++ b/test/integration/api_test/enumerations_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::EnumerationsTest < ActionController::IntegrationTest
+class Redmine::ApiTest::EnumerationsTest < Redmine::ApiTest::Base
   fixtures :enumerations
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/groups_test.rb
--- a/test/integration/api_test/groups_test.rb
+++ b/test/integration/api_test/groups_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::GroupsTest < ActionController::IntegrationTest
+class Redmine::ApiTest::GroupsTest < Redmine::ApiTest::Base
   fixtures :users, :groups_users
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/http_basic_login_test.rb
--- a/test/integration/api_test/http_basic_login_test.rb
+++ b/test/integration/api_test/http_basic_login_test.rb
@@ -1,14 +1,30 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::HttpBasicLoginTest < ActionController::IntegrationTest
+class Redmine::ApiTest::HttpBasicLoginTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
            :roles,
            :member_roles,
            :members,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   def setup
     Setting.rest_api_enabled = '1'
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/http_basic_login_with_api_token_test.rb
--- a/test/integration/api_test/http_basic_login_with_api_token_test.rb
+++ b/test/integration/api_test/http_basic_login_with_api_token_test.rb
@@ -1,14 +1,30 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::HttpBasicLoginWithApiTokenTest < ActionController::IntegrationTest
+class Redmine::ApiTest::HttpBasicLoginWithApiTokenTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
            :roles,
            :member_roles,
            :members,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   def setup
     Setting.rest_api_enabled = '1'
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/issue_categories_test.rb
--- a/test/integration/api_test/issue_categories_test.rb
+++ b/test/integration/api_test/issue_categories_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::IssueCategoriesTest < ActionController::IntegrationTest
+class Redmine::ApiTest::IssueCategoriesTest < Redmine::ApiTest::Base
   fixtures :projects, :users, :issue_categories, :issues,
            :roles,
            :member_roles,
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/issue_relations_test.rb
--- a/test/integration/api_test/issue_relations_test.rb
+++ b/test/integration/api_test/issue_relations_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::IssueRelationsTest < ActionController::IntegrationTest
+class Redmine::ApiTest::IssueRelationsTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
@@ -25,7 +25,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :issue_relations
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/issue_statuses_test.rb
--- a/test/integration/api_test/issue_statuses_test.rb
+++ b/test/integration/api_test/issue_statuses_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::IssueStatusesTest < ActionController::IntegrationTest
+class Redmine::ApiTest::IssueStatusesTest < Redmine::ApiTest::Base
   fixtures :issue_statuses
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/issues_test.rb
--- a/test/integration/api_test/issues_test.rb
+++ b/test/integration/api_test/issues_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::IssuesTest < ActionController::IntegrationTest
+class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
   fixtures :projects,
     :users,
     :roles,
@@ -453,6 +453,21 @@
     end
   end
 
+  test "GET /issues/:id.xml?include=watchers should include watchers" do
+    Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
+
+    get '/issues/1.xml?include=watchers', {}, credentials('jsmith')
+
+    assert_response :ok
+    assert_equal 'application/xml', response.content_type
+    assert_select 'issue' do
+      assert_select 'watchers', Issue.find(1).watchers.count
+      assert_select 'watchers' do
+        assert_select 'user[id=3]'
+      end
+    end
+  end
+
   context "POST /issues.xml" do
     should_allow_api_authentication(
       :post,
@@ -478,6 +493,18 @@
     end
   end
 
+  test "POST /issues.xml with watcher_user_ids should create issue with watchers" do
+    assert_difference('Issue.count') do
+      post '/issues.xml',
+           {:issue => {:project_id => 1, :subject => 'Watchers',
+            :tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]}}, credentials('jsmith')
+      assert_response :created
+    end
+    issue = Issue.order('id desc').first
+    assert_equal 2, issue.watchers.size
+    assert_equal [1, 3], issue.watcher_user_ids.sort
+  end
+
   context "POST /issues.xml with failure" do
     should "have an errors tag" do
       assert_no_difference('Issue.count') do
@@ -720,6 +747,30 @@
     end
   end
 
+  test "POST /issues/:id/watchers.xml should add watcher" do
+    assert_difference 'Watcher.count' do
+      post '/issues/1/watchers.xml', {:user_id => 3}, credentials('jsmith')
+
+      assert_response :ok
+      assert_equal '', response.body
+    end
+    watcher = Watcher.order('id desc').first
+    assert_equal Issue.find(1), watcher.watchable
+    assert_equal User.find(3), watcher.user
+  end
+
+  test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do
+    Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
+
+    assert_difference 'Watcher.count', -1 do
+      delete '/issues/1/watchers/3.xml', {}, credentials('jsmith')
+
+      assert_response :ok
+      assert_equal '', response.body
+    end
+    assert_equal false, Issue.find(1).watched_by?(User.find(3))
+  end
+
   def test_create_issue_with_uploaded_file
     set_tmp_attachments_directory
     # upload the file
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/jsonp_test.rb
--- a/test/integration/api_test/jsonp_test.rb
+++ b/test/integration/api_test/jsonp_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,11 +17,23 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::JsonpTest < ActionController::IntegrationTest
+class Redmine::ApiTest::JsonpTest < Redmine::ApiTest::Base
   fixtures :trackers
 
+  def test_should_ignore_jsonp_callback_with_jsonp_disabled
+    with_settings :jsonp_enabled => '0' do
+      get '/trackers.json?jsonp=handler'
+    end
+
+    assert_response :success
+    assert_match %r{^\{"trackers":.+\}$}, response.body
+    assert_equal 'application/json; charset=utf-8', response.headers['Content-Type']
+  end
+
   def test_jsonp_should_accept_callback_param
-    get '/trackers.json?callback=handler'
+    with_settings :jsonp_enabled => '1' do
+      get '/trackers.json?callback=handler'
+    end
 
     assert_response :success
     assert_match %r{^handler\(\{"trackers":.+\}\)$}, response.body
@@ -29,7 +41,9 @@
   end
 
   def test_jsonp_should_accept_jsonp_param
-    get '/trackers.json?jsonp=handler'
+    with_settings :jsonp_enabled => '1' do
+      get '/trackers.json?jsonp=handler'
+    end
 
     assert_response :success
     assert_match %r{^handler\(\{"trackers":.+\}\)$}, response.body
@@ -37,7 +51,9 @@
   end
 
   def test_jsonp_should_strip_invalid_characters_from_callback
-    get '/trackers.json?callback=+-aA$1_'
+    with_settings :jsonp_enabled => '1' do
+      get '/trackers.json?callback=+-aA$1_'
+    end
 
     assert_response :success
     assert_match %r{^aA1_\(\{"trackers":.+\}\)$}, response.body
@@ -45,7 +61,9 @@
   end
 
   def test_jsonp_without_callback_should_return_json
-    get '/trackers.json?callback='
+    with_settings :jsonp_enabled => '1' do
+      get '/trackers.json?callback='
+    end
 
     assert_response :success
     assert_match %r{^\{"trackers":.+\}$}, response.body
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/memberships_test.rb
--- a/test/integration/api_test/memberships_test.rb
+++ b/test/integration/api_test/memberships_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::MembershipsTest < ActionController::IntegrationTest
+class Redmine::ApiTest::MembershipsTest < Redmine::ApiTest::Base
   fixtures :projects, :users, :roles, :members, :member_roles
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/news_test.rb
--- a/test/integration/api_test/news_test.rb
+++ b/test/integration/api_test/news_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,8 +16,8 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../../test_helper', __FILE__)
-require 'pp'
-class ApiTest::NewsTest < ActionController::IntegrationTest
+
+class Redmine::ApiTest::NewsTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
@@ -25,7 +25,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :news
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/projects_test.rb
--- a/test/integration/api_test/projects_test.rb
+++ b/test/integration/api_test/projects_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::ProjectsTest < ActionController::IntegrationTest
+class Redmine::ApiTest::ProjectsTest < Redmine::ApiTest::Base
   fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
            :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
            :attachments, :custom_fields, :custom_values, :time_entries, :issue_categories
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/queries_test.rb
--- a/test/integration/api_test/queries_test.rb
+++ b/test/integration/api_test/queries_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::QueriesTest < ActionController::IntegrationTest
+class Redmine::ApiTest::QueriesTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
@@ -25,7 +25,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :queries
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/roles_test.rb
--- a/test/integration/api_test/roles_test.rb
+++ b/test/integration/api_test/roles_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::RolesTest < ActionController::IntegrationTest
+class Redmine::ApiTest::RolesTest < Redmine::ApiTest::Base
   fixtures :roles
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/time_entries_test.rb
--- a/test/integration/api_test/time_entries_test.rb
+++ b/test/integration/api_test/time_entries_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::TimeEntriesTest < ActionController::IntegrationTest
+class Redmine::ApiTest::TimeEntriesTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
@@ -25,7 +25,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :time_entries
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/token_authentication_test.rb
--- a/test/integration/api_test/token_authentication_test.rb
+++ b/test/integration/api_test/token_authentication_test.rb
@@ -1,14 +1,30 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::TokenAuthenticationTest < ActionController::IntegrationTest
+class Redmine::ApiTest::TokenAuthenticationTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
            :roles,
            :member_roles,
            :members,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   def setup
     Setting.rest_api_enabled = '1'
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/trackers_test.rb
--- a/test/integration/api_test/trackers_test.rb
+++ b/test/integration/api_test/trackers_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::TrackersTest < ActionController::IntegrationTest
+class Redmine::ApiTest::TrackersTest < Redmine::ApiTest::Base
   fixtures :trackers
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/users_test.rb
--- a/test/integration/api_test/users_test.rb
+++ b/test/integration/api_test/users_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,8 +16,8 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../../test_helper', __FILE__)
-require 'pp'
-class ApiTest::UsersTest < ActionController::IntegrationTest
+
+class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
   fixtures :users, :members, :member_roles, :roles, :projects
 
   def setup
@@ -96,6 +96,30 @@
     end
   end
 
+  test "GET /users/:id should not return login for other user" do
+    get '/users/3.xml', {}, credentials('jsmith')
+    assert_response :success
+    assert_no_tag 'user', :child => {:tag => 'login'}
+  end
+
+  test "GET /users/:id should return login for current user" do
+    get '/users/2.xml', {}, credentials('jsmith')
+    assert_response :success
+    assert_tag 'user', :child => {:tag => 'login', :content => 'jsmith'}
+  end
+
+  test "GET /users/:id should not return api_key for other user" do
+    get '/users/3.xml', {}, credentials('jsmith')
+    assert_response :success
+    assert_no_tag 'user', :child => {:tag => 'api_key'}
+  end
+
+  test "GET /users/:id should return api_key for current user" do
+    get '/users/2.xml', {}, credentials('jsmith')
+    assert_response :success
+    assert_tag 'user', :child => {:tag => 'api_key', :content => User.find(2).api_key}
+  end
+
   context "POST /users" do
     context "with valid parameters" do
       setup do
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/versions_test.rb
--- a/test/integration/api_test/versions_test.rb
+++ b/test/integration/api_test/versions_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::VersionsTest < ActionController::IntegrationTest
+class Redmine::ApiTest::VersionsTest < Redmine::ApiTest::Base
   fixtures :projects, :trackers, :issue_statuses, :issues,
            :enumerations, :users, :issue_categories,
            :projects_trackers,
@@ -25,7 +25,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :versions
 
   def setup
@@ -83,6 +82,29 @@
         assert_tag 'version', :child => {:tag => 'id', :content => version.id.to_s}
       end
 
+      should "create the version with custom fields" do
+        field = VersionCustomField.generate!
+
+        assert_difference 'Version.count' do
+          post '/projects/1/versions.xml', {
+              :version => {
+                :name => 'API test',
+                :custom_fields => [
+                  {'id' => field.id.to_s, 'value' => 'Some value'}
+                ]
+              }
+            }, credentials('jsmith')
+        end
+
+        version = Version.first(:order => 'id DESC')
+        assert_equal 'API test', version.name
+        assert_equal 'Some value', version.custom_field_value(field)
+
+        assert_response :created
+        assert_equal 'application/xml', @response.content_type
+        assert_select 'version>custom_fields>custom_field[id=?]>value', field.id.to_s, 'Some value'
+      end
+
       context "with failure" do
         should "return the errors" do
           assert_no_difference('Version.count') do
diff -r 0a574315af3e -r 4f746d8966dd test/integration/api_test/wiki_pages_test.rb
--- a/test/integration/api_test/wiki_pages_test.rb
+++ b/test/integration/api_test/wiki_pages_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
 
 require File.expand_path('../../../test_helper', __FILE__)
 
-class ApiTest::WikiPagesTest < ActionController::IntegrationTest
+class Redmine::ApiTest::WikiPagesTest < Redmine::ApiTest::Base
   fixtures :projects, :users, :roles, :members, :member_roles,
            :enabled_modules, :wikis, :wiki_pages, :wiki_contents,
            :wiki_content_versions, :attachments
diff -r 0a574315af3e -r 4f746d8966dd test/integration/application_test.rb
--- a/test/integration/application_test.rb
+++ b/test/integration/application_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -26,8 +26,7 @@
            :roles,
            :member_roles,
            :members,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   def test_set_localization
     Setting.default_language = 'en'
diff -r 0a574315af3e -r 4f746d8966dd test/integration/attachments_test.rb
--- /dev/null
+++ b/test/integration/attachments_test.rb
@@ -0,0 +1,132 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class AttachmentsTest < ActionController::IntegrationTest
+  fixtures :projects, :enabled_modules,
+           :users, :roles, :members, :member_roles,
+           :trackers, :projects_trackers,
+           :issue_statuses, :enumerations
+
+  def test_upload_as_js_and_attach_to_an_issue
+    log_user('jsmith', 'jsmith')
+
+    token = ajax_upload('myupload.txt', 'File content')
+
+    assert_difference 'Issue.count' do
+      post '/projects/ecookbook/issues', {
+          :issue => {:tracker_id => 1, :subject => 'Issue with upload'},
+          :attachments => {'1' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
+        }
+      assert_response 302
+    end
+
+    issue = Issue.order('id DESC').first
+    assert_equal 'Issue with upload', issue.subject
+    assert_equal 1, issue.attachments.count
+
+    attachment = issue.attachments.first
+    assert_equal 'myupload.txt', attachment.filename
+    assert_equal 'My uploaded file', attachment.description
+    assert_equal 'File content'.length, attachment.filesize
+  end
+
+  def test_upload_as_js_and_preview_as_inline_attachment
+    log_user('jsmith', 'jsmith')
+
+    token = ajax_upload('myupload.jpg', 'JPEG content')
+
+    post '/issues/preview/new/ecookbook', {
+        :issue => {:tracker_id => 1, :description => 'Inline upload: !myupload.jpg!'},
+        :attachments => {'1' => {:filename => 'myupload.jpg', :description => 'My uploaded file', :token => token}}
+      }
+    assert_response :success
+
+    attachment_path = response.body.match(%r{<img src="(/attachments/download/\d+/myupload.jpg)"})[1]
+    assert_not_nil token, "No attachment path found in response:\n#{response.body}"
+
+    get attachment_path
+    assert_response :success
+    assert_equal 'JPEG content', response.body
+  end
+
+  def test_upload_and_resubmit_after_validation_failure
+    log_user('jsmith', 'jsmith')
+
+    token = ajax_upload('myupload.txt', 'File content')
+
+    assert_no_difference 'Issue.count' do
+      post '/projects/ecookbook/issues', {
+          :issue => {:tracker_id => 1, :subject => ''},
+          :attachments => {'1' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
+        }
+      assert_response :success
+    end
+    assert_select 'input[type=hidden][name=?][value=?]', 'attachments[p0][token]', token
+    assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'myupload.txt'
+    assert_select 'input[name=?][value=?]', 'attachments[p0][description]', 'My uploaded file'
+
+    assert_difference 'Issue.count' do
+      post '/projects/ecookbook/issues', {
+          :issue => {:tracker_id => 1, :subject => 'Issue with upload'},
+          :attachments => {'p0' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
+        }
+      assert_response 302
+    end
+
+    issue = Issue.order('id DESC').first
+    assert_equal 'Issue with upload', issue.subject
+    assert_equal 1, issue.attachments.count
+
+    attachment = issue.attachments.first
+    assert_equal 'myupload.txt', attachment.filename
+    assert_equal 'My uploaded file', attachment.description
+    assert_equal 'File content'.length, attachment.filesize
+  end
+
+  def test_upload_as_js_and_destroy
+    log_user('jsmith', 'jsmith')
+
+    token = ajax_upload('myupload.txt', 'File content')
+
+    attachment = Attachment.order('id DESC').first
+    attachment_path = "/attachments/#{attachment.id}.js?attachment_id=1"
+    assert_include "href: '#{attachment_path}'", response.body, "Path to attachment: #{attachment_path} not found in response:\n#{response.body}"
+
+    assert_difference 'Attachment.count', -1 do
+      delete attachment_path
+      assert_response :success
+    end
+
+    assert_include "$('#attachments_1').remove();", response.body
+  end
+
+  private
+
+  def ajax_upload(filename, content, attachment_id=1)
+    assert_difference 'Attachment.count' do
+      post "/uploads.js?attachment_id=#{attachment_id}&filename=#{filename}", content, {"CONTENT_TYPE" => 'application/octet-stream'}
+      assert_response :success
+      assert_equal 'text/javascript', response.content_type
+    end
+
+    token = response.body.match(/\.val\('(\d+\.[0-9a-f]+)'\)/)[1]
+    assert_not_nil token, "No upload token found in response:\n#{response.body}"
+    token
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd test/integration/issues_test.rb
--- a/test/integration/issues_test.rb
+++ b/test/integration/issues_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -65,15 +65,6 @@
     assert_equal 1, issue.status.id
   end
 
-  def test_update_issue_form
-    log_user('jsmith', 'jsmith')
-    post 'projects/ecookbook/issues/new', :issue => { :tracker_id => "2"}
-    assert_response :success
-    assert_tag 'select',
-      :attributes => {:name => 'issue[tracker_id]'},
-      :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}}
-  end
-
   # add then remove 2 attachments to an issue
   def test_issue_attachments
     log_user('jsmith', 'jsmith')
diff -r 0a574315af3e -r 4f746d8966dd test/integration/layout_test.rb
--- a/test/integration/layout_test.rb
+++ b/test/integration/layout_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -24,8 +24,7 @@
            :roles,
            :member_roles,
            :members,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   test "browsing to a missing page should render the base layout" do
     get "/users/100000000"
@@ -86,6 +85,26 @@
       get '/issues'
       assert_not_include "/javascripts/i18n/jquery.ui.datepicker", response.body
     end
+
+    with_settings :default_language => 'zh' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-zh-CN.js", response.body
+    end
+
+    with_settings :default_language => 'zh-TW' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-zh-TW.js", response.body
+    end
+
+    with_settings :default_language => 'pt' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-pt.js", response.body
+    end
+
+    with_settings :default_language => 'pt-BR' do
+      get '/issues'
+      assert_include "/javascripts/i18n/jquery.ui.datepicker-pt-BR.js", response.body
+    end
   end
 
   def test_search_field_outside_project_should_link_to_global_search
diff -r 0a574315af3e -r 4f746d8966dd test/integration/lib/redmine/hook_test.rb
--- a/test/integration/lib/redmine/hook_test.rb
+++ b/test/integration/lib/redmine/hook_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/lib/redmine/menu_manager_test.rb
--- a/test/integration/lib/redmine/menu_manager_test.rb
+++ b/test/integration/lib/redmine/menu_manager_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -26,8 +26,7 @@
            :roles,
            :member_roles,
            :members,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   def test_project_menu_with_specific_locale
     get 'projects/ecookbook/issues', { }, 'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
diff -r 0a574315af3e -r 4f746d8966dd test/integration/lib/redmine/themes_test.rb
--- a/test/integration/lib/redmine/themes_test.rb
+++ b/test/integration/lib/redmine/themes_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/projects_test.rb
--- a/test/integration/projects_test.rb
+++ b/test/integration/projects_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/repositories_git_test.rb
--- a/test/integration/repositories_git_test.rb
+++ b/test/integration/repositories_git_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/account_test.rb
--- a/test/integration/routing/account_test.rb
+++ b/test/integration/routing/account_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,10 +25,12 @@
           { :controller => 'account', :action => 'login' }
         )
     end
-    assert_routing(
-        { :method => 'get', :path => "/logout" },
-        { :controller => 'account', :action => 'logout' }
-      )
+    ["get", "post"].each do |method|
+      assert_routing(
+          { :method => method, :path => "/logout" },
+          { :controller => 'account', :action => 'logout' }
+        )
+    end
     ["get", "post"].each do |method|
       assert_routing(
           { :method => method, :path => "/account/register" },
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/activities_test.rb
--- a/test/integration/routing/activities_test.rb
+++ b/test/integration/routing/activities_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/admin_test.rb
--- a/test/integration/routing/admin_test.rb
+++ b/test/integration/routing/admin_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/attachments_test.rb
--- a/test/integration/routing/attachments_test.rb
+++ b/test/integration/routing/attachments_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/auth_sources_test.rb
--- a/test/integration/routing/auth_sources_test.rb
+++ b/test/integration/routing/auth_sources_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -51,5 +51,9 @@
         { :controller => 'auth_sources', :action => 'test_connection',
           :id => '1234' }
       )
+    assert_routing(
+        { :method => 'get', :path => "/auth_sources/autocomplete_for_new_user" },
+        { :controller => 'auth_sources', :action => 'autocomplete_for_new_user' }
+      )
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/auto_completes_test.rb
--- a/test/integration/routing/auto_completes_test.rb
+++ b/test/integration/routing/auto_completes_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/boards_test.rb
--- a/test/integration/routing/boards_test.rb
+++ b/test/integration/routing/boards_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/calendars_test.rb
--- a/test/integration/routing/calendars_test.rb
+++ b/test/integration/routing/calendars_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/comments_test.rb
--- a/test/integration/routing/comments_test.rb
+++ b/test/integration/routing/comments_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/context_menus_test.rb
--- a/test/integration/routing/context_menus_test.rb
+++ b/test/integration/routing/context_menus_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/custom_fields_test.rb
--- a/test/integration/routing/custom_fields_test.rb
+++ b/test/integration/routing/custom_fields_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/documents_test.rb
--- a/test/integration/routing/documents_test.rb
+++ b/test/integration/routing/documents_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/enumerations_test.rb
--- a/test/integration/routing/enumerations_test.rb
+++ b/test/integration/routing/enumerations_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/files_test.rb
--- a/test/integration/routing/files_test.rb
+++ b/test/integration/routing/files_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/gantts_test.rb
--- a/test/integration/routing/gantts_test.rb
+++ b/test/integration/routing/gantts_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/groups_test.rb
--- a/test/integration/routing/groups_test.rb
+++ b/test/integration/routing/groups_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -48,6 +48,10 @@
         { :controller => 'groups', :action => 'autocomplete_for_user', :id => '1' }
       )
     assert_routing(
+        { :method => 'get', :path => "/groups/1/autocomplete_for_user.js" },
+        { :controller => 'groups', :action => 'autocomplete_for_user', :id => '1', :format => 'js' }
+      )
+    assert_routing(
         { :method => 'get', :path => "/groups/1" },
         { :controller => 'groups', :action => 'show', :id => '1' }
       )
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/issue_categories_test.rb
--- a/test/integration/routing/issue_categories_test.rb
+++ b/test/integration/routing/issue_categories_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/issue_relations_test.rb
--- a/test/integration/routing/issue_relations_test.rb
+++ b/test/integration/routing/issue_relations_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/issue_statuses_test.rb
--- a/test/integration/routing/issue_statuses_test.rb
+++ b/test/integration/routing/issue_statuses_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/issues_test.rb
--- a/test/integration/routing/issues_test.rb
+++ b/test/integration/routing/issues_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -107,8 +107,8 @@
   def test_issues_form_update
     ["post", "put"].each do |method|
       assert_routing(
-          { :method => method, :path => "/projects/23/issues/new" },
-          { :controller => 'issues', :action => 'new', :project_id => '23' }
+          { :method => method, :path => "/projects/23/issues/update_form" },
+          { :controller => 'issues', :action => 'update_form', :project_id => '23' }
         )
     end
   end
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/journals_test.rb
--- a/test/integration/routing/journals_test.rb
+++ b/test/integration/routing/journals_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/mail_handler_test.rb
--- a/test/integration/routing/mail_handler_test.rb
+++ b/test/integration/routing/mail_handler_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/members_test.rb
--- a/test/integration/routing/members_test.rb
+++ b/test/integration/routing/members_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -55,5 +55,9 @@
         { :method => 'get', :path => "/projects/5234/memberships/autocomplete" },
         { :controller => 'members', :action => 'autocomplete', :project_id => '5234' }
       )
+    assert_routing(
+        { :method => 'get', :path => "/projects/5234/memberships/autocomplete.js" },
+        { :controller => 'members', :action => 'autocomplete', :project_id => '5234', :format => 'js' }
+      )
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/messages_test.rb
--- a/test/integration/routing/messages_test.rb
+++ b/test/integration/routing/messages_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/my_test.rb
--- a/test/integration/routing/my_test.rb
+++ b/test/integration/routing/my_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/news_test.rb
--- a/test/integration/routing/news_test.rb
+++ b/test/integration/routing/news_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/previews_test.rb
--- a/test/integration/routing/previews_test.rb
+++ b/test/integration/routing/previews_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -19,7 +19,7 @@
 
 class RoutingPreviewsTest < ActionController::IntegrationTest
   def test_previews
-    ["get", "post"].each do |method|
+    ["get", "post", "put"].each do |method|
       assert_routing(
           { :method => method, :path => "/issues/preview/new/123" },
           { :controller => 'previews', :action => 'issue', :project_id => '123' }
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/project_enumerations_test.rb
--- a/test/integration/routing/project_enumerations_test.rb
+++ b/test/integration/routing/project_enumerations_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/projects_test.rb
--- a/test/integration/routing/projects_test.rb
+++ b/test/integration/routing/projects_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/queries_test.rb
--- a/test/integration/routing/queries_test.rb
+++ b/test/integration/routing/queries_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/reports_test.rb
--- a/test/integration/routing/reports_test.rb
+++ b/test/integration/routing/reports_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/repositories_test.rb
--- a/test/integration/routing/repositories_test.rb
+++ b/test/integration/routing/repositories_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/roles_test.rb
--- a/test/integration/routing/roles_test.rb
+++ b/test/integration/routing/roles_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/search_test.rb
--- a/test/integration/routing/search_test.rb
+++ b/test/integration/routing/search_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/settings_test.rb
--- a/test/integration/routing/settings_test.rb
+++ b/test/integration/routing/settings_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/sys_test.rb
--- a/test/integration/routing/sys_test.rb
+++ b/test/integration/routing/sys_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/timelog_test.rb
--- a/test/integration/routing/timelog_test.rb
+++ b/test/integration/routing/timelog_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/trackers_test.rb
--- a/test/integration/routing/trackers_test.rb
+++ b/test/integration/routing/trackers_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/users_test.rb
--- a/test/integration/routing/users_test.rb
+++ b/test/integration/routing/users_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/versions_test.rb
--- a/test/integration/routing/versions_test.rb
+++ b/test/integration/routing/versions_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/watchers_test.rb
--- a/test/integration/routing/watchers_test.rb
+++ b/test/integration/routing/watchers_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -32,7 +32,7 @@
         { :controller => 'watchers', :action => 'create' }
       )
     assert_routing(
-        { :method => 'post', :path => "/watchers/destroy" },
+        { :method => 'delete', :path => "/watchers" },
         { :controller => 'watchers', :action => 'destroy' }
       )
     assert_routing(
@@ -44,8 +44,18 @@
         { :controller => 'watchers', :action => 'watch' }
       )
     assert_routing(
-        { :method => 'post', :path => "/watchers/unwatch" },
+        { :method => 'delete', :path => "/watchers/watch" },
         { :controller => 'watchers', :action => 'unwatch' }
       )
+    assert_routing(
+        { :method => 'post', :path => "/issues/12/watchers.xml" },
+        { :controller => 'watchers', :action => 'create',
+          :object_type => 'issue', :object_id => '12', :format => 'xml' }
+      )
+    assert_routing(
+        { :method => 'delete', :path => "/issues/12/watchers/3.xml" },
+        { :controller => 'watchers', :action => 'destroy',
+          :object_type => 'issue', :object_id => '12', :user_id => '3', :format => 'xml'}
+      )
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/welcome_test.rb
--- a/test/integration/routing/welcome_test.rb
+++ b/test/integration/routing/welcome_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/wiki_test.rb
--- a/test/integration/routing/wiki_test.rb
+++ b/test/integration/routing/wiki_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -53,6 +53,10 @@
          { :controller => 'wiki', :action => 'annotate', :project_id => '1',
            :id => 'CookBook_documentation', :version => '2' }
        )
+    # Make sure we don't route wiki page sub-uris to let plugins handle them
+    assert_raise(ActionController::RoutingError) do
+      assert_recognizes({}, {:method => 'get', :path => "/projects/1/wiki/CookBook_documentation/whatever"})
+    end
   end
 
   def test_wiki_misc
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/wikis_test.rb
--- a/test/integration/routing/wikis_test.rb
+++ b/test/integration/routing/wikis_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/routing/workflows_test.rb
--- a/test/integration/routing/workflows_test.rb
+++ b/test/integration/routing/workflows_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/integration/users_test.rb
--- a/test/integration/users_test.rb
+++ b/test/integration/users_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/object_helpers.rb
--- a/test/object_helpers.rb
+++ b/test/object_helpers.rb
@@ -3,7 +3,7 @@
     @generated_user_login ||= 'user0'
     @generated_user_login.succ!
     user = User.new(attributes)
-    user.login = @generated_user_login if user.login.blank?
+    user.login = @generated_user_login.dup if user.login.blank?
     user.mail = "#{@generated_user_login}@example.com" if user.mail.blank?
     user.firstname = "Bob" if user.firstname.blank?
     user.lastname = "Doe" if user.lastname.blank?
@@ -22,7 +22,7 @@
     @generated_group_name ||= 'Group 0'
     @generated_group_name.succ!
     group = Group.new(attributes)
-    group.name = @generated_group_name if group.name.blank?
+    group.name = @generated_group_name.dup if group.name.blank?
     yield group if block_given?
     group.save!
     group
@@ -32,18 +32,24 @@
     @generated_project_identifier ||= 'project-0000'
     @generated_project_identifier.succ!
     project = Project.new(attributes)
-    project.name = @generated_project_identifier if project.name.blank?
-    project.identifier = @generated_project_identifier if project.identifier.blank?
+    project.name = @generated_project_identifier.dup if project.name.blank?
+    project.identifier = @generated_project_identifier.dup if project.identifier.blank?
     yield project if block_given?
     project.save!
     project
   end
 
+  def Project.generate_with_parent!(parent, attributes={})
+    project = Project.generate!(attributes)
+    project.set_parent!(parent)
+    project
+  end
+
   def Tracker.generate!(attributes={})
     @generated_tracker_name ||= 'Tracker 0'
     @generated_tracker_name.succ!
     tracker = Tracker.new(attributes)
-    tracker.name = @generated_tracker_name if tracker.name.blank?
+    tracker.name = @generated_tracker_name.dup if tracker.name.blank?
     yield tracker if block_given?
     tracker.save!
     tracker
@@ -53,7 +59,7 @@
     @generated_role_name ||= 'Role 0'
     @generated_role_name.succ!
     role = Role.new(attributes)
-    role.name = @generated_role_name if role.name.blank?
+    role.name = @generated_role_name.dup if role.name.blank?
     yield role if block_given?
     role.save!
     role
@@ -92,17 +98,29 @@
     @generated_version_name ||= 'Version 0'
     @generated_version_name.succ!
     version = Version.new(attributes)
-    version.name = @generated_version_name if version.name.blank?
+    version.name = @generated_version_name.dup if version.name.blank?
     yield version if block_given?
     version.save!
     version
   end
 
+  def TimeEntry.generate!(attributes={})
+    entry = TimeEntry.new(attributes)
+    entry.user ||= User.find(2)
+    entry.issue ||= Issue.find(1) unless entry.project
+    entry.project ||= entry.issue.project
+    entry.activity ||= TimeEntryActivity.first
+    entry.spent_on ||= Date.today
+    entry.hours ||= 1.0
+    entry.save!
+    entry
+  end
+
   def AuthSource.generate!(attributes={})
     @generated_auth_source_name ||= 'Auth 0'
     @generated_auth_source_name.succ!
     source = AuthSource.new(attributes)
-    source.name = @generated_auth_source_name if source.name.blank?
+    source.name = @generated_auth_source_name.dup if source.name.blank?
     yield source if block_given?
     source.save!
     source
@@ -112,8 +130,8 @@
     @generated_board_name ||= 'Forum 0'
     @generated_board_name.succ!
     board = Board.new(attributes)
-    board.name = @generated_board_name if board.name.blank?
-    board.description = @generated_board_name if board.description.blank?
+    board.name = @generated_board_name.dup if board.name.blank?
+    board.description = @generated_board_name.dup if board.description.blank?
     yield board if block_given?
     board.save!
     board
@@ -126,8 +144,19 @@
     attachment = Attachment.new(attributes)
     attachment.container ||= Issue.find(1)
     attachment.author ||= User.find(2)
-    attachment.filename = @generated_filename if attachment.filename.blank?
+    attachment.filename = @generated_filename.dup if attachment.filename.blank?
     attachment.save!
     attachment
   end
+
+  def CustomField.generate!(attributes={})
+    @generated_custom_field_name ||= 'Custom field 0'
+    @generated_custom_field_name.succ!
+    field = new(attributes)
+    field.name = @generated_custom_field_name.dup if field.name.blank?
+    field.field_format = 'string' if field.field_format.blank?
+    yield field if block_given?
+    field.save!
+    field
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/test_helper.rb
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -26,30 +26,10 @@
 
 class ActiveSupport::TestCase
   include ActionDispatch::TestProcess
-  
-  # Transactional fixtures accelerate your tests by wrapping each test method
-  # in a transaction that's rolled back on completion.  This ensures that the
-  # test database remains unchanged so your fixtures don't have to be reloaded
-  # between every test method.  Fewer database queries means faster tests.
-  #
-  # Read Mike Clark's excellent walkthrough at
-  #   http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
-  #
-  # Every Active Record database supports transactions except MyISAM tables
-  # in MySQL.  Turn off transactional fixtures in this case; however, if you
-  # don't care one way or the other, switching from MyISAM to InnoDB tables
-  # is recommended.
+
   self.use_transactional_fixtures = true
-
-  # Instantiated fixtures are slow, but give you @david where otherwise you
-  # would need people(:david).  If you don't want to migrate your existing
-  # test cases which use the @david style and don't mind the speed hit (each
-  # instantiated fixtures translates to a database query per test method),
-  # then set this back to true.
   self.use_instantiated_fixtures  = false
 
-  # Add more helper methods to be used by all tests here...
-
   def log_user(login, password)
     User.anonymous
     get "/login"
@@ -107,7 +87,15 @@
   end
 
   def with_settings(options, &block)
-    saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].is_a?(Symbol) ? Setting[k] : Setting[k].dup; h}
+    saved_settings = options.keys.inject({}) do |h, k|
+      h[k] = case Setting[k]
+        when Symbol, false, true, nil
+          Setting[k]
+        else
+          Setting[k].dup
+        end
+      h
+    end
     options.each {|k, v| Setting[k] = v}
     yield
   ensure
@@ -209,286 +197,272 @@
   def mail_body(mail)
     mail.parts.first.body.encoded
   end
+end
 
-  # Shoulda macros
-  def self.should_render_404
-    should_respond_with :not_found
-    should_render_template 'common/error'
-  end
-
-  def self.should_have_before_filter(expected_method, options = {})
-    should_have_filter('before', expected_method, options)
-  end
-
-  def self.should_have_after_filter(expected_method, options = {})
-    should_have_filter('after', expected_method, options)
-  end
-
-  def self.should_have_filter(filter_type, expected_method, options)
-    description = "have #{filter_type}_filter :#{expected_method}"
-    description << " with #{options.inspect}" unless options.empty?
-
-    should description do
-      klass = "action_controller/filters/#{filter_type}_filter".classify.constantize
-      expected = klass.new(:filter, expected_method.to_sym, options)
-      assert_equal 1, @controller.class.filter_chain.select { |filter|
-        filter.method == expected.method && filter.kind == expected.kind &&
-        filter.options == expected.options && filter.class == expected.class
-      }.size
-    end
-  end
-
-  # Test that a request allows the three types of API authentication
-  #
-  # * HTTP Basic with username and password
-  # * HTTP Basic with an api key for the username
-  # * Key based with the key=X parameter
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_api_authentication(http_method, url, parameters={}, options={})
-    should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters, options)
-    should_allow_http_basic_auth_with_key(http_method, url, parameters, options)
-    should_allow_key_based_auth(http_method, url, parameters, options)
-  end
-
-  # Test that a request allows the username and password for HTTP BASIC
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters={}, options={})
-    success_code = options[:success_code] || :success
-    failure_code = options[:failure_code] || :unauthorized
-
-    context "should allow http basic auth using a username and password for #{http_method} #{url}" do
-      context "with a valid HTTP authentication" do
-        setup do
-          @user = User.generate! do |user|
-            user.admin = true
-            user.password = 'my_password'
+module Redmine
+  module ApiTest
+    # Base class for API tests
+    class Base < ActionDispatch::IntegrationTest
+      # Test that a request allows the three types of API authentication
+      #
+      # * HTTP Basic with username and password
+      # * HTTP Basic with an api key for the username
+      # * Key based with the key=X parameter
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_api_authentication(http_method, url, parameters={}, options={})
+        should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters, options)
+        should_allow_http_basic_auth_with_key(http_method, url, parameters, options)
+        should_allow_key_based_auth(http_method, url, parameters, options)
+      end
+    
+      # Test that a request allows the username and password for HTTP BASIC
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters={}, options={})
+        success_code = options[:success_code] || :success
+        failure_code = options[:failure_code] || :unauthorized
+    
+        context "should allow http basic auth using a username and password for #{http_method} #{url}" do
+          context "with a valid HTTP authentication" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+                user.password = 'my_password'
+              end
+              send(http_method, url, parameters, credentials(@user.login, 'my_password'))
+            end
+    
+            should_respond_with success_code
+            should_respond_with_content_type_based_on_url(url)
+            should "login as the user" do
+              assert_equal @user, User.current
+            end
           end
-          send(http_method, url, parameters, credentials(@user.login, 'my_password'))
-        end
-
-        should_respond_with success_code
-        should_respond_with_content_type_based_on_url(url)
-        should "login as the user" do
-          assert_equal @user, User.current
+    
+          context "with an invalid HTTP authentication" do
+            setup do
+              @user = User.generate!
+              send(http_method, url, parameters, credentials(@user.login, 'wrong_password'))
+            end
+    
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "not login as the user" do
+              assert_equal User.anonymous, User.current
+            end
+          end
+    
+          context "without credentials" do
+            setup do
+              send(http_method, url, parameters)
+            end
+    
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "include_www_authenticate_header" do
+              assert @controller.response.headers.has_key?('WWW-Authenticate')
+            end
+          end
         end
       end
-
-      context "with an invalid HTTP authentication" do
-        setup do
-          @user = User.generate!
-          send(http_method, url, parameters, credentials(@user.login, 'wrong_password'))
-        end
-
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
+    
+      # Test that a request allows the API key with HTTP BASIC
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_http_basic_auth_with_key(http_method, url, parameters={}, options={})
+        success_code = options[:success_code] || :success
+        failure_code = options[:failure_code] || :unauthorized
+    
+        context "should allow http basic auth with a key for #{http_method} #{url}" do
+          context "with a valid HTTP authentication using the API token" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+              end
+              @token = Token.create!(:user => @user, :action => 'api')
+              send(http_method, url, parameters, credentials(@token.value, 'X'))
+            end
+            should_respond_with success_code
+            should_respond_with_content_type_based_on_url(url)
+            should_be_a_valid_response_string_based_on_url(url)
+            should "login as the user" do
+              assert_equal @user, User.current
+            end
+          end
+    
+          context "with an invalid HTTP authentication" do
+            setup do
+              @user = User.generate!
+              @token = Token.create!(:user => @user, :action => 'feeds')
+              send(http_method, url, parameters, credentials(@token.value, 'X'))
+            end
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "not login as the user" do
+              assert_equal User.anonymous, User.current
+            end
+          end
         end
       end
-
-      context "without credentials" do
-        setup do
-          send(http_method, url, parameters)
+    
+      # Test that a request allows full key authentication
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url, without the key=ZXY parameter
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_key_based_auth(http_method, url, parameters={}, options={})
+        success_code = options[:success_code] || :success
+        failure_code = options[:failure_code] || :unauthorized
+    
+        context "should allow key based auth using key=X for #{http_method} #{url}" do
+          context "with a valid api token" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+              end
+              @token = Token.create!(:user => @user, :action => 'api')
+              # Simple url parse to add on ?key= or &key=
+              request_url = if url.match(/\?/)
+                              url + "&key=#{@token.value}"
+                            else
+                              url + "?key=#{@token.value}"
+                            end
+              send(http_method, request_url, parameters)
+            end
+            should_respond_with success_code
+            should_respond_with_content_type_based_on_url(url)
+            should_be_a_valid_response_string_based_on_url(url)
+            should "login as the user" do
+              assert_equal @user, User.current
+            end
+          end
+    
+          context "with an invalid api token" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+              end
+              @token = Token.create!(:user => @user, :action => 'feeds')
+              # Simple url parse to add on ?key= or &key=
+              request_url = if url.match(/\?/)
+                              url + "&key=#{@token.value}"
+                            else
+                              url + "?key=#{@token.value}"
+                            end
+              send(http_method, request_url, parameters)
+            end
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "not login as the user" do
+              assert_equal User.anonymous, User.current
+            end
+          end
         end
-
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "include_www_authenticate_header" do
-          assert @controller.response.headers.has_key?('WWW-Authenticate')
+    
+        context "should allow key based auth using X-Redmine-API-Key header for #{http_method} #{url}" do
+          setup do
+            @user = User.generate! do |user|
+              user.admin = true
+            end
+            @token = Token.create!(:user => @user, :action => 'api')
+            send(http_method, url, parameters, {'X-Redmine-API-Key' => @token.value.to_s})
+          end
+          should_respond_with success_code
+          should_respond_with_content_type_based_on_url(url)
+          should_be_a_valid_response_string_based_on_url(url)
+          should "login as the user" do
+            assert_equal @user, User.current
+          end
+        end
+      end
+    
+      # Uses should_respond_with_content_type based on what's in the url:
+      #
+      # '/project/issues.xml' => should_respond_with_content_type :xml
+      # '/project/issues.json' => should_respond_with_content_type :json
+      #
+      # @param [String] url Request
+      def self.should_respond_with_content_type_based_on_url(url)
+        case
+        when url.match(/xml/i)
+          should "respond with XML" do
+            assert_equal 'application/xml', @response.content_type
+          end
+        when url.match(/json/i)
+          should "respond with JSON" do
+            assert_equal 'application/json', @response.content_type
+          end
+        else
+          raise "Unknown content type for should_respond_with_content_type_based_on_url: #{url}"
+        end
+      end
+    
+      # Uses the url to assert which format the response should be in
+      #
+      # '/project/issues.xml' => should_be_a_valid_xml_string
+      # '/project/issues.json' => should_be_a_valid_json_string
+      #
+      # @param [String] url Request
+      def self.should_be_a_valid_response_string_based_on_url(url)
+        case
+        when url.match(/xml/i)
+          should_be_a_valid_xml_string
+        when url.match(/json/i)
+          should_be_a_valid_json_string
+        else
+          raise "Unknown content type for should_be_a_valid_response_based_on_url: #{url}"
+        end
+      end
+    
+      # Checks that the response is a valid JSON string
+      def self.should_be_a_valid_json_string
+        should "be a valid JSON string (or empty)" do
+          assert(response.body.blank? || ActiveSupport::JSON.decode(response.body))
+        end
+      end
+    
+      # Checks that the response is a valid XML string
+      def self.should_be_a_valid_xml_string
+        should "be a valid XML string" do
+          assert REXML::Document.new(response.body)
+        end
+      end
+    
+      def self.should_respond_with(status)
+        should "respond with #{status}" do
+          assert_response status
         end
       end
     end
   end
+end
 
-  # Test that a request allows the API key with HTTP BASIC
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_http_basic_auth_with_key(http_method, url, parameters={}, options={})
-    success_code = options[:success_code] || :success
-    failure_code = options[:failure_code] || :unauthorized
-
-    context "should allow http basic auth with a key for #{http_method} #{url}" do
-      context "with a valid HTTP authentication using the API token" do
-        setup do
-          @user = User.generate! do |user|
-            user.admin = true
-          end
-          @token = Token.create!(:user => @user, :action => 'api')
-          send(http_method, url, parameters, credentials(@token.value, 'X'))
-        end
-        should_respond_with success_code
-        should_respond_with_content_type_based_on_url(url)
-        should_be_a_valid_response_string_based_on_url(url)
-        should "login as the user" do
-          assert_equal @user, User.current
-        end
-      end
-
-      context "with an invalid HTTP authentication" do
-        setup do
-          @user = User.generate!
-          @token = Token.create!(:user => @user, :action => 'feeds')
-          send(http_method, url, parameters, credentials(@token.value, 'X'))
-        end
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-    end
-  end
-
-  # Test that a request allows full key authentication
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url, without the key=ZXY parameter
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_key_based_auth(http_method, url, parameters={}, options={})
-    success_code = options[:success_code] || :success
-    failure_code = options[:failure_code] || :unauthorized
-
-    context "should allow key based auth using key=X for #{http_method} #{url}" do
-      context "with a valid api token" do
-        setup do
-          @user = User.generate! do |user|
-            user.admin = true
-          end
-          @token = Token.create!(:user => @user, :action => 'api')
-          # Simple url parse to add on ?key= or &key=
-          request_url = if url.match(/\?/)
-                          url + "&key=#{@token.value}"
-                        else
-                          url + "?key=#{@token.value}"
-                        end
-          send(http_method, request_url, parameters)
-        end
-        should_respond_with success_code
-        should_respond_with_content_type_based_on_url(url)
-        should_be_a_valid_response_string_based_on_url(url)
-        should "login as the user" do
-          assert_equal @user, User.current
-        end
-      end
-
-      context "with an invalid api token" do
-        setup do
-          @user = User.generate! do |user|
-            user.admin = true
-          end
-          @token = Token.create!(:user => @user, :action => 'feeds')
-          # Simple url parse to add on ?key= or &key=
-          request_url = if url.match(/\?/)
-                          url + "&key=#{@token.value}"
-                        else
-                          url + "?key=#{@token.value}"
-                        end
-          send(http_method, request_url, parameters)
-        end
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-    end
-
-    context "should allow key based auth using X-Redmine-API-Key header for #{http_method} #{url}" do
-      setup do
-        @user = User.generate! do |user|
-          user.admin = true
-        end
-        @token = Token.create!(:user => @user, :action => 'api')
-        send(http_method, url, parameters, {'X-Redmine-API-Key' => @token.value.to_s})
-      end
-      should_respond_with success_code
-      should_respond_with_content_type_based_on_url(url)
-      should_be_a_valid_response_string_based_on_url(url)
-      should "login as the user" do
-        assert_equal @user, User.current
-      end
-    end
-  end
-
-  # Uses should_respond_with_content_type based on what's in the url:
-  #
-  # '/project/issues.xml' => should_respond_with_content_type :xml
-  # '/project/issues.json' => should_respond_with_content_type :json
-  #
-  # @param [String] url Request
-  def self.should_respond_with_content_type_based_on_url(url)
-    case
-    when url.match(/xml/i)
-      should "respond with XML" do
-        assert_equal 'application/xml', @response.content_type
-      end
-    when url.match(/json/i)
-      should "respond with JSON" do
-        assert_equal 'application/json', @response.content_type
-      end
-    else
-      raise "Unknown content type for should_respond_with_content_type_based_on_url: #{url}"
-    end
-  end
-
-  # Uses the url to assert which format the response should be in
-  #
-  # '/project/issues.xml' => should_be_a_valid_xml_string
-  # '/project/issues.json' => should_be_a_valid_json_string
-  #
-  # @param [String] url Request
-  def self.should_be_a_valid_response_string_based_on_url(url)
-    case
-    when url.match(/xml/i)
-      should_be_a_valid_xml_string
-    when url.match(/json/i)
-      should_be_a_valid_json_string
-    else
-      raise "Unknown content type for should_be_a_valid_response_based_on_url: #{url}"
-    end
-  end
-
-  # Checks that the response is a valid JSON string
-  def self.should_be_a_valid_json_string
-    should "be a valid JSON string (or empty)" do
-      assert(response.body.blank? || ActiveSupport::JSON.decode(response.body))
-    end
-  end
-
-  # Checks that the response is a valid XML string
-  def self.should_be_a_valid_xml_string
-    should "be a valid XML string" do
-      assert REXML::Document.new(response.body)
-    end
-  end
-
-  def self.should_respond_with(status)
-    should "respond with #{status}" do
-      assert_response status
-    end
+# URL helpers do not work with config.threadsafe!
+# https://github.com/rspec/rspec-rails/issues/476#issuecomment-4705454
+ActionView::TestCase::TestController.instance_eval do
+  helper Rails.application.routes.url_helpers
+end
+ActionView::TestCase::TestController.class_eval do
+  def _routes
+    Rails.application.routes
   end
 end
-
-# Simple module to "namespace" all of the API tests
-module ApiTest
-end
diff -r 0a574315af3e -r 4f746d8966dd test/ui/base.rb
--- /dev/null
+++ b/test/ui/base.rb
@@ -0,0 +1,63 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+require 'capybara/rails'
+
+Capybara.default_driver = :selenium
+Capybara.register_driver :selenium do |app|
+  # Use the following driver definition to test locally using Chrome (also requires chromedriver to be in PATH)
+  # Capybara::Selenium::Driver.new(app, :browser => :chrome)
+  # Add :switches => %w[--lang=en] to force default browser locale to English
+  # Default for Selenium remote driver is to connect to local host on port 4444 
+  # This can be change using :url => 'http://localhost:9195' if necessary
+  # PhantomJS 1.8 now directly supports Webdriver Wire API, simply run it with `phantomjs --webdriver 4444`
+  # Add :desired_capabilities => Selenium::WebDriver::Remote::Capabilities.internet_explorer) to run on Selenium Grid Hub with IE
+  Capybara::Selenium::Driver.new(app, :browser => :remote)
+end
+
+module Redmine
+  module UiTest
+    # Base class for UI tests
+    class Base < ActionDispatch::IntegrationTest
+      include Capybara::DSL
+
+      # Stop ActiveRecord from wrapping tests in transactions
+      # Transactional fixtures do not work with Selenium tests, because Capybara
+      # uses a separate server thread, which the transactions would be hidden
+      self.use_transactional_fixtures = false
+
+      # Should not depend on locale since Redmine displays login page
+      # using default browser locale which depend on system locale for "real" browsers drivers
+      def log_user(login, password)
+        visit '/my/page'
+        assert_equal '/login', current_path
+        within('#login-form form') do
+          fill_in 'username', :with => login
+          fill_in 'password', :with => password
+          find('input[name=login]').click
+        end
+        assert_equal '/my/page', current_path
+      end
+
+      teardown do
+        Capybara.reset_sessions!    # Forget the (simulated) browser state
+        Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
+      end
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd test/ui/issues_test.rb
--- /dev/null
+++ b/test/ui/issues_test.rb
@@ -0,0 +1,217 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../base', __FILE__)
+
+class Redmine::UiTest::IssuesTest < Redmine::UiTest::Base
+  fixtures :projects, :users, :roles, :members, :member_roles,
+           :trackers, :projects_trackers, :enabled_modules, :issue_statuses, :issues,
+           :enumerations, :custom_fields, :custom_values, :custom_fields_trackers,
+           :watchers
+
+  def test_create_issue
+    log_user('jsmith', 'jsmith')
+    visit '/projects/ecookbook/issues/new'
+    within('form#issue-form') do
+      select 'Bug', :from => 'Tracker'
+      select 'Low', :from => 'Priority'
+      fill_in 'Subject', :with => 'new test issue'
+      fill_in 'Description', :with => 'new issue'
+      select '0 %', :from => 'Done'
+      fill_in 'Due date', :with => ''
+      select '', :from => 'Assignee'
+      fill_in 'Searchable field', :with => 'Value for field 2'
+      # click_button 'Create' would match both 'Create' and 'Create and continue' buttons
+      find('input[name=commit]').click
+    end
+
+    # find created issue
+    issue = Issue.find_by_subject("new test issue")
+    assert_kind_of Issue, issue
+
+    # check redirection
+    find 'div#flash_notice', :visible => true, :text => "Issue \##{issue.id} created."
+    assert_equal issue_path(:id => issue), current_path
+
+    # check issue attributes
+    assert_equal 'jsmith', issue.author.login
+    assert_equal 1, issue.project.id
+    assert_equal IssueStatus.find_by_name('New'), issue.status 
+    assert_equal Tracker.find_by_name('Bug'), issue.tracker
+    assert_equal IssuePriority.find_by_name('Low'), issue.priority
+    assert_equal 'Value for field 2', issue.custom_field_value(CustomField.find_by_name('Searchable field'))
+  end
+
+  def test_create_issue_with_form_update
+    field1 = IssueCustomField.create!(
+      :field_format => 'string',
+      :name => 'Field1',
+      :is_for_all => true,
+      :trackers => Tracker.find_all_by_id([1, 2])
+    )
+    field2 = IssueCustomField.create!(
+      :field_format => 'string',
+      :name => 'Field2',
+      :is_for_all => true,
+      :trackers => Tracker.find_all_by_id(2)
+    )
+
+    Role.non_member.add_permission! :add_issues
+    Role.non_member.remove_permission! :edit_issues, :add_issue_notes
+
+    log_user('someone', 'foo')
+    visit '/projects/ecookbook/issues/new'
+    assert page.has_no_content?(field2.name)
+    assert page.has_content?(field1.name)
+
+    fill_in 'Subject', :with => 'New test issue'
+    fill_in 'Description', :with => 'New test issue description'
+    fill_in field1.name, :with => 'CF1 value'
+    select 'Low', :from => 'Priority'
+
+    # field2 should show up when changing tracker
+    select 'Feature request', :from => 'Tracker'
+    assert page.has_content?(field2.name)
+    assert page.has_content?(field1.name)
+
+    fill_in field2.name, :with => 'CF2 value'
+    assert_difference 'Issue.count' do
+      page.first(:button, 'Create').click
+    end
+
+    issue = Issue.order('id desc').first
+    assert_equal 'New test issue', issue.subject
+    assert_equal 'New test issue description', issue.description
+    assert_equal 'Low', issue.priority.name
+    assert_equal 'CF1 value', issue.custom_field_value(field1)
+    assert_equal 'CF2 value', issue.custom_field_value(field2)
+  end
+
+  def test_create_issue_with_watchers
+    User.generate!(:firstname => 'Some', :lastname => 'Watcher')
+
+    log_user('jsmith', 'jsmith')
+    visit '/projects/ecookbook/issues/new'
+    fill_in 'Subject', :with => 'Issue with watchers'
+    # Add a project member as watcher
+    check 'Dave Lopper'
+    # Search for another user
+    click_link 'Search for watchers to add'
+    within('form#new-watcher-form') do
+      assert page.has_content?('Some One')
+      fill_in 'user_search', :with => 'watch'
+      assert page.has_no_content?('Some One')
+      check 'Some Watcher'
+      click_button 'Add'
+    end
+    assert_difference 'Issue.count' do
+      find('input[name=commit]').click
+    end
+
+    issue = Issue.order('id desc').first
+    assert_equal ['Dave Lopper', 'Some Watcher'], issue.watcher_users.map(&:name).sort
+  end
+
+  def test_preview_issue_description
+    log_user('jsmith', 'jsmith')
+    visit '/projects/ecookbook/issues/new'
+    within('form#issue-form') do
+      fill_in 'Subject', :with => 'new issue subject'
+      fill_in 'Description', :with => 'new issue description'
+      click_link 'Preview'
+    end
+    find 'div#preview fieldset', :visible => true, :text => 'new issue description'
+    assert_difference 'Issue.count' do
+      find('input[name=commit]').click
+    end
+
+    issue = Issue.order('id desc').first
+    assert_equal 'new issue description', issue.description
+  end
+
+  def test_update_issue_with_form_update
+    field = IssueCustomField.create!(
+      :field_format => 'string',
+      :name => 'Form update CF',
+      :is_for_all => true,
+      :trackers => Tracker.find_all_by_name('Feature request')
+    )
+
+    Role.non_member.add_permission! :edit_issues
+    Role.non_member.remove_permission! :add_issues, :add_issue_notes
+
+    log_user('someone', 'foo')
+    visit '/issues/1'
+    assert page.has_no_content?('Form update CF')
+
+    page.first(:link, 'Update').click
+    # the custom field should show up when changing tracker
+    select 'Feature request', :from => 'Tracker'
+    assert page.has_content?('Form update CF')
+
+    fill_in 'Form update', :with => 'CF value'
+    assert_no_difference 'Issue.count' do
+      page.first(:button, 'Submit').click
+    end
+
+    issue = Issue.find(1)
+    assert_equal 'CF value', issue.custom_field_value(field)
+  end
+
+  def test_remove_issue_watcher_from_sidebar
+    user = User.find(3)
+    Watcher.create!(:watchable => Issue.find(1), :user => user)
+
+    log_user('jsmith', 'jsmith')
+    visit '/issues/1'
+    assert page.first('#sidebar').has_content?('Watchers (1)')
+    assert page.first('#sidebar').has_content?(user.name)
+    assert_difference 'Watcher.count', -1 do
+      page.first('ul.watchers .user-3 a.delete').click
+    end
+    assert page.first('#sidebar').has_content?('Watchers (0)')
+    assert page.first('#sidebar').has_no_content?(user.name)
+  end
+
+  def test_watch_issue_via_context_menu
+    log_user('jsmith', 'jsmith')
+    visit '/issues'
+    find('tr#issue-1 td.updated_on').click
+    page.execute_script "$('tr#issue-1 td.updated_on').trigger('contextmenu');"
+    assert_difference 'Watcher.count' do
+      within('#context-menu') do
+        click_link 'Watch'
+      end
+    end
+    assert Issue.find(1).watched_by?(User.find_by_login('jsmith'))
+  end
+
+  def test_bulk_watch_issues_via_context_menu
+    log_user('jsmith', 'jsmith')
+    visit '/issues'
+    find('tr#issue-1 input[type=checkbox]').click
+    find('tr#issue-4 input[type=checkbox]').click
+    page.execute_script "$('tr#issue-1 td.updated_on').trigger('contextmenu');"
+    assert_difference 'Watcher.count', 2 do
+      within('#context-menu') do
+        click_link 'Watch'
+      end
+    end
+    assert Issue.find(1).watched_by?(User.find_by_login('jsmith'))
+    assert Issue.find(4).watched_by?(User.find_by_login('jsmith'))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/activity_test.rb
--- a/test/unit/activity_test.rb
+++ b/test/unit/activity_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -19,7 +19,8 @@
 
 class ActivityTest < ActiveSupport::TestCase
   fixtures :projects, :versions, :attachments, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
-           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages
+           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages, :time_entries,
+           :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
 
   def setup
     @project = Project.find(1)
@@ -87,6 +88,39 @@
     assert_equal %w(Project Version), events.collect(&:container_type).uniq.sort
   end
 
+  def test_event_group_for_issue
+    issue = Issue.find(1)
+    assert_equal issue, issue.event_group
+  end
+
+  def test_event_group_for_journal
+    issue = Issue.find(1)
+    journal = issue.journals.first
+    assert_equal issue, journal.event_group
+  end
+
+  def test_event_group_for_issue_time_entry
+    time = TimeEntry.where(:issue_id => 1).first
+    assert_equal time.issue, time.event_group
+  end
+
+  def test_event_group_for_project_time_entry
+    time = TimeEntry.where(:issue_id => nil).first
+    assert_equal time, time.event_group
+  end
+
+  def test_event_group_for_message
+    message = Message.find(1)
+    reply = message.children.first
+    assert_equal message, message.event_group
+    assert_equal message, reply.event_group
+  end
+
+  def test_event_group_for_wiki_content_version
+    content = WikiContent::Version.find(1)
+    assert_equal content.page, content.event_group
+  end
+
   private
 
   def find_events(user, options={})
diff -r 0a574315af3e -r 4f746d8966dd test/unit/attachment_test.rb
--- a/test/unit/attachment_test.rb
+++ b/test/unit/attachment_test.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -52,10 +52,25 @@
     assert_equal 'text/plain', a.content_type
     assert_equal 0, a.downloads
     assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
+
+    assert a.disk_directory
+    assert_match %r{\A\d{4}/\d{2}\z}, a.disk_directory
+
     assert File.exist?(a.diskfile)
     assert_equal 59, File.size(a.diskfile)
   end
 
+  def test_copy_should_preserve_attributes
+    a = Attachment.find(1)
+    copy = a.copy
+
+    assert_save copy
+    copy = Attachment.order('id DESC').first
+    %w(filename filesize content_type author_id created_on description digest disk_filename disk_directory diskfile).each do |attribute|
+      assert_equal a.send(attribute), copy.send(attribute), "#{attribute} was different"
+    end
+  end
+
   def test_size_should_be_validated_for_new_file
     with_settings :attachment_max_size => 0 do
       a = Attachment.new(:container => Issue.find(1),
@@ -168,42 +183,55 @@
     end
   end
 
-  context "Attachmnet.attach_files" do
-    should "attach the file" do
-      issue = Issue.first
-      assert_difference 'Attachment.count' do
-        Attachment.attach_files(issue,
-          '1' => {
-            'file' => uploaded_test_file('testfile.txt', 'text/plain'),
-            'description' => 'test'
-          })
-      end
+  def test_move_from_root_to_target_directory_should_move_root_files
+    a = Attachment.find(20)
+    assert a.disk_directory.blank?
+    # Create a real file for this fixture
+    File.open(a.diskfile, "w") do |f|
+      f.write "test file at the root of files directory"
+    end
+    assert a.readable?
+    Attachment.move_from_root_to_target_directory
 
-      attachment = Attachment.first(:order => 'id DESC')
-      assert_equal issue, attachment.container
-      assert_equal 'testfile.txt', attachment.filename
-      assert_equal 59, attachment.filesize
-      assert_equal 'test', attachment.description
-      assert_equal 'text/plain', attachment.content_type
-      assert File.exists?(attachment.diskfile)
-      assert_equal 59, File.size(attachment.diskfile)
+    a.reload
+    assert_equal '2012/05', a.disk_directory
+    assert a.readable?
+  end
+
+  test "Attachmnet.attach_files should attach the file" do
+    issue = Issue.first
+    assert_difference 'Attachment.count' do
+      Attachment.attach_files(issue,
+        '1' => {
+          'file' => uploaded_test_file('testfile.txt', 'text/plain'),
+          'description' => 'test'
+        })
     end
 
-    should "add unsaved files to the object as unsaved attachments" do
-      # Max size of 0 to force Attachment creation failures
-      with_settings(:attachment_max_size => 0) do
-        @project = Project.find(1)
-        response = Attachment.attach_files(@project, {
-                                             '1' => {'file' => mock_file, 'description' => 'test'},
-                                             '2' => {'file' => mock_file, 'description' => 'test'}
-                                           })
+    attachment = Attachment.first(:order => 'id DESC')
+    assert_equal issue, attachment.container
+    assert_equal 'testfile.txt', attachment.filename
+    assert_equal 59, attachment.filesize
+    assert_equal 'test', attachment.description
+    assert_equal 'text/plain', attachment.content_type
+    assert File.exists?(attachment.diskfile)
+    assert_equal 59, File.size(attachment.diskfile)
+  end
 
-        assert response[:unsaved].present?
-        assert_equal 2, response[:unsaved].length
-        assert response[:unsaved].first.new_record?
-        assert response[:unsaved].second.new_record?
-        assert_equal response[:unsaved], @project.unsaved_attachments
-      end
+  test "Attachmnet.attach_files should add unsaved files to the object as unsaved attachments" do
+    # Max size of 0 to force Attachment creation failures
+    with_settings(:attachment_max_size => 0) do
+      @project = Project.find(1)
+      response = Attachment.attach_files(@project, {
+                                           '1' => {'file' => mock_file, 'description' => 'test'},
+                                           '2' => {'file' => mock_file, 'description' => 'test'}
+                                         })
+
+      assert response[:unsaved].present?
+      assert_equal 2, response[:unsaved].length
+      assert response[:unsaved].first.new_record?
+      assert response[:unsaved].second.new_record?
+      assert_equal response[:unsaved], @project.unsaved_attachments
     end
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/auth_source_ldap_test.rb
--- a/test/unit/auth_source_ldap_test.rb
+++ b/test/unit/auth_source_ldap_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -58,61 +58,48 @@
   end
 
   if ldap_configured?
-    context '#authenticate' do
-      setup do
-        @auth = AuthSourceLdap.find(1)
-        @auth.update_attribute :onthefly_register, true
+    test '#authenticate with a valid LDAP user should return the user attributes' do
+      auth = AuthSourceLdap.find(1)
+      auth.update_attribute :onthefly_register, true
+
+      attributes =  auth.authenticate('example1','123456')
+      assert attributes.is_a?(Hash), "An hash was not returned"
+      assert_equal 'Example', attributes[:firstname]
+      assert_equal 'One', attributes[:lastname]
+      assert_equal 'example1@redmine.org', attributes[:mail]
+      assert_equal auth.id, attributes[:auth_source_id]
+      attributes.keys.each do |attribute|
+        assert User.new.respond_to?("#{attribute}="), "Unexpected :#{attribute} attribute returned"
       end
+    end
 
-      context 'with a valid LDAP user' do
-        should 'return the user attributes' do
-          attributes =  @auth.authenticate('example1','123456')
-          assert attributes.is_a?(Hash), "An hash was not returned"
-          assert_equal 'Example', attributes[:firstname]
-          assert_equal 'One', attributes[:lastname]
-          assert_equal 'example1@redmine.org', attributes[:mail]
-          assert_equal @auth.id, attributes[:auth_source_id]
-          attributes.keys.each do |attribute|
-            assert User.new.respond_to?("#{attribute}="), "Unexpected :#{attribute} attribute returned"
-          end
-        end
-      end
+    test '#authenticate with an invalid LDAP user should return nil' do
+      auth = AuthSourceLdap.find(1)
+      assert_equal nil, auth.authenticate('nouser','123456')
+    end
 
-      context 'with an invalid LDAP user' do
-        should 'return nil' do
-          assert_equal nil, @auth.authenticate('nouser','123456')
-        end
-      end
+    test '#authenticate without a login should return nil' do
+      auth = AuthSourceLdap.find(1)
+      assert_equal nil, auth.authenticate('','123456')
+    end
 
-      context 'without a login' do
-        should 'return nil' do
-          assert_equal nil, @auth.authenticate('','123456')
-        end
-      end
+    test '#authenticate without a password should return nil' do
+      auth = AuthSourceLdap.find(1)
+      assert_equal nil, auth.authenticate('edavis','')
+    end
 
-      context 'without a password' do
-        should 'return nil' do
-          assert_equal nil, @auth.authenticate('edavis','')
-        end
-      end
+    test '#authenticate without filter should return any user' do
+      auth = AuthSourceLdap.find(1)
+      assert auth.authenticate('example1','123456')
+      assert auth.authenticate('edavis', '123456')
+    end
 
-      context 'without filter' do
-        should 'return any user' do
-          assert @auth.authenticate('example1','123456')
-          assert @auth.authenticate('edavis', '123456')
-        end
-      end
+    test '#authenticate with filter should return user who matches the filter only' do
+      auth = AuthSourceLdap.find(1)
+      auth.filter = "(mail=*@redmine.org)"
 
-      context 'with filter' do
-        setup do
-          @auth.filter = "(mail=*@redmine.org)"
-        end
-
-        should 'return user who matches the filter only' do
-          assert @auth.authenticate('example1','123456')
-          assert_nil @auth.authenticate('edavis', '123456')
-        end
-      end
+      assert auth.authenticate('example1','123456')
+      assert_nil auth.authenticate('edavis', '123456')
     end
 
     def test_authenticate_should_timeout
@@ -124,6 +111,30 @@
         auth_source.authenticate 'example1', '123456'
       end
     end
+
+    def test_search_should_return_matching_entries
+      results = AuthSource.search("exa")
+      assert_equal 1, results.size
+      result = results.first
+      assert_kind_of Hash, result
+      assert_equal "example1", result[:login]
+      assert_equal "Example", result[:firstname]
+      assert_equal "One", result[:lastname]
+      assert_equal "example1@redmine.org", result[:mail]
+      assert_equal 1, result[:auth_source_id]
+    end
+
+    def test_search_with_no_match_should_return_an_empty_array
+      results = AuthSource.search("wro")
+      assert_equal [], results
+    end
+
+    def test_search_with_exception_should_return_an_empty_array
+      Net::LDAP.stubs(:new).raises(Net::LDAP::LdapError, 'Cannot connect')
+
+      results = AuthSource.search("exa")
+      assert_equal [], results
+    end
   else
     puts '(Test LDAP server not configured)'
   end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/board_test.rb
--- a/test/unit/board_test.rb
+++ b/test/unit/board_test.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/changeset_test.rb
--- a/test/unit/changeset_test.rb
+++ b/test/unit/changeset_test.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/comment_test.rb
--- a/test/unit/comment_test.rb
+++ b/test/unit/comment_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/custom_field_test.rb
--- a/test/unit/custom_field_test.rb
+++ b/test/unit/custom_field_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -209,6 +209,24 @@
     assert !f.valid_field_value?(['value1', 'abc'])
   end
 
+  def test_changing_multiple_to_false_should_delete_multiple_values
+    field = ProjectCustomField.create!(:name => 'field', :field_format => 'list', :multiple => 'true', :possible_values => ['field1', 'field2'])
+    other = ProjectCustomField.create!(:name => 'other', :field_format => 'list', :multiple => 'true', :possible_values => ['other1', 'other2'])
+
+    item_with_multiple_values = Project.generate!(:custom_field_values => {field.id => ['field1', 'field2'], other.id => ['other1', 'other2']})
+    item_with_single_values = Project.generate!(:custom_field_values => {field.id => ['field1'], other.id => ['other2']})
+
+    assert_difference 'CustomValue.count', -1 do
+      field.multiple = false
+      field.save!
+    end
+
+    item_with_multiple_values = Project.find(item_with_multiple_values.id)
+    assert_kind_of String, item_with_multiple_values.custom_field_value(field)
+    assert_kind_of Array, item_with_multiple_values.custom_field_value(other)
+    assert_equal 2, item_with_multiple_values.custom_field_value(other).size
+  end
+
   def test_value_class_should_return_the_class_used_for_fields_values
     assert_equal User, CustomField.new(:field_format => 'user').value_class
     assert_equal Version, CustomField.new(:field_format => 'version').value_class
diff -r 0a574315af3e -r 4f746d8966dd test/unit/custom_field_user_format_test.rb
--- a/test/unit/custom_field_user_format_test.rb
+++ b/test/unit/custom_field_user_format_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/custom_field_version_format_test.rb
--- a/test/unit/custom_field_version_format_test.rb
+++ b/test/unit/custom_field_version_format_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/custom_value_test.rb
--- a/test/unit/custom_value_test.rb
+++ b/test/unit/custom_value_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/default_data_test.rb
--- a/test/unit/default_data_test.rb
+++ b/test/unit/default_data_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/document_category_test.rb
--- a/test/unit/document_category_test.rb
+++ b/test/unit/document_category_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -34,14 +34,14 @@
   end
 
   def test_default
-    assert_nil DocumentCategory.find(:first, :conditions => { :is_default => true })
+    assert_nil DocumentCategory.where(:is_default => true).first
     e = Enumeration.find_by_name('Technical documentation')
     e.update_attributes(:is_default => true)
     assert_equal 3, DocumentCategory.default.id
   end
 
   def test_force_default
-    assert_nil DocumentCategory.find(:first, :conditions => { :is_default => true })
+    assert_nil DocumentCategory.where(:is_default => true).first
     assert_equal 1, DocumentCategory.default.id
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/document_test.rb
--- a/test/unit/document_test.rb
+++ b/test/unit/document_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/enabled_module_test.rb
--- a/test/unit/enabled_module_test.rb
+++ b/test/unit/enabled_module_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/enumeration_test.rb
--- a/test/unit/enumeration_test.rb
+++ b/test/unit/enumeration_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -86,7 +86,7 @@
 
   def test_destroy_with_reassign
     Enumeration.find(4).destroy(Enumeration.find(6))
-    assert_nil Issue.find(:first, :conditions => {:priority_id => 4})
+    assert_nil Issue.where(:priority_id => 4).first
     assert_equal 6, Enumeration.find(6).objects_count
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/group_test.rb
--- a/test/unit/group_test.rb
+++ b/test/unit/group_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -19,13 +19,11 @@
 
 class GroupTest < ActiveSupport::TestCase
   fixtures :projects, :trackers, :issue_statuses, :issues,
-           :enumerations, :users, :issue_categories,
+           :enumerations, :users,
            :projects_trackers,
            :roles,
            :member_roles,
            :members,
-           :enabled_modules,
-           :workflows,
            :groups_users
 
   include Redmine::I18n
@@ -37,6 +35,14 @@
     assert_equal 'New group', g.name
   end
 
+  def test_name_should_accept_255_characters
+    name = 'a' * 255
+    g = Group.new(:name => name)
+    assert g.save
+    g.reload
+    assert_equal name, g.name
+  end
+
   def test_blank_name_error_message
     set_language_if_valid 'en'
     g = Group.new
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/activities_helper_test.rb
--- /dev/null
+++ b/test/unit/helpers/activities_helper_test.rb
@@ -0,0 +1,101 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class ActivitiesHelperTest < ActionView::TestCase
+  include ActivitiesHelper
+
+  class MockEvent
+    attr_reader :event_datetime, :event_group, :name
+
+    def initialize(group=nil)
+      @@count ||= 0
+      @name = "e#{@@count}"
+      @event_datetime = Time.now + @@count.hours
+      @event_group = group || self
+      @@count += 1
+    end
+
+    def self.clear
+      @@count = 0
+    end
+  end
+
+  def setup
+    MockEvent.clear
+  end
+
+  def test_sort_activity_events_should_sort_by_datetime
+    events = []
+    events << MockEvent.new
+    events << MockEvent.new
+    events << MockEvent.new
+
+    assert_equal [
+        ['e2', false],
+        ['e1', false],
+        ['e0', false]
+      ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
+  end
+
+  def test_sort_activity_events_should_group_events
+    events = []
+    events << MockEvent.new
+    events << MockEvent.new(events[0])
+    events << MockEvent.new(events[0])
+
+    assert_equal [
+        ['e2', false],
+        ['e1', true],
+        ['e0', true]
+      ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
+  end
+
+  def test_sort_activity_events_with_group_not_in_set_should_group_events
+    e = MockEvent.new
+    events = []
+    events << MockEvent.new(e)
+    events << MockEvent.new(e)
+
+    assert_equal [
+        ['e2', false],
+        ['e1', true]
+      ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
+  end
+
+  def test_sort_activity_events_should_sort_by_datetime_and_group
+    events = []
+    events << MockEvent.new
+    events << MockEvent.new
+    events << MockEvent.new
+    events << MockEvent.new(events[1])
+    events << MockEvent.new(events[2])
+    events << MockEvent.new
+    events << MockEvent.new(events[2])
+
+    assert_equal [
+        ['e6', false],
+        ['e4', true],
+        ['e2', true],
+        ['e5', false],
+        ['e3', false],
+        ['e1', true],
+        ['e0', false]
+      ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/application_helper_test.rb
--- a/test/unit/helpers/application_helper_test.rb
+++ b/test/unit/helpers/application_helper_test.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -21,6 +21,7 @@
 
 class ApplicationHelperTest < ActionView::TestCase
   include ERB::Util
+  include Rails.application.routes.url_helpers
 
   fixtures :projects, :roles, :enabled_modules, :users,
            :repositories, :changesets,
@@ -83,7 +84,11 @@
       # escaping
       'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo&quot;bar</a>',
       # wrap in angle brackets
-      '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
+      '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;',
+      # invalid urls
+      'http://' => 'http://',
+      'www.' => 'www.',
+      'test-www.bar.com' => 'test-www.bar.com',
     }
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
   end
@@ -100,8 +105,11 @@
   end
 
   def test_auto_mailto
-    assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
-      textilizable('test@foo.bar')
+    to_test = {
+      'test@foo.bar' => '<a class="email" href="mailto:test@foo.bar">test@foo.bar</a>',
+      'test@www.foo.bar' => '<a class="email" href="mailto:test@www.foo.bar">test@www.foo.bar</a>',
+    }
+    to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
   end
 
   def test_inline_images
@@ -131,14 +139,14 @@
 
   def test_attached_images
     to_test = {
-      'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
-      'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
+      'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
+      'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
       'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
       'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
       # link image
-      '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3" title="This is a logo" alt="This is a logo" /></a>',
+      '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" /></a>',
     }
-    attachments = Attachment.find(:all)
+    attachments = Attachment.all
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
   end
 
@@ -182,13 +190,13 @@
 
     to_test = {
       'Inline image: !testtest.jpg!' =>
-        'Inline image: <img src="/attachments/download/' + a1.id.to_s + '" alt="" />',
+        'Inline image: <img src="/attachments/download/' + a1.id.to_s + '/testtest.JPG" alt="" />',
       'Inline image: !testtest.jpeg!' =>
-        'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
+        'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testtest.jpeg" alt="" />',
       'Inline image: !testtest.jpe!' =>
-        'Inline image: <img src="/attachments/download/' + a3.id.to_s + '" alt="" />',
+        'Inline image: <img src="/attachments/download/' + a3.id.to_s + '/testtest.JPE" alt="" />',
       'Inline image: !testtest.bmp!' =>
-        'Inline image: <img src="/attachments/download/' + a4.id.to_s + '" alt="" />',
+        'Inline image: <img src="/attachments/download/' + a4.id.to_s + '/Testtest.BMP" alt="" />',
     }
 
     attachments = [a1, a2, a3, a4]
@@ -211,9 +219,9 @@
 
     to_test = {
       'Inline image: !testfile.png!' =>
-        'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
+        'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
       'Inline image: !Testfile.PNG!' =>
-        'Inline image: <img src="/attachments/download/' + a2.id.to_s + '" alt="" />',
+        'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
     }
     attachments = [a1, a2]
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
@@ -252,15 +260,19 @@
 
   def test_redmine_links
     issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
-                               :class => 'issue status-1 priority-4 priority-lowest overdue', :title => 'Error 281 when updating a recipe (New)')
+                               :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
     note_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'},
-                               :class => 'issue status-1 priority-4 priority-lowest overdue', :title => 'Error 281 when updating a recipe (New)')
+                               :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
 
-    changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
-                                   :class => 'changeset', :title => 'My very first commit')
-    changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
+    revision_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
+                                   :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
+    revision_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
                                     :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
 
+    changeset_link2 = link_to('691322a8eb01e11fd7',
+                              {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
+                               :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
+
     document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
                                              :class => 'document')
 
@@ -279,11 +291,13 @@
     source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file'
     source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext'
     source_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/entry/some/file.ext'
+    source_url_with_branch = '/projects/ecookbook/repository/revisions/branch/entry/some/file'
 
     export_url = '/projects/ecookbook/repository/raw/some/file'
     export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
     export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext'
     export_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/raw/some/file.ext'
+    export_url_with_branch = '/projects/ecookbook/repository/revisions/branch/raw/some/file'
 
     to_test = {
       # tickets
@@ -294,10 +308,11 @@
       # should not ignore leading zero
       '#03'                         => '#03',
       # changesets
-      'r1'                          => changeset_link,
-      'r1.'                         => "#{changeset_link}.",
-      'r1, r2'                      => "#{changeset_link}, #{changeset_link2}",
-      'r1,r2'                       => "#{changeset_link},#{changeset_link2}",
+      'r1'                          => revision_link,
+      'r1.'                         => "#{revision_link}.",
+      'r1, r2'                      => "#{revision_link}, #{revision_link2}",
+      'r1,r2'                       => "#{revision_link},#{revision_link2}",
+      'commit:691322a8eb01e11fd7'   => changeset_link2,
       # documents
       'document#1'                  => document_link,
       'document:"Test document"'    => document_link,
@@ -314,6 +329,7 @@
       'source:/some/file.ext. '     => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
       'source:/some/file, '         => link_to('source:/some/file', source_url, :class => 'source') + ",",
       'source:/some/file@52'        => link_to('source:/some/file@52', source_url_with_rev, :class => 'source'),
+      'source:/some/file@branch'    => link_to('source:/some/file@branch', source_url_with_branch, :class => 'source'),
       'source:/some/file.ext@52'    => link_to('source:/some/file.ext@52', source_url_with_rev_and_ext, :class => 'source'),
       'source:/some/file#L110'      => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'),
       'source:/some/file.ext#L110'  => link_to('source:/some/file.ext#L110', source_url_with_ext + "#L110", :class => 'source'),
@@ -323,6 +339,7 @@
       'export:/some/file.ext'       => link_to('export:/some/file.ext', export_url_with_ext, :class => 'source download'),
       'export:/some/file@52'        => link_to('export:/some/file@52', export_url_with_rev, :class => 'source download'),
       'export:/some/file.ext@52'    => link_to('export:/some/file.ext@52', export_url_with_rev_and_ext, :class => 'source download'),
+      'export:/some/file@branch'    => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'),
       # forum
       'forum#2'                     => link_to('Discussion', board_url, :class => 'board'),
       'forum:Discussion'            => link_to('Discussion', board_url, :class => 'board'),
@@ -553,9 +570,8 @@
   end
 
   def test_attachment_links
-    attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
     to_test = {
-      'attachment:error281.txt'      => attachment_link
+      'attachment:error281.txt' => '<a href="/attachments/download/1/error281.txt" class="attachment">error281.txt</a>'
     }
     to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
   end
@@ -565,7 +581,7 @@
     a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
     a2 = Attachment.generate!(:filename => "test.txt")
 
-    assert_equal %(<p><a href="/attachments/download/#{a2.id}" class="attachment">test.txt</a></p>),
+    assert_equal %(<p><a href="/attachments/download/#{a2.id}/test.txt" class="attachment">test.txt</a></p>),
       textilizable('attachment:test.txt', :attachments => [a1, a2])
   end
 
@@ -741,7 +757,7 @@
 
     expected = <<-EXPECTED
 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
-<p><a href="/issues/1" class="issue status-1 priority-4 priority-lowest" title="Can&#x27;t print recipes (New)">#1</a></p>
+<p><a href="/issues/1" class="#{Issue.find(1).css_classes}" title="Can&#x27;t print recipes (New)">#1</a></p>
 <pre>
 [[CookBook documentation]]
 
@@ -1076,6 +1092,26 @@
     assert_equal ::I18n.t(:label_user_anonymous), t
   end
 
+  def test_link_to_attachment
+    a = Attachment.find(3)
+    assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
+      link_to_attachment(a)
+    assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
+      link_to_attachment(a, :text => 'Text')
+    assert_equal '<a href="/attachments/3/logo.gif" class="foo">logo.gif</a>',
+      link_to_attachment(a, :class => 'foo')
+    assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
+      link_to_attachment(a, :download => true)
+    assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
+      link_to_attachment(a, :only_path => false)
+  end
+
+  def test_thumbnail_tag
+    a = Attachment.find(3)
+    assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
+      thumbnail_tag(a)
+  end
+
   def test_link_to_project
     project = Project.find(1)
     assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
@@ -1088,6 +1124,17 @@
                  link_to_project(project, {:action => 'settings'}, :class => "project")
   end
 
+  def test_link_to_project_settings
+    project = Project.find(1)
+    assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
+
+    project.status = Project::STATUS_CLOSED
+    assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
+
+    project.status = Project::STATUS_ARCHIVED
+    assert_equal 'eCookbook', link_to_project_settings(project)
+  end
+
   def test_link_to_legacy_project_with_numerical_identifier_should_use_id
     # numeric identifier are no longer allowed
     Project.update_all "identifier=25", "id=1"
@@ -1163,19 +1210,4 @@
   def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
     assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
   end
-
-  def test_per_page_links_should_show_usefull_values
-    set_language_if_valid 'en'
-    stubs(:link_to).returns("[link]")
-
-    with_settings :per_page_options => '10, 25, 50, 100' do
-      assert_nil per_page_links(10, 3)
-      assert_nil per_page_links(25, 3)
-      assert_equal "Per page: 10, [link]", per_page_links(10, 22)
-      assert_equal "Per page: [link], 25", per_page_links(25, 22)
-      assert_equal "Per page: [link], [link], 50", per_page_links(50, 22)
-      assert_equal "Per page: [link], 25, [link]", per_page_links(25, 26)
-      assert_equal "Per page: [link], 25, [link], [link]", per_page_links(25, 120)
-    end
-  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/custom_fields_helper_test.rb
--- a/test/unit/helpers/custom_fields_helper_test.rb
+++ b/test/unit/helpers/custom_fields_helper_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/issues_helper_test.rb
--- a/test/unit/helpers/issues_helper_test.rb
+++ b/test/unit/helpers/issues_helper_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,7 +30,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :custom_fields,
            :attachments,
            :versions
@@ -64,164 +63,132 @@
     assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find([1, 2]))
   end
 
-  context "IssuesHelper#show_detail" do
-    context "with no_html" do
-      should 'show a changing attribute' do
-        @detail = JournalDetail.new(:property => 'attr', :old_value => '40', :value => '100', :prop_key => 'done_ratio')
-        assert_equal "% Done changed from 40 to 100", show_detail(@detail, true)
-      end
+  test 'IssuesHelper#show_detail with no_html should show a changing attribute' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => '40', :value => '100', :prop_key => 'done_ratio')
+    assert_equal "% Done changed from 40 to 100", show_detail(detail, true)
+  end
 
-      should 'show a new attribute' do
-        @detail = JournalDetail.new(:property => 'attr', :old_value => nil, :value => '100', :prop_key => 'done_ratio')
-        assert_equal "% Done set to 100", show_detail(@detail, true)
-      end
+  test 'IssuesHelper#show_detail with no_html should show a new attribute' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => nil, :value => '100', :prop_key => 'done_ratio')
+    assert_equal "% Done set to 100", show_detail(detail, true)
+  end
 
-      should 'show a deleted attribute' do
-        @detail = JournalDetail.new(:property => 'attr', :old_value => '50', :value => nil, :prop_key => 'done_ratio')
-        assert_equal "% Done deleted (50)", show_detail(@detail, true)
-      end
-    end
+  test 'IssuesHelper#show_detail with no_html should show a deleted attribute' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => '50', :value => nil, :prop_key => 'done_ratio')
+    assert_equal "% Done deleted (50)", show_detail(detail, true)
+  end
 
-    context "with html" do
-      should 'show a changing attribute with HTML highlights' do
-        @detail = JournalDetail.new(:property => 'attr', :old_value => '40', :value => '100', :prop_key => 'done_ratio')
-        html = show_detail(@detail, false)
+  test 'IssuesHelper#show_detail with html should show a changing attribute with HTML highlights' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => '40', :value => '100', :prop_key => 'done_ratio')
+    html = show_detail(detail, false)
 
-        assert_include '<strong>% Done</strong>', html
-        assert_include '<i>40</i>', html
-        assert_include '<i>100</i>', html
-      end
+    assert_include '<strong>% Done</strong>', html
+    assert_include '<i>40</i>', html
+    assert_include '<i>100</i>', html
+  end
 
-      should 'show a new attribute with HTML highlights' do
-        @detail = JournalDetail.new(:property => 'attr', :old_value => nil, :value => '100', :prop_key => 'done_ratio')
-        html = show_detail(@detail, false)
+  test 'IssuesHelper#show_detail with html should show a new attribute with HTML highlights' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => nil, :value => '100', :prop_key => 'done_ratio')
+    html = show_detail(detail, false)
 
-        assert_include '<strong>% Done</strong>', html
-        assert_include '<i>100</i>', html
-      end
+    assert_include '<strong>% Done</strong>', html
+    assert_include '<i>100</i>', html
+  end
 
-      should 'show a deleted attribute with HTML highlights' do
-        @detail = JournalDetail.new(:property => 'attr', :old_value => '50', :value => nil, :prop_key => 'done_ratio')
-        html = show_detail(@detail, false)
+  test 'IssuesHelper#show_detail with html should show a deleted attribute with HTML highlights' do
+    detail = JournalDetail.new(:property => 'attr', :old_value => '50', :value => nil, :prop_key => 'done_ratio')
+    html = show_detail(detail, false)
 
-        assert_include '<strong>% Done</strong>', html
-        assert_include '<del><i>50</i></del>', html
-      end
-    end
+    assert_include '<strong>% Done</strong>', html
+    assert_include '<del><i>50</i></del>', html
+  end
 
-    context "with a start_date attribute" do
-      should "format the current date" do
-        @detail = JournalDetail.new(
-                   :property  => 'attr',
-                   :old_value => '2010-01-01',
-                   :value     => '2010-01-31',
-                   :prop_key  => 'start_date'
-                )
-        with_settings :date_format => '%m/%d/%Y' do
-          assert_match "01/31/2010", show_detail(@detail, true)
-        end
-      end
-
-      should "format the old date" do
-        @detail = JournalDetail.new(
-                   :property  => 'attr',
-                   :old_value => '2010-01-01',
-                   :value     => '2010-01-31',
-                   :prop_key  => 'start_date'
-                )
-        with_settings :date_format => '%m/%d/%Y' do
-          assert_match "01/01/2010", show_detail(@detail, true)
-        end
-      end
-    end
-
-    context "with a due_date attribute" do
-      should "format the current date" do
-        @detail = JournalDetail.new(
-                  :property  => 'attr',
-                  :old_value => '2010-01-01',
-                  :value     => '2010-01-31',
-                  :prop_key  => 'due_date'
-                )
-        with_settings :date_format => '%m/%d/%Y' do
-          assert_match "01/31/2010", show_detail(@detail, true)
-        end
-      end
-
-      should "format the old date" do
-        @detail = JournalDetail.new(
-                  :property  => 'attr',
-                  :old_value => '2010-01-01',
-                  :value     => '2010-01-31',
-                  :prop_key  => 'due_date'
-                )
-        with_settings :date_format => '%m/%d/%Y' do
-          assert_match "01/01/2010", show_detail(@detail, true)
-        end
-      end
-    end
-
-    should "show old and new values with a project attribute" do
-      detail = JournalDetail.new(:property => 'attr', :prop_key => 'project_id', :old_value => 1, :value => 2)
-      assert_match 'eCookbook', show_detail(detail, true)
-      assert_match 'OnlineStore', show_detail(detail, true)
-    end
-
-    should "show old and new values with a issue status attribute" do
-      detail = JournalDetail.new(:property => 'attr', :prop_key => 'status_id', :old_value => 1, :value => 2)
-      assert_match 'New', show_detail(detail, true)
-      assert_match 'Assigned', show_detail(detail, true)
-    end
-
-    should "show old and new values with a tracker attribute" do
-      detail = JournalDetail.new(:property => 'attr', :prop_key => 'tracker_id', :old_value => 1, :value => 2)
-      assert_match 'Bug', show_detail(detail, true)
-      assert_match 'Feature request', show_detail(detail, true)
-    end
-
-    should "show old and new values with a assigned to attribute" do
-      detail = JournalDetail.new(:property => 'attr', :prop_key => 'assigned_to_id', :old_value => 1, :value => 2)
-      assert_match 'redMine Admin', show_detail(detail, true)
-      assert_match 'John Smith', show_detail(detail, true)
-    end
-
-    should "show old and new values with a priority attribute" do
-      detail = JournalDetail.new(:property => 'attr', :prop_key => 'priority_id', :old_value => 4, :value => 5)
-      assert_match 'Low', show_detail(detail, true)
-      assert_match 'Normal', show_detail(detail, true)
-    end
-
-    should "show old and new values with a category attribute" do
-      detail = JournalDetail.new(:property => 'attr', :prop_key => 'category_id', :old_value => 1, :value => 2)
-      assert_match 'Printing', show_detail(detail, true)
-      assert_match 'Recipes', show_detail(detail, true)
-    end
-
-    should "show old and new values with a fixed version attribute" do
-      detail = JournalDetail.new(:property => 'attr', :prop_key => 'fixed_version_id', :old_value => 1, :value => 2)
-      assert_match '0.1', show_detail(detail, true)
-      assert_match '1.0', show_detail(detail, true)
-    end
-
-    should "show old and new values with a estimated hours attribute" do
-      detail = JournalDetail.new(:property => 'attr', :prop_key => 'estimated_hours', :old_value => '5', :value => '6.3')
-      assert_match '5.00', show_detail(detail, true)
-      assert_match '6.30', show_detail(detail, true)
-    end
-
-    should "show old and new values with a custom field" do
-      detail = JournalDetail.new(:property => 'cf', :prop_key => '1', :old_value => 'MySQL', :value => 'PostgreSQL')
-      assert_equal 'Database changed from MySQL to PostgreSQL', show_detail(detail, true)
-    end
-
-    should "show added file" do
-      detail = JournalDetail.new(:property => 'attachment', :prop_key => '1', :old_value => nil, :value => 'error281.txt')
-      assert_match 'error281.txt', show_detail(detail, true)
-    end
-
-    should "show removed file" do
-      detail = JournalDetail.new(:property => 'attachment', :prop_key => '1', :old_value => 'error281.txt', :value => nil)
-      assert_match 'error281.txt', show_detail(detail, true)
+  test 'IssuesHelper#show_detail with a start_date attribute should format the dates' do
+    detail = JournalDetail.new(
+               :property  => 'attr',
+               :old_value => '2010-01-01',
+               :value     => '2010-01-31',
+               :prop_key  => 'start_date'
+            )
+    with_settings :date_format => '%m/%d/%Y' do
+      assert_match "01/31/2010", show_detail(detail, true)
+      assert_match "01/01/2010", show_detail(detail, true)
     end
   end
+
+  test 'IssuesHelper#show_detail with a due_date attribute should format the dates' do
+    detail = JournalDetail.new(
+              :property  => 'attr',
+              :old_value => '2010-01-01',
+              :value     => '2010-01-31',
+              :prop_key  => 'due_date'
+            )
+    with_settings :date_format => '%m/%d/%Y' do
+      assert_match "01/31/2010", show_detail(detail, true)
+      assert_match "01/01/2010", show_detail(detail, true)
+    end
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a project attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'project_id', :old_value => 1, :value => 2)
+    assert_match 'eCookbook', show_detail(detail, true)
+    assert_match 'OnlineStore', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a issue status attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'status_id', :old_value => 1, :value => 2)
+    assert_match 'New', show_detail(detail, true)
+    assert_match 'Assigned', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a tracker attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'tracker_id', :old_value => 1, :value => 2)
+    assert_match 'Bug', show_detail(detail, true)
+    assert_match 'Feature request', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a assigned to attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'assigned_to_id', :old_value => 1, :value => 2)
+    assert_match 'Redmine Admin', show_detail(detail, true)
+    assert_match 'John Smith', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a priority attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'priority_id', :old_value => 4, :value => 5)
+    assert_match 'Low', show_detail(detail, true)
+    assert_match 'Normal', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a category attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'category_id', :old_value => 1, :value => 2)
+    assert_match 'Printing', show_detail(detail, true)
+    assert_match 'Recipes', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a fixed version attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'fixed_version_id', :old_value => 1, :value => 2)
+    assert_match '0.1', show_detail(detail, true)
+    assert_match '1.0', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a estimated hours attribute' do
+    detail = JournalDetail.new(:property => 'attr', :prop_key => 'estimated_hours', :old_value => '5', :value => '6.3')
+    assert_match '5.00', show_detail(detail, true)
+    assert_match '6.30', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show old and new values with a custom field' do
+    detail = JournalDetail.new(:property => 'cf', :prop_key => '1', :old_value => 'MySQL', :value => 'PostgreSQL')
+    assert_equal 'Database changed from MySQL to PostgreSQL', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show added file' do
+    detail = JournalDetail.new(:property => 'attachment', :prop_key => '1', :old_value => nil, :value => 'error281.txt')
+    assert_match 'error281.txt', show_detail(detail, true)
+  end
+
+  test 'IssuesHelper#show_detail should show removed file' do
+    detail = JournalDetail.new(:property => 'attachment', :prop_key => '1', :old_value => 'error281.txt', :value => nil)
+    assert_match 'error281.txt', show_detail(detail, true)
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/projects_helper_test.rb
--- a/test/unit/helpers/projects_helper_test.rb
+++ b/test/unit/helpers/projects_helper_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -29,8 +29,7 @@
            :member_roles,
            :members,
            :groups_users,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   def setup
     super
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/queries_helper_test.rb
--- a/test/unit/helpers/queries_helper_test.rb
+++ b/test/unit/helpers/queries_helper_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -29,37 +29,41 @@
            :projects_trackers,
            :custom_fields_trackers
 
-  def test_order
-    User.current = User.find_by_login('admin')
-    query = Query.new(:project => nil, :name => '_')
-    assert_equal 30, query.available_filters.size
+  def test_filters_options_should_be_ordered
+    set_language_if_valid 'en'
+    query = IssueQuery.new
+    filter_count = query.available_filters.size
     fo = filters_options(query)
-    assert_equal 31, fo.size
+    assert_equal filter_count + 1, fo.size
     assert_equal [], fo[0]
-    assert_equal "status_id", fo[1][1]
-    assert_equal "project_id", fo[2][1]
-    assert_equal "tracker_id", fo[3][1]
-    assert_equal "priority_id", fo[4][1]
-    assert_equal "watcher_id", fo[17][1]
-    assert_equal "is_private", fo[18][1]
+
+    expected_order = [
+      "Status",
+      "Project",
+      "Tracker",
+      "Priority"
+    ]
+    assert_equal expected_order, (fo.map(&:first) & expected_order)
   end
 
-  def test_order_custom_fields
+  def test_filters_options_should_be_ordered_with_custom_fields
     set_language_if_valid 'en'
-    field = UserCustomField.new(
+    field = UserCustomField.create!(
               :name => 'order test', :field_format => 'string',
               :is_for_all => true, :is_filter => true
             )
-    assert field.save
-    User.current = User.find_by_login('admin')
-    query = Query.new(:project => nil, :name => '_')
-    assert_equal 32, query.available_filters.size
+    query = IssueQuery.new
+    filter_count = query.available_filters.size
     fo = filters_options(query)
-    assert_equal 33, fo.size
-    assert_equal "Searchable field", fo[19][0]
-    assert_equal "Database", fo[20][0]
-    assert_equal "Project's Development status", fo[21][0]
-    assert_equal "Assignee's order test", fo[22][0]
-    assert_equal "Author's order test", fo[23][0]
+    assert_equal filter_count + 1, fo.size
+
+    expected_order = [
+      "Searchable field",
+      "Database",
+      "Project's Development status",
+      "Author's order test",
+      "Assignee's order test"
+    ]
+    assert_equal expected_order, (fo.map(&:first) & expected_order)
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/search_helper_test.rb
--- a/test/unit/helpers/search_helper_test.rb
+++ b/test/unit/helpers/search_helper_test.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/sort_helper_test.rb
--- a/test/unit/helpers/sort_helper_test.rb
+++ b/test/unit/helpers/sort_helper_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,21 +30,21 @@
     sort_init 'attr1', 'desc'
     sort_update(['attr1', 'attr2'])
 
-    assert_equal 'attr1 DESC', sort_clause
+    assert_equal ['attr1 DESC'], sort_clause
   end
 
   def test_default_sort_clause_with_hash
     sort_init 'attr1', 'desc'
     sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
 
-    assert_equal 'table1.attr1 DESC', sort_clause
+    assert_equal ['table1.attr1 DESC'], sort_clause
   end
 
   def test_default_sort_clause_with_multiple_columns
     sort_init 'attr1', 'desc'
     sort_update({'attr1' => ['table1.attr1', 'table1.attr2'], 'attr2' => 'table2.attr2'})
 
-    assert_equal 'table1.attr1 DESC, table1.attr2 DESC', sort_clause
+    assert_equal ['table1.attr1 DESC', 'table1.attr2 DESC'], sort_clause
   end
 
   def test_params_sort
@@ -53,7 +53,7 @@
     sort_init 'attr1', 'desc'
     sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
 
-    assert_equal 'table1.attr1, table2.attr2 DESC', sort_clause
+    assert_equal ['table1.attr1', 'table2.attr2 DESC'], sort_clause
     assert_equal 'attr1,attr2:desc', @session['foo_bar_sort']
   end
 
@@ -63,7 +63,7 @@
     sort_init 'attr1', 'desc'
     sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
 
-    assert_equal 'table1.attr1 DESC', sort_clause
+    assert_equal ['table1.attr1 DESC'], sort_clause
     assert_equal 'attr1:desc', @session['foo_bar_sort']
   end
 
@@ -73,7 +73,7 @@
     sort_init 'attr1', 'desc'
     sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
 
-    assert_equal 'table1.attr1, table2.attr2', sort_clause
+    assert_equal ['table1.attr1', 'table2.attr2'], sort_clause
     assert_equal 'attr1,attr2', @session['foo_bar_sort']
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/timelog_helper_test.rb
--- a/test/unit/helpers/timelog_helper_test.rb
+++ b/test/unit/helpers/timelog_helper_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/helpers/watchers_helper_test.rb
--- /dev/null
+++ b/test/unit/helpers/watchers_helper_test.rb
@@ -0,0 +1,69 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../test_helper', __FILE__)
+
+class WatchersHelperTest < ActionView::TestCase
+  include WatchersHelper
+  include Redmine::I18n
+
+  fixtures :users, :issues
+
+  def setup
+    super
+    set_language_if_valid('en')
+    User.current = nil
+  end
+
+  test '#watcher_link with a non-watched object' do
+    expected = link_to(
+      "Watch",
+      "/watchers/watch?object_id=1&object_type=issue",
+      :remote => true, :method => 'post', :class => "issue-1-watcher icon icon-fav-off"
+    )
+    assert_equal expected, watcher_link(Issue.find(1), User.find(1))
+  end
+
+  test '#watcher_link with a single objet array' do
+    expected = link_to(
+      "Watch",
+      "/watchers/watch?object_id=1&object_type=issue",
+      :remote => true, :method => 'post', :class => "issue-1-watcher icon icon-fav-off"
+    )
+    assert_equal expected, watcher_link([Issue.find(1)], User.find(1))
+  end
+
+  test '#watcher_link with a multiple objets array' do
+    expected = link_to(
+      "Watch",
+      "/watchers/watch?object_id%5B%5D=1&object_id%5B%5D=3&object_type=issue",
+      :remote => true, :method => 'post', :class => "issue-bulk-watcher icon icon-fav-off"
+    )
+    assert_equal expected, watcher_link([Issue.find(1), Issue.find(3)], User.find(1))
+  end
+
+  test '#watcher_link with a watched object' do
+    Watcher.create!(:watchable => Issue.find(1), :user => User.find(1))
+
+    expected = link_to(
+      "Unwatch",
+      "/watchers/watch?object_id=1&object_type=issue",
+      :remote => true, :method => 'delete', :class => "issue-1-watcher icon icon-fav"
+    )
+    assert_equal expected, watcher_link(Issue.find(1), User.find(1))
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/initializers/patches_test.rb
--- a/test/unit/initializers/patches_test.rb
+++ b/test/unit/initializers/patches_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/issue_category_test.rb
--- a/test/unit/issue_category_test.rb
+++ b/test/unit/issue_category_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/issue_nested_set_test.rb
--- a/test/unit/issue_nested_set_test.rb
+++ b/test/unit/issue_nested_set_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,14 +18,11 @@
 require File.expand_path('../../test_helper', __FILE__)
 
 class IssueNestedSetTest < ActiveSupport::TestCase
-  fixtures :projects, :users, :members, :member_roles, :roles,
+  fixtures :projects, :users, :roles,
            :trackers, :projects_trackers,
-           :versions,
-           :issue_statuses, :issue_categories, :issue_relations, :workflows,
+           :issue_statuses, :issue_categories, :issue_relations,
            :enumerations,
-           :issues,
-           :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
-           :time_entries
+           :issues
 
   def test_create_root_issue
     issue1 = Issue.generate!
@@ -169,22 +166,6 @@
     assert_not_nil child.errors[:parent_issue_id]
   end
 
-  def test_moving_an_issue_should_keep_valid_relations_only
-    issue1 = Issue.generate!
-    issue2 = Issue.generate!
-    issue3 = Issue.generate!(:parent_issue_id => issue2.id)
-    issue4 = Issue.generate!
-    r1 = IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
-    r2 = IssueRelation.create!(:issue_from => issue1, :issue_to => issue3, :relation_type => IssueRelation::TYPE_PRECEDES)
-    r3 = IssueRelation.create!(:issue_from => issue2, :issue_to => issue4, :relation_type => IssueRelation::TYPE_PRECEDES)
-    issue2.reload
-    issue2.parent_issue_id = issue1.id
-    issue2.save!
-    assert !IssueRelation.exists?(r1.id)
-    assert !IssueRelation.exists?(r2.id)
-    assert IssueRelation.exists?(r3.id)
-  end
-
   def test_destroy_should_destroy_children
     issue1 = Issue.generate!
     issue2 = Issue.generate!
@@ -367,7 +348,7 @@
     c.reload
 
     assert_equal 5, c.issues.count
-    ic1, ic2, ic3, ic4, ic5 = c.issues.find(:all, :order => 'subject')
+    ic1, ic2, ic3, ic4, ic5 = c.issues.order('subject').all
     assert ic1.root?
     assert_equal ic1, ic2.parent
     assert_equal ic1, ic3.parent
diff -r 0a574315af3e -r 4f746d8966dd test/unit/issue_priority_test.rb
--- a/test/unit/issue_priority_test.rb
+++ b/test/unit/issue_priority_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/issue_relation_test.rb
--- a/test/unit/issue_relation_test.rb
+++ b/test/unit/issue_relation_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,6 +30,8 @@
            :enumerations,
            :trackers
 
+  include Redmine::I18n
+
   def test_create
     from = Issue.find(1)
     to = Issue.find(2)
@@ -115,6 +117,39 @@
     assert_not_nil r.errors[:base]
   end
 
+  def test_validates_circular_dependency_of_subtask
+    set_language_if_valid 'en'
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+    IssueRelation.create!(
+      :issue_from => issue1, :issue_to => issue2,
+      :relation_type => IssueRelation::TYPE_PRECEDES
+    )
+    child = Issue.generate!(:parent_issue_id => issue2.id)
+    issue1.reload
+    child.reload
+
+    r = IssueRelation.new(
+          :issue_from => child, :issue_to => issue1,
+          :relation_type => IssueRelation::TYPE_PRECEDES
+        )
+    assert !r.save
+    assert_include 'This relation would create a circular dependency', r.errors.full_messages
+  end
+
+  def test_subtasks_should_allow_precedes_relation
+    parent = Issue.generate!
+    child1 = Issue.generate!(:parent_issue_id => parent.id)
+    child2 = Issue.generate!(:parent_issue_id => parent.id)
+
+    r = IssueRelation.new(
+          :issue_from => child1, :issue_to => child2,
+          :relation_type => IssueRelation::TYPE_PRECEDES
+        )
+    assert r.valid?
+    assert r.save
+  end
+
   def test_validates_circular_dependency_on_reverse_relations
     IssueRelation.delete_all
     assert IssueRelation.create!(
diff -r 0a574315af3e -r 4f746d8966dd test/unit/issue_status_test.rb
--- a/test/unit/issue_status_test.rb
+++ b/test/unit/issue_status_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/issue_test.rb
--- a/test/unit/issue_test.rb
+++ b/test/unit/issue_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -35,6 +35,19 @@
     User.current = nil
   end
 
+  def test_initialize
+    issue = Issue.new
+
+    assert_nil issue.project_id
+    assert_nil issue.tracker_id
+    assert_nil issue.author_id
+    assert_nil issue.assigned_to_id
+    assert_nil issue.category_id
+
+    assert_equal IssueStatus.default, issue.status
+    assert_equal IssuePriority.default, issue.priority
+  end
+
   def test_create
     issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
                       :status_id => 1, :priority => IssuePriority.all.first,
@@ -79,6 +92,15 @@
     assert_include 'Due date must be greater than start date', issue.errors.full_messages
   end
 
+  def test_estimated_hours_should_be_validated
+    set_language_if_valid 'en'
+    ['-2'].each do |invalid|
+      issue = Issue.new(:estimated_hours => invalid)
+      assert !issue.valid?
+      assert_include 'Estimated time is invalid', issue.errors.full_messages
+    end
+  end
+
   def test_create_with_required_custom_field
     set_language_if_valid 'en'
     field = IssueCustomField.find_by_name('Database')
@@ -300,6 +322,16 @@
     assert_equal issues, issues.select(&:closed?)
   end
 
+  def test_fixed_version_scope_with_a_version_should_return_its_fixed_issues
+    version = Version.find(2)
+    assert version.fixed_issues.any?
+    assert_equal version.fixed_issues.to_a.sort, Issue.fixed_version(version).to_a.sort
+  end
+
+  def test_fixed_version_scope_with_empty_array_should_return_no_result
+    assert_equal 0, Issue.fixed_version([]).count
+  end
+
   def test_errors_full_messages_should_include_custom_fields_errors
     field = IssueCustomField.find_by_name('Database')
 
@@ -402,6 +434,21 @@
     assert_equal 'MySQL', issue.custom_field_value(1)
   end
 
+  def test_reload_should_reload_custom_field_values
+    issue = Issue.generate!
+    issue.custom_field_values = {'2' => 'Foo'}
+    issue.save!
+
+    issue = Issue.order('id desc').first
+    assert_equal 'Foo', issue.custom_field_value(2)
+
+    issue.custom_field_values = {'2' => 'Bar'}
+    assert_equal 'Bar', issue.custom_field_value(2)
+
+    issue.reload
+    assert_equal 'Foo', issue.custom_field_value(2)
+  end
+
   def test_should_update_issue_with_disabled_tracker
     p = Project.find(1)
     issue = Issue.find(1)
@@ -802,6 +849,49 @@
     assert_equal copy.author, child_copy.author
   end
 
+  def test_copy_as_a_child_of_copied_issue_should_not_copy_itself
+    parent = Issue.generate!
+    child1 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 1')
+    child2 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 2')
+
+    copy = parent.reload.copy
+    copy.parent_issue_id = parent.id
+    copy.author = User.find(7)
+    assert_difference 'Issue.count', 3 do
+      assert copy.save
+    end
+    parent.reload
+    copy.reload
+    assert_equal parent, copy.parent
+    assert_equal 3, parent.children.count
+    assert_equal 5, parent.descendants.count
+    assert_equal 2, copy.children.count
+    assert_equal 2, copy.descendants.count
+  end
+
+  def test_copy_as_a_descendant_of_copied_issue_should_not_copy_itself
+    parent = Issue.generate!
+    child1 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 1')
+    child2 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 2')
+
+    copy = parent.reload.copy
+    copy.parent_issue_id = child1.id
+    copy.author = User.find(7)
+    assert_difference 'Issue.count', 3 do
+      assert copy.save
+    end
+    parent.reload
+    child1.reload
+    copy.reload
+    assert_equal child1, copy.parent
+    assert_equal 2, parent.children.count
+    assert_equal 5, parent.descendants.count
+    assert_equal 1, child1.children.count
+    assert_equal 3, child1.descendants.count
+    assert_equal 2, copy.children.count
+    assert_equal 2, copy.descendants.count
+  end
+
   def test_copy_should_copy_subtasks_to_target_project
     issue = Issue.generate_with_descendants!
 
@@ -876,8 +966,8 @@
     assert issue1.reload.duplicates.include?(issue2)
 
     # Closing issue 1
-    issue1.init_journal(User.find(:first), "Closing issue1")
-    issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
+    issue1.init_journal(User.first, "Closing issue1")
+    issue1.status = IssueStatus.where(:is_closed => true).first
     assert issue1.save
     # 2 and 3 should be also closed
     assert issue2.reload.closed?
@@ -895,8 +985,8 @@
     assert !issue2.reload.duplicates.include?(issue1)
 
     # Closing issue 2
-    issue2.init_journal(User.find(:first), "Closing issue2")
-    issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
+    issue2.init_journal(User.first, "Closing issue2")
+    issue2.status = IssueStatus.where(:is_closed => true).first
     assert issue2.save
     # 1 should not be also closed
     assert !issue1.reload.closed?
@@ -1110,57 +1200,51 @@
     assert_nil copy.custom_value_for(2)
   end
 
-  context "#copy" do
-    setup do
-      @issue = Issue.find(1)
-    end
+  test "#copy should not create a journal" do
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
+    copy.save!
+    assert_equal 0, copy.reload.journals.size
+  end
 
-    should "not create a journal" do
-      copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
-      copy.save!
-      assert_equal 0, copy.reload.journals.size
-    end
+  test "#copy should allow assigned_to changes" do
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
+    assert_equal 3, copy.assigned_to_id
+  end
 
-    should "allow assigned_to changes" do
-      copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
-      assert_equal 3, copy.assigned_to_id
-    end
+  test "#copy should allow status changes" do
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :status_id => 2)
+    assert_equal 2, copy.status_id
+  end
 
-    should "allow status changes" do
-      copy = @issue.copy(:project_id => 3, :tracker_id => 2, :status_id => 2)
-      assert_equal 2, copy.status_id
-    end
+  test "#copy should allow start date changes" do
+    date = Date.today
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :start_date => date)
+    assert_equal date, copy.start_date
+  end
 
-    should "allow start date changes" do
-      date = Date.today
-      copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date)
-      assert_equal date, copy.start_date
-    end
+  test "#copy should allow due date changes" do
+    date = Date.today
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :due_date => date)
+    assert_equal date, copy.due_date
+  end
 
-    should "allow due date changes" do
-      date = Date.today
-      copy = @issue.copy(:project_id => 3, :tracker_id => 2, :due_date => date)
-      assert_equal date, copy.due_date
-    end
+  test "#copy should set current user as author" do
+    User.current = User.find(9)
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2)
+    assert_equal User.current, copy.author
+  end
 
-    should "set current user as author" do
-      User.current = User.find(9)
-      copy = @issue.copy(:project_id => 3, :tracker_id => 2)
-      assert_equal User.current, copy.author
-    end
+  test "#copy should create a journal with notes" do
+    date = Date.today
+    notes = "Notes added when copying"
+    copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :start_date => date)
+    copy.init_journal(User.current, notes)
+    copy.save!
 
-    should "create a journal with notes" do
-      date = Date.today
-      notes = "Notes added when copying"
-      copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date)
-      copy.init_journal(User.current, notes)
-      copy.save!
-
-      assert_equal 1, copy.journals.size
-      journal = copy.journals.first
-      assert_equal 0, journal.details.size
-      assert_equal notes, journal.notes
-    end
+    assert_equal 1, copy.journals.size
+    journal = copy.journals.first
+    assert_equal 0, journal.details.size
+    assert_equal notes, journal.notes
   end
 
   def test_valid_parent_project
@@ -1425,99 +1509,139 @@
     end
   end
 
+  def test_child_issue_should_consider_parent_soonest_start_on_create
+    set_language_if_valid 'en'
+    issue1 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
+    issue2 = Issue.generate!(:start_date => '2012-10-18', :due_date => '2012-10-20')
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2,
+                          :relation_type => IssueRelation::TYPE_PRECEDES)
+    issue1.reload
+    issue2.reload
+    assert_equal Date.parse('2012-10-18'), issue2.start_date
+
+    child = Issue.new(:parent_issue_id => issue2.id, :start_date => '2012-10-16',
+      :project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Child', :author_id => 1)
+    assert !child.valid?
+    assert_include 'Start date is invalid', child.errors.full_messages
+    assert_equal Date.parse('2012-10-18'), child.soonest_start
+    child.start_date = '2012-10-18'
+    assert child.save
+  end
+
+  def test_setting_parent_to_a_dependent_issue_should_not_validate
+    set_language_if_valid 'en'
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+    issue3 = Issue.generate!
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
+    IssueRelation.create!(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_PRECEDES)
+    issue3.reload
+    issue3.parent_issue_id = issue2.id
+    assert !issue3.valid?
+    assert_include 'Parent task is invalid', issue3.errors.full_messages
+  end
+
+  def test_setting_parent_should_not_allow_circular_dependency
+    set_language_if_valid 'en'
+    issue1 = Issue.generate!
+    issue2 = Issue.generate!
+    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
+    issue3 = Issue.generate!
+    issue2.reload
+    issue2.parent_issue_id = issue3.id
+    issue2.save!
+    issue4 = Issue.generate!
+    IssueRelation.create!(:issue_from => issue3, :issue_to => issue4, :relation_type => IssueRelation::TYPE_PRECEDES)
+    issue4.reload
+    issue4.parent_issue_id = issue1.id
+    assert !issue4.valid?
+    assert_include 'Parent task is invalid', issue4.errors.full_messages
+  end
+
   def test_overdue
     assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
     assert !Issue.new(:due_date => Date.today).overdue?
     assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
     assert !Issue.new(:due_date => nil).overdue?
     assert !Issue.new(:due_date => 1.day.ago.to_date,
-                      :status => IssueStatus.find(:first,
-                                                  :conditions => {:is_closed => true})
+                      :status => IssueStatus.where(:is_closed => true).first
                       ).overdue?
   end
 
-  context "#behind_schedule?" do
-    should "be false if the issue has no start_date" do
-      assert !Issue.new(:start_date => nil,
-                        :due_date => 1.day.from_now.to_date,
-                        :done_ratio => 0).behind_schedule?
-    end
+  test "#behind_schedule? should be false if the issue has no start_date" do
+    assert !Issue.new(:start_date => nil,
+                      :due_date => 1.day.from_now.to_date,
+                      :done_ratio => 0).behind_schedule?
+  end
 
-    should "be false if the issue has no end_date" do
-      assert !Issue.new(:start_date => 1.day.from_now.to_date,
-                        :due_date => nil,
-                        :done_ratio => 0).behind_schedule?
-    end
+  test "#behind_schedule? should be false if the issue has no end_date" do
+    assert !Issue.new(:start_date => 1.day.from_now.to_date,
+                      :due_date => nil,
+                      :done_ratio => 0).behind_schedule?
+  end
 
-    should "be false if the issue has more done than it's calendar time" do
-      assert !Issue.new(:start_date => 50.days.ago.to_date,
-                        :due_date => 50.days.from_now.to_date,
-                        :done_ratio => 90).behind_schedule?
-    end
+  test "#behind_schedule? should be false if the issue has more done than it's calendar time" do
+    assert !Issue.new(:start_date => 50.days.ago.to_date,
+                      :due_date => 50.days.from_now.to_date,
+                      :done_ratio => 90).behind_schedule?
+  end
 
-    should "be true if the issue hasn't been started at all" do
-      assert Issue.new(:start_date => 1.day.ago.to_date,
-                       :due_date => 1.day.from_now.to_date,
-                       :done_ratio => 0).behind_schedule?
-    end
+  test "#behind_schedule? should be true if the issue hasn't been started at all" do
+    assert Issue.new(:start_date => 1.day.ago.to_date,
+                     :due_date => 1.day.from_now.to_date,
+                     :done_ratio => 0).behind_schedule?
+  end
 
-    should "be true if the issue has used more calendar time than it's done ratio" do
-      assert Issue.new(:start_date => 100.days.ago.to_date,
-                       :due_date => Date.today,
-                       :done_ratio => 90).behind_schedule?
+  test "#behind_schedule? should be true if the issue has used more calendar time than it's done ratio" do
+    assert Issue.new(:start_date => 100.days.ago.to_date,
+                     :due_date => Date.today,
+                     :done_ratio => 90).behind_schedule?
+  end
+
+  test "#assignable_users should be Users" do
+    assert_kind_of User, Issue.find(1).assignable_users.first
+  end
+
+  test "#assignable_users should include the issue author" do
+    non_project_member = User.generate!
+    issue = Issue.generate!(:author => non_project_member)
+
+    assert issue.assignable_users.include?(non_project_member)
+  end
+
+  test "#assignable_users should include the current assignee" do
+    user = User.generate!
+    issue = Issue.generate!(:assigned_to => user)
+    user.lock!
+
+    assert Issue.find(issue.id).assignable_users.include?(user)
+  end
+
+  test "#assignable_users should not show the issue author twice" do
+    assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
+    assert_equal 2, assignable_user_ids.length
+
+    assignable_user_ids.each do |user_id|
+      assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length,
+                   "User #{user_id} appears more or less than once"
     end
   end
 
-  context "#assignable_users" do
-    should "be Users" do
-      assert_kind_of User, Issue.find(1).assignable_users.first
+  test "#assignable_users with issue_group_assignment should include groups" do
+    issue = Issue.new(:project => Project.find(2))
+
+    with_settings :issue_group_assignment => '1' do
+      assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
+      assert issue.assignable_users.include?(Group.find(11))
     end
+  end
 
-    should "include the issue author" do
-      non_project_member = User.generate!
-      issue = Issue.generate!(:author => non_project_member)
+  test "#assignable_users without issue_group_assignment should not include groups" do
+    issue = Issue.new(:project => Project.find(2))
 
-      assert issue.assignable_users.include?(non_project_member)
-    end
-
-    should "include the current assignee" do
-      user = User.generate!
-      issue = Issue.generate!(:assigned_to => user)
-      user.lock!
-
-      assert Issue.find(issue.id).assignable_users.include?(user)
-    end
-
-    should "not show the issue author twice" do
-      assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
-      assert_equal 2, assignable_user_ids.length
-
-      assignable_user_ids.each do |user_id|
-        assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length,
-                     "User #{user_id} appears more or less than once"
-      end
-    end
-
-    context "with issue_group_assignment" do
-      should "include groups" do
-        issue = Issue.new(:project => Project.find(2))
-
-        with_settings :issue_group_assignment => '1' do
-          assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
-          assert issue.assignable_users.include?(Group.find(11))
-        end
-      end
-    end
-
-    context "without issue_group_assignment" do
-      should "not include groups" do
-        issue = Issue.new(:project => Project.find(2))
-
-        with_settings :issue_group_assignment => '0' do
-          assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
-          assert !issue.assignable_users.include?(Group.find(11))
-        end
-      end
+    with_settings :issue_group_assignment => '0' do
+      assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
+      assert !issue.assignable_users.include?(Group.find(11))
     end
   end
 
@@ -1630,7 +1754,7 @@
   end
 
   def test_saving_twice_should_not_duplicate_journal_details
-    i = Issue.find(:first)
+    i = Issue.first
     i.init_journal(User.find(2), 'Some notes')
     # initial changes
     i.subject = 'New subject'
@@ -1639,7 +1763,7 @@
       assert i.save
     end
     # 1 more change
-    i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id])
+    i.priority = IssuePriority.where("id <> ?", i.priority_id).first
     assert_no_difference 'Journal.count' do
       assert_difference 'JournalDetail.count', 1 do
         i.save
@@ -1710,79 +1834,47 @@
     assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
   end
 
-  context "#done_ratio" do
-    setup do
-      @issue = Issue.find(1)
-      @issue_status = IssueStatus.find(1)
-      @issue_status.update_attribute(:default_done_ratio, 50)
-      @issue2 = Issue.find(2)
-      @issue_status2 = IssueStatus.find(2)
-      @issue_status2.update_attribute(:default_done_ratio, 0)
+  test "#done_ratio should use the issue_status according to Setting.issue_done_ratio" do
+    @issue = Issue.find(1)
+    @issue_status = IssueStatus.find(1)
+    @issue_status.update_attribute(:default_done_ratio, 50)
+    @issue2 = Issue.find(2)
+    @issue_status2 = IssueStatus.find(2)
+    @issue_status2.update_attribute(:default_done_ratio, 0)
+
+    with_settings :issue_done_ratio => 'issue_field' do
+      assert_equal 0, @issue.done_ratio
+      assert_equal 30, @issue2.done_ratio
     end
 
-    teardown do
-      Setting.issue_done_ratio = 'issue_field'
-    end
-
-    context "with Setting.issue_done_ratio using the issue_field" do
-      setup do
-        Setting.issue_done_ratio = 'issue_field'
-      end
-
-      should "read the issue's field" do
-        assert_equal 0, @issue.done_ratio
-        assert_equal 30, @issue2.done_ratio
-      end
-    end
-
-    context "with Setting.issue_done_ratio using the issue_status" do
-      setup do
-        Setting.issue_done_ratio = 'issue_status'
-      end
-
-      should "read the Issue Status's default done ratio" do
-        assert_equal 50, @issue.done_ratio
-        assert_equal 0, @issue2.done_ratio
-      end
+    with_settings :issue_done_ratio => 'issue_status' do
+      assert_equal 50, @issue.done_ratio
+      assert_equal 0, @issue2.done_ratio
     end
   end
 
-  context "#update_done_ratio_from_issue_status" do
-    setup do
-      @issue = Issue.find(1)
-      @issue_status = IssueStatus.find(1)
-      @issue_status.update_attribute(:default_done_ratio, 50)
-      @issue2 = Issue.find(2)
-      @issue_status2 = IssueStatus.find(2)
-      @issue_status2.update_attribute(:default_done_ratio, 0)
+  test "#update_done_ratio_from_issue_status should update done_ratio according to Setting.issue_done_ratio" do
+    @issue = Issue.find(1)
+    @issue_status = IssueStatus.find(1)
+    @issue_status.update_attribute(:default_done_ratio, 50)
+    @issue2 = Issue.find(2)
+    @issue_status2 = IssueStatus.find(2)
+    @issue_status2.update_attribute(:default_done_ratio, 0)
+
+    with_settings :issue_done_ratio => 'issue_field' do
+      @issue.update_done_ratio_from_issue_status
+      @issue2.update_done_ratio_from_issue_status
+
+      assert_equal 0, @issue.read_attribute(:done_ratio)
+      assert_equal 30, @issue2.read_attribute(:done_ratio)
     end
 
-    context "with Setting.issue_done_ratio using the issue_field" do
-      setup do
-        Setting.issue_done_ratio = 'issue_field'
-      end
+    with_settings :issue_done_ratio => 'issue_status' do
+      @issue.update_done_ratio_from_issue_status
+      @issue2.update_done_ratio_from_issue_status
 
-      should "not change the issue" do
-        @issue.update_done_ratio_from_issue_status
-        @issue2.update_done_ratio_from_issue_status
-
-        assert_equal 0, @issue.read_attribute(:done_ratio)
-        assert_equal 30, @issue2.read_attribute(:done_ratio)
-      end
-    end
-
-    context "with Setting.issue_done_ratio using the issue_status" do
-      setup do
-        Setting.issue_done_ratio = 'issue_status'
-      end
-
-      should "change the issue's done ratio" do
-        @issue.update_done_ratio_from_issue_status
-        @issue2.update_done_ratio_from_issue_status
-
-        assert_equal 50, @issue.read_attribute(:done_ratio)
-        assert_equal 0, @issue2.read_attribute(:done_ratio)
-      end
+      assert_equal 50, @issue.read_attribute(:done_ratio)
+      assert_equal 0, @issue2.read_attribute(:done_ratio)
     end
   end
 
@@ -1855,48 +1947,42 @@
     assert_equal before, Issue.on_active_project.length
   end
 
-  context "Issue#recipients" do
-    setup do
-      @project = Project.find(1)
-      @author = User.generate!
-      @assignee = User.generate!
-      @issue = Issue.generate!(:project => @project, :assigned_to => @assignee, :author => @author)
+  test "Issue#recipients should include project recipients" do
+    issue = Issue.generate!
+    assert issue.project.recipients.present?
+    issue.project.recipients.each do |project_recipient|
+      assert issue.recipients.include?(project_recipient)
     end
+  end
 
-    should "include project recipients" do
-      assert @project.recipients.present?
-      @project.recipients.each do |project_recipient|
-        assert @issue.recipients.include?(project_recipient)
-      end
-    end
+  test "Issue#recipients should include the author if the author is active" do
+    issue = Issue.generate!(:author => User.generate!)
+    assert issue.author, "No author set for Issue"
+    assert issue.recipients.include?(issue.author.mail)
+  end
 
-    should "include the author if the author is active" do
-      assert @issue.author, "No author set for Issue"
-      assert @issue.recipients.include?(@issue.author.mail)
-    end
+  test "Issue#recipients should include the assigned to user if the assigned to user is active" do
+    issue = Issue.generate!(:assigned_to => User.generate!)
+    assert issue.assigned_to, "No assigned_to set for Issue"
+    assert issue.recipients.include?(issue.assigned_to.mail)
+  end
 
-    should "include the assigned to user if the assigned to user is active" do
-      assert @issue.assigned_to, "No assigned_to set for Issue"
-      assert @issue.recipients.include?(@issue.assigned_to.mail)
-    end
+  test "Issue#recipients should not include users who opt out of all email" do
+    issue = Issue.generate!(:author => User.generate!)
+    issue.author.update_attribute(:mail_notification, :none)
+    assert !issue.recipients.include?(issue.author.mail)
+  end
 
-    should "not include users who opt out of all email" do
-      @author.update_attribute(:mail_notification, :none)
+  test "Issue#recipients should not include the issue author if they are only notified of assigned issues" do
+    issue = Issue.generate!(:author => User.generate!)
+    issue.author.update_attribute(:mail_notification, :only_assigned)
+    assert !issue.recipients.include?(issue.author.mail)
+  end
 
-      assert !@issue.recipients.include?(@issue.author.mail)
-    end
-
-    should "not include the issue author if they are only notified of assigned issues" do
-      @author.update_attribute(:mail_notification, :only_assigned)
-
-      assert !@issue.recipients.include?(@issue.author.mail)
-    end
-
-    should "not include the assigned user if they are only notified of owned issues" do
-      @assignee.update_attribute(:mail_notification, :only_owner)
-
-      assert !@issue.recipients.include?(@issue.assigned_to.mail)
-    end
+  test "Issue#recipients should not include the assigned user if they are only notified of owned issues" do
+    issue = Issue.generate!(:assigned_to => User.generate!)
+    issue.assigned_to.update_attribute(:mail_notification, :only_owner)
+    assert !issue.recipients.include?(issue.assigned_to.mail)
   end
 
   def test_last_journal_id_with_journals_should_return_the_journal_id
@@ -1916,6 +2002,12 @@
     assert_equal [Journal.find(1), Journal.find(2)], Issue.find(1).journals_after('')
   end
 
+  def test_css_classes_should_include_tracker
+    issue = Issue.new(:tracker => Tracker.find(2))
+    classes = issue.css_classes.split(' ')
+    assert_include 'tracker-2', classes
+  end
+
   def test_css_classes_should_include_priority
     issue = Issue.new(:priority => IssuePriority.find(8))
     classes = issue.css_classes.split(' ')
@@ -1936,4 +2028,77 @@
     assert_equal 3, issue.reload.attachments.count
     assert_equal %w(upload foo bar), issue.attachments.map(&:filename)
   end
+
+  def test_closed_on_should_be_nil_when_creating_an_open_issue
+    issue = Issue.generate!(:status_id => 1).reload
+    assert !issue.closed?
+    assert_nil issue.closed_on
+  end
+
+  def test_closed_on_should_be_set_when_creating_a_closed_issue
+    issue = Issue.generate!(:status_id => 5).reload
+    assert issue.closed?
+    assert_not_nil issue.closed_on
+    assert_equal issue.updated_on, issue.closed_on
+    assert_equal issue.created_on, issue.closed_on
+  end
+
+  def test_closed_on_should_be_nil_when_updating_an_open_issue
+    issue = Issue.find(1)
+    issue.subject = 'Not closed yet'
+    issue.save!
+    issue.reload
+    assert_nil issue.closed_on
+  end
+
+  def test_closed_on_should_be_set_when_closing_an_open_issue
+    issue = Issue.find(1)
+    issue.subject = 'Now closed'
+    issue.status_id = 5
+    issue.save!
+    issue.reload
+    assert_not_nil issue.closed_on
+    assert_equal issue.updated_on, issue.closed_on
+  end
+
+  def test_closed_on_should_not_be_updated_when_updating_a_closed_issue
+    issue = Issue.open(false).first
+    was_closed_on = issue.closed_on
+    assert_not_nil was_closed_on
+    issue.subject = 'Updating a closed issue'
+    issue.save!
+    issue.reload
+    assert_equal was_closed_on, issue.closed_on
+  end
+
+  def test_closed_on_should_be_preserved_when_reopening_a_closed_issue
+    issue = Issue.open(false).first
+    was_closed_on = issue.closed_on
+    assert_not_nil was_closed_on
+    issue.subject = 'Reopening a closed issue'
+    issue.status_id = 1
+    issue.save!
+    issue.reload
+    assert !issue.closed?
+    assert_equal was_closed_on, issue.closed_on
+  end
+
+  def test_status_was_should_return_nil_for_new_issue
+    issue = Issue.new
+    assert_nil issue.status_was
+  end
+
+  def test_status_was_should_return_status_before_change
+    issue = Issue.find(1)
+    issue.status = IssueStatus.find(2)
+    assert_equal IssueStatus.find(1), issue.status_was
+  end
+
+  def test_status_was_should_be_reset_on_save
+    issue = Issue.find(1)
+    issue.status = IssueStatus.find(2)
+    assert_equal IssueStatus.find(1), issue.status_was
+    assert issue.save!
+    assert_equal IssueStatus.find(2), issue.status_was
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/issue_transaction_test.rb
--- a/test/unit/issue_transaction_test.rb
+++ b/test/unit/issue_transaction_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/journal_observer_test.rb
--- a/test/unit/journal_observer_test.rb
+++ b/test/unit/journal_observer_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -29,8 +29,8 @@
 
   # context: issue_updated notified_events
   def test_create_should_send_email_notification_with_issue_updated
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     journal = issue.init_journal(user, issue)
 
     with_settings :notified_events => %w(issue_updated) do
@@ -40,8 +40,8 @@
   end
 
   def test_create_should_not_send_email_notification_with_notify_set_to_false
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     journal = issue.init_journal(user, issue)
     journal.notify = false
 
@@ -52,8 +52,8 @@
   end
 
   def test_create_should_not_send_email_notification_without_issue_updated
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     journal = issue.init_journal(user, issue)
 
     with_settings :notified_events => [] do
@@ -64,8 +64,8 @@
 
   # context: issue_note_added notified_events
   def test_create_should_send_email_notification_with_issue_note_added
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     journal = issue.init_journal(user, issue)
     journal.notes = 'This update has a note'
 
@@ -76,8 +76,8 @@
   end
 
   def test_create_should_not_send_email_notification_without_issue_note_added
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     journal = issue.init_journal(user, issue)
     journal.notes = 'This update has a note'
 
@@ -89,8 +89,8 @@
 
   # context: issue_status_updated notified_events
   def test_create_should_send_email_notification_with_issue_status_updated
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     issue.init_journal(user, issue)
     issue.status = IssueStatus.last
 
@@ -101,8 +101,8 @@
   end
 
   def test_create_should_not_send_email_notification_without_issue_status_updated
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     issue.init_journal(user, issue)
     issue.status = IssueStatus.last
 
@@ -114,8 +114,8 @@
 
   # context: issue_priority_updated notified_events
   def test_create_should_send_email_notification_with_issue_priority_updated
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     issue.init_journal(user, issue)
     issue.priority = IssuePriority.last
 
@@ -126,8 +126,8 @@
   end
 
   def test_create_should_not_send_email_notification_without_issue_priority_updated
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     issue.init_journal(user, issue)
     issue.priority = IssuePriority.last
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/journal_test.rb
--- a/test/unit/journal_test.rb
+++ b/test/unit/journal_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -41,8 +41,8 @@
 
   def test_create_should_send_email_notification
     ActionMailer::Base.deliveries.clear
-    issue = Issue.find(:first)
-    user = User.find(:first)
+    issue = Issue.first
+    user = User.first
     journal = issue.init_journal(user, issue)
 
     assert journal.save
@@ -154,4 +154,25 @@
     # Admin should see issues on private projects that he does not belong to
     assert journals.detect {|journal| !journal.issue.project.is_public?}
   end
+
+  def test_details_should_normalize_dates
+    j = JournalDetail.create!(:old_value => Date.parse('2012-11-03'), :value => Date.parse('2013-01-02'))
+    j.reload
+    assert_equal '2012-11-03', j.old_value
+    assert_equal '2013-01-02', j.value
+  end
+
+  def test_details_should_normalize_true_values
+    j = JournalDetail.create!(:old_value => true, :value => true)
+    j.reload
+    assert_equal '1', j.old_value
+    assert_equal '1', j.value
+  end
+
+  def test_details_should_normalize_false_values
+    j = JournalDetail.create!(:old_value => false, :value => false)
+    j.reload
+    assert_equal '0', j.old_value
+    assert_equal '0', j.value
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/access_control_test.rb
--- a/test/unit/lib/redmine/access_control_test.rb
+++ b/test/unit/lib/redmine/access_control_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/ciphering_test.rb
--- a/test/unit/lib/redmine/ciphering_test.rb
+++ b/test/unit/lib/redmine/ciphering_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/codeset_util_test.rb
--- a/test/unit/lib/redmine/codeset_util_test.rb
+++ b/test/unit/lib/redmine/codeset_util_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/configuration_test.rb
--- a/test/unit/lib/redmine/configuration_test.rb
+++ b/test/unit/lib/redmine/configuration_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/export/pdf_test.rb
--- a/test/unit/lib/redmine/export/pdf_test.rb
+++ b/test/unit/lib/redmine/export/pdf_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -16,7 +16,6 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 require File.expand_path('../../../../../test_helper', __FILE__)
-require 'iconv'
 
 class PdfTest < ActiveSupport::TestCase
   fixtures :users, :projects, :roles, :members, :member_roles,
@@ -36,9 +35,9 @@
       txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding)
       txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding)
       txt_3 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding)
-      assert_equal "?\x91\xd4", txt_1
-      assert_equal "?\x91\xd4?", txt_2
-      assert_equal "??\x91\xd4?", txt_3
+      assert_equal "?\x91\xd4".force_encoding("ASCII-8BIT"), txt_1
+      assert_equal "?\x91\xd4?".force_encoding("ASCII-8BIT"), txt_2
+      assert_equal "??\x91\xd4?".force_encoding("ASCII-8BIT"), txt_3
       assert_equal "ASCII-8BIT", txt_1.encoding.to_s
       assert_equal "ASCII-8BIT", txt_2.encoding.to_s
       assert_equal "ASCII-8BIT", txt_3.encoding.to_s
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/helpers/calendar_test.rb
--- a/test/unit/lib/redmine/helpers/calendar_test.rb
+++ b/test/unit/lib/redmine/helpers/calendar_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/helpers/gantt_test.rb
--- a/test/unit/lib/redmine/helpers/gantt_test.rb
+++ b/test/unit/lib/redmine/helpers/gantt_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -26,7 +26,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :versions,
            :groups_users
 
@@ -34,6 +33,7 @@
   include ProjectsHelper
   include IssuesHelper
   include ERB::Util
+  include Rails.application.routes.url_helpers
 
   def setup
     setup_with_controller
@@ -49,7 +49,7 @@
     @project = project
     @gantt = Redmine::Helpers::Gantt.new(options)
     @gantt.project = @project
-    @gantt.query = Query.create!(:project => @project, :name => 'Gantt')
+    @gantt.query = IssueQuery.create!(:project => @project, :name => 'Gantt')
     @gantt.view = self
     @gantt.instance_variable_set('@date_from', options[:date_from] || (today - 14))
     @gantt.instance_variable_set('@date_to', options[:date_to] || (today + 14))
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/hook_test.rb
--- a/test/unit/lib/redmine/hook_test.rb
+++ b/test/unit/lib/redmine/hook_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -23,7 +23,7 @@
            :trackers, :projects_trackers,
            :enabled_modules,
            :versions,
-           :issue_statuses, :issue_categories, :issue_relations, :workflows,
+           :issue_statuses, :issue_categories, :issue_relations,
            :enumerations,
            :issues
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/i18n_test.rb
--- a/test/unit/lib/redmine/i18n_test.rb
+++ b/test/unit/lib/redmine/i18n_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/info_test.rb
--- a/test/unit/lib/redmine/info_test.rb
+++ b/test/unit/lib/redmine/info_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/menu_manager/mapper_test.rb
--- a/test/unit/lib/redmine/menu_manager/mapper_test.rb
+++ b/test/unit/lib/redmine/menu_manager/mapper_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/menu_manager/menu_helper_test.rb
--- a/test/unit/lib/redmine/menu_manager/menu_helper_test.rb
+++ b/test/unit/lib/redmine/menu_manager/menu_helper_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/menu_manager_test.rb
--- a/test/unit/lib/redmine/menu_manager_test.rb
+++ b/test/unit/lib/redmine/menu_manager_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -18,11 +18,17 @@
 require File.expand_path('../../../../test_helper', __FILE__)
 
 class Redmine::MenuManagerTest < ActiveSupport::TestCase
-  context "MenuManager#map" do
-    should "be tested"
+  def test_map_should_yield_a_mapper
+    assert_difference 'Redmine::MenuManager.items(:project_menu).size' do
+      Redmine::MenuManager.map :project_menu do |mapper|
+        assert_kind_of  Redmine::MenuManager::Mapper, mapper
+        mapper.push :new_item, '/'
+      end
+    end
   end
 
-  context "MenuManager#items" do
-    should "be tested"
+  def test_items_should_return_menu_items
+    items = Redmine::MenuManager.items(:project_menu)
+    assert_kind_of Redmine::MenuManager::MenuNode, items.first
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/mime_type_test.rb
--- a/test/unit/lib/redmine/mime_type_test.rb
+++ b/test/unit/lib/redmine/mime_type_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/notifiable_test.rb
--- a/test/unit/lib/redmine/notifiable_test.rb
+++ b/test/unit/lib/redmine/notifiable_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/pagination_helper_test.rb
--- /dev/null
+++ b/test/unit/lib/redmine/pagination_helper_test.rb
@@ -0,0 +1,34 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class ApplicationHelperTest < ActionView::TestCase
+  include Redmine::Pagination::Helper
+
+  def test_per_page_options_should_return_usefull_values
+    with_settings :per_page_options => '10, 25, 50, 100' do
+      assert_equal [], per_page_options(10, 3)
+      assert_equal [], per_page_options(25, 3)
+      assert_equal [10, 25], per_page_options(10, 22)
+      assert_equal [10, 25], per_page_options(25, 22)
+      assert_equal [10, 25, 50], per_page_options(50, 22)
+      assert_equal [10, 25, 50], per_page_options(25, 26)
+      assert_equal [10, 25, 50, 100], per_page_options(25, 120)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/pagination_test.rb
--- /dev/null
+++ b/test/unit/lib/redmine/pagination_test.rb
@@ -0,0 +1,94 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../../../test_helper', __FILE__)
+
+class Redmine::PaginationTest < ActiveSupport::TestCase
+
+  def setup
+    @klass = Redmine::Pagination::Paginator
+  end
+
+  def test_count_is_zero
+    p = @klass.new 0, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    %w(first_page previous_page next_page last_page).each do |method|
+      assert_nil p.send(method), "#{method} was not nil"
+    end
+    assert_equal 0, p.first_item
+    assert_equal 0, p.last_item
+    assert_equal [], p.linked_pages
+  end
+
+  def test_count_is_less_than_per_page
+    p = @klass.new 7, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    assert_equal 1, p.first_page
+    assert_nil p.previous_page
+    assert_nil p.next_page
+    assert_equal 1, p.last_page
+    assert_equal 1, p.first_item
+    assert_equal 7, p.last_item
+    assert_equal [], p.linked_pages
+  end
+
+  def test_count_is_equal_to_per_page
+    p = @klass.new 10, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    assert_equal 1, p.first_page
+    assert_nil p.previous_page
+    assert_nil p.next_page
+    assert_equal 1, p.last_page
+    assert_equal 1, p.first_item
+    assert_equal 10, p.last_item
+    assert_equal [], p.linked_pages
+  end
+
+  def test_2_pages
+    p = @klass.new 16, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    assert_equal 1, p.first_page
+    assert_nil p.previous_page
+    assert_equal 2, p.next_page
+    assert_equal 2, p.last_page
+    assert_equal 1, p.first_item
+    assert_equal 10, p.last_item
+    assert_equal [1, 2], p.linked_pages
+  end
+
+  def test_many_pages
+    p = @klass.new 155, 10, 1
+
+    assert_equal 0, p.offset
+    assert_equal 10, p.per_page
+    assert_equal 1, p.first_page
+    assert_nil p.previous_page
+    assert_equal 2, p.next_page
+    assert_equal 16, p.last_page
+    assert_equal 1, p.first_item
+    assert_equal 10, p.last_item
+    assert_equal [1, 2, 3, 16], p.linked_pages
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/plugin_test.rb
--- a/test/unit/lib/redmine/plugin_test.rb
+++ b/test/unit/lib/redmine/plugin_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/safe_attributes_test.rb
--- a/test/unit/lib/redmine/safe_attributes_test.rb
+++ b/test/unit/lib/redmine/safe_attributes_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/scm/adapters/bazaar_adapter_test.rb
--- a/test/unit/lib/redmine/scm/adapters/bazaar_adapter_test.rb
+++ b/test/unit/lib/redmine/scm/adapters/bazaar_adapter_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/scm/adapters/cvs_adapter_test.rb
--- a/test/unit/lib/redmine/scm/adapters/cvs_adapter_test.rb
+++ b/test/unit/lib/redmine/scm/adapters/cvs_adapter_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb
--- a/test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb
+++ b/test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/scm/adapters/filesystem_adapter_test.rb
--- a/test/unit/lib/redmine/scm/adapters/filesystem_adapter_test.rb
+++ b/test/unit/lib/redmine/scm/adapters/filesystem_adapter_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/scm/adapters/git_adapter_test.rb
--- a/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb
+++ b/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/scm/adapters/mercurial_adapter_test.rb
--- a/test/unit/lib/redmine/scm/adapters/mercurial_adapter_test.rb
+++ b/test/unit/lib/redmine/scm/adapters/mercurial_adapter_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/scm/adapters/subversion_adapter_test.rb
--- a/test/unit/lib/redmine/scm/adapters/subversion_adapter_test.rb
+++ b/test/unit/lib/redmine/scm/adapters/subversion_adapter_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/themes_test.rb
--- a/test/unit/lib/redmine/themes_test.rb
+++ b/test/unit/lib/redmine/themes_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/unified_diff_test.rb
--- a/test/unit/lib/redmine/unified_diff_test.rb
+++ b/test/unit/lib/redmine/unified_diff_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -221,6 +221,93 @@
     assert_equal "test02.txt", diff[0].file_name
   end
 
+  def test_utf8_ja
+    ja = "  text_tip_issue_end_day: "
+    ja += "\xe3\x81\x93\xe3\x81\xae\xe6\x97\xa5\xe3\x81\xab\xe7\xb5\x82\xe4\xba\x86\xe3\x81\x99\xe3\x82\x8b<span>\xe3\x82\xbf\xe3\x82\xb9\xe3\x82\xaf</span>"
+    ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
+    with_settings :repositories_encodings => '' do
+      diff = Redmine::UnifiedDiff.new(read_diff_fixture('issue-12641-ja.diff'), :type => 'inline')
+      assert_equal 1, diff.size
+      assert_equal 12, diff.first.size
+      assert_equal ja, diff.first[4].html_line_left
+    end
+  end
+
+  def test_utf8_ru
+    ru = "        other: &quot;\xd0\xbe\xd0\xba\xd0\xbe\xd0\xbb\xd0\xbe %{count} \xd1\x87\xd0\xb0\xd1\x81<span>\xd0\xb0</span>&quot;"
+    ru.force_encoding('UTF-8') if ru.respond_to?(:force_encoding)
+    with_settings :repositories_encodings => '' do
+      diff = Redmine::UnifiedDiff.new(read_diff_fixture('issue-12641-ru.diff'), :type => 'inline')
+      assert_equal 1, diff.size
+      assert_equal 8, diff.first.size
+      assert_equal ru, diff.first[3].html_line_left
+    end
+  end
+
+  def test_offset_range_ascii_1
+    raw = <<-DIFF
+--- a.txt	2013-04-05 14:19:39.000000000 +0900
++++ b.txt	2013-04-05 14:19:51.000000000 +0900
+@@ -1,3 +1,3 @@
+ aaaa
+-abc
++abcd
+ bbbb
+DIFF
+    diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs')
+    assert_equal 1, diff.size
+    assert_equal 3, diff.first.size
+    assert_equal "abc<span></span>", diff.first[1].html_line_left
+    assert_equal "abc<span>d</span>", diff.first[1].html_line_right
+  end
+
+  def test_offset_range_ascii_2
+    raw = <<-DIFF
+--- a.txt	2013-04-05 14:19:39.000000000 +0900
++++ b.txt	2013-04-05 14:19:51.000000000 +0900
+@@ -1,3 +1,3 @@
+ aaaa
+-abc
++zabc
+ bbbb
+DIFF
+    diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs')
+    assert_equal 1, diff.size
+    assert_equal 3, diff.first.size
+    assert_equal "<span></span>abc", diff.first[1].html_line_left
+    assert_equal "<span>z</span>abc", diff.first[1].html_line_right
+  end
+
+  def test_offset_range_japanese_1
+    ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span></span>"
+    ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding)
+    ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x9e</span>"
+    ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding)
+    with_settings :repositories_encodings => '' do
+      diff = Redmine::UnifiedDiff.new(
+               read_diff_fixture('issue-13644-1.diff'), :type => 'sbs')
+      assert_equal 1, diff.size
+      assert_equal 3, diff.first.size
+      assert_equal ja1, diff.first[1].html_line_left
+      assert_equal ja2, diff.first[1].html_line_right
+    end
+  end
+
+  def test_offset_range_japanese_2
+    ja1 = "<span></span>\xe6\x97\xa5\xe6\x9c\xac"
+    ja1.force_encoding('UTF-8') if ja1.respond_to?(:force_encoding)
+    ja2 = "<span>\xe3\x81\xab\xe3\x81\xa3\xe3\x81\xbd\xe3\x82\x93</span>\xe6\x97\xa5\xe6\x9c\xac"
+    ja2.force_encoding('UTF-8') if ja2.respond_to?(:force_encoding)
+    with_settings :repositories_encodings => '' do
+      diff = Redmine::UnifiedDiff.new(
+               read_diff_fixture('issue-13644-2.diff'), :type => 'sbs')
+      assert_equal 1, diff.size
+      assert_equal 3, diff.first.size
+      assert_equal ja1, diff.first[1].html_line_left
+      assert_equal ja2, diff.first[1].html_line_right
+    end
+  end
+
   private
 
   def read_diff_fixture(filename)
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/utils/date_calculation.rb
--- a/test/unit/lib/redmine/utils/date_calculation.rb
+++ b/test/unit/lib/redmine/utils/date_calculation.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/views/builders/json_test.rb
--- a/test/unit/lib/redmine/views/builders/json_test.rb
+++ b/test/unit/lib/redmine/views/builders/json_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/views/builders/xml_test.rb
--- a/test/unit/lib/redmine/views/builders/xml_test.rb
+++ b/test/unit/lib/redmine/views/builders/xml_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/wiki_formatting/macros_test.rb
--- a/test/unit/lib/redmine/wiki_formatting/macros_test.rb
+++ b/test/unit/lib/redmine/wiki_formatting/macros_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb
--- a/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb
+++ b/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine/wiki_formatting_test.rb
--- a/test/unit/lib/redmine/wiki_formatting_test.rb
+++ b/test/unit/lib/redmine/wiki_formatting_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/lib/redmine_test.rb
--- a/test/unit/lib/redmine_test.rb
+++ b/test/unit/lib/redmine_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/mail_handler_test.rb
--- a/test/unit/mail_handler_test.rb
+++ b/test/unit/mail_handler_test.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -304,6 +304,51 @@
     end
   end
 
+  def test_created_user_should_be_added_to_groups
+    group1 = Group.generate!
+    group2 = Group.generate!
+
+    assert_difference 'User.count' do
+      submit_email(
+        'ticket_by_unknown_user.eml',
+        :issue => {:project => 'ecookbook'},
+        :unknown_user => 'create',
+        :default_group => "#{group1.name},#{group2.name}"
+      )
+    end
+    user = User.order('id DESC').first
+    assert_same_elements [group1, group2], user.groups
+  end
+
+  def test_created_user_should_not_receive_account_information_with_no_account_info_option
+    assert_difference 'User.count' do
+      submit_email(
+        'ticket_by_unknown_user.eml',
+        :issue => {:project => 'ecookbook'},
+        :unknown_user => 'create',
+        :no_account_notice => '1'
+      )
+    end
+
+    # only 1 email for the new issue notification
+    assert_equal 1, ActionMailer::Base.deliveries.size
+    email = ActionMailer::Base.deliveries.first
+    assert_include 'Ticket by unknown user', email.subject
+  end
+
+  def test_created_user_should_have_mail_notification_to_none_with_no_notification_option
+    assert_difference 'User.count' do
+      submit_email(
+        'ticket_by_unknown_user.eml',
+        :issue => {:project => 'ecookbook'},
+        :unknown_user => 'create',
+        :no_notification => '1'
+      )
+    end
+    user = User.order('id DESC').first
+    assert_equal 'none', user.mail_notification
+  end
+
   def test_add_issue_without_from_header
     Role.anonymous.add_permission!(:add_issues)
     assert_equal false, submit_email('ticket_without_from_header.eml')
@@ -646,73 +691,55 @@
     assert_equal 'This is a html-only email.', issue.description
   end
 
-  context "truncate emails based on the Setting" do
-    context "with no setting" do
-      setup do
-        Setting.mail_handler_body_delimiters = ''
-      end
+  test "truncate emails with no setting should add the entire email into the issue" do
+    with_settings :mail_handler_body_delimiters => '' do
+      issue = submit_email('ticket_on_given_project.eml')
+      assert_issue_created(issue)
+      assert issue.description.include?('---')
+      assert issue.description.include?('This paragraph is after the delimiter')
+    end
+  end
 
-      should "add the entire email into the issue" do
-        issue = submit_email('ticket_on_given_project.eml')
-        assert_issue_created(issue)
-        assert issue.description.include?('---')
-        assert issue.description.include?('This paragraph is after the delimiter')
-      end
+  test "truncate emails with a single string should truncate the email at the delimiter for the issue" do
+    with_settings :mail_handler_body_delimiters => '---' do
+      issue = submit_email('ticket_on_given_project.eml')
+      assert_issue_created(issue)
+      assert issue.description.include?('This paragraph is before delimiters')
+      assert issue.description.include?('--- This line starts with a delimiter')
+      assert !issue.description.match(/^---$/)
+      assert !issue.description.include?('This paragraph is after the delimiter')
     end
+  end
 
-    context "with a single string" do
-      setup do
-        Setting.mail_handler_body_delimiters = '---'
-      end
-      should "truncate the email at the delimiter for the issue" do
-        issue = submit_email('ticket_on_given_project.eml')
-        assert_issue_created(issue)
-        assert issue.description.include?('This paragraph is before delimiters')
-        assert issue.description.include?('--- This line starts with a delimiter')
-        assert !issue.description.match(/^---$/)
-        assert !issue.description.include?('This paragraph is after the delimiter')
-      end
+  test "truncate emails with a single quoted reply should truncate the email at the delimiter with the quoted reply symbols (>)" do
+    with_settings :mail_handler_body_delimiters => '--- Reply above. Do not remove this line. ---' do
+      journal = submit_email('issue_update_with_quoted_reply_above.eml')
+      assert journal.is_a?(Journal)
+      assert journal.notes.include?('An update to the issue by the sender.')
+      assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
+      assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
     end
+  end
 
-    context "with a single quoted reply (e.g. reply to a Redmine email notification)" do
-      setup do
-        Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
-      end
-      should "truncate the email at the delimiter with the quoted reply symbols (>)" do
-        journal = submit_email('issue_update_with_quoted_reply_above.eml')
-        assert journal.is_a?(Journal)
-        assert journal.notes.include?('An update to the issue by the sender.')
-        assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
-        assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
-      end
+  test "truncate emails with multiple quoted replies should truncate the email at the delimiter with the quoted reply symbols (>)" do
+    with_settings :mail_handler_body_delimiters => '--- Reply above. Do not remove this line. ---' do
+      journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml')
+      assert journal.is_a?(Journal)
+      assert journal.notes.include?('An update to the issue by the sender.')
+      assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
+      assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
     end
+  end
 
-    context "with multiple quoted replies (e.g. reply to a reply of a Redmine email notification)" do
-      setup do
-        Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
-      end
-      should "truncate the email at the delimiter with the quoted reply symbols (>)" do
-        journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml')
-        assert journal.is_a?(Journal)
-        assert journal.notes.include?('An update to the issue by the sender.')
-        assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
-        assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
-      end
-    end
-
-    context "with multiple strings" do
-      setup do
-        Setting.mail_handler_body_delimiters = "---\nBREAK"
-      end
-      should "truncate the email at the first delimiter found (BREAK)" do
-        issue = submit_email('ticket_on_given_project.eml')
-        assert_issue_created(issue)
-        assert issue.description.include?('This paragraph is before delimiters')
-        assert !issue.description.include?('BREAK')
-        assert !issue.description.include?('This paragraph is between delimiters')
-        assert !issue.description.match(/^---$/)
-        assert !issue.description.include?('This paragraph is after the delimiter')
-      end
+  test "truncate emails with multiple strings should truncate the email at the first delimiter found (BREAK)" do
+    with_settings :mail_handler_body_delimiters => "---\nBREAK" do
+      issue = submit_email('ticket_on_given_project.eml')
+      assert_issue_created(issue)
+      assert issue.description.include?('This paragraph is before delimiters')
+      assert !issue.description.include?('BREAK')
+      assert !issue.description.include?('This paragraph is between delimiters')
+      assert !issue.description.match(/^---$/)
+      assert !issue.description.include?('This paragraph is after the delimiter')
     end
   end
 
@@ -741,6 +768,7 @@
       assert_equal expected[0], user.login
       assert_equal expected[1], user.firstname
       assert_equal expected[2], user.lastname
+      assert_equal 'only_my_events', user.mail_notification
     end
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/mailer_test.rb
--- a/test/unit/mailer_test.rb
+++ b/test/unit/mailer_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -210,7 +210,7 @@
   end
 
   def test_should_not_send_email_without_recipient
-    news = News.find(:first)
+    news = News.first
     user = news.author
     # Remove members except news author
     news.project.memberships.each {|m| m.destroy unless m.user == user}
@@ -279,44 +279,40 @@
     end
   end
 
-  context("#issue_add") do
-    setup do
-      ActionMailer::Base.deliveries.clear
-      Setting.bcc_recipients = '1'
-      @issue = Issue.find(1)
-    end
+  test "#issue_add should notify project members" do
+    issue = Issue.find(1)
+    assert Mailer.issue_add(issue).deliver
+    assert last_email.bcc.include?('dlopper@somenet.foo')
+  end
 
-    should "notify project members" do
-      assert Mailer.issue_add(@issue).deliver
-      assert last_email.bcc.include?('dlopper@somenet.foo')
-    end
+  test "#issue_add should not notify project members that are not allow to view the issue" do
+    issue = Issue.find(1)
+    Role.find(2).remove_permission!(:view_issues)
+    assert Mailer.issue_add(issue).deliver
+    assert !last_email.bcc.include?('dlopper@somenet.foo')
+  end
 
-    should "not notify project members that are not allow to view the issue" do
-      Role.find(2).remove_permission!(:view_issues)
-      assert Mailer.issue_add(@issue).deliver
-      assert !last_email.bcc.include?('dlopper@somenet.foo')
-    end
+  test "#issue_add should notify issue watchers" do
+    issue = Issue.find(1)
+    user = User.find(9)
+    # minimal email notification options
+    user.pref[:no_self_notified] = '1'
+    user.pref.save
+    user.mail_notification = false
+    user.save
 
-    should "notify issue watchers" do
-      user = User.find(9)
-      # minimal email notification options
-      user.pref[:no_self_notified] = '1'
-      user.pref.save
-      user.mail_notification = false
-      user.save
+    Watcher.create!(:watchable => issue, :user => user)
+    assert Mailer.issue_add(issue).deliver
+    assert last_email.bcc.include?(user.mail)
+  end
 
-      Watcher.create!(:watchable => @issue, :user => user)
-      assert Mailer.issue_add(@issue).deliver
-      assert last_email.bcc.include?(user.mail)
-    end
-
-    should "not notify watchers not allowed to view the issue" do
-      user = User.find(9)
-      Watcher.create!(:watchable => @issue, :user => user)
-      Role.non_member.remove_permission!(:view_issues)
-      assert Mailer.issue_add(@issue).deliver
-      assert !last_email.bcc.include?(user.mail)
-    end
+  test "#issue_add should not notify watchers not allowed to view the issue" do
+    issue = Issue.find(1)
+    user = User.find(9)
+    Watcher.create!(:watchable => issue, :user => user)
+    Role.non_member.remove_permission!(:view_issues)
+    assert Mailer.issue_add(issue).deliver
+    assert !last_email.bcc.include?(user.mail)
   end
 
   # test mailer methods for each language
@@ -402,7 +398,7 @@
   end
 
   def test_news_added
-    news = News.find(:first)
+    news = News.first
     valid_languages.each do |lang|
       Setting.default_language = lang.to_s
       assert Mailer.news_added(news).deliver
@@ -418,7 +414,7 @@
   end
 
   def test_message_posted
-    message = Message.find(:first)
+    message = Message.first
     recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
     recipients = recipients.compact.uniq
     valid_languages.each do |lang|
diff -r 0a574315af3e -r 4f746d8966dd test/unit/member_test.rb
--- a/test/unit/member_test.rb
+++ b/test/unit/member_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,7 +25,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :groups_users,
            :watchers,
            :journals, :journal_details,
@@ -122,70 +121,4 @@
     assert_equal -1, a <=> b
     assert_equal 1,  b <=> a
   end
-
-  context "removing permissions" do
-    setup do
-      Watcher.delete_all("user_id = 9")
-      user = User.find(9)
-      # public
-      Watcher.create!(:watchable => Issue.find(1), :user => user)
-      # private
-      Watcher.create!(:watchable => Issue.find(4), :user => user)
-      Watcher.create!(:watchable => Message.find(7), :user => user)
-      Watcher.create!(:watchable => Wiki.find(2), :user => user)
-      Watcher.create!(:watchable => WikiPage.find(3), :user => user)
-    end
-
-    context "of user" do
-      setup do
-        @member = Member.create!(:project => Project.find(2), :principal => User.find(9), :role_ids => [1, 2])
-      end
-
-      context "by deleting membership" do
-        should "prune watchers" do
-          assert_difference 'Watcher.count', -4 do
-            @member.destroy
-          end
-        end
-      end
-
-      context "by updating roles" do
-        should "prune watchers" do
-          Role.find(2).remove_permission! :view_wiki_pages
-          member = Member.first(:order => 'id desc')
-          assert_difference 'Watcher.count', -2 do
-            member.role_ids = [2]
-            member.save
-          end
-          assert !Message.find(7).watched_by?(@user)
-        end
-      end
-    end
-
-    context "of group" do
-      setup do
-        group = Group.find(10)
-        @member = Member.create!(:project => Project.find(2), :principal => group, :role_ids => [1, 2])
-        group.users << User.find(9)
-      end
-
-      context "by deleting membership" do
-        should "prune watchers" do
-          assert_difference 'Watcher.count', -4 do
-            @member.destroy
-          end
-        end
-      end
-
-      context "by updating roles" do
-        should "prune watchers" do
-          Role.find(2).remove_permission! :view_wiki_pages
-          assert_difference 'Watcher.count', -2 do
-            @member.role_ids = [2]
-            @member.save
-          end
-        end
-      end
-    end
-  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/message_test.rb
--- a/test/unit/message_test.rb
+++ b/test/unit/message_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -36,9 +36,9 @@
     assert message.save
     @board.reload
     # topics count incremented
-    assert_equal topics_count+1, @board[:topics_count]
+    assert_equal topics_count + 1, @board[:topics_count]
     # messages count incremented
-    assert_equal messages_count+1, @board[:messages_count]
+    assert_equal messages_count + 1, @board[:messages_count]
     assert_equal message, @board.last_message
     # author should be watching the message
     assert message.watched_by?(@user)
@@ -47,13 +47,13 @@
   def test_reply
     topics_count = @board.topics_count
     messages_count = @board.messages_count
-    @message = Message.find(1)
-    replies_count = @message.replies_count
+    message = Message.find(1)
+    replies_count = message.replies_count
 
     reply_author = User.find(2)
     reply = Message.new(:board => @board, :subject => 'Test reply',
                         :content => 'Test reply content',
-                        :parent => @message, :author => reply_author)
+                        :parent => message, :author => reply_author)
     assert reply.save
     @board.reload
     # same topics count
@@ -61,42 +61,42 @@
     # messages count incremented
     assert_equal messages_count+1, @board[:messages_count]
     assert_equal reply, @board.last_message
-    @message.reload
+    message.reload
     # replies count incremented
-    assert_equal replies_count+1, @message[:replies_count]
-    assert_equal reply, @message.last_reply
+    assert_equal replies_count+1, message[:replies_count]
+    assert_equal reply, message.last_reply
     # author should be watching the message
-    assert @message.watched_by?(reply_author)
+    assert message.watched_by?(reply_author)
   end
 
   def test_cannot_reply_to_locked_topic
     topics_count = @board.topics_count
     messages_count = @board.messages_count
-    @message = Message.find(1)
-    replies_count = @message.replies_count
-    assert_equal false, @message.locked
-    @message.locked = true
-    assert @message.save
-    assert_equal true, @message.locked
+    message = Message.find(1)
+    replies_count = message.replies_count
+    assert_equal false, message.locked
+    message.locked = true
+    assert message.save
+    assert_equal true, message.locked
 
     reply_author = User.find(2)
     reply = Message.new(:board => @board, :subject => 'Test reply',
                         :content => 'Test reply content',
-                        :parent => @message, :author => reply_author)
+                        :parent => message, :author => reply_author)
     reply.save
     assert_equal 1, reply.errors.count
   end
 
   def test_moving_message_should_update_counters
-    @message = Message.find(1)
+    message = Message.find(1)
     assert_no_difference 'Message.count' do
       # Previous board
       assert_difference 'Board.find(1).topics_count', -1 do
-        assert_difference 'Board.find(1).messages_count', -(1 + @message.replies_count) do
+        assert_difference 'Board.find(1).messages_count', -(1 + message.replies_count) do
           # New board
           assert_difference 'Board.find(2).topics_count' do
-            assert_difference 'Board.find(2).messages_count', (1 + @message.replies_count) do
-              @message.update_attributes(:board_id => 2)
+            assert_difference 'Board.find(2).messages_count', (1 + message.replies_count) do
+              message.update_attributes(:board_id => 2)
             end
           end
         end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/news_test.rb
--- a/test/unit/news_test.rb
+++ b/test/unit/news_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -21,7 +21,7 @@
   fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news
 
   def valid_news
-    { :title => 'Test news', :description => 'Lorem ipsum etc', :author => User.find(:first) }
+    { :title => 'Test news', :description => 'Lorem ipsum etc', :author => User.first }
   end
 
   def setup
diff -r 0a574315af3e -r 4f746d8966dd test/unit/principal_test.rb
--- a/test/unit/principal_test.rb
+++ b/test/unit/principal_test.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -49,64 +49,60 @@
     assert_equal [], Principal.not_member_of([]).sort
   end
 
-  context "#like" do
-    setup do
-      Principal.create!(:login => 'login')
-      Principal.create!(:login => 'login2')
+  def test_sorted_scope_should_sort_users_before_groups
+    scope = Principal.where("type <> ?", 'AnonymousUser')
+    expected_order = scope.all.sort do |a, b|
+      if a.is_a?(User) && b.is_a?(Group)
+        -1
+      elsif a.is_a?(Group) && b.is_a?(User)
+        1
+      else
+        a.name.downcase <=> b.name.downcase
+      end
+    end
+    assert_equal expected_order.map(&:name).map(&:downcase), scope.sorted.all.map(&:name).map(&:downcase)
+  end
 
-      Principal.create!(:firstname => 'firstname')
-      Principal.create!(:firstname => 'firstname2')
+  test "like scope should search login" do
+    results = Principal.like('jsmi')
 
-      Principal.create!(:lastname => 'lastname')
-      Principal.create!(:lastname => 'lastname2')
+    assert results.any?
+    assert results.all? {|u| u.login.match(/jsmi/i) }
+  end
 
-      Principal.create!(:mail => 'mail@example.com')
-      Principal.create!(:mail => 'mail2@example.com')
+  test "like scope should search firstname" do
+    results = Principal.like('john')
 
-      @palmer = Principal.create!(:firstname => 'David', :lastname => 'Palmer')
-    end
+    assert results.any?
+    assert results.all? {|u| u.firstname.match(/john/i) }
+  end
 
-    should "search login" do
-      results = Principal.like('login')
+  test "like scope should search lastname" do
+    results = Principal.like('smi')
 
-      assert_equal 2, results.count
-      assert results.all? {|u| u.login.match(/login/) }
-    end
+    assert results.any?
+    assert results.all? {|u| u.lastname.match(/smi/i) }
+  end
 
-    should "search firstname" do
-      results = Principal.like('firstname')
+  test "like scope should search mail" do
+    results = Principal.like('somenet')
 
-      assert_equal 2, results.count
-      assert results.all? {|u| u.firstname.match(/firstname/) }
-    end
+    assert results.any?
+    assert results.all? {|u| u.mail.match(/somenet/i) }
+  end
 
-    should "search lastname" do
-      results = Principal.like('lastname')
+  test "like scope should search firstname and lastname" do
+    results = Principal.like('john smi')
 
-      assert_equal 2, results.count
-      assert results.all? {|u| u.lastname.match(/lastname/) }
-    end
+    assert_equal 1, results.count
+    assert_equal User.find(2), results.first
+  end
 
-    should "search mail" do
-      results = Principal.like('mail')
+  test "like scope should search lastname and firstname" do
+    results = Principal.like('smith joh')
 
-      assert_equal 2, results.count
-      assert results.all? {|u| u.mail.match(/mail/) }
-    end
-
-    should "search firstname and lastname" do
-      results = Principal.like('david palm')
-
-      assert_equal 1, results.count
-      assert_equal @palmer, results.first
-    end
-
-    should "search lastname and firstname" do
-      results = Principal.like('palmer davi')
-
-      assert_equal 1, results.count
-      assert_equal @palmer, results.first
-    end
+    assert_equal 1, results.count
+    assert_equal User.find(2), results.first
   end
 
   def test_like_scope_with_cyrillic_name
diff -r 0a574315af3e -r 4f746d8966dd test/unit/project_copy_test.rb
--- /dev/null
+++ b/test/unit/project_copy_test.rb
@@ -0,0 +1,337 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ProjectCopyTest < ActiveSupport::TestCase
+  fixtures :projects, :trackers, :issue_statuses, :issues,
+           :journals, :journal_details,
+           :enumerations, :users, :issue_categories,
+           :projects_trackers,
+           :custom_fields,
+           :custom_fields_projects,
+           :custom_fields_trackers,
+           :custom_values,
+           :roles,
+           :member_roles,
+           :members,
+           :enabled_modules,
+           :versions,
+           :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
+           :groups_users,
+           :boards, :messages,
+           :repositories,
+           :news, :comments,
+           :documents
+
+  def setup
+    ProjectCustomField.destroy_all
+    @source_project = Project.find(2)
+    @project = Project.new(:name => 'Copy Test', :identifier => 'copy-test')
+    @project.trackers = @source_project.trackers
+    @project.enabled_module_names = @source_project.enabled_modules.collect(&:name)
+  end
+
+  test "#copy should copy issues" do
+    @source_project.issues << Issue.generate!(:status => IssueStatus.find_by_name('Closed'),
+                                              :subject => "copy issue status",
+                                              :tracker_id => 1,
+                                              :assigned_to_id => 2,
+                                              :project_id => @source_project.id)
+    assert @project.valid?
+    assert @project.issues.empty?
+    assert @project.copy(@source_project)
+
+    assert_equal @source_project.issues.size, @project.issues.size
+    @project.issues.each do |issue|
+      assert issue.valid?
+      assert ! issue.assigned_to.blank?
+      assert_equal @project, issue.project
+    end
+
+    copied_issue = @project.issues.first(:conditions => {:subject => "copy issue status"})
+    assert copied_issue
+    assert copied_issue.status
+    assert_equal "Closed", copied_issue.status.name
+  end
+
+  test "#copy should copy issues custom values" do
+    field = IssueCustomField.generate!(:is_for_all => true, :trackers => Tracker.all)
+    issue = Issue.generate!(:project => @source_project, :subject => 'Custom field copy')
+    issue.custom_field_values = {field.id => 'custom'}
+    issue.save!
+    assert_equal 'custom', issue.reload.custom_field_value(field)
+
+    assert @project.copy(@source_project)
+    copy = @project.issues.find_by_subject('Custom field copy')
+    assert copy
+    assert_equal 'custom', copy.reload.custom_field_value(field)
+  end
+
+  test "#copy should copy issues assigned to a locked version" do
+    User.current = User.find(1)
+    assigned_version = Version.generate!(:name => "Assigned Issues")
+    @source_project.versions << assigned_version
+    Issue.generate!(:project => @source_project,
+                    :fixed_version_id => assigned_version.id,
+                    :subject => "copy issues assigned to a locked version")
+    assigned_version.update_attribute :status, 'locked'
+
+    assert @project.copy(@source_project)
+    @project.reload
+    copied_issue = @project.issues.first(:conditions => {:subject => "copy issues assigned to a locked version"})
+
+    assert copied_issue
+    assert copied_issue.fixed_version
+    assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
+    assert_equal 'locked', copied_issue.fixed_version.status
+  end
+
+  test "#copy should change the new issues to use the copied version" do
+    User.current = User.find(1)
+    assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open')
+    @source_project.versions << assigned_version
+    assert_equal 3, @source_project.versions.size
+    Issue.generate!(:project => @source_project,
+                    :fixed_version_id => assigned_version.id,
+                    :subject => "change the new issues to use the copied version")
+
+    assert @project.copy(@source_project)
+    @project.reload
+    copied_issue = @project.issues.first(:conditions => {:subject => "change the new issues to use the copied version"})
+
+    assert copied_issue
+    assert copied_issue.fixed_version
+    assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
+    assert_not_equal assigned_version.id, copied_issue.fixed_version.id # Different record
+  end
+
+  test "#copy should keep target shared versions from other project" do
+    assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open', :project_id => 1, :sharing => 'system')
+    issue = Issue.generate!(:project => @source_project,
+                            :fixed_version => assigned_version,
+                            :subject => "keep target shared versions")
+
+    assert @project.copy(@source_project)
+    @project.reload
+    copied_issue = @project.issues.first(:conditions => {:subject => "keep target shared versions"})
+
+    assert copied_issue
+    assert_equal assigned_version, copied_issue.fixed_version
+  end
+
+  test "#copy should copy issue relations" do
+    Setting.cross_project_issue_relations = '1'
+
+    second_issue = Issue.generate!(:status_id => 5,
+                                   :subject => "copy issue relation",
+                                   :tracker_id => 1,
+                                   :assigned_to_id => 2,
+                                   :project_id => @source_project.id)
+    source_relation = IssueRelation.create!(:issue_from => Issue.find(4),
+                                              :issue_to => second_issue,
+                                              :relation_type => "relates")
+    source_relation_cross_project = IssueRelation.create!(:issue_from => Issue.find(1),
+                                                            :issue_to => second_issue,
+                                                            :relation_type => "duplicates")
+
+    assert @project.copy(@source_project)
+    assert_equal @source_project.issues.count, @project.issues.count
+    copied_issue = @project.issues.find_by_subject("Issue on project 2") # Was #4
+    copied_second_issue = @project.issues.find_by_subject("copy issue relation")
+
+    # First issue with a relation on project
+    assert_equal 1, copied_issue.relations.size, "Relation not copied"
+    copied_relation = copied_issue.relations.first
+    assert_equal "relates", copied_relation.relation_type
+    assert_equal copied_second_issue.id, copied_relation.issue_to_id
+    assert_not_equal source_relation.id, copied_relation.id
+
+    # Second issue with a cross project relation
+    assert_equal 2, copied_second_issue.relations.size, "Relation not copied"
+    copied_relation = copied_second_issue.relations.select {|r| r.relation_type == 'duplicates'}.first
+    assert_equal "duplicates", copied_relation.relation_type
+    assert_equal 1, copied_relation.issue_from_id, "Cross project relation not kept"
+    assert_not_equal source_relation_cross_project.id, copied_relation.id
+  end
+
+  test "#copy should copy issue attachments" do
+    issue = Issue.generate!(:subject => "copy with attachment", :tracker_id => 1, :project_id => @source_project.id)
+    Attachment.create!(:container => issue, :file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 1)
+    @source_project.issues << issue
+    assert @project.copy(@source_project)
+
+    copied_issue = @project.issues.first(:conditions => {:subject => "copy with attachment"})
+    assert_not_nil copied_issue
+    assert_equal 1, copied_issue.attachments.count, "Attachment not copied"
+    assert_equal "testfile.txt", copied_issue.attachments.first.filename
+  end
+
+  test "#copy should copy memberships" do
+    assert @project.valid?
+    assert @project.members.empty?
+    assert @project.copy(@source_project)
+
+    assert_equal @source_project.memberships.size, @project.memberships.size
+    @project.memberships.each do |membership|
+      assert membership
+      assert_equal @project, membership.project
+    end
+  end
+
+  test "#copy should copy memberships with groups and additional roles" do
+    group = Group.create!(:lastname => "Copy group")
+    user = User.find(7)
+    group.users << user
+    # group role
+    Member.create!(:project_id => @source_project.id, :principal => group, :role_ids => [2])
+    member = Member.find_by_user_id_and_project_id(user.id, @source_project.id)
+    # additional role
+    member.role_ids = [1]
+
+    assert @project.copy(@source_project)
+    member = Member.find_by_user_id_and_project_id(user.id, @project.id)
+    assert_not_nil member
+    assert_equal [1, 2], member.role_ids.sort
+  end
+
+  test "#copy should copy project specific queries" do
+    assert @project.valid?
+    assert @project.queries.empty?
+    assert @project.copy(@source_project)
+
+    assert_equal @source_project.queries.size, @project.queries.size
+    @project.queries.each do |query|
+      assert query
+      assert_equal @project, query.project
+    end
+    assert_equal @source_project.queries.map(&:user_id).sort, @project.queries.map(&:user_id).sort
+  end
+
+  test "#copy should copy versions" do
+    @source_project.versions << Version.generate!
+    @source_project.versions << Version.generate!
+
+    assert @project.versions.empty?
+    assert @project.copy(@source_project)
+
+    assert_equal @source_project.versions.size, @project.versions.size
+    @project.versions.each do |version|
+      assert version
+      assert_equal @project, version.project
+    end
+  end
+
+  test "#copy should copy wiki" do
+    assert_difference 'Wiki.count' do
+      assert @project.copy(@source_project)
+    end
+
+    assert @project.wiki
+    assert_not_equal @source_project.wiki, @project.wiki
+    assert_equal "Start page", @project.wiki.start_page
+  end
+
+  test "#copy should copy wiki without wiki module" do
+    project = Project.new(:name => 'Copy Test', :identifier => 'copy-test', :enabled_module_names => [])
+    assert_difference 'Wiki.count' do
+      assert project.copy(@source_project)
+    end
+
+    assert project.wiki
+  end
+
+  test "#copy should copy wiki pages and content with hierarchy" do
+    assert_difference 'WikiPage.count', @source_project.wiki.pages.size do
+      assert @project.copy(@source_project)
+    end
+
+    assert @project.wiki
+    assert_equal @source_project.wiki.pages.size, @project.wiki.pages.size
+
+    @project.wiki.pages.each do |wiki_page|
+      assert wiki_page.content
+      assert !@source_project.wiki.pages.include?(wiki_page)
+    end
+
+    parent = @project.wiki.find_page('Parent_page')
+    child1 = @project.wiki.find_page('Child_page_1')
+    child2 = @project.wiki.find_page('Child_page_2')
+    assert_equal parent, child1.parent
+    assert_equal parent, child2.parent
+  end
+
+  test "#copy should copy issue categories" do
+    assert @project.copy(@source_project)
+
+    assert_equal 2, @project.issue_categories.size
+    @project.issue_categories.each do |issue_category|
+      assert !@source_project.issue_categories.include?(issue_category)
+    end
+  end
+
+  test "#copy should copy boards" do
+    assert @project.copy(@source_project)
+
+    assert_equal 1, @project.boards.size
+    @project.boards.each do |board|
+      assert !@source_project.boards.include?(board)
+    end
+  end
+
+  test "#copy should change the new issues to use the copied issue categories" do
+    issue = Issue.find(4)
+    issue.update_attribute(:category_id, 3)
+
+    assert @project.copy(@source_project)
+
+    @project.issues.each do |issue|
+      assert issue.category
+      assert_equal "Stock management", issue.category.name # Same name
+      assert_not_equal IssueCategory.find(3), issue.category # Different record
+    end
+  end
+
+  test "#copy should limit copy with :only option" do
+    assert @project.members.empty?
+    assert @project.issue_categories.empty?
+    assert @source_project.issues.any?
+
+    assert @project.copy(@source_project, :only => ['members', 'issue_categories'])
+
+    assert @project.members.any?
+    assert @project.issue_categories.any?
+    assert @project.issues.empty?
+  end
+
+  test "#copy should copy subtasks" do
+    source = Project.generate!(:tracker_ids => [1])
+    issue = Issue.generate_with_descendants!(:project => source)
+    project = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1])
+
+    assert_difference 'Project.count' do
+      assert_difference 'Issue.count', 1+issue.descendants.count do
+        assert project.copy(source.reload)
+      end
+    end
+    copy = Issue.where(:parent_id => nil).order("id DESC").first
+    assert_equal project, copy.project
+    assert_equal issue.descendants.count, copy.descendants.count
+    child_copy = copy.children.detect {|c| c.subject == 'Child1'}
+    assert child_copy.descendants.any?
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/project_members_inheritance_test.rb
--- /dev/null
+++ b/test/unit/project_members_inheritance_test.rb
@@ -0,0 +1,260 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class ProjectMembersInheritanceTest < ActiveSupport::TestCase
+  fixtures :roles, :users
+
+  def setup
+    @parent = Project.generate!
+    @member = Member.create!(:principal => User.find(2), :project => @parent, :role_ids => [1, 2])
+    assert_equal 2, @member.reload.roles.size
+  end
+
+  def test_project_created_with_inherit_members_disabled_should_not_inherit_members
+    assert_no_difference 'Member.count' do
+      project = Project.generate_with_parent!(@parent, :inherit_members => false)
+
+      assert_equal 0, project.memberships.count
+    end
+  end
+
+  def test_project_created_with_inherit_members_should_inherit_members
+    assert_difference 'Member.count', 1 do
+      project = Project.generate_with_parent!(@parent, :inherit_members => true)
+      project.reload
+
+      assert_equal 1, project.memberships.count
+      member = project.memberships.first
+      assert_equal @member.principal, member.principal
+      assert_equal @member.roles.sort, member.roles.sort
+    end
+  end
+
+  def test_turning_on_inherit_members_should_inherit_members
+    Project.generate_with_parent!(@parent, :inherit_members => false)
+
+    assert_difference 'Member.count', 1 do
+      project = Project.order('id desc').first
+      project.inherit_members = true
+      project.save!
+      project.reload
+
+      assert_equal 1, project.memberships.count
+      member = project.memberships.first
+      assert_equal @member.principal, member.principal
+      assert_equal @member.roles.sort, member.roles.sort
+    end
+  end
+
+  def test_turning_off_inherit_members_should_remove_inherited_members
+    Project.generate_with_parent!(@parent, :inherit_members => true)
+
+    assert_difference 'Member.count', -1 do
+      project = Project.order('id desc').first
+      project.inherit_members = false
+      project.save!
+      project.reload
+
+      assert_equal 0, project.memberships.count
+    end
+  end
+
+  def test_moving_a_root_project_under_a_parent_should_inherit_members
+    Project.generate!(:inherit_members => true)
+    project = Project.order('id desc').first
+
+    assert_difference 'Member.count', 1 do
+      project.set_parent!(@parent)
+      project.reload
+
+      assert_equal 1, project.memberships.count
+      member = project.memberships.first
+      assert_equal @member.principal, member.principal
+      assert_equal @member.roles.sort, member.roles.sort
+    end
+  end
+
+  def test_moving_a_subproject_as_root_should_loose_inherited_members
+    Project.generate_with_parent!(@parent, :inherit_members => true)
+    project = Project.order('id desc').first
+
+    assert_difference 'Member.count', -1 do
+      project.set_parent!(nil)
+      project.reload
+
+      assert_equal 0, project.memberships.count
+    end
+  end
+
+  def test_moving_a_subproject_to_another_parent_should_change_inherited_members
+    other_parent = Project.generate!
+    other_member = Member.create!(:principal => User.find(4), :project => other_parent, :role_ids => [3])
+
+    Project.generate_with_parent!(@parent, :inherit_members => true)
+    project = Project.order('id desc').first
+    project.set_parent!(other_parent.reload)
+    project.reload
+
+    assert_equal 1, project.memberships.count
+    member = project.memberships.first
+    assert_equal other_member.principal, member.principal
+    assert_equal other_member.roles.sort, member.roles.sort
+  end
+
+  def test_inheritance_should_propagate_to_subprojects
+    project = Project.generate_with_parent!(@parent, :inherit_members => false)
+    subproject = Project.generate_with_parent!(project, :inherit_members => true)
+    project.reload
+
+    assert_difference 'Member.count', 2 do
+      project.inherit_members = true
+      project.save
+      project.reload
+      subproject.reload
+
+      assert_equal 1, project.memberships.count
+      assert_equal 1, subproject.memberships.count
+      member = subproject.memberships.first
+      assert_equal @member.principal, member.principal
+      assert_equal @member.roles.sort, member.roles.sort
+    end
+  end
+
+  def test_inheritance_removal_should_propagate_to_subprojects
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+    subproject = Project.generate_with_parent!(project, :inherit_members => true)
+    project.reload
+
+    assert_difference 'Member.count', -2 do
+      project.inherit_members = false
+      project.save
+      project.reload
+      subproject.reload
+
+      assert_equal 0, project.memberships.count
+      assert_equal 0, subproject.memberships.count
+    end
+  end
+
+  def test_adding_a_member_should_propagate
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+
+    assert_difference 'Member.count', 2 do
+      member = Member.create!(:principal => User.find(4), :project => @parent, :role_ids => [1, 3])
+
+      inherited_member = project.memberships.order('id desc').first
+      assert_equal member.principal, inherited_member.principal
+      assert_equal member.roles.sort, inherited_member.roles.sort
+    end
+  end
+
+  def test_adding_a_member_should_not_propagate_if_child_does_not_inherit
+    project = Project.generate_with_parent!(@parent, :inherit_members => false)
+
+    assert_difference 'Member.count', 1 do
+      member = Member.create!(:principal => User.find(4), :project => @parent, :role_ids => [1, 3])
+
+      assert_nil project.reload.memberships.detect {|m| m.principal == member.principal}
+    end
+  end
+
+  def test_removing_a_member_should_propagate
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+
+    assert_difference 'Member.count', -2 do
+      @member.reload.destroy
+      project.reload
+
+      assert_equal 0, project.memberships.count
+    end
+  end
+
+  def test_adding_a_group_member_should_propagate_with_its_users
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+    group = Group.generate!
+    user = User.find(4)
+    group.users << user
+
+    assert_difference 'Member.count', 4 do
+      assert_difference 'MemberRole.count', 8 do
+        member = Member.create!(:principal => group, :project => @parent, :role_ids => [1, 3])
+        project.reload
+  
+        inherited_group_member = project.memberships.detect {|m| m.principal == group}
+        assert_not_nil inherited_group_member
+        assert_equal member.roles.sort, inherited_group_member.roles.sort
+  
+        inherited_user_member = project.memberships.detect {|m| m.principal == user}
+        assert_not_nil inherited_user_member
+        assert_equal member.roles.sort, inherited_user_member.roles.sort
+      end
+    end
+  end
+
+  def test_removing_a_group_member_should_propagate
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+    group = Group.generate!
+    user = User.find(4)
+    group.users << user
+    member = Member.create!(:principal => group, :project => @parent, :role_ids => [1, 3])
+
+    assert_difference 'Member.count', -4 do
+      assert_difference 'MemberRole.count', -8 do
+        member.destroy
+        project.reload
+  
+        inherited_group_member = project.memberships.detect {|m| m.principal == group}
+        assert_nil inherited_group_member
+  
+        inherited_user_member = project.memberships.detect {|m| m.principal == user}
+        assert_nil inherited_user_member
+      end
+    end
+  end
+
+  def test_adding_user_who_use_is_already_a_member_to_parent_project_should_merge_roles
+    project = Project.generate_with_parent!(@parent, :inherit_members => true)
+    user = User.find(4)
+    Member.create!(:principal => user, :project => project, :role_ids => [1, 2])
+
+    assert_difference 'Member.count', 1 do
+      Member.create!(:principal => User.find(4), :project => @parent.reload, :role_ids => [1, 3])
+
+      member = project.reload.memberships.detect {|m| m.principal == user}
+      assert_not_nil member
+      assert_equal [1, 2, 3], member.roles.uniq.sort.map(&:id)
+    end
+  end
+
+  def test_turning_on_inheritance_with_user_who_is_already_a_member_should_merge_roles
+    project = Project.generate_with_parent!(@parent)
+    user = @member.user
+    Member.create!(:principal => user, :project => project, :role_ids => [1, 3])
+    project.reload
+
+    assert_no_difference 'Member.count' do
+      project.inherit_members = true
+      project.save!
+
+      member = project.reload.memberships.detect {|m| m.principal == user}
+      assert_not_nil member
+      assert_equal [1, 2, 3], member.roles.uniq.sort.map(&:id)
+    end
+  end
+end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/project_nested_set_test.rb
--- a/test/unit/project_nested_set_test.rb
+++ b/test/unit/project_nested_set_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/project_test.rb
--- a/test/unit/project_test.rb
+++ b/test/unit/project_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,7 +30,6 @@
            :member_roles,
            :members,
            :enabled_modules,
-           :workflows,
            :versions,
            :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
            :groups_users,
@@ -75,9 +74,30 @@
     with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
       assert_equal ['issue_tracking', 'repository'], Project.new.enabled_module_names
     end
+  end
 
-    assert_equal Tracker.all.sort, Project.new.trackers.sort
-    assert_equal Tracker.find(1, 3).sort, Project.new(:tracker_ids => [1, 3]).trackers.sort
+  def test_default_trackers_should_match_default_tracker_ids_setting
+    with_settings :default_projects_tracker_ids => ['1', '3'] do
+      assert_equal Tracker.find(1, 3).sort, Project.new.trackers.sort
+    end
+  end
+
+  def test_default_trackers_should_be_all_trackers_with_blank_setting
+    with_settings :default_projects_tracker_ids => nil do
+      assert_equal Tracker.all.sort, Project.new.trackers.sort
+    end
+  end
+
+  def test_default_trackers_should_be_empty_with_empty_setting
+    with_settings :default_projects_tracker_ids => [] do
+      assert_equal [], Project.new.trackers
+    end
+  end
+
+  def test_default_trackers_should_not_replace_initialized_trackers
+    with_settings :default_projects_tracker_ids => ['1', '3'] do
+      assert_equal Tracker.find(1, 2).sort, Project.new(:tracker_ids => [1, 2]).trackers.sort
+    end
   end
 
   def test_update
@@ -183,7 +203,7 @@
     # 2 active members
     assert_equal 2, @ecookbook.members.size
     # and 1 is locked
-    assert_equal 3, Member.find(:all, :conditions => ['project_id = ?', @ecookbook.id]).size
+    assert_equal 3, Member.where('project_id = ?', @ecookbook.id).all.size
     # some boards
     assert @ecookbook.boards.any?
 
@@ -435,56 +455,67 @@
     assert_equal [1,2], parent.rolled_up_trackers.collect(&:id)
   end
 
-  context "#rolled_up_versions" do
-    setup do
-      @project = Project.generate!
-      @parent_version_1 = Version.generate!(:project => @project)
-      @parent_version_2 = Version.generate!(:project => @project)
-    end
+  test "#rolled_up_trackers should ignore projects with issue_tracking module disabled" do
+    parent = Project.generate!
+    parent.trackers = Tracker.find([1, 2])
+    child = Project.generate_with_parent!(parent)
+    child.trackers = Tracker.find([2, 3])
 
-    should "include the versions for the current project" do
-      assert_same_elements [@parent_version_1, @parent_version_2], @project.rolled_up_versions
-    end
+    assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id).sort
 
-    should "include versions for a subproject" do
-      @subproject = Project.generate!
-      @subproject.set_parent!(@project)
-      @subproject_version = Version.generate!(:project => @subproject)
+    assert child.disable_module!(:issue_tracking)
+    parent.reload
+    assert_equal [1, 2], parent.rolled_up_trackers.collect(&:id).sort
+  end
 
-      assert_same_elements [
-                            @parent_version_1,
-                            @parent_version_2,
-                            @subproject_version
-                           ], @project.rolled_up_versions
-    end
+  test "#rolled_up_versions should include the versions for the current project" do
+    project = Project.generate!
+    parent_version_1 = Version.generate!(:project => project)
+    parent_version_2 = Version.generate!(:project => project)
+    assert_same_elements [parent_version_1, parent_version_2], project.rolled_up_versions
+  end
 
-    should "include versions for a sub-subproject" do
-      @subproject = Project.generate!
-      @subproject.set_parent!(@project)
-      @sub_subproject = Project.generate!
-      @sub_subproject.set_parent!(@subproject)
-      @sub_subproject_version = Version.generate!(:project => @sub_subproject)
+  test "#rolled_up_versions should include versions for a subproject" do
+    project = Project.generate!
+    parent_version_1 = Version.generate!(:project => project)
+    parent_version_2 = Version.generate!(:project => project)
+    subproject = Project.generate_with_parent!(project)
+    subproject_version = Version.generate!(:project => subproject)
 
-      @project.reload
+    assert_same_elements [
+                          parent_version_1,
+                          parent_version_2,
+                          subproject_version
+                         ], project.rolled_up_versions
+  end
 
-      assert_same_elements [
-                            @parent_version_1,
-                            @parent_version_2,
-                            @sub_subproject_version
-                           ], @project.rolled_up_versions
-    end
+  test "#rolled_up_versions should include versions for a sub-subproject" do
+    project = Project.generate!
+    parent_version_1 = Version.generate!(:project => project)
+    parent_version_2 = Version.generate!(:project => project)
+    subproject = Project.generate_with_parent!(project)
+    sub_subproject = Project.generate_with_parent!(subproject)
+    sub_subproject_version = Version.generate!(:project => sub_subproject)
+    project.reload
 
-    should "only check active projects" do
-      @subproject = Project.generate!
-      @subproject.set_parent!(@project)
-      @subproject_version = Version.generate!(:project => @subproject)
-      assert @subproject.archive
+    assert_same_elements [
+                          parent_version_1,
+                          parent_version_2,
+                          sub_subproject_version
+                         ], project.rolled_up_versions
+  end
 
-      @project.reload
+  test "#rolled_up_versions should only check active projects" do
+    project = Project.generate!
+    parent_version_1 = Version.generate!(:project => project)
+    parent_version_2 = Version.generate!(:project => project)
+    subproject = Project.generate_with_parent!(project)
+    subproject_version = Version.generate!(:project => subproject)
+    assert subproject.archive
+    project.reload
 
-      assert !@subproject.active?
-      assert_same_elements [@parent_version_1, @parent_version_2], @project.rolled_up_versions
-    end
+    assert !subproject.active?
+    assert_same_elements [parent_version_1, parent_version_2], project.rolled_up_versions
   end
 
   def test_shared_versions_none_sharing
@@ -611,52 +642,49 @@
     end
   end
 
-  context "enabled_modules" do
-    setup do
-      @project = Project.find(1)
+  test "enabled_modules should define module by names and preserve ids" do
+    @project = Project.find(1)
+    # Remove one module
+    modules = @project.enabled_modules.slice(0..-2)
+    assert modules.any?
+    assert_difference 'EnabledModule.count', -1 do
+      @project.enabled_module_names = modules.collect(&:name)
     end
+    @project.reload
+    # Ids should be preserved
+    assert_equal @project.enabled_module_ids.sort, modules.collect(&:id).sort
+  end
 
-    should "define module by names and preserve ids" do
-      # Remove one module
-      modules = @project.enabled_modules.slice(0..-2)
-      assert modules.any?
-      assert_difference 'EnabledModule.count', -1 do
-        @project.enabled_module_names = modules.collect(&:name)
-      end
-      @project.reload
-      # Ids should be preserved
-      assert_equal @project.enabled_module_ids.sort, modules.collect(&:id).sort
-    end
+  test "enabled_modules should enable a module" do
+    @project = Project.find(1)
+    @project.enabled_module_names = []
+    @project.reload
+    assert_equal [], @project.enabled_module_names
+    #with string
+    @project.enable_module!("issue_tracking")
+    assert_equal ["issue_tracking"], @project.enabled_module_names
+    #with symbol
+    @project.enable_module!(:gantt)
+    assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
+    #don't add a module twice
+    @project.enable_module!("issue_tracking")
+    assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
+  end
 
-    should "enable a module" do
-      @project.enabled_module_names = []
-      @project.reload
-      assert_equal [], @project.enabled_module_names
-      #with string
-      @project.enable_module!("issue_tracking")
-      assert_equal ["issue_tracking"], @project.enabled_module_names
-      #with symbol
-      @project.enable_module!(:gantt)
-      assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
-      #don't add a module twice
-      @project.enable_module!("issue_tracking")
-      assert_equal ["issue_tracking", "gantt"], @project.enabled_module_names
-    end
-
-    should "disable a module" do
-      #with string
-      assert @project.enabled_module_names.include?("issue_tracking")
-      @project.disable_module!("issue_tracking")
-      assert ! @project.reload.enabled_module_names.include?("issue_tracking")
-      #with symbol
-      assert @project.enabled_module_names.include?("gantt")
-      @project.disable_module!(:gantt)
-      assert ! @project.reload.enabled_module_names.include?("gantt")
-      #with EnabledModule object
-      first_module = @project.enabled_modules.first
-      @project.disable_module!(first_module)
-      assert ! @project.reload.enabled_module_names.include?(first_module.name)
-    end
+  test "enabled_modules should disable a module" do
+    @project = Project.find(1)
+    #with string
+    assert @project.enabled_module_names.include?("issue_tracking")
+    @project.disable_module!("issue_tracking")
+    assert ! @project.reload.enabled_module_names.include?("issue_tracking")
+    #with symbol
+    assert @project.enabled_module_names.include?("gantt")
+    @project.disable_module!(:gantt)
+    assert ! @project.reload.enabled_module_names.include?("gantt")
+    #with EnabledModule object
+    first_module = @project.enabled_modules.first
+    @project.disable_module!(first_module)
+    assert ! @project.reload.enabled_module_names.include?(first_module.name)
   end
 
   def test_enabled_module_names_should_not_recreate_enabled_modules
@@ -693,7 +721,7 @@
 
   def test_activities_should_use_the_system_activities
     project = Project.find(1)
-    assert_equal project.activities, TimeEntryActivity.find(:all, :conditions => {:active => true} )
+    assert_equal project.activities, TimeEntryActivity.where(:active => true).all
   end
 
 
@@ -707,7 +735,7 @@
 
   def test_activities_should_not_include_the_inactive_project_specific_activities
     project = Project.find(1)
-    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.find(:first), :active => false})
+    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.first, :active => false})
     assert overridden_activity.save!
 
     assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity found"
@@ -722,7 +750,7 @@
   end
 
   def test_activities_should_handle_nils
-    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(1), :parent => TimeEntryActivity.find(:first)})
+    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(1), :parent => TimeEntryActivity.first})
     TimeEntryActivity.delete_all
 
     # No activities
@@ -737,7 +765,7 @@
 
   def test_activities_should_override_system_activities_with_project_activities
     project = Project.find(1)
-    parent_activity = TimeEntryActivity.find(:first)
+    parent_activity = TimeEntryActivity.first
     overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => parent_activity})
     assert overridden_activity.save!
 
@@ -747,7 +775,7 @@
 
   def test_activities_should_include_inactive_activities_if_specified
     project = Project.find(1)
-    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.find(:first), :active => false})
+    overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.first, :active => false})
     assert overridden_activity.save!
 
     assert project.activities(true).include?(overridden_activity), "Inactive Project specific Activity not found"
@@ -775,438 +803,135 @@
     assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'}
   end
 
-  context "Project#copy" do
-    setup do
-      ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
-      Project.destroy_all :identifier => "copy-test"
-      @source_project = Project.find(2)
-      @project = Project.new(:name => 'Copy Test', :identifier => 'copy-test')
-      @project.trackers = @source_project.trackers
-      @project.enabled_module_names = @source_project.enabled_modules.collect(&:name)
-    end
-
-    should "copy issues" do
-      @source_project.issues << Issue.generate!(:status => IssueStatus.find_by_name('Closed'),
-                                                :subject => "copy issue status",
-                                                :tracker_id => 1,
-                                                :assigned_to_id => 2,
-                                                :project_id => @source_project.id)
-      assert @project.valid?
-      assert @project.issues.empty?
-      assert @project.copy(@source_project)
-
-      assert_equal @source_project.issues.size, @project.issues.size
-      @project.issues.each do |issue|
-        assert issue.valid?
-        assert ! issue.assigned_to.blank?
-        assert_equal @project, issue.project
-      end
-
-      copied_issue = @project.issues.first(:conditions => {:subject => "copy issue status"})
-      assert copied_issue
-      assert copied_issue.status
-      assert_equal "Closed", copied_issue.status.name
-    end
-
-    should "copy issues assigned to a locked version" do
-      User.current = User.find(1)
-      assigned_version = Version.generate!(:name => "Assigned Issues")
-      @source_project.versions << assigned_version
-      Issue.generate!(:project => @source_project,
-                      :fixed_version_id => assigned_version.id,
-                      :subject => "copy issues assigned to a locked version")
-      assigned_version.update_attribute :status, 'locked'
-
-      assert @project.copy(@source_project)
-      @project.reload
-      copied_issue = @project.issues.first(:conditions => {:subject => "copy issues assigned to a locked version"})
-
-      assert copied_issue
-      assert copied_issue.fixed_version
-      assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
-      assert_equal 'locked', copied_issue.fixed_version.status
-    end
-
-    should "change the new issues to use the copied version" do
-      User.current = User.find(1)
-      assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open')
-      @source_project.versions << assigned_version
-      assert_equal 3, @source_project.versions.size
-      Issue.generate!(:project => @source_project,
-                      :fixed_version_id => assigned_version.id,
-                      :subject => "change the new issues to use the copied version")
-
-      assert @project.copy(@source_project)
-      @project.reload
-      copied_issue = @project.issues.first(:conditions => {:subject => "change the new issues to use the copied version"})
-
-      assert copied_issue
-      assert copied_issue.fixed_version
-      assert_equal "Assigned Issues", copied_issue.fixed_version.name # Same name
-      assert_not_equal assigned_version.id, copied_issue.fixed_version.id # Different record
-    end
-
-    should "keep target shared versions from other project" do
-      assigned_version = Version.generate!(:name => "Assigned Issues", :status => 'open', :project_id => 1, :sharing => 'system')
-      issue = Issue.generate!(:project => @source_project,
-                              :fixed_version => assigned_version,
-                              :subject => "keep target shared versions")
-
-      assert @project.copy(@source_project)
-      @project.reload
-      copied_issue = @project.issues.first(:conditions => {:subject => "keep target shared versions"})
-
-      assert copied_issue
-      assert_equal assigned_version, copied_issue.fixed_version
-    end
-
-    should "copy issue relations" do
-      Setting.cross_project_issue_relations = '1'
-
-      second_issue = Issue.generate!(:status_id => 5,
-                                     :subject => "copy issue relation",
-                                     :tracker_id => 1,
-                                     :assigned_to_id => 2,
-                                     :project_id => @source_project.id)
-      source_relation = IssueRelation.create!(:issue_from => Issue.find(4),
-                                                :issue_to => second_issue,
-                                                :relation_type => "relates")
-      source_relation_cross_project = IssueRelation.create!(:issue_from => Issue.find(1),
-                                                              :issue_to => second_issue,
-                                                              :relation_type => "duplicates")
-
-      assert @project.copy(@source_project)
-      assert_equal @source_project.issues.count, @project.issues.count
-      copied_issue = @project.issues.find_by_subject("Issue on project 2") # Was #4
-      copied_second_issue = @project.issues.find_by_subject("copy issue relation")
-
-      # First issue with a relation on project
-      assert_equal 1, copied_issue.relations.size, "Relation not copied"
-      copied_relation = copied_issue.relations.first
-      assert_equal "relates", copied_relation.relation_type
-      assert_equal copied_second_issue.id, copied_relation.issue_to_id
-      assert_not_equal source_relation.id, copied_relation.id
-
-      # Second issue with a cross project relation
-      assert_equal 2, copied_second_issue.relations.size, "Relation not copied"
-      copied_relation = copied_second_issue.relations.select {|r| r.relation_type == 'duplicates'}.first
-      assert_equal "duplicates", copied_relation.relation_type
-      assert_equal 1, copied_relation.issue_from_id, "Cross project relation not kept"
-      assert_not_equal source_relation_cross_project.id, copied_relation.id
-    end
-
-    should "copy issue attachments" do
-      issue = Issue.generate!(:subject => "copy with attachment", :tracker_id => 1, :project_id => @source_project.id)
-      Attachment.create!(:container => issue, :file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 1)
-      @source_project.issues << issue
-      assert @project.copy(@source_project)
-
-      copied_issue = @project.issues.first(:conditions => {:subject => "copy with attachment"})
-      assert_not_nil copied_issue
-      assert_equal 1, copied_issue.attachments.count, "Attachment not copied"
-      assert_equal "testfile.txt", copied_issue.attachments.first.filename
-    end
-
-    should "copy memberships" do
-      assert @project.valid?
-      assert @project.members.empty?
-      assert @project.copy(@source_project)
-
-      assert_equal @source_project.memberships.size, @project.memberships.size
-      @project.memberships.each do |membership|
-        assert membership
-        assert_equal @project, membership.project
-      end
-    end
-
-    should "copy memberships with groups and additional roles" do
-      group = Group.create!(:lastname => "Copy group")
-      user = User.find(7)
-      group.users << user
-      # group role
-      Member.create!(:project_id => @source_project.id, :principal => group, :role_ids => [2])
-      member = Member.find_by_user_id_and_project_id(user.id, @source_project.id)
-      # additional role
-      member.role_ids = [1]
-
-      assert @project.copy(@source_project)
-      member = Member.find_by_user_id_and_project_id(user.id, @project.id)
-      assert_not_nil member
-      assert_equal [1, 2], member.role_ids.sort
-    end
-
-    should "copy project specific queries" do
-      assert @project.valid?
-      assert @project.queries.empty?
-      assert @project.copy(@source_project)
-
-      assert_equal @source_project.queries.size, @project.queries.size
-      @project.queries.each do |query|
-        assert query
-        assert_equal @project, query.project
-      end
-      assert_equal @source_project.queries.map(&:user_id).sort, @project.queries.map(&:user_id).sort
-    end
-
-    should "copy versions" do
-      @source_project.versions << Version.generate!
-      @source_project.versions << Version.generate!
-
-      assert @project.versions.empty?
-      assert @project.copy(@source_project)
-
-      assert_equal @source_project.versions.size, @project.versions.size
-      @project.versions.each do |version|
-        assert version
-        assert_equal @project, version.project
-      end
-    end
-
-    should "copy wiki" do
-      assert_difference 'Wiki.count' do
-        assert @project.copy(@source_project)
-      end
-
-      assert @project.wiki
-      assert_not_equal @source_project.wiki, @project.wiki
-      assert_equal "Start page", @project.wiki.start_page
-    end
-
-    should "copy wiki pages and content with hierarchy" do
-      assert_difference 'WikiPage.count', @source_project.wiki.pages.size do
-        assert @project.copy(@source_project)
-      end
-
-      assert @project.wiki
-      assert_equal @source_project.wiki.pages.size, @project.wiki.pages.size
-
-      @project.wiki.pages.each do |wiki_page|
-        assert wiki_page.content
-        assert !@source_project.wiki.pages.include?(wiki_page)
-      end
-
-      parent = @project.wiki.find_page('Parent_page')
-      child1 = @project.wiki.find_page('Child_page_1')
-      child2 = @project.wiki.find_page('Child_page_2')
-      assert_equal parent, child1.parent
-      assert_equal parent, child2.parent
-    end
-
-    should "copy issue categories" do
-      assert @project.copy(@source_project)
-
-      assert_equal 2, @project.issue_categories.size
-      @project.issue_categories.each do |issue_category|
-        assert !@source_project.issue_categories.include?(issue_category)
-      end
-    end
-
-    should "copy boards" do
-      assert @project.copy(@source_project)
-
-      assert_equal 1, @project.boards.size
-      @project.boards.each do |board|
-        assert !@source_project.boards.include?(board)
-      end
-    end
-
-    should "change the new issues to use the copied issue categories" do
-      issue = Issue.find(4)
-      issue.update_attribute(:category_id, 3)
-
-      assert @project.copy(@source_project)
-
-      @project.issues.each do |issue|
-        assert issue.category
-        assert_equal "Stock management", issue.category.name # Same name
-        assert_not_equal IssueCategory.find(3), issue.category # Different record
-      end
-    end
-
-    should "limit copy with :only option" do
-      assert @project.members.empty?
-      assert @project.issue_categories.empty?
-      assert @source_project.issues.any?
-
-      assert @project.copy(@source_project, :only => ['members', 'issue_categories'])
-
-      assert @project.members.any?
-      assert @project.issue_categories.any?
-      assert @project.issues.empty?
-    end
+  test "#start_date should be nil if there are no issues on the project" do
+    project = Project.generate!
+    assert_nil project.start_date
   end
 
-  def test_copy_should_copy_subtasks
-    source = Project.generate!(:tracker_ids => [1])
-    issue = Issue.generate_with_descendants!(:project => source)
-    project = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1])
+  test "#start_date should be nil when issues have no start date" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    early = 7.days.ago.to_date
+    Issue.generate!(:project => project, :start_date => nil)
 
-    assert_difference 'Project.count' do
-      assert_difference 'Issue.count', 1+issue.descendants.count do
-        assert project.copy(source.reload)
-      end
-    end
-    copy = Issue.where(:parent_id => nil).order("id DESC").first
-    assert_equal project, copy.project
-    assert_equal issue.descendants.count, copy.descendants.count
-    child_copy = copy.children.detect {|c| c.subject == 'Child1'}
-    assert child_copy.descendants.any?
+    assert_nil project.start_date
   end
 
-  context "#start_date" do
-    setup do
-      ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
-      @project = Project.generate!(:identifier => 'test0')
-      @project.trackers << Tracker.generate!
-    end
+  test "#start_date should be the earliest start date of it's issues" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    early = 7.days.ago.to_date
+    Issue.generate!(:project => project, :start_date => Date.today)
+    Issue.generate!(:project => project, :start_date => early)
 
-    should "be nil if there are no issues on the project" do
-      assert_nil @project.start_date
-    end
-
-    should "be tested when issues have no start date"
-
-    should "be the earliest start date of it's issues" do
-      early = 7.days.ago.to_date
-      Issue.generate!(:project => @project, :start_date => Date.today)
-      Issue.generate!(:project => @project, :start_date => early)
-
-      assert_equal early, @project.start_date
-    end
-
+    assert_equal early, project.start_date
   end
 
-  context "#due_date" do
-    setup do
-      ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
-      @project = Project.generate!(:identifier => 'test0')
-      @project.trackers << Tracker.generate!
-    end
-
-    should "be nil if there are no issues on the project" do
-      assert_nil @project.due_date
-    end
-
-    should "be tested when issues have no due date"
-
-    should "be the latest due date of it's issues" do
-      future = 7.days.from_now.to_date
-      Issue.generate!(:project => @project, :due_date => future)
-      Issue.generate!(:project => @project, :due_date => Date.today)
-
-      assert_equal future, @project.due_date
-    end
-
-    should "be the latest due date of it's versions" do
-      future = 7.days.from_now.to_date
-      @project.versions << Version.generate!(:effective_date => future)
-      @project.versions << Version.generate!(:effective_date => Date.today)
-
-
-      assert_equal future, @project.due_date
-
-    end
-
-    should "pick the latest date from it's issues and versions" do
-      future = 7.days.from_now.to_date
-      far_future = 14.days.from_now.to_date
-      Issue.generate!(:project => @project, :due_date => far_future)
-      @project.versions << Version.generate!(:effective_date => future)
-
-      assert_equal far_future, @project.due_date
-    end
-
+  test "#due_date should be nil if there are no issues on the project" do
+    project = Project.generate!
+    assert_nil project.due_date
   end
 
-  context "Project#completed_percent" do
-    setup do
-      ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
-      @project = Project.generate!(:identifier => 'test0')
-      @project.trackers << Tracker.generate!
-    end
+  test "#due_date should be nil if there are no issues with due dates" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    Issue.generate!(:project => project, :due_date => nil)
 
-    context "no versions" do
-      should "be 100" do
-        assert_equal 100, @project.completed_percent
-      end
-    end
-
-    context "with versions" do
-      should "return 0 if the versions have no issues" do
-        Version.generate!(:project => @project)
-        Version.generate!(:project => @project)
-
-        assert_equal 0, @project.completed_percent
-      end
-
-      should "return 100 if the version has only closed issues" do
-        v1 = Version.generate!(:project => @project)
-        Issue.generate!(:project => @project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v1)
-        v2 = Version.generate!(:project => @project)
-        Issue.generate!(:project => @project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v2)
-
-        assert_equal 100, @project.completed_percent
-      end
-
-      should "return the averaged completed percent of the versions (not weighted)" do
-        v1 = Version.generate!(:project => @project)
-        Issue.generate!(:project => @project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v1)
-        v2 = Version.generate!(:project => @project)
-        Issue.generate!(:project => @project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v2)
-
-        assert_equal 50, @project.completed_percent
-      end
-
-    end
+    assert_nil project.due_date
   end
 
-  context "#notified_users" do
-    setup do
-      @project = Project.generate!
-      @role = Role.generate!
+  test "#due_date should be the latest due date of it's issues" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    future = 7.days.from_now.to_date
+    Issue.generate!(:project => project, :due_date => future)
+    Issue.generate!(:project => project, :due_date => Date.today)
 
-      @user_with_membership_notification = User.generate!(:mail_notification => 'selected')
-      Member.create!(:project => @project, :roles => [@role], :principal => @user_with_membership_notification, :mail_notification => true)
-
-      @all_events_user = User.generate!(:mail_notification => 'all')
-      Member.create!(:project => @project, :roles => [@role], :principal => @all_events_user)
-
-      @no_events_user = User.generate!(:mail_notification => 'none')
-      Member.create!(:project => @project, :roles => [@role], :principal => @no_events_user)
-
-      @only_my_events_user = User.generate!(:mail_notification => 'only_my_events')
-      Member.create!(:project => @project, :roles => [@role], :principal => @only_my_events_user)
-
-      @only_assigned_user = User.generate!(:mail_notification => 'only_assigned')
-      Member.create!(:project => @project, :roles => [@role], :principal => @only_assigned_user)
-
-      @only_owned_user = User.generate!(:mail_notification => 'only_owner')
-      Member.create!(:project => @project, :roles => [@role], :principal => @only_owned_user)
-    end
-
-    should "include members with a mail notification" do
-      assert @project.notified_users.include?(@user_with_membership_notification)
-    end
-
-    should "include users with the 'all' notification option" do
-      assert @project.notified_users.include?(@all_events_user)
-    end
-
-    should "not include users with the 'none' notification option" do
-      assert !@project.notified_users.include?(@no_events_user)
-    end
-
-    should "not include users with the 'only_my_events' notification option" do
-      assert !@project.notified_users.include?(@only_my_events_user)
-    end
-
-    should "not include users with the 'only_assigned' notification option" do
-      assert !@project.notified_users.include?(@only_assigned_user)
-    end
-
-    should "not include users with the 'only_owner' notification option" do
-      assert !@project.notified_users.include?(@only_owned_user)
-    end
+    assert_equal future, project.due_date
   end
 
+  test "#due_date should be the latest due date of it's versions" do
+    project = Project.generate!
+    future = 7.days.from_now.to_date
+    project.versions << Version.generate!(:effective_date => future)
+    project.versions << Version.generate!(:effective_date => Date.today)
+
+    assert_equal future, project.due_date
+  end
+
+  test "#due_date should pick the latest date from it's issues and versions" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    future = 7.days.from_now.to_date
+    far_future = 14.days.from_now.to_date
+    Issue.generate!(:project => project, :due_date => far_future)
+    project.versions << Version.generate!(:effective_date => future)
+
+    assert_equal far_future, project.due_date
+  end
+
+  test "#completed_percent with no versions should be 100" do
+    project = Project.generate!
+    assert_equal 100, project.completed_percent
+  end
+
+  test "#completed_percent with versions should return 0 if the versions have no issues" do
+    project = Project.generate!
+    Version.generate!(:project => project)
+    Version.generate!(:project => project)
+
+    assert_equal 0, project.completed_percent
+  end
+
+  test "#completed_percent with versions should return 100 if the version has only closed issues" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    v1 = Version.generate!(:project => project)
+    Issue.generate!(:project => project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v1)
+    v2 = Version.generate!(:project => project)
+    Issue.generate!(:project => project, :status => IssueStatus.find_by_name('Closed'), :fixed_version => v2)
+
+    assert_equal 100, project.completed_percent
+  end
+
+  test "#completed_percent with versions should return the averaged completed percent of the versions (not weighted)" do
+    project = Project.generate!
+    project.trackers << Tracker.generate!
+    v1 = Version.generate!(:project => project)
+    Issue.generate!(:project => project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v1)
+    v2 = Version.generate!(:project => project)
+    Issue.generate!(:project => project, :status => IssueStatus.find_by_name('New'), :estimated_hours => 10, :done_ratio => 50, :fixed_version => v2)
+
+    assert_equal 50, project.completed_percent
+  end
+
+  test "#notified_users" do
+    project = Project.generate!
+    role = Role.generate!
+
+    user_with_membership_notification = User.generate!(:mail_notification => 'selected')
+    Member.create!(:project => project, :roles => [role], :principal => user_with_membership_notification, :mail_notification => true)
+
+    all_events_user = User.generate!(:mail_notification => 'all')
+    Member.create!(:project => project, :roles => [role], :principal => all_events_user)
+
+    no_events_user = User.generate!(:mail_notification => 'none')
+    Member.create!(:project => project, :roles => [role], :principal => no_events_user)
+
+    only_my_events_user = User.generate!(:mail_notification => 'only_my_events')
+    Member.create!(:project => project, :roles => [role], :principal => only_my_events_user)
+
+    only_assigned_user = User.generate!(:mail_notification => 'only_assigned')
+    Member.create!(:project => project, :roles => [role], :principal => only_assigned_user)
+
+    only_owned_user = User.generate!(:mail_notification => 'only_owner')
+    Member.create!(:project => project, :roles => [role], :principal => only_owned_user)
+
+    assert project.notified_users.include?(user_with_membership_notification), "should include members with a mail notification"
+    assert project.notified_users.include?(all_events_user), "should include users with the 'all' notification option"
+    assert !project.notified_users.include?(no_events_user), "should not include users with the 'none' notification option"
+    assert !project.notified_users.include?(only_my_events_user), "should not include users with the 'only_my_events' notification option"
+    assert !project.notified_users.include?(only_assigned_user), "should not include users with the 'only_assigned' notification option"
+    assert !project.notified_users.include?(only_owned_user), "should not include users with the 'only_owner' notification option"
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/query_test.rb
--- a/test/unit/query_test.rb
+++ b/test/unit/query_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -28,21 +28,26 @@
            :projects_trackers,
            :custom_fields_trackers
 
+  def test_available_filters_should_be_ordered
+    query = IssueQuery.new
+    assert_equal 0, query.available_filters.keys.index('status_id')
+  end
+
   def test_custom_fields_for_all_projects_should_be_available_in_global_queries
-    query = Query.new(:project => nil, :name => '_')
+    query = IssueQuery.new(:project => nil, :name => '_')
     assert query.available_filters.has_key?('cf_1')
     assert !query.available_filters.has_key?('cf_3')
   end
 
   def test_system_shared_versions_should_be_available_in_global_queries
     Version.find(2).update_attribute :sharing, 'system'
-    query = Query.new(:project => nil, :name => '_')
+    query = IssueQuery.new(:project => nil, :name => '_')
     assert query.available_filters.has_key?('fixed_version_id')
     assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'}
   end
 
   def test_project_filter_in_global_queries
-    query = Query.new(:project => nil, :name => '_')
+    query = IssueQuery.new(:project => nil, :name => '_')
     project_filter = query.available_filters["project_id"]
     assert_not_nil project_filter
     project_ids = project_filter[:values].map{|p| p[1]}
@@ -63,7 +68,7 @@
   end
 
   def assert_query_statement_includes(query, condition)
-    assert query.statement.include?(condition), "Query statement condition not found in: #{query.statement}"
+    assert_include condition, query.statement
   end
   
   def assert_query_result(expected, query)
@@ -75,14 +80,14 @@
 
   def test_query_should_allow_shared_versions_for_a_project_query
     subproject_version = Version.find(4)
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
 
     assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
   end
 
   def test_query_with_multiple_custom_fields
-    query = Query.find(1)
+    query = IssueQuery.find(1)
     assert query.valid?
     assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
     issues = find_issues_with_query(query)
@@ -91,7 +96,7 @@
   end
 
   def test_operator_none
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('fixed_version_id', '!*', [''])
     query.add_filter('cf_1', '!*', [''])
     assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
@@ -100,7 +105,7 @@
   end
 
   def test_operator_none_for_integer
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('estimated_hours', '!*', [''])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -108,7 +113,7 @@
   end
 
   def test_operator_none_for_date
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('start_date', '!*', [''])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -116,7 +121,7 @@
   end
 
   def test_operator_none_for_string_custom_field
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('cf_2', '!*', [''])
     assert query.has_filter?('cf_2')
     issues = find_issues_with_query(query)
@@ -125,7 +130,7 @@
   end
 
   def test_operator_all
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('fixed_version_id', '*', [''])
     query.add_filter('cf_1', '*', [''])
     assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
@@ -134,7 +139,7 @@
   end
 
   def test_operator_all_for_date
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('start_date', '*', [''])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -142,7 +147,7 @@
   end
 
   def test_operator_all_for_string_custom_field
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('cf_2', '*', [''])
     assert query.has_filter?('cf_2')
     issues = find_issues_with_query(query)
@@ -151,7 +156,7 @@
   end
 
   def test_numeric_filter_should_not_accept_non_numeric_values
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter('estimated_hours', '=', ['a'])
 
     assert query.has_filter?('estimated_hours')
@@ -161,7 +166,7 @@
   def test_operator_is_on_float
     Issue.update_all("estimated_hours = 171.2", "id=2")
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter('estimated_hours', '=', ['171.20'])
     issues = find_issues_with_query(query)
     assert_equal 1, issues.size
@@ -174,7 +179,7 @@
     CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
     CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter("cf_#{f.id}", '=', ['12'])
     issues = find_issues_with_query(query)
     assert_equal 1, issues.size
@@ -187,7 +192,7 @@
     CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12')
     CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter("cf_#{f.id}", '=', ['-12'])
     assert query.valid?
     issues = find_issues_with_query(query)
@@ -201,7 +206,7 @@
     CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12.7')
     CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter("cf_#{f.id}", '=', ['12.7'])
     issues = find_issues_with_query(query)
     assert_equal 1, issues.size
@@ -214,7 +219,7 @@
     CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12.7')
     CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter("cf_#{f.id}", '=', ['-12.7'])
     assert query.valid?
     issues = find_issues_with_query(query)
@@ -229,12 +234,12 @@
     CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
     CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter("cf_#{f.id}", '=', ['value1'])
     issues = find_issues_with_query(query)
     assert_equal [1, 3], issues.map(&:id).sort
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter("cf_#{f.id}", '=', ['value2'])
     issues = find_issues_with_query(query)
     assert_equal [1], issues.map(&:id).sort
@@ -247,13 +252,13 @@
     CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
     CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter("cf_#{f.id}", '!', ['value1'])
     issues = find_issues_with_query(query)
     assert !issues.map(&:id).include?(1)
     assert !issues.map(&:id).include?(3)
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter("cf_#{f.id}", '!', ['value2'])
     issues = find_issues_with_query(query)
     assert !issues.map(&:id).include?(1)
@@ -264,7 +269,7 @@
     # is_private filter only available for those who can set issues private
     User.current = User.find(2)
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     assert query.available_filters.key?('is_private')
 
     query.add_filter("is_private", '=', ['1'])
@@ -279,7 +284,7 @@
     # is_private filter only available for those who can set issues private
     User.current = User.find(2)
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     assert query.available_filters.key?('is_private')
 
     query.add_filter("is_private", '!', ['1'])
@@ -291,14 +296,14 @@
   end
 
   def test_operator_greater_than
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('done_ratio', '>=', ['40'])
     assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
     find_issues_with_query(query)
   end
 
   def test_operator_greater_than_a_float
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('estimated_hours', '>=', ['40.5'])
     assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
     find_issues_with_query(query)
@@ -310,7 +315,7 @@
     CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
     CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
 
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter("cf_#{f.id}", '>=', ['8'])
     issues = find_issues_with_query(query)
     assert_equal 1, issues.size
@@ -318,7 +323,7 @@
   end
 
   def test_operator_lesser_than
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('done_ratio', '<=', ['30'])
     assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
     find_issues_with_query(query)
@@ -326,14 +331,28 @@
 
   def test_operator_lesser_than_on_custom_field
     f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter("cf_#{f.id}", '<=', ['30'])
-    assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) <= 30.0")
+    assert_match /CAST.+ <= 30\.0/, query.statement
     find_issues_with_query(query)
   end
 
+  def test_operator_lesser_than_on_date_custom_field
+    f = IssueCustomField.create!(:name => 'filter', :field_format => 'date', :is_filter => true, :is_for_all => true)
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '2013-04-11')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '2013-05-14')
+    CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
+
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
+    query.add_filter("cf_#{f.id}", '<=', ['2013-05-01'])
+    issue_ids = find_issues_with_query(query).map(&:id)
+    assert_include 1, issue_ids
+    assert_not_include 2, issue_ids
+    assert_not_include 3, issue_ids
+  end
+
   def test_operator_between
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('done_ratio', '><', ['30', '40'])
     assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
     find_issues_with_query(query)
@@ -341,14 +360,14 @@
 
   def test_operator_between_on_custom_field
     f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter("cf_#{f.id}", '><', ['30', '40'])
-    assert_include "CAST(custom_values.value AS decimal(60,3)) BETWEEN 30.0 AND 40.0", query.statement
+    assert_match /CAST.+ BETWEEN 30.0 AND 40.0/, query.statement
     find_issues_with_query(query)
   end
 
   def test_date_filter_should_not_accept_non_date_values
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter('created_on', '=', ['a'])
 
     assert query.has_filter?('created_on')
@@ -356,7 +375,7 @@
   end
 
   def test_date_filter_should_not_accept_invalid_date_values
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter('created_on', '=', ['2011-01-34'])
 
     assert query.has_filter?('created_on')
@@ -364,7 +383,7 @@
   end
 
   def test_relative_date_filter_should_not_accept_non_integer_values
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter('created_on', '>t-', ['a'])
 
     assert query.has_filter?('created_on')
@@ -372,28 +391,28 @@
   end
 
   def test_operator_date_equals
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter('due_date', '=', ['2011-07-10'])
     assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
     find_issues_with_query(query)
   end
 
   def test_operator_date_lesser_than
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter('due_date', '<=', ['2011-07-10'])
     assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
     find_issues_with_query(query)
   end
 
   def test_operator_date_greater_than
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter('due_date', '>=', ['2011-07-10'])
     assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
     find_issues_with_query(query)
   end
 
   def test_operator_date_between
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
     assert_match /issues\.due_date > '2011-06-22 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
     find_issues_with_query(query)
@@ -401,7 +420,7 @@
 
   def test_operator_in_more_than
     Issue.find(7).update_attribute(:due_date, (Date.today + 15))
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', '>t+', ['15'])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -409,7 +428,7 @@
   end
 
   def test_operator_in_less_than
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', '<t+', ['15'])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -417,7 +436,7 @@
   end
 
   def test_operator_in_the_next_days
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', '><t+', ['15'])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -426,7 +445,7 @@
 
   def test_operator_less_than_ago
     Issue.find(7).update_attribute(:due_date, (Date.today - 3))
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', '>t-', ['3'])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -435,7 +454,7 @@
 
   def test_operator_in_the_past_days
     Issue.find(7).update_attribute(:due_date, (Date.today - 3))
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', '><t-', ['3'])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -444,7 +463,7 @@
 
   def test_operator_more_than_ago
     Issue.find(7).update_attribute(:due_date, (Date.today - 10))
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', '<t-', ['10'])
     assert query.statement.include?("#{Issue.table_name}.due_date <=")
     issues = find_issues_with_query(query)
@@ -454,7 +473,7 @@
 
   def test_operator_in
     Issue.find(7).update_attribute(:due_date, (Date.today + 2))
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', 't+', ['2'])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -463,7 +482,7 @@
 
   def test_operator_ago
     Issue.find(7).update_attribute(:due_date, (Date.today - 3))
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', 't-', ['3'])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -471,7 +490,7 @@
   end
 
   def test_operator_today
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', 't', [''])
     issues = find_issues_with_query(query)
     assert !issues.empty?
@@ -479,19 +498,19 @@
   end
 
   def test_operator_this_week_on_date
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', 'w', [''])
     find_issues_with_query(query)
   end
 
   def test_operator_this_week_on_datetime
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('created_on', 'w', [''])
     find_issues_with_query(query)
   end
 
   def test_operator_contains
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('subject', '~', ['uNable'])
     assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
     result = find_issues_with_query(query)
@@ -505,7 +524,7 @@
 
     Date.stubs(:today).returns(Date.parse('2011-04-29'))
 
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', 'w', [''])
     assert query.statement.match(/issues\.due_date > '2011-04-24 23:59:59(\.9+)?' AND issues\.due_date <= '2011-05-01 23:59:59(\.9+)?/), "range not found in #{query.statement}"
     I18n.locale = :en
@@ -517,13 +536,13 @@
 
     Date.stubs(:today).returns(Date.parse('2011-04-29'))
 
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('due_date', 'w', [''])
     assert query.statement.match(/issues\.due_date > '2011-04-23 23:59:59(\.9+)?' AND issues\.due_date <= '2011-04-30 23:59:59(\.9+)?/), "range not found in #{query.statement}"
   end
 
   def test_operator_does_not_contains
-    query = Query.new(:project => Project.find(1), :name => '_')
+    query = IssueQuery.new(:project => Project.find(1), :name => '_')
     query.add_filter('subject', '!~', ['uNable'])
     assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
     find_issues_with_query(query)
@@ -538,7 +557,7 @@
     i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
     group.users << user
 
-    query = Query.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
+    query = IssueQuery.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
     result = query.issues
     assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id)
 
@@ -553,7 +572,7 @@
     issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '2'}, :subject => 'Test', :author_id => 1)
     issue2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '3'})
 
-    query = Query.new(:name => '_', :project => Project.find(1))
+    query = IssueQuery.new(:name => '_', :project => Project.find(1))
     filter = query.available_filters["cf_#{cf.id}"]
     assert_not_nil filter
     assert_include 'me', filter[:values].map{|v| v[1]}
@@ -566,7 +585,7 @@
 
   def test_filter_my_projects
     User.current = User.find(2)
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     filter = query.available_filters['project_id']
     assert_not_nil filter
     assert_include 'mine', filter[:values].map{|v| v[1]}
@@ -578,7 +597,7 @@
 
   def test_filter_watched_issues
     User.current = User.find(1)
-    query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
+    query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
     result = find_issues_with_query(query)
     assert_not_nil result
     assert !result.empty?
@@ -588,7 +607,7 @@
 
   def test_filter_unwatched_issues
     User.current = User.find(1)
-    query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
+    query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
     result = find_issues_with_query(query)
     assert_not_nil result
     assert !result.empty?
@@ -601,7 +620,7 @@
     CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
     CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     filter_name = "project.cf_#{field.id}"
     assert_include filter_name, query.available_filters.keys
     query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
@@ -612,7 +631,7 @@
     field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
     CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     filter_name = "author.cf_#{field.id}"
     assert_include filter_name, query.available_filters.keys
     query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
@@ -623,7 +642,7 @@
     field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
     CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     filter_name = "assigned_to.cf_#{field.id}"
     assert_include filter_name, query.available_filters.keys
     query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
@@ -634,7 +653,7 @@
     field = VersionCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
     CustomValue.create!(:custom_field => field, :customized => Version.find(2), :value => 'Foo')
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     filter_name = "fixed_version.cf_#{field.id}"
     assert_include filter_name, query.available_filters.keys
     query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
@@ -646,11 +665,11 @@
     IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
     IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.filters = {"relates" => {:operator => '=', :values => ['1']}}
     assert_equal [2, 3], find_issues_with_query(query).map(&:id).sort
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.filters = {"relates" => {:operator => '=', :values => ['2']}}
     assert_equal [1], find_issues_with_query(query).map(&:id).sort
   end
@@ -663,15 +682,15 @@
       IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
     end
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.filters = {"relates" => {:operator => '=p', :values => ['2']}}
     assert_equal [1, 2], find_issues_with_query(query).map(&:id).sort
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.filters = {"relates" => {:operator => '=p', :values => ['3']}}
     assert_equal [1], find_issues_with_query(query).map(&:id).sort
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.filters = {"relates" => {:operator => '=p', :values => ['4']}}
     assert_equal [], find_issues_with_query(query).map(&:id).sort
   end
@@ -684,7 +703,7 @@
       IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
     end
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.filters = {"relates" => {:operator => '=!p', :values => ['1']}}
     assert_equal [1], find_issues_with_query(query).map(&:id).sort
   end
@@ -697,7 +716,7 @@
       IssueRelation.create!(:relation_type => "relates", :issue_to => Project.find(2).issues.first, :issue_from => Issue.find(3))
     end
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.filters = {"relates" => {:operator => '!p', :values => ['2']}}
     ids = find_issues_with_query(query).map(&:id).sort
     assert_include 2, ids
@@ -710,7 +729,7 @@
     IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
     IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.filters = {"relates" => {:operator => '!*', :values => ['']}}
     ids = find_issues_with_query(query).map(&:id)
     assert_equal [], ids & [1, 2, 3]
@@ -722,13 +741,13 @@
     IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
     IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
 
-    query = Query.new(:name => '_')
+    query = IssueQuery.new(:name => '_')
     query.filters = {"relates" => {:operator => '*', :values => ['']}}
     assert_equal [1, 2, 3], find_issues_with_query(query).map(&:id).sort
   end
 
   def test_statement_should_be_nil_with_no_filters
-    q = Query.new(:name => '_')
+    q = IssueQuery.new(:name => '_')
     q.filters = {}
 
     assert q.valid?
@@ -736,44 +755,62 @@
   end
 
   def test_default_columns
-    q = Query.new
+    q = IssueQuery.new
     assert q.columns.any?
     assert q.inline_columns.any?
     assert q.block_columns.empty?
   end
 
   def test_set_column_names
-    q = Query.new
+    q = IssueQuery.new
     q.column_names = ['tracker', :subject, '', 'unknonw_column']
-    assert_equal [:tracker, :subject], q.columns.collect {|c| c.name}
-    c = q.columns.first
-    assert q.has_column?(c)
+    assert_equal [:id, :tracker, :subject], q.columns.collect {|c| c.name}
+  end
+
+  def test_has_column_should_accept_a_column_name
+    q = IssueQuery.new
+    q.column_names = ['tracker', :subject]
+    assert q.has_column?(:tracker)
+    assert !q.has_column?(:category)
+  end
+
+  def test_has_column_should_accept_a_column
+    q = IssueQuery.new
+    q.column_names = ['tracker', :subject]
+
+    tracker_column = q.available_columns.detect {|c| c.name==:tracker}
+    assert_kind_of QueryColumn, tracker_column
+    category_column = q.available_columns.detect {|c| c.name==:category}
+    assert_kind_of QueryColumn, category_column
+
+    assert q.has_column?(tracker_column)
+    assert !q.has_column?(category_column)
   end
 
   def test_inline_and_block_columns
-    q = Query.new
+    q = IssueQuery.new
     q.column_names = ['subject', 'description', 'tracker']
 
-    assert_equal [:subject, :tracker], q.inline_columns.map(&:name)
+    assert_equal [:id, :subject, :tracker], q.inline_columns.map(&:name)
     assert_equal [:description], q.block_columns.map(&:name)
   end
 
   def test_custom_field_columns_should_be_inline
-    q = Query.new
+    q = IssueQuery.new
     columns = q.available_columns.select {|column| column.is_a? QueryCustomFieldColumn}
     assert columns.any?
     assert_nil columns.detect {|column| !column.inline?}
   end
 
   def test_query_should_preload_spent_hours
-    q = Query.new(:name => '_', :column_names => [:subject, :spent_hours])
+    q = IssueQuery.new(:name => '_', :column_names => [:subject, :spent_hours])
     assert q.has_column?(:spent_hours)
     issues = q.issues
     assert_not_nil issues.first.instance_variable_get("@spent_hours")
   end
 
   def test_groupable_columns_should_include_custom_fields
-    q = Query.new
+    q = IssueQuery.new
     column = q.groupable_columns.detect {|c| c.name == :cf_1}
     assert_not_nil column
     assert_kind_of QueryCustomFieldColumn, column
@@ -783,7 +820,7 @@
     field = CustomField.find(1)
     field.update_attribute :multiple, true
 
-    q = Query.new
+    q = IssueQuery.new
     column = q.groupable_columns.detect {|c| c.name == :cf_1}
     assert_nil column
   end
@@ -791,19 +828,19 @@
   def test_groupable_columns_should_include_user_custom_fields
     cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'user')
 
-    q = Query.new
+    q = IssueQuery.new
     assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
   end
 
   def test_groupable_columns_should_include_version_custom_fields
     cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'version')
 
-    q = Query.new
+    q = IssueQuery.new
     assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
   end
 
   def test_grouped_with_valid_column
-    q = Query.new(:group_by => 'status')
+    q = IssueQuery.new(:group_by => 'status')
     assert q.grouped?
     assert_not_nil q.group_by_column
     assert_equal :status, q.group_by_column.name
@@ -812,7 +849,7 @@
   end
 
   def test_grouped_with_invalid_column
-    q = Query.new(:group_by => 'foo')
+    q = IssueQuery.new(:group_by => 'foo')
     assert !q.grouped?
     assert_nil q.group_by_column
     assert_nil q.group_by_statement
@@ -820,7 +857,7 @@
   
   def test_sortable_columns_should_sort_assignees_according_to_user_format_setting
     with_settings :user_format => 'lastname_coma_firstname' do
-      q = Query.new
+      q = IssueQuery.new
       assert q.sortable_columns.has_key?('assigned_to')
       assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to']
     end
@@ -828,14 +865,14 @@
   
   def test_sortable_columns_should_sort_authors_according_to_user_format_setting
     with_settings :user_format => 'lastname_coma_firstname' do
-      q = Query.new
+      q = IssueQuery.new
       assert q.sortable_columns.has_key?('author')
       assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author']
     end
   end
 
   def test_sortable_columns_should_include_custom_field
-    q = Query.new
+    q = IssueQuery.new
     assert q.sortable_columns['cf_1']
   end
 
@@ -843,29 +880,29 @@
     field = CustomField.find(1)
     field.update_attribute :multiple, true
 
-    q = Query.new
+    q = IssueQuery.new
     assert !q.sortable_columns['cf_1']
   end
 
   def test_default_sort
-    q = Query.new
+    q = IssueQuery.new
     assert_equal [], q.sort_criteria
   end
 
   def test_set_sort_criteria_with_hash
-    q = Query.new
+    q = IssueQuery.new
     q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
     assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
   end
 
   def test_set_sort_criteria_with_array
-    q = Query.new
+    q = IssueQuery.new
     q.sort_criteria = [['priority', 'desc'], 'tracker']
     assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
   end
 
   def test_create_query_with_sort
-    q = Query.new(:name => 'Sorted')
+    q = IssueQuery.new(:name => 'Sorted')
     q.sort_criteria = [['priority', 'desc'], 'tracker']
     assert q.save
     q.reload
@@ -873,53 +910,47 @@
   end
 
   def test_sort_by_string_custom_field_asc
-    q = Query.new
+    q = IssueQuery.new
     c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
     assert c
     assert c.sortable
-    issues = Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where(
-         q.statement
-       ).order("#{c.sortable} ASC").all
+    issues = q.issues(:order => "#{c.sortable} ASC")
     values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
     assert !values.empty?
     assert_equal values.sort, values
   end
 
   def test_sort_by_string_custom_field_desc
-    q = Query.new
+    q = IssueQuery.new
     c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
     assert c
     assert c.sortable
-    issues = Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where(
-         q.statement
-       ).order("#{c.sortable} DESC").all
+    issues = q.issues(:order => "#{c.sortable} DESC")
     values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
     assert !values.empty?
     assert_equal values.sort.reverse, values
   end
 
   def test_sort_by_float_custom_field_asc
-    q = Query.new
+    q = IssueQuery.new
     c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
     assert c
     assert c.sortable
-    issues = Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where(
-         q.statement
-       ).order("#{c.sortable} ASC").all
+    issues = q.issues(:order => "#{c.sortable} ASC")
     values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
     assert !values.empty?
     assert_equal values.sort, values
   end
 
   def test_invalid_query_should_raise_query_statement_invalid_error
-    q = Query.new
+    q = IssueQuery.new
     assert_raise Query::StatementInvalid do
       q.issues(:conditions => "foo = 1")
     end
   end
 
   def test_issue_count
-    q = Query.new(:name => '_')
+    q = IssueQuery.new(:name => '_')
     issue_count = q.issue_count
     assert_equal q.issues.size, issue_count
   end
@@ -935,7 +966,7 @@
   end
 
   def test_issue_count_by_association_group
-    q = Query.new(:name => '_', :group_by => 'assigned_to')
+    q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
     count_by_group = q.issue_count_by_group
     assert_kind_of Hash, count_by_group
     assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
@@ -944,7 +975,7 @@
   end
 
   def test_issue_count_by_list_custom_field_group
-    q = Query.new(:name => '_', :group_by => 'cf_1')
+    q = IssueQuery.new(:name => '_', :group_by => 'cf_1')
     count_by_group = q.issue_count_by_group
     assert_kind_of Hash, count_by_group
     assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
@@ -953,7 +984,7 @@
   end
 
   def test_issue_count_by_date_custom_field_group
-    q = Query.new(:name => '_', :group_by => 'cf_8')
+    q = IssueQuery.new(:name => '_', :group_by => 'cf_8')
     count_by_group = q.issue_count_by_group
     assert_kind_of Hash, count_by_group
     assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
@@ -963,7 +994,7 @@
   def test_issue_count_with_nil_group_only
     Issue.update_all("assigned_to_id = NULL")
 
-    q = Query.new(:name => '_', :group_by => 'assigned_to')
+    q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
     count_by_group = q.issue_count_by_group
     assert_kind_of Hash, count_by_group
     assert_equal 1, count_by_group.keys.size
@@ -971,7 +1002,7 @@
   end
 
   def test_issue_ids
-    q = Query.new(:name => '_')
+    q = IssueQuery.new(:name => '_')
     order = "issues.subject, issues.id"
     issues = q.issues(:order => order)
     assert_equal issues.map(&:id), q.issue_ids(:order => order)
@@ -979,13 +1010,13 @@
 
   def test_label_for
     set_language_if_valid 'en'
-    q = Query.new
+    q = IssueQuery.new
     assert_equal 'Assignee', q.label_for('assigned_to_id')
   end
 
   def test_label_for_fr
     set_language_if_valid 'fr'
-    q = Query.new
+    q = IssueQuery.new
     s = "Assign\xc3\xa9 \xc3\xa0"
     s.force_encoding('UTF-8') if s.respond_to?(:force_encoding)
     assert_equal s, q.label_for('assigned_to_id')
@@ -997,32 +1028,32 @@
     developer = User.find(3)
 
     # Public query on project 1
-    q = Query.find(1)
+    q = IssueQuery.find(1)
     assert q.editable_by?(admin)
     assert q.editable_by?(manager)
     assert !q.editable_by?(developer)
 
     # Private query on project 1
-    q = Query.find(2)
+    q = IssueQuery.find(2)
     assert q.editable_by?(admin)
     assert !q.editable_by?(manager)
     assert q.editable_by?(developer)
 
     # Private query for all projects
-    q = Query.find(3)
+    q = IssueQuery.find(3)
     assert q.editable_by?(admin)
     assert !q.editable_by?(manager)
     assert q.editable_by?(developer)
 
     # Public query for all projects
-    q = Query.find(4)
+    q = IssueQuery.find(4)
     assert q.editable_by?(admin)
     assert !q.editable_by?(manager)
     assert !q.editable_by?(developer)
   end
 
   def test_visible_scope
-    query_ids = Query.visible(User.anonymous).map(&:id)
+    query_ids = IssueQuery.visible(User.anonymous).map(&:id)
 
     assert query_ids.include?(1), 'public query on public project was not visible'
     assert query_ids.include?(4), 'public query for all projects was not visible'
@@ -1031,81 +1062,50 @@
     assert !query_ids.include?(7), 'public query on private project was visible'
   end
 
-  context "#available_filters" do
-    setup do
-      @query = Query.new(:name => "_")
-    end
+  test "#available_filters should include users of visible projects in cross-project view" do
+    users = IssueQuery.new.available_filters["assigned_to_id"]
+    assert_not_nil users
+    assert users[:values].map{|u|u[1]}.include?("3")
+  end
 
-    should "include users of visible projects in cross-project view" do
-      users = @query.available_filters["assigned_to_id"]
-      assert_not_nil users
-      assert users[:values].map{|u|u[1]}.include?("3")
-    end
+  test "#available_filters should include users of subprojects" do
+    user1 = User.generate!
+    user2 = User.generate!
+    project = Project.find(1)
+    Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1])
 
-    should "include users of subprojects" do
-      user1 = User.generate!
-      user2 = User.generate!
-      project = Project.find(1)
-      Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1])
-      @query.project = project
+    users = IssueQuery.new(:project => project).available_filters["assigned_to_id"]
+    assert_not_nil users
+    assert users[:values].map{|u|u[1]}.include?(user1.id.to_s)
+    assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s)
+  end
 
-      users = @query.available_filters["assigned_to_id"]
-      assert_not_nil users
-      assert users[:values].map{|u|u[1]}.include?(user1.id.to_s)
-      assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s)
-    end
+  test "#available_filters should include visible projects in cross-project view" do
+    projects = IssueQuery.new.available_filters["project_id"]
+    assert_not_nil projects
+    assert projects[:values].map{|u|u[1]}.include?("1")
+  end
 
-    should "include visible projects in cross-project view" do
-      projects = @query.available_filters["project_id"]
-      assert_not_nil projects
-      assert projects[:values].map{|u|u[1]}.include?("1")
-    end
+  test "#available_filters should include 'member_of_group' filter" do
+    query = IssueQuery.new
+    assert query.available_filters.keys.include?("member_of_group")
+    assert_equal :list_optional, query.available_filters["member_of_group"][:type]
+    assert query.available_filters["member_of_group"][:values].present?
+    assert_equal Group.all.sort.map {|g| [g.name, g.id.to_s]},
+      query.available_filters["member_of_group"][:values].sort
+  end
 
-    context "'member_of_group' filter" do
-      should "be present" do
-        assert @query.available_filters.keys.include?("member_of_group")
-      end
+  test "#available_filters should include 'assigned_to_role' filter" do
+    query = IssueQuery.new
+    assert query.available_filters.keys.include?("assigned_to_role")
+    assert_equal :list_optional, query.available_filters["assigned_to_role"][:type]
 
-      should "be an optional list" do
-        assert_equal :list_optional, @query.available_filters["member_of_group"][:type]
-      end
+    assert query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
+    assert query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
+    assert query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
 
-      should "have a list of the groups as values" do
-        Group.destroy_all # No fixtures
-        group1 = Group.generate!.reload
-        group2 = Group.generate!.reload
-
-        expected_group_list = [
-                               [group1.name, group1.id.to_s],
-                               [group2.name, group2.id.to_s]
-                              ]
-        assert_equal expected_group_list.sort, @query.available_filters["member_of_group"][:values].sort
-      end
-
-    end
-
-    context "'assigned_to_role' filter" do
-      should "be present" do
-        assert @query.available_filters.keys.include?("assigned_to_role")
-      end
-
-      should "be an optional list" do
-        assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type]
-      end
-
-      should "have a list of the Roles as values" do
-        assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
-        assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
-        assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
-      end
-
-      should "not include the built in Roles as values" do
-        assert ! @query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
-        assert ! @query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
-      end
-
-    end
-
+    assert ! query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
+    assert ! query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
   end
 
   context "#statement" do
@@ -1127,34 +1127,34 @@
       end
 
       should "search assigned to for users in the group" do
-        @query = Query.new(:name => '_')
+        @query = IssueQuery.new(:name => '_')
         @query.add_filter('member_of_group', '=', [@group.id.to_s])
 
-        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')"
+        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@group.id}')"
         assert_find_issues_with_query_is_successful @query
       end
 
       should "search not assigned to any group member (none)" do
-        @query = Query.new(:name => '_')
+        @query = IssueQuery.new(:name => '_')
         @query.add_filter('member_of_group', '!*', [''])
 
         # Users not in a group
-        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')"
+        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}','#{@group.id}','#{@group2.id}')"
         assert_find_issues_with_query_is_successful @query
       end
 
       should "search assigned to any group member (all)" do
-        @query = Query.new(:name => '_')
+        @query = IssueQuery.new(:name => '_')
         @query.add_filter('member_of_group', '*', [''])
 
         # Only users in a group
-        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')"
+        assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}','#{@group.id}','#{@group2.id}')"
         assert_find_issues_with_query_is_successful @query
       end
 
       should "return an empty set with = empty group" do
         @empty_group = Group.generate!
-        @query = Query.new(:name => '_')
+        @query = IssueQuery.new(:name => '_')
         @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
 
         assert_equal [], find_issues_with_query(@query)
@@ -1162,7 +1162,7 @@
 
       should "return issues with ! empty group" do
         @empty_group = Group.generate!
-        @query = Query.new(:name => '_')
+        @query = IssueQuery.new(:name => '_')
         @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
 
         assert_find_issues_with_query_is_successful @query
@@ -1191,7 +1191,7 @@
       end
 
       should "search assigned to for users with the Role" do
-        @query = Query.new(:name => '_', :project => @project)
+        @query = IssueQuery.new(:name => '_', :project => @project)
         @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
 
         assert_query_result [@issue1, @issue3], @query
@@ -1201,7 +1201,7 @@
         other_project = Project.generate!
         User.add_to_project(@developer, other_project, @manager_role)
         
-        @query = Query.new(:name => '_', :project => @project)
+        @query = IssueQuery.new(:name => '_', :project => @project)
         @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
 
         assert_query_result [@issue1, @issue3], @query
@@ -1209,28 +1209,28 @@
 
       should "return an empty set with empty role" do
         @empty_role = Role.generate!
-        @query = Query.new(:name => '_', :project => @project)
+        @query = IssueQuery.new(:name => '_', :project => @project)
         @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
 
         assert_query_result [], @query
       end
 
       should "search assigned to for users without the Role" do
-        @query = Query.new(:name => '_', :project => @project)
+        @query = IssueQuery.new(:name => '_', :project => @project)
         @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s])
 
         assert_query_result [@issue2, @issue4, @issue5], @query
       end
 
       should "search assigned to for users not assigned to any Role (none)" do
-        @query = Query.new(:name => '_', :project => @project)
+        @query = IssueQuery.new(:name => '_', :project => @project)
         @query.add_filter('assigned_to_role', '!*', [''])
 
         assert_query_result [@issue4, @issue5], @query
       end
 
       should "search assigned to for users assigned to any Role (all)" do
-        @query = Query.new(:name => '_', :project => @project)
+        @query = IssueQuery.new(:name => '_', :project => @project)
         @query.add_filter('assigned_to_role', '*', [''])
 
         assert_query_result [@issue1, @issue2, @issue3], @query
@@ -1238,12 +1238,11 @@
 
       should "return issues with ! empty role" do
         @empty_role = Role.generate!
-        @query = Query.new(:name => '_', :project => @project)
+        @query = IssueQuery.new(:name => '_', :project => @project)
         @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s])
 
         assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query
       end
     end
   end
-
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/repository_bazaar_test.rb
--- a/test/unit/repository_bazaar_test.rb
+++ b/test/unit/repository_bazaar_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -105,7 +105,7 @@
       @project.reload
       assert_equal NUM_REV, @repository.changesets.count
       # Remove changesets with revision > 5
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 2}
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 2}
       @project.reload
       assert_equal 2, @repository.changesets.count
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/repository_cvs_test.rb
--- a/test/unit/repository_cvs_test.rb
+++ b/test/unit/repository_cvs_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -116,12 +116,12 @@
       assert_equal CHANGESETS_NUM, @repository.changesets.count
 
       # Remove changesets with revision > 3
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 3}
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 3}
       @project.reload
       assert_equal 3, @repository.changesets.count
       assert_equal %w|3 2 1|, @repository.changesets.all.collect(&:revision)
 
-      rev3_commit = @repository.changesets.find(:first, :order => 'committed_on DESC')
+      rev3_commit = @repository.changesets.reorder('committed_on DESC').first
       assert_equal '3', rev3_commit.revision
        # 2007-12-14 01:27:22 +0900
       rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
diff -r 0a574315af3e -r 4f746d8966dd test/unit/repository_darcs_test.rb
--- a/test/unit/repository_darcs_test.rb
+++ b/test/unit/repository_darcs_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -79,7 +79,7 @@
       assert_equal NUM_REV, @repository.changesets.count
 
       # Remove changesets with revision > 3
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 3}
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 3}
       @project.reload
       assert_equal 3, @repository.changesets.count
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/repository_filesystem_test.rb
--- a/test/unit/repository_filesystem_test.rb
+++ b/test/unit/repository_filesystem_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/repository_git_test.rb
--- a/test/unit/repository_git_test.rb
+++ b/test/unit/repository_git_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/repository_mercurial_test.rb
--- a/test/unit/repository_mercurial_test.rb
+++ b/test/unit/repository_mercurial_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -102,7 +102,7 @@
       @project.reload
       assert_equal NUM_REV, @repository.changesets.count
       # Remove changesets with revision > 2
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 2}
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 2}
       @project.reload
       assert_equal 3, @repository.changesets.count
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/repository_subversion_test.rb
--- a/test/unit/repository_subversion_test.rb
+++ b/test/unit/repository_subversion_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -47,7 +47,7 @@
       assert_equal NUM_REV, @repository.changesets.count
 
       # Remove changesets with revision > 5
-      @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 5}
+      @repository.changesets.all.each {|c| c.destroy if c.revision.to_i > 5}
       @project.reload
       assert_equal 5, @repository.changesets.count
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/repository_test.rb
--- a/test/unit/repository_test.rb
+++ b/test/unit/repository_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -209,7 +209,7 @@
     assert_equal [101], fixed_issue.changeset_ids
 
     # issue change
-    journal = fixed_issue.journals.find(:first, :order => 'created_on desc')
+    journal = fixed_issue.journals.reorder('created_on desc').first
     assert_equal User.find_by_login('dlopper'), journal.user
     assert_equal 'Applied in changeset r2.', journal.notes
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/role_test.rb
--- a/test/unit/role_test.rb
+++ b/test/unit/role_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/search_test.rb
--- a/test/unit/search_test.rb
+++ b/test/unit/search_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/setting_test.rb
--- a/test/unit/setting_test.rb
+++ b/test/unit/setting_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/time_entry_activity_test.rb
--- a/test/unit/time_entry_activity_test.rb
+++ b/test/unit/time_entry_activity_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -84,5 +84,33 @@
     e.reload
     assert_equal "0", e.custom_value_for(field).value
   end
+
+  def test_system_activity_with_child_in_use_should_be_in_use
+    project = Project.generate!
+    system_activity = TimeEntryActivity.create!(:name => 'Activity')
+    project_activity = TimeEntryActivity.create!(:name => 'Activity', :project => project, :parent_id => system_activity.id)
+
+    TimeEntry.generate!(:project => project, :activity => project_activity)
+
+    assert project_activity.in_use?
+    assert system_activity.in_use?
+  end
+
+  def test_destroying_a_system_activity_should_reassign_children_activities
+    project = Project.generate!
+    system_activity = TimeEntryActivity.create!(:name => 'Activity')
+    project_activity = TimeEntryActivity.create!(:name => 'Activity', :project => project, :parent_id => system_activity.id)
+
+    entries = [
+      TimeEntry.generate!(:project => project, :activity => system_activity),
+      TimeEntry.generate!(:project => project, :activity => project_activity)
+    ]
+
+    assert_difference 'TimeEntryActivity.count', -2 do
+      assert_nothing_raised do
+        assert system_activity.destroy(TimeEntryActivity.find_by_name('Development'))
+      end
+    end
+    assert entries.all? {|entry| entry.reload.activity.name == 'Development'}
+  end
 end
-
diff -r 0a574315af3e -r 4f746d8966dd test/unit/time_entry_test.rb
--- a/test/unit/time_entry_test.rb
+++ b/test/unit/time_entry_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,8 +25,7 @@
            :journals, :journal_details,
            :issue_categories, :enumerations,
            :groups_users,
-           :enabled_modules,
-           :workflows
+           :enabled_modules
 
   def test_hours_format
     assertions = { "2"      => 2.0,
@@ -111,6 +110,13 @@
     assert_equal 1, te.errors.count
   end
 
+  def test_spent_on_with_2_digits_year_should_not_be_valid
+    entry = TimeEntry.new(:project => Project.find(1), :user => User.find(1), :activity => TimeEntryActivity.first, :hours => 1)
+    entry.spent_on = "09-02-04"
+    assert !entry.valid?
+    assert_include I18n.translate('activerecord.errors.messages.not_a_date'), entry.errors[:spent_on]
+  end
+
   def test_set_project_if_nil
     anon     = User.anonymous
     project  = Project.find(1)
diff -r 0a574315af3e -r 4f746d8966dd test/unit/token_test.rb
--- a/test/unit/token_test.rb
+++ b/test/unit/token_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -58,4 +58,56 @@
       assert_equal 2, Token.destroy_expired
     end
   end
+
+  def test_find_active_user_should_return_user
+    token = Token.create!(:user_id => 1, :action => 'api')
+    assert_equal User.find(1), Token.find_active_user('api', token.value)
+  end
+
+  def test_find_active_user_should_return_nil_for_locked_user
+    token = Token.create!(:user_id => 1, :action => 'api')
+    User.find(1).lock!
+    assert_nil Token.find_active_user('api', token.value)
+  end
+
+  def test_find_user_should_return_user
+    token = Token.create!(:user_id => 1, :action => 'api')
+    assert_equal User.find(1), Token.find_user('api', token.value)
+  end
+
+  def test_find_user_should_return_locked_user
+    token = Token.create!(:user_id => 1, :action => 'api')
+    User.find(1).lock!
+    assert_equal User.find(1), Token.find_user('api', token.value)
+  end
+
+  def test_find_token_should_return_the_token
+    token = Token.create!(:user_id => 1, :action => 'api')
+    assert_equal token, Token.find_token('api', token.value)
+  end
+
+  def test_find_token_should_return_the_token_with_validity
+    token = Token.create!(:user_id => 1, :action => 'api', :created_on => 1.hour.ago)
+    assert_equal token, Token.find_token('api', token.value, 1)
+  end
+
+  def test_find_token_should_return_nil_with_wrong_action
+    token = Token.create!(:user_id => 1, :action => 'feeds')
+    assert_nil Token.find_token('api', token.value)
+  end
+
+  def test_find_token_should_return_nil_with_wrong_action
+    token = Token.create!(:user_id => 1, :action => 'feeds')
+    assert_nil Token.find_token('api', Token.generate_token_value)
+  end
+
+  def test_find_token_should_return_nil_without_user
+    token = Token.create!(:user_id => 999, :action => 'api')
+    assert_nil Token.find_token('api', token.value)
+  end
+
+  def test_find_token_should_return_nil_with_validity_expired
+    token = Token.create!(:user_id => 999, :action => 'api', :created_on => 2.days.ago)
+    assert_nil Token.find_token('api', token.value, 1)
+  end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/user_preference_test.rb
--- a/test/unit/user_preference_test.rb
+++ b/test/unit/user_preference_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/user_test.rb
--- a/test/unit/user_test.rb
+++ b/test/unit/user_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,8 +25,7 @@
             :issue_categories, :enumerations, :issues,
             :journals, :journal_details,
             :groups_users,
-            :enabled_modules,
-            :workflows
+            :enabled_modules
 
   def setup
     @admin = User.find(1)
@@ -34,6 +33,10 @@
     @dlopper = User.find(3)
   end
 
+  def test_sorted_scope_should_sort_user_by_display_name
+    assert_equal User.all.map(&:name).map(&:downcase).sort, User.sorted.all.map(&:name).map(&:downcase)
+  end
+
   def test_generate
     User.generate!(:firstname => 'Testing connection')
     User.generate!(:firstname => 'Testing connection')
@@ -724,6 +727,32 @@
     assert_equal true, User.default_admin_account_changed?
   end
 
+  def test_membership_with_project_should_return_membership
+    project = Project.find(1)
+
+    membership = @jsmith.membership(project)
+    assert_kind_of Member, membership
+    assert_equal @jsmith, membership.user
+    assert_equal project, membership.project
+  end
+
+  def test_membership_with_project_id_should_return_membership
+    project = Project.find(1)
+
+    membership = @jsmith.membership(1)
+    assert_kind_of Member, membership
+    assert_equal @jsmith, membership.user
+    assert_equal project, membership.project
+  end
+
+  def test_membership_for_non_member_should_return_nil
+    project = Project.find(1)
+
+    user = User.generate!
+    membership = user.membership(1)
+    assert_nil membership
+  end
+
   def test_roles_for_project
     # user with a role
     roles = @jsmith.roles_for_project(Project.find(1))
@@ -901,7 +930,7 @@
       should "authorize nearly everything for admin users" do
         project = Project.find(1)
         assert ! @admin.member_of?(project)
-        %w(edit_issues delete_issues manage_news manage_documents manage_wiki).each do |p|
+        %w(edit_issues delete_issues manage_news add_documents manage_wiki).each do |p|
           assert_equal true, @admin.allowed_to?(p.to_sym, project)
         end
       end
@@ -1014,9 +1043,15 @@
         assert ! @user.notify_about?(@issue)
       end
     end
+  end
 
-    context "other events" do
-      should 'be added and tested'
+  def test_notify_about_news
+    user = User.generate!
+    news = News.new
+
+    User::MAIL_NOTIFICATION_OPTIONS.map(&:first).each do |option|
+      user.mail_notification = option
+      assert_equal (option != 'none'), user.notify_about?(news)
     end
   end
 
diff -r 0a574315af3e -r 4f746d8966dd test/unit/version_test.rb
--- a/test/unit/version_test.rb
+++ b/test/unit/version_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -37,6 +37,8 @@
     assert !v.valid?
     v.effective_date = '2012-31-11'
     assert !v.valid?
+    v.effective_date = '-2012-31-11'
+    assert !v.valid?
     v.effective_date = 'ABC'
     assert !v.valid?
     assert_include I18n.translate('activerecord.errors.messages.not_a_date'),
@@ -46,8 +48,8 @@
   def test_progress_should_be_0_with_no_assigned_issues
     project = Project.find(1)
     v = Version.create!(:project => project, :name => 'Progress')
-    assert_equal 0, v.completed_pourcent
-    assert_equal 0, v.closed_pourcent
+    assert_equal 0, v.completed_percent
+    assert_equal 0, v.closed_percent
   end
 
   def test_progress_should_be_0_with_unbegun_assigned_issues
@@ -55,20 +57,20 @@
     v = Version.create!(:project => project, :name => 'Progress')
     add_issue(v)
     add_issue(v, :done_ratio => 0)
-    assert_progress_equal 0, v.completed_pourcent
-    assert_progress_equal 0, v.closed_pourcent
+    assert_progress_equal 0, v.completed_percent
+    assert_progress_equal 0, v.closed_percent
   end
 
   def test_progress_should_be_100_with_closed_assigned_issues
     project = Project.find(1)
-    status = IssueStatus.find(:first, :conditions => {:is_closed => true})
+    status = IssueStatus.where(:is_closed => true).first
     v = Version.create!(:project => project, :name => 'Progress')
     add_issue(v, :status => status)
     add_issue(v, :status => status, :done_ratio => 20)
     add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
     add_issue(v, :status => status, :estimated_hours => 15)
-    assert_progress_equal 100.0, v.completed_pourcent
-    assert_progress_equal 100.0, v.closed_pourcent
+    assert_progress_equal 100.0, v.completed_percent
+    assert_progress_equal 100.0, v.closed_percent
   end
 
   def test_progress_should_consider_done_ratio_of_open_assigned_issues
@@ -77,8 +79,8 @@
     add_issue(v)
     add_issue(v, :done_ratio => 20)
     add_issue(v, :done_ratio => 70)
-    assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_pourcent
-    assert_progress_equal 0, v.closed_pourcent
+    assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_percent
+    assert_progress_equal 0, v.closed_percent
   end
 
   def test_progress_should_consider_closed_issues_as_completed
@@ -86,9 +88,9 @@
     v = Version.create!(:project => project, :name => 'Progress')
     add_issue(v)
     add_issue(v, :done_ratio => 20)
-    add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
-    assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_pourcent
-    assert_progress_equal (100.0)/3, v.closed_pourcent
+    add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
+    assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_percent
+    assert_progress_equal (100.0)/3, v.closed_percent
   end
 
   def test_progress_should_consider_estimated_hours_to_weigth_issues
@@ -97,20 +99,20 @@
     add_issue(v, :estimated_hours => 10)
     add_issue(v, :estimated_hours => 20, :done_ratio => 30)
     add_issue(v, :estimated_hours => 40, :done_ratio => 10)
-    add_issue(v, :estimated_hours => 25, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
-    assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_pourcent
-    assert_progress_equal 25.0/95.0*100, v.closed_pourcent
+    add_issue(v, :estimated_hours => 25, :status => IssueStatus.where(:is_closed => true).first)
+    assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_percent
+    assert_progress_equal 25.0/95.0*100, v.closed_percent
   end
 
   def test_progress_should_consider_average_estimated_hours_to_weigth_unestimated_issues
     project = Project.find(1)
     v = Version.create!(:project => project, :name => 'Progress')
     add_issue(v, :done_ratio => 20)
-    add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
+    add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
     add_issue(v, :estimated_hours => 10, :done_ratio => 30)
     add_issue(v, :estimated_hours => 40, :done_ratio => 10)
-    assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_pourcent
-    assert_progress_equal 25.0/100.0*100, v.closed_pourcent
+    assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_percent
+    assert_progress_equal 25.0/100.0*100, v.closed_percent
   end
 
   def test_should_sort_scheduled_then_unscheduled_versions
@@ -152,7 +154,7 @@
       @version.update_attribute(:effective_date, 7.days.from_now.to_date)
       add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
       add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
-      assert_equal 60, @version.completed_pourcent
+      assert_equal 60, @version.completed_percent
       assert_equal false, @version.behind_schedule?
     end
 
@@ -160,7 +162,7 @@
       @version.update_attribute(:effective_date, 7.days.from_now.to_date)
       add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
       add_issue(@version, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
-      assert_equal 40, @version.completed_pourcent
+      assert_equal 40, @version.completed_percent
       assert_equal true, @version.behind_schedule?
     end
 
@@ -168,7 +170,7 @@
       @version.update_attribute(:effective_date, 7.days.from_now.to_date)
       add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
       add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
-      assert_equal 100, @version.completed_pourcent
+      assert_equal 100, @version.completed_percent
       assert_equal false, @version.behind_schedule?
     end
   end
@@ -242,8 +244,8 @@
     Issue.create!({:project => version.project,
                    :fixed_version => version,
                    :subject => 'Test',
-                   :author => User.find(:first),
-                   :tracker => version.project.trackers.find(:first)}.merge(attributes))
+                   :author => User.first,
+                   :tracker => version.project.trackers.first}.merge(attributes))
   end
 
   def assert_progress_equal(expected_float, actual_float, message="")
diff -r 0a574315af3e -r 4f746d8966dd test/unit/watcher_test.rb
--- a/test/unit/watcher_test.rb
+++ b/test/unit/watcher_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/wiki_content_test.rb
--- a/test/unit/wiki_content_test.rb
+++ b/test/unit/wiki_content_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/wiki_content_version_test.rb
--- a/test/unit/wiki_content_version_test.rb
+++ b/test/unit/wiki_content_version_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/wiki_page_test.rb
--- a/test/unit/wiki_page_test.rb
+++ b/test/unit/wiki_page_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/wiki_redirect_test.rb
--- a/test/unit/wiki_redirect_test.rb
+++ b/test/unit/wiki_redirect_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -69,6 +69,6 @@
     assert WikiRedirect.create(:wiki => @wiki, :title => 'An_old_page', :redirects_to => 'Original_title')
 
     @original.destroy
-    assert !@wiki.redirects.find(:first)
+    assert_nil @wiki.redirects.first
   end
 end
diff -r 0a574315af3e -r 4f746d8966dd test/unit/wiki_test.rb
--- a/test/unit/wiki_test.rb
+++ b/test/unit/wiki_test.rb
@@ -1,7 +1,7 @@
 # encoding: utf-8
 #
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
diff -r 0a574315af3e -r 4f746d8966dd test/unit/workflow_test.rb
--- a/test/unit/workflow_test.rb
+++ b/test/unit/workflow_test.rb
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
